aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Joey Hess <joeyh@debian.org>2013-11-27 18:41:44 -0400
committerGravatar Joey Hess <joeyh@debian.org>2013-11-27 18:41:44 -0400
commit2e6d39d426f6b08f236d6071e671a9dcfc799d91 (patch)
tree1618fd9e34a30409ee0937cb4b3861ec3b5e7bba
git-annex (5.20131127) unstable; urgency=low
* webapp: Detect when upgrades are available, and upgrade if the user desires. (Only when git-annex is installed using the prebuilt binaries from git-annex upstream, not from eg Debian.) * assistant: Detect when the git-annex binary is modified or replaced, and either prompt the user to restart the program, or automatically restart it. * annex.autoupgrade configures both the above upgrade behaviors. * Added support for quvi 0.9. Slightly suboptimal due to limitations in its interface compared with the old version. * Bug fix: annex.version did not get set on automatic upgrade to v5 direct mode repo, so the upgrade was performed repeatedly, slowing commands down. * webapp: Fix bug that broke switching between local repositories that use the new guarded direct mode. * Android: Fix stripping of the git-annex binary. * Android: Make terminal app show git-annex version number. * Android: Re-enable XMPP support. * reinject: Allow to be used in direct mode. * Futher improvements to git repo repair. Has now been tested in tens of thousands of intentionally damaged repos, and successfully repaired them all. * Allow use of --unused in bare repository. # imported from the archive
-rw-r--r--.ghci1
-rw-r--r--Annex.hs252
-rw-r--r--Annex/Branch.hs533
-rw-r--r--Annex/Branch/Transitions.hs53
-rw-r--r--Annex/BranchState.hs43
-rw-r--r--Annex/CatFile.hs139
-rw-r--r--Annex/CheckAttr.hs35
-rw-r--r--Annex/CheckIgnore.hs32
-rw-r--r--Annex/Content.hs529
-rw-r--r--Annex/Content/Direct.hs259
-rw-r--r--Annex/Direct.hs306
-rw-r--r--Annex/Direct/Fixup.hs31
-rw-r--r--Annex/Environment.hs65
-rw-r--r--Annex/Exception.hs46
-rw-r--r--Annex/FileMatcher.hs102
-rw-r--r--Annex/Hook.hs42
-rw-r--r--Annex/Journal.hs128
-rw-r--r--Annex/Link.hs105
-rw-r--r--Annex/LockPool.hs56
-rw-r--r--Annex/Path.hs34
-rw-r--r--Annex/Perms.hs125
-rw-r--r--Annex/Queue.hs62
-rw-r--r--Annex/Quvi.hs20
-rw-r--r--Annex/ReplaceFile.hs39
-rw-r--r--Annex/Ssh.hs198
-rw-r--r--Annex/TaggedPush.hs61
-rw-r--r--Annex/UUID.hs96
-rw-r--r--Annex/Url.hs27
-rw-r--r--Annex/Version.hs47
-rw-r--r--Annex/Wanted.hs32
-rw-r--r--Assistant.hs175
-rw-r--r--Assistant/Alert.hs433
-rw-r--r--Assistant/Alert/Utility.hs130
-rw-r--r--Assistant/BranchChange.hs19
-rw-r--r--Assistant/Changes.hs47
-rw-r--r--Assistant/Commits.hs23
-rw-r--r--Assistant/Common.hs14
-rw-r--r--Assistant/DaemonStatus.hs262
-rw-r--r--Assistant/DeleteRemote.hs89
-rw-r--r--Assistant/Drop.hs112
-rw-r--r--Assistant/Install.hs101
-rw-r--r--Assistant/Install/AutoStart.hs39
-rw-r--r--Assistant/Install/Menu.hs47
-rw-r--r--Assistant/MakeRemote.hs165
-rw-r--r--Assistant/Monad.hs144
-rw-r--r--Assistant/NamedThread.hs102
-rw-r--r--Assistant/NetMessager.hs180
-rw-r--r--Assistant/Pairing.hs92
-rw-r--r--Assistant/Pairing/MakeRemote.hs95
-rw-r--r--Assistant/Pairing/Network.hs130
-rw-r--r--Assistant/Pushes.hs40
-rw-r--r--Assistant/RepoProblem.hs34
-rw-r--r--Assistant/ScanRemotes.hs41
-rw-r--r--Assistant/Ssh.hs342
-rw-r--r--Assistant/Sync.hs276
-rw-r--r--Assistant/Threads/Committer.hs493
-rw-r--r--Assistant/Threads/ConfigMonitor.hs87
-rw-r--r--Assistant/Threads/Cronner.hs225
-rw-r--r--Assistant/Threads/DaemonStatus.hs29
-rw-r--r--Assistant/Threads/Glacier.hs43
-rw-r--r--Assistant/Threads/Merger.hs118
-rw-r--r--Assistant/Threads/MountWatcher.hs195
-rw-r--r--Assistant/Threads/NetWatcher.hs138
-rw-r--r--Assistant/Threads/PairListener.hs160
-rw-r--r--Assistant/Threads/ProblemFixer.hs70
-rw-r--r--Assistant/Threads/Pusher.hs49
-rw-r--r--Assistant/Threads/SanityChecker.hs175
-rw-r--r--Assistant/Threads/TransferPoller.hs56
-rw-r--r--Assistant/Threads/TransferScanner.hs183
-rw-r--r--Assistant/Threads/TransferWatcher.hs104
-rw-r--r--Assistant/Threads/Transferrer.hs25
-rw-r--r--Assistant/Threads/UpgradeWatcher.hs109
-rw-r--r--Assistant/Threads/Upgrader.hs101
-rw-r--r--Assistant/Threads/Watcher.hs355
-rw-r--r--Assistant/Threads/WebApp.hs109
-rw-r--r--Assistant/Threads/XMPPClient.hs368
-rw-r--r--Assistant/Threads/XMPPPusher.hs81
-rw-r--r--Assistant/TransferQueue.hs223
-rw-r--r--Assistant/TransferSlots.hs286
-rw-r--r--Assistant/TransferrerPool.hs95
-rw-r--r--Assistant/Types/Alert.hs78
-rw-r--r--Assistant/Types/BranchChange.hs19
-rw-r--r--Assistant/Types/Buddies.hs80
-rw-r--r--Assistant/Types/Changes.hs77
-rw-r--r--Assistant/Types/Commits.hs19
-rw-r--r--Assistant/Types/DaemonStatus.hs119
-rw-r--r--Assistant/Types/NamedThread.hs21
-rw-r--r--Assistant/Types/NetMessager.hs155
-rw-r--r--Assistant/Types/Pushes.hs24
-rw-r--r--Assistant/Types/RepoProblem.hs28
-rw-r--r--Assistant/Types/ScanRemotes.hs25
-rw-r--r--Assistant/Types/ThreadName.hs14
-rw-r--r--Assistant/Types/ThreadedMonad.hs38
-rw-r--r--Assistant/Types/TransferQueue.hs29
-rw-r--r--Assistant/Types/TransferSlots.hs34
-rw-r--r--Assistant/Types/TransferrerPool.hs23
-rw-r--r--Assistant/Types/UrlRenderer.hs26
-rw-r--r--Assistant/XMPP.hs273
-rw-r--r--Assistant/XMPP/Buddies.hs87
-rw-r--r--Assistant/XMPP/Client.hs84
-rw-r--r--Assistant/XMPP/Git.hs382
-rw-r--r--Backend.hs120
-rw-r--r--Backend/Hash.hs168
-rw-r--r--Backend/URL.hs37
-rw-r--r--Backend/Utilities.hs25
-rw-r--r--Backend/WORM.hs43
-rw-r--r--Build/BundledPrograms.hs58
-rw-r--r--Build/Configure.hs140
-rw-r--r--Build/DesktopFile.hs82
-rw-r--r--Build/DistributionUpdate.hs64
-rw-r--r--Build/EvilSplicer.hs606
-rw-r--r--Build/InstallDesktopFile.hs19
-rw-r--r--Build/NullSoftInstaller.hs139
-rw-r--r--Build/OSXMkLibs.hs157
-rw-r--r--Build/Standalone.hs54
-rw-r--r--Build/TestConfig.hs143
-rw-r--r--Build/Version.hs69
-rwxr-xr-xBuild/make-sdist.sh21
-rwxr-xr-xBuild/mdwn2man44
-rw-r--r--BuildFlags.hs66
l---------CHANGELOG1
l---------COPYRIGHT1
-rw-r--r--Checks.hs49
-rw-r--r--CmdLine.hs138
-rw-r--r--Command.hs123
-rw-r--r--Command/Add.hs261
-rw-r--r--Command/AddUnused.hs41
-rw-r--r--Command/AddUrl.hs231
-rw-r--r--Command/Assistant.hs88
-rw-r--r--Command/Commit.hs29
-rw-r--r--Command/ConfigList.hs30
-rw-r--r--Command/Copy.hs39
-rw-r--r--Command/Dead.hs40
-rw-r--r--Command/Describe.hs32
-rw-r--r--Command/Direct.hs73
-rw-r--r--Command/Drop.hs161
-rw-r--r--Command/DropKey.hs39
-rw-r--r--Command/DropUnused.hs43
-rw-r--r--Command/EnableRemote.hs56
-rw-r--r--Command/Find.hs61
-rw-r--r--Command/Fix.hs61
-rw-r--r--Command/Forget.hs52
-rw-r--r--Command/FromKey.hs46
-rw-r--r--Command/Fsck.hs508
-rw-r--r--Command/FuzzTest.hs288
-rw-r--r--Command/GCryptSetup.hs39
-rw-r--r--Command/Get.hs90
-rw-r--r--Command/Group.hs35
-rw-r--r--Command/Help.hs62
-rw-r--r--Command/Import.hs104
-rw-r--r--Command/ImportFeed.hs218
-rw-r--r--Command/InAnnex.hs27
-rw-r--r--Command/Indirect.hs113
-rw-r--r--Command/Info.hs384
-rw-r--r--Command/Init.hs31
-rw-r--r--Command/InitRemote.hs98
-rw-r--r--Command/List.hs88
-rw-r--r--Command/Lock.hs29
-rw-r--r--Command/Log.hs171
-rw-r--r--Command/Map.hs247
-rw-r--r--Command/Merge.hs38
-rw-r--r--Command/Migrate.hs77
-rw-r--r--Command/Mirror.hs58
-rw-r--r--Command/Move.hs166
-rw-r--r--Command/PreCommit.hs57
-rw-r--r--Command/ReKey.hs71
-rw-r--r--Command/RecvKey.hs89
-rw-r--r--Command/Reinject.hs58
-rw-r--r--Command/Repair.hs71
-rw-r--r--Command/RmUrl.hs30
-rw-r--r--Command/Schedule.hs50
-rw-r--r--Command/Semitrust.hs32
-rw-r--r--Command/SendKey.hs49
-rw-r--r--Command/Status.hs89
-rw-r--r--Command/Sync.hs450
-rw-r--r--Command/Test.hs24
-rw-r--r--Command/TransferInfo.hs64
-rw-r--r--Command/TransferKey.hs59
-rw-r--r--Command/TransferKeys.hs142
-rw-r--r--Command/Trust.hs32
-rw-r--r--Command/Unannex.hs98
-rw-r--r--Command/Ungroup.hs35
-rw-r--r--Command/Uninit.hs100
-rw-r--r--Command/Unlock.hs50
-rw-r--r--Command/Untrust.hs32
-rw-r--r--Command/Unused.hs369
-rw-r--r--Command/Upgrade.hs28
-rw-r--r--Command/Version.hs48
-rw-r--r--Command/Vicfg.hs213
-rw-r--r--Command/Wanted.hs48
-rw-r--r--Command/Watch.hs36
-rw-r--r--Command/WebApp.hs226
-rw-r--r--Command/Whereis.hs54
-rw-r--r--Command/XMPPGit.hs43
-rw-r--r--Common.hs35
-rw-r--r--Common/Annex.hs8
-rw-r--r--Config.hs88
-rw-r--r--Config/Cost.hs82
-rw-r--r--Config/Files.hs69
-rw-r--r--Creds.hs147
-rw-r--r--Crypto.hs211
-rw-r--r--Fields.hs35
-rw-r--r--Git.hs140
-rw-r--r--Git/AutoCorrect.hs71
-rw-r--r--Git/Branch.hs133
-rw-r--r--Git/BuildVersion.hs21
-rw-r--r--Git/CatFile.hs108
-rw-r--r--Git/CheckAttr.hs93
-rw-r--r--Git/CheckIgnore.hs71
-rw-r--r--Git/Command.hs138
-rw-r--r--Git/Config.hs198
-rw-r--r--Git/Construct.hs236
-rw-r--r--Git/CurrentRepo.hs67
-rw-r--r--Git/DiffTree.hs102
-rw-r--r--Git/FileMode.hs23
-rw-r--r--Git/FilePath.hs64
-rw-r--r--Git/Filename.hs28
-rw-r--r--Git/Fsck.hs79
-rw-r--r--Git/GCrypt.hs103
-rw-r--r--Git/HashObject.hs46
-rw-r--r--Git/Hook.hs54
-rw-r--r--Git/Index.hs27
-rw-r--r--Git/LsFiles.hs214
-rw-r--r--Git/LsTree.hs65
-rw-r--r--Git/Merge.hs21
-rw-r--r--Git/Objects.hs35
-rw-r--r--Git/Queue.hs167
-rw-r--r--Git/Ref.hs133
-rw-r--r--Git/RefLog.hs22
-rw-r--r--Git/Remote.hs115
-rw-r--r--Git/Repair.hs551
-rw-r--r--Git/Sha.hs39
-rw-r--r--Git/SharedRepository.hs27
-rw-r--r--Git/Types.hs95
-rw-r--r--Git/UnionMerge.hs110
-rw-r--r--Git/UpdateIndex.hs86
-rw-r--r--Git/Url.hs71
-rw-r--r--Git/Version.hs43
-rw-r--r--GitAnnex.hs181
-rw-r--r--GitAnnex/Options.hs87
-rw-r--r--GitAnnexShell.hs200
l---------INSTALL1
-rw-r--r--Init.hs175
-rw-r--r--Limit.hs251
-rw-r--r--Limit/Wanted.hs21
-rw-r--r--Locations.hs412
-rw-r--r--Logs.hs114
-rw-r--r--Logs/FsckResults.hs43
-rw-r--r--Logs/Group.hs83
-rw-r--r--Logs/Location.hs63
-rw-r--r--Logs/PreferredContent.hs114
-rw-r--r--Logs/Presence.hs45
-rw-r--r--Logs/Presence/Pure.hs84
-rw-r--r--Logs/Remote.hs97
-rw-r--r--Logs/Schedule.hs72
-rw-r--r--Logs/Transfer.hs394
-rw-r--r--Logs/Transitions.hs86
-rw-r--r--Logs/Trust.hs97
-rw-r--r--Logs/Trust/Pure.hs36
-rw-r--r--Logs/UUID.hs96
-rw-r--r--Logs/UUIDBased.hs119
-rw-r--r--Logs/Unused.hs45
-rw-r--r--Logs/Web.hs95
-rw-r--r--Makefile228
-rw-r--r--Messages.hs245
-rw-r--r--Messages/JSON.hs37
l---------NEWS1
-rw-r--r--Option.hs79
-rw-r--r--README6
-rw-r--r--Remote.hs294
-rw-r--r--Remote/Bup.hs288
-rw-r--r--Remote/Directory.hs254
-rw-r--r--Remote/GCrypt.hs402
-rw-r--r--Remote/Git.hs489
-rw-r--r--Remote/Glacier.hs302
-rw-r--r--Remote/Helper/AWS.hs66
-rw-r--r--Remote/Helper/Chunked.hs144
-rw-r--r--Remote/Helper/Encryptable.hs164
-rw-r--r--Remote/Helper/Git.hs30
-rw-r--r--Remote/Helper/Hooks.hs94
-rw-r--r--Remote/Helper/Messages.hs17
-rw-r--r--Remote/Helper/Special.hs40
-rw-r--r--Remote/Helper/Ssh.hs146
-rw-r--r--Remote/Hook.hs159
-rw-r--r--Remote/List.hs107
-rw-r--r--Remote/Rsync.hs308
-rw-r--r--Remote/S3.hs345
-rw-r--r--Remote/Web.hs128
-rw-r--r--Remote/WebDAV.hs356
-rw-r--r--Seek.hs178
-rw-r--r--Setup.hs63
-rw-r--r--Test.hs1331
-rw-r--r--Types.hs31
-rw-r--r--Types/Backend.hs26
-rw-r--r--Types/BranchState.hs16
-rw-r--r--Types/Command.hs77
-rw-r--r--Types/Crypto.hs73
-rw-r--r--Types/Distribution.hs38
-rw-r--r--Types/FileMatcher.hs13
-rw-r--r--Types/GitConfig.hs157
-rw-r--r--Types/Group.hs27
-rw-r--r--Types/Key.hs96
-rw-r--r--Types/KeySource.hs29
-rw-r--r--Types/Limit.hs20
-rw-r--r--Types/Messages.hs24
-rw-r--r--Types/Option.hs17
-rw-r--r--Types/Remote.hs98
-rw-r--r--Types/ScheduledActivity.hs69
-rw-r--r--Types/StandardGroups.hs96
-rw-r--r--Types/TrustLevel.hs43
-rw-r--r--Types/UUID.hs24
-rw-r--r--Upgrade.hs58
-rw-r--r--Upgrade/V0.hs49
-rw-r--r--Upgrade/V1.hs241
-rw-r--r--Upgrade/V2.hs137
-rw-r--r--Upgrade/V4.hs23
-rw-r--r--Usage.hs111
-rw-r--r--Utility/Applicative.hs16
-rw-r--r--Utility/Base64.hs24
-rw-r--r--Utility/Batch.hs91
-rw-r--r--Utility/CoProcess.hs93
-rw-r--r--Utility/CopyFile.hs48
-rw-r--r--Utility/DBus.hs84
-rw-r--r--Utility/Daemon.hs124
-rw-r--r--Utility/Data.hs17
-rw-r--r--Utility/DataUnits.hs160
-rw-r--r--Utility/DirWatcher.hs157
-rw-r--r--Utility/DirWatcher/Types.hs24
-rw-r--r--Utility/Directory.hs107
-rw-r--r--Utility/DiskFree.hs38
-rw-r--r--Utility/Dot.hs63
-rw-r--r--Utility/Env.hs63
-rw-r--r--Utility/Exception.hs59
-rw-r--r--Utility/ExternalSHA.hs68
-rw-r--r--Utility/FSEvents.hs92
-rw-r--r--Utility/FileMode.hs142
-rw-r--r--Utility/FileSystemEncoding.hs93
-rw-r--r--Utility/Format.hs178
-rw-r--r--Utility/FreeDesktop.hs144
-rw-r--r--Utility/Gpg.hs379
-rw-r--r--Utility/Hash.hs69
-rw-r--r--Utility/HumanNumber.hs21
-rw-r--r--Utility/HumanTime.hs86
-rw-r--r--Utility/INotify.hs185
-rw-r--r--Utility/InodeCache.hs94
-rw-r--r--Utility/JSONStream.hs44
-rw-r--r--Utility/Kqueue.hs267
-rw-r--r--Utility/LogFile.hs68
-rw-r--r--Utility/Lsof.hs120
-rw-r--r--Utility/Matcher.hs169
-rw-r--r--Utility/Metered.hs116
-rw-r--r--Utility/Misc.hs153
-rw-r--r--Utility/Monad.hs69
-rw-r--r--Utility/Mounts.hsc93
-rw-r--r--Utility/Network.hs21
-rw-r--r--Utility/NotificationBroadcaster.hs86
-rw-r--r--Utility/OSX.hs44
-rw-r--r--Utility/Parallel.hs35
-rw-r--r--Utility/PartialPrelude.hs68
-rw-r--r--Utility/Path.hs254
-rw-r--r--Utility/Percentage.hs33
-rw-r--r--Utility/Process.hs356
-rw-r--r--Utility/QuickCheck.hs48
-rw-r--r--Utility/Quvi.hs133
-rw-r--r--Utility/Rsync.hs152
-rw-r--r--Utility/SRV.hs112
-rw-r--r--Utility/SafeCommand.hs120
-rw-r--r--Utility/Scheduled.hs350
-rw-r--r--Utility/Shell.hs26
-rw-r--r--Utility/TList.hs66
-rw-r--r--Utility/Tense.hs57
-rw-r--r--Utility/ThreadLock.hs19
-rw-r--r--Utility/ThreadScheduler.hs69
-rw-r--r--Utility/Tmp.hs88
-rw-r--r--Utility/Touch.hsc120
-rw-r--r--Utility/Url.hs190
-rw-r--r--Utility/UserInfo.hs55
-rw-r--r--Utility/Verifiable.hs37
-rw-r--r--Utility/WebApp.hs281
-rw-r--r--Utility/Win32Notify.hs65
-rw-r--r--Utility/Yesod.hs71
-rw-r--r--Utility/libdiskfree.c73
-rw-r--r--Utility/libdiskfree.h1
-rw-r--r--Utility/libkqueue.c74
-rw-r--r--Utility/libkqueue.h3
-rw-r--r--Utility/libmounts.c103
-rw-r--r--Utility/libmounts.h38
-rw-r--r--configure.hs6
-rw-r--r--debian/NEWS44
-rw-r--r--debian/changelog2542
-rw-r--r--debian/compat1
-rw-r--r--debian/control90
-rw-r--r--debian/copyright780
-rw-r--r--debian/doc-base9
-rw-r--r--debian/menu2
-rwxr-xr-xdebian/rules17
-rw-r--r--debian/tests/basics4
-rw-r--r--debian/tests/control4
-rw-r--r--doc/Android.mdwn53
-rw-r--r--doc/Android/comment_15_77bafc01b47d4cf8f96bde2b6704ed71._comment8
-rw-r--r--doc/Android/comment_19_dc7b428f525a082834cb87221fc627ff._comment8
-rw-r--r--doc/Android/comment_20_81940ea56ace3dcd5fa84dfccd88ad96._comment10
-rw-r--r--doc/Android/comment_29_37aa87a451d4390ed367402eec740855._comment12
-rw-r--r--doc/Android/comment_5_ba11b81c671d9bcd6f496fbd6f562b0f._comment16
-rw-r--r--doc/Android/oldcomments.mdwn2
-rw-r--r--doc/Android/oldcomments/comment_10_20e3d513b8b97496d76aca4619026cd6._comment16
-rw-r--r--doc/Android/oldcomments/comment_11_c96b8f1cc1583a74eb2483f48357f023._comment15
-rw-r--r--doc/Android/oldcomments/comment_12_6551f5fa081494b079c10a33c9b0d8ad._comment10
-rw-r--r--doc/Android/oldcomments/comment_13_7c633d245651ec08f63194fe1fc194ae._comment8
-rw-r--r--doc/Android/oldcomments/comment_14_60c2403140085f9caf48a33b59a36ab4._comment8
-rw-r--r--doc/Android/oldcomments/comment_16_9af73451be09f03cfff81fdf9481ffc4._comment27
-rw-r--r--doc/Android/oldcomments/comment_17_f76561a654b534df3a807b1c045710b2._comment8
-rw-r--r--doc/Android/oldcomments/comment_18_1b46cdf154ddadfe17e4b6e4054dc619._comment17
-rw-r--r--doc/Android/oldcomments/comment_1_cc9caa5dd22dd67e5c1d22d697096dd2._comment15
-rw-r--r--doc/Android/oldcomments/comment_21_5903f6a4a81a6534fa8cfafb3b6c37bb._comment8
-rw-r--r--doc/Android/oldcomments/comment_22_36afd354f9669a154d7b6b2c4d43ded9._comment8
-rw-r--r--doc/Android/oldcomments/comment_23_de98154792e8611a134429f06d82bcb1._comment8
-rw-r--r--doc/Android/oldcomments/comment_24_7ab509c25243009bfbffd796ec64e77b._comment10
-rw-r--r--doc/Android/oldcomments/comment_25_026d1a01d5753d71ac3dfc002f2a5eec._comment10
-rw-r--r--doc/Android/oldcomments/comment_26_f0a044fb649d43e32c96b08edbc336c3._comment12
-rw-r--r--doc/Android/oldcomments/comment_27_6b9ae35b1ceeba14cd7a74e142870705._comment34
-rw-r--r--doc/Android/oldcomments/comment_28_c91db1215f529aa68bfb0576c3c5eddc._comment10
-rw-r--r--doc/Android/oldcomments/comment_2_c2422b7dd9d526b3616e49f48cf178c2._comment10
-rw-r--r--doc/Android/oldcomments/comment_3_0e4980c27b13dbc28477c02a82898248._comment14
-rw-r--r--doc/Android/oldcomments/comment_4_86f7b5444e2eaea7f8f7b9160f671a1d._comment10
-rw-r--r--doc/Android/oldcomments/comment_5_9d78009435736a178d5a3f5a9bc0ed6a._comment8
-rw-r--r--doc/Android/oldcomments/comment_6_7b9523ddb20dc4a929e556c3ed0c7406._comment18
-rw-r--r--doc/Android/oldcomments/comment_7_a56628a622da752806c42c5b8b54ceef._comment8
-rw-r--r--doc/Android/oldcomments/comment_8_19656ec99b8f6aa64c1d01a3c9ae9bd0._comment8
-rw-r--r--doc/Android/oldcomments/comment_9_55e703ae105d0c0ee9ac50df8cc59dfb._comment10
-rw-r--r--doc/android/DCIM.pngbin0 -> 95786 bytes
-rw-r--r--doc/android/appinstalled.pngbin0 -> 16805 bytes
-rw-r--r--doc/android/apps.pngbin0 -> 53971 bytes
-rw-r--r--doc/android/install.pngbin0 -> 55106 bytes
-rw-r--r--doc/android/newwindow.pngbin0 -> 1009 bytes
-rw-r--r--doc/android/terminal.pngbin0 -> 20565 bytes
-rw-r--r--doc/android/webapp.pngbin0 -> 64097 bytes
-rw-r--r--doc/assistant.mdwn43
-rw-r--r--doc/assistant/addsshserver.pngbin0 -> 31740 bytes
-rw-r--r--doc/assistant/archival_walkthrough.mdwn32
-rw-r--r--doc/assistant/brokenrepositoryalert.pngbin0 -> 5806 bytes
-rw-r--r--doc/assistant/buddylist.pngbin0 -> 4347 bytes
-rw-r--r--doc/assistant/cloudnudge.pngbin0 -> 7332 bytes
-rw-r--r--doc/assistant/combinerepos.pngbin0 -> 10677 bytes
-rw-r--r--doc/assistant/comment_1_f2c4857b7b000e005f0c19279db14eaf._comment8
-rw-r--r--doc/assistant/comment_2_befa1f48e5a43a7965060491430a6bc4._comment9
-rw-r--r--doc/assistant/controlmenu.pngbin0 -> 8863 bytes
-rw-r--r--doc/assistant/crashrecovery.pngbin0 -> 6594 bytes
-rw-r--r--doc/assistant/dashboard.pngbin0 -> 41061 bytes
-rw-r--r--doc/assistant/deleterepository.pngbin0 -> 22780 bytes
-rw-r--r--doc/assistant/downloadupgrade.pngbin0 -> 9071 bytes
-rw-r--r--doc/assistant/encryptdrive.pngbin0 -> 42725 bytes
-rw-r--r--doc/assistant/example.pngbin0 -> 110994 bytes
-rw-r--r--doc/assistant/fsckconfig.pngbin0 -> 59050 bytes
-rw-r--r--doc/assistant/genkey.pngbin0 -> 27854 bytes
-rw-r--r--doc/assistant/iaitem.pngbin0 -> 34868 bytes
-rw-r--r--doc/assistant/inotify_max_limit_alert.pngbin0 -> 12583 bytes
-rw-r--r--doc/assistant/local_pairing_walkthrough.mdwn90
-rw-r--r--doc/assistant/local_pairing_walkthrough/addrepository.pngbin0 -> 2259 bytes
-rw-r--r--doc/assistant/local_pairing_walkthrough/comment_1_b33deed054d3aa8cfa6c9e3958643f16._comment8
-rw-r--r--doc/assistant/local_pairing_walkthrough/comment_2_39f1162b4d43b61e957e7497df4b9e2b._comment8
-rw-r--r--doc/assistant/local_pairing_walkthrough/comment_3_588869692b290483f58f3a7aa2bfb55f._comment17
-rw-r--r--doc/assistant/local_pairing_walkthrough/comment_4_f6bf82c263fefe38701709d9dbd974cc._comment10
-rw-r--r--doc/assistant/local_pairing_walkthrough/comment_5_bada601ea4b7104f162a3e00def4be2b._comment19
-rw-r--r--doc/assistant/local_pairing_walkthrough/comment_6_01ba0f9bfa0ed066c4b73d2d6028eecc._comment8
-rw-r--r--doc/assistant/local_pairing_walkthrough/comment_7_17d44229e4fa46c50815672b96a9735a._comment10
-rw-r--r--doc/assistant/local_pairing_walkthrough/comment_8_b9d4c29cf2cca0427808df6af08fb789._comment8
-rw-r--r--doc/assistant/local_pairing_walkthrough/pairing.pngbin0 -> 6771 bytes
-rw-r--r--doc/assistant/local_pairing_walkthrough/pairrequest.pngbin0 -> 5383 bytes
-rw-r--r--doc/assistant/local_pairing_walkthrough/secret.pngbin0 -> 5132 bytes
-rw-r--r--doc/assistant/local_pairing_walkthrough/secretempty.pngbin0 -> 9575 bytes
-rw-r--r--doc/assistant/logs.pngbin0 -> 33631 bytes
-rw-r--r--doc/assistant/makerepo.pngbin0 -> 32061 bytes
-rw-r--r--doc/assistant/menu.pngbin0 -> 22921 bytes
-rw-r--r--doc/assistant/osx-app.pngbin0 -> 2604 bytes
-rw-r--r--doc/assistant/preferences.pngbin0 -> 22815 bytes
-rw-r--r--doc/assistant/quickstart.mdwn30
-rw-r--r--doc/assistant/release_notes.mdwn365
-rw-r--r--doc/assistant/release_notes/comment_1_bd8f376c9d0c1d5ed07fb013907a60ee._comment14
-rw-r--r--doc/assistant/release_notes/comment_2_75e0774ad042717fbd059a8a9ec2db1e._comment12
-rw-r--r--doc/assistant/release_notes/comment_3_b3bfd8e547e20c51f7c32c6c9424e936._comment10
-rw-r--r--doc/assistant/release_notes/comment_4_c6caa2b521b456bb4ce594d64919cffe._comment8
-rw-r--r--doc/assistant/remote_sharing_walkthrough.mdwn12
-rw-r--r--doc/assistant/remote_sharing_walkthrough/comment_1_e0187b0a926904b363065ab0f850f0b2._comment10
-rw-r--r--doc/assistant/remote_sharing_walkthrough/comment_2_dabcbc9aaf0bdb82716f5a5d55807a21._comment8
-rw-r--r--doc/assistant/remote_sharing_walkthrough/comment_4_978fab3cd165b4ca245e32fc48cf0970._comment8
-rw-r--r--doc/assistant/remote_sharing_walkthrough/comment_4_d7e879f7b098964040df2e27a18eda72._comment18
-rw-r--r--doc/assistant/remote_sharing_walkthrough/comment_5_00852736d47c05772b15c5ff54ae7da7._comment8
-rw-r--r--doc/assistant/repairrepository.pngbin0 -> 31791 bytes
-rw-r--r--doc/assistant/repogroups.pngbin0 -> 15636 bytes
-rw-r--r--doc/assistant/repoinfo.pngbin0 -> 7603 bytes
-rw-r--r--doc/assistant/repositories.pngbin0 -> 63405 bytes
-rw-r--r--doc/assistant/rsync.net.encryption.pngbin0 -> 40504 bytes
-rw-r--r--doc/assistant/rsync.net.pngbin0 -> 61465 bytes
-rw-r--r--doc/assistant/running.pngbin0 -> 24664 bytes
-rw-r--r--doc/assistant/share_with_a_friend_walkthrough.mdwn58
-rw-r--r--doc/assistant/share_with_a_friend_walkthrough/buddylist.pngbin0 -> 5114 bytes
-rw-r--r--doc/assistant/share_with_a_friend_walkthrough/pairing.pngbin0 -> 6892 bytes
-rw-r--r--doc/assistant/share_with_a_friend_walkthrough/repolist.pngbin0 -> 8525 bytes
-rw-r--r--doc/assistant/share_with_a_friend_walkthrough/xmppalert.pngbin0 -> 4070 bytes
-rw-r--r--doc/assistant/thanks.mdwn243
-rw-r--r--doc/assistant/thumbnail.pngbin0 -> 3491 bytes
-rw-r--r--doc/assistant/upgradecomplete.pngbin0 -> 4817 bytes
-rw-r--r--doc/assistant/xmpp.pngbin0 -> 27753 bytes
-rw-r--r--doc/assistant/xmppnudge.pngbin0 -> 6156 bytes
-rw-r--r--doc/assistant/xmpppairingend.pngbin0 -> 34379 bytes
-rw-r--r--doc/automatic_conflict_resolution.mdwn23
-rw-r--r--doc/backends.mdwn42
-rw-r--r--doc/backends/comment_1_375bb1fb5973e8fa67b763f2dd6e404b._comment13
-rw-r--r--doc/backends/comment_2_1f2626eca9004b31a0b7fc1a0df8027b._comment24
-rw-r--r--doc/backends/comment_3_fdcbf8727fdefb9942a54689234b9698._comment12
-rw-r--r--doc/backends/comment_4_46591a3ba888fb686b1b319b80ca2c22._comment9
-rw-r--r--doc/backends/comment_5_2210c7ff2d5812fb3b778ac172291656._comment8
-rw-r--r--doc/backends/comment_6_82f239b58680a2681bd8074c7ef9584d._comment8
-rw-r--r--doc/bare_repositories.mdwn48
-rw-r--r--doc/bare_repositories/comment_1_148e1da70d37d311634a0309a4ff8dcd._comment22
-rw-r--r--doc/bugs.mdwn18
-rw-r--r--doc/bugs/127.0.0.1_references_on_remote_assistant_access.mdwn20
-rw-r--r--doc/bugs/3.20121112:_build_error_in_assistant.mdwn432
-rw-r--r--doc/bugs/3.20121112:_build_error_in_assistant/comment_1_b42f40ffd83321ab5cc0ef24ced15e98._comment8
-rw-r--r--doc/bugs/3.20121112:_build_error_in_assistant/comment_2_b1d2aa10ea84c5c370b3e76507fc8761._comment476
-rw-r--r--doc/bugs/3.20121112:_build_error_in_assistant/comment_3_b38e40d36bba95b16afbce68e7f25a80._comment8
-rw-r--r--doc/bugs/3.20121112_build_fails_on_Ubuntu_12.04.mdwn97
-rw-r--r--doc/bugs/3.20121112_build_fails_on_Ubuntu_12.04/comment_1_ce2efd2196e7682f4cdbabdb0616d449._comment8
-rw-r--r--doc/bugs/3.20121112_build_fails_on_Ubuntu_12.04/comment_2_2a6faf662ebb85a8f1c89adcdfb9adb6._comment10
-rw-r--r--doc/bugs/3.20121112_build_fails_on_Ubuntu_12.04/comment_3_37f34baa34068def1adf794d0942e462._comment8
-rw-r--r--doc/bugs/3.20121112_build_fails_on_Ubuntu_12.04/comment_4_2f8a859fef9edc8eb93bf1cc74296702._comment8
-rw-r--r--doc/bugs/3.20121113_build_error___39__not_in_scope_getAddBoxComR__39__.mdwn33
-rw-r--r--doc/bugs/4.20130227_won__39__t_build_on_OS_X_Lion__44___because_testpack_won__39__t_build.mdwn57
-rw-r--r--doc/bugs/4.20130227_won__39__t_build_on_OS_X_Lion__44___because_testpack_won__39__t_build/comment_1_b7140e2bf1ea9c73ecc9e214095968e7._comment8
-rw-r--r--doc/bugs/4.20130227_won__39__t_build_on_OS_X_Lion__44___because_testpack_won__39__t_build/comment_2_6be87b2fb2ed828e7b4bf785729e910e._comment9
-rw-r--r--doc/bugs/4.20130601_xmpp_sync_error.mdwn125
-rw-r--r--doc/bugs/4.20130601_xmpp_sync_error/comment_1_5b50d97e44cbd5b31ff24537ec3f8603._comment14
-rw-r--r--doc/bugs/400_mode_leakage.mdwn25
-rw-r--r--doc/bugs/Add_another_repository_on_USB_drive_causes_sync_loop.mdwn22
-rw-r--r--doc/bugs/Add_another_repository_on_USB_drive_causes_sync_loop/comment_1_81839a6de7450734ee75b51e47a0898e._comment10
-rw-r--r--doc/bugs/Add_another_repository_on_USB_drive_causes_sync_loop/comment_2_907ce31a31df94984c2bd7aaafe5b10b._comment8
-rw-r--r--doc/bugs/Add_another_repository_on_USB_drive_causes_sync_loop/comment_3_d8a86ae0ae5fa1f91e0b40b8b2ba0406._comment10
-rw-r--r--doc/bugs/Add_another_repository_on_USB_drive_causes_sync_loop/comment_4_1f08fd5dd4f5d8723c2b5391cc3b60f9._comment22
-rw-r--r--doc/bugs/Adding_a_repository_as_a___34__remote_server__34___creates_a_bare_repository_next_to_the_existing_one.mdwn21
-rw-r--r--doc/bugs/Adding_a_repository_as_a___34__remote_server__34___creates_a_bare_repository_next_to_the_existing_one/comment_1_cb781d34889d583663e855c4074f8e0e._comment16
-rw-r--r--doc/bugs/Adding_a_repository_as_a___34__remote_server__34___creates_a_bare_repository_next_to_the_existing_one/comment_2_c0c87957d7c7a09664e60571a2ca0e8c._comment12
-rw-r--r--doc/bugs/Adding_box.com_remote_on_Android_fails_for_me.mdwn20
-rw-r--r--doc/bugs/Adding_box.com_remote_on_Android_fails_for_me/comment_1_0303ce880415d7e043533551c2b24694._comment10
-rw-r--r--doc/bugs/Adding_git_ssh_remote_fails.mdwn32
-rw-r--r--doc/bugs/Adding_git_ssh_remote_fails/comment_1_05c0bd9ac7c6f0045217fd72fc1f0a1b._comment10
-rw-r--r--doc/bugs/Adding_git_ssh_remote_fails/comment_2_df05456cafdd89e8ceea830199f42d45._comment10
-rw-r--r--doc/bugs/Adding_second_remote_repository_over_ssh_fails.mdwn41
-rw-r--r--doc/bugs/Adding_second_remote_repository_over_ssh_fails/comment_1_308d5f517bf00c8edc53db438de52355._comment14
-rw-r--r--doc/bugs/Adding_unencrypted_repo_on_drive_in_webapp_gives_internal_server_error__.mdwn69
-rw-r--r--doc/bugs/Addurl_downloads_but_does_not_checkout_files.mdwn74
-rw-r--r--doc/bugs/Allow_syncing_to_a_specific_directory_on_a_USB_remote.mdwn30
-rw-r--r--doc/bugs/Allow_syncing_to_a_specific_directory_on_a_USB_remote/comment_1_13ecedfbb34c3564af3a790b8bf0f591._comment25
-rw-r--r--doc/bugs/Android:_Clocking_on___34__Files__34___in_the_Dashboard_seems_to_do_nothing.mdwn21
-rw-r--r--doc/bugs/Android:_Clocking_on___34__Files__34___in_the_Dashboard_seems_to_do_nothing/comment_1_a9b03d4f4760fea2754a4dc93547f0a3._comment10
-rw-r--r--doc/bugs/Android:_Clocking_on___34__Files__34___in_the_Dashboard_seems_to_do_nothing/comment_2_015e859a16b1ce4c0c7601df0594d555._comment10
-rw-r--r--doc/bugs/Android___34__This_build_of_git-annex_does_not_support_XMPP_pairing__34__.mdwn24
-rw-r--r--doc/bugs/Android___34__This_build_of_git-annex_does_not_support_XMPP_pairing__34__/comment_1_c034bb84e58b2dda1038ba205ec78c56._comment273
-rw-r--r--doc/bugs/Android___34__This_build_of_git-annex_does_not_support_XMPP_pairing__34__/comment_2_99a754f41d59fdd401ba6d169945e7c9._comment8
-rw-r--r--doc/bugs/Android_app_permission_denial_on_startup.mdwn18
-rw-r--r--doc/bugs/Android_app_permission_denial_on_startup/comment_10_dc06737997c8883ef0a12dbecd9ac30f._comment8
-rw-r--r--doc/bugs/Android_app_permission_denial_on_startup/comment_11_b444cd6717658116533745c51481dd3d._comment8
-rw-r--r--doc/bugs/Android_app_permission_denial_on_startup/comment_12_66181f34ed7496d1f6601b39e5ae3c65._comment13
-rw-r--r--doc/bugs/Android_app_permission_denial_on_startup/comment_1_ddf5761bf14de30ac97030ad338601ae._comment14
-rw-r--r--doc/bugs/Android_app_permission_denial_on_startup/comment_2_8b9fafa73ebf5f803c7da9531cfb5b34._comment10
-rw-r--r--doc/bugs/Android_app_permission_denial_on_startup/comment_3_58501bb043b4c5836d7472ffd6baa72c._comment23
-rw-r--r--doc/bugs/Android_app_permission_denial_on_startup/comment_4_d3a04dc7bbc1816cccc8d85c73ffb689._comment8
-rw-r--r--doc/bugs/Android_app_permission_denial_on_startup/comment_5_eeabbc0cc434ed84c36a3f4e03fcef36._comment10
-rw-r--r--doc/bugs/Android_app_permission_denial_on_startup/comment_6_4203b496bee1bdd424466ed63b5d31cf._comment10
-rw-r--r--doc/bugs/Android_app_permission_denial_on_startup/comment_7_74373eb2cc46b76659e3c463d6682d15._comment10
-rw-r--r--doc/bugs/Android_app_permission_denial_on_startup/comment_8_0923d2a09df01d152ec4784c92689c96._comment8
-rw-r--r--doc/bugs/Android_app_permission_denial_on_startup/comment_9_b60928e54a5b620899cf29820b9b8e70._comment10
-rw-r--r--doc/bugs/Android_daily_build_missing_webapp.mdwn23
-rw-r--r--doc/bugs/Annex_thinks_file_exists_afer_being_dropped.mdwn27
-rw-r--r--doc/bugs/Annex_thinks_file_exists_afer_being_dropped/comment_1_1d100441fd1ef529eb854b350fece9ee._comment29
-rw-r--r--doc/bugs/Annex_thinks_file_exists_afer_being_dropped/comment_2_166c459c2b27859cf457e17da685fe75._comment14
-rw-r--r--doc/bugs/Annex_thinks_file_exists_afer_being_dropped/comment_3_9d985b6e7973bfaaf8b4f5349d8c13ee._comment8
-rw-r--r--doc/bugs/Annex_thinks_file_exists_afer_being_dropped/comment_4_3e084cff454b95c7170c0225a53f0c30._comment11
-rw-r--r--doc/bugs/Assistant_does_not_actually_check_newly_annex-added_files_into_git_until_daily_sanity_check.mdwn106
-rw-r--r--doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default.mdwn16
-rw-r--r--doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default/comment_1_8577fdaa4d49e6241c4372b159694c9c._comment12
-rw-r--r--doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default/comment_2_027521e48283c68b39315bb8213f6e45._comment10
-rw-r--r--doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default/comment_3_fd8f6938596aace60b04fb35c4069e37._comment10
-rw-r--r--doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default/comment_4_ca908021ab5a2a50fd0d4a7e8d12498f._comment9
-rw-r--r--doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default/comment_5_73532556cfc354ad5f37a3f3a048fb32._comment12
-rw-r--r--doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default/comment_6_ced397b9e6119a0798a282ee07e885df._comment61
-rw-r--r--doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default/comment_7_8acb66850e5db8337cf3f2b2dd236ccc._comment10
-rw-r--r--doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default/comment_8_7eb530851ae6fa1a69813725c4e8fcec._comment59
-rw-r--r--doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default/comment_9_c7d51a26e1febc3894d02546940d64e5._comment19
-rw-r--r--doc/bugs/Assistant_dropping_files_it_has_just_transferred_elsewhere_again.mdwn26
-rw-r--r--doc/bugs/Assistant_dropping_from_backup_repo.mdwn28
-rw-r--r--doc/bugs/Assistant_dropping_from_backup_repo/comment_1_c13d86fb2541676ee4ca1446b99e0e68._comment8
-rw-r--r--doc/bugs/Assistant_enters_eternal_loop_and_eats_up_all_of_RAM_after_X_restart.mdwn24
-rw-r--r--doc/bugs/Assistant_has_created_155_semitrusted_repositories.mdwn191
-rw-r--r--doc/bugs/Assistant_has_created_155_semitrusted_repositories/comment_1_169b24b34cce3f5c8446c2150beb6827._comment8
-rw-r--r--doc/bugs/Assistant_has_created_155_semitrusted_repositories/comment_2_6acd6f38297772a07d8d5fb999bd2eaa._comment183
-rw-r--r--doc/bugs/Assistant_has_created_155_semitrusted_repositories/comment_3_6a4118e5c5fbe5e84d27094ac72b741b._comment22
-rw-r--r--doc/bugs/Assistant_has_created_155_semitrusted_repositories/comment_4_04daa20d5d7c74bb34ec48e752ed9fe8._comment8
-rw-r--r--doc/bugs/Assistant_has_created_155_semitrusted_repositories/comment_5_11af8ab2587e6eeb671051ba8191995b._comment11
-rw-r--r--doc/bugs/Assistant_has_created_155_semitrusted_repositories/comment_6_26236cdc2bce532017854791bcd727d1._comment8
-rw-r--r--doc/bugs/Assistant_has_created_155_semitrusted_repositories/comment_7_3c532dd5b8a01ecdeda1300b49aba675._comment12
-rw-r--r--doc/bugs/Assistant_has_created_155_semitrusted_repositories/comment_8_119142c5ebc499f0ee0926dbca265308._comment10
-rw-r--r--doc/bugs/Assistant_redirects_to_127.0.0.1_in_some_cases__44___although_used_remotely.mdwn29
-rw-r--r--doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux.mdwn75
-rw-r--r--doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_10_ec4a7388ea7106a953f599b664b37f1d._comment8
-rw-r--r--doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_1_6a60c23850a5e2a7bba355e1317abc69._comment13
-rw-r--r--doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_2_90b6ed232b2917b9fe041532284e1212._comment10
-rw-r--r--doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_3_5a89d79395d96c43d7d8a6fd9dc275f1._comment248
-rw-r--r--doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_4_cdd26c71875428dbe3c100944a443d3f._comment9
-rw-r--r--doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_5_76242f5d6c815acd5bd58213bd8bb0fe._comment10
-rw-r--r--doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_6_10852171c0207ca61ea6df1082107353._comment8
-rw-r--r--doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_7_73e8a5696709f8154e63693ba5e569c3._comment10
-rw-r--r--doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_8_392fc344e5833b0eb665fcd38f956b7a._comment8
-rw-r--r--doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_9_9f0fc19a7fcaf7a5827e59e1495cf8c9._comment8
-rw-r--r--doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor.mdwn28
-rw-r--r--doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_10_0e1db417a5815ea903c1f7ccd07308c4._comment8
-rw-r--r--doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_1_28b0cfcba8902c9c16dbe6c4b07984c4._comment10
-rw-r--r--doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_2_952b3f78da756ff5f89235db94bec67f._comment53
-rw-r--r--doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_3_d86aba42d014c4b4f708dcb5fe86e055._comment10
-rw-r--r--doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_4_9aaf296ef53da317d6dc6728705d5c56._comment16
-rw-r--r--doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_5_0d5f8a05a1505660f7ff1bc4ac6ff271._comment8
-rw-r--r--doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_6_3dfdfd49597c85575cb689adb70d2de6._comment8
-rw-r--r--doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_7_943a446c60ed9d7d4f240ba7f00fe925._comment8
-rw-r--r--doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_8_9563859850fb40b1cc2c20c516c12960._comment16
-rw-r--r--doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_9_cf6221c585ee3dbf039bdaea71842d9b._comment9
-rw-r--r--doc/bugs/Browser_fails_to_launch_on_Android___39__git_annex_webapp__39__.mdwn35
-rw-r--r--doc/bugs/Browser_fails_to_launch_on_Android___39__git_annex_webapp__39__/comment_1_173393b0b3d2d8c622c0d8a2eaace421._comment8
-rw-r--r--doc/bugs/Build-depends_needs___39__hxt__39___added_-_3.20121127.mdwn36
-rw-r--r--doc/bugs/Build_error_on_Linux.mdwn29
-rw-r--r--doc/bugs/Build_error_on_Mac_OSX_10.6.mdwn11
-rw-r--r--doc/bugs/Build_failure_at_commit_1efe4f3.mdwn45
-rw-r--r--doc/bugs/Building_fails:_Could_not_find_module___96__Text.Blaze__39__.mdwn105
-rw-r--r--doc/bugs/Building_fails:_Not_in_scope:___96__myHomeDir__39___.mdwn56
-rw-r--r--doc/bugs/Building_fails:__Could_not_find_module___96__Data.XML.Types__39__.mdwn82
-rw-r--r--doc/bugs/Building_fails:___Not_in_scope:_type_constructor_or_class___96__Html__39__.mdwn189
-rw-r--r--doc/bugs/Building_in_cabal_using_--bindir___126____47__bin_breaks_the_desktop_link.mdwn15
-rw-r--r--doc/bugs/Building_in_cabal_using_--bindir___126____47__bin_breaks_the_desktop_link/comment_1_c0f0a2878070ed86900815c6b6a5fa5e._comment8
-rw-r--r--doc/bugs/Building_in_cabal_using_--bindir___126____47__bin_breaks_the_desktop_link/comment_2_53f2de3d3993821d8502fd08a0fcce12._comment8
-rw-r--r--doc/bugs/Cabal_cannot_solve_dependencies.mdwn36
-rw-r--r--doc/bugs/Cabal_cannot_solve_dependencies/comment_1_1d41ac79867226dcb71f1c7b38da062d._comment21
-rw-r--r--doc/bugs/Cabal_cannot_solve_dependencies/comment_2_50e72633a4462f6f6eb33d57b137fdcc._comment48
-rw-r--r--doc/bugs/Cabal_cannot_solve_dependencies/comment_3_886f2d1f7c47a3973b8dc7d7c412289a._comment10
-rw-r--r--doc/bugs/Cabal_dependency_monadIO_missing.mdwn17
-rw-r--r--doc/bugs/Cabal_dependency_monadIO_missing/comment_1_14be660aa57fadec0d81b32a8b52c66f._comment75
-rw-r--r--doc/bugs/Cabal_dependency_monadIO_missing/comment_2_4f4d8e1e00a2a4f7e8a8ab082e16adac._comment8
-rw-r--r--doc/bugs/Calls_to_rsync_don__39__t_always_use__annex-rsync-options.mdwn35
-rw-r--r--doc/bugs/Can__39__t___34__git-annex_get__34___with_3.20111203.mdwn27
-rw-r--r--doc/bugs/Can__39__t_access_files_from___39__Removable_drive__39___repo_even_if_set_as_client.mdwn21
-rw-r--r--doc/bugs/Can__39__t_access_files_from___39__Removable_drive__39___repo_even_if_set_as_client/comment_1_25eb2d7d0a9cdd1c55df0cec68472723._comment10
-rw-r--r--doc/bugs/Can__39__t_access_files_from___39__Removable_drive__39___repo_even_if_set_as_client/comment_2_9e9b96e5113a50533251e946c2560d81._comment17
-rw-r--r--doc/bugs/Can__39__t_access_files_from___39__Removable_drive__39___repo_even_if_set_as_client/comment_3_6b091198ddd6ed709b076df1296aeb77._comment11
-rw-r--r--doc/bugs/Can__39__t_access_files_from___39__Removable_drive__39___repo_even_if_set_as_client/comment_4_118b588685b535cca4c02eb6ef297c67._comment21
-rw-r--r--doc/bugs/Can__39__t_access_files_from___39__Removable_drive__39___repo_even_if_set_as_client/comment_5_5cead277493e1c020e16be6f9245fe33._comment12
-rw-r--r--doc/bugs/Can__39__t_access_files_from___39__Removable_drive__39___repo_even_if_set_as_client/comment_6_0f135f97c2808dce094628dc6608e617._comment8
-rw-r--r--doc/bugs/Can__39__t_access_files_from___39__Removable_drive__39___repo_even_if_set_as_client/comment_7_1d6f47f9e6cf935f19d68af6d5aa92fa._comment10
-rw-r--r--doc/bugs/Can__39__t_access_files_from___39__Removable_drive__39___repo_even_if_set_as_client/comment_8_c5758fdb32348b9cd804ff17d27864e1._comment16
-rw-r--r--doc/bugs/Can__39__t_add_a_git_repo_to_git_annex:___34__Invalid_path_repo__47__.git__47__X__34___for_many_X.mdwn34
-rw-r--r--doc/bugs/Can__39__t_add_a_git_repo_to_git_annex:___34__Invalid_path_repo__47__.git__47__X__34___for_many_X/comment_1_7f54e24c8e721d69bdb1e5a4181641b8._comment10
-rw-r--r--doc/bugs/Can__39__t_add_a_git_repo_to_git_annex:___34__Invalid_path_repo__47__.git__47__X__34___for_many_X/comment_2_6e91bc254f79ccf80d385ba7d35ffa9c._comment14
-rw-r--r--doc/bugs/Can__39__t_add_a_git_repo_to_git_annex:___34__Invalid_path_repo__47__.git__47__X__34___for_many_X/comment_3_4cf34da6050dd96f94ffc3652aa39715._comment12
-rw-r--r--doc/bugs/Can__39__t_add_a_git_repo_to_git_annex:___34__Invalid_path_repo__47__.git__47__X__34___for_many_X/comment_4_cafcc24e98a89f10adaed5e09f75b659._comment19
-rw-r--r--doc/bugs/Can__39__t_add_a_git_repo_to_git_annex:___34__Invalid_path_repo__47__.git__47__X__34___for_many_X/comment_5_118d61dea9ef0faa2960da6f2f62ec8b._comment12
-rw-r--r--doc/bugs/Can__39__t_add_a_git_repo_to_git_annex:___34__Invalid_path_repo__47__.git__47__X__34___for_many_X/comment_6_3978557c6e85608243e5b4eb698ac5a5._comment27
-rw-r--r--doc/bugs/Can__39__t_add_a_git_repo_to_git_annex:___34__Invalid_path_repo__47__.git__47__X__34___for_many_X/comment_7_e6dfc41d2042402b40efb6f6139d5662._comment18
-rw-r--r--doc/bugs/Can__39__t_add_a_git_repo_to_git_annex:___34__Invalid_path_repo__47__.git__47__X__34___for_many_X/comment_8_33a84937c87dd2406bc090a0d2969683._comment30
-rw-r--r--doc/bugs/Can__39__t_clone_on_Windows_because_some_filenames_have_a_colon_in_them.mdwn20
-rw-r--r--doc/bugs/Can__39__t_clone_on_Windows_because_some_filenames_have_a_colon_in_them/comment_1_5fc1347f4bcc13c9f8dbc5ecd4847fc7._comment12
-rw-r--r--doc/bugs/Can__39__t_clone_on_Windows_because_some_filenames_have_a_colon_in_them/comment_2_38696178e658d1d32deec37dbea66a3d._comment8
-rw-r--r--doc/bugs/Can__39__t_clone_on_Windows_because_some_filenames_have_a_colon_in_them/comment_3_f34d996827f5e7662bec409cbcce961b._comment12
-rw-r--r--doc/bugs/Can__39__t_rename___34__here__34___repository.mdwn32
-rw-r--r--doc/bugs/Can__39__t_set_repositories_directory.mdwn15
-rw-r--r--doc/bugs/Can__39__t_set_repositories_directory/comment_1_beb5d5b66a8d0fab12be44a7d877e9b0._comment8
-rw-r--r--doc/bugs/Can__39__t_set_repositories_directory/comment_2_366aa798a5e55350d32b63b31c19112b._comment19
-rw-r--r--doc/bugs/Can__39__t_set_repositories_directory/comment_3_812554d58ad9274a50b2a33d5f4d2ec3._comment10
-rw-r--r--doc/bugs/Can__39__t_set_repositories_directory/comment_4_bec5f147441ad18c97845b44c90c728b._comment28
-rw-r--r--doc/bugs/Can__39__t_start_on_Cyanogenmod_10.2_nightly.mdwn158
-rw-r--r--doc/bugs/Can__39__t_transfer_files_to_rsync_remote_with_encryption__61__shared.mdwn54
-rw-r--r--doc/bugs/Can__39__t_transfer_files_to_rsync_remote_with_encryption__61__shared/comment_1_ca7ec2041bbec330476fb040b1e66a92._comment8
-rw-r--r--doc/bugs/Can__39__t_transfer_files_to_rsync_remote_with_encryption__61__shared/comment_2_c476847665a5320214721497d8fad15b._comment8
-rw-r--r--doc/bugs/Cannot_build_the_latest_with_GHC_7.6.1.mdwn18
-rw-r--r--doc/bugs/Cannot_build_the_latest_with_GHC_7.6.1/comment_1_b25859c159d62f2e92b92f505535131b._comment14
-rw-r--r--doc/bugs/Cannot_build_the_latest_with_GHC_7.6.1/comment_2_4c9eab9120718457fdc1ae9051e44bca._comment16
-rw-r--r--doc/bugs/Cannot_build_the_latest_with_GHC_7.6.1/comment_3_61aec9801e1f76db4a286536ffacc3ed._comment12
-rw-r--r--doc/bugs/Cannot_build_the_latest_with_GHC_7.6.1/comment_4_6381ff0ea419831d9bbed27511cad1e9._comment16
-rw-r--r--doc/bugs/Cannot_clone_an_annex.mdwn69
-rw-r--r--doc/bugs/Cannot_clone_an_annex/comment_1_b40a2652361a79c6c6eab0fc21be8e46._comment8
-rw-r--r--doc/bugs/Cannot_copy_to_a_git-annex_remote.mdwn14
-rw-r--r--doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_10_258a376cff4c62bc4be919322bb1bd88._comment10
-rw-r--r--doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_10_d9b830a1fdea8760cb7da1d36b3cd34d._comment12
-rw-r--r--doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_1_09d76e5f9480b9a35644a8f08790cd97._comment10
-rw-r--r--doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_2_7b586c705a937d09a1b44bd6af2d4686._comment8
-rw-r--r--doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_3_07dbd8f64982f1921077e23f468122cf._comment25
-rw-r--r--doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_4_926fd494f0b27103a99083cd5d0702d5._comment8
-rw-r--r--doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_5_80444a509cc340f5eb3cd08b193fd389._comment10
-rw-r--r--doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_6_4c6b99cd67b4aa742da5101fb1b379f7._comment8
-rw-r--r--doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_8_f45cdd2b6acc5f458b67539fced0e529._comment12
-rw-r--r--doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_9_5a455dd14fb9d3ff408bb3f81e366c38._comment10
-rw-r--r--doc/bugs/Cannot_sync_repos_setup_using_webapp:___34__git-annex-shell:_Only_allowed_to_access___126____47__foo_not___126____47__bar__47____34__.mdwn29
-rw-r--r--doc/bugs/Cannot_sync_repos_setup_using_webapp:___34__git-annex-shell:_Only_allowed_to_access___126____47__foo_not___126____47__bar__47____34__/comment_1_6f7b5c164ff64f00b8814b2ee334709f._comment13
-rw-r--r--doc/bugs/Cannot_sync_repos_setup_using_webapp:___34__git-annex-shell:_Only_allowed_to_access___126____47__foo_not___126____47__bar__47____34__/comment_2_807ef1250237bf4426e3a24c1f9ba357._comment10
-rw-r--r--doc/bugs/Committer_crashed.mdwn32
-rw-r--r--doc/bugs/Compile_needs_more_than_1.5gb_of_memory.mdwn16
-rw-r--r--doc/bugs/Compile_needs_more_than_1.5gb_of_memory/comment_1_0806b5132c55d7a5a17fbdad7e3f2291._comment16
-rw-r--r--doc/bugs/Complete_failure_trying_to_unannex_a_large_annex.mdwn56
-rw-r--r--doc/bugs/Complete_failure_trying_to_unannex_a_large_annex/comment_1_1c202695ab7fe62cdc8770e1fb428d0c._comment10
-rw-r--r--doc/bugs/Conflicting_archive_descriptions.mdwn16
-rw-r--r--doc/bugs/ControlPath_too_long_for_Unix_domain_socket.mdwn53
-rw-r--r--doc/bugs/ControlPath_too_long_for_Unix_domain_socket/comment_1_60f58e205604eebe668b1e05dcfbf9a7._comment24
-rw-r--r--doc/bugs/Corrupted_drive:_Assistant_seems_consider_files_deleted_and_deletes_them_elsewhere_too.mdwn33
-rw-r--r--doc/bugs/Corrupted_drive:_Assistant_seems_consider_files_deleted_and_deletes_them_elsewhere_too/comment_1_80ca50f5305eda71fe32f2b0bc922c34._comment21
-rw-r--r--doc/bugs/Corrupted_drive:_Assistant_seems_consider_files_deleted_and_deletes_them_elsewhere_too/comment_2_e6bc6d1c0eb8c469e9e00b37bbcc9b86._comment9
-rw-r--r--doc/bugs/Corrupted_drive:_Assistant_seems_consider_files_deleted_and_deletes_them_elsewhere_too/comment_5_0d0f6b6b46d0153433fead2bbd1bbe64._comment12
-rw-r--r--doc/bugs/Corrupted_drive:_Assistant_seems_consider_files_deleted_and_deletes_them_elsewhere_too/comment_5_6058a22b733cb02126286af950074ed4._comment10
-rw-r--r--doc/bugs/Corrupted_drive:_Assistant_seems_consider_files_deleted_and_deletes_them_elsewhere_too/comment_6_593a49669e2fadfb91773f8c84fbb031._comment8
-rw-r--r--doc/bugs/Corrupted_drive:_Assistant_seems_consider_files_deleted_and_deletes_them_elsewhere_too/comment_6_5a348c5f327f16e1192ef6bd7f2880bb._comment15
-rw-r--r--doc/bugs/Could_not_find_module_Data.Default.mdwn33
-rw-r--r--doc/bugs/Could_not_read_from_remote_repository.mdwn24
-rw-r--r--doc/bugs/Could_not_read_from_remote_repository/comment_1_da842a9d146bcd5c7773b58364c25597._comment8
-rw-r--r--doc/bugs/Could_not_read_from_remote_repository/comment_2_82746a0cf989d884cd0fd796db092b3c._comment36
-rw-r--r--doc/bugs/Could_not_resolve_dependencies.mdwn40
-rw-r--r--doc/bugs/Crash_trying_to_sync_with_a_repo_over_ssh.mdwn43
-rw-r--r--doc/bugs/Crash_trying_to_sync_with_a_repo_over_ssh/comment_1_9705f295ad8101f3f0ede18e590b56ef._comment8
-rw-r--r--doc/bugs/Crash_trying_to_sync_with_a_repo_over_ssh/comment_2_0d751d81ac618f8d7e3f1dd20c830542._comment8
-rw-r--r--doc/bugs/Crash_when_adding_jabber_account_.mdwn32
-rw-r--r--doc/bugs/Crash_when_adding_jabber_account_/comment_1_2dc61ebcfa8919fb839656999c155c52._comment10
-rw-r--r--doc/bugs/Crash_when_adding_jabber_account_/comment_2_e49af3b8a937d82eda1509b6f67b21d4._comment8
-rw-r--r--doc/bugs/Crash_when_adding_jabber_account_/comment_3_e59f8813bf1a7c4e3c8c120fe82348b9._comment10
-rw-r--r--doc/bugs/Crash_when_adding_jabber_account_/comment_4_716ac138cb69eecd0fb586699b4aeb2a._comment8
-rw-r--r--doc/bugs/Creating_an_S3_repository_with_an_invalid_name_throws_an_exception.mdwn18
-rw-r--r--doc/bugs/Creating_an_encrypted_S3_does_not_check_for_presence_of_GPG.mdwn18
-rw-r--r--doc/bugs/Creating_second_repository_leads_to_wrong_ip___40__using_git-annex_webapp_--listen__41__.mdwn35
-rw-r--r--doc/bugs/DS__95__Store_not_gitignored.mdwn26
-rw-r--r--doc/bugs/DS__95__Store_not_gitignored/comment_1_b93ac0ea3be82c361ceb4352e742ba39._comment8
-rw-r--r--doc/bugs/DS__95__Store_not_gitignored/comment_2_4136e1f4aba7aa7562dafcf6a213e10c._comment58
-rw-r--r--doc/bugs/Deasn__39__t_clean_up_ssh_keys_after_removing_remote_repo.mdwn18
-rw-r--r--doc/bugs/Deasn__39__t_clean_up_ssh_keys_after_removing_remote_repo/comment_1_88fbf70eae48484988dbb433a437c717._comment14
-rw-r--r--doc/bugs/Detection_assumes_that_shell_is_bash.mdwn24
-rw-r--r--doc/bugs/Difficult_to_troubleshoot_XMPP_login_failures.mdwn11
-rw-r--r--doc/bugs/Difficult_to_troubleshoot_XMPP_login_failures/comment_1_4205bccf515169031e4a9ed8e905262c._comment10
-rw-r--r--doc/bugs/Direct_mode_keeps_re-checksuming_duplicated_files.mdwn25
-rw-r--r--doc/bugs/Direct_mode_keeps_re-checksuming_duplicated_files/comment_1_cb10385a4f046bfe676720ded3409379._comment14
-rw-r--r--doc/bugs/Direct_mode_keeps_re-checksuming_duplicated_files/comment_2_4bcf1a897181e40c9c8969d597a844f0._comment8
-rw-r--r--doc/bugs/Direct_mode_keeps_re-checksuming_duplicated_files/comment_3_6a6d22d218f036c9977072973ed99aa8._comment11
-rw-r--r--doc/bugs/Direct_mode_keeps_re-checksuming_duplicated_files/comment_4_eaa7ffb3a1d9ffd6d89de301bd2cd5b2._comment11
-rw-r--r--doc/bugs/Direct_mode_repositories_end_up_with_unstaged_changes.mdwn46
-rw-r--r--doc/bugs/Direct_mode_repositories_end_up_with_unstaged_changes/comment_1_300a2b246182be3079db20a7e3322261._comment8
-rw-r--r--doc/bugs/Direct_mode_repositories_still_use_symlinks_sometimes.mdwn32
-rw-r--r--doc/bugs/Disconcerting_warning_from_git-annex.mdwn6
-rw-r--r--doc/bugs/Disconcerting_warning_from_git-annex/comment_1_58cebd377bfdf247b6c4fee27a3ba461._comment8
-rw-r--r--doc/bugs/Disconcerting_warning_from_git-annex/comment_2_dc7407044d4c739d05248300c58d8ef2._comment8
-rw-r--r--doc/bugs/Discrepancy_between_git_annex_add_and_git_annex_watch.mdwn33
-rw-r--r--doc/bugs/Displayed_copy_speed_is_wrong.mdwn8
-rw-r--r--doc/bugs/Displayed_copy_speed_is_wrong/comment_1_74de3091e8bfd7acd6795e61f39f07c6._comment8
-rw-r--r--doc/bugs/Displayed_copy_speed_is_wrong/comment_2_8b240de1d5ae9229fa2d77d1cc15a552._comment8
-rw-r--r--doc/bugs/During_synchronisation_top-level_folder_suddenly_appear_in_sub-sub-folder.mdwn3747
-rw-r--r--doc/bugs/During_synchronisation_top-level_folder_suddenly_appear_in_sub-sub-folder/comment_1_ae4a13ff121d27f78904eee9bf5e716b._comment20
-rw-r--r--doc/bugs/During_synchronisation_top-level_folder_suddenly_appear_in_sub-sub-folder/comment_2_32e360cd7b100ddb9a526e7833fc55e1._comment15
-rw-r--r--doc/bugs/During_synchronisation_top-level_folder_suddenly_appear_in_sub-sub-folder/comment_3_650dc9ede4e16ef668d96840f63dad47._comment12
-rw-r--r--doc/bugs/During_synchronisation_top-level_folder_suddenly_appear_in_sub-sub-folder/comment_4_721cf184fb5a5244ec5c15de3302ebf7._comment33
-rw-r--r--doc/bugs/Enable__47__paus_syncing_to_remote_ssh_server_with_multiple_directories.mdwn19
-rw-r--r--doc/bugs/Enable__47__paus_syncing_to_remote_ssh_server_with_multiple_directories/comment_1_e8affeca873c2ef73255f8f77e0ac16f._comment10
-rw-r--r--doc/bugs/Endless_SSH_password_prompts.mdwn15
-rw-r--r--doc/bugs/Endless_SSH_password_prompts/comment_1_b3a32d7a53c30478f409a47f856282ab._comment10
-rw-r--r--doc/bugs/Endless_SSH_password_prompts/comment_2_0a1fc4b4580d8be4c37064e0a16de99b._comment8
-rw-r--r--doc/bugs/Endless_SSH_password_prompts/comment_3_46210f7745b8c7c237fc8b08309390fe._comment11
-rw-r--r--doc/bugs/Error___39__get__39__ting_files_from_rsync_remote__44___versions_3.20120315_and_3.20120430.mdwn79
-rw-r--r--doc/bugs/Error_creating_encrypted_cloud_repository:___34__internal_server_error__34__.mdwn28
-rw-r--r--doc/bugs/Error_creating_encrypted_cloud_repository:___34__internal_server_error__34__/comment_1_9be1b577fa4d5fe9754845073fdf5d32._comment10
-rw-r--r--doc/bugs/Error_creating_encrypted_cloud_repository:___34__internal_server_error__34__/comment_2_0da0d68b646f2b38be6ecf7c0fe13743._comment8
-rw-r--r--doc/bugs/Error_creating_encrypted_cloud_repository:___34__internal_server_error__34__/comment_3_09c56f5574931f2ebe903069f0731160._comment16
-rw-r--r--doc/bugs/Error_creating_encrypted_cloud_repository:___34__internal_server_error__34__/comment_4_0c127396e682ca6ced43aec7deeb0335._comment12
-rw-r--r--doc/bugs/Error_creating_encrypted_cloud_repository:___34__internal_server_error__34__/comment_5_6bc3eadefde4750eec67a55de6651b2d._comment13
-rw-r--r--doc/bugs/Error_creating_encrypted_cloud_repository:___34__internal_server_error__34__/comment_6_263ab9c1483438b1717c8061ac81a2fa._comment9
-rw-r--r--doc/bugs/Error_creating_encrypted_cloud_repository:___34__internal_server_error__34__/comment_7_eccc10990dff37584f8e60cd481a7140._comment26
-rw-r--r--doc/bugs/Error_creating_encrypted_cloud_repository:___34__internal_server_error__34__/comment_8_f897d20cbe5e0f3f58ce1a0bacad3d71._comment8
-rw-r--r--doc/bugs/Error_creating_remote_repository_using_ssh_on_OSX.mdwn36
-rw-r--r--doc/bugs/Error_creating_remote_repository_using_ssh_on_OSX/comment_1_559555934d79ae6be383063abcaae22e._comment10
-rw-r--r--doc/bugs/Error_creating_remote_repository_using_ssh_on_OSX/comment_2_a9f4f9db042ab6f6c15d6954651971b2._comment12
-rw-r--r--doc/bugs/Error_creating_remote_repository_using_ssh_on_OSX/comment_3_55a496d0a0be80ba723b17bf9faa3bc0._comment8
-rw-r--r--doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__.mdwn31
-rw-r--r--doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_10_8742f7ac27b5f4ad6261d04a174a691c._comment10
-rw-r--r--doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_11_b8e720340000537de6713c49b7733b2f._comment21
-rw-r--r--doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_1_489fa3a717519cd5d8b4c1a9d143d8c6._comment8
-rw-r--r--doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_2_b0796d3b1913e1b6f7b34d75a591be42._comment16
-rw-r--r--doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_3_d8ca17ccaa5ee48d590736af8e77d88a._comment8
-rw-r--r--doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_4_aa7a690aaf75d21f52051a31d7fce70e._comment8
-rw-r--r--doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_5_dc235dc2d024b7f340721bb578630e00._comment10
-rw-r--r--doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_6_5d1e6ea5b5725c773acc6e288add812c._comment8
-rw-r--r--doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_7_6389b4f03ebc916358bc6674398d70c4._comment14
-rw-r--r--doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_8_bcacc9fb3751042968118ebe33802e27._comment10
-rw-r--r--doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_9_6d4c9f0e133ebd94fc11346df446402e._comment16
-rw-r--r--doc/bugs/Error_when_moving_annexed_file_to_a_.gitignored_location.mdwn21
-rw-r--r--doc/bugs/Error_when_moving_annexed_file_to_a_.gitignored_location/comment_1_b524e70156e8bc1219d5c6741974ad99._comment18
-rw-r--r--doc/bugs/Error_when_moving_annexed_file_to_a_.gitignored_location/comment_2_ff7349c396d1249204d621e71f6a7a52._comment10
-rw-r--r--doc/bugs/Error_when_moving_annexed_file_to_a_.gitignored_location/comment_4_4bc7d4c51faea3fdafc977cb66b7f73a._comment26
-rw-r--r--doc/bugs/Error_while_adding_a_file___34__createSymbolicLink:_already_exists__34__.mdwn46
-rw-r--r--doc/bugs/Every_new_file_gets_symlinked_to_a_git_object.mdwn78
-rw-r--r--doc/bugs/Every_new_file_gets_symlinked_to_a_git_object/comment_1_d4e7ed56b16494a95e6c904c746cc91f._comment8
-rw-r--r--doc/bugs/Every_new_file_gets_symlinked_to_a_git_object/comment_2_656b2a2cc44e9102c86bdd57045549d5._comment10
-rw-r--r--doc/bugs/Failed_to_make_repository___40__calling_nonexistant_shell__41__.mdwn28
-rw-r--r--doc/bugs/Failed_to_make_repository___40__calling_nonexistant_shell__41__/comment_1_fb8a379ed7f4b88bd55245ce5b18042c._comment8
-rw-r--r--doc/bugs/Fails_to_create_remote_repo_if_no_global_email_set.mdwn55
-rw-r--r--doc/bugs/Feature_request:___34__quvi__34___flag.mdwn14
-rw-r--r--doc/bugs/Feature_request:___34__quvi__34___flag/comment_1_908c38024fd252328566034608c2dec3._comment12
-rw-r--r--doc/bugs/Feature_request:___34__quvi__34___flag/comment_2_4b6822fe91aa865f2ac1297a3daa3fca._comment8
-rw-r--r--doc/bugs/Feature_request:___34__quvi__34___flag/comment_3_c72ef77e76b1c99b5e0c78d0742080e7._comment8
-rw-r--r--doc/bugs/Feature_request:___34__quvi__34___flag/comment_4_6092695d6afb1608447afe6f86e6fb83._comment8
-rw-r--r--doc/bugs/Files_disappear_from_locally_paired_annexes_when_edited.mdwn36
-rw-r--r--doc/bugs/Files_disappear_from_locally_paired_annexes_when_edited/comment_1_bdc97db9dc9954331e4c400baf9e5541._comment10
-rw-r--r--doc/bugs/Finding_an_Unused_file.mdwn152
-rw-r--r--doc/bugs/Fix_for_opening_a_browser_on_a_mac___40__or_xdg-open_on_linux__47__bsd__63____41__.mdwn26
-rw-r--r--doc/bugs/Freshly_initialized_repo_has_staged_change___34__deleted:_uuid.log__34__.mdwn44
-rw-r--r--doc/bugs/Freshly_initialized_repo_has_staged_change___34__deleted:_uuid.log__34__/comment_1_6441dd04adc158df22589c81746108a9._comment10
-rw-r--r--doc/bugs/Freshly_initialized_repo_has_staged_change___34__deleted:_uuid.log__34__/comment_2_d1c5d7642284a375f9c455dbf76efa5c._comment12
-rw-r--r--doc/bugs/Freshly_initialized_repo_has_staged_change___34__deleted:_uuid.log__34__/comment_3_4b863da1c8ba73ad54da20f7d2ec6e5c._comment14
-rw-r--r--doc/bugs/Freshly_initialized_repo_has_staged_change___34__deleted:_uuid.log__34__/comment_4_8e0f489305ce30ad578b9f8526e86416._comment10
-rw-r--r--doc/bugs/Freshly_initialized_repo_has_staged_change___34__deleted:_uuid.log__34__/comment_5_c699034c8e02b2354516414d0ab73aab._comment53
-rw-r--r--doc/bugs/Freshly_initialized_repo_has_staged_change___34__deleted:_uuid.log__34__/comment_6_786cb7e643811dfd2496ceeff8f34f44._comment10
-rw-r--r--doc/bugs/GIT_DIR_support_incomplete.mdwn17
-rw-r--r--doc/bugs/GPG_can__39__t_handle_some_files.mdwn23
-rw-r--r--doc/bugs/GPG_can__39__t_handle_some_files/comment_1_4388c971e991dbc0326e69c49994df1e._comment8
-rw-r--r--doc/bugs/GPG_passphrase_repeated_prompt.mdwn24
-rw-r--r--doc/bugs/GPG_passphrase_repeated_prompt/comment_1_6ef1c9725befc84ad57bce196ef630ef._comment16
-rw-r--r--doc/bugs/GPG_problem_on_Mac.mdwn34
-rw-r--r--doc/bugs/GPG_problem_on_Mac/comment_1_9ccfa12e7a9569a7ae9a3b819917c275._comment9
-rw-r--r--doc/bugs/GPG_problem_on_Mac/comment_2_a5e07131e2bc1a646c8439fc2506128b._comment29
-rw-r--r--doc/bugs/GPG_problem_on_Mac/comment_3_388238360f2423f84881e904443efb86._comment12
-rw-r--r--doc/bugs/Git_annex_add_fails_on_read-only_files.mdwn37
-rw-r--r--doc/bugs/Git_annex_add_fails_on_read-only_files/comment_1_d31018e8bf31d729ee9fee43a0a07934._comment10
-rw-r--r--doc/bugs/Git_annex_add_fails_on_read-only_files/comment_2_e38e7048749f890169cd0be602be6ee7._comment10
-rw-r--r--doc/bugs/Git_annex_hangs_after_git_annex_add_on_vfat__47__sdcard__47__android.mdwn280
-rw-r--r--doc/bugs/Git_annex_hangs_after_git_annex_add_on_vfat__47__sdcard__47__android/comment_1_2fc435d1c741f9fc422401f682e7c8b7._comment17
-rw-r--r--doc/bugs/Git_annex_hangs_after_git_annex_add_on_vfat__47__sdcard__47__android/comment_2_b73fb99a75aef912f8286626c5bde66d._comment14
-rw-r--r--doc/bugs/Git_annex_hangs_after_git_annex_add_on_vfat__47__sdcard__47__android/comment_3_b7115f2c658439ff59a029f500697fc1._comment57
-rw-r--r--doc/bugs/Git_annex_hangs_after_git_annex_add_on_vfat__47__sdcard__47__android/comment_4_67de7a56ddb06fc0e31cc011d281c633._comment8
-rw-r--r--doc/bugs/Git_annex_hangs_after_git_annex_add_on_vfat__47__sdcard__47__android/comment_5_58fdb2a00f1737746cdbc804f831a0e7._comment8
-rw-r--r--doc/bugs/Git_annexed_files_symlink_are_wrong_when_submodule_is_not_in_the_same_path.mdwn63
-rw-r--r--doc/bugs/Git_annexed_files_symlink_are_wrong_when_submodule_is_not_in_the_same_path/comment_1_b3197993dbdfaf2db5e4651ac54a896e._comment12
-rw-r--r--doc/bugs/Git_annexed_files_symlink_are_wrong_when_submodule_is_not_in_the_same_path/comment_2_1fbbd02e61ef524597dafd69460b00b4._comment10
-rw-r--r--doc/bugs/Glacier_remote_uploads_duplicates.mdwn36
-rw-r--r--doc/bugs/Glacier_remote_uploads_duplicates/comment_1_8aef582a0f0d0c7f764b425fc45de3b4._comment25
-rw-r--r--doc/bugs/Glacier_remote_uploads_duplicates/comment_2_150ce8b7c4424a83c4b1760da5a89d27._comment8
-rw-r--r--doc/bugs/Glacier_remote_uploads_duplicates/comment_3_718af5048c5f894eee134547a2e0a644._comment8
-rw-r--r--doc/bugs/Glacier_remote_uploads_duplicates/comment_4_184ad0f8c2847309632f8c18b918cd42._comment10
-rw-r--r--doc/bugs/Glacier_remote_uploads_duplicates/comment_5_6980a912d3582c2f2511e4827e9e76b3._comment21
-rw-r--r--doc/bugs/Glacier_remote_uploads_duplicates/comment_6_feea067d6856af2840604782b29af86a._comment12
-rw-r--r--doc/bugs/Glacier_remote_uploads_duplicates/comment_7_e96187bad3dae2f5f95118f6df87a1ec._comment10
-rw-r--r--doc/bugs/Glacier_remote_uploads_duplicates/comment_8_34216b514a6fca788cfacb8579ce5311._comment12
-rw-r--r--doc/bugs/Handling_of_files_inside_and_outside_archive_directory_at_the_same_time.mdwn16
-rw-r--r--doc/bugs/Handling_of_files_inside_and_outside_archive_directory_at_the_same_time/comment_1_e8bb3d6a2318402b985caed08282d473._comment12
-rw-r--r--doc/bugs/Handling_of_files_inside_and_outside_archive_directory_at_the_same_time/comment_2_ead9fa75a12ef36be9a92637b144e74f._comment14
-rw-r--r--doc/bugs/Hanging_on_install_on_Mountain_lion.mdwn26
-rw-r--r--doc/bugs/Hanging_on_install_on_Mountain_lion/comment_10_f57ff027b19ca16e2ecf1fc6aee9ef4a._comment10
-rw-r--r--doc/bugs/Hanging_on_install_on_Mountain_lion/comment_11_2ff78d2090d0fd3418ab50b27c6028ce._comment8
-rw-r--r--doc/bugs/Hanging_on_install_on_Mountain_lion/comment_1_523d3c0c71f80536850a001b90fd0e9e._comment8
-rw-r--r--doc/bugs/Hanging_on_install_on_Mountain_lion/comment_2_6c360c64093b016c2150206dc3ad1709._comment10
-rw-r--r--doc/bugs/Hanging_on_install_on_Mountain_lion/comment_3_7b77fd9b7dc236c345f2f6149c8138ee._comment18
-rw-r--r--doc/bugs/Hanging_on_install_on_Mountain_lion/comment_5_08289596445d7588e43d35490fbfe5f4._comment8
-rw-r--r--doc/bugs/Hanging_on_install_on_Mountain_lion/comment_5_2a336fe7b8aed07cbdaa868bd34078f9._comment8
-rw-r--r--doc/bugs/Hanging_on_install_on_Mountain_lion/comment_6_ea7a40c3b6748738421aed00a6f7ca10._comment10
-rw-r--r--doc/bugs/Hanging_on_install_on_Mountain_lion/comment_7_00962da9288976f8a48d0cbc08e1d9e2._comment15
-rw-r--r--doc/bugs/Hanging_on_install_on_Mountain_lion/comment_8_5d53d23e529f33f6e7deb10643831613._comment11
-rw-r--r--doc/bugs/Hanging_on_install_on_Mountain_lion/comment_9_f00c8761e3184975b6645c0c3e241365._comment10
-rw-r--r--doc/bugs/Hangs_on_creating_repository_when_using_--listen.mdwn46
-rw-r--r--doc/bugs/Hangs_on_creating_repository_when_using_--listen/comment_1_8cbe786de8cf8b407418149b9c811aab._comment14
-rw-r--r--doc/bugs/Hangs_on_creating_repository_when_using_--listen/comment_2_dc128eeddeaaf3f84e71aca0fb7d341f._comment8
-rw-r--r--doc/bugs/Hard_links_not_synced_in_direct_mode.mdwn125
-rw-r--r--doc/bugs/Hard_links_not_synced_in_direct_mode/comment_1_aaa781664ae0c62c4f6530cb075ed367._comment17
-rw-r--r--doc/bugs/Hard_links_not_synced_in_direct_mode/comment_2_213aa10909d1fd0f20ed078a7ed93e79._comment8
-rw-r--r--doc/bugs/Hard_links_not_synced_in_direct_mode/comment_3_e6b783d9aaae20c0d35e9888d878716a._comment10
-rw-r--r--doc/bugs/Hard_links_not_synced_in_direct_mode/comment_4_b008ae7b1cf8685d92c9a87a7609de1e._comment18
-rw-r--r--doc/bugs/Hard_links_not_synced_in_direct_mode/comment_5_949c891209713a2c0a5e66af11ed4c79._comment14
-rw-r--r--doc/bugs/How_can_I_solve_a_non-fast-forward_push_without_using_the_assistant__63__.mdwn295
-rw-r--r--doc/bugs/How_can_I_solve_a_non-fast-forward_push_without_using_the_assistant__63__/comment_1_0ddcbe0ccecdec1012964dfa436a3eee._comment19
-rw-r--r--doc/bugs/How_can_I_solve_a_non-fast-forward_push_without_using_the_assistant__63__/comment_2_5765b849bcf045ead9f007bd50b2cfbd._comment20
-rw-r--r--doc/bugs/Huge_annex_out_of_memory_on_switch_to_indirect_mode_and_status.mdwn69
-rw-r--r--doc/bugs/Huge_annex_out_of_memory_on_switch_to_indirect_mode_and_status/comment_1_94c678e1348280a96f11d7456c240d3a._comment8
-rw-r--r--doc/bugs/Huge_annex_out_of_memory_on_switch_to_indirect_mode_and_status/comment_2_09450d58df2373174a1f0d90b08e9eb3._comment14
-rw-r--r--doc/bugs/Huge_annex_out_of_memory_on_switch_to_indirect_mode_and_status/comment_3_a07105226ef3488b97731db004651976._comment10
-rw-r--r--doc/bugs/Impossible_to_enable_an_existing_gcrypt_repo_in_the_webapp.mdwn21
-rw-r--r--doc/bugs/Impossible_to_enable_an_existing_gcrypt_repo_in_the_webapp/comment_1_17814787e333d15da3ab4e57c7d31d4b._comment12
-rw-r--r--doc/bugs/Incorrect_merge__44___direct_repos___40__2__41__.mdwn44
-rw-r--r--doc/bugs/Incorrect_merge__44___direct_repos___40__2__41__/comment_1_15c354c4841d364e78882d2b46a0a764._comment66
-rw-r--r--doc/bugs/Incorrect_merge__44___direct_repos___40__2__41__/comment_2_8bc496226a977dbeeb1ce3f06122f1c2._comment12
-rw-r--r--doc/bugs/Incorrect_merge___40__a_special_case__41__.mdwn48
-rw-r--r--doc/bugs/Incorrect_merge___40__a_special_case__41__/comment_1_c80418d76b501c688e3a9fb4831520fd._comment41
-rw-r--r--doc/bugs/Incorrect_merge___40__a_special_case__41__/comment_2_8b2a188696f46819f6e3f0e9660362d2._comment45
-rw-r--r--doc/bugs/Incorrect_merge___40__a_special_case__41__/comment_3_8cdbb1fda506b9e53a0e9ab88b2569c1._comment15
-rw-r--r--doc/bugs/Incorrect_merge___40__a_special_case__41__/comment_4_9d74e2854a5d77f0f793f56fa0cff9e2._comment14
-rw-r--r--doc/bugs/Incorrect_version_of_Git_Annex___40__1.0.52__41___as_seen_by_Android.mdwn24
-rw-r--r--doc/bugs/Incorrect_version_on_64_Standalone_Build.mdwn11
-rw-r--r--doc/bugs/Incorrect_version_on_64_Standalone_Build/comment_1_1964e4cad33a9f98b2eedbf095e899ff._comment12
-rw-r--r--doc/bugs/Install_of_git-annex-3.20121112_fails.mdwn20
-rw-r--r--doc/bugs/Install_of_git-annex-3.20121112_fails/comment_1_80fc80151d4390bd8a4332f30723962e._comment8
-rw-r--r--doc/bugs/Install_of_git-annex-3.20121112_fails/comment_2_2613320a41a74dc757a3277c8c328bd0._comment62
-rw-r--r--doc/bugs/Install_of_git-annex-3.20121112_fails/comment_3_c364764d0c56e8dc3cac276905d99841._comment10
-rw-r--r--doc/bugs/Install_of_git-annex-3.20121112_fails/comment_4_f1057340dfa978071d3bbc9e2af1e612._comment19
-rw-r--r--doc/bugs/Install_of_git-annex-3.20121112_fails/comment_5_9007b1a3abd647945604968db19cb841._comment8
-rw-r--r--doc/bugs/Install_of_git-annex-3.20121112_fails/comment_6_0bb3ac5375f29ce9d3d0be93879267e3._comment11
-rw-r--r--doc/bugs/Install_of_git-annex-3.20121112_fails/comment_7_ae4443b8cd069080d1f77fca16aa8b04._comment10
-rw-r--r--doc/bugs/Internal_Server_Error:_Unknown_UUID.mdwn37
-rw-r--r--doc/bugs/Internal_Server_Error:_Unknown_UUID/comment_1_f42f703a5d267557abf5e932f0890d4a._comment37
-rw-r--r--doc/bugs/Internal_Server_Error:_Unknown_UUID/comment_2_eb1999f99c5babf3fcb1ff5d72ea6db6._comment18
-rw-r--r--doc/bugs/Internal_Server_Error:_Unknown_UUID/comment_3_bda72b0d615843d18d6ef21f833432a8._comment9
-rw-r--r--doc/bugs/Internal_Server_Error:_Unknown_UUID/comment_4_651440cda405ad40a04479f5d87d581e._comment10
-rw-r--r--doc/bugs/Internal_Server_Error:_Unknown_UUID/comment_5_21fa189b631c246ac5df16a49c3c0178._comment8
-rw-r--r--doc/bugs/Internal_Server_Error:_Unknown_UUID/comment_6_1f712693d2ded5abceb869fdb7f47ef3._comment12
-rw-r--r--doc/bugs/Internal_Server_Error:_Unknown_UUID/comment_7_7a5ead0ce5c9429d4723ccce4f6a6d6c._comment14
-rw-r--r--doc/bugs/Internal_Server_Error:_Unknown_UUID/comment_8_a4683fd73ae452a9cd7f61d9930f6266._comment10
-rw-r--r--doc/bugs/Internal_Server_Error:_Unknown_UUID/comment_9_ced3516c3e7161e4d7e599232f62a511._comment8
-rw-r--r--doc/bugs/Internal_Server_Error_unknown_UUID__59___cannot_modify.mdwn26
-rw-r--r--doc/bugs/Internal_Server_Error_when_adding_an_uncrypted_box.com_repo_after_deleted_an_encrypted_one..mdwn28
-rw-r--r--doc/bugs/Internal_server_error_adding_USB_drive_on_OS_X.mdwn25
-rw-r--r--doc/bugs/Internal_server_error_adding_USB_drive_on_OS_X/comment_1_b2ef077d87a9da624f20649c21401b5b._comment17
-rw-r--r--doc/bugs/Internal_server_error_adding_USB_drive_on_OS_X/comment_2_ef849e25b0264808bff800d9d3836119._comment10
-rw-r--r--doc/bugs/Internal_server_error_adding_USB_drive_on_OS_X/comment_3_ae3cbd0eb69cbeb9b349e0060d056d43._comment18
-rw-r--r--doc/bugs/Internal_server_error_adding_USB_drive_on_OS_X/comment_4_0ff2897805928b14829b7b369a3aed91._comment16
-rw-r--r--doc/bugs/Internal_server_error_adding_USB_drive_on_OS_X/comment_5_414a45573aeb5201f4d80433955669d5._comment12
-rw-r--r--doc/bugs/Interrupted_switch_to_direct_mode_can_cause_all_following_switches_to_fail.mdwn50
-rw-r--r--doc/bugs/Is_there_any_way_to_rate_limit_uploads_to_an_S3_backend__63__.mdwn19
-rw-r--r--doc/bugs/Is_there_any_way_to_rate_limit_uploads_to_an_S3_backend__63__/comment_1_ef97e735ce308f7bcc03f5d9fda588bf._comment10
-rw-r--r--doc/bugs/Is_there_any_way_to_rate_limit_uploads_to_an_S3_backend__63__/comment_2_539b89de8743e435386b86119d1e982f._comment8
-rw-r--r--doc/bugs/Issue_on_OSX_with_some_system_limits.mdwn26
-rw-r--r--doc/bugs/Issue_on_OSX_with_some_system_limits/comment_1_5fc1eedb5231edc37c87a2d9b91313b9._comment12
-rw-r--r--doc/bugs/Issue_on_OSX_with_some_system_limits/comment_2_b14e697c211843163285aaa8de5bf4c6._comment12
-rw-r--r--doc/bugs/Issue_on_OSX_with_some_system_limits/comment_3_18ddf8b5934dd6fb1676cd6adc7d103b._comment19
-rw-r--r--doc/bugs/Issue_on_OSX_with_some_system_limits/comment_4_c25a8eb369e546f65e1a72d89f43066f._comment12
-rw-r--r--doc/bugs/Issue_on_OSX_with_some_system_limits/comment_5_6407a3e7aa0316cba2994bfef0e3c633._comment37
-rw-r--r--doc/bugs/Issue_on_OSX_with_some_system_limits/comment_6_f01887695e8b8386e125464c6d401565._comment8
-rw-r--r--doc/bugs/Issue_on_OSX_with_some_system_limits/comment_7_c7776d5b2d073e0d2ae36515185c25aa._comment17
-rw-r--r--doc/bugs/It_is_very_easy_to_turn_git-annex_into_a_zombie.mdwn25
-rw-r--r--doc/bugs/It_is_very_easy_to_turn_git-annex_into_a_zombie/comment_1_d5fba6c061fb21795021ea83070dbfa2._comment8
-rw-r--r--doc/bugs/It_is_very_easy_to_turn_git-annex_into_a_zombie/comment_2_12cba707239018989e8d5b6f456fa754._comment10
-rw-r--r--doc/bugs/JSON_output_broken_with___34__git_annex_sync__34__.mdwn21
-rw-r--r--doc/bugs/JSON_output_broken_with___34__git_annex_sync__34__/comment_1_380a49b3c132f9f529729a1cb5a69621._comment8
-rw-r--r--doc/bugs/JSON_output_broken_with___34__git_annex_sync__34__/comment_2_282f5f89fb4a46e1fad0980e0b2994a0._comment8
-rw-r--r--doc/bugs/JSON_output_broken_with___34__git_annex_sync__34__/comment_3_7ff98958146b7f6396226bdd878ec86e._comment10
-rw-r--r--doc/bugs/JSON_output_broken_with___34__git_annex_sync__34__/comment_4_f9e460a09e7e5f53c16c20ded2649201._comment8
-rw-r--r--doc/bugs/Killing_the_assistant_daemon_leaves_ssh_mux_sessions_behind.mdwn38
-rw-r--r--doc/bugs/Killing_the_assistant_daemon_leaves_ssh_mux_sessions_behind/comment_1_17879b98a5e79ace03b543064751e46e._comment8
-rw-r--r--doc/bugs/Killing_the_assistant_daemon_leaves_ssh_mux_sessions_behind/comment_2_2dc877e281750004b16619ea7b931160._comment8
-rw-r--r--doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss.mdwn57
-rw-r--r--doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_10_52364dc5b1b43b51748453d1896e35c6._comment8
-rw-r--r--doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_11_99b4db1841f8630a9c5efd08910e87a3._comment104
-rw-r--r--doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_1_fbb410a54bb0bd82d0953ef58a88600e._comment24
-rw-r--r--doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_2_8007c9ba42a951a4426255ec3c37d961._comment13
-rw-r--r--doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_3_73ecd4cb8ee58a8dfe7cab0e893dbe5b._comment8
-rw-r--r--doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_4_e8a10886a564f35414c30a04335d9d32._comment8
-rw-r--r--doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_5_6a318edfe45c80343d017dc7b4837acb._comment8
-rw-r--r--doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_6_f7a1d9f9d40aff531d873a95d2196edd._comment8
-rw-r--r--doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_7_1724ffdf986301bf37ef7a6d16b6ea8a._comment10
-rw-r--r--doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_8_5470e2f50e6506139ecb1b342371c509._comment10
-rw-r--r--doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_9_e53148a9efa061a825f668a9492182f7._comment10
-rw-r--r--doc/bugs/Last_two_versions_didn__39__t_show_up_on_hackage.mdwn11
-rw-r--r--doc/bugs/Last_two_versions_didn__39__t_show_up_on_hackage/comment_1_74b56dea2100450e322e726bb55bb310._comment8
-rw-r--r--doc/bugs/Linux_stand_alone_build_20130723_breaks_support_for_glibc_2.13_debian_stable.txt43
-rw-r--r--doc/bugs/Linux_stand_alone_build_20130723_breaks_support_for_glibc_2.13_debian_stable/comment_1_dc7f726a0b60f64392cbbd1b4317bab5._comment10
-rw-r--r--doc/bugs/Linux_stand_alone_build_20130723_breaks_support_for_glibc_2.13_debian_stable/comment_2_4a0198d714bd3b52ba9baa68dc45f535._comment12
-rw-r--r--doc/bugs/Local_files_not_found.mdwn50
-rw-r--r--doc/bugs/Local_files_not_found/comment_1_5e1fcc0597594fa493ffa28aa32e1df8._comment12
-rw-r--r--doc/bugs/Local_network___40__ssh__41___fails_to_pair__47__sync.mdwn175
-rw-r--r--doc/bugs/Local_network___40__ssh__41___fails_to_pair__47__sync/comment_1_bab9cd5bdcffec3c48b9e8657cd9bbf7._comment14
-rw-r--r--doc/bugs/Local_network___40__ssh__41___fails_to_pair__47__sync/comment_2_104898dce3c67c082a9f2b36e2f45ff8._comment10
-rw-r--r--doc/bugs/Local_pairing_fails:_PairListener_crashed.mdwn18
-rw-r--r--doc/bugs/Local_pairing_fails:_PairListener_crashed/comment_1_d9c5d2147cf6d8d8477eb13b72081d46._comment12
-rw-r--r--doc/bugs/Local_pairing_fails:_PairListener_crashed/comment_2_60a21105145ac228f486bc4beb2ea54d._comment32
-rw-r--r--doc/bugs/Local_pairing_fails:_received_PairMsg_loop.mdwn39
-rw-r--r--doc/bugs/Local_pairing_fails:_received_PairMsg_loop/comment_1_b8c485bafd98be8c21595597af361255._comment8
-rw-r--r--doc/bugs/Local_pairing_fails:_received_PairMsg_loop/comment_2_bc63489334f44a423645021415ffe196._comment10
-rw-r--r--doc/bugs/Local_pairing_fails:_received_PairMsg_loop/comment_3_6345b174d04b6613c2c55a6ec9e50c21._comment16
-rw-r--r--doc/bugs/Local_pairing_fails:_received_PairMsg_loop/comment_4_f39ec6c3d5a016b3c5260162c0b42177._comment12
-rw-r--r--doc/bugs/Local_pairing_fails:_received_PairMsg_loop/comment_5_ca0c5ef6e6a6d2c4b64430ac68370b6a._comment8
-rw-r--r--doc/bugs/Lost_S3_Remote.mdwn59
-rw-r--r--doc/bugs/Lost_S3_Remote/comment_1_6e80e6db6671581d471fc9a54181c04c._comment10
-rw-r--r--doc/bugs/Lost_S3_Remote/comment_2_c99c65882a3924f4890e500f9492b442._comment8
-rw-r--r--doc/bugs/Lost_S3_Remote/comment_3_1e434d5a20a692cd9dc7f6f8f20f30dd._comment8
-rw-r--r--doc/bugs/Mac_OS_10.9_GPG_erro_when_creating_USB_repo___40__solved__41__.mdwn23
-rw-r--r--doc/bugs/Mac_OS_10.9_GPG_erro_when_creating_USB_repo___40__solved__41__/comment_1_0b4dcedc58e5071733e1239490aed2ea._comment10
-rw-r--r--doc/bugs/Mac_OS_10.9_GPG_erro_when_creating_USB_repo___40__solved__41__/comment_2_1cb1ef0292a3357874b461a77c13373e._comment8
-rw-r--r--doc/bugs/Mac_OS_10.9_GPG_erro_when_creating_USB_repo___40__solved__41__/comment_3_e5ec1e3ab304d738e3b0847287a47af4._comment10
-rw-r--r--doc/bugs/Mac_OS_10.9_GPG_error_adding_S3_repo___40__solved__41__.mdwn28
-rw-r--r--doc/bugs/Mac_OS_10.9_GPG_error_adding_S3_repo___40__solved__41__/comment_1_d95accb43bd18cc9acbbf1d4069f86b3._comment8
-rw-r--r--doc/bugs/Mac_OS_10.9_GPG_error_adding_S3_repo___40__solved__41__/comment_2_452a3c524974832f0742efb00df4d576._comment13
-rw-r--r--doc/bugs/Mac_OS_10.9_GPG_error_adding_S3_repo___40__solved__41__/comment_3_f8f6d1e0065e5ba56cd405b1c021ca09._comment10
-rw-r--r--doc/bugs/Mac_OS_10.9_GPG_error_adding_S3_repo___40__solved__41__/comment_4_b524649cee751532d20a4894d71c5cf3._comment8
-rw-r--r--doc/bugs/Mac_OS_10.9_GPG_error_adding_S3_repo___40__solved__41__/comment_5_8312ba868ef616ec00563446c9c3464f._comment12
-rw-r--r--doc/bugs/Mac_OS_10.9_GPG_error_adding_S3_repo___40__solved__41__/comment_6_1af75c691d27c97397f1901f7c2483b0._comment8
-rw-r--r--doc/bugs/Mac_OS_10.9_GPG_error_adding_S3_repo___40__solved__41__/comment_7_e519df252875de87c4ef5b727f033bdf._comment8
-rw-r--r--doc/bugs/Mac_OS_10.9_GPG_error_adding_S3_repo___40__solved__41__/comment_8_4bb959e2659991cd392853e8beacf708._comment8
-rw-r--r--doc/bugs/Makefile_is_missing_dependancies.mdwn47
-rw-r--r--doc/bugs/Makefile_is_missing_dependancies/comment_1_5a3da5f79c8563c7a450aa29728abe7c._comment47
-rw-r--r--doc/bugs/Makefile_is_missing_dependancies/comment_2_416f12dbd0c2b841fac8164645b81df5._comment8
-rw-r--r--doc/bugs/Makefile_is_missing_dependancies/comment_3_c38b6f4abc9b9ad413c3b83ca04386c3._comment25
-rw-r--r--doc/bugs/Makefile_is_missing_dependancies/comment_4_cc13873175edf191047282700315beee._comment30
-rw-r--r--doc/bugs/Makefile_is_missing_dependancies/comment_5_0a1c52e2c96d19b9c3eb7e99b8c2434f._comment59
-rw-r--r--doc/bugs/Makefile_is_missing_dependancies/comment_6_24119fc5d5963ce9dd669f7dcf006859._comment10
-rw-r--r--doc/bugs/Makefile_is_missing_dependancies/comment_7_96fd4725df4b54e670077a18d3ac4943._comment12
-rw-r--r--doc/bugs/Makefile_is_missing_dependancies/comment_8_a3555e3286cdc2bfeb9cde0ff727ba74._comment8
-rw-r--r--doc/bugs/Manual_content_mode_isn__39__t_manual.mdwn89
-rw-r--r--doc/bugs/Manual_mode_weirdness.mdwn37
-rw-r--r--doc/bugs/Manual_mode_weirdness/comment_1_f8ab3bac9e9a6768e5fd5a052f0d920f._comment8
-rw-r--r--doc/bugs/Manual_mode_weirdness/comment_2_e810daa488fad32ca8bdaae620051da8._comment8
-rw-r--r--doc/bugs/Missing_dependancy_in_commit_6cecc26206c4a539999b04664136c6f785211a41.mdwn35
-rw-r--r--doc/bugs/Missing_repo_uuid_after_local_pairing_with_older_annex.mdwn31
-rw-r--r--doc/bugs/Missing_repo_uuid_after_local_pairing_with_older_annex/comment_1_8229df64a872bee7590f75eb78f78c4a._comment10
-rw-r--r--doc/bugs/Missing_repo_uuid_after_local_pairing_with_older_annex/comment_2_f37be896396915b1c85cff8811dceb4a._comment12
-rw-r--r--doc/bugs/Missing_repo_uuid_after_local_pairing_with_older_annex/comment_3_df7fc1078059538a76f384a40541e91f._comment10
-rw-r--r--doc/bugs/Missing_repo_uuid_after_local_pairing_with_older_annex/comment_4_70c444c61f41df2f59294c10f94f0c09._comment8
-rw-r--r--doc/bugs/More_sync__39__ing_weirdness_with_the_assistant_branch_on_OSX.mdwn15
-rw-r--r--doc/bugs/More_sync__39__ing_weirdness_with_the_assistant_branch_on_OSX/comment_1_377525e70640751e1ead445aeed15efa._comment8
-rw-r--r--doc/bugs/Most_recent_git-annex_will_not_build_on_OpenIndiana.mdwn36
-rw-r--r--doc/bugs/Most_recent_git-annex_will_not_build_on_OpenIndiana/comment_1_f3c336ecfee51e074ea3a9fc95301de5._comment8
-rw-r--r--doc/bugs/Most_recent_git-annex_will_not_build_on_OpenIndiana/comment_2_102c0e998934e84deca92fd1c90145fa._comment8
-rw-r--r--doc/bugs/Most_recent_git-annex_will_not_build_on_OpenIndiana/comment_3_1449dd796ce9f2209f085d4b017a5f33._comment19
-rw-r--r--doc/bugs/Most_recent_git-annex_will_not_build_on_OpenIndiana/comment_4_c4aa8a4379b2c056ca9b7afcff412bbc._comment10
-rw-r--r--doc/bugs/Most_recent_git-annex_will_not_build_on_OpenIndiana/comment_5_6ca4dd2ad51182edf7198f38b336b9b6._comment8
-rw-r--r--doc/bugs/Name_scheme_does_not_follow_git__39__s_rules.mdwn31
-rw-r--r--doc/bugs/Need_to_manually_install_c2hs_-_3.20121127_and_previous.mdwn37
-rw-r--r--doc/bugs/No_easy_way_to_re-inject_a_file_into_an_annex.mdwn12
-rw-r--r--doc/bugs/No_easy_way_to_re-inject_a_file_into_an_annex/comment_1_c871605e187f539f3bfe7478433e7fb5._comment8
-rw-r--r--doc/bugs/No_easy_way_to_re-inject_a_file_into_an_annex/comment_2_e6f1e9eee8b8dfb60ca10c8cfd807ac9._comment10
-rw-r--r--doc/bugs/No_easy_way_to_re-inject_a_file_into_an_annex/comment_3_be62be5fe819acc0cb8b878802decd46._comment14
-rw-r--r--doc/bugs/No_easy_way_to_re-inject_a_file_into_an_annex/comment_4_480a4f72445a636eab1b1c0f816d365c._comment8
-rw-r--r--doc/bugs/No_progress_bars_with_S3.mdwn26
-rw-r--r--doc/bugs/No_progress_bars_with_S3/comment_1_33a601201a9fdd2357f1c03e32fa6b9c._comment8
-rw-r--r--doc/bugs/No_progress_bars_with_S3/comment_2_52361805ced99c22d663b3b1e8a5b221._comment8
-rw-r--r--doc/bugs/No_progress_bars_with_S3/comment_3_5903c1c40c4562f4fbaccd1640fedb18._comment8
-rw-r--r--doc/bugs/No_progress_bars_with_S3/comment_4_80799c33e513384894b390fe34ab312a._comment8
-rw-r--r--doc/bugs/No_version_information_from_cli.mdwn18
-rw-r--r--doc/bugs/OSX_.dmg_unnecessarily_large_and_not_inherently_compressed.mdwn68
-rw-r--r--doc/bugs/OSX_alias_permissions_and_versions_problem.mdwn37
-rw-r--r--doc/bugs/OSX_alias_permissions_and_versions_problem/comment_1_4fabe32e7e626e6ca23aa0b6f449c4c6._comment14
-rw-r--r--doc/bugs/OSX_alias_permissions_and_versions_problem/comment_2_064d60fcc8366a70958540bc145e611a._comment11
-rw-r--r--doc/bugs/OSX_alias_permissions_and_versions_problem/comment_3_6c72d4f40ea0a9566a1185901beff5ba._comment14
-rw-r--r--doc/bugs/OSX_alias_permissions_and_versions_problem/comment_4_8a11f404bb72a1aeb2290744cce2d00d._comment12
-rw-r--r--doc/bugs/OSX_alias_permissions_and_versions_problem/comment_5_30888607199d6a48b76d0c48f5aa4f64._comment8
-rw-r--r--doc/bugs/OSX_app_issues.mdwn6
-rw-r--r--doc/bugs/OSX_app_issues/comment_10_54d8f3e429df9a9958370635c890abf0._comment11
-rw-r--r--doc/bugs/OSX_app_issues/comment_10_6d23232fbb15d0ee3ab532a4884f81ed._comment10
-rw-r--r--doc/bugs/OSX_app_issues/comment_11_5db2baa771fd01a284eac8a16c1c8c67._comment8
-rw-r--r--doc/bugs/OSX_app_issues/comment_11_bb2ceb95a844449795addee6986d0763._comment26
-rw-r--r--doc/bugs/OSX_app_issues/comment_12_62170597c7f441d84d48986857998858._comment10
-rw-r--r--doc/bugs/OSX_app_issues/comment_12_f3bc5a4e4895ac9351786f0bdd8005ba._comment11
-rw-r--r--doc/bugs/OSX_app_issues/comment_13_cb12d419459e5cac766022ee0697fedc._comment18
-rw-r--r--doc/bugs/OSX_app_issues/comment_14_c966fa549bc73c52034ac9abc49de52a._comment8
-rw-r--r--doc/bugs/OSX_app_issues/comment_15_10f1df95266f1a8c9ef933183190f6e2._comment8
-rw-r--r--doc/bugs/OSX_app_issues/comment_16_064e151da121f9c2ef13c19ecb4e7458._comment16
-rw-r--r--doc/bugs/OSX_app_issues/comment_17_0e6ac5e0a54ce78bdc56c62e6fb92846._comment8
-rw-r--r--doc/bugs/OSX_app_issues/comment_2_fd560811c57df5cbc3976639642b8b19._comment8
-rw-r--r--doc/bugs/OSX_app_issues/comment_7_93e0bb53ac2d7daef53426fbdc5f92d9._comment15
-rw-r--r--doc/bugs/OSX_app_issues/comment_8_141eac2f3fb25fe18b4268786f00ad6a._comment8
-rw-r--r--doc/bugs/OSX_app_issues/comment_8_f4d5b2645d7f29b80925159efb94a998._comment8
-rw-r--r--doc/bugs/OSX_app_issues/comment_9_2e6dfca0fd8df04066769653724eae28._comment17
-rw-r--r--doc/bugs/OSX_app_issues/comment_9_e1bbe83a1b9a7385ed6d443d0cc22bc7._comment18
-rw-r--r--doc/bugs/OSX_app_issues/old.mdwn1
-rw-r--r--doc/bugs/OSX_app_issues/old/comment_10_bb823dc3cd6dc914ed14c176afa0b2f3._comment8
-rw-r--r--doc/bugs/OSX_app_issues/old/comment_11_a30e69fed14b0809184ffe05358ab871._comment10
-rw-r--r--doc/bugs/OSX_app_issues/old/comment_12_23d47b3696e537d60df1d383f33f19e4._comment15
-rw-r--r--doc/bugs/OSX_app_issues/old/comment_13_be5738b42b13ec8cd828c5fa66f030e8._comment10
-rw-r--r--doc/bugs/OSX_app_issues/old/comment_14_5783a4716cd104e1f1c276aa0b9cb153._comment41
-rw-r--r--doc/bugs/OSX_app_issues/old/comment_14_e126d87a263f3aa6261f72ee7ff086fc._comment8
-rw-r--r--doc/bugs/OSX_app_issues/old/comment_15_56c7fcafc7dca8be28ebf9e37a8f6b71._comment23
-rw-r--r--doc/bugs/OSX_app_issues/old/comment_15_e58bd3d66f0f43c159d2b37172f152de._comment8
-rw-r--r--doc/bugs/OSX_app_issues/old/comment_16_01f2c968bad66b0ff0c09eb468325deb._comment8
-rw-r--r--doc/bugs/OSX_app_issues/old/comment_16_0b7cd3d5952c5abf36a89a68a4afc1e7._comment8
-rw-r--r--doc/bugs/OSX_app_issues/old/comment_17_82d9963e1fbf17644ce697e5a43943f5._comment16
-rw-r--r--doc/bugs/OSX_app_issues/old/comment_17_c2de94a48e7958b9efffd89dda9144ff._comment59
-rw-r--r--doc/bugs/OSX_app_issues/old/comment_18_29af9df9ea295d114574e76e15b8e737._comment8
-rw-r--r--doc/bugs/OSX_app_issues/old/comment_18_88ddc846eb4e4a2d54028a3412ba28d6._comment12
-rw-r--r--doc/bugs/OSX_app_issues/old/comment_19_6d6341b05123cd317c4eac96353c8662._comment10
-rw-r--r--doc/bugs/OSX_app_issues/old/comment_19_aff4ab761c4d196732baa046af45fe24._comment11
-rw-r--r--doc/bugs/OSX_app_issues/old/comment_20_43bd5985d8a3a5e7f826a34e5dd9216e._comment10
-rw-r--r--doc/bugs/OSX_app_issues/old/comment_3_08613b2e2318680508483d204a43da76._comment76
-rw-r--r--doc/bugs/OSX_app_issues/old/comment_4_4cda124b57ddc87645d5822f14ed5c59._comment8
-rw-r--r--doc/bugs/OSX_app_issues/old/comment_5_0d1df34f83a8dac9c438d93806236818._comment8
-rw-r--r--doc/bugs/OSX_app_issues/old/comment_6_12bd83e7e2327c992448e87bdb85d17e._comment15
-rw-r--r--doc/bugs/OSX_app_issues/old/comment_6_bc44d5aea5f77e331a32913ada293730._comment27
-rw-r--r--doc/bugs/OSX_app_issues/old/comment_6_cea97dbbfb566a9fe463365ca4511119._comment16
-rw-r--r--doc/bugs/OSX_app_issues/old/comment_7_911f187d46890093a54859032ada2442._comment10
-rw-r--r--doc/bugs/OSX_app_issues/old/comment_7_acd73cc5c4caa88099e2d2f19947aadf._comment8
-rw-r--r--doc/bugs/OSX_app_issues/old/comment_8_08b091a58106ca6050ac669579ed9ff4._comment11
-rw-r--r--doc/bugs/OSX_app_issues/old/comment_9_8464c839cb169a4c6e72bebdc2065e9a._comment8
-rw-r--r--doc/bugs/OSX_git-annex.app_error:__LSOpenURLsWithRole__40____41__.mdwn26
-rw-r--r--doc/bugs/OSX_git-annex.app_error:__LSOpenURLsWithRole__40____41__/comment_1_0dfa839f1ba689b23f811787515b8cff._comment8
-rw-r--r--doc/bugs/OSX_git-annex.app_error:__LSOpenURLsWithRole__40____41__/comment_2_612b947eb5474f6d792a833e33105665._comment8
-rw-r--r--doc/bugs/OSX_git-annex.app_error:__LSOpenURLsWithRole__40____41__/comment_3_549b8bcae6f1f8b21932b734e32fbdd1._comment8
-rw-r--r--doc/bugs/OSX_git-annex.app_error:__LSOpenURLsWithRole__40____41__/comment_4_23078dfea127fa3ef20696eb10ce964c._comment10
-rw-r--r--doc/bugs/OSX_git-annex.app_error:__LSOpenURLsWithRole__40____41__/comment_5_7da5ef8325b8787bbf1c6e2c17b1142e._comment8
-rw-r--r--doc/bugs/OS_X_10.8:_Can__39__t_reopen_webapp.mdwn31
-rw-r--r--doc/bugs/OS_X_10.8:_Can__39__t_reopen_webapp/comment_1_2653fe701a1bb20254f3d6b90f10a43b._comment18
-rw-r--r--doc/bugs/OS_X_10.8:_Can__39__t_reopen_webapp/comment_2_d9ce701d077e40f39b142ce2cc570a3b._comment8
-rw-r--r--doc/bugs/OS_X_10.8:_Can__39__t_reopen_webapp/comment_3_14964ab68253dc1a8903d14a821b8b40._comment10
-rw-r--r--doc/bugs/OS_X_10.8:_Can__39__t_reopen_webapp/comment_4_4a579e9a13305ab4157f4b3eba46b92d._comment16
-rw-r--r--doc/bugs/OS_X_10.8:_Can__39__t_reopen_webapp/comment_5_2a710960dc3a177ce62ef92f8546c496._comment12
-rw-r--r--doc/bugs/OS_X_10.8:_Can__39__t_reopen_webapp/comment_6_a4ad73530cd0f6621bcc6394d5f39af7._comment41
-rw-r--r--doc/bugs/Of_identical_files__44___all_but_the_first_copy_are_lost_on_unannex.mdwn54
-rw-r--r--doc/bugs/Of_identical_files__44___all_but_the_first_copy_are_lost_on_unannex/comment_2_f7149b684a97070cff051b780c73be48._comment15
-rw-r--r--doc/bugs/Old_repository_stuck.mdwn9
-rw-r--r--doc/bugs/Older_version_of_git_causes_Internal_Server_Error_when_push.default___61___simple.mdwn64
-rw-r--r--doc/bugs/Older_version_of_git_causes_Internal_Server_Error_when_push.default___61___simple/comment_1_971224d2c0c0ce8d4530b1991508f849._comment12
-rw-r--r--doc/bugs/Older_version_of_git_causes_Internal_Server_Error_when_push.default___61___simple/comment_2_6866f96277dbe83a8aadcdeb426b6750._comment8
-rw-r--r--doc/bugs/Older_version_of_git_causes_Internal_Server_Error_when_push.default___61___simple/comment_3_eaed9b5532e30e401f50193a72b98310._comment13
-rw-r--r--doc/bugs/Older_version_of_git_causes_Internal_Server_Error_when_push.default___61___simple/comment_4_1fab407f3823ce8cec87f5df55e49f8c._comment8
-rw-r--r--doc/bugs/On_Windows__44___annex_get_fails_with_HTTP_Remote__44___but_believes_it_has_succeeded..mdwn180
-rw-r--r--doc/bugs/On_Windows__44___annex_get_over_HTTP_sends_URLs_with_incorrect_separator.mdwn186
-rw-r--r--doc/bugs/On_Windows__44___can__39__t_use_a_USB_disk_annex_created_on_Linux.mdwn18
-rw-r--r--doc/bugs/On_Windows__44___can__39__t_use_a_USB_disk_annex_created_on_Linux/comment_1_f224f4155d857a59595658357f97dac1._comment12
-rw-r--r--doc/bugs/On_Windows__44___can__39__t_use_repository_that_has_a_unix-style_local_remote_configured.mdwn22
-rw-r--r--doc/bugs/On_Windows__44___can__39__t_use_repository_that_has_a_unix-style_local_remote_configured/comment_1_95655915ff6ba9fb5d873358ff047496._comment10
-rw-r--r--doc/bugs/On_Windows__44___wget_is_not_used__44___even_if_available.mdwn67
-rw-r--r--doc/bugs/On_restart__44___most_repositories__44___including_original_one__44___gone..mdwn230
-rw-r--r--doc/bugs/On_restart__44___most_repositories__44___including_original_one__44___gone./comment_1_3a3891c9d7ee808f6a71780cb628f23d._comment12
-rw-r--r--doc/bugs/On_restart__44___most_repositories__44___including_original_one__44___gone./comment_2_2bc6efb1d9e872cc5d4fbfbaaf5cc10e._comment27
-rw-r--r--doc/bugs/On_restart__44___most_repositories__44___including_original_one__44___gone./comment_3_fff1e778a6334258c173a96e6bf7ef6a._comment10
-rw-r--r--doc/bugs/On_restart__44___most_repositories__44___including_original_one__44___gone./comment_4_2a86da97a89e28f0a0f5e160d4932ae6._comment19
-rw-r--r--doc/bugs/On_restart__44___most_repositories__44___including_original_one__44___gone./comment_5_41b8e8e58025cc8c8f12efb9a51acd29._comment50
-rw-r--r--doc/bugs/On_restart__44___most_repositories__44___including_original_one__44___gone./comment_6_38afcd8e7fb278ca0ee2e9e0c9f6883e._comment10
-rw-r--r--doc/bugs/On_restart__44___most_repositories__44___including_original_one__44___gone./comment_7_06de36dcde4c52ab74c8134f3242ac02._comment9
-rw-r--r--doc/bugs/Open_webapp_ask_to_create_new_repo___40__on_first_start__41___even_if_repo_exists_on_Android.mdwn40
-rw-r--r--doc/bugs/Open_webapp_ask_to_create_new_repo___40__on_first_start__41___even_if_repo_exists_on_Android/comment_1_9f10bf273b15e93f1eea029f091f26cb._comment12
-rw-r--r--doc/bugs/Out_of_memory_error_in_fsck_whereis_find_and_status_cmds.mdwn84
-rw-r--r--doc/bugs/Out_of_memory_error_in_fsck_whereis_find_and_status_cmds/comment_1_3aef6ca929fad198f2dda0868f2d49cb._comment18
-rw-r--r--doc/bugs/Out_of_memory_error_in_fsck_whereis_find_and_status_cmds/comment_2_f2c1aa84a0d04e840cb34ae15eb1cb03._comment8
-rw-r--r--doc/bugs/Out_of_memory_error_in_fsck_whereis_find_and_status_cmds/comment_3_480c39648e3ca6fc58c30377bdb25a8c._comment16
-rw-r--r--doc/bugs/Out_of_memory_error_in_fsck_whereis_find_and_status_cmds/comment_4_b31496b37046a9886f632ba4f11c56e3._comment8
-rw-r--r--doc/bugs/Out_of_memory_error_in_fsck_whereis_find_and_status_cmds/comment_5_d25ff424dda1f6021c1ba20f79d71ffc._comment12
-rw-r--r--doc/bugs/Out_of_memory_error_in_fsck_whereis_find_and_status_cmds/comment_6_9e3300b223dd54a3f07c650f5cf70ae0._comment8
-rw-r--r--doc/bugs/Out_of_memory_error_in_fsck_whereis_find_and_status_cmds/comment_7_b91f4a87b6d29ae6b4262922fd65a79d._comment8
-rw-r--r--doc/bugs/Pairing_locally_shows:___34__bad_comment_in_ssh_public_key_ssh-rsa__34__.mdwn23
-rw-r--r--doc/bugs/Partial_direct__47__indirect_repo.mdwn24
-rw-r--r--doc/bugs/Partial_direct__47__indirect_repo/comment_1_42344fce051d759f95215c985e9d1135._comment12
-rw-r--r--doc/bugs/Partial_direct__47__indirect_repo/comment_2_8ba64f2750d0ef4adf595674c723bc65._comment8
-rw-r--r--doc/bugs/Partial_direct__47__indirect_repo/comment_3_bd4985864b7dcd70a609ca7bc2617e4a._comment8
-rw-r--r--doc/bugs/Possible_data_loss_-_git_status___39__typechange__39___and_direct_mode.mdwn32
-rw-r--r--doc/bugs/Possible_data_loss_-_git_status___39__typechange__39___and_direct_mode/comment_1_84cb8c651584ec2887f6e1b7dc107190._comment8
-rw-r--r--doc/bugs/Possible_issues_with_git_1.7.10_and_newer___40__merge_command_now_asks_for_a_commit_message__34__.mdwn18
-rw-r--r--doc/bugs/Prevent_accidental_merges.mdwn14
-rw-r--r--doc/bugs/Prevent_accidental_merges/comment_1_4c46a193915eab8f308a04175cb2e40a._comment8
-rw-r--r--doc/bugs/Problem_when_dropping_unused_files.mdwn21
-rw-r--r--doc/bugs/Problem_when_dropping_unused_files/comment_10_d4f6bfe8e04560fc661a47b09ed8a5f4._comment8
-rw-r--r--doc/bugs/Problem_when_dropping_unused_files/comment_1_e1a99bd3eb8b3186653b52a52b1836de._comment10
-rw-r--r--doc/bugs/Problem_when_dropping_unused_files/comment_2_dec3e5ffe5cfdc439f418ee00d7d9810._comment8
-rw-r--r--doc/bugs/Problem_when_dropping_unused_files/comment_3_d106a87101db52f957da84d90dafcdbb._comment12
-rw-r--r--doc/bugs/Problem_when_dropping_unused_files/comment_4_f28ed0635612693e437e64d872af5c37._comment8
-rw-r--r--doc/bugs/Problem_when_dropping_unused_files/comment_5_f0237075653768c84deb702442645f28._comment8
-rw-r--r--doc/bugs/Problem_when_dropping_unused_files/comment_6_b509006e1590480a104627369bc910f2._comment8
-rw-r--r--doc/bugs/Problem_when_dropping_unused_files/comment_7_fe261c074211ccb94bbcb32cfd8ee654._comment14
-rw-r--r--doc/bugs/Problem_when_dropping_unused_files/comment_8_bc8e4dc7e0d6577ba5fcc98f56627b1f._comment8
-rw-r--r--doc/bugs/Problem_when_dropping_unused_files/comment_9_e9a22aa2ebcde5f6595b49dba9375761._comment14
-rw-r--r--doc/bugs/Problem_with_bup:_cannot_lock_refs.mdwn52
-rw-r--r--doc/bugs/Problems_building_on_Mac_OS_X.mdwn62
-rw-r--r--doc/bugs/Problems_building_on_Mac_OS_X/comment_1_1c199b826fdd84b5184b1466ad03a9a4._comment8
-rw-r--r--doc/bugs/Problems_running_make_on_osx.mdwn49
-rw-r--r--doc/bugs/Problems_running_make_on_osx/comment_10_94e4ac430140042a2d0fb5a16d86b4e5._comment8
-rw-r--r--doc/bugs/Problems_running_make_on_osx/comment_11_56f1143fa191361d63b441741699e17f._comment8
-rw-r--r--doc/bugs/Problems_running_make_on_osx/comment_12_ec5131624d0d2285d3b6880e47033f97._comment8
-rw-r--r--doc/bugs/Problems_running_make_on_osx/comment_13_88ed095a448096bf8a69015a04e64df1._comment16
-rw-r--r--doc/bugs/Problems_running_make_on_osx/comment_14_89a960b6706ed703b390a81a8bc4e311._comment8
-rw-r--r--doc/bugs/Problems_running_make_on_osx/comment_15_6b8867b8e48bf807c955779c9f8f0909._comment71
-rw-r--r--doc/bugs/Problems_running_make_on_osx/comment_16_5c2dd6002aadaab30841b77a5f5aed34._comment8
-rw-r--r--doc/bugs/Problems_running_make_on_osx/comment_17_62fccb04b0e4b695312f7a3f32fb96ee._comment43
-rw-r--r--doc/bugs/Problems_running_make_on_osx/comment_18_64fab50d95de619eb2e8f08f90237de1._comment24
-rw-r--r--doc/bugs/Problems_running_make_on_osx/comment_19_4253988ed178054c8b6400beeed68a29._comment11
-rw-r--r--doc/bugs/Problems_running_make_on_osx/comment_1_34120e82331ace01a6a4960862d38f2d._comment17
-rw-r--r--doc/bugs/Problems_running_make_on_osx/comment_20_7db27d1a22666c831848bc6c06d66a84._comment10
-rw-r--r--doc/bugs/Problems_running_make_on_osx/comment_2_cc53d1681d576186dbc868dd9801d551._comment8
-rw-r--r--doc/bugs/Problems_running_make_on_osx/comment_3_68f0f8ae953589ae26d57310b40c878d._comment57
-rw-r--r--doc/bugs/Problems_running_make_on_osx/comment_4_c52be386f79f14c8570a8f1397c68581._comment12
-rw-r--r--doc/bugs/Problems_running_make_on_osx/comment_5_7f1330a1e541b0f3e2192e596d7f7bee._comment107
-rw-r--r--doc/bugs/Problems_running_make_on_osx/comment_6_0c46f5165ceb5a7b9ea9689c33b3a4f8._comment9
-rw-r--r--doc/bugs/Problems_running_make_on_osx/comment_7_237a137cce58a28abcc736cbf2c420b0._comment22
-rw-r--r--doc/bugs/Problems_running_make_on_osx/comment_8_efafa203addf8fa79e33e21a87fb5a2b._comment8
-rw-r--r--doc/bugs/Problems_running_make_on_osx/comment_9_cc283b485b3c95ba7eebc8f0c96969b3._comment66
-rw-r--r--doc/bugs/Problems_with_syncing_gnucash.mdwn568
-rw-r--r--doc/bugs/Problems_with_syncing_gnucash/comment_1_ca195af3ba4a286eb5ab687634192fa4._comment8
-rw-r--r--doc/bugs/Problems_with_syncing_gnucash/comment_2_754fb430381ad88e6248ecb902b32118._comment20
-rw-r--r--doc/bugs/Problems_with_syncing_gnucash/comment_4_25881998c6f149c70b1358f37b7c66ba._comment20
-rw-r--r--doc/bugs/Provide_64-bit_standalone_build.mdwn6
-rw-r--r--doc/bugs/Provide_64-bit_standalone_build/comment_1_1850bb3eb464f1d3c122cfeb4ccaf265._comment15
-rw-r--r--doc/bugs/Proxy_support.mdwn18
-rw-r--r--doc/bugs/Remote_repo_and_set_operation_with_find.mdwn6
-rw-r--r--doc/bugs/Remote_repositories_have_to_be_setup_encrypted.mdwn27
-rw-r--r--doc/bugs/Remote_repositories_have_to_be_setup_encrypted/comment_1_95f73315657bc35a8d3ff9b4ba207af0._comment8
-rw-r--r--doc/bugs/Remotes_only_start_showing_changes_after_both_sides_have_written_to_the_repository.mdwn70
-rw-r--r--doc/bugs/Remotes_only_start_showing_changes_after_both_sides_have_written_to_the_repository/comment_1_92211091daf9827a4ec7e5b5a6769d59._comment8
-rw-r--r--doc/bugs/Remotes_only_start_showing_changes_after_both_sides_have_written_to_the_repository/comment_2_f0fa97a9eba1c624f6f8720ba8a160b7._comment8
-rw-r--r--doc/bugs/Remotes_only_start_showing_changes_after_both_sides_have_written_to_the_repository/comment_3_e3d677ea4170c07cd31efe6dc85fa5f3._comment8
-rw-r--r--doc/bugs/Renamed_special_remote_cannot_be_reactivated_by_the_webapp.mdwn30
-rw-r--r--doc/bugs/Repository_deletion_error.mdwn46
-rw-r--r--doc/bugs/Repository_deletion_error/comment_1_31673d0300986b6098d1af2cc4b180c6._comment10
-rw-r--r--doc/bugs/Resource_exhausted.mdwn45
-rw-r--r--doc/bugs/Resource_exhausted/comment_10_bccf9528ffe963154c92ce49762e7ea6._comment10
-rw-r--r--doc/bugs/Resource_exhausted/comment_1_a5ef7a62d4ed9365f9448520bb17e3b5._comment9
-rw-r--r--doc/bugs/Resource_exhausted/comment_2_cdba2015e603f3c21f3e1697dd6fafcd._comment18
-rw-r--r--doc/bugs/Resource_exhausted/comment_3_747d16d050fdcf69dd3d2bc5ca469a2e._comment39
-rw-r--r--doc/bugs/Resource_exhausted/comment_4_1e9b74e60da57c3d5f08c1eb3801c1d2._comment10
-rw-r--r--doc/bugs/Resource_exhausted/comment_5_f55d933bce77fd2185ebd0cc46fe57ec._comment64
-rw-r--r--doc/bugs/Resource_exhausted/comment_6_26c98fca45b029a527f9684873db4be5._comment18
-rw-r--r--doc/bugs/Resource_exhausted/comment_7_8bab413b472f900e04977db2bc3951b6._comment8
-rw-r--r--doc/bugs/Resource_exhausted/comment_8_e9bec0b80179b1229b6af0979a21c727._comment9
-rw-r--r--doc/bugs/Resource_exhausted/comment_9_419e24e0b91f569294ece28c42daa246._comment15
-rw-r--r--doc/bugs/Resource_leak_somewhere_in_the___39__get__39___code.mdwn24
-rw-r--r--doc/bugs/Resource_leak_somewhere_in_the___39__get__39___code/comment_1_66b21720cd1b2a4f66ef24252d3e6305._comment8
-rw-r--r--doc/bugs/Resource_leak_somewhere_in_the___39__get__39___code/comment_2_18c9f55c5af1f4f690a7727df71ab561._comment8
-rw-r--r--doc/bugs/Rsync_encrypted_remote_asks_for_ssh_key_password_for_each_file.mdwn30
-rw-r--r--doc/bugs/Rsync_encrypted_remote_asks_for_ssh_key_password_for_each_file/comment_1_fd95e0bb61e80a72b4ac1304ef6c2e77._comment16
-rw-r--r--doc/bugs/Rsync_remote_created_via_webapp_remains_empty.mdwn138
-rw-r--r--doc/bugs/Rsync_remote_created_via_webapp_remains_empty/comment_1_cccf9d58c0ebb8d31cacdd029ea8e23a._comment12
-rw-r--r--doc/bugs/S3_bucket_uses_the_same_key_for_encryption_and_hashing.mdwn10
-rw-r--r--doc/bugs/S3_bucket_uses_the_same_key_for_encryption_and_hashing/comment_1_dc5ae7af499203cfd903e866595b8fea._comment18
-rw-r--r--doc/bugs/S3_bucket_uses_the_same_key_for_encryption_and_hashing/comment_2_c62daf5b3bfcd2f684262c96ef6628c1._comment12
-rw-r--r--doc/bugs/S3_bucket_uses_the_same_key_for_encryption_and_hashing/comment_3_e1f39c4af5bdb0daabf000da80858cd9._comment10
-rw-r--r--doc/bugs/S3_bucket_uses_the_same_key_for_encryption_and_hashing/comment_4_bb6b814ab961818d514f6553455d2bf3._comment8
-rw-r--r--doc/bugs/S3_bucket_uses_the_same_key_for_encryption_and_hashing/comment_5_5bb128f6d2ca4b5e4d881fae297fa1f8._comment8
-rw-r--r--doc/bugs/S3_bucket_uses_the_same_key_for_encryption_and_hashing/comment_6_63fb74da342751fc35e1850409c506f6._comment8
-rw-r--r--doc/bugs/S3_buckets_with_capital_letters_breaks_authentication.mdwn32
-rw-r--r--doc/bugs/S3_memory_leaks.mdwn14
-rw-r--r--doc/bugs/S3_memory_leaks/comment_1_a7268213b090bce6b1f1858a8e23d90e._comment14
-rw-r--r--doc/bugs/S3_upload_not_using_multipart.mdwn53
-rw-r--r--doc/bugs/SSH:_command-line:_line_0:_Bad_configuration_option:_ControlPersist___40__SSH_too_old_on_OS_X_10.6.8__63____41__.mdwn27
-rw-r--r--doc/bugs/SSH:_command-line:_line_0:_Bad_configuration_option:_ControlPersist___40__SSH_too_old_on_OS_X_10.6.8__63____41__/comment_1_0c57a2196d35eb1ecfb0c51273bba05c._comment10
-rw-r--r--doc/bugs/Segfaults_on_Fedora_18_with_SELinux_enabled.mdwn65
-rw-r--r--doc/bugs/Segfaults_on_Fedora_18_with_SELinux_enabled/comment_1_f708d87aa65cd38c20087859d3ab2dc7._comment12
-rw-r--r--doc/bugs/Segfaults_on_Fedora_18_with_SELinux_enabled/comment_2_fb7188db031147992f3c906783ebbee0._comment59
-rw-r--r--doc/bugs/Selfsigned_certificates_with_jabber_fail_miserably..mdwn22
-rw-r--r--doc/bugs/Selfsigned_certificates_with_jabber_fail_miserably./comment_1_13d27ba41d9ef78c8db534b6bc26314e._comment12
-rw-r--r--doc/bugs/Selfsigned_certificates_with_jabber_fail_miserably./comment_2_018eed99e71680be9e7c0844020419bb._comment8
-rw-r--r--doc/bugs/Selfsigned_certificates_with_jabber_fail_miserably./comment_3_1e7578dd1321f399b12197056495b0b6._comment8
-rw-r--r--doc/bugs/Should_UUID__39__s_for_Remotes_be_case_sensitive__63__.txt46
-rw-r--r--doc/bugs/Should_UUID__39__s_for_Remotes_be_case_sensitive__63__/comment_1_00b52dba3bc30516e06c44cbfd3a05a2._comment17
-rw-r--r--doc/bugs/Should_UUID__39__s_for_Remotes_be_case_sensitive__63__/comment_2_8f5fa659c2ab91b1757bac31cd3b15eb._comment10
-rw-r--r--doc/bugs/Should_UUID__39__s_for_Remotes_be_case_sensitive__63__/comment_3_ccf9623d60c58d036d8bf24757e50de3._comment10
-rw-r--r--doc/bugs/Should_ignore_.thumbnails__47___on_android.mdwn28
-rw-r--r--doc/bugs/Should_try_again_when_network_fails___40__esp._DNS__41__.mdwn50
-rw-r--r--doc/bugs/Should_try_again_when_network_fails___40__esp._DNS__41__/comment_1_dd792bd98a48554a65150c06401ed3e5._comment12
-rw-r--r--doc/bugs/Small_archive_behaving_like_archive.mdwn33
-rw-r--r--doc/bugs/Small_archive_behaving_like_archive/comment_1_718dc246cbbbeae04436fa033011ab12._comment13
-rw-r--r--doc/bugs/Specifying_a_filename_starting_with___34__-c__34___instead_applies_it_to_all_files.mdwn75
-rw-r--r--doc/bugs/Specifying_a_filename_starting_with___34__-c__34___instead_applies_it_to_all_files/comment_1_2fe6d735bc075275a6b8890fac48ee58._comment18
-rw-r--r--doc/bugs/Stale_lock_files_on_Android.mdwn44
-rw-r--r--doc/bugs/Stress_test.mdwn45
-rw-r--r--doc/bugs/Stress_test/comment_10_1694e990eab6592159309c231c6dcc16._comment12
-rw-r--r--doc/bugs/Stress_test/comment_11_ab4cb6eefd279e6c1f229e089f703581._comment25
-rw-r--r--doc/bugs/Stress_test/comment_1_c4c764488ac082f5c48d3a6b4b5fba42._comment17
-rw-r--r--doc/bugs/Stress_test/comment_2_42125bba09a0ea9821cda7183e458100._comment47
-rw-r--r--doc/bugs/Stress_test/comment_3_8240e61106b494d3600ad91f16eb5b1c._comment20
-rw-r--r--doc/bugs/Stress_test/comment_4_c38d84e0dcc834931804c44bce7f7b7a._comment11
-rw-r--r--doc/bugs/Stress_test/comment_5_60ce20ee255451c4ea809ba475561adb._comment15
-rw-r--r--doc/bugs/Stress_test/comment_6_1371562e201393986cd41597f6f288cb._comment14
-rw-r--r--doc/bugs/Stress_test/comment_7_a14be7699da224a8f6c9b34f1b911219._comment8
-rw-r--r--doc/bugs/Stress_test/comment_8_a01995bdca7ade7dde9842b53fbc4e0c._comment57
-rw-r--r--doc/bugs/Stress_test/comment_9_9f7efe81b7e40aaa04a865394c53e20f._comment52
-rw-r--r--doc/bugs/Switching_between_direct_and_indirect_stomps_on___39__regular__39___git_files.mdwn27
-rw-r--r--doc/bugs/Switching_between_direct_and_indirect_stomps_on___39__regular__39___git_files/comment_1_0d2cb3b8509cd0eba50aafa14afefc02._comment63
-rw-r--r--doc/bugs/Switching_from_indirect_mode_to_direct_mode_breaks_duplicates.mdwn30
-rw-r--r--doc/bugs/Switching_repositories_in_webapp_on_a_remote_server_is_not_honoring_--listen_parameter.mdwn21
-rw-r--r--doc/bugs/Switching_repositories_in_webapp_on_a_remote_server_is_not_honoring_--listen_parameter/comment_1_4dd773372979dd95538bfba6516a11eb._comment9
-rw-r--r--doc/bugs/Syncing_creates_broken_links_instead_of_proper_files.mdwn51
-rw-r--r--doc/bugs/Syncing_creates_broken_links_instead_of_proper_files/comment_1_a2bedb2e77451b02fc66fc9ef5c4405c._comment11
-rw-r--r--doc/bugs/Test_failure_on_debian_dropunused.mdwn31
-rw-r--r--doc/bugs/The_assistant_hangs_forever.mdwn46
-rw-r--r--doc/bugs/The_assistant_hangs_forever/comment_1_b0291e32860e0da0b66837d14ed5aab6._comment8
-rw-r--r--doc/bugs/The_assistant_hangs_forever/comment_2_a2950cf91b8a4e4f2951f5522ef0e9c4._comment18
-rw-r--r--doc/bugs/The_assistant_hangs_forever/comment_3_db95f78519d5ffbad793906028730dab._comment12
-rw-r--r--doc/bugs/The_assistant_hangs_forever/comment_4_28b13fd3165b38a2fbc9e1a461c38921._comment22
-rw-r--r--doc/bugs/The_assistant_hangs_forever/comment_5_81a79c8840ff26307a9c6edad5b850f9._comment9
-rw-r--r--doc/bugs/The_assistant_hangs_forever/comment_6_b739719b14705f4d7e1d412b3cab090c._comment17
-rw-r--r--doc/bugs/The_assistant_hangs_forever/comment_7_2b300d960697c5b967c1f109dfd6dfbf._comment16
-rw-r--r--doc/bugs/The_assistant_hangs_forever/comment_8_8623220d08b1a72ed8b669a2d9cc0f75._comment15
-rw-r--r--doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible.mdwn29
-rw-r--r--doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_10_8305becdc6e70abdaf17e42f263173fc._comment12
-rw-r--r--doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_11_d75896a6e204d1abdda04923aa668d04._comment8
-rw-r--r--doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_12_a36a4a64a04c01c2db467b09300e6ebd._comment8
-rw-r--r--doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_13_c9d6631c304acb289e485fb901e1f274._comment35
-rw-r--r--doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_14_10282c4352075c8d148b8674973b7b16._comment22
-rw-r--r--doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_15_ceb68da01d9e2fe9a70fab6244116da0._comment15
-rw-r--r--doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_16_cca4abde86a8be5e2919c4738f5bdd0c._comment18
-rw-r--r--doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_17_2fa5d7d9110c91b0a3a833cb3d9f53fd._comment10
-rw-r--r--doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_18_bf21d28142e4c304aa0bc740955ddea0._comment10
-rw-r--r--doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_19_45537758fa937f16fc82120bf8b234e8._comment8
-rw-r--r--doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_1_a38497772834a4b12137390b461ce70b._comment12
-rw-r--r--doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_20_b685050ee6fbb1a685e33f9656a10e84._comment8
-rw-r--r--doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_3_17bc0220c20553c848875475c5fd4ae6._comment12
-rw-r--r--doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_4_76472bc58bb790f773c46ec2c39fcf88._comment11
-rw-r--r--doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_4_dcd9286e314779c25764484beff40561._comment10
-rw-r--r--doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_5_2146eec77b87b615100d0d003e8dce75._comment15
-rw-r--r--doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_6_2bd6f4e04903ee251d43d0a97bd40b6e._comment8
-rw-r--r--doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_7_7db8ed002eb6313b07f09bd1a34019e3._comment10
-rw-r--r--doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_8_1bcb2a238006044bc78849e56cb21a01._comment9
-rw-r--r--doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_9_26c6937cf78e7141e0e3b20f25ed8f7a._comment8
-rw-r--r--doc/bugs/The_tests_are_failing_to_build_now_on_commit_e0fdfb2e706da2cb1451193c658dc676b0530968.mdwn23
-rw-r--r--doc/bugs/The_webapp_doesn__39__t_allow_deleting_repositories.mdwn33
-rw-r--r--doc/bugs/The_webapp_doesn__39__t_allow_deleting_repositories/comment_1_1b80f9cfedd25e34997fa07e08d15012._comment8
-rw-r--r--doc/bugs/The_webapp_doesn__39__t_allow_deleting_repositories/comment_2_53499da1185c56d8fd25f86ba41d96ce._comment11
-rw-r--r--doc/bugs/The_webapp_doesn__39__t_allow_deleting_repositories/comment_3_3e07b8386d2c7afce2a78d24b9c260b9._comment14
-rw-r--r--doc/bugs/Too_many_open_files.mdwn55
-rw-r--r--doc/bugs/Too_many_open_files/comment_1_d5d509b9b431d2ea6000ebc0aed62857._comment8
-rw-r--r--doc/bugs/Too_much_system_load_on_startup.mdwn24
-rw-r--r--doc/bugs/Too_much_system_load_on_startup/comment_1_4470cddc0965062588acff1bc77285e9._comment8
-rw-r--r--doc/bugs/TransferScanner_crash_on_Android.mdwn24
-rw-r--r--doc/bugs/TransferScanner_crash_on_Android/comment_1_6c3584ade1ee6cccddddeaa8e1697945._comment20
-rw-r--r--doc/bugs/TransferScanner_crash_on_Android/comment_2_06574e05149a677d666a722061586658._comment10
-rw-r--r--doc/bugs/TransferScanner_crash_on_Android/comment_3_54ae097d30bb7a49fe151f38c9bac033._comment8
-rw-r--r--doc/bugs/Transfers_continue_after_daemon_stopped.mdwn5
-rw-r--r--doc/bugs/Transfers_continue_after_daemon_stopped/comment_1_39eb527d64367e6762281246f1d49b1f._comment12
-rw-r--r--doc/bugs/Tries_to_upload_to_remote_although_remote_is_dead.mdwn51
-rw-r--r--doc/bugs/Tries_to_upload_to_remote_although_remote_is_dead/comment_1_108b3984891f82429430b503cddfb3c1._comment10
-rw-r--r--doc/bugs/Tries_to_upload_to_remote_although_remote_is_dead/comment_2_fa5b1bc26ed3e5bfe48441490c94fe3a._comment8
-rw-r--r--doc/bugs/Tries_to_upload_to_remote_although_remote_is_dead/comment_3_0a785b5dfbf4eef30854d6bedb12b7d1._comment10
-rw-r--r--doc/bugs/Trouble_initializing_git_annex_on_NFS.mdwn16
-rw-r--r--doc/bugs/Trouble_initializing_git_annex_on_NFS/comment_1_e26952373150d63b8a5d3643a2762de1._comment10
-rw-r--r--doc/bugs/Trouble_initializing_git_annex_on_NFS/comment_2_f80b10ed395738e50e345fc22c708ae5._comment10
-rw-r--r--doc/bugs/Trouble_initializing_git_annex_on_NFS/comment_3_f99e0f05950fc2fc80fdecd35e17012c._comment8
-rw-r--r--doc/bugs/Trouble_initializing_git_annex_on_NFS/comment_4_e42146d2dcc4052266dd61d204aeb551._comment8
-rw-r--r--doc/bugs/True_backup_support.mdwn7
-rw-r--r--doc/bugs/True_backup_support/comment_1_50aa0bc1e2502622585682cb703e0b85._comment10
-rw-r--r--doc/bugs/True_backup_support/comment_2_d6030c6c49b227e022f05d590746d4ca._comment8
-rw-r--r--doc/bugs/Truncated_file_transferred_via_S3.mdwn614
-rw-r--r--doc/bugs/Truncated_file_transferred_via_S3/comment_1_5962358e6067448f633cc0eaf42f9ca7._comment10
-rw-r--r--doc/bugs/Truncated_file_transferred_via_S3/comment_2_75a2c272c36fc4fe8f9a79a3fd3ac4e5._comment19
-rw-r--r--doc/bugs/Truncated_file_transferred_via_S3/comment_3_3dae1914c8c90fdad0c21e1fc795f2ca._comment8
-rw-r--r--doc/bugs/Truncated_file_transferred_via_S3/comment_4_3c5fe109f2196cfc196c30da3b62bafd._comment10
-rw-r--r--doc/bugs/Truncated_file_transferred_via_S3/comment_5_f86f83c89300f255e730ddd23f876f61._comment16
-rw-r--r--doc/bugs/Unable_to_add_files_on_Android_due_to_weird_rename_error.mdwn37
-rw-r--r--doc/bugs/Unable_to_add_files_on_Android_due_to_weird_rename_error/comment_1_928289956111d1b22f9d55f15b54f72f._comment10
-rw-r--r--doc/bugs/Unable_to_add_files_on_Android_due_to_weird_rename_error/comment_2_6a0cb836b93ba4cb1e07b11d5d2a7094._comment8
-rw-r--r--doc/bugs/Unable_to_import_feed.mdwn27
-rw-r--r--doc/bugs/Unable_to_import_feed/comment_1_16230fbbb996e165b84787ed4d5f72ea._comment45
-rw-r--r--doc/bugs/Unable_to_switch_back_to_direct_mode.mdwn55
-rw-r--r--doc/bugs/Unable_to_switch_back_to_direct_mode/comment_1_4585b251f011a153c62f377c324cf963._comment24
-rw-r--r--doc/bugs/Unable_to_switch_back_to_direct_mode/comment_2_5848ebbab38d1244347f7e7351b3a30d._comment10
-rw-r--r--doc/bugs/Unable_to_switch_back_to_direct_mode/comment_3_1c5c7b0c7bc336e00f43e257b87a6208._comment8
-rw-r--r--doc/bugs/Unable_to_switch_back_to_direct_mode/comment_4_b0bfd68998bc3e11d8e089646b8292a6._comment12
-rw-r--r--doc/bugs/Unable_to_sync_a_second_machine_through_Box.mdwn46
-rw-r--r--doc/bugs/Unable_to_sync_a_second_machine_through_Box/comment_1_cb43a2bc976e3eb1cfc3ee9d4d34e78e._comment22
-rw-r--r--doc/bugs/Unable_to_sync_a_second_machine_through_Box/comment_2_3375e9bfab3fed271413bd9bb5fa0121._comment30
-rw-r--r--doc/bugs/Unable_to_sync_a_second_machine_through_Box/comment_3_c4420e1a3db321b4135b1626d3582adb._comment12
-rw-r--r--doc/bugs/Unable_to_sync_a_second_machine_through_Box/comment_4_f4b2c88bb5938dacdd04dfe9a68560de._comment18
-rw-r--r--doc/bugs/Unable_to_sync_a_second_machine_through_Box/comment_5_6dcc95ffb3fc7bbbedd6be5df0111c85._comment8
-rw-r--r--doc/bugs/Unable_to_use_remotes_with_space_in_the_path.mdwn35
-rw-r--r--doc/bugs/Unfortunate_interaction_with_Calibre.mdwn24
-rw-r--r--doc/bugs/Unfortunate_interaction_with_Calibre/comment_1_7cb5561f11dfc7726a537ddde2477489._comment8
-rw-r--r--doc/bugs/Unfortunate_interaction_with_Calibre/comment_2_b8ae4bc589c787dacc08ab2ee5491d6e._comment8
-rw-r--r--doc/bugs/Unfortunate_interaction_with_Calibre/comment_3_977c5f6b82f9e18cdd81d57005bb8b89._comment8
-rw-r--r--doc/bugs/Unfortunate_interaction_with_Calibre/comment_4_ff7d2e9a39dfe12b975d04650ac57cc4._comment8
-rw-r--r--doc/bugs/Unfortunate_interaction_with_Calibre/comment_5_fc4d5301797589e92cc9a24697b2155d._comment15
-rw-r--r--doc/bugs/Unknown_command___39__list__39__.mdwn15
-rw-r--r--doc/bugs/Unknown_command___39__list__39__/comment_1_c625d03d1ed2019141ac9202f933466d._comment8
-rw-r--r--doc/bugs/Unknown_command___39__list__39__/comment_2_800e1b6417768bdadda311ebfb5df637._comment8
-rw-r--r--doc/bugs/Unknown_command___39__list__39__/comment_3_35dfc75ce9efffff139f8929dc311e29._comment10
-rw-r--r--doc/bugs/Unknown_remote_type_webdav.mdwn8
-rw-r--r--doc/bugs/Unnecessary_remote_transfers.mdwn24
-rw-r--r--doc/bugs/Unnecessary_remote_transfers/comment_10_b778fbb1386f0f51bf057ffacd590ebb._comment12
-rw-r--r--doc/bugs/Unnecessary_remote_transfers/comment_11_55430eac842d0a192dc7f41d7730e4d5._comment10
-rw-r--r--doc/bugs/Unnecessary_remote_transfers/comment_1_00c18e07678dc513a02d974fe059df73._comment12
-rw-r--r--doc/bugs/Unnecessary_remote_transfers/comment_2_2e9992dbfceabd6df535a2770626de16._comment35
-rw-r--r--doc/bugs/Unnecessary_remote_transfers/comment_3_a98f3091a6a658919f0562cf396439c2._comment8
-rw-r--r--doc/bugs/Unnecessary_remote_transfers/comment_4_417c1e8e27ee1a1f9ebf9160560605c5._comment96
-rw-r--r--doc/bugs/Unnecessary_remote_transfers/comment_5_eb5a2717a1f0c7bb761d2a7866b23def._comment8
-rw-r--r--doc/bugs/Unnecessary_remote_transfers/comment_6_89f756db1f3f2e60a3bd1f35f55fee43._comment40
-rw-r--r--doc/bugs/Unnecessary_remote_transfers/comment_7_5aaf8766a7ba05c4f92715e5d5175a8f._comment13
-rw-r--r--doc/bugs/Unnecessary_remote_transfers/comment_8_e856b350632cc865d16d1995a6cdf065._comment14
-rw-r--r--doc/bugs/Unnecessary_remote_transfers/comment_9_64f831545b34b78452952cf49b5f5b05._comment25
-rw-r--r--doc/bugs/Update_dependency_on_certificate___62____61___1.3.3.mdwn64
-rw-r--r--doc/bugs/Use_a_git_repository_on_the_server_don__39__t_work.mdwn49
-rw-r--r--doc/bugs/Use_a_git_repository_on_the_server_don__39__t_work/comment_1_2143f0540fdcd7efeb25b5a3b54fe0fd._comment12
-rw-r--r--doc/bugs/Use_a_git_repository_on_the_server_don__39__t_work/comment_2_bca95245b457631d08b47591da6163ad._comment9
-rw-r--r--doc/bugs/Use_a_git_repository_on_the_server_don__39__t_work/comment_3_f54bb003096752dae0442660267a1e37._comment11
-rw-r--r--doc/bugs/Use_a_git_repository_on_the_server_don__39__t_work/comment_4_38bb916ed5b90b92ffa91a452ff052a9._comment10
-rw-r--r--doc/bugs/Use_a_git_repository_on_the_server_don__39__t_work/comment_5_5b6ef464ab1ad061f27122db40191e26._comment8
-rw-r--r--doc/bugs/Use_a_git_repository_on_the_server_don__39__t_work/comment_6_3727bda5082cb1f2b1f746f9f80ced7d._comment8
-rw-r--r--doc/bugs/Use_a_git_repository_on_the_server_don__39__t_work/comment_7_a7139f19f0b73c024cd9218eb01e6104._comment8
-rw-r--r--doc/bugs/Using_Github_as_remote_throws_proxy_errors.mdwn27
-rw-r--r--doc/bugs/Using_Github_as_remote_throws_proxy_errors/comment_1_10616b17c3fb8286fdc64c841023f8a1._comment9
-rw-r--r--doc/bugs/Using_Github_as_remote_throws_proxy_errors/comment_2_8a72887d33e492a041f8246d93d0c778._comment8
-rw-r--r--doc/bugs/Using_a_revoked_GPG_key.mdwn34
-rw-r--r--doc/bugs/Using_a_revoked_GPG_key/comment_1_7bb01d081282e5b02b7720b2953fe5be._comment8
-rw-r--r--doc/bugs/Using_a_revoked_GPG_key/comment_2_9c0c40360f0058a4bd346c1362e302b6._comment8
-rw-r--r--doc/bugs/Using_a_revoked_GPG_key/comment_3_8f69f58107246595f5603f35c4aa7395._comment8
-rw-r--r--doc/bugs/Using_a_revoked_GPG_key/comment_4_78b3c52ba85edfa6ee6e273bec3bea5c._comment13
-rw-r--r--doc/bugs/Using_a_revoked_GPG_key/comment_5_a85ccf2f09ebe87147f8761b81a02326._comment8
-rw-r--r--doc/bugs/Using_a_revoked_GPG_key/comment_6_8b89eb5e6386acd0a922310c04f863ac._comment12
-rw-r--r--doc/bugs/Using_a_revoked_GPG_key/comment_7_20dc5a7ce7cb6ca97ccdfb923c3b24bb._comment10
-rw-r--r--doc/bugs/Using_a_revoked_GPG_key/comment_8_9dc921dc6077f828454a4444088b9a43._comment15
-rw-r--r--doc/bugs/Using_a_revoked_GPG_key/comment_9_f50c802d78041fd1522f0e7599ce6a45._comment42
-rw-r--r--doc/bugs/WEBDAV_443.mdwn307
-rw-r--r--doc/bugs/WEBDAV_443/comment_10_9ee2c5ed44295455af890caee7b06f1a._comment18
-rw-r--r--doc/bugs/WEBDAV_443/comment_11_863a7d315212c9a8ab8f6fafa5d1b7f5._comment8
-rw-r--r--doc/bugs/WEBDAV_443/comment_12_c17a4e23011e0a917dbe0ecf7e9f0cb5._comment8
-rw-r--r--doc/bugs/WEBDAV_443/comment_13_3414416ff455d2fd1a7c7e7c4554b54d._comment11
-rw-r--r--doc/bugs/WEBDAV_443/comment_14_e1da141eefb0445c217e5f5c119356da._comment8
-rw-r--r--doc/bugs/WEBDAV_443/comment_15_41c3134bcc222b97bf183559723713d9._comment27
-rw-r--r--doc/bugs/WEBDAV_443/comment_16_89621b526065b5bef753ce75db1af7b5._comment14
-rw-r--r--doc/bugs/WEBDAV_443/comment_17_131a1b65c8008cf9f02c93d4fb75720b._comment10
-rw-r--r--doc/bugs/WEBDAV_443/comment_18_b4f894a0b9ebb84ab73f6ffcf0778090._comment29
-rw-r--r--doc/bugs/WEBDAV_443/comment_1_c6572ca1eaaf89b01c0ed99a4058412f._comment10
-rw-r--r--doc/bugs/WEBDAV_443/comment_2_a357969cde382a91e13920ee1e9f711c._comment8
-rw-r--r--doc/bugs/WEBDAV_443/comment_3_213815d6b827d467c60f3e8af925813b._comment14
-rw-r--r--doc/bugs/WEBDAV_443/comment_4_b775be4b722fc7124d9fbe2d5d01cc9f._comment22
-rw-r--r--doc/bugs/WEBDAV_443/comment_5_c4ea745da437e56b2426d1c2c00dfcec._comment17
-rw-r--r--doc/bugs/WEBDAV_443/comment_6_ef05c0ae88fee9c626922c6064ffdf1e._comment8
-rw-r--r--doc/bugs/WEBDAV_443/comment_7_eecabe8d5ed564cb540450770ca7d0b6._comment8
-rw-r--r--doc/bugs/WEBDAV_443/comment_8_7f77ba8ebd90186d3b3949ae529ba393._comment12
-rw-r--r--doc/bugs/WEBDAV_443/comment_9_87ebdc92b48d672964fb3f248c53600f._comment9
-rw-r--r--doc/bugs/WORM:_Handle_long_filenames_correctly.mdwn4
-rw-r--r--doc/bugs/WORM:_Handle_long_filenames_correctly/comment_1_77aa9cafbe20367a41377f3edccc9ddb._comment10
-rw-r--r--doc/bugs/WORM:_Handle_long_filenames_correctly/comment_2_fe735d728878d889ccd34ec12b3a7dea._comment8
-rw-r--r--doc/bugs/WORM:_Handle_long_filenames_correctly/comment_3_2bf0f02d27190578e8f4a32ddb195a0a._comment10
-rw-r--r--doc/bugs/WORM:_Handle_long_filenames_correctly/comment_4_8f7ba9372463863dda5aae13205861bf._comment8
-rw-r--r--doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults.mdwn31
-rw-r--r--doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_10_6c872dff4fcc63c16bf69d1e96891c89._comment8
-rw-r--r--doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_1_5cad24007f819e4be193123dab0d511a._comment10
-rw-r--r--doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_2_d449bf656a59d424833f9ab5a7fb4e82._comment8
-rw-r--r--doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_3_ffb1ce41477ad60840abd7a89a133067._comment8
-rw-r--r--doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_4_cebbc138c6861c086bb7937b54f5adbc._comment8
-rw-r--r--doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_5_5e27737a5bb0e9e46c98708700318e67._comment8
-rw-r--r--doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_6_1f92da712232d050e085a4f39063d7a6._comment21
-rw-r--r--doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_7_4153dc8029c545f8e86584a38bd536fb._comment15
-rw-r--r--doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_8_f85b6eb5bfd28ffc6973fb4ab0fe4337._comment8
-rw-r--r--doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_9_c747c488461c98cd285b51d3afc2c3eb._comment10
-rw-r--r--doc/bugs/Watcher_crashed:_addWatch:_does_not_exist.mdwn25
-rw-r--r--doc/bugs/Watcher_crashed:_addWatch:_does_not_exist/comment_1_24f511a8103727894c6e96798a559870._comment10
-rw-r--r--doc/bugs/Watcher_crashed:_addWatch:_does_not_exist/comment_2_e14eddbc09cadbf1e4dbbb0c07e0e5b0._comment10
-rw-r--r--doc/bugs/Watcher_crashed:_addWatch:_does_not_exist/comment_3_513fae4d379008f954a307be8df34976._comment13
-rw-r--r--doc/bugs/Watcher_crashed:_addWatch:_does_not_exist/comment_4_172eaeb3bb8b502379695aba35f96120._comment12
-rw-r--r--doc/bugs/Watcher_crashed:_addWatch:_does_not_exist/comment_5_8adb9de82cc8581422734acc66dd094c._comment11
-rw-r--r--doc/bugs/Watcher_crashed:_addWatch:_does_not_exist/comment_6_02f0beef1188bfa336bf4220eb5c6286._comment13
-rw-r--r--doc/bugs/Watcher_crashed_in_Android_on___47__storage__47__sdcard1_-_bug__63__.mdwn43
-rw-r--r--doc/bugs/Watcher_crashed_in_Android_on___47__storage__47__sdcard1_-_bug__63__/comment_1_71b052be40fbdaca09ca3ede8c59ac7a._comment8
-rw-r--r--doc/bugs/Watcher_crashed_in_Android_on___47__storage__47__sdcard1_-_bug__63__/comment_3_0f7cc02e0193c969c9b6ceb27e71af8a._comment20
-rw-r--r--doc/bugs/Watcher_crashed_in_Android_on___47__storage__47__sdcard1_-_bug__63__/comment_3_1a7542249b9c37507126e97441057c12._comment12
-rw-r--r--doc/bugs/WebDAV_HandshakeFailed_.mdwn7
-rw-r--r--doc/bugs/WebDAV_HandshakeFailed_/comment_1_40499110ea43bc99ad9dd9f642da434c._comment15
-rw-r--r--doc/bugs/WebDAV_HandshakeFailed_/comment_2_506712e8cc5b47b9bd69edf67ae54da7._comment10
-rw-r--r--doc/bugs/WebDAV_HandshakeFailed_/comment_3_5641481d9e9ed2b711b1516f1abc5c30._comment8
-rw-r--r--doc/bugs/WebDAV_HandshakeFailed_/comment_4_1d609de93fa66ce9dc802e67b5922243._comment8
-rw-r--r--doc/bugs/WebDAV_HandshakeFailed_/comment_5_62761882d30c1b02930c938cb8e30ed4._comment10
-rw-r--r--doc/bugs/WebDAV_HandshakeFailed_/comment_6_acda8fae848ec486ce2a0b3dff3bd0a5._comment8
-rw-r--r--doc/bugs/WebDAV_HandshakeFailed_/comment_7_6c51b6c7dd477d8911dd9a7a5c41ea2e._comment8
-rw-r--r--doc/bugs/WebDAV_HandshakeFailed_/comment_8_e834f791d3000669fab25732a7c72ab3._comment13
-rw-r--r--doc/bugs/Webapp_fails_to_resolve_ipv6_hostname.mdwn15
-rw-r--r--doc/bugs/Weird_behaviour_of_direct_and_indirect_annexes.mdwn57
-rw-r--r--doc/bugs/Weird_behaviour_of_direct_and_indirect_annexes/comment_1_56474a69c2f174d83be9137d3c045a47._comment33
-rw-r--r--doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace.mdwn49
-rw-r--r--doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_0._comment34
-rw-r--r--doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_10_037a6dd6e15ef5f789a1f364f7507b53._comment45
-rw-r--r--doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_11_614e4110188fc6474e7da50fc4281e13._comment10
-rw-r--r--doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_12_dcb74fb91e1c2f0db4efd68c8bcbc96c._comment20
-rw-r--r--doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_14_38671ba8d302f4d32460d1478abd2111._comment45
-rw-r--r--doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_14_483244b1ed5744308022465f45c091fd._comment14
-rw-r--r--doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_1_d2c63723fa4bf828873770a42ffaab20._comment8
-rw-r--r--doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_3_52f0db73dc38c3e3a73f6c7a420bf016._comment8
-rw-r--r--doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_4_93596b4d5a48ffcf4bc11ba9c83cf7ca._comment9
-rw-r--r--doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_5_de94e80dde6d12485140bb079d74d775._comment14
-rw-r--r--doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_6_5f34c3d449247b4bce4665b3ea4d054c._comment25
-rw-r--r--doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_7_b43ae8aec23ba3acaf70edc0de058710._comment17
-rw-r--r--doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_8_13b8e0a62f6b6d02960687e206a8b016._comment15
-rw-r--r--doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_9_818b94a74b01a210d1106dd35bc932d8._comment10
-rw-r--r--doc/bugs/Windows_and_Linux_in_direct_mode_confuses_git.mdwn384
-rw-r--r--doc/bugs/Windows_and_Linux_in_direct_mode_confuses_git/comment_1_155e0c4d3aa41eebfe27533ab70a91d3._comment68
-rw-r--r--doc/bugs/Windows_build_test_failures.mdwn1232
-rw-r--r--doc/bugs/Windows_build_test_failures/comment_1_ea7523fdbafdc8be2971df52d9038826._comment10
-rw-r--r--doc/bugs/Windows_installer_includes_curl_and_wget__44___but_not_required_DLLs.mdwn17
-rw-r--r--doc/bugs/Windows_installer_includes_curl_and_wget__44___but_not_required_DLLs/comment_1_a7bf0f027f2209e5632e292afd7214d0._comment10
-rw-r--r--doc/bugs/Windows_to_Linux_clone_-_Windows_drive_letters_cause_git_annex_get_to_fail.mdwn131
-rw-r--r--doc/bugs/Windows_to_Linux_clone_-_Windows_drive_letters_cause_git_annex_get_to_fail/comment_1_c87bae87b7902db60a3fef41e1fca85d._comment9
-rw-r--r--doc/bugs/Windows_to_Linux_clone_-_Windows_drive_letters_cause_git_annex_get_to_fail/comment_2_9e3c1f1ba05d8996b5a95829ce32c07e._comment10
-rw-r--r--doc/bugs/Windows_to_Linux_clone_-_Windows_drive_letters_cause_git_annex_get_to_fail/comment_3_3a0787912f4a3a8797b7786f5ce38590._comment8
-rw-r--r--doc/bugs/Windows_to_Linux_clone_-_Windows_drive_letters_cause_git_annex_get_to_fail/comment_4_c4249f32d65594d79ea01145b93ec948._comment9
-rw-r--r--doc/bugs/With_S3__44___GPG_ask_for_a_new_passphrase.mdwn21
-rw-r--r--doc/bugs/With_S3__44___GPG_ask_for_a_new_passphrase/comment_1_a4fc30bf7d39cae337286e9e815e6cba._comment13
-rw-r--r--doc/bugs/With_S3__44___GPG_ask_for_a_new_passphrase/comment_2_e5d42b623017acedf6a3890ce15680a3._comment12
-rw-r--r--doc/bugs/With_S3__44___GPG_ask_for_a_new_passphrase/comment_3_e5150b65b514896e14b9ad3d951963f7._comment10
-rw-r--r--doc/bugs/With_S3__44___GPG_ask_for_a_new_passphrase/comment_4_47c2fc167b0c396edc40468fb7c7bfee._comment8
-rw-r--r--doc/bugs/Won__39__t_drop_files__44___even_though_remote_annexes_have_at_least_numcopies.mdwn39
-rw-r--r--doc/bugs/Wrong_port_while_configuring_ssh_remote.mdwn35
-rw-r--r--doc/bugs/Zombie_processes_and__47__or_stuck_git_processes.mdwn44
-rw-r--r--doc/bugs/Zombie_processes_and__47__or_stuck_git_processes/comment_1_0f8b248025722309e9577d7dad74b76b._comment10
-rw-r--r--doc/bugs/Zombie_processes_and__47__or_stuck_git_processes/comment_2_f5f7db688a2a93ee7453674fb742043b._comment52
-rw-r--r--doc/bugs/Zombie_processes_and__47__or_stuck_git_processes/comment_3_ffcae976aa3dc2426188797c1aaffb82._comment10
-rw-r--r--doc/bugs/Zombie_processes_and__47__or_stuck_git_processes/comment_4_8a7ff6841ad7c27ead06bf12f46b20a0._comment49
-rw-r--r--doc/bugs/Zombie_processes_and__47__or_stuck_git_processes/comment_5_406fdee0728680774a69d28446163f10._comment26
-rw-r--r--doc/bugs/__34__Adding_4923_files__34___is_really_slow.mdwn100
-rw-r--r--doc/bugs/__34__Adding_4923_files__34___is_really_slow/comment_2_5f3b9f00bc31ce71d695c008971ed7fd._comment16
-rw-r--r--doc/bugs/__34__Adding_4923_files__34___is_really_slow/comment_2_708b02dd06a1eed6b5ded9eb7aa9e7a8._comment16
-rw-r--r--doc/bugs/__34__Adding_4923_files__34___is_really_slow/comment_3_6a735b7875d2a0c92df6786dd649985d._comment28
-rw-r--r--doc/bugs/__34__Adding_4923_files__34___is_really_slow/comment_4_7e768908ba6983ea13af27635c4a947f._comment12
-rw-r--r--doc/bugs/__34__Configuring_Jabber_Account__34___fails_with_a___34__Network_unreachable__34___error..mdwn39
-rw-r--r--doc/bugs/__34__Configuring_Jabber_Account__34___fails_with_a___34__Network_unreachable__34___error./comment_1_6d821af99ab3c83a5b0f52d3713ab8e2._comment10
-rw-r--r--doc/bugs/__34__Configuring_Jabber_Account__34___fails_with_a___34__Network_unreachable__34___error./comment_2_206b6c8cce8350fc088f01c42fc4715b._comment8
-rw-r--r--doc/bugs/__34__Configuring_Jabber_Account__34___fails_with_a___34__Network_unreachable__34___error./comment_3_ed36f503f88611382b50687608b9b7e7._comment10
-rw-r--r--doc/bugs/__34__annex_sync__34___gets_confused_when_operating_in_a_symlink__39__ed_directory.mdwn18
-rw-r--r--doc/bugs/__34__drop__34___deletes_all_files_with_identical_content.mdwn49
-rw-r--r--doc/bugs/__34__drop__34___deletes_all_files_with_identical_content/comment_1_2eb20b65582fa7f271b1d0bb5560d08c._comment10
-rw-r--r--doc/bugs/__34__drop__34___deletes_all_files_with_identical_content/comment_2_b14e1d31dd6a8fb930fcc0bec798e194._comment19
-rw-r--r--doc/bugs/__34__drop__34___deletes_all_files_with_identical_content/comment_3_1892bcfbe3c462aa74552a241d65cad9._comment8
-rw-r--r--doc/bugs/__34__drop__34___deletes_all_files_with_identical_content/comment_4_dfa0e31996eaa14e2945c1d11670c4d9._comment15
-rw-r--r--doc/bugs/__34__drop__34___deletes_all_files_with_identical_content/comment_5_e2a9336cf1080c158765d4adfe72f26b._comment9
-rw-r--r--doc/bugs/__34__fatal:_bad_config_file__34__.mdwn14
-rw-r--r--doc/bugs/__34__git_annex_watch__34___adds_map.dot.mdwn23
-rw-r--r--doc/bugs/__34__make_test__34___fails_silently.mdwn4
-rw-r--r--doc/bugs/__34__make_test__34___fails_silently/comment_1_f868e34f41d828d4571968d1ab07820a._comment16
-rw-r--r--doc/bugs/__34__make_test__34___fails_silently/comment_2_fb9e8e2716b0dea15b0d4807ae7cd114._comment8
-rw-r--r--doc/bugs/__39__annex_add__39___fails_to___39__git_add__39___for_parent_relative_path.mdwn15
-rw-r--r--doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content.mdwn24
-rw-r--r--doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content/comment_1_56f9cd5cc2e089b32cb076dc2e2a8ca5._comment22
-rw-r--r--doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content/comment_2_21c0f7f328cb51080fbd97e086c47a30._comment37
-rw-r--r--doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content/comment_3_3287b2f25f3b5ae4c27f4748694563ee._comment8
-rw-r--r--doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content/comment_4_e515eca68a70d40c522805d7e0d7c0e6._comment24
-rw-r--r--doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content/comment_5_b27f4c103dda050b6e9cf03ea3157abc._comment10
-rw-r--r--doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content/comment_6_2cc7083dab944705bf91fc00319b75e6._comment9
-rw-r--r--doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content/comment_7_1175f9be789d4c1907f0be98e435bd2f._comment10
-rw-r--r--doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content/comment_8_78e6164ef67a9560a3a9ead1f7a72473._comment15
-rw-r--r--doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content/comment_9_1d578fd13022dcd6382b415a7f6e097a._comment8
-rw-r--r--doc/bugs/__40__assistant__41___dependency_on_ssh-askpass_-_not_installed_automatically_on_xubuntu.mdwn22
-rw-r--r--doc/bugs/__40__assistant__41___dependency_on_ssh-askpass_-_not_installed_automatically_on_xubuntu/comment_1_f4656f8a0f36535def0772db06098c5f._comment13
-rw-r--r--doc/bugs/__91__Installation__93___There_is_no_available_version_of_quickcheck_that_satisfies___62____61__2.1.mdwn40
-rw-r--r--doc/bugs/__91__webapp__93___pause_syncing_with_specific_repository.mdwn8
-rw-r--r--doc/bugs/__91__wishlistAndroid:_bundle_an_ssh_server___40__dropbear__63____41___and_add_an_option_to_start_it_easily_with_the_terminal_app_menu.mdwn21
-rw-r--r--doc/bugs/__91__wishlistAndroid:_bundle_an_ssh_server___40__dropbear__63____41___and_add_an_option_to_start_it_easily_with_the_terminal_app_menu/comment_1_9bb53c45d685b368c7ba1758885f2874._comment12
-rw-r--r--doc/bugs/__91__wishlistAndroid:_bundle_an_ssh_server___40__dropbear__63____41___and_add_an_option_to_start_it_easily_with_the_terminal_app_menu/comment_2_251311a04f1a610e54ebe8e9b92de72e._comment13
-rw-r--r--doc/bugs/__96__git_annex_add__96___changes_mtime_if_symlinks_are_fixed_in_the_background.mdwn51
-rw-r--r--doc/bugs/__96__git_annex_fix__96___run_on_non-annexed_files_is_no-op.mdwn15
-rw-r--r--doc/bugs/__96__git_annex_fix__96___run_on_non-annexed_files_is_no-op/comment_1_9b671e583eec5adf870dccd1e97b5dbc._comment8
-rw-r--r--doc/bugs/__96__git_annex_fix__96___run_on_non-annexed_files_is_no-op/comment_2_d11744202213d6f897f4234bc4c70c18._comment9
-rw-r--r--doc/bugs/__96__git_annex_fix__96___run_on_non-annexed_files_is_no-op/comment_3_a729deb465ff44f5a9b87c963cd6235a._comment15
-rw-r--r--doc/bugs/__96__git_annex_fix__96___run_on_non-annexed_files_is_no-op/comment_4_3f735503df9a08472d42fabd219c2ec5._comment31
-rw-r--r--doc/bugs/__96__git_annex_fix__96___run_on_non-annexed_files_is_no-op/comment_5_2c61eabbba7fd2a52ba02d59a0a76a42._comment8
-rw-r--r--doc/bugs/__96__git_annex_import__96___clobbers_mtime.mdwn62
-rw-r--r--doc/bugs/__96__git_annex_import__96___clobbers_mtime/comment_1_d173f2903faf4bff115a0be02c146ce9._comment8
-rw-r--r--doc/bugs/__96__git_annex_import__96___clobbers_mtime/comment_2_3563d9eeb9806f8ca1b9b340925837f5._comment18
-rw-r--r--doc/bugs/__96__git_annex_import__96___clobbers_mtime/comment_3_d5c7488db16b71c4f337662c897278ca._comment95
-rw-r--r--doc/bugs/__96__git_annex_import__96___clobbers_mtime/comment_4_7235130786e764ec3ad5facfecde62da._comment8
-rw-r--r--doc/bugs/__96__git_annex_import__96___does_not_work_on_other_git_annex_repositories.mdwn113
-rw-r--r--doc/bugs/__96__git_annex_import__96___does_not_work_on_other_git_annex_repositories/comment_1_94ccd548c084286163eeb2af1ddc18e3._comment8
-rw-r--r--doc/bugs/__96__git_annex_import__96___does_not_work_on_other_git_annex_repositories/comment_2_befde3ef3d2b171ebb691915ff3af172._comment8
-rw-r--r--doc/bugs/__96__git_annex_sync__96___ignores_remotes.mdwn106
-rw-r--r--doc/bugs/__96__git_annex_sync__96___ignores_remotes/comment_1_39421e6935233cd8f45949ebdef369fe._comment9
-rw-r--r--doc/bugs/__96__git_annex_sync__96___ignores_remotes/comment_2_53fb15d6fbf96d43564ff7c866239d18._comment8
-rw-r--r--doc/bugs/_impossible_to_switch_repositories_on_android__in_webapp.mdwn21
-rw-r--r--doc/bugs/_impossible_to_switch_repositories_on_android__in_webapp/comment_1_d488d71a72eb54d7711d2a867db6172f._comment8
-rw-r--r--doc/bugs/_impossible_to_switch_repositories_on_android__in_webapp/comment_2_85b31db6d0fb2d20018db3d8c8258bf4._comment8
-rw-r--r--doc/bugs/acl_not_honoured_in_rsync_remote.mdwn57
-rw-r--r--doc/bugs/acl_not_honoured_in_rsync_remote/comment_1_aa6fe1d7b029eae7ee71c97e0f0937a6._comment8
-rw-r--r--doc/bugs/acl_not_honoured_in_rsync_remote/comment_2_ffb9424e966ee10a4fe2d446b3042cb2._comment10
-rw-r--r--doc/bugs/add_range_argument_to___34__git_annex_dropunused__34___.mdwn21
-rw-r--r--doc/bugs/add_script-friendly_output_options.mdwn19
-rw-r--r--doc/bugs/added_branches_makes___39__git_annex_unused__39___slow.mdwn87
-rw-r--r--doc/bugs/added_branches_makes___39__git_annex_unused__39___slow/comment_1_d350c39c67031c500e3224e92c0029ea._comment19
-rw-r--r--doc/bugs/added_branches_makes___39__git_annex_unused__39___slow/comment_2_b2d2b1caa51ffec3d87c36b373cb8d4a._comment20
-rw-r--r--doc/bugs/added_branches_makes___39__git_annex_unused__39___slow/comment_3_12b20cbbc2b4cd1ab8af7e3eec9589b4._comment30
-rw-r--r--doc/bugs/added_branches_makes___39__git_annex_unused__39___slow/comment_4_a50b43c15d2650df90f0fa1ced47f532._comment10
-rw-r--r--doc/bugs/added_branches_makes___39__git_annex_unused__39___slow/comment_5_7328bc51bd001f2b732a92a2ae175839._comment114
-rw-r--r--doc/bugs/added_branches_makes___39__git_annex_unused__39___slow/comment_6_880ef2ee797221332dbb629b2d55522f._comment10
-rw-r--r--doc/bugs/added_branches_makes___39__git_annex_unused__39___slow/comment_7_826fd82cdf9b1c79c9b555ca26c2c176._comment8
-rw-r--r--doc/bugs/adding_an_rsync.net_repo_give_an_gpg_error.mdwn22
-rw-r--r--doc/bugs/adding_an_rsync.net_repo_give_an_gpg_error/comment_1_f55cfc133be72ac10cae93c877c487df._comment21
-rw-r--r--doc/bugs/adding_an_rsync.net_repo_give_an_gpg_error/comment_2_24dd024ac4b21a82a781343b8fe3891e._comment11
-rw-r--r--doc/bugs/addurl:___34__rename:_does_not_exist__34___and_reports_fail__44___but_succeeds.mdwn197
-rw-r--r--doc/bugs/addurl:___34__rename:_does_not_exist__34___and_reports_fail__44___but_succeeds/comment_1_1f5e0bc93631baf0f8c1bec2e68493c5._comment20
-rw-r--r--doc/bugs/addurl_--relaxed_with_--file_doesn__39__t_actually_relax.mdwn26
-rw-r--r--doc/bugs/addurl_fails_on_the_internet_archive.mdwn65
-rw-r--r--doc/bugs/addurl_fails_on_the_internet_archive/comment_1_e227aa25eea0b41f1176037a601c5844._comment10
-rw-r--r--doc/bugs/addurl_fails_on_the_internet_archive/comment_2_6d4fd58f0caa1f75ee2dd3f0a909cd91._comment8
-rw-r--r--doc/bugs/addurl_file_doesn__39__t_work_with_spaces_in_filenames_and_--fast.mdwn29
-rw-r--r--doc/bugs/addurl_file_doesn__39__t_work_with_spaces_in_filenames_and_--fast/comment_1_eea9477ea1157cb88c8a07d8da5f0dba._comment10
-rw-r--r--doc/bugs/allows_repository_with_the_same_name_twice.mdwn24
-rw-r--r--doc/bugs/allows_repository_with_the_same_name_twice/comment_1_ba7801403e7138684704a3471c8bc4a6._comment12
-rw-r--r--doc/bugs/allows_repository_with_the_same_name_twice/comment_2_8c19a4ddedbe7ddb8bdcf84acac68cc8._comment14
-rw-r--r--doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit.mdwn28
-rw-r--r--doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_10_1d841ff0b0ffd814efed2449dc1f35f3._comment10
-rw-r--r--doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_10_cd101e0af45d8f463011fb0d04b3b822._comment9
-rw-r--r--doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_11_8595041cfe703d9bea49e792732dc15f._comment8
-rw-r--r--doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_1_8e7bc6965ea967a8d43240791a30c5bc._comment9
-rw-r--r--doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_2_891c1073f908b204651899d41599f944._comment8
-rw-r--r--doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_3_de02b8f1b5928fa1a7078c4aa2124bea._comment11
-rw-r--r--doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_6_506acc4275a81ed9e9b08e8a40fcf96a._comment9
-rw-r--r--doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_7_d38d6f40db4c9437764c7b2ddf36b5a9._comment10
-rw-r--r--doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_8_9bb23e9cbc77ecca4b1209b0f66bc2b0._comment8
-rw-r--r--doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_9_d1ce7fc251db076da61eed5bb9d71b9a._comment9
-rw-r--r--doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_9_feb71c1022ff65d82e66a3958a41dfb2._comment8
-rw-r--r--doc/bugs/android_4.2.1__44___galaxy_nexus_java.lang.SecurityException.mdwn41
-rw-r--r--doc/bugs/annex-rsync-options_shell-split_carelessly.mdwn16
-rw-r--r--doc/bugs/annex-rsync-options_shell-split_carelessly/comment_1_2636e0d224317f2e6db94658d8a094c4._comment23
-rw-r--r--doc/bugs/annex.numcopies_not_overriden_by_--numcopies_option.mdwn16
-rw-r--r--doc/bugs/annex_add_in_annex.mdwn6
-rw-r--r--doc/bugs/annex_get_fails:___34__No_such_file_or_directory__34__.mdwn68
-rw-r--r--doc/bugs/annex_get_over_SSH_is_very_slow.mdwn33
-rw-r--r--doc/bugs/annex_unannex__47__uninit_should_handle_copies.mdwn20
-rw-r--r--doc/bugs/annex_unannex__47__uninit_should_handle_copies/comment_1_c896ff6589f62178b60e606771e4f2bf._comment10
-rw-r--r--doc/bugs/annex_unannex__47__uninit_should_handle_copies/comment_2_9249609f83f8e9c7521cd2f007c1a39e._comment8
-rw-r--r--doc/bugs/another_build_error_in_assistant.mdwn79
-rw-r--r--doc/bugs/archiving_git_repositories.mdwn1
-rw-r--r--doc/bugs/archiving_git_repositories/comment_1_51f546a571303118446a9e0b3e6482c9._comment10
-rw-r--r--doc/bugs/assistant_-_GTalk_collision.mdwn17
-rw-r--r--doc/bugs/assistant_-_GTalk_collision/comment_1_ab2c1f36113d40f27e1893d32f214296._comment12
-rw-r--r--doc/bugs/assistant_-_GTalk_collision/comment_2_91dff34c629a3b3a97a2313ff077e4ae._comment14
-rw-r--r--doc/bugs/assistant_-_GTalk_collision/comment_3_fefb73f6e570f96b4d82779d6622f690._comment8
-rw-r--r--doc/bugs/assistant___40__OS_X_Lion__41___-___34__too_many_open_files__34___error.mdwn32
-rw-r--r--doc/bugs/assistant___40__OS_X_Lion__41___-___34__too_many_open_files__34___error/comment_1_9904c30a4c24a699d71e90ce5e9b89cf._comment8
-rw-r--r--doc/bugs/assistant_always_assumes_port_22__63__.mdwn39
-rw-r--r--doc/bugs/assistant_bails_when_adding_encrypted_usbdrive_repo_on_mac.mdwn53
-rw-r--r--doc/bugs/assistant_bails_when_adding_encrypted_usbdrive_repo_on_mac/comment_1_4ea192e57f86a33087997746722e6acf._comment10
-rw-r--r--doc/bugs/assistant_bails_when_adding_encrypted_usbdrive_repo_on_mac/comment_2_622ad5b34780fc8468c5c515ad9f27fa._comment8
-rw-r--r--doc/bugs/assistant_cannot_set_up_remote_repo_via_an_ssh_alias_or_an_ip_address/comment_1_1650539846521ae11837e4ac73348af6._comment9
-rw-r--r--doc/bugs/assistant_cannot_set_up_remote_repo_via_an_ssh_alias_or_an_ip_address/comment_2_b91415e4ee74eb12bc6e6faddd00af6e._comment12
-rw-r--r--doc/bugs/assistant_does_not_allow_adding_an_existing_repo.mdwn8
-rw-r--r--doc/bugs/assistant_does_not_allow_adding_an_existing_repo/comment_1_87e84d56d56abefe8cac8a52b76c9003._comment8
-rw-r--r--doc/bugs/assistant_does_not_always_use_repo_cost_info_when_queueing_downloads.mdwn16
-rw-r--r--doc/bugs/assistant_does_not_list_remote___39__origin__39__.mdwn26
-rw-r--r--doc/bugs/assistant_does_not_list_remote___39__origin__39__/comment_1_ffa008240c61b50396aa92f467731db6._comment12
-rw-r--r--doc/bugs/assistant_does_not_list_remote___39__origin__39__/comment_2_a53f80090bc2a0f32b8d8307cb24b563._comment8
-rw-r--r--doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add.mdwn46
-rw-r--r--doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add/comment_1_13b2f93b7d09c8fd6c22829a0dc6428b._comment10
-rw-r--r--doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add/comment_2_94e46bc0044b8a91a9fd51058825aa8f._comment60
-rw-r--r--doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add/comment_3_10a38bdbf31dd4071e4bc4ac746d9c56._comment11
-rw-r--r--doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add/comment_4_b8fdf502c7e80aece5a9544a2078c85c._comment36
-rw-r--r--doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add/comment_5_a2ff7668f2a0d549b362d7de97fac8a1._comment10
-rw-r--r--doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add/comment_6_60d72f34a6cfd1c081f74aa610f4305a._comment33
-rw-r--r--doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add/comment_7_53a73e662c9356b759fbfa1e5a3bd927._comment14
-rw-r--r--doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add/comment_8_10b65168b6a54d960427966d7e3d05f5._comment19
-rw-r--r--doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add/comment_9_b640e8fa6aafb041d66bbf8857a8fa3d._comment44
-rw-r--r--doc/bugs/assistant_doesn__39__t_sync_empty_directories.mdwn30
-rw-r--r--doc/bugs/assistant_doesn__39__t_sync_empty_directories/comment_1_78a3bde607f43c0f518bd2d3d7196022._comment8
-rw-r--r--doc/bugs/assistant_doesn__39__t_sync_empty_directories/comment_2_83777384b72732b1d0a19b32686d3d1f._comment8
-rw-r--r--doc/bugs/assistant_doesn__39__t_sync_empty_directories/comment_3_f9b2a700c060707fae1bcb2ec0e4e4dc._comment9
-rw-r--r--doc/bugs/assistant_doesn__39__t_sync_empty_directories/comment_4_014d213a959dd7993bdd247722a8817e._comment8
-rw-r--r--doc/bugs/assistant_doesn__39__t_sync_empty_directories/comment_5_440f349781d7d9ca2d1ed81386f7dd26._comment8
-rw-r--r--doc/bugs/assistant_doesn__39__t_sync_file_permissions.mdwn45
-rw-r--r--doc/bugs/assistant_doesn__39__t_sync_file_permissions/comment_1_fc8d3ea209a2ab39c1aeff52452d4c58._comment10
-rw-r--r--doc/bugs/assistant_doesn__39__t_sync_file_permissions/comment_2_1a364c422e0dd7418f74e1cc3d543a3c._comment8
-rw-r--r--doc/bugs/assistant_doesn__39__t_sync_file_permissions/comment_3_4d5ae51b4c7e6177d934d7c9f21b912c._comment8
-rw-r--r--doc/bugs/assistant_fails_to_sync_in_preferred_content_mode_manual.mdwn24
-rw-r--r--doc/bugs/assistant_fails_to_sync_in_preferred_content_mode_manual/comment_1_37acb3afafb1b4c4da7c778130cf3035._comment8
-rw-r--r--doc/bugs/assistant_fails_to_sync_in_preferred_content_mode_manual/comment_2_9d58887ee0184663852bde83b8d497c7._comment10
-rw-r--r--doc/bugs/assistant_fails_to_sync_in_preferred_content_mode_manual/comment_3_b70881c8026e30fd3ddc051bd01a888b._comment8
-rw-r--r--doc/bugs/assistant_fails_to_sync_in_preferred_content_mode_manual/comment_4_43f756e2e6ff985c8e050da0e369d486._comment25
-rw-r--r--doc/bugs/assistant_fails_to_sync_in_preferred_content_mode_manual/comment_5_eda947eb7f8c46b9a61d6430b5f9ebfd._comment25
-rw-r--r--doc/bugs/assistant_hangs_during_commit.mdwn27
-rw-r--r--doc/bugs/assistant_hangs_during_commit/comment_1_aacc15c589d2795254387e427b3afe0c._comment8
-rw-r--r--doc/bugs/assistant_hangs_during_commit/comment_2_b9f1bf9fa919603dca28182c80d39a11._comment10
-rw-r--r--doc/bugs/assistant_hangs_during_commit/comment_3_fb5be10fcf5e7c89da5c34f48539612f._comment12
-rw-r--r--doc/bugs/assistant_hangs_during_commit/comment_4_9ba7efe9112578729d02ac4e6557b3cc._comment10
-rw-r--r--doc/bugs/assistant_hangs_during_commit/comment_5_73b24c901c73d41e0e0abe91267d4920._comment16
-rw-r--r--doc/bugs/assistant_hangs_during_commit/comment_6_1a30b8c82e58222f1366aa368c23e6d3._comment10
-rw-r--r--doc/bugs/assistant_hangs_during_commit/comment_7_56868b2a504ad0a60e8a8c1928330175._comment8
-rw-r--r--doc/bugs/assistant_ignore_.gitignore.mdwn31
-rw-r--r--doc/bugs/assistant_ignore_.gitignore/comment_1_3458b1342cb2e3ccc01eeedc7f0e48fc._comment8
-rw-r--r--doc/bugs/assistant_ignore_.gitignore/comment_2_22f75af80c779dcb4d6033b90373f74e._comment10
-rw-r--r--doc/bugs/assistant_ignore_.gitignore/comment_3_8b2a400e1d44a1c9b183e2b7861efbe3._comment8
-rw-r--r--doc/bugs/assistant_ignores___34__manual__34___group__44___tries_to_transfer_files.mdwn56
-rw-r--r--doc/bugs/assistant_ignores___34__manual__34___group__44___tries_to_transfer_files/comment_1_e3f545d9adc27a4e7340bf16177c4fe0._comment12
-rw-r--r--doc/bugs/assistant_ignores___34__manual__34___group__44___tries_to_transfer_files/comment_2_1403076dbc47733607f0c8b2856e2381._comment37
-rw-r--r--doc/bugs/assistant_ignores___34__manual__34___group__44___tries_to_transfer_files/comment_3_af83717bfb260bea6d52ff71c6b34743._comment8
-rw-r--r--doc/bugs/assistant_ignores___34__manual__34___group__44___tries_to_transfer_files/comment_4_b4f811611d14e7392009c539fa6b8574._comment8
-rw-r--r--doc/bugs/assistant_listens_on_127.0.0.1_not_::1_which_breaks_IPv6_enabled_hosts.mdwn30
-rw-r--r--doc/bugs/assistant_listens_on_127.0.0.1_not_::1_which_breaks_IPv6_enabled_hosts/comment_1_91a62a2ce14a1027d2ac8b8e88df5f0c._comment12
-rw-r--r--doc/bugs/assistant_listens_on_127.0.0.1_not_::1_which_breaks_IPv6_enabled_hosts/comment_2_4982cd373eaaeee180be03c6e9fda7b1._comment10
-rw-r--r--doc/bugs/assistant_listens_on_127.0.0.1_not_::1_which_breaks_IPv6_enabled_hosts/comment_3_85d264e311acaa91dac0597ee8deda82._comment8
-rw-r--r--doc/bugs/assistant_not_noticing_file_renames__44___not_fixing_files.mdwn68
-rw-r--r--doc/bugs/assistant_not_noticing_file_renames__44___not_fixing_files/comment_1_e0dafc410ffd617d445bb9403c7bfafe._comment9
-rw-r--r--doc/bugs/assistant_not_noticing_file_renames__44___not_fixing_files/comment_2_2af247c8a1fcbde10795a990ef3303e9._comment9
-rw-r--r--doc/bugs/assistant_syncs_with_remotes_even_when_all_remotes_disabled.mdwn33
-rw-r--r--doc/bugs/assistant_wants_my_gpg_passphrase_when_it_has_nothing_to_drop_or_copy_to_that_remote.mdwn5
-rw-r--r--doc/bugs/assistant_wants_my_gpg_passphrase_when_it_has_nothing_to_drop_or_copy_to_that_remote/comment_1_10a9570a5d762ba2da271b38dc63edb6._comment12
-rw-r--r--doc/bugs/assistant_wants_my_gpg_passphrase_when_it_has_nothing_to_drop_or_copy_to_that_remote/comment_2_57d50955b038c2e2405068536c7e83f3._comment8
-rw-r--r--doc/bugs/assistant_wants_my_gpg_passphrase_when_it_has_nothing_to_drop_or_copy_to_that_remote/comment_3_a66f34daaba421c87eb404ef933e5191._comment10
-rw-r--r--doc/bugs/assistant_wants_my_gpg_passphrase_when_it_has_nothing_to_drop_or_copy_to_that_remote/comment_4_094a3272eca1c6d2b4d264911ffe96e5._comment19
-rw-r--r--doc/bugs/assistant_wants_my_gpg_passphrase_when_it_has_nothing_to_drop_or_copy_to_that_remote/comment_5_0161410d042a3421addd4a1fc7c1cd01._comment10
-rw-r--r--doc/bugs/authentication_to_rsync.net_fails.mdwn30
-rw-r--r--doc/bugs/authentication_to_rsync.net_fails/comment_1_9db65f89415c8d825f268afb75244998._comment10
-rw-r--r--doc/bugs/backend_version_upgrade_leaves_repo_unusable.mdwn72
-rw-r--r--doc/bugs/bad_behaviour_with_file_names_with_newline_in_them.mdwn5
-rw-r--r--doc/bugs/bad_behaviour_with_file_names_with_newline_in_them/comment_1_92dfe6e9089c79eb64e2177fb135ef55._comment10
-rw-r--r--doc/bugs/bad_comment_in_ssh_public_key_ssh-rsa.mdwn22
-rw-r--r--doc/bugs/bad_comment_in_ssh_public_key_ssh-rsa/comment_1_15cce6e6f455e83f4362a38c561bc973._comment17
-rw-r--r--doc/bugs/bad_comment_in_ssh_public_key_ssh-rsa/comment_2_e9e1f38880a32610b3fbce475bffc3e4._comment12
-rw-r--r--doc/bugs/bad_comment_in_ssh_public_key_ssh-rsa/comment_3_51da7f5881f65422328d341e5ab0d250._comment33
-rw-r--r--doc/bugs/bad_comment_in_ssh_public_key_ssh-rsa/comment_4_ba384314c1e47ec4b72e1843e0500df9._comment10
-rw-r--r--doc/bugs/bare_git_repos.mdwn29
-rw-r--r--doc/bugs/box.com_never_stops_syncing..mdwn63
-rw-r--r--doc/bugs/box.com_never_stops_syncing./comment_1_124a5edcd89cc6b61e1a41f5b4d640d7._comment10
-rw-r--r--doc/bugs/box.com_never_stops_syncing./comment_2_42574181aa721319ba54eadf0a15ddff._comment11
-rw-r--r--doc/bugs/box.com_never_stops_syncing./comment_3_2ad727849070cfd52d6c719478e9cce3._comment8
-rw-r--r--doc/bugs/box.com_never_stops_syncing./comment_4_83ce23e45f5a5845d4f04519ee14ec65._comment9
-rw-r--r--doc/bugs/box.com_never_stops_syncing./comment_5_ef1c9d87b04db5047ab72167d3269687._comment8
-rw-r--r--doc/bugs/box.com_never_stops_syncing./comment_6_c9cb39eba941678035f9b2888da1085c._comment10
-rw-r--r--doc/bugs/box.com_never_stops_syncing./comment_7_4b0632a4e37c96959a8e6434e9fd86fb._comment17
-rw-r--r--doc/bugs/box.com_never_stops_syncing./comment_8_d9d318b8c958de6031ae323da20af625._comment55
-rw-r--r--doc/bugs/box.com_never_stops_syncing./comment_9_689ac6a4a305197cf5566f98dab47b4b._comment8
-rw-r--r--doc/bugs/bug_in_download_prebuilt_linux_tarball__44___and_constraints_issues_with_3.20121112.mdwn45
-rw-r--r--doc/bugs/build_fails_in_Assistant__47__WebApp__47__Gpg.hs.mdwn57
-rw-r--r--doc/bugs/build_failure_with_kqueue_code__44___first_commit_that_breaks_is_3dce75fb23fca94ad86c3f0ee816bb0ad2ecb27c.mdwn25
-rw-r--r--doc/bugs/build_is_broken_at_commit_cc0e5b7.mdwn13
-rw-r--r--doc/bugs/build_issue_with_8baff14054e65ecbe801eb66786a55fa5245cb30.mdwn43
-rw-r--r--doc/bugs/build_issue_with_latest_release_0.20110522-1-gde817ba.mdwn14
-rw-r--r--doc/bugs/build_problem_on_OSX.mdwn18
-rw-r--r--doc/bugs/building_on_lenny.mdwn80
-rw-r--r--doc/bugs/bup_initremote_failed_with_localhost_+_username.mdwn49
-rw-r--r--doc/bugs/bup_initremote_failed_with_localhost_+_username/comment_1_0e669c3039b089fa8a815d3ec11465d2._comment20
-rw-r--r--doc/bugs/cabal_build:___34__Could_not_find_module___96__Data.AssocList__39____34__.mdwn23
-rw-r--r--doc/bugs/cabal_build:___34__Could_not_find_module___96__Data.AssocList__39____34__/comment_1_0da9fd67c3cc01b316f95a1df4eb62ae._comment8
-rw-r--r--doc/bugs/cabal_configure_is_broken_on_OSX_builds.mdwn14
-rw-r--r--doc/bugs/cabal_install_fails_to_install_manpage.mdwn43
-rw-r--r--doc/bugs/cabal_install_on_Ubuntu_12.04_fails_with_complaint_about_regex-base.mdwn34
-rw-r--r--doc/bugs/call_to_git-annex-shell_when_on_centralised___40__non-git-annex__41___repository.mdwn208
-rw-r--r--doc/bugs/call_to_git-annex-shell_when_on_centralised___40__non-git-annex__41___repository/comment_1_dd202a7764d9df998868d595a86ffb21._comment30
-rw-r--r--doc/bugs/call_to_git-annex-shell_when_on_centralised___40__non-git-annex__41___repository/comment_2_ca065c82ac8e3215b581660f3e44f459._comment51
-rw-r--r--doc/bugs/call_to_git-annex-shell_when_on_centralised___40__non-git-annex__41___repository/comment_3_927a01f9961c71bedb42c519a31b5fe5._comment14
-rw-r--r--doc/bugs/can__39__t_annex_get_from_annex_in_direct_mode.mdwn23
-rw-r--r--doc/bugs/can__39__t_annex_get_from_annex_in_direct_mode/comment_1_20c31a844d8351a99cf69e05d2836e0e._comment19
-rw-r--r--doc/bugs/can__39__t_annex_get_from_annex_in_direct_mode/comment_2_f26e0f763f9027d9dfc08cd840ced153._comment10
-rw-r--r--doc/bugs/can__39__t_run_the_assistant_from_the_command_line_anymore__63__.mdwn31
-rw-r--r--doc/bugs/can_not_add_ssh_remote_to_assistant_with___34__host:port__34___syntax.mdwn30
-rw-r--r--doc/bugs/can_not_add_ssh_remote_to_assistant_with___34__host:port__34___syntax/comment_1_397eb359c3f8ef30460a9556b6f55848._comment14
-rw-r--r--doc/bugs/cannot_add_file__44___get___34__user_error__34__.mdwn32
-rw-r--r--doc/bugs/cannot_add_file__44___get___34__user_error__34__/comment_1_14aa717c1befcbbf526f25ca2f0af825._comment14
-rw-r--r--doc/bugs/cannot_add_file__44___get___34__user_error__34__/comment_2_7f7ac59e7f3dce9d7a7d0c3379c2edcf._comment18
-rw-r--r--doc/bugs/cannot_add_file__44___get___34__user_error__34__/comment_3_5ebf03120b12edb3fbb8954546e7603e._comment8
-rw-r--r--doc/bugs/cannot_add_file__44___get___34__user_error__34__/comment_4_1ba6d2614778949520b47896fd98b598._comment8
-rw-r--r--doc/bugs/cannot_add_file__44___get___34__user_error__34__/comment_5_4a6e55861a63b350a02edb888b4da99b._comment21
-rw-r--r--doc/bugs/cannot_connect_to_xmpp_server.mdwn32
-rw-r--r--doc/bugs/cannot_connect_to_xmpp_server/comment_10_5072de8fcca9fe70bc235ea8c8ee2877._comment8
-rw-r--r--doc/bugs/cannot_connect_to_xmpp_server/comment_11_dabd74bba1f38b326a2d0c86d3027cd9._comment17
-rw-r--r--doc/bugs/cannot_connect_to_xmpp_server/comment_12_0245b426cc0ab64f8c167b8806b03f5d._comment10
-rw-r--r--doc/bugs/cannot_connect_to_xmpp_server/comment_1_307df11b5bcf289d7999e1e7f7c461c9._comment10
-rw-r--r--doc/bugs/cannot_connect_to_xmpp_server/comment_2_f24378cf30a7d32594da90749fabec3c._comment12
-rw-r--r--doc/bugs/cannot_connect_to_xmpp_server/comment_3_4b07093be844ac62b611cee1dfde5aa7._comment8
-rw-r--r--doc/bugs/cannot_connect_to_xmpp_server/comment_4_fe1ed152a485c4aebfa9b9f300101835._comment8
-rw-r--r--doc/bugs/cannot_connect_to_xmpp_server/comment_5_2d311f520aee04287df6bddfd8535734._comment28
-rw-r--r--doc/bugs/cannot_connect_to_xmpp_server/comment_6_d9f916f012184738446c5996ee9d2270._comment13
-rw-r--r--doc/bugs/cannot_connect_to_xmpp_server/comment_7_0b5f9350e2367301241c7668a15815ef._comment8
-rw-r--r--doc/bugs/cannot_connect_to_xmpp_server/comment_8_f00b6ae154004e405f0bd23b7359962e._comment8
-rw-r--r--doc/bugs/cannot_connect_to_xmpp_server/comment_9_41b86468013da15f46be29da520afa10._comment8
-rw-r--r--doc/bugs/cannot_determine_uuid_for_origin.mdwn135
-rw-r--r--doc/bugs/cannot_link_executable_on_android.mdwn28
-rw-r--r--doc/bugs/case-insensitive.mdwn20
-rw-r--r--doc/bugs/case_sensitivity_on_FAT.mdwn49
-rw-r--r--doc/bugs/check_for_curl_in_configure.hs.mdwn92
-rw-r--r--doc/bugs/clicking_back_in_the_web_browser_crashes.mdwn23
-rw-r--r--doc/bugs/clicking_back_in_the_web_browser_crashes/comment_1_c962218657a28494ff837a471d71b43f._comment8
-rw-r--r--doc/bugs/clicking_back_in_the_web_browser_crashes/comment_2_643b2c99ecfe851c576a023ce4385dbb._comment10
-rw-r--r--doc/bugs/clicking_back_in_the_web_browser_crashes/comment_3_6e85c50439da81212f4239c74947b75e._comment12
-rw-r--r--doc/bugs/com.branchable.git-annex.assistant.plist_is_invalid.mdwn15
-rw-r--r--doc/bugs/commitBuffer:_invalid_argument___40__invalid_character__41__.mdwn228
-rw-r--r--doc/bugs/commit_f20a40f_breaks_on_OSX_as_mntent.h_doesn__39__t_exist.mdwn8
-rw-r--r--doc/bugs/concurrent_git-annex_processes_can_lead_to_locking_issues.mdwn53
-rw-r--r--doc/bugs/configurable_path_to_git-annex-shell.mdwn7
-rw-r--r--doc/bugs/configurable_path_to_git-annex-shell/comment_1_fb6771f902b57f2b690e7cc46fdac47e._comment10
-rw-r--r--doc/bugs/configurable_path_to_git-annex-shell/comment_2_2b856f4f0b65c2331be7d565f0e4e8a8._comment8
-rw-r--r--doc/bugs/configurable_path_to_git-annex-shell/comment_3_aea42acc039a82efc6bb3a8f173a632e._comment12
-rw-r--r--doc/bugs/configure_mistakes_hashalot_bins_for_sha__63____63____63__sum_and_builds_a_broken_git-annex_executable.mdwn57
-rw-r--r--doc/bugs/configure_script_should_detect_uuidgen_instead_of_just_uuid.mdwn6
-rw-r--r--doc/bugs/conflicting_haskell_packages.mdwn17
-rw-r--r--doc/bugs/conflicting_haskell_packages/comment_1_e552a6cc6d7d1882e14130edfc2d6b3b._comment24
-rw-r--r--doc/bugs/conq:_invalid_command_syntax.mdwn30
-rw-r--r--doc/bugs/conq:_invalid_command_syntax/comment_1_f33b83025ce974e496f83f248275a66a._comment10
-rw-r--r--doc/bugs/conq:_invalid_command_syntax/comment_2_195106ca8dedad5f4d755f625e38e8af._comment9
-rw-r--r--doc/bugs/conq:_invalid_command_syntax/comment_3_55af43e2f43a4c373f7a0a33678d0b1c._comment15
-rw-r--r--doc/bugs/copy_doesn__39__t_scale.mdwn38
-rw-r--r--doc/bugs/copy_doesn__39__t_scale/comment_1_7c12499c9ac28a9883c029f8c659eb57._comment10
-rw-r--r--doc/bugs/copy_doesn__39__t_scale/comment_2_f85d8023cdbc203bb439644cf7245d4e._comment15
-rw-r--r--doc/bugs/copy_doesn__39__t_scale/comment_3_4592765c3d77bb5664b8d16867e9d79c._comment11
-rw-r--r--doc/bugs/copy_fast_confusing_with_broken_locationlog.mdwn6
-rw-r--r--doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_10_435f87d54052f264096a8f23e99eae06._comment8
-rw-r--r--doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_11_9be0aef403a002c1706d17deee45763c._comment24
-rw-r--r--doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_12_26d60661196f63fd01ee4fbb6e2340e7._comment11
-rw-r--r--doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_13_ead55b915d3b92a62549b2957ad211c8._comment35
-rw-r--r--doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_14_191de89d3988083d9cf001799818ff4a._comment10
-rw-r--r--doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_15_b3e3b338ccfa0a32510c78ba1b1bb617._comment8
-rw-r--r--doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_16_04a9f4468c3246c8eff3dbe21dd90101._comment8
-rw-r--r--doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_1_6a41bf7e2db83db3a01722b516fb6886._comment18
-rw-r--r--doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_2_9f5f1dbffb2dd24f4fcf8c2027bf0384._comment8
-rw-r--r--doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_3_b596b5cfd3377e58dbbb5d509d026b90._comment14
-rw-r--r--doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_4_d7112c315fb016a8a399e24e9b6461d8._comment12
-rw-r--r--doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_5_4ea29a6f8152eddf806c536de33ef162._comment14
-rw-r--r--doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_6_0d85f114a103bd6532a3b3b24466012e._comment8
-rw-r--r--doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_7_d38d5bee6d360b0ea852f39e3a7b1bc6._comment12
-rw-r--r--doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_8_29c3de4bf5fbd990b230c443c0303cbe._comment10
-rw-r--r--doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_9_2cee4f6bd6db7518fd61453c595162c6._comment8
-rw-r--r--doc/bugs/copy_to_webdav_sometimes_doesn__39__t_work.mdwn74
-rw-r--r--doc/bugs/copy_to_webdav_sometimes_doesn__39__t_work/comment_1_77629f620b28ac62364de44b41fa539d._comment8
-rw-r--r--doc/bugs/creating_a_plain_directory_where_a_mountpoint_should_have_been.mdwn27
-rw-r--r--doc/bugs/creating_a_plain_directory_where_a_mountpoint_should_have_been/comment_1_41cfd5e48426a6ef52bef70a06a6f46a._comment11
-rw-r--r--doc/bugs/creating_a_plain_directory_where_a_mountpoint_should_have_been/comment_2_bd584ccbe128427fca99e61d66d301c9._comment18
-rw-r--r--doc/bugs/creating_a_plain_directory_where_a_mountpoint_should_have_been/comment_3_5bb0347215b321444643646f25a35759._comment10
-rw-r--r--doc/bugs/creating_a_plain_directory_where_a_mountpoint_should_have_been/comment_4_73848a9c783ecf3d9fccdd41b20fbe36._comment56
-rw-r--r--doc/bugs/creating_a_remote_server_repository.mdwn24
-rw-r--r--doc/bugs/creating_a_remote_server_repository/comment_1_de1a370347428245bcfca60eaca96779._comment10
-rw-r--r--doc/bugs/creds_directory_not_automatically_created.mdwn3
-rw-r--r--doc/bugs/cross_platform_permissions_woes.mdwn36
-rw-r--r--doc/bugs/cross_platform_permissions_woes/comment_1_7f01104de38a6a319a8f36aa1dc8b4b3._comment14
-rw-r--r--doc/bugs/cross_platform_permissions_woes/comment_2_0a34e11b466fad287325425e76487fa1._comment73
-rw-r--r--doc/bugs/cross_platform_permissions_woes/comment_3_278f91b4bc4c32717ab1c39c2abf9305._comment8
-rw-r--r--doc/bugs/cross_platform_permissions_woes/comment_4_eb6a271cb63c71341469c9ff89dc0eb9._comment9
-rw-r--r--doc/bugs/cyclic_drop.mdwn104
-rw-r--r--doc/bugs/data_loss:_incorrect_merge_upon_conflicting_directory-file_of_direct_repos.mdwn199
-rw-r--r--doc/bugs/data_loss:_incorrect_merge_upon_conflicting_directory-file_of_direct_repos/comment_1_294c33af08649256908a97894f93c05d._comment10
-rw-r--r--doc/bugs/data_loss:_incorrect_merge_upon_conflicting_directory-file_of_direct_repos/comment_2_02a2b69adbb04b557146e713b70b34d2._comment14
-rw-r--r--doc/bugs/data_loss:_incorrect_merge_upon_conflicting_directory-file_of_direct_repos/comment_3_d296ef26fc90f4e3166bba6d2de0a1ee._comment8
-rw-r--r--doc/bugs/data_loss:_incorrect_merge_upon_conflicting_directory-file_of_direct_repos/comment_4_33ba2c890c962a71ae9fadc417359f8e._comment8
-rw-r--r--doc/bugs/data_loss:_incorrect_merge_upon_conflicting_directory-file_of_direct_repos/comment_5_39eb0bb96fd271bd0de4a3a40814ae1b._comment11
-rw-r--r--doc/bugs/data_loss:_incorrect_merge_upon_conflicting_directory-file_of_direct_repos/comment_6_d80c4b631bdf58901a06f29a2c5682e2._comment8
-rw-r--r--doc/bugs/data_loss_with___34__git_annex_add__34___on_android_in_direct_mode_.mdwn19
-rw-r--r--doc/bugs/data_loss_with___34__git_annex_add__34___on_android_in_direct_mode_/comment_1_eb6db7f6a156a065e2724c2de5fc4366._comment10
-rw-r--r--doc/bugs/data_loss_with___34__git_annex_add__34___on_android_in_direct_mode_/comment_2_59a96cade9e4881767562a139fc7fb4b._comment40
-rw-r--r--doc/bugs/data_loss_with___34__git_annex_add__34___on_android_in_direct_mode_/comment_3_bf9d2562d66f0f6a9478ac178606cf4e._comment12
-rw-r--r--doc/bugs/data_loss_with___34__git_annex_add__34___on_android_in_direct_mode_/comment_4_ad0dbdc448fff2e126ffec9aac6d7463._comment23
-rw-r--r--doc/bugs/data_loss_with___34__git_annex_add__34___on_android_in_direct_mode_/comment_5_e828585e56b10710598143483ce362b6._comment12
-rw-r--r--doc/bugs/direct_mode_assistant_in_subdir_confusion.mdwn37
-rw-r--r--doc/bugs/direct_mode_assistant_in_subdir_confusion/comment_1_351143deec29e712f8718a373ad650d7._comment8
-rw-r--r--doc/bugs/direct_mode_renames.mdwn15
-rw-r--r--doc/bugs/direct_mode_renames/comment_1_f18c335e0d6f4259d2470935ef391cb8._comment8
-rw-r--r--doc/bugs/direct_mode_sync_should_avoid_git_commit.mdwn5
-rw-r--r--doc/bugs/direct_repository_on_FAT32_fails_to_addurl_containing___63__.mdwn44
-rw-r--r--doc/bugs/directory_remote_+_shared_encryption_+_chunk_size___61___lost_files__63__.mdwn51
-rw-r--r--doc/bugs/directory_remote_+_shared_encryption_+_chunk_size___61___lost_files__63__/comment_1_69dfbf566c75396cdaaf5ad70f1a94a8._comment19
-rw-r--r--doc/bugs/directory_remote_+_shared_encryption_+_chunk_size___61___lost_files__63__/comment_2_8d09cc0e06548c4ebde7956edd1b5d85._comment8
-rw-r--r--doc/bugs/directory_remote_and_case_sensitivity_on_FAT/comment_1_bcac9fd7b3f4a2ac28bee59bae674fa0._comment79
-rw-r--r--doc/bugs/directory_remote_and_case_sensitivity_on_FAT/comment_2_c9088060fb9133b66951f1a3075981e8._comment18
-rw-r--r--doc/bugs/directory_remote_and_case_sensitivity_on_FAT/comment_3_5bf34466187cfc9b34bd3ca8c89a07c6._comment20
-rw-r--r--doc/bugs/directory_remote_and_case_sensitivity_on_FAT/comment_4_d6201f2d86d5b44051a7fd7a8c9de583._comment8
-rw-r--r--doc/bugs/directory_remote_and_case_sensitivity_on_FAT/comment_5_61c5f0889f30a68ac3b57c4ea564ee0e._comment8
-rw-r--r--doc/bugs/done.mdwn4
-rw-r--r--doc/bugs/dotdot_problem.mdwn4
-rw-r--r--doc/bugs/drop_fails_to_see_copies_that_whereis_sees.mdwn69
-rw-r--r--doc/bugs/drop_fails_to_see_copies_that_whereis_sees/comment_1_f5a9d99d90daf5eba4773d361fa1807a._comment14
-rw-r--r--doc/bugs/drop_fails_to_see_copies_that_whereis_sees/comment_2_040aa454cd8acd2857ef36884465576f._comment16
-rw-r--r--doc/bugs/drop_fails_to_see_copies_that_whereis_sees/comment_3_f5d8faab325ee26800ecad5aba49b54b._comment10
-rw-r--r--doc/bugs/dropping_and_re-adding_from_web_remotes_doesn__39__t_work.mdwn139
-rw-r--r--doc/bugs/dropping_files_with_a_URL_backend_fails.mdwn13
-rw-r--r--doc/bugs/dropunused_doesn__39__t_handle_double_spaces_in_filename.mdwn87
-rw-r--r--doc/bugs/dropunused_doesn__39__t_work_in_my_case__63__.mdwn70
-rw-r--r--doc/bugs/encfs_accused_of_being_crippled.mdwn41
-rw-r--r--doc/bugs/encfs_accused_of_being_crippled/comment_1_5c5be012e1171ef108f38825d72791b6._comment23
-rw-r--r--doc/bugs/encrpyted_ssh_remote_on_macosx.mdwn42
-rw-r--r--doc/bugs/encrpyted_ssh_remote_on_macosx/comment_1_46c37aacb7ae41864488fb7c7d87d437._comment10
-rw-r--r--doc/bugs/encrypted_S3_stalls.mdwn9
-rw-r--r--doc/bugs/encryption_given_a_gpg_keyid_still_uses_symmetric_encryption.mdwn46
-rw-r--r--doc/bugs/encryption_given_a_gpg_keyid_still_uses_symmetric_encryption/comment_1_2f4ec4b7b92a0f0a0c4c0758da4a05a5._comment13
-rw-r--r--doc/bugs/encryption_given_a_gpg_keyid_still_uses_symmetric_encryption/comment_2_7c0aeae6b1b2b0338735b0231c5db7d4._comment16
-rw-r--r--doc/bugs/encryption_key_is_surprising.mdwn24
-rw-r--r--doc/bugs/encryption_key_is_surprising/comment_1_5b172830ac31d51a1687bc8b1db489f9._comment10
-rw-r--r--doc/bugs/encryption_key_is_surprising/comment_2_5b7e6bb36c3333dfd71808e8b4544746._comment8
-rw-r--r--doc/bugs/encryption_key_is_surprising/comment_4_8ec86b8c35bce15337a143e275961cd5._comment8
-rw-r--r--doc/bugs/encryption_key_is_surprising/comment_4_c5e49b3a0eceabe6d14f5226d7ba4c7a._comment8
-rw-r--r--doc/bugs/encryption_key_is_surprising/comment_5_cd7cbf0c0ee9cafec344dfbf1acd9590._comment8
-rw-r--r--doc/bugs/encryption_key_is_surprising/comment_6_01381524114d885961704acc3f172536._comment8
-rw-r--r--doc/bugs/encryption_key_is_surprising/comment_7_c1eb59e1c5f583dcef7cea17623a2435._comment8
-rw-r--r--doc/bugs/error_building_git-annex_3.20120624_using_cabal.mdwn159
-rw-r--r--doc/bugs/error_on_only_repository_copy_deletion.mdwn16
-rw-r--r--doc/bugs/error_on_only_repository_copy_deletion/comment_1_af394ac0956ab33a77256bcb02ef2a0f._comment14
-rw-r--r--doc/bugs/error_propigation.mdwn3
-rw-r--r--doc/bugs/error_when_using_repositories_with_non-ASCII_characters.mdwn62
-rw-r--r--doc/bugs/error_when_using_repositories_with_non-ASCII_characters/comment_1_38cc2d2ed907649df085de8ad83cb9dd._comment14
-rw-r--r--doc/bugs/error_with_file_names_starting_with_dash.mdwn15
-rw-r--r--doc/bugs/extraneous_shell_escaping_for_rsync_remotes.mdwn15
-rw-r--r--doc/bugs/fails_to_handle_lot_of_files.mdwn445
-rw-r--r--doc/bugs/fails_to_handle_lot_of_files/comment_1_09d8e4e66d8273fab611bd29e82dc7fc._comment8
-rw-r--r--doc/bugs/fails_to_handle_lot_of_files/comment_2_fd2ec05f4b5a7a6ae6bd9f5dbc3156de._comment8
-rw-r--r--doc/bugs/failure_to_find_file_that___34__should__34___exist_in_remote_is_silent.mdwn37
-rw-r--r--doc/bugs/failure_to_find_file_that___34__should__34___exist_in_remote_is_silent/comment_1_c686df2824d3f588c0bfb339c99168b7._comment29
-rw-r--r--doc/bugs/failure_to_find_file_that___34__should__34___exist_in_remote_is_silent/comment_2_22edfac4ce25cd9f4e4c85e0a8a52bc1._comment14
-rw-r--r--doc/bugs/failure_to_find_file_that___34__should__34___exist_in_remote_is_silent/comment_3_74fc0e41a6bd5c4d8c4b2f15e5ed8d2f._comment17
-rw-r--r--doc/bugs/failure_to_find_file_that___34__should__34___exist_in_remote_is_silent/comment_4_7d642fc65040a7b583cdece33db01826._comment8
-rw-r--r--doc/bugs/failure_to_find_file_that___34__should__34___exist_in_remote_is_silent/comment_5_49be366b6af6db595fa538373a61e650._comment10
-rw-r--r--doc/bugs/failure_to_return_to_indirect_mode_on_usb.mdwn19
-rw-r--r--doc/bugs/failure_to_return_to_indirect_mode_on_usb/comment_1_d7822b90c68bf845572b0a04a378d0bb._comment10
-rw-r--r--doc/bugs/fat_support.mdwn13
-rw-r--r--doc/bugs/fat_support/comment_1_04bcc4795d431e8cb32293aab29bbfe2._comment12
-rw-r--r--doc/bugs/fat_support/comment_2_bb4a97ebadb5c53809fc78431eabd7c8._comment14
-rw-r--r--doc/bugs/fat_support/comment_3_df3b943bc1081a8f3f7434ae0c8e061e._comment11
-rw-r--r--doc/bugs/fat_support/comment_4_90a8a15bedd94480945a374f9d706b86._comment10
-rw-r--r--doc/bugs/fat_support/comment_5_64bbf89de0836673224b83fdefa0407b._comment8
-rw-r--r--doc/bugs/fat_support/comment_6_a3b6000330c9c376611c228d746a1d55._comment8
-rw-r--r--doc/bugs/fat_support/comment_7_a0ac7f2c44efc8116940c7b94b35e9d0._comment7
-rw-r--r--doc/bugs/fat_support/comment_8_acc947643a635eb10a1bff92083a3506._comment10
-rw-r--r--doc/bugs/fatal:_empty_ident_name.mdwn51
-rw-r--r--doc/bugs/fatal:_empty_ident_name/comment_1_ceae87308fb75a1f79c7c8d63ec47226._comment8
-rw-r--r--doc/bugs/fatal:_empty_ident_name/comment_2_68832ee3e0e7244ce62bccabe2e52630._comment25
-rw-r--r--doc/bugs/fatal:_empty_ident_name/comment_3_ed31ad316747343d7730e4c2d7dacd24._comment10
-rw-r--r--doc/bugs/fatal:_empty_ident_name/comment_4_b812d6f30e8a866bce7260a9ee3218e3._comment13
-rw-r--r--doc/bugs/fatal:_unable_to_access___39__..__47__..__47__..__47__..__47__C:__92__Users__92____91__...__93____92__annex__92__.git__47__config__39__:_Invalid_argument___40__Windows__41__.mdwn63
-rw-r--r--doc/bugs/fatal:_unable_to_access___39__..__47__..__47__..__47__..__47__C:__92__Users__92____91__...__93____92__annex__92__.git__47__config__39__:_Invalid_argument___40__Windows__41__/comment_1_e6f39b2ef55b0daa491f4b6329a906bc._comment8
-rw-r--r--doc/bugs/fatal:_unable_to_access___39__..__47__..__47__..__47__..__47__C:__92__Users__92____91__...__93____92__annex__92__.git__47__config__39__:_Invalid_argument___40__Windows__41__/comment_2_b47d6d188f38a8e4ca5ef5f70afadf6a._comment48
-rw-r--r--doc/bugs/fatal:_unable_to_access___39__..__47__..__47__..__47__..__47__C:__92__Users__92____91__...__93____92__annex__92__.git__47__config__39__:_Invalid_argument___40__Windows__41__/comment_4_b533b1de535a057b7ebf99afc92691ed._comment13
-rw-r--r--doc/bugs/file_access__47__locking_issues_with_the_assitant.mdwn54
-rw-r--r--doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_10_fadf06f5ab34e36ab130536ec55afc8e._comment12
-rw-r--r--doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_11_4a337f7b1140c45e5dd660b40202f696._comment10
-rw-r--r--doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_1_05e1398e78218ced9c2da6a2510949e8._comment21
-rw-r--r--doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_2_9226f0adf091154c0d8a08b340b71869._comment8
-rw-r--r--doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_3_44d3e2096b7d45a1062222bee83a346d._comment8
-rw-r--r--doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_4_f2e1d188b7b2d2daf0d832c59a68583e._comment8
-rw-r--r--doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_5_998fe58994ecf855310e4b8e6cce9e18._comment8
-rw-r--r--doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_6_4ce243cb0ea8ff810a4949a5320e4afc._comment13
-rw-r--r--doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_7_c713f6316d889c8fc52326f21375c1c4._comment8
-rw-r--r--doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_8_6dd23bab7983b8b1f938dd4f21a16f5a._comment8
-rw-r--r--doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_9_961c8f968eff0b39a85b607ee3f7630d._comment16
-rw-r--r--doc/bugs/file_modification_times.mdwn13
-rw-r--r--doc/bugs/fix_for_makefile_to_check_if_OS_is_linux_or_not___40__relates_to_the_new_inotify_flag__41__.mdwn36
-rw-r--r--doc/bugs/free_space_checking.mdwn21
-rw-r--r--doc/bugs/free_space_checking/comment_1_a868e805be43c5a7c19c41f1af8e41e6._comment10
-rw-r--r--doc/bugs/free_space_checking/comment_2_8a65f6d3dcf5baa3f7f2dbe1346e2615._comment8
-rw-r--r--doc/bugs/free_space_checking/comment_3_0fc6ff79a357b1619d13018ccacc7c10._comment8
-rw-r--r--doc/bugs/fsck__47__fix_should_check__47__fix_the_permissions_of_.git__47__annex.mdwn8
-rw-r--r--doc/bugs/fsck_claims_failed_checksum_when_less_copies_than_required_are_found.mdwn57
-rw-r--r--doc/bugs/fsck_output.mdwn46
-rw-r--r--doc/bugs/fsck_should_double-check_when_a_content-check_fails.mdwn3
-rw-r--r--doc/bugs/fsck_should_double-check_when_a_content-check_fails/comment_1_03af24b70adbcd9f4b94d009f6b71d0a._comment13
-rw-r--r--doc/bugs/fsck_should_double-check_when_a_content-check_fails/comment_2_41214a7d18c66b694645248d6ebeadbf._comment25
-rw-r--r--doc/bugs/fsck_should_double-check_when_a_content-check_fails/comment_3_e7ddd77ea35994f2051f840e9b4c7e0c._comment11
-rw-r--r--doc/bugs/fsck_should_double-check_when_a_content-check_fails/comment_4_36a70d5a378983a76fcdbb7fba044044._comment32
-rw-r--r--doc/bugs/fsck_should_double-check_when_a_content-check_fails/comment_5_899c4afbc988d81984c5c3397285bb01._comment12
-rw-r--r--doc/bugs/fsck_should_double-check_when_a_content-check_fails/comment_6_dbff51d00c5645eb1832aa4644889c5e._comment10
-rw-r--r--doc/bugs/fsck_thinks_file_content_is_bad_when_it_isn__39__t.mdwn35
-rw-r--r--doc/bugs/fsck_thinks_file_content_is_bad_when_it_isn__39__t/comment_1_cafb58eca97a0a66110ac39b169d8de3._comment8
-rw-r--r--doc/bugs/gcrypt_initremote_pushes_git-annex_but_not_master.mdwn19
-rw-r--r--doc/bugs/get_failed__44___but_remote_has_the_file.mdwn40
-rw-r--r--doc/bugs/get_failed__44___but_remote_has_the_file/comment_1_55c8b73ce05dfca11a393bb296b99b9a._comment10
-rw-r--r--doc/bugs/get_failed__44___but_remote_has_the_file/comment_2_474c67a421dca4c245e7bfe495d3f6d3._comment18
-rw-r--r--doc/bugs/get_failed__44___but_remote_has_the_file/comment_3_845e8a23d63fb0b071c63ee736697d26._comment20
-rw-r--r--doc/bugs/get_failed__44___but_remote_has_the_file/comment_4_7dec21cb67e7f4dbdb49da97f2443e8f._comment35
-rw-r--r--doc/bugs/get_fails_for_file:__47____47___web_remotes_if_the_file_is_empty.mdwn26
-rw-r--r--doc/bugs/get_from_bup-remote_with_pubkey_failing.mdwn93
-rw-r--r--doc/bugs/git-annex-shell:_gcryptsetup_permission_denied.mdwn48
-rw-r--r--doc/bugs/git-annex-shell:_gcryptsetup_permission_denied/comment_1_f4584158b35b80ece1060308883e2dc4._comment8
-rw-r--r--doc/bugs/git-annex-shell:_gcryptsetup_permission_denied/comment_2_a4d7aae848340771a9b8e2c87abeea42._comment26
-rw-r--r--doc/bugs/git-annex-shell:_gcryptsetup_permission_denied/comment_3_06bda101ad584b4b882de8b2e202d679._comment8
-rw-r--r--doc/bugs/git-annex-shell:_gcryptsetup_permission_denied/comment_4_4fc6b25401b645cabc04b510bdfa6863._comment10
-rw-r--r--doc/bugs/git-annex-shell:_gcryptsetup_permission_denied/comment_5_4e193306801680bba433e75eb4dcba05._comment12
-rw-r--r--doc/bugs/git-annex-shell:_gcryptsetup_permission_denied/comment_6_76ccdf0542e76e4dbd61f3b3228d40ba._comment10
-rw-r--r--doc/bugs/git-annex-shell:_gcryptsetup_permission_denied/comment_7_cd964d0a375c5cba299bf2bbbbb86acb._comment12
-rw-r--r--doc/bugs/git-annex-shell:_gcryptsetup_permission_denied/comment_8_9bac87c85deb5bb15795df28533d0cde._comment10
-rw-r--r--doc/bugs/git-annex-shell:_internal_error:_evacuate__40__static__41__:_strange_closure_type_30799.mdwn75
-rw-r--r--doc/bugs/git-annex-shell:_internal_error:_evacuate__40__static__41__:_strange_closure_type_30799/comment_1_1c19e716069911f17bbebd196d9e4b61._comment10
-rw-r--r--doc/bugs/git-annex-shell:_internal_error:_evacuate__40__static__41__:_strange_closure_type_30799/comment_2_a4d66f29d257044e548313e014ca3dc3._comment66
-rw-r--r--doc/bugs/git-annex-shell:_internal_error:_evacuate__40__static__41__:_strange_closure_type_30799/comment_3_f5f1081eb18143383b2fb1f57d8640f5._comment38
-rw-r--r--doc/bugs/git-annex-shell:_internal_error:_evacuate__40__static__41__:_strange_closure_type_30799/comment_4_b1f818b85c3540591c48e7ba8560d070._comment10
-rw-r--r--doc/bugs/git-annex-shell:_internal_error:_evacuate__40__static__41__:_strange_closure_type_30799/comment_5_67406dd8d9bd4944202353508468c907._comment13
-rw-r--r--doc/bugs/git-annex-shell:_user_error___40__unrecognized_option___96__--uuid__39__.mdwn53
-rw-r--r--doc/bugs/git-annex-shell:_user_error___40__unrecognized_option___96__--uuid__39__/comment_1_13510e954e36484e196e7395a3a9bf1f._comment10
-rw-r--r--doc/bugs/git-annex-shell:_user_error___40__unrecognized_option___96__--uuid__39__/comment_2_7edc478a76983a3b3c68d01f24dce613._comment9
-rw-r--r--doc/bugs/git-annex-shell_doesn__39__t_honour_Rsync__39__s_bwlimit_option.mdwn37
-rw-r--r--doc/bugs/git-annex-shell_doesn__39__t_honour_Rsync__39__s_bwlimit_option/comment_1_8cda861c11ef2fff3442e5a0df741939._comment12
-rw-r--r--doc/bugs/git-annex-shell_doesn__39__t_honour_Rsync__39__s_bwlimit_option/comment_2_15e06f6db9a14a8217dea25e24ddc23a._comment12
-rw-r--r--doc/bugs/git-annex-shell_doesn__39__t_honour_Rsync__39__s_bwlimit_option/comment_3_d36045e2b466882108c5bf09580755fa._comment8
-rw-r--r--doc/bugs/git-annex:_Argument_list_too_long.mdwn40
-rw-r--r--doc/bugs/git-annex:_Argument_list_too_long/comment_1_3f83ea525436b2379ab29a0f860c4669._comment8
-rw-r--r--doc/bugs/git-annex:_Argument_list_too_long/comment_2_b417c94169378ef7d0d278ebae517fa1._comment8
-rw-r--r--doc/bugs/git-annex:_Argument_list_too_long/comment_3_fa925cca216cb810ad80482b19fc6053._comment8
-rw-r--r--doc/bugs/git-annex:_Argument_list_too_long/comment_4_8bd2996107b2d272c32810658e07e715._comment8
-rw-r--r--doc/bugs/git-annex:_Argument_list_too_long/comment_5_378de7d7503a64611eab62f2f5cffef3._comment15
-rw-r--r--doc/bugs/git-annex:_Argument_list_too_long/comment_6_a94e17151348d02999442dd1219babfb._comment10
-rw-r--r--doc/bugs/git-annex:_Cannot_decode_byte___39____92__xfc__39__.mdwn34
-rw-r--r--doc/bugs/git-annex:_Cannot_decode_byte___39____92__xfc__39__/comment_1_f1a7352b04f395e06e0094c1f51b6fff._comment12
-rw-r--r--doc/bugs/git-annex:_Cannot_decode_byte___39____92__xfc__39__/comment_2_c1890067079cd99667f31cbb4d2e4545._comment8
-rw-r--r--doc/bugs/git-annex:_Cannot_decode_byte___39____92__xfc__39__/comment_3_213c96085c60c8e52cd803df07240158._comment13
-rw-r--r--doc/bugs/git-annex:_Not_in_a_git_repository._.mdwn22
-rw-r--r--doc/bugs/git-annex:_Not_in_a_git_repository._/comment_1_e10363a912953a646b87c824d1c6e5d4._comment10
-rw-r--r--doc/bugs/git-annex:_Not_in_a_git_repository._/comment_2_9e96063a664b2be8a36d7940e7632d3f._comment8
-rw-r--r--doc/bugs/git-annex:_Not_in_a_git_repository._/comment_3_8c9bd76b0e1200723ec13fbef943a2cc._comment10
-rw-r--r--doc/bugs/git-annex:_Not_in_a_git_repository._/comment_4_8c49979b8a815f0d6f9de39ee9a88730._comment8
-rw-r--r--doc/bugs/git-annex:___60__socket:_16__62__:_hPutBuf:_resource_vanished___40__Broken_pipe__41__.mdwn14
-rw-r--r--doc/bugs/git-annex:___60__socket:_16__62__:_hPutBuf:_resource_vanished___40__Broken_pipe__41__/comment_1_e962317a939bf76097ae1a3b53b146e6._comment14
-rw-r--r--doc/bugs/git-annex:___60__socket:_16__62__:_hPutBuf:_resource_vanished___40__Broken_pipe__41__/comment_2_b32472b4c9b61e7a33dca802ecafb05b._comment11
-rw-r--r--doc/bugs/git-annex:___60__socket:_16__62__:_hPutBuf:_resource_vanished___40__Broken_pipe__41__/comment_3_fcfea3216831df9afbd855fbd842c27e._comment20
-rw-r--r--doc/bugs/git-annex:___60__socket:_16__62__:_hPutBuf:_resource_vanished___40__Broken_pipe__41__/comment_4_30d0b40efa59eeecb8a4be6d1baa1520._comment10
-rw-r--r--doc/bugs/git-annex:___60__socket:_16__62__:_hPutBuf:_resource_vanished___40__Broken_pipe__41__/comment_5_4af107f3184bc2abd2c9693167018628._comment8
-rw-r--r--doc/bugs/git-annex:___60__socket:_16__62__:_hPutBuf:_resource_vanished___40__Broken_pipe__41__/comment_6_f96027f1e3c405809fae42ce8533c6d1._comment8
-rw-r--r--doc/bugs/git-annex:___60__socket:_16__62__:_hPutBuf:_resource_vanished___40__Broken_pipe__41__/comment_7_b6fe89deb468a7e4f63f7faab147e3fb._comment12
-rw-r--r--doc/bugs/git-annex:___60__socket:_16__62__:_hPutBuf:_resource_vanished___40__Broken_pipe__41__/comment_8_ebec5d9266604f03959dc16d933ff4a4._comment13
-rw-r--r--doc/bugs/git-annex:_fd:14:_hGetLine:_end_of_file.mdwn51
-rw-r--r--doc/bugs/git-annex:_fd:14:_hGetLine:_end_of_file/comment_1_36756f5d9d591cc52113c5cc0c1eae91._comment8
-rw-r--r--doc/bugs/git-annex:_getUserEntryForID:_failed___40__Success__41__.mdwn13
-rw-r--r--doc/bugs/git-annex:_getUserEntryForID:_failed___40__Success__41__/comment_1_11a1615962325327466895d03e3d2379._comment8
-rw-r--r--doc/bugs/git-annex:_getUserEntryForID:_failed___40__Success__41__/comment_2_eac51c3299e9fc04025675360969d537._comment8
-rw-r--r--doc/bugs/git-annex:_getUserEntryForID:_failed___40__Success__41__/comment_3_c23dc02c7487d63b0905f1b7f3ca59f5._comment9
-rw-r--r--doc/bugs/git-annex:_getUserEntryForID:_failed___40__Success__41__/comment_4_0e8b28de5c173bc60ecc0126fb2209ca._comment10
-rw-r--r--doc/bugs/git-annex:_status:_1_failed.mdwn25
-rw-r--r--doc/bugs/git-annex:_status:_1_failed/comment_10_7cd9de88e55633fc75460f4fe0400f09._comment8
-rw-r--r--doc/bugs/git-annex:_status:_1_failed/comment_11_504a944aab34155046f2fd82c2878f3e._comment18
-rw-r--r--doc/bugs/git-annex:_status:_1_failed/comment_1_c235cc83c75474e6393e08d2d94b119d._comment10
-rw-r--r--doc/bugs/git-annex:_status:_1_failed/comment_2_932f6aaa712298a47868002872e16310._comment10
-rw-r--r--doc/bugs/git-annex:_status:_1_failed/comment_3_4bf55320439de152a65e2f21d4a0604b._comment14
-rw-r--r--doc/bugs/git-annex:_status:_1_failed/comment_4_cb2cfb798c6171f77eb7c4c4061c0f0c._comment8
-rw-r--r--doc/bugs/git-annex:_status:_1_failed/comment_5_05c84dde377298adfd3fc20749b3108f._comment10
-rw-r--r--doc/bugs/git-annex:_status:_1_failed/comment_6_bb5141e29c665bc0bb82611ea27d4be8._comment11
-rw-r--r--doc/bugs/git-annex:_status:_1_failed/comment_7_5fd39168c9e1bf43909ee0ab3c75c40c._comment35
-rw-r--r--doc/bugs/git-annex:_status:_1_failed/comment_8_e493f6bddb0bfcd9478d5f4d9fc170e0._comment8
-rw-r--r--doc/bugs/git-annex:_status:_1_failed/comment_9_573377d444aee0895b231082bc6839a4._comment8
-rw-r--r--doc/bugs/git-annex_3.20130216.1_tests_are_broken.mdwn43
-rw-r--r--doc/bugs/git-annex___38___rsync_can__39__t_copy_files_with___39__:__39___in_their_names.mdwn38
-rw-r--r--doc/bugs/git-annex_add_should_repack_as_it_goes.mdwn32
-rw-r--r--doc/bugs/git-annex_add_should_repack_as_it_goes/comment_1_dbcaa0be4cd764128fb7263a95f73a32._comment22
-rw-r--r--doc/bugs/git-annex_add_should_repack_as_it_goes/comment_2_6a27551c4fb7f62ed9f627134c755d01._comment14
-rw-r--r--doc/bugs/git-annex_add_should_repack_as_it_goes/comment_3_ff8b589fbcf25c98abd1c58830074650._comment8
-rw-r--r--doc/bugs/git-annex_branch_corruption.mdwn95
-rw-r--r--doc/bugs/git-annex_branch_push_race.mdwn45
-rw-r--r--doc/bugs/git-annex_broken_on_Android_4.3.mdwn7
-rw-r--r--doc/bugs/git-annex_broken_on_Android_4.3/comment_10_e47c073f1614f7b57f86acedeeb1cadc._comment8
-rw-r--r--doc/bugs/git-annex_broken_on_Android_4.3/comment_11_ce34578c45060b7c8b759efd1c1d8df8._comment13
-rw-r--r--doc/bugs/git-annex_broken_on_Android_4.3/comment_12_75965395dc33046ce34ac5ba972b7d64._comment8
-rw-r--r--doc/bugs/git-annex_broken_on_Android_4.3/comment_13_f07bc76dd3c5580fc0855a33ae835c8d._comment12
-rw-r--r--doc/bugs/git-annex_broken_on_Android_4.3/comment_14_637c59becc68a1e4f60069d8873489ff._comment8
-rw-r--r--doc/bugs/git-annex_broken_on_Android_4.3/comment_15_d80b87055f72873f5678a01d2630bea4._comment10
-rw-r--r--doc/bugs/git-annex_broken_on_Android_4.3/comment_16_57ac84868b223b30f005704eefa01b8d._comment8
-rw-r--r--doc/bugs/git-annex_broken_on_Android_4.3/comment_17_a41f4d8a72c07ad770e6479e9b8c7f1d._comment8
-rw-r--r--doc/bugs/git-annex_broken_on_Android_4.3/comment_18_7d36637f11cda51de395303d5c1c6a3f._comment8
-rw-r--r--doc/bugs/git-annex_broken_on_Android_4.3/comment_19_c8609c3f7f62ae5427fd8c60bc9546ed._comment8
-rw-r--r--doc/bugs/git-annex_broken_on_Android_4.3/comment_1_0ffb3833ce2c2e0320468dc9a09866d7._comment10
-rw-r--r--doc/bugs/git-annex_broken_on_Android_4.3/comment_20_0886bca6d0c6a9415a7794d256be2e9d._comment14
-rw-r--r--doc/bugs/git-annex_broken_on_Android_4.3/comment_21_2b39729f95c9c4bba620ecdd3d1558ed._comment8
-rw-r--r--doc/bugs/git-annex_broken_on_Android_4.3/comment_22_8d90d92951919aa70638b31e9248bec5._comment16
-rw-r--r--doc/bugs/git-annex_broken_on_Android_4.3/comment_23_6398271f5cd9e94996202ef3bce6f6ed._comment20
-rw-r--r--doc/bugs/git-annex_broken_on_Android_4.3/comment_24_c9e399833cc6235077161f490dfa866f._comment8
-rw-r--r--doc/bugs/git-annex_broken_on_Android_4.3/comment_25_cf093737eefb2b99f6f0eac9bf3e74b3._comment9
-rw-r--r--doc/bugs/git-annex_broken_on_Android_4.3/comment_26_c122ce53175fc9e0e114a8acd2385c0d._comment29
-rw-r--r--doc/bugs/git-annex_broken_on_Android_4.3/comment_27_237e41e61781bb058f5fd39362a904e4._comment10
-rw-r--r--doc/bugs/git-annex_broken_on_Android_4.3/comment_28_97f423a41ee9d2d74291594fae20dd4e._comment10
-rw-r--r--doc/bugs/git-annex_broken_on_Android_4.3/comment_29_7b3fbe7e38f637fcea511441ac243d93._comment10
-rw-r--r--doc/bugs/git-annex_broken_on_Android_4.3/comment_2_53e2d095b2501844cadec910de286814._comment14
-rw-r--r--doc/bugs/git-annex_broken_on_Android_4.3/comment_30_26c04584c3c6dacf59e1b6c82042c97c._comment8
-rw-r--r--doc/bugs/git-annex_broken_on_Android_4.3/comment_3_ddc9cbae1a721400a9acf2153e18f4f0._comment8
-rw-r--r--doc/bugs/git-annex_broken_on_Android_4.3/comment_4_593235735e32238094121b1f79355bbd._comment8
-rw-r--r--doc/bugs/git-annex_broken_on_Android_4.3/comment_5_f806fd5930e90920db24456297465bae._comment9
-rw-r--r--doc/bugs/git-annex_broken_on_Android_4.3/comment_6_5741b6a5997328fdcd5cc99f841b18d3._comment8
-rw-r--r--doc/bugs/git-annex_broken_on_Android_4.3/comment_7_3e0d9949dd810069af0b8076807e5924._comment8
-rw-r--r--doc/bugs/git-annex_broken_on_Android_4.3/comment_8_f58897eff6b4693f0c73474ccfe6e733._comment8
-rw-r--r--doc/bugs/git-annex_broken_on_Android_4.3/comment_9_ddba87b2f20d8a63f7b8ebdb9bd13515._comment18
-rw-r--r--doc/bugs/git-annex_direct_fails_on_repositories_with_a_partial_set_of_files.mdwn29
-rw-r--r--doc/bugs/git-annex_directory_hashing_problems_on_osx.mdwn100
-rw-r--r--doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_10_f3594de3ba2ab17771a4b116031511bb._comment8
-rw-r--r--doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_11_97de7252bf5d2a4f1381f4b2b4e24ef8._comment13
-rw-r--r--doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_12_f1c53c3058a587185e7a78d84987539d._comment8
-rw-r--r--doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_13_4f56aea35effe5c10ef37d7ad7adb48c._comment8
-rw-r--r--doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_14_cc2a53c31332fe4b828ef1e72c2a4d49._comment10
-rw-r--r--doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_15_37f1d669c1fa53ee371f781c7bb820ae._comment17
-rw-r--r--doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_16_8a4ab1af59098f4950726cf53636c2b3._comment22
-rw-r--r--doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_17_515d5c5fbf5bd0c188a4f1e936d913e2._comment9
-rw-r--r--doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_18_db64c91dd1322a0ab168190686db494f._comment14
-rw-r--r--doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_19_ff555c271637af065203ca99c9eeaf89._comment8
-rw-r--r--doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_1_9a7b09de132097100c1a68ea7b846727._comment8
-rw-r--r--doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_20_7e328b970169fffb8bce373d1522743b._comment19
-rw-r--r--doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_21_98f632652b0db9131b0173d3572f4d62._comment10
-rw-r--r--doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_22_52d41afd7fd0b71a4c8e84ab1b4df5bd._comment8
-rw-r--r--doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_23_c2cd8a69c37539c0511bae02016180ca._comment8
-rw-r--r--doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_2_174952fc3e3be12912e5fcfe78f2dd13._comment185
-rw-r--r--doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_3_a18ada7ac74c63be5753fdb2fe68dae5._comment18
-rw-r--r--doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_4_039e945617a6c1852c96974a402db29c._comment8
-rw-r--r--doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_5_eacd0b18475c05ab9feed8cf7290b79a._comment37
-rw-r--r--doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_6_e55117cb628dc532e468519252571474._comment14
-rw-r--r--doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_7_0f4f471102e394ebb01da40e4d0fd9f6._comment68
-rw-r--r--doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_8_68e2d6ccdb9622b879e4bc7005804623._comment12
-rw-r--r--doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_9_45b11ddd200261115b653c7a14d28aa9._comment8
-rw-r--r--doc/bugs/git-annex_does_not_install_on_windows_without_admin_rights.mdwn19
-rw-r--r--doc/bugs/git-annex_does_not_install_on_windows_without_admin_rights/comment_1_2533800ab5a95c5d71c3b47a630e751a._comment10
-rw-r--r--doc/bugs/git-annex_does_not_install_on_windows_without_admin_rights/comment_2_5b71785acf16a8d9ea457726599daef3._comment8
-rw-r--r--doc/bugs/git-annex_doesn__39__t_list_files_containing_ISO8859-15_characters.mdwn48
-rw-r--r--doc/bugs/git-annex_doesn__39__t_list_files_containing_ISO8859-15_characters/comment_1_b84e831298c03b12471fb75da597e365._comment8
-rw-r--r--doc/bugs/git-annex_dropunused_has_no_effect.mdwn12
-rw-r--r--doc/bugs/git-annex_dropunused_has_no_effect/comment_1_66b581eb7111a9e98c6406ec75b899cf._comment12
-rw-r--r--doc/bugs/git-annex_dropunused_has_no_effect/comment_2_11c46cd2087511c3d22b7ce7c149b3e9._comment16
-rw-r--r--doc/bugs/git-annex_dropunused_has_no_effect/comment_3_b1c3d8c6ec4b20727aaa9c4b746531b0._comment10
-rw-r--r--doc/bugs/git-annex_dropunused_has_no_effect/comment_4_f05a9a3760858c5ee5c98dd8ab059c28._comment8
-rw-r--r--doc/bugs/git-annex_fix_not_noticing_file_renames.mdwn36
-rw-r--r--doc/bugs/git-annex_fix_not_noticing_file_renames/comment_1_4edd95200d59ec5a5426167b8da8e3f9._comment24
-rw-r--r--doc/bugs/git-annex_fix_not_noticing_file_renames/comment_2_a9a44debefb3bdd4b8ed2d1cf53f2338._comment8
-rw-r--r--doc/bugs/git-annex_fix_not_noticing_file_renames/comment_3_0efb11f35b872b75a3fbc4ebb71ac827._comment10
-rw-r--r--doc/bugs/git-annex_get:_requested_key_is_not_present.mdwn41
-rw-r--r--doc/bugs/git-annex_get:_requested_key_is_not_present/comment_1_d4baa6607a61d0e6a7cea1325a5ddf95._comment26
-rw-r--r--doc/bugs/git-annex_get:_requested_key_is_not_present/comment_2_b49725488c3db5e00ede7b65ed9d62fa._comment110
-rw-r--r--doc/bugs/git-annex_get:_requested_key_is_not_present/comment_3_c17a7138579b93c6f14e3444c11664ac._comment8
-rw-r--r--doc/bugs/git-annex_happily_deleted_most_of_my_files___36____35____38____33__.mdwn58
-rw-r--r--doc/bugs/git-annex_happily_deleted_most_of_my_files___36____35____38____33__/comment_1_5dd4d1cec069c13184f5dd9efca6721b._comment8
-rw-r--r--doc/bugs/git-annex_happily_deleted_most_of_my_files___36____35____38____33__/comment_2_d9b65fe4cb4bfd58f37e7da5350c6401._comment14
-rw-r--r--doc/bugs/git-annex_happily_deleted_most_of_my_files___36____35____38____33__/comment_3_1027187b203addd65af8cf1faf28727d._comment10
-rw-r--r--doc/bugs/git-annex_happily_deleted_most_of_my_files___36____35____38____33__/comment_4_ac65028203ff0cbdb978200235fb4e9c._comment10
-rw-r--r--doc/bugs/git-annex_has_issues_with_git_when_staging__47__commiting_logs.mdwn34
-rw-r--r--doc/bugs/git-annex_immediately_re-gets_dropped_files.mdwn27
-rw-r--r--doc/bugs/git-annex_immediately_re-gets_dropped_files/comment_1_09e616a4866e726a48be4febe6375cc8._comment8
-rw-r--r--doc/bugs/git-annex_incorrectly_parses_bare_IPv6_addresses.mdwn59
-rw-r--r--doc/bugs/git-annex_losing_rsync_remotes_with_encryption_enabled.mdwn103
-rw-r--r--doc/bugs/git-annex_merge_stalls.mdwn16
-rw-r--r--doc/bugs/git-annex_merge_stalls/comment_1_31578a754945bdcb902c62ff58704bcb._comment17
-rw-r--r--doc/bugs/git-annex_merge_stalls/comment_2_f3b6bf180466b5931bfd20b2f0229422._comment10
-rw-r--r--doc/bugs/git-annex_merge_stalls/comment_3_ced9b0d724fb55c756106b64c3721003._comment18
-rw-r--r--doc/bugs/git-annex_on_crippled_filesystem_can_still_failed_due_to_case_.mdwn32
-rw-r--r--doc/bugs/git-annex_on_crippled_filesystem_can_still_failed_due_to_case_/comment_1_850695231926dfe94f11342d3af7f63c._comment54
-rw-r--r--doc/bugs/git-annex_on_crippled_filesystem_can_still_failed_due_to_case_/comment_2_c2a2f801a3e18ad597ff0acf2f104557._comment22
-rw-r--r--doc/bugs/git-annex_opens_too_many_files.mdwn40
-rw-r--r--doc/bugs/git-annex_opens_too_many_files/comment_1_37f6f5838c41c533df4be1f927b9b03d._comment26
-rw-r--r--doc/bugs/git-annex_opens_too_many_files/comment_2_347ef233b9845b84d7c4d49ed166e797._comment10
-rw-r--r--doc/bugs/git-annex_opens_too_many_files/comment_3_d5f644d97cd2db471deb5dcd728cae60._comment8
-rw-r--r--doc/bugs/git-annex_opens_too_many_files/comment_4_c03bde64be8fdd962826bc7afa07d2a9._comment137
-rw-r--r--doc/bugs/git-annex_opens_too_many_files/comment_5_33a2e783e5355e981497b9861997570b._comment18
-rw-r--r--doc/bugs/git-annex_opens_too_many_files/comment_6_b3a5a4e4ca29c5cd2840bfeb4c63ea68._comment15
-rw-r--r--doc/bugs/git-annex_quit_unexpectedly___40__macosx__41__.mdwn358
-rw-r--r--doc/bugs/git-annex_quit_unexpectedly___40__macosx__41__/comment_1_97abb8442329d19c9687002f43afac74._comment23
-rw-r--r--doc/bugs/git-annex_quit_unexpectedly___40__macosx__41__/comment_2_3405f3cd699860ee239cf23ade19e92c._comment10
-rw-r--r--doc/bugs/git-annex_sync_broken_on_squeeze_backports.mdwn20
-rw-r--r--doc/bugs/git-annex_sync_may_fail_when_the_directory_I__39__m_in_disepeared.mdwn15
-rw-r--r--doc/bugs/git-annex_thinks_files_are_in_repositories_they_are_not.mdwn29
-rw-r--r--doc/bugs/git-annex_thinks_files_are_in_repositories_they_are_not/comment_1_6722fd627ec4add9f2b16546bd8ef341._comment8
-rw-r--r--doc/bugs/git-annex_thinks_files_are_in_repositories_they_are_not/comment_2_508e475f764e1cb453b756eb50bc3a15._comment34
-rw-r--r--doc/bugs/git-annex_thinks_files_are_in_repositories_they_are_not/comment_3_1656ba18c519a262c57ef626a3449e77._comment12
-rw-r--r--doc/bugs/git-annex_thinks_files_are_in_repositories_they_are_not/comment_4_347dc3b6e5bc6c4195ec09d54bc1398e._comment24
-rw-r--r--doc/bugs/git-annex_thinks_files_are_in_repositories_they_are_not/comment_5_a9c93bfc3278ef8b1117eac2af859bc3._comment12
-rw-r--r--doc/bugs/git-annex_thinks_files_are_in_repositories_they_are_not/comment_6_804dd62beef64f7d4e203bdb28cbe660._comment11
-rw-r--r--doc/bugs/git-annex_thinks_files_are_in_repositories_they_are_not/comment_7_4ef107d70647780eb5347cae6f467fed._comment12
-rw-r--r--doc/bugs/git-annex_webapp_command_not_found.mdwn25
-rw-r--r--doc/bugs/git-annex_webapp_command_not_found/comment_1_6fa63ae1a7affb2351eda57ab3b4eda1._comment10
-rw-r--r--doc/bugs/git-annex_webapp_command_not_found/comment_2_d25232bb5eaff725281869d7681e81ad._comment8
-rw-r--r--doc/bugs/git_annex_add_..._adds_too_much.mdwn25
-rw-r--r--doc/bugs/git_annex_add_eats_files_when_filename_is_too_long.mdwn14
-rw-r--r--doc/bugs/git_annex_add_eats_files_when_filename_is_too_long/comment_1_9650284913bec2a00cf551b90ab5d8ff._comment21
-rw-r--r--doc/bugs/git_annex_add_eats_files_when_filename_is_too_long/comment_2_c6c8d2a1f444d85c582bc5396b08e148._comment8
-rw-r--r--doc/bugs/git_annex_add_eats_files_when_filename_is_too_long/comment_3_5776864d78d56849001dd12e3adb9cbe._comment8
-rw-r--r--doc/bugs/git_annex_add_eats_files_when_filename_is_too_long/comment_4_371ec7b4ae73280ede31edfe90b42a95._comment9
-rw-r--r--doc/bugs/git_annex_add_eats_files_when_filename_is_too_long/comment_5_4fb04f646de591640f8504c0caf61acd._comment12
-rw-r--r--doc/bugs/git_annex_add_eats_files_when_filename_is_too_long/comment_6_b4055409fe48da95bb3101c0242ef0bc._comment8
-rw-r--r--doc/bugs/git_annex_add_error_with_Andrew_File_System.mdwn28
-rw-r--r--doc/bugs/git_annex_add_error_with_Andrew_File_System/comment_1_bc783e551fc0e8da87bc95bff5b8f73a._comment8
-rw-r--r--doc/bugs/git_annex_add_error_with_Andrew_File_System/comment_2_faefcf69bd61c47566131cb31b78cc19._comment10
-rw-r--r--doc/bugs/git_annex_add_error_with_Andrew_File_System/comment_3_d5014c8b78437b9fddbb1e83d3679081._comment10
-rw-r--r--doc/bugs/git_annex_add_memory_leak.mdwn39
-rw-r--r--doc/bugs/git_annex_add_removes_file_with_no_data_left.mdwn103
-rw-r--r--doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_10_9cc749a6efd4359a99316036f5bc867f._comment12
-rw-r--r--doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_11_1fed5be9db29866e4dc3d3bb12907bf3._comment8
-rw-r--r--doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_12_06d517ac4ef8def4629a40d7c3549bac._comment8
-rw-r--r--doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_1_8f081aeba7065d143a453dc128543f59._comment18
-rw-r--r--doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_2_54a4b10723fd8a80dd486377ff15ce0d._comment10
-rw-r--r--doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_3_f1964e4e07991a251c2795da0361a4e2._comment28
-rw-r--r--doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_4_73c38d843c30f00f6fd8883db8e55f62._comment10
-rw-r--r--doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_5_7ede5ee312f3abdf78979c0d52a7871a._comment12
-rw-r--r--doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_6_e37cf18708f09619442c3a9532d12ed9._comment13
-rw-r--r--doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_7_a744ef7dd3a224a911ebb24858bc2fd6._comment8
-rw-r--r--doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_8_f97141b255073b90120895148220c2d7._comment10
-rw-r--r--doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_9_dd2be11dfd190129d491f5f891e7cd1a._comment10
-rw-r--r--doc/bugs/git_annex_assistant_--autostart_failed.mdwn39
-rw-r--r--doc/bugs/git_annex_assistant_--autostart_failed/comment_1_746545273b53849c42ff6272324e5155._comment10
-rw-r--r--doc/bugs/git_annex_assistant_--autostart_failed/comment_2_5bdf6f94da12e551ae12e7f550a84d62._comment8
-rw-r--r--doc/bugs/git_annex_assistant_--autostart_failed/comment_3_bfd646f69946a5fe926b270cf94f87cb._comment8
-rw-r--r--doc/bugs/git_annex_content_fails_with_a_parse_error.txt32
-rw-r--r--doc/bugs/git_annex_content_fails_with_a_parse_error/comment_1_2b60b6ae0115de13ecf837b34dadcd1d._comment8
-rw-r--r--doc/bugs/git_annex_copy_--fast_does_not_copy_files.mdwn22
-rw-r--r--doc/bugs/git_annex_copy_-f_REMOTE_._doesn__39__t_work_as_expected.mdwn18
-rw-r--r--doc/bugs/git_annex_copy_trying_to_connect_to_remotes_uninvolved.mdwn27
-rw-r--r--doc/bugs/git_annex_copy_trying_to_connect_to_remotes_uninvolved/comment_1_f1330935a07460c9c8bc82ee8d4709c5._comment12
-rw-r--r--doc/bugs/git_annex_dead_does_not_work_as_expected_when_multiple_repos_exist_with_the_same_name___40__notably_including_dead_ones__41__.mdwn42
-rw-r--r--doc/bugs/git_annex_dead_does_not_work_as_expected_when_multiple_repos_exist_with_the_same_name___40__notably_including_dead_ones__41__/comment_1_7ee08a60e4b2516c010d3c2163049681._comment15
-rw-r--r--doc/bugs/git_annex_dead_does_not_work_as_expected_when_multiple_repos_exist_with_the_same_name___40__notably_including_dead_ones__41__/comment_2_c29525bfda08717f68aaac83014e6b08._comment8
-rw-r--r--doc/bugs/git_annex_describe_can_break_uuid.log.mdwn46
-rw-r--r--doc/bugs/git_annex_describe_can_break_uuid.log/comment_2_9ead36f13cbde6c822b231441de636ae._comment8
-rw-r--r--doc/bugs/git_annex_does_nothing_useful.mdwn67
-rw-r--r--doc/bugs/git_annex_does_nothing_useful/comment_10_457354dc0018333002dc5049935c0feb._comment8
-rw-r--r--doc/bugs/git_annex_does_nothing_useful/comment_11_8a6d244165dd238ddf9dd629795de2f6._comment10
-rw-r--r--doc/bugs/git_annex_does_nothing_useful/comment_12_30d06bc0f1c37d988a1a31962b57533c._comment18
-rw-r--r--doc/bugs/git_annex_does_nothing_useful/comment_1_fc4f51ddcbc69631e2835b86c3489c8e._comment7
-rw-r--r--doc/bugs/git_annex_does_nothing_useful/comment_2_9bb1647e6c59f1ed7b13b81ecc33f920._comment13
-rw-r--r--doc/bugs/git_annex_does_nothing_useful/comment_3_d434f5c614a27b75d73530b5b918b851._comment14
-rw-r--r--doc/bugs/git_annex_does_nothing_useful/comment_4_998e33219d29ea41b0b2a5d2955a9862._comment46
-rw-r--r--doc/bugs/git_annex_does_nothing_useful/comment_5_c72e2571e5b8c06bbfa2276a7ad1e8a6._comment16
-rw-r--r--doc/bugs/git_annex_does_nothing_useful/comment_6_bc8b42432ba25de8f972c192bc3cdff6._comment44
-rw-r--r--doc/bugs/git_annex_does_nothing_useful/comment_7_e7469a4c5e45078ade775f5cbdd17cfc._comment67
-rw-r--r--doc/bugs/git_annex_does_nothing_useful/comment_8_bc9e6fd284440a59ffe4e4ed1f73f7d7._comment30
-rw-r--r--doc/bugs/git_annex_does_nothing_useful/comment_9_38a2dbeee3750d79ca9a943a02fceb29._comment17
-rw-r--r--doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9.mdwn220
-rw-r--r--doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_10_141819a6b67de2602673698f6f148106._comment13
-rw-r--r--doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_11_8be96359fd2bd33ed2961e499dc2685e._comment12
-rw-r--r--doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_12_26950a37e86d4dd83dd59fb2564d0a2e._comment11
-rw-r--r--doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_13_cbf8150dbe0da64bde7f6af8e041eda8._comment8
-rw-r--r--doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_14_0c203f90d911cf6869894dae89575a49._comment13
-rw-r--r--doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_15_68cbb7268bdad73357da2d11e05d73c4._comment8
-rw-r--r--doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_16_816d552f871a1b06306f04d575adb2e5._comment8
-rw-r--r--doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_17_7905b097a9c582452fb04cdc88ed4285._comment14
-rw-r--r--doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_18_bd5ac9bb2eaab66af6aa13b39172b49d._comment9
-rw-r--r--doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_19_9881db7bb6fef4e47c54cdc23e995f17._comment13
-rw-r--r--doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_1_4fb9d3de245dddab65fb1a53a67a095c._comment8
-rw-r--r--doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_20_41e2ea458669f59f96b5860825745910._comment8
-rw-r--r--doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_21_515039e321e0595f95430d8082bd54a5._comment20
-rw-r--r--doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_22_9412236296871c570c66f5b4c7f9681e._comment10
-rw-r--r--doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_23_e4e7d13be6c0bc63f426e535de6172f8._comment8
-rw-r--r--doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_24_c73e1277c5f284b1019362fb2bef94a8._comment8
-rw-r--r--doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_2_f513259a2641e00b049203014ab940c8._comment12
-rw-r--r--doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_3_54ee7b90467fee8b0457e9c447747500._comment10
-rw-r--r--doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_4_7e6223c2dae3346e17276c7bbb01d53e._comment12
-rw-r--r--doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_5_13b6e595d595da7f036e81258a65541e._comment8
-rw-r--r--doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_6_94144c0cbdbccc72c13e12daf7657a29._comment8
-rw-r--r--doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_7_9eb064ffdc3fdb70e85572185e151a3f._comment8
-rw-r--r--doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_8_cde756e8a9b18fe2ca9cda25967bc7fb._comment10
-rw-r--r--doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_9_1fd6a4374a334bc03914c3e0df95ef95._comment10
-rw-r--r--doc/bugs/git_annex_fork_bombs_on_gpg_file.mdwn25
-rw-r--r--doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_10_6e29b60cd77f3288e33ad270f95f410e._comment8
-rw-r--r--doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_11_ad13e3221ae06086e86800316912d951._comment12
-rw-r--r--doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_12_41746b731eae7f280bb668c776022bcb._comment8
-rw-r--r--doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_13_56ca8590110abffeed6d826c54ca1136._comment10
-rw-r--r--doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_1_73ae438a37e4c5f56fe291448e1c64dd._comment13
-rw-r--r--doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_2_aa237adebe7674b8cdb9a967bb5f96a8._comment8
-rw-r--r--doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_3_ab403d7abbbbabd498b954b0b9742755._comment12
-rw-r--r--doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_4_a35d04440b1220faf9088107c3f17762._comment10
-rw-r--r--doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_5_8345331b9b313769ba401da2ffd89332._comment10
-rw-r--r--doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_6_7eb535ca38b3e84d44d0f8cbf5e61b8b._comment18
-rw-r--r--doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_7_a3aa4231a82917c56cbdf52b65db7133._comment21
-rw-r--r--doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_8_178fd4e4d6abbca192fcd6d592615fca._comment12
-rw-r--r--doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_9_7d80f131f43312bb061df2be7fa956ef._comment10
-rw-r--r--doc/bugs/git_annex_fsck_in_direct_mode_does_not_checksum_files.mdwn18
-rw-r--r--doc/bugs/git_annex_fsck_in_direct_mode_does_not_checksum_files/comment_1_a6cde4aa495512344fa7f50e10749c68._comment8
-rw-r--r--doc/bugs/git_annex_fsck_in_direct_mode_does_not_checksum_files/comment_2_4ac3b87ec0bc0514c4eff9f5a75b9f5d._comment26
-rw-r--r--doc/bugs/git_annex_fsck_in_direct_mode_does_not_checksum_files/comment_3_d18b1fdc866edf2786d2c6b7ec55119f._comment11
-rw-r--r--doc/bugs/git_annex_fsck_in_direct_mode_does_not_checksum_files/comment_4_31e4fcbf63c11cc374a849daf3ce1dbc._comment8
-rw-r--r--doc/bugs/git_annex_fsck_is_a_no-op_in_bare_repos.mdwn21
-rw-r--r--doc/bugs/git_annex_fsck_is_a_no-op_in_bare_repos/comment_1_fc59fbd1cdf8ca97b0a4471d9914aaa1._comment8
-rw-r--r--doc/bugs/git_annex_fsck_is_a_no-op_in_bare_repos/comment_2_273a45e6977d40d39e0d9ab924a83240._comment9
-rw-r--r--doc/bugs/git_annex_get_choke_when_remote_is_an_ssh_url_with_a_port.mdwn13
-rw-r--r--doc/bugs/git_annex_gets_confused_about_remotes_with_dots_in_their_names.mdwn34
-rw-r--r--doc/bugs/git_annex_import_destroys_a_fellow_git_annex_repository.mdwn130
-rw-r--r--doc/bugs/git_annex_importfeed_fails.mdwn64
-rw-r--r--doc/bugs/git_annex_indirect_can_fail_catastrophically.mdwn78
-rw-r--r--doc/bugs/git_annex_indirect_can_fail_catastrophically/comment_1_0b085e7e8c8e364f479574bc00c7c394._comment21
-rw-r--r--doc/bugs/git_annex_initremote_needs_some___34__error_checking__34__.mdwn65
-rw-r--r--doc/bugs/git_annex_initremote_walks_.git-annex.mdwn19
-rw-r--r--doc/bugs/git_annex_map_has_problems_with_urls_containing___126__.mdwn46
-rw-r--r--doc/bugs/git_annex_migrate_leaves_old_backend_versions_around.mdwn19
-rw-r--r--doc/bugs/git_annex_migrate_leaves_old_backend_versions_around/comment_1_f3e418144e5a5a9b3eda459546fc2bb0._comment8
-rw-r--r--doc/bugs/git_annex_should_use___39__git_add_-f__39___internally.mdwn11
-rw-r--r--doc/bugs/git_annex_should_use___39__git_add_-f__39___internally/comment_1_7683bf02cf9e97830fb4690314501568._comment8
-rw-r--r--doc/bugs/git_annex_sync_in_direct_mode_does_not_honor_skip-worktree.mdwn35
-rw-r--r--doc/bugs/git_annex_sync_in_direct_mode_does_not_honor_skip-worktree/comment_1_69baeb997086c885f34fd1dc385cf5d6._comment12
-rw-r--r--doc/bugs/git_annex_sync_in_direct_mode_does_not_honor_skip-worktree/comment_2_fb8c0bebb9aaa75ee7eaf6999b1db49e._comment10
-rw-r--r--doc/bugs/git_annex_sync_in_direct_mode_does_not_honor_skip-worktree/comment_3_6bfd4e9a7853af93e72b717249de9439._comment8
-rw-r--r--doc/bugs/git_annex_uninit_loses_content_when_interrupted.mdwn33
-rw-r--r--doc/bugs/git_annex_uninit_loses_content_when_interrupted/comment_1_fd9d2abbc90fb4f470b2212bc1f4a2dd._comment8
-rw-r--r--doc/bugs/git_annex_uninit_loses_content_when_interrupted/comment_2_0e99f6ef4f8b342ef0ebc64dbf8e2ce6._comment12
-rw-r--r--doc/bugs/git_annex_uninit_removes_files_not_previously_added_to_annex.mdwn32
-rw-r--r--doc/bugs/git_annex_uninit_removes_files_not_previously_added_to_annex/comment_1_ce4e3b1bf0d53119d049cf7dd621c5c4._comment10
-rw-r--r--doc/bugs/git_annex_uninit_removes_files_not_previously_added_to_annex/comment_2_3aa125635609fce41ab0c98cefb81f98._comment9
-rw-r--r--doc/bugs/git_annex_unlock_is_not_atomic.mdwn7
-rw-r--r--doc/bugs/git_annex_unused_aborts_due_to_filename_encoding_problems.mdwn15
-rw-r--r--doc/bugs/git_annex_unused_aborts_due_to_filename_encoding_problems/comment_1_8ba4fdb9f2d3bd44db5e910526cb9124._comment8
-rw-r--r--doc/bugs/git_annex_unused_aborts_due_to_filename_encoding_problems/comment_2_2a4a2b3e287a0444a1c8e8d98768a206._comment8
-rw-r--r--doc/bugs/git_annex_unused_aborts_due_to_filename_encoding_problems/comment_3_dacfdb8322045fc4ceefc9128bf7c505._comment17
-rw-r--r--doc/bugs/git_annex_unused_aborts_due_to_filename_encoding_problems/comment_4_7889a3ff5ce80c6322448aa674df8525._comment10
-rw-r--r--doc/bugs/git_annex_unused_aborts_due_to_filename_encoding_problems/comment_5_6d28c2537ce24eeb3496ca349823defd._comment19
-rw-r--r--doc/bugs/git_annex_unused_aborts_due_to_filename_encoding_problems/comment_6_4bf14ecef622988e80976c0fb55c24b9._comment10
-rw-r--r--doc/bugs/git_annex_unused_aborts_due_to_filename_encoding_problems/comment_7_d2e5382fe0f38fb9dd9ee69901c68151._comment8
-rw-r--r--doc/bugs/git_annex_unused_aborts_due_to_filename_encoding_problems/comment_8_b282757537cda863d3dc6d0bbfd6b656._comment8
-rw-r--r--doc/bugs/git_annex_unused_considers_remote_branches_which_makes_it_inconsistent.mdwn106
-rw-r--r--doc/bugs/git_annex_unused_considers_remote_branches_which_makes_it_inconsistent/comment_1_a636ffe55b11c46a0afcc0b9a3a88cd4._comment10
-rw-r--r--doc/bugs/git_annex_unused_considers_remote_branches_which_makes_it_inconsistent/comment_2_5e1ad57420efd16ae09c9e5cad55b5f2._comment13
-rw-r--r--doc/bugs/git_annex_unused_failes_on_empty_repository.mdwn15
-rw-r--r--doc/bugs/git_annex_unused_seems_to_check_for_current_path.mdwn39
-rw-r--r--doc/bugs/git_annex_upgrade_loses_track_of_files_with___34____38____34___character___40__and_probably_others__41__.mdwn33
-rw-r--r--doc/bugs/git_annex_upgrade_loses_track_of_files_with___34____38____34___character___40__and_probably_others__41__/comment_1_861506e40e0d04d2be98bbfe9188be89._comment12
-rw-r--r--doc/bugs/git_annex_upgrade_output_is_inconsistent_and_spammy.mdwn15
-rw-r--r--doc/bugs/git_annex_upgrade_output_is_inconsistent_and_spammy/comment_1_3a01c81efba321b0e46d1bc0426ad8d1._comment10
-rw-r--r--doc/bugs/git_annex_version_should_without_being_in_a_repo_.mdwn7
-rw-r--r--doc/bugs/git_annex_version_should_without_being_in_a_repo_/comment_1_e7b26eeb1a765fd83280ef907c0deef2._comment8
-rw-r--r--doc/bugs/git_annex_webapp_--listen_on_a_remote_linux_server.mdwn50
-rw-r--r--doc/bugs/git_annex_webapp_--listen_on_a_remote_linux_server/comment_1_db99c00830d3f15ebe790c4dc8b60bd7._comment8
-rw-r--r--doc/bugs/git_annex_webapp_runs_on_wine.mdwn47
-rw-r--r--doc/bugs/git_annex_webapp_runs_on_wine/comment_1_c71dfa42780c0fc78f88ce054e5f3ee3._comment16
-rw-r--r--doc/bugs/git_annex_webapp_runs_on_wine/comment_2_f28441b18b0be90c1e58348455ce09d9._comment23
-rw-r--r--doc/bugs/git_annex_won__39__t_copy_files_to_my_usb_drive.mdwn60
-rw-r--r--doc/bugs/git_annex_won__39__t_copy_files_to_my_usb_drive/comment_1_7707017fbf3d92ee21d600fe0aefce4f._comment10
-rw-r--r--doc/bugs/git_annex_won__39__t_copy_files_to_my_usb_drive/comment_2_f3392ec3ca7392823cbad2cc9b77f54e._comment9
-rw-r--r--doc/bugs/git_annex_won__39__t_copy_files_to_my_usb_drive/comment_3_b3d016a487b12748fe2c4d14300eb158._comment20
-rw-r--r--doc/bugs/git_annex_won__39__t_copy_files_to_my_usb_drive/comment_4_61f600511a3172f0707e5809fc444d0c._comment9
-rw-r--r--doc/bugs/git_annex_won__39__t_copy_files_to_my_usb_drive/comment_5_8cf029ac7bf3c19dcb0b613eed3b52ac._comment10
-rw-r--r--doc/bugs/git_annex_won__39__t_copy_files_to_my_usb_drive/comment_6_e40d88eba7d8aec1530ce1d32d1c85f2._comment11
-rw-r--r--doc/bugs/git_annex_won__39__t_copy_files_to_my_usb_drive/comment_7_b101fab9e690d1b335a1a29abab68d6c._comment10
-rw-r--r--doc/bugs/git_annex_won__39__t_copy_files_to_my_usb_drive/comment_8_b30d32086314a7e357f3dd6608828ee5._comment9
-rw-r--r--doc/bugs/git_annix_breaks_git_commit_after_uninstall.mdwn42
-rw-r--r--doc/bugs/git_annix_breaks_git_commit_after_uninstall/comment_1_c8b1bab40d3bb2468a5bba7b116e854e._comment8
-rw-r--r--doc/bugs/git_annix_breaks_git_commit_after_uninstall/comment_2_4173770375fca51dcaf9b974296d041a._comment8
-rw-r--r--doc/bugs/git_command_line_constructed_by_unannex_command_has_tons_of_redundant_-a_paramters.mdwn15
-rw-r--r--doc/bugs/git_defunct_processes___40__child_of_git-annex_assistant__41__.mdwn34
-rw-r--r--doc/bugs/git_defunct_processes___40__child_of_git-annex_assistant__41__/comment_1_5e3f4b63db5cd32b63fb3e6a78f9b093._comment10
-rw-r--r--doc/bugs/git_rename_detection_on_file_move.mdwn13
-rw-r--r--doc/bugs/git_rename_detection_on_file_move/comment_10_5ec2f965c80cc5dd31ee3c4edb695664._comment8
-rw-r--r--doc/bugs/git_rename_detection_on_file_move/comment_1_0531dcfa833b0321a7009526efe3df33._comment26
-rw-r--r--doc/bugs/git_rename_detection_on_file_move/comment_2_7101d07400ad5935f880dc00d89bf90e._comment27
-rw-r--r--doc/bugs/git_rename_detection_on_file_move/comment_3_57010bcaca42089b451ad8659a1e018e._comment8
-rw-r--r--doc/bugs/git_rename_detection_on_file_move/comment_4_79d96599f757757f34d7b784e6c0e81c._comment34
-rw-r--r--doc/bugs/git_rename_detection_on_file_move/comment_5_d61f5693d947b9736b29fca1dbc7ad76._comment12
-rw-r--r--doc/bugs/git_rename_detection_on_file_move/comment_6_f63de6fe2f7189c8c2908cc41c4bc963._comment19
-rw-r--r--doc/bugs/git_rename_detection_on_file_move/comment_7_7f20d0b2f6ed1c34021a135438037306._comment10
-rw-r--r--doc/bugs/git_rename_detection_on_file_move/comment_8_6a00500b24ba53248c78e1ffc8d1a591._comment21
-rw-r--r--doc/bugs/git_rename_detection_on_file_move/comment_9_75e0973f6d573df615e01005ebcea87d._comment9
-rw-r--r--doc/bugs/git_version_in_prebuilt_linux_tarball_is_outdated.mdwn11
-rw-r--r--doc/bugs/git_version_in_prebuilt_linux_tarball_is_outdated/comment_1_2a5a07498df9d38531d4570f7b463b9a._comment8
-rw-r--r--doc/bugs/gitignore_for_DCIM_on_Android_misses_some_files.mdwn17
-rw-r--r--doc/bugs/gitignore_for_DCIM_on_Android_misses_some_files/comment_1_f683ecf93e5a17c5c9c06225dbcce2a9._comment12
-rw-r--r--doc/bugs/gix-annex_help_is_homicidal.mdwn23
-rw-r--r--doc/bugs/glacier_from_multiple_repos.mdwn14
-rw-r--r--doc/bugs/googlemail.mdwn16
-rw-r--r--doc/bugs/gpg_bundled_with_OSX_build_fails.mdwn25
-rw-r--r--doc/bugs/gpg_bundled_with_OSX_build_fails/comment_1_ec911f920db6c354ba998ffbb5886606._comment10
-rw-r--r--doc/bugs/gpg_bundled_with_OSX_build_fails/comment_2_bf2a3ab1bbe258bd501ec4b776882adf._comment12
-rw-r--r--doc/bugs/gpg_bundled_with_OSX_build_fails/comment_3_c0142427400323c00bd8294415ae32c5._comment15
-rw-r--r--doc/bugs/gpg_bundled_with_OSX_build_fails/comment_4_b56db4b5afc276f88a2b980e22fda8a0._comment10
-rw-r--r--doc/bugs/gpg_bundled_with_OSX_build_fails/comment_5_a4eda81e5f927c463593bc48fbe84077._comment12
-rw-r--r--doc/bugs/gpg_bundled_with_OSX_build_fails/comment_6_2f0b9331d16a208883bac586258a7b50._comment8
-rw-r--r--doc/bugs/gpg_bundled_with_OSX_build_fails/comment_7_c05c484a6134f93796cff08de0f63e80._comment16
-rw-r--r--doc/bugs/gpg_bundled_with_OSX_build_fails/comment_8_f2cb5467ebe80cf67e1155b771b73978._comment8
-rw-r--r--doc/bugs/gpg_bundled_with_OSX_build_fails/comment_9_27bbda7e31f55b29e1473555ee17e613._comment8
-rw-r--r--doc/bugs/gpg_error_on_android.mdwn39
-rw-r--r--doc/bugs/gpg_error_on_android/comment_1_870583fd1b7a33b688b9a228077d1333._comment629
-rw-r--r--doc/bugs/gpg_error_on_android/comment_2_9ce5511a109bde50d8cf87bad0268b4a._comment26
-rw-r--r--doc/bugs/gpg_error_on_android/comment_3_b345e80f38d38f82cfcfce3102138fb8._comment46
-rw-r--r--doc/bugs/gpg_error_on_android/comment_4_032f42235b7f26854e725041ca33384b._comment10
-rw-r--r--doc/bugs/gpg_fails_on_Mac_OS_10.9_when_creating_a_new_remote_repository_via_assistant.mdwn55
-rw-r--r--doc/bugs/gpg_fails_on_Mac_OS_10.9_when_creating_a_new_remote_repository_via_assistant/comment_1_7b409701c650b55b3472accd70555f16._comment8
-rw-r--r--doc/bugs/gpg_fails_on_Mac_OS_10.9_when_creating_a_new_remote_repository_via_assistant/comment_2_40b00f7258512677516ec5036b89090f._comment14
-rw-r--r--doc/bugs/gpg_goes_to_100__37___cpu_on_bad_input_data.mdwn18
-rw-r--r--doc/bugs/gpg_goes_to_100__37___cpu_on_bad_input_data/comment_1_889218fb7c0115b03d9bad0c07296097._comment36
-rw-r--r--doc/bugs/gpg_hangs_on_glacier_remote_creation.mdwn78
-rw-r--r--doc/bugs/gpg_hangs_on_glacier_remote_creation/comment_1_41ca74a4e4aaf4f6b012a92677037651._comment14
-rw-r--r--doc/bugs/gpg_hangs_on_glacier_remote_creation/comment_2_dd11fd25c8bb1f2d7e1292c07abf553e._comment591
-rw-r--r--doc/bugs/gpg_hangs_on_glacier_remote_creation/comment_3_543d8a13756c1355a5752867bdcbefd3._comment20
-rw-r--r--doc/bugs/gpg_hangs_on_glacier_remote_creation/comment_4_6441cf25e6bd62c96d7e766da9bdd7fb._comment25
-rw-r--r--doc/bugs/gpg_hangs_on_glacier_remote_creation/comment_5_72e152294e36bc5f2d78e8e2ebed6a23._comment8
-rw-r--r--doc/bugs/gpg_hangs_on_glacier_remote_creation/comment_6_890e85df05903795e01efbd7879f9c87._comment8
-rw-r--r--doc/bugs/gpg_hangs_on_glacier_remote_creation/comment_7_042047f9fcc45abbfa47c3973d79f08e._comment10
-rw-r--r--doc/bugs/gpg_needs_--use-agent.mdwn53
-rw-r--r--doc/bugs/hGetContents:_user_error.mdwn38
-rw-r--r--doc/bugs/hGetContents:_user_error/comment_1_30178f151f8c60d2ff856ca543dc506c._comment10
-rw-r--r--doc/bugs/hGetContents:_user_error/comment_2_f74eeed4a007058a22183fd678ecd6c6._comment8
-rw-r--r--doc/bugs/hGetContents:_user_error/comment_3_515e562228a89a13d6d857a874f4a468._comment8
-rw-r--r--doc/bugs/hGetContents:_user_error/comment_4_8c6ed5e459c5c66b77db446c6317114c._comment8
-rw-r--r--doc/bugs/hGetContents:_user_error/comment_5_f80bce48c3f96b0cd6892af43ee88a96._comment8
-rw-r--r--doc/bugs/hGetContents:_user_error/comment_6_69dc09e4ae726856dafbeec34170671c._comment8
-rw-r--r--doc/bugs/hGetContents:_user_error/comment_7_3f66b03f773341fad94ec16b4f55edaa._comment32
-rw-r--r--doc/bugs/hGetContents:_user_error/comment_8_a697e2d36abfc999e65c9f587c0de56e._comment10
-rw-r--r--doc/bugs/hGetContents:_user_error/comment_9_da7c5905a64bb6779970f9394155e629._comment10
-rw-r--r--doc/bugs/haskell-dbus_problems_on_OSX___40__or_this_a_general_problem__41__.mdwn113
-rw-r--r--doc/bugs/host_with_rysnc_installed__44___not_recognized.mdwn19
-rw-r--r--doc/bugs/host_with_rysnc_installed__44___not_recognized/comment_1_3ff000eb3efde41426c7b086ae627dcf._comment12
-rw-r--r--doc/bugs/host_with_rysnc_installed__44___not_recognized/comment_2_34e592ab057df2df54e13d3f5cae64f0._comment14
-rw-r--r--doc/bugs/host_with_rysnc_installed__44___not_recognized/comment_3_05ffbae13d8f9b08315f40bb9b206f46._comment21
-rw-r--r--doc/bugs/host_with_rysnc_installed__44___not_recognized/comment_4_99d1f151263ca3433dd4afa8a928b1fe._comment30
-rw-r--r--doc/bugs/host_with_rysnc_installed__44___not_recognized/comment_5_6ef1a377b0b4d3efeffdf9693d0b496b._comment12
-rw-r--r--doc/bugs/host_with_rysnc_installed__44___not_recognized/comment_6_d9e36828ad55f3181a1c650010f23d6b._comment14
-rw-r--r--doc/bugs/immediately_drops_files.mdwn222
-rw-r--r--doc/bugs/immediately_drops_files/comment_1_9ef6e694ef8a8eee7a42f88554475db7._comment10
-rw-r--r--doc/bugs/immediately_drops_files/comment_2_76e4f8b73ab60b2540dd2a3e5379791d._comment8
-rw-r--r--doc/bugs/immediately_drops_files/comment_3_788db083f5ba2e5589c3b952203ec954._comment21
-rw-r--r--doc/bugs/immediately_drops_files/comment_4_425b79865eb77d69d0b7a71a14639f81._comment10
-rw-r--r--doc/bugs/immediately_drops_files/comment_5_7c9f660b6bcec31827a44a650e9d4622._comment10
-rw-r--r--doc/bugs/importfeed_fails__44___bad_feed_content.mdwn36
-rw-r--r--doc/bugs/importfeed_fails_when_using_the_option_--lazy_for_specific_podcast.mdwn77
-rw-r--r--doc/bugs/importfeed_fails_when_using_the_option_--lazy_for_specific_podcast/comment_1_4ccfabbaf75e139b32f6fa6f7bc6a7fe._comment8
-rw-r--r--doc/bugs/importfeed_should_allow_pubdate_in_the_template.mdwn5
-rw-r--r--doc/bugs/importfeed_uses___34____95__foo__34___as_extension.mdwn17
-rw-r--r--doc/bugs/inconsistent_use_of_SI_prefixes.mdwn55
-rw-r--r--doc/bugs/internal_server_error:_hGetContents:_invalid_argument___40__invalid_byte_sequence__41__.mdwn29
-rw-r--r--doc/bugs/internal_server_error:_unknown_UUID_on_webapp.mdwn147
-rw-r--r--doc/bugs/internal_server_error_creating_repo_on_ssh_server.mdwn26
-rw-r--r--doc/bugs/internal_server_error_creating_repo_on_ssh_server/comment_1_4a2c9338d5c779496049d78e29cf5cbd._comment8
-rw-r--r--doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option.mdwn28
-rw-r--r--doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option/comment_1_14a2f775f43a86129ce3649a06f8ba0b._comment8
-rw-r--r--doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option/comment_2_7b277320fcffd8d03e0d3d31398eb571._comment16
-rw-r--r--doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option/comment_3_ba9dd8f2cc46640383d4339a3661571f._comment16
-rw-r--r--doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option/comment_4_274ae39d55545bde0be931d7a6c42c94._comment12
-rw-r--r--doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option/comment_5_242291d46acc61bdfc112e3316de528b._comment10
-rw-r--r--doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option/comment_6_76b936263e82ca6c415a16ed57e770b4._comment8
-rw-r--r--doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option/comment_7_9ccd3749fd9f32b0906c0b9428cc514f._comment10
-rw-r--r--doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option/comment_8_4e8982668b5044b2286d55c90adb9da3._comment8
-rw-r--r--doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option/comment_9_aaf0ee250972d737a2ca57de5b5f1c0a._comment12
-rw-r--r--doc/bugs/interrupting_migration_causes_problems.mdwn52
-rw-r--r--doc/bugs/javascript_functions_qouting_issue.mdwn44
-rw-r--r--doc/bugs/journal_commit_error_when_using_annex.mdwn21
-rw-r--r--doc/bugs/journal_commit_error_when_using_annex/comment_1_38f60ca3503ea1530c4bd2cde5c9182f._comment10
-rw-r--r--doc/bugs/journal_commit_error_when_using_annex/comment_2_6de455a67f37d9ee0a307a78123781bf._comment10
-rw-r--r--doc/bugs/long_running_assistant_causes_resource_starvation_on_OSX.mdwn30
-rw-r--r--doc/bugs/long_running_assistant_causes_resource_starvation_on_OSX/comment_1_91c911c29fd126ddc365c561591f627e._comment10
-rw-r--r--doc/bugs/long_running_assistant_causes_resource_starvation_on_OSX/comment_2_c316aead931a6a2377a4515bbb34ac5b._comment8
-rw-r--r--doc/bugs/lsof__47__committer_thread_loops_occassionally.mdwn53
-rw-r--r--doc/bugs/lsof__47__committer_thread_loops_occassionally/comment_1_f8d1720aa26c719609720acf0772606e._comment11
-rw-r--r--doc/bugs/lsof__47__committer_thread_loops_occassionally/comment_2_0527569ea2924721d19dadcf4fe0ec5a._comment8
-rw-r--r--doc/bugs/lsof__47__committer_thread_loops_occassionally/comment_3_5b67ff08a897ea3d2266ccc910ab4278._comment8
-rw-r--r--doc/bugs/make_SHA512E_the_default.mdwn29
-rw-r--r--doc/bugs/make_install_can__39__t_be_used_with_sudo.mdwn20
-rw-r--r--doc/bugs/make_install_doesn__39__t_create_git-annex-shell.mdwn62
-rw-r--r--doc/bugs/make_install_doesn__39__t_create_git-annex-shell/comment_1_8c20edd8c6483500f807528d616c6dfd._comment14
-rw-r--r--doc/bugs/make_install_doesn__39__t_create_git-annex-shell/comment_2_8b2cf0fe7219e0bc83fd326adbf26c8a._comment31
-rw-r--r--doc/bugs/make_install_doesn__39__t_create_git-annex-shell/comment_3_25fe06eb127e59a4a07aeb52a5cfeabe._comment8
-rw-r--r--doc/bugs/make_install_doesn__39__t_create_git-annex-shell/comment_4_ec78032ba62d6918baa2c0b07ead5b50._comment8
-rw-r--r--doc/bugs/making_annex-merge_try_a_fast-forward.mdwn35
-rw-r--r--doc/bugs/manpage_has_slight_indentation_error.mdwn38
-rw-r--r--doc/bugs/map_not_respecting_annex_ssh_options__63__.mdwn38
-rw-r--r--doc/bugs/map_not_respecting_annex_ssh_options__63__/comment_1_c63a1ed5909d53f116f06e60aba74dc6._comment10
-rw-r--r--doc/bugs/merge_causes_out_of_memory_on_large_repos.mdwn26
-rw-r--r--doc/bugs/merge_causes_out_of_memory_on_large_repos/comment_1_6d47485728ea65a9b555f8be7159dea5._comment10
-rw-r--r--doc/bugs/merge_causes_out_of_memory_on_large_repos/comment_2_06723d13ecdaf87de5ff2b209e3c5198._comment10
-rw-r--r--doc/bugs/merge_causes_out_of_memory_on_large_repos/comment_3_9f83ef190547b291a715cda55b7977d4._comment10
-rw-r--r--doc/bugs/merge_causes_out_of_memory_on_large_repos/comment_4_0e32ae0300472c56079cfbcd78a3e386._comment9
-rw-r--r--doc/bugs/merge_causes_out_of_memory_on_large_repos/comment_5_e8998716107e7ae8d0e8d332812517ad._comment14
-rw-r--r--doc/bugs/microsd__47__thumbdrives_seem_to_die_when_using_the_ARM_build.mdwn36
-rw-r--r--doc/bugs/microsd__47__thumbdrives_seem_to_die_when_using_the_ARM_build/comment_1_0527581ea60d28bb28504fa2a355ed87._comment10
-rw-r--r--doc/bugs/microsd__47__thumbdrives_seem_to_die_when_using_the_ARM_build/comment_2_926a87b60e20d286d49639c8dad13a1a._comment8
-rw-r--r--doc/bugs/microsd__47__thumbdrives_seem_to_die_when_using_the_ARM_build/comment_3_c509fba1a9adacfd26a2bd12b4aea988._comment8
-rw-r--r--doc/bugs/migrated_files_not_showing_up_in_unused_list.mdwn62
-rw-r--r--doc/bugs/migrated_files_not_showing_up_in_unused_list/comment_1_2cfbf6693b051c758fe5efa5ee885829._comment16
-rw-r--r--doc/bugs/migrated_files_not_showing_up_in_unused_list/comment_2_acb1abeb32c3aba8ba65151afbea753c._comment10
-rw-r--r--doc/bugs/minor_bug:_errors_are_not_verbose_enough.mdwn26
-rw-r--r--doc/bugs/missing_dependency_in_git-annex-3.20130216.mdwn29
-rw-r--r--doc/bugs/missing_kde__47__gnome_menu_item..mdwn29
-rw-r--r--doc/bugs/moreinfo.mdwn6
-rw-r--r--doc/bugs/network___62____61___2.4.0.1_is_not_in_Haskell_Platform_2012.4.0.0.mdwn12
-rw-r--r--doc/bugs/network___62____61___2.4.0.1_is_not_in_Haskell_Platform_2012.4.0.0/comment_1_2c4b3757bb8de563edca65aeabcbbc5a._comment29
-rw-r--r--doc/bugs/nfs_mounted_repo_results_in_errors_on_drop_move.mdwn59
-rw-r--r--doc/bugs/non-annexed_file_changed_to_annexed_on_typechange.mdwn40
-rw-r--r--doc/bugs/non-annexed_file_changed_to_annexed_on_typechange/comment_1_6ac691645edb483797bee05043fd83b3._comment8
-rw-r--r--doc/bugs/non-annexed_file_changed_to_annexed_on_typechange/comment_2_5d67e3a60b7cc30c2b1857f50895d363._comment8
-rw-r--r--doc/bugs/non-annexed_file_changed_to_annexed_on_typechange/comment_3_78f1e081b92f418c20893d86a8715501._comment8
-rw-r--r--doc/bugs/non-annexed_file_changed_to_annexed_on_typechange/comment_4_1e2a59e0eec89ef1a57d1488ff40dcf0._comment12
-rw-r--r--doc/bugs/non-annexed_file_changed_to_annexed_on_typechange/comment_5_5e74431048b07631e0dbeca90fdb365b._comment47
-rw-r--r--doc/bugs/non-annexed_file_changed_to_annexed_on_typechange/comment_6_3724e1c1a5fc6d3589452478249792ec._comment8
-rw-r--r--doc/bugs/non-annexed_file_changed_to_annexed_on_typechange/comment_7_7f841ea7bf7d44f3d810ca097ac9eb47._comment8
-rw-r--r--doc/bugs/non-annexed_file_changed_to_annexed_on_typechange/comment_8_c53ce2274388711ffbde1595b64f932b._comment10
-rw-r--r--doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status.mdwn89
-rw-r--r--doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status/comment_1_fcd230cbb2ac363c469b98021042c011._comment10
-rw-r--r--doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status/comment_2_23207ecabd4b41d9551d0491fa71e96b._comment12
-rw-r--r--doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status/comment_3_6ea92adfe955b6a5cd2a39fea78b3bf6._comment119
-rw-r--r--doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status/comment_4_d0e55585f1612148163039d157253258._comment11
-rw-r--r--doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status/comment_6_5506dc1b08516677886da4aa97263864._comment12
-rw-r--r--doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status/comment_7_073449cc2cb73efd2b2d3d778a5573de._comment14
-rw-r--r--doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status/comment_7_3516e71ba3b07427a10cbb4965712aa6._comment24
-rw-r--r--doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status/comment_8_ea2e4704adb2f304f9c11c61eb62e919._comment8
-rw-r--r--doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status/comment_9_4d17fedead7977541371a3f2c192e030._comment46
-rw-r--r--doc/bugs/not_possible_to_have_annex_on_a_separate_filesystem.mdwn32
-rw-r--r--doc/bugs/old_data_isn__39__t_unused_after_migration.mdwn66
-rw-r--r--doc/bugs/on--git-dir_and_--work-tree_options.mdwn31
-rw-r--r--doc/bugs/optinally_transfer_file_unencryptedly/comment_1_13a7653d96ddf91f4492a9f3555a69aa._comment16
-rw-r--r--doc/bugs/optinally_transfer_file_unencryptedly/comment_2_31f154011ec26a463de7b1e307e49cb6._comment8
-rw-r--r--doc/bugs/optinally_transfer_file_unencryptedly/comment_3_33433bcfb1946b52f1f41b9158ab452d._comment8
-rw-r--r--doc/bugs/ordering.mdwn12
-rw-r--r--doc/bugs/pasting_into_annex_on_OSX.mdwn28
-rw-r--r--doc/bugs/pasting_into_annex_on_OSX/comment_1_4eab52bb6eda92e39bdaa8eee8f31a7f._comment8
-rw-r--r--doc/bugs/pasting_into_annex_on_OSX/comment_2_f1b58adfec179b75c1fc2bf578a3b5c4._comment8
-rw-r--r--doc/bugs/pasting_into_annex_on_OSX/comment_3_270aa7680c3b899a92ce6543eaba666a._comment17
-rw-r--r--doc/bugs/pasting_into_annex_on_OSX/comment_4_ec11a80d5b0f78c7a927f8aa71a6c57a._comment8
-rw-r--r--doc/bugs/pasting_into_annex_on_OSX/comment_5_1928bd25e5e6874a3b83c2f2adc776f5._comment7
-rw-r--r--doc/bugs/pasting_into_annex_on_OSX/comment_6_0fe288f54b781a0c51395cb32f0e2f9d._comment8
-rw-r--r--doc/bugs/problem_commit_normal_links.mdwn59
-rw-r--r--doc/bugs/problem_with_upgrade_v2_-__62___v3.mdwn3
-rw-r--r--doc/bugs/problem_with_upgrade_v2_-__62___v3/comment_1_5f60006c9bb095167d817f234a14d20b._comment8
-rw-r--r--doc/bugs/problem_with_upgrade_v2_-__62___v3/comment_2_cd0123392b16d89db41b45464165c247._comment23
-rw-r--r--doc/bugs/problem_with_upgrade_v2_-__62___v3/comment_3_86d9e7244ae492bcbe62720b8c4fc4a9._comment16
-rw-r--r--doc/bugs/problem_with_upgrade_v2_-__62___v3/comment_4_91439d4dbbf1461e281b276eb0003691._comment8
-rw-r--r--doc/bugs/problem_with_upgrade_v2_-__62___v3/comment_5_ca33a9ca0df33f7c1b58353d7ffb943d._comment8
-rw-r--r--doc/bugs/problem_with_upgrade_v2_-__62___v3/comment_6_f360f0006bc9115bc5a3e2eb9fe58abd._comment10
-rw-r--r--doc/bugs/problems_with_utf8_names.mdwn81
-rw-r--r--doc/bugs/problems_with_utf8_names/comment_1_3c7e3f021c2c94277eecf9c8af6cec5f._comment17
-rw-r--r--doc/bugs/problems_with_utf8_names/comment_2_bad4c4c5f54358d1bc0ab2adc713782a._comment10
-rw-r--r--doc/bugs/problems_with_utf8_names/comment_3_4f936a5d3f9c7df64c8a87e62b7fbfdc._comment8
-rw-r--r--doc/bugs/problems_with_utf8_names/comment_4_93bee35f5fa7744834994bc7a253a6f9._comment10
-rw-r--r--doc/bugs/problems_with_utf8_names/comment_5_519cda534c7aea7f5ad5acd3f76e21fa._comment11
-rw-r--r--doc/bugs/problems_with_utf8_names/comment_6_52e0bfff2b177b6f92e226b25d2f3ff1._comment8
-rw-r--r--doc/bugs/problems_with_utf8_names/comment_7_0cc588f787d6eecfa19a8f6cee4b07b5._comment8
-rw-r--r--doc/bugs/problems_with_utf8_names/comment_8_ff5c6da9eadfee20c18c86b648a62c47._comment10
-rw-r--r--doc/bugs/random_files_vanishing_when_assistant_gets_restarted.mdwn34
-rw-r--r--doc/bugs/random_files_vanishing_when_assistant_gets_restarted/comment_1_53b4f388c47c1b3f6ffa4fc2155b30fc._comment21
-rw-r--r--doc/bugs/random_files_vanishing_when_assistant_gets_restarted/comment_2_e66532b23b089c9ea61122d6664cddb9._comment10
-rw-r--r--doc/bugs/random_files_vanishing_when_assistant_gets_restarted/comment_3_c9d692c867acc076f64f1213ea03ca11._comment8
-rw-r--r--doc/bugs/regression_in_direct_mode_on_windows_:_weird___96__git_annex_sync__96___behavior.mdwn113
-rw-r--r--doc/bugs/regression_in_direct_mode_on_windows_:_weird___96__git_annex_sync__96___behavior/comment_1_1a0b964f93c753838d6ccbdc8f79b39e._comment8
-rw-r--r--doc/bugs/regression_in_direct_mode_on_windows_:_weird___96__git_annex_sync__96___behavior/comment_2_d22dcd7f95c5dc1c381c3c746781efce._comment8
-rw-r--r--doc/bugs/regression_in_direct_mode_on_windows_:_weird___96__git_annex_sync__96___behavior/comment_3_a25140eb90f6b24c1a3ca39c901694e2._comment10
-rw-r--r--doc/bugs/regression_in_direct_mode_on_windows_:_weird___96__git_annex_sync__96___behavior/comment_4_825e15183008ff7d97a81cacc3f55fb4._comment8
-rw-r--r--doc/bugs/regression_in_direct_mode_on_windows_:_weird___96__git_annex_sync__96___behavior/comment_5_e858fc7c729cd39740354fb12627d556._comment10
-rw-r--r--doc/bugs/regression_in_direct_mode_on_windows_:_weird___96__git_annex_sync__96___behavior/comment_6_9881b0f2dfb0907a60c0da296bc3da3f._comment10
-rw-r--r--doc/bugs/regression_in_direct_mode_on_windows_:_weird___96__git_annex_sync__96___behavior/comment_7_ca017b9d3bafea4cb31448c802f3834e._comment8
-rw-r--r--doc/bugs/reinject_should_leave_file_in_place_on_checksum_mismatch.mdwn15
-rw-r--r--doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist.mdwn65
-rw-r--r--doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_10_8a1d16b2aaba224e94be3d9dcc036d91._comment12
-rw-r--r--doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_11_434ed328a22a6657dba3b2929a56e499._comment18
-rw-r--r--doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_12_1837b70ace42882db3ab82e001680934._comment29
-rw-r--r--doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_13_ca9c87a10f29e41572540edeb99652f2._comment11
-rw-r--r--doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_1_69eafc4201e3014ef1b5d74fe319e462._comment10
-rw-r--r--doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_2_b7a64db9abe006af8c30169ad849efe9._comment76
-rw-r--r--doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_3_197ac6070f256131c6e18a07aa3834fa._comment14
-rw-r--r--doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_4_fe07832333b536c71b7dcb46a4a44bd0._comment19
-rw-r--r--doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_5_540bca4e6fdfc10eeab875ecc0f2b3f3._comment10
-rw-r--r--doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_6_3f236b35e9820cd88bb77fcd57d6975e._comment43
-rw-r--r--doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_7_3cc5dae0351201522711a7caeecd60d5._comment10
-rw-r--r--doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_8_3c3883cb66d02a15d5de84d22aa113da._comment38
-rw-r--r--doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_9_c8cece9559bd2dc6154cd28772369e48._comment10
-rw-r--r--doc/bugs/remote_not_showing_up_in_webapp.mdwn88
-rw-r--r--doc/bugs/remote_not_showing_up_in_webapp/comment_1_2a269732fd528f505777542d3556437a._comment17
-rw-r--r--doc/bugs/removable_device_configurator_chokes_on_spaces.mdwn18
-rw-r--r--doc/bugs/rename:_permission_denied__44___after_direct_mode_switch.mdwn81
-rw-r--r--doc/bugs/rename:_permission_denied__44___after_direct_mode_switch/comment_1_14cec6448831c67794b62926a03b2fc5._comment13
-rw-r--r--doc/bugs/rename:_permission_denied__44___after_direct_mode_switch/comment_2_93af8f48a01b6e2d011bd6f60499ccd2._comment23
-rw-r--r--doc/bugs/rename:_permission_denied__44___after_direct_mode_switch/comment_3_f8fba1955e62360061613e5898b3d74e._comment16
-rw-r--r--doc/bugs/renaming_a_file_makes_annex_get_the_file__39__s_content_from_remote.mdwn27
-rw-r--r--doc/bugs/renaming_a_file_makes_annex_get_the_file__39__s_content_from_remote/comment_1_d6aad1831674586fe4cdf61dd2a4bbb9._comment15
-rw-r--r--doc/bugs/renaming_a_file_makes_annex_get_the_file__39__s_content_from_remote/comment_2_8591e174c1a8cddfae9371407a58ff1c._comment10
-rw-r--r--doc/bugs/repair_fails_when_home_on_seperate_partition.mdwn60
-rw-r--r--doc/bugs/restart_daemon_required.mdwn22
-rw-r--r--doc/bugs/restart_daemon_required/comment_1_f79ac16cc9f1e3b08cd121bf5efb29c3._comment8
-rw-r--r--doc/bugs/restart_daemon_required/comment_2_50c1b268a3cc4514681059eabca674e3._comment8
-rw-r--r--doc/bugs/restart_daemon_required/comment_3_1716e0f3c7c44dc77ebf7f00fdd8f9e3._comment310
-rw-r--r--doc/bugs/restart_daemon_required/comment_4_3ce776786eca83fcb8ff94c8f6ff3eb9._comment15
-rw-r--r--doc/bugs/rsync_remote_shows_no_progress.mdwn15
-rw-r--r--doc/bugs/rsync_remote_shows_no_progress/comment_1_a7f5d646a924c462b987561cf6fc4318._comment8
-rw-r--r--doc/bugs/rsync_special_remote_fails_to___96__get__96___files_which_have_names_containing_spaces.mdwn50
-rw-r--r--doc/bugs/scp_interrupt_to_background.mdwn2
-rw-r--r--doc/bugs/show_version_without_having_to_be_in_a_git_repo.mdwn11
-rw-r--r--doc/bugs/signal_weirdness.mdwn48
-rw-r--r--doc/bugs/size_of_the_Android_installation_is_HUGE_--_please_seek_possibility_to_shrink.mdwn41
-rw-r--r--doc/bugs/size_of_the_Android_installation_is_HUGE_--_please_seek_possibility_to_shrink/comment_1_d2faaff98386433110dcf7aae87916b7._comment9
-rw-r--r--doc/bugs/size_of_the_Android_installation_is_HUGE_--_please_seek_possibility_to_shrink/comment_2_1359ddf1b5db4303f8bd219d3f07df3a._comment10
-rw-r--r--doc/bugs/smarter_flood_filling.mdwn31
-rw-r--r--doc/bugs/softlink_mtime.mdwn54
-rw-r--r--doc/bugs/ssh-keygen_failed_when_adding_remote_server_repo.mdwn44
-rw-r--r--doc/bugs/ssh-keygen_failed_when_adding_remote_server_repo/comment_1_52180983b59c247389a55a9523ec435b._comment14
-rw-r--r--doc/bugs/ssh_connection_caching_broken_on_NTFS.mdwn66
-rw-r--r--doc/bugs/ssh_connection_caching_broken_on_NTFS/comment_1_54e7e12514f4c109fd57a4eb744b731a._comment14
-rw-r--r--doc/bugs/submodule_path_problem.mdwn56
-rw-r--r--doc/bugs/submodule_path_problem/comment_1_69aec9207d2e9da4bc042d3f4963d80e._comment48
-rw-r--r--doc/bugs/submodule_path_problem/comment_2_53d9eb28cb70b51637470175a80ddf35._comment8
-rw-r--r--doc/bugs/submodule_path_problem/comment_3_aa5e0f99000a5b4988bccbb2ca28353b._comment20
-rw-r--r--doc/bugs/submodule_path_problem/comment_4_ab1508a5a04e2106aad5e7985775a6fa._comment8
-rw-r--r--doc/bugs/submodule_path_problem/comment_5_8c7539d1c11b81f5d46aa8e1c61745ae._comment14
-rw-r--r--doc/bugs/submodule_path_problem/comment_6_cacc91afcb1739dfca3a60590bb70356._comment67
-rw-r--r--doc/bugs/subtle_build_issue_on_OSX_10.7_and_Haskell_Platform___40__if_you_have_the_32bit_version_installed__41__.mdwn50
-rw-r--r--doc/bugs/subtle_build_issue_on_OSX_10.7_and_Haskell_Platform___40__if_you_have_the_32bit_version_installed__41__/comment_1_6208e70a21a048d5423926d16e32d421._comment9
-rw-r--r--doc/bugs/subtle_build_issue_on_OSX_10.7_and_Haskell_Platform___40__if_you_have_the_32bit_version_installed__41__/comment_2_8765b6190e79251637bb59ba28f245c1._comment21
-rw-r--r--doc/bugs/support_bare_git_repo__44___with_the_annex_directory_exposed_to_http.mdwn20
-rw-r--r--doc/bugs/test_failures_on_window_for_5.20131118.mdwn20
-rw-r--r--doc/bugs/test_failures_on_window_for_5.20131118/comment_1_5a7a284625c12d54390fe4a4ec1d4211._comment188
-rw-r--r--doc/bugs/test_suite_failure_on_samba_mount.mdwn278
-rw-r--r--doc/bugs/test_suite_failure_on_samba_mount/comment_1_e074b20801b921ee2661025a050a8af2._comment12
-rw-r--r--doc/bugs/test_suite_shouldn__39__t_fail_silently.mdwn3
-rw-r--r--doc/bugs/tests_fail_when_there_is_no_global_.gitconfig_for_the_user.mdwn50
-rw-r--r--doc/bugs/tests_failed_to_build_-_after_an_update_of_haskell_platform.mdwn23
-rw-r--r--doc/bugs/tests_failed_to_build_-_after_an_update_of_haskell_platform/comment_1_20a6fe046111e9ae56fd4d9c9f41f536._comment8
-rw-r--r--doc/bugs/tests_failed_to_build_-_after_an_update_of_haskell_platform/comment_2_6fdc5f8b07908c6eda8a97690408f44e._comment45
-rw-r--r--doc/bugs/tests_failed_to_build_-_after_an_update_of_haskell_platform/comment_3_014474a133c7ff0131029d8721afc710._comment46
-rw-r--r--doc/bugs/tests_failed_to_build_-_after_an_update_of_haskell_platform/comment_4_9c537e251dc99667fe87870804d802c2._comment10
-rw-r--r--doc/bugs/the_tip_at_commit_6cecc26206c4a539999b04664136c6f785211a41_disables_the_watch_command_on_OSX.mdwn22
-rw-r--r--doc/bugs/three_character_directories_created.mdwn56
-rw-r--r--doc/bugs/three_character_directories_created/comment_1_dd91de24dab4f2eaded1f7d659869d4d._comment8
-rw-r--r--doc/bugs/three_character_directories_created/comment_2_f6375964a6c8bb1e6c5b7238effca66d._comment62
-rw-r--r--doc/bugs/three_character_directories_created/comment_3_776e0a9b938d8b260a5111594b442536._comment8
-rw-r--r--doc/bugs/three_character_directories_created/comment_4_e288bacdb336c4886adb6eeb4dca1e92._comment8
-rw-r--r--doc/bugs/three_character_directories_created/comment_5_359b80948ac92a0f1eb695599456486c._comment10
-rw-r--r--doc/bugs/three_way_sync_via_S3_and_Jabber.mdwn119
-rw-r--r--doc/bugs/three_way_sync_via_S3_and_Jabber/comment_10_fc5ec5505f141bb9135e772d1094bc4d._comment12
-rw-r--r--doc/bugs/three_way_sync_via_S3_and_Jabber/comment_11_0df2210c30dec6d88d7858d93eec19a3._comment10
-rw-r--r--doc/bugs/three_way_sync_via_S3_and_Jabber/comment_1_41682b2e72e657e0f23af244f8345e85._comment10
-rw-r--r--doc/bugs/three_way_sync_via_S3_and_Jabber/comment_2_c7b4ea9aea6839763eb8b89e8d6a5ad5._comment14
-rw-r--r--doc/bugs/three_way_sync_via_S3_and_Jabber/comment_3_063f5e5e554ad6710f16394906d87616._comment33
-rw-r--r--doc/bugs/three_way_sync_via_S3_and_Jabber/comment_4_197ad39b4a46936afeeb04eb26cf1ef3._comment138
-rw-r--r--doc/bugs/three_way_sync_via_S3_and_Jabber/comment_5_0b0d829ccd255be0177ae9d8f6b10e63._comment61
-rw-r--r--doc/bugs/three_way_sync_via_S3_and_Jabber/comment_6_37a8e19440c764317589bc4248cbccdf._comment10
-rw-r--r--doc/bugs/three_way_sync_via_S3_and_Jabber/comment_7_12eb333327d31ca2bfee3f3c5e26d641._comment24
-rw-r--r--doc/bugs/three_way_sync_via_S3_and_Jabber/comment_8_e6b1084b2f18d8e536c8692e165754a3._comment12
-rw-r--r--doc/bugs/three_way_sync_via_S3_and_Jabber/comment_9_2120a1c3e5f490a55f68bb1bef5efd0d._comment183
-rw-r--r--doc/bugs/tmp_file_handling.mdwn13
-rw-r--r--doc/bugs/tmp_file_handling/comment_1_0300c11ee3f94a9e7c832671e16f5511._comment13
-rw-r--r--doc/bugs/tmp_file_handling/comment_2_cc14c7a79a544e47654e4cd8abc85edd._comment8
-rw-r--r--doc/bugs/touch.hsc_has_problems_on_non-linux_based_systems.mdwn19
-rw-r--r--doc/bugs/touch.hsc_has_problems_on_non-linux_based_systems/comment_1_1d38283c9ea87174f3bbef9a58f5cb88._comment10
-rw-r--r--doc/bugs/touch.hsc_has_problems_on_non-linux_based_systems/comment_2_bf112edd075fbebe4fc959a387946eb9._comment8
-rw-r--r--doc/bugs/touch.hsc_has_problems_on_non-linux_based_systems/comment_3_a46080fbe82adf0986c5dc045e382501._comment8
-rw-r--r--doc/bugs/touch.hsc_has_problems_on_non-linux_based_systems/comment_4_760437bf3ba972a775bb190fb4b38202._comment8
-rw-r--r--doc/bugs/touch.hsc_has_problems_on_non-linux_based_systems/comment_5_060ba5ea88dcab2f4a0c199f13ef4f67._comment10
-rw-r--r--doc/bugs/touch.hsc_has_problems_on_non-linux_based_systems/comment_6_548303d6ffb21a9370b6904f41ff49c1._comment42
-rw-r--r--doc/bugs/touch.hsc_has_problems_on_non-linux_based_systems/comment_7_7ca00527ab5db058aadec4fe813e51fd._comment8
-rw-r--r--doc/bugs/touch.hsc_has_problems_on_non-linux_based_systems/comment_8_881aecb9ae671689453f6d5d780d844b._comment8
-rw-r--r--doc/bugs/transferkey_fails_due_to_gpg.mdwn51
-rw-r--r--doc/bugs/transferkey_fails_due_to_gpg/comment_1_f6434400d528a0fa59c056995ff2e6f3._comment12
-rw-r--r--doc/bugs/transferkey_fails_due_to_gpg/comment_2_c540b05b62a3186a87efcb180ea2a52d._comment12
-rw-r--r--doc/bugs/transferkey_fails_due_to_gpg/comment_3_9ad2ef73169dbd2866da2f4259ab0f00._comment8
-rw-r--r--doc/bugs/transferkey_fails_due_to_gpg/comment_4_7631b8842efba6a4aad87386ce9443a7._comment8
-rw-r--r--doc/bugs/typo_in___34__ready_to_add_remote_server__34___message.mdwn16
-rw-r--r--doc/bugs/typo_on_the_Mac_OS_10.7.5_Lion_build.mdwn11
-rw-r--r--doc/bugs/typo_on_the_Mac_OS_10.7.5_Lion_build/comment_1_e8df4b36a89b37edd94f3a318ae93a32._comment8
-rw-r--r--doc/bugs/typo_on_the_Mac_OS_10.7.5_Lion_build/comment_2_3b2c3c84bd1910280c549a2ee1c622b9._comment8
-rw-r--r--doc/bugs/unable_to_change_repository_group_of___34__here__34__.mdwn13
-rw-r--r--doc/bugs/unannex_and_uninit_do_not_work_when_git_index_is_broken.mdwn17
-rw-r--r--doc/bugs/unannex_and_uninit_do_not_work_when_git_index_is_broken/comment_1_1931e733f0698af5603a8b92267203d4._comment8
-rw-r--r--doc/bugs/unannex_and_uninit_do_not_work_when_git_index_is_broken/comment_2_40920b88537b7715395808d8aa94bf03._comment8
-rw-r--r--doc/bugs/unannex_command_doesn__39__t_all_files.mdwn30
-rw-r--r--doc/bugs/unannex_removes_object_even_if_referred_to_by_others.mdwn20
-rw-r--r--doc/bugs/unannex_removes_object_even_if_referred_to_by_others/comment_1_0ce72d0f67082f202cfa58b7c00f2fd3._comment39
-rw-r--r--doc/bugs/unannex_removes_object_even_if_referred_to_by_others/comment_2_647f49ffcaa348660659f9954a59b3ae._comment16
-rw-r--r--doc/bugs/unannex_removes_object_even_if_referred_to_by_others/comment_3_3f7f4b55b7ec2641a70109788e0b5672._comment10
-rw-r--r--doc/bugs/unannex_removes_object_even_if_referred_to_by_others/comment_4_313d393c416495aa0f8573113e41c2f7._comment431
-rw-r--r--doc/bugs/unannex_removes_object_even_if_referred_to_by_others/comment_5_c0e7742672db2629bd906cebefe74f72._comment10
-rw-r--r--doc/bugs/unannex_removes_object_even_if_referred_to_by_others/comment_6_c56171665db3ed14109a09097d49ac5d._comment8
-rw-r--r--doc/bugs/unannex_vs_unlock_hook_confusion.mdwn15
-rw-r--r--doc/bugs/undefined.mdwn5
-rw-r--r--doc/bugs/unfinished_repos_in_webapp.mdwn31
-rw-r--r--doc/bugs/unfinished_repos_in_webapp/comment_1_9628b100e39489be9f28ef75276a7341._comment11
-rw-r--r--doc/bugs/unfinished_repos_in_webapp/comment_2_ba0fbff536b1d067c4098db401dc49f2._comment10
-rw-r--r--doc/bugs/unfinished_repos_in_webapp/comment_3_fd554aa7d93117177784a29270ccf790._comment12
-rw-r--r--doc/bugs/unfinished_repository_when_using_annex-ignore_true_.mdwn25
-rw-r--r--doc/bugs/unhappy_without_UTF8_locale.mdwn41
-rw-r--r--doc/bugs/uninit_and_indirect_don__39__t_work_on_android.mdwn23
-rw-r--r--doc/bugs/uninit_and_indirect_don__39__t_work_on_android/comment_1_fec69c4c41987b9469eaa8f745c0a124._comment8
-rw-r--r--doc/bugs/uninit_and_indirect_don__39__t_work_on_android/comment_2_54c3fa77a069b36d03c41aad08fee9af._comment8
-rw-r--r--doc/bugs/uninit_does_not_abort_when_hard_link_creation_fails.mdwn47
-rw-r--r--doc/bugs/uninit_does_not_work_in_old_repos.mdwn20
-rw-r--r--doc/bugs/uninit_does_not_work_in_old_repos/comment_1_bc0619c6e17139df74639448aa6a0f72._comment8
-rw-r--r--doc/bugs/uninit_loses_data_if_git-annex_add_didn__39__t_complete.mdwn15
-rw-r--r--doc/bugs/uninit_should_not_run_when_branch_git-annex_is_checked_out.mdwn15
-rw-r--r--doc/bugs/unlock_fails_silently_with_directory_symlinks.mdwn53
-rw-r--r--doc/bugs/unlock_not_working_on_os_x_10.6_-_cp:_illegal_option_--_-_.mdwn22
-rw-r--r--doc/bugs/unlock_not_working_on_os_x_10.6_-_cp:_illegal_option_--_-_/comment_1_a634a9f1c023bf836183de64abab1224._comment10
-rw-r--r--doc/bugs/unlock_not_working_on_os_x_10.6_-_cp:_illegal_option_--_-_/comment_2_d9ae61a7c3f1eb243ca650945b40f21d._comment19
-rw-r--r--doc/bugs/unlock_not_working_on_os_x_10.6_-_cp:_illegal_option_--_-_/comment_3_fe229c03c14e8eb2b57389e0e193ed99._comment8
-rw-r--r--doc/bugs/unlock_not_working_on_os_x_10.6_-_cp:_illegal_option_--_-_/comment_4_fa12afe295de63c4aa7eb043b715325a._comment15
-rw-r--r--doc/bugs/unlock_then_lock_of_uncommitted_file_loses_it.mdwn7
-rw-r--r--doc/bugs/upgrade_left_untracked_.git-annex__47____42___directories.mdwn16
-rw-r--r--doc/bugs/upgrade_left_untracked_.git-annex__47____42___directories/comment_1_9ca2da52f3c8add0276b72d6099516a6._comment10
-rw-r--r--doc/bugs/upgrade_left_untracked_.git-annex__47____42___directories/comment_2_e14e84b770305893f2fc6e4938359f47._comment18
-rw-r--r--doc/bugs/upgrade_left_untracked_.git-annex__47____42___directories/comment_3_ec04e306c96fd20ab912aea54a8340aa._comment8
-rw-r--r--doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again.mdwn434
-rw-r--r--doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_10_51097a6b84edcc607abc0e6e21ca21f2._comment8
-rw-r--r--doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_1_c34a4009213c410bba3c147ae0552029._comment15
-rw-r--r--doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_2_634542867fd28962c47b7bc3ea022175._comment8
-rw-r--r--doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_3_301f3ff2d203ac4c58a037e553b2c14d._comment18
-rw-r--r--doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_4_82ecdc88ccc1f87386b128adc4ff9af4._comment14
-rw-r--r--doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_6_158b2ba3da815910505899606177d415._comment16
-rw-r--r--doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_6_b068924802f3917e3e005350cb0cc2a2._comment8
-rw-r--r--doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_7_f4772858c927d4a62edc3caf59b5da10._comment8
-rw-r--r--doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_8_d0923d2950357f4444c5ef94ff196ba3._comment8
-rw-r--r--doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_9_7fb30cb80aecc60e48c64846aa185206._comment9
-rw-r--r--doc/bugs/uploads_queued_to_annex-ignore_remotes.mdwn34
-rw-r--r--doc/bugs/uploads_queued_to_annex-ignore_remotes/comment_1_fa1c98f38253db8c2be3604c72eb3726._comment17
-rw-r--r--doc/bugs/using_old_remote_format_generates_irritating_output.mdwn28
-rw-r--r--doc/bugs/using_old_remote_format_generates_irritating_output/comment_1_fceba878f1097e27f056580e8d6d5b31._comment26
-rw-r--r--doc/bugs/using_old_remote_format_generates_irritating_output/comment_2_416992874813f120721a56d88b2bef65._comment9
-rw-r--r--doc/bugs/using_old_remote_format_generates_irritating_output/comment_3_a20f470c5226ac5693eb15146a02b3f5._comment8
-rw-r--r--doc/bugs/using_old_remote_format_generates_irritating_output/comment_4_a81f06191bc03a7aad5929af99f0634e._comment28
-rw-r--r--doc/bugs/using_old_remote_format_generates_irritating_output/comment_5_7438caecf78b4fb5d21f9f31dff95cf2._comment14
-rw-r--r--doc/bugs/utf8.mdwn192
-rw-r--r--doc/bugs/utf8/comment_10_f298b8b480d3ab2dd9c279589afcd0ea._comment10
-rw-r--r--doc/bugs/utf8/comment_11_a8864a46f8154680beeea27449ac6f09._comment142
-rw-r--r--doc/bugs/utf8/comment_12_2202c3479d19d306f31aac5a47b55e7d._comment10
-rw-r--r--doc/bugs/utf8/comment_13_7044d2c5bb1c91ee37eb9868963a1ff2._comment41
-rw-r--r--doc/bugs/utf8/comment_14_656b3caa16ae93b092fb5804fa575a3b._comment8
-rw-r--r--doc/bugs/utf8/comment_15_25b3d4c47c45b72129b17b171a45c5f9._comment8
-rw-r--r--doc/bugs/utf8/comment_16_2aaab9253bbc75012292c7b5a7d55696._comment173
-rw-r--r--doc/bugs/utf8/comment_1_416ad6fb5f7379732129dc5283a7e550._comment23
-rw-r--r--doc/bugs/utf8/comment_2_cd55f6bbeb145fd554f331dcff64f5e1._comment10
-rw-r--r--doc/bugs/utf8/comment_3_bb583a419d6fa4e33e5364c4468b35c6._comment8
-rw-r--r--doc/bugs/utf8/comment_4_cd8a22cfb70d9d21f0a5339ccc52ee93._comment14
-rw-r--r--doc/bugs/utf8/comment_5_14eefd4bee283802e9c462fa20b7835c._comment19
-rw-r--r--doc/bugs/utf8/comment_6_58d8b5bdb9f11e8c344e86a675a075dd._comment11
-rw-r--r--doc/bugs/utf8/comment_7_00fa9672ce55b6bfa885b8a13287ac25._comment10
-rw-r--r--doc/bugs/utf8/comment_8_a01e26fa0fafbc291020f53dbfdf6443._comment10
-rw-r--r--doc/bugs/utf8/comment_9_b7c084be01ce985be51e48503fcba468._comment8
-rw-r--r--doc/bugs/uuid.log_trust.log_and_remote.log_merge_wackiness.mdwn36
-rw-r--r--doc/bugs/version_doesn__39__t_show___34__Feeds__34___but_podcasting_feature_working.mdwn28
-rw-r--r--doc/bugs/version_doesn__39__t_show___34__Feeds__34___but_podcasting_feature_working/comment_1_ce06ba4f65f322362b23797f6190c7c3._comment17
-rw-r--r--doc/bugs/view_logs_fails:_Internal_Server_Error__internal_liftAnnex.mdwn20
-rw-r--r--doc/bugs/view_logs_fails:_Internal_Server_Error__internal_liftAnnex/comment_1_57547f9a480df2c3f7b3997b0fb7039a._comment12
-rw-r--r--doc/bugs/view_logs_fails:_Internal_Server_Error__internal_liftAnnex/comment_2_99f12da3ef01141dc7a9105fcf966793._comment10
-rw-r--r--doc/bugs/warning_-_WebApp_crashed:___60__file_descriptor_15__62__:_hPutStr:_illegal_operation___40__handle_is_closed__41___on_Android.mdwn24
-rw-r--r--doc/bugs/warning_-_WebApp_crashed:___60__file_descriptor_15__62__:_hPutStr:_illegal_operation___40__handle_is_closed__41___on_Android/comment_1_e8866dc15f8fc049229e7451addad1d5._comment12
-rw-r--r--doc/bugs/warning_-_WebApp_crashed:___60__file_descriptor_15__62__:_hPutStr:_illegal_operation___40__handle_is_closed__41___on_Android/comment_2_ee616b0251ffaace9844cfd7af896c35._comment10
-rw-r--r--doc/bugs/warning_-_WebApp_crashed:___60__file_descriptor_15__62__:_hPutStr:_illegal_operation___40__handle_is_closed__41___on_Android/comment_3_6b8bd314b647ea3a485f5faf4856f9a9._comment35
-rw-r--r--doc/bugs/warning_-_WebApp_crashed:___60__file_descriptor_15__62__:_hPutStr:_illegal_operation___40__handle_is_closed__41___on_Android/comment_4_7009b6727ba40bc9bd1b1f939e75d093._comment8
-rw-r--r--doc/bugs/warning_-_WebApp_crashed:___60__file_descriptor_15__62__:_hPutStr:_illegal_operation___40__handle_is_closed__41___on_Android/comment_5_00ddf7ade6cca758afa838be0b9588cb._comment20
-rw-r--r--doc/bugs/warning_-_WebApp_crashed:___60__file_descriptor_15__62__:_hPutStr:_illegal_operation___40__handle_is_closed__41___on_Android/comment_6_6137ef0ad01d5600dab6fccbeed9a88b._comment14
-rw-r--r--doc/bugs/warning_-_WebApp_crashed:___60__file_descriptor_15__62__:_hPutStr:_illegal_operation___40__handle_is_closed__41___on_Android/comment_7_4b79d7ea338d9f70eb80b8cc2c5a21e4._comment8
-rw-r--r--doc/bugs/watch_command_on_OSX_--_hangs_with_a_small_repo.mdwn41
-rw-r--r--doc/bugs/watch_command_on_OSX_--_hangs_with_a_small_repo/comment_1_63f04694610839db0c2381005b15da35._comment14
-rw-r--r--doc/bugs/watch_command_on_OSX_--_hangs_with_a_small_repo/comment_2_8afe4720e301cf7ccf11ff0a23261936._comment8
-rw-r--r--doc/bugs/watch_command_on_OSX_10.7.mdwn37
-rw-r--r--doc/bugs/watcher_commits_unlocked_files.mdwn37
-rw-r--r--doc/bugs/watcher_commits_unlocked_files/comment_1_f70e1912fde0eee59e208307df06b503._comment8
-rw-r--r--doc/bugs/web_app_loops_over_a_non-addable_file.mdwn56
-rw-r--r--doc/bugs/webapp:_difficult_to_abort_adding_a_repository.mdwn24
-rw-r--r--doc/bugs/webapp_hang.mdwn144
-rw-r--r--doc/bugs/webapp_hang/comment_1_08aa908a64d0fe2d50438d01545c3f01._comment8
-rw-r--r--doc/bugs/webapp_hang/comment_2_2a21ac5657128a454f9deb77c4d18057._comment21
-rw-r--r--doc/bugs/webapp_raise_an_internal_server_error_upon_creating_the_initial_repo.mdwn26
-rw-r--r--doc/bugs/webapp_raise_an_internal_server_error_upon_creating_the_initial_repo/comment_1_1bcf0f565eacac851bd21cd428c8e0a5._comment33
-rw-r--r--doc/bugs/webapp_raise_an_internal_server_error_upon_creating_the_initial_repo/comment_2_7dd2483b5b07df8f3b37a34651c05962._comment8
-rw-r--r--doc/bugs/webapp_requires_reload_for_notification_bubbles.mdwn41
-rw-r--r--doc/bugs/webapp_requires_reload_for_notification_bubbles/comment_1_b15480e5dec1ffbebb8cde1ca8d7c9d5._comment11
-rw-r--r--doc/bugs/webapp_requires_reload_for_notification_bubbles/comment_2_8dad57a852e1db804aa38f90f3bb398b._comment8
-rw-r--r--doc/bugs/webapp_shows___34__Added_x_files__34___a_bit_ugly.mdwn15
-rw-r--r--doc/bugs/webapp_usability:_fails_mysteriously_on_newer_repo_layouts.mdwn34
-rw-r--r--doc/bugs/webapp_usability:_put_the_notices_on_the_right.mdwn18
-rw-r--r--doc/bugs/webapp_usability:_put_the_notices_on_the_right/comment_1_ec7a444e09a028b5225bd41fb83442e8._comment9
-rw-r--r--doc/bugs/weird_local_clone_confuses.mdwn20
-rw-r--r--doc/bugs/whereis_outputs_no_informaiton_for_unlocked_files.mdwn44
-rw-r--r--doc/bugs/windows_fails_test___34__recoverEncode__34__.mdwn39
-rw-r--r--doc/bugs/windows_fails_test___34__recoverEncode__34__/comment_1_424b3536e21e02f192f7f2b8e833ed18._comment67
-rw-r--r--doc/bugs/windows_fails_test___34__recoverEncode__34__/comment_2_78db183aa401e2023d7faec5f7a4a573._comment10
-rw-r--r--doc/bugs/windows_fails_test___34__recoverEncode__34__/comment_3_ed2da19eaf0bd0864f6b28816a79bc23._comment8
-rw-r--r--doc/bugs/windows_install_failure.mdwn30
-rw-r--r--doc/bugs/windows_install_failure/comment_1_f339574c7cfa35c1f0dfd515fde457f5._comment8
-rw-r--r--doc/bugs/windows_install_failure/comment_2_1d3364d8f5c4963f3a7e473298ec6ed1._comment8
-rw-r--r--doc/bugs/windows_port_-_can__39__t_directly_access_files.mdwn250
-rw-r--r--doc/bugs/windows_port_-_can__39__t_directly_access_files/comment_1_03ef9d33839173044dcc4f2b37f575d2._comment8
-rw-r--r--doc/bugs/windows_port_-_can__39__t_directly_access_files/comment_2_c65e5491c82908af46fe2c97e048d210._comment20
-rw-r--r--doc/bugs/windows_port_-_git_annex_add_hangs_when_adding_17_files_at_once_or_more_.mdwn197
-rw-r--r--doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_.mdwn559
-rw-r--r--doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_10_b4f5e2d6a0d690f6b0089fa80a3c920b._comment8
-rw-r--r--doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_1_c2092add1430667108a3fdc5e1c9b5f5._comment8
-rw-r--r--doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_2_f0ea453951daf84dbddc653ac64822b6._comment8
-rw-r--r--doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_3_35a8be5ecc9d1b72c38f8ddb47678160._comment8
-rw-r--r--doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_4_29e72997b88f91f84639587b4cede34c._comment76
-rw-r--r--doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_5_2de7f6532de4cbc21737ce53a89d6525._comment10
-rw-r--r--doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_6_80d130b5af829763be77c61a9c5ca306._comment29
-rw-r--r--doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_7_ec199db851952b40e8b18922da574ea4._comment8
-rw-r--r--doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_8_d269fcadea9d5a668e3c6d6cf019f56a._comment353
-rw-r--r--doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_9_908d1b981d56107f29d8972bf11aefc8._comment12
-rw-r--r--doc/bugs/wrong_program_path_in___126____47__.config__47__git-annex__47__program.mdwn20
-rw-r--r--doc/bugs/wrong_program_path_in___126____47__.config__47__git-annex__47__program/comment_1_44c11918d00ead38d40556aade98c0af._comment12
-rw-r--r--doc/bugs/xdg-user-dir_error.mdwn8
-rw-r--r--doc/bugs/xmpp_needs_one_account_per_distinct_repository.mdwn107
-rw-r--r--doc/bugs/xmpp_needs_one_account_per_distinct_repository/comment_1_820732c4dcb15186b4f635c50fdb0805._comment19
-rw-r--r--doc/bugs/yesod-default_is_needed_as_a_dependancy.mdwn10
-rw-r--r--doc/bugs/yesod-form_missing.mdwn23
-rw-r--r--doc/bugs/youtube_support_suddenly_stopped_working.mdwn62
-rw-r--r--doc/builds.mdwn20
-rw-r--r--doc/coding_style.mdwn92
-rw-r--r--doc/comments.mdwn9
-rw-r--r--doc/contact.mdwn11
-rw-r--r--doc/contact/comment_1_12d60f767d90bea94974e1ff6b206d31._comment8
-rw-r--r--doc/contact/comment_2_95b6d868b913418de50ba121d71d2390._comment10
-rw-r--r--doc/contact/comment_3_2cf43bd406673294e6cdbd785c4a0d0c._comment16
-rw-r--r--doc/contact/comment_4_586a506e27379d74fbc0f4b654e89c7d._comment10
-rw-r--r--doc/copies.mdwn38
-rw-r--r--doc/copies/comment_1_af9bee33777fb8a187b714fc8c5fb11d._comment8
-rw-r--r--doc/design.mdwn8
-rw-r--r--doc/design/assistant.mdwn45
-rw-r--r--doc/design/assistant/OSX.mdwn13
-rw-r--r--doc/design/assistant/OSX/comment_1_9290f6e6f265e906b08631224392b7bf._comment14
-rw-r--r--doc/design/assistant/android.mdwn42
-rw-r--r--doc/design/assistant/android/comment_10_316bde8d22628e5e9d4f8dabce1d2ad4._comment14
-rw-r--r--doc/design/assistant/android/comment_1_8be9a74e5fc4641c2bf2e1bb7673dd59._comment8
-rw-r--r--doc/design/assistant/android/comment_2_3dd386ac1b757c73d14f14377b9eedd4._comment8
-rw-r--r--doc/design/assistant/android/comment_3_5dca47a4599d6e88d19193701c5a571b._comment46
-rw-r--r--doc/design/assistant/android/comment_4_054f06311e2b51d73be569f181eb004f._comment10
-rw-r--r--doc/design/assistant/android/comment_5_bb3d36e9d29f2fa77bee6d47ef9917fe._comment21
-rw-r--r--doc/design/assistant/android/comment_6_fee32a831eeb5736fe1dce52e30320c8._comment16
-rw-r--r--doc/design/assistant/android/comment_7_d8e9b0a5287fc96b19dc2cb9da3586ce._comment17
-rw-r--r--doc/design/assistant/android/comment_8_79a7b5bb5f4aaeea4a4e8ced0561701a._comment11
-rw-r--r--doc/design/assistant/android/comment_9_55ea70a6929523d26248ff6409b04a6e._comment10
-rw-r--r--doc/design/assistant/blog.mdwn11
-rw-r--r--doc/design/assistant/blog/day_100__cursed_clouds.mdwn19
-rw-r--r--doc/design/assistant/blog/day_102__very_high_level_programming.mdwn37
-rw-r--r--doc/design/assistant/blog/day_102__very_high_level_programming/comment_1_c028b403261dd66bcf83e6ffd134b80b._comment8
-rw-r--r--doc/design/assistant/blog/day_103__bugfix_day.mdwn25
-rw-r--r--doc/design/assistant/blog/day_104__misc.mdwn18
-rw-r--r--doc/design/assistant/blog/day_104__misc/comment_1_13d7fad2d3f8eab10314784c035e2a16._comment8
-rw-r--r--doc/design/assistant/blog/day_105__lazy_Sunday.mdwn43
-rw-r--r--doc/design/assistant/blog/day_106__lazy_Monday.mdwn10
-rw-r--r--doc/design/assistant/blog/day_107__memory_leak.mdwn11
-rw-r--r--doc/design/assistant/blog/day_108__another_zombie_outbreak.mdwn33
-rw-r--r--doc/design/assistant/blog/day_108__another_zombie_outbreak/comment_1_194c48d65993462f809a2cfaa774a3e2._comment11
-rw-r--r--doc/design/assistant/blog/day_108__another_zombie_outbreak/comment_2_ef5ee5933fcadcb81cc81b816db14bda._comment8
-rw-r--r--doc/design/assistant/blog/day_109__dropping.mdwn16
-rw-r--r--doc/design/assistant/blog/day_10__lsof.mdwn54
-rw-r--r--doc/design/assistant/blog/day_10__lsof/comment_1_9b8c28c85c979f32e5c295b6a03c048e._comment9
-rw-r--r--doc/design/assistant/blog/day_110__more_dropping.mdwn55
-rw-r--r--doc/design/assistant/blog/day_111__config_monitor.mdwn18
-rw-r--r--doc/design/assistant/blog/day_112__and_now_for_something_completely_different.mdwn50
-rw-r--r--doc/design/assistant/blog/day_112__and_now_for_something_completely_different/comment_1_5e4fe1538d9ae1c450b0a6602fc6d29b._comment10
-rw-r--r--doc/design/assistant/blog/day_112__and_now_for_something_completely_different/comment_2_c5a734f611ecc95729904e645583ee43._comment8
-rw-r--r--doc/design/assistant/blog/day_112__and_now_for_something_completely_different/comment_3_46b16dcd0fce07036cd8ed6ed9d2b055._comment8
-rw-r--r--doc/design/assistant/blog/day_112__and_now_for_something_completely_different/comment_4_1fe036e4c65fb4211aa2c394f535344a._comment8
-rw-r--r--doc/design/assistant/blog/day_112__and_now_for_something_completely_different/comment_5_e4ba3568c4efd98f212dd47427a1cf47._comment10
-rw-r--r--doc/design/assistant/blog/day_113__notifier_work.mdwn22
-rw-r--r--doc/design/assistant/blog/day_114__xmpp.mdwn56
-rw-r--r--doc/design/assistant/blog/day_114__xmpp/comment_1_c2b0617a2fc3dc4f19a6be6947913842._comment8
-rw-r--r--doc/design/assistant/blog/day_114__xmpp/comment_2_d14375dfb5791615802dab3c5438f8e2._comment8
-rw-r--r--doc/design/assistant/blog/day_114__xmpp/comment_3_6d72ea32c111e605be30ad2153fc71c9._comment10
-rw-r--r--doc/design/assistant/blog/day_114__xmpp/comment_4_e51d6f854db5f9e74a1aa58bd8923795._comment12
-rw-r--r--doc/design/assistant/blog/day_115__my_new_form.mdwn17
-rw-r--r--doc/design/assistant/blog/day_116__the_segfault.mdwn25
-rw-r--r--doc/design/assistant/blog/day_117__new_topologies.mdwn41
-rw-r--r--doc/design/assistant/blog/day_118__monadic_discontinuity.mdwn15
-rw-r--r--doc/design/assistant/blog/day_119__time_for_testing.mdwn12
-rw-r--r--doc/design/assistant/blog/day_11__freebsd.mdwn50
-rw-r--r--doc/design/assistant/blog/day_120__test_day.mdwn2
-rw-r--r--doc/design/assistant/blog/day_121__buddy_list.mdwn10
-rw-r--r--doc/design/assistant/blog/day_122__xmpp_pairing.mdwn29
-rw-r--r--doc/design/assistant/blog/day_122__xmpp_pairing/comment_1_e95efb23eb2e67e3f11a5c7de56424a7._comment10
-rw-r--r--doc/design/assistant/blog/day_122__xmpp_pairing/comment_2_30e251e73146512bde8b2f69eddeef2e._comment8
-rw-r--r--doc/design/assistant/blog/day_123__xmpp_insanity.mdwn49
-rw-r--r--doc/design/assistant/blog/day_124__git_push_over_xmpp_groundwork.mdwn28
-rw-r--r--doc/design/assistant/blog/day_125__xmpp_push_continues.mdwn15
-rw-r--r--doc/design/assistant/blog/day_126__mr_watson_come_here.mdwn52
-rw-r--r--doc/design/assistant/blog/day_126__mr_watson_come_here/comment_1_ee1361e6b235f4e1c00596ba516b519a._comment10
-rw-r--r--doc/design/assistant/blog/day_126__mr_watson_come_here/comment_2_8eb366ae7efb347bd3bbd9a98e0821b3._comment8
-rw-r--r--doc/design/assistant/blog/day_127__xmpp_syncs.mdwn35
-rw-r--r--doc/design/assistant/blog/day_128__last_xmpp_day.mdwn49
-rw-r--r--doc/design/assistant/blog/day_128__last_xmpp_day/comment_1_fd8c1d6358cb50f4dad8ba11d33d861f._comment10
-rw-r--r--doc/design/assistant/blog/day_128__last_xmpp_day/comment_2_43664b73c71c41d71bc95e665f128106._comment8
-rw-r--r--doc/design/assistant/blog/day_128__last_xmpp_day/comment_3_d369b04f686009a9dbb57b999107a55e._comment11
-rw-r--r--doc/design/assistant/blog/day_128__last_xmpp_day/comment_4_095855d301e7ccd3689ffe507cfb63ee._comment8
-rw-r--r--doc/design/assistant/blog/day_128__last_xmpp_day/comment_5_da7b0586b0b28e1e0fe4126f6543a7bc._comment9
-rw-r--r--doc/design/assistant/blog/day_128__last_xmpp_day/comment_6_2f9ba367e19d77bf52f372b6f0f5938a._comment8
-rw-r--r--doc/design/assistant/blog/day_129__release.mdwn4
-rw-r--r--doc/design/assistant/blog/day_12__freebsd_redux.mdwn23
-rw-r--r--doc/design/assistant/blog/day_12__freebsd_redux/comment_1_5da32cf53f1de27bfe6cec2d294db3e1._comment8
-rw-r--r--doc/design/assistant/blog/day_12__freebsd_redux/comment_2_696d6e22034acf5bb60d80124b72ef2f._comment8
-rw-r--r--doc/design/assistant/blog/day_130__what_now.mdwn36
-rw-r--r--doc/design/assistant/blog/day_130__what_now/comment_1_402f00cc034351d8253a797dd4de55bf._comment8
-rw-r--r--doc/design/assistant/blog/day_131__webdav_groundwork.mdwn28
-rw-r--r--doc/design/assistant/blog/day_132__webdav_continued.mdwn22
-rw-r--r--doc/design/assistant/blog/day_133__webdav_working.mdwn31
-rw-r--r--doc/design/assistant/blog/day_134__box.com_configurator.mdwn8
-rw-r--r--doc/design/assistant/blog/day_135__progress_revisited.mdwn37
-rw-r--r--doc/design/assistant/blog/day_136__misc.mdwn14
-rw-r--r--doc/design/assistant/blog/day_137__Glacier.mdwn30
-rw-r--r--doc/design/assistant/blog/day_138__back.mdwn25
-rw-r--r--doc/design/assistant/blog/day_138__back/comment_1_65a8499b284bed38d2bde1886a54a311._comment8
-rw-r--r--doc/design/assistant/blog/day_139__catch_up.mdwn11
-rw-r--r--doc/design/assistant/blog/day_13__kqueue_continued.mdwn34
-rw-r--r--doc/design/assistant/blog/day_140__release_monday.mdwn25
-rw-r--r--doc/design/assistant/blog/day_141__release_tuesday.mdwn6
-rw-r--r--doc/design/assistant/blog/day_141__release_tuesday/comment_1_a5adea7a726df12f9121c744a036f08d._comment10
-rw-r--r--doc/design/assistant/blog/day_142__filling_in.mdwn9
-rw-r--r--doc/design/assistant/blog/day_143__what_next.mdwn22
-rw-r--r--doc/design/assistant/blog/day_143__what_next/comment_1_40cf25a2ebdd43d8974a28e180e100e5._comment13
-rw-r--r--doc/design/assistant/blog/day_143__what_next/comment_2_af9ccbbc5131e6333c029415141bdb51._comment10
-rw-r--r--doc/design/assistant/blog/day_144__webapp_work.mdwn8
-rw-r--r--doc/design/assistant/blog/day_145__more_webapp_work.mdwn12
-rw-r--r--doc/design/assistant/blog/day_146__meanwhile.mdwn22
-rw-r--r--doc/design/assistant/blog/day_147__direct_mode.mdwn36
-rw-r--r--doc/design/assistant/blog/day_147__direct_mode/comment_1_0bd69532afce9dc04e3d88bfd0aed4b2._comment16
-rw-r--r--doc/design/assistant/blog/day_147__direct_mode/comment_2_3b26f0d081c3bf1037bb872d529ce825._comment8
-rw-r--r--doc/design/assistant/blog/day_148__direct_mode.mdwn42
-rw-r--r--doc/design/assistant/blog/day_149__rainy_day.mdwn15
-rw-r--r--doc/design/assistant/blog/day_14__kqueue_kqueue_kqueue.mdwn23
-rw-r--r--doc/design/assistant/blog/day_14__thinking_about_syncing.mdwn44
-rw-r--r--doc/design/assistant/blog/day_150__12:12.mdwn53
-rw-r--r--doc/design/assistant/blog/day_151__direct_mode_toggle.mdwn59
-rw-r--r--doc/design/assistant/blog/day_152__bugfixes.mdwn18
-rw-r--r--doc/design/assistant/blog/day_152__bugfixes/comment_1_46863a875f9daa6f2c9248b66ff91929._comment9
-rw-r--r--doc/design/assistant/blog/day_152__bugfixes/comment_2_a586e617bc024c8a9ff60f1b8345d74d._comment8
-rw-r--r--doc/design/assistant/blog/day_153__hibernation.mdwn26
-rw-r--r--doc/design/assistant/blog/day_154__direct_mode_merging.mdwn21
-rw-r--r--doc/design/assistant/blog/day_155__bugfixes.mdwn15
-rw-r--r--doc/design/assistant/blog/day_156_and_157__direct_mode_assistant.mdwn45
-rw-r--r--doc/design/assistant/blog/day_158__fsevents.mdwn20
-rw-r--r--doc/design/assistant/blog/day_158__fsevents/comment_1_b278372ac6399f64d5fa9da178278a6d._comment8
-rw-r--r--doc/design/assistant/blog/day_158__fsevents/comment_2_2d5ce9b2807068c3517e185945662bd2._comment8
-rw-r--r--doc/design/assistant/blog/day_159__fsevents_and_assistant.mdwn16
-rw-r--r--doc/design/assistant/blog/day_159__fsevents_and_assistant/comment_1_b85f446c3fa8d703a2a8882825c6f33f._comment8
-rw-r--r--doc/design/assistant/blog/day_159__fsevents_and_assistant/comment_2_a150b404e0c39e0bb2f7dd00cda63cdc._comment8
-rw-r--r--doc/design/assistant/blog/day_159__fsevents_and_assistant/comment_3_37abc41bae23a1d7de0d19d952aec492._comment8
-rw-r--r--doc/design/assistant/blog/day_15__its_aliiive.mdwn33
-rw-r--r--doc/design/assistant/blog/day_160__finishing_up_direct_mode.mdwn10
-rw-r--r--doc/design/assistant/blog/day_161__release_day.mdwn8
-rw-r--r--doc/design/assistant/blog/day_161__release_day/comment_1_e82c67f3ce216618149537bba1e0b850._comment19
-rw-r--r--doc/design/assistant/blog/day_161__release_day/comment_2_b1fe96fd818935c0497b78bb8ad32ffa._comment14
-rw-r--r--doc/design/assistant/blog/day_161__release_day/comment_3_40bac0e1756aa77bb966c4654857141c._comment44
-rw-r--r--doc/design/assistant/blog/day_161__release_day/comment_4_af65656b0d1179636937595868bb97b0._comment30
-rw-r--r--doc/design/assistant/blog/day_161__release_day/comment_5_0c05caaaf9588e124585041bf5f45d75._comment20
-rw-r--r--doc/design/assistant/blog/day_161__release_day/comment_6_5dfb5f428633d6062925f61af2b8829b._comment23
-rw-r--r--doc/design/assistant/blog/day_161__release_day/comment_7_ac4effb381b08d94d4a2d2482e92c89a._comment13
-rw-r--r--doc/design/assistant/blog/day_161__release_day/comment_8_32600e89e3098e52a1280895e03b3f86._comment13
-rw-r--r--doc/design/assistant/blog/day_161__release_day/comment_9_07e5d0c3cad0ce2bd4943e53b61f1767._comment8
-rw-r--r--doc/design/assistant/blog/day_162__UI.mdwn17
-rw-r--r--doc/design/assistant/blog/day_163__free_features.mdwn32
-rw-r--r--doc/design/assistant/blog/day_164__bugfixes.mdwn17
-rw-r--r--doc/design/assistant/blog/day_165__release_day.mdwn16
-rw-r--r--doc/design/assistant/blog/day_166__a_short_long_day.mdwn25
-rw-r--r--doc/design/assistant/blog/day_167__safe_direct_mode_transfers.mdwn12
-rw-r--r--doc/design/assistant/blog/day_167__safe_direct_mode_transfers/comment_1_f1aa64fe803d8c14b250a4e98b88142a._comment8
-rw-r--r--doc/design/assistant/blog/day_167__safe_direct_mode_transfers/comment_2_5ce1db84c9ead713f1272c4975645b93._comment8
-rw-r--r--doc/design/assistant/blog/day_168__back_to_theme.mdwn18
-rw-r--r--doc/design/assistant/blog/day_168__back_to_theme/comment_1_f248780bfcbd0384d9d72c2633a4ea46._comment12
-rw-r--r--doc/design/assistant/blog/day_168__back_to_theme/comment_2_5beba073373b8e75a32d1fcfdc1a0782._comment13
-rw-r--r--doc/design/assistant/blog/day_169__direct_mode_is_safe.mdwn24
-rw-r--r--doc/design/assistant/blog/day_169__direct_mode_is_safe/comment_1_65f87656c4e6bc7cdb614f53961341c9._comment8
-rw-r--r--doc/design/assistant/blog/day_169__direct_mode_is_safe/comment_2_a116a402a126c62be54c06afd82439ab._comment19
-rw-r--r--doc/design/assistant/blog/day_16__more_robust_syncing.mdwn44
-rw-r--r--doc/design/assistant/blog/day_16__more_robust_syncing/comment_1_23e7a90429e4431f90787cd016ebe188._comment8
-rw-r--r--doc/design/assistant/blog/day_16__more_robust_syncing/comment_2_8e7e7cd27791bb47625e60a284e9c802._comment10
-rw-r--r--doc/design/assistant/blog/day_170__bugfixes_and_release.mdwn8
-rw-r--r--doc/design/assistant/blog/day_171__logs.mdwn23
-rw-r--r--doc/design/assistant/blog/day_172__short_day.mdwn22
-rw-r--r--doc/design/assistant/blog/day_172__short_day/comment_1_b75e26b77a23a45da1c4c3bca1399246._comment12
-rw-r--r--doc/design/assistant/blog/day_173__snow_day.mdwn22
-rw-r--r--doc/design/assistant/blog/day_174__last_weekend_before_AU.mdwn25
-rw-r--r--doc/design/assistant/blog/day_174__last_weekend_before_AU/comment_1_05a8fd47f54373331741cc869a53b0c3._comment10
-rw-r--r--doc/design/assistant/blog/day_174__last_weekend_before_AU/comment_2_fc8e65eef954c4caa8321c2fe8b711b7._comment8
-rw-r--r--doc/design/assistant/blog/day_174__last_weekend_before_AU/comment_3_399534f540d85cac067fbb7be9d373b4._comment8
-rw-r--r--doc/design/assistant/blog/day_175__pacific_features.mdwn15
-rw-r--r--doc/design/assistant/blog/day_175__pacific_features/comment_1_c3ee4386f872b7c76aaecfa638b368cb._comment9
-rw-r--r--doc/design/assistant/blog/day_176__thread_management.mdwn13
-rw-r--r--doc/design/assistant/blog/day_178__bus_hacking.mdwn10
-rw-r--r--doc/design/assistant/blog/day_179__brief_updates.mdwn19
-rw-r--r--doc/design/assistant/blog/day_179__brief_updates/comment_1_920a84457d40358507a3eb817a4568d9._comment8
-rw-r--r--doc/design/assistant/blog/day_17__push_queue_prune.mdwn19
-rw-r--r--doc/design/assistant/blog/day_180__back.mdwn7
-rw-r--r--doc/design/assistant/blog/day_181__triage.mdwn23
-rw-r--r--doc/design/assistant/blog/day_182__it_begins.mdwn50
-rw-r--r--doc/design/assistant/blog/day_183__plan_b.mdwn19
-rw-r--r--doc/design/assistant/blog/day_184__just_wanna_run_something.mdwn46
-rw-r--r--doc/design/assistant/blog/day_184__just_wanna_run_something/comment_1_689adac7e26cb0b0a4e7ecc787cfd716._comment16
-rw-r--r--doc/design/assistant/blog/day_185__android_liftoff.mdwn20
-rw-r--r--doc/design/assistant/blog/day_185__android_liftoff/comment_1_b7d28010a72619a7e9a5ad4f2a0d6c07._comment9
-rw-r--r--doc/design/assistant/blog/day_185__android_liftoff/comment_2_ddeb24e86fafb7dae93142cc02767aad._comment10
-rw-r--r--doc/design/assistant/blog/day_186__Android_success.mdwn33
-rw-r--r--doc/design/assistant/blog/day_186__Android_success/comment_1_1629da240ca7db5f8a32059f561fd435._comment8
-rw-r--r--doc/design/assistant/blog/day_187__porting_utilities.mdwn22
-rw-r--r--doc/design/assistant/blog/day_187__porting_utilities/comment_1_0e6a3f4fe8e09f247fa04156bc60f8c7._comment8
-rw-r--r--doc/design/assistant/blog/day_188__crippled_filesystem_support.mdwn37
-rw-r--r--doc/design/assistant/blog/day_188__crippled_filesystem_support/comment_1_32a296fce23ae4b1e18bd5a9964bf619._comment14
-rw-r--r--doc/design/assistant/blog/day_189__more_crippling.mdwn44
-rw-r--r--doc/design/assistant/blog/day_18__merging.mdwn82
-rw-r--r--doc/design/assistant/blog/day_18__merging/comment_1_7a553ad559519f3b3e3cd20115b4c44e._comment15
-rw-r--r--doc/design/assistant/blog/day_190-191__weekend.mdwn28
-rw-r--r--doc/design/assistant/blog/day_190-191__weekend/comment_1_dbd692d12c14d08acd7d73a655b34e8b._comment10
-rw-r--r--doc/design/assistant/blog/day_190-191__weekend/comment_2_c813830e53471a9732e010a748d574fc._comment28
-rw-r--r--doc/design/assistant/blog/day_192_193__more_porting.mdwn44
-rw-r--r--doc/design/assistant/blog/day_194__nice_moment.mdwn37
-rw-r--r--doc/design/assistant/blog/day_195__real_android_app.mdwn32
-rw-r--r--doc/design/assistant/blog/day_195__real_android_app/comment_10_0112007552b30cd9bfeac614a1e399c4._comment10
-rw-r--r--doc/design/assistant/blog/day_195__real_android_app/comment_11_230d3c169c713f613b9d607d84ce5092._comment12
-rw-r--r--doc/design/assistant/blog/day_195__real_android_app/comment_12_8d74ad2a61c02272758d157282ad56ec._comment10
-rw-r--r--doc/design/assistant/blog/day_195__real_android_app/comment_13_4f6bc0680f2debd638933968a26975e0._comment10
-rw-r--r--doc/design/assistant/blog/day_195__real_android_app/comment_14_71539c62608866464e8faa76bc522a55._comment9
-rw-r--r--doc/design/assistant/blog/day_195__real_android_app/comment_15_e1b205289721ae79ac7fbed2f44018b2._comment10
-rw-r--r--doc/design/assistant/blog/day_195__real_android_app/comment_1_4bc0aeae4fa1116944644c64feaf9697._comment8
-rw-r--r--doc/design/assistant/blog/day_195__real_android_app/comment_2_17bb6e7565d4c757f6c1e3514c22f47d._comment10
-rw-r--r--doc/design/assistant/blog/day_195__real_android_app/comment_3_cd8a6bec0f7c6843dd11d3266f25f864._comment44
-rw-r--r--doc/design/assistant/blog/day_195__real_android_app/comment_4_2d2eee4bcbbd1d069a80bff5edc90c3c._comment13
-rw-r--r--doc/design/assistant/blog/day_195__real_android_app/comment_6_3d96568c469a8c53a982f304eae5e7d4._comment10
-rw-r--r--doc/design/assistant/blog/day_195__real_android_app/comment_6_e8667c47d07fc842cf0fe2ebbfbc1c58._comment8
-rw-r--r--doc/design/assistant/blog/day_195__real_android_app/comment_7_cf8da7720ddc20b05955ee671ca4acd5._comment8
-rw-r--r--doc/design/assistant/blog/day_195__real_android_app/comment_8_f4709bdbc739182819b648fd6aa00531._comment36
-rw-r--r--doc/design/assistant/blog/day_195__real_android_app/comment_9_e66af12c7eca0d457b8406e9fb4b69be._comment8
-rw-r--r--doc/design/assistant/blog/day_196__android_bugfixes.mdwn26
-rw-r--r--doc/design/assistant/blog/day_197__template_haskell.mdwn36
-rw-r--r--doc/design/assistant/blog/day_197__template_haskell/comment_1_82d9f9508929d84abf7b718c59436ae8._comment18
-rw-r--r--doc/design/assistant/blog/day_198__bugfixes.mdwn11
-rw-r--r--doc/design/assistant/blog/day_198__bugfixes/comment_1_5a15b5bad0f9ba2423d2aebe440ac0ea._comment19
-rw-r--r--doc/design/assistant/blog/day_198__bugfixes/comment_2_36d94b838e5e65c85e7afaabe8a578f1._comment12
-rw-r--r--doc/design/assistant/blog/day_198__bugfixes/comment_3_ae9b74341a3bc6e1e84d2c0ca4c5f612._comment10
-rw-r--r--doc/design/assistant/blog/day_198__bugfixes/comment_4_5a4827227c03bcff3b1e4c44b531f816._comment12
-rw-r--r--doc/design/assistant/blog/day_198__bugfixes/comment_5_9c5f4c85217e898be4c57c615e53c36f._comment8
-rw-r--r--doc/design/assistant/blog/day_198__bugfixes/comment_6_bccf1abfb7f56d97673158f3ccfce511._comment9
-rw-r--r--doc/design/assistant/blog/day_198__bugfixes/comment_7_6f1b51b002cc5d2b505d80e3e04bf6f3._comment8
-rw-r--r--doc/design/assistant/blog/day_198__bugfixes/comment_8_8a3542437663028b17442818eba3f7c5._comment9
-rw-r--r--doc/design/assistant/blog/day_199__wrapping_up_Android_for_now.mdwn26
-rw-r--r--doc/design/assistant/blog/day_199__wrapping_up_Android_for_now/comment_1_ec57358afc7e78d2860aa4237793832d._comment11
-rw-r--r--doc/design/assistant/blog/day_19__random_improvements.mdwn50
-rw-r--r--doc/design/assistant/blog/day_1__inotify.mdwn57
-rw-r--r--doc/design/assistant/blog/day_200__release_day.mdwn19
-rw-r--r--doc/design/assistant/blog/day_200__release_day/comment_10_40cfe9bfd9e611fd734dbb5aad348aa3._comment10
-rw-r--r--doc/design/assistant/blog/day_200__release_day/comment_11_b26890fdae575d42170988073fb2e45d._comment8
-rw-r--r--doc/design/assistant/blog/day_200__release_day/comment_13_710a30c5d31bf549833ecfe9a0997c94._comment8
-rw-r--r--doc/design/assistant/blog/day_200__release_day/comment_13_b6f62ab7e810ba6d3a43f0ead370c79a._comment8
-rw-r--r--doc/design/assistant/blog/day_200__release_day/comment_1_a68e1ed7829b49086c567d97ddc09912._comment8
-rw-r--r--doc/design/assistant/blog/day_200__release_day/comment_2_39d3ad0a029fe56e96f97d28d17fbbd2._comment8
-rw-r--r--doc/design/assistant/blog/day_200__release_day/comment_3_5b752d6a8d74e61190f09384b6108206._comment31
-rw-r--r--doc/design/assistant/blog/day_200__release_day/comment_4_881274ae0d6230bb4cafa4151ad72b49._comment12
-rw-r--r--doc/design/assistant/blog/day_200__release_day/comment_5_e220059be77cf0ef396f37a4f9ccf9b5._comment8
-rw-r--r--doc/design/assistant/blog/day_200__release_day/comment_6_ec2152151188dd252cdb61c68cfc12e4._comment10
-rw-r--r--doc/design/assistant/blog/day_200__release_day/comment_7_42572411617c287368482bb9dcf94324._comment18
-rw-r--r--doc/design/assistant/blog/day_200__release_day/comment_8_6b69aa81a9ba4e07e547ed1869946d51._comment15
-rw-r--r--doc/design/assistant/blog/day_200__release_day/comment_9_b070a2e4151d9fbf43d7906efa78515f._comment12
-rw-r--r--doc/design/assistant/blog/day_201__real_Android_wrapup.mdwn38
-rw-r--r--doc/design/assistant/blog/day_201__real_Android_wrapup/comment_1_88b9950c51324f0bb89c5646b3170952._comment19
-rw-r--r--doc/design/assistant/blog/day_201__real_Android_wrapup/fib.pngbin0 -> 69535 bytes
-rw-r--r--doc/design/assistant/blog/day_201__working_web_server.mdwn31
-rw-r--r--doc/design/assistant/blog/day_203__procrastination.mdwn25
-rw-r--r--doc/design/assistant/blog/day_204__deprocrastination.mdwn62
-rw-r--r--doc/design/assistant/blog/day_205_206__rainy_day__snow_day.mdwn12
-rw-r--r--doc/design/assistant/blog/day_207__XMPP.mdwn7
-rw-r--r--doc/design/assistant/blog/day_208__bugfixes.mdwn17
-rw-r--r--doc/design/assistant/blog/day_209__The_Bug.mdwn23
-rw-r--r--doc/design/assistant/blog/day_20__data_transfer_design.mdwn22
-rw-r--r--doc/design/assistant/blog/day_210__spring.mdwn29
-rw-r--r--doc/design/assistant/blog/day_211__zooming_along.mdwn24
-rw-r--r--doc/design/assistant/blog/day_212__accidental_all_nighter.mdwn24
-rw-r--r--doc/design/assistant/blog/day_212__accidental_all_nighter/comment_1_6ee1f8056eedb6eb18013faf8f5ec212._comment8
-rw-r--r--doc/design/assistant/blog/day_212__accidental_all_nighter/comment_2_07c83d75bb105bb77ada07359ed0ea7a._comment8
-rw-r--r--doc/design/assistant/blog/day_212__accidental_all_nighter/comment_3_2c904d33f4f14807fbe718a01e98800a._comment8
-rw-r--r--doc/design/assistant/blog/day_212__accidental_all_nighter/comment_4_59ec5c1cab75df87293800a7a03fe9c6._comment8
-rw-r--r--doc/design/assistant/blog/day_212__accidental_all_nighter/comment_5_13893f106e835dcc52e03c7c6740c35b._comment8
-rw-r--r--doc/design/assistant/blog/day_213__costs.mdwn34
-rw-r--r--doc/design/assistant/blog/day_214__release_day.mdwn5
-rw-r--r--doc/design/assistant/blog/day_215__dashboard_UI_refresh.mdwn25
-rw-r--r--doc/design/assistant/blog/day_216__more_bugfixes.mdwn42
-rw-r--r--doc/design/assistant/blog/day_216__more_bugfixes/comment_1_299462bcdd0e4f6cd7895b5f40ca00ad._comment10
-rw-r--r--doc/design/assistant/blog/day_216__more_bugfixes/comment_2_1913d65dfe4ba08379d82a4a2ca91c40._comment8
-rw-r--r--doc/design/assistant/blog/day_216__more_bugfixes/comment_3_92c774599a78540ad398afcd1d05f7ce._comment20
-rw-r--r--doc/design/assistant/blog/day_217__nothing.mdwn2
-rw-r--r--doc/design/assistant/blog/day_219__bug_triage.mdwn14
-rw-r--r--doc/design/assistant/blog/day_219__bug_triage/comment_1_c6b977a969cacdce62987a439b7686f5._comment16
-rw-r--r--doc/design/assistant/blog/day_21__transfer_tracking.mdwn28
-rw-r--r--doc/design/assistant/blog/day_220__performance.mdwn40
-rw-r--r--doc/design/assistant/blog/day_221__this_and_that.mdwn28
-rw-r--r--doc/design/assistant/blog/day_222__back.mdwn16
-rw-r--r--doc/design/assistant/blog/day_222__back/comment_1_f05b48231a1ee0cffba7d66e112e5551._comment8
-rw-r--r--doc/design/assistant/blog/day_222__back/comment_2_4d5f003ccd81580017ebf0dc31bc9cda._comment8
-rw-r--r--doc/design/assistant/blog/day_223__progress_revisited.mdwn24
-rw-r--r--doc/design/assistant/blog/day_224__annex.largefiles.mdwn23
-rw-r--r--doc/design/assistant/blog/day_224__annex.largefiles/comment_1_408e4021b18f7ff5548d2d19ab558922._comment8
-rw-r--r--doc/design/assistant/blog/day_224__annex.largefiles/comment_2_b24d1da2bc4307ded0216daffb8f9336._comment8
-rw-r--r--doc/design/assistant/blog/day_225__back_from_the_dead.mdwn47
-rw-r--r--doc/design/assistant/blog/day_225__back_from_the_dead/comment_1_9ac37c3b5c4c72ec8a39dce00bcbe420._comment8
-rw-r--r--doc/design/assistant/blog/day_225__back_from_the_dead/comment_2_26125dd9ef2bd10b597d14b2c6180952._comment8
-rw-r--r--doc/design/assistant/blog/day_226__poll_results.mdwn28
-rw-r--r--doc/design/assistant/blog/day_226__poll_results/comment_1_1ed980472214be6d0a8cf55f37797fda._comment8
-rw-r--r--doc/design/assistant/blog/day_226__poll_results/comment_2_6823b0a9a8037f1a5214db4db98fb16e._comment8
-rw-r--r--doc/design/assistant/blog/day_227__bigfixing_all_day_today.mdwn21
-rw-r--r--doc/design/assistant/blog/day_228__more_work_on_repository_removals.mdwn27
-rw-r--r--doc/design/assistant/blog/day_229__rainy_day_bugfixes.mdwn17
-rw-r--r--doc/design/assistant/blog/day_22__horrible_option_parsing_hack.mdwn34
-rw-r--r--doc/design/assistant/blog/day_230__Mom.mdwn35
-rw-r--r--doc/design/assistant/blog/day_230__Mom/comment_1_696bba2246c8a9e6ce4aed3071bcc96c._comment8
-rw-r--r--doc/design/assistant/blog/day_230__Mom/comment_2_2fa295ab6db0828cb725cfcfb6777822._comment8
-rw-r--r--doc/design/assistant/blog/day_230__Mom/comment_3_fafd7abec629290418334ddb015bf62c._comment10
-rw-r--r--doc/design/assistant/blog/day_230__Mom/comment_4_450cac0f2e82c94fd34b527ae05ef1b8._comment8
-rw-r--r--doc/design/assistant/blog/day_231__insert_title.mdwn26
-rw-r--r--doc/design/assistant/blog/day_232__headless_webapp.mdwn22
-rw-r--r--doc/design/assistant/blog/day_232__headless_webapp/comment_1_0fdd77d143ecba6fdb9f75cb6fc37bfb._comment16
-rw-r--r--doc/design/assistant/blog/day_232__headless_webapp/comment_2_0784a2a73c3e2945f3d3f2577b3b9c9c._comment8
-rw-r--r--doc/design/assistant/blog/day_232__headless_webapp/comment_3_ccb9fa22422fb913b6a496ebe65c49fb._comment8
-rw-r--r--doc/design/assistant/blog/day_232__headless_webapp/comment_4_ceba4468760a2525960327698431cee2._comment8
-rw-r--r--doc/design/assistant/blog/day_233__taxes.mdwn11
-rw-r--r--doc/design/assistant/blog/day_233__taxes/comment_1_9473ffdc42595af9c293fbcd5a1cdb54._comment14
-rw-r--r--doc/design/assistant/blog/day_233__taxes/comment_2_5feed8d7053ba03812ccda8c61fd9775._comment8
-rw-r--r--doc/design/assistant/blog/day_234__clean_shutdown.mdwn29
-rw-r--r--doc/design/assistant/blog/day_235__birthday.mdwn31
-rw-r--r--doc/design/assistant/blog/day_235__birthday/comment_1_db558b071067c1e63cde05cca0551094._comment8
-rw-r--r--doc/design/assistant/blog/day_235__birthday/comment_2_d1a2c1124781118267599457ae9e0512._comment8
-rw-r--r--doc/design/assistant/blog/day_235__birthday/comment_3_b853508d1d15234958b9f4a39277e45c._comment8
-rw-r--r--doc/design/assistant/blog/day_235__birthday/comment_5_73aad3398a43bc4d28bca9bf635fa757._comment8
-rw-r--r--doc/design/assistant/blog/day_236__evil_splicer.mdwn29
-rw-r--r--doc/design/assistant/blog/day_237__gnome-keyring_craziness.mdwn29
-rw-r--r--doc/design/assistant/blog/day_237__gnome-keyring_craziness/comment_1_0cb088b732881d1fa92493aa1fd93d43._comment8
-rw-r--r--doc/design/assistant/blog/day_237__gnome-keyring_craziness/comment_2_b855fd710954beebaafe6d2bd03eb368._comment8
-rw-r--r--doc/design/assistant/blog/day_238__back_to_Android.mdwn11
-rw-r--r--doc/design/assistant/blog/day_239__bugfixes_and_frustration.mdwn28
-rw-r--r--doc/design/assistant/blog/day_23__transfer_watching.mdwn25
-rw-r--r--doc/design/assistant/blog/day_240__it_builds.mdwn37
-rw-r--r--doc/design/assistant/blog/day_240__it_builds/comment_1_151840ae0020ea63b2f041488c905386._comment25
-rw-r--r--doc/design/assistant/blog/day_241__cleanup.mdwn14
-rw-r--r--doc/design/assistant/blog/day_241__cleanup/comment_1_0e283cdf66a25b3cc9423fe651084cb9._comment8
-rw-r--r--doc/design/assistant/blog/day_242__more_porting.mdwn4
-rw-r--r--doc/design/assistant/blog/day_243__in_the_field.mdwn21
-rw-r--r--doc/design/assistant/blog/day_244__android_porting.mdwn6
-rw-r--r--doc/design/assistant/blog/day_245__misc.mdwn15
-rw-r--r--doc/design/assistant/blog/day_245__misc/comment_1_3a2976617bb0cdc206fb1397a2ef1177._comment8
-rw-r--r--doc/design/assistant/blog/day_245__misc/comment_2_e0f9704e91fedca8ff26356f354cc1c3._comment10
-rw-r--r--doc/design/assistant/blog/day_245__misc/comment_3_93003a0d0983efbdc046d7459be194b0._comment8
-rw-r--r--doc/design/assistant/blog/day_246__bug_treadmill.mdwn18
-rw-r--r--doc/design/assistant/blog/day_246__bug_treadmill/comment_1_f76f653364fe2b97e85e8356c93b0fce._comment8
-rw-r--r--doc/design/assistant/blog/day_247__performance_tuning.mdwn16
-rw-r--r--doc/design/assistant/blog/day_248__Internet_Archive.mdwn28
-rw-r--r--doc/design/assistant/blog/day_249__quiet_day.mdwn7
-rw-r--r--doc/design/assistant/blog/day_24__airport_digressions.mdwn99
-rw-r--r--doc/design/assistant/blog/day_250__stymied.mdwn23
-rw-r--r--doc/design/assistant/blog/day_250__stymied/comment_1_330a10d447ccc3db03fcbfe571dbb404._comment8
-rw-r--r--doc/design/assistant/blog/day_251__xmpp_improvements.mdwn34
-rw-r--r--doc/design/assistant/blog/day_252__release_day.mdwn6
-rw-r--r--doc/design/assistant/blog/day_253__OMG.mdwn22
-rw-r--r--doc/design/assistant/blog/day_253__OMG/comment_1_bbdc61092771163e65a90a4755a807d8._comment8
-rw-r--r--doc/design/assistant/blog/day_254__Android_app_polishing.mdwn35
-rw-r--r--doc/design/assistant/blog/day_254__Android_app_polishing/comment_1_37f4ff5227566ce4b3fa69fc32568841._comment14
-rw-r--r--doc/design/assistant/blog/day_254__Android_app_polishing/comment_2_58bbb105bdbb72bba85c3622195f43b9._comment12
-rw-r--r--doc/design/assistant/blog/day_255__Debian_release_day.mdwn26
-rw-r--r--doc/design/assistant/blog/day_256__8bit.mdwn27
-rw-r--r--doc/design/assistant/blog/day_256__8bit/comment_1_f9b50263e3997d4c5b9836a2e0a346d7._comment8
-rw-r--r--doc/design/assistant/blog/day_257__rainy_day.mdwn6
-rw-r--r--doc/design/assistant/blog/day_258__beginning_of_the_end.mdwn24
-rw-r--r--doc/design/assistant/blog/day_259__Android_dominos_toppling.mdwn15
-rw-r--r--doc/design/assistant/blog/day_259__Android_dominos_toppling/comment_1_0b4a6e4893b0157e4768b46468dbbb87._comment10
-rw-r--r--doc/design/assistant/blog/day_259__Android_dominos_toppling/comment_2_1ebc5aff5d217e1392cb7c8bb6c5156b._comment14
-rw-r--r--doc/design/assistant/blog/day_259__Android_dominos_toppling/comment_3_eed7792f6142f3fc74d3c384bb16559b._comment8
-rw-r--r--doc/design/assistant/blog/day_25__transfer_queueing.mdwn41
-rw-r--r--doc/design/assistant/blog/day_25__transfer_queueing/comment_1_59fd4f1ffe96c412f613dc86276e7dbd._comment10
-rw-r--r--doc/design/assistant/blog/day_25__transfer_queueing/comment_2_93bf768a67117e873af5732ecf08dc78._comment7
-rw-r--r--doc/design/assistant/blog/day_260__Windows_dev_environment.mdwn46
-rw-r--r--doc/design/assistant/blog/day_261__Windows_first_stage_complete.mdwn29
-rw-r--r--doc/design/assistant/blog/day_262__DOS_path_separators.mdwn14
-rw-r--r--doc/design/assistant/blog/day_262__DOS_path_separators/comment_1_45ecae90b22e31202c21083980d6b567._comment10
-rw-r--r--doc/design/assistant/blog/day_263_catching_up.mdwn11
-rw-r--r--doc/design/assistant/blog/day_263_catching_up/comment_1_9023da0573dfc81644d68128adb331a7._comment8
-rw-r--r--doc/design/assistant/blog/day_264__Windows_second_stage_complete.mdwn21
-rw-r--r--doc/design/assistant/blog/day_264__Windows_second_stage_complete/comment_1_42a7502d6ece75520eb59a76fdb1e2f0._comment9
-rw-r--r--doc/design/assistant/blog/day_264__Windows_second_stage_complete/comment_2_f2b11322ac87e2a36cddc035b2c3c1ea._comment8
-rw-r--r--doc/design/assistant/blog/day_264__Windows_second_stage_complete/comment_3_ea6ee05acb946fc7e8d95e62647cfa2a._comment8
-rw-r--r--doc/design/assistant/blog/day_264__Windows_second_stage_complete/comment_4_9ce106baf28b7f75f7f6febd7bfcea70._comment8
-rw-r--r--doc/design/assistant/blog/day_265__correctness.mdwn23
-rw-r--r--doc/design/assistant/blog/day_265__correctness/comment_1_e8959a6df87eb92310947e66c7471e97._comment12
-rw-r--r--doc/design/assistant/blog/day_265__correctness/comment_2_0cb953fcc085eedb34e65c227309ede7._comment8
-rw-r--r--doc/design/assistant/blog/day_265__correctness/comment_3_df57628a8969af2995732e7ea2a0fae3._comment10
-rw-r--r--doc/design/assistant/blog/day_266__release_day.mdwn6
-rw-r--r--doc/design/assistant/blog/day_266__release_day/comment_1_92c8d1d9216b46b07dfe69bbc77a923e._comment8
-rw-r--r--doc/design/assistant/blog/day_267__windows_autobuilder.mdwn9
-rw-r--r--doc/design/assistant/blog/day_267__windows_autobuilder/comment_1_978b584d86395f2f621b0e1f7c5e70d7._comment21
-rw-r--r--doc/design/assistant/blog/day_267__windows_autobuilder/comment_2_8f978d2811c8fbf11e3d12f245bdb52b._comment10
-rw-r--r--doc/design/assistant/blog/day_268__core_monad_change.mdwn9
-rw-r--r--doc/design/assistant/blog/day_269__bugfixes.mdwn14
-rw-r--r--doc/design/assistant/blog/day_26__dying_drives.mdwn28
-rw-r--r--doc/design/assistant/blog/day_270__release_and_xmpp.mdwn39
-rw-r--r--doc/design/assistant/blog/day_271__more_xmpp.mdwn31
-rw-r--r--doc/design/assistant/blog/day_272__fuzz_tester.mdwn37
-rw-r--r--doc/design/assistant/blog/day_273-274__fun.mdwn19
-rw-r--r--doc/design/assistant/blog/day_275__working_hard_or.mdwn12
-rw-r--r--doc/design/assistant/blog/day_276__fuzzing_continues.mdwn12
-rw-r--r--doc/design/assistant/blog/day_276__fuzzing_continues/comment_1_f5dd0658511a1063c2eb025b0fe98426._comment14
-rw-r--r--doc/design/assistant/blog/day_276__fuzzing_continues/comment_2_a56c4c26a9e7bb8cfe3f598dbeed0813._comment10
-rw-r--r--doc/design/assistant/blog/day_277__private_static_protected_void.mdwn19
-rw-r--r--doc/design/assistant/blog/day_278__winding_down.mdwn11
-rw-r--r--doc/design/assistant/blog/day_279__final_release_prep.mdwn14
-rw-r--r--doc/design/assistant/blog/day_27__robust_transfers.mdwn31
-rw-r--r--doc/design/assistant/blog/day_28-35__threaded_runtime_tarpit.mdwn17
-rw-r--r--doc/design/assistant/blog/day_280__yesod.mdwn7
-rw-r--r--doc/design/assistant/blog/day_280__yesod/comment_1_a42213a8cef71f2b54db18606028136d._comment8
-rw-r--r--doc/design/assistant/blog/day_281__back.mdwn37
-rw-r--r--doc/design/assistant/blog/day_281__back/comment_1_128809c5a2a9f5cc345a10fdbf55be01._comment8
-rw-r--r--doc/design/assistant/blog/day_281__back/comment_2_6d0bbdf6ebaff9da399804570f0e606d._comment10
-rw-r--r--doc/design/assistant/blog/day_282-283__caught_up.mdwn18
-rw-r--r--doc/design/assistant/blog/day_284__porting.mdwn13
-rw-r--r--doc/design/assistant/blog/day_285__fixed_the_archive_directory_loop.mdwn23
-rw-r--r--doc/design/assistant/blog/day_285__fixed_the_archive_directory_loop/comment_1_1065e756dc6d66aefd214eb8ac5ebe1d._comment25
-rw-r--r--doc/design/assistant/blog/day_286__Windows_test_suite.mdwn19
-rw-r--r--doc/design/assistant/blog/day_287__niceness.mdwn13
-rw-r--r--doc/design/assistant/blog/day_288__success_stories.mdwn32
-rw-r--r--doc/design/assistant/blog/day_288__success_stories/comment_10_9ddf57b8ae0241268bb33bec1b169e4c._comment20
-rw-r--r--doc/design/assistant/blog/day_288__success_stories/comment_11_50b8a597bd8677608f2ef176443f23f3._comment10
-rw-r--r--doc/design/assistant/blog/day_288__success_stories/comment_12_f2df427cf3608377e9a52d8bdeadb26f._comment21
-rw-r--r--doc/design/assistant/blog/day_288__success_stories/comment_13_8762efed97f21eeba8f0a7be45bd924a._comment35
-rw-r--r--doc/design/assistant/blog/day_288__success_stories/comment_14_55e1bb15c3a93d582d110f8173ceefc2._comment9
-rw-r--r--doc/design/assistant/blog/day_288__success_stories/comment_15_5749aef8b585b293385b20b75c40f9d8._comment31
-rw-r--r--doc/design/assistant/blog/day_288__success_stories/comment_16_911c6d2764906cad7d6324835441ed34._comment12
-rw-r--r--doc/design/assistant/blog/day_288__success_stories/comment_17_eb6aa8af5aa70877255a11d132d51aba._comment10
-rw-r--r--doc/design/assistant/blog/day_288__success_stories/comment_18_9a57de4cea407a73b2d023d85afdccc6._comment12
-rw-r--r--doc/design/assistant/blog/day_288__success_stories/comment_19_1767c86067bee35941004282b96b8e95._comment10
-rw-r--r--doc/design/assistant/blog/day_288__success_stories/comment_1_22b28ca3d4d3283ad8c21ae052fb9752._comment11
-rw-r--r--doc/design/assistant/blog/day_288__success_stories/comment_20_1d47f3e1b9f0081649cedae4288bac83._comment8
-rw-r--r--doc/design/assistant/blog/day_288__success_stories/comment_21_31d3f58cad83cb1ecc4821a15ca258d8._comment14
-rw-r--r--doc/design/assistant/blog/day_288__success_stories/comment_22_b512bd2bf29dfaab6b36bf204518fdb6._comment8
-rw-r--r--doc/design/assistant/blog/day_288__success_stories/comment_2_343333356de20e170edb8020faa7400d._comment10
-rw-r--r--doc/design/assistant/blog/day_288__success_stories/comment_3_4e4034bec789543b562ac263df3e21dd._comment15
-rw-r--r--doc/design/assistant/blog/day_288__success_stories/comment_4_0c52794c77a9b7afc5112f5edf9cb793._comment8
-rw-r--r--doc/design/assistant/blog/day_288__success_stories/comment_5_7ca419aa3a187857b19268572d5df297._comment18
-rw-r--r--doc/design/assistant/blog/day_288__success_stories/comment_6_3edd56b3b04f19faba8d75cca285a662._comment10
-rw-r--r--doc/design/assistant/blog/day_288__success_stories/comment_7_146331ae2de25a6dc3595dffab9514de._comment12
-rw-r--r--doc/design/assistant/blog/day_288__success_stories/comment_8_72be9307e75eb120451f3d6ab7c8165e._comment8
-rw-r--r--doc/design/assistant/blog/day_288__success_stories/comment_9_c27eb0a4181e85a3eed41130402350bf._comment12
-rw-r--r--doc/design/assistant/blog/day_289__back_in_the_swing.mdwn16
-rw-r--r--doc/design/assistant/blog/day_290__https_release.mdwn17
-rw-r--r--doc/design/assistant/blog/day_291__--all.mdwn32
-rw-r--r--doc/design/assistant/blog/day_291__--all/comment_1_eaa9fef19a035bef9c439e87d47c834b._comment17
-rw-r--r--doc/design/assistant/blog/day_291__--all/comment_2_90bbc26bf92048de7cbaf5fb719c9593._comment11
-rw-r--r--doc/design/assistant/blog/day_291__--all/comment_3_75006e9909425dcbf86415a9f7c90372._comment10
-rw-r--r--doc/design/assistant/blog/day_291__--all/comment_4_5440449bbc5a353f7430f72e19c35e92._comment8
-rw-r--r--doc/design/assistant/blog/day_292__bugfixes.mdwn24
-rw-r--r--doc/design/assistant/blog/day_292__bugfixes/comment_1_bbac3878d80f7540d229183c56664784._comment8
-rw-r--r--doc/design/assistant/blog/day_292__bugfixes/comment_2_8c9e5291ceb257f3a938af0ad967c5d7._comment10
-rw-r--r--doc/design/assistant/blog/day_292__bugfixes/comment_3_02f875e8edd30f47939249f16d92712b._comment8
-rw-r--r--doc/design/assistant/blog/day_293__gpg_builds.mdwn32
-rw-r--r--doc/design/assistant/blog/day_293__gpg_builds/comment_1_4f152de8ea5aca4ec381d439e2a821f7._comment12
-rw-r--r--doc/design/assistant/blog/day_293__gpg_builds/comment_2_42f625638638bc875379f6c604d6f673._comment8
-rw-r--r--doc/design/assistant/blog/day_294__release_day.mdwn7
-rw-r--r--doc/design/assistant/blog/day_295__balls_in_the_air.mdwn13
-rw-r--r--doc/design/assistant/blog/day_296__new_crowdfunding_campaign.mdwn41
-rw-r--r--doc/design/assistant/blog/day_296__new_crowdfunding_campaign/comment_1_cccad1a5103c504d21d0f8e69bb39e1b._comment8
-rw-r--r--doc/design/assistant/blog/day_296__new_crowdfunding_campaign/comment_2_4fef7bd9c8e15cd57df365fadb95717f._comment8
-rw-r--r--doc/design/assistant/blog/day_296__new_crowdfunding_campaign/comment_3_0b9258a1f5079e53c60138f06d0c63b1._comment8
-rw-r--r--doc/design/assistant/blog/day_296__new_crowdfunding_campaign/comment_4_46183b97ca904bc06e46569c30db2edc._comment8
-rw-r--r--doc/design/assistant/blog/day_297__back_to_work.mdwn16
-rw-r--r--doc/design/assistant/blog/day_297__back_to_work/comment_1_e300feb821bfe7b76b2cec4376d16ffa._comment8
-rw-r--r--doc/design/assistant/blog/day_298__exceptional.mdwn21
-rw-r--r--doc/design/assistant/blog/day_299__bugfixing.mdwn8
-rw-r--r--doc/design/assistant/blog/day_2__races.mdwn45
-rw-r--r--doc/design/assistant/blog/day_300__new_logo.mdwn36
-rw-r--r--doc/design/assistant/blog/day_300__new_logo/comment_1_9fc64e33863b9fce00f6a03417a91e36._comment9
-rw-r--r--doc/design/assistant/blog/day_300__new_logo/comment_2_e8aac0298f90004e81492d2c7f85eda0._comment8
-rw-r--r--doc/design/assistant/blog/day_300__new_logo/comment_3_6308c767f6e4bf090102191c91520d04._comment8
-rw-r--r--doc/design/assistant/blog/day_301__direct_unannex.mdwn21
-rw-r--r--doc/design/assistant/blog/day_302_release_day.mdwn6
-rw-r--r--doc/design/assistant/blog/day_302_release_day/comment_1_fe6e572ba706e95188463d9f3e004d03._comment17
-rw-r--r--doc/design/assistant/blog/day_303__oops.mdwn8
-rw-r--r--doc/design/assistant/blog/day_304__dropunused_safety.mdwn28
-rw-r--r--doc/design/assistant/blog/day_304__dropunused_safety/comment_1_1bbcf6c74b6437c44ff8604401fb1432._comment10
-rw-r--r--doc/design/assistant/blog/day_305__interesting_bugs.mdwn21
-rw-r--r--doc/design/assistant/blog/day_306__offtopic.mdwn2
-rw-r--r--doc/design/assistant/blog/day_307__buuuugs.mdwn31
-rw-r--r--doc/design/assistant/blog/day_308__ssh-agent.mdwn16
-rw-r--r--doc/design/assistant/blog/day_308__ssh-agent/comment_1_5f0fc810cf1e1cd9b3ddba3cd19bb19d._comment12
-rw-r--r--doc/design/assistant/blog/day_309__filenames.mdwn17
-rw-r--r--doc/design/assistant/blog/day_310__release_day.mdwn18
-rw-r--r--doc/design/assistant/blog/day_310__release_day/comment_1_1e008583cebd8e373e83729529914db7._comment8
-rw-r--r--doc/design/assistant/blog/day_311__Windows_porting.mdwn10
-rw-r--r--doc/design/assistant/blog/day_311__Windows_porting/comment_1_8e738f54a72557bee1e19970472b925c._comment8
-rw-r--r--doc/design/assistant/blog/day_312__DebConf_midpoint.mdwn30
-rw-r--r--doc/design/assistant/blog/day_313__back.mdwn34
-rw-r--r--doc/design/assistant/blog/day_313__back/comment_1_fbf3fdf9688c18156753d446facd942d._comment10
-rw-r--r--doc/design/assistant/blog/day_314__quvi.mdwn27
-rw-r--r--doc/design/assistant/blog/day_314__quvi/comment_1_3fdfb0742cb5422530ddd97b904f2a42._comment8
-rw-r--r--doc/design/assistant/blog/day_315__backlog.mdwn12
-rw-r--r--doc/design/assistant/blog/day_316__day_off.mdwn6
-rw-r--r--doc/design/assistant/blog/day_317__misc.mdwn17
-rw-r--r--doc/design/assistant/blog/day_36__minimal_test_case.mdwn9
-rw-r--r--doc/design/assistant/blog/day_37__back.mdwn64
-rw-r--r--doc/design/assistant/blog/day_39__twice_is_enemy_action.mdwn66
-rw-r--r--doc/design/assistant/blog/day_3__more_races.mdwn26
-rw-r--r--doc/design/assistant/blog/day_3__more_races/comment_1_d6015338f602b574a3805de5481fc45e._comment8
-rw-r--r--doc/design/assistant/blog/day_3__more_races/comment_2_4d6b23fc6442e0ee0303523cb69d0fba._comment8
-rw-r--r--doc/design/assistant/blog/day_3__more_races/comment_3_03f5b2344c2a47dea60086f217d60f9b._comment14
-rw-r--r--doc/design/assistant/blog/day_3__more_races/comment_4_860e90e989ec022100001c65e353a91e._comment8
-rw-r--r--doc/design/assistant/blog/day_40__dbus.mdwn100
-rw-r--r--doc/design/assistant/blog/day_40__dbus/comment_1_43ed2a79629868b018ec9f54a32bcacc._comment12
-rw-r--r--doc/design/assistant/blog/day_40__dbus/comment_2_6799f2baf6a6ce14b1fa76a8402840c0._comment10
-rw-r--r--doc/design/assistant/blog/day_40__dbus/comment_3_fa1d7444bdafcb990cacf2ace7ee6ef1._comment10
-rw-r--r--doc/design/assistant/blog/day_40__dbus/comment_4_3399ddad951c1a950281bb6941fc3f6f._comment8
-rw-r--r--doc/design/assistant/blog/day_40__dbus/comment_5_40b6b9d741d3081203f0cc94eb8dc3ea._comment12
-rw-r--r--doc/design/assistant/blog/day_41__foo.mdwn46
-rw-r--r--doc/design/assistant/blog/day_41__foo/comment_1_ace21fa257a4c2fd412b6ff2944a23e8._comment10
-rw-r--r--doc/design/assistant/blog/day_42__the_answer.mdwn27
-rw-r--r--doc/design/assistant/blog/day_43__simple_scanner.mdwn37
-rw-r--r--doc/design/assistant/blog/day_44__webapp_basics.mdwn83
-rw-r--r--doc/design/assistant/blog/day_44__webapp_basics/comment_1_d5fb67f373038e9f583cb2e1992bef67._comment18
-rw-r--r--doc/design/assistant/blog/day_45__long_polling.mdwn66
-rw-r--r--doc/design/assistant/blog/day_45__long_polling/comment_1_994bec0978324e268666073e8ff4f6ae._comment8
-rw-r--r--doc/design/assistant/blog/day_45__long_polling/comment_2_dfa164c86290899139491acccddd8b2b._comment10
-rw-r--r--doc/design/assistant/blog/day_45__long_polling/full.pngbin0 -> 55185 bytes
-rw-r--r--doc/design/assistant/blog/day_45__long_polling/phone.pngbin0 -> 41602 bytes
-rw-r--r--doc/design/assistant/blog/day_46__notification_pools.mdwn68
-rw-r--r--doc/design/assistant/blog/day_47__alert_messages.mdwn14
-rw-r--r--doc/design/assistant/blog/day_48__intro.mdwn8
-rw-r--r--doc/design/assistant/blog/day_49__first_run_experience.mdwn39
-rw-r--r--doc/design/assistant/blog/day_49__first_run_experience/comment_1_e146cf06c8dd6303dd6a991f152a73fe._comment8
-rw-r--r--doc/design/assistant/blog/day_49__first_run_experience/comment_2_5d6adcf6782c02283bef6189582ee467._comment12
-rw-r--r--doc/design/assistant/blog/day_49__first_run_experience/comment_3_7ac2e34c2a7bc9b57488ca0c91307d32._comment14
-rw-r--r--doc/design/assistant/blog/day_49__first_run_experience/comment_4_549b07bb02c07a5b1b95445b01758db2._comment14
-rw-r--r--doc/design/assistant/blog/day_4__speed.mdwn47
-rw-r--r--doc/design/assistant/blog/day_4__speed/comment_1_bf3c9c33cc0dea5eaeb6f2af110b924b._comment8
-rw-r--r--doc/design/assistant/blog/day_4__speed/comment_2_33aba4c9abaa3e6a05a2c87ab7df9d0e._comment8
-rw-r--r--doc/design/assistant/blog/day_50__directory_name.mdwn20
-rw-r--r--doc/design/assistant/blog/day_50__directory_name/comment_1_782cec95a8558a05b2b38a2d2302214d._comment8
-rw-r--r--doc/design/assistant/blog/day_50__directory_name/comment_2_2b8ceb0a26f25e8ed2711bcbe7225a58._comment8
-rw-r--r--doc/design/assistant/blog/day_51__desktop.mdwn34
-rw-r--r--doc/design/assistant/blog/day_52__file_browser.mdwn21
-rw-r--r--doc/design/assistant/blog/day_52__file_browser/comment_1_cd000c2d56b60cc1f17b221322a32aa7._comment8
-rw-r--r--doc/design/assistant/blog/day_52__file_browser/comment_2_21d1da67cf9105a545583ba2302c10fb._comment7
-rw-r--r--doc/design/assistant/blog/day_54__adding_removable_drives.mdwn99
-rw-r--r--doc/design/assistant/blog/day_54__adding_removable_drives/comment_1_5de4f220a3534f55b1f2208d1d812d63._comment10
-rw-r--r--doc/design/assistant/blog/day_54__adding_removable_drives/comment_2_8dae1ed0a70acf9628b88692dc32ac5f._comment10
-rw-r--r--doc/design/assistant/blog/day_55__alerts.mdwn10
-rw-r--r--doc/design/assistant/blog/day_55__alerts/comment_1_6319045500a8a5e049304fdec5ff4cf4._comment8
-rw-r--r--doc/design/assistant/blog/day_56__transfer_control.mdwn8
-rw-r--r--doc/design/assistant/blog/day_57__afk.mdwn40
-rw-r--r--doc/design/assistant/blog/day_57__afk/comment_1_70e1c9f925f040c1700d3e26bab373d5._comment9
-rw-r--r--doc/design/assistant/blog/day_57__afk/comment_2_c70d3faccfcebf47deb25e270498cb56._comment18
-rw-r--r--doc/design/assistant/blog/day_57__afk/comment_3_89020ebc6d31485339bdea41a872df3c._comment11
-rw-r--r--doc/design/assistant/blog/day_57__afk/comment_4_8b1f65f141ffd9813e7f5a3380f7f520._comment27
-rw-r--r--doc/design/assistant/blog/day_58__more_transfer_control.mdwn26
-rw-r--r--doc/design/assistant/blog/day_59__dinner.mdwn10
-rw-r--r--doc/design/assistant/blog/day_59__dinner/comment_1_0c1e2d69496473e7e4a2956a2814f5dd._comment9
-rw-r--r--doc/design/assistant/blog/day_5__committing.mdwn57
-rw-r--r--doc/design/assistant/blog/day_60__taking_stock.mdwn40
-rw-r--r--doc/design/assistant/blog/day_60__taking_stock/comment_1_6722f81ee084f1ea9e8fe47f34576397._comment8
-rw-r--r--doc/design/assistant/blog/day_61__network_connection_detection.mdwn36
-rw-r--r--doc/design/assistant/blog/day_61__network_connection_detection/comment_1_09b58f41a8d48f218619711ee19511ac._comment8
-rw-r--r--doc/design/assistant/blog/day_62__smarter_syncing.mdwn21
-rw-r--r--doc/design/assistant/blog/day_63__transfer_retries.mdwn26
-rw-r--r--doc/design/assistant/blog/day_63__transfer_retries/comment_1_990d4eb6066c4e2b9ddb3cabef32e4b9._comment10
-rw-r--r--doc/design/assistant/blog/day_64__syncing_robustly.mdwn33
-rw-r--r--doc/design/assistant/blog/day_65__transfer_polish.mdwn33
-rw-r--r--doc/design/assistant/blog/day_66__the_merge.mdwn19
-rw-r--r--doc/design/assistant/blog/day_66__the_merge/comment_10_eeccf4e73cc321542a1fe4780805a81e._comment12
-rw-r--r--doc/design/assistant/blog/day_66__the_merge/comment_1_a34e89316d1662826848f31061c4e46b._comment8
-rw-r--r--doc/design/assistant/blog/day_66__the_merge/comment_2_09e244d23d05052fa2b11a7181888366._comment8
-rw-r--r--doc/design/assistant/blog/day_66__the_merge/comment_3_3961a03e167903959b96b054835613f6._comment8
-rw-r--r--doc/design/assistant/blog/day_66__the_merge/comment_4_12a57af9f580918818b4a9f68396d5c4._comment23
-rw-r--r--doc/design/assistant/blog/day_66__the_merge/comment_5_8ce638960012367c888e018a5f05db19._comment8
-rw-r--r--doc/design/assistant/blog/day_66__the_merge/comment_6_f461b856b940e6914bcd2b681cf9505f._comment13
-rw-r--r--doc/design/assistant/blog/day_66__the_merge/comment_7_6e73aca1fc1747d0e742e054b88b5d78._comment12
-rw-r--r--doc/design/assistant/blog/day_66__the_merge/comment_8_d85f1ce23ae16d5a8eb88d2c3999acb7._comment19
-rw-r--r--doc/design/assistant/blog/day_66__the_merge/comment_9_c06dab4d78122c85beeaf300ffc3e376._comment8
-rw-r--r--doc/design/assistant/blog/day_67__progress_bars.mdwn10
-rw-r--r--doc/design/assistant/blog/day_68__transfers.mdwn15
-rw-r--r--doc/design/assistant/blog/day_68__transfers/comment_1_5282960c0b553fbc0f411345b9745324._comment14
-rw-r--r--doc/design/assistant/blog/day_69__build_fixes.mdwn7
-rw-r--r--doc/design/assistant/blog/day_6__polish.mdwn50
-rw-r--r--doc/design/assistant/blog/day_70__adding_ssh_remotes.mdwn66
-rw-r--r--doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_10_2fac85357ac8feccff82beabd3791439._comment13
-rw-r--r--doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_11_e9e496005fd1bf5a10c9e286b83e51fa._comment8
-rw-r--r--doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_1_913e6ae7c8f7db90b9767ec35fc84205._comment23
-rw-r--r--doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_2_634ca3c236e2062289e7df5f0d77a3c5._comment8
-rw-r--r--doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_3_e365bbcbb7f66ce2b35fcd5b969ab315._comment16
-rw-r--r--doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_4_b15499722a655489f9ea60ff9d4c47c6._comment12
-rw-r--r--doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_5_8ea48276f060e75d9f40617d2a1ccd08._comment12
-rw-r--r--doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_6_9b8bf7e9fa715977fbeb98087deefd1a._comment10
-rw-r--r--doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_7_42e09eacdc10c7cf579bfc6470b5117c._comment8
-rw-r--r--doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_8_6c02f31063b3d399d1b4f823bd6543ce._comment16
-rw-r--r--doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_9_dd0447cb3b39d3a8c1a7cc00f17d8bc2._comment10
-rw-r--r--doc/design/assistant/blog/day_71__ssh_probing.mdwn26
-rw-r--r--doc/design/assistant/blog/day_71__ssh_probing/comment_1_56a0c29f7454cfca5cc30b2849e6e942._comment8
-rw-r--r--doc/design/assistant/blog/day_71__ssh_probing/comment_2_f3bd3e366c92c833c7e217da125481b8._comment8
-rw-r--r--doc/design/assistant/blog/day_72__remote_ssh_server_configurator_finished.mdwn34
-rw-r--r--doc/design/assistant/blog/day_73__rsync.net_configurator.mdwn17
-rw-r--r--doc/design/assistant/blog/day_74__bits_and_peices.mdwn7
-rw-r--r--doc/design/assistant/blog/day_75__zeromq_and_pairing.mdwn50
-rw-r--r--doc/design/assistant/blog/day_76__pairing.mdwn16
-rw-r--r--doc/design/assistant/blog/day_76__pairing/comment_1_09665f269343422cd18051fad1a8c19e._comment24
-rw-r--r--doc/design/assistant/blog/day_76__pairing/comment_2_8e1b2233579bc26bfd758bbf6b3bdc07._comment10
-rw-r--r--doc/design/assistant/blog/day_76__pairing/comment_3_a8b6a8432da20c468c633da8e7cbc2f3._comment8
-rw-r--r--doc/design/assistant/blog/day_76__pairing/comment_4_36a428a2e1803f4391b821d1892f0cd7._comment10
-rw-r--r--doc/design/assistant/blog/day_76__pairing/comment_5_11f332fe2050d8c1416e71f9e85ba280._comment8
-rw-r--r--doc/design/assistant/blog/day_76__pairing/comment_6_973aeb656b78eca97474ea1a3f5b57b7._comment12
-rw-r--r--doc/design/assistant/blog/day_76__pairing/comment_7_03d2b3343f34377a4d6171e06b7609f6._comment8
-rw-r--r--doc/design/assistant/blog/day_77_alert_buttons.mdwn21
-rw-r--r--doc/design/assistant/blog/day_78__pairing_continued.mdwn8
-rw-r--r--doc/design/assistant/blog/day_79__pairing_finished.mdwn33
-rw-r--r--doc/design/assistant/blog/day_7__bugfixes.mdwn45
-rw-r--r--doc/design/assistant/blog/day_7__bugfixes/profile.pngbin0 -> 47098 bytes
-rw-r--r--doc/design/assistant/blog/day_7__bugfixes/profile2.pngbin0 -> 230937 bytes
-rw-r--r--doc/design/assistant/blog/day_80__default_backend.mdwn14
-rw-r--r--doc/design/assistant/blog/day_81__enabling_pre-existing_special_remotes.mdwn34
-rw-r--r--doc/design/assistant/blog/day_82__git-annex_branch_work.mdwn26
-rw-r--r--doc/design/assistant/blog/day_83__3-way.mdwn73
-rw-r--r--doc/design/assistant/blog/day_84__deferred_downloads.mdwn33
-rw-r--r--doc/design/assistant/blog/day_85__more_foundation_work.mdwn17
-rw-r--r--doc/design/assistant/blog/day_86__towards_the_beta.mdwn33
-rw-r--r--doc/design/assistant/blog/day_87__more_progress_progress.mdwn28
-rw-r--r--doc/design/assistant/blog/day_88__progressbars_still_progressing.mdwn18
-rw-r--r--doc/design/assistant/blog/day_89__final_polish.mdwn24
-rw-r--r--doc/design/assistant/blog/day_8__speed.mdwn67
-rw-r--r--doc/design/assistant/blog/day_8__speed/comment_1_a3dba537b276d5737abc8cb93f1965f4._comment10
-rw-r--r--doc/design/assistant/blog/day_90__beta.mdwn16
-rw-r--r--doc/design/assistant/blog/day_90__beta/comment_1_5f2a3b18ad7558abe04f51534a29ff13._comment9
-rw-r--r--doc/design/assistant/blog/day_90__beta/comment_2_961c4eba97f4eac75174244d6b2b00c0._comment8
-rw-r--r--doc/design/assistant/blog/day_90__beta/comment_3_c76675a4633cbbe347ed42c222918d38._comment24
-rw-r--r--doc/design/assistant/blog/day_90__beta/comment_4_f0b8f77cb691e747fe35bcf2f51b5baa._comment8
-rw-r--r--doc/design/assistant/blog/day_90__beta/comment_5_99fbc9feac62e66a12b0d357cf86ccc1._comment8
-rw-r--r--doc/design/assistant/blog/day_91__break.mdwn7
-rw-r--r--doc/design/assistant/blog/day_92__S3.mdwn23
-rw-r--r--doc/design/assistant/blog/day_92__S3/comment_1_eda656247d11cea7fbed2e33137a39e5._comment10
-rw-r--r--doc/design/assistant/blog/day_92__S3/comment_2_8249d2d9521e44c674da3fda74be077a._comment10
-rw-r--r--doc/design/assistant/blog/day_93__OSX_standalone_app.mdwn23
-rw-r--r--doc/design/assistant/blog/day_93__easy_install.mdwn34
-rw-r--r--doc/design/assistant/blog/day_93__easy_install/comment_1_d4f7de723c98577ef28d89ee6b87fd13._comment10
-rw-r--r--doc/design/assistant/blog/day_93__easy_install/comment_2_6337b341c1cfb2132b59704394e57b36._comment8
-rw-r--r--doc/design/assistant/blog/day_95__repository_groups.mdwn21
-rw-r--r--doc/design/assistant/blog/day_96__revisiting_file_adds.mdwn24
-rw-r--r--doc/design/assistant/blog/day_96__revisiting_file_adds/comment_1_da3ca47041168b6c82aeb2c18acc5017._comment8
-rw-r--r--doc/design/assistant/blog/day_97__stuffing.mdwn14
-rw-r--r--doc/design/assistant/blog/day_98__preferred_content.mdwn44
-rw-r--r--doc/design/assistant/blog/day_98__preferred_content/comment_1_2136618e3515d0ac6369a41f1934ec2a._comment17
-rw-r--r--doc/design/assistant/blog/day_98__preferred_content/comment_2_5f6db00e69628bf2f72b0e6f2981a49b._comment14
-rw-r--r--doc/design/assistant/blog/day_99_shotgun.mdwn70
-rw-r--r--doc/design/assistant/blog/day_99_shotgun/comment_1_12bb8f54bb13ea20ac4187a2301d77ca._comment10
-rw-r--r--doc/design/assistant/blog/day_9__correctness.mdwn30
-rw-r--r--doc/design/assistant/blog/day_9__correctness/comment_1_564a39cb976767e2c0a9c74fabe10be4._comment8
-rw-r--r--doc/design/assistant/blog/day_9__correctness/comment_2_77924e9d50b40f05e792e427a25849a6._comment9
-rw-r--r--doc/design/assistant/blog/day_9__correctness/comment_3_92bd86cd06d579e23800af2e5c66a291._comment8
-rw-r--r--doc/design/assistant/blog/day_9__correctness/comment_4_0d12b51ccdfc2a94d3e59a5628521e0a._comment10
-rw-r--r--doc/design/assistant/blog/day_9__correctness/comment_5_208f9dd3e1d92555b05c29159538a901._comment14
-rw-r--r--doc/design/assistant/blog/day_9__correctness/comment_6_90cc6b60718896fb175919417600fdf9._comment8
-rw-r--r--doc/design/assistant/chunks.mdwn7
-rw-r--r--doc/design/assistant/cloud.mdwn45
-rw-r--r--doc/design/assistant/cloud/comment_1_4997778abc171999499487b71b31c9ba._comment16
-rw-r--r--doc/design/assistant/cloud/comment_2_08da8bc74a4845e354dca99184cffd70._comment8
-rw-r--r--doc/design/assistant/cloud/comment_3_faafd1266301997b1822d215ec8e8d8c._comment8
-rw-r--r--doc/design/assistant/cloud/comment_4_3eb557d5439831f6e0032944d12c02cf._comment12
-rw-r--r--doc/design/assistant/comment_10_f2233fad55c20686cf299bf6788f1f23._comment10
-rw-r--r--doc/design/assistant/comment_11_a38f0f21c2346e65b786d791b6829f9b._comment12
-rw-r--r--doc/design/assistant/comment_12_5e991177d6577384f39a36ae02f5f574._comment13
-rw-r--r--doc/design/assistant/comment_13_f8625c6f43b58847840df338a73b7972._comment7
-rw-r--r--doc/design/assistant/comment_14_c37ef5931b0f5c1f808083e0d636a208._comment11
-rw-r--r--doc/design/assistant/comment_15_68c98a27083567f20c2e6bc2a760991b._comment9
-rw-r--r--doc/design/assistant/comment_16_8e6788c817c60371d2a2f158e1a65f87._comment8
-rw-r--r--doc/design/assistant/comment_17_97bdfacac5ac492281c9454ee4c0228e._comment8
-rw-r--r--doc/design/assistant/comment_18_53137b2df4913496c0afb2d895aa4ee2._comment8
-rw-r--r--doc/design/assistant/comment_19_ff1b0ba57e22ed757ec3fc5400b5e43e._comment8
-rw-r--r--doc/design/assistant/comment_1_a48fcfbf97f0a373ea375cd8f07f0fc8._comment8
-rw-r--r--doc/design/assistant/comment_20_099da245e3276fa84f5e14312d186621._comment8
-rw-r--r--doc/design/assistant/comment_2_6d3552414fdcc2ed3244567e6c67989d._comment7
-rw-r--r--doc/design/assistant/comment_3_05223be50c889b2ed6bc4abf74116450._comment9
-rw-r--r--doc/design/assistant/comment_4_fbbd93b55803ae21e6ba4b6568c2fafd._comment9
-rw-r--r--doc/design/assistant/comment_5_f4e9af3fed6c27e8ff39badb9794064d._comment12
-rw-r--r--doc/design/assistant/comment_6_c7ad07cade1f44f9a8b61f92225bb9c5._comment10
-rw-r--r--doc/design/assistant/comment_7_609d38e993267195a80fecd84c93d1e2._comment8
-rw-r--r--doc/design/assistant/comment_8_22b818e1a2a825efb78139271a14f944._comment10
-rw-r--r--doc/design/assistant/comment_9_d052e2142da8b4838fb1edf791ea23ae._comment10
-rw-r--r--doc/design/assistant/configurators.mdwn20
-rw-r--r--doc/design/assistant/deltas.mdwn9
-rw-r--r--doc/design/assistant/deltas/comment_1_bdb477af913c9782c0e8509e6b294b6e._comment8
-rw-r--r--doc/design/assistant/deltas/comment_2_71889d15ba20ebb0fe13080c68162a5b._comment11
-rw-r--r--doc/design/assistant/desymlink.mdwn145
-rw-r--r--doc/design/assistant/desymlink/comment_1_f1bfe250b7f872359f7075998b6e42e3._comment11
-rw-r--r--doc/design/assistant/desymlink/comment_2_5e876edfe9853645f761b5ed9b5021aa._comment9
-rw-r--r--doc/design/assistant/desymlink/comment_3_538561d74371e53c2f8df7f5ebdf58a8._comment8
-rw-r--r--doc/design/assistant/desymlink/comment_4_586ecaa800e6c162377c937da5e65440._comment12
-rw-r--r--doc/design/assistant/desymlink/comment_5_8fc703de67814cf2aec2a908852298a4._comment10
-rw-r--r--doc/design/assistant/desymlink/comment_6_1b473ad89494afb82250af4b6df5f5c9._comment22
-rw-r--r--doc/design/assistant/disaster_recovery.mdwn185
-rw-r--r--doc/design/assistant/disaster_recovery/comment_1_955dc807196863da23aa8dbd15e04364._comment10
-rw-r--r--doc/design/assistant/encrypted_git_remotes.mdwn22
-rw-r--r--doc/design/assistant/gpgkeys.mdwn37
-rw-r--r--doc/design/assistant/inotify.mdwn196
-rw-r--r--doc/design/assistant/inotify/comment_1_3d3ff74447452d65c10ccc3dbfc323cd._comment7
-rw-r--r--doc/design/assistant/inotify/comment_2_a3c0fa6d97397c508b4b8aafdcee8f6f._comment7
-rw-r--r--doc/design/assistant/inotify/comment_3_b346e870c1cd80e4b0a313c3a9fed6b3._comment8
-rw-r--r--doc/design/assistant/inotify/comment_4_32be58b4c3b17a4ea539690d2fb45159._comment12
-rw-r--r--doc/design/assistant/inotify/comment_5_0cdd3046d90ad2012025d846ece0731e._comment8
-rw-r--r--doc/design/assistant/inotify/comment_6_e197d5d0d853572ec1f2e5985762e60d._comment9
-rw-r--r--doc/design/assistant/leftovers.mdwn17
-rw-r--r--doc/design/assistant/leftovers/comment_1_b20c88bb3c583a32023c1f6b6dc9486d._comment8
-rw-r--r--doc/design/assistant/more_cloud_providers.mdwn24
-rw-r--r--doc/design/assistant/pairing.mdwn83
-rw-r--r--doc/design/assistant/partial_content.mdwn36
-rw-r--r--doc/design/assistant/partial_content/comment_1_58c4faa321a5bb71adf9fdee079849f4._comment18
-rw-r--r--doc/design/assistant/polls.mdwn1
-rw-r--r--doc/design/assistant/polls/2013_user_survey.mdwn1
-rw-r--r--doc/design/assistant/polls/Android.mdwn18
-rw-r--r--doc/design/assistant/polls/Android/comment_1_fa6c409833f28c67da105d25f4a440e0._comment8
-rw-r--r--doc/design/assistant/polls/Android_default_directory.mdwn7
-rw-r--r--doc/design/assistant/polls/Android_default_directory/comment_1_d39655091ac3ed51a9d4325d86b23ad7._comment10
-rw-r--r--doc/design/assistant/polls/Android_default_directory/comment_2_2f1eaae95075db26488517720afd1c63._comment8
-rw-r--r--doc/design/assistant/polls/Android_default_directory/comment_3_b484012f60789be73d7d5b338cff6203._comment10
-rw-r--r--doc/design/assistant/polls/goals_for_April.mdwn17
-rw-r--r--doc/design/assistant/polls/goals_for_April/comment_1_9f81fa96db5970a4be0828c74a6d2d55._comment22
-rw-r--r--doc/design/assistant/polls/goals_for_April/comment_2_d8956d220ccacff3d2f6cbeb15718459._comment28
-rw-r--r--doc/design/assistant/polls/goals_for_April/comment_3_aadad6dfd56d068d2e377606910c006f._comment8
-rw-r--r--doc/design/assistant/polls/prioritizing_special_remotes.mdwn16
-rw-r--r--doc/design/assistant/polls/prioritizing_special_remotes/comment_1_dd9280df27848a7ff132f5809dab0a79._comment8
-rw-r--r--doc/design/assistant/polls/prioritizing_special_remotes/comment_2_370e0b9c43486ee96c825f9155eebde4._comment8
-rw-r--r--doc/design/assistant/polls/prioritizing_special_remotes/comment_3_883a003b9c552b89f191135c582f99aa._comment14
-rw-r--r--doc/design/assistant/polls/prioritizing_special_remotes/comment_4_746006c3fffc7f917c4526fd688051f7._comment8
-rw-r--r--doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant.mdwn16
-rw-r--r--doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_10_10a4839a05be39ced54ffbe880a588bb._comment25
-rw-r--r--doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_11_ac91d866f11c66dd8c86e2cd1a368c85._comment10
-rw-r--r--doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_12_e244c1bf334b1cc9ad0cc760bf8fe5de._comment29
-rw-r--r--doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_13_1a0faf4bdc78741937e8a2f5cb5bbec6._comment12
-rw-r--r--doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_14_8d8a11dbfae7a7bc574bdf37f87e0684._comment16
-rw-r--r--doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_15_c437adeaccf0b3d134e0f81c64e25b9f._comment14
-rw-r--r--doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_16_6e3fce3a32ab346dc3d0fd4b69967536._comment8
-rw-r--r--doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_17_1b7233d88593d0d99b26ea3e7af20d9c._comment8
-rw-r--r--doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_18_a23d5a0e2718b8e486f036fe8a413b36._comment10
-rw-r--r--doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_19_f4c84a9d701d52cf2f2e45f3d764a90c._comment18
-rw-r--r--doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_1_00a0de8190d946caaeeca3b44646146f._comment16
-rw-r--r--doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_20_199c9807499470771af6cbca6d034cfa._comment8
-rw-r--r--doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_2_35f6f121e54260cb960211a6e2e51e8e._comment14
-rw-r--r--doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_3_acbe4f63b5d552ac5ae5a12c6f42dc18._comment25
-rw-r--r--doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_4_0d988280865caae498a3b693b6342e37._comment16
-rw-r--r--doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_5_ac8fe3768c30dd7999c183500f8567bb._comment19
-rw-r--r--doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_6_36832de705a2bebf8dc6e65dcd661731._comment15
-rw-r--r--doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_7_3618067e473577a112e36970ca71e0ab._comment12
-rw-r--r--doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_8_07a13b6f000ddc0ac4472b863d8b50bd._comment14
-rw-r--r--doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_9_e15eb407d988fda363296c8b566cc8fb._comment12
-rw-r--r--doc/design/assistant/progressbars.mdwn43
-rw-r--r--doc/design/assistant/progressbars/comment_1_3ea263b1f334e8e38e14f00a96202988._comment8
-rw-r--r--doc/design/assistant/rate_limiting.mdwn57
-rw-r--r--doc/design/assistant/screenshot/firstrun.pngbin0 -> 54347 bytes
-rw-r--r--doc/design/assistant/screenshot/intro.pngbin0 -> 50730 bytes
-rw-r--r--doc/design/assistant/sshpassword.mdwn12
-rw-r--r--doc/design/assistant/syncing.mdwn260
-rw-r--r--doc/design/assistant/syncing/comment_1_c70156174ff19b503978d623bd2df36f._comment19
-rw-r--r--doc/design/assistant/syncing/comment_2_eb992b5b2c7a5ce23443e2a6007e5ff9._comment8
-rw-r--r--doc/design/assistant/syncing/comment_3_e1b5e8a24556de16d1cacd27ee0c1bd1._comment80
-rw-r--r--doc/design/assistant/thanks/comment_1_8b08b5c30e5aea3fc4599f856fd25df5._comment8
-rw-r--r--doc/design/assistant/todo.mdwn4
-rw-r--r--doc/design/assistant/transfer_control.mdwn123
-rw-r--r--doc/design/assistant/transfer_control/comment_1_d5adaef4712913dc0263d4ebafb79320._comment15
-rw-r--r--doc/design/assistant/upgrading.mdwn52
-rw-r--r--doc/design/assistant/webapp.mdwn65
-rw-r--r--doc/design/assistant/webapp/comment_1_bab6f6fa720273c0f9700a3765150189._comment8
-rw-r--r--doc/design/assistant/webapp/comment_2_3cf0cf460c7869d0cc22940fcc84aec4._comment10
-rw-r--r--doc/design/assistant/webapp/comment_3_428e153135f7a64215730719207d82c4._comment8
-rw-r--r--doc/design/assistant/webapp/comment_4_f4068a7abbb77ba6a3297cbcf1e503e9._comment10
-rw-r--r--doc/design/assistant/windows.mdwn33
-rw-r--r--doc/design/assistant/windows/comment_1_f4b829318b182e1cec29f13babb6498e._comment10
-rw-r--r--doc/design/assistant/xmpp.mdwn136
-rw-r--r--doc/design/assistant/xmpp/comment_1_f20650f93d7f0ca39b9ba3ce0380193f._comment10
-rw-r--r--doc/design/assistant/xmpp/comment_2_8c22839a8f5912b4a817415c4a359697._comment8
-rw-r--r--doc/design/assistant/xmpp/comment_4_773102522f21844cffc841e6cde9229e._comment8
-rw-r--r--doc/design/assistant/xmpp_security.mdwn26
-rw-r--r--doc/design/assistant/xmpp_security/comment_1_c714e86553c02600249795efb224be8a._comment10
-rw-r--r--doc/design/encryption.mdwn126
-rw-r--r--doc/design/encryption/comment_1_4715ffafb3c4a9915bc33f2b26aaa9c1._comment12
-rw-r--r--doc/design/encryption/comment_2_a610b3d056a059899178859a3a821ea5._comment10
-rw-r--r--doc/design/encryption/comment_3_cca186a9536cd3f6e86994631b14231c._comment12
-rw-r--r--doc/design/encryption/comment_4_8f3ba3e504b058791fc6e6f9c38154cf._comment10
-rw-r--r--doc/design/encryption/comment_5_520e60aa53217b5ba428d4c05d897dee._comment16
-rw-r--r--doc/design/encryption/comment_6_d677fead0fe0c543f48f07d85f83f592._comment14
-rw-r--r--doc/design/encryption/comment_7_c1c38a09b1276e29adc3ba564dc0fe4e._comment14
-rw-r--r--doc/design/gcrypt.mdwn8
-rw-r--r--doc/design/roadmap.mdwn18
-rw-r--r--doc/devblog.mdwn10
-rw-r--r--doc/devblog/day_-1__drop_dead.mdwn5
-rw-r--r--doc/devblog/day_-3__.mdwn29
-rw-r--r--doc/devblog/day_-4__forgetting.mdwn80
-rw-r--r--doc/devblog/day_-4__forgetting/comment_1_f3cc7a25af4c59fda3924c737a789419._comment8
-rw-r--r--doc/devblog/day_10__lazy_Sunday.mdwn23
-rw-r--r--doc/devblog/day_11__webapp_encrypted_drives.mdwn12
-rw-r--r--doc/devblog/day_12__gpg_key_generation.mdwn35
-rw-r--r--doc/devblog/day_12__gpg_key_generation/comment_1_48cdfe3bd71fb348ae05fd90e8cf1dab._comment8
-rw-r--r--doc/devblog/day_13__encrypted_sneakernet_working.mdwn13
-rw-r--r--doc/devblog/day_14__gcrypt_refinements_and_OOM_fixes.mdwn26
-rw-r--r--doc/devblog/day_15-17__Android_rebuild.mdwn67
-rw-r--r--doc/devblog/day_19__moving_on.mdwn37
-rw-r--r--doc/devblog/day_19__moving_on/comment_1_870106f671f9a055b81e6fc83e0850b5._comment8
-rw-r--r--doc/devblog/day_19__moving_on/comment_2_fad055c8860385ac6c012f897c96408f._comment10
-rw-r--r--doc/devblog/day_19__moving_on/comment_3_69e47d612159587f080ab761566d1830._comment18
-rw-r--r--doc/devblog/day_1__inauspicious_beginning.mdwn11
-rw-r--r--doc/devblog/day_1__inauspicious_beginning/comment_1_cc4dea43caf3126c6f814b589b701d70._comment10
-rw-r--r--doc/devblog/day_20__gcrypt_and_git-annex-shell.mdwn14
-rw-r--r--doc/devblog/day_21__bugfix_day.mdwn5
-rw-r--r--doc/devblog/day_22__gcrypt_on_rsync.net.mdwn20
-rw-r--r--doc/devblog/day_23__GNU_day.mdwn23
-rw-r--r--doc/devblog/day_24__nearly_done_with_gcrypt.mdwn23
-rw-r--r--doc/devblog/day_25__finishing_up_gcrypt.mdwn25
-rw-r--r--doc/devblog/day_26__gcrypt_really_done_this_time.mdwn17
-rw-r--r--doc/devblog/day_27__locking_fun.mdwn49
-rw-r--r--doc/devblog/day_27__locking_fun/comment_1_0eb247235fbf8f563934f3548e1d2e10._comment8
-rw-r--r--doc/devblog/day_27__locking_fun/comment_2_e8b1dfe1b0641e031d05733448b7bc8b._comment8
-rw-r--r--doc/devblog/day_27__locking_fun/comment_3_b67f8ef4ed42b49c8c2e6c4e53163b16._comment18
-rw-r--r--doc/devblog/day_27__locking_fun/comment_4_0759644baf26b75f4e48dbb387d725a5._comment10
-rw-r--r--doc/devblog/day_28__lazy_saturday.mdwn17
-rw-r--r--doc/devblog/day_29__scheduling.mdwn10
-rw-r--r--doc/devblog/day_2__new_laptop.mdwn8
-rw-r--r--doc/devblog/day_2__new_laptop/comment_1_93447dbd4eb09b4db96770644ea663cb._comment10
-rw-r--r--doc/devblog/day_2__new_laptop/comment_2_e1d022b25f2c16dbe72db07ad4b10a2d._comment8
-rw-r--r--doc/devblog/day_30__cronner.mdwn17
-rw-r--r--doc/devblog/day_30__cronner/comment_1_53dfd9310e92f5225db52a13e20a46d4._comment10
-rw-r--r--doc/devblog/day_30__cronner/comment_2_f98357c6f7a6da23873ac27c2e1e9638._comment10
-rw-r--r--doc/devblog/day_31__blah.mdwn17
-rw-r--r--doc/devblog/day_32__fsck_config_UI.mdwn20
-rw-r--r--doc/devblog/day_33__fsck_on_connect.mdwn9
-rw-r--r--doc/devblog/day_34__wrapping_up_fsck.mdwn7
-rw-r--r--doc/devblog/day_35__anacron_and_bugfixing.mdwn15
-rw-r--r--doc/devblog/day_36__bugfixing.mdwn1
-rw-r--r--doc/devblog/day_37__long_day.mdwn6
-rw-r--r--doc/devblog/day_38__starting_git_repo_repair.mdwn11
-rw-r--r--doc/devblog/day_38__starting_git_repo_repair/comment_1_321468d9686db5dde072500bdaeb7d29._comment10
-rw-r--r--doc/devblog/day_39__git-recover-repository.mdwn54
-rw-r--r--doc/devblog/day_3__gcrypt_uuids.mdwn63
-rw-r--r--doc/devblog/day_40__another_fine_mess.mdwn15
-rw-r--r--doc/devblog/day_41__onward.mdwn17
-rw-r--r--doc/devblog/day_41__onward/comment_1_a716c7b5a9ea3c949ff047cfb4e9a0a4._comment8
-rw-r--r--doc/devblog/day_41__onward/comment_2_33149e424cd5f03fac376288bcc4dfdc._comment8
-rw-r--r--doc/devblog/day_41__onward/comment_3_3b07503bd79089ad3ce3ddd7535ed116._comment14
-rw-r--r--doc/devblog/day_42__repair_milestone.mdwn35
-rw-r--r--doc/devblog/day_43__bugfix_day.mdwn26
-rw-r--r--doc/devblog/day_44__automatic_removable_drive_repair.mdwn16
-rw-r--r--doc/devblog/day_45__command_line.mdwn9
-rw-r--r--doc/devblog/day_46__wrapping_up_the_month.mdwn18
-rw-r--r--doc/devblog/day_47__fell_off_the_blogging_wagon.mdwn3
-rw-r--r--doc/devblog/day_48__direct_mode_guard_design.mdwn29
-rw-r--r--doc/devblog/day_48__direct_mode_guard_design/comment_1_ec0147ccc55bad3a38652383f4098a65._comment8
-rw-r--r--doc/devblog/day_49__direct_mode_guard_implementation.mdwn14
-rw-r--r--doc/devblog/day_49__direct_mode_guard_implementation/comment_1_3ebe5c3f708070f164ecaf36b79f7bfc._comment8
-rw-r--r--doc/devblog/day_4__unexpected_windows_day.mdwn10
-rw-r--r--doc/devblog/day_50__grab_bag.mdwn34
-rw-r--r--doc/devblog/day_50__grab_bag/comment_1_01846f6494fe843889391fd09fd127a0._comment8
-rw-r--r--doc/devblog/day_50__grab_bag/comment_2_12736014aa2c1af81e4b83072505e7d5._comment8
-rw-r--r--doc/devblog/day_51__direct_mode_guard_finished.mdwn6
-rw-r--r--doc/devblog/day_52__slowly_but_surely.mdwn5
-rw-r--r--doc/devblog/day_54__android_bisection_minions.mdwn9
-rw-r--r--doc/devblog/day_54__android_bisection_minions/comment_1_bea8fbe2b87d4a4865b92fa796298fa0._comment8
-rw-r--r--doc/devblog/day_55__fireside_porting.mdwn22
-rw-r--r--doc/devblog/day_55__fireside_porting/comment_1_d690a52db82f9594d99ae65fe51e1f1a._comment8
-rw-r--r--doc/devblog/day_56__git-annex_user_survey.mdwn20
-rw-r--r--doc/devblog/day_57__mavericks.mdwn14
-rw-r--r--doc/devblog/day_58__urgle.mdwn16
-rw-r--r--doc/devblog/day_58__urgle/comment_1_bd279f58f614b103a53215dfb0211007._comment12
-rw-r--r--doc/devblog/day_59__release_day.mdwn11
-rw-r--r--doc/devblog/day_5__gcrypt_special_remote_part_1.mdwn7
-rw-r--r--doc/devblog/day_60__damage_driven_development.mdwn36
-rw-r--r--doc/devblog/day_61__damage_driven_development__II.mdwn15
-rw-r--r--doc/devblog/day_62__upgrade_alerts.mdwn22
-rw-r--r--doc/devblog/day_62__upgrade_alerts/comment_1_cdb44aaa1d2a784a72613cbf16038f89._comment8
-rw-r--r--doc/devblog/day_62__upgrade_alerts/comment_2_b08bb946e4760d7f03b45c852c745b2e._comment8
-rw-r--r--doc/devblog/day_63__leverage.mdwn24
-rw-r--r--doc/devblog/day_64__overkill.mdwn31
-rw-r--r--doc/devblog/day_64__overkill/comment_1_e1db7678aae37af281d31ae211677786._comment10
-rw-r--r--doc/devblog/day_64__overkill/comment_3_f7a96f0b6d942d0b59d9d0ec1b21c4bf._comment8
-rw-r--r--doc/devblog/day_65__wrapping_up_upgrades.mdwn5
-rw-r--r--doc/devblog/day_66__upgrade_testing.mdwn17
-rw-r--r--doc/devblog/day_67_thanksgiving_rush.mdwn19
-rw-r--r--doc/devblog/day_6__gcrypt_fully_working.mdwn8
-rw-r--r--doc/devblog/day_6__gcrypt_fully_working/comment_1_136bb7537a9ba93d400ce6f6ea1932ac._comment8
-rw-r--r--doc/devblog/day_6__gcrypt_fully_working/comment_2_1f8faa65bbd56a12588b43a5bc822d96._comment10
-rw-r--r--doc/devblog/day_7__release_day.mdwn10
-rw-r--r--doc/devblog/day_7__release_day/comment_1_12bb94d903868ecddb3e348c9c4afeaf._comment8
-rw-r--r--doc/devblog/day_7__release_day/comment_2_d3e38d6f6bba179dab40d4d75ff061de._comment8
-rw-r--r--doc/devblog/day_8__ill.mdwn20
-rw-r--r--doc/devblog/day_9__Friday_the_13th.mdwn21
-rw-r--r--doc/devblog/day_9__Friday_the_13th/comment_1_07195b4ec399ba1be6c8bdb3ae0fa50b._comment12
-rw-r--r--doc/devblog/moving_blogs.mdwn5
-rw-r--r--doc/devblog/moving_blogs/comment_1_6caa7e67461a6ea5de8155ae9cf75fab._comment8
-rw-r--r--doc/devblog/moving_blogs/comment_2_e3e2048fc2397b87a2f29c9fe49394cb._comment10
-rw-r--r--doc/direct_mode.mdwn93
-rw-r--r--doc/direct_mode/comment_11_1c79c93f4b17cfc354ab920e3775cc60._comment26
-rw-r--r--doc/direct_mode/comment_12_1b5218fdb6ee362d6df68ff1229590d4._comment10
-rw-r--r--doc/direct_mode/comment_13_55108ac736ea450df89332ba5de4a208._comment12
-rw-r--r--doc/direct_mode/comment_14_ff4ffc2aabc5fd174d7386ef13860f78._comment10
-rw-r--r--doc/direct_mode/comment_15_1cd32456630b25d5aaa6d2763e6eb384._comment8
-rw-r--r--doc/direct_mode/comment_3_8020d74bddf0e38b0a297e5dae7c217b._comment12
-rw-r--r--doc/direct_mode/comment_4_97c26bd82f623a3b2d56bab4afff0126._comment12
-rw-r--r--doc/direct_mode/comment_5_42363bf0367f935b3eee8ad3d2eaf5cf._comment10
-rw-r--r--doc/direct_mode/comment_6_5f03b1686c1fb3f7606a5bc724ac3812._comment8
-rw-r--r--doc/direct_mode/comment_7_5355ac418bfb26e990762b80f4c36b77._comment12
-rw-r--r--doc/direct_mode/comment_8_6cd15e2c5fd0bef48f60c6993322c2fc._comment9
-rw-r--r--doc/distributed_version_control.mdwn21
-rw-r--r--doc/download.mdwn40
-rw-r--r--doc/download/comment_1_ec2578241a966cfcdd43f2a26a5c8709._comment13
-rw-r--r--doc/download/comment_2_ee0d158ac59903737dbc4ef632f11fe3._comment7
-rw-r--r--doc/ekg.mdwn14
-rw-r--r--doc/ekg/ekg.pngbin0 -> 57392 bytes
-rw-r--r--doc/encryption.mdwn101
-rw-r--r--doc/encryption/comment_1_1afca8d7182075d46db41f6ad3dd5911._comment10
-rw-r--r--doc/favicon.icobin0 -> 405 bytes
-rw-r--r--doc/favicon.pngbin0 -> 714 bytes
-rw-r--r--doc/feeds.mdwn4
-rw-r--r--doc/footer/column_a.mdwn7
-rw-r--r--doc/footer/column_b.mdwn7
-rw-r--r--doc/forum.mdwn8
-rw-r--r--doc/forum/A_question_an_the_nomad_use_cases:_files_to_fetch__44___files_to_delete__44___files_to_keep__63__.mdwn12
-rw-r--r--doc/forum/A_question_an_the_nomad_use_cases:_files_to_fetch__44___files_to_delete__44___files_to_keep__63__/comment_1_fe291cd6cd8e2d5b8e23f8e3689d824b._comment15
-rw-r--r--doc/forum/A_question_an_the_nomad_use_cases:_files_to_fetch__44___files_to_delete__44___files_to_keep__63__/comment_2_f0dbc3c723999bf0f22502e3a89d1d4a._comment8
-rw-r--r--doc/forum/A_really_stupid_question.mdwn3
-rw-r--r--doc/forum/A_really_stupid_question/comment_1_40e02556de0b00b94f245a0196b5a89f._comment31
-rw-r--r--doc/forum/Accessing_files_directly_on__a_USB_device.mdwn11
-rw-r--r--doc/forum/Accessing_files_in_bare_repository.mdwn5
-rw-r--r--doc/forum/Accessing_files_in_bare_repository/comment_10_7eb66e3806f9524e043fae2da9d57d64._comment10
-rw-r--r--doc/forum/Accessing_files_in_bare_repository/comment_11_f0165d66865ad14f7eb5d50e900c1df4._comment10
-rw-r--r--doc/forum/Accessing_files_in_bare_repository/comment_12_0e7ea5161b6da6e9bb9425bdb953de33._comment8
-rw-r--r--doc/forum/Accessing_files_in_bare_repository/comment_13_f804b9bf71f7d04bd23ce32d813dc340._comment8
-rw-r--r--doc/forum/Accessing_files_in_bare_repository/comment_1_6de649d38febd2240eb5b703da77c2d6._comment15
-rw-r--r--doc/forum/Accessing_files_in_bare_repository/comment_2_7e8dd09915ddc3267377e900891cb02c._comment24
-rw-r--r--doc/forum/Accessing_files_in_bare_repository/comment_3_80eae4a73f38d1a7e35f97c33b6401f8._comment8
-rw-r--r--doc/forum/Accessing_files_in_bare_repository/comment_4_5ec13e98d3ecb69426e974d34f712f9b._comment8
-rw-r--r--doc/forum/Accessing_files_in_bare_repository/comment_5_dccbf5793998c6381e23eb8ff6497ebf._comment17
-rw-r--r--doc/forum/Accessing_files_in_bare_repository/comment_6_42d923916232c81f3b8bdbefa34a89d3._comment18
-rw-r--r--doc/forum/Accessing_files_in_bare_repository/comment_7_43a0a7d222faee582aeb3150a59cef87._comment8
-rw-r--r--doc/forum/Accessing_files_in_bare_repository/comment_8_ec1024235c1c74c113483a833df84654._comment12
-rw-r--r--doc/forum/Accessing_files_in_bare_repository/comment_9_c156b8c1ae0f2905566bbdb13b84e577._comment37
-rw-r--r--doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository.mdwn28
-rw-r--r--doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/bugs/direct_mode_sync_should_avoid_git_commit.mdwn1
-rw-r--r--doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_10_06dae5709750ea1da4f7fdbee4e84efc._comment16
-rw-r--r--doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_11_2069c5c41882ae0a1973fb7da583b60e._comment10
-rw-r--r--doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_12_b35e3a87c30974eedd71ebe52ecbed96._comment8
-rw-r--r--doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_13_84e026f9bda87bfd12a3769dcef77f8b._comment8
-rw-r--r--doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_1_ed3534196164c6736a8dbf21c65c119d._comment10
-rw-r--r--doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_2_1e29bcf568f02765c48f0eac6c640673._comment45
-rw-r--r--doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_3_9ea6803a94b1de15079a3fa20d59c9af._comment10
-rw-r--r--doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_4_3fae5a7fa5d99d0eb4473adb43e7f6f5._comment8
-rw-r--r--doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_5_57a5b73cff480266355e75c7bdc762c2._comment8
-rw-r--r--doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_6_bbcf5e863c8f152e1079536e9011a404._comment16
-rw-r--r--doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_7_fdcd144c22601bdf98ff844254b0120d._comment8
-rw-r--r--doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_8_b77243e765b2af7ba71e963fcb5cbbb1._comment71
-rw-r--r--doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_9_cb0815e96ee211d4778f2e7a4274e855._comment8
-rw-r--r--doc/forum/Add_a___34__local__34___remote.txt13
-rw-r--r--doc/forum/Add_a___34__local__34___remote/comment_1_c68ad724b465c4be5243be687168c0b3._comment12
-rw-r--r--doc/forum/Adding_existing_S3_bucket_to_sync_with.mdwn16
-rw-r--r--doc/forum/Adding_existing_S3_bucket_to_sync_with/comment_1_30b9a70d367dd5b8781e9a86e42d4c3e._comment10
-rw-r--r--doc/forum/Adding_existing_S3_bucket_to_sync_with/comment_2_a8525c1a7e5f89c30c9503fe8bfed02e._comment8
-rw-r--r--doc/forum/Adding_existing_S3_bucket_to_sync_with/comment_3_c3878989f74e740c0ed42f440750f3a4._comment8
-rw-r--r--doc/forum/Adding_existing_S3_bucket_to_sync_with/comment_4_c06cc86496f9d4c0c42a8c89aa5a7b35._comment8
-rw-r--r--doc/forum/Adding_existing_S3_bucket_to_sync_with/comment_5_0a1c2dd0929511ff824be8de2c8d85eb._comment9
-rw-r--r--doc/forum/Adding_existing_S3_bucket_to_sync_with/comment_6_1444c2f89885f028f20a4d3ce225a403._comment23
-rw-r--r--doc/forum/Adding_existing_S3_bucket_to_sync_with/comment_7_1c30944010d541096baff18198a5560d._comment23
-rw-r--r--doc/forum/Android:_is_constant_high_cpu_usage_to_be_expected__63__.mdwn3
-rw-r--r--doc/forum/Android:_is_constant_high_cpu_usage_to_be_expected__63__/comment_1_7880fc38792a1fcbf3e5c47e8bcaabce._comment8
-rw-r--r--doc/forum/Android:_is_constant_high_cpu_usage_to_be_expected__63__/comment_2_840fbce18b4fdec21ee557fdf52c366e._comment10
-rw-r--r--doc/forum/Annex_contents_just_disappeared__63__.mdwn12
-rw-r--r--doc/forum/Annex_contents_just_disappeared__63__/comment_1_4ab5ca00f912c0c95fabc10f2d9600d3._comment12
-rw-r--r--doc/forum/Annex_contents_just_disappeared__63__/comment_2_657f737c5d64d440aa133ddb41408fbc._comment8
-rw-r--r--doc/forum/Annex_contents_just_disappeared__63__/comment_3_9b4c35feb14b37d43d053d7430da9abf._comment12
-rw-r--r--doc/forum/Annex_contents_just_disappeared__63__/comment_4_c3625409652bff5f2165260803269a8a._comment10
-rw-r--r--doc/forum/Annex_dropping_files.mdwn12
-rw-r--r--doc/forum/Annex_dropping_files/comment_1_62fbea95248fda2ff075b5a8952a728f._comment8
-rw-r--r--doc/forum/Assistant:_configure_auto-sync.mdwn11
-rw-r--r--doc/forum/Assistant:_configure_auto-sync/comment_1_c8cabd38114582bbdbad49f2d81959d7._comment13
-rw-r--r--doc/forum/Assistant_not_syncing_to_Rsync.mdwn15
-rw-r--r--doc/forum/Assistant_not_syncing_to_Rsync/comment_1_2178a7fc0d66643e84597b0938ef65f2._comment10
-rw-r--r--doc/forum/Assistant_not_syncing_to_Rsync/comment_2_650651398443e128c2adc6a2a2d320d0._comment12
-rw-r--r--doc/forum/Assistant_not_syncing_to_Rsync/comment_3_e6d0c9620b148acc72342862a8b4cfef._comment10
-rw-r--r--doc/forum/Assistant_not_syncing_to_Rsync/comment_4_b91f9febdb8b69d8b487ba4ea08c119a._comment11
-rw-r--r--doc/forum/Assistant_not_syncing_to_Rsync/comment_5_c5ad7c1546a17d8459c995c9c8c26414._comment31
-rw-r--r--doc/forum/Assistant_not_syncing_to_Rsync/comment_6_4c12587f972eced91c5128d4885800b5._comment30
-rw-r--r--doc/forum/Assistant_not_syncing_to_Rsync/comment_7_6ecaaee9316bcf0c65688676d60fc055._comment8
-rw-r--r--doc/forum/Assistant_not_syncing_to_Rsync/comment_8_daa9a9a6188afa0394833e1b682f7cd4._comment10
-rw-r--r--doc/forum/Auto_archiving.mdwn17
-rw-r--r--doc/forum/Automatic___96__git_annex_get__96___after_invalidation_of_local_files_due_to_external_modification__63__.mdwn46
-rw-r--r--doc/forum/Automatic___96__git_annex_get__96___after_invalidation_of_local_files_due_to_external_modification__63__/comment_1_dab1099ee56541c194de319c593f1268._comment9
-rw-r--r--doc/forum/Automatic___96__git_annex_get__96___after_invalidation_of_local_files_due_to_external_modification__63__/comment_2_b5faccf132fb47e3cda778a6600fd9ef._comment8
-rw-r--r--doc/forum/Automatic_commit_messages_for_git_annex_sync.mdwn1
-rw-r--r--doc/forum/Automatic_commit_messages_for_git_annex_sync/comment_1_ea2ec57bc695da4df8a30a35d433959d._comment15
-rw-r--r--doc/forum/Automatic_commit_messages_for_git_annex_sync/comment_2_af71f53dbbca35d5a5c66ff131887ada._comment8
-rw-r--r--doc/forum/Automatically_syncronise_centralised_repository.mdwn14
-rw-r--r--doc/forum/Automatically_syncronise_centralised_repository/comment_1_6a2047daa9faf4309d2ed27d5cc48b76._comment10
-rw-r--r--doc/forum/Automatically_syncronise_centralised_repository/comment_2_3be7b45bc2284019f17a81375637a576._comment10
-rw-r--r--doc/forum/Behaviour_of_fsck.mdwn13
-rw-r--r--doc/forum/Behaviour_of_fsck/comment_1_0e40f158b3f4ccdcaab1408d858b68b8._comment8
-rw-r--r--doc/forum/Behaviour_of_fsck/comment_2_ead36a23c3e6efa1c41e4555f93e014e._comment19
-rw-r--r--doc/forum/Behaviour_of_fsck/comment_3_97848f9a3db89c0427cfb671ba13300e._comment19
-rw-r--r--doc/forum/Behaviour_of_fsck/comment_4_e4911dc6793f98fb81151daacbe49968._comment8
-rw-r--r--doc/forum/Best_way_to_manage_files_on_removable_media__63__.mdwn18
-rw-r--r--doc/forum/Best_way_to_re-add_a_file_in_a_direct_and_crippled_annex_repository.mdwn17
-rw-r--r--doc/forum/Best_way_to_re-add_a_file_in_a_direct_and_crippled_annex_repository/comment_1_552e74f9573a34ec178f396b83252c3e._comment12
-rw-r--r--doc/forum/Best_way_to_re-add_a_file_in_a_direct_and_crippled_annex_repository/comment_2_33c57922714f204fc63c260b838f3712._comment8
-rw-r--r--doc/forum/Box.com_hasn__39__t_been_working_for_a_few_days.mdwn72
-rw-r--r--doc/forum/Box.com_hasn__39__t_been_working_for_a_few_days/comment_1_6ca872c241399b9129cf9a18f42ebd43._comment8
-rw-r--r--doc/forum/Building_a_Debian_package_of_git-annex.mdwn27
-rw-r--r--doc/forum/Building_a_Debian_package_of_git-annex/comment_1_0848513c46f3efa21bc34784554ae88a._comment10
-rw-r--r--doc/forum/Building_git-annex-3.20121112-19309.mdwn78
-rw-r--r--doc/forum/Building_git-annex-3.20121112-19309/comment_1_b115e28c77fe748ee6643c41f766beb4._comment12
-rw-r--r--doc/forum/Building_git-annex-3.20121112-19309/comment_2_8c6ae1fd74f14da12ccfa77dbd27fc65._comment16
-rw-r--r--doc/forum/Building_git-annex-3.20121112-19309/comment_3_2f30b301c14f3a7fa0f52715d6140353._comment13
-rw-r--r--doc/forum/Building_git-annex-3.20121112-19309/comment_4_1e3c3903a71a2ff7109372aa4dd5742a._comment8
-rw-r--r--doc/forum/Cabal:_Could_not_resolve_dependencies___40__yesod__41__.mdwn19
-rw-r--r--doc/forum/Cabal:_Could_not_resolve_dependencies___40__yesod__41__/comment_1_2eb4f410b54a25fcc895893a3c631c43._comment8
-rw-r--r--doc/forum/Cabal:_Could_not_resolve_dependencies___40__yesod__41__/comment_2_44cd6f6dd674df105d6f0b3f320f3236._comment19
-rw-r--r--doc/forum/Cabal:_Could_not_resolve_dependencies___40__yesod__41__/comment_3_992af6855901df79a2018a07941cb8b6._comment8
-rw-r--r--doc/forum/Calculating_Annex_Cost_by_Ping_Times.mdwn1
-rw-r--r--doc/forum/Calculating_Annex_Cost_by_Ping_Times/comment_1_9b4a6bc8d52ecbbdd537e8cf76757a80._comment15
-rw-r--r--doc/forum/Calculating_Annex_Cost_by_Ping_Times/comment_2_7e04f85c6ba74c18c8dde148aef9bf80._comment8
-rw-r--r--doc/forum/Can_I_store_normal_files_in_the_git-annex_git_repository__63__.mdwn6
-rw-r--r--doc/forum/Can_I_store_normal_files_in_the_git-annex_git_repository__63__/comment_1_c8f9923d8dc76b8bed25dce5ae09b520._comment8
-rw-r--r--doc/forum/Can__39__t_get_git-annex_merge_to_work_from_git_hook.mdwn41
-rw-r--r--doc/forum/Can__39__t_get_git-annex_merge_to_work_from_git_hook/comment_1_8b71cb6772b219c27c17392d5099907a._comment12
-rw-r--r--doc/forum/Can__39__t_get_git-annex_merge_to_work_from_git_hook/comment_2_af2a2634d8d128868022d033d6adb549._comment13
-rw-r--r--doc/forum/Can__39__t_get_git-annex_merge_to_work_from_git_hook/comment_3_31ec762a0684d2ce87d229ed2924db93._comment16
-rw-r--r--doc/forum/Can__39__t_get_pairing_to_work.mdwn5
-rw-r--r--doc/forum/Can__39__t_get_pairing_to_work/comment_1_b981977b4fb942fd109c37fcf40f35d7._comment22
-rw-r--r--doc/forum/Can__39__t_get_pairing_to_work/comment_2_341e2ff6c88ace1b1422e16781edf580._comment8
-rw-r--r--doc/forum/Can__39__t_get_pairing_to_work/comment_3_0c8cce48f179f2564ff0844bb7ef6bd1._comment8
-rw-r--r--doc/forum/Can__39__t_get_pairing_to_work/comment_4_169d77b30cea05125068ee1eeb2ef328._comment25
-rw-r--r--doc/forum/Can__39__t_get_pairing_to_work/comment_5_70e6c4f4f01277be1767b38ca8374793._comment11
-rw-r--r--doc/forum/Can__39__t_get_pairing_to_work/comment_6_2cd014a76fac6e08269dfd8146957418._comment10
-rw-r--r--doc/forum/Can__39__t_get_pairing_to_work/comment_7_b9b715084d5a5562998b1724699d49e5._comment8
-rw-r--r--doc/forum/Can__39__t_init_git_annex.mdwn15
-rw-r--r--doc/forum/Can__39__t_init_git_annex/comment_10_c4d2ab1ecf69718a2211c3ea7b27092b._comment10
-rw-r--r--doc/forum/Can__39__t_init_git_annex/comment_12_fca9ed3707e097bee2cd642424681005._comment8
-rw-r--r--doc/forum/Can__39__t_init_git_annex/comment_1_a294b5e7e52aa9f66a708866be16f137._comment10
-rw-r--r--doc/forum/Can__39__t_init_git_annex/comment_2_fcf678d5188821d63b4c9ea5b59474a8._comment13
-rw-r--r--doc/forum/Can__39__t_init_git_annex/comment_3_c83f7dea7d5304e226e52eb3c43ef14a._comment9
-rw-r--r--doc/forum/Can__39__t_init_git_annex/comment_4_06a01dd51ffbfd006c0afb8eab40b530._comment8
-rw-r--r--doc/forum/Can__39__t_init_git_annex/comment_5_53c33484bded57abc60f0449331c7b05._comment11
-rw-r--r--doc/forum/Can__39__t_init_git_annex/comment_6_9e0ff44f6e62581bfc83f9f1da3e0100._comment14
-rw-r--r--doc/forum/Can__39__t_init_git_annex/comment_7_7f96b5ef05e2faf4a3dbe8bfc39b810e._comment10
-rw-r--r--doc/forum/Can__39__t_init_git_annex/comment_8_65ab8463716f4ddd7721a5bcfcd18fa0._comment8
-rw-r--r--doc/forum/Can__39__t_init_git_annex/comment_9_31a45f6a72266190b3ed7a7b02e03d5b._comment8
-rw-r--r--doc/forum/Can__39__t_install:_Mac_OS_10.8.2.mdwn36
-rw-r--r--doc/forum/Can__39__t_install:_Mac_OS_10.8.2/comment_1_c44023d81e9e4f7c9341af0e4271a1e4._comment10
-rw-r--r--doc/forum/Can__39__t_install:_Mac_OS_10.8.2/comment_2_dfbcd39eedff28dc9ed866a8f1411ef3._comment30
-rw-r--r--doc/forum/Can__39__t_install:_Mac_OS_10.8.2/comment_3_b37b2a9906ffb956cca91adb4bb4e521._comment8
-rw-r--r--doc/forum/Can__39__t_install:_Mac_OS_10.8.2/comment_4_afddf16f8faedc78d458835480f10dc3._comment15
-rw-r--r--doc/forum/Can_we_have_remotes_that_aren__39__t_tracked__63___.mdwn13
-rw-r--r--doc/forum/Can_we_have_remotes_that_aren__39__t_tracked__63___/comment_1_35e5a963b9e58ed7773dfcb884f8ecbd._comment10
-rw-r--r--doc/forum/Cannot_find_git-annex_in_server.mdwn10
-rw-r--r--doc/forum/Cannot_find_git-annex_in_server/comment_1_bf7e98e6130698ad0dc92e3a6a63ade3._comment15
-rw-r--r--doc/forum/Cannot_find_git-annex_in_server/comment_2_168dda4aed09f90a510bc453e8a7cda7._comment10
-rw-r--r--doc/forum/Cannot_launch_webapp_on_ubuntu_12.04_using_ppa.mdwn6
-rw-r--r--doc/forum/Cannot_launch_webapp_on_ubuntu_12.04_using_ppa/comment_1_9345551f5772c3a6f1490b00e1edbf69._comment8
-rw-r--r--doc/forum/Cannot_launch_webapp_on_ubuntu_12.04_using_ppa/comment_2_0b688a442b6a911a0353e73097a24cb6._comment12
-rw-r--r--doc/forum/Cannot_launch_webapp_on_ubuntu_12.04_using_ppa/comment_3_7e246caa00005560bb489c927c663046._comment12
-rw-r--r--doc/forum/Cannot_launch_webapp_on_ubuntu_12.04_using_ppa/comment_4_1d8025aabe8bc72711a77f691f67da5f._comment8
-rw-r--r--doc/forum/Cannot_launch_webapp_on_ubuntu_12.04_using_ppa/comment_5_7c2f95da65190016192424e7c622122f._comment8
-rw-r--r--doc/forum/Cannot_launch_webapp_on_ubuntu_12.04_using_ppa/comment_6_9b8465cefe609e7a696e7573b8892e38._comment8
-rw-r--r--doc/forum/Cannot_launch_webapp_on_ubuntu_12.04_using_ppa/comment_7_af6472762a598a454ba52ac0caa059aa._comment10
-rw-r--r--doc/forum/Centralized_repository_with_webapp.mdwn13
-rw-r--r--doc/forum/Centralized_repository_with_webapp/comment_1_dcb9b07fd154f4d4fdef4809cc37ce77._comment18
-rw-r--r--doc/forum/Centralized_repository_with_webapp/comment_2_08c84f2703f89dc12982eba9dd2a06d1._comment11
-rw-r--r--doc/forum/Change_remote_server_address.mdwn6
-rw-r--r--doc/forum/Change_remote_server_address/comment_1_401c3d2530ac7ba41dd3857ab4737ed5._comment10
-rw-r--r--doc/forum/Check_if_remote_is_using_GPG__63__.mdwn1
-rw-r--r--doc/forum/Check_if_remote_is_using_GPG__63__/comment_1_db8ce8ef50fc33a28860ee475988450f._comment14
-rw-r--r--doc/forum/Check_if_remote_is_using_GPG__63__/comment_2_11c7033904c9c7a1df766e915632c386._comment8
-rw-r--r--doc/forum/Check_if_remote_is_using_GPG__63__/comment_3_a7ab70ad87a334c36761ddb3d830d99b._comment8
-rw-r--r--doc/forum/Check_when_your_last_fsck_was__63__.mdwn4
-rw-r--r--doc/forum/Check_when_your_last_fsck_was__63__/comment_1_ee98a1fcd796fe4fd7af6f77d0c1837d._comment10
-rw-r--r--doc/forum/Cleaning_up_after_aborted_sync_in_direct_mode.mdwn19
-rw-r--r--doc/forum/Cleaning_up_after_aborted_sync_in_direct_mode/comment_1_3440b2e1662d3b113c18283afcbf4520._comment8
-rw-r--r--doc/forum/Cleaning_up_after_aborted_sync_in_direct_mode/comment_2_9a61ba8ac4a375f1d69cd09b5a6f8091._comment14
-rw-r--r--doc/forum/Cleaning_up_after_aborted_sync_in_direct_mode/comment_3_6b9d8c48547f3d0a911310622ba91df7._comment13
-rw-r--r--doc/forum/Coming_from_git_world.mdwn9
-rw-r--r--doc/forum/Coming_from_git_world/comment_10_098bef38c2688607e869425a557cc482._comment8
-rw-r--r--doc/forum/Coming_from_git_world/comment_11_98d75a1415e0c3689ab4231855e61233._comment12
-rw-r--r--doc/forum/Coming_from_git_world/comment_12_5e7079e9bf3e4d97191333c66ac00e52._comment10
-rw-r--r--doc/forum/Coming_from_git_world/comment_1_357443dc601ae38784c01cf18552f4d5._comment14
-rw-r--r--doc/forum/Coming_from_git_world/comment_2_ed1847dd3f47a9d013b8dd0455fb80ff._comment8
-rw-r--r--doc/forum/Coming_from_git_world/comment_3_09c6bb83a73d34dff2b8bc185a14a1db._comment18
-rw-r--r--doc/forum/Coming_from_git_world/comment_4_6c731bb9a8d21dd9ab8c09612b23f908._comment16
-rw-r--r--doc/forum/Coming_from_git_world/comment_5_e719d99af5afd90da3d3db692eff28dc._comment11
-rw-r--r--doc/forum/Coming_from_git_world/comment_6_85a42106944dba9995fb3f4bfee3443a._comment10
-rw-r--r--doc/forum/Coming_from_git_world/comment_7_90623294b910ceca3dc8ebd41b50fc9b._comment38
-rw-r--r--doc/forum/Coming_from_git_world/comment_8_28dbee30eb54877418f72eb8935302d8._comment8
-rw-r--r--doc/forum/Coming_from_git_world/comment_9_6edb36ea9535030fa3766937398e5bc7._comment8
-rw-r--r--doc/forum/Compression_in_special_remotes___40__specifically_S3__41____63__.mdwn1
-rw-r--r--doc/forum/Compression_in_special_remotes___40__specifically_S3__41____63__/comment_1_9c6c4ca0c9dc6976ba7cf27e84683bf0._comment8
-rw-r--r--doc/forum/DBus_on_Ubuntu_12.04__63__.mdwn3
-rw-r--r--doc/forum/DBus_on_Ubuntu_12.04__63__/comment_1_dc14a40b64b7eda94d1a3fd766cd39cc._comment28
-rw-r--r--doc/forum/DBus_on_Ubuntu_12.04__63__/comment_2_608a30e274e6a691a39f69503720e320._comment10
-rw-r--r--doc/forum/DBus_on_Ubuntu_12.04__63__/comment_3_791b9978b410c1aff7fd8ef05c38f5f9._comment40
-rw-r--r--doc/forum/DBus_on_Ubuntu_12.04__63__/comment_4_8665c95299916138c4af375626d9ec7d._comment8
-rw-r--r--doc/forum/DS__95__Store_files_are_not_added.mdwn3
-rw-r--r--doc/forum/DS__95__Store_files_are_not_added/comment_1_30687306da9bd35ec02a806193c5e240._comment7
-rw-r--r--doc/forum/Debugging_Git_Annex.mdwn4
-rw-r--r--doc/forum/Debugging_Git_Annex/comment_1_ce63b2ee641a2338f1ad5ded9e6f09a8._comment7
-rw-r--r--doc/forum/Debugging_Git_Annex/comment_2_1d70ff052d00f33c34fd45730ea13040._comment12
-rw-r--r--doc/forum/Default_text__47__html_handler.mdwn2
-rw-r--r--doc/forum/Default_text__47__html_handler/comment_1_4730061916c7e12b7a41906152f847ee._comment12
-rw-r--r--doc/forum/Delete_unused_files__47__metadata.mdwn7
-rw-r--r--doc/forum/Delete_unused_files__47__metadata/comment_1_3efc19895c8dec89b71ae3778b583fea._comment11
-rw-r--r--doc/forum/Delete_unused_files__47__metadata/comment_2_23597d9468347b3d94257f3c02afe1b8._comment8
-rw-r--r--doc/forum/Detached_git_work_tree__63__.mdwn11
-rw-r--r--doc/forum/Detached_git_work_tree__63__/comment_10_656c737772bf92be2c7a2f33bd2bb0f0._comment10
-rw-r--r--doc/forum/Detached_git_work_tree__63__/comment_1_28ac35a325fba250721d9f1b7c994960._comment8
-rw-r--r--doc/forum/Detached_git_work_tree__63__/comment_2_7128c26bbc8efea04a5a317edf0ca9f2._comment13
-rw-r--r--doc/forum/Detached_git_work_tree__63__/comment_3_a3c22f905748ff2c803e8621c74a87a0._comment8
-rw-r--r--doc/forum/Detached_git_work_tree__63__/comment_4_8063921241760458349e7cb0cadf3d4e._comment8
-rw-r--r--doc/forum/Detached_git_work_tree__63__/comment_5_4510a787255cb03e7d0c3e7b830b7d52._comment16
-rw-r--r--doc/forum/Detached_git_work_tree__63__/comment_6_ffd9c67ecc5b46ae98996018573f5591._comment10
-rw-r--r--doc/forum/Detached_git_work_tree__63__/comment_7_36ca007643c983604fc4aed6ec8cb3d2._comment8
-rw-r--r--doc/forum/Detached_git_work_tree__63__/comment_8_b7a2da4fbace7156e11c48a496a19dc9._comment8
-rw-r--r--doc/forum/Detached_git_work_tree__63__/comment_9_f9fa237a693d28178f0451799209f7e2._comment8
-rw-r--r--doc/forum/Difference_between_copy__44___move_and_get__63__.mdwn24
-rw-r--r--doc/forum/Difference_between_copy__44___move_and_get__63__/comment_1_26ee8192af3a62178c1ccf17c6da5ca5._comment10
-rw-r--r--doc/forum/Different_annexes_pointing_to_same_special_remote__63__.mdwn6
-rw-r--r--doc/forum/Different_annexes_pointing_to_same_special_remote__63__/comment_1_359f46805e6508d03aadd90429937546._comment10
-rw-r--r--doc/forum/Direct_special_remotes.mdwn26
-rw-r--r--doc/forum/Direct_special_remotes/comment_1_50357130a1c57ad2fab70f71925faf02._comment8
-rw-r--r--doc/forum/Direct_special_remotes/comment_2_e94a722ca056a068bcc16eb822008602._comment18
-rw-r--r--doc/forum/Direct_special_remotes/comment_4_187036bbfee0508e2914afb51ead3c71._comment16
-rw-r--r--doc/forum/Direct_special_remotes/comment_4_6bfbf60f2061d49b7d34c844e7e1dea2._comment66
-rw-r--r--doc/forum/Direct_special_remotes/comment_5_69c34c655e4b153dfc0d1b8580091124._comment8
-rw-r--r--doc/forum/Direct_special_remotes/comment_6_b054cfc3d3f81873f3faae7eb4f5337c._comment8
-rw-r--r--doc/forum/Does_Jabber_syncing_work_when_the_buddy_is_offline__63__.mdwn1
-rw-r--r--doc/forum/Does_Jabber_syncing_work_when_the_buddy_is_offline__63__/comment_1_f290dd8547176793934f8077374e1c0a._comment17
-rw-r--r--doc/forum/Does_Jabber_syncing_work_when_the_buddy_is_offline__63__/comment_2_c358eb51047f333e582bd824be5e0e65._comment8
-rw-r--r--doc/forum/Does_Jabber_syncing_work_when_the_buddy_is_offline__63__/comment_3_a2332c0e7b29110b9aed2ab69ce9d8c4._comment12
-rw-r--r--doc/forum/Does_git-annex_version_big_files__63__.mdwn5
-rw-r--r--doc/forum/Does_git-annex_version_big_files__63__/comment_1_0b44003c1dc53adb807298ae452f8004._comment8
-rw-r--r--doc/forum/Does_git-annex_version_big_files__63__/comment_2_ca40b67abd7bd36155d16d0396d7472c._comment14
-rw-r--r--doc/forum/Does_git-annex_version_big_files__63__/comment_3_32de3501feedce51b43ed9dcc399c7a9._comment15
-rw-r--r--doc/forum/Does_git-annex_version_big_files__63__/comment_4_8c65a7f8bda3c876971c2801fb6a76a1._comment8
-rw-r--r--doc/forum/Does_migrate_ensure_data_integrity__63__.mdwn7
-rw-r--r--doc/forum/Does_migrate_ensure_data_integrity__63__/comment_1_cef50b32c46f4406c6f918c5866ddc15._comment11
-rw-r--r--doc/forum/Does_migrate_ensure_data_integrity__63__/comment_2_f389b924c8531b35fdf5dedd10fc8000._comment8
-rw-r--r--doc/forum/Don__39__t_understand_how_to_delete__47__recover_files.mdwn25
-rw-r--r--doc/forum/Don__39__t_understand_how_to_delete__47__recover_files/comment_1_b307bfb0b70d649897f411eb753bd50a._comment14
-rw-r--r--doc/forum/Don__39__t_understand_how_to_delete__47__recover_files/comment_2_58a6a1476274b8c4feb3d43ecd998759._comment41
-rw-r--r--doc/forum/Don__39__t_understand_how_to_delete__47__recover_files/comment_3_4b857f481db7b2437ac9f8137a8510e2._comment11
-rw-r--r--doc/forum/Don__39__t_understand_how_to_delete__47__recover_files/comment_4_828db3bf2863d98c0b0fb4074aa7f066._comment33
-rw-r--r--doc/forum/Don__39__t_understand_how_to_delete__47__recover_files/comment_5_cb2063d6a4e08a5c12bf3723d0fa74e0._comment8
-rw-r--r--doc/forum/Don__39__t_understand_how_to_delete__47__recover_files/comment_6_1759bcd5708f591f91b9c410f6dc5c54._comment14
-rw-r--r--doc/forum/Don__39__t_understand_how_to_delete__47__recover_files/comment_7_2a389f01eb5131042ea1e71a73c9787a._comment21
-rw-r--r--doc/forum/Don__39__t_understand_local_vs._known_keys.mdwn19
-rw-r--r--doc/forum/Don__39__t_understand_local_vs._known_keys/comment_1_10749c0d76e824217dd1ff8c8a6e42a5._comment10
-rw-r--r--doc/forum/Don__39__t_understand_local_vs._known_keys/comment_2_db9f1b6d9638c2b0a7e241c2727e8cfb._comment13
-rw-r--r--doc/forum/Drop_with_assistant.mdwn5
-rw-r--r--doc/forum/Drop_with_assistant/comment_1_048f5a31c549afb19b76a65bddd0cd24._comment13
-rw-r--r--doc/forum/Drop_with_assistant/comment_2_527d7b6a8efa85b904111f179912d926._comment8
-rw-r--r--doc/forum/Drop_with_assistant/comment_3_c50857506869bb1cd306b66acf37fba8._comment14
-rw-r--r--doc/forum/Drop_with_assistant/comment_4_1ea37445d5eb96c3efa182e88e07b867._comment8
-rw-r--r--doc/forum/Drop_with_assistant/comment_5_c08908ea5232cbe067c73ecd12d0e218._comment10
-rw-r--r--doc/forum/Drop_with_assistant/comment_6_015134228cb865f97326fbb7193636ea._comment8
-rw-r--r--doc/forum/Drop_with_assistant/comment_7_950759930667588f21659cd6d7065fbb._comment17
-rw-r--r--doc/forum/Drop_with_assistant/comment_8_773e540e46adc43487323e8d38ceb2d9._comment23
-rw-r--r--doc/forum/Drop_with_assistant/comment_9_d85d120d7219ea6c179c2619a17bdae9._comment15
-rw-r--r--doc/forum/Effectively_replicating_backup_files.mdwn25
-rw-r--r--doc/forum/Effectively_replicating_backup_files/comment_1_b1ab0da82db076c5244b0dcc95282ddd._comment14
-rw-r--r--doc/forum/Effectively_replicating_backup_files/comment_2_472ab9c973b475f7f3ce7e3934f94281._comment19
-rw-r--r--doc/forum/Effectively_replicating_backup_files/comment_3_826493bd59b81786c1f6a56f1c438004._comment10
-rw-r--r--doc/forum/Encrypted_ssh_remote__44___synced_folders.mdwn87
-rw-r--r--doc/forum/Encrypted_ssh_remote__44___synced_folders/comment_1_7b9b4ef614c90e0b222d24678d1b9026._comment10
-rw-r--r--doc/forum/Error_adding_ssh_remote_in_assistant.mdwn15
-rw-r--r--doc/forum/Error_adding_ssh_remote_in_assistant/comment_1_eecc0660db4083cc91c5330587f74610._comment8
-rw-r--r--doc/forum/Error_adding_ssh_remote_in_assistant/comment_2_3e6aad22e8020b12ff7ef914b75281d1._comment8
-rw-r--r--doc/forum/Error_adding_ssh_remote_in_assistant/comment_3_3ea529e16502071fc0980c6d5c60a036._comment8
-rw-r--r--doc/forum/External_drive_syncs_git-annex_branch_but_not_master_branch.mdwn1
-rw-r--r--doc/forum/External_drive_syncs_git-annex_branch_but_not_master_branch/comment_1_9a909e3d89061adacbd8ed370520250c._comment9
-rw-r--r--doc/forum/External_drive_syncs_git-annex_branch_but_not_master_branch/comment_2_0dd489b264374b7b1065b89e1ff7561b._comment8
-rw-r--r--doc/forum/Feature_Request:_add_filename_to_hash_objects.mdwn6
-rw-r--r--doc/forum/Feature_Request:_add_filename_to_hash_objects/comment_1_73dc0a9cad486cf2d34faf064c6193b1._comment10
-rw-r--r--doc/forum/Feature_Request:_add_filename_to_hash_objects/comment_2_f818b3ecfeb1d1dd83df4668c061718a._comment8
-rw-r--r--doc/forum/Feature_request:_Multiple_concurrent_transfers.mdwn19
-rw-r--r--doc/forum/Feature_request:_git_annex_copy_--auto_does_the_right_thing.mdwn5
-rw-r--r--doc/forum/Feature_request:_git_annex_copy_--auto_does_the_right_thing/comment_1_bbac7d0810a79eb1f42a01e1b31d5c4c._comment12
-rw-r--r--doc/forum/Feature_request:_webapp_support_for_centralized_bare_repos.mdwn1
-rw-r--r--doc/forum/First_attempt_at_an_OSX_launcher___40__.app__41__.mdwn3
-rw-r--r--doc/forum/First_attempt_at_an_OSX_launcher___40__.app__41__/comment_1_97c261b9080c5ecc5424683066bbe05b._comment14
-rw-r--r--doc/forum/First_attempt_at_an_OSX_launcher___40__.app__41__/comment_2_ae45f9703b635c235409682cf252d36c._comment8
-rw-r--r--doc/forum/First_attempt_at_an_OSX_launcher___40__.app__41__/comment_3_066ca31a2e5dfe55a58092ba85231c7c._comment10
-rw-r--r--doc/forum/First_attempt_at_an_OSX_launcher___40__.app__41__/comment_4_a0a9f7f44cadb8036fcddfc21bb0781f._comment10
-rw-r--r--doc/forum/First_attempt_at_an_OSX_launcher___40__.app__41__/comment_5_92240b3f8629f1f2bbe1829700082a79._comment10
-rw-r--r--doc/forum/Fixing_up_corrupt_annexes.mdwn10
-rw-r--r--doc/forum/Fixing_up_corrupt_annexes/comment_1_cea21f96bcfb56aaab7ea03c1c804d2d._comment7
-rw-r--r--doc/forum/Fixing_up_corrupt_annexes/comment_2_5cdd2fcfa61b3f6255e5ad63a3ab00ce._comment8
-rw-r--r--doc/forum/Forcing_one_repo_to_contain_a_copy_of_all_files.mdwn1
-rw-r--r--doc/forum/Forcing_one_repo_to_contain_a_copy_of_all_files/comment_1_702b1b94c735f1b9cde16daa77a80c12._comment8
-rw-r--r--doc/forum/Forcing_one_repo_to_contain_a_copy_of_all_files/comment_2_3df7fcbcd482bb9377ead238b314995b._comment8
-rw-r--r--doc/forum/GPG_passphrase_handling.txt76
-rw-r--r--doc/forum/GPG_passphrase_handling/comment_1_11ba130e8bea6698858d0a1a5b01830f._comment15
-rw-r--r--doc/forum/GPG_passphrase_handling/comment_2_ef9d58d15b7bbe0b3c7140bb01d73a31._comment15
-rw-r--r--doc/forum/GPG_passphrase_handling/comment_3_84eb129c8483b87b3ae6ecaf8b4a8309._comment12
-rw-r--r--doc/forum/GPG_passphrase_handling/comment_4_8724297f6d7ac140ab395a940bab0d7d._comment8
-rw-r--r--doc/forum/Getting_started_with_Amazon_S3.mdwn28
-rw-r--r--doc/forum/Getting_started_with_Amazon_S3/comment_1_f50883133d5d4903cc95c0dcaa52d052._comment10
-rw-r--r--doc/forum/Getting_started_with_Amazon_S3/comment_2_e90aa3259d9a12cd67daa27d42d69ab5._comment8
-rw-r--r--doc/forum/Getting_started_with_Amazon_S3/comment_3_c3adce7c0f29e71ed9dd07103ede2c1a._comment8
-rw-r--r--doc/forum/Git_Annex_Assistant:_How_to_add_a_remote__63__.mdwn11
-rw-r--r--doc/forum/Git_Annex_Assistant:_How_to_add_a_remote__63__/comment_1_d0a3d0090928790d5a05e9f8e5f05320._comment12
-rw-r--r--doc/forum/Git_Annex_Transfer_Protocols.mdwn9
-rw-r--r--doc/forum/Git_Annex_Transfer_Protocols/comment_1_a870ec991078c95a6bb683d6962ab56e._comment8
-rw-r--r--doc/forum/Git_Annex_Transfer_Protocols/comment_2_71419376ef50a679ea8f0f9e16991c17._comment8
-rw-r--r--doc/forum/Git_Annex_Transfer_Protocols/comment_3_fea43664a500111ca99f4043e0dadb14._comment8
-rw-r--r--doc/forum/Git_Annex_Transfer_Protocols/comment_4_56fb2dab1d4030c9820be32b495afdf0._comment8
-rw-r--r--doc/forum/Git_Annex_Transfer_Protocols/comment_5_a6ec9c5a4a3c0bac1df87f1df9be140b._comment8
-rw-r--r--doc/forum/Git_Annex_Transfer_Protocols/comment_6_1678452fb7114aeabcf0cc3d5f6c69b0._comment8
-rw-r--r--doc/forum/Git_annex___39__corrupting__39___itself.mdwn34
-rw-r--r--doc/forum/Git_annex___39__corrupting__39___itself/comment_1_bcf50a215e2f8771e098aadfff4c300c._comment43
-rw-r--r--doc/forum/Git_annex___39__corrupting__39___itself/comment_3_75f957e7be6c1ad8936c0a2a5374db3e._comment20
-rw-r--r--doc/forum/Git_annex___39__corrupting__39___itself/comment_3_ab062b1df3b55fd49852a6220c98249e._comment10
-rw-r--r--doc/forum/Git_annex_assistant_in_command_line.mdwn2
-rw-r--r--doc/forum/Git_annex_assistant_in_command_line/comment_1_ce05226307ade8db90ada2dbf290bd58._comment10
-rw-r--r--doc/forum/Git_annex_assistant_on_EC2.mdwn5
-rw-r--r--doc/forum/Git_annex_assistant_on_EC2/comment_1_bbdb4611373117a2176c225378110a05._comment8
-rw-r--r--doc/forum/Git_annex_assistant_on_EC2/comment_2_614ed11f7134137d6376d36a61c293f5._comment8
-rw-r--r--doc/forum/Git_annex_on_Windows.mdwn11
-rw-r--r--doc/forum/Git_annex_on_Windows/comment_1_da24ba0219a164f9ab93fe75dd85127e._comment11
-rw-r--r--doc/forum/Git_annex_on_Windows/comment_2_c0880ce3ee13d388ab5b46a740170845._comment50
-rw-r--r--doc/forum/Git_annex_on_Windows/comment_3_70c22716fde60d14fd0c7e74acf4a224._comment11
-rw-r--r--doc/forum/Git_annex_on_Windows/comment_4_b9232deab6bc5036d7339aa202013218._comment12
-rw-r--r--doc/forum/Git_annex_on_Windows/comment_5_27af3c431b50b540d2bd1d3af3f21080._comment8
-rw-r--r--doc/forum/Git_annex_syncing_speed__44___possible__63__.mdwn21
-rw-r--r--doc/forum/Git_annex_syncing_speed__44___possible__63__/comment_1_8aa224b3016dc38e4cea8ee1865a3ab6._comment12
-rw-r--r--doc/forum/Git_repos_in_git_annex__63__.mdwn7
-rw-r--r--doc/forum/Git_repos_in_git_annex__63__/comment_1_8aaa0d83e8fcd5997f6b0097f3b21622._comment14
-rw-r--r--doc/forum/Git_repositories_in_the_annex__63__.mdwn5
-rw-r--r--doc/forum/Handling_web_special_remote_when_content_changes__63__.mdwn19
-rw-r--r--doc/forum/Handling_web_special_remote_when_content_changes__63__/comment_1_05ee6a1b1943ef3c90634e52233bde1c._comment12
-rw-r--r--doc/forum/Handling_web_special_remote_when_content_changes__63__/comment_2_48d82e391812d8ec0d4e6562d0607fe7._comment10
-rw-r--r--doc/forum/Help_Windows_walkthrough.mdwn177
-rw-r--r--doc/forum/Help_Windows_walkthrough/comment_1_5fc22393a1b28235eabb2871ad83d0a7._comment12
-rw-r--r--doc/forum/Help_on_my_usecase.mdwn22
-rw-r--r--doc/forum/Help_on_my_usecase/comment_1_a35b35c7927640f21d47c3df4f91dabb._comment12
-rw-r--r--doc/forum/Help_with_syncing_file_contents.mdwn68
-rw-r--r--doc/forum/Help_with_syncing_file_contents/comment_1_7ec34de3140983739080115c82966bf5._comment18
-rw-r--r--doc/forum/Help_with_syncing_file_contents/comment_2_7dba58d3c62d6f64a270298e4e4329a4._comment10
-rw-r--r--doc/forum/Help_with_syncing_file_contents/comment_3_b26cfa20dc81517d93e760f4809bdc24._comment12
-rw-r--r--doc/forum/How_do_I_cleanly_remove_an_Android_git-annex_installation__63__.mdwn1
-rw-r--r--doc/forum/How_do_I_cleanly_remove_an_Android_git-annex_installation__63__/comment_1_e14757c2c106770c2d7069ace4987b3b._comment8
-rw-r--r--doc/forum/How_do_I_dropunused_with_an_rsync_remote__63__.mdwn3
-rw-r--r--doc/forum/How_do_I_dropunused_with_an_rsync_remote__63__/comment_1_8db3cb5348b845eb99c2c829957db9ea._comment8
-rw-r--r--doc/forum/How_do_I_dropunused_with_an_rsync_remote__63__/comment_2_6cc909d9d74bc1ccb8a7b0d7d234c7cd._comment10
-rw-r--r--doc/forum/How_do_I_dropunused_with_an_rsync_remote__63__/comment_3_f24d678e4192a70322aa164ed9b71fc8._comment8
-rw-r--r--doc/forum/How_do_I_dropunused_with_an_rsync_remote__63__/comment_4_9233decd0aaf9211447f36e0d9346445._comment15
-rw-r--r--doc/forum/How_do_I_dropunused_with_an_rsync_remote__63__/comment_5_e1deb110f752e5495d5c77ec444abac5._comment8
-rw-r--r--doc/forum/How_do_you_know_when_something_fails_a_fsck__63__.mdwn4
-rw-r--r--doc/forum/How_do_you_know_when_something_fails_a_fsck__63__/comment_1_1c14981916dd55376d5e9f95023556cb._comment32
-rw-r--r--doc/forum/How_does_one_change_git-annex_assistant__39__s_web_browser__63__.mdwn7
-rw-r--r--doc/forum/How_does_one_change_git-annex_assistant__39__s_web_browser__63__/comment_1_f4402eabda2327da3a0bbc64ed3baf9a._comment12
-rw-r--r--doc/forum/How_does_one_change_git-annex_assistant__39__s_web_browser__63__/comment_2_cdb41f2c7b6bc5bf40d88582dcbf45aa._comment10
-rw-r--r--doc/forum/How_does_one_change_git-annex_assistant__39__s_web_browser__63__/comment_3_ca75e928c245eb23a02b5f40ec69cbb1._comment8
-rw-r--r--doc/forum/How_does_one_change_git-annex_assistant__39__s_web_browser__63__/comment_4_1635f136909711295b9b70d1255e0378._comment11
-rw-r--r--doc/forum/How_does_one_change_git-annex_assistant__39__s_web_browser__63__/comment_5_ee0cbe9498c518de98480a2ad229f685._comment10
-rw-r--r--doc/forum/How_does_one_change_git-annex_assistant__39__s_web_browser__63__/comment_6_799b9d9d3ffbc2c14eca8d442e2aff8c._comment11
-rw-r--r--doc/forum/How_to_cancel_an_add__63__.mdwn5
-rw-r--r--doc/forum/How_to_cancel_an_add__63__/comment_1_f768ce5dc7c76f96ee6eb352f167be44._comment8
-rw-r--r--doc/forum/How_to_copy__47__duplicate_all_data_from_rsync__47__ssh_backend_to_other_backend__63__.mdwn14
-rw-r--r--doc/forum/How_to_copy__47__duplicate_all_data_from_rsync__47__ssh_backend_to_other_backend__63__/comment_1_7973928b1aa9e0fcfeb6bf80885441f5._comment10
-rw-r--r--doc/forum/How_to_deal_with_renamed_files_in_direct_mode__63__.mdwn3
-rw-r--r--doc/forum/How_to_deal_with_renamed_files_in_direct_mode__63__/comment_1_fe38fedbbc9e4a9e13bf19950e63c7ac._comment10
-rw-r--r--doc/forum/How_to_define_an_alternative_remote_url_for_a_git_remote_repository__63__.mdwn7
-rw-r--r--doc/forum/How_to_define_an_alternative_remote_url_for_a_git_remote_repository__63__/comment_1_52918b5ec25e55837215439fe1bb1a14._comment8
-rw-r--r--doc/forum/How_to_define_an_alternative_remote_url_for_a_git_remote_repository__63__/comment_2_3a1567c9f484b5e12e5560cdcc2cfddd._comment8
-rw-r--r--doc/forum/How_to_define_an_alternative_remote_url_for_a_git_remote_repository__63__/comment_3_48c3a80c14a85f27d742482b2ccbe628._comment8
-rw-r--r--doc/forum/How_to_delete_a_remote__63__.mdwn1
-rw-r--r--doc/forum/How_to_delete_a_remote__63__/comment_1_8cba186bb67079ff41bf6d0b04613f4a._comment10
-rw-r--r--doc/forum/How_to_delete_a_remote__63__/comment_2_33c429ffa7e9e2ed9c5fac760ee8e82c._comment12
-rw-r--r--doc/forum/How_to_delete_a_remote__63__/comment_3_e9c5508092ca2983f458b16bf1e07082._comment14
-rw-r--r--doc/forum/How_to_destroy_a_master_annex_and_all_remotes_with_git_annex_assistant_and_ext4.mdwn28
-rw-r--r--doc/forum/How_to_destroy_a_master_annex_and_all_remotes_with_git_annex_assistant_and_ext4/comment_1_42ca6cfbbb79fe63514805b8119ac16b._comment8
-rw-r--r--doc/forum/How_to_destroy_a_master_annex_and_all_remotes_with_git_annex_assistant_and_ext4/comment_2_c94ce6a9767c624e2445a7d9eea40396._comment29
-rw-r--r--doc/forum/How_to_destroy_a_master_annex_and_all_remotes_with_git_annex_assistant_and_ext4/comment_3_bcda51053b62bbb20ce71a59469e1b26._comment10
-rw-r--r--doc/forum/How_to_destroy_a_master_annex_and_all_remotes_with_git_annex_assistant_and_ext4/comment_4_48e5b9eae920e5f13812de8d6f6bc640._comment8
-rw-r--r--doc/forum/How_to_destroy_a_master_annex_and_all_remotes_with_git_annex_assistant_and_ext4/comment_5_787c0bfdc1d309db1486c3a37723a957._comment13
-rw-r--r--doc/forum/How_to_destroy_a_master_annex_and_all_remotes_with_git_annex_assistant_and_ext4/comment_6_8894beb06443f234e9200b03b5f3badf._comment8
-rw-r--r--doc/forum/How_to_destroy_a_master_annex_and_all_remotes_with_git_annex_assistant_and_ext4/comment_7_457f62ee3e58f68a55f66c5bde6002fd._comment10
-rw-r--r--doc/forum/How_to_destroy_a_master_annex_and_all_remotes_with_git_annex_assistant_and_ext4/comment_8_bd2b412116a66107bc0ff0efd7e39a58._comment10
-rw-r--r--doc/forum/How_to_expire_old_versions_of_files_that_have_been_edited__63__.mdwn7
-rw-r--r--doc/forum/How_to_expire_old_versions_of_files_that_have_been_edited__63__/comment_1_dccf4dc4483d08e5e2936b2cadeafeaf._comment8
-rw-r--r--doc/forum/How_to_expire_old_versions_of_files_that_have_been_edited__63__/comment_2_5710294c1c8652c12b6df2233255a45e._comment8
-rw-r--r--doc/forum/How_to_handle_the_git-annex_branch__63__.mdwn5
-rw-r--r--doc/forum/How_to_handle_the_git-annex_branch__63__/comment_1_800bd55b322e72f229882d7fd3888b14._comment8
-rw-r--r--doc/forum/How_to_make_Maven_releases_work_with_git_annex___63__.mdwn5
-rw-r--r--doc/forum/How_to_make_Maven_releases_work_with_git_annex___63__/comment_1_9298aa55771b68873de02e6a7964bbdc._comment8
-rw-r--r--doc/forum/How_to_prevent_the_assistant_from_downloading_all_data__63__.mdwn9
-rw-r--r--doc/forum/How_to_prevent_the_assistant_from_downloading_all_data__63__/comment_1_fd8b287758ad77b3527ae71017cffabf._comment8
-rw-r--r--doc/forum/How_to_prevent_the_assistant_from_downloading_all_data__63__/comment_2_e8e75b4451aaf55461edf2f3d68797ed._comment8
-rw-r--r--doc/forum/How_to_rename_a_remote__63__.mdwn1
-rw-r--r--doc/forum/How_to_rename_a_remote__63__/comment_1_a9bfbd82f7bb47661f0d9e0e0d904332._comment28
-rw-r--r--doc/forum/How_to_restore_symlinks.mdwn1
-rw-r--r--doc/forum/How_to_restore_symlinks/comment_1_c67e752cf7d5431096fab4b3304790a7._comment11
-rw-r--r--doc/forum/How_to_restore_symlinks/comment_2_f9ec6096595e2c149c48924e3b54542f._comment14
-rw-r--r--doc/forum/How_to_restore_symlinks/comment_3_4ff80729787a2a4e2baf05dd1db37da3._comment12
-rw-r--r--doc/forum/How_to_retroactively_annex_a_file_already_in_a_git_repo.mdwn5
-rw-r--r--doc/forum/How_to_set_up_two_assistants_with_one_shared_transfer_repository__63__.mdwn15
-rw-r--r--doc/forum/How_to_set_up_two_assistants_with_one_shared_transfer_repository__63__/comment_1_bedaf308cfc70b9e751914a400ebcbc2._comment10
-rw-r--r--doc/forum/How_to_set_up_two_assistants_with_one_shared_transfer_repository__63__/comment_2_d665b1514253c8aa487ebf8b2728e3b1._comment10
-rw-r--r--doc/forum/How_to_set_up_two_assistants_with_one_shared_transfer_repository__63__/comment_3_aef42387a3673ab6710fb23e878d7e17._comment10
-rw-r--r--doc/forum/How_to_set_up_two_assistants_with_one_shared_transfer_repository__63__/comment_4_bfbcc041db472f4808979e6b3d7c4be2._comment10
-rw-r--r--doc/forum/Howto_remove_a_repository__63__.mdwn4
-rw-r--r--doc/forum/Howto_remove_a_repository__63__/comment_1_b55fa4e92bb457ecaa5ca8f5cee7be1d._comment8
-rw-r--r--doc/forum/Howto_remove_unused_files.mdwn31
-rw-r--r--doc/forum/Howto_remove_unused_files/comment_1_f2a7948268ce3cb3967a9fdd8ccc570a._comment16
-rw-r--r--doc/forum/Howto_remove_unused_files/comment_2_9b4d198c2d8a52adef3d166a8196fc0d._comment8
-rw-r--r--doc/forum/Howto_remove_unused_files/comment_3_441d10901d5c055ac3ed2a6cb61c075c._comment8
-rw-r--r--doc/forum/Import_options.txt14
-rw-r--r--doc/forum/Import_options/comment_1_118a5f978090a3909299876a01c0adec._comment21
-rw-r--r--doc/forum/Import_options/comment_2_21da91f08cb6b28ae3e79ade033db516._comment17
-rw-r--r--doc/forum/Is_an_automagic_upgrade_of_the_object_directory_safe__63__.mdwn9
-rw-r--r--doc/forum/Is_an_automagic_upgrade_of_the_object_directory_safe__63__/comment_1_c25900b9d2d62cc0b8c77150bcfebadf._comment13
-rw-r--r--doc/forum/Is_git-annex_in_a_precarious_state_before_the_initial_commit__63__.mdwn18
-rw-r--r--doc/forum/Is_git-annex_in_a_precarious_state_before_the_initial_commit__63__/comment_1_f9decde3955f10148febc4646fba5a68._comment12
-rw-r--r--doc/forum/Is_git-annex_in_a_precarious_state_before_the_initial_commit__63__/comment_2_ed32a48edce4f150bedf24cfe91de254._comment8
-rw-r--r--doc/forum/Is_git-annex_in_a_precarious_state_before_the_initial_commit__63__/comment_3_ef9618850e5e688bac3c646983f00ed8._comment10
-rw-r--r--doc/forum/Is_git-annex_in_a_precarious_state_before_the_initial_commit__63__/comment_4_4bf460c5826c36b205e418c4f3f7d770._comment15
-rw-r--r--doc/forum/Is_it_possible_to_make_git-sync_not_nullify_symlinks__63__.mdwn23
-rw-r--r--doc/forum/Is_it_possible_to_make_git-sync_not_nullify_symlinks__63__/comment_1_d6f2d2cdc5f4ffde9eee9f3a8c215a06._comment10
-rw-r--r--doc/forum/Lacking_webapp_on_Trisquel__47__Ubuntu_Precise.mdwn7
-rw-r--r--doc/forum/Lacking_webapp_on_Trisquel__47__Ubuntu_Precise/comment_1_6bd27bd31833336c1df783253378ccae._comment10
-rw-r--r--doc/forum/Let_watch_selectively_annex_files.mdwn27
-rw-r--r--doc/forum/Let_watch_selectively_annex_files/comment_1_8379de87d16502d9aadf252da01e4d9a._comment10
-rw-r--r--doc/forum/Let_watch_selectively_annex_files/comment_2_2219ff6b4dc927eb2a299cd1af90aed8._comment8
-rw-r--r--doc/forum/Links_or_actual_files__63___Confused__33__.mdwn21
-rw-r--r--doc/forum/Links_or_actual_files__63___Confused__33__/comment_1_779cee2448d7070b1dd636d01296c01e._comment8
-rw-r--r--doc/forum/Links_or_actual_files__63___Confused__33__/comment_2_bccda88697ab7beec0b9fe9ee0230688._comment18
-rw-r--r--doc/forum/Links_or_actual_files__63___Confused__33__/comment_3_c2a9da3f03b55ff294dc0d2010380119._comment8
-rw-r--r--doc/forum/Local_and_remote_in_direct_mode.mdwn7
-rw-r--r--doc/forum/Local_and_remote_in_direct_mode/comment_1_45f89ebcb6092d1b2582feebc8a5e9d7._comment15
-rw-r--r--doc/forum/Looking_at_the_webapp_on_OSX.mdwn18
-rw-r--r--doc/forum/Looking_at_the_webapp_on_OSX/comment_1_68820f2f469356633c1abb18a47e0c59._comment12
-rw-r--r--doc/forum/Looking_at_the_webapp_on_OSX/comment_2_4ce86546d8a135df9cfab46b4612fa0b._comment23
-rw-r--r--doc/forum/Looking_at_the_webapp_on_OSX/comment_3_6d398a2cceff14a1b774b85ee1725073._comment12
-rw-r--r--doc/forum/Looking_at_the_webapp_on_OSX/comment_4_5e503787a4b1d3534c5e20da5480b763._comment8
-rw-r--r--doc/forum/Looking_at_the_webapp_on_OSX/comment_5_c735841bc230efc61594ea013fc2902b._comment8
-rw-r--r--doc/forum/Looking_at_the_webapp_on_OSX/comment_6_0e489fbfc89d282e9eb47f1b814ff70c._comment8
-rw-r--r--doc/forum/Make_whereis_output_more_compact.mdwn13
-rw-r--r--doc/forum/Making_git-annex_a_self-funded_project__63__.mdwn10
-rw-r--r--doc/forum/Making_git-annex_a_self-funded_project__63__/comment_1_4a1ba95b7231ba973ddb672d2419e28c._comment8
-rw-r--r--doc/forum/Making_git-annex_a_self-funded_project__63__/comment_2_7c476ae92e63c991f229708678874ca2._comment8
-rw-r--r--doc/forum/Making_git-annex_less_necessary.mdwn5
-rw-r--r--doc/forum/Making_git-annex_less_necessary/comment_1_03faaa3866778d24cd03887b85dc9954._comment12
-rw-r--r--doc/forum/Making_git-annex_less_necessary/comment_2_2db02a94dffd525885c9d7fc6c5fa464._comment12
-rw-r--r--doc/forum/Making_git-annex_less_necessary/comment_3_429ec656e0ac02f98843f8d7f3c02d6a._comment11
-rw-r--r--doc/forum/Making_git-annex_less_necessary/comment_4_384813dd022dfd9c1ef14e0f1479a123._comment18
-rw-r--r--doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__.mdwn118
-rw-r--r--doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_10_a061d300b718ad943c940e122cc57220._comment23
-rw-r--r--doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_11_76529080054407570611b4357ce4f3ed._comment8
-rw-r--r--doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_12_9acf5ce41a023f3848a51891cceeb51b._comment21
-rw-r--r--doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_1_25e65ee3949e7d918376298cf11585f2._comment10
-rw-r--r--doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_2_8a71ca048f9de29a198a6afb17d5315e._comment11
-rw-r--r--doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_3_e3d1d3a3d3d831432ec940a8ab6f31e9._comment14
-rw-r--r--doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_4_26a33eae98b4faaf6baf6635e3d28a8f._comment27
-rw-r--r--doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_5_49ac298d39c824b0e52a239961463e09._comment14
-rw-r--r--doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_6_55a4a3616ea59654da1c2f9902561e3b._comment13
-rw-r--r--doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_7_92a2af3e0e328bb48bcc67a69187ee57._comment13
-rw-r--r--doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_8_f6e39e71882d55cdc061166aea3e2bd3._comment26
-rw-r--r--doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_9_6c45a6264d69e22800c329a0f8a2d470._comment8
-rw-r--r--doc/forum/Managing_multiple_annexes_with_assistant__63__.mdwn13
-rw-r--r--doc/forum/Managing_multiple_annexes_with_assistant__63__/comment_1_ba8c70e4a46441b48ad910625636eee5._comment8
-rw-r--r--doc/forum/Managing_multiple_annexes_with_assistant__63__/comment_2_4b4f0a7d84a51ae92536e2c190256069._comment10
-rw-r--r--doc/forum/Managing_multiple_annexes_with_assistant__63__/comment_3_86daadc565f96db5db13b6dbcbc66db3._comment8
-rw-r--r--doc/forum/Managing_multiple_annexes_with_assistant__63__/comment_4_e43d71ddfdfdb7bcb13bfb894de6a5ec._comment8
-rw-r--r--doc/forum/Managing_multiple_annexes_with_assistant__63__/comment_5_e94d33be83b45918d1a39d6e16fba4b4._comment8
-rw-r--r--doc/forum/Managing_multiple_repositories_concurrently__63__.mdwn5
-rw-r--r--doc/forum/Managing_multiple_repositories_concurrently__63__/comment_1_ebec1ddad71e961cdc9b21cbddfbcdaf._comment10
-rw-r--r--doc/forum/Manual_Setup_of_a_Central_Repo.mdwn1
-rw-r--r--doc/forum/Manual_Setup_of_a_Central_Repo/comment_1_3a163fd5629dc40423f1290a78ae1c07._comment12
-rw-r--r--doc/forum/Manual_mode_option_in_assistant_auto-syncs.mdwn11
-rw-r--r--doc/forum/Manual_mode_option_in_assistant_auto-syncs/comment_1_4a0468b6ca2ffff8ef8f19800597567d._comment10
-rw-r--r--doc/forum/Manual_webapp_behaviour_on_ARM.mdwn15
-rw-r--r--doc/forum/Missing_git-annex.linux__47__runshell.mdwn44
-rw-r--r--doc/forum/Missing_git-annex.linux__47__runshell/comment_1_f29a5105649579ef15e79d983c4e1f8e._comment8
-rw-r--r--doc/forum/Moving_large_files_within_the_repo_without_copying___63__.mdwn19
-rw-r--r--doc/forum/Moving_large_files_within_the_repo_without_copying___63__/comment_1_9e3290138133d5a23a80f72342f47ec4._comment8
-rw-r--r--doc/forum/Moving_large_files_within_the_repo_without_copying___63__/comment_2_232b77894dda51d02cbc34bd25d3213b._comment13
-rw-r--r--doc/forum/Moving_large_files_within_the_repo_without_copying___63__/comment_3_d35ac1bdb3fa6e303ad92348ba174158._comment11
-rw-r--r--doc/forum/Moving_large_files_within_the_repo_without_copying___63__/comment_4_4b443ec6b47eaabe214d0c2222083e4a._comment8
-rw-r--r--doc/forum/Moving_older_version__39__s_file_content_without_doing_checkout.mdwn4
-rw-r--r--doc/forum/Moving_older_version__39__s_file_content_without_doing_checkout/comment_1_f114b75b29123453758b493fae7f5167._comment8
-rw-r--r--doc/forum/Moving_older_version__39__s_file_content_without_doing_checkout/comment_2_e377b7614c2961b460a10e285f3db274._comment10
-rw-r--r--doc/forum/Moving_older_version__39__s_file_content_without_doing_checkout/comment_3_d251958795ab0867c65cf182e54a6ffe._comment8
-rw-r--r--doc/forum/My_first_impressions_after_some_weeks_with_git-annex_assistant.mdwn57
-rw-r--r--doc/forum/My_first_impressions_after_some_weeks_with_git-annex_assistant/comment_1_9d4019a54fb508e286a5d6d2660361d9._comment26
-rw-r--r--doc/forum/My_first_impressions_after_some_weeks_with_git-annex_assistant/comment_2_109534a45881ce94a4586c8a83945f9f._comment85
-rw-r--r--doc/forum/Need_new_build_instructions_for_Debian_stable.mdwn5
-rw-r--r--doc/forum/Need_new_build_instructions_for_Debian_stable/comment_1_8c1eea6dfec8b7e1c7a371b6e9c26118._comment8
-rw-r--r--doc/forum/Need_new_build_instructions_for_Debian_stable/comment_2_f6ff8306c946219dbe39bb8938a349ab._comment21
-rw-r--r--doc/forum/Need_new_build_instructions_for_Debian_stable/comment_3_bcda70cbfc7c1a14fa82da70f9f876e2._comment8
-rw-r--r--doc/forum/Need_some_help_to_fix_my_repository.mdwn31
-rw-r--r--doc/forum/Need_some_help_to_fix_my_repository/comment_1_f0d279c530b796b2c93d793f85d147e8._comment13
-rw-r--r--doc/forum/Need_some_help_to_fix_my_repository/comment_2_a3fcfa1f8eadec5fa8a9efacca174048._comment10
-rw-r--r--doc/forum/Need_some_help_to_fix_my_repository/comment_3_7878f9b76ddfa3392c9ec6a1810cb745._comment10
-rw-r--r--doc/forum/New_git-annex_integration_mode_for_Emacs_users.mdwn3
-rw-r--r--doc/forum/New_special_remote_suggeston_-_clean_directory.mdwn15
-rw-r--r--doc/forum/New_special_remote_suggeston_-_clean_directory/comment_1_4d81941fe53881eebff97109a07ba2f4._comment8
-rw-r--r--doc/forum/New_special_remote_suggeston_-_clean_directory/comment_2_660a5b764ad42468154b2bb94f8ec004._comment8
-rw-r--r--doc/forum/New_user_misunderstandings.mdwn24
-rw-r--r--doc/forum/New_user_misunderstandings/comment_1_c1785924109b5d5cde9aa3d3460cf955._comment10
-rw-r--r--doc/forum/Newbie_stuck_at___34__Unable_to_connect_to_the_Jabber_server__34__.mdwn5
-rw-r--r--doc/forum/Newbie_stuck_at___34__Unable_to_connect_to_the_Jabber_server__34__/comment_1_59158afcedac18a7285d57491b2a468a._comment8
-rw-r--r--doc/forum/Newbie_stuck_at___34__Unable_to_connect_to_the_Jabber_server__34__/comment_2_2a70ac08bb95774415b09dab7d7f8605._comment8
-rw-r--r--doc/forum/Newbie_stuck_at___34__Unable_to_connect_to_the_Jabber_server__34__/comment_3_92a52b523ed4c68b70ddcabc2a050b76._comment12
-rw-r--r--doc/forum/Newbie_stuck_at___34__Unable_to_connect_to_the_Jabber_server__34__/comment_4_c52a75761ea107f6d69c09bac64f0f0a._comment12
-rw-r--r--doc/forum/Newbie_stuck_at___34__Unable_to_connect_to_the_Jabber_server__34__/comment_5_2685e3a87464ccd37d593516d94ba5cf._comment10
-rw-r--r--doc/forum/No_SSL_traffic_for_S3__63__.mdwn8
-rw-r--r--doc/forum/No_SSL_traffic_for_S3__63__/comment_1_f509bf273896180e6df8c771438dd093._comment11
-rw-r--r--doc/forum/No_SSL_traffic_for_S3__63__/comment_2_358635d19c82202c63014ca84de7fc3b._comment8
-rw-r--r--doc/forum/Not_sure_how_to_get_my_s3_remote_back.mdwn31
-rw-r--r--doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_10_ed35a6ec605e8f79ec107856af6d1a46._comment18
-rw-r--r--doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_11_e48b6efa42159dc83e1be11bfb54abcd._comment14
-rw-r--r--doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_12_b58232d0e3fa4649565c0c7d4ce2e82e._comment31
-rw-r--r--doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_13_85368b60091dc3ce2efb58013ffe9f83._comment10
-rw-r--r--doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_14_e65281bef23e0076936c508728a87897._comment25
-rw-r--r--doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_1_fffb59ad5a197d2980dd0ec35cf4aafa._comment10
-rw-r--r--doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_2_0cfcc2075bff556b9fde5acc3dc1d599._comment8
-rw-r--r--doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_3_6fe2ff1282fb14a4ce26ef8dc775d07e._comment8
-rw-r--r--doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_4_64338d2d77dcbabd16b55eb145f40dc6._comment12
-rw-r--r--doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_5_dd66c9ea0c83388f6826751944330d10._comment16
-rw-r--r--doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_6_dc0c5e395e4c443b7227afdb157194e5._comment10
-rw-r--r--doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_7_3c0ea4c76cdd889707f7308576e3efa0._comment65
-rw-r--r--doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_8_36519ee4499a19f0864e4fcd264e9933._comment20
-rw-r--r--doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_9_85b23f375e53469fb09b24b945b3aba9._comment17
-rw-r--r--doc/forum/OSX_Mavericks_anyone__63__.mdwn3
-rw-r--r--doc/forum/OSX_Mavericks_anyone__63__/comment_1_3075b02aeb57adcbf4addf9fb4c123ba._comment11
-rw-r--r--doc/forum/OSX_Mavericks_anyone__63__/comment_2_c2b6110fc4a3d3481ed8a4b48efb9635._comment17
-rw-r--r--doc/forum/OSX_Mavericks_anyone__63__/comment_3_7df9ba63cb1f385681242b4b58d6a87c._comment8
-rw-r--r--doc/forum/OSX_Mavericks_anyone__63__/comment_4_740fee31c4ca9d84428f97f63ffc075a._comment8
-rw-r--r--doc/forum/OSX__39__s_default_sshd_behaviour_has_limited_paths_set.mdwn12
-rw-r--r--doc/forum/OSX__39__s_haskell-platform_statically_links_things.mdwn17
-rw-r--r--doc/forum/OpenOffice___47___Libre_Office.mdwn5
-rw-r--r--doc/forum/OpenOffice___47___Libre_Office/comment_1_98ed542fedd820d47bf8deb7d3232725._comment8
-rw-r--r--doc/forum/OpenOffice___47___Libre_Office/comment_2_f313fdaa23863c2ae99cfbfe9ec2e1e0._comment8
-rw-r--r--doc/forum/Out_of_memory_error_in_fsck__44___whereis__44___find_and_status_cmds.mdwn5
-rw-r--r--doc/forum/Overwriting_data_without_getting_it.mdwn3
-rw-r--r--doc/forum/Overwriting_data_without_getting_it/comment_1_f1c0199ee9bffcc84287370b89361294._comment26
-rw-r--r--doc/forum/Overwriting_data_without_getting_it/comment_2_6a1d08dbca206129ef6cf8aa97daeee1._comment8
-rw-r--r--doc/forum/Overwriting_data_without_getting_it/comment_3_52958e76e506fdbb6b533681ab619b3b._comment8
-rw-r--r--doc/forum/Permission_denied___40__publickey__41___On_second_Step_...___63__.mdwn36
-rw-r--r--doc/forum/Permission_denied___40__publickey__41___On_second_Step_...___63__/comment_1_6c74f0b43c457fe97b2d8630ca4fde29._comment10
-rw-r--r--doc/forum/Permission_denied___40__publickey__41___On_second_Step_...___63__/comment_2_b7a384e853e1756a684774348fad29e6._comment22
-rw-r--r--doc/forum/Permission_denied___40__publickey__41___On_second_Step_...___63__/comment_3_3a8a7f51cb04a92c576549d379b57248._comment12
-rw-r--r--doc/forum/Permission_denied___40__publickey__41___On_second_Step_...___63__/comment_4_582ad3ba0c62a77b08a10b37a780c670._comment15
-rw-r--r--doc/forum/Please_fix_compatibility_with_ghc_7.0.mdwn1
-rw-r--r--doc/forum/Please_fix_compatibility_with_ghc_7.0/comment_1_d1d10217ebd0151e947b3a6cd37399ce._comment8
-rw-r--r--doc/forum/Please_publish_new_releases_not_shorter_than_11_days.mdwn6
-rw-r--r--doc/forum/Please_publish_new_releases_not_shorter_than_11_days/comment_1_da3d39de5be47ebe8b25a42ed1f36510._comment8
-rw-r--r--doc/forum/Podcast_syncing_use-case.mdwn34
-rw-r--r--doc/forum/Podcast_syncing_use-case/comment_1_ace6f9d3a950348a3ac0ff592b62e786._comment10
-rw-r--r--doc/forum/Podcast_syncing_use-case/comment_2_930a6620b4d516e69ed952f9da5371bb._comment8
-rw-r--r--doc/forum/Poor_man__39__s_IMAP.mdwn6
-rw-r--r--doc/forum/Poor_man__39__s_IMAP/comment_1_258ff23c462dc88b88ced405c4f5040f._comment11
-rw-r--r--doc/forum/Poor_man__39__s_IMAP/comment_2_c88d1abdda4cb526a6ee45a710c75bc4._comment10
-rw-r--r--doc/forum/Poor_man__39__s_IMAP/comment_3_3847e371db1c2788c075e7dca1fbd33e._comment8
-rw-r--r--doc/forum/Poor_man__39__s_IMAP/comment_4_cf6cc21f2cf2aa5c949844e24a7b4075._comment8
-rw-r--r--doc/forum/Poor_man__39__s_IMAP/comment_5_d861fa69475ce526841b3195be8ee356._comment10
-rw-r--r--doc/forum/Poor_man__39__s_IMAP/comment_6_1e81bd4bb62652bc674cdcd7ed57ac5c._comment12
-rw-r--r--doc/forum/Poor_man__39__s_IMAP/comment_7_b3929281dff6078d77f1b9ae42e25bb6._comment16
-rw-r--r--doc/forum/Poor_man__39__s_IMAP/comment_8_69506e8c519196f44b9ed15b32f00106._comment22
-rw-r--r--doc/forum/Post-Kickstarter.mdwn5
-rw-r--r--doc/forum/Preserving_file_access_rights_in_directory_tree_below_objects__47__.mdwn77
-rw-r--r--doc/forum/Preserving_file_access_rights_in_directory_tree_below_objects__47__/comment_1_5dd978f9b5a0771f44ab9e086bf5a07f._comment14
-rw-r--r--doc/forum/Preserving_file_access_rights_in_directory_tree_below_objects__47__/comment_2_9f51947b35ee04e473655e20d56c740a._comment16
-rw-r--r--doc/forum/Problem_compiling_current_master.mdwn12
-rw-r--r--doc/forum/Problem_compiling_current_master/comment_1_135df61ec850c06e3b48ccfef7b5b031._comment8
-rw-r--r--doc/forum/Problem_compiling_current_master/comment_2_fb3e27b6014e84bd919a7a4a95e39ef9._comment20
-rw-r--r--doc/forum/Problem_compiling_current_master/comment_3_b737b3945103c5e2aa798b4e65fbce06._comment8
-rw-r--r--doc/forum/Problem_compiling_current_master/comment_4_28c1b335ae388d4e1f22b711ac1c001f._comment8
-rw-r--r--doc/forum/Problems_syncing_with_box.com.mdwn26
-rw-r--r--doc/forum/Problems_syncing_with_box.com/comment_1_8db642849da4d42cd9a43142e2b7cb70._comment12
-rw-r--r--doc/forum/Problems_syncing_with_box.com/comment_2_cd18f33647aebc04af5469e4ce1fbcd2._comment11
-rw-r--r--doc/forum/Problems_using_submodules_with_git-annex__63__.mdwn1
-rw-r--r--doc/forum/Problems_using_submodules_with_git-annex__63__/comment_1_c7a927736d419d3c31c912001ff16ee4._comment7
-rw-r--r--doc/forum/Problems_with_large_numbers_of_files.mdwn8
-rw-r--r--doc/forum/Problems_with_large_numbers_of_files/comment_1_08791cb78b982087c2a07316fe3ed46c._comment22
-rw-r--r--doc/forum/Problems_with_large_numbers_of_files/comment_2_0392a11219463e40c53bae73c8188b69._comment25
-rw-r--r--doc/forum/Problems_with_large_numbers_of_files/comment_3_537e9884c1488a7a4bcf131ea63b71f7._comment8
-rw-r--r--doc/forum/Problems_with_large_numbers_of_files/comment_4_7cb65d013e72bd2b7e90452079d42ac9._comment29
-rw-r--r--doc/forum/Problems_with_large_numbers_of_files/comment_5_86a42ee3173a5d38f803e64b79496ab3._comment14
-rw-r--r--doc/forum/Problems_with_large_numbers_of_files/comment_6_4551274288383c9cc27cbf85b122d307._comment11
-rw-r--r--doc/forum/Problems_with_large_numbers_of_files/comment_7_d18cf944352f8303799c86f2c0354e8e._comment8
-rw-r--r--doc/forum/Pruning_out_unwanted_Git_objects.mdwn3
-rw-r--r--doc/forum/Pruning_out_unwanted_Git_objects/comment_1_0cf7a12bfa2957260f4b2f79b0cadf2f._comment8
-rw-r--r--doc/forum/Pruning_out_unwanted_Git_objects/comment_2_7472943c02cfe2808b0d566e06caa1a5._comment8
-rw-r--r--doc/forum/Pruning_out_unwanted_Git_objects/comment_3_6a1e7a83d94394454fc085f6d2728cd7._comment8
-rw-r--r--doc/forum/Purge_a_remote.txt2
-rw-r--r--doc/forum/Purge_a_remote/comment_1_78b3b77f457c65d31fd8a5abf714905d._comment8
-rw-r--r--doc/forum/Purge_a_remote/comment_2_dc65719157dee63b3979563ed57ee0ce._comment10
-rw-r--r--doc/forum/Purge_a_remote/comment_3_63e0280273b816fa4b837724e102f813._comment8
-rw-r--r--doc/forum/Purge_a_remote/comment_4_7fad1c4798ca03a4095ac3241c279f6d._comment11
-rw-r--r--doc/forum/Push__47__Pull_with_the_Assistant.mdwn1
-rw-r--r--doc/forum/Push__47__Pull_with_the_Assistant/comment_1_f7b63d379c2d21794adf8658f546f8a7._comment10
-rw-r--r--doc/forum/Push__47__Pull_with_the_Assistant/comment_2_aec8cc20576e7ffd5a8be4348d1a0073._comment21
-rw-r--r--doc/forum/Pushing_git_repo_to_AWS_S3_from_behind_proxy.mdwn9
-rw-r--r--doc/forum/Reappearing_repos_in_webapp_and_vicfg.mdwn43
-rw-r--r--doc/forum/Reappearing_repos_in_webapp_and_vicfg/comment_1_bd977e864ae89816fa7f4ff69879b15f._comment8
-rw-r--r--doc/forum/Reappearing_repos_in_webapp_and_vicfg/comment_2_05749f9e75689d0111339b7126c12300._comment15
-rw-r--r--doc/forum/Reappearing_repos_in_webapp_and_vicfg/comment_3_b1531994eea0fbbf4cb097e604378a53._comment12
-rw-r--r--doc/forum/Reappearing_repos_in_webapp_and_vicfg/comment_4_f1eba3e8aa4116e3c20747ec1d6e24e5._comment12
-rw-r--r--doc/forum/Recommended_number_of_repositories.mdwn4
-rw-r--r--doc/forum/Recommended_number_of_repositories/comment_1_3ef256230756be8a9679b107cdbfd018._comment15
-rw-r--r--doc/forum/Relocating_annex_directory.mdwn1
-rw-r--r--doc/forum/Relocating_annex_directory/comment_1_13ff5438baa1db110beb6aab3a783def._comment11
-rw-r--r--doc/forum/Relocating_annex_directory/comment_2_6d88ff03fcf00ae872442e8a86c968ed._comment10
-rw-r--r--doc/forum/Removing_files_not_found_by_git_annex_unused.mdwn29
-rw-r--r--doc/forum/Removing_files_not_found_by_git_annex_unused/comment_1_420c6230e68de0a0ac7d7da91ac60801._comment8
-rw-r--r--doc/forum/Repo_accessible_from___34__dumb__34___client_without_git-annex.mdwn11
-rw-r--r--doc/forum/Repo_accessible_from___34__dumb__34___client_without_git-annex/comment_1_077c492fd37d335f74a5c886ff0d524f._comment32
-rw-r--r--doc/forum/Repo_accessible_from___34__dumb__34___client_without_git-annex/comment_2_00e6576e3e60d2650461eeb0f918e6e5._comment8
-rw-r--r--doc/forum/Repo_accessible_from___34__dumb__34___client_without_git-annex/comment_3_c36a9562c53ac683b62fc4471405aa2a._comment15
-rw-r--r--doc/forum/Restricting_git-annex-shell_to_a_specific_repository.mdwn25
-rw-r--r--doc/forum/Restricting_git-annex-shell_to_a_specific_repository/comment_1_66544520bff71181e4a03ca583b0b458._comment12
-rw-r--r--doc/forum/Restricting_git-annex-shell_to_a_specific_repository/comment_2_2a210255e8535712c71fa183e56ab600._comment13
-rw-r--r--doc/forum/Restricting_git-annex-shell_to_a_specific_repository/comment_3_52cd4bd9694b2100b0e0dd2eafa9e828._comment8
-rw-r--r--doc/forum/Retrieve_previous_version_in_direct_mode.mdwn5
-rw-r--r--doc/forum/Retrieve_previous_version_in_direct_mode/comment_1_ca3a999ed64c42b8df810115de205d2f._comment12
-rw-r--r--doc/forum/Retrieve_previous_version_in_direct_mode/comment_2_1292b34ff6d9976b2bd08748e1ba4e7a._comment8
-rw-r--r--doc/forum/Retrieve_previous_version_in_direct_mode/comment_3_699e816c0397f6db924feeab906f1151._comment8
-rw-r--r--doc/forum/Retrieve_previous_version_in_direct_mode/comment_4_d900388753de5870b7b9c0e8b8c06ed7._comment8
-rw-r--r--doc/forum/Revert_file_linkage_to_original_files.mdwn9
-rw-r--r--doc/forum/Revert_file_linkage_to_original_files/comment_1_898ca2c9976e92d22470c7404aa9813f._comment10
-rw-r--r--doc/forum/Running_assistant_on_a_server___40__no_X_available__41__.mdwn2
-rw-r--r--doc/forum/Running_assistant_on_a_server___40__no_X_available__41__/comment_1_dd75d78ef63f2689199a302ed1846017._comment8
-rw-r--r--doc/forum/Running_assistant_on_a_server___40__no_X_available__41__/comment_2_df654df60c5fa6a84d786d248928a352._comment11
-rw-r--r--doc/forum/Running_assistant_steps_manually.mdwn20
-rw-r--r--doc/forum/Running_assistant_steps_manually/comment_1_e14e0a1d55d01cb4f67a94bbe349b872._comment20
-rw-r--r--doc/forum/Running_assistant_steps_manually/comment_2_3192f614c929b8060d4fbde56a7adec1._comment14
-rw-r--r--doc/forum/Running_out_of__inodes.mdwn17
-rw-r--r--doc/forum/Running_out_of__inodes/comment_1_abc73d9ad662ef642337b683bf0a0253._comment12
-rw-r--r--doc/forum/Same_Jabber_account_for_different_annexes.mdwn1
-rw-r--r--doc/forum/Same_Jabber_account_for_different_annexes/comment_1_90c3954fe11980eef42b5f5d34f83488._comment8
-rw-r--r--doc/forum/Same_Jabber_account_for_different_annexes/comment_2_802600b3568e5f94d0550092b22975db._comment8
-rw-r--r--doc/forum/Securing_a_shared_ssh_server.mdwn3
-rw-r--r--doc/forum/Securing_a_shared_ssh_server/comment_1_ea971b57d94db5b8d487f728faa5e9a8._comment10
-rw-r--r--doc/forum/Securing_a_shared_ssh_server/comment_2_421a19f6e1fb40db6ee205daf8e3f867._comment15
-rw-r--r--doc/forum/Securing_a_shared_ssh_server/comment_3_acdbf92f646dbbf691621f08b3d94c26._comment12
-rw-r--r--doc/forum/Securing_a_shared_ssh_server/comment_4_67533d08e1b8706b844262e9c483d982._comment15
-rw-r--r--doc/forum/Securing_a_shared_ssh_server/comment_5_bf193e02b388b4358632a169d2425b5c._comment10
-rw-r--r--doc/forum/Securing_a_shared_ssh_server/comment_6_50d391992cd444080ebc70db30b215c5._comment9
-rw-r--r--doc/forum/Setup_of_rsync_special_remote_with_non-standard_ssh_port.mdwn13
-rw-r--r--doc/forum/Setup_of_rsync_special_remote_with_non-standard_ssh_port/comment_1_1eb6990e93ec92cb6fd7dbee59f31072._comment13
-rw-r--r--doc/forum/Setup_of_rsync_special_remote_with_non-standard_ssh_port/comment_2_c85d5167e7ccce1ecf1de396e72ce7bc._comment8
-rw-r--r--doc/forum/Share_only_certain_files_of_a_repo___40__Assistant__41__.mdwn6
-rw-r--r--doc/forum/Share_only_certain_files_of_a_repo___40__Assistant__41__/comment_1_ec0d56cb31b918023a9184cee168b406._comment8
-rw-r--r--doc/forum/Share_with_friend_copies_only_sym_links.mdwn38
-rw-r--r--doc/forum/Share_with_friend_copies_only_sym_links/comment_1_a8d22dfefb219f0c9130cc294364b198._comment17
-rw-r--r--doc/forum/Sharing_annex_with_local_clones.mdwn1
-rw-r--r--doc/forum/Sharing_annex_with_local_clones/comment_1_2b60e13e5f7b8cee56cf2ddc6c47f64d._comment12
-rw-r--r--doc/forum/Sharing_annex_with_local_clones/comment_2_24ff2c1eb643077daa37c01644cebcd2._comment8
-rw-r--r--doc/forum/Sharing_annex_with_local_clones/comment_3_5359b8eada24d27be83214ac0ae62f23._comment8
-rw-r--r--doc/forum/Simple_check_out_with_assistant__63__.mdwn2
-rw-r--r--doc/forum/Simple_check_out_with_assistant__63__/comment_1_ade8a0743ef1ec933c8a40ed64eeac2d._comment8
-rw-r--r--doc/forum/Slightly_finer_control_over_file_whereabouts.mdwn18
-rw-r--r--doc/forum/Slightly_finer_control_over_file_whereabouts/comment_10_bcb883d46a637dd1a8ef9a92733d202a._comment10
-rw-r--r--doc/forum/Slightly_finer_control_over_file_whereabouts/comment_11_b7a8b9eaf114f883866fbf2be51b622f._comment8
-rw-r--r--doc/forum/Slightly_finer_control_over_file_whereabouts/comment_1_6236bcfa9beba705ead3ec2141c5d835._comment8
-rw-r--r--doc/forum/Slightly_finer_control_over_file_whereabouts/comment_2_ea935b37ca93e73c85d04df7c9bf6057._comment12
-rw-r--r--doc/forum/Slightly_finer_control_over_file_whereabouts/comment_3_f89a8e38283ac4c8c4a3b74c413d67a1._comment8
-rw-r--r--doc/forum/Slightly_finer_control_over_file_whereabouts/comment_4_07a0a754a089c46ff69dc97ea7ba9384._comment22
-rw-r--r--doc/forum/Slightly_finer_control_over_file_whereabouts/comment_5_e884c001a556a0c693d1cc9a97c068ac._comment8
-rw-r--r--doc/forum/Slightly_finer_control_over_file_whereabouts/comment_6_3e8674b5857e4994dfbc26be4f4b2855._comment25
-rw-r--r--doc/forum/Slightly_finer_control_over_file_whereabouts/comment_7_7aeabc2e52a39423e83fbd04560e8f91._comment8
-rw-r--r--doc/forum/Slightly_finer_control_over_file_whereabouts/comment_8_53b95449cfad2fe0f72d2ad642822c03._comment15
-rw-r--r--doc/forum/Slightly_finer_control_over_file_whereabouts/comment_9_a17c102a45e4fc3f101a79acb8eb4081._comment18
-rw-r--r--doc/forum/Some_mounted_devices_not_detected.mdwn3
-rw-r--r--doc/forum/Some_mounted_devices_not_detected/comment_1_0ba07b95f12f57ea63bb450b88430c45._comment8
-rw-r--r--doc/forum/Some_mounted_devices_not_detected/comment_2_4f8c7bcd0f20dafa5635a3580ec8d1f6._comment13
-rw-r--r--doc/forum/Some_mounted_devices_not_detected/comment_3_06c0db7d670d9b82823102d22db15a36._comment10
-rw-r--r--doc/forum/Some_mounted_devices_not_detected/comment_4_80820a29361c5be4a94672dacfdefa6f._comment8
-rw-r--r--doc/forum/Special_remote_without_chmod.mdwn12
-rw-r--r--doc/forum/Special_remote_without_chmod/comment_1_4f5f9506cae72a1f321296fc5a5f339a._comment8
-rw-r--r--doc/forum/Storing_uncontrolled_files_in_an_annex.mdwn3
-rw-r--r--doc/forum/Storing_uncontrolled_files_in_an_annex/comment_1_175645a90be0c79221c129308adf643e._comment27
-rw-r--r--doc/forum/Storing_uncontrolled_files_in_an_annex/comment_2_d29f214eadfe3bfd098bbc3bcf07129a._comment8
-rw-r--r--doc/forum/Storing_uncontrolled_files_in_an_annex/comment_3_286b502e7906cca50e9e747db735bc88._comment10
-rw-r--r--doc/forum/Stupid_mistake:_recoverable__63__.mdwn31
-rw-r--r--doc/forum/Stupid_mistake:_recoverable__63__/comment_1_00ceb3a5e37825c4bbc806f532893706._comment23
-rw-r--r--doc/forum/Stupid_mistake:_recoverable__63__/comment_2_cbedc29678d9b6af3b3c0bb1915d2391._comment12
-rw-r--r--doc/forum/Stupid_mistake:_recoverable__63__/comment_3_86aa4d92a1330811862da1ba568b3037._comment42
-rw-r--r--doc/forum/Stupid_mistake:_recoverable__63__/comment_4_6d15bf8a3c3c27cc92957070161675a9._comment12
-rw-r--r--doc/forum/Stupid_mistake:_recoverable__63__/comment_5_f836b9b1d03d94c49e3798961790b2ba._comment21
-rw-r--r--doc/forum/Suggestion:_Put_ssh_server_back_into_android_version.mdwn9
-rw-r--r--doc/forum/Suggestion:_Put_ssh_server_back_into_android_version/comment_1_5c2f376a82458c6387560355940419d3._comment12
-rw-r--r--doc/forum/Suggestion:_Put_ssh_server_back_into_android_version/comment_2_6321dec0b2f22f841f3cb986e063113f._comment8
-rw-r--r--doc/forum/Sync_with_one_offline_peer.txt11
-rw-r--r--doc/forum/Sync_with_one_offline_peer/comment_1_3859d842d4f7e2ef44877b05ebe881fb._comment20
-rw-r--r--doc/forum/Sync_with_one_offline_peer/comment_2_c9ba3983b37b0c1868269616fd81e518._comment14
-rw-r--r--doc/forum/Sync_with_one_offline_peer/comment_3_28b9c003b4560c3ce90c9ebf808b091b._comment10
-rw-r--r--doc/forum/Sync_without_jabber_account.mdwn9
-rw-r--r--doc/forum/Sync_without_jabber_account/comment_1_3e95ac2e67451f953cf0538094109f8b._comment10
-rw-r--r--doc/forum/Synchronize_large_files___40__VM_images__41__.mdwn10
-rw-r--r--doc/forum/Synchronize_large_files___40__VM_images__41__/comment_1_619f6ed2d7da5832ab253d61b6dd8044._comment10
-rw-r--r--doc/forum/Syncing_machines_on_different_networks.mdwn9
-rw-r--r--doc/forum/Syncing_machines_on_different_networks/comment_1_1c3523c722c178a96b096a68b9be4165._comment8
-rw-r--r--doc/forum/Syncing_machines_on_different_networks/comment_2_d7b14ffee65072329cfe9ab08a0dba50._comment8
-rw-r--r--doc/forum/Syncing_machines_on_different_networks/comment_3_65d1dae9b76fccb5f2b8fd8c69b60075._comment15
-rw-r--r--doc/forum/Syncing_machines_on_different_networks/comment_4_2ec67428af69d6c0ea051c6a67d58905._comment10
-rw-r--r--doc/forum/Syncing_machines_on_different_networks/comment_5_5ce093f82a2aad3fd8d7ccd5fdcab94f._comment8
-rw-r--r--doc/forum/Syncing_machines_on_different_networks/comment_6_a55982c28d7b90e0b70ec2bb5e594e08._comment8
-rw-r--r--doc/forum/Syncing_machines_on_different_networks/comment_7_c519d546e1a2a4e834609f3de3a605b0._comment8
-rw-r--r--doc/forum/Syncing_machines_on_different_networks/comment_8_84a822238ddbaf211cce5f527c3559d3._comment8
-rw-r--r--doc/forum/Syncing_with_an_encrypted_remote_from_a_different_computer__63__.mdwn4
-rw-r--r--doc/forum/Syncing_with_an_encrypted_remote_from_a_different_computer__63__/comment_1_cd55d06a4065b9d3f14d50674c3fcaf7._comment8
-rw-r--r--doc/forum/Syncing_with_an_encrypted_remote_from_a_different_computer__63__/comment_2_25cbdf478091af9923090e049c432a7d._comment22
-rw-r--r--doc/forum/Syncing_with_an_encrypted_remote_from_a_different_computer__63__/comment_3_7e71d355457d6b1a0391d4cdae6895e6._comment16
-rw-r--r--doc/forum/Syncing_with_an_encrypted_remote_from_a_different_computer__63__/comment_4_a73f67f2fcf0762fbd7c8366b3844af6._comment11
-rw-r--r--doc/forum/Syncronisation_of_syncronisation_between_3_repositories__63__.mdwn11
-rw-r--r--doc/forum/Syncronisation_of_syncronisation_between_3_repositories__63__/comment_1_ca5192a26950627a1c2efcb55d6d2fa3._comment10
-rw-r--r--doc/forum/The_ability_to_leave_a_file_unlocked_for_a_bit_while_committing_it_repeatedly__63__.mdwn3
-rw-r--r--doc/forum/The_ability_to_leave_a_file_unlocked_for_a_bit_while_committing_it_repeatedly__63__/comment_1_3cbe520b184d323219cb402ff046c3b4._comment29
-rw-r--r--doc/forum/The_ability_to_leave_a_file_unlocked_for_a_bit_while_committing_it_repeatedly__63__/comment_2_6afe7f593e955db2eefe87d9fa01882b._comment8
-rw-r--r--doc/forum/The_ability_to_leave_a_file_unlocked_for_a_bit_while_committing_it_repeatedly__63__/comment_3_209399487fc4f76b29f03ad82dbc2d6f._comment8
-rw-r--r--doc/forum/The_ability_to_leave_a_file_unlocked_for_a_bit_while_committing_it_repeatedly__63__/comment_4_f33fd6f72cb9ad7dd20a04c82199413b._comment26
-rw-r--r--doc/forum/Transfer_remotes.mdwn3
-rw-r--r--doc/forum/Transfer_remotes/comment_1_c08cf3bda00d7f20a3ca3d0fdba19c9c._comment8
-rw-r--r--doc/forum/Transfer_remotes/comment_2_98930629d398329f1161135464a966a5._comment12
-rw-r--r--doc/forum/Trouble_installing_from_cabal_on_debian-testing.mdwn15
-rw-r--r--doc/forum/Trouble_installing_from_cabal_on_debian-testing/comment_1_0d3e9d7cffafc34bc212557e8bbb987d._comment12
-rw-r--r--doc/forum/Truly_purging_dead_repositories.mdwn1
-rw-r--r--doc/forum/Truly_purging_dead_repositories/comment_1_a4c75d49714b3543a9f1617a15d4a2d1._comment8
-rw-r--r--doc/forum/Truly_purging_dead_repositories/comment_2_3da60a02e7323a204c5c5dd02ba04d6c._comment8
-rw-r--r--doc/forum/Truly_purging_dead_repositories/comment_3_2576e45436008ff5a7ae5a38cade658e._comment8
-rw-r--r--doc/forum/Truly_purging_dead_repositories/comment_4_477e3c213c5a5d4a33afd42a5b94c718._comment10
-rw-r--r--doc/forum/Two_computer_setup:___34__transfer__34___or___34__full_backup__34___repository_groups__63__.mdwn18
-rw-r--r--doc/forum/Two_computer_setup:___34__transfer__34___or___34__full_backup__34___repository_groups__63__/comment_1_b8702892280447193e6e80be22a580a0._comment11
-rw-r--r--doc/forum/Two_computer_setup:___34__transfer__34___or___34__full_backup__34___repository_groups__63__/comment_2_50cafde7e30b928480d1f142ddd763d2._comment10
-rw-r--r--doc/forum/USB_backup_with_files_visible.mdwn7
-rw-r--r--doc/forum/USB_backup_with_files_visible/comment_1_2832f8ae24dfb0f101e06f7c18283028._comment10
-rw-r--r--doc/forum/USB_backup_with_files_visible/comment_2_6163e01aa441f8435091f026cc6da337._comment8
-rw-r--r--doc/forum/USB_backup_with_files_visible/comment_3_ee92ff320eb5d9a031bdd1896aee0d86._comment11
-rw-r--r--doc/forum/USB_backup_with_files_visible/comment_4_437c8342c0b65e3a89129800313eb73c._comment10
-rw-r--r--doc/forum/USB_backup_with_files_visible/comment_5_5e10cffe8465ea4ecaa71c03a4c29ea4._comment8
-rw-r--r--doc/forum/USB_backup_with_files_visible/comment_6_add048a16837f7940a859f21426cdbe9._comment8
-rw-r--r--doc/forum/USB_backup_with_files_visible/comment_7_de227ca9911fe57d7a6d3e037f574fe9._comment14
-rw-r--r--doc/forum/USB_backup_with_files_visible/comment_8_0c0ed0e038f7f0e2d2d4ed69b7b29fbc._comment10
-rw-r--r--doc/forum/USB_drive_in_transfer_group_keeps_growing_-_assistant.txt22
-rw-r--r--doc/forum/USB_drive_in_transfer_group_keeps_growing_-_assistant/comment_1_0a6f6054d70009979f4a036e24b7c500._comment10
-rw-r--r--doc/forum/Ubuntu_PPA.mdwn3
-rw-r--r--doc/forum/Ubuntu_PPA/comment_1_b55535258b1b4bcfc802235f0cba075d._comment8
-rw-r--r--doc/forum/Ubuntu_PPA/comment_2_adc4d644fed058d1811acf0b35db9c18._comment8
-rw-r--r--doc/forum/Ubuntu_PPA/comment_3_fc9cd51558c47718f243437202a11803._comment8
-rw-r--r--doc/forum/Ubuntu_PPA/comment_4_3a8bbd0a7450a7f5323cd13144824aea._comment12
-rw-r--r--doc/forum/Ubuntu_PPA/comment_5_2e1beaeebda0201c635db8b276cedf20._comment12
-rw-r--r--doc/forum/Ubuntu_PPA/comment_6_bd99fb70399fc58d98781a89c6d38428._comment8
-rw-r--r--doc/forum/Ubuntu_PPA/comment_7_c3f7ec8573934c59d70a48e36e321c13._comment12
-rw-r--r--doc/forum/Un-git-annex__63__.mdwn6
-rw-r--r--doc/forum/Un-git-annex__63__/comment_1_6059265afb66190d325083e0f28bcf33._comment10
-rw-r--r--doc/forum/Un-git-annex__63__/comment_2_fac4bfb81dbbf0dc82059aace261eb51._comment10
-rw-r--r--doc/forum/Undo_Git_Annex_Changes_To_Linked_Files.mdwn7
-rw-r--r--doc/forum/Undo_Git_Annex_Changes_To_Linked_Files/comment_1_568dde820c2608d86d05b07444146a26._comment13
-rw-r--r--doc/forum/Undo_Git_Annex_Changes_To_Linked_Files/comment_2_a8cf71cdf1217d9c8596cd9006eb83f5._comment8
-rw-r--r--doc/forum/Unknown_remote_type_S3.mdwn5
-rw-r--r--doc/forum/Unknown_remote_type_S3/comment_1_2aea2cd51286c809427d16519606cd37._comment8
-rw-r--r--doc/forum/Unknown_remote_type_S3/comment_2_06f775062cd30767979fe56bcb3cf7bf._comment8
-rw-r--r--doc/forum/Unlock_files_when_assistant_is_running__63__.mdwn13
-rw-r--r--doc/forum/Unlock_files_when_assistant_is_running__63__/comment_1_3f4aadf0c856c81e15c6f5ae7f1992b4._comment10
-rw-r--r--doc/forum/Unlock_files_when_assistant_is_running__63__/comment_2_a76797ee9e05e43af7947508cadd7bed._comment9
-rw-r--r--doc/forum/Use_case_with_syncing_only_a_subset_possible__63__.mdwn13
-rw-r--r--doc/forum/Use_case_with_syncing_only_a_subset_possible__63__/comment_1_a0a272a0931b27e5c94b93e42656b62c._comment10
-rw-r--r--doc/forum/Use_local_files_instead_of_re-downloading_from_S3_remote.mdwn3
-rw-r--r--doc/forum/Use_local_files_instead_of_re-downloading_from_S3_remote/comment_1_cfb6021a36eee087705967a69967f327._comment10
-rw-r--r--doc/forum/Use_local_files_instead_of_re-downloading_from_S3_remote/comment_2_7268b194ba72331858bc3274996b780e._comment11
-rw-r--r--doc/forum/Use_reflinks_on_BTRFS_instead_of_symlinks___63__.mdwn1
-rw-r--r--doc/forum/Use_reflinks_on_BTRFS_instead_of_symlinks___63__/comment_1_85806316ed28d7a891f04fab4027141b._comment8
-rw-r--r--doc/forum/Use_reflinks_on_BTRFS_instead_of_symlinks___63__/comment_2_ecb411a2c4d67917b734a90bd460d44b._comment10
-rw-r--r--doc/forum/Using_Git-Annex___40__Assistant__41___to_manage_photos_with_Shotwell.mdwn13
-rw-r--r--doc/forum/Using_Git-Annex___40__Assistant__41___to_manage_photos_with_Shotwell/comment_1_5e8d54daf6b7ff357619ac65fe39a2d7._comment12
-rw-r--r--doc/forum/Using_Linux_static_builds.mdwn25
-rw-r--r--doc/forum/Using_Linux_static_builds/comment_1_22fd266cbe68af3e754a10f1f1295e9b._comment13
-rw-r--r--doc/forum/Using_Linux_static_builds/comment_2_36f69f30117ff8696425a754ab19a08b._comment8
-rw-r--r--doc/forum/Using_Linux_static_builds/comment_3_64506833dad0202626239e00d1eb6490._comment23
-rw-r--r--doc/forum/Using___34__sync__34___to_sink_all_branches__63__.mdwn9
-rw-r--r--doc/forum/Using___34__sync__34___to_sink_all_branches__63__/comment_1_ef3d5c5e2600ffa36dd933c8a42cdf96._comment16
-rw-r--r--doc/forum/Using___34__sync__34___to_sink_all_branches__63__/comment_2_424b0c6fdfe87ca08f5d408b7684ab08._comment10
-rw-r--r--doc/forum/Using___34__sync__34___to_sink_all_branches__63__/comment_3_adaf9114c69f1268330adcebd8018fa0._comment10
-rw-r--r--doc/forum/Using_a_single_backup_repo_for_multiple_independent_client_repos__63__.mdwn36
-rw-r--r--doc/forum/Using_a_single_backup_repo_for_multiple_independent_client_repos__63__/comment_1_c61c28600f1079fb03ddabc950307f27._comment11
-rw-r--r--doc/forum/Using_for_Music_repo.mdwn13
-rw-r--r--doc/forum/Using_for_Music_repo/comment_1_3488ed85ad98f14cb17f229225ece26e._comment10
-rw-r--r--doc/forum/Using_for_Music_repo/comment_2_c794648878cfc77558f8db862271f997._comment25
-rw-r--r--doc/forum/Using_for_Music_repo/comment_3_8c5e820f5ff7d717d64b1fd66927941b._comment8
-rw-r--r--doc/forum/Using_git-annex_as_a_library.mdwn1
-rw-r--r--doc/forum/Using_git-annex_as_a_library/comment_1_1f8e74c5856f21c53d5a91892cbef0c6._comment8
-rw-r--r--doc/forum/Using_git-annex_as_a_library/comment_2_11a243fa7d8ac947aa9a798228dbd191._comment12
-rw-r--r--doc/forum/Using_git-annex_via_command_line_in_OS_X.mdwn3
-rw-r--r--doc/forum/Using_git-annex_via_command_line_in_OS_X/comment_1_1c9e121f60fb6868c07f1a53b03c4ed0._comment8
-rw-r--r--doc/forum/Using_git-annex_via_command_line_in_OS_X/comment_2_52d8ffba82e29ac2722a8e43e469cc47._comment9
-rw-r--r--doc/forum/Using_git_annex_with_Android_tablet_which_only_has_exFAT_and_no_symlinks.mdwn8
-rw-r--r--doc/forum/Using_git_annex_with_Android_tablet_which_only_has_exFAT_and_no_symlinks/comment_1_b9f202a30ba7e3bc264064d24454c099._comment12
-rw-r--r--doc/forum/Using_git_annex_with_Android_tablet_which_only_has_exFAT_and_no_symlinks/comment_2_1334a8d9f4bb60f3bf3ebabc656d98d9._comment18
-rw-r--r--doc/forum/Using_git_annex_with_Android_tablet_which_only_has_exFAT_and_no_symlinks/comment_3_076f22d05fad140068a540e4d835106f._comment8
-rw-r--r--doc/forum/Using_git_annex_with_Android_tablet_which_only_has_exFAT_and_no_symlinks/comment_4_c8446ee1b817f1824fa0df07e742015c._comment12
-rw-r--r--doc/forum/Using_git_annex_with_Android_tablet_which_only_has_exFAT_and_no_symlinks/comment_5_f746c1b85ee8e4b57b6819ccceabd28b._comment8
-rw-r--r--doc/forum/Using_git_annex_with_a_SMB__47__FTP_TV_NAS_with_preconfigured_dirs.mdwn5
-rw-r--r--doc/forum/Using_git_annex_with_a_SMB__47__FTP_TV_NAS_with_preconfigured_dirs/comment_1_bd73c8d10028e1b45da9ea8f657e5064._comment10
-rw-r--r--doc/forum/Using_git_annex_with_a_SMB__47__FTP_TV_NAS_with_preconfigured_dirs/comment_2_16c3c994ee8fcb466e52ca0e812e5915._comment8
-rw-r--r--doc/forum/Using_git_annex_with_a_SMB__47__FTP_TV_NAS_with_preconfigured_dirs/comment_3_ac60f6edb76bdd541711e472eec9591a._comment10
-rw-r--r--doc/forum/Using_git_annex_with_a_SMB__47__FTP_TV_NAS_with_preconfigured_dirs/comment_4_2194f0600d9a90f0d9c947ea9cc213a3._comment8
-rw-r--r--doc/forum/Using_git_annex_with_a_SMB__47__FTP_TV_NAS_with_preconfigured_dirs/comment_5_eb7d13f6b6fa674a2536bde51bfc3fd1._comment48
-rw-r--r--doc/forum/Using_git_annex_with_a_SMB__47__FTP_TV_NAS_with_preconfigured_dirs/comment_6_ae323b16ddb9342e91be955408eca3b1._comment8
-rw-r--r--doc/forum/Walkthrough_does_not_work_for_me__44___what_am_i_doing_wrong__63__.mdwn16
-rw-r--r--doc/forum/Walkthrough_does_not_work_for_me__44___what_am_i_doing_wrong__63__/comment_1_cdac15fec6fc41d5487b7f653fa718a4._comment14
-rw-r--r--doc/forum/Walkthrough_does_not_work_for_me__44___what_am_i_doing_wrong__63__/comment_2_82050b7dc367ca5968ab0306db9bd7e3._comment10
-rw-r--r--doc/forum/Watch__47__assistant__47__webapp_documentation.mdwn12
-rw-r--r--doc/forum/Watch__47__assistant__47__webapp_documentation/comment_1_adb377589dbae7fc91001df235c6b48e._comment14
-rw-r--r--doc/forum/Webapp_on_ARM.mdwn6
-rw-r--r--doc/forum/Webapp_on_ARM/comment_1_82ac40cef5b59070136527b8d81a5ce2._comment10
-rw-r--r--doc/forum/Weird_behavior_with_OS_X_Finder_and_Preview.app.mdwn12
-rw-r--r--doc/forum/Weird_behavior_with_OS_X_Finder_and_Preview.app/comment_1_8c8d86790a9d31518f9bb96a2d2dafee._comment18
-rw-r--r--doc/forum/Weird_behavior_with_OS_X_Finder_and_Preview.app/comment_2_b538dc2c6f122b9ce5f7569de1b03f3e._comment8
-rw-r--r--doc/forum/Weird_behavior_with_OS_X_Finder_and_Preview.app/comment_3_16e6724fa184392d4decbe0c4eb6efe6._comment14
-rw-r--r--doc/forum/Weird_behavior_with_OS_X_Finder_and_Preview.app/comment_4_e514fe2d4d0ad6a10e281939e6ab4266._comment15
-rw-r--r--doc/forum/Weird_behavior_with_OS_X_Finder_and_Preview.app/comment_5_e0eec765f72f7bf6f5a2a92c9b5dacad._comment10
-rw-r--r--doc/forum/What_can_be_done_in_case_of_conflict.mdwn7
-rw-r--r--doc/forum/What_can_be_done_in_case_of_conflict/comment_1_5ca86b099dfa08a50f656ea03bf1dcd9._comment12
-rw-r--r--doc/forum/What_can_be_done_in_case_of_conflict/comment_2_69ee17959a92bb8359c0fd7b2a9d8dfb._comment10
-rw-r--r--doc/forum/What_can_be_done_in_case_of_conflict/comment_3_017f4bac57a040c496e0c9d068dcfd9e._comment41
-rw-r--r--doc/forum/What_happened_to_the_walkthrough__63__.mdwn1
-rw-r--r--doc/forum/What_happened_to_the_walkthrough__63__/comment_1_70db0e3cfb1318e95671c23726e5541d._comment8
-rw-r--r--doc/forum/What_happened_to_the_walkthrough__63__/comment_2_f9305dd19b9b5f35e66d915b8c30374b._comment7
-rw-r--r--doc/forum/What_is_the_best_way_to___34__git_annex_mv__34___file__63__.mdwn1
-rw-r--r--doc/forum/What_is_the_best_way_to___34__git_annex_mv__34___file__63__/comment_1_02d305f307b4d2ff7acd98cb36508a2f._comment10
-rw-r--r--doc/forum/What_is_the_difference_between___34__local_computer__34___and___34__remote_server__34__.mdwn3
-rw-r--r--doc/forum/What_is_the_difference_between___34__local_computer__34___and___34__remote_server__34__/comment_1_68734a118b7dc0c88ba67eca20953a55._comment10
-rw-r--r--doc/forum/What_to_do_when_computer_is_lost_and_only_an_encrypted_ssh_remote_is_left__63__.mdwn1
-rw-r--r--doc/forum/What_to_do_when_computer_is_lost_and_only_an_encrypted_ssh_remote_is_left__63__/comment_1_67ee446ca6d66e2c259ea771c2c9a2b2._comment12
-rw-r--r--doc/forum/What_to_do_when_computer_is_lost_and_only_an_encrypted_ssh_remote_is_left__63__/comment_2_6d3cce3c8048e4aea8f0ed76473f6af1._comment8
-rw-r--r--doc/forum/What_to_do_when_computer_is_lost_and_only_an_encrypted_ssh_remote_is_left__63__/comment_3_bd506e1ca7307660b3b9769eb97beddb._comment8
-rw-r--r--doc/forum/Which_cloud_providers_are_supported__63___.mdwn3
-rw-r--r--doc/forum/Which_cloud_providers_are_supported__63___/comment_1_1f9398840144e0452a2fed9336046547._comment10
-rw-r--r--doc/forum/Why_can__39__t_encryption_be_enabled_for_removable_drives__63__.mdwn7
-rw-r--r--doc/forum/Why_can__39__t_encryption_be_enabled_for_removable_drives__63__/comment_1_4341898d5ae4f09a5b06d24f5fe6192d._comment8
-rw-r--r--doc/forum/Why_does_the_bup_remote_use___126____47__.bup__63__.mdwn5
-rw-r--r--doc/forum/Why_does_the_bup_remote_use___126____47__.bup__63__/comment_1_da9c7c0e93aefc2da7409de5b138d86f._comment8
-rw-r--r--doc/forum/Will_git-annex_solve_my_problem__63__.mdwn7
-rw-r--r--doc/forum/Will_git-annex_solve_my_problem__63__/comment_1_35acbdd1a7727df204d776c2e8f02b53._comment8
-rw-r--r--doc/forum/Will_git-annex_solve_my_problem__63__/comment_2_230256c19ac139dea207d89c06f70782._comment8
-rw-r--r--doc/forum/Will_git_annex_work_on_a_FAT32_formatted_key__63__.mdwn3
-rw-r--r--doc/forum/Will_git_annex_work_on_a_FAT32_formatted_key__63__/comment_1_426482e6eb3a27687a48f24f6ef2332f._comment8
-rw-r--r--doc/forum/Will_git_annex_work_on_a_FAT32_formatted_key__63__/comment_2_af4f8b52526d8bea2904c95406fd2796._comment8
-rw-r--r--doc/forum/Windows_support.mdwn6
-rw-r--r--doc/forum/Windows_support/comment_1_23fa9aa3b00940a1c1b3876c35eef019._comment9
-rw-r--r--doc/forum/Windows_usage_instructions.mdwn25
-rw-r--r--doc/forum/Windows_usage_instructions/comment_1_d43dbd9406da3b9747b147715eca94ac._comment8
-rw-r--r--doc/forum/Wishlist:_Bittorrent-like_transfers.mdwn5
-rw-r--r--doc/forum/Wishlist:_Bittorrent-like_transfers/comment_1_13544d54fb0418af4ca9200cdb045d91._comment15
-rw-r--r--doc/forum/Wishlist:_Bittorrent-like_transfers/comment_2_9a7dad35bf80c684ad97892420d7370c._comment16
-rw-r--r--doc/forum/Wishlist:_Bittorrent-like_transfers/comment_3_e5de748bc5da12a4a01e08cde2407dd1._comment14
-rw-r--r--doc/forum/Wishlist:_Bittorrent-like_transfers/comment_4_e51530178f1e034c0fdd5c9aa9945567._comment8
-rw-r--r--doc/forum/Wishlist:_Bittorrent-like_transfers/comment_5_81ea9c129d8c02097f09ef8c68f1bb11._comment27
-rw-r--r--doc/forum/Wishlist:_Bittorrent-like_transfers/comment_6_3b5798414f89686526da3dfa72c0c4f2._comment10
-rw-r--r--doc/forum/Wishlist:_Don__39__t_make_files_readonly.mdwn3
-rw-r--r--doc/forum/Wishlist:_Don__39__t_make_files_readonly/comment_1_7148527961e2d27793810966588c8d35._comment10
-rw-r--r--doc/forum/Wishlist:_Is_it_possible_to___34__unlock__34___files_without_copying_the_file_data__63__.mdwn6
-rw-r--r--doc/forum/Wishlist:_Is_it_possible_to___34__unlock__34___files_without_copying_the_file_data__63__/comment_1_1cf4ab29dfa2cff59b86305fc0018251._comment10
-rw-r--r--doc/forum/Wishlist:_Is_it_possible_to___34__unlock__34___files_without_copying_the_file_data__63__/comment_2_f5ebb7f43dcef861ecc13373fb1e263f._comment15
-rw-r--r--doc/forum/Wishlist:_Ways_of_selecting_files_based_on_meta-information.mdwn15
-rw-r--r--doc/forum/Wishlist:_Ways_of_selecting_files_based_on_meta-information/comment_1_818f38aa988177d3a9415055e084f0fb._comment15
-rw-r--r--doc/forum/Wishlist:_Ways_of_selecting_files_based_on_meta-information/comment_2_97e2ed48bd552d02918c4f98f963e6e1._comment9
-rw-r--r--doc/forum/Wishlist:_automatic_reinject.mdwn14
-rw-r--r--doc/forum/Wishlist:_getting_the_disk_used_by_a_subtree_of_files.mdwn10
-rw-r--r--doc/forum/Wishlist:_getting_the_disk_used_by_a_subtree_of_files/comment_1_7abb1155081a23ce4829ee69b2064541._comment9
-rw-r--r--doc/forum/Wishlist:_getting_the_disk_used_by_a_subtree_of_files/comment_2_b4c6ebada7526263e04c70eac312fda9._comment18
-rw-r--r--doc/forum/Wishlist:_getting_the_disk_used_by_a_subtree_of_files/comment_3_ded71b270b94617a8ebb3a713d46a274._comment19
-rw-r--r--doc/forum/Wishlist:_logging_to_file_when_running_as_a_daemon___40__for_the_assistant__41__.mdwn1
-rw-r--r--doc/forum/Wishlist:_logging_to_file_when_running_as_a_daemon___40__for_the_assistant__41__/comment_1_42aa2b61b880f4048d874210212aa63b._comment8
-rw-r--r--doc/forum/Wishlist:_logging_to_file_when_running_as_a_daemon___40__for_the_assistant__41__/comment_2_3e201039fa0e611554171ee30e69a414._comment8
-rw-r--r--doc/forum/Wishlist:_logging_to_file_when_running_as_a_daemon___40__for_the_assistant__41__/comment_3_d1074724c44f3296cb438b2d526d8728._comment8
-rw-r--r--doc/forum/Wishlist:_mark_remotes_offline.mdwn12
-rw-r--r--doc/forum/Wishlist:_mark_remotes_offline/comment_1_9e3901f0123abb66034cce95cc5a941a._comment14
-rw-r--r--doc/forum/Wishlist:_mark_remotes_offline/comment_2_d10e3d90cf421ae425e64ab266ea811b._comment12
-rw-r--r--doc/forum/Wishlist:_options_for_syncing_meta-data_and_data.mdwn13
-rw-r--r--doc/forum/Wishlist:_rename_files__47__dirs_w__47___special_characters_if_filesystem_is_FAT.mdwn5
-rw-r--r--doc/forum/Wishlist:_rename_files__47__dirs_w__47___special_characters_if_filesystem_is_FAT/comment_1_5d33bcbd862537f53edd91dcff2b8977._comment13
-rw-r--r--doc/forum/XBMC__44___NFS___38___git-annex_.txt27
-rw-r--r--doc/forum/XBMC__44___NFS___38___git-annex_/comment_1_86480f31d410e903766f82e6ecf83e1c._comment12
-rw-r--r--doc/forum/XBMC__44___NFS___38___git-annex_/comment_2_d8ed4dd51d3050db691a8abdec24cd42._comment10
-rw-r--r--doc/forum/XBMC__44___NFS___38___git-annex_/comment_3_42b80ee51ce25775bf4532f53a8ecfe3._comment11
-rw-r--r--doc/forum/XBMC__44___NFS___38___git-annex_/comment_4_01767f3f864954cf8080274e206da9d4._comment8
-rw-r--r--doc/forum/XMPP_authentication_failure.mdwn15
-rw-r--r--doc/forum/XMPP_authentication_failure/comment_1_19c7c3aa79d209d613d2e061e3129690._comment8
-rw-r--r--doc/forum/XMPP_authentication_failure/comment_2_870059fed451e8377e5d382464ecc34b._comment8
-rw-r--r--doc/forum/XMPP_authentication_failure/comment_3_1a7ff955e9173f13d10b75f203792384._comment10
-rw-r--r--doc/forum/XMPP_authentication_failure/comment_4_d59031ebc0dd3abc1f4c96878328362c._comment8
-rw-r--r--doc/forum/XMPP_authentication_failure/comment_5_c37ef477bef7efdb79dd05dce90dfde6._comment10
-rw-r--r--doc/forum/XMPP_authentication_failure/comment_6_48cabea4c2caf5b3bd854df3aaa17d3d._comment8
-rw-r--r--doc/forum/XMPP_authentication_failure/comment_7_14cd9b67806db93c3af055d88c9a910a._comment10
-rw-r--r--doc/forum/XMPP_authentication_failure/comment_8_151d3fd7d3cceb30fd20a8f3bd54036c._comment24
-rw-r--r--doc/forum/XMPP_authentication_failure/comment_9_fbb9eba65fbb72201f08511945fbcf8c._comment9
-rw-r--r--doc/forum/XMPP_email_setup_says_wrong_password_but_it__39__s_correct._Can_I_provide_some_kind_of_debug_data__63__.mdwn9
-rw-r--r--doc/forum/XMPP_email_setup_says_wrong_password_but_it__39__s_correct._Can_I_provide_some_kind_of_debug_data__63__/comment_1_1ba0735141fc6a21ac15913f4cacefae._comment8
-rw-r--r--doc/forum/XMPP_email_setup_says_wrong_password_but_it__39__s_correct._Can_I_provide_some_kind_of_debug_data__63__/comment_2_16994dc86b87592fc62799e2d206d172._comment10
-rw-r--r--doc/forum/XMPP_email_setup_says_wrong_password_but_it__39__s_correct._Can_I_provide_some_kind_of_debug_data__63__/comment_3_6afd424edc4095b8f71b136de2a9e64d._comment10
-rw-r--r--doc/forum/XMPP_email_setup_says_wrong_password_but_it__39__s_correct._Can_I_provide_some_kind_of_debug_data__63__/comment_4_1381b6a927410642c6a93aa8354be791._comment17
-rw-r--r--doc/forum/XMPP_email_setup_says_wrong_password_but_it__39__s_correct._Can_I_provide_some_kind_of_debug_data__63__/comment_5_c5b33c7a8aa8e6d0f9349510dac2366d._comment12
-rw-r--r--doc/forum/XMPP_email_setup_says_wrong_password_but_it__39__s_correct._Can_I_provide_some_kind_of_debug_data__63__/comment_6_9913d2983ba2744ed24911f74988e4c7._comment11
-rw-r--r--doc/forum/XMPP_email_setup_says_wrong_password_but_it__39__s_correct._Can_I_provide_some_kind_of_debug_data__63__/comment_7_ad6f385a2b95803eb9d81dfe76359551._comment10
-rw-r--r--doc/forum/_Does_git_annex_find___40____38___friends__41___batch_queries_to_the_location_log__63__.mdwn45
-rw-r--r--doc/forum/_Does_git_annex_find___40____38___friends__41___batch_queries_to_the_location_log__63__/comment_1_01cbfc513c790faef3a3ede5315d3589._comment10
-rw-r--r--doc/forum/_Does_git_annex_find___40____38___friends__41___batch_queries_to_the_location_log__63__/comment_2_fe28dfb360caa12d5d5bc186def3eb45._comment35
-rw-r--r--doc/forum/_Does_git_annex_find___40____38___friends__41___batch_queries_to_the_location_log__63__/comment_3_9bb30ab62febe4ef63bed49f831a473a._comment8
-rw-r--r--doc/forum/_Does_git_annex_find___40____38___friends__41___batch_queries_to_the_location_log__63__/comment_4_7832f0347a41b8204538c01b72487803._comment19
-rw-r--r--doc/forum/__34__Pairing__34___more_than_two_computers.mdwn11
-rw-r--r--doc/forum/__34__Pairing__34___more_than_two_computers/comment_1_80f7a4bb3c66b11e566043407b611bbf._comment10
-rw-r--r--doc/forum/__34__du__34___equivalent_on_an_annex__63__.mdwn5
-rw-r--r--doc/forum/__34__du__34___equivalent_on_an_annex__63__/comment_1_a41bd02361aa961e5285aeaf1ea062be._comment10
-rw-r--r--doc/forum/__34__du__34___equivalent_on_an_annex__63__/comment_2_28ba62a546f5cc8f416491423d743d8a._comment10
-rw-r--r--doc/forum/__34__du__34___equivalent_on_an_annex__63__/comment_3_8d97f40c1d14b7230f3656a00a99cf80._comment8
-rw-r--r--doc/forum/__34__du__34___equivalent_on_an_annex__63__/comment_4_baa8fbbdd5c449a0dc2bb622cb4a47ce._comment18
-rw-r--r--doc/forum/__34__du__34___equivalent_on_an_annex__63__/comment_5_2ee6cbbfe54a2e7b6e8eb539c18e663d._comment10
-rw-r--r--doc/forum/__34__du__34___equivalent_on_an_annex__63__/comment_6_48f6a2761a34b7f991325f1d24e2c5ff._comment8
-rw-r--r--doc/forum/__34__du__34___equivalent_on_an_annex__63__/comment_7_d632baff41b8582f1a79bc5018c68545._comment8
-rw-r--r--doc/forum/__34__git_annex_copy_--to___60__REMOTE__62___.__34___doesn__39__t_send_it_to_working_directory..mdwn11
-rw-r--r--doc/forum/__34__git_annex_copy_--to___60__REMOTE__62___.__34___doesn__39__t_send_it_to_working_directory./comment_1_0c0a5999a92bf5880f2113177dc67cc2._comment11
-rw-r--r--doc/forum/__34__git_annex_copy_--to___60__REMOTE__62___.__34___doesn__39__t_send_it_to_working_directory./comment_2_c18083d9054f66f0bd51d63452af07eb._comment8
-rw-r--r--doc/forum/__34__git_annex_lock__34___very_slow_for_big_repo.mdwn7
-rw-r--r--doc/forum/__34__git_annex_lock__34___very_slow_for_big_repo/comment_1_044f1c5e5f7a939315c28087495a8ba8._comment16
-rw-r--r--doc/forum/__34__git_annex_lock__34___very_slow_for_big_repo/comment_2_e854b93415d5ab80eda8e3be3b145ec2._comment13
-rw-r--r--doc/forum/__34__git_annex_lock__34___very_slow_for_big_repo/comment_3_95c110500bc54013bc1969c1a9c8f842._comment8
-rw-r--r--doc/forum/__34__next_time_Im_online_I_would_like_to_have_file_x_y_z__34__.mdwn5
-rw-r--r--doc/forum/__34__next_time_Im_online_I_would_like_to_have_file_x_y_z__34__/comment_1_bfeb1446dee4d2f52ef25fabfb8cc8f6._comment11
-rw-r--r--doc/forum/__34__next_time_Im_online_I_would_like_to_have_file_x_y_z__34__/comment_2_e60f2bbc1c058993472fd920edbc75fc._comment8
-rw-r--r--doc/forum/__34__permission_denied__34___in_fsck_on_shared_repo.mdwn17
-rw-r--r--doc/forum/__34__permission_denied__34___in_fsck_on_shared_repo/comment_1_3a5202ef2116ebb5559b6f4d920755fc._comment10
-rw-r--r--doc/forum/__34__permission_denied__34___in_fsck_on_shared_repo/comment_2_86663eeb75b0477f53c45f26c8e4b051._comment8
-rw-r--r--doc/forum/__34__permission_denied__34___in_fsck_on_shared_repo/comment_3_c336b2b07cd006d378e5be9639ff17ec._comment10
-rw-r--r--doc/forum/__34__permission_denied__34___in_fsck_on_shared_repo/comment_4_1339cd27ca2955f30b01ecf4da7d6fe8._comment10
-rw-r--r--doc/forum/__34__unable_to_resolve_reference_refs__47__heads__47__git-annex__34__.mdwn34
-rw-r--r--doc/forum/__34__unable_to_resolve_reference_refs__47__heads__47__git-annex__34__/comment_1_e50188896df347f1d92e20a52053aa14._comment10
-rw-r--r--doc/forum/__34__unable_to_resolve_reference_refs__47__heads__47__git-annex__34__/comment_2_d67793f7c969f64943d1fd54a1208c2b._comment15
-rw-r--r--doc/forum/__34__unable_to_resolve_reference_refs__47__heads__47__git-annex__34__/comment_3_3523884833b5fd458a35f898797bf897._comment10
-rw-r--r--doc/forum/__34__unable_to_resolve_reference_refs__47__heads__47__git-annex__34__/comment_4_02c32c2521ba1a1eaa19eaca7281f2a6._comment10
-rw-r--r--doc/forum/__91__Installation__93___base-3.0.3.2_requires_syb___61____61__0.1.0.2.mdwn16
-rw-r--r--doc/forum/__91__Installation__93___base-3.0.3.2_requires_syb___61____61__0.1.0.2/comment_1_fae6e88115d175239fc55cef4c33fb2c._comment13
-rw-r--r--doc/forum/__91__Installation__93___base-3.0.3.2_requires_syb___61____61__0.1.0.2/comment_2_4c7a75638e8717132ccde949018d6008._comment10
-rw-r--r--doc/forum/_preferred_content:_lastpresent.mdwn1
-rw-r--r--doc/forum/_preferred_content:_lastpresent/comment_1_7610cd866b256d36646b642eb5f8cae5._comment14
-rw-r--r--doc/forum/_preferred_content:_lastpresent/comment_2_d25666a173b78213d583f029fd166d06._comment10
-rw-r--r--doc/forum/advantages_of_SHA__42___over_WORM.mdwn5
-rw-r--r--doc/forum/advantages_of_SHA__42___over_WORM/comment_1_96c354cac4b5ce5cf6664943bc84db1d._comment8
-rw-r--r--doc/forum/android_binary-only_download.mdwn9
-rw-r--r--doc/forum/android_binary-only_download/comment_1_aab206e0bf0bb5ff47c7cc9795f12f92._comment8
-rw-r--r--doc/forum/annexed_file_key_for_web_remote_with_SHA256E_backend.mdwn12
-rw-r--r--doc/forum/annexed_file_key_for_web_remote_with_SHA256E_backend/comment_1_d1605a6e3b4d6863f4089218994ce564._comment29
-rw-r--r--doc/forum/annexed_file_key_for_web_remote_with_SHA256E_backend/comment_2_d249ff27fa3d9ac3ca32485cdef49930._comment8
-rw-r--r--doc/forum/archaeology_of_deleted_files.mdwn36
-rw-r--r--doc/forum/archaeology_of_deleted_files/comment_1_48f27df03ec18d2c27cf6b70dcf71dc5._comment10
-rw-r--r--doc/forum/archaeology_of_deleted_files/comment_2_c698cd10c8038bac45bd1049506a27c3._comment8
-rw-r--r--doc/forum/archival_and_multiple_users.mdwn8
-rw-r--r--doc/forum/archival_and_multiple_users/comment_1_fc4ee256f03a7c189d687caf4a34e21e._comment9
-rw-r--r--doc/forum/archival_and_multiple_users/comment_2_a96d57d4bb567ac9b0b9167d5b1be011._comment12
-rw-r--r--doc/forum/archival_and_multiple_users/comment_3_bd44634b04732ffb91154c61ef9cf828._comment14
-rw-r--r--doc/forum/archival_and_multiple_users/comment_4_b89a56a5f1cd641f87925c7a5f74bcec._comment13
-rw-r--r--doc/forum/archival_and_multiple_users/comment_5_81293bf5dc8ad4552712c2083fd589c9._comment19
-rw-r--r--doc/forum/assistant__44___direct_mode__44___large_files__44___command_line_-_how_do_these_play_together__63__.mdwn10
-rw-r--r--doc/forum/assistant__44___direct_mode__44___large_files__44___command_line_-_how_do_these_play_together__63__/comment_1_d90d1d599ce557af03c6f0f2ea188212._comment10
-rw-r--r--doc/forum/assistant__44___direct_mode__44___large_files__44___command_line_-_how_do_these_play_together__63__/comment_2_58b1af497cab132acb28cb5f9283ec2a._comment8
-rw-r--r--doc/forum/assistant__44___direct_mode__44___large_files__44___command_line_-_how_do_these_play_together__63__/comment_3_37d4fd8f69e8066b5aa19454b714e443._comment11
-rw-r--r--doc/forum/assistant__44___direct_mode__44___large_files__44___command_line_-_how_do_these_play_together__63__/comment_4_a974e2105774d4f82ad286ff0792ba84._comment10
-rw-r--r--doc/forum/assistant_created_encrypted__backup_remote:_Howto_restore__63__.mdwn38
-rw-r--r--doc/forum/assistant_created_encrypted__backup_remote:_Howto_restore__63__/comment_1_70200f871b9df49261f32752a6bb0e67._comment14
-rw-r--r--doc/forum/assistant_created_encrypted__backup_remote:_Howto_restore__63__/comment_2_173da510b45f0320ae8aa2df9f14ae7b._comment11
-rw-r--r--doc/forum/assistant_overzealously_moving_stuff_to_other_repos.mdwn5
-rw-r--r--doc/forum/assistant_overzealously_moving_stuff_to_other_repos/comment_1_6bd240edf1868615024ff11c24c3d52c._comment13
-rw-r--r--doc/forum/assistant_overzealously_moving_stuff_to_other_repos/comment_2_37c5e9a7669b5b94fbadb8792a765316._comment8
-rw-r--r--doc/forum/assistant_overzealously_moving_stuff_to_other_repos/comment_3_87aa4c5942929be81ddc1e2795d56f0e._comment9
-rw-r--r--doc/forum/assistant_without_watch__63__.mdwn13
-rw-r--r--doc/forum/assistant_without_watch__63__/comment_1_be1f7c038426e53209a85ae1119269d5._comment15
-rw-r--r--doc/forum/autobuilders_for_git-annex_to_aid_development.mdwn34
-rw-r--r--doc/forum/autobuilders_for_git-annex_to_aid_development/comment_1_7e88f815e8d9652ef18ea6d54b118962._comment8
-rw-r--r--doc/forum/autobuilders_for_git-annex_to_aid_development/comment_2_fef17a10226af5671495c2929653c337._comment8
-rw-r--r--doc/forum/bainstorming:_git_annex_push___38___pull.mdwn28
-rw-r--r--doc/forum/bainstorming:_git_annex_push___38___pull/comment_1_3a0bf74b51586354b7a91f8b43472376._comment11
-rw-r--r--doc/forum/bainstorming:_git_annex_push___38___pull/comment_2_b02ca09914e788393c01196686f95831._comment14
-rw-r--r--doc/forum/bash_completion.mdwn1
-rw-r--r--doc/forum/bash_completion/comment_1_5c42c0c8e7fc3224bf5406880f9fd0c4._comment8
-rw-r--r--doc/forum/bash_completion/comment_2_6cbe3c825db99bf9188a0de8bb937d5b._comment8
-rw-r--r--doc/forum/bash_completion/comment_3_948c40f1e46ca220d61365aebcd4f6d7._comment136
-rw-r--r--doc/forum/bash_completion/comment_4_dbae348b230b780cda91ed8576b8f9fa._comment8
-rw-r--r--doc/forum/batch_check_on_remote_when_using_copy.mdwn34
-rw-r--r--doc/forum/benefit_of_splitting_a_repository.mdwn10
-rw-r--r--doc/forum/benefit_of_splitting_a_repository/comment_1_93a86cb03b66e7ab5dd7146e7b86c9e8._comment15
-rw-r--r--doc/forum/benefit_of_splitting_a_repository/comment_2_4e2fed247298d620fee7be883a1e86a6._comment15
-rw-r--r--doc/forum/cabal_install_fails_on_uuid.mdwn23
-rw-r--r--doc/forum/cabal_install_fails_on_uuid/comment_1_2a3963e21bc7ff526124b902cb0b6ad2._comment8
-rw-r--r--doc/forum/cabal_install_fails_on_uuid/comment_2_1609525998e2b36c04d67f4d988139c0._comment10
-rw-r--r--doc/forum/can_I_only_add_my_own_files__63__.mdwn27
-rw-r--r--doc/forum/can_I_only_add_my_own_files__63__/comment_1_767d647af9d0345f337338d6319071fa._comment10
-rw-r--r--doc/forum/can_I_only_add_my_own_files__63__/comment_2_0c3306ffb38b97b54e1e0436d12c1876._comment8
-rw-r--r--doc/forum/can_git-annex_replace_ddm__63__.mdwn13
-rw-r--r--doc/forum/can_git-annex_replace_ddm__63__/comment_1_aa05008dfe800474ff76678a400099e1._comment12
-rw-r--r--doc/forum/can_git-annex_replace_ddm__63__/comment_2_008554306dd082d7f543baf283510e92._comment19
-rw-r--r--doc/forum/can_git-annex_replace_ddm__63__/comment_3_4c69097fe2ee81359655e59a03a9bb8d._comment12
-rw-r--r--doc/forum/cannot_fetch_from___40__gpg-encrypted__41___rsync_remote_on_MacOSX.mdwn18
-rw-r--r--doc/forum/cannot_fetch_from___40__gpg-encrypted__41___rsync_remote_on_MacOSX/comment_1_21f0101447623f5a0cf9e72c3ff463bb._comment8
-rw-r--r--doc/forum/cannot_fetch_from___40__gpg-encrypted__41___rsync_remote_on_MacOSX/comment_2_6234ca64bd03a0e15efbe8f5c204338a._comment8
-rw-r--r--doc/forum/cannot_fetch_from___40__gpg-encrypted__41___rsync_remote_on_MacOSX/comment_3_5ac2b520a907e232984eb513ce088054._comment8
-rw-r--r--doc/forum/cannot_fetch_from___40__gpg-encrypted__41___rsync_remote_on_MacOSX/comment_4_183dd1c29f66539193e7c0b73f329430._comment9
-rw-r--r--doc/forum/cannot_fetch_from___40__gpg-encrypted__41___rsync_remote_on_MacOSX/comment_5_c920d04ffe332caed9d223fa0ac42746._comment7
-rw-r--r--doc/forum/cannot_fetch_from___40__gpg-encrypted__41___rsync_remote_on_MacOSX/comment_6_7a3cf0853a8ec7b996e19b5e80145d21._comment8
-rw-r--r--doc/forum/central_non-bare_and_git_push.txt9
-rw-r--r--doc/forum/central_non-bare_and_git_push/comment_1_76d0c73c8985e860eb86333c63be6340._comment8
-rw-r--r--doc/forum/clear_box.com_repository.mdwn1
-rw-r--r--doc/forum/clear_box.com_repository/comment_1_2e839d8f974269c80a9fca183712350f._comment8
-rw-r--r--doc/forum/clear_box.com_repository/comment_2_8f9c7248a148a24ae2aba39c4a79a6d1._comment8
-rw-r--r--doc/forum/clear_box.com_repository/comment_3_f64ad21e5abfbf4e1f925b3d651bdba3._comment10
-rw-r--r--doc/forum/clear_box.com_repository/comment_4_f8c06ac9b23b51cf18d362c260fc47a9._comment13
-rw-r--r--doc/forum/clear_box.com_repository/comment_5_61d401b29322802cb25896503f3e6514._comment8
-rw-r--r--doc/forum/cloud_services_to_support.mdwn16
-rw-r--r--doc/forum/cloudcmd.mdwn6
-rw-r--r--doc/forum/commit_current_workdir_state_in_direct_mode.mdwn5
-rw-r--r--doc/forum/commit_current_workdir_state_in_direct_mode/comment_1_748481ff00374f570284bd4571584874._comment10
-rw-r--r--doc/forum/confusion_with_remotes__44___map.mdwn113
-rw-r--r--doc/forum/confusion_with_remotes__44___map/comment_1_a38ded23b7f288292a843abcb1a56f38._comment10
-rw-r--r--doc/forum/confusion_with_remotes__44___map/comment_2_cd1c98b1276444e859a22c3dbd6f2a79._comment8
-rw-r--r--doc/forum/confusion_with_remotes__44___map/comment_3_18531754089c991b6caefc57a5c17fe9._comment24
-rw-r--r--doc/forum/confusion_with_remotes__44___map/comment_4_3b89b6d1518267fcbc050c9de038b9ca._comment11
-rw-r--r--doc/forum/confusion_with_remotes__44___map/comment_5_27801584325d259fa490f67273f2ff71._comment16
-rw-r--r--doc/forum/confusion_with_remotes__44___map/comment_6_496b0d9b86869bbac3a1356d53a3dda4._comment8
-rw-r--r--doc/forum/confusion_with_remotes__44___map/comment_7_9a456f61f956a3d5e81e723d5a90794c._comment27
-rw-r--r--doc/forum/correct_way_to_add_two_preexisting_datasets.mdwn25
-rw-r--r--doc/forum/correct_way_to_add_two_preexisting_datasets/comment_1_c5c3ff25c9f5e34db222b5f4ae58b093._comment10
-rw-r--r--doc/forum/correct_way_to_add_two_preexisting_datasets/comment_2_ee3ecc86990ac5a8d0c4fdfb482a7594._comment16
-rw-r--r--doc/forum/correct_way_to_add_two_preexisting_datasets/comment_3_e29bf8b848da04c761dc601ac979ac14._comment11
-rw-r--r--doc/forum/could_not_read_from_remote_repository.mdwn36
-rw-r--r--doc/forum/could_not_read_from_remote_repository/comment_1_27d4d1556a80c06505ed3d8a9422d082._comment8
-rw-r--r--doc/forum/dot_git_slash_annex_slash_tmp.mdwn5
-rw-r--r--doc/forum/dot_git_slash_annex_slash_tmp/comment_10_14b74438bb1e3e02cff7926d774ba09a._comment8
-rw-r--r--doc/forum/dot_git_slash_annex_slash_tmp/comment_11_b1f717342c1c8ea42a451caa2d936622._comment8
-rw-r--r--doc/forum/dot_git_slash_annex_slash_tmp/comment_12_e2c6ad99333018c8c46e736da416b8ef._comment8
-rw-r--r--doc/forum/dot_git_slash_annex_slash_tmp/comment_1_1a35ef8cb89e0cd392f6e9fcee1fb92c._comment8
-rw-r--r--doc/forum/dot_git_slash_annex_slash_tmp/comment_2_f4cc36c493d7c20fbaf949edd38e1252._comment15
-rw-r--r--doc/forum/dot_git_slash_annex_slash_tmp/comment_3_69268f8aa29e807a56248f1fac86aa41._comment10
-rw-r--r--doc/forum/dot_git_slash_annex_slash_tmp/comment_4_0ffb0c803c232a1587f956f16113aeb7._comment27
-rw-r--r--doc/forum/dot_git_slash_annex_slash_tmp/comment_5_c303e28825241733d69fca74f2015fc6._comment13
-rw-r--r--doc/forum/dot_git_slash_annex_slash_tmp/comment_6_3f0b376e37bd092b8d46c46bb1940e35._comment14
-rw-r--r--doc/forum/dot_git_slash_annex_slash_tmp/comment_7_615641b3dd176d4b3a5bbfb521098e38._comment9
-rw-r--r--doc/forum/dot_git_slash_annex_slash_tmp/comment_8_4600fa9234a787004ea0e0dbb36184b9._comment8
-rw-r--r--doc/forum/dot_git_slash_annex_slash_tmp/comment_9_4f5cd0d0d4db0479c1ad86ffdc5ae434._comment8
-rw-r--r--doc/forum/dropping_files_not_working_when_using_git_annex_assistant.txt18
-rw-r--r--doc/forum/endless_password_prompt_loop.mdwn8
-rw-r--r--doc/forum/endless_password_prompt_loop/comment_1_cceba12ed25cd671c7cee5a28631163e._comment10
-rw-r--r--doc/forum/endless_password_prompt_loop/comment_2_f0cb86b45eb289f35197c43f83660a8f._comment8
-rw-r--r--doc/forum/error_in_installation_of_base-4.5.0.0.mdwn14
-rw-r--r--doc/forum/error_in_installation_of_base-4.5.0.0/comment_1_0b2f79c014e0dd9badd52b8b6aa47e0c._comment19
-rw-r--r--doc/forum/error_in_installation_of_base-4.5.0.0/comment_2_3badd64e48fbb174cd7de1ac9589bedf._comment31
-rw-r--r--doc/forum/error_in_installation_of_base-4.5.0.0/comment_3_d8190061ac1c683a7b699cf42e9db694._comment8
-rw-r--r--doc/forum/error_in_installation_of_base-4.5.0.0/comment_4_49a4fcd2dc4f97d4055b5051feea5e3b._comment8
-rw-r--r--doc/forum/example_of_massively_disconnected_operation.mdwn33
-rw-r--r--doc/forum/exclude_files_from_annex.mdwn10
-rw-r--r--doc/forum/exclude_files_from_annex/comment_1_82e7de5e631bae3b347815586274a936._comment25
-rw-r--r--doc/forum/exclude_files_from_annex/comment_2_03d4599fdceb3dff184eed82824674bc._comment12
-rw-r--r--doc/forum/expire_files__44___move_to_other_hosts.mdwn19
-rw-r--r--doc/forum/expire_files__44___move_to_other_hosts/comment_1_ddcc2a00be1ae96a352d75a443458bcf._comment14
-rw-r--r--doc/forum/expire_files__44___move_to_other_hosts/comment_2_7a4c3858c5eae409d04de3f9da43b57e._comment17
-rw-r--r--doc/forum/exporting_annexed_files.mdwn4
-rw-r--r--doc/forum/exporting_annexed_files/comment_1_e08e4c79588e17fb2f1cdf53d9fab7ea._comment16
-rw-r--r--doc/forum/exporting_annexed_files/comment_2_15dc3024417b5b2ff3544a08beacab34._comment8
-rw-r--r--doc/forum/exporting_annexed_files/comment_3_86f0e0f767a84a0f583e121d36cb7d48._comment8
-rw-r--r--doc/forum/fail_to_git_annex_add_some_files:_getFileStatus:_does_not_exist__40__v_3.20111231__41__.mdwn26
-rw-r--r--doc/forum/fail_to_git_annex_add_some_files:_getFileStatus:_does_not_exist__40__v_3.20111231__41__/comment_1_990197bf01351dc1ccbe1940d5084adb._comment7
-rw-r--r--doc/forum/fail_to_git_annex_add_some_files:_getFileStatus:_does_not_exist__40__v_3.20111231__41__/comment_2_3bb1d21b7f0d0bd6d59190ae9d246d46._comment12
-rw-r--r--doc/forum/fail_to_git_annex_add_some_files:_getFileStatus:_does_not_exist__40__v_3.20111231__41__/comment_3_692f268218690437138ae0540c879425._comment16
-rw-r--r--doc/forum/first-time_setup_git-annex.mdwn7
-rw-r--r--doc/forum/first-time_setup_git-annex/comment_1_a58d83ee3a7c2251d9a775847223f8ca._comment13
-rw-r--r--doc/forum/flickrannex_--_not_sure_I_get_it.mdwn7
-rw-r--r--doc/forum/flickrannex_--_not_sure_I_get_it/comment_1_57ea9f26760f970a70f09934d31a79b5._comment8
-rw-r--r--doc/forum/flickrannex_--_not_sure_I_get_it/comment_2_ba93563b4ce1f6497a9f1d5e6eb0d1bb._comment8
-rw-r--r--doc/forum/flickrannex_--_not_sure_I_get_it/comment_3_74f143965f48c89a3583acf1b6a7635a._comment9
-rw-r--r--doc/forum/flickrannex_--_not_sure_I_get_it/comment_4_493bb86dedfa91ccc0c9be4045953ee4._comment8
-rw-r--r--doc/forum/flickrannex_--_not_sure_I_get_it/comment_5_2c410aa478b21c0e6eb0e4d54bc8c362._comment8
-rw-r--r--doc/forum/fsck_gives_false_positives.mdwn6
-rw-r--r--doc/forum/fsck_gives_false_positives/comment_1_b91070218b9d5fb687eeee1f244237ad._comment15
-rw-r--r--doc/forum/fsck_gives_false_positives/comment_2_f51c53f3f6e6ee1ad463992657db5828._comment10
-rw-r--r--doc/forum/fsck_gives_false_positives/comment_3_692d6d4cd2f75a497e7d314041a768d2._comment10
-rw-r--r--doc/forum/fsck_gives_false_positives/comment_4_7ceb395bf8a2e6a041ccd8de63b1b6eb._comment10
-rw-r--r--doc/forum/fsck_gives_false_positives/comment_5_86484a504c3bbcecd5876982b9c95688._comment13
-rw-r--r--doc/forum/fsck_gives_false_positives/comment_6_1d4fbbd212fa92967abda346323031f4._comment8
-rw-r--r--doc/forum/gadu_-_git-annex_disk_usage.mdwn7
-rw-r--r--doc/forum/gadu_-_git-annex_disk_usage/comment_10_f632a62c4dbbf01b29f146893d7725f9._comment15
-rw-r--r--doc/forum/gadu_-_git-annex_disk_usage/comment_11_73461da2d55d040cb43e0db286975821._comment21
-rw-r--r--doc/forum/gadu_-_git-annex_disk_usage/comment_12_6c4fb123091bde435c18ac3dfd5a9b77._comment8
-rw-r--r--doc/forum/gadu_-_git-annex_disk_usage/comment_1_067d0ffe8900751bd2d2743254ac4d77._comment11
-rw-r--r--doc/forum/gadu_-_git-annex_disk_usage/comment_2_ec8b57426e4d82c3392eb7dd683f2ddc._comment17
-rw-r--r--doc/forum/gadu_-_git-annex_disk_usage/comment_3_38296fef5a2dc5794c2dc09df676b8c1._comment18
-rw-r--r--doc/forum/gadu_-_git-annex_disk_usage/comment_4_1bcc94f9982c6cfd0888f3dba0f9221e._comment8
-rw-r--r--doc/forum/gadu_-_git-annex_disk_usage/comment_5_4365cd3031456fac1b563ee72984638e._comment18
-rw-r--r--doc/forum/gadu_-_git-annex_disk_usage/comment_6_2b03d7b857497cb811e992f85700cdcc._comment12
-rw-r--r--doc/forum/gadu_-_git-annex_disk_usage/comment_7_03a4dfaf3bd73d41c6f3c3fab0a6a922._comment8
-rw-r--r--doc/forum/gadu_-_git-annex_disk_usage/comment_8_fc6ddb4dc075ee42368863c1b026dbf7._comment13
-rw-r--r--doc/forum/gadu_-_git-annex_disk_usage/comment_9_f03254e518cbdda73e4b88e72476275d._comment8
-rw-r--r--doc/forum/get_and_copy_with_bare_repositories.mdwn7
-rw-r--r--doc/forum/get_and_copy_with_bare_repositories/comment_1_a6e4628c0770e3f5e81348a6f29dd845._comment10
-rw-r--r--doc/forum/get_and_copy_with_bare_repositories/comment_2_652fa1bae5c2bb63dcffcbda97a567c4._comment8
-rw-r--r--doc/forum/getting_git_annex_to_do_a_force_copy_to_a_remote.mdwn11
-rw-r--r--doc/forum/getting_git_annex_to_do_a_force_copy_to_a_remote/comment_1_3deb2c31cad37a49896f00d600253ee3._comment14
-rw-r--r--doc/forum/getting_git_annex_to_do_a_force_copy_to_a_remote/comment_2_627f54d158d3ca4b72e45b4da70ff5cd._comment12
-rw-r--r--doc/forum/getting_git_annex_to_do_a_force_copy_to_a_remote/comment_3_3f49dab11aae5df0c4eb5e4b8d741379._comment8
-rw-r--r--doc/forum/git-annex___38___ikiwiki_experiment.mdwn28
-rw-r--r--doc/forum/git-annex___38___ikiwiki_experiment/comment_1_9f74449ec91577dbf6095f4beafac293._comment10
-rw-r--r--doc/forum/git-annex___38___ikiwiki_experiment/comment_2_e034585c8b51cc30b35c1f7ae68205bf._comment14
-rw-r--r--doc/forum/git-annex___38___ikiwiki_experiment/comment_3_fbbd47c3dbe8de24b0df664e4afd5cb8._comment14
-rw-r--r--doc/forum/git-annex___38___ikiwiki_experiment/comment_4_55da5c3c41c13b08590ce1ff8117cef6._comment23
-rw-r--r--doc/forum/git-annex___38___ikiwiki_experiment/comment_5_f67823351164ddfe7d595685c3679652._comment10
-rw-r--r--doc/forum/git-annex___38___ikiwiki_experiment/comment_6_d5cc91164772849d027fed5f962d9000._comment10
-rw-r--r--doc/forum/git-annex___38___ikiwiki_experiment/comment_7_cb4ec7ed3c39d0649133191a85ea6ab3._comment17
-rw-r--r--doc/forum/git-annex___38___ikiwiki_experiment/comment_8_86565e5e1508ff1862f88975446650a2._comment12
-rw-r--r--doc/forum/git-annex_across_two_filesystems.mdwn30
-rw-r--r--doc/forum/git-annex_across_two_filesystems/comment_1_53167648b8b70b41d19ca662a5f3687e._comment26
-rw-r--r--doc/forum/git-annex_across_two_filesystems/comment_2_39adeebc1af9c437f1fc2e00c07509bf._comment11
-rw-r--r--doc/forum/git-annex_across_two_filesystems/comment_3_f4e3f28db005301adeef7ccd2c9998fb._comment18
-rw-r--r--doc/forum/git-annex_across_two_filesystems/comment_4_53fa7ac6f80e3281768a7bfd3d438b34._comment10
-rw-r--r--doc/forum/git-annex_across_two_filesystems/comment_5_2e1be54c01970ef3456e8af4aaf00cbf._comment10
-rw-r--r--doc/forum/git-annex_and_tagfs.mdwn14
-rw-r--r--doc/forum/git-annex_and_tagfs/comment_1_887c74cb61d30198322ef74ebc80f950._comment8
-rw-r--r--doc/forum/git-annex_assistant_with_2_dedicated_servers.mdwn11
-rw-r--r--doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_10_533ade2215c879cd46782fd66a97b167._comment16
-rw-r--r--doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_11_c9ae51d7b772cf7a91d90925f74d2b60._comment10
-rw-r--r--doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_12_41fbee0ec9bc890e309bcd48a58c3851._comment18
-rw-r--r--doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_13_571cffc0beb8ba5fc936db6971cd3d62._comment8
-rw-r--r--doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_1_53a79af2d8e3abe50b983bf91972b8f2._comment14
-rw-r--r--doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_2_c0ba3e8b7fbf8a5ed718001cec8df676._comment35
-rw-r--r--doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_3_60c39bc8ef74e80e72381d514b6dd223._comment8
-rw-r--r--doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_4_6241120b4325c905661ef72881f4d7af._comment20
-rw-r--r--doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_5_cab00b8fa195340f4d3fdaf5af975b57._comment8
-rw-r--r--doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_6_e24df9a1c68724a912b8ac6533d9bd25._comment16
-rw-r--r--doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_7_ace3dc7c60c710a04b0a587206b341c4._comment8
-rw-r--r--doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_8_9a96bc970a17ed62b0ceb7aa3f0a6f8b._comment14
-rw-r--r--doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_9_ea88e0696f6e25e6904248a323f6cc36._comment8
-rw-r--r--doc/forum/git-annex_build_for_Nokia_N9___40__Meego_Harmattan__41___and_Sailfish_OS.mdwn7
-rw-r--r--doc/forum/git-annex_build_for_Nokia_N9___40__Meego_Harmattan__41___and_Sailfish_OS/comment_1_301a51c48c3d54f9d37feace26a772f8._comment8
-rw-r--r--doc/forum/git-annex_communication_channels.mdwn10
-rw-r--r--doc/forum/git-annex_communication_channels/comment_1_198325d2e9337c90f026396de89eec0e._comment17
-rw-r--r--doc/forum/git-annex_communication_channels/comment_2_c7aeefa6ef9a2e75d8667b479ade1b7f._comment8
-rw-r--r--doc/forum/git-annex_communication_channels/comment_3_1ff08a3e0e63fa0e560cbc9602245caa._comment8
-rw-r--r--doc/forum/git-annex_communication_channels/comment_4_1ba6ddf54843c17c7d19a9996f2ab712._comment8
-rw-r--r--doc/forum/git-annex_communication_channels/comment_5_404b723a681eb93fee015cea8024b6bc._comment8
-rw-r--r--doc/forum/git-annex_communication_channels/comment_6_0d87d0e26461494b1d7f8a701a924729._comment8
-rw-r--r--doc/forum/git-annex_communication_channels/comment_7_2c87c7a0648fe87c2bf6b4391f1cc468._comment10
-rw-r--r--doc/forum/git-annex_on_OSX.mdwn1
-rw-r--r--doc/forum/git-annex_on_Samba_share.mdwn9
-rw-r--r--doc/forum/git-annex_on_Samba_share/comment_1_3e9cfdf2c088e48c967ad08f79966742._comment12
-rw-r--r--doc/forum/git-annex_on_Samba_share/comment_2_9d3df393b7b727653598453d94dd33db._comment12
-rw-r--r--doc/forum/git-annex_on_Ubuntu_13.04_and_13.10_not_working.mdwn12
-rw-r--r--doc/forum/git-annex_on_Ubuntu_13.04_and_13.10_not_working/comment_1_209956f3812450a43986d4ca5e647da6._comment10
-rw-r--r--doc/forum/git-annex_on_Ubuntu_13.04_and_13.10_not_working/comment_3_12a58b8efe545e09b64760c87849839b._comment12
-rw-r--r--doc/forum/git-annex_on_Ubuntu_13.04_and_13.10_not_working/comment_3_e0f7328603256f25c3be3706ecc9c76c._comment12
-rw-r--r--doc/forum/git-annex_on_Ubuntu_13.04_and_13.10_not_working/comment_4_6bb8e4522241556fb82784d9b834cbfe._comment10
-rw-r--r--doc/forum/git-annex_on_Ubuntu_13.04_and_13.10_not_working/comment_5_89a5296b461d400b51006074a13a4560._comment8
-rw-r--r--doc/forum/git-annex_on_Ubuntu_13.04_and_13.10_not_working/comment_6_62daef4b4392c951b914a01b3effac11._comment8
-rw-r--r--doc/forum/git-annex_on_archlinuxarm__44___armv6.mdwn20
-rw-r--r--doc/forum/git-annex_on_archlinuxarm__44___armv6/comment_1_88fa644df8614c2db0d092b3eb1d3156._comment10
-rw-r--r--doc/forum/git-annex_pre-commit_eats_all_my_4GB_of_ram.mdwn24
-rw-r--r--doc/forum/git-annex_pre-commit_eats_all_my_4GB_of_ram/comment_1_ff16c7932b60b85c744bafc48bb040e4._comment13
-rw-r--r--doc/forum/git-annex_pre-commit_eats_all_my_4GB_of_ram/comment_2_5599cddf579d18f70cab6e48d04ae99d._comment12
-rw-r--r--doc/forum/git-annex_pre-commit_eats_all_my_4GB_of_ram/comment_3_412941e9385f63153b23695641e71deb._comment15
-rw-r--r--doc/forum/git-annex_pre-commit_eats_all_my_4GB_of_ram/comment_4_112ad140d9006c530db2121bec24de30._comment10
-rw-r--r--doc/forum/git-annex_pre-commit_eats_all_my_4GB_of_ram/comment_5_9178023b95683a649355f291165a1467._comment8
-rw-r--r--doc/forum/git-annex_pre-commit_eats_all_my_4GB_of_ram/comment_6_9251203421c1c3c3aed7828c4b97ecb8._comment17
-rw-r--r--doc/forum/git-annex_teams___47___groups.mdwn5
-rw-r--r--doc/forum/git-annex_teams___47___groups/comment_1_0450673ab74f184a47ac7bab568d26dc._comment8
-rw-r--r--doc/forum/git-annex_unused_not_dropping_deleted_files.mdwn34
-rw-r--r--doc/forum/git-annex_unused_not_dropping_deleted_files/comment_1_2152cfb09675e46e7492e198dd3ea094._comment8
-rw-r--r--doc/forum/git-annex_unused_not_dropping_deleted_files/comment_2_97e666dbac9de2a5e688921cba8a42e9._comment20
-rw-r--r--doc/forum/git-annex_unused_not_dropping_deleted_files/comment_3_d7b0e9515bface28f3650b8aa20ec2f4._comment8
-rw-r--r--doc/forum/git-annex_unused_not_dropping_deleted_files/comment_4_5816f6cab42e27e724e735368f693b09._comment8
-rw-r--r--doc/forum/git-annex_unused_not_dropping_deleted_files/comment_5_8e97f39225515f0bf8b168dfd6a0efab._comment10
-rw-r--r--doc/forum/git-annex_unused_not_dropping_deleted_files/comment_6_bef37f8ec9c337387b79ffd6d56fe425._comment10
-rw-r--r--doc/forum/git-assistant_clarification.mdwn11
-rw-r--r--doc/forum/git-assistant_clarification/comment_1_8f553e59da12f798b854a457b96b5778._comment14
-rw-r--r--doc/forum/git-assistant_clarification/comment_2_06cf62b599edea6ad8396776f0081494._comment10
-rw-r--r--doc/forum/git-assistant_clarification/comment_3_36f0bd6e7a824e6ef40a309850bb087b._comment15
-rw-r--r--doc/forum/git-remote-gcrypt.mdwn1
-rw-r--r--doc/forum/git-remote-gcrypt/comment_1_175c8c35d9bbb470fcc17697eb8cc6b8._comment12
-rw-r--r--doc/forum/git-remote-gcrypt/comment_2_fdcaf507e14c995636dd93a41e488df3._comment8
-rw-r--r--doc/forum/git-remote-gcrypt/comment_3_f4e830f961dbe1c60ddd277b9d888133._comment8
-rw-r--r--doc/forum/git-status_typechange_in_direct_mode.mdwn48
-rw-r--r--doc/forum/git-status_typechange_in_direct_mode/comment_1_12c8b67aadbfa2b073e12997a55d49a7._comment12
-rw-r--r--doc/forum/git-status_typechange_in_direct_mode/comment_2_005d1b17f3c2ae192aa30c6e5163989e._comment8
-rw-r--r--doc/forum/git-subtree_support__63__.mdwn9
-rw-r--r--doc/forum/git-subtree_support__63__/comment_1_4f333cb71ed1ff259bbfd86704806aa6._comment10
-rw-r--r--doc/forum/git-subtree_support__63__/comment_2_73d2a015b1ac79ec99e071a8b1e29034._comment8
-rw-r--r--doc/forum/git-subtree_support__63__/comment_3_c533400e22c306c033fcd56e64761b0b._comment8
-rw-r--r--doc/forum/git-subtree_support__63__/comment_4_75b0e072e668aa46ff0a8d62a6620306._comment8
-rw-r--r--doc/forum/git-subtree_support__63__/comment_5_f5ec9649d9f1dc122e715de5533bc674._comment8
-rw-r--r--doc/forum/git-subtree_support__63__/comment_6_85df530f7b6d76b74ac8017c6034f95e._comment8
-rw-r--r--doc/forum/git_annex_add_crash_and_subsequent_recovery.mdwn25
-rw-r--r--doc/forum/git_annex_add_crash_and_subsequent_recovery/comment_1_062d0153a379c1ba1df8585b90220d3d._comment18
-rw-r--r--doc/forum/git_annex_add_crash_and_subsequent_recovery/comment_2_6fc6be43c488c468a4811cd0a1360225._comment19
-rw-r--r--doc/forum/git_annex_add_crash_and_subsequent_recovery/comment_3_45efaaf27d9b580c4c75cbcdc4f65b64._comment10
-rw-r--r--doc/forum/git_annex_add_crash_and_subsequent_recovery/comment_4_c560eae40867512b0af2cbef161fc8ac._comment8
-rw-r--r--doc/forum/git_annex_alternative.mdwn10
-rw-r--r--doc/forum/git_annex_assistant__44___share_with_other_devices.mdwn3
-rw-r--r--doc/forum/git_annex_copy_--fast_--to_blah_much_slower_than_--from_blah.mdwn15
-rw-r--r--doc/forum/git_annex_copy_--fast_--to_blah_much_slower_than_--from_blah/comment_1_5b6e0b749b01a97a6b52a2c1cca6e35a._comment12
-rw-r--r--doc/forum/git_annex_copy_--fast_--to_blah_much_slower_than_--from_blah/comment_2_8f2567f4c4f6db2078211a87689757d3._comment17
-rw-r--r--doc/forum/git_annex_copy_--fast_--to_blah_much_slower_than_--from_blah/comment_3_ab98121076b88f351fc8cd9197e6bf64._comment8
-rw-r--r--doc/forum/git_annex_copy_--fast_--to_blah_much_slower_than_--from_blah/comment_4_cb13328add1b7a812efd817ad3dd1a4f._comment8
-rw-r--r--doc/forum/git_annex_failing_to_get_non-English_filenames.__Rsync_problem__63__.mdwn22
-rw-r--r--doc/forum/git_annex_failing_to_get_non-English_filenames.__Rsync_problem__63__/comment_1_292ee7c8b37cbd13f03eb67d0359b99e._comment10
-rw-r--r--doc/forum/git_annex_failing_to_get_non-English_filenames.__Rsync_problem__63__/comment_2_f6341119fcfde5d8160c8f603b1a6fea._comment10
-rw-r--r--doc/forum/git_annex_failing_to_get_non-English_filenames.__Rsync_problem__63__/comment_3_8ad3a1d1fe5995d61e5e137280bc76c3._comment8
-rw-r--r--doc/forum/git_annex_failing_to_get_non-English_filenames.__Rsync_problem__63__/comment_4_86b61b0484f3f4ecff657e46333b3d4f._comment8
-rw-r--r--doc/forum/git_annex_failing_to_get_non-English_filenames.__Rsync_problem__63__/comment_5_5ffac00d08d26acaba8c3513b24c4d65._comment10
-rw-r--r--doc/forum/git_annex_get_creates_a_new_uuid.mdwn6
-rw-r--r--doc/forum/git_annex_get_creates_a_new_uuid/comment_1_004c87183968c326058bd3159a5baa0b._comment14
-rw-r--r--doc/forum/git_annex_ls___47___metadata_in_git_annex_whereis.mdwn1
-rw-r--r--doc/forum/git_annex_ls___47___metadata_in_git_annex_whereis/comment_1_7fba10b85f4d9289c7782eccef46949e._comment8
-rw-r--r--doc/forum/git_annex_ls___47___metadata_in_git_annex_whereis/comment_2_7dcec124ea7d0291ed40d80e2ffd5c7e._comment8
-rw-r--r--doc/forum/git_annex_sync_dies___40__sometimes__41__.mdwn22
-rw-r--r--doc/forum/git_annex_sync_dies___40__sometimes__41__/comment_1_48bbac0545bf13bbf04da723e418d037._comment14
-rw-r--r--doc/forum/git_annex_test_on_windows.mdwn5
-rw-r--r--doc/forum/git_annex_test_on_windows/comment_1_258ac5cfa2f5d24e737d94dc48f06899._comment10
-rw-r--r--doc/forum/git_pull_remote_git-annex.mdwn11
-rw-r--r--doc/forum/git_pull_remote_git-annex/comment_1_9c245db3518d8b889ecdf5115ad9e053._comment36
-rw-r--r--doc/forum/git_pull_remote_git-annex/comment_2_0f7f4a311b0ec1d89613e80847e69b42._comment14
-rw-r--r--doc/forum/git_pull_remote_git-annex/comment_3_1aa89725b5196e40a16edeeb5ccfa371._comment14
-rw-r--r--doc/forum/git_pull_remote_git-annex/comment_4_646f2077edcabc000a7d9cb75a93cf55._comment37
-rw-r--r--doc/forum/git_pull_remote_git-annex/comment_5_4f2a05ef6551806dd0ec65372f183ca4._comment10
-rw-r--r--doc/forum/git_pull_remote_git-annex/comment_6_3925d1aa56bce9380f712e238d63080f._comment8
-rw-r--r--doc/forum/git_pull_remote_git-annex/comment_7_24c45ee981b18bc78325c768242e635d._comment8
-rw-r--r--doc/forum/git_pull_remote_git-annex/comment_8_7e76ee9b6520cbffaf484c9299a63ad3._comment12
-rw-r--r--doc/forum/git_tag_missing_for_3.20111011.mdwn1
-rw-r--r--doc/forum/git_tag_missing_for_3.20111011/comment_1_7a53bf273f3078ab3351369ef2b5f2a6._comment8
-rw-r--r--doc/forum/git_unannex_speed.mdwn1
-rw-r--r--doc/forum/git_unannex_speed/comment_1_10cf326248f4e89e1f75bf97d7574763._comment7
-rw-r--r--doc/forum/glacier_-_range_retrievals_and_daily_free_retrieval_allowance.mdwn6
-rw-r--r--doc/forum/hashing_objects_directories.mdwn27
-rw-r--r--doc/forum/hashing_objects_directories/comment_1_c55c56076be4f54251b0b7f79f28a607._comment12
-rw-r--r--doc/forum/hashing_objects_directories/comment_2_504c96959c779176f991f4125ea22009._comment14
-rw-r--r--doc/forum/hashing_objects_directories/comment_3_9134bde0a13aac0b6a4e5ebabd7f22e8._comment12
-rw-r--r--doc/forum/hashing_objects_directories/comment_4_0de9170e429cbfea66f5afa8980d45ac._comment12
-rw-r--r--doc/forum/hashing_objects_directories/comment_5_ef6cfd49d24c180c2d0a062e5bd3a0be._comment12
-rw-r--r--doc/forum/help_running_git-annex_on_top_of_existing_repo.mdwn12
-rw-r--r--doc/forum/help_running_git-annex_on_top_of_existing_repo/comment_1_4cb38d71c943657c5ba0896cd70d2e64._comment8
-rw-r--r--doc/forum/help_running_git-annex_on_top_of_existing_repo/comment_2_b5e94c10ebbed9125c7e2332f75709ca._comment13
-rw-r--r--doc/forum/help_running_git-annex_on_top_of_existing_repo/comment_3_2b3b93bbc60fbc24d436231954d6822a._comment10
-rw-r--r--doc/forum/help_running_git-annex_on_top_of_existing_repo/comment_4_2dfda33ffa39b92b16c8bd9005e1cefe._comment21
-rw-r--r--doc/forum/help_running_git-annex_on_top_of_existing_repo/comment_5_96b1eb1e8e9f315c646f4686870f9b52._comment10
-rw-r--r--doc/forum/help_running_git-annex_on_top_of_existing_repo/comment_6_e85c3fa1d17f1d6ec625b9c4f9b698c3._comment47
-rw-r--r--doc/forum/how_to_decrypt_file_from_encrypted_special_remote__63__.mdwn14
-rw-r--r--doc/forum/how_to_decrypt_file_from_encrypted_special_remote__63__/comment_1_d4dc451892e7a6e230bf32adb7f3f9fa._comment8
-rw-r--r--doc/forum/how_to_decrypt_file_from_encrypted_special_remote__63__/comment_2_79340bf3c0691073a9808c5ac2da0a3d._comment14
-rw-r--r--doc/forum/how_to_decrypt_file_from_encrypted_special_remote__63__/comment_3_6302fb6e5bb7cbddf2cfe74d98d32897._comment12
-rw-r--r--doc/forum/how_to_decrypt_file_from_encrypted_special_remote__63__/comment_4_e3d95bc09c9fb21e8e9bbacc642aa60f._comment8
-rw-r--r--doc/forum/how_to_decrypt_file_from_encrypted_special_remote__63__/comment_5_f2f0a1c2fb0c6323707b11e2b06aa2db._comment8
-rw-r--r--doc/forum/how_to_decrypt_file_from_encrypted_special_remote__63__/comment_6_66fe80e634a8f13cce18fe68974ec67a._comment8
-rw-r--r--doc/forum/how_to_remove_files_and_symlinks_but_keep_historical_file_contents.mdwn7
-rw-r--r--doc/forum/how_to_remove_files_and_symlinks_but_keep_historical_file_contents/comment_1_cba76311e146dabb8ffc789bf4c8b714._comment14
-rw-r--r--doc/forum/how_to_remove_files_and_symlinks_but_keep_historical_file_contents/comment_2_8d99c50fc1347367ccc0714e8d1af385._comment40
-rw-r--r--doc/forum/how_to_remove_files_and_symlinks_but_keep_historical_file_contents/comment_3_a7a9c55c2ad448179dff5d5b69976c7d._comment10
-rw-r--r--doc/forum/howto_update_feed.mdwn14
-rw-r--r--doc/forum/howto_update_feed/comment_1_bec356619f370a618f19a187d09d2e35._comment8
-rw-r--r--doc/forum/howto_update_feed/comment_2_84dfb80ba3db8d41164eb97022becae3._comment8
-rw-r--r--doc/forum/howto_update_feed/comment_3_20166db298c10074e062aecad59ffd71._comment20
-rw-r--r--doc/forum/howto_update_feed/comment_4_f040e31b763fc9a7aa092442b4d6b8e8._comment20
-rw-r--r--doc/forum/incompatible_versions__63__.mdwn1
-rw-r--r--doc/forum/incompatible_versions__63__/comment_1_629f28258746d413e452cbd42a1a43f4._comment8
-rw-r--r--doc/forum/known_and_local_annex_keys.mdwn14
-rw-r--r--doc/forum/known_and_local_annex_keys/comment_1_3cb4828dc7116e4cf49e119f055ae9a3._comment20
-rw-r--r--doc/forum/known_and_local_annex_keys/comment_2_68f20c881eafe986694bde10571cf1c0._comment10
-rw-r--r--doc/forum/known_and_local_annex_keys/comment_3_e195a7091a06ce0427bb28aca9a17d04._comment8
-rw-r--r--doc/forum/known_and_local_annex_keys/comment_4_d81f0bf7465832cb676fd89f5d53ec18._comment8
-rw-r--r--doc/forum/linux_standalone_tarballs.mdwn1
-rw-r--r--doc/forum/linux_standalone_tarballs/comment_1_5c3ceb845a45e50784f7098bfbf94df1._comment13
-rw-r--r--doc/forum/location_tracking_cleanup.mdwn24
-rw-r--r--doc/forum/location_tracking_cleanup/comment_1_7d6319e8c94dfe998af9cfcbf170efb2._comment10
-rw-r--r--doc/forum/location_tracking_cleanup/comment_2_e7395cb6e01f42da72adf71ea3ebcde4._comment15
-rw-r--r--doc/forum/location_tracking_cleanup/comment_3_c15428cec90e969284a5e690fb4b2fde._comment10
-rw-r--r--doc/forum/lost_in_walkthrough....txt78
-rw-r--r--doc/forum/lost_in_walkthrough.../comment_1_51b703b961ca762f0359e1c169f1ee75._comment8
-rw-r--r--doc/forum/lost_in_walkthrough.../comment_2_a9de0401a103bdd4401ba2d5983dc54a._comment11
-rw-r--r--doc/forum/making_good_use_of_my_shiny_new_rsync.net_account.mdwn20
-rw-r--r--doc/forum/making_good_use_of_my_shiny_new_rsync.net_account/comment_1_0ebe509b768d46081db2100f5b712ef7._comment10
-rw-r--r--doc/forum/making_good_use_of_my_shiny_new_rsync.net_account/comment_2_ef63d893531d93d2eb09f48f8baff4dd._comment13
-rw-r--r--doc/forum/man_pages_in_the_prebuilt_linux_tarball.mdwn1
-rw-r--r--doc/forum/man_pages_in_the_prebuilt_linux_tarball/comment_1_a7bc2e84e6d7c0e2de5900685207af78._comment9
-rw-r--r--doc/forum/managing_multiple_repositories.mdwn3
-rw-r--r--doc/forum/manual_update_of_.git__47__annex__47__objects.txt8
-rw-r--r--doc/forum/manual_update_of_.git__47__annex__47__objects/comment_1_ea6ec91150c8962e2711631f2422bf3a._comment10
-rw-r--r--doc/forum/many_remotes.mdwn24
-rw-r--r--doc/forum/migrate_existing_git_repository_to_git-annex.mdwn66
-rw-r--r--doc/forum/migrate_existing_git_repository_to_git-annex/comment_1_4181bf34c71e2e8845e6e5fb55d53381._comment10
-rw-r--r--doc/forum/migrate_existing_git_repository_to_git-annex/comment_2_5f08da5e21c0b3b5a8d1e4408c0d6405._comment60
-rw-r--r--doc/forum/migrate_existing_git_repository_to_git-annex/comment_3_f483038c006cf7dcccf1014fa771744f._comment12
-rw-r--r--doc/forum/migration_to_git-annex_and_rsync.mdwn33
-rw-r--r--doc/forum/mistakenly_checked___42__files__42___into_an_annex.__bummer..mdwn3
-rw-r--r--doc/forum/mistakenly_checked___42__files__42___into_an_annex.__bummer./comment_1_752db25abb647804a1cc12c5b247378a._comment10
-rw-r--r--doc/forum/mistakenly_checked___42__files__42___into_an_annex.__bummer./comment_2_db6f4959c35732f72e7a90bd9f4c665c._comment8
-rw-r--r--doc/forum/multiple_routes_to_same_repository.mdwn2
-rw-r--r--doc/forum/multiple_routes_to_same_repository/comment_1_26c1734d41d5374f18fc688d862d6b8e._comment8
-rw-r--r--doc/forum/multiple_routes_to_same_repository/comment_2_d119ab485fb2d5512c15372efdb2327d._comment8
-rw-r--r--doc/forum/multiple_sym_links___40__for_tagging_photos__41____63__.mdwn11
-rw-r--r--doc/forum/multiple_sym_links___40__for_tagging_photos__41____63__/comment_1_96beb9ea895c80285748adb940b4f57d._comment9
-rw-r--r--doc/forum/multiple_sym_links___40__for_tagging_photos__41____63__/comment_2_985065c1feed9300631dac7a2701f669._comment8
-rw-r--r--doc/forum/multiple_urls_for_the_same_UUID.mdwn26
-rw-r--r--doc/forum/multiple_urls_for_the_same_UUID/comment_1_de7410d8824a864c4d106c9f1afaec3f._comment8
-rw-r--r--doc/forum/multiple_urls_for_the_same_UUID/comment_2_309a86cf7e08448be64357a30d8b56ae._comment13
-rw-r--r--doc/forum/multiple_urls_for_the_same_UUID/comment_3_fa97a45fc1392935fd5e0714db999bc2._comment14
-rw-r--r--doc/forum/multiple_urls_for_the_same_UUID/comment_4_139178b1ba45b62eec0c89a660c0c81e._comment8
-rw-r--r--doc/forum/new_microfeatures.mdwn59
-rw-r--r--doc/forum/new_microfeatures/comment_1_058bd517c6fffaf3446b1f5d5be63623._comment8
-rw-r--r--doc/forum/new_microfeatures/comment_2_41ad904c68e89c85e1fc49c9e9106969._comment8
-rw-r--r--doc/forum/new_microfeatures/comment_3_a1a9347b5bc517f2a89a8b292c3f8517._comment15
-rw-r--r--doc/forum/new_microfeatures/comment_4_5a6786dc52382fff5cc42fdb05770196._comment18
-rw-r--r--doc/forum/new_microfeatures/comment_5_3c627d275586ff499d928a8f8136babf._comment8
-rw-r--r--doc/forum/new_microfeatures/comment_6_31ea08c008500560c0b96c6601bc6362._comment8
-rw-r--r--doc/forum/new_microfeatures/comment_7_94045b9078b1fff877933b012d1b49e2._comment10
-rw-r--r--doc/forum/nntp__47__usenet_special_remote.mdwn18
-rw-r--r--doc/forum/nntp__47__usenet_special_remote/comment_1_171a0b95b1f95cfd82073e88bdefaab9._comment10
-rw-r--r--doc/forum/nntp__47__usenet_special_remote/comment_2_48736ed17c98ffcfb13ec00b901b2dd6._comment13
-rw-r--r--doc/forum/non-bare_repo_on_cloud_remote.mdwn6
-rw-r--r--doc/forum/non-bare_repo_on_cloud_remote/comment_1_da0c023af7c78f1ef1cfe1143a900a9f._comment10
-rw-r--r--doc/forum/non-bare_repo_on_cloud_remote/comment_2_71baea93f6caaf7b81a9ac00bee91e5e._comment67
-rw-r--r--doc/forum/not_getting_file_contents.mdwn1
-rw-r--r--doc/forum/not_getting_file_contents/comment_1_4a0f7f4de9c9bc4d13db033cb75d20af._comment10
-rw-r--r--doc/forum/not_getting_file_contents/comment_2_dc7403e1b551552f9fd00da6a1453570._comment8
-rw-r--r--doc/forum/one_annex_versus_many_annexes__63__.mdwn10
-rw-r--r--doc/forum/one_or_many_annexes__63__.mdwn7
-rw-r--r--doc/forum/one_or_many_annexes__63__/comment_1_656d96011801d67a45b0b3bb3d70fa63._comment8
-rw-r--r--doc/forum/performance_and_multiple_replication_problems.mdwn17
-rw-r--r--doc/forum/performance_and_multiple_replication_problems/comment_1_a2cdf1a4840f099f6bc941fd8de966c7._comment16
-rw-r--r--doc/forum/performance_and_multiple_replication_problems/comment_2_e65b360706c66ede6e0e841b2ebbbfbc._comment8
-rw-r--r--doc/forum/performance_improvement:_git_on_ssd__44___annex_on_spindle_disk.mdwn12
-rw-r--r--doc/forum/performance_improvement:_git_on_ssd__44___annex_on_spindle_disk/comment_1_b3f22f9be02bc4f2d5a121db3d753ff5._comment8
-rw-r--r--doc/forum/performance_improvement:_git_on_ssd__44___annex_on_spindle_disk/comment_2_f94abce32ef818176b42a3cc860691ae._comment20
-rw-r--r--doc/forum/performance_improvement:_git_on_ssd__44___annex_on_spindle_disk/comment_3_0c8e77fe248e00bd990d568623e5a5c9._comment10
-rw-r--r--doc/forum/performance_improvement:_git_on_ssd__44___annex_on_spindle_disk/comment_4_4b7e8f9521d61900d9ad418e74808ffb._comment8
-rw-r--r--doc/forum/performance_improvement:_git_on_ssd__44___annex_on_spindle_disk/comment_5_7abbbe7db3988a2d239d11b0a4c597e7._comment10
-rw-r--r--doc/forum/performance_improvement:_git_on_ssd__44___annex_on_spindle_disk/comment_6_46bd45fdc25d9c583f4ebe3a9730ab9f._comment8
-rw-r--r--doc/forum/post-copy__47__sync_hook.mdwn14
-rw-r--r--doc/forum/post-copy__47__sync_hook/comment_1_c8322d4b9bbf5eac80b48c312a42fbcf._comment11
-rw-r--r--doc/forum/preferred_content.mdwn11
-rw-r--r--doc/forum/preferred_content/comment_1_9c9e5f2ee5ae4d8459358ad16f879ef1._comment10
-rw-r--r--doc/forum/preferred_content_settings_for_multiple_symlinks.mdwn7
-rw-r--r--doc/forum/preferred_content_settings_for_multiple_symlinks/comment_1_70da012d96ab576151fe3e081ef905d1._comment10
-rw-r--r--doc/forum/preferred_content_settings_for_multiple_symlinks/comment_2_ccea74d8b5a4de1f3cd1f6da6694ae0e._comment8
-rw-r--r--doc/forum/preferred_content_settings_for_multiple_symlinks/comment_3_fab70c642d5aaf26de05270860281030._comment10
-rw-r--r--doc/forum/preferred_content_settings_for_multiple_symlinks/comment_4_3cbd06de53b6a13e2741124a8e7b5b5b._comment10
-rw-r--r--doc/forum/preferred_content_settings_for_multiple_symlinks/comment_5_963558ab261d8a6315402d371e8348f9._comment10
-rw-r--r--doc/forum/public-web-frontend.mdwn16
-rw-r--r--doc/forum/public-web-frontend/comment_1_c73bd2dfe020c25eaad1c0707dd2db01._comment9
-rw-r--r--doc/forum/public-web-frontend/comment_2_0026d7be6b17e50d86b3b54985882f80._comment14
-rw-r--r--doc/forum/pulling_from_encrypted_remote.mdwn12
-rw-r--r--doc/forum/pulling_from_encrypted_remote/comment_1_e9d6a9a6e01d01edb41a11b0da11d74d._comment10
-rw-r--r--doc/forum/pulling_from_encrypted_remote/comment_2_8d0db2ff65ce935c6e68044a3e0721a8._comment16
-rw-r--r--doc/forum/pure_git-annex_only_workflow.mdwn46
-rw-r--r--doc/forum/pure_git-annex_only_workflow/comment_10_683768c9826b0bf0f267e8734b9eb872._comment8
-rw-r--r--doc/forum/pure_git-annex_only_workflow/comment_11_6b541ed834ef45606f3b98779a25a148._comment30
-rw-r--r--doc/forum/pure_git-annex_only_workflow/comment_12_ca8ca35d6cd4a9f94568536736c12adc._comment10
-rw-r--r--doc/forum/pure_git-annex_only_workflow/comment_13_00c82d320c7b4bb51078beba17e14dc8._comment8
-rw-r--r--doc/forum/pure_git-annex_only_workflow/comment_14_b63568b327215ef8f646a39d760fdfc0._comment32
-rw-r--r--doc/forum/pure_git-annex_only_workflow/comment_15_cb7c856d8141b2de3cc95874753f1ee5._comment12
-rw-r--r--doc/forum/pure_git-annex_only_workflow/comment_1_a32f7efd18d174845099a4ed59e6feae._comment32
-rw-r--r--doc/forum/pure_git-annex_only_workflow/comment_2_66dc9b65523a9912411db03c039ba848._comment15
-rw-r--r--doc/forum/pure_git-annex_only_workflow/comment_3_9b7d89da52f7ebb7801f9ec8545c3aba._comment12
-rw-r--r--doc/forum/pure_git-annex_only_workflow/comment_4_dc8a3f75533906ad3756fcc47f7e96bb._comment20
-rw-r--r--doc/forum/pure_git-annex_only_workflow/comment_5_afe5035a6b35ed2c7e193fb69cc182e2._comment24
-rw-r--r--doc/forum/pure_git-annex_only_workflow/comment_6_3660d45c5656f68924acbd23790024ee._comment12
-rw-r--r--doc/forum/pure_git-annex_only_workflow/comment_7_33db51096f568c65b22b4be0b5538c0d._comment15
-rw-r--r--doc/forum/pure_git-annex_only_workflow/comment_8_6e5b42fdb7801daadc0b3046cbc3d51e._comment12
-rw-r--r--doc/forum/pure_git-annex_only_workflow/comment_9_ace319652f9c7546883b5152ddc82591._comment14
-rw-r--r--doc/forum/purge_files_with_no_copies.mdwn3
-rw-r--r--doc/forum/purge_files_with_no_copies/comment_1_12b578689eb8d5d38c06261ec65e2109._comment12
-rw-r--r--doc/forum/question_about_assistant_and___47__archive__47__.mdwn22
-rw-r--r--doc/forum/question_about_assistant_and___47__archive__47__/comment_1_97890e26072af9277144651e3fdcada0._comment10
-rw-r--r--doc/forum/question_about_assistant_and___47__archive__47__/comment_2_542bf265e35a976ac76767762d67d617._comment104
-rw-r--r--doc/forum/question_about_assistant_and___47__archive__47__/comment_3_bafe99159df2adcd5fecc0d67bbf05a5._comment8
-rw-r--r--doc/forum/question_about_assistant_and___47__archive__47__/comment_4_e77fa2992d9302a49a05f514c81612ca._comment10
-rw-r--r--doc/forum/receiving_indirect_renames_on_direct_repo___63__.mdwn254
-rw-r--r--doc/forum/receiving_indirect_renames_on_direct_repo___63__/comment_1_f4b0a14373c75cb752597c832e296bcc._comment17
-rw-r--r--doc/forum/receiving_indirect_renames_on_direct_repo___63__/comment_2_8c86dfc99f0b9040402c9d746decda53._comment41
-rw-r--r--doc/forum/receiving_indirect_renames_on_direct_repo___63__/comment_3_0246fff6c7c75f6be45bd257ec3872a5._comment75
-rw-r--r--doc/forum/recover_deleted_files___63__.mdwn66
-rw-r--r--doc/forum/recover_deleted_files___63__/comment_1_d7abb7c45c6ec2723a04f153ed215453._comment8
-rw-r--r--doc/forum/recover_deleted_files___63__/comment_2_8ea2acaa30d3ee7e9f75310f4ec859b2._comment8
-rw-r--r--doc/forum/recover_deleted_files___63__/comment_3_376de81c70799bf409be189a48234815._comment12
-rw-r--r--doc/forum/recovering_from_repo_corruption.mdwn11
-rw-r--r--doc/forum/recovering_from_repo_corruption/comment_1_01fc85037e24fc70e5c5329898cf6781._comment15
-rw-r--r--doc/forum/recovering_from_repo_corruption/comment_2_3bd1c0bf25a0e892e711a60f53cd5298._comment8
-rw-r--r--doc/forum/recovering_from_repo_corruption/comment_3_679dde8ca0081fc6854d6d2e8a42abdb._comment8
-rw-r--r--doc/forum/reinstalled_os__44___cloned_annex__44___does_not_recognize_remote.mdwn8
-rw-r--r--doc/forum/reinstalled_os__44___cloned_annex__44___does_not_recognize_remote/comment_1_c1962d757dd22f49e774afa13a9862ca._comment10
-rw-r--r--doc/forum/reinstalled_os__44___cloned_annex__44___does_not_recognize_remote/comment_2_1f0f4a1dc89643cee81ff7199b55e747._comment8
-rw-r--r--doc/forum/reliability__47__completeness_of_XMPP_updates.mdwn7
-rw-r--r--doc/forum/reliability__47__completeness_of_XMPP_updates/comment_1_e0f7aa48d54fc0564f41c3a569c723b7._comment12
-rw-r--r--doc/forum/reliability__47__completeness_of_XMPP_updates/comment_2_4e74039a673c16c0163f2cfb406dc4c3._comment8
-rw-r--r--doc/forum/reliability__47__completeness_of_XMPP_updates/comment_3_41ade4fe72804b2f06cd4dbf405c1746._comment8
-rw-r--r--doc/forum/relying_on_git_for_numcopies.mdwn47
-rw-r--r--doc/forum/relying_on_git_for_numcopies/comment_1_8ad3cccd7f66f6423341d71241ba89fc._comment36
-rw-r--r--doc/forum/relying_on_git_for_numcopies/comment_2_be6acbc26008a9cb54e7b8f498f2c2a2._comment18
-rw-r--r--doc/forum/relying_on_git_for_numcopies/comment_3_43d8e1513eb9947f8a503f094c03f307._comment8
-rw-r--r--doc/forum/remote_server_client_repositories_are_bare__33____63__.mdwn17
-rw-r--r--doc/forum/remote_server_client_repositories_are_bare__33____63__/comment_1_234241460f6c75a8376b303b8dd4e882._comment11
-rw-r--r--doc/forum/remote_server_client_repositories_are_bare__33____63__/comment_2_42dfc382d07af2a4f29c76016084f87c._comment12
-rw-r--r--doc/forum/reserving_space_with_directory_special_remotes.mdwn2
-rw-r--r--doc/forum/reserving_space_with_directory_special_remotes/comment_1_cd17b624704d93b51931023f69573323._comment8
-rw-r--r--doc/forum/reserving_space_with_directory_special_remotes/comment_2_877ca1be23d1484a8a30cdaeb6630053._comment15
-rw-r--r--doc/forum/reserving_space_with_directory_special_remotes/comment_3_65910eeaf3c6fcfd03f22c2957293232._comment8
-rw-r--r--doc/forum/retrieving_previous_versions.mdwn7
-rw-r--r--doc/forum/retrieving_previous_versions/comment_1_a4e83f688d4ec9177e7bf520f12ed26d._comment11
-rw-r--r--doc/forum/rsync_over_ssh__63__.mdwn2
-rw-r--r--doc/forum/rsync_over_ssh__63__/comment_1_ee21f32e90303e20339e0a568321bbbe._comment8
-rw-r--r--doc/forum/rsync_over_ssh__63__/comment_2_aa690da6ecfb2b30fc5080ad76dc77b1._comment8
-rw-r--r--doc/forum/rsync_remote_is_not_available_from_a_cloned_repo/comment_1_2e340c5a6473f165dc06cc35db38e5c0._comment8
-rw-r--r--doc/forum/rsyncing_.git__47__annex__47__objects.mdwn24
-rw-r--r--doc/forum/rsyncing_.git__47__annex__47__objects/comment_1_25eb9f7be5730337b9efd96dce9efd2e._comment10
-rw-r--r--doc/forum/rsyncing_.git__47__annex__47__objects/comment_2_d7ceae666c8a1951021d3c6e6ac39a11._comment8
-rw-r--r--doc/forum/s3_vs_ssh_Performance_Problems.mdwn8
-rw-r--r--doc/forum/s3_vs_ssh_Performance_Problems/comment_1_65f064f09d7850abecab97007b0d30f0._comment12
-rw-r--r--doc/forum/s3_vs_ssh_Performance_Problems/comment_2_baaf2384d9196077268e9ca9bbe3b871._comment8
-rw-r--r--doc/forum/s3_vs_ssh_Performance_Problems/comment_3_dc44be42070c073d150c476406e9b425._comment10
-rw-r--r--doc/forum/safely_dropping_git-annex_history.mdwn20
-rw-r--r--doc/forum/safely_dropping_git-annex_history/comment_10_a4b93a3fbc98d9b86e942f95e0039862._comment8
-rw-r--r--doc/forum/safely_dropping_git-annex_history/comment_11_383882fafd32f25ed22b5eb2fb3691b9._comment18
-rw-r--r--doc/forum/safely_dropping_git-annex_history/comment_12_47794a2abf29bf4ea2763ff89d872ab4._comment8
-rw-r--r--doc/forum/safely_dropping_git-annex_history/comment_1_4fd76d10a93fe01588fce7a621f9254d._comment12
-rw-r--r--doc/forum/safely_dropping_git-annex_history/comment_2_10ecf3220ffcbbe94ba09da225458f18._comment12
-rw-r--r--doc/forum/safely_dropping_git-annex_history/comment_3_e3beb8acb075faaeef6c052aecbf0a41._comment50
-rw-r--r--doc/forum/safely_dropping_git-annex_history/comment_4_61a5fe2e7e47c60a8b237ea69404a37f._comment8
-rw-r--r--doc/forum/safely_dropping_git-annex_history/comment_5_426d02e2f2a2ae4ec7eae02dfe4519b3._comment9
-rw-r--r--doc/forum/safely_dropping_git-annex_history/comment_6_410a7296c2cee16d3d5bb618a5a41c1d._comment10
-rw-r--r--doc/forum/safely_dropping_git-annex_history/comment_7_42cf492fc98a9eba8176387749ef12e0._comment8
-rw-r--r--doc/forum/safely_dropping_git-annex_history/comment_8_c0327ada073d8b69535f71b4dc6aa57e._comment21
-rw-r--r--doc/forum/safely_dropping_git-annex_history/comment_9_f83d6090aea2b7d5d54c876df940cbad._comment40
-rw-r--r--doc/forum/seems_to_build_fine_on_haskell_platform_2011.mdwn1
-rw-r--r--doc/forum/shared_cipher_tries_to_use_gpg.mdwn10
-rw-r--r--doc/forum/shared_cipher_tries_to_use_gpg/comment_1_760961eaaa7d5c254dd71c5792437c9e._comment12
-rw-r--r--doc/forum/shared_cipher_tries_to_use_gpg/comment_2_f3260aea3a5bb9b95a9bdf1d0dfce090._comment8
-rw-r--r--doc/forum/something_really_good_happened_with_3.20130124.mdwn5
-rw-r--r--doc/forum/something_really_good_happened_with_3.20130124/comment_1_1712bddd2f483a353f6313aa626445f1._comment8
-rw-r--r--doc/forum/sparse_git_checkouts_with_annex.mdwn31
-rw-r--r--doc/forum/sparse_git_checkouts_with_annex/comment_1_c7dc199c5740a0e7ba606dfb5e3e579a._comment12
-rw-r--r--doc/forum/sparse_git_checkouts_with_annex/comment_2_e357db3ccc4079f07a291843975535eb._comment8
-rw-r--r--doc/forum/sparse_git_checkouts_with_annex/comment_3_fcfafca994194d57dccf5319c7c9e646._comment8
-rw-r--r--doc/forum/sparse_git_checkouts_with_annex/comment_4_04dc14880f31eee2b6d767d4d4258c5a._comment20
-rw-r--r--doc/forum/special_remote_for_IMAP.mdwn44
-rw-r--r--doc/forum/special_remote_for_IMAP/comment_1_7c7d4b57a1b6508fff1a6b0508c861f8._comment10
-rw-r--r--doc/forum/special_remote_for_IMAP/comment_2_9c46fe8a857aa7a5ce797288144386bd._comment8
-rw-r--r--doc/forum/special_remote_for_IMAP/comment_3_27e3b644df6942ce4c103236d0d5cb1b._comment23
-rw-r--r--doc/forum/special_remote_for_iPods.mdwn5
-rw-r--r--doc/forum/special_remote_for_iPods/comment_1_37cc3dc740341cc663074fd3bfb85947._comment8
-rw-r--r--doc/forum/speed_up_assistant_startup_on_large_repositories.mdwn1
-rw-r--r--doc/forum/speed_up_assistant_startup_on_large_repositories/comment_1_5ba637a0f6d01ba24fe25e6265134e0a._comment10
-rw-r--r--doc/forum/speed_up_assistant_startup_on_large_repositories/comment_2_d65746697977f8971a4b59f5b413f926._comment13
-rw-r--r--doc/forum/speed_up_assistant_startup_on_large_repositories/comment_3_be6c4fe5a0c745688438b716973791cc._comment12
-rw-r--r--doc/forum/speed_up_assistant_startup_on_large_repositories/comment_4_a07472338a08c068a9b88b2176fc2bee._comment9
-rw-r--r--doc/forum/ssh_password.mdwn3
-rw-r--r--doc/forum/ssh_password/comment_1_a3e5a41e1d4da683d577976b134b11ee._comment10
-rw-r--r--doc/forum/ssh_password/comment_2_fa261676a99d49d4b237b0d43048d76d._comment10
-rw-r--r--doc/forum/ssh_remote_-_no___34__use_a_git_repository__34___option_during_setup__63__.mdwn3
-rw-r--r--doc/forum/ssh_remote_-_no___34__use_a_git_repository__34___option_during_setup__63__/comment_1_7244794579a191a677190c60758f32e7._comment8
-rw-r--r--doc/forum/ssh_remote_-_no___34__use_a_git_repository__34___option_during_setup__63__/comment_2_277cf12907bd7c5930eb4f137b115e29._comment8
-rw-r--r--doc/forum/start_assistant_from_command_line.mdwn11
-rw-r--r--doc/forum/start_assistant_from_command_line/comment_1_f8dfce1fca9f1212ccaf84e431db71a9._comment12
-rw-r--r--doc/forum/start_assistant_from_command_line/comment_2_e769c5d09afbff85961363ddc5eb4019._comment10
-rw-r--r--doc/forum/switching_backends.mdwn12
-rw-r--r--doc/forum/switching_backends/comment_1_ecf4109c1148dafde3519243ae3c5a03._comment10
-rw-r--r--doc/forum/switching_backends/comment_2_21f465a18f40b95dafd307fce0de659a._comment8
-rw-r--r--doc/forum/switching_backends/comment_4_4c13d22c1695195e6b101bd20ef6bb42._comment35
-rw-r--r--doc/forum/switching_backends/comment_4_e1d4a48baac23fd3f67b20eba4eee8af._comment8
-rw-r--r--doc/forum/switching_to__47__from_direct_mode_while_assistant_is_running.mdwn2
-rw-r--r--doc/forum/switching_to__47__from_direct_mode_while_assistant_is_running/comment_1_7832243a36613c48d0077b438dbf8b4a._comment10
-rw-r--r--doc/forum/syncing_home_directories.mdwn7
-rw-r--r--doc/forum/syncing_home_directories/comment_1_220a6e0ffe0ea610921a63c0a6e3beab._comment16
-rw-r--r--doc/forum/syncing_non-git_trees_with_git-annex.mdwn46
-rw-r--r--doc/forum/syncing_non-git_trees_with_git-annex/comment_1_7f9593bdfd95e4a8814e6cc5c44619e6._comment24
-rw-r--r--doc/forum/syncing_non-git_trees_with_git-annex/comment_2_49f15478781a0ad5e46e75319070335c._comment16
-rw-r--r--doc/forum/syncing_non-git_trees_with_git-annex/comment_3_6d8f399f0549eddd1d1f5c9c9a10c654._comment13
-rw-r--r--doc/forum/taskwarrior.mdwn11
-rw-r--r--doc/forum/taskwarrior/comment_1_1c3a29e7d292cb602d9d349f8009b51e._comment10
-rw-r--r--doc/forum/tell_us_how_you__39__re_using_git-annex.mdwn6
-rw-r--r--doc/forum/tell_us_how_you__39__re_using_git-annex/comment_1_4884803ddee7f642a3ac995a19967a6a._comment17
-rw-r--r--doc/forum/tell_us_how_you__39__re_using_git-annex/comment_2_61f5054918e7b36c191454365bc7f3b7._comment10
-rw-r--r--doc/forum/tell_us_how_you__39__re_using_git-annex/comment_3_db07e8703be606c998c831e91d300d69._comment10
-rw-r--r--doc/forum/tell_us_how_you__39__re_using_git-annex/comment_4_a58595969cdd42ed20210e9615b42e42._comment22
-rw-r--r--doc/forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs.mdwn22
-rw-r--r--doc/forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs/comment_1_76bb33ce45ce6a91b86454147463193b._comment10
-rw-r--r--doc/forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs/comment_2_4d9b9d47d01d606a475678f630797bf9._comment10
-rw-r--r--doc/forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs/comment_3_8a812b11fcc2dc3b6fcf01cdbbb8459d._comment12
-rw-r--r--doc/forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs/comment_4_fc98c819bc5eb4d7c9e74d87fb4f6f3b._comment39
-rw-r--r--doc/forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs/comment_5_c459fb479fe7b13eaea2377cfc1923a6._comment8
-rw-r--r--doc/forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs/comment_6_2e9da5a919bbbc27b32de3b243867d4f._comment23
-rw-r--r--doc/forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs/comment_7_d636c868524b2055ee85832527437f90._comment20
-rw-r--r--doc/forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs/comment_8_39dc449cc60a787c3bfbfaaac6f9be0c._comment10
-rw-r--r--doc/forum/ui.mdwn11
-rw-r--r--doc/forum/ui/comment_1_f3e3446b05d6b573e29e6cad300fb635._comment10
-rw-r--r--doc/forum/ui/comment_2_b493ee97eb2378e72c12f3d137109580._comment15
-rw-r--r--doc/forum/unannex_alternatives.mdwn9
-rw-r--r--doc/forum/unannex_alternatives/comment_1_dcd4cd41280b41512bbdffafaf307993._comment46
-rw-r--r--doc/forum/unannex_alternatives/comment_2_58a72a9fe0f58c7af0b4d7927a2dd21d._comment36
-rw-r--r--doc/forum/unannex_alternatives/comment_3_b1687fc8f9e7744327bbeb6f0635d1cd._comment16
-rw-r--r--doc/forum/unknown_response_from_git_cat-file.mdwn8
-rw-r--r--doc/forum/unknown_response_from_git_cat-file/comment_1_f26ba569e715fe69b6de3093930362ee._comment8
-rw-r--r--doc/forum/unlock__47__lock_always_gets_me.mdwn11
-rw-r--r--doc/forum/unlock__47__lock_always_gets_me/comment_1_dee73a7ea3e1a5154601adb59782831f._comment12
-rw-r--r--doc/forum/unlock__47__lock_always_gets_me/comment_2_f89b4349dde840c355a3bc28908decdf._comment8
-rw-r--r--doc/forum/unsynced_folder.mdwn3
-rw-r--r--doc/forum/updating_the___34__number_of_copies__34__.mdwn14
-rw-r--r--doc/forum/updating_the___34__number_of_copies__34__/comment_1_327bdb0d9c190c60c7147b3acf07af09._comment10
-rw-r--r--doc/forum/updating_the___34__number_of_copies__34__/comment_2_7e11c839637e0894332e413cde02cee9._comment8
-rw-r--r--doc/forum/updating_the___34__number_of_copies__34__/comment_3_8b7a70fb3bb41e4eda412302834730bb._comment8
-rw-r--r--doc/forum/use_existing_ssh_keys__63__.mdwn5
-rw-r--r--doc/forum/use_existing_ssh_keys__63__/comment_1_c420c53f022bbd1b28494bc44d076feb._comment8
-rw-r--r--doc/forum/use_existing_ssh_keys__63__/comment_2_e4cae848e5701852073ced307832872b._comment12
-rw-r--r--doc/forum/use_existing_ssh_keys__63__/comment_3_a97c20b6df74c49e5f57c7caf962f1e2._comment10
-rw-r--r--doc/forum/using_git_annex_to_merge_and_synchronize_2_directories___40__like_unison__41__.mdwn7
-rw-r--r--doc/forum/using_git_annex_to_merge_and_synchronize_2_directories___40__like_unison__41__/comment_1_5c3ee8a8aaa6d0918c0cc9683ce177ae._comment10
-rw-r--r--doc/forum/using_git_annex_to_merge_and_synchronize_2_directories___40__like_unison__41__/comment_2_648946353c6d90c57351cce4010f1301._comment10
-rw-r--r--doc/forum/version_3_upgrade.mdwn9
-rw-r--r--doc/forum/version_3_upgrade/comment_1_05fc9c9cad26c520bebb98c852c71e35._comment13
-rw-r--r--doc/forum/vlc_and_git-annex.mdwn11
-rw-r--r--doc/forum/vlc_and_git-annex/comment_1_9c9ab8ce463cf74418aa2f385955f165._comment10
-rw-r--r--doc/forum/vlc_and_git-annex/comment_2_037f94c1deeac873dbdb36cd4c927e45._comment8
-rw-r--r--doc/forum/webapp___47___assistant_without_watch.mdwn9
-rw-r--r--doc/forum/webapp___47___assistant_without_watch/comment_1_1bcd99aa81f937ded683e19a69d33dd9._comment10
-rw-r--r--doc/forum/webapp___47___assistant_without_watch/comment_2_9f5b3f5bf7fedcd5baec519d97d3aa8c._comment16
-rw-r--r--doc/forum/webapp_and_manual_mode.mdwn7
-rw-r--r--doc/forum/webapp_and_manual_mode/comment_1_5b5df5ffeb6ee15779972f13fdc11729._comment10
-rw-r--r--doc/forum/webapp_and_manual_mode/comment_2_a1f06b50d1317c78a301b47eb05d2617._comment19
-rw-r--r--doc/forum/webapp_listen_port_with_autostart.mdwn3
-rw-r--r--doc/forum/webapp_listen_port_with_autostart/comment_1_65dbcf3d8f6c16568f5a326242eab9c5._comment20
-rw-r--r--doc/forum/webapp_listen_port_with_autostart/comment_2_39664f833dedc1a4fe083eec9bc4a7cd._comment75
-rw-r--r--doc/forum/windows_port__63__.mdwn2
-rw-r--r--doc/forum/windows_port__63__/comment_1_23fa9aa3b00940a1c1b3876c35eef019._comment9
-rw-r--r--doc/forum/wishlist:_get__47__drop_via_webapp_file_explorer.mdwn1
-rw-r--r--doc/forum/wishlist:_get__47__drop_via_webapp_file_explorer/comment_1_c818a6d44dc13a56460b1865f70eb97c._comment8
-rw-r--r--doc/forum/wishlist:_make_copy_stop_on_exhausted_disk_space.mdwn4
-rw-r--r--doc/forum/wishlist:_make_copy_stop_on_exhausted_disk_space/comment_1_467e5e3db3e836030bc4b4f15846951f._comment12
-rw-r--r--doc/forum/wishlist:_make_copy_stop_on_exhausted_disk_space/comment_2_e3ca3db9bea11d3e085ee9c3c56b33fe._comment8
-rw-r--r--doc/forum/wishlist:_make_copy_stop_on_exhausted_disk_space/comment_3_0ef8c37350fc192d9b784fbab1d9f318._comment8
-rw-r--r--doc/forum/working_without_git-annex_commits.mdwn20
-rw-r--r--doc/future_proofing.mdwn38
-rw-r--r--doc/git-annex-shell.mdwn120
-rw-r--r--doc/git-annex.mdwn1419
-rw-r--r--doc/git-union-merge.mdwn38
-rw-r--r--doc/how_it_works.mdwn41
-rw-r--r--doc/how_it_works/comment_1_b3bdd6a06d5764db521ae54878131f5f._comment14
-rw-r--r--doc/ikiwiki/pagespec.mdwn86
-rw-r--r--doc/index.mdwn45
-rw-r--r--doc/install.mdwn31
-rw-r--r--doc/install/Android.mdwn37
-rw-r--r--doc/install/Android/comment_10_225f2c6fe255be93702cfbd4dc172f3b._comment8
-rw-r--r--doc/install/Android/comment_11_4e970633d9073fcf4bc33f3fff2525b2._comment10
-rw-r--r--doc/install/Android/comment_12_87da4f379a0276b662583e7e22061218._comment8
-rw-r--r--doc/install/Android/comment_1_f9ced494a530e6ae3e76cfbaddb89f5d._comment8
-rw-r--r--doc/install/Android/comment_2_74cccae04ea23a8600069c7e658143aa._comment8
-rw-r--r--doc/install/Android/comment_3_82c7cb31d19d4e18ca5548da5ca19a79._comment8
-rw-r--r--doc/install/Android/comment_4_cebaa8ee5bbed27d9b2d032ca7bdec6e._comment8
-rw-r--r--doc/install/Android/comment_8_34f7c42050fa48769a6bfae60d72e477._comment8
-rw-r--r--doc/install/Android/comment_9_f3d289b78d6bdb3cc65689495a8439a5._comment11
-rw-r--r--doc/install/ArchLinux.mdwn19
-rw-r--r--doc/install/ArchLinux/comment_1_da5919c986d2ae187bc2f73de9633978._comment8
-rw-r--r--doc/install/ArchLinux/comment_2_e5f923e6d81cfb3fba7a72f60baaf4ab._comment16
-rw-r--r--doc/install/ArchLinux/comment_3_8e607cd883ec174571e9dfe3b25bfd05._comment8
-rw-r--r--doc/install/ArchLinux/comment_4_a378391dd218859f381c479259dd8fe3._comment10
-rw-r--r--doc/install/Debian.mdwn20
-rw-r--r--doc/install/Debian/comment_10_d5da996e106d2e4d8a822aa9bcc78596._comment12
-rw-r--r--doc/install/Debian/comment_11_84283676da247c401bc9b4bb12c2b453._comment8
-rw-r--r--doc/install/Debian/comment_12_0aca83b055d0a9dd8589c50250a8bbea._comment13
-rw-r--r--doc/install/Debian/comment_13_167a091764e5e99ec0f35a65e95a22de._comment8
-rw-r--r--doc/install/Debian/comment_14_a34e23d9aa3027012ab1236aa4f7d5cb._comment8
-rw-r--r--doc/install/Debian/comment_15_20d8271ba3f6cfe3c8849c3d41607630._comment8
-rw-r--r--doc/install/Debian/comment_1_029486088d098c2d4f1099f2f0e701a9._comment9
-rw-r--r--doc/install/Debian/comment_2_648e3467e260cdf233acdb0b53313ce0._comment8
-rw-r--r--doc/install/Debian/comment_3_4d922e11249627634ecc35bba4044d9e._comment8
-rw-r--r--doc/install/Debian/comment_4_2a93ab18b05ccb90e7acc5885866fca2._comment9
-rw-r--r--doc/install/Debian/comment_5_38e6399083e10a6a274f35bddc15d4ac._comment18
-rw-r--r--doc/install/Debian/comment_6_2e7bbdbaabbfb9d89de22e913066e822._comment8
-rw-r--r--doc/install/Debian/comment_7_1bccc7bf7a4ef61a9b30024b9b22ba7d._comment12
-rw-r--r--doc/install/Debian/comment_8_5b5a3b0e8abe8831a6a15a4e258d14fd._comment10
-rw-r--r--doc/install/Debian/comment_9_97eaed998ffd1ed79585075ed5cff06e._comment8
-rw-r--r--doc/install/Fedora.mdwn39
-rw-r--r--doc/install/Fedora/comment_1_c4db84e672ad4b45b522db735706b00f._comment16
-rw-r--r--doc/install/Fedora/comment_2_f98c488c09bef86e2b0414589ce9e141._comment25
-rw-r--r--doc/install/Fedora/comment_3_d872acf8865fe7c99a9b712db5b38ea4._comment8
-rw-r--r--doc/install/Fedora/comment_4_93b3402e4c51e1a5c96f907bb528164b._comment16
-rw-r--r--doc/install/Fedora/comment_5_0427e0503764b29e57abf9e97155136b._comment15
-rw-r--r--doc/install/Fedora/comment_6_1b1b38a79251fe2e8c1e4debbe3bc3c5._comment12
-rw-r--r--doc/install/FreeBSD.mdwn2
-rw-r--r--doc/install/Gentoo.mdwn3
-rw-r--r--doc/install/Linux_standalone.mdwn34
-rw-r--r--doc/install/NixOS.mdwn6
-rw-r--r--doc/install/OSX.mdwn71
-rw-r--r--doc/install/OSX/comment_10_cd2120552ef894a37933b328136fa4cc._comment8
-rw-r--r--doc/install/OSX/comment_11_740fa80e2e54e6fb570f820ff1f56440._comment8
-rw-r--r--doc/install/OSX/comment_12_a84028080578a8b60115b6c4ef823627._comment8
-rw-r--r--doc/install/OSX/comment_13_d6f1db401858ffea23c123db49f5b296._comment8
-rw-r--r--doc/install/OSX/comment_14_035f856923276b0edad879e196e94097._comment9
-rw-r--r--doc/install/OSX/comment_15_336e0acb00e84943715e69917643a69e._comment35
-rw-r--r--doc/install/OSX/comment_16_1befafa862b7d07b1f6e57c0182497cf._comment36
-rw-r--r--doc/install/OSX/comment_17_19c08b2c6c2c5cd88bf96d2bcbbd9055._comment10
-rw-r--r--doc/install/OSX/comment_18_537fad5d8854e765499d47602d1ab398._comment8
-rw-r--r--doc/install/OSX/comment_19_18d4377f4ded5604d395d73783ba82c9._comment8
-rw-r--r--doc/install/OSX/comment_20_3e6a3c00444badf2cf7a9ee3d54af11e._comment8
-rw-r--r--doc/install/OSX/comment_21_987f1302f56107c926b6daf83e124654._comment11
-rw-r--r--doc/install/OSX/comment_22_6b5f44a98f9d37a1c6ecfe19a60fe6c5._comment12
-rw-r--r--doc/install/OSX/comment_23_3d82a270dd4b0159f4aab5675166e1e3._comment30
-rw-r--r--doc/install/OSX/comment_24_b9d3563a2cc3d769f27876e028dc344d._comment12
-rw-r--r--doc/install/OSX/comment_25_db90984062a07576a4777b2d743161f1._comment24
-rw-r--r--doc/install/OSX/comment_27_2a60108a440231ba83f5a54b6bcc5488._comment14
-rw-r--r--doc/install/OSX/comment_27_d453510b9bb62072a4c663206c12c8a4._comment8
-rw-r--r--doc/install/OSX/comment_28_0970bfd63137ea48701dff6aea1b4bcb._comment18
-rw-r--r--doc/install/OSX/comment_29_8622ed56c6a8034c20fb311418d94003._comment8
-rw-r--r--doc/install/OSX/comment_2_25552ff2942048fafe97d653757f1ad6._comment8
-rw-r--r--doc/install/OSX/comment_30_ce58633ef5b2f8f4caa7e626358f33be._comment8
-rw-r--r--doc/install/OSX/comment_31_09084a7b3cf06bfa3add0f4991476ffe._comment10
-rw-r--r--doc/install/OSX/comment_32_a46d8e3e7795b9afb1e1c2be943d12af._comment10
-rw-r--r--doc/install/OSX/comment_33_203a36322b3c453c05c8906c64e62e06._comment8
-rw-r--r--doc/install/OSX/comment_34_c9362141d15a2f68a75df9f8bfe29da0._comment17
-rw-r--r--doc/install/OSX/comment_35_8106196c3fef70652cb2106e2d5857db._comment8
-rw-r--r--doc/install/OSX/comment_3_47a77a03040fe628109bd54f82f9ad7a._comment17
-rw-r--r--doc/install/OSX/comment_4_25cac8bcd84a5210fc0a5243260b8cc7._comment18
-rw-r--r--doc/install/OSX/comment_4_bbe99673033e4c48c8bb3db24ee419f9._comment8
-rw-r--r--doc/install/OSX/comment_5_39b4b748b4586bf32b37edfefef84bba._comment8
-rw-r--r--doc/install/OSX/comment_6_1a9c91ef43edc4148947f202ff604114._comment8
-rw-r--r--doc/install/OSX/comment_7_892f7e65f95f43697164267c4b71c0d5._comment8
-rw-r--r--doc/install/OSX/comment_8_38d9c2eea1090674de2361274eab5b0e._comment29
-rw-r--r--doc/install/OSX/comment_9_35bf3812db6f3ef25da9b3bc84f147c5._comment8
-rw-r--r--doc/install/OSX/old_comments.mdwn1
-rw-r--r--doc/install/OSX/old_comments/comment_10_4d15bfc4fc26e7249953bebfbb09e0aa._comment11
-rw-r--r--doc/install/OSX/old_comments/comment_10_798000aab19af2944b6e44dbc550c6fe._comment10
-rw-r--r--doc/install/OSX/old_comments/comment_11_707a1a27a15b2de8dfc8d1a30420ab4c._comment10
-rw-r--r--doc/install/OSX/old_comments/comment_12_60d13f2c8e008af1041bea565a392c83._comment8
-rw-r--r--doc/install/OSX/old_comments/comment_13_a6f48c87c2d6eabe379d6e10a6cac453._comment8
-rw-r--r--doc/install/OSX/old_comments/comment_14_6ef2ddb7b11ce6ad54578ae118ed346e._comment9
-rw-r--r--doc/install/OSX/old_comments/comment_15_6fd1fad5b6d9f36620e5a0e99edd2f89._comment9
-rw-r--r--doc/install/OSX/old_comments/comment_16_af6fe3540032cdf4400478de87771058._comment30
-rw-r--r--doc/install/OSX/old_comments/comment_17_8d3a0596db67108041728b20f2790f31._comment7
-rw-r--r--doc/install/OSX/old_comments/comment_1_0a1760bf0db1f1ba89bdb4c62032f631._comment13
-rw-r--r--doc/install/OSX/old_comments/comment_2_0327c64b15249596add635d26f4ce67f._comment19
-rw-r--r--doc/install/OSX/old_comments/comment_2_7683740a98182de06cb329792e0c0a25._comment25
-rw-r--r--doc/install/OSX/old_comments/comment_3_47c682a779812dda77601c24a619923c._comment8
-rw-r--r--doc/install/OSX/old_comments/comment_3_733147cebe501c60f2141b711f1d7f24._comment16
-rw-r--r--doc/install/OSX/old_comments/comment_3_b090f40fe5a32e00b472a5ab2b850b4a._comment8
-rw-r--r--doc/install/OSX/old_comments/comment_3_fc092412e99cf4c5f095b0ef710bc4de._comment8
-rw-r--r--doc/install/OSX/old_comments/comment_4_d513e21512a9b207983d38abf348d00f._comment16
-rw-r--r--doc/install/OSX/old_comments/comment_4_d68c36432c7be3f4a76f4f0d7300bac9._comment20
-rw-r--r--doc/install/OSX/old_comments/comment_4_e6109a964064a2a799768a370e57801d._comment30
-rw-r--r--doc/install/OSX/old_comments/comment_5_50777853f808d57b957f8ce9a0f84b3d._comment10
-rw-r--r--doc/install/OSX/old_comments/comment_5_626a4b4bf302d4ae750174f860402f70._comment8
-rw-r--r--doc/install/OSX/old_comments/comment_6_18a8df794aa0ddd294dbf17d3d4c7fe2._comment7
-rw-r--r--doc/install/OSX/old_comments/comment_7_2ce7acab15403d3f993cec94ec7f3bc6._comment14
-rw-r--r--doc/install/OSX/old_comments/comment_8_a93ad4b67c5df4243268bcf32562f6be._comment39
-rw-r--r--doc/install/OSX/old_comments/comment_9_ae3ed5345bc84f57e44251d2e6c39342._comment14
-rw-r--r--doc/install/OSX/old_comments/comment_9_c6b1b31d16f2144ad08abd8c767b6ab9._comment23
-rw-r--r--doc/install/ScientificLinux5.mdwn62
-rw-r--r--doc/install/Ubuntu.mdwn39
-rw-r--r--doc/install/Ubuntu/comment_10_490e065314693423ab6969d8ae6978fe._comment8
-rw-r--r--doc/install/Ubuntu/comment_11_4ebac3fb43de854ed1a3b1d2ea94011a._comment10
-rw-r--r--doc/install/Ubuntu/comment_12_38f69dffe2db0d15e4c4e5cb47f40ef8._comment8
-rw-r--r--doc/install/Ubuntu/comment_1_d1c511153fe94bf33e19a1281f1c92f2._comment8
-rw-r--r--doc/install/Ubuntu/comment_2_ad13886c1c1f76d1cd995ea7b7d8471c._comment8
-rw-r--r--doc/install/Ubuntu/comment_3_a08817322739b03cf0fec97283b16f1a._comment8
-rw-r--r--doc/install/Ubuntu/comment_4_fe0997e56136bd30749f0995cbf19b56._comment12
-rw-r--r--doc/install/Ubuntu/comment_5_fbb5306a162db1a1ee9efa3523aac952._comment11
-rw-r--r--doc/install/Ubuntu/comment_6_a97e7f0e62ac685c3ded423bddeaa67f._comment14
-rw-r--r--doc/install/Ubuntu/comment_7_921a223fd7e679b9ced3d8ba5ce688e0._comment8
-rw-r--r--doc/install/Ubuntu/comment_8_1f943cb084fa8e21bc6ee5fc3118f02f._comment8
-rw-r--r--doc/install/Ubuntu/comment_9_c2f8b35ada873acb1ce593b04e2899fe._comment11
-rw-r--r--doc/install/Windows.mdwn34
-rw-r--r--doc/install/cabal.mdwn58
-rw-r--r--doc/install/cabal/comment_10_7ebe353b05d4df29897dc9a4f45c8a91._comment8
-rw-r--r--doc/install/cabal/comment_11_0d06702e6e0ae3cd331cf748a9f6f273._comment44
-rw-r--r--doc/install/cabal/comment_12_b93ca271dffca3f948645d3e1326c1d9._comment12
-rw-r--r--doc/install/cabal/comment_13_3dac019cda71bf99878c0a1d9382323b._comment8
-rw-r--r--doc/install/cabal/comment_14_14b46470593f84f8c3768a91cb77bdab._comment9
-rw-r--r--doc/install/cabal/comment_15_c3a5b0aad28a90e0bb8da31a430578eb._comment8
-rw-r--r--doc/install/cabal/comment_16_4faf214f97f9516898d7c17d743ef825._comment10
-rw-r--r--doc/install/cabal/comment_17_2a9d6807a3a13815c824985521757167._comment10
-rw-r--r--doc/install/cabal/comment_18_1efa0c7a963ec452fc6336fbe4964f6e._comment10
-rw-r--r--doc/install/cabal/comment_19_6f42f9234f9ff6a2ca6bbb4d2643843e._comment44
-rw-r--r--doc/install/cabal/comment_1_f04df6bcd50d1d01eb34868bb00ac35c._comment18
-rw-r--r--doc/install/cabal/comment_20_0f553be2a4c666e3bed58b2bce549406._comment8
-rw-r--r--doc/install/cabal/comment_21_f91a6ec21e96eced73ea9579fd8cbd15._comment8
-rw-r--r--doc/install/cabal/comment_22_2f27b78215f97ade1986ca806c634cb3._comment16
-rw-r--r--doc/install/cabal/comment_23_c34d2b1d95830a3e58671a5b566a1758._comment8
-rw-r--r--doc/install/cabal/comment_24_40cbde8ec067b3a860e6df1a9bea5f76._comment8
-rw-r--r--doc/install/cabal/comment_25_8a7664e6f9271718dc607a0782366c5b._comment8
-rw-r--r--doc/install/cabal/comment_26_bd455c732639728bce2bfc39e32871d2._comment8
-rw-r--r--doc/install/cabal/comment_27_c080e9239b6eec88d329c28da7bb4141._comment17
-rw-r--r--doc/install/cabal/comment_28_15951dd070a675300420eea137a28ef9._comment10
-rw-r--r--doc/install/cabal/comment_29_ac082dca67f4a29b06070c0283130f52._comment39
-rw-r--r--doc/install/cabal/comment_2_a69d17c55e56a707ec6606d5cdddee25._comment17
-rw-r--r--doc/install/cabal/comment_30_ad639c07cb79e89406e95c1dafce3a01._comment35
-rw-r--r--doc/install/cabal/comment_31_4763b24a29627d55f465b9ea260ea7ec._comment22
-rw-r--r--doc/install/cabal/comment_32_1d34c294486c85b1149675fa5861ae35._comment10
-rw-r--r--doc/install/cabal/comment_3_55bed050bdb768543dbe1b86edec057d._comment10
-rw-r--r--doc/install/cabal/comment_4_2ff7f8a3b03bea7e860248829d595bd1._comment14
-rw-r--r--doc/install/cabal/comment_5_8789fc27466714faa5a3a7a6b8ec6e5d._comment24
-rw-r--r--doc/install/cabal/comment_6_5afb2d081e8b603bc338cd460ad9317d._comment21
-rw-r--r--doc/install/cabal/comment_7_129c4f2e404c874e5adfa52902a81104._comment22
-rw-r--r--doc/install/cabal/comment_8_738c108f131e3aab0d720bc4fd6a81fd._comment8
-rw-r--r--doc/install/cabal/comment_9_5ddbba419d96a7411f7edddaa4d7b739._comment12
-rw-r--r--doc/install/fromscratch.mdwn72
-rw-r--r--doc/install/openSUSE.mdwn3
-rw-r--r--doc/internals.mdwn132
-rw-r--r--doc/internals/comment_1_4b8ed353dca4f484b3b6eb463fa02fd8._comment8
-rw-r--r--doc/internals/comment_2_c19232d5cc4976c2e5b014aef6e8d9ec._comment8
-rw-r--r--doc/internals/hashing.mdwn30
-rw-r--r--doc/internals/key_format.mdwn20
-rw-r--r--doc/internals/lockdown.mdwn44
-rw-r--r--doc/license.mdwn14
-rw-r--r--doc/license/AGPL661
-rw-r--r--doc/license/GPL674
-rw-r--r--doc/license/LGPL502
-rw-r--r--doc/links/key_concepts.mdwn7
-rw-r--r--doc/links/other_stuff.mdwn7
-rw-r--r--doc/links/the_details.mdwn8
-rw-r--r--doc/location_tracking.mdwn30
-rw-r--r--doc/logo-old-bw.svg60
-rw-r--r--doc/logo-old.pngbin0 -> 9092 bytes
-rw-r--r--doc/logo-old.svg77
-rw-r--r--doc/logo-old_small.pngbin0 -> 4713 bytes
-rw-r--r--doc/logo.mdwn13
-rw-r--r--doc/logo.svg92
-rw-r--r--doc/logo_small.pngbin0 -> 4749 bytes
-rw-r--r--doc/meta.mdwn5
-rw-r--r--doc/news.mdwn11
-rw-r--r--doc/news/2013_git-annex_user_survey.mdwn5
-rw-r--r--doc/news/LWN_article.mdwn2
-rw-r--r--doc/news/Presentation_at_FOSDEM.mdwn4
-rw-r--r--doc/news/git_annex_fall_of_code.mdwn27
-rw-r--r--doc/news/sharebox_a_FUSE_filesystem_for_git-annex.mdwn19
-rw-r--r--doc/news/sharebox_a_FUSE_filesystem_for_git-annex/comment_1_e238d1734238e37bb55ff952b32e06b8._comment9
-rw-r--r--doc/news/version_4.20130827/comment_1_937cbaccf235d6d9118aacd49058bb4f._comment11
-rw-r--r--doc/news/version_4.20130827/comment_2_faa5cf0645728b4ade850a691fa472db._comment25
-rw-r--r--doc/news/version_4.20130827/comment_3_ad156d6199b525884114ff823d265bf7._comment39
-rw-r--r--doc/news/version_4.20130827/comment_4_877061eb24d9d9543cc9cd229906bd64._comment8
-rw-r--r--doc/news/version_4.20130827/comment_5_8991648dda991768e3a58477a4c3c923._comment10
-rw-r--r--doc/news/version_4.20131024.mdwn43
-rw-r--r--doc/news/version_4.20131101.mdwn29
-rw-r--r--doc/news/version_4.20131106.mdwn18
-rw-r--r--doc/news/version_5.20131118.mdwn42
-rw-r--r--doc/news/version_5.20131120.mdwn11
-rw-r--r--doc/not.mdwn55
-rw-r--r--doc/not/comment_1_ab41bec1ccc884e71780cb9458439170._comment8
-rw-r--r--doc/not/comment_2_0e19ff7deb5ed65f2bc685d4c516d816._comment8
-rw-r--r--doc/not/comment_3_bab9584c41a25dda934ad230e3eb732d._comment8
-rw-r--r--doc/not/comment_4_b2a0d5a45ab8ddd66c29dde9412d7a12._comment51
-rw-r--r--doc/not/comment_5_f2829ecbe80a61aa9a8411d2403de69e._comment14
-rw-r--r--doc/not/comment_6_547fc59b19ad66d7280c53a7f923ea08._comment13
-rw-r--r--doc/not/comment_7_581e23cca0219711f8a4500a8d5d20fc._comment16
-rw-r--r--doc/not/comment_8_5c61457f117de38ef487e5cc2780d554._comment24
-rw-r--r--doc/polls.mdwn2
-rw-r--r--doc/polls/2013.mdwn5
-rw-r--r--doc/preferred_content.mdwn207
-rw-r--r--doc/preferred_content/comment_10_f0bce3c67f293eaba97b92f0942876b6._comment8
-rw-r--r--doc/preferred_content/comment_1_7d45e21dfb016e9ffa4715346dd0c1a6._comment19
-rw-r--r--doc/preferred_content/comment_2_1ccd90b009245667ad59f4d29d2a3a37._comment8
-rw-r--r--doc/preferred_content/comment_4_384025b5fa23a3f175985a081438149f._comment8
-rw-r--r--doc/preferred_content/comment_4_6a9bc657bc7415f0e118357d8c6664c6._comment18
-rw-r--r--doc/preferred_content/comment_5_f0a957e67297c4bb5a8778c11b3c9fd4._comment9
-rw-r--r--doc/preferred_content/comment_6_b434c0e2aaa132020fd4a01551285376._comment12
-rw-r--r--doc/preferred_content/comment_7_c4acaa237bf1a8512c5e8ea4cdbd11b9._comment8
-rw-r--r--doc/preferred_content/comment_8_ff2a2dc9c566ebd9f570bdfcd7bfc030._comment27
-rw-r--r--doc/preferred_content/comment_9_f82538be42428691d7cab60a7add2e74._comment13
-rw-r--r--doc/privacy.mdwn47
-rw-r--r--doc/related_software.mdwn12
-rw-r--r--doc/repomap.pngbin0 -> 67316 bytes
-rw-r--r--doc/scalability.mdwn44
-rw-r--r--doc/shortcuts.mdwn12
-rw-r--r--doc/sidebar.mdwn15
-rw-r--r--doc/sitemap.mdwn4
-rw-r--r--doc/special_remotes.mdwn63
-rw-r--r--doc/special_remotes/S3.mdwn53
-rw-r--r--doc/special_remotes/S3/comment_10_c366f020c9b97a365e21878a33360079._comment10
-rw-r--r--doc/special_remotes/S3/comment_11_c1da387e082d91feec13dde91ccb111a._comment12
-rw-r--r--doc/special_remotes/S3/comment_12_59c3ecab7dbc8be53258460473cac21c._comment8
-rw-r--r--doc/special_remotes/S3/comment_13_0789a21d980825188bb09f7fc8bba8be._comment33
-rw-r--r--doc/special_remotes/S3/comment_14_29574a51d5831c51e2e765eb2c06e567._comment12
-rw-r--r--doc/special_remotes/S3/comment_15_ceb9048c743135f6beca57a23505f0a3._comment8
-rw-r--r--doc/special_remotes/S3/comment_16_7b79f8b5ef88a2775d61b5ac5774d3e0._comment8
-rw-r--r--doc/special_remotes/S3/comment_1_4a1f7a230dad6caa84831685b236fd73._comment8
-rw-r--r--doc/special_remotes/S3/comment_2_5b22d67de946f4d34a4a3c7449d32988._comment8
-rw-r--r--doc/special_remotes/S3/comment_3_bcab2bd0f168954243aa9bcc9671bd94._comment8
-rw-r--r--doc/special_remotes/S3/comment_4_38c0b062997fde1ad28facc05d973e83._comment12
-rw-r--r--doc/special_remotes/S3/comment_5_409bc2b56382417cf26bb222fb783ba7._comment8
-rw-r--r--doc/special_remotes/S3/comment_6_78da9e233882ec0908962882ea8c4056._comment10
-rw-r--r--doc/special_remotes/S3/comment_7_6af9781004d982d8e6b20a83ad29eead._comment8
-rw-r--r--doc/special_remotes/S3/comment_8_0fa68d584ee7f6b5c9058fba7e911a11._comment12
-rw-r--r--doc/special_remotes/S3/comment_9_7ad757b3865b04967c79af0a263bb3b0._comment10
-rw-r--r--doc/special_remotes/bup.mdwn39
-rw-r--r--doc/special_remotes/bup/comment_10_f78c1ed97d2e4c6ebffaa7482cfe0c9b._comment23
-rw-r--r--doc/special_remotes/bup/comment_11_b53bceb0058acf4d1ab12ea4853ee443._comment24
-rw-r--r--doc/special_remotes/bup/comment_12_65d923226cf6120349d807c5c60f640c._comment8
-rw-r--r--doc/special_remotes/bup/comment_1_96179a003da4444f6fc08867872cda0a._comment43
-rw-r--r--doc/special_remotes/bup/comment_2_612b038c15206f9f3c2e23c7104ca627._comment12
-rw-r--r--doc/special_remotes/bup/comment_3_1186def82741ddab1ade256fb2e59e6f._comment17
-rw-r--r--doc/special_remotes/bup/comment_4_7d22a805dd2914971e7ca628ceea69be._comment10
-rw-r--r--doc/special_remotes/bup/comment_6_5942333cde09fd98e26c4f1d389cb76f._comment10
-rw-r--r--doc/special_remotes/bup/comment_7_cb1a0d3076e9d06e7a24204478f6fa98._comment10
-rw-r--r--doc/special_remotes/bup/comment_8_4cbc67e5911748d13cee3c483d7ece8a._comment12
-rw-r--r--doc/special_remotes/bup/comment_9_ca7096a759961af375e6bd49663b45b3._comment10
-rw-r--r--doc/special_remotes/comment_10_e9881290486a1770bd260f8650ada9c6._comment8
-rw-r--r--doc/special_remotes/comment_11_e01b5cc5a0d81b071e93e27e7b91fe2a._comment8
-rw-r--r--doc/special_remotes/comment_12_13237170ef5b6646e0e25d3421af3fe5._comment10
-rw-r--r--doc/special_remotes/comment_13_1a36a0483a9db04d36e0234a192ebad8._comment12
-rw-r--r--doc/special_remotes/comment_14_a8419963dc024b1d9eb73807596012dc._comment8
-rw-r--r--doc/special_remotes/comment_15_95ccfdd22a2391daa99e0beb04adedd6._comment11
-rw-r--r--doc/special_remotes/comment_16_b9d238fb15ad7628e33c90b071e07bb0._comment12
-rw-r--r--doc/special_remotes/comment_17_cc21b81a8f809f6efa5f5b6332513fc3._comment12
-rw-r--r--doc/special_remotes/comment_18_3fe750118ff1edbe91a110b86fb5b662._comment10
-rw-r--r--doc/special_remotes/comment_19_6794eb52bd87c28ef1df3172aa7d5780._comment9
-rw-r--r--doc/special_remotes/comment_1_961276c18e9353ca8e25cad53e7ec51f._comment8
-rw-r--r--doc/special_remotes/comment_20_6b7242721f2f2c77b634568cb737e3e3._comment13
-rw-r--r--doc/special_remotes/comment_21_5c11e69c28b9ed4cbe238a36c0839a47._comment15
-rw-r--r--doc/special_remotes/comment_2_97543acfa7434e332ebea5672e446317._comment8
-rw-r--r--doc/special_remotes/comment_3_9229776623c234204c8b164edff95da0._comment8
-rw-r--r--doc/special_remotes/comment_4_3bbda479d13f6bf393dcd59ed94ddeaa._comment10
-rw-r--r--doc/special_remotes/comment_5_f7000975d38077828ab11a99095b39eb._comment8
-rw-r--r--doc/special_remotes/comment_6_5d2bd7c1e1493d3c3784708a9b0bc001._comment8
-rw-r--r--doc/special_remotes/comment_7_af01ee5ce31b1490af565cb087d65277._comment10
-rw-r--r--doc/special_remotes/comment_8_3d4ffec566d68d601eafe8758a616756._comment13
-rw-r--r--doc/special_remotes/comment_9_26af468952f0403171370b56e127830a._comment8
-rw-r--r--doc/special_remotes/directory.mdwn33
-rw-r--r--doc/special_remotes/directory/comment_11_86f8c1b09cbd82bcd76378dfa1b3ca07._comment49
-rw-r--r--doc/special_remotes/directory/comment_12._comment16
-rw-r--r--doc/special_remotes/directory/comment_12_311cd013fd8db47856d84161119e059d._comment12
-rw-r--r--doc/special_remotes/directory/comment_1_e8a53592adb13f7d7f212a2eb5a18a31._comment12
-rw-r--r--doc/special_remotes/directory/comment_2_d949edad6a330079f9e15f703f9091e3._comment10
-rw-r--r--doc/special_remotes/directory/comment_3_49009f4e9e335c9a9d0422aa59c9a432._comment8
-rw-r--r--doc/special_remotes/directory/comment_4_f5e9b0b477c4e521f8633fd274757fa3._comment8
-rw-r--r--doc/special_remotes/directory/comment_5_e790718423c41f5ea8047ea5225bfacd._comment11
-rw-r--r--doc/special_remotes/directory/comment_6_325aac80b86588912c4fd61339ccbd0b._comment10
-rw-r--r--doc/special_remotes/directory/comment_7_4206db69d68d9917623ce02500387021._comment12
-rw-r--r--doc/special_remotes/directory/comment_8_acd9023511fe43817718bc89430f96c3._comment8
-rw-r--r--doc/special_remotes/directory/comment_9_d330eb808a990bb71034613c297a265e._comment8
-rw-r--r--doc/special_remotes/gcrypt.mdwn45
-rw-r--r--doc/special_remotes/glacier.mdwn47
-rw-r--r--doc/special_remotes/glacier/comment_1_fcd856b99dc6b3f9141b65fe639ef76b._comment10
-rw-r--r--doc/special_remotes/glacier/comment_2_38fcca87074f6ea31a12569a822aa8c9._comment12
-rw-r--r--doc/special_remotes/glacier/comment_3_cea5bcb162e4288847ba5f25464a0406._comment28
-rw-r--r--doc/special_remotes/glacier/comment_4_0c92cc82c7ac513130f862391a02d329._comment8
-rw-r--r--doc/special_remotes/glacier/comment_5_8d1dcb4bf48386314bfb248ea6eeeb68._comment8
-rw-r--r--doc/special_remotes/glacier/comment_6_adb1db354dc4941e4b004e4ba34660d7._comment8
-rw-r--r--doc/special_remotes/glacier/comment_7_747e403aac5acaba00e220931e926951._comment10
-rw-r--r--doc/special_remotes/hook.mdwn103
-rw-r--r--doc/special_remotes/hook/comment_1_6a74a25891974a28a8cb42b87cb53c26._comment32
-rw-r--r--doc/special_remotes/hook/comment_2_ee7c43b93c5b787216334f019643f6a0._comment17
-rw-r--r--doc/special_remotes/hook/comment_3_2593291795e732994862d08bf2ed467b._comment17
-rw-r--r--doc/special_remotes/hook/comment_4_35d79b5ffa5a19056efcdc805070bc4b._comment18
-rw-r--r--doc/special_remotes/hook/comment_5_6fbf1e963fa3ea4b2eb8ca5a3819762d._comment10
-rw-r--r--doc/special_remotes/hook/comment_6_e0ab48d5333e5de85f016b097e6fdac1._comment12
-rw-r--r--doc/special_remotes/hook/comment_7_cc2b1243c2c36e63241513bcaddfea67._comment10
-rw-r--r--doc/special_remotes/hook/comment_8_bbae315233bda48eb04662dfd48cf1ae._comment30
-rw-r--r--doc/special_remotes/hook/comment_9_037523d1994c702239ca96791156fe65._comment10
-rw-r--r--doc/special_remotes/rsync.mdwn56
-rw-r--r--doc/special_remotes/rsync/comment_10_43e8fa3517c1f5935f02ad06fbed63dc._comment8
-rw-r--r--doc/special_remotes/rsync/comment_11_8cafc1a8b37e6fb056185ec058c0c3e8._comment8
-rw-r--r--doc/special_remotes/rsync/comment_1_9e180c397486989beab21699b8e8f103._comment16
-rw-r--r--doc/special_remotes/rsync/comment_2_25545dc0b53f09ae73b29899c8884b02._comment8
-rw-r--r--doc/special_remotes/rsync/comment_3_960a89b1ae7e3888ffba06baa963dc21._comment20
-rw-r--r--doc/special_remotes/rsync/comment_4_db84816c31239953dd21f23a8c557b43._comment15
-rw-r--r--doc/special_remotes/rsync/comment_5_ccaffa4aded9dab88c76a856b96ea5b9._comment9
-rw-r--r--doc/special_remotes/rsync/comment_6_e687b9482b177e1351c8c65ea617d3fa._comment8
-rw-r--r--doc/special_remotes/rsync/comment_7_e122979ea811d9ef835ba05bb936190f._comment10
-rw-r--r--doc/special_remotes/rsync/comment_8_d566113318d0aa7500d76ffe1bd46069._comment10
-rw-r--r--doc/special_remotes/rsync/comment_9_5dcf10a502b2d4feac46b620d43e9d00._comment8
-rw-r--r--doc/special_remotes/web.mdwn11
-rw-r--r--doc/special_remotes/web/comment_1_0bd570025f6cd551349ea88a4729ac8e._comment8
-rw-r--r--doc/special_remotes/web/comment_2_333141cc9ec6c26ffd19aa95303a91e3._comment8
-rw-r--r--doc/special_remotes/webdav.mdwn42
-rw-r--r--doc/special_remotes/webdav/comment_1_6b523eea78eae1d19fe2a9950ee33e3a._comment26
-rw-r--r--doc/special_remotes/webdav/comment_2_83fc4e7d9ba7a05c8500da659f561b8f._comment10
-rw-r--r--doc/special_remotes/webdav/comment_3_239367ad639c61ecdf87a89f7ac53efe._comment10
-rw-r--r--doc/special_remotes/webdav/comment_4_ffa52f7776cdc8caa28667b5eadae123._comment8
-rw-r--r--doc/special_remotes/webdav/comment_5_5b8cbdb5e9a1b90d748a5074997e1cd5._comment12
-rw-r--r--doc/special_remotes/webdav/comment_6_d3be3e588c3a2abb2025ceb82c18b0ef._comment10
-rw-r--r--doc/special_remotes/webdav/comment_7_6fa7e11331db5a943015bd5367eb3d73._comment12
-rw-r--r--doc/special_remotes/webdav/comment_8_2627b41f80c7511b27464e2040b128a8._comment8
-rw-r--r--doc/special_remotes/xmpp.mdwn39
-rw-r--r--doc/special_remotes/xmpp/comment_10_c7c2e2e81cb5b2b9a5272430c835dd39._comment10
-rw-r--r--doc/special_remotes/xmpp/comment_1_568247938929a2934e8198fca80b7184._comment11
-rw-r--r--doc/special_remotes/xmpp/comment_2_9fc3f512020b7eb2591d6b7b2e8de2d7._comment10
-rw-r--r--doc/special_remotes/xmpp/comment_3_48ddbba1402d89acaea07cff747c48e0._comment28
-rw-r--r--doc/special_remotes/xmpp/comment_4_59857879abaae22bde444a215e00bf18._comment14
-rw-r--r--doc/special_remotes/xmpp/comment_5_583ee374bd34fcc9ae26c2fd690e8c47._comment73
-rw-r--r--doc/special_remotes/xmpp/comment_6_8f0b5bba1271d031a67e7f0c175d67d5._comment8
-rw-r--r--doc/special_remotes/xmpp/comment_7_ac7acbded03325b015959d82ae77faf1._comment10
-rw-r--r--doc/special_remotes/xmpp/comment_8_81a9636a1e8a36a58185468a26f8633d._comment8
-rw-r--r--doc/special_remotes/xmpp/comment_9_eda76b826491c96b1ce072aacf9d3adf._comment23
-rw-r--r--doc/summary.mdwn11
-rw-r--r--doc/sync.mdwn38
-rw-r--r--doc/sync/comment_1_59681be5568f568f5c54eb0445163dd2._comment8
-rw-r--r--doc/sync/comment_2_9301ff5e81d37475f594e74fbe32f24e._comment11
-rw-r--r--doc/sync/comment_3_49560003da47490e4fabd4ab0089f2d7._comment8
-rw-r--r--doc/sync/comment_4_cf29326408e62575085d1f980087c923._comment8
-rw-r--r--doc/sync/comment_5_18c396c59907147bb2bf713e55392b6b._comment8
-rw-r--r--doc/sync/comment_6_012e9d4468d0b88ee3c5dad3911c3606._comment10
-rw-r--r--doc/sync/comment_7_6276e100d1341f1a0be368f54de0ae7b._comment8
-rw-r--r--doc/templates/bare.tmpl1
-rw-r--r--doc/templates/bugtemplate.mdwn18
-rw-r--r--doc/templates/walkthrough.tmpl2
-rw-r--r--doc/testimonials.mdwn34
-rw-r--r--doc/testimonials/comment_1_2bf439f7a3bc3d6fab91849017946182._comment8
-rw-r--r--doc/tips.mdwn4
-rw-r--r--doc/tips/Building_git-annex_on_Debian_OR___37____164____35____34____164____37____38____34____35___Haskell__33__.mdwn111
-rw-r--r--doc/tips/Building_git-annex_on_Debian_OR___37____164____35____34____164____37____38____34____35___Haskell__33__/comment_1_835a3608df3e9d044cabe822d0f3e7e4._comment27
-rw-r--r--doc/tips/Building_git-annex_on_Debian_OR___37____164____35____34____164____37____38____34____35___Haskell__33__/comment_2_080b30cba72a718e73ea715e259e1cfb._comment8
-rw-r--r--doc/tips/Crude_Windows_Sync.mdwn35
-rw-r--r--doc/tips/Decentralized_repository_behind_a_Firewall.mdwn59
-rw-r--r--doc/tips/Decentralized_repository_behind_a_Firewall/comment_1_78b9035234a690ca5a7c9f3cc78fa092._comment8
-rw-r--r--doc/tips/Delay_Assistant_Startup_on_Login.mdwn13
-rw-r--r--doc/tips/Delay_Assistant_Startup_on_Login/comment_1_c63917150527efab4b1106183b3aa7ef._comment8
-rw-r--r--doc/tips/Git_annex_and_Calibre.mdwn120
-rw-r--r--doc/tips/How_to_retroactively_annex_a_file_already_in_a_git_repo.mdwn19
-rw-r--r--doc/tips/How_to_retroactively_annex_a_file_already_in_a_git_repo/comment_1_7eaf73fb3355bd706ab18a43790b3c10._comment8
-rw-r--r--doc/tips/How_to_retroactively_annex_a_file_already_in_a_git_repo/comment_2_dac1a171204f30d7c906e878eb6bd461._comment45
-rw-r--r--doc/tips/How_to_retroactively_annex_a_file_already_in_a_git_repo/comment_3_b62ec0b848d2487d68d7032682622193._comment36
-rw-r--r--doc/tips/How_to_retroactively_annex_a_file_already_in_a_git_repo/comment_4_2423904e41a86cd1c6bc155d7b733642._comment9
-rw-r--r--doc/tips/Internet_Archive_via_S3.mdwn58
-rw-r--r--doc/tips/Internet_Archive_via_S3/comment_1_d53a3848c20dce61867283fc03c2adaa._comment34
-rw-r--r--doc/tips/Internet_Archive_via_S3/comment_2_91c1472da27b00e5d682d22bc1ef04e0._comment10
-rw-r--r--doc/tips/Internet_Archive_via_S3/comment_3_e23cf781c532f80d47d52265f2b2c87e._comment8
-rw-r--r--doc/tips/The_perfect_preferred_content_settings_for_my_android_phone.mdwn32
-rw-r--r--doc/tips/The_perfect_preferred_content_settings_for_my_android_phone/comment_1_393d1636bb313530be383a075bd3440a._comment14
-rw-r--r--doc/tips/Using_Git-annex_as_a_web_browsing_assistant.mdwn46
-rw-r--r--doc/tips/Using_Git-annex_as_a_web_browsing_assistant/comment_1_74167f9fff400f148916003468c77de4._comment8
-rw-r--r--doc/tips/assume-unstaged.mdwn31
-rw-r--r--doc/tips/assume-unstaged/comment_1_44abd811ef79a85e557418e17a3927be._comment10
-rw-r--r--doc/tips/assume-unstaged/comment_2_5b589f37cfc03bf7be33a51826cc4dba._comment13
-rw-r--r--doc/tips/automatically_getting_files_on_checkout.mdwn15
-rw-r--r--doc/tips/beware_of_SSD_wear_when_doing_fsck_on_large_special_remotes.mdwn2
-rw-r--r--doc/tips/beware_of_SSD_wear_when_doing_fsck_on_large_special_remotes/comment_1_e7c5c46112a2406b873d08bbf53c40d8._comment8
-rw-r--r--doc/tips/beware_of_SSD_wear_when_doing_fsck_on_large_special_remotes/comment_2_daf45ce29fed986fa9aa8b173760d0b7._comment14
-rw-r--r--doc/tips/beware_of_SSD_wear_when_doing_fsck_on_large_special_remotes/comment_3_72d222020af4a9c6c753eb1ee7e1f1cf._comment8
-rw-r--r--doc/tips/centralised_repository:_starting_from_nothing.mdwn75
-rw-r--r--doc/tips/centralised_repository:_starting_from_nothing/comment_1_b0d22822017646775869ce1292e676f4._comment8
-rw-r--r--doc/tips/centralized_git_repository_tutorial.mdwn140
-rw-r--r--doc/tips/centralized_git_repository_tutorial/comment_1_9072ebc0c61446d7b151fcfab616fea9._comment33
-rw-r--r--doc/tips/centralized_git_repository_tutorial/comment_2_528e92b21f0551fde4adb956654953ae._comment8
-rw-r--r--doc/tips/downloading_podcasts.mdwn63
-rw-r--r--doc/tips/downloading_podcasts/comment_10_4d4f6c22070b58918ee8d34c5e7290ad._comment8
-rw-r--r--doc/tips/downloading_podcasts/comment_11_d8d77048c7e2524968c188e1ad517873._comment24
-rw-r--r--doc/tips/downloading_podcasts/comment_12_0859317471b43c88744dd3df95c879f7._comment10
-rw-r--r--doc/tips/downloading_podcasts/comment_13_e8c3c97282d17e2a1d47fb9d5e2b2f7b._comment18
-rw-r--r--doc/tips/downloading_podcasts/comment_14_05a3694052de36848fbbad6eeeada895._comment8
-rw-r--r--doc/tips/downloading_podcasts/comment_15_21028bed8858c2dae1ac9c2d014fd2a1._comment8
-rw-r--r--doc/tips/downloading_podcasts/comment_16_4869fb5c9f896acc477c44de06c36ca7._comment8
-rw-r--r--doc/tips/downloading_podcasts/comment_17_2e278ff200c1c15efd27c46a3e0aed40._comment9
-rw-r--r--doc/tips/downloading_podcasts/comment_18_382f2b970738d9b1af577955c3083e90._comment15
-rw-r--r--doc/tips/downloading_podcasts/comment_19_f76fc6835e5787b0156380bf09fd81ca._comment8
-rw-r--r--doc/tips/downloading_podcasts/comment_1_f04bc32a34baeeffcd691e9f7cce0230._comment13
-rw-r--r--doc/tips/downloading_podcasts/comment_20_65ebf3a3bbf0a2aebd2b69640b757e16._comment10
-rw-r--r--doc/tips/downloading_podcasts/comment_2_a9a98cad7358d16792853a2ee413fe6c._comment8
-rw-r--r--doc/tips/downloading_podcasts/comment_3_5a8068a5cb0fd864581157a3aa5d1113._comment10
-rw-r--r--doc/tips/downloading_podcasts/comment_4_e7072a9da30b4c4b4c526013144238d4._comment10
-rw-r--r--doc/tips/downloading_podcasts/comment_5_79b3f8d678ac9f67df4c0cd649657283._comment8
-rw-r--r--doc/tips/downloading_podcasts/comment_6_35106fee5458bdd5c21868fbc49d3616._comment10
-rw-r--r--doc/tips/downloading_podcasts/comment_7_ceb16498b7aadbf04a27acd5d6561d46._comment8
-rw-r--r--doc/tips/downloading_podcasts/comment_8_147397603f0b3fdb42ca387d1da7c5ef._comment8
-rw-r--r--doc/tips/downloading_podcasts/comment_9_6a26a6cc7683d38fae0f23c5a52d1e23._comment24
-rw-r--r--doc/tips/dropboxannex.mdwn28
-rw-r--r--doc/tips/emacs_integration.mdwn20
-rw-r--r--doc/tips/finding_duplicate_files.mdwn21
-rw-r--r--doc/tips/finding_duplicate_files/comment_10_2ed5aa8c632048b13e01d358883fa383._comment12
-rw-r--r--doc/tips/finding_duplicate_files/comment_1_ddb477ca242ffeb21e0df394d8fdf5d2._comment8
-rw-r--r--doc/tips/finding_duplicate_files/comment_2_900eafe0a781018ff44b35ac232e3ad3._comment8
-rw-r--r--doc/tips/finding_duplicate_files/comment_3._comment39
-rw-r--r--doc/tips/finding_duplicate_files/comment_4_1494143a74cc1e9fbe4720c14b73d42b._comment8
-rw-r--r--doc/tips/finding_duplicate_files/comment_5_1a35ca360468bcb84a67ad8d62a2ef7d._comment8
-rw-r--r--doc/tips/finding_duplicate_files/comment_6_a6e88c93b31f67c933523725ff61b287._comment16
-rw-r--r--doc/tips/finding_duplicate_files/comment_7_347b0186755a809594bd42feda6363e2._comment10
-rw-r--r--doc/tips/finding_duplicate_files/comment_8_3af51722da0980b724facb184f0f66e9._comment10
-rw-r--r--doc/tips/finding_duplicate_files/comment_9_7b4b78a5cd253abfe4f6001049bf64f3._comment10
-rw-r--r--doc/tips/flickrannex.mdwn62
-rw-r--r--doc/tips/flickrannex/comment_10_50707f259abe5829ce075dfbecd5a4ba._comment13
-rw-r--r--doc/tips/flickrannex/comment_11_ab5bcb025381b3da4d7c6dfd0c7310dd._comment46
-rw-r--r--doc/tips/flickrannex/comment_12_90a331275d888221bc695003c8acbe46._comment58
-rw-r--r--doc/tips/flickrannex/comment_13_1596e70dca71c853fd1d6fc9bde02b18._comment12
-rw-r--r--doc/tips/flickrannex/comment_2_d74c4fc7edf8e47f7482564ce0ef4d12._comment10
-rw-r--r--doc/tips/flickrannex/comment_2_f53d0d5520e2835e9705bea4e75556f0._comment30
-rw-r--r--doc/tips/flickrannex/comment_4_9ebba4d61140f6c2071e988c9328cf7e._comment14
-rw-r--r--doc/tips/flickrannex/comment_5_4470dae270613dd8712623474bc80ab0._comment24
-rw-r--r--doc/tips/flickrannex/comment_5_d395cdcf815cb430e374ff05c1a63ff4._comment17
-rw-r--r--doc/tips/flickrannex/comment_6_8cf730097001ffe106f2c743edce9d0a._comment12
-rw-r--r--doc/tips/flickrannex/comment_7_a80c8087c4e1562a4c98a24edc182e5a._comment12
-rw-r--r--doc/tips/flickrannex/comment_8_94f84254c32cf0f7dd1441b7da5d2bc6._comment8
-rw-r--r--doc/tips/flickrannex/comment_9_5299b4cab4a4cb8e8fd4d2b39f0ea59c._comment9
-rw-r--r--doc/tips/fully_encrypted_git_repositories_with_gcrypt.mdwn127
-rw-r--r--doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_10_4440a80d64c60c7312d5c405d54e607a._comment15
-rw-r--r--doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_1_5c54690586f2a781905ea4b25aa1147f._comment18
-rw-r--r--doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_2_07feedb4348f8c31176cc744c19368a1._comment21
-rw-r--r--doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_3_c2f873dffa015f1d72ad0c3921909316._comment8
-rw-r--r--doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_4_f8a6e4415f4fe6da14f6a3b7334bc952._comment18
-rw-r--r--doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_5_11b8e82d2a234f65b58b823e71c6d6a2._comment10
-rw-r--r--doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_6_3e41948e1beffcf279bb05ef8e61cc07._comment16
-rw-r--r--doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_7_4ce0b26b25b336f07b2e27246cdfba3e._comment16
-rw-r--r--doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_8_49aa34d75d24a2066baa8a585bc9c2e9._comment14
-rw-r--r--doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_9_3784e0c828cd60b6a9075c2d32d070cc._comment14
-rw-r--r--doc/tips/googledriveannex.mdwn28
-rw-r--r--doc/tips/imapannex.mdwn27
-rw-r--r--doc/tips/megaannex.mdwn41
-rw-r--r--doc/tips/migrating_data_to_a_new_backend.mdwn16
-rw-r--r--doc/tips/migrating_two_seperate_disconnected_directories_to_git_annex.mdwn77
-rw-r--r--doc/tips/offline_archive_drives.mdwn69
-rw-r--r--doc/tips/offline_archive_drives/comment_1_3d4fdf42191a9d81434d00f51c3609ff._comment12
-rw-r--r--doc/tips/offline_archive_drives/comment_2_864c752aa8d064791a4b14dbbe2e6882._comment15
-rw-r--r--doc/tips/offline_archive_drives/comment_3_7be2ccaf70c9ecfc9a34384e0e31f490._comment10
-rw-r--r--doc/tips/owncloudannex.mdwn28
-rw-r--r--doc/tips/owncloudannex/comment_1_129652308c3c499462828dcaf8e747a4._comment40
-rw-r--r--doc/tips/owncloudannex/comment_2_38604990368666f654d41891ba99ac61._comment15
-rw-r--r--doc/tips/owncloudannex/comment_3_1bfd290d00d6536da7d31818db46f8ec._comment87
-rw-r--r--doc/tips/owncloudannex/comment_4_492b6922a7c5bb5464fedb46b0c5303b._comment17
-rw-r--r--doc/tips/owncloudannex/comment_5_1d48ac08714fadcb06d874570d745bd8._comment16
-rw-r--r--doc/tips/owncloudannex/comment_6_65959f49a2f56bffd6fe48670c0c8d5a._comment8
-rw-r--r--doc/tips/owncloudannex/comment_7_7482002991672ef67836bae43b8d0be8._comment8
-rw-r--r--doc/tips/powerful_file_matching.mdwn36
-rw-r--r--doc/tips/recover_data_from_lost+found.mdwn19
-rw-r--r--doc/tips/recovering_from_a_corrupt_git_repository.mdwn17
-rw-r--r--doc/tips/recovering_from_a_corrupt_git_repository/comment_1_f5827be97f78dbae113a5ba0c9ced896._comment8
-rw-r--r--doc/tips/recovering_from_a_corrupt_git_repository/comment_2_e98df7275bb032308bb87e3607bdde32._comment8
-rw-r--r--doc/tips/recovering_from_a_corrupt_git_repository/comment_3_11bece6dfac090edbcd783b266c482a3._comment8
-rw-r--r--doc/tips/recovering_from_a_corrupt_git_repository/comment_4_86e99017f7585ac2f76753051214637e._comment8
-rw-r--r--doc/tips/recovering_from_a_corrupt_git_repository/comment_6_c8953732ce353cdf0c4fb81ddc98c04a._comment8
-rw-r--r--doc/tips/recovering_from_a_corrupt_git_repository/comment_6_d0da84df0241dc6ccf0aa0c7598917df._comment8
-rw-r--r--doc/tips/recovering_from_a_corrupt_git_repository/comment_7_addf49556e4c33d55a41c393f519d0a4._comment10
-rw-r--r--doc/tips/recovering_from_a_corrupt_git_repository/comment_8_505a2fc2b841fe8eb419801f923ef35f._comment8
-rw-r--r--doc/tips/replacing_Sparkleshare_or_dvcs-autosync_with_the_assistant.mdwn41
-rw-r--r--doc/tips/replacing_Sparkleshare_or_dvcs-autosync_with_the_assistant/comment_1_907e4032ca4a39adb846cf16dbf447dc._comment8
-rw-r--r--doc/tips/replacing_Sparkleshare_or_dvcs-autosync_with_the_assistant/comment_2_902d001ba86657ef0f8cca5b175f99ca._comment8
-rw-r--r--doc/tips/replacing_Sparkleshare_or_dvcs-autosync_with_the_assistant/comment_3_a1cf93f9b29658f0f26e9e0ae6057ee3._comment60
-rw-r--r--doc/tips/replacing_Sparkleshare_or_dvcs-autosync_with_the_assistant/comment_4_e10671908b58c554375787d0f76e2366._comment13
-rw-r--r--doc/tips/replacing_Sparkleshare_or_dvcs-autosync_with_the_assistant/comment_5_4114380f66b6376c851e93f6876d590b._comment8
-rw-r--r--doc/tips/replacing_Sparkleshare_or_dvcs-autosync_with_the_assistant/comment_6_6a5d6af107b297afd008b021f73d787b._comment8
-rw-r--r--doc/tips/replacing_Sparkleshare_or_dvcs-autosync_with_the_assistant/comment_7_74d57cf503a86d8f7ace2d769dbb58be._comment10
-rw-r--r--doc/tips/setup_a_public_repository_on_a_web_site.mdwn55
-rw-r--r--doc/tips/setup_a_public_repository_on_a_web_site/comment_1_1d0fa6da33e401df1d7ff31979247fec._comment10
-rw-r--r--doc/tips/setup_a_public_repository_on_a_web_site/comment_2_b98b761dee9d923153e3c288c1d987ee._comment11
-rw-r--r--doc/tips/shared_git_annex_directory_between_multiple_users.mdwn39
-rw-r--r--doc/tips/skydriveannex.mdwn29
-rw-r--r--doc/tips/untrusted_repositories.mdwn28
-rw-r--r--doc/tips/using_Amazon_Glacier.mdwn75
-rw-r--r--doc/tips/using_Amazon_S3.mdwn37
-rw-r--r--doc/tips/using_Amazon_S3/comment_1_666a26f95024760c99c627eed37b1966._comment8
-rw-r--r--doc/tips/using_Amazon_S3/comment_2_f5a0883be7dbb421b584c6dc0165f1ef._comment8
-rw-r--r--doc/tips/using_Google_Cloud_Storage.mdwn9
-rw-r--r--doc/tips/using_Google_Cloud_Storage/comment_1_c576182f39563ae68767391c4227a177._comment18
-rw-r--r--doc/tips/using_box.com_as_a_special_remote.mdwn71
-rw-r--r--doc/tips/using_git_annex_with_no_fixed_hostname_and_optimising_ssh.mdwn59
-rw-r--r--doc/tips/using_git_annex_with_no_fixed_hostname_and_optimising_ssh/comment_1_c0b7682a2b6f3078457b85683c825baf._comment10
-rw-r--r--doc/tips/using_gitolite_with_git-annex.mdwn89
-rw-r--r--doc/tips/using_gitolite_with_git-annex/comment_10_8767bc8014b459a3cd76f275fd4fa8d6._comment8
-rw-r--r--doc/tips/using_gitolite_with_git-annex/comment_11_00715e0b47f09130e0e536e29f7b9258._comment31
-rw-r--r--doc/tips/using_gitolite_with_git-annex/comment_12_7027ce60265b8f24c8ab54553e544068._comment8
-rw-r--r--doc/tips/using_gitolite_with_git-annex/comment_13_75218b7409c0e281cb01c9b2791e8cdf._comment20
-rw-r--r--doc/tips/using_gitolite_with_git-annex/comment_14_7d4d4515218d1259d32be3baeb5ee56e._comment13
-rw-r--r--doc/tips/using_gitolite_with_git-annex/comment_15_dc6f21b5a3d5931c8d949a9753411b9e._comment29
-rw-r--r--doc/tips/using_gitolite_with_git-annex/comment_16_8e5039e6655fc80dc863b6cdf44ef02a._comment15
-rw-r--r--doc/tips/using_gitolite_with_git-annex/comment_17_9c40e1da8bb44f7207e802377f5cf923._comment11
-rw-r--r--doc/tips/using_gitolite_with_git-annex/comment_1_9a2a2a8eac9af97e0c984ad105763a73._comment15
-rw-r--r--doc/tips/using_gitolite_with_git-annex/comment_2_d8efea4ab9576555fadbb47666ecefa9._comment8
-rw-r--r--doc/tips/using_gitolite_with_git-annex/comment_3_807035f38509ccb9f93f1929ecd37417._comment8
-rw-r--r--doc/tips/using_gitolite_with_git-annex/comment_4_eb81f824aadc97f098379c5f7e4fba4c._comment33
-rw-r--r--doc/tips/using_gitolite_with_git-annex/comment_5_f688309532d2993630e9e72e87fb9c46._comment20
-rw-r--r--doc/tips/using_gitolite_with_git-annex/comment_6_3e203e010a4df5bf03899f867718adc5._comment25
-rw-r--r--doc/tips/using_gitolite_with_git-annex/comment_7_f8fd08b6ab47378ad88c87348057220d._comment10
-rw-r--r--doc/tips/using_gitolite_with_git-annex/comment_8_8249772c142117f88e37975d058aa936._comment29
-rw-r--r--doc/tips/using_gitolite_with_git-annex/comment_9_28418635a6ed7231b89e02211cd3c236._comment8
-rw-r--r--doc/tips/using_the_SHA1_backend.mdwn11
-rw-r--r--doc/tips/using_the_web_as_a_special_remote.mdwn101
-rw-r--r--doc/tips/using_the_web_as_a_special_remote/comment_1_321a41d611c6fe45e047af9c96c5176c._comment26
-rw-r--r--doc/tips/using_the_web_as_a_special_remote/comment_2_dfe9c8c49aadff80d2020288584e0390._comment10
-rw-r--r--doc/tips/using_the_web_as_a_special_remote/comment_3_ed8dd3bbd9b9ae7f2309b72b94f61eb1._comment18
-rw-r--r--doc/tips/using_the_web_as_a_special_remote/comment_4_c1133a524989a940f1b5db588707157a._comment10
-rw-r--r--doc/tips/visualizing_repositories_with_gource.mdwn22
-rw-r--r--doc/tips/visualizing_repositories_with_gource/screenshot.jpgbin0 -> 78509 bytes
-rw-r--r--doc/tips/what_to_do_when_a_repository_is_corrupted.mdwn22
-rw-r--r--doc/tips/what_to_do_when_you_lose_a_repository.mdwn19
-rw-r--r--doc/tips/what_to_do_when_you_lose_a_repository/comment_1_cf19b8dc304dc37c26717174c4a98aa4._comment11
-rw-r--r--doc/tips/what_to_do_when_you_lose_a_repository/comment_3_fa9ca81668f5faebf2f61b10f82c97d2._comment8
-rw-r--r--doc/tips/yet_another_simple_disk_usage_like_utility.mdwn9
-rw-r--r--doc/tips/yet_another_simple_disk_usage_like_utility/comment_1_41b212bde8bc88d2a5dea93bd0dc75f1._comment9
-rw-r--r--doc/tips/yet_another_simple_disk_usage_like_utility/comment_2_73698913837bfd5a58cf15721211e43e._comment8
-rw-r--r--doc/todo.mdwn4
-rw-r--r--doc/todo/A_really_simple_way_to_pair_devices_like_bittorent_sync.mdwn7
-rw-r--r--doc/todo/A_really_simple_way_to_pair_devices_like_bittorent_sync/comment_1_d828bc374e50a49101c0b863f9b33080._comment8
-rw-r--r--doc/todo/A_really_simple_way_to_pair_devices_like_bittorent_sync/comment_2_a4badfc248be428e6426a936212cc896._comment8
-rw-r--r--doc/todo/A_really_simple_way_to_pair_devices_like_bittorent_sync/comment_3_0b04089d3d33fdb48eeb46bf168e9a3c._comment8
-rw-r--r--doc/todo/A_really_simple_way_to_pair_devices_like_bittorent_sync/comment_4_2bcab1b7998b4df08fca41b8d810f115._comment10
-rw-r--r--doc/todo/A_really_simple_way_to_pair_devices_like_bittorent_sync/comment_5_677e958c3f2effec7528b484aeb6478d._comment13
-rw-r--r--doc/todo/A_really_simple_way_to_pair_devices_like_bittorent_sync/comment_6_56e53803fdede895cba717e6b6e9a1bb._comment23
-rw-r--r--doc/todo/Bittorrent-like_features.mdwn45
-rw-r--r--doc/todo/Bittorrent-like_features/comment_1_f4c110ef35ebf4fd89f06edf2c4f0c48._comment13
-rw-r--r--doc/todo/Build_for_Synology_DSM.mdwn1
-rw-r--r--doc/todo/Build_for_Synology_DSM/comment_10_e351084d9a83db3fd6d9d983227a6410._comment8
-rw-r--r--doc/todo/Build_for_Synology_DSM/comment_11_cc67a584f5c460a6fb63cf099c20e573._comment9
-rw-r--r--doc/todo/Build_for_Synology_DSM/comment_12_94023593d294b9cf69090fcfd6ca0e5a._comment9
-rw-r--r--doc/todo/Build_for_Synology_DSM/comment_13_314255fd503d125b5aeae2f62acfd592._comment8
-rw-r--r--doc/todo/Build_for_Synology_DSM/comment_15_9525cd0d75ff4c15182d10a855774b69._comment30
-rw-r--r--doc/todo/Build_for_Synology_DSM/comment_1_4059016fa8da6af7a3eba8966821e8eb._comment10
-rw-r--r--doc/todo/Build_for_Synology_DSM/comment_2_8900c2985ab68b3b566c9f5d326471d6._comment8
-rw-r--r--doc/todo/Build_for_Synology_DSM/comment_3_f2b77368473d42b7f21e9d51d6415b58._comment10
-rw-r--r--doc/todo/Build_for_Synology_DSM/comment_4_a55fea734044c270ceb10adf9c8d9a76._comment8
-rw-r--r--doc/todo/Build_for_Synology_DSM/comment_5_59865ada057c640ac29855c65cf45dd9._comment23
-rw-r--r--doc/todo/Build_for_Synology_DSM/comment_6_6d860b1ad8816077b5fa596a71b12d5c._comment8
-rw-r--r--doc/todo/Build_for_Synology_DSM/comment_7_19ef2d293ba3bc7ece443d7278371c3f._comment8
-rw-r--r--doc/todo/Build_for_Synology_DSM/comment_8_609b7ad87dfbba49ec1f8c6fc2739ccd._comment12
-rw-r--r--doc/todo/Build_for_Synology_DSM/comment_9_d94a73b9a07c5cadf191005f817fd59a._comment29
-rw-r--r--doc/todo/Check_if_an_upgrade_is_available_in_the_webapp.mdwn5
-rw-r--r--doc/todo/Check_if_an_upgrade_is_available_in_the_webapp/comment_1_c904182f6bff8b1a42070bbc038eb34e._comment17
-rw-r--r--doc/todo/Deleting_Unused_Files_by_Age.mdwn13
-rw-r--r--doc/todo/Move_ssh_config_to___126____47__ssh__47__git-annex__47__config.mdwn7
-rw-r--r--doc/todo/Move_ssh_config_to___126____47__ssh__47__git-annex__47__config/comment_1_284c806e83a32af81b02aea7c7bc285a._comment10
-rw-r--r--doc/todo/Move_ssh_config_to___126____47__ssh__47__git-annex__47__config/comment_2_1f55ad6b39906458779b2d604b003ffe._comment10
-rw-r--r--doc/todo/Move_ssh_config_to___126____47__ssh__47__git-annex__47__config/comment_3_b00dce2374aac6968317d05d23bcfaf7._comment8
-rw-r--r--doc/todo/Move_ssh_config_to___126____47__ssh__47__git-annex__47__config/comment_4_743d0b077110c5cac1e2f47187b75333._comment10
-rw-r--r--doc/todo/Not_working_on_Android-x86.mdwn19
-rw-r--r--doc/todo/Not_working_on_Android-x86/comment_1_5eec4d7530c9df68f1bd1b1ca7021ef5._comment14
-rw-r--r--doc/todo/Option_for_browser_to_launch_webapp_with.mdwn7
-rw-r--r--doc/todo/Please_abort_build_if___34__make_test__34___fails.mdwn7
-rw-r--r--doc/todo/Please_add_support_for_monad-control_0.3.x.mdwn9
-rw-r--r--doc/todo/S3.mdwn24
-rw-r--r--doc/todo/Show_repo_type_in_repo_list.mdwn1
-rw-r--r--doc/todo/Show_repo_type_in_repo_list/comment_1_ac6eb1072ef902a094b79dd8e0917c4d._comment10
-rw-r--r--doc/todo/Show_repo_type_in_repo_list/comment_2_6979c487f707a724a048d20e2e5744e6._comment14
-rw-r--r--doc/todo/Show_repo_type_in_repo_list/comment_3_529254a6cc20de7259d60a3cbc5ccaf7._comment8
-rw-r--r--doc/todo/Slow_transfer_for_a_lot_of_small_files..mdwn20
-rw-r--r--doc/todo/Sync_repo_names__63__.mdwn10
-rw-r--r--doc/todo/Use_MediaScannerConnection_on_Android.mdwn7
-rw-r--r--doc/todo/Use_a_remote_as_a_sharing_site_for_files_with_obfuscated_URLs.mdwn7
-rw-r--r--doc/todo/Use_a_remote_as_a_sharing_site_for_files_with_obfuscated_URLs/comment_1_1a1f34f4f389267d67e79409c0ca8b1d._comment9
-rw-r--r--doc/todo/Wishlist:_additional_environment_variables_for_hooks.mdwn14
-rw-r--r--doc/todo/Wishlist:_sanitychecker_fix_wrong_UUID__47__duplicate_remote.mdwn7
-rw-r--r--doc/todo/__96__git_annex_import_--lazy__96___--_Delete_everything_that__39__s_in_the_source_directory_and_also_in_the_target_annex.mdwn29
-rw-r--r--doc/todo/__96__git_annex_import_--lazy__96___--_Delete_everything_that__39__s_in_the_source_directory_and_also_in_the_target_annex/comment_1_0cc16eb17151309113cec6d1cccf203d._comment20
-rw-r--r--doc/todo/__96__git_annex_status__47__version__96___should_print_the_local_OS.mdwn6
-rw-r--r--doc/todo/__96__git_annex_sync_--auto__96___or___96__git_annex_auto__96___--_synchronize_symlinks__44___tracking_info__44___and_actual_data.mdwn3
-rw-r--r--doc/todo/add_--exclude_option_to_git_annex_find.mdwn4
-rw-r--r--doc/todo/add_-all_option.mdwn22
-rw-r--r--doc/todo/add_a_git_backend.mdwn18
-rw-r--r--doc/todo/add_an_icon_for_the_.desktop_file.mdwn1
-rw-r--r--doc/todo/add_metadata_to_annexed_files.mdwn5
-rw-r--r--doc/todo/add_metadata_to_annexed_files/comment_1_38af9b352020194e9ace34d7dde188cf._comment10
-rw-r--r--doc/todo/assistant_cannot_set_up_remote_repo_via_an_ssh_alias_or_an_ip_address.mdwn48
-rw-r--r--doc/todo/assistant_git_sync_laddering.mdwn10
-rw-r--r--doc/todo/assistant_parallel_file_transfers.txt15
-rw-r--r--doc/todo/assistant_smarter_archive_directory_handling.mdwn31
-rw-r--r--doc/todo/assistant_threaded_runtime.mdwn40
-rw-r--r--doc/todo/auto_remotes.mdwn29
-rw-r--r--doc/todo/auto_remotes/discussion.mdwn7
-rw-r--r--doc/todo/automatic_bookkeeping_watch_command.mdwn15
-rw-r--r--doc/todo/automatic_merge_of_synced_branches_upon___34__git_annex_sync__34__.mdwn16
-rw-r--r--doc/todo/avoid_unnecessary_union_merges.mdwn20
-rw-r--r--doc/todo/backendSHA1.mdwn7
-rw-r--r--doc/todo/branching.mdwn159
-rw-r--r--doc/todo/cache_key_info.mdwn37
-rw-r--r--doc/todo/cache_key_info/comment_1_578df1b3b2cbfdc4aa1805378f35dc48._comment11
-rw-r--r--doc/todo/checkout.mdwn23
-rw-r--r--doc/todo/checksum_verification_on_transfer.mdwn7
-rw-r--r--doc/todo/checksum_verification_on_transfer/comment_1_30f77e631608b9751f9032f97d58cc30._comment17
-rw-r--r--doc/todo/direct_mode_guard.mdwn105
-rw-r--r--doc/todo/direct_mode_guard/comment_1_431b6e1577bbd30b07dce9002a8fe1a2._comment10
-rw-r--r--doc/todo/direct_mode_guard/comment_2_85bdb9dc601b87bd7c77150d7b0a5cde._comment8
-rw-r--r--doc/todo/done.mdwn4
-rw-r--r--doc/todo/dumb_plaindir_remote___40__e.g._for_NAS_mounts__41__.mdwn5
-rw-r--r--doc/todo/dumb_plaindir_remote___40__e.g._for_NAS_mounts__41__/comment_1_5ed9a2336b432b842c1805add6d96509._comment10
-rw-r--r--doc/todo/dumb_plaindir_remote___40__e.g._for_NAS_mounts__41__/comment_2_e6ba58c5c31ba23a4575f1189689946f._comment8
-rw-r--r--doc/todo/exclude_files_on_a_given_remote.mdwn18
-rw-r--r--doc/todo/faster_gnupg_cipher.mdwn9
-rw-r--r--doc/todo/faster_gnupg_cipher/comment_1_8f61f7c724a8224e61c015be68f43db7._comment14
-rw-r--r--doc/todo/faster_gnupg_cipher/comment_2_36e1f227a320527653500b445f7c001c._comment12
-rw-r--r--doc/todo/faster_gnupg_cipher/comment_3_bd0c975494333dfe558de048d888ace8._comment17
-rw-r--r--doc/todo/faster_rsync_remotes.mdwn4
-rw-r--r--doc/todo/faster_rsync_remotes/comment_1_0bc3ee0ae563357675eeccf42461e59a._comment8
-rw-r--r--doc/todo/faster_rsync_remotes/comment_2_ccf6f75450c89ca498c8130054f8d32d._comment24
-rw-r--r--doc/todo/faster_rsync_remotes/comment_3_2f6a9d23cb8351fbf0f60ed93752e76e._comment14
-rw-r--r--doc/todo/faster_rsync_remotes/comment_4_3a2f45defebae3dde336ee5f40c26d7e._comment8
-rw-r--r--doc/todo/file_copy_progress_bar.mdwn5
-rw-r--r--doc/todo/free_space_checking_for_local_special_remotes.mdwn4
-rw-r--r--doc/todo/free_space_checking_for_local_special_remotes/comment_1_47c254cec58cbbb3ea84c93ef8282f01._comment8
-rw-r--r--doc/todo/fsck.mdwn11
-rw-r--r--doc/todo/fsck_special_remotes.mdwn13
-rw-r--r--doc/todo/git-annex-shell.mdwn15
-rw-r--r--doc/todo/git-annex_unused_eats_memory.mdwn32
-rw-r--r--doc/todo/git_annex_init_:_include_repo_description_and__47__or_UUID_in_commit_message.mdwn13
-rw-r--r--doc/todo/gitolite_and_gitosis_support.mdwn39
-rw-r--r--doc/todo/gitrm.mdwn5
-rw-r--r--doc/todo/hidden_files.mdwn30
-rw-r--r--doc/todo/http_git_annex_404_retry.mdwn16
-rw-r--r--doc/todo/http_headers.mdwn8
-rw-r--r--doc/todo/immutable_annexed_files.mdwn8
-rw-r--r--doc/todo/importfeed:_allow___36____123__itemdate__125___with_--template.mdwn5
-rw-r--r--doc/todo/importfeed:_allow___36____123__itemdate__125___with_--template/comment_1_62752c760fc12eca0c34d67d58753d00._comment10
-rw-r--r--doc/todo/importfeed:_allow___36____123__itemdate__125___with_--template/comment_2_21672360060f48bc2eacfa535ff4c94d._comment11
-rw-r--r--doc/todo/incremental_fsck.mdwn24
-rw-r--r--doc/todo/incremental_fsck/comment_1_609b21141dd5686b2c0eaef2b8d63229._comment14
-rw-r--r--doc/todo/keep_annexed_files_for_a_while.mdwn8
-rw-r--r--doc/todo/link_file_to_remote_repo_feature.mdwn52
-rw-r--r--doc/todo/makefile:_respect___36__PREFIX.mdwn25
-rw-r--r--doc/todo/mdwn2man:_make_backticks_bold.mdwn22
-rw-r--r--doc/todo/network_remotes.mdwn5
-rw-r--r--doc/todo/nicer_whereis_output.mdwn100
-rw-r--r--doc/todo/object_dir_reorg_v2.mdwn25
-rw-r--r--doc/todo/object_dir_reorg_v2/comment_1_ba03333dc76ff49eccaba375e68cb525._comment8
-rw-r--r--doc/todo/object_dir_reorg_v2/comment_2_81276ac309959dc741bc90101c213ab7._comment8
-rw-r--r--doc/todo/object_dir_reorg_v2/comment_3_79bdf9c51dec9f52372ce95b53233bb2._comment12
-rw-r--r--doc/todo/object_dir_reorg_v2/comment_4_93aada9b1680fed56cc6f0f7c3aca5e5._comment12
-rw-r--r--doc/todo/object_dir_reorg_v2/comment_5_821c382987f105da72a50e0a5ce61fdc._comment12
-rw-r--r--doc/todo/object_dir_reorg_v2/comment_6_8834c3a3f1258c4349d23aff8549bf35._comment10
-rw-r--r--doc/todo/object_dir_reorg_v2/comment_7_42501404c82ca07147e2cce0cff59474._comment12
-rw-r--r--doc/todo/optimise_git-annex_merge.mdwn23
-rw-r--r--doc/todo/optinally_transfer_file_unencryptedly.mdwn6
-rw-r--r--doc/todo/optinally_transfer_file_unencryptedly/comment_1_4be47e7ac85d0f4e7029a96b615545a7._comment8
-rw-r--r--doc/todo/parallel_possibilities.mdwn13
-rw-r--r--doc/todo/parallel_possibilities/comment_1_d8e34fc2bc4e5cf761574608f970d496._comment8
-rw-r--r--doc/todo/parallel_possibilities/comment_2_adb76f06a7997abe4559d3169a3181c3._comment12
-rw-r--r--doc/todo/parallel_possibilities/comment_3_145fb974f45da99b7d4b117a3699cccf._comment12
-rw-r--r--doc/todo/pushpull.mdwn4
-rw-r--r--doc/todo/quvi_0.9_support.mdwn8
-rw-r--r--doc/todo/redundancy_stats_in_status.mdwn23
-rw-r--r--doc/todo/redundancy_stats_in_status/comment_1_9f1c10f8cea4fa60a99cbcc8306dd5de._comment10
-rw-r--r--doc/todo/redundancy_stats_in_status/comment_2_686ced0684d10511caf07953c64cd5b6._comment10
-rw-r--r--doc/todo/resuming_encrypted_uploads.mdwn22
-rw-r--r--doc/todo/resuming_encrypted_uploads/comment_1_1832a6fb78e8ad7c838582f46731ac3b._comment8
-rw-r--r--doc/todo/resuming_encrypted_uploads/comment_2_2ecc8e782f49e90ed1549e9179eb1a1e._comment8
-rw-r--r--doc/todo/rsync.mdwn4
-rw-r--r--doc/todo/smudge.mdwn162
-rw-r--r--doc/todo/smudge/comment_1_4ea616bcdbc9e9a6fae9f2e2795c31c9._comment8
-rw-r--r--doc/todo/smudge/comment_2_e04b32caa0d2b4c577cdaf382a3ff7f6._comment12
-rw-r--r--doc/todo/smudge/comment_3_4e7c25fe24a1e71f58a8354fa64f41c2._comment10
-rw-r--r--doc/todo/special_remote_for_amazon_glacier.mdwn30
-rw-r--r--doc/todo/special_remote_for_amazon_glacier/comment_1_68f129441eefcbfebf7a9db680f52759._comment8
-rw-r--r--doc/todo/special_remote_for_amazon_glacier/comment_2_c5eeaf8ceee414fa0379831ca52e290c._comment7
-rw-r--r--doc/todo/speed_up_fsck.mdwn40
-rw-r--r--doc/todo/stream_feature__63__.mdwn23
-rw-r--r--doc/todo/support-non-utf8-locales.mdwn26
-rw-r--r--doc/todo/support_S3_multipart_uploads.mdwn14
-rw-r--r--doc/todo/support_for_lossy_remotes.mdwn11
-rw-r--r--doc/todo/support_for_lossy_remotes/comment_1_f5cd9f9deab13ab2d2290ad763906dd3._comment8
-rw-r--r--doc/todo/support_for_writing_external_special_remotes.mdwn25
-rw-r--r--doc/todo/support_fsck_in_bare_repos.mdwn17
-rw-r--r--doc/todo/symlink_farming_commit_hook.mdwn14
-rw-r--r--doc/todo/sync_my_local_git-annex_from_a_dump_remote.mdwn6
-rw-r--r--doc/todo/sync_my_local_git-annex_from_a_dump_remote/comment_1_81d63854f89f00855cda5ace0fc8262a._comment14
-rw-r--r--doc/todo/sync_my_local_git-annex_from_a_dump_remote/comment_2_66822b72b1450e79e8edd0c6c21d5aa6._comment14
-rw-r--r--doc/todo/sync_my_local_git-annex_from_a_dump_remote/comment_3_b9f73375e2c732e798495f8ee6970c7c._comment14
-rw-r--r--doc/todo/tahoe_lfs_for_reals.mdwn21
-rw-r--r--doc/todo/tahoe_lfs_for_reals/comment_1_0a4793ce6a867638f6e510e71dd4bb44._comment10
-rw-r--r--doc/todo/tahoe_lfs_for_reals/comment_2_80b9e848edfdc7be21baab7d0cef0e3a._comment13
-rw-r--r--doc/todo/union_mounting.mdwn10
-rw-r--r--doc/todo/union_mounting/comment_1_cb08435812dd7766de26199c73f38e8b._comment8
-rw-r--r--doc/todo/union_mounting/comment_2_240b1736f6bd4fbf87c372d3a46e661b._comment9
-rw-r--r--doc/todo/untracked_remotes.mdwn9
-rw-r--r--doc/todo/use_cp_reflink.mdwn7
-rw-r--r--doc/todo/using_url_backend.mdwn11
-rw-r--r--doc/todo/whishlist:_git_annex_drop_--dry-run.mdwn5
-rw-r--r--doc/todo/whishlist:_git_annex_drop_--dry-run/comment_1_20ecfa8ffa52c238d21b904076ac69a2._comment10
-rw-r--r--doc/todo/whishlist:_git_annex_drop_--dry-run/comment_2_d19bc268c9467d24baa8d8f77a6e5e09._comment8
-rw-r--r--doc/todo/windows_support.mdwn23
-rw-r--r--doc/todo/windows_support/comment_10_394127e34e07ab3dc0e7b94ee6898866._comment8
-rw-r--r--doc/todo/windows_support/comment_1_3cc26ad8101a22e95a8c60cf0c4dedcc._comment10
-rw-r--r--doc/todo/windows_support/comment_2_8acae818ce468967499050bbe3c532ea._comment12
-rw-r--r--doc/todo/windows_support/comment_3_bd0a12f4c9b884ab8a06082842381a01._comment8
-rw-r--r--doc/todo/windows_support/comment_4_ad06b98b2ddac866ffee334e41fee6a8._comment8
-rw-r--r--doc/todo/windows_support/comment_5_444fc7251f57db241b6e80abae41851c._comment10
-rw-r--r--doc/todo/windows_support/comment_6_34f1f60b570c389bb1e741b990064a7e._comment8
-rw-r--r--doc/todo/windows_support/comment_7_a5ca56c487257434650420acfa60e39f._comment8
-rw-r--r--doc/todo/windows_support/comment_8_61214de7d967740d42905f3823ce2f65._comment12
-rw-r--r--doc/todo/windows_support/comment_9_259a0b1a6f4d8d1944173380adc5e7c8._comment8
-rw-r--r--doc/todo/wishlist:_Add_to_Android_version_to_Google_Play.mdwn9
-rw-r--r--doc/todo/wishlist:_Advanced_settings_for_xmpp_and_webdav.mdwn7
-rw-r--r--doc/todo/wishlist:_Advanced_settings_for_xmpp_and_webdav/comment_1_11c7444ab4988c60732af505b52bde3c._comment20
-rw-r--r--doc/todo/wishlist:_An_--all_option_for_dropunused.mdwn4
-rw-r--r--doc/todo/wishlist:_An_--all_option_for_dropunused/comment_1_d8726d108b3b40116b4ec3c9935f2dff._comment8
-rw-r--r--doc/todo/wishlist:_An_--all_option_for_dropunused/comment_2_578248f7686ba2d80d7dc8b17c0cdf52._comment16
-rw-r--r--doc/todo/wishlist:_An_option_like_--git-dir.mdwn3
-rw-r--r--doc/todo/wishlist:_An_option_like_--git-dir/comment_1_5d877d90b8bdf21d4b8649744d229efd._comment8
-rw-r--r--doc/todo/wishlist:_An_option_like_--git-dir/comment_2_462264821cbc48a433330cbf7ec6044d._comment8
-rw-r--r--doc/todo/wishlist:_An_option_like_--git-dir/comment_3_0c3709b07a0a1091ceeee73b69e0f7ac._comment8
-rw-r--r--doc/todo/wishlist:_Freeing_X_space_on_remote_Y.mdwn1
-rw-r--r--doc/todo/wishlist:_GnuPG_options.mdwn16
-rw-r--r--doc/todo/wishlist:_GnuPG_options/comment_1_6662e8a71ce20acc62147ef41ecffa50._comment12
-rw-r--r--doc/todo/wishlist:_Have_a_preview_of_download_or_upload_size.mdwn10
-rw-r--r--doc/todo/wishlist:_Have_a_preview_of_download_or_upload_size/comment_1_019a2457e07377510feaa089a93bd76c._comment8
-rw-r--r--doc/todo/wishlist:_Have_a_preview_of_download_or_upload_size/comment_3_29a154699339bf040af0ee8aa24034f1._comment15
-rw-r--r--doc/todo/wishlist:_Have_a_preview_of_download_or_upload_size/comment_3_8f7e1c4a5c714cbd719ee170354d79fa._comment12
-rw-r--r--doc/todo/wishlist:_Have_a_preview_of_download_or_upload_size/comment_4_c7335f757e5546aa841cab38fffe7605._comment19
-rw-r--r--doc/todo/wishlist:_Have_a_preview_of_download_or_upload_size/comment_5_d2a845354f23d07880612740cf99ddd4._comment8
-rw-r--r--doc/todo/wishlist:_Option_to_specify_max_transfer_rate.mdwn3
-rw-r--r--doc/todo/wishlist:_Option_to_specify_max_transfer_rate/comment_1_4fd870e14b5b70c8a6ade41406294387._comment10
-rw-r--r--doc/todo/wishlist:_Option_to_specify_max_transfer_rate/comment_2_dd854f297ad6a94b54be9f3edfd0f766._comment8
-rw-r--r--doc/todo/wishlist:_Option_to_specify_max_transfer_rate/comment_3_a8b7e90a473d5937807cc7eb456efe33._comment10
-rw-r--r--doc/todo/wishlist:_Prevent_repeated_password_prompts_for_one_command.mdwn45
-rw-r--r--doc/todo/wishlist:_Prevent_repeated_password_prompts_for_one_command/comment_1_3f9c0d08932c2ede61c802a91261a1f7._comment14
-rw-r--r--doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates.mdwn28
-rw-r--r--doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_10_d78d79fb2f3713aa69f45d2691cf8dfe._comment68
-rw-r--r--doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_11_4316d9d74312112dc4c823077af7febe._comment8
-rw-r--r--doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_12_ed6d07f16a11c6eee7e3d5005e8e6fa3._comment8
-rw-r--r--doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_1_fd213310ee548d8726791d2b02237fde._comment29
-rw-r--r--doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_2_4394bde1c6fd44acae649baffe802775._comment18
-rw-r--r--doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_3_076cb22057583957d5179d8ba9004605._comment18
-rw-r--r--doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_4_f120d1e83c1a447f2ecce302fc69cf74._comment35
-rw-r--r--doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_5_5c30294b3c59fdebb1eef0ae5da4cd4f._comment10
-rw-r--r--doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_6_f24541ada1c86d755acba7e9fa7cff24._comment16
-rw-r--r--doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_7_c39f1bb7c61a89b238c61bee1c049767._comment54
-rw-r--r--doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_8_221ed2e53420278072a6d879c6f251d1._comment8
-rw-r--r--doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_9_aecfa896c97b9448f235bce18a40621d._comment14
-rw-r--r--doc/todo/wishlist:_Restore_s3_files_moved_to_Glacier.mdwn7
-rw-r--r--doc/todo/wishlist:_Tell_git_annex___40__assistant__41___which_files___40__not__41___to_annex_via_.gitattributes.mdwn9
-rw-r--r--doc/todo/wishlist:___34__git_annex_add__34___multiple_processes.mdwn10
-rw-r--r--doc/todo/wishlist:___34__git_annex_add__34___multiple_processes/comment_1_85b14478411a33e6186a64bd41f0910d._comment10
-rw-r--r--doc/todo/wishlist:___34__git_annex_add__34___multiple_processes/comment_2_82e857f463cfdf73c70f6c0a9f9a31d6._comment8
-rw-r--r--doc/todo/wishlist:___34__git_annex_add__34___multiple_processes/comment_3_8af85eba7472d9025c6fae4f03e3ad75._comment8
-rw-r--r--doc/todo/wishlist:___34__quiet__34___annex_get_for_centralized_use_case.mdwn14
-rw-r--r--doc/todo/wishlist:___34__quiet__34___annex_get_for_centralized_use_case/comment_1_5c8812973cf91b046e7fc44d7e86c78e._comment14
-rw-r--r--doc/todo/wishlist:___34__quiet__34___annex_get_for_centralized_use_case/comment_2_f36b6a5b128423211aac91a252ecf85f._comment18
-rw-r--r--doc/todo/wishlist:___34__quiet__34___annex_get_for_centralized_use_case/comment_3_ad1569b2405acacd2e37f42b82f24c88._comment10
-rw-r--r--doc/todo/wishlist:___34__quiet__34___annex_get_for_centralized_use_case/comment_4_8aba90150fe178ce9712ad951628f3d6._comment8
-rw-r--r--doc/todo/wishlist:___34__quiet__34___annex_get_for_centralized_use_case/comment_5_6f42d240e0021f4dfa37146bea3f5d7e._comment16
-rw-r--r--doc/todo/wishlist:___34__quiet__34___annex_get_for_centralized_use_case/comment_6_5fda455febf728b079f26fe42bf7bcab._comment16
-rw-r--r--doc/todo/wishlist:___34__quiet__34___annex_get_for_centralized_use_case/comment_7_f1052ab997f1a2cccbabfd1533fc0a59._comment8
-rw-r--r--doc/todo/wishlist:___34__quiet__34___annex_get_for_centralized_use_case/comment_8_07804647b6023436878756bd97a23f32._comment8
-rw-r--r--doc/todo/wishlist:___39__get__39___queue_and_schedule..mdwn30
-rw-r--r--doc/todo/wishlist:___39__whereis__39___support_in_the_webapp.mdwn4
-rw-r--r--doc/todo/wishlist:___96__git_annex_drop_--relaxed__96__.mdwn5
-rw-r--r--doc/todo/wishlist:___96__git_annex_drop_--relaxed__96__/comment_1_c83a6cddd0ce222205a149cfa41ca395._comment10
-rw-r--r--doc/todo/wishlist:___96__git_annex_drop_--relaxed__96__/comment_2_353fbc2bcc40cb8c9af42907a34c6e5a._comment11
-rw-r--r--doc/todo/wishlist:___96__git_annex_fsck_--checksums__96___--_verify_checksums_but_disregard_annex.numcopies.mdwn12
-rw-r--r--doc/todo/wishlist:___96__git_annex_fsck_--checksums__96___--_verify_checksums_but_disregard_annex.numcopies/comment_1_6bcf067e4860bdfeb1d7b9fd1702a43a._comment8
-rw-r--r--doc/todo/wishlist:___96__git_annex_import__96___--_An_easy_way_to_get_data_into_an_annex.mdwn13
-rw-r--r--doc/todo/wishlist:___96__git_annex_import__96___--_An_easy_way_to_get_data_into_an_annex/comment_1_b9fd1bfaf9a3d238fdb7bc9c2d75fe5f._comment22
-rw-r--r--doc/todo/wishlist:___96__git_annex_import__96___--_An_easy_way_to_get_data_into_an_annex/comment_2_56f6972413c6f0d9f414245b6f4d27b9._comment62
-rw-r--r--doc/todo/wishlist:___96__git_annex_import__96___--_An_easy_way_to_get_data_into_an_annex/comment_3_2c094bef802a2182de4fcd0def1ad29b._comment12
-rw-r--r--doc/todo/wishlist:___96__git_annex_import__96___--_An_easy_way_to_get_data_into_an_annex/comment_4_14915c43001f7f72c9fe5119a104ef5c._comment10
-rw-r--r--doc/todo/wishlist:___96__git_annex_sync_-m__96__.mdwn10
-rw-r--r--doc/todo/wishlist:_a_spec.remote_for_network_directories_that_would_mount_them_whenever_needed___40__e.g.__44___with_WebDAV__41__.mdwn25
-rw-r--r--doc/todo/wishlist:_a_spec.remote_for_network_directories_that_would_mount_them_whenever_needed___40__e.g.__44___with_WebDAV__41__/comment_1_f46b0c9b49607e9f4f7a27f5a331ce83._comment8
-rw-r--r--doc/todo/wishlist:_a_spec.remote_for_network_directories_that_would_mount_them_whenever_needed___40__e.g.__44___with_WebDAV__41__/comment_2_1b34e1dd72011c65e881dec2543a0373._comment12
-rw-r--r--doc/todo/wishlist:_add_systemd_services_file_samples_for_assistant_and_webapp.mdwn6
-rw-r--r--doc/todo/wishlist:_add_systemd_services_file_samples_for_assistant_and_webapp/comment_1_b89e90f9a70748c95aaf81740a40b76e._comment8
-rw-r--r--doc/todo/wishlist:_add_systemd_services_file_samples_for_assistant_and_webapp/comment_2_d64361380cb18b98ddb43ada1c9f540a._comment8
-rw-r--r--doc/todo/wishlist:_addurl_https:.mdwn11
-rw-r--r--doc/todo/wishlist:_addurl_https:/comment_1_4e8f5e1fc52c3000eb2a1dad0624906e._comment14
-rw-r--r--doc/todo/wishlist:_allow_configuration_of_downloader_for_addurl.mdwn3
-rw-r--r--doc/todo/wishlist:_allow_the_same_remote_to_be_accissable_via_different_methods.mdwn5
-rw-r--r--doc/todo/wishlist:_allow_the_same_remote_to_be_accissable_via_different_methods/comment_1_abb6263f3807160222bba1122475c89c._comment8
-rw-r--r--doc/todo/wishlist:_allow_users_to_provide_UUID_when_running___96__git_annex_init__96__.mdwn5
-rw-r--r--doc/todo/wishlist:_an___34__assistant__34___for_web-browsing_--_tracking_the_sources_of_the_downloads.mdwn28
-rw-r--r--doc/todo/wishlist:_an___34__assistant__34___for_web-browsing_--_tracking_the_sources_of_the_downloads/comment_1_36ae3c75053d5ec278b5e6eb2084d57a._comment8
-rw-r--r--doc/todo/wishlist:_an___34__assistant__34___for_web-browsing_--_tracking_the_sources_of_the_downloads/comment_3_be8eb800523db8cf7a2c68a28fbf5ea5._comment8
-rw-r--r--doc/todo/wishlist:_an___34__assistant__34___for_web-browsing_--_tracking_the_sources_of_the_downloads/comment_3_d9f725de41a8572c85e4c6d9b4bcc927._comment8
-rw-r--r--doc/todo/wishlist:_an___34__assistant__34___for_web-browsing_--_tracking_the_sources_of_the_downloads/comment_4_f52492e4cc6f965515800bd1c0e05c90._comment10
-rw-r--r--doc/todo/wishlist:_an___34__assistant__34___for_web-browsing_--_tracking_the_sources_of_the_downloads/comment_5_5b36656fc5fa124e763f06711d9da32b._comment10
-rw-r--r--doc/todo/wishlist:_an___34__assistant__34___for_web-browsing_--_tracking_the_sources_of_the_downloads/comment_6_285215a4466806baf85b8606f680494a._comment12
-rw-r--r--doc/todo/wishlist:_an___34__assistant__34___for_web-browsing_--_tracking_the_sources_of_the_downloads/comment_7_15bf62e46db4b84ed3156f550f03de42._comment12
-rw-r--r--doc/todo/wishlist:_annex.largefiles_configuration_in_webapp_and_sync.mdwn1
-rw-r--r--doc/todo/wishlist:_annex.largefiles_configuration_in_webapp_and_sync/comment_1_db632de391ce9fce42af51a770ed3aeb._comment10
-rw-r--r--doc/todo/wishlist:_annex.largefiles_configuration_in_webapp_and_sync/comment_2_4a0931d9884054d764fde315d4fe4851._comment14
-rw-r--r--doc/todo/wishlist:_annex.largefiles_support_for_mimetypes.mdwn1
-rw-r--r--doc/todo/wishlist:_annex.largefiles_support_for_mimetypes/comment_1_304431bb62b5b8a64edc37a11bbaff59._comment8
-rw-r--r--doc/todo/wishlist:_archive_from_remote_with_the_least_free_space.mdwn1
-rw-r--r--doc/todo/wishlist:_archive_from_remote_with_the_least_free_space/comment_1_6813fdc7ecc98765a5d35d34163a1712._comment8
-rw-r--r--doc/todo/wishlist:_archive_from_remote_with_the_least_free_space/comment_2_21a249cedca1ceb80d10784004735524._comment8
-rw-r--r--doc/todo/wishlist:_assistant_autostart_port_and_secret_configuration.mdwn1
-rw-r--r--doc/todo/wishlist:_assistant_autostart_port_and_secret_configuration/comment_1_be53b8456eed7eadad5d4b8465c8a42b._comment10
-rw-r--r--doc/todo/wishlist:_command_options_changes.mdwn17
-rw-r--r--doc/todo/wishlist:_command_options_changes/comment_1_bfba72a696789bf21b2435dea15f967a._comment17
-rw-r--r--doc/todo/wishlist:_command_options_changes/comment_2_f6a637c78c989382e3c22d41b7fb4cc2._comment19
-rw-r--r--doc/todo/wishlist:_command_options_changes/comment_3_bf1114533d2895804e531e76eb6b8095._comment8
-rw-r--r--doc/todo/wishlist:_define_remotes_that_must_have_all_files.mdwn18
-rw-r--r--doc/todo/wishlist:_define_remotes_that_must_have_all_files/comment_1_cceccc1a1730ac688d712b81a44e31c3._comment10
-rw-r--r--doc/todo/wishlist:_define_remotes_that_must_have_all_files/comment_2_eec848fcf3979c03cbff2b7407c75a7a._comment16
-rw-r--r--doc/todo/wishlist:_detection_of_merge_conflicts.mdwn13
-rw-r--r--doc/todo/wishlist:_disable_automatic_commits.mdwn36
-rw-r--r--doc/todo/wishlist:_display_name_of_object_when_addWatcher_gets_a_permission_denied.mdwn6
-rw-r--r--doc/todo/wishlist:_display_name_of_object_when_addWatcher_gets_a_permission_denied/comment_1_d2665e7347689b520d37561cfddf0aa8._comment8
-rw-r--r--doc/todo/wishlist:_display_name_of_object_when_addWatcher_gets_a_permission_denied/comment_2_db153571a32fb072453ed583e3e9ccf4._comment8
-rw-r--r--doc/todo/wishlist:_display_status_of_remotes_in_the_webapp.mdwn1
-rw-r--r--doc/todo/wishlist:_do_round_robin_downloading_of_data.mdwn5
-rw-r--r--doc/todo/wishlist:_do_round_robin_downloading_of_data/comment_1_460335b0e59ad03871c524f1fe812357._comment8
-rw-r--r--doc/todo/wishlist:_dropping_git-annex_history.mdwn28
-rw-r--r--doc/todo/wishlist:_dropping_git-annex_history/comment_1_a4bee2e26b22a9bdaadc05b7227769ef._comment10
-rw-r--r--doc/todo/wishlist:_dropping_git-annex_history/comment_2_f6d750bfe0c9d8a2aa6bc218ca5c49cc._comment14
-rw-r--r--doc/todo/wishlist:_encrypted_git_remote_on_hosting_site_from_webapp.mdwn1
-rw-r--r--doc/todo/wishlist:_generic_annex.cost-command.mdwn17
-rw-r--r--doc/todo/wishlist:_git-annex_replicate.mdwn12
-rw-r--r--doc/todo/wishlist:_git-annex_replicate/comment_1_9926132ec6052760cdf28518a24e2358._comment10
-rw-r--r--doc/todo/wishlist:_git-annex_replicate/comment_2_c43932f4194aba8fb2470b18e0817599._comment12
-rw-r--r--doc/todo/wishlist:_git-annex_replicate/comment_3_c13f4f9c3d5884fc6255fd04feadc2b1._comment10
-rw-r--r--doc/todo/wishlist:_git-annex_replicate/comment_4_63f24abf086d644dced8b01e1a9948c9._comment8
-rw-r--r--doc/todo/wishlist:_git_annex_diff.mdwn9
-rw-r--r--doc/todo/wishlist:_git_annex_put_--_same_as_get__44___but_for_defaults.mdwn17
-rw-r--r--doc/todo/wishlist:_git_annex_put_--_same_as_get__44___but_for_defaults/comment_1_d5413c8acce308505e4e2bec82fb1261._comment10
-rw-r--r--doc/todo/wishlist:_git_annex_put_--_same_as_get__44___but_for_defaults/comment_2_0aa227c85d34dfff4e94febca44abea8._comment12
-rw-r--r--doc/todo/wishlist:_git_annex_put_--_same_as_get__44___but_for_defaults/comment_3_2082f4d708a584a1403cc1d4d005fb56._comment10
-rw-r--r--doc/todo/wishlist:_git_annex_status.mdwn21
-rw-r--r--doc/todo/wishlist:_git_annex_status/comment_1_994bfd12c5d82e08040d6116915c5090._comment8
-rw-r--r--doc/todo/wishlist:_git_annex_status/comment_2_c2b0ce025805b774dc77ce264a222824._comment13
-rw-r--r--doc/todo/wishlist:_git_annex_status/comment_3_d1fd70c67243971c96d59e1ffb7ef6e7._comment23
-rw-r--r--doc/todo/wishlist:_git_annex_status/comment_4_9aeeb83d202dc8fb33ff364b0705ad94._comment8
-rw-r--r--doc/todo/wishlist:_git_backend_for_git-annex.mdwn9
-rw-r--r--doc/todo/wishlist:_git_backend_for_git-annex/comment_1_04319051fedc583e6c326bb21fcce5a5._comment10
-rw-r--r--doc/todo/wishlist:_git_backend_for_git-annex/comment_2_7f529f19a47e10b571f65ab382e97fd5._comment14
-rw-r--r--doc/todo/wishlist:_git_backend_for_git-annex/comment_3_a077bbad3e4b07cce019eb55a45330e7._comment10
-rw-r--r--doc/todo/wishlist:_git_backend_for_git-annex/comment_4_ecca429e12d734b509c671166a676c9d._comment8
-rw-r--r--doc/todo/wishlist:_git_backend_for_git-annex/comment_5_3459f0b41d818c23c8fb33edb89df634._comment8
-rw-r--r--doc/todo/wishlist:_history_of_operations.mdwn8
-rw-r--r--doc/todo/wishlist:_history_of_operations/comment_1_f9a77ce83c6f39b6272d5c577ffbb9f9._comment8
-rw-r--r--doc/todo/wishlist:_incremental_unannex___40__currently_requires_twice_the_size_of_repo_to_complete__41__.mdwn10
-rw-r--r--doc/todo/wishlist:_incremental_unannex___40__currently_requires_twice_the_size_of_repo_to_complete__41__/comment_1_067b29fc47d26b9da0766f9810684ae8._comment10
-rw-r--r--doc/todo/wishlist:_make_git_annex_reinject_work_in_direct_mode.mdwn21
-rw-r--r--doc/todo/wishlist:_make_partial_files_available_during_transfer.mdwn18
-rw-r--r--doc/todo/wishlist:_make_partial_files_available_during_transfer/comment_3_1304a721da6f5133fdfa1dac507f1ecb._comment10
-rw-r--r--doc/todo/wishlist:_more_descriptive_commit_messages_in_git-annex_branch.mdwn39
-rw-r--r--doc/todo/wishlist:_more_info_in_the_standard_commit_message_of___96__sync__96__.mdwn3
-rw-r--r--doc/todo/wishlist:_move_pending_transfers_for_a_host_to_the_end_of_the_queue_when_one_fails.mdwn7
-rw-r--r--doc/todo/wishlist:_move_pending_transfers_for_a_host_to_the_end_of_the_queue_when_one_fails/comment_1_82ee9de610a0ac55cd1c27c211079e5b._comment10
-rw-r--r--doc/todo/wishlist:_move_pending_transfers_for_a_host_to_the_end_of_the_queue_when_one_fails/comment_2_bea55156bd32cf9e6dd9b946ba1bb8c1._comment10
-rw-r--r--doc/todo/wishlist:_option_to_disable_url_checking_with_addurl.mdwn9
-rw-r--r--doc/todo/wishlist:_option_to_disable_url_checking_with_addurl/comment_1_868a380faa1e55faa3c2d314e3258e86._comment10
-rw-r--r--doc/todo/wishlist:_option_to_print_more_info_with___39__unused__39__.mdwn37
-rw-r--r--doc/todo/wishlist:_perform_fsck_remotely.mdwn39
-rw-r--r--doc/todo/wishlist:_perform_fsck_remotely/comment_1_db92311dcdb1ef0ab0413f83e191c70c._comment15
-rw-r--r--doc/todo/wishlist:_perform_fsck_remotely/comment_2_2f0dbaf143d94290bfbebb6869eb7241._comment12
-rw-r--r--doc/todo/wishlist:_print_locations_for_files_in_rsync_remote.mdwn6
-rw-r--r--doc/todo/wishlist:_push_to_cia.vc_from_the_website__39__s_repo__44___not_your_personal_one.mdwn3
-rw-r--r--doc/todo/wishlist:_push_to_cia.vc_from_the_website__39__s_repo__44___not_your_personal_one/comment_1_3480b0ec629ef29a151408d869186bf8._comment8
-rw-r--r--doc/todo/wishlist:_query_things_like_description__44___trust_level.mdwn4
-rw-r--r--doc/todo/wishlist:_query_things_like_description__44___trust_level/comment_1_14311384788312b96e550749ab7de9ea._comment10
-rw-r--r--doc/todo/wishlist:_query_things_like_description__44___trust_level/comment_2_342d1ac07573c7ef4e27f003a692e261._comment32
-rw-r--r--doc/todo/wishlist:_recursive_directory_remote_setup__47__addurl.mdwn7
-rw-r--r--doc/todo/wishlist:_recursive_directory_remote_setup__47__addurl/comment_1_b79976afc2242791523e63831f30af71._comment12
-rw-r--r--doc/todo/wishlist:_recursive_directory_remote_setup__47__addurl/comment_2_1741d2392006a9af9cfd1f3b847600b9._comment9
-rw-r--r--doc/todo/wishlist:_simple_url_for_webapp.mdwn36
-rw-r--r--doc/todo/wishlist:_simple_url_for_webapp/comment_1_552aad504fbb68d1f85abfde8c535e69._comment10
-rw-r--r--doc/todo/wishlist:_simpler_gpg_usage.mdwn12
-rw-r--r--doc/todo/wishlist:_simpler_gpg_usage/comment_1_6923fa6ebc0bbe7d93edb1d01d7c46c5._comment19
-rw-r--r--doc/todo/wishlist:_simpler_gpg_usage/comment_2_6fc874b6c391df242bd2592c4a65eae8._comment10
-rw-r--r--doc/todo/wishlist:_simpler_gpg_usage/comment_3_012f340c8c572fe598fc860c1046dabd._comment8
-rw-r--r--doc/todo/wishlist:_simpler_gpg_usage/comment_4_e0c2a13217b795964f3b630c001661ef._comment10
-rw-r--r--doc/todo/wishlist:_simpler_gpg_usage/comment_5_9668b58eb71901e1db8da7db38e068ca._comment8
-rw-r--r--doc/todo/wishlist:_spec.remotes_for_other_peer_network_data_stores___40__gnunet__44___freenet__41__.mdwn26
-rw-r--r--doc/todo/wishlist:_spec.remotes_for_other_peer_network_data_stores___40__gnunet__44___freenet__41__/comment_1_e2c2047e7401cb95a82ffb686a732859._comment8
-rw-r--r--doc/todo/wishlist:_spec.remotes_for_other_peer_network_data_stores___40__gnunet__44___freenet__41__/comment_2_472b576afdb169b233edd01adcb2123d._comment8
-rw-r--r--doc/todo/wishlist:_special-case_handling_of_Youtube_URLs_in_Web_special_remote.mdwn22
-rw-r--r--doc/todo/wishlist:_special-case_handling_of_Youtube_URLs_in_Web_special_remote/comment_1_1a383c30df4fb1767f13d8c670b0c0b5._comment10
-rw-r--r--doc/todo/wishlist:_special-case_handling_of_Youtube_URLs_in_Web_special_remote/comment_2_81f7f893ac36c145b31f02db6a682a17._comment20
-rw-r--r--doc/todo/wishlist:_special-case_handling_of_Youtube_URLs_in_Web_special_remote/comment_3_a7e3cd68c5e5f05139151a58f358df95._comment13
-rw-r--r--doc/todo/wishlist:_special-case_handling_of_Youtube_URLs_in_Web_special_remote/comment_4_a57947ed257b28bbe995a68bfeb5eeaa._comment8
-rw-r--r--doc/todo/wishlist:_special-case_handling_of_Youtube_URLs_in_Web_special_remote/comment_5_a0612ae05dbda7f7935be648b42b30fc._comment8
-rw-r--r--doc/todo/wishlist:_special_remote_Ubuntu_One.mdwn1
-rw-r--r--doc/todo/wishlist:_special_remote_for_sftp_or_rsync.mdwn28
-rw-r--r--doc/todo/wishlist:_special_remote_for_sftp_or_rsync/comment_1_6f07d9cc92cf8b4927b3a7d1820c9140._comment10
-rw-r--r--doc/todo/wishlist:_special_remote_for_sftp_or_rsync/comment_2_84e4414c88ae91c048564a2cdc2d3250._comment8
-rw-r--r--doc/todo/wishlist:_special_remote_for_sftp_or_rsync/comment_3_79de7ac44e3c0f0f5691a56d3fb88897._comment8
-rw-r--r--doc/todo/wishlist:_special_remote_mega.co.nz.mdwn3
-rw-r--r--doc/todo/wishlist:_special_remote_mega.co.nz/comment_2_6ca08ef808d4336fc42d0f279d6627b5._comment44
-rw-r--r--doc/todo/wishlist:_support_copy_--from__61__x_--to__61__y.mdwn29
-rw-r--r--doc/todo/wishlist:_support_copy_--from__61__x_--to__61__y/comment_1_cf8e0f16b723516374c95a93e4da42fc._comment12
-rw-r--r--doc/todo/wishlist:_support_copy_--from__61__x_--to__61__y/comment_2_d35359c9dd4dd4365d9a7caf695ff833._comment16
-rw-r--r--doc/todo/wishlist:_support_drop__44___find_on_special_remotes.mdwn18
-rw-r--r--doc/todo/wishlist:_support_drop__44___find_on_special_remotes/comment_1_f11ed642a83d965076778a162f701e84._comment8
-rw-r--r--doc/todo/wishlist:_support_for_more_ssh_urls_.mdwn22
-rw-r--r--doc/todo/wishlist:_swift_backend.mdwn5
-rw-r--r--doc/todo/wishlist:_swift_backend/comment_1_e6efbb35f61ee521b473a92674036788._comment8
-rw-r--r--doc/todo/wishlist:_swift_backend/comment_2_5d8c83b0485112e98367b7abaab3f4e3._comment8
-rw-r--r--doc/todo/wishlist:_swift_backend/comment_3_bf8625b909c3a7321cae40e6f145e874._comment8
-rw-r--r--doc/todo/wishlist:_swift_backend/comment_4_4d97d12ddd99834788e94648c8eebef9._comment10
-rw-r--r--doc/todo/wishlist:_traffic_accounting_for_git-annex.mdwn3
-rw-r--r--doc/todo/wishlist:_unify_directory_scheme_for_the_store.mdwn20
-rw-r--r--doc/todo/wishlist:_unify_directory_scheme_for_the_store/comment_1_44da58beaaab359ecaba7fb905ca4ae1._comment10
-rw-r--r--doc/todo/wishlist:_unify_directory_scheme_for_the_store/comment_2_bc698c501ecdb56df57171f4f3bb831a._comment16
-rw-r--r--doc/todo/wishlist:_unify_directory_scheme_for_the_store/comment_3_e555d0dbbaa05528806905c6a940724b._comment8
-rw-r--r--doc/todo/wishlist:_use_hardlinks_for_local_clones.mdwn9
-rw-r--r--doc/todo/wishlist:_use_hardlinks_for_local_clones/comment_1_85064fafe472a5bd395d60ce8f7acb56._comment12
-rw-r--r--doc/todo/wishlist:_vicfg_possible_repo_group_names.mdwn16
-rw-r--r--doc/todo/wishlist:alias_system.mdwn1
-rw-r--r--doc/todo/wishlist_degraded_files.mdwn5
-rw-r--r--doc/transferring_data.mdwn19
-rw-r--r--doc/trust.mdwn59
-rw-r--r--doc/upgrades.mdwn106
-rw-r--r--doc/upgrades/SHA_size.mdwn20
-rw-r--r--doc/upgrades/SHA_size/comment_1_20f9b7b75786075de666b2146dc13a60._comment12
-rw-r--r--doc/upgrades/gcrypt.mdwn25
-rw-r--r--doc/upgrades/gcrypt/comment_1_606c1527735996ae671f78948e4ad84b._comment8
-rw-r--r--doc/use_case/Alice.mdwn24
-rw-r--r--doc/use_case/Bob.mdwn25
-rw-r--r--doc/users.mdwn9
-rw-r--r--doc/users/anarcat.mdwn41
-rw-r--r--doc/users/chrysn.mdwn11
-rw-r--r--doc/users/clacke.mdwn3
-rw-r--r--doc/users/fmarier.mdwn6
-rw-r--r--doc/users/gebi.mdwn1
-rw-r--r--doc/users/joey.mdwn2
-rw-r--r--doc/users/tobiastheviking.mdwn20
-rw-r--r--doc/videos.mdwn8
-rw-r--r--doc/videos/FOSDEM2012.mdwn7
-rw-r--r--doc/videos/LCA2013.mdwn8
-rw-r--r--doc/videos/git-annex_assistant_archiving.mdwn5
-rw-r--r--doc/videos/git-annex_assistant_introduction.mdwn5
-rw-r--r--doc/videos/git-annex_assistant_introduction/comment_1_f42ad4183c2c28319d3705a82fceb82f._comment15
-rw-r--r--doc/videos/git-annex_assistant_introduction/comment_2_b62f4eeeac1138570f7cb8c98d41c2cb._comment12
-rw-r--r--doc/videos/git-annex_assistant_remote_sharing.mdwn6
-rw-r--r--doc/videos/git-annex_assistant_sync_demo.mdwn8
-rw-r--r--doc/videos/git-annex_watch_demo.mdwn7
-rw-r--r--doc/videos/git-annex_weppapp_demo.mdwn8
-rw-r--r--doc/walkthrough.mdwn25
-rw-r--r--doc/walkthrough/adding_a_remote.mdwn19
-rw-r--r--doc/walkthrough/adding_a_remote/comment_1_0a59355bd33a796aec97173607e6adc9._comment8
-rw-r--r--doc/walkthrough/adding_a_remote/comment_2_f8cd79ef1593a8181a7f1086a87713e8._comment9
-rw-r--r--doc/walkthrough/adding_a_remote/comment_3_60691af4400521b5a8c8d75efe3b44cb._comment9
-rw-r--r--doc/walkthrough/adding_a_remote/comment_4_6f7cf5c330272c96b3abeb6612075c9d._comment10
-rw-r--r--doc/walkthrough/adding_files.mdwn11
-rw-r--r--doc/walkthrough/automatically_managing_content.mdwn45
-rw-r--r--doc/walkthrough/backups.mdwn25
-rw-r--r--doc/walkthrough/creating_a_repository.mdwn6
-rw-r--r--doc/walkthrough/fsck:_verifying_your_data.mdwn16
-rw-r--r--doc/walkthrough/fsck:_when_things_go_wrong.mdwn13
-rw-r--r--doc/walkthrough/getting_file_content.mdwn12
-rw-r--r--doc/walkthrough/modifying_annexed_files.mdwn44
-rw-r--r--doc/walkthrough/modifying_annexed_files/comment_1_624b4a0b521b553d68ab6049f7dbaf8c._comment14
-rw-r--r--doc/walkthrough/modifying_annexed_files/comment_2_b000622304535d32b69db17d51156b21._comment10
-rw-r--r--doc/walkthrough/more.mdwn3
-rw-r--r--doc/walkthrough/moving_file_content_between_repositories.mdwn13
-rw-r--r--doc/walkthrough/moving_file_content_between_repositories/comment_1_4c30ade91fc7113a95960aa3bd1d5427._comment19
-rw-r--r--doc/walkthrough/moving_file_content_between_repositories/comment_2_7d90e1e150e7524ba31687108fcc38d6._comment10
-rw-r--r--doc/walkthrough/moving_file_content_between_repositories/comment_3_558d80384434207b9cfc033763863de3._comment12
-rw-r--r--doc/walkthrough/moving_file_content_between_repositories/comment_4_a2f343eceed9e9fba1670f21e0fc6af4._comment8
-rw-r--r--doc/walkthrough/removing_files.mdwn17
-rw-r--r--doc/walkthrough/removing_files/comment_1_cb65e7c510b75be1c51f655b058667c6._comment8
-rw-r--r--doc/walkthrough/removing_files/comment_2_64709ea4558915edd5c8ca4486965b07._comment8
-rw-r--r--doc/walkthrough/removing_files:_When_things_go_wrong.mdwn24
-rw-r--r--doc/walkthrough/renaming_files.mdwn13
-rw-r--r--doc/walkthrough/syncing.mdwn27
-rw-r--r--doc/walkthrough/transferring_files:_When_things_go_wrong.mdwn17
-rw-r--r--doc/walkthrough/unused_data.mdwn35
-rw-r--r--doc/walkthrough/unused_data/comment_1_684b7b652d3a8ec04f32129c5528f1ab._comment22
-rw-r--r--doc/walkthrough/using_bup.mdwn37
-rw-r--r--doc/walkthrough/using_ssh_remotes.mdwn33
-rw-r--r--doc/walkthrough/using_ssh_remotes/comment_10_98e97c4d7fbbcd449eddf683967a71d6._comment8
-rw-r--r--doc/walkthrough/using_ssh_remotes/comment_11_f2775a151ed50caba27057bd9c38bae2._comment13
-rw-r--r--doc/walkthrough/using_ssh_remotes/comment_12_a8bc6110128431ca2a8624ddc75ea364._comment10
-rw-r--r--doc/walkthrough/using_ssh_remotes/comment_2_365db5820d96d5daa62c19fd76fcdf1e._comment13
-rw-r--r--doc/walkthrough/using_ssh_remotes/comment_2_451fd0c6a25ee61ef137e8e5be0c286b._comment16
-rw-r--r--doc/walkthrough/using_ssh_remotes/comment_3_b2f15a46620385da26d5fe8f11ebfc1a._comment15
-rw-r--r--doc/walkthrough/using_ssh_remotes/comment_4_433ccc87fbb0a13e32d59d77f0b4e56c._comment8
-rw-r--r--doc/walkthrough/using_ssh_remotes/comment_5_a9805c7965da0b88a1c9f7f207c450a1._comment18
-rw-r--r--doc/walkthrough/using_ssh_remotes/comment_6_9d5c12c056892b706cf100ea01866685._comment12
-rw-r--r--doc/walkthrough/using_ssh_remotes/comment_7_725e7dbb2d0a74a035127cb01ee0442c._comment16
-rw-r--r--doc/walkthrough/using_ssh_remotes/comment_8_8448e55026d2c2b50d8da41707686bea._comment16
-rw-r--r--doc/walkthrough/using_ssh_remotes/comment_9_61833299a9878f23ac57598fa6da8839._comment23
-rw-r--r--doc/walkthrough/using_tags_and_branches.mdwn14
-rwxr-xr-xghci4
-rw-r--r--git-annex.cabal201
-rw-r--r--git-annex.hs34
-rw-r--r--git-union-merge.hs48
-rw-r--r--standalone/android/Makefile167
-rw-r--r--standalone/android/abiversion1
-rwxr-xr-xstandalone/android/buildchroot27
-rwxr-xr-xstandalone/android/buildchroot-inchroot25
-rwxr-xr-xstandalone/android/buildchroot-inchroot-asuser38
-rw-r--r--standalone/android/busybox_config997
-rwxr-xr-xstandalone/android/clean-haskell-packages6
-rw-r--r--standalone/android/dropbear.patch55
-rw-r--r--standalone/android/evilsplicer-headers.hs32
-rw-r--r--standalone/android/haskell-patches/DAV_build-without-TH.patch377
-rw-r--r--standalone/android/haskell-patches/HTTP_4000.2.8-0001-build-with-base-4.8.patch25
-rw-r--r--standalone/android/haskell-patches/MissingH_1.2.0.0_0001-fix-build-not-Android-specific.patch34
-rw-r--r--standalone/android/haskell-patches/MonadCatchIO-transformers_hack-to-get-to-build-with-new-ghc.patch56
-rw-r--r--standalone/android/haskell-patches/SafeSemaphore_fix-build-with-new-base.patch36
-rw-r--r--standalone/android/haskell-patches/async_fix-build-with-new-ghc.patch25
-rw-r--r--standalone/android/haskell-patches/bloomfilter_fix-build-with-newer-base.patch26
-rw-r--r--standalone/android/haskell-patches/comonad_cross-build.patch25
-rw-r--r--standalone/android/haskell-patches/crypto-numbers_build-fix.patch235
-rw-r--r--standalone/android/haskell-patches/distributive_0.3-0001-fixes-for-cross-build.patch25
-rw-r--r--standalone/android/haskell-patches/entropy_cross-build.patch25
-rw-r--r--standalone/android/haskell-patches/gnuidn_fix-build-with-new-base.patch50
-rw-r--r--standalone/android/haskell-patches/gnutls_0.1.4-0001-statically-link-with-gnutls.patch37
-rw-r--r--standalone/android/haskell-patches/gsasl_0.3.5-0001-link-with-libgsasl.patch25
-rw-r--r--standalone/android/haskell-patches/iproute_1.2.11_0001-build-without-IPv6-stuff.patch47
-rw-r--r--standalone/android/haskell-patches/language-javascript_fix-build-with-new-ghc.patch25
-rw-r--r--standalone/android/haskell-patches/lens_various-hacking-to-cross-build.patch385
-rw-r--r--standalone/android/haskell-patches/lifted-base_crossbuild.patch25
-rw-r--r--standalone/android/haskell-patches/network_2.4.1.0_0001-android-port-fixes.patch1960
-rw-r--r--standalone/android/haskell-patches/network_2.4.1.0_0002-remove-Network.BSD-symbols-not-available-in-bionic.patch157
-rw-r--r--standalone/android/haskell-patches/network_2.4.1.0_0003-configure-misdetects-accept4.patch34
-rw-r--r--standalone/android/haskell-patches/network_2.4.1.0_0004-getprotobyname-hack-for-tcp-and-udp.patch28
-rw-r--r--standalone/android/haskell-patches/persistent-template_stub-out.patch25
-rw-r--r--standalone/android/haskell-patches/persistent_1.1.5.1_0001-disable-TH.patch32
-rw-r--r--standalone/android/haskell-patches/primitive_0.5.0.1_0001-disable-i386-opt-stuff-to-allow-cross-compilation.patch24
-rw-r--r--standalone/android/haskell-patches/process_fix-build-with-new-ghc.patch24
-rw-r--r--standalone/android/haskell-patches/profunctors_3.3-0001-fix-cross-build.patch26
-rw-r--r--standalone/android/haskell-patches/shakespeare-css_1.0.2_0001-remove-TH.patch148
-rw-r--r--standalone/android/haskell-patches/shakespeare-css_1.0.2_0002-expose-modules-used-by-TH.patch26
-rw-r--r--standalone/android/haskell-patches/shakespeare_1.0.3_0001-export-symbol-used-by-TH-splices.patch26
-rw-r--r--standalone/android/haskell-patches/skein_hardcode_little-endian.patch24
-rw-r--r--standalone/android/haskell-patches/socks_0.4.2_0001-remove-IPv6-stuff.patch135
-rw-r--r--standalone/android/haskell-patches/stm-chans_cross-build.patch25
-rw-r--r--standalone/android/haskell-patches/unix-time_hack-for-Bionic.patch56
-rw-r--r--standalone/android/haskell-patches/uuid_build-without-v1-uuid-which-needs-network-info.patch79
-rw-r--r--standalone/android/haskell-patches/vector_hack-to-build-with-new-ghc.patch24
-rw-r--r--standalone/android/haskell-patches/wai-app-static_deal-with-TH.patch54
-rw-r--r--standalone/android/haskell-patches/yesod-auth_don-t-really-build.patch34
-rw-r--r--standalone/android/haskell-patches/yesod-core_expand_TH.patch411
-rw-r--r--standalone/android/haskell-patches/yesod-form_spliced-TH.patch1783
-rw-r--r--standalone/android/haskell-patches/yesod-persistent_do-not-really-build.patch26
-rw-r--r--standalone/android/haskell-patches/yesod-routes_export-module-referenced-by-TH-splices.patch29
-rw-r--r--standalone/android/haskell-patches/yesod_001_hacked-up-for-Android.patch74
-rw-r--r--standalone/android/haskell-patches/yesod_002_hack-around-missing-symbols.patch41
-rw-r--r--standalone/android/haskell-patches/zlib_0.5.4.0_0001-hack-to-build-on-Android.patch35
-rw-r--r--standalone/android/icons/drawable-hdpi/ic_launcher.pngbin0 -> 2612 bytes
-rw-r--r--standalone/android/icons/drawable-hdpi/ic_stat_service_notification_icon.pngbin0 -> 1310 bytes
-rw-r--r--standalone/android/icons/drawable-ldpi/ic_launcher.pngbin0 -> 1279 bytes
-rw-r--r--standalone/android/icons/drawable-ldpi/ic_stat_service_notification_icon.pngbin0 -> 682 bytes
-rw-r--r--standalone/android/icons/drawable-mdpi/ic_launcher.pngbin0 -> 1768 bytes
-rw-r--r--standalone/android/icons/drawable-mdpi/ic_stat_service_notification_icon.pngbin0 -> 946 bytes
-rw-r--r--standalone/android/icons/drawable-xhdpi/ic_launcher.pngbin0 -> 3396 bytes
-rw-r--r--standalone/android/icons/drawable-xhdpi/ic_stat_service_notification_icon.pngbin0 -> 1837 bytes
l---------standalone/android/icons/drawable/ic_launcher.png1
l---------standalone/android/icons/drawable/ic_stat_service_notification_icon.png1
-rwxr-xr-xstandalone/android/install-haskell-packages120
-rw-r--r--standalone/android/openssh.config.h249
-rw-r--r--standalone/android/openssh.patch205
-rw-r--r--standalone/android/rsync.patch40
-rwxr-xr-xstandalone/android/runshell132
-rwxr-xr-xstandalone/android/startbin0 -> 6492 bytes
-rw-r--r--standalone/android/start.c64
-rw-r--r--standalone/android/term.patch598
-rw-r--r--standalone/licences.gzbin0 -> 60519 bytes
-rw-r--r--standalone/linux/README25
-rwxr-xr-xstandalone/linux/git-annex25
-rwxr-xr-xstandalone/linux/git-annex-shell25
-rwxr-xr-xstandalone/linux/git-annex-webapp25
-rw-r--r--standalone/linux/glibc-libs43
-rwxr-xr-xstandalone/linux/runshell76
-rw-r--r--standalone/osx/git-annex.app/Contents/Info.plist41
-rw-r--r--standalone/osx/git-annex.app/Contents/MacOS/README9
-rwxr-xr-xstandalone/osx/git-annex.app/Contents/MacOS/git-annex25
-rwxr-xr-xstandalone/osx/git-annex.app/Contents/MacOS/git-annex-shell25
-rwxr-xr-xstandalone/osx/git-annex.app/Contents/MacOS/git-annex-webapp26
-rwxr-xr-xstandalone/osx/git-annex.app/Contents/MacOS/runshell71
-rw-r--r--standalone/osx/git-annex.app/Contents/Resources/git-annex.icnsbin0 -> 77548 bytes
-rw-r--r--standalone/windows/build.sh56
6246 files changed, 179247 insertions, 0 deletions
diff --git a/.ghci b/.ghci
new file mode 100644
index 000000000..c5550cee6
--- /dev/null
+++ b/.ghci
@@ -0,0 +1 @@
+:load Common
diff --git a/Annex.hs b/Annex.hs
new file mode 100644
index 000000000..583cb0e02
--- /dev/null
+++ b/Annex.hs
@@ -0,0 +1,252 @@
+{- git-annex monad
+ -
+ - Copyright 2010-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE GeneralizedNewtypeDeriving, PackageImports #-}
+
+module Annex (
+ Annex,
+ AnnexState(..),
+ PreferredContentMap,
+ new,
+ run,
+ eval,
+ getState,
+ changeState,
+ setFlag,
+ setField,
+ setOutput,
+ getFlag,
+ getField,
+ addCleanup,
+ gitRepo,
+ inRepo,
+ fromRepo,
+ calcRepo,
+ getGitConfig,
+ changeGitConfig,
+ changeGitRepo,
+ withCurrentState,
+) where
+
+import "mtl" Control.Monad.Reader
+import "MonadCatchIO-transformers" Control.Monad.CatchIO
+import System.Posix.Types (Fd)
+import Control.Concurrent
+
+import Common
+import qualified Git
+import qualified Git.Config
+import Annex.Direct.Fixup
+import Git.CatFile
+import Git.CheckAttr
+import Git.CheckIgnore
+import Git.SharedRepository
+import qualified Git.Queue
+import Types.Backend
+import Types.GitConfig
+import qualified Types.Remote
+import Types.Crypto
+import Types.BranchState
+import Types.TrustLevel
+import Types.Group
+import Types.Messages
+import Types.UUID
+import Types.FileMatcher
+import qualified Utility.Matcher
+import qualified Data.Map as M
+import qualified Data.Set as S
+
+{- git-annex's monad is a ReaderT around an AnnexState stored in a MVar.
+ - This allows modifying the state in an exception-safe fashion.
+ - The MVar is not exposed outside this module.
+ -}
+newtype Annex a = Annex { runAnnex :: ReaderT (MVar AnnexState) IO a }
+ deriving (
+ Monad,
+ MonadIO,
+ MonadReader (MVar AnnexState),
+ MonadCatchIO,
+ Functor,
+ Applicative
+ )
+
+type Matcher a = Either [Utility.Matcher.Token a] (Utility.Matcher.Matcher a)
+type PreferredContentMap = M.Map UUID (Utility.Matcher.Matcher (S.Set UUID -> FileInfo -> Annex Bool))
+
+-- internal state storage
+data AnnexState = AnnexState
+ { repo :: Git.Repo
+ , gitconfig :: GitConfig
+ , backends :: [BackendA Annex]
+ , remotes :: [Types.Remote.RemoteA Annex]
+ , output :: MessageState
+ , force :: Bool
+ , fast :: Bool
+ , auto :: Bool
+ , daemon :: Bool
+ , branchstate :: BranchState
+ , repoqueue :: Maybe Git.Queue.Queue
+ , catfilehandles :: M.Map FilePath CatFileHandle
+ , checkattrhandle :: Maybe CheckAttrHandle
+ , checkignorehandle :: Maybe (Maybe CheckIgnoreHandle)
+ , forcebackend :: Maybe String
+ , forcenumcopies :: Maybe Int
+ , limit :: Matcher (FileInfo -> Annex Bool)
+ , uuidmap :: Maybe UUIDMap
+ , preferredcontentmap :: Maybe PreferredContentMap
+ , shared :: Maybe SharedRepository
+ , forcetrust :: TrustMap
+ , trustmap :: Maybe TrustMap
+ , groupmap :: Maybe GroupMap
+ , ciphers :: M.Map StorableCipher Cipher
+ , lockpool :: M.Map FilePath Fd
+ , flags :: M.Map String Bool
+ , fields :: M.Map String String
+ , cleanup :: M.Map String (Annex ())
+ , inodeschanged :: Maybe Bool
+ , useragent :: Maybe String
+ }
+
+newState :: GitConfig -> Git.Repo -> AnnexState
+newState c r = AnnexState
+ { repo = r
+ , gitconfig = c
+ , backends = []
+ , remotes = []
+ , output = defaultMessageState
+ , force = False
+ , fast = False
+ , auto = False
+ , daemon = False
+ , branchstate = startBranchState
+ , repoqueue = Nothing
+ , catfilehandles = M.empty
+ , checkattrhandle = Nothing
+ , checkignorehandle = Nothing
+ , forcebackend = Nothing
+ , forcenumcopies = Nothing
+ , limit = Left []
+ , uuidmap = Nothing
+ , preferredcontentmap = Nothing
+ , shared = Nothing
+ , forcetrust = M.empty
+ , trustmap = Nothing
+ , groupmap = Nothing
+ , ciphers = M.empty
+ , lockpool = M.empty
+ , flags = M.empty
+ , fields = M.empty
+ , cleanup = M.empty
+ , inodeschanged = Nothing
+ , useragent = Nothing
+ }
+
+{- Makes an Annex state object for the specified git repo.
+ - Ensures the config is read, if it was not already. -}
+new :: Git.Repo -> IO AnnexState
+new r = do
+ r' <- Git.Config.read r
+ let c = extractGitConfig r'
+ newState c <$> if annexDirect c then fixupDirect r' else return r'
+
+{- Performs an action in the Annex monad from a starting state,
+ - returning a new state. -}
+run :: AnnexState -> Annex a -> IO (a, AnnexState)
+run s a = do
+ mvar <- newMVar s
+ r <- runReaderT (runAnnex a) mvar
+ s' <- takeMVar mvar
+ return (r, s')
+
+{- Performs an action in the Annex monad from a starting state,
+ - and throws away the new state. -}
+eval :: AnnexState -> Annex a -> IO a
+eval s a = do
+ mvar <- newMVar s
+ runReaderT (runAnnex a) mvar
+
+getState :: (AnnexState -> v) -> Annex v
+getState selector = do
+ mvar <- ask
+ s <- liftIO $ readMVar mvar
+ return $ selector s
+
+changeState :: (AnnexState -> AnnexState) -> Annex ()
+changeState modifier = do
+ mvar <- ask
+ liftIO $ modifyMVar_ mvar $ return . modifier
+
+{- Sets a flag to True -}
+setFlag :: String -> Annex ()
+setFlag flag = changeState $ \s ->
+ s { flags = M.insertWith' const flag True $ flags s }
+
+{- Sets a field to a value -}
+setField :: String -> String -> Annex ()
+setField field value = changeState $ \s ->
+ s { fields = M.insertWith' const field value $ fields s }
+
+{- Adds a cleanup action to perform. -}
+addCleanup :: String -> Annex () -> Annex ()
+addCleanup uid a = changeState $ \s ->
+ s { cleanup = M.insertWith' const uid a $ cleanup s }
+
+{- Sets the type of output to emit. -}
+setOutput :: OutputType -> Annex ()
+setOutput o = changeState $ \s ->
+ s { output = (output s) { outputType = o } }
+
+{- Checks if a flag was set. -}
+getFlag :: String -> Annex Bool
+getFlag flag = fromMaybe False . M.lookup flag <$> getState flags
+
+{- Gets the value of a field. -}
+getField :: String -> Annex (Maybe String)
+getField field = M.lookup field <$> getState fields
+
+{- Returns the annex's git repository. -}
+gitRepo :: Annex Git.Repo
+gitRepo = getState repo
+
+{- Runs an IO action in the annex's git repository. -}
+inRepo :: (Git.Repo -> IO a) -> Annex a
+inRepo a = liftIO . a =<< gitRepo
+
+{- Extracts a value from the annex's git repisitory. -}
+fromRepo :: (Git.Repo -> a) -> Annex a
+fromRepo a = a <$> gitRepo
+
+{- Calculates a value from an annex's git repository and its GitConfig. -}
+calcRepo :: (Git.Repo -> GitConfig -> IO a) -> Annex a
+calcRepo a = do
+ s <- getState id
+ liftIO $ a (repo s) (gitconfig s)
+
+{- Gets the GitConfig settings. -}
+getGitConfig :: Annex GitConfig
+getGitConfig = getState gitconfig
+
+{- Modifies a GitConfig setting. -}
+changeGitConfig :: (GitConfig -> GitConfig) -> Annex ()
+changeGitConfig a = changeState $ \s -> s { gitconfig = a (gitconfig s) }
+
+{- Changing the git Repo data also involves re-extracting its GitConfig. -}
+changeGitRepo :: Git.Repo -> Annex ()
+changeGitRepo r = changeState $ \s -> s
+ { repo = r
+ , gitconfig = extractGitConfig r
+ }
+
+{- Converts an Annex action into an IO action, that runs with a copy
+ - of the current Annex state.
+ -
+ - Use with caution; the action should not rely on changing the
+ - state, as it will be thrown away. -}
+withCurrentState :: Annex a -> Annex (IO a)
+withCurrentState a = do
+ s <- getState id
+ return $ eval s a
diff --git a/Annex/Branch.hs b/Annex/Branch.hs
new file mode 100644
index 000000000..9838af25f
--- /dev/null
+++ b/Annex/Branch.hs
@@ -0,0 +1,533 @@
+{- management of the git-annex branch
+ -
+ - Copyright 2011-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Annex.Branch (
+ fullname,
+ name,
+ hasOrigin,
+ hasSibling,
+ siblingBranches,
+ create,
+ update,
+ forceUpdate,
+ updateTo,
+ get,
+ change,
+ commit,
+ forceCommit,
+ files,
+ withIndex,
+ performTransitions,
+) where
+
+import qualified Data.ByteString.Lazy.Char8 as L
+import qualified Data.Set as S
+import qualified Data.Map as M
+import qualified Control.Exception as E
+
+import Common.Annex
+import Annex.BranchState
+import Annex.Journal
+import qualified Git
+import qualified Git.Command
+import qualified Git.Ref
+import qualified Git.Sha
+import qualified Git.Branch
+import qualified Git.UnionMerge
+import qualified Git.UpdateIndex
+import Git.HashObject
+import Git.Types
+import Git.FilePath
+import Annex.CatFile
+import Annex.Perms
+import qualified Annex
+import Utility.Env
+import Logs
+import Logs.Transitions
+import Logs.Trust.Pure
+import Annex.ReplaceFile
+import qualified Annex.Queue
+import Annex.Branch.Transitions
+import Annex.Exception
+
+{- Name of the branch that is used to store git-annex's information. -}
+name :: Git.Ref
+name = Git.Ref "git-annex"
+
+{- Fully qualified name of the branch. -}
+fullname :: Git.Ref
+fullname = Git.Ref $ "refs/heads/" ++ show name
+
+{- Branch's name in origin. -}
+originname :: Git.Ref
+originname = Git.Ref $ "origin/" ++ show name
+
+{- Does origin/git-annex exist? -}
+hasOrigin :: Annex Bool
+hasOrigin = inRepo $ Git.Ref.exists originname
+
+{- Does the git-annex branch or a sibling foo/git-annex branch exist? -}
+hasSibling :: Annex Bool
+hasSibling = not . null <$> siblingBranches
+
+{- List of git-annex (refs, branches), including the main one and any
+ - from remotes. Duplicate refs are filtered out. -}
+siblingBranches :: Annex [(Git.Ref, Git.Branch)]
+siblingBranches = inRepo $ Git.Ref.matchingUniq [name]
+
+{- Creates the branch, if it does not already exist. -}
+create :: Annex ()
+create = void getBranch
+
+{- Returns the ref of the branch, creating it first if necessary. -}
+getBranch :: Annex Git.Ref
+getBranch = maybe (hasOrigin >>= go >>= use) return =<< branchsha
+ where
+ go True = do
+ inRepo $ Git.Command.run
+ [Param "branch", Param $ show name, Param $ show originname]
+ fromMaybe (error $ "failed to create " ++ show name)
+ <$> branchsha
+ go False = withIndex' True $
+ inRepo $ Git.Branch.commit "branch created" fullname []
+ use sha = do
+ setIndexSha sha
+ return sha
+ branchsha = inRepo $ Git.Ref.sha fullname
+
+{- Ensures that the branch and index are up-to-date; should be
+ - called before data is read from it. Runs only once per git-annex run. -}
+update :: Annex ()
+update = runUpdateOnce $ void $ updateTo =<< siblingBranches
+
+{- Forces an update even if one has already been run. -}
+forceUpdate :: Annex Bool
+forceUpdate = updateTo =<< siblingBranches
+
+{- Merges the specified Refs into the index, if they have any changes not
+ - already in it. The Branch names are only used in the commit message;
+ - it's even possible that the provided Branches have not been updated to
+ - point to the Refs yet.
+ -
+ - The branch is fast-forwarded if possible, otherwise a merge commit is
+ - made.
+ -
+ - Before Refs are merged into the index, it's important to first stage the
+ - journal into the index. Otherwise, any changes in the journal would
+ - later get staged, and might overwrite changes made during the merge.
+ - This is only done if some of the Refs do need to be merged.
+ -
+ - Also handles performing any Transitions that have not yet been
+ - performed, in either the local branch, or the Refs.
+ -
+ - Returns True if any refs were merged in, False otherwise.
+ -}
+updateTo :: [(Git.Ref, Git.Branch)] -> Annex Bool
+updateTo pairs = do
+ -- ensure branch exists, and get its current ref
+ branchref <- getBranch
+ dirty <- journalDirty
+ ignoredrefs <- getIgnoredRefs
+ (refs, branches) <- unzip <$> filterM (isnewer ignoredrefs) pairs
+ if null refs
+ {- Even when no refs need to be merged, the index
+ - may still be updated if the branch has gotten ahead
+ - of the index. -}
+ then whenM (needUpdateIndex branchref) $ lockJournal $ \jl -> do
+ forceUpdateIndex jl branchref
+ {- When there are journalled changes
+ - as well as the branch being updated,
+ - a commit needs to be done. -}
+ when dirty $
+ go branchref True [] [] jl
+ else lockJournal $ go branchref dirty refs branches
+ return $ not $ null refs
+ where
+ isnewer ignoredrefs (r, _)
+ | S.member r ignoredrefs = return False
+ | otherwise = inRepo $ Git.Branch.changed fullname r
+ go branchref dirty refs branches jl = withIndex $ do
+ cleanjournal <- if dirty then stageJournal jl else return noop
+ let merge_desc = if null branches
+ then "update"
+ else "merging " ++
+ unwords (map Git.Ref.describe branches) ++
+ " into " ++ show name
+ localtransitions <- parseTransitionsStrictly "local"
+ <$> getLocal transitionsLog
+ unless (null branches) $ do
+ showSideAction merge_desc
+ mergeIndex jl refs
+ let commitrefs = nub $ fullname:refs
+ unlessM (handleTransitions jl localtransitions commitrefs) $ do
+ ff <- if dirty
+ then return False
+ else inRepo $ Git.Branch.fastForward fullname refs
+ if ff
+ then updateIndex jl branchref
+ else commitIndex jl branchref merge_desc commitrefs
+ liftIO cleanjournal
+
+{- Gets the content of a file, which may be in the journal, or in the index
+ - (and committed to the branch).
+ -
+ - Updates the branch if necessary, to ensure the most up-to-date available
+ - content is returned.
+ -
+ - Returns an empty string if the file doesn't exist yet. -}
+get :: FilePath -> Annex String
+get file = do
+ update
+ getLocal file
+
+{- Like get, but does not merge the branch, so the info returned may not
+ - reflect changes in remotes.
+ - (Changing the value this returns, and then merging is always the
+ - same as using get, and then changing its value.) -}
+getLocal :: FilePath -> Annex String
+getLocal file = go =<< getJournalFileStale file
+ where
+ go (Just journalcontent) = return journalcontent
+ go Nothing = getRaw file
+
+getRaw :: FilePath -> Annex String
+getRaw file = withIndex $ L.unpack <$> catFile fullname file
+
+{- Applies a function to modifiy the content of a file.
+ -
+ - Note that this does not cause the branch to be merged, it only
+ - modifes the current content of the file on the branch.
+ -}
+change :: FilePath -> (String -> String) -> Annex ()
+change file a = lockJournal $ \jl -> a <$> getLocal file >>= set jl file
+
+{- Records new content of a file into the journal -}
+set :: JournalLocked -> FilePath -> String -> Annex ()
+set = setJournalFile
+
+{- Stages the journal, and commits staged changes to the branch. -}
+commit :: String -> Annex ()
+commit = whenM journalDirty . forceCommit
+
+{- Commits the current index to the branch even without any journalleda
+ - changes. -}
+forceCommit :: String -> Annex ()
+forceCommit message = lockJournal $ \jl -> do
+ cleanjournal <- stageJournal jl
+ ref <- getBranch
+ withIndex $ commitIndex jl ref message [fullname]
+ liftIO cleanjournal
+
+{- Commits the staged changes in the index to the branch.
+ -
+ - Ensures that the branch's index file is first updated to the state
+ - of the branch at branchref, before running the commit action. This
+ - is needed because the branch may have had changes pushed to it, that
+ - are not yet reflected in the index.
+ -
+ - Also safely handles a race that can occur if a change is being pushed
+ - into the branch at the same time. When the race happens, the commit will
+ - be made on top of the newly pushed change, but without the index file
+ - being updated to include it. The result is that the newly pushed
+ - change is reverted. This race is detected and another commit made
+ - to fix it.
+ -
+ - The branchref value can have been obtained using getBranch at any
+ - previous point, though getting it a long time ago makes the race
+ - more likely to occur.
+ -}
+commitIndex :: JournalLocked -> Git.Ref -> String -> [Git.Ref] -> Annex ()
+commitIndex jl branchref message parents = do
+ showStoringStateAction
+ commitIndex' jl branchref message parents
+commitIndex' :: JournalLocked -> Git.Ref -> String -> [Git.Ref] -> Annex ()
+commitIndex' jl branchref message parents = do
+ updateIndex jl branchref
+ committedref <- inRepo $ Git.Branch.commit message fullname parents
+ setIndexSha committedref
+ parentrefs <- commitparents <$> catObject committedref
+ when (racedetected branchref parentrefs) $ do
+ liftIO $ print ("race detected", branchref, parentrefs, "committing", (branchref, parents))
+ fixrace committedref parentrefs
+ where
+ -- look for "parent ref" lines and return the refs
+ commitparents = map (Git.Ref . snd) . filter isparent .
+ map (toassoc . L.unpack) . L.lines
+ toassoc = separate (== ' ')
+ isparent (k,_) = k == "parent"
+
+ {- The race can be detected by checking the commit's
+ - parent, which will be the newly pushed branch,
+ - instead of the expected ref that the index was updated to. -}
+ racedetected expectedref parentrefs
+ | expectedref `elem` parentrefs = False -- good parent
+ | otherwise = True -- race!
+
+ {- To recover from the race, union merge the lost refs
+ - into the index, and recommit on top of the bad commit. -}
+ fixrace committedref lostrefs = do
+ mergeIndex jl lostrefs
+ commitIndex jl committedref racemessage [committedref]
+
+ racemessage = message ++ " (recovery from race)"
+
+{- Lists all files on the branch. There may be duplicates in the list. -}
+files :: Annex [FilePath]
+files = do
+ update
+ (++)
+ <$> branchFiles
+ <*> getJournalledFilesStale
+
+{- Files in the branch, not including any from journalled changes,
+ - and without updating the branch. -}
+branchFiles :: Annex [FilePath]
+branchFiles = withIndex $ inRepo $ Git.Command.pipeNullSplitZombie
+ [ Params "ls-tree --name-only -r -z"
+ , Param $ show fullname
+ ]
+
+{- Populates the branch's index file with the current branch contents.
+ -
+ - This is only done when the index doesn't yet exist, and the index
+ - is used to build up changes to be commited to the branch, and merge
+ - in changes from other branches.
+ -}
+genIndex :: Git.Repo -> IO ()
+genIndex g = Git.UpdateIndex.streamUpdateIndex g
+ [Git.UpdateIndex.lsTree fullname g]
+
+{- Merges the specified refs into the index.
+ - Any changes staged in the index will be preserved. -}
+mergeIndex :: JournalLocked -> [Git.Ref] -> Annex ()
+mergeIndex jl branches = do
+ prepareModifyIndex jl
+ h <- catFileHandle
+ inRepo $ \g -> Git.UnionMerge.mergeIndex h g branches
+
+{- Removes any stale git lock file, to avoid git falling over when
+ - updating the index.
+ -
+ - Since all modifications of the index are performed inside this module,
+ - and only when the journal is locked, the fact that the journal has to be
+ - locked when this is called ensures that no other process is currently
+ - modifying the index. So any index.lock file must be stale, caused
+ - by git running when the system crashed, or the repository's disk was
+ - removed, etc.
+ -}
+prepareModifyIndex :: JournalLocked -> Annex ()
+prepareModifyIndex _jl = do
+ index <- fromRepo gitAnnexIndex
+ void $ liftIO $ tryIO $ removeFile $ index ++ ".lock"
+
+{- Runs an action using the branch's index file. -}
+withIndex :: Annex a -> Annex a
+withIndex = withIndex' False
+withIndex' :: Bool -> Annex a -> Annex a
+withIndex' bootstrapping a = do
+ f <- fromRepo gitAnnexIndex
+ g <- gitRepo
+#ifdef __ANDROID__
+ {- This should not be necessary on Android, but there is some
+ - weird getEnvironment breakage. See
+ - https://github.com/neurocyte/ghc-android/issues/7
+ - Use getEnv to get some key environment variables that
+ - git expects to have. -}
+ let keyenv = words "USER PATH GIT_EXEC_PATH HOSTNAME HOME"
+ let getEnvPair k = maybe Nothing (\v -> Just (k, v)) <$> getEnv k
+ e <- liftIO $ catMaybes <$> forM keyenv getEnvPair
+#else
+ e <- liftIO getEnvironment
+#endif
+ let g' = g { gitEnv = Just $ ("GIT_INDEX_FILE", f):e }
+
+ r <- tryAnnex $ do
+ Annex.changeState $ \s -> s { Annex.repo = g' }
+ checkIndexOnce $ unlessM (liftIO $ doesFileExist f) $ do
+ unless bootstrapping create
+ createAnnexDirectory $ takeDirectory f
+ unless bootstrapping $ inRepo genIndex
+ a
+ Annex.changeState $ \s -> s { Annex.repo = (Annex.repo s) { gitEnv = gitEnv g} }
+ either E.throw return r
+
+{- Updates the branch's index to reflect the current contents of the branch.
+ - Any changes staged in the index will be preserved.
+ -
+ - Compares the ref stored in the lock file with the current
+ - ref of the branch to see if an update is needed.
+ -}
+updateIndex :: JournalLocked -> Git.Ref -> Annex ()
+updateIndex jl branchref = whenM (needUpdateIndex branchref) $
+ forceUpdateIndex jl branchref
+
+forceUpdateIndex :: JournalLocked -> Git.Ref -> Annex ()
+forceUpdateIndex jl branchref = do
+ withIndex $ mergeIndex jl [fullname]
+ setIndexSha branchref
+
+{- Checks if the index needs to be updated. -}
+needUpdateIndex :: Git.Ref -> Annex Bool
+needUpdateIndex branchref = do
+ f <- fromRepo gitAnnexIndexStatus
+ committedref <- Git.Ref . firstLine <$>
+ liftIO (catchDefaultIO "" $ readFileStrict f)
+ return (committedref /= branchref)
+
+{- Record that the branch's index has been updated to correspond to a
+ - given ref of the branch. -}
+setIndexSha :: Git.Ref -> Annex ()
+setIndexSha ref = do
+ f <- fromRepo gitAnnexIndexStatus
+ liftIO $ writeFile f $ show ref ++ "\n"
+ setAnnexFilePerm f
+
+{- Stages the journal into the index and returns an action that will
+ - clean up the staged journal files, which should only be run once
+ - the index has been committed to the branch.
+ -
+ - Before staging, this removes any existing git index file lock.
+ - This is safe to do because stageJournal is the only thing that
+ - modifies this index file, and only one can run at a time, because
+ - the journal is locked. So any existing git index file lock must be
+ - stale, and the journal must contain any data that was in the process
+ - of being written to the index file when it crashed.
+ -}
+stageJournal :: JournalLocked -> Annex (IO ())
+stageJournal jl = withIndex $ do
+ prepareModifyIndex jl
+ g <- gitRepo
+ let dir = gitAnnexJournalDir g
+ fs <- getJournalFiles jl
+ liftIO $ do
+ h <- hashObjectStart g
+ Git.UpdateIndex.streamUpdateIndex g
+ [genstream dir h fs]
+ hashObjectStop h
+ return $ liftIO $ mapM_ (removeFile . (dir </>)) fs
+ where
+ genstream dir h fs streamer = forM_ fs $ \file -> do
+ let path = dir </> file
+ sha <- hashFile h path
+ streamer $ Git.UpdateIndex.updateIndexLine
+ sha FileBlob (asTopFilePath $ fileJournal file)
+
+{- This is run after the refs have been merged into the index,
+ - but before the result is committed to the branch.
+ - (Which is why it's passed the contents of the local branches's
+ - transition log before that merge took place.)
+ -
+ - When the refs contain transitions that have not yet been done locally,
+ - the transitions are performed on the index, and a new branch
+ - is created from the result.
+ -
+ - When there are transitions recorded locally that have not been done
+ - to the remote refs, the transitions are performed in the index,
+ - and committed to the existing branch. In this case, the untransitioned
+ - remote refs cannot be merged into the branch (since transitions
+ - throw away history), so they are added to the list of refs to ignore,
+ - to avoid re-merging content from them again.
+ -}
+handleTransitions :: JournalLocked -> Transitions -> [Git.Ref] -> Annex Bool
+handleTransitions jl localts refs = do
+ m <- M.fromList <$> mapM getreftransition refs
+ let remotets = M.elems m
+ if all (localts ==) remotets
+ then return False
+ else do
+ let allts = combineTransitions (localts:remotets)
+ let (transitionedrefs, untransitionedrefs) =
+ partition (\r -> M.lookup r m == Just allts) refs
+ performTransitionsLocked jl allts (localts /= allts) transitionedrefs
+ ignoreRefs untransitionedrefs
+ return True
+ where
+ getreftransition ref = do
+ ts <- parseTransitionsStrictly "remote" . L.unpack
+ <$> catFile ref transitionsLog
+ return (ref, ts)
+
+ignoreRefs :: [Git.Ref] -> Annex ()
+ignoreRefs rs = do
+ old <- getIgnoredRefs
+ let s = S.unions [old, S.fromList rs]
+ f <- fromRepo gitAnnexIgnoredRefs
+ replaceFile f $ \tmp -> liftIO $ writeFile tmp $
+ unlines $ map show $ S.elems s
+
+getIgnoredRefs :: Annex (S.Set Git.Ref)
+getIgnoredRefs = S.fromList . mapMaybe Git.Sha.extractSha . lines <$> content
+ where
+ content = do
+ f <- fromRepo gitAnnexIgnoredRefs
+ liftIO $ catchDefaultIO "" $ readFile f
+
+{- Performs the specified transitions on the contents of the index file,
+ - commits it to the branch, or creates a new branch.
+ -}
+performTransitions :: Transitions -> Bool -> [Ref] -> Annex ()
+performTransitions ts neednewlocalbranch transitionedrefs = lockJournal $ \jl ->
+ performTransitionsLocked jl ts neednewlocalbranch transitionedrefs
+performTransitionsLocked :: JournalLocked -> Transitions -> Bool -> [Ref] -> Annex ()
+performTransitionsLocked jl ts neednewlocalbranch transitionedrefs = do
+ -- For simplicity & speed, we're going to use the Annex.Queue to
+ -- update the git-annex branch, while it usually holds changes
+ -- for the head branch. Flush any such changes.
+ Annex.Queue.flush
+ withIndex $ do
+ prepareModifyIndex jl
+ run $ mapMaybe getTransitionCalculator $ transitionList ts
+ Annex.Queue.flush
+ if neednewlocalbranch
+ then do
+ committedref <- inRepo $ Git.Branch.commit message fullname transitionedrefs
+ setIndexSha committedref
+ else do
+ ref <- getBranch
+ commitIndex jl ref message (nub $ fullname:transitionedrefs)
+ where
+ message
+ | neednewlocalbranch && null transitionedrefs = "new branch for transition " ++ tdesc
+ | otherwise = "continuing transition " ++ tdesc
+ tdesc = show $ map describeTransition $ transitionList ts
+
+ {- The changes to make to the branch are calculated and applied to
+ - the branch directly, rather than going through the journal,
+ - which would be innefficient. (And the journal is not designed
+ - to hold changes to every file in the branch at once.)
+ -
+ - When a file in the branch is changed by transition code,
+ - that value is remembered and fed into the code for subsequent
+ - transitions.
+ -}
+ run [] = noop
+ run changers = do
+ trustmap <- calcTrustMap <$> getRaw trustLog
+ fs <- branchFiles
+ hasher <- inRepo hashObjectStart
+ forM_ fs $ \f -> do
+ content <- getRaw f
+ apply changers hasher f content trustmap
+ liftIO $ hashObjectStop hasher
+ apply [] _ _ _ _ = return ()
+ apply (changer:rest) hasher file content trustmap =
+ case changer file content trustmap of
+ RemoveFile -> do
+ Annex.Queue.addUpdateIndex
+ =<< inRepo (Git.UpdateIndex.unstageFile file)
+ -- File is deleted; can't run any other
+ -- transitions on it.
+ return ()
+ ChangeFile content' -> do
+ sha <- inRepo $ hashObject BlobObject content'
+ Annex.Queue.addUpdateIndex $ Git.UpdateIndex.pureStreamer $
+ Git.UpdateIndex.updateIndexLine sha FileBlob (asTopFilePath file)
+ apply rest hasher file content' trustmap
+ PreserveFile ->
+ apply rest hasher file content trustmap
diff --git a/Annex/Branch/Transitions.hs b/Annex/Branch/Transitions.hs
new file mode 100644
index 000000000..90002de62
--- /dev/null
+++ b/Annex/Branch/Transitions.hs
@@ -0,0 +1,53 @@
+{- git-annex branch transitions
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Annex.Branch.Transitions (
+ FileTransition(..),
+ getTransitionCalculator
+) where
+
+import Logs
+import Logs.Transitions
+import Logs.UUIDBased as UUIDBased
+import Logs.Presence.Pure as Presence
+import Types.TrustLevel
+import Types.UUID
+
+import qualified Data.Map as M
+
+data FileTransition
+ = ChangeFile String
+ | RemoveFile
+ | PreserveFile
+
+type TransitionCalculator = FilePath -> String -> TrustMap -> FileTransition
+
+getTransitionCalculator :: Transition -> Maybe TransitionCalculator
+getTransitionCalculator ForgetGitHistory = Nothing
+getTransitionCalculator ForgetDeadRemotes = Just dropDead
+
+dropDead :: FilePath -> String -> TrustMap -> FileTransition
+dropDead f content trustmap = case getLogVariety f of
+ Just UUIDBasedLog -> ChangeFile $
+ UUIDBased.showLog id $ dropDeadFromUUIDBasedLog trustmap $ UUIDBased.parseLog Just content
+ Just (PresenceLog _) ->
+ let newlog = Presence.compactLog $ dropDeadFromPresenceLog trustmap $ Presence.parseLog content
+ in if null newlog
+ then RemoveFile
+ else ChangeFile $ Presence.showLog newlog
+ Nothing -> PreserveFile
+
+dropDeadFromUUIDBasedLog :: TrustMap -> UUIDBased.Log String -> UUIDBased.Log String
+dropDeadFromUUIDBasedLog trustmap = M.filterWithKey $ notDead trustmap . const
+
+{- Presence logs can contain UUIDs or other values. Any line that matches
+ - a dead uuid is dropped; any other values are passed through. -}
+dropDeadFromPresenceLog :: TrustMap -> [Presence.LogLine] -> [Presence.LogLine]
+dropDeadFromPresenceLog trustmap = filter $ notDead trustmap (toUUID . Presence.info)
+
+notDead :: TrustMap -> (v -> UUID) -> v -> Bool
+notDead trustmap a v = M.findWithDefault SemiTrusted (a v) trustmap /= DeadTrusted
diff --git a/Annex/BranchState.hs b/Annex/BranchState.hs
new file mode 100644
index 000000000..9b2f9a04c
--- /dev/null
+++ b/Annex/BranchState.hs
@@ -0,0 +1,43 @@
+{- git-annex branch state management
+ -
+ - Runtime state about the git-annex branch.
+ -
+ - Copyright 2011-2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Annex.BranchState where
+
+import Common.Annex
+import Types.BranchState
+import qualified Annex
+
+getState :: Annex BranchState
+getState = Annex.getState Annex.branchstate
+
+setState :: BranchState -> Annex ()
+setState state = Annex.changeState $ \s -> s { Annex.branchstate = state }
+
+changeState :: (BranchState -> BranchState) -> Annex ()
+changeState changer = setState =<< changer <$> getState
+
+{- Runs an action to check that the index file exists, if it's not been
+ - checked before in this run of git-annex. -}
+checkIndexOnce :: Annex () -> Annex ()
+checkIndexOnce a = unlessM (indexChecked <$> getState) $ do
+ a
+ changeState $ \s -> s { indexChecked = True }
+
+{- Runs an action to update the branch, if it's not been updated before
+ - in this run of git-annex. -}
+runUpdateOnce :: Annex () -> Annex ()
+runUpdateOnce a = unlessM (branchUpdated <$> getState) $ do
+ a
+ disableUpdate
+
+{- Avoids updating the branch. A useful optimisation when the branch
+ - is known to have not changed, or git-annex won't be relying on info
+ - from it. -}
+disableUpdate :: Annex ()
+disableUpdate = changeState $ \s -> s { branchUpdated = True }
diff --git a/Annex/CatFile.hs b/Annex/CatFile.hs
new file mode 100644
index 000000000..812d032c6
--- /dev/null
+++ b/Annex/CatFile.hs
@@ -0,0 +1,139 @@
+{- git cat-file interface, with handle automatically stored in the Annex monad
+ -
+ - Copyright 2011-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Annex.CatFile (
+ catFile,
+ catObject,
+ catTree,
+ catObjectDetails,
+ catFileHandle,
+ catKey,
+ catKeyFile,
+ catKeyFileHEAD,
+) where
+
+import qualified Data.ByteString.Lazy as L
+import qualified Data.Map as M
+import System.PosixCompat.Types
+
+import Common.Annex
+import qualified Git
+import qualified Git.CatFile
+import qualified Annex
+import Git.Types
+import Git.FilePath
+import Git.FileMode
+import qualified Git.Ref
+
+catFile :: Git.Branch -> FilePath -> Annex L.ByteString
+catFile branch file = do
+ h <- catFileHandle
+ liftIO $ Git.CatFile.catFile h branch file
+
+catObject :: Git.Ref -> Annex L.ByteString
+catObject ref = do
+ h <- catFileHandle
+ liftIO $ Git.CatFile.catObject h ref
+
+catTree :: Git.Ref -> Annex [(FilePath, FileMode)]
+catTree ref = do
+ h <- catFileHandle
+ liftIO $ Git.CatFile.catTree h ref
+
+catObjectDetails :: Git.Ref -> Annex (Maybe (L.ByteString, Sha, ObjectType))
+catObjectDetails ref = do
+ h <- catFileHandle
+ liftIO $ Git.CatFile.catObjectDetails h ref
+
+{- There can be multiple index files, and a different cat-file is needed
+ - for each. This is selected by setting GIT_INDEX_FILE in the gitEnv. -}
+catFileHandle :: Annex Git.CatFile.CatFileHandle
+catFileHandle = do
+ m <- Annex.getState Annex.catfilehandles
+ indexfile <- fromMaybe "" . maybe Nothing (lookup "GIT_INDEX_FILE")
+ <$> fromRepo gitEnv
+ case M.lookup indexfile m of
+ Just h -> return h
+ Nothing -> do
+ h <- inRepo Git.CatFile.catFileStart
+ let m' = M.insert indexfile h m
+ Annex.changeState $ \s -> s { Annex.catfilehandles = m' }
+ return h
+
+{- From the Sha or Ref of a symlink back to the key.
+ -
+ - Requires a mode witness, to guarantee that the file is a symlink.
+ -}
+catKey :: Ref -> FileMode -> Annex (Maybe Key)
+catKey = catKey' True
+
+catKey' :: Bool -> Ref -> FileMode -> Annex (Maybe Key)
+catKey' modeguaranteed ref mode
+ | isSymLink mode = do
+ l <- fromInternalGitPath . encodeW8 . L.unpack <$> get
+ return $ if isLinkToAnnex l
+ then fileKey $ takeFileName l
+ else Nothing
+ | otherwise = return Nothing
+ where
+ -- If the mode is not guaranteed to be correct, avoid
+ -- buffering the whole file content, which might be large.
+ -- 8192 is enough if it really is a symlink.
+ get
+ | modeguaranteed = catObject ref
+ | otherwise = L.take 8192 <$> catObject ref
+
+{- Looks up the file mode corresponding to the Ref using the running
+ - cat-file.
+ -
+ - Currently this always has to look in HEAD, because cat-file --batch
+ - does not offer a way to specify that we want to look up a tree object
+ - in the index. So if the index has a file staged not as a symlink,
+ - and it is a symlink in head, the wrong mode is gotten.
+ - Also, we have to assume the file is a symlink if it's not yet committed
+ - to HEAD. For these reasons, modeguaranteed is not set.
+ -}
+catKeyChecked :: Bool -> Ref -> Annex (Maybe Key)
+catKeyChecked needhead ref@(Ref r) =
+ catKey' False ref =<< findmode <$> catTree treeref
+ where
+ pathparts = split "/" r
+ dir = intercalate "/" $ take (length pathparts - 1) pathparts
+ file = fromMaybe "" $ lastMaybe pathparts
+ treeref = Ref $ if needhead then "HEAD" ++ dir ++ "/" else dir ++ "/"
+ findmode = fromMaybe symLinkMode . headMaybe .
+ map snd . filter (\p -> fst p == file)
+
+{- From a file in the repository back to the key.
+ -
+ - Ideally, this should reflect the key that's staged in the index,
+ - not the key that's committed to HEAD. Unfortunately, git cat-file
+ - does not refresh the index file after it's started up, so things
+ - newly staged in the index won't show up. It does, however, notice
+ - when branches change.
+ -
+ - For command-line git-annex use, that doesn't matter. It's perfectly
+ - reasonable for things staged in the index after the currently running
+ - git-annex process to not be noticed by it. However, we do want to see
+ - what's in the index, since it may have uncommitted changes not in HEAD>
+ -
+ - For the assistant, this is much more of a problem, since it commits
+ - files and then needs to be able to immediately look up their keys.
+ - OTOH, the assistant doesn't keep changes staged in the index for very
+ - long at all before committing them -- and it won't look at the keys
+ - of files until after committing them.
+ -
+ - So, this gets info from the index, unless running as a daemon.
+ -}
+catKeyFile :: FilePath -> Annex (Maybe Key)
+catKeyFile f = ifM (Annex.getState Annex.daemon)
+ ( catKeyFileHEAD f
+ , catKeyChecked True $ Git.Ref.fileRef f
+ )
+
+catKeyFileHEAD :: FilePath -> Annex (Maybe Key)
+catKeyFileHEAD f = catKeyChecked False $ Git.Ref.fileFromRef Git.Ref.headRef f
diff --git a/Annex/CheckAttr.hs b/Annex/CheckAttr.hs
new file mode 100644
index 000000000..8eed9e804
--- /dev/null
+++ b/Annex/CheckAttr.hs
@@ -0,0 +1,35 @@
+{- git check-attr interface, with handle automatically stored in the Annex monad
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Annex.CheckAttr (
+ checkAttr,
+ checkAttrHandle
+) where
+
+import Common.Annex
+import qualified Git.CheckAttr as Git
+import qualified Annex
+
+{- All gitattributes used by git-annex. -}
+annexAttrs :: [Git.Attr]
+annexAttrs =
+ [ "annex.backend"
+ , "annex.numcopies"
+ ]
+
+checkAttr :: Git.Attr -> FilePath -> Annex String
+checkAttr attr file = do
+ h <- checkAttrHandle
+ liftIO $ Git.checkAttr h attr file
+
+checkAttrHandle :: Annex Git.CheckAttrHandle
+checkAttrHandle = maybe startup return =<< Annex.getState Annex.checkattrhandle
+ where
+ startup = do
+ h <- inRepo $ Git.checkAttrStart annexAttrs
+ Annex.changeState $ \s -> s { Annex.checkattrhandle = Just h }
+ return h
diff --git a/Annex/CheckIgnore.hs b/Annex/CheckIgnore.hs
new file mode 100644
index 000000000..d45e652bc
--- /dev/null
+++ b/Annex/CheckIgnore.hs
@@ -0,0 +1,32 @@
+{- git check-ignore interface, with handle automatically stored in
+ - the Annex monad
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Annex.CheckIgnore (
+ checkIgnored,
+ checkIgnoreHandle
+) where
+
+import Common.Annex
+import qualified Git.CheckIgnore as Git
+import qualified Annex
+
+checkIgnored :: FilePath -> Annex Bool
+checkIgnored file = go =<< checkIgnoreHandle
+ where
+ go Nothing = return False
+ go (Just h) = liftIO $ Git.checkIgnored h file
+
+checkIgnoreHandle :: Annex (Maybe Git.CheckIgnoreHandle)
+checkIgnoreHandle = maybe startup return =<< Annex.getState Annex.checkignorehandle
+ where
+ startup = do
+ v <- inRepo Git.checkIgnoreStart
+ when (isNothing v) $
+ warning "The installed version of git is too old for .gitignores to be honored by git-annex."
+ Annex.changeState $ \s -> s { Annex.checkignorehandle = Just v }
+ return v
diff --git a/Annex/Content.hs b/Annex/Content.hs
new file mode 100644
index 000000000..62f1b1ccb
--- /dev/null
+++ b/Annex/Content.hs
@@ -0,0 +1,529 @@
+{- git-annex file content managing
+ -
+ - Copyright 2010-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Annex.Content (
+ inAnnex,
+ inAnnexSafe,
+ inAnnexCheck,
+ lockContent,
+ getViaTmp,
+ getViaTmpChecked,
+ getViaTmpUnchecked,
+ withTmp,
+ checkDiskSpace,
+ moveAnnex,
+ sendAnnex,
+ prepSendAnnex,
+ removeAnnex,
+ fromAnnex,
+ moveBad,
+ getKeysPresent,
+ saveState,
+ downloadUrl,
+ preseedTmp,
+ freezeContent,
+ thawContent,
+ dirKeys,
+ withObjectLoc,
+) where
+
+import System.IO.Unsafe (unsafeInterleaveIO)
+import System.PosixCompat.Files
+
+import Common.Annex
+import Logs.Location
+import qualified Git
+import qualified Annex
+import qualified Annex.Queue
+import qualified Annex.Branch
+import Utility.DiskFree
+import Utility.FileMode
+import qualified Annex.Url as Url
+import Types.Key
+import Utility.DataUnits
+import Utility.CopyFile
+import Config
+import Git.SharedRepository
+import Annex.Perms
+import Annex.Link
+import Annex.Content.Direct
+import Annex.ReplaceFile
+import Annex.Exception
+
+{- Checks if a given key's content is currently present. -}
+inAnnex :: Key -> Annex Bool
+inAnnex key = inAnnexCheck key $ liftIO . doesFileExist
+
+{- Runs an arbitrary check on a key's content. -}
+inAnnexCheck :: Key -> (FilePath -> Annex Bool) -> Annex Bool
+inAnnexCheck key check = inAnnex' id False check key
+
+{- Generic inAnnex, handling both indirect and direct mode.
+ -
+ - In direct mode, at least one of the associated files must pass the
+ - check. Additionally, the file must be unmodified.
+ -}
+inAnnex' :: (a -> Bool) -> a -> (FilePath -> Annex a) -> Key -> Annex a
+inAnnex' isgood bad check key = withObjectLoc key checkindirect checkdirect
+ where
+ checkindirect loc = do
+ whenM (fromRepo Git.repoIsUrl) $
+ error "inAnnex cannot check remote repo"
+ check loc
+ checkdirect [] = return bad
+ checkdirect (loc:locs) = do
+ r <- check loc
+ if isgood r
+ then ifM (goodContent key loc)
+ ( return r
+ , checkdirect locs
+ )
+ else checkdirect locs
+
+{- A safer check; the key's content must not only be present, but
+ - is not in the process of being removed. -}
+inAnnexSafe :: Key -> Annex (Maybe Bool)
+inAnnexSafe = inAnnex' (fromMaybe False) (Just False) go
+ where
+ go f = liftIO $ openforlock f >>= check
+#ifndef mingw32_HOST_OS
+ openforlock f = catchMaybeIO $
+ openFd f ReadOnly Nothing defaultFileFlags
+#else
+ openforlock _ = return $ Just ()
+#endif
+ check Nothing = return is_missing
+#ifndef mingw32_HOST_OS
+ check (Just h) = do
+ v <- getLock h (ReadLock, AbsoluteSeek, 0, 0)
+ closeFd h
+ return $ case v of
+ Just _ -> is_locked
+ Nothing -> is_unlocked
+#else
+ check (Just _) = return is_unlocked
+#endif
+#ifndef mingw32_HOST_OS
+ is_locked = Nothing
+#endif
+ is_unlocked = Just True
+ is_missing = Just False
+
+{- Content is exclusively locked while running an action that might remove
+ - it. (If the content is not present, no locking is done.) -}
+lockContent :: Key -> Annex a -> Annex a
+#ifndef mingw32_HOST_OS
+lockContent key a = do
+ file <- calcRepo $ gitAnnexLocation key
+ bracketIO (openforlock file >>= lock) unlock (const a)
+ where
+ {- Since files are stored with the write bit disabled, have
+ - to fiddle with permissions to open for an exclusive lock. -}
+ openforlock f = catchMaybeIO $ ifM (doesFileExist f)
+ ( withModifiedFileMode f
+ (`unionFileModes` ownerWriteMode)
+ open
+ , open
+ )
+ where
+ open = openFd f ReadWrite Nothing defaultFileFlags
+ lock Nothing = return Nothing
+ lock (Just fd) = do
+ v <- tryIO $ setLock fd (WriteLock, AbsoluteSeek, 0, 0)
+ case v of
+ Left _ -> error "content is locked"
+ Right _ -> return $ Just fd
+ unlock Nothing = noop
+ unlock (Just l) = closeFd l
+#else
+lockContent _key a = a -- no locking for Windows!
+#endif
+
+{- Runs an action, passing it a temporary filename to get,
+ - and if the action succeeds, moves the temp file into
+ - the annex as a key's content. -}
+getViaTmp :: Key -> (FilePath -> Annex Bool) -> Annex Bool
+getViaTmp = getViaTmpChecked (return True)
+
+{- Like getViaTmp, but does not check that there is enough disk space
+ - for the incoming key. For use when the key content is already on disk
+ - and not being copied into place. -}
+getViaTmpUnchecked :: Key -> (FilePath -> Annex Bool) -> Annex Bool
+getViaTmpUnchecked = finishGetViaTmp (return True)
+
+getViaTmpChecked :: Annex Bool -> Key -> (FilePath -> Annex Bool) -> Annex Bool
+getViaTmpChecked check key action = do
+ tmp <- fromRepo $ gitAnnexTmpLocation key
+
+ -- Check that there is enough free disk space.
+ -- When the temp file already exists, count the space
+ -- it is using as free.
+ e <- liftIO $ doesFileExist tmp
+ alreadythere <- if e
+ then fromIntegral . fileSize <$> liftIO (getFileStatus tmp)
+ else return 0
+ ifM (checkDiskSpace Nothing key alreadythere)
+ ( do
+ when e $ thawContent tmp
+ finishGetViaTmp check key action
+ , return False
+ )
+
+finishGetViaTmp :: Annex Bool -> Key -> (FilePath -> Annex Bool) -> Annex Bool
+finishGetViaTmp check key action = do
+ tmpfile <- prepTmp key
+ ifM (action tmpfile <&&> check)
+ ( do
+ moveAnnex key tmpfile
+ logStatus key InfoPresent
+ return True
+ , do
+ -- the tmp file is left behind, in case caller wants
+ -- to resume its transfer
+ return False
+ )
+
+prepTmp :: Key -> Annex FilePath
+prepTmp key = do
+ tmp <- fromRepo $ gitAnnexTmpLocation key
+ createAnnexDirectory (parentDir tmp)
+ return tmp
+
+{- Creates a temp file, runs an action on it, and cleans up the temp file. -}
+withTmp :: Key -> (FilePath -> Annex a) -> Annex a
+withTmp key action = do
+ tmp <- prepTmp key
+ res <- action tmp
+ liftIO $ nukeFile tmp
+ return res
+
+{- Checks that there is disk space available to store a given key,
+ - in a destination (or the annex) printing a warning if not. -}
+checkDiskSpace :: Maybe FilePath -> Key -> Integer -> Annex Bool
+checkDiskSpace destination key alreadythere = do
+ reserve <- annexDiskReserve <$> Annex.getGitConfig
+ free <- liftIO . getDiskFree =<< dir
+ force <- Annex.getState Annex.force
+ case (free, keySize key) of
+ (Just have, Just need) -> do
+ let ok = (need + reserve <= have + alreadythere) || force
+ unless ok $
+ needmorespace (need + reserve - have - alreadythere)
+ return ok
+ _ -> return True
+ where
+ dir = maybe (fromRepo gitAnnexDir) return destination
+ needmorespace n =
+ warning $ "not enough free space, need " ++
+ roughSize storageUnits True n ++
+ " more" ++ forcemsg
+ forcemsg = " (use --force to override this check or adjust annex.diskreserve)"
+
+{- Moves a key's content into .git/annex/objects/
+ -
+ - In direct mode, moves it to the associated file, or files.
+ -
+ - What if the key there already has content? This could happen for
+ - various reasons; perhaps the same content is being annexed again.
+ - Perhaps there has been a hash collision generating the keys.
+ -
+ - The current strategy is to assume that in this case it's safe to delete
+ - one of the two copies of the content; and the one already in the annex
+ - is left there, assuming it's the original, canonical copy.
+ -
+ - I considered being more paranoid, and checking that both files had
+ - the same content. Decided against it because A) users explicitly choose
+ - a backend based on its hashing properties and so if they're dealing
+ - with colliding files it's their own fault and B) adding such a check
+ - would not catch all cases of colliding keys. For example, perhaps
+ - a remote has a key; if it's then added again with different content then
+ - the overall system now has two different peices of content for that
+ - key, and one of them will probably get deleted later. So, adding the
+ - check here would only raise expectations that git-annex cannot truely
+ - meet.
+ -}
+moveAnnex :: Key -> FilePath -> Annex ()
+moveAnnex key src = withObjectLoc key storeobject storedirect
+ where
+ storeobject dest = ifM (liftIO $ doesFileExist dest)
+ ( alreadyhave
+ , modifyContent dest $ do
+ liftIO $ moveFile src dest
+ freezeContent dest
+ )
+ storeindirect = storeobject =<< calcRepo (gitAnnexLocation key)
+
+ {- In direct mode, the associated file's content may be locally
+ - modified. In that case, it's preserved. However, the content
+ - we're moving into the annex may be the only extant copy, so
+ - it's important we not lose it. So, when the key's content
+ - cannot be moved to any associated file, it's stored in indirect
+ - mode.
+ -}
+ storedirect = storedirect' storeindirect
+ storedirect' fallback [] = fallback
+ storedirect' fallback (f:fs) = do
+ thawContent src
+ v <- isAnnexLink f
+ if Just key == v
+ then do
+ updateInodeCache key src
+ replaceFile f $ liftIO . moveFile src
+ chmodContent f
+ forM_ fs $
+ addContentWhenNotPresent key f
+ else ifM (goodContent key f)
+ ( storedirect' alreadyhave fs
+ , storedirect' fallback fs
+ )
+
+ alreadyhave = liftIO $ removeFile src
+
+{- Runs an action to transfer an object's content.
+ -
+ - In direct mode, it's possible for the file to change as it's being sent.
+ - If this happens, runs the rollback action and returns False. The
+ - rollback action should remove the data that was transferred.
+ -}
+sendAnnex :: Key -> Annex () -> (FilePath -> Annex Bool) -> Annex Bool
+sendAnnex key rollback sendobject = go =<< prepSendAnnex key
+ where
+ go Nothing = return False
+ go (Just (f, checksuccess)) = do
+ r <- sendobject f
+ ifM checksuccess
+ ( return r
+ , do
+ rollback
+ return False
+ )
+
+{- Returns a file that contains an object's content,
+ - and an check to run after the transfer is complete.
+ -
+ - In direct mode, it's possible for the file to change as it's being sent,
+ - and the check detects this case and returns False.
+ -
+ - Note that the returned check action is, in some cases, run in the
+ - Annex monad of the remote that is receiving the object, rather than
+ - the sender. So it cannot rely on Annex state.
+ -}
+prepSendAnnex :: Key -> Annex (Maybe (FilePath, Annex Bool))
+prepSendAnnex key = withObjectLoc key indirect direct
+ where
+ indirect f = return $ Just (f, return True)
+ direct [] = return Nothing
+ direct (f:fs) = do
+ cache <- recordedInodeCache key
+ -- check that we have a good file
+ ifM (sameInodeCache f cache)
+ ( return $ Just (f, sameInodeCache f cache)
+ , direct fs
+ )
+
+{- Performs an action, passing it the location to use for a key's content.
+ -
+ - In direct mode, the associated files will be passed. But, if there are
+ - no associated files for a key, the indirect mode action will be
+ - performed instead. -}
+withObjectLoc :: Key -> (FilePath -> Annex a) -> ([FilePath] -> Annex a) -> Annex a
+withObjectLoc key indirect direct = ifM isDirect
+ ( do
+ fs <- associatedFiles key
+ if null fs
+ then goindirect
+ else direct fs
+ , goindirect
+ )
+ where
+ goindirect = indirect =<< calcRepo (gitAnnexLocation key)
+
+cleanObjectLoc :: Key -> Annex () -> Annex ()
+cleanObjectLoc key cleaner = do
+ file <- calcRepo $ gitAnnexLocation key
+ void $ tryAnnexIO $ thawContentDir file
+ cleaner
+ liftIO $ removeparents file (3 :: Int)
+ where
+ removeparents _ 0 = noop
+ removeparents file n = do
+ let dir = parentDir file
+ maybe noop (const $ removeparents dir (n-1))
+ <=< catchMaybeIO $ removeDirectory dir
+
+{- Removes a key's file from .git/annex/objects/
+ -
+ - In direct mode, deletes the associated files or files, and replaces
+ - them with symlinks. -}
+removeAnnex :: Key -> Annex ()
+removeAnnex key = withObjectLoc key remove removedirect
+ where
+ remove file = cleanObjectLoc key $ do
+ liftIO $ nukeFile file
+ removeInodeCache key
+ removedirect fs = do
+ cache <- recordedInodeCache key
+ removeInodeCache key
+ mapM_ (resetfile cache) fs
+ resetfile cache f = whenM (sameInodeCache f cache) $ do
+ l <- inRepo $ gitAnnexLink f key
+ top <- fromRepo Git.repoPath
+ cwd <- liftIO getCurrentDirectory
+ let top' = fromMaybe top $ absNormPath cwd top
+ let l' = relPathDirToFile top' (fromMaybe l $ absNormPath top' l)
+ replaceFile f $ makeAnnexLink l'
+
+{- Moves a key's file out of .git/annex/objects/ -}
+fromAnnex :: Key -> FilePath -> Annex ()
+fromAnnex key dest = cleanObjectLoc key $ do
+ file <- calcRepo $ gitAnnexLocation key
+ thawContent file
+ liftIO $ moveFile file dest
+
+{- Moves a key out of .git/annex/objects/ into .git/annex/bad, and
+ - returns the file it was moved to. -}
+moveBad :: Key -> Annex FilePath
+moveBad key = do
+ src <- calcRepo $ gitAnnexLocation key
+ bad <- fromRepo gitAnnexBadDir
+ let dest = bad </> takeFileName src
+ createAnnexDirectory (parentDir dest)
+ cleanObjectLoc key $
+ liftIO $ moveFile src dest
+ logStatus key InfoMissing
+ return dest
+
+{- List of keys whose content exists in the annex. -}
+getKeysPresent :: Annex [Key]
+getKeysPresent = do
+ direct <- isDirect
+ dir <- fromRepo gitAnnexObjectDir
+ liftIO $ traverse direct (2 :: Int) dir
+ where
+ traverse direct depth dir = do
+ contents <- catchDefaultIO [] (dirContents dir)
+ if depth == 0
+ then do
+ contents' <- filterM (present direct) contents
+ let keys = mapMaybe (fileKey . takeFileName) contents'
+ continue keys []
+ else do
+ let deeper = traverse direct (depth - 1)
+ continue [] (map deeper contents)
+ continue keys [] = return keys
+ continue keys (a:as) = do
+ {- Force lazy traversal with unsafeInterleaveIO. -}
+ morekeys <- unsafeInterleaveIO a
+ continue (morekeys++keys) as
+
+ {- In indirect mode, look for the key. In direct mode,
+ - the inode cache file is only present when a key's content
+ - is present. -}
+ present False d = doesFileExist $ contentfile d
+ present True d = doesFileExist $ contentfile d ++ ".cache"
+ contentfile d = d </> takeFileName d
+
+{- Things to do to record changes to content when shutting down.
+ -
+ - It's acceptable to avoid committing changes to the branch,
+ - especially if performing a short-lived action.
+ -}
+saveState :: Bool -> Annex ()
+saveState nocommit = doSideAction $ do
+ Annex.Queue.flush
+ unless nocommit $
+ whenM (annexAlwaysCommit <$> Annex.getGitConfig) $
+ Annex.Branch.commit "update"
+
+{- Downloads content from any of a list of urls. -}
+downloadUrl :: [Url.URLString] -> FilePath -> Annex Bool
+downloadUrl urls file = go =<< annexWebDownloadCommand <$> Annex.getGitConfig
+ where
+ go Nothing = do
+ opts <- map Param . annexWebOptions <$> Annex.getGitConfig
+ headers <- getHttpHeaders
+ anyM (\u -> Url.withUserAgent $ Url.download u headers opts file) urls
+ go (Just basecmd) = liftIO $ anyM (downloadcmd basecmd) urls
+ downloadcmd basecmd url =
+ boolSystem "sh" [Param "-c", Param $ gencmd url basecmd]
+ <&&> doesFileExist file
+ gencmd url = massReplace
+ [ ("%file", shellEscape file)
+ , ("%url", shellEscape url)
+ ]
+
+{- Copies a key's content, when present, to a temp file.
+ - This is used to speed up some rsyncs. -}
+preseedTmp :: Key -> FilePath -> Annex Bool
+preseedTmp key file = go =<< inAnnex key
+ where
+ go False = return False
+ go True = do
+ ok <- copy
+ when ok $ thawContent file
+ return ok
+ copy = ifM (liftIO $ doesFileExist file)
+ ( return True
+ , do
+ s <- calcRepo $ gitAnnexLocation key
+ liftIO $ copyFileExternal s file
+ )
+
+{- Blocks writing to an annexed file, and modifies file permissions to
+ - allow reading it, per core.sharedRepository setting. -}
+freezeContent :: FilePath -> Annex ()
+freezeContent file = unlessM crippledFileSystem $
+ liftIO . go =<< fromRepo getSharedRepository
+ where
+ go GroupShared = modifyFileMode file $
+ removeModes writeModes .
+ addModes [ownerReadMode, groupReadMode]
+ go AllShared = modifyFileMode file $
+ removeModes writeModes .
+ addModes readModes
+ go _ = modifyFileMode file $
+ removeModes writeModes .
+ addModes [ownerReadMode]
+
+{- Adjusts read mode of annexed file per core.sharedRepository setting. -}
+chmodContent :: FilePath -> Annex ()
+chmodContent file = unlessM crippledFileSystem $
+ liftIO . go =<< fromRepo getSharedRepository
+ where
+ go GroupShared = modifyFileMode file $
+ addModes [ownerReadMode, groupReadMode]
+ go AllShared = modifyFileMode file $
+ addModes readModes
+ go _ = modifyFileMode file $
+ addModes [ownerReadMode]
+
+{- Allows writing to an annexed file that freezeContent was called on
+ - before. -}
+thawContent :: FilePath -> Annex ()
+thawContent file = unlessM crippledFileSystem $
+ liftIO . go =<< fromRepo getSharedRepository
+ where
+ go GroupShared = groupWriteRead file
+ go AllShared = groupWriteRead file
+ go _ = allowWrite file
+
+{- Finds files directly inside a directory like gitAnnexBadDir
+ - (not in subdirectories) and returns the corresponding keys. -}
+dirKeys :: (Git.Repo -> FilePath) -> Annex [Key]
+dirKeys dirspec = do
+ dir <- fromRepo dirspec
+ ifM (liftIO $ doesDirectoryExist dir)
+ ( do
+ contents <- liftIO $ getDirectoryContents dir
+ files <- liftIO $ filterM doesFileExist $
+ map (dir </>) contents
+ return $ mapMaybe (fileKey . takeFileName) files
+ , return []
+ )
+
diff --git a/Annex/Content/Direct.hs b/Annex/Content/Direct.hs
new file mode 100644
index 000000000..a5d71288b
--- /dev/null
+++ b/Annex/Content/Direct.hs
@@ -0,0 +1,259 @@
+{- git-annex file content managing for direct mode
+ -
+ - Copyright 2012-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Annex.Content.Direct (
+ associatedFiles,
+ associatedFilesRelative,
+ removeAssociatedFile,
+ removeAssociatedFileUnchecked,
+ removeAssociatedFiles,
+ addAssociatedFile,
+ goodContent,
+ recordedInodeCache,
+ updateInodeCache,
+ addInodeCache,
+ writeInodeCache,
+ compareInodeCaches,
+ compareInodeCachesWith,
+ sameInodeCache,
+ elemInodeCaches,
+ sameFileStatus,
+ removeInodeCache,
+ toInodeCache,
+ inodesChanged,
+ createInodeSentinalFile,
+ addContentWhenNotPresent,
+) where
+
+import Common.Annex
+import qualified Annex
+import Annex.Perms
+import qualified Git
+import Utility.Tmp
+import Logs.Location
+import Utility.InodeCache
+import Utility.CopyFile
+import Annex.ReplaceFile
+import Annex.Link
+
+{- Absolute FilePaths of Files in the tree that are associated with a key. -}
+associatedFiles :: Key -> Annex [FilePath]
+associatedFiles key = do
+ files <- associatedFilesRelative key
+ top <- fromRepo Git.repoPath
+ return $ map (top </>) files
+
+{- List of files in the tree that are associated with a key, relative to
+ - the top of the repo. -}
+associatedFilesRelative :: Key -> Annex [FilePath]
+associatedFilesRelative key = do
+ mapping <- calcRepo $ gitAnnexMapping key
+ liftIO $ catchDefaultIO [] $ do
+ h <- openFile mapping ReadMode
+ fileEncoding h
+ lines <$> hGetContents h
+
+{- Changes the associated files information for a key, applying a
+ - transformation to the list. Returns new associatedFiles value. -}
+changeAssociatedFiles :: Key -> ([FilePath] -> [FilePath]) -> Annex [FilePath]
+changeAssociatedFiles key transform = do
+ mapping <- calcRepo $ gitAnnexMapping key
+ files <- associatedFilesRelative key
+ let files' = transform files
+ when (files /= files') $ do
+ modifyContent mapping $
+ liftIO $ viaTmp write mapping $ unlines files'
+ top <- fromRepo Git.repoPath
+ return $ map (top </>) files'
+ where
+ write file content = do
+ h <- openFile file WriteMode
+ fileEncoding h
+ hPutStr h content
+ hClose h
+
+{- Removes the list of associated files. -}
+removeAssociatedFiles :: Key -> Annex ()
+removeAssociatedFiles key = do
+ mapping <- calcRepo $ gitAnnexMapping key
+ modifyContent mapping $
+ liftIO $ nukeFile mapping
+
+{- Removes an associated file. Returns new associatedFiles value.
+ - Checks if this was the last copy of the object, and updates location
+ - log. -}
+removeAssociatedFile :: Key -> FilePath -> Annex [FilePath]
+removeAssociatedFile key file = do
+ fs <- removeAssociatedFileUnchecked key file
+ when (null fs) $
+ logStatus key InfoMissing
+ return fs
+
+{- Removes an associated file. Returns new associatedFiles value. -}
+removeAssociatedFileUnchecked :: Key -> FilePath -> Annex [FilePath]
+removeAssociatedFileUnchecked key file = do
+ file' <- normaliseAssociatedFile file
+ changeAssociatedFiles key $ filter (/= file')
+
+{- Adds an associated file. Returns new associatedFiles value. -}
+addAssociatedFile :: Key -> FilePath -> Annex [FilePath]
+addAssociatedFile key file = do
+ file' <- normaliseAssociatedFile file
+ changeAssociatedFiles key $ \files ->
+ if file' `elem` files
+ then files
+ else file':files
+
+{- Associated files are always stored relative to the top of the repository.
+ - The input FilePath is relative to the CWD, or is absolute. -}
+normaliseAssociatedFile :: FilePath -> Annex FilePath
+normaliseAssociatedFile file = do
+ top <- fromRepo Git.repoPath
+ liftIO $ relPathDirToFile top <$> absPath file
+
+{- Checks if a file in the tree, associated with a key, has not been modified.
+ -
+ - To avoid needing to fsck the file's content, which can involve an
+ - expensive checksum, this relies on a cache that contains the file's
+ - expected mtime and inode.
+ -}
+goodContent :: Key -> FilePath -> Annex Bool
+goodContent key file = sameInodeCache file =<< recordedInodeCache key
+
+{- Gets the recorded inode cache for a key.
+ -
+ - A key can be associated with multiple files, so may return more than
+ - one. -}
+recordedInodeCache :: Key -> Annex [InodeCache]
+recordedInodeCache key = withInodeCacheFile key $ \f ->
+ liftIO $ catchDefaultIO [] $
+ mapMaybe readInodeCache . lines <$> readFileStrict f
+
+{- Caches an inode for a file.
+ -
+ - Anything else already cached is preserved.
+ -}
+updateInodeCache :: Key -> FilePath -> Annex ()
+updateInodeCache key file = maybe noop (addInodeCache key)
+ =<< liftIO (genInodeCache file)
+
+{- Adds another inode to the cache for a key. -}
+addInodeCache :: Key -> InodeCache -> Annex ()
+addInodeCache key cache = do
+ oldcaches <- recordedInodeCache key
+ unlessM (elemInodeCaches cache oldcaches) $
+ writeInodeCache key (cache:oldcaches)
+
+{- Writes inode cache for a key. -}
+writeInodeCache :: Key -> [InodeCache] -> Annex ()
+writeInodeCache key caches = withInodeCacheFile key $ \f ->
+ modifyContent f $
+ liftIO $ writeFile f $
+ unlines $ map showInodeCache caches
+
+{- Removes an inode cache. -}
+removeInodeCache :: Key -> Annex ()
+removeInodeCache key = withInodeCacheFile key $ \f ->
+ modifyContent f $
+ liftIO $ nukeFile f
+
+withInodeCacheFile :: Key -> (FilePath -> Annex a) -> Annex a
+withInodeCacheFile key a = a =<< calcRepo (gitAnnexInodeCache key)
+
+{- Checks if a InodeCache matches the current version of a file. -}
+sameInodeCache :: FilePath -> [InodeCache] -> Annex Bool
+sameInodeCache _ [] = return False
+sameInodeCache file old = go =<< liftIO (genInodeCache file)
+ where
+ go Nothing = return False
+ go (Just curr) = elemInodeCaches curr old
+
+{- Checks if a FileStatus matches the recorded InodeCache of a file. -}
+sameFileStatus :: Key -> FileStatus -> Annex Bool
+sameFileStatus key status = do
+ old <- recordedInodeCache key
+ let curr = toInodeCache status
+ case (old, curr) of
+ (_, Just c) -> elemInodeCaches c old
+ ([], Nothing) -> return True
+ _ -> return False
+
+{- If the inodes have changed, only the size and mtime are compared. -}
+compareInodeCaches :: InodeCache -> InodeCache -> Annex Bool
+compareInodeCaches x y
+ | compareStrong x y = return True
+ | otherwise = ifM inodesChanged
+ ( return $ compareWeak x y
+ , return False
+ )
+
+elemInodeCaches :: InodeCache -> [InodeCache] -> Annex Bool
+elemInodeCaches _ [] = return False
+elemInodeCaches c (l:ls) = ifM (compareInodeCaches c l)
+ ( return True
+ , elemInodeCaches c ls
+ )
+
+compareInodeCachesWith :: Annex InodeComparisonType
+compareInodeCachesWith = ifM inodesChanged ( return Weakly, return Strongly )
+
+{- Copies the contentfile to the associated file, if the associated
+ - file has no content. If the associated file does have content,
+ - even if the content differs, it's left unchanged. -}
+addContentWhenNotPresent :: Key -> FilePath -> FilePath -> Annex ()
+addContentWhenNotPresent key contentfile associatedfile = do
+ v <- isAnnexLink associatedfile
+ when (Just key == v) $
+ replaceFile associatedfile $
+ liftIO . void . copyFileExternal contentfile
+ updateInodeCache key associatedfile
+
+{- Some filesystems get new inodes each time they are mounted.
+ - In order to work on such a filesystem, a sentinal file is used to detect
+ - when the inodes have changed.
+ -
+ - If the sentinal file does not exist, we have to assume that the
+ - inodes have changed.
+ -}
+inodesChanged :: Annex Bool
+inodesChanged = maybe calc return =<< Annex.getState Annex.inodeschanged
+ where
+ calc = do
+ scache <- liftIO . genInodeCache
+ =<< fromRepo gitAnnexInodeSentinal
+ scached <- readInodeSentinalFile
+ let changed = case (scache, scached) of
+ (Just c1, Just c2) -> not $ compareStrong c1 c2
+ _ -> True
+ Annex.changeState $ \s -> s { Annex.inodeschanged = Just changed }
+ return changed
+
+readInodeSentinalFile :: Annex (Maybe InodeCache)
+readInodeSentinalFile = do
+ sentinalcachefile <- fromRepo gitAnnexInodeSentinalCache
+ liftIO $ catchDefaultIO Nothing $
+ readInodeCache <$> readFile sentinalcachefile
+
+writeInodeSentinalFile :: Annex ()
+writeInodeSentinalFile = do
+ sentinalfile <- fromRepo gitAnnexInodeSentinal
+ createAnnexDirectory (parentDir sentinalfile)
+ sentinalcachefile <- fromRepo gitAnnexInodeSentinalCache
+ liftIO $ writeFile sentinalfile ""
+ liftIO $ maybe noop (writeFile sentinalcachefile . showInodeCache)
+ =<< genInodeCache sentinalfile
+
+{- The sentinal file is only created when first initializing a repository.
+ - If there are any annexed objects in the repository already, creating
+ - the file would invalidate their inode caches. -}
+createInodeSentinalFile :: Annex ()
+createInodeSentinalFile =
+ unlessM (alreadyexists <||> hasobjects)
+ writeInodeSentinalFile
+ where
+ alreadyexists = isJust <$> readInodeSentinalFile
+ hasobjects = liftIO . doesDirectoryExist =<< fromRepo gitAnnexObjectDir
diff --git a/Annex/Direct.hs b/Annex/Direct.hs
new file mode 100644
index 000000000..3fa5f9362
--- /dev/null
+++ b/Annex/Direct.hs
@@ -0,0 +1,306 @@
+{- git-annex direct mode
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Annex.Direct where
+
+import Common.Annex
+import qualified Annex
+import qualified Git
+import qualified Git.LsFiles
+import qualified Git.Merge
+import qualified Git.DiffTree as DiffTree
+import qualified Git.Config
+import qualified Git.Ref
+import qualified Git.Branch
+import Git.Sha
+import Git.FilePath
+import Git.Types
+import Config
+import Annex.CatFile
+import qualified Annex.Queue
+import Logs.Location
+import Backend
+import Types.KeySource
+import Annex.Content
+import Annex.Content.Direct
+import Annex.Link
+import Utility.InodeCache
+import Utility.CopyFile
+import Annex.Perms
+import Annex.ReplaceFile
+import Annex.Exception
+
+{- Uses git ls-files to find files that need to be committed, and stages
+ - them into the index. Returns True if some changes were staged. -}
+stageDirect :: Annex Bool
+stageDirect = do
+ Annex.Queue.flush
+ top <- fromRepo Git.repoPath
+ (l, cleanup) <- inRepo $ Git.LsFiles.stagedOthersDetails [top]
+ forM_ l go
+ void $ liftIO cleanup
+ staged <- Annex.Queue.size
+ Annex.Queue.flush
+ return $ staged /= 0
+ where
+ {- Determine what kind of modified or deleted file this is, as
+ - efficiently as we can, by getting any key that's associated
+ - with it in git, as well as its stat info. -}
+ go (file, Just sha, Just mode) = do
+ shakey <- catKey sha mode
+ mstat <- liftIO $ catchMaybeIO $ getSymbolicLinkStatus file
+ filekey <- isAnnexLink file
+ case (shakey, filekey, mstat, toInodeCache =<< mstat) of
+ (_, Just key, _, _)
+ | shakey == filekey -> noop
+ {- A changed symlink. -}
+ | otherwise -> stageannexlink file key
+ (Just key, _, _, Just cache) -> do
+ {- All direct mode files will show as
+ - modified, so compare the cache to see if
+ - it really was. -}
+ oldcache <- recordedInodeCache key
+ case oldcache of
+ [] -> modifiedannexed file key cache
+ _ -> unlessM (elemInodeCaches cache oldcache) $
+ modifiedannexed file key cache
+ (Just key, _, Nothing, _) -> deletedannexed file key
+ (Nothing, _, Nothing, _) -> deletegit file
+ (_, _, Just _, _) -> addgit file
+ go _ = noop
+
+ modifiedannexed file oldkey cache = do
+ void $ removeAssociatedFile oldkey file
+ void $ addDirect file cache
+
+ deletedannexed file key = do
+ void $ removeAssociatedFile key file
+ deletegit file
+
+ stageannexlink file key = do
+ l <- inRepo $ gitAnnexLink file key
+ stageSymlink file =<< hashSymlink l
+ void $ addAssociatedFile key file
+
+ addgit file = Annex.Queue.addCommand "add" [Param "-f"] [file]
+
+ deletegit file = Annex.Queue.addCommand "rm" [Param "-f"] [file]
+
+{- Adds a file to the annex in direct mode. Can fail, if the file is
+ - modified or deleted while it's being added. -}
+addDirect :: FilePath -> InodeCache -> Annex Bool
+addDirect file cache = do
+ showStart "add" file
+ let source = KeySource
+ { keyFilename = file
+ , contentLocation = file
+ , inodeCache = Just cache
+ }
+ got =<< genKey source =<< chooseBackend file
+ where
+ got Nothing = do
+ showEndFail
+ return False
+ got (Just (key, _)) = ifM (sameInodeCache file [cache])
+ ( do
+ l <- inRepo $ gitAnnexLink file key
+ stageSymlink file =<< hashSymlink l
+ addInodeCache key cache
+ void $ addAssociatedFile key file
+ logStatus key InfoPresent
+ showEndOk
+ return True
+ , do
+ showEndFail
+ return False
+ )
+
+{- In direct mode, git merge would usually refuse to do anything, since it
+ - sees present direct mode files as type changed files. To avoid this,
+ - merge is run with the work tree set to a temp directory.
+ -
+ - This should only be used once any changes to the real working tree have
+ - already been committed, because it overwrites files in the working tree.
+ -}
+mergeDirect :: FilePath -> Git.Ref -> Git.Repo -> IO Bool
+mergeDirect d branch g = do
+ whenM (doesDirectoryExist d) $
+ removeDirectoryRecursive d
+ createDirectoryIfMissing True d
+ let g' = g { location = Local { gitdir = Git.localGitDir g, worktree = Just d } }
+ Git.Merge.mergeNonInteractive branch g'
+
+{- Cleans up after a direct mode merge. The merge must have been committed,
+ - and the commit sha passed in, along with the old sha of the tree
+ - before the merge. Uses git diff-tree to find files that changed between
+ - the two shas, and applies those changes to the work tree.
+ -
+ - There are really only two types of changes: An old item can be deleted,
+ - or a new item added. Two passes are made, first deleting and then
+ - adding. This is to handle cases where eg, a file is deleted and a
+ - directory is added. The diff-tree output may list these in the opposite
+ - order, but we cannot really add the directory until the file with the
+ - same name is remvoed.
+ -}
+mergeDirectCleanup :: FilePath -> Git.Ref -> Git.Ref -> Annex ()
+mergeDirectCleanup d oldsha newsha = do
+ (items, cleanup) <- inRepo $ DiffTree.diffTreeRecursive oldsha newsha
+ makeabs <- flip fromTopFilePath <$> gitRepo
+ let fsitems = zip (map (makeabs . DiffTree.file) items) items
+ forM_ fsitems $
+ go DiffTree.srcsha DiffTree.srcmode moveout moveout_raw
+ forM_ fsitems $
+ go DiffTree.dstsha DiffTree.dstmode movein movein_raw
+ void $ liftIO cleanup
+ liftIO $ removeDirectoryRecursive d
+ where
+ go getsha getmode a araw (f, item)
+ | getsha item == nullSha = noop
+ | otherwise = void $
+ tryAnnex . maybe (araw f) (\k -> void $ a k f)
+ =<< catKey (getsha item) (getmode item)
+
+ moveout k f = removeDirect k f
+
+ {- Files deleted by the merge are removed from the work tree.
+ - Empty work tree directories are removed, per git behavior. -}
+ moveout_raw f = liftIO $ do
+ nukeFile f
+ void $ tryIO $ removeDirectory $ parentDir f
+
+ {- If the file is already present, with the right content for the
+ - key, it's left alone. Otherwise, create the symlink and then
+ - if possible, replace it with the content. -}
+ movein k f = unlessM (goodContent k f) $ do
+ l <- inRepo $ gitAnnexLink f k
+ replaceFile f $ makeAnnexLink l
+ toDirect k f
+
+ {- Any new, modified, or renamed files were written to the temp
+ - directory by the merge, and are moved to the real work tree. -}
+ movein_raw f = liftIO $ do
+ createDirectoryIfMissing True $ parentDir f
+ void $ tryIO $ rename (d </> f) f
+
+{- If possible, converts a symlink in the working tree into a direct
+ - mode file. If the content is not available, leaves the symlink
+ - unchanged. -}
+toDirect :: Key -> FilePath -> Annex ()
+toDirect k f = fromMaybe noop =<< toDirectGen k f
+
+toDirectGen :: Key -> FilePath -> Annex (Maybe (Annex ()))
+toDirectGen k f = do
+ loc <- calcRepo $ gitAnnexLocation k
+ ifM (liftIO $ doesFileExist loc)
+ ( return $ Just $ fromindirect loc
+ , do
+ {- Copy content from another direct file. -}
+ absf <- liftIO $ absPath f
+ dlocs <- filterM (goodContent k) =<<
+ filterM (\l -> isNothing <$> getAnnexLinkTarget l) =<<
+ (filter (/= absf) <$> addAssociatedFile k f)
+ case dlocs of
+ [] -> return Nothing
+ (dloc:_) -> return $ Just $ fromdirect dloc
+ )
+ where
+ fromindirect loc = do
+ {- Move content from annex to direct file. -}
+ updateInodeCache k loc
+ void $ addAssociatedFile k f
+ modifyContent loc $ do
+ thawContent loc
+ replaceFile f $ liftIO . moveFile loc
+ fromdirect loc = do
+ replaceFile f $
+ liftIO . void . copyFileExternal loc
+ updateInodeCache k f
+
+{- Removes a direct mode file, while retaining its content in the annex
+ - (unless its content has already been changed). -}
+removeDirect :: Key -> FilePath -> Annex ()
+removeDirect k f = do
+ void $ removeAssociatedFileUnchecked k f
+ unlessM (inAnnex k) $
+ ifM (goodContent k f)
+ ( moveAnnex k f
+ , logStatus k InfoMissing
+ )
+ liftIO $ do
+ nukeFile f
+ void $ tryIO $ removeDirectory $ parentDir f
+
+{- Called when a direct mode file has been changed. Its old content may be
+ - lost. -}
+changedDirect :: Key -> FilePath -> Annex ()
+changedDirect oldk f = do
+ locs <- removeAssociatedFile oldk f
+ whenM (pure (null locs) <&&> not <$> inAnnex oldk) $
+ logStatus oldk InfoMissing
+
+{- Enable/disable direct mode. -}
+setDirect :: Bool -> Annex ()
+setDirect wantdirect = do
+ if wantdirect
+ then do
+ switchHEAD
+ setbare
+ else do
+ setbare
+ switchHEADBack
+ setConfig (annexConfig "direct") val
+ Annex.changeGitConfig $ \c -> c { annexDirect = wantdirect }
+ where
+ val = Git.Config.boolConfig wantdirect
+ setbare = setConfig (ConfigKey Git.Config.coreBare) val
+
+{- Since direct mode sets core.bare=true, incoming pushes could change
+ - the currently checked out branch. To avoid this problem, HEAD
+ - is changed to a internal ref that nothing is going to push to.
+ -
+ - For refs/heads/master, use refs/heads/annex/direct/master;
+ - this way things that show HEAD (eg shell prompts) will
+ - hopefully show just "master". -}
+directBranch :: Ref -> Ref
+directBranch orighead = case split "/" $ show orighead of
+ ("refs":"heads":"annex":"direct":_) -> orighead
+ ("refs":"heads":rest) ->
+ Ref $ "refs/heads/annex/direct/" ++ intercalate "/" rest
+ _ -> Ref $ "refs/heads/" ++ show (Git.Ref.base orighead)
+
+{- Converts a directBranch back to the original branch.
+ -
+ - Any other ref is left unchanged.
+ -}
+fromDirectBranch :: Ref -> Ref
+fromDirectBranch directhead = case split "/" $ show directhead of
+ ("refs":"heads":"annex":"direct":rest) ->
+ Ref $ "refs/heads/" ++ intercalate "/" rest
+ _ -> directhead
+
+switchHEAD :: Annex ()
+switchHEAD = maybe noop switch =<< inRepo Git.Branch.currentUnsafe
+ where
+ switch orighead = do
+ let newhead = directBranch orighead
+ maybe noop (inRepo . Git.Branch.update newhead)
+ =<< inRepo (Git.Ref.sha orighead)
+ inRepo $ Git.Branch.checkout newhead
+
+switchHEADBack :: Annex ()
+switchHEADBack = maybe noop switch =<< inRepo Git.Branch.currentUnsafe
+ where
+ switch currhead = do
+ let orighead = fromDirectBranch currhead
+ v <- inRepo $ Git.Ref.sha currhead
+ case v of
+ Just headsha
+ | orighead /= currhead -> do
+ inRepo $ Git.Branch.update orighead headsha
+ inRepo $ Git.Branch.checkout orighead
+ inRepo $ Git.Branch.delete currhead
+ _ -> inRepo $ Git.Branch.checkout orighead
diff --git a/Annex/Direct/Fixup.hs b/Annex/Direct/Fixup.hs
new file mode 100644
index 000000000..13485242a
--- /dev/null
+++ b/Annex/Direct/Fixup.hs
@@ -0,0 +1,31 @@
+{- git-annex direct mode guard fixup
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Annex.Direct.Fixup where
+
+import Git.Types
+import Git.Config
+import qualified Git.Construct as Construct
+import Utility.Path
+import Utility.SafeCommand
+
+{- Direct mode repos have core.bare=true, but are not really bare.
+ - Fix up the Repo to be a non-bare repo, and arrange for git commands
+ - run by git-annex to be passed parameters that override this setting. -}
+fixupDirect :: Repo -> IO Repo
+fixupDirect r@(Repo { location = l@(Local { gitdir = d, worktree = Nothing }) }) = do
+ let r' = r
+ { location = l { worktree = Just (parentDir d) }
+ , gitGlobalOpts = gitGlobalOpts r ++
+ [ Param "-c"
+ , Param $ coreBare ++ "=" ++ boolConfig False
+ ]
+ }
+ -- Recalc now that the worktree is correct.
+ rs' <- Construct.fromRemotes r'
+ return $ r' { remotes = rs' }
+fixupDirect r = return r
diff --git a/Annex/Environment.hs b/Annex/Environment.hs
new file mode 100644
index 000000000..f22c5f2d4
--- /dev/null
+++ b/Annex/Environment.hs
@@ -0,0 +1,65 @@
+{- git-annex environment
+ -
+ - Copyright 2012, 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Annex.Environment where
+
+import Common.Annex
+import Utility.UserInfo
+import qualified Git.Config
+import Config
+import Annex.Exception
+
+#ifndef mingw32_HOST_OS
+import Utility.Env
+#endif
+
+{- Checks that the system's environment allows git to function.
+ - Git requires a GECOS username, or suitable git configuration, or
+ - environment variables.
+ -
+ - Git also requires the system have a hostname containing a dot.
+ - Otherwise, it tries various methods to find a FQDN, and will fail if it
+ - does not. To avoid replicating that code here, which would break if its
+ - methods change, this function does not check the hostname is valid.
+ - Instead, code that commits can use ensureCommit.
+ -}
+checkEnvironment :: Annex ()
+checkEnvironment = do
+ gitusername <- fromRepo $ Git.Config.getMaybe "user.name"
+ when (isNothing gitusername || gitusername == Just "") $
+ liftIO checkEnvironmentIO
+
+checkEnvironmentIO :: IO ()
+checkEnvironmentIO =
+#ifdef mingw32_HOST_OS
+ noop
+#else
+ whenM (null <$> myUserGecos) $ do
+ username <- myUserName
+ ensureEnv "GIT_AUTHOR_NAME" username
+ ensureEnv "GIT_COMMITTER_NAME" username
+ where
+#ifndef __ANDROID__
+ -- existing environment is not overwritten
+ ensureEnv var val = void $ setEnv var val False
+#else
+ -- Environment setting is broken on Android, so this is dealt with
+ -- in runshell instead.
+ ensureEnv _ _ = noop
+#endif
+#endif
+
+{- Runs an action that commits to the repository, and if it fails,
+ - sets user.email to a dummy value and tries the action again. -}
+ensureCommit :: Annex a -> Annex a
+ensureCommit a = either retry return =<< tryAnnex a
+ where
+ retry _ = do
+ setConfig (ConfigKey "user.email") =<< liftIO myUserName
+ a
diff --git a/Annex/Exception.hs b/Annex/Exception.hs
new file mode 100644
index 000000000..91347583e
--- /dev/null
+++ b/Annex/Exception.hs
@@ -0,0 +1,46 @@
+{- exception handling in the git-annex monad
+ -
+ - Note that when an Annex action fails and the exception is handled
+ - by these functions, any changes the action has made to the
+ - AnnexState are retained. This works because the Annex monad
+ - internally stores the AnnexState in a MVar.
+ -
+ - Copyright 2011-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE PackageImports #-}
+
+module Annex.Exception (
+ bracketIO,
+ tryAnnex,
+ tryAnnexIO,
+ throwAnnex,
+ catchAnnex,
+) where
+
+import qualified "MonadCatchIO-transformers" Control.Monad.CatchIO as M
+import Control.Exception
+
+import Common.Annex
+
+{- Runs an Annex action, with setup and cleanup both in the IO monad. -}
+bracketIO :: IO v -> (v -> IO b) -> (v -> Annex a) -> Annex a
+bracketIO setup cleanup = M.bracket (liftIO setup) (liftIO . cleanup)
+
+{- try in the Annex monad -}
+tryAnnex :: Annex a -> Annex (Either SomeException a)
+tryAnnex = M.try
+
+{- try in the Annex monad, but only catching IO exceptions -}
+tryAnnexIO :: Annex a -> Annex (Either IOException a)
+tryAnnexIO = M.try
+
+{- throw in the Annex monad -}
+throwAnnex :: Exception e => e -> Annex a
+throwAnnex = M.throw
+
+{- catch in the Annex monad -}
+catchAnnex :: Exception e => Annex a -> (e -> Annex a) -> Annex a
+catchAnnex = M.catch
diff --git a/Annex/FileMatcher.hs b/Annex/FileMatcher.hs
new file mode 100644
index 000000000..cded857a2
--- /dev/null
+++ b/Annex/FileMatcher.hs
@@ -0,0 +1,102 @@
+{- git-annex file matching
+ -
+ - Copyright 2012, 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Annex.FileMatcher where
+
+import qualified Data.Map as M
+
+import Common.Annex
+import Limit
+import Utility.Matcher
+import Types.Group
+import Types.Limit
+import Logs.Group
+import Logs.Remote
+import Annex.UUID
+import qualified Annex
+import Types.FileMatcher
+import Git.FilePath
+import Types.Remote (RemoteConfig)
+
+import Data.Either
+import qualified Data.Set as S
+
+type FileMatcher = Matcher MatchFiles
+
+checkFileMatcher :: FileMatcher -> FilePath -> Annex Bool
+checkFileMatcher matcher file = checkFileMatcher' matcher file S.empty True
+
+checkFileMatcher' :: FileMatcher -> FilePath -> AssumeNotPresent -> Bool -> Annex Bool
+checkFileMatcher' matcher file notpresent def
+ | isEmpty matcher = return def
+ | otherwise = do
+ matchfile <- getTopFilePath <$> inRepo (toTopFilePath file)
+ let fi = FileInfo
+ { matchFile = matchfile
+ , relFile = file
+ }
+ matchMrun matcher $ \a -> a notpresent fi
+
+matchAll :: FileMatcher
+matchAll = generate []
+
+parsedToMatcher :: [Either String (Token MatchFiles)] -> Either String FileMatcher
+parsedToMatcher parsed = case partitionEithers parsed of
+ ([], vs) -> Right $ generate vs
+ (es, _) -> Left $ unwords $ map ("Parse failure: " ++) es
+
+exprParser :: GroupMap -> M.Map UUID RemoteConfig -> Maybe UUID -> String -> [Either String (Token MatchFiles)]
+exprParser groupmap configmap mu expr =
+ map parse $ tokenizeMatcher expr
+ where
+ parse = parseToken
+ (limitPresent mu)
+ (limitInDir preferreddir)
+ groupmap
+ preferreddir = fromMaybe "public" $
+ M.lookup "preferreddir" =<< (`M.lookup` configmap) =<< mu
+
+parseToken :: MkLimit -> MkLimit -> GroupMap -> String -> Either String (Token MatchFiles)
+parseToken checkpresent checkpreferreddir groupmap t
+ | t `elem` tokens = Right $ token t
+ | t == "present" = use checkpresent
+ | t == "inpreferreddir" = use checkpreferreddir
+ | otherwise = maybe (Left $ "near " ++ show t) use $ M.lookup k $
+ M.fromList
+ [ ("include", limitInclude)
+ , ("exclude", limitExclude)
+ , ("copies", limitCopies)
+ , ("inbackend", limitInBackend)
+ , ("largerthan", limitSize (>))
+ , ("smallerthan", limitSize (<))
+ , ("inallgroup", limitInAllGroup groupmap)
+ ]
+ where
+ (k, v) = separate (== '=') t
+ use a = Operation <$> a v
+
+{- This is really dumb tokenization; there's no support for quoted values.
+ - Open and close parens are always treated as standalone tokens;
+ - otherwise tokens must be separated by whitespace. -}
+tokenizeMatcher :: String -> [String]
+tokenizeMatcher = filter (not . null ) . concatMap splitparens . words
+ where
+ splitparens = segmentDelim (`elem` "()")
+
+{- Generates a matcher for files large enough (or meeting other criteria)
+ - to be added to the annex, rather than directly to git. -}
+largeFilesMatcher :: Annex FileMatcher
+largeFilesMatcher = go =<< annexLargeFiles <$> Annex.getGitConfig
+ where
+ go Nothing = return matchAll
+ go (Just expr) = do
+ gm <- groupMap
+ rc <- readRemoteLog
+ u <- getUUID
+ either badexpr return $
+ parsedToMatcher $ exprParser gm rc (Just u) expr
+ badexpr e = error $ "bad annex.largefiles configuration: " ++ e
diff --git a/Annex/Hook.hs b/Annex/Hook.hs
new file mode 100644
index 000000000..7301a0958
--- /dev/null
+++ b/Annex/Hook.hs
@@ -0,0 +1,42 @@
+{- git-annex git hooks
+ -
+ - Note that it's important that the scripts not change, otherwise
+ - removing old hooks using an old version of the script would fail.
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Annex.Hook where
+
+import Common.Annex
+import qualified Git.Hook as Git
+import Utility.Shell
+import Config
+
+preCommitHook :: Git.Hook
+preCommitHook = Git.Hook "pre-commit" (mkHookScript "git annex pre-commit .")
+
+mkHookScript :: String -> String
+mkHookScript s = unlines
+ [ shebang_local
+ , "# automatically configured by git-annex"
+ , s
+ ]
+
+hookWrite :: Git.Hook -> Annex ()
+hookWrite h =
+ -- cannot have git hooks in a crippled filesystem (no execute bit)
+ unlessM crippledFileSystem $
+ unlessM (inRepo $ Git.hookWrite h) $
+ hookWarning h "already exists, not configuring"
+
+hookUnWrite :: Git.Hook -> Annex ()
+hookUnWrite h = unlessM (inRepo $ Git.hookUnWrite h) $
+ hookWarning h "contents modified; not deleting. Edit it to remove call to git annex."
+
+hookWarning :: Git.Hook -> String -> Annex ()
+hookWarning h msg = do
+ r <- gitRepo
+ warning $ Git.hookName h ++ " hook (" ++ Git.hookFile h r ++ ") " ++ msg
diff --git a/Annex/Journal.hs b/Annex/Journal.hs
new file mode 100644
index 000000000..8b88ab2fb
--- /dev/null
+++ b/Annex/Journal.hs
@@ -0,0 +1,128 @@
+{- management of the git-annex journal
+ -
+ - The journal is used to queue up changes before they are committed to the
+ - git-annex branch. Among other things, it ensures that if git-annex is
+ - interrupted, its recorded data is not lost.
+ -
+ - Copyright 2011-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Annex.Journal where
+
+import System.IO.Binary
+
+import Common.Annex
+import Annex.Exception
+import qualified Git
+import Annex.Perms
+
+{- Records content for a file in the branch to the journal.
+ -
+ - Using the journal, rather than immediatly staging content to the index
+ - avoids git needing to rewrite the index after every change.
+ -
+ - The file in the journal is updated atomically, which allows
+ - getJournalFileStale to always return a consistent journal file
+ - content, although possibly not the most current one.
+ -}
+setJournalFile :: JournalLocked -> FilePath -> String -> Annex ()
+setJournalFile _jl file content = do
+ createAnnexDirectory =<< fromRepo gitAnnexJournalDir
+ createAnnexDirectory =<< fromRepo gitAnnexTmpDir
+ -- journal file is written atomically
+ jfile <- fromRepo $ journalFile file
+ tmp <- fromRepo gitAnnexTmpDir
+ let tmpfile = tmp </> takeFileName jfile
+ liftIO $ do
+ writeBinaryFile tmpfile content
+ moveFile tmpfile jfile
+
+{- Gets any journalled content for a file in the branch. -}
+getJournalFile :: JournalLocked -> FilePath -> Annex (Maybe String)
+getJournalFile _jl = getJournalFileStale
+
+{- Without locking, this is not guaranteed to be the most recent
+ - version of the file in the journal, so should not be used as a basis for
+ - changes. -}
+getJournalFileStale :: FilePath -> Annex (Maybe String)
+getJournalFileStale file = inRepo $ \g -> catchMaybeIO $
+ readFileStrict $ journalFile file g
+
+{- List of files that have updated content in the journal. -}
+getJournalledFiles :: JournalLocked -> Annex [FilePath]
+getJournalledFiles jl = map fileJournal <$> getJournalFiles jl
+
+getJournalledFilesStale :: Annex [FilePath]
+getJournalledFilesStale = map fileJournal <$> getJournalFilesStale
+
+{- List of existing journal files. -}
+getJournalFiles :: JournalLocked -> Annex [FilePath]
+getJournalFiles _jl = getJournalFilesStale
+
+{- List of existing journal files, but without locking, may miss new ones
+ - just being added, or may have false positives if the journal is staged
+ - as it is run. -}
+getJournalFilesStale :: Annex [FilePath]
+getJournalFilesStale = do
+ g <- gitRepo
+ fs <- liftIO $ catchDefaultIO [] $
+ getDirectoryContents $ gitAnnexJournalDir g
+ return $ filter (`notElem` [".", ".."]) fs
+
+{- Checks if there are changes in the journal. -}
+journalDirty :: Annex Bool
+journalDirty = not . null <$> getJournalFilesStale
+
+{- Produces a filename to use in the journal for a file on the branch.
+ -
+ - The journal typically won't have a lot of files in it, so the hashing
+ - used in the branch is not necessary, and all the files are put directly
+ - in the journal directory.
+ -}
+journalFile :: FilePath -> Git.Repo -> FilePath
+journalFile file repo = gitAnnexJournalDir repo </> concatMap mangle file
+ where
+ mangle c
+ | c == pathSeparator = "_"
+ | c == '_' = "__"
+ | otherwise = [c]
+
+{- Converts a journal file (relative to the journal dir) back to the
+ - filename on the branch. -}
+fileJournal :: FilePath -> FilePath
+fileJournal = replace [pathSeparator, pathSeparator] "_" .
+ replace "_" [pathSeparator]
+
+{- Sentinal value, only produced by lockJournal; required
+ - as a parameter by things that need to ensure the journal is
+ - locked. -}
+data JournalLocked = ProduceJournalLocked
+
+{- Runs an action that modifies the journal, using locking to avoid
+ - contention with other git-annex processes. -}
+lockJournal :: (JournalLocked -> Annex a) -> Annex a
+lockJournal a = do
+ lockfile <- fromRepo gitAnnexJournalLock
+ createAnnexDirectory $ takeDirectory lockfile
+ mode <- annexFileMode
+ bracketIO (lock lockfile mode) unlock (const $ a ProduceJournalLocked)
+ where
+#ifndef mingw32_HOST_OS
+ lock lockfile mode = do
+ l <- noUmask mode $ createFile lockfile mode
+ waitToSetLock l (WriteLock, AbsoluteSeek, 0, 0)
+ return l
+#else
+ lock lockfile _mode = do
+ writeFile lockfile ""
+ return lockfile
+#endif
+#ifndef mingw32_HOST_OS
+ unlock = closeFd
+#else
+ unlock = removeFile
+#endif
diff --git a/Annex/Link.hs b/Annex/Link.hs
new file mode 100644
index 000000000..30d8c2ae8
--- /dev/null
+++ b/Annex/Link.hs
@@ -0,0 +1,105 @@
+{- git-annex links to content
+ -
+ - On file systems that support them, symlinks are used.
+ -
+ - On other filesystems, git instead stores the symlink target in a regular
+ - file.
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Annex.Link where
+
+import Common.Annex
+import qualified Annex
+import qualified Git.HashObject
+import qualified Git.UpdateIndex
+import qualified Annex.Queue
+import Git.Types
+import Git.FilePath
+
+type LinkTarget = String
+
+{- Checks if a file is a link to a key. -}
+isAnnexLink :: FilePath -> Annex (Maybe Key)
+isAnnexLink file = maybe Nothing (fileKey . takeFileName) <$> getAnnexLinkTarget file
+
+{- Gets the link target of a symlink.
+ -
+ - On a filesystem that does not support symlinks, fall back to getting the
+ - link target by looking inside the file.
+ -
+ - Returns Nothing if the file is not a symlink, or not a link to annex
+ - content.
+ -}
+getAnnexLinkTarget :: FilePath -> Annex (Maybe LinkTarget)
+getAnnexLinkTarget file = ifM (coreSymlinks <$> Annex.getGitConfig)
+ ( check readSymbolicLink $
+ return Nothing
+ , check readSymbolicLink $
+ check probefilecontent $
+ return Nothing
+ )
+ where
+ check getlinktarget fallback = do
+ v <- liftIO $ catchMaybeIO $ getlinktarget file
+ case v of
+ Just l
+ | isLinkToAnnex (fromInternalGitPath l) -> return v
+ | otherwise -> return Nothing
+ Nothing -> fallback
+
+ probefilecontent f = do
+ h <- openFile f ReadMode
+ fileEncoding h
+ -- The first 8k is more than enough to read; link
+ -- files are small.
+ s <- take 8192 <$> hGetContents h
+ -- If we got the full 8k, the file is too large
+ if length s == 8192
+ then do
+ hClose h
+ return ""
+ else do
+ hClose h
+ -- If there are any NUL or newline
+ -- characters, or whitespace, we
+ -- certianly don't have a link to a
+ -- git-annex key.
+ return $ if any (`elem` s) "\0\n\r \t"
+ then ""
+ else s
+
+{- Creates a link on disk.
+ -
+ - On a filesystem that does not support symlinks, writes the link target
+ - to a file. Note that git will only treat the file as a symlink if
+ - it's staged as such, so use addAnnexLink when adding a new file or
+ - modified link to git.
+ -}
+makeAnnexLink :: LinkTarget -> FilePath -> Annex ()
+makeAnnexLink linktarget file = ifM (coreSymlinks <$> Annex.getGitConfig)
+ ( liftIO $ do
+ void $ tryIO $ removeFile file
+ createSymbolicLink linktarget file
+ , liftIO $ writeFile file linktarget
+ )
+
+{- Creates a link on disk, and additionally stages it in git. -}
+addAnnexLink :: LinkTarget -> FilePath -> Annex ()
+addAnnexLink linktarget file = do
+ makeAnnexLink linktarget file
+ stageSymlink file =<< hashSymlink linktarget
+
+{- Injects a symlink target into git, returning its Sha. -}
+hashSymlink :: LinkTarget -> Annex Sha
+hashSymlink linktarget = inRepo $ Git.HashObject.hashObject BlobObject $
+ toInternalGitPath linktarget
+
+{- Stages a symlink to the annex, using a Sha of its target. -}
+stageSymlink :: FilePath -> Sha -> Annex ()
+stageSymlink file sha =
+ Annex.Queue.addUpdateIndex =<<
+ inRepo (Git.UpdateIndex.stageSymlink file sha)
diff --git a/Annex/LockPool.hs b/Annex/LockPool.hs
new file mode 100644
index 000000000..a9a0f3101
--- /dev/null
+++ b/Annex/LockPool.hs
@@ -0,0 +1,56 @@
+{- git-annex lock pool
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Annex.LockPool where
+
+import qualified Data.Map as M
+import System.Posix.Types (Fd)
+
+import Common.Annex
+import Annex
+#ifndef mingw32_HOST_OS
+import Annex.Perms
+#endif
+
+{- Create a specified lock file, and takes a shared lock. -}
+lockFile :: FilePath -> Annex ()
+lockFile file = go =<< fromPool file
+ where
+ go (Just _) = noop -- already locked
+ go Nothing = do
+#ifndef mingw32_HOST_OS
+ mode <- annexFileMode
+ fd <- liftIO $ noUmask mode $
+ openFd file ReadOnly (Just mode) defaultFileFlags
+ liftIO $ waitToSetLock fd (ReadLock, AbsoluteSeek, 0, 0)
+#else
+ liftIO $ writeFile file ""
+ let fd = 0
+#endif
+ changePool $ M.insert file fd
+
+unlockFile :: FilePath -> Annex ()
+unlockFile file = maybe noop go =<< fromPool file
+ where
+ go fd = do
+#ifndef mingw32_HOST_OS
+ liftIO $ closeFd fd
+#endif
+ changePool $ M.delete file
+
+getPool :: Annex (M.Map FilePath Fd)
+getPool = getState lockpool
+
+fromPool :: FilePath -> Annex (Maybe Fd)
+fromPool file = M.lookup file <$> getPool
+
+changePool :: (M.Map FilePath Fd -> M.Map FilePath Fd) -> Annex ()
+changePool a = do
+ m <- getPool
+ changeState $ \s -> s { lockpool = a m }
diff --git a/Annex/Path.hs b/Annex/Path.hs
new file mode 100644
index 000000000..a8c4907b2
--- /dev/null
+++ b/Annex/Path.hs
@@ -0,0 +1,34 @@
+{- git-annex program path
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Annex.Path where
+
+import Common
+import Config.Files
+import System.Environment
+
+{- A fully qualified path to the currently running git-annex program.
+ -
+ - getExecutablePath is available since ghc 7.4.2. On OSs it supports
+ - well, it returns the complete path to the program. But, on other OSs,
+ - it might return just the basename.
+ -}
+programPath :: IO (Maybe FilePath)
+programPath = do
+#if MIN_VERSION_base(4,6,0)
+ exe <- getExecutablePath
+ p <- if isAbsolute exe
+ then return exe
+ else readProgramFile
+#else
+ p <- readProgramFile
+#endif
+ -- In case readProgramFile returned just the command name,
+ -- fall back to finding it in PATH.
+ searchPath p
diff --git a/Annex/Perms.hs b/Annex/Perms.hs
new file mode 100644
index 000000000..e3a2fa65a
--- /dev/null
+++ b/Annex/Perms.hs
@@ -0,0 +1,125 @@
+{- git-annex file permissions
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Annex.Perms (
+ setAnnexFilePerm,
+ setAnnexDirPerm,
+ annexFileMode,
+ createAnnexDirectory,
+ noUmask,
+ createContentDir,
+ freezeContentDir,
+ thawContentDir,
+ modifyContent,
+) where
+
+import Common.Annex
+import Utility.FileMode
+import Git.SharedRepository
+import qualified Annex
+import Annex.Exception
+import Config
+
+import System.Posix.Types
+
+withShared :: (SharedRepository -> Annex a) -> Annex a
+withShared a = maybe startup a =<< Annex.getState Annex.shared
+ where
+ startup = do
+ shared <- fromRepo getSharedRepository
+ Annex.changeState $ \s -> s { Annex.shared = Just shared }
+ a shared
+
+setAnnexFilePerm :: FilePath -> Annex ()
+setAnnexFilePerm = setAnnexPerm False
+
+setAnnexDirPerm :: FilePath -> Annex ()
+setAnnexDirPerm = setAnnexPerm True
+
+{- Sets appropriate file mode for a file or directory in the annex,
+ - other than the content files and content directory. Normally,
+ - use the default mode, but with core.sharedRepository set,
+ - allow the group to write, etc. -}
+setAnnexPerm :: Bool -> FilePath -> Annex ()
+setAnnexPerm isdir file = unlessM crippledFileSystem $
+ withShared $ liftIO . go
+ where
+ go GroupShared = modifyFileMode file $ addModes $
+ groupSharedModes ++
+ if isdir then [ ownerExecuteMode, groupExecuteMode ] else []
+ go AllShared = modifyFileMode file $ addModes $
+ readModes ++
+ [ ownerWriteMode, groupWriteMode ] ++
+ if isdir then executeModes else []
+ go _ = noop
+
+{- Gets the appropriate mode to use for creating a file in the annex
+ - (other than content files, which are locked down more). -}
+annexFileMode :: Annex FileMode
+annexFileMode = withShared $ return . go
+ where
+ go GroupShared = sharedmode
+ go AllShared = combineModes (sharedmode:readModes)
+ go _ = stdFileMode
+ sharedmode = combineModes groupSharedModes
+
+{- Creates a directory inside the gitAnnexDir, including any parent
+ - directories. Makes directories with appropriate permissions. -}
+createAnnexDirectory :: FilePath -> Annex ()
+createAnnexDirectory dir = traverse dir [] =<< top
+ where
+ top = parentDir <$> fromRepo gitAnnexDir
+ traverse d below stop
+ | d `equalFilePath` stop = done
+ | otherwise = ifM (liftIO $ doesDirectoryExist d)
+ ( done
+ , traverse (parentDir d) (d:below) stop
+ )
+ where
+ done = forM_ below $ \p -> do
+ liftIO $ createDirectoryIfMissing True p
+ setAnnexDirPerm p
+
+{- Blocks writing to the directory an annexed file is in, to prevent the
+ - file accidentially being deleted. However, if core.sharedRepository
+ - is set, this is not done, since the group must be allowed to delete the
+ - file.
+ -}
+freezeContentDir :: FilePath -> Annex ()
+freezeContentDir file = unlessM crippledFileSystem $
+ liftIO . go =<< fromRepo getSharedRepository
+ where
+ dir = parentDir file
+ go GroupShared = groupWriteRead dir
+ go AllShared = groupWriteRead dir
+ go _ = preventWrite dir
+
+thawContentDir :: FilePath -> Annex ()
+thawContentDir file = unlessM crippledFileSystem $
+ liftIO $ allowWrite $ parentDir file
+
+{- Makes the directory tree to store an annexed file's content,
+ - with appropriate permissions on each level. -}
+createContentDir :: FilePath -> Annex ()
+createContentDir dest = do
+ unlessM (liftIO $ doesDirectoryExist dir) $
+ createAnnexDirectory dir
+ -- might have already existed with restricted perms
+ unlessM crippledFileSystem $
+ liftIO $ allowWrite dir
+ where
+ dir = parentDir dest
+
+{- Creates the content directory for a file if it doesn't already exist,
+ - or thaws it if it does, then runs an action to modify the file, and
+ - finally, freezes the content directory. -}
+modifyContent :: FilePath -> Annex a -> Annex a
+modifyContent f a = do
+ createContentDir f -- also thaws it
+ v <- tryAnnex a
+ freezeContentDir f
+ either throwAnnex return v
diff --git a/Annex/Queue.hs b/Annex/Queue.hs
new file mode 100644
index 000000000..a5ef60037
--- /dev/null
+++ b/Annex/Queue.hs
@@ -0,0 +1,62 @@
+{- git-annex command queue
+ -
+ - Copyright 2011, 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Annex.Queue (
+ addCommand,
+ addUpdateIndex,
+ flush,
+ flushWhenFull,
+ size
+) where
+
+import Common.Annex
+import Annex hiding (new)
+import qualified Git.Queue
+import qualified Git.UpdateIndex
+
+{- Adds a git command to the queue. -}
+addCommand :: String -> [CommandParam] -> [FilePath] -> Annex ()
+addCommand command params files = do
+ q <- get
+ store <=< inRepo $ Git.Queue.addCommand command params files q
+
+{- Adds an update-index stream to the queue. -}
+addUpdateIndex :: Git.UpdateIndex.Streamer -> Annex ()
+addUpdateIndex streamer = do
+ q <- get
+ store <=< inRepo $ Git.Queue.addUpdateIndex streamer q
+
+{- Runs the queue if it is full. Should be called periodically. -}
+flushWhenFull :: Annex ()
+flushWhenFull = do
+ q <- get
+ when (Git.Queue.full q) flush
+
+{- Runs (and empties) the queue. -}
+flush :: Annex ()
+flush = do
+ q <- get
+ unless (0 == Git.Queue.size q) $ do
+ showStoringStateAction
+ q' <- inRepo $ Git.Queue.flush q
+ store q'
+
+{- Gets the size of the queue. -}
+size :: Annex Int
+size = Git.Queue.size <$> get
+
+get :: Annex Git.Queue.Queue
+get = maybe new return =<< getState repoqueue
+
+new :: Annex Git.Queue.Queue
+new = do
+ q <- Git.Queue.new . annexQueueSize <$> getGitConfig
+ store q
+ return q
+
+store :: Git.Queue.Queue -> Annex ()
+store q = changeState $ \s -> s { repoqueue = Just q }
diff --git a/Annex/Quvi.hs b/Annex/Quvi.hs
new file mode 100644
index 000000000..b0725bae7
--- /dev/null
+++ b/Annex/Quvi.hs
@@ -0,0 +1,20 @@
+{- quvi options for git-annex
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE Rank2Types #-}
+
+module Annex.Quvi where
+
+import Common.Annex
+import qualified Annex
+import Utility.Quvi
+import Utility.Url
+
+withQuviOptions :: forall a. Query a -> [CommandParam] -> URLString -> Annex a
+withQuviOptions a ps url = do
+ opts <- map Param . annexQuviOptions <$> Annex.getGitConfig
+ liftIO $ a (ps++opts) url
diff --git a/Annex/ReplaceFile.hs b/Annex/ReplaceFile.hs
new file mode 100644
index 000000000..dd93b471c
--- /dev/null
+++ b/Annex/ReplaceFile.hs
@@ -0,0 +1,39 @@
+{- git-annex file replacing
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Annex.ReplaceFile where
+
+import Common.Annex
+import Annex.Perms
+import Annex.Exception
+
+{- Replaces a possibly already existing file with a new version,
+ - atomically, by running an action.
+ -
+ - The action is passed a temp file, which it can write to, and once
+ - done the temp file is moved into place.
+ -
+ - The action can throw an IO exception, in which case the temp file
+ - will be deleted, and the existing file will be preserved.
+ -
+ - Throws an IO exception when it was unable to replace the file.
+ -}
+replaceFile :: FilePath -> (FilePath -> Annex ()) -> Annex ()
+replaceFile file a = do
+ tmpdir <- fromRepo gitAnnexTmpDir
+ void $ createAnnexDirectory tmpdir
+ bracketIO (setup tmpdir) nukeFile $ \tmpfile -> do
+ a tmpfile
+ liftIO $ catchIO (rename tmpfile file) (fallback tmpfile)
+ where
+ setup tmpdir = do
+ (tmpfile, h) <- openTempFileWithDefaultPermissions tmpdir "tmp"
+ hClose h
+ return tmpfile
+ fallback tmpfile _ = do
+ createDirectoryIfMissing True $ parentDir file
+ rename tmpfile file
diff --git a/Annex/Ssh.hs b/Annex/Ssh.hs
new file mode 100644
index 000000000..8553ee797
--- /dev/null
+++ b/Annex/Ssh.hs
@@ -0,0 +1,198 @@
+{- git-annex ssh interface, with connection caching
+ -
+ - Copyright 2012,2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Annex.Ssh (
+ sshCachingOptions,
+ sshCleanup,
+ sshCacheDir,
+ sshReadPort,
+) where
+
+import qualified Data.Map as M
+import Data.Hash.MD5
+import System.Process (cwd)
+
+import Common.Annex
+import Annex.LockPool
+import qualified Build.SysConfig as SysConfig
+import qualified Annex
+import Config
+import Utility.Env
+#ifndef mingw32_HOST_OS
+import Annex.Perms
+#endif
+
+{- Generates parameters to ssh to a given host (or user@host) on a given
+ - port, with connection caching. -}
+sshCachingOptions :: (String, Maybe Integer) -> [CommandParam] -> Annex [CommandParam]
+sshCachingOptions (host, port) opts = go =<< sshInfo (host, port)
+ where
+ go (Nothing, params) = ret params
+ go (Just socketfile, params) = do
+ cleanstale
+ liftIO $ createDirectoryIfMissing True $ parentDir socketfile
+ lockFile $ socket2lock socketfile
+ ret params
+ ret ps = return $ ps ++ opts ++ portParams port ++ [Param "-T"]
+ -- If the lock pool is empty, this is the first ssh of this
+ -- run. There could be stale ssh connections hanging around
+ -- from a previous git-annex run that was interrupted.
+ cleanstale = whenM (not . any isLock . M.keys <$> getPool)
+ sshCleanup
+
+{- Returns a filename to use for a ssh connection caching socket, and
+ - parameters to enable ssh connection caching. -}
+sshInfo :: (String, Maybe Integer) -> Annex (Maybe FilePath, [CommandParam])
+sshInfo (host, port) = go =<< sshCacheDir
+ where
+ go Nothing = return (Nothing, [])
+ go (Just dir) = do
+ r <- liftIO $ bestSocketPath $ dir </> hostport2socket host port
+ return $ case r of
+ Nothing -> (Nothing, [])
+ Just socketfile -> (Just socketfile, sshConnectionCachingParams socketfile)
+
+{- Given an absolute path to use for a socket file,
+ - returns whichever is shorter of that or the relative path to the same
+ - file.
+ -
+ - If no path can be constructed that is a valid socket, returns Nothing. -}
+bestSocketPath :: FilePath -> IO (Maybe FilePath)
+bestSocketPath abssocketfile = do
+ relsocketfile <- liftIO $ relPathCwdToFile abssocketfile
+ let socketfile = if length abssocketfile <= length relsocketfile
+ then abssocketfile
+ else relsocketfile
+ return $ if valid_unix_socket_path (socketfile ++ sshgarbage)
+ then Just socketfile
+ else Nothing
+ where
+ -- ssh appends a 16 char extension to the socket when setting it
+ -- up, which needs to be taken into account when checking
+ -- that a valid socket was constructed.
+ sshgarbage = take (1+16) $ repeat 'X'
+
+sshConnectionCachingParams :: FilePath -> [CommandParam]
+sshConnectionCachingParams socketfile =
+ [ Param "-S", Param socketfile
+ , Params "-o ControlMaster=auto -o ControlPersist=yes"
+ ]
+
+{- ssh connection caching creates sockets, so will not work on a
+ - crippled filesystem. A GIT_ANNEX_TMP_DIR can be provided to use
+ - a different filesystem. -}
+sshCacheDir :: Annex (Maybe FilePath)
+sshCacheDir
+ | SysConfig.sshconnectioncaching = ifM crippledFileSystem
+ ( maybe (return Nothing) usetmpdir =<< gettmpdir
+ , ifM (fromMaybe True . annexSshCaching <$> Annex.getGitConfig)
+ ( Just <$> fromRepo gitAnnexSshDir
+ , return Nothing
+ )
+ )
+ | otherwise = return Nothing
+ where
+ gettmpdir = liftIO $ getEnv "GIT_ANNEX_TMP_DIR"
+ usetmpdir tmpdir = liftIO $ catchMaybeIO $ do
+ createDirectoryIfMissing True tmpdir
+ return tmpdir
+
+portParams :: Maybe Integer -> [CommandParam]
+portParams Nothing = []
+portParams (Just port) = [Param "-p", Param $ show port]
+
+{- Stop any unused ssh processes. -}
+sshCleanup :: Annex ()
+sshCleanup = go =<< sshCacheDir
+ where
+ go Nothing = noop
+ go (Just dir) = do
+ sockets <- liftIO $ filter (not . isLock)
+ <$> catchDefaultIO [] (dirContents dir)
+ forM_ sockets cleanup
+ cleanup socketfile = do
+#ifndef mingw32_HOST_OS
+ -- Drop any shared lock we have, and take an
+ -- exclusive lock, without blocking. If the lock
+ -- succeeds, nothing is using this ssh, and it can
+ -- be stopped.
+ let lockfile = socket2lock socketfile
+ unlockFile lockfile
+ mode <- annexFileMode
+ fd <- liftIO $ noUmask mode $
+ openFd lockfile ReadWrite (Just mode) defaultFileFlags
+ v <- liftIO $ tryIO $
+ setLock fd (WriteLock, AbsoluteSeek, 0, 0)
+ case v of
+ Left _ -> noop
+ Right _ -> stopssh socketfile
+ liftIO $ closeFd fd
+#else
+ stopssh socketfile
+#endif
+ stopssh socketfile = do
+ let (dir, base) = splitFileName socketfile
+ let params = sshConnectionCachingParams base
+ -- "ssh -O stop" is noisy on stderr even with -q
+ void $ liftIO $ catchMaybeIO $
+ withQuietOutput createProcessSuccess $
+ (proc "ssh" $ toCommand $
+ [ Params "-O stop"
+ ] ++ params ++ [Param "any"])
+ { cwd = Just dir }
+ -- Cannot remove the lock file; other processes may
+ -- be waiting on our exclusive lock to use it.
+
+{- This needs to be as short as possible, due to limitations on the length
+ - of the path to a socket file. At the same time, it needs to be unique
+ - for each host.
+ -}
+hostport2socket :: String -> Maybe Integer -> FilePath
+hostport2socket host Nothing = hostport2socket' host
+hostport2socket host (Just port) = hostport2socket' $ host ++ "!" ++ show port
+hostport2socket' :: String -> FilePath
+hostport2socket' s
+ | length s > lengthofmd5s = md5s (Str s)
+ | otherwise = s
+ where
+ lengthofmd5s = 32
+
+socket2lock :: FilePath -> FilePath
+socket2lock socket = socket ++ lockExt
+
+isLock :: FilePath -> Bool
+isLock f = lockExt `isSuffixOf` f
+
+lockExt :: String
+lockExt = ".lock"
+
+{- This is the size of the sun_path component of sockaddr_un, which
+ - is the limit to the total length of the filename of a unix socket.
+ -
+ - On Linux, this is 108. On OSX, 104. TODO: Probe
+ -}
+sizeof_sockaddr_un_sun_path :: Int
+sizeof_sockaddr_un_sun_path = 100
+
+{- Note that this looks at the true length of the path in bytes, as it will
+ - appear on disk. -}
+valid_unix_socket_path :: FilePath -> Bool
+valid_unix_socket_path f = length (decodeW8 f) < sizeof_sockaddr_un_sun_path
+
+{- Parses the SSH port, and returns the other OpenSSH options. If
+ - several ports are found, the last one takes precedence. -}
+sshReadPort :: [String] -> (Maybe Integer, [String])
+sshReadPort params = (port, reverse args)
+ where
+ (port,args) = aux (Nothing, []) params
+ aux (p,ps) [] = (p,ps)
+ aux (_,ps) ("-p":p:rest) = aux (readPort p, ps) rest
+ aux (p,ps) (q:rest) | "-p" `isPrefixOf` q = aux (readPort $ drop 2 q, ps) rest
+ | otherwise = aux (p,q:ps) rest
+ readPort p = fmap fst $ listToMaybe $ reads p
diff --git a/Annex/TaggedPush.hs b/Annex/TaggedPush.hs
new file mode 100644
index 000000000..039dc0e17
--- /dev/null
+++ b/Annex/TaggedPush.hs
@@ -0,0 +1,61 @@
+{- git-annex tagged pushes
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Annex.TaggedPush where
+
+import Common.Annex
+import qualified Remote
+import qualified Annex.Branch
+import qualified Git
+import qualified Git.Ref
+import qualified Git.Command
+import qualified Git.Branch
+import Utility.Base64
+
+{- Converts a git branch into a branch that is tagged with a UUID, typically
+ - the UUID of the repo that will be pushing it, and possibly with other
+ - information.
+ -
+ - Pushing to branches on the remote that have our uuid in them is ugly,
+ - but it reserves those branches for pushing by us, and so our pushes will
+ - never conflict with other pushes.
+ -
+ - To avoid cluttering up the branch display, the branch is put under
+ - refs/synced/, rather than the usual refs/remotes/
+ -
+ - Both UUIDs and Base64 encoded data are always legal to be used in git
+ - refs, per git-check-ref-format.
+ -}
+toTaggedBranch :: UUID -> Maybe String -> Git.Branch -> Git.Branch
+toTaggedBranch u info b = Git.Ref $ intercalate "/" $ catMaybes
+ [ Just "refs/synced"
+ , Just $ fromUUID u
+ , toB64 <$> info
+ , Just $ show $ Git.Ref.base b
+ ]
+
+fromTaggedBranch :: Git.Branch -> Maybe (UUID, Maybe String)
+fromTaggedBranch b = case split "/" $ show b of
+ ("refs":"synced":u:info:_base) ->
+ Just (toUUID u, fromB64Maybe info)
+ ("refs":"synced":u:_base) ->
+ Just (toUUID u, Nothing)
+ _ -> Nothing
+ where
+
+taggedPush :: UUID -> Maybe String -> Git.Ref -> Remote -> Git.Repo -> IO Bool
+taggedPush u info branch remote = Git.Command.runBool
+ [ Param "push"
+ , Param $ Remote.name remote
+ {- 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
+ ]
+ where
+ refspec b = show b ++ ":" ++ show (toTaggedBranch u info b)
diff --git a/Annex/UUID.hs b/Annex/UUID.hs
new file mode 100644
index 000000000..4e274503b
--- /dev/null
+++ b/Annex/UUID.hs
@@ -0,0 +1,96 @@
+{- git-annex uuids
+ -
+ - Each git repository used by git-annex has an annex.uuid setting that
+ - uniquely identifies that repository.
+ -
+ - UUIDs of remotes are cached in git config, using keys named
+ - remote.<name>.annex-uuid
+ -
+ - Copyright 2010-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Annex.UUID (
+ getUUID,
+ getRepoUUID,
+ getUncachedUUID,
+ prepUUID,
+ genUUID,
+ genUUIDInNameSpace,
+ gCryptNameSpace,
+ removeRepoUUID,
+ storeUUID,
+ setUUID,
+) where
+
+import Common.Annex
+import qualified Git
+import qualified Git.Config
+import Config
+
+import qualified Data.UUID as U
+import qualified Data.UUID.V5 as U5
+import System.Random
+import Data.Bits.Utils
+
+configkey :: ConfigKey
+configkey = annexConfig "uuid"
+
+{- Generates a random UUID, that does not include the MAC address. -}
+genUUID :: IO UUID
+genUUID = UUID . show <$> (randomIO :: IO U.UUID)
+
+{- Generates a UUID from a given string, using a namespace.
+ - Given the same namespace, the same string will always result
+ - in the same UUID. -}
+genUUIDInNameSpace :: U.UUID -> String -> UUID
+genUUIDInNameSpace namespace = UUID . show . U5.generateNamed namespace . s2w8
+
+{- Namespace used for UUIDs derived from git-remote-gcrypt ids. -}
+gCryptNameSpace :: U.UUID
+gCryptNameSpace = U5.generateNamed U5.namespaceURL $
+ s2w8 "http://git-annex.branchable.com/design/gcrypt/"
+
+{- Get current repository's UUID. -}
+getUUID :: Annex UUID
+getUUID = getRepoUUID =<< gitRepo
+
+{- Looks up a repo's UUID, caching it in .git/config if it's not already. -}
+getRepoUUID :: Git.Repo -> Annex UUID
+getRepoUUID r = do
+ c <- toUUID <$> getConfig cachekey ""
+ let u = getUncachedUUID r
+
+ if c /= u && u /= NoUUID
+ then do
+ updatecache u
+ return u
+ else return c
+ where
+ updatecache u = do
+ g <- gitRepo
+ when (g /= r) $ storeUUID cachekey u
+ cachekey = remoteConfig r "uuid"
+
+removeRepoUUID :: Annex ()
+removeRepoUUID = unsetConfig configkey
+
+getUncachedUUID :: Git.Repo -> UUID
+getUncachedUUID = toUUID . Git.Config.get key ""
+ where
+ (ConfigKey key) = configkey
+
+{- Make sure that the repo has an annex.uuid setting. -}
+prepUUID :: Annex ()
+prepUUID = whenM ((==) NoUUID <$> getUUID) $
+ storeUUID configkey =<< liftIO genUUID
+
+storeUUID :: ConfigKey -> UUID -> Annex ()
+storeUUID configfield = setConfig configfield . fromUUID
+
+{- Only sets the configkey in the Repo; does not change .git/config -}
+setUUID :: Git.Repo -> UUID -> IO Git.Repo
+setUUID r u = do
+ let s = show configkey ++ "=" ++ fromUUID u
+ Git.Config.store s r
diff --git a/Annex/Url.hs b/Annex/Url.hs
new file mode 100644
index 000000000..0401ffe07
--- /dev/null
+++ b/Annex/Url.hs
@@ -0,0 +1,27 @@
+{- Url downloading, with git-annex user agent.
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Annex.Url (
+ module U,
+ withUserAgent,
+ getUserAgent,
+) where
+
+import Common.Annex
+import qualified Annex
+import Utility.Url as U
+import qualified Build.SysConfig as SysConfig
+
+defaultUserAgent :: U.UserAgent
+defaultUserAgent = "git-annex/" ++ SysConfig.packageversion
+
+getUserAgent :: Annex (Maybe U.UserAgent)
+getUserAgent = Annex.getState $
+ Just . fromMaybe defaultUserAgent . Annex.useragent
+
+withUserAgent :: (Maybe U.UserAgent -> IO a) -> Annex a
+withUserAgent a = liftIO . a =<< getUserAgent
diff --git a/Annex/Version.hs b/Annex/Version.hs
new file mode 100644
index 000000000..2b4a49fd2
--- /dev/null
+++ b/Annex/Version.hs
@@ -0,0 +1,47 @@
+{- git-annex repository versioning
+ -
+ - Copyright 2010,2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Annex.Version where
+
+import Common.Annex
+import Config
+import qualified Annex
+
+type Version = String
+
+defaultVersion :: Version
+defaultVersion = "3"
+
+directModeVersion :: Version
+directModeVersion = "5"
+
+supportedVersions :: [Version]
+supportedVersions = [defaultVersion, directModeVersion]
+
+upgradableVersions :: [Version]
+#ifndef mingw32_HOST_OS
+upgradableVersions = ["0", "1", "2", "4"]
+#else
+upgradableVersions = ["2", "4"]
+#endif
+
+autoUpgradeableVersions :: [Version]
+autoUpgradeableVersions = ["4"]
+
+versionField :: ConfigKey
+versionField = annexConfig "version"
+
+getVersion :: Annex (Maybe Version)
+getVersion = annexVersion <$> Annex.getGitConfig
+
+setVersion :: Version -> Annex ()
+setVersion = setConfig versionField
+
+removeVersion :: Annex ()
+removeVersion = unsetConfig versionField
diff --git a/Annex/Wanted.hs b/Annex/Wanted.hs
new file mode 100644
index 000000000..04dcc1c1c
--- /dev/null
+++ b/Annex/Wanted.hs
@@ -0,0 +1,32 @@
+{- git-annex checking whether content is wanted
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Annex.Wanted where
+
+import Common.Annex
+import Logs.PreferredContent
+import Annex.UUID
+
+import qualified Data.Set as S
+
+{- Check if a file is preferred content for the local repository. -}
+wantGet :: Bool -> AssociatedFile -> Annex Bool
+wantGet def Nothing = return def
+wantGet def (Just file) = isPreferredContent Nothing S.empty file def
+
+{- Check if a file is preferred content for a remote. -}
+wantSend :: Bool -> AssociatedFile -> UUID -> Annex Bool
+wantSend def Nothing _ = return def
+wantSend def (Just file) to = isPreferredContent (Just to) S.empty file def
+
+{- Check if a file can be dropped, maybe from a remote.
+ - Don't drop files that are preferred content. -}
+wantDrop :: Bool -> Maybe UUID -> AssociatedFile -> Annex Bool
+wantDrop def _ Nothing = return $ not def
+wantDrop def from (Just file) = do
+ u <- maybe getUUID (return . id) from
+ not <$> isPreferredContent (Just u) (S.singleton u) file def
diff --git a/Assistant.hs b/Assistant.hs
new file mode 100644
index 000000000..d4786f99a
--- /dev/null
+++ b/Assistant.hs
@@ -0,0 +1,175 @@
+{- git-annex assistant daemon
+ -
+ - Copyright 2012-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Assistant where
+
+import qualified Annex
+import Assistant.Common
+import Assistant.DaemonStatus
+import Assistant.NamedThread
+import Assistant.Types.ThreadedMonad
+import Assistant.Threads.DaemonStatus
+import Assistant.Threads.Watcher
+import Assistant.Threads.Committer
+import Assistant.Threads.Pusher
+import Assistant.Threads.Merger
+import Assistant.Threads.TransferWatcher
+import Assistant.Threads.Transferrer
+import Assistant.Threads.SanityChecker
+import Assistant.Threads.Cronner
+import Assistant.Threads.ProblemFixer
+#ifdef WITH_CLIBS
+import Assistant.Threads.MountWatcher
+#endif
+import Assistant.Threads.NetWatcher
+import Assistant.Threads.Upgrader
+import Assistant.Threads.UpgradeWatcher
+import Assistant.Threads.TransferScanner
+import Assistant.Threads.TransferPoller
+import Assistant.Threads.ConfigMonitor
+import Assistant.Threads.Glacier
+#ifdef WITH_WEBAPP
+import Assistant.WebApp
+import Assistant.Threads.WebApp
+#ifdef WITH_PAIRING
+import Assistant.Threads.PairListener
+#endif
+#ifdef WITH_XMPP
+import Assistant.Threads.XMPPClient
+import Assistant.Threads.XMPPPusher
+#endif
+#else
+#warning Building without the webapp. You probably need to install Yesod..
+import Assistant.Types.UrlRenderer
+#endif
+import qualified Utility.Daemon
+import Utility.LogFile
+import Utility.ThreadScheduler
+import Utility.HumanTime
+import Annex.Perms
+import qualified Build.SysConfig as SysConfig
+
+import System.Log.Logger
+import Network.Socket (HostName)
+
+stopDaemon :: Annex ()
+stopDaemon = liftIO . Utility.Daemon.stopDaemon =<< fromRepo gitAnnexPidFile
+
+{- Starts the daemon. If the daemon is run in the foreground, once it's
+ - running, can start the browser.
+ -
+ - startbrowser is passed the url and html shim file, as well as the original
+ - stdout and stderr descriptors. -}
+startDaemon :: Bool -> Bool -> Maybe Duration -> Maybe String -> Maybe HostName -> Maybe (Maybe Handle -> Maybe Handle -> String -> FilePath -> IO ()) -> Annex ()
+startDaemon assistant foreground startdelay cannotrun listenhost startbrowser = do
+ Annex.changeState $ \s -> s { Annex.daemon = True }
+ pidfile <- fromRepo gitAnnexPidFile
+ logfile <- fromRepo gitAnnexLogFile
+#ifndef mingw32_HOST_OS
+ createAnnexDirectory (parentDir logfile)
+ logfd <- liftIO $ openLog logfile
+ if foreground
+ then do
+ origout <- liftIO $ catchMaybeIO $
+ fdToHandle =<< dup stdOutput
+ origerr <- liftIO $ catchMaybeIO $
+ fdToHandle =<< dup stdError
+ let undaemonize a = do
+ debugM desc $ "logging to " ++ logfile
+ Utility.Daemon.lockPidFile pidfile
+ Utility.LogFile.redirLog logfd
+ a
+ start undaemonize $
+ case startbrowser of
+ Nothing -> Nothing
+ Just a -> Just $ a origout origerr
+ else
+ start (Utility.Daemon.daemonize logfd (Just pidfile) False) Nothing
+#else
+ -- Windows is always foreground, and has no log file.
+ start id $
+ case startbrowser of
+ Nothing -> Nothing
+ Just a -> Just $ a Nothing Nothing
+#endif
+ where
+ desc
+ | assistant = "assistant"
+ | otherwise = "watch"
+ start daemonize webappwaiter = withThreadState $ \st -> do
+ checkCanWatch
+ dstatus <- startDaemonStatus
+ logfile <- fromRepo gitAnnexLogFile
+ liftIO $ debugM desc $ "logging to " ++ logfile
+ liftIO $ daemonize $
+ flip runAssistant (go webappwaiter)
+ =<< newAssistantData st dstatus
+
+#ifdef WITH_WEBAPP
+ go webappwaiter = do
+ d <- getAssistant id
+#else
+ go _webappwaiter = do
+#endif
+ notice ["starting", desc, "version", SysConfig.packageversion]
+ urlrenderer <- liftIO newUrlRenderer
+#ifdef WITH_WEBAPP
+ let webappthread = [ assist $ webAppThread d urlrenderer False cannotrun listenhost Nothing webappwaiter ]
+#else
+ let webappthread = []
+#endif
+ let threads = if isJust cannotrun
+ then webappthread
+ else webappthread ++
+ [ watch $ commitThread
+#ifdef WITH_WEBAPP
+#ifdef WITH_PAIRING
+ , assist $ pairListenerThread urlrenderer
+#endif
+#ifdef WITH_XMPP
+ , assist $ xmppClientThread urlrenderer
+ , assist $ xmppSendPackThread urlrenderer
+ , assist $ xmppReceivePackThread urlrenderer
+#endif
+#endif
+ , assist $ pushThread
+ , assist $ pushRetryThread
+ , assist $ mergeThread
+ , assist $ transferWatcherThread
+ , assist $ transferPollerThread
+ , assist $ transfererThread
+ , assist $ daemonStatusThread
+ , assist $ sanityCheckerDailyThread
+ , assist $ sanityCheckerHourlyThread
+ , assist $ problemFixerThread urlrenderer
+#ifdef WITH_CLIBS
+ , assist $ mountWatcherThread urlrenderer
+#endif
+ , assist $ netWatcherThread
+ , assist $ upgraderThread urlrenderer
+ , assist $ upgradeWatcherThread urlrenderer
+ , assist $ netWatcherFallbackThread
+ , assist $ transferScannerThread urlrenderer
+ , assist $ cronnerThread urlrenderer
+ , assist $ configMonitorThread
+ , assist $ glacierThread
+ , watch $ watchThread
+ -- must come last so that all threads that wait
+ -- on it have already started waiting
+ , watch $ sanityCheckerStartupThread startdelay
+ ]
+
+ mapM_ (startthread urlrenderer) threads
+ liftIO waitForTermination
+
+ watch a = (True, a)
+ assist a = (False, a)
+ startthread urlrenderer (watcher, t)
+ | watcher || assistant = startNamedThread urlrenderer t
+ | otherwise = noop
diff --git a/Assistant/Alert.hs b/Assistant/Alert.hs
new file mode 100644
index 000000000..c767d429d
--- /dev/null
+++ b/Assistant/Alert.hs
@@ -0,0 +1,433 @@
+{- git-annex assistant alerts
+ -
+ - Copyright 2012, 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE OverloadedStrings, CPP #-}
+
+module Assistant.Alert where
+
+import Common.Annex
+import Assistant.Types.Alert
+import Assistant.Alert.Utility
+import qualified Remote
+import Utility.Tense
+import Logs.Transfer
+import Types.Distribution
+
+import Data.String
+import qualified Data.Text as T
+import qualified Control.Exception as E
+
+#ifdef WITH_WEBAPP
+import Assistant.DaemonStatus
+import Assistant.WebApp.Types
+import Assistant.WebApp (renderUrl)
+import Yesod
+#endif
+import Assistant.Monad
+import Assistant.Types.UrlRenderer
+
+{- Makes a button for an alert that opens a Route.
+ -
+ - If autoclose is set, the button will close the alert it's
+ - attached to when clicked. -}
+#ifdef WITH_WEBAPP
+mkAlertButton :: Bool -> T.Text -> UrlRenderer -> Route WebApp -> Assistant AlertButton
+mkAlertButton autoclose label urlrenderer route = do
+ close <- asIO1 removeAlert
+ url <- liftIO $ renderUrl urlrenderer route []
+ return $ AlertButton
+ { buttonLabel = label
+ , buttonUrl = url
+ , buttonAction = if autoclose then Just close else Nothing
+ , buttonPrimary = True
+ }
+#endif
+
+renderData :: Alert -> TenseText
+renderData = tenseWords . alertData
+
+baseActivityAlert :: Alert
+baseActivityAlert = Alert
+ { alertClass = Activity
+ , alertHeader = Nothing
+ , alertMessageRender = renderData
+ , alertData = []
+ , alertCounter = 0
+ , alertBlockDisplay = False
+ , alertClosable = False
+ , alertPriority = Medium
+ , alertIcon = Just ActivityIcon
+ , alertCombiner = Nothing
+ , alertName = Nothing
+ , alertButtons = []
+ }
+
+warningAlert :: String -> String -> Alert
+warningAlert name msg = Alert
+ { alertClass = Warning
+ , alertHeader = Just $ tenseWords ["warning"]
+ , alertMessageRender = renderData
+ , alertData = [UnTensed $ T.pack msg]
+ , alertCounter = 0
+ , alertBlockDisplay = True
+ , alertClosable = True
+ , alertPriority = High
+ , alertIcon = Just ErrorIcon
+ , alertCombiner = Just $ dataCombiner $ \_old new -> new
+ , alertName = Just $ WarningAlert name
+ , alertButtons = []
+ }
+
+errorAlert :: String -> [AlertButton] -> Alert
+errorAlert msg buttons = Alert
+ { alertClass = Error
+ , alertHeader = Nothing
+ , alertMessageRender = renderData
+ , alertData = [UnTensed $ T.pack msg]
+ , alertCounter = 0
+ , alertBlockDisplay = True
+ , alertClosable = True
+ , alertPriority = Pinned
+ , alertIcon = Just ErrorIcon
+ , alertCombiner = Nothing
+ , alertName = Nothing
+ , alertButtons = buttons
+ }
+
+activityAlert :: Maybe TenseText -> [TenseChunk] -> Alert
+activityAlert header dat = baseActivityAlert
+ { alertHeader = header
+ , alertData = dat
+ }
+
+startupScanAlert :: Alert
+startupScanAlert = activityAlert Nothing
+ [Tensed "Performing" "Performed", "startup scan"]
+
+{- Displayed when a shutdown is occurring, so will be seen after shutdown
+ - has happened. -}
+shutdownAlert :: Alert
+shutdownAlert = warningAlert "shutdown" "git-annex has been shut down"
+
+commitAlert :: Alert
+commitAlert = activityAlert Nothing
+ [Tensed "Committing" "Committed", "changes to git"]
+
+showRemotes :: [Remote] -> TenseChunk
+showRemotes = UnTensed . T.intercalate ", " . map (T.pack . Remote.name)
+
+syncAlert :: [Remote] -> Alert
+syncAlert rs = baseActivityAlert
+ { alertName = Just SyncAlert
+ , alertHeader = Just $ tenseWords
+ [Tensed "Syncing" "Synced", "with", showRemotes rs]
+ , alertPriority = Low
+ , alertIcon = Just SyncIcon
+ }
+
+syncResultAlert :: [Remote] -> [Remote] -> Alert
+syncResultAlert succeeded failed = makeAlertFiller (not $ null succeeded) $
+ baseActivityAlert
+ { alertName = Just SyncAlert
+ , alertHeader = Just $ tenseWords msg
+ }
+ where
+ msg
+ | null succeeded = ["Failed to sync with", showRemotes failed]
+ | null failed = ["Synced with", showRemotes succeeded]
+ | otherwise =
+ [ "Synced with", showRemotes succeeded
+ , "but not with", showRemotes failed
+ ]
+
+sanityCheckAlert :: Alert
+sanityCheckAlert = activityAlert
+ (Just $ tenseWords [Tensed "Running" "Ran", "daily sanity check"])
+ ["to make sure everything is ok."]
+
+sanityCheckFixAlert :: String -> Alert
+sanityCheckFixAlert msg = Alert
+ { alertClass = Warning
+ , alertHeader = Just $ tenseWords ["Fixed a problem"]
+ , alertMessageRender = render
+ , alertData = [UnTensed $ T.pack msg]
+ , alertCounter = 0
+ , alertBlockDisplay = True
+ , alertPriority = High
+ , alertClosable = True
+ , alertIcon = Just ErrorIcon
+ , alertName = Just SanityCheckFixAlert
+ , alertCombiner = Just $ dataCombiner (++)
+ , alertButtons = []
+ }
+ where
+ render alert = tenseWords $ alerthead : alertData alert ++ [alertfoot]
+ alerthead = "The daily sanity check found and fixed a problem:"
+ alertfoot = "If these problems persist, consider filing a bug report."
+
+fsckingAlert :: AlertButton -> Maybe Remote -> Alert
+fsckingAlert button mr = baseActivityAlert
+ { alertData = case mr of
+ Nothing -> [ UnTensed $ T.pack $ "Consistency check in progress" ]
+ Just r -> [ UnTensed $ T.pack $ "Consistency check of " ++ Remote.name r ++ " in progress"]
+ , alertButtons = [button]
+ }
+
+showFscking :: UrlRenderer -> Maybe Remote -> IO (Either E.SomeException a) -> Assistant a
+showFscking urlrenderer mr a = do
+#ifdef WITH_WEBAPP
+ button <- mkAlertButton False (T.pack "Configure") urlrenderer ConfigFsckR
+ r <- alertDuring (fsckingAlert button mr) $
+ liftIO a
+#else
+ r <- liftIO a
+#endif
+ either (liftIO . E.throwIO) return r
+
+notFsckedNudge :: UrlRenderer -> Maybe Remote -> Assistant ()
+#ifdef WITH_WEBAPP
+notFsckedNudge urlrenderer mr = do
+ button <- mkAlertButton True (T.pack "Configure") urlrenderer ConfigFsckR
+ void $ addAlert (notFsckedAlert mr button)
+#else
+notFsckedNudge _ _ = noop
+#endif
+
+notFsckedAlert :: Maybe Remote -> AlertButton -> Alert
+notFsckedAlert mr button = Alert
+ { alertHeader = Just $ fromString $ concat
+ [ "You should enable consistency checking to protect your data"
+ , maybe "" (\r -> " in " ++ Remote.name r) mr
+ , "."
+ ]
+ , alertIcon = Just InfoIcon
+ , alertPriority = High
+ , alertButtons = [button]
+ , alertClosable = True
+ , alertClass = Message
+ , alertMessageRender = renderData
+ , alertCounter = 0
+ , alertBlockDisplay = True
+ , alertName = Just NotFsckedAlert
+ , alertCombiner = Just $ dataCombiner $ \_old new -> new
+ , alertData = []
+ }
+
+baseUpgradeAlert :: [AlertButton] -> TenseText -> Alert
+baseUpgradeAlert buttons message = Alert
+ { alertHeader = Just message
+ , alertIcon = Just UpgradeIcon
+ , alertPriority = High
+ , alertButtons = buttons
+ , alertClosable = True
+ , alertClass = Message
+ , alertMessageRender = renderData
+ , alertCounter = 0
+ , alertBlockDisplay = True
+ , alertName = Just UpgradeAlert
+ , alertCombiner = Just $ fullCombiner $ \new _old -> new
+ , alertData = []
+ }
+
+canUpgradeAlert :: AlertPriority -> GitAnnexVersion -> AlertButton -> Alert
+canUpgradeAlert priority version button =
+ (baseUpgradeAlert [button] $ fromString msg)
+ { alertPriority = priority
+ , alertData = [fromString $ " (version " ++ version ++ ")"]
+ }
+ where
+ msg = if priority >= High
+ then "An important upgrade of git-annex is available!"
+ else "An upgrade of git-annex is available."
+
+upgradeReadyAlert :: AlertButton -> Alert
+upgradeReadyAlert button = baseUpgradeAlert [button] $
+ fromString "A new version of git-annex has been installed."
+
+upgradingAlert :: Alert
+upgradingAlert = activityAlert Nothing [ fromString "Upgrading git-annex" ]
+
+upgradeFinishedAlert :: Maybe AlertButton -> GitAnnexVersion -> Alert
+upgradeFinishedAlert button version =
+ baseUpgradeAlert (maybe [] (:[]) button) $ fromString $
+ "Finished upgrading git-annex to version " ++ version
+
+upgradeFailedAlert :: String -> Alert
+upgradeFailedAlert msg = (errorAlert msg [])
+ { alertHeader = Just $ fromString "Upgrade failed." }
+
+brokenRepositoryAlert :: [AlertButton] -> Alert
+brokenRepositoryAlert = errorAlert "Serious problems have been detected with your repository. This needs your immediate attention!"
+
+repairingAlert :: String -> Alert
+repairingAlert repodesc = activityAlert Nothing
+ [ Tensed "Attempting to repair" "Repaired"
+ , UnTensed $ T.pack repodesc
+ ]
+
+pairingAlert :: AlertButton -> Alert
+pairingAlert button = baseActivityAlert
+ { alertData = [ UnTensed "Pairing in progress" ]
+ , alertPriority = High
+ , alertButtons = [button]
+ }
+
+pairRequestReceivedAlert :: String -> AlertButton -> Alert
+pairRequestReceivedAlert who button = Alert
+ { alertClass = Message
+ , alertHeader = Nothing
+ , alertMessageRender = renderData
+ , alertData = [UnTensed $ T.pack $ who ++ " is sending a pair request."]
+ , alertCounter = 0
+ , alertBlockDisplay = False
+ , alertPriority = High
+ , alertClosable = True
+ , alertIcon = Just InfoIcon
+ , alertName = Just $ PairAlert who
+ , alertCombiner = Just $ dataCombiner $ \_old new -> new
+ , alertButtons = [button]
+ }
+
+pairRequestAcknowledgedAlert :: String -> Maybe AlertButton -> Alert
+pairRequestAcknowledgedAlert who button = baseActivityAlert
+ { alertData = ["Pairing with", UnTensed (T.pack who), Tensed "in progress" "complete"]
+ , alertPriority = High
+ , alertName = Just $ PairAlert who
+ , alertCombiner = Just $ dataCombiner $ \_old new -> new
+ , alertButtons = maybe [] (:[]) button
+ }
+
+xmppNeededAlert :: AlertButton -> Alert
+xmppNeededAlert button = Alert
+ { alertHeader = Just "Share with friends, and keep your devices in sync across the cloud."
+ , alertIcon = Just TheCloud
+ , alertPriority = High
+ , alertButtons = [button]
+ , alertClosable = True
+ , alertClass = Message
+ , alertMessageRender = renderData
+ , alertCounter = 0
+ , alertBlockDisplay = True
+ , alertName = Just $ XMPPNeededAlert
+ , alertCombiner = Just $ dataCombiner $ \_old new -> new
+ , alertData = []
+ }
+
+cloudRepoNeededAlert :: Maybe String -> AlertButton -> Alert
+cloudRepoNeededAlert friendname button = Alert
+ { alertHeader = Just $ fromString $ unwords
+ [ "Unable to download files from"
+ , (fromMaybe "your other devices" friendname) ++ "."
+ ]
+ , alertIcon = Just ErrorIcon
+ , alertPriority = High
+ , alertButtons = [button]
+ , alertClosable = True
+ , alertClass = Message
+ , alertMessageRender = renderData
+ , alertCounter = 0
+ , alertBlockDisplay = True
+ , alertName = Just $ CloudRepoNeededAlert
+ , alertCombiner = Just $ dataCombiner $ \_old new -> new
+ , alertData = []
+ }
+
+remoteRemovalAlert :: String -> AlertButton -> Alert
+remoteRemovalAlert desc button = Alert
+ { alertHeader = Just $ fromString $
+ "The repository \"" ++ desc ++
+ "\" has been emptied, and can now be removed."
+ , alertIcon = Just InfoIcon
+ , alertPriority = High
+ , alertButtons = [button]
+ , alertClosable = True
+ , alertClass = Message
+ , alertMessageRender = renderData
+ , alertCounter = 0
+ , alertBlockDisplay = True
+ , alertName = Just $ RemoteRemovalAlert desc
+ , alertCombiner = Just $ dataCombiner $ \_old new -> new
+ , alertData = []
+ }
+
+{- Show a message that relates to a list of files.
+ -
+ - The most recent several files are shown, and a count of any others. -}
+fileAlert :: TenseChunk -> [FilePath] -> Alert
+fileAlert msg files = (activityAlert Nothing shortfiles)
+ { alertName = Just $ FileAlert msg
+ , alertMessageRender = renderer
+ , alertCounter = counter
+ , alertCombiner = Just $ fullCombiner combiner
+ }
+ where
+ maxfilesshown = 10
+
+ (somefiles, counter) = splitcounter (dedupadjacent files)
+ shortfiles = map (fromString . shortFile . takeFileName) somefiles
+
+ renderer alert = tenseWords $ msg : alertData alert ++ showcounter
+ where
+ showcounter = case alertCounter alert of
+ 0 -> []
+ _ -> [fromString $ "and " ++ show (alertCounter alert) ++ " other files"]
+
+ dedupadjacent (x:y:rest)
+ | x == y = dedupadjacent (y:rest)
+ | otherwise = x : dedupadjacent (y:rest)
+ dedupadjacent (x:[]) = [x]
+ dedupadjacent [] = []
+
+ {- Note that this ensures the counter is never 1; no need to say
+ - "1 file" when the filename could be shown. -}
+ splitcounter l
+ | length l <= maxfilesshown = (l, 0)
+ | otherwise =
+ let (keep, rest) = splitAt (maxfilesshown - 1) l
+ in (keep, length rest)
+
+ combiner new old =
+ let (fs, n) = splitcounter $
+ dedupadjacent $ alertData new ++ alertData old
+ cnt = n + alertCounter new + alertCounter old
+ in old
+ { alertData = fs
+ , alertCounter = cnt
+ }
+
+addFileAlert :: [FilePath] -> Alert
+addFileAlert = fileAlert (Tensed "Adding" "Added")
+
+{- This is only used as a success alert after a transfer, not during it. -}
+transferFileAlert :: Direction -> Bool -> FilePath -> Alert
+transferFileAlert direction True file
+ | direction == Upload = fileAlert "Uploaded" [file]
+ | otherwise = fileAlert "Downloaded" [file]
+transferFileAlert direction False file
+ | direction == Upload = fileAlert "Upload failed" [file]
+ | otherwise = fileAlert "Download failed" [file]
+
+dataCombiner :: ([TenseChunk] -> [TenseChunk] -> [TenseChunk]) -> AlertCombiner
+dataCombiner combiner = fullCombiner $
+ \new old -> old { alertData = alertData new `combiner` alertData old }
+
+fullCombiner :: (Alert -> Alert -> Alert) -> AlertCombiner
+fullCombiner combiner new old
+ | alertClass new /= alertClass old = Nothing
+ | alertName new == alertName old =
+ Just $! new `combiner` old
+ | otherwise = Nothing
+
+shortFile :: FilePath -> String
+shortFile f
+ | len < maxlen = f
+ | otherwise = take half f ++ ".." ++ drop (len - half) f
+ where
+ len = length f
+ maxlen = 20
+ half = (maxlen - 2) `div` 2
+
diff --git a/Assistant/Alert/Utility.hs b/Assistant/Alert/Utility.hs
new file mode 100644
index 000000000..db2ea1925
--- /dev/null
+++ b/Assistant/Alert/Utility.hs
@@ -0,0 +1,130 @@
+{- git-annex assistant alert utilities
+ -
+ - Copyright 2012, 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.Alert.Utility where
+
+import Common.Annex
+import Assistant.Types.Alert
+import Utility.Tense
+
+import qualified Data.Text as T
+import Data.Text (Text)
+import qualified Data.Map as M
+
+{- This is as many alerts as it makes sense to display at a time.
+ - A display might be smaller, or larger, the point is to not overwhelm the
+ - user with a ton of alerts. -}
+displayAlerts :: Int
+displayAlerts = 6
+
+{- This is not a hard maximum, but there's no point in keeping a great
+ - many filler alerts in an AlertMap, so when there's more than this many,
+ - they start being pruned, down toward displayAlerts. -}
+maxAlerts :: Int
+maxAlerts = displayAlerts * 2
+
+type AlertPair = (AlertId, Alert)
+
+{- The desired order is the reverse of:
+ -
+ - - Pinned alerts
+ - - High priority alerts, newest first
+ - - Medium priority Activity, newest first (mostly used for Activity)
+ - - Low priority alerts, newest first
+ - - Filler priorty alerts, newest first
+ - - Ties are broken by the AlertClass, with Errors etc coming first.
+ -}
+compareAlertPairs :: AlertPair -> AlertPair -> Ordering
+compareAlertPairs
+ (aid, Alert { alertClass = aclass, alertPriority = aprio })
+ (bid, Alert { alertClass = bclass, alertPriority = bprio })
+ = compare aprio bprio
+ `thenOrd` compare aid bid
+ `thenOrd` compare aclass bclass
+
+sortAlertPairs :: [AlertPair] -> [AlertPair]
+sortAlertPairs = sortBy compareAlertPairs
+
+{- Renders an alert's header for display, if it has one. -}
+renderAlertHeader :: Alert -> Maybe Text
+renderAlertHeader alert = renderTense (alertTense alert) <$> alertHeader alert
+
+{- Renders an alert's message for display. -}
+renderAlertMessage :: Alert -> Text
+renderAlertMessage alert = renderTense (alertTense alert) $
+ (alertMessageRender alert) alert
+
+showAlert :: Alert -> String
+showAlert alert = T.unpack $ T.unwords $ catMaybes
+ [ renderAlertHeader alert
+ , Just $ renderAlertMessage alert
+ ]
+
+alertTense :: Alert -> Tense
+alertTense alert
+ | alertClass alert == Activity = Present
+ | otherwise = Past
+
+{- Checks if two alerts display the same. -}
+effectivelySameAlert :: Alert -> Alert -> Bool
+effectivelySameAlert x y = all id
+ [ alertClass x == alertClass y
+ , alertHeader x == alertHeader y
+ , alertData x == alertData y
+ , alertBlockDisplay x == alertBlockDisplay y
+ , alertClosable x == alertClosable y
+ , alertPriority x == alertPriority y
+ ]
+
+makeAlertFiller :: Bool -> Alert -> Alert
+makeAlertFiller success alert
+ | isFiller alert = alert
+ | otherwise = alert
+ { alertClass = if c == Activity then c' else c
+ , alertPriority = Filler
+ , alertClosable = True
+ , alertButtons = []
+ , alertIcon = Just $ if success then SuccessIcon else ErrorIcon
+ }
+ where
+ c = alertClass alert
+ c'
+ | success = Success
+ | otherwise = Error
+
+isFiller :: Alert -> Bool
+isFiller alert = alertPriority alert == Filler
+
+{- Updates the Alertmap, adding or updating an alert.
+ -
+ - Any old filler that looks the same as the alert is removed.
+ -
+ - Or, if the alert has an alertCombiner that combines it with
+ - an old alert, the old alert is replaced with the result, and the
+ - alert is removed.
+ -
+ - Old filler alerts are pruned once maxAlerts is reached.
+ -}
+mergeAlert :: AlertId -> Alert -> AlertMap -> AlertMap
+mergeAlert i al m = maybe updatePrune updateCombine (alertCombiner al)
+ where
+ pruneSame k al' = k == i || not (effectivelySameAlert al al')
+ pruneBloat m'
+ | bloat > 0 = M.fromList $ pruneold $ M.toList m'
+ | otherwise = m'
+ where
+ bloat = M.size m' - maxAlerts
+ pruneold l =
+ let (f, rest) = partition (\(_, a) -> isFiller a) l
+ in drop bloat f ++ rest
+ updatePrune = pruneBloat $ M.filterWithKey pruneSame $
+ M.insertWith' const i al m
+ updateCombine combiner =
+ let combined = M.mapMaybe (combiner al) m
+ in if M.null combined
+ then updatePrune
+ else M.delete i $ M.union combined m
diff --git a/Assistant/BranchChange.hs b/Assistant/BranchChange.hs
new file mode 100644
index 000000000..c9354544a
--- /dev/null
+++ b/Assistant/BranchChange.hs
@@ -0,0 +1,19 @@
+{- git-annex assistant git-annex branch change tracking
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.BranchChange where
+
+import Assistant.Common
+import Assistant.Types.BranchChange
+
+import Control.Concurrent.MSampleVar
+
+branchChanged :: Assistant ()
+branchChanged = flip writeSV () <<~ (fromBranchChangeHandle . branchChangeHandle)
+
+waitBranchChange :: Assistant ()
+waitBranchChange = readSV <<~ (fromBranchChangeHandle . branchChangeHandle)
diff --git a/Assistant/Changes.hs b/Assistant/Changes.hs
new file mode 100644
index 000000000..2ecd2036c
--- /dev/null
+++ b/Assistant/Changes.hs
@@ -0,0 +1,47 @@
+{- git-annex assistant change tracking
+ -
+ - Copyright 2012-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.Changes where
+
+import Assistant.Common
+import Assistant.Types.Changes
+import Utility.TList
+
+import Data.Time.Clock
+import Control.Concurrent.STM
+
+{- Handlers call this when they made a change that needs to get committed. -}
+madeChange :: FilePath -> ChangeInfo -> Assistant (Maybe Change)
+madeChange f t = Just <$> (Change <$> liftIO getCurrentTime <*> pure f <*> pure t)
+
+noChange :: Assistant (Maybe Change)
+noChange = return Nothing
+
+{- Indicates an add needs to be done, but has not started yet. -}
+pendingAddChange :: FilePath -> Assistant (Maybe Change)
+pendingAddChange f = Just <$> (PendingAddChange <$> liftIO getCurrentTime <*> pure f)
+
+{- Gets all unhandled changes.
+ - Blocks until at least one change is made. -}
+getChanges :: Assistant [Change]
+getChanges = (atomically . getTList) <<~ changePool
+
+{- Gets all unhandled changes, without blocking. -}
+getAnyChanges :: Assistant [Change]
+getAnyChanges = (atomically . takeTList) <<~ changePool
+
+{- Puts unhandled changes back into the pool.
+ - Note: Original order is not preserved. -}
+refillChanges :: [Change] -> Assistant ()
+refillChanges cs = (atomically . flip appendTList cs) <<~ changePool
+
+{- Records a change to the pool. -}
+recordChange :: Change -> Assistant ()
+recordChange c = (atomically . flip snocTList c) <<~ changePool
+
+recordChanges :: [Change] -> Assistant ()
+recordChanges = refillChanges
diff --git a/Assistant/Commits.hs b/Assistant/Commits.hs
new file mode 100644
index 000000000..7d1d3780f
--- /dev/null
+++ b/Assistant/Commits.hs
@@ -0,0 +1,23 @@
+{- git-annex assistant commit tracking
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.Commits where
+
+import Assistant.Common
+import Assistant.Types.Commits
+import Utility.TList
+
+import Control.Concurrent.STM
+
+{- Gets all unhandled commits.
+ - Blocks until at least one commit is made. -}
+getCommits :: Assistant [Commit]
+getCommits = (atomically . getTList) <<~ commitChan
+
+{- Records a commit in the channel. -}
+recordCommit :: Assistant ()
+recordCommit = (atomically . flip consTList Commit) <<~ commitChan
diff --git a/Assistant/Common.hs b/Assistant/Common.hs
new file mode 100644
index 000000000..f9719422d
--- /dev/null
+++ b/Assistant/Common.hs
@@ -0,0 +1,14 @@
+{- Common infrastructure for the git-annex assistant.
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.Common (module X) where
+
+import Common.Annex as X
+import Assistant.Monad as X
+import Assistant.Types.DaemonStatus as X
+import Assistant.Types.NamedThread as X
+import Assistant.Types.Alert as X
diff --git a/Assistant/DaemonStatus.hs b/Assistant/DaemonStatus.hs
new file mode 100644
index 000000000..7268bbbfb
--- /dev/null
+++ b/Assistant/DaemonStatus.hs
@@ -0,0 +1,262 @@
+{- git-annex assistant daemon status
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.DaemonStatus where
+
+import Assistant.Common
+import Assistant.Alert.Utility
+import Utility.Tmp
+import Assistant.Types.NetMessager
+import Utility.NotificationBroadcaster
+import Logs.Transfer
+import Logs.Trust
+import qualified Remote
+import qualified Types.Remote as Remote
+import qualified Git
+
+import Control.Concurrent.STM
+import System.Posix.Types
+import Data.Time.Clock.POSIX
+import Data.Time
+import System.Locale
+import qualified Data.Map as M
+import qualified Data.Text as T
+
+getDaemonStatus :: Assistant DaemonStatus
+getDaemonStatus = (atomically . readTMVar) <<~ daemonStatusHandle
+
+modifyDaemonStatus_ :: (DaemonStatus -> DaemonStatus) -> Assistant ()
+modifyDaemonStatus_ a = modifyDaemonStatus $ \s -> (a s, ())
+
+modifyDaemonStatus :: (DaemonStatus -> (DaemonStatus, b)) -> Assistant b
+modifyDaemonStatus a = do
+ dstatus <- getAssistant daemonStatusHandle
+ liftIO $ do
+ (s, b) <- atomically $ do
+ r@(s, _) <- a <$> takeTMVar dstatus
+ putTMVar dstatus s
+ return r
+ sendNotification $ changeNotifier s
+ return b
+
+{- Returns a function that updates the lists of syncable remotes
+ - and other associated information. -}
+calcSyncRemotes :: Annex (DaemonStatus -> DaemonStatus)
+calcSyncRemotes = do
+ rs <- filter (remoteAnnexSync . Remote.gitconfig) .
+ concat . Remote.byCost <$> Remote.remoteList
+ alive <- trustExclude DeadTrusted (map Remote.uuid rs)
+ let good r = Remote.uuid r `elem` alive
+ let syncable = filter good rs
+ let syncdata = filter (not . remoteAnnexIgnore . Remote.gitconfig) $
+ filter (not . isXMPPRemote) syncable
+
+ return $ \dstatus -> dstatus
+ { syncRemotes = syncable
+ , syncGitRemotes = filter Remote.syncableRemote syncable
+ , syncDataRemotes = syncdata
+ , syncingToCloudRemote = any iscloud syncdata
+ }
+ where
+ iscloud r = not (Remote.readonly r) && Remote.globallyAvailable r
+
+{- Updates the syncRemotes list from the list of all remotes in Annex state. -}
+updateSyncRemotes :: Assistant ()
+updateSyncRemotes = do
+ modifyDaemonStatus_ =<< liftAnnex calcSyncRemotes
+ status <- getDaemonStatus
+ liftIO $ sendNotification $ syncRemotesNotifier status
+
+ when (syncingToCloudRemote status) $
+ updateAlertMap $
+ M.filter $ \alert ->
+ alertName alert /= Just CloudRepoNeededAlert
+
+updateScheduleLog :: Assistant ()
+updateScheduleLog =
+ liftIO . sendNotification =<< scheduleLogNotifier <$> getDaemonStatus
+
+{- Load any previous daemon status file, and store it in a MVar for this
+ - process to use as its DaemonStatus. Also gets current transfer status. -}
+startDaemonStatus :: Annex DaemonStatusHandle
+startDaemonStatus = do
+ file <- fromRepo gitAnnexDaemonStatusFile
+ status <- liftIO $
+ flip catchDefaultIO (readDaemonStatusFile file) =<< newDaemonStatus
+ transfers <- M.fromList <$> getTransfers
+ addsync <- calcSyncRemotes
+ liftIO $ atomically $ newTMVar $ addsync $ status
+ { scanComplete = False
+ , sanityCheckRunning = False
+ , currentTransfers = transfers
+ }
+
+{- Don't just dump out the structure, because it will change over time,
+ - and parts of it are not relevant. -}
+writeDaemonStatusFile :: FilePath -> DaemonStatus -> IO ()
+writeDaemonStatusFile file status =
+ viaTmp writeFile file =<< serialized <$> getPOSIXTime
+ where
+ serialized now = unlines
+ [ "lastRunning:" ++ show now
+ , "scanComplete:" ++ show (scanComplete status)
+ , "sanityCheckRunning:" ++ show (sanityCheckRunning status)
+ , "lastSanityCheck:" ++ maybe "" show (lastSanityCheck status)
+ ]
+
+readDaemonStatusFile :: FilePath -> IO DaemonStatus
+readDaemonStatusFile file = parse <$> newDaemonStatus <*> readFile file
+ where
+ parse status = foldr parseline status . lines
+ parseline line status
+ | key == "lastRunning" = parseval readtime $ \v ->
+ status { lastRunning = Just v }
+ | key == "scanComplete" = parseval readish $ \v ->
+ status { scanComplete = v }
+ | key == "sanityCheckRunning" = parseval readish $ \v ->
+ status { sanityCheckRunning = v }
+ | key == "lastSanityCheck" = parseval readtime $ \v ->
+ status { lastSanityCheck = Just v }
+ | otherwise = status -- unparsable line
+ where
+ (key, value) = separate (== ':') line
+ parseval parser a = maybe status a (parser value)
+ readtime s = do
+ d <- parseTime defaultTimeLocale "%s%Qs" s
+ Just $ utcTimeToPOSIXSeconds d
+
+{- Checks if a time stamp was made after the daemon was lastRunning.
+ -
+ - Some slop is built in; this really checks if the time stamp was made
+ - at least ten minutes after the daemon was lastRunning. This is to
+ - ensure the daemon shut down cleanly, and deal with minor clock skew.
+ -
+ - If the daemon has never ran before, this always returns False.
+ -}
+afterLastDaemonRun :: EpochTime -> DaemonStatus -> Bool
+afterLastDaemonRun timestamp status = maybe False (< t) (lastRunning status)
+ where
+ t = realToFrac (timestamp + slop) :: POSIXTime
+ slop = fromIntegral tenMinutes
+
+tenMinutes :: Int
+tenMinutes = 10 * 60
+
+{- Mutates the transfer map. Runs in STM so that the transfer map can
+ - be modified in the same transaction that modifies the transfer queue.
+ - Note that this does not send a notification of the change; that's left
+ - to the caller. -}
+adjustTransfersSTM :: DaemonStatusHandle -> (TransferMap -> TransferMap) -> STM ()
+adjustTransfersSTM dstatus a = do
+ s <- takeTMVar dstatus
+ putTMVar dstatus $ s { currentTransfers = a (currentTransfers s) }
+
+{- Checks if a transfer is currently running. -}
+checkRunningTransferSTM :: DaemonStatusHandle -> Transfer -> STM Bool
+checkRunningTransferSTM dstatus t = M.member t . currentTransfers
+ <$> readTMVar dstatus
+
+{- Alters a transfer's info, if the transfer is in the map. -}
+alterTransferInfo :: Transfer -> (TransferInfo -> TransferInfo) -> Assistant ()
+alterTransferInfo t a = updateTransferInfo' $ M.adjust a t
+
+{- Updates a transfer's info. Adds the transfer to the map if necessary,
+ - or if already present, updates it while preserving the old transferTid,
+ - transferPaused, and bytesComplete values, which are not written to disk. -}
+updateTransferInfo :: Transfer -> TransferInfo -> Assistant ()
+updateTransferInfo t info = updateTransferInfo' $ M.insertWith' merge t info
+ where
+ merge new old = new
+ { transferTid = maybe (transferTid new) Just (transferTid old)
+ , transferPaused = transferPaused new || transferPaused old
+ , bytesComplete = maybe (bytesComplete new) Just (bytesComplete old)
+ }
+
+updateTransferInfo' :: (TransferMap -> TransferMap) -> Assistant ()
+updateTransferInfo' a = notifyTransfer `after` modifyDaemonStatus_ update
+ where
+ update s = s { currentTransfers = a (currentTransfers s) }
+
+{- Removes a transfer from the map, and returns its info. -}
+removeTransfer :: Transfer -> Assistant (Maybe TransferInfo)
+removeTransfer t = notifyTransfer `after` modifyDaemonStatus remove
+ where
+ remove s =
+ let (info, ts) = M.updateLookupWithKey
+ (\_k _v -> Nothing)
+ t (currentTransfers s)
+ in (s { currentTransfers = ts }, info)
+
+{- Send a notification when a transfer is changed. -}
+notifyTransfer :: Assistant ()
+notifyTransfer = do
+ dstatus <- getAssistant daemonStatusHandle
+ liftIO $ sendNotification
+ =<< transferNotifier <$> atomically (readTMVar dstatus)
+
+{- Send a notification when alerts are changed. -}
+notifyAlert :: Assistant ()
+notifyAlert = do
+ dstatus <- getAssistant daemonStatusHandle
+ liftIO $ sendNotification
+ =<< alertNotifier <$> atomically (readTMVar dstatus)
+
+{- Returns the alert's identifier, which can be used to remove it. -}
+addAlert :: Alert -> Assistant AlertId
+addAlert alert = do
+ notice [showAlert alert]
+ notifyAlert `after` modifyDaemonStatus add
+ where
+ add s = (s { lastAlertId = i, alertMap = m }, i)
+ where
+ i = nextAlertId $ lastAlertId s
+ m = mergeAlert i alert (alertMap s)
+
+removeAlert :: AlertId -> Assistant ()
+removeAlert i = updateAlert i (const Nothing)
+
+updateAlert :: AlertId -> (Alert -> Maybe Alert) -> Assistant ()
+updateAlert i a = updateAlertMap $ \m -> M.update a i m
+
+updateAlertMap :: (AlertMap -> AlertMap) -> Assistant ()
+updateAlertMap a = notifyAlert `after` modifyDaemonStatus_ update
+ where
+ update s = s { alertMap = a (alertMap s) }
+
+{- Displays an alert while performing an activity that returns True on
+ - success.
+ -
+ - The alert is left visible afterwards, as filler.
+ - Old filler is pruned, to prevent the map growing too large. -}
+alertWhile :: Alert -> Assistant Bool -> Assistant Bool
+alertWhile alert a = alertWhile' alert $ do
+ r <- a
+ return (r, r)
+
+{- Like alertWhile, but allows the activity to return a value too. -}
+alertWhile' :: Alert -> Assistant (Bool, a) -> Assistant a
+alertWhile' alert a = do
+ let alert' = alert { alertClass = Activity }
+ i <- addAlert alert'
+ (ok, r) <- a
+ updateAlertMap $ mergeAlert i $ makeAlertFiller ok alert'
+ return r
+
+{- Displays an alert while performing an activity, then removes it. -}
+alertDuring :: Alert -> Assistant a -> Assistant a
+alertDuring alert a = do
+ i <- addAlert $ alert { alertClass = Activity }
+ removeAlert i `after` a
+
+{- Remotes using the XMPP transport have urls like xmpp::user@host -}
+isXMPPRemote :: Remote -> Bool
+isXMPPRemote remote = Git.repoIsUrl r && "xmpp::" `isPrefixOf` Git.repoLocation r
+ where
+ r = Remote.repo remote
+
+getXMPPClientID :: Remote -> ClientID
+getXMPPClientID r = T.pack $ drop (length "xmpp::") (Git.repoLocation (Remote.repo r))
diff --git a/Assistant/DeleteRemote.hs b/Assistant/DeleteRemote.hs
new file mode 100644
index 000000000..cc05786e4
--- /dev/null
+++ b/Assistant/DeleteRemote.hs
@@ -0,0 +1,89 @@
+{- git-annex assistant remote deletion utilities
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Assistant.DeleteRemote where
+
+import Assistant.Common
+import Assistant.Types.UrlRenderer
+import Assistant.TransferQueue
+import Logs.Transfer
+import Logs.Location
+import Assistant.DaemonStatus
+import qualified Remote
+import Remote.List
+import qualified Git.Remote
+import Logs.Trust
+import qualified Annex
+
+#ifdef WITH_WEBAPP
+import Assistant.WebApp.Types
+import Assistant.Alert
+import qualified Data.Text as T
+#endif
+
+{- Removes a remote (but leave the repository as-is), and returns the old
+ - Remote data. -}
+disableRemote :: UUID -> Assistant Remote
+disableRemote uuid = do
+ remote <- fromMaybe (error "unknown remote")
+ <$> liftAnnex (Remote.remoteFromUUID uuid)
+ liftAnnex $ do
+ inRepo $ Git.Remote.remove (Remote.name remote)
+ void $ remoteListRefresh
+ updateSyncRemotes
+ return remote
+
+{- Removes a remote, marking it dead .-}
+removeRemote :: UUID -> Assistant Remote
+removeRemote uuid = do
+ liftAnnex $ trustSet uuid DeadTrusted
+ disableRemote uuid
+
+{- Called when a Remote is probably empty, to remove it.
+ -
+ - This does one last check for any objects remaining in the Remote,
+ - and if there are any, queues Downloads of them, and defers removing
+ - the remote for later. This is to catch any objects not referred to
+ - in keys in the current branch.
+ -}
+removableRemote :: UrlRenderer -> UUID -> Assistant ()
+removableRemote urlrenderer uuid = do
+ keys <- getkeys
+ if null keys
+ then finishRemovingRemote urlrenderer uuid
+ else do
+ r <- fromMaybe (error "unknown remote")
+ <$> liftAnnex (Remote.remoteFromUUID uuid)
+ mapM_ (queueremaining r) keys
+ where
+ queueremaining r k =
+ queueTransferWhenSmall "remaining object in unwanted remote"
+ Nothing (Transfer Download uuid k) r
+ {- Scanning for keys can take a long time; do not tie up
+ - the Annex monad while doing it, so other threads continue to
+ - run. -}
+ getkeys = do
+ a <- liftAnnex $ Annex.withCurrentState $ loggedKeysFor uuid
+ liftIO a
+
+{- With the webapp, this asks the user to click on a button to finish
+ - removing the remote.
+ -
+ - Without the webapp, just do the removal now.
+ -}
+finishRemovingRemote :: UrlRenderer -> UUID -> Assistant ()
+#ifdef WITH_WEBAPP
+finishRemovingRemote urlrenderer uuid = do
+ desc <- liftAnnex $ Remote.prettyUUID uuid
+ button <- mkAlertButton True (T.pack "Finish deletion process") urlrenderer $
+ FinishDeleteRepositoryR uuid
+ void $ addAlert $ remoteRemovalAlert desc button
+#else
+finishRemovingRemote _ uuid = void $ removeRemote uuid
+#endif
diff --git a/Assistant/Drop.hs b/Assistant/Drop.hs
new file mode 100644
index 000000000..d677a69c8
--- /dev/null
+++ b/Assistant/Drop.hs
@@ -0,0 +1,112 @@
+{- git-annex assistant dropping of unwanted content
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.Drop where
+
+import Assistant.Common
+import Assistant.DaemonStatus
+import Logs.Location
+import Logs.Trust
+import Types.Remote (uuid)
+import qualified Remote
+import qualified Command.Drop
+import Command
+import Annex.Wanted
+import Annex.Exception
+import Config
+import Annex.Content.Direct
+
+import qualified Data.Set as S
+
+type Reason = String
+
+{- Drop from local and/or remote when allowed by the preferred content and
+ - numcopies settings. -}
+handleDrops :: Reason -> Bool -> Key -> AssociatedFile -> Maybe Remote -> Assistant ()
+handleDrops _ _ _ Nothing _ = noop
+handleDrops reason fromhere key f knownpresentremote = do
+ syncrs <- syncDataRemotes <$> getDaemonStatus
+ locs <- liftAnnex $ loggedLocations key
+ handleDropsFrom locs syncrs reason fromhere key f knownpresentremote
+
+{- The UUIDs are ones where the content is believed to be present.
+ - The Remote list can include other remotes that do not have the content;
+ - only ones that match the UUIDs will be dropped from.
+ - If allowed to drop fromhere, that drop will be tried first.
+ -
+ - In direct mode, all associated files are checked, and only if all
+ - of them are unwanted are they dropped.
+ -}
+handleDropsFrom :: [UUID] -> [Remote] -> Reason -> Bool -> Key -> AssociatedFile -> Maybe Remote -> Assistant ()
+handleDropsFrom _ _ _ _ _ Nothing _ = noop
+handleDropsFrom locs rs reason fromhere key (Just afile) knownpresentremote = do
+ fs <- liftAnnex $ ifM isDirect
+ ( do
+ l <- associatedFilesRelative key
+ if null l
+ then return [afile]
+ else return l
+ , return [afile]
+ )
+ n <- getcopies fs
+ if fromhere && checkcopies n Nothing
+ then go fs rs =<< dropl fs n
+ else go fs rs n
+ where
+ getcopies fs = liftAnnex $ do
+ (untrusted, have) <- trustPartition UnTrusted locs
+ numcopies <- maximum <$> mapM (getNumCopies <=< numCopies) fs
+ return (length have, numcopies, S.fromList untrusted)
+
+ {- Check that we have enough copies still to drop the content.
+ - When the remote being dropped from is untrusted, it was not
+ - counted as a copy, so having only numcopies suffices. Otherwise,
+ - we need more than numcopies to safely drop. -}
+ checkcopies (have, numcopies, _untrusted) Nothing = have > numcopies
+ checkcopies (have, numcopies, untrusted) (Just u)
+ | S.member u untrusted = have >= numcopies
+ | otherwise = have > numcopies
+
+ decrcopies (have, numcopies, untrusted) Nothing =
+ (have - 1, numcopies, untrusted)
+ decrcopies v@(_have, _numcopies, untrusted) (Just u)
+ | S.member u untrusted = v
+ | otherwise = decrcopies v Nothing
+
+ go _ [] _ = noop
+ go fs (r:rest) n
+ | uuid r `S.notMember` slocs = go fs rest n
+ | checkcopies n (Just $ Remote.uuid r) =
+ dropr fs r n >>= go fs rest
+ | otherwise = noop
+
+ checkdrop fs n@(have, numcopies, _untrusted) u a =
+ ifM (liftAnnex $ allM (wantDrop True u . Just) fs)
+ ( ifM (liftAnnex $ safely $ doCommand $ a (Just numcopies))
+ ( do
+ debug
+ [ "dropped"
+ , afile
+ , "(from " ++ maybe "here" show u ++ ")"
+ , "(copies now " ++ show (have - 1) ++ ")"
+ , ": " ++ reason
+ ]
+ return $ decrcopies n u
+ , return n
+ )
+ , return n
+ )
+
+ dropl fs n = checkdrop fs n Nothing $ \numcopies ->
+ Command.Drop.startLocal afile numcopies key knownpresentremote
+
+ dropr fs r n = checkdrop fs n (Just $ Remote.uuid r) $ \numcopies ->
+ Command.Drop.startRemote afile numcopies key r
+
+ safely a = either (const False) id <$> tryAnnex a
+
+ slocs = S.fromList locs
diff --git a/Assistant/Install.hs b/Assistant/Install.hs
new file mode 100644
index 000000000..dee1b5be3
--- /dev/null
+++ b/Assistant/Install.hs
@@ -0,0 +1,101 @@
+{- Assistant installation
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Assistant.Install where
+
+import Assistant.Common
+import Assistant.Install.AutoStart
+import Assistant.Install.Menu
+import Assistant.Ssh
+import Config.Files
+import Utility.FileMode
+import Utility.Shell
+import Utility.Tmp
+import Utility.Env
+
+#ifdef darwin_HOST_OS
+import Utility.OSX
+#else
+import Utility.FreeDesktop
+#endif
+
+standaloneAppBase :: IO (Maybe FilePath)
+standaloneAppBase = getEnv "GIT_ANNEX_APP_BASE"
+
+{- The standalone app does not have an installation process.
+ - So when it's run, it needs to set up autostarting of the assistant
+ - daemon, as well as writing the programFile, and putting a
+ - git-annex-shell wrapper into ~/.ssh
+ -
+ - Note that this is done every time it's started, so if the user moves
+ - it around, the paths this sets up won't break.
+ -}
+ensureInstalled :: IO ()
+ensureInstalled = go =<< standaloneAppBase
+ where
+ go Nothing = noop
+ go (Just base) = do
+ let program = base </> "git-annex"
+ programfile <- programFile
+ createDirectoryIfMissing True (parentDir programfile)
+ writeFile programfile program
+
+#ifdef darwin_HOST_OS
+ autostartfile <- userAutoStart osxAutoStartLabel
+#else
+ menufile <- desktopMenuFilePath "git-annex" <$> userDataDir
+ icondir <- iconDir <$> userDataDir
+ installMenu program menufile base icondir
+ autostartfile <- autoStartPath "git-annex" <$> userConfigDir
+#endif
+ installAutoStart program autostartfile
+
+ {- This shim is only updated if it doesn't
+ - already exist with the right content. -}
+ sshdir <- sshDir
+ let shim = sshdir </> "git-annex-shell"
+ let runshell var = "exec " ++ base </> "runshell" ++
+ " git-annex-shell -c \"" ++ var ++ "\""
+ let content = unlines
+ [ shebang_local
+ , "set -e"
+ , "if [ \"x$SSH_ORIGINAL_COMMAND\" != \"x\" ]; then"
+ , runshell "$SSH_ORIGINAL_COMMAND"
+ , "else"
+ , runshell "$@"
+ , "fi"
+ ]
+
+ curr <- catchDefaultIO "" $ readFileStrict shim
+ when (curr /= content) $ do
+ createDirectoryIfMissing True (parentDir shim)
+ viaTmp writeFile shim content
+ modifyFileMode shim $ addModes [ownerExecuteMode]
+
+{- Returns a cleaned up environment that lacks settings used to make the
+ - standalone builds use their bundled libraries and programs.
+ - Useful when calling programs not included in the standalone builds.
+ -
+ - For a non-standalone build, returns Nothing.
+ -}
+cleanEnvironment :: IO (Maybe [(String, String)])
+cleanEnvironment = clean <$> getEnvironment
+ where
+ clean env
+ | null vars = Nothing
+ | otherwise = Just $ catMaybes $ map (restoreorig env) env
+ | otherwise = Nothing
+ where
+ vars = words $ fromMaybe "" $
+ lookup "GIT_ANNEX_STANDLONE_ENV" env
+ restoreorig oldenv p@(k, _v)
+ | k `elem` vars = case lookup ("ORIG_" ++ k) oldenv of
+ Nothing -> Nothing
+ (Just v') -> Just (k, v')
+ | otherwise = Just p
diff --git a/Assistant/Install/AutoStart.hs b/Assistant/Install/AutoStart.hs
new file mode 100644
index 000000000..b03d20224
--- /dev/null
+++ b/Assistant/Install/AutoStart.hs
@@ -0,0 +1,39 @@
+{- Assistant autostart file installation
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Assistant.Install.AutoStart where
+
+import Utility.FreeDesktop
+#ifdef darwin_HOST_OS
+import Utility.OSX
+import Utility.Path
+import System.Directory
+#endif
+
+installAutoStart :: FilePath -> FilePath -> IO ()
+installAutoStart command file = do
+#ifdef darwin_HOST_OS
+ createDirectoryIfMissing True (parentDir file)
+ writeFile file $ genOSXAutoStartFile osxAutoStartLabel command
+ ["assistant", "--autostart"]
+#else
+ writeDesktopMenuFile (fdoAutostart command) file
+#endif
+
+osxAutoStartLabel :: String
+osxAutoStartLabel = "com.branchable.git-annex.assistant"
+
+fdoAutostart :: FilePath -> DesktopEntry
+fdoAutostart command = genDesktopEntry
+ "Git Annex Assistant"
+ "Autostart"
+ False
+ (command ++ " assistant --autostart")
+ Nothing
+ []
diff --git a/Assistant/Install/Menu.hs b/Assistant/Install/Menu.hs
new file mode 100644
index 000000000..41ec855b6
--- /dev/null
+++ b/Assistant/Install/Menu.hs
@@ -0,0 +1,47 @@
+{- Assistant menu installation.
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Assistant.Install.Menu where
+
+import Common
+
+import Utility.FreeDesktop
+
+installMenu :: FilePath -> FilePath -> FilePath -> FilePath -> IO ()
+installMenu command menufile iconsrcdir icondir = do
+#ifdef darwin_HOST_OS
+ return ()
+#else
+ writeDesktopMenuFile (fdoDesktopMenu command) menufile
+ installIcon (iconsrcdir </> "logo.svg") $
+ iconFilePath (iconBaseName ++ ".svg") "scalable" icondir
+ installIcon (iconsrcdir </> "favicon.png") $
+ iconFilePath (iconBaseName ++ ".png") "16x16" icondir
+#endif
+
+{- The command can be either just "git-annex", or the full path to use
+ - to run it. -}
+fdoDesktopMenu :: FilePath -> DesktopEntry
+fdoDesktopMenu command = genDesktopEntry
+ "Git Annex"
+ "Track and sync the files in your Git Annex"
+ False
+ (command ++ " webapp")
+ (Just iconBaseName)
+ ["Network", "FileTransfer"]
+
+installIcon :: FilePath -> FilePath -> IO ()
+installIcon src dest = do
+ createDirectoryIfMissing True (parentDir dest)
+ withBinaryFile src ReadMode $ \hin ->
+ withBinaryFile dest WriteMode $ \hout ->
+ hGetContents hin >>= hPutStr hout
+
+iconBaseName :: String
+iconBaseName = "git-annex"
diff --git a/Assistant/MakeRemote.hs b/Assistant/MakeRemote.hs
new file mode 100644
index 000000000..bf316e49d
--- /dev/null
+++ b/Assistant/MakeRemote.hs
@@ -0,0 +1,165 @@
+{- git-annex assistant remote creation utilities
+ -
+ - Copyright 2012, 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.MakeRemote where
+
+import Assistant.Common
+import Assistant.Ssh
+import qualified Types.Remote as R
+import qualified Remote
+import Remote.List
+import qualified Remote.Rsync as Rsync
+import qualified Remote.GCrypt as GCrypt
+import qualified Git
+import qualified Git.Command
+import qualified Command.InitRemote
+import Logs.UUID
+import Logs.Remote
+import Git.Remote
+import Git.Types (RemoteName)
+import Creds
+import Assistant.Gpg
+import Utility.Gpg (KeyId)
+
+import qualified Data.Map as M
+
+{- Sets up a new git or rsync remote, accessed over ssh. -}
+makeSshRemote :: SshData -> Annex RemoteName
+makeSshRemote sshdata = maker (sshRepoName sshdata) (genSshUrl sshdata)
+ where
+ maker
+ | onlyCapability sshdata RsyncCapable = makeRsyncRemote
+ | otherwise = makeGitRemote
+
+{- Runs an action that returns a name of the remote, and finishes adding it. -}
+addRemote :: Annex RemoteName -> Annex Remote
+addRemote a = do
+ name <- a
+ void remoteListRefresh
+ maybe (error "failed to add remote") return
+ =<< Remote.byName (Just name)
+
+{- Inits a rsync special remote, and returns its name. -}
+makeRsyncRemote :: RemoteName -> String -> Annex String
+makeRsyncRemote name location = makeRemote name location $ const $ void $
+ go =<< Command.InitRemote.findExisting name
+ where
+ go Nothing = setupSpecialRemote name Rsync.remote config
+ (Nothing, Command.InitRemote.newConfig name)
+ go (Just (u, c)) = setupSpecialRemote name Rsync.remote config (Just u, c)
+ config = M.fromList
+ [ ("encryption", "shared")
+ , ("rsyncurl", location)
+ , ("type", "rsync")
+ ]
+
+{- Inits a gcrypt special remote, and returns its name. -}
+makeGCryptRemote :: RemoteName -> String -> KeyId -> Annex RemoteName
+makeGCryptRemote remotename location keyid =
+ initSpecialRemote remotename GCrypt.remote $ M.fromList
+ [ ("type", "gcrypt")
+ , ("gitrepo", location)
+ , configureEncryption HybridEncryption
+ , ("keyid", keyid)
+ ]
+
+type SpecialRemoteMaker = RemoteName -> RemoteType -> R.RemoteConfig -> Annex RemoteName
+
+{- Inits a new special remote. The name is used as a suggestion, but
+ - will be changed if there is already a special remote with that name. -}
+initSpecialRemote :: SpecialRemoteMaker
+initSpecialRemote name remotetype config = go 0
+ where
+ go :: Int -> Annex RemoteName
+ go n = do
+ let fullname = if n == 0 then name else name ++ show n
+ r <- Command.InitRemote.findExisting fullname
+ case r of
+ Nothing -> setupSpecialRemote fullname remotetype config
+ (Nothing, Command.InitRemote.newConfig fullname)
+ Just _ -> go (n + 1)
+
+{- Enables an existing special remote. -}
+enableSpecialRemote :: SpecialRemoteMaker
+enableSpecialRemote name remotetype config = do
+ r <- Command.InitRemote.findExisting name
+ case r of
+ Nothing -> error $ "Cannot find a special remote named " ++ name
+ Just (u, c) -> setupSpecialRemote name remotetype config (Just u, c)
+
+setupSpecialRemote :: RemoteName -> RemoteType -> R.RemoteConfig -> (Maybe UUID, R.RemoteConfig) -> Annex RemoteName
+setupSpecialRemote name remotetype config (mu, c) = do
+ {- Currently, only 'weak' ciphers can be generated from the
+ - assistant, because otherwise GnuPG may block once the entropy
+ - pool is drained, and as of now there's no way to tell the user
+ - to perform IO actions to refill the pool. -}
+ (c', u) <- R.setup remotetype mu $
+ M.insert "highRandomQuality" "false" $ M.union config c
+ describeUUID u name
+ configSet u c'
+ return name
+
+{- Returns the name of the git remote it created. If there's already a
+ - remote at the location, returns its name. -}
+makeGitRemote :: String -> String -> Annex RemoteName
+makeGitRemote basename location = makeRemote basename location $ \name ->
+ void $ inRepo $ Git.Command.runBool
+ [Param "remote", Param "add", Param name, Param location]
+
+{- If there's not already a remote at the location, adds it using the
+ - action, which is passed the name of the remote to make.
+ -
+ - Returns the name of the remote. -}
+makeRemote :: String -> String -> (RemoteName -> Annex ()) -> Annex RemoteName
+makeRemote basename location a = do
+ g <- gitRepo
+ if not (any samelocation $ Git.remotes g)
+ then do
+ let name = uniqueRemoteName basename 0 g
+ a name
+ return name
+ else return basename
+ where
+ samelocation x = Git.repoLocation x == location
+
+{- Generate an unused name for a remote, adding a number if
+ - necessary.
+ -
+ - Ensures that the returned name is a legal git remote name. -}
+uniqueRemoteName :: String -> Int -> Git.Repo -> RemoteName
+uniqueRemoteName basename n r
+ | null namecollision = name
+ | otherwise = uniqueRemoteName legalbasename (succ n) r
+ where
+ namecollision = filter samename (Git.remotes r)
+ samename x = Git.remoteName x == Just name
+ name
+ | n == 0 = legalbasename
+ | otherwise = legalbasename ++ show n
+ legalbasename = makeLegalName basename
+
+{- Finds a CredPair belonging to any Remote that is of a given type
+ - and matches some other criteria.
+ -
+ - This can be used as a default when another repository is being set up
+ - using the same service.
+ -
+ - A function must be provided that returns the CredPairStorage
+ - to use for a particular Remote's uuid.
+ -}
+previouslyUsedCredPair
+ :: (UUID -> CredPairStorage)
+ -> RemoteType
+ -> (Remote -> Bool)
+ -> Annex (Maybe CredPair)
+previouslyUsedCredPair getstorage remotetype criteria =
+ getM fromstorage =<< filter criteria . filter sametype <$> remoteList
+ where
+ sametype r = R.typename (R.remotetype r) == R.typename remotetype
+ fromstorage r = do
+ let storage = getstorage (R.uuid r)
+ getRemoteCredPair (R.config r) storage
diff --git a/Assistant/Monad.hs b/Assistant/Monad.hs
new file mode 100644
index 000000000..6b843ea88
--- /dev/null
+++ b/Assistant/Monad.hs
@@ -0,0 +1,144 @@
+{- git-annex assistant monad
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE GeneralizedNewtypeDeriving, MultiParamTypeClasses #-}
+
+module Assistant.Monad (
+ Assistant,
+ AssistantData(..),
+ newAssistantData,
+ runAssistant,
+ getAssistant,
+ LiftAnnex,
+ liftAnnex,
+ (<~>),
+ (<<~),
+ asIO,
+ asIO1,
+ asIO2,
+ ThreadName,
+ debug,
+ notice
+) where
+
+import "mtl" Control.Monad.Reader
+import System.Log.Logger
+
+import Common.Annex
+import Assistant.Types.ThreadedMonad
+import Assistant.Types.DaemonStatus
+import Assistant.Types.ScanRemotes
+import Assistant.Types.TransferQueue
+import Assistant.Types.TransferSlots
+import Assistant.Types.TransferrerPool
+import Assistant.Types.Pushes
+import Assistant.Types.BranchChange
+import Assistant.Types.Commits
+import Assistant.Types.Changes
+import Assistant.Types.RepoProblem
+import Assistant.Types.Buddies
+import Assistant.Types.NetMessager
+import Assistant.Types.ThreadName
+
+newtype Assistant a = Assistant { mkAssistant :: ReaderT AssistantData IO a }
+ deriving (
+ Monad,
+ MonadIO,
+ MonadReader AssistantData,
+ Functor,
+ Applicative
+ )
+
+data AssistantData = AssistantData
+ { threadName :: ThreadName
+ , threadState :: ThreadState
+ , daemonStatusHandle :: DaemonStatusHandle
+ , scanRemoteMap :: ScanRemoteMap
+ , transferQueue :: TransferQueue
+ , transferSlots :: TransferSlots
+ , transferrerPool :: TransferrerPool
+ , failedPushMap :: FailedPushMap
+ , commitChan :: CommitChan
+ , changePool :: ChangePool
+ , repoProblemChan :: RepoProblemChan
+ , branchChangeHandle :: BranchChangeHandle
+ , buddyList :: BuddyList
+ , netMessager :: NetMessager
+ }
+
+newAssistantData :: ThreadState -> DaemonStatusHandle -> IO AssistantData
+newAssistantData st dstatus = AssistantData
+ <$> pure (ThreadName "main")
+ <*> pure st
+ <*> pure dstatus
+ <*> newScanRemoteMap
+ <*> newTransferQueue
+ <*> newTransferSlots
+ <*> newTransferrerPool
+ <*> newFailedPushMap
+ <*> newCommitChan
+ <*> newChangePool
+ <*> newRepoProblemChan
+ <*> newBranchChangeHandle
+ <*> newBuddyList
+ <*> newNetMessager
+
+runAssistant :: AssistantData -> Assistant a -> IO a
+runAssistant d a = runReaderT (mkAssistant a) d
+
+getAssistant :: (AssistantData -> a) -> Assistant a
+getAssistant = reader
+
+{- Using a type class for lifting into the annex monad allows
+ - easily lifting to it from multiple different monads. -}
+class LiftAnnex m where
+ liftAnnex :: Annex a -> m a
+
+{- Runs an action in the git-annex monad. Note that the same monad state
+ - is shared amoung all assistant threads, so only one of these can run at
+ - a time. Therefore, long-duration actions should be avoided. -}
+instance LiftAnnex Assistant where
+ liftAnnex a = do
+ st <- reader threadState
+ liftIO $ runThreadState st a
+
+{- Runs an IO action, passing it an IO action that runs an Assistant action. -}
+(<~>) :: (IO a -> IO b) -> Assistant a -> Assistant b
+io <~> a = do
+ d <- reader id
+ liftIO $ io $ runAssistant d a
+
+{- Creates an IO action that will run an Assistant action when run. -}
+asIO :: Assistant a -> Assistant (IO a)
+asIO a = do
+ d <- reader id
+ return $ runAssistant d a
+
+asIO1 :: (a -> Assistant b) -> Assistant (a -> IO b)
+asIO1 a = do
+ d <- reader id
+ return $ \v -> runAssistant d $ a v
+
+asIO2 :: (a -> b -> Assistant c) -> Assistant (a -> b -> IO c)
+asIO2 a = do
+ d <- reader id
+ return $ \v1 v2 -> runAssistant d (a v1 v2)
+
+{- Runs an IO action on a selected field of the AssistantData. -}
+(<<~) :: (a -> IO b) -> (AssistantData -> a) -> Assistant b
+io <<~ v = reader v >>= liftIO . io
+
+debug :: [String] -> Assistant ()
+debug = logaction debugM
+
+notice :: [String] -> Assistant ()
+notice = logaction noticeM
+
+logaction :: (String -> String -> IO ()) -> [String] -> Assistant ()
+logaction a ws = do
+ ThreadName name <- getAssistant threadName
+ liftIO $ a name $ unwords $ (name ++ ":") : ws
diff --git a/Assistant/NamedThread.hs b/Assistant/NamedThread.hs
new file mode 100644
index 000000000..e1b3983f7
--- /dev/null
+++ b/Assistant/NamedThread.hs
@@ -0,0 +1,102 @@
+{- git-annex assistant named threads.
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Assistant.NamedThread where
+
+import Common.Annex
+import Assistant.Types.NamedThread
+import Assistant.Types.ThreadName
+import Assistant.Types.DaemonStatus
+import Assistant.Types.UrlRenderer
+import Assistant.DaemonStatus
+import Assistant.Monad
+import Utility.NotificationBroadcaster
+
+import Control.Concurrent
+import Control.Concurrent.Async
+import qualified Data.Map as M
+import qualified Control.Exception as E
+
+#ifdef WITH_WEBAPP
+import Assistant.WebApp.Types
+import Assistant.Types.Alert
+import Assistant.Alert
+import qualified Data.Text as T
+#endif
+
+{- Starts a named thread, if it's not already running.
+ -
+ - Named threads are run by a management thread, so if they crash
+ - an alert is displayed, allowing the thread to be restarted. -}
+startNamedThread :: UrlRenderer -> NamedThread -> Assistant ()
+startNamedThread urlrenderer (NamedThread afterstartupsanitycheck name a) = do
+ m <- startedThreads <$> getDaemonStatus
+ case M.lookup name m of
+ Nothing -> start
+ Just (aid, _) -> do
+ r <- liftIO (E.try (poll aid) :: IO (Either E.SomeException (Maybe (Either E.SomeException ()))))
+ case r of
+ Right Nothing -> noop
+ _ -> start
+ where
+ start
+ | afterstartupsanitycheck = do
+ status <- getDaemonStatus
+ h <- liftIO $ newNotificationHandle False $
+ startupSanityCheckNotifier status
+ startwith $ runmanaged $
+ liftIO $ waitNotification h
+ | otherwise = startwith $ runmanaged noop
+ startwith runner = do
+ d <- getAssistant id
+ aid <- liftIO $ runner $ d { threadName = name }
+ restart <- asIO $ startNamedThread urlrenderer (NamedThread False name a)
+ modifyDaemonStatus_ $ \s -> s
+ { startedThreads = M.insertWith' const name (aid, restart) (startedThreads s) }
+ runmanaged first d = do
+ aid <- async $ runAssistant d $ do
+ void first
+ a
+ void $ forkIO $ manager d aid
+ return aid
+ manager d aid = do
+ r <- E.try (wait aid) :: IO (Either E.SomeException ())
+ case r of
+ Right _ -> noop
+ Left e -> do
+ let msg = unwords
+ [ fromThreadName $ threadName d
+ , "crashed:", show e
+ ]
+ hPutStrLn stderr msg
+#ifdef WITH_WEBAPP
+ button <- runAssistant d $ mkAlertButton True
+ (T.pack "Restart Thread")
+ urlrenderer
+ (RestartThreadR name)
+ runAssistant d $ void $ addAlert $
+ (warningAlert (fromThreadName name) msg)
+ { alertButtons = [button] }
+#endif
+
+namedThreadId :: NamedThread -> Assistant (Maybe ThreadId)
+namedThreadId (NamedThread _ name _) = do
+ m <- startedThreads <$> getDaemonStatus
+ return $ asyncThreadId . fst <$> M.lookup name m
+
+{- Waits for all named threads that have been started to finish.
+ -
+ - Note that if a named thread crashes, it will probably
+ - cause this to crash as well. Also, named threads that are started
+ - after this is called will not be waited on. -}
+waitNamedThreads :: Assistant ()
+waitNamedThreads = do
+ m <- startedThreads <$> getDaemonStatus
+ liftIO $ mapM_ (wait . fst) $ M.elems m
+
diff --git a/Assistant/NetMessager.hs b/Assistant/NetMessager.hs
new file mode 100644
index 000000000..acb18b648
--- /dev/null
+++ b/Assistant/NetMessager.hs
@@ -0,0 +1,180 @@
+{- git-annex assistant out of band network messager interface
+ -
+ - Copyright 2012-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE BangPatterns #-}
+
+module Assistant.NetMessager where
+
+import Assistant.Common
+import Assistant.Types.NetMessager
+
+import Control.Concurrent.STM
+import Control.Concurrent.MSampleVar
+import qualified Data.Set as S
+import qualified Data.Map as M
+import qualified Data.DList as D
+
+sendNetMessage :: NetMessage -> Assistant ()
+sendNetMessage m =
+ (atomically . flip writeTChan m) <<~ (netMessages . netMessager)
+
+waitNetMessage :: Assistant (NetMessage)
+waitNetMessage = (atomically . readTChan) <<~ (netMessages . netMessager)
+
+notifyNetMessagerRestart :: Assistant ()
+notifyNetMessagerRestart =
+ flip writeSV () <<~ (netMessagerRestart . netMessager)
+
+{- This can be used to get an early indication if the network has
+ - changed, to immediately restart a connection. However, that is not
+ - available on all systems, so clients also need to deal with
+ - restarting dropped connections in the usual way. -}
+waitNetMessagerRestart :: Assistant ()
+waitNetMessagerRestart = readSV <<~ (netMessagerRestart . netMessager)
+
+{- Store a new important NetMessage for a client, and if an equivilant
+ - older message is already stored, remove it from both importantNetMessages
+ - and sentImportantNetMessages. -}
+storeImportantNetMessage :: NetMessage -> ClientID -> (ClientID -> Bool) -> Assistant ()
+storeImportantNetMessage m client matchingclient = go <<~ netMessager
+ where
+ go nm = atomically $ do
+ q <- takeTMVar $ importantNetMessages nm
+ sent <- takeTMVar $ sentImportantNetMessages nm
+ putTMVar (importantNetMessages nm) $
+ M.alter (Just . maybe (S.singleton m) (S.insert m)) client $
+ M.mapWithKey removematching q
+ putTMVar (sentImportantNetMessages nm) $
+ M.mapWithKey removematching sent
+ removematching someclient s
+ | matchingclient someclient = S.filter (not . equivilantImportantNetMessages m) s
+ | otherwise = s
+
+{- Indicates that an important NetMessage has been sent to a client. -}
+sentImportantNetMessage :: NetMessage -> ClientID -> Assistant ()
+sentImportantNetMessage m client = go <<~ (sentImportantNetMessages . netMessager)
+ where
+ go v = atomically $ do
+ sent <- takeTMVar v
+ putTMVar v $
+ M.alter (Just . maybe (S.singleton m) (S.insert m)) client sent
+
+{- Checks for important NetMessages that have been stored for a client, and
+ - sent to a client. Typically the same client for both, although
+ - a modified or more specific client may need to be used. -}
+checkImportantNetMessages :: (ClientID, ClientID) -> Assistant (S.Set NetMessage, S.Set NetMessage)
+checkImportantNetMessages (storedclient, sentclient) = go <<~ netMessager
+ where
+ go nm = atomically $ do
+ stored <- M.lookup storedclient <$> (readTMVar $ importantNetMessages nm)
+ sent <- M.lookup sentclient <$> (readTMVar $ sentImportantNetMessages nm)
+ return (fromMaybe S.empty stored, fromMaybe S.empty sent)
+
+{- Queues a push initiation message in the queue for the appropriate
+ - side of the push but only if there is not already an initiation message
+ - from the same client in the queue. -}
+queuePushInitiation :: NetMessage -> Assistant ()
+queuePushInitiation msg@(Pushing clientid stage) = do
+ tv <- getPushInitiationQueue side
+ liftIO $ atomically $ do
+ r <- tryTakeTMVar tv
+ case r of
+ Nothing -> putTMVar tv [msg]
+ Just l -> do
+ let !l' = msg : filter differentclient l
+ putTMVar tv l'
+ where
+ side = pushDestinationSide stage
+ differentclient (Pushing cid _) = cid /= clientid
+ differentclient _ = True
+queuePushInitiation _ = noop
+
+{- Waits for a push inititation message to be received, and runs
+ - function to select a message from the queue. -}
+waitPushInitiation :: PushSide -> ([NetMessage] -> (NetMessage, [NetMessage])) -> Assistant NetMessage
+waitPushInitiation side selector = do
+ tv <- getPushInitiationQueue side
+ liftIO $ atomically $ do
+ q <- takeTMVar tv
+ if null q
+ then retry
+ else do
+ let (msg, !q') = selector q
+ unless (null q') $
+ putTMVar tv q'
+ return msg
+
+{- Stores messages for a push into the appropriate inbox.
+ -
+ - To avoid overflow, only 1000 messages max are stored in any
+ - inbox, which should be far more than necessary.
+ -
+ - TODO: If we have more than 100 inboxes for different clients,
+ - discard old ones that are not currently being used by any push.
+ -}
+storeInbox :: NetMessage -> Assistant ()
+storeInbox msg@(Pushing clientid stage) = do
+ inboxes <- getInboxes side
+ stored <- liftIO $ atomically $ do
+ m <- readTVar inboxes
+ let update = \v -> do
+ writeTVar inboxes $
+ M.insertWith' const clientid v m
+ return True
+ case M.lookup clientid m of
+ Nothing -> update (1, tostore)
+ Just (sz, l)
+ | sz > 1000 -> return False
+ | otherwise ->
+ let !sz' = sz + 1
+ !l' = D.append l tostore
+ in update (sz', l')
+ if stored
+ then netMessagerDebug clientid ["stored", logNetMessage msg, "in", show side, "inbox"]
+ else netMessagerDebug clientid ["discarded", logNetMessage msg, "; ", show side, "inbox is full"]
+ where
+ side = pushDestinationSide stage
+ tostore = D.singleton msg
+storeInbox _ = noop
+
+{- Gets the new message for a push from its inbox.
+ - Blocks until a message has been received. -}
+waitInbox :: ClientID -> PushSide -> Assistant (NetMessage)
+waitInbox clientid side = do
+ inboxes <- getInboxes side
+ liftIO $ atomically $ do
+ m <- readTVar inboxes
+ case M.lookup clientid m of
+ Nothing -> retry
+ Just (sz, dl)
+ | sz < 1 -> retry
+ | otherwise -> do
+ let msg = D.head dl
+ let dl' = D.tail dl
+ let !sz' = sz - 1
+ writeTVar inboxes $
+ M.insertWith' const clientid (sz', dl') m
+ return msg
+
+emptyInbox :: ClientID -> PushSide -> Assistant ()
+emptyInbox clientid side = do
+ inboxes <- getInboxes side
+ liftIO $ atomically $
+ modifyTVar' inboxes $
+ M.delete clientid
+
+getInboxes :: PushSide -> Assistant Inboxes
+getInboxes side =
+ getSide side . netMessagerInboxes <$> getAssistant netMessager
+
+getPushInitiationQueue :: PushSide -> Assistant (TMVar [NetMessage])
+getPushInitiationQueue side =
+ getSide side . netMessagerPushInitiations <$> getAssistant netMessager
+
+netMessagerDebug :: ClientID -> [String] -> Assistant ()
+netMessagerDebug clientid l = debug $
+ "NetMessager" : l ++ [show $ logClientID clientid]
diff --git a/Assistant/Pairing.hs b/Assistant/Pairing.hs
new file mode 100644
index 000000000..bb1384a15
--- /dev/null
+++ b/Assistant/Pairing.hs
@@ -0,0 +1,92 @@
+{- git-annex assistant repo pairing, core data types
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Assistant.Pairing where
+
+import Common.Annex
+import Utility.Verifiable
+import Assistant.Ssh
+
+import Control.Concurrent
+import Network.Socket
+import Data.Char
+import qualified Data.Text as T
+
+data PairStage
+ {- "I'll pair with anybody who shares the secret that can be used
+ - to verify this request." -}
+ = PairReq
+ {- "I've verified your request, and you can verify this to see
+ - that I know the secret. I set up your ssh key already.
+ - Here's mine for you to set up." -}
+ | PairAck
+ {- "I saw your PairAck; you can stop sending them." -}
+ | PairDone
+ deriving (Eq, Read, Show, Ord, Enum)
+
+newtype PairMsg = PairMsg (Verifiable (PairStage, PairData, SomeAddr))
+ deriving (Eq, Read, Show)
+
+verifiedPairMsg :: PairMsg -> PairingInProgress -> Bool
+verifiedPairMsg (PairMsg m) pip = verify m $ inProgressSecret pip
+
+fromPairMsg :: PairMsg -> Verifiable (PairStage, PairData, SomeAddr)
+fromPairMsg (PairMsg m) = m
+
+pairMsgStage :: PairMsg -> PairStage
+pairMsgStage (PairMsg (Verifiable (s, _, _) _)) = s
+
+pairMsgData :: PairMsg -> PairData
+pairMsgData (PairMsg (Verifiable (_, d, _) _)) = d
+
+pairMsgAddr :: PairMsg -> SomeAddr
+pairMsgAddr (PairMsg (Verifiable (_, _, a) _)) = a
+
+data PairData = PairData
+ -- uname -n output, not a full domain name
+ { remoteHostName :: Maybe HostName
+ , remoteUserName :: UserName
+ , remoteDirectory :: FilePath
+ , remoteSshPubKey :: SshPubKey
+ , pairUUID :: UUID
+ }
+ deriving (Eq, Read, Show)
+
+type UserName = String
+
+{- A pairing that is in progress has a secret, a thread that is
+ - broadcasting pairing messages, and a SshKeyPair that has not yet been
+ - set up on disk. -}
+data PairingInProgress = PairingInProgress
+ { inProgressSecret :: Secret
+ , inProgressThreadId :: Maybe ThreadId
+ , inProgressSshKeyPair :: SshKeyPair
+ , inProgressPairData :: PairData
+ , inProgressPairStage :: PairStage
+ }
+ deriving (Show)
+
+data SomeAddr = IPv4Addr HostAddress
+{- My Android build of the Network library does not currently have IPV6
+ - support. -}
+#ifndef __ANDROID__
+ | IPv6Addr HostAddress6
+#endif
+ deriving (Ord, Eq, Read, Show)
+
+{- This contains the whole secret, just lightly obfuscated to make it not
+ - too obvious. It's only displayed in the user's web browser. -}
+newtype SecretReminder = SecretReminder [Int]
+ deriving (Show, Eq, Ord, Read)
+
+toSecretReminder :: T.Text -> SecretReminder
+toSecretReminder = SecretReminder . map ord . T.unpack
+
+fromSecretReminder :: SecretReminder -> T.Text
+fromSecretReminder (SecretReminder s) = T.pack $ map chr s
diff --git a/Assistant/Pairing/MakeRemote.hs b/Assistant/Pairing/MakeRemote.hs
new file mode 100644
index 000000000..144b236a4
--- /dev/null
+++ b/Assistant/Pairing/MakeRemote.hs
@@ -0,0 +1,95 @@
+{- git-annex assistant pairing remote creation
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.Pairing.MakeRemote where
+
+import Assistant.Common
+import Assistant.Ssh
+import Assistant.Pairing
+import Assistant.Pairing.Network
+import Assistant.MakeRemote
+import Assistant.Sync
+import Config.Cost
+import Config
+
+import Network.Socket
+import qualified Data.Text as T
+
+{- Authorized keys are set up before pairing is complete, so that the other
+ - side can immediately begin syncing. -}
+setupAuthorizedKeys :: PairMsg -> FilePath -> IO ()
+setupAuthorizedKeys msg repodir = do
+ validateSshPubKey pubkey
+ unlessM (liftIO $ addAuthorizedKeys True repodir pubkey) $
+ error "failed setting up ssh authorized keys"
+ where
+ pubkey = remoteSshPubKey $ pairMsgData msg
+
+{- When local pairing is complete, this is used to set up the remote for
+ - the host we paired with. -}
+finishedLocalPairing :: PairMsg -> SshKeyPair -> Assistant ()
+finishedLocalPairing msg keypair = do
+ sshdata <- liftIO $ setupSshKeyPair keypair =<< pairMsgToSshData msg
+ {- Ensure that we know the ssh host key for the host we paired with.
+ - If we don't, ssh over to get it. -}
+ liftIO $ unlessM (knownHost $ sshHostName sshdata) $
+ void $ sshTranscript
+ [ sshOpt "StrictHostKeyChecking" "no"
+ , sshOpt "NumberOfPasswordPrompts" "0"
+ , "-n"
+ , genSshHost (sshHostName sshdata) (sshUserName sshdata)
+ , "git-annex-shell -c configlist " ++ T.unpack (sshDirectory sshdata)
+ ]
+ Nothing
+ r <- liftAnnex $ addRemote $ makeSshRemote sshdata
+ liftAnnex $ setRemoteCost r semiExpensiveRemoteCost
+ syncRemote r
+
+{- Mostly a straightforward conversion. Except:
+ - * Determine the best hostname to use to contact the host.
+ - * Strip leading ~/ from the directory name.
+ -}
+pairMsgToSshData :: PairMsg -> IO SshData
+pairMsgToSshData msg = do
+ let d = pairMsgData msg
+ hostname <- liftIO $ bestHostName msg
+ let dir = case remoteDirectory d of
+ ('~':'/':v) -> v
+ v -> v
+ return SshData
+ { sshHostName = T.pack hostname
+ , sshUserName = Just (T.pack $ remoteUserName d)
+ , sshDirectory = T.pack dir
+ , sshRepoName = genSshRepoName hostname dir
+ , sshPort = 22
+ , needsPubKey = True
+ , sshCapabilities = [GitAnnexShellCapable, GitCapable, RsyncCapable]
+ }
+
+{- Finds the best hostname to use for the host that sent the PairMsg.
+ -
+ - If remoteHostName is set, tries to use a .local address based on it.
+ - That's the most robust, if this system supports .local.
+ - Otherwise, looks up the hostname in the DNS for the remoteAddress,
+ - if any. May fall back to remoteAddress if there's no DNS. Ugh. -}
+bestHostName :: PairMsg -> IO HostName
+bestHostName msg = case remoteHostName $ pairMsgData msg of
+ Just h -> do
+ let localname = h ++ ".local"
+ addrs <- catchDefaultIO [] $
+ getAddrInfo Nothing (Just localname) Nothing
+ maybe fallback (const $ return localname) (headMaybe addrs)
+ Nothing -> fallback
+ where
+ fallback = do
+ let a = pairMsgAddr msg
+ let sockaddr = case a of
+ IPv4Addr addr -> SockAddrInet (PortNum 0) addr
+ IPv6Addr addr -> SockAddrInet6 (PortNum 0) 0 addr 0
+ fromMaybe (showAddr a)
+ <$> catchDefaultIO Nothing
+ (fst <$> getNameInfo [] True False sockaddr)
diff --git a/Assistant/Pairing/Network.hs b/Assistant/Pairing/Network.hs
new file mode 100644
index 000000000..6c625f881
--- /dev/null
+++ b/Assistant/Pairing/Network.hs
@@ -0,0 +1,130 @@
+{- git-annex assistant pairing network code
+ -
+ - All network traffic is sent over multicast UDP. For reliability,
+ - each message is repeated until acknowledged. This is done using a
+ - thread, that gets stopped before the next message is sent.
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.Pairing.Network where
+
+import Assistant.Common
+import Assistant.Pairing
+import Assistant.DaemonStatus
+import Utility.ThreadScheduler
+import Utility.Verifiable
+
+import Network.Multicast
+import Network.Info
+import Network.Socket
+import Control.Exception (bracket)
+import qualified Data.Map as M
+import Control.Concurrent
+
+{- This is an arbitrary port in the dynamic port range, that could
+ - conceivably be used for some other broadcast messages.
+ - If so, hope they ignore the garbage from us; we'll certianly
+ - ignore garbage from them. Wild wild west. -}
+pairingPort :: PortNumber
+pairingPort = 55556
+
+{- Goal: Reach all hosts on the same network segment.
+ - Method: Use same address that avahi uses. Other broadcast addresses seem
+ - to not be let through some routers. -}
+multicastAddress :: SomeAddr -> HostName
+multicastAddress (IPv4Addr _) = "224.0.0.251"
+multicastAddress (IPv6Addr _) = "ff02::fb"
+
+{- Multicasts a message repeatedly on all interfaces, with a 2 second
+ - delay between each transmission. The message is repeated forever
+ - unless a number of repeats is specified.
+ -
+ - The remoteHostAddress is set to the interface's IP address.
+ -
+ - Note that new sockets are opened each time. This is hardly efficient,
+ - but it allows new network interfaces to be used as they come up.
+ - On the other hand, the expensive DNS lookups are cached.
+ -}
+multicastPairMsg :: Maybe Int -> Secret -> PairData -> PairStage -> IO ()
+multicastPairMsg repeats secret pairdata stage = go M.empty repeats
+ where
+ go _ (Just 0) = noop
+ go cache n = do
+ addrs <- activeNetworkAddresses
+ let cache' = updatecache cache addrs
+ mapM_ (sendinterface cache') addrs
+ threadDelaySeconds (Seconds 2)
+ go cache' $ pred <$> n
+ {- The multicast library currently chokes on ipv6 addresses. -}
+ sendinterface _ (IPv6Addr _) = noop
+ sendinterface cache i = void $ tryIO $
+ withSocketsDo $ bracket setup cleanup use
+ where
+ setup = multicastSender (multicastAddress i) pairingPort
+ cleanup (sock, _) = sClose sock -- FIXME does not work
+ use (sock, addr) = do
+ setInterface sock (showAddr i)
+ maybe noop (\s -> void $ sendTo sock s addr)
+ (M.lookup i cache)
+ updatecache cache [] = cache
+ updatecache cache (i:is)
+ | M.member i cache = updatecache cache is
+ | otherwise = updatecache (M.insert i (show $ mkmsg i) cache) is
+ mkmsg addr = PairMsg $
+ mkVerifiable (stage, pairdata, addr) secret
+
+startSending :: PairingInProgress -> PairStage -> (PairStage -> IO ()) -> Assistant ()
+startSending pip stage sender = do
+ a <- asIO start
+ void $ liftIO $ forkIO a
+ where
+ start = do
+ tid <- liftIO myThreadId
+ let pip' = pip { inProgressPairStage = stage, inProgressThreadId = Just tid }
+ oldpip <- modifyDaemonStatus $
+ \s -> (s { pairingInProgress = Just pip' }, pairingInProgress s)
+ maybe noop stopold oldpip
+ liftIO $ sender stage
+ stopold = maybe noop (liftIO . killThread) . inProgressThreadId
+
+stopSending :: PairingInProgress -> Assistant ()
+stopSending pip = do
+ maybe noop (liftIO . killThread) $ inProgressThreadId pip
+ modifyDaemonStatus_ $ \s -> s { pairingInProgress = Nothing }
+
+class ToSomeAddr a where
+ toSomeAddr :: a -> SomeAddr
+
+instance ToSomeAddr IPv4 where
+ toSomeAddr (IPv4 a) = IPv4Addr a
+
+instance ToSomeAddr IPv6 where
+ toSomeAddr (IPv6 o1 o2 o3 o4) = IPv6Addr (o1, o2, o3, o4)
+
+showAddr :: SomeAddr -> HostName
+showAddr (IPv4Addr a) = show $ IPv4 a
+showAddr (IPv6Addr (o1, o2, o3, o4)) = show $ IPv6 o1 o2 o3 o4
+
+activeNetworkAddresses :: IO [SomeAddr]
+activeNetworkAddresses = filter (not . all (`elem` "0.:") . showAddr)
+ . concatMap (\ni -> [toSomeAddr $ ipv4 ni, toSomeAddr $ ipv6 ni])
+ <$> getNetworkInterfaces
+
+{- A human-visible description of the repository being paired with.
+ - Note that the repository's description is not shown to the user, because
+ - it could be something like "my repo", which is confusing when pairing
+ - with someone else's repo. However, this has the same format as the
+ - default decription of a repo. -}
+pairRepo :: PairMsg -> String
+pairRepo msg = concat
+ [ remoteUserName d
+ , "@"
+ , fromMaybe (showAddr $ pairMsgAddr msg) (remoteHostName d)
+ , ":"
+ , remoteDirectory d
+ ]
+ where
+ d = pairMsgData msg
diff --git a/Assistant/Pushes.hs b/Assistant/Pushes.hs
new file mode 100644
index 000000000..54f31a84b
--- /dev/null
+++ b/Assistant/Pushes.hs
@@ -0,0 +1,40 @@
+{- git-annex assistant push tracking
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.Pushes where
+
+import Assistant.Common
+import Assistant.Types.Pushes
+
+import Control.Concurrent.STM
+import Data.Time.Clock
+import qualified Data.Map as M
+
+{- Blocks until there are failed pushes.
+ - Returns Remotes whose pushes failed a given time duration or more ago.
+ - (This may be an empty list.) -}
+getFailedPushesBefore :: NominalDiffTime -> Assistant [Remote]
+getFailedPushesBefore duration = do
+ v <- getAssistant failedPushMap
+ liftIO $ do
+ m <- atomically $ readTMVar v
+ now <- getCurrentTime
+ return $ M.keys $ M.filter (not . toorecent now) m
+ where
+ toorecent now time = now `diffUTCTime` time < duration
+
+{- Modifies the map. -}
+changeFailedPushMap :: (PushMap -> PushMap) -> Assistant ()
+changeFailedPushMap a = do
+ v <- getAssistant failedPushMap
+ liftIO $ atomically $ store v . a . fromMaybe M.empty =<< tryTakeTMVar v
+ where
+ {- tryTakeTMVar empties the TMVar; refill it only if
+ - the modified map is not itself empty -}
+ store v m
+ | m == M.empty = noop
+ | otherwise = putTMVar v $! m
diff --git a/Assistant/RepoProblem.hs b/Assistant/RepoProblem.hs
new file mode 100644
index 000000000..6913fefc6
--- /dev/null
+++ b/Assistant/RepoProblem.hs
@@ -0,0 +1,34 @@
+{- git-annex assistant remote problem handling
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.RepoProblem where
+
+import Assistant.Common
+import Assistant.Types.RepoProblem
+import Utility.TList
+
+import Control.Concurrent.STM
+
+{- Gets all repositories that have problems. Blocks until there is at
+ - least one. -}
+getRepoProblems :: Assistant [RepoProblem]
+getRepoProblems = nubBy sameRepoProblem
+ <$> (atomically . getTList) <<~ repoProblemChan
+
+{- Indicates that there was a problem with a repository, and the problem
+ - appears to not be a transient (eg network connection) problem.
+ -
+ - If the problem is able to be repaired, the passed action will be run.
+ - (However, if multiple problems are reported with a single repository,
+ - only a single action will be run.)
+ -}
+repoHasProblem :: UUID -> Assistant () -> Assistant ()
+repoHasProblem u afterrepair = do
+ rp <- RepoProblem
+ <$> pure u
+ <*> asIO afterrepair
+ (atomically . flip consTList rp) <<~ repoProblemChan
diff --git a/Assistant/ScanRemotes.hs b/Assistant/ScanRemotes.hs
new file mode 100644
index 000000000..2743c0f36
--- /dev/null
+++ b/Assistant/ScanRemotes.hs
@@ -0,0 +1,41 @@
+{- git-annex assistant remotes needing scanning
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.ScanRemotes where
+
+import Assistant.Common
+import Assistant.Types.ScanRemotes
+import qualified Types.Remote as Remote
+
+import Data.Function
+import Control.Concurrent.STM
+import qualified Data.Map as M
+
+{- Blocks until there is a remote or remotes that need to be scanned.
+ -
+ - The list has higher priority remotes listed first. -}
+getScanRemote :: Assistant [(Remote, ScanInfo)]
+getScanRemote = do
+ v <- getAssistant scanRemoteMap
+ liftIO $ atomically $
+ reverse . sortBy (compare `on` scanPriority . snd) . M.toList
+ <$> takeTMVar v
+
+{- Adds new remotes that need scanning. -}
+addScanRemotes :: Bool -> [Remote] -> Assistant ()
+addScanRemotes _ [] = noop
+addScanRemotes full rs = do
+ v <- getAssistant scanRemoteMap
+ liftIO $ atomically $ do
+ m <- fromMaybe M.empty <$> tryTakeTMVar v
+ putTMVar v $ M.unionWith merge (M.fromList $ zip rs (map info rs)) m
+ where
+ info r = ScanInfo (-1 * Remote.cost r) full
+ merge x y = ScanInfo
+ { scanPriority = max (scanPriority x) (scanPriority y)
+ , fullScan = fullScan x || fullScan y
+ }
diff --git a/Assistant/Ssh.hs b/Assistant/Ssh.hs
new file mode 100644
index 000000000..1dc982ba6
--- /dev/null
+++ b/Assistant/Ssh.hs
@@ -0,0 +1,342 @@
+{- git-annex assistant ssh utilities
+ -
+ - Copyright 2012-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.Ssh where
+
+import Common.Annex
+import Utility.Tmp
+import Utility.UserInfo
+import Utility.Shell
+import Utility.Rsync
+import Utility.FileMode
+import Git.Remote
+
+import Data.Text (Text)
+import qualified Data.Text as T
+import Data.Char
+import Network.URI
+
+data SshData = SshData
+ { sshHostName :: Text
+ , sshUserName :: Maybe Text
+ , sshDirectory :: Text
+ , sshRepoName :: String
+ , sshPort :: Int
+ , needsPubKey :: Bool
+ , sshCapabilities :: [SshServerCapability]
+ }
+ deriving (Read, Show, Eq)
+
+data SshServerCapability = GitAnnexShellCapable | GitCapable | RsyncCapable
+ deriving (Read, Show, Eq)
+
+hasCapability :: SshData -> SshServerCapability -> Bool
+hasCapability d c = c `elem` sshCapabilities d
+
+onlyCapability :: SshData -> SshServerCapability -> Bool
+onlyCapability d c = all (== c) (sshCapabilities d)
+
+data SshKeyPair = SshKeyPair
+ { sshPubKey :: String
+ , sshPrivKey :: String
+ }
+
+instance Show SshKeyPair where
+ show = sshPubKey
+
+type SshPubKey = String
+
+{- ssh -ofoo=bar command-line option -}
+sshOpt :: String -> String -> String
+sshOpt k v = concat ["-o", k, "=", v]
+
+sshDir :: IO FilePath
+sshDir = do
+ home <- myHomeDir
+ return $ home </> ".ssh"
+
+{- user@host or host -}
+genSshHost :: Text -> Maybe Text -> String
+genSshHost host user = maybe "" (\v -> T.unpack v ++ "@") user ++ T.unpack host
+
+{- Generates a ssh or rsync url from a SshData. -}
+genSshUrl :: SshData -> String
+genSshUrl sshdata = addtrailingslash $ T.unpack $ T.concat $
+ if (onlyCapability sshdata RsyncCapable)
+ then [u, h, T.pack ":", sshDirectory sshdata]
+ else [T.pack "ssh://", u, h, d]
+ where
+ u = maybe (T.pack "") (\v -> T.concat [v, T.pack "@"]) $ sshUserName sshdata
+ h = sshHostName sshdata
+ d
+ | T.pack "/" `T.isPrefixOf` sshDirectory sshdata = sshDirectory sshdata
+ | T.pack "~/" `T.isPrefixOf` sshDirectory sshdata = T.concat [T.pack "/", sshDirectory sshdata]
+ | otherwise = T.concat [T.pack "/~/", sshDirectory sshdata]
+ addtrailingslash s
+ | "/" `isSuffixOf` s = s
+ | otherwise = s ++ "/"
+
+{- Reverses genSshUrl -}
+parseSshUrl :: String -> Maybe SshData
+parseSshUrl u
+ | "ssh://" `isPrefixOf` u = fromssh (drop (length "ssh://") u)
+ | otherwise = fromrsync u
+ where
+ mkdata (userhost, dir) = Just $ SshData
+ { sshHostName = T.pack host
+ , sshUserName = if null user then Nothing else Just $ T.pack user
+ , sshDirectory = T.pack dir
+ , sshRepoName = genSshRepoName host dir
+ -- dummy values, cannot determine from url
+ , sshPort = 22
+ , needsPubKey = True
+ , sshCapabilities = []
+ }
+ where
+ (user, host) = if '@' `elem` userhost
+ then separate (== '@') userhost
+ else ("", userhost)
+ fromrsync s
+ | not (rsyncUrlIsShell u) = Nothing
+ | otherwise = mkdata $ separate (== ':') s
+ fromssh = mkdata . break (== '/')
+
+{- Generates a git remote name, like host_dir or host -}
+genSshRepoName :: String -> FilePath -> String
+genSshRepoName host dir
+ | null dir = makeLegalName host
+ | otherwise = makeLegalName $ host ++ "_" ++ dir
+
+{- The output of ssh, including both stdout and stderr. -}
+sshTranscript :: [String] -> (Maybe String) -> IO (String, Bool)
+sshTranscript opts input = processTranscript "ssh" opts input
+
+{- Ensure that the ssh public key doesn't include any ssh options, like
+ - command=foo, or other weirdness -}
+validateSshPubKey :: SshPubKey -> IO ()
+validateSshPubKey pubkey
+ | length (lines pubkey) == 1 =
+ either error return $ check $ words pubkey
+ | otherwise = error "too many lines in ssh public key"
+ where
+ check [prefix, _key, comment] = do
+ checkprefix prefix
+ checkcomment comment
+ check [prefix, _key] =
+ checkprefix prefix
+ check _ = err "wrong number of words in ssh public key"
+
+ ok = Right ()
+ err msg = Left $ unwords [msg, pubkey]
+
+ checkprefix prefix
+ | ssh == "ssh" && all isAlphaNum keytype = ok
+ | otherwise = err "bad ssh public key prefix"
+ where
+ (ssh, keytype) = separate (== '-') prefix
+
+ checkcomment comment = case filter (not . safeincomment) comment of
+ [] -> ok
+ badstuff -> err $ "bad comment in ssh public key (contains: \"" ++ badstuff ++ "\")"
+ safeincomment c = isAlphaNum c || c == '@' || c == '-' || c == '_' || c == '.'
+
+addAuthorizedKeys :: Bool -> FilePath -> SshPubKey -> IO Bool
+addAuthorizedKeys gitannexshellonly dir pubkey = boolSystem "sh"
+ [ Param "-c" , Param $ addAuthorizedKeysCommand gitannexshellonly dir pubkey ]
+
+removeAuthorizedKeys :: Bool -> FilePath -> SshPubKey -> IO ()
+removeAuthorizedKeys gitannexshellonly dir pubkey = do
+ let keyline = authorizedKeysLine gitannexshellonly dir pubkey
+ sshdir <- sshDir
+ let keyfile = sshdir </> "authorized_keys"
+ ls <- lines <$> readFileStrict keyfile
+ writeFile keyfile $ unlines $ filter (/= keyline) ls
+
+{- Implemented as a shell command, so it can be run on remote servers over
+ - ssh.
+ -
+ - The ~/.ssh/git-annex-shell wrapper script is created if not already
+ - present.
+ -}
+addAuthorizedKeysCommand :: Bool -> FilePath -> SshPubKey -> String
+addAuthorizedKeysCommand gitannexshellonly dir pubkey = intercalate "&&"
+ [ "mkdir -p ~/.ssh"
+ , intercalate "; "
+ [ "if [ ! -e " ++ wrapper ++ " ]"
+ , "then (" ++ intercalate ";" (map echoval script) ++ ") > " ++ wrapper
+ , "fi"
+ ]
+ , "chmod 700 " ++ wrapper
+ , "touch ~/.ssh/authorized_keys"
+ , "chmod 600 ~/.ssh/authorized_keys"
+ , unwords
+ [ "echo"
+ , shellEscape $ authorizedKeysLine gitannexshellonly dir pubkey
+ , ">>~/.ssh/authorized_keys"
+ ]
+ ]
+ where
+ echoval v = "echo " ++ shellEscape v
+ wrapper = "~/.ssh/git-annex-shell"
+ script =
+ [ shebang_portable
+ , "set -e"
+ , "if [ \"x$SSH_ORIGINAL_COMMAND\" != \"x\" ]; then"
+ , runshell "$SSH_ORIGINAL_COMMAND"
+ , "else"
+ , runshell "$@"
+ , "fi"
+ ]
+ runshell var = "exec git-annex-shell -c \"" ++ var ++ "\""
+
+authorizedKeysLine :: Bool -> FilePath -> SshPubKey -> String
+authorizedKeysLine gitannexshellonly dir pubkey
+ | gitannexshellonly = limitcommand ++ pubkey
+ {- TODO: Locking down rsync is difficult, requiring a rather
+ - long perl script. -}
+ | otherwise = pubkey
+ where
+ limitcommand = "command=\"GIT_ANNEX_SHELL_DIRECTORY="++shellEscape dir++" ~/.ssh/git-annex-shell\",no-agent-forwarding,no-port-forwarding,no-X11-forwarding "
+
+{- Generates a ssh key pair. -}
+genSshKeyPair :: IO SshKeyPair
+genSshKeyPair = withTmpDir "git-annex-keygen" $ \dir -> do
+ ok <- boolSystem "ssh-keygen"
+ [ Param "-P", Param "" -- no password
+ , Param "-f", File $ dir </> "key"
+ ]
+ unless ok $
+ error "ssh-keygen failed"
+ SshKeyPair
+ <$> readFile (dir </> "key.pub")
+ <*> readFile (dir </> "key")
+
+{- Installs a ssh key pair, and sets up ssh config with a mangled hostname
+ - that will enable use of the key. This way we avoid changing the user's
+ - regular ssh experience at all. Returns a modified SshData containing the
+ - mangled hostname.
+ -
+ - Note that the key files are put in ~/.ssh/git-annex/, rather than directly
+ - in ssh because of an **INSANE** behavior of gnome-keyring: It loads
+ - ~/.ssh/ANYTHING.pub, and uses them indiscriminately. But using this key
+ - for a normal login to the server will force git-annex-shell to run,
+ - and locks the user out. Luckily, it does not recurse into subdirectories.
+ -
+ - Similarly, IdentitiesOnly is set in the ssh config to prevent the
+ - ssh-agent from forcing use of a different key.
+ -}
+setupSshKeyPair :: SshKeyPair -> SshData -> IO SshData
+setupSshKeyPair sshkeypair sshdata = do
+ sshdir <- sshDir
+ createDirectoryIfMissing True $ parentDir $ sshdir </> sshprivkeyfile
+
+ unlessM (doesFileExist $ sshdir </> sshprivkeyfile) $
+ writeFileProtected (sshdir </> sshprivkeyfile) (sshPrivKey sshkeypair)
+ unlessM (doesFileExist $ sshdir </> sshpubkeyfile) $
+ writeFile (sshdir </> sshpubkeyfile) (sshPubKey sshkeypair)
+
+ setSshConfig sshdata
+ [ ("IdentityFile", "~/.ssh/" ++ sshprivkeyfile)
+ , ("IdentitiesOnly", "yes")
+ ]
+ where
+ sshprivkeyfile = "git-annex" </> "key." ++ mangleSshHostName sshdata
+ sshpubkeyfile = sshprivkeyfile ++ ".pub"
+
+{- Fixes git-annex ssh key pairs configured in .ssh/config
+ - by old versions to set IdentitiesOnly. -}
+fixSshKeyPair :: IO ()
+fixSshKeyPair = do
+ sshdir <- sshDir
+ let configfile = sshdir </> "config"
+ whenM (doesFileExist configfile) $ do
+ ls <- lines <$> readFileStrict configfile
+ let ls' = fixSshKeyPair' ls
+ when (ls /= ls') $
+ viaTmp writeFile configfile $ unlines ls'
+
+{- Strategy: Search for IdentityFile lines in for files with key.git-annex
+ - in their names. These are for git-annex ssh key pairs.
+ - Add the IdentitiesOnly line immediately after them, if not already
+ - present. -}
+fixSshKeyPair' :: [String] -> [String]
+fixSshKeyPair' = go []
+ where
+ go c [] = reverse c
+ go c (l:[])
+ | all (`isInfixOf` l) indicators = go (fixedline l:l:c) []
+ | otherwise = go (l:c) []
+ go c (l:next:rest)
+ | all (`isInfixOf` l) indicators && not ("IdentitiesOnly" `isInfixOf` next) =
+ go (fixedline l:l:c) (next:rest)
+ | otherwise = go (l:c) (next:rest)
+ indicators = ["IdentityFile", "key.git-annex"]
+ fixedline tmpl = takeWhile isSpace tmpl ++ "IdentitiesOnly yes"
+
+{- Setups up a ssh config with a mangled hostname.
+ - Returns a modified SshData containing the mangled hostname. -}
+setSshConfig :: SshData -> [(String, String)] -> IO SshData
+setSshConfig sshdata config = do
+ sshdir <- sshDir
+ createDirectoryIfMissing True sshdir
+ let configfile = sshdir </> "config"
+ unlessM (catchBoolIO $ isInfixOf mangledhost <$> readFile configfile) $
+ appendFile configfile $ unlines $
+ [ ""
+ , "# Added automatically by git-annex"
+ , "Host " ++ mangledhost
+ ] ++ map (\(k, v) -> "\t" ++ k ++ " " ++ v)
+ (settings ++ config)
+ return $ sshdata { sshHostName = T.pack mangledhost }
+ where
+ mangledhost = mangleSshHostName sshdata
+ settings =
+ [ ("Hostname", T.unpack $ sshHostName sshdata)
+ , ("Port", show $ sshPort sshdata)
+ ]
+
+{- This hostname is specific to a given repository on the ssh host,
+ - so it is based on the real hostname, the username, and the directory.
+ -
+ - The mangled hostname has the form "git-annex-realhostname-username_dir".
+ - The only use of "-" is to separate the parts shown; this is necessary
+ - to allow unMangleSshHostName to work. Any unusual characters in the
+ - username or directory are url encoded, except using "." rather than "%"
+ - (the latter has special meaning to ssh).
+ -}
+mangleSshHostName :: SshData -> String
+mangleSshHostName sshdata = "git-annex-" ++ T.unpack (sshHostName sshdata)
+ ++ "-" ++ escape extra
+ where
+ extra = intercalate "_" $ map T.unpack $ catMaybes
+ [ sshUserName sshdata
+ , Just $ sshDirectory sshdata
+ ]
+ safe c
+ | isAlphaNum c = True
+ | c == '_' = True
+ | otherwise = False
+ escape s = replace "%" "." $ escapeURIString safe s
+
+{- Extracts the real hostname from a mangled ssh hostname. -}
+unMangleSshHostName :: String -> String
+unMangleSshHostName h = case split "-" h of
+ ("git":"annex":rest) -> intercalate "-" (beginning rest)
+ _ -> h
+
+{- Does ssh have known_hosts data for a hostname? -}
+knownHost :: Text -> IO Bool
+knownHost hostname = do
+ sshdir <- sshDir
+ ifM (doesFileExist $ sshdir </> "known_hosts")
+ ( not . null <$> checkhost
+ , return False
+ )
+ where
+ {- ssh-keygen -F can crash on some old known_hosts file -}
+ checkhost = catchDefaultIO "" $
+ readProcess "ssh-keygen" ["-F", T.unpack hostname]
diff --git a/Assistant/Sync.hs b/Assistant/Sync.hs
new file mode 100644
index 000000000..f7656f52d
--- /dev/null
+++ b/Assistant/Sync.hs
@@ -0,0 +1,276 @@
+{- git-annex assistant repo syncing
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.Sync where
+
+import Assistant.Common
+import Assistant.Pushes
+import Assistant.NetMessager
+import Assistant.Types.NetMessager
+import Assistant.Alert
+import Assistant.Alert.Utility
+import Assistant.DaemonStatus
+import Assistant.ScanRemotes
+import qualified Command.Sync
+import Utility.Parallel
+import qualified Git
+import qualified Git.Branch
+import qualified Git.Command
+import qualified Git.Ref
+import qualified Remote
+import qualified Types.Remote as Remote
+import qualified Remote.List as Remote
+import qualified Annex.Branch
+import Annex.UUID
+import Annex.TaggedPush
+import qualified Config
+import Git.Config
+import Assistant.NamedThread
+import Assistant.Threads.Watcher (watchThread, WatcherControl(..))
+import Assistant.TransferSlots
+import Assistant.TransferQueue
+import Assistant.RepoProblem
+import Logs.Transfer
+
+import Data.Time.Clock
+import qualified Data.Map as M
+import qualified Data.Set as S
+import Control.Concurrent
+
+{- Syncs with remotes that may have been disconnected for a while.
+ -
+ - First gets git in sync, and then prepares any necessary file transfers.
+ -
+ - An expensive full scan is queued when the git-annex branches of some of
+ - the remotes have diverged from the local git-annex branch. Otherwise,
+ - it's sufficient to requeue failed transfers.
+ -
+ - XMPP remotes are also signaled that we can push to them, and we request
+ - they push to us. Since XMPP pushes run ansynchronously, any scan of the
+ - XMPP remotes has to be deferred until they're done pushing to us, so
+ - all XMPP remotes are marked as possibly desynced.
+ -
+ - Also handles signaling any connectRemoteNotifiers, after the syncing is
+ - done.
+ -}
+reconnectRemotes :: Bool -> [Remote] -> Assistant ()
+reconnectRemotes _ [] = noop
+reconnectRemotes notifypushes rs = void $ do
+ rs' <- liftIO $ filterM (Remote.checkAvailable True) rs
+ unless (null rs') $ do
+ modifyDaemonStatus_ $ \s -> s
+ { desynced = S.union (S.fromList $ map Remote.uuid xmppremotes) (desynced s) }
+ failedrs <- syncAction rs' (const go)
+ forM_ failedrs $ \r ->
+ whenM (liftIO $ Remote.checkAvailable False r) $
+ repoHasProblem (Remote.uuid r) (syncRemote r)
+ mapM_ signal $ filter (`notElem` failedrs) rs'
+ where
+ gitremotes = filter (notspecialremote . Remote.repo) rs
+ (xmppremotes, nonxmppremotes) = partition isXMPPRemote rs
+ notspecialremote r
+ | Git.repoIsUrl r = True
+ | Git.repoIsLocal r = True
+ | Git.repoIsLocalUnknown r = True
+ | otherwise = False
+ sync (Just branch) = do
+ (failedpull, diverged) <- manualPull (Just branch) gitremotes
+ now <- liftIO getCurrentTime
+ failedpush <- pushToRemotes' now notifypushes gitremotes
+ return (nub $ failedpull ++ failedpush, diverged)
+ {- No local branch exists yet, but we can try pulling. -}
+ sync Nothing = manualPull Nothing gitremotes
+ go = do
+ (failed, diverged) <- sync
+ =<< liftAnnex (inRepo Git.Branch.current)
+ addScanRemotes diverged $
+ filter (not . remoteAnnexIgnore . Remote.gitconfig)
+ nonxmppremotes
+ return failed
+ signal r = liftIO . mapM_ (flip tryPutMVar ())
+ =<< fromMaybe [] . M.lookup (Remote.uuid r) . connectRemoteNotifiers
+ <$> getDaemonStatus
+
+{- Updates the local sync branch, then pushes it to all remotes, in
+ - parallel, along with the git-annex branch. This is the same
+ - as "git annex sync", except in parallel, and will co-exist with use of
+ - "git annex sync".
+ -
+ - After the pushes to normal git remotes, also signals XMPP clients that
+ - they can request an XMPP push.
+ -
+ - Avoids running possibly long-duration commands in the Annex monad, so
+ - as not to block other threads.
+ -
+ - This can fail, when the remote's sync branch (or git-annex branch) has
+ - been updated by some other remote pushing into it, or by the remote
+ - itself. To handle failure, a manual pull and merge is done, and the push
+ - is retried.
+ -
+ - When there's a lot of activity, we may fail more than once.
+ - On the other hand, we may fail because the remote is not available.
+ - Rather than retrying indefinitely, after the first retry we enter a
+ - fallback mode, where our push is guarenteed to succeed if the remote is
+ - reachable. If the fallback fails, the push is queued to be retried
+ - later.
+ -
+ - Returns any remotes that it failed to push to.
+ -}
+pushToRemotes :: Bool -> [Remote] -> Assistant [Remote]
+pushToRemotes notifypushes remotes = do
+ now <- liftIO getCurrentTime
+ syncAction remotes (pushToRemotes' now notifypushes)
+pushToRemotes' :: UTCTime -> Bool -> [Remote] -> Assistant [Remote]
+pushToRemotes' now notifypushes remotes = do
+ (g, branch, u) <- liftAnnex $ do
+ Annex.Branch.commit "update"
+ (,,)
+ <$> gitRepo
+ <*> inRepo Git.Branch.current
+ <*> getUUID
+ let (xmppremotes, normalremotes) = partition isXMPPRemote remotes
+ ret <- go True branch g u normalremotes
+ unless (null xmppremotes) $ do
+ shas <- liftAnnex $ map fst <$>
+ inRepo (Git.Ref.matchingWithHEAD
+ [Annex.Branch.fullname, Git.Ref.headRef])
+ forM_ xmppremotes $ \r -> sendNetMessage $
+ Pushing (getXMPPClientID r) (CanPush u shas)
+ return ret
+ where
+ go _ Nothing _ _ _ = return [] -- no branch, so nothing to do
+ go _ _ _ _ [] = return [] -- no remotes, so nothing to do
+ go shouldretry (Just branch) g u rs = do
+ debug ["pushing to", show rs]
+ liftIO $ Command.Sync.updateBranch (Command.Sync.syncBranch branch) g
+ (succeeded, failed) <- liftIO $ inParallel (push g branch) rs
+ updatemap succeeded []
+ if null failed
+ then do
+ when notifypushes $
+ sendNetMessage $ NotifyPush $
+ map Remote.uuid succeeded
+ return failed
+ else if shouldretry
+ then retry branch g u failed
+ else fallback branch g u failed
+
+ updatemap succeeded failed = changeFailedPushMap $ \m ->
+ M.union (makemap failed) $
+ M.difference m (makemap succeeded)
+ makemap l = M.fromList $ zip l (repeat now)
+
+ retry branch g u rs = do
+ debug ["trying manual pull to resolve failed pushes"]
+ void $ manualPull (Just branch) rs
+ go False (Just branch) g u rs
+
+ fallback branch g u rs = do
+ debug ["fallback pushing to", show rs]
+ (succeeded, failed) <- liftIO $
+ inParallel (\r -> taggedPush u Nothing branch r g) rs
+ updatemap succeeded failed
+ when (notifypushes && (not $ null succeeded)) $
+ sendNetMessage $ NotifyPush $
+ map Remote.uuid succeeded
+ return failed
+
+ push g branch remote = Command.Sync.pushBranch remote branch g
+
+{- Displays an alert while running an action that syncs with some remotes,
+ - and returns any remotes that it failed to sync with.
+ -
+ - XMPP remotes are handled specially; since the action can only start
+ - an async process for them, they are not included in the alert, but are
+ - still passed to the action.
+ -
+ - Readonly remotes are also hidden (to hide the web special remote).
+ -}
+syncAction :: [Remote] -> ([Remote] -> Assistant [Remote]) -> Assistant [Remote]
+syncAction rs a
+ | null visibleremotes = a rs
+ | otherwise = do
+ i <- addAlert $ syncAlert visibleremotes
+ failed <- a rs
+ let failed' = filter (not . Git.repoIsLocalUnknown . Remote.repo) failed
+ let succeeded = filter (`notElem` failed) visibleremotes
+ if null succeeded && null failed'
+ then removeAlert i
+ else updateAlertMap $ mergeAlert i $
+ syncResultAlert succeeded failed'
+ return failed
+ where
+ visibleremotes = filter (not . Remote.readonly) $
+ filter (not . isXMPPRemote) rs
+
+{- Manually pull from remotes and merge their branches. Returns any
+ - remotes that it failed to pull from, and a Bool indicating
+ - whether the git-annex branches of the remotes and local had
+ - diverged before the pull.
+ -
+ - After pulling from the normal git remotes, requests pushes from any
+ - XMPP remotes. However, those pushes will run asynchronously, so their
+ - results are not included in the return data.
+ -}
+manualPull :: Maybe Git.Ref -> [Remote] -> Assistant ([Remote], Bool)
+manualPull currentbranch remotes = do
+ g <- liftAnnex gitRepo
+ let (xmppremotes, normalremotes) = partition isXMPPRemote remotes
+ failed <- liftIO $ forM normalremotes $ \r ->
+ ifM (Git.Command.runBool [Param "fetch", Param $ Remote.name r] g)
+ ( return Nothing
+ , return $ Just r
+ )
+ haddiverged <- liftAnnex Annex.Branch.forceUpdate
+ forM_ normalremotes $ \r ->
+ liftAnnex $ Command.Sync.mergeRemote r currentbranch
+ u <- liftAnnex getUUID
+ forM_ xmppremotes $ \r ->
+ sendNetMessage $ Pushing (getXMPPClientID r) (PushRequest u)
+ return (catMaybes failed, haddiverged)
+
+{- Start syncing a remote, using a background thread. -}
+syncRemote :: Remote -> Assistant ()
+syncRemote remote = do
+ updateSyncRemotes
+ thread <- asIO $ do
+ reconnectRemotes False [remote]
+ addScanRemotes True [remote]
+ void $ liftIO $ forkIO $ thread
+
+{- Use Nothing to change autocommit setting; or a remote to change
+ - its sync setting. -}
+changeSyncable :: Maybe Remote -> Bool -> Assistant ()
+changeSyncable Nothing enable = do
+ liftAnnex $ Config.setConfig key (boolConfig enable)
+ liftIO . maybe noop (`throwTo` signal)
+ =<< namedThreadId watchThread
+ where
+ key = Config.annexConfig "autocommit"
+ signal
+ | enable = ResumeWatcher
+ | otherwise = PauseWatcher
+changeSyncable (Just r) True = do
+ liftAnnex $ changeSyncFlag r True
+ syncRemote r
+changeSyncable (Just r) False = do
+ liftAnnex $ changeSyncFlag r False
+ updateSyncRemotes
+ {- Stop all transfers to or from this remote.
+ - XXX Can't stop any ongoing scan, or git syncs. -}
+ void $ dequeueTransfers tofrom
+ mapM_ (cancelTransfer False) =<<
+ filter tofrom . M.keys . currentTransfers <$> getDaemonStatus
+ where
+ tofrom t = transferUUID t == Remote.uuid r
+
+changeSyncFlag :: Remote -> Bool -> Annex ()
+changeSyncFlag r enabled = do
+ Config.setConfig key (boolConfig enabled)
+ void Remote.remoteListRefresh
+ where
+ key = Config.remoteConfig (Remote.repo r) "sync"
diff --git a/Assistant/Threads/Committer.hs b/Assistant/Threads/Committer.hs
new file mode 100644
index 000000000..695703e22
--- /dev/null
+++ b/Assistant/Threads/Committer.hs
@@ -0,0 +1,493 @@
+{- git-annex assistant commit thread
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Assistant.Threads.Committer where
+
+import Assistant.Common
+import Assistant.Changes
+import Assistant.Types.Changes
+import Assistant.Commits
+import Assistant.Alert
+import Assistant.DaemonStatus
+import Assistant.TransferQueue
+import Assistant.Drop
+import Logs.Transfer
+import Logs.Location
+import qualified Annex.Queue
+import qualified Git.Command
+import qualified Git.LsFiles
+import qualified Git.BuildVersion
+import qualified Command.Add
+import Utility.ThreadScheduler
+import qualified Utility.Lsof as Lsof
+import qualified Utility.DirWatcher as DirWatcher
+import Types.KeySource
+import Config
+import Annex.Exception
+import Annex.Content
+import Annex.Link
+import Annex.CatFile
+import qualified Annex
+import Utility.InodeCache
+import Annex.Content.Direct
+
+import Data.Time.Clock
+import Data.Tuple.Utils
+import qualified Data.Set as S
+import qualified Data.Map as M
+import Data.Either
+import Control.Concurrent
+
+{- This thread makes git commits at appropriate times. -}
+commitThread :: NamedThread
+commitThread = namedThread "Committer" $ do
+ delayadd <- liftAnnex $
+ maybe delayaddDefault (return . Just . Seconds)
+ =<< annexDelayAdd <$> Annex.getGitConfig
+ waitChangeTime $ \(changes, time) -> do
+ readychanges <- handleAdds delayadd changes
+ if shouldCommit time (length readychanges) readychanges
+ then do
+ debug
+ [ "committing"
+ , show (length readychanges)
+ , "changes"
+ ]
+ void $ alertWhile commitAlert $
+ liftAnnex commitStaged
+ recordCommit
+ let numchanges = length readychanges
+ mapM_ checkChangeContent readychanges
+ return numchanges
+ else do
+ refill readychanges
+ return 0
+
+refill :: [Change] -> Assistant ()
+refill [] = noop
+refill cs = do
+ debug ["delaying commit of", show (length cs), "changes"]
+ refillChanges cs
+
+{- Wait for one or more changes to arrive to be committed, and then
+ - runs an action to commit them. If more changes arrive while this is
+ - going on, they're handled intelligently, batching up changes into
+ - large commits where possible, doing rename detection, and
+ - commiting immediately otherwise. -}
+waitChangeTime :: (([Change], UTCTime) -> Assistant Int) -> Assistant ()
+waitChangeTime a = waitchanges 0
+ where
+ waitchanges lastcommitsize = do
+ -- Wait one one second as a simple rate limiter.
+ liftIO $ threadDelaySeconds (Seconds 1)
+ -- Now, wait until at least one change is available for
+ -- processing.
+ cs <- getChanges
+ handlechanges cs lastcommitsize
+ handlechanges changes lastcommitsize = do
+ let len = length changes
+ -- See if now's a good time to commit.
+ now <- liftIO getCurrentTime
+ case (lastcommitsize >= maxCommitSize, shouldCommit now len changes, possiblyrename changes) of
+ (True, True, _)
+ | len > maxCommitSize ->
+ waitchanges =<< a (changes, now)
+ | otherwise -> aftermaxcommit changes
+ (_, True, False) ->
+ waitchanges =<< a (changes, now)
+ (_, True, True) -> do
+ morechanges <- getrelatedchanges changes
+ waitchanges =<< a (changes ++ morechanges, now)
+ _ -> do
+ refill changes
+ waitchanges lastcommitsize
+
+ {- Did we perhaps only get one of the AddChange and RmChange pair
+ - that make up a file rename? Or some of the pairs that make up
+ - a directory rename?
+ -}
+ possiblyrename = all renamepart
+
+ renamepart (PendingAddChange _ _) = True
+ renamepart c = isRmChange c
+
+ {- Gets changes related to the passed changes, without blocking
+ - very long.
+ -
+ - If there are multiple RmChanges, this is probably a directory
+ - rename, in which case it may be necessary to wait longer to get
+ - all the Changes involved.
+ -}
+ getrelatedchanges oldchanges
+ | length (filter isRmChange oldchanges) > 1 =
+ concat <$> getbatchchanges []
+ | otherwise = do
+ liftIO humanImperceptibleDelay
+ getAnyChanges
+ getbatchchanges cs = do
+ liftIO $ threadDelay $ fromIntegral $ oneSecond `div` 10
+ cs' <- getAnyChanges
+ if null cs'
+ then return cs
+ else getbatchchanges (cs':cs)
+
+ {- The last commit was maximum size, so it's very likely there
+ - are more changes and we'd like to ensure we make another commit
+ - of maximum size if possible.
+ -
+ - But, it can take a while for the Watcher to wake back up
+ - after a commit. It can get blocked by another thread
+ - that is using the Annex state, such as a git-annex branch
+ - commit. Especially after such a large commit, this can
+ - take several seconds. When this happens, it defeats the
+ - normal commit batching, which sees some old changes the
+ - Watcher found while the commit was being prepared, and sees
+ - no recent ones, and wants to commit immediately.
+ -
+ - All that we need to do, then, is wait for the Watcher to
+ - wake up, and queue up one more change.
+ -
+ - However, it's also possible that we're at the end of changes for
+ - now. So to avoid waiting a really long time before committing
+ - those changes we have, poll for up to 30 seconds, and then
+ - commit them.
+ -
+ - Also, try to run something in Annex, to ensure we block
+ - longer if the Annex state is indeed blocked.
+ -}
+ aftermaxcommit oldchanges = loop (30 :: Int)
+ where
+ loop 0 = continue oldchanges
+ loop n = do
+ liftAnnex noop -- ensure Annex state is free
+ liftIO $ threadDelaySeconds (Seconds 1)
+ changes <- getAnyChanges
+ if null changes
+ then loop (n - 1)
+ else continue (oldchanges ++ changes)
+ continue cs
+ | null cs = waitchanges 0
+ | otherwise = handlechanges cs 0
+
+isRmChange :: Change -> Bool
+isRmChange (Change { changeInfo = i }) | i == RmChange = True
+isRmChange _ = False
+
+{- An amount of time that is hopefully imperceptably short for humans,
+ - while long enough for a computer to get some work done.
+ - Note that 0.001 is a little too short for rename change batching to
+ - work. -}
+humanImperceptibleInterval :: NominalDiffTime
+humanImperceptibleInterval = 0.01
+
+humanImperceptibleDelay :: IO ()
+humanImperceptibleDelay = threadDelay $
+ truncate $ humanImperceptibleInterval * fromIntegral oneSecond
+
+maxCommitSize :: Int
+maxCommitSize = 5000
+
+{- Decide if now is a good time to make a commit.
+ - Note that the list of changes has an undefined order.
+ -
+ - Current strategy: If there have been 10 changes within the past second,
+ - a batch activity is taking place, so wait for later.
+ -}
+shouldCommit :: UTCTime -> Int -> [Change] -> Bool
+shouldCommit now len changes
+ | len == 0 = False
+ | len >= maxCommitSize = True
+ | length recentchanges < 10 = True
+ | otherwise = False -- batch activity
+ where
+ thissecond c = timeDelta c <= 1
+ recentchanges = filter thissecond changes
+ timeDelta c = now `diffUTCTime` changeTime c
+
+commitStaged :: Annex Bool
+commitStaged = do
+ {- This could fail if there's another commit being made by
+ - something else. -}
+ v <- tryAnnex Annex.Queue.flush
+ case v of
+ Left _ -> return False
+ Right _ -> do
+ {- Empty commits may be made if tree changes cancel
+ - each other out, etc. Git returns nonzero on those,
+ - so don't propigate out commit failures. -}
+ void $ inRepo $ catchMaybeIO .
+ Git.Command.runQuiet
+ (Param "commit" : nomessage params)
+ return True
+ where
+ params =
+ [ Param "--quiet"
+ {- Avoid running the usual pre-commit hook;
+ - the Watcher does the same symlink fixing,
+ - and direct mode bookkeeping updating. -}
+ , Param "--no-verify"
+ ]
+ nomessage ps
+ | Git.BuildVersion.older "1.7.2" =
+ Param "-m" : Param "autocommit" : ps
+ | Git.BuildVersion.older "1.7.8" =
+ Param "--allow-empty-message" :
+ Param "-m" : Param "" : ps
+ | otherwise =
+ Param "--allow-empty-message" :
+ Param "--no-edit" : Param "-m" : Param "" : ps
+
+{- OSX needs a short delay after a file is added before locking it down,
+ - when using a non-direct mode repository, as pasting a file seems to
+ - try to set file permissions or otherwise access the file after closing
+ - it. -}
+delayaddDefault :: Annex (Maybe Seconds)
+#ifdef darwin_HOST_OS
+delayaddDefault = ifM isDirect
+ ( return Nothing
+ , return $ Just $ Seconds 1
+ )
+#else
+delayaddDefault = return Nothing
+#endif
+
+{- If there are PendingAddChanges, or InProcessAddChanges, the files
+ - have not yet actually been added to the annex, and that has to be done
+ - now, before committing.
+ -
+ - Deferring the adds to this point causes batches to be bundled together,
+ - which allows faster checking with lsof that the files are not still open
+ - for write by some other process, and faster checking with git-ls-files
+ - that the files are not already checked into git.
+ -
+ - When a file is added, Inotify will notice the new symlink. So this waits
+ - for additional Changes to arrive, so that the symlink has hopefully been
+ - staged before returning, and will be committed immediately.
+ -
+ - OTOH, for kqueue, eventsCoalesce, so instead the symlink is directly
+ - created and staged.
+ -
+ - Returns a list of all changes that are ready to be committed.
+ - Any pending adds that are not ready yet are put back into the ChangeChan,
+ - where they will be retried later.
+ -}
+handleAdds :: Maybe Seconds -> [Change] -> Assistant [Change]
+handleAdds delayadd cs = returnWhen (null incomplete) $ do
+ let (pending, inprocess) = partition isPendingAddChange incomplete
+ direct <- liftAnnex isDirect
+ (pending', cleanup) <- if direct
+ then return (pending, noop)
+ else findnew pending
+ (postponed, toadd) <- partitionEithers <$> safeToAdd delayadd pending' inprocess
+ cleanup
+
+ unless (null postponed) $
+ refillChanges postponed
+
+ returnWhen (null toadd) $ do
+ added <- addaction toadd $
+ catMaybes <$> if direct
+ then adddirect toadd
+ else forM toadd add
+ if DirWatcher.eventsCoalesce || null added || direct
+ then return $ added ++ otherchanges
+ else do
+ r <- handleAdds delayadd =<< getChanges
+ return $ r ++ added ++ otherchanges
+ where
+ (incomplete, otherchanges) = partition (\c -> isPendingAddChange c || isInProcessAddChange c) cs
+
+ findnew [] = return ([], noop)
+ findnew pending@(exemplar:_) = do
+ (newfiles, cleanup) <- liftAnnex $
+ inRepo (Git.LsFiles.notInRepo False $ map changeFile pending)
+ -- note: timestamp info is lost here
+ let ts = changeTime exemplar
+ return (map (PendingAddChange ts) newfiles, void $ liftIO cleanup)
+
+ returnWhen c a
+ | c = return otherchanges
+ | otherwise = a
+
+ add :: Change -> Assistant (Maybe Change)
+ add change@(InProcessAddChange { keySource = ks }) =
+ catchDefaultIO Nothing <~> doadd
+ where
+ doadd = sanitycheck ks $ do
+ (mkey, mcache) <- liftAnnex $ do
+ showStart "add" $ keyFilename ks
+ Command.Add.ingest $ Just ks
+ maybe (failedingest change) (done change mcache $ keyFilename ks) mkey
+ add _ = return Nothing
+
+ {- In direct mode, avoid overhead of re-injesting a renamed
+ - file, by examining the other Changes to see if a removed
+ - file has the same InodeCache as the new file. If so,
+ - we can just update bookkeeping, and stage the file in git.
+ -}
+ adddirect :: [Change] -> Assistant [Maybe Change]
+ adddirect toadd = do
+ ct <- liftAnnex compareInodeCachesWith
+ m <- liftAnnex $ removedKeysMap ct cs
+ if M.null m
+ then forM toadd add
+ else forM toadd $ \c -> do
+ mcache <- liftIO $ genInodeCache $ changeFile c
+ case mcache of
+ Nothing -> add c
+ Just cache ->
+ case M.lookup (inodeCacheToKey ct cache) m of
+ Nothing -> add c
+ Just k -> fastadd c k
+
+ fastadd :: Change -> Key -> Assistant (Maybe Change)
+ fastadd change key = do
+ let source = keySource change
+ liftAnnex $ Command.Add.finishIngestDirect key source
+ done change Nothing (keyFilename source) key
+
+ removedKeysMap :: InodeComparisonType -> [Change] -> Annex (M.Map InodeCacheKey Key)
+ removedKeysMap ct l = do
+ mks <- forM (filter isRmChange l) $ \c ->
+ catKeyFile $ changeFile c
+ M.fromList . concat <$> mapM mkpairs (catMaybes mks)
+ where
+ mkpairs k = map (\c -> (inodeCacheToKey ct c, k)) <$>
+ recordedInodeCache k
+
+ failedingest change = do
+ refill [retryChange change]
+ liftAnnex showEndFail
+ return Nothing
+
+ done change mcache file key = liftAnnex $ do
+ logStatus key InfoPresent
+ link <- ifM isDirect
+ ( inRepo $ gitAnnexLink file key
+ , Command.Add.link file key mcache
+ )
+ whenM (pure DirWatcher.eventsCoalesce <||> isDirect) $
+ stageSymlink file =<< hashSymlink link
+ showEndOk
+ return $ Just $ finishedChange change key
+
+ {- Check that the keysource's keyFilename still exists,
+ - and is still a hard link to its contentLocation,
+ - before ingesting it. -}
+ sanitycheck keysource a = do
+ fs <- liftIO $ getSymbolicLinkStatus $ keyFilename keysource
+ ks <- liftIO $ getSymbolicLinkStatus $ contentLocation keysource
+ if deviceID ks == deviceID fs && fileID ks == fileID fs
+ then a
+ else do
+ -- remove the hard link
+ when (contentLocation keysource /= keyFilename keysource) $
+ void $ liftIO $ tryIO $ removeFile $ contentLocation keysource
+ return Nothing
+
+ {- Shown an alert while performing an action to add a file or
+ - files. When only a few files are added, their names are shown
+ - in the alert. When it's a batch add, the number of files added
+ - is shown.
+ -
+ - Add errors tend to be transient and will be
+ - automatically dealt with, so the alert is always told
+ - the add succeeded.
+ -}
+ addaction [] a = a
+ addaction toadd a = alertWhile' (addFileAlert $ map changeFile toadd) $
+ (,)
+ <$> pure True
+ <*> a
+
+{- Files can Either be Right to be added now,
+ - or are unsafe, and must be Left for later.
+ -
+ - Check by running lsof on the repository.
+ -}
+safeToAdd :: Maybe Seconds -> [Change] -> [Change] -> Assistant [Either Change Change]
+safeToAdd _ [] [] = return []
+safeToAdd delayadd pending inprocess = do
+ maybe noop (liftIO . threadDelaySeconds) delayadd
+ liftAnnex $ do
+ keysources <- forM pending $ Command.Add.lockDown . changeFile
+ let inprocess' = inprocess ++ mapMaybe mkinprocess (zip pending keysources)
+ openfiles <- S.fromList . map fst3 . filter openwrite <$>
+ findopenfiles (map keySource inprocess')
+ let checked = map (check openfiles) inprocess'
+
+ {- If new events are received when files are closed,
+ - there's no need to retry any changes that cannot
+ - be done now. -}
+ if DirWatcher.closingTracked
+ then do
+ mapM_ canceladd $ lefts checked
+ allRight $ rights checked
+ else return checked
+ where
+ check openfiles change@(InProcessAddChange { keySource = ks })
+ | S.member (contentLocation ks) openfiles = Left change
+ check _ change = Right change
+
+ mkinprocess (c, Just ks) = Just InProcessAddChange
+ { changeTime = changeTime c
+ , keySource = ks
+ }
+ mkinprocess (_, Nothing) = Nothing
+
+ canceladd (InProcessAddChange { keySource = ks }) = do
+ warning $ keyFilename ks
+ ++ " still has writers, not adding"
+ -- remove the hard link
+ when (contentLocation ks /= keyFilename ks) $
+ void $ liftIO $ tryIO $ removeFile $ contentLocation ks
+ canceladd _ = noop
+
+ openwrite (_file, mode, _pid)
+ | mode == Lsof.OpenWriteOnly = True
+ | mode == Lsof.OpenReadWrite = True
+ | mode == Lsof.OpenUnknown = True
+ | otherwise = False
+
+ allRight = return . map Right
+
+ {- Normally the KeySources are locked down inside the temp directory,
+ - so can just lsof that, which is quite efficient.
+ -
+ - In crippled filesystem mode, there is no lock down, so must run lsof
+ - on each individual file.
+ -}
+ findopenfiles keysources = ifM crippledFileSystem
+ ( liftIO $ do
+ let segments = segmentXargs $ map keyFilename keysources
+ concat <$> forM segments (\fs -> Lsof.query $ "--" : fs)
+ , do
+ tmpdir <- fromRepo gitAnnexTmpDir
+ liftIO $ Lsof.queryDir tmpdir
+ )
+
+{- After a Change is committed, queue any necessary transfers or drops
+ - of the content of the key.
+ -
+ - This is not done during the startup scan, because the expensive
+ - transfer scan does the same thing then.
+ -}
+checkChangeContent :: Change -> Assistant ()
+checkChangeContent change@(Change { changeInfo = i }) =
+ case changeInfoKey i of
+ Nothing -> noop
+ Just k -> whenM (scanComplete <$> getDaemonStatus) $ do
+ present <- liftAnnex $ inAnnex k
+ if present
+ then queueTransfers "new file created" Next k (Just f) Upload
+ else queueTransfers "new or renamed file wanted" Next k (Just f) Download
+ handleDrops "file renamed" present k (Just f) Nothing
+ where
+ f = changeFile change
+checkChangeContent _ = noop
diff --git a/Assistant/Threads/ConfigMonitor.hs b/Assistant/Threads/ConfigMonitor.hs
new file mode 100644
index 000000000..c180c4da9
--- /dev/null
+++ b/Assistant/Threads/ConfigMonitor.hs
@@ -0,0 +1,87 @@
+{- git-annex assistant config monitor thread
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.Threads.ConfigMonitor where
+
+import Assistant.Common
+import Assistant.BranchChange
+import Assistant.DaemonStatus
+import Assistant.Commits
+import Utility.ThreadScheduler
+import Logs
+import Logs.UUID
+import Logs.Trust
+import Logs.PreferredContent
+import Logs.Group
+import Remote.List (remoteListRefresh)
+import qualified Git.LsTree as LsTree
+import Git.FilePath
+import qualified Annex.Branch
+
+import qualified Data.Set as S
+
+{- This thread detects when configuration changes have been made to the
+ - git-annex branch and reloads cached configuration.
+ -
+ - If the branch is frequently changing, it's checked for configuration
+ - changes no more often than once every 60 seconds. On the other hand,
+ - if the branch has not changed in a while, configuration changes will
+ - be detected immediately.
+ -}
+configMonitorThread :: NamedThread
+configMonitorThread = namedThread "ConfigMonitor" $ loop =<< getConfigs
+ where
+ loop old = do
+ waitBranchChange
+ new <- getConfigs
+ when (old /= new) $ do
+ let changedconfigs = new `S.difference` old
+ debug $ "reloading config" :
+ map fst (S.toList changedconfigs)
+ reloadConfigs new
+ {- Record a commit to get this config
+ - change pushed out to remotes. -}
+ recordCommit
+ liftIO $ threadDelaySeconds (Seconds 60)
+ loop new
+
+{- Config files, and their checksums. -}
+type Configs = S.Set (FilePath, String)
+
+{- All git-annex's config files, and actions to run when they change. -}
+configFilesActions :: [(FilePath, Assistant ())]
+configFilesActions =
+ [ (uuidLog, void $ liftAnnex uuidMapLoad)
+ , (remoteLog, void $ liftAnnex remoteListRefresh)
+ , (trustLog, void $ liftAnnex trustMapLoad)
+ , (groupLog, void $ liftAnnex groupMapLoad)
+ , (scheduleLog, void updateScheduleLog)
+ -- Preferred content settings depend on most of the other configs,
+ -- so will be reloaded whenever any configs change.
+ , (preferredContentLog, noop)
+ ]
+
+reloadConfigs :: Configs -> Assistant ()
+reloadConfigs changedconfigs = do
+ sequence_ as
+ void $ liftAnnex preferredContentMapLoad
+ {- Changes to the remote log, or the trust log, can affect the
+ - syncRemotes list. Changes to the uuid log may affect its
+ - display so are also included. -}
+ when (any (`elem` fs) [remoteLog, trustLog, uuidLog])
+ updateSyncRemotes
+ where
+ (fs, as) = unzip $ filter (flip S.member changedfiles . fst)
+ configFilesActions
+ changedfiles = S.map fst changedconfigs
+
+getConfigs :: Assistant Configs
+getConfigs = S.fromList . map extract
+ <$> liftAnnex (inRepo $ LsTree.lsTreeFiles Annex.Branch.fullname files)
+ where
+ files = map fst configFilesActions
+ extract treeitem = (getTopFilePath $ LsTree.file treeitem, LsTree.sha treeitem)
diff --git a/Assistant/Threads/Cronner.hs b/Assistant/Threads/Cronner.hs
new file mode 100644
index 000000000..55b3ca2f1
--- /dev/null
+++ b/Assistant/Threads/Cronner.hs
@@ -0,0 +1,225 @@
+{- git-annex assistant sceduled jobs runner
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE DeriveDataTypeable #-}
+
+module Assistant.Threads.Cronner (
+ cronnerThread
+) where
+
+import Assistant.Common
+import Assistant.DaemonStatus
+import Utility.NotificationBroadcaster
+import Annex.UUID
+import Config.Files
+import Logs.Schedule
+import Utility.Scheduled
+import Types.ScheduledActivity
+import Utility.ThreadScheduler
+import Utility.HumanTime
+import Utility.Batch
+import Assistant.TransferQueue
+import Annex.Content
+import Logs.Transfer
+import Assistant.Types.UrlRenderer
+import Assistant.Alert
+import Remote
+import qualified Types.Remote as Remote
+import qualified Git
+import qualified Git.Fsck
+import Assistant.Fsck
+import Assistant.Repair
+
+import Control.Concurrent.Async
+import Control.Concurrent.MVar
+import Data.Time.LocalTime
+import Data.Time.Clock
+import qualified Data.Map as M
+import qualified Data.Set as S
+
+{- Loads schedules for this repository, and fires off one thread for each
+ - scheduled event that runs on this repository. Each thread sleeps until
+ - its event is scheduled to run.
+ -
+ - To handle events that run on remotes, which need to only run when
+ - their remote gets connected, threads are also started, and are passed
+ - a MVar to wait on, which is stored in the DaemonStatus's
+ - connectRemoteNotifiers.
+ -
+ - In the meantime the main thread waits for any changes to the
+ - schedules. When there's a change, compare the old and new list of
+ - schedules to find deleted and added ones. Start new threads for added
+ - ones, and kill the threads for deleted ones. -}
+cronnerThread :: UrlRenderer -> NamedThread
+cronnerThread urlrenderer = namedThreadUnchecked "Cronner" $ do
+ fsckNudge urlrenderer Nothing
+ dstatus <- getDaemonStatus
+ h <- liftIO $ newNotificationHandle False (scheduleLogNotifier dstatus)
+ go h M.empty M.empty
+ where
+ go h amap nmap = do
+ activities <- liftAnnex $ scheduleGet =<< getUUID
+
+ let addedactivities = activities `S.difference` M.keysSet amap
+ let removedactivities = M.keysSet amap `S.difference` activities
+
+ forM_ (S.toList removedactivities) $ \activity ->
+ case M.lookup activity amap of
+ Just a -> do
+ debug ["stopping removed job for", fromScheduledActivity activity, show (asyncThreadId a)]
+ liftIO $ cancel a
+ Nothing -> noop
+
+ lastruntimes <- liftAnnex getLastRunTimes
+ started <- startactivities (S.toList addedactivities) lastruntimes
+ let addedamap = M.fromList $ map fst started
+ let addednmap = M.fromList $ catMaybes $ map snd started
+
+ let removefiltered = M.filterWithKey (\k _ -> S.member k removedactivities)
+ let amap' = M.difference (M.union addedamap amap) (removefiltered amap)
+ let nmap' = M.difference (M.union addednmap nmap) (removefiltered nmap)
+ modifyDaemonStatus_ $ \s -> s { connectRemoteNotifiers = M.fromListWith (++) (M.elems nmap') }
+
+ liftIO $ waitNotification h
+ debug ["reloading changed activities"]
+ go h amap' nmap'
+ startactivities as lastruntimes = forM as $ \activity ->
+ case connectActivityUUID activity of
+ Nothing -> do
+ runner <- asIO2 (sleepingActivityThread urlrenderer)
+ a <- liftIO $ async $
+ runner activity (M.lookup activity lastruntimes)
+ return ((activity, a), Nothing)
+ Just u -> do
+ mvar <- liftIO newEmptyMVar
+ runner <- asIO2 (remoteActivityThread urlrenderer mvar)
+ a <- liftIO $ async $
+ runner activity (M.lookup activity lastruntimes)
+ return ((activity, a), Just (activity, (u, [mvar])))
+
+{- Calculate the next time the activity is scheduled to run, then
+ - sleep until that time, and run it. Then call setLastRunTime, and
+ - loop.
+ -}
+sleepingActivityThread :: UrlRenderer -> ScheduledActivity -> Maybe LocalTime -> Assistant ()
+sleepingActivityThread urlrenderer activity lasttime = go lasttime =<< getnexttime lasttime
+ where
+ getnexttime = liftIO . nextTime schedule
+ go _ Nothing = debug ["no scheduled events left for", desc]
+ go l (Just (NextTimeExactly t)) = waitrun l t Nothing
+ go l (Just (NextTimeWindow windowstart windowend)) =
+ waitrun l windowstart (Just windowend)
+ desc = fromScheduledActivity activity
+ schedule = getSchedule activity
+ waitrun l t mmaxt = do
+ seconds <- liftIO $ secondsUntilLocalTime t
+ when (seconds > Seconds 0) $ do
+ debug ["waiting", show seconds, "for next scheduled", desc]
+ liftIO $ threadDelaySeconds seconds
+ now <- liftIO getCurrentTime
+ tz <- liftIO $ getTimeZone now
+ let nowt = utcToLocalTime tz now
+ if tolate nowt tz
+ then do
+ debug ["too late to run scheduled", desc]
+ go l =<< getnexttime l
+ else run nowt
+ where
+ tolate nowt tz = case mmaxt of
+ Just maxt -> nowt > maxt
+ -- allow the job to start 10 minutes late
+ Nothing ->diffUTCTime
+ (localTimeToUTC tz nowt)
+ (localTimeToUTC tz t) > 600
+ run nowt = do
+ runActivity urlrenderer activity nowt
+ go (Just nowt) =<< getnexttime (Just nowt)
+
+{- Wait for the remote to become available by waiting on the MVar.
+ - Then check if the time is within a time window when activity
+ - is scheduled to run, and if so run it.
+ - Otherwise, just wait again on the MVar.
+ -}
+remoteActivityThread :: UrlRenderer -> MVar () -> ScheduledActivity -> Maybe LocalTime -> Assistant ()
+remoteActivityThread urlrenderer mvar activity lasttime = do
+ liftIO $ takeMVar mvar
+ go =<< liftIO (nextTime (getSchedule activity) lasttime)
+ where
+ go (Just (NextTimeWindow windowstart windowend)) = do
+ now <- liftIO getCurrentTime
+ tz <- liftIO $ getTimeZone now
+ if now >= localTimeToUTC tz windowstart && now <= localTimeToUTC tz windowend
+ then do
+ let nowt = utcToLocalTime tz now
+ runActivity urlrenderer activity nowt
+ loop (Just nowt)
+ else loop lasttime
+ go _ = noop -- running at exact time not handled here
+ loop = remoteActivityThread urlrenderer mvar activity
+
+secondsUntilLocalTime :: LocalTime -> IO Seconds
+secondsUntilLocalTime t = do
+ now <- getCurrentTime
+ tz <- getTimeZone now
+ let secs = truncate $ diffUTCTime (localTimeToUTC tz t) now
+ return $ if secs > 0
+ then Seconds secs
+ else Seconds 0
+
+runActivity :: UrlRenderer -> ScheduledActivity -> LocalTime -> Assistant ()
+runActivity urlrenderer activity nowt = do
+ debug ["starting", desc]
+ runActivity' urlrenderer activity
+ debug ["finished", desc]
+ liftAnnex $ setLastRunTime activity nowt
+ where
+ desc = fromScheduledActivity activity
+
+runActivity' :: UrlRenderer -> ScheduledActivity -> Assistant ()
+runActivity' urlrenderer (ScheduledSelfFsck _ d) = do
+ program <- liftIO $ readProgramFile
+ g <- liftAnnex gitRepo
+ fsckresults <- showFscking urlrenderer Nothing $ tryNonAsync $ do
+ void $ batchCommand program (Param "fsck" : annexFsckParams d)
+ Git.Fsck.findBroken True g
+ u <- liftAnnex getUUID
+ void $ repairWhenNecessary urlrenderer u Nothing fsckresults
+ mapM_ reget =<< liftAnnex (dirKeys gitAnnexBadDir)
+ where
+ reget k = queueTransfers "fsck found bad file; redownloading" Next k Nothing Download
+runActivity' urlrenderer (ScheduledRemoteFsck u s d) = handle =<< liftAnnex (remoteFromUUID u)
+ where
+ handle Nothing = debug ["skipping remote fsck of uuid without a configured remote", fromUUID u, fromSchedule s]
+ handle (Just rmt) = void $ case Remote.remoteFsck rmt of
+ Nothing -> go rmt $ do
+ program <- readProgramFile
+ void $ batchCommand program $
+ [ Param "fsck"
+ -- avoid downloading files
+ , Param "--fast"
+ , Param "--from"
+ , Param $ Remote.name rmt
+ ] ++ annexFsckParams d
+ Just mkfscker -> do
+ {- Note that having mkfsker return an IO action
+ - avoids running a long duration fsck in the
+ - Annex monad. -}
+ go rmt =<< liftAnnex (mkfscker (annexFsckParams d))
+ go rmt annexfscker = do
+ fsckresults <- showFscking urlrenderer (Just rmt) $ tryNonAsync $ do
+ void annexfscker
+ let r = Remote.repo rmt
+ if Git.repoIsLocal r && not (Git.repoIsLocalUnknown r)
+ then Just <$> Git.Fsck.findBroken True r
+ else pure Nothing
+ maybe noop (void . repairWhenNecessary urlrenderer u (Just rmt)) fsckresults
+
+annexFsckParams :: Duration -> [CommandParam]
+annexFsckParams d =
+ [ Param "--incremental-schedule=1d"
+ , Param $ "--time-limit=" ++ fromDuration d
+ ]
diff --git a/Assistant/Threads/DaemonStatus.hs b/Assistant/Threads/DaemonStatus.hs
new file mode 100644
index 000000000..5bbb15acb
--- /dev/null
+++ b/Assistant/Threads/DaemonStatus.hs
@@ -0,0 +1,29 @@
+{- git-annex assistant daemon status thread
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.Threads.DaemonStatus where
+
+import Assistant.Common
+import Assistant.DaemonStatus
+import Utility.ThreadScheduler
+import Utility.NotificationBroadcaster
+
+{- This writes the daemon status to disk, when it changes, but no more
+ - frequently than once every ten minutes.
+ -}
+daemonStatusThread :: NamedThread
+daemonStatusThread = namedThread "DaemonStatus" $ do
+ notifier <- liftIO . newNotificationHandle False
+ =<< changeNotifier <$> getDaemonStatus
+ checkpoint
+ runEvery (Seconds tenMinutes) <~> do
+ liftIO $ waitNotification notifier
+ checkpoint
+ where
+ checkpoint = do
+ file <- liftAnnex $ fromRepo gitAnnexDaemonStatusFile
+ liftIO . writeDaemonStatusFile file =<< getDaemonStatus
diff --git a/Assistant/Threads/Glacier.hs b/Assistant/Threads/Glacier.hs
new file mode 100644
index 000000000..4c4012a67
--- /dev/null
+++ b/Assistant/Threads/Glacier.hs
@@ -0,0 +1,43 @@
+{- git-annex assistant Amazon Glacier retrieval
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE OverloadedStrings #-}
+
+module Assistant.Threads.Glacier where
+
+import Assistant.Common
+import Utility.ThreadScheduler
+import qualified Types.Remote as Remote
+import qualified Remote.Glacier as Glacier
+import Logs.Transfer
+import Assistant.DaemonStatus
+import Assistant.TransferQueue
+
+import qualified Data.Set as S
+
+{- Wakes up every half hour and checks if any glacier remotes have failed
+ - downloads. If so, runs glacier-cli to check if the files are now
+ - available, and queues the downloads. -}
+glacierThread :: NamedThread
+glacierThread = namedThread "Glacier" $ runEvery (Seconds 3600) <~> go
+ where
+ isglacier r = Remote.remotetype r == Glacier.remote
+ go = do
+ rs <- filter isglacier . syncDataRemotes <$> getDaemonStatus
+ forM_ rs $ \r ->
+ check r =<< liftAnnex (getFailedTransfers $ Remote.uuid r)
+ check _ [] = noop
+ check r l = do
+ let keys = map getkey l
+ (availkeys, failedkeys) <- liftAnnex $ Glacier.jobList r keys
+ let s = S.fromList (failedkeys ++ availkeys)
+ let l' = filter (\p -> S.member (getkey p) s) l
+ forM_ l' $ \(t, info) -> do
+ liftAnnex $ removeFailedTransfer t
+ queueTransferWhenSmall "object available from glacier" (associatedFile info) t r
+ getkey = transferKey . fst
diff --git a/Assistant/Threads/Merger.hs b/Assistant/Threads/Merger.hs
new file mode 100644
index 000000000..3f4fcb0cc
--- /dev/null
+++ b/Assistant/Threads/Merger.hs
@@ -0,0 +1,118 @@
+{- git-annex assistant git merge thread
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.Threads.Merger where
+
+import Assistant.Common
+import Assistant.TransferQueue
+import Assistant.BranchChange
+import Assistant.DaemonStatus
+import Assistant.ScanRemotes
+import Utility.DirWatcher
+import Utility.DirWatcher.Types
+import qualified Annex.Branch
+import qualified Git
+import qualified Git.Branch
+import qualified Command.Sync
+import Annex.TaggedPush
+import Remote (remoteFromUUID)
+
+import qualified Data.Set as S
+import qualified Data.Text as T
+
+{- This thread watches for changes to .git/refs/, and handles incoming
+ - pushes. -}
+mergeThread :: NamedThread
+mergeThread = namedThread "Merger" $ do
+ g <- liftAnnex gitRepo
+ let dir = Git.localGitDir g </> "refs"
+ liftIO $ createDirectoryIfMissing True dir
+ let hook a = Just <$> asIO2 (runHandler a)
+ changehook <- hook onChange
+ errhook <- hook onErr
+ let hooks = mkWatchHooks
+ { addHook = changehook
+ , modifyHook = changehook
+ , errHook = errhook
+ }
+ void $ liftIO $ watchDir dir (const False) hooks id
+ debug ["watching", dir]
+
+type Handler = FilePath -> Assistant ()
+
+{- Runs an action handler.
+ -
+ - Exceptions are ignored, otherwise a whole thread could be crashed.
+ -}
+runHandler :: Handler -> FilePath -> Maybe FileStatus -> Assistant ()
+runHandler handler file _filestatus =
+ either (liftIO . print) (const noop) =<< tryIO <~> handler file
+
+{- Called when there's an error with inotify. -}
+onErr :: Handler
+onErr = error
+
+{- Called when a new branch ref is written, or a branch ref is modified.
+ -
+ - At startup, synthetic add events fire, causing this to run, but that's
+ - ok; it ensures that any changes pushed since the last time the assistant
+ - ran are merged in.
+ -}
+onChange :: Handler
+onChange file
+ | ".lock" `isSuffixOf` file = noop
+ | isAnnexBranch file = do
+ branchChanged
+ diverged <- liftAnnex Annex.Branch.forceUpdate
+ when diverged $
+ unlessM handleDesynced $
+ queueDeferredDownloads "retrying deferred download" Later
+ | "/synced/" `isInfixOf` file =
+ mergecurrent =<< liftAnnex (inRepo Git.Branch.current)
+ | otherwise = noop
+ where
+ changedbranch = fileToBranch file
+
+ mergecurrent (Just current)
+ | equivBranches changedbranch current = do
+ debug
+ [ "merging", show changedbranch
+ , "into", show current
+ ]
+ void $ liftAnnex $ Command.Sync.mergeFrom changedbranch
+ mergecurrent _ = noop
+
+ handleDesynced = case fromTaggedBranch changedbranch of
+ Nothing -> return False
+ Just (u, info) -> do
+ mr <- liftAnnex $ remoteFromUUID u
+ case mr of
+ Nothing -> return False
+ Just r -> do
+ s <- desynced <$> getDaemonStatus
+ if S.member u s || Just (T.unpack $ getXMPPClientID r) == info
+ then do
+ modifyDaemonStatus_ $ \st -> st
+ { desynced = S.delete u s }
+ addScanRemotes True [r]
+ return True
+ else return False
+
+equivBranches :: Git.Ref -> Git.Ref -> Bool
+equivBranches x y = base x == base y
+ where
+ base = takeFileName . show
+
+isAnnexBranch :: FilePath -> Bool
+isAnnexBranch f = n `isSuffixOf` f
+ where
+ n = '/' : show Annex.Branch.name
+
+fileToBranch :: FilePath -> Git.Ref
+fileToBranch f = Git.Ref $ "refs" </> base
+ where
+ base = Prelude.last $ split "/refs/" f
diff --git a/Assistant/Threads/MountWatcher.hs b/Assistant/Threads/MountWatcher.hs
new file mode 100644
index 000000000..39ae67537
--- /dev/null
+++ b/Assistant/Threads/MountWatcher.hs
@@ -0,0 +1,195 @@
+{- git-annex assistant mount watcher, using either dbus or mtab polling
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE OverloadedStrings #-}
+
+module Assistant.Threads.MountWatcher where
+
+import Assistant.Common
+import Assistant.DaemonStatus
+import Assistant.Sync
+import qualified Annex
+import qualified Git
+import Utility.ThreadScheduler
+import Utility.Mounts
+import Remote.List
+import qualified Types.Remote as Remote
+import Assistant.Types.UrlRenderer
+import Assistant.Fsck
+
+import qualified Data.Set as S
+
+#if WITH_DBUS
+import Utility.DBus
+import DBus.Client
+import DBus
+import Data.Word (Word32)
+import Control.Concurrent
+import qualified Control.Exception as E
+#else
+#warning Building without dbus support; will use mtab polling
+#endif
+
+mountWatcherThread :: UrlRenderer -> NamedThread
+mountWatcherThread urlrenderer = namedThread "MountWatcher" $
+#if WITH_DBUS
+ dbusThread urlrenderer
+#else
+ pollingThread urlrenderer
+#endif
+
+#if WITH_DBUS
+
+dbusThread :: UrlRenderer -> Assistant ()
+dbusThread urlrenderer = do
+ runclient <- asIO1 go
+ r <- liftIO $ E.try $ runClient getSessionAddress runclient
+ either onerr (const noop) r
+ where
+ go client = ifM (checkMountMonitor client)
+ ( do
+ {- Store the current mount points in an MVar, to be
+ - compared later. We could in theory work out the
+ - mount point from the dbus message, but this is
+ - easier. -}
+ mvar <- liftIO $ newMVar =<< currentMountPoints
+ handleevent <- asIO1 $ \_event -> do
+ nowmounted <- liftIO $ currentMountPoints
+ wasmounted <- liftIO $ swapMVar mvar nowmounted
+ handleMounts urlrenderer wasmounted nowmounted
+ liftIO $ forM_ mountChanged $ \matcher ->
+ listen client matcher handleevent
+ , do
+ liftAnnex $
+ warning "No known volume monitor available through dbus; falling back to mtab polling"
+ pollingThread urlrenderer
+ )
+ onerr :: E.SomeException -> Assistant ()
+ onerr e = do
+ {- If the session dbus fails, the user probably
+ - logged out of their desktop. Even if they log
+ - back in, we won't have access to the dbus
+ - session key, so polling is the best that can be
+ - done in this situation. -}
+ liftAnnex $
+ warning $ "dbus failed; falling back to mtab polling (" ++ show e ++ ")"
+ pollingThread urlrenderer
+
+{- Examine the list of services connected to dbus, to see if there
+ - are any we can use to monitor mounts. If not, will attempt to start one. -}
+checkMountMonitor :: Client -> Assistant Bool
+checkMountMonitor client = do
+ running <- filter (`elem` usableservices)
+ <$> liftIO (listServiceNames client)
+ case running of
+ [] -> startOneService client startableservices
+ (service:_) -> do
+ debug [ "Using running DBUS service"
+ , service
+ , "to monitor mount events."
+ ]
+ return True
+ where
+ startableservices = [gvfs, gvfsgdu]
+ usableservices = startableservices ++ [kde]
+ gvfs = "org.gtk.Private.UDisks2VolumeMonitor"
+ gvfsgdu = "org.gtk.Private.GduVolumeMonitor"
+ kde = "org.kde.DeviceNotifications"
+
+startOneService :: Client -> [ServiceName] -> Assistant Bool
+startOneService _ [] = return False
+startOneService client (x:xs) = do
+ _ <- liftIO $ tryNonAsync $ callDBus client "StartServiceByName"
+ [toVariant x, toVariant (0 :: Word32)]
+ ifM (liftIO $ elem x <$> listServiceNames client)
+ ( do
+ debug
+ [ "Started DBUS service", x
+ , "to monitor mount events."
+ ]
+ return True
+ , startOneService client xs
+ )
+
+{- Filter matching events recieved when drives are mounted and unmounted. -}
+mountChanged :: [MatchRule]
+mountChanged = [gvfs True, gvfs False, kde, kdefallback]
+ where
+ {- gvfs reliably generates this event whenever a
+ - drive is mounted/unmounted, whether automatically, or manually -}
+ gvfs mount = matchAny
+ { matchInterface = Just "org.gtk.Private.RemoteVolumeMonitor"
+ , matchMember = Just $ if mount then "MountAdded" else "MountRemoved"
+ }
+ {- This event fires when KDE prompts the user what to do with a drive,
+ - but maybe not at other times. And it's not received -}
+ kde = matchAny
+ { matchInterface = Just "org.kde.Solid.Device"
+ , matchMember = Just "setupDone"
+ }
+ {- This event may not be closely related to mounting a drive, but it's
+ - observed reliably when a drive gets mounted or unmounted. -}
+ kdefallback = matchAny
+ { matchInterface = Just "org.kde.KDirNotify"
+ , matchMember = Just "enteredDirectory"
+ }
+
+#endif
+
+pollingThread :: UrlRenderer -> Assistant ()
+pollingThread urlrenderer = go =<< liftIO currentMountPoints
+ where
+ go wasmounted = do
+ liftIO $ threadDelaySeconds (Seconds 10)
+ nowmounted <- liftIO currentMountPoints
+ handleMounts urlrenderer wasmounted nowmounted
+ go nowmounted
+
+handleMounts :: UrlRenderer -> MountPoints -> MountPoints -> Assistant ()
+handleMounts urlrenderer wasmounted nowmounted =
+ mapM_ (handleMount urlrenderer . mnt_dir) $
+ S.toList $ newMountPoints wasmounted nowmounted
+
+handleMount :: UrlRenderer -> FilePath -> Assistant ()
+handleMount urlrenderer dir = do
+ debug ["detected mount of", dir]
+ rs <- filter (Git.repoIsLocal . Remote.repo) <$> remotesUnder dir
+ mapM_ (fsckNudge urlrenderer . Just) rs
+ reconnectRemotes True rs
+
+{- Finds remotes located underneath the mount point.
+ -
+ - Updates state to include the remotes.
+ -
+ - The config of git remotes is re-read, as it may not have been available
+ - at startup time, or may have changed (it could even be a different
+ - repository at the same remote location..)
+ -}
+remotesUnder :: FilePath -> Assistant [Remote]
+remotesUnder dir = do
+ repotop <- liftAnnex $ fromRepo Git.repoPath
+ rs <- liftAnnex remoteList
+ pairs <- liftAnnex $ mapM (checkremote repotop) rs
+ let (waschanged, rs') = unzip pairs
+ when (or waschanged) $ do
+ liftAnnex $ Annex.changeState $ \s -> s { Annex.remotes = catMaybes rs' }
+ updateSyncRemotes
+ return $ mapMaybe snd $ filter fst pairs
+ where
+ checkremote repotop r = case Remote.localpath r of
+ Just p | dirContains dir (absPathFrom repotop p) ->
+ (,) <$> pure True <*> updateRemote r
+ _ -> return (False, Just r)
+
+type MountPoints = S.Set Mntent
+
+currentMountPoints :: IO MountPoints
+currentMountPoints = S.fromList <$> getMounts
+
+newMountPoints :: MountPoints -> MountPoints -> MountPoints
+newMountPoints old new = S.difference new old
diff --git a/Assistant/Threads/NetWatcher.hs b/Assistant/Threads/NetWatcher.hs
new file mode 100644
index 000000000..a7124fa01
--- /dev/null
+++ b/Assistant/Threads/NetWatcher.hs
@@ -0,0 +1,138 @@
+{- git-annex assistant network connection watcher, using dbus
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE OverloadedStrings #-}
+
+module Assistant.Threads.NetWatcher where
+
+import Assistant.Common
+import Assistant.Sync
+import Utility.ThreadScheduler
+import qualified Types.Remote as Remote
+import Assistant.DaemonStatus
+import Utility.NotificationBroadcaster
+
+#if WITH_DBUS
+import Utility.DBus
+import DBus.Client
+import DBus
+import Data.Word (Word32)
+import Assistant.NetMessager
+#else
+#warning Building without dbus support; will poll for network connection changes
+#endif
+
+netWatcherThread :: NamedThread
+#if WITH_DBUS
+netWatcherThread = thread dbusThread
+#else
+netWatcherThread = thread noop
+#endif
+ where
+ thread = namedThread "NetWatcher"
+
+{- This is a fallback for when dbus cannot be used to detect
+ - network connection changes, but it also ensures that
+ - any networked remotes that may have not been routable for a
+ - while (despite the local network staying up), are synced with
+ - periodically.
+ -
+ - Note that it does not call notifyNetMessagerRestart, because
+ - it doesn't know that the network has changed.
+ -}
+netWatcherFallbackThread :: NamedThread
+netWatcherFallbackThread = namedThread "NetWatcherFallback" $
+ runEvery (Seconds 3600) <~> handleConnection
+
+#if WITH_DBUS
+
+dbusThread :: Assistant ()
+dbusThread = do
+ handleerr <- asIO2 onerr
+ runclient <- asIO1 go
+ liftIO $ persistentClient getSystemAddress () handleerr runclient
+ where
+ go client = ifM (checkNetMonitor client)
+ ( do
+ listenNMConnections client <~> handleconn
+ listenWicdConnections client <~> handleconn
+ , do
+ liftAnnex $
+ warning "No known network monitor available through dbus; falling back to polling"
+ )
+ handleconn = do
+ debug ["detected network connection"]
+ notifyNetMessagerRestart
+ handleConnection
+ onerr e _ = do
+ liftAnnex $
+ warning $ "lost dbus connection; falling back to polling (" ++ show e ++ ")"
+ {- Wait, in hope that dbus will come back -}
+ liftIO $ threadDelaySeconds (Seconds 60)
+
+{- Examine the list of services connected to dbus, to see if there
+ - are any we can use to monitor network connections. -}
+checkNetMonitor :: Client -> Assistant Bool
+checkNetMonitor client = do
+ running <- liftIO $ filter (`elem` [networkmanager, wicd])
+ <$> listServiceNames client
+ case running of
+ [] -> return False
+ (service:_) -> do
+ debug [ "Using running DBUS service"
+ , service
+ , "to monitor network connection events."
+ ]
+ return True
+ where
+ networkmanager = "org.freedesktop.NetworkManager"
+ wicd = "org.wicd.daemon"
+
+{- Listens for new NetworkManager connections. -}
+listenNMConnections :: Client -> IO () -> IO ()
+listenNMConnections client callback =
+ listen client matcher $ \event ->
+ when (Just True == anyM activeconnection (signalBody event)) $
+ callback
+ where
+ matcher = matchAny
+ { matchInterface = Just "org.freedesktop.NetworkManager.Connection.Active"
+ , matchMember = Just "PropertiesChanged"
+ }
+ nm_connection_activated = toVariant (2 :: Word32)
+ nm_state_key = toVariant ("State" :: String)
+ activeconnection v = do
+ m <- fromVariant v
+ vstate <- lookup nm_state_key $ dictionaryItems m
+ state <- fromVariant vstate
+ return $ state == nm_connection_activated
+
+{- Listens for new Wicd connections. -}
+listenWicdConnections :: Client -> IO () -> IO ()
+listenWicdConnections client callback =
+ listen client matcher $ \event ->
+ when (any (== wicd_success) (signalBody event)) $
+ callback
+ where
+ matcher = matchAny
+ { matchInterface = Just "org.wicd.daemon"
+ , matchMember = Just "ConnectResultsSent"
+ }
+ wicd_success = toVariant ("success" :: String)
+
+#endif
+
+handleConnection :: Assistant ()
+handleConnection = do
+ liftIO . sendNotification . networkConnectedNotifier =<< getDaemonStatus
+ reconnectRemotes True =<< networkRemotes
+
+{- Network remotes to sync with. -}
+networkRemotes :: Assistant [Remote]
+networkRemotes = filter (isNothing . Remote.localpath) . syncRemotes
+ <$> getDaemonStatus
diff --git a/Assistant/Threads/PairListener.hs b/Assistant/Threads/PairListener.hs
new file mode 100644
index 000000000..cd95ab5a4
--- /dev/null
+++ b/Assistant/Threads/PairListener.hs
@@ -0,0 +1,160 @@
+{- git-annex assistant thread to listen for incoming pairing traffic
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.Threads.PairListener where
+
+import Assistant.Common
+import Assistant.Pairing
+import Assistant.Pairing.Network
+import Assistant.Pairing.MakeRemote
+import Assistant.WebApp (UrlRenderer)
+import Assistant.WebApp.Types
+import Assistant.Alert
+import Assistant.DaemonStatus
+import Utility.ThreadScheduler
+import Utility.Format
+import Git
+
+import Network.Multicast
+import Network.Socket
+import qualified Data.Text as T
+import Data.Char
+
+pairListenerThread :: UrlRenderer -> NamedThread
+pairListenerThread urlrenderer = namedThread "PairListener" $ do
+ listener <- asIO1 $ go [] []
+ liftIO $ withSocketsDo $
+ runEvery (Seconds 60) $ void $ tryIO $
+ listener =<< getsock
+ where
+ {- Note this can crash if there's no network interface,
+ - or only one like lo that doesn't support multicast. -}
+ getsock = multicastReceiver (multicastAddress $ IPv4Addr undefined) pairingPort
+
+ go reqs cache sock = liftIO (getmsg sock []) >>= \msg -> case readish msg of
+ Nothing -> go reqs cache sock
+ Just m -> do
+ debug ["received", show msg]
+ sane <- checkSane msg
+ (pip, verified) <- verificationCheck m
+ =<< (pairingInProgress <$> getDaemonStatus)
+ let wrongstage = maybe False (\p -> pairMsgStage m <= inProgressPairStage p) pip
+ let fromus = maybe False (\p -> remoteSshPubKey (pairMsgData m) == remoteSshPubKey (inProgressPairData p)) pip
+ case (wrongstage, fromus, sane, pairMsgStage m) of
+ (_, True, _, _) -> do
+ debug ["ignoring message that looped back"]
+ go reqs cache sock
+ (_, _, False, _) -> go reqs cache sock
+ -- PairReq starts a pairing process, so a
+ -- new one is always heeded, even if
+ -- some other pairing is in process.
+ (_, _, _, PairReq) -> if m `elem` reqs
+ then go reqs (invalidateCache m cache) sock
+ else do
+ pairReqReceived verified urlrenderer m
+ go (m:take 10 reqs) (invalidateCache m cache) sock
+ (True, _, _, _) -> do
+ debug
+ ["ignoring out of order message"
+ , show (pairMsgStage m)
+ , "expected"
+ , show (succ . inProgressPairStage <$> pip)
+ ]
+ go reqs cache sock
+ (_, _, _, PairAck) -> do
+ cache' <- pairAckReceived verified pip m cache
+ go reqs cache' sock
+ (_,_ , _, PairDone) -> do
+ pairDoneReceived verified pip m
+ go reqs cache sock
+
+ {- As well as verifying the message using the shared secret,
+ - check its UUID against the UUID we have stored. If
+ - they're the same, someone is sending bogus messages,
+ - which could be an attempt to brute force the shared secret. -}
+ verificationCheck _ Nothing = return (Nothing, False)
+ verificationCheck m (Just pip)
+ | not verified && sameuuid = do
+ liftAnnex $ warning
+ "detected possible pairing brute force attempt; disabled pairing"
+ stopSending pip
+ return (Nothing, False)
+ |otherwise = return (Just pip, verified && sameuuid)
+ where
+ verified = verifiedPairMsg m pip
+ sameuuid = pairUUID (inProgressPairData pip) == pairUUID (pairMsgData m)
+
+ checkSane msg
+ {- Control characters could be used in a
+ - console poisoning attack. -}
+ | any isControl (filter (/= '\n') (decode_c msg)) = do
+ liftAnnex $ warning
+ "illegal control characters in pairing message; ignoring"
+ return False
+ | otherwise = return True
+
+ {- PairReqs invalidate the cache of recently finished pairings.
+ - This is so that, if a new pairing is started with the
+ - same secret used before, a bogus PairDone is not sent. -}
+ invalidateCache msg = filter (not . verifiedPairMsg msg)
+
+ getmsg sock c = do
+ (msg, n, _) <- recvFrom sock chunksz
+ if n < chunksz
+ then return $ c ++ msg
+ else getmsg sock $ c ++ msg
+ where
+ chunksz = 1024
+
+{- Show an alert when a PairReq is seen. -}
+pairReqReceived :: Bool -> UrlRenderer -> PairMsg -> Assistant ()
+pairReqReceived True _ _ = noop -- ignore our own PairReq
+pairReqReceived False urlrenderer msg = do
+ button <- mkAlertButton True (T.pack "Respond") urlrenderer (FinishLocalPairR msg)
+ void $ addAlert $ pairRequestReceivedAlert repo button
+ where
+ repo = pairRepo msg
+
+{- When a verified PairAck is seen, a host is ready to pair with us, and has
+ - already configured our ssh key. Stop sending PairReqs, finish the pairing,
+ - and send a single PairDone. -}
+pairAckReceived :: Bool -> Maybe PairingInProgress -> PairMsg -> [PairingInProgress] -> Assistant [PairingInProgress]
+pairAckReceived True (Just pip) msg cache = do
+ stopSending pip
+ repodir <- repoPath <$> liftAnnex gitRepo
+ liftIO $ setupAuthorizedKeys msg repodir
+ finishedLocalPairing msg (inProgressSshKeyPair pip)
+ startSending pip PairDone $ multicastPairMsg
+ (Just 1) (inProgressSecret pip) (inProgressPairData pip)
+ return $ pip : take 10 cache
+{- A stale PairAck might also be seen, after we've finished pairing.
+ - Perhaps our PairDone was not received. To handle this, we keep
+ - a cache of recently finished pairings, and re-send PairDone in
+ - response to stale PairAcks for them. -}
+pairAckReceived _ _ msg cache = do
+ let pips = filter (verifiedPairMsg msg) cache
+ unless (null pips) $
+ forM_ pips $ \pip ->
+ startSending pip PairDone $ multicastPairMsg
+ (Just 1) (inProgressSecret pip) (inProgressPairData pip)
+ return cache
+
+{- If we get a verified PairDone, the host has accepted our PairAck, and
+ - has paired with us. Stop sending PairAcks, and finish pairing with them.
+ -
+ - TODO: Should third-party hosts remove their pair request alert when they
+ - see a PairDone?
+ - Complication: The user could have already clicked on the alert and be
+ - entering the secret. Would be better to start a fresh pair request in this
+ - situation.
+ -}
+pairDoneReceived :: Bool -> Maybe PairingInProgress -> PairMsg -> Assistant ()
+pairDoneReceived False _ _ = noop -- not verified
+pairDoneReceived True Nothing _ = noop -- not in progress
+pairDoneReceived True (Just pip) msg = do
+ stopSending pip
+ finishedLocalPairing msg (inProgressSshKeyPair pip)
diff --git a/Assistant/Threads/ProblemFixer.hs b/Assistant/Threads/ProblemFixer.hs
new file mode 100644
index 000000000..8095581a6
--- /dev/null
+++ b/Assistant/Threads/ProblemFixer.hs
@@ -0,0 +1,70 @@
+{- git-annex assistant thread to handle fixing problems with repositories
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.Threads.ProblemFixer (
+ problemFixerThread
+) where
+
+import Assistant.Common
+import Assistant.Types.RepoProblem
+import Assistant.RepoProblem
+import Assistant.Types.UrlRenderer
+import Assistant.Alert
+import Remote
+import qualified Types.Remote as Remote
+import qualified Git.Fsck
+import Assistant.Repair
+import qualified Git
+import Annex.UUID
+import Utility.ThreadScheduler
+
+{- Waits for problems with a repo, and tries to fsck the repo and repair
+ - the problem. -}
+problemFixerThread :: UrlRenderer -> NamedThread
+problemFixerThread urlrenderer = namedThread "ProblemFixer" $
+ go =<< getRepoProblems
+ where
+ go problems = do
+ mapM_ (handleProblem urlrenderer) problems
+ liftIO $ threadDelaySeconds (Seconds 60)
+ -- Problems may have been re-reported while they were being
+ -- fixed, so ignore those. If a new unique problem happened
+ -- 60 seconds after the last was fixed, we're unlikely
+ -- to do much good anyway.
+ go =<< filter (\p -> not (any (sameRepoProblem p) problems))
+ <$> getRepoProblems
+
+handleProblem :: UrlRenderer -> RepoProblem -> Assistant ()
+handleProblem urlrenderer repoproblem = do
+ fixed <- ifM ((==) (problemUUID repoproblem) <$> liftAnnex getUUID)
+ ( handleLocalRepoProblem urlrenderer
+ , maybe (return False) (handleRemoteProblem urlrenderer)
+ =<< liftAnnex (remoteFromUUID $ problemUUID repoproblem)
+ )
+ when fixed $
+ liftIO $ afterFix repoproblem
+
+handleRemoteProblem :: UrlRenderer -> Remote -> Assistant Bool
+handleRemoteProblem urlrenderer rmt
+ | Git.repoIsLocal r && not (Git.repoIsLocalUnknown r) =
+ ifM (liftIO $ checkAvailable True rmt)
+ ( do
+ fixedlocks <- repairStaleGitLocks r
+ fsckresults <- showFscking urlrenderer (Just rmt) $ tryNonAsync $
+ Git.Fsck.findBroken True r
+ repaired <- repairWhenNecessary urlrenderer (Remote.uuid rmt) (Just rmt) fsckresults
+ return $ fixedlocks || repaired
+ , return False
+ )
+ | otherwise = return False
+ where
+ r = Remote.repo rmt
+
+{- This is not yet used, and should probably do a fsck. -}
+handleLocalRepoProblem :: UrlRenderer -> Assistant Bool
+handleLocalRepoProblem _urlrenderer = do
+ repairStaleGitLocks =<< liftAnnex gitRepo
diff --git a/Assistant/Threads/Pusher.hs b/Assistant/Threads/Pusher.hs
new file mode 100644
index 000000000..3ec922fe4
--- /dev/null
+++ b/Assistant/Threads/Pusher.hs
@@ -0,0 +1,49 @@
+{- git-annex assistant git pushing thread
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.Threads.Pusher where
+
+import Assistant.Common
+import Assistant.Commits
+import Assistant.Pushes
+import Assistant.DaemonStatus
+import Assistant.Sync
+import Utility.ThreadScheduler
+import qualified Remote
+import qualified Types.Remote as Remote
+
+{- This thread retries pushes that failed before. -}
+pushRetryThread :: NamedThread
+pushRetryThread = namedThread "PushRetrier" $ runEvery (Seconds halfhour) <~> do
+ -- We already waited half an hour, now wait until there are failed
+ -- pushes to retry.
+ topush <- getFailedPushesBefore (fromIntegral halfhour)
+ unless (null topush) $ do
+ debug ["retrying", show (length topush), "failed pushes"]
+ void $ pushToRemotes True topush
+ where
+ halfhour = 1800
+
+{- This thread pushes git commits out to remotes soon after they are made. -}
+pushThread :: NamedThread
+pushThread = namedThread "Pusher" $ runEvery (Seconds 2) <~> do
+ -- We already waited two seconds as a simple rate limiter.
+ -- Next, wait until at least one commit has been made
+ void getCommits
+ -- Now see if now's a good time to push.
+ void $ pushToRemotes True =<< pushTargets
+
+{- We want to avoid pushing to remotes that are marked readonly.
+ -
+ - Also, avoid pushing to local remotes we can easily tell are not available,
+ - to avoid ugly messages when a removable drive is not attached.
+ -}
+pushTargets :: Assistant [Remote]
+pushTargets = liftIO . filterM (Remote.checkAvailable True)
+ =<< candidates <$> getDaemonStatus
+ where
+ candidates = filter (not . Remote.readonly) . syncGitRemotes
diff --git a/Assistant/Threads/SanityChecker.hs b/Assistant/Threads/SanityChecker.hs
new file mode 100644
index 000000000..6946e8b3a
--- /dev/null
+++ b/Assistant/Threads/SanityChecker.hs
@@ -0,0 +1,175 @@
+{- git-annex assistant sanity checker
+ -
+ - Copyright 2012, 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.Threads.SanityChecker (
+ sanityCheckerStartupThread,
+ sanityCheckerDailyThread,
+ sanityCheckerHourlyThread
+) where
+
+import Assistant.Common
+import Assistant.DaemonStatus
+import Assistant.Alert
+import Assistant.Repair
+import qualified Git.LsFiles
+import qualified Git.Command
+import qualified Git.Config
+import Utility.ThreadScheduler
+import qualified Assistant.Threads.Watcher as Watcher
+import Utility.LogFile
+import Utility.Batch
+import Utility.NotificationBroadcaster
+import Config
+import Utility.HumanTime
+import Git.Repair
+
+import Data.Time.Clock.POSIX
+import qualified Data.Set as S
+
+{- This thread runs once at startup, and most other threads wait for it
+ - to finish. (However, the webapp thread does not, to prevent the UI
+ - being nonresponsive.) -}
+sanityCheckerStartupThread :: Maybe Duration -> NamedThread
+sanityCheckerStartupThread startupdelay = namedThreadUnchecked "SanityCheckerStartup" $ do
+ {- Stale git locks can prevent commits from happening, etc. -}
+ void $ repairStaleGitLocks =<< liftAnnex gitRepo
+
+ {- A corrupt index file can prevent the assistant from working at
+ - all, so detect and repair. -}
+ ifM (not <$> liftAnnex (inRepo (checkIndex S.empty)))
+ ( do
+ notice ["corrupt index file found at startup; removing and restaging"]
+ liftAnnex $ inRepo nukeIndex
+ {- Normally the startup scan avoids re-staging files,
+ - but with the index deleted, everything needs to be
+ - restaged. -}
+ modifyDaemonStatus_ $ \s -> s { forceRestage = True }
+ , whenM (liftAnnex $ inRepo missingIndex) $ do
+ debug ["no index file; restaging"]
+ modifyDaemonStatus_ $ \s -> s { forceRestage = True }
+ )
+
+ {- If there's a startup delay, it's done here. -}
+ liftIO $ maybe noop (threadDelaySeconds . Seconds . fromIntegral . durationSeconds) startupdelay
+
+ {- Notify other threads that the startup sanity check is done. -}
+ status <- getDaemonStatus
+ liftIO $ sendNotification $ startupSanityCheckNotifier status
+
+{- This thread wakes up hourly for inxepensive frequent sanity checks. -}
+sanityCheckerHourlyThread :: NamedThread
+sanityCheckerHourlyThread = namedThread "SanityCheckerHourly" $ forever $ do
+ liftIO $ threadDelaySeconds $ Seconds oneHour
+ hourlyCheck
+
+{- This thread wakes up daily to make sure the tree is in good shape. -}
+sanityCheckerDailyThread :: NamedThread
+sanityCheckerDailyThread = namedThread "SanityCheckerDaily" $ forever $ do
+ waitForNextCheck
+
+ debug ["starting sanity check"]
+ void $ alertWhile sanityCheckAlert go
+ debug ["sanity check complete"]
+ where
+ go = do
+ modifyDaemonStatus_ $ \s -> s { sanityCheckRunning = True }
+
+ now <- liftIO getPOSIXTime -- before check started
+ r <- either showerr return =<< (tryIO . batch) <~> dailyCheck
+
+ modifyDaemonStatus_ $ \s -> s
+ { sanityCheckRunning = False
+ , lastSanityCheck = Just now
+ }
+
+ return r
+
+ showerr e = do
+ liftAnnex $ warning $ show e
+ return False
+
+{- Only run one check per day, from the time of the last check. -}
+waitForNextCheck :: Assistant ()
+waitForNextCheck = do
+ v <- lastSanityCheck <$> getDaemonStatus
+ now <- liftIO getPOSIXTime
+ liftIO $ threadDelaySeconds $ Seconds $ calcdelay now v
+ where
+ calcdelay _ Nothing = oneDay
+ calcdelay now (Just lastcheck)
+ | lastcheck < now = max oneDay $
+ oneDay - truncate (now - lastcheck)
+ | otherwise = oneDay
+
+{- It's important to stay out of the Annex monad as much as possible while
+ - running potentially expensive parts of this check, since remaining in it
+ - will block the watcher. -}
+dailyCheck :: Assistant Bool
+dailyCheck = do
+ g <- liftAnnex gitRepo
+
+ -- Find old unstaged symlinks, and add them to git.
+ (unstaged, cleanup) <- liftIO $ Git.LsFiles.notInRepo False ["."] g
+ now <- liftIO getPOSIXTime
+ forM_ unstaged $ \file -> do
+ ms <- liftIO $ catchMaybeIO $ getSymbolicLinkStatus file
+ case ms of
+ Just s | toonew (statusChangeTime s) now -> noop
+ | isSymbolicLink s -> addsymlink file ms
+ _ -> noop
+ liftIO $ void cleanup
+
+ {- Allow git-gc to run once per day. More frequent gc is avoided
+ - by default to avoid slowing things down. Only run repacks when 100x
+ - the usual number of loose objects are present; we tend
+ - to have a lot of small objects and they should not be a
+ - significant size. -}
+ when (Git.Config.getMaybe "gc.auto" g == Just "0") $
+ liftIO $ void $ Git.Command.runBool
+ [ Param "-c", Param "gc.auto=670000"
+ , Param "gc"
+ , Param "--auto"
+ ] g
+
+ return True
+ where
+ toonew timestamp now = now < (realToFrac (timestamp + slop) :: POSIXTime)
+ slop = fromIntegral tenMinutes
+ insanity msg = do
+ liftAnnex $ warning msg
+ void $ addAlert $ sanityCheckFixAlert msg
+ addsymlink file s = do
+ isdirect <- liftAnnex isDirect
+ Watcher.runHandler (Watcher.onAddSymlink isdirect) file s
+ insanity $ "found unstaged symlink: " ++ file
+
+hourlyCheck :: Assistant ()
+hourlyCheck = checkLogSize 0
+
+{- Rotate logs until log file size is < 1 mb. -}
+checkLogSize :: Int -> Assistant ()
+checkLogSize n = do
+ f <- liftAnnex $ fromRepo gitAnnexLogFile
+ logs <- liftIO $ listLogs f
+ totalsize <- liftIO $ sum <$> mapM filesize logs
+ when (totalsize > oneMegabyte) $ do
+ notice ["Rotated logs due to size:", show totalsize]
+ liftIO $ openLog f >>= redirLog
+ when (n < maxLogs + 1) $
+ checkLogSize $ n + 1
+ where
+ filesize f = fromIntegral . fileSize <$> liftIO (getFileStatus f)
+
+oneMegabyte :: Int
+oneMegabyte = 1000000
+
+oneHour :: Int
+oneHour = 60 * 60
+
+oneDay :: Int
+oneDay = 24 * oneHour
+
diff --git a/Assistant/Threads/TransferPoller.hs b/Assistant/Threads/TransferPoller.hs
new file mode 100644
index 000000000..68075cac8
--- /dev/null
+++ b/Assistant/Threads/TransferPoller.hs
@@ -0,0 +1,56 @@
+{- git-annex assistant transfer polling thread
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.Threads.TransferPoller where
+
+import Assistant.Common
+import Assistant.DaemonStatus
+import Logs.Transfer
+import Utility.NotificationBroadcaster
+import qualified Assistant.Threads.TransferWatcher as TransferWatcher
+
+import Control.Concurrent
+import qualified Data.Map as M
+
+{- This thread polls the status of ongoing transfers, determining how much
+ - of each transfer is complete. -}
+transferPollerThread :: NamedThread
+transferPollerThread = namedThread "TransferPoller" $ do
+ g <- liftAnnex gitRepo
+ tn <- liftIO . newNotificationHandle True =<<
+ transferNotifier <$> getDaemonStatus
+ forever $ do
+ liftIO $ threadDelay 500000 -- 0.5 seconds
+ ts <- currentTransfers <$> getDaemonStatus
+ if M.null ts
+ -- block until transfers running
+ then liftIO $ waitNotification tn
+ else mapM_ (poll g) $ M.toList ts
+ where
+ poll g (t, info)
+ {- Downloads are polled by checking the size of the
+ - temp file being used for the transfer. -}
+ | transferDirection t == Download = do
+ let f = gitAnnexTmpLocation (transferKey t) g
+ sz <- liftIO $ catchMaybeIO $
+ fromIntegral . fileSize <$> getFileStatus f
+ newsize t info sz
+ {- Uploads don't need to be polled for when the TransferWatcher
+ - thread can track file modifications. -}
+ | TransferWatcher.watchesTransferSize = noop
+ {- Otherwise, this code polls the upload progress
+ - by reading the transfer info file. -}
+ | otherwise = do
+ let f = transferFile t g
+ mi <- liftIO $ catchDefaultIO Nothing $
+ readTransferInfoFile Nothing f
+ maybe noop (newsize t info . bytesComplete) mi
+
+ newsize t info sz
+ | bytesComplete info /= sz && isJust sz =
+ alterTransferInfo t $ \i -> i { bytesComplete = sz }
+ | otherwise = noop
diff --git a/Assistant/Threads/TransferScanner.hs b/Assistant/Threads/TransferScanner.hs
new file mode 100644
index 000000000..ba302d6bb
--- /dev/null
+++ b/Assistant/Threads/TransferScanner.hs
@@ -0,0 +1,183 @@
+{- git-annex assistant thread to scan remotes to find needed transfers
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.Threads.TransferScanner where
+
+import Assistant.Common
+import Assistant.Types.ScanRemotes
+import Assistant.ScanRemotes
+import Assistant.TransferQueue
+import Assistant.DaemonStatus
+import Assistant.Drop
+import Assistant.Sync
+import Assistant.DeleteRemote
+import Assistant.Types.UrlRenderer
+import Logs.Transfer
+import Logs.Location
+import Logs.Group
+import Logs.Web (webUUID)
+import qualified Remote
+import qualified Types.Remote as Remote
+import Utility.ThreadScheduler
+import Utility.NotificationBroadcaster
+import Utility.Batch
+import qualified Git.LsFiles as LsFiles
+import qualified Backend
+import Annex.Content
+import Annex.Wanted
+
+import qualified Data.Set as S
+
+{- This thread waits until a remote needs to be scanned, to find transfers
+ - that need to be made, to keep data in sync.
+ -}
+transferScannerThread :: UrlRenderer -> NamedThread
+transferScannerThread urlrenderer = namedThread "TransferScanner" $ do
+ startupScan
+ go S.empty
+ where
+ go scanned = do
+ scanrunning False
+ liftIO $ threadDelaySeconds (Seconds 2)
+ (rs, infos) <- unzip <$> getScanRemote
+ scanrunning True
+ if any fullScan infos || any (`S.notMember` scanned) rs
+ then do
+ expensiveScan urlrenderer rs
+ go $ scanned `S.union` S.fromList rs
+ else do
+ mapM_ failedTransferScan rs
+ go scanned
+ scanrunning b = do
+ ds <- modifyDaemonStatus $ \s ->
+ (s { transferScanRunning = b }, s)
+ liftIO $ sendNotification $ transferNotifier ds
+
+ {- All git remotes are synced, and all available remotes
+ - are scanned in full on startup, for multiple reasons, including:
+ -
+ - * This may be the first run, and there may be remotes
+ - already in place, that need to be synced.
+ - * Changes may have been made last time we run, but remotes were
+ - not available to be synced with.
+ - * Changes may have been made to remotes while we were down.
+ - * We may have run before, and scanned a remote, but
+ - only been in a subdirectory of the git remote, and so
+ - not synced it all.
+ - * We may have run before, and had transfers queued,
+ - and then the system (or us) crashed, and that info was
+ - lost.
+ - * A remote may be in the unwanted group, and this is a chance
+ - to determine if the remote has been emptied.
+ -}
+ startupScan = do
+ reconnectRemotes True =<< syncGitRemotes <$> getDaemonStatus
+ addScanRemotes True =<< syncDataRemotes <$> getDaemonStatus
+
+{- This is a cheap scan for failed transfers involving a remote. -}
+failedTransferScan :: Remote -> Assistant ()
+failedTransferScan r = do
+ failed <- liftAnnex $ clearFailedTransfers (Remote.uuid r)
+ mapM_ retry failed
+ where
+ retry (t, info)
+ | transferDirection t == Download =
+ {- Check if the remote still has the key.
+ - If not, relies on the expensiveScan to
+ - get it queued from some other remote. -}
+ whenM (liftAnnex $ remoteHas r $ transferKey t) $
+ requeue t info
+ | otherwise =
+ {- The Transferrer checks when uploading
+ - that the remote doesn't already have the
+ - key, so it's not redundantly checked here. -}
+ requeue t info
+ requeue t info = queueTransferWhenSmall "retrying failed transfer" (associatedFile info) t r
+
+{- This is a expensive scan through the full git work tree, finding
+ - files to transfer. The scan is blocked when the transfer queue gets
+ - too large.
+ -
+ - This also finds files that are present either here or on a remote
+ - but that are not preferred content, and drops them. Searching for files
+ - to drop is done concurrently with the scan for transfers.
+ -
+ - TODO: It would be better to first drop as much as we can, before
+ - transferring much, to minimise disk use.
+ -
+ - During the scan, we'll also check if any unwanted repositories are empty,
+ - and can be removed. While unrelated, this is a cheap place to do it,
+ - since we need to look at the locations of all keys anyway.
+ -}
+expensiveScan :: UrlRenderer -> [Remote] -> Assistant ()
+expensiveScan urlrenderer rs = unless onlyweb $ batch <~> do
+ debug ["starting scan of", show visiblers]
+
+ let us = map Remote.uuid rs
+
+ mapM_ (liftAnnex . clearFailedTransfers) us
+
+ unwantedrs <- liftAnnex $ S.fromList
+ <$> filterM inUnwantedGroup us
+
+ g <- liftAnnex gitRepo
+ (files, cleanup) <- liftIO $ LsFiles.inRepo [] g
+ removablers <- scan unwantedrs files
+ void $ liftIO cleanup
+
+ debug ["finished scan of", show visiblers]
+
+ remove <- asIO1 $ removableRemote urlrenderer
+ liftIO $ mapM_ (void . tryNonAsync . remove) $ S.toList removablers
+ where
+ onlyweb = all (== webUUID) $ map Remote.uuid rs
+ visiblers = let rs' = filter (not . Remote.readonly) rs
+ in if null rs' then rs else rs'
+
+ scan unwanted [] = return unwanted
+ scan unwanted (f:fs) = do
+ (unwanted', ts) <- maybe
+ (return (unwanted, []))
+ (findtransfers f unwanted)
+ =<< liftAnnex (Backend.lookupFile f)
+ mapM_ (enqueue f) ts
+ scan unwanted' fs
+
+ enqueue f (r, t) =
+ queueTransferWhenSmall "expensive scan found missing object"
+ (Just f) t r
+ findtransfers f unwanted (key, _) = do
+ {- The syncable remotes may have changed since this
+ - scan began. -}
+ syncrs <- syncDataRemotes <$> getDaemonStatus
+ locs <- liftAnnex $ loggedLocations key
+ present <- liftAnnex $ inAnnex key
+ handleDropsFrom locs syncrs
+ "expensive scan found too many copies of object"
+ present key (Just f) Nothing
+ liftAnnex $ do
+ let slocs = S.fromList locs
+ let use a = return $ mapMaybe (a key slocs) syncrs
+ ts <- if present
+ then filterM (wantSend True (Just f) . Remote.uuid . fst)
+ =<< use (genTransfer Upload False)
+ else ifM (wantGet True $ Just f)
+ ( use (genTransfer Download True) , return [] )
+ let unwanted' = S.difference unwanted slocs
+ return (unwanted', ts)
+
+genTransfer :: Direction -> Bool -> Key -> S.Set UUID -> Remote -> Maybe (Remote, Transfer)
+genTransfer direction want key slocs r
+ | direction == Upload && Remote.readonly r = Nothing
+ | S.member (Remote.uuid r) slocs == want = Just
+ (r, Transfer direction (Remote.uuid r) key)
+ | otherwise = Nothing
+
+remoteHas :: Remote -> Key -> Annex Bool
+remoteHas r key = elem
+ <$> pure (Remote.uuid r)
+ <*> loggedLocations key
diff --git a/Assistant/Threads/TransferWatcher.hs b/Assistant/Threads/TransferWatcher.hs
new file mode 100644
index 000000000..cd7282865
--- /dev/null
+++ b/Assistant/Threads/TransferWatcher.hs
@@ -0,0 +1,104 @@
+{- git-annex assistant transfer watching thread
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.Threads.TransferWatcher where
+
+import Assistant.Common
+import Assistant.DaemonStatus
+import Assistant.TransferSlots
+import Logs.Transfer
+import Utility.DirWatcher
+import Utility.DirWatcher.Types
+import qualified Remote
+
+import Control.Concurrent
+import qualified Data.Map as M
+
+{- This thread watches for changes to the gitAnnexTransferDir,
+ - and updates the DaemonStatus's map of ongoing transfers. -}
+transferWatcherThread :: NamedThread
+transferWatcherThread = namedThread "TransferWatcher" $ do
+ dir <- liftAnnex $ gitAnnexTransferDir <$> gitRepo
+ liftIO $ createDirectoryIfMissing True dir
+ let hook a = Just <$> asIO2 (runHandler a)
+ addhook <- hook onAdd
+ delhook <- hook onDel
+ modifyhook <- hook onModify
+ errhook <- hook onErr
+ let hooks = mkWatchHooks
+ { addHook = addhook
+ , delHook = delhook
+ , modifyHook = modifyhook
+ , errHook = errhook
+ }
+ void $ liftIO $ watchDir dir (const False) hooks id
+ debug ["watching for transfers"]
+
+type Handler = FilePath -> Assistant ()
+
+{- Runs an action handler.
+ -
+ - Exceptions are ignored, otherwise a whole thread could be crashed.
+ -}
+runHandler :: Handler -> FilePath -> Maybe FileStatus -> Assistant ()
+runHandler handler file _filestatus =
+ either (liftIO . print) (const noop) =<< tryIO <~> handler file
+
+{- Called when there's an error with inotify. -}
+onErr :: Handler
+onErr = error
+
+{- Called when a new transfer information file is written. -}
+onAdd :: Handler
+onAdd file = case parseTransferFile file of
+ Nothing -> noop
+ Just t -> go t =<< liftAnnex (checkTransfer t)
+ where
+ go _ Nothing = noop -- transfer already finished
+ go t (Just info) = do
+ debug [ "transfer starting:", describeTransfer t info ]
+ r <- liftAnnex $ Remote.remoteFromUUID $ transferUUID t
+ updateTransferInfo t info { transferRemote = r }
+
+{- Called when a transfer information file is updated.
+ -
+ - The only thing that should change in the transfer info is the
+ - bytesComplete, so that's the only thing updated in the DaemonStatus. -}
+onModify :: Handler
+onModify file = case parseTransferFile file of
+ Nothing -> noop
+ Just t -> go t =<< liftIO (readTransferInfoFile Nothing file)
+ where
+ go _ Nothing = noop
+ go t (Just newinfo) = alterTransferInfo t $
+ \i -> i { bytesComplete = bytesComplete newinfo }
+
+{- This thread can only watch transfer sizes when the DirWatcher supports
+ - tracking modificatons to files. -}
+watchesTransferSize :: Bool
+watchesTransferSize = modifyTracked
+
+{- Called when a transfer information file is removed. -}
+onDel :: Handler
+onDel file = case parseTransferFile file of
+ Nothing -> noop
+ Just t -> do
+ debug [ "transfer finishing:", show t]
+ minfo <- removeTransfer t
+
+ -- Run transfer hook.
+ m <- transferHook <$> getDaemonStatus
+ maybe noop (\hook -> void $ liftIO $ forkIO $ hook t)
+ (M.lookup (transferKey t) m)
+
+ finished <- asIO2 finishedTransfer
+ void $ liftIO $ forkIO $ do
+ {- XXX race workaround delay. The location
+ - log needs to be updated before finishedTransfer
+ - runs. -}
+ threadDelay 10000000 -- 10 seconds
+ finished t minfo
diff --git a/Assistant/Threads/Transferrer.hs b/Assistant/Threads/Transferrer.hs
new file mode 100644
index 000000000..0bc419e15
--- /dev/null
+++ b/Assistant/Threads/Transferrer.hs
@@ -0,0 +1,25 @@
+{- git-annex assistant data transferrer thread
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.Threads.Transferrer where
+
+import Assistant.Common
+import Assistant.TransferQueue
+import Assistant.TransferSlots
+import Logs.Transfer
+import Config.Files
+
+{- Dispatches transfers from the queue. -}
+transfererThread :: NamedThread
+transfererThread = namedThread "Transferrer" $ do
+ program <- liftIO readProgramFile
+ forever $ inTransferSlot program $
+ maybe (return Nothing) (uncurry genTransfer)
+ =<< getNextTransfer notrunning
+ where
+ {- Skip transfers that are already running. -}
+ notrunning = isNothing . startedTime
diff --git a/Assistant/Threads/UpgradeWatcher.hs b/Assistant/Threads/UpgradeWatcher.hs
new file mode 100644
index 000000000..80f2040a0
--- /dev/null
+++ b/Assistant/Threads/UpgradeWatcher.hs
@@ -0,0 +1,109 @@
+{- git-annex assistant thread to detect when git-annex is upgraded
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Assistant.Threads.UpgradeWatcher (
+ upgradeWatcherThread
+) where
+
+import Assistant.Common
+import Assistant.Upgrade
+import Utility.DirWatcher
+import Utility.DirWatcher.Types
+import Utility.ThreadScheduler
+import Assistant.Types.UrlRenderer
+import Assistant.Alert
+import Assistant.DaemonStatus
+#ifdef WITH_WEBAPP
+import Assistant.WebApp.Types
+import qualified Build.SysConfig
+#endif
+
+import Control.Concurrent.MVar
+import qualified Data.Text as T
+
+data WatcherState = InStartupScan | Started | Upgrading
+ deriving (Eq)
+
+upgradeWatcherThread :: UrlRenderer -> NamedThread
+upgradeWatcherThread urlrenderer = namedThread "UpgradeWatcher" $ do
+ whenM (liftIO checkSuccessfulUpgrade) $
+ showSuccessfulUpgrade urlrenderer
+ go =<< liftIO upgradeFlagFile
+ where
+ go Nothing = debug [ "cannot determine program path" ]
+ go (Just flagfile) = do
+ mvar <- liftIO $ newMVar InStartupScan
+ changed <- Just <$> asIO2 (changedFile urlrenderer mvar flagfile)
+ let hooks = mkWatchHooks
+ { addHook = changed
+ , delHook = changed
+ , addSymlinkHook = changed
+ , modifyHook = changed
+ , delDirHook = changed
+ }
+ let dir = parentDir flagfile
+ let depth = length (splitPath dir) + 1
+ let nosubdirs f = length (splitPath f) == depth
+ void $ liftIO $ watchDir dir nosubdirs hooks (startup mvar)
+ -- Ignore bogus events generated during the startup scan.
+ startup mvar scanner = do
+ r <- scanner
+ void $ swapMVar mvar Started
+ return r
+
+changedFile :: UrlRenderer -> MVar WatcherState -> FilePath -> FilePath -> Maybe FileStatus -> Assistant ()
+changedFile urlrenderer mvar flagfile file _status
+ | flagfile /= file = noop
+ | otherwise = do
+ state <- liftIO $ readMVar mvar
+ when (state == Started) $ do
+ setstate Upgrading
+ ifM (liftIO upgradeSanityCheck)
+ ( handleUpgrade urlrenderer
+ , do
+ debug ["new version failed sanity check; not using"]
+ setstate Started
+ )
+ where
+ setstate = void . liftIO . swapMVar mvar
+
+handleUpgrade :: UrlRenderer -> Assistant ()
+handleUpgrade urlrenderer = do
+ -- Wait 2 minutes for any final upgrade changes to settle.
+ -- (For example, other associated files may be being put into
+ -- place.) Not needed when using a distribution bundle, because
+ -- in that case git-annex handles the upgrade in a non-racy way.
+ liftIO $ unlessM usingDistribution $
+ threadDelaySeconds (Seconds 120)
+ ifM autoUpgradeEnabled
+ ( do
+ debug ["starting automatic upgrade"]
+ unattendedUpgrade
+#ifdef WITH_WEBAPP
+ , do
+ button <- mkAlertButton True (T.pack "Finish Upgrade") urlrenderer ConfigFinishUpgradeR
+ void $ addAlert $ upgradeReadyAlert button
+#else
+ , noop
+#endif
+ )
+
+showSuccessfulUpgrade :: UrlRenderer -> Assistant ()
+showSuccessfulUpgrade urlrenderer = do
+#ifdef WITH_WEBAPP
+ button <- ifM autoUpgradeEnabled
+ ( pure Nothing
+ , Just <$> mkAlertButton True
+ (T.pack "Enable Automatic Upgrades")
+ urlrenderer ConfigEnableAutomaticUpgradeR
+ )
+ void $ addAlert $ upgradeFinishedAlert button Build.SysConfig.packageversion
+#else
+ noop
+#endif
diff --git a/Assistant/Threads/Upgrader.hs b/Assistant/Threads/Upgrader.hs
new file mode 100644
index 000000000..f0c47e844
--- /dev/null
+++ b/Assistant/Threads/Upgrader.hs
@@ -0,0 +1,101 @@
+{- git-annex assistant thread to detect when upgrade is available
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Assistant.Threads.Upgrader (
+ upgraderThread
+) where
+
+import Assistant.Common
+import Assistant.Upgrade
+
+import Assistant.Types.UrlRenderer
+import Assistant.DaemonStatus
+import Assistant.Alert
+import Utility.NotificationBroadcaster
+import Utility.Tmp
+import qualified Annex
+import qualified Build.SysConfig
+import qualified Utility.Url as Url
+import qualified Annex.Url as Url
+import qualified Git.Version
+import Types.Distribution
+#ifdef WITH_WEBAPP
+import Assistant.WebApp.Types
+#endif
+
+import Data.Time.Clock
+import qualified Data.Text as T
+
+upgraderThread :: UrlRenderer -> NamedThread
+upgraderThread urlrenderer = namedThread "Upgrader" $
+ when (isJust Build.SysConfig.upgradelocation) $ do
+ {- Check for upgrade on startup, unless it was just
+ - upgraded. -}
+ unlessM (liftIO checkSuccessfulUpgrade) $
+ checkUpgrade urlrenderer
+ h <- liftIO . newNotificationHandle False . networkConnectedNotifier =<< getDaemonStatus
+ go h =<< liftIO getCurrentTime
+ where
+ {- Wait for a network connection event. Then see if it's been
+ - half a day since the last upgrade check. If so, proceed with
+ - check. -}
+ go h lastchecked = do
+ liftIO $ waitNotification h
+ autoupgrade <- liftAnnex $ annexAutoUpgrade <$> Annex.getGitConfig
+ if autoupgrade == NoAutoUpgrade
+ then go h lastchecked
+ else do
+ now <- liftIO getCurrentTime
+ if diffUTCTime now lastchecked > halfday
+ then do
+ checkUpgrade urlrenderer
+ go h =<< liftIO getCurrentTime
+ else go h lastchecked
+ halfday = 12 * 60 * 60
+
+checkUpgrade :: UrlRenderer -> Assistant ()
+checkUpgrade urlrenderer = do
+ debug [ "Checking if an upgrade is available." ]
+ go =<< getDistributionInfo
+ where
+ go Nothing = debug [ "Failed to check if upgrade is available." ]
+ go (Just d) = do
+ let installed = Git.Version.normalize Build.SysConfig.packageversion
+ let avail = Git.Version.normalize $ distributionVersion d
+ let old = Git.Version.normalize <$> distributionUrgentUpgrade d
+ if Just installed <= old
+ then canUpgrade High urlrenderer d
+ else if installed < avail
+ then canUpgrade Low urlrenderer d
+ else debug [ "No new version found." ]
+
+canUpgrade :: AlertPriority -> UrlRenderer -> GitAnnexDistribution -> Assistant ()
+canUpgrade urgency urlrenderer d = ifM autoUpgradeEnabled
+ ( startDistributionDownload d
+ , do
+#ifdef WITH_WEBAPP
+ button <- mkAlertButton True (T.pack "Upgrade") urlrenderer (ConfigStartUpgradeR d)
+ void $ addAlert (canUpgradeAlert urgency (distributionVersion d) button)
+#else
+ noop
+#endif
+ )
+
+getDistributionInfo :: Assistant (Maybe GitAnnexDistribution)
+getDistributionInfo = do
+ ua <- liftAnnex Url.getUserAgent
+ liftIO $ withTmpFile "git-annex.tmp" $ \tmpfile h -> do
+ hClose h
+ ifM (Url.downloadQuiet distributionInfoUrl [] [] tmpfile ua)
+ ( readish <$> readFileStrict tmpfile
+ , return Nothing
+ )
+
+distributionInfoUrl :: String
+distributionInfoUrl = fromJust Build.SysConfig.upgradelocation ++ ".info"
diff --git a/Assistant/Threads/Watcher.hs b/Assistant/Threads/Watcher.hs
new file mode 100644
index 000000000..6a56eadbb
--- /dev/null
+++ b/Assistant/Threads/Watcher.hs
@@ -0,0 +1,355 @@
+{- git-annex assistant tree watcher
+ -
+ - Copyright 2012-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE DeriveDataTypeable, CPP #-}
+
+module Assistant.Threads.Watcher (
+ watchThread,
+ WatcherControl(..),
+ checkCanWatch,
+ needLsof,
+ onAddSymlink,
+ runHandler,
+) where
+
+import Assistant.Common
+import Assistant.DaemonStatus
+import Assistant.Changes
+import Assistant.Types.Changes
+import Assistant.Alert
+import Utility.DirWatcher
+import Utility.DirWatcher.Types
+import qualified Utility.Lsof as Lsof
+import qualified Annex
+import qualified Annex.Queue
+import qualified Git
+import qualified Git.UpdateIndex
+import qualified Git.LsFiles as LsFiles
+import qualified Backend
+import Annex.Direct
+import Annex.Content.Direct
+import Annex.CatFile
+import Annex.CheckIgnore
+import Annex.Link
+import Annex.FileMatcher
+import Annex.ReplaceFile
+import Git.Types
+import Config
+import Utility.ThreadScheduler
+
+import Data.Bits.Utils
+import Data.Typeable
+import qualified Data.ByteString.Lazy as L
+import qualified Control.Exception as E
+import Data.Time.Clock
+
+checkCanWatch :: Annex ()
+checkCanWatch
+ | canWatch = do
+ liftIO Lsof.setup
+ unlessM (liftIO (inPath "lsof") <||> Annex.getState Annex.force)
+ needLsof
+ | otherwise = error "watch mode is not available on this system"
+
+needLsof :: Annex ()
+needLsof = error $ unlines
+ [ "The lsof command is needed for watch mode to be safe, and is not in PATH."
+ , "To override lsof checks to ensure that files are not open for writing"
+ , "when added to the annex, you can use --force"
+ , "Be warned: This can corrupt data in the annex, and make fsck complain."
+ ]
+
+{- A special exception that can be thrown to pause or resume the watcher. -}
+data WatcherControl = PauseWatcher | ResumeWatcher
+ deriving (Show, Eq, Typeable)
+
+instance E.Exception WatcherControl
+
+watchThread :: NamedThread
+watchThread = namedThread "Watcher" $
+ ifM (liftAnnex $ annexAutoCommit <$> Annex.getGitConfig)
+ ( runWatcher
+ , waitFor ResumeWatcher runWatcher
+ )
+
+runWatcher :: Assistant ()
+runWatcher = do
+ startup <- asIO1 startupScan
+ matcher <- liftAnnex largeFilesMatcher
+ direct <- liftAnnex isDirect
+ symlinkssupported <- liftAnnex $ coreSymlinks <$> Annex.getGitConfig
+ addhook <- hook $ if direct
+ then onAddDirect symlinkssupported matcher
+ else onAdd matcher
+ delhook <- hook onDel
+ addsymlinkhook <- hook $ onAddSymlink direct
+ deldirhook <- hook onDelDir
+ errhook <- hook onErr
+ let hooks = mkWatchHooks
+ { addHook = addhook
+ , delHook = delhook
+ , addSymlinkHook = addsymlinkhook
+ , delDirHook = deldirhook
+ , errHook = errhook
+ }
+ handle <- liftIO $ watchDir "." ignored hooks startup
+ debug [ "watching", "."]
+
+ {- Let the DirWatcher thread run until signalled to pause it,
+ - then wait for a resume signal, and restart. -}
+ waitFor PauseWatcher $ do
+ liftIO $ stopWatchDir handle
+ waitFor ResumeWatcher runWatcher
+ where
+ hook a = Just <$> asIO2 (runHandler a)
+
+waitFor :: WatcherControl -> Assistant () -> Assistant ()
+waitFor sig next = do
+ r <- liftIO (E.try pause :: IO (Either E.SomeException ()))
+ case r of
+ Left e -> case E.fromException e of
+ Just s
+ | s == sig -> next
+ _ -> noop
+ _ -> noop
+ where
+ pause = runEvery (Seconds 86400) noop
+
+{- Initial scartup scan. The action should return once the scan is complete. -}
+startupScan :: IO a -> Assistant a
+startupScan scanner = do
+ liftAnnex $ showAction "scanning"
+ alertWhile' startupScanAlert $ do
+ r <- liftIO scanner
+
+ -- Notice any files that were deleted before
+ -- watching was started.
+ top <- liftAnnex $ fromRepo Git.repoPath
+ (fs, cleanup) <- liftAnnex $ inRepo $ LsFiles.deleted [top]
+ forM_ fs $ \f -> do
+ liftAnnex $ onDel' f
+ maybe noop recordChange =<< madeChange f RmChange
+ void $ liftIO cleanup
+
+ liftAnnex $ showAction "started"
+ liftIO $ putStrLn ""
+
+ modifyDaemonStatus_ $ \s -> s { scanComplete = True }
+
+ return (True, r)
+
+{- Hardcoded ignores, passed to the DirWatcher so it can avoid looking
+ - at the entire .git directory. Does not include .gitignores. -}
+ignored :: FilePath -> Bool
+ignored = ig . takeFileName
+ where
+ ig ".git" = True
+ ig ".gitignore" = True
+ ig ".gitattributes" = True
+#ifdef darwin_HOST_OS
+ ig ".DS_Store" = True
+#endif
+ ig _ = False
+
+unlessIgnored :: FilePath -> Assistant (Maybe Change) -> Assistant (Maybe Change)
+unlessIgnored file a = ifM (liftAnnex $ checkIgnored file)
+ ( noChange
+ , a
+ )
+
+type Handler = FilePath -> Maybe FileStatus -> Assistant (Maybe Change)
+
+{- Runs an action handler, and if there was a change, adds it to the ChangeChan.
+ -
+ - Exceptions are ignored, otherwise a whole watcher thread could be crashed.
+ -}
+runHandler :: Handler -> FilePath -> Maybe FileStatus -> Assistant ()
+runHandler handler file filestatus = void $ do
+ r <- tryIO <~> handler (normalize file) filestatus
+ case r of
+ Left e -> liftIO $ print e
+ Right Nothing -> noop
+ Right (Just change) -> do
+ -- Just in case the commit thread is not
+ -- flushing the queue fast enough.
+ liftAnnex Annex.Queue.flushWhenFull
+ recordChange change
+ where
+ normalize f
+ | "./" `isPrefixOf` file = drop 2 f
+ | otherwise = f
+
+{- Small files are added to git as-is, while large ones go into the annex. -}
+add :: FileMatcher -> FilePath -> Assistant (Maybe Change)
+add bigfilematcher file = ifM (liftAnnex $ checkFileMatcher bigfilematcher file)
+ ( pendingAddChange file
+ , do
+ liftAnnex $ Annex.Queue.addCommand "add"
+ [Params "--force --"] [file]
+ madeChange file AddFileChange
+ )
+
+onAdd :: FileMatcher -> Handler
+onAdd matcher file filestatus
+ | maybe False isRegularFile filestatus =
+ unlessIgnored file $
+ add matcher file
+ | otherwise = noChange
+
+shouldRestage :: DaemonStatus -> Bool
+shouldRestage ds = scanComplete ds || forceRestage ds
+
+{- In direct mode, add events are received for both new files, and
+ - modified existing files.
+ -}
+onAddDirect :: Bool -> FileMatcher -> Handler
+onAddDirect symlinkssupported matcher file fs = do
+ v <- liftAnnex $ catKeyFile file
+ case (v, fs) of
+ (Just key, Just filestatus) ->
+ ifM (liftAnnex $ sameFileStatus key filestatus)
+ {- It's possible to get an add event for
+ - an existing file that is not
+ - really modified, but it might have
+ - just been deleted and been put back,
+ - so it symlink is restaged to make sure. -}
+ ( ifM (shouldRestage <$> getDaemonStatus)
+ ( do
+ link <- liftAnnex $ inRepo $ gitAnnexLink file key
+ addLink file link (Just key)
+ , noChange
+ )
+ , guardSymlinkStandin (Just key) $ do
+ debug ["changed direct", file]
+ liftAnnex $ changedDirect key file
+ add matcher file
+ )
+ _ -> unlessIgnored file $
+ guardSymlinkStandin Nothing $ do
+ debug ["add direct", file]
+ add matcher file
+ where
+ {- On a filesystem without symlinks, we'll get changes for regular
+ - files that git uses to stand-in for symlinks. Detect when
+ - this happens, and stage the symlink, rather than annexing the
+ - file. -}
+ guardSymlinkStandin mk a
+ | symlinkssupported = a
+ | otherwise = do
+ linktarget <- liftAnnex $ getAnnexLinkTarget file
+ case linktarget of
+ Nothing -> a
+ Just lt -> do
+ case fileKey $ takeFileName lt of
+ Nothing -> noop
+ Just key -> void $ liftAnnex $
+ addAssociatedFile key file
+ onAddSymlink' linktarget mk True file fs
+
+{- A symlink might be an arbitrary symlink, which is just added.
+ - Or, if it is a git-annex symlink, ensure it points to the content
+ - before adding it.
+ -}
+onAddSymlink :: Bool -> Handler
+onAddSymlink isdirect file filestatus = unlessIgnored file $ do
+ linktarget <- liftIO (catchMaybeIO $ readSymbolicLink file)
+ kv <- liftAnnex (Backend.lookupFile file)
+ onAddSymlink' linktarget (fmap fst kv) isdirect file filestatus
+
+onAddSymlink' :: Maybe String -> Maybe Key -> Bool -> Handler
+onAddSymlink' linktarget mk isdirect file filestatus = go mk
+ where
+ go (Just key) = do
+ when isdirect $
+ liftAnnex $ void $ addAssociatedFile key file
+ link <- liftAnnex $ inRepo $ gitAnnexLink file key
+ if linktarget == Just link
+ then ensurestaged (Just link) =<< getDaemonStatus
+ else do
+ unless isdirect $
+ liftAnnex $ replaceFile file $
+ makeAnnexLink link
+ addLink file link (Just key)
+ -- other symlink, not git-annex
+ go Nothing = ensurestaged linktarget =<< getDaemonStatus
+
+ {- This is often called on symlinks that are already
+ - staged correctly. A symlink may have been deleted
+ - and being re-added, or added when the watcher was
+ - not running. So they're normally restaged to make sure.
+ -
+ - As an optimisation, during the startup scan, avoid
+ - restaging everything. Only links that were created since
+ - the last time the daemon was running are staged.
+ - (If the daemon has never ran before, avoid staging
+ - links too.)
+ -}
+ ensurestaged (Just link) daemonstatus
+ | shouldRestage daemonstatus = addLink file link mk
+ | otherwise = case filestatus of
+ Just s
+ | not (afterLastDaemonRun (statusChangeTime s) daemonstatus) -> noChange
+ _ -> addLink file link mk
+ ensurestaged Nothing _ = noChange
+
+{- For speed, tries to reuse the existing blob for symlink target. -}
+addLink :: FilePath -> FilePath -> Maybe Key -> Assistant (Maybe Change)
+addLink file link mk = do
+ debug ["add symlink", file]
+ liftAnnex $ do
+ v <- catObjectDetails $ Ref $ ':':file
+ case v of
+ Just (currlink, sha, _type)
+ | s2w8 link == L.unpack currlink ->
+ stageSymlink file sha
+ _ -> stageSymlink file =<< hashSymlink link
+ madeChange file $ LinkChange mk
+
+onDel :: Handler
+onDel file _ = do
+ debug ["file deleted", file]
+ liftAnnex $ onDel' file
+ madeChange file RmChange
+
+onDel' :: FilePath -> Annex ()
+onDel' file = do
+ whenM isDirect $ do
+ mkey <- catKeyFile file
+ case mkey of
+ Nothing -> noop
+ Just key -> void $ removeAssociatedFile key file
+ Annex.Queue.addUpdateIndex =<<
+ inRepo (Git.UpdateIndex.unstageFile file)
+
+{- A directory has been deleted, or moved, so tell git to remove anything
+ - that was inside it from its cache. Since it could reappear at any time,
+ - use --cached to only delete it from the index.
+ -
+ - This queues up a lot of RmChanges, which assists the Committer in
+ - pairing up renamed files when the directory was renamed. -}
+onDelDir :: Handler
+onDelDir dir _ = do
+ debug ["directory deleted", dir]
+ (fs, clean) <- liftAnnex $ inRepo $ LsFiles.deleted [dir]
+
+ liftAnnex $ mapM_ onDel' fs
+
+ -- Get the events queued up as fast as possible, so the
+ -- committer sees them all in one block.
+ now <- liftIO getCurrentTime
+ recordChanges $ map (\f -> Change now f RmChange) fs
+
+ void $ liftIO clean
+ liftAnnex Annex.Queue.flushWhenFull
+ noChange
+
+{- Called when there's an error with inotify or kqueue. -}
+onErr :: Handler
+onErr msg _ = do
+ liftAnnex $ warning msg
+ void $ addAlert $ warningAlert "watcher" msg
+ noChange
diff --git a/Assistant/Threads/WebApp.hs b/Assistant/Threads/WebApp.hs
new file mode 100644
index 000000000..2ad61168e
--- /dev/null
+++ b/Assistant/Threads/WebApp.hs
@@ -0,0 +1,109 @@
+{- git-annex assistant webapp thread
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE TemplateHaskell, MultiParamTypeClasses #-}
+{-# LANGUAGE CPP #-}
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+
+module Assistant.Threads.WebApp where
+
+import Assistant.Common
+import Assistant.WebApp
+import Assistant.WebApp.Types
+import Assistant.WebApp.DashBoard
+import Assistant.WebApp.SideBar
+import Assistant.WebApp.Notifications
+import Assistant.WebApp.RepoList
+import Assistant.WebApp.Configurators
+import Assistant.WebApp.Configurators.Local
+import Assistant.WebApp.Configurators.Ssh
+import Assistant.WebApp.Configurators.Pairing
+import Assistant.WebApp.Configurators.AWS
+import Assistant.WebApp.Configurators.IA
+import Assistant.WebApp.Configurators.WebDAV
+import Assistant.WebApp.Configurators.XMPP
+import Assistant.WebApp.Configurators.Preferences
+import Assistant.WebApp.Configurators.Edit
+import Assistant.WebApp.Configurators.Delete
+import Assistant.WebApp.Configurators.Fsck
+import Assistant.WebApp.Configurators.Upgrade
+import Assistant.WebApp.Documentation
+import Assistant.WebApp.Control
+import Assistant.WebApp.OtherRepos
+import Assistant.WebApp.Repair
+import Assistant.Types.ThreadedMonad
+import Utility.WebApp
+import Utility.Tmp
+import Utility.FileMode
+import Git
+
+import Yesod
+import Network.Socket (SockAddr, HostName)
+import Data.Text (pack, unpack)
+
+mkYesodDispatch "WebApp" $(parseRoutesFile "Assistant/WebApp/routes")
+
+type Url = String
+
+webAppThread
+ :: AssistantData
+ -> UrlRenderer
+ -> Bool
+ -> Maybe String
+ -> Maybe HostName
+ -> Maybe (IO Url)
+ -> Maybe (Url -> FilePath -> IO ())
+ -> NamedThread
+webAppThread assistantdata urlrenderer noannex cannotrun listenhost postfirstrun onstartup = thread $ liftIO $ do
+#ifdef __ANDROID__
+ when (isJust listenhost) $
+ -- See Utility.WebApp
+ error "Sorry, --listen is not currently supported on Android"
+#endif
+ webapp <- WebApp
+ <$> pure assistantdata
+ <*> (pack <$> genRandomToken)
+ <*> getreldir
+ <*> pure staticRoutes
+ <*> pure postfirstrun
+ <*> pure cannotrun
+ <*> pure noannex
+ <*> pure listenhost
+ setUrlRenderer urlrenderer $ yesodRender webapp (pack "")
+ app <- toWaiAppPlain webapp
+ app' <- ifM debugEnabled
+ ( return $ httpDebugLogger app
+ , return app
+ )
+ runWebApp listenhost app' $ \addr -> if noannex
+ then withTmpFile "webapp.html" $ \tmpfile _ ->
+ go addr webapp tmpfile Nothing
+ else do
+ let st = threadState assistantdata
+ htmlshim <- runThreadState st $ fromRepo gitAnnexHtmlShim
+ urlfile <- runThreadState st $ fromRepo gitAnnexUrlFile
+ go addr webapp htmlshim (Just urlfile)
+ where
+ -- The webapp thread does not wait for the startupSanityCheckThread
+ -- to finish, so that the user interface remains responsive while
+ -- that's going on.
+ thread = namedThreadUnchecked "WebApp"
+ getreldir
+ | noannex = return Nothing
+ | otherwise = Just <$>
+ (relHome =<< absPath
+ =<< runThreadState (threadState assistantdata) (fromRepo repoPath))
+ go addr webapp htmlshim urlfile = do
+ let url = myUrl webapp addr
+ maybe noop (`writeFileProtected` url) urlfile
+ writeHtmlShim "Starting webapp..." url htmlshim
+ maybe noop (\a -> a url htmlshim) onstartup
+
+myUrl :: WebApp -> SockAddr -> Url
+myUrl webapp addr = unpack $ yesodRender webapp urlbase DashboardR []
+ where
+ urlbase = pack $ "http://" ++ show addr
diff --git a/Assistant/Threads/XMPPClient.hs b/Assistant/Threads/XMPPClient.hs
new file mode 100644
index 000000000..8eb469939
--- /dev/null
+++ b/Assistant/Threads/XMPPClient.hs
@@ -0,0 +1,368 @@
+{- git-annex XMPP client
+ -
+ - Copyright 2012, 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.Threads.XMPPClient where
+
+import Assistant.Common
+import Assistant.XMPP
+import Assistant.XMPP.Client
+import Assistant.NetMessager
+import Assistant.Types.NetMessager
+import Assistant.Types.Buddies
+import Assistant.XMPP.Buddies
+import Assistant.Sync
+import Assistant.DaemonStatus
+import qualified Remote
+import Utility.ThreadScheduler
+import Assistant.WebApp (UrlRenderer)
+import Assistant.WebApp.Types hiding (liftAssistant)
+import Assistant.Alert
+import Assistant.Pairing
+import Assistant.XMPP.Git
+import Annex.UUID
+import Logs.UUID
+
+import Network.Protocol.XMPP
+import Control.Concurrent
+import Control.Concurrent.STM.TMVar
+import Control.Concurrent.STM (atomically)
+import qualified Data.Text as T
+import qualified Data.Set as S
+import qualified Data.Map as M
+import qualified Git.Branch
+import Data.Time.Clock
+import Control.Concurrent.Async
+
+xmppClientThread :: UrlRenderer -> NamedThread
+xmppClientThread urlrenderer = namedThread "XMPPClient" $
+ restartableClient . xmppClient urlrenderer =<< getAssistant id
+
+{- Runs the client, handing restart events. -}
+restartableClient :: (XMPPCreds -> IO ()) -> Assistant ()
+restartableClient a = forever $ go =<< liftAnnex getXMPPCreds
+ where
+ go Nothing = waitNetMessagerRestart
+ go (Just creds) = do
+ tid <- liftIO $ forkIO $ a creds
+ waitNetMessagerRestart
+ liftIO $ killThread tid
+
+xmppClient :: UrlRenderer -> AssistantData -> XMPPCreds -> IO ()
+xmppClient urlrenderer d creds =
+ retry (runclient creds) =<< getCurrentTime
+ where
+ liftAssistant = runAssistant d
+ inAssistant = liftIO . liftAssistant
+
+ {- When the client exits, it's restarted;
+ - if it keeps failing, back off to wait 5 minutes before
+ - trying it again. -}
+ retry client starttime = do
+ {- The buddy list starts empty each time
+ - the client connects, so that stale info
+ - is not retained. -}
+ liftAssistant $
+ updateBuddyList (const noBuddies) <<~ buddyList
+ void client
+ liftAssistant $ modifyDaemonStatus_ $ \s -> s
+ { xmppClientID = Nothing }
+ now <- getCurrentTime
+ if diffUTCTime now starttime > 300
+ then do
+ liftAssistant $ debug ["connection lost; reconnecting"]
+ retry client now
+ else do
+ liftAssistant $ debug ["connection failed; will retry"]
+ threadDelaySeconds (Seconds 300)
+ retry client =<< getCurrentTime
+
+ runclient c = liftIO $ connectXMPP c $ \jid -> do
+ selfjid <- bindJID jid
+ putStanza gitAnnexSignature
+
+ inAssistant $ do
+ modifyDaemonStatus_ $ \s -> s
+ { xmppClientID = Just $ xmppJID creds }
+ debug ["connected", logJid selfjid]
+
+ lasttraffic <- liftIO $ atomically . newTMVar =<< getCurrentTime
+
+ sender <- xmppSession $ sendnotifications selfjid
+ receiver <- xmppSession $ receivenotifications selfjid lasttraffic
+ pinger <- xmppSession $ sendpings selfjid lasttraffic
+ {- Run all 3 threads concurrently, until
+ - any of them throw an exception.
+ - Then kill all 3 threads, and rethrow the
+ - exception.
+ -
+ - If this thread gets an exception, the 3 threads
+ - will also be killed. -}
+ liftIO $ pinger `concurrently` sender `concurrently` receiver
+
+ sendnotifications selfjid = forever $
+ join $ inAssistant $ relayNetMessage selfjid
+ receivenotifications selfjid lasttraffic = forever $ do
+ l <- decodeStanza selfjid <$> getStanza
+ void $ liftIO $ atomically . swapTMVar lasttraffic =<< getCurrentTime
+ inAssistant $ debug
+ ["received:", show $ map logXMPPEvent l]
+ mapM_ (handle selfjid) l
+ sendpings selfjid lasttraffic = forever $ do
+ putStanza pingstanza
+
+ startping <- liftIO getCurrentTime
+ liftIO $ threadDelaySeconds (Seconds 120)
+ t <- liftIO $ atomically $ readTMVar lasttraffic
+ when (t < startping) $ do
+ inAssistant $ debug ["ping timeout"]
+ error "ping timeout"
+ where
+ {- XEP-0199 says that the server will respond with either
+ - a ping response or an error message. Either will
+ - cause traffic, so good enough. -}
+ pingstanza = xmppPing selfjid
+
+ handle selfjid (PresenceMessage p) = do
+ void $ inAssistant $
+ updateBuddyList (updateBuddies p) <<~ buddyList
+ resendImportantMessages selfjid p
+ handle _ (GotNetMessage QueryPresence) = putStanza gitAnnexSignature
+ handle _ (GotNetMessage (NotifyPush us)) = void $ inAssistant $ pull us
+ handle selfjid (GotNetMessage (PairingNotification stage c u)) =
+ maybe noop (inAssistant . pairMsgReceived urlrenderer stage u selfjid) (parseJID c)
+ handle _ (GotNetMessage m@(Pushing _ pushstage))
+ | isPushNotice pushstage = inAssistant $ handlePushNotice m
+ | isPushInitiation pushstage = inAssistant $ queuePushInitiation m
+ | otherwise = inAssistant $ storeInbox m
+ handle _ (Ignorable _) = noop
+ handle _ (Unknown _) = noop
+ handle _ (ProtocolError _) = noop
+
+ resendImportantMessages selfjid (Presence { presenceFrom = Just jid }) = do
+ let c = formatJID jid
+ (stored, sent) <- inAssistant $
+ checkImportantNetMessages (formatJID (baseJID jid), c)
+ forM_ (S.toList $ S.difference stored sent) $ \msg -> do
+ let msg' = readdressNetMessage msg c
+ inAssistant $ debug
+ [ "sending to new client:"
+ , logJid jid
+ , show $ logNetMessage msg'
+ ]
+ join $ inAssistant $ convertNetMsg msg' selfjid
+ inAssistant $ sentImportantNetMessage msg c
+ resendImportantMessages _ _ = noop
+
+data XMPPEvent
+ = GotNetMessage NetMessage
+ | PresenceMessage Presence
+ | Ignorable ReceivedStanza
+ | Unknown ReceivedStanza
+ | ProtocolError ReceivedStanza
+ deriving Show
+
+logXMPPEvent :: XMPPEvent -> String
+logXMPPEvent (GotNetMessage m) = logNetMessage m
+logXMPPEvent (PresenceMessage p) = logPresence p
+logXMPPEvent (Ignorable (ReceivedPresence p)) = "Ignorable " ++ logPresence p
+logXMPPEvent (Ignorable _) = "Ignorable message"
+logXMPPEvent (Unknown _) = "Unknown message"
+logXMPPEvent (ProtocolError _) = "Protocol error message"
+
+logPresence :: Presence -> String
+logPresence (p@Presence { presenceFrom = Just jid }) = unwords
+ [ "Presence from"
+ , logJid jid
+ , show $ extractGitAnnexTag p
+ ]
+logPresence _ = "Presence from unknown"
+
+logJid :: JID -> String
+logJid jid =
+ let name = T.unpack (buddyName jid)
+ resource = maybe "" (T.unpack . strResource) (jidResource jid)
+ in take 1 name ++ show (length name) ++ "/" ++ resource
+
+logClient :: Client -> String
+logClient (Client jid) = logJid jid
+
+{- Decodes an XMPP stanza into one or more events. -}
+decodeStanza :: JID -> ReceivedStanza -> [XMPPEvent]
+decodeStanza selfjid s@(ReceivedPresence p)
+ | presenceType p == PresenceError = [ProtocolError s]
+ | isNothing (presenceFrom p) = [Ignorable s]
+ | presenceFrom p == Just selfjid = [Ignorable s]
+ | otherwise = maybe [PresenceMessage p] decode (gitAnnexTagInfo p)
+ where
+ decode i
+ | tagAttr i == pushAttr = impliedp $ GotNetMessage $ NotifyPush $
+ decodePushNotification (tagValue i)
+ | tagAttr i == queryAttr = impliedp $ GotNetMessage QueryPresence
+ | otherwise = [Unknown s]
+ {- Things sent via presence imply a presence message,
+ - along with their real meaning. -}
+ impliedp v = [PresenceMessage p, v]
+decodeStanza selfjid s@(ReceivedMessage m)
+ | isNothing (messageFrom m) = [Ignorable s]
+ | messageFrom m == Just selfjid = [Ignorable s]
+ | messageType m == MessageError = [ProtocolError s]
+ | otherwise = [fromMaybe (Unknown s) (GotNetMessage <$> decodeMessage m)]
+decodeStanza _ s = [Unknown s]
+
+{- Waits for a NetMessager message to be sent, and relays it to XMPP.
+ -
+ - Chat messages must be directed to specific clients, not a base
+ - account JID, due to git-annex clients using a negative presence priority.
+ - PairingNotification messages are always directed at specific
+ - clients, but Pushing messages are sometimes not, and need to be exploded
+ - out to specific clients.
+ -
+ - Important messages, not directed at any specific client,
+ - are cached to be sent later when additional clients connect.
+ -}
+relayNetMessage :: JID -> Assistant (XMPP ())
+relayNetMessage selfjid = do
+ msg <- waitNetMessage
+ debug ["sending:", logNetMessage msg]
+ a1 <- handleImportant msg
+ a2 <- convert msg
+ return (a1 >> a2)
+ where
+ handleImportant msg = case parseJID =<< isImportantNetMessage msg of
+ Just tojid
+ | tojid == baseJID tojid -> do
+ storeImportantNetMessage msg (formatJID tojid) $
+ \c -> (baseJID <$> parseJID c) == Just tojid
+ return $ putStanza presenceQuery
+ _ -> return noop
+ convert (Pushing c pushstage) = withOtherClient selfjid c $ \tojid ->
+ if tojid == baseJID tojid
+ then do
+ clients <- maybe [] (S.toList . buddyAssistants)
+ <$> getBuddy (genBuddyKey tojid) <<~ buddyList
+ debug ["exploded undirected message to clients", unwords $ map logClient clients]
+ return $ forM_ clients $ \(Client jid) ->
+ putStanza $ pushMessage pushstage jid selfjid
+ else do
+ debug ["to client:", logJid tojid]
+ return $ putStanza $ pushMessage pushstage tojid selfjid
+ convert msg = convertNetMsg msg selfjid
+
+{- Converts a NetMessage to an XMPP action. -}
+convertNetMsg :: NetMessage -> JID -> Assistant (XMPP ())
+convertNetMsg msg selfjid = convert msg
+ where
+ convert (NotifyPush us) = return $ putStanza $ pushNotification us
+ convert QueryPresence = return $ putStanza presenceQuery
+ convert (PairingNotification stage c u) = withOtherClient selfjid c $ \tojid -> do
+ changeBuddyPairing tojid True
+ return $ putStanza $ pairingNotification stage u tojid selfjid
+ convert (Pushing c pushstage) = withOtherClient selfjid c $ \tojid ->
+ return $ putStanza $ pushMessage pushstage tojid selfjid
+
+withOtherClient :: JID -> ClientID -> (JID -> Assistant (XMPP ())) -> Assistant (XMPP ())
+withOtherClient selfjid c a = case parseJID c of
+ Nothing -> return noop
+ Just tojid
+ | tojid == selfjid -> return noop
+ | otherwise -> a tojid
+
+withClient :: ClientID -> (JID -> XMPP ()) -> XMPP ()
+withClient c a = maybe noop a $ parseJID c
+
+{- Returns an IO action that runs a XMPP action in a separate thread,
+ - using a session to allow it to access the same XMPP client. -}
+xmppSession :: XMPP () -> XMPP (IO ())
+xmppSession a = do
+ s <- getSession
+ return $ void $ runXMPP s a
+
+{- We only pull from one remote out of the set listed in the push
+ - notification, as an optimisation.
+ -
+ - Note that it might be possible (though very unlikely) for the push
+ - notification to take a while to be sent, and multiple pushes happen
+ - before it is sent, so it includes multiple remotes that were pushed
+ - to at different times.
+ -
+ - It could then be the case that the remote we choose had the earlier
+ - push sent to it, but then failed to get the later push, and so is not
+ - fully up-to-date. If that happens, the pushRetryThread will come along
+ - and retry the push, and we'll get another notification once it succeeds,
+ - and pull again. -}
+pull :: [UUID] -> Assistant ()
+pull [] = noop
+pull us = do
+ rs <- filter matching . syncGitRemotes <$> getDaemonStatus
+ debug $ "push notification for" : map (fromUUID . Remote.uuid ) rs
+ pullone rs =<< liftAnnex (inRepo Git.Branch.current)
+ where
+ matching r = Remote.uuid r `S.member` s
+ s = S.fromList us
+
+ pullone [] _ = noop
+ pullone (r:rs) branch =
+ unlessM (null . fst <$> manualPull branch [r]) $
+ pullone rs branch
+
+{- PairReq from another client using our JID is automatically
+ - accepted. This is so pairing devices all using the same XMPP
+ - account works without confirmations.
+ -
+ - Also, autoaccept PairReq from the same JID of any repo we've
+ - already paired with, as long as the UUID in the PairReq is
+ - one we know about.
+-}
+pairMsgReceived :: UrlRenderer -> PairStage -> UUID -> JID -> JID -> Assistant ()
+pairMsgReceived urlrenderer PairReq theiruuid selfjid theirjid
+ | baseJID selfjid == baseJID theirjid = autoaccept
+ | otherwise = do
+ knownjids <- mapMaybe (parseJID . getXMPPClientID)
+ . filter isXMPPRemote . syncRemotes <$> getDaemonStatus
+ um <- liftAnnex uuidMap
+ if elem (baseJID theirjid) knownjids && M.member theiruuid um
+ then autoaccept
+ else showalert
+
+ where
+ autoaccept = do
+ selfuuid <- liftAnnex getUUID
+ sendNetMessage $
+ PairingNotification PairAck (formatJID theirjid) selfuuid
+ finishXMPPPairing theirjid theiruuid
+ -- Show an alert to let the user decide if they want to pair.
+ showalert = do
+ button <- mkAlertButton True (T.pack "Respond") urlrenderer $
+ ConfirmXMPPPairFriendR $
+ PairKey theiruuid $ formatJID theirjid
+ void $ addAlert $ pairRequestReceivedAlert
+ (T.unpack $ buddyName theirjid)
+ button
+
+{- PairAck must come from one of the buddies we are pairing with;
+ - don't pair with just anyone. -}
+pairMsgReceived _ PairAck theiruuid _selfjid theirjid =
+ whenM (isBuddyPairing theirjid) $ do
+ changeBuddyPairing theirjid False
+ selfuuid <- liftAnnex getUUID
+ sendNetMessage $
+ PairingNotification PairDone (formatJID theirjid) selfuuid
+ finishXMPPPairing theirjid theiruuid
+
+pairMsgReceived _ PairDone _theiruuid _selfjid theirjid =
+ changeBuddyPairing theirjid False
+
+isBuddyPairing :: JID -> Assistant Bool
+isBuddyPairing jid = maybe False buddyPairing <$>
+ getBuddy (genBuddyKey jid) <<~ buddyList
+
+changeBuddyPairing :: JID -> Bool -> Assistant ()
+changeBuddyPairing jid ispairing =
+ updateBuddyList (M.adjust set key) <<~ buddyList
+ where
+ key = genBuddyKey jid
+ set b = b { buddyPairing = ispairing }
diff --git a/Assistant/Threads/XMPPPusher.hs b/Assistant/Threads/XMPPPusher.hs
new file mode 100644
index 000000000..30c91c7f0
--- /dev/null
+++ b/Assistant/Threads/XMPPPusher.hs
@@ -0,0 +1,81 @@
+{- git-annex XMPP pusher threads
+ -
+ - This is a pair of threads. One handles git send-pack,
+ - and the other git receive-pack. Each thread can be running at most
+ - one such operation at a time.
+ -
+ - Why not use a single thread? Consider two clients A and B.
+ - If both decide to run a receive-pack at the same time to the other,
+ - they would deadlock with only one thread. For larger numbers of
+ - clients, the two threads are also sufficient.
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.Threads.XMPPPusher where
+
+import Assistant.Common
+import Assistant.NetMessager
+import Assistant.Types.NetMessager
+import Assistant.WebApp (UrlRenderer)
+import Assistant.WebApp.Configurators.XMPP (checkCloudRepos)
+import Assistant.XMPP.Git
+
+import Control.Exception as E
+
+xmppSendPackThread :: UrlRenderer -> NamedThread
+xmppSendPackThread = pusherThread "XMPPSendPack" SendPack
+
+xmppReceivePackThread :: UrlRenderer -> NamedThread
+xmppReceivePackThread = pusherThread "XMPPReceivePack" ReceivePack
+
+pusherThread :: String -> PushSide -> UrlRenderer -> NamedThread
+pusherThread threadname side urlrenderer = namedThread threadname $ go Nothing
+ where
+ go lastpushedto = do
+ msg <- waitPushInitiation side $ selectNextPush lastpushedto
+ debug ["started running push", logNetMessage msg]
+
+ runpush <- asIO $ runPush checker msg
+ r <- liftIO (E.try runpush :: IO (Either SomeException (Maybe ClientID)))
+ let successful = case r of
+ Right (Just _) -> True
+ _ -> False
+
+ {- Empty the inbox, because stuff may have
+ - been left in it if the push failed. -}
+ let justpushedto = getclient msg
+ maybe noop (`emptyInbox` side) justpushedto
+
+ debug ["finished running push", logNetMessage msg, show successful]
+ go $ if successful then justpushedto else lastpushedto
+
+ checker = checkCloudRepos urlrenderer
+
+ getclient (Pushing cid _) = Just cid
+ getclient _ = Nothing
+
+{- Select the next push to run from the queue.
+ - The queue cannot be empty!
+ -
+ - We prefer to select the most recently added push, because its requestor
+ - is more likely to still be connected.
+ -
+ - When passed the ID of a client we just pushed to, we prefer to not
+ - immediately push again to that same client. This avoids one client
+ - drowing out others. So pushes from the client we just pushed to are
+ - relocated to the beginning of the list, to be processed later.
+ -}
+selectNextPush :: Maybe ClientID -> [NetMessage] -> (NetMessage, [NetMessage])
+selectNextPush _ (m:[]) = (m, []) -- common case
+selectNextPush _ [] = error "selectNextPush: empty list"
+selectNextPush lastpushedto l = go [] l
+ where
+ go (r:ejected) [] = (r, ejected)
+ go rejected (m:ms) = case m of
+ (Pushing clientid _)
+ | Just clientid /= lastpushedto -> (m, rejected ++ ms)
+ _ -> go (m:rejected) ms
+ go [] [] = undefined
diff --git a/Assistant/TransferQueue.hs b/Assistant/TransferQueue.hs
new file mode 100644
index 000000000..f94e73c2b
--- /dev/null
+++ b/Assistant/TransferQueue.hs
@@ -0,0 +1,223 @@
+{- git-annex assistant pending transfer queue
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.TransferQueue (
+ TransferQueue,
+ Schedule(..),
+ newTransferQueue,
+ getTransferQueue,
+ queueTransfers,
+ queueTransfersMatching,
+ queueDeferredDownloads,
+ queueTransfer,
+ queueTransferAt,
+ queueTransferWhenSmall,
+ getNextTransfer,
+ getMatchingTransfers,
+ dequeueTransfers,
+) where
+
+import Assistant.Common
+import Assistant.DaemonStatus
+import Assistant.Types.TransferQueue
+import Logs.Transfer
+import Types.Remote
+import qualified Remote
+import qualified Types.Remote as Remote
+import Annex.Wanted
+import Utility.TList
+
+import Control.Concurrent.STM
+import qualified Data.Map as M
+import qualified Data.Set as S
+
+type Reason = String
+
+{- Reads the queue's content without blocking or changing it. -}
+getTransferQueue :: Assistant [(Transfer, TransferInfo)]
+getTransferQueue = (atomically . readTList . queuelist) <<~ transferQueue
+
+stubInfo :: AssociatedFile -> Remote -> TransferInfo
+stubInfo f r = stubTransferInfo
+ { transferRemote = Just r
+ , associatedFile = f
+ }
+
+{- Adds transfers to queue for some of the known remotes.
+ - Honors preferred content settings, only transferring wanted files. -}
+queueTransfers :: Reason -> Schedule -> Key -> AssociatedFile -> Direction -> Assistant ()
+queueTransfers = queueTransfersMatching (const True)
+
+{- Adds transfers to queue for some of the known remotes, that match a
+ - condition. Honors preferred content settings. -}
+queueTransfersMatching :: (UUID -> Bool) -> Reason -> Schedule -> Key -> AssociatedFile -> Direction -> Assistant ()
+queueTransfersMatching matching reason schedule k f direction
+ | direction == Download = whenM (liftAnnex $ wantGet True f) go
+ | otherwise = go
+ where
+ go = do
+
+ rs <- liftAnnex . selectremotes
+ =<< syncDataRemotes <$> getDaemonStatus
+ let matchingrs = filter (matching . Remote.uuid) rs
+ if null matchingrs
+ then defer
+ else forM_ matchingrs $ \r ->
+ enqueue reason schedule (gentransfer r) (stubInfo f r)
+ selectremotes rs
+ {- Queue downloads from all remotes that
+ - have the key. The list of remotes is ordered with
+ - cheapest first. More expensive ones will only be tried
+ - if downloading from a cheap one fails. -}
+ | direction == Download = do
+ s <- locs
+ return $ filter (inset s) rs
+ {- Upload to all remotes that want the content and don't
+ - already have it. -}
+ | otherwise = do
+ s <- locs
+ filterM (wantSend True f . Remote.uuid) $
+ filter (\r -> not (inset s r || Remote.readonly r)) rs
+ where
+ locs = S.fromList <$> Remote.keyLocations k
+ inset s r = S.member (Remote.uuid r) s
+ gentransfer r = Transfer
+ { transferDirection = direction
+ , transferKey = k
+ , transferUUID = Remote.uuid r
+ }
+ defer
+ {- Defer this download, as no known remote has the key. -}
+ | direction == Download = do
+ q <- getAssistant transferQueue
+ void $ liftIO $ atomically $
+ consTList (deferreddownloads q) (k, f)
+ | otherwise = noop
+
+{- Queues any deferred downloads that can now be accomplished, leaving
+ - any others in the list to try again later. -}
+queueDeferredDownloads :: Reason -> Schedule -> Assistant ()
+queueDeferredDownloads reason schedule = do
+ q <- getAssistant transferQueue
+ l <- liftIO $ atomically $ readTList (deferreddownloads q)
+ rs <- syncDataRemotes <$> getDaemonStatus
+ left <- filterM (queue rs) l
+ unless (null left) $
+ liftIO $ atomically $ appendTList (deferreddownloads q) left
+ where
+ queue rs (k, f) = do
+ uuids <- liftAnnex $ Remote.keyLocations k
+ let sources = filter (\r -> uuid r `elem` uuids) rs
+ unless (null sources) $
+ forM_ sources $ \r ->
+ enqueue reason schedule
+ (gentransfer r) (stubInfo f r)
+ return $ null sources
+ where
+ gentransfer r = Transfer
+ { transferDirection = Download
+ , transferKey = k
+ , transferUUID = Remote.uuid r
+ }
+
+enqueue :: Reason -> Schedule -> Transfer -> TransferInfo -> Assistant ()
+enqueue reason schedule t info
+ | schedule == Next = go consTList
+ | otherwise = go snocTList
+ where
+ go modlist = whenM (add modlist) $ do
+ debug [ "queued", describeTransfer t info, ": " ++ reason ]
+ notifyTransfer
+ add modlist = do
+ q <- getAssistant transferQueue
+ dstatus <- getAssistant daemonStatusHandle
+ liftIO $ atomically $ ifM (checkRunningTransferSTM dstatus t)
+ ( return False
+ , do
+ l <- readTList (queuelist q)
+ if (t `notElem` map fst l)
+ then do
+ void $ modifyTVar' (queuesize q) succ
+ void $ modlist (queuelist q) (t, info)
+ return True
+ else return False
+ )
+
+{- Adds a transfer to the queue. -}
+queueTransfer :: Reason -> Schedule -> AssociatedFile -> Transfer -> Remote -> Assistant ()
+queueTransfer reason schedule f t remote =
+ enqueue reason schedule t (stubInfo f remote)
+
+{- Blocks until the queue is no larger than a given size, and then adds a
+ - transfer to the queue. -}
+queueTransferAt :: Int -> Reason -> Schedule -> AssociatedFile -> Transfer -> Remote -> Assistant ()
+queueTransferAt wantsz reason schedule f t remote = do
+ q <- getAssistant transferQueue
+ liftIO $ atomically $ do
+ sz <- readTVar (queuesize q)
+ unless (sz <= wantsz) $
+ retry -- blocks until queuesize changes
+ enqueue reason schedule t (stubInfo f remote)
+
+queueTransferWhenSmall :: Reason -> AssociatedFile -> Transfer -> Remote -> Assistant ()
+queueTransferWhenSmall reason = queueTransferAt 10 reason Later
+
+{- Blocks until a pending transfer is available in the queue,
+ - and removes it.
+ -
+ - Checks that it's acceptable, before adding it to the
+ - currentTransfers map. If it's not acceptable, it's discarded.
+ -
+ - This is done in a single STM transaction, so there is no window
+ - where an observer sees an inconsistent status. -}
+getNextTransfer :: (TransferInfo -> Bool) -> Assistant (Maybe (Transfer, TransferInfo))
+getNextTransfer acceptable = do
+ q <- getAssistant transferQueue
+ dstatus <- getAssistant daemonStatusHandle
+ liftIO $ atomically $ do
+ sz <- readTVar (queuesize q)
+ if sz < 1
+ then retry -- blocks until queuesize changes
+ else do
+ (r@(t,info):rest) <- readTList (queuelist q)
+ void $ modifyTVar' (queuesize q) pred
+ setTList (queuelist q) rest
+ if acceptable info
+ then do
+ adjustTransfersSTM dstatus $
+ M.insertWith' const t info
+ return $ Just r
+ else return Nothing
+
+{- Moves transfers matching a condition from the queue, to the
+ - currentTransfers map. -}
+getMatchingTransfers :: (Transfer -> Bool) -> Assistant [(Transfer, TransferInfo)]
+getMatchingTransfers c = do
+ q <- getAssistant transferQueue
+ dstatus <- getAssistant daemonStatusHandle
+ liftIO $ atomically $ do
+ ts <- dequeueTransfersSTM q c
+ unless (null ts) $
+ adjustTransfersSTM dstatus $ \m -> M.union m $ M.fromList ts
+ return ts
+
+{- Removes transfers matching a condition from the queue, and returns the
+ - removed transfers. -}
+dequeueTransfers :: (Transfer -> Bool) -> Assistant [(Transfer, TransferInfo)]
+dequeueTransfers c = do
+ q <- getAssistant transferQueue
+ removed <- liftIO $ atomically $ dequeueTransfersSTM q c
+ unless (null removed) $
+ notifyTransfer
+ return removed
+
+dequeueTransfersSTM :: TransferQueue -> (Transfer -> Bool) -> STM [(Transfer, TransferInfo)]
+dequeueTransfersSTM q c = do
+ (removed, ts) <- partition (c . fst) <$> readTList (queuelist q)
+ void $ writeTVar (queuesize q) (length ts)
+ setTList (queuelist q) ts
+ return removed
diff --git a/Assistant/TransferSlots.hs b/Assistant/TransferSlots.hs
new file mode 100644
index 000000000..cb66e845a
--- /dev/null
+++ b/Assistant/TransferSlots.hs
@@ -0,0 +1,286 @@
+{- git-annex assistant transfer slots
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Assistant.TransferSlots where
+
+import Assistant.Common
+import Utility.ThreadScheduler
+import Assistant.Types.TransferSlots
+import Assistant.DaemonStatus
+import Assistant.TransferrerPool
+import Assistant.Types.TransferrerPool
+import Assistant.Types.TransferQueue
+import Assistant.TransferQueue
+import Assistant.Alert
+import Assistant.Alert.Utility
+import Assistant.Commits
+import Assistant.Drop
+import Logs.Transfer
+import Logs.Location
+import qualified Git
+import qualified Remote
+import qualified Types.Remote as Remote
+import Annex.Content
+import Annex.Wanted
+import Config.Files
+
+import qualified Data.Map as M
+import qualified Control.Exception as E
+import Control.Concurrent
+import qualified Control.Concurrent.MSemN as MSemN
+#ifndef mingw32_HOST_OS
+import System.Posix.Process (getProcessGroupIDOf)
+import System.Posix.Signals (signalProcessGroup, sigTERM, sigKILL)
+#endif
+
+type TransferGenerator = Assistant (Maybe (Transfer, TransferInfo, Transferrer -> Assistant ()))
+
+{- Waits until a transfer slot becomes available, then runs a
+ - TransferGenerator, and then runs the transfer action in its own thread.
+ -}
+inTransferSlot :: FilePath -> TransferGenerator -> Assistant ()
+inTransferSlot program gen = do
+ flip MSemN.wait 1 <<~ transferSlots
+ runTransferThread program =<< gen
+
+{- Runs a TransferGenerator, and its transfer action,
+ - without waiting for a slot to become available. -}
+inImmediateTransferSlot :: FilePath -> TransferGenerator -> Assistant ()
+inImmediateTransferSlot program gen = do
+ flip MSemN.signal (-1) <<~ transferSlots
+ runTransferThread program =<< gen
+
+{- Runs a transfer action, in an already allocated transfer slot.
+ - Once it finishes, frees the transfer slot.
+ -
+ - Note that the action is subject to being killed when the transfer
+ - is canceled or paused.
+ -
+ - A PauseTransfer exception is handled by letting the action be killed,
+ - then pausing the thread until a ResumeTransfer exception is raised,
+ - then rerunning the action.
+ -}
+runTransferThread :: FilePath -> Maybe (Transfer, TransferInfo, Transferrer -> Assistant ()) -> Assistant ()
+runTransferThread _ Nothing = flip MSemN.signal 1 <<~ transferSlots
+runTransferThread program (Just (t, info, a)) = do
+ d <- getAssistant id
+ aio <- asIO1 a
+ tid <- liftIO $ forkIO $ runTransferThread' program d aio
+ updateTransferInfo t $ info { transferTid = Just tid }
+
+runTransferThread' :: FilePath -> AssistantData -> (Transferrer -> IO ()) -> IO ()
+runTransferThread' program d run = go
+ where
+ go = catchPauseResume $
+ withTransferrer program (transferrerPool d)
+ run
+ pause = catchPauseResume $
+ runEvery (Seconds 86400) noop
+ {- Note: This must use E.try, rather than E.catch.
+ - When E.catch is used, and has called go in its exception
+ - handler, Control.Concurrent.throwTo will block sometimes
+ - when signaling. Using E.try avoids the problem. -}
+ catchPauseResume a' = do
+ r <- E.try a' :: IO (Either E.SomeException ())
+ case r of
+ Left e -> case E.fromException e of
+ Just PauseTransfer -> pause
+ Just ResumeTransfer -> go
+ _ -> done
+ _ -> done
+ done = runAssistant d $
+ flip MSemN.signal 1 <<~ transferSlots
+
+{- By the time this is called, the daemonstatus's currentTransfers map should
+ - already have been updated to include the transfer. -}
+genTransfer :: Transfer -> TransferInfo -> TransferGenerator
+genTransfer t info = case (transferRemote info, associatedFile info) of
+ (Just remote, Just file)
+ | Git.repoIsLocalUnknown (Remote.repo remote) -> do
+ -- optimisation for removable drives not plugged in
+ liftAnnex $ recordFailedTransfer t info
+ void $ removeTransfer t
+ return Nothing
+ | otherwise -> ifM (liftAnnex $ shouldTransfer t info)
+ ( do
+ debug [ "Transferring:" , describeTransfer t info ]
+ notifyTransfer
+ return $ Just (t, info, go remote file)
+ , do
+ debug [ "Skipping unnecessary transfer:",
+ describeTransfer t info ]
+ void $ removeTransfer t
+ finishedTransfer t (Just info)
+ return Nothing
+ )
+ _ -> return Nothing
+ where
+ direction = transferDirection t
+ isdownload = direction == Download
+
+ {- Alerts are only shown for successful transfers.
+ - Transfers can temporarily fail for many reasons,
+ - so there's no point in bothering the user about
+ - those. The assistant should recover.
+ -
+ - After a successful upload, handle dropping it from
+ - here, if desired. In this case, the remote it was
+ - uploaded to is known to have it.
+ -
+ - Also, after a successful transfer, the location
+ - log has changed. Indicate that a commit has been
+ - made, in order to queue a push of the git-annex
+ - branch out to remotes that did not participate
+ - in the transfer.
+ -
+ - If the process failed, it could have crashed,
+ - so remove the transfer from the list of current
+ - transfers, just in case it didn't stop
+ - in a way that lets the TransferWatcher do its
+ - usual cleanup. However, first check if something else is
+ - running the transfer, to avoid removing active transfers.
+ -}
+ go remote file transferrer = ifM (liftIO $ performTransfer transferrer t $ associatedFile info)
+ ( do
+ void $ addAlert $ makeAlertFiller True $
+ transferFileAlert direction True file
+ unless isdownload $
+ handleDrops
+ ("object uploaded to " ++ show remote)
+ True (transferKey t)
+ (associatedFile info)
+ (Just remote)
+ void recordCommit
+ , whenM (liftAnnex $ isNothing <$> checkTransfer t) $
+ void $ removeTransfer t
+ )
+
+{- Called right before a transfer begins, this is a last chance to avoid
+ - unnecessary transfers.
+ -
+ - For downloads, we obviously don't need to download if the already
+ - have the object.
+ -
+ - Smilarly, for uploads, check if the remote is known to already have
+ - the object.
+ -
+ - Also, uploads get queued to all remotes, in order of cost.
+ - This may mean, for example, that an object is uploaded over the LAN
+ - to a locally paired client, and once that upload is done, a more
+ - expensive transfer remote no longer wants the object. (Since
+ - all the clients have it already.) So do one last check if this is still
+ - preferred content.
+ -
+ - We'll also do one last preferred content check for downloads. An
+ - example of a case where this could be needed is if a download is queued
+ - for a file that gets moved out of an archive directory -- but before
+ - that download can happen, the file is put back in the archive.
+ -}
+shouldTransfer :: Transfer -> TransferInfo -> Annex Bool
+shouldTransfer t info
+ | transferDirection t == Download =
+ (not <$> inAnnex key) <&&> wantGet True file
+ | transferDirection t == Upload = case transferRemote info of
+ Nothing -> return False
+ Just r -> notinremote r
+ <&&> wantSend True file (Remote.uuid r)
+ | otherwise = return False
+ where
+ key = transferKey t
+ file = associatedFile info
+
+ {- Trust the location log to check if the remote already has
+ - the key. This avoids a roundtrip to the remote. -}
+ notinremote r = notElem (Remote.uuid r) <$> loggedLocations key
+
+{- Queue uploads of files downloaded to us, spreading them
+ - out to other reachable remotes.
+ -
+ - Downloading a file may have caused a remote to not want it;
+ - so check for drops from remotes.
+ -
+ - Uploading a file may cause the local repo, or some other remote to not
+ - want it; handle that too.
+ -}
+finishedTransfer :: Transfer -> Maybe TransferInfo -> Assistant ()
+finishedTransfer t (Just info)
+ | transferDirection t == Download =
+ whenM (liftAnnex $ inAnnex $ transferKey t) $ do
+ dodrops False
+ queueTransfersMatching (/= transferUUID t)
+ "newly received object"
+ Later (transferKey t) (associatedFile info) Upload
+ | otherwise = dodrops True
+ where
+ dodrops fromhere = handleDrops
+ ("drop wanted after " ++ describeTransfer t info)
+ fromhere (transferKey t) (associatedFile info) Nothing
+finishedTransfer _ _ = noop
+
+{- Pause a running transfer. -}
+pauseTransfer :: Transfer -> Assistant ()
+pauseTransfer = cancelTransfer True
+
+{- Cancel a running transfer. -}
+cancelTransfer :: Bool -> Transfer -> Assistant ()
+cancelTransfer pause t = do
+ m <- getCurrentTransfers
+ unless pause $
+ {- remove queued transfer -}
+ void $ dequeueTransfers $ equivilantTransfer t
+ {- stop running transfer -}
+ maybe noop stop (M.lookup t m)
+ where
+ stop info = do
+ {- When there's a thread associated with the
+ - transfer, it's signaled first, to avoid it
+ - displaying any alert about the transfer having
+ - failed when the transfer process is killed. -}
+ liftIO $ maybe noop signalthread $ transferTid info
+ liftIO $ maybe noop killproc $ transferPid info
+ if pause
+ then void $ alterTransferInfo t $
+ \i -> i { transferPaused = True }
+ else void $ removeTransfer t
+ signalthread tid
+ | pause = throwTo tid PauseTransfer
+ | otherwise = killThread tid
+ killproc pid = void $ tryIO $ do
+#ifndef mingw32_HOST_OS
+ {- In order to stop helper processes like rsync,
+ - kill the whole process group of the process
+ - running the transfer. -}
+ g <- getProcessGroupIDOf pid
+ void $ tryIO $ signalProcessGroup sigTERM g
+ threadDelay 50000 -- 0.05 second grace period
+ void $ tryIO $ signalProcessGroup sigKILL g
+#else
+ error "TODO: cancelTransfer not implemented on Windows"
+#endif
+
+{- Start or resume a transfer. -}
+startTransfer :: Transfer -> Assistant ()
+startTransfer t = do
+ m <- getCurrentTransfers
+ maybe startqueued go (M.lookup t m)
+ where
+ go info = maybe (start info) resume $ transferTid info
+ startqueued = do
+ is <- map snd <$> getMatchingTransfers (== t)
+ maybe noop start $ headMaybe is
+ resume tid = do
+ alterTransferInfo t $ \i -> i { transferPaused = False }
+ liftIO $ throwTo tid ResumeTransfer
+ start info = do
+ program <- liftIO readProgramFile
+ inImmediateTransferSlot program $
+ genTransfer t info
+
+getCurrentTransfers :: Assistant TransferMap
+getCurrentTransfers = currentTransfers <$> getDaemonStatus
diff --git a/Assistant/TransferrerPool.hs b/Assistant/TransferrerPool.hs
new file mode 100644
index 000000000..bb4648731
--- /dev/null
+++ b/Assistant/TransferrerPool.hs
@@ -0,0 +1,95 @@
+{- A pool of "git-annex transferkeys" processes
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Assistant.TransferrerPool where
+
+import Assistant.Common
+import Assistant.Types.TransferrerPool
+import Logs.Transfer
+
+#ifndef mingw32_HOST_OS
+import qualified Command.TransferKeys as T
+#endif
+
+import Control.Concurrent.STM
+import System.Process (create_group)
+import Control.Exception (throw)
+import Control.Concurrent
+
+{- Runs an action with a Transferrer from the pool. -}
+withTransferrer :: FilePath -> TransferrerPool -> (Transferrer -> IO a) -> IO a
+withTransferrer program pool a = do
+ t <- maybe (mkTransferrer program) (checkTransferrer program)
+ =<< atomically (tryReadTChan pool)
+ v <- tryNonAsync $ a t
+ unlessM (putback t) $
+ void $ forkIO $ stopTransferrer t
+ either throw return v
+ where
+ putback t = atomically $ ifM (isEmptyTChan pool)
+ ( do
+ writeTChan pool t
+ return True
+ , return False
+ )
+
+{- Requests that a Transferrer perform a Transfer, and waits for it to
+ - finish. -}
+performTransfer :: Transferrer -> Transfer -> AssociatedFile -> IO Bool
+performTransfer transferrer t f = catchBoolIO $ do
+#ifndef mingw32_HOST_OS
+ T.sendRequest t f (transferrerWrite transferrer)
+ T.readResponse (transferrerRead transferrer)
+#else
+ error "TODO performTransfer not implemented on Windows"
+#endif
+
+{- Starts a new git-annex transferkeys process, setting up a pipe
+ - that will be used to communicate with it. -}
+mkTransferrer :: FilePath -> IO Transferrer
+mkTransferrer program = do
+#ifndef mingw32_HOST_OS
+ (myread, twrite) <- createPipe
+ (tread, mywrite) <- createPipe
+ mapM_ (\fd -> setFdOption fd CloseOnExec True) [myread, mywrite]
+ let params =
+ [ Param "transferkeys"
+ , Param "--readfd", Param $ show tread
+ , Param "--writefd", Param $ show twrite
+ ]
+ {- It's put into its own group so that the whole group can be
+ - killed to stop a transfer. -}
+ (_, _, _, pid) <- createProcess (proc program $ toCommand params)
+ { create_group = True }
+ closeFd twrite
+ closeFd tread
+ myreadh <- fdToHandle myread
+ mywriteh <- fdToHandle mywrite
+ fileEncoding myreadh
+ fileEncoding mywriteh
+ return $ Transferrer
+ { transferrerRead = myreadh
+ , transferrerWrite = mywriteh
+ , transferrerHandle = pid
+ }
+#else
+ error "TODO mkTransferrer not implemented on Windows"
+#endif
+
+{- Checks if a Transferrer is still running. If not, makes a new one. -}
+checkTransferrer :: FilePath -> Transferrer -> IO Transferrer
+checkTransferrer program t = maybe (return t) (const $ mkTransferrer program)
+ =<< getProcessExitCode (transferrerHandle t)
+
+{- Closing the fds will stop the transferrer. -}
+stopTransferrer :: Transferrer -> IO ()
+stopTransferrer t = do
+ hClose $ transferrerRead t
+ hClose $ transferrerWrite t
+ void $ waitForProcess $ transferrerHandle t
diff --git a/Assistant/Types/Alert.hs b/Assistant/Types/Alert.hs
new file mode 100644
index 000000000..e6fbe86d3
--- /dev/null
+++ b/Assistant/Types/Alert.hs
@@ -0,0 +1,78 @@
+{- git-annex assistant alert types
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.Types.Alert where
+
+import Utility.Tense
+
+import Data.Text (Text)
+import qualified Data.Map as M
+
+{- Different classes of alerts are displayed differently. -}
+data AlertClass = Success | Message | Activity | Warning | Error
+ deriving (Eq, Ord)
+
+data AlertPriority = Filler | Low | Medium | High | Pinned
+ deriving (Eq, Ord)
+
+{- An alert can have an name, which is used to combine it with other similar
+ - alerts. -}
+data AlertName
+ = FileAlert TenseChunk
+ | SanityCheckFixAlert
+ | WarningAlert String
+ | PairAlert String
+ | XMPPNeededAlert
+ | RemoteRemovalAlert String
+ | CloudRepoNeededAlert
+ | SyncAlert
+ | NotFsckedAlert
+ | UpgradeAlert
+ deriving (Eq)
+
+{- The first alert is the new alert, the second is an old alert.
+ - Should return a modified version of the old alert. -}
+type AlertCombiner = Alert -> Alert -> Maybe Alert
+
+data Alert = Alert
+ { alertClass :: AlertClass
+ , alertHeader :: Maybe TenseText
+ , alertMessageRender :: Alert -> TenseText
+ , alertData :: [TenseChunk]
+ , alertCounter :: Int
+ , alertBlockDisplay :: Bool
+ , alertClosable :: Bool
+ , alertPriority :: AlertPriority
+ , alertIcon :: Maybe AlertIcon
+ , alertCombiner :: Maybe AlertCombiner
+ , alertName :: Maybe AlertName
+ , alertButtons :: [AlertButton]
+ }
+
+data AlertIcon = ActivityIcon | SyncIcon | SuccessIcon | ErrorIcon | InfoIcon | UpgradeIcon | TheCloud
+
+type AlertMap = M.Map AlertId Alert
+
+{- Higher AlertId indicates a more recent alert. -}
+newtype AlertId = AlertId Integer
+ deriving (Read, Show, Eq, Ord)
+
+firstAlertId :: AlertId
+firstAlertId = AlertId 0
+
+nextAlertId :: AlertId -> AlertId
+nextAlertId (AlertId i) = AlertId $ succ i
+
+{- When clicked, a button always redirects to a URL
+ - It may also run an IO action in the background, which is useful
+ - to make the button close or otherwise change the alert. -}
+data AlertButton = AlertButton
+ { buttonLabel :: Text
+ , buttonUrl :: Text
+ , buttonAction :: Maybe (AlertId -> IO ())
+ , buttonPrimary :: Bool
+ }
diff --git a/Assistant/Types/BranchChange.hs b/Assistant/Types/BranchChange.hs
new file mode 100644
index 000000000..399abee54
--- /dev/null
+++ b/Assistant/Types/BranchChange.hs
@@ -0,0 +1,19 @@
+{- git-annex assistant git-annex branch change tracking
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.Types.BranchChange where
+
+import Control.Concurrent.MSampleVar
+import Common.Annex
+
+newtype BranchChangeHandle = BranchChangeHandle (MSampleVar ())
+
+newBranchChangeHandle :: IO BranchChangeHandle
+newBranchChangeHandle = BranchChangeHandle <$> newEmptySV
+
+fromBranchChangeHandle :: BranchChangeHandle -> MSampleVar ()
+fromBranchChangeHandle (BranchChangeHandle v) = v
diff --git a/Assistant/Types/Buddies.hs b/Assistant/Types/Buddies.hs
new file mode 100644
index 000000000..36d8a4fed
--- /dev/null
+++ b/Assistant/Types/Buddies.hs
@@ -0,0 +1,80 @@
+{- git-annex assistant buddies
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Assistant.Types.Buddies where
+
+import Common.Annex
+
+import qualified Data.Map as M
+import Control.Concurrent.STM
+import Utility.NotificationBroadcaster
+import Data.Text as T
+
+{- For simplicity, dummy types are defined even when XMPP is disabled. -}
+#ifdef WITH_XMPP
+import Network.Protocol.XMPP
+import Data.Set as S
+import Data.Ord
+
+newtype Client = Client JID
+ deriving (Eq, Show)
+
+instance Ord Client where
+ compare = comparing show
+
+data Buddy = Buddy
+ { buddyPresent :: S.Set Client
+ , buddyAway :: S.Set Client
+ , buddyAssistants :: S.Set Client
+ , buddyPairing :: Bool
+ }
+#else
+data Buddy = Buddy
+#endif
+ deriving (Eq, Show)
+
+data BuddyKey = BuddyKey T.Text
+ deriving (Eq, Ord, Show, Read)
+
+data PairKey = PairKey UUID T.Text
+ deriving (Eq, Ord, Show, Read)
+
+type Buddies = M.Map BuddyKey Buddy
+
+{- A list of buddies, and a way to notify when it changes. -}
+type BuddyList = (TMVar Buddies, NotificationBroadcaster)
+
+noBuddies :: Buddies
+noBuddies = M.empty
+
+newBuddyList :: IO BuddyList
+newBuddyList = (,)
+ <$> atomically (newTMVar noBuddies)
+ <*> newNotificationBroadcaster
+
+getBuddyList :: BuddyList -> IO [Buddy]
+getBuddyList (v, _) = M.elems <$> atomically (readTMVar v)
+
+getBuddy :: BuddyKey -> BuddyList -> IO (Maybe Buddy)
+getBuddy k (v, _) = M.lookup k <$> atomically (readTMVar v)
+
+getBuddyBroadcaster :: BuddyList -> NotificationBroadcaster
+getBuddyBroadcaster (_, h) = h
+
+{- Applies a function to modify the buddy list, and if it's changed,
+ - sends notifications to any listeners. -}
+updateBuddyList :: (Buddies -> Buddies) -> BuddyList -> IO ()
+updateBuddyList a (v, caster) = do
+ changed <- atomically $ do
+ buds <- takeTMVar v
+ let buds' = a buds
+ putTMVar v buds'
+ return $ buds /= buds'
+ when changed $
+ sendNotification caster
diff --git a/Assistant/Types/Changes.hs b/Assistant/Types/Changes.hs
new file mode 100644
index 000000000..e8ecc6e48
--- /dev/null
+++ b/Assistant/Types/Changes.hs
@@ -0,0 +1,77 @@
+{- git-annex assistant change tracking
+ -
+ - Copyright 2012-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.Types.Changes where
+
+import Types.KeySource
+import Types.Key
+import Utility.TList
+
+import Control.Concurrent.STM
+import Data.Time.Clock
+
+{- An un-ordered pool of Changes that have been noticed and should be
+ - staged and committed. Changes will typically be in order, but ordering
+ - may be lost. In any case, order should not matter, as any given Change
+ - may later be reverted by a later Change (ie, a file is added and then
+ - deleted). Code that processes the changes needs to deal with such
+ - scenarios.
+ -}
+type ChangePool = TList Change
+
+newChangePool :: IO ChangePool
+newChangePool = atomically newTList
+
+data Change
+ = Change
+ { changeTime :: UTCTime
+ , _changeFile :: FilePath
+ , changeInfo :: ChangeInfo
+ }
+ | PendingAddChange
+ { changeTime ::UTCTime
+ , _changeFile :: FilePath
+ }
+ | InProcessAddChange
+ { changeTime ::UTCTime
+ , keySource :: KeySource
+ }
+ deriving (Show)
+
+data ChangeInfo = AddKeyChange Key | AddFileChange | LinkChange (Maybe Key) | RmChange
+ deriving (Show, Eq, Ord)
+
+changeInfoKey :: ChangeInfo -> Maybe Key
+changeInfoKey (AddKeyChange k) = Just k
+changeInfoKey (LinkChange (Just k)) = Just k
+changeInfoKey _ = Nothing
+
+changeFile :: Change -> FilePath
+changeFile (Change _ f _) = f
+changeFile (PendingAddChange _ f) = f
+changeFile (InProcessAddChange _ ks) = keyFilename ks
+
+isPendingAddChange :: Change -> Bool
+isPendingAddChange (PendingAddChange {}) = True
+isPendingAddChange _ = False
+
+isInProcessAddChange :: Change -> Bool
+isInProcessAddChange (InProcessAddChange {}) = True
+isInProcessAddChange _ = False
+
+retryChange :: Change -> Change
+retryChange (InProcessAddChange time ks) =
+ PendingAddChange time (keyFilename ks)
+retryChange c = c
+
+finishedChange :: Change -> Key -> Change
+finishedChange c@(InProcessAddChange { keySource = ks }) k = Change
+ { changeTime = changeTime c
+ , _changeFile = keyFilename ks
+ , changeInfo = AddKeyChange k
+ }
+finishedChange c _ = c
diff --git a/Assistant/Types/Commits.hs b/Assistant/Types/Commits.hs
new file mode 100644
index 000000000..500faa901
--- /dev/null
+++ b/Assistant/Types/Commits.hs
@@ -0,0 +1,19 @@
+{- git-annex assistant commit tracking
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.Types.Commits where
+
+import Utility.TList
+
+import Control.Concurrent.STM
+
+type CommitChan = TList Commit
+
+data Commit = Commit
+
+newCommitChan :: IO CommitChan
+newCommitChan = atomically newTList
diff --git a/Assistant/Types/DaemonStatus.hs b/Assistant/Types/DaemonStatus.hs
new file mode 100644
index 000000000..a618c700d
--- /dev/null
+++ b/Assistant/Types/DaemonStatus.hs
@@ -0,0 +1,119 @@
+{- git-annex assistant daemon status
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.Types.DaemonStatus where
+
+import Common.Annex
+import Assistant.Pairing
+import Utility.NotificationBroadcaster
+import Logs.Transfer
+import Assistant.Types.ThreadName
+import Assistant.Types.NetMessager
+import Assistant.Types.Alert
+import Utility.Url
+
+import Control.Concurrent.STM
+import Control.Concurrent.MVar
+import Control.Concurrent.Async
+import Data.Time.Clock.POSIX
+import qualified Data.Map as M
+import qualified Data.Set as S
+
+data DaemonStatus = DaemonStatus
+ -- All the named threads that comprise the daemon,
+ -- and actions to run to restart them.
+ { startedThreads :: M.Map ThreadName (Async (), IO ())
+ -- False when the daemon is performing its startup scan
+ , scanComplete :: Bool
+ -- True when all files should be restaged.
+ , forceRestage :: Bool
+ -- Time when a previous process of the daemon was running ok
+ , lastRunning :: Maybe POSIXTime
+ -- True when the daily sanity checker is running
+ , sanityCheckRunning :: Bool
+ -- Last time the daily sanity checker ran
+ , lastSanityCheck :: Maybe POSIXTime
+ -- True when a scan for file transfers is running
+ , transferScanRunning :: Bool
+ -- Currently running file content transfers
+ , currentTransfers :: TransferMap
+ -- Messages to display to the user.
+ , alertMap :: AlertMap
+ , lastAlertId :: AlertId
+ -- Ordered list of all remotes that can be synced with
+ , syncRemotes :: [Remote]
+ -- Ordered list of remotes to sync git with
+ , syncGitRemotes :: [Remote]
+ -- Ordered list of remotes to sync data with
+ , syncDataRemotes :: [Remote]
+ -- Are we syncing to any cloud remotes?
+ , syncingToCloudRemote :: Bool
+ -- List of uuids of remotes that we may have gotten out of sync with.
+ , desynced :: S.Set UUID
+ -- Pairing request that is in progress.
+ , pairingInProgress :: Maybe PairingInProgress
+ -- Broadcasts notifications about all changes to the DaemonStatus.
+ , changeNotifier :: NotificationBroadcaster
+ -- Broadcasts notifications when queued or current transfers change.
+ , transferNotifier :: NotificationBroadcaster
+ -- Broadcasts notifications when there's a change to the alerts.
+ , alertNotifier :: NotificationBroadcaster
+ -- Broadcasts notifications when the syncRemotes change.
+ , syncRemotesNotifier :: NotificationBroadcaster
+ -- Broadcasts notifications when the scheduleLog changes.
+ , scheduleLogNotifier :: NotificationBroadcaster
+ -- Broadcasts a notification once the startup sanity check has run.
+ , startupSanityCheckNotifier :: NotificationBroadcaster
+ -- Broadcasts notifications when the network is connected.
+ , networkConnectedNotifier :: NotificationBroadcaster
+ -- Broadcasts notifications when a global redirect is needed.
+ , globalRedirNotifier :: NotificationBroadcaster
+ , globalRedirUrl :: Maybe URLString
+ -- Actions to run after a Key is transferred.
+ , transferHook :: M.Map Key (Transfer -> IO ())
+ -- When the XMPP client is connected, this will contain the XMPP
+ -- address.
+ , xmppClientID :: Maybe ClientID
+ -- MVars to signal when a remote gets connected.
+ , connectRemoteNotifiers :: M.Map UUID [MVar ()]
+ }
+
+type TransferMap = M.Map Transfer TransferInfo
+
+{- This TMVar is never left empty, so accessing it will never block. -}
+type DaemonStatusHandle = TMVar DaemonStatus
+
+newDaemonStatus :: IO DaemonStatus
+newDaemonStatus = DaemonStatus
+ <$> pure M.empty
+ <*> pure False
+ <*> pure False
+ <*> pure Nothing
+ <*> pure False
+ <*> pure Nothing
+ <*> pure False
+ <*> pure M.empty
+ <*> pure M.empty
+ <*> pure firstAlertId
+ <*> pure []
+ <*> pure []
+ <*> pure []
+ <*> pure False
+ <*> pure S.empty
+ <*> pure Nothing
+ <*> newNotificationBroadcaster
+ <*> newNotificationBroadcaster
+ <*> newNotificationBroadcaster
+ <*> newNotificationBroadcaster
+ <*> newNotificationBroadcaster
+ <*> newNotificationBroadcaster
+ <*> newNotificationBroadcaster
+ <*> newNotificationBroadcaster
+ <*> pure Nothing
+ <*> pure M.empty
+ <*> pure Nothing
+ <*> pure M.empty
diff --git a/Assistant/Types/NamedThread.hs b/Assistant/Types/NamedThread.hs
new file mode 100644
index 000000000..5dd1364ad
--- /dev/null
+++ b/Assistant/Types/NamedThread.hs
@@ -0,0 +1,21 @@
+{- named threads
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.Types.NamedThread where
+
+import Assistant.Monad
+import Assistant.Types.ThreadName
+
+{- Information about a named thread that can be run. -}
+data NamedThread = NamedThread Bool ThreadName (Assistant ())
+
+namedThread :: String -> Assistant () -> NamedThread
+namedThread = NamedThread True . ThreadName
+
+{- A named thread that can start running before the startup sanity check. -}
+namedThreadUnchecked :: String -> Assistant () -> NamedThread
+namedThreadUnchecked = NamedThread False . ThreadName
diff --git a/Assistant/Types/NetMessager.hs b/Assistant/Types/NetMessager.hs
new file mode 100644
index 000000000..0af262e9a
--- /dev/null
+++ b/Assistant/Types/NetMessager.hs
@@ -0,0 +1,155 @@
+{- git-annex assistant out of band network messager types
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.Types.NetMessager where
+
+import Common.Annex
+import Assistant.Pairing
+import Git.Types
+
+import qualified Data.Text as T
+import qualified Data.Set as S
+import qualified Data.Map as M
+import qualified Data.DList as D
+import Control.Concurrent.STM
+import Control.Concurrent.MSampleVar
+import Data.ByteString (ByteString)
+import qualified Data.ByteString.Char8 as B8
+import Data.Text (Text)
+
+{- Messages that can be sent out of band by a network messager. -}
+data NetMessage
+ -- indicate that pushes have been made to the repos with these uuids
+ = NotifyPush [UUID]
+ -- requests other clients to inform us of their presence
+ | QueryPresence
+ -- notification about a stage in the pairing process,
+ -- involving a client, and a UUID.
+ | PairingNotification PairStage ClientID UUID
+ -- used for git push over the network messager
+ | Pushing ClientID PushStage
+ deriving (Show, Eq, Ord)
+
+{- Something used to identify the client, or clients to send the message to. -}
+type ClientID = Text
+
+data PushStage
+ -- indicates that we have data to push over the out of band network
+ = CanPush UUID [Sha]
+ -- request that a git push be sent over the out of band network
+ | PushRequest UUID
+ -- indicates that a push is starting
+ | StartingPush UUID
+ -- a chunk of output of git receive-pack
+ | ReceivePackOutput SequenceNum ByteString
+ -- a chuck of output of git send-pack
+ | SendPackOutput SequenceNum ByteString
+ -- sent when git receive-pack exits, with its exit code
+ | ReceivePackDone ExitCode
+ deriving (Show, Eq, Ord)
+
+{- A sequence number. Incremented by one per packet in a sequence,
+ - starting with 1 for the first packet. 0 means sequence numbers are
+ - not being used. -}
+type SequenceNum = Int
+
+{- NetMessages that are important (and small), and should be stored to be
+ - resent when new clients are seen. -}
+isImportantNetMessage :: NetMessage -> Maybe ClientID
+isImportantNetMessage (Pushing c (CanPush _ _)) = Just c
+isImportantNetMessage (Pushing c (PushRequest _)) = Just c
+isImportantNetMessage _ = Nothing
+
+{- Checks if two important NetMessages are equivilant.
+ - That is to say, assuming they were sent to the same client,
+ - would it do the same thing for one as for the other? -}
+equivilantImportantNetMessages :: NetMessage -> NetMessage -> Bool
+equivilantImportantNetMessages (Pushing _ (CanPush _ _)) (Pushing _ (CanPush _ _)) = True
+equivilantImportantNetMessages (Pushing _ (PushRequest _)) (Pushing _ (PushRequest _)) = True
+equivilantImportantNetMessages _ _ = False
+
+readdressNetMessage :: NetMessage -> ClientID -> NetMessage
+readdressNetMessage (PairingNotification stage _ uuid) c = PairingNotification stage c uuid
+readdressNetMessage (Pushing _ stage) c = Pushing c stage
+readdressNetMessage m _ = m
+
+{- Convert a NetMessage to something that can be logged. -}
+logNetMessage :: NetMessage -> String
+logNetMessage (Pushing c stage) = show $ Pushing (logClientID c) $
+ case stage of
+ ReceivePackOutput n _ -> ReceivePackOutput n elided
+ SendPackOutput n _ -> SendPackOutput n elided
+ s -> s
+ where
+ elided = B8.pack "<elided>"
+logNetMessage (PairingNotification stage c uuid) =
+ show $ PairingNotification stage (logClientID c) uuid
+logNetMessage m = show m
+
+logClientID :: ClientID -> ClientID
+logClientID c = T.concat [T.take 1 c, T.pack $ show $ T.length c]
+
+{- Things that initiate either side of a push, but do not actually send data. -}
+isPushInitiation :: PushStage -> Bool
+isPushInitiation (PushRequest _) = True
+isPushInitiation (StartingPush _) = True
+isPushInitiation _ = False
+
+isPushNotice :: PushStage -> Bool
+isPushNotice (CanPush _ _) = True
+isPushNotice _ = False
+
+data PushSide = SendPack | ReceivePack
+ deriving (Eq, Ord, Show)
+
+pushDestinationSide :: PushStage -> PushSide
+pushDestinationSide (CanPush _ _) = ReceivePack
+pushDestinationSide (PushRequest _) = SendPack
+pushDestinationSide (StartingPush _) = ReceivePack
+pushDestinationSide (ReceivePackOutput _ _) = SendPack
+pushDestinationSide (SendPackOutput _ _) = ReceivePack
+pushDestinationSide (ReceivePackDone _) = SendPack
+
+type SideMap a = PushSide -> a
+
+mkSideMap :: STM a -> IO (SideMap a)
+mkSideMap gen = do
+ (sp, rp) <- atomically $ (,) <$> gen <*> gen
+ return $ lookupside sp rp
+ where
+ lookupside sp _ SendPack = sp
+ lookupside _ rp ReceivePack = rp
+
+getSide :: PushSide -> SideMap a -> a
+getSide side m = m side
+
+type Inboxes = TVar (M.Map ClientID (Int, D.DList NetMessage))
+
+data NetMessager = NetMessager
+ -- outgoing messages
+ { netMessages :: TChan NetMessage
+ -- important messages for each client
+ , importantNetMessages :: TMVar (M.Map ClientID (S.Set NetMessage))
+ -- important messages that are believed to have been sent to a client
+ , sentImportantNetMessages :: TMVar (M.Map ClientID (S.Set NetMessage))
+ -- write to this to restart the net messager
+ , netMessagerRestart :: MSampleVar ()
+ -- queue of incoming messages that request the initiation of pushes
+ , netMessagerPushInitiations :: SideMap (TMVar [NetMessage])
+ -- incoming messages containing data for a running
+ -- (or not yet started) push
+ , netMessagerInboxes :: SideMap Inboxes
+ }
+
+newNetMessager :: IO NetMessager
+newNetMessager = NetMessager
+ <$> atomically newTChan
+ <*> atomically (newTMVar M.empty)
+ <*> atomically (newTMVar M.empty)
+ <*> newEmptySV
+ <*> mkSideMap newEmptyTMVar
+ <*> mkSideMap (newTVar M.empty)
diff --git a/Assistant/Types/Pushes.hs b/Assistant/Types/Pushes.hs
new file mode 100644
index 000000000..99e0ee162
--- /dev/null
+++ b/Assistant/Types/Pushes.hs
@@ -0,0 +1,24 @@
+{- git-annex assistant push tracking
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.Types.Pushes where
+
+import Common.Annex
+
+import Control.Concurrent.STM
+import Data.Time.Clock
+import qualified Data.Map as M
+
+{- Track the most recent push failure for each remote. -}
+type PushMap = M.Map Remote UTCTime
+type FailedPushMap = TMVar PushMap
+
+{- The TMVar starts empty, and is left empty when there are no
+ - failed pushes. This way we can block until there are some failed pushes.
+ -}
+newFailedPushMap :: IO FailedPushMap
+newFailedPushMap = atomically newEmptyTMVar
diff --git a/Assistant/Types/RepoProblem.hs b/Assistant/Types/RepoProblem.hs
new file mode 100644
index 000000000..ece5a5286
--- /dev/null
+++ b/Assistant/Types/RepoProblem.hs
@@ -0,0 +1,28 @@
+{- git-annex assistant repository problem tracking
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.Types.RepoProblem where
+
+import Types
+import Utility.TList
+
+import Control.Concurrent.STM
+import Data.Function
+
+data RepoProblem = RepoProblem
+ { problemUUID :: UUID
+ , afterFix :: IO ()
+ }
+
+{- The afterFix actions are assumed to all be equivilant. -}
+sameRepoProblem :: RepoProblem -> RepoProblem -> Bool
+sameRepoProblem = (==) `on` problemUUID
+
+type RepoProblemChan = TList RepoProblem
+
+newRepoProblemChan :: IO RepoProblemChan
+newRepoProblemChan = atomically newTList
diff --git a/Assistant/Types/ScanRemotes.hs b/Assistant/Types/ScanRemotes.hs
new file mode 100644
index 000000000..8219f9baf
--- /dev/null
+++ b/Assistant/Types/ScanRemotes.hs
@@ -0,0 +1,25 @@
+{- git-annex assistant remotes needing scanning
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.Types.ScanRemotes where
+
+import Common.Annex
+
+import Control.Concurrent.STM
+import qualified Data.Map as M
+
+data ScanInfo = ScanInfo
+ { scanPriority :: Float
+ , fullScan :: Bool
+ }
+
+type ScanRemoteMap = TMVar (M.Map Remote ScanInfo)
+
+{- The TMVar starts empty, and is left empty when there are no remotes
+ - to scan. -}
+newScanRemoteMap :: IO ScanRemoteMap
+newScanRemoteMap = atomically newEmptyTMVar
diff --git a/Assistant/Types/ThreadName.hs b/Assistant/Types/ThreadName.hs
new file mode 100644
index 000000000..c8d264a38
--- /dev/null
+++ b/Assistant/Types/ThreadName.hs
@@ -0,0 +1,14 @@
+{- name of a thread
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.Types.ThreadName where
+
+newtype ThreadName = ThreadName String
+ deriving (Eq, Read, Show, Ord)
+
+fromThreadName :: ThreadName -> String
+fromThreadName (ThreadName n) = n
diff --git a/Assistant/Types/ThreadedMonad.hs b/Assistant/Types/ThreadedMonad.hs
new file mode 100644
index 000000000..1a2aa7eb7
--- /dev/null
+++ b/Assistant/Types/ThreadedMonad.hs
@@ -0,0 +1,38 @@
+{- making the Annex monad available across threads
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.Types.ThreadedMonad where
+
+import Common.Annex
+import qualified Annex
+
+import Control.Concurrent
+import Data.Tuple
+
+{- The Annex state is stored in a MVar, so that threaded actions can access
+ - it. -}
+type ThreadState = MVar Annex.AnnexState
+
+{- Stores the Annex state in a MVar.
+ -
+ - Once the action is finished, retrieves the state from the MVar.
+ -}
+withThreadState :: (ThreadState -> Annex a) -> Annex a
+withThreadState a = do
+ state <- Annex.getState id
+ mvar <- liftIO $ newMVar state
+ r <- a mvar
+ newstate <- liftIO $ takeMVar mvar
+ Annex.changeState (const newstate)
+ return r
+
+{- Runs an Annex action, using the state from the MVar.
+ -
+ - This serializes calls by threads; only one thread can run in Annex at a
+ - time. -}
+runThreadState :: ThreadState -> Annex a -> IO a
+runThreadState mvar a = modifyMVar mvar $ \state -> swap <$> Annex.run state a
diff --git a/Assistant/Types/TransferQueue.hs b/Assistant/Types/TransferQueue.hs
new file mode 100644
index 000000000..e4bf2ae92
--- /dev/null
+++ b/Assistant/Types/TransferQueue.hs
@@ -0,0 +1,29 @@
+{- git-annex assistant pending transfer queue
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.Types.TransferQueue where
+
+import Common.Annex
+import Logs.Transfer
+
+import Control.Concurrent.STM
+import Utility.TList
+
+data TransferQueue = TransferQueue
+ { queuesize :: TVar Int
+ , queuelist :: TList (Transfer, TransferInfo)
+ , deferreddownloads :: TList (Key, AssociatedFile)
+ }
+
+data Schedule = Next | Later
+ deriving (Eq)
+
+newTransferQueue :: IO TransferQueue
+newTransferQueue = atomically $ TransferQueue
+ <$> newTVar 0
+ <*> newTList
+ <*> newTList
diff --git a/Assistant/Types/TransferSlots.hs b/Assistant/Types/TransferSlots.hs
new file mode 100644
index 000000000..5140995a3
--- /dev/null
+++ b/Assistant/Types/TransferSlots.hs
@@ -0,0 +1,34 @@
+{- git-annex assistant transfer slots
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE DeriveDataTypeable #-}
+
+module Assistant.Types.TransferSlots where
+
+import qualified Control.Exception as E
+import qualified Control.Concurrent.MSemN as MSemN
+import Data.Typeable
+
+type TransferSlots = MSemN.MSemN Int
+
+{- A special exception that can be thrown to pause or resume a transfer, while
+ - keeping its slot in use. -}
+data TransferException = PauseTransfer | ResumeTransfer
+ deriving (Show, Eq, Typeable)
+
+instance E.Exception TransferException
+
+{- Number of concurrent transfers allowed to be run from the assistant.
+ -
+ - Transfers launched by other means, including by remote assistants,
+ - do not currently take up slots.
+ -}
+numSlots :: Int
+numSlots = 1
+
+newTransferSlots :: IO TransferSlots
+newTransferSlots = MSemN.new numSlots
diff --git a/Assistant/Types/TransferrerPool.hs b/Assistant/Types/TransferrerPool.hs
new file mode 100644
index 000000000..2727a6919
--- /dev/null
+++ b/Assistant/Types/TransferrerPool.hs
@@ -0,0 +1,23 @@
+{- A pool of "git-annex transferkeys" processes
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.Types.TransferrerPool where
+
+import Common.Annex
+
+import Control.Concurrent.STM
+
+type TransferrerPool = TChan Transferrer
+
+data Transferrer = Transferrer
+ { transferrerRead :: Handle
+ , transferrerWrite :: Handle
+ , transferrerHandle :: ProcessHandle
+ }
+
+newTransferrerPool :: IO TransferrerPool
+newTransferrerPool = newTChanIO
diff --git a/Assistant/Types/UrlRenderer.hs b/Assistant/Types/UrlRenderer.hs
new file mode 100644
index 000000000..521905bf3
--- /dev/null
+++ b/Assistant/Types/UrlRenderer.hs
@@ -0,0 +1,26 @@
+{- webapp url renderer access from the assistant
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Assistant.Types.UrlRenderer (
+ UrlRenderer,
+ newUrlRenderer
+) where
+
+#ifdef WITH_WEBAPP
+
+import Assistant.WebApp (UrlRenderer, newUrlRenderer)
+
+#else
+
+data UrlRenderer = UrlRenderer -- dummy type
+
+newUrlRenderer :: IO UrlRenderer
+newUrlRenderer = return UrlRenderer
+
+#endif
diff --git a/Assistant/XMPP.hs b/Assistant/XMPP.hs
new file mode 100644
index 000000000..09b7daf4e
--- /dev/null
+++ b/Assistant/XMPP.hs
@@ -0,0 +1,273 @@
+{- core xmpp support
+ -
+ - Copyright 2012-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE OverloadedStrings #-}
+
+module Assistant.XMPP where
+
+import Assistant.Common
+import Assistant.Types.NetMessager
+import Assistant.Pairing
+import Git.Sha (extractSha)
+
+import Network.Protocol.XMPP hiding (Node)
+import Data.Text (Text)
+import qualified Data.Text as T
+import qualified Data.Map as M
+import Data.ByteString (ByteString)
+import qualified Data.ByteString as B
+import Data.XML.Types
+import qualified "dataenc" Codec.Binary.Base64 as B64
+
+{- Name of the git-annex tag, in our own XML namespace.
+ - (Not using a namespace URL to avoid unnecessary bloat.) -}
+gitAnnexTagName :: Name
+gitAnnexTagName = "{git-annex}git-annex"
+
+{- Creates a git-annex tag containing a particular attribute and value. -}
+gitAnnexTag :: Name -> Text -> Element
+gitAnnexTag attr val = gitAnnexTagContent attr val []
+
+{- Also with some content. -}
+gitAnnexTagContent :: Name -> Text -> [Node] -> Element
+gitAnnexTagContent attr val = Element gitAnnexTagName [(attr, [ContentText val])]
+
+isGitAnnexTag :: Element -> Bool
+isGitAnnexTag t = elementName t == gitAnnexTagName
+
+{- Things that a git-annex tag can inserted into. -}
+class GitAnnexTaggable a where
+ insertGitAnnexTag :: a -> Element -> a
+
+ extractGitAnnexTag :: a -> Maybe Element
+
+ hasGitAnnexTag :: a -> Bool
+ hasGitAnnexTag = isJust . extractGitAnnexTag
+
+instance GitAnnexTaggable Message where
+ insertGitAnnexTag m elt = m { messagePayloads = elt : messagePayloads m }
+ extractGitAnnexTag = headMaybe . filter isGitAnnexTag . messagePayloads
+
+instance GitAnnexTaggable Presence where
+ -- always mark extended away and set presence priority to negative
+ insertGitAnnexTag p elt = p
+ { presencePayloads = extendedAway : negativePriority : elt : presencePayloads p }
+ extractGitAnnexTag = headMaybe . filter isGitAnnexTag . presencePayloads
+
+data GitAnnexTagInfo = GitAnnexTagInfo
+ { tagAttr :: Name
+ , tagValue :: Text
+ , tagElement :: Element
+ }
+
+type Decoder = Message -> GitAnnexTagInfo -> Maybe NetMessage
+
+gitAnnexTagInfo :: GitAnnexTaggable a => a -> Maybe GitAnnexTagInfo
+gitAnnexTagInfo v = case extractGitAnnexTag v of
+ {- Each git-annex tag has a single attribute. -}
+ Just (tag@(Element _ [(attr, _)] _)) -> GitAnnexTagInfo
+ <$> pure attr
+ <*> attributeText attr tag
+ <*> pure tag
+ _ -> Nothing
+
+{- A presence with a git-annex tag in it.
+ - Also includes a status tag, which may be visible in XMPP clients. -}
+gitAnnexPresence :: Element -> Presence
+gitAnnexPresence = insertGitAnnexTag $ addStatusTag $ emptyPresence PresenceAvailable
+ where
+ addStatusTag p = p
+ { presencePayloads = status : presencePayloads p }
+ status = Element "status" [] [statusMessage]
+ statusMessage = NodeContent $ ContentText $ T.pack "git-annex"
+
+{- A presence with an empty git-annex tag in it, used for letting other
+ - clients know we're around and are a git-annex client. -}
+gitAnnexSignature :: Presence
+gitAnnexSignature = gitAnnexPresence $ Element gitAnnexTagName [] []
+
+{- XMPP client to server ping -}
+xmppPing :: JID -> IQ
+xmppPing selfjid = (emptyIQ IQGet)
+ { iqID = Just "c2s1"
+ , iqFrom = Just selfjid
+ , iqTo = Just $ JID Nothing (jidDomain selfjid) Nothing
+ , iqPayload = Just $ Element xmppPingTagName [] []
+ }
+
+xmppPingTagName :: Name
+xmppPingTagName = "{urn:xmpp}ping"
+
+{- A message with a git-annex tag in it. -}
+gitAnnexMessage :: Element -> JID -> JID -> Message
+gitAnnexMessage elt tojid fromjid = (insertGitAnnexTag silentMessage elt)
+ { messageTo = Just tojid
+ , messageFrom = Just fromjid
+ }
+
+{- A notification that we've pushed to some repositories, listing their
+ - UUIDs. -}
+pushNotification :: [UUID] -> Presence
+pushNotification = gitAnnexPresence . gitAnnexTag pushAttr . encodePushNotification
+
+encodePushNotification :: [UUID] -> Text
+encodePushNotification = T.intercalate uuidSep . map (T.pack . fromUUID)
+
+decodePushNotification :: Text -> [UUID]
+decodePushNotification = map (toUUID . T.unpack) . T.splitOn uuidSep
+
+uuidSep :: Text
+uuidSep = ","
+
+{- A request for other git-annex clients to send presence. -}
+presenceQuery :: Presence
+presenceQuery = gitAnnexPresence $ gitAnnexTag queryAttr T.empty
+
+{- A notification about a stage of pairing. -}
+pairingNotification :: PairStage -> UUID -> JID -> JID -> Message
+pairingNotification pairstage u = gitAnnexMessage $
+ gitAnnexTag pairAttr $ encodePairingNotification pairstage u
+
+encodePairingNotification :: PairStage -> UUID -> Text
+encodePairingNotification pairstage u = T.unwords $ map T.pack
+ [ show pairstage
+ , fromUUID u
+ ]
+
+decodePairingNotification :: Decoder
+decodePairingNotification m = parse . words . T.unpack . tagValue
+ where
+ parse [stage, u] = PairingNotification
+ <$> readish stage
+ <*> (formatJID <$> messageFrom m)
+ <*> pure (toUUID u)
+ parse _ = Nothing
+
+pushMessage :: PushStage -> JID -> JID -> Message
+pushMessage = gitAnnexMessage . encode
+ where
+ encode (CanPush u shas) =
+ gitAnnexTag canPushAttr $ T.pack $ unwords $
+ fromUUID u : map show shas
+ encode (PushRequest u) =
+ gitAnnexTag pushRequestAttr $ T.pack $ fromUUID u
+ encode (StartingPush u) =
+ gitAnnexTag startingPushAttr $ T.pack $ fromUUID u
+ encode (ReceivePackOutput n b) =
+ gitAnnexTagContent receivePackAttr (val n) $ encodeTagContent b
+ encode (SendPackOutput n b) =
+ gitAnnexTagContent sendPackAttr (val n) $ encodeTagContent b
+ encode (ReceivePackDone code) =
+ gitAnnexTag receivePackDoneAttr $ val $ encodeExitCode code
+ val = T.pack . show
+
+decodeMessage :: Message -> Maybe NetMessage
+decodeMessage m = decode =<< gitAnnexTagInfo m
+ where
+ decode i = M.lookup (tagAttr i) decoders >>= rundecoder i
+ rundecoder i d = d m i
+ decoders = M.fromList $ zip
+ [ pairAttr
+ , canPushAttr
+ , pushRequestAttr
+ , startingPushAttr
+ , receivePackAttr
+ , sendPackAttr
+ , receivePackDoneAttr
+ ]
+ [ decodePairingNotification
+ , pushdecoder $ shasgen CanPush
+ , pushdecoder $ gen PushRequest
+ , pushdecoder $ gen StartingPush
+ , pushdecoder $ seqgen ReceivePackOutput
+ , pushdecoder $ seqgen SendPackOutput
+ , pushdecoder $
+ fmap (ReceivePackDone . decodeExitCode) . readish .
+ T.unpack . tagValue
+ ]
+ pushdecoder a m' i = Pushing
+ <$> (formatJID <$> messageFrom m')
+ <*> a i
+ gen c i = c . toUUID <$> headMaybe (words (T.unpack (tagValue i)))
+ seqgen c i = do
+ packet <- decodeTagContent $ tagElement i
+ let seqnum = fromMaybe 0 $ readish $ T.unpack $ tagValue i
+ return $ c seqnum packet
+ shasgen c i = do
+ let (u:shas) = words $ T.unpack $ tagValue i
+ return $ c (toUUID u) (mapMaybe extractSha shas)
+
+decodeExitCode :: Int -> ExitCode
+decodeExitCode 0 = ExitSuccess
+decodeExitCode n = ExitFailure n
+
+encodeExitCode :: ExitCode -> Int
+encodeExitCode ExitSuccess = 0
+encodeExitCode (ExitFailure n) = n
+
+{- Base 64 encoding a ByteString to use as the content of a tag. -}
+encodeTagContent :: ByteString -> [Node]
+encodeTagContent b = [NodeContent $ ContentText $ T.pack $ B64.encode $ B.unpack b]
+
+decodeTagContent :: Element -> Maybe ByteString
+decodeTagContent elt = B.pack <$> B64.decode s
+ where
+ s = T.unpack $ T.concat $ elementText elt
+
+{- The JID without the client part. -}
+baseJID :: JID -> JID
+baseJID j = JID (jidNode j) (jidDomain j) Nothing
+
+{- An XMPP chat message with an empty body. This should not be displayed
+ - by clients, but can be used for communications. -}
+silentMessage :: Message
+silentMessage = (emptyMessage MessageChat)
+ { messagePayloads = [ emptybody ] }
+ where
+ emptybody = Element
+ { elementName = "body"
+ , elementAttributes = []
+ , elementNodes = []
+ }
+
+{- Add to a presence to mark its client as extended away. -}
+extendedAway :: Element
+extendedAway = Element "show" [] [NodeContent $ ContentText "xa"]
+
+{- Add to a presence to give it a negative priority. -}
+negativePriority :: Element
+negativePriority = Element "priority" [] [NodeContent $ ContentText "-1"]
+
+pushAttr :: Name
+pushAttr = "push"
+
+queryAttr :: Name
+queryAttr = "query"
+
+pairAttr :: Name
+pairAttr = "pair"
+
+canPushAttr :: Name
+canPushAttr = "canpush"
+
+pushRequestAttr :: Name
+pushRequestAttr = "pushrequest"
+
+startingPushAttr :: Name
+startingPushAttr = "startingpush"
+
+receivePackAttr :: Name
+receivePackAttr = "rp"
+
+sendPackAttr :: Name
+sendPackAttr = "sp"
+
+receivePackDoneAttr :: Name
+receivePackDoneAttr = "rpdone"
+
+shasAttr :: Name
+shasAttr = "shas"
diff --git a/Assistant/XMPP/Buddies.hs b/Assistant/XMPP/Buddies.hs
new file mode 100644
index 000000000..0c466e51c
--- /dev/null
+++ b/Assistant/XMPP/Buddies.hs
@@ -0,0 +1,87 @@
+{- xmpp buddies
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.XMPP.Buddies where
+
+import Assistant.XMPP
+import Common.Annex
+import Assistant.Types.Buddies
+
+import Network.Protocol.XMPP
+import qualified Data.Map as M
+import qualified Data.Set as S
+import Data.Text (Text)
+import qualified Data.Text as T
+
+genBuddyKey :: JID -> BuddyKey
+genBuddyKey j = BuddyKey $ formatJID $ baseJID j
+
+buddyName :: JID -> Text
+buddyName j = maybe (T.pack "") strNode (jidNode j)
+
+ucFirst :: Text -> Text
+ucFirst s = let (first, rest) = T.splitAt 1 s
+ in T.concat [T.toUpper first, rest]
+
+{- Summary of info about a buddy.
+ -
+ - If the buddy has no clients at all anymore, returns Nothing. -}
+buddySummary :: [JID] -> Buddy -> Maybe (Text, Bool, Bool, Bool, BuddyKey)
+buddySummary pairedwith b = case clients of
+ ((Client j):_) -> Just (buddyName j, away, canpair, alreadypaired j, genBuddyKey j)
+ [] -> Nothing
+ where
+ away = S.null (buddyPresent b) && S.null (buddyAssistants b)
+ canpair = not $ S.null (buddyAssistants b)
+ clients = S.toList $ buddyPresent b `S.union` buddyAway b `S.union` buddyAssistants b
+ alreadypaired j = baseJID j `elem` pairedwith
+
+{- Updates the buddies with XMPP presence info. -}
+updateBuddies :: Presence -> Buddies -> Buddies
+updateBuddies p@(Presence { presenceFrom = Just jid }) = M.alter update key
+ where
+ key = genBuddyKey jid
+ update (Just b) = Just $ applyPresence p b
+ update Nothing = newBuddy p
+updateBuddies _ = id
+
+{- Creates a new buddy based on XMPP presence info. -}
+newBuddy :: Presence -> Maybe Buddy
+newBuddy p
+ | presenceType p == PresenceAvailable = go
+ | presenceType p == PresenceUnavailable = go
+ | otherwise = Nothing
+ where
+ go = make <$> presenceFrom p
+ make _jid = applyPresence p $ Buddy
+ { buddyPresent = S.empty
+ , buddyAway = S.empty
+ , buddyAssistants = S.empty
+ , buddyPairing = False
+ }
+
+applyPresence :: Presence -> Buddy -> Buddy
+applyPresence p b = fromMaybe b $! go <$> presenceFrom p
+ where
+ go jid
+ | presenceType p == PresenceUnavailable = b
+ { buddyAway = addto $ buddyAway b
+ , buddyPresent = removefrom $ buddyPresent b
+ , buddyAssistants = removefrom $ buddyAssistants b
+ }
+ | hasGitAnnexTag p = b
+ { buddyAssistants = addto $ buddyAssistants b
+ , buddyAway = removefrom $ buddyAway b }
+ | presenceType p == PresenceAvailable = b
+ { buddyPresent = addto $ buddyPresent b
+ , buddyAway = removefrom $ buddyAway b
+ }
+ | otherwise = b
+ where
+ client = Client jid
+ removefrom = S.filter (/= client)
+ addto = S.insert client
diff --git a/Assistant/XMPP/Client.hs b/Assistant/XMPP/Client.hs
new file mode 100644
index 000000000..677bb2ff3
--- /dev/null
+++ b/Assistant/XMPP/Client.hs
@@ -0,0 +1,84 @@
+{- xmpp client support
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Assistant.XMPP.Client where
+
+import Assistant.Common
+import Utility.SRV
+import Creds
+
+import Network.Protocol.XMPP
+import Network
+import Control.Concurrent
+import qualified Data.Text as T
+import Control.Exception (SomeException)
+
+{- Everything we need to know to connect to an XMPP server. -}
+data XMPPCreds = XMPPCreds
+ { xmppUsername :: T.Text
+ , xmppPassword :: T.Text
+ , xmppHostname :: HostName
+ , xmppPort :: Int
+ , xmppJID :: T.Text
+ }
+ deriving (Read, Show)
+
+connectXMPP :: XMPPCreds -> (JID -> XMPP a) -> IO [(HostPort, Either SomeException ())]
+connectXMPP c a = case parseJID (xmppJID c) of
+ Nothing -> error "bad JID"
+ Just jid -> connectXMPP' jid c a
+
+{- Do a SRV lookup, but if it fails, fall back to the cached xmppHostname. -}
+connectXMPP' :: JID -> XMPPCreds -> (JID -> XMPP a) -> IO [(HostPort, Either SomeException ())]
+connectXMPP' jid c a = reverse <$> (handle =<< lookupSRV srvrecord)
+ where
+ srvrecord = mkSRVTcp "xmpp-client" $
+ T.unpack $ strDomain $ jidDomain jid
+ serverjid = JID Nothing (jidDomain jid) Nothing
+
+ handle [] = do
+ let h = xmppHostname c
+ let p = PortNumber $ fromIntegral $ xmppPort c
+ r <- run h p $ a jid
+ return [r]
+ handle srvs = go [] srvs
+
+ go l [] = return l
+ go l ((h,p):rest) = do
+ {- Try each SRV record in turn, until one connects,
+ - at which point the MVar will be full. -}
+ mv <- newEmptyMVar
+ r <- run h p $ do
+ liftIO $ putMVar mv ()
+ a jid
+ ifM (isEmptyMVar mv)
+ ( go (r : l) rest
+ , return (r : l)
+ )
+
+ {- Async exceptions are let through so the XMPP thread can
+ - be killed. -}
+ run h p a' = do
+ r <- tryNonAsync $
+ runClientError (Server serverjid h p) jid
+ (xmppUsername c) (xmppPassword c) (void a')
+ return ((h, p), r)
+
+{- XMPP runClient, that throws errors rather than returning an Either -}
+runClientError :: Server -> JID -> T.Text -> T.Text -> XMPP a -> IO a
+runClientError s j u p x = either (error . show) return =<< runClient s j u p x
+
+getXMPPCreds :: Annex (Maybe XMPPCreds)
+getXMPPCreds = parse <$> readCacheCreds xmppCredsFile
+ where
+ parse s = readish =<< s
+
+setXMPPCreds :: XMPPCreds -> Annex ()
+setXMPPCreds creds = writeCacheCreds (show creds) xmppCredsFile
+
+xmppCredsFile :: FilePath
+xmppCredsFile = "xmpp"
diff --git a/Assistant/XMPP/Git.hs b/Assistant/XMPP/Git.hs
new file mode 100644
index 000000000..97b974f82
--- /dev/null
+++ b/Assistant/XMPP/Git.hs
@@ -0,0 +1,382 @@
+{- git over XMPP
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Assistant.XMPP.Git where
+
+import Assistant.Common
+import Assistant.NetMessager
+import Assistant.Types.NetMessager
+import Assistant.XMPP
+import Assistant.XMPP.Buddies
+import Assistant.DaemonStatus
+import Assistant.Alert
+import Assistant.MakeRemote
+import Assistant.Sync
+import qualified Command.Sync
+import qualified Annex.Branch
+import Annex.UUID
+import Logs.UUID
+import Annex.TaggedPush
+import Annex.CatFile
+import Config
+import Git
+import qualified Git.Branch
+import Config.Files
+import qualified Types.Remote as Remote
+import qualified Remote as Remote
+import Remote.List
+import Utility.FileMode
+import Utility.Shell
+import Utility.Env
+
+import Network.Protocol.XMPP
+import qualified Data.Text as T
+import System.Posix.Types
+import System.Process (std_in, std_out, std_err)
+import Control.Concurrent
+import System.Timeout
+import qualified Data.ByteString as B
+import qualified Data.Map as M
+
+{- Largest chunk of data to send in a single XMPP message. -}
+chunkSize :: Int
+chunkSize = 4096
+
+{- How long to wait for an expected message before assuming the other side
+ - has gone away and canceling a push.
+ -
+ - This needs to be long enough to allow a message of up to 2+ times
+ - chunkSize to propigate up to a XMPP server, perhaps across to another
+ - server, and back down to us. On the other hand, other XMPP pushes can be
+ - delayed for running until the timeout is reached, so it should not be
+ - excessive.
+ -}
+xmppTimeout :: Int
+xmppTimeout = 120000000 -- 120 seconds
+
+finishXMPPPairing :: JID -> UUID -> Assistant ()
+finishXMPPPairing jid u = void $ alertWhile alert $
+ makeXMPPGitRemote buddy (baseJID jid) u
+ where
+ buddy = T.unpack $ buddyName jid
+ alert = pairRequestAcknowledgedAlert buddy Nothing
+
+gitXMPPLocation :: JID -> String
+gitXMPPLocation jid = "xmpp::" ++ T.unpack (formatJID $ baseJID jid)
+
+makeXMPPGitRemote :: String -> JID -> UUID -> Assistant Bool
+makeXMPPGitRemote buddyname jid u = do
+ remote <- liftAnnex $ addRemote $
+ makeGitRemote buddyname $ gitXMPPLocation jid
+ liftAnnex $ storeUUID (remoteConfig (Remote.repo remote) "uuid") u
+ liftAnnex $ void remoteListRefresh
+ remote' <- liftAnnex $ fromMaybe (error "failed to add remote")
+ <$> Remote.byName (Just buddyname)
+ syncRemote remote'
+ return True
+
+{- Pushes over XMPP, communicating with a specific client.
+ - Runs an arbitrary IO action to push, which should run git-push with
+ - an xmpp:: url.
+ -
+ - To handle xmpp:: urls, git push will run git-remote-xmpp, which is
+ - injected into its PATH, and in turn runs git-annex xmppgit. The
+ - dataflow them becomes:
+ -
+ - git push <--> git-annex xmppgit <--> xmppPush <-------> xmpp
+ - |
+ - git receive-pack <--> xmppReceivePack <---------------> xmpp
+ -
+ - The pipe between git-annex xmppgit and us is set up and communicated
+ - using two environment variables, relayIn and relayOut, that are set
+ - to the file descriptors to use. Another, relayControl, is used to
+ - propigate the exit status of git receive-pack.
+ -
+ - We listen at the other end of the pipe and relay to and from XMPP.
+ -}
+xmppPush :: ClientID -> (Git.Repo -> IO Bool) -> Assistant Bool
+xmppPush cid gitpush = do
+ u <- liftAnnex getUUID
+ sendNetMessage $ Pushing cid (StartingPush u)
+
+ (Fd inf, writepush) <- liftIO createPipe
+ (readpush, Fd outf) <- liftIO createPipe
+ (Fd controlf, writecontrol) <- liftIO createPipe
+
+ tmpdir <- gettmpdir
+ installwrapper tmpdir
+
+ env <- liftIO getEnvironment
+ path <- liftIO getSearchPath
+ let myenv = M.fromList
+ [ ("PATH", intercalate [searchPathSeparator] $ tmpdir:path)
+ , (relayIn, show inf)
+ , (relayOut, show outf)
+ , (relayControl, show controlf)
+ ]
+ `M.union` M.fromList env
+
+ inh <- liftIO $ fdToHandle readpush
+ outh <- liftIO $ fdToHandle writepush
+ controlh <- liftIO $ fdToHandle writecontrol
+
+ t1 <- forkIO <~> toxmpp 0 inh
+ t2 <- forkIO <~> fromxmpp outh controlh
+
+ {- This can take a long time to run, so avoid running it in the
+ - Annex monad. Also, override environment. -}
+ g <- liftAnnex gitRepo
+ r <- liftIO $ gitpush $ g { gitEnv = Just $ M.toList myenv }
+
+ liftIO $ do
+ mapM_ killThread [t1, t2]
+ mapM_ hClose [inh, outh, controlh]
+ mapM_ closeFd [Fd inf, Fd outf, Fd controlf]
+
+ return r
+ where
+ toxmpp seqnum inh = do
+ b <- liftIO $ B.hGetSome inh chunkSize
+ if B.null b
+ then liftIO $ killThread =<< myThreadId
+ else do
+ let seqnum' = succ seqnum
+ sendNetMessage $ Pushing cid $
+ SendPackOutput seqnum' b
+ toxmpp seqnum' inh
+
+ fromxmpp outh controlh = withPushMessagesInSequence cid SendPack handle
+ where
+ handle (Just (Pushing _ (ReceivePackOutput _ b))) =
+ liftIO $ writeChunk outh b
+ handle (Just (Pushing _ (ReceivePackDone exitcode))) =
+ liftIO $ do
+ hPrint controlh exitcode
+ hFlush controlh
+ handle (Just _) = noop
+ handle Nothing = do
+ debug ["timeout waiting for git receive-pack output via XMPP"]
+ -- Send a synthetic exit code to git-annex
+ -- xmppgit, which will exit and cause git push
+ -- to die.
+ liftIO $ do
+ hPrint controlh (ExitFailure 1)
+ hFlush controlh
+ killThread =<< myThreadId
+
+ installwrapper tmpdir = liftIO $ do
+ createDirectoryIfMissing True tmpdir
+ let wrapper = tmpdir </> "git-remote-xmpp"
+ program <- readProgramFile
+ writeFile wrapper $ unlines
+ [ shebang_local
+ , "exec " ++ program ++ " xmppgit"
+ ]
+ modifyFileMode wrapper $ addModes executeModes
+
+ {- Use GIT_ANNEX_TMP_DIR if set, since that may be a better temp
+ - dir (ie, not on a crippled filesystem where we can't make
+ - the wrapper executable). -}
+ gettmpdir = do
+ v <- liftIO $ getEnv "GIT_ANNEX_TMP_DIR"
+ case v of
+ Nothing -> do
+ tmp <- liftAnnex $ fromRepo gitAnnexTmpDir
+ return $ tmp </> "xmppgit"
+ Just d -> return $ d </> "xmppgit"
+
+type EnvVar = String
+
+envVar :: String -> EnvVar
+envVar s = "GIT_ANNEX_XMPPGIT_" ++ s
+
+relayIn :: EnvVar
+relayIn = envVar "IN"
+
+relayOut :: EnvVar
+relayOut = envVar "OUT"
+
+relayControl :: EnvVar
+relayControl = envVar "CONTROL"
+
+relayHandle :: EnvVar -> IO Handle
+relayHandle var = do
+ v <- getEnv var
+ case readish =<< v of
+ Nothing -> error $ var ++ " not set"
+ Just n -> fdToHandle $ Fd n
+
+{- Called by git-annex xmppgit.
+ -
+ - git-push is talking to us on stdin
+ - we're talking to git-push on stdout
+ - git-receive-pack is talking to us on relayIn (via XMPP)
+ - we're talking to git-receive-pack on relayOut (via XMPP)
+ - git-receive-pack's exit code will be passed to us on relayControl
+ -}
+xmppGitRelay :: IO ()
+xmppGitRelay = do
+ flip relay stdout =<< relayHandle relayIn
+ relay stdin =<< relayHandle relayOut
+ code <- hGetLine =<< relayHandle relayControl
+ exitWith $ fromMaybe (ExitFailure 1) $ readish code
+ where
+ {- Is it possible to set up pipes and not need to copy the data
+ - ourselves? See splice(2) -}
+ relay fromh toh = void $ forkIO $ forever $ do
+ b <- B.hGetSome fromh chunkSize
+ when (B.null b) $ do
+ hClose fromh
+ hClose toh
+ killThread =<< myThreadId
+ writeChunk toh b
+
+{- Relays git receive-pack stdin and stdout via XMPP, as well as propigating
+ - its exit status to XMPP. -}
+xmppReceivePack :: ClientID -> Assistant Bool
+xmppReceivePack cid = do
+ repodir <- liftAnnex $ fromRepo repoPath
+ let p = (proc "git" ["receive-pack", repodir])
+ { std_in = CreatePipe
+ , std_out = CreatePipe
+ , std_err = Inherit
+ }
+ (Just inh, Just outh, _, pid) <- liftIO $ createProcess p
+ readertid <- forkIO <~> relayfromxmpp inh
+ relaytoxmpp 0 outh
+ code <- liftIO $ waitForProcess pid
+ void $ sendNetMessage $ Pushing cid $ ReceivePackDone code
+ liftIO $ do
+ killThread readertid
+ hClose inh
+ hClose outh
+ return $ code == ExitSuccess
+ where
+ relaytoxmpp seqnum outh = do
+ b <- liftIO $ B.hGetSome outh chunkSize
+ -- empty is EOF, so exit
+ unless (B.null b) $ do
+ let seqnum' = succ seqnum
+ sendNetMessage $ Pushing cid $ ReceivePackOutput seqnum' b
+ relaytoxmpp seqnum' outh
+ relayfromxmpp inh = withPushMessagesInSequence cid ReceivePack handle
+ where
+ handle (Just (Pushing _ (SendPackOutput _ b))) =
+ liftIO $ writeChunk inh b
+ handle (Just _) = noop
+ handle Nothing = do
+ debug ["timeout waiting for git send-pack output via XMPP"]
+ -- closing the handle will make git receive-pack exit
+ liftIO $ do
+ hClose inh
+ killThread =<< myThreadId
+
+xmppRemotes :: ClientID -> UUID -> Assistant [Remote]
+xmppRemotes cid theiruuid = case baseJID <$> parseJID cid of
+ Nothing -> return []
+ Just jid -> do
+ let loc = gitXMPPLocation jid
+ um <- liftAnnex uuidMap
+ filter (matching loc . Remote.repo) . filter (knownuuid um) . syncGitRemotes
+ <$> getDaemonStatus
+ where
+ matching loc r = repoIsUrl r && repoLocation r == loc
+ knownuuid um r = Remote.uuid r == theiruuid || M.member theiruuid um
+
+{- Returns the ClientID that it pushed to. -}
+runPush :: (Remote -> Assistant ()) -> NetMessage -> Assistant (Maybe ClientID)
+runPush checkcloudrepos (Pushing cid (PushRequest theiruuid)) =
+ go =<< liftAnnex (inRepo Git.Branch.current)
+ where
+ go Nothing = return Nothing
+ go (Just branch) = do
+ rs <- xmppRemotes cid theiruuid
+ liftAnnex $ Annex.Branch.commit "update"
+ (g, u) <- liftAnnex $ (,)
+ <$> gitRepo
+ <*> getUUID
+ liftIO $ Command.Sync.updateBranch (Command.Sync.syncBranch branch) g
+ selfjid <- ((T.unpack <$>) . xmppClientID) <$> getDaemonStatus
+ if null rs
+ then return Nothing
+ else do
+ forM_ rs $ \r -> do
+ void $ alertWhile (syncAlert [r]) $
+ xmppPush cid (taggedPush u selfjid branch r)
+ checkcloudrepos r
+ return $ Just cid
+runPush checkcloudrepos (Pushing cid (StartingPush theiruuid)) = do
+ rs <- xmppRemotes cid theiruuid
+ if null rs
+ then return Nothing
+ else do
+ void $ alertWhile (syncAlert rs) $
+ xmppReceivePack cid
+ mapM_ checkcloudrepos rs
+ return $ Just cid
+runPush _ _ = return Nothing
+
+{- Check if any of the shas that can be pushed are ones we do not
+ - have.
+ -
+ - (Older clients send no shas, so when there are none, always
+ - request a push.)
+ -}
+handlePushNotice :: NetMessage -> Assistant ()
+handlePushNotice (Pushing cid (CanPush theiruuid shas)) =
+ unlessM (null <$> xmppRemotes cid theiruuid) $
+ if null shas
+ then go
+ else ifM (haveall shas)
+ ( debug ["ignoring CanPush with known shas"]
+ , go
+ )
+ where
+ go = do
+ u <- liftAnnex getUUID
+ sendNetMessage $ Pushing cid (PushRequest u)
+ haveall l = liftAnnex $ not <$> anyM donthave l
+ donthave sha = isNothing <$> catObjectDetails sha
+handlePushNotice _ = noop
+
+writeChunk :: Handle -> B.ByteString -> IO ()
+writeChunk h b = do
+ B.hPut h b
+ hFlush h
+
+{- Gets NetMessages for a PushSide, ensures they are in order,
+ - and runs an action to handle each in turn. The action will be passed
+ - Nothing on timeout.
+ -
+ - Does not currently reorder messages, but does ensure that any
+ - duplicate messages, or messages not in the sequence, are discarded.
+ -}
+withPushMessagesInSequence :: ClientID -> PushSide -> (Maybe NetMessage -> Assistant ()) -> Assistant ()
+withPushMessagesInSequence cid side a = loop 0
+ where
+ loop seqnum = do
+ m <- timeout xmppTimeout <~> waitInbox cid side
+ let go s = a m >> loop s
+ let next = seqnum + 1
+ case extractSequence =<< m of
+ Just seqnum'
+ | seqnum' == next -> go next
+ | seqnum' == 0 -> go seqnum
+ | seqnum' == seqnum -> do
+ debug ["ignoring duplicate sequence number", show seqnum]
+ loop seqnum
+ | otherwise -> do
+ debug ["ignoring out of order sequence number", show seqnum', "expected", show next]
+ loop seqnum
+ Nothing -> go seqnum
+
+extractSequence :: NetMessage -> Maybe Int
+extractSequence (Pushing _ (ReceivePackOutput seqnum _)) = Just seqnum
+extractSequence (Pushing _ (SendPackOutput seqnum _)) = Just seqnum
+extractSequence _ = Nothing
diff --git a/Backend.hs b/Backend.hs
new file mode 100644
index 000000000..38314687a
--- /dev/null
+++ b/Backend.hs
@@ -0,0 +1,120 @@
+{- git-annex key/value backends
+ -
+ - Copyright 2010,2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Backend (
+ list,
+ orderedList,
+ genKey,
+ lookupFile,
+ isAnnexLink,
+ chooseBackend,
+ lookupBackendName,
+ maybeLookupBackendName
+) where
+
+import Common.Annex
+import qualified Annex
+import Annex.CheckAttr
+import Annex.CatFile
+import Annex.Link
+import Types.Key
+import Types.KeySource
+import qualified Types.Backend as B
+import Config
+
+-- When adding a new backend, import it here and add it to the list.
+import qualified Backend.Hash
+import qualified Backend.WORM
+import qualified Backend.URL
+
+list :: [Backend]
+list = Backend.Hash.backends ++ Backend.WORM.backends ++ Backend.URL.backends
+
+{- List of backends in the order to try them when storing a new key. -}
+orderedList :: Annex [Backend]
+orderedList = do
+ l <- Annex.getState Annex.backends -- list is cached here
+ if not $ null l
+ then return l
+ else do
+ f <- Annex.getState Annex.forcebackend
+ case f of
+ Just name | not (null name) ->
+ return [lookupBackendName name]
+ _ -> do
+ l' <- gen . annexBackends <$> Annex.getGitConfig
+ Annex.changeState $ \s -> s { Annex.backends = l' }
+ return l'
+ where
+ gen [] = list
+ gen l = map lookupBackendName l
+
+{- Generates a key for a file, trying each backend in turn until one
+ - accepts it. -}
+genKey :: KeySource -> Maybe Backend -> Annex (Maybe (Key, Backend))
+genKey source trybackend = do
+ bs <- orderedList
+ let bs' = maybe bs (: bs) trybackend
+ genKey' bs' source
+genKey' :: [Backend] -> KeySource -> Annex (Maybe (Key, Backend))
+genKey' [] _ = return Nothing
+genKey' (b:bs) source = do
+ r <- B.getKey b source
+ case r of
+ Nothing -> genKey' bs source
+ Just k -> return $ Just (makesane k, b)
+ where
+ -- keyNames should not contain newline characters.
+ makesane k = k { keyName = map fixbadchar (keyName k) }
+ fixbadchar c
+ | c == '\n' = '_'
+ | otherwise = c
+
+{- Looks up the key and backend corresponding to an annexed file,
+ - by examining what the file links to.
+ -
+ - In direct mode, there is often no link on disk, in which case
+ - the symlink is looked up in git instead. However, a real link
+ - on disk still takes precedence over what was committed to git in direct
+ - mode.
+ -}
+lookupFile :: FilePath -> Annex (Maybe (Key, Backend))
+lookupFile file = do
+ mkey <- isAnnexLink file
+ case mkey of
+ Just key -> makeret key
+ Nothing -> ifM isDirect
+ ( maybe (return Nothing) makeret =<< catKeyFile file
+ , return Nothing
+ )
+ where
+ makeret k = let bname = keyBackendName k in
+ case maybeLookupBackendName bname of
+ Just backend -> return $ Just (k, backend)
+ Nothing -> do
+ warning $
+ "skipping " ++ file ++
+ " (unknown backend " ++ bname ++ ")"
+ return Nothing
+
+{- Looks up the backend that should be used for a file.
+ - That can be configured on a per-file basis in the gitattributes file. -}
+chooseBackend :: FilePath -> Annex (Maybe Backend)
+chooseBackend f = Annex.getState Annex.forcebackend >>= go
+ where
+ go Nothing = maybeLookupBackendName <$> checkAttr "annex.backend" f
+ go (Just _) = Just . Prelude.head <$> orderedList
+
+{- Looks up a backend by name. May fail if unknown. -}
+lookupBackendName :: String -> Backend
+lookupBackendName s = fromMaybe unknown $ maybeLookupBackendName s
+ where
+ unknown = error $ "unknown backend " ++ s
+maybeLookupBackendName :: String -> Maybe Backend
+maybeLookupBackendName s = headMaybe matches
+ where
+ matches = filter (\b -> s == B.name b) list
diff --git a/Backend/Hash.hs b/Backend/Hash.hs
new file mode 100644
index 000000000..96a9bab3c
--- /dev/null
+++ b/Backend/Hash.hs
@@ -0,0 +1,168 @@
+{- git-annex hashing backends
+ -
+ - Copyright 2011-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Backend.Hash (backends) where
+
+import Common.Annex
+import qualified Annex
+import Types.Backend
+import Types.Key
+import Types.KeySource
+import Utility.Hash
+import Utility.ExternalSHA
+
+import qualified Build.SysConfig as SysConfig
+import qualified Data.ByteString.Lazy as L
+import Data.Char
+
+data Hash = SHAHash HashSize | SkeinHash HashSize
+type HashSize = Int
+
+{- Order is slightly significant; want SHA256 first, and more general
+ - sizes earlier. -}
+hashes :: [Hash]
+hashes = concat
+ [ map SHAHash [256, 1, 512, 224, 384]
+#ifdef WITH_CRYPTOHASH
+ , map SkeinHash [256, 512]
+#endif
+ ]
+
+{- The SHA256E backend is the default, so genBackendE comes first. -}
+backends :: [Backend]
+backends = catMaybes $ map genBackendE hashes ++ map genBackend hashes
+
+genBackend :: Hash -> Maybe Backend
+genBackend hash = Just Backend
+ { name = hashName hash
+ , getKey = keyValue hash
+ , fsckKey = Just $ checkKeyChecksum hash
+ , canUpgradeKey = Just needsUpgrade
+ }
+
+genBackendE :: Hash -> Maybe Backend
+genBackendE hash = do
+ b <- genBackend hash
+ return $ b
+ { name = hashNameE hash
+ , getKey = keyValueE hash
+ }
+
+hashName :: Hash -> String
+hashName (SHAHash size) = "SHA" ++ show size
+hashName (SkeinHash size) = "SKEIN" ++ show size
+
+hashNameE :: Hash -> String
+hashNameE hash = hashName hash ++ "E"
+
+{- A key is a hash of its contents. -}
+keyValue :: Hash -> KeySource -> Annex (Maybe Key)
+keyValue hash source = do
+ let file = contentLocation source
+ stat <- liftIO $ getFileStatus file
+ let filesize = fromIntegral $ fileSize stat
+ s <- hashFile hash file filesize
+ return $ Just $ stubKey
+ { keyName = s
+ , keyBackendName = hashName hash
+ , keySize = Just filesize
+ }
+
+{- Extension preserving keys. -}
+keyValueE :: Hash -> KeySource -> Annex (Maybe Key)
+keyValueE hash source = keyValue hash source >>= maybe (return Nothing) addE
+ where
+ addE k = return $ Just $ k
+ { keyName = keyName k ++ selectExtension (keyFilename source)
+ , keyBackendName = hashNameE hash
+ }
+
+selectExtension :: FilePath -> String
+selectExtension f
+ | null es = ""
+ | otherwise = intercalate "." ("":es)
+ where
+ es = filter (not . null) $ reverse $
+ take 2 $ takeWhile shortenough $
+ reverse $ split "." $ filter validExtension $ takeExtensions f
+ shortenough e = length e <= 4 -- long enough for "jpeg"
+
+{- A key's checksum is checked during fsck. -}
+checkKeyChecksum :: Hash -> Key -> FilePath -> Annex Bool
+checkKeyChecksum hash key file = do
+ fast <- Annex.getState Annex.fast
+ mstat <- liftIO $ catchMaybeIO $ getFileStatus file
+ case (mstat, fast) of
+ (Just stat, False) -> do
+ let filesize = fromIntegral $ fileSize stat
+ check <$> hashFile hash file filesize
+ _ -> return True
+ where
+ expected = keyHash key
+ check s
+ | s == expected = True
+ {- A bug caused checksums to be prefixed with \ in some
+ - cases; still accept these as legal now that the bug has been
+ - fixed. -}
+ | '\\' : s == expected = True
+ | otherwise = False
+
+keyHash :: Key -> String
+keyHash key = dropExtensions (keyName key)
+
+validExtension :: Char -> Bool
+validExtension c
+ | isAlphaNum c = True
+ | c == '.' = True
+ | otherwise = False
+
+{- Upgrade keys that have the \ prefix on their sha due to a bug, or
+ - that contain non-alphanumeric characters in their extension. -}
+needsUpgrade :: Key -> Bool
+needsUpgrade key = "\\" `isPrefixOf` keyHash key ||
+ any (not . validExtension) (takeExtensions $ keyName key)
+
+hashFile :: Hash -> FilePath -> Integer -> Annex String
+hashFile hash file filesize = do
+ showAction "checksum"
+ liftIO $ go hash
+ where
+ go (SHAHash hashsize) = case shaHasher hashsize filesize of
+ Left sha -> sha <$> L.readFile file
+ Right command ->
+ either error return
+ =<< externalSHA command hashsize file
+ go (SkeinHash hashsize) = skeinHasher hashsize <$> L.readFile file
+
+shaHasher :: HashSize -> Integer -> Either (L.ByteString -> String) String
+shaHasher hashsize filesize
+ | hashsize == 1 = use SysConfig.sha1 sha1
+ | hashsize == 256 = use SysConfig.sha256 sha256
+ | hashsize == 224 = use SysConfig.sha224 sha224
+ | hashsize == 384 = use SysConfig.sha384 sha384
+ | hashsize == 512 = use SysConfig.sha512 sha512
+ | otherwise = error $ "unsupported sha size " ++ show hashsize
+ where
+ use Nothing hasher = Left $ show . hasher
+ use (Just c) hasher
+ {- Use builtin, but slightly slower hashing for
+ - smallish files. Cryptohash benchmarks 90 to 101%
+ - faster than external hashers, depending on the hash
+ - and system. So there is no point forking an external
+ - process unless the file is large. -}
+ | filesize < 1048576 = use Nothing hasher
+ | otherwise = Right c
+
+skeinHasher :: HashSize -> (L.ByteString -> String)
+skeinHasher hashsize
+#ifdef WITH_CRYPTOHASH
+ | hashsize == 256 = show . skein256
+ | hashsize == 512 = show . skein512
+#endif
+ | otherwise = error $ "unsupported skein size " ++ show hashsize
diff --git a/Backend/URL.hs b/Backend/URL.hs
new file mode 100644
index 000000000..a8161c98d
--- /dev/null
+++ b/Backend/URL.hs
@@ -0,0 +1,37 @@
+{- git-annex "URL" backend -- keys whose content is available from urls.
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Backend.URL (
+ backends,
+ fromUrl
+) where
+
+import Common.Annex
+import Types.Backend
+import Types.Key
+import Backend.Utilities
+
+backends :: [Backend]
+backends = [backend]
+
+backend :: Backend
+backend = Backend
+ { name = "URL"
+ , getKey = const $ return Nothing
+ , fsckKey = Nothing
+ , canUpgradeKey = Nothing
+ }
+
+{- Every unique url has a corresponding key. -}
+fromUrl :: String -> Maybe Integer -> Annex Key
+fromUrl url size = do
+ n <- genKeyName url
+ return $ stubKey
+ { keyName = n
+ , keyBackendName = "URL"
+ , keySize = size
+ }
diff --git a/Backend/Utilities.hs b/Backend/Utilities.hs
new file mode 100644
index 000000000..24dbfd6d9
--- /dev/null
+++ b/Backend/Utilities.hs
@@ -0,0 +1,25 @@
+{- git-annex backend utilities
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Backend.Utilities where
+
+import Data.Hash.MD5
+
+import Common.Annex
+
+{- Generates a keyName from an input string. Takes care of sanitizing it.
+ - If it's not too long, the full string is used as the keyName.
+ - Otherwise, it's truncated at half the filename length limit, and its
+ - md5 is prepended to ensure a unique key. -}
+genKeyName :: String -> Annex String
+genKeyName s = do
+ limit <- liftIO . fileNameLengthLimit =<< fromRepo gitAnnexDir
+ let s' = preSanitizeKeyName s
+ let truncs = truncateFilePath (limit `div` 2) s'
+ return $ if s' == truncs
+ then s'
+ else truncs ++ "-" ++ md5s (Str s)
diff --git a/Backend/WORM.hs b/Backend/WORM.hs
new file mode 100644
index 000000000..60db42f56
--- /dev/null
+++ b/Backend/WORM.hs
@@ -0,0 +1,43 @@
+{- git-annex "WORM" backend -- Write Once, Read Many
+ -
+ - Copyright 2010 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Backend.WORM (backends) where
+
+import Common.Annex
+import Types.Backend
+import Types.Key
+import Types.KeySource
+import Backend.Utilities
+
+backends :: [Backend]
+backends = [backend]
+
+backend :: Backend
+backend = Backend
+ { name = "WORM"
+ , getKey = keyValue
+ , fsckKey = Nothing
+ , canUpgradeKey = Nothing
+ }
+
+{- The key includes the file size, modification time, and the
+ - basename of the filename.
+ -
+ - That allows multiple files with the same names to have different keys,
+ - while also allowing a file to be moved around while retaining the
+ - same key.
+ -}
+keyValue :: KeySource -> Annex (Maybe Key)
+keyValue source = do
+ stat <- liftIO $ getFileStatus $ contentLocation source
+ n <- genKeyName $ keyFilename source
+ return $ Just Key
+ { keyName = n
+ , keyBackendName = name backend
+ , keySize = Just $ fromIntegral $ fileSize stat
+ , keyMtime = Just $ modificationTime stat
+ }
diff --git a/Build/BundledPrograms.hs b/Build/BundledPrograms.hs
new file mode 100644
index 000000000..3c53f06fb
--- /dev/null
+++ b/Build/BundledPrograms.hs
@@ -0,0 +1,58 @@
+{- Bundled programs
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Build.BundledPrograms where
+
+import Data.Maybe
+
+import Build.SysConfig as SysConfig
+
+{- Programs that git-annex uses, to include in the bundle.
+ -
+ - These may be just the command name, or the full path to it. -}
+bundledPrograms :: [FilePath]
+bundledPrograms = catMaybes
+ [ Nothing
+#ifndef mingw32_HOST_OS
+ -- git is not included in the windows bundle
+ , Just "git"
+#endif
+ , Just "cp"
+#ifndef mingw32_HOST_OS
+ -- using xargs on windows led to problems, so it's not used there
+ , Just "xargs"
+#endif
+ , Just "rsync"
+ , Just "ssh"
+ , Just "ssh-keygen"
+#ifndef mingw32_HOST_OS
+ , Just "sh"
+#endif
+ , SysConfig.gpg
+ , ifset SysConfig.curl "curl"
+ , ifset SysConfig.wget "wget"
+ , ifset SysConfig.bup "bup"
+ , SysConfig.lsof
+ , SysConfig.gcrypt
+ , SysConfig.sha1
+ , SysConfig.sha256
+ , SysConfig.sha512
+ , SysConfig.sha224
+ , SysConfig.sha384
+#ifdef linux_HOST_OS
+ -- used to unpack the tarball when upgrading
+ , Just "gunzip"
+ , Just "tar"
+#endif
+ -- nice and ionice are not included in the bundle; we rely on the
+ -- system's own version, which may better match its kernel
+ ]
+ where
+ ifset True s = Just s
+ ifset False _ = Nothing
diff --git a/Build/Configure.hs b/Build/Configure.hs
new file mode 100644
index 000000000..d17f6cbf0
--- /dev/null
+++ b/Build/Configure.hs
@@ -0,0 +1,140 @@
+{- Checks system configuration and generates SysConfig.hs. -}
+
+module Build.Configure where
+
+import System.Directory
+import Data.List
+import System.Process
+import Control.Applicative
+import System.FilePath
+import System.Environment (getArgs)
+import Data.Maybe
+import Control.Monad.IfElse
+import Data.Char
+
+import Build.TestConfig
+import Build.Version
+import Utility.SafeCommand
+import Utility.Monad
+import Utility.ExternalSHA
+import Utility.Env
+import qualified Git.Version
+
+tests :: [TestCase]
+tests =
+ [ TestCase "version" getVersion
+ , TestCase "UPGRADE_LOCATION" getUpgradeLocation
+ , TestCase "git" $ requireCmd "git" "git --version >/dev/null"
+ , TestCase "git version" getGitVersion
+ , testCp "cp_a" "-a"
+ , testCp "cp_p" "-p"
+ , testCp "cp_reflink_auto" "--reflink=auto"
+ , TestCase "xargs -0" $ requireCmd "xargs_0" "xargs -0 </dev/null"
+ , TestCase "rsync" $ requireCmd "rsync" "rsync --version >/dev/null"
+ , TestCase "curl" $ testCmd "curl" "curl --version >/dev/null"
+ , TestCase "wget" $ testCmd "wget" "wget --version >/dev/null"
+ , TestCase "bup" $ testCmd "bup" "bup --version >/dev/null"
+ , TestCase "quvi" $ testCmd "quvi" "quvi --version >/dev/null"
+ , TestCase "newquvi" $ testCmd "newquvi" "quvi info >/dev/null"
+ , TestCase "nice" $ testCmd "nice" "nice true >/dev/null"
+ , TestCase "ionice" $ testCmd "ionice" "ionice -c3 true >/dev/null"
+ , TestCase "gpg" $ maybeSelectCmd "gpg"
+ [ ("gpg", "--version >/dev/null")
+ , ("gpg2", "--version >/dev/null") ]
+ , TestCase "lsof" $ findCmdPath "lsof" "lsof"
+ , TestCase "git-remote-gcrypt" $ findCmdPath "gcrypt" "git-remote-gcrypt"
+ , TestCase "ssh connection caching" getSshConnectionCaching
+ ] ++ shaTestCases
+ [ (1, "da39a3ee5e6b4b0d3255bfef95601890afd80709")
+ , (256, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
+ , (512, "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e")
+ , (224, "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f")
+ , (384, "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b")
+ ]
+
+{- shaNsum are the program names used by coreutils. Some systems like OSX
+ - sometimes install these with 'g' prefixes.
+ -
+ - On some systems, shaN is used instead, but on other
+ - systems, it might be "hashalot", which does not produce
+ - usable checksums. Only accept programs that produce
+ - known-good hashes when run on files. -}
+shaTestCases :: [(Int, String)] -> [TestCase]
+shaTestCases l = map make l
+ where
+ make (n, knowngood) = TestCase key $
+ Config key . MaybeStringConfig <$> search (shacmds n)
+ where
+ key = "sha" ++ show n
+ search [] = return Nothing
+ search (c:cmds) = do
+ sha <- externalSHA c n "/dev/null"
+ if sha == Right knowngood
+ then return $ Just c
+ else search cmds
+
+ shacmds n = concatMap (\x -> [x, 'g':x, osxpath </> x]) $
+ map (\x -> "sha" ++ show n ++ x) ["sum", ""]
+
+ {- Max OSX sometimes puts GNU tools outside PATH, so look in
+ - the location it uses, and remember where to run them
+ - from. -}
+ osxpath = "/opt/local/libexec/gnubin"
+
+tmpDir :: String
+tmpDir = "tmp"
+
+testFile :: String
+testFile = tmpDir ++ "/testfile"
+
+testCp :: ConfigKey -> String -> TestCase
+testCp k option = TestCase cmd $ testCmd k cmdline
+ where
+ cmd = "cp " ++ option
+ cmdline = cmd ++ " " ++ testFile ++ " " ++ testFile ++ ".new"
+
+getUpgradeLocation :: Test
+getUpgradeLocation = do
+ e <- getEnv "UPGRADE_LOCATION"
+ return $ Config "upgradelocation" $ MaybeStringConfig e
+
+getGitVersion :: Test
+getGitVersion = Config "gitversion" . StringConfig . show
+ <$> Git.Version.installed
+
+getSshConnectionCaching :: Test
+getSshConnectionCaching = Config "sshconnectioncaching" . BoolConfig <$>
+ boolSystem "sh" [Param "-c", Param "ssh -o ControlPersist=yes -V >/dev/null 2>/dev/null"]
+
+setup :: IO ()
+setup = do
+ createDirectoryIfMissing True tmpDir
+ writeFile testFile "test file contents"
+
+cleanup :: IO ()
+cleanup = removeDirectoryRecursive tmpDir
+
+run :: [TestCase] -> IO ()
+run ts = do
+ args <- getArgs
+ setup
+ config <- runTests ts
+ if args == ["Android"]
+ then writeSysConfig $ androidConfig config
+ else writeSysConfig config
+ cleanup
+ whenM isReleaseBuild $
+ cabalSetup "git-annex.cabal"
+
+{- Hard codes some settings to cross-compile for Android. -}
+androidConfig :: [Config] -> [Config]
+androidConfig c = overrides ++ filter (not . overridden) c
+ where
+ overrides =
+ [ Config "cp_reflink_auto" $ BoolConfig False
+ , Config "curl" $ BoolConfig False
+ , Config "sha224" $ MaybeStringConfig Nothing
+ , Config "sha384" $ MaybeStringConfig Nothing
+ ]
+ overridden (Config k _) = k `elem` overridekeys
+ overridekeys = map (\(Config k _) -> k) overrides
diff --git a/Build/DesktopFile.hs b/Build/DesktopFile.hs
new file mode 100644
index 000000000..9f4ba5992
--- /dev/null
+++ b/Build/DesktopFile.hs
@@ -0,0 +1,82 @@
+{- Generating and installing a desktop menu entry file and icon,
+ - and a desktop autostart file. (And OSX equivilants.)
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Build.DesktopFile where
+
+import Utility.Exception
+import Utility.FreeDesktop
+import Utility.Path
+import Utility.Monad
+import Config.Files
+import Utility.OSX
+import Assistant.Install.AutoStart
+import Assistant.Install.Menu
+
+import Control.Applicative
+import System.Directory
+import System.Environment
+#ifndef mingw32_HOST_OS
+import System.Posix.User
+import System.Posix.Files
+#endif
+import System.FilePath
+import Data.Maybe
+
+systemwideInstall :: IO Bool
+#ifndef mingw32_HOST_OS
+systemwideInstall = isroot <||> destdirset
+ where
+ isroot = do
+ uid <- fromIntegral <$> getRealUserID
+ return $ uid == (0 :: Int)
+ destdirset = isJust <$> catchMaybeIO (getEnv "DESTDIR")
+#else
+systemwideInstall = return False
+#endif
+
+inDestDir :: FilePath -> IO FilePath
+inDestDir f = do
+ destdir <- catchDefaultIO "" (getEnv "DESTDIR")
+ return $ destdir ++ "/" ++ f
+
+writeFDODesktop :: FilePath -> IO ()
+writeFDODesktop command = do
+ systemwide <- systemwideInstall
+
+ datadir <- if systemwide then return systemDataDir else userDataDir
+ menufile <- inDestDir (desktopMenuFilePath "git-annex" datadir)
+ icondir <- inDestDir (iconDir datadir)
+ installMenu command menufile "doc" icondir
+
+ configdir <- if systemwide then return systemConfigDir else userConfigDir
+ installAutoStart command
+ =<< inDestDir (autoStartPath "git-annex" configdir)
+
+writeOSXDesktop :: FilePath -> IO ()
+writeOSXDesktop command = do
+ installAutoStart command =<< inDestDir =<< ifM systemwideInstall
+ ( return $ systemAutoStart osxAutoStartLabel
+ , userAutoStart osxAutoStartLabel
+ )
+
+install :: FilePath -> IO ()
+install command = do
+#ifdef darwin_HOST_OS
+ writeOSXDesktop command
+#else
+ writeFDODesktop command
+#endif
+ ifM systemwideInstall
+ ( return ()
+ , do
+ programfile <- inDestDir =<< programFile
+ createDirectoryIfMissing True (parentDir programfile)
+ writeFile programfile command
+ )
diff --git a/Build/DistributionUpdate.hs b/Build/DistributionUpdate.hs
new file mode 100644
index 000000000..0afc2211f
--- /dev/null
+++ b/Build/DistributionUpdate.hs
@@ -0,0 +1,64 @@
+{- Builds distributon info files for each git-annex release in a directory
+ - tree, which must itself be part of a git-annex repository. Only files
+ - that are present have their info file created. -}
+
+import Common.Annex
+import Types.Distribution
+import Build.Version
+import Utility.UserInfo
+import Utility.Path
+import qualified Git.Construct
+import qualified Annex
+import Annex.Content
+import Backend
+import Git.Command
+
+import Data.Time.Clock
+
+main = do
+ state <- Annex.new =<< Git.Construct.fromPath =<< getRepoDir
+ Annex.eval state makeinfos
+
+makeinfos :: Annex ()
+makeinfos = do
+ basedir <- liftIO getRepoDir
+ version <- liftIO getChangelogVersion
+ now <- liftIO getCurrentTime
+ liftIO $ putStrLn $ "building info files for version " ++ version ++ " in " ++ basedir
+ fs <- liftIO $ dirContentsRecursiveSkipping (== "info") (basedir </> "git-annex")
+ forM_ fs $ \f -> do
+ v <- lookupFile f
+ case v of
+ Nothing -> noop
+ Just (k, _b) -> whenM (inAnnex k) $ do
+ liftIO $ putStrLn f
+ let infofile = f ++ ".info"
+ liftIO $ writeFile infofile $ show $ GitAnnexDistribution
+ { distributionUrl = mkUrl basedir f
+ , distributionKey = k
+ , distributionVersion = version
+ , distributionReleasedate = now
+ , distributionUrgentUpgrade = Nothing
+ }
+ void $ inRepo $ runBool [Param "add", Param infofile]
+ void $ inRepo $ runBool
+ [ Param "commit"
+ , Param "-m"
+ , Param $ "publishing git-annex " ++ version
+ ]
+ void $ inRepo $ runBool
+ [ Param "annex"
+ , Params "move --to website"
+ ]
+ void $ inRepo $ runBool
+ [ Param "annex"
+ , Params "sync"
+ ]
+
+getRepoDir :: IO FilePath
+getRepoDir = do
+ home <- liftIO myHomeDir
+ return $ home </> "lib" </> "downloads"
+
+mkUrl :: FilePath -> FilePath -> String
+mkUrl basedir f = "https://downloads.kitenet.net/" ++ relPathDirToFile basedir f
diff --git a/Build/EvilSplicer.hs b/Build/EvilSplicer.hs
new file mode 100644
index 000000000..35dba4968
--- /dev/null
+++ b/Build/EvilSplicer.hs
@@ -0,0 +1,606 @@
+{- Expands template haskell splices
+ -
+ - You should probably just use http://hackage.haskell.org/package/zeroth
+ - instead. I wish I had known about it before writing this.
+ -
+ - First, the code must be built with a ghc that supports TH,
+ - and the splices dumped to a log. For example:
+ - cabal build --ghc-options=-ddump-splices 2>&1 | tee log
+ -
+ - Along with the log, a headers file may also be provided, containing
+ - additional imports needed by the template haskell code.
+ -
+ - This program will parse the log, and expand all splices therein,
+ - writing files to the specified destdir (which can be "." to modify
+ - the source tree directly). They can then be built a second
+ - time, with a ghc that does not support TH.
+ -
+ - Note that template haskell code may refer to symbols that are not
+ - exported by the library that defines the TH code. In this case,
+ - the library has to be modifed to export those symbols.
+ -
+ - There can also be other problems with the generated code; it may
+ - need modifications to compile.
+ -
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Main where
+
+import Text.Parsec
+import Text.Parsec.String
+import Control.Applicative ((<$>))
+import Data.Either
+import Data.List
+import Data.String.Utils
+import Data.Char
+import System.Environment
+import System.FilePath
+import System.Directory
+import Control.Monad
+
+import Utility.Monad
+import Utility.Misc
+import Utility.Exception
+import Utility.Path
+
+data Coord = Coord
+ { coordLine :: Int
+ , coordColumn :: Int
+ }
+ deriving (Read, Show)
+
+offsetCoord :: Coord -> Coord -> Coord
+offsetCoord a b = Coord
+ (coordLine a - coordLine b)
+ (coordColumn a - coordColumn b)
+
+data SpliceType = SpliceExpression | SpliceDeclaration
+ deriving (Read, Show, Eq)
+
+data Splice = Splice
+ { splicedFile :: FilePath
+ , spliceStart :: Coord
+ , spliceEnd :: Coord
+ , splicedExpression :: String
+ , splicedCode :: String
+ , spliceType :: SpliceType
+ }
+ deriving (Read, Show)
+
+isExpressionSplice :: Splice -> Bool
+isExpressionSplice s = spliceType s == SpliceExpression
+
+number :: Parser Int
+number = read <$> many1 digit
+
+{- A pair of Coords is written in one of three ways:
+ - "95:21-73", "1:1", or "(92,25)-(94,2)"
+ -}
+coordsParser :: Parser (Coord, Coord)
+coordsParser = (try singleline <|> try weird <|> multiline) <?> "Coords"
+ where
+ singleline = do
+ line <- number
+ char ':'
+ startcol <- number
+ char '-'
+ endcol <- number
+ return $ (Coord line startcol, Coord line endcol)
+
+ weird = do
+ line <- number
+ char ':'
+ col <- number
+ return $ (Coord line col, Coord line col)
+
+ multiline = do
+ start <- fromparens
+ char '-'
+ end <- fromparens
+ return $ (start, end)
+
+ fromparens = between (char '(') (char ')') $ do
+ line <- number
+ char ','
+ col <- number
+ return $ Coord line col
+
+indent :: Parser String
+indent = many1 $ char ' '
+
+restOfLine :: Parser String
+restOfLine = newline `after` many (noneOf "\n")
+
+indentedLine :: Parser String
+indentedLine = indent >> restOfLine
+
+spliceParser :: Parser Splice
+spliceParser = do
+ file <- many1 (noneOf ":\n")
+ char ':'
+ (start, end) <- coordsParser
+ string ": Splicing "
+ splicetype <- tosplicetype
+ <$> (string "expression" <|> string "declarations")
+ newline
+
+ getthline <- expressionextractor
+ expression <- unlines <$> many1 getthline
+
+ indent
+ string "======>"
+ newline
+
+ getcodeline <- expressionextractor
+ realcoords <- try (Right <$> getrealcoords file) <|> (Left <$> getcodeline)
+ codelines <- many getcodeline
+ return $ case realcoords of
+ Left firstcodeline ->
+ Splice file start end expression
+ (unlines $ firstcodeline:codelines)
+ splicetype
+ Right (realstart, realend) ->
+ Splice file realstart realend expression
+ (unlines codelines)
+ splicetype
+ where
+ tosplicetype "declarations" = SpliceDeclaration
+ tosplicetype "expression" = SpliceExpression
+ tosplicetype s = error $ "unknown splice type: " ++ s
+
+ {- All lines of the indented expression start with the same
+ - indent, which is stripped. Any other indentation is preserved. -}
+ expressionextractor = do
+ i <- lookAhead indent
+ return $ try $ do
+ string i
+ restOfLine
+
+ {- When splicing declarations, GHC will output a splice
+ - at 1:1, and then inside the splice code block,
+ - the first line will give the actual coordinates of the
+ - line that was spliced. -}
+ getrealcoords file = do
+ indent
+ string file
+ char ':'
+ char '\n' `after` coordsParser
+
+{- Extracts the splices, ignoring the rest of the compiler output. -}
+splicesExtractor :: Parser [Splice]
+splicesExtractor = rights <$> many extract
+ where
+ extract = try (Right <$> spliceParser) <|> (Left <$> compilerJunkLine)
+ compilerJunkLine = restOfLine
+
+{- Modifies the source file, expanding the splices, which all must
+ - have the same splicedFile. Writes the new file to the destdir.
+ -
+ - Each splice's Coords refer to the original position in the file,
+ - and not to its position after any previous splices may have inserted
+ - or removed lines.
+ -
+ - To deal with this complication, the file is broken into logical lines
+ - (which can contain any String, including a multiline or empty string).
+ - Each splice is assumed to be on its own block of lines; two
+ - splices on the same line is not currently supported.
+ - This means that a splice can modify the logical lines within its block
+ - as it likes, without interfering with the Coords of other splices.
+ -
+ - As well as expanding splices, this can add a block of imports to the
+ - file. These are put right before the first line in the file that
+ - starts with "import "
+ -}
+applySplices :: FilePath -> Maybe String -> [Splice] -> IO ()
+applySplices destdir imports splices@(first:_) = do
+ let f = splicedFile first
+ let dest = (destdir </> f)
+ lls <- map (++ "\n") . lines <$> readFileStrict f
+ createDirectoryIfMissing True (parentDir dest)
+ let newcontent = concat $ addimports $ expand lls splices
+ oldcontent <- catchMaybeIO $ readFileStrict dest
+ when (oldcontent /= Just newcontent) $ do
+ putStrLn $ "splicing " ++ f
+ writeFile dest newcontent
+ where
+ expand lls [] = lls
+ expand lls (s:rest)
+ | isExpressionSplice s = expand (expandExpressionSplice s lls) rest
+ | otherwise = expand (expandDeclarationSplice s lls) rest
+
+ addimports lls = case imports of
+ Nothing -> lls
+ Just v ->
+ let (start, end) = break ("import " `isPrefixOf`) lls
+ in if null end
+ then start
+ else concat
+ [ start
+ , [v]
+ , end
+ ]
+
+{- Declaration splices are expanded to replace their whole line. -}
+expandDeclarationSplice :: Splice -> [String] -> [String]
+expandDeclarationSplice s lls = concat [before, [splice], end]
+ where
+ cs = spliceStart s
+ ce = spliceEnd s
+
+ (before, rest) = splitAt (coordLine cs - 1) lls
+ (_oldlines, end) = splitAt (1 + coordLine (offsetCoord ce cs)) rest
+ splice = mangleCode $ splicedCode s
+
+{- Expression splices are expanded within their line. -}
+expandExpressionSplice :: Splice -> [String] -> [String]
+expandExpressionSplice s lls = concat [before, spliced:padding, end]
+ where
+ cs = spliceStart s
+ ce = spliceEnd s
+
+ (before, rest) = splitAt (coordLine cs - 1) lls
+ (oldlines, end) = splitAt (1 + coordLine (offsetCoord ce cs)) rest
+ (splicestart, padding, spliceend) = case map expandtabs oldlines of
+ ss:r
+ | null r -> (ss, [], ss)
+ | otherwise -> (ss, take (length r) (repeat []), last r)
+ _ -> ([], [], [])
+ spliced = concat
+ [ joinsplice $ deqqstart $ take (coordColumn cs - 1) splicestart
+ , addindent (findindent splicestart) (mangleCode $ splicedCode s)
+ , deqqend $ drop (coordColumn ce) spliceend
+ ]
+
+ {- coordinates assume tabs are expanded to 8 spaces -}
+ expandtabs = replace "\t" (take 8 $ repeat ' ')
+
+ {- splicing leaves $() quasiquote behind; remove it -}
+ deqqstart s = case reverse s of
+ ('(':'$':rest) -> reverse rest
+ _ -> s
+ deqqend (')':s) = s
+ deqqend s = s
+
+ {- Prepare the code that comes just before the splice so
+ - the splice will combine with it appropriately. -}
+ joinsplice s
+ -- all indentation? Skip it, we'll use the splice's indentation
+ | all isSpace s = ""
+ -- function definition needs no preparation
+ -- ie: foo = $(splice)
+ | "=" `isSuffixOf` s' = s
+ -- nor does lambda definition or case expression
+ | "->" `isSuffixOf` s' = s
+ -- nor does a let .. in declaration
+ | "in" `isSuffixOf` s' = s
+ -- already have a $ to set off the splice
+ -- ie: foo $ $(splice)
+ | "$" `isSuffixOf` s' = s
+ -- need to add a $ to set off the splice
+ -- ie: bar $(splice)
+ | otherwise = s ++ " $ "
+ where
+ s' = filter (not . isSpace) s
+
+ findindent = length . takeWhile isSpace
+ addindent n = unlines . map (i ++) . lines
+ where
+ i = take n $ repeat ' '
+
+{- Tweaks code output by GHC in splices to actually build. Yipes. -}
+mangleCode :: String -> String
+mangleCode = flip_colon
+ . remove_unnecessary_type_signatures
+ . lambdaparenhack
+ . lambdaparens
+ . declaration_parens
+ . case_layout
+ . case_layout_multiline
+ . yesod_url_render_hack
+ . text_builder_hack
+ . nested_instances
+ . collapse_multiline_strings
+ . remove_package_version
+ . emptylambda
+ where
+ {- Lambdas are often output without parens around them.
+ - This breaks when the lambda is immediately applied to a
+ - parameter.
+ -
+ - For example:
+ -
+ - renderRoute (StaticR sub_a1nUH)
+ - = \ (a_a1nUI, b_a1nUJ)
+ - -> (((pack "static") : a_a1nUI),
+ - b_a1nUJ)
+ - (renderRoute sub_a1nUH)
+ -
+ - There are sometimes many lines of lambda code that need to be
+ - parenthesised. Approach: find the "->" and scan down the
+ - column to the first non-whitespace. This is assumed
+ - to be the expression after the lambda.
+ -
+ - Runs recursively on the body of the lambda, to handle nested
+ - lambdas.
+ -}
+ lambdaparens = parsecAndReplace $ do
+ -- skip lambdas inside tuples or parens
+ prefix <- noneOf "(, \n"
+ preindent <- many1 $ oneOf " \n"
+ string "\\ "
+ lambdaparams <- restofline
+ continuedlambdaparams <- many $ try $ do
+ indent <- many1 $ char ' '
+ p <- satisfy isLetter
+ aram <- many $ satisfy isAlphaNum <|> oneOf "_"
+ newline
+ return $ indent ++ p:aram ++ "\n"
+ indent <- many1 $ char ' '
+ string "-> "
+ firstline <- restofline
+ lambdalines <- many $ try $ do
+ string indent
+ char ' '
+ l <- restofline
+ return $ indent ++ " " ++ l
+ return $ concat
+ [ prefix:preindent
+ , "(\\ " ++ lambdaparams ++ "\n"
+ , concat continuedlambdaparams
+ , indent ++ "-> "
+ , lambdaparens $ intercalate "\n" (firstline:lambdalines)
+ , ")\n"
+ ]
+
+ {- Hack to add missing parens in a specific case in yesod
+ - static route code.
+ -
+ - StaticR
+ - yesod_dispatch_env_a4iDV
+ - (\ p_a4iE2 r_a4iE3
+ - -> r_a4iE3 {Network.Wai.pathInfo = p_a4iE2}
+ - xrest_a4iDT req_a4iDW)) }
+ -
+ - Need to add another paren around the lambda, and close it
+ - before its parameters. lambdaparens misses this one because
+ - there is already one paren present.
+ -
+ - FIXME: This is a hack. lambdaparens could just always add a
+ - layer of parens even when a lambda seems to be in parent.
+ -}
+ lambdaparenhack = parsecAndReplace $ do
+ indent <- many1 $ char ' '
+ staticr <- string "StaticR"
+ newline
+ string indent
+ yesod_dispatch_env <- restofline
+ string indent
+ lambdaprefix <- string "(\\ "
+ l1 <- restofline
+ string indent
+ lambdaarrow <- string " ->"
+ l2 <- restofline
+ return $ unlines
+ [ indent ++ staticr
+ , indent ++ yesod_dispatch_env
+ , indent ++ "(" ++ lambdaprefix ++ l1
+ , indent ++ lambdaarrow ++ l2 ++ ")"
+ ]
+
+ restofline = manyTill (noneOf "\n") newline
+
+ {- For some reason, GHC sometimes doesn't like the multiline
+ - strings it creates. It seems to get hung up on \{ at the
+ - start of a new line sometimes, wanting it to not be escaped.
+ -
+ - To work around what is likely a GHC bug, just collapse
+ - multiline strings. -}
+ collapse_multiline_strings = parsecAndReplace $ do
+ string "\\\n"
+ many1 $ oneOf " \t"
+ string "\\"
+ return "\\n"
+
+ {- GHC outputs splices using explicit braces rather than layout.
+ - For a case expression, it does something weird:
+ -
+ - case foo of {
+ - xxx -> blah
+ - yyy -> blah };
+ -
+ - This is not legal Haskell; the statements in the case must be
+ - separated by ';'
+ -
+ - To fix, we could just put a semicolon at the start of every line
+ - containing " -> " ... Except that lambdas also contain that.
+ - But we can get around that: GHC outputs lambas like this:
+ -
+ - \ foo
+ - -> bar
+ -
+ - Or like this:
+ -
+ - \ foo -> bar
+ -
+ - So, we can put the semicolon at the start of every line
+ - containing " -> " unless there's a "\ " first, or it's
+ - all whitespace up until it.
+ -}
+ case_layout = parsecAndReplace $ do
+ newline
+ indent <- many1 $ char ' '
+ prefix <- manyTill (noneOf "\n") (try (string "-> "))
+ if length prefix > 10
+ then unexpected "too long a prefix"
+ else if "\\ " `isInfixOf` prefix
+ then unexpected "lambda expression"
+ else if null prefix
+ then unexpected "second line of lambda"
+ else return $ "\n" ++ indent ++ "; " ++ prefix ++ " -> "
+ {- Sometimes cases themselves span multiple lines:
+ -
+ - Nothing
+ - -> foo
+ -}
+ case_layout_multiline = parsecAndReplace $ do
+ newline
+ indent <- many1 $ char ' '
+ firstline <- restofline
+
+ string indent
+ indent2 <- many1 $ char ' '
+ string "-> "
+ if "\\ " `isInfixOf` firstline
+ then unexpected "lambda expression"
+ else return $ "\n" ++ indent ++ "; " ++ firstline ++ "\n"
+ ++ indent ++ indent2 ++ "-> "
+
+ {- (foo, \ -> bar) is not valid haskell, GHC.
+ - Change to (foo, bar)
+ -
+ - (Does this ever happen outside a tuple? Only saw
+ - it inside them..
+ -}
+ emptylambda = replace ", \\ -> " ", "
+
+ {- GHC may output this:
+ -
+ - instance RenderRoute WebApp where
+ - data instance Route WebApp
+ - ^^^^^^^^
+ - The marked word should not be there.
+ -
+ - FIXME: This is a yesod-specific hack, it should look for the
+ - outer instance.
+ -}
+ nested_instances = replace " data instance Route" " data Route"
+
+ {- GHC does not properly parenthesise generated data type
+ - declarations. -}
+ declaration_parens = replace "StaticR Route Static" "StaticR (Route Static)"
+
+ {- A type signature is sometimes given for an entire lambda,
+ - which is not properly parenthesized or laid out. This is a
+ - hack to remove one specific case where this happens and the
+ - signature is easily inferred, so is just removed.
+ -}
+ remove_unnecessary_type_signatures = parsecAndReplace $ do
+ string " ::"
+ newline
+ many1 $ char ' '
+ string "Text.Css.Block Text.Css.Resolved"
+ newline
+ return ""
+
+ {- GHC may add full package and version qualifications for
+ - symbols from unimported modules. We don't want these.
+ -
+ - Examples:
+ - "blaze-html-0.4.3.1:Text.Blaze.Internal.preEscapedText"
+ - "ghc-prim:GHC.Types.:"
+ -}
+ remove_package_version = parsecAndReplace $
+ mangleSymbol <$> qualifiedSymbol
+
+ mangleSymbol "GHC.Types." = ""
+ mangleSymbol "GHC.Tuple." = ""
+ mangleSymbol s = s
+
+ qualifiedSymbol :: Parser String
+ qualifiedSymbol = do
+ s <- token
+ char ':'
+ if length s < 5
+ then unexpected "too short to be a namespace"
+ else do
+ token
+
+ token :: Parser String
+ token = do
+ t <- satisfy isLetter
+ oken <- many $ satisfy isAlphaNum <|> oneOf "-.'"
+ return $ t:oken
+
+ {- This works when it's "GHC.Types.:", but we strip
+ - that above, so have to fix up after it here.
+ - The ; is added by case_layout. -}
+ flip_colon = replace "; : _ " "; _ : "
+
+{- This works around a problem in the expanded template haskell for Yesod
+ - type-safe url rendering.
+ -
+ - It generates code like this:
+ -
+ - (toHtml
+ - (\ u_a2ehE -> urender_a2ehD u_a2ehE []
+ - (CloseAlert aid)))));
+ -
+ - Where urender_a2ehD is the function returned by getUrlRenderParams.
+ - But, that function that only takes 2 params, not 3.
+ - And toHtml doesn't take a parameter at all!
+ -
+ - So, this modifes the code, to look like this:
+ -
+ - (toHtml
+ - (flip urender_a2ehD []
+ - (CloseAlert aid)))));
+ -
+ - FIXME: Investigate and fix this properly.
+ -}
+yesod_url_render_hack :: String -> String
+yesod_url_render_hack = parsecAndReplace $ do
+ string "(toHtml"
+ whitespace
+ string "(\\"
+ whitespace
+ wtf <- token
+ whitespace
+ string "->"
+ whitespace
+ renderer <- token
+ whitespace
+ string wtf
+ whitespace
+ return $ "(toHtml (flip " ++ renderer ++ " "
+ where
+ whitespace :: Parser String
+ whitespace = many $ oneOf " \t\r\n"
+
+ token :: Parser String
+ token = many1 $ satisfy isAlphaNum <|> oneOf "_"
+
+{- Use exported symbol. -}
+text_builder_hack :: String -> String
+text_builder_hack = replace "Data.Text.Lazy.Builder.Internal.fromText" "Data.Text.Lazy.Builder.fromText"
+
+{- Given a Parser that finds strings it wants to modify,
+ - and returns the modified string, does a mass
+ - find and replace throughout the input string.
+ - Rather slow, but crazy powerful. -}
+parsecAndReplace :: Parser String -> String -> String
+parsecAndReplace p s = case parse find "" s of
+ Left e -> s
+ Right l -> concatMap (either return id) l
+ where
+ find :: Parser [Either Char String]
+ find = many $ try (Right <$> p) <|> (Left <$> anyChar)
+
+main :: IO ()
+main = go =<< getArgs
+ where
+ go (destdir:log:header:[]) = run destdir log (Just header)
+ go (destdir:log:[]) = run destdir log Nothing
+ go _ = error "usage: EvilSplicer destdir logfile [headerfile]"
+
+ run destdir log mheader = do
+ r <- parseFromFile splicesExtractor log
+ case r of
+ Left e -> error $ show e
+ Right splices -> do
+ let groups = groupBy (\a b -> splicedFile a == splicedFile b) splices
+ imports <- maybe (return Nothing) (catchMaybeIO . readFile) mheader
+ mapM_ (applySplices destdir imports) groups
diff --git a/Build/InstallDesktopFile.hs b/Build/InstallDesktopFile.hs
new file mode 100644
index 000000000..c8a3f07f5
--- /dev/null
+++ b/Build/InstallDesktopFile.hs
@@ -0,0 +1,19 @@
+{- Generating and installing a desktop menu entry file and icon,
+ - and a desktop autostart file. (And OSX equivilants.)
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Main where
+
+import Build.DesktopFile
+
+import System.Environment
+
+main :: IO ()
+main = getArgs >>= go
+ where
+ go [] = error "specify git-annex command"
+ go (command:_) = install command
diff --git a/Build/NullSoftInstaller.hs b/Build/NullSoftInstaller.hs
new file mode 100644
index 000000000..427507b02
--- /dev/null
+++ b/Build/NullSoftInstaller.hs
@@ -0,0 +1,139 @@
+{- Generates a NullSoft installer program for git-annex on Windows.
+ -
+ - To build the installer, git-annex should already be built by cabal,
+ - and ssh and rsync, as well as cygwin libraries, already installed.
+ -
+ - This uses the Haskell nsis package (cabal install nsis)
+ - to generate a .nsi file, which is then used to produce
+ - git-annex-installer.exe
+ -
+ - The installer includes git-annex, and utilities it uses, with the
+ - exception of git. The user needs to install git separately,
+ - and the installer checks for that.
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE OverloadedStrings #-}
+
+import Development.NSIS
+import System.Directory
+import System.FilePath
+import Control.Monad
+import Data.String
+import Data.Maybe
+
+import Utility.Tmp
+import Utility.Path
+import Utility.CopyFile
+import Utility.SafeCommand
+import Build.BundledPrograms
+
+main = do
+ withTmpDir "nsis-build" $ \tmpdir -> do
+ let gitannex = tmpdir </> gitannexprogram
+ mustSucceed "ln" [File "dist/build/git-annex/git-annex.exe", File gitannex]
+ let license = tmpdir </> licensefile
+ mustSucceed "sh" [Param "-c", Param $ "zcat standalone/licences.gz > '" ++ license ++ "'"]
+ extrafiles <- forM (cygwinPrograms ++ cygwinDlls) $ \f -> do
+ p <- searchPath f
+ when (isNothing p) $
+ print ("unable to find in PATH", f)
+ return p
+ writeFile nsifile $ makeInstaller gitannex license $
+ catMaybes extrafiles
+ mustSucceed "makensis" [File nsifile]
+ removeFile nsifile -- left behind if makensis fails
+ where
+ nsifile = "git-annex.nsi"
+ mustSucceed cmd params = do
+ r <- boolSystem cmd params
+ case r of
+ True -> return ()
+ False -> error $ cmd ++ " failed"
+
+gitannexprogram :: FilePath
+gitannexprogram = "git-annex.exe"
+
+licensefile :: FilePath
+licensefile = "git-annex-licenses.txt"
+
+installer :: FilePath
+installer = "git-annex-installer.exe"
+
+uninstaller :: FilePath
+uninstaller = "git-annex-uninstall.exe"
+
+gitInstallDir :: Exp FilePath
+gitInstallDir = fromString "$PROGRAMFILES\\Git\\cmd"
+
+needGit :: Exp String
+needGit = strConcat
+ [ fromString "You need git installed to use git-annex. Looking at "
+ , gitInstallDir
+ , fromString " , it seems to not be installed, "
+ , fromString "or may be installed in another location. "
+ , fromString "You can install git from http:////git-scm.com//"
+ ]
+
+makeInstaller :: FilePath -> FilePath -> [FilePath] -> String
+makeInstaller gitannex license extrafiles = nsis $ do
+ name "git-annex"
+ outFile $ str installer
+ {- Installing into the same directory as git avoids needing to modify
+ - path myself, since the git installer already does it. -}
+ installDir gitInstallDir
+ requestExecutionLevel User
+
+ iff (fileExists gitInstallDir)
+ (return ())
+ (alert needGit)
+
+ -- Pages to display
+ page Directory -- Pick where to install
+ page (License license)
+ page InstFiles -- Give a progress bar while installing
+ -- Groups of files to install
+ section "main" [] $ do
+ setOutPath "$INSTDIR"
+ addfile gitannex
+ addfile license
+ mapM_ addfile extrafiles
+ writeUninstaller $ str uninstaller
+ uninstall $
+ mapM_ (\f -> delete [RebootOK] $ fromString $ "$INSTDIR/" ++ f) $
+ [ gitannexprogram
+ , licensefile
+ , uninstaller
+ ] ++ cygwinPrograms ++ cygwinDlls
+ where
+ addfile f = file [] (str f)
+
+cygwinPrograms :: [FilePath]
+cygwinPrograms = map (\p -> p ++ ".exe") bundledPrograms
+
+-- These are the dlls needed by Cygwin's rsync, ssh, etc.
+cygwinDlls :: [FilePath]
+cygwinDlls =
+ [ "cygwin1.dll"
+ , "cygasn1-8.dll"
+ , "cygattr-1.dll"
+ , "cygheimbase-1.dll"
+ , "cygroken-18.dll"
+ , "cygcom_err-2.dll"
+ , "cygheimntlm-0.dll"
+ , "cygsqlite3-0.dll"
+ , "cygcrypt-0.dll"
+ , "cyghx509-5.dll"
+ , "cygssp-0.dll"
+ , "cygcrypto-1.0.0.dll"
+ , "cygiconv-2.dll"
+ , "cyggcc_s-1.dll"
+ , "cygintl-8.dll"
+ , "cygwind-0.dll"
+ , "cyggssapi-3.dll"
+ , "cygkrb5-26.dll"
+ , "cygz.dll"
+ ]
diff --git a/Build/OSXMkLibs.hs b/Build/OSXMkLibs.hs
new file mode 100644
index 000000000..dae9bc0ae
--- /dev/null
+++ b/Build/OSXMkLibs.hs
@@ -0,0 +1,157 @@
+{- OSX library copier
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Main where
+
+import Control.Applicative
+import System.Environment
+import Data.Maybe
+import System.FilePath
+import System.Directory
+import System.IO
+import Control.Monad
+import Data.List
+
+import Utility.PartialPrelude
+import Utility.Directory
+import Utility.Process
+import Utility.Monad
+import Utility.SafeCommand
+import Utility.Path
+import Utility.Exception
+
+import qualified Data.Map as M
+import qualified Data.Set as S
+
+type LibMap = M.Map FilePath String
+
+{- Recursively find and install libs, until nothing new to install is found. -}
+mklibs :: FilePath -> [FilePath] -> [(FilePath, FilePath)] -> LibMap -> IO ()
+mklibs appbase libdirs replacement_libs libmap = do
+ (new, replacement_libs', libmap') <- installLibs appbase replacement_libs libmap
+ unless (null new) $
+ mklibs appbase (libdirs++new) replacement_libs' libmap'
+
+{- Returns directories into which new libs were installed. -}
+installLibs :: FilePath -> [(FilePath, FilePath)] -> LibMap -> IO ([FilePath], [(FilePath, FilePath)], LibMap)
+installLibs appbase replacement_libs libmap = do
+ (needlibs, replacement_libs', libmap') <- otool appbase replacement_libs libmap
+ libs <- forM needlibs $ \lib -> do
+ let shortlib = fromMaybe (error "internal") (M.lookup lib libmap')
+ let fulllib = dropWhile (== '/') lib
+ let dest = appbase </> fulllib
+ let symdest = appbase </> shortlib
+ ifM (doesFileExist dest)
+ ( return Nothing
+ , do
+ createDirectoryIfMissing True (parentDir dest)
+ putStrLn $ "installing " ++ lib ++ " as " ++ shortlib
+ _ <- boolSystem "cp" [File lib, File dest]
+ _ <- boolSystem "chmod" [Param "644", File dest]
+ _ <- boolSystem "ln" [Param "-s", File fulllib, File symdest]
+ return $ Just appbase
+ )
+ return (catMaybes libs, replacement_libs', libmap')
+
+{- Returns libraries to install. -}
+otool :: FilePath -> [(FilePath, FilePath)] -> LibMap -> IO ([FilePath], [(FilePath, FilePath)], LibMap)
+otool appbase replacement_libs libmap = do
+ files <- filterM doesFileExist =<< dirContentsRecursive appbase
+ process [] files replacement_libs libmap
+ where
+ want s = not ("@executable_path" `isInfixOf` s)
+ && not (".framework" `isInfixOf` s)
+ && not ("libSystem.B" `isInfixOf` s)
+ process c [] rls m = return (nub $ concat c, rls, m)
+ process c (file:rest) rls m = do
+ _ <- boolSystem "chmod" [Param "755", File file]
+ libs <- filter want . parseOtool
+ <$> readProcess "otool" ["-L", file]
+ expanded_libs <- expand_rpath libs replacement_libs file
+ let rls' = nub $ rls ++ (zip libs expanded_libs)
+ m' <- install_name_tool file libs expanded_libs m
+ process (expanded_libs:c) rest rls' m'
+
+{- Expands any @rpath in the list of libraries.
+ -
+ - This is done by the nasty method of running the command with a dummy
+ - option (so it doesn't do anything.. hopefully!) and asking the dynamic
+ - linker to print expanded rpaths.
+ -}
+expand_rpath :: [String] -> [(FilePath, FilePath)] -> FilePath -> IO [String]
+expand_rpath libs replacement_libs cmd
+ | any ("@rpath" `isInfixOf`) libs = do
+ installed <- M.fromList . Prelude.read
+ <$> readFile "tmp/standalone-installed"
+ let origcmd = case M.lookup cmd installed of
+ Nothing -> cmd
+ Just cmd' -> cmd'
+ s <- catchDefaultIO "" $ readProcess "sh" ["-c", probe origcmd]
+ let m = if (null s)
+ then M.fromList replacement_libs
+ else M.fromList $ mapMaybe parse $ lines s
+ return $ map (replace m) libs
+ | otherwise = return libs
+ where
+ probe c = "DYLD_PRINT_RPATHS=1 " ++ c ++ " --getting-rpath-dummy-option 2>&1 | grep RPATH"
+ parse s = case words s of
+ ("RPATH":"successful":"expansion":"of":old:"to:":new:[]) ->
+ Just (old, new)
+ _ -> Nothing
+ replace m l = fromMaybe l $ M.lookup l m
+
+parseOtool :: String -> [FilePath]
+parseOtool = catMaybes . map parse . lines
+ where
+ parse l
+ | "\t" `isPrefixOf` l = headMaybe $ words l
+ | otherwise = Nothing
+
+{- Adjusts binaries to use libraries bundled with it, rather than the
+ - system libraries. -}
+install_name_tool :: FilePath -> [FilePath] -> [FilePath] -> LibMap -> IO LibMap
+install_name_tool _ [] _ libmap = return libmap
+install_name_tool binary libs expanded_libs libmap = do
+ let (libnames, libmap') = getLibNames expanded_libs libmap
+ let params = concatMap change $ zip libs libnames
+ ok <- boolSystem "install_name_tool" $ params ++ [File binary]
+ unless ok $
+ error $ "install_name_tool failed for " ++ binary
+ return libmap'
+ where
+ change (lib, libname) =
+ [ Param "-change"
+ , File lib
+ , Param $ "@executable_path/" ++ libname
+ ]
+
+getLibNames :: [FilePath] -> LibMap -> ([FilePath], LibMap)
+getLibNames libs libmap = go [] libs libmap
+ where
+ go c [] m = (reverse c, m)
+ go c (l:rest) m =
+ let (f, m') = getLibName l m
+ in go (f:c) rest m'
+
+{- Uses really short names for the library files it installs, because
+ - binaries have arbitrarily short RPATH field limits. -}
+getLibName :: FilePath -> LibMap -> (FilePath, LibMap)
+getLibName lib libmap = case M.lookup lib libmap of
+ Just n -> (n, libmap)
+ Nothing -> (nextfreename, M.insert lib nextfreename libmap)
+ where
+ names = map pure ['A' .. 'Z'] ++
+ [[n, l] | n <- ['0' .. '9'], l <- ['A' .. 'Z']]
+ used = S.fromList $ M.elems libmap
+ nextfreename = fromMaybe (error "ran out of short library names!") $
+ headMaybe $ dropWhile (`S.member` used) names
+
+main :: IO ()
+main = getArgs >>= go
+ where
+ go [] = error "specify OSXAPP_BASE"
+ go (appbase:_) = mklibs appbase [] [] M.empty
diff --git a/Build/Standalone.hs b/Build/Standalone.hs
new file mode 100644
index 000000000..343daf9c9
--- /dev/null
+++ b/Build/Standalone.hs
@@ -0,0 +1,54 @@
+{- Makes standalone bundle.
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Main where
+
+import Control.Applicative
+import Control.Monad.IfElse
+import System.Environment
+import Data.Maybe
+import System.FilePath
+import System.Directory
+import System.IO
+import Control.Monad
+import Data.List
+import Build.BundledPrograms
+
+import Utility.PartialPrelude
+import Utility.Directory
+import Utility.Process
+import Utility.Monad
+import Utility.SafeCommand
+import Utility.Path
+
+progDir :: FilePath -> FilePath
+#ifdef darwin_HOST_OS
+progDir topdir = topdir
+#else
+progDir topdir = topdir </> "bin"
+#endif
+
+installProg :: FilePath -> FilePath -> IO (FilePath, FilePath)
+installProg dir prog = searchPath prog >>= go
+ where
+ go Nothing = error $ "cannot find " ++ prog ++ " in PATH"
+ go (Just f) = do
+ let dest = dir </> takeFileName f
+ unlessM (boolSystem "install" [File f, File dest]) $
+ error $ "install failed for " ++ prog
+ return (dest, f)
+
+main = getArgs >>= go
+ where
+ go [] = error "specify topdir"
+ go (topdir:_) = do
+ let dir = progDir topdir
+ createDirectoryIfMissing True dir
+ installed <- forM bundledPrograms $ installProg dir
+ writeFile "tmp/standalone-installed" (show installed)
diff --git a/Build/TestConfig.hs b/Build/TestConfig.hs
new file mode 100644
index 000000000..8628ebe58
--- /dev/null
+++ b/Build/TestConfig.hs
@@ -0,0 +1,143 @@
+{- Tests the system and generates Build.SysConfig.hs. -}
+
+module Build.TestConfig where
+
+import Utility.Path
+import Utility.Monad
+import Utility.SafeCommand
+
+import System.IO
+import System.Cmd
+import System.Exit
+import System.FilePath
+import System.Directory
+
+type ConfigKey = String
+data ConfigValue =
+ BoolConfig Bool |
+ StringConfig String |
+ MaybeStringConfig (Maybe String) |
+ MaybeBoolConfig (Maybe Bool)
+data Config = Config ConfigKey ConfigValue
+
+type Test = IO Config
+type TestName = String
+data TestCase = TestCase TestName Test
+
+instance Show ConfigValue where
+ show (BoolConfig b) = show b
+ show (StringConfig s) = show s
+ show (MaybeStringConfig s) = show s
+ show (MaybeBoolConfig s) = show s
+
+instance Show Config where
+ show (Config key value) = unlines
+ [ key ++ " :: " ++ valuetype value
+ , key ++ " = " ++ show value
+ ]
+ where
+ valuetype (BoolConfig _) = "Bool"
+ valuetype (StringConfig _) = "String"
+ valuetype (MaybeStringConfig _) = "Maybe String"
+ valuetype (MaybeBoolConfig _) = "Maybe Bool"
+
+writeSysConfig :: [Config] -> IO ()
+writeSysConfig config = writeFile "Build/SysConfig.hs" body
+ where
+ body = unlines $ header ++ map show config ++ footer
+ header = [
+ "{- Automatically generated. -}"
+ , "module Build.SysConfig where"
+ , ""
+ ]
+ footer = []
+
+runTests :: [TestCase] -> IO [Config]
+runTests [] = return []
+runTests (TestCase tname t : ts) = do
+ testStart tname
+ c <- t
+ testEnd c
+ rest <- runTests ts
+ return $ c:rest
+
+{- Tests that a command is available, aborting if not. -}
+requireCmd :: ConfigKey -> String -> Test
+requireCmd k cmdline = do
+ ret <- testCmd k cmdline
+ handle ret
+ where
+ handle r@(Config _ (BoolConfig True)) = return r
+ handle r = do
+ testEnd r
+ error $ "** the " ++ c ++ " command is required"
+ c = head $ words cmdline
+
+{- Checks if a command is available by running a command line. -}
+testCmd :: ConfigKey -> String -> Test
+testCmd k cmdline = do
+ ok <- boolSystem "sh" [ Param "-c", Param $ quiet cmdline ]
+ return $ Config k (BoolConfig ok)
+
+{- Ensures that one of a set of commands is available by running each in
+ - turn. The Config is set to the first one found. -}
+selectCmd :: ConfigKey -> [(String, String)] -> Test
+selectCmd k = searchCmd
+ (return . Config k . StringConfig)
+ (\cmds -> do
+ testEnd $ Config k $ BoolConfig False
+ error $ "* need one of these commands, but none are available: " ++ show cmds
+ )
+
+maybeSelectCmd :: ConfigKey -> [(String, String)] -> Test
+maybeSelectCmd k = searchCmd
+ (return . Config k . MaybeStringConfig . Just)
+ (\_ -> return $ Config k $ MaybeStringConfig Nothing)
+
+searchCmd :: (String -> Test) -> ([String] -> Test) -> [(String, String)] -> Test
+searchCmd success failure cmdsparams = search cmdsparams
+ where
+ search [] = failure $ fst $ unzip cmdsparams
+ search ((c, params):cs) = do
+ ok <- boolSystem "sh" [ Param "-c", Param $ quiet $ c ++ " " ++ params ]
+ if ok
+ then success c
+ else search cs
+
+{- Finds a command, either in PATH or perhaps in a sbin directory not in
+ - PATH. If it's in PATH the config is set to just the command name,
+ - but if it's found outside PATH, the config is set to the full path to
+ - the command. -}
+findCmdPath :: ConfigKey -> String -> Test
+findCmdPath k command = do
+ ifM (inPath command)
+ ( return $ Config k $ MaybeStringConfig $ Just command
+ , do
+ r <- getM find ["/usr/sbin", "/sbin", "/usr/local/sbin"]
+ return $ Config k $ MaybeStringConfig r
+ )
+ where
+ find d =
+ let f = d </> command
+ in ifM (doesFileExist f) ( return (Just f), return Nothing )
+
+quiet :: String -> String
+quiet s = s ++ " >/dev/null 2>&1"
+
+testStart :: TestName -> IO ()
+testStart s = do
+ putStr $ " checking " ++ s ++ "..."
+ hFlush stdout
+
+testEnd :: Config -> IO ()
+testEnd (Config _ (BoolConfig True)) = status "yes"
+testEnd (Config _ (BoolConfig False)) = status "no"
+testEnd (Config _ (StringConfig s)) = status s
+testEnd (Config _ (MaybeStringConfig (Just s))) = status s
+testEnd (Config _ (MaybeStringConfig Nothing)) = status "not available"
+testEnd (Config _ (MaybeBoolConfig (Just True))) = status "yes"
+testEnd (Config _ (MaybeBoolConfig (Just False))) = status "no"
+testEnd (Config _ (MaybeBoolConfig Nothing)) = status "unknown"
+
+status :: String -> IO ()
+status s = putStrLn $ ' ':s
diff --git a/Build/Version.hs b/Build/Version.hs
new file mode 100644
index 000000000..7ff2fe662
--- /dev/null
+++ b/Build/Version.hs
@@ -0,0 +1,69 @@
+{- Package version determination, for configure script. -}
+
+module Build.Version where
+
+import Data.Maybe
+import Control.Applicative
+import Data.List
+import System.Environment
+import System.Directory
+import Data.Char
+import System.Process
+
+import Build.TestConfig
+import Utility.Monad
+import Utility.Exception
+
+{- Set when making an official release. (Distribution vendors should set
+ - this too.) -}
+isReleaseBuild :: IO Bool
+isReleaseBuild = isJust <$> catchMaybeIO (getEnv "RELEASE_BUILD")
+
+{- Version is usually based on the major version from the changelog,
+ - plus the date of the last commit, plus the git rev of that commit.
+ - This works for autobuilds, ad-hoc builds, etc.
+ -
+ - If git or a git repo is not available, or something goes wrong,
+ - or this is a release build, just use the version from the changelog. -}
+getVersion :: Test
+getVersion = do
+ changelogversion <- getChangelogVersion
+ version <- ifM (isReleaseBuild)
+ ( return changelogversion
+ , catchDefaultIO changelogversion $ do
+ let major = takeWhile (/= '.') changelogversion
+ autoversion <- takeWhile (\c -> isAlphaNum c || c == '-') <$> readProcess "sh"
+ [ "-c"
+ , "git log -n 1 --format=format:'%ci %h'| sed -e 's/-//g' -e 's/ .* /-g/'"
+ ] ""
+ if null autoversion
+ then return changelogversion
+ else return $ concat [ major, ".", autoversion ]
+ )
+ return $ Config "packageversion" (StringConfig version)
+
+getChangelogVersion :: IO String
+getChangelogVersion = do
+ changelog <- readFile "debian/changelog"
+ let verline = takeWhile (/= '\n') changelog
+ return $ middle (words verline !! 1)
+ where
+ middle = drop 1 . init
+
+{- Set up cabal file with version. -}
+cabalSetup :: FilePath -> IO ()
+cabalSetup cabalfile = do
+ version <- takeWhile (\c -> isDigit c || c == '.')
+ <$> getChangelogVersion
+ cabal <- readFile cabalfile
+ writeFile tmpcabalfile $ unlines $
+ map (setfield "Version" version) $
+ lines cabal
+ renameFile tmpcabalfile cabalfile
+ where
+ tmpcabalfile = cabalfile++".tmp"
+ setfield field value s
+ | fullfield `isPrefixOf` s = fullfield ++ value
+ | otherwise = s
+ where
+ fullfield = field ++ ": "
diff --git a/Build/make-sdist.sh b/Build/make-sdist.sh
new file mode 100755
index 000000000..950334532
--- /dev/null
+++ b/Build/make-sdist.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+#
+# Workaround for `cabal sdist` requiring all included files to be listed
+# in .cabal.
+
+# Create target directory
+sdist_dir=git-annex-$(grep '^Version:' git-annex.cabal | sed -re 's/Version: *//')
+mkdir --parents dist/$sdist_dir
+
+find . \( -name .git -or -name dist -or -name cabal-dev \) -prune \
+ -or -not -name \\*.orig -not -type d -print \
+| perl -ne "print unless length >= 100 - length q{$sdist_dir}" \
+| xargs cp --parents --target-directory dist/$sdist_dir
+
+cd dist
+tar -caf $sdist_dir.tar.gz $sdist_dir
+
+# Check that tarball can be unpacked by cabal.
+# It's picky about tar longlinks etc.
+rm -rf $sdist_dir
+cabal unpack $sdist_dir.tar.gz
diff --git a/Build/mdwn2man b/Build/mdwn2man
new file mode 100755
index 000000000..aadb13cdf
--- /dev/null
+++ b/Build/mdwn2man
@@ -0,0 +1,44 @@
+#!/usr/bin/env perl
+# Warning: hack
+
+my $prog=shift;
+my $section=shift;
+
+print ".TH $prog $section\n";
+
+while (<>) {
+ s{(\\?)\[\[([^\s\|\]]+)(\|[^\s\]]+)?\]\]}{$1 ? "[[$2]]" : $2}eg;
+ s/\`([^\`]*)\`/\\fB$1\\fP/g;
+ s/\`//g;
+ s/^\s*\./\\&./g;
+ if (/^#\s/) {
+ s/^#\s/.SH /;
+ <>; # blank;
+ }
+ s/^[ \n]+//;
+ s/^\t/ /;
+ s/-/\\-/g;
+ s/^Warning:.*//g;
+ s/^$/.PP\n/;
+ s/^\*\s+(.*)/.IP "$1"/;
+ next if $_ eq ".PP\n" && $skippara;
+ if (/^.IP /) {
+ $inlist=1;
+ $spippara=0;
+ }
+ elsif (/^.SH/) {
+ $skippara=0;
+ $inlist=0;
+ }
+ elsif (/^\./) {
+ $skippara=1;
+ }
+ else {
+ $skippara=0;
+ }
+ if ($inlist && $_ eq ".PP\n") {
+ $_=".IP\n";
+ }
+
+ print $_;
+}
diff --git a/BuildFlags.hs b/BuildFlags.hs
new file mode 100644
index 000000000..1dba47eaf
--- /dev/null
+++ b/BuildFlags.hs
@@ -0,0 +1,66 @@
+{- git-annex build flags reporting
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module BuildFlags where
+
+buildFlags :: [String]
+buildFlags = filter (not . null)
+ [ ""
+#ifdef WITH_ASSISTANT
+ , "Assistant"
+#endif
+#ifdef WITH_WEBAPP
+ , "Webapp"
+#endif
+#ifdef WITH_PAIRING
+ , "Pairing"
+#endif
+#ifdef WITH_TESTSUITE
+ , "Testsuite"
+#endif
+#ifdef WITH_S3
+ , "S3"
+#endif
+#ifdef WITH_WEBDAV
+ , "WebDAV"
+#endif
+#ifdef WITH_INOTIFY
+ , "Inotify"
+#endif
+#ifdef WITH_FSEVENTS
+ , "FsEvents"
+#endif
+#ifdef WITH_KQUEUE
+ , "Kqueue"
+#endif
+#ifdef WITH_DBUS
+ , "DBus"
+#endif
+#ifdef WITH_XMPP
+ , "XMPP"
+#endif
+#ifdef WITH_DNS
+ , "DNS"
+#endif
+#ifdef WITH_FEED
+ , "Feeds"
+#endif
+#ifdef WITH_QUVI
+ , "Quvi"
+#endif
+#ifdef WITH_TDFA
+ , "TDFA"
+#endif
+#ifdef WITH_CRYPTOHASH
+ , "CryptoHash"
+#endif
+#ifdef WITH_EKG
+ , "EKG"
+#endif
+ ]
diff --git a/CHANGELOG b/CHANGELOG
new file mode 120000
index 000000000..d526672ce
--- /dev/null
+++ b/CHANGELOG
@@ -0,0 +1 @@
+debian/changelog \ No newline at end of file
diff --git a/COPYRIGHT b/COPYRIGHT
new file mode 120000
index 000000000..9060ce820
--- /dev/null
+++ b/COPYRIGHT
@@ -0,0 +1 @@
+debian/copyright \ No newline at end of file
diff --git a/Checks.hs b/Checks.hs
new file mode 100644
index 000000000..67aa51a2a
--- /dev/null
+++ b/Checks.hs
@@ -0,0 +1,49 @@
+{- git-annex command checks
+ -
+ - Common sanity checks for commands, and an interface to selectively
+ - remove them, or add others.
+ -
+ - Copyright 2011-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Checks where
+
+import Common.Annex
+import Types.Command
+import Init
+import Config
+import Utility.Daemon
+import qualified Git
+
+commonChecks :: [CommandCheck]
+commonChecks = [repoExists]
+
+repoExists :: CommandCheck
+repoExists = CommandCheck 0 ensureInitialized
+
+notDirect :: Command -> Command
+notDirect = addCheck $ whenM isDirect $
+ error "You cannot run this command in a direct mode repository."
+
+notBareRepo :: Command -> Command
+notBareRepo = addCheck $ whenM (fromRepo Git.repoIsLocalBare) $
+ error "You cannot run this command in a bare repository."
+
+noDaemonRunning :: Command -> Command
+noDaemonRunning = addCheck $ whenM (isJust <$> daemonpid) $
+ error "You cannot run this command while git-annex watch or git-annex assistant is running."
+ where
+ daemonpid = liftIO . checkDaemon =<< fromRepo gitAnnexPidFile
+
+dontCheck :: CommandCheck -> Command -> Command
+dontCheck check cmd = mutateCheck cmd $ \c -> filter (/= check) c
+
+addCheck :: Annex () -> Command -> Command
+addCheck check cmd = mutateCheck cmd $ \c ->
+ CommandCheck (length c + 100) check : c
+
+mutateCheck :: Command -> ([CommandCheck] -> [CommandCheck]) -> Command
+mutateCheck cmd@(Command { cmdcheck = c }) a = cmd { cmdcheck = a c }
+
diff --git a/CmdLine.hs b/CmdLine.hs
new file mode 100644
index 000000000..83a89ef7d
--- /dev/null
+++ b/CmdLine.hs
@@ -0,0 +1,138 @@
+{- git-annex command line parsing and dispatch
+ -
+ - Copyright 2010-2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module CmdLine (
+ dispatch,
+ usage,
+ shutdown
+) where
+
+import qualified Control.Exception as E
+import qualified Data.Map as M
+import Control.Exception (throw)
+import System.Console.GetOpt
+#ifndef mingw32_HOST_OS
+import System.Posix.Signals
+#endif
+
+import Common.Annex
+import qualified Annex
+import qualified Annex.Queue
+import qualified Git
+import qualified Git.AutoCorrect
+import Annex.Content
+import Annex.Ssh
+import Annex.Environment
+import Command
+import Types.Messages
+
+type Params = [String]
+type Flags = [Annex ()]
+
+{- Runs the passed command line. -}
+dispatch :: Bool -> Params -> [Command] -> [Option] -> [(String, String)] -> String -> IO Git.Repo -> IO ()
+dispatch fuzzyok allargs allcmds commonoptions fields header getgitrepo = do
+ setupConsole
+ r <- E.try getgitrepo :: IO (Either E.SomeException Git.Repo)
+ case r of
+ Left e -> fromMaybe (throw e) (cmdnorepo cmd)
+ Right g -> do
+ state <- Annex.new g
+ (actions, state') <- Annex.run state $ do
+ checkEnvironment
+ checkfuzzy
+ forM_ fields $ uncurry Annex.setField
+ when (cmdnomessages cmd) $
+ Annex.setOutput QuietOutput
+ sequence_ flags
+ whenM (annexDebug <$> Annex.getGitConfig) $
+ liftIO enableDebugOutput
+ prepCommand cmd params
+ tryRun state' cmd $ [startup] ++ actions ++ [shutdown $ cmdnocommit cmd]
+ where
+ err msg = msg ++ "\n\n" ++ usage header allcmds
+ cmd = Prelude.head cmds
+ (fuzzy, cmds, name, args) = findCmd fuzzyok allargs allcmds err
+ (flags, params) = getOptCmd args cmd commonoptions
+ checkfuzzy = when fuzzy $
+ inRepo $ Git.AutoCorrect.prepare name cmdname cmds
+
+{- Parses command line params far enough to find the Command to run, and
+ - returns the remaining params.
+ - Does fuzzy matching if necessary, which may result in multiple Commands. -}
+findCmd :: Bool -> Params -> [Command] -> (String -> String) -> (Bool, [Command], String, Params)
+findCmd fuzzyok argv cmds err
+ | isNothing name = error $ err "missing command"
+ | not (null exactcmds) = (False, exactcmds, fromJust name, args)
+ | fuzzyok && not (null inexactcmds) = (True, inexactcmds, fromJust name, args)
+ | otherwise = error $ err $ "unknown command " ++ fromJust name
+ where
+ (name, args) = findname argv []
+ findname [] c = (Nothing, reverse c)
+ findname (a:as) c
+ | "-" `isPrefixOf` a = findname as (a:c)
+ | otherwise = (Just a, reverse c ++ as)
+ exactcmds = filter (\c -> name == Just (cmdname c)) cmds
+ inexactcmds = case name of
+ Nothing -> []
+ Just n -> Git.AutoCorrect.fuzzymatches n cmdname cmds
+
+{- Parses command line options, and returns actions to run to configure flags
+ - and the remaining parameters for the command. -}
+getOptCmd :: Params -> Command -> [Option] -> (Flags, Params)
+getOptCmd argv cmd commonoptions = check $
+ getOpt Permute (commonoptions ++ cmdoptions cmd) argv
+ where
+ check (flags, rest, []) = (flags, rest)
+ check (_, _, errs) = error $ unlines
+ [ concat errs
+ , commandUsage cmd
+ ]
+
+{- Runs a list of Annex actions. Catches IO errors and continues
+ - (but explicitly thrown errors terminate the whole command).
+ -}
+tryRun :: Annex.AnnexState -> Command -> [CommandCleanup] -> IO ()
+tryRun = tryRun' 0
+tryRun' :: Integer -> Annex.AnnexState -> Command -> [CommandCleanup] -> IO ()
+tryRun' errnum _ cmd []
+ | errnum > 0 = error $ cmdname cmd ++ ": " ++ show errnum ++ " failed"
+ | otherwise = noop
+tryRun' errnum state cmd (a:as) = do
+ r <- run
+ handle $! r
+ where
+ run = tryIO $ Annex.run state $ do
+ Annex.Queue.flushWhenFull
+ a
+ handle (Left err) = showerr err >> cont False state
+ handle (Right (success, state')) = cont success state'
+ cont success s = do
+ let errnum' = if success then errnum else errnum + 1
+ (tryRun' $! errnum') s cmd as
+ showerr err = Annex.eval state $ do
+ showErr err
+ showEndFail
+
+{- Actions to perform each time ran. -}
+startup :: Annex Bool
+startup = liftIO $ do
+#ifndef mingw32_HOST_OS
+ void $ installHandler sigINT Default Nothing
+#endif
+ return True
+
+{- Cleanup actions. -}
+shutdown :: Bool -> Annex Bool
+shutdown nocommit = do
+ saveState nocommit
+ sequence_ =<< M.elems <$> Annex.getState Annex.cleanup
+ liftIO reapZombies -- zombies from long-running git processes
+ sshCleanup -- ssh connection caching
+ return True
diff --git a/Command.hs b/Command.hs
new file mode 100644
index 000000000..2c157304f
--- /dev/null
+++ b/Command.hs
@@ -0,0 +1,123 @@
+{- git-annex command infrastructure
+ -
+ - Copyright 2010-2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command (
+ command,
+ noRepo,
+ noCommit,
+ noMessages,
+ withOptions,
+ next,
+ stop,
+ stopUnless,
+ prepCommand,
+ doCommand,
+ whenAnnexed,
+ ifAnnexed,
+ isBareRepo,
+ numCopies,
+ numCopiesCheck,
+ checkAuto,
+ module ReExported
+) where
+
+import Common.Annex
+import qualified Backend
+import qualified Annex
+import qualified Git
+import qualified Remote
+import Types.Command as ReExported
+import Types.Option as ReExported
+import Seek as ReExported
+import Checks as ReExported
+import Usage as ReExported
+import Logs.Trust
+import Config
+import Annex.CheckAttr
+
+{- Generates a normal command -}
+command :: String -> String -> [CommandSeek] -> CommandSection -> String -> Command
+command = Command [] Nothing commonChecks False False
+
+{- Indicates that a command doesn't need to commit any changes to
+ - the git-annex branch. -}
+noCommit :: Command -> Command
+noCommit c = c { cmdnocommit = True }
+
+{- Indicates that a command should not output anything other than what
+ - it directly sends to stdout. (--json can override this). -}
+noMessages :: Command -> Command
+noMessages c = c { cmdnomessages = True }
+
+{- Adds a fallback action to a command, that will be run if it's used
+ - outside a git repository. -}
+noRepo :: IO () -> Command -> Command
+noRepo a c = c { cmdnorepo = Just a }
+
+{- Adds options to a command. -}
+withOptions :: [Option] -> Command -> Command
+withOptions o c = c { cmdoptions = o }
+
+{- For start and perform stages to indicate what step to run next. -}
+next :: a -> Annex (Maybe a)
+next a = return $ Just a
+
+{- Or to indicate nothing needs to be done. -}
+stop :: Annex (Maybe a)
+stop = return Nothing
+
+{- Stops unless a condition is met. -}
+stopUnless :: Annex Bool -> Annex (Maybe a) -> Annex (Maybe a)
+stopUnless c a = ifM c ( a , stop )
+
+{- Prepares to run a command via the check and seek stages, returning a
+ - list of actions to perform to run the command. -}
+prepCommand :: Command -> [String] -> Annex [CommandCleanup]
+prepCommand Command { cmdseek = seek, cmdcheck = c } params = do
+ mapM_ runCheck c
+ map doCommand . concat <$> mapM (\s -> s params) seek
+
+{- Runs a command through the start, perform and cleanup stages -}
+doCommand :: CommandStart -> CommandCleanup
+doCommand = start
+ where
+ start = stage $ maybe skip perform
+ perform = stage $ maybe failure cleanup
+ cleanup = stage $ status
+ stage = (=<<)
+ skip = return True
+ failure = showEndFail >> return False
+ status r = showEndResult r >> return r
+
+{- Modifies an action to only act on files that are already annexed,
+ - and passes the key and backend on to it. -}
+whenAnnexed :: (FilePath -> (Key, Backend) -> Annex (Maybe a)) -> FilePath -> Annex (Maybe a)
+whenAnnexed a file = ifAnnexed file (a file) (return Nothing)
+
+ifAnnexed :: FilePath -> ((Key, Backend) -> Annex a) -> Annex a -> Annex a
+ifAnnexed file yes no = maybe no yes =<< Backend.lookupFile file
+
+isBareRepo :: Annex Bool
+isBareRepo = fromRepo Git.repoIsLocalBare
+
+numCopies :: FilePath -> Annex (Maybe Int)
+numCopies file = do
+ forced <- Annex.getState Annex.forcenumcopies
+ case forced of
+ Just n -> return $ Just n
+ Nothing -> readish <$> checkAttr "annex.numcopies" file
+
+numCopiesCheck :: FilePath -> Key -> (Int -> Int -> v) -> Annex v
+numCopiesCheck file key vs = do
+ numcopiesattr <- numCopies file
+ needed <- getNumCopies numcopiesattr
+ have <- trustExclude UnTrusted =<< Remote.keyLocations key
+ return $ length have `vs` needed
+
+checkAuto :: Annex Bool -> Annex Bool
+checkAuto checker = ifM (Annex.getState Annex.auto)
+ ( checker , return True )
diff --git a/Command/Add.hs b/Command/Add.hs
new file mode 100644
index 000000000..9f1beb28a
--- /dev/null
+++ b/Command/Add.hs
@@ -0,0 +1,261 @@
+{- git-annex command
+ -
+ - Copyright 2010, 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Command.Add where
+
+import System.PosixCompat.Files
+
+import Common.Annex
+import Annex.Exception
+import Command
+import Types.KeySource
+import Backend
+import Logs.Location
+import Annex.Content
+import Annex.Content.Direct
+import Annex.Perms
+import Annex.Link
+import qualified Annex
+import qualified Annex.Queue
+#ifdef WITH_CLIBS
+#ifndef __ANDROID__
+import Utility.Touch
+#endif
+#endif
+import Config
+import Utility.InodeCache
+import Annex.FileMatcher
+import Annex.ReplaceFile
+import Utility.Tmp
+
+def :: [Command]
+def = [notBareRepo $ command "add" paramPaths seek SectionCommon
+ "add files to annex"]
+
+{- Add acts on both files not checked into git yet, and unlocked files.
+ -
+ - In direct mode, it acts on any files that have changed. -}
+seek :: [CommandSeek]
+seek =
+ [ go withFilesNotInGit
+ , whenNotDirect $ go withFilesUnlocked
+ , whenDirect $ go withFilesMaybeModified
+ ]
+ where
+ go a = withValue largeFilesMatcher $ \matcher ->
+ a $ \file -> ifM (checkFileMatcher matcher file <||> Annex.getState Annex.force)
+ ( start file
+ , stop
+ )
+
+{- The add subcommand annexes a file, generating a key for it using a
+ - backend, and then moving it into the annex directory and setting up
+ - the symlink pointing to its content. -}
+start :: FilePath -> CommandStart
+start file = ifAnnexed file addpresent add
+ where
+ add = do
+ ms <- liftIO $ catchMaybeIO $ getSymbolicLinkStatus file
+ case ms of
+ Nothing -> stop
+ Just s
+ | isSymbolicLink s || not (isRegularFile s) -> stop
+ | otherwise -> do
+ showStart "add" file
+ next $ perform file
+ addpresent (key, _) = ifM isDirect
+ ( ifM (goodContent key file) ( stop , add )
+ , fixup key
+ )
+ fixup key = do
+ -- fixup from an interrupted add; the symlink
+ -- is present but not yet added to git
+ showStart "add" file
+ liftIO $ removeFile file
+ next $ next $ cleanup file key Nothing =<< inAnnex key
+
+{- The file that's being added is locked down before a key is generated,
+ - to prevent it from being modified in between. This lock down is not
+ - perfect at best (and pretty weak at worst). For example, it does not
+ - guard against files that are already opened for write by another process.
+ - So a KeySource is returned. Its inodeCache can be used to detect any
+ - changes that might be made to the file after it was locked down.
+ -
+ - When possible, the file is hard linked to a temp directory. This guards
+ - against some changes, like deletion or overwrite of the file, and
+ - allows lsof checks to be done more efficiently when adding a lot of files.
+ -
+ - Lockdown can fail if a file gets deleted, and Nothing will be returned.
+ -}
+lockDown :: FilePath -> Annex (Maybe KeySource)
+lockDown file = ifM crippledFileSystem
+ ( liftIO $ catchMaybeIO nohardlink
+ , do
+ tmp <- fromRepo gitAnnexTmpDir
+ createAnnexDirectory tmp
+ eitherToMaybe <$> tryAnnexIO (go tmp)
+ )
+ where
+ {- In indirect mode, the write bit is removed from the file as part
+ - of lock down to guard against further writes, and because objects
+ - in the annex have their write bit disabled anyway.
+ -
+ - Freezing the content early also lets us fail early when
+ - someone else owns the file.
+ -
+ - This is not done in direct mode, because files there need to
+ - remain writable at all times.
+ -}
+ go tmp = do
+ unlessM isDirect $
+ freezeContent file
+ liftIO $ do
+ (tmpfile, h) <- openTempFile tmp $
+ relatedTemplate $ takeFileName file
+ hClose h
+ nukeFile tmpfile
+ withhardlink tmpfile `catchIO` const nohardlink
+ nohardlink = do
+ cache <- genInodeCache file
+ return KeySource
+ { keyFilename = file
+ , contentLocation = file
+ , inodeCache = cache
+ }
+ withhardlink tmpfile = do
+ createLink file tmpfile
+ cache <- genInodeCache tmpfile
+ return KeySource
+ { keyFilename = file
+ , contentLocation = tmpfile
+ , inodeCache = cache
+ }
+
+{- Ingests a locked down file into the annex.
+ -
+ - In direct mode, leaves the file alone, and just updates bookkeeping
+ - information.
+ -}
+ingest :: Maybe KeySource -> Annex (Maybe Key, Maybe InodeCache)
+ingest Nothing = return (Nothing, Nothing)
+ingest (Just source) = do
+ backend <- chooseBackend $ keyFilename source
+ k <- genKey source backend
+ cache <- liftIO $ genInodeCache $ contentLocation source
+ case (cache, inodeCache source) of
+ (_, Nothing) -> go k cache
+ (Just newc, Just c) | compareStrong c newc -> go k cache
+ _ -> failure "changed while it was being added"
+ where
+ go k cache = ifM isDirect ( godirect k cache , goindirect k cache )
+
+ goindirect (Just (key, _)) mcache = do
+ catchAnnex (moveAnnex key $ contentLocation source)
+ (undo (keyFilename source) key)
+ liftIO $ nukeFile $ keyFilename source
+ return $ (Just key, mcache)
+ goindirect Nothing _ = failure "failed to generate a key"
+
+ godirect (Just (key, _)) (Just cache) = do
+ addInodeCache key cache
+ finishIngestDirect key source
+ return $ (Just key, Just cache)
+ godirect _ _ = failure "failed to generate a key"
+
+ failure msg = do
+ warning $ keyFilename source ++ " " ++ msg
+ when (contentLocation source /= keyFilename source) $
+ liftIO $ nukeFile $ contentLocation source
+ return (Nothing, Nothing)
+
+finishIngestDirect :: Key -> KeySource -> Annex ()
+finishIngestDirect key source = do
+ void $ addAssociatedFile key $ keyFilename source
+ when (contentLocation source /= keyFilename source) $
+ liftIO $ nukeFile $ contentLocation source
+
+ {- Copy to any other locations using the same key. -}
+ otherfs <- filter (/= keyFilename source) <$> associatedFiles key
+ forM_ otherfs $
+ addContentWhenNotPresent key (keyFilename source)
+
+perform :: FilePath -> CommandPerform
+perform file = lockDown file >>= ingest >>= go
+ where
+ go (Just key, cache) = next $ cleanup file key cache True
+ go (Nothing, _) = stop
+
+{- On error, put the file back so it doesn't seem to have vanished.
+ - This can be called before or after the symlink is in place. -}
+undo :: FilePath -> Key -> IOException -> Annex a
+undo file key e = do
+ whenM (inAnnex key) $ do
+ liftIO $ nukeFile file
+ catchAnnex (fromAnnex key file) tryharder
+ logStatus key InfoMissing
+ throwAnnex e
+ where
+ -- fromAnnex could fail if the file ownership is weird
+ tryharder :: IOException -> Annex ()
+ tryharder _ = do
+ src <- calcRepo $ gitAnnexLocation key
+ liftIO $ moveFile src file
+
+{- Creates the symlink to the annexed content, returns the link target. -}
+link :: FilePath -> Key -> Maybe InodeCache -> Annex String
+link file key mcache = flip catchAnnex (undo file key) $ do
+ l <- inRepo $ gitAnnexLink file key
+ replaceFile file $ makeAnnexLink l
+
+#ifdef WITH_CLIBS
+#ifndef __ANDROID__
+ -- touch symlink to have same time as the original file,
+ -- as provided in the InodeCache
+ case mcache of
+ Just c -> liftIO $ touch file (TimeSpec $ inodeCacheToMtime c) False
+ Nothing -> noop
+#endif
+#endif
+
+ return l
+
+{- Creates the symlink to the annexed content, and stages it in git.
+ -
+ - As long as the filesystem supports symlinks, we use
+ - git add, rather than directly staging the symlink to git.
+ - Using git add is best because it allows the queuing to work
+ - and is faster (staging the symlink runs hash-object commands each time).
+ - Also, using git add allows it to skip gitignored files, unless forced
+ - to include them.
+ -}
+addLink :: FilePath -> Key -> Maybe InodeCache -> Annex ()
+addLink file key mcache = ifM (coreSymlinks <$> Annex.getGitConfig)
+ ( do
+ _ <- link file key mcache
+ params <- ifM (Annex.getState Annex.force)
+ ( return [Param "-f"]
+ , return []
+ )
+ Annex.Queue.addCommand "add" (params++[Param "--"]) [file]
+ , do
+ l <- link file key mcache
+ addAnnexLink l file
+ )
+
+cleanup :: FilePath -> Key -> Maybe InodeCache -> Bool -> CommandCleanup
+cleanup file key mcache hascontent = do
+ when hascontent $
+ logStatus key InfoPresent
+ ifM (isDirect <&&> pure hascontent)
+ ( do
+ l <- inRepo $ gitAnnexLink file key
+ stageSymlink file =<< hashSymlink l
+ , addLink file key mcache
+ )
+ return True
diff --git a/Command/AddUnused.hs b/Command/AddUnused.hs
new file mode 100644
index 000000000..1a178e8d4
--- /dev/null
+++ b/Command/AddUnused.hs
@@ -0,0 +1,41 @@
+{- git-annex command
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.AddUnused where
+
+import Common.Annex
+import Logs.Location
+import Command
+import qualified Command.Add
+import Command.Unused (withUnusedMaps, UnusedMaps(..), startUnused)
+import Types.Key
+
+def :: [Command]
+def = [notDirect $ command "addunused" (paramRepeating paramNumRange)
+ seek SectionMaintenance "add back unused files"]
+
+seek :: [CommandSeek]
+seek = [withUnusedMaps start]
+
+start :: UnusedMaps -> Int -> CommandStart
+start = startUnused "addunused" perform
+ (performOther "bad")
+ (performOther "tmp")
+
+perform :: Key -> CommandPerform
+perform key = next $ do
+ logStatus key InfoPresent
+ Command.Add.addLink file key Nothing
+ return True
+ where
+ file = "unused." ++ key2file key
+
+{- The content is not in the annex, but in another directory, and
+ - it seems better to error out, rather than moving bad/tmp content into
+ - the annex. -}
+performOther :: String -> Key -> CommandPerform
+performOther other _ = error $ "cannot addunused " ++ other ++ "content"
diff --git a/Command/AddUrl.hs b/Command/AddUrl.hs
new file mode 100644
index 000000000..27ca72d1a
--- /dev/null
+++ b/Command/AddUrl.hs
@@ -0,0 +1,231 @@
+{- git-annex command
+ -
+ - Copyright 2011-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Command.AddUrl where
+
+import Network.URI
+
+import Common.Annex
+import Command
+import Backend
+import qualified Command.Add
+import qualified Annex
+import qualified Annex.Queue
+import qualified Annex.Url as Url
+import qualified Backend.URL
+import Annex.Content
+import Logs.Web
+import qualified Option
+import Types.Key
+import Types.KeySource
+import Config
+import Annex.Content.Direct
+import Logs.Location
+import qualified Logs.Transfer as Transfer
+import Utility.Daemon (checkDaemon)
+#ifdef WITH_QUVI
+import Annex.Quvi
+import qualified Utility.Quvi as Quvi
+#endif
+
+def :: [Command]
+def = [notBareRepo $ withOptions [fileOption, pathdepthOption, relaxedOption] $
+ command "addurl" (paramRepeating paramUrl) seek
+ SectionCommon "add urls to annex"]
+
+fileOption :: Option
+fileOption = Option.field [] "file" paramFile "specify what file the url is added to"
+
+pathdepthOption :: Option
+pathdepthOption = Option.field [] "pathdepth" paramNumber "path components to use in filename"
+
+relaxedOption :: Option
+relaxedOption = Option.flag [] "relaxed" "skip size check"
+
+seek :: [CommandSeek]
+seek = [withField fileOption return $ \f ->
+ withFlag relaxedOption $ \relaxed ->
+ withField pathdepthOption (return . maybe Nothing readish) $ \d ->
+ withStrings $ start relaxed f d]
+
+start :: Bool -> Maybe FilePath -> Maybe Int -> String -> CommandStart
+start relaxed optfile pathdepth s = go $ fromMaybe bad $ parseURI s
+ where
+ (s', downloader) = getDownloader s
+ bad = fromMaybe (error $ "bad url " ++ s') $
+ parseURI $ escapeURIString isUnescapedInURI s'
+ choosefile = flip fromMaybe optfile
+ go url = case downloader of
+ QuviDownloader -> usequvi
+ DefaultDownloader ->
+#ifdef WITH_QUVI
+ ifM (liftIO $ Quvi.supported s')
+ ( usequvi
+ , regulardownload url
+ )
+#else
+ regulardownload url
+#endif
+ regulardownload url = do
+ pathmax <- liftIO $ fileNameLengthLimit "."
+ let file = choosefile $ url2file url pathdepth pathmax
+ showStart "addurl" file
+ next $ perform relaxed s' file
+#ifdef WITH_QUVI
+ badquvi = error $ "quvi does not know how to download url " ++ s'
+ usequvi = do
+ page <- fromMaybe badquvi
+ <$> withQuviOptions Quvi.forceQuery [Quvi.quiet, Quvi.httponly] s'
+ let link = fromMaybe badquvi $ headMaybe $ Quvi.pageLinks page
+ pathmax <- liftIO $ fileNameLengthLimit "."
+ let file = choosefile $ truncateFilePath pathmax $ sanitizeFilePath $
+ Quvi.pageTitle page ++ "." ++ Quvi.linkSuffix link
+ showStart "addurl" file
+ next $ performQuvi relaxed s' (Quvi.linkUrl link) file
+#else
+ usequvi = error "not built with quvi support"
+#endif
+
+#ifdef WITH_QUVI
+performQuvi :: Bool -> URLString -> URLString -> FilePath -> CommandPerform
+performQuvi relaxed pageurl videourl file = ifAnnexed file addurl geturl
+ where
+ quviurl = setDownloader pageurl QuviDownloader
+ addurl (key, _backend) = next $ cleanup quviurl file key Nothing
+ geturl = do
+ key <- Backend.URL.fromUrl quviurl Nothing
+ ifM (pure relaxed <||> Annex.getState Annex.fast)
+ ( next $ cleanup quviurl file key Nothing
+ , do
+ tmp <- fromRepo $ gitAnnexTmpLocation key
+ showOutput
+ ok <- Transfer.download webUUID key (Just file) Transfer.forwardRetry $ const $ do
+ liftIO $ createDirectoryIfMissing True (parentDir tmp)
+ downloadUrl [videourl] tmp
+ if ok
+ then next $ cleanup quviurl file key (Just tmp)
+ else stop
+ )
+#endif
+
+perform :: Bool -> URLString -> FilePath -> CommandPerform
+perform relaxed url file = ifAnnexed file addurl geturl
+ where
+ geturl = next $ addUrlFile relaxed url file
+ addurl (key, _backend)
+ | relaxed = do
+ setUrlPresent key url
+ next $ return True
+ | otherwise = do
+ headers <- getHttpHeaders
+ (exists, samesize) <- Url.withUserAgent $ Url.check url headers $ keySize key
+ if exists && samesize
+ then do
+ setUrlPresent key url
+ next $ return True
+ else do
+ warning $ if exists
+ then "url does not have expected file size (use --relaxed to bypass this check) " ++ url
+ else "failed to verify url exists: " ++ url
+ stop
+
+addUrlFile :: Bool -> URLString -> FilePath -> Annex Bool
+addUrlFile relaxed url file = do
+ liftIO $ createDirectoryIfMissing True (parentDir file)
+ ifM (Annex.getState Annex.fast <||> pure relaxed)
+ ( nodownload relaxed url file
+ , do
+ showAction $ "downloading " ++ url ++ " "
+ download url file
+ )
+
+download :: URLString -> FilePath -> Annex Bool
+download url file = do
+ dummykey <- genkey
+ tmp <- fromRepo $ gitAnnexTmpLocation dummykey
+ showOutput
+ ifM (runtransfer dummykey tmp)
+ ( do
+ backend <- chooseBackend file
+ let source = KeySource
+ { keyFilename = file
+ , contentLocation = tmp
+ , inodeCache = Nothing
+ }
+ k <- genKey source backend
+ case k of
+ Nothing -> return False
+ Just (key, _) -> cleanup url file key (Just tmp)
+ , return False
+ )
+ where
+ {- Generate a dummy key to use for this download, before we can
+ - examine the file and find its real key. This allows resuming
+ - downloads, as the dummy key for a given url is stable.
+ -
+ - If the assistant is running, actually hits the url here,
+ - to get the size, so it can display a pretty progress bar.
+ -}
+ genkey = do
+ pidfile <- fromRepo gitAnnexPidFile
+ size <- ifM (liftIO $ isJust <$> checkDaemon pidfile)
+ ( do
+ headers <- getHttpHeaders
+ snd <$> Url.withUserAgent (Url.exists url headers)
+ , return Nothing
+ )
+ Backend.URL.fromUrl url size
+ runtransfer dummykey tmp =
+ Transfer.download webUUID dummykey (Just file) Transfer.forwardRetry $ const $ do
+ liftIO $ createDirectoryIfMissing True (parentDir tmp)
+ downloadUrl [url] tmp
+
+
+cleanup :: URLString -> FilePath -> Key -> Maybe FilePath -> Annex Bool
+cleanup url file key mtmp = do
+ when (isJust mtmp) $
+ logStatus key InfoPresent
+ setUrlPresent key url
+ Command.Add.addLink file key Nothing
+ whenM isDirect $ do
+ void $ addAssociatedFile key file
+ {- For moveAnnex to work in direct mode, the symlink
+ - must already exist, so flush the queue. -}
+ Annex.Queue.flush
+ maybe noop (moveAnnex key) mtmp
+ return True
+
+nodownload :: Bool -> URLString -> FilePath -> Annex Bool
+nodownload relaxed url file = do
+ headers <- getHttpHeaders
+ (exists, size) <- if relaxed
+ then pure (True, Nothing)
+ else Url.withUserAgent $ Url.exists url headers
+ if exists
+ then do
+ key <- Backend.URL.fromUrl url size
+ cleanup url file key Nothing
+ else do
+ warning $ "unable to access url: " ++ url
+ return False
+
+url2file :: URI -> Maybe Int -> Int -> FilePath
+url2file url pathdepth pathmax = case pathdepth of
+ Nothing -> truncateFilePath pathmax $ sanitizeFilePath fullurl
+ Just depth
+ | depth >= length urlbits -> frombits id
+ | depth > 0 -> frombits $ drop depth
+ | depth < 0 -> frombits $ reverse . take (negate depth) . reverse
+ | otherwise -> error "bad --pathdepth"
+ where
+ fullurl = uriRegName auth ++ uriPath url ++ uriQuery url
+ frombits a = intercalate "/" $ a urlbits
+ urlbits = map (truncateFilePath pathmax . sanitizeFilePath) $
+ filter (not . null) $ split "/" fullurl
+ auth = fromMaybe (error $ "bad url " ++ show url) $ uriAuthority url
diff --git a/Command/Assistant.hs b/Command/Assistant.hs
new file mode 100644
index 000000000..521a88571
--- /dev/null
+++ b/Command/Assistant.hs
@@ -0,0 +1,88 @@
+{- git-annex assistant
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Assistant where
+
+import Common.Annex
+import Command
+import qualified Option
+import qualified Command.Watch
+import Init
+import Config.Files
+import qualified Build.SysConfig
+import Utility.HumanTime
+
+import System.Environment
+
+def :: [Command]
+def = [noRepo checkAutoStart $ dontCheck repoExists $ withOptions options $
+ command "assistant" paramNothing seek SectionCommon
+ "automatically handle changes"]
+
+options :: [Option]
+options =
+ [ Command.Watch.foregroundOption
+ , Command.Watch.stopOption
+ , autoStartOption
+ , startDelayOption
+ ]
+
+autoStartOption :: Option
+autoStartOption = Option.flag [] "autostart" "start in known repositories"
+
+startDelayOption :: Option
+startDelayOption = Option.field [] "startdelay" paramNumber "delay before running startup scan"
+
+seek :: [CommandSeek]
+seek = [withFlag Command.Watch.stopOption $ \stopdaemon ->
+ withFlag Command.Watch.foregroundOption $ \foreground ->
+ withFlag autoStartOption $ \autostart ->
+ withField startDelayOption (pure . maybe Nothing parseDuration) $ \startdelay ->
+ withNothing $ start foreground stopdaemon autostart startdelay]
+
+start :: Bool -> Bool -> Bool -> Maybe Duration -> CommandStart
+start foreground stopdaemon autostart startdelay
+ | autostart = do
+ liftIO $ autoStart startdelay
+ stop
+ | otherwise = do
+ ensureInitialized
+ Command.Watch.start True foreground stopdaemon startdelay
+
+{- Run outside a git repository. Check to see if any parameter is
+ - --autostart and enter autostart mode. -}
+checkAutoStart :: IO ()
+checkAutoStart = ifM (elem "--autostart" <$> getArgs)
+ ( autoStart Nothing
+ , error "Not in a git repository."
+ )
+
+autoStart :: Maybe Duration -> IO ()
+autoStart startdelay = do
+ dirs <- liftIO readAutoStartFile
+ when (null dirs) $ do
+ f <- autoStartFile
+ error $ "Nothing listed in " ++ f
+ program <- readProgramFile
+ haveionice <- pure Build.SysConfig.ionice <&&> inPath "ionice"
+ forM_ dirs $ \d -> do
+ putStrLn $ "git-annex autostart in " ++ d
+ ifM (catchBoolIO $ go haveionice program d)
+ ( putStrLn "ok"
+ , putStrLn "failed"
+ )
+ where
+ go haveionice program dir = do
+ setCurrentDirectory dir
+ if haveionice
+ then boolSystem "ionice" (Param "-c3" : Param program : baseparams)
+ else boolSystem program baseparams
+ where
+ baseparams =
+ [ Param "assistant"
+ , Param $ "--startdelay=" ++ fromDuration (fromMaybe (Duration 5) startdelay)
+ ]
diff --git a/Command/Commit.hs b/Command/Commit.hs
new file mode 100644
index 000000000..6f3f9df28
--- /dev/null
+++ b/Command/Commit.hs
@@ -0,0 +1,29 @@
+{- git-annex command
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Commit where
+
+import Common.Annex
+import Command
+import qualified Annex.Branch
+import qualified Git
+
+def :: [Command]
+def = [command "commit" paramNothing seek
+ SectionPlumbing "commits any staged changes to the git-annex branch"]
+
+seek :: [CommandSeek]
+seek = [withNothing start]
+
+start :: CommandStart
+start = next $ next $ do
+ Annex.Branch.commit "update"
+ _ <- runhook <=< inRepo $ Git.hookPath "annex-content"
+ return True
+ where
+ runhook (Just hook) = liftIO $ boolSystem hook []
+ runhook Nothing = return True
diff --git a/Command/ConfigList.hs b/Command/ConfigList.hs
new file mode 100644
index 000000000..c42480200
--- /dev/null
+++ b/Command/ConfigList.hs
@@ -0,0 +1,30 @@
+{- git-annex command
+ -
+ - Copyright 2010 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.ConfigList where
+
+import Common.Annex
+import Command
+import Annex.UUID
+import qualified Git.Config
+import Remote.GCrypt (coreGCryptId)
+
+def :: [Command]
+def = [noCommit $ command "configlist" paramNothing seek
+ SectionPlumbing "outputs relevant git configuration"]
+
+seek :: [CommandSeek]
+seek = [withNothing start]
+
+start :: CommandStart
+start = do
+ u <- getUUID
+ showConfig "annex.uuid" $ fromUUID u
+ showConfig coreGCryptId =<< fromRepo (Git.Config.get coreGCryptId "")
+ stop
+ where
+ showConfig k v = liftIO $ putStrLn $ k ++ "=" ++ v
diff --git a/Command/Copy.hs b/Command/Copy.hs
new file mode 100644
index 000000000..9fd97334a
--- /dev/null
+++ b/Command/Copy.hs
@@ -0,0 +1,39 @@
+{- git-annex command
+ -
+ - Copyright 2010 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Copy where
+
+import Common.Annex
+import Command
+import GitAnnex.Options
+import qualified Command.Move
+import qualified Remote
+import Annex.Wanted
+
+def :: [Command]
+def = [withOptions Command.Move.moveOptions $ command "copy" paramPaths seek
+ SectionCommon "copy content of files to/from another repository"]
+
+seek :: [CommandSeek]
+seek =
+ [ withField toOption Remote.byNameWithUUID $ \to ->
+ withField fromOption Remote.byNameWithUUID $ \from ->
+ withKeyOptions (Command.Move.startKey to from False) $
+ withFilesInGit $ whenAnnexed $ start to from
+ ]
+
+{- A copy is just a move that does not delete the source file.
+ - However, --auto mode avoids unnecessary copies, and avoids getting or
+ - sending non-preferred content. -}
+start :: Maybe Remote -> Maybe Remote -> FilePath -> (Key, Backend) -> CommandStart
+start to from file (key, backend) = stopUnless shouldCopy $
+ Command.Move.start to from False file (key, backend)
+ where
+ shouldCopy = checkAuto (check <||> numCopiesCheck file key (<))
+ check = case to of
+ Nothing -> wantGet False (Just file)
+ Just r -> wantSend False (Just file) (Remote.uuid r)
diff --git a/Command/Dead.hs b/Command/Dead.hs
new file mode 100644
index 000000000..180f2fda9
--- /dev/null
+++ b/Command/Dead.hs
@@ -0,0 +1,40 @@
+{- git-annex command
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Dead where
+
+import Common.Annex
+import Command
+import qualified Remote
+import Logs.Trust
+import Logs.Group
+
+import qualified Data.Set as S
+
+def :: [Command]
+def = [command "dead" (paramRepeating paramRemote) seek
+ SectionSetup "hide a lost repository"]
+
+seek :: [CommandSeek]
+seek = [withWords start]
+
+start :: [String] -> CommandStart
+start ws = do
+ let name = unwords ws
+ showStart "dead" name
+ u <- Remote.nameToUUID name
+ next $ perform u
+
+perform :: UUID -> CommandPerform
+perform uuid = do
+ markDead uuid
+ next $ return True
+
+markDead :: UUID -> Annex ()
+markDead uuid = do
+ trustSet uuid DeadTrusted
+ groupSet uuid S.empty
diff --git a/Command/Describe.hs b/Command/Describe.hs
new file mode 100644
index 000000000..18851b172
--- /dev/null
+++ b/Command/Describe.hs
@@ -0,0 +1,32 @@
+{- git-annex command
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Describe where
+
+import Common.Annex
+import Command
+import qualified Remote
+import Logs.UUID
+
+def :: [Command]
+def = [command "describe" (paramPair paramRemote paramDesc) seek
+ SectionSetup "change description of a repository"]
+
+seek :: [CommandSeek]
+seek = [withWords start]
+
+start :: [String] -> CommandStart
+start (name:description) = do
+ showStart "describe" name
+ u <- Remote.nameToUUID name
+ next $ perform u $ unwords description
+start _ = error "Specify a repository and a description."
+
+perform :: UUID -> String -> CommandPerform
+perform u description = do
+ describeUUID u description
+ next $ return True
diff --git a/Command/Direct.hs b/Command/Direct.hs
new file mode 100644
index 000000000..1f262bd9f
--- /dev/null
+++ b/Command/Direct.hs
@@ -0,0 +1,73 @@
+{- git-annex command
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Direct where
+
+import Control.Exception.Extensible
+
+import Common.Annex
+import Command
+import qualified Git
+import qualified Git.Command
+import qualified Git.LsFiles
+import Config
+import Annex.Direct
+import Annex.Version
+import Annex.Exception
+
+def :: [Command]
+def = [notBareRepo $ noDaemonRunning $
+ command "direct" paramNothing seek
+ SectionSetup "switch repository to direct mode"]
+
+seek :: [CommandSeek]
+seek = [withNothing start]
+
+start :: CommandStart
+start = ifM isDirect ( stop , next perform )
+
+perform :: CommandPerform
+perform = do
+ showStart "commit" ""
+ showOutput
+ _ <- inRepo $ Git.Command.runBool
+ [ Param "commit"
+ , Param "-a"
+ , Param "-m"
+ , Param "commit before switching to direct mode"
+ ]
+ showEndOk
+
+ top <- fromRepo Git.repoPath
+ (l, clean) <- inRepo $ Git.LsFiles.inRepo [top]
+ forM_ l go
+ void $ liftIO clean
+ next cleanup
+ where
+ go = whenAnnexed $ \f (k, _) -> do
+ r <- toDirectGen k f
+ case r of
+ Nothing -> noop
+ Just a -> do
+ showStart "direct" f
+ r' <- tryAnnex a
+ case r' of
+ Left e -> warnlocked e
+ Right _ -> showEndOk
+ return Nothing
+
+ warnlocked :: SomeException -> Annex ()
+ warnlocked e = do
+ warning $ show e
+ warning "leaving this file as-is; correct this problem and run git annex fsck on it"
+
+cleanup :: CommandCleanup
+cleanup = do
+ showStart "direct" ""
+ setDirect True
+ setVersion directModeVersion
+ return True
diff --git a/Command/Drop.hs b/Command/Drop.hs
new file mode 100644
index 000000000..5d642ed3a
--- /dev/null
+++ b/Command/Drop.hs
@@ -0,0 +1,161 @@
+{- git-annex command
+ -
+ - Copyright 2010 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Drop where
+
+import Common.Annex
+import Command
+import qualified Remote
+import qualified Annex
+import Annex.UUID
+import Logs.Location
+import Logs.Trust
+import Annex.Content
+import Config
+import qualified Option
+import Annex.Wanted
+
+def :: [Command]
+def = [withOptions [fromOption] $ command "drop" paramPaths seek
+ SectionCommon "indicate content of files not currently wanted"]
+
+fromOption :: Option
+fromOption = Option.field ['f'] "from" paramRemote "drop content from a remote"
+
+seek :: [CommandSeek]
+seek = [withField fromOption Remote.byNameWithUUID $ \from ->
+ withFilesInGit $ whenAnnexed $ start from]
+
+start :: Maybe Remote -> FilePath -> (Key, Backend) -> CommandStart
+start from file (key, _) = checkDropAuto from file key $ \numcopies ->
+ stopUnless (checkAuto $ wantDrop False (Remote.uuid <$> from) (Just file)) $
+ case from of
+ Nothing -> startLocal file numcopies key Nothing
+ Just remote -> do
+ u <- getUUID
+ if Remote.uuid remote == u
+ then startLocal file numcopies key Nothing
+ else startRemote file numcopies key remote
+
+startLocal :: FilePath -> Maybe Int -> Key -> Maybe Remote -> CommandStart
+startLocal file numcopies key knownpresentremote = stopUnless (inAnnex key) $ do
+ showStart "drop" file
+ next $ performLocal key numcopies knownpresentremote
+
+startRemote :: FilePath -> Maybe Int -> Key -> Remote -> CommandStart
+startRemote file numcopies key remote = do
+ showStart ("drop " ++ Remote.name remote) file
+ next $ performRemote key numcopies remote
+
+performLocal :: Key -> Maybe Int -> Maybe Remote -> CommandPerform
+performLocal key numcopies knownpresentremote = lockContent key $ do
+ (remotes, trusteduuids) <- Remote.keyPossibilitiesTrusted key
+ let trusteduuids' = case knownpresentremote of
+ Nothing -> trusteduuids
+ Just r -> nub (Remote.uuid r:trusteduuids)
+ untrusteduuids <- trustGet UnTrusted
+ let tocheck = Remote.remotesWithoutUUID remotes (trusteduuids'++untrusteduuids)
+ stopUnless (canDropKey key numcopies trusteduuids' tocheck []) $ do
+ removeAnnex key
+ next $ cleanupLocal key
+
+performRemote :: Key -> Maybe Int -> Remote -> CommandPerform
+performRemote key numcopies remote = lockContent key $ do
+ -- Filter the remote it's being dropped from out of the lists of
+ -- places assumed to have the key, and places to check.
+ -- When the local repo has the key, that's one additional copy.
+ (remotes, trusteduuids) <- Remote.keyPossibilitiesTrusted key
+ present <- inAnnex key
+ u <- getUUID
+ let have = filter (/= uuid) $
+ if present then u:trusteduuids else trusteduuids
+ untrusteduuids <- trustGet UnTrusted
+ let tocheck = filter (/= remote) $
+ Remote.remotesWithoutUUID remotes (have++untrusteduuids)
+ stopUnless (canDropKey key numcopies have tocheck [uuid]) $ do
+ ok <- Remote.removeKey remote key
+ next $ cleanupRemote key remote ok
+ where
+ uuid = Remote.uuid remote
+
+cleanupLocal :: Key -> CommandCleanup
+cleanupLocal key = do
+ logStatus key InfoMissing
+ return True
+
+cleanupRemote :: Key -> Remote -> Bool -> CommandCleanup
+cleanupRemote key remote ok = do
+ when ok $
+ Remote.logStatus remote key InfoMissing
+ return ok
+
+{- Checks specified remotes to verify that enough copies of a key exist to
+ - allow it to be safely removed (with no data loss). Can be provided with
+ - some locations where the key is known/assumed to be present. -}
+canDropKey :: Key -> Maybe Int -> [UUID] -> [Remote] -> [UUID] -> Annex Bool
+canDropKey key numcopiesM have check skip = do
+ force <- Annex.getState Annex.force
+ if force || numcopiesM == Just 0
+ then return True
+ else do
+ need <- getNumCopies numcopiesM
+ findCopies key need skip have check
+
+findCopies :: Key -> Int -> [UUID] -> [UUID] -> [Remote] -> Annex Bool
+findCopies key need skip = helper [] []
+ where
+ helper bad missing have []
+ | length have >= need = return True
+ | otherwise = notEnoughCopies key need have (skip++missing) bad
+ helper bad missing have (r:rs)
+ | length have >= need = return True
+ | otherwise = do
+ let u = Remote.uuid r
+ let duplicate = u `elem` have
+ haskey <- Remote.hasKey r key
+ case (duplicate, haskey) of
+ (False, Right True) -> helper bad missing (u:have) rs
+ (False, Left _) -> helper (r:bad) missing have rs
+ (False, Right False) -> helper bad (u:missing) have rs
+ _ -> helper bad missing have rs
+
+notEnoughCopies :: Key -> Int -> [UUID] -> [UUID] -> [Remote] -> Annex Bool
+notEnoughCopies key need have skip bad = do
+ unsafe
+ showLongNote $
+ "Could only verify the existence of " ++
+ show (length have) ++ " out of " ++ show need ++
+ " necessary copies"
+ Remote.showTriedRemotes bad
+ Remote.showLocations key (have++skip)
+ "Rather than dropping this file, try using: git annex move"
+ hint
+ return False
+ where
+ unsafe = showNote "unsafe"
+ hint = showLongNote "(Use --force to override this check, or adjust annex.numcopies.)"
+
+{- In auto mode, only runs the action if there are enough
+ - copies on other semitrusted repositories.
+ -
+ - Passes any numcopies attribute of the file on to the action as an
+ - optimisation. -}
+checkDropAuto :: Maybe Remote -> FilePath -> Key -> (Maybe Int -> CommandStart) -> CommandStart
+checkDropAuto mremote file key a = do
+ numcopiesattr <- numCopies file
+ Annex.getState Annex.auto >>= auto numcopiesattr
+ where
+ auto numcopiesattr False = a numcopiesattr
+ auto numcopiesattr True = do
+ needed <- getNumCopies numcopiesattr
+ locs <- Remote.keyLocations key
+ uuid <- getUUID
+ let remoteuuid = fromMaybe uuid $ Remote.uuid <$> mremote
+ locs' <- trustExclude UnTrusted $ filter (/= remoteuuid) locs
+ if length locs' >= needed
+ then a numcopiesattr
+ else stop
diff --git a/Command/DropKey.hs b/Command/DropKey.hs
new file mode 100644
index 000000000..624919584
--- /dev/null
+++ b/Command/DropKey.hs
@@ -0,0 +1,39 @@
+{- git-annex command
+ -
+ - Copyright 2010 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.DropKey where
+
+import Common.Annex
+import Command
+import qualified Annex
+import Logs.Location
+import Annex.Content
+import Types.Key
+
+def :: [Command]
+def = [noCommit $ command "dropkey" (paramRepeating paramKey) seek
+ SectionPlumbing "drops annexed content for specified keys"]
+
+seek :: [CommandSeek]
+seek = [withKeys start]
+
+start :: Key -> CommandStart
+start key = stopUnless (inAnnex key) $ do
+ unlessM (Annex.getState Annex.force) $
+ error "dropkey can cause data loss; use --force if you're sure you want to do this"
+ showStart "dropkey" (key2file key)
+ next $ perform key
+
+perform :: Key -> CommandPerform
+perform key = lockContent key $ do
+ removeAnnex key
+ next $ cleanup key
+
+cleanup :: Key -> CommandCleanup
+cleanup key = do
+ logStatus key InfoMissing
+ return True
diff --git a/Command/DropUnused.hs b/Command/DropUnused.hs
new file mode 100644
index 000000000..bf2635e00
--- /dev/null
+++ b/Command/DropUnused.hs
@@ -0,0 +1,43 @@
+{- git-annex command
+ -
+ - Copyright 2010,2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.DropUnused where
+
+import Common.Annex
+import Command
+import qualified Annex
+import qualified Command.Drop
+import qualified Remote
+import qualified Git
+import qualified Option
+import Command.Unused (withUnusedMaps, UnusedMaps(..), startUnused)
+
+def :: [Command]
+def = [withOptions [Command.Drop.fromOption] $
+ command "dropunused" (paramRepeating paramNumRange)
+ seek SectionMaintenance "drop unused file content"]
+
+seek :: [CommandSeek]
+seek = [withUnusedMaps start]
+
+start :: UnusedMaps -> Int -> CommandStart
+start = startUnused "dropunused" perform (performOther gitAnnexBadLocation) (performOther gitAnnexTmpLocation)
+
+perform :: Key -> CommandPerform
+perform key = maybe droplocal dropremote =<< Remote.byNameWithUUID =<< from
+ where
+ dropremote r = do
+ showAction $ "from " ++ Remote.name r
+ Command.Drop.performRemote key Nothing r
+ droplocal = Command.Drop.performLocal key Nothing Nothing
+ from = Annex.getField $ Option.name Command.Drop.fromOption
+
+performOther :: (Key -> Git.Repo -> FilePath) -> Key -> CommandPerform
+performOther filespec key = do
+ f <- fromRepo $ filespec key
+ liftIO $ nukeFile f
+ next $ return True
diff --git a/Command/EnableRemote.hs b/Command/EnableRemote.hs
new file mode 100644
index 000000000..f6a1b819c
--- /dev/null
+++ b/Command/EnableRemote.hs
@@ -0,0 +1,56 @@
+{- git-annex command
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.EnableRemote where
+
+import Common.Annex
+import Command
+import qualified Logs.Remote
+import qualified Types.Remote as R
+import qualified Command.InitRemote as InitRemote
+
+import qualified Data.Map as M
+
+def :: [Command]
+def = [command "enableremote"
+ (paramPair paramName $ paramOptional $ paramRepeating paramKeyValue)
+ seek SectionSetup "enables use of an existing special remote"]
+
+seek :: [CommandSeek]
+seek = [withWords start]
+
+start :: [String] -> CommandStart
+start [] = unknownNameError "Specify the name of the special remote to enable."
+start (name:ws) = go =<< InitRemote.findExisting name
+ where
+ config = Logs.Remote.keyValToConfig ws
+
+ go Nothing = unknownNameError "Unknown special remote name."
+ go (Just (u, c)) = do
+ let fullconfig = config `M.union` c
+ t <- InitRemote.findType fullconfig
+
+ showStart "enableremote" name
+ next $ perform t u fullconfig
+
+unknownNameError :: String -> Annex a
+unknownNameError prefix = do
+ names <- InitRemote.remoteNames
+ error $ prefix ++
+ if null names
+ then ""
+ else " Known special remotes: " ++ unwords names
+
+perform :: RemoteType -> UUID -> R.RemoteConfig -> CommandPerform
+perform t u c = do
+ (c', u') <- R.setup t (Just u) c
+ next $ cleanup u' c'
+
+cleanup :: UUID -> R.RemoteConfig -> CommandCleanup
+cleanup u c = do
+ Logs.Remote.configSet u c
+ return True
diff --git a/Command/Find.hs b/Command/Find.hs
new file mode 100644
index 000000000..4b8c7ce0e
--- /dev/null
+++ b/Command/Find.hs
@@ -0,0 +1,61 @@
+{- git-annex command
+ -
+ - Copyright 2010-2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Find where
+
+import qualified Data.Map as M
+
+import Common.Annex
+import Command
+import Annex.Content
+import Limit
+import qualified Annex
+import qualified Utility.Format
+import Utility.DataUnits
+import Types.Key
+import qualified Option
+
+def :: [Command]
+def = [noCommit $ noMessages $ withOptions [formatOption, print0Option] $
+ command "find" paramPaths seek SectionQuery "lists available files"]
+
+formatOption :: Option
+formatOption = Option.field [] "format" paramFormat "control format of output"
+
+print0Option :: Option
+print0Option = Option.Option [] ["print0"] (Option.NoArg set)
+ "terminate output with null"
+ where
+ set = Annex.setField (Option.name formatOption) "${file}\0"
+
+seek :: [CommandSeek]
+seek = [withField formatOption formatconverter $ \f ->
+ withFilesInGit $ whenAnnexed $ start f]
+ where
+ formatconverter = return . fmap Utility.Format.gen
+
+start :: Maybe Utility.Format.Format -> FilePath -> (Key, Backend) -> CommandStart
+start format file (key, _) = do
+ -- only files inAnnex are shown, unless the user has requested
+ -- others via a limit
+ whenM (limited <||> inAnnex key) $
+ unlessM (showFullJSON vars) $
+ case format of
+ Nothing -> liftIO $ putStrLn file
+ Just formatter -> liftIO $ putStr $
+ Utility.Format.format formatter $
+ M.fromList vars
+ stop
+ where
+ vars =
+ [ ("file", file)
+ , ("key", key2file key)
+ , ("backend", keyBackendName key)
+ , ("bytesize", size show)
+ , ("humansize", size $ roughSize storageUnits True)
+ ]
+ size c = maybe "unknown" c $ keySize key
diff --git a/Command/Fix.hs b/Command/Fix.hs
new file mode 100644
index 000000000..a63a10f8f
--- /dev/null
+++ b/Command/Fix.hs
@@ -0,0 +1,61 @@
+{- git-annex command
+ -
+ - Copyright 2010 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Command.Fix where
+
+import System.PosixCompat.Files
+
+import Common.Annex
+import Command
+import qualified Annex.Queue
+#ifdef WITH_CLIBS
+#ifndef __ANDROID__
+import Utility.Touch
+#endif
+#endif
+
+def :: [Command]
+def = [notDirect $ noCommit $ command "fix" paramPaths seek
+ SectionMaintenance "fix up symlinks to point to annexed content"]
+
+seek :: [CommandSeek]
+seek = [withFilesInGit $ whenAnnexed start]
+
+{- Fixes the symlink to an annexed file. -}
+start :: FilePath -> (Key, Backend) -> CommandStart
+start file (key, _) = do
+ link <- inRepo $ gitAnnexLink file key
+ stopUnless ((/=) (Just link) <$> liftIO (catchMaybeIO $ readSymbolicLink file)) $ do
+ showStart "fix" file
+ next $ perform file link
+
+perform :: FilePath -> FilePath -> CommandPerform
+perform file link = do
+ liftIO $ do
+#ifdef WITH_CLIBS
+#ifndef __ANDROID__
+ -- preserve mtime of symlink
+ mtime <- catchMaybeIO $ TimeSpec . modificationTime
+ <$> getSymbolicLinkStatus file
+#endif
+#endif
+ createDirectoryIfMissing True (parentDir file)
+ removeFile file
+ createSymbolicLink link file
+#ifdef WITH_CLIBS
+#ifndef __ANDROID__
+ maybe noop (\t -> touch file t False) mtime
+#endif
+#endif
+ next $ cleanup file
+
+cleanup :: FilePath -> CommandCleanup
+cleanup file = do
+ Annex.Queue.addCommand "add" [Param "--force", Param "--"] [file]
+ return True
diff --git a/Command/Forget.hs b/Command/Forget.hs
new file mode 100644
index 000000000..74bd68ad1
--- /dev/null
+++ b/Command/Forget.hs
@@ -0,0 +1,52 @@
+{- git-annex command
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Forget where
+
+import Common.Annex
+import Command
+import qualified Annex.Branch as Branch
+import Logs.Transitions
+import qualified Annex
+import qualified Option
+
+import Data.Time.Clock.POSIX
+
+def :: [Command]
+def = [withOptions forgetOptions $ command "forget" paramNothing seek
+ SectionMaintenance "prune git-annex branch history"]
+
+forgetOptions :: [Option]
+forgetOptions = [dropDeadOption]
+
+dropDeadOption :: Option
+dropDeadOption = Option.flag [] "drop-dead" "drop references to dead repositories"
+
+seek :: [CommandSeek]
+seek = [withFlag dropDeadOption $ \dropdead ->
+ withNothing $ start dropdead]
+
+start :: Bool -> CommandStart
+start dropdead = do
+ showStart "forget" "git-annex"
+ now <- liftIO getPOSIXTime
+ let basets = addTransition now ForgetGitHistory noTransitions
+ let ts = if dropdead
+ then addTransition now ForgetDeadRemotes basets
+ else basets
+ next $ perform ts =<< Annex.getState Annex.force
+
+perform :: Transitions -> Bool -> CommandPerform
+perform ts True = do
+ recordTransitions Branch.change ts
+ -- get branch committed before contining with the transition
+ Branch.update
+ void $ Branch.performTransitions ts True []
+ next $ return True
+perform _ False = do
+ showLongNote "To forget git-annex branch history, you must specify --force. This deletes metadata!"
+ stop
diff --git a/Command/FromKey.hs b/Command/FromKey.hs
new file mode 100644
index 000000000..c3d2daafe
--- /dev/null
+++ b/Command/FromKey.hs
@@ -0,0 +1,46 @@
+{- git-annex command
+ -
+ - Copyright 2010 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.FromKey where
+
+import System.PosixCompat.Files
+
+import Common.Annex
+import Command
+import qualified Annex.Queue
+import Annex.Content
+import Types.Key
+
+def :: [Command]
+def = [notDirect $ notBareRepo $
+ command "fromkey" (paramPair paramKey paramPath) seek
+ SectionPlumbing "adds a file using a specific key"]
+
+seek :: [CommandSeek]
+seek = [withWords start]
+
+start :: [String] -> CommandStart
+start (keyname:file:[]) = do
+ let key = fromMaybe (error "bad key") $ file2key keyname
+ inbackend <- inAnnex key
+ unless inbackend $ error $
+ "key ("++ keyname ++") is not present in backend"
+ showStart "fromkey" file
+ next $ perform key file
+start _ = error "specify a key and a dest file"
+
+perform :: Key -> FilePath -> CommandPerform
+perform key file = do
+ link <- inRepo $ gitAnnexLink file key
+ liftIO $ createDirectoryIfMissing True (parentDir file)
+ liftIO $ createSymbolicLink link file
+ next $ cleanup file
+
+cleanup :: FilePath -> CommandCleanup
+cleanup file = do
+ Annex.Queue.addCommand "add" [Param "--"] [file]
+ return True
diff --git a/Command/Fsck.hs b/Command/Fsck.hs
new file mode 100644
index 000000000..a8e52af98
--- /dev/null
+++ b/Command/Fsck.hs
@@ -0,0 +1,508 @@
+{- git-annex command
+ -
+ - Copyright 2010-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Command.Fsck where
+
+import System.PosixCompat.Files
+
+import Common.Annex
+import Command
+import qualified Annex
+import qualified Remote
+import qualified Types.Backend
+import qualified Types.Key
+import qualified Backend
+import Annex.Content
+import Annex.Content.Direct
+import Annex.Direct
+import Annex.Perms
+import Annex.Link
+import Logs.Location
+import Logs.Trust
+import Annex.UUID
+import Utility.DataUnits
+import Utility.FileMode
+import Config
+import qualified Option
+import Types.Key
+import Utility.HumanTime
+import Git.FilePath
+import GitAnnex.Options hiding (fromOption)
+
+#ifndef mingw32_HOST_OS
+import System.Posix.Process (getProcessID)
+#else
+import System.Random (getStdRandom, random)
+#endif
+import Data.Time.Clock.POSIX
+import Data.Time
+import System.Posix.Types (EpochTime)
+import System.Locale
+
+def :: [Command]
+def = [withOptions fsckOptions $ command "fsck" paramPaths seek
+ SectionMaintenance "check for problems"]
+
+fromOption :: Option
+fromOption = Option.field ['f'] "from" paramRemote "check remote"
+
+startIncrementalOption :: Option
+startIncrementalOption = Option.flag ['S'] "incremental" "start an incremental fsck"
+
+moreIncrementalOption :: Option
+moreIncrementalOption = Option.flag ['m'] "more" "continue an incremental fsck"
+
+incrementalScheduleOption :: Option
+incrementalScheduleOption = Option.field [] "incremental-schedule" paramTime
+ "schedule incremental fscking"
+
+fsckOptions :: [Option]
+fsckOptions =
+ [ fromOption
+ , startIncrementalOption
+ , moreIncrementalOption
+ , incrementalScheduleOption
+ ] ++ keyOptions
+
+seek :: [CommandSeek]
+seek =
+ [ withField fromOption Remote.byNameWithUUID $ \from ->
+ withIncremental $ \i ->
+ withKeyOptions (startKey i) $
+ withFilesInGit $ whenAnnexed $ start from i
+ ]
+
+withIncremental :: (Incremental -> CommandSeek) -> CommandSeek
+withIncremental = withValue $ do
+ i <- maybe (return False) (checkschedule . parseDuration)
+ =<< Annex.getField (Option.name incrementalScheduleOption)
+ starti <- Annex.getFlag (Option.name startIncrementalOption)
+ morei <- Annex.getFlag (Option.name moreIncrementalOption)
+ case (i, starti, morei) of
+ (False, False, False) -> return NonIncremental
+ (False, True, _) -> startIncremental
+ (False ,False, True) -> ContIncremental <$> getStartTime
+ (True, _, _) ->
+ maybe startIncremental (return . ContIncremental . Just)
+ =<< getStartTime
+ where
+ startIncremental = do
+ recordStartTime
+ return StartIncremental
+
+ checkschedule Nothing = error "bad --incremental-schedule value"
+ checkschedule (Just delta) = do
+ Annex.addCleanup "" $ do
+ v <- getStartTime
+ case v of
+ Nothing -> noop
+ Just started -> do
+ now <- liftIO getPOSIXTime
+ when (now - realToFrac started >= durationToPOSIXTime delta)
+ resetStartTime
+ return True
+
+start :: Maybe Remote -> Incremental -> FilePath -> (Key, Backend) -> CommandStart
+start from inc file (key, backend) = do
+ numcopies <- numCopies file
+ case from of
+ Nothing -> go $ perform key file backend numcopies
+ Just r -> go $ performRemote key file backend numcopies r
+ where
+ go = runFsck inc file key
+
+perform :: Key -> FilePath -> Backend -> Maybe Int -> Annex Bool
+perform key file backend numcopies = check
+ -- order matters
+ [ fixLink key file
+ , verifyLocationLog key file
+ , verifyDirectMapping key file
+ , verifyDirectMode key file
+ , checkKeySize key
+ , checkBackend backend key (Just file)
+ , checkKeyNumCopies key file numcopies
+ ]
+
+{- To fsck a remote, the content is retrieved to a tmp file,
+ - and checked locally. -}
+performRemote :: Key -> FilePath -> Backend -> Maybe Int -> Remote -> Annex Bool
+performRemote key file backend numcopies remote =
+ dispatch =<< Remote.hasKey remote key
+ where
+ dispatch (Left err) = do
+ showNote err
+ return False
+ dispatch (Right True) = withtmp $ \tmpfile ->
+ ifM (getfile tmpfile)
+ ( go True (Just tmpfile)
+ , go True Nothing
+ )
+ dispatch (Right False) = go False Nothing
+ go present localcopy = check
+ [ verifyLocationLogRemote key file remote present
+ , checkKeySizeRemote key remote localcopy
+ , checkBackendRemote backend key remote localcopy
+ , checkKeyNumCopies key file numcopies
+ ]
+ withtmp a = do
+#ifndef mingw32_HOST_OS
+ v <- liftIO getProcessID
+#else
+ v <- liftIO (getStdRandom random :: IO Int)
+#endif
+ t <- fromRepo gitAnnexTmpDir
+ createAnnexDirectory t
+ let tmp = t </> "fsck" ++ show v ++ "." ++ keyFile key
+ let cleanup = liftIO $ catchIO (removeFile tmp) (const noop)
+ cleanup
+ cleanup `after` a tmp
+ getfile tmp =
+ ifM (Remote.retrieveKeyFileCheap remote key tmp)
+ ( return True
+ , ifM (Annex.getState Annex.fast)
+ ( return False
+ , Remote.retrieveKeyFile remote key Nothing tmp dummymeter
+ )
+ )
+ dummymeter _ = noop
+
+startKey :: Incremental -> Key -> CommandStart
+startKey inc key = case Backend.maybeLookupBackendName (Types.Key.keyBackendName key) of
+ Nothing -> stop
+ Just backend -> runFsck inc (key2file key) key $ performAll key backend
+
+{- Note that numcopies cannot be checked in --all mode, since we do not
+ - have associated filenames to look up in the .gitattributes file. -}
+performAll :: Key -> Backend -> Annex Bool
+performAll key backend = check
+ [ verifyLocationLog key (key2file key)
+ , checkKeySize key
+ , checkBackend backend key Nothing
+ ]
+
+check :: [Annex Bool] -> Annex Bool
+check cs = and <$> sequence cs
+
+{- Checks that the file's link points correctly to the content.
+ -
+ - In direct mode, there is only a link when the content is not present.
+ -}
+fixLink :: Key -> FilePath -> Annex Bool
+fixLink key file = do
+ want <- inRepo $ gitAnnexLink file key
+ have <- getAnnexLinkTarget file
+ maybe noop (go want) have
+ return True
+ where
+ go want have
+ | want /= fromInternalGitPath have = do
+ showNote "fixing link"
+ liftIO $ createDirectoryIfMissing True (parentDir file)
+ liftIO $ removeFile file
+ addAnnexLink want file
+ | otherwise = noop
+
+{- Checks that the location log reflects the current status of the key,
+ - in this repository only. -}
+verifyLocationLog :: Key -> String -> Annex Bool
+verifyLocationLog key desc = do
+ present <- inAnnex key
+ direct <- isDirect
+ u <- getUUID
+
+ {- Since we're checking that a key's file is present, throw
+ - in a permission fixup here too. -}
+ file <- calcRepo $ gitAnnexLocation key
+ when (present && not direct) $
+ freezeContent file
+ whenM (liftIO $ doesDirectoryExist $ parentDir file) $
+ freezeContentDir file
+
+ {- In direct mode, modified files will show up as not present,
+ - but that is expected and not something to do anything about. -}
+ if direct && not present
+ then return True
+ else verifyLocationLog' key desc present u (logChange key u)
+
+verifyLocationLogRemote :: Key -> String -> Remote -> Bool -> Annex Bool
+verifyLocationLogRemote key desc remote present =
+ verifyLocationLog' key desc present (Remote.uuid remote)
+ (Remote.logStatus remote key)
+
+verifyLocationLog' :: Key -> String -> Bool -> UUID -> (LogStatus -> Annex ()) -> Annex Bool
+verifyLocationLog' key desc present u bad = do
+ uuids <- Remote.keyLocations key
+ case (present, u `elem` uuids) of
+ (True, False) -> do
+ fix InfoPresent
+ -- There is no data loss, so do not fail.
+ return True
+ (False, True) -> do
+ fix InfoMissing
+ warning $
+ "** Based on the location log, " ++ desc
+ ++ "\n** was expected to be present, " ++
+ "but its content is missing."
+ return False
+ _ -> return True
+ where
+ fix s = do
+ showNote "fixing location log"
+ bad s
+
+{- Ensures the direct mode mapping file is consistent. Each file
+ - it lists for the key should exist, and the specified file should be
+ - included in it.
+ -}
+verifyDirectMapping :: Key -> FilePath -> Annex Bool
+verifyDirectMapping key file = do
+ whenM isDirect $ do
+ fs <- addAssociatedFile key file
+ forM_ fs $ \f ->
+ unlessM (liftIO $ doesFileExist f) $
+ void $ removeAssociatedFile key f
+ return True
+
+{- Ensures that files whose content is available are in direct mode. -}
+verifyDirectMode :: Key -> FilePath -> Annex Bool
+verifyDirectMode key file = do
+ whenM (isDirect <&&> isJust <$> isAnnexLink file) $ do
+ v <- toDirectGen key file
+ case v of
+ Nothing -> noop
+ Just a -> do
+ showNote "fixing direct mode"
+ a
+ return True
+
+{- The size of the data for a key is checked against the size encoded in
+ - the key's metadata, if available.
+ -
+ - Not checked in direct mode, because files can be changed directly.
+ -}
+checkKeySize :: Key -> Annex Bool
+checkKeySize key = ifM isDirect
+ ( return True
+ , do
+ file <- calcRepo $ gitAnnexLocation key
+ ifM (liftIO $ doesFileExist file)
+ ( checkKeySizeOr badContent key file
+ , return True
+ )
+ )
+
+checkKeySizeRemote :: Key -> Remote -> Maybe FilePath -> Annex Bool
+checkKeySizeRemote _ _ Nothing = return True
+checkKeySizeRemote key remote (Just file) =
+ checkKeySizeOr (badContentRemote remote) key file
+
+checkKeySizeOr :: (Key -> Annex String) -> Key -> FilePath -> Annex Bool
+checkKeySizeOr bad key file = case Types.Key.keySize key of
+ Nothing -> return True
+ Just size -> do
+ size' <- fromIntegral . fileSize
+ <$> liftIO (getFileStatus file)
+ comparesizes size size'
+ where
+ comparesizes a b = do
+ let same = a == b
+ unless same $ badsize a b
+ return same
+ badsize a b = do
+ msg <- bad key
+ warning $ concat
+ [ "Bad file size ("
+ , compareSizes storageUnits True a b
+ , "); "
+ , msg
+ ]
+
+{- Runs the backend specific check on a key's content.
+ -
+ - In direct mode this is not done if the file has clearly been modified,
+ - because modification of direct mode files is allowed. It's still done
+ - if the file does not appear modified, to catch disk corruption, etc.
+ -}
+checkBackend :: Backend -> Key -> Maybe FilePath -> Annex Bool
+checkBackend backend key mfile = go =<< isDirect
+ where
+ go False = do
+ content <- calcRepo $ gitAnnexLocation key
+ checkBackendOr badContent backend key content
+ go True = maybe nocheck checkdirect mfile
+ checkdirect file = ifM (goodContent key file)
+ ( checkBackendOr' (badContentDirect file) backend key file
+ (goodContent key file)
+ , nocheck
+ )
+ nocheck = return True
+
+checkBackendRemote :: Backend -> Key -> Remote -> Maybe FilePath -> Annex Bool
+checkBackendRemote backend key remote = maybe (return True) go
+ where
+ go = checkBackendOr (badContentRemote remote) backend key
+
+checkBackendOr :: (Key -> Annex String) -> Backend -> Key -> FilePath -> Annex Bool
+checkBackendOr bad backend key file =
+ checkBackendOr' bad backend key file (return True)
+
+checkBackendOr' :: (Key -> Annex String) -> Backend -> Key -> FilePath -> Annex Bool -> Annex Bool
+checkBackendOr' bad backend key file postcheck =
+ case Types.Backend.fsckKey backend of
+ Nothing -> return True
+ Just a -> do
+ ok <- a key file
+ ifM postcheck
+ ( do
+ unless ok $ do
+ msg <- bad key
+ warning $ "Bad file content; " ++ msg
+ return ok
+ , return True
+ )
+
+checkKeyNumCopies :: Key -> FilePath -> Maybe Int -> Annex Bool
+checkKeyNumCopies key file numcopies = do
+ needed <- getNumCopies numcopies
+ (untrustedlocations, safelocations) <- trustPartition UnTrusted =<< Remote.keyLocations key
+ let present = length safelocations
+ if present < needed
+ then do
+ ppuuids <- Remote.prettyPrintUUIDs "untrusted" untrustedlocations
+ warning $ missingNote file present needed ppuuids
+ return False
+ else return True
+
+missingNote :: String -> Int -> Int -> String -> String
+missingNote file 0 _ [] =
+ "** No known copies exist of " ++ file
+missingNote file 0 _ untrusted =
+ "Only these untrusted locations may have copies of " ++ file ++
+ "\n" ++ untrusted ++
+ "Back it up to trusted locations with git-annex copy."
+missingNote file present needed [] =
+ "Only " ++ show present ++ " of " ++ show needed ++
+ " trustworthy copies exist of " ++ file ++
+ "\nBack it up with git-annex copy."
+missingNote file present needed untrusted =
+ missingNote file present needed [] ++
+ "\nThe following untrusted locations may also have copies: " ++
+ "\n" ++ untrusted
+
+{- Bad content is moved aside. -}
+badContent :: Key -> Annex String
+badContent key = do
+ dest <- moveBad key
+ return $ "moved to " ++ dest
+
+{- Bad content is left where it is, but we touch the file, so it'll be
+ - committed to a new key. -}
+badContentDirect :: FilePath -> Key -> Annex String
+badContentDirect file key = do
+ void $ liftIO $ catchMaybeIO $ touchFile file
+ logStatus key InfoMissing
+ return "left in place for you to examine"
+
+badContentRemote :: Remote -> Key -> Annex String
+badContentRemote remote key = do
+ ok <- Remote.removeKey remote key
+ when ok $
+ Remote.logStatus remote key InfoMissing
+ return $ (if ok then "dropped from " else "failed to drop from ")
+ ++ Remote.name remote
+
+data Incremental = StartIncremental | ContIncremental (Maybe EpochTime) | NonIncremental
+ deriving (Eq)
+
+runFsck :: Incremental -> FilePath -> Key -> Annex Bool -> CommandStart
+runFsck inc file key a = ifM (needFsck inc key)
+ ( do
+ showStart "fsck" file
+ next $ do
+ ok <- a
+ when ok $
+ recordFsckTime key
+ next $ return ok
+ , stop
+ )
+
+{- Check if a key needs to be fscked, with support for incremental fscks. -}
+needFsck :: Incremental -> Key -> Annex Bool
+needFsck (ContIncremental Nothing) _ = return True
+needFsck (ContIncremental starttime) key = do
+ fscktime <- getFsckTime key
+ return $ fscktime < starttime
+needFsck _ _ = return True
+
+{- To record the time that a key was last fscked, without
+ - modifying its mtime, we set the timestamp of its parent directory.
+ - Each annexed file is the only thing in its directory, so this is fine.
+ -
+ - To record that the file was fscked, the directory's sticky bit is set.
+ - (None of the normal unix behaviors of the sticky bit should matter, so
+ - we can reuse this permission bit.)
+ -
+ - Note that this relies on the parent directory being deleted when a file
+ - is dropped. That way, if it's later added back, the fsck record
+ - won't still be present.
+ -}
+recordFsckTime :: Key -> Annex ()
+recordFsckTime key = do
+ parent <- parentDir <$> calcRepo (gitAnnexLocation key)
+ liftIO $ void $ tryIO $ do
+ touchFile parent
+#ifndef mingw32_HOST_OS
+ setSticky parent
+#endif
+
+getFsckTime :: Key -> Annex (Maybe EpochTime)
+getFsckTime key = do
+ parent <- parentDir <$> calcRepo (gitAnnexLocation key)
+ liftIO $ catchDefaultIO Nothing $ do
+ s <- getFileStatus parent
+ return $ if isSticky $ fileMode s
+ then Just $ modificationTime s
+ else Nothing
+
+{- Records the start time of an incremental fsck.
+ -
+ - To guard against time stamp damange (for example, if an annex directory
+ - is copied without -a), the fsckstate file contains a time that should
+ - be identical to its modification time. -}
+recordStartTime :: Annex ()
+recordStartTime = do
+ f <- fromRepo gitAnnexFsckState
+ createAnnexDirectory $ parentDir f
+ liftIO $ do
+ nukeFile f
+ h <- openFile f WriteMode
+ t <- modificationTime <$> getFileStatus f
+ hPutStr h $ showTime $ realToFrac t
+ hClose h
+ where
+ showTime :: POSIXTime -> String
+ showTime = show
+
+resetStartTime :: Annex ()
+resetStartTime = liftIO . nukeFile =<< fromRepo gitAnnexFsckState
+
+{- Gets the incremental fsck start time. -}
+getStartTime :: Annex (Maybe EpochTime)
+getStartTime = do
+ f <- fromRepo gitAnnexFsckState
+ liftIO $ catchDefaultIO Nothing $ do
+ timestamp <- modificationTime <$> getFileStatus f
+ t <- readishTime <$> readFile f
+ return $ if Just (realToFrac timestamp) == t
+ then Just timestamp
+ else Nothing
+ where
+ readishTime :: String -> Maybe POSIXTime
+ readishTime s = utcTimeToPOSIXSeconds <$>
+ parseTime defaultTimeLocale "%s%Qs" s
diff --git a/Command/FuzzTest.hs b/Command/FuzzTest.hs
new file mode 100644
index 000000000..34e74b433
--- /dev/null
+++ b/Command/FuzzTest.hs
@@ -0,0 +1,288 @@
+{- git-annex fuzz generator
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.FuzzTest where
+
+import Common.Annex
+import qualified Annex
+import Command
+import qualified Git.Config
+import Config
+import Utility.ThreadScheduler
+import Annex.Exception
+import Utility.DiskFree
+
+import Data.Time.Clock
+import System.Random (getStdRandom, random, randomR)
+import Test.QuickCheck
+import Control.Concurrent
+
+def :: [Command]
+def = [ notBareRepo $ command "fuzztest" paramNothing seek SectionPlumbing
+ "generates fuzz test files"]
+
+seek :: [CommandSeek]
+seek = [withNothing start]
+
+start :: CommandStart
+start = do
+ guardTest
+ logf <- fromRepo gitAnnexFuzzTestLogFile
+ showStart "fuzztest" logf
+ logh <-liftIO $ openFile logf WriteMode
+ void $ forever $ fuzz logh
+ stop
+
+guardTest :: Annex ()
+guardTest = unlessM (fromMaybe False . Git.Config.isTrue <$> getConfig key "") $
+ error $ unlines
+ [ "Running fuzz tests *writes* to and *deletes* files in"
+ , "this repository, and pushes those changes to other"
+ , "repositories! This is a developer tool, not something"
+ , "to play with."
+ , ""
+ , "Refusing to run fuzz tests, since " ++ keyname ++ " is not set!"
+ ]
+ where
+ key = annexConfig "eat-my-repository"
+ (ConfigKey keyname) = key
+
+
+fuzz :: Handle -> Annex ()
+fuzz logh = do
+ action <- genFuzzAction
+ record logh $ flip Started action
+ result <- tryAnnex $ runFuzzAction action
+ record logh $ flip Finished $
+ either (const False) (const True) result
+
+record :: Handle -> (UTCTime -> TimeStampedFuzzAction) -> Annex ()
+record h tmpl = liftIO $ do
+ now <- getCurrentTime
+ let s = show $ tmpl now
+ print s
+ hPrint h s
+ hFlush h
+
+{- Delay for either a fraction of a second, or a few seconds, or up
+ - to 1 minute.
+ -
+ - The MinutesDelay is used as an opportunity to do housekeeping tasks.
+ -}
+randomDelay :: Delay -> Annex ()
+randomDelay TinyDelay = liftIO $
+ threadDelay =<< getStdRandom (randomR (10000, 1000000))
+randomDelay SecondsDelay = liftIO $
+ threadDelaySeconds =<< Seconds <$> getStdRandom (randomR (1, 10))
+randomDelay MinutesDelay = do
+ liftIO $ threadDelaySeconds =<< Seconds <$> getStdRandom (randomR (1, 60))
+ reserve <- annexDiskReserve <$> Annex.getGitConfig
+ free <- liftIO $ getDiskFree "."
+ case free of
+ Just have | have < reserve -> do
+ warning "Low disk space; fuzz test paused."
+ liftIO $ threadDelaySeconds (Seconds 60)
+ randomDelay MinutesDelay
+ _ -> noop
+
+data Delay
+ = TinyDelay
+ | SecondsDelay
+ | MinutesDelay
+ deriving (Read, Show, Eq)
+
+instance Arbitrary Delay where
+ arbitrary = elements [TinyDelay, SecondsDelay, MinutesDelay]
+
+data FuzzFile = FuzzFile FilePath
+ deriving (Read, Show, Eq)
+
+data FuzzDir = FuzzDir FilePath
+ deriving (Read, Show, Eq)
+
+instance Arbitrary FuzzFile where
+ arbitrary = FuzzFile <$> arbitrary
+
+instance Arbitrary FuzzDir where
+ arbitrary = FuzzDir <$> arbitrary
+
+class ToFilePath a where
+ toFilePath :: a -> FilePath
+
+instance ToFilePath FuzzFile where
+ toFilePath (FuzzFile f) = f
+
+instance ToFilePath FuzzDir where
+ toFilePath (FuzzDir d) = d
+
+isFuzzFile :: FilePath -> Bool
+isFuzzFile f = "fuzzfile_" `isPrefixOf` takeFileName f
+
+isFuzzDir :: FilePath -> Bool
+isFuzzDir d = "fuzzdir_" `isPrefixOf` d
+
+mkFuzzFile :: FilePath -> [FuzzDir] -> FuzzFile
+mkFuzzFile file dirs = FuzzFile $ joinPath (map toFilePath dirs) </> ("fuzzfile_" ++ file)
+
+mkFuzzDir :: Int -> FuzzDir
+mkFuzzDir n = FuzzDir $ "fuzzdir_" ++ show n
+
+{- File is placed inside a directory hierarchy up to 4 subdirectories deep. -}
+genFuzzFile :: IO FuzzFile
+genFuzzFile = do
+ n <- getStdRandom $ randomR (0, 4)
+ dirs <- replicateM n genFuzzDir
+ file <- show <$> (getStdRandom random :: IO Int)
+ return $ mkFuzzFile file dirs
+
+{- Only 16 distinct subdirectories are used. When nested 4 deep, this
+ - yields 69904 total directories max, which is below the default Linux
+ - inotify limit of 81920. The goal is not to run the assistant out of
+ - inotify descriptors. -}
+genFuzzDir :: IO FuzzDir
+genFuzzDir = mkFuzzDir <$> (getStdRandom (randomR (1,16)) :: IO Int)
+
+localFile :: FilePath -> Bool
+localFile f
+ | isAbsolute f = False
+ | ".." `isInfixOf` f = False
+ | ".git" `isPrefixOf` f = False
+ | otherwise = True
+
+data TimeStampedFuzzAction
+ = Started UTCTime FuzzAction
+ | Finished UTCTime Bool
+ deriving (Read, Show)
+
+data FuzzAction
+ = FuzzAdd FuzzFile
+ | FuzzDelete FuzzFile
+ | FuzzMove FuzzFile FuzzFile
+ | FuzzModify FuzzFile
+ | FuzzDeleteDir FuzzDir
+ | FuzzMoveDir FuzzDir FuzzDir
+ | FuzzPause Delay
+ deriving (Read, Show, Eq)
+
+instance Arbitrary FuzzAction where
+ arbitrary = frequency
+ [ (50, FuzzAdd <$> arbitrary)
+ , (50, FuzzDelete <$> arbitrary)
+ , (10, FuzzMove <$> arbitrary <*> arbitrary)
+ , (10, FuzzModify <$> arbitrary)
+ , (10, FuzzDeleteDir <$> arbitrary)
+ , (10, FuzzMoveDir <$> arbitrary <*> arbitrary)
+ , (10, FuzzPause <$> arbitrary)
+ ]
+
+runFuzzAction :: FuzzAction -> Annex ()
+runFuzzAction (FuzzAdd (FuzzFile f)) = liftIO $ do
+ createDirectoryIfMissing True $ parentDir f
+ n <- getStdRandom random :: IO Int
+ writeFile f $ show n ++ "\n"
+runFuzzAction (FuzzDelete (FuzzFile f)) = liftIO $ nukeFile f
+runFuzzAction (FuzzMove (FuzzFile src) (FuzzFile dest)) = liftIO $
+ rename src dest
+runFuzzAction (FuzzModify (FuzzFile f)) = whenM isDirect $ liftIO $ do
+ n <- getStdRandom random :: IO Int
+ appendFile f $ show n ++ "\n"
+runFuzzAction (FuzzDeleteDir (FuzzDir d)) = liftIO $
+ removeDirectoryRecursive d
+runFuzzAction (FuzzMoveDir (FuzzDir src) (FuzzDir dest)) = liftIO $
+ rename src dest
+runFuzzAction (FuzzPause d) = randomDelay d
+
+genFuzzAction :: Annex FuzzAction
+genFuzzAction = do
+ tmpl <- liftIO $ Prelude.head <$> sample' (arbitrary :: Gen FuzzAction)
+ -- Fix up template action to make sense in the current repo tree.
+ case tmpl of
+ FuzzAdd _ -> do
+ f <- liftIO newFile
+ maybe genFuzzAction (return . FuzzAdd) f
+ FuzzDelete _ -> do
+ f <- liftIO $ existingFile 0 ""
+ maybe genFuzzAction (return . FuzzDelete) f
+ FuzzMove _ _ -> do
+ src <- liftIO $ existingFile 0 ""
+ dest <- liftIO newFile
+ case (src, dest) of
+ (Just s, Just d) -> return $ FuzzMove s d
+ _ -> genFuzzAction
+ FuzzMoveDir _ _ -> do
+ md <- liftIO existingDir
+ case md of
+ Nothing -> genFuzzAction
+ Just d -> do
+ newd <- liftIO $ newDir (parentDir $ toFilePath d)
+ maybe genFuzzAction (return . FuzzMoveDir d) newd
+ FuzzDeleteDir _ -> do
+ d <- liftIO existingDir
+ maybe genFuzzAction (return . FuzzDeleteDir) d
+ FuzzModify _ -> do
+ f <- liftIO $ existingFile 0 ""
+ maybe genFuzzAction (return . FuzzModify) f
+ FuzzPause _ -> return tmpl
+
+existingFile :: Int -> FilePath -> IO (Maybe FuzzFile)
+existingFile 0 _ = return Nothing
+existingFile n top = do
+ dir <- existingDirIncludingTop
+ contents <- catchDefaultIO [] (getDirectoryContents dir)
+ let files = filter isFuzzFile contents
+ if null files
+ then do
+ let dirs = filter isFuzzDir contents
+ if null dirs
+ then return Nothing
+ else do
+ i <- getStdRandom $ randomR (0, length dirs - 1)
+ existingFile (n - 1) (top </> dirs !! i)
+ else do
+ i <- getStdRandom $ randomR (0, length files - 1)
+ return $ Just $ FuzzFile $ top </> dir </> files !! i
+
+existingDirIncludingTop :: IO FilePath
+existingDirIncludingTop = do
+ dirs <- filter isFuzzDir <$> getDirectoryContents "."
+ if null dirs
+ then return "."
+ else do
+ n <- getStdRandom $ randomR (0, length dirs)
+ return $ ("." : dirs) !! n
+
+existingDir :: IO (Maybe FuzzDir)
+existingDir = do
+ d <- existingDirIncludingTop
+ return $ if isFuzzDir d
+ then Just $ FuzzDir d
+ else Nothing
+
+newFile :: IO (Maybe FuzzFile)
+newFile = go (100 :: Int)
+ where
+ go 0 = return Nothing
+ go n = do
+ f <- genFuzzFile
+ ifM (doesnotexist (toFilePath f))
+ ( return $ Just f
+ , go (n - 1)
+ )
+
+newDir :: FilePath -> IO (Maybe FuzzDir)
+newDir parent = go (100 :: Int)
+ where
+ go 0 = return Nothing
+ go n = do
+ (FuzzDir d) <- genFuzzDir
+ ifM (doesnotexist (parent </> d))
+ ( return $ Just $ FuzzDir d
+ , go (n - 1)
+ )
+
+doesnotexist :: FilePath -> IO Bool
+doesnotexist f = isNothing <$> catchMaybeIO (getSymbolicLinkStatus f)
diff --git a/Command/GCryptSetup.hs b/Command/GCryptSetup.hs
new file mode 100644
index 000000000..bdd770f15
--- /dev/null
+++ b/Command/GCryptSetup.hs
@@ -0,0 +1,39 @@
+{- git-annex command
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.GCryptSetup where
+
+import Common.Annex
+import Command
+import Annex.UUID
+import qualified Remote.GCrypt
+import qualified Git
+
+def :: [Command]
+def = [dontCheck repoExists $ noCommit $
+ command "gcryptsetup" paramValue seek
+ SectionPlumbing "sets up gcrypt repository"]
+
+seek :: [CommandSeek]
+seek = [withStrings start]
+
+start :: String -> CommandStart
+start gcryptid = next $ next $ do
+ u <- getUUID
+ when (u /= NoUUID) $
+ error "gcryptsetup refusing to run; this repository already has a git-annex uuid!"
+
+ g <- gitRepo
+ gu <- Remote.GCrypt.getGCryptUUID True g
+ let newgu = genUUIDInNameSpace gCryptNameSpace gcryptid
+ if gu == Nothing || gu == Just newgu
+ then if Git.repoIsLocalBare g
+ then do
+ void $ Remote.GCrypt.setupRepo gcryptid g
+ return True
+ else error "cannot use gcrypt in a non-bare repository"
+ else error "gcryptsetup uuid mismatch"
diff --git a/Command/Get.hs b/Command/Get.hs
new file mode 100644
index 000000000..9adf79393
--- /dev/null
+++ b/Command/Get.hs
@@ -0,0 +1,90 @@
+{- git-annex command
+ -
+ - Copyright 2010, 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Get where
+
+import Common.Annex
+import Command
+import qualified Remote
+import Annex.Content
+import Logs.Transfer
+import Annex.Wanted
+import GitAnnex.Options
+import qualified Command.Move
+import Types.Key
+
+def :: [Command]
+def = [withOptions getOptions $ command "get" paramPaths seek
+ SectionCommon "make content of annexed files available"]
+
+getOptions :: [Option]
+getOptions = fromOption : keyOptions
+
+seek :: [CommandSeek]
+seek =
+ [ withField fromOption Remote.byNameWithUUID $ \from ->
+ withKeyOptions (startKeys from) $
+ withFilesInGit $ whenAnnexed $ start from
+ ]
+
+start :: Maybe Remote -> FilePath -> (Key, Backend) -> CommandStart
+start from file (key, _) = start' expensivecheck from key (Just file)
+ where
+ expensivecheck = checkAuto (numCopiesCheck file key (<) <||> wantGet False (Just file))
+
+startKeys :: Maybe Remote -> Key -> CommandStart
+startKeys from key = start' (return True) from key Nothing
+
+start' :: Annex Bool -> Maybe Remote -> Key -> AssociatedFile -> CommandStart
+start' expensivecheck from key afile = stopUnless (not <$> inAnnex key) $
+ stopUnless expensivecheck $
+ case from of
+ Nothing -> go $ perform key afile
+ Just src ->
+ stopUnless (Command.Move.fromOk src key) $
+ go $ Command.Move.fromPerform src False key afile
+ where
+ go a = do
+ showStart "get" (fromMaybe (key2file key) afile)
+ next a
+
+perform :: Key -> AssociatedFile -> CommandPerform
+perform key afile = stopUnless (getViaTmp key $ getKeyFile key afile) $
+ next $ return True -- no cleanup needed
+
+{- Try to find a copy of the file in one of the remotes,
+ - and copy it to here. -}
+getKeyFile :: Key -> AssociatedFile -> FilePath -> Annex Bool
+getKeyFile key afile dest = dispatch =<< Remote.keyPossibilities key
+ where
+ dispatch [] = do
+ showNote "not available"
+ showlocs
+ return False
+ dispatch remotes = trycopy remotes remotes
+ trycopy full [] = do
+ Remote.showTriedRemotes full
+ showlocs
+ return False
+ trycopy full (r:rs) =
+ ifM (probablyPresent r)
+ ( docopy r (trycopy full rs)
+ , trycopy full rs
+ )
+ showlocs = Remote.showLocations key []
+ "No other repository is known to contain the file."
+ -- This check is to avoid an ugly message if a remote is a
+ -- drive that is not mounted.
+ probablyPresent r
+ | Remote.hasKeyCheap r =
+ either (const False) id <$> Remote.hasKey r key
+ | otherwise = return True
+ docopy r continue = do
+ ok <- download (Remote.uuid r) key afile noRetry $ \p -> do
+ showAction $ "from " ++ Remote.name r
+ Remote.retrieveKeyFile r key afile dest p
+ if ok then return ok else continue
diff --git a/Command/Group.hs b/Command/Group.hs
new file mode 100644
index 000000000..4c0bf4899
--- /dev/null
+++ b/Command/Group.hs
@@ -0,0 +1,35 @@
+{- git-annex command
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Group where
+
+import Common.Annex
+import Command
+import qualified Remote
+import Logs.Group
+import Types.Group
+
+import qualified Data.Set as S
+
+def :: [Command]
+def = [command "group" (paramPair paramRemote paramDesc) seek
+ SectionSetup "add a repository to a group"]
+
+seek :: [CommandSeek]
+seek = [withWords start]
+
+start :: [String] -> CommandStart
+start (name:g:[]) = do
+ showStart "group" name
+ u <- Remote.nameToUUID name
+ next $ perform u g
+start _ = error "Specify a repository and a group."
+
+perform :: UUID -> Group -> CommandPerform
+perform uuid g = do
+ groupChange uuid (S.insert g)
+ next $ return True
diff --git a/Command/Help.hs b/Command/Help.hs
new file mode 100644
index 000000000..c77f739c1
--- /dev/null
+++ b/Command/Help.hs
@@ -0,0 +1,62 @@
+{- git-annex command
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Help where
+
+import Common.Annex
+import Command
+import qualified Command.Init
+import qualified Command.Add
+import qualified Command.Drop
+import qualified Command.Get
+import qualified Command.Move
+import qualified Command.Copy
+import qualified Command.Sync
+import qualified Command.Whereis
+import qualified Command.Fsck
+import GitAnnex.Options
+
+import System.Console.GetOpt
+
+def :: [Command]
+def = [noCommit $ noRepo showGeneralHelp $ dontCheck repoExists $
+ command "help" paramNothing seek SectionQuery "display help"]
+
+seek :: [CommandSeek]
+seek = [withWords start]
+
+start :: [String] -> CommandStart
+start ["options"] = do
+ liftIO showCommonOptions
+ stop
+start _ = do
+ liftIO showGeneralHelp
+ stop
+
+showCommonOptions :: IO ()
+showCommonOptions = putStrLn $ usageInfo "Common options:" options
+
+showGeneralHelp :: IO ()
+showGeneralHelp = putStrLn $ unlines
+ [ "The most frequently used git-annex commands are:"
+ , unlines $ map cmdline $ concat
+ [ Command.Init.def
+ , Command.Add.def
+ , Command.Drop.def
+ , Command.Get.def
+ , Command.Move.def
+ , Command.Copy.def
+ , Command.Sync.def
+ , Command.Whereis.def
+ , Command.Fsck.def
+ ]
+ , "Run 'git-annex' for a complete command list."
+ , "Run 'git-annex command --help' for help on a specific command."
+ , "Run `git annex help options' for a list of common options."
+ ]
+ where
+ cmdline c = "\t" ++ cmdname c ++ "\t" ++ cmddesc c
diff --git a/Command/Import.hs b/Command/Import.hs
new file mode 100644
index 000000000..dcadd96ce
--- /dev/null
+++ b/Command/Import.hs
@@ -0,0 +1,104 @@
+{- git-annex command
+ -
+ - Copyright 2012-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Import where
+
+import System.PosixCompat.Files
+
+import Common.Annex
+import Command
+import qualified Annex
+import qualified Command.Add
+import qualified Option
+import Utility.CopyFile
+import Backend
+import Remote
+import Types.KeySource
+
+def :: [Command]
+def = [withOptions opts $ notBareRepo $ command "import" paramPaths seek
+ SectionCommon "move and add files from outside git working copy"]
+
+opts :: [Option]
+opts =
+ [ duplicateOption
+ , deduplicateOption
+ , cleanDuplicatesOption
+ ]
+
+duplicateOption :: Option
+duplicateOption = Option.flag [] "duplicate" "do not delete outside files"
+
+deduplicateOption :: Option
+deduplicateOption = Option.flag [] "deduplicate" "do not add files whose content has been seen"
+
+cleanDuplicatesOption :: Option
+cleanDuplicatesOption = Option.flag [] "clean-duplicates" "delete outside duplicate files (import nothing)"
+
+data DuplicateMode = Default | Duplicate | DeDuplicate | CleanDuplicates
+ deriving (Eq)
+
+getDuplicateMode :: Annex DuplicateMode
+getDuplicateMode = gen
+ <$> getflag duplicateOption
+ <*> getflag deduplicateOption
+ <*> getflag cleanDuplicatesOption
+ where
+ getflag = Annex.getFlag . Option.name
+ gen False False False = Default
+ gen True False False = Duplicate
+ gen False True False = DeDuplicate
+ gen False False True = CleanDuplicates
+ gen _ _ _ = error "bad combination of --duplicate, --deduplicate, --clean-duplicates"
+
+seek :: [CommandSeek]
+seek = [withValue getDuplicateMode $ \mode -> withPathContents $ start mode]
+
+start :: DuplicateMode -> (FilePath, FilePath) -> CommandStart
+start mode (srcfile, destfile) =
+ ifM (liftIO $ isRegularFile <$> getSymbolicLinkStatus srcfile)
+ ( do
+ showStart "import" destfile
+ next $ perform mode srcfile destfile
+ , stop
+ )
+
+perform :: DuplicateMode -> FilePath -> FilePath -> CommandPerform
+perform mode srcfile destfile =
+ case mode of
+ DeDuplicate -> ifM isdup
+ ( deletedup
+ , go
+ )
+ CleanDuplicates -> ifM isdup
+ ( deletedup
+ , next $ return True
+ )
+ _ -> go
+ where
+ isdup = do
+ backend <- chooseBackend destfile
+ let ks = KeySource srcfile srcfile Nothing
+ v <- genKey ks backend
+ case v of
+ Just (k, _) -> not . null <$> keyLocations k
+ _ -> return False
+ deletedup = do
+ showNote "duplicate"
+ liftIO $ removeFile srcfile
+ next $ return True
+ go = do
+ whenM (liftIO $ doesFileExist destfile) $
+ unlessM (Annex.getState Annex.force) $
+ error $ "not overwriting existing " ++ destfile ++
+ " (use --force to override)"
+
+ liftIO $ createDirectoryIfMissing True (parentDir destfile)
+ liftIO $ if mode == Duplicate
+ then void $ copyFileExternal srcfile destfile
+ else moveFile srcfile destfile
+ Command.Add.perform destfile
diff --git a/Command/ImportFeed.hs b/Command/ImportFeed.hs
new file mode 100644
index 000000000..45a0d3b7e
--- /dev/null
+++ b/Command/ImportFeed.hs
@@ -0,0 +1,218 @@
+{- git-annex command
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.ImportFeed where
+
+import Text.Feed.Import
+import Text.Feed.Query
+import Text.Feed.Types
+import qualified Data.Set as S
+import qualified Data.Map as M
+import Data.Time.Clock
+
+import Common.Annex
+import qualified Annex
+import Command
+import qualified Annex.Url as Url
+import Logs.Web
+import qualified Option
+import qualified Utility.Format
+import Utility.Tmp
+import Command.AddUrl (addUrlFile, relaxedOption)
+import Annex.Perms
+import Backend.URL (fromUrl)
+
+def :: [Command]
+def = [notBareRepo $ withOptions [templateOption, relaxedOption] $
+ command "importfeed" (paramRepeating paramUrl) seek
+ SectionCommon "import files from podcast feeds"]
+
+templateOption :: Option
+templateOption = Option.field [] "template" paramFormat "template for filenames"
+
+seek :: [CommandSeek]
+seek = [withField templateOption return $ \tmpl ->
+ withFlag relaxedOption $ \relaxed ->
+ withValue (getCache tmpl) $ \cache ->
+ withStrings $ start relaxed cache]
+
+start :: Bool -> Cache -> URLString -> CommandStart
+start relaxed cache url = do
+ showStart "importfeed" url
+ next $ perform relaxed cache url
+
+perform :: Bool -> Cache -> URLString -> CommandPerform
+perform relaxed cache url = do
+ v <- findEnclosures url
+ case v of
+ Just l | not (null l) -> do
+ ok <- and <$> mapM (downloadEnclosure relaxed cache) l
+ unless ok $
+ feedProblem url "problem downloading item"
+ next $ cleanup url True
+ _ -> do
+ feedProblem url "bad feed content"
+ next $ return True
+
+cleanup :: URLString -> Bool -> CommandCleanup
+cleanup url ok = do
+ when ok $
+ clearFeedProblem url
+ return ok
+
+data ToDownload = ToDownload
+ { feed :: Feed
+ , feedurl :: URLString
+ , item :: Item
+ , location :: URLString
+ }
+
+mkToDownload :: Feed -> URLString -> Item -> Maybe ToDownload
+mkToDownload f u i = case getItemEnclosure i of
+ Nothing -> Nothing
+ Just (enclosureurl, _, _) -> Just $ ToDownload f u i enclosureurl
+
+data Cache = Cache
+ { knownurls :: S.Set URLString
+ , template :: Utility.Format.Format
+ }
+
+getCache :: Maybe String -> Annex Cache
+getCache opttemplate = ifM (Annex.getState Annex.force)
+ ( ret S.empty
+ , do
+ showSideAction "checking known urls"
+ ret =<< S.fromList <$> knownUrls
+ )
+ where
+ tmpl = Utility.Format.gen $ fromMaybe defaultTemplate opttemplate
+ ret s = return $ Cache s tmpl
+
+findEnclosures :: URLString -> Annex (Maybe [ToDownload])
+findEnclosures url = extract <$> downloadFeed url
+ where
+ extract Nothing = Nothing
+ extract (Just f) = Just $ mapMaybe (mkToDownload f url) (feedItems f)
+
+{- Feeds change, so a feed download cannot be resumed. -}
+downloadFeed :: URLString -> Annex (Maybe Feed)
+downloadFeed url = do
+ showOutput
+ ua <- Url.getUserAgent
+ liftIO $ withTmpFile "feed" $ \f h -> do
+ fileEncoding h
+ ifM (Url.download url [] [] f ua)
+ ( parseFeedString <$> hGetContentsStrict h
+ , return Nothing
+ )
+
+{- Avoids downloading any urls that are already known to be associated
+ - with a file in the annex, unless forced. -}
+downloadEnclosure :: Bool -> Cache -> ToDownload -> Annex Bool
+downloadEnclosure relaxed cache enclosure
+ | S.member url (knownurls cache) = ifM forced (go, return True)
+ | otherwise = go
+ where
+ forced = Annex.getState Annex.force
+ url = location enclosure
+ go = do
+ dest <- makeunique (1 :: Integer) $ feedFile (template cache) enclosure
+ case dest of
+ Nothing -> return True
+ Just f -> do
+ showStart "addurl" f
+ ok <- addUrlFile relaxed url f
+ if ok
+ then do
+ showEndOk
+ return True
+ else do
+ showEndFail
+ checkFeedBroken (feedurl enclosure)
+ {- Find a unique filename to save the url to.
+ - If the file exists, prefixes it with a number.
+ - When forced, the file may already exist and have the same
+ - url, in which case Nothing is returned as it does not need
+ - to be re-downloaded. -}
+ makeunique n file = ifM alreadyexists
+ ( ifM forced
+ ( ifAnnexed f checksameurl tryanother
+ , tryanother
+ )
+ , return $ Just f
+ )
+ where
+ f = if n < 2
+ then file
+ else
+ let (d, base) = splitFileName file
+ in d </> show n ++ "_" ++ base
+ tryanother = makeunique (n + 1) file
+ alreadyexists = liftIO $ isJust <$> catchMaybeIO (getSymbolicLinkStatus f)
+ checksameurl (k, _) = ifM (elem url <$> getUrls k)
+ ( return Nothing
+ , tryanother
+ )
+
+defaultTemplate :: String
+defaultTemplate = "${feedtitle}/${itemtitle}${extension}"
+
+{- Generates a filename to use for a feed item by filling out the template.
+ - The filename may not be unique. -}
+feedFile :: Utility.Format.Format -> ToDownload -> FilePath
+feedFile tmpl i = Utility.Format.format tmpl $ M.fromList
+ [ field "feedtitle" $ getFeedTitle $ feed i
+ , fieldMaybe "itemtitle" $ getItemTitle $ item i
+ , fieldMaybe "feedauthor" $ getFeedAuthor $ feed i
+ , fieldMaybe "itemauthor" $ getItemAuthor $ item i
+ , fieldMaybe "itemsummary" $ getItemSummary $ item i
+ , fieldMaybe "itemdescription" $ getItemDescription $ item i
+ , fieldMaybe "itemrights" $ getItemRights $ item i
+ , fieldMaybe "itemid" $ snd <$> getItemId (item i)
+ , ("extension", sanitizeFilePath $ takeExtension $ location i)
+ ]
+ where
+ field k v =
+ let s = sanitizeFilePath v in
+ if null s then (k, "none") else (k, s)
+ fieldMaybe k Nothing = (k, "none")
+ fieldMaybe k (Just v) = field k v
+
+{- Called when there is a problem with a feed.
+ - Throws an error if the feed is broken, otherwise shows a warning. -}
+feedProblem :: URLString -> String -> Annex ()
+feedProblem url message = ifM (checkFeedBroken url)
+ ( error $ message ++ " (having repeated problems with this feed!)"
+ , warning $ "warning: " ++ message
+ )
+
+{- A feed is only broken if problems have occurred repeatedly, for at
+ - least 23 hours. -}
+checkFeedBroken :: URLString -> Annex Bool
+checkFeedBroken url = checkFeedBroken' url =<< feedState url
+checkFeedBroken' :: URLString -> FilePath -> Annex Bool
+checkFeedBroken' url f = do
+ prev <- maybe Nothing readish <$> liftIO (catchMaybeIO $ readFile f)
+ now <- liftIO getCurrentTime
+ case prev of
+ Nothing -> do
+ createAnnexDirectory (parentDir f)
+ liftIO $ writeFile f $ show now
+ return False
+ Just prevtime -> do
+ let broken = diffUTCTime now prevtime > 60 * 60 * 23
+ when broken $
+ -- Avoid repeatedly complaining about
+ -- broken feed.
+ clearFeedProblem url
+ return broken
+
+clearFeedProblem :: URLString -> Annex ()
+clearFeedProblem url = void $ liftIO . tryIO . removeFile =<< feedState url
+
+feedState :: URLString -> Annex FilePath
+feedState url = fromRepo . gitAnnexFeedState =<< fromUrl url Nothing
diff --git a/Command/InAnnex.hs b/Command/InAnnex.hs
new file mode 100644
index 000000000..4410d722d
--- /dev/null
+++ b/Command/InAnnex.hs
@@ -0,0 +1,27 @@
+{- git-annex command
+ -
+ - Copyright 2010 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.InAnnex where
+
+import Common.Annex
+import Command
+import Annex.Content
+
+def :: [Command]
+def = [noCommit $ command "inannex" (paramRepeating paramKey) seek
+ SectionPlumbing "checks if keys are present in the annex"]
+
+seek :: [CommandSeek]
+seek = [withKeys start]
+
+start :: Key -> CommandStart
+start key = inAnnexSafe key >>= dispatch
+ where
+ dispatch (Just True) = stop
+ dispatch (Just False) = exit 1
+ dispatch Nothing = exit 100
+ exit n = liftIO $ exitWith $ ExitFailure n
diff --git a/Command/Indirect.hs b/Command/Indirect.hs
new file mode 100644
index 000000000..8b857e2f6
--- /dev/null
+++ b/Command/Indirect.hs
@@ -0,0 +1,113 @@
+{- git-annex command
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Indirect where
+
+import System.PosixCompat.Files
+import Control.Exception.Extensible
+
+import Common.Annex
+import Command
+import qualified Git
+import qualified Git.Command
+import qualified Git.LsFiles
+import Git.FileMode
+import Config
+import qualified Annex
+import Annex.Direct
+import Annex.Content
+import Annex.Content.Direct
+import Annex.CatFile
+import Annex.Version
+import Annex.Exception
+import Init
+import qualified Command.Add
+
+def :: [Command]
+def = [notBareRepo $ noDaemonRunning $
+ command "indirect" paramNothing seek
+ SectionSetup "switch repository to indirect mode"]
+
+seek :: [CommandSeek]
+seek = [withNothing start]
+
+start :: CommandStart
+start = ifM isDirect
+ ( do
+ unlessM (coreSymlinks <$> Annex.getGitConfig) $
+ error "Git is configured to not use symlinks, so you must use direct mode."
+ whenM probeCrippledFileSystem $
+ error "This repository seems to be on a crippled filesystem, you must use direct mode."
+ next perform
+ , stop
+ )
+
+perform :: CommandPerform
+perform = do
+ showStart "commit" ""
+ whenM stageDirect $ do
+ showOutput
+ void $ inRepo $ Git.Command.runBool
+ [ Param "commit"
+ , Param "-m"
+ , Param "commit before switching to indirect mode"
+ ]
+ showEndOk
+
+ -- Note that we set indirect mode early, so that we can use
+ -- moveAnnex in indirect mode.
+ setDirect False
+
+ top <- fromRepo Git.repoPath
+ (l, clean) <- inRepo $ Git.LsFiles.stagedOthersDetails [top]
+ forM_ l go
+ void $ liftIO clean
+ next cleanup
+ where
+ {- Walk tree from top and move all present direct mode files into
+ - the annex, replacing with symlinks. Also delete direct mode
+ - caches and mappings. -}
+ go (f, Just sha, Just mode) | isSymLink mode = do
+ r <- liftIO $ catchMaybeIO $ getSymbolicLinkStatus f
+ case r of
+ Just s
+ | isSymbolicLink s -> void $ flip whenAnnexed f $
+ \_ (k, _) -> do
+ removeInodeCache k
+ removeAssociatedFiles k
+ return Nothing
+ | otherwise ->
+ maybe noop (fromdirect f)
+ =<< catKey sha mode
+ _ -> noop
+ go _ = noop
+
+ fromdirect f k = do
+ showStart "indirect" f
+ removeInodeCache k
+ removeAssociatedFiles k
+ whenM (liftIO $ not . isSymbolicLink <$> getSymbolicLinkStatus f) $ do
+ v <-tryAnnexIO (moveAnnex k f)
+ case v of
+ Right _ -> do
+ l <- inRepo $ gitAnnexLink f k
+ liftIO $ createSymbolicLink l f
+ Left e -> catchAnnex (Command.Add.undo f k e)
+ warnlocked
+ showEndOk
+
+ warnlocked :: SomeException -> Annex ()
+ warnlocked e = do
+ warning $ show e
+ warning "leaving this file as-is; correct this problem and run git annex add on it"
+
+cleanup :: CommandCleanup
+cleanup = do
+ setVersion defaultVersion
+ showStart "indirect" ""
+ showEndOk
+ return True
diff --git a/Command/Info.hs b/Command/Info.hs
new file mode 100644
index 000000000..d465f2d84
--- /dev/null
+++ b/Command/Info.hs
@@ -0,0 +1,384 @@
+{- git-annex command
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE BangPatterns #-}
+
+module Command.Info where
+
+import "mtl" Control.Monad.State.Strict
+import qualified Data.Map as M
+import Text.JSON
+import Data.Tuple
+import Data.Ord
+import System.PosixCompat.Files
+
+import Common.Annex
+import qualified Remote
+import qualified Command.Unused
+import qualified Git
+import qualified Annex
+import Command
+import Utility.DataUnits
+import Utility.DiskFree
+import Annex.Content
+import Types.Key
+import Logs.UUID
+import Logs.Trust
+import Remote
+import Config
+import Utility.Percentage
+import Logs.Transfer
+import Types.TrustLevel
+import Types.FileMatcher
+import qualified Limit
+
+-- a named computation that produces a statistic
+type Stat = StatState (Maybe (String, StatState String))
+
+-- data about a set of keys
+data KeyData = KeyData
+ { countKeys :: Integer
+ , sizeKeys :: Integer
+ , unknownSizeKeys :: Integer
+ , backendsKeys :: M.Map String Integer
+ }
+
+data NumCopiesStats = NumCopiesStats
+ { numCopiesVarianceMap :: M.Map Variance Integer
+ }
+
+newtype Variance = Variance Int
+ deriving (Eq, Ord)
+
+instance Show Variance where
+ show (Variance n)
+ | n >= 0 = "numcopies +" ++ show n
+ | otherwise = "numcopies " ++ show n
+
+-- cached info that multiple Stats use
+data StatInfo = StatInfo
+ { presentData :: Maybe KeyData
+ , referencedData :: Maybe KeyData
+ , numCopiesStats :: Maybe NumCopiesStats
+ }
+
+-- a state monad for running Stats in
+type StatState = StateT StatInfo Annex
+
+def :: [Command]
+def = [noCommit $ command "info" paramPaths seek
+ SectionQuery "shows general information about the annex"]
+
+seek :: [CommandSeek]
+seek = [withWords start]
+
+start :: [FilePath] -> CommandStart
+start [] = do
+ globalInfo
+ stop
+start ps = do
+ mapM_ localInfo =<< filterM isdir ps
+ stop
+ where
+ isdir = liftIO . catchBoolIO . (isDirectory <$$> getFileStatus)
+
+globalInfo :: Annex ()
+globalInfo = do
+ stats <- selStats global_fast_stats global_slow_stats
+ showCustom "info" $ do
+ evalStateT (mapM_ showStat stats) (StatInfo Nothing Nothing Nothing)
+ return True
+
+localInfo :: FilePath -> Annex ()
+localInfo dir = showCustom (unwords ["info", dir]) $ do
+ stats <- selStats (tostats local_fast_stats) (tostats local_slow_stats)
+ evalStateT (mapM_ showStat stats) =<< getLocalStatInfo dir
+ return True
+ where
+ tostats = map (\s -> s dir)
+
+selStats :: [Stat] -> [Stat] -> Annex [Stat]
+selStats fast_stats slow_stats = do
+ fast <- Annex.getState Annex.fast
+ return $ if fast
+ then fast_stats
+ else fast_stats ++ slow_stats
+
+{- Order is significant. Less expensive operations, and operations
+ - that share data go together.
+ -}
+global_fast_stats :: [Stat]
+global_fast_stats =
+ [ repository_mode
+ , remote_list Trusted
+ , remote_list SemiTrusted
+ , remote_list UnTrusted
+ , transfer_list
+ , disk_size
+ ]
+global_slow_stats :: [Stat]
+global_slow_stats =
+ [ tmp_size
+ , bad_data_size
+ , local_annex_keys
+ , local_annex_size
+ , known_annex_files
+ , known_annex_size
+ , bloom_info
+ , backend_usage
+ ]
+local_fast_stats :: [FilePath -> Stat]
+local_fast_stats =
+ [ local_dir
+ , const local_annex_keys
+ , const local_annex_size
+ , const known_annex_files
+ , const known_annex_size
+ ]
+local_slow_stats :: [FilePath -> Stat]
+local_slow_stats =
+ [ const numcopies_stats
+ ]
+
+stat :: String -> (String -> StatState String) -> Stat
+stat desc a = return $ Just (desc, a desc)
+
+nostat :: Stat
+nostat = return Nothing
+
+json :: JSON j => (j -> String) -> StatState j -> String -> StatState String
+json serialize a desc = do
+ j <- a
+ lift $ maybeShowJSON [(desc, j)]
+ return $ serialize j
+
+nojson :: StatState String -> String -> StatState String
+nojson a _ = a
+
+showStat :: Stat -> StatState ()
+showStat s = maybe noop calc =<< s
+ where
+ calc (desc, a) = do
+ (lift . showHeader) desc
+ lift . showRaw =<< a
+
+repository_mode :: Stat
+repository_mode = stat "repository mode" $ json id $ lift $
+ ifM isDirect
+ ( return "direct", return "indirect" )
+
+remote_list :: TrustLevel -> Stat
+remote_list level = stat n $ nojson $ lift $ do
+ us <- M.keys <$> (M.union <$> uuidMap <*> remoteMap Remote.name)
+ rs <- fst <$> trustPartition level us
+ s <- prettyPrintUUIDs n rs
+ return $ if null s then "0" else show (length rs) ++ "\n" ++ beginning s
+ where
+ n = showTrustLevel level ++ " repositories"
+
+local_dir :: FilePath -> Stat
+local_dir dir = stat "directory" $ json id $ return dir
+
+local_annex_keys :: Stat
+local_annex_keys = stat "local annex keys" $ json show $
+ countKeys <$> cachedPresentData
+
+local_annex_size :: Stat
+local_annex_size = stat "local annex size" $ json id $
+ showSizeKeys <$> cachedPresentData
+
+known_annex_files :: Stat
+known_annex_files = stat "annexed files in working tree" $ json show $
+ countKeys <$> cachedReferencedData
+
+known_annex_size :: Stat
+known_annex_size = stat "size of annexed files in working tree" $ json id $
+ showSizeKeys <$> cachedReferencedData
+
+tmp_size :: Stat
+tmp_size = staleSize "temporary directory size" gitAnnexTmpDir
+
+bad_data_size :: Stat
+bad_data_size = staleSize "bad keys size" gitAnnexBadDir
+
+bloom_info :: Stat
+bloom_info = stat "bloom filter size" $ json id $ do
+ localkeys <- countKeys <$> cachedPresentData
+ capacity <- fromIntegral <$> lift Command.Unused.bloomCapacity
+ let note = aside $
+ if localkeys >= capacity
+ then "appears too small for this repository; adjust annex.bloomcapacity"
+ else showPercentage 1 (percentage capacity localkeys) ++ " full"
+
+ -- Two bloom filters are used at the same time, so double the size
+ -- of one.
+ size <- roughSize memoryUnits False . (* 2) . fromIntegral . fst <$>
+ lift Command.Unused.bloomBitsHashes
+
+ return $ size ++ note
+
+transfer_list :: Stat
+transfer_list = stat "transfers in progress" $ nojson $ lift $ do
+ uuidmap <- Remote.remoteMap id
+ ts <- getTransfers
+ return $ if null ts
+ then "none"
+ else multiLine $
+ map (uncurry $ line uuidmap) $ sort ts
+ where
+ line uuidmap t i = unwords
+ [ showLcDirection (transferDirection t) ++ "ing"
+ , fromMaybe (key2file $ transferKey t) (associatedFile i)
+ , if transferDirection t == Upload then "to" else "from"
+ , maybe (fromUUID $ transferUUID t) Remote.name $
+ M.lookup (transferUUID t) uuidmap
+ ]
+
+disk_size :: Stat
+disk_size = stat "available local disk space" $ json id $ lift $
+ calcfree
+ <$> (annexDiskReserve <$> Annex.getGitConfig)
+ <*> inRepo (getDiskFree . gitAnnexDir)
+ where
+ calcfree reserve (Just have) = unwords
+ [ roughSize storageUnits False $ nonneg $ have - reserve
+ , "(+" ++ roughSize storageUnits False reserve
+ , "reserved)"
+ ]
+ calcfree _ _ = "unknown"
+
+ nonneg x
+ | x >= 0 = x
+ | otherwise = 0
+
+backend_usage :: Stat
+backend_usage = stat "backend usage" $ nojson $
+ calc
+ <$> (backendsKeys <$> cachedReferencedData)
+ <*> (backendsKeys <$> cachedPresentData)
+ where
+ calc x y = multiLine $
+ map (\(n, b) -> b ++ ": " ++ show n) $
+ reverse $ sort $ map swap $ M.toList $
+ M.unionWith (+) x y
+
+numcopies_stats :: Stat
+numcopies_stats = stat "numcopies stats" $ nojson $
+ calc <$> (maybe M.empty numCopiesVarianceMap <$> cachedNumCopiesStats)
+ where
+ calc = multiLine
+ . map (\(variance, count) -> show variance ++ ": " ++ show count)
+ . reverse . sortBy (comparing snd) . M.toList
+
+cachedPresentData :: StatState KeyData
+cachedPresentData = do
+ s <- get
+ case presentData s of
+ Just v -> return v
+ Nothing -> do
+ v <- foldKeys <$> lift getKeysPresent
+ put s { presentData = Just v }
+ return v
+
+cachedReferencedData :: StatState KeyData
+cachedReferencedData = do
+ s <- get
+ case referencedData s of
+ Just v -> return v
+ Nothing -> do
+ !v <- lift $ Command.Unused.withKeysReferenced
+ emptyKeyData addKey
+ put s { referencedData = Just v }
+ return v
+
+-- currently only available for local info
+cachedNumCopiesStats :: StatState (Maybe NumCopiesStats)
+cachedNumCopiesStats = numCopiesStats <$> get
+
+getLocalStatInfo :: FilePath -> Annex StatInfo
+getLocalStatInfo dir = do
+ fast <- Annex.getState Annex.fast
+ matcher <- Limit.getMatcher
+ (presentdata, referenceddata, numcopiesstats) <-
+ Command.Unused.withKeysFilesReferencedIn dir initial
+ (update matcher fast)
+ return $ StatInfo (Just presentdata) (Just referenceddata) (Just numcopiesstats)
+ where
+ initial = (emptyKeyData, emptyKeyData, emptyNumCopiesStats)
+ update matcher fast key file vs@(presentdata, referenceddata, numcopiesstats) =
+ ifM (matcher $ FileInfo file file)
+ ( do
+ !presentdata' <- ifM (inAnnex key)
+ ( return $ addKey key presentdata
+ , return presentdata
+ )
+ let !referenceddata' = addKey key referenceddata
+ !numcopiesstats' <- if fast
+ then return numcopiesstats
+ else updateNumCopiesStats key file numcopiesstats
+ return $! (presentdata', referenceddata', numcopiesstats')
+ , return vs
+ )
+
+emptyKeyData :: KeyData
+emptyKeyData = KeyData 0 0 0 M.empty
+
+emptyNumCopiesStats :: NumCopiesStats
+emptyNumCopiesStats = NumCopiesStats M.empty
+
+foldKeys :: [Key] -> KeyData
+foldKeys = foldl' (flip addKey) emptyKeyData
+
+addKey :: Key -> KeyData -> KeyData
+addKey key (KeyData count size unknownsize backends) =
+ KeyData count' size' unknownsize' backends'
+ where
+ {- All calculations strict to avoid thunks when repeatedly
+ - applied to many keys. -}
+ !count' = count + 1
+ !backends' = M.insertWith' (+) (keyBackendName key) 1 backends
+ !size' = maybe size (+ size) ks
+ !unknownsize' = maybe (unknownsize + 1) (const unknownsize) ks
+ ks = keySize key
+
+updateNumCopiesStats :: Key -> FilePath -> NumCopiesStats -> Annex NumCopiesStats
+updateNumCopiesStats key file (NumCopiesStats m) = do
+ !variance <- Variance <$> numCopiesCheck file key (-)
+ let !m' = M.insertWith' (+) variance 1 m
+ let !ret = NumCopiesStats m'
+ return ret
+
+showSizeKeys :: KeyData -> String
+showSizeKeys d = total ++ missingnote
+ where
+ total = roughSize storageUnits False $ sizeKeys d
+ missingnote
+ | unknownSizeKeys d == 0 = ""
+ | otherwise = aside $
+ "+ " ++ show (unknownSizeKeys d) ++
+ " unknown size"
+
+staleSize :: String -> (Git.Repo -> FilePath) -> Stat
+staleSize label dirspec = go =<< lift (dirKeys dirspec)
+ where
+ go [] = nostat
+ go keys = onsize =<< sum <$> keysizes keys
+ onsize 0 = nostat
+ onsize size = stat label $
+ json (++ aside "clean up with git-annex unused") $
+ return $ roughSize storageUnits False size
+ keysizes keys = do
+ dir <- lift $ fromRepo dirspec
+ liftIO $ forM keys $ \k -> catchDefaultIO 0 $
+ fromIntegral . fileSize
+ <$> getFileStatus (dir </> keyFile k)
+
+aside :: String -> String
+aside s = " (" ++ s ++ ")"
+
+multiLine :: [String] -> String
+multiLine = concatMap (\l -> "\n\t" ++ l)
diff --git a/Command/Init.hs b/Command/Init.hs
new file mode 100644
index 000000000..3db9a6be3
--- /dev/null
+++ b/Command/Init.hs
@@ -0,0 +1,31 @@
+{- git-annex command
+ -
+ - Copyright 2010 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Init where
+
+import Common.Annex
+import Command
+import Init
+
+def :: [Command]
+def = [dontCheck repoExists $
+ command "init" paramDesc seek SectionSetup "initialize git-annex"]
+
+seek :: [CommandSeek]
+seek = [withWords start]
+
+start :: [String] -> CommandStart
+start ws = do
+ showStart "init" description
+ next $ perform description
+ where
+ description = unwords ws
+
+perform :: String -> CommandPerform
+perform description = do
+ initialize $ if null description then Nothing else Just description
+ next $ return True
diff --git a/Command/InitRemote.hs b/Command/InitRemote.hs
new file mode 100644
index 000000000..5a240f800
--- /dev/null
+++ b/Command/InitRemote.hs
@@ -0,0 +1,98 @@
+{- git-annex command
+ -
+ - Copyright 2011,2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.InitRemote where
+
+import qualified Data.Map as M
+
+import Common.Annex
+import Command
+import qualified Remote
+import qualified Logs.Remote
+import qualified Types.Remote as R
+import Logs.UUID
+import Logs.Trust
+
+import Data.Ord
+
+def :: [Command]
+def = [command "initremote"
+ (paramPair paramName $ paramOptional $ paramRepeating paramKeyValue)
+ seek SectionSetup "creates a special (non-git) remote"]
+
+seek :: [CommandSeek]
+seek = [withWords start]
+
+start :: [String] -> CommandStart
+start [] = error "Specify a name for the remote."
+start (name:ws) = ifM (isJust <$> findExisting name)
+ ( error $ "There is already a special remote named \"" ++ name ++
+ "\". (Use enableremote to enable an existing special remote.)"
+ , do
+ let c = newConfig name
+ t <- findType config
+
+ showStart "initremote" name
+ next $ perform t name $ M.union config c
+ )
+ where
+ config = Logs.Remote.keyValToConfig ws
+
+perform :: RemoteType -> String -> R.RemoteConfig -> CommandPerform
+perform t name c = do
+ (c', u) <- R.setup t Nothing c
+ next $ cleanup u name c'
+
+cleanup :: UUID -> String -> R.RemoteConfig -> CommandCleanup
+cleanup u name c = do
+ describeUUID u name
+ Logs.Remote.configSet u c
+ return True
+
+{- See if there's an existing special remote with this name. -}
+findExisting :: String -> Annex (Maybe (UUID, R.RemoteConfig))
+findExisting name = do
+ t <- trustMap
+ matches <- sortBy (comparing $ \(u, _c) -> M.lookup u t )
+ . findByName name
+ <$> Logs.Remote.readRemoteLog
+ return $ headMaybe matches
+
+newConfig :: String -> R.RemoteConfig
+newConfig name = M.singleton nameKey name
+
+findByName :: String -> M.Map UUID R.RemoteConfig -> [(UUID, R.RemoteConfig)]
+findByName n = filter (matching . snd) . M.toList
+ where
+ matching c = case M.lookup nameKey c of
+ Nothing -> False
+ Just n'
+ | n' == n -> True
+ | otherwise -> False
+
+remoteNames :: Annex [String]
+remoteNames = do
+ m <- Logs.Remote.readRemoteLog
+ return $ mapMaybe (M.lookup nameKey . snd) $ M.toList m
+
+{- find the specified remote type -}
+findType :: R.RemoteConfig -> Annex RemoteType
+findType config = maybe unspecified specified $ M.lookup typeKey config
+ where
+ unspecified = error "Specify the type of remote with type="
+ specified s = case filter (findtype s) Remote.remoteTypes of
+ [] -> error $ "Unknown remote type " ++ s
+ (t:_) -> return t
+ findtype s i = R.typename i == s
+
+{- The name of a configured remote is stored in its config using this key. -}
+nameKey :: String
+nameKey = "name"
+
+{- The type of a remote is stored in its config using this key. -}
+typeKey :: String
+typeKey = "type"
diff --git a/Command/List.hs b/Command/List.hs
new file mode 100644
index 000000000..12c27c022
--- /dev/null
+++ b/Command/List.hs
@@ -0,0 +1,88 @@
+{- git-annex command
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ - Copyright 2013 Antoine Beaupré
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.List where
+
+import qualified Data.Set as S
+import qualified Data.Map as M
+import Data.Function
+import Data.Tuple.Utils
+import Data.Ord
+
+import Common.Annex
+import Command
+import Remote
+import Logs.Trust
+import Logs.UUID
+import Annex.UUID
+import qualified Option
+import qualified Annex
+import Git.Types (RemoteName)
+
+def :: [Command]
+def = [noCommit $ withOptions [allrepos] $ command "list" paramPaths seek
+ SectionQuery "show which remotes contain files"]
+
+allrepos :: Option
+allrepos = Option.flag [] "allrepos" "show all repositories, not only remotes"
+
+seek :: [CommandSeek]
+seek =
+ [ withValue getList $ withNothing . startHeader
+ , withValue getList $ withFilesInGit . whenAnnexed . start
+ ]
+
+getList :: Annex [(UUID, RemoteName, TrustLevel)]
+getList = ifM (Annex.getFlag $ Option.name allrepos)
+ ( nubBy ((==) `on` fst3) <$> ((++) <$> getRemotes <*> getAll)
+ , getRemotes
+ )
+ where
+ getRemotes = do
+ rs <- remoteList
+ ts <- mapM (lookupTrust . uuid) rs
+ hereu <- getUUID
+ heretrust <- lookupTrust hereu
+ return $ (hereu, "here", heretrust) : zip3 (map uuid rs) (map name rs) ts
+ getAll = do
+ rs <- M.toList <$> uuidMap
+ rs3 <- forM rs $ \(u, n) -> (,,)
+ <$> pure u
+ <*> pure n
+ <*> lookupTrust u
+ return $ sortBy (comparing snd3) $
+ filter (\t -> thd3 t /= DeadTrusted) rs3
+
+startHeader :: [(UUID, RemoteName, TrustLevel)] -> CommandStart
+startHeader l = do
+ liftIO $ putStrLn $ header $ map (\(_, n, t) -> (n, t)) l
+ stop
+
+start :: [(UUID, RemoteName, TrustLevel)] -> FilePath -> (Key, Backend) -> CommandStart
+start l file (key, _) = do
+ ls <- S.fromList <$> keyLocations key
+ liftIO $ putStrLn $ format (map (\(u, _, t) -> (t, S.member u ls)) l) file
+ stop
+
+type Present = Bool
+
+header :: [(RemoteName, TrustLevel)] -> String
+header remotes = unlines (zipWith formatheader [0..] remotes) ++ pipes (length remotes)
+ where
+ formatheader n (remotename, trustlevel) = pipes n ++ remotename ++ trust trustlevel
+ pipes = flip replicate '|'
+ trust UnTrusted = " (untrusted)"
+ trust _ = ""
+
+format :: [(TrustLevel, Present)] -> FilePath -> String
+format remotes file = thereMap ++ " " ++ file
+ where
+ thereMap = concatMap there remotes
+ there (UnTrusted, True) = "x"
+ there (_, True) = "X"
+ there (_, False) = "_"
diff --git a/Command/Lock.hs b/Command/Lock.hs
new file mode 100644
index 000000000..6dc58df74
--- /dev/null
+++ b/Command/Lock.hs
@@ -0,0 +1,29 @@
+{- git-annex command
+ -
+ - Copyright 2010 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Lock where
+
+import Common.Annex
+import Command
+import qualified Annex.Queue
+
+def :: [Command]
+def = [notDirect $ command "lock" paramPaths seek SectionCommon
+ "undo unlock command"]
+
+seek :: [CommandSeek]
+seek = [withFilesUnlocked start, withFilesUnlockedToBeCommitted start]
+
+start :: FilePath -> CommandStart
+start file = do
+ showStart "lock" file
+ next $ perform file
+
+perform :: FilePath -> CommandPerform
+perform file = do
+ Annex.Queue.addCommand "checkout" [Param "--"] [file]
+ next $ return True -- no cleanup needed
diff --git a/Command/Log.hs b/Command/Log.hs
new file mode 100644
index 000000000..f3a5becb8
--- /dev/null
+++ b/Command/Log.hs
@@ -0,0 +1,171 @@
+{- git-annex command
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Log where
+
+import qualified Data.Set as S
+import qualified Data.Map as M
+import qualified Data.ByteString.Lazy.Char8 as L
+import Data.Time.Clock.POSIX
+import Data.Time
+import System.Locale
+import Data.Char
+
+import Common.Annex
+import Command
+import Logs
+import qualified Logs.Presence
+import Annex.CatFile
+import qualified Annex.Branch
+import qualified Git
+import Git.Command
+import qualified Remote
+import qualified Option
+import qualified Annex
+
+data RefChange = RefChange
+ { changetime :: POSIXTime
+ , oldref :: Git.Ref
+ , newref :: Git.Ref
+ }
+
+type Outputter = Bool -> POSIXTime -> [UUID] -> Annex ()
+
+def :: [Command]
+def = [withOptions options $
+ command "log" paramPaths seek SectionQuery "shows location log"]
+
+options :: [Option]
+options = passthruOptions ++ [gourceOption]
+
+passthruOptions :: [Option]
+passthruOptions = map odate ["since", "after", "until", "before"] ++
+ [ Option.field ['n'] "max-count" paramNumber
+ "limit number of logs displayed"
+ ]
+ where
+ odate n = Option.field [] n paramDate $ "show log " ++ n ++ " date"
+
+gourceOption :: Option
+gourceOption = Option.flag [] "gource" "format output for gource"
+
+seek :: [CommandSeek]
+seek = [withValue Remote.uuidDescriptions $ \m ->
+ withValue (liftIO getCurrentTimeZone) $ \zone ->
+ withValue (concat <$> mapM getoption passthruOptions) $ \os ->
+ withFlag gourceOption $ \gource ->
+ withFilesInGit $ whenAnnexed $ start m zone os gource]
+ where
+ getoption o = maybe [] (use o) <$>
+ Annex.getField (Option.name o)
+ use o v = [Param ("--" ++ Option.name o), Param v]
+
+start :: M.Map UUID String -> TimeZone -> [CommandParam] -> Bool ->
+ FilePath -> (Key, Backend) -> CommandStart
+start m zone os gource file (key, _) = do
+ showLog output =<< readLog <$> getLog key os
+ -- getLog produces a zombie; reap it
+ liftIO reapZombies
+ stop
+ where
+ output
+ | gource = gourceOutput lookupdescription file
+ | otherwise = normalOutput lookupdescription file zone
+ lookupdescription u = fromMaybe (fromUUID u) $ M.lookup u m
+
+showLog :: Outputter -> [RefChange] -> Annex ()
+showLog outputter ps = do
+ sets <- mapM (getset newref) ps
+ previous <- maybe (return genesis) (getset oldref) (lastMaybe ps)
+ sequence_ $ compareChanges outputter $ sets ++ [previous]
+ where
+ genesis = (0, S.empty)
+ getset select change = do
+ s <- S.fromList <$> get (select change)
+ return (changetime change, s)
+ get ref = map toUUID . Logs.Presence.getLog . L.unpack <$>
+ catObject ref
+
+normalOutput :: (UUID -> String) -> FilePath -> TimeZone -> Outputter
+normalOutput lookupdescription file zone present ts us =
+ liftIO $ mapM_ (putStrLn . format) us
+ where
+ time = showTimeStamp zone ts
+ addel = if present then "+" else "-"
+ format u = unwords [ addel, time, file, "|",
+ fromUUID u ++ " -- " ++ lookupdescription u ]
+
+gourceOutput :: (UUID -> String) -> FilePath -> Outputter
+gourceOutput lookupdescription file present ts us =
+ liftIO $ mapM_ (putStrLn . intercalate "|" . format) us
+ where
+ time = takeWhile isDigit $ show ts
+ addel = if present then "A" else "M"
+ format u = [ time, lookupdescription u, addel, file ]
+
+{- Generates a display of the changes (which are ordered with newest first),
+ - by comparing each change with the previous change.
+ - Uses a formatter to generate a display of items that are added and
+ - removed. -}
+compareChanges :: Ord a => (Bool -> POSIXTime -> [a] -> b) -> [(POSIXTime, S.Set a)] -> [b]
+compareChanges format changes = concatMap diff $ zip changes (drop 1 changes)
+ where
+ diff ((ts, new), (_, old)) =
+ [format True ts added, format False ts removed]
+ where
+ added = S.toList $ S.difference new old
+ removed = S.toList $ S.difference old new
+
+{- Gets the git log for a given location log file.
+ -
+ - This is complicated by git log using paths relative to the current
+ - directory, even when looking at files in a different branch. A wacky
+ - relative path to the log file has to be used.
+ -
+ - The --remove-empty is a significant optimisation. It relies on location
+ - log files never being deleted in normal operation. Letting git stop
+ - once the location log file is gone avoids it checking all the way back
+ - to commit 0 to see if it used to exist, so generally speeds things up a
+ - *lot* for newish files. -}
+getLog :: Key -> [CommandParam] -> Annex [String]
+getLog key os = do
+ top <- fromRepo Git.repoPath
+ p <- liftIO $ relPathCwdToFile top
+ let logfile = p </> locationLogFile key
+ inRepo $ pipeNullSplitZombie $
+ [ Params "log -z --pretty=format:%ct --raw --abbrev=40"
+ , Param "--remove-empty"
+ ] ++ os ++
+ [ Param $ show Annex.Branch.fullname
+ , Param "--"
+ , Param logfile
+ ]
+
+readLog :: [String] -> [RefChange]
+readLog = mapMaybe (parse . lines)
+ where
+ parse (ts:raw:[]) = let (old, new) = parseRaw raw in
+ Just RefChange
+ { changetime = parseTimeStamp ts
+ , oldref = old
+ , newref = new
+ }
+ parse _ = Nothing
+
+-- Parses something like ":100644 100644 oldsha newsha M"
+parseRaw :: String -> (Git.Ref, Git.Ref)
+parseRaw l = go $ words l
+ where
+ go (_:_:oldsha:newsha:_) = (Git.Ref oldsha, Git.Ref newsha)
+ go _ = error $ "unable to parse git log output: " ++ l
+
+parseTimeStamp :: String -> POSIXTime
+parseTimeStamp = utcTimeToPOSIXSeconds . fromMaybe (error "bad timestamp") .
+ parseTime defaultTimeLocale "%s"
+
+showTimeStamp :: TimeZone -> POSIXTime -> String
+showTimeStamp zone = show . utcToLocalTime zone . posixSecondsToUTCTime
diff --git a/Command/Map.hs b/Command/Map.hs
new file mode 100644
index 000000000..91f4a0251
--- /dev/null
+++ b/Command/Map.hs
@@ -0,0 +1,247 @@
+{- git-annex command
+ -
+ - Copyright 2010 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Map where
+
+import Control.Exception.Extensible
+import qualified Data.Map as M
+
+import Common.Annex
+import Command
+import qualified Git
+import qualified Git.Url
+import qualified Git.Config
+import qualified Git.Construct
+import qualified Annex
+import Annex.UUID
+import Logs.UUID
+import Logs.Trust
+import qualified Remote.Helper.Ssh as Ssh
+import qualified Utility.Dot as Dot
+
+-- a link from the first repository to the second (its remote)
+data Link = Link Git.Repo Git.Repo
+
+def :: [Command]
+def = [dontCheck repoExists $
+ command "map" paramNothing seek SectionQuery
+ "generate map of repositories"]
+
+seek :: [CommandSeek]
+seek = [withNothing start]
+
+start :: CommandStart
+start = do
+ rs <- combineSame <$> (spider =<< gitRepo)
+
+ umap <- uuidMap
+ trusted <- trustGet Trusted
+
+ file <- (</>) <$> fromRepo gitAnnexDir <*> pure "map.dot"
+
+ liftIO $ writeFile file (drawMap rs umap trusted)
+ next $ next $
+ ifM (Annex.getState Annex.fast)
+ ( return True
+ , do
+ showLongNote $ "running: dot -Tx11 " ++ file
+ showOutput
+ liftIO $ boolSystem "dot" [Param "-Tx11", File file]
+ )
+
+{- Generates a graph for dot(1). Each repository, and any other uuids, are
+ - displayed as a node, and each of its remotes is represented as an edge
+ - pointing at the node for the remote.
+ -
+ - The order nodes are added to the graph matters, since dot will draw
+ - the first ones near to the top and left. So it looks better to put
+ - the repositories first, followed by uuids that were not matched
+ - to a repository.
+ -}
+drawMap :: [Git.Repo] -> M.Map UUID String -> [UUID] -> String
+drawMap rs umap ts = Dot.graph $ repos ++ trusted ++ others
+ where
+ repos = map (node umap rs) rs
+ ruuids = ts ++ map getUncachedUUID rs
+ others = map (unreachable . uuidnode) $
+ filter (`notElem` ruuids) (M.keys umap)
+ trusted = map (trustworthy . uuidnode) ts
+ uuidnode u = Dot.graphNode (fromUUID u) $ M.findWithDefault "" u umap
+
+hostname :: Git.Repo -> String
+hostname r
+ | Git.repoIsUrl r = fromMaybe (Git.repoLocation r) (Git.Url.host r)
+ | otherwise = "localhost"
+
+basehostname :: Git.Repo -> String
+basehostname r = fromMaybe "" $ headMaybe $ split "." $ hostname r
+
+{- A name to display for a repo. Uses the name from uuid.log if available,
+ - or the remote name if not. -}
+repoName :: M.Map UUID String -> Git.Repo -> String
+repoName umap r
+ | repouuid == NoUUID = fallback
+ | otherwise = M.findWithDefault fallback repouuid umap
+ where
+ repouuid = getUncachedUUID r
+ fallback = fromMaybe "unknown" $ Git.remoteName r
+
+{- A unique id for the node for a repo. Uses the annex.uuid if available. -}
+nodeId :: Git.Repo -> String
+nodeId r =
+ case getUncachedUUID r of
+ NoUUID -> Git.repoLocation r
+ UUID u -> u
+
+{- A node representing a repo. -}
+node :: M.Map UUID String -> [Git.Repo] -> Git.Repo -> String
+node umap fullinfo r = unlines $ n:edges
+ where
+ n = Dot.subGraph (hostname r) (basehostname r) "lightblue" $
+ decorate $ Dot.graphNode (nodeId r) (repoName umap r)
+ edges = map (edge umap fullinfo r) (Git.remotes r)
+ decorate
+ | Git.config r == M.empty = unreachable
+ | otherwise = reachable
+
+{- An edge between two repos. The second repo is a remote of the first. -}
+edge :: M.Map UUID String -> [Git.Repo] -> Git.Repo -> Git.Repo -> String
+edge umap fullinfo from to =
+ Dot.graphEdge (nodeId from) (nodeId fullto) edgename
+ where
+ -- get the full info for the remote, to get its UUID
+ fullto = findfullinfo to
+ findfullinfo n =
+ case filter (same n) fullinfo of
+ [] -> n
+ (n':_) -> n'
+ {- Only name an edge if the name is different than the name
+ - that will be used for the destination node, and is
+ - different from its hostname. (This reduces visual clutter.) -}
+ edgename = maybe Nothing calcname $ Git.remoteName to
+ calcname n
+ | n `elem` [repoName umap fullto, hostname fullto] = Nothing
+ | otherwise = Just n
+
+unreachable :: String -> String
+unreachable = Dot.fillColor "red"
+reachable :: String -> String
+reachable = Dot.fillColor "white"
+trustworthy :: String -> String
+trustworthy = Dot.fillColor "green"
+
+{- Recursively searches out remotes starting with the specified repo. -}
+spider :: Git.Repo -> Annex [Git.Repo]
+spider r = spider' [r] []
+spider' :: [Git.Repo] -> [Git.Repo] -> Annex [Git.Repo]
+spider' [] known = return known
+spider' (r:rs) known
+ | any (same r) known = spider' rs known
+ | otherwise = do
+ r' <- scan r
+
+ -- The remotes will be relative to r', and need to be
+ -- made absolute for later use.
+ remotes <- mapM (absRepo r') (Git.remotes r')
+ let r'' = r' { Git.remotes = remotes }
+
+ spider' (rs ++ remotes) (r'':known)
+
+{- Converts repos to a common absolute form. -}
+absRepo :: Git.Repo -> Git.Repo -> Annex Git.Repo
+absRepo reference r
+ | Git.repoIsUrl reference = return $ Git.Construct.localToUrl reference r
+ | Git.repoIsUrl r = return r
+ | otherwise = liftIO $ Git.Construct.fromAbsPath =<< absPath (Git.repoPath r)
+
+{- Checks if two repos are the same. -}
+same :: Git.Repo -> Git.Repo -> Bool
+same a b
+ | both Git.repoIsSsh = matching Git.Url.authority && matching Git.repoPath
+ | both Git.repoIsUrl && neither Git.repoIsSsh = matching show
+ | neither Git.repoIsSsh = matching Git.repoPath
+ | otherwise = False
+ where
+ matching t = t a == t b
+ both t = t a && t b
+ neither t = not (t a) && not (t b)
+
+{- reads the config of a remote, with progress display -}
+scan :: Git.Repo -> Annex Git.Repo
+scan r = do
+ showStart "map" $ Git.repoDescribe r
+ v <- tryScan r
+ case v of
+ Just r' -> do
+ showEndOk
+ return r'
+ Nothing -> do
+ showOutput
+ showEndFail
+ return r
+
+{- tries to read the config of a remote, returning it only if it can
+ - be accessed -}
+tryScan :: Git.Repo -> Annex (Maybe Git.Repo)
+tryScan r
+ | Git.repoIsSsh r = sshscan
+ | Git.repoIsUrl r = return Nothing
+ | otherwise = safely $ Git.Config.read r
+ where
+ safely a = do
+ result <- liftIO (try a :: IO (Either SomeException Git.Repo))
+ case result of
+ Left _ -> return Nothing
+ Right r' -> return $ Just r'
+ pipedconfig cmd params = safely $
+ withHandle StdoutHandle createProcessSuccess p $
+ Git.Config.hRead r
+ where
+ p = proc cmd $ toCommand params
+
+ configlist = Ssh.onRemote r (pipedconfig, Nothing) "configlist" [] []
+ manualconfiglist = do
+ sshparams <- Ssh.toRepo r [Param sshcmd]
+ liftIO $ pipedconfig "ssh" sshparams
+ where
+ sshcmd = cddir ++ " && " ++
+ "git config --null --list"
+ dir = Git.repoPath r
+ cddir
+ | "/~" `isPrefixOf` dir =
+ let (userhome, reldir) = span (/= '/') (drop 1 dir)
+ in "cd " ++ userhome ++ " && cd " ++ shellEscape (drop 1 reldir)
+ | otherwise = "cd " ++ shellEscape dir
+
+ -- First, try sshing and running git config manually,
+ -- only fall back to git-annex-shell configlist if that
+ -- fails.
+ --
+ -- This is done for two reasons, first I'd like this
+ -- subcommand to be usable on non-git-annex repos.
+ -- Secondly, configlist doesn't include information about
+ -- the remote's remotes.
+ sshscan = do
+ sshnote
+ v <- manualconfiglist
+ case v of
+ Nothing -> do
+ sshnote
+ configlist
+ ok -> return ok
+
+ sshnote = do
+ showAction "sshing"
+ showOutput
+
+{- Spidering can find multiple paths to the same repo, so this is used
+ - to combine (really remove) duplicate repos with the same UUID. -}
+combineSame :: [Git.Repo] -> [Git.Repo]
+combineSame = map snd . nubBy sameuuid . map pair
+ where
+ sameuuid (u1, _) (u2, _) = u1 == u2 && u1 /= NoUUID
+ pair r = (getUncachedUUID r, r)
diff --git a/Command/Merge.hs b/Command/Merge.hs
new file mode 100644
index 000000000..31db7a99f
--- /dev/null
+++ b/Command/Merge.hs
@@ -0,0 +1,38 @@
+{- git-annex command
+ -
+ - Copyright 2011, 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Merge where
+
+import Common.Annex
+import Command
+import qualified Annex.Branch
+import qualified Git.Branch
+import Command.Sync (prepMerge, mergeLocal)
+
+def :: [Command]
+def = [command "merge" paramNothing seek SectionMaintenance
+ "automatically merge changes from remotes"]
+
+seek :: [CommandSeek]
+seek =
+ [ withNothing mergeBranch
+ , withNothing mergeSynced
+ ]
+
+mergeBranch :: CommandStart
+mergeBranch = do
+ showStart "merge" "git-annex"
+ next $ do
+ Annex.Branch.update
+ -- commit explicitly, in case no remote branches were merged
+ Annex.Branch.commit "update"
+ next $ return True
+
+mergeSynced :: CommandStart
+mergeSynced = do
+ prepMerge
+ mergeLocal =<< inRepo Git.Branch.current
diff --git a/Command/Migrate.hs b/Command/Migrate.hs
new file mode 100644
index 000000000..0fdf0e817
--- /dev/null
+++ b/Command/Migrate.hs
@@ -0,0 +1,77 @@
+{- git-annex command
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Migrate where
+
+import Common.Annex
+import Command
+import Backend
+import qualified Types.Key
+import qualified Types.Backend
+import Types.KeySource
+import Annex.Content
+import qualified Command.ReKey
+import qualified Command.Fsck
+
+def :: [Command]
+def = [notDirect $
+ command "migrate" paramPaths seek
+ SectionUtility "switch data to different backend"]
+
+seek :: [CommandSeek]
+seek = [withFilesInGit $ whenAnnexed start]
+
+start :: FilePath -> (Key, Backend) -> CommandStart
+start file (key, oldbackend) = do
+ exists <- inAnnex key
+ newbackend <- choosebackend =<< chooseBackend file
+ if (newbackend /= oldbackend || upgradableKey oldbackend key) && exists
+ then do
+ showStart "migrate" file
+ next $ perform file key oldbackend newbackend
+ else stop
+ where
+ choosebackend Nothing = Prelude.head <$> orderedList
+ choosebackend (Just backend) = return backend
+
+{- Checks if a key is upgradable to a newer representation.
+ -
+ - Reasons for migration:
+ - - Ideally, all keys have file size metadata. Old keys may not.
+ - - Something has changed in the backend, such as a bug fix.
+ -}
+upgradableKey :: Backend -> Key -> Bool
+upgradableKey backend key = isNothing (Types.Key.keySize key) || backendupgradable
+ where
+ backendupgradable = maybe False (\a -> a key)
+ (Types.Backend.canUpgradeKey backend)
+
+{- Store the old backend's key in the new backend
+ - The old backend's key is not dropped from it, because there may
+ - be other files still pointing at that key.
+ -
+ - To ensure that the data we have for the old key is valid, it's
+ - fscked here. First we generate the new key. This ensures that the
+ - data cannot get corrupted after the fsck but before the new key is
+ - generated.
+ -}
+perform :: FilePath -> Key -> Backend -> Backend -> CommandPerform
+perform file oldkey oldbackend newbackend = go =<< genkey
+ where
+ go Nothing = stop
+ go (Just newkey) = stopUnless checkcontent $ finish newkey
+ checkcontent = Command.Fsck.checkBackend oldbackend oldkey $ Just file
+ finish newkey = stopUnless (Command.ReKey.linkKey oldkey newkey) $
+ next $ Command.ReKey.cleanup file oldkey newkey
+ genkey = do
+ content <- calcRepo $ gitAnnexLocation oldkey
+ let source = KeySource
+ { keyFilename = file
+ , contentLocation = content
+ , inodeCache = Nothing
+ }
+ liftM fst <$> genKey source (Just newbackend)
diff --git a/Command/Mirror.hs b/Command/Mirror.hs
new file mode 100644
index 000000000..c0dd8a51f
--- /dev/null
+++ b/Command/Mirror.hs
@@ -0,0 +1,58 @@
+{- git-annex command
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Mirror where
+
+import Common.Annex
+import Command
+import GitAnnex.Options
+import qualified Command.Move
+import qualified Command.Drop
+import qualified Command.Get
+import qualified Remote
+import Annex.Content
+import qualified Annex
+
+def :: [Command]
+def = [withOptions fromToOptions $ command "mirror" paramPaths seek
+ SectionCommon "mirror content of files to/from another repository"]
+
+seek :: [CommandSeek]
+seek =
+ [ withField toOption Remote.byNameWithUUID $ \to ->
+ withField fromOption Remote.byNameWithUUID $ \from ->
+ withFilesInGit $ whenAnnexed $ start to from
+ ]
+
+start :: Maybe Remote -> Maybe Remote -> FilePath -> (Key, Backend) -> CommandStart
+start to from file (key, _backend) = do
+ noAuto
+ case (from, to) of
+ (Nothing, Nothing) -> error "specify either --from or --to"
+ (Nothing, Just r) -> mirrorto r
+ (Just r, Nothing) -> mirrorfrom r
+ _ -> error "only one of --from or --to can be specified"
+ where
+ noAuto = whenM (Annex.getState Annex.auto) $
+ error "--auto is not supported for mirror"
+ mirrorto r = ifM (inAnnex key)
+ ( Command.Move.toStart r False (Just file) key
+ , do
+ numcopies <- numCopies file
+ Command.Drop.startRemote file numcopies key r
+ )
+ mirrorfrom r = do
+ haskey <- Remote.hasKey r key
+ case haskey of
+ Left _ -> stop
+ Right True -> Command.Get.start' (return True) Nothing key (Just file)
+ Right False -> ifM (inAnnex key)
+ ( do
+ numcopies <- numCopies file
+ Command.Drop.startLocal file numcopies key Nothing
+ , stop
+ )
diff --git a/Command/Move.hs b/Command/Move.hs
new file mode 100644
index 000000000..dc501ae0f
--- /dev/null
+++ b/Command/Move.hs
@@ -0,0 +1,166 @@
+{- git-annex command
+ -
+ - Copyright 2010-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Move where
+
+import Common.Annex
+import Command
+import qualified Command.Drop
+import qualified Annex
+import Annex.Content
+import qualified Remote
+import Annex.UUID
+import Logs.Presence
+import Logs.Transfer
+import GitAnnex.Options
+import Types.Key
+
+def :: [Command]
+def = [withOptions moveOptions $ command "move" paramPaths seek
+ SectionCommon "move content of files to/from another repository"]
+
+moveOptions :: [Option]
+moveOptions = fromToOptions ++ keyOptions
+
+seek :: [CommandSeek]
+seek =
+ [ withField toOption Remote.byNameWithUUID $ \to ->
+ withField fromOption Remote.byNameWithUUID $ \from ->
+ withKeyOptions (startKey to from True) $
+ withFilesInGit $ whenAnnexed $ start to from True
+ ]
+
+start :: Maybe Remote -> Maybe Remote -> Bool -> FilePath -> (Key, Backend) -> CommandStart
+start to from move file (key, _) = start' to from move (Just file) key
+
+startKey :: Maybe Remote -> Maybe Remote -> Bool -> Key -> CommandStart
+startKey to from move = start' to from move Nothing
+
+start' :: Maybe Remote -> Maybe Remote -> Bool -> AssociatedFile -> Key -> CommandStart
+start' to from move afile key = do
+ noAuto
+ case (from, to) of
+ (Nothing, Nothing) -> error "specify either --from or --to"
+ (Nothing, Just dest) -> toStart dest move afile key
+ (Just src, Nothing) -> fromStart src move afile key
+ _ -> error "only one of --from or --to can be specified"
+ where
+ noAuto = when move $ whenM (Annex.getState Annex.auto) $ error
+ "--auto is not supported for move"
+
+showMoveAction :: Bool -> Key -> AssociatedFile -> Annex ()
+showMoveAction True _ (Just file) = showStart "move" file
+showMoveAction False _ (Just file) = showStart "copy" file
+showMoveAction True key Nothing = showStart "move" (key2file key)
+showMoveAction False key Nothing = showStart "copy" (key2file key)
+
+{- Moves (or copies) the content of an annexed file to a remote.
+ -
+ - If the remote already has the content, it is still removed from
+ - the current repository.
+ -
+ - Note that unlike drop, this does not honor annex.numcopies.
+ - A file's content can be moved even if there are insufficient copies to
+ - allow it to be dropped.
+ -}
+toStart :: Remote -> Bool -> AssociatedFile -> Key -> CommandStart
+toStart dest move afile key = do
+ u <- getUUID
+ ishere <- inAnnex key
+ if not ishere || u == Remote.uuid dest
+ then stop -- not here, so nothing to do
+ else do
+ showMoveAction move key afile
+ next $ toPerform dest move key afile
+toPerform :: Remote -> Bool -> Key -> AssociatedFile -> CommandPerform
+toPerform dest move key afile = moveLock move key $ do
+ -- Checking the remote is expensive, so not done in the start step.
+ -- In fast mode, location tracking is assumed to be correct,
+ -- and an explicit check is not done, when copying. When moving,
+ -- it has to be done, to avoid inaverdent data loss.
+ fast <- Annex.getState Annex.fast
+ let fastcheck = fast && not move && not (Remote.hasKeyCheap dest)
+ isthere <- if fastcheck
+ then Right <$> expectedpresent
+ else Remote.hasKey dest key
+ case isthere of
+ Left err -> do
+ showNote err
+ stop
+ Right False -> do
+ showAction $ "to " ++ Remote.name dest
+ ok <- upload (Remote.uuid dest) key afile noRetry $
+ Remote.storeKey dest key afile
+ if ok
+ then do
+ Remote.logStatus dest key InfoPresent
+ finish
+ else do
+ when fastcheck $
+ warning "This could have failed because --fast is enabled."
+ stop
+ Right True -> do
+ unlessM expectedpresent $
+ Remote.logStatus dest key InfoPresent
+ finish
+ where
+ finish
+ | move = do
+ removeAnnex key
+ next $ Command.Drop.cleanupLocal key
+ | otherwise = next $ return True
+ expectedpresent = do
+ remotes <- Remote.keyPossibilities key
+ return $ dest `elem` remotes
+
+{- Moves (or copies) the content of an annexed file from a remote
+ - to the current repository.
+ -
+ - If the current repository already has the content, it is still removed
+ - from the remote.
+ -}
+fromStart :: Remote -> Bool -> AssociatedFile -> Key -> CommandStart
+fromStart src move afile key
+ | move = go
+ | otherwise = stopUnless (not <$> inAnnex key) go
+ where
+ go = stopUnless (fromOk src key) $ do
+ showMoveAction move key afile
+ next $ fromPerform src move key afile
+
+fromOk :: Remote -> Key -> Annex Bool
+fromOk src key
+ | Remote.hasKeyCheap src =
+ either (const expensive) return =<< Remote.hasKey src key
+ | otherwise = expensive
+ where
+ expensive = do
+ u <- getUUID
+ remotes <- Remote.keyPossibilities key
+ return $ u /= Remote.uuid src && elem src remotes
+
+fromPerform :: Remote -> Bool -> Key -> AssociatedFile -> CommandPerform
+fromPerform src move key afile = moveLock move key $
+ ifM (inAnnex key)
+ ( handle move True
+ , handle move =<< go
+ )
+ where
+ go = download (Remote.uuid src) key afile noRetry $ \p -> do
+ showAction $ "from " ++ Remote.name src
+ getViaTmp key $ \t -> Remote.retrieveKeyFile src key afile t p
+ handle _ False = stop -- failed
+ handle False True = next $ return True -- copy complete
+ handle True True = do -- finish moving
+ ok <- Remote.removeKey src key
+ next $ Command.Drop.cleanupRemote key src ok
+
+{- Locks a key in order for it to be moved.
+ - No lock is needed when a key is being copied. -}
+moveLock :: Bool -> Key -> Annex a -> Annex a
+moveLock True key a = lockContent key a
+moveLock False _ a = a
diff --git a/Command/PreCommit.hs b/Command/PreCommit.hs
new file mode 100644
index 000000000..f10ac628e
--- /dev/null
+++ b/Command/PreCommit.hs
@@ -0,0 +1,57 @@
+{- git-annex command
+ -
+ - Copyright 2010, 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.PreCommit where
+
+import Common.Annex
+import Command
+import qualified Command.Add
+import qualified Command.Fix
+import qualified Git.DiffTree
+import qualified Git.Ref
+import Annex.CatFile
+import Annex.Content.Direct
+import Git.Sha
+import Git.FilePath
+
+def :: [Command]
+def = [command "pre-commit" paramPaths seek SectionPlumbing
+ "run by git pre-commit hook"]
+
+seek :: [CommandSeek]
+seek =
+ -- fix symlinks to files being committed
+ [ whenNotDirect $ withFilesToBeCommitted $ whenAnnexed Command.Fix.start
+ -- inject unlocked files into the annex
+ , whenNotDirect $ withFilesUnlockedToBeCommitted startIndirect
+ -- update direct mode mappings for committed files
+ , whenDirect $ withWords startDirect
+ ]
+
+startIndirect :: FilePath -> CommandStart
+startIndirect file = next $ do
+ unlessM (doCommand $ Command.Add.start file) $
+ error $ "failed to add " ++ file ++ "; canceling commit"
+ next $ return True
+
+startDirect :: [String] -> CommandStart
+startDirect _ = next $ do
+ (diffs, clean) <- inRepo $ Git.DiffTree.diffIndex Git.Ref.headRef
+ makeabs <- flip fromTopFilePath <$> gitRepo
+ forM_ diffs (go makeabs)
+ next $ liftIO clean
+ where
+ go makeabs diff = do
+ withkey (Git.DiffTree.srcsha diff) (Git.DiffTree.srcmode diff) removeAssociatedFile
+ withkey (Git.DiffTree.dstsha diff) (Git.DiffTree.dstmode diff) addAssociatedFile
+ where
+ withkey sha mode a = when (sha /= nullSha) $ do
+ k <- catKey sha mode
+ case k of
+ Nothing -> noop
+ Just key -> void $ a key $
+ makeabs $ Git.DiffTree.file diff
diff --git a/Command/ReKey.hs b/Command/ReKey.hs
new file mode 100644
index 000000000..7448ba97e
--- /dev/null
+++ b/Command/ReKey.hs
@@ -0,0 +1,71 @@
+{- git-annex command
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.ReKey where
+
+import Common.Annex
+import Command
+import qualified Annex
+import Types.Key
+import Annex.Content
+import qualified Command.Add
+import Logs.Web
+import Logs.Location
+import Utility.CopyFile
+
+def :: [Command]
+def = [notDirect $ command "rekey"
+ (paramOptional $ paramRepeating $ paramPair paramPath paramKey)
+ seek SectionPlumbing "change keys used for files"]
+
+seek :: [CommandSeek]
+seek = [withPairs start]
+
+start :: (FilePath, String) -> CommandStart
+start (file, keyname) = ifAnnexed file go stop
+ where
+ newkey = fromMaybe (error "bad key") $ file2key keyname
+ go (oldkey, _)
+ | oldkey == newkey = stop
+ | otherwise = do
+ showStart "rekey" file
+ next $ perform file oldkey newkey
+
+perform :: FilePath -> Key -> Key -> CommandPerform
+perform file oldkey newkey = do
+ present <- inAnnex oldkey
+ _ <- if present
+ then linkKey oldkey newkey
+ else do
+ unlessM (Annex.getState Annex.force) $
+ error $ file ++ " is not available (use --force to override)"
+ return True
+ next $ cleanup file oldkey newkey
+
+{- Make a hard link to the old key content (when supported),
+ - to avoid wasting disk space. -}
+linkKey :: Key -> Key -> Annex Bool
+linkKey oldkey newkey = getViaTmpUnchecked newkey $ \tmp -> do
+ src <- calcRepo $ gitAnnexLocation oldkey
+ liftIO $ ifM (doesFileExist tmp)
+ ( return True
+ , createLinkOrCopy src tmp
+ )
+
+cleanup :: FilePath -> Key -> Key -> CommandCleanup
+cleanup file oldkey newkey = do
+ -- If the old key had some associated urls, record them for
+ -- the new key as well.
+ urls <- getUrls oldkey
+ unless (null urls) $
+ mapM_ (setUrlPresent newkey) urls
+
+ -- Update symlink to use the new key.
+ liftIO $ removeFile file
+ Command.Add.addLink file newkey Nothing
+ logStatus newkey InfoPresent
+ return True
diff --git a/Command/RecvKey.hs b/Command/RecvKey.hs
new file mode 100644
index 000000000..3b2a8c496
--- /dev/null
+++ b/Command/RecvKey.hs
@@ -0,0 +1,89 @@
+{- git-annex command
+ -
+ - Copyright 2010 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.RecvKey where
+
+import System.PosixCompat.Files
+
+import Common.Annex
+import Command
+import CmdLine
+import Annex.Content
+import Annex
+import Utility.Rsync
+import Logs.Transfer
+import Command.SendKey (fieldTransfer)
+import qualified Fields
+import qualified Types.Key
+import qualified Types.Backend
+import qualified Backend
+
+def :: [Command]
+def = [noCommit $ command "recvkey" paramKey seek
+ SectionPlumbing "runs rsync in server mode to receive content"]
+
+seek :: [CommandSeek]
+seek = [withKeys start]
+
+start :: Key -> CommandStart
+start key = ifM (inAnnex key)
+ ( error "key is already present in annex"
+ , fieldTransfer Download key $ \_p ->
+ ifM (getViaTmp key go)
+ ( do
+ -- forcibly quit after receiving one key,
+ -- and shutdown cleanly
+ _ <- shutdown True
+ return True
+ , return False
+ )
+ )
+ where
+ go tmp = do
+ opts <- filterRsyncSafeOptions . maybe [] words
+ <$> getField "RsyncOptions"
+ ok <- liftIO $ rsyncServerReceive (map Param opts) tmp
+
+ -- The file could have been received with permissions that
+ -- do not allow reading it, so this is done before the
+ -- directcheck.
+ freezeContent tmp
+
+ if ok
+ then ifM (isJust <$> Fields.getField Fields.direct)
+ ( directcheck tmp
+ , return True
+ )
+ else return False
+ {- If the sending repository uses direct mode, the file
+ - it sends could be modified as it's sending it. So check
+ - that the right size file was received, and that the key/value
+ - Backend is happy with it. -}
+ directcheck tmp = do
+ oksize <- case Types.Key.keySize key of
+ Nothing -> return True
+ Just size -> do
+ size' <- fromIntegral . fileSize
+ <$> liftIO (getFileStatus tmp)
+ return $ size == size'
+ if oksize
+ then case Backend.maybeLookupBackendName (Types.Key.keyBackendName key) of
+ Nothing -> do
+ warning "recvkey: received key from direct mode repository using unknown backend; cannot check; discarding"
+ return False
+ Just backend -> maybe (return True) runfsck
+ (Types.Backend.fsckKey backend)
+ else do
+ warning "recvkey: received key with wrong size; discarding"
+ return False
+ where
+ runfsck check = ifM (check key tmp)
+ ( return True
+ , do
+ warning "recvkey: received key from direct mode repository seems to have changed as it was transferred; discarding"
+ return False
+ )
diff --git a/Command/Reinject.hs b/Command/Reinject.hs
new file mode 100644
index 000000000..c49af0060
--- /dev/null
+++ b/Command/Reinject.hs
@@ -0,0 +1,58 @@
+{- git-annex command
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Reinject where
+
+import Common.Annex
+import Command
+import Logs.Location
+import Annex.Content
+import qualified Command.Fsck
+
+def :: [Command]
+def = [command "reinject" (paramPair "SRC" "DEST") seek
+ SectionUtility "sets content of annexed file"]
+
+seek :: [CommandSeek]
+seek = [withWords start]
+
+start :: [FilePath] -> CommandStart
+start (src:dest:[])
+ | src == dest = stop
+ | otherwise =
+ ifAnnexed src
+ (error $ "cannot used annexed file as src: " ++ src)
+ go
+ where
+ go = do
+ showStart "reinject" dest
+ next $ whenAnnexed (perform src) dest
+start _ = error "specify a src file and a dest file"
+
+perform :: FilePath -> FilePath -> (Key, Backend) -> CommandPerform
+perform src _dest (key, backend) =
+ {- Check the content before accepting it. -}
+ ifM (Command.Fsck.checkKeySizeOr reject key src
+ <&&> Command.Fsck.checkBackendOr reject backend key src)
+ ( do
+ unlessM move $ error "mv failed!"
+ next $ cleanup key
+ , error "not reinjecting"
+ )
+ where
+ -- the file might be on a different filesystem,
+ -- so mv is used rather than simply calling
+ -- moveToObjectDir; disk space is also
+ -- checked this way.
+ move = getViaTmp key $ \tmp ->
+ liftIO $ boolSystem "mv" [File src, File tmp]
+ reject = const $ return "wrong file?"
+
+cleanup :: Key -> CommandCleanup
+cleanup key = do
+ logStatus key InfoPresent
+ return True
diff --git a/Command/Repair.hs b/Command/Repair.hs
new file mode 100644
index 000000000..517e14afc
--- /dev/null
+++ b/Command/Repair.hs
@@ -0,0 +1,71 @@
+{- git-annex command
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Repair where
+
+import Common.Annex
+import Command
+import qualified Annex
+import qualified Git.Repair
+import qualified Annex.Branch
+import Git.Fsck (MissingObjects)
+import Git.Types
+import Annex.Version
+
+def :: [Command]
+def = [noCommit $ dontCheck repoExists $
+ command "repair" paramNothing seek SectionMaintenance "recover broken git repository"]
+
+seek :: [CommandSeek]
+seek = [withNothing start]
+
+start :: CommandStart
+start = next $ next $ runRepair =<< Annex.getState Annex.force
+
+runRepair :: Bool -> Annex Bool
+runRepair forced = do
+ (ok, stillmissing, modifiedbranches) <- inRepo $
+ Git.Repair.runRepair forced
+ -- This command can be run in git repos not using git-annex,
+ -- so avoid git annex branch stuff in that case.
+ whenM (isJust <$> getVersion) $
+ repairAnnexBranch stillmissing modifiedbranches
+ return ok
+
+{- After git repository repair, the .git/annex/index file could
+ - still be broken, by pointing to bad objects, or might just be corrupt on
+ - its own. Since this index file is not used to stage things
+ - for long durations of time, it can safely be deleted if it is broken.
+ -
+ - Otherwise, if the git-annex branch was modified by the repair,
+ - commit the index file to the git-annex branch.
+ - This way, if the git-annex branch got rewound to an old version by
+ - the repository repair, or was completely deleted, this will get it back
+ - to a good state. Note that in the unlikely case where the git-annex
+ - branch was rewound to a state that, had new changes from elsewhere not
+ - yet reflected in the index, this does properly merge those into the
+ - index before committing.
+ -}
+repairAnnexBranch :: MissingObjects -> [Branch] -> Annex ()
+repairAnnexBranch missing modifiedbranches
+ | Annex.Branch.fullname `elem` modifiedbranches = ifM okindex
+ ( commitindex
+ , do
+ nukeindex
+ liftIO $ putStrLn "Had to delete the .git/annex/index file as it was corrupt. Since the git-annex branch is not up-to-date anymore. It would be a very good idea to run: git annex fsck --fast"
+ )
+ | otherwise = ifM okindex
+ ( noop
+ , nukeindex
+ )
+ where
+ okindex = Annex.Branch.withIndex $
+ inRepo $ Git.Repair.checkIndex missing
+ commitindex = do
+ Annex.Branch.forceCommit "committing index after git repository repair"
+ liftIO $ putStrLn "Successfully recovered the git-annex branch using .git/annex/index"
+ nukeindex = inRepo $ nukeFile . gitAnnexIndex
diff --git a/Command/RmUrl.hs b/Command/RmUrl.hs
new file mode 100644
index 000000000..d3ded38a3
--- /dev/null
+++ b/Command/RmUrl.hs
@@ -0,0 +1,30 @@
+{- git-annex command
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.RmUrl where
+
+import Common.Annex
+import Command
+import Logs.Web
+
+def :: [Command]
+def = [notBareRepo $
+ command "rmurl" (paramPair paramFile paramUrl) seek
+ SectionCommon "record file is not available at url"]
+
+seek :: [CommandSeek]
+seek = [withPairs start]
+
+start :: (FilePath, String) -> CommandStart
+start (file, url) = flip whenAnnexed file $ \_ (key, _) -> do
+ showStart "rmurl" file
+ next $ next $ cleanup url key
+
+cleanup :: String -> Key -> CommandCleanup
+cleanup url key = do
+ setUrlMissing key url
+ return True
diff --git a/Command/Schedule.hs b/Command/Schedule.hs
new file mode 100644
index 000000000..35f144c75
--- /dev/null
+++ b/Command/Schedule.hs
@@ -0,0 +1,50 @@
+{- git-annex command
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Schedule where
+
+import Common.Annex
+import Command
+import qualified Remote
+import Logs.Schedule
+import Types.ScheduledActivity
+
+import qualified Data.Set as S
+
+def :: [Command]
+def = [command "schedule" (paramPair paramRemote (paramOptional paramExpression)) seek
+ SectionSetup "get or set scheduled jobs"]
+
+seek :: [CommandSeek]
+seek = [withWords start]
+
+start :: [String] -> CommandStart
+start = parse
+ where
+ parse (name:[]) = go name performGet
+ parse (name:expr:[]) = go name $ \uuid -> do
+ showStart "schedile" name
+ performSet expr uuid
+ parse _ = error "Specify a repository."
+
+ go name a = do
+ u <- Remote.nameToUUID name
+ next $ a u
+
+performGet :: UUID -> CommandPerform
+performGet uuid = do
+ s <- scheduleGet uuid
+ liftIO $ putStrLn $ intercalate "; " $
+ map fromScheduledActivity $ S.toList s
+ next $ return True
+
+performSet :: String -> UUID -> CommandPerform
+performSet expr uuid = case parseScheduledActivities expr of
+ Left e -> error $ "Parse error: " ++ e
+ Right l -> do
+ scheduleSet uuid l
+ next $ return True
diff --git a/Command/Semitrust.hs b/Command/Semitrust.hs
new file mode 100644
index 000000000..e20563672
--- /dev/null
+++ b/Command/Semitrust.hs
@@ -0,0 +1,32 @@
+{- git-annex command
+ -
+ - Copyright 2010 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Semitrust where
+
+import Common.Annex
+import Command
+import qualified Remote
+import Logs.Trust
+
+def :: [Command]
+def = [command "semitrust" (paramRepeating paramRemote) seek
+ SectionSetup "return repository to default trust level"]
+
+seek :: [CommandSeek]
+seek = [withWords start]
+
+start :: [String] -> CommandStart
+start ws = do
+ let name = unwords ws
+ showStart "semitrust" name
+ u <- Remote.nameToUUID name
+ next $ perform u
+
+perform :: UUID -> CommandPerform
+perform uuid = do
+ trustSet uuid SemiTrusted
+ next $ return True
diff --git a/Command/SendKey.hs b/Command/SendKey.hs
new file mode 100644
index 000000000..24b1821c3
--- /dev/null
+++ b/Command/SendKey.hs
@@ -0,0 +1,49 @@
+{- git-annex command
+ -
+ - Copyright 2010,2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.SendKey where
+
+import Common.Annex
+import Command
+import Annex.Content
+import Annex
+import Utility.Rsync
+import Logs.Transfer
+import qualified Fields
+import Utility.Metered
+
+def :: [Command]
+def = [noCommit $ command "sendkey" paramKey seek
+ SectionPlumbing "runs rsync in server mode to send content"]
+
+seek :: [CommandSeek]
+seek = [withKeys start]
+
+start :: Key -> CommandStart
+start key = do
+ opts <- filterRsyncSafeOptions . maybe [] words
+ <$> getField "RsyncOptions"
+ ifM (inAnnex key)
+ ( fieldTransfer Upload key $ \_p ->
+ sendAnnex key rollback $ liftIO . rsyncServerSend (map Param opts)
+ , do
+ warning "requested key is not present"
+ liftIO exitFailure
+ )
+ where
+ {- No need to do any rollback; when sendAnnex fails, a nonzero
+ - exit will be propigated, and the remote will know the transfer
+ - failed. -}
+ rollback = noop
+
+fieldTransfer :: Direction -> Key -> (MeterUpdate -> Annex Bool) -> CommandStart
+fieldTransfer direction key a = do
+ afile <- Fields.getField Fields.associatedFile
+ ok <- maybe (a $ const noop)
+ (\u -> runTransfer (Transfer direction (toUUID u) key) afile noRetry a)
+ =<< Fields.getField Fields.remoteUUID
+ liftIO $ exitBool ok
diff --git a/Command/Status.hs b/Command/Status.hs
new file mode 100644
index 000000000..5dc625994
--- /dev/null
+++ b/Command/Status.hs
@@ -0,0 +1,89 @@
+{- git-annex command
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Status where
+
+import Common.Annex
+import Command
+import Annex.CatFile
+import Annex.Content.Direct
+import Config
+import qualified Git.LsFiles as LsFiles
+import qualified Git.Ref
+import qualified Git
+
+def :: [Command]
+def = [notBareRepo $ noCommit $ noMessages $
+ command "status" paramPaths seek SectionCommon
+ "show the working tree status"]
+
+seek :: [CommandSeek]
+seek =
+ [ withWords start
+ ]
+
+start :: [FilePath] -> CommandStart
+start [] = do
+ -- Like git status, when run without a directory, behave as if
+ -- given the path to the top of the repository.
+ cwd <- liftIO getCurrentDirectory
+ top <- fromRepo Git.repoPath
+ next $ perform [relPathDirToFile cwd top]
+start locs = next $ perform locs
+
+perform :: [FilePath] -> CommandPerform
+perform locs = do
+ (l, cleanup) <- inRepo $ LsFiles.modifiedOthers locs
+ getstatus <- ifM isDirect
+ ( return statusDirect
+ , return $ Just <$$> statusIndirect
+ )
+ forM_ l $ \f -> maybe noop (showFileStatus f) =<< getstatus f
+ void $ liftIO cleanup
+ next $ return True
+
+data Status
+ = NewFile
+ | DeletedFile
+ | ModifiedFile
+
+showStatus :: Status -> String
+showStatus NewFile = "?"
+showStatus DeletedFile = "D"
+showStatus ModifiedFile = "M"
+
+showFileStatus :: FilePath -> Status -> Annex ()
+showFileStatus f s = liftIO $ putStrLn $ showStatus s ++ " " ++ f
+
+statusDirect :: FilePath -> Annex (Maybe Status)
+statusDirect f = checkstatus =<< liftIO (catchMaybeIO $ getFileStatus f)
+ where
+ checkstatus Nothing = return $ Just DeletedFile
+ checkstatus (Just s)
+ -- Git thinks that present direct mode files modifed,
+ -- so have to check.
+ | not (isSymbolicLink s) = checkkey s =<< catKeyFile f
+ | otherwise = Just <$> checkNew f
+
+ checkkey s (Just k) = ifM (sameFileStatus k s)
+ ( return Nothing
+ , return $ Just ModifiedFile
+ )
+ checkkey _ Nothing = Just <$> checkNew f
+
+statusIndirect :: FilePath -> Annex Status
+statusIndirect f = ifM (liftIO $ isJust <$> catchMaybeIO (getFileStatus f))
+ ( checkNew f
+ , return DeletedFile
+ )
+ where
+
+checkNew :: FilePath -> Annex Status
+checkNew f = ifM (isJust <$> catObjectDetails (Git.Ref.fileRef f))
+ ( return ModifiedFile
+ , return NewFile
+ )
diff --git a/Command/Sync.hs b/Command/Sync.hs
new file mode 100644
index 000000000..c41f46f8a
--- /dev/null
+++ b/Command/Sync.hs
@@ -0,0 +1,450 @@
+{- git-annex command
+ -
+ - Copyright 2011 Joachim Breitner <mail@joachim-breitner.de>
+ - Copyright 2011,2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Sync where
+
+import Common.Annex
+import Command
+import qualified Remote
+import qualified Annex
+import qualified Annex.Branch
+import qualified Annex.Queue
+import Annex.Direct
+import Annex.CatFile
+import Annex.Link
+import qualified Git.Command
+import qualified Git.LsFiles as LsFiles
+import qualified Git.Merge
+import qualified Git.Branch
+import qualified Git.Ref
+import qualified Git
+import Git.Types (BlobType(..))
+import qualified Types.Remote
+import qualified Remote.Git
+import Types.Key
+import Config
+import Annex.ReplaceFile
+import Git.FileMode
+
+import qualified Data.Set as S
+import Data.Hash.MD5
+import Control.Concurrent.MVar
+
+def :: [Command]
+def = [command "sync" (paramOptional (paramRepeating paramRemote))
+ [seek] SectionCommon "synchronize local repository with remotes"]
+
+-- syncing involves several operations, any of which can independently fail
+seek :: CommandSeek
+seek rs = do
+ prepMerge
+
+ -- There may not be a branch checked out until after the commit,
+ -- or perhaps after it gets merged from the remote.
+ -- So only look it up once it's needed, and if once there is a
+ -- branch, cache it.
+ mvar <- liftIO newEmptyMVar
+ let getbranch = ifM (liftIO $ isEmptyMVar mvar)
+ ( do
+ branch <- inRepo Git.Branch.current
+ when (isJust branch) $
+ liftIO $ putMVar mvar branch
+ return branch
+ , liftIO $ readMVar mvar
+ )
+ let withbranch a = a =<< getbranch
+
+ remotes <- syncRemotes rs
+ return $ concat
+ [ [ commit ]
+ , [ withbranch mergeLocal ]
+ , [ withbranch (pullRemote remote) | remote <- remotes ]
+ , [ mergeAnnex ]
+ , [ withbranch pushLocal ]
+ , [ withbranch (pushRemote remote) | remote <- remotes ]
+ ]
+
+{- Merging may delete the current directory, so go to the top
+ - of the repo. -}
+prepMerge :: Annex ()
+prepMerge = liftIO . setCurrentDirectory =<< fromRepo Git.repoPath
+
+syncBranch :: Git.Ref -> Git.Ref
+syncBranch = Git.Ref.under "refs/heads/synced" . fromDirectBranch
+
+remoteBranch :: Remote -> Git.Ref -> Git.Ref
+remoteBranch remote = Git.Ref.underBase $ "refs/remotes/" ++ Remote.name remote
+
+syncRemotes :: [String] -> Annex [Remote]
+syncRemotes rs = ifM (Annex.getState Annex.fast) ( nub <$> pickfast , wanted )
+ where
+ pickfast = (++) <$> listed <*> (good =<< fastest <$> available)
+ wanted
+ | null rs = good =<< concat . Remote.byCost <$> available
+ | otherwise = listed
+ listed = do
+ l <- catMaybes <$> mapM (Remote.byName . Just) rs
+ let s = filter (not . Remote.syncableRemote) l
+ unless (null s) $
+ error $ "cannot sync special remotes: " ++
+ unwords (map Types.Remote.name s)
+ return l
+ available = filter Remote.syncableRemote
+ . filter (remoteAnnexSync . Types.Remote.gitconfig)
+ <$> Remote.remoteList
+ good = filterM $ Remote.Git.repoAvail . Types.Remote.repo
+ fastest = fromMaybe [] . headMaybe . Remote.byCost
+
+commit :: CommandStart
+commit = next $ next $ ifM isDirect
+ ( do
+ void stageDirect
+ runcommit []
+ , runcommit [Param "-a"]
+ )
+ where
+ runcommit ps = do
+ showStart "commit" ""
+ showOutput
+ Annex.Branch.commit "update"
+ -- Commit will fail when the tree is clean, so ignore failure.
+ let params = Param "commit" : ps ++
+ [Param "-m", Param "git-annex automatic sync"]
+ _ <- inRepo $ tryIO . Git.Command.runQuiet params
+ return True
+
+mergeLocal :: Maybe Git.Ref -> CommandStart
+mergeLocal Nothing = stop
+mergeLocal (Just branch) = go =<< needmerge
+ where
+ syncbranch = syncBranch branch
+ needmerge = ifM isBareRepo
+ ( return False
+ , do
+ unlessM (inRepo $ Git.Ref.exists syncbranch) $
+ inRepo $ updateBranch syncbranch
+ inRepo $ Git.Branch.changed branch syncbranch
+ )
+ go False = stop
+ go True = do
+ showStart "merge" $ Git.Ref.describe syncbranch
+ next $ next $ mergeFrom syncbranch
+
+pushLocal :: Maybe Git.Ref -> CommandStart
+pushLocal Nothing = stop
+pushLocal (Just branch) = do
+ -- Update the sync branch to match the new state of the branch
+ inRepo $ updateBranch $ syncBranch branch
+ -- In direct mode, we're operating on some special direct mode
+ -- branch, rather than the intended branch, so update the indended
+ -- branch.
+ whenM isDirect $
+ inRepo $ updateBranch $ fromDirectBranch branch
+ stop
+
+updateBranch :: Git.Ref -> Git.Repo -> IO ()
+updateBranch syncbranch g =
+ unlessM go $ error $ "failed to update " ++ show syncbranch
+ where
+ go = Git.Command.runBool
+ [ Param "branch"
+ , Param "-f"
+ , Param $ show $ Git.Ref.base syncbranch
+ ] g
+
+pullRemote :: Remote -> Maybe Git.Ref -> CommandStart
+pullRemote remote branch = do
+ showStart "pull" (Remote.name remote)
+ next $ do
+ showOutput
+ stopUnless fetch $
+ next $ mergeRemote remote branch
+ where
+ fetch = inRepo $ Git.Command.runBool
+ [Param "fetch", Param $ Remote.name remote]
+
+{- 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 (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
+ Nothing -> do
+ branch <- inRepo Git.Branch.currentUnsafe
+ and <$> mapM merge (branchlist branch)
+ Just _ -> and <$> (mapM merge =<< tomerge (branchlist b))
+ where
+ merge = mergeFrom . remoteBranch remote
+ tomerge branches = filterM (changed remote) branches
+ branchlist Nothing = []
+ branchlist (Just branch) = [branch, syncBranch branch]
+
+pushRemote :: Remote -> Maybe Git.Ref -> CommandStart
+pushRemote _remote Nothing = stop
+pushRemote remote (Just branch) = go =<< needpush
+ where
+ needpush = anyM (newer remote) [syncBranch branch, Annex.Branch.name]
+ go False = stop
+ go True = do
+ showStart "push" (Remote.name remote)
+ next $ next $ do
+ showOutput
+ ok <- inRepo $ pushBranch remote branch
+ unless ok $ do
+ warning $ unwords [ "Pushing to " ++ Remote.name remote ++ " failed." ]
+ showLongNote "(non-fast-forward problems can be solved by setting receive.denyNonFastforwards to false in the remote's git config)"
+ return ok
+
+{- Pushes a regular branch like master to a remote. Also pushes the git-annex
+ - branch.
+ -
+ - 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
+ - are tried.
+ -
+ - The direct push is likely to spew an ugly error message, so stderr is
+ - elided. Since git progress display goes 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.
+ -
+ - 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.
+ -
+ - The sync push will fail to overwrite if receive.denyNonFastforwards is
+ - set on the remote.
+ -}
+pushBranch :: Remote -> Git.Ref -> Git.Repo -> IO Bool
+pushBranch remote branch g = tryIO (directpush g) `after` syncpush g
+ where
+ syncpush = Git.Command.runBool $ pushparams
+ [ Git.Branch.forcePush $ refspec Annex.Branch.name
+ , refspec branch
+ ]
+ directpush = Git.Command.runQuiet $ pushparams
+ [show $ Git.Ref.base $ fromDirectBranch branch]
+ pushparams branches =
+ [ Param "push"
+ , Param $ Remote.name remote
+ ] ++ map Param branches
+ refspec b = concat
+ [ show $ Git.Ref.base b
+ , ":"
+ , show $ Git.Ref.base $ syncBranch b
+ ]
+
+mergeAnnex :: CommandStart
+mergeAnnex = do
+ void Annex.Branch.forceUpdate
+ stop
+
+{- Merges from a branch into the current branch. -}
+mergeFrom :: Git.Ref -> Annex Bool
+mergeFrom branch = do
+ showOutput
+ ifM isDirect
+ ( maybe go godirect =<< inRepo Git.Branch.current
+ , go
+ )
+ where
+ go = runmerge $ inRepo $ Git.Merge.mergeNonInteractive branch
+ godirect currbranch = do
+ old <- inRepo $ Git.Ref.sha currbranch
+ d <- fromRepo gitAnnexMergeDir
+ r <- runmerge $ inRepo $ mergeDirect d branch
+ new <- inRepo $ Git.Ref.sha currbranch
+ case (old, new) of
+ (Just oldsha, Just newsha) ->
+ mergeDirectCleanup d oldsha newsha
+ _ -> noop
+ return r
+ runmerge a = ifM a
+ ( return True
+ , resolveMerge
+ )
+
+{- Resolves a conflicted merge. It's important that any conflicts be
+ - resolved in a way that itself avoids later merge conflicts, since
+ - multiple repositories may be doing this concurrently.
+ -
+ - Only annexed files are resolved; other files are left for the user to
+ - handle.
+ -
+ - This uses the Keys pointed to by the files to construct new
+ - filenames. So when both sides modified file foo,
+ - it will be deleted, and replaced with files foo.variant-A and
+ - foo.variant-B.
+ -
+ - On the other hand, when one side deleted foo, and the other modified it,
+ - it will be deleted, and the modified version stored as file
+ - foo.variant-A (or B).
+ -
+ - It's also possible that one side has foo as an annexed file, and
+ - the other as a directory or non-annexed file. The annexed file
+ - is renamed to resolve the merge, and the other object is preserved as-is.
+ -}
+resolveMerge :: Annex Bool
+resolveMerge = do
+ top <- fromRepo Git.repoPath
+ (fs, cleanup) <- inRepo (LsFiles.unmerged [top])
+ mergedfs <- catMaybes <$> mapM resolveMerge' fs
+ let merged = not (null mergedfs)
+ void $ liftIO cleanup
+
+ (deleted, cleanup2) <- inRepo (LsFiles.deleted [top])
+ unless (null deleted) $
+ Annex.Queue.addCommand "rm" [Params "--quiet -f --"] deleted
+ void $ liftIO cleanup2
+
+ when merged $ do
+ unlessM isDirect $
+ cleanConflictCruft mergedfs top
+ Annex.Queue.flush
+ void $ inRepo $ Git.Command.runBool
+ [ Param "commit"
+ , Param "-m"
+ , Param "git-annex automatic merge conflict fix"
+ ]
+ showLongNote "Merge conflict was automatically resolved; you may want to examine the result."
+ return merged
+
+resolveMerge' :: LsFiles.Unmerged -> Annex (Maybe FilePath)
+resolveMerge' u
+ | issymlink LsFiles.valUs && issymlink LsFiles.valThem = do
+ kus <- getKey LsFiles.valUs
+ kthem <- getKey LsFiles.valThem
+ case (kus, kthem) of
+ -- Both sides of conflict are annexed files
+ (Just keyUs, Just keyThem) -> do
+ removeoldfile keyUs
+ if keyUs == keyThem
+ then makelink keyUs
+ else do
+ makelink keyUs
+ makelink keyThem
+ return $ Just file
+ -- Our side is annexed, other side is not.
+ (Just keyUs, Nothing) -> do
+ ifM isDirect
+ -- Move newly added non-annexed object
+ -- out of direct mode merge directory.
+ ( do
+ removeoldfile keyUs
+ makelink keyUs
+ d <- fromRepo gitAnnexMergeDir
+ liftIO $ rename (d </> file) file
+ -- cleaup tree after git merge
+ , do
+ unstageoldfile
+ makelink keyUs
+ )
+ return $ Just file
+ -- Our side is not annexed, other side is.
+ (Nothing, Just keyThem) -> do
+ makelink keyThem
+ unstageoldfile
+ return $ Just file
+ -- Neither side is annexed; cannot resolve.
+ (Nothing, Nothing) -> return Nothing
+ | otherwise = return Nothing
+ where
+ file = LsFiles.unmergedFile u
+ issymlink select = select (LsFiles.unmergedBlobType u) `elem` [Just SymlinkBlob, Nothing]
+ makelink key = do
+ let dest = mergeFile file key
+ l <- inRepo $ gitAnnexLink dest key
+ replaceFile dest $ makeAnnexLink l
+ stageSymlink dest =<< hashSymlink l
+ whenM isDirect $
+ toDirect key dest
+ removeoldfile keyUs = do
+ ifM isDirect
+ ( removeDirect keyUs file
+ , liftIO $ nukeFile file
+ )
+ Annex.Queue.addCommand "rm" [Params "--quiet -f --"] [file]
+ unstageoldfile = Annex.Queue.addCommand "rm" [Params "--quiet -f --cached --"] [file]
+ getKey select = case select (LsFiles.unmergedSha u) of
+ Nothing -> return Nothing
+ Just sha -> catKey sha symLinkMode
+
+{- git-merge moves conflicting files away to files
+ - named something like f~HEAD or f~branch, but the
+ - exact name chosen can vary. Once the conflict is resolved,
+ - this cruft can be deleted. To avoid deleting legitimate
+ - files that look like this, only delete files that are
+ - A) not staged in git and B) look like git-annex symlinks.
+ -}
+cleanConflictCruft :: [FilePath] -> FilePath -> Annex ()
+cleanConflictCruft resolvedfs top = do
+ (fs, cleanup) <- inRepo $ LsFiles.notInRepo False [top]
+ mapM_ clean fs
+ void $ liftIO cleanup
+ where
+ clean f
+ | matchesresolved f = whenM (isJust <$> isAnnexLink f) $
+ liftIO $ nukeFile f
+ | otherwise = noop
+ s = S.fromList resolvedfs
+ matchesresolved f = S.member (base f) s
+ base f = reverse $ drop 1 $ dropWhile (/= '~') $ reverse f
+
+{- The filename to use when resolving a conflicted merge of a file,
+ - that points to a key.
+ -
+ - Something derived from the key needs to be included in the filename,
+ - but rather than exposing the whole key to the user, a very weak hash
+ - is used. There is a very real, although still unlikely, chance of
+ - conflicts using this hash.
+ -
+ - In the event that there is a conflict with the filename generated
+ - for some other key, that conflict will itself be handled by the
+ - conflicted merge resolution code. That case is detected, and the full
+ - key is used in the filename.
+ -}
+mergeFile :: FilePath -> Key -> FilePath
+mergeFile file key
+ | doubleconflict = go $ key2file key
+ | otherwise = go $ shortHash $ key2file key
+ where
+ varmarker = ".variant-"
+ doubleconflict = varmarker `isInfixOf` file
+ go v = takeDirectory file
+ </> dropExtension (takeFileName file)
+ ++ varmarker ++ v
+ ++ takeExtension file
+
+shortHash :: String -> String
+shortHash = take 4 . md5s . md5FilePath
+
+changed :: Remote -> Git.Ref -> Annex Bool
+changed remote b = do
+ let r = remoteBranch remote b
+ ifM (inRepo $ Git.Ref.exists r)
+ ( inRepo $ Git.Branch.changed b r
+ , return False
+ )
+
+newer :: Remote -> Git.Ref -> Annex Bool
+newer remote b = do
+ let r = remoteBranch remote b
+ ifM (inRepo $ Git.Ref.exists r)
+ ( inRepo $ Git.Branch.changed r b
+ , return True
+ )
diff --git a/Command/Test.hs b/Command/Test.hs
new file mode 100644
index 000000000..bf15dcf50
--- /dev/null
+++ b/Command/Test.hs
@@ -0,0 +1,24 @@
+{- git-annex command
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Test where
+
+import Command
+
+def :: [Command]
+def = [ dontCheck repoExists $
+ command "test" paramNothing seek SectionPlumbing
+ "run built-in test suite"]
+
+seek :: [CommandSeek]
+seek = [withWords start]
+
+{- We don't actually run the test suite here because of a dependency loop.
+ - The main program notices when the command is test and runs it; this
+ - function is never run if that works. -}
+start :: [String] -> CommandStart
+start _ = error "Cannot specify any additional parameters when running test"
diff --git a/Command/TransferInfo.hs b/Command/TransferInfo.hs
new file mode 100644
index 000000000..93f6c7077
--- /dev/null
+++ b/Command/TransferInfo.hs
@@ -0,0 +1,64 @@
+{- git-annex command
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.TransferInfo where
+
+import Common.Annex
+import Command
+import Annex.Content
+import Logs.Transfer
+import Types.Key
+import qualified Fields
+import Utility.Metered
+
+def :: [Command]
+def = [noCommit $ command "transferinfo" paramKey seek SectionPlumbing
+ "updates sender on number of bytes of content received"]
+
+seek :: [CommandSeek]
+seek = [withWords start]
+
+{- Security:
+ -
+ - The transfer info file contains the user-supplied key, but
+ - the built-in guards prevent slashes in it from showing up in the filename.
+ - It also contains the UUID of the remote. But slashes are also filtered
+ - out of that when generating the filename.
+ -
+ - Checks that the key being transferred is inAnnex, to prevent
+ - malicious spamming of bogus keys. Does not check that a transfer
+ - of the key is actually in progress, because this could be started
+ - concurrently with sendkey, and win the race.
+ -}
+start :: [String] -> CommandStart
+start (k:[]) = do
+ case file2key k of
+ Nothing -> error "bad key"
+ (Just key) -> whenM (inAnnex key) $ do
+ file <- Fields.getField Fields.associatedFile
+ u <- maybe (error "missing remoteuuid") toUUID
+ <$> Fields.getField Fields.remoteUUID
+ let t = Transfer
+ { transferDirection = Upload
+ , transferUUID = u
+ , transferKey = key
+ }
+ info <- liftIO $ startTransferInfo file
+ (update, tfile, _) <- mkProgressUpdater t info
+ liftIO $ mapM_ void
+ [ tryIO $ forever $ do
+ bytes <- readUpdate
+ maybe (error "transferinfo protocol error")
+ (update . toBytesProcessed) bytes
+ , tryIO $ removeFile tfile
+ , exitSuccess
+ ]
+ stop
+start _ = error "wrong number of parameters"
+
+readUpdate :: IO (Maybe Integer)
+readUpdate = readish <$> getLine
diff --git a/Command/TransferKey.hs b/Command/TransferKey.hs
new file mode 100644
index 000000000..5bb53d98d
--- /dev/null
+++ b/Command/TransferKey.hs
@@ -0,0 +1,59 @@
+{- git-annex command, used internally by old versions of assistant;
+ - kept around for now so running daemons don't break when upgraded
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.TransferKey where
+
+import Common.Annex
+import Command
+import Annex.Content
+import Logs.Location
+import Logs.Transfer
+import qualified Remote
+import Types.Remote
+import GitAnnex.Options
+import qualified Option
+
+def :: [Command]
+def = [withOptions transferKeyOptions $
+ noCommit $ command "transferkey" paramKey seek SectionPlumbing
+ "transfers a key from or to a remote"]
+
+transferKeyOptions :: [Option]
+transferKeyOptions = fileOption : fromToOptions
+
+fileOption :: Option
+fileOption = Option.field [] "file" paramFile "the associated file"
+
+seek :: [CommandSeek]
+seek = [withField toOption Remote.byNameWithUUID $ \to ->
+ withField fromOption Remote.byNameWithUUID $ \from ->
+ withField fileOption return $ \file ->
+ withKeys $ start to from file]
+
+start :: Maybe Remote -> Maybe Remote -> AssociatedFile -> Key -> CommandStart
+start to from file key =
+ case (from, to) of
+ (Nothing, Just dest) -> next $ toPerform dest key file
+ (Just src, Nothing) -> next $ fromPerform src key file
+ _ -> error "specify either --from or --to"
+
+toPerform :: Remote -> Key -> AssociatedFile -> CommandPerform
+toPerform remote key file = go $
+ upload (uuid remote) key file forwardRetry $ \p -> do
+ ok <- Remote.storeKey remote key file p
+ when ok $
+ Remote.logStatus remote key InfoPresent
+ return ok
+
+fromPerform :: Remote -> Key -> AssociatedFile -> CommandPerform
+fromPerform remote key file = go $
+ download (uuid remote) key file forwardRetry $ \p ->
+ getViaTmp key $ \t -> Remote.retrieveKeyFile remote key file t p
+
+go :: Annex Bool -> CommandPerform
+go a = a >>= liftIO . exitBool
diff --git a/Command/TransferKeys.hs b/Command/TransferKeys.hs
new file mode 100644
index 000000000..5ac9454aa
--- /dev/null
+++ b/Command/TransferKeys.hs
@@ -0,0 +1,142 @@
+{- git-annex command, used internally by assistant
+ -
+ - Copyright 2012, 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE TypeSynonymInstances, FlexibleInstances #-}
+
+module Command.TransferKeys where
+
+import Common.Annex
+import Command
+import Annex.Content
+import Logs.Location
+import Logs.Transfer
+import qualified Remote
+import Types.Key
+import qualified Option
+
+data TransferRequest = TransferRequest Direction Remote Key AssociatedFile
+
+def :: [Command]
+def = [withOptions options $
+ command "transferkeys" paramNothing seek
+ SectionPlumbing "transfers keys"]
+
+options :: [Option]
+options = [readFdOption, writeFdOption]
+
+readFdOption :: Option
+readFdOption = Option.field [] "readfd" paramNumber "read from this fd"
+
+writeFdOption :: Option
+writeFdOption = Option.field [] "writefd" paramNumber "write to this fd"
+
+seek :: [CommandSeek]
+seek = [withField readFdOption convertFd $ \readh ->
+ withField writeFdOption convertFd $ \writeh ->
+ withNothing $ start readh writeh]
+
+convertFd :: Maybe String -> Annex (Maybe Handle)
+convertFd Nothing = return Nothing
+convertFd (Just s) = liftIO $
+ case readish s of
+ Nothing -> error "bad fd"
+ Just fd -> Just <$> fdToHandle fd
+
+start :: Maybe Handle -> Maybe Handle -> CommandStart
+start readh writeh = do
+ runRequests (fromMaybe stdin readh) (fromMaybe stdout writeh) runner
+ stop
+ where
+ runner (TransferRequest direction remote key file)
+ | direction == Upload =
+ upload (Remote.uuid remote) key file forwardRetry $ \p -> do
+ ok <- Remote.storeKey remote key file p
+ when ok $
+ Remote.logStatus remote key InfoPresent
+ return ok
+ | otherwise = download (Remote.uuid remote) key file forwardRetry $ \p ->
+ getViaTmp key $ \t -> Remote.retrieveKeyFile remote key file t p
+
+runRequests
+ :: Handle
+ -> Handle
+ -> (TransferRequest -> Annex Bool)
+ -> Annex ()
+runRequests readh writeh a = do
+ liftIO $ do
+ hSetBuffering readh NoBuffering
+ fileEncoding readh
+ fileEncoding writeh
+ go =<< readrequests
+ where
+ go (d:u:k:f:rest) = do
+ case (deserialize d, deserialize u, deserialize k, deserialize f) of
+ (Just direction, Just uuid, Just key, Just file) -> do
+ mremote <- Remote.remoteFromUUID uuid
+ case mremote of
+ Nothing -> sendresult False
+ Just remote -> sendresult =<< a
+ (TransferRequest direction remote key file)
+ _ -> sendresult False
+ go rest
+ go [] = noop
+ go [""] = noop
+ go v = error $ "transferkeys protocol error: " ++ show v
+
+ readrequests = liftIO $ split fieldSep <$> hGetContents readh
+ sendresult b = liftIO $ do
+ hPutStrLn writeh $ serialize b
+ hFlush writeh
+
+sendRequest :: Transfer -> AssociatedFile -> Handle -> IO ()
+sendRequest t f h = do
+ hPutStr h $ intercalate fieldSep
+ [ serialize (transferDirection t)
+ , serialize (transferUUID t)
+ , serialize (transferKey t)
+ , serialize f
+ , "" -- adds a trailing null
+ ]
+ hFlush h
+
+readResponse :: Handle -> IO Bool
+readResponse h = fromMaybe False . deserialize <$> hGetLine h
+
+fieldSep :: String
+fieldSep = "\0"
+
+class Serialized a where
+ serialize :: a -> String
+ deserialize :: String -> Maybe a
+
+instance Serialized Bool where
+ serialize True = "1"
+ serialize False = "0"
+ deserialize "1" = Just True
+ deserialize "0" = Just False
+ deserialize _ = Nothing
+
+instance Serialized Direction where
+ serialize Upload = "u"
+ serialize Download = "d"
+ deserialize "u" = Just Upload
+ deserialize "d" = Just Download
+ deserialize _ = Nothing
+
+instance Serialized AssociatedFile where
+ serialize (Just f) = f
+ serialize Nothing = ""
+ deserialize "" = Just Nothing
+ deserialize f = Just $ Just f
+
+instance Serialized UUID where
+ serialize = fromUUID
+ deserialize = Just . toUUID
+
+instance Serialized Key where
+ serialize = key2file
+ deserialize = file2key
diff --git a/Command/Trust.hs b/Command/Trust.hs
new file mode 100644
index 000000000..26993ef77
--- /dev/null
+++ b/Command/Trust.hs
@@ -0,0 +1,32 @@
+{- git-annex command
+ -
+ - Copyright 2010 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Trust where
+
+import Common.Annex
+import Command
+import qualified Remote
+import Logs.Trust
+
+def :: [Command]
+def = [command "trust" (paramRepeating paramRemote) seek
+ SectionSetup "trust a repository"]
+
+seek :: [CommandSeek]
+seek = [withWords start]
+
+start :: [String] -> CommandStart
+start ws = do
+ let name = unwords ws
+ showStart "trust" name
+ u <- Remote.nameToUUID name
+ next $ perform u
+
+perform :: UUID -> CommandPerform
+perform uuid = do
+ trustSet uuid Trusted
+ next $ return True
diff --git a/Command/Unannex.hs b/Command/Unannex.hs
new file mode 100644
index 000000000..5e3c4279a
--- /dev/null
+++ b/Command/Unannex.hs
@@ -0,0 +1,98 @@
+{- git-annex command
+ -
+ - Copyright 2010-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Command.Unannex where
+
+import Common.Annex
+import Command
+import Config
+import qualified Annex
+import Annex.Content
+import Annex.Content.Direct
+import qualified Git.Command
+import qualified Git.LsFiles as LsFiles
+import Utility.CopyFile
+
+def :: [Command]
+def = [command "unannex" paramPaths seek SectionUtility
+ "undo accidential add command"]
+
+seek :: [CommandSeek]
+seek = [withFilesInGit $ whenAnnexed start]
+
+start :: FilePath -> (Key, Backend) -> CommandStart
+start file (key, _) = stopUnless (inAnnex key) $ do
+ showStart "unannex" file
+ next $ ifM isDirect
+ ( performDirect file key
+ , performIndirect file key)
+
+performIndirect :: FilePath -> Key -> CommandPerform
+performIndirect file key = do
+ liftIO $ removeFile file
+
+ -- git rm deletes empty directory without --cached
+ inRepo $ Git.Command.run [Params "rm --cached --force --quiet --", File file]
+
+ -- If the file was already committed, it is now staged for removal.
+ -- Commit that removal now, to avoid later confusing the
+ -- pre-commit hook, if this file is later added back to
+ -- git as a normal non-annexed file, to thinking that the
+ -- file has been unlocked and needs to be re-annexed.
+ (s, reap) <- inRepo $ LsFiles.staged [file]
+ unless (null s) $
+ inRepo $ Git.Command.run
+ [ Param "commit"
+ , Param "-q"
+ , Param "--no-verify"
+ , Param "-m", Param "content removed from git annex"
+ , Param "--", File file
+ ]
+ void $ liftIO reap
+
+ next $ cleanupIndirect file key
+
+cleanupIndirect :: FilePath -> Key -> CommandCleanup
+cleanupIndirect file key = do
+ src <- calcRepo $ gitAnnexLocation key
+ ifM (Annex.getState Annex.fast)
+ ( hardlinkfrom src
+ , copyfrom src
+ )
+ where
+ copyfrom src =
+ thawContent file `after` liftIO (copyFileExternal src file)
+ hardlinkfrom src =
+#ifndef mingw32_HOST_OS
+ -- creating a hard link could fall; fall back to copying
+ ifM (liftIO $ catchBoolIO $ createLink src file >> return True)
+ ( return True
+ , copyfrom src
+ )
+#else
+ copyfrom src
+#endif
+
+performDirect :: FilePath -> Key -> CommandPerform
+performDirect file key = do
+ -- --force is needed when the file is not committed
+ inRepo $ Git.Command.run [Params "rm --cached --force --quiet --", File file]
+ next $ cleanupDirect file key
+
+{- The direct mode file is not touched during unannex, so the content
+ - is already where it needs to be, so this does not need to do anything
+ - except remove it from the associated file map (which also updates
+ - the location log if this was the last copy), and, if this was the last
+ - associated file, remove the inode cache. -}
+cleanupDirect :: FilePath -> Key -> CommandCleanup
+cleanupDirect file key = do
+ fs <- removeAssociatedFile key file
+ when (null fs) $
+ removeInodeCache key
+ return True
diff --git a/Command/Ungroup.hs b/Command/Ungroup.hs
new file mode 100644
index 000000000..a6557f21d
--- /dev/null
+++ b/Command/Ungroup.hs
@@ -0,0 +1,35 @@
+{- git-annex command
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Ungroup where
+
+import Common.Annex
+import Command
+import qualified Remote
+import Logs.Group
+import Types.Group
+
+import qualified Data.Set as S
+
+def :: [Command]
+def = [command "ungroup" (paramPair paramRemote paramDesc) seek
+ SectionSetup "remove a repository from a group"]
+
+seek :: [CommandSeek]
+seek = [withWords start]
+
+start :: [String] -> CommandStart
+start (name:g:[]) = do
+ showStart "ungroup" name
+ u <- Remote.nameToUUID name
+ next $ perform u g
+start _ = error "Specify a repository and a group."
+
+perform :: UUID -> Group -> CommandPerform
+perform uuid g = do
+ groupChange uuid (S.delete g)
+ next $ return True
diff --git a/Command/Uninit.hs b/Command/Uninit.hs
new file mode 100644
index 000000000..3fbe6758a
--- /dev/null
+++ b/Command/Uninit.hs
@@ -0,0 +1,100 @@
+{- git-annex command
+ -
+ - Copyright 2010 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Uninit where
+
+import Common.Annex
+import Command
+import qualified Git
+import qualified Git.Command
+import qualified Command.Unannex
+import Init
+import qualified Annex.Branch
+import Annex.Content
+
+def :: [Command]
+def = [addCheck check $ command "uninit" paramPaths seek
+ SectionUtility "de-initialize git-annex and clean out repository"]
+
+check :: Annex ()
+check = do
+ b <- current_branch
+ when (b == Annex.Branch.name) $ error $
+ "cannot uninit when the " ++ show b ++ " branch is checked out"
+ top <- fromRepo Git.repoPath
+ cwd <- liftIO getCurrentDirectory
+ whenM ((/=) <$> liftIO (absPath top) <*> liftIO (absPath cwd)) $
+ error "can only run uninit from the top of the git repository"
+ where
+ current_branch = Git.Ref . Prelude.head . lines <$> revhead
+ revhead = inRepo $ Git.Command.pipeReadStrict
+ [Params "rev-parse --abbrev-ref HEAD"]
+
+seek :: [CommandSeek]
+seek =
+ [ withFilesNotInGit $ whenAnnexed startCheckIncomplete
+ , withFilesInGit $ whenAnnexed Command.Unannex.start
+ , withNothing start
+ ]
+
+{- git annex symlinks that are not checked into git could be left by an
+ - interrupted add. -}
+startCheckIncomplete :: FilePath -> (Key, Backend) -> CommandStart
+startCheckIncomplete file _ = error $ unlines
+ [ file ++ " points to annexed content, but is not checked into git."
+ , "Perhaps this was left behind by an interrupted git annex add?"
+ , "Not continuing with uninit; either delete or git annex add the file and retry."
+ ]
+
+start :: CommandStart
+start = next $ next $ do
+ annexdir <- fromRepo gitAnnexDir
+ annexobjectdir <- fromRepo gitAnnexObjectDir
+ leftovers <- removeUnannexed =<< getKeysPresent
+ if null leftovers
+ then liftIO $ removeDirectoryRecursive annexdir
+ else error $ unlines
+ [ "Not fully uninitialized"
+ , "Some annexed data is still left in " ++ annexobjectdir
+ , "This may include deleted files, or old versions of modified files."
+ , ""
+ , "If you don't care about preserving the data, just delete the"
+ , "directory."
+ , ""
+ , "Or, you can move it to another location, in case it turns out"
+ , "something in there is important."
+ , ""
+ , "Or, you can run `git annex unused` followed by `git annex dropunused`"
+ , "to remove data that is not used by any tag or branch, which might"
+ , "take care of all the data."
+ , ""
+ , "Then run `git annex uninit` again to finish."
+ ]
+ uninitialize
+ -- avoid normal shutdown
+ saveState False
+ inRepo $ Git.Command.run
+ [Param "branch", Param "-D", Param $ show Annex.Branch.name]
+ liftIO exitSuccess
+
+{- Keys that were moved out of the annex have a hard link still in the
+ - annex, with > 1 link count, and those can be removed.
+ -
+ - Returns keys that cannot be removed. -}
+removeUnannexed :: [Key] -> Annex [Key]
+removeUnannexed = go []
+ where
+ go c [] = return c
+ go c (k:ks) = ifM (inAnnexCheck k $ liftIO . enoughlinks)
+ ( do
+ removeAnnex k
+ go c ks
+ , go (k:c) ks
+ )
+ enoughlinks f = catchBoolIO $ do
+ s <- getFileStatus f
+ return $ linkCount s > 1
diff --git a/Command/Unlock.hs b/Command/Unlock.hs
new file mode 100644
index 000000000..1eba26ff7
--- /dev/null
+++ b/Command/Unlock.hs
@@ -0,0 +1,50 @@
+{- git-annex command
+ -
+ - Copyright 2010 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Unlock where
+
+import Common.Annex
+import Command
+import Annex.Content
+import Utility.CopyFile
+
+def :: [Command]
+def =
+ [ c "unlock" "unlock files for modification"
+ , c "edit" "same as unlock"
+ ]
+ where
+ c n = notDirect . command n paramPaths seek SectionCommon
+
+seek :: [CommandSeek]
+seek = [withFilesInGit $ whenAnnexed start]
+
+{- The unlock subcommand replaces the symlink with a copy of the file's
+ - content. -}
+start :: FilePath -> (Key, Backend) -> CommandStart
+start file (key, _) = do
+ showStart "unlock" file
+ next $ perform file key
+
+perform :: FilePath -> Key -> CommandPerform
+perform dest key = do
+ unlessM (inAnnex key) $ error "content not present"
+ unlessM (checkDiskSpace Nothing key 0) $ error "cannot unlock"
+
+ src <- calcRepo $ gitAnnexLocation key
+ tmpdest <- fromRepo $ gitAnnexTmpLocation key
+ liftIO $ createDirectoryIfMissing True (parentDir tmpdest)
+ showAction "copying"
+ ifM (liftIO $ copyFileExternal src tmpdest)
+ ( do
+ liftIO $ do
+ removeFile dest
+ moveFile tmpdest dest
+ thawContent dest
+ next $ return True
+ , error "copy failed!"
+ )
diff --git a/Command/Untrust.hs b/Command/Untrust.hs
new file mode 100644
index 000000000..f18637838
--- /dev/null
+++ b/Command/Untrust.hs
@@ -0,0 +1,32 @@
+{- git-annex command
+ -
+ - Copyright 2010 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Untrust where
+
+import Common.Annex
+import Command
+import qualified Remote
+import Logs.Trust
+
+def :: [Command]
+def = [command "untrust" (paramRepeating paramRemote) seek
+ SectionSetup "do not trust a repository"]
+
+seek :: [CommandSeek]
+seek = [withWords start]
+
+start :: [String] -> CommandStart
+start ws = do
+ let name = unwords ws
+ showStart "untrust" name
+ u <- Remote.nameToUUID name
+ next $ perform u
+
+perform :: UUID -> CommandPerform
+perform uuid = do
+ trustSet uuid UnTrusted
+ next $ return True
diff --git a/Command/Unused.hs b/Command/Unused.hs
new file mode 100644
index 000000000..1e5cdc163
--- /dev/null
+++ b/Command/Unused.hs
@@ -0,0 +1,369 @@
+{- git-annex command
+ -
+ - Copyright 2010-2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE BangPatterns #-}
+
+module Command.Unused where
+
+import qualified Data.Set as S
+import qualified Data.ByteString.Lazy as L
+import Data.BloomFilter
+import Data.BloomFilter.Easy
+import Data.BloomFilter.Hash
+import Control.Monad.ST
+import qualified Data.Map as M
+
+import Common.Annex
+import Command
+import Logs.Unused
+import Annex.Content
+import Logs.Location
+import Logs.Transfer
+import qualified Annex
+import qualified Git
+import qualified Git.Command
+import qualified Git.Ref
+import qualified Git.Branch
+import qualified Git.LsFiles as LsFiles
+import qualified Git.DiffTree as DiffTree
+import qualified Backend
+import qualified Remote
+import qualified Annex.Branch
+import qualified Option
+import Annex.CatFile
+import Types.Key
+import Git.FilePath
+
+def :: [Command]
+def = [withOptions [fromOption] $ command "unused" paramNothing seek
+ SectionMaintenance "look for unused file content"]
+
+fromOption :: Option
+fromOption = Option.field ['f'] "from" paramRemote "remote to check for unused content"
+
+seek :: [CommandSeek]
+seek = [withNothing start]
+
+{- Finds unused content in the annex. -}
+start :: CommandStart
+start = do
+ from <- Annex.getField $ Option.name fromOption
+ let (name, action) = case from of
+ Nothing -> (".", checkUnused)
+ Just "." -> (".", checkUnused)
+ Just "here" -> (".", checkUnused)
+ Just n -> (n, checkRemoteUnused n)
+ showStart "unused" name
+ next action
+
+checkUnused :: CommandPerform
+checkUnused = chain 0
+ [ check "" unusedMsg $ findunused =<< Annex.getState Annex.fast
+ , check "bad" staleBadMsg $ staleKeysPrune gitAnnexBadDir False
+ , check "tmp" staleTmpMsg $ staleKeysPrune gitAnnexTmpDir True
+ ]
+ where
+ findunused True = do
+ showNote "fast mode enabled; only finding stale files"
+ return []
+ findunused False = do
+ showAction "checking for unused data"
+ excludeReferenced =<< getKeysPresent
+ chain _ [] = next $ return True
+ chain v (a:as) = do
+ v' <- a v
+ chain v' as
+
+checkRemoteUnused :: String -> CommandPerform
+checkRemoteUnused name = go =<< fromJust <$> Remote.byNameWithUUID (Just name)
+ where
+ go r = do
+ showAction "checking for unused data"
+ _ <- check "" (remoteUnusedMsg r) (remoteunused r) 0
+ next $ return True
+ remoteunused r = excludeReferenced <=< loggedKeysFor $ Remote.uuid r
+
+check :: FilePath -> ([(Int, Key)] -> String) -> Annex [Key] -> Int -> Annex Int
+check file msg a c = do
+ l <- a
+ let unusedlist = number c l
+ unless (null l) $ showLongNote $ msg unusedlist
+ writeUnusedLog file unusedlist
+ return $ c + length l
+
+number :: Int -> [a] -> [(Int, a)]
+number _ [] = []
+number n (x:xs) = (n+1, x) : number (n+1) xs
+
+table :: [(Int, Key)] -> [String]
+table l = " NUMBER KEY" : map cols l
+ where
+ cols (n,k) = " " ++ pad 6 (show n) ++ " " ++ key2file k
+ pad n s = s ++ replicate (n - length s) ' '
+
+staleTmpMsg :: [(Int, Key)] -> String
+staleTmpMsg t = unlines $
+ ["Some partially transferred data exists in temporary files:"]
+ ++ table t ++ [dropMsg Nothing]
+
+staleBadMsg :: [(Int, Key)] -> String
+staleBadMsg t = unlines $
+ ["Some corrupted files have been preserved by fsck, just in case:"]
+ ++ table t ++ [dropMsg Nothing]
+
+unusedMsg :: [(Int, Key)] -> String
+unusedMsg u = unusedMsg' u
+ ["Some annexed data is no longer used by any files:"]
+ [dropMsg Nothing]
+unusedMsg' :: [(Int, Key)] -> [String] -> [String] -> String
+unusedMsg' u header trailer = unlines $
+ header ++
+ table u ++
+ ["(To see where data was previously used, try: git log --stat -S'KEY')"] ++
+ trailer
+
+remoteUnusedMsg :: Remote -> [(Int, Key)] -> String
+remoteUnusedMsg r u = unusedMsg' u
+ ["Some annexed data on " ++ name ++ " is not used by any files:"]
+ [dropMsg $ Just r]
+ where
+ name = Remote.name r
+
+dropMsg :: Maybe Remote -> String
+dropMsg Nothing = dropMsg' ""
+dropMsg (Just r) = dropMsg' $ " --from " ++ Remote.name r
+dropMsg' :: String -> String
+dropMsg' s = "\nTo remove unwanted data: git-annex dropunused" ++ s ++ " NUMBER\n"
+
+{- Finds keys in the list that are not referenced in the git repository.
+ -
+ - Strategy:
+ -
+ - * Build a bloom filter of all keys referenced by symlinks. This
+ - is the fastest one to build and will filter out most keys.
+ - * If keys remain, build a second bloom filter of keys referenced by
+ - all branches.
+ - * The list is streamed through these bloom filters lazily, so both will
+ - exist at the same time. This means that twice the memory is used,
+ - but they're relatively small, so the added complexity of using a
+ - mutable bloom filter does not seem worthwhile.
+ - * Generating the second bloom filter can take quite a while, since
+ - it needs enumerating all keys in all git branches. But, the common
+ - case, if the second filter is needed, is for some keys to be globally
+ - unused, and in that case, no short-circuit is possible.
+ - Short-circuiting if the first filter filters all the keys handles the
+ - other common case.
+ -}
+excludeReferenced :: [Key] -> Annex [Key]
+excludeReferenced ks = runfilter firstlevel ks >>= runfilter secondlevel
+ where
+ runfilter _ [] = return [] -- optimisation
+ runfilter a l = bloomFilter show l <$> genBloomFilter show a
+ firstlevel = withKeysReferencedM
+ secondlevel = withKeysReferencedInGit
+
+{- Finds items in the first, smaller list, that are not
+ - present in the second, larger list.
+ -
+ - Constructing a single set, of the list that tends to be
+ - smaller, appears more efficient in both memory and CPU
+ - than constructing and taking the S.difference of two sets. -}
+exclude :: Ord a => [a] -> [a] -> [a]
+exclude [] _ = [] -- optimisation
+exclude smaller larger = S.toList $ remove larger $ S.fromList smaller
+ where
+ remove a b = foldl (flip S.delete) b a
+
+{- A bloom filter capable of holding half a million keys with a
+ - false positive rate of 1 in 1000 uses around 8 mb of memory,
+ - so will easily fit on even my lowest memory systems.
+ -}
+bloomCapacity :: Annex Int
+bloomCapacity = fromMaybe 500000 . annexBloomCapacity <$> Annex.getGitConfig
+bloomAccuracy :: Annex Int
+bloomAccuracy = fromMaybe 1000 . annexBloomAccuracy <$> Annex.getGitConfig
+bloomBitsHashes :: Annex (Int, Int)
+bloomBitsHashes = do
+ capacity <- bloomCapacity
+ accuracy <- bloomAccuracy
+ return $ suggestSizing capacity (1/ fromIntegral accuracy)
+
+{- Creates a bloom filter, and runs an action, such as withKeysReferenced,
+ - to populate it.
+ -
+ - The action is passed a callback that it can use to feed values into the
+ - bloom filter.
+ -
+ - Once the action completes, the mutable filter is frozen
+ - for later use.
+ -}
+genBloomFilter :: Hashable t => (v -> t) -> ((v -> Annex ()) -> Annex b) -> Annex (Bloom t)
+genBloomFilter convert populate = do
+ (numbits, numhashes) <- bloomBitsHashes
+ bloom <- lift $ newMB (cheapHashes numhashes) numbits
+ _ <- populate $ \v -> lift $ insertMB bloom (convert v)
+ lift $ unsafeFreezeMB bloom
+ where
+ lift = liftIO . stToIO
+
+bloomFilter :: Hashable t => (v -> t) -> [v] -> Bloom t -> [v]
+bloomFilter convert l bloom = filter (\k -> convert k `notElemB` bloom) l
+
+{- Given an initial value, folds it with each key referenced by
+ - symlinks in the git repo. -}
+withKeysReferenced :: v -> (Key -> v -> v) -> Annex v
+withKeysReferenced initial a = withKeysReferenced' Nothing initial folda
+ where
+ folda k _ v = return $ a k v
+
+{- Runs an action on each referenced key in the git repo. -}
+withKeysReferencedM :: (Key -> Annex ()) -> Annex ()
+withKeysReferencedM a = withKeysReferenced' Nothing () calla
+ where
+ calla k _ _ = a k
+
+{- Folds an action over keys and files referenced in a particular directory. -}
+withKeysFilesReferencedIn :: FilePath -> v -> (Key -> FilePath -> v -> Annex v) -> Annex v
+withKeysFilesReferencedIn = withKeysReferenced' . Just
+
+withKeysReferenced' :: Maybe FilePath -> v -> (Key -> FilePath -> v -> Annex v) -> Annex v
+withKeysReferenced' mdir initial a = do
+ (files, clean) <- getfiles
+ r <- go initial files
+ liftIO $ void clean
+ return r
+ where
+ getfiles = case mdir of
+ Nothing -> ifM isBareRepo
+ ( return ([], return True)
+ , do
+ top <- fromRepo Git.repoPath
+ inRepo $ LsFiles.allFiles [top]
+ )
+ Just dir -> inRepo $ LsFiles.inRepo [dir]
+ go v [] = return v
+ go v (f:fs) = do
+ x <- Backend.lookupFile f
+ case x of
+ Nothing -> go v fs
+ Just (k, _) -> do
+ !v' <- a k f v
+ go v' fs
+
+withKeysReferencedInGit :: (Key -> Annex ()) -> Annex ()
+withKeysReferencedInGit a = do
+ current <- inRepo Git.Branch.currentUnsafe
+ shaHead <- maybe (return Nothing) (inRepo . Git.Ref.sha) current
+ showref >>= mapM_ (withKeysReferencedInGitRef a) .
+ relevantrefs (shaHead, current)
+ where
+ showref = inRepo $ Git.Command.pipeReadStrict [Param "show-ref"]
+ relevantrefs headRef = addHead headRef .
+ filter ourbranches .
+ map (separate (== ' ')) .
+ lines
+ nubRefs = map (Git.Ref . snd) . nubBy (\(x, _) (y, _) -> x == y)
+ ourbranchend = '/' : show Annex.Branch.name
+ ourbranches (_, b) = not (ourbranchend `isSuffixOf` b)
+ && not ("refs/synced/" `isPrefixOf` b)
+ addHead headRef refs = case headRef of
+ -- if HEAD diverges from all branches (except the branch it
+ -- points to), run the actions on staged keys (and keys
+ -- that are only present in the work tree if the repo is
+ -- non bare)
+ (Just (Git.Ref x), Just (Git.Ref b))
+ | all (\(x',b') -> x /= x' || b == b') refs ->
+ Git.Ref.headRef
+ : nubRefs (filter ((/= x) . fst) refs)
+ _ -> nubRefs refs
+
+{- Runs an action on keys referenced in the given Git reference which
+ - differ from those referenced in the index. -}
+withKeysReferencedInGitRef :: (Key -> Annex ()) -> Git.Ref -> Annex ()
+withKeysReferencedInGitRef a ref = do
+ showAction $ "checking " ++ Git.Ref.describe ref
+ bare <- isBareRepo
+ (ts,clean) <- inRepo $ if bare
+ then DiffTree.diffIndex ref
+ else DiffTree.diffWorkTree ref
+ let lookAtWorkingTree = not bare && ref == Git.Ref.headRef
+ forM_ ts $ tKey lookAtWorkingTree >=> maybe noop a
+ liftIO $ void clean
+ where
+ tKey True = fmap fst <$$> Backend.lookupFile . getTopFilePath . DiffTree.file
+ tKey False = fileKey . takeFileName . encodeW8 . L.unpack <$$>
+ catFile ref . getTopFilePath . DiffTree.file
+
+{- Looks in the specified directory for bad/tmp keys, and returns a list
+ - of those that might still have value, or might be stale and removable.
+ -
+ - Also, stale keys that can be proven to have no value are deleted.
+ -}
+staleKeysPrune :: (Git.Repo -> FilePath) -> Bool -> Annex [Key]
+staleKeysPrune dirspec nottransferred = do
+ contents <- dirKeys dirspec
+
+ dups <- filterM inAnnex contents
+ let stale = contents `exclude` dups
+
+ dir <- fromRepo dirspec
+ liftIO $ forM_ dups $ \t -> removeFile $ dir </> keyFile t
+
+ if nottransferred
+ then do
+ inprogress <- S.fromList . map (transferKey . fst)
+ <$> getTransfers
+ return $ filter (`S.notMember` inprogress) stale
+ else return stale
+
+data UnusedMaps = UnusedMaps
+ { unusedMap :: UnusedMap
+ , unusedBadMap :: UnusedMap
+ , unusedTmpMap :: UnusedMap
+ }
+
+{- Read unused logs once, and pass the maps to each start action. -}
+withUnusedMaps :: (UnusedMaps -> Int -> CommandStart) -> CommandSeek
+withUnusedMaps a params = do
+ unused <- readUnusedLog ""
+ unusedbad <- readUnusedLog "bad"
+ unusedtmp <- readUnusedLog "tmp"
+ let m = unused `M.union` unusedbad `M.union` unusedtmp
+ return $ map (a $ UnusedMaps unused unusedbad unusedtmp) $
+ concatMap (unusedSpec m) params
+
+unusedSpec :: UnusedMap -> String -> [Int]
+unusedSpec m spec
+ | spec == "all" = [fst (M.findMin m)..fst (M.findMax m)]
+ | "-" `isInfixOf` spec = range $ separate (== '-') spec
+ | otherwise = maybe badspec (: []) (readish spec)
+ where
+ range (a, b) = case (readish a, readish b) of
+ (Just x, Just y) -> [x..y]
+ _ -> badspec
+ badspec = error $ "Expected number or range, not \"" ++ spec ++ "\""
+
+{- Start action for unused content. Finds the number in the maps, and
+ - calls either of 3 actions, depending on the type of unused file. -}
+startUnused :: String
+ -> (Key -> CommandPerform)
+ -> (Key -> CommandPerform)
+ -> (Key -> CommandPerform)
+ -> UnusedMaps -> Int -> CommandStart
+startUnused message unused badunused tmpunused maps n = search
+ [ (unusedMap maps, unused)
+ , (unusedBadMap maps, badunused)
+ , (unusedTmpMap maps, tmpunused)
+ ]
+ where
+ search [] = error $ show n ++ " not valid (run git annex unused for list)"
+ search ((m, a):rest) =
+ case M.lookup n m of
+ Nothing -> search rest
+ Just key -> do
+ showStart message (show n)
+ next $ a key
diff --git a/Command/Upgrade.hs b/Command/Upgrade.hs
new file mode 100644
index 000000000..c6c0f7a8c
--- /dev/null
+++ b/Command/Upgrade.hs
@@ -0,0 +1,28 @@
+{- git-annex command
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Upgrade where
+
+import Common.Annex
+import Command
+import Upgrade
+import Annex.Version
+import Config
+
+def :: [Command]
+def = [dontCheck repoExists $ -- because an old version may not seem to exist
+ command "upgrade" paramNothing seek
+ SectionMaintenance "upgrade repository layout"]
+
+seek :: [CommandSeek]
+seek = [withNothing start]
+
+start :: CommandStart
+start = do
+ showStart "upgrade" "."
+ r <- upgrade False
+ next $ next $ return r
diff --git a/Command/Version.hs b/Command/Version.hs
new file mode 100644
index 000000000..b330d1ff1
--- /dev/null
+++ b/Command/Version.hs
@@ -0,0 +1,48 @@
+{- git-annex command
+ -
+ - Copyright 2010 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Version where
+
+import Common.Annex
+import Command
+import qualified Build.SysConfig as SysConfig
+import Annex.Version
+import BuildFlags
+import qualified Types.Backend as B
+import qualified Types.Remote as R
+import qualified Remote
+import qualified Backend
+
+def :: [Command]
+def = [noCommit $ noRepo showPackageVersion $ dontCheck repoExists $
+ command "version" paramNothing seek SectionQuery "show version info"]
+
+seek :: [CommandSeek]
+seek = [withNothing start]
+
+start :: CommandStart
+start = do
+ v <- getVersion
+ liftIO $ do
+ showPackageVersion
+ info "local repository version" $ fromMaybe "unknown" v
+ info "default repository version" defaultVersion
+ info "supported repository versions" $
+ unwords supportedVersions
+ info "upgrade supported from repository versions" $
+ unwords upgradableVersions
+ stop
+
+showPackageVersion :: IO ()
+showPackageVersion = do
+ info "git-annex version" SysConfig.packageversion
+ info "build flags" $ unwords buildFlags
+ info "key/value backends" $ unwords $ map B.name Backend.list
+ info "remote types" $ unwords $ map R.typename Remote.remoteTypes
+
+info :: String -> String -> IO ()
+info k v = putStrLn $ k ++ ": " ++ v
diff --git a/Command/Vicfg.hs b/Command/Vicfg.hs
new file mode 100644
index 000000000..22c641408
--- /dev/null
+++ b/Command/Vicfg.hs
@@ -0,0 +1,213 @@
+{- git-annex command
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Vicfg where
+
+import qualified Data.Map as M
+import qualified Data.Set as S
+import System.Environment (getEnv)
+import Data.Tuple (swap)
+import Data.Char (isSpace)
+
+import Common.Annex
+import Command
+import Annex.Perms
+import Types.TrustLevel
+import Types.Group
+import Logs.Trust
+import Logs.Group
+import Logs.PreferredContent
+import Logs.Schedule
+import Types.StandardGroups
+import Types.ScheduledActivity
+import Remote
+
+def :: [Command]
+def = [command "vicfg" paramNothing seek
+ SectionSetup "edit git-annex's configuration"]
+
+seek :: [CommandSeek]
+seek = [withNothing start]
+
+start :: CommandStart
+start = do
+ f <- fromRepo gitAnnexTmpCfgFile
+ createAnnexDirectory $ parentDir f
+ cfg <- getCfg
+ descs <- uuidDescriptions
+ liftIO $ writeFile f $ genCfg cfg descs
+ vicfg cfg f
+ stop
+
+vicfg :: Cfg -> FilePath -> Annex ()
+vicfg curcfg f = do
+ vi <- liftIO $ catchDefaultIO "vi" $ getEnv "EDITOR"
+ -- Allow EDITOR to be processed by the shell, so it can contain options.
+ unlessM (liftIO $ boolSystem "sh" [Param "-c", Param $ unwords [vi, shellEscape f]]) $
+ error $ vi ++ " exited nonzero; aborting"
+ r <- parseCfg curcfg <$> liftIO (readFileStrict f)
+ liftIO $ nukeFile f
+ case r of
+ Left s -> do
+ liftIO $ writeFile f s
+ vicfg curcfg f
+ Right newcfg -> setCfg curcfg newcfg
+
+data Cfg = Cfg
+ { cfgTrustMap :: TrustMap
+ , cfgGroupMap :: M.Map UUID (S.Set Group)
+ , cfgPreferredContentMap :: M.Map UUID String
+ , cfgScheduleMap :: M.Map UUID [ScheduledActivity]
+ }
+
+getCfg :: Annex Cfg
+getCfg = Cfg
+ <$> trustMapRaw -- without local trust overrides
+ <*> (groupsByUUID <$> groupMap)
+ <*> preferredContentMapRaw
+ <*> scheduleMap
+
+setCfg :: Cfg -> Cfg -> Annex ()
+setCfg curcfg newcfg = do
+ let (trustchanges, groupchanges, preferredcontentchanges, schedulechanges) = diffCfg curcfg newcfg
+ mapM_ (uncurry trustSet) $ M.toList trustchanges
+ mapM_ (uncurry groupSet) $ M.toList groupchanges
+ mapM_ (uncurry preferredContentSet) $ M.toList preferredcontentchanges
+ mapM_ (uncurry scheduleSet) $ M.toList schedulechanges
+
+diffCfg :: Cfg -> Cfg -> (TrustMap, M.Map UUID (S.Set Group), M.Map UUID String, M.Map UUID [ScheduledActivity])
+diffCfg curcfg newcfg = (diff cfgTrustMap, diff cfgGroupMap, diff cfgPreferredContentMap, diff cfgScheduleMap)
+ where
+ diff f = M.differenceWith (\x y -> if x == y then Nothing else Just x)
+ (f newcfg) (f curcfg)
+
+genCfg :: Cfg -> M.Map UUID String -> String
+genCfg cfg descs = unlines $ concat
+ [intro, trust, groups, preferredcontent, schedule]
+ where
+ intro =
+ [ com "git-annex configuration"
+ , com ""
+ , com "Changes saved to this file will be recorded in the git-annex branch."
+ , com ""
+ , com "Lines in this file have the format:"
+ , com " setting uuid = value"
+ ]
+
+ trust = settings cfgTrustMap
+ [ ""
+ , com "Repository trust configuration"
+ , com "(Valid trust levels: " ++ trustlevels ++ ")"
+ ]
+ (\(t, u) -> line "trust" u $ showTrustLevel t)
+ (\u -> lcom $ line "trust" u $ showTrustLevel SemiTrusted)
+ where
+ trustlevels = unwords $ map showTrustLevel [Trusted .. DeadTrusted]
+
+ groups = settings cfgGroupMap
+ [ ""
+ , com "Repository groups"
+ , com $ "(Standard groups: " ++ grouplist ++ ")"
+ , com "(Separate group names with spaces)"
+ ]
+ (\(s, u) -> line "group" u $ unwords $ S.toList s)
+ (\u -> lcom $ line "group" u "")
+ where
+ grouplist = unwords $ map fromStandardGroup [minBound..]
+
+ preferredcontent = settings cfgPreferredContentMap
+ [ ""
+ , com "Repository preferred contents"
+ ]
+ (\(s, u) -> line "content" u s)
+ (\u -> line "content" u "")
+
+ schedule = settings cfgScheduleMap
+ [ ""
+ , com "Scheduled activities"
+ , com "(Separate multiple activities with \"; \")"
+ ]
+ (\(l, u) -> line "schedule" u $ fromScheduledActivities l)
+ (\u -> line "schedule" u "")
+
+ settings field desc showvals showdefaults = concat
+ [ desc
+ , concatMap showvals $ sort $ map swap $ M.toList $ field cfg
+ , concatMap (lcom . showdefaults) $ missing field
+ ]
+
+ line setting u value =
+ [ com $ "(for " ++ fromMaybe "" (M.lookup u descs) ++ ")"
+ , unwords [setting, fromUUID u, "=", value]
+ ]
+ lcom = map (\l -> if "#" `isPrefixOf` l then l else '#' : l)
+ missing field = S.toList $ M.keysSet descs `S.difference` M.keysSet (field cfg)
+
+{- If there's a parse error, returns a new version of the file,
+ - with the problem lines noted. -}
+parseCfg :: Cfg -> String -> Either String Cfg
+parseCfg curcfg = go [] curcfg . lines
+ where
+ go c cfg []
+ | null (mapMaybe fst c) = Right cfg
+ | otherwise = Left $ unlines $
+ badheader ++ concatMap showerr (reverse c)
+ go c cfg (l:ls) = case parse (dropWhile isSpace l) cfg of
+ Left msg -> go ((Just msg, l):c) cfg ls
+ Right cfg' -> go ((Nothing, l):c) cfg' ls
+
+ parse l cfg
+ | null l = Right cfg
+ | "#" `isPrefixOf` l = Right cfg
+ | null setting || null u = Left "missing repository uuid"
+ | otherwise = handle cfg (toUUID u) setting value'
+ where
+ (setting, rest) = separate isSpace l
+ (r, value) = separate (== '=') rest
+ value' = trimspace value
+ u = reverse $ trimspace $ reverse $ trimspace r
+ trimspace = dropWhile isSpace
+
+ handle cfg u setting value
+ | setting == "trust" = case readTrustLevel value of
+ Nothing -> badval "trust value" value
+ Just t ->
+ let m = M.insert u t (cfgTrustMap cfg)
+ in Right $ cfg { cfgTrustMap = m }
+ | setting == "group" =
+ let m = M.insert u (S.fromList $ words value) (cfgGroupMap cfg)
+ in Right $ cfg { cfgGroupMap = m }
+ | setting == "content" =
+ case checkPreferredContentExpression value of
+ Just e -> Left e
+ Nothing ->
+ let m = M.insert u value (cfgPreferredContentMap cfg)
+ in Right $ cfg { cfgPreferredContentMap = m }
+ | setting == "schedule" = case parseScheduledActivities value of
+ Left e -> Left e
+ Right l ->
+ let m = M.insert u l (cfgScheduleMap cfg)
+ in Right $ cfg { cfgScheduleMap = m }
+ | otherwise = badval "setting" setting
+
+ showerr (Just msg, l) = [parseerr ++ msg, l]
+ showerr (Nothing, l)
+ -- filter out the header and parse error lines
+ -- from any previous parse failure
+ | any (`isPrefixOf` l) (parseerr:badheader) = []
+ | otherwise = [l]
+
+ badval desc val = Left $ "unknown " ++ desc ++ " \"" ++ val ++ "\""
+ badheader =
+ [ com "There was a problem parsing your input."
+ , com "Search for \"Parse error\" to find the bad lines."
+ , com "Either fix the bad lines, or delete them (to discard your changes)."
+ ]
+ parseerr = com "Parse error in next line: "
+
+com :: String -> String
+com s = "# " ++ s
diff --git a/Command/Wanted.hs b/Command/Wanted.hs
new file mode 100644
index 000000000..a7b4a3d9e
--- /dev/null
+++ b/Command/Wanted.hs
@@ -0,0 +1,48 @@
+{- git-annex command
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Wanted where
+
+import Common.Annex
+import Command
+import qualified Remote
+import Logs.PreferredContent
+
+import qualified Data.Map as M
+
+def :: [Command]
+def = [command "wanted" (paramPair paramRemote (paramOptional paramExpression)) seek
+ SectionSetup "get or set preferred content expression"]
+
+seek :: [CommandSeek]
+seek = [withWords start]
+
+start :: [String] -> CommandStart
+start = parse
+ where
+ parse (name:[]) = go name performGet
+ parse (name:expr:[]) = go name $ \uuid -> do
+ showStart "wanted" name
+ performSet expr uuid
+ parse _ = error "Specify a repository."
+
+ go name a = do
+ u <- Remote.nameToUUID name
+ next $ a u
+
+performGet :: UUID -> CommandPerform
+performGet uuid = do
+ m <- preferredContentMapRaw
+ liftIO $ putStrLn $ fromMaybe "" $ M.lookup uuid m
+ next $ return True
+
+performSet :: String -> UUID -> CommandPerform
+performSet expr uuid = case checkPreferredContentExpression expr of
+ Just e -> error $ "Parse error: " ++ e
+ Nothing -> do
+ preferredContentSet uuid expr
+ next $ return True
diff --git a/Command/Watch.hs b/Command/Watch.hs
new file mode 100644
index 000000000..a33fc633c
--- /dev/null
+++ b/Command/Watch.hs
@@ -0,0 +1,36 @@
+{- git-annex watch command
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Watch where
+
+import Common.Annex
+import Assistant
+import Command
+import Option
+import Utility.HumanTime
+
+def :: [Command]
+def = [notBareRepo $ withOptions [foregroundOption, stopOption] $
+ command "watch" paramNothing seek SectionCommon "watch for changes"]
+
+seek :: [CommandSeek]
+seek = [withFlag stopOption $ \stopdaemon ->
+ withFlag foregroundOption $ \foreground ->
+ withNothing $ start False foreground stopdaemon Nothing]
+
+foregroundOption :: Option
+foregroundOption = Option.flag [] "foreground" "do not daemonize"
+
+stopOption :: Option
+stopOption = Option.flag [] "stop" "stop daemon"
+
+start :: Bool -> Bool -> Bool -> Maybe Duration -> CommandStart
+start assistant foreground stopdaemon startdelay = do
+ if stopdaemon
+ then stopDaemon
+ else startDaemon assistant foreground startdelay Nothing Nothing Nothing -- does not return
+ stop
diff --git a/Command/WebApp.hs b/Command/WebApp.hs
new file mode 100644
index 000000000..70f28a113
--- /dev/null
+++ b/Command/WebApp.hs
@@ -0,0 +1,226 @@
+{- git-annex webapp launcher
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Command.WebApp where
+
+import Common.Annex
+import Command
+import Assistant
+import Assistant.Common
+import Assistant.NamedThread
+import Assistant.Threads.WebApp
+import Assistant.WebApp
+import Assistant.Install
+import Annex.Environment
+import Utility.WebApp
+import Utility.Daemon (checkDaemon)
+#ifdef __ANDROID__
+import Utility.Env
+#endif
+import Init
+import qualified Git
+import qualified Git.Config
+import qualified Git.CurrentRepo
+import qualified Annex
+import Config.Files
+import qualified Option
+import Upgrade
+import Annex.Version
+
+import Control.Concurrent
+import Control.Concurrent.STM
+import System.Process (env, std_out, std_err)
+import Network.Socket (HostName)
+import System.Environment (getArgs)
+
+def :: [Command]
+def = [ withOptions [listenOption] $
+ noCommit $ noRepo startNoRepo $ dontCheck repoExists $ notBareRepo $
+ command "webapp" paramNothing seek SectionCommon "launch webapp"]
+
+listenOption :: Option
+listenOption = Option.field [] "listen" paramAddress
+ "accept connections to this address"
+
+seek :: [CommandSeek]
+seek = [withField listenOption return $ \listenhost ->
+ withNothing $ start listenhost]
+
+start :: Maybe HostName -> CommandStart
+start = start' True
+
+start' :: Bool -> Maybe HostName -> CommandStart
+start' allowauto listenhost = do
+ liftIO ensureInstalled
+ ifM isInitialized
+ ( go
+ , auto
+ )
+ stop
+ where
+ go = do
+ cannotrun <- needsUpgrade . fromMaybe (error "no version") =<< getVersion
+ browser <- fromRepo webBrowser
+ f <- liftIO . absPath =<< fromRepo gitAnnexHtmlShim
+ ifM (checkpid <&&> checkshim f)
+ ( if isJust listenhost
+ then error "The assistant is already running, so --listen cannot be used."
+ else do
+ url <- liftIO . readFile
+ =<< fromRepo gitAnnexUrlFile
+ liftIO $ openBrowser browser f url Nothing Nothing
+ , startDaemon True True Nothing cannotrun listenhost $ Just $
+ \origout origerr url htmlshim ->
+ if isJust listenhost
+ then maybe noop (`hPutStrLn` url) origout
+ else openBrowser browser htmlshim url origout origerr
+ )
+ auto
+ | allowauto = liftIO startNoRepo
+ | otherwise = do
+ d <- liftIO getCurrentDirectory
+ error $ "no git repository in " ++ d
+ checkpid = do
+ pidfile <- fromRepo gitAnnexPidFile
+ liftIO $ isJust <$> checkDaemon pidfile
+ checkshim f = liftIO $ doesFileExist f
+
+{- When run without a repo, start the first available listed repository in
+ - the autostart file. If not, it's our first time being run! -}
+startNoRepo :: IO ()
+startNoRepo = do
+ -- FIXME should be able to reuse regular getopt, but
+ -- it currently runs in the Annex monad.
+ args <- getArgs
+ let listenhost = headMaybe $ map (snd . separate (== '=')) $
+ filter ("--listen=" `isPrefixOf`) args
+
+ dirs <- liftIO $ filterM doesDirectoryExist =<< readAutoStartFile
+ case dirs of
+ [] -> firstRun listenhost
+ (d:_) -> do
+ setCurrentDirectory d
+ state <- Annex.new =<< Git.CurrentRepo.get
+ void $ Annex.eval state $ doCommand $
+ start' False listenhost
+
+{- Run the webapp without a repository, which prompts the user, makes one,
+ - changes to it, starts the regular assistant, and redirects the
+ - browser to its url.
+ -
+ - This is a very tricky dance -- The first webapp calls the signaler,
+ - which signals the main thread when it's ok to continue by writing to a
+ - MVar. The main thread starts the second webapp, and uses its callback
+ - to write its url back to the MVar, from where the signaler retrieves it,
+ - returning it to the first webapp, which does the redirect.
+ -
+ - Note that it's important that mainthread never terminates! Much
+ - of this complication is due to needing to keep the mainthread running.
+ -}
+firstRun :: Maybe HostName -> IO ()
+firstRun listenhost = do
+ checkEnvironmentIO
+ {- Without a repository, we cannot have an Annex monad, so cannot
+ - get a ThreadState. Using undefined is only safe because the
+ - webapp checks its noAnnex field before accessing the
+ - threadstate. -}
+ let st = undefined
+ {- Get a DaemonStatus without running in the Annex monad. -}
+ dstatus <- atomically . newTMVar =<< newDaemonStatus
+ d <- newAssistantData st dstatus
+ urlrenderer <- newUrlRenderer
+ v <- newEmptyMVar
+ let callback a = Just $ a v
+ runAssistant d $ do
+ startNamedThread urlrenderer $
+ webAppThread d urlrenderer True Nothing listenhost
+ (callback signaler)
+ (callback mainthread)
+ waitNamedThreads
+ where
+ signaler v = do
+ putMVar v ""
+ takeMVar v
+ mainthread v url htmlshim
+ | isJust listenhost = do
+ putStrLn url
+ hFlush stdout
+ go
+ | otherwise = do
+ browser <- maybe Nothing webBrowser <$> Git.Config.global
+ openBrowser browser htmlshim url Nothing Nothing
+ go
+ where
+ go = do
+ _wait <- takeMVar v
+ state <- Annex.new =<< Git.CurrentRepo.get
+ Annex.eval state $
+ startDaemon True True Nothing Nothing listenhost $ Just $
+ sendurlback v
+ sendurlback v _origout _origerr url _htmlshim = do
+ recordUrl url
+ putMVar v url
+
+recordUrl :: String -> IO ()
+#ifdef __ANDROID__
+{- The Android app has a menu item that opens the url recorded
+ - in this file. -}
+recordUrl url = writeFile "/sdcard/git-annex.home/.git-annex-url" url
+#else
+recordUrl _ = noop
+#endif
+
+openBrowser :: Maybe FilePath -> FilePath -> String -> Maybe Handle -> Maybe Handle -> IO ()
+#ifndef __ANDROID__
+openBrowser mcmd htmlshim _realurl outh errh = runbrowser
+#else
+openBrowser mcmd htmlshim realurl outh errh = do
+ recordUrl url
+ {- Android's `am` command does not work reliably across the
+ - wide range of Android devices. Intead, FIFO should be set to
+ - the filename of a fifo that we can write the URL to. -}
+ v <- getEnv "FIFO"
+ case v of
+ Nothing -> runbrowser
+ Just f -> void $ forkIO $ do
+ fd <- openFd f WriteOnly Nothing defaultFileFlags
+ void $ fdWrite fd url
+ closeFd fd
+#endif
+ where
+ p = case mcmd of
+ Just cmd -> proc cmd [htmlshim]
+ Nothing -> browserProc url
+#ifdef __ANDROID__
+ {- Android does not support file:// urls, but neither is
+ - the security of the url in the process table important
+ - there, so just use the real url. -}
+ url = realurl
+#else
+ url = fileUrl htmlshim
+#endif
+ runbrowser = do
+ hPutStrLn (fromMaybe stdout outh) $ "Launching web browser on " ++ url
+ hFlush stdout
+ environ <- cleanEnvironment
+ (_, _, _, pid) <- createProcess p
+ { env = environ
+ , std_out = maybe Inherit UseHandle outh
+ , std_err = maybe Inherit UseHandle errh
+ }
+ exitcode <- waitForProcess pid
+ unless (exitcode == ExitSuccess) $
+ hPutStrLn (fromMaybe stderr errh) "failed to start web browser"
+
+{- web.browser is a generic git config setting for a web browser program -}
+webBrowser :: Git.Repo -> Maybe FilePath
+webBrowser = Git.Config.getMaybe "web.browser"
+
+fileUrl :: FilePath -> String
+fileUrl file = "file://" ++ file
diff --git a/Command/Whereis.hs b/Command/Whereis.hs
new file mode 100644
index 000000000..7086bf645
--- /dev/null
+++ b/Command/Whereis.hs
@@ -0,0 +1,54 @@
+{- git-annex command
+ -
+ - Copyright 2010 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.Whereis where
+
+import qualified Data.Map as M
+
+import Common.Annex
+import Command
+import Remote
+import Logs.Trust
+
+def :: [Command]
+def = [noCommit $ command "whereis" paramPaths seek
+ SectionQuery "lists repositories that have file content"]
+
+seek :: [CommandSeek]
+seek = [withValue (remoteMap id) $ \m ->
+ withFilesInGit $ whenAnnexed $ start m]
+
+start :: M.Map UUID Remote -> FilePath -> (Key, Backend) -> CommandStart
+start remotemap file (key, _) = do
+ showStart "whereis" file
+ next $ perform remotemap key
+
+perform :: M.Map UUID Remote -> Key -> CommandPerform
+perform remotemap key = do
+ locations <- keyLocations key
+ (untrustedlocations, safelocations) <- trustPartition UnTrusted locations
+ let num = length safelocations
+ showNote $ show num ++ " " ++ copiesplural num
+ pp <- prettyPrintUUIDs "whereis" safelocations
+ unless (null safelocations) $ showLongNote pp
+ pp' <- prettyPrintUUIDs "untrusted" untrustedlocations
+ unless (null untrustedlocations) $ showLongNote $ untrustedheader ++ pp'
+ forM_ (mapMaybe (`M.lookup` remotemap) locations) $
+ performRemote key
+ if null safelocations then stop else next $ return True
+ where
+ copiesplural 1 = "copy"
+ copiesplural _ = "copies"
+ untrustedheader = "The following untrusted locations may also have copies:\n"
+
+performRemote :: Key -> Remote -> Annex ()
+performRemote key remote = maybe noop go $ whereisKey remote
+ where
+ go a = do
+ ls <- a key
+ unless (null ls) $ showLongNote $ unlines $
+ map (\l -> name remote ++ ": " ++ l) ls
diff --git a/Command/XMPPGit.hs b/Command/XMPPGit.hs
new file mode 100644
index 000000000..c1ff0b108
--- /dev/null
+++ b/Command/XMPPGit.hs
@@ -0,0 +1,43 @@
+{- git-annex command
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Command.XMPPGit where
+
+import Common.Annex
+import Command
+import Assistant.XMPP.Git
+
+def :: [Command]
+def = [noCommit $ noRepo xmppGitRelay $ dontCheck repoExists $
+ command "xmppgit" paramNothing seek
+ SectionPlumbing "git to XMPP relay"]
+
+seek :: [CommandSeek]
+seek = [withWords start]
+
+start :: [String] -> CommandStart
+start _ = do
+ liftIO gitRemoteHelper
+ liftIO xmppGitRelay
+ stop
+
+{- A basic implementation of the git-remote-helpers protocol. -}
+gitRemoteHelper :: IO ()
+gitRemoteHelper = do
+ expect "capabilities"
+ respond ["connect"]
+ expect "connect git-receive-pack"
+ respond []
+ where
+ expect s = do
+ cmd <- getLine
+ unless (cmd == s) $
+ error $ "git-remote-helpers protocol error: expected: " ++ s ++ ", but got: " ++ cmd
+ respond l = do
+ mapM_ putStrLn l
+ putStrLn ""
+ hFlush stdout
diff --git a/Common.hs b/Common.hs
new file mode 100644
index 000000000..a6203b9a6
--- /dev/null
+++ b/Common.hs
@@ -0,0 +1,35 @@
+{-# LANGUAGE PackageImports, CPP #-}
+
+module Common (module X) where
+
+import Control.Monad as X
+import Control.Monad.IfElse as X
+import Control.Applicative as X
+import "mtl" Control.Monad.State.Strict as X (liftIO)
+import Control.Exception.Extensible as X (IOException)
+
+import Data.Maybe as X
+import Data.List as X hiding (head, tail, init, last)
+import Data.String.Utils as X hiding (join)
+
+import System.FilePath as X
+import System.Directory as X
+import System.IO as X hiding (FilePath)
+import System.PosixCompat.Files as X
+#ifndef mingw32_HOST_OS
+import System.Posix.IO as X
+#endif
+import System.Exit as X
+
+import Utility.Misc as X
+import Utility.Exception as X
+import Utility.SafeCommand as X
+import Utility.Process as X
+import Utility.Path as X
+import Utility.Directory as X
+import Utility.Monad as X
+import Utility.Data as X
+import Utility.Applicative as X
+import Utility.FileSystemEncoding as X
+
+import Utility.PartialPrelude as X
diff --git a/Common/Annex.hs b/Common/Annex.hs
new file mode 100644
index 000000000..3b8bcdbdd
--- /dev/null
+++ b/Common/Annex.hs
@@ -0,0 +1,8 @@
+module Common.Annex (module X) where
+
+import Common as X
+import Types as X
+import Types.UUID as X (toUUID, fromUUID)
+import Annex as X (gitRepo, inRepo, fromRepo, calcRepo)
+import Locations as X
+import Messages as X
diff --git a/Config.hs b/Config.hs
new file mode 100644
index 000000000..0c6b64f50
--- /dev/null
+++ b/Config.hs
@@ -0,0 +1,88 @@
+{- Git configuration
+ -
+ - Copyright 2011-2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Config where
+
+import Common.Annex
+import qualified Git
+import qualified Git.Config
+import qualified Git.Command
+import qualified Annex
+import qualified Types.Remote as Remote
+import Config.Cost
+
+type UnqualifiedConfigKey = String
+data ConfigKey = ConfigKey String
+
+instance Show ConfigKey where
+ show (ConfigKey s) = s
+
+{- Looks up a setting in git config. -}
+getConfig :: ConfigKey -> String -> Annex String
+getConfig (ConfigKey key) def = fromRepo $ Git.Config.get key def
+
+getConfigMaybe :: ConfigKey -> Annex (Maybe String)
+getConfigMaybe (ConfigKey key) = fromRepo $ Git.Config.getMaybe key
+
+{- Changes a git config setting in both internal state and .git/config -}
+setConfig :: ConfigKey -> String -> Annex ()
+setConfig (ConfigKey key) value = do
+ inRepo $ Git.Command.run [Param "config", Param key, Param value]
+ Annex.changeGitRepo =<< inRepo Git.Config.reRead
+
+{- Unsets a git config setting. (Leaves it in state currently.) -}
+unsetConfig :: ConfigKey -> Annex ()
+unsetConfig ck@(ConfigKey key) = ifM (isJust <$> getConfigMaybe ck)
+ ( inRepo $ Git.Command.run
+ [Param "config", Param "--unset", Param key]
+ , noop -- avoid unsetting something not set; that would fail
+ )
+
+{- A per-remote config setting in git config. -}
+remoteConfig :: Git.Repo -> UnqualifiedConfigKey -> ConfigKey
+remoteConfig r key = ConfigKey $
+ "remote." ++ fromMaybe "" (Git.remoteName r) ++ ".annex-" ++ key
+
+{- A global annex setting in git config. -}
+annexConfig :: UnqualifiedConfigKey -> ConfigKey
+annexConfig key = ConfigKey $ "annex." ++ key
+
+{- Calculates cost for a remote. Either the specific default, or as configured
+ - by remote.<name>.annex-cost, or if remote.<name>.annex-cost-command
+ - is set and prints a number, that is used. -}
+remoteCost :: RemoteGitConfig -> Cost -> Annex Cost
+remoteCost c def = case remoteAnnexCostCommand c of
+ Just cmd | not (null cmd) -> liftIO $
+ (fromMaybe def . readish) <$>
+ readProcess "sh" ["-c", cmd]
+ _ -> return $ fromMaybe def $ remoteAnnexCost c
+
+setRemoteCost :: Remote -> Cost -> Annex ()
+setRemoteCost r c = setConfig (remoteConfig (Remote.repo r) "cost") (show c)
+
+getNumCopies :: Maybe Int -> Annex Int
+getNumCopies (Just v) = return v
+getNumCopies Nothing = annexNumCopies <$> Annex.getGitConfig
+
+isDirect :: Annex Bool
+isDirect = annexDirect <$> Annex.getGitConfig
+
+crippledFileSystem :: Annex Bool
+crippledFileSystem = annexCrippledFileSystem <$> Annex.getGitConfig
+
+setCrippledFileSystem :: Bool -> Annex ()
+setCrippledFileSystem b = do
+ setConfig (annexConfig "crippledfilesystem") (Git.Config.boolConfig b)
+ Annex.changeGitConfig $ \c -> c { annexCrippledFileSystem = b }
+
+{- Gets the http headers to use. -}
+getHttpHeaders :: Annex [String]
+getHttpHeaders = do
+ v <- annexHttpHeadersCommand <$> Annex.getGitConfig
+ case v of
+ Just cmd -> lines <$> liftIO (readProcess "sh" ["-c", cmd])
+ Nothing -> annexHttpHeaders <$> Annex.getGitConfig
diff --git a/Config/Cost.hs b/Config/Cost.hs
new file mode 100644
index 000000000..2d94a6b15
--- /dev/null
+++ b/Config/Cost.hs
@@ -0,0 +1,82 @@
+{- Remote costs.
+ -
+ - Copyright 2011-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Config.Cost where
+
+{- We use a float for a cost to ensure that there is a cost in
+ - between any two other costs. -}
+type Cost = Float
+
+{- Some predefined default costs.
+ - Users setting costs in config files can be aware of these,
+ - and pick values relative to them. So don't change. -}
+cheapRemoteCost :: Cost
+cheapRemoteCost = 100
+nearlyCheapRemoteCost :: Cost
+nearlyCheapRemoteCost = 110
+semiExpensiveRemoteCost :: Cost
+semiExpensiveRemoteCost = 175
+expensiveRemoteCost :: Cost
+expensiveRemoteCost = 200
+veryExpensiveRemoteCost :: Cost
+veryExpensiveRemoteCost = 1000
+
+{- Adjusts a remote's cost to reflect it being encrypted. -}
+encryptedRemoteCostAdj :: Cost
+encryptedRemoteCostAdj = 50
+
+{- Given an ordered list of costs, and the position of one of the items
+ - the list, inserts a new cost into the list, in between the item
+ - and the item after it.
+ -
+ - If two or move items have the same cost, their costs are adjusted
+ - to make room. The costs of other items in the list are left
+ - unchanged.
+ -
+ - To insert the new cost before any other in the list, specify a negative
+ - position. To insert the new cost at the end of the list, specify a
+ - position longer than the list.
+ -}
+insertCostAfter :: [Cost] -> Int -> [Cost]
+insertCostAfter [] _ = []
+insertCostAfter l pos
+ | pos < 0 = costBetween 0 (l !! 0) : l
+ | nextpos > maxpos = l ++ [1 + l !! maxpos]
+ | item == nextitem =
+ let (_dup:new:l') = insertCostAfter lastsegment 0
+ in firstsegment ++ [costBetween item new, new] ++ l'
+ | otherwise =
+ firstsegment ++ [costBetween item nextitem ] ++ lastsegment
+ where
+ nextpos = pos + 1
+ maxpos = length l - 1
+
+ item = l !! pos
+ nextitem = l !! nextpos
+
+ (firstsegment, lastsegment) = splitAt (pos + 1) l
+
+costBetween :: Cost -> Cost -> Cost
+costBetween x y
+ | x == y = x
+ | x > y = -- avoid fractions unless needed
+ let mid = y + (x - y) / 2
+ mid' = fromIntegral (floor mid :: Int)
+ in if mid' > y then mid' else mid
+ | otherwise = costBetween y x
+
+{- Make sure the remote cost numbers work out. -}
+prop_cost_sane :: Bool
+prop_cost_sane = False `notElem`
+ [ expensiveRemoteCost > 0
+ , cheapRemoteCost < nearlyCheapRemoteCost
+ , nearlyCheapRemoteCost < semiExpensiveRemoteCost
+ , semiExpensiveRemoteCost < expensiveRemoteCost
+ , cheapRemoteCost + encryptedRemoteCostAdj > nearlyCheapRemoteCost
+ , nearlyCheapRemoteCost + encryptedRemoteCostAdj < semiExpensiveRemoteCost
+ , nearlyCheapRemoteCost + encryptedRemoteCostAdj < expensiveRemoteCost
+ ]
diff --git a/Config/Files.hs b/Config/Files.hs
new file mode 100644
index 000000000..30ed0a3cf
--- /dev/null
+++ b/Config/Files.hs
@@ -0,0 +1,69 @@
+{- git-annex extra config files
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Config.Files where
+
+import Common
+import Utility.Tmp
+import Utility.FreeDesktop
+
+{- ~/.config/git-annex/file -}
+userConfigFile :: FilePath -> IO FilePath
+userConfigFile file = do
+ dir <- userConfigDir
+ return $ dir </> "git-annex" </> file
+
+autoStartFile :: IO FilePath
+autoStartFile = userConfigFile "autostart"
+
+{- Returns anything listed in the autostart file (which may not exist). -}
+readAutoStartFile :: IO [FilePath]
+readAutoStartFile = do
+ f <- autoStartFile
+ nub . map dropTrailingPathSeparator . lines
+ <$> catchDefaultIO "" (readFile f)
+
+modifyAutoStartFile :: ([FilePath] -> [FilePath]) -> IO ()
+modifyAutoStartFile func = do
+ dirs <- readAutoStartFile
+ let dirs' = nubBy equalFilePath $ func dirs
+ when (dirs' /= dirs) $ do
+ f <- autoStartFile
+ createDirectoryIfMissing True (parentDir f)
+ viaTmp writeFile f $ unlines dirs'
+
+{- Adds a directory to the autostart file. If the directory is already
+ - present, it's moved to the top, so it will be used as the default
+ - when opening the webapp. -}
+addAutoStartFile :: FilePath -> IO ()
+addAutoStartFile path = modifyAutoStartFile $ (:) path
+
+{- Removes a directory from the autostart file. -}
+removeAutoStartFile :: FilePath -> IO ()
+removeAutoStartFile path = modifyAutoStartFile $
+ filter (not . equalFilePath path)
+
+{- The path to git-annex is written here; which is useful when cabal
+ - has installed it to some awful non-PATH location. -}
+programFile :: IO FilePath
+programFile = userConfigFile "program"
+
+{- Returns a command to run for git-annex. -}
+readProgramFile :: IO FilePath
+readProgramFile = do
+ programfile <- programFile
+ p <- catchDefaultIO cmd $
+ fromMaybe cmd . headMaybe . lines <$> readFile programfile
+ ifM (inPath p)
+ ( return p
+ , ifM (inPath cmd)
+ ( return cmd
+ , error $ "cannot find git-annex program in PATH or in the location listed in " ++ programfile
+ )
+ )
+ where
+ cmd = "git-annex"
diff --git a/Creds.hs b/Creds.hs
new file mode 100644
index 000000000..c79c16cce
--- /dev/null
+++ b/Creds.hs
@@ -0,0 +1,147 @@
+{- Credentials storage
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Creds where
+
+import Common.Annex
+import Annex.Perms
+import Utility.FileMode
+import Crypto
+import Types.Remote (RemoteConfig, RemoteConfigKey)
+import Remote.Helper.Encryptable (remoteCipher, embedCreds)
+import Utility.Env (setEnv, getEnv)
+
+import qualified Data.ByteString.Lazy.Char8 as L
+import qualified Data.Map as M
+import Utility.Base64
+
+type Creds = String -- can be any data
+type CredPair = (String, String) -- login, password
+
+{- A CredPair can be stored in a file, or in the environment, or perhaps
+ - in a remote's configuration. -}
+data CredPairStorage = CredPairStorage
+ { credPairFile :: FilePath
+ , credPairEnvironment :: (String, String)
+ , credPairRemoteKey :: Maybe RemoteConfigKey
+ }
+
+{- Stores creds in a remote's configuration, if the remote allows
+ - that. Otherwise, caches them locally. -}
+setRemoteCredPair :: RemoteConfig -> CredPairStorage -> Annex RemoteConfig
+setRemoteCredPair c storage = go =<< getRemoteCredPair c storage
+ where
+ go (Just creds)
+ | embedCreds c = case credPairRemoteKey storage of
+ Nothing -> localcache creds
+ Just key -> storeconfig creds key =<< remoteCipher c
+ | otherwise = localcache creds
+ go Nothing = return c
+
+ localcache creds = do
+ writeCacheCredPair creds storage
+ return c
+
+ storeconfig creds key (Just cipher) = do
+ s <- liftIO $ encrypt [] cipher
+ (feedBytes $ L.pack $ encodeCredPair creds)
+ (readBytes $ return . L.unpack)
+ return $ M.insert key (toB64 s) c
+ storeconfig creds key Nothing =
+ return $ M.insert key (toB64 $ encodeCredPair creds) c
+
+{- Gets a remote's credpair, from the environment if set, otherwise
+ - from the cache in gitAnnexCredsDir, or failing that, from the
+ - value in RemoteConfig. -}
+getRemoteCredPairFor :: String -> RemoteConfig -> CredPairStorage -> Annex (Maybe CredPair)
+getRemoteCredPairFor this c storage = maybe missing (return . Just) =<< getRemoteCredPair c storage
+ where
+ (loginvar, passwordvar) = credPairEnvironment storage
+ missing = do
+ warning $ unwords
+ [ "Set both", loginvar
+ , "and", passwordvar
+ , "to use", this
+ ]
+ return Nothing
+
+getRemoteCredPair :: RemoteConfig -> CredPairStorage -> Annex (Maybe CredPair)
+getRemoteCredPair c storage = maybe fromcache (return . Just) =<< fromenv
+ where
+ fromenv = liftIO $ getEnvCredPair storage
+ fromcache = maybe fromconfig (return . Just) =<< readCacheCredPair storage
+ fromconfig = case credPairRemoteKey storage of
+ Just key -> do
+ mcipher <- remoteCipher c
+ case (M.lookup key c, mcipher) of
+ (Nothing, _) -> return Nothing
+ (Just enccreds, Just cipher) -> do
+ creds <- liftIO $ decrypt cipher
+ (feedBytes $ L.pack $ fromB64 enccreds)
+ (readBytes $ return . L.unpack)
+ fromcreds creds
+ (Just bcreds, Nothing) ->
+ fromcreds $ fromB64 bcreds
+ Nothing -> return Nothing
+ fromcreds creds = case decodeCredPair creds of
+ Just credpair -> do
+ writeCacheCredPair credpair storage
+ return $ Just credpair
+ _ -> error "bad creds"
+
+{- Gets a CredPair from the environment. -}
+getEnvCredPair :: CredPairStorage -> IO (Maybe CredPair)
+getEnvCredPair storage = liftM2 (,)
+ <$> getEnv uenv
+ <*> getEnv penv
+ where
+ (uenv, penv) = credPairEnvironment storage
+
+{- Stores a CredPair in the environment. -}
+setEnvCredPair :: CredPair -> CredPairStorage -> IO ()
+#ifndef mingw32_HOST_OS
+setEnvCredPair (l, p) storage = do
+ set uenv l
+ set penv p
+ where
+ (uenv, penv) = credPairEnvironment storage
+ set var val = void $ setEnv var val True
+#else
+setEnvCredPair _ _ = error "setEnvCredPair TODO"
+#endif
+
+writeCacheCredPair :: CredPair -> CredPairStorage -> Annex ()
+writeCacheCredPair credpair storage =
+ writeCacheCreds (encodeCredPair credpair) (credPairFile storage)
+
+{- Stores the creds in a file inside gitAnnexCredsDir that only the user
+ - can read. -}
+writeCacheCreds :: Creds -> FilePath -> Annex ()
+writeCacheCreds creds file = do
+ d <- fromRepo gitAnnexCredsDir
+ createAnnexDirectory d
+ liftIO $ writeFileProtected (d </> file) creds
+
+readCacheCredPair :: CredPairStorage -> Annex (Maybe CredPair)
+readCacheCredPair storage = maybe Nothing decodeCredPair
+ <$> readCacheCreds (credPairFile storage)
+
+readCacheCreds :: FilePath -> Annex (Maybe Creds)
+readCacheCreds file = do
+ d <- fromRepo gitAnnexCredsDir
+ let f = d </> file
+ liftIO $ catchMaybeIO $ readFile f
+
+encodeCredPair :: CredPair -> Creds
+encodeCredPair (l, p) = unlines [l, p]
+
+decodeCredPair :: Creds -> Maybe CredPair
+decodeCredPair creds = case lines creds of
+ l:p:[] -> Just (l, p)
+ _ -> Nothing
diff --git a/Crypto.hs b/Crypto.hs
new file mode 100644
index 000000000..371bbcaf1
--- /dev/null
+++ b/Crypto.hs
@@ -0,0 +1,211 @@
+{- git-annex crypto
+ -
+ - Currently using gpg; could later be modified to support different
+ - crypto backends if neccessary.
+ -
+ - Copyright 2011-2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE FlexibleInstances #-}
+
+module Crypto (
+ Cipher,
+ KeyIds(..),
+ StorableCipher(..),
+ genEncryptedCipher,
+ genSharedCipher,
+ updateEncryptedCipher,
+ describeCipher,
+ decryptCipher,
+ encryptKey,
+ feedFile,
+ feedBytes,
+ readBytes,
+ encrypt,
+ decrypt,
+ getGpgEncParams,
+
+ prop_HmacSha1WithCipher_sane
+) where
+
+import qualified Data.ByteString.Lazy as L
+import Data.ByteString.Lazy.UTF8 (fromString)
+import Control.Applicative
+import qualified Data.Map as M
+
+import Common.Annex
+import qualified Utility.Gpg as Gpg
+import Types.Key
+import Types.Crypto
+import Types.Remote
+
+{- The beginning of a Cipher is used for MAC'ing; the remainder is used
+ - as the GPG symmetric encryption passphrase when using the hybrid
+ - scheme. Note that the cipher itself is base-64 encoded, hence the
+ - string is longer than 'cipherSize': 683 characters, padded to 684.
+ -
+ - The 256 first characters that feed the MAC represent at best 192
+ - bytes of entropy. However that's more than enough for both the
+ - default MAC algorithm, namely HMAC-SHA1, and the "strongest"
+ - currently supported, namely HMAC-SHA512, which respectively need
+ - (ideally) 64 and 128 bytes of entropy.
+ -
+ - The remaining characters (320 bytes of entropy) is enough for GnuPG's
+ - symetric cipher; unlike weaker public key crypto, the key does not
+ - need to be too large.
+ -}
+cipherBeginning :: Int
+cipherBeginning = 256
+
+cipherSize :: Int
+cipherSize = 512
+
+cipherPassphrase :: Cipher -> String
+cipherPassphrase (Cipher c) = drop cipherBeginning c
+cipherPassphrase (MacOnlyCipher _) = error "MAC-only cipher"
+
+cipherMac :: Cipher -> String
+cipherMac (Cipher c) = take cipherBeginning c
+cipherMac (MacOnlyCipher c) = c
+
+{- Creates a new Cipher, encrypted to the specified key id. -}
+genEncryptedCipher :: String -> EncryptedCipherVariant -> Bool -> IO StorableCipher
+genEncryptedCipher keyid variant highQuality = do
+ ks <- Gpg.findPubKeys keyid
+ random <- Gpg.genRandom highQuality size
+ encryptCipher (mkCipher random) variant ks
+ where
+ (mkCipher, size) = case variant of
+ Hybrid -> (Cipher, cipherSize) -- used for MAC + symmetric
+ PubKey -> (MacOnlyCipher, cipherBeginning) -- only used for MAC
+
+{- Creates a new, shared Cipher. -}
+genSharedCipher :: Bool -> IO StorableCipher
+genSharedCipher highQuality =
+ SharedCipher <$> Gpg.genRandom highQuality cipherSize
+
+{- Updates an existing Cipher, re-encrypting it to add or remove keyids,
+ - depending on whether the first component is True or False. -}
+updateEncryptedCipher :: [(Bool, String)] -> StorableCipher -> IO StorableCipher
+updateEncryptedCipher _ SharedCipher{} = undefined
+updateEncryptedCipher [] encipher = return encipher
+updateEncryptedCipher newkeys encipher@(EncryptedCipher _ variant (KeyIds ks)) = do
+ dropKeys <- listKeyIds [ k | (False, k) <- newkeys ]
+ forM_ dropKeys $ \k -> unless (k `elem` ks) $
+ error $ "Key " ++ k ++ " was not present; cannot remove."
+ addKeys <- listKeyIds [ k | (True, k) <- newkeys ]
+ let ks' = (addKeys ++ ks) \\ dropKeys
+ when (null ks') $
+ error "Cannot remove the last key."
+ cipher <- decryptCipher encipher
+ encryptCipher cipher variant $ KeyIds ks'
+ where
+ listKeyIds = concat <$$> mapM (keyIds <$$> Gpg.findPubKeys)
+
+describeCipher :: StorableCipher -> String
+describeCipher (SharedCipher _) = "shared cipher"
+describeCipher (EncryptedCipher _ variant (KeyIds ks)) =
+ scheme ++ " with gpg " ++ keys ks ++ " " ++ unwords ks
+ where
+ scheme = case variant of
+ Hybrid -> "hybrid cipher"
+ PubKey -> "pubkey crypto"
+ keys [_] = "key"
+ keys _ = "keys"
+
+{- Encrypts a Cipher to the specified KeyIds. -}
+encryptCipher :: Cipher -> EncryptedCipherVariant -> KeyIds -> IO StorableCipher
+encryptCipher c variant (KeyIds ks) = do
+ -- gpg complains about duplicate recipient keyids
+ let ks' = nub $ sort ks
+ let params = Gpg.pkEncTo ks' ++ Gpg.stdEncryptionParams False
+ encipher <- Gpg.pipeStrict params cipher
+ return $ EncryptedCipher encipher variant (KeyIds ks')
+ where
+ cipher = case c of
+ Cipher x -> x
+ MacOnlyCipher x -> x
+
+{- Decrypting an EncryptedCipher is expensive; the Cipher should be cached. -}
+decryptCipher :: StorableCipher -> IO Cipher
+decryptCipher (SharedCipher t) = return $ Cipher t
+decryptCipher (EncryptedCipher t variant _) =
+ mkCipher <$> Gpg.pipeStrict [ Param "--decrypt" ] t
+ where
+ mkCipher = case variant of
+ Hybrid -> Cipher
+ PubKey -> MacOnlyCipher
+
+{- Generates an encrypted form of a Key. The encryption does not need to be
+ - reversable, nor does it need to be the same type of encryption used
+ - on content. It does need to be repeatable. -}
+encryptKey :: Mac -> Cipher -> Key -> Key
+encryptKey mac c k = Key
+ { keyName = macWithCipher mac c (key2file k)
+ , keyBackendName = "GPG" ++ showMac mac
+ , keySize = Nothing -- size and mtime omitted
+ , keyMtime = Nothing -- to avoid leaking data
+ }
+
+type Feeder = Handle -> IO ()
+type Reader a = Handle -> IO a
+
+feedFile :: FilePath -> Feeder
+feedFile f h = L.hPut h =<< L.readFile f
+
+feedBytes :: L.ByteString -> Feeder
+feedBytes = flip L.hPut
+
+readBytes :: (L.ByteString -> IO a) -> Reader a
+readBytes a h = L.hGetContents h >>= a
+
+{- Runs a Feeder action, that generates content that is symmetrically
+ - encrypted with the Cipher (unless it is empty, in which case
+ - public-key encryption is used) using the given gpg options, and then
+ - read by the Reader action. Note: For public-key encryption,
+ - recipients MUST be included in 'params' (for instance using
+ - 'getGpgEncParams'). -}
+encrypt :: [CommandParam] -> Cipher -> Feeder -> Reader a -> IO a
+encrypt params cipher = case cipher of
+ Cipher{} -> Gpg.feedRead (params ++ Gpg.stdEncryptionParams True) $
+ cipherPassphrase cipher
+ MacOnlyCipher{} -> Gpg.pipeLazy $ params ++ Gpg.stdEncryptionParams False
+
+{- Runs a Feeder action, that generates content that is decrypted with the
+ - Cipher (or using a private key if the Cipher is empty), and read by the
+ - Reader action. -}
+decrypt :: Cipher -> Feeder -> Reader a -> IO a
+decrypt cipher = case cipher of
+ Cipher{} -> Gpg.feedRead [Param "--decrypt"] $ cipherPassphrase cipher
+ MacOnlyCipher{} -> Gpg.pipeLazy [Param "--decrypt"]
+
+macWithCipher :: Mac -> Cipher -> String -> String
+macWithCipher mac c = macWithCipher' mac (cipherMac c)
+macWithCipher' :: Mac -> String -> String -> String
+macWithCipher' mac c s = calcMac mac (fromString c) (fromString s)
+
+{- Ensure that macWithCipher' returns the same thing forevermore. -}
+prop_HmacSha1WithCipher_sane :: Bool
+prop_HmacSha1WithCipher_sane = known_good == macWithCipher' HmacSha1 "foo" "bar"
+ where
+ known_good = "46b4ec586117154dacd49d664e5d63fdc88efb51"
+
+{- Return some options suitable for GnuPG encryption, symmetric or not. -}
+class LensGpgEncParams a where getGpgEncParams :: a -> [CommandParam]
+
+{- Extract the GnuPG options from a pair of a Remote Config and a Remote
+ - Git Config. If the remote is configured to use public-key encryption,
+ - look up the recipient keys and add them to the option list. -}
+instance LensGpgEncParams (RemoteConfig, RemoteGitConfig) where
+ getGpgEncParams (c,gc) = map Param (remoteAnnexGnupgOptions gc) ++ recipients
+ where
+ recipients = case M.lookup "encryption" c of
+ Just "pubkey" -> Gpg.pkEncTo $ maybe [] (split ",") $
+ M.lookup "cipherkeys" c
+ _ -> []
+
+{- Extract the GnuPG options from a Remote. -}
+instance LensGpgEncParams (RemoteA a) where
+ getGpgEncParams r = getGpgEncParams (config r, gitconfig r)
diff --git a/Fields.hs b/Fields.hs
new file mode 100644
index 000000000..ffd273be6
--- /dev/null
+++ b/Fields.hs
@@ -0,0 +1,35 @@
+{- git-annex fields
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Fields where
+
+import Common.Annex
+import qualified Annex
+
+import Data.Char
+
+{- A field, stored in Annex state, with a value sanity checker. -}
+data Field = Field
+ { fieldName :: String
+ , fieldCheck :: String -> Bool
+ }
+
+getField :: Field -> Annex (Maybe String)
+getField = Annex.getField . fieldName
+
+remoteUUID :: Field
+remoteUUID = Field "remoteuuid" $
+ -- does it look like a UUID?
+ all (\c -> isAlphaNum c || c == '-')
+
+associatedFile :: Field
+associatedFile = Field "associatedfile" $ \f ->
+ -- is the file a safe relative filename?
+ not (isAbsolute f) && not ("../" `isPrefixOf` f)
+
+direct :: Field
+direct = Field "direct" $ \f -> f == "1"
diff --git a/Git.hs b/Git.hs
new file mode 100644
index 000000000..cad466853
--- /dev/null
+++ b/Git.hs
@@ -0,0 +1,140 @@
+{- git repository handling
+ -
+ - This is written to be completely independant of git-annex and should be
+ - suitable for other uses.
+ -
+ - Copyright 2010-2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Git (
+ Repo(..),
+ Ref(..),
+ Branch,
+ Sha,
+ Tag,
+ repoIsUrl,
+ repoIsSsh,
+ repoIsHttp,
+ repoIsLocal,
+ repoIsLocalBare,
+ repoIsLocalUnknown,
+ repoDescribe,
+ repoLocation,
+ repoPath,
+ localGitDir,
+ attributes,
+ hookPath,
+ assertLocal,
+) where
+
+import Network.URI (uriPath, uriScheme, unEscapeString)
+#ifndef mingw32_HOST_OS
+import System.Posix.Files
+#endif
+
+import Common
+import Git.Types
+#ifndef mingw32_HOST_OS
+import Utility.FileMode
+#endif
+
+{- User-visible description of a git repo. -}
+repoDescribe :: Repo -> String
+repoDescribe Repo { remoteName = Just name } = name
+repoDescribe Repo { location = Url url } = show url
+repoDescribe Repo { location = Local { worktree = Just dir } } = dir
+repoDescribe Repo { location = Local { gitdir = dir } } = dir
+repoDescribe Repo { location = LocalUnknown dir } = dir
+repoDescribe Repo { location = Unknown } = "UNKNOWN"
+
+{- Location of the repo, either as a path or url. -}
+repoLocation :: Repo -> String
+repoLocation Repo { location = Url url } = show url
+repoLocation Repo { location = Local { worktree = Just dir } } = dir
+repoLocation Repo { location = Local { gitdir = dir } } = dir
+repoLocation Repo { location = LocalUnknown dir } = dir
+repoLocation Repo { location = Unknown } = undefined
+
+{- Path to a repository. For non-bare, this is the worktree, for bare,
+ - it's the gitdir, and for URL repositories, is the path on the remote
+ - host. -}
+repoPath :: Repo -> FilePath
+repoPath Repo { location = Url u } = unEscapeString $ uriPath u
+repoPath Repo { location = Local { worktree = Just d } } = d
+repoPath Repo { location = Local { gitdir = d } } = d
+repoPath Repo { location = LocalUnknown dir } = dir
+repoPath Repo { location = Unknown } = undefined
+
+{- Path to a local repository's .git directory. -}
+localGitDir :: Repo -> FilePath
+localGitDir Repo { location = Local { gitdir = d } } = d
+localGitDir _ = undefined
+
+{- Some code needs to vary between URL and normal repos,
+ - or bare and non-bare, these functions help with that. -}
+repoIsUrl :: Repo -> Bool
+repoIsUrl Repo { location = Url _ } = True
+repoIsUrl _ = False
+
+repoIsSsh :: Repo -> Bool
+repoIsSsh Repo { location = Url url }
+ | scheme == "ssh:" = True
+ -- git treats these the same as ssh
+ | scheme == "git+ssh:" = True
+ | scheme == "ssh+git:" = True
+ | otherwise = False
+ where
+ scheme = uriScheme url
+repoIsSsh _ = False
+
+repoIsHttp :: Repo -> Bool
+repoIsHttp Repo { location = Url url }
+ | uriScheme url == "http:" = True
+ | uriScheme url == "https:" = True
+ | otherwise = False
+repoIsHttp _ = False
+
+repoIsLocal :: Repo -> Bool
+repoIsLocal Repo { location = Local { } } = True
+repoIsLocal _ = False
+
+repoIsLocalBare :: Repo -> Bool
+repoIsLocalBare Repo { location = Local { worktree = Nothing } } = True
+repoIsLocalBare _ = False
+
+repoIsLocalUnknown :: Repo -> Bool
+repoIsLocalUnknown Repo { location = LocalUnknown { } } = True
+repoIsLocalUnknown _ = False
+
+assertLocal :: Repo -> a -> a
+assertLocal repo action
+ | repoIsUrl repo = error $ unwords
+ [ "acting on non-local git repo"
+ , repoDescribe repo
+ , "not supported"
+ ]
+ | otherwise = action
+
+{- Path to a repository's gitattributes file. -}
+attributes :: Repo -> FilePath
+attributes repo
+ | repoIsLocalBare repo = repoPath repo ++ "/info/.gitattributes"
+ | otherwise = repoPath repo ++ "/.gitattributes"
+
+{- Path to a given hook script in a repository, only if the hook exists
+ - and is executable. -}
+hookPath :: String -> Repo -> IO (Maybe FilePath)
+hookPath script repo = do
+ let hook = localGitDir repo </> "hooks" </> script
+ ifM (catchBoolIO $ isexecutable hook)
+ ( return $ Just hook , return Nothing )
+ where
+#if mingw32_HOST_OS
+ isexecutable f = doesFileExist f
+#else
+ isexecutable f = isExecutable . fileMode <$> getFileStatus f
+#endif
diff --git a/Git/AutoCorrect.hs b/Git/AutoCorrect.hs
new file mode 100644
index 000000000..325632de9
--- /dev/null
+++ b/Git/AutoCorrect.hs
@@ -0,0 +1,71 @@
+{- git autocorrection using Damerau-Levenshtein edit distance
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Git.AutoCorrect where
+
+import Common
+import Git.Types
+import qualified Git.Config
+
+import Text.EditDistance
+import Control.Concurrent
+
+{- These are the same cost values as used in git. -}
+gitEditCosts :: EditCosts
+gitEditCosts = EditCosts
+ { deletionCosts = ConstantCost 4
+ , insertionCosts = ConstantCost 1
+ , substitutionCosts = ConstantCost 2
+ , transpositionCosts = ConstantCost 0
+ }
+
+{- Git's source calls this "an empirically derived magic number" -}
+similarityFloor :: Int
+similarityFloor = 7
+
+{- Finds inexact matches for the input amoung the choices.
+ - Returns an ordered list of good enough matches, or an empty list if
+ - nothing matches well. -}
+fuzzymatches :: String -> (c -> String) -> [c] -> [c]
+fuzzymatches input showchoice choices = fst $ unzip $
+ sortBy comparecost $ filter similarEnough $ zip choices costs
+ where
+ distance = restrictedDamerauLevenshteinDistance gitEditCosts input
+ costs = map (distance . showchoice) choices
+ comparecost a b = compare (snd a) (snd b)
+ similarEnough (_, cst) = cst < similarityFloor
+
+{- Takes action based on git's autocorrect configuration, in preparation for
+ - an autocorrected command being run. -}
+prepare :: String -> (c -> String) -> [c] -> Repo -> IO ()
+prepare input showmatch matches r =
+ case readish $ Git.Config.get "help.autocorrect" "0" r of
+ Just n
+ | n == 0 -> list
+ | n < 0 -> warn
+ | otherwise -> sleep n
+ Nothing -> list
+ where
+ list = error $ unlines $
+ [ "Unknown command '" ++ input ++ "'"
+ , ""
+ , "Did you mean one of these?"
+ ] ++ map (\m -> "\t" ++ showmatch m) matches
+ warn =
+ hPutStr stderr $ unlines
+ [ "WARNING: You called a command named '" ++
+ input ++ "', which does not exist."
+ , "Continuing under the assumption that you meant '" ++
+ showmatch (Prelude.head matches) ++ "'"
+ ]
+ sleep n = do
+ warn
+ hPutStrLn stderr $ unwords
+ [ "in"
+ , show (fromIntegral n / 10 :: Float)
+ , "seconds automatically..."]
+ threadDelay (n * 100000) -- deciseconds to microseconds
diff --git a/Git/Branch.hs b/Git/Branch.hs
new file mode 100644
index 000000000..7b3297d74
--- /dev/null
+++ b/Git/Branch.hs
@@ -0,0 +1,133 @@
+{- git branch stuff
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE BangPatterns #-}
+
+module Git.Branch where
+
+import Common
+import Git
+import Git.Sha
+import Git.Command
+import qualified Git.Ref
+
+{- The currently checked out branch.
+ -
+ - In a just initialized git repo before the first commit,
+ - symbolic-ref will show the master branch, even though that
+ - branch is not created yet. So, this also looks at show-ref HEAD
+ - to double-check.
+ -}
+current :: Repo -> IO (Maybe Git.Ref)
+current r = do
+ v <- currentUnsafe r
+ case v of
+ Nothing -> return Nothing
+ Just branch ->
+ ifM (null <$> pipeReadStrict [Param "show-ref", Param $ show branch] r)
+ ( return Nothing
+ , return v
+ )
+
+{- The current branch, which may not really exist yet. -}
+currentUnsafe :: Repo -> IO (Maybe Git.Ref)
+currentUnsafe r = parse . firstLine
+ <$> pipeReadStrict [Param "symbolic-ref", Param $ show Git.Ref.headRef] r
+ where
+ parse l
+ | null l = Nothing
+ | otherwise = Just $ Git.Ref l
+
+{- Checks if the second branch has any commits not present on the first
+ - branch. -}
+changed :: Branch -> Branch -> Repo -> IO Bool
+changed origbranch newbranch repo
+ | origbranch == newbranch = return False
+ | otherwise = not . null <$> diffs
+ where
+ diffs = pipeReadStrict
+ [ Param "log"
+ , Param (show origbranch ++ ".." ++ show newbranch)
+ , Params "--oneline -n1"
+ ] repo
+
+{- Given a set of refs that are all known to have commits not
+ - on the branch, tries to update the branch by a fast-forward.
+ -
+ - In order for that to be possible, one of the refs must contain
+ - every commit present in all the other refs.
+ -}
+fastForward :: Branch -> [Ref] -> Repo -> IO Bool
+fastForward _ [] _ = return True
+fastForward branch (first:rest) repo =
+ -- First, check that the branch does not contain any
+ -- new commits that are not in the first ref. If it does,
+ -- cannot fast-forward.
+ ifM (changed first branch repo)
+ ( no_ff
+ , maybe no_ff do_ff =<< findbest first rest
+ )
+ where
+ no_ff = return False
+ do_ff to = do
+ run [Param "update-ref", Param $ show branch, Param $ show to] repo
+ return True
+ findbest c [] = return $ Just c
+ findbest c (r:rs)
+ | c == r = findbest c rs
+ | otherwise = do
+ better <- changed c r repo
+ worse <- changed r c repo
+ case (better, worse) of
+ (True, True) -> return Nothing -- divergent fail
+ (True, False) -> findbest r rs -- better
+ (False, True) -> findbest c rs -- worse
+ (False, False) -> findbest c rs -- same
+
+{- Commits the index into the specified branch (or other ref),
+ - with the specified parent refs, and returns the committed sha -}
+commit :: String -> Branch -> [Ref] -> Repo -> IO Sha
+commit message branch parentrefs repo = do
+ tree <- getSha "write-tree" $
+ pipeReadStrict [Param "write-tree"] repo
+ sha <- getSha "commit-tree" $ pipeWriteRead
+ (map Param $ ["commit-tree", show tree] ++ ps)
+ (Just $ flip hPutStr message) repo
+ update branch sha repo
+ return sha
+ where
+ ps = concatMap (\r -> ["-p", show r]) parentrefs
+
+{- A leading + makes git-push force pushing a branch. -}
+forcePush :: String -> String
+forcePush b = "+" ++ b
+
+{- Updates a branch (or other ref) to a new Sha. -}
+update :: Branch -> Sha -> Repo -> IO ()
+update branch sha = run
+ [ Param "update-ref"
+ , Param $ show branch
+ , Param $ show sha
+ ]
+
+{- Checks out a branch, creating it if necessary. -}
+checkout :: Branch -> Repo -> IO ()
+checkout branch = run
+ [ Param "checkout"
+ , Param "-q"
+ , Param "-B"
+ , Param $ show $ Git.Ref.base branch
+ ]
+
+{- Removes a branch. -}
+delete :: Branch -> Repo -> IO ()
+delete branch = run
+ [ Param "branch"
+ , Param "-q"
+ , Param "-D"
+ , Param $ show $ Git.Ref.base branch
+ ]
diff --git a/Git/BuildVersion.hs b/Git/BuildVersion.hs
new file mode 100644
index 000000000..832ee8ab7
--- /dev/null
+++ b/Git/BuildVersion.hs
@@ -0,0 +1,21 @@
+{- git build version
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Git.BuildVersion where
+
+import Git.Version
+import qualified Build.SysConfig
+
+{- Using the version it was configured for avoids running git to check its
+ - version, at the cost that upgrading git won't be noticed.
+ - This is only acceptable because it's rare that git's version influences
+ - code's behavior. -}
+buildVersion :: GitVersion
+buildVersion = normalize Build.SysConfig.gitversion
+
+older :: String -> Bool
+older n = buildVersion < normalize n
diff --git a/Git/CatFile.hs b/Git/CatFile.hs
new file mode 100644
index 000000000..aee6bd19f
--- /dev/null
+++ b/Git/CatFile.hs
@@ -0,0 +1,108 @@
+{- git cat-file interface
+ -
+ - Copyright 2011, 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Git.CatFile (
+ CatFileHandle,
+ catFileStart,
+ catFileStart',
+ catFileStop,
+ catFile,
+ catTree,
+ catObject,
+ catObjectDetails,
+) where
+
+import System.IO
+import qualified Data.ByteString as S
+import qualified Data.ByteString.Lazy as L
+import Data.Tuple.Utils
+import Numeric
+import System.Posix.Types
+
+import Common
+import Git
+import Git.Sha
+import Git.Command
+import Git.Types
+import Git.FilePath
+import qualified Utility.CoProcess as CoProcess
+
+data CatFileHandle = CatFileHandle CoProcess.CoProcessHandle Repo
+
+catFileStart :: Repo -> IO CatFileHandle
+catFileStart = catFileStart' True
+
+catFileStart' :: Bool -> Repo -> IO CatFileHandle
+catFileStart' restartable repo = do
+ coprocess <- CoProcess.rawMode =<< gitCoProcessStart restartable
+ [ Param "cat-file"
+ , Param "--batch"
+ ] repo
+ return $ CatFileHandle coprocess repo
+
+catFileStop :: CatFileHandle -> IO ()
+catFileStop (CatFileHandle p _) = CoProcess.stop p
+
+{- Reads a file from a specified branch. -}
+catFile :: CatFileHandle -> Branch -> FilePath -> IO L.ByteString
+catFile h branch file = catObject h $ Ref $
+ show branch ++ ":" ++ toInternalGitPath file
+
+{- Uses a running git cat-file read the content of an object.
+ - Objects that do not exist will have "" returned. -}
+catObject :: CatFileHandle -> Ref -> IO L.ByteString
+catObject h object = maybe L.empty fst3 <$> catObjectDetails h object
+
+catObjectDetails :: CatFileHandle -> Ref -> IO (Maybe (L.ByteString, Sha, ObjectType))
+catObjectDetails (CatFileHandle hdl _) object = CoProcess.query hdl send receive
+ where
+ query = show object
+ send to = hPutStrLn to query
+ receive from = do
+ header <- hGetLine from
+ case words header of
+ [sha, objtype, size]
+ | length sha == shaSize ->
+ case (readObjectType objtype, reads size) of
+ (Just t, [(bytes, "")]) -> readcontent t bytes from sha
+ _ -> dne
+ | otherwise -> dne
+ _
+ | header == show object ++ " missing" -> dne
+ | otherwise -> error $ "unknown response from git cat-file " ++ show (header, object)
+ readcontent objtype bytes from sha = do
+ content <- S.hGet from bytes
+ eatchar '\n' from
+ return $ Just (L.fromChunks [content], Ref sha, objtype)
+ dne = return Nothing
+ eatchar expected from = do
+ c <- hGetChar from
+ when (c /= expected) $
+ error $ "missing " ++ (show expected) ++ " from git cat-file"
+
+{- Gets a list of files and directories in a tree. (Not recursive.) -}
+catTree :: CatFileHandle -> Ref -> IO [(FilePath, FileMode)]
+catTree h treeref = go <$> catObjectDetails h treeref
+ where
+ go (Just (b, _, TreeObject)) = parsetree [] b
+ go _ = []
+
+ parsetree c b = case L.break (== 0) b of
+ (modefile, rest)
+ | L.null modefile -> c
+ | otherwise -> parsetree
+ (parsemodefile modefile:c)
+ (dropsha rest)
+
+ -- these 20 bytes after the NUL hold the file's sha
+ -- TODO: convert from raw form to regular sha
+ dropsha = L.drop 21
+
+ parsemodefile b =
+ let (modestr, file) = separate (== ' ') (encodeW8 $ L.unpack b)
+ in (file, readmode modestr)
+ readmode = fst . fromMaybe (0, undefined) . headMaybe . readOct
diff --git a/Git/CheckAttr.hs b/Git/CheckAttr.hs
new file mode 100644
index 000000000..94ead5b4c
--- /dev/null
+++ b/Git/CheckAttr.hs
@@ -0,0 +1,93 @@
+{- git check-attr interface
+ -
+ - Copyright 2010-2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Git.CheckAttr where
+
+import Common
+import Git
+import Git.Command
+import qualified Git.BuildVersion
+import qualified Utility.CoProcess as CoProcess
+
+import System.IO.Error
+
+type CheckAttrHandle = (CoProcess.CoProcessHandle, [Attr], String)
+
+type Attr = String
+
+{- Starts git check-attr running to look up the specified gitattributes
+ - values and returns a handle. -}
+checkAttrStart :: [Attr] -> Repo -> IO CheckAttrHandle
+checkAttrStart attrs repo = do
+ cwd <- getCurrentDirectory
+ h <- CoProcess.rawMode =<< gitCoProcessStart True params repo
+ return (h, attrs, cwd)
+ where
+ params =
+ [ Param "check-attr"
+ , Params "-z --stdin"
+ ] ++ map Param attrs ++
+ [ Param "--" ]
+
+checkAttrStop :: CheckAttrHandle -> IO ()
+checkAttrStop (h, _, _) = CoProcess.stop h
+
+{- Gets an attribute of a file. -}
+checkAttr :: CheckAttrHandle -> Attr -> FilePath -> IO String
+checkAttr (h, attrs, cwd) want file = do
+ pairs <- CoProcess.query h send (receive "")
+ let vals = map snd $ filter (\(attr, _) -> attr == want) pairs
+ case vals of
+ [v] -> return v
+ _ -> error $ "unable to determine " ++ want ++ " attribute of " ++ file
+ where
+ send to = hPutStr to $ file' ++ "\0"
+ receive c from = do
+ s <- hGetSomeString from 1024
+ if null s
+ then eofError
+ else do
+ let v = c ++ s
+ maybe (receive v from) return (parse v)
+ eofError = ioError $ mkIOError userErrorType "git check-attr EOF" Nothing Nothing
+ parse s
+ -- new null separated output
+ | '\0' `elem` s = if "\0" `isSuffixOf` s
+ then
+ let bits = segment (== '\0') s
+ in if length bits == (numattrs * 3) + 1
+ then Just $ getattrvalues bits []
+ else Nothing -- more attributes to come
+ else Nothing -- output incomplete
+ -- old one line per value output
+ | otherwise = if "\n" `isSuffixOf` s
+ then
+ let ls = lines s
+ in if length ls == numattrs
+ then Just $ map (\(attr, val) -> (attr, oldattrvalue attr val))
+ (zip attrs ls)
+ else Nothing -- more attributes to come
+ else Nothing -- line incomplete
+ numattrs = length attrs
+
+ {- Before git 1.7.7, git check-attr worked best with
+ - absolute filenames; using them worked around some bugs
+ - with relative filenames.
+ -
+ - With newer git, git check-attr chokes on some absolute
+ - filenames, and the bugs that necessitated them were fixed,
+ - so use relative filenames. -}
+ oldgit = Git.BuildVersion.older "1.7.7"
+ file'
+ | oldgit = absPathFrom cwd file
+ | otherwise = relPathDirToFile cwd $ absPathFrom cwd file
+ oldattrvalue attr l = end bits !! 0
+ where
+ bits = split sep l
+ sep = ": " ++ attr ++ ": "
+ getattrvalues (_filename:attr:val:rest) c = getattrvalues rest ((attr,val):c)
+ getattrvalues _ c = c
diff --git a/Git/CheckIgnore.hs b/Git/CheckIgnore.hs
new file mode 100644
index 000000000..2ab7cb3dc
--- /dev/null
+++ b/Git/CheckIgnore.hs
@@ -0,0 +1,71 @@
+{- git check-ignore interface
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Git.CheckIgnore (
+ CheckIgnoreHandle,
+ checkIgnoreStart,
+ checkIgnoreStop,
+ checkIgnored
+) where
+
+import Common
+import Git
+import Git.Command
+import qualified Git.Version
+import qualified Utility.CoProcess as CoProcess
+
+import System.IO.Error
+
+type CheckIgnoreHandle = CoProcess.CoProcessHandle
+
+{- Starts git check-ignore running, and returns a handle.
+ -
+ - This relies on git check-ignore --non-matching -v outputting
+ - lines for both matching an non-matching files. Also relies on
+ - GIT_FLUSH behavior flushing the output buffer when git check-ignore
+ - is piping to us.
+ -
+ - The first version of git to support what we need is 1.8.4.
+ - Nothing is returned if an older git is installed.
+ -}
+checkIgnoreStart :: Repo -> IO (Maybe CheckIgnoreHandle)
+checkIgnoreStart repo = ifM supportedGitVersion
+ ( Just <$> (CoProcess.rawMode =<< gitCoProcessStart True params repo)
+ , return Nothing
+ )
+ where
+ params =
+ [ Param "check-ignore"
+ , Params "-z --stdin --verbose --non-matching"
+ ]
+
+supportedGitVersion :: IO Bool
+supportedGitVersion = do
+ v <- Git.Version.installed
+ return $ v >= Git.Version.normalize "1.8.4"
+
+checkIgnoreStop :: CheckIgnoreHandle -> IO ()
+checkIgnoreStop = CoProcess.stop
+
+{- Returns True if a file is ignored. -}
+checkIgnored :: CheckIgnoreHandle -> FilePath -> IO Bool
+checkIgnored h file = CoProcess.query h send (receive "")
+ where
+ send to = do
+ hPutStr to $ file ++ "\0"
+ hFlush to
+ receive c from = do
+ s <- hGetSomeString from 1024
+ if null s
+ then eofError
+ else do
+ let v = c ++ s
+ maybe (receive v from) return (parse v)
+ parse s = case segment (== '\0') s of
+ (_source:_line:pattern:_pathname:_eol:[]) -> Just $ not $ null pattern
+ _ -> Nothing
+ eofError = ioError $ mkIOError userErrorType "git cat-file EOF" Nothing Nothing
diff --git a/Git/Command.hs b/Git/Command.hs
new file mode 100644
index 000000000..adcc53bcd
--- /dev/null
+++ b/Git/Command.hs
@@ -0,0 +1,138 @@
+{- running git commands
+ -
+ - Copyright 2010-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Git.Command where
+
+import System.Process (std_out, env)
+
+import Common
+import Git
+import Git.Types
+import qualified Utility.CoProcess as CoProcess
+#ifdef mingw32_HOST_OS
+import Git.FilePath
+#endif
+
+{- Constructs a git command line operating on the specified repo. -}
+gitCommandLine :: [CommandParam] -> Repo -> [CommandParam]
+gitCommandLine params r@(Repo { location = l@(Local _ _ ) }) =
+ setdir : settree ++ gitGlobalOpts r ++ params
+ where
+ setdir = Param $ "--git-dir=" ++ gitpath (gitdir l)
+ settree = case worktree l of
+ Nothing -> []
+ Just t -> [Param $ "--work-tree=" ++ gitpath t]
+#ifdef mingw32_HOST_OS
+ -- despite running on windows, msysgit wants a unix-formatted path
+ gitpath s
+ | isAbsolute s = "/" ++ dropDrive (toInternalGitPath s)
+ | otherwise = s
+#else
+ gitpath = id
+#endif
+gitCommandLine _ repo = assertLocal repo $ error "internal"
+
+{- Runs git in the specified repo. -}
+runBool :: [CommandParam] -> Repo -> IO Bool
+runBool params repo = assertLocal repo $
+ boolSystemEnv "git"
+ (gitCommandLine params repo)
+ (gitEnv repo)
+
+{- Runs git in the specified repo, throwing an error if it fails. -}
+run :: [CommandParam] -> Repo -> IO ()
+run params repo = assertLocal repo $
+ unlessM (runBool params repo) $
+ error $ "git " ++ show params ++ " failed"
+
+{- Runs git and forces it to be quiet, throwing an error if it fails. -}
+runQuiet :: [CommandParam] -> Repo -> IO ()
+runQuiet params repo = withQuietOutput createProcessSuccess $
+ (proc "git" $ toCommand $ gitCommandLine (params) repo)
+ { env = gitEnv repo }
+
+{- Runs a git command and returns its output, lazily.
+ -
+ - Also returns an action that should be used when the output is all
+ - read (or no more is needed), that will wait on the command, and
+ - return True if it succeeded. Failure to wait will result in zombies.
+ -}
+pipeReadLazy :: [CommandParam] -> Repo -> IO (String, IO Bool)
+pipeReadLazy params repo = assertLocal repo $ do
+ (_, Just h, _, pid) <- createProcess p { std_out = CreatePipe }
+ fileEncoding h
+ c <- hGetContents h
+ return (c, checkSuccessProcess pid)
+ where
+ p = gitCreateProcess params repo
+
+{- Runs a git command, and returns its output, strictly.
+ -
+ - Nonzero exit status is ignored.
+ -}
+pipeReadStrict :: [CommandParam] -> Repo -> IO String
+pipeReadStrict params repo = assertLocal repo $
+ withHandle StdoutHandle (createProcessChecked ignoreFailureProcess) p $ \h -> do
+ fileEncoding h
+ output <- hGetContentsStrict h
+ hClose h
+ return output
+ where
+ p = gitCreateProcess params repo
+
+{- Runs a git command, feeding it an input, and returning its output,
+ - which is expected to be fairly small, since it's all read into memory
+ - strictly. -}
+pipeWriteRead :: [CommandParam] -> Maybe (Handle -> IO ()) -> Repo -> IO String
+pipeWriteRead params writer repo = assertLocal repo $
+ writeReadProcessEnv "git" (toCommand $ gitCommandLine params repo)
+ (gitEnv repo) writer (Just adjusthandle)
+ where
+ adjusthandle h = do
+ fileEncoding h
+ hSetNewlineMode h noNewlineTranslation
+
+{- Runs a git command, feeding it input on a handle with an action. -}
+pipeWrite :: [CommandParam] -> Repo -> (Handle -> IO ()) -> IO ()
+pipeWrite params repo = withHandle StdinHandle createProcessSuccess $
+ gitCreateProcess params repo
+
+{- Reads null terminated output of a git command (as enabled by the -z
+ - parameter), and splits it. -}
+pipeNullSplit :: [CommandParam] -> Repo -> IO ([String], IO Bool)
+pipeNullSplit params repo = do
+ (s, cleanup) <- pipeReadLazy params repo
+ return (filter (not . null) $ split sep s, cleanup)
+ where
+ sep = "\0"
+
+pipeNullSplitStrict :: [CommandParam] -> Repo -> IO [String]
+pipeNullSplitStrict params repo = do
+ s <- pipeReadStrict params repo
+ return $ filter (not . null) $ split sep s
+ where
+ sep = "\0"
+
+pipeNullSplitZombie :: [CommandParam] -> Repo -> IO [String]
+pipeNullSplitZombie params repo = leaveZombie <$> pipeNullSplit params repo
+
+{- Doesn't run the cleanup action. A zombie results. -}
+leaveZombie :: (a, IO Bool) -> a
+leaveZombie = fst
+
+{- Runs a git command as a coprocess. -}
+gitCoProcessStart :: Bool -> [CommandParam] -> Repo -> IO CoProcess.CoProcessHandle
+gitCoProcessStart restartable params repo = CoProcess.start restartable "git"
+ (toCommand $ gitCommandLine params repo)
+ (gitEnv repo)
+
+gitCreateProcess :: [CommandParam] -> Repo -> CreateProcess
+gitCreateProcess params repo =
+ (proc "git" $ toCommand $ gitCommandLine params repo)
+ { env = gitEnv repo }
diff --git a/Git/Config.hs b/Git/Config.hs
new file mode 100644
index 000000000..b5c1be04a
--- /dev/null
+++ b/Git/Config.hs
@@ -0,0 +1,198 @@
+{- git repository configuration handling
+ -
+ - Copyright 2010-2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Git.Config where
+
+import qualified Data.Map as M
+import Data.Char
+import System.Process (cwd, env)
+import Control.Exception.Extensible
+
+import Common
+import Git
+import Git.Types
+import qualified Git.Construct
+import Utility.UserInfo
+
+{- Returns a single git config setting, or a default value if not set. -}
+get :: String -> String -> Repo -> String
+get key defaultValue repo = M.findWithDefault defaultValue key (config repo)
+
+{- Returns a list with each line of a multiline config setting. -}
+getList :: String -> Repo -> [String]
+getList key repo = M.findWithDefault [] key (fullconfig repo)
+
+{- Returns a single git config setting, if set. -}
+getMaybe :: String -> Repo -> Maybe String
+getMaybe key repo = M.lookup key (config repo)
+
+{- Runs git config and populates a repo with its config.
+ - Avoids re-reading config when run repeatedly. -}
+read :: Repo -> IO Repo
+read repo@(Repo { config = c })
+ | c == M.empty = read' repo
+ | otherwise = return repo
+
+{- Reads config even if it was read before. -}
+reRead :: Repo -> IO Repo
+reRead r = read' $ r
+ { config = M.empty
+ , fullconfig = M.empty
+ }
+
+{- Cannot use pipeRead because it relies on the config having been already
+ - read. Instead, chdir to the repo and run git config.
+ -}
+read' :: Repo -> IO Repo
+read' repo = go repo
+ where
+ go Repo { location = Local { gitdir = d } } = git_config d
+ go Repo { location = LocalUnknown d } = git_config d
+ go _ = assertLocal repo $ error "internal"
+ git_config d = withHandle StdoutHandle createProcessSuccess p $
+ hRead repo
+ where
+ params = ["config", "--null", "--list"]
+ p = (proc "git" params)
+ { cwd = Just d
+ , env = gitEnv repo
+ }
+
+{- Gets the global git config, returning a dummy Repo containing it. -}
+global :: IO (Maybe Repo)
+global = do
+ home <- myHomeDir
+ ifM (doesFileExist $ home </> ".gitconfig")
+ ( do
+ repo <- Git.Construct.fromUnknown
+ repo' <- withHandle StdoutHandle createProcessSuccess p $
+ hRead repo
+ return $ Just repo'
+ , return Nothing
+ )
+ where
+ params = ["config", "--null", "--list", "--global"]
+ p = (proc "git" params)
+
+{- Reads git config from a handle and populates a repo with it. -}
+hRead :: Repo -> Handle -> IO Repo
+hRead repo h = do
+ -- We use the FileSystemEncoding when reading from git-config,
+ -- because it can contain arbitrary filepaths (and other strings)
+ -- in any encoding.
+ fileEncoding h
+ val <- hGetContentsStrict h
+ store val repo
+
+{- Stores a git config into a Repo, returning the new version of the Repo.
+ - The git config may be multiple lines, or a single line.
+ - Config settings can be updated incrementally.
+ -}
+store :: String -> Repo -> IO Repo
+store s repo = do
+ let c = parse s
+ repo' <- updateLocation $ repo
+ { config = (M.map Prelude.head c) `M.union` config repo
+ , fullconfig = M.unionWith (++) c (fullconfig repo)
+ }
+ rs <- Git.Construct.fromRemotes repo'
+ return $ repo' { remotes = rs }
+
+{- Updates the location of a repo, based on its configuration.
+ -
+ - Git.Construct makes LocalUknown repos, of which only a directory is
+ - known. Once the config is read, this can be fixed up to a Local repo,
+ - based on the core.bare and core.worktree settings.
+ -}
+updateLocation :: Repo -> IO Repo
+updateLocation r@(Repo { location = LocalUnknown d })
+ | isBare r = ifM (doesDirectoryExist dotgit)
+ ( updateLocation' r $ Local dotgit Nothing
+ , updateLocation' r $ Local d Nothing
+ )
+ | otherwise = updateLocation' r $ Local dotgit (Just d)
+ where
+ dotgit = (d </> ".git")
+updateLocation r@(Repo { location = l@(Local {}) }) = updateLocation' r l
+updateLocation r = return r
+
+updateLocation' :: Repo -> RepoLocation -> IO Repo
+updateLocation' r l = do
+ l' <- case getMaybe "core.worktree" r of
+ Nothing -> return l
+ Just d -> do
+ {- core.worktree is relative to the gitdir -}
+ top <- absPath $ gitdir l
+ return $ l { worktree = Just $ absPathFrom top d }
+ return $ r { location = l' }
+
+{- Parses git config --list or git config --null --list output into a
+ - config map. -}
+parse :: String -> M.Map String [String]
+parse [] = M.empty
+parse s
+ -- --list output will have an = in the first line
+ | all ('=' `elem`) (take 1 ls) = sep '=' ls
+ -- --null --list output separates keys from values with newlines
+ | otherwise = sep '\n' $ split "\0" s
+ where
+ ls = lines s
+ sep c = M.fromListWith (++) . map (\(k,v) -> (k, [v])) .
+ map (separate (== c))
+
+{- Checks if a string from git config is a true value. -}
+isTrue :: String -> Maybe Bool
+isTrue s
+ | s' == "true" = Just True
+ | s' == "false" = Just False
+ | otherwise = Nothing
+ where
+ s' = map toLower s
+
+boolConfig :: Bool -> String
+boolConfig True = "true"
+boolConfig False = "false"
+
+isBare :: Repo -> Bool
+isBare r = fromMaybe False $ isTrue =<< getMaybe coreBare r
+
+coreBare :: String
+coreBare = "core.bare"
+
+{- Runs a command to get the configuration of a repo,
+ - and returns a repo populated with the configuration, as well as the raw
+ - output of the command. -}
+fromPipe :: Repo -> String -> [CommandParam] -> IO (Either SomeException (Repo, String))
+fromPipe r cmd params = try $
+ withHandle StdoutHandle createProcessSuccess p $ \h -> do
+ fileEncoding h
+ val <- hGetContentsStrict h
+ r' <- store val r
+ return (r', val)
+ where
+ p = proc cmd $ toCommand params
+
+{- Reads git config from a specified file and returns the repo populated
+ - with the configuration. -}
+fromFile :: Repo -> FilePath -> IO (Either SomeException (Repo, String))
+fromFile r f = fromPipe r "git"
+ [ Param "config"
+ , Param "--file"
+ , File f
+ , Param "--list"
+ ]
+
+{- Changes a git config setting in the specified config file.
+ - (Creates the file if it does not already exist.) -}
+changeFile :: FilePath -> String -> String -> IO Bool
+changeFile f k v = boolSystem "git"
+ [ Param "config"
+ , Param "--file"
+ , File f
+ , Param k
+ , Param v
+ ]
diff --git a/Git/Construct.hs b/Git/Construct.hs
new file mode 100644
index 000000000..71a13f49f
--- /dev/null
+++ b/Git/Construct.hs
@@ -0,0 +1,236 @@
+{- Construction of Git Repo objects
+ -
+ - Copyright 2010-2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Git.Construct (
+ fromCwd,
+ fromAbsPath,
+ fromPath,
+ fromUrl,
+ fromUnknown,
+ localToUrl,
+ remoteNamed,
+ remoteNamedFromKey,
+ fromRemotes,
+ fromRemoteLocation,
+ repoAbsPath,
+ newFrom,
+ checkForRepo,
+) where
+
+#ifndef mingw32_HOST_OS
+import System.Posix.User
+#endif
+import qualified Data.Map as M hiding (map, split)
+import Network.URI
+
+import Common
+import Git.Types
+import Git
+import Git.Remote
+import qualified Git.Url as Url
+import Utility.UserInfo
+
+{- Finds the git repository used for the cwd, which may be in a parent
+ - directory. -}
+fromCwd :: IO (Maybe Repo)
+fromCwd = getCurrentDirectory >>= seekUp
+ where
+ seekUp dir = do
+ r <- checkForRepo dir
+ case r of
+ Nothing -> case parentDir dir of
+ "" -> return Nothing
+ d -> seekUp d
+ Just loc -> Just <$> newFrom loc
+
+{- Local Repo constructor, accepts a relative or absolute path. -}
+fromPath :: FilePath -> IO Repo
+fromPath dir = fromAbsPath =<< absPath dir
+
+{- Local Repo constructor, requires an absolute path to the repo be
+ - specified. -}
+fromAbsPath :: FilePath -> IO Repo
+fromAbsPath dir
+ | isAbsolute dir = ifM (doesDirectoryExist dir') ( ret dir' , hunt )
+ | otherwise =
+ error $ "internal error, " ++ dir ++ " is not absolute"
+ where
+ ret = newFrom . LocalUnknown
+ {- Git always looks for "dir.git" in preference to
+ - to "dir", even if dir ends in a "/". -}
+ canondir = dropTrailingPathSeparator dir
+ dir' = canondir ++ ".git"
+ {- When dir == "foo/.git", git looks for "foo/.git/.git",
+ - and failing that, uses "foo" as the repository. -}
+ hunt
+ | (pathSeparator:".git") `isSuffixOf` canondir =
+ ifM (doesDirectoryExist $ dir </> ".git")
+ ( ret dir
+ , ret $ takeDirectory canondir
+ )
+ | otherwise = ret dir
+
+{- Remote Repo constructor. Throws exception on invalid url.
+ -
+ - Git is somewhat forgiving about urls to repositories, allowing
+ - eg spaces that are not normally allowed unescaped in urls.
+ -}
+fromUrl :: String -> IO Repo
+fromUrl url
+ | not (isURI url) = fromUrlStrict $ escapeURIString isUnescapedInURI url
+ | otherwise = fromUrlStrict url
+
+fromUrlStrict :: String -> IO Repo
+fromUrlStrict url
+ | startswith "file://" url = fromAbsPath $ unEscapeString $ uriPath u
+ | otherwise = newFrom $ Url u
+ where
+ u = fromMaybe bad $ parseURI url
+ bad = error $ "bad url " ++ url
+
+{- Creates a repo that has an unknown location. -}
+fromUnknown :: IO Repo
+fromUnknown = newFrom Unknown
+
+{- Converts a local Repo into a remote repo, using the reference repo
+ - which is assumed to be on the same host. -}
+localToUrl :: Repo -> Repo -> Repo
+localToUrl reference r
+ | not $ repoIsUrl reference = error "internal error; reference repo not url"
+ | repoIsUrl r = r
+ | otherwise = case Url.authority reference of
+ Nothing -> r
+ Just auth ->
+ let absurl = concat
+ [ Url.scheme reference
+ , "//"
+ , auth
+ , repoPath r
+ ]
+ in r { location = Url $ fromJust $ parseURI absurl }
+
+{- Calculates a list of a repo's configured remotes, by parsing its config. -}
+fromRemotes :: Repo -> IO [Repo]
+fromRemotes repo = mapM construct remotepairs
+ where
+ filterconfig f = filter f $ M.toList $ config repo
+ filterkeys f = filterconfig (\(k,_) -> f k)
+ remotepairs = filterkeys isremote
+ isremote k = startswith "remote." k && endswith ".url" k
+ construct (k,v) = remoteNamedFromKey k $ fromRemoteLocation v repo
+
+{- Sets the name of a remote when constructing the Repo to represent it. -}
+remoteNamed :: String -> IO Repo -> IO Repo
+remoteNamed n constructor = do
+ r <- constructor
+ return $ r { remoteName = Just n }
+
+{- Sets the name of a remote based on the git config key, such as
+ - "remote.foo.url". -}
+remoteNamedFromKey :: String -> IO Repo -> IO Repo
+remoteNamedFromKey k = remoteNamed basename
+ where
+ basename = intercalate "." $
+ reverse $ drop 1 $ reverse $ drop 1 $ split "." k
+
+{- Constructs a new Repo for one of a Repo's remotes using a given
+ - location (ie, an url). -}
+fromRemoteLocation :: String -> Repo -> IO Repo
+fromRemoteLocation s repo = gen $ parseRemoteLocation s repo
+ where
+ gen (RemotePath p) = fromRemotePath p repo
+ gen (RemoteUrl u) = fromUrl u
+
+{- Constructs a Repo from the path specified in the git remotes of
+ - another Repo. -}
+fromRemotePath :: FilePath -> Repo -> IO Repo
+fromRemotePath dir repo = do
+ dir' <- expandTilde dir
+ fromAbsPath $ repoPath repo </> dir'
+
+{- Git remotes can have a directory that is specified relative
+ - to the user's home directory, or that contains tilde expansions.
+ - This converts such a directory to an absolute path.
+ - Note that it has to run on the system where the remote is.
+ -}
+repoAbsPath :: FilePath -> IO FilePath
+repoAbsPath d = do
+ d' <- expandTilde d
+ h <- myHomeDir
+ return $ h </> d'
+
+expandTilde :: FilePath -> IO FilePath
+#ifdef mingw32_HOST_OS
+expandTilde = return
+#else
+expandTilde = expandt True
+ where
+ expandt _ [] = return ""
+ expandt _ ('/':cs) = do
+ v <- expandt True cs
+ return ('/':v)
+ expandt True ('~':'/':cs) = do
+ h <- myHomeDir
+ return $ h </> cs
+ expandt True ('~':cs) = do
+ let (name, rest) = findname "" cs
+ u <- getUserEntryForName name
+ return $ homeDirectory u </> rest
+ expandt _ (c:cs) = do
+ v <- expandt False cs
+ return (c:v)
+ findname n [] = (n, "")
+ findname n (c:cs)
+ | c == '/' = (n, cs)
+ | otherwise = findname (n++[c]) cs
+#endif
+
+{- Checks if a git repository exists in a directory. Does not find
+ - git repositories in parent directories. -}
+checkForRepo :: FilePath -> IO (Maybe RepoLocation)
+checkForRepo dir =
+ check isRepo $
+ check gitDirFile $
+ check isBareRepo $
+ return Nothing
+ where
+ check test cont = maybe cont (return . Just) =<< test
+ checkdir c = ifM c
+ ( return $ Just $ LocalUnknown dir
+ , return Nothing
+ )
+ isRepo = checkdir $ gitSignature $ ".git" </> "config"
+ isBareRepo = checkdir $ gitSignature "config"
+ <&&> doesDirectoryExist (dir </> "objects")
+ gitDirFile = do
+ c <- firstLine <$>
+ catchDefaultIO "" (readFile $ dir </> ".git")
+ return $ if gitdirprefix `isPrefixOf` c
+ then Just $ Local
+ { gitdir = absPathFrom dir $
+ drop (length gitdirprefix) c
+ , worktree = Just dir
+ }
+ else Nothing
+ where
+ gitdirprefix = "gitdir: "
+ gitSignature file = doesFileExist $ dir </> file
+
+newFrom :: RepoLocation -> IO Repo
+newFrom l = return Repo
+ { location = l
+ , config = M.empty
+ , fullconfig = M.empty
+ , remotes = []
+ , remoteName = Nothing
+ , gitEnv = Nothing
+ , gitGlobalOpts = []
+ }
+
+
diff --git a/Git/CurrentRepo.hs b/Git/CurrentRepo.hs
new file mode 100644
index 000000000..ee91a6b81
--- /dev/null
+++ b/Git/CurrentRepo.hs
@@ -0,0 +1,67 @@
+{- The current git repository.
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Git.CurrentRepo where
+
+import Common
+import Git.Types
+import Git.Construct
+import qualified Git.Config
+#ifndef mingw32_HOST_OS
+import Utility.Env
+#endif
+
+{- Gets the current git repository.
+ -
+ - Honors GIT_DIR and GIT_WORK_TREE.
+ - Both environment variables are unset, to avoid confusing other git
+ - commands that also look at them. Instead, the Git module passes
+ - --work-tree and --git-dir to git commands it runs.
+ -
+ - When GIT_WORK_TREE or core.worktree are set, changes the working
+ - directory if necessary to ensure it is within the repository's work
+ - tree. While not needed for git commands, this is useful for anything
+ - else that looks for files in the worktree.
+ -}
+get :: IO Repo
+get = do
+ gd <- pathenv "GIT_DIR"
+ r <- configure gd =<< fromCwd
+ wt <- maybe (worktree $ location r) Just <$> pathenv "GIT_WORK_TREE"
+ case wt of
+ Nothing -> return r
+ Just d -> do
+ cwd <- getCurrentDirectory
+ unless (d `dirContains` cwd) $
+ setCurrentDirectory d
+ return $ addworktree wt r
+ where
+#ifndef mingw32_HOST_OS
+ pathenv s = do
+ v <- getEnv s
+ case v of
+ Just d -> do
+ void $ unsetEnv s
+ Just <$> absPath d
+ Nothing -> return Nothing
+#else
+ pathenv _ = return Nothing
+#endif
+
+ configure Nothing (Just r) = Git.Config.read r
+ configure (Just d) _ = do
+ absd <- absPath d
+ cwd <- getCurrentDirectory
+ r <- newFrom $ Local { gitdir = absd, worktree = Just cwd }
+ Git.Config.read r
+ configure Nothing Nothing = error "Not in a git repository."
+
+ addworktree w r = changelocation r $
+ Local { gitdir = gitdir (location r), worktree = w }
+ changelocation r l = r { location = l }
diff --git a/Git/DiffTree.hs b/Git/DiffTree.hs
new file mode 100644
index 000000000..e7787caee
--- /dev/null
+++ b/Git/DiffTree.hs
@@ -0,0 +1,102 @@
+{- git diff-tree interface
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Git.DiffTree (
+ DiffTreeItem(..),
+ diffTree,
+ diffTreeRecursive,
+ diffIndex,
+ diffWorkTree,
+) where
+
+import Numeric
+import System.Posix.Types
+
+import Common
+import Git
+import Git.Sha
+import Git.Command
+import Git.FilePath
+import qualified Git.Filename
+import qualified Git.Ref
+
+data DiffTreeItem = DiffTreeItem
+ { srcmode :: FileMode
+ , dstmode :: FileMode
+ , srcsha :: Sha -- nullSha if file was added
+ , dstsha :: Sha -- nullSha if file was deleted
+ , status :: String
+ , file :: TopFilePath
+ } deriving Show
+
+{- Diffs two tree Refs. -}
+diffTree :: Ref -> Ref -> Repo -> IO ([DiffTreeItem], IO Bool)
+diffTree src dst = getdiff (Param "diff-tree")
+ [Param (show src), Param (show dst)]
+
+{- Diffs two tree Refs, recursing into sub-trees -}
+diffTreeRecursive :: Ref -> Ref -> Repo -> IO ([DiffTreeItem], IO Bool)
+diffTreeRecursive src dst = getdiff (Param "diff-tree")
+ [Param "-r", Param (show src), Param (show dst)]
+
+{- Diffs between a tree and the index. Does nothing if there is not yet a
+ - commit in the repository. -}
+diffIndex :: Ref -> Repo -> IO ([DiffTreeItem], IO Bool)
+diffIndex ref = diffIndex' ref [Param "--cached"]
+
+{- Diffs between a tree and the working tree. Does nothing if there is not
+ - yet a commit in the repository, of if the repository is bare. -}
+diffWorkTree :: Ref -> Repo -> IO ([DiffTreeItem], IO Bool)
+diffWorkTree ref repo =
+ ifM (Git.Ref.headExists repo)
+ ( diffIndex' ref [] repo
+ , return ([], return True)
+ )
+
+diffIndex' :: Ref -> [CommandParam] -> Repo -> IO ([DiffTreeItem], IO Bool)
+diffIndex' ref params repo =
+ ifM (Git.Ref.headExists repo)
+ ( getdiff (Param "diff-index")
+ ( params ++ [Param $ show ref] )
+ repo
+ , return ([], return True)
+ )
+
+getdiff :: CommandParam -> [CommandParam] -> Repo -> IO ([DiffTreeItem], IO Bool)
+getdiff command params repo = do
+ (diff, cleanup) <- pipeNullSplit ps repo
+ return (parseDiffTree diff, cleanup)
+ where
+ ps = command : Params "-z --raw --no-renames -l0" : params
+
+{- Parses diff-tree output. -}
+parseDiffTree :: [String] -> [DiffTreeItem]
+parseDiffTree l = go l []
+ where
+ go [] c = c
+ go (info:f:rest) c = go rest (mk info f : c)
+ go (s:[]) _ = error $ "diff-tree parse error " ++ s
+
+ mk info f = DiffTreeItem
+ { srcmode = readmode srcm
+ , dstmode = readmode dstm
+ , srcsha = fromMaybe (error "bad srcsha") $ extractSha ssha
+ , dstsha = fromMaybe (error "bad dstsha") $ extractSha dsha
+ , status = s
+ , file = asTopFilePath $ Git.Filename.decode f
+ }
+ where
+ readmode = fst . Prelude.head . readOct
+
+ -- info = :<srcmode> SP <dstmode> SP <srcsha> SP <dstsha> SP <status>
+ -- All fields are fixed, so we can pull them out of
+ -- specific positions in the line.
+ (srcm, past_srcm) = splitAt 7 $ drop 1 info
+ (dstm, past_dstm) = splitAt 7 past_srcm
+ (ssha, past_ssha) = splitAt shaSize past_dstm
+ (dsha, past_dsha) = splitAt shaSize $ drop 1 past_ssha
+ s = drop 1 past_dsha
diff --git a/Git/FileMode.hs b/Git/FileMode.hs
new file mode 100644
index 000000000..fc4d0264e
--- /dev/null
+++ b/Git/FileMode.hs
@@ -0,0 +1,23 @@
+{- git file modes
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Git.FileMode where
+
+import Utility.FileMode
+
+import System.PosixCompat.Types
+
+symLinkMode :: FileMode
+symLinkMode = 40960
+
+{- Git uses a special file mode to indicate a symlink. This is the case
+ - even on Windows, so we hard code the valuse here, rather than using
+ - System.Posix.Files.symbolicLinkMode. -}
+isSymLink :: FileMode -> Bool
+isSymLink = checkMode symLinkMode
diff --git a/Git/FilePath.hs b/Git/FilePath.hs
new file mode 100644
index 000000000..37d740f25
--- /dev/null
+++ b/Git/FilePath.hs
@@ -0,0 +1,64 @@
+{- git FilePath library
+ -
+ - Different git commands use different types of FilePaths to refer to
+ - files in the repository. Some commands use paths relative to the
+ - top of the repository even when run in a subdirectory. Adding some
+ - types helps keep that straight.
+ -
+ - Copyright 2012-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Git.FilePath (
+ TopFilePath,
+ fromTopFilePath,
+ getTopFilePath,
+ toTopFilePath,
+ asTopFilePath,
+ InternalGitPath,
+ toInternalGitPath,
+ fromInternalGitPath
+) where
+
+import Common
+import Git
+
+{- A FilePath, relative to the top of the git repository. -}
+newtype TopFilePath = TopFilePath { getTopFilePath :: FilePath }
+ deriving (Show)
+
+{- Returns an absolute FilePath. -}
+fromTopFilePath :: TopFilePath -> Git.Repo -> FilePath
+fromTopFilePath p repo = absPathFrom (repoPath repo) (getTopFilePath p)
+
+{- The input FilePath can be absolute, or relative to the CWD. -}
+toTopFilePath :: FilePath -> Git.Repo -> IO TopFilePath
+toTopFilePath file repo = TopFilePath <$>
+ relPathDirToFile (repoPath repo) <$> absPath file
+
+{- The input FilePath must already be relative to the top of the git
+ - repository -}
+asTopFilePath :: FilePath -> TopFilePath
+asTopFilePath file = TopFilePath file
+
+{- Git may use a different representation of a path when storing
+ - it internally. For example, on Windows, git uses '/' to separate paths
+ - stored in the repository, despite Windows using '\' -}
+type InternalGitPath = String
+
+toInternalGitPath :: FilePath -> InternalGitPath
+#ifndef mingw32_HOST_OS
+toInternalGitPath = id
+#else
+toInternalGitPath = replace "\\" "/"
+#endif
+
+fromInternalGitPath :: InternalGitPath -> FilePath
+#ifndef mingw32_HOST_OS
+fromInternalGitPath = id
+#else
+fromInternalGitPath = replace "/" "\\"
+#endif
diff --git a/Git/Filename.hs b/Git/Filename.hs
new file mode 100644
index 000000000..5e076d3b5
--- /dev/null
+++ b/Git/Filename.hs
@@ -0,0 +1,28 @@
+{- Some git commands output encoded filenames, in a rather annoyingly complex
+ - C-style encoding.
+ -
+ - Copyright 2010, 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Git.Filename where
+
+import Utility.Format (decode_c, encode_c)
+
+import Common
+
+decode :: String -> FilePath
+decode [] = []
+decode f@(c:s)
+ -- encoded strings will be inside double quotes
+ | c == '"' && end s == ['"'] = decode_c $ beginning s
+ | otherwise = f
+
+{- Should not need to use this, except for testing decode. -}
+encode :: FilePath -> String
+encode s = "\"" ++ encode_c s ++ "\""
+
+{- for quickcheck -}
+prop_idempotent_deencode :: String -> Bool
+prop_idempotent_deencode s = s == decode (encode s)
diff --git a/Git/Fsck.hs b/Git/Fsck.hs
new file mode 100644
index 000000000..8bfddb4ba
--- /dev/null
+++ b/Git/Fsck.hs
@@ -0,0 +1,79 @@
+{- git fsck interface
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Git.Fsck (
+ FsckResults,
+ MissingObjects,
+ findBroken,
+ foundBroken,
+ findMissing,
+) where
+
+import Common
+import Git
+import Git.Command
+import Git.Sha
+import Utility.Batch
+
+import qualified Data.Set as S
+
+type MissingObjects = S.Set Sha
+
+{- If fsck succeeded, Just a set of missing objects it found.
+ - If it failed, Nothing. -}
+type FsckResults = Maybe MissingObjects
+
+{- Runs fsck to find some of the broken objects in the repository.
+ - May not find all broken objects, if fsck fails on bad data in some of
+ - the broken objects it does find.
+ -
+ - Strategy: Rather than parsing fsck's current specific output,
+ - look for anything in its output (both stdout and stderr) that appears
+ - to be a git sha. Not all such shas are of broken objects, so ask git
+ - to try to cat the object, and see if it fails.
+ -}
+findBroken :: Bool -> Repo -> IO FsckResults
+findBroken batchmode r = do
+ (output, fsckok) <- processTranscript command' (toCommand params') Nothing
+ let objs = findShas output
+ badobjs <- findMissing objs r
+ if S.null badobjs && not fsckok
+ then return Nothing
+ else return $ Just badobjs
+ where
+ (command, params) = ("git", fsckParams r)
+ (command', params')
+ | batchmode = toBatchCommand (command, params)
+ | otherwise = (command, params)
+
+foundBroken :: FsckResults -> Bool
+foundBroken Nothing = True
+foundBroken (Just s) = not (S.null s)
+
+{- Finds objects that are missing from the git repsitory, or are corrupt.
+ -
+ - This does not use git cat-file --batch, because catting a corrupt
+ - object can cause it to crash, or to report incorrect size information.a
+ -}
+findMissing :: [Sha] -> Repo -> IO MissingObjects
+findMissing objs r = S.fromList <$> filterM (not <$$> present) objs
+ where
+ present o = either (const False) (const True) <$> tryIO (dump o)
+ dump o = runQuiet
+ [ Param "show"
+ , Param (show o)
+ ] r
+
+findShas :: String -> [Sha]
+findShas = catMaybes . map extractSha . concat . map words . lines
+
+fsckParams :: Repo -> [CommandParam]
+fsckParams = gitCommandLine $
+ [ Param "fsck"
+ , Param "--no-dangling"
+ , Param "--no-reflogs"
+ ]
diff --git a/Git/GCrypt.hs b/Git/GCrypt.hs
new file mode 100644
index 000000000..156441dae
--- /dev/null
+++ b/Git/GCrypt.hs
@@ -0,0 +1,103 @@
+{- git-remote-gcrypt support
+ -
+ - https://github.com/blake2-ppc/git-remote-gcrypt
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Git.GCrypt where
+
+import Common
+import Git.Types
+import Git.Construct
+import qualified Git.Config as Config
+import qualified Git.Command as Command
+import Utility.Gpg
+
+urlPrefix :: String
+urlPrefix = "gcrypt::"
+
+isEncrypted :: Repo -> Bool
+isEncrypted Repo { location = Url url } = urlPrefix `isPrefixOf` show url
+isEncrypted _ = False
+
+{- The first Repo is the git repository that has the second Repo
+ - as one of its remotes.
+ -
+ - When the remote Repo uses gcrypt, returns the actual underlying
+ - git repository that gcrypt is using to store its data.
+ -
+ - Throws an exception if an url is invalid or the repo does not use
+ - gcrypt.
+ -}
+encryptedRemote :: Repo -> Repo -> IO Repo
+encryptedRemote baserepo = go
+ where
+ go Repo { location = Url url }
+ | urlPrefix `isPrefixOf` u =
+ fromRemoteLocation (drop plen u) baserepo
+ | otherwise = notencrypted
+ where
+ u = show url
+ plen = length urlPrefix
+ go _ = notencrypted
+ notencrypted = error "not a gcrypt encrypted repository"
+
+data ProbeResult = Decryptable | NotDecryptable | NotEncrypted
+
+{- Checks if the git repo at a location uses gcrypt.
+ -
+ - Rather expensive -- many need to fetch the entire repo contents.
+ - (Which is fine if the repo is going to be added as a remote..)
+ -}
+probeRepo :: String -> Repo -> IO ProbeResult
+probeRepo loc baserepo = do
+ let p = proc "git" $ toCommand $ Command.gitCommandLine
+ [ Param "remote-gcrypt"
+ , Param "--check"
+ , Param loc
+ ] baserepo
+ (_, _, _, pid) <- createProcess p
+ code <- waitForProcess pid
+ return $ case code of
+ ExitSuccess -> Decryptable
+ ExitFailure 1 -> NotDecryptable
+ ExitFailure _ -> NotEncrypted
+
+type GCryptId = String
+
+{- gcrypt gives each encrypted repository a uique gcrypt-id,
+ - which is stored in the repository (in encrypted form)
+ - and cached in a per-remote gcrypt-id configuration setting. -}
+remoteRepoId :: Repo -> Maybe RemoteName -> Maybe GCryptId
+remoteRepoId = getRemoteConfig "gcrypt-id"
+
+getRemoteConfig :: String -> Repo -> Maybe RemoteName -> Maybe String
+getRemoteConfig field repo remotename = do
+ n <- remotename
+ Config.getMaybe (remoteConfigKey field n) repo
+
+{- Gpg keys that the remote is encrypted for.
+ - If empty, gcrypt uses --default-recipient-self -}
+getParticiantList :: Maybe Repo -> Repo -> Maybe RemoteName -> KeyIds
+getParticiantList globalconfigrepo repo remotename = KeyIds $ parse $ firstJust
+ [ getRemoteConfig "gcrypt-participants" repo remotename
+ , Config.getMaybe defaultkey repo
+ , Config.getMaybe defaultkey =<< globalconfigrepo
+ ]
+ where
+ defaultkey = "gcrypt.participants"
+ parse (Just "simple") = []
+ parse (Just l) = words l
+ parse Nothing = []
+
+remoteParticipantConfigKey :: RemoteName -> String
+remoteParticipantConfigKey = remoteConfigKey "gcrypt-participants"
+
+remoteSigningKey :: RemoteName -> String
+remoteSigningKey = remoteConfigKey "gcrypt-signingkey"
+
+remoteConfigKey :: String -> RemoteName -> String
+remoteConfigKey key remotename = "remote." ++ remotename ++ "." ++ key
diff --git a/Git/HashObject.hs b/Git/HashObject.hs
new file mode 100644
index 000000000..bb9b20d96
--- /dev/null
+++ b/Git/HashObject.hs
@@ -0,0 +1,46 @@
+{- git hash-object interface
+ -
+ - Copyright 2011-2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Git.HashObject where
+
+import Common
+import Git
+import Git.Sha
+import Git.Command
+import Git.Types
+import qualified Utility.CoProcess as CoProcess
+
+type HashObjectHandle = CoProcess.CoProcessHandle
+
+hashObjectStart :: Repo -> IO HashObjectHandle
+hashObjectStart = CoProcess.rawMode <=< gitCoProcessStart True
+ [ Param "hash-object"
+ , Param "-w"
+ , Param "--stdin-paths"
+ , Param "--no-filters"
+ ]
+
+hashObjectStop :: HashObjectHandle -> IO ()
+hashObjectStop = CoProcess.stop
+
+{- Injects a file into git, returning the Sha of the object. -}
+hashFile :: HashObjectHandle -> FilePath -> IO Sha
+hashFile h file = CoProcess.query h send receive
+ where
+ send to = hPutStrLn to file
+ receive from = getSha "hash-object" $ hGetLine from
+
+{- Injects some content into git, returning its Sha. -}
+hashObject :: ObjectType -> String -> Repo -> IO Sha
+hashObject objtype content = hashObject' objtype (flip hPutStr content)
+
+hashObject' :: ObjectType -> (Handle -> IO ()) -> Repo -> IO Sha
+hashObject' objtype writer repo = getSha subcmd $
+ pipeWriteRead (map Param params) (Just writer) repo
+ where
+ subcmd = "hash-object"
+ params = [subcmd, "-t", show objtype, "-w", "--stdin", "--no-filters"]
diff --git a/Git/Hook.hs b/Git/Hook.hs
new file mode 100644
index 000000000..d56a4a565
--- /dev/null
+++ b/Git/Hook.hs
@@ -0,0 +1,54 @@
+{- git hooks
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Git.Hook where
+
+import Common
+import Git
+import Utility.Tmp
+
+data Hook = Hook
+ { hookName :: FilePath
+ , hookScript :: String
+ }
+
+hookFile :: Hook -> Repo -> FilePath
+hookFile h r = localGitDir r </> "hooks" </> hookName h
+
+{- Writes a hook. Returns False if the hook already exists with a different
+ - content. -}
+hookWrite :: Hook -> Repo -> IO Bool
+hookWrite h r = do
+ let f = hookFile h r
+ ifM (doesFileExist f)
+ ( expectedContent h r
+ , do
+ viaTmp writeFile f (hookScript h)
+ p <- getPermissions f
+ setPermissions f $ p {executable = True}
+ return True
+ )
+
+{- Removes a hook. Returns False if the hook contained something else, and
+ - could not be removed. -}
+hookUnWrite :: Hook -> Repo -> IO Bool
+hookUnWrite h r = do
+ let f = hookFile h r
+ ifM (doesFileExist f)
+ ( ifM (expectedContent h r)
+ ( do
+ removeFile f
+ return True
+ , return False
+ )
+ , return True
+ )
+
+expectedContent :: Hook -> Repo -> IO Bool
+expectedContent h r = do
+ content <- readFile $ hookFile h r
+ return $ content == hookScript h
diff --git a/Git/Index.hs b/Git/Index.hs
new file mode 100644
index 000000000..5b660bb30
--- /dev/null
+++ b/Git/Index.hs
@@ -0,0 +1,27 @@
+{- git index file stuff
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Git.Index where
+
+import Utility.Env
+
+{- Forces git to use the specified index file.
+ -
+ - Returns an action that will reset back to the default
+ - index file.
+ -
+ - Warning: Not thread safe.
+ -}
+override :: FilePath -> IO (IO ())
+override index = do
+ res <- getEnv var
+ setEnv var index True
+ return $ reset res
+ where
+ var = "GIT_INDEX_FILE"
+ reset (Just v) = setEnv var v True
+ reset _ = unsetEnv var
diff --git a/Git/LsFiles.hs b/Git/LsFiles.hs
new file mode 100644
index 000000000..8aaa09067
--- /dev/null
+++ b/Git/LsFiles.hs
@@ -0,0 +1,214 @@
+{- git ls-files interface
+ -
+ - Copyright 2010,2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Git.LsFiles (
+ inRepo,
+ notInRepo,
+ allFiles,
+ deleted,
+ modified,
+ modifiedOthers,
+ staged,
+ stagedNotDeleted,
+ stagedOthersDetails,
+ stagedDetails,
+ typeChanged,
+ typeChangedStaged,
+ Conflicting(..),
+ Unmerged(..),
+ unmerged,
+ StagedDetails,
+) where
+
+import Common
+import Git
+import Git.Command
+import Git.Types
+import Git.Sha
+
+import Numeric
+import System.Posix.Types
+
+{- Scans for files that are checked into git at the specified locations. -}
+inRepo :: [FilePath] -> Repo -> IO ([FilePath], IO Bool)
+inRepo l = pipeNullSplit $ Params "ls-files --cached -z --" : map File l
+
+{- Scans for files at the specified locations that are not checked into git. -}
+notInRepo :: Bool -> [FilePath] -> Repo -> IO ([FilePath], IO Bool)
+notInRepo include_ignored l repo = pipeNullSplit params repo
+ where
+ params = [Params "ls-files --others"] ++ exclude ++
+ [Params "-z --"] ++ map File l
+ exclude
+ | include_ignored = []
+ | otherwise = [Param "--exclude-standard"]
+
+{- Finds all files in the specified locations, whether checked into git or
+ - not. -}
+allFiles :: [FilePath] -> Repo -> IO ([FilePath], IO Bool)
+allFiles l = pipeNullSplit $ Params "ls-files --cached --others -z --" : map File l
+
+{- Returns a list of files in the specified locations that have been
+ - deleted. -}
+deleted :: [FilePath] -> Repo -> IO ([FilePath], IO Bool)
+deleted l repo = pipeNullSplit params repo
+ where
+ params = [Params "ls-files --deleted -z --"] ++ map File l
+
+{- Returns a list of files in the specified locations that have been
+ - modified. -}
+modified :: [FilePath] -> Repo -> IO ([FilePath], IO Bool)
+modified l repo = pipeNullSplit params repo
+ where
+ params = [Params "ls-files --modified -z --"] ++ map File l
+
+{- Files that have been modified or are not checked into git. -}
+modifiedOthers :: [FilePath] -> Repo -> IO ([FilePath], IO Bool)
+modifiedOthers l repo = pipeNullSplit params repo
+ where
+ params = [Params "ls-files --modified --others -z --"] ++ map File l
+
+{- Returns a list of all files that are staged for commit. -}
+staged :: [FilePath] -> Repo -> IO ([FilePath], IO Bool)
+staged = staged' []
+
+{- Returns a list of the files, staged for commit, that are being added,
+ - moved, or changed (but not deleted), from the specified locations. -}
+stagedNotDeleted :: [FilePath] -> Repo -> IO ([FilePath], IO Bool)
+stagedNotDeleted = staged' [Param "--diff-filter=ACMRT"]
+
+staged' :: [CommandParam] -> [FilePath] -> Repo -> IO ([FilePath], IO Bool)
+staged' ps l = pipeNullSplit $ prefix ++ ps ++ suffix
+ where
+ prefix = [Params "diff --cached --name-only -z"]
+ suffix = Param "--" : map File l
+
+type StagedDetails = (FilePath, Maybe Sha, Maybe FileMode)
+
+{- Returns details about files that are staged in the index,
+ - as well as files not yet in git. Skips ignored files. -}
+stagedOthersDetails :: [FilePath] -> Repo -> IO ([StagedDetails], IO Bool)
+stagedOthersDetails = stagedDetails' [Params "--others --exclude-standard"]
+
+{- Returns details about all files that are staged in the index. -}
+stagedDetails :: [FilePath] -> Repo -> IO ([StagedDetails], IO Bool)
+stagedDetails = stagedDetails' []
+
+{- Gets details about staged files, including the Sha of their staged
+ - contents. -}
+stagedDetails' :: [CommandParam] -> [FilePath] -> Repo -> IO ([StagedDetails], IO Bool)
+stagedDetails' ps l repo = do
+ (ls, cleanup) <- pipeNullSplit params repo
+ return (map parse ls, cleanup)
+ where
+ params = Params "ls-files --stage -z" : ps ++
+ Param "--" : map File l
+ parse s
+ | null file = (s, Nothing, Nothing)
+ | otherwise = (file, extractSha $ take shaSize rest, readmode mode)
+ where
+ (metadata, file) = separate (== '\t') s
+ (mode, rest) = separate (== ' ') metadata
+ readmode = fst <$$> headMaybe . readOct
+
+{- Returns a list of the files in the specified locations that are staged
+ - for commit, and whose type has changed. -}
+typeChangedStaged :: [FilePath] -> Repo -> IO ([FilePath], IO Bool)
+typeChangedStaged = typeChanged' [Param "--cached"]
+
+{- Returns a list of the files in the specified locations whose type has
+ - changed. Files only staged for commit will not be included. -}
+typeChanged :: [FilePath] -> Repo -> IO ([FilePath], IO Bool)
+typeChanged = typeChanged' []
+
+typeChanged' :: [CommandParam] -> [FilePath] -> Repo -> IO ([FilePath], IO Bool)
+typeChanged' ps l repo = do
+ (fs, cleanup) <- pipeNullSplit (prefix ++ ps ++ suffix) repo
+ -- git diff returns filenames relative to the top of the git repo;
+ -- convert to filenames relative to the cwd, like git ls-files.
+ let top = repoPath repo
+ cwd <- getCurrentDirectory
+ return (map (\f -> relPathDirToFile cwd $ top </> f) fs, cleanup)
+ where
+ prefix = [Params "diff --name-only --diff-filter=T -z"]
+ suffix = Param "--" : (if null l then [File "."] else map File l)
+
+{- A item in conflict has two possible values.
+ - Either can be Nothing, when that side deleted the file. -}
+data Conflicting v = Conflicting
+ { valUs :: Maybe v
+ , valThem :: Maybe v
+ } deriving (Show)
+
+data Unmerged = Unmerged
+ { unmergedFile :: FilePath
+ , unmergedBlobType :: Conflicting BlobType
+ , unmergedSha :: Conflicting Sha
+ } deriving (Show)
+
+{- Returns a list of the files in the specified locations that have
+ - unresolved merge conflicts.
+ -
+ - ls-files outputs multiple lines per conflicting file, each with its own
+ - stage number:
+ - 1 = old version, can be ignored
+ - 2 = us
+ - 3 = them
+ - If a line is omitted, that side removed the file.
+ -}
+unmerged :: [FilePath] -> Repo -> IO ([Unmerged], IO Bool)
+unmerged l repo = do
+ (fs, cleanup) <- pipeNullSplit params repo
+ return (reduceUnmerged [] $ catMaybes $ map parseUnmerged fs, cleanup)
+ where
+ params = Params "ls-files --unmerged -z --" : map File l
+
+data InternalUnmerged = InternalUnmerged
+ { isus :: Bool
+ , ifile :: FilePath
+ , iblobtype :: Maybe BlobType
+ , isha :: Maybe Sha
+ } deriving (Show)
+
+parseUnmerged :: String -> Maybe InternalUnmerged
+parseUnmerged s
+ | null file = Nothing
+ | otherwise = case words metadata of
+ (rawblobtype:rawsha:rawstage:_) -> do
+ stage <- readish rawstage :: Maybe Int
+ unless (stage == 2 || stage == 3) $
+ fail undefined -- skip stage 1
+ blobtype <- readBlobType rawblobtype
+ sha <- extractSha rawsha
+ return $ InternalUnmerged (stage == 2) file
+ (Just blobtype) (Just sha)
+ _ -> Nothing
+ where
+ (metadata, file) = separate (== '\t') s
+
+reduceUnmerged :: [Unmerged] -> [InternalUnmerged] -> [Unmerged]
+reduceUnmerged c [] = c
+reduceUnmerged c (i:is) = reduceUnmerged (new:c) rest
+ where
+ (rest, sibi) = findsib i is
+ (blobtypeA, blobtypeB, shaA, shaB)
+ | isus i = (iblobtype i, iblobtype sibi, isha i, isha sibi)
+ | otherwise = (iblobtype sibi, iblobtype i, isha sibi, isha i)
+ new = Unmerged
+ { unmergedFile = ifile i
+ , unmergedBlobType = Conflicting blobtypeA blobtypeB
+ , unmergedSha = Conflicting shaA shaB
+ }
+ findsib templatei [] = ([], removed templatei)
+ findsib templatei (l:ls)
+ | ifile l == ifile templatei = (ls, l)
+ | otherwise = (l:ls, removed templatei)
+ removed templatei = templatei
+ { isus = not (isus templatei)
+ , iblobtype = Nothing
+ , isha = Nothing
+ }
diff --git a/Git/LsTree.hs b/Git/LsTree.hs
new file mode 100644
index 000000000..956f9f5b4
--- /dev/null
+++ b/Git/LsTree.hs
@@ -0,0 +1,65 @@
+{- git ls-tree interface
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Git.LsTree (
+ TreeItem(..),
+ lsTree,
+ lsTreeParams,
+ lsTreeFiles,
+ parseLsTree
+) where
+
+import Numeric
+import Control.Applicative
+import System.Posix.Types
+
+import Common
+import Git
+import Git.Command
+import Git.Sha
+import Git.FilePath
+import qualified Git.Filename
+
+data TreeItem = TreeItem
+ { mode :: FileMode
+ , typeobj :: String
+ , sha :: String
+ , file :: TopFilePath
+ } deriving Show
+
+{- Lists the complete contents of a tree, recursing into sub-trees,
+ - with lazy output. -}
+lsTree :: Ref -> Repo -> IO [TreeItem]
+lsTree t repo = map parseLsTree
+ <$> pipeNullSplitZombie (lsTreeParams t) repo
+
+lsTreeParams :: Ref -> [CommandParam]
+lsTreeParams t = [ Params "ls-tree --full-tree -z -r --", File $ show t ]
+
+{- Lists specified files in a tree. -}
+lsTreeFiles :: Ref -> [FilePath] -> Repo -> IO [TreeItem]
+lsTreeFiles t fs repo = map parseLsTree <$> pipeNullSplitStrict ps repo
+ where
+ ps = [Params "ls-tree --full-tree -z --", File $ show t] ++ map File fs
+
+{- Parses a line of ls-tree output.
+ - (The --long format is not currently supported.) -}
+parseLsTree :: String -> TreeItem
+parseLsTree l = TreeItem
+ { mode = fst $ Prelude.head $ readOct m
+ , typeobj = t
+ , sha = s
+ , file = asTopFilePath $ Git.Filename.decode f
+ }
+ where
+ -- l = <mode> SP <type> SP <sha> TAB <file>
+ -- All fields are fixed, so we can pull them out of
+ -- specific positions in the line.
+ (m, past_m) = splitAt 7 l
+ (t, past_t) = splitAt 4 past_m
+ (s, past_s) = splitAt shaSize $ Prelude.tail past_t
+ f = Prelude.tail past_s
diff --git a/Git/Merge.hs b/Git/Merge.hs
new file mode 100644
index 000000000..f5791274f
--- /dev/null
+++ b/Git/Merge.hs
@@ -0,0 +1,21 @@
+{- git merging
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Git.Merge where
+
+import Common
+import Git
+import Git.Command
+import Git.BuildVersion
+
+{- Avoids recent git's interactive merge. -}
+mergeNonInteractive :: Ref -> Repo -> IO Bool
+mergeNonInteractive branch
+ | older "1.7.7.6" = merge [Param $ show branch]
+ | otherwise = merge [Param "--no-edit", Param $ show branch]
+ where
+ merge ps = runBool $ Param "merge" : ps
diff --git a/Git/Objects.hs b/Git/Objects.hs
new file mode 100644
index 000000000..d9d2c6701
--- /dev/null
+++ b/Git/Objects.hs
@@ -0,0 +1,35 @@
+{- .git/objects
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Git.Objects where
+
+import Common
+import Git
+import Git.Sha
+
+objectsDir :: Repo -> FilePath
+objectsDir r = localGitDir r </> "objects"
+
+packDir :: Repo -> FilePath
+packDir r = objectsDir r </> "pack"
+
+packIdxFile :: FilePath -> FilePath
+packIdxFile = flip replaceExtension "idx"
+
+listPackFiles :: Repo -> IO [FilePath]
+listPackFiles r = filter (".pack" `isSuffixOf`)
+ <$> catchDefaultIO [] (dirContents $ packDir r)
+
+listLooseObjectShas :: Repo -> IO [Sha]
+listLooseObjectShas r = catchDefaultIO [] $
+ mapMaybe (extractSha . concat . reverse . take 2 . reverse . splitDirectories)
+ <$> dirContentsRecursiveSkipping (== "pack") (objectsDir r)
+
+looseObjectFile :: Repo -> Sha -> FilePath
+looseObjectFile r sha = objectsDir r </> prefix </> rest
+ where
+ (prefix, rest) = splitAt 2 (show sha)
diff --git a/Git/Queue.hs b/Git/Queue.hs
new file mode 100644
index 000000000..9bb7f77d1
--- /dev/null
+++ b/Git/Queue.hs
@@ -0,0 +1,167 @@
+{- git repository command queue
+ -
+ - Copyright 2010,2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP, BangPatterns #-}
+
+module Git.Queue (
+ Queue,
+ new,
+ addCommand,
+ addUpdateIndex,
+ size,
+ full,
+ flush,
+) where
+
+import qualified Data.Map as M
+import System.IO
+import System.Process
+
+import Utility.SafeCommand
+import Common
+import Git
+import Git.Command
+import qualified Git.UpdateIndex
+
+{- Queable actions that can be performed in a git repository.
+ -}
+data Action
+ {- Updating the index file, using a list of streamers that can
+ - be added to as the queue grows. -}
+ = UpdateIndexAction
+ { getStreamers :: [Git.UpdateIndex.Streamer] -- in reverse order
+ }
+ {- A git command to run, on a list of files that can be added to
+ - as the queue grows. -}
+ | CommandAction
+ { getSubcommand :: String
+ , getParams :: [CommandParam]
+ , getFiles :: [CommandParam]
+ }
+
+{- A key that can uniquely represent an action in a Map. -}
+data ActionKey = UpdateIndexActionKey | CommandActionKey String
+ deriving (Eq, Ord)
+
+actionKey :: Action -> ActionKey
+actionKey (UpdateIndexAction _) = UpdateIndexActionKey
+actionKey CommandAction { getSubcommand = s } = CommandActionKey s
+
+{- A queue of actions to perform (in any order) on a git repository,
+ - with lists of files to perform them on. This allows coalescing
+ - similar git commands. -}
+data Queue = Queue
+ { size :: Int
+ , _limit :: Int
+ , items :: M.Map ActionKey Action
+ }
+
+{- A recommended maximum size for the queue, after which it should be
+ - run.
+ -
+ - 10240 is semi-arbitrary. If we assume git filenames are between 10 and
+ - 255 characters long, then the queue will build up between 100kb and
+ - 2550kb long commands. The max command line length on linux is somewhere
+ - above 20k, so this is a fairly good balance -- the queue will buffer
+ - only a few megabytes of stuff and a minimal number of commands will be
+ - run by xargs. -}
+defaultLimit :: Int
+defaultLimit = 10240
+
+{- Constructor for empty queue. -}
+new :: Maybe Int -> Queue
+new lim = Queue 0 (fromMaybe defaultLimit lim) M.empty
+
+{- Adds an git command to the queue.
+ -
+ - Git commands with the same subcommand but different parameters are
+ - assumed to be equivilant enough to perform in any order with the same
+ - result.
+ -}
+addCommand :: String -> [CommandParam] -> [FilePath] -> Queue -> Repo -> IO Queue
+addCommand subcommand params files q repo =
+ updateQueue action different (length newfiles) q repo
+ where
+ key = actionKey action
+ action = CommandAction
+ { getSubcommand = subcommand
+ , getParams = params
+ , getFiles = newfiles
+ }
+ newfiles = map File files ++ maybe [] getFiles (M.lookup key $ items q)
+
+ different (CommandAction { getSubcommand = s }) = s /= subcommand
+ different _ = True
+
+{- Adds an update-index streamer to the queue. -}
+addUpdateIndex :: Git.UpdateIndex.Streamer -> Queue -> Repo -> IO Queue
+addUpdateIndex streamer q repo =
+ updateQueue action different 1 q repo
+ where
+ key = actionKey action
+ -- the list is built in reverse order
+ action = UpdateIndexAction $ streamer : streamers
+ streamers = maybe [] getStreamers $ M.lookup key $ items q
+
+ different (UpdateIndexAction _) = False
+ different _ = True
+
+{- Updates or adds an action in the queue. If the queue already contains a
+ - different action, it will be flushed; this is to ensure that conflicting
+ - actions, like add and rm, are run in the right order.-}
+updateQueue :: Action -> (Action -> Bool) -> Int -> Queue -> Repo -> IO Queue
+updateQueue !action different sizeincrease q repo
+ | null (filter different (M.elems (items q))) = return $ go q
+ | otherwise = go <$> flush q repo
+ where
+ go q' = newq
+ where
+ !newq = q'
+ { size = newsize
+ , items = newitems
+ }
+ !newsize = size q' + sizeincrease
+ !newitems = M.insertWith' const (actionKey action) action (items q')
+
+{- Is a queue large enough that it should be flushed? -}
+full :: Queue -> Bool
+full (Queue cur lim _) = cur > lim
+
+{- Runs a queue on a git repository. -}
+flush :: Queue -> Repo -> IO Queue
+flush (Queue _ lim m) repo = do
+ forM_ (M.elems m) $ runAction repo
+ return $ Queue 0 lim M.empty
+
+{- Runs an Action on a list of files in a git repository.
+ -
+ - Complicated by commandline length limits.
+ -
+ - Intentionally runs the command even if the list of files is empty;
+ - this allows queueing commands that do not need a list of files. -}
+runAction :: Repo -> Action -> IO ()
+runAction repo (UpdateIndexAction streamers) =
+ -- list is stored in reverse order
+ Git.UpdateIndex.streamUpdateIndex repo $ reverse streamers
+runAction repo action@(CommandAction {}) =
+#ifndef mingw32_HOST_OS
+ withHandle StdinHandle createProcessSuccess p $ \h -> do
+ fileEncoding h
+ hPutStr h $ intercalate "\0" $ toCommand $ getFiles action
+ hClose h
+#else
+ -- Using xargs on Windows is problimatic, so just run the command
+ -- once per file (not as efficient.)
+ if null (getFiles action)
+ then void $ boolSystem "git" gitparams
+ else forM_ (getFiles action) $ \f ->
+ void $ boolSystem "git" (gitparams ++ [f])
+#endif
+ where
+ p = (proc "xargs" $ "-0":"git":toCommand gitparams) { env = gitEnv repo }
+ gitparams = gitCommandLine
+ (Param (getSubcommand action):getParams action) repo
diff --git a/Git/Ref.hs b/Git/Ref.hs
new file mode 100644
index 000000000..6ce1b8784
--- /dev/null
+++ b/Git/Ref.hs
@@ -0,0 +1,133 @@
+{- git ref stuff
+ -
+ - Copyright 2011-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Git.Ref where
+
+import Common
+import Git
+import Git.Command
+
+import Data.Char (chr)
+
+headRef :: Ref
+headRef = Ref "HEAD"
+
+{- Converts a fully qualified git ref into a user-visible string. -}
+describe :: Ref -> String
+describe = show . base
+
+{- Often git refs are fully qualified (eg: refs/heads/master).
+ - Converts such a fully qualified ref into a base ref (eg: master). -}
+base :: Ref -> Ref
+base = Ref . remove "refs/heads/" . remove "refs/remotes/" . show
+ where
+ remove prefix s
+ | prefix `isPrefixOf` s = drop (length prefix) s
+ | otherwise = s
+
+{- Given a directory and any ref, takes the basename of the ref and puts
+ - it under the directory. -}
+under :: String -> Ref -> Ref
+under dir r = Ref $ dir ++ "/" ++
+ (reverse $ takeWhile (/= '/') $ reverse $ show r)
+
+{- Given a directory such as "refs/remotes/origin", and a ref such as
+ - refs/heads/master, yields a version of that ref under the directory,
+ - such as refs/remotes/origin/master. -}
+underBase :: String -> Ref -> Ref
+underBase dir r = Ref $ dir ++ "/" ++ show (base r)
+
+{- A Ref that can be used to refer to a file in the repository, as staged
+ - in the index.
+ -
+ - Prefixing the file with ./ makes this work even if in a subdirectory
+ - of a repo.
+ -}
+fileRef :: FilePath -> Ref
+fileRef f = Ref $ ":./" ++ f
+
+{- A Ref that can be used to refer to a file in the repository as it
+ - appears in a given Ref. -}
+fileFromRef :: Ref -> FilePath -> Ref
+fileFromRef (Ref r) f = let (Ref fr) = fileRef f in Ref (r ++ fr)
+
+{- Checks if a ref exists. -}
+exists :: Ref -> Repo -> IO Bool
+exists ref = runBool
+ [Param "show-ref", Param "--verify", Param "-q", Param $ show ref]
+
+{- The file used to record a ref. (Git also stores some refs in a
+ - packed-refs file.) -}
+file :: Ref -> Repo -> FilePath
+file ref repo = localGitDir repo </> show ref
+
+{- Checks if HEAD exists. It generally will, except for in a repository
+ - that was just created. -}
+headExists :: Repo -> IO Bool
+headExists repo = do
+ ls <- lines <$> pipeReadStrict [Param "show-ref", Param "--head"] repo
+ return $ any (" HEAD" `isSuffixOf`) ls
+
+{- Get the sha of a fully qualified git ref, if it exists. -}
+sha :: Branch -> Repo -> IO (Maybe Sha)
+sha branch repo = process <$> showref repo
+ where
+ showref = pipeReadStrict [Param "show-ref",
+ Param "--hash", -- get the hash
+ Param $ show branch]
+ process [] = Nothing
+ process s = Just $ Ref $ firstLine s
+
+{- List of (shas, branches) matching a given ref or refs. -}
+matching :: [Ref] -> Repo -> IO [(Sha, Branch)]
+matching refs repo = matching' (map show refs) repo
+
+{- Includes HEAD in the output, if asked for it. -}
+matchingWithHEAD :: [Ref] -> Repo -> IO [(Sha, Branch)]
+matchingWithHEAD refs repo = matching' ("--head" : map show refs) repo
+
+{- List of (shas, branches) matching a given ref or refs. -}
+matching' :: [String] -> Repo -> IO [(Sha, Branch)]
+matching' ps repo = map gen . lines <$>
+ pipeReadStrict (Param "show-ref" : map Param ps) repo
+ where
+ gen l = let (r, b) = separate (== ' ') l
+ in (Ref r, Ref b)
+
+{- List of (shas, branches) matching a given ref spec.
+ - Duplicate shas are filtered out. -}
+matchingUniq :: [Ref] -> Repo -> IO [(Sha, Branch)]
+matchingUniq refs repo = nubBy uniqref <$> matching refs repo
+ where
+ uniqref (a, _) (b, _) = a == b
+
+{- Checks if a String is a legal git ref name.
+ -
+ - The rules for this are complex; see git-check-ref-format(1) -}
+legal :: Bool -> String -> Bool
+legal allowonelevel s = all (== False) illegal
+ where
+ illegal =
+ [ any ("." `isPrefixOf`) pathbits
+ , any (".lock" `isSuffixOf`) pathbits
+ , not allowonelevel && length pathbits < 2
+ , contains ".."
+ , any (\c -> contains [c]) illegalchars
+ , begins "/"
+ , ends "/"
+ , contains "//"
+ , ends "."
+ , contains "@{"
+ , null s
+ ]
+ contains v = v `isInfixOf` s
+ ends v = v `isSuffixOf` s
+ begins v = v `isPrefixOf` s
+
+ pathbits = split "/" s
+ illegalchars = " ~^:?*[\\" ++ controlchars
+ controlchars = chr 0o177 : [chr 0 .. chr (0o40-1)]
diff --git a/Git/RefLog.hs b/Git/RefLog.hs
new file mode 100644
index 000000000..3f41e8eaa
--- /dev/null
+++ b/Git/RefLog.hs
@@ -0,0 +1,22 @@
+{- git reflog interface
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Git.RefLog where
+
+import Common
+import Git
+import Git.Command
+import Git.Sha
+
+{- Gets the reflog for a given branch. -}
+get :: Branch -> Repo -> IO [Sha]
+get b = mapMaybe extractSha . lines <$$> pipeReadStrict
+ [ Param "log"
+ , Param "-g"
+ , Param "--format=%H"
+ , Param (show b)
+ ]
diff --git a/Git/Remote.hs b/Git/Remote.hs
new file mode 100644
index 000000000..9d969c416
--- /dev/null
+++ b/Git/Remote.hs
@@ -0,0 +1,115 @@
+{- git remote stuff
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Git.Remote where
+
+import Common
+import Git
+import Git.Types
+import qualified Git.Command
+import qualified Git.BuildVersion
+
+import Data.Char
+import qualified Data.Map as M
+import Network.URI
+#ifdef mingw32_HOST_OS
+import Git.FilePath
+#endif
+
+{- Construct a legal git remote name out of an arbitrary input string.
+ -
+ - There seems to be no formal definition of this in the git source,
+ - just some ad-hoc checks, and some other things that fail with certian
+ - types of names (like ones starting with '-').
+ -}
+makeLegalName :: String -> RemoteName
+makeLegalName s = case filter legal $ replace "/" "_" s of
+ -- it can't be empty
+ [] -> "unnamed"
+ -- it can't start with / or - or .
+ '.':s' -> makeLegalName s'
+ '/':s' -> makeLegalName s'
+ '-':s' -> makeLegalName s'
+ s' -> s'
+ where
+ {- Only alphanumerics, and a few common bits of punctuation common
+ - in hostnames. -}
+ legal '_' = True
+ legal '.' = True
+ legal c = isAlphaNum c
+
+remove :: RemoteName -> Repo -> IO ()
+remove remotename = Git.Command.run
+ [ Param "remote"
+ -- name of this subcommand changed
+ , Param $
+ if Git.BuildVersion.older "1.8.0"
+ then "rm"
+ else "remove"
+ , Param remotename
+ ]
+
+data RemoteLocation = RemoteUrl String | RemotePath FilePath
+
+remoteLocationIsUrl :: RemoteLocation -> Bool
+remoteLocationIsUrl (RemoteUrl _) = True
+remoteLocationIsUrl _ = False
+
+remoteLocationIsSshUrl :: RemoteLocation -> Bool
+remoteLocationIsSshUrl (RemoteUrl u) = "ssh://" `isPrefixOf` u
+remoteLocationIsSshUrl _ = False
+
+{- Determines if a given remote location is an url, or a local
+ - path. Takes the repository's insteadOf configuration into account. -}
+parseRemoteLocation :: String -> Repo -> RemoteLocation
+parseRemoteLocation s repo = ret $ calcloc s
+ where
+ ret v
+#ifdef mingw32_HOST_OS
+ | dosstyle v = RemotePath (dospath v)
+#endif
+ | scpstyle v = RemoteUrl (scptourl v)
+ | urlstyle v = RemoteUrl v
+ | otherwise = RemotePath v
+ -- insteadof config can rewrite remote location
+ calcloc l
+ | null insteadofs = l
+ | otherwise = replacement ++ drop (length bestvalue) l
+ where
+ replacement = drop (length prefix) $
+ take (length bestkey - length suffix) bestkey
+ (bestkey, bestvalue) = maximumBy longestvalue insteadofs
+ longestvalue (_, a) (_, b) = compare b a
+ insteadofs = filterconfig $ \(k, v) ->
+ startswith prefix k &&
+ endswith suffix k &&
+ startswith v l
+ filterconfig f = filter f $
+ concatMap splitconfigs $ M.toList $ fullconfig repo
+ splitconfigs (k, vs) = map (\v -> (k, v)) vs
+ (prefix, suffix) = ("url." , ".insteadof")
+ urlstyle v = isURI v || ":" `isInfixOf` v && "//" `isInfixOf` v
+ -- git remotes can be written scp style -- [user@]host:dir
+ -- but foo::bar is a git-remote-helper location instead
+ scpstyle v = ":" `isInfixOf` v
+ && not ("//" `isInfixOf` v)
+ && not ("::" `isInfixOf` v)
+ scptourl v = "ssh://" ++ host ++ slash dir
+ where
+ (host, dir) = separate (== ':') v
+ slash d | d == "" = "/~/" ++ d
+ | "/" `isPrefixOf` d = d
+ | "~" `isPrefixOf` d = '/':d
+ | otherwise = "/~/" ++ d
+#ifdef mingw32_HOST_OS
+ -- git on Windows will write a path to .git/config with "drive:",
+ -- which is not to be confused with a "host:"
+ dosstyle = hasDrive
+ dospath = fromInternalGitPath
+#endif
diff --git a/Git/Repair.hs b/Git/Repair.hs
new file mode 100644
index 000000000..2fe9f3896
--- /dev/null
+++ b/Git/Repair.hs
@@ -0,0 +1,551 @@
+{- git repository recovery
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Git.Repair (
+ runRepair,
+ runRepairOf,
+ successfulRepair,
+ cleanCorruptObjects,
+ retrieveMissingObjects,
+ resetLocalBranches,
+ removeTrackingBranches,
+ checkIndex,
+ missingIndex,
+ nukeIndex,
+ emptyGoodCommits,
+) where
+
+import Common
+import Git
+import Git.Command
+import Git.Objects
+import Git.Sha
+import Git.Types
+import Git.Fsck
+import qualified Git.Config as Config
+import qualified Git.Construct as Construct
+import qualified Git.LsTree as LsTree
+import qualified Git.LsFiles as LsFiles
+import qualified Git.Ref as Ref
+import qualified Git.RefLog as RefLog
+import qualified Git.UpdateIndex as UpdateIndex
+import qualified Git.Branch as Branch
+import Utility.Tmp
+import Utility.Rsync
+import Utility.FileMode
+
+import qualified Data.Set as S
+import qualified Data.ByteString.Lazy as L
+import Data.Tuple.Utils
+
+{- Given a set of bad objects found by git fsck, which may not
+ - be complete, finds and removes all corrupt objects, and
+ - returns a list of missing objects, which need to be
+ - found elsewhere to finish recovery.
+ -}
+cleanCorruptObjects :: FsckResults -> Repo -> IO (Maybe MissingObjects)
+cleanCorruptObjects fsckresults r = do
+ void $ explodePacks r
+ objs <- listLooseObjectShas r
+ bad <- findMissing objs r
+ void $ removeLoose r $ S.union bad (fromMaybe S.empty fsckresults)
+ -- Rather than returning the loose objects that were removed, re-run
+ -- fsck. Other missing objects may have been in the packs,
+ -- and this way fsck will find them.
+ findBroken False r
+
+removeLoose :: Repo -> MissingObjects -> IO Bool
+removeLoose r s = do
+ fs <- filterM doesFileExist (map (looseObjectFile r) (S.toList s))
+ let count = length fs
+ if count > 0
+ then do
+ putStrLn $ unwords
+ [ "Removing"
+ , show count
+ , "corrupt loose objects."
+ ]
+ mapM_ nukeFile fs
+ return True
+ else return False
+
+explodePacks :: Repo -> IO Bool
+explodePacks r = do
+ packs <- listPackFiles r
+ if null packs
+ then return False
+ else do
+ putStrLn "Unpacking all pack files."
+ mapM_ go packs
+ return True
+ where
+ go packfile = withTmpFileIn (localGitDir r) "pack" $ \tmp _ -> do
+ moveFile packfile tmp
+ nukeFile $ packIdxFile packfile
+ allowRead tmp
+ -- May fail, if pack file is corrupt.
+ void $ tryIO $
+ pipeWrite [Param "unpack-objects", Param "-r"] r $ \h ->
+ L.hPut h =<< L.readFile tmp
+
+{- Try to retrieve a set of missing objects, from the remotes of a
+ - repository. Returns any that could not be retreived.
+ -
+ - If another clone of the repository exists locally, which might not be a
+ - remote of the repo being repaired, its path can be passed as a reference
+ - repository.
+
+ - Can also be run with Nothing, if it's not known which objects are
+ - missing, just that some are. (Ie, fsck failed badly.)
+ -}
+retrieveMissingObjects :: Maybe MissingObjects -> Maybe FilePath -> Repo -> IO (Maybe MissingObjects)
+retrieveMissingObjects missing referencerepo r
+ | missing == Just S.empty = return $ Just S.empty
+ | otherwise = withTmpDir "tmprepo" $ \tmpdir -> do
+ unlessM (boolSystem "git" [Params "init", File tmpdir]) $
+ error $ "failed to create temp repository in " ++ tmpdir
+ tmpr <- Config.read =<< Construct.fromAbsPath tmpdir
+ stillmissing <- pullremotes tmpr (remotes r) fetchrefstags missing
+ if stillmissing == Just S.empty
+ then return $ Just S.empty
+ else pullremotes tmpr (remotes r) fetchallrefs stillmissing
+ where
+ pullremotes tmpr [] fetchrefs stillmissing = case referencerepo of
+ Nothing -> return stillmissing
+ Just p -> ifM (fetchfrom p fetchrefs tmpr)
+ ( do
+ void $ explodePacks tmpr
+ void $ copyObjects tmpr r
+ case stillmissing of
+ Nothing -> return $ Just S.empty
+ Just s -> Just <$> findMissing (S.toList s) r
+ , return stillmissing
+ )
+ pullremotes tmpr (rmt:rmts) fetchrefs ms
+ | ms == Just S.empty = return $ Just S.empty
+ | otherwise = do
+ putStrLn $ "Trying to recover missing objects from remote " ++ repoDescribe rmt ++ "."
+ ifM (fetchfrom (repoLocation rmt) fetchrefs tmpr)
+ ( do
+ void $ explodePacks tmpr
+ void $ copyObjects tmpr r
+ case ms of
+ Nothing -> pullremotes tmpr rmts fetchrefs ms
+ Just s -> do
+ stillmissing <- findMissing (S.toList s) r
+ pullremotes tmpr rmts fetchrefs (Just stillmissing)
+ , pullremotes tmpr rmts fetchrefs ms
+ )
+ fetchfrom fetchurl ps = runBool $
+ [ Param "fetch"
+ , Param fetchurl
+ , Params "--force --update-head-ok --quiet"
+ ] ++ ps
+ -- fetch refs and tags
+ fetchrefstags = [ Param "+refs/heads/*:refs/heads/*", Param "--tags"]
+ -- Fetch all available refs (more likely to fail,
+ -- as the remote may have refs it refuses to send).
+ fetchallrefs = [ Param "+*:*" ]
+
+{- Copies all objects from the src repository to the dest repository.
+ - This is done using rsync, so it copies all missing objects, and all
+ - objects they rely on. -}
+copyObjects :: Repo -> Repo -> IO Bool
+copyObjects srcr destr = rsync
+ [ Param "-qr"
+ , File $ addTrailingPathSeparator $ objectsDir srcr
+ , File $ addTrailingPathSeparator $ objectsDir destr
+ ]
+
+{- To deal with missing objects that cannot be recovered, resets any
+ - local branches to point to an old commit before the missing
+ - objects. Returns all branches that were changed, and deleted.
+ -}
+resetLocalBranches :: MissingObjects -> GoodCommits -> Repo -> IO ([Branch], [Branch], GoodCommits)
+resetLocalBranches missing goodcommits r =
+ go [] [] goodcommits =<< filter islocalbranch <$> getAllRefs r
+ where
+ islocalbranch b = "refs/heads/" `isPrefixOf` show b
+ go changed deleted gcs [] = return (changed, deleted, gcs)
+ go changed deleted gcs (b:bs) = do
+ (mc, gcs') <- findUncorruptedCommit missing gcs b r
+ case mc of
+ Just c
+ | c == b -> go changed deleted gcs' bs
+ | otherwise -> do
+ reset b c
+ go (b:changed) deleted gcs' bs
+ Nothing -> do
+ nukeBranchRef b r
+ go changed (b:deleted) gcs' bs
+ reset b c = do
+ nukeBranchRef b r
+ void $ runBool
+ [ Param "branch"
+ , Param (show $ Ref.base b)
+ , Param (show c)
+ ] r
+
+{- To deal with missing objects that cannot be recovered, removes
+ - any remote tracking branches that reference them. Returns a list of
+ - all removed branches.
+ -}
+removeTrackingBranches :: MissingObjects -> GoodCommits -> Repo -> IO ([Branch], GoodCommits)
+removeTrackingBranches missing goodcommits r =
+ go [] goodcommits =<< filter istrackingbranch <$> getAllRefs r
+ where
+ istrackingbranch b = "refs/remotes/" `isPrefixOf` show b
+ go removed gcs [] = return (removed, gcs)
+ go removed gcs (b:bs) = do
+ (ok, gcs') <- verifyCommit missing gcs b r
+ if ok
+ then go removed gcs' bs
+ else do
+ nukeBranchRef b r
+ go (b:removed) gcs' bs
+
+{- Gets all refs, including ones that are corrupt.
+ - git show-ref does not output refs to commits that are directly
+ - corrupted, so it is not used.
+ -
+ - Relies on packed refs being exploded before it's called.
+ -}
+getAllRefs :: Repo -> IO [Ref]
+getAllRefs r = map toref <$> dirContentsRecursive refdir
+ where
+ refdir = localGitDir r </> "refs"
+ toref = Ref . relPathDirToFile (localGitDir r)
+
+explodePackedRefsFile :: Repo -> IO ()
+explodePackedRefsFile r = do
+ let f = packedRefsFile r
+ whenM (doesFileExist f) $ do
+ rs <- mapMaybe parsePacked . lines
+ <$> catchDefaultIO "" (safeReadFile f)
+ forM_ rs makeref
+ nukeFile f
+ where
+ makeref (sha, ref) = do
+ let dest = localGitDir r ++ show ref
+ createDirectoryIfMissing True (parentDir dest)
+ unlessM (doesFileExist dest) $
+ writeFile dest (show sha)
+
+packedRefsFile :: Repo -> FilePath
+packedRefsFile r = localGitDir r </> "packed-refs"
+
+parsePacked :: String -> Maybe (Sha, Ref)
+parsePacked l = case words l of
+ (sha:ref:[])
+ | isJust (extractSha sha) && Ref.legal True ref ->
+ Just (Ref sha, Ref ref)
+ _ -> Nothing
+
+{- git-branch -d cannot be used to remove a branch that is directly
+ - pointing to a corrupt commit. -}
+nukeBranchRef :: Branch -> Repo -> IO ()
+nukeBranchRef b r = nukeFile $ localGitDir r </> show b
+
+{- Finds the most recent commit to a branch that does not need any
+ - of the missing objects. If the input branch is good as-is, returns it.
+ - Otherwise, tries to traverse the commits in the branch to find one
+ - that is ok. That might fail, if one of them is corrupt, or if an object
+ - at the root of the branch is missing. Finally, looks for an old version
+ - of the branch from the reflog.
+ -}
+findUncorruptedCommit :: MissingObjects -> GoodCommits -> Branch -> Repo -> IO (Maybe Sha, GoodCommits)
+findUncorruptedCommit missing goodcommits branch r = do
+ (ok, goodcommits') <- verifyCommit missing goodcommits branch r
+ if ok
+ then return (Just branch, goodcommits')
+ else do
+ (ls, cleanup) <- pipeNullSplit
+ [ Param "log"
+ , Param "-z"
+ , Param "--format=%H"
+ , Param (show branch)
+ ] r
+ let branchshas = catMaybes $ map extractSha ls
+ reflogshas <- RefLog.get branch r
+ -- XXX Could try a bit harder here, and look
+ -- for uncorrupted old commits in branches in the
+ -- reflog.
+ cleanup `after` findfirst goodcommits (branchshas ++ reflogshas)
+ where
+ findfirst gcs [] = return (Nothing, gcs)
+ findfirst gcs (c:cs) = do
+ (ok, gcs') <- verifyCommit missing gcs c r
+ if ok
+ then return (Just c, gcs')
+ else findfirst gcs' cs
+
+{- Verifies tha none of the missing objects in the set are used by
+ - the commit. Also adds to a set of commit shas that have been verified to
+ - be good, which can be passed into subsequent calls to avoid
+ - redundant work when eg, chasing down branches to find the first
+ - uncorrupted commit. -}
+verifyCommit :: MissingObjects -> GoodCommits -> Sha -> Repo -> IO (Bool, GoodCommits)
+verifyCommit missing goodcommits commit r
+ | checkGoodCommit commit goodcommits = return (True, goodcommits)
+ | otherwise = do
+ (ls, cleanup) <- pipeNullSplit
+ [ Param "log"
+ , Param "-z"
+ , Param "--format=%H %T"
+ , Param (show commit)
+ ] r
+ let committrees = map parse ls
+ if any isNothing committrees || null committrees
+ then do
+ void cleanup
+ return (False, goodcommits)
+ else do
+ let cts = catMaybes committrees
+ ifM (cleanup <&&> check cts)
+ ( return (True, addGoodCommits (map fst cts) goodcommits)
+ , return (False, goodcommits)
+ )
+ where
+ parse l = case words l of
+ (commitsha:treesha:[]) -> (,)
+ <$> extractSha commitsha
+ <*> extractSha treesha
+ _ -> Nothing
+ check [] = return True
+ check ((c, t):rest)
+ | checkGoodCommit c goodcommits = return True
+ | otherwise = verifyTree missing t r <&&> check rest
+
+{- Verifies that a tree is good, including all trees and blobs
+ - referenced by it. -}
+verifyTree :: MissingObjects -> Sha -> Repo -> IO Bool
+verifyTree missing treesha r
+ | S.member treesha missing = return False
+ | otherwise = do
+ (ls, cleanup) <- pipeNullSplit (LsTree.lsTreeParams treesha) r
+ let objshas = map (extractSha . LsTree.sha . LsTree.parseLsTree) ls
+ if any isNothing objshas || any (`S.member` missing) (catMaybes objshas)
+ then do
+ void cleanup
+ return False
+ -- as long as ls-tree succeeded, we're good
+ else cleanup
+
+{- Checks that the index file only refers to objects that are not missing,
+ - and is not itself corrupt. Note that a missing index file is not
+ - considered a problem (repo may be new). -}
+checkIndex :: MissingObjects -> Repo -> IO Bool
+checkIndex missing r = do
+ (bad, _good, cleanup) <- partitionIndex missing r
+ if null bad
+ then cleanup
+ else do
+ void cleanup
+ return False
+
+missingIndex :: Repo -> IO Bool
+missingIndex r = not <$> doesFileExist (localGitDir r </> "index")
+
+partitionIndex :: MissingObjects -> Repo -> IO ([LsFiles.StagedDetails], [LsFiles.StagedDetails], IO Bool)
+partitionIndex missing r = do
+ (indexcontents, cleanup) <- LsFiles.stagedDetails [repoPath r] r
+ let (bad, good) = partition ismissing indexcontents
+ return (bad, good, cleanup)
+ where
+ getblob (_file, Just sha, Just _mode) = Just sha
+ getblob _ = Nothing
+ ismissing = maybe False (`S.member` missing) . getblob
+
+{- Rewrites the index file, removing from it any files whose blobs are
+ - missing. Returns the list of affected files. -}
+rewriteIndex :: MissingObjects -> Repo -> IO [FilePath]
+rewriteIndex missing r
+ | repoIsLocalBare r = return []
+ | otherwise = do
+ (bad, good, cleanup) <- partitionIndex missing r
+ unless (null bad) $ do
+ nukeIndex r
+ UpdateIndex.streamUpdateIndex r
+ =<< (catMaybes <$> mapM reinject good)
+ void cleanup
+ return $ map fst3 bad
+ where
+ reinject (file, Just sha, Just mode) = case toBlobType mode of
+ Nothing -> return Nothing
+ Just blobtype -> Just <$>
+ UpdateIndex.stageFile sha blobtype file r
+ reinject _ = return Nothing
+
+nukeIndex :: Repo -> IO ()
+nukeIndex r = nukeFile (localGitDir r </> "index")
+
+newtype GoodCommits = GoodCommits (S.Set Sha)
+
+emptyGoodCommits :: GoodCommits
+emptyGoodCommits = GoodCommits S.empty
+
+checkGoodCommit :: Sha -> GoodCommits -> Bool
+checkGoodCommit sha (GoodCommits s) = S.member sha s
+
+addGoodCommits :: [Sha] -> GoodCommits -> GoodCommits
+addGoodCommits shas (GoodCommits s) = GoodCommits $
+ S.union s (S.fromList shas)
+
+displayList :: [String] -> String -> IO ()
+displayList items header
+ | null items = return ()
+ | otherwise = do
+ putStrLn header
+ putStr $ unlines $ map (\i -> "\t" ++ i) truncateditems
+ where
+ numitems = length items
+ truncateditems
+ | numitems > 10 = take 10 items ++ ["(and " ++ show (numitems - 10) ++ " more)"]
+ | otherwise = items
+
+{- Fix problems that would prevent repair from working at all
+ -
+ - A missing or corrupt .git/HEAD makes git not treat the repository as a
+ - git repo. If there is a git repo in a parent directory, it may move up
+ - the tree and use that one instead. So, cannot use `git show-ref HEAD` to
+ - test it.
+ -
+ - Explode the packed refs file, to simplify dealing with refs, and because
+ - fsck can complain about bad refs in it.
+ -}
+preRepair :: Repo -> IO ()
+preRepair g = do
+ unlessM (validhead <$> catchDefaultIO "" (safeReadFile headfile)) $ do
+ nukeFile headfile
+ writeFile headfile "ref: refs/heads/master"
+ explodePackedRefsFile g
+ where
+ headfile = localGitDir g </> "HEAD"
+ validhead s = "ref: refs/" `isPrefixOf` s || isJust (extractSha s)
+
+{- Put it all together. -}
+runRepair :: Bool -> Repo -> IO (Bool, MissingObjects, [Branch])
+runRepair forced g = do
+ preRepair g
+ putStrLn "Running git fsck ..."
+ fsckresult <- findBroken False g
+ if foundBroken fsckresult
+ then runRepair' fsckresult forced Nothing g
+ else do
+ putStrLn "No problems found."
+ return (True, S.empty, [])
+
+runRepairOf :: FsckResults -> Bool -> Maybe FilePath -> Repo -> IO (Bool, MissingObjects, [Branch])
+runRepairOf fsckresult forced referencerepo g = do
+ preRepair g
+ runRepair' fsckresult forced referencerepo g
+
+runRepair' :: FsckResults -> Bool -> Maybe FilePath -> Repo -> IO (Bool, MissingObjects, [Branch])
+runRepair' fsckresult forced referencerepo g = do
+ missing <- cleanCorruptObjects fsckresult g
+ stillmissing <- retrieveMissingObjects missing referencerepo g
+ case stillmissing of
+ Just s
+ | S.null s -> if repoIsLocalBare g
+ then successfulfinish S.empty []
+ else ifM (checkIndex S.empty g)
+ ( successfulfinish s []
+ , do
+ putStrLn "No missing objects found, but the index file is corrupt!"
+ if forced
+ then corruptedindex
+ else needforce S.empty
+ )
+ | otherwise -> if forced
+ then ifM (checkIndex s g)
+ ( continuerepairs s
+ , corruptedindex
+ )
+ else do
+ putStrLn $ unwords
+ [ show (S.size s)
+ , "missing objects could not be recovered!"
+ ]
+ unsuccessfulfinish s
+ Nothing
+ | forced -> ifM (pure (repoIsLocalBare g) <||> checkIndex S.empty g)
+ ( do
+ missing' <- cleanCorruptObjects Nothing g
+ case missing' of
+ Nothing -> return (False, S.empty, [])
+ Just stillmissing' -> continuerepairs stillmissing'
+ , corruptedindex
+ )
+ | otherwise -> unsuccessfulfinish S.empty
+ where
+ continuerepairs stillmissing = do
+ (remotebranches, goodcommits) <- removeTrackingBranches stillmissing emptyGoodCommits g
+ unless (null remotebranches) $
+ putStrLn $ unwords
+ [ "Removed"
+ , show (length remotebranches)
+ , "remote tracking branches that referred to missing objects."
+ ]
+ (resetbranches, deletedbranches, _) <- resetLocalBranches stillmissing goodcommits g
+ displayList (map show resetbranches)
+ "Reset these local branches to old versions before the missing objects were committed:"
+ displayList (map show deletedbranches)
+ "Deleted these local branches, which could not be recovered due to missing objects:"
+ deindexedfiles <- rewriteIndex stillmissing g
+ displayList deindexedfiles
+ "Removed these missing files from the index. You should look at what files are present in your working tree and git add them back to the index when appropriate."
+ let modifiedbranches = resetbranches ++ deletedbranches
+ if null resetbranches && null deletedbranches
+ then successfulfinish stillmissing modifiedbranches
+ else do
+ unless (repoIsLocalBare g) $ do
+ mcurr <- Branch.currentUnsafe g
+ case mcurr of
+ Nothing -> return ()
+ Just curr -> when (any (== curr) modifiedbranches) $ do
+ putStrLn $ unwords
+ [ "You currently have"
+ , show curr
+ , "checked out. You may have staged changes in the index that can be committed to recover the lost state of this branch!"
+ ]
+ putStrLn "Successfully recovered repository!"
+ putStrLn "Please carefully check that the changes mentioned above are ok.."
+ return (True, stillmissing, modifiedbranches)
+
+ corruptedindex = do
+ nukeIndex g
+ -- The corrupted index can prevent fsck from finding other
+ -- problems, so re-run repair.
+ fsckresult' <- findBroken False g
+ result <- runRepairOf fsckresult' forced referencerepo g
+ putStrLn "Removed the corrupted index file. You should look at what files are present in your working tree and git add them back to the index when appropriate."
+ return result
+
+ successfulfinish stillmissing modifiedbranches = do
+ mapM_ putStrLn
+ [ "Successfully recovered repository!"
+ , "You should run \"git fsck\" to make sure, but it looks like everything was recovered ok."
+ ]
+ return (True, stillmissing, modifiedbranches)
+ unsuccessfulfinish stillmissing = do
+ if repoIsLocalBare g
+ then do
+ putStrLn "If you have a clone of this bare repository, you should add it as a remote of this repository, and retry."
+ putStrLn "If there are no clones of this repository, you can instead retry with the --force parameter to force recovery to a possibly usable state."
+ return (False, stillmissing, [])
+ else needforce stillmissing
+ needforce stillmissing = do
+ putStrLn "To force a recovery to a usable state, retry with the --force parameter."
+ return (False, stillmissing, [])
+
+successfulRepair :: (Bool, MissingObjects, [Branch]) -> Bool
+successfulRepair = fst3
+
+safeReadFile :: FilePath -> IO String
+safeReadFile f = do
+ allowRead f
+ readFileStrictAnyEncoding f
diff --git a/Git/Sha.hs b/Git/Sha.hs
new file mode 100644
index 000000000..ee1b6d669
--- /dev/null
+++ b/Git/Sha.hs
@@ -0,0 +1,39 @@
+{- git SHA stuff
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Git.Sha where
+
+import Common
+import Git.Types
+
+{- Runs an action that causes a git subcommand to emit a Sha, and strips
+ - any trailing newline, returning the sha. -}
+getSha :: String -> IO String -> IO Sha
+getSha subcommand a = maybe bad return =<< extractSha <$> a
+ where
+ bad = error $ "failed to read sha from git " ++ subcommand
+
+{- Extracts the Sha from a string. There can be a trailing newline after
+ - it, but nothing else. -}
+extractSha :: String -> Maybe Sha
+extractSha s
+ | len == shaSize = val s
+ | len == shaSize + 1 && length s' == shaSize = val s'
+ | otherwise = Nothing
+ where
+ len = length s
+ s' = firstLine s
+ val v
+ | all (`elem` "1234567890ABCDEFabcdef") v = Just $ Ref v
+ | otherwise = Nothing
+
+{- Size of a git sha. -}
+shaSize :: Int
+shaSize = 40
+
+nullSha :: Ref
+nullSha = Ref $ replicate shaSize '0'
diff --git a/Git/SharedRepository.hs b/Git/SharedRepository.hs
new file mode 100644
index 000000000..f3efa8fde
--- /dev/null
+++ b/Git/SharedRepository.hs
@@ -0,0 +1,27 @@
+{- git core.sharedRepository handling
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Git.SharedRepository where
+
+import Data.Char
+
+import Common
+import Git
+import qualified Git.Config
+
+data SharedRepository = UnShared | GroupShared | AllShared | UmaskShared Int
+
+getSharedRepository :: Repo -> SharedRepository
+getSharedRepository r =
+ case map toLower $ Git.Config.get "core.sharedrepository" "" r of
+ "1" -> GroupShared
+ "group" -> GroupShared
+ "true" -> GroupShared
+ "all" -> AllShared
+ "world" -> AllShared
+ "everybody" -> AllShared
+ v -> maybe UnShared UmaskShared (readish v)
diff --git a/Git/Types.hs b/Git/Types.hs
new file mode 100644
index 000000000..e63e93077
--- /dev/null
+++ b/Git/Types.hs
@@ -0,0 +1,95 @@
+{- git data types
+ -
+ - Copyright 2010-2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Git.Types where
+
+import Network.URI
+import qualified Data.Map as M
+import System.Posix.Types
+import Utility.SafeCommand
+
+{- Support repositories on local disk, and repositories accessed via an URL.
+ -
+ - Repos on local disk have a git directory, and unless bare, a worktree.
+ -
+ - A local repo may not have had its config read yet, in which case all
+ - that's known about it is its path.
+ -
+ - Finally, an Unknown repository may be known to exist, but nothing
+ - else known about it.
+ -}
+data RepoLocation
+ = Local { gitdir :: FilePath, worktree :: Maybe FilePath }
+ | LocalUnknown FilePath
+ | Url URI
+ | Unknown
+ deriving (Show, Eq)
+
+data Repo = Repo
+ { location :: RepoLocation
+ , config :: M.Map String String
+ -- a given git config key can actually have multiple values
+ , fullconfig :: M.Map String [String]
+ , remotes :: [Repo]
+ -- remoteName holds the name used for this repo in remotes
+ , remoteName :: Maybe RemoteName
+ -- alternate environment to use when running git commands
+ , gitEnv :: Maybe [(String, String)]
+ -- global options to pass to git when running git commands
+ , gitGlobalOpts :: [CommandParam]
+ } deriving (Show, Eq)
+
+type RemoteName = String
+
+{- A git ref. Can be a sha1, or a branch or tag name. -}
+newtype Ref = Ref String
+ deriving (Eq, Ord)
+
+instance Show Ref where
+ show (Ref v) = v
+
+{- Aliases for Ref. -}
+type Branch = Ref
+type Sha = Ref
+type Tag = Ref
+
+{- Types of objects that can be stored in git. -}
+data ObjectType = BlobObject | CommitObject | TreeObject
+ deriving (Eq)
+
+instance Show ObjectType where
+ show BlobObject = "blob"
+ show CommitObject = "commit"
+ show TreeObject = "tree"
+
+readObjectType :: String -> Maybe ObjectType
+readObjectType "blob" = Just BlobObject
+readObjectType "commit" = Just CommitObject
+readObjectType "tree" = Just TreeObject
+readObjectType _ = Nothing
+
+{- Types of blobs. -}
+data BlobType = FileBlob | ExecutableBlob | SymlinkBlob
+ deriving (Eq)
+
+{- Git uses magic numbers to denote the type of a blob. -}
+instance Show BlobType where
+ show FileBlob = "100644"
+ show ExecutableBlob = "100755"
+ show SymlinkBlob = "120000"
+
+readBlobType :: String -> Maybe BlobType
+readBlobType "100644" = Just FileBlob
+readBlobType "100755" = Just ExecutableBlob
+readBlobType "120000" = Just SymlinkBlob
+readBlobType _ = Nothing
+
+toBlobType :: FileMode -> Maybe BlobType
+toBlobType 0o100644 = Just FileBlob
+toBlobType 0o100755 = Just ExecutableBlob
+toBlobType 0o120000 = Just SymlinkBlob
+toBlobType _ = Nothing
diff --git a/Git/UnionMerge.hs b/Git/UnionMerge.hs
new file mode 100644
index 000000000..464200af4
--- /dev/null
+++ b/Git/UnionMerge.hs
@@ -0,0 +1,110 @@
+{- git-union-merge library
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Git.UnionMerge (
+ merge,
+ mergeIndex
+) where
+
+import qualified Data.ByteString.Lazy as L
+import qualified Data.Set as S
+
+import Common
+import Git
+import Git.Sha
+import Git.CatFile
+import Git.Command
+import Git.UpdateIndex
+import Git.HashObject
+import Git.Types
+import Git.FilePath
+
+{- Performs a union merge between two branches, staging it in the index.
+ - Any previously staged changes in the index will be lost.
+ -
+ - Should be run with a temporary index file configured by useIndex.
+ -}
+merge :: Ref -> Ref -> Repo -> IO ()
+merge x y repo = do
+ h <- catFileStart repo
+ streamUpdateIndex repo
+ [ lsTree x repo
+ , mergeTrees x y h repo
+ ]
+ catFileStop h
+
+{- Merges a list of branches into the index. Previously staged changes in
+ - the index are preserved (and participate in the merge).
+ -
+ - update-index is run once per ref in turn, so that each ref is merged on
+ - top of the merge for the previous ref. It would be more efficient, but
+ - harder to calculate a single union merge involving all the refs, as well
+ - as the index.
+ -}
+mergeIndex :: CatFileHandle -> Repo -> [Ref] -> IO ()
+mergeIndex h repo bs = forM_ bs $ \b ->
+ streamUpdateIndex repo [mergeTreeIndex b h repo]
+
+{- For merging two trees. -}
+mergeTrees :: Ref -> Ref -> CatFileHandle -> Repo -> Streamer
+mergeTrees (Ref x) (Ref y) h = doMerge h $ "diff-tree":diffOpts ++ [x, y]
+
+{- For merging a single tree into the index. -}
+mergeTreeIndex :: Ref -> CatFileHandle -> Repo -> Streamer
+mergeTreeIndex (Ref x) h = doMerge h $
+ "diff-index" : diffOpts ++ ["--cached", x]
+
+diffOpts :: [String]
+diffOpts = ["--raw", "-z", "-r", "--no-renames", "-l0"]
+
+{- Streams update-index changes to perform a merge,
+ - using git to get a raw diff. -}
+doMerge :: CatFileHandle -> [String] -> Repo -> Streamer
+doMerge ch differ repo streamer = do
+ (diff, cleanup) <- pipeNullSplit (map Param differ) repo
+ go diff
+ void $ cleanup
+ where
+ go [] = noop
+ go (info:file:rest) = mergeFile info file ch repo >>=
+ maybe (go rest) (\l -> streamer l >> go rest)
+ go (_:[]) = error $ "parse error " ++ show differ
+
+{- Given an info line from a git raw diff, and the filename, generates
+ - a line suitable for update-index that union merges the two sides of the
+ - diff. -}
+mergeFile :: String -> FilePath -> CatFileHandle -> Repo -> IO (Maybe String)
+mergeFile info file h repo = case filter (/= nullSha) [Ref asha, Ref bsha] of
+ [] -> return Nothing
+ (sha:[]) -> use sha
+ shas -> use
+ =<< either return (\s -> hashObject BlobObject (unlines s) repo)
+ =<< calcMerge . zip shas <$> mapM getcontents shas
+ where
+ [_colonmode, _bmode, asha, bsha, _status] = words info
+ use sha = return $ Just $
+ updateIndexLine sha FileBlob $ asTopFilePath file
+ -- We don't know how the file is encoded, but need to
+ -- split it into lines to union merge. Using the
+ -- FileSystemEncoding for this is a hack, but ensures there
+ -- are no decoding errors. Note that this works because
+ -- hashObject sets fileEncoding on its write handle.
+ getcontents s = lines . encodeW8 . L.unpack <$> catObject h s
+
+{- Calculates a union merge between a list of refs, with contents.
+ -
+ - When possible, reuses the content of an existing ref, rather than
+ - generating new content.
+ -}
+calcMerge :: [(Ref, [String])] -> Either Ref [String]
+calcMerge shacontents
+ | null reuseable = Right $ new
+ | otherwise = Left $ fst $ Prelude.head reuseable
+ where
+ reuseable = filter (\c -> sorteduniq (snd c) == new) shacontents
+ new = sorteduniq $ concat $ map snd shacontents
+ sorteduniq = S.toList . S.fromList
diff --git a/Git/UpdateIndex.hs b/Git/UpdateIndex.hs
new file mode 100644
index 000000000..3b33ac846
--- /dev/null
+++ b/Git/UpdateIndex.hs
@@ -0,0 +1,86 @@
+{- git-update-index library
+ -
+ - Copyright 2011-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE BangPatterns, CPP #-}
+
+module Git.UpdateIndex (
+ Streamer,
+ pureStreamer,
+ streamUpdateIndex,
+ lsTree,
+ updateIndexLine,
+ stageFile,
+ unstageFile,
+ stageSymlink
+) where
+
+import Common
+import Git
+import Git.Types
+import Git.Command
+import Git.FilePath
+import Git.Sha
+
+{- Streamers are passed a callback and should feed it lines in the form
+ - read by update-index, and generated by ls-tree. -}
+type Streamer = (String -> IO ()) -> IO ()
+
+{- A streamer with a precalculated value. -}
+pureStreamer :: String -> Streamer
+pureStreamer !s = \streamer -> streamer s
+
+{- Streams content into update-index from a list of Streamers. -}
+streamUpdateIndex :: Repo -> [Streamer] -> IO ()
+streamUpdateIndex repo as = pipeWrite params repo $ \h -> do
+ fileEncoding h
+ forM_ as (stream h)
+ hClose h
+ where
+ params = map Param ["update-index", "-z", "--index-info"]
+ stream h a = a (streamer h)
+ streamer h s = do
+ hPutStr h s
+ hPutStr h "\0"
+
+{- A streamer that adds the current tree for a ref. Useful for eg, copying
+ - and modifying branches. -}
+lsTree :: Ref -> Repo -> Streamer
+lsTree (Ref x) repo streamer = do
+ (s, cleanup) <- pipeNullSplit params repo
+ mapM_ streamer s
+ void $ cleanup
+ where
+ params = map Param ["ls-tree", "-z", "-r", "--full-tree", x]
+
+{- Generates a line suitable to be fed into update-index, to add
+ - a given file with a given sha. -}
+updateIndexLine :: Sha -> BlobType -> TopFilePath -> String
+updateIndexLine sha filetype file =
+ show filetype ++ " blob " ++ show sha ++ "\t" ++ indexPath file
+
+stageFile :: Sha -> BlobType -> FilePath -> Repo -> IO Streamer
+stageFile sha filetype file repo = do
+ p <- toTopFilePath file repo
+ return $ pureStreamer $ updateIndexLine sha filetype p
+
+{- A streamer that removes a file from the index. -}
+unstageFile :: FilePath -> Repo -> IO Streamer
+unstageFile file repo = do
+ p <- toTopFilePath file repo
+ return $ pureStreamer $ "0 " ++ show nullSha ++ "\t" ++ indexPath p
+
+{- A streamer that adds a symlink to the index. -}
+stageSymlink :: FilePath -> Sha -> Repo -> IO Streamer
+stageSymlink file sha repo = do
+ !line <- updateIndexLine
+ <$> pure sha
+ <*> pure SymlinkBlob
+ <*> toTopFilePath file repo
+ return $ pureStreamer line
+
+indexPath :: TopFilePath -> InternalGitPath
+indexPath = toInternalGitPath . getTopFilePath
diff --git a/Git/Url.hs b/Git/Url.hs
new file mode 100644
index 000000000..d383a6aca
--- /dev/null
+++ b/Git/Url.hs
@@ -0,0 +1,71 @@
+{- git repository urls
+ -
+ - Copyright 2010, 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Git.Url (
+ scheme,
+ host,
+ port,
+ hostuser,
+ authority,
+) where
+
+import Network.URI hiding (scheme, authority)
+
+import Common
+import Git.Types
+import Git
+
+{- Scheme of an URL repo. -}
+scheme :: Repo -> String
+scheme Repo { location = Url u } = uriScheme u
+scheme repo = notUrl repo
+
+{- Work around a bug in the real uriRegName
+ - <http://trac.haskell.org/network/ticket/40> -}
+uriRegName' :: URIAuth -> String
+uriRegName' a = fixup $ uriRegName a
+ where
+ fixup x@('[':rest)
+ | rest !! len == ']' = take len rest
+ | otherwise = x
+ where
+ len = length rest - 1
+ fixup x = x
+
+{- Hostname of an URL repo. -}
+host :: Repo -> Maybe String
+host = authpart uriRegName'
+
+{- Port of an URL repo, if it has a nonstandard one. -}
+port :: Repo -> Maybe Integer
+port r =
+ case authpart uriPort r of
+ Nothing -> Nothing
+ Just ":" -> Nothing
+ Just (':':p) -> readish p
+ Just _ -> Nothing
+
+{- Hostname of an URL repo, including any username (ie, "user@host") -}
+hostuser :: Repo -> Maybe String
+hostuser r = (++)
+ <$> authpart uriUserInfo r
+ <*> authpart uriRegName' r
+
+{- The full authority portion an URL repo. (ie, "user@host:port") -}
+authority :: Repo -> Maybe String
+authority = authpart assemble
+ where
+ assemble a = uriUserInfo a ++ uriRegName' a ++ uriPort a
+
+{- Applies a function to extract part of the uriAuthority of an URL repo. -}
+authpart :: (URIAuth -> a) -> Repo -> Maybe a
+authpart a Repo { location = Url u } = a <$> uriAuthority u
+authpart _ repo = notUrl repo
+
+notUrl :: Repo -> a
+notUrl repo = error $
+ "acting on local git repo " ++ repoDescribe repo ++ " not supported"
diff --git a/Git/Version.hs b/Git/Version.hs
new file mode 100644
index 000000000..5ad1d5959
--- /dev/null
+++ b/Git/Version.hs
@@ -0,0 +1,43 @@
+{- git versions
+ -
+ - Copyright 2011, 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Git.Version where
+
+import Common
+
+data GitVersion = GitVersion String Integer
+ deriving (Eq)
+
+instance Ord GitVersion where
+ compare (GitVersion _ x) (GitVersion _ y) = compare x y
+
+instance Show GitVersion where
+ show (GitVersion s _) = s
+
+installed :: IO GitVersion
+installed = normalize . extract <$> readProcess "git" ["--version"]
+ where
+ extract s = case lines s of
+ [] -> ""
+ (l:_) -> unwords $ drop 2 $ words l
+
+{- To compare dotted versions like 1.7.7 and 1.8, they are normalized to
+ - a somewhat arbitrary integer representation. -}
+normalize :: String -> GitVersion
+normalize v = GitVersion v $
+ sum $ mult 1 $ reverse $ extend precision $ take precision $
+ map readi $ split "." v
+ where
+ extend n l = l ++ replicate (n - length l) 0
+ mult _ [] = []
+ mult n (x:xs) = (n*x) : mult (n*10^width) xs
+ readi :: String -> Integer
+ readi s = case reads s of
+ ((x,_):_) -> x
+ _ -> 0
+ precision = 10 -- number of segments of the version to compare
+ width = length "yyyymmddhhmmss" -- maximum width of a segment
diff --git a/GitAnnex.hs b/GitAnnex.hs
new file mode 100644
index 000000000..61d8b918a
--- /dev/null
+++ b/GitAnnex.hs
@@ -0,0 +1,181 @@
+{- git-annex main program
+ -
+ - Copyright 2010 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP, OverloadedStrings #-}
+
+module GitAnnex where
+
+import qualified Git.CurrentRepo
+import CmdLine
+import Command
+import GitAnnex.Options
+
+import qualified Command.Add
+import qualified Command.Unannex
+import qualified Command.Drop
+import qualified Command.Move
+import qualified Command.Copy
+import qualified Command.Get
+import qualified Command.FromKey
+import qualified Command.DropKey
+import qualified Command.TransferKey
+#ifndef mingw32_HOST_OS
+import qualified Command.TransferKeys
+#endif
+import qualified Command.ReKey
+import qualified Command.Reinject
+import qualified Command.Fix
+import qualified Command.Init
+import qualified Command.Describe
+import qualified Command.InitRemote
+import qualified Command.EnableRemote
+import qualified Command.Fsck
+import qualified Command.Repair
+import qualified Command.Unused
+import qualified Command.DropUnused
+import qualified Command.AddUnused
+import qualified Command.Unlock
+import qualified Command.Lock
+import qualified Command.PreCommit
+import qualified Command.Find
+import qualified Command.Whereis
+import qualified Command.List
+import qualified Command.Log
+import qualified Command.Merge
+import qualified Command.Info
+import qualified Command.Status
+import qualified Command.Migrate
+import qualified Command.Uninit
+import qualified Command.Trust
+import qualified Command.Untrust
+import qualified Command.Semitrust
+import qualified Command.Dead
+import qualified Command.Group
+import qualified Command.Wanted
+import qualified Command.Schedule
+import qualified Command.Ungroup
+import qualified Command.Vicfg
+import qualified Command.Sync
+import qualified Command.Mirror
+import qualified Command.AddUrl
+#ifdef WITH_FEED
+import qualified Command.ImportFeed
+#endif
+import qualified Command.RmUrl
+import qualified Command.Import
+import qualified Command.Map
+import qualified Command.Direct
+import qualified Command.Indirect
+import qualified Command.Upgrade
+import qualified Command.Forget
+import qualified Command.Version
+import qualified Command.Help
+#ifdef WITH_ASSISTANT
+import qualified Command.Watch
+import qualified Command.Assistant
+#ifdef WITH_WEBAPP
+import qualified Command.WebApp
+#endif
+#ifdef WITH_XMPP
+import qualified Command.XMPPGit
+#endif
+#endif
+#ifdef WITH_TESTSUITE
+import qualified Command.Test
+import qualified Command.FuzzTest
+#endif
+#ifdef WITH_EKG
+import System.Remote.Monitoring
+#endif
+
+cmds :: [Command]
+cmds = concat
+ [ Command.Add.def
+ , Command.Get.def
+ , Command.Drop.def
+ , Command.Move.def
+ , Command.Copy.def
+ , Command.Unlock.def
+ , Command.Lock.def
+ , Command.Sync.def
+ , Command.Mirror.def
+ , Command.AddUrl.def
+#ifdef WITH_FEED
+ , Command.ImportFeed.def
+#endif
+ , Command.RmUrl.def
+ , Command.Import.def
+ , Command.Init.def
+ , Command.Describe.def
+ , Command.InitRemote.def
+ , Command.EnableRemote.def
+ , Command.Reinject.def
+ , Command.Unannex.def
+ , Command.Uninit.def
+ , Command.PreCommit.def
+ , Command.Trust.def
+ , Command.Untrust.def
+ , Command.Semitrust.def
+ , Command.Dead.def
+ , Command.Group.def
+ , Command.Wanted.def
+ , Command.Schedule.def
+ , Command.Ungroup.def
+ , Command.Vicfg.def
+ , Command.FromKey.def
+ , Command.DropKey.def
+ , Command.TransferKey.def
+#ifndef mingw32_HOST_OS
+ , Command.TransferKeys.def
+#endif
+ , Command.ReKey.def
+ , Command.Fix.def
+ , Command.Fsck.def
+ , Command.Repair.def
+ , Command.Unused.def
+ , Command.DropUnused.def
+ , Command.AddUnused.def
+ , Command.Find.def
+ , Command.Whereis.def
+ , Command.List.def
+ , Command.Log.def
+ , Command.Merge.def
+ , Command.Info.def
+ , Command.Status.def
+ , Command.Migrate.def
+ , Command.Map.def
+ , Command.Direct.def
+ , Command.Indirect.def
+ , Command.Upgrade.def
+ , Command.Forget.def
+ , Command.Version.def
+ , Command.Help.def
+#ifdef WITH_ASSISTANT
+ , Command.Watch.def
+ , Command.Assistant.def
+#ifdef WITH_WEBAPP
+ , Command.WebApp.def
+#endif
+#ifdef WITH_XMPP
+ , Command.XMPPGit.def
+#endif
+#endif
+#ifdef WITH_TESTSUITE
+ , Command.Test.def
+ , Command.FuzzTest.def
+#endif
+ ]
+
+header :: String
+header = "git-annex command [option ...]"
+
+run :: [String] -> IO ()
+run args = do
+#ifdef WITH_EKG
+ _ <- forkServer "localhost" 4242
+#endif
+ dispatch True args cmds options [] header Git.CurrentRepo.get
diff --git a/GitAnnex/Options.hs b/GitAnnex/Options.hs
new file mode 100644
index 000000000..88fad948a
--- /dev/null
+++ b/GitAnnex/Options.hs
@@ -0,0 +1,87 @@
+{- git-annex options
+ -
+ - Copyright 2010, 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module GitAnnex.Options where
+
+import System.Console.GetOpt
+
+import Common.Annex
+import qualified Git.Config
+import Git.Types
+import Command
+import Types.TrustLevel
+import qualified Annex
+import qualified Remote
+import qualified Limit
+import qualified Limit.Wanted
+import qualified Option
+
+options :: [Option]
+options = Option.common ++
+ [ Option ['N'] ["numcopies"] (ReqArg setnumcopies paramNumber)
+ "override default number of copies"
+ , Option [] ["trust"] (trustArg Trusted)
+ "override trust setting"
+ , Option [] ["semitrust"] (trustArg SemiTrusted)
+ "override trust setting back to default"
+ , Option [] ["untrust"] (trustArg UnTrusted)
+ "override trust setting to untrusted"
+ , Option ['c'] ["config"] (ReqArg setgitconfig "NAME=VALUE")
+ "override git configuration setting"
+ , Option ['x'] ["exclude"] (ReqArg Limit.addExclude paramGlob)
+ "skip files matching the glob pattern"
+ , Option ['I'] ["include"] (ReqArg Limit.addInclude paramGlob)
+ "limit to files matching the glob pattern"
+ , Option ['i'] ["in"] (ReqArg Limit.addIn paramRemote)
+ "match files present in a remote"
+ , Option ['C'] ["copies"] (ReqArg Limit.addCopies paramNumber)
+ "skip files with fewer copies"
+ , Option ['B'] ["inbackend"] (ReqArg Limit.addInBackend paramName)
+ "match files using a key-value backend"
+ , Option [] ["inallgroup"] (ReqArg Limit.addInAllGroup paramGroup)
+ "match files present in all remotes in a group"
+ , Option [] ["largerthan"] (ReqArg Limit.addLargerThan paramSize)
+ "match files larger than a size"
+ , Option [] ["smallerthan"] (ReqArg Limit.addSmallerThan paramSize)
+ "match files smaller than a size"
+ , Option [] ["want-get"] (NoArg Limit.Wanted.addWantGet)
+ "match files the repository wants to get"
+ , Option [] ["want-drop"] (NoArg Limit.Wanted.addWantDrop)
+ "match files the repository wants to drop"
+ , Option ['T'] ["time-limit"] (ReqArg Limit.addTimeLimit paramTime)
+ "stop after the specified amount of time"
+ , Option [] ["user-agent"] (ReqArg setuseragent paramName)
+ "override default User-Agent"
+ , Option [] ["trust-glacier"] (NoArg (Annex.setFlag "trustglacier"))
+ "Trust Amazon Glacier inventory"
+ ] ++ Option.matcher
+ where
+ trustArg t = ReqArg (Remote.forceTrust t) paramRemote
+ setnumcopies v = maybe noop
+ (\n -> Annex.changeState $ \s -> s { Annex.forcenumcopies = Just n })
+ (readish v)
+ setuseragent v = Annex.changeState $ \s -> s { Annex.useragent = Just v }
+ setgitconfig v = inRepo (Git.Config.store v)
+ >>= pure . (\r -> r { gitGlobalOpts = gitGlobalOpts r ++ [Param "-c", Param v] })
+ >>= Annex.changeGitRepo
+
+keyOptions :: [Option]
+keyOptions =
+ [ Option ['A'] ["all"] (NoArg (Annex.setFlag "all"))
+ "operate on all versions of all files"
+ , Option ['U'] ["unused"] (NoArg (Annex.setFlag "unused"))
+ "operate on files found by last run of git-annex unused"
+ ]
+
+fromOption :: Option
+fromOption = Option.field ['f'] "from" paramRemote "source remote"
+
+toOption :: Option
+toOption = Option.field ['t'] "to" paramRemote "destination remote"
+
+fromToOptions :: [Option]
+fromToOptions = [fromOption, toOption]
diff --git a/GitAnnexShell.hs b/GitAnnexShell.hs
new file mode 100644
index 000000000..b5f6804e7
--- /dev/null
+++ b/GitAnnexShell.hs
@@ -0,0 +1,200 @@
+{- git-annex-shell main program
+ -
+ - Copyright 2010-2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module GitAnnexShell where
+
+import System.Environment
+import System.Console.GetOpt
+
+import Common.Annex
+import qualified Git.Construct
+import CmdLine
+import Command
+import Annex.UUID
+import Annex (setField)
+import qualified Option
+import Fields
+import Utility.UserInfo
+import Remote.GCrypt (getGCryptUUID)
+import qualified Annex
+import Init
+
+import qualified Command.ConfigList
+import qualified Command.InAnnex
+import qualified Command.DropKey
+import qualified Command.RecvKey
+import qualified Command.SendKey
+import qualified Command.TransferInfo
+import qualified Command.Commit
+import qualified Command.GCryptSetup
+
+cmds_readonly :: [Command]
+cmds_readonly = concat
+ [ gitAnnexShellCheck Command.ConfigList.def
+ , gitAnnexShellCheck Command.InAnnex.def
+ , gitAnnexShellCheck Command.SendKey.def
+ , gitAnnexShellCheck Command.TransferInfo.def
+ ]
+
+cmds_notreadonly :: [Command]
+cmds_notreadonly = concat
+ [ gitAnnexShellCheck Command.RecvKey.def
+ , gitAnnexShellCheck Command.DropKey.def
+ , gitAnnexShellCheck Command.Commit.def
+ , Command.GCryptSetup.def
+ ]
+
+cmds :: [Command]
+cmds = map adddirparam $ cmds_readonly ++ cmds_notreadonly
+ where
+ adddirparam c = c { cmdparamdesc = "DIRECTORY " ++ cmdparamdesc c }
+
+options :: [OptDescr (Annex ())]
+options = Option.common ++
+ [ Option [] ["uuid"] (ReqArg checkUUID paramUUID) "local repository uuid"
+ ]
+ where
+ checkUUID expected = getUUID >>= check
+ where
+ check u | u == toUUID expected = noop
+ check NoUUID = checkGCryptUUID expected
+ check u = unexpectedUUID expected u
+ checkGCryptUUID expected = check =<< getGCryptUUID True =<< gitRepo
+ where
+ check (Just u) | u == toUUID expected = noop
+ check Nothing = unexpected expected "uninitialized repository"
+ check (Just u) = unexpectedUUID expected u
+ unexpectedUUID expected u = unexpected expected $ "UUID " ++ fromUUID u
+ unexpected expected s = error $
+ "expected repository UUID " ++ expected ++ " but found " ++ s
+
+header :: String
+header = "git-annex-shell [-c] command [parameters ...] [option ...]"
+
+run :: [String] -> IO ()
+run [] = failure
+-- skip leading -c options, passed by eg, ssh
+run ("-c":p) = run p
+-- a command can be either a builtin or something to pass to git-shell
+run c@(cmd:dir:params)
+ | cmd `elem` builtins = builtin cmd dir params
+ | otherwise = external c
+run c@(cmd:_)
+ -- Handle the case of being the user's login shell. It will be passed
+ -- a single string containing all the real parameters.
+ | "git-annex-shell " `isPrefixOf` cmd = run $ drop 1 $ shellUnEscape cmd
+ | cmd `elem` builtins = failure
+ | otherwise = external c
+
+builtins :: [String]
+builtins = map cmdname cmds
+
+builtin :: String -> String -> [String] -> IO ()
+builtin cmd dir params = do
+ checkNotReadOnly cmd
+ checkDirectory $ Just dir
+ let (params', fieldparams, opts) = partitionParams params
+ fields = filter checkField $ parseFields fieldparams
+ cmds' = map (newcmd $ unwords opts) cmds
+ dispatch False (cmd : params') cmds' options fields header $
+ Git.Construct.repoAbsPath dir >>= Git.Construct.fromAbsPath
+ where
+ addrsyncopts opts seek k = setField "RsyncOptions" opts >> seek k
+ newcmd opts c = c { cmdseek = map (addrsyncopts opts) (cmdseek c) }
+
+external :: [String] -> IO ()
+external params = do
+ {- Normal git-shell commands all have the directory as their last
+ - parameter. -}
+ let lastparam = lastMaybe =<< shellUnEscape <$> lastMaybe params
+ (params', _, _) = partitionParams params
+ checkDirectory lastparam
+ checkNotLimited
+ unlessM (boolSystem "git-shell" $ map Param $ "-c":params') $
+ error "git-shell failed"
+
+{- Split the input list into 3 groups separated with a double dash --.
+ - Parameters between two -- markers are field settings, in the form:
+ - field=value field=value
+ -
+ - Parameters after the last -- are the command itself and its arguments e.g.,
+ - rsync --bandwidth=100.
+ -}
+partitionParams :: [String] -> ([String], [String], [String])
+partitionParams ps = case segment (== "--") ps of
+ params:fieldparams:rest -> ( params, fieldparams, intercalate ["--"] rest )
+ [params] -> (params, [], [])
+ _ -> ([], [], [])
+
+parseFields :: [String] -> [(String, String)]
+parseFields = map (separate (== '='))
+
+{- Only allow known fields to be set, ignore others.
+ - Make sure that field values make sense. -}
+checkField :: (String, String) -> Bool
+checkField (field, value)
+ | field == fieldName remoteUUID = fieldCheck remoteUUID value
+ | field == fieldName associatedFile = fieldCheck associatedFile value
+ | field == fieldName direct = fieldCheck direct value
+ | otherwise = False
+
+failure :: IO ()
+failure = error $ "bad parameters\n\n" ++ usage header cmds
+
+checkNotLimited :: IO ()
+checkNotLimited = checkEnv "GIT_ANNEX_SHELL_LIMITED"
+
+checkNotReadOnly :: String -> IO ()
+checkNotReadOnly cmd
+ | cmd `elem` map cmdname cmds_readonly = noop
+ | otherwise = checkEnv "GIT_ANNEX_SHELL_READONLY"
+
+checkDirectory :: Maybe FilePath -> IO ()
+checkDirectory mdir = do
+ v <- catchMaybeIO $ getEnv "GIT_ANNEX_SHELL_DIRECTORY"
+ case (v, mdir) of
+ (Nothing, _) -> noop
+ (Just d, Nothing) -> req d Nothing
+ (Just d, Just dir)
+ | d `equalFilePath` dir -> noop
+ | otherwise -> do
+ home <- myHomeDir
+ d' <- canondir home d
+ dir' <- canondir home dir
+ if d' `equalFilePath` dir'
+ then noop
+ else req d' (Just dir')
+ where
+ req d mdir' = error $ unwords
+ [ "Only allowed to access"
+ , d
+ , maybe "and could not determine directory from command line" ("not " ++) mdir'
+ ]
+
+ {- A directory may start with ~/ or in some cases, even /~/,
+ - or could just be relative to home, or of course could
+ - be absolute. -}
+ canondir home d
+ | "~/" `isPrefixOf` d = return d
+ | "/~/" `isPrefixOf` d = return $ drop 1 d
+ | otherwise = relHome $ absPathFrom home d
+
+checkEnv :: String -> IO ()
+checkEnv var = do
+ v <- catchMaybeIO $ getEnv var
+ case v of
+ Nothing -> noop
+ Just "" -> noop
+ Just _ -> error $ "Action blocked by " ++ var
+
+{- Modifies a Command to check that it is run in either a git-annex
+ - repository, or a repository with a gcrypt-id set. -}
+gitAnnexShellCheck :: [Command] -> [Command]
+gitAnnexShellCheck = map $ addCheck okforshell . dontCheck repoExists
+ where
+ okforshell = unlessM (isInitialized <||> isJust . gcryptId <$> Annex.getGitConfig) $
+ error "Not a git-annex or gcrypt repository."
diff --git a/INSTALL b/INSTALL
new file mode 120000
index 000000000..67566818f
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1 @@
+doc/install.mdwn \ No newline at end of file
diff --git a/Init.hs b/Init.hs
new file mode 100644
index 000000000..ad1803995
--- /dev/null
+++ b/Init.hs
@@ -0,0 +1,175 @@
+{- git-annex repository initialization
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Init (
+ ensureInitialized,
+ isInitialized,
+ initialize,
+ uninitialize,
+ probeCrippledFileSystem,
+) where
+
+import Common.Annex
+import Utility.Network
+import qualified Annex
+import qualified Git
+import qualified Git.LsFiles
+import qualified Git.Config
+import qualified Annex.Branch
+import Logs.UUID
+import Annex.Version
+import Annex.UUID
+import Config
+import Annex.Direct
+import Annex.Content.Direct
+import Annex.Environment
+import Annex.Perms
+import Backend
+#ifndef mingw32_HOST_OS
+import Utility.UserInfo
+import Utility.FileMode
+#endif
+import Annex.Hook
+import Upgrade
+
+genDescription :: Maybe String -> Annex String
+genDescription (Just d) = return d
+genDescription Nothing = do
+ reldir <- liftIO . relHome =<< fromRepo Git.repoPath
+ hostname <- fromMaybe "" <$> liftIO getHostname
+#ifndef mingw32_HOST_OS
+ let at = if null hostname then "" else "@"
+ username <- liftIO myUserName
+ return $ concat [username, at, hostname, ":", reldir]
+#else
+ return $ concat [hostname, ":", reldir]
+#endif
+
+initialize :: Maybe String -> Annex ()
+initialize mdescription = do
+ prepUUID
+ checkFifoSupport
+ checkCrippledFileSystem
+ unlessM isBare $
+ hookWrite preCommitHook
+ ifM (crippledFileSystem <&&> not <$> isBare)
+ ( do
+ enableDirectMode
+ setDirect True
+ setVersion directModeVersion
+ , do
+ setVersion defaultVersion
+ setDirect False
+ )
+ createInodeSentinalFile
+ u <- getUUID
+ {- This will make the first commit to git, so ensure git is set up
+ - properly to allow commits when running it. -}
+ ensureCommit $ do
+ Annex.Branch.create
+ describeUUID u =<< genDescription mdescription
+
+uninitialize :: Annex ()
+uninitialize = do
+ hookUnWrite preCommitHook
+ removeRepoUUID
+ removeVersion
+
+{- Will automatically initialize if there is already a git-annex
+ - branch from somewhere. Otherwise, require a manual init
+ - to avoid git-annex accidentially being run in git
+ - repos that did not intend to use it.
+ -
+ - Checks repository version and handles upgrades too.
+ -}
+ensureInitialized :: Annex ()
+ensureInitialized = getVersion >>= maybe needsinit checkUpgrade
+ where
+ needsinit = ifM Annex.Branch.hasSibling
+ ( initialize Nothing
+ , error "First run: git-annex init"
+ )
+
+{- Checks if a repository is initialized. Does not check version for ugrade. -}
+isInitialized :: Annex Bool
+isInitialized = maybe Annex.Branch.hasSibling (const $ return True) =<< getVersion
+
+isBare :: Annex Bool
+isBare = fromRepo Git.repoIsLocalBare
+
+{- A crippled filesystem is one that does not allow making symlinks,
+ - or removing write access from files. -}
+probeCrippledFileSystem :: Annex Bool
+probeCrippledFileSystem = do
+#ifdef mingw32_HOST_OS
+ return True
+#else
+ tmp <- fromRepo gitAnnexTmpDir
+ let f = tmp </> "gaprobe"
+ createAnnexDirectory tmp
+ liftIO $ writeFile f ""
+ uncrippled <- liftIO $ probe f
+ liftIO $ removeFile f
+ return $ not uncrippled
+ where
+ probe f = catchBoolIO $ do
+ let f2 = f ++ "2"
+ nukeFile f2
+ createSymbolicLink f f2
+ nukeFile f2
+ preventWrite f
+ allowWrite f
+ return True
+#endif
+
+checkCrippledFileSystem :: Annex ()
+checkCrippledFileSystem = whenM probeCrippledFileSystem $ do
+ warning "Detected a crippled filesystem."
+ setCrippledFileSystem True
+
+ {- Normally git disables core.symlinks itself when the
+ - filesystem does not support them, but in Cygwin, git
+ - does support symlinks, while git-annex, not linking
+ - with Cygwin, does not. -}
+ whenM (coreSymlinks <$> Annex.getGitConfig) $ do
+ warning "Disabling core.symlinks."
+ setConfig (ConfigKey "core.symlinks")
+ (Git.Config.boolConfig False)
+
+probeFifoSupport :: Annex Bool
+probeFifoSupport = do
+#ifdef mingw32_HOST_OS
+ return False
+#else
+ tmp <- fromRepo gitAnnexTmpDir
+ let f = tmp </> "gaprobe"
+ createAnnexDirectory tmp
+ liftIO $ do
+ nukeFile f
+ ms <- tryIO $ do
+ createNamedPipe f ownerReadMode
+ getFileStatus f
+ nukeFile f
+ return $ either (const False) isNamedPipe ms
+#endif
+
+checkFifoSupport :: Annex ()
+checkFifoSupport = unlessM probeFifoSupport $ do
+ warning "Detected a filesystem without fifo support."
+ warning "Disabling ssh connection caching."
+ setConfig (annexConfig "sshcaching") (Git.Config.boolConfig False)
+
+enableDirectMode :: Annex ()
+enableDirectMode = unlessM isDirect $ do
+ warning "Enabling direct mode."
+ top <- fromRepo Git.repoPath
+ (l, clean) <- inRepo $ Git.LsFiles.inRepo [top]
+ forM_ l $ \f ->
+ maybe noop (`toDirect` f) =<< isAnnexLink f
+ void $ liftIO clean
diff --git a/Limit.hs b/Limit.hs
new file mode 100644
index 000000000..f3586e029
--- /dev/null
+++ b/Limit.hs
@@ -0,0 +1,251 @@
+{- user-specified limits on files to act on
+ -
+ - Copyright 2011-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Limit where
+
+import Data.Time.Clock.POSIX
+import qualified Data.Set as S
+import qualified Data.Map as M
+import System.Path.WildMatch
+import System.PosixCompat.Files
+
+import Common.Annex
+import qualified Annex
+import qualified Utility.Matcher
+import qualified Remote
+import qualified Backend
+import Annex.Content
+import Annex.UUID
+import Logs.Trust
+import Types.TrustLevel
+import Types.Key
+import Types.Group
+import Types.FileMatcher
+import Types.Limit
+import Logs.Group
+import Utility.HumanTime
+import Utility.DataUnits
+
+#ifdef WITH_TDFA
+import Text.Regex.TDFA
+import Text.Regex.TDFA.String
+#else
+#ifndef mingw32_HOST_OS
+import System.Path.WildMatch
+import Types.FileMatcher
+#endif
+#endif
+
+{- Checks if there are user-specified limits. -}
+limited :: Annex Bool
+limited = (not . Utility.Matcher.isEmpty) <$> getMatcher'
+
+{- Gets a matcher for the user-specified limits. The matcher is cached for
+ - speed; once it's obtained the user-specified limits can't change. -}
+getMatcher :: Annex (FileInfo -> Annex Bool)
+getMatcher = Utility.Matcher.matchM <$> getMatcher'
+
+getMatcher' :: Annex (Utility.Matcher.Matcher (FileInfo -> Annex Bool))
+getMatcher' = do
+ m <- Annex.getState Annex.limit
+ case m of
+ Right r -> return r
+ Left l -> do
+ let matcher = Utility.Matcher.generate (reverse l)
+ Annex.changeState $ \s ->
+ s { Annex.limit = Right matcher }
+ return matcher
+
+{- Adds something to the limit list, which is built up reversed. -}
+add :: Utility.Matcher.Token (FileInfo -> Annex Bool) -> Annex ()
+add l = Annex.changeState $ \s -> s { Annex.limit = prepend $ Annex.limit s }
+ where
+ prepend (Left ls) = Left $ l:ls
+ prepend _ = error "internal"
+
+{- Adds a new token. -}
+addToken :: String -> Annex ()
+addToken = add . Utility.Matcher.token
+
+{- Adds a new limit. -}
+addLimit :: Either String MatchFiles -> Annex ()
+addLimit = either error (\l -> add $ Utility.Matcher.Operation $ l S.empty)
+
+{- Add a limit to skip files that do not match the glob. -}
+addInclude :: String -> Annex ()
+addInclude = addLimit . limitInclude
+
+limitInclude :: MkLimit
+limitInclude glob = Right $ const $ return . matchglob glob
+
+{- Add a limit to skip files that match the glob. -}
+addExclude :: String -> Annex ()
+addExclude = addLimit . limitExclude
+
+limitExclude :: MkLimit
+limitExclude glob = Right $ const $ return . not . matchglob glob
+
+{- Could just use wildCheckCase, but this way the regex is only compiled
+ - once. Also, we use regex-TDFA when available, because it's less buggy
+ - in its support of non-unicode characters. -}
+matchglob :: String -> FileInfo -> Bool
+matchglob glob fi =
+#ifdef WITH_TDFA
+ case cregex of
+ Right r -> case execute r (matchFile fi) of
+ Right (Just _) -> True
+ _ -> False
+ Left _ -> error $ "failed to compile regex: " ++ regex
+ where
+ cregex = compile defaultCompOpt defaultExecOpt regex
+ regex = '^':wildToRegex glob
+#else
+ wildCheckCase glob (matchFile fi)
+#endif
+
+{- Adds a limit to skip files not believed to be present
+ - in a specfied repository. -}
+addIn :: String -> Annex ()
+addIn = addLimit . limitIn
+
+limitIn :: MkLimit
+limitIn name = Right $ \notpresent -> check $
+ if name == "."
+ then inhere notpresent
+ else inremote notpresent
+ where
+ check a = lookupFile >=> handle a
+ handle _ Nothing = return False
+ handle a (Just (key, _)) = a key
+ inremote notpresent key = do
+ u <- Remote.nameToUUID name
+ us <- Remote.keyLocations key
+ return $ u `elem` us && u `S.notMember` notpresent
+ inhere notpresent key
+ | S.null notpresent = inAnnex key
+ | otherwise = do
+ u <- getUUID
+ if u `S.member` notpresent
+ then return False
+ else inAnnex key
+
+{- Limit to content that is currently present on a uuid. -}
+limitPresent :: Maybe UUID -> MkLimit
+limitPresent u _ = Right $ const $ check $ \key -> do
+ hereu <- getUUID
+ if u == Just hereu || isNothing u
+ then inAnnex key
+ else do
+ us <- Remote.keyLocations key
+ return $ maybe False (`elem` us) u
+ where
+ check a = lookupFile >=> handle a
+ handle _ Nothing = return False
+ handle a (Just (key, _)) = a key
+
+{- Limit to content that is in a directory, anywhere in the repository tree -}
+limitInDir :: FilePath -> MkLimit
+limitInDir dir = const $ Right $ const $ \fi -> return $
+ any (== dir) $ splitPath $ takeDirectory $ matchFile fi
+
+{- Adds a limit to skip files not believed to have the specified number
+ - of copies. -}
+addCopies :: String -> Annex ()
+addCopies = addLimit . limitCopies
+
+limitCopies :: MkLimit
+limitCopies want = case split ":" want of
+ [v, n] -> case parsetrustspec v of
+ Just checker -> go n $ checktrust checker
+ Nothing -> go n $ checkgroup v
+ [n] -> go n $ const $ return True
+ _ -> Left "bad value for copies"
+ where
+ go num good = case readish num of
+ Nothing -> Left "bad number for copies"
+ Just n -> Right $ \notpresent f ->
+ lookupFile f >>= handle n good notpresent
+ handle _ _ _ Nothing = return False
+ handle n good notpresent (Just (key, _)) = do
+ us <- filter (`S.notMember` notpresent)
+ <$> (filterM good =<< Remote.keyLocations key)
+ return $ length us >= n
+ checktrust checker u = checker <$> lookupTrust u
+ checkgroup g u = S.member g <$> lookupGroups u
+ parsetrustspec s
+ | "+" `isSuffixOf` s = (>=) <$> readTrustLevel (beginning s)
+ | otherwise = (==) <$> readTrustLevel s
+
+{- Adds a limit to skip files not believed to be present in all
+ - repositories in the specified group. -}
+addInAllGroup :: String -> Annex ()
+addInAllGroup groupname = do
+ m <- groupMap
+ addLimit $ limitInAllGroup m groupname
+
+limitInAllGroup :: GroupMap -> MkLimit
+limitInAllGroup m groupname
+ | S.null want = Right $ const $ const $ return True
+ | otherwise = Right $ \notpresent -> lookupFile >=> check notpresent
+ where
+ want = fromMaybe S.empty $ M.lookup groupname $ uuidsByGroup m
+ check _ Nothing = return False
+ check notpresent (Just (key, _))
+ -- optimisation: Check if a wanted uuid is notpresent.
+ | not (S.null (S.intersection want notpresent)) = return False
+ | otherwise = do
+ present <- S.fromList <$> Remote.keyLocations key
+ return $ S.null $ want `S.difference` present
+
+{- Adds a limit to skip files not using a specified key-value backend. -}
+addInBackend :: String -> Annex ()
+addInBackend = addLimit . limitInBackend
+
+limitInBackend :: MkLimit
+limitInBackend name = Right $ const $ lookupFile >=> check
+ where
+ wanted = Backend.lookupBackendName name
+ check = return . maybe False ((==) wanted . snd)
+
+{- Adds a limit to skip files that are too large or too small -}
+addLargerThan :: String -> Annex ()
+addLargerThan = addLimit . limitSize (>)
+
+addSmallerThan :: String -> Annex ()
+addSmallerThan = addLimit . limitSize (<)
+
+limitSize :: (Maybe Integer -> Maybe Integer -> Bool) -> MkLimit
+limitSize vs s = case readSize dataUnits s of
+ Nothing -> Left "bad size"
+ Just sz -> Right $ go sz
+ where
+ go sz _ fi = lookupFile fi >>= check fi sz
+ check _ sz (Just (key, _)) = return $ keySize key `vs` Just sz
+ check fi sz Nothing = do
+ filesize <- liftIO $ catchMaybeIO $
+ fromIntegral . fileSize
+ <$> getFileStatus (relFile fi)
+ return $ filesize `vs` Just sz
+
+addTimeLimit :: String -> Annex ()
+addTimeLimit s = do
+ let seconds = maybe (error "bad time-limit") durationToPOSIXTime $
+ parseDuration s
+ start <- liftIO getPOSIXTime
+ let cutoff = start + seconds
+ addLimit $ Right $ const $ const $ do
+ now <- liftIO getPOSIXTime
+ if now > cutoff
+ then do
+ warning $ "Time limit (" ++ s ++ ") reached!"
+ liftIO $ exitWith $ ExitFailure 101
+ else return True
+
+lookupFile :: FileInfo -> Annex (Maybe (Key, Backend))
+lookupFile = Backend.lookupFile . relFile
diff --git a/Limit/Wanted.hs b/Limit/Wanted.hs
new file mode 100644
index 000000000..ed4529dea
--- /dev/null
+++ b/Limit/Wanted.hs
@@ -0,0 +1,21 @@
+{- git-annex limits by wanted status
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Limit.Wanted where
+
+import Common.Annex
+import Annex.Wanted
+import Limit
+import Types.FileMatcher
+
+addWantGet :: Annex ()
+addWantGet = addLimit $ Right $ const $
+ \fileinfo -> wantGet False (Just $ matchFile fileinfo)
+
+addWantDrop :: Annex ()
+addWantDrop = addLimit $ Right $ const $
+ \fileinfo -> wantDrop False Nothing (Just $ matchFile fileinfo)
diff --git a/Locations.hs b/Locations.hs
new file mode 100644
index 000000000..47a009590
--- /dev/null
+++ b/Locations.hs
@@ -0,0 +1,412 @@
+{- git-annex file locations
+ -
+ - Copyright 2010-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Locations (
+ keyFile,
+ fileKey,
+ keyPaths,
+ keyPath,
+ annexDir,
+ objectDir,
+ gitAnnexLocation,
+ gitAnnexLink,
+ gitAnnexMapping,
+ gitAnnexInodeCache,
+ gitAnnexInodeSentinal,
+ gitAnnexInodeSentinalCache,
+ annexLocations,
+ annexLocation,
+ gitAnnexDir,
+ gitAnnexObjectDir,
+ gitAnnexTmpDir,
+ gitAnnexTmpLocation,
+ gitAnnexBadDir,
+ gitAnnexBadLocation,
+ gitAnnexUnusedLog,
+ gitAnnexFsckState,
+ gitAnnexFsckResultsLog,
+ gitAnnexScheduleState,
+ gitAnnexTransferDir,
+ gitAnnexCredsDir,
+ gitAnnexFeedStateDir,
+ gitAnnexFeedState,
+ gitAnnexMergeDir,
+ gitAnnexJournalDir,
+ gitAnnexJournalLock,
+ gitAnnexIndex,
+ gitAnnexIndexStatus,
+ gitAnnexIgnoredRefs,
+ gitAnnexPidFile,
+ gitAnnexDaemonStatusFile,
+ gitAnnexLogFile,
+ gitAnnexFuzzTestLogFile,
+ gitAnnexHtmlShim,
+ gitAnnexUrlFile,
+ gitAnnexTmpCfgFile,
+ gitAnnexSshDir,
+ gitAnnexRemotesDir,
+ gitAnnexAssistantDefaultDir,
+ isLinkToAnnex,
+ annexHashes,
+ hashDirMixed,
+ hashDirLower,
+ preSanitizeKeyName,
+
+ prop_idempotent_fileKey
+) where
+
+import Data.Bits
+import Data.Word
+import Data.Hash.MD5
+import Data.Char
+
+import Common
+import Types
+import Types.Key
+import Types.UUID
+import qualified Git
+
+{- Conventions:
+ -
+ - Functions ending in "Dir" should always return values ending with a
+ - trailing path separator. Most code does not rely on that, but a few
+ - things do.
+ -
+ - Everything else should not end in a trailing path sepatator.
+ -
+ - Only functions (with names starting with "git") that build a path
+ - based on a git repository should return an absolute path.
+ - Everything else should use relative paths.
+ -}
+
+{- The directory git annex uses for local state, relative to the .git
+ - directory -}
+annexDir :: FilePath
+annexDir = addTrailingPathSeparator "annex"
+
+{- The directory git annex uses for locally available object content,
+ - relative to the .git directory -}
+objectDir :: FilePath
+objectDir = addTrailingPathSeparator $ annexDir </> "objects"
+
+{- Annexed file's possible locations relative to the .git directory.
+ - There are two different possibilities, using different hashes. -}
+annexLocations :: Key -> [FilePath]
+annexLocations key = map (annexLocation key) annexHashes
+annexLocation :: Key -> Hasher -> FilePath
+annexLocation key hasher = objectDir </> keyPath key hasher
+
+{- Annexed object's absolute location in a repository.
+ -
+ - When there are multiple possible locations, returns the one where the
+ - file is actually present.
+ -
+ - When the file is not present, returns the location where the file should
+ - be stored.
+ -
+ - This does not take direct mode into account, so in direct mode it is not
+ - the actual location of the file's content.
+ -}
+gitAnnexLocation :: Key -> Git.Repo -> GitConfig -> IO FilePath
+gitAnnexLocation key r config = gitAnnexLocation' key r (annexCrippledFileSystem config)
+gitAnnexLocation' :: Key -> Git.Repo -> Bool -> IO FilePath
+gitAnnexLocation' key r crippled
+ {- Bare repositories default to hashDirLower for new
+ - content, as it's more portable.
+ -
+ - Repositories on filesystems that are crippled also use
+ - hashDirLower, since they do not use symlinks and it's
+ - more portable. -}
+ | Git.repoIsLocalBare r || crippled =
+ check $ map inrepo $ annexLocations key
+ {- Non-bare repositories only use hashDirMixed, so
+ - don't need to do any work to check if the file is
+ - present. -}
+ | otherwise = return $ inrepo $ annexLocation key hashDirMixed
+ where
+ inrepo d = Git.localGitDir r </> d
+ check locs@(l:_) = fromMaybe l <$> firstM doesFileExist locs
+ check [] = error "internal"
+
+{- Calculates a symlink to link a file to an annexed object. -}
+gitAnnexLink :: FilePath -> Key -> Git.Repo -> IO FilePath
+gitAnnexLink file key r = do
+ cwd <- getCurrentDirectory
+ let absfile = fromMaybe whoops $ absNormPath cwd file
+ loc <- gitAnnexLocation' key r False
+ return $ relPathDirToFile (parentDir absfile) loc
+ where
+ whoops = error $ "unable to normalize " ++ file
+
+{- File that maps from a key to the file(s) in the git repository.
+ - Used in direct mode. -}
+gitAnnexMapping :: Key -> Git.Repo -> GitConfig -> IO FilePath
+gitAnnexMapping key r config = do
+ loc <- gitAnnexLocation key r config
+ return $ loc ++ ".map"
+
+{- File that caches information about a key's content, used to determine
+ - if a file has changed.
+ - Used in direct mode. -}
+gitAnnexInodeCache :: Key -> Git.Repo -> GitConfig -> IO FilePath
+gitAnnexInodeCache key r config = do
+ loc <- gitAnnexLocation key r config
+ return $ loc ++ ".cache"
+
+gitAnnexInodeSentinal :: Git.Repo -> FilePath
+gitAnnexInodeSentinal r = gitAnnexDir r </> "sentinal"
+
+gitAnnexInodeSentinalCache :: Git.Repo -> FilePath
+gitAnnexInodeSentinalCache r = gitAnnexInodeSentinal r ++ ".cache"
+
+{- The annex directory of a repository. -}
+gitAnnexDir :: Git.Repo -> FilePath
+gitAnnexDir r = addTrailingPathSeparator $ Git.localGitDir r </> annexDir
+
+{- The part of the annex directory where file contents are stored. -}
+gitAnnexObjectDir :: Git.Repo -> FilePath
+gitAnnexObjectDir r = addTrailingPathSeparator $ Git.localGitDir r </> objectDir
+
+{- .git/annex/tmp/ is used for temp files -}
+gitAnnexTmpDir :: Git.Repo -> FilePath
+gitAnnexTmpDir r = addTrailingPathSeparator $ gitAnnexDir r </> "tmp"
+
+{- The temp file to use for a given key's content. -}
+gitAnnexTmpLocation :: Key -> Git.Repo -> FilePath
+gitAnnexTmpLocation key r = gitAnnexTmpDir r </> keyFile key
+
+{- .git/annex/bad/ is used for bad files found during fsck -}
+gitAnnexBadDir :: Git.Repo -> FilePath
+gitAnnexBadDir r = addTrailingPathSeparator $ gitAnnexDir r </> "bad"
+
+{- The bad file to use for a given key. -}
+gitAnnexBadLocation :: Key -> Git.Repo -> FilePath
+gitAnnexBadLocation key r = gitAnnexBadDir r </> keyFile key
+
+{- .git/annex/foounused is used to number possibly unused keys -}
+gitAnnexUnusedLog :: FilePath -> Git.Repo -> FilePath
+gitAnnexUnusedLog prefix r = gitAnnexDir r </> (prefix ++ "unused")
+
+{- .git/annex/fsckstate is used to store information about incremental fscks. -}
+gitAnnexFsckState :: Git.Repo -> FilePath
+gitAnnexFsckState r = gitAnnexDir r </> "fsckstate"
+
+{- .git/annex/fsckresults/uuid is used to store results of git fscks -}
+gitAnnexFsckResultsLog :: UUID -> Git.Repo -> FilePath
+gitAnnexFsckResultsLog u r = gitAnnexDir r </> "fsckresults" </> fromUUID u
+
+{- .git/annex/schedulestate is used to store information about when
+ - scheduled jobs were last run. -}
+gitAnnexScheduleState :: Git.Repo -> FilePath
+gitAnnexScheduleState r = gitAnnexDir r </> "schedulestate"
+
+{- .git/annex/creds/ is used to store credentials to access some special
+ - remotes. -}
+gitAnnexCredsDir :: Git.Repo -> FilePath
+gitAnnexCredsDir r = addTrailingPathSeparator $ gitAnnexDir r </> "creds"
+
+{- .git/annex/feeds/ is used to record per-key (url) state by importfeeds -}
+gitAnnexFeedStateDir :: Git.Repo -> FilePath
+gitAnnexFeedStateDir r = addTrailingPathSeparator $ gitAnnexDir r </> "feedstate"
+
+gitAnnexFeedState :: Key -> Git.Repo -> FilePath
+gitAnnexFeedState k r = gitAnnexFeedStateDir r </> keyFile k
+
+{- .git/annex/merge/ is used for direct mode merges. -}
+gitAnnexMergeDir :: Git.Repo -> FilePath
+gitAnnexMergeDir r = addTrailingPathSeparator $ gitAnnexDir r </> "merge"
+
+{- .git/annex/transfer/ is used to record keys currently
+ - being transferred, and other transfer bookkeeping info. -}
+gitAnnexTransferDir :: Git.Repo -> FilePath
+gitAnnexTransferDir r = addTrailingPathSeparator $ gitAnnexDir r </> "transfer"
+
+{- .git/annex/journal/ is used to journal changes made to the git-annex
+ - branch -}
+gitAnnexJournalDir :: Git.Repo -> FilePath
+gitAnnexJournalDir r = addTrailingPathSeparator $ gitAnnexDir r </> "journal"
+
+{- Lock file for the journal. -}
+gitAnnexJournalLock :: Git.Repo -> FilePath
+gitAnnexJournalLock r = gitAnnexDir r </> "journal.lck"
+
+{- .git/annex/index is used to stage changes to the git-annex branch -}
+gitAnnexIndex :: Git.Repo -> FilePath
+gitAnnexIndex r = gitAnnexDir r </> "index"
+
+{- Holds the ref of the git-annex branch that the index was last updated to.
+ -
+ - The .lck in the name is a historical accident; this is not used as a
+ - lock. -}
+gitAnnexIndexStatus :: Git.Repo -> FilePath
+gitAnnexIndexStatus r = gitAnnexDir r </> "index.lck"
+
+{- List of refs that should not be merged into the git-annex branch. -}
+gitAnnexIgnoredRefs :: Git.Repo -> FilePath
+gitAnnexIgnoredRefs r = gitAnnexDir r </> "ignoredrefs"
+
+{- Pid file for daemon mode. -}
+gitAnnexPidFile :: Git.Repo -> FilePath
+gitAnnexPidFile r = gitAnnexDir r </> "daemon.pid"
+
+{- Status file for daemon mode. -}
+gitAnnexDaemonStatusFile :: Git.Repo -> FilePath
+gitAnnexDaemonStatusFile r = gitAnnexDir r </> "daemon.status"
+
+{- Log file for daemon mode. -}
+gitAnnexLogFile :: Git.Repo -> FilePath
+gitAnnexLogFile r = gitAnnexDir r </> "daemon.log"
+
+{- Log file for fuzz test. -}
+gitAnnexFuzzTestLogFile :: Git.Repo -> FilePath
+gitAnnexFuzzTestLogFile r = gitAnnexDir r </> "fuzztest.log"
+
+{- Html shim file used to launch the webapp. -}
+gitAnnexHtmlShim :: Git.Repo -> FilePath
+gitAnnexHtmlShim r = gitAnnexDir r </> "webapp.html"
+
+{- File containing the url to the webapp. -}
+gitAnnexUrlFile :: Git.Repo -> FilePath
+gitAnnexUrlFile r = gitAnnexDir r </> "url"
+
+{- Temporary file used to edit configuriation from the git-annex branch. -}
+gitAnnexTmpCfgFile :: Git.Repo -> FilePath
+gitAnnexTmpCfgFile r = gitAnnexDir r </> "config.tmp"
+
+{- .git/annex/ssh/ is used for ssh connection caching -}
+gitAnnexSshDir :: Git.Repo -> FilePath
+gitAnnexSshDir r = addTrailingPathSeparator $ gitAnnexDir r </> "ssh"
+
+{- .git/annex/remotes/ is used for remote-specific state. -}
+gitAnnexRemotesDir :: Git.Repo -> FilePath
+gitAnnexRemotesDir r = addTrailingPathSeparator $ gitAnnexDir r </> "remotes"
+
+{- This is the base directory name used by the assistant when making
+ - repositories, by default. -}
+gitAnnexAssistantDefaultDir :: FilePath
+gitAnnexAssistantDefaultDir = "annex"
+
+{- Checks a symlink target to see if it appears to point to annexed content.
+ -
+ - We only look at paths inside the .git directory, and not at the .git
+ - directory itself, because GIT_DIR may cause a directory name other
+ - than .git to be used.
+ -}
+isLinkToAnnex :: FilePath -> Bool
+isLinkToAnnex s = (pathSeparator:objectDir) `isInfixOf` s
+
+{- Sanitizes a String that will be used as part of a Key's keyName,
+ - dealing with characters that cause problems on substandard filesystems.
+ -
+ - This is used when a new Key is initially being generated, eg by getKey.
+ - Unlike keyFile and fileKey, it does not need to be a reversable
+ - escaping. Also, it's ok to change this to add more problimatic
+ - characters later. Unlike changing keyFile, which could result in the
+ - filenames used for existing keys changing and contents getting lost.
+ -
+ - It is, however, important that the input and output of this function
+ - have a 1:1 mapping, to avoid two different inputs from mapping to the
+ - same key.
+ -}
+preSanitizeKeyName :: String -> String
+preSanitizeKeyName = concatMap escape
+ where
+ escape c
+ | isAsciiUpper c || isAsciiLower c || isDigit c = [c]
+ | c `elem` ".-_ " = [c] -- common, assumed safe
+ | c `elem` "/%:" = [c] -- handled by keyFile
+ -- , is safe and uncommon, so will be used to escape
+ -- other characters. By itself, it is escaped to
+ -- doubled form.
+ | c == ',' = ",,"
+ | otherwise = ',' : show(ord(c))
+
+{- Converts a key into a filename fragment without any directory.
+ -
+ - Escape "/" in the key name, to keep a flat tree of files and avoid
+ - issues with keys containing "/../" or ending with "/" etc.
+ -
+ - "/" is escaped to "%" because it's short and rarely used, and resembles
+ - a slash
+ - "%" is escaped to "&s", and "&" to "&a"; this ensures that the mapping
+ - is one to one.
+ - ":" is escaped to "&c", because it seemed like a good idea at the time.
+ -
+ - Changing what this function escapes and how is not a good idea, as it
+ - can cause existing objects to get lost.
+ -}
+keyFile :: Key -> FilePath
+keyFile key = replace "/" "%" $ replace ":" "&c" $
+ replace "%" "&s" $ replace "&" "&a" $ key2file key
+
+{- Reverses keyFile, converting a filename fragment (ie, the basename of
+ - the symlink target) into a key. -}
+fileKey :: FilePath -> Maybe Key
+fileKey file = file2key $
+ replace "&a" "&" $ replace "&s" "%" $
+ replace "&c" ":" $ replace "%" "/" file
+
+{- for quickcheck -}
+prop_idempotent_fileKey :: String -> Bool
+prop_idempotent_fileKey s
+ | null s = True -- it's not legal for a key to have no keyName
+ | otherwise= Just k == fileKey (keyFile k)
+ where
+ k = stubKey { keyName = s, keyBackendName = "test" }
+
+{- A location to store a key on the filesystem. A directory hash is used,
+ - to protect against filesystems that dislike having many items in a
+ - single directory.
+ -
+ - The file is put in a directory with the same name, this allows
+ - write-protecting the directory to avoid accidental deletion of the file.
+ -}
+keyPath :: Key -> Hasher -> FilePath
+keyPath key hasher = hasher key </> f </> f
+ where
+ f = keyFile key
+
+{- All possibile locations to store a key using different directory hashes. -}
+keyPaths :: Key -> [FilePath]
+keyPaths key = map (keyPath key) annexHashes
+
+{- Two different directory hashes may be used. The mixed case hash
+ - came first, and is fine, except for the problem of case-strict
+ - filesystems such as Linux VFAT (mounted with shortname=mixed),
+ - which do not allow using a directory "XX" when "xx" already exists.
+ - To support that, most repositories use the lower case hash for new data. -}
+type Hasher = Key -> FilePath
+annexHashes :: [Hasher]
+annexHashes = [hashDirLower, hashDirMixed]
+
+hashDirMixed :: Hasher
+hashDirMixed k = addTrailingPathSeparator $ take 2 dir </> drop 2 dir
+ where
+ dir = take 4 $ display_32bits_as_dir =<< [a,b,c,d]
+ ABCD (a,b,c,d) = md5 $ md5FilePath $ key2file k
+
+hashDirLower :: Hasher
+hashDirLower k = addTrailingPathSeparator $ take 3 dir </> drop 3 dir
+ where
+ dir = take 6 $ md5s $ md5FilePath $ key2file k
+
+{- modified version of display_32bits_as_hex from Data.Hash.MD5
+ - Copyright (C) 2001 Ian Lynagh
+ - License: Either BSD or GPL
+ -}
+display_32bits_as_dir :: Word32 -> String
+display_32bits_as_dir w = trim $ swap_pairs cs
+ where
+ -- Need 32 characters to use. To avoid inaverdently making
+ -- a real word, use letters that appear less frequently.
+ chars = ['0'..'9'] ++ "zqjxkmvwgpfZQJXKMVWGPF"
+ cs = map (\x -> getc $ (shiftR w (6*x)) .&. 31) [0..7]
+ getc n = chars !! fromIntegral n
+ swap_pairs (x1:x2:xs) = x2:x1:swap_pairs xs
+ swap_pairs _ = []
+ -- Last 2 will always be 00, so omit.
+ trim = take 6
diff --git a/Logs.hs b/Logs.hs
new file mode 100644
index 000000000..4386b7fd7
--- /dev/null
+++ b/Logs.hs
@@ -0,0 +1,114 @@
+{- git-annex log file names
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Logs where
+
+import Common.Annex
+import Types.Key
+
+data LogVariety = UUIDBasedLog | PresenceLog Key
+ deriving (Show)
+
+{- Converts a path from the git-annex branch into one of the varieties
+ - of logs used by git-annex, if it's a known path. -}
+getLogVariety :: FilePath -> Maybe LogVariety
+getLogVariety f
+ | f `elem` uuidBasedLogs = Just UUIDBasedLog
+ | otherwise = PresenceLog <$> firstJust (presenceLogs f)
+
+{- All the uuid-based logs stored in the git-annex branch. -}
+uuidBasedLogs :: [FilePath]
+uuidBasedLogs =
+ [ uuidLog
+ , remoteLog
+ , trustLog
+ , groupLog
+ , preferredContentLog
+ , scheduleLog
+ ]
+
+{- All the ways to get a key from a presence log file -}
+presenceLogs :: FilePath -> [Maybe Key]
+presenceLogs f =
+ [ urlLogFileKey f
+ , locationLogFileKey f
+ ]
+
+uuidLog :: FilePath
+uuidLog = "uuid.log"
+
+remoteLog :: FilePath
+remoteLog = "remote.log"
+
+trustLog :: FilePath
+trustLog = "trust.log"
+
+groupLog :: FilePath
+groupLog = "group.log"
+
+preferredContentLog :: FilePath
+preferredContentLog = "preferred-content.log"
+
+scheduleLog :: FilePath
+scheduleLog = "schedule.log"
+
+{- The pathname of the location log file for a given key. -}
+locationLogFile :: Key -> String
+locationLogFile key = hashDirLower key ++ keyFile key ++ ".log"
+
+{- Converts a pathname into a key if it's a location log. -}
+locationLogFileKey :: FilePath -> Maybe Key
+locationLogFileKey path
+ | ["remote", "web"] `isPrefixOf` splitDirectories dir = Nothing
+ | ext == ".log" = fileKey base
+ | otherwise = Nothing
+ where
+ (dir, file) = splitFileName path
+ (base, ext) = splitAt (length file - 4) file
+
+{- The filename of the url log for a given key. -}
+urlLogFile :: Key -> FilePath
+urlLogFile key = hashDirLower key </> keyFile key ++ urlLogExt
+
+{- Old versions stored the urls elsewhere. -}
+oldurlLogs :: Key -> [FilePath]
+oldurlLogs key =
+ [ "remote/web" </> hashDirLower key </> key2file key ++ ".log"
+ , "remote/web" </> hashDirLower key </> keyFile key ++ ".log"
+ ]
+
+urlLogExt :: String
+urlLogExt = ".log.web"
+
+{- Converts a url log file into a key.
+ - (Does not work on oldurlLogs.) -}
+urlLogFileKey :: FilePath -> Maybe Key
+urlLogFileKey path
+ | ext == urlLogExt = fileKey base
+ | otherwise = Nothing
+ where
+ file = takeFileName path
+ (base, ext) = splitAt (length file - extlen) file
+ extlen = length urlLogExt
+
+{- Does not work on oldurllogs. -}
+isUrlLog :: FilePath -> Bool
+isUrlLog file = urlLogExt `isSuffixOf` file
+
+prop_logs_sane :: Key -> Bool
+prop_logs_sane dummykey = all id
+ [ isNothing (getLogVariety "unknown")
+ , expect isUUIDBasedLog (getLogVariety uuidLog)
+ , expect isPresenceLog (getLogVariety $ locationLogFile dummykey)
+ , expect isPresenceLog (getLogVariety $ urlLogFile dummykey)
+ ]
+ where
+ expect = maybe False
+ isUUIDBasedLog UUIDBasedLog = True
+ isUUIDBasedLog _ = False
+ isPresenceLog (PresenceLog k) = k == dummykey
+ isPresenceLog _ = False
diff --git a/Logs/FsckResults.hs b/Logs/FsckResults.hs
new file mode 100644
index 000000000..75ed7389c
--- /dev/null
+++ b/Logs/FsckResults.hs
@@ -0,0 +1,43 @@
+{- git-annex fsck results log files
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Logs.FsckResults (
+ writeFsckResults,
+ readFsckResults
+) where
+
+import Common.Annex
+import Utility.Tmp
+import Git.Fsck
+import Git.Types
+
+import qualified Data.Set as S
+
+writeFsckResults :: UUID -> FsckResults -> Annex ()
+writeFsckResults u fsckresults = do
+ logfile <- fromRepo $ gitAnnexFsckResultsLog u
+ liftIO $
+ case fsckresults of
+ Nothing -> store S.empty logfile
+ Just s
+ | S.null s -> nukeFile logfile
+ | otherwise -> store s logfile
+ where
+ store s logfile = do
+ createDirectoryIfMissing True (parentDir logfile)
+ liftIO $ viaTmp writeFile logfile $ serialize s
+ serialize = unlines . map show . S.toList
+
+readFsckResults :: UUID -> Annex FsckResults
+readFsckResults u = do
+ logfile <- fromRepo $ gitAnnexFsckResultsLog u
+ liftIO $ catchDefaultIO (Just S.empty) $
+ deserialize <$> readFile logfile
+ where
+ deserialize l =
+ let s = S.fromList $ map Ref $ lines l
+ in if S.null s then Nothing else Just s
diff --git a/Logs/Group.hs b/Logs/Group.hs
new file mode 100644
index 000000000..3f88b627d
--- /dev/null
+++ b/Logs/Group.hs
@@ -0,0 +1,83 @@
+{- git-annex group log
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Logs.Group (
+ groupLog,
+ groupChange,
+ groupSet,
+ lookupGroups,
+ groupMap,
+ groupMapLoad,
+ getStandardGroup,
+ inUnwantedGroup
+) where
+
+import qualified Data.Map as M
+import qualified Data.Set as S
+import Data.Time.Clock.POSIX
+
+import Common.Annex
+import Logs
+import qualified Annex.Branch
+import qualified Annex
+import Logs.UUIDBased
+import Types.Group
+import Types.StandardGroups
+
+{- Returns the groups of a given repo UUID. -}
+lookupGroups :: UUID -> Annex (S.Set Group)
+lookupGroups u = (fromMaybe S.empty . M.lookup u) . groupsByUUID <$> groupMap
+
+{- Applies a set modifier to change the groups for a uuid in the groupLog. -}
+groupChange :: UUID -> (S.Set Group -> S.Set Group) -> Annex ()
+groupChange uuid@(UUID _) modifier = do
+ curr <- lookupGroups uuid
+ ts <- liftIO getPOSIXTime
+ Annex.Branch.change groupLog $
+ showLog (unwords . S.toList) .
+ changeLog ts uuid (modifier curr) .
+ parseLog (Just . S.fromList . words)
+
+ -- The changed group invalidates the preferred content cache.
+ Annex.changeState $ \s -> s
+ { Annex.groupmap = Nothing
+ , Annex.preferredcontentmap = Nothing
+ }
+groupChange NoUUID _ = error "unknown UUID; cannot modify"
+
+groupSet :: UUID -> S.Set Group -> Annex ()
+groupSet u g = groupChange u (const g)
+
+{- The map is cached for speed. -}
+groupMap :: Annex GroupMap
+groupMap = maybe groupMapLoad return =<< Annex.getState Annex.groupmap
+
+{- Loads the map, updating the cache. -}
+groupMapLoad :: Annex GroupMap
+groupMapLoad = do
+ m <- makeGroupMap . simpleMap .
+ parseLog (Just . S.fromList . words) <$>
+ Annex.Branch.get groupLog
+ Annex.changeState $ \s -> s { Annex.groupmap = Just m }
+ return m
+
+makeGroupMap :: M.Map UUID (S.Set Group) -> GroupMap
+makeGroupMap byuuid = GroupMap byuuid bygroup
+ where
+ bygroup = M.fromListWith S.union $
+ concatMap explode $ M.toList byuuid
+ explode (u, s) = map (\g -> (g, S.singleton u)) (S.toList s)
+
+{- If a repository is in exactly one standard group, returns it. -}
+getStandardGroup :: S.Set Group -> Maybe StandardGroup
+getStandardGroup s = case mapMaybe toStandardGroup $ S.toList s of
+ [g] -> Just g
+ _ -> Nothing
+
+inUnwantedGroup :: UUID -> Annex Bool
+inUnwantedGroup u = elem UnwantedGroup
+ . mapMaybe toStandardGroup . S.toList <$> lookupGroups u
diff --git a/Logs/Location.hs b/Logs/Location.hs
new file mode 100644
index 000000000..f751c00de
--- /dev/null
+++ b/Logs/Location.hs
@@ -0,0 +1,63 @@
+{-# LANGUAGE BangPatterns #-}
+
+{- git-annex location log
+ -
+ - git-annex keeps track of which repositories have the contents of annexed
+ - files.
+ -
+ - Repositories record their UUID and the date when they --get or --drop
+ - a value.
+ -
+ - Copyright 2010-2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Logs.Location (
+ LogStatus(..),
+ logStatus,
+ logChange,
+ loggedLocations,
+ loggedKeys,
+ loggedKeysFor,
+) where
+
+import Common.Annex
+import qualified Annex.Branch
+import Logs
+import Logs.Presence
+import Annex.UUID
+
+{- Log a change in the presence of a key's value in current repository. -}
+logStatus :: Key -> LogStatus -> Annex ()
+logStatus key s = do
+ u <- getUUID
+ logChange key u s
+
+{- Log a change in the presence of a key's value in a repository. -}
+logChange :: Key -> UUID -> LogStatus -> Annex ()
+logChange key (UUID u) s = addLog (locationLogFile key) =<< logNow s u
+logChange _ NoUUID _ = noop
+
+{- Returns a list of repository UUIDs that, according to the log, have
+ - the value of a key.
+ -}
+loggedLocations :: Key -> Annex [UUID]
+loggedLocations key = map toUUID <$> (currentLog . locationLogFile) key
+
+{- Finds all keys that have location log information.
+ - (There may be duplicate keys in the list.) -}
+loggedKeys :: Annex [Key]
+loggedKeys = mapMaybe locationLogFileKey <$> Annex.Branch.files
+
+{- Finds all keys that have location log information indicating
+ - they are present for the specified repository. -}
+loggedKeysFor :: UUID -> Annex [Key]
+loggedKeysFor u = filterM isthere =<< loggedKeys
+ where
+ {- This should run strictly to avoid the filterM
+ - building many thunks containing keyLocations data. -}
+ isthere k = do
+ us <- loggedLocations k
+ let !there = u `elem` us
+ return there
diff --git a/Logs/PreferredContent.hs b/Logs/PreferredContent.hs
new file mode 100644
index 000000000..57367148c
--- /dev/null
+++ b/Logs/PreferredContent.hs
@@ -0,0 +1,114 @@
+{- git-annex preferred content matcher configuration
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Logs.PreferredContent (
+ preferredContentLog,
+ preferredContentSet,
+ isPreferredContent,
+ preferredContentMap,
+ preferredContentMapLoad,
+ preferredContentMapRaw,
+ checkPreferredContentExpression,
+ setStandardGroup,
+) where
+
+import qualified Data.Map as M
+import qualified Data.Set as S
+import Data.Either
+import Data.Time.Clock.POSIX
+
+import Common.Annex
+import qualified Annex.Branch
+import qualified Annex
+import Logs
+import Logs.UUIDBased
+import qualified Utility.Matcher
+import Annex.FileMatcher
+import Annex.UUID
+import Types.Limit
+import Types.Group
+import Types.Remote (RemoteConfig)
+import Logs.Group
+import Logs.Remote
+import Types.StandardGroups
+
+{- Changes the preferred content configuration of a remote. -}
+preferredContentSet :: UUID -> String -> Annex ()
+preferredContentSet uuid@(UUID _) val = do
+ ts <- liftIO getPOSIXTime
+ Annex.Branch.change preferredContentLog $
+ showLog id . changeLog ts uuid val . parseLog Just
+ Annex.changeState $ \s -> s { Annex.preferredcontentmap = Nothing }
+preferredContentSet NoUUID _ = error "unknown UUID; cannot modify"
+
+{- Checks if a file is preferred content for the specified repository
+ - (or the current repository if none is specified). -}
+isPreferredContent :: Maybe UUID -> AssumeNotPresent -> FilePath -> Bool -> Annex Bool
+isPreferredContent mu notpresent file def = do
+ u <- maybe getUUID return mu
+ m <- preferredContentMap
+ case M.lookup u m of
+ Nothing -> return def
+ Just matcher -> checkFileMatcher' matcher file notpresent def
+
+{- The map is cached for speed. -}
+preferredContentMap :: Annex Annex.PreferredContentMap
+preferredContentMap = maybe preferredContentMapLoad return
+ =<< Annex.getState Annex.preferredcontentmap
+
+{- Loads the map, updating the cache. -}
+preferredContentMapLoad :: Annex Annex.PreferredContentMap
+preferredContentMapLoad = do
+ groupmap <- groupMap
+ configmap <- readRemoteLog
+ m <- simpleMap
+ . parseLogWithUUID ((Just .) . makeMatcher groupmap configmap)
+ <$> Annex.Branch.get preferredContentLog
+ Annex.changeState $ \s -> s { Annex.preferredcontentmap = Just m }
+ return m
+
+preferredContentMapRaw :: Annex (M.Map UUID String)
+preferredContentMapRaw = simpleMap . parseLog Just
+ <$> Annex.Branch.get preferredContentLog
+
+{- This intentionally never fails, even on unparsable expressions,
+ - because the configuration is shared amoung repositories and newer
+ - versions of git-annex may add new features. Instead, parse errors
+ - result in a Matcher that will always succeed. -}
+makeMatcher :: GroupMap -> M.Map UUID RemoteConfig -> UUID -> String -> FileMatcher
+makeMatcher groupmap configmap u expr
+ | expr == "standard" = standardMatcher groupmap configmap u
+ | null (lefts tokens) = Utility.Matcher.generate $ rights tokens
+ | otherwise = matchAll
+ where
+ tokens = exprParser groupmap configmap (Just u) expr
+
+{- Standard matchers are pre-defined for some groups. If none is defined,
+ - or a repository is in multiple groups with standard matchers, match all. -}
+standardMatcher :: GroupMap -> M.Map UUID RemoteConfig -> UUID -> FileMatcher
+standardMatcher groupmap configmap u =
+ maybe matchAll (makeMatcher groupmap configmap u . preferredContent) $
+ getStandardGroup =<< u `M.lookup` groupsByUUID groupmap
+
+{- Checks if an expression can be parsed, if not returns Just error -}
+checkPreferredContentExpression :: String -> Maybe String
+checkPreferredContentExpression expr
+ | expr == "standard" = Nothing
+ | otherwise = case parsedToMatcher tokens of
+ Left e -> Just e
+ Right _ -> Nothing
+ where
+ tokens = exprParser emptyGroupMap M.empty Nothing expr
+
+{- Puts a UUID in a standard group, and sets its preferred content to use
+ - the standard expression for that group, unless something is already set. -}
+setStandardGroup :: UUID -> StandardGroup -> Annex ()
+setStandardGroup u g = do
+ groupSet u $ S.singleton $ fromStandardGroup g
+ m <- preferredContentMap
+ unless (isJust $ M.lookup u m) $
+ preferredContentSet u "standard"
diff --git a/Logs/Presence.hs b/Logs/Presence.hs
new file mode 100644
index 000000000..516d59618
--- /dev/null
+++ b/Logs/Presence.hs
@@ -0,0 +1,45 @@
+{- git-annex presence log
+ -
+ - This is used to store presence information in the git-annex branch in
+ - a way that can be union merged.
+ -
+ - A line of the log will look like: "date N INFO"
+ - Where N=1 when the INFO is present, and 0 otherwise.
+ -
+ - Copyright 2010-2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Logs.Presence (
+ module X,
+ addLog,
+ readLog,
+ logNow,
+ currentLog
+) where
+
+import Data.Time.Clock.POSIX
+
+import Logs.Presence.Pure as X
+import Common.Annex
+import qualified Annex.Branch
+
+addLog :: FilePath -> LogLine -> Annex ()
+addLog file line = Annex.Branch.change file $ \s ->
+ showLog $ compactLog (line : parseLog s)
+
+{- Reads a log file.
+ - Note that the LogLines returned may be in any order. -}
+readLog :: FilePath -> Annex [LogLine]
+readLog = parseLog <$$> Annex.Branch.get
+
+{- Generates a new LogLine with the current date. -}
+logNow :: LogStatus -> String -> Annex LogLine
+logNow s i = do
+ now <- liftIO getPOSIXTime
+ return $ LogLine now s i
+
+{- Reads a log and returns only the info that is still in effect. -}
+currentLog :: FilePath -> Annex [String]
+currentLog file = map info . filterPresent <$> readLog file
diff --git a/Logs/Presence/Pure.hs b/Logs/Presence/Pure.hs
new file mode 100644
index 000000000..ffeb78b26
--- /dev/null
+++ b/Logs/Presence/Pure.hs
@@ -0,0 +1,84 @@
+{- git-annex presence log, pure operations
+ -
+ - Copyright 2010-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Logs.Presence.Pure where
+
+import Data.Time.Clock.POSIX
+import Data.Time
+import System.Locale
+import qualified Data.Map as M
+
+import Common.Annex
+import Utility.QuickCheck
+
+data LogLine = LogLine {
+ date :: POSIXTime,
+ status :: LogStatus,
+ info :: String
+} deriving (Eq, Show)
+
+data LogStatus = InfoPresent | InfoMissing
+ deriving (Eq, Show, Bounded, Enum)
+
+{- Parses a log file. Unparseable lines are ignored. -}
+parseLog :: String -> [LogLine]
+parseLog = mapMaybe parseline . lines
+ where
+ parseline l = LogLine
+ <$> (utcTimeToPOSIXSeconds <$> parseTime defaultTimeLocale "%s%Qs" d)
+ <*> parsestatus s
+ <*> pure rest
+ where
+ (d, pastd) = separate (== ' ') l
+ (s, rest) = separate (== ' ') pastd
+ parsestatus "1" = Just InfoPresent
+ parsestatus "0" = Just InfoMissing
+ parsestatus _ = Nothing
+
+{- Generates a log file. -}
+showLog :: [LogLine] -> String
+showLog = unlines . map genline
+ where
+ genline (LogLine d s i) = unwords [show d, genstatus s, i]
+ genstatus InfoPresent = "1"
+ genstatus InfoMissing = "0"
+
+{- Given a log, returns only the info that is are still in effect. -}
+getLog :: String -> [String]
+getLog = map info . filterPresent . parseLog
+
+{- Returns the info from LogLines that are in effect. -}
+filterPresent :: [LogLine] -> [LogLine]
+filterPresent = filter (\l -> InfoPresent == status l) . compactLog
+
+{- Compacts a set of logs, returning a subset that contains the current
+ - status. -}
+compactLog :: [LogLine] -> [LogLine]
+compactLog = M.elems . foldr mapLog M.empty
+
+type LogMap = M.Map String LogLine
+
+{- Inserts a log into a map of logs, if the log has better (ie, newer)
+ - information than the other logs in the map -}
+mapLog :: LogLine -> LogMap -> LogMap
+mapLog l m
+ | better = M.insert i l m
+ | otherwise = m
+ where
+ better = maybe True newer $ M.lookup i m
+ newer l' = date l' <= date l
+ i = info l
+
+instance Arbitrary LogLine where
+ arbitrary = LogLine
+ <$> arbitrary
+ <*> elements [minBound..maxBound]
+ <*> arbitrary `suchThat` ('\n' `notElem`)
+
+prop_parse_show_log :: [LogLine] -> Bool
+prop_parse_show_log l = parseLog (showLog l) == l
+
diff --git a/Logs/Remote.hs b/Logs/Remote.hs
new file mode 100644
index 000000000..48ee9eb60
--- /dev/null
+++ b/Logs/Remote.hs
@@ -0,0 +1,97 @@
+{- git-annex remote log
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Logs.Remote (
+ remoteLog,
+ readRemoteLog,
+ configSet,
+ keyValToConfig,
+ configToKeyVal,
+ showConfig,
+ parseConfig,
+
+ prop_idempotent_configEscape,
+ prop_parse_show_Config,
+) where
+
+import qualified Data.Map as M
+import Data.Time.Clock.POSIX
+import Data.Char
+
+import Common.Annex
+import qualified Annex.Branch
+import Types.Remote
+import Logs
+import Logs.UUIDBased
+
+{- Adds or updates a remote's config in the log. -}
+configSet :: UUID -> RemoteConfig -> Annex ()
+configSet u c = do
+ ts <- liftIO getPOSIXTime
+ Annex.Branch.change remoteLog $
+ showLog showConfig . changeLog ts u c . parseLog parseConfig
+
+{- Map of remotes by uuid containing key/value config maps. -}
+readRemoteLog :: Annex (M.Map UUID RemoteConfig)
+readRemoteLog = simpleMap . parseLog parseConfig <$> Annex.Branch.get remoteLog
+
+parseConfig :: String -> Maybe RemoteConfig
+parseConfig = Just . keyValToConfig . words
+
+showConfig :: RemoteConfig -> String
+showConfig = unwords . configToKeyVal
+
+{- Given Strings like "key=value", generates a RemoteConfig. -}
+keyValToConfig :: [String] -> RemoteConfig
+keyValToConfig ws = M.fromList $ map (/=/) ws
+ where
+ (/=/) s = (k, v)
+ where
+ k = takeWhile (/= '=') s
+ v = configUnEscape $ drop (1 + length k) s
+
+configToKeyVal :: M.Map String String -> [String]
+configToKeyVal m = map toword $ sort $ M.toList m
+ where
+ toword (k, v) = k ++ "=" ++ configEscape v
+
+configEscape :: String -> String
+configEscape = concatMap escape
+ where
+ escape c
+ | isSpace c || c `elem` "&" = "&" ++ show (ord c) ++ ";"
+ | otherwise = [c]
+
+configUnEscape :: String -> String
+configUnEscape = unescape
+ where
+ unescape [] = []
+ unescape (c:rest)
+ | c == '&' = entity rest
+ | otherwise = c : unescape rest
+ entity s
+ | not (null num) && ";" `isPrefixOf` r =
+ chr (Prelude.read num) : unescape rest
+ | otherwise =
+ '&' : unescape s
+ where
+ num = takeWhile isNumber s
+ r = drop (length num) s
+ rest = drop 1 r
+
+{- for quickcheck -}
+prop_idempotent_configEscape :: String -> Bool
+prop_idempotent_configEscape s = s == (configUnEscape . configEscape) s
+
+prop_parse_show_Config :: RemoteConfig -> Bool
+prop_parse_show_Config c
+ -- whitespace and '=' are not supported in keys
+ | any (\k -> any isSpace k || elem '=' k) (M.keys c) = True
+ | otherwise = parseConfig (showConfig c) ~~ Just c
+ where
+ normalize v = sort . M.toList <$> v
+ a ~~ b = normalize a == normalize b
diff --git a/Logs/Schedule.hs b/Logs/Schedule.hs
new file mode 100644
index 000000000..1d78467bb
--- /dev/null
+++ b/Logs/Schedule.hs
@@ -0,0 +1,72 @@
+{- git-annex scheduled activities log
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Logs.Schedule (
+ scheduleLog,
+ scheduleSet,
+ scheduleAdd,
+ scheduleRemove,
+ scheduleChange,
+ scheduleGet,
+ scheduleMap,
+ getLastRunTimes,
+ setLastRunTime,
+) where
+
+import qualified Data.Map as M
+import qualified Data.Set as S
+import Data.Time.Clock.POSIX
+import Data.Time.LocalTime
+
+import Common.Annex
+import Types.ScheduledActivity
+import qualified Annex.Branch
+import Logs
+import Logs.UUIDBased
+import Utility.Tmp
+
+scheduleSet :: UUID -> [ScheduledActivity] -> Annex ()
+scheduleSet uuid@(UUID _) activities = do
+ ts <- liftIO getPOSIXTime
+ Annex.Branch.change scheduleLog $
+ showLog id . changeLog ts uuid val . parseLog Just
+ where
+ val = fromScheduledActivities activities
+scheduleSet NoUUID _ = error "unknown UUID; cannot modify"
+
+scheduleMap :: Annex (M.Map UUID [ScheduledActivity])
+scheduleMap = simpleMap
+ . parseLogWithUUID parser
+ <$> Annex.Branch.get scheduleLog
+ where
+ parser _uuid = eitherToMaybe . parseScheduledActivities
+
+scheduleGet :: UUID -> Annex (S.Set ScheduledActivity)
+scheduleGet u = do
+ m <- scheduleMap
+ return $ maybe S.empty S.fromList (M.lookup u m)
+
+scheduleRemove :: UUID -> ScheduledActivity -> Annex ()
+scheduleRemove u activity = scheduleChange u $ S.delete activity
+
+scheduleAdd :: UUID -> ScheduledActivity -> Annex ()
+scheduleAdd u activity = scheduleChange u $ S.insert activity
+
+scheduleChange :: UUID -> (S.Set ScheduledActivity -> S.Set ScheduledActivity) -> Annex ()
+scheduleChange u a = scheduleSet u . S.toList . a =<< scheduleGet u
+
+getLastRunTimes :: Annex (M.Map ScheduledActivity LocalTime)
+getLastRunTimes = do
+ f <- fromRepo gitAnnexScheduleState
+ liftIO $ fromMaybe M.empty
+ <$> catchDefaultIO Nothing (readish <$> readFile f)
+
+setLastRunTime :: ScheduledActivity -> LocalTime -> Annex ()
+setLastRunTime activity lastrun = do
+ f <- fromRepo gitAnnexScheduleState
+ liftIO . viaTmp writeFile f . show . M.insert activity lastrun
+ =<< getLastRunTimes
diff --git a/Logs/Transfer.hs b/Logs/Transfer.hs
new file mode 100644
index 000000000..24fb940d5
--- /dev/null
+++ b/Logs/Transfer.hs
@@ -0,0 +1,394 @@
+{- git-annex transfer information files and lock files
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Logs.Transfer where
+
+import Common.Annex
+import Annex.Perms
+import Annex.Exception
+import qualified Git
+import Types.Key
+import Utility.Metered
+import Utility.Percentage
+import Utility.QuickCheck
+
+import System.Posix.Types
+import Data.Time.Clock
+import Data.Time.Clock.POSIX
+import Data.Time
+import System.Locale
+import Control.Concurrent
+
+{- Enough information to uniquely identify a transfer, used as the filename
+ - of the transfer information file. -}
+data Transfer = Transfer
+ { transferDirection :: Direction
+ , transferUUID :: UUID
+ , transferKey :: Key
+ }
+ deriving (Eq, Ord, Read, Show)
+
+{- Information about a Transfer, stored in the transfer information file.
+ -
+ - Note that the associatedFile may not correspond to a file in the local
+ - git repository. It's some file, possibly relative to some directory,
+ - of some repository, that was acted on to initiate the transfer.
+ -}
+data TransferInfo = TransferInfo
+ { startedTime :: Maybe POSIXTime
+ , transferPid :: Maybe ProcessID
+ , transferTid :: Maybe ThreadId
+ , transferRemote :: Maybe Remote
+ , bytesComplete :: Maybe Integer
+ , associatedFile :: Maybe FilePath
+ , transferPaused :: Bool
+ }
+ deriving (Show, Eq, Ord)
+
+stubTransferInfo :: TransferInfo
+stubTransferInfo = TransferInfo Nothing Nothing Nothing Nothing Nothing Nothing False
+
+data Direction = Upload | Download
+ deriving (Eq, Ord, Read, Show)
+
+showLcDirection :: Direction -> String
+showLcDirection Upload = "upload"
+showLcDirection Download = "download"
+
+readLcDirection :: String -> Maybe Direction
+readLcDirection "upload" = Just Upload
+readLcDirection "download" = Just Download
+readLcDirection _ = Nothing
+
+describeTransfer :: Transfer -> TransferInfo -> String
+describeTransfer t info = unwords
+ [ show $ transferDirection t
+ , show $ transferUUID t
+ , fromMaybe (key2file $ transferKey t) (associatedFile info)
+ , show $ bytesComplete info
+ ]
+
+{- Transfers that will accomplish the same task. -}
+equivilantTransfer :: Transfer -> Transfer -> Bool
+equivilantTransfer t1 t2
+ | transferDirection t1 == Download && transferDirection t2 == Download &&
+ transferKey t1 == transferKey t2 = True
+ | otherwise = t1 == t2
+
+percentComplete :: Transfer -> TransferInfo -> Maybe Percentage
+percentComplete (Transfer { transferKey = key }) info =
+ percentage <$> keySize key <*> Just (fromMaybe 0 $ bytesComplete info)
+
+type RetryDecider = TransferInfo -> TransferInfo -> Bool
+
+noRetry :: RetryDecider
+noRetry _ _ = False
+
+{- Retries a transfer when it fails, as long as the failed transfer managed
+ - to send some data. -}
+forwardRetry :: RetryDecider
+forwardRetry old new = bytesComplete old < bytesComplete new
+
+upload :: UUID -> Key -> AssociatedFile -> RetryDecider -> (MeterUpdate -> Annex Bool) -> Annex Bool
+upload u key = runTransfer (Transfer Upload u key)
+
+download :: UUID -> Key -> AssociatedFile -> RetryDecider -> (MeterUpdate -> Annex Bool) -> Annex Bool
+download u key = runTransfer (Transfer Download u key)
+
+{- Runs a transfer action. Creates and locks the lock file while the
+ - action is running, and stores info in the transfer information
+ - file.
+ -
+ - If the transfer action returns False, the transfer info is
+ - left in the failedTransferDir.
+ -
+ - If the transfer is already in progress, returns False.
+ -
+ - An upload can be run from a read-only filesystem, and in this case
+ - no transfer information or lock file is used.
+ -}
+runTransfer :: Transfer -> Maybe FilePath -> RetryDecider -> (MeterUpdate -> Annex Bool) -> Annex Bool
+runTransfer t file shouldretry a = do
+ info <- liftIO $ startTransferInfo file
+ (meter, tfile, metervar) <- mkProgressUpdater t info
+ mode <- annexFileMode
+ (fd, inprogress) <- liftIO $ prep tfile mode info
+ if inprogress
+ then do
+ showNote "transfer already in progress"
+ return False
+ else do
+ ok <- retry info metervar $
+ bracketIO (return fd) (cleanup tfile) (const $ a meter)
+ unless ok $ recordFailedTransfer t info
+ return ok
+ where
+#ifndef mingw32_HOST_OS
+ prep tfile mode info = do
+ mfd <- catchMaybeIO $
+ openFd (transferLockFile tfile) ReadWrite (Just mode)
+ defaultFileFlags { trunc = True }
+ case mfd of
+ Nothing -> return (mfd, False)
+ Just fd -> do
+ locked <- catchMaybeIO $
+ setLock fd (WriteLock, AbsoluteSeek, 0, 0)
+ if isNothing locked
+ then return (Nothing, True)
+ else do
+ void $ tryIO $ writeTransferInfoFile info tfile
+ return (mfd, False)
+#else
+ prep tfile _mode info = do
+ mfd <- catchMaybeIO $ do
+ writeFile (transferLockFile tfile) ""
+ writeTransferInfoFile info tfile
+ return (mfd, False)
+#endif
+ cleanup _ Nothing = noop
+ cleanup tfile (Just fd) = do
+ void $ tryIO $ removeFile tfile
+ void $ tryIO $ removeFile $ transferLockFile tfile
+#ifndef mingw32_HOST_OS
+ closeFd fd
+#endif
+ retry oldinfo metervar run = do
+ v <- tryAnnex run
+ case v of
+ Right b -> return b
+ Left _ -> do
+ b <- getbytescomplete metervar
+ let newinfo = oldinfo { bytesComplete = Just b }
+ if shouldretry oldinfo newinfo
+ then retry newinfo metervar run
+ else return False
+ getbytescomplete metervar
+ | transferDirection t == Upload =
+ liftIO $ readMVar metervar
+ | otherwise = do
+ f <- fromRepo $ gitAnnexTmpLocation (transferKey t)
+ liftIO $ catchDefaultIO 0 $
+ fromIntegral . fileSize <$> getFileStatus f
+
+{- Generates a callback that can be called as transfer progresses to update
+ - the transfer info file. Also returns the file it'll be updating, and a
+ - MVar that can be used to read the number of bytesComplete. -}
+mkProgressUpdater :: Transfer -> TransferInfo -> Annex (MeterUpdate, FilePath, MVar Integer)
+mkProgressUpdater t info = do
+ tfile <- fromRepo $ transferFile t
+ _ <- tryAnnex $ createAnnexDirectory $ takeDirectory tfile
+ mvar <- liftIO $ newMVar 0
+ return (liftIO . updater tfile mvar, tfile, mvar)
+ where
+ updater tfile mvar b = modifyMVar_ mvar $ \oldbytes -> do
+ let newbytes = fromBytesProcessed b
+ if newbytes - oldbytes >= mindelta
+ then do
+ let info' = info { bytesComplete = Just newbytes }
+ _ <- tryIO $ writeTransferInfoFile info' tfile
+ return newbytes
+ else return oldbytes
+ {- The minimum change in bytesComplete that is worth
+ - updating a transfer info file for is 1% of the total
+ - keySize, rounded down. -}
+ mindelta = case keySize (transferKey t) of
+ Just sz -> sz `div` 100
+ Nothing -> 100 * 1024 -- arbitrarily, 100 kb
+
+startTransferInfo :: Maybe FilePath -> IO TransferInfo
+startTransferInfo file = TransferInfo
+ <$> (Just . utcTimeToPOSIXSeconds <$> getCurrentTime)
+ <*> pure Nothing -- pid not stored in file, so omitted for speed
+ <*> pure Nothing -- tid ditto
+ <*> pure Nothing -- not 0; transfer may be resuming
+ <*> pure Nothing
+ <*> pure file
+ <*> pure False
+
+{- If a transfer is still running, returns its TransferInfo. -}
+checkTransfer :: Transfer -> Annex (Maybe TransferInfo)
+checkTransfer t = do
+ tfile <- fromRepo $ transferFile t
+#ifndef mingw32_HOST_OS
+ mode <- annexFileMode
+ mfd <- liftIO $ catchMaybeIO $
+ openFd (transferLockFile tfile) ReadOnly (Just mode) defaultFileFlags
+ case mfd of
+ Nothing -> return Nothing -- failed to open file; not running
+ Just fd -> do
+ locked <- liftIO $
+ getLock fd (WriteLock, AbsoluteSeek, 0, 0)
+ liftIO $ closeFd fd
+ case locked of
+ Nothing -> return Nothing
+ Just (pid, _) -> liftIO $ catchDefaultIO Nothing $
+ readTransferInfoFile (Just pid) tfile
+#else
+ ifM (liftIO $ doesFileExist $ transferLockFile tfile)
+ ( liftIO $ catchDefaultIO Nothing $
+ readTransferInfoFile Nothing tfile
+ , return Nothing
+ )
+#endif
+
+{- Gets all currently running transfers. -}
+getTransfers :: Annex [(Transfer, TransferInfo)]
+getTransfers = do
+ transfers <- mapMaybe parseTransferFile . concat <$> findfiles
+ infos <- mapM checkTransfer transfers
+ return $ map (\(t, Just i) -> (t, i)) $
+ filter running $ zip transfers infos
+ where
+ findfiles = liftIO . mapM dirContentsRecursive
+ =<< mapM (fromRepo . transferDir) [Download, Upload]
+ running (_, i) = isJust i
+
+{- Gets failed transfers for a given remote UUID. -}
+getFailedTransfers :: UUID -> Annex [(Transfer, TransferInfo)]
+getFailedTransfers u = catMaybes <$> (liftIO . getpairs =<< concat <$> findfiles)
+ where
+ getpairs = mapM $ \f -> do
+ let mt = parseTransferFile f
+ mi <- readTransferInfoFile Nothing f
+ return $ case (mt, mi) of
+ (Just t, Just i) -> Just (t, i)
+ _ -> Nothing
+ findfiles = liftIO . mapM dirContentsRecursive
+ =<< mapM (fromRepo . failedTransferDir u) [Download, Upload]
+
+clearFailedTransfers :: UUID -> Annex [(Transfer, TransferInfo)]
+clearFailedTransfers u = do
+ failed <- getFailedTransfers u
+ mapM_ (removeFailedTransfer . fst) failed
+ return failed
+
+removeFailedTransfer :: Transfer -> Annex ()
+removeFailedTransfer t = do
+ f <- fromRepo $ failedTransferFile t
+ liftIO $ void $ tryIO $ removeFile f
+
+recordFailedTransfer :: Transfer -> TransferInfo -> Annex ()
+recordFailedTransfer t info = do
+ failedtfile <- fromRepo $ failedTransferFile t
+ createAnnexDirectory $ takeDirectory failedtfile
+ liftIO $ writeTransferInfoFile info failedtfile
+
+{- The transfer information file to use for a given Transfer. -}
+transferFile :: Transfer -> Git.Repo -> FilePath
+transferFile (Transfer direction u key) r = transferDir direction r
+ </> filter (/= '/') (fromUUID u)
+ </> keyFile key
+
+{- The transfer information file to use to record a failed Transfer -}
+failedTransferFile :: Transfer -> Git.Repo -> FilePath
+failedTransferFile (Transfer direction u key) r = failedTransferDir u direction r
+ </> keyFile key
+
+{- The transfer lock file corresponding to a given transfer info file. -}
+transferLockFile :: FilePath -> FilePath
+transferLockFile infofile = let (d,f) = splitFileName infofile in
+ combine d ("lck." ++ f)
+
+{- Parses a transfer information filename to a Transfer. -}
+parseTransferFile :: FilePath -> Maybe Transfer
+parseTransferFile file
+ | "lck." `isPrefixOf` takeFileName file = Nothing
+ | otherwise = case drop (length bits - 3) bits of
+ [direction, u, key] -> Transfer
+ <$> readLcDirection direction
+ <*> pure (toUUID u)
+ <*> fileKey key
+ _ -> Nothing
+ where
+ bits = splitDirectories file
+
+writeTransferInfoFile :: TransferInfo -> FilePath -> IO ()
+writeTransferInfoFile info tfile = do
+ h <- openFile tfile WriteMode
+ fileEncoding h
+ hPutStr h $ writeTransferInfo info
+ hClose h
+
+{- File format is a header line containing the startedTime and any
+ - bytesComplete value. Followed by a newline and the associatedFile.
+ -
+ - The transferPid is not included; instead it is obtained by looking
+ - at the process that locks the file.
+ -}
+writeTransferInfo :: TransferInfo -> String
+writeTransferInfo info = unlines
+ [ (maybe "" show $ startedTime info) ++
+ (maybe "" (\b -> ' ' : show b) (bytesComplete info))
+ , fromMaybe "" $ associatedFile info -- comes last; arbitrary content
+ ]
+
+readTransferInfoFile :: Maybe ProcessID -> FilePath -> IO (Maybe TransferInfo)
+readTransferInfoFile mpid tfile = catchDefaultIO Nothing $ do
+ h <- openFile tfile ReadMode
+ fileEncoding h
+ hClose h `after` (readTransferInfo mpid <$> hGetContentsStrict h)
+
+readTransferInfo :: Maybe ProcessID -> String -> Maybe TransferInfo
+readTransferInfo mpid s = TransferInfo
+ <$> time
+ <*> pure mpid
+ <*> pure Nothing
+ <*> pure Nothing
+ <*> bytes
+ <*> pure (if null filename then Nothing else Just filename)
+ <*> pure False
+ where
+ (firstline, rest) = separate (== '\n') s
+ filename
+ | end rest == "\n" = beginning rest
+ | otherwise = rest
+ bits = split " " firstline
+ numbits = length bits
+ time = if numbits > 0
+ then Just <$> parsePOSIXTime =<< headMaybe bits
+ else pure Nothing -- not failure
+ bytes = if numbits > 1
+ then Just <$> readish =<< headMaybe (drop 1 bits)
+ else pure Nothing -- not failure
+
+parsePOSIXTime :: String -> Maybe POSIXTime
+parsePOSIXTime s = utcTimeToPOSIXSeconds
+ <$> parseTime defaultTimeLocale "%s%Qs" s
+
+{- The directory holding transfer information files for a given Direction. -}
+transferDir :: Direction -> Git.Repo -> FilePath
+transferDir direction r = gitAnnexTransferDir r </> showLcDirection direction
+
+{- The directory holding failed transfer information files for a given
+ - Direction and UUID -}
+failedTransferDir :: UUID -> Direction -> Git.Repo -> FilePath
+failedTransferDir u direction r = gitAnnexTransferDir r
+ </> "failed"
+ </> showLcDirection direction
+ </> filter (/= '/') (fromUUID u)
+
+instance Arbitrary TransferInfo where
+ arbitrary = TransferInfo
+ <$> arbitrary
+ <*> arbitrary
+ <*> pure Nothing -- cannot generate a ThreadID
+ <*> pure Nothing -- remote not needed
+ <*> arbitrary
+ -- associated file cannot be empty (but can be Nothing)
+ <*> arbitrary `suchThat` (/= Just "")
+ <*> arbitrary
+
+prop_read_write_transferinfo :: TransferInfo -> Bool
+prop_read_write_transferinfo info
+ | isJust (transferRemote info) = True -- remote not stored
+ | isJust (transferTid info) = True -- tid not stored
+ | otherwise = Just (info { transferPaused = False }) == info'
+ where
+ info' = readTransferInfo (transferPid info) (writeTransferInfo info)
+
diff --git a/Logs/Transitions.hs b/Logs/Transitions.hs
new file mode 100644
index 000000000..64e9d3344
--- /dev/null
+++ b/Logs/Transitions.hs
@@ -0,0 +1,86 @@
+{- git-annex transitions log
+ -
+ - This is used to record transitions that have been performed on the
+ - git-annex branch, and when the transition was first started.
+ -
+ - We can quickly detect when the local branch has already had an transition
+ - done that is listed in the remote branch by checking that the local
+ - branch contains the same transition, with the same or newer start time.
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Logs.Transitions where
+
+import Data.Time.Clock.POSIX
+import Data.Time
+import System.Locale
+import qualified Data.Set as S
+
+import Common.Annex
+
+transitionsLog :: FilePath
+transitionsLog = "transitions.log"
+
+data Transition
+ = ForgetGitHistory
+ | ForgetDeadRemotes
+ deriving (Show, Ord, Eq, Read)
+
+data TransitionLine = TransitionLine
+ { transitionStarted :: POSIXTime
+ , transition :: Transition
+ } deriving (Show, Ord, Eq)
+
+type Transitions = S.Set TransitionLine
+
+describeTransition :: Transition -> String
+describeTransition ForgetGitHistory = "forget git history"
+describeTransition ForgetDeadRemotes = "forget dead remotes"
+
+noTransitions :: Transitions
+noTransitions = S.empty
+
+addTransition :: POSIXTime -> Transition -> Transitions -> Transitions
+addTransition ts t = S.insert $ TransitionLine ts t
+
+showTransitions :: Transitions -> String
+showTransitions = unlines . map showTransitionLine . S.elems
+
+{- If the log contains new transitions we don't support, returns Nothing. -}
+parseTransitions :: String -> Maybe Transitions
+parseTransitions = check . map parseTransitionLine . lines
+ where
+ check l
+ | all isJust l = Just $ S.fromList $ catMaybes l
+ | otherwise = Nothing
+
+parseTransitionsStrictly :: String -> String -> Transitions
+parseTransitionsStrictly source = fromMaybe badsource . parseTransitions
+ where
+ badsource = error $ "unknown transitions listed in " ++ source ++ "; upgrade git-annex!"
+
+showTransitionLine :: TransitionLine -> String
+showTransitionLine (TransitionLine ts t) = unwords [show t, show ts]
+
+parseTransitionLine :: String -> Maybe TransitionLine
+parseTransitionLine s = TransitionLine <$> pdate ds <*> readish ts
+ where
+ ws = words s
+ ts = Prelude.head ws
+ ds = unwords $ Prelude.tail ws
+ pdate = utcTimeToPOSIXSeconds <$$> parseTime defaultTimeLocale "%s%Qs"
+
+combineTransitions :: [Transitions] -> Transitions
+combineTransitions = S.unions
+
+transitionList :: Transitions -> [Transition]
+transitionList = map transition . S.elems
+
+{- Typically ran with Annex.Branch.change, but we can't import Annex.Branch
+ - here since it depends on this module. -}
+recordTransitions :: (FilePath -> (String -> String) -> Annex ()) -> Transitions -> Annex ()
+recordTransitions changer t = changer transitionsLog $
+ showTransitions . S.union t . parseTransitionsStrictly "local"
diff --git a/Logs/Trust.hs b/Logs/Trust.hs
new file mode 100644
index 000000000..c6f0ad3ab
--- /dev/null
+++ b/Logs/Trust.hs
@@ -0,0 +1,97 @@
+{- git-annex trust log
+ -
+ - Copyright 2010-2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Logs.Trust (
+ module X,
+ trustLog,
+ TrustLevel(..),
+ trustGet,
+ trustMap,
+ trustSet,
+ trustPartition,
+ trustExclude,
+ lookupTrust,
+ trustMapLoad,
+ trustMapRaw,
+) where
+
+import qualified Data.Map as M
+import Data.Time.Clock.POSIX
+
+import Common.Annex
+import Types.TrustLevel
+import qualified Annex.Branch
+import qualified Annex
+import Logs
+import Logs.UUIDBased
+import Remote.List
+import qualified Types.Remote
+import Logs.Trust.Pure as X
+
+{- Returns a list of UUIDs that the trustLog indicates have the
+ - specified trust level.
+ - Note that the list can be incomplete for SemiTrusted, since that's
+ - the default. -}
+trustGet :: TrustLevel -> Annex [UUID]
+trustGet level = M.keys . M.filter (== level) <$> trustMap
+
+{- Changes the trust level for a uuid in the trustLog. -}
+trustSet :: UUID -> TrustLevel -> Annex ()
+trustSet uuid@(UUID _) level = do
+ ts <- liftIO getPOSIXTime
+ Annex.Branch.change trustLog $
+ showLog showTrustLog .
+ changeLog ts uuid level .
+ parseLog (Just . parseTrustLog)
+ Annex.changeState $ \s -> s { Annex.trustmap = Nothing }
+trustSet NoUUID _ = error "unknown UUID; cannot modify"
+
+{- Returns the TrustLevel of a given repo UUID. -}
+lookupTrust :: UUID -> Annex TrustLevel
+lookupTrust u = (fromMaybe SemiTrusted . M.lookup u) <$> trustMap
+
+{- Partitions a list of UUIDs to those matching a TrustLevel and not. -}
+trustPartition :: TrustLevel -> [UUID] -> Annex ([UUID], [UUID])
+trustPartition level ls
+ | level == SemiTrusted = do
+ t <- trustGet Trusted
+ u <- trustGet UnTrusted
+ d <- trustGet DeadTrusted
+ let uncandidates = t ++ u ++ d
+ return $ partition (`notElem` uncandidates) ls
+ | otherwise = do
+ candidates <- trustGet level
+ return $ partition (`elem` candidates) ls
+
+{- Filters UUIDs to those not matching a TrustLevel. -}
+trustExclude :: TrustLevel -> [UUID] -> Annex [UUID]
+trustExclude level ls = snd <$> trustPartition level ls
+
+{- trustLog in a map, overridden with any values from forcetrust or
+ - the git config. The map is cached for speed. -}
+trustMap :: Annex TrustMap
+trustMap = maybe trustMapLoad return =<< Annex.getState Annex.trustmap
+
+{- Loads the map, updating the cache, -}
+trustMapLoad :: Annex TrustMap
+trustMapLoad = do
+ overrides <- Annex.getState Annex.forcetrust
+ logged <- trustMapRaw
+ configured <- M.fromList . catMaybes
+ <$> (map configuredtrust <$> remoteList)
+ let m = M.union overrides $ M.union configured logged
+ Annex.changeState $ \s -> s { Annex.trustmap = Just m }
+ return m
+ where
+ configuredtrust r = (\l -> Just (Types.Remote.uuid r, l))
+ =<< readTrustLevel
+ =<< remoteAnnexTrustLevel (Types.Remote.gitconfig r)
+
+{- Does not include forcetrust or git config values, just those from the
+ - log file. -}
+trustMapRaw :: Annex TrustMap
+trustMapRaw = calcTrustMap <$> Annex.Branch.get trustLog
diff --git a/Logs/Trust/Pure.hs b/Logs/Trust/Pure.hs
new file mode 100644
index 000000000..11cfbe056
--- /dev/null
+++ b/Logs/Trust/Pure.hs
@@ -0,0 +1,36 @@
+{- git-annex trust log, pure operations
+ -
+ - Copyright 2010-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Logs.Trust.Pure where
+
+import Common.Annex
+import Types.TrustLevel
+import Logs.UUIDBased
+
+calcTrustMap :: String -> TrustMap
+calcTrustMap = simpleMap . parseLog (Just . parseTrustLog)
+
+{- The trust.log used to only list trusted repos, without a field for the
+ - trust status, which is why this defaults to Trusted. -}
+parseTrustLog :: String -> TrustLevel
+parseTrustLog s = maybe Trusted parse $ headMaybe $ words s
+ where
+ parse "1" = Trusted
+ parse "0" = UnTrusted
+ parse "X" = DeadTrusted
+ parse _ = SemiTrusted
+
+showTrustLog :: TrustLevel -> String
+showTrustLog Trusted = "1"
+showTrustLog UnTrusted = "0"
+showTrustLog DeadTrusted = "X"
+showTrustLog SemiTrusted = "?"
+
+prop_parse_show_TrustLog :: Bool
+prop_parse_show_TrustLog = all check [minBound .. maxBound]
+ where
+ check l = parseTrustLog (showTrustLog l) == l
diff --git a/Logs/UUID.hs b/Logs/UUID.hs
new file mode 100644
index 000000000..154f86d51
--- /dev/null
+++ b/Logs/UUID.hs
@@ -0,0 +1,96 @@
+{- git-annex uuids
+ -
+ - Each git repository used by git-annex has an annex.uuid setting that
+ - uniquely identifies that repository.
+ -
+ - UUIDs of remotes are cached in git config, using keys named
+ - remote.<name>.annex-uuid
+ -
+ - uuid.log stores a list of known uuids, and their descriptions.
+ -
+ - Copyright 2010-2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Logs.UUID (
+ uuidLog,
+ describeUUID,
+ recordUUID,
+ uuidMap,
+ uuidMapLoad
+) where
+
+import qualified Data.Map as M
+import Data.Time.Clock.POSIX
+
+import Types.UUID
+import Common.Annex
+import qualified Annex
+import qualified Annex.Branch
+import Logs
+import Logs.UUIDBased
+import qualified Annex.UUID
+
+{- Records a description for a uuid in the log. -}
+describeUUID :: UUID -> String -> Annex ()
+describeUUID uuid desc = do
+ ts <- liftIO getPOSIXTime
+ Annex.Branch.change uuidLog $
+ showLog id . changeLog ts uuid desc . fixBadUUID . parseLog Just
+
+{- Temporarily here to fix badly formatted uuid logs generated by
+ - versions 3.20111105 and 3.20111025.
+ -
+ - Those logs contain entries with the UUID and description flipped.
+ - Due to parsing, if the description is multiword, only the first
+ - will be taken to be the UUID. So, if the UUID of an entry does
+ - not look like a UUID, and the last word of the description does,
+ - flip them back.
+ -}
+fixBadUUID :: Log String -> Log String
+fixBadUUID = M.fromList . map fixup . M.toList
+ where
+ fixup (k, v)
+ | isbad = (fixeduuid, LogEntry (Date $ newertime v) fixedvalue)
+ | otherwise = (k, v)
+ where
+ kuuid = fromUUID k
+ isbad = not (isuuid kuuid) && not (null ws) && isuuid lastword
+ ws = words $ value v
+ lastword = Prelude.last ws
+ fixeduuid = toUUID lastword
+ fixedvalue = unwords $ kuuid: Prelude.init ws
+ -- For the fixed line to take precidence, it should be
+ -- slightly newer, but only slightly.
+ newertime (LogEntry (Date d) _) = d + minimumPOSIXTimeSlice
+ newertime (LogEntry Unknown _) = minimumPOSIXTimeSlice
+ minimumPOSIXTimeSlice = 0.000001
+ isuuid s = length s == 36 && length (split "-" s) == 5
+
+{- Records the uuid in the log, if it's not already there. -}
+recordUUID :: UUID -> Annex ()
+recordUUID u = go . M.lookup u =<< uuidMap
+ where
+ go (Just "") = set
+ go Nothing = set
+ go _ = noop
+ set = describeUUID u ""
+
+{- The map is cached for speed. -}
+uuidMap :: Annex UUIDMap
+uuidMap = maybe uuidMapLoad return =<< Annex.getState Annex.uuidmap
+
+{- Read the uuidLog into a simple Map.
+ -
+ - The UUID of the current repository is included explicitly, since
+ - it may not have been described and so otherwise would not appear. -}
+uuidMapLoad :: Annex UUIDMap
+uuidMapLoad = do
+ m <- (simpleMap . parseLog Just) <$> Annex.Branch.get uuidLog
+ u <- Annex.UUID.getUUID
+ let m' = M.insertWith' preferold u "" m
+ Annex.changeState $ \s -> s { Annex.uuidmap = Just m' }
+ return m'
+ where
+ preferold = flip const
diff --git a/Logs/UUIDBased.hs b/Logs/UUIDBased.hs
new file mode 100644
index 000000000..10b3bf55d
--- /dev/null
+++ b/Logs/UUIDBased.hs
@@ -0,0 +1,119 @@
+{- git-annex uuid-based logs
+ -
+ - This is used to store information about a UUID in a way that can
+ - be union merged.
+ -
+ - A line of the log will look like: "UUID[ INFO[ timestamp=foo]]"
+ - The timestamp is last for backwards compatability reasons,
+ - and may not be present on old log lines.
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Logs.UUIDBased (
+ Log,
+ LogEntry(..),
+ TimeStamp(..),
+ parseLog,
+ parseLogWithUUID,
+ showLog,
+ changeLog,
+ addLog,
+ simpleMap,
+
+ prop_TimeStamp_sane,
+ prop_addLog_sane,
+) where
+
+import qualified Data.Map as M
+import Data.Time.Clock.POSIX
+import Data.Time
+import System.Locale
+
+import Common
+import Types.UUID
+
+data TimeStamp = Unknown | Date POSIXTime
+ deriving (Eq, Ord, Show)
+
+data LogEntry a = LogEntry
+ { changed :: TimeStamp
+ , value :: a
+ } deriving (Eq, Show)
+
+type Log a = M.Map UUID (LogEntry a)
+
+tskey :: String
+tskey = "timestamp="
+
+showLog :: (a -> String) -> Log a -> String
+showLog shower = unlines . map showpair . M.toList
+ where
+ showpair (k, LogEntry (Date p) v) =
+ unwords [fromUUID k, shower v, tskey ++ show p]
+ showpair (k, LogEntry Unknown v) =
+ unwords [fromUUID k, shower v]
+
+parseLog :: (String -> Maybe a) -> String -> Log a
+parseLog = parseLogWithUUID . const
+
+parseLogWithUUID :: (UUID -> String -> Maybe a) -> String -> Log a
+parseLogWithUUID parser = M.fromListWith best . mapMaybe parse . lines
+ where
+ parse line
+ -- This is a workaround for a bug that caused
+ -- NoUUID items to be stored in the log.
+ -- It can be removed at any time; is just here to clean
+ -- up logs where that happened temporarily.
+ | " " `isPrefixOf` line = Nothing
+ | null ws = Nothing
+ | otherwise = parser u (unwords info) >>= makepair
+ where
+ makepair v = Just (u, LogEntry ts v)
+ ws = words line
+ u = toUUID $ Prelude.head ws
+ t = Prelude.last ws
+ ts
+ | tskey `isPrefixOf` t =
+ pdate $ drop 1 $ dropWhile (/= '=') t
+ | otherwise = Unknown
+ info
+ | ts == Unknown = drop 1 ws
+ | otherwise = drop 1 $ beginning ws
+ pdate s = case parseTime defaultTimeLocale "%s%Qs" s of
+ Nothing -> Unknown
+ Just d -> Date $ utcTimeToPOSIXSeconds d
+
+changeLog :: POSIXTime -> UUID -> a -> Log a -> Log a
+changeLog t u v = M.insert u $ LogEntry (Date t) v
+
+{- Only add an LogEntry if it's newer (or at least as new as) than any
+ - existing LogEntry for a UUID. -}
+addLog :: UUID -> LogEntry a -> Log a -> Log a
+addLog = M.insertWith' best
+
+{- Converts a Log into a simple Map without the timestamp information.
+ - This is a one-way trip, but useful for code that never needs to change
+ - the log. -}
+simpleMap :: Log a -> M.Map UUID a
+simpleMap = M.map value
+
+best :: LogEntry a -> LogEntry a -> LogEntry a
+best new old
+ | changed old > changed new = old
+ | otherwise = new
+
+-- Unknown is oldest.
+prop_TimeStamp_sane :: Bool
+prop_TimeStamp_sane = Unknown < Date 1
+
+prop_addLog_sane :: Bool
+prop_addLog_sane = newWins && newestWins
+ where
+ newWins = addLog (UUID "foo") (LogEntry (Date 1) "new") l == l2
+ newestWins = addLog (UUID "foo") (LogEntry (Date 1) "newest") l2 /= l2
+
+ l = M.fromList [(UUID "foo", LogEntry (Date 0) "old")]
+ l2 = M.fromList [(UUID "foo", LogEntry (Date 1) "new")]
diff --git a/Logs/Unused.hs b/Logs/Unused.hs
new file mode 100644
index 000000000..4de5bc17a
--- /dev/null
+++ b/Logs/Unused.hs
@@ -0,0 +1,45 @@
+{- git-annex unused log file
+ -
+ - Copyright 2010,2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Logs.Unused (
+ UnusedMap,
+ writeUnusedLog,
+ readUnusedLog,
+ unusedKeys,
+) where
+
+import qualified Data.Map as M
+
+import Common.Annex
+import Types.Key
+import Utility.Tmp
+
+type UnusedMap = M.Map Int Key
+
+writeUnusedLog :: FilePath -> [(Int, Key)] -> Annex ()
+writeUnusedLog prefix l = do
+ logfile <- fromRepo $ gitAnnexUnusedLog prefix
+ liftIO $ viaTmp writeFile logfile $
+ unlines $ map (\(n, k) -> show n ++ " " ++ key2file k) l
+
+readUnusedLog :: FilePath -> Annex UnusedMap
+readUnusedLog prefix = do
+ f <- fromRepo $ gitAnnexUnusedLog prefix
+ ifM (liftIO $ doesFileExist f)
+ ( M.fromList . mapMaybe parse . lines
+ <$> liftIO (readFile f)
+ , return M.empty
+ )
+ where
+ parse line = case (readish tag, file2key rest) of
+ (Just num, Just key) -> Just (num, key)
+ _ -> Nothing
+ where
+ (tag, rest) = separate (== ' ') line
+
+unusedKeys :: Annex [Key]
+unusedKeys = M.elems <$> readUnusedLog ""
diff --git a/Logs/Web.hs b/Logs/Web.hs
new file mode 100644
index 000000000..ede600ec2
--- /dev/null
+++ b/Logs/Web.hs
@@ -0,0 +1,95 @@
+{- Web url logs.
+ -
+ - Copyright 2011, 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Logs.Web (
+ URLString,
+ webUUID,
+ getUrls,
+ setUrlPresent,
+ setUrlMissing,
+ knownUrls,
+ Downloader(..),
+ getDownloader,
+ setDownloader,
+) where
+
+import qualified Data.ByteString.Lazy.Char8 as L
+import Data.Tuple.Utils
+
+import Common.Annex
+import Logs
+import Logs.Presence
+import Logs.Location
+import qualified Annex.Branch
+import Annex.CatFile
+import qualified Git
+import qualified Git.LsFiles
+
+type URLString = String
+
+-- Dummy uuid for the whole web. Do not alter.
+webUUID :: UUID
+webUUID = UUID "00000000-0000-0000-0000-000000000001"
+
+{- Gets all urls that a key might be available from. -}
+getUrls :: Key -> Annex [URLString]
+getUrls key = go $ urlLogFile key : oldurlLogs key
+ where
+ go [] = return []
+ go (l:ls) = do
+ us <- currentLog l
+ if null us
+ then go ls
+ else return us
+
+setUrlPresent :: Key -> URLString -> Annex ()
+setUrlPresent key url = do
+ us <- getUrls key
+ unless (url `elem` us) $ do
+ addLog (urlLogFile key) =<< logNow InfoPresent url
+ -- update location log to indicate that the web has the key
+ logChange key webUUID InfoPresent
+
+setUrlMissing :: Key -> URLString -> Annex ()
+setUrlMissing key url = do
+ addLog (urlLogFile key) =<< logNow InfoMissing url
+ whenM (null <$> getUrls key) $
+ logChange key webUUID InfoMissing
+
+{- Finds all known urls. -}
+knownUrls :: Annex [URLString]
+knownUrls = do
+ {- Ensure the git-annex branch's index file is up-to-date and
+ - any journaled changes are reflected in it, since we're going
+ - to query its index directly. -}
+ Annex.Branch.update
+ Annex.Branch.commit "update"
+ Annex.Branch.withIndex $ do
+ top <- fromRepo Git.repoPath
+ (l, cleanup) <- inRepo $ Git.LsFiles.stagedDetails [top]
+ r <- mapM (geturls . snd3) $ filter (isUrlLog . fst3) l
+ void $ liftIO cleanup
+ return $ concat r
+ where
+ geturls Nothing = return []
+ geturls (Just logsha) = getLog . L.unpack <$> catObject logsha
+
+data Downloader = DefaultDownloader | QuviDownloader
+
+{- Determines the downloader for an URL.
+ -
+ - Some URLs are not downloaded by normal means, and this is indicated
+ - by prefixing them with downloader: when they are recorded in the url
+ - logs. -}
+getDownloader :: URLString -> (URLString, Downloader)
+getDownloader u = case separate (== ':') u of
+ ("quvi", u') -> (u', QuviDownloader)
+ _ -> (u, DefaultDownloader)
+
+setDownloader :: URLString -> Downloader -> URLString
+setDownloader u DefaultDownloader = u
+setDownloader u QuviDownloader = "quvi:" ++ u
diff --git a/Makefile b/Makefile
new file mode 100644
index 000000000..92c5f6dcc
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,228 @@
+mans=git-annex.1 git-annex-shell.1
+all=git-annex $(mans) docs
+
+GHC?=ghc
+PREFIX?=/usr
+CABAL?=cabal # set to "./Setup" if you lack a cabal program
+
+# Am I typing :make in vim? Do a fast build.
+ifdef VIM
+all=fast
+endif
+
+build: build-stamp
+build-stamp: $(all)
+ touch $@
+
+Build/SysConfig.hs: configure.hs Build/TestConfig.hs Build/Configure.hs
+ if [ "$(CABAL)" = ./Setup ]; then ghc --make Setup; fi
+ $(CABAL) configure
+
+git-annex: Build/SysConfig.hs
+ $(CABAL) build
+ ln -sf dist/build/git-annex/git-annex git-annex
+
+git-annex.1: doc/git-annex.mdwn
+ ./Build/mdwn2man git-annex 1 doc/git-annex.mdwn > git-annex.1
+git-annex-shell.1: doc/git-annex-shell.mdwn
+ ./Build/mdwn2man git-annex-shell 1 doc/git-annex-shell.mdwn > git-annex-shell.1
+
+# These are not built normally.
+git-union-merge.1: doc/git-union-merge.mdwn
+ ./Build/mdwn2man git-union-merge 1 doc/git-union-merge.mdwn > git-union-merge.1
+git-union-merge:
+ $(GHC) --make -threaded $@
+
+install-mans: $(mans)
+ install -d $(DESTDIR)$(PREFIX)/share/man/man1
+ install -m 0644 $(mans) $(DESTDIR)$(PREFIX)/share/man/man1
+
+install-docs: docs install-mans
+ install -d $(DESTDIR)$(PREFIX)/share/doc/git-annex
+ if [ -d html ]; then \
+ rsync -a --delete html/ $(DESTDIR)$(PREFIX)/share/doc/git-annex/html/; \
+ fi
+
+install: build install-docs Build/InstallDesktopFile
+ install -d $(DESTDIR)$(PREFIX)/bin
+ install git-annex $(DESTDIR)$(PREFIX)/bin
+ ln -sf git-annex $(DESTDIR)$(PREFIX)/bin/git-annex-shell
+ ./Build/InstallDesktopFile $(PREFIX)/bin/git-annex || true
+
+test: git-annex
+ ./git-annex test
+
+# hothasktags chokes on some template haskell etc, so ignore errors
+tags:
+ find . | grep -v /.git/ | grep -v /tmp/ | grep -v /dist/ | grep -v /doc/ | egrep '\.hs$$' | xargs hothasktags > tags 2>/dev/null
+
+# If ikiwiki is available, build static html docs suitable for being
+# shipped in the software package.
+ifeq ($(shell which ikiwiki),)
+IKIWIKI=@echo "** ikiwiki not found, skipping building docs" >&2; true
+else
+IKIWIKI=ikiwiki
+endif
+
+docs: $(mans)
+ $(IKIWIKI) doc html -v --wikiname git-annex --plugin=goodstuff \
+ --no-usedirs --disable-plugin=openid --plugin=sidebar \
+ --underlaydir=/dev/null --disable-plugin=shortcut \
+ --disable-plugin=smiley \
+ --plugin=comments --set comments_pagespec="*" \
+ --exclude='news/.*' --exclude='design/assistant/blog/*' \
+ --exclude='bugs/*' --exclude='todo/*' --exclude='forum/*'
+
+clean:
+ rm -rf tmp dist git-annex $(mans) configure *.tix .hpc \
+ doc/.ikiwiki html dist tags Build/SysConfig.hs build-stamp \
+ Setup Build/InstallDesktopFile Build/EvilSplicer \
+ Build/Standalone Build/OSXMkLibs Build/DistributionUpdate \
+ git-union-merge
+ find . -name \*.o -exec rm {} \;
+ find . -name \*.hi -exec rm {} \;
+
+Build/InstallDesktopFile: Build/InstallDesktopFile.hs
+ $(GHC) --make $@
+Build/EvilSplicer: Build/EvilSplicer.hs
+ $(GHC) --make $@
+Build/Standalone: Build/Standalone.hs Build/SysConfig.hs
+ $(GHC) --make $@
+Build/OSXMkLibs: Build/OSXMkLibs.hs
+ $(GHC) --make $@
+
+sdist: clean $(mans)
+ ./Build/make-sdist.sh
+
+# Upload to hackage.
+hackage: sdist
+ @cabal upload dist/*.tar.gz
+
+LINUXSTANDALONE_DEST=tmp/git-annex.linux
+linuxstandalone: Build/Standalone
+ $(MAKE) git-annex
+
+ rm -rf "$(LINUXSTANDALONE_DEST)"
+ mkdir -p tmp
+ cp -R standalone/linux "$(LINUXSTANDALONE_DEST)"
+
+ install -d "$(LINUXSTANDALONE_DEST)/bin"
+ cp git-annex "$(LINUXSTANDALONE_DEST)/bin/"
+ strip "$(LINUXSTANDALONE_DEST)/bin/git-annex"
+ ln -sf git-annex "$(LINUXSTANDALONE_DEST)/bin/git-annex-shell"
+ zcat standalone/licences.gz > $(LINUXSTANDALONE_DEST)/LICENSE
+ cp doc/favicon.png doc/logo.svg $(LINUXSTANDALONE_DEST)
+
+ ./Build/Standalone "$(LINUXSTANDALONE_DEST)"
+
+ install -d "$(LINUXSTANDALONE_DEST)/git-core"
+ (cd "$(shell git --exec-path)" && tar c .) | (cd "$(LINUXSTANDALONE_DEST)"/git-core && tar x)
+ install -d "$(LINUXSTANDALONE_DEST)/templates"
+
+ touch "$(LINUXSTANDALONE_DEST)/libdirs.tmp"
+ for lib in $$(ldd "$(LINUXSTANDALONE_DEST)"/bin/* $$(find "$(LINUXSTANDALONE_DEST)"/git-core/ -type f) | grep -v -f standalone/linux/glibc-libs | grep -v "not a dynamic executable" | egrep '^ ' | sed 's/^\t//' | sed 's/.*=> //' | cut -d ' ' -f 1 | sort | uniq); do \
+ dir=$$(dirname "$$lib"); \
+ install -d "$(LINUXSTANDALONE_DEST)/$$dir"; \
+ echo "$$dir" >> "$(LINUXSTANDALONE_DEST)/libdirs.tmp"; \
+ cp "$$lib" "$(LINUXSTANDALONE_DEST)/$$dir"; \
+ if [ -L "$lib" ]; then \
+ link=$$(readlink -f "$$lib"); \
+ cp "$$link" "$(LINUXSTANDALONE_DEST)/$$(dirname "$$link")"; \
+ fi; \
+ done
+ sort "$(LINUXSTANDALONE_DEST)/libdirs.tmp" | uniq > "$(LINUXSTANDALONE_DEST)/libdirs"
+ rm -f "$(LINUXSTANDALONE_DEST)/libdirs.tmp"
+
+ cd tmp/git-annex.linux && find . -type f > git-annex.MANIFEST
+ cd tmp/git-annex.linux && find . -type l >> git-annex.MANIFEST
+ cd tmp && tar czf git-annex-standalone-$(shell dpkg --print-architecture).tar.gz git-annex.linux
+
+OSXAPP_DEST=tmp/build-dmg/git-annex.app
+OSXAPP_BASE=$(OSXAPP_DEST)/Contents/MacOS/bundle
+osxapp: Build/Standalone Build/OSXMkLibs
+ $(MAKE) git-annex
+
+ rm -rf "$(OSXAPP_DEST)"
+ install -d tmp/build-dmg
+ cp -R standalone/osx/git-annex.app "$(OSXAPP_DEST)"
+
+ install -d "$(OSXAPP_BASE)"
+ cp git-annex "$(OSXAPP_BASE)"
+ strip "$(OSXAPP_BASE)/git-annex"
+ ln -sf git-annex "$(OSXAPP_BASE)/git-annex-shell"
+ gzcat standalone/licences.gz > $(OSXAPP_BASE)/LICENSE
+ cp $(OSXAPP_BASE)/LICENSE tmp/build-dmg/LICENSE.txt
+
+ ./Build/Standalone $(OSXAPP_BASE)
+
+ (cd "$(shell git --exec-path)" && tar c .) | (cd "$(OSXAPP_BASE)" && tar x)
+ install -d "$(OSXAPP_BASE)/templates"
+
+ ./Build/OSXMkLibs $(OSXAPP_BASE)
+ cd $(OSXAPP_DEST) && find . -type f > Contents/MacOS/git-annex.MANIFEST
+ cd $(OSXAPP_DEST) && find . -type l >> Contents/MacOS/git-annex.MANIFEST
+ rm -f tmp/git-annex.dmg
+ hdiutil create -format UDBZ -srcfolder tmp/build-dmg \
+ -volname git-annex -o tmp/git-annex.dmg
+
+ANDROID_FLAGS?=
+# Cross compile for Android.
+# Uses https://github.com/neurocyte/ghc-android
+android: Build/EvilSplicer
+ echo "Running native build, to get TH splices.."
+ if [ ! -e dist/setup/setup ]; then $(CABAL) configure -f-Production -O0 $(ANDROID_FLAGS) -fAndroidSplice; fi
+ mkdir -p tmp
+ if ! $(CABAL) build --ghc-options=-ddump-splices 2> tmp/dump-splices; then tail tmp/dump-splices >&2; exit 1; fi
+ echo "Setting up Android build tree.."
+ ./Build/EvilSplicer tmp/splices tmp/dump-splices standalone/android/evilsplicer-headers.hs
+ rsync -az --exclude tmp --exclude dist . tmp/androidtree
+# Copy the files with expanded splices to the source tree, but
+# only if the existing source file is not newer. (So, if a file
+# used to have TH splices but they were removed, it will be newer,
+# and not overwritten.)
+ cp -uR tmp/splices/* tmp/androidtree || true
+# Some additional dependencies needed by the expanded splices.
+ sed -i 's/^ Build-Depends: / Build-Depends: yesod-routes, yesod-core, shakespeare-css, shakespeare-js, shakespeare, blaze-markup, file-embed, wai-app-static, /' tmp/androidtree/git-annex.cabal
+# Avoid warnings due to sometimes unused imports added for the splices.
+ sed -i 's/GHC-Options: \(.*\)-Wall/GHC-Options: \1-Wall -fno-warn-unused-imports /i' tmp/androidtree/git-annex.cabal
+# Cabal cannot cross compile with custom build type, so workaround.
+ sed -i 's/Build-type: Custom/Build-type: Simple/' tmp/androidtree/git-annex.cabal
+# Build just once, but link twice, for 2 different versions of Android.
+ mkdir -p tmp/androidtree/dist/build/git-annex/4.0 tmp/androidtree/dist/build/git-annex/4.3
+ if [ ! -e tmp/androidtree/dist/setup-config ]; then \
+ cd tmp/androidtree && $$HOME/.ghc/$(shell cat standalone/android/abiversion)/arm-linux-androideabi/bin/cabal configure -fAndroid $(ANDROID_FLAGS); \
+ fi
+ cd tmp/androidtree && $$HOME/.ghc/$(shell cat standalone/android/abiversion)/arm-linux-androideabi/bin/cabal build \
+ && mv dist/build/git-annex/git-annex dist/build/git-annex/4.0/git-annex
+ cd tmp/androidtree && $$HOME/.ghc/$(shell cat standalone/android/abiversion)/arm-linux-androideabi/bin/cabal build \
+ --ghc-options=-optl-z --ghc-options=-optlnocopyreloc \
+ && mv dist/build/git-annex/git-annex dist/build/git-annex/4.3/git-annex
+
+androidapp:
+ $(MAKE) android
+ $(MAKE) -C standalone/android
+
+# We bypass cabal, and only run the main ghc --make command for a
+# fast development built. Note: Does not rebuild C libraries.
+fast: dist/caballog
+ @$$(grep 'ghc --make' dist/caballog | head -n 1 | sed -e 's/-package-id [^ ]*//g' -e 's/-hide-all-packages//') -O0
+ @ln -sf dist/build/git-annex/git-annex git-annex
+ @$(MAKE) tags >/dev/null 2>&1 &
+
+dist/caballog: git-annex.cabal
+ $(CABAL) configure -f"-Production" -O0
+ $(CABAL) build -v2 | tee $@
+
+# Hardcoded command line to make hdevtools start up and work.
+# You will need some memory. It's worth it.
+# Note: Don't include WebDAV or Webapp. TH use bloats memory > 500 mb!
+# TODO should be possible to derive this from caballog.
+hdevtools:
+ hdevtools --stop-server || true
+ hdevtools check git-annex.hs -g -cpp -g -i -g -idist/build/git-annex/git-annex-tmp -g -i. -g -idist/build/autogen -g -Idist/build/autogen -g -Idist/build/git-annex/git-annex-tmp -g -IUtility -g -DWITH_TESTSUITE -g -DWITH_S3 -g -DWITH_ASSISTANT -g -DWITH_INOTIFY -g -DWITH_DBUS -g -DWITH_PAIRING -g -DWITH_XMPP -g -optP-include -g -optPdist/build/autogen/cabal_macros.h -g -odir -g dist/build/git-annex/git-annex-tmp -g -hidir -g dist/build/git-annex/git-annex-tmp -g -stubdir -g dist/build/git-annex/git-annex-tmp -g -threaded -g -Wall -g -XHaskell98 -g -XPackageImports
+
+distributionupdate:
+ ghc --make Build/DistributionUpdate
+ ./Build/DistributionUpdate
+
+.PHONY: git-annex git-union-merge git-recover-repository tags build-stamp
diff --git a/Messages.hs b/Messages.hs
new file mode 100644
index 000000000..0357da12d
--- /dev/null
+++ b/Messages.hs
@@ -0,0 +1,245 @@
+{- git-annex output messages
+ -
+ - Copyright 2010-2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Messages (
+ showStart,
+ showNote,
+ showAction,
+ showProgress,
+ metered,
+ meteredBytes,
+ showSideAction,
+ doSideAction,
+ doQuietSideAction,
+ showStoringStateAction,
+ showOutput,
+ showLongNote,
+ showEndOk,
+ showEndFail,
+ showEndResult,
+ showErr,
+ warning,
+ warningIO,
+ fileNotFound,
+ indent,
+ maybeShowJSON,
+ showFullJSON,
+ showCustom,
+ showHeader,
+ showRaw,
+ setupConsole,
+ enableDebugOutput,
+ disableDebugOutput
+) where
+
+import Text.JSON
+import Data.Progress.Meter
+import Data.Progress.Tracker
+import Data.Quantity
+import System.Log.Logger
+import System.Log.Formatter
+import System.Log.Handler (setFormatter, LogHandler)
+import System.Log.Handler.Simple
+import qualified Data.Set as S
+
+import Common
+import Types
+import Types.Messages
+import qualified Messages.JSON as JSON
+import Types.Key
+import qualified Annex
+import Utility.Metered
+
+showStart :: String -> String -> Annex ()
+showStart command file = handle (JSON.start command $ Just file) $
+ flushed $ putStr $ command ++ " " ++ file ++ " "
+
+showNote :: String -> Annex ()
+showNote s = handle (JSON.note s) $
+ flushed $ putStr $ "(" ++ s ++ ") "
+
+showAction :: String -> Annex ()
+showAction s = showNote $ s ++ "..."
+
+{- Progress dots. -}
+showProgress :: Annex ()
+showProgress = handle q $
+ flushed $ putStr "."
+
+{- Shows a progress meter while performing a transfer of a key.
+ - The action is passed a callback to use to update the meter. -}
+metered :: Maybe MeterUpdate -> Key -> (MeterUpdate -> Annex a) -> Annex a
+metered combinemeterupdate key a = go (keySize key)
+ where
+ go (Just size) = meteredBytes combinemeterupdate size a
+ go _ = a (const noop)
+
+{- Shows a progress meter while performing an action on a given number
+ - of bytes. -}
+meteredBytes :: Maybe MeterUpdate -> Integer -> (MeterUpdate -> Annex a) -> Annex a
+meteredBytes combinemeterupdate size a = withOutputType go
+ where
+ go NormalOutput = do
+ progress <- liftIO $ newProgress "" size
+ meter <- liftIO $ newMeter progress "B" 25 (renderNums binaryOpts 1)
+ showOutput
+ r <- a $ \n -> liftIO $ do
+ setP progress $ fromBytesProcessed n
+ displayMeter stdout meter
+ maybe noop (\m -> m n) combinemeterupdate
+ liftIO $ clearMeter stdout meter
+ return r
+ go _ = a (const noop)
+
+showSideAction :: String -> Annex ()
+showSideAction m = Annex.getState Annex.output >>= go
+ where
+ go st
+ | sideActionBlock st == StartBlock = do
+ p
+ let st' = st { sideActionBlock = InBlock }
+ Annex.changeState $ \s -> s { Annex.output = st' }
+ | sideActionBlock st == InBlock = return ()
+ | otherwise = p
+ p = handle q $ putStrLn $ "(" ++ m ++ "...)"
+
+showStoringStateAction :: Annex ()
+showStoringStateAction = showSideAction "Recording state in git"
+
+{- Performs an action, supressing showSideAction messages. -}
+doQuietSideAction :: Annex a -> Annex a
+doQuietSideAction = doSideAction' InBlock
+
+{- Performs an action, that may call showSideAction multiple times.
+ - Only the first will be displayed. -}
+doSideAction :: Annex a -> Annex a
+doSideAction = doSideAction' StartBlock
+
+doSideAction' :: SideActionBlock -> Annex a -> Annex a
+doSideAction' b a = do
+ o <- Annex.getState Annex.output
+ set $ o { sideActionBlock = b }
+ set o `after` a
+ where
+ set o = Annex.changeState $ \s -> s { Annex.output = o }
+
+showOutput :: Annex ()
+showOutput = handle q $
+ putStr "\n"
+
+showLongNote :: String -> Annex ()
+showLongNote s = handle (JSON.note s) $
+ putStrLn $ '\n' : indent s
+
+showEndOk :: Annex ()
+showEndOk = showEndResult True
+
+showEndFail :: Annex ()
+showEndFail = showEndResult False
+
+showEndResult :: Bool -> Annex ()
+showEndResult ok = handle (JSON.end ok) $ putStrLn msg
+ where
+ msg
+ | ok = "ok"
+ | otherwise = "failed"
+
+showErr :: (Show a) => a -> Annex ()
+showErr e = warning' $ "git-annex: " ++ show e
+
+warning :: String -> Annex ()
+warning = warning' . indent
+
+warning' :: String -> Annex ()
+warning' w = do
+ handle q $ putStr "\n"
+ liftIO $ do
+ hFlush stdout
+ hPutStrLn stderr w
+
+warningIO :: String -> IO ()
+warningIO w = do
+ putStr "\n"
+ hFlush stdout
+ hPutStrLn stderr w
+
+{- Displays a warning one time about a file the user specified not existing. -}
+fileNotFound :: FilePath -> Annex ()
+fileNotFound file = do
+ st <- Annex.getState Annex.output
+ let shown = fileNotFoundShown st
+ when (S.notMember file shown) $ do
+ let shown' = S.insert file shown
+ let st' = st { fileNotFoundShown = shown' }
+ Annex.changeState $ \s -> s { Annex.output = st' }
+ liftIO $ hPutStrLn stderr $ unwords
+ [ "git-annex:", file, "not found" ]
+
+indent :: String -> String
+indent = intercalate "\n" . map (\l -> " " ++ l) . lines
+
+{- Shows a JSON fragment only when in json mode. -}
+maybeShowJSON :: JSON a => [(String, a)] -> Annex ()
+maybeShowJSON v = handle (JSON.add v) q
+
+{- Shows a complete JSON value, only when in json mode. -}
+showFullJSON :: JSON a => [(String, a)] -> Annex Bool
+showFullJSON v = withOutputType $ liftIO . go
+ where
+ go JSONOutput = JSON.complete v >> return True
+ go _ = return False
+
+{- Performs an action that outputs nonstandard/customized output, and
+ - in JSON mode wraps its output in JSON.start and JSON.end, so it's
+ - a complete JSON document.
+ - This is only needed when showStart and showEndOk is not used. -}
+showCustom :: String -> Annex Bool -> Annex ()
+showCustom command a = do
+ handle (JSON.start command Nothing) q
+ r <- a
+ handle (JSON.end r) q
+
+showHeader :: String -> Annex ()
+showHeader h = handle q $
+ flushed $ putStr $ h ++ ": "
+
+showRaw :: String -> Annex ()
+showRaw s = handle q $ putStrLn s
+
+setupConsole :: IO ()
+setupConsole = do
+ s <- setFormatter
+ <$> streamHandler stderr DEBUG
+ <*> pure (simpleLogFormatter "[$time] $msg")
+ updateGlobalLogger rootLoggerName (setLevel NOTICE . setHandlers [s])
+ {- This avoids ghc's output layer crashing on
+ - invalid encoded characters in
+ - filenames when printing them out. -}
+ fileEncoding stdout
+ fileEncoding stderr
+
+enableDebugOutput :: IO ()
+enableDebugOutput = updateGlobalLogger rootLoggerName $ setLevel DEBUG
+
+disableDebugOutput :: IO ()
+disableDebugOutput = updateGlobalLogger rootLoggerName $ setLevel NOTICE
+
+handle :: IO () -> IO () -> Annex ()
+handle json normal = withOutputType go
+ where
+ go NormalOutput = liftIO normal
+ go QuietOutput = q
+ go JSONOutput = liftIO $ flushed json
+
+q :: Monad m => m ()
+q = noop
+
+flushed :: IO () -> IO ()
+flushed a = a >> hFlush stdout
+
+withOutputType :: (OutputType -> Annex a) -> Annex a
+withOutputType a = outputType <$> Annex.getState Annex.output >>= a
diff --git a/Messages/JSON.hs b/Messages/JSON.hs
new file mode 100644
index 000000000..d57d69318
--- /dev/null
+++ b/Messages/JSON.hs
@@ -0,0 +1,37 @@
+{- git-annex JSON output
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Messages.JSON (
+ start,
+ end,
+ note,
+ add,
+ complete
+) where
+
+import Text.JSON
+
+import qualified Utility.JSONStream as Stream
+
+start :: String -> Maybe String -> IO ()
+start command file =
+ putStr $ Stream.start $ ("command", command) : filepart file
+ where
+ filepart Nothing = []
+ filepart (Just f) = [("file", f)]
+
+end :: Bool -> IO ()
+end b = putStr $ Stream.add [("success", b)] ++ Stream.end
+
+note :: String -> IO ()
+note s = add [("note", s)]
+
+add :: JSON a => [(String, a)] -> IO ()
+add v = putStr $ Stream.add v
+
+complete :: JSON a => [(String, a)] -> IO ()
+complete v = putStr $ Stream.start v ++ Stream.end
diff --git a/NEWS b/NEWS
new file mode 120000
index 000000000..798088bec
--- /dev/null
+++ b/NEWS
@@ -0,0 +1 @@
+debian/NEWS \ No newline at end of file
diff --git a/Option.hs b/Option.hs
new file mode 100644
index 000000000..64ba56f6d
--- /dev/null
+++ b/Option.hs
@@ -0,0 +1,79 @@
+{- common command-line options
+ -
+ - Copyright 2010-2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Option (
+ common,
+ matcher,
+ flag,
+ field,
+ name,
+ ArgDescr(..),
+ OptDescr(..),
+) where
+
+import System.Console.GetOpt
+
+import Common.Annex
+import qualified Annex
+import Types.Messages
+import Limit
+import Usage
+
+common :: [Option]
+common =
+ [ Option [] ["force"] (NoArg (setforce True))
+ "allow actions that may lose annexed data"
+ , Option ['F'] ["fast"] (NoArg (setfast True))
+ "avoid slow operations"
+ , Option ['a'] ["auto"] (NoArg (setauto True))
+ "automatic mode"
+ , Option ['q'] ["quiet"] (NoArg (Annex.setOutput QuietOutput))
+ "avoid verbose output"
+ , Option ['v'] ["verbose"] (NoArg (Annex.setOutput NormalOutput))
+ "allow verbose output (default)"
+ , Option ['j'] ["json"] (NoArg (Annex.setOutput JSONOutput))
+ "enable JSON output"
+ , Option ['d'] ["debug"] (NoArg setdebug)
+ "show debug messages"
+ , Option [] ["no-debug"] (NoArg unsetdebug)
+ "don't show debug messages"
+ , Option ['b'] ["backend"] (ReqArg setforcebackend paramName)
+ "specify key-value backend to use"
+ ]
+ where
+ setforce v = Annex.changeState $ \s -> s { Annex.force = v }
+ setfast v = Annex.changeState $ \s -> s { Annex.fast = v }
+ setauto v = Annex.changeState $ \s -> s { Annex.auto = v }
+ setforcebackend v = Annex.changeState $ \s -> s { Annex.forcebackend = Just v }
+ setdebug = Annex.changeGitConfig $ \c -> c { annexDebug = True }
+ unsetdebug = Annex.changeGitConfig $ \c -> c { annexDebug = False }
+
+matcher :: [Option]
+matcher =
+ [ longopt "not" "negate next option"
+ , longopt "and" "both previous and next option must match"
+ , longopt "or" "either previous or next option must match"
+ , shortopt "(" "open group of options"
+ , shortopt ")" "close group of options"
+ ]
+ where
+ longopt o = Option [] [o] $ NoArg $ addToken o
+ shortopt o = Option o [] $ NoArg $ addToken o
+
+{- An option that sets a flag. -}
+flag :: String -> String -> String -> Option
+flag short opt description =
+ Option short [opt] (NoArg (Annex.setFlag opt)) description
+
+{- An option that sets a field. -}
+field :: String -> String -> String -> String -> Option
+field short opt paramdesc description =
+ Option short [opt] (ReqArg (Annex.setField opt) paramdesc) description
+
+{- The flag or field name used for an option. -}
+name :: Option -> String
+name (Option _ o _ _) = Prelude.head o
diff --git a/README b/README
new file mode 100644
index 000000000..ce67d6816
--- /dev/null
+++ b/README
@@ -0,0 +1,6 @@
+git-annex allows managing files with git, without checking the file
+contents into git. While that may seem paradoxical, it is useful when
+dealing with files larger than git can currently easily handle, whether due
+to limitations in memory, checksumming time, or disk space.
+
+For documentation, see doc/ or <http://git-annex.branchable.com/>
diff --git a/Remote.hs b/Remote.hs
new file mode 100644
index 000000000..e355b0975
--- /dev/null
+++ b/Remote.hs
@@ -0,0 +1,294 @@
+{- git-annex remotes
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Remote (
+ Remote,
+ uuid,
+ name,
+ storeKey,
+ retrieveKeyFile,
+ retrieveKeyFileCheap,
+ removeKey,
+ hasKey,
+ hasKeyCheap,
+ whereisKey,
+ remoteFsck,
+
+ remoteTypes,
+ remoteList,
+ syncableRemote,
+ remoteMap,
+ uuidDescriptions,
+ byName,
+ byNameOnly,
+ byNameWithUUID,
+ byCost,
+ prettyPrintUUIDs,
+ prettyListUUIDs,
+ prettyUUID,
+ remoteFromUUID,
+ remotesWithUUID,
+ remotesWithoutUUID,
+ keyLocations,
+ keyPossibilities,
+ keyPossibilitiesTrusted,
+ nameToUUID,
+ showTriedRemotes,
+ showLocations,
+ forceTrust,
+ logStatus,
+ checkAvailable
+) where
+
+import qualified Data.Map as M
+import Text.JSON
+import Text.JSON.Generic
+import Data.Tuple
+import Data.Ord
+
+import Common.Annex
+import Types.Remote
+import qualified Annex
+import Annex.UUID
+import Logs.UUID
+import Logs.Trust
+import Logs.Location hiding (logStatus)
+import Remote.List
+import Config
+import Git.Types (RemoteName)
+
+{- Map from UUIDs of Remotes to a calculated value. -}
+remoteMap :: (Remote -> a) -> Annex (M.Map UUID a)
+remoteMap c = M.fromList . map (\r -> (uuid r, c r)) .
+ filter (\r -> uuid r /= NoUUID) <$> remoteList
+
+{- Map of UUIDs of remotes and their descriptions.
+ - The names of Remotes are added to suppliment any description that has
+ - been set for a repository. -}
+uuidDescriptions :: Annex (M.Map UUID String)
+uuidDescriptions = M.unionWith addName <$> uuidMap <*> remoteMap name
+
+addName :: String -> RemoteName -> String
+addName desc n
+ | desc == n = desc
+ | null desc = n
+ | otherwise = n ++ " (" ++ desc ++ ")"
+
+{- When a name is specified, looks up the remote matching that name.
+ - (Or it can be a UUID.) -}
+byName :: Maybe RemoteName -> Annex (Maybe Remote)
+byName Nothing = return Nothing
+byName (Just n) = either error Just <$> byName' n
+
+{- Like byName, but the remote must have a configured UUID. -}
+byNameWithUUID :: Maybe RemoteName -> Annex (Maybe Remote)
+byNameWithUUID = checkuuid <=< byName
+ where
+ checkuuid Nothing = return Nothing
+ checkuuid (Just r)
+ | uuid r == NoUUID =
+ if remoteAnnexIgnore (gitconfig r)
+ then error $ noRemoteUUIDMsg r ++
+ " (" ++ show (remoteConfig (repo r) "ignore") ++
+ " is set)"
+ else error $ noRemoteUUIDMsg r
+ | otherwise = return $ Just r
+
+byName' :: RemoteName -> Annex (Either String Remote)
+byName' "" = return $ Left "no remote specified"
+byName' n = handle . filter matching <$> remoteList
+ where
+ handle [] = Left $ "there is no available git remote named \"" ++ n ++ "\""
+ handle (match:_) = Right match
+ matching r = n == name r || toUUID n == uuid r
+
+{- Only matches remote name, not UUID -}
+byNameOnly :: RemoteName -> Annex (Maybe Remote)
+byNameOnly n = headMaybe . filter matching <$> remoteList
+ where
+ matching r = n == name r
+
+noRemoteUUIDMsg :: Remote -> String
+noRemoteUUIDMsg r = "cannot determine uuid for " ++ name r
+
+{- Looks up a remote by name (or by UUID, or even by description),
+ - and returns its UUID. Finds even repositories that are not
+ - configured in .git/config. -}
+nameToUUID :: RemoteName -> Annex UUID
+nameToUUID "." = getUUID -- special case for current repo
+nameToUUID "here" = getUUID
+nameToUUID "" = error "no remote specified"
+nameToUUID n = byName' n >>= go
+ where
+ go (Right r) = case uuid r of
+ NoUUID -> error $ noRemoteUUIDMsg r
+ u -> return u
+ go (Left e) = fromMaybe (error e) <$> bydescription
+ bydescription = do
+ m <- uuidMap
+ case M.lookup n $ transform swap m of
+ Just u -> return $ Just u
+ Nothing -> return $ byuuid m
+ byuuid m = M.lookup (toUUID n) $ transform double m
+ transform a = M.fromList . map a . M.toList
+ double (a, _) = (a, a)
+
+{- Pretty-prints a list of UUIDs of remotes, for human display.
+ -
+ - When JSON is enabled, also generates a machine-readable description
+ - of the UUIDs. -}
+prettyPrintUUIDs :: String -> [UUID] -> Annex String
+prettyPrintUUIDs desc uuids = do
+ hereu <- getUUID
+ m <- uuidDescriptions
+ maybeShowJSON [(desc, map (jsonify m hereu) uuids)]
+ return $ unwords $ map (\u -> "\t" ++ prettify m hereu u ++ "\n") uuids
+ where
+ finddescription m u = M.findWithDefault "" u m
+ prettify m hereu u
+ | not (null d) = fromUUID u ++ " -- " ++ d
+ | otherwise = fromUUID u
+ where
+ ishere = hereu == u
+ n = finddescription m u
+ d
+ | null n && ishere = "here"
+ | ishere = addName n "here"
+ | otherwise = n
+ jsonify m hereu u = toJSObject
+ [ ("uuid", toJSON $ fromUUID u)
+ , ("description", toJSON $ finddescription m u)
+ , ("here", toJSON $ hereu == u)
+ ]
+
+{- List of remote names and/or descriptions, for human display. -}
+prettyListUUIDs :: [UUID] -> Annex [String]
+prettyListUUIDs uuids = do
+ hereu <- getUUID
+ m <- uuidDescriptions
+ return $ map (prettify m hereu) uuids
+ where
+ finddescription m u = M.findWithDefault "" u m
+ prettify m hereu u
+ | u == hereu = addName n "here"
+ | otherwise = n
+ where
+ n = finddescription m u
+
+{- Nice display of a remote's name and/or description. -}
+prettyUUID :: UUID -> Annex String
+prettyUUID u = concat <$> prettyListUUIDs [u]
+
+{- Gets the remote associated with a UUID. -}
+remoteFromUUID :: UUID -> Annex (Maybe Remote)
+remoteFromUUID u = ifM ((==) u <$> getUUID)
+ ( return Nothing
+ , do
+ maybe tryharder (return . Just) =<< findinmap
+ )
+ where
+ findinmap = M.lookup u <$> remoteMap id
+ {- Re-read remote list in case a new remote has popped up. -}
+ tryharder = do
+ void remoteListRefresh
+ findinmap
+
+{- Filters a list of remotes to ones that have the listed uuids. -}
+remotesWithUUID :: [Remote] -> [UUID] -> [Remote]
+remotesWithUUID rs us = filter (\r -> uuid r `elem` us) rs
+
+{- Filters a list of remotes to ones that do not have the listed uuids. -}
+remotesWithoutUUID :: [Remote] -> [UUID] -> [Remote]
+remotesWithoutUUID rs us = filter (\r -> uuid r `notElem` us) rs
+
+{- List of repository UUIDs that the location log indicates may have a key.
+ - Dead repositories are excluded. -}
+keyLocations :: Key -> Annex [UUID]
+keyLocations key = trustExclude DeadTrusted =<< loggedLocations key
+
+{- Cost ordered lists of remotes that the location log indicates
+ - may have a key.
+ -}
+keyPossibilities :: Key -> Annex [Remote]
+keyPossibilities key = fst <$> keyPossibilities' key []
+
+{- Cost ordered lists of remotes that the location log indicates
+ - may have a key.
+ -
+ - Also returns a list of UUIDs that are trusted to have the key
+ - (some may not have configured remotes).
+ -}
+keyPossibilitiesTrusted :: Key -> Annex ([Remote], [UUID])
+keyPossibilitiesTrusted key = keyPossibilities' key =<< trustGet Trusted
+
+keyPossibilities' :: Key -> [UUID] -> Annex ([Remote], [UUID])
+keyPossibilities' key trusted = do
+ u <- getUUID
+
+ -- uuids of all remotes that are recorded to have the key
+ validuuids <- filter (/= u) <$> keyLocations key
+
+ -- note that validuuids is assumed to not have dups
+ let validtrusteduuids = validuuids `intersect` trusted
+
+ -- remotes that match uuids that have the key
+ allremotes <- filter (not . remoteAnnexIgnore . gitconfig)
+ <$> remoteList
+ let validremotes = remotesWithUUID allremotes validuuids
+
+ return (sortBy (comparing cost) validremotes, validtrusteduuids)
+
+{- Displays known locations of a key. -}
+showLocations :: Key -> [UUID] -> String -> Annex ()
+showLocations key exclude nolocmsg = do
+ u <- getUUID
+ uuids <- keyLocations key
+ untrusteduuids <- trustGet UnTrusted
+ let uuidswanted = filteruuids uuids (u:exclude++untrusteduuids)
+ let uuidsskipped = filteruuids uuids (u:exclude++uuidswanted)
+ ppuuidswanted <- Remote.prettyPrintUUIDs "wanted" uuidswanted
+ ppuuidsskipped <- Remote.prettyPrintUUIDs "skipped" uuidsskipped
+ showLongNote $ message ppuuidswanted ppuuidsskipped
+ ignored <- filter (remoteAnnexIgnore . gitconfig) <$> remoteList
+ unless (null ignored) $
+ showLongNote $ "(Note that these git remotes have annex-ignore set: " ++ unwords (map name ignored) ++ ")"
+ where
+ filteruuids l x = filter (`notElem` x) l
+ message [] [] = nolocmsg
+ message rs [] = "Try making some of these repositories available:\n" ++ rs
+ message [] us = "Also these untrusted repositories may contain the file:\n" ++ us
+ message rs us = message rs [] ++ message [] us
+
+showTriedRemotes :: [Remote] -> Annex ()
+showTriedRemotes [] = noop
+showTriedRemotes remotes =
+ showLongNote $ "Unable to access these remotes: " ++
+ intercalate ", " (map name remotes)
+
+forceTrust :: TrustLevel -> String -> Annex ()
+forceTrust level remotename = do
+ u <- nameToUUID remotename
+ Annex.changeState $ \s ->
+ s { Annex.forcetrust = M.insert u level (Annex.forcetrust s) }
+
+{- Used to log a change in a remote's having a key. The change is logged
+ - in the local repo, not on the remote. The process of transferring the
+ - key to the remote, or removing the key from it *may* log the change
+ - on the remote, but this cannot always be relied on. -}
+logStatus :: Remote -> Key -> LogStatus -> Annex ()
+logStatus remote key = logChange key (uuid remote)
+
+{- Orders remotes by cost, with ones with the lowest cost grouped together. -}
+byCost :: [Remote] -> [[Remote]]
+byCost = map snd . sortBy (comparing fst) . M.toList . costmap
+ where
+ costmap = M.fromListWith (++) . map costpair
+ costpair r = (cost r, [r])
+
+checkAvailable :: Bool -> Remote -> IO Bool
+checkAvailable assumenetworkavailable =
+ maybe (return assumenetworkavailable) doesDirectoryExist . localpath
diff --git a/Remote/Bup.hs b/Remote/Bup.hs
new file mode 100644
index 000000000..4e89dcff2
--- /dev/null
+++ b/Remote/Bup.hs
@@ -0,0 +1,288 @@
+{- Using bup as a remote.
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Remote.Bup (remote) where
+
+import qualified Data.ByteString.Lazy as L
+import qualified Data.Map as M
+import System.Process
+import Data.ByteString.Lazy.UTF8 (fromString)
+
+import Common.Annex
+import Types.Remote
+import Types.Key
+import qualified Git
+import qualified Git.Command
+import qualified Git.Config
+import qualified Git.Construct
+import qualified Git.Ref
+import Config
+import Config.Cost
+import qualified Remote.Helper.Ssh as Ssh
+import Remote.Helper.Special
+import Remote.Helper.Encryptable
+import Remote.Helper.Messages
+import Crypto
+import Utility.Hash
+import Utility.UserInfo
+import Annex.Content
+import Annex.UUID
+import Utility.Metered
+
+type BupRepo = String
+
+remote :: RemoteType
+remote = RemoteType {
+ typename = "bup",
+ enumerate = findSpecialRemotes "buprepo",
+ generate = gen,
+ setup = bupSetup
+}
+
+gen :: Git.Repo -> UUID -> RemoteConfig -> RemoteGitConfig -> Annex (Maybe Remote)
+gen r u c gc = do
+ bupr <- liftIO $ bup2GitRemote buprepo
+ cst <- remoteCost gc $
+ if bupLocal buprepo
+ then nearlyCheapRemoteCost
+ else expensiveRemoteCost
+ (u', bupr') <- getBupUUID bupr u
+
+ let new = Remote
+ { uuid = u'
+ , cost = cst
+ , name = Git.repoDescribe r
+ , storeKey = store new buprepo
+ , retrieveKeyFile = retrieve buprepo
+ , retrieveKeyFileCheap = retrieveCheap buprepo
+ , removeKey = remove
+ , hasKey = checkPresent r bupr'
+ , hasKeyCheap = bupLocal buprepo
+ , whereisKey = Nothing
+ , remoteFsck = Nothing
+ , repairRepo = Nothing
+ , config = c
+ , repo = r
+ , gitconfig = gc
+ , localpath = if bupLocal buprepo && not (null buprepo)
+ then Just buprepo
+ else Nothing
+ , remotetype = remote
+ , globallyAvailable = not $ bupLocal buprepo
+ , readonly = False
+ }
+ return $ Just $ encryptableRemote c
+ (storeEncrypted new buprepo)
+ (retrieveEncrypted buprepo)
+ new
+ where
+ buprepo = fromMaybe (error "missing buprepo") $ remoteAnnexBupRepo gc
+
+bupSetup :: Maybe UUID -> RemoteConfig -> Annex (RemoteConfig, UUID)
+bupSetup mu c = do
+ u <- maybe (liftIO genUUID) return mu
+
+ -- verify configuration is sane
+ let buprepo = fromMaybe (error "Specify buprepo=") $
+ M.lookup "buprepo" c
+ c' <- encryptionSetup c
+
+ -- bup init will create the repository.
+ -- (If the repository already exists, bup init again appears safe.)
+ showAction "bup init"
+ unlessM (bup "init" buprepo []) $ error "bup init failed"
+
+ storeBupUUID u buprepo
+
+ -- The buprepo is stored in git config, as well as this repo's
+ -- persistant state, so it can vary between hosts.
+ gitConfigSpecialRemote u c' "buprepo" buprepo
+
+ return (c', u)
+
+bupParams :: String -> BupRepo -> [CommandParam] -> [CommandParam]
+bupParams command buprepo params =
+ Param command : [Param "-r", Param buprepo] ++ params
+
+bup :: String -> BupRepo -> [CommandParam] -> Annex Bool
+bup command buprepo params = do
+ showOutput -- make way for bup output
+ liftIO $ boolSystem "bup" $ bupParams command buprepo params
+
+pipeBup :: [CommandParam] -> Maybe Handle -> Maybe Handle -> IO Bool
+pipeBup params inh outh = do
+ p <- runProcess "bup" (toCommand params)
+ Nothing Nothing inh outh Nothing
+ ok <- waitForProcess p
+ case ok of
+ ExitSuccess -> return True
+ _ -> return False
+
+bupSplitParams :: Remote -> BupRepo -> Key -> [CommandParam] -> Annex [CommandParam]
+bupSplitParams r buprepo k src = do
+ let os = map Param $ remoteAnnexBupSplitOptions $ gitconfig r
+ showOutput -- make way for bup output
+ return $ bupParams "split" buprepo
+ (os ++ [Param "-n", Param (bupRef k)] ++ src)
+
+store :: Remote -> BupRepo -> Key -> AssociatedFile -> MeterUpdate -> Annex Bool
+store r buprepo k _f _p = sendAnnex k (rollback k buprepo) $ \src -> do
+ params <- bupSplitParams r buprepo k [File src]
+ liftIO $ boolSystem "bup" params
+
+storeEncrypted :: Remote -> BupRepo -> (Cipher, Key) -> Key -> MeterUpdate -> Annex Bool
+storeEncrypted r buprepo (cipher, enck) k _p =
+ sendAnnex k (rollback enck buprepo) $ \src -> do
+ params <- bupSplitParams r buprepo enck []
+ liftIO $ catchBoolIO $
+ encrypt (getGpgEncParams r) cipher (feedFile src) $ \h ->
+ pipeBup params (Just h) Nothing
+
+retrieve :: BupRepo -> Key -> AssociatedFile -> FilePath -> MeterUpdate -> Annex Bool
+retrieve buprepo k _f d _p = do
+ let params = bupParams "join" buprepo [Param $ bupRef k]
+ liftIO $ catchBoolIO $ do
+ tofile <- openFile d WriteMode
+ pipeBup params Nothing (Just tofile)
+
+retrieveCheap :: BupRepo -> Key -> FilePath -> Annex Bool
+retrieveCheap _ _ _ = return False
+
+retrieveEncrypted :: BupRepo -> (Cipher, Key) -> Key -> FilePath -> MeterUpdate -> Annex Bool
+retrieveEncrypted buprepo (cipher, enck) _ f _p = liftIO $ catchBoolIO $
+ withHandle StdoutHandle createProcessSuccess p $ \h -> do
+ decrypt cipher (\toh -> L.hPut toh =<< L.hGetContents h) $
+ readBytes $ L.writeFile f
+ return True
+ where
+ params = bupParams "join" buprepo [Param $ bupRef enck]
+ p = proc "bup" $ toCommand params
+
+remove :: Key -> Annex Bool
+remove _ = do
+ warning "content cannot be removed from bup remote"
+ return False
+
+{- Cannot revert having stored a key in bup, but at least the data for the
+ - key will be used for deltaing data of other keys stored later.
+ -
+ - We can, however, remove the git branch that bup created for the key.
+ -}
+rollback :: Key -> BupRepo -> Annex ()
+rollback k bupr = go =<< liftIO (bup2GitRemote bupr)
+ where
+ go r
+ | Git.repoIsUrl r = void $ onBupRemote r boolSystem "git" params
+ | otherwise = void $ liftIO $ catchMaybeIO $
+ boolSystem "git" $ Git.Command.gitCommandLine params r
+ params = [ Params "branch -D", Param (bupRef k) ]
+
+{- Bup does not provide a way to tell if a given dataset is present
+ - in a bup repository. One way it to check if the git repository has
+ - a branch matching the name (as created by bup split -n).
+ -}
+checkPresent :: Git.Repo -> Git.Repo -> Key -> Annex (Either String Bool)
+checkPresent r bupr k
+ | Git.repoIsUrl bupr = do
+ showChecking r
+ ok <- onBupRemote bupr boolSystem "git" params
+ return $ Right ok
+ | otherwise = liftIO $ catchMsgIO $
+ boolSystem "git" $ Git.Command.gitCommandLine params bupr
+ where
+ params =
+ [ Params "show-ref --quiet --verify"
+ , Param $ "refs/heads/" ++ bupRef k
+ ]
+
+{- Store UUID in the annex.uuid setting of the bup repository. -}
+storeBupUUID :: UUID -> BupRepo -> Annex ()
+storeBupUUID u buprepo = do
+ r <- liftIO $ bup2GitRemote buprepo
+ if Git.repoIsUrl r
+ then do
+ showAction "storing uuid"
+ unlessM (onBupRemote r boolSystem "git"
+ [Params $ "config annex.uuid " ++ v]) $
+ error "ssh failed"
+ else liftIO $ do
+ r' <- Git.Config.read r
+ let olduuid = Git.Config.get "annex.uuid" "" r'
+ when (olduuid == "") $
+ Git.Command.run
+ [ Param "config"
+ , Param "annex.uuid"
+ , Param v
+ ] r'
+ where
+ v = fromUUID u
+
+onBupRemote :: Git.Repo -> (FilePath -> [CommandParam] -> IO a) -> FilePath -> [CommandParam] -> Annex a
+onBupRemote r a command params = do
+ sshparams <- Ssh.toRepo r [Param $
+ "cd " ++ dir ++ " && " ++ unwords (command : toCommand params)]
+ liftIO $ a "ssh" sshparams
+ where
+ path = Git.repoPath r
+ base = fromMaybe path (stripPrefix "/~/" path)
+ dir = shellEscape base
+
+{- Allow for bup repositories on removable media by checking
+ - local bup repositories to see if they are available, and getting their
+ - uuid (which may be different from the stored uuid for the bup remote).
+ -
+ - If a bup repository is not available, returns NoUUID.
+ - This will cause checkPresent to indicate nothing from the bup remote
+ - is known to be present.
+ -
+ - Also, returns a version of the repo with config read, if it is local.
+ -}
+getBupUUID :: Git.Repo -> UUID -> Annex (UUID, Git.Repo)
+getBupUUID r u
+ | Git.repoIsUrl r = return (u, r)
+ | otherwise = liftIO $ do
+ ret <- tryIO $ Git.Config.read r
+ case ret of
+ Right r' -> return (toUUID $ Git.Config.get "annex.uuid" "" r', r')
+ Left _ -> return (NoUUID, r)
+
+{- Converts a bup remote path spec into a Git.Repo. There are some
+ - differences in path representation between git and bup. -}
+bup2GitRemote :: BupRepo -> IO Git.Repo
+bup2GitRemote "" = do
+ -- bup -r "" operates on ~/.bup
+ h <- myHomeDir
+ Git.Construct.fromAbsPath $ h </> ".bup"
+bup2GitRemote r
+ | bupLocal r =
+ if "/" `isPrefixOf` r
+ then Git.Construct.fromAbsPath r
+ else error "please specify an absolute path"
+ | otherwise = Git.Construct.fromUrl $ "ssh://" ++ host ++ slash dir
+ where
+ bits = split ":" r
+ host = Prelude.head bits
+ dir = intercalate ":" $ drop 1 bits
+ -- "host:~user/dir" is not supported specially by bup;
+ -- "host:dir" is relative to the home directory;
+ -- "host:" goes in ~/.bup
+ slash d
+ | null d = "/~/.bup"
+ | "/" `isPrefixOf` d = d
+ | otherwise = "/~/" ++ d
+
+{- Converts a key into a git ref name, which bup-split -n will use to point
+ - to it. -}
+bupRef :: Key -> String
+bupRef k
+ | Git.Ref.legal True shown = shown
+ | otherwise = "git-annex-" ++ show (sha256 (fromString shown))
+ where
+ shown = key2file k
+
+bupLocal :: BupRepo -> Bool
+bupLocal = notElem ':'
diff --git a/Remote/Directory.hs b/Remote/Directory.hs
new file mode 100644
index 000000000..e6deee4bf
--- /dev/null
+++ b/Remote/Directory.hs
@@ -0,0 +1,254 @@
+{- A "remote" that is just a filesystem directory.
+ -
+ - Copyright 2011-2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Remote.Directory (remote) where
+
+import qualified Data.ByteString.Lazy as L
+import qualified Data.ByteString as S
+import qualified Data.Map as M
+import Data.Int
+
+import Common.Annex
+import Types.Remote
+import qualified Git
+import Config.Cost
+import Config
+import Utility.FileMode
+import Remote.Helper.Special
+import Remote.Helper.Encryptable
+import Remote.Helper.Chunked
+import Crypto
+import Annex.Content
+import Annex.UUID
+import Utility.Metered
+
+remote :: RemoteType
+remote = RemoteType {
+ typename = "directory",
+ enumerate = findSpecialRemotes "directory",
+ generate = gen,
+ setup = directorySetup
+}
+
+gen :: Git.Repo -> UUID -> RemoteConfig -> RemoteGitConfig -> Annex (Maybe Remote)
+gen r u c gc = do
+ cst <- remoteCost gc cheapRemoteCost
+ let chunksize = chunkSize c
+ return $ Just $ encryptableRemote c
+ (storeEncrypted dir (getGpgEncParams (c,gc)) chunksize)
+ (retrieveEncrypted dir chunksize)
+ Remote {
+ uuid = u,
+ cost = cst,
+ name = Git.repoDescribe r,
+ storeKey = store dir chunksize,
+ retrieveKeyFile = retrieve dir chunksize,
+ retrieveKeyFileCheap = retrieveCheap dir chunksize,
+ removeKey = remove dir,
+ hasKey = checkPresent dir chunksize,
+ hasKeyCheap = True,
+ whereisKey = Nothing,
+ remoteFsck = Nothing,
+ repairRepo = Nothing,
+ config = c,
+ repo = r,
+ gitconfig = gc,
+ localpath = Just dir,
+ readonly = False,
+ globallyAvailable = False,
+ remotetype = remote
+ }
+ where
+ dir = fromMaybe (error "missing directory") $ remoteAnnexDirectory gc
+
+directorySetup :: Maybe UUID -> RemoteConfig -> Annex (RemoteConfig, UUID)
+directorySetup mu c = do
+ u <- maybe (liftIO genUUID) return mu
+ -- verify configuration is sane
+ let dir = fromMaybe (error "Specify directory=") $
+ M.lookup "directory" c
+ absdir <- liftIO $ absPath dir
+ liftIO $ unlessM (doesDirectoryExist absdir) $
+ error $ "Directory does not exist: " ++ absdir
+ c' <- encryptionSetup c
+
+ -- The directory is stored in git config, not in this remote's
+ -- persistant state, so it can vary between hosts.
+ gitConfigSpecialRemote u c' "directory" absdir
+ return (M.delete "directory" c', u)
+
+{- Locations to try to access a given Key in the Directory.
+ - We try more than since we used to write to different hash directories. -}
+locations :: FilePath -> Key -> [FilePath]
+locations d k = map (d </>) (keyPaths k)
+
+{- Directory where the file(s) for a key are stored. -}
+storeDir :: FilePath -> Key -> FilePath
+storeDir d k = addTrailingPathSeparator $ d </> hashDirLower k </> keyFile k
+
+{- Where we store temporary data for a key as it's being uploaded. -}
+tmpDir :: FilePath -> Key -> FilePath
+tmpDir d k = addTrailingPathSeparator $ d </> "tmp" </> keyFile k
+
+withCheckedFiles :: (FilePath -> IO Bool) -> ChunkSize -> FilePath -> Key -> ([FilePath] -> IO Bool) -> IO Bool
+withCheckedFiles _ _ [] _ _ = return False
+withCheckedFiles check Nothing d k a = go $ locations d k
+ where
+ go [] = return False
+ go (f:fs) = ifM (check f) ( a [f] , go fs )
+withCheckedFiles check (Just _) d k a = go $ locations d k
+ where
+ go [] = return False
+ go (f:fs) = do
+ let chunkcount = f ++ chunkCount
+ ifM (check chunkcount)
+ ( do
+ chunks <- listChunks f <$> readFile chunkcount
+ ifM (allM check chunks)
+ ( a chunks , return False )
+ , do
+ chunks <- probeChunks f check
+ if null chunks
+ then go fs
+ else a chunks
+ )
+
+withStoredFiles :: ChunkSize -> FilePath -> Key -> ([FilePath] -> IO Bool) -> IO Bool
+withStoredFiles = withCheckedFiles doesFileExist
+
+store :: FilePath -> ChunkSize -> Key -> AssociatedFile -> MeterUpdate -> Annex Bool
+store d chunksize k _f p = sendAnnex k (void $ remove d k) $ \src ->
+ metered (Just p) k $ \meterupdate ->
+ storeHelper d chunksize k k $ \dests ->
+ case chunksize of
+ Nothing -> do
+ let dest = Prelude.head dests
+ meteredWriteFile meterupdate dest
+ =<< L.readFile src
+ return [dest]
+ Just _ ->
+ storeSplit meterupdate chunksize dests
+ =<< L.readFile src
+
+storeEncrypted :: FilePath -> [CommandParam] -> ChunkSize -> (Cipher, Key) -> Key -> MeterUpdate -> Annex Bool
+storeEncrypted d gpgOpts chunksize (cipher, enck) k p = sendAnnex k (void $ remove d enck) $ \src ->
+ metered (Just p) k $ \meterupdate ->
+ storeHelper d chunksize enck k $ \dests ->
+ encrypt gpgOpts cipher (feedFile src) $ readBytes $ \b ->
+ case chunksize of
+ Nothing -> do
+ let dest = Prelude.head dests
+ meteredWriteFile meterupdate dest b
+ return [dest]
+ Just _ -> storeSplit meterupdate chunksize dests b
+
+{- Splits a ByteString into chunks and writes to dests, obeying configured
+ - chunk size (not to be confused with the L.ByteString chunk size).
+ - Note: Must always write at least one file, even for empty ByteString. -}
+storeSplit :: MeterUpdate -> ChunkSize -> [FilePath] -> L.ByteString -> IO [FilePath]
+storeSplit _ Nothing _ _ = error "bad storeSplit call"
+storeSplit _ _ [] _ = error "bad storeSplit call"
+storeSplit meterupdate (Just chunksize) alldests@(firstdest:_) b
+ | L.null b = do
+ -- must always write at least one file, even for empty
+ L.writeFile firstdest b
+ return [firstdest]
+ | otherwise = storeSplit' meterupdate chunksize alldests (L.toChunks b) []
+storeSplit' :: MeterUpdate -> Int64 -> [FilePath] -> [S.ByteString] -> [FilePath] -> IO [FilePath]
+storeSplit' _ _ [] _ _ = error "ran out of dests"
+storeSplit' _ _ _ [] c = return $ reverse c
+storeSplit' meterupdate chunksize (d:dests) bs c = do
+ bs' <- withFile d WriteMode $
+ feed zeroBytesProcessed chunksize bs
+ storeSplit' meterupdate chunksize dests bs' (d:c)
+ where
+ feed _ _ [] _ = return []
+ feed bytes sz (l:ls) h = do
+ let len = S.length l
+ let s = fromIntegral len
+ if s <= sz || sz == chunksize
+ then do
+ S.hPut h l
+ let bytes' = addBytesProcessed bytes len
+ meterupdate bytes'
+ feed bytes' (sz - s) ls h
+ else return (l:ls)
+
+storeHelper :: FilePath -> ChunkSize -> Key -> Key -> ([FilePath] -> IO [FilePath]) -> Annex Bool
+storeHelper d chunksize key origkey storer = check <&&> go
+ where
+ tmpdir = tmpDir d key
+ destdir = storeDir d key
+ {- An encrypted key does not have a known size,
+ - so check that the size of the original key is available as free
+ - space. -}
+ check = do
+ liftIO $ createDirectoryIfMissing True tmpdir
+ checkDiskSpace (Just tmpdir) origkey 0
+ go = liftIO $ catchBoolIO $
+ storeChunks key tmpdir destdir chunksize storer recorder finalizer
+ finalizer tmp dest = do
+ void $ tryIO $ allowWrite dest -- may already exist
+ void $ tryIO $ removeDirectoryRecursive dest -- or not exist
+ createDirectoryIfMissing True (parentDir dest)
+ renameDirectory tmp dest
+ -- may fail on some filesystems
+ void $ tryIO $ do
+ mapM_ preventWrite =<< dirContents dest
+ preventWrite dest
+ recorder f s = do
+ void $ tryIO $ allowWrite f
+ writeFile f s
+ void $ tryIO $ preventWrite f
+
+retrieve :: FilePath -> ChunkSize -> Key -> AssociatedFile -> FilePath -> MeterUpdate -> Annex Bool
+retrieve d chunksize k _ f p = metered (Just p) k $ \meterupdate ->
+ liftIO $ withStoredFiles chunksize d k $ \files ->
+ catchBoolIO $ do
+ meteredWriteFileChunks meterupdate f files L.readFile
+ return True
+
+retrieveEncrypted :: FilePath -> ChunkSize -> (Cipher, Key) -> Key -> FilePath -> MeterUpdate -> Annex Bool
+retrieveEncrypted d chunksize (cipher, enck) k f p = metered (Just p) k $ \meterupdate ->
+ liftIO $ withStoredFiles chunksize d enck $ \files ->
+ catchBoolIO $ do
+ decrypt cipher (feeder files) $
+ readBytes $ meteredWriteFile meterupdate f
+ return True
+ where
+ feeder files h = forM_ files $ L.hPut h <=< L.readFile
+
+retrieveCheap :: FilePath -> ChunkSize -> Key -> FilePath -> Annex Bool
+retrieveCheap _ (Just _) _ _ = return False -- no cheap retrieval for chunks
+#ifndef mingw32_HOST_OS
+retrieveCheap d _ k f = liftIO $ withStoredFiles Nothing d k go
+ where
+ go [file] = catchBoolIO $ createSymbolicLink file f >> return True
+ go _files = return False
+#else
+retrieveCheap _ _ _ _ = return False
+#endif
+
+remove :: FilePath -> Key -> Annex Bool
+remove d k = liftIO $ do
+ void $ tryIO $ allowWrite dir
+#ifdef mingw32_HOST_OS
+ {- Windows needs the files inside the directory to be writable
+ - before it can delete them. -}
+ void $ tryIO $ mapM_ allowWrite =<< dirContents dir
+#endif
+ catchBoolIO $ do
+ removeDirectoryRecursive dir
+ return True
+ where
+ dir = storeDir d k
+
+checkPresent :: FilePath -> ChunkSize -> Key -> Annex (Either String Bool)
+checkPresent d chunksize k = liftIO $ catchMsgIO $ withStoredFiles chunksize d k $
+ const $ return True -- withStoredFiles checked that it exists
diff --git a/Remote/GCrypt.hs b/Remote/GCrypt.hs
new file mode 100644
index 000000000..e1b6811c7
--- /dev/null
+++ b/Remote/GCrypt.hs
@@ -0,0 +1,402 @@
+{- git remotes encrypted using git-remote-gcrypt
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Remote.GCrypt (
+ remote,
+ gen,
+ getGCryptUUID,
+ coreGCryptId,
+ setupRepo
+) where
+
+import qualified Data.Map as M
+import qualified Data.ByteString.Lazy as L
+import Control.Exception.Extensible
+
+import Common.Annex
+import Types.Remote
+import Types.GitConfig
+import Types.Crypto
+import qualified Git
+import qualified Git.Command
+import qualified Git.Config
+import qualified Git.GCrypt
+import qualified Git.Construct
+import qualified Git.Types as Git ()
+import qualified Annex.Branch
+import qualified Annex.Content
+import Config
+import Config.Cost
+import Remote.Helper.Git
+import Remote.Helper.Encryptable
+import Remote.Helper.Special
+import Remote.Helper.Messages
+import qualified Remote.Helper.Ssh as Ssh
+import Utility.Metered
+import Crypto
+import Annex.UUID
+import Annex.Ssh
+import qualified Remote.Rsync
+import Utility.Rsync
+import Utility.Tmp
+import Logs.Remote
+import Logs.Transfer
+import Utility.Gpg
+import Annex.Content
+
+remote :: RemoteType
+remote = RemoteType {
+ typename = "gcrypt",
+ -- Remote.Git takes care of enumerating gcrypt remotes too,
+ -- and will call our gen on them.
+ enumerate = return [],
+ generate = gen,
+ setup = gCryptSetup
+}
+
+gen :: Git.Repo -> UUID -> RemoteConfig -> RemoteGitConfig -> Annex (Maybe Remote)
+gen gcryptr u c gc = do
+ g <- gitRepo
+ -- get underlying git repo with real path, not gcrypt path
+ r <- liftIO $ Git.GCrypt.encryptedRemote g gcryptr
+ let r' = r { Git.remoteName = Git.remoteName gcryptr }
+ -- doublecheck that cache matches underlying repo's gcrypt-id
+ -- (which might not be set), only for local repos
+ (mgcryptid, r'') <- getGCryptId True r'
+ case (mgcryptid, Git.GCrypt.remoteRepoId g (Git.remoteName gcryptr)) of
+ (Just gcryptid, Just cachedgcryptid)
+ | gcryptid /= cachedgcryptid -> resetup gcryptid r''
+ _ -> gen' r'' u c gc
+ where
+ -- A different drive may have been mounted, making a different
+ -- gcrypt remote available. So need to set the cached
+ -- gcrypt-id and annex-uuid of the remote to match the remote
+ -- that is now available. Also need to set the gcrypt particiants
+ -- correctly.
+ resetup gcryptid r = do
+ let u' = genUUIDInNameSpace gCryptNameSpace gcryptid
+ v <- M.lookup u' <$> readRemoteLog
+ case (Git.remoteName gcryptr, v) of
+ (Just remotename, Just c') -> do
+ setGcryptEncryption c' remotename
+ setConfig (remoteConfig gcryptr "uuid") (fromUUID u')
+ setConfig (ConfigKey $ Git.GCrypt.remoteConfigKey "gcrypt-id" remotename) gcryptid
+ gen' r u' c' gc
+ _ -> do
+ warning $ "not using unknown gcrypt repository pointed to by remote " ++ Git.repoDescribe r
+ return Nothing
+
+gen' :: Git.Repo -> UUID -> RemoteConfig -> RemoteGitConfig -> Annex (Maybe Remote)
+gen' r u c gc = do
+ cst <- remoteCost gc $
+ if repoCheap r then nearlyCheapRemoteCost else expensiveRemoteCost
+ (rsynctransport, rsyncurl) <- rsyncTransportToObjects r
+ let rsyncopts = Remote.Rsync.genRsyncOpts c gc rsynctransport rsyncurl
+ let this = Remote
+ { uuid = u
+ , cost = cst
+ , name = Git.repoDescribe r
+ , storeKey = \_ _ _ -> noCrypto
+ , retrieveKeyFile = \_ _ _ _ -> noCrypto
+ , retrieveKeyFileCheap = \_ _ -> return False
+ , removeKey = remove this rsyncopts
+ , hasKey = checkPresent this rsyncopts
+ , hasKeyCheap = repoCheap r
+ , whereisKey = Nothing
+ , remoteFsck = Nothing
+ , repairRepo = Nothing
+ , config = c
+ , localpath = localpathCalc r
+ , repo = r
+ , gitconfig = gc { remoteGitConfig = Just $ extractGitConfig r }
+ , readonly = Git.repoIsHttp r
+ , globallyAvailable = globallyAvailableCalc r
+ , remotetype = remote
+ }
+ return $ Just $ encryptableRemote c
+ (store this rsyncopts)
+ (retrieve this rsyncopts)
+ this
+
+rsyncTransportToObjects :: Git.Repo -> Annex ([CommandParam], String)
+rsyncTransportToObjects r = do
+ (rsynctransport, rsyncurl, _) <- rsyncTransport r
+ return (rsynctransport, rsyncurl ++ "/annex/objects")
+
+rsyncTransport :: Git.Repo -> Annex ([CommandParam], String, AccessMethod)
+rsyncTransport r
+ | "ssh://" `isPrefixOf` loc = sshtransport $ break (== '/') $ drop (length "ssh://") loc
+ | "//:" `isInfixOf` loc = othertransport
+ | ":" `isInfixOf` loc = sshtransport $ separate (== ':') loc
+ | otherwise = othertransport
+ where
+ loc = Git.repoLocation r
+ sshtransport (host, path) = do
+ let rsyncpath = if "/~/" `isPrefixOf` path
+ then drop 3 path
+ else path
+ opts <- sshCachingOptions (host, Nothing) []
+ return (rsyncShell $ Param "ssh" : opts, host ++ ":" ++ rsyncpath, AccessShell)
+ othertransport = return ([], loc, AccessDirect)
+
+noCrypto :: Annex a
+noCrypto = error "cannot use gcrypt remote without encryption enabled"
+
+unsupportedUrl :: Annex a
+unsupportedUrl = error "using non-ssh remote repo url with gcrypt is not supported"
+
+gCryptSetup :: Maybe UUID -> RemoteConfig -> Annex (RemoteConfig, UUID)
+gCryptSetup mu c = go $ M.lookup "gitrepo" c
+ where
+ remotename = fromJust (M.lookup "name" c)
+ go Nothing = error "Specify gitrepo="
+ go (Just gitrepo) = do
+ c' <- encryptionSetup c
+ inRepo $ Git.Command.run
+ [ Params "remote add"
+ , Param remotename
+ , Param $ Git.GCrypt.urlPrefix ++ gitrepo
+ ]
+
+ setGcryptEncryption c' remotename
+
+ {- Run a git fetch and a push to the git repo in order to get
+ - its gcrypt-id set up, so that later git annex commands
+ - will use the remote as a gcrypt remote. The fetch is
+ - needed if the repo already exists; the push is needed
+ - if the repo has not yet been initialized by gcrypt. -}
+ void $ inRepo $ Git.Command.runBool
+ [ Param "fetch"
+ , Param remotename
+ ]
+ void $ inRepo $ Git.Command.runBool
+ [ Param "push"
+ , Param remotename
+ , Param $ show Annex.Branch.fullname
+ ]
+ g <- inRepo Git.Config.reRead
+ case Git.GCrypt.remoteRepoId g (Just remotename) of
+ Nothing -> error "unable to determine gcrypt-id of remote"
+ Just gcryptid -> do
+ let u = genUUIDInNameSpace gCryptNameSpace gcryptid
+ if Just u == mu || isNothing mu
+ then do
+ method <- setupRepo gcryptid =<< inRepo (Git.Construct.fromRemoteLocation gitrepo)
+ gitConfigSpecialRemote u c' "gcrypt" (fromAccessMethod method)
+ return (c', u)
+ else error $ "uuid mismatch " ++ show (u, mu, gcryptid)
+
+{- Sets up the gcrypt repository. The repository is either a local
+ - repo, or it is accessed via rsync directly, or it is accessed over ssh
+ - and git-annex-shell is available to manage it.
+ -
+ - The GCryptID is recorded in the repository's git config for later use.
+ - Also, if the git config has receive.denyNonFastForwards set, disable
+ - it; gcrypt relies on being able to fast-forward branches.
+ -}
+setupRepo :: Git.GCrypt.GCryptId -> Git.Repo -> Annex AccessMethod
+setupRepo gcryptid r
+ | Git.repoIsUrl r = do
+ (_, _, accessmethod) <- rsyncTransport r
+ case accessmethod of
+ AccessDirect -> rsyncsetup
+ AccessShell -> ifM gitannexshellsetup
+ ( return AccessShell
+ , rsyncsetup
+ )
+ | Git.repoIsLocalUnknown r = localsetup =<< liftIO (Git.Config.read r)
+ | otherwise = localsetup r
+ where
+ localsetup r' = do
+ let setconfig k v = liftIO $ Git.Command.run [Param "config", Param k, Param v] r'
+ setconfig coreGCryptId gcryptid
+ setconfig denyNonFastForwards (Git.Config.boolConfig False)
+ return AccessDirect
+
+ {- As well as modifying the remote's git config,
+ - create the objectDir on the remote,
+ - which is needed for direct rsync of objects to work.
+ -}
+ rsyncsetup = Remote.Rsync.withRsyncScratchDir $ \tmp -> do
+ liftIO $ createDirectoryIfMissing True $ tmp </> objectDir
+ (rsynctransport, rsyncurl, _) <- rsyncTransport r
+ let tmpconfig = tmp </> "config"
+ void $ liftIO $ rsync $ rsynctransport ++
+ [ Param $ rsyncurl ++ "/config"
+ , Param tmpconfig
+ ]
+ liftIO $ do
+ void $ Git.Config.changeFile tmpconfig coreGCryptId gcryptid
+ void $ Git.Config.changeFile tmpconfig denyNonFastForwards (Git.Config.boolConfig False)
+ ok <- liftIO $ rsync $ rsynctransport ++
+ [ Params "--recursive"
+ , Param $ tmp ++ "/"
+ , Param rsyncurl
+ ]
+ unless ok $
+ error "Failed to connect to remote to set it up."
+ return AccessDirect
+
+ {- Ask git-annex-shell to configure the repository as a gcrypt
+ - repository. May fail if it is too old. -}
+ gitannexshellsetup = Ssh.onRemote r (boolSystem, False)
+ "gcryptsetup" [ Param gcryptid ] []
+
+ denyNonFastForwards = "receive.denyNonFastForwards"
+
+shellOrRsync :: Remote -> Annex a -> Annex a -> Annex a
+shellOrRsync r ashell arsync = case method of
+ AccessShell -> ashell
+ _ -> arsync
+ where
+ method = toAccessMethod $ fromMaybe "" $
+ remoteAnnexGCrypt $ gitconfig r
+
+{- Configure gcrypt to use the same list of keyids that
+ - were passed to initremote as its participants.
+ - Also, configure it to use a signing key that is in the list of
+ - participants, which gcrypt requires is the case, and may not be
+ - depending on system configuration.
+ -
+ - (For shared encryption, gcrypt's default behavior is used.) -}
+setGcryptEncryption :: RemoteConfig -> String -> Annex ()
+setGcryptEncryption c remotename = do
+ let participants = ConfigKey $ Git.GCrypt.remoteParticipantConfigKey remotename
+ case extractCipher c of
+ Nothing -> noCrypto
+ Just (EncryptedCipher _ _ (KeyIds { keyIds = ks})) -> do
+ setConfig participants (unwords ks)
+ let signingkey = ConfigKey $ Git.GCrypt.remoteSigningKey remotename
+ skeys <- M.keys <$> liftIO secretKeys
+ case filter (`elem` ks) skeys of
+ [] -> noop
+ (k:_) -> setConfig signingkey k
+ Just (SharedCipher _) ->
+ unsetConfig participants
+
+store :: Remote -> Remote.Rsync.RsyncOpts -> (Cipher, Key) -> Key -> MeterUpdate -> Annex Bool
+store r rsyncopts (cipher, enck) k p
+ | not $ Git.repoIsUrl (repo r) = guardUsable (repo r) False $
+ metered (Just p) k $ \meterupdate -> spoolencrypted $ \h -> do
+ let dest = gCryptLocation r enck
+ createDirectoryIfMissing True $ parentDir dest
+ readBytes (meteredWriteFile meterupdate dest) h
+ return True
+ | Git.repoIsSsh (repo r) = shellOrRsync r storeshell storersync
+ | otherwise = unsupportedUrl
+ where
+ gpgopts = getGpgEncParams r
+ storersync = Remote.Rsync.storeEncrypted rsyncopts gpgopts (cipher, enck) k p
+ storeshell = withTmp enck $ \tmp ->
+ ifM (spoolencrypted $ readBytes $ \b -> catchBoolIO $ L.writeFile tmp b >> return True)
+ ( Ssh.rsyncHelper (Just p)
+ =<< Ssh.rsyncParamsRemote False r Upload enck tmp Nothing
+ , return False
+ )
+ spoolencrypted a = Annex.Content.sendAnnex k noop $ \src ->
+ liftIO $ catchBoolIO $
+ encrypt gpgopts cipher (feedFile src) a
+
+retrieve :: Remote -> Remote.Rsync.RsyncOpts -> (Cipher, Key) -> Key -> FilePath -> MeterUpdate -> Annex Bool
+retrieve r rsyncopts (cipher, enck) k d p
+ | not $ Git.repoIsUrl (repo r) = guardUsable (repo r) False $ do
+ retrievewith $ L.readFile src
+ return True
+ | Git.repoIsSsh (repo r) = shellOrRsync r retrieveshell retrieversync
+ | otherwise = unsupportedUrl
+ where
+ src = gCryptLocation r enck
+ retrievewith a = metered (Just p) k $ \meterupdate -> liftIO $
+ a >>= \b ->
+ decrypt cipher (feedBytes b)
+ (readBytes $ meteredWriteFile meterupdate d)
+ retrieversync = Remote.Rsync.retrieveEncrypted rsyncopts (cipher, enck) k d p
+ retrieveshell = withTmp enck $ \tmp ->
+ ifM (Ssh.rsyncHelper (Just p) =<< Ssh.rsyncParamsRemote False r Download enck tmp Nothing)
+ ( liftIO $ catchBoolIO $ do
+ decrypt cipher (feedFile tmp) $
+ readBytes $ L.writeFile d
+ return True
+ , return False
+ )
+
+remove :: Remote -> Remote.Rsync.RsyncOpts -> Key -> Annex Bool
+remove r rsyncopts k
+ | not $ Git.repoIsUrl (repo r) = guardUsable (repo r) False $ do
+ liftIO $ removeDirectoryRecursive $ parentDir $ gCryptLocation r k
+ return True
+ | Git.repoIsSsh (repo r) = shellOrRsync r removeshell removersync
+ | otherwise = unsupportedUrl
+ where
+ removersync = Remote.Rsync.remove rsyncopts k
+ removeshell = Ssh.dropKey (repo r) k
+
+checkPresent :: Remote -> Remote.Rsync.RsyncOpts -> Key -> Annex (Either String Bool)
+checkPresent r rsyncopts k
+ | not $ Git.repoIsUrl (repo r) =
+ guardUsable (repo r) (cantCheck $ repo r) $
+ liftIO $ catchDefaultIO (cantCheck $ repo r) $
+ Right <$> doesFileExist (gCryptLocation r k)
+ | Git.repoIsSsh (repo r) = shellOrRsync r checkshell checkrsync
+ | otherwise = unsupportedUrl
+ where
+ checkrsync = Remote.Rsync.checkPresent (repo r) rsyncopts k
+ checkshell = Ssh.inAnnex (repo r) k
+
+{- Annexed objects are hashed using lower-case directories for max
+ - portability. -}
+gCryptLocation :: Remote -> Key -> FilePath
+gCryptLocation r key = Git.repoLocation (repo r) </> objectDir </> keyPath key hashDirLower
+
+data AccessMethod = AccessDirect | AccessShell
+
+fromAccessMethod :: AccessMethod -> String
+fromAccessMethod AccessShell = "shell"
+fromAccessMethod AccessDirect = "true"
+
+toAccessMethod :: String -> AccessMethod
+toAccessMethod "shell" = AccessShell
+toAccessMethod _ = AccessDirect
+
+getGCryptUUID :: Bool -> Git.Repo -> Annex (Maybe UUID)
+getGCryptUUID fast r = (genUUIDInNameSpace gCryptNameSpace <$>) . fst
+ <$> getGCryptId fast r
+
+coreGCryptId :: String
+coreGCryptId = "core.gcrypt-id"
+
+{- gcrypt repos set up by git-annex as special remotes have a
+ - core.gcrypt-id setting in their config, which can be mapped back to
+ - the remote's UUID.
+ -
+ - In fast mode, only checks local repos. To check a remote repo,
+ - tries git-annex-shell and direct rsync of the git config file.
+ -
+ - (Also returns a version of input repo with its config read.) -}
+getGCryptId :: Bool -> Git.Repo -> Annex (Maybe Git.GCrypt.GCryptId, Git.Repo)
+getGCryptId fast r
+ | Git.repoIsLocal r || Git.repoIsLocalUnknown r = extract <$>
+ liftIO (catchMaybeIO $ Git.Config.read r)
+ | not fast = extract . liftM fst <$> getM (eitherToMaybe <$>)
+ [ Ssh.onRemote r (Git.Config.fromPipe r, Left undefined) "configlist" [] []
+ , getConfigViaRsync r
+ ]
+ | otherwise = return (Nothing, r)
+ where
+ extract Nothing = (Nothing, r)
+ extract (Just r') = (Git.Config.getMaybe coreGCryptId r', r')
+
+getConfigViaRsync :: Git.Repo -> Annex (Either SomeException (Git.Repo, String))
+getConfigViaRsync r = do
+ (rsynctransport, rsyncurl, _) <- rsyncTransport r
+ liftIO $ do
+ withTmpFile "tmpconfig" $ \tmpconfig _ -> do
+ void $ rsync $ rsynctransport ++
+ [ Param $ rsyncurl ++ "/config"
+ , Param tmpconfig
+ ]
+ Git.Config.fromFile r tmpconfig
diff --git a/Remote/Git.hs b/Remote/Git.hs
new file mode 100644
index 000000000..d4e5987dc
--- /dev/null
+++ b/Remote/Git.hs
@@ -0,0 +1,489 @@
+{- Standard git remotes.
+ -
+ - Copyright 2011-2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Remote.Git (
+ remote,
+ configRead,
+ repoAvail,
+) where
+
+import Common.Annex
+import Annex.Ssh
+import Types.Remote
+import Types.GitConfig
+import qualified Git
+import qualified Git.Config
+import qualified Git.Construct
+import qualified Git.Command
+import qualified Git.GCrypt
+import qualified Annex
+import Logs.Presence
+import Logs.Transfer
+import Annex.UUID
+import Annex.Exception
+import qualified Annex.Content
+import qualified Annex.BranchState
+import qualified Annex.Branch
+import qualified Annex.Url as Url
+import Utility.Tmp
+import Config
+import Config.Cost
+import Init
+import Types.Key
+import qualified Fields
+import Logs.Location
+import Utility.Metered
+#ifndef mingw32_HOST_OS
+import Utility.CopyFile
+#endif
+import Utility.Env
+import Utility.Batch
+import Remote.Helper.Git
+import Remote.Helper.Messages
+import qualified Remote.Helper.Ssh as Ssh
+import qualified Remote.GCrypt
+import Config.Files
+
+import Control.Concurrent
+import Control.Concurrent.MSampleVar
+import System.Process (std_in, std_err)
+import qualified Data.Map as M
+import Control.Exception.Extensible
+
+remote :: RemoteType
+remote = RemoteType {
+ typename = "git",
+ enumerate = list,
+ generate = gen,
+ setup = error "not supported"
+}
+
+list :: Annex [Git.Repo]
+list = do
+ c <- fromRepo Git.config
+ rs <- mapM (tweakurl c) =<< fromRepo Git.remotes
+ mapM configRead rs
+ where
+ annexurl n = "remote." ++ n ++ ".annexurl"
+ tweakurl c r = do
+ let n = fromJust $ Git.remoteName r
+ case M.lookup (annexurl n) c of
+ Nothing -> return r
+ Just url -> inRepo $ \g ->
+ Git.Construct.remoteNamed n $
+ Git.Construct.fromRemoteLocation url g
+
+{- It's assumed to be cheap to read the config of non-URL remotes, so this is
+ - done each time git-annex is run in a way that uses remotes.
+ -
+ - Conversely, the config of an URL remote is only read when there is no
+ - cached UUID value. -}
+configRead :: Git.Repo -> Annex Git.Repo
+configRead r = do
+ g <- fromRepo id
+ let c = extractRemoteGitConfig g (Git.repoDescribe r)
+ u <- getRepoUUID r
+ case (repoCheap r, remoteAnnexIgnore c, u) of
+ (_, True, _) -> return r
+ (True, _, _) -> tryGitConfigRead r
+ (False, _, NoUUID) -> tryGitConfigRead r
+ _ -> return r
+
+gen :: Git.Repo -> UUID -> RemoteConfig -> RemoteGitConfig -> Annex (Maybe Remote)
+gen r u c gc
+ | Git.GCrypt.isEncrypted r = Remote.GCrypt.gen r u c gc
+ | otherwise = go <$> remoteCost gc defcst
+ where
+ defcst = if repoCheap r then cheapRemoteCost else expensiveRemoteCost
+ go cst = Just new
+ where
+ new = Remote
+ { uuid = u
+ , cost = cst
+ , name = Git.repoDescribe r
+ , storeKey = copyToRemote new
+ , retrieveKeyFile = copyFromRemote new
+ , retrieveKeyFileCheap = copyFromRemoteCheap new
+ , removeKey = dropKey new
+ , hasKey = inAnnex r
+ , hasKeyCheap = repoCheap r
+ , whereisKey = Nothing
+ , remoteFsck = if Git.repoIsUrl r
+ then Nothing
+ else Just $ fsckOnRemote r
+ , repairRepo = if Git.repoIsUrl r
+ then Nothing
+ else Just $ repairRemote r
+ , config = c
+ , localpath = localpathCalc r
+ , repo = r
+ , gitconfig = gc
+ { remoteGitConfig = Just $ extractGitConfig r }
+ , readonly = Git.repoIsHttp r
+ , globallyAvailable = globallyAvailableCalc r
+ , remotetype = remote
+ }
+
+{- Checks relatively inexpensively if a repository is available for use. -}
+repoAvail :: Git.Repo -> Annex Bool
+repoAvail r
+ | Git.repoIsHttp r = return True
+ | Git.GCrypt.isEncrypted r = do
+ g <- gitRepo
+ liftIO $ do
+ er <- Git.GCrypt.encryptedRemote g r
+ if Git.repoIsLocal er || Git.repoIsLocalUnknown er
+ then catchBoolIO $
+ void (Git.Config.read er) >> return True
+ else return True
+ | Git.repoIsUrl r = return True
+ | Git.repoIsLocalUnknown r = return False
+ | otherwise = liftIO $ catchBoolIO $ onLocal r $ return True
+
+{- Tries to read the config for a specified remote, updates state, and
+ - returns the updated repo. -}
+tryGitConfigRead :: Git.Repo -> Annex Git.Repo
+tryGitConfigRead r
+ | haveconfig r = return r -- already read
+ | Git.repoIsSsh r = store $ do
+ v <- Ssh.onRemote r (pipedconfig, Left undefined) "configlist" [] []
+ case v of
+ Right r'
+ | haveconfig r' -> return r'
+ | otherwise -> configlist_failed
+ Left _ -> configlist_failed
+ | Git.repoIsHttp r = do
+ headers <- getHttpHeaders
+ store $ geturlconfig headers
+ | Git.GCrypt.isEncrypted r = handlegcrypt =<< getConfigMaybe (remoteConfig r "uuid")
+ | Git.repoIsUrl r = return r
+ | otherwise = store $ safely $ onLocal r $ do
+ ensureInitialized
+ Annex.getState Annex.repo
+ where
+ haveconfig = not . M.null . Git.config
+
+ -- Reading config can fail due to IO error or
+ -- for other reasons; catch all possible exceptions.
+ safely a = either (const $ return r) return
+ =<< liftIO (try a :: IO (Either SomeException Git.Repo))
+
+ pipedconfig cmd params = do
+ v <- Git.Config.fromPipe r cmd params
+ case v of
+ Right (r', val) -> do
+ when (getUncachedUUID r' == NoUUID && not (null val)) $ do
+ warningIO $ "Failed to get annex.uuid configuration of repository " ++ Git.repoDescribe r
+ warningIO $ "Instead, got: " ++ show val
+ warningIO $ "This is unexpected; please check the network transport!"
+ return $ Right r'
+ Left l -> return $ Left l
+
+ geturlconfig headers = do
+ ua <- Url.getUserAgent
+ v <- liftIO $ withTmpFile "git-annex.tmp" $ \tmpfile h -> do
+ hClose h
+ ifM (Url.downloadQuiet (Git.repoLocation r ++ "/config") headers [] tmpfile ua)
+ ( pipedconfig "git" [Param "config", Param "--null", Param "--list", Param "--file", File tmpfile]
+ , return $ Left undefined
+ )
+ case v of
+ Left _ -> do
+ set_ignore "not usable by git-annex"
+ return r
+ Right r' -> return r'
+
+ store = observe $ \r' -> do
+ g <- gitRepo
+ let l = Git.remotes g
+ let g' = g { Git.remotes = exchange l r' }
+ Annex.changeState $ \s -> s { Annex.repo = g' }
+
+ exchange [] _ = []
+ exchange (old:ls) new
+ | Git.remoteName old == Git.remoteName new =
+ new : exchange ls new
+ | otherwise =
+ old : exchange ls new
+
+ {- Is this remote just not available, or does
+ - it not have git-annex-shell?
+ - Find out by trying to fetch from the remote. -}
+ configlist_failed = case Git.remoteName r of
+ Nothing -> return r
+ Just n -> do
+ whenM (inRepo $ Git.Command.runBool [Param "fetch", Param "--quiet", Param n]) $
+ set_ignore "does not have git-annex installed"
+ return r
+
+ set_ignore msg = case Git.remoteName r of
+ Nothing -> noop
+ Just n -> do
+ let k = "remote." ++ n ++ ".annex-ignore"
+ warning $ "Remote " ++ n ++ " " ++ msg ++ "; setting " ++ k
+ inRepo $ Git.Command.run [Param "config", Param k, Param "true"]
+
+ handlegcrypt Nothing = return r
+ handlegcrypt (Just _cacheduuid) = do
+ -- Generate UUID from the gcrypt-id
+ g <- gitRepo
+ case Git.GCrypt.remoteRepoId g (Git.remoteName r) of
+ Nothing -> return r
+ Just v -> store $ liftIO $ setUUID r $
+ genUUIDInNameSpace gCryptNameSpace v
+
+{- Checks if a given remote has the content for a key inAnnex.
+ - If the remote cannot be accessed, or if it cannot determine
+ - whether it has the content, returns a Left error message.
+ -}
+inAnnex :: Git.Repo -> Key -> Annex (Either String Bool)
+inAnnex r key
+ | Git.repoIsHttp r = checkhttp =<< getHttpHeaders
+ | Git.repoIsUrl r = checkremote
+ | otherwise = checklocal
+ where
+ checkhttp headers = do
+ showChecking r
+ ifM (anyM (\u -> Url.withUserAgent $ Url.checkBoth u headers (keySize key)) (keyUrls r key))
+ ( return $ Right True
+ , return $ Left "not found"
+ )
+ checkremote = Ssh.inAnnex r key
+ checklocal = guardUsable r (cantCheck r) $ dispatch <$> check
+ where
+ check = liftIO $ catchMsgIO $ onLocal r $
+ Annex.Content.inAnnexSafe key
+ dispatch (Left e) = Left e
+ dispatch (Right (Just b)) = Right b
+ dispatch (Right Nothing) = cantCheck r
+
+keyUrls :: Git.Repo -> Key -> [String]
+keyUrls r key = map tourl locs
+ where
+ tourl l = Git.repoLocation r ++ "/" ++ l
+#ifndef mingw32_HOST_OS
+ locs = annexLocations key
+#else
+ locs = map (replace "\\" "/") (annexLocations key)
+#endif
+
+dropKey :: Remote -> Key -> Annex Bool
+dropKey r key
+ | not $ Git.repoIsUrl (repo r) =
+ guardUsable (repo r) False $ commitOnCleanup r $ liftIO $ onLocal (repo r) $ do
+ ensureInitialized
+ whenM (Annex.Content.inAnnex key) $ do
+ Annex.Content.lockContent key $
+ Annex.Content.removeAnnex key
+ logStatus key InfoMissing
+ Annex.Content.saveState True
+ return True
+ | Git.repoIsHttp (repo r) = error "dropping from http remote not supported"
+ | otherwise = commitOnCleanup r $ Ssh.dropKey (repo r) key
+
+{- Tries to copy a key's content from a remote's annex to a file. -}
+copyFromRemote :: Remote -> Key -> AssociatedFile -> FilePath -> MeterUpdate -> Annex Bool
+copyFromRemote r key file dest _p = copyFromRemote' r key file dest
+copyFromRemote' :: Remote -> Key -> AssociatedFile -> FilePath -> Annex Bool
+copyFromRemote' r key file dest
+ | not $ Git.repoIsUrl (repo r) = guardUsable (repo r) False $ do
+ let params = Ssh.rsyncParams r
+ u <- getUUID
+ -- run copy from perspective of remote
+ liftIO $ onLocal (repo r) $ do
+ ensureInitialized
+ v <- Annex.Content.prepSendAnnex key
+ case v of
+ Nothing -> return False
+ Just (object, checksuccess) ->
+ upload u key file noRetry
+ (rsyncOrCopyFile params object dest)
+ <&&> checksuccess
+ | Git.repoIsSsh (repo r) = feedprogressback $ \feeder -> do
+ direct <- isDirect
+ Ssh.rsyncHelper (Just feeder)
+ =<< Ssh.rsyncParamsRemote direct r Download key dest file
+ | Git.repoIsHttp (repo r) = Annex.Content.downloadUrl (keyUrls (repo r) key) dest
+ | otherwise = error "copying from non-ssh, non-http remote not supported"
+ where
+ {- Feed local rsync's progress info back to the remote,
+ - by forking a feeder thread that runs
+ - git-annex-shell transferinfo at the same time
+ - git-annex-shell sendkey is running.
+ -
+ - To avoid extra password prompts, this is only done when ssh
+ - connection caching is supported.
+ - Note that it actually waits for rsync to indicate
+ - progress before starting transferinfo, in order
+ - to ensure ssh connection caching works and reuses
+ - the connection set up for the sendkey.
+ -
+ - Also note that older git-annex-shell does not support
+ - transferinfo, so stderr is dropped and failure ignored.
+ -}
+ feedprogressback a = ifM (isJust <$> sshCacheDir)
+ ( feedprogressback' a
+ , a $ const noop
+ )
+ feedprogressback' a = do
+ u <- getUUID
+ let fields = (Fields.remoteUUID, fromUUID u)
+ : maybe [] (\f -> [(Fields.associatedFile, f)]) file
+ Just (cmd, params) <- Ssh.git_annex_shell (repo r) "transferinfo"
+ [Param $ key2file key] fields
+ v <- liftIO (newEmptySV :: IO (MSampleVar Integer))
+ tid <- liftIO $ forkIO $ void $ tryIO $ do
+ bytes <- readSV v
+ p <- createProcess $
+ (proc cmd (toCommand params))
+ { std_in = CreatePipe
+ , std_err = CreatePipe
+ }
+ hClose $ stderrHandle p
+ let h = stdinHandle p
+ let send b = do
+ hPrint h b
+ hFlush h
+ send bytes
+ forever $
+ send =<< readSV v
+ let feeder = writeSV v . fromBytesProcessed
+ bracketIO noop (const $ tryIO $ killThread tid) (const $ a feeder)
+
+copyFromRemoteCheap :: Remote -> Key -> FilePath -> Annex Bool
+#ifndef mingw32_HOST_OS
+copyFromRemoteCheap r key file
+ | not $ Git.repoIsUrl (repo r) = guardUsable (repo r) False $ do
+ loc <- liftIO $ gitAnnexLocation key (repo r) $
+ fromJust $ remoteGitConfig $ gitconfig r
+ liftIO $ catchBoolIO $ createSymbolicLink loc file >> return True
+ | Git.repoIsSsh (repo r) =
+ ifM (Annex.Content.preseedTmp key file)
+ ( copyFromRemote' r key Nothing file
+ , return False
+ )
+ | otherwise = return False
+#else
+copyFromRemoteCheap _ _ _ = return False
+#endif
+
+{- Tries to copy a key's content to a remote's annex. -}
+copyToRemote :: Remote -> Key -> AssociatedFile -> MeterUpdate -> Annex Bool
+copyToRemote r key file p
+ | not $ Git.repoIsUrl (repo r) =
+ guardUsable (repo r) False $ commitOnCleanup r $
+ copylocal =<< Annex.Content.prepSendAnnex key
+ | Git.repoIsSsh (repo r) = commitOnCleanup r $
+ Annex.Content.sendAnnex key noop $ \object -> do
+ direct <- isDirect
+ Ssh.rsyncHelper (Just p)
+ =<< Ssh.rsyncParamsRemote direct r Upload key object file
+ | otherwise = error "copying to non-ssh repo not supported"
+ where
+ copylocal Nothing = return False
+ copylocal (Just (object, checksuccess)) = do
+ -- The checksuccess action is going to be run in
+ -- the remote's Annex, but it needs access to the current
+ -- Annex monad's state.
+ checksuccessio <- Annex.withCurrentState checksuccess
+ let params = Ssh.rsyncParams r
+ u <- getUUID
+ -- run copy from perspective of remote
+ liftIO $ onLocal (repo r) $ ifM (Annex.Content.inAnnex key)
+ ( return True
+ , do
+ ensureInitialized
+ download u key file noRetry $ const $
+ Annex.Content.saveState True `after`
+ Annex.Content.getViaTmpChecked (liftIO checksuccessio) key
+ (\d -> rsyncOrCopyFile params object d p)
+ )
+
+fsckOnRemote :: Git.Repo -> [CommandParam] -> Annex (IO Bool)
+fsckOnRemote r params
+ | Git.repoIsUrl r = do
+ s <- Ssh.git_annex_shell r "fsck" params []
+ return $ case s of
+ Nothing -> return False
+ Just (c, ps) -> batchCommand c ps
+ | otherwise = return $ do
+ program <- readProgramFile
+ env <- getEnvironment
+ r' <- Git.Config.read r
+ let env' =
+ [ ("GIT_WORK_TREE", Git.repoPath r')
+ , ("GIT_DIR", Git.localGitDir r')
+ ] ++ env
+ batchCommandEnv program (Param "fsck" : params) (Just env')
+
+{- The passed repair action is run in the Annex monad of the remote. -}
+repairRemote :: Git.Repo -> Annex Bool -> Annex (IO Bool)
+repairRemote r a = return $ Remote.Git.onLocal r a
+
+{- Runs an action on a local repository inexpensively, by making an annex
+ - monad using that repository. -}
+onLocal :: Git.Repo -> Annex a -> IO a
+onLocal r a = do
+ s <- Annex.new r
+ Annex.eval s $ do
+ -- No need to update the branch; its data is not used
+ -- for anything onLocal is used to do.
+ Annex.BranchState.disableUpdate
+ a
+
+{- Copys a file with rsync unless both locations are on the same
+ - filesystem. Then cp could be faster. -}
+rsyncOrCopyFile :: [CommandParam] -> FilePath -> FilePath -> MeterUpdate -> Annex Bool
+rsyncOrCopyFile rsyncparams src dest p =
+#ifdef mingw32_HOST_OS
+ dorsync
+ where
+#else
+ ifM (sameDeviceIds src dest) (docopy, dorsync)
+ where
+ sameDeviceIds a b = (==) <$> getDeviceId a <*> getDeviceId b
+ getDeviceId f = deviceID <$> liftIO (getFileStatus $ parentDir f)
+ docopy = liftIO $ bracket
+ (forkIO $ watchfilesize zeroBytesProcessed)
+ (void . tryIO . killThread)
+ (const $ copyFileExternal src dest)
+ watchfilesize oldsz = do
+ threadDelay 500000 -- 0.5 seconds
+ v <- catchMaybeIO $
+ toBytesProcessed . fileSize
+ <$> getFileStatus dest
+ case v of
+ Just sz
+ | sz /= oldsz -> do
+ p sz
+ watchfilesize sz
+ _ -> watchfilesize oldsz
+#endif
+ dorsync = Ssh.rsyncHelper (Just p) $
+ rsyncparams ++ [File src, File dest]
+
+commitOnCleanup :: Remote -> Annex a -> Annex a
+commitOnCleanup r a = go `after` a
+ where
+ go = Annex.addCleanup (Git.repoLocation $ repo r) cleanup
+ cleanup
+ | not $ Git.repoIsUrl (repo r) = liftIO $ onLocal (repo r) $
+ doQuietSideAction $
+ Annex.Branch.commit "update"
+ | otherwise = void $ do
+ Just (shellcmd, shellparams) <-
+ Ssh.git_annex_shell (repo r) "commit" [] []
+
+ -- Throw away stderr, since the remote may not
+ -- have a new enough git-annex shell to
+ -- support committing.
+ liftIO $ catchMaybeIO $
+ withQuietOutput createProcessSuccess $
+ proc shellcmd $
+ toCommand shellparams
diff --git a/Remote/Glacier.hs b/Remote/Glacier.hs
new file mode 100644
index 000000000..300e682a7
--- /dev/null
+++ b/Remote/Glacier.hs
@@ -0,0 +1,302 @@
+{- Amazon Glacier remotes.
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Remote.Glacier (remote, jobList) where
+
+import qualified Data.Map as M
+import qualified Data.Text as T
+import System.Environment
+
+import Common.Annex
+import Types.Remote
+import Types.Key
+import qualified Git
+import Config
+import Config.Cost
+import Remote.Helper.Special
+import Remote.Helper.Encryptable
+import qualified Remote.Helper.AWS as AWS
+import Crypto
+import Creds
+import Utility.Metered
+import qualified Annex
+import Annex.Content
+import Annex.UUID
+
+import System.Process
+
+type Vault = String
+type Archive = FilePath
+
+remote :: RemoteType
+remote = RemoteType {
+ typename = "glacier",
+ enumerate = findSpecialRemotes "glacier",
+ generate = gen,
+ setup = glacierSetup
+}
+
+gen :: Git.Repo -> UUID -> RemoteConfig -> RemoteGitConfig -> Annex (Maybe Remote)
+gen r u c gc = new <$> remoteCost gc veryExpensiveRemoteCost
+ where
+ new cst = Just $ encryptableRemote c
+ (storeEncrypted this)
+ (retrieveEncrypted this)
+ this
+ where
+ this = Remote {
+ uuid = u,
+ cost = cst,
+ name = Git.repoDescribe r,
+ storeKey = store this,
+ retrieveKeyFile = retrieve this,
+ retrieveKeyFileCheap = retrieveCheap this,
+ removeKey = remove this,
+ hasKey = checkPresent this,
+ hasKeyCheap = False,
+ whereisKey = Nothing,
+ remoteFsck = Nothing,
+ repairRepo = Nothing,
+ config = c,
+ repo = r,
+ gitconfig = gc,
+ localpath = Nothing,
+ readonly = False,
+ globallyAvailable = True,
+ remotetype = remote
+ }
+
+glacierSetup :: Maybe UUID -> RemoteConfig -> Annex (RemoteConfig, UUID)
+glacierSetup mu c = do
+ u <- maybe (liftIO genUUID) return mu
+ glacierSetup' u c
+glacierSetup' :: UUID -> RemoteConfig -> Annex (RemoteConfig, UUID)
+glacierSetup' u c = do
+ c' <- encryptionSetup c
+ let fullconfig = c' `M.union` defaults
+ genVault fullconfig u
+ gitConfigSpecialRemote u fullconfig "glacier" "true"
+ c'' <- setRemoteCredPair fullconfig (AWS.creds u)
+ return (c'', u)
+ where
+ remotename = fromJust (M.lookup "name" c)
+ defvault = remotename ++ "-" ++ fromUUID u
+ defaults = M.fromList
+ [ ("datacenter", T.unpack $ AWS.defaultRegion AWS.Glacier)
+ , ("vault", defvault)
+ ]
+
+store :: Remote -> Key -> AssociatedFile -> MeterUpdate -> Annex Bool
+store r k _f p
+ | keySize k == Just 0 = do
+ warning "Cannot store empty files in Glacier."
+ return False
+ | otherwise = sendAnnex k (void $ remove r k) $ \src ->
+ metered (Just p) k $ \meterupdate ->
+ storeHelper r k $ streamMeteredFile src meterupdate
+
+storeEncrypted :: Remote -> (Cipher, Key) -> Key -> MeterUpdate -> Annex Bool
+storeEncrypted r (cipher, enck) k p = sendAnnex k (void $ remove r enck) $ \src ->
+ metered (Just p) k $ \meterupdate ->
+ storeHelper r enck $ \h ->
+ encrypt (getGpgEncParams r) cipher (feedFile src)
+ (readBytes $ meteredWrite meterupdate h)
+
+retrieve :: Remote -> Key -> AssociatedFile -> FilePath -> MeterUpdate -> Annex Bool
+retrieve r k _f d p = metered (Just p) k $ \meterupdate ->
+ retrieveHelper r k $
+ readBytes $ meteredWriteFile meterupdate d
+
+retrieveCheap :: Remote -> Key -> FilePath -> Annex Bool
+retrieveCheap _ _ _ = return False
+
+retrieveEncrypted :: Remote -> (Cipher, Key) -> Key -> FilePath -> MeterUpdate -> Annex Bool
+retrieveEncrypted r (cipher, enck) k d p = metered (Just p) k $ \meterupdate ->
+ retrieveHelper r enck $ readBytes $ \b ->
+ decrypt cipher (feedBytes b) $
+ readBytes $ meteredWriteFile meterupdate d
+
+storeHelper :: Remote -> Key -> (Handle -> IO ()) -> Annex Bool
+storeHelper r k feeder = go =<< glacierEnv c u
+ where
+ c = config r
+ u = uuid r
+ params = glacierParams c
+ [ Param "archive"
+ , Param "upload"
+ , Param "--name", Param $ archive r k
+ , Param $ getVault $ config r
+ , Param "-"
+ ]
+ go Nothing = return False
+ go (Just e) = do
+ let p = (proc "glacier" (toCommand params)) { env = Just e }
+ liftIO $ catchBoolIO $
+ withHandle StdinHandle createProcessSuccess p $ \h -> do
+ feeder h
+ return True
+
+retrieveHelper :: Remote -> Key -> (Handle -> IO ()) -> Annex Bool
+retrieveHelper r k reader = go =<< glacierEnv c u
+ where
+ c = config r
+ u = uuid r
+ params = glacierParams c
+ [ Param "archive"
+ , Param "retrieve"
+ , Param "-o-"
+ , Param $ getVault $ config r
+ , Param $ archive r k
+ ]
+ go Nothing = return False
+ go (Just e) = do
+ let p = (proc "glacier" (toCommand params)) { env = Just e }
+ ok <- liftIO $ catchBoolIO $
+ withHandle StdoutHandle createProcessSuccess p $ \h ->
+ ifM (hIsEOF h)
+ ( return False
+ , do
+ reader h
+ return True
+ )
+ unless ok later
+ return ok
+ later = showLongNote "Recommend you wait up to 4 hours, and then run this command again."
+
+remove :: Remote -> Key -> Annex Bool
+remove r k = glacierAction r
+ [ Param "archive"
+ , Param "delete"
+ , Param $ getVault $ config r
+ , Param $ archive r k
+ ]
+
+checkPresent :: Remote -> Key -> Annex (Either String Bool)
+checkPresent r k = do
+ showAction $ "checking " ++ name r
+ go =<< glacierEnv (config r) (uuid r)
+ where
+ go Nothing = return $ Left "cannot check glacier"
+ go (Just e) = do
+ {- glacier checkpresent outputs the archive name to stdout if
+ - it's present. -}
+ v <- liftIO $ catchMsgIO $
+ readProcessEnv "glacier" (toCommand params) (Just e)
+ case v of
+ Right s -> do
+ let probablypresent = key2file k `elem` lines s
+ if probablypresent
+ then ifM (Annex.getFlag "trustglacier")
+ ( return $ Right True, untrusted )
+ else return $ Right False
+ Left err -> return $ Left err
+
+ params =
+ [ Param "archive"
+ , Param "checkpresent"
+ , Param $ getVault $ config r
+ , Param "--quiet"
+ , Param $ archive r k
+ ]
+
+ untrusted = return $ Left $ unlines
+ [ "Glacier's inventory says it has a copy."
+ , "However, the inventory could be out of date, if it was recently removed."
+ , "(Use --trust-glacier if you're sure it's still in Glacier.)"
+ , ""
+ ]
+
+glacierAction :: Remote -> [CommandParam] -> Annex Bool
+glacierAction r = runGlacier (config r) (uuid r)
+
+runGlacier :: RemoteConfig -> UUID -> [CommandParam] -> Annex Bool
+runGlacier c u params = go =<< glacierEnv c u
+ where
+ go Nothing = return False
+ go (Just e) = liftIO $
+ boolSystemEnv "glacier" (glacierParams c params) (Just e)
+
+glacierParams :: RemoteConfig -> [CommandParam] -> [CommandParam]
+glacierParams c params = datacenter:params
+ where
+ datacenter = Param $ "--region=" ++
+ fromJust (M.lookup "datacenter" c)
+
+glacierEnv :: RemoteConfig -> UUID -> Annex (Maybe [(String, String)])
+glacierEnv c u = go =<< getRemoteCredPairFor "glacier" c creds
+ where
+ go Nothing = return Nothing
+ go (Just (user, pass)) = do
+ e <- liftIO getEnvironment
+ return $ Just $ (uk, user):(pk, pass):e
+
+ creds = AWS.creds u
+ (uk, pk) = credPairEnvironment creds
+
+getVault :: RemoteConfig -> Vault
+getVault = fromJust . M.lookup "vault"
+
+archive :: Remote -> Key -> Archive
+archive r k = fileprefix ++ key2file k
+ where
+ fileprefix = M.findWithDefault "" "fileprefix" $ config r
+
+-- glacier vault create will succeed even if the vault already exists.
+genVault :: RemoteConfig -> UUID -> Annex ()
+genVault c u = unlessM (runGlacier c u params) $
+ error "Failed creating glacier vault."
+ where
+ params =
+ [ Param "vault"
+ , Param "create"
+ , Param $ getVault c
+ ]
+
+{- Partitions the input list of keys into ones which have
+ - glacier retieval jobs that have succeeded, or failed.
+ -
+ - A complication is that `glacier job list` will display the encrypted
+ - keys when the remote is encrypted.
+ -}
+jobList :: Remote -> [Key] -> Annex ([Key], [Key])
+jobList r keys = go =<< glacierEnv (config r) (uuid r)
+ where
+ params = [ Param "job", Param "list" ]
+ nada = ([], [])
+ myvault = getVault $ config r
+
+ go Nothing = return nada
+ go (Just e) = do
+ v <- liftIO $ catchMaybeIO $
+ readProcessEnv "glacier" (toCommand params) (Just e)
+ maybe (return nada) extract v
+
+ extract s = do
+ let result@(succeeded, failed) =
+ parse nada $ (map words . lines) s
+ if result == nada
+ then return nada
+ else do
+ enckeys <- forM keys $ \k ->
+ maybe k snd <$> cipherKey (config r) k
+ let keymap = M.fromList $ zip enckeys keys
+ let convert = mapMaybe (`M.lookup` keymap)
+ return (convert succeeded, convert failed)
+
+ parse c [] = c
+ parse c@(succeeded, failed) ((status:_date:vault:key:[]):rest)
+ | vault == myvault =
+ case file2key key of
+ Nothing -> parse c rest
+ Just k
+ | "a/d" `isPrefixOf` status ->
+ parse (k:succeeded, failed) rest
+ | "a/e" `isPrefixOf` status ->
+ parse (succeeded, k:failed) rest
+ | otherwise ->
+ parse c rest
+ parse c (_:rest) = parse c rest
diff --git a/Remote/Helper/AWS.hs b/Remote/Helper/AWS.hs
new file mode 100644
index 000000000..1d80ff1b4
--- /dev/null
+++ b/Remote/Helper/AWS.hs
@@ -0,0 +1,66 @@
+{- Amazon Web Services common infrastructure.
+ -
+ - Copyright 2011,2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE OverloadedStrings, TupleSections #-}
+
+module Remote.Helper.AWS where
+
+import Common.Annex
+import Creds
+
+import qualified Data.Map as M
+import Data.Text (Text)
+
+creds :: UUID -> CredPairStorage
+creds u = CredPairStorage
+ { credPairFile = fromUUID u
+ , credPairEnvironment = ("AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY")
+ , credPairRemoteKey = Just "s3creds"
+ }
+
+setCredsEnv :: CredPair -> IO ()
+setCredsEnv p = setEnvCredPair p $ creds undefined
+
+data Service = S3 | Glacier
+ deriving (Eq)
+
+type Region = Text
+
+regionMap :: Service -> M.Map Text Region
+regionMap = M.fromList . regionInfo
+
+defaultRegion :: Service -> Region
+defaultRegion = snd . Prelude.head . regionInfo
+
+{- S3 and Glacier use different names for some regions. Ie, "us-east-1"
+ - cannot be used with S3, while "US" cannot be used with Glacier. Dunno why.
+ - Also, Glacier is not yet available in all regions. -}
+regionInfo :: Service -> [(Text, Region)]
+regionInfo service = map (\(t, r) -> (t, fromServiceRegion r)) $
+ filter (matchingService . snd) $
+ concatMap (\(t, l) -> map (t,) l) regions
+ where
+ regions =
+ [ ("US East (N. Virginia)", [S3Region "US", GlacierRegion "us-east-1"])
+ , ("US West (Oregon)", [BothRegion "us-west-2"])
+ , ("US West (N. California)", [BothRegion "us-west-1"])
+ , ("EU (Ireland)", [S3Region "EU", GlacierRegion "eu-west-1"])
+ , ("Asia Pacific (Singapore)", [S3Region "ap-southeast-1"])
+ , ("Asia Pacific (Tokyo)", [BothRegion "ap-northeast-1"])
+ , ("Asia Pacific (Sydney)", [S3Region "ap-southeast-2"])
+ , ("South America (São Paulo)", [S3Region "sa-east-1"])
+ ]
+
+ fromServiceRegion (BothRegion s) = s
+ fromServiceRegion (S3Region s) = s
+ fromServiceRegion (GlacierRegion s) = s
+
+ matchingService (BothRegion _) = True
+ matchingService (S3Region _) = service == S3
+ matchingService (GlacierRegion _) = service == Glacier
+
+data ServiceRegion = BothRegion Region | S3Region Region | GlacierRegion Region
diff --git a/Remote/Helper/Chunked.hs b/Remote/Helper/Chunked.hs
new file mode 100644
index 000000000..ad3b04d49
--- /dev/null
+++ b/Remote/Helper/Chunked.hs
@@ -0,0 +1,144 @@
+{- git-annex chunked remotes
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Remote.Helper.Chunked where
+
+import Common.Annex
+import Utility.DataUnits
+import Types.Remote
+import Utility.Metered
+
+import qualified Data.Map as M
+import qualified Data.ByteString.Lazy as L
+import Data.Int
+import qualified Control.Exception as E
+
+type ChunkSize = Maybe Int64
+
+{- Gets a remote's configured chunk size. -}
+chunkSize :: RemoteConfig -> ChunkSize
+chunkSize m =
+ case M.lookup "chunksize" m of
+ Nothing -> Nothing
+ Just v -> case readSize dataUnits v of
+ Nothing -> error "bad chunksize"
+ Just size
+ | size <= 0 -> error "bad chunksize"
+ | otherwise -> Just $ fromInteger size
+
+{- This is an extension that's added to the usual file (or whatever)
+ - where the remote stores a key. -}
+type ChunkExt = String
+
+{- A record of the number of chunks used.
+ -
+ - While this can be guessed at based on the size of the key, encryption
+ - makes that larger. Also, using this helps deal with changes to chunksize
+ - over the life of a remote.
+ -}
+chunkCount :: ChunkExt
+chunkCount = ".chunkcount"
+
+{- An infinite stream of extensions to use for chunks. -}
+chunkStream :: [ChunkExt]
+chunkStream = map (\n -> ".chunk" ++ show n) [1 :: Integer ..]
+
+{- Parses the String from the chunkCount file, and returns the files that
+ - are used to store the chunks. -}
+listChunks :: FilePath -> String -> [FilePath]
+listChunks basedest chunkcount = take count $ map (basedest ++) chunkStream
+ where
+ count = fromMaybe 0 $ readish chunkcount
+
+{- For use when there is no chunkCount file; uses the action to find
+ - chunks, and returns them, or Nothing if none found. Relies on
+ - storeChunks's finalizer atomically moving the chunks into place once all
+ - are written.
+ -
+ - This is only needed to work around a bug that caused the chunkCount file
+ - not to be written.
+ -}
+probeChunks :: FilePath -> (FilePath -> IO Bool) -> IO [FilePath]
+probeChunks basedest check = go [] $ map (basedest ++) chunkStream
+ where
+ go l [] = return (reverse l)
+ go l (c:cs) = ifM (check c)
+ ( go (c:l) cs
+ , go l []
+ )
+
+{- Given the base destination to use to store a value,
+ - generates a stream of temporary destinations (just one when not chunking)
+ - and passes it to an action, which should chunk and store the data,
+ - and return the destinations it stored to, or [] on error. Then
+ - calls the recorder to write the chunk count (if chunking). Finally, the
+ - finalizer is called to rename the tmp into the dest
+ - (and do any other cleanup).
+ -}
+storeChunks :: Key -> FilePath -> FilePath -> ChunkSize -> ([FilePath] -> IO [FilePath]) -> (FilePath -> String -> IO ()) -> (FilePath -> FilePath -> IO ()) -> IO Bool
+storeChunks key tmp dest chunksize storer recorder finalizer = either onerr return
+ =<< (E.try go :: IO (Either E.SomeException Bool))
+ where
+ go = do
+ stored <- storer tmpdests
+ when (isJust chunksize) $ do
+ let chunkcount = basef ++ chunkCount
+ recorder chunkcount (show $ length stored)
+ finalizer tmp dest
+ return (not $ null stored)
+ onerr e = do
+ print e
+ return False
+
+ basef = tmp ++ keyFile key
+ tmpdests
+ | isNothing chunksize = [basef]
+ | otherwise = map (basef ++ ) chunkStream
+
+{- Given a list of destinations to use, chunks the data according to the
+ - ChunkSize, and runs the storer action to store each chunk. Returns
+ - the destinations where data was stored, or [] on error.
+ -
+ - This buffers each chunk in memory.
+ - More optimal versions of this can be written, that rely
+ - on L.toChunks to split the lazy bytestring into chunks (typically
+ - smaller than the ChunkSize), and eg, write those chunks to a Handle.
+ - But this is the best that can be done with the storer interface that
+ - writes a whole L.ByteString at a time.
+ -}
+storeChunked :: ChunkSize -> [FilePath] -> (FilePath -> L.ByteString -> IO ()) -> L.ByteString -> IO [FilePath]
+storeChunked chunksize dests storer content = either onerr return
+ =<< (E.try (go chunksize dests) :: IO (Either E.SomeException [FilePath]))
+ where
+ go _ [] = return [] -- no dests!?
+ go Nothing (d:_) = do
+ storer d content
+ return [d]
+ go (Just sz) _
+ -- always write a chunk, even if the data is 0 bytes
+ | L.null content = go Nothing dests
+ | otherwise = storechunks sz [] dests content
+
+ onerr e = do
+ print e
+ return []
+
+ storechunks _ _ [] _ = return [] -- ran out of dests
+ storechunks sz useddests (d:ds) b
+ | L.null b = return $ reverse useddests
+ | otherwise = do
+ let (chunk, b') = L.splitAt sz b
+ storer d chunk
+ storechunks sz (d:useddests) ds b'
+
+{- Writes a series of chunks to a file. The feeder is called to get
+ - each chunk. -}
+meteredWriteFileChunks :: MeterUpdate -> FilePath -> [v] -> (v -> IO L.ByteString) -> IO ()
+meteredWriteFileChunks meterupdate dest chunks feeder =
+ withBinaryFile dest WriteMode $ \h ->
+ forM_ chunks $
+ meteredWrite meterupdate h <=< feeder
diff --git a/Remote/Helper/Encryptable.hs b/Remote/Helper/Encryptable.hs
new file mode 100644
index 000000000..a6e79ddc4
--- /dev/null
+++ b/Remote/Helper/Encryptable.hs
@@ -0,0 +1,164 @@
+{- common functions for encryptable remotes
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Remote.Helper.Encryptable where
+
+import qualified Data.Map as M
+
+import Common.Annex
+import Types.Remote
+import Crypto
+import Types.Crypto
+import qualified Annex
+import Config.Cost
+import Utility.Base64
+import Utility.Metered
+
+{- Encryption setup for a remote. The user must specify whether to use
+ - an encryption key, or not encrypt. An encrypted cipher is created, or is
+ - updated to be accessible to an additional encryption key. Or the user
+ - could opt to use a shared cipher, which is stored unencrypted. -}
+encryptionSetup :: RemoteConfig -> Annex RemoteConfig
+encryptionSetup c = maybe genCipher updateCipher $ extractCipher c
+ where
+ -- The type of encryption
+ encryption = M.lookup "encryption" c
+ -- Generate a new cipher, depending on the chosen encryption scheme
+ genCipher = case encryption of
+ _ | M.member "cipher" c || M.member "cipherkeys" c -> cannotchange
+ Just "none" -> return c
+ Just "shared" -> use "encryption setup" . genSharedCipher
+ =<< highRandomQuality
+ -- hybrid encryption is the default when a keyid is
+ -- specified but no encryption
+ _ | maybe (M.member "keyid" c) (== "hybrid") encryption ->
+ use "encryption setup" . genEncryptedCipher key Hybrid
+ =<< highRandomQuality
+ Just "pubkey" -> use "encryption setup" . genEncryptedCipher key PubKey
+ =<< highRandomQuality
+ _ -> error $ "Specify " ++ intercalate " or "
+ (map ("encryption=" ++)
+ ["none","shared","hybrid","pubkey"])
+ ++ "."
+ key = fromMaybe (error "Specifiy keyid=...") $ M.lookup "keyid" c
+ newkeys = maybe [] (\k -> [(True,k)]) (M.lookup "keyid+" c) ++
+ maybe [] (\k -> [(False,k)]) (M.lookup "keyid-" c)
+ cannotchange = error "Cannot set encryption type of existing remotes."
+ -- Update an existing cipher if possible.
+ updateCipher v = case v of
+ SharedCipher _ | maybe True (== "shared") encryption -> return c'
+ EncryptedCipher _ variant _
+ | maybe True (== if variant == Hybrid then "hybrid" else "pubkey") encryption ->
+ use "encryption update" $ updateEncryptedCipher newkeys v
+ _ -> cannotchange
+ use m a = do
+ showNote m
+ cipher <- liftIO a
+ showNote $ describeCipher cipher
+ return $ storeCipher c' cipher
+ highRandomQuality =
+ (&&) (maybe True ( /= "false") $ M.lookup "highRandomQuality" c)
+ <$> fmap not (Annex.getState Annex.fast)
+ c' = foldr M.delete c
+ -- git-annex used to remove 'encryption' as well, since
+ -- it was redundant; we now need to keep it for
+ -- public-key incryption, hence we leave it on newer
+ -- remotes (while being backward-compatible).
+ [ "keyid", "keyid+", "keyid-", "highRandomQuality" ]
+
+{- Modifies a Remote to support encryption.
+ -
+ - Two additional functions must be provided by the remote,
+ - to support storing and retrieving encrypted content. -}
+encryptableRemote
+ :: RemoteConfig
+ -> ((Cipher, Key) -> Key -> MeterUpdate -> Annex Bool)
+ -> ((Cipher, Key) -> Key -> FilePath -> MeterUpdate -> Annex Bool)
+ -> Remote
+ -> Remote
+encryptableRemote c storeKeyEncrypted retrieveKeyFileEncrypted r =
+ r {
+ storeKey = store,
+ retrieveKeyFile = retrieve,
+ retrieveKeyFileCheap = retrieveCheap,
+ removeKey = withkey $ removeKey r,
+ hasKey = withkey $ hasKey r,
+ cost = cost r + encryptedRemoteCostAdj
+ }
+ where
+ store k f p = cip k >>= maybe
+ (storeKey r k f p)
+ (\enck -> storeKeyEncrypted enck k p)
+ retrieve k f d p = cip k >>= maybe
+ (retrieveKeyFile r k f d p)
+ (\enck -> retrieveKeyFileEncrypted enck k d p)
+ retrieveCheap k d = cip k >>= maybe
+ (retrieveKeyFileCheap r k d)
+ (\_ -> return False)
+ withkey a k = cip k >>= maybe (a k) (a . snd)
+ cip = cipherKey c
+
+{- Gets encryption Cipher. The decrypted Ciphers are cached in the Annex
+ - state. -}
+remoteCipher :: RemoteConfig -> Annex (Maybe Cipher)
+remoteCipher c = go $ extractCipher c
+ where
+ go Nothing = return Nothing
+ go (Just encipher) = do
+ cache <- Annex.getState Annex.ciphers
+ case M.lookup encipher cache of
+ Just cipher -> return $ Just cipher
+ Nothing -> do
+ showNote "gpg"
+ cipher <- liftIO $ decryptCipher encipher
+ Annex.changeState (\s -> s { Annex.ciphers = M.insert encipher cipher cache })
+ return $ Just cipher
+
+{- Checks if the remote's config allows storing creds in the remote's config.
+ -
+ - embedcreds=yes allows this, and embedcreds=no prevents it.
+ -
+ - If not set, the default is to only store creds when it's surely safe:
+ - When gpg encryption is used, in which case the creds will be encrypted
+ - using it. Not when a shared cipher is used.
+ -}
+embedCreds :: RemoteConfig -> Bool
+embedCreds c
+ | M.lookup "embedcreds" c == Just "yes" = True
+ | M.lookup "embedcreds" c == Just "no" = False
+ | isJust (M.lookup "cipherkeys" c) && isJust (M.lookup "cipher" c) = True
+ | otherwise = False
+
+{- Gets encryption Cipher, and encrypted version of Key. -}
+cipherKey :: RemoteConfig -> Key -> Annex (Maybe (Cipher, Key))
+cipherKey c k = fmap make <$> remoteCipher c
+ where
+ make ciphertext = (ciphertext, encryptKey mac ciphertext k)
+ mac = fromMaybe defaultMac $ M.lookup "mac" c >>= readMac
+
+{- Stores an StorableCipher in a remote's configuration. -}
+storeCipher :: RemoteConfig -> StorableCipher -> RemoteConfig
+storeCipher c (SharedCipher t) = M.insert "cipher" (toB64 t) c
+storeCipher c (EncryptedCipher t _ ks) =
+ M.insert "cipher" (toB64 t) $ M.insert "cipherkeys" (showkeys ks) c
+ where
+ showkeys (KeyIds l) = intercalate "," l
+
+{- Extracts an StorableCipher from a remote's configuration. -}
+extractCipher :: RemoteConfig -> Maybe StorableCipher
+extractCipher c = case (M.lookup "cipher" c,
+ M.lookup "cipherkeys" c,
+ M.lookup "encryption" c) of
+ (Just t, Just ks, encryption) | maybe True (== "hybrid") encryption ->
+ Just $ EncryptedCipher (fromB64 t) Hybrid (readkeys ks)
+ (Just t, Just ks, Just "pubkey") ->
+ Just $ EncryptedCipher (fromB64 t) PubKey (readkeys ks)
+ (Just t, Nothing, encryption) | maybe True (== "shared") encryption ->
+ Just $ SharedCipher (fromB64 t)
+ _ -> Nothing
+ where
+ readkeys = KeyIds . split ","
diff --git a/Remote/Helper/Git.hs b/Remote/Helper/Git.hs
new file mode 100644
index 000000000..7c24ff2e7
--- /dev/null
+++ b/Remote/Helper/Git.hs
@@ -0,0 +1,30 @@
+{- Utilities for git remotes.
+ -
+ - Copyright 2011-2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Remote.Helper.Git where
+
+import Common.Annex
+import qualified Git
+
+repoCheap :: Git.Repo -> Bool
+repoCheap = not . Git.repoIsUrl
+
+localpathCalc :: Git.Repo -> Maybe FilePath
+localpathCalc r = if globallyAvailableCalc r
+ then Nothing
+ else Just $ Git.repoPath r
+
+globallyAvailableCalc :: Git.Repo -> Bool
+globallyAvailableCalc r = not $
+ Git.repoIsLocal r || Git.repoIsLocalUnknown r
+
+{- Avoids performing an action on a local repository that's not usable.
+ - Does not check that the repository is still available on disk. -}
+guardUsable :: Git.Repo -> a -> Annex a -> Annex a
+guardUsable r onerr a
+ | Git.repoIsLocalUnknown r = return onerr
+ | otherwise = a
diff --git a/Remote/Helper/Hooks.hs b/Remote/Helper/Hooks.hs
new file mode 100644
index 000000000..91c6318bf
--- /dev/null
+++ b/Remote/Helper/Hooks.hs
@@ -0,0 +1,94 @@
+{- Adds hooks to remotes.
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Remote.Helper.Hooks (addHooks) where
+
+import qualified Data.Map as M
+
+import Common.Annex
+import Types.Remote
+import qualified Annex
+import Annex.LockPool
+#ifndef mingw32_HOST_OS
+import Annex.Perms
+#endif
+
+{- Modifies a remote's access functions to first run the
+ - annex-start-command hook, and trigger annex-stop-command on shutdown.
+ - This way, the hooks are only run when a remote is actively being used.
+ -}
+addHooks :: Remote -> Remote
+addHooks r = addHooks' r
+ (remoteAnnexStartCommand $ gitconfig r)
+ (remoteAnnexStopCommand $ gitconfig r)
+addHooks' :: Remote -> Maybe String -> Maybe String -> Remote
+addHooks' r Nothing Nothing = r
+addHooks' r starthook stophook = r'
+ where
+ r' = r
+ { storeKey = \k f p -> wrapper $ storeKey r k f p
+ , retrieveKeyFile = \k f d p -> wrapper $ retrieveKeyFile r k f d p
+ , retrieveKeyFileCheap = \k f -> wrapper $ retrieveKeyFileCheap r k f
+ , removeKey = wrapper . removeKey r
+ , hasKey = wrapper . hasKey r
+ }
+ where
+ wrapper = runHooks r' starthook stophook
+
+runHooks :: Remote -> Maybe String -> Maybe String -> Annex a -> Annex a
+runHooks r starthook stophook a = do
+ dir <- fromRepo gitAnnexRemotesDir
+ let lck = dir </> remoteid ++ ".lck"
+ whenM (notElem lck . M.keys <$> getPool) $ do
+ liftIO $ createDirectoryIfMissing True dir
+ firstrun lck
+ a
+ where
+ remoteid = show (uuid r)
+ run Nothing = noop
+ run (Just command) = void $ liftIO $
+ boolSystem "sh" [Param "-c", Param command]
+ firstrun lck = do
+ -- Take a shared lock; This indicates that git-annex
+ -- is using the remote, and prevents other instances
+ -- of it from running the stophook. If another
+ -- instance is shutting down right now, this
+ -- will block waiting for its exclusive lock to clear.
+ lockFile lck
+
+ -- The starthook is run even if some other git-annex
+ -- is already running, and ran it before.
+ -- It would be difficult to use locking to ensure
+ -- it's only run once, and it's also possible for
+ -- git-annex to be interrupted before it can run the
+ -- stophook, in which case the starthook
+ -- would be run again by the next git-annex.
+ -- So, requiring idempotency is the right approach.
+ run starthook
+
+ Annex.addCleanup (remoteid ++ "-stop-command") $ runstop lck
+#ifndef mingw32_HOST_OS
+ runstop lck = do
+ -- Drop any shared lock we have, and take an
+ -- exclusive lock, without blocking. If the lock
+ -- succeeds, we're the only process using this remote,
+ -- so can stop it.
+ unlockFile lck
+ mode <- annexFileMode
+ fd <- liftIO $ noUmask mode $
+ openFd lck ReadWrite (Just mode) defaultFileFlags
+ v <- liftIO $ tryIO $
+ setLock fd (WriteLock, AbsoluteSeek, 0, 0)
+ case v of
+ Left _ -> noop
+ Right _ -> run stophook
+ liftIO $ closeFd fd
+#else
+ runstop _lck = run stophook
+#endif
diff --git a/Remote/Helper/Messages.hs b/Remote/Helper/Messages.hs
new file mode 100644
index 000000000..c4b1966dc
--- /dev/null
+++ b/Remote/Helper/Messages.hs
@@ -0,0 +1,17 @@
+{- git-annex remote messages
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Remote.Helper.Messages where
+
+import Common.Annex
+import qualified Git
+
+showChecking :: Git.Repo -> Annex ()
+showChecking r = showAction $ "checking " ++ Git.repoDescribe r
+
+cantCheck :: Git.Repo -> Either String Bool
+cantCheck r = Left $ "unable to check " ++ Git.repoDescribe r
diff --git a/Remote/Helper/Special.hs b/Remote/Helper/Special.hs
new file mode 100644
index 000000000..7fc421f46
--- /dev/null
+++ b/Remote/Helper/Special.hs
@@ -0,0 +1,40 @@
+{- common functions for special remotes
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Remote.Helper.Special where
+
+import qualified Data.Map as M
+
+import Common.Annex
+import Types.Remote
+import qualified Git
+import qualified Git.Command
+import qualified Git.Construct
+
+{- Special remotes don't have a configured url, so Git.Repo does not
+ - automatically generate remotes for them. This looks for a different
+ - configuration key instead.
+ -}
+findSpecialRemotes :: String -> Annex [Git.Repo]
+findSpecialRemotes s = do
+ m <- fromRepo Git.config
+ liftIO $ mapM construct $ remotepairs m
+ where
+ remotepairs = M.toList . M.filterWithKey match
+ construct (k,_) = Git.Construct.remoteNamedFromKey k Git.Construct.fromUnknown
+ match k _ = startswith "remote." k && endswith (".annex-"++s) k
+
+{- Sets up configuration for a special remote in .git/config. -}
+gitConfigSpecialRemote :: UUID -> RemoteConfig -> String -> String -> Annex ()
+gitConfigSpecialRemote u c k v = do
+ set ("annex-"++k) v
+ set ("annex-uuid") (fromUUID u)
+ where
+ set a b = inRepo $ Git.Command.run
+ [Param "config", Param (configsetting a), Param b]
+ remotename = fromJust (M.lookup "name" c)
+ configsetting s = "remote." ++ remotename ++ "." ++ s
diff --git a/Remote/Helper/Ssh.hs b/Remote/Helper/Ssh.hs
new file mode 100644
index 000000000..8cf9275a0
--- /dev/null
+++ b/Remote/Helper/Ssh.hs
@@ -0,0 +1,146 @@
+{- git-annex remote access with ssh and git-annex-shell
+ -
+ - Copyright 2011-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Remote.Helper.Ssh where
+
+import Common.Annex
+import qualified Git
+import qualified Git.Url
+import Annex.UUID
+import Annex.Ssh
+import Fields (Field, fieldName)
+import qualified Fields
+import Types.GitConfig
+import Types.Key
+import Remote.Helper.Messages
+import Utility.Metered
+import Utility.Rsync
+import Types.Remote
+import Logs.Transfer
+
+{- Generates parameters to ssh to a repository's host and run a command.
+ - Caller is responsible for doing any neccessary shellEscaping of the
+ - passed command. -}
+toRepo :: Git.Repo -> [CommandParam] -> Annex [CommandParam]
+toRepo r sshcmd = do
+ g <- fromRepo id
+ let c = extractRemoteGitConfig g (Git.repoDescribe r)
+ let opts = map Param $ remoteAnnexSshOptions c
+ let host = fromMaybe (error "bad ssh url") $ Git.Url.hostuser r
+ params <- sshCachingOptions (host, Git.Url.port r) opts
+ return $ params ++ Param host : sshcmd
+
+{- Generates parameters to run a git-annex-shell command on a remote
+ - repository. -}
+git_annex_shell :: Git.Repo -> String -> [CommandParam] -> [(Field, String)] -> Annex (Maybe (FilePath, [CommandParam]))
+git_annex_shell r command params fields
+ | not $ Git.repoIsUrl r = return $ Just (shellcmd, shellopts ++ fieldopts)
+ | Git.repoIsSsh r = do
+ u <- getRepoUUID r
+ sshparams <- toRepo r [Param $ sshcmd u ]
+ return $ Just ("ssh", sshparams)
+ | otherwise = return Nothing
+ where
+ dir = Git.repoPath r
+ shellcmd = "git-annex-shell"
+ shellopts = Param command : File dir : params
+ sshcmd u = unwords $
+ shellcmd : map shellEscape (toCommand shellopts) ++
+ uuidcheck u ++
+ map shellEscape (toCommand fieldopts)
+ uuidcheck NoUUID = []
+ uuidcheck (UUID u) = ["--uuid", u]
+ fieldopts
+ | null fields = []
+ | otherwise = fieldsep : map fieldopt fields ++ [fieldsep]
+ fieldsep = Param "--"
+ fieldopt (field, value) = Param $
+ fieldName field ++ "=" ++ value
+
+{- Uses a supplied function (such as boolSystem) to run a git-annex-shell
+ - command on a remote.
+ -
+ - Or, if the remote does not support running remote commands, returns
+ - a specified error value. -}
+onRemote
+ :: Git.Repo
+ -> (FilePath -> [CommandParam] -> IO a, a)
+ -> String
+ -> [CommandParam]
+ -> [(Field, String)]
+ -> Annex a
+onRemote r (with, errorval) command params fields = do
+ s <- git_annex_shell r command params fields
+ case s of
+ Just (c, ps) -> liftIO $ with c ps
+ Nothing -> return errorval
+
+{- Checks if a remote contains a key. -}
+inAnnex :: Git.Repo -> Key -> Annex (Either String Bool)
+inAnnex r k = do
+ showChecking r
+ onRemote r (check, cantCheck r) "inannex" [Param $ key2file k] []
+ where
+ check c p = dispatch <$> safeSystem c p
+ dispatch ExitSuccess = Right True
+ dispatch (ExitFailure 1) = Right False
+ dispatch _ = cantCheck r
+
+{- Removes a key from a remote. -}
+dropKey :: Git.Repo -> Key -> Annex Bool
+dropKey r key = onRemote r (boolSystem, False) "dropkey"
+ [ Params "--quiet --force"
+ , Param $ key2file key
+ ]
+ []
+
+rsyncHelper :: Maybe MeterUpdate -> [CommandParam] -> Annex Bool
+rsyncHelper callback params = do
+ showOutput -- make way for progress bar
+ ifM (liftIO $ (maybe rsync rsyncProgress callback) params)
+ ( return True
+ , do
+ showLongNote "rsync failed -- run git annex again to resume file transfer"
+ return False
+ )
+
+{- Generates rsync parameters that ssh to the remote and asks it
+ - to either receive or send the key's content. -}
+rsyncParamsRemote :: Bool -> Remote -> Direction -> Key -> FilePath -> AssociatedFile -> Annex [CommandParam]
+rsyncParamsRemote direct r direction key file afile = do
+ u <- getUUID
+ let fields = (Fields.remoteUUID, fromUUID u)
+ : (Fields.direct, if direct then "1" else "")
+ : maybe [] (\f -> [(Fields.associatedFile, f)]) afile
+ Just (shellcmd, shellparams) <- git_annex_shell (repo r)
+ (if direction == Download then "sendkey" else "recvkey")
+ [ Param $ key2file key ]
+ fields
+ -- Convert the ssh command into rsync command line.
+ let eparam = rsyncShell (Param shellcmd:shellparams)
+ let o = rsyncParams r
+ return $ if direction == Download
+ then o ++ rsyncopts eparam dummy (File file)
+ else o ++ rsyncopts eparam (File file) dummy
+ where
+ rsyncopts ps source dest
+ | end ps == [dashdash] = ps ++ [source, dest]
+ | otherwise = ps ++ [dashdash, source, dest]
+ dashdash = Param "--"
+ {- The rsync shell parameter controls where rsync
+ - goes, so the source/dest parameter can be a dummy value,
+ - that just enables remote rsync mode.
+ - For maximum compatability with some patched rsyncs,
+ - the dummy value needs to still contain a hostname,
+ - even though this hostname will never be used. -}
+ dummy = Param "dummy:"
+
+-- --inplace to resume partial files
+rsyncParams :: Remote -> [CommandParam]
+rsyncParams r = Params "--progress --inplace" :
+ map Param (remoteAnnexRsyncOptions $ gitconfig r)
+
diff --git a/Remote/Hook.hs b/Remote/Hook.hs
new file mode 100644
index 000000000..55ff78514
--- /dev/null
+++ b/Remote/Hook.hs
@@ -0,0 +1,159 @@
+{- A remote that provides hooks to run shell commands.
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Remote.Hook (remote) where
+
+import qualified Data.ByteString.Lazy as L
+import qualified Data.Map as M
+import System.Environment
+
+import Common.Annex
+import Types.Remote
+import Types.Key
+import qualified Git
+import Config
+import Config.Cost
+import Annex.Content
+import Annex.UUID
+import Remote.Helper.Special
+import Remote.Helper.Encryptable
+import Crypto
+import Utility.Metered
+
+type Action = String
+type HookName = String
+
+remote :: RemoteType
+remote = RemoteType {
+ typename = "hook",
+ enumerate = findSpecialRemotes "hooktype",
+ generate = gen,
+ setup = hookSetup
+}
+
+gen :: Git.Repo -> UUID -> RemoteConfig -> RemoteGitConfig -> Annex (Maybe Remote)
+gen r u c gc = do
+ cst <- remoteCost gc expensiveRemoteCost
+ return $ Just $ encryptableRemote c
+ (storeEncrypted hooktype $ getGpgEncParams (c,gc))
+ (retrieveEncrypted hooktype)
+ Remote {
+ uuid = u,
+ cost = cst,
+ name = Git.repoDescribe r,
+ storeKey = store hooktype,
+ retrieveKeyFile = retrieve hooktype,
+ retrieveKeyFileCheap = retrieveCheap hooktype,
+ removeKey = remove hooktype,
+ hasKey = checkPresent r hooktype,
+ hasKeyCheap = False,
+ whereisKey = Nothing,
+ remoteFsck = Nothing,
+ repairRepo = Nothing,
+ config = c,
+ localpath = Nothing,
+ repo = r,
+ gitconfig = gc,
+ readonly = False,
+ globallyAvailable = False,
+ remotetype = remote
+ }
+ where
+ hooktype = fromMaybe (error "missing hooktype") $ remoteAnnexHookType gc
+
+hookSetup :: Maybe UUID -> RemoteConfig -> Annex (RemoteConfig, UUID)
+hookSetup mu c = do
+ u <- maybe (liftIO genUUID) return mu
+ let hooktype = fromMaybe (error "Specify hooktype=") $
+ M.lookup "hooktype" c
+ c' <- encryptionSetup c
+ gitConfigSpecialRemote u c' "hooktype" hooktype
+ return (c', u)
+
+hookEnv :: Action -> Key -> Maybe FilePath -> IO (Maybe [(String, String)])
+hookEnv action k f = Just <$> mergeenv (fileenv f ++ keyenv)
+ where
+ mergeenv l = M.toList . M.union (M.fromList l)
+ <$> M.fromList <$> getEnvironment
+ env s v = ("ANNEX_" ++ s, v)
+ keyenv = catMaybes
+ [ Just $ env "KEY" (key2file k)
+ , Just $ env "ACTION" action
+ , env "HASH_1" <$> headMaybe hashbits
+ , env "HASH_2" <$> headMaybe (drop 1 hashbits)
+ ]
+ fileenv Nothing = []
+ fileenv (Just file) = [env "FILE" file]
+ hashbits = map takeDirectory $ splitPath $ hashDirMixed k
+
+lookupHook :: HookName -> Action -> Annex (Maybe String)
+lookupHook hookname action = do
+ command <- getConfig (annexConfig hook) ""
+ if null command
+ then do
+ fallback <- getConfig (annexConfig hookfallback) ""
+ if null fallback
+ then do
+ warning $ "missing configuration for " ++ hook ++ " or " ++ hookfallback
+ return Nothing
+ else return $ Just fallback
+ else return $ Just command
+ where
+ hook = hookname ++ "-" ++ action ++ "-hook"
+ hookfallback = hookname ++ "-hook"
+
+runHook :: HookName -> Action -> Key -> Maybe FilePath -> Annex Bool -> Annex Bool
+runHook hook action k f a = maybe (return False) run =<< lookupHook hook action
+ where
+ run command = do
+ showOutput -- make way for hook output
+ ifM (liftIO $ boolSystemEnv "sh" [Param "-c", Param command] =<< hookEnv action k f)
+ ( a
+ , do
+ warning $ hook ++ " hook exited nonzero!"
+ return False
+ )
+
+store :: HookName -> Key -> AssociatedFile -> MeterUpdate -> Annex Bool
+store h k _f _p = sendAnnex k (void $ remove h k) $ \src ->
+ runHook h "store" k (Just src) $ return True
+
+storeEncrypted :: HookName -> [CommandParam] -> (Cipher, Key) -> Key -> MeterUpdate -> Annex Bool
+storeEncrypted h gpgOpts (cipher, enck) k _p = withTmp enck $ \tmp ->
+ sendAnnex k (void $ remove h enck) $ \src -> do
+ liftIO $ encrypt gpgOpts cipher (feedFile src) $
+ readBytes $ L.writeFile tmp
+ runHook h "store" enck (Just tmp) $ return True
+
+retrieve :: HookName -> Key -> AssociatedFile -> FilePath -> MeterUpdate -> Annex Bool
+retrieve h k _f d _p = runHook h "retrieve" k (Just d) $ return True
+
+retrieveCheap :: HookName -> Key -> FilePath -> Annex Bool
+retrieveCheap _ _ _ = return False
+
+retrieveEncrypted :: HookName -> (Cipher, Key) -> Key -> FilePath -> MeterUpdate -> Annex Bool
+retrieveEncrypted h (cipher, enck) _ f _p = withTmp enck $ \tmp ->
+ runHook h "retrieve" enck (Just tmp) $ liftIO $ catchBoolIO $ do
+ decrypt cipher (feedFile tmp) $
+ readBytes $ L.writeFile f
+ return True
+
+remove :: HookName -> Key -> Annex Bool
+remove h k = runHook h "remove" k Nothing $ return True
+
+checkPresent :: Git.Repo -> HookName -> Key -> Annex (Either String Bool)
+checkPresent r h k = do
+ showAction $ "checking " ++ Git.repoDescribe r
+ v <- lookupHook h action
+ liftIO $ catchMsgIO $ check v
+ where
+ action = "checkpresent"
+ findkey s = key2file k `elem` lines s
+ check Nothing = error $ action ++ " hook misconfigured"
+ check (Just hook) = do
+ env <- hookEnv action k Nothing
+ findkey <$> readProcessEnv "sh" ["-c", hook] env
diff --git a/Remote/List.hs b/Remote/List.hs
new file mode 100644
index 000000000..d53b92912
--- /dev/null
+++ b/Remote/List.hs
@@ -0,0 +1,107 @@
+{-# LANGUAGE CPP #-}
+
+{- git-annex remote list
+ -
+ - Copyright 2011,2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Remote.List where
+
+import qualified Data.Map as M
+
+import Common.Annex
+import qualified Annex
+import Logs.Remote
+import Types.Remote
+import Types.GitConfig
+import Annex.UUID
+import Remote.Helper.Hooks
+import qualified Git
+import qualified Git.Config
+
+import qualified Remote.Git
+import qualified Remote.GCrypt
+#ifdef WITH_S3
+import qualified Remote.S3
+#endif
+import qualified Remote.Bup
+import qualified Remote.Directory
+import qualified Remote.Rsync
+import qualified Remote.Web
+#ifdef WITH_WEBDAV
+import qualified Remote.WebDAV
+#endif
+import qualified Remote.Glacier
+import qualified Remote.Hook
+
+remoteTypes :: [RemoteType]
+remoteTypes =
+ [ Remote.Git.remote
+ , Remote.GCrypt.remote
+#ifdef WITH_S3
+ , Remote.S3.remote
+#endif
+ , Remote.Bup.remote
+ , Remote.Directory.remote
+ , Remote.Rsync.remote
+ , Remote.Web.remote
+#ifdef WITH_WEBDAV
+ , Remote.WebDAV.remote
+#endif
+ , Remote.Glacier.remote
+ , Remote.Hook.remote
+ ]
+
+{- Builds a list of all available Remotes.
+ - Since doing so can be expensive, the list is cached. -}
+remoteList :: Annex [Remote]
+remoteList = do
+ rs <- Annex.getState Annex.remotes
+ if null rs
+ then do
+ m <- readRemoteLog
+ rs' <- concat <$> mapM (process m) remoteTypes
+ Annex.changeState $ \s -> s { Annex.remotes = rs' }
+ return rs'
+ else return rs
+ where
+ process m t = enumerate t >>= mapM (remoteGen m t) >>= return . catMaybes
+
+{- Forces the remoteList to be re-generated, re-reading the git config. -}
+remoteListRefresh :: Annex [Remote]
+remoteListRefresh = do
+ newg <- inRepo Git.Config.reRead
+ Annex.changeState $ \s -> s
+ { Annex.remotes = []
+ , Annex.repo = newg
+ }
+ remoteList
+
+{- Generates a Remote. -}
+remoteGen :: M.Map UUID RemoteConfig -> RemoteType -> Git.Repo -> Annex (Maybe Remote)
+remoteGen m t r = do
+ u <- getRepoUUID r
+ g <- fromRepo id
+ let gc = extractRemoteGitConfig g (Git.repoDescribe r)
+ let c = fromMaybe M.empty $ M.lookup u m
+ mrmt <- generate t r u c gc
+ return $ addHooks <$> mrmt
+
+{- Updates a local git Remote, re-reading its git config. -}
+updateRemote :: Remote -> Annex (Maybe Remote)
+updateRemote remote = do
+ m <- readRemoteLog
+ remote' <- updaterepo $ repo remote
+ remoteGen m (remotetype remote) remote'
+ where
+ updaterepo r
+ | Git.repoIsLocal r || Git.repoIsLocalUnknown r =
+ Remote.Git.configRead r
+ | otherwise = return r
+
+{- Checks if a remote is syncable using git. -}
+syncableRemote :: Remote -> Bool
+syncableRemote r = remotetype r `elem`
+ [ Remote.Git.remote, Remote.GCrypt.remote ]
diff --git a/Remote/Rsync.hs b/Remote/Rsync.hs
new file mode 100644
index 000000000..91638de98
--- /dev/null
+++ b/Remote/Rsync.hs
@@ -0,0 +1,308 @@
+{- A remote that is only accessible by rsync.
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Remote.Rsync (
+ remote,
+ storeEncrypted,
+ retrieveEncrypted,
+ remove,
+ checkPresent,
+ withRsyncScratchDir,
+ genRsyncOpts,
+ RsyncOpts
+) where
+
+import qualified Data.ByteString.Lazy as L
+import qualified Data.Map as M
+#ifndef mingw32_HOST_OS
+import System.Posix.Process (getProcessID)
+#else
+import System.Random (getStdRandom, random)
+#endif
+
+import Common.Annex
+import Types.Remote
+import qualified Git
+import Config
+import Config.Cost
+import Annex.Content
+import Annex.UUID
+import Annex.Ssh
+import Remote.Helper.Special
+import Remote.Helper.Encryptable
+import Crypto
+import Utility.Rsync
+import Utility.CopyFile
+import Utility.Metered
+import Annex.Perms
+
+type RsyncUrl = String
+
+data RsyncOpts = RsyncOpts
+ { rsyncUrl :: RsyncUrl
+ , rsyncOptions :: [CommandParam]
+ , rsyncShellEscape :: Bool
+}
+
+remote :: RemoteType
+remote = RemoteType {
+ typename = "rsync",
+ enumerate = findSpecialRemotes "rsyncurl",
+ generate = gen,
+ setup = rsyncSetup
+}
+
+gen :: Git.Repo -> UUID -> RemoteConfig -> RemoteGitConfig -> Annex (Maybe Remote)
+gen r u c gc = do
+ cst <- remoteCost gc expensiveRemoteCost
+ (transport, url) <- rsyncTransport gc $
+ fromMaybe (error "missing rsyncurl") $ remoteAnnexRsyncUrl gc
+ let o = genRsyncOpts c gc transport url
+ let islocal = rsyncUrlIsPath $ rsyncUrl o
+ return $ Just $ encryptableRemote c
+ (storeEncrypted o $ getGpgEncParams (c,gc))
+ (retrieveEncrypted o)
+ Remote
+ { uuid = u
+ , cost = cst
+ , name = Git.repoDescribe r
+ , storeKey = store o
+ , retrieveKeyFile = retrieve o
+ , retrieveKeyFileCheap = retrieveCheap o
+ , removeKey = remove o
+ , hasKey = checkPresent r o
+ , hasKeyCheap = False
+ , whereisKey = Nothing
+ , remoteFsck = Nothing
+ , repairRepo = Nothing
+ , config = c
+ , repo = r
+ , gitconfig = gc
+ , localpath = if islocal
+ then Just $ rsyncUrl o
+ else Nothing
+ , readonly = False
+ , globallyAvailable = not islocal
+ , remotetype = remote
+ }
+
+genRsyncOpts :: RemoteConfig -> RemoteGitConfig -> [CommandParam] -> RsyncUrl -> RsyncOpts
+genRsyncOpts c gc transport url = RsyncOpts url (transport ++ opts) escape
+ where
+ opts = map Param $ filter safe $ remoteAnnexRsyncOptions gc
+ escape = M.lookup "shellescape" c /= Just "no"
+ safe opt
+ -- Don't allow user to pass --delete to rsync;
+ -- that could cause it to delete other keys
+ -- in the same hash bucket as a key it sends.
+ | opt == "--delete" = False
+ | opt == "--delete-excluded" = False
+ | otherwise = True
+
+rsyncTransport :: RemoteGitConfig -> RsyncUrl -> Annex ([CommandParam], RsyncUrl)
+rsyncTransport gc rawurl
+ | rsyncUrlIsShell rawurl =
+ (\rsh -> return (rsyncShell rsh, resturl)) =<<
+ case fromNull ["ssh"] (remoteAnnexRsyncTransport gc) of
+ "ssh":sshopts -> do
+ let (port, sshopts') = sshReadPort sshopts
+ host = takeWhile (/=':') resturl
+ -- Connection caching
+ (Param "ssh":) <$> sshCachingOptions
+ (host, port)
+ (map Param $ loginopt ++ sshopts')
+ "rsh":rshopts -> return $ map Param $ "rsh" :
+ loginopt ++ rshopts
+ rsh -> error $ "Unknown Rsync transport: "
+ ++ unwords rsh
+ | otherwise = return ([], rawurl)
+ where
+ (login,resturl) = case separate (=='@') rawurl of
+ (h, "") -> (Nothing, h)
+ (l, h) -> (Just l, h)
+ loginopt = maybe [] (\l -> ["-l",l]) login
+ fromNull as xs = if null xs then as else xs
+
+rsyncSetup :: Maybe UUID -> RemoteConfig -> Annex (RemoteConfig, UUID)
+rsyncSetup mu c = do
+ u <- maybe (liftIO genUUID) return mu
+ -- verify configuration is sane
+ let url = fromMaybe (error "Specify rsyncurl=") $
+ M.lookup "rsyncurl" c
+ c' <- encryptionSetup c
+
+ -- The rsyncurl is stored in git config, not only in this remote's
+ -- persistant state, so it can vary between hosts.
+ gitConfigSpecialRemote u c' "rsyncurl" url
+ return (c', u)
+
+rsyncEscape :: RsyncOpts -> String -> String
+rsyncEscape o s
+ | rsyncShellEscape o && rsyncUrlIsShell (rsyncUrl o) = shellEscape s
+ | otherwise = s
+
+rsyncUrls :: RsyncOpts -> Key -> [String]
+rsyncUrls o k = map use annexHashes
+ where
+ use h = rsyncUrl o </> h k </> rsyncEscape o (f </> f)
+ f = keyFile k
+
+store :: RsyncOpts -> Key -> AssociatedFile -> MeterUpdate -> Annex Bool
+store o k _f p = sendAnnex k (void $ remove o k) $ rsyncSend o p k False
+
+storeEncrypted :: RsyncOpts -> [CommandParam] -> (Cipher, Key) -> Key -> MeterUpdate -> Annex Bool
+storeEncrypted o gpgOpts (cipher, enck) k p = withTmp enck $ \tmp ->
+ sendAnnex k (void $ remove o enck) $ \src -> do
+ liftIO $ encrypt gpgOpts cipher (feedFile src) $
+ readBytes $ L.writeFile tmp
+ rsyncSend o p enck True tmp
+
+retrieve :: RsyncOpts -> Key -> AssociatedFile -> FilePath -> MeterUpdate -> Annex Bool
+retrieve o k _ f p = rsyncRetrieve o k f (Just p)
+
+retrieveCheap :: RsyncOpts -> Key -> FilePath -> Annex Bool
+retrieveCheap o k f = ifM (preseedTmp k f) ( rsyncRetrieve o k f Nothing , return False )
+
+retrieveEncrypted :: RsyncOpts -> (Cipher, Key) -> Key -> FilePath -> MeterUpdate -> Annex Bool
+retrieveEncrypted o (cipher, enck) _ f p = withTmp enck $ \tmp ->
+ ifM (rsyncRetrieve o enck tmp (Just p))
+ ( liftIO $ catchBoolIO $ do
+ decrypt cipher (feedFile tmp) $
+ readBytes $ L.writeFile f
+ return True
+ , return False
+ )
+
+remove :: RsyncOpts -> Key -> Annex Bool
+remove o k = do
+ ps <- sendParams
+ withRsyncScratchDir $ \tmp -> liftIO $ do
+ {- Send an empty directory to rysnc to make it delete. -}
+ let dummy = tmp </> keyFile k
+ createDirectoryIfMissing True dummy
+ rsync $ rsyncOptions o ++ ps ++
+ map (\s -> Param $ "--include=" ++ s) includes ++
+ [ Param "--exclude=*" -- exclude everything else
+ , Params "--quiet --delete --recursive"
+ , partialParams
+ , Param $ addTrailingPathSeparator dummy
+ , Param $ rsyncUrl o
+ ]
+ where
+ {- Specify include rules to match the directories where the
+ - content could be. Note that the parent directories have
+ - to also be explicitly included, due to how rsync
+ - traverses directories. -}
+ includes = concatMap use annexHashes
+ use h = let dir = h k in
+ [ parentDir dir
+ , dir
+ -- match content directory and anything in it
+ , dir </> keyFile k </> "***"
+ ]
+
+checkPresent :: Git.Repo -> RsyncOpts -> Key -> Annex (Either String Bool)
+checkPresent r o k = do
+ showAction $ "checking " ++ Git.repoDescribe r
+ -- note: Does not currently differentiate between rsync failing
+ -- to connect, and the file not being present.
+ Right <$> check
+ where
+ check = untilTrue (rsyncUrls o k) $ \u ->
+ liftIO $ catchBoolIO $ do
+ withQuietOutput createProcessSuccess $
+ proc "rsync" $ toCommand $
+ rsyncOptions o ++ [Param u]
+ return True
+
+{- Rsync params to enable resumes of sending files safely,
+ - ensure that files are only moved into place once complete
+ -}
+partialParams :: CommandParam
+partialParams = Params "--partial --partial-dir=.rsync-partial"
+
+{- When sending files from crippled filesystems, the permissions can be all
+ - messed up, and it's better to use the default permissions on the
+ - destination. -}
+sendParams :: Annex [CommandParam]
+sendParams = ifM crippledFileSystem
+ ( return [rsyncUseDestinationPermissions]
+ , return []
+ )
+
+{- Runs an action in an empty scratch directory that can be used to build
+ - up trees for rsync. -}
+withRsyncScratchDir :: (FilePath -> Annex a) -> Annex a
+withRsyncScratchDir a = do
+#ifndef mingw32_HOST_OS
+ v <- liftIO getProcessID
+#else
+ v <- liftIO (getStdRandom random :: IO Int)
+#endif
+ t <- fromRepo gitAnnexTmpDir
+ createAnnexDirectory t
+ let tmp = t </> "rsynctmp" </> show v
+ nuke tmp
+ liftIO $ createDirectoryIfMissing True tmp
+ nuke tmp `after` a tmp
+ where
+ nuke d = liftIO $ whenM (doesDirectoryExist d) $
+ removeDirectoryRecursive d
+
+rsyncRetrieve :: RsyncOpts -> Key -> FilePath -> Maybe MeterUpdate -> Annex Bool
+rsyncRetrieve o k dest callback =
+ untilTrue (rsyncUrls o k) $ \u -> rsyncRemote o callback
+ -- use inplace when retrieving to support resuming
+ [ Param "--inplace"
+ , Param u
+ , File dest
+ ]
+
+rsyncRemote :: RsyncOpts -> Maybe MeterUpdate -> [CommandParam] -> Annex Bool
+rsyncRemote o callback params = do
+ showOutput -- make way for progress bar
+ ifM (liftIO $ (maybe rsync rsyncProgress callback) ps)
+ ( return True
+ , do
+ showLongNote "rsync failed -- run git annex again to resume file transfer"
+ return False
+ )
+ where
+ defaultParams = [Params "--progress"]
+ ps = rsyncOptions o ++ defaultParams ++ params
+
+{- To send a single key is slightly tricky; need to build up a temporary
+ - directory structure to pass to rsync so it can create the hash
+ - directories.
+ -
+ - This would not be necessary if the hash directory structure used locally
+ - was always the same as that used on the rsync remote. So if that's ever
+ - unified, this gets nicer.
+ - (When we have the right hash directory structure, we can just
+ - pass --include=X --include=X/Y --include=X/Y/file --exclude=*)
+ -}
+rsyncSend :: RsyncOpts -> MeterUpdate -> Key -> Bool -> FilePath -> Annex Bool
+rsyncSend o callback k canrename src = withRsyncScratchDir $ \tmp -> do
+ let dest = tmp </> Prelude.head (keyPaths k)
+ liftIO $ createDirectoryIfMissing True $ parentDir dest
+ ok <- liftIO $ if canrename
+ then do
+ renameFile src dest
+ return True
+ else createLinkOrCopy src dest
+ ps <- sendParams
+ if ok
+ then rsyncRemote o (Just callback) $ ps ++
+ [ Param "--recursive"
+ , partialParams
+ -- tmp/ to send contents of tmp dir
+ , File $ addTrailingPathSeparator tmp
+ , Param $ rsyncUrl o
+ ]
+ else return False
diff --git a/Remote/S3.hs b/Remote/S3.hs
new file mode 100644
index 000000000..0933f30de
--- /dev/null
+++ b/Remote/S3.hs
@@ -0,0 +1,345 @@
+{- S3 remotes
+ -
+ - Copyright 2011-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Remote.S3 (remote, iaHost, isIA, isIAHost, iaItemUrl) where
+
+import Network.AWS.AWSConnection
+import Network.AWS.S3Object hiding (getStorageClass)
+import Network.AWS.S3Bucket hiding (size)
+import Network.AWS.AWSResult
+import qualified Data.Text as T
+import qualified Data.ByteString.Lazy.Char8 as L
+import qualified Data.Map as M
+import Data.Char
+import Network.Socket (HostName)
+
+import Common.Annex
+import Types.Remote
+import Types.Key
+import qualified Git
+import Config
+import Config.Cost
+import Remote.Helper.Special
+import Remote.Helper.Encryptable
+import qualified Remote.Helper.AWS as AWS
+import Crypto
+import Creds
+import Utility.Metered
+import Annex.Content
+import Annex.UUID
+import Logs.Web
+
+type Bucket = String
+
+remote :: RemoteType
+remote = RemoteType {
+ typename = "S3",
+ enumerate = findSpecialRemotes "s3",
+ generate = gen,
+ setup = s3Setup
+}
+
+gen :: Git.Repo -> UUID -> RemoteConfig -> RemoteGitConfig -> Annex (Maybe Remote)
+gen r u c gc = new <$> remoteCost gc expensiveRemoteCost
+ where
+ new cst = Just $ encryptableRemote c
+ (storeEncrypted this)
+ (retrieveEncrypted this)
+ this
+ where
+ this = Remote {
+ uuid = u,
+ cost = cst,
+ name = Git.repoDescribe r,
+ storeKey = store this,
+ retrieveKeyFile = retrieve this,
+ retrieveKeyFileCheap = retrieveCheap this,
+ removeKey = remove this c,
+ hasKey = checkPresent this,
+ hasKeyCheap = False,
+ whereisKey = Nothing,
+ remoteFsck = Nothing,
+ repairRepo = Nothing,
+ config = c,
+ repo = r,
+ gitconfig = gc,
+ localpath = Nothing,
+ readonly = False,
+ globallyAvailable = True,
+ remotetype = remote
+ }
+
+s3Setup :: Maybe UUID -> RemoteConfig -> Annex (RemoteConfig, UUID)
+s3Setup mu c = do
+ u <- maybe (liftIO genUUID) return mu
+ s3Setup' u c
+s3Setup' :: UUID -> RemoteConfig -> Annex (RemoteConfig, UUID)
+s3Setup' u c = if isIA c then archiveorg else defaulthost
+ where
+ remotename = fromJust (M.lookup "name" c)
+ defbucket = remotename ++ "-" ++ fromUUID u
+ defaults = M.fromList
+ [ ("datacenter", T.unpack $ AWS.defaultRegion AWS.S3)
+ , ("storageclass", "STANDARD")
+ , ("host", defaultAmazonS3Host)
+ , ("port", show defaultAmazonS3Port)
+ , ("bucket", defbucket)
+ ]
+
+ use fullconfig = do
+ gitConfigSpecialRemote u fullconfig "s3" "true"
+ c' <- setRemoteCredPair fullconfig (AWS.creds u)
+ return (c', u)
+
+ defaulthost = do
+ c' <- encryptionSetup c
+ let fullconfig = c' `M.union` defaults
+ genBucket fullconfig u
+ use fullconfig
+
+ archiveorg = do
+ showNote "Internet Archive mode"
+ -- Ensure user enters a valid bucket name, since
+ -- this determines the name of the archive.org item.
+ let bucket = replace " " "-" $ map toLower $
+ fromMaybe (error "specify bucket=") $
+ getBucket c
+ let archiveconfig =
+ -- hS3 does not pass through x-archive-* headers
+ M.mapKeys (replace "x-archive-" "x-amz-") $
+ -- encryption does not make sense here
+ M.insert "encryption" "none" $
+ M.insert "bucket" bucket $
+ M.union c $
+ -- special constraints on key names
+ M.insert "mungekeys" "ia" $
+ -- bucket created only when files are uploaded
+ M.insert "x-amz-auto-make-bucket" "1" defaults
+ writeUUIDFile archiveconfig u
+ use archiveconfig
+
+store :: Remote -> Key -> AssociatedFile -> MeterUpdate -> Annex Bool
+store r k _f p = s3Action r False $ \(conn, bucket) ->
+ sendAnnex k (void $ remove' r k) $ \src -> do
+ ok <- s3Bool =<< storeHelper (conn, bucket) r k p src
+
+ -- Store public URL to item in Internet Archive.
+ when (ok && isIA (config r)) $
+ setUrlPresent k (iaKeyUrl r k)
+
+ return ok
+
+storeEncrypted :: Remote -> (Cipher, Key) -> Key -> MeterUpdate -> Annex Bool
+storeEncrypted r (cipher, enck) k p = s3Action r False $ \(conn, bucket) ->
+ -- To get file size of the encrypted content, have to use a temp file.
+ -- (An alternative would be chunking to to a constant size.)
+ withTmp enck $ \tmp -> sendAnnex k (void $ remove' r enck) $ \src -> do
+ liftIO $ encrypt (getGpgEncParams r) cipher (feedFile src) $
+ readBytes $ L.writeFile tmp
+ s3Bool =<< storeHelper (conn, bucket) r enck p tmp
+
+storeHelper :: (AWSConnection, Bucket) -> Remote -> Key -> MeterUpdate -> FilePath -> Annex (AWSResult ())
+storeHelper (conn, bucket) r k p file = do
+ size <- maybe getsize (return . fromIntegral) $ keySize k
+ meteredBytes (Just p) size $ \meterupdate ->
+ liftIO $ withMeteredFile file meterupdate $ \content -> do
+ -- size is provided to S3 so the whole content
+ -- does not need to be buffered to calculate it
+ let object = S3Object
+ bucket (bucketFile r k) ""
+ (("Content-Length", show size) : getXheaders (config r))
+ content
+ sendObject conn $
+ setStorageClass (getStorageClass $ config r) object
+ where
+ getsize = liftIO $ fromIntegral . fileSize <$> getFileStatus file
+
+retrieve :: Remote -> Key -> AssociatedFile -> FilePath -> MeterUpdate -> Annex Bool
+retrieve r k _f d p = s3Action r False $ \(conn, bucket) ->
+ metered (Just p) k $ \meterupdate -> do
+ res <- liftIO $ getObject conn $ bucketKey r bucket k
+ case res of
+ Right o -> do
+ liftIO $ meteredWriteFile meterupdate d $
+ obj_data o
+ return True
+ Left e -> s3Warning e
+
+retrieveCheap :: Remote -> Key -> FilePath -> Annex Bool
+retrieveCheap _ _ _ = return False
+
+retrieveEncrypted :: Remote -> (Cipher, Key) -> Key -> FilePath -> MeterUpdate -> Annex Bool
+retrieveEncrypted r (cipher, enck) k d p = s3Action r False $ \(conn, bucket) ->
+ metered (Just p) k $ \meterupdate -> do
+ res <- liftIO $ getObject conn $ bucketKey r bucket enck
+ case res of
+ Right o -> liftIO $ decrypt cipher (\h -> meteredWrite meterupdate h $ obj_data o) $
+ readBytes $ \content -> do
+ L.writeFile d content
+ return True
+ Left e -> s3Warning e
+
+{- Internet Archive doesn't easily allow removing content.
+ - While it may remove the file, there are generally other files
+ - derived from it that it does not remove. -}
+remove :: Remote -> RemoteConfig -> Key -> Annex Bool
+remove r c k
+ | isIA c = do
+ warning "Cannot remove content from the Internet Archive"
+ return False
+ | otherwise = remove' r k
+
+remove' :: Remote -> Key -> Annex Bool
+remove' r k = s3Action r False $ \(conn, bucket) ->
+ s3Bool =<< liftIO (deleteObject conn $ bucketKey r bucket k)
+
+checkPresent :: Remote -> Key -> Annex (Either String Bool)
+checkPresent r k = s3Action r noconn $ \(conn, bucket) -> do
+ showAction $ "checking " ++ name r
+ res <- liftIO $ getObjectInfo conn $ bucketKey r bucket k
+ case res of
+ Right _ -> return $ Right True
+ Left (AWSError _ _) -> return $ Right False
+ Left e -> return $ Left (s3Error e)
+ where
+ noconn = Left $ error "S3 not configured"
+
+s3Warning :: ReqError -> Annex Bool
+s3Warning e = do
+ warning $ prettyReqError e
+ return False
+
+s3Error :: ReqError -> a
+s3Error e = error $ prettyReqError e
+
+s3Bool :: AWSResult () -> Annex Bool
+s3Bool (Right _) = return True
+s3Bool (Left e) = s3Warning e
+
+s3Action :: Remote -> a -> ((AWSConnection, Bucket) -> Annex a) -> Annex a
+s3Action r noconn action = do
+ let bucket = M.lookup "bucket" $ config r
+ conn <- s3Connection (config r) (uuid r)
+ case (bucket, conn) of
+ (Just b, Just c) -> action (c, b)
+ _ -> return noconn
+
+bucketFile :: Remote -> Key -> FilePath
+bucketFile r = munge . key2file
+ where
+ munge s = case M.lookup "mungekeys" c of
+ Just "ia" -> iaMunge $ filePrefix c ++ s
+ _ -> filePrefix c ++ s
+ c = config r
+
+filePrefix :: RemoteConfig -> String
+filePrefix = M.findWithDefault "" "fileprefix"
+
+bucketKey :: Remote -> Bucket -> Key -> S3Object
+bucketKey r bucket k = S3Object bucket (bucketFile r k) "" [] L.empty
+
+{- Internet Archive limits filenames to a subset of ascii,
+ - with no whitespace. Other characters are xml entity
+ - encoded. -}
+iaMunge :: String -> String
+iaMunge = (>>= munge)
+ where
+ munge c
+ | isAsciiUpper c || isAsciiLower c || isNumber c = [c]
+ | c `elem` "_-.\"" = [c]
+ | isSpace c = []
+ | otherwise = "&" ++ show (ord c) ++ ";"
+
+genBucket :: RemoteConfig -> UUID -> Annex ()
+genBucket c u = do
+ conn <- s3ConnectionRequired c u
+ showAction "checking bucket"
+ loc <- liftIO $ getBucketLocation conn bucket
+ case loc of
+ Right _ -> writeUUIDFile c u
+ Left err@(NetworkError _) -> s3Error err
+ Left (AWSError _ _) -> do
+ showAction $ "creating bucket in " ++ datacenter
+ res <- liftIO $ createBucketIn conn bucket datacenter
+ case res of
+ Right _ -> writeUUIDFile c u
+ Left err -> s3Error err
+ where
+ bucket = fromJust $ getBucket c
+ datacenter = fromJust $ M.lookup "datacenter" c
+
+{- Writes the UUID to an annex-uuid file within the bucket.
+ -
+ - If the file already exists in the bucket, it must match.
+ -
+ - Note that IA items do not get created by createBucketIn.
+ - Rather, they are created the first time a file is stored in them.
+ - So this also takes care of that.
+ -}
+writeUUIDFile :: RemoteConfig -> UUID -> Annex ()
+writeUUIDFile c u = do
+ conn <- s3ConnectionRequired c u
+ go conn =<< liftIO (tryNonAsync $ getObject conn $ mkobject L.empty)
+ where
+ go _conn (Right (Right o)) = unless (obj_data o == uuidb) $
+ error $ "This bucket is already in use by a different S3 special remote, with UUID: " ++ L.unpack (obj_data o)
+ go conn _ = do
+ let object = setStorageClass (getStorageClass c) (mkobject uuidb)
+ either s3Error return =<< liftIO (sendObject conn object)
+
+ file = filePrefix c ++ "annex-uuid"
+ uuidb = L.pack $ fromUUID u
+ bucket = fromJust $ getBucket c
+
+ mkobject = S3Object bucket file "" (getXheaders c)
+
+s3ConnectionRequired :: RemoteConfig -> UUID -> Annex AWSConnection
+s3ConnectionRequired c u =
+ maybe (error "Cannot connect to S3") return =<< s3Connection c u
+
+s3Connection :: RemoteConfig -> UUID -> Annex (Maybe AWSConnection)
+s3Connection c u = go =<< getRemoteCredPairFor "S3" c (AWS.creds u)
+ where
+ go Nothing = return Nothing
+ go (Just (ak, sk)) = return $ Just $ AWSConnection host port ak sk
+
+ host = fromJust $ M.lookup "host" c
+ port = let s = fromJust $ M.lookup "port" c in
+ case reads s of
+ [(p, _)] -> p
+ _ -> error $ "bad S3 port value: " ++ s
+
+getBucket :: RemoteConfig -> Maybe Bucket
+getBucket = M.lookup "bucket"
+
+getStorageClass :: RemoteConfig -> StorageClass
+getStorageClass c = case fromJust $ M.lookup "storageclass" c of
+ "REDUCED_REDUNDANCY" -> REDUCED_REDUNDANCY
+ _ -> STANDARD
+
+getXheaders :: RemoteConfig -> [(String, String)]
+getXheaders = filter isxheader . M.assocs
+ where
+ isxheader (h, _) = "x-amz-" `isPrefixOf` h
+
+{- Hostname to use for archive.org S3. -}
+iaHost :: HostName
+iaHost = "s3.us.archive.org"
+
+isIA :: RemoteConfig -> Bool
+isIA c = maybe False isIAHost (M.lookup "host" c)
+
+isIAHost :: HostName -> Bool
+isIAHost h = ".archive.org" `isSuffixOf` map toLower h
+
+iaItemUrl :: Bucket -> URLString
+iaItemUrl bucket = "http://archive.org/details/" ++ bucket
+
+iaKeyUrl :: Remote -> Key -> URLString
+iaKeyUrl r k = "http://archive.org/download/" ++ bucket ++ "/" ++ bucketFile r k
+ where
+ bucket = fromMaybe "" $ getBucket $ config r
diff --git a/Remote/Web.hs b/Remote/Web.hs
new file mode 100644
index 000000000..0a8df35d5
--- /dev/null
+++ b/Remote/Web.hs
@@ -0,0 +1,128 @@
+{- Web remotes.
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Remote.Web (remote) where
+
+import Common.Annex
+import Types.Remote
+import qualified Git
+import qualified Git.Construct
+import Annex.Content
+import Config
+import Config.Cost
+import Logs.Web
+import Types.Key
+import Utility.Metered
+import qualified Annex.Url as Url
+#ifdef WITH_QUVI
+import Annex.Quvi
+import qualified Utility.Quvi as Quvi
+#endif
+
+remote :: RemoteType
+remote = RemoteType {
+ typename = "web",
+ enumerate = list,
+ generate = gen,
+ setup = error "not supported"
+}
+
+-- There is only one web remote, and it always exists.
+-- (If the web should cease to exist, remove this module and redistribute
+-- a new release to the survivors by carrier pigeon.)
+list :: Annex [Git.Repo]
+list = do
+ r <- liftIO $ Git.Construct.remoteNamed "web" Git.Construct.fromUnknown
+ return [r]
+
+gen :: Git.Repo -> UUID -> RemoteConfig -> RemoteGitConfig -> Annex (Maybe Remote)
+gen r _ c gc =
+ return $ Just Remote {
+ uuid = webUUID,
+ cost = expensiveRemoteCost,
+ name = Git.repoDescribe r,
+ storeKey = uploadKey,
+ retrieveKeyFile = downloadKey,
+ retrieveKeyFileCheap = downloadKeyCheap,
+ removeKey = dropKey,
+ hasKey = checkKey,
+ hasKeyCheap = False,
+ whereisKey = Just getUrls,
+ remoteFsck = Nothing,
+ repairRepo = Nothing,
+ config = c,
+ gitconfig = gc,
+ localpath = Nothing,
+ repo = r,
+ readonly = True,
+ globallyAvailable = True,
+ remotetype = remote
+ }
+
+downloadKey :: Key -> AssociatedFile -> FilePath -> MeterUpdate -> Annex Bool
+downloadKey key _file dest _p = get =<< getUrls key
+ where
+ get [] = do
+ warning "no known url"
+ return False
+ get urls = do
+ showOutput -- make way for download progress bar
+ untilTrue urls $ \u -> do
+ let (u', downloader) = getDownloader u
+ case downloader of
+ QuviDownloader -> do
+#ifdef WITH_QUVI
+ flip downloadUrl dest
+ =<< withQuviOptions Quvi.queryLinks [Quvi.httponly, Quvi.quiet] u'
+#else
+ warning "quvi support needed for this url"
+ return False
+#endif
+ DefaultDownloader -> downloadUrl [u'] dest
+
+downloadKeyCheap :: Key -> FilePath -> Annex Bool
+downloadKeyCheap _ _ = return False
+
+uploadKey :: Key -> AssociatedFile -> MeterUpdate -> Annex Bool
+uploadKey _ _ _ = do
+ warning "upload to web not supported"
+ return False
+
+dropKey :: Key -> Annex Bool
+dropKey k = do
+ mapM_ (setUrlMissing k) =<< getUrls k
+ return True
+
+checkKey :: Key -> Annex (Either String Bool)
+checkKey key = do
+ us <- getUrls key
+ if null us
+ then return $ Right False
+ else return =<< checkKey' key us
+checkKey' :: Key -> [URLString] -> Annex (Either String Bool)
+checkKey' key us = firsthit us (Right False) $ \u -> do
+ let (u', downloader) = getDownloader u
+ showAction $ "checking " ++ u'
+ case downloader of
+ QuviDownloader ->
+#ifdef WITH_QUVI
+ Right <$> withQuviOptions Quvi.check [Quvi.httponly, Quvi.quiet] u'
+#else
+ return $ Left "quvi support needed for this url"
+#endif
+ DefaultDownloader -> do
+ headers <- getHttpHeaders
+ Right <$> Url.withUserAgent (Url.checkBoth u' headers $ keySize key)
+ where
+ firsthit [] miss _ = return miss
+ firsthit (u:rest) _ a = do
+ r <- a u
+ case r of
+ Right _ -> return r
+ Left _ -> firsthit rest r a
diff --git a/Remote/WebDAV.hs b/Remote/WebDAV.hs
new file mode 100644
index 000000000..738dbde3f
--- /dev/null
+++ b/Remote/WebDAV.hs
@@ -0,0 +1,356 @@
+{- WebDAV remotes.
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE ScopedTypeVariables, CPP #-}
+
+module Remote.WebDAV (remote, davCreds, setCredsEnv, configUrl) where
+
+import Network.Protocol.HTTP.DAV
+import qualified Data.Map as M
+import qualified Data.ByteString.UTF8 as B8
+import qualified Data.ByteString.Lazy.UTF8 as L8
+import qualified Data.ByteString.Lazy as L
+import Network.URI (normalizePathSegments)
+import qualified Control.Exception as E
+import Network.HTTP.Conduit (HttpException(..))
+import Network.HTTP.Types
+import System.IO.Error
+
+import Common.Annex
+import Types.Remote
+import qualified Git
+import Config
+import Config.Cost
+import Remote.Helper.Special
+import Remote.Helper.Encryptable
+import Remote.Helper.Chunked
+import Crypto
+import Creds
+import Utility.Metered
+import Annex.Content
+import Annex.UUID
+
+type DavUrl = String
+type DavUser = B8.ByteString
+type DavPass = B8.ByteString
+
+remote :: RemoteType
+remote = RemoteType {
+ typename = "webdav",
+ enumerate = findSpecialRemotes "webdav",
+ generate = gen,
+ setup = webdavSetup
+}
+
+gen :: Git.Repo -> UUID -> RemoteConfig -> RemoteGitConfig -> Annex (Maybe Remote)
+gen r u c gc = new <$> remoteCost gc expensiveRemoteCost
+ where
+ new cst = Just $ encryptableRemote c
+ (storeEncrypted this)
+ (retrieveEncrypted this)
+ this
+ where
+ this = Remote {
+ uuid = u,
+ cost = cst,
+ name = Git.repoDescribe r,
+ storeKey = store this,
+ retrieveKeyFile = retrieve this,
+ retrieveKeyFileCheap = retrieveCheap this,
+ removeKey = remove this,
+ hasKey = checkPresent this,
+ hasKeyCheap = False,
+ whereisKey = Nothing,
+ remoteFsck = Nothing,
+ repairRepo = Nothing,
+ config = c,
+ repo = r,
+ gitconfig = gc,
+ localpath = Nothing,
+ readonly = False,
+ globallyAvailable = True,
+ remotetype = remote
+ }
+
+webdavSetup :: Maybe UUID -> RemoteConfig -> Annex (RemoteConfig, UUID)
+webdavSetup mu c = do
+ u <- maybe (liftIO genUUID) return mu
+ let url = fromMaybe (error "Specify url=") $
+ M.lookup "url" c
+ c' <- encryptionSetup c
+ creds <- getCreds c' u
+ testDav url creds
+ gitConfigSpecialRemote u c' "webdav" "true"
+ c'' <- setRemoteCredPair c' (davCreds u)
+ return (c'', u)
+
+store :: Remote -> Key -> AssociatedFile -> MeterUpdate -> Annex Bool
+store r k _f p = metered (Just p) k $ \meterupdate ->
+ davAction r False $ \(baseurl, user, pass) ->
+ sendAnnex k (void $ remove r k) $ \src ->
+ liftIO $ withMeteredFile src meterupdate $
+ storeHelper r k baseurl user pass
+
+storeEncrypted :: Remote -> (Cipher, Key) -> Key -> MeterUpdate -> Annex Bool
+storeEncrypted r (cipher, enck) k p = metered (Just p) k $ \meterupdate ->
+ davAction r False $ \(baseurl, user, pass) ->
+ sendAnnex k (void $ remove r enck) $ \src ->
+ liftIO $ encrypt (getGpgEncParams r) cipher
+ (streamMeteredFile src meterupdate) $
+ readBytes $ storeHelper r enck baseurl user pass
+
+storeHelper :: Remote -> Key -> DavUrl -> DavUser -> DavPass -> L.ByteString -> IO Bool
+storeHelper r k baseurl user pass b = catchBoolIO $ do
+ davMkdir tmpurl user pass
+ storeChunks k tmpurl keyurl chunksize storer recorder finalizer
+ where
+ tmpurl = tmpLocation baseurl k
+ keyurl = davLocation baseurl k
+ chunksize = chunkSize $ config r
+ storer urls = storeChunked chunksize urls storehttp b
+ recorder url s = storehttp url (L8.fromString s)
+ finalizer srcurl desturl = do
+ void $ catchMaybeHttp (deleteContent desturl user pass)
+ davMkdir (urlParent desturl) user pass
+ moveContent srcurl (B8.fromString desturl) user pass
+ storehttp url v = putContent url user pass
+ (contentType, v)
+
+retrieveCheap :: Remote -> Key -> FilePath -> Annex Bool
+retrieveCheap _ _ _ = return False
+
+retrieve :: Remote -> Key -> AssociatedFile -> FilePath -> MeterUpdate -> Annex Bool
+retrieve r k _f d p = metered (Just p) k $ \meterupdate ->
+ davAction r False $ \(baseurl, user, pass) -> liftIO $ catchBoolIO $
+ withStoredFiles r k baseurl user pass onerr $ \urls -> do
+ meteredWriteFileChunks meterupdate d urls $ \url -> do
+ mb <- davGetUrlContent url user pass
+ case mb of
+ Nothing -> throwIO "download failed"
+ Just b -> return b
+ return True
+ where
+ onerr _ = return False
+
+retrieveEncrypted :: Remote -> (Cipher, Key) -> Key -> FilePath -> MeterUpdate -> Annex Bool
+retrieveEncrypted r (cipher, enck) k d p = metered (Just p) k $ \meterupdate ->
+ davAction r False $ \(baseurl, user, pass) -> liftIO $ catchBoolIO $
+ withStoredFiles r enck baseurl user pass onerr $ \urls -> do
+ decrypt cipher (feeder user pass urls) $
+ readBytes $ meteredWriteFile meterupdate d
+ return True
+ where
+ onerr _ = return False
+
+ feeder _ _ [] _ = noop
+ feeder user pass (url:urls) h = do
+ mb <- davGetUrlContent url user pass
+ case mb of
+ Nothing -> throwIO "download failed"
+ Just b -> do
+ L.hPut h b
+ feeder user pass urls h
+
+remove :: Remote -> Key -> Annex Bool
+remove r k = davAction r False $ \(baseurl, user, pass) -> liftIO $ do
+ -- Delete the key's whole directory, including any chunked
+ -- files, etc, in a single action.
+ let url = davLocation baseurl k
+ isJust <$> catchMaybeHttp (deleteContent url user pass)
+
+checkPresent :: Remote -> Key -> Annex (Either String Bool)
+checkPresent r k = davAction r noconn go
+ where
+ noconn = Left $ error $ name r ++ " not configured"
+
+ go (baseurl, user, pass) = do
+ showAction $ "checking " ++ name r
+ liftIO $ withStoredFiles r k baseurl user pass onerr check
+ where
+ check [] = return $ Right True
+ check (url:urls) = do
+ v <- davUrlExists url user pass
+ if v == Right True
+ then check urls
+ else return v
+
+ {- Failed to read the chunkcount file; see if it's missing,
+ - or if there's a problem accessing it,
+ - or perhaps this was an intermittent error. -}
+ onerr url = do
+ v <- davUrlExists url user pass
+ return $ if v == Right True
+ then Left $ "failed to read " ++ url
+ else v
+
+withStoredFiles
+ :: Remote
+ -> Key
+ -> DavUrl
+ -> DavUser
+ -> DavPass
+ -> (DavUrl -> IO a)
+ -> ([DavUrl] -> IO a)
+ -> IO a
+withStoredFiles r k baseurl user pass onerr a
+ | isJust $ chunkSize $ config r = do
+ let chunkcount = keyurl ++ chunkCount
+ v <- davGetUrlContent chunkcount user pass
+ case v of
+ Just s -> a $ listChunks keyurl $ L8.toString s
+ Nothing -> do
+ chunks <- probeChunks keyurl $ \u -> (== Right True) <$> davUrlExists u user pass
+ if null chunks
+ then onerr chunkcount
+ else a chunks
+ | otherwise = a [keyurl]
+ where
+ keyurl = davLocation baseurl k ++ keyFile k
+
+davAction :: Remote -> a -> ((DavUrl, DavUser, DavPass) -> Annex a) -> Annex a
+davAction r unconfigured action = do
+ mcreds <- getCreds (config r) (uuid r)
+ case (mcreds, configUrl r) of
+ (Just (user, pass), Just url) ->
+ action (url, toDavUser user, toDavPass pass)
+ _ -> return unconfigured
+
+configUrl :: Remote -> Maybe DavUrl
+configUrl r = M.lookup "url" $ config r
+
+toDavUser :: String -> DavUser
+toDavUser = B8.fromString
+
+toDavPass :: String -> DavPass
+toDavPass = B8.fromString
+
+{- The directory where files(s) for a key are stored. -}
+davLocation :: DavUrl -> Key -> DavUrl
+davLocation baseurl k = addTrailingPathSeparator $
+ davUrl baseurl $ hashDirLower k </> keyFile k
+
+{- Where we store temporary data for a key as it's being uploaded. -}
+tmpLocation :: DavUrl -> Key -> DavUrl
+tmpLocation baseurl k = addTrailingPathSeparator $
+ davUrl baseurl $ "tmp" </> keyFile k
+
+davUrl :: DavUrl -> FilePath -> DavUrl
+davUrl baseurl file = baseurl </> file
+
+davUrlExists :: DavUrl -> DavUser -> DavPass -> IO (Either String Bool)
+davUrlExists url user pass = decode <$> catchHttp get
+ where
+ decode (Right _) = Right True
+#if ! MIN_VERSION_http_conduit(1,9,0)
+ decode (Left (Left (StatusCodeException status _)))
+#else
+ decode (Left (Left (StatusCodeException status _ _)))
+#endif
+ | statusCode status == statusCode notFound404 = Right False
+ decode (Left e) = Left $ showEitherException e
+#if ! MIN_VERSION_DAV(0,4,0)
+ get = getProps url user pass
+#else
+ get = getProps url user pass Nothing
+#endif
+
+davGetUrlContent :: DavUrl -> DavUser -> DavPass -> IO (Maybe L.ByteString)
+davGetUrlContent url user pass = fmap (snd . snd) <$>
+ catchMaybeHttp (getPropsAndContent url user pass)
+
+{- Creates a directory in WebDAV, if not already present; also creating
+ - any missing parent directories. -}
+davMkdir :: DavUrl -> DavUser -> DavPass -> IO ()
+davMkdir url user pass = go url
+ where
+ make u = makeCollection u user pass
+
+ go u = do
+ r <- E.try (make u) :: IO (Either E.SomeException Bool)
+ case r of
+ {- Parent directory is missing. Recurse to create
+ - it, and try once more to create the directory. -}
+ Right False -> do
+ go (urlParent u)
+ void $ make u
+ {- Directory created successfully -}
+ Right True -> return ()
+ {- Directory already exists, or some other error
+ - occurred. In the latter case, whatever wanted
+ - to use this directory will fail. -}
+ Left _ -> return ()
+
+{- Catches HTTP and IO exceptions. -}
+catchMaybeHttp :: IO a -> IO (Maybe a)
+catchMaybeHttp a = (Just <$> a) `E.catches`
+ [ E.Handler $ \(_e :: HttpException) -> return Nothing
+ , E.Handler $ \(_e :: E.IOException) -> return Nothing
+ ]
+
+{- Catches HTTP and IO exceptions -}
+catchHttp :: IO a -> IO (Either EitherException a)
+catchHttp a = (Right <$> a) `E.catches`
+ [ E.Handler $ \(e :: HttpException) -> return $ Left $ Left e
+ , E.Handler $ \(e :: E.IOException) -> return $ Left $ Right e
+ ]
+
+type EitherException = Either HttpException E.IOException
+
+showEitherException :: EitherException -> String
+#if ! MIN_VERSION_http_conduit(1,9,0)
+showEitherException (Left (StatusCodeException status _)) =
+#else
+showEitherException (Left (StatusCodeException status _ _)) =
+#endif
+ show $ statusMessage status
+showEitherException (Left httpexception) = show httpexception
+showEitherException (Right ioexception) = show ioexception
+
+throwIO :: String -> IO a
+throwIO msg = ioError $ mkIOError userErrorType msg Nothing Nothing
+
+urlParent :: DavUrl -> DavUrl
+urlParent url = dropTrailingPathSeparator $
+ normalizePathSegments (dropTrailingPathSeparator url ++ "/..")
+ where
+
+{- Test if a WebDAV store is usable, by writing to a test file, and then
+ - deleting the file. Exits with an IO error if not. -}
+testDav :: String -> Maybe CredPair -> Annex ()
+testDav baseurl (Just (u, p)) = do
+ showSideAction "testing WebDAV server"
+ test "make directory" $ davMkdir baseurl user pass
+ test "write file" $ putContent testurl user pass
+ (contentType, L.empty)
+ test "delete file" $ deleteContent testurl user pass
+ where
+ test desc a = liftIO $
+ either (\e -> throwIO $ "WebDAV failed to " ++ desc ++ ": " ++ showEitherException e)
+ (const noop)
+ =<< catchHttp a
+
+ user = toDavUser u
+ pass = toDavPass p
+ testurl = davUrl baseurl "git-annex-test"
+testDav _ Nothing = error "Need to configure webdav username and password."
+
+{- Content-Type to use for files uploaded to WebDAV. -}
+contentType :: Maybe B8.ByteString
+contentType = Just $ B8.fromString "application/octet-stream"
+
+getCreds :: RemoteConfig -> UUID -> Annex (Maybe CredPair)
+getCreds c u = getRemoteCredPairFor "webdav" c (davCreds u)
+
+davCreds :: UUID -> CredPairStorage
+davCreds u = CredPairStorage
+ { credPairFile = fromUUID u
+ , credPairEnvironment = ("WEBDAV_USERNAME", "WEBDAV_PASSWORD")
+ , credPairRemoteKey = Just "davcreds"
+ }
+
+setCredsEnv :: (String, String) -> IO ()
+setCredsEnv creds = setEnvCredPair creds $ davCreds undefined
diff --git a/Seek.hs b/Seek.hs
new file mode 100644
index 000000000..b2782fc36
--- /dev/null
+++ b/Seek.hs
@@ -0,0 +1,178 @@
+{- git-annex command seeking
+ -
+ - These functions find appropriate files or other things based on
+ - the values a user passes to a command, and prepare actions operating
+ - on them.
+ -
+ - Copyright 2010-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Seek where
+
+import System.PosixCompat.Files
+
+import Common.Annex
+import Types.Command
+import Types.Key
+import Types.FileMatcher
+import qualified Annex
+import qualified Git
+import qualified Git.Command
+import qualified Git.LsFiles as LsFiles
+import qualified Limit
+import qualified Option
+import Config
+import Logs.Location
+import Logs.Unused
+import Annex.CatFile
+
+seekHelper :: ([FilePath] -> Git.Repo -> IO ([FilePath], IO Bool)) -> [FilePath] -> Annex [FilePath]
+seekHelper a params = do
+ ll <- inRepo $ \g ->
+ runSegmentPaths (\fs -> Git.Command.leaveZombie <$> a fs g) params
+ {- Show warnings only for files/directories that do not exist. -}
+ forM_ (map fst $ filter (null . snd) $ zip params ll) $ \p ->
+ unlessM (isJust <$> liftIO (catchMaybeIO $ getSymbolicLinkStatus p)) $
+ fileNotFound p
+ return $ concat ll
+
+withFilesInGit :: (FilePath -> CommandStart) -> CommandSeek
+withFilesInGit a params = prepFiltered a $ seekHelper LsFiles.inRepo params
+
+withFilesNotInGit :: (FilePath -> CommandStart) -> CommandSeek
+withFilesNotInGit a params = do
+ {- dotfiles are not acted on unless explicitly listed -}
+ files <- filter (not . dotfile) <$>
+ seekunless (null ps && not (null params)) ps
+ dotfiles <- seekunless (null dotps) dotps
+ prepFiltered a $ return $ concat $ segmentPaths params (files++dotfiles)
+ where
+ (dotps, ps) = partition dotfile params
+ seekunless True _ = return []
+ seekunless _ l = do
+ force <- Annex.getState Annex.force
+ g <- gitRepo
+ liftIO $ Git.Command.leaveZombie <$> LsFiles.notInRepo force l g
+
+withPathContents :: ((FilePath, FilePath) -> CommandStart) -> CommandSeek
+withPathContents a params = map a . concat <$> liftIO (mapM get params)
+ where
+ get p = ifM (isDirectory <$> getFileStatus p)
+ ( map (\f -> (f, makeRelative (parentDir p) f))
+ <$> dirContentsRecursiveSkipping (".git" `isSuffixOf`) p
+ , return [(p, takeFileName p)]
+ )
+
+withWords :: ([String] -> CommandStart) -> CommandSeek
+withWords a params = return [a params]
+
+withStrings :: (String -> CommandStart) -> CommandSeek
+withStrings a params = return $ map a params
+
+withPairs :: ((String, String) -> CommandStart) -> CommandSeek
+withPairs a params = return $ map a $ pairs [] params
+ where
+ pairs c [] = reverse c
+ pairs c (x:y:xs) = pairs ((x,y):c) xs
+ pairs _ _ = error "expected pairs"
+
+withFilesToBeCommitted :: (String -> CommandStart) -> CommandSeek
+withFilesToBeCommitted a params = prepFiltered a $
+ seekHelper LsFiles.stagedNotDeleted params
+
+withFilesUnlocked :: (FilePath -> CommandStart) -> CommandSeek
+withFilesUnlocked = withFilesUnlocked' LsFiles.typeChanged
+
+withFilesUnlockedToBeCommitted :: (FilePath -> CommandStart) -> CommandSeek
+withFilesUnlockedToBeCommitted = withFilesUnlocked' LsFiles.typeChangedStaged
+
+{- Unlocked files have changed type from a symlink to a regular file.
+ -
+ - Furthermore, unlocked files used to be a git-annex symlink,
+ - not some other sort of symlink.
+ -}
+withFilesUnlocked' :: ([FilePath] -> Git.Repo -> IO ([FilePath], IO Bool)) -> (FilePath -> CommandStart) -> CommandSeek
+withFilesUnlocked' typechanged a params = prepFiltered a unlockedfiles
+ where
+ check f = liftIO (notSymlink f) <&&>
+ (isJust <$> catKeyFile f <||> isJust <$> catKeyFileHEAD f)
+ unlockedfiles = filterM check =<< seekHelper typechanged params
+
+{- Finds files that may be modified. -}
+withFilesMaybeModified :: (FilePath -> CommandStart) -> CommandSeek
+withFilesMaybeModified a params =
+ prepFiltered a $ seekHelper LsFiles.modified params
+
+withKeys :: (Key -> CommandStart) -> CommandSeek
+withKeys a params = return $ map (a . parse) params
+ where
+ parse p = fromMaybe (error "bad key") $ file2key p
+
+withValue :: Annex v -> (v -> CommandSeek) -> CommandSeek
+withValue v a params = do
+ r <- v
+ a r params
+
+{- Modifies a seek action using the value of a field option, which is fed into
+ - a conversion function, and then is passed into the seek action.
+ - This ensures that the conversion function only runs once.
+ -}
+withField :: Option -> (Maybe String -> Annex a) -> (a -> CommandSeek) -> CommandSeek
+withField option converter = withValue $
+ converter <=< Annex.getField $ Option.name option
+
+withFlag :: Option -> (Bool -> CommandSeek) -> CommandSeek
+withFlag option = withValue $ Annex.getFlag (Option.name option)
+
+withNothing :: CommandStart -> CommandSeek
+withNothing a [] = return [a]
+withNothing _ _ = error "This command takes no parameters."
+
+{- If --all is specified, or in a bare repo, runs an action on all
+ - known keys.
+ -
+ - If --unused is specified, runs an action on all keys found by
+ - the last git annex unused scan.
+ -
+ - Otherwise, fall back to a regular CommandSeek action on
+ - whatever params were passed. -}
+withKeyOptions :: (Key -> CommandStart) -> CommandSeek -> CommandSeek
+withKeyOptions keyop fallbackop params = do
+ bare <- fromRepo Git.repoIsLocalBare
+ allkeys <- Annex.getFlag "all"
+ unused <- Annex.getFlag "unused"
+ auto <- Annex.getState Annex.auto
+ case (allkeys || bare , unused, auto ) of
+ (True , False , False) -> go loggedKeys
+ (False , True , False) -> go unusedKeys
+ (True , True , _ )
+ | bare && not allkeys -> go unusedKeys
+ | otherwise -> error "Cannot use --all with --unused."
+ (False , False , _ ) -> fallbackop params
+ (_ , _ , True )
+ | bare -> error "Cannot use --auto in a bare repository."
+ | otherwise -> error "Cannot use --auto with --all or --unused."
+ where
+ go a = do
+ unless (null params) $
+ error "Cannot mix --all or --unused with file names."
+ map keyop <$> a
+
+prepFiltered :: (FilePath -> CommandStart) -> Annex [FilePath] -> Annex [CommandStart]
+prepFiltered a fs = do
+ matcher <- Limit.getMatcher
+ map (process matcher) <$> fs
+ where
+ process matcher f = ifM (matcher $ FileInfo f f)
+ ( a f , return Nothing )
+
+notSymlink :: FilePath -> IO Bool
+notSymlink f = liftIO $ not . isSymbolicLink <$> getSymbolicLinkStatus f
+
+whenNotDirect :: CommandSeek -> CommandSeek
+whenNotDirect a params = ifM isDirect ( return [] , a params )
+
+whenDirect :: CommandSeek -> CommandSeek
+whenDirect a params = ifM isDirect ( a params, return [] )
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
index 000000000..0a187bd95
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,63 @@
+{-# LANGUAGE NamedFieldPuns #-}
+
+{- cabal setup file -}
+
+import Distribution.Simple
+import Distribution.Simple.LocalBuildInfo
+import Distribution.Simple.Setup
+import Distribution.Simple.Utils (installOrdinaryFiles, rawSystemExit)
+import Distribution.PackageDescription (PackageDescription(..))
+import Distribution.Verbosity (Verbosity)
+import System.FilePath
+import Control.Applicative
+import Control.Monad
+import System.Directory
+
+import qualified Build.DesktopFile as DesktopFile
+import qualified Build.Configure as Configure
+
+main = defaultMainWithHooks simpleUserHooks
+ { preConf = configure
+ , postInst = myPostInst
+ }
+
+configure _ _ = do
+ Configure.run Configure.tests
+ return (Nothing, [])
+
+myPostInst :: Args -> InstallFlags -> PackageDescription -> LocalBuildInfo -> IO ()
+myPostInst _ (InstallFlags { installVerbosity }) pkg lbi = do
+ installGitAnnexShell dest verbosity pkg lbi
+ installManpages dest verbosity pkg lbi
+ installDesktopFile dest verbosity pkg lbi
+ where
+ dest = NoCopyDest
+ verbosity = fromFlag installVerbosity
+
+installGitAnnexShell :: CopyDest -> Verbosity -> PackageDescription -> LocalBuildInfo -> IO ()
+installGitAnnexShell copyDest verbosity pkg lbi =
+ rawSystemExit verbosity "ln"
+ ["-sf", "git-annex", dstBinDir </> "git-annex-shell"]
+ where
+ dstBinDir = bindir $ absoluteInstallDirs pkg lbi copyDest
+
+{- See http://www.haskell.org/haskellwiki/Cabal/Developer-FAQ#Installing_manpages
+ -
+ - Man pages are provided prebuilt in the tarball in cabal,
+ - but may not be available otherwise, in which case, skip installing them.
+ -}
+installManpages :: CopyDest -> Verbosity -> PackageDescription -> LocalBuildInfo -> IO ()
+installManpages copyDest verbosity pkg lbi =
+ installOrdinaryFiles verbosity dstManDir =<< srcManpages
+ where
+ dstManDir = mandir (absoluteInstallDirs pkg lbi copyDest) </> "man1"
+ srcManpages = zip (repeat srcManDir)
+ <$> filterM doesFileExist manpages
+ srcManDir = ""
+ manpages = ["git-annex.1", "git-annex-shell.1"]
+
+installDesktopFile :: CopyDest -> Verbosity -> PackageDescription -> LocalBuildInfo -> IO ()
+installDesktopFile copyDest verbosity pkg lbi =
+ DesktopFile.install $ dstBinDir </> "git-annex"
+ where
+ dstBinDir = bindir $ absoluteInstallDirs pkg lbi copyDest
diff --git a/Test.hs b/Test.hs
new file mode 100644
index 000000000..4c7281fce
--- /dev/null
+++ b/Test.hs
@@ -0,0 +1,1331 @@
+{- git-annex test suite
+ -
+ - Copyright 2010-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Test where
+
+import Test.Tasty
+import Test.Tasty.Runners
+import Test.Tasty.HUnit
+import Test.Tasty.QuickCheck
+
+import System.PosixCompat.Files
+import Control.Exception.Extensible
+import Data.Monoid
+import qualified Data.Map as M
+import System.IO.HVFS (SystemFS(..))
+import qualified Text.JSON
+import System.Path
+
+import Common
+
+import qualified Utility.SafeCommand
+import qualified Annex
+import qualified Annex.UUID
+import qualified Backend
+import qualified Git.CurrentRepo
+import qualified Git.Filename
+import qualified Locations
+import qualified Types.KeySource
+import qualified Types.Backend
+import qualified Types.TrustLevel
+import qualified Types
+import qualified Logs
+import qualified Logs.UUIDBased
+import qualified Logs.Trust
+import qualified Logs.Remote
+import qualified Logs.Unused
+import qualified Logs.Transfer
+import qualified Logs.Presence
+import qualified Remote
+import qualified Types.Key
+import qualified Types.Messages
+import qualified Config
+import qualified Config.Cost
+import qualified Crypto
+import qualified Init
+import qualified Utility.Path
+import qualified Utility.FileMode
+import qualified Build.SysConfig
+import qualified Utility.Format
+import qualified Utility.Verifiable
+import qualified Utility.Process
+import qualified Utility.Misc
+import qualified Utility.InodeCache
+import qualified Utility.Env
+import qualified Utility.Matcher
+import qualified Utility.Exception
+import qualified Utility.Hash
+import qualified Utility.Scheduled
+import qualified Utility.HumanTime
+#ifndef mingw32_HOST_OS
+import qualified GitAnnex
+import qualified Remote.Helper.Encryptable
+import qualified Types.Crypto
+import qualified Utility.Gpg
+#endif
+
+type TestEnv = M.Map String String
+
+main :: IO ()
+main = do
+#ifndef mingw32_HOST_OS
+ indirectenv <- prepare False
+ directenv <- prepare True
+ let tests = testGroup "Tests"
+ [ localOption (QuickCheckTests 1000) properties
+ , unitTests directenv "(direct)"
+ , unitTests indirectenv "(indirect)"
+ ]
+#else
+ -- Windows is only going to use direct mode, so don't test twice.
+ env <- prepare False
+ let tests = testGroup "Tests"
+ [properties, unitTests env ""]
+#endif
+ let runner = tryIngredients [consoleTestReporter] mempty tests
+ ifM (maybe (error "tasty failed to return a runner!") id runner)
+ ( exitSuccess
+ , do
+ putStrLn " (This could be due to a bug in git-annex, or an incompatability"
+ putStrLn " with utilities, such as git, installed on this system.)"
+ exitFailure
+ )
+
+properties :: TestTree
+properties = testGroup "QuickCheck"
+ [ testProperty "prop_idempotent_deencode_git" Git.Filename.prop_idempotent_deencode
+ , testProperty "prop_idempotent_deencode" Utility.Format.prop_idempotent_deencode
+ , testProperty "prop_idempotent_fileKey" Locations.prop_idempotent_fileKey
+ , testProperty "prop_idempotent_key_encode" Types.Key.prop_idempotent_key_encode
+ , testProperty "prop_idempotent_key_decode" Types.Key.prop_idempotent_key_decode
+ , testProperty "prop_idempotent_shellEscape" Utility.SafeCommand.prop_idempotent_shellEscape
+ , testProperty "prop_idempotent_shellEscape_multiword" Utility.SafeCommand.prop_idempotent_shellEscape_multiword
+ , testProperty "prop_logs_sane" Logs.prop_logs_sane
+ , testProperty "prop_idempotent_configEscape" Logs.Remote.prop_idempotent_configEscape
+ , testProperty "prop_parse_show_Config" Logs.Remote.prop_parse_show_Config
+ , testProperty "prop_parentDir_basics" Utility.Path.prop_parentDir_basics
+ , testProperty "prop_relPathDirToFile_basics" Utility.Path.prop_relPathDirToFile_basics
+ , testProperty "prop_relPathDirToFile_regressionTest" Utility.Path.prop_relPathDirToFile_regressionTest
+ , testProperty "prop_cost_sane" Config.Cost.prop_cost_sane
+ , testProperty "prop_matcher_sane" Utility.Matcher.prop_matcher_sane
+ , testProperty "prop_HmacSha1WithCipher_sane" Crypto.prop_HmacSha1WithCipher_sane
+ , testProperty "prop_TimeStamp_sane" Logs.UUIDBased.prop_TimeStamp_sane
+ , testProperty "prop_addLog_sane" Logs.UUIDBased.prop_addLog_sane
+ , testProperty "prop_verifiable_sane" Utility.Verifiable.prop_verifiable_sane
+ , testProperty "prop_segment_regressionTest" Utility.Misc.prop_segment_regressionTest
+ , testProperty "prop_read_write_transferinfo" Logs.Transfer.prop_read_write_transferinfo
+ , testProperty "prop_read_show_inodecache" Utility.InodeCache.prop_read_show_inodecache
+ , testProperty "prop_parse_show_log" Logs.Presence.prop_parse_show_log
+ , testProperty "prop_read_show_TrustLevel" Types.TrustLevel.prop_read_show_TrustLevel
+ , testProperty "prop_parse_show_TrustLog" Logs.Trust.prop_parse_show_TrustLog
+ , testProperty "prop_hashes_stable" Utility.Hash.prop_hashes_stable
+ , testProperty "prop_schedule_roundtrips" Utility.Scheduled.prop_schedule_roundtrips
+ , testProperty "prop_duration_roundtrips" Utility.HumanTime.prop_duration_roundtrips
+ ]
+
+unitTests :: TestEnv -> String -> TestTree
+unitTests env note = testGroup ("Unit Tests " ++ note)
+ -- test order matters, later tests may rely on state from earlier
+ [ check "init" test_init
+ , check "add" test_add
+ , check "add sha1dup" test_add_sha1dup
+ , check "add subdirs" test_add_subdirs
+ , check "reinject" test_reinject
+ , check "unannex (no copy)" test_unannex_nocopy
+ , check "unannex (with copy)" test_unannex_withcopy
+ , check "drop (no remote)" test_drop_noremote
+ , check "drop (with remote)" test_drop_withremote
+ , check "drop (untrusted remote)" test_drop_untrustedremote
+ , check "get" test_get
+ , check "move" test_move
+ , check "copy" test_copy
+ , check "lock" test_lock
+ , check "edit (no pre-commit)" test_edit
+ , check "edit (pre-commit)" test_edit_precommit
+ , check "fix" test_fix
+ , check "trust" test_trust
+ , check "fsck (basics)" test_fsck_basic
+ , check "fsck (bare)" test_fsck_bare
+ , check "fsck (local untrusted)" test_fsck_localuntrusted
+ , check "fsck (remote untrusted)" test_fsck_remoteuntrusted
+ , check "migrate" test_migrate
+ , check "migrate (via gitattributes)" test_migrate_via_gitattributes
+ , check" unused" test_unused
+ , check "describe" test_describe
+ , check "find" test_find
+ , check "merge" test_merge
+ , check "info" test_info
+ , check "version" test_version
+ , check "sync" test_sync
+ , check "union merge regression" test_union_merge_regression
+ , check "conflict resolution" test_conflict_resolution_movein_bug
+ , check "conflict_resolution (mixed directory and file)" test_mixed_conflict_resolution
+ , check "map" test_map
+ , check "uninit" test_uninit
+ , check "uninit (in git-annex branch)" test_uninit_inbranch
+ , check "upgrade" test_upgrade
+ , check "whereis" test_whereis
+ , check "hook remote" test_hook_remote
+ , check "directory remote" test_directory_remote
+ , check "rsync remote" test_rsync_remote
+ , check "bup remote" test_bup_remote
+ , check "crypto" test_crypto
+ , check "preferred content" test_preferred_content
+ , check "global cleanup" test_global_cleanup
+ ]
+ where
+ check desc t = testCase desc (t env)
+
+test_global_cleanup :: TestEnv -> Assertion
+test_global_cleanup _env = cleanup tmpdir
+
+test_init :: TestEnv -> Assertion
+test_init env = innewrepo env $ do
+ git_annex env "init" [reponame] @? "init failed"
+ handleforcedirect env
+ where
+ reponame = "test repo"
+
+-- this test case runs in the main repo, to set up a basic
+-- annexed file that later tests will use
+test_add :: TestEnv -> Assertion
+test_add env = inmainrepo env $ do
+ writeFile annexedfile $ content annexedfile
+ git_annex env "add" [annexedfile] @? "add failed"
+ annexed_present annexedfile
+ writeFile sha1annexedfile $ content sha1annexedfile
+ git_annex env "add" [sha1annexedfile, "--backend=SHA1"] @? "add with SHA1 failed"
+ annexed_present sha1annexedfile
+ checkbackend sha1annexedfile backendSHA1
+ writeFile wormannexedfile $ content wormannexedfile
+ git_annex env "add" [wormannexedfile, "--backend=WORM"] @? "add with WORM failed"
+ annexed_present wormannexedfile
+ checkbackend wormannexedfile backendWORM
+ ifM (annexeval Config.isDirect)
+ ( do
+ boolSystem "rm" [Params "-f", File wormannexedfile] @? "rm failed"
+ writeFile ingitfile $ content ingitfile
+ not <$> boolSystem "git" [Param "add", File ingitfile] @? "git add failed to fail in direct mode"
+ boolSystem "rm" [Params "-f", File ingitfile] @? "rm failed"
+ git_annex env "sync" [] @? "sync failed"
+ , do
+ boolSystem "git" [Params "rm --force -q", File wormannexedfile] @? "git rm failed"
+ writeFile ingitfile $ content ingitfile
+ boolSystem "git" [Param "add", File ingitfile] @? "git add failed"
+ boolSystem "git" [Params "commit -q -m commit"] @? "git commit failed"
+ git_annex env "add" [ingitfile] @? "add ingitfile should be no-op"
+ unannexed ingitfile
+ )
+
+test_add_sha1dup :: TestEnv -> Assertion
+test_add_sha1dup env = intmpclonerepo env $ do
+ writeFile sha1annexedfiledup $ content sha1annexedfiledup
+ git_annex env "add" [sha1annexedfiledup, "--backend=SHA1"] @? "add of second file with same SHA1 failed"
+ annexed_present sha1annexedfiledup
+ annexed_present sha1annexedfile
+
+test_add_subdirs :: TestEnv -> Assertion
+test_add_subdirs env = intmpclonerepo env $ do
+ createDirectory "dir"
+ writeFile ("dir" </> "foo") $ content annexedfile
+ git_annex env "add" ["dir"] @? "add of subdir failed"
+ createDirectory "dir2"
+ writeFile ("dir2" </> "foo") $ content annexedfile
+#ifndef mingw32_HOST_OS
+ {- This does not work on Windows, for whatever reason. -}
+ setCurrentDirectory "dir"
+ git_annex env "add" [".." </> "dir2"] @? "add of ../subdir failed"
+#endif
+
+test_reinject :: TestEnv -> Assertion
+test_reinject env = intmpclonerepoInDirect env $ do
+ git_annex env "drop" ["--force", sha1annexedfile] @? "drop failed"
+ writeFile tmp $ content sha1annexedfile
+ r <- annexeval $ Types.Backend.getKey backendSHA1 $
+ Types.KeySource.KeySource { Types.KeySource.keyFilename = tmp, Types.KeySource.contentLocation = tmp, Types.KeySource.inodeCache = Nothing }
+ let key = Types.Key.key2file $ fromJust r
+ git_annex env "reinject" [tmp, sha1annexedfile] @? "reinject failed"
+ git_annex env "fromkey" [key, sha1annexedfiledup] @? "fromkey failed for dup"
+ annexed_present sha1annexedfiledup
+ where
+ tmp = "tmpfile"
+
+test_unannex_nocopy :: TestEnv -> Assertion
+test_unannex_nocopy env = intmpclonerepo env $ do
+ annexed_notpresent annexedfile
+ git_annex env "unannex" [annexedfile] @? "unannex failed with no copy"
+ annexed_notpresent annexedfile
+
+test_unannex_withcopy :: TestEnv -> Assertion
+test_unannex_withcopy env = intmpclonerepo env $ do
+ git_annex env "get" [annexedfile] @? "get failed"
+ annexed_present annexedfile
+ git_annex env "unannex" [annexedfile, sha1annexedfile] @? "unannex failed"
+ unannexed annexedfile
+ git_annex env "unannex" [annexedfile] @? "unannex failed on non-annexed file"
+ unannexed annexedfile
+ unlessM (annexeval Config.isDirect) $ do
+ git_annex env "unannex" [ingitfile] @? "unannex ingitfile should be no-op"
+ unannexed ingitfile
+
+test_drop_noremote :: TestEnv -> Assertion
+test_drop_noremote env = intmpclonerepo env $ do
+ git_annex env "get" [annexedfile] @? "get failed"
+ boolSystem "git" [Params "remote rm origin"]
+ @? "git remote rm origin failed"
+ not <$> git_annex env "drop" [annexedfile] @? "drop wrongly succeeded with no known copy of file"
+ annexed_present annexedfile
+ git_annex env "drop" ["--force", annexedfile] @? "drop --force failed"
+ annexed_notpresent annexedfile
+ git_annex env "drop" [annexedfile] @? "drop of dropped file failed"
+ unlessM (annexeval Config.isDirect) $ do
+ git_annex env "drop" [ingitfile] @? "drop ingitfile should be no-op"
+ unannexed ingitfile
+
+test_drop_withremote :: TestEnv -> Assertion
+test_drop_withremote env = intmpclonerepo env $ do
+ git_annex env "get" [annexedfile] @? "get failed"
+ annexed_present annexedfile
+ git_annex env "drop" [annexedfile] @? "drop failed though origin has copy"
+ annexed_notpresent annexedfile
+ inmainrepo env $ annexed_present annexedfile
+
+test_drop_untrustedremote :: TestEnv -> Assertion
+test_drop_untrustedremote env = intmpclonerepo env $ do
+ git_annex env "untrust" ["origin"] @? "untrust of origin failed"
+ git_annex env "get" [annexedfile] @? "get failed"
+ annexed_present annexedfile
+ not <$> git_annex env "drop" [annexedfile] @? "drop wrongly suceeded with only an untrusted copy of the file"
+ annexed_present annexedfile
+ inmainrepo env $ annexed_present annexedfile
+
+test_get :: TestEnv -> Assertion
+test_get env = intmpclonerepo env $ do
+ inmainrepo env $ annexed_present annexedfile
+ annexed_notpresent annexedfile
+ git_annex env "get" [annexedfile] @? "get of file failed"
+ inmainrepo env $ annexed_present annexedfile
+ annexed_present annexedfile
+ git_annex env "get" [annexedfile] @? "get of file already here failed"
+ inmainrepo env $ annexed_present annexedfile
+ annexed_present annexedfile
+ unlessM (annexeval Config.isDirect) $ do
+ inmainrepo env $ unannexed ingitfile
+ unannexed ingitfile
+ git_annex env "get" [ingitfile] @? "get ingitfile should be no-op"
+ inmainrepo env $ unannexed ingitfile
+ unannexed ingitfile
+
+test_move :: TestEnv -> Assertion
+test_move env = intmpclonerepo env $ do
+ annexed_notpresent annexedfile
+ inmainrepo env $ annexed_present annexedfile
+ git_annex env "move" ["--from", "origin", annexedfile] @? "move --from of file failed"
+ annexed_present annexedfile
+ inmainrepo env $ annexed_notpresent annexedfile
+ git_annex env "move" ["--from", "origin", annexedfile] @? "move --from of file already here failed"
+ annexed_present annexedfile
+ inmainrepo env $ annexed_notpresent annexedfile
+ git_annex env "move" ["--to", "origin", annexedfile] @? "move --to of file failed"
+ inmainrepo env $ annexed_present annexedfile
+ annexed_notpresent annexedfile
+ git_annex env "move" ["--to", "origin", annexedfile] @? "move --to of file already there failed"
+ inmainrepo env $ annexed_present annexedfile
+ annexed_notpresent annexedfile
+ unlessM (annexeval Config.isDirect) $ do
+ unannexed ingitfile
+ inmainrepo env $ unannexed ingitfile
+ git_annex env "move" ["--to", "origin", ingitfile] @? "move of ingitfile should be no-op"
+ unannexed ingitfile
+ inmainrepo env $ unannexed ingitfile
+ git_annex env "move" ["--from", "origin", ingitfile] @? "move of ingitfile should be no-op"
+ unannexed ingitfile
+ inmainrepo env $ unannexed ingitfile
+
+test_copy :: TestEnv -> Assertion
+test_copy env = intmpclonerepo env $ do
+ annexed_notpresent annexedfile
+ inmainrepo env $ annexed_present annexedfile
+ git_annex env "copy" ["--from", "origin", annexedfile] @? "copy --from of file failed"
+ annexed_present annexedfile
+ inmainrepo env $ annexed_present annexedfile
+ git_annex env "copy" ["--from", "origin", annexedfile] @? "copy --from of file already here failed"
+ annexed_present annexedfile
+ inmainrepo env $ annexed_present annexedfile
+ git_annex env "copy" ["--to", "origin", annexedfile] @? "copy --to of file already there failed"
+ annexed_present annexedfile
+ inmainrepo env $ annexed_present annexedfile
+ git_annex env "move" ["--to", "origin", annexedfile] @? "move --to of file already there failed"
+ annexed_notpresent annexedfile
+ inmainrepo env $ annexed_present annexedfile
+ unlessM (annexeval Config.isDirect) $ do
+ unannexed ingitfile
+ inmainrepo env $ unannexed ingitfile
+ git_annex env "copy" ["--to", "origin", ingitfile] @? "copy of ingitfile should be no-op"
+ unannexed ingitfile
+ inmainrepo env $ unannexed ingitfile
+ git_annex env "copy" ["--from", "origin", ingitfile] @? "copy of ingitfile should be no-op"
+ checkregularfile ingitfile
+ checkcontent ingitfile
+
+test_preferred_content :: TestEnv -> Assertion
+test_preferred_content env = intmpclonerepo env $ do
+ annexed_notpresent annexedfile
+ -- get --auto only looks at numcopies when preferred content is not
+ -- set, and with 1 copy existing, does not get the file.
+ git_annex env "get" ["--auto", annexedfile] @? "get --auto of file failed with default preferred content"
+ annexed_notpresent annexedfile
+
+ git_annex env "wanted" [".", "standard"] @? "set expression to standard failed"
+ git_annex env "group" [".", "client"] @? "set group to standard failed"
+ git_annex env "get" ["--auto", annexedfile] @? "get --auto of file failed for client"
+ annexed_present annexedfile
+ git_annex env "ungroup" [".", "client"] @? "ungroup failed"
+
+ git_annex env "wanted" [".", "standard"] @? "set expression to standard failed"
+ git_annex env "group" [".", "manual"] @? "set group to manual failed"
+ -- drop --auto with manual leaves the file where it is
+ git_annex env "drop" ["--auto", annexedfile] @? "drop --auto of file failed with manual preferred content"
+ annexed_present annexedfile
+ git_annex env "drop" [annexedfile] @? "drop of file failed"
+ annexed_notpresent annexedfile
+ -- get --auto with manual does not get the file
+ git_annex env "get" ["--auto", annexedfile] @? "get --auto of file failed with manual preferred content"
+ annexed_notpresent annexedfile
+ git_annex env "ungroup" [".", "client"] @? "ungroup failed"
+
+ git_annex env "wanted" [".", "exclude=*"] @? "set expression to exclude=* failed"
+ git_annex env "get" [annexedfile] @? "get of file failed"
+ annexed_present annexedfile
+ git_annex env "drop" ["--auto", annexedfile] @? "drop --auto of file failed with exclude=*"
+ annexed_notpresent annexedfile
+ git_annex env "get" ["--auto", annexedfile] @? "get --auto of file failed with exclude=*"
+ annexed_notpresent annexedfile
+
+test_lock :: TestEnv -> Assertion
+test_lock env = intmpclonerepoInDirect env $ do
+ -- regression test: unlock of not present file should skip it
+ annexed_notpresent annexedfile
+ not <$> git_annex env "unlock" [annexedfile] @? "unlock failed to fail with not present file"
+ annexed_notpresent annexedfile
+
+ git_annex env "get" [annexedfile] @? "get of file failed"
+ annexed_present annexedfile
+ git_annex env "unlock" [annexedfile] @? "unlock failed"
+ unannexed annexedfile
+ -- write different content, to verify that lock
+ -- throws it away
+ changecontent annexedfile
+ writeFile annexedfile $ content annexedfile ++ "foo"
+ git_annex env "lock" [annexedfile] @? "lock failed"
+ annexed_present annexedfile
+ git_annex env "unlock" [annexedfile] @? "unlock failed"
+ unannexed annexedfile
+ changecontent annexedfile
+ git_annex env "add" [annexedfile] @? "add of modified file failed"
+ runchecks [checklink, checkunwritable] annexedfile
+ c <- readFile annexedfile
+ assertEqual "content of modified file" c (changedcontent annexedfile)
+ r' <- git_annex env "drop" [annexedfile]
+ not r' @? "drop wrongly succeeded with no known copy of modified file"
+
+test_edit :: TestEnv -> Assertion
+test_edit = test_edit' False
+
+test_edit_precommit :: TestEnv -> Assertion
+test_edit_precommit = test_edit' True
+
+test_edit' :: Bool -> TestEnv -> Assertion
+test_edit' precommit env = intmpclonerepoInDirect env $ do
+ git_annex env "get" [annexedfile] @? "get of file failed"
+ annexed_present annexedfile
+ git_annex env "edit" [annexedfile] @? "edit failed"
+ unannexed annexedfile
+ changecontent annexedfile
+ boolSystem "git" [Param "add", File annexedfile]
+ @? "git add of edited file failed"
+ if precommit
+ then git_annex env "pre-commit" []
+ @? "pre-commit failed"
+ else boolSystem "git" [Params "commit -q -m contentchanged"]
+ @? "git commit of edited file failed"
+ runchecks [checklink, checkunwritable] annexedfile
+ c <- readFile annexedfile
+ assertEqual "content of modified file" c (changedcontent annexedfile)
+ not <$> git_annex env "drop" [annexedfile] @? "drop wrongly succeeded with no known copy of modified file"
+
+test_fix :: TestEnv -> Assertion
+test_fix env = intmpclonerepoInDirect env $ do
+ annexed_notpresent annexedfile
+ git_annex env "fix" [annexedfile] @? "fix of not present failed"
+ annexed_notpresent annexedfile
+ git_annex env "get" [annexedfile] @? "get of file failed"
+ annexed_present annexedfile
+ git_annex env "fix" [annexedfile] @? "fix of present file failed"
+ annexed_present annexedfile
+ createDirectory subdir
+ boolSystem "git" [Param "mv", File annexedfile, File subdir]
+ @? "git mv failed"
+ git_annex env "fix" [newfile] @? "fix of moved file failed"
+ runchecks [checklink, checkunwritable] newfile
+ c <- readFile newfile
+ assertEqual "content of moved file" c (content annexedfile)
+ where
+ subdir = "s"
+ newfile = subdir ++ "/" ++ annexedfile
+
+test_trust :: TestEnv -> Assertion
+test_trust env = intmpclonerepo env $ do
+ git_annex env "trust" [repo] @? "trust failed"
+ trustcheck Logs.Trust.Trusted "trusted 1"
+ git_annex env "trust" [repo] @? "trust of trusted failed"
+ trustcheck Logs.Trust.Trusted "trusted 2"
+ git_annex env "untrust" [repo] @? "untrust failed"
+ trustcheck Logs.Trust.UnTrusted "untrusted 1"
+ git_annex env "untrust" [repo] @? "untrust of untrusted failed"
+ trustcheck Logs.Trust.UnTrusted "untrusted 2"
+ git_annex env "dead" [repo] @? "dead failed"
+ trustcheck Logs.Trust.DeadTrusted "deadtrusted 1"
+ git_annex env "dead" [repo] @? "dead of dead failed"
+ trustcheck Logs.Trust.DeadTrusted "deadtrusted 2"
+ git_annex env "semitrust" [repo] @? "semitrust failed"
+ trustcheck Logs.Trust.SemiTrusted "semitrusted 1"
+ git_annex env "semitrust" [repo] @? "semitrust of semitrusted failed"
+ trustcheck Logs.Trust.SemiTrusted "semitrusted 2"
+ where
+ repo = "origin"
+ trustcheck expected msg = do
+ present <- annexeval $ do
+ l <- Logs.Trust.trustGet expected
+ u <- Remote.nameToUUID repo
+ return $ u `elem` l
+ assertBool msg present
+
+test_fsck_basic :: TestEnv -> Assertion
+test_fsck_basic env = intmpclonerepo env $ do
+ git_annex env "fsck" [] @? "fsck failed"
+ boolSystem "git" [Params "config annex.numcopies 2"] @? "git config failed"
+ fsck_should_fail env "numcopies unsatisfied"
+ boolSystem "git" [Params "config annex.numcopies 1"] @? "git config failed"
+ corrupt annexedfile
+ corrupt sha1annexedfile
+ where
+ corrupt f = do
+ git_annex env "get" [f] @? "get of file failed"
+ Utility.FileMode.allowWrite f
+ writeFile f (changedcontent f)
+ ifM (annexeval Config.isDirect)
+ ( git_annex env "fsck" [] @? "fsck failed in direct mode with changed file content"
+ , not <$> git_annex env "fsck" [] @? "fsck failed to fail with corrupted file content"
+ )
+ git_annex env "fsck" [] @? "fsck unexpectedly failed again; previous one did not fix problem with " ++ f
+
+test_fsck_bare :: TestEnv -> Assertion
+test_fsck_bare env = intmpbareclonerepo env $ do
+ git_annex env "fsck" [] @? "fsck failed"
+
+test_fsck_localuntrusted :: TestEnv -> Assertion
+test_fsck_localuntrusted env = intmpclonerepo env $ do
+ git_annex env "get" [annexedfile] @? "get failed"
+ git_annex env "untrust" ["origin"] @? "untrust of origin repo failed"
+ git_annex env "untrust" ["."] @? "untrust of current repo failed"
+ fsck_should_fail env "content only available in untrusted (current) repository"
+ git_annex env "trust" ["."] @? "trust of current repo failed"
+ git_annex env "fsck" [annexedfile] @? "fsck failed on file present in trusted repo"
+
+test_fsck_remoteuntrusted :: TestEnv -> Assertion
+test_fsck_remoteuntrusted env = intmpclonerepo env $ do
+ boolSystem "git" [Params "config annex.numcopies 2"] @? "git config failed"
+ git_annex env "get" [annexedfile] @? "get failed"
+ git_annex env "get" [sha1annexedfile] @? "get failed"
+ git_annex env "fsck" [] @? "fsck failed with numcopies=2 and 2 copies"
+ git_annex env "untrust" ["origin"] @? "untrust of origin failed"
+ fsck_should_fail env "content not replicated to enough non-untrusted repositories"
+
+fsck_should_fail :: TestEnv -> String -> Assertion
+fsck_should_fail env m = not <$> git_annex env "fsck" []
+ @? "fsck failed to fail with " ++ m
+
+test_migrate :: TestEnv -> Assertion
+test_migrate = test_migrate' False
+
+test_migrate_via_gitattributes :: TestEnv -> Assertion
+test_migrate_via_gitattributes = test_migrate' True
+
+test_migrate' :: Bool -> TestEnv -> Assertion
+test_migrate' usegitattributes env = intmpclonerepoInDirect env $ do
+ annexed_notpresent annexedfile
+ annexed_notpresent sha1annexedfile
+ git_annex env "migrate" [annexedfile] @? "migrate of not present failed"
+ git_annex env "migrate" [sha1annexedfile] @? "migrate of not present failed"
+ git_annex env "get" [annexedfile] @? "get of file failed"
+ git_annex env "get" [sha1annexedfile] @? "get of file failed"
+ annexed_present annexedfile
+ annexed_present sha1annexedfile
+ if usegitattributes
+ then do
+ writeFile ".gitattributes" $ "* annex.backend=SHA1"
+ git_annex env "migrate" [sha1annexedfile]
+ @? "migrate sha1annexedfile failed"
+ git_annex env "migrate" [annexedfile]
+ @? "migrate annexedfile failed"
+ else do
+ git_annex env "migrate" [sha1annexedfile, "--backend", "SHA1"]
+ @? "migrate sha1annexedfile failed"
+ git_annex env "migrate" [annexedfile, "--backend", "SHA1"]
+ @? "migrate annexedfile failed"
+ annexed_present annexedfile
+ annexed_present sha1annexedfile
+ checkbackend annexedfile backendSHA1
+ checkbackend sha1annexedfile backendSHA1
+
+ -- check that reversing a migration works
+ writeFile ".gitattributes" $ "* annex.backend=SHA256"
+ git_annex env "migrate" [sha1annexedfile]
+ @? "migrate sha1annexedfile failed"
+ git_annex env "migrate" [annexedfile]
+ @? "migrate annexedfile failed"
+ annexed_present annexedfile
+ annexed_present sha1annexedfile
+ checkbackend annexedfile backendSHA256
+ checkbackend sha1annexedfile backendSHA256
+
+test_unused :: TestEnv -> Assertion
+-- This test is broken in direct mode
+test_unused env = intmpclonerepoInDirect env $ do
+ -- keys have to be looked up before files are removed
+ annexedfilekey <- annexeval $ findkey annexedfile
+ sha1annexedfilekey <- annexeval $ findkey sha1annexedfile
+ git_annex env "get" [annexedfile] @? "get of file failed"
+ git_annex env "get" [sha1annexedfile] @? "get of file failed"
+ checkunused [] "after get"
+ boolSystem "git" [Params "rm -fq", File annexedfile] @? "git rm failed"
+ checkunused [] "after rm"
+ boolSystem "git" [Params "commit -q -m foo"] @? "git commit failed"
+ checkunused [] "after commit"
+ -- unused checks origin/master; once it's gone it is really unused
+ boolSystem "git" [Params "remote rm origin"] @? "git remote rm origin failed"
+ checkunused [annexedfilekey] "after origin branches are gone"
+ boolSystem "git" [Params "rm -fq", File sha1annexedfile] @? "git rm failed"
+ boolSystem "git" [Params "commit -q -m foo"] @? "git commit failed"
+ checkunused [annexedfilekey, sha1annexedfilekey] "after rm sha1annexedfile"
+
+ -- good opportunity to test dropkey also
+ git_annex env "dropkey" ["--force", Types.Key.key2file annexedfilekey]
+ @? "dropkey failed"
+ checkunused [sha1annexedfilekey] ("after dropkey --force " ++ Types.Key.key2file annexedfilekey)
+
+ not <$> git_annex env "dropunused" ["1"] @? "dropunused failed to fail without --force"
+ git_annex env "dropunused" ["--force", "1"] @? "dropunused failed"
+ checkunused [] "after dropunused"
+ not <$> git_annex env "dropunused" ["--force", "10", "501"] @? "dropunused failed to fail on bogus numbers"
+
+ -- unused used to miss symlinks that were not staged and pointed
+ -- at annexed content, and think that content was unused
+ writeFile "unusedfile" "unusedcontent"
+ git_annex env "add" ["unusedfile"] @? "add of unusedfile failed"
+ unusedfilekey <- annexeval $ findkey "unusedfile"
+ renameFile "unusedfile" "unusedunstagedfile"
+ boolSystem "git" [Params "rm -qf", File "unusedfile"] @? "git rm failed"
+ checkunused [] "with unstaged link"
+ removeFile "unusedunstagedfile"
+ checkunused [unusedfilekey] "with unstaged link deleted"
+
+ -- unused used to miss symlinks that were deleted or modified
+ -- manually, but commited as such.
+ writeFile "unusedfile" "unusedcontent"
+ git_annex env "add" ["unusedfile"] @? "add of unusedfile failed"
+ boolSystem "git" [Param "add", File "unusedfile"] @? "git add failed"
+ unusedfilekey' <- annexeval $ findkey "unusedfile"
+ checkunused [] "with staged deleted link"
+ boolSystem "git" [Params "rm -qf", File "unusedfile"] @? "git rm failed"
+ checkunused [unusedfilekey'] "with staged link deleted"
+
+ -- unused used to miss symlinks that were deleted or modified
+ -- manually, but not staged as such.
+ writeFile "unusedfile" "unusedcontent"
+ git_annex env "add" ["unusedfile"] @? "add of unusedfile failed"
+ boolSystem "git" [Param "add", File "unusedfile"] @? "git add failed"
+ unusedfilekey'' <- annexeval $ findkey "unusedfile"
+ checkunused [] "with unstaged deleted link"
+ removeFile "unusedfile"
+ checkunused [unusedfilekey''] "with unstaged link deleted"
+
+ where
+ checkunused expectedkeys desc = do
+ git_annex env "unused" [] @? "unused failed"
+ unusedmap <- annexeval $ Logs.Unused.readUnusedLog ""
+ let unusedkeys = M.elems unusedmap
+ assertEqual ("unused keys differ " ++ desc)
+ (sort expectedkeys) (sort unusedkeys)
+ findkey f = do
+ r <- Backend.lookupFile f
+ return $ fst $ fromJust r
+
+test_describe :: TestEnv -> Assertion
+test_describe env = intmpclonerepo env $ do
+ git_annex env "describe" [".", "this repo"] @? "describe 1 failed"
+ git_annex env "describe" ["origin", "origin repo"] @? "describe 2 failed"
+
+test_find :: TestEnv -> Assertion
+test_find env = intmpclonerepo env $ do
+ annexed_notpresent annexedfile
+ git_annex_expectoutput env "find" [] []
+ git_annex env "get" [annexedfile] @? "get failed"
+ annexed_present annexedfile
+ annexed_notpresent sha1annexedfile
+ git_annex_expectoutput env "find" [] [annexedfile]
+ git_annex_expectoutput env "find" ["--exclude", annexedfile, "--and", "--exclude", sha1annexedfile] []
+ git_annex_expectoutput env "find" ["--include", annexedfile] [annexedfile]
+ git_annex_expectoutput env "find" ["--not", "--in", "origin"] []
+ git_annex_expectoutput env "find" ["--copies", "1", "--and", "--not", "--copies", "2"] [sha1annexedfile]
+ git_annex_expectoutput env "find" ["--inbackend", "SHA1"] [sha1annexedfile]
+ git_annex_expectoutput env "find" ["--inbackend", "WORM"] []
+
+ {- --include=* should match files in subdirectories too,
+ - and --exclude=* should exclude them. -}
+ createDirectory "dir"
+ writeFile "dir/subfile" "subfile"
+ git_annex env "add" ["dir"] @? "add of subdir failed"
+ git_annex_expectoutput env "find" ["--include", "*", "--exclude", annexedfile, "--exclude", sha1annexedfile] ["dir/subfile"]
+ git_annex_expectoutput env "find" ["--exclude", "*"] []
+
+test_merge :: TestEnv -> Assertion
+test_merge env = intmpclonerepo env $ do
+ git_annex env "merge" [] @? "merge failed"
+
+test_info :: TestEnv -> Assertion
+test_info env = intmpclonerepo env $ do
+ json <- git_annex_output env "info" ["--json"]
+ case Text.JSON.decodeStrict json :: Text.JSON.Result (Text.JSON.JSObject Text.JSON.JSValue) of
+ Text.JSON.Ok _ -> return ()
+ Text.JSON.Error e -> assertFailure e
+
+test_version :: TestEnv -> Assertion
+test_version env = intmpclonerepo env $ do
+ git_annex env "version" [] @? "version failed"
+
+test_sync :: TestEnv -> Assertion
+test_sync env = intmpclonerepo env $ do
+ git_annex env "sync" [] @? "sync failed"
+ {- Regression test for bug fixed in
+ - 7b0970b340d7faeb745c666146c7f701ec71808f, where in direct mode
+ - sync committed the symlink standin file to the annex. -}
+ git_annex_expectoutput env "find" ["--in", "."] []
+
+{- Regression test for union merge bug fixed in
+ - 0214e0fb175a608a49b812d81b4632c081f63027 -}
+test_union_merge_regression :: TestEnv -> Assertion
+test_union_merge_regression env =
+ {- We need 3 repos to see this bug. -}
+ withtmpclonerepo env False $ \r1 -> do
+ withtmpclonerepo env False $ \r2 -> do
+ withtmpclonerepo env False $ \r3 -> do
+ forM_ [r1, r2, r3] $ \r -> indir env r $ do
+ when (r /= r1) $
+ boolSystem "git" [Params "remote add r1", File ("../../" ++ r1)] @? "remote add"
+ when (r /= r2) $
+ boolSystem "git" [Params "remote add r2", File ("../../" ++ r2)] @? "remote add"
+ when (r /= r3) $
+ boolSystem "git" [Params "remote add r3", File ("../../" ++ r3)] @? "remote add"
+ git_annex env "get" [annexedfile] @? "get failed"
+ boolSystem "git" [Params "remote rm origin"] @? "remote rm"
+ forM_ [r3, r2, r1] $ \r -> indir env r $
+ git_annex env "sync" [] @? "sync failed"
+ forM_ [r3, r2] $ \r -> indir env r $
+ git_annex env "drop" ["--force", annexedfile] @? "drop failed"
+ indir env r1 $ do
+ git_annex env "sync" [] @? "sync failed in r1"
+ git_annex_expectoutput env "find" ["--in", "r3"] []
+ {- This was the bug. The sync
+ - mangled location log data and it
+ - thought the file was still in r2 -}
+ git_annex_expectoutput env "find" ["--in", "r2"] []
+
+{- Regression test for the automatic conflict resolution bug fixed
+ - in f4ba19f2b8a76a1676da7bb5850baa40d9c388e2. -}
+test_conflict_resolution_movein_bug :: TestEnv -> Assertion
+test_conflict_resolution_movein_bug env = withtmpclonerepo env False $ \r1 -> do
+ withtmpclonerepo env False $ \r2 -> do
+ let rname r = if r == r1 then "r1" else "r2"
+ forM_ [r1, r2] $ \r -> indir env r $ do
+ {- Get all files, see check below. -}
+ git_annex env "get" [] @? "get failed"
+ pair env r1 r2
+ forM_ [r1, r2] $ \r -> indir env r $ do
+ {- Set up a conflict. -}
+ let newcontent = content annexedfile ++ rname r
+ ifM (annexeval Config.isDirect)
+ ( writeFile annexedfile newcontent
+ , do
+ git_annex env "unlock" [annexedfile] @? "unlock failed"
+ writeFile annexedfile newcontent
+ )
+ {- Sync twice in r1 so it gets the conflict resolution
+ - update from r2 -}
+ forM_ [r1, r2, r1] $ \r -> indir env r $ do
+ git_annex env "sync" ["--force"] @? "sync failed in " ++ rname r
+ {- After the sync, it should be possible to get all
+ - files. This includes both sides of the conflict,
+ - although the filenames are not easily predictable.
+ -
+ - The bug caused, in direct mode, one repo to
+ - be missing the content of the file that had
+ - been put in it. -}
+ forM_ [r1, r2] $ \r -> indir env r $ do
+ git_annex env "get" [] @? "unable to get all files after merge conflict resolution in " ++ rname r
+
+{- Check merge conflict resolution when one side is an annexed
+ - file, and the other is a directory. -}
+test_mixed_conflict_resolution :: TestEnv -> Assertion
+test_mixed_conflict_resolution env = do
+ check_mixed_conflict True
+ check_mixed_conflict False
+ where
+ check_mixed_conflict inr1 = withtmpclonerepo env False $ \r1 ->
+ withtmpclonerepo env False $ \r2 -> do
+ indir env r1 $ do
+ writeFile conflictor "conflictor"
+ git_annex env "add" [conflictor] @? "add conflicter failed"
+ git_annex env "sync" [] @? "sync failed"
+ indir env r2 $ do
+ createDirectory conflictor
+ writeFile (conflictor </> "subfile") "subfile"
+ git_annex env "add" [conflictor] @? "add conflicter failed"
+ git_annex env "sync" [] @? "sync failed"
+ pair env r1 r2
+ let r = if inr1 then r1 else r2
+ indir env r $ do
+ git_annex env "sync" [] @? "sync failed in mixed conflict"
+ checkmerge r1
+ checkmerge r2
+ where
+ conflictor = "conflictor"
+ variantprefix = conflictor ++ ".variant"
+ checkmerge d = do
+ doesDirectoryExist (d </> conflictor) @? (d ++ " conflictor directory missing")
+ (any (variantprefix `isPrefixOf`)
+ <$> getDirectoryContents d)
+ @? (d ++ "conflictor file missing")
+
+{- Set up repos as remotes of each other;
+ - remove origin since we're going to sync
+ - some changes to a file. -}
+pair :: TestEnv -> FilePath -> FilePath -> Assertion
+pair env r1 r2 = forM_ [r1, r2] $ \r -> indir env r $ do
+ when (r /= r1) $
+ boolSystem "git" [Params "remote add r1", File ("../../" ++ r1)] @? "remote add"
+ when (r /= r2) $
+ boolSystem "git" [Params "remote add r2", File ("../../" ++ r2)] @? "remote add"
+ boolSystem "git" [Params "remote rm origin"] @? "remote rm"
+
+test_map :: TestEnv -> Assertion
+test_map env = intmpclonerepo env $ do
+ -- set descriptions, that will be looked for in the map
+ git_annex env "describe" [".", "this repo"] @? "describe 1 failed"
+ git_annex env "describe" ["origin", "origin repo"] @? "describe 2 failed"
+ -- --fast avoids it running graphviz, not a build dependency
+ git_annex env "map" ["--fast"] @? "map failed"
+
+test_uninit :: TestEnv -> Assertion
+test_uninit env = intmpclonerepo env $ do
+ git_annex env "get" [] @? "get failed"
+ annexed_present annexedfile
+ _ <- git_annex env "uninit" [] -- exit status not checked; does abnormal exit
+ checkregularfile annexedfile
+ doesDirectoryExist ".git" @? ".git vanished in uninit"
+
+test_uninit_inbranch :: TestEnv -> Assertion
+test_uninit_inbranch env = intmpclonerepoInDirect env $ do
+ boolSystem "git" [Params "checkout git-annex"] @? "git checkout git-annex"
+ not <$> git_annex env "uninit" [] @? "uninit failed to fail when git-annex branch was checked out"
+
+test_upgrade :: TestEnv -> Assertion
+test_upgrade env = intmpclonerepo env $ do
+ git_annex env "upgrade" [] @? "upgrade from same version failed"
+
+test_whereis :: TestEnv -> Assertion
+test_whereis env = intmpclonerepo env $ do
+ annexed_notpresent annexedfile
+ git_annex env "whereis" [annexedfile] @? "whereis on non-present file failed"
+ git_annex env "untrust" ["origin"] @? "untrust failed"
+ not <$> git_annex env "whereis" [annexedfile] @? "whereis on non-present file only present in untrusted repo failed to fail"
+ git_annex env "get" [annexedfile] @? "get failed"
+ annexed_present annexedfile
+ git_annex env "whereis" [annexedfile] @? "whereis on present file failed"
+
+test_hook_remote :: TestEnv -> Assertion
+test_hook_remote env = intmpclonerepo env $ do
+#ifndef mingw32_HOST_OS
+ git_annex env "initremote" (words "foo type=hook encryption=none hooktype=foo") @? "initremote failed"
+ createDirectory dir
+ git_config "annex.foo-store-hook" $
+ "cp $ANNEX_FILE " ++ loc
+ git_config "annex.foo-retrieve-hook" $
+ "cp " ++ loc ++ " $ANNEX_FILE"
+ git_config "annex.foo-remove-hook" $
+ "rm -f " ++ loc
+ git_config "annex.foo-checkpresent-hook" $
+ "if [ -e " ++ loc ++ " ]; then echo $ANNEX_KEY; fi"
+ git_annex env "get" [annexedfile] @? "get of file failed"
+ annexed_present annexedfile
+ git_annex env "copy" [annexedfile, "--to", "foo"] @? "copy --to hook remote failed"
+ annexed_present annexedfile
+ git_annex env "drop" [annexedfile, "--numcopies=2"] @? "drop failed"
+ annexed_notpresent annexedfile
+ git_annex env "move" [annexedfile, "--from", "foo"] @? "move --from hook remote failed"
+ annexed_present annexedfile
+ not <$> git_annex env "drop" [annexedfile, "--numcopies=2"] @? "drop failed to fail"
+ annexed_present annexedfile
+ where
+ dir = "dir"
+ loc = dir ++ "/$ANNEX_KEY"
+ git_config k v = boolSystem "git" [Param "config", Param k, Param v]
+ @? "git config failed"
+#else
+ -- this test doesn't work in Windows TODO
+ noop
+#endif
+
+test_directory_remote :: TestEnv -> Assertion
+test_directory_remote env = intmpclonerepo env $ do
+ createDirectory "dir"
+ git_annex env "initremote" (words $ "foo type=directory encryption=none directory=dir") @? "initremote failed"
+ git_annex env "get" [annexedfile] @? "get of file failed"
+ annexed_present annexedfile
+ git_annex env "copy" [annexedfile, "--to", "foo"] @? "copy --to directory remote failed"
+ annexed_present annexedfile
+ git_annex env "drop" [annexedfile, "--numcopies=2"] @? "drop failed"
+ annexed_notpresent annexedfile
+ git_annex env "move" [annexedfile, "--from", "foo"] @? "move --from directory remote failed"
+ annexed_present annexedfile
+ not <$> git_annex env "drop" [annexedfile, "--numcopies=2"] @? "drop failed to fail"
+ annexed_present annexedfile
+
+test_rsync_remote :: TestEnv -> Assertion
+test_rsync_remote env = intmpclonerepo env $ do
+#ifndef mingw32_HOST_OS
+ createDirectory "dir"
+ git_annex env "initremote" (words $ "foo type=rsync encryption=none rsyncurl=dir") @? "initremote failed"
+ git_annex env "get" [annexedfile] @? "get of file failed"
+ annexed_present annexedfile
+ git_annex env "copy" [annexedfile, "--to", "foo"] @? "copy --to rsync remote failed"
+ annexed_present annexedfile
+ git_annex env "drop" [annexedfile, "--numcopies=2"] @? "drop failed"
+ annexed_notpresent annexedfile
+ git_annex env "move" [annexedfile, "--from", "foo"] @? "move --from rsync remote failed"
+ annexed_present annexedfile
+ not <$> git_annex env "drop" [annexedfile, "--numcopies=2"] @? "drop failed to fail"
+ annexed_present annexedfile
+#else
+ -- this test doesn't work in Windows TODO
+ noop
+#endif
+
+test_bup_remote :: TestEnv -> Assertion
+test_bup_remote env = intmpclonerepo env $ when Build.SysConfig.bup $ do
+ dir <- absPath "dir" -- bup special remote needs an absolute path
+ createDirectory dir
+ git_annex env "initremote" (words $ "foo type=bup encryption=none buprepo="++dir) @? "initremote failed"
+ git_annex env "get" [annexedfile] @? "get of file failed"
+ annexed_present annexedfile
+ git_annex env "copy" [annexedfile, "--to", "foo"] @? "copy --to bup remote failed"
+ annexed_present annexedfile
+ git_annex env "drop" [annexedfile, "--numcopies=2"] @? "drop failed"
+ annexed_notpresent annexedfile
+ git_annex env "copy" [annexedfile, "--from", "foo"] @? "copy --from bup remote failed"
+ annexed_present annexedfile
+ not <$> git_annex env "move" [annexedfile, "--from", "foo"] @? "move --from bup remote failed to fail"
+ annexed_present annexedfile
+
+-- gpg is not a build dependency, so only test when it's available
+test_crypto :: TestEnv -> Assertion
+#ifndef mingw32_HOST_OS
+test_crypto env = do
+ testscheme "shared"
+ testscheme "hybrid"
+ testscheme "pubkey"
+ where
+ testscheme scheme = intmpclonerepo env $ whenM (Utility.Path.inPath Utility.Gpg.gpgcmd) $ do
+ Utility.Gpg.testTestHarness @? "test harness self-test failed"
+ Utility.Gpg.testHarness $ do
+ createDirectory "dir"
+ let a cmd = git_annex env cmd $
+ [ "foo"
+ , "type=directory"
+ , "encryption=" ++ scheme
+ , "directory=dir"
+ , "highRandomQuality=false"
+ ] ++ if scheme `elem` ["hybrid","pubkey"]
+ then ["keyid=" ++ Utility.Gpg.testKeyId]
+ else []
+ a "initremote" @? "initremote failed"
+ not <$> a "initremote" @? "initremote failed to fail when run twice in a row"
+ a "enableremote" @? "enableremote failed"
+ a "enableremote" @? "enableremote failed when run twice in a row"
+ git_annex env "get" [annexedfile] @? "get of file failed"
+ annexed_present annexedfile
+ git_annex env "copy" [annexedfile, "--to", "foo"] @? "copy --to encrypted remote failed"
+ (c,k) <- annexeval $ do
+ uuid <- Remote.nameToUUID "foo"
+ rs <- Logs.Remote.readRemoteLog
+ Just (k,_) <- Backend.lookupFile annexedfile
+ return (fromJust $ M.lookup uuid rs, k)
+ let key = if scheme `elem` ["hybrid","pubkey"]
+ then Just $ Utility.Gpg.KeyIds [Utility.Gpg.testKeyId]
+ else Nothing
+ testEncryptedRemote scheme key c [k] @? "invalid crypto setup"
+
+ annexed_present annexedfile
+ git_annex env "drop" [annexedfile, "--numcopies=2"] @? "drop failed"
+ annexed_notpresent annexedfile
+ git_annex env "move" [annexedfile, "--from", "foo"] @? "move --from encrypted remote failed"
+ annexed_present annexedfile
+ not <$> git_annex env "drop" [annexedfile, "--numcopies=2"] @? "drop failed to fail"
+ annexed_present annexedfile
+ {- Ensure the configuration complies with the encryption scheme, and
+ - that all keys are encrypted properly for the given directory remote. -}
+ testEncryptedRemote scheme ks c keys = case Remote.Helper.Encryptable.extractCipher c of
+ Just cip@Crypto.SharedCipher{} | scheme == "shared" && isNothing ks ->
+ checkKeys cip Nothing
+ Just cip@(Crypto.EncryptedCipher encipher v ks')
+ | checkScheme v && keysMatch ks' ->
+ checkKeys cip (Just v) <&&> checkCipher encipher ks'
+ _ -> return False
+ where
+ keysMatch (Utility.Gpg.KeyIds ks') =
+ maybe False (\(Utility.Gpg.KeyIds ks2) ->
+ sort (nub ks2) == sort (nub ks')) ks
+ checkCipher encipher = Utility.Gpg.checkEncryptionStream encipher . Just
+ checkScheme Types.Crypto.Hybrid = scheme == "hybrid"
+ checkScheme Types.Crypto.PubKey = scheme == "pubkey"
+ checkKeys cip mvariant = do
+ cipher <- Crypto.decryptCipher cip
+ files <- filterM doesFileExist $
+ map ("dir" </>) $ concatMap (key2files cipher) keys
+ return (not $ null files) <&&> allM (checkFile mvariant) files
+ checkFile mvariant filename =
+ Utility.Gpg.checkEncryptionFile filename $
+ if mvariant == Just Types.Crypto.PubKey then ks else Nothing
+ key2files cipher = Locations.keyPaths .
+ Crypto.encryptKey Types.Crypto.HmacSha1 cipher
+#else
+test_crypto _env = putStrLn "gpg testing not implemented on Windows"
+#endif
+
+-- This is equivilant to running git-annex, but it's all run in-process
+-- (when the OS allows) so test coverage collection works.
+git_annex :: TestEnv -> String -> [String] -> IO Bool
+git_annex env command params = do
+#ifndef mingw32_HOST_OS
+ forM_ (M.toList env) $ \(var, val) ->
+ Utility.Env.setEnv var val True
+
+ -- catch all errors, including normally fatal errors
+ r <- try (run)::IO (Either SomeException ())
+ case r of
+ Right _ -> return True
+ Left _ -> return False
+ where
+ run = GitAnnex.run (command:"-q":params)
+#else
+ Utility.SafeCommand.boolSystemEnv "git-annex"
+ (map Param $ command : params)
+ (Just $ M.toList env)
+#endif
+
+{- Runs git-annex and returns its output. -}
+git_annex_output :: TestEnv -> String -> [String] -> IO String
+git_annex_output env command params = do
+ got <- Utility.Process.readProcessEnv "git-annex" (command:params)
+ (Just $ M.toList env)
+ -- XXX since the above is a separate process, code coverage stats are
+ -- not gathered for things run in it.
+ -- Run same command again, to get code coverage.
+ _ <- git_annex env command params
+ return got
+
+git_annex_expectoutput :: TestEnv -> String -> [String] -> [String] -> IO ()
+git_annex_expectoutput env command params expected = do
+ got <- lines <$> git_annex_output env command params
+ got == expected @? ("unexpected value running " ++ command ++ " " ++ show params ++ " -- got: " ++ show got ++ " expected: " ++ show expected)
+
+-- Runs an action in the current annex. Note that shutdown actions
+-- are not run; this should only be used for actions that query state.
+annexeval :: Types.Annex a -> IO a
+annexeval a = do
+ s <- Annex.new =<< Git.CurrentRepo.get
+ Annex.eval s $ do
+ Annex.setOutput Types.Messages.QuietOutput
+ a
+
+innewrepo :: TestEnv -> Assertion -> Assertion
+innewrepo env a = withgitrepo env $ \r -> indir env r a
+
+inmainrepo :: TestEnv -> Assertion -> Assertion
+inmainrepo env a = indir env mainrepodir a
+
+intmpclonerepo :: TestEnv -> Assertion -> Assertion
+intmpclonerepo env a = withtmpclonerepo env False $ \r -> indir env r a
+
+intmpclonerepoInDirect :: TestEnv -> Assertion -> Assertion
+intmpclonerepoInDirect env a = intmpclonerepo env $
+ ifM isdirect
+ ( putStrLn "not supported in direct mode; skipping"
+ , a
+ )
+ where
+ isdirect = annexeval $ do
+ Init.initialize Nothing
+ Config.isDirect
+
+intmpbareclonerepo :: TestEnv -> Assertion -> Assertion
+intmpbareclonerepo env a = withtmpclonerepo env True $ \r -> indir env r a
+
+withtmpclonerepo :: TestEnv -> Bool -> (FilePath -> Assertion) -> Assertion
+withtmpclonerepo env bare a = do
+ dir <- tmprepodir
+ bracket (clonerepo env mainrepodir dir bare) cleanup a
+
+withgitrepo :: TestEnv -> (FilePath -> Assertion) -> Assertion
+withgitrepo env = bracket (setuprepo env mainrepodir) return
+
+indir :: TestEnv -> FilePath -> Assertion -> Assertion
+indir env dir a = do
+ cwd <- getCurrentDirectory
+ -- Assertion failures throw non-IO errors; catch
+ -- any type of error and change back to cwd before
+ -- rethrowing.
+ r <- bracket_ (changeToTmpDir env dir) (setCurrentDirectory cwd)
+ (try (a)::IO (Either SomeException ()))
+ case r of
+ Right () -> return ()
+ Left e -> throw e
+
+setuprepo :: TestEnv -> FilePath -> IO FilePath
+setuprepo env dir = do
+ cleanup dir
+ ensuretmpdir
+ boolSystem "git" [Params "init -q", File dir] @? "git init failed"
+ indir env dir $ do
+ boolSystem "git" [Params "config user.name", Param "Test User"] @? "git config failed"
+ boolSystem "git" [Params "config user.email test@example.com"] @? "git config failed"
+ return dir
+
+-- clones are always done as local clones; we cannot test ssh clones
+clonerepo :: TestEnv -> FilePath -> FilePath -> Bool -> IO FilePath
+clonerepo env old new bare = do
+ cleanup new
+ ensuretmpdir
+ let b = if bare then " --bare" else ""
+ boolSystem "git" [Params ("clone -q" ++ b), File old, File new] @? "git clone failed"
+ indir env new $
+ git_annex env "init" ["-q", new] @? "git annex init failed"
+ when (not bare) $
+ indir env new $
+ handleforcedirect env
+ return new
+
+handleforcedirect :: TestEnv -> IO ()
+handleforcedirect env = when (M.lookup "FORCEDIRECT" env == Just "1") $
+ git_annex env "direct" ["-q"] @? "git annex direct failed"
+
+ensuretmpdir :: IO ()
+ensuretmpdir = do
+ e <- doesDirectoryExist tmpdir
+ unless e $
+ createDirectory tmpdir
+
+cleanup :: FilePath -> IO ()
+cleanup dir = do
+ e <- doesDirectoryExist dir
+ when e $ do
+ -- git-annex prevents annexed file content from being
+ -- removed via directory permissions; undo
+ recurseDir SystemFS dir >>=
+ filterM doesDirectoryExist >>=
+ mapM_ Utility.FileMode.allowWrite
+ -- For unknown reasons, this sometimes fails on Windows.
+ void $ tryIO $ removeDirectoryRecursive dir
+
+checklink :: FilePath -> Assertion
+checklink f = do
+ s <- getSymbolicLinkStatus f
+ -- in direct mode, it may be a symlink, or not, depending
+ -- on whether the content is present.
+ unlessM (annexeval Config.isDirect) $
+ isSymbolicLink s @? f ++ " is not a symlink"
+
+checkregularfile :: FilePath -> Assertion
+checkregularfile f = do
+ s <- getSymbolicLinkStatus f
+ isRegularFile s @? f ++ " is not a normal file"
+ return ()
+
+checkcontent :: FilePath -> Assertion
+checkcontent f = do
+ c <- Utility.Exception.catchDefaultIO "could not read file" $ readFile f
+ assertEqual ("checkcontent " ++ f) (content f) c
+
+checkunwritable :: FilePath -> Assertion
+checkunwritable f = unlessM (annexeval Config.isDirect) $ do
+ -- Look at permissions bits rather than trying to write or
+ -- using fileAccess because if run as root, any file can be
+ -- modified despite permissions.
+ s <- getFileStatus f
+ let mode = fileMode s
+ if (mode == mode `unionFileModes` ownerWriteMode)
+ then assertFailure $ "able to modify annexed file's " ++ f ++ " content"
+ else return ()
+
+checkwritable :: FilePath -> Assertion
+checkwritable f = do
+ r <- tryIO $ writeFile f $ content f
+ case r of
+ Left _ -> assertFailure $ "unable to modify " ++ f
+ Right _ -> return ()
+
+checkdangling :: FilePath -> Assertion
+checkdangling f = ifM (annexeval Config.crippledFileSystem)
+ ( return () -- probably no real symlinks to test
+ , do
+ r <- tryIO $ readFile f
+ case r of
+ Left _ -> return () -- expected; dangling link
+ Right _ -> assertFailure $ f ++ " was not a dangling link as expected"
+ )
+
+checklocationlog :: FilePath -> Bool -> Assertion
+checklocationlog f expected = do
+ thisuuid <- annexeval Annex.UUID.getUUID
+ r <- annexeval $ Backend.lookupFile f
+ case r of
+ Just (k, _) -> do
+ uuids <- annexeval $ Remote.keyLocations k
+ assertEqual ("bad content in location log for " ++ f ++ " key " ++ (Types.Key.key2file k) ++ " uuid " ++ show thisuuid)
+ expected (thisuuid `elem` uuids)
+ _ -> assertFailure $ f ++ " failed to look up key"
+
+checkbackend :: FilePath -> Types.Backend -> Assertion
+checkbackend file expected = do
+ r <- annexeval $ Backend.lookupFile file
+ let b = snd $ fromJust r
+ assertEqual ("backend for " ++ file) expected b
+
+inlocationlog :: FilePath -> Assertion
+inlocationlog f = checklocationlog f True
+
+notinlocationlog :: FilePath -> Assertion
+notinlocationlog f = checklocationlog f False
+
+runchecks :: [FilePath -> Assertion] -> FilePath -> Assertion
+runchecks [] _ = return ()
+runchecks (a:as) f = do
+ a f
+ runchecks as f
+
+annexed_notpresent :: FilePath -> Assertion
+annexed_notpresent = runchecks
+ [checklink, checkdangling, notinlocationlog]
+
+annexed_present :: FilePath -> Assertion
+annexed_present = runchecks
+ [checklink, checkcontent, checkunwritable, inlocationlog]
+
+unannexed :: FilePath -> Assertion
+unannexed = runchecks [checkregularfile, checkcontent, checkwritable]
+
+prepare :: Bool -> IO TestEnv
+prepare forcedirect = do
+ whenM (doesDirectoryExist tmpdir) $
+ error $ "The temporary directory " ++ tmpdir ++ " already exists; cannot run test suite."
+
+ cwd <- getCurrentDirectory
+ p <- Utility.Env.getEnvDefault "PATH" ""
+
+ let env =
+ -- Ensure that the just-built git annex is used.
+ [ ("PATH", cwd ++ [searchPathSeparator] ++ p)
+ , ("TOPDIR", cwd)
+ -- Avoid git complaining if it cannot determine the user's
+ -- email address, or exploding if it doesn't know the user's
+ -- name.
+ , ("GIT_AUTHOR_EMAIL", "test@example.com")
+ , ("GIT_AUTHOR_NAME", "git-annex test")
+ , ("GIT_COMMITTER_EMAIL", "test@example.com")
+ , ("GIT_COMMITTER_NAME", "git-annex test")
+ -- force gpg into batch mode for the tests
+ , ("GPG_BATCH", "1")
+ , ("FORCEDIRECT", if forcedirect then "1" else "")
+ ]
+
+ return $ M.fromList env
+
+changeToTmpDir :: TestEnv -> FilePath -> IO ()
+changeToTmpDir env t = do
+ let topdir = fromMaybe "" $ M.lookup "TOPDIR" env
+ setCurrentDirectory $ topdir ++ "/" ++ t
+
+tmpdir :: String
+tmpdir = ".t"
+
+mainrepodir :: FilePath
+mainrepodir = tmpdir </> "repo"
+
+tmprepodir :: IO FilePath
+tmprepodir = go (0 :: Int)
+ where
+ go n = do
+ let d = tmpdir </> "tmprepo" ++ show n
+ ifM (doesDirectoryExist d)
+ ( go $ n + 1
+ , return d
+ )
+
+annexedfile :: String
+annexedfile = "foo"
+
+wormannexedfile :: String
+wormannexedfile = "apple"
+
+sha1annexedfile :: String
+sha1annexedfile = "sha1foo"
+
+sha1annexedfiledup :: String
+sha1annexedfiledup = "sha1foodup"
+
+ingitfile :: String
+ingitfile = "bar"
+
+content :: FilePath -> String
+content f
+ | f == annexedfile = "annexed file content"
+ | f == ingitfile = "normal file content"
+ | f == sha1annexedfile ="sha1 annexed file content"
+ | f == sha1annexedfiledup = content sha1annexedfile
+ | f == wormannexedfile = "worm annexed file content"
+ | otherwise = "unknown file " ++ f
+
+changecontent :: FilePath -> IO ()
+changecontent f = writeFile f $ changedcontent f
+
+changedcontent :: FilePath -> String
+changedcontent f = (content f) ++ " (modified)"
+
+backendSHA1 :: Types.Backend
+backendSHA1 = backend_ "SHA1"
+
+backendSHA256 :: Types.Backend
+backendSHA256 = backend_ "SHA256"
+
+backendWORM :: Types.Backend
+backendWORM = backend_ "WORM"
+
+backend_ :: String -> Types.Backend
+backend_ name = Backend.lookupBackendName name
diff --git a/Types.hs b/Types.hs
new file mode 100644
index 000000000..8768ed1fe
--- /dev/null
+++ b/Types.hs
@@ -0,0 +1,31 @@
+{- git-annex abstract data types
+ -
+ - Copyright 2010 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Types (
+ Annex,
+ Backend,
+ Key,
+ AssociatedFile,
+ UUID(..),
+ GitConfig(..),
+ RemoteGitConfig(..),
+ Remote,
+ RemoteType,
+ Option
+) where
+
+import Annex
+import Types.Backend
+import Types.GitConfig
+import Types.Key
+import Types.UUID
+import Types.Remote
+import Types.Option
+
+type Backend = BackendA Annex
+type Remote = RemoteA Annex
+type RemoteType = RemoteTypeA Annex
diff --git a/Types/Backend.hs b/Types/Backend.hs
new file mode 100644
index 000000000..c7d962db0
--- /dev/null
+++ b/Types/Backend.hs
@@ -0,0 +1,26 @@
+{- git-annex key/value backend data type
+ -
+ - Most things should not need this, using Types instead
+ -
+ - Copyright 2010,2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Types.Backend where
+
+import Types.Key
+import Types.KeySource
+
+data BackendA a = Backend
+ { name :: String
+ , getKey :: KeySource -> a (Maybe Key)
+ , fsckKey :: Maybe (Key -> FilePath -> a Bool)
+ , canUpgradeKey :: Maybe (Key -> Bool)
+ }
+
+instance Show (BackendA a) where
+ show backend = "Backend { name =\"" ++ name backend ++ "\" }"
+
+instance Eq (BackendA a) where
+ a == b = name a == name b
diff --git a/Types/BranchState.hs b/Types/BranchState.hs
new file mode 100644
index 000000000..2f7948ebb
--- /dev/null
+++ b/Types/BranchState.hs
@@ -0,0 +1,16 @@
+{- git-annex BranchState data type
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Types.BranchState where
+
+data BranchState = BranchState
+ { branchUpdated :: Bool -- has the branch been updated this run?
+ , indexChecked :: Bool -- has the index file been checked to exist?
+ }
+
+startBranchState :: BranchState
+startBranchState = BranchState False False
diff --git a/Types/Command.hs b/Types/Command.hs
new file mode 100644
index 000000000..3187efd17
--- /dev/null
+++ b/Types/Command.hs
@@ -0,0 +1,77 @@
+{- git-annex command data types
+ -
+ - Copyright 2010-2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Types.Command where
+
+import Data.Ord
+
+import Types
+
+{- A command runs in these stages.
+ -
+ - a. The check stage runs checks, that error out if
+ - anything prevents the command from running. -}
+data CommandCheck = CommandCheck { idCheck :: Int, runCheck :: Annex () }
+{- b. The seek stage takes the parameters passed to the command,
+ - looks through the repo to find the ones that are relevant
+ - to that command (ie, new files to add), and generates
+ - a list of start stage actions. -}
+type CommandSeek = [String] -> Annex [CommandStart]
+{- c. The start stage is run before anything is printed about the
+ - command, is passed some input, and can early abort it
+ - if the input does not make sense. It should run quickly and
+ - should not modify Annex state. -}
+type CommandStart = Annex (Maybe CommandPerform)
+{- d. The perform stage is run after a message is printed about the command
+ - being run, and it should be where the bulk of the work happens. -}
+type CommandPerform = Annex (Maybe CommandCleanup)
+{- e. The cleanup stage is run only if the perform stage succeeds, and it
+ - returns the overall success/fail of the command. -}
+type CommandCleanup = Annex Bool
+
+{- A command is defined by specifying these things. -}
+data Command = Command
+ { cmdoptions :: [Option] -- command-specific options
+ , cmdnorepo :: Maybe (IO ()) -- an action to run when not in a repo
+ , cmdcheck :: [CommandCheck] -- check stage
+ , cmdnocommit :: Bool -- don't commit journalled state changes
+ , cmdnomessages :: Bool -- don't output normal messages
+ , cmdname :: String
+ , cmdparamdesc :: String -- description of params for usage
+ , cmdseek :: [CommandSeek] -- seek stage
+ , cmdsection :: CommandSection
+ , cmddesc :: String -- description of command for usage
+ }
+
+{- CommandCheck functions can be compared using their unique id. -}
+instance Eq CommandCheck where
+ a == b = idCheck a == idCheck b
+
+instance Eq Command where
+ a == b = cmdname a == cmdname b
+
+{- Order commands by name. -}
+instance Ord Command where
+ compare = comparing cmdname
+
+{- The same sections are listed in doc/git-annex.mdwn -}
+data CommandSection
+ = SectionCommon
+ | SectionSetup
+ | SectionMaintenance
+ | SectionQuery
+ | SectionUtility
+ | SectionPlumbing
+ deriving (Eq, Ord, Enum, Bounded)
+
+descSection :: CommandSection -> String
+descSection SectionCommon = "Commonly used commands"
+descSection SectionSetup = "Repository setup commands"
+descSection SectionMaintenance = "Repository maintenance commands"
+descSection SectionQuery = "Query commands"
+descSection SectionUtility = "Utility commands"
+descSection SectionPlumbing = "Plumbing commands"
diff --git a/Types/Crypto.hs b/Types/Crypto.hs
new file mode 100644
index 000000000..1a9a7774a
--- /dev/null
+++ b/Types/Crypto.hs
@@ -0,0 +1,73 @@
+{- git-annex crypto types
+ -
+ - Copyright 2011-2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Types.Crypto (
+ Cipher(..),
+ StorableCipher(..),
+ EncryptedCipherVariant(..),
+ KeyIds(..),
+ Mac(..),
+ readMac,
+ showMac,
+ defaultMac,
+ calcMac,
+) where
+
+import qualified Data.ByteString.Lazy as L
+import Data.Digest.Pure.SHA
+
+import Utility.Gpg (KeyIds(..))
+
+-- XXX ideally, this would be a locked memory region
+data Cipher = Cipher String | MacOnlyCipher String
+
+data StorableCipher = EncryptedCipher String EncryptedCipherVariant KeyIds
+ | SharedCipher String
+ deriving (Ord, Eq)
+data EncryptedCipherVariant = Hybrid | PubKey
+ deriving (Ord, Eq)
+
+{- File names are (client-side) MAC'ed on special remotes.
+ - The chosen MAC algorithm needs to be same for all files stored on the
+ - remote.
+ -}
+data Mac = HmacSha1 | HmacSha224 | HmacSha256 | HmacSha384 | HmacSha512
+ deriving (Eq)
+
+defaultMac :: Mac
+defaultMac = HmacSha1
+
+-- MAC algorithms are shown as follows in the file names.
+showMac :: Mac -> String
+showMac HmacSha1 = "HMACSHA1"
+showMac HmacSha224 = "HMACSHA224"
+showMac HmacSha256 = "HMACSHA256"
+showMac HmacSha384 = "HMACSHA384"
+showMac HmacSha512 = "HMACSHA512"
+
+-- Read the MAC algorithm from the remote config.
+readMac :: String -> Maybe Mac
+readMac "HMACSHA1" = Just HmacSha1
+readMac "HMACSHA224" = Just HmacSha224
+readMac "HMACSHA256" = Just HmacSha256
+readMac "HMACSHA384" = Just HmacSha384
+readMac "HMACSHA512" = Just HmacSha512
+readMac _ = Nothing
+
+calcMac
+ :: Mac -- ^ MAC
+ -> L.ByteString -- ^ secret key
+ -> L.ByteString -- ^ message
+ -> String -- ^ MAC'ed message, in hexadecimals
+calcMac mac = case mac of
+ HmacSha1 -> showDigest $* hmacSha1
+ HmacSha224 -> showDigest $* hmacSha224
+ HmacSha256 -> showDigest $* hmacSha256
+ HmacSha384 -> showDigest $* hmacSha384
+ HmacSha512 -> showDigest $* hmacSha512
+ where
+ ($*) g f x y = g $ f x y
diff --git a/Types/Distribution.hs b/Types/Distribution.hs
new file mode 100644
index 000000000..4201f49ad
--- /dev/null
+++ b/Types/Distribution.hs
@@ -0,0 +1,38 @@
+{- Data type for a distribution of git-annex
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Types.Distribution where
+
+import Types.Key
+import Data.Time.Clock
+import Git.Config (isTrue, boolConfig)
+
+data GitAnnexDistribution = GitAnnexDistribution
+ { distributionUrl :: String
+ , distributionKey :: Key
+ , distributionVersion :: GitAnnexVersion
+ , distributionReleasedate :: UTCTime
+ , distributionUrgentUpgrade :: Maybe GitAnnexVersion
+ }
+ deriving (Read, Show, Eq)
+
+type GitAnnexVersion = String
+
+data AutoUpgrade = AskUpgrade | AutoUpgrade | NoAutoUpgrade
+ deriving (Eq)
+
+toAutoUpgrade :: (Maybe String) -> AutoUpgrade
+toAutoUpgrade Nothing = AskUpgrade
+toAutoUpgrade (Just s)
+ | s == "ask" = AskUpgrade
+ | isTrue s == Just True = AutoUpgrade
+ | otherwise = NoAutoUpgrade
+
+fromAutoUpgrade :: AutoUpgrade -> String
+fromAutoUpgrade AskUpgrade = "ask"
+fromAutoUpgrade AutoUpgrade = boolConfig True
+fromAutoUpgrade NoAutoUpgrade = boolConfig False
diff --git a/Types/FileMatcher.hs b/Types/FileMatcher.hs
new file mode 100644
index 000000000..fc442b604
--- /dev/null
+++ b/Types/FileMatcher.hs
@@ -0,0 +1,13 @@
+{- git-annex file matcher types
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Types.FileMatcher where
+
+data FileInfo = FileInfo
+ { relFile :: FilePath -- may be relative to cwd
+ , matchFile :: FilePath -- filepath to match on; may be relative to top
+ }
diff --git a/Types/GitConfig.hs b/Types/GitConfig.hs
new file mode 100644
index 000000000..7224f43ff
--- /dev/null
+++ b/Types/GitConfig.hs
@@ -0,0 +1,157 @@
+{- git-annex configuration
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Types.GitConfig (
+ GitConfig(..),
+ extractGitConfig,
+ RemoteGitConfig(..),
+ extractRemoteGitConfig,
+) where
+
+import Common
+import qualified Git
+import qualified Git.Config
+import Utility.DataUnits
+import Config.Cost
+import Types.Distribution
+
+{- Main git-annex settings. Each setting corresponds to a git-config key
+ - such as annex.foo -}
+data GitConfig = GitConfig
+ { annexVersion :: Maybe String
+ , annexNumCopies :: Int
+ , annexDiskReserve :: Integer
+ , annexDirect :: Bool
+ , annexBackends :: [String]
+ , annexQueueSize :: Maybe Int
+ , annexBloomCapacity :: Maybe Int
+ , annexBloomAccuracy :: Maybe Int
+ , annexSshCaching :: Maybe Bool
+ , annexAlwaysCommit :: Bool
+ , annexDelayAdd :: Maybe Int
+ , annexHttpHeaders :: [String]
+ , annexHttpHeadersCommand :: Maybe String
+ , annexAutoCommit :: Bool
+ , annexDebug :: Bool
+ , annexWebOptions :: [String]
+ , annexQuviOptions :: [String]
+ , annexWebDownloadCommand :: Maybe String
+ , annexCrippledFileSystem :: Bool
+ , annexLargeFiles :: Maybe String
+ , annexFsckNudge :: Bool
+ , annexAutoUpgrade :: AutoUpgrade
+ , coreSymlinks :: Bool
+ , gcryptId :: Maybe String
+ }
+
+extractGitConfig :: Git.Repo -> GitConfig
+extractGitConfig r = GitConfig
+ { annexVersion = notempty $ getmaybe (annex "version")
+ , annexNumCopies = get (annex "numcopies") 1
+ , annexDiskReserve = fromMaybe onemegabyte $
+ readSize dataUnits =<< getmaybe (annex "diskreserve")
+ , annexDirect = getbool (annex "direct") False
+ , annexBackends = getwords (annex "backends")
+ , annexQueueSize = getmayberead (annex "queuesize")
+ , annexBloomCapacity = getmayberead (annex "bloomcapacity")
+ , annexBloomAccuracy = getmayberead (annex "bloomaccuracy")
+ , annexSshCaching = getmaybebool (annex "sshcaching")
+ , annexAlwaysCommit = getbool (annex "alwayscommit") True
+ , annexDelayAdd = getmayberead (annex "delayadd")
+ , annexHttpHeaders = getlist (annex "http-headers")
+ , annexHttpHeadersCommand = getmaybe (annex "http-headers-command")
+ , annexAutoCommit = getbool (annex "autocommit") True
+ , annexDebug = getbool (annex "debug") False
+ , annexWebOptions = getwords (annex "web-options")
+ , annexQuviOptions = getwords (annex "quvi-options")
+ , annexWebDownloadCommand = getmaybe (annex "web-download-command")
+ , annexCrippledFileSystem = getbool (annex "crippledfilesystem") False
+ , annexLargeFiles = getmaybe (annex "largefiles")
+ , annexFsckNudge = getbool (annex "fscknudge") True
+ , annexAutoUpgrade = toAutoUpgrade $ getmaybe (annex "autoupgrade")
+ , coreSymlinks = getbool "core.symlinks" True
+ , gcryptId = getmaybe "core.gcrypt-id"
+ }
+ where
+ get k def = fromMaybe def $ getmayberead k
+ getbool k def = fromMaybe def $ getmaybebool k
+ getmaybebool k = Git.Config.isTrue =<< getmaybe k
+ getmayberead k = readish =<< getmaybe k
+ getmaybe k = Git.Config.getMaybe k r
+ getlist k = Git.Config.getList k r
+ getwords k = fromMaybe [] $ words <$> getmaybe k
+
+ annex k = "annex." ++ k
+
+ onemegabyte = 1000000
+
+{- Per-remote git-annex settings. Each setting corresponds to a git-config
+ - key such as <remote>.annex-foo, or if that is not set, a default from
+ - annex.foo -}
+data RemoteGitConfig = RemoteGitConfig
+ { remoteAnnexCost :: Maybe Cost
+ , remoteAnnexCostCommand :: Maybe String
+ , remoteAnnexIgnore :: Bool
+ , remoteAnnexSync :: Bool
+ , remoteAnnexTrustLevel :: Maybe String
+ , remoteAnnexStartCommand :: Maybe String
+ , remoteAnnexStopCommand :: Maybe String
+
+ {- These settings are specific to particular types of remotes
+ - including special remotes. -}
+ , remoteAnnexSshOptions :: [String]
+ , remoteAnnexRsyncOptions :: [String]
+ , remoteAnnexRsyncTransport :: [String]
+ , remoteAnnexGnupgOptions :: [String]
+ , remoteAnnexRsyncUrl :: Maybe String
+ , remoteAnnexBupRepo :: Maybe String
+ , remoteAnnexBupSplitOptions :: [String]
+ , remoteAnnexDirectory :: Maybe FilePath
+ , remoteAnnexGCrypt :: Maybe String
+ , remoteAnnexHookType :: Maybe String
+ {- A regular git remote's git repository config. -}
+ , remoteGitConfig :: Maybe GitConfig
+ }
+
+extractRemoteGitConfig :: Git.Repo -> String -> RemoteGitConfig
+extractRemoteGitConfig r remotename = RemoteGitConfig
+ { remoteAnnexCost = getmayberead "cost"
+ , remoteAnnexCostCommand = notempty $ getmaybe "cost-command"
+ , remoteAnnexIgnore = getbool "ignore" False
+ , remoteAnnexSync = getbool "sync" True
+ , remoteAnnexTrustLevel = notempty $ getmaybe "trustlevel"
+ , remoteAnnexStartCommand = notempty $ getmaybe "start-command"
+ , remoteAnnexStopCommand = notempty $ getmaybe "stop-command"
+
+ , remoteAnnexSshOptions = getoptions "ssh-options"
+ , remoteAnnexRsyncOptions = getoptions "rsync-options"
+ , remoteAnnexRsyncTransport = getoptions "rsync-transport"
+ , remoteAnnexGnupgOptions = getoptions "gnupg-options"
+ , remoteAnnexRsyncUrl = notempty $ getmaybe "rsyncurl"
+ , remoteAnnexBupRepo = getmaybe "buprepo"
+ , remoteAnnexBupSplitOptions = getoptions "bup-split-options"
+ , remoteAnnexDirectory = notempty $ getmaybe "directory"
+ , remoteAnnexGCrypt = notempty $ getmaybe "gcrypt"
+ , remoteAnnexHookType = notempty $ getmaybe "hooktype"
+ , remoteGitConfig = Nothing
+ }
+ where
+ getbool k def = fromMaybe def $ getmaybebool k
+ getmaybebool k = Git.Config.isTrue =<< getmaybe k
+ getmayberead k = readish =<< getmaybe k
+ getmaybe k = mplus (Git.Config.getMaybe (key k) r)
+ (Git.Config.getMaybe (remotekey k) r)
+ getoptions k = fromMaybe [] $ words <$> getmaybe k
+
+ key k = "annex." ++ k
+ remotekey k = "remote." ++ remotename ++ ".annex-" ++ k
+
+notempty :: Maybe String -> Maybe String
+notempty Nothing = Nothing
+notempty (Just "") = Nothing
+notempty (Just s) = Just s
+
diff --git a/Types/Group.hs b/Types/Group.hs
new file mode 100644
index 000000000..88bc35207
--- /dev/null
+++ b/Types/Group.hs
@@ -0,0 +1,27 @@
+{- git-annex repo groups
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Types.Group (
+ Group,
+ GroupMap(..),
+ emptyGroupMap
+) where
+
+import Types.UUID
+
+import qualified Data.Map as M
+import qualified Data.Set as S
+
+type Group = String
+
+data GroupMap = GroupMap
+ { groupsByUUID :: M.Map UUID (S.Set Group)
+ , uuidsByGroup :: M.Map Group (S.Set UUID)
+ }
+
+emptyGroupMap :: GroupMap
+emptyGroupMap = GroupMap M.empty M.empty
diff --git a/Types/Key.hs b/Types/Key.hs
new file mode 100644
index 000000000..598d5ed20
--- /dev/null
+++ b/Types/Key.hs
@@ -0,0 +1,96 @@
+{- git-annex Key data type
+ -
+ - Most things should not need this, using Types instead
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Types.Key (
+ Key(..),
+ AssociatedFile,
+ stubKey,
+ key2file,
+ file2key,
+
+ prop_idempotent_key_encode,
+ prop_idempotent_key_decode
+) where
+
+import System.Posix.Types
+
+import Common
+import Utility.QuickCheck
+
+{- A Key has a unique name, which is derived from a particular backend,
+ - and may contain other optional metadata. -}
+data Key = Key
+ { keyName :: String
+ , keyBackendName :: String
+ , keySize :: Maybe Integer
+ , keyMtime :: Maybe EpochTime
+ } deriving (Eq, Ord, Read, Show)
+
+{- A filename may be associated with a Key. -}
+type AssociatedFile = Maybe FilePath
+
+stubKey :: Key
+stubKey = Key
+ { keyName = ""
+ , keyBackendName = ""
+ , keySize = Nothing
+ , keyMtime = Nothing
+ }
+
+fieldSep :: Char
+fieldSep = '-'
+
+{- Converts a key to a string that is suitable for use as a filename.
+ - The name field is always shown last, separated by doubled fieldSeps,
+ - and is the only field allowed to contain the fieldSep. -}
+key2file :: Key -> FilePath
+key2file Key { keyBackendName = b, keySize = s, keyMtime = m, keyName = n } =
+ b +++ ('s' ?: s) +++ ('m' ?: m) +++ (fieldSep : n)
+ where
+ "" +++ y = y
+ x +++ "" = x
+ x +++ y = x ++ fieldSep:y
+ c ?: (Just v) = c : show v
+ _ ?: _ = ""
+
+file2key :: FilePath -> Maybe Key
+file2key s
+ | key == Just stubKey || (keyName <$> key) == Just "" || (keyBackendName <$> key) == Just "" = Nothing
+ | otherwise = key
+ where
+ key = startbackend stubKey s
+
+ startbackend k v = sepfield k v addbackend
+
+ sepfield k v a = case span (/= fieldSep) v of
+ (v', _:r) -> findfields r $ a k v'
+ _ -> Nothing
+
+ findfields (c:v) (Just k)
+ | c == fieldSep = Just $ k { keyName = v }
+ | otherwise = sepfield k v $ addfield c
+ findfields _ v = v
+
+ addbackend k v = Just k { keyBackendName = v }
+ addfield 's' k v = Just k { keySize = readish v }
+ addfield 'm' k v = Just k { keyMtime = readish v }
+ addfield _ _ _ = Nothing
+
+instance Arbitrary Key where
+ arbitrary = Key
+ <$> (listOf1 $ elements $ ['A'..'Z'] ++ ['a'..'z'] ++ ['0'..'9'] ++ "-_\r\n \t")
+ <*> (listOf1 $ elements ['A'..'Z']) -- BACKEND
+ <*> ((abs <$>) <$> arbitrary) -- size cannot be negative
+ <*> arbitrary
+
+prop_idempotent_key_encode :: Key -> Bool
+prop_idempotent_key_encode k = Just k == (file2key . key2file) k
+
+prop_idempotent_key_decode :: FilePath -> Bool
+prop_idempotent_key_decode f = maybe True (\k -> key2file k == f) (file2key f)
diff --git a/Types/KeySource.hs b/Types/KeySource.hs
new file mode 100644
index 000000000..fd4af07a6
--- /dev/null
+++ b/Types/KeySource.hs
@@ -0,0 +1,29 @@
+{- KeySource data type
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Types.KeySource where
+
+import Utility.InodeCache
+
+{- When content is in the process of being added to the annex,
+ - and a Key generated from it, this data type is used.
+ -
+ - The contentLocation may be different from the filename
+ - associated with the key. For example, the add command
+ - may temporarily hard link the content into a lockdown directory
+ - for checking. The migrate command uses the content
+ - of a different Key.
+ -
+ - The inodeCache can be used to detect some types of modifications to
+ - files that may be made while they're in the process of being added.
+ -}
+data KeySource = KeySource
+ { keyFilename :: FilePath
+ , contentLocation :: FilePath
+ , inodeCache :: Maybe InodeCache
+ }
+ deriving (Show)
diff --git a/Types/Limit.hs b/Types/Limit.hs
new file mode 100644
index 000000000..4436f6953
--- /dev/null
+++ b/Types/Limit.hs
@@ -0,0 +1,20 @@
+{- types for limits
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Types.Limit where
+
+import Common.Annex
+import Types.FileMatcher
+
+import qualified Data.Set as S
+
+type MkLimit = String -> Either String MatchFiles
+
+type AssumeNotPresent = S.Set UUID
+type MatchFiles = AssumeNotPresent -> FileInfo -> Annex Bool
diff --git a/Types/Messages.hs b/Types/Messages.hs
new file mode 100644
index 000000000..4fcce79f8
--- /dev/null
+++ b/Types/Messages.hs
@@ -0,0 +1,24 @@
+{- git-annex Messages data types
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Types.Messages where
+
+import qualified Data.Set as S
+
+data OutputType = NormalOutput | QuietOutput | JSONOutput
+
+data SideActionBlock = NoBlock | StartBlock | InBlock
+ deriving (Eq)
+
+data MessageState = MessageState
+ { outputType :: OutputType
+ , sideActionBlock :: SideActionBlock
+ , fileNotFoundShown :: S.Set FilePath
+ }
+
+defaultMessageState :: MessageState
+defaultMessageState = MessageState NormalOutput NoBlock S.empty
diff --git a/Types/Option.hs b/Types/Option.hs
new file mode 100644
index 000000000..036257838
--- /dev/null
+++ b/Types/Option.hs
@@ -0,0 +1,17 @@
+{- git-annex command options
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Types.Option where
+
+import System.Console.GetOpt
+
+import Annex
+
+{- Each dashed command-line option results in generation of an action
+ - in the Annex monad that performs the necessary setting.
+ -}
+type Option = OptDescr (Annex ())
diff --git a/Types/Remote.hs b/Types/Remote.hs
new file mode 100644
index 000000000..8a94dcc05
--- /dev/null
+++ b/Types/Remote.hs
@@ -0,0 +1,98 @@
+{- git-annex remotes types
+ -
+ - Most things should not need this, using Types instead
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Types.Remote where
+
+import Data.Map as M
+import Data.Ord
+
+import qualified Git
+import Types.Key
+import Types.UUID
+import Types.GitConfig
+import Config.Cost
+import Utility.Metered
+import Git.Types
+import Utility.SafeCommand
+
+type RemoteConfigKey = String
+type RemoteConfig = M.Map RemoteConfigKey String
+
+{- There are different types of remotes. -}
+data RemoteTypeA a = RemoteType {
+ -- human visible type name
+ typename :: String,
+ -- enumerates remotes of this type
+ enumerate :: a [Git.Repo],
+ -- generates a remote of this type
+ generate :: Git.Repo -> UUID -> RemoteConfig -> RemoteGitConfig -> a (Maybe (RemoteA a)),
+ -- initializes or changes a remote
+ setup :: Maybe UUID -> RemoteConfig -> a (RemoteConfig, UUID)
+}
+
+instance Eq (RemoteTypeA a) where
+ x == y = typename x == typename y
+
+{- An individual remote. -}
+data RemoteA a = Remote {
+ -- each Remote has a unique uuid
+ uuid :: UUID,
+ -- each Remote has a human visible name
+ name :: RemoteName,
+ -- Remotes have a use cost; higher is more expensive
+ cost :: Cost,
+ -- Transfers a key to the remote.
+ storeKey :: Key -> AssociatedFile -> MeterUpdate -> a Bool,
+ -- Retrieves a key's contents to a file.
+ -- (The MeterUpdate does not need to be used if it retrieves
+ -- directly to the file, and not to an intermediate file.)
+ retrieveKeyFile :: Key -> AssociatedFile -> FilePath -> MeterUpdate -> a Bool,
+ -- retrieves a key's contents to a tmp file, if it can be done cheaply
+ retrieveKeyFileCheap :: Key -> FilePath -> a Bool,
+ -- removes a key's contents
+ removeKey :: Key -> a Bool,
+ -- Checks if a key is present in the remote; if the remote
+ -- cannot be accessed returns a Left error message.
+ hasKey :: Key -> a (Either String Bool),
+ -- Some remotes can check hasKey without an expensive network
+ -- operation.
+ hasKeyCheap :: Bool,
+ -- Some remotes can provide additional details for whereis.
+ whereisKey :: Maybe (Key -> a [String]),
+ -- Some remotes can run a fsck operation on the remote,
+ -- without transferring all the data to the local repo
+ -- The parameters are passed to the fsck command on the remote.
+ remoteFsck :: Maybe ([CommandParam] -> a (IO Bool)),
+ -- Runs an action to repair the remote's git repository.
+ repairRepo :: Maybe (a Bool -> a (IO Bool)),
+ -- a Remote has a persistent configuration store
+ config :: RemoteConfig,
+ -- git repo for the Remote
+ repo :: Git.Repo,
+ -- a Remote's configuration from git
+ gitconfig :: RemoteGitConfig,
+ -- a Remote can be assocated with a specific local filesystem path
+ localpath :: Maybe FilePath,
+ -- a Remote can be known to be readonly
+ readonly :: Bool,
+ -- a Remote can be globally available. (Ie, "in the cloud".)
+ globallyAvailable :: Bool,
+ -- the type of the remote
+ remotetype :: RemoteTypeA a
+}
+
+instance Show (RemoteA a) where
+ show remote = "Remote { name =\"" ++ name remote ++ "\" }"
+
+-- two remotes are the same if they have the same uuid
+instance Eq (RemoteA a) where
+ x == y = uuid x == uuid y
+
+instance Ord (RemoteA a) where
+ compare = comparing uuid
diff --git a/Types/ScheduledActivity.hs b/Types/ScheduledActivity.hs
new file mode 100644
index 000000000..b683409ce
--- /dev/null
+++ b/Types/ScheduledActivity.hs
@@ -0,0 +1,69 @@
+{- git-annex scheduled activities
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Types.ScheduledActivity where
+
+import Common
+import Utility.Scheduled
+import Utility.HumanTime
+import Types.UUID
+
+import Data.Either
+
+data ScheduledActivity
+ = ScheduledSelfFsck Schedule Duration
+ | ScheduledRemoteFsck UUID Schedule Duration
+ deriving (Eq, Read, Show, Ord)
+
+{- Activities that run on a remote, within a time window, so
+ - should be run when the remote gets connected. -}
+connectActivityUUID :: ScheduledActivity -> Maybe UUID
+connectActivityUUID (ScheduledRemoteFsck u (Schedule _ AnyTime) _) = Just u
+connectActivityUUID _ = Nothing
+
+getSchedule :: ScheduledActivity -> Schedule
+getSchedule (ScheduledSelfFsck s _) = s
+getSchedule (ScheduledRemoteFsck _ s _) = s
+
+getDuration :: ScheduledActivity -> Duration
+getDuration (ScheduledSelfFsck _ d) = d
+getDuration (ScheduledRemoteFsck _ _ d) = d
+
+fromScheduledActivity :: ScheduledActivity -> String
+fromScheduledActivity (ScheduledSelfFsck s d) = unwords
+ [ "fsck self", fromDuration d, fromSchedule s ]
+fromScheduledActivity (ScheduledRemoteFsck u s d) = unwords
+ [ "fsck", fromUUID u, fromDuration d, fromSchedule s ]
+
+toScheduledActivity :: String -> Maybe ScheduledActivity
+toScheduledActivity = eitherToMaybe . parseScheduledActivity
+
+parseScheduledActivity :: String -> Either String ScheduledActivity
+parseScheduledActivity s = case words s of
+ ("fsck":"self":d:rest) -> qualified $ ScheduledSelfFsck
+ <$> parseSchedule (unwords rest)
+ <*> getduration d
+ ("fsck":u:d:rest) -> qualified $ ScheduledRemoteFsck
+ <$> pure (toUUID u)
+ <*> parseSchedule (unwords rest)
+ <*> getduration d
+ _ -> qualified $ Left "unknown activity"
+ where
+ qualified (Left e) = Left $ e ++ " in \"" ++ s ++ "\""
+ qualified v = v
+ getduration d = maybe (Left $ "failed to parse duration \""++d++"\"") Right (parseDuration d)
+
+fromScheduledActivities :: [ScheduledActivity] -> String
+fromScheduledActivities = intercalate "; " . map fromScheduledActivity
+
+parseScheduledActivities :: String -> Either String [ScheduledActivity]
+parseScheduledActivities s
+ | null bad = Right good
+ | otherwise = Left $ intercalate "; " bad
+ where
+ (bad, good) = partitionEithers $
+ map parseScheduledActivity $ split "; " s
diff --git a/Types/StandardGroups.hs b/Types/StandardGroups.hs
new file mode 100644
index 000000000..2d977a357
--- /dev/null
+++ b/Types/StandardGroups.hs
@@ -0,0 +1,96 @@
+{- git-annex standard repository groups
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Types.StandardGroups where
+
+import Types.Remote (RemoteConfig)
+
+import qualified Data.Map as M
+import Data.Maybe
+
+data StandardGroup
+ = ClientGroup
+ | TransferGroup
+ | BackupGroup
+ | IncrementalBackupGroup
+ | SmallArchiveGroup
+ | FullArchiveGroup
+ | SourceGroup
+ | ManualGroup
+ | PublicGroup
+ | UnwantedGroup
+ deriving (Eq, Ord, Enum, Bounded, Show)
+
+fromStandardGroup :: StandardGroup -> String
+fromStandardGroup ClientGroup = "client"
+fromStandardGroup TransferGroup = "transfer"
+fromStandardGroup BackupGroup = "backup"
+fromStandardGroup IncrementalBackupGroup = "incrementalbackup"
+fromStandardGroup SmallArchiveGroup = "smallarchive"
+fromStandardGroup FullArchiveGroup = "archive"
+fromStandardGroup SourceGroup = "source"
+fromStandardGroup ManualGroup = "manual"
+fromStandardGroup PublicGroup = "public"
+fromStandardGroup UnwantedGroup = "unwanted"
+
+toStandardGroup :: String -> Maybe StandardGroup
+toStandardGroup "client" = Just ClientGroup
+toStandardGroup "transfer" = Just TransferGroup
+toStandardGroup "backup" = Just BackupGroup
+toStandardGroup "incrementalbackup" = Just IncrementalBackupGroup
+toStandardGroup "smallarchive" = Just SmallArchiveGroup
+toStandardGroup "archive" = Just FullArchiveGroup
+toStandardGroup "source" = Just SourceGroup
+toStandardGroup "manual" = Just ManualGroup
+toStandardGroup "public" = Just PublicGroup
+toStandardGroup "unwanted" = Just UnwantedGroup
+toStandardGroup _ = Nothing
+
+descStandardGroup :: StandardGroup -> String
+descStandardGroup ClientGroup = "client: a repository on your computer"
+descStandardGroup TransferGroup = "transfer: distributes files to clients"
+descStandardGroup BackupGroup = "full backup: backs up all files"
+descStandardGroup IncrementalBackupGroup = "incremental backup: backs up files not backed up elsewhere"
+descStandardGroup SmallArchiveGroup = "small archive: archives files located in \"archive\" directories"
+descStandardGroup FullArchiveGroup = "full archive: archives all files not archived elsewhere"
+descStandardGroup SourceGroup = "file source: moves files on to other repositories"
+descStandardGroup ManualGroup = "manual mode: only stores files you manually choose"
+descStandardGroup UnwantedGroup = "unwanted: remove content from this repository"
+descStandardGroup PublicGroup = "public: publishes files located in an associated directory"
+
+associatedDirectory :: Maybe RemoteConfig -> StandardGroup -> Maybe FilePath
+associatedDirectory _ SmallArchiveGroup = Just "archive"
+associatedDirectory _ FullArchiveGroup = Just "archive"
+associatedDirectory (Just c) PublicGroup = Just $
+ fromMaybe "public" $ M.lookup "preferreddir" c
+associatedDirectory Nothing PublicGroup = Just "public"
+associatedDirectory _ _ = Nothing
+
+{- See doc/preferred_content.mdwn for explanations of these expressions. -}
+preferredContent :: StandardGroup -> String
+preferredContent ClientGroup = lastResort $
+ "(exclude=*/archive/* and exclude=archive/*) or (" ++ notArchived ++ ")"
+preferredContent TransferGroup = lastResort $
+ "not (inallgroup=client and copies=client:2) and (" ++ preferredContent ClientGroup ++ ")"
+preferredContent BackupGroup = "include=*"
+preferredContent IncrementalBackupGroup = lastResort
+ "include=* and (not copies=incrementalbackup:1)"
+preferredContent SmallArchiveGroup = lastResort $
+ "(include=*/archive/* or include=archive/*) and (" ++ preferredContent FullArchiveGroup ++ ")"
+preferredContent FullArchiveGroup = lastResort notArchived
+preferredContent SourceGroup = "not (copies=1)"
+preferredContent ManualGroup = "present and (" ++ preferredContent ClientGroup ++ ")"
+preferredContent PublicGroup = "inpreferreddir"
+preferredContent UnwantedGroup = "exclude=*"
+
+notArchived :: String
+notArchived = "not (copies=archive:1 or copies=smallarchive:1)"
+
+{- Most repositories want any content that is only on untrusted
+ - or dead repositories. -}
+lastResort :: String -> String
+lastResort s = "(" ++ s ++ ") or (not copies=semitrusted+:1)"
diff --git a/Types/TrustLevel.hs b/Types/TrustLevel.hs
new file mode 100644
index 000000000..a72dbb8c6
--- /dev/null
+++ b/Types/TrustLevel.hs
@@ -0,0 +1,43 @@
+{- git-annex trust levels
+ -
+ - Copyright 2010 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Types.TrustLevel (
+ TrustLevel(..),
+ TrustMap,
+ readTrustLevel,
+ showTrustLevel,
+ prop_read_show_TrustLevel
+) where
+
+import qualified Data.Map as M
+
+import Types.UUID
+
+-- This order may seem backwards, but we generally want to list dead
+-- remotes last and trusted ones first.
+data TrustLevel = Trusted | SemiTrusted | UnTrusted | DeadTrusted
+ deriving (Eq, Enum, Ord, Bounded)
+
+type TrustMap = M.Map UUID TrustLevel
+
+readTrustLevel :: String -> Maybe TrustLevel
+readTrustLevel "trusted" = Just Trusted
+readTrustLevel "untrusted" = Just UnTrusted
+readTrustLevel "semitrusted" = Just SemiTrusted
+readTrustLevel "dead" = Just DeadTrusted
+readTrustLevel _ = Nothing
+
+showTrustLevel :: TrustLevel -> String
+showTrustLevel Trusted = "trusted"
+showTrustLevel UnTrusted = "untrusted"
+showTrustLevel SemiTrusted = "semitrusted"
+showTrustLevel DeadTrusted = "dead"
+
+prop_read_show_TrustLevel :: Bool
+prop_read_show_TrustLevel = all check [minBound .. maxBound]
+ where
+ check l = readTrustLevel (showTrustLevel l) == Just l
diff --git a/Types/UUID.hs b/Types/UUID.hs
new file mode 100644
index 000000000..8a304dffa
--- /dev/null
+++ b/Types/UUID.hs
@@ -0,0 +1,24 @@
+{- git-annex UUID type
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Types.UUID where
+
+import qualified Data.Map as M
+
+-- A UUID is either an arbitrary opaque string, or UUID info may be missing.
+data UUID = NoUUID | UUID String
+ deriving (Eq, Ord, Show, Read)
+
+fromUUID :: UUID -> String
+fromUUID (UUID u) = u
+fromUUID NoUUID = ""
+
+toUUID :: String -> UUID
+toUUID [] = NoUUID
+toUUID s = UUID s
+
+type UUIDMap = M.Map UUID String
diff --git a/Upgrade.hs b/Upgrade.hs
new file mode 100644
index 000000000..7385268e8
--- /dev/null
+++ b/Upgrade.hs
@@ -0,0 +1,58 @@
+{- git-annex upgrade support
+ -
+ - Copyright 2010, 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Upgrade where
+
+import Common.Annex
+import Annex.Version
+import Config
+#ifndef mingw32_HOST_OS
+import qualified Upgrade.V0
+import qualified Upgrade.V1
+#endif
+import qualified Upgrade.V2
+import qualified Upgrade.V4
+
+checkUpgrade :: Version -> Annex ()
+checkUpgrade = maybe noop error <=< needsUpgrade
+
+needsUpgrade :: Version -> Annex (Maybe String)
+needsUpgrade v
+ | v `elem` supportedVersions = ok
+ | v `elem` autoUpgradeableVersions = ifM (upgrade True)
+ ( ok
+ , err "Automatic upgrade failed!"
+ )
+ | v `elem` upgradableVersions = err "Upgrade this repository: git-annex upgrade"
+ | otherwise = err "Upgrade git-annex."
+ where
+ err msg = return $ Just $ "Repository version " ++ v ++
+ " is not supported. " ++ msg
+ ok = return Nothing
+
+upgrade :: Bool -> Annex Bool
+upgrade automatic = do
+ upgraded <- go =<< getVersion
+ when upgraded $
+ ifM isDirect
+ ( setVersion directModeVersion
+ , setVersion defaultVersion
+ )
+ return upgraded
+ where
+#ifndef mingw32_HOST_OS
+ go (Just "0") = Upgrade.V0.upgrade
+ go (Just "1") = Upgrade.V1.upgrade
+#else
+ go (Just "0") = error "upgrade from v0 on Windows not supported"
+ go (Just "1") = error "upgrade from v1 on Windows not supported"
+#endif
+ go (Just "2") = Upgrade.V2.upgrade
+ go (Just "4") = Upgrade.V4.upgrade automatic
+ go _ = return True
diff --git a/Upgrade/V0.hs b/Upgrade/V0.hs
new file mode 100644
index 000000000..00a08cb45
--- /dev/null
+++ b/Upgrade/V0.hs
@@ -0,0 +1,49 @@
+{- git-annex v0 -> v1 upgrade support
+ -
+ - Copyright 2010 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Upgrade.V0 where
+
+import Common.Annex
+import Annex.Content
+import qualified Upgrade.V1
+
+upgrade :: Annex Bool
+upgrade = do
+ showAction "v0 to v1"
+
+ -- do the reorganisation of the key files
+ olddir <- fromRepo gitAnnexDir
+ keys <- getKeysPresent0 olddir
+ forM_ keys $ \k -> moveAnnex k $ olddir </> keyFile0 k
+
+ -- update the symlinks to the key files
+ -- No longer needed here; V1.upgrade does the same thing
+
+ -- Few people had v0 repos, so go the long way around from 0 -> 1 -> 2
+ Upgrade.V1.upgrade
+
+-- these stayed unchanged between v0 and v1
+keyFile0 :: Key -> FilePath
+keyFile0 = Upgrade.V1.keyFile1
+fileKey0 :: FilePath -> Key
+fileKey0 = Upgrade.V1.fileKey1
+lookupFile0 :: FilePath -> Annex (Maybe (Key, Backend))
+lookupFile0 = Upgrade.V1.lookupFile1
+
+getKeysPresent0 :: FilePath -> Annex [Key]
+getKeysPresent0 dir = ifM (liftIO $ doesDirectoryExist dir)
+ ( liftIO $ map fileKey0
+ <$> (filterM present =<< getDirectoryContents dir)
+ , return []
+ )
+ where
+ present d = do
+ result <- tryIO $
+ getFileStatus $ dir ++ "/" ++ takeFileName d
+ case result of
+ Right s -> return $ isRegularFile s
+ Left _ -> return False
diff --git a/Upgrade/V1.hs b/Upgrade/V1.hs
new file mode 100644
index 000000000..688f4c571
--- /dev/null
+++ b/Upgrade/V1.hs
@@ -0,0 +1,241 @@
+{- git-annex v1 -> v2 upgrade support
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Upgrade.V1 where
+
+import System.Posix.Types
+import Data.Char
+
+import Common.Annex
+import Types.Key
+import Annex.Content
+import Logs.Presence
+import qualified Annex.Queue
+import qualified Git
+import qualified Git.LsFiles as LsFiles
+import Backend
+import Annex.Version
+import Utility.FileMode
+import Utility.Tmp
+import qualified Upgrade.V2
+
+-- v2 adds hashing of filenames of content and location log files.
+-- Key information is encoded in filenames differently, so
+-- both content and location log files move around, and symlinks
+-- to content need to be changed.
+--
+-- When upgrading a v1 key to v2, file size metadata ought to be
+-- added to the key (unless it is a WORM key, which encoded
+-- mtime:size in v1). This can only be done when the file content
+-- is present. Since upgrades need to happen consistently,
+-- (so that two repos get changed the same way by the upgrade, and
+-- will merge), that metadata cannot be added on upgrade.
+--
+-- Note that file size metadata
+-- will only be used for detecting situations where git-annex
+-- would run out of disk space, so if some keys don't have it,
+-- the impact is minor. At least initially. It could be used in the
+-- future by smart auto-repo balancing code, etc.
+--
+-- Anyway, since v2 plans ahead for other metadata being included
+-- in keys, there should probably be a way to update a key.
+-- Something similar to the migrate subcommand could be used,
+-- and users could then run that at their leisure.
+
+upgrade :: Annex Bool
+upgrade = do
+ showAction "v1 to v2"
+
+ ifM (fromRepo Git.repoIsLocalBare)
+ ( do
+ moveContent
+ setVersion defaultVersion
+ , do
+ moveContent
+ updateSymlinks
+ moveLocationLogs
+
+ Annex.Queue.flush
+ setVersion defaultVersion
+ )
+
+ Upgrade.V2.upgrade
+
+moveContent :: Annex ()
+moveContent = do
+ showAction "moving content"
+ files <- getKeyFilesPresent1
+ forM_ files move
+ where
+ move f = do
+ let k = fileKey1 (takeFileName f)
+ let d = parentDir f
+ liftIO $ allowWrite d
+ liftIO $ allowWrite f
+ moveAnnex k f
+ liftIO $ removeDirectory d
+
+updateSymlinks :: Annex ()
+updateSymlinks = do
+ showAction "updating symlinks"
+ top <- fromRepo Git.repoPath
+ (files, cleanup) <- inRepo $ LsFiles.inRepo [top]
+ forM_ files fixlink
+ void $ liftIO cleanup
+ where
+ fixlink f = do
+ r <- lookupFile1 f
+ case r of
+ Nothing -> noop
+ Just (k, _) -> do
+ link <- inRepo $ gitAnnexLink f k
+ liftIO $ removeFile f
+ liftIO $ createSymbolicLink link f
+ Annex.Queue.addCommand "add" [Param "--"] [f]
+
+moveLocationLogs :: Annex ()
+moveLocationLogs = do
+ showAction "moving location logs"
+ logkeys <- oldlocationlogs
+ forM_ logkeys move
+ where
+ oldlocationlogs = do
+ dir <- fromRepo Upgrade.V2.gitStateDir
+ ifM (liftIO $ doesDirectoryExist dir)
+ ( mapMaybe oldlog2key
+ <$> liftIO (getDirectoryContents dir)
+ , return []
+ )
+ move (l, k) = do
+ dest <- fromRepo $ logFile2 k
+ dir <- fromRepo Upgrade.V2.gitStateDir
+ let f = dir </> l
+ liftIO $ createDirectoryIfMissing True (parentDir dest)
+ -- could just git mv, but this way deals with
+ -- log files that are not checked into git,
+ -- as well as merging with already upgraded
+ -- logs that have been pulled from elsewhere
+ old <- liftIO $ readLog1 f
+ new <- liftIO $ readLog1 dest
+ liftIO $ writeLog1 dest (old++new)
+ Annex.Queue.addCommand "add" [Param "--"] [dest]
+ Annex.Queue.addCommand "add" [Param "--"] [f]
+ Annex.Queue.addCommand "rm" [Param "--quiet", Param "-f", Param "--"] [f]
+
+oldlog2key :: FilePath -> Maybe (FilePath, Key)
+oldlog2key l
+ | drop len l == ".log" && sane = Just (l, k)
+ | otherwise = Nothing
+ where
+ len = length l - 4
+ k = readKey1 (take len l)
+ sane = (not . null $ keyName k) && (not . null $ keyBackendName k)
+
+-- WORM backend keys: "WORM:mtime:size:filename"
+-- all the rest: "backend:key"
+--
+-- If the file looks like "WORM:XXX-...", then it was created by mixing
+-- v2 and v1; that infelicity is worked around by treating the value
+-- as the v2 key that it is.
+readKey1 :: String -> Key
+readKey1 v
+ | mixup = fromJust $ file2key $ intercalate ":" $ Prelude.tail bits
+ | otherwise = Key
+ { keyName = n
+ , keyBackendName = b
+ , keySize = s
+ , keyMtime = t
+ }
+ where
+ bits = split ":" v
+ b = Prelude.head bits
+ n = intercalate ":" $ drop (if wormy then 3 else 1) bits
+ t = if wormy
+ then Just (Prelude.read (bits !! 1) :: EpochTime)
+ else Nothing
+ s = if wormy
+ then Just (Prelude.read (bits !! 2) :: Integer)
+ else Nothing
+ wormy = Prelude.head bits == "WORM"
+ mixup = wormy && isUpper (Prelude.head $ bits !! 1)
+
+showKey1 :: Key -> String
+showKey1 Key { keyName = n , keyBackendName = b, keySize = s, keyMtime = t } =
+ intercalate ":" $ filter (not . null) [b, showifhere t, showifhere s, n]
+ where
+ showifhere Nothing = ""
+ showifhere (Just v) = show v
+
+keyFile1 :: Key -> FilePath
+keyFile1 key = replace "/" "%" $ replace "%" "&s" $ replace "&" "&a" $ showKey1 key
+
+fileKey1 :: FilePath -> Key
+fileKey1 file = readKey1 $
+ replace "&a" "&" $ replace "&s" "%" $ replace "%" "/" file
+
+writeLog1 :: FilePath -> [LogLine] -> IO ()
+writeLog1 file ls = viaTmp writeFile file (showLog ls)
+
+readLog1 :: FilePath -> IO [LogLine]
+readLog1 file = catchDefaultIO [] $
+ parseLog <$> readFileStrict file
+
+lookupFile1 :: FilePath -> Annex (Maybe (Key, Backend))
+lookupFile1 file = do
+ tl <- liftIO $ tryIO getsymlink
+ case tl of
+ Left _ -> return Nothing
+ Right l -> makekey l
+ where
+ getsymlink = takeFileName <$> readSymbolicLink file
+ makekey l = case maybeLookupBackendName bname of
+ Nothing -> do
+ unless (null kname || null bname ||
+ not (isLinkToAnnex l)) $
+ warning skip
+ return Nothing
+ Just backend -> return $ Just (k, backend)
+ where
+ k = fileKey1 l
+ bname = keyBackendName k
+ kname = keyName k
+ skip = "skipping " ++ file ++
+ " (unknown backend " ++ bname ++ ")"
+
+getKeyFilesPresent1 :: Annex [FilePath]
+getKeyFilesPresent1 = getKeyFilesPresent1' =<< fromRepo gitAnnexObjectDir
+getKeyFilesPresent1' :: FilePath -> Annex [FilePath]
+getKeyFilesPresent1' dir =
+ ifM (liftIO $ doesDirectoryExist dir)
+ ( do
+ dirs <- liftIO $ getDirectoryContents dir
+ let files = map (\d -> dir ++ "/" ++ d ++ "/" ++ takeFileName d) dirs
+ liftIO $ filterM present files
+ , return []
+ )
+ where
+ present f = do
+ result <- tryIO $ getFileStatus f
+ case result of
+ Right s -> return $ isRegularFile s
+ Left _ -> return False
+
+logFile1 :: Git.Repo -> Key -> String
+logFile1 repo key = Upgrade.V2.gitStateDir repo ++ keyFile1 key ++ ".log"
+
+logFile2 :: Key -> Git.Repo -> String
+logFile2 = logFile' hashDirLower
+
+logFile' :: (Key -> FilePath) -> Key -> Git.Repo -> String
+logFile' hasher key repo =
+ gitStateDir repo ++ hasher key ++ keyFile key ++ ".log"
+
+stateDir :: FilePath
+stateDir = addTrailingPathSeparator ".git-annex"
+
+gitStateDir :: Git.Repo -> FilePath
+gitStateDir repo = addTrailingPathSeparator $ Git.repoPath repo </> stateDir
diff --git a/Upgrade/V2.hs b/Upgrade/V2.hs
new file mode 100644
index 000000000..42419b8ab
--- /dev/null
+++ b/Upgrade/V2.hs
@@ -0,0 +1,137 @@
+{- git-annex v2 -> v3 upgrade support
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Upgrade.V2 where
+
+import Common.Annex
+import qualified Git
+import qualified Git.Command
+import qualified Git.Ref
+import qualified Annex.Branch
+import Annex.Content
+import Utility.Tmp
+import Logs
+
+olddir :: Git.Repo -> FilePath
+olddir g
+ | Git.repoIsLocalBare g = ""
+ | otherwise = ".git-annex"
+
+{- .git-annex/ moved to a git-annex branch.
+ -
+ - Strategy:
+ -
+ - * Create the git-annex branch.
+ - * Find each location log file in .git-annex/, and inject its content
+ - into the git-annex branch, unioning with any content already in
+ - there. (in passing, this deals with the semi transition that left
+ - some location logs hashed two different ways; both are found and
+ - merged).
+ - * Also inject remote.log, trust.log, and uuid.log.
+ - * git rm -rf .git-annex
+ - * Remove stuff that used to be needed in .gitattributes.
+ - * Commit changes.
+ -}
+upgrade :: Annex Bool
+upgrade = do
+ showAction "v2 to v3"
+ bare <- fromRepo Git.repoIsLocalBare
+ old <- fromRepo olddir
+
+ Annex.Branch.create
+ showProgress
+
+ e <- liftIO $ doesDirectoryExist old
+ when e $ do
+ mapM_ (\(k, f) -> inject f $ locationLogFile k) =<< locationLogs
+ mapM_ (\f -> inject f f) =<< logFiles old
+
+ saveState False
+ showProgress
+
+ when e $ do
+ inRepo $ Git.Command.run [Param "rm", Param "-r", Param "-f", Param "-q", File old]
+ unless bare $ inRepo gitAttributesUnWrite
+ showProgress
+
+ unless bare push
+
+ return True
+
+locationLogs :: Annex [(Key, FilePath)]
+locationLogs = do
+ dir <- fromRepo gitStateDir
+ liftIO $ do
+ levela <- dirContents dir
+ levelb <- mapM tryDirContents levela
+ files <- mapM tryDirContents (concat levelb)
+ return $ mapMaybe islogfile (concat files)
+ where
+ tryDirContents d = catchDefaultIO [] $ dirContents d
+ islogfile f = maybe Nothing (\k -> Just (k, f)) $
+ locationLogFileKey f
+
+inject :: FilePath -> FilePath -> Annex ()
+inject source dest = do
+ old <- fromRepo olddir
+ new <- liftIO (readFile $ old </> source)
+ Annex.Branch.change dest $ \prev ->
+ unlines $ nub $ lines prev ++ lines new
+
+logFiles :: FilePath -> Annex [FilePath]
+logFiles dir = return . filter (".log" `isSuffixOf`)
+ <=< liftIO $ getDirectoryContents dir
+
+push :: Annex ()
+push = do
+ origin_master <- inRepo $ Git.Ref.exists $ Git.Ref "origin/master"
+ origin_gitannex <- Annex.Branch.hasOrigin
+ case (origin_master, origin_gitannex) of
+ (_, True) -> do
+ -- Merge in the origin's git-annex branch,
+ -- so that pushing the git-annex branch
+ -- will immediately work. Not pushed here,
+ -- because it's less obnoxious to let the user
+ -- push.
+ Annex.Branch.update
+ (True, False) -> do
+ -- push git-annex to origin, so that
+ -- "git push" will from then on
+ -- automatically push it
+ Annex.Branch.update -- just in case
+ showAction "pushing new git-annex branch to origin"
+ showOutput
+ inRepo $ Git.Command.run
+ [Param "push", Param "origin", Param $ show Annex.Branch.name]
+ _ -> do
+ -- no origin exists, so just let the user
+ -- know about the new branch
+ Annex.Branch.update
+ showLongNote $
+ "git-annex branch created\n" ++
+ "Be sure to push this branch when pushing to remotes.\n"
+
+{- Old .gitattributes contents, not needed anymore. -}
+attrLines :: [String]
+attrLines =
+ [ stateDir </> "*.log merge=union"
+ , stateDir </> "*/*/*.log merge=union"
+ ]
+
+gitAttributesUnWrite :: Git.Repo -> IO ()
+gitAttributesUnWrite repo = do
+ let attributes = Git.attributes repo
+ whenM (doesFileExist attributes) $ do
+ c <- readFileStrict attributes
+ liftIO $ viaTmp writeFile attributes $ unlines $
+ filter (`notElem` attrLines) $ lines c
+ Git.Command.run [Param "add", File attributes] repo
+
+stateDir :: FilePath
+stateDir = addTrailingPathSeparator ".git-annex"
+gitStateDir :: Git.Repo -> FilePath
+gitStateDir repo = addTrailingPathSeparator $ Git.repoPath repo </> stateDir
diff --git a/Upgrade/V4.hs b/Upgrade/V4.hs
new file mode 100644
index 000000000..147ace559
--- /dev/null
+++ b/Upgrade/V4.hs
@@ -0,0 +1,23 @@
+{- git-annex v4 -> v5 uppgrade support
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Upgrade.V4 where
+
+import Common.Annex
+import Config
+import Annex.Direct
+
+{- Direct mode only upgrade. -}
+upgrade :: Bool -> Annex Bool
+upgrade automatic = ifM isDirect
+ ( do
+ unless automatic $
+ showAction "v4 to v5"
+ setDirect True
+ return True
+ , return False
+ )
diff --git a/Usage.hs b/Usage.hs
new file mode 100644
index 000000000..9a48a0908
--- /dev/null
+++ b/Usage.hs
@@ -0,0 +1,111 @@
+{- git-annex usage messages
+ -
+ - Copyright 2010-2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Usage where
+
+import Common.Annex
+
+import Types.Command
+
+import System.Console.GetOpt
+
+usageMessage :: String -> String
+usageMessage s = "Usage: " ++ s
+
+{- Usage message with lists of commands by section. -}
+usage :: String -> [Command] -> String
+usage header cmds = unlines $ usageMessage header : concatMap go [minBound..]
+ where
+ go section
+ | null cs = []
+ | otherwise =
+ [ ""
+ , descSection section ++ ":"
+ , ""
+ ] ++ map cmdline cs
+ where
+ cs = filter (\c -> cmdsection c == section) scmds
+ cmdline c = concat
+ [ cmdname c
+ , namepad (cmdname c)
+ , cmdparamdesc c
+ , descpad (cmdparamdesc c)
+ , cmddesc c
+ ]
+ pad n s = replicate (n - length s) ' '
+ namepad = pad $ longest cmdname + 1
+ descpad = pad $ longest cmdparamdesc + 2
+ longest f = foldl max 0 $ map (length . f) cmds
+ scmds = sort cmds
+
+{- Usage message for a single command. -}
+commandUsage :: Command -> String
+commandUsage cmd = unlines
+ [ usageInfo header (cmdoptions cmd)
+ , "To see additional options common to all commands, run: git annex help options"
+ ]
+ where
+ header = usageMessage $ unwords
+ [ "git-annex"
+ , cmdname cmd
+ , cmdparamdesc cmd
+ , "[option ...]"
+ ]
+
+{- Descriptions of params used in usage messages. -}
+paramPaths :: String
+paramPaths = paramOptional $ paramRepeating paramPath -- most often used
+paramPath :: String
+paramPath = "PATH"
+paramKey :: String
+paramKey = "KEY"
+paramDesc :: String
+paramDesc = "DESC"
+paramUrl :: String
+paramUrl = "URL"
+paramNumber :: String
+paramNumber = "NUMBER"
+paramNumRange :: String
+paramNumRange = "NUM|RANGE"
+paramRemote :: String
+paramRemote = "REMOTE"
+paramGlob :: String
+paramGlob = "GLOB"
+paramName :: String
+paramName = "NAME"
+paramValue :: String
+paramValue = "VALUE"
+paramUUID :: String
+paramUUID = "UUID"
+paramType :: String
+paramType = "TYPE"
+paramDate :: String
+paramDate = "DATE"
+paramTime :: String
+paramTime = "TIME"
+paramFormat :: String
+paramFormat = "FORMAT"
+paramFile :: String
+paramFile = "FILE"
+paramGroup :: String
+paramGroup = "GROUP"
+paramExpression :: String
+paramExpression = "EXPR"
+paramSize :: String
+paramSize = "SIZE"
+paramAddress :: String
+paramAddress = "ADDRESS"
+paramKeyValue :: String
+paramKeyValue = "K=V"
+paramNothing :: String
+paramNothing = ""
+paramRepeating :: String -> String
+paramRepeating s = s ++ " ..."
+paramOptional :: String -> String
+paramOptional s = "[" ++ s ++ "]"
+paramPair :: String -> String -> String
+paramPair a b = a ++ " " ++ b
diff --git a/Utility/Applicative.hs b/Utility/Applicative.hs
new file mode 100644
index 000000000..64400c801
--- /dev/null
+++ b/Utility/Applicative.hs
@@ -0,0 +1,16 @@
+{- applicative stuff
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Utility.Applicative where
+
+{- Like <$> , but supports one level of currying.
+ -
+ - foo v = bar <$> action v == foo = bar <$$> action
+ -}
+(<$$>) :: Functor f => (a -> b) -> (c -> f a) -> c -> f b
+f <$$> v = fmap f . v
+infixr 4 <$$>
diff --git a/Utility/Base64.hs b/Utility/Base64.hs
new file mode 100644
index 000000000..0c6c8677a
--- /dev/null
+++ b/Utility/Base64.hs
@@ -0,0 +1,24 @@
+{- Simple Base64 access
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Utility.Base64 (toB64, fromB64Maybe, fromB64) where
+
+import "dataenc" Codec.Binary.Base64
+import Data.Bits.Utils
+import Control.Applicative
+import Data.Maybe
+
+toB64 :: String -> String
+toB64 = encode . s2w8
+
+fromB64Maybe :: String -> Maybe String
+fromB64Maybe s = w82s <$> decode s
+
+fromB64 :: String -> String
+fromB64 = fromMaybe bad . fromB64Maybe
+ where
+ bad = error "bad base64 encoded data"
diff --git a/Utility/Batch.hs b/Utility/Batch.hs
new file mode 100644
index 000000000..035a2eb04
--- /dev/null
+++ b/Utility/Batch.hs
@@ -0,0 +1,91 @@
+{- Running a long or expensive batch operation niced.
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Utility.Batch where
+
+import Common
+#ifndef mingw32_HOST_OS
+import qualified Build.SysConfig
+#endif
+
+#if defined(linux_HOST_OS) || defined(__ANDROID__)
+import Control.Concurrent.Async
+import System.Posix.Process
+#endif
+import qualified Control.Exception as E
+import System.Process (env)
+
+{- Runs an operation, at batch priority.
+ -
+ - This is done by running it in a bound thread, which on Linux can be set
+ - to have a different nice level than the rest of the program. Note that
+ - due to running in a bound thread, some operations may be more expensive
+ - to perform. Also note that if the action calls forkIO or forkOS itself,
+ - that will make a new thread that does not have the batch priority.
+ -
+ - POSIX threads do not support separate nice levels, so on other operating
+ - systems, the action is simply ran.
+ -}
+batch :: IO a -> IO a
+#if defined(linux_HOST_OS) || defined(__ANDROID__)
+batch a = wait =<< batchthread
+ where
+ batchthread = asyncBound $ do
+ setProcessPriority 0 maxNice
+ a
+#else
+batch a = a
+#endif
+
+maxNice :: Int
+maxNice = 19
+
+{- Converts a command to run niced. -}
+toBatchCommand :: (String, [CommandParam]) -> (String, [CommandParam])
+toBatchCommand (command, params) = (command', params')
+ where
+#ifndef mingw32_HOST_OS
+ commandline = unwords $ map shellEscape $ command : toCommand params
+ nicedcommand
+ | Build.SysConfig.nice = "nice " ++ commandline
+ | otherwise = commandline
+ command' = "sh"
+ params' =
+ [ Param "-c"
+ , Param $ "exec " ++ nicedcommand
+ ]
+#else
+ command' = command
+ params' = params
+#endif
+
+{- Runs a command in a way that's suitable for batch jobs that can be
+ - interrupted.
+ -
+ - The command is run niced. If the calling thread receives an async
+ - exception, it sends the command a SIGTERM, and after the command
+ - finishes shuttting down, it re-raises the async exception. -}
+batchCommand :: String -> [CommandParam] -> IO Bool
+batchCommand command params = batchCommandEnv command params Nothing
+
+batchCommandEnv :: String -> [CommandParam] -> Maybe [(String, String)] -> IO Bool
+batchCommandEnv command params environ = do
+ (_, _, _, pid) <- createProcess $ p { env = environ }
+ r <- E.try (waitForProcess pid) :: IO (Either E.SomeException ExitCode)
+ case r of
+ Right ExitSuccess -> return True
+ Right _ -> return False
+ Left asyncexception -> do
+ terminateProcess pid
+ void $ waitForProcess pid
+ E.throwIO asyncexception
+ where
+ (command', params') = toBatchCommand (command, params)
+ p = proc command' $ toCommand params'
+
diff --git a/Utility/CoProcess.hs b/Utility/CoProcess.hs
new file mode 100644
index 000000000..710d2af13
--- /dev/null
+++ b/Utility/CoProcess.hs
@@ -0,0 +1,93 @@
+{- Interface for running a shell command as a coprocess,
+ - sending it queries and getting back results.
+ -
+ - Copyright 2012-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Utility.CoProcess (
+ CoProcessHandle,
+ start,
+ stop,
+ query,
+ rawMode
+) where
+
+import Common
+
+import Control.Concurrent.MVar
+
+type CoProcessHandle = MVar CoProcessState
+
+data CoProcessState = CoProcessState
+ { coProcessPid :: ProcessHandle
+ , coProcessTo :: Handle
+ , coProcessFrom :: Handle
+ , coProcessSpec :: CoProcessSpec
+ }
+
+data CoProcessSpec = CoProcessSpec
+ { coProcessRestartable :: Bool
+ , coProcessCmd :: FilePath
+ , coProcessParams :: [String]
+ , coProcessEnv :: Maybe [(String, String)]
+ }
+
+start :: Bool -> FilePath -> [String] -> Maybe [(String, String)] -> IO CoProcessHandle
+start restartable cmd params env = do
+ s <- start' $ CoProcessSpec restartable cmd params env
+ newMVar s
+
+start' :: CoProcessSpec -> IO CoProcessState
+start' s = do
+ (pid, from, to) <- startInteractiveProcess (coProcessCmd s) (coProcessParams s) (coProcessEnv s)
+ return $ CoProcessState pid to from s
+
+stop :: CoProcessHandle -> IO ()
+stop ch = do
+ s <- readMVar ch
+ hClose $ coProcessTo s
+ hClose $ coProcessFrom s
+ let p = proc (coProcessCmd $ coProcessSpec s) (coProcessParams $ coProcessSpec s)
+ forceSuccessProcess p (coProcessPid s)
+
+{- To handle a restartable process, any IO exception thrown by the send and
+ - receive actions are assumed to mean communication with the process
+ - failed, and the failed action is re-run with a new process. -}
+query :: CoProcessHandle -> (Handle -> IO a) -> (Handle -> IO b) -> IO b
+query ch send receive = do
+ s <- readMVar ch
+ restartable s (send $ coProcessTo s) $ const $
+ restartable s (hFlush $ coProcessTo s) $ const $
+ restartable s (receive $ coProcessFrom s) $
+ return
+ where
+ restartable s a cont
+ | coProcessRestartable (coProcessSpec s) =
+ maybe restart cont =<< catchMaybeIO a
+ | otherwise = cont =<< a
+ restart = do
+ s <- takeMVar ch
+ void $ catchMaybeIO $ do
+ hClose $ coProcessTo s
+ hClose $ coProcessFrom s
+ void $ waitForProcess $ coProcessPid s
+ s' <- start' (coProcessSpec s)
+ putMVar ch s'
+ query ch send receive
+
+rawMode :: CoProcessHandle -> IO CoProcessHandle
+rawMode ch = do
+ s <- readMVar ch
+ raw $ coProcessFrom s
+ raw $ coProcessTo s
+ return ch
+ where
+ raw h = do
+ fileEncoding h
+#ifdef mingw32_HOST_OS
+ hSetNewlineMode h noNewlineTranslation
+#endif
diff --git a/Utility/CopyFile.hs b/Utility/CopyFile.hs
new file mode 100644
index 000000000..4a609fd16
--- /dev/null
+++ b/Utility/CopyFile.hs
@@ -0,0 +1,48 @@
+{- file copying
+ -
+ - Copyright 2010-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Utility.CopyFile (
+ copyFileExternal,
+ createLinkOrCopy
+) where
+
+import Common
+import qualified Build.SysConfig as SysConfig
+
+{- The cp command is used, because I hate reinventing the wheel,
+ - and because this allows easy access to features like cp --reflink. -}
+copyFileExternal :: FilePath -> FilePath -> IO Bool
+copyFileExternal src dest = do
+ whenM (doesFileExist dest) $
+ removeFile dest
+ boolSystem "cp" $ params ++ [File src, File dest]
+ where
+#ifndef __ANDROID__
+ params = map snd $ filter fst
+ [ (SysConfig.cp_reflink_auto, Param "--reflink=auto")
+ , (SysConfig.cp_a, Param "-a")
+ , (SysConfig.cp_p && not SysConfig.cp_a, Param "-p")
+ ]
+#else
+ params = []
+#endif
+
+{- Create a hard link if the filesystem allows it, and fall back to copying
+ - the file. -}
+createLinkOrCopy :: FilePath -> FilePath -> IO Bool
+#ifndef mingw32_HOST_OS
+createLinkOrCopy src dest = go `catchIO` const fallback
+ where
+ go = do
+ createLink src dest
+ return True
+ fallback = copyFileExternal src dest
+#else
+createLinkOrCopy = copyFileExternal
+#endif
diff --git a/Utility/DBus.hs b/Utility/DBus.hs
new file mode 100644
index 000000000..3523a3aa3
--- /dev/null
+++ b/Utility/DBus.hs
@@ -0,0 +1,84 @@
+{- DBus utilities
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE OverloadedStrings, ScopedTypeVariables #-}
+
+module Utility.DBus where
+
+import Utility.Exception
+
+import DBus.Client
+import DBus
+import Data.Maybe
+import Control.Concurrent
+import Control.Exception as E
+
+type ServiceName = String
+
+listServiceNames :: Client -> IO [ServiceName]
+listServiceNames client = do
+ reply <- callDBus client "ListNames" []
+ return $ fromMaybe [] $ fromVariant (methodReturnBody reply !! 0)
+
+callDBus :: Client -> MemberName -> [Variant] -> IO MethodReturn
+callDBus client name params = call_ client $
+ (methodCall "/org/freedesktop/DBus" "org.freedesktop.DBus" name)
+ { methodCallDestination = Just "org.freedesktop.DBus"
+ , methodCallBody = params
+ }
+
+{- Connects to the bus, and runs the client action.
+ -
+ - Throws a ClientError, and closes the connection if it fails to
+ - process an incoming message, or if the connection is lost.
+ - Unlike DBus's usual interface, this error is thrown at the top level,
+ - rather than inside the clientThreadRunner, so it can be caught, and
+ - runClient re-run as needed. -}
+runClient :: IO (Maybe Address) -> (Client -> IO ()) -> IO ()
+runClient getaddr clientaction = do
+ env <- getaddr
+ case env of
+ Nothing -> throwIO (clientError "runClient: unable to determine DBUS address")
+ Just addr -> do
+ {- The clientaction will set up listeners, which
+ - run in a different thread. We block while
+ - they're running, until our threadrunner catches
+ - a ClientError, which it will put into the MVar
+ - to be rethrown here. -}
+ mv <- newEmptyMVar
+ let tr = threadrunner (putMVar mv)
+ let opts = defaultClientOptions { clientThreadRunner = tr }
+ client <- connectWith opts addr
+ clientaction client
+ e <- takeMVar mv
+ disconnect client
+ throw e
+ where
+ threadrunner storeerr io = loop
+ where
+ loop = catchClientError (io >> loop) storeerr
+
+{- Connects to the bus, and runs the client action.
+ -
+ - If the connection is lost, runs onretry, which can do something like
+ - a delay, or printing a warning, and has a state value (useful for
+ - exponential backoff). Once onretry returns, the connection is retried.
+ -}
+persistentClient :: IO (Maybe Address) -> v -> (SomeException -> v -> IO v) -> (Client -> IO ()) -> IO ()
+persistentClient getaddr v onretry clientaction =
+ {- runClient can fail with not just ClientError, but also other
+ - things, if dbus is not running. Let async exceptions through. -}
+ runClient getaddr clientaction `catchNonAsync` retry
+ where
+ retry e = do
+ v' <- onretry e v
+ persistentClient getaddr v' onretry clientaction
+
+{- Catches only ClientError -}
+catchClientError :: IO () -> (ClientError -> IO ()) -> IO ()
+catchClientError io handler =
+ either handler return =<< (E.try io :: IO (Either ClientError ()))
diff --git a/Utility/Daemon.hs b/Utility/Daemon.hs
new file mode 100644
index 000000000..12beb235a
--- /dev/null
+++ b/Utility/Daemon.hs
@@ -0,0 +1,124 @@
+{- daemon support
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Utility.Daemon where
+
+import Common
+#ifndef mingw32_HOST_OS
+import Utility.LogFile
+#endif
+
+#ifndef mingw32_HOST_OS
+import System.Posix
+import Control.Concurrent.Async
+#else
+import System.PosixCompat
+#endif
+
+{- Run an action as a daemon, with all output sent to a file descriptor.
+ -
+ - Can write its pid to a file, to guard against multiple instances
+ - running and allow easy termination.
+ -
+ - When successful, does not return. -}
+daemonize :: Fd -> Maybe FilePath -> Bool -> IO () -> IO ()
+#ifndef mingw32_HOST_OS
+daemonize logfd pidfile changedirectory a = do
+ maybe noop checkalreadyrunning pidfile
+ _ <- forkProcess child1
+ out
+ where
+ checkalreadyrunning f = maybe noop (const $ alreadyRunning)
+ =<< checkDaemon f
+ child1 = do
+ _ <- createSession
+ _ <- forkProcess child2
+ out
+ child2 = do
+ maybe noop lockPidFile pidfile
+ when changedirectory $
+ setCurrentDirectory "/"
+ nullfd <- openFd "/dev/null" ReadOnly Nothing defaultFileFlags
+ redir nullfd stdInput
+ redirLog logfd
+ {- forkProcess masks async exceptions; unmask them inside
+ - the action. -}
+ wait =<< asyncWithUnmask (\unmask -> unmask a)
+ out
+ out = exitImmediately ExitSuccess
+#else
+daemonize = error "daemonize is not implemented on Windows" -- TODO
+#endif
+
+{- Locks the pid file, with an exclusive, non-blocking lock.
+ - Writes the pid to the file, fully atomically.
+ - Fails if the pid file is already locked by another process. -}
+lockPidFile :: FilePath -> IO ()
+lockPidFile file = do
+ createDirectoryIfMissing True (parentDir file)
+#ifndef mingw32_HOST_OS
+ fd <- openFd file ReadWrite (Just stdFileMode) defaultFileFlags
+ locked <- catchMaybeIO $ setLock fd (WriteLock, AbsoluteSeek, 0, 0)
+ fd' <- openFd newfile ReadWrite (Just stdFileMode) defaultFileFlags
+ { trunc = True }
+ locked' <- catchMaybeIO $ setLock fd' (WriteLock, AbsoluteSeek, 0, 0)
+ case (locked, locked') of
+ (Nothing, _) -> alreadyRunning
+ (_, Nothing) -> alreadyRunning
+ _ -> do
+ _ <- fdWrite fd' =<< show <$> getProcessID
+ closeFd fd
+#else
+ writeFile newfile "-1"
+#endif
+ renameFile newfile file
+ where
+ newfile = file ++ ".new"
+
+alreadyRunning :: IO ()
+alreadyRunning = error "Daemon is already running."
+
+{- Checks if the daemon is running, by checking that the pid file
+ - is locked by the same process that is listed in the pid file.
+ -
+ - If it's running, returns its pid. -}
+checkDaemon :: FilePath -> IO (Maybe ProcessID)
+#ifndef mingw32_HOST_OS
+checkDaemon pidfile = do
+ v <- catchMaybeIO $
+ openFd pidfile ReadOnly (Just stdFileMode) defaultFileFlags
+ case v of
+ Just fd -> do
+ locked <- getLock fd (ReadLock, AbsoluteSeek, 0, 0)
+ p <- readish <$> readFile pidfile
+ closeFd fd `after` return (check locked p)
+ Nothing -> return Nothing
+ where
+ check Nothing _ = Nothing
+ check _ Nothing = Nothing
+ check (Just (pid, _)) (Just pid')
+ | pid == pid' = Just pid
+ | otherwise = error $
+ "stale pid in " ++ pidfile ++
+ " (got " ++ show pid' ++
+ "; expected " ++ show pid ++ " )"
+#else
+checkDaemon pidfile = maybe Nothing readish <$> catchMaybeIO (readFile pidfile)
+#endif
+
+{- Stops the daemon, safely. -}
+stopDaemon :: FilePath -> IO ()
+#ifndef mingw32_HOST_OS
+stopDaemon pidfile = go =<< checkDaemon pidfile
+ where
+ go Nothing = noop
+ go (Just pid) = signalProcess sigTERM pid
+#else
+stopDaemon = error "stopDaemon is not implemented on Windows" -- TODO
+#endif
diff --git a/Utility/Data.hs b/Utility/Data.hs
new file mode 100644
index 000000000..359258296
--- /dev/null
+++ b/Utility/Data.hs
@@ -0,0 +1,17 @@
+{- utilities for simple data types
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Utility.Data where
+
+{- First item in the list that is not Nothing. -}
+firstJust :: Eq a => [Maybe a] -> Maybe a
+firstJust ms = case dropWhile (== Nothing) ms of
+ [] -> Nothing
+ (md:_) -> md
+
+eitherToMaybe :: Either a b -> Maybe b
+eitherToMaybe = either (const Nothing) Just
diff --git a/Utility/DataUnits.hs b/Utility/DataUnits.hs
new file mode 100644
index 000000000..2a936f1fd
--- /dev/null
+++ b/Utility/DataUnits.hs
@@ -0,0 +1,160 @@
+{- data size display and parsing
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -
+ -
+ - And now a rant:
+ -
+ - In the beginning, we had powers of two, and they were good.
+ -
+ - Disk drive manufacturers noticed that some powers of two were
+ - sorta close to some powers of ten, and that rounding down to the nearest
+ - power of ten allowed them to advertise their drives were bigger. This
+ - was sorta annoying.
+ -
+ - Then drives got big. Really, really big. This was good.
+ -
+ - Except that the small rounding error perpretrated by the drive
+ - manufacturers suffered the fate of a small error, and became a large
+ - error. This was bad.
+ -
+ - So, a committee was formed. And it arrived at a committee-like decision,
+ - which satisfied noone, confused everyone, and made the world an uglier
+ - place. As with all committees, this was meh.
+ -
+ - And the drive manufacturers happily continued selling drives that are
+ - increasingly smaller than you'd expect, if you don't count on your
+ - fingers. But that are increasingly too big for anyone to much notice.
+ - This caused me to need git-annex.
+ -
+ - Thus, I use units here that I loathe. Because if I didn't, people would
+ - be confused that their drives seem the wrong size, and other people would
+ - complain at me for not being standards compliant. And we call this
+ - progress?
+ -}
+
+module Utility.DataUnits (
+ dataUnits,
+ storageUnits,
+ memoryUnits,
+ bandwidthUnits,
+ oldSchoolUnits,
+
+ roughSize,
+ compareSizes,
+ readSize
+) where
+
+import Data.List
+import Data.Char
+
+import Utility.HumanNumber
+
+type ByteSize = Integer
+type Name = String
+type Abbrev = String
+data Unit = Unit ByteSize Abbrev Name
+ deriving (Ord, Show, Eq)
+
+dataUnits :: [Unit]
+dataUnits = storageUnits ++ memoryUnits
+
+{- Storage units are (stupidly) powers of ten. -}
+storageUnits :: [Unit]
+storageUnits =
+ [ Unit (p 8) "YB" "yottabyte"
+ , Unit (p 7) "ZB" "zettabyte"
+ , Unit (p 6) "EB" "exabyte"
+ , Unit (p 5) "PB" "petabyte"
+ , Unit (p 4) "TB" "terabyte"
+ , Unit (p 3) "GB" "gigabyte"
+ , Unit (p 2) "MB" "megabyte"
+ , Unit (p 1) "kB" "kilobyte" -- weird capitalization thanks to committe
+ , Unit (p 0) "B" "byte"
+ ]
+ where
+ p :: Integer -> Integer
+ p n = 1000^n
+
+{- Memory units are (stupidly named) powers of 2. -}
+memoryUnits :: [Unit]
+memoryUnits =
+ [ Unit (p 8) "YiB" "yobibyte"
+ , Unit (p 7) "ZiB" "zebibyte"
+ , Unit (p 6) "EiB" "exbibyte"
+ , Unit (p 5) "PiB" "pebibyte"
+ , Unit (p 4) "TiB" "tebibyte"
+ , Unit (p 3) "GiB" "gibibyte"
+ , Unit (p 2) "MiB" "mebibyte"
+ , Unit (p 1) "KiB" "kibibyte"
+ , Unit (p 0) "B" "byte"
+ ]
+ where
+ p :: Integer -> Integer
+ p n = 2^(n*10)
+
+{- Bandwidth units are only measured in bits if you're some crazy telco. -}
+bandwidthUnits :: [Unit]
+bandwidthUnits = error "stop trying to rip people off"
+
+{- Do you yearn for the days when men were men and megabytes were megabytes? -}
+oldSchoolUnits :: [Unit]
+oldSchoolUnits = zipWith (curry mingle) storageUnits memoryUnits
+ where
+ mingle (Unit _ a n, Unit s' _ _) = Unit s' a n
+
+{- approximate display of a particular number of bytes -}
+roughSize :: [Unit] -> Bool -> ByteSize -> String
+roughSize units short i
+ | i < 0 = '-' : findUnit units' (negate i)
+ | otherwise = findUnit units' i
+ where
+ units' = reverse $ sort units -- largest first
+
+ findUnit (u@(Unit s _ _):us) i'
+ | i' >= s = showUnit i' u
+ | otherwise = findUnit us i'
+ findUnit [] i' = showUnit i' (last units') -- bytes
+
+ showUnit x (Unit size abbrev name) = s ++ " " ++ unit
+ where
+ v = (fromInteger x :: Double) / fromInteger size
+ s = showImprecise 2 v
+ unit
+ | short = abbrev
+ | s == "1" = name
+ | otherwise = name ++ "s"
+
+{- displays comparison of two sizes -}
+compareSizes :: [Unit] -> Bool -> ByteSize -> ByteSize -> String
+compareSizes units abbrev old new
+ | old > new = roughSize units abbrev (old - new) ++ " smaller"
+ | old < new = roughSize units abbrev (new - old) ++ " larger"
+ | otherwise = "same"
+
+{- Parses strings like "10 kilobytes" or "0.5tb". -}
+readSize :: [Unit] -> String -> Maybe ByteSize
+readSize units input
+ | null parsednum || null parsedunit = Nothing
+ | otherwise = Just $ round $ number * fromIntegral multiplier
+ where
+ (number, rest) = head parsednum
+ multiplier = head parsedunit
+ unitname = takeWhile isAlpha $ dropWhile isSpace rest
+
+ parsednum = reads input :: [(Double, String)]
+ parsedunit = lookupUnit units unitname
+
+ lookupUnit _ [] = [1] -- no unit given, assume bytes
+ lookupUnit [] _ = []
+ lookupUnit (Unit s a n:us) v
+ | a ~~ v || n ~~ v = [s]
+ | plural n ~~ v || a ~~ byteabbrev v = [s]
+ | otherwise = lookupUnit us v
+
+ a ~~ b = map toLower a == map toLower b
+
+ plural n = n ++ "s"
+ byteabbrev a = a ++ "b"
diff --git a/Utility/DirWatcher.hs b/Utility/DirWatcher.hs
new file mode 100644
index 000000000..5231286fc
--- /dev/null
+++ b/Utility/DirWatcher.hs
@@ -0,0 +1,157 @@
+{- generic directory watching interface
+ -
+ - Uses inotify, or kqueue, or fsevents, or win32-notify to watch a directory
+ - (and subdirectories) for changes, and runs hooks for different
+ - sorts of events as they occur.
+ -
+ - Copyright 2012-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Utility.DirWatcher where
+
+import Utility.DirWatcher.Types
+
+#if WITH_INOTIFY
+import qualified Utility.INotify as INotify
+import qualified System.INotify as INotify
+#endif
+#if WITH_KQUEUE
+import qualified Utility.Kqueue as Kqueue
+import Control.Concurrent
+#endif
+#if WITH_FSEVENTS
+import qualified Utility.FSEvents as FSEvents
+import qualified System.OSX.FSEvents as FSEvents
+#endif
+#if WITH_WIN32NOTIFY
+import qualified Utility.Win32Notify as Win32Notify
+import qualified System.Win32.Notify as Win32Notify
+#endif
+
+type Pruner = FilePath -> Bool
+
+canWatch :: Bool
+#if (WITH_INOTIFY || WITH_KQUEUE || WITH_FSEVENTS || WITH_WIN32NOTIFY)
+canWatch = True
+#else
+#if defined linux_HOST_OS
+#warning "Building without inotify support"
+#endif
+canWatch = False
+#endif
+
+{- With inotify, discrete events will be received when making multiple changes
+ - to the same filename. For example, adding it, deleting it, and adding it
+ - again will be three events.
+ -
+ - OTOH, with kqueue, often only one event is received, indicating the most
+ - recent state of the file. -}
+eventsCoalesce :: Bool
+#if (WITH_INOTIFY || WITH_WIN32NOTIFY)
+eventsCoalesce = False
+#else
+#if (WITH_KQUEUE || WITH_FSEVENTS)
+eventsCoalesce = True
+#else
+eventsCoalesce = undefined
+#endif
+#endif
+
+{- 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. -}
+closingTracked :: Bool
+#if (WITH_INOTIFY || WITH_FSEVENTS || WITH_WIN32NOTIFY)
+closingTracked = True
+#else
+#if WITH_KQUEUE
+closingTracked = False
+#else
+closingTracked = undefined
+#endif
+#endif
+
+{- With inotify, modifications to existing files can be tracked.
+ - Kqueue does not support this.
+ - Fsevents generates events when an existing file is reopened and rewritten,
+ - but not necessarily when it's opened once and modified repeatedly. -}
+modifyTracked :: Bool
+#if (WITH_INOTIFY || WITH_FSEVENTS || WITH_WIN32NOTIFY)
+modifyTracked = True
+#else
+#if WITH_KQUEUE
+modifyTracked = False
+#else
+modifyTracked = undefined
+#endif
+#endif
+
+{- Starts a watcher thread. The runstartup action is passed a scanner action
+ - to run, that will return once the initial directory scan is complete.
+ - Once runstartup returns, the watcher thread continues running,
+ - and processing events. Returns a DirWatcherHandle that can be used
+ - to shutdown later. -}
+#if WITH_INOTIFY
+type DirWatcherHandle = INotify.INotify
+watchDir :: FilePath -> Pruner -> WatchHooks -> (IO () -> IO ()) -> IO DirWatcherHandle
+watchDir dir prune hooks runstartup = do
+ i <- INotify.initINotify
+ runstartup $ INotify.watchDir i dir prune hooks
+ return i
+#else
+#if WITH_KQUEUE
+type DirWatcherHandle = ThreadId
+watchDir :: FilePath -> Pruner -> WatchHooks -> (IO Kqueue.Kqueue -> IO Kqueue.Kqueue) -> IO DirWatcherHandle
+watchDir dir prune hooks runstartup = do
+ kq <- runstartup $ Kqueue.initKqueue dir prune
+ forkIO $ Kqueue.runHooks kq hooks
+#else
+#if WITH_FSEVENTS
+type DirWatcherHandle = FSEvents.EventStream
+watchDir :: FilePath -> Pruner -> WatchHooks -> (IO FSEvents.EventStream -> IO FSEvents.EventStream) -> IO DirWatcherHandle
+watchDir dir prune hooks runstartup =
+ runstartup $ FSEvents.watchDir dir prune hooks
+#else
+#if WITH_WIN32NOTIFY
+type DirWatcherHandle = Win32Notify.WatchManager
+watchDir :: FilePath -> Pruner -> WatchHooks -> (IO Win32Notify.WatchManager -> IO Win32Notify.WatchManager) -> IO DirWatcherHandle
+watchDir dir prune hooks runstartup =
+ runstartup $ Win32Notify.watchDir dir prune hooks
+#else
+type DirWatcherHandle = ()
+watchDir :: FilePath -> Pruner -> WatchHooks -> (IO () -> IO ()) -> IO DirWatcherHandle
+watchDir = undefined
+#endif
+#endif
+#endif
+#endif
+
+stopWatchDir :: DirWatcherHandle -> IO ()
+#if WITH_INOTIFY
+stopWatchDir = INotify.killINotify
+#else
+#if WITH_KQUEUE
+stopWatchDir = killThread
+#else
+#if WITH_FSEVENTS
+stopWatchDir = FSEvents.eventStreamDestroy
+#else
+#if WITH_WIN32NOTIFY
+stopWatchDir = Win32Notify.killWatchManager
+#else
+stopWatchDir = undefined
+#endif
+#endif
+#endif
+#endif
diff --git a/Utility/DirWatcher/Types.hs b/Utility/DirWatcher/Types.hs
new file mode 100644
index 000000000..8cfa69d34
--- /dev/null
+++ b/Utility/DirWatcher/Types.hs
@@ -0,0 +1,24 @@
+{- generic directory watching types
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Utility.DirWatcher.Types where
+
+import Common
+
+type Hook a = Maybe (a -> Maybe FileStatus -> IO ())
+
+data WatchHooks = WatchHooks
+ { addHook :: Hook FilePath
+ , addSymlinkHook :: Hook FilePath
+ , delHook :: Hook FilePath
+ , delDirHook :: Hook FilePath
+ , errHook :: Hook String -- error message
+ , modifyHook :: Hook FilePath
+ }
+
+mkWatchHooks :: WatchHooks
+mkWatchHooks = WatchHooks Nothing Nothing Nothing Nothing Nothing Nothing
diff --git a/Utility/Directory.hs b/Utility/Directory.hs
new file mode 100644
index 000000000..4918d20be
--- /dev/null
+++ b/Utility/Directory.hs
@@ -0,0 +1,107 @@
+{- directory manipulation
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Utility.Directory where
+
+import System.IO.Error
+import System.PosixCompat.Files
+import System.Directory
+import Control.Exception (throw)
+import Control.Monad
+import Control.Monad.IfElse
+import System.FilePath
+import Control.Applicative
+import System.IO.Unsafe (unsafeInterleaveIO)
+
+import Utility.SafeCommand
+import Utility.Tmp
+import Utility.Exception
+import Utility.Monad
+
+dirCruft :: FilePath -> Bool
+dirCruft "." = True
+dirCruft ".." = True
+dirCruft _ = False
+
+{- Lists the contents of a directory.
+ - Unlike getDirectoryContents, paths are not relative to the directory. -}
+dirContents :: FilePath -> IO [FilePath]
+dirContents d = map (d </>) . filter (not . dirCruft) <$> getDirectoryContents d
+
+{- Gets files in a directory, and then its subdirectories, recursively,
+ - and lazily. If the directory does not exist, no exception is thrown,
+ - instead, [] is returned. -}
+dirContentsRecursive :: FilePath -> IO [FilePath]
+dirContentsRecursive topdir = dirContentsRecursiveSkipping (const False) topdir
+
+{- Skips directories whose basenames match the skipdir. -}
+dirContentsRecursiveSkipping :: (FilePath -> Bool) -> FilePath -> IO [FilePath]
+dirContentsRecursiveSkipping skipdir topdir = go [topdir]
+ where
+ go [] = return []
+ go (dir:dirs)
+ | skipdir (takeFileName dir) = go dirs
+ | otherwise = unsafeInterleaveIO $ do
+ (files, dirs') <- collect [] []
+ =<< catchDefaultIO [] (dirContents dir)
+ files' <- go (dirs' ++ dirs)
+ return (files ++ files')
+ collect files dirs' [] = return (reverse files, reverse dirs')
+ collect files dirs' (entry:entries)
+ | dirCruft entry = collect files dirs' entries
+ | otherwise = do
+ ifM (doesDirectoryExist entry)
+ ( collect files (entry:dirs') entries
+ , collect (entry:files) dirs' entries
+ )
+
+{- Moves one filename to another.
+ - First tries a rename, but falls back to moving across devices if needed. -}
+moveFile :: FilePath -> FilePath -> IO ()
+moveFile src dest = tryIO (rename src dest) >>= onrename
+ where
+ onrename (Right _) = noop
+ onrename (Left e)
+ | isPermissionError e = rethrow
+ | isDoesNotExistError e = rethrow
+ | otherwise = do
+ -- copyFile is likely not as optimised as
+ -- the mv command, so we'll use the latter.
+ -- But, mv will move into a directory if
+ -- dest is one, which is not desired.
+ whenM (isdir dest) rethrow
+ viaTmp mv dest undefined
+ where
+ rethrow = throw e
+ mv tmp _ = do
+ ok <- boolSystem "mv" [Param "-f", Param src, Param tmp]
+ unless ok $ do
+ -- delete any partial
+ _ <- tryIO $ removeFile tmp
+ rethrow
+
+ isdir f = do
+ r <- tryIO $ getFileStatus f
+ case r of
+ (Left _) -> return False
+ (Right s) -> return $ isDirectory s
+
+{- Removes a file, which may or may not exist, and does not have to
+ - be a regular file.
+ -
+ - Note that an exception is thrown if the file exists but
+ - cannot be removed. -}
+nukeFile :: FilePath -> IO ()
+nukeFile file = void $ tryWhenExists go
+ where
+#ifndef mingw32_HOST_OS
+ go = removeLink file
+#else
+ go = removeFile file
+#endif
diff --git a/Utility/DiskFree.hs b/Utility/DiskFree.hs
new file mode 100644
index 000000000..aa1bfeedb
--- /dev/null
+++ b/Utility/DiskFree.hs
@@ -0,0 +1,38 @@
+{- disk free space checking
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE ForeignFunctionInterface, CPP #-}
+
+module Utility.DiskFree ( getDiskFree ) where
+
+#ifdef WITH_CLIBS
+
+import Common
+
+import Foreign.C.Types
+import Foreign.C.String
+import Foreign.C.Error
+
+foreign import ccall safe "libdiskfree.h diskfree" c_diskfree
+ :: CString -> IO CULLong
+
+getDiskFree :: FilePath -> IO (Maybe Integer)
+getDiskFree path = withFilePath path $ \c_path -> do
+ free <- c_diskfree c_path
+ ifM (safeErrno <$> getErrno)
+ ( return $ Just $ toInteger free
+ , return Nothing
+ )
+ where
+ safeErrno (Errno v) = v == 0
+
+#else
+
+getDiskFree :: FilePath -> IO (Maybe Integer)
+getDiskFree _ = return Nothing
+
+#endif
diff --git a/Utility/Dot.hs b/Utility/Dot.hs
new file mode 100644
index 000000000..e57bf009f
--- /dev/null
+++ b/Utility/Dot.hs
@@ -0,0 +1,63 @@
+{- a simple graphviz / dot(1) digraph description generator library
+ -
+ - Copyright 2010 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Utility.Dot where -- import qualified
+
+{- generates a graph description from a list of lines -}
+graph :: [String] -> String
+graph s = unlines $ [header] ++ map indent s ++ [footer]
+ where
+ header = "digraph map {"
+ footer= "}"
+
+{- a node in the graph -}
+graphNode :: String -> String -> String
+graphNode nodeid desc = label desc $ quote nodeid
+
+{- an edge between two nodes -}
+graphEdge :: String -> String -> Maybe String -> String
+graphEdge fromid toid desc = indent $ maybe edge (`label` edge) desc
+ where
+ edge = quote fromid ++ " -> " ++ quote toid
+
+{- adds a label to a node or edge -}
+label :: String -> String -> String
+label = attr "label"
+
+{- adds an attribute to a node or edge
+ - (can be called multiple times for multiple attributes) -}
+attr :: String -> String -> String -> String
+attr a v s = s ++ " [ " ++ a ++ "=" ++ quote v ++ " ]"
+
+{- fills a node with a color -}
+fillColor :: String -> String -> String
+fillColor color s = attr "fillcolor" color $ attr "style" "filled" s
+
+{- apply to graphNode to put the node in a labeled box -}
+subGraph :: String -> String -> String -> String -> String
+subGraph subid l color s =
+ "subgraph " ++ name ++ " {\n" ++
+ ii setlabel ++
+ ii setfilled ++
+ ii setcolor ++
+ ii s ++
+ indent "}"
+ where
+ -- the "cluster_" makes dot draw a box
+ name = quote ("cluster_" ++ subid)
+ setlabel = "label=" ++ quote l
+ setfilled = "style=" ++ quote "filled"
+ setcolor = "fillcolor=" ++ quote color
+ ii x = indent (indent x) ++ "\n"
+
+indent ::String -> String
+indent s = '\t' : s
+
+quote :: String -> String
+quote s = "\"" ++ s' ++ "\""
+ where
+ s' = filter (/= '"') s
diff --git a/Utility/Env.hs b/Utility/Env.hs
new file mode 100644
index 000000000..cb738732f
--- /dev/null
+++ b/Utility/Env.hs
@@ -0,0 +1,63 @@
+{- portable environment variables
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Utility.Env where
+
+#ifdef mingw32_HOST_OS
+import Utility.Exception
+import Control.Applicative
+import Data.Maybe
+import qualified System.Environment as E
+#else
+import qualified System.Posix.Env as PE
+#endif
+
+getEnv :: String -> IO (Maybe String)
+#ifndef mingw32_HOST_OS
+getEnv = PE.getEnv
+#else
+getEnv = catchMaybeIO . E.getEnv
+#endif
+
+getEnvDefault :: String -> String -> IO String
+#ifndef mingw32_HOST_OS
+getEnvDefault = PE.getEnvDefault
+#else
+getEnvDefault var fallback = fromMaybe fallback <$> getEnv var
+#endif
+
+getEnvironment :: IO [(String, String)]
+#ifndef mingw32_HOST_OS
+getEnvironment = PE.getEnvironment
+#else
+getEnvironment = E.getEnvironment
+#endif
+
+{- Returns True if it could successfully set the environment variable.
+ -
+ - There is, apparently, no way to do this in Windows. Instead,
+ - environment varuables must be provided when running a new process. -}
+setEnv :: String -> String -> Bool -> IO Bool
+#ifndef mingw32_HOST_OS
+setEnv var val overwrite = do
+ PE.setEnv var val overwrite
+ return True
+#else
+setEnv _ _ _ = return False
+#endif
+
+{- Returns True if it could successfully unset the environment variable. -}
+unsetEnv :: String -> IO Bool
+#ifndef mingw32_HOST_OS
+unsetEnv var = do
+ PE.unsetEnv var
+ return True
+#else
+unsetEnv _ = return False
+#endif
diff --git a/Utility/Exception.hs b/Utility/Exception.hs
new file mode 100644
index 000000000..cf2c615c7
--- /dev/null
+++ b/Utility/Exception.hs
@@ -0,0 +1,59 @@
+{- Simple IO exception handling (and some more)
+ -
+ - Copyright 2011-2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE ScopedTypeVariables #-}
+
+module Utility.Exception where
+
+import Control.Exception
+import qualified Control.Exception as E
+import Control.Applicative
+import Control.Monad
+import System.IO.Error (isDoesNotExistError)
+import Utility.Data
+
+{- Catches IO errors and returns a Bool -}
+catchBoolIO :: IO Bool -> IO Bool
+catchBoolIO a = catchDefaultIO False a
+
+{- Catches IO errors and returns a Maybe -}
+catchMaybeIO :: IO a -> IO (Maybe a)
+catchMaybeIO a = catchDefaultIO Nothing $ Just <$> a
+
+{- Catches IO errors and returns a default value. -}
+catchDefaultIO :: a -> IO a -> IO a
+catchDefaultIO def a = catchIO a (const $ return def)
+
+{- Catches IO errors and returns the error message. -}
+catchMsgIO :: IO a -> IO (Either String a)
+catchMsgIO a = either (Left . show) Right <$> tryIO a
+
+{- catch specialized for IO errors only -}
+catchIO :: IO a -> (IOException -> IO a) -> IO a
+catchIO = E.catch
+
+{- try specialized for IO errors only -}
+tryIO :: IO a -> IO (Either IOException a)
+tryIO = try
+
+{- Catches all exceptions except for async exceptions.
+ - This is often better to use than catching them all, so that
+ - ThreadKilled and UserInterrupt get through.
+ -}
+catchNonAsync :: IO a -> (SomeException -> IO a) -> IO a
+catchNonAsync a onerr = a `catches`
+ [ Handler (\ (e :: AsyncException) -> throw e)
+ , Handler (\ (e :: SomeException) -> onerr e)
+ ]
+
+tryNonAsync :: IO a -> IO (Either SomeException a)
+tryNonAsync a = (Right <$> a) `catchNonAsync` (return . Left)
+
+{- Catches only DoesNotExist exceptions, and lets all others through. -}
+tryWhenExists :: IO a -> IO (Maybe a)
+tryWhenExists a = eitherToMaybe <$>
+ tryJust (guard . isDoesNotExistError) a
diff --git a/Utility/ExternalSHA.hs b/Utility/ExternalSHA.hs
new file mode 100644
index 000000000..adbde795a
--- /dev/null
+++ b/Utility/ExternalSHA.hs
@@ -0,0 +1,68 @@
+{- Calculating a SHA checksum with an external command.
+ -
+ - This is typically a bit faster than using Haskell libraries,
+ - by around 1% to 10%. Worth it for really big files.
+ -
+ - Copyright 2011-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Utility.ExternalSHA (externalSHA) where
+
+import Utility.SafeCommand
+import Utility.Process
+import Utility.FileSystemEncoding
+import Utility.Misc
+
+import System.Process
+import Data.List
+import Data.Char
+import Control.Applicative
+import System.IO
+
+externalSHA :: String -> Int -> FilePath -> IO (Either String String)
+externalSHA command shasize file = do
+ ls <- lines <$> readsha (toCommand [File file])
+ return $ sanitycheck =<< parse ls
+ where
+ {- sha commands output the filename, so need to set fileEncoding -}
+ readsha args =
+ withHandle StdoutHandle (createProcessChecked checkSuccessProcess) p $ \h -> do
+ fileEncoding h
+ output <- hGetContentsStrict h
+ hClose h
+ return output
+ where
+ p = (proc command args) { std_out = CreatePipe }
+
+ {- The first word of the output is taken to be the sha. -}
+ parse [] = bad
+ parse (l:_)
+ | null sha = bad
+ -- sha is prefixed with \ when filename contains certian chars
+ | "\\" `isPrefixOf` sha = Right $ drop 1 sha
+ | otherwise = Right sha
+ where
+ sha = fst $ separate (== ' ') l
+ bad = Left $ command ++ " parse error"
+
+ {- Check that we've correctly parsing the output of the command,
+ - by making sure the sha we read is of the expected length
+ - and contains only the right characters. -}
+ sanitycheck sha
+ | length sha /= expectedSHALength shasize =
+ Left $ "Failed to parse the output of " ++ command
+ | any (`notElem` "0123456789abcdef") sha' =
+ Left $ "Unexpected character in output of " ++ command ++ "\"" ++ sha ++ "\""
+ | otherwise = Right sha'
+ where
+ sha' = map toLower sha
+
+expectedSHALength :: Int -> Int
+expectedSHALength 1 = 40
+expectedSHALength 256 = 64
+expectedSHALength 512 = 128
+expectedSHALength 224 = 56
+expectedSHALength 384 = 96
+expectedSHALength _ = 0
diff --git a/Utility/FSEvents.hs b/Utility/FSEvents.hs
new file mode 100644
index 000000000..d6663e9d7
--- /dev/null
+++ b/Utility/FSEvents.hs
@@ -0,0 +1,92 @@
+{- FSEvents interface
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Utility.FSEvents where
+
+import Common hiding (isDirectory)
+import Utility.DirWatcher.Types
+
+import System.OSX.FSEvents
+import qualified System.Posix.Files as Files
+import Data.Bits ((.&.))
+
+watchDir :: FilePath -> (FilePath -> Bool) -> WatchHooks -> IO EventStream
+watchDir dir ignored hooks = do
+ unlessM fileLevelEventsSupported $
+ error "Need at least OSX 10.7.0 for file-level FSEvents"
+ scan dir
+ eventStreamCreate [dir] 1.0 True True True handle
+ where
+ handle evt
+ | ignoredPath ignored (eventPath evt) = noop
+ | otherwise = do
+ {- More than one flag may be set, if events occurred
+ - close together.
+ -
+ - Order is important..
+ - If a file is added and then deleted, we'll see it's
+ - not present, and addHook won't run.
+ - OTOH, if a file is deleted and then re-added,
+ - the delHook will run first, followed by the addHook.
+ -}
+
+ when (hasflag eventFlagItemRemoved) $
+ if hasflag eventFlagItemIsDir
+ then runhook delDirHook Nothing
+ else runhook delHook Nothing
+ when (hasflag eventFlagItemCreated) $
+ maybe noop handleadd =<< getstatus (eventPath evt)
+ {- When a file or dir is renamed, a rename event is
+ - received for both its old and its new name. -}
+ when (hasflag eventFlagItemRenamed) $
+ if hasflag eventFlagItemIsDir
+ then ifM (doesDirectoryExist $ eventPath evt)
+ ( scan $ eventPath evt
+ , runhook delDirHook Nothing
+ )
+ else maybe (runhook delHook Nothing) handleadd
+ =<< getstatus (eventPath evt)
+ {- Add hooks are run when a file is modified for
+ - compatability with INotify, which calls the add
+ - hook when a file is closed, and so tends to call
+ - both add and modify for file modifications. -}
+ when (hasflag eventFlagItemModified && not (hasflag eventFlagItemIsDir)) $ do
+ ms <- getstatus $ eventPath evt
+ maybe noop handleadd ms
+ runhook modifyHook ms
+ where
+ hasflag f = eventFlags evt .&. f /= 0
+ runhook h s = maybe noop (\a -> a (eventPath evt) s) (h hooks)
+ handleadd s
+ | Files.isSymbolicLink s = runhook addSymlinkHook $ Just s
+ | Files.isRegularFile s = runhook addHook $ Just s
+ | otherwise = noop
+
+ scan d = unless (ignoredPath ignored d) $
+ mapM_ go =<< dirContentsRecursive d
+ where
+ go f
+ | ignoredPath ignored f = noop
+ | otherwise = do
+ ms <- getstatus f
+ case ms of
+ Nothing -> noop
+ Just s
+ | Files.isSymbolicLink s ->
+ runhook addSymlinkHook ms
+ | Files.isRegularFile s ->
+ runhook addHook ms
+ | otherwise ->
+ noop
+ where
+ runhook h s = maybe noop (\a -> a f s) (h hooks)
+
+ getstatus = catchMaybeIO . getSymbolicLinkStatus
+
+{- Check each component of the path to see if it's ignored. -}
+ignoredPath :: (FilePath -> Bool) -> FilePath -> Bool
+ignoredPath ignored = any ignored . map dropTrailingPathSeparator . splitPath
diff --git a/Utility/FileMode.hs b/Utility/FileMode.hs
new file mode 100644
index 000000000..46c6a31f5
--- /dev/null
+++ b/Utility/FileMode.hs
@@ -0,0 +1,142 @@
+{- File mode utilities.
+ -
+ - Copyright 2010-2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Utility.FileMode where
+
+import Common
+
+import Control.Exception (bracket)
+import System.PosixCompat.Types
+#ifndef mingw32_HOST_OS
+import System.Posix.Files
+#endif
+import Foreign (complement)
+
+{- Applies a conversion function to a file's mode. -}
+modifyFileMode :: FilePath -> (FileMode -> FileMode) -> IO ()
+modifyFileMode f convert = void $ modifyFileMode' f convert
+modifyFileMode' :: FilePath -> (FileMode -> FileMode) -> IO FileMode
+modifyFileMode' f convert = do
+ s <- getFileStatus f
+ let old = fileMode s
+ let new = convert old
+ when (new /= old) $
+ setFileMode f new
+ return old
+
+{- Adds the specified FileModes to the input mode, leaving the rest
+ - unchanged. -}
+addModes :: [FileMode] -> FileMode -> FileMode
+addModes ms m = combineModes (m:ms)
+
+{- Removes the specified FileModes from the input mode. -}
+removeModes :: [FileMode] -> FileMode -> FileMode
+removeModes ms m = m `intersectFileModes` complement (combineModes ms)
+
+{- Runs an action after changing a file's mode, then restores the old mode. -}
+withModifiedFileMode :: FilePath -> (FileMode -> FileMode) -> IO a -> IO a
+withModifiedFileMode file convert a = bracket setup cleanup go
+ where
+ setup = modifyFileMode' file convert
+ cleanup oldmode = modifyFileMode file (const oldmode)
+ go _ = a
+
+writeModes :: [FileMode]
+writeModes = [ownerWriteMode, groupWriteMode, otherWriteMode]
+
+readModes :: [FileMode]
+readModes = [ownerReadMode, groupReadMode, otherReadMode]
+
+executeModes :: [FileMode]
+executeModes = [ownerExecuteMode, groupExecuteMode, otherExecuteMode]
+
+{- Removes the write bits from a file. -}
+preventWrite :: FilePath -> IO ()
+preventWrite f = modifyFileMode f $ removeModes writeModes
+
+{- Turns a file's owner write bit back on. -}
+allowWrite :: FilePath -> IO ()
+allowWrite f = modifyFileMode f $ addModes [ownerWriteMode]
+
+{- Turns a file's owner read bit back on. -}
+allowRead :: FilePath -> IO ()
+allowRead f = modifyFileMode f $ addModes [ownerReadMode]
+
+{- Allows owner and group to read and write to a file. -}
+groupSharedModes :: [FileMode]
+groupSharedModes =
+ [ ownerWriteMode, groupWriteMode
+ , ownerReadMode, groupReadMode
+ ]
+
+groupWriteRead :: FilePath -> IO ()
+groupWriteRead f = modifyFileMode f $ addModes groupSharedModes
+
+checkMode :: FileMode -> FileMode -> Bool
+checkMode checkfor mode = checkfor `intersectFileModes` mode == checkfor
+
+{- Checks if a file mode indicates it's a symlink. -}
+isSymLink :: FileMode -> Bool
+#ifdef mingw32_HOST_OS
+isSymLink _ = False
+#else
+isSymLink = checkMode symbolicLinkMode
+#endif
+
+{- Checks if a file has any executable bits set. -}
+isExecutable :: FileMode -> Bool
+isExecutable mode = combineModes executeModes `intersectFileModes` mode /= 0
+
+{- Runs an action without that pesky umask influencing it, unless the
+ - passed FileMode is the standard one. -}
+noUmask :: FileMode -> IO a -> IO a
+#ifndef mingw32_HOST_OS
+noUmask mode a
+ | mode == stdFileMode = a
+ | otherwise = bracket setup cleanup go
+ where
+ setup = setFileCreationMask nullFileMode
+ cleanup = setFileCreationMask
+ go _ = a
+#else
+noUmask _ a = a
+#endif
+
+combineModes :: [FileMode] -> FileMode
+combineModes [] = undefined
+combineModes [m] = m
+combineModes (m:ms) = foldl unionFileModes m ms
+
+isSticky :: FileMode -> Bool
+#ifdef mingw32_HOST_OS
+isSticky _ = False
+#else
+isSticky = checkMode stickyMode
+
+stickyMode :: FileMode
+stickyMode = 512
+
+setSticky :: FilePath -> IO ()
+setSticky f = modifyFileMode f $ addModes [stickyMode]
+#endif
+
+{- Writes a file, ensuring that its modes do not allow it to be read
+ - by anyone other than the current user, before any content is written.
+ -
+ - On a filesystem that does not support file permissions, this is the same
+ - as writeFile.
+ -}
+writeFileProtected :: FilePath -> String -> IO ()
+writeFileProtected file content = do
+ h <- openFile file WriteMode
+ void $ tryIO $
+ modifyFileMode file $
+ removeModes [groupReadMode, otherReadMode]
+ hPutStr h content
+ hClose h
diff --git a/Utility/FileSystemEncoding.hs b/Utility/FileSystemEncoding.hs
new file mode 100644
index 000000000..ac105e73d
--- /dev/null
+++ b/Utility/FileSystemEncoding.hs
@@ -0,0 +1,93 @@
+{- GHC File system encoding handling.
+ -
+ - Copyright 2012-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Utility.FileSystemEncoding (
+ fileEncoding,
+ withFilePath,
+ md5FilePath,
+ decodeW8,
+ encodeW8,
+ truncateFilePath,
+) where
+
+import qualified GHC.Foreign as GHC
+import qualified GHC.IO.Encoding as Encoding
+import Foreign.C
+import System.IO
+import System.IO.Unsafe
+import qualified Data.Hash.MD5 as MD5
+import Data.Word
+import Data.Bits.Utils
+
+{- Sets a Handle to use the filesystem encoding. This causes data
+ - written or read from it to be encoded/decoded the same
+ - as ghc 7.4 does to filenames etc. This special encoding
+ - allows "arbitrary undecodable bytes to be round-tripped through it". -}
+fileEncoding :: Handle -> IO ()
+fileEncoding h = hSetEncoding h =<< Encoding.getFileSystemEncoding
+
+{- Marshal a Haskell FilePath into a NUL terminated C string using temporary
+ - storage. The FilePath is encoded using the filesystem encoding,
+ - reversing the decoding that should have been done when the FilePath
+ - was obtained. -}
+withFilePath :: FilePath -> (CString -> IO a) -> IO a
+withFilePath fp f = Encoding.getFileSystemEncoding
+ >>= \enc -> GHC.withCString enc fp f
+
+{- Encodes a FilePath into a String, applying the filesystem encoding.
+ -
+ - There are very few things it makes sense to do with such an encoded
+ - string. It's not a legal filename; it should not be displayed.
+ - So this function is not exported, but instead used by the few functions
+ - that can usefully consume it.
+ -
+ - This use of unsafePerformIO is belived to be safe; GHC's interface
+ - only allows doing this conversion with CStrings, and the CString buffer
+ - is allocated, used, and deallocated within the call, with no side
+ - effects.
+ -}
+{-# NOINLINE _encodeFilePath #-}
+_encodeFilePath :: FilePath -> String
+_encodeFilePath fp = unsafePerformIO $ do
+ enc <- Encoding.getFileSystemEncoding
+ GHC.withCString enc fp $ GHC.peekCString Encoding.char8
+
+{- Encodes a FilePath into a Md5.Str, applying the filesystem encoding. -}
+md5FilePath :: FilePath -> MD5.Str
+md5FilePath = MD5.Str . _encodeFilePath
+
+{- Converts a [Word8] to a FilePath, encoding using the filesystem encoding.
+ -
+ - w82c produces a String, which may contain Chars that are invalid
+ - unicode. From there, this is really a simple matter of applying the
+ - file system encoding, only complicated by GHC's interface to doing so.
+ -}
+{-# NOINLINE encodeW8 #-}
+encodeW8 :: [Word8] -> FilePath
+encodeW8 w8 = unsafePerformIO $ do
+ enc <- Encoding.getFileSystemEncoding
+ GHC.withCString Encoding.char8 (w82s w8) $ GHC.peekCString enc
+
+{- Useful when you want the actual number of bytes that will be used to
+ - represent the FilePath on disk. -}
+decodeW8 :: FilePath -> [Word8]
+decodeW8 = s2w8 . _encodeFilePath
+
+{- Truncates a FilePath to the given number of bytes (or less),
+ - as represented on disk.
+ -
+ - Avoids returning an invalid part of a unicode byte sequence, at the
+ - cost of efficiency when running on a large FilePath.
+ -}
+truncateFilePath :: Int -> FilePath -> FilePath
+truncateFilePath n = go . reverse
+ where
+ go f =
+ let bytes = decodeW8 f
+ in if length bytes <= n
+ then reverse f
+ else go (drop 1 f)
diff --git a/Utility/Format.hs b/Utility/Format.hs
new file mode 100644
index 000000000..e7a27515e
--- /dev/null
+++ b/Utility/Format.hs
@@ -0,0 +1,178 @@
+{- Formatted string handling.
+ -
+ - Copyright 2010, 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Utility.Format (
+ Format,
+ gen,
+ format,
+ decode_c,
+ encode_c,
+ prop_idempotent_deencode
+) where
+
+import Text.Printf (printf)
+import Data.Char (isAlphaNum, isOctDigit, isHexDigit, isSpace, chr, ord)
+import Data.Maybe (fromMaybe)
+import Data.Word (Word8)
+import Data.List (isPrefixOf)
+import qualified Codec.Binary.UTF8.String
+import qualified Data.Map as M
+
+import Utility.PartialPrelude
+
+type FormatString = String
+
+{- A format consists of a list of fragments. -}
+type Format = [Frag]
+
+{- A fragment is either a constant string,
+ - or a variable, with a justification. -}
+data Frag = Const String | Var String Justify
+ deriving (Show)
+
+data Justify = LeftJustified Int | RightJustified Int | UnJustified
+ deriving (Show)
+
+type Variables = M.Map String String
+
+{- Expands a Format using some variables, generating a formatted string.
+ - This can be repeatedly called, efficiently. -}
+format :: Format -> Variables -> String
+format f vars = concatMap expand f
+ where
+ expand (Const s) = s
+ expand (Var name j)
+ | "escaped_" `isPrefixOf` name =
+ justify j $ encode_c_strict $
+ getvar $ drop (length "escaped_") name
+ | otherwise = justify j $ getvar name
+ getvar name = fromMaybe "" $ M.lookup name vars
+ justify UnJustified s = s
+ justify (LeftJustified i) s = s ++ pad i s
+ justify (RightJustified i) s = pad i s ++ s
+ pad i s = take (i - length s) spaces
+ spaces = repeat ' '
+
+{- Generates a Format that can be used to expand variables in a
+ - format string, such as "${foo} ${bar;10} ${baz;-10}\n"
+ -
+ - (This is the same type of format string used by dpkg-query.)
+ -}
+gen :: FormatString -> Format
+gen = filter (not . empty) . fuse [] . scan [] . decode_c
+ where
+ -- The Format is built up in reverse, for efficiency,
+ -- and can have many adjacent Consts. Fusing it fixes both
+ -- problems.
+ fuse f [] = f
+ fuse f (Const c1:Const c2:vs) = fuse f $ Const (c2++c1) : vs
+ fuse f (v:vs) = fuse (v:f) vs
+
+ scan f (a:b:cs)
+ | a == '$' && b == '{' = invar f [] cs
+ | otherwise = scan (Const [a] : f ) (b:cs)
+ scan f v = Const v : f
+
+ invar f var [] = Const (novar var) : f
+ invar f var (c:cs)
+ | c == '}' = foundvar f var UnJustified cs
+ | isAlphaNum c || c == '_' = invar f (c:var) cs
+ | c == ';' = inpad "" f var cs
+ | otherwise = scan ((Const $ novar $ c:var):f) cs
+
+ inpad p f var (c:cs)
+ | c == '}' = foundvar f var (readjustify $ reverse p) cs
+ | otherwise = inpad (c:p) f var cs
+ inpad p f var [] = Const (novar $ p++";"++var) : f
+ readjustify = getjustify . fromMaybe 0 . readish
+ getjustify i
+ | i == 0 = UnJustified
+ | i < 0 = LeftJustified (-1 * i)
+ | otherwise = RightJustified i
+ novar v = "${" ++ reverse v
+ foundvar f v p = scan (Var (reverse v) p : f)
+
+empty :: Frag -> Bool
+empty (Const "") = True
+empty _ = False
+
+{- Decodes a C-style encoding, where \n is a newline, \NNN is an octal
+ - encoded character, and \xNN is a hex encoded character.
+ -}
+decode_c :: FormatString -> FormatString
+decode_c [] = []
+decode_c s = unescape ("", s)
+ where
+ e = '\\'
+ unescape (b, []) = b
+ -- look for escapes starting with '\'
+ unescape (b, v) = b ++ fst pair ++ unescape (handle $ snd pair)
+ where
+ pair = span (/= e) v
+ isescape x = x == e
+ handle (x:'x':n1:n2:rest)
+ | isescape x && allhex = (fromhex, rest)
+ where
+ allhex = isHexDigit n1 && isHexDigit n2
+ fromhex = [chr $ readhex [n1, n2]]
+ readhex h = Prelude.read $ "0x" ++ h :: Int
+ handle (x:n1:n2:n3:rest)
+ | isescape x && alloctal = (fromoctal, rest)
+ where
+ alloctal = isOctDigit n1 && isOctDigit n2 && isOctDigit n3
+ fromoctal = [chr $ readoctal [n1, n2, n3]]
+ readoctal o = Prelude.read $ "0o" ++ o :: Int
+ -- \C is used for a few special characters
+ handle (x:nc:rest)
+ | isescape x = ([echar nc], rest)
+ where
+ echar 'a' = '\a'
+ echar 'b' = '\b'
+ echar 'f' = '\f'
+ echar 'n' = '\n'
+ echar 'r' = '\r'
+ echar 't' = '\t'
+ echar 'v' = '\v'
+ echar a = a
+ handle n = ("", n)
+
+{- Inverse of decode_c. -}
+encode_c :: FormatString -> FormatString
+encode_c = encode_c' (const False)
+
+{- Encodes more strictly, including whitespace. -}
+encode_c_strict :: FormatString -> FormatString
+encode_c_strict = encode_c' isSpace
+
+encode_c' :: (Char -> Bool) -> FormatString -> FormatString
+encode_c' p = concatMap echar
+ where
+ e c = '\\' : [c]
+ echar '\a' = e 'a'
+ echar '\b' = e 'b'
+ echar '\f' = e 'f'
+ echar '\n' = e 'n'
+ echar '\r' = e 'r'
+ echar '\t' = e 't'
+ echar '\v' = e 'v'
+ echar '\\' = e '\\'
+ echar '"' = e '"'
+ echar c
+ | ord c < 0x20 = e_asc c -- low ascii
+ | ord c >= 256 = e_utf c -- unicode
+ | ord c > 0x7E = e_asc c -- high ascii
+ | p c = e_asc c -- unprintable ascii
+ | otherwise = [c] -- printable ascii
+ -- unicode character is decomposed to individual Word8s,
+ -- and each is shown in octal
+ e_utf c = showoctal =<< (Codec.Binary.UTF8.String.encode [c] :: [Word8])
+ e_asc c = showoctal $ ord c
+ showoctal i = '\\' : printf "%03o" i
+
+{- for quickcheck -}
+prop_idempotent_deencode :: String -> Bool
+prop_idempotent_deencode s = s == decode_c (encode_c s)
diff --git a/Utility/FreeDesktop.hs b/Utility/FreeDesktop.hs
new file mode 100644
index 000000000..da9d7b618
--- /dev/null
+++ b/Utility/FreeDesktop.hs
@@ -0,0 +1,144 @@
+{- Freedesktop.org specifications
+ -
+ - http://standards.freedesktop.org/basedir-spec/latest/
+ - http://standards.freedesktop.org/desktop-entry-spec/latest/
+ - http://standards.freedesktop.org/menu-spec/latest/
+ - http://standards.freedesktop.org/icon-theme-spec/latest/
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Utility.FreeDesktop (
+ DesktopEntry,
+ genDesktopEntry,
+ buildDesktopMenuFile,
+ writeDesktopMenuFile,
+ desktopMenuFilePath,
+ autoStartPath,
+ iconDir,
+ iconFilePath,
+ systemDataDir,
+ systemConfigDir,
+ userDataDir,
+ userConfigDir,
+ userDesktopDir
+) where
+
+import Utility.Exception
+import Utility.Path
+import Utility.UserInfo
+import Utility.Process
+import Utility.PartialPrelude
+
+import System.Environment
+import System.Directory
+import System.FilePath
+import Data.List
+import Data.String.Utils
+import Data.Maybe
+import Control.Applicative
+
+type DesktopEntry = [(Key, Value)]
+
+type Key = String
+
+data Value = StringV String | BoolV Bool | NumericV Float | ListV [Value]
+
+toString :: Value -> String
+toString (StringV s) = s
+toString (BoolV b)
+ | b = "true"
+ | otherwise = "false"
+toString(NumericV f) = show f
+toString (ListV l)
+ | null l = ""
+ | otherwise = (intercalate ";" $ map (escapesemi . toString) l) ++ ";"
+ where
+ escapesemi = join "\\;" . split ";"
+
+genDesktopEntry :: String -> String -> Bool -> FilePath -> Maybe String -> [String] -> DesktopEntry
+genDesktopEntry name comment terminal program icon categories = catMaybes
+ [ item "Type" StringV "Application"
+ , item "Version" NumericV 1.0
+ , item "Name" StringV name
+ , item "Comment" StringV comment
+ , item "Terminal" BoolV terminal
+ , item "Exec" StringV program
+ , maybe Nothing (item "Icon" StringV) icon
+ , item "Categories" ListV (map StringV categories)
+ ]
+ where
+ item x c y = Just (x, c y)
+
+buildDesktopMenuFile :: DesktopEntry -> String
+buildDesktopMenuFile d = unlines ("[Desktop Entry]" : map keyvalue d) ++ "\n"
+ where
+ keyvalue (k, v) = k ++ "=" ++ toString v
+
+writeDesktopMenuFile :: DesktopEntry -> String -> IO ()
+writeDesktopMenuFile d file = do
+ createDirectoryIfMissing True (parentDir file)
+ writeFile file $ buildDesktopMenuFile d
+
+{- Path to use for a desktop menu file, in either the systemDataDir or
+ - the userDataDir -}
+desktopMenuFilePath :: String -> FilePath -> FilePath
+desktopMenuFilePath basename datadir =
+ datadir </> "applications" </> desktopfile basename
+
+{- Path to use for a desktop autostart file, in either the systemDataDir
+ - or the userDataDir -}
+autoStartPath :: String -> FilePath -> FilePath
+autoStartPath basename configdir =
+ configdir </> "autostart" </> desktopfile basename
+
+{- Base directory to install an icon file, in either the systemDataDir
+ - or the userDatadir. -}
+iconDir :: FilePath -> FilePath
+iconDir datadir = datadir </> "icons" </> "hicolor"
+
+{- Filename of an icon, given the iconDir to use.
+ -
+ - The resolution is something like "48x48" or "scalable". -}
+iconFilePath :: FilePath -> String -> FilePath -> FilePath
+iconFilePath file resolution icondir =
+ icondir </> resolution </> "apps" </> file
+
+desktopfile :: FilePath -> FilePath
+desktopfile f = f ++ ".desktop"
+
+{- Directory used for installation of system wide data files.. -}
+systemDataDir :: FilePath
+systemDataDir = "/usr/share"
+
+{- Directory used for installation of system wide config files. -}
+systemConfigDir :: FilePath
+systemConfigDir = "/etc/xdg"
+
+{- Directory for user data files. -}
+userDataDir :: IO FilePath
+userDataDir = xdgEnvHome "DATA_HOME" ".local/share"
+
+{- Directory for user config files. -}
+userConfigDir :: IO FilePath
+userConfigDir = xdgEnvHome "CONFIG_HOME" ".config"
+
+{- Directory for the user's Desktop, may be localized.
+ -
+ - This is not looked up very fast; the config file is in a shell format
+ - that is best parsed by shell, so xdg-user-dir is used, with a fallback
+ - to ~/Desktop. -}
+userDesktopDir :: IO FilePath
+userDesktopDir = maybe fallback return =<< (parse <$> xdg_user_dir)
+ where
+ parse = maybe Nothing (headMaybe . lines)
+ xdg_user_dir = catchMaybeIO $ readProcess "xdg-user-dir" ["DESKTOP"]
+ fallback = xdgEnvHome "DESKTOP_DIR" "Desktop"
+
+xdgEnvHome :: String -> String -> IO String
+xdgEnvHome envbase homedef = do
+ home <- myHomeDir
+ catchDefaultIO (home </> homedef) $
+ getEnv $ "XDG_" ++ envbase
diff --git a/Utility/Gpg.hs b/Utility/Gpg.hs
new file mode 100644
index 000000000..a2baa74dc
--- /dev/null
+++ b/Utility/Gpg.hs
@@ -0,0 +1,379 @@
+{- gpg interface
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Utility.Gpg where
+
+import Control.Applicative
+import Control.Concurrent
+import qualified Data.Map as M
+
+import Common
+import qualified Build.SysConfig as SysConfig
+
+#ifndef mingw32_HOST_OS
+import System.Posix.Types
+import Control.Exception (bracket)
+import System.Path
+import Utility.Env
+#else
+import Utility.Tmp
+#endif
+import Utility.Format (decode_c)
+
+type KeyId = String
+
+newtype KeyIds = KeyIds { keyIds :: [KeyId] }
+ deriving (Ord, Eq)
+
+{- If a specific gpg command was found at configure time, use it.
+ - Otherwise, try to run gpg. -}
+gpgcmd :: FilePath
+gpgcmd = fromMaybe "gpg" SysConfig.gpg
+
+-- Generate an argument list to asymetrically encrypt to the given recipients.
+pkEncTo :: [String] -> [CommandParam]
+pkEncTo = concatMap (\r -> [Param "--recipient", Param r])
+
+stdParams :: [CommandParam] -> IO [String]
+stdParams params = do
+#ifndef mingw32_HOST_OS
+ -- Enable batch mode if GPG_AGENT_INFO is set, to avoid extraneous
+ -- gpg output about password prompts. GPG_BATCH is set by the test
+ -- suite for a similar reason.
+ e <- getEnv "GPG_AGENT_INFO"
+ b <- getEnv "GPG_BATCH"
+ let batch = if isNothing e && isNothing b
+ then []
+ else ["--batch", "--no-tty", "--use-agent"]
+ return $ batch ++ defaults ++ toCommand params
+#else
+ return $ defaults ++ toCommand params
+#endif
+ where
+ -- Be quiet, even about checking the trustdb.
+ defaults = ["--quiet", "--trust-model", "always"]
+
+{- Usual options for symmetric / public-key encryption. -}
+stdEncryptionParams :: Bool -> [CommandParam]
+stdEncryptionParams symmetric =
+ [ enc symmetric
+ , Param "--force-mdc"
+ , Param "--no-textmode"
+ ]
+ where
+ enc True = Param "--symmetric"
+ -- Force gpg to only encrypt to the specified recipients, not
+ -- configured defaults. Recipients are assumed to be specified in
+ -- elsewhere.
+ enc False = Params "--encrypt --no-encrypt-to --no-default-recipient"
+
+{- Runs gpg with some params and returns its stdout, strictly. -}
+readStrict :: [CommandParam] -> IO String
+readStrict params = do
+ params' <- stdParams params
+ withHandle StdoutHandle createProcessSuccess (proc gpgcmd params') $ \h -> do
+ hSetBinaryMode h True
+ hGetContentsStrict h
+
+{- Runs gpg, piping an input value to it, and returning its stdout,
+ - strictly. -}
+pipeStrict :: [CommandParam] -> String -> IO String
+pipeStrict params input = do
+ params' <- stdParams params
+ withBothHandles createProcessSuccess (proc gpgcmd params') $ \(to, from) -> do
+ hSetBinaryMode to True
+ hSetBinaryMode from True
+ hPutStr to input
+ hClose to
+ hGetContentsStrict from
+
+{- Runs gpg with some parameters. First sends it a passphrase (unless it
+ - is empty) via '--passphrase-fd'. Then runs a feeder action that is
+ - passed a handle and should write to it all the data to input to gpg.
+ - Finally, runs a reader action that is passed a handle to gpg's
+ - output.
+ -
+ - Runs gpg in batch mode; this is necessary to avoid gpg 2.x prompting for
+ - the passphrase.
+ -
+ - Note that to avoid deadlock with the cleanup stage,
+ - the reader must fully consume gpg's input before returning. -}
+feedRead :: [CommandParam] -> String -> (Handle -> IO ()) -> (Handle -> IO a) -> IO a
+feedRead params passphrase feeder reader = do
+#ifndef mingw32_HOST_OS
+ -- pipe the passphrase into gpg on a fd
+ (frompipe, topipe) <- createPipe
+ void $ forkIO $ do
+ toh <- fdToHandle topipe
+ hPutStrLn toh passphrase
+ hClose toh
+ let Fd pfd = frompipe
+ let passphrasefd = [Param "--passphrase-fd", Param $ show pfd]
+ closeFd frompipe `after` go (passphrasefd ++ params)
+#else
+ -- store the passphrase in a temp file for gpg
+ withTmpFile "gpg" $ \tmpfile h -> do
+ hPutStr h passphrase
+ hClose h
+ let passphrasefile = [Param "--passphrase-file", File tmpfile]
+ go $ passphrasefile ++ params
+#endif
+ where
+ go params' = pipeLazy params' feeder reader
+
+{- Like feedRead, but without passphrase. -}
+pipeLazy :: [CommandParam] -> (Handle -> IO ()) -> (Handle -> IO a) -> IO a
+pipeLazy params feeder reader = do
+ params' <- stdParams $ Param "--batch" : params
+ withBothHandles createProcessSuccess (proc gpgcmd params')
+ $ \(to, from) -> do
+ void $ forkIO $ do
+ feeder to
+ hClose to
+ reader from
+
+{- Finds gpg public keys matching some string. (Could be an email address,
+ - a key id, or a name; See the section 'HOW TO SPECIFY A USER ID' of
+ - GnuPG's manpage.) -}
+findPubKeys :: String -> IO KeyIds
+findPubKeys for = KeyIds . parse . lines <$> readStrict params
+ where
+ params = [Params "--with-colons --list-public-keys", Param for]
+ parse = catMaybes . map (keyIdField . split ":")
+ keyIdField ("pub":_:_:_:f:_) = Just f
+ keyIdField _ = Nothing
+
+type UserId = String
+
+{- All of the user's secret keys, with their UserIds.
+ - Note that the UserId may be empty. -}
+secretKeys :: IO (M.Map KeyId UserId)
+secretKeys = M.fromList . parse . lines <$> readStrict params
+ where
+ params = [Params "--with-colons --list-secret-keys --fixed-list-mode"]
+ parse = extract [] Nothing . map (split ":")
+ extract c (Just keyid) (("uid":_:_:_:_:_:_:_:_:userid:_):rest) =
+ extract ((keyid, decode_c userid):c) Nothing rest
+ extract c (Just keyid) rest =
+ extract ((keyid, ""):c) Nothing rest
+ extract c _ [] = c
+ extract c _ (("sec":_:_:_:keyid:_):rest) =
+ extract c (Just keyid) rest
+ extract c k (_:rest) =
+ extract c k rest
+
+type Passphrase = String
+type Size = Int
+data KeyType = Algo Int | DSA | RSA
+
+{- The maximum key size that gpg currently offers in its UI when
+ - making keys. -}
+maxRecommendedKeySize :: Size
+maxRecommendedKeySize = 4096
+
+{- Generates a secret key using the experimental batch mode.
+ - The key is added to the secret key ring.
+ - Can take a very long time, depending on system entropy levels.
+ -}
+genSecretKey :: KeyType -> Passphrase -> UserId -> Size -> IO ()
+genSecretKey keytype passphrase userid keysize =
+ withHandle StdinHandle createProcessSuccess (proc gpgcmd params) feeder
+ where
+ params = ["--batch", "--gen-key"]
+ feeder h = do
+ hPutStr h $ unlines $ catMaybes
+ [ Just $ "Key-Type: " ++
+ case keytype of
+ DSA -> "DSA"
+ RSA -> "RSA"
+ Algo n -> show n
+ , Just $ "Key-Length: " ++ show keysize
+ , Just $ "Name-Real: " ++ userid
+ , Just $ "Expire-Date: 0"
+ , if null passphrase
+ then Nothing
+ else Just $ "Passphrase: " ++ passphrase
+ ]
+ hClose h
+
+{- Creates a block of high-quality random data suitable to use as a cipher.
+ - It is armored, to avoid newlines, since gpg only reads ciphers up to the
+ - first newline. -}
+genRandom :: Bool -> Size -> IO String
+genRandom highQuality size = checksize <$> readStrict
+ [ Params params
+ , Param $ show randomquality
+ , Param $ show size
+ ]
+ where
+ params = "--gen-random --armor"
+
+ -- See http://www.gnupg.org/documentation/manuals/gcrypt/Quality-of-random-numbers.html
+ -- for the meaning of random quality levels.
+ -- The highest available is 2, which is the default for OpenPGP
+ -- key generation; Note that it uses the blocking PRNG /dev/random
+ -- on the Linux kernel, hence the running time may take a while.
+ randomquality :: Int
+ randomquality = if highQuality then 2 else 1
+
+ {- The size is the number of bytes of entropy desired; the data is
+ - base64 encoded, so needs 8 bits to represent every 6 bytes of
+ - entropy. -}
+ expectedlength = size * 8 `div` 6
+
+ checksize s = let len = length s in
+ if len >= expectedlength
+ then s
+ else shortread len
+
+ shortread got = error $ unwords
+ [ "Not enough bytes returned from gpg", params
+ , "(got", show got, "; expected", show expectedlength, ")"
+ ]
+
+{- A test key. This is provided pre-generated since generating a new gpg
+ - key is too much work (requires too much entropy) for a test suite to
+ - do.
+ -
+ - This key was generated with no exipiration date, and a small keysize.
+ - It has an empty passphrase. -}
+testKeyId :: String
+testKeyId = "129D6E0AC537B9C7"
+testKey :: String
+testKey = keyBlock True
+ [ "mI0ETvFAZgEEAKnqwWgZqznMhi1RQExem2H8t3OyKDxaNN3rBN8T6LWGGqAYV4wT"
+ , "r8In5tfsnz64bKpE1Qi68JURFwYmthgUL9N48tbODU8t3xzijdjLOSaTyqkH1ik6"
+ , "EyulfKN63xLne9i4F9XqNwpiZzukXYbNfHkDA2yb0M6g4UFKLY/fNzGXABEBAAG0"
+ , "W2luc2VjdXJlIHRlc3Qga2V5ICh0aGlzIGlzIGEgdGVzdCBrZXksIGRvIG5vdCB1"
+ , "c2UgZm9yIGFjdHVhbCBlbmNyeXB0aW9uKSA8dGVzdEBleGFtcGxlLmNvbT6IuAQT"
+ , "AQgAIgUCTvFAZgIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AACgkQEp1uCsU3"
+ , "uceQ9wP/YMd1f0+/eLLcwGXNBvGqyVhUOfAKknO1bMzGbqTsq9g60qegy/cldqee"
+ , "xVxNfy0VN//JeMfgdcb8+RgJYLoaMrTy9CcsUcFPxtwN9tcLmsM0V2/fNmmFBO9t"
+ , "v75iH+zeFbNg0/FbPkHiN6Mjw7P2gXYKQXgTvQZBWaphk8oQlBm4jQRO8UBmAQQA"
+ , "vdi50M/WRCkOLt2RsUve8V8brMWYTJBJTTWoHUeRr82v4NCdX7OE1BsoVK8cy/1Q"
+ , "Y+gLOH9PqinuGGNWRmPV2Ju/RYn5H7sdewXA8E80xWhc4phHRMJ8Jjhg/GVPamkJ"
+ , "8B5zeKF0jcLFl7cuVdOyQakhoeDWJd0CyfW837nmPtMAEQEAAYifBBgBCAAJBQJO"
+ , "8UBmAhsMAAoJEBKdbgrFN7nHclAEAKBShuP/toH03atDUQTbGE34CA4yEC9BVghi"
+ , "7kviOZlOz2s8xAfp/8AYsrECx1kgbXcA7JD902eNyp7NzXsdJX0zJwHqiuZW0XlD"
+ , "T8ZJu4qrYRYgl/790WPESZ+ValvHD/fqkR38RF4tfxvyoMhhp0roGmJY33GASIG/"
+ , "+gQkDF9/"
+ , "=1k11"
+ ]
+testSecretKey :: String
+testSecretKey = keyBlock False
+ [ "lQHYBE7xQGYBBACp6sFoGas5zIYtUUBMXpth/Ldzsig8WjTd6wTfE+i1hhqgGFeM"
+ , "E6/CJ+bX7J8+uGyqRNUIuvCVERcGJrYYFC/TePLWzg1PLd8c4o3Yyzkmk8qpB9Yp"
+ , "OhMrpXyjet8S53vYuBfV6jcKYmc7pF2GzXx5AwNsm9DOoOFBSi2P3zcxlwARAQAB"
+ , "AAP+PlRboxy7Z0XjuG70N6+CrzSddQbW5KCwgPFrxYsPk7sAPFcBkmRMVlv9vZpS"
+ , "phbP4bvDK+MrSntM51g+9uE802yhPhSWdmEbImiWfV2ucEhlLjD8gw7JDex9XZ0a"
+ , "EbTOV56wOsILuedX/jF/6i6IQzy5YmuMeo+ip1XQIsIN+80CAMyXepOBJgHw/gBD"
+ , "VdXh/l//vUkQQlhInQYwgkKbr0POCTdr8DM1qdKLcUD9Q1khgNRp0vZGGz+5xsrc"
+ , "KaODUlMCANSczLJcYWa8yPqB3S14yTe7qmtDiOS362+SeVUwQA7eQ06PcHLPsN+p"
+ , "NtWoHRfYazxrs+g0JvmoQOYdj4xSQy0CAMq7H/l6aeG1n8tpyMxqE7OvBOsvzdu5"
+ , "XS7I1AnwllVFgvTadVvqgf7b+hdYd91doeHDUGqSYO78UG1GgaBHJdylqrRbaW5z"
+ , "ZWN1cmUgdGVzdCBrZXkgKHRoaXMgaXMgYSB0ZXN0IGtleSwgZG8gbm90IHVzZSBm"
+ , "b3IgYWN0dWFsIGVuY3J5cHRpb24pIDx0ZXN0QGV4YW1wbGUuY29tPoi4BBMBCAAi"
+ , "BQJO8UBmAhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIXgAAKCRASnW4KxTe5x5D3"
+ , "A/9gx3V/T794stzAZc0G8arJWFQ58AqSc7VszMZupOyr2DrSp6DL9yV2p57FXE1/"
+ , "LRU3/8l4x+B1xvz5GAlguhoytPL0JyxRwU/G3A321wuawzRXb982aYUE722/vmIf"
+ , "7N4Vs2DT8Vs+QeI3oyPDs/aBdgpBeBO9BkFZqmGTyhCUGZ0B2ARO8UBmAQQAvdi5"
+ , "0M/WRCkOLt2RsUve8V8brMWYTJBJTTWoHUeRr82v4NCdX7OE1BsoVK8cy/1QY+gL"
+ , "OH9PqinuGGNWRmPV2Ju/RYn5H7sdewXA8E80xWhc4phHRMJ8Jjhg/GVPamkJ8B5z"
+ , "eKF0jcLFl7cuVdOyQakhoeDWJd0CyfW837nmPtMAEQEAAQAD/RaVtFFTkF1udun7"
+ , "YOwzJvQXCO9OWHZvSdEeG4BUNdAwy4YWu0oZzKkBDBS6+lWILqqb/c28U4leUJ1l"
+ , "H+viz5svN9BWWyj/UpI00uwUo9JaIqalemwfLx6vsh69b54L1B4exLZHYGLvy/B3"
+ , "5T6bT0gpOE+53BRtKcJaOh/McQeJAgDTOCBU5weWOf6Bhqnw3Vr/gRfxntAz2okN"
+ , "gqz/h79mWbCc/lHKoYQSsrCdMiwziHSjXwvehUrdWE/AcomtW0vbAgDmGJqJ2fNr"
+ , "HvdsGx4Ld/BxyiZbCURJLUQ5CwzfHGIvBu9PMT8zM26NOSncaXRjxDna2Ggh8Uum"
+ , "ANEwbnhxFwZpAf9L9RLYIMTtAqwBjfXJg/lHcc2R+VP0hL5c8zFz+S+w7bRqINwL"
+ , "ff1JstKuHT2nJnu0ustK66by8YI3T0hDFFahnNCInwQYAQgACQUCTvFAZgIbDAAK"
+ , "CRASnW4KxTe5x3JQBACgUobj/7aB9N2rQ1EE2xhN+AgOMhAvQVYIYu5L4jmZTs9r"
+ , "PMQH6f/AGLKxAsdZIG13AOyQ/dNnjcqezc17HSV9MycB6ormVtF5Q0/GSbuKq2EW"
+ , "IJf+/dFjxEmflWpbxw/36pEd/EReLX8b8qDIYadK6BpiWN9xgEiBv/oEJAxffw=="
+ , "=LDsg"
+ ]
+keyBlock :: Bool -> [String] -> String
+keyBlock public ls = unlines
+ [ "-----BEGIN PGP "++t++" KEY BLOCK-----"
+ , "Version: GnuPG v1.4.11 (GNU/Linux)"
+ , ""
+ , unlines ls
+ , "-----END PGP "++t++" KEY BLOCK-----"
+ ]
+ where
+ t
+ | public = "PUBLIC"
+ | otherwise = "PRIVATE"
+
+#ifndef mingw32_HOST_OS
+{- Runs an action using gpg in a test harness, in which gpg does
+ - not use ~/.gpg/, but a directory with the test key set up to be used. -}
+testHarness :: IO a -> IO a
+testHarness a = do
+ orig <- getEnv var
+ bracket setup (cleanup orig) (const a)
+ where
+ var = "GNUPGHOME"
+
+ setup = do
+ base <- getTemporaryDirectory
+ dir <- mktmpdir $ base </> "gpgtmpXXXXXX"
+ void $ setEnv var dir True
+ _ <- pipeStrict [Params "--import -q"] $ unlines
+ [testSecretKey, testKey]
+ return dir
+
+ cleanup orig tmpdir = removeDirectoryRecursive tmpdir >> reset orig
+ reset (Just v) = setEnv var v True
+ reset _ = unsetEnv var
+
+{- Tests the test harness. -}
+testTestHarness :: IO Bool
+testTestHarness = do
+ keys <- testHarness $ findPubKeys testKeyId
+ return $ KeyIds [testKeyId] == keys
+#endif
+
+#ifndef mingw32_HOST_OS
+checkEncryptionFile :: FilePath -> Maybe KeyIds -> IO Bool
+checkEncryptionFile filename keys =
+ checkGpgPackets keys =<< readStrict params
+ where
+ params = [Params "--list-packets --list-only", File filename]
+
+checkEncryptionStream :: String -> Maybe KeyIds -> IO Bool
+checkEncryptionStream stream keys =
+ checkGpgPackets keys =<< pipeStrict params stream
+ where
+ params = [Params "--list-packets --list-only"]
+
+{- Parses an OpenPGP packet list, and checks whether data is
+ - symmetrically encrypted (keys is Nothing), or encrypted to some
+ - public key(s).
+ - /!\ The key needs to be in the keyring! -}
+checkGpgPackets :: Maybe KeyIds -> String -> IO Bool
+checkGpgPackets keys str = do
+ let (asym,sym) = partition (pubkeyEncPacket `isPrefixOf`) $
+ filter (\l' -> pubkeyEncPacket `isPrefixOf` l' ||
+ symkeyEncPacket `isPrefixOf` l') $
+ takeWhile (/= ":encrypted data packet:") $
+ lines str
+ case (keys,asym,sym) of
+ (Nothing, [], [_]) -> return True
+ (Just (KeyIds ks), ls, []) -> do
+ -- Find the master key associated with the
+ -- encryption subkey.
+ ks' <- concat <$> mapM (keyIds <$$> findPubKeys)
+ [ k | k:"keyid":_ <- map (reverse . words) ls ]
+ return $ sort (nub ks) == sort (nub ks')
+ _ -> return False
+ where
+ pubkeyEncPacket = ":pubkey enc packet: "
+ symkeyEncPacket = ":symkey enc packet: "
+#endif
diff --git a/Utility/Hash.hs b/Utility/Hash.hs
new file mode 100644
index 000000000..cecc6af3e
--- /dev/null
+++ b/Utility/Hash.hs
@@ -0,0 +1,69 @@
+{- Convenience wrapper around cryptohash.
+ - Falls back to SHA if it's not available.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Utility.Hash (
+ sha1,
+ sha224,
+ sha256,
+ sha384,
+ sha512,
+#ifdef WITH_CRYPTOHASH
+ skein256,
+ skein512,
+#endif
+ prop_hashes_stable
+) where
+
+import qualified Data.ByteString.Lazy as L
+import qualified Data.ByteString.Char8 as C8
+
+#ifndef WITH_CRYPTOHASH
+import Data.Digest.Pure.SHA
+#else
+import Crypto.Hash
+
+sha1 :: L.ByteString -> Digest SHA1
+sha1 = hashlazy
+
+sha224 :: L.ByteString -> Digest SHA224
+sha224 = hashlazy
+
+sha256 :: L.ByteString -> Digest SHA256
+sha256 = hashlazy
+
+sha384 :: L.ByteString -> Digest SHA384
+sha384 = hashlazy
+
+sha512 :: L.ByteString -> Digest SHA512
+sha512 = hashlazy
+
+-- sha3 is not yet fully standardized
+--sha3 :: L.ByteString -> Digest SHA3
+--sha3 = hashlazy
+
+skein256 :: L.ByteString -> Digest Skein256_256
+skein256 = hashlazy
+
+skein512 :: L.ByteString -> Digest Skein512_512
+skein512 = hashlazy
+
+#endif
+
+{- Check that all the hashes continue to hash the same. -}
+prop_hashes_stable :: Bool
+prop_hashes_stable = all (\(hasher, result) -> hasher foo == result)
+ [ (show . sha1, "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33")
+ , (show . sha224, "0808f64e60d58979fcb676c96ec938270dea42445aeefcd3a4e6f8db")
+ , (show . sha256, "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae")
+ , (show . sha384, "98c11ffdfdd540676b1a137cb1a22b2a70350c9a44171d6b1180c6be5cbb2ee3f79d532c8a1dd9ef2e8e08e752a3babb")
+ , (show . sha512, "f7fbba6e0636f890e56fbbf3283e524c6fa3204ae298382d624741d0dc6638326e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7")
+#ifdef WITH_CRYPTOHASH
+ , (show . skein256, "a04efd9a0aeed6ede40fe5ce0d9361ae7b7d88b524aa19917b9315f1ecf00d33")
+ , (show . skein512, "fd8956898113510180aa4658e6c0ac85bd74fb47f4a4ba264a6b705d7a8e8526756e75aecda12cff4f1aca1a4c2830fbf57f458012a66b2b15a3dd7d251690a7")
+#endif
+ ]
+ where
+ foo = L.fromChunks [C8.pack "foo"]
diff --git a/Utility/HumanNumber.hs b/Utility/HumanNumber.hs
new file mode 100644
index 000000000..904135987
--- /dev/null
+++ b/Utility/HumanNumber.hs
@@ -0,0 +1,21 @@
+{- numbers for humans
+ -
+ - Copyright 2012-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Utility.HumanNumber where
+
+{- Displays a fractional value as a string with a limited number
+ - of decimal digits. -}
+showImprecise :: RealFrac a => Int -> a -> String
+showImprecise precision n
+ | precision == 0 || remainder == 0 = show (round n :: Integer)
+ | otherwise = show int ++ "." ++ striptrailing0s (pad0s $ show remainder)
+ where
+ int :: Integer
+ (int, frac) = properFraction n
+ remainder = round (frac * 10 ^ precision) :: Integer
+ pad0s s = (take (precision - length s) (repeat '0')) ++ s
+ striptrailing0s = reverse . dropWhile (== '0') . reverse
diff --git a/Utility/HumanTime.hs b/Utility/HumanTime.hs
new file mode 100644
index 000000000..644e6fbab
--- /dev/null
+++ b/Utility/HumanTime.hs
@@ -0,0 +1,86 @@
+{- Time for humans.
+ -
+ - Copyright 2012-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Utility.HumanTime (
+ Duration(..),
+ durationToPOSIXTime,
+ parseDuration,
+ fromDuration,
+ prop_duration_roundtrips
+) where
+
+import Utility.PartialPrelude
+import Utility.Applicative
+import Utility.QuickCheck
+
+import Data.Time.Clock.POSIX (POSIXTime)
+import Data.Char
+import Control.Applicative
+import qualified Data.Map as M
+
+newtype Duration = Duration { durationSeconds :: Integer }
+ deriving (Eq, Ord, Read, Show)
+
+durationToPOSIXTime :: Duration -> POSIXTime
+durationToPOSIXTime = fromIntegral . durationSeconds
+
+{- Parses a human-input time duration, of the form "5h", "1m", "5h1m", etc -}
+parseDuration :: String -> Maybe Duration
+parseDuration = Duration <$$> go 0
+ where
+ go n [] = return n
+ go n s = do
+ num <- readish s :: Maybe Integer
+ case dropWhile isDigit s of
+ (c:rest) -> do
+ u <- M.lookup c unitmap
+ go (n + num * u) rest
+ _ -> return $ n + num
+
+fromDuration :: Duration -> String
+fromDuration Duration { durationSeconds = d }
+ | d == 0 = "0s"
+ | otherwise = concat $ map showunit $ go [] units d
+ where
+ showunit (u, n)
+ | n > 0 = show n ++ [u]
+ | otherwise = ""
+ go c [] _ = reverse c
+ go c ((u, n):us) v =
+ let (q,r) = v `quotRem` n
+ in go ((u, q):c) us r
+
+units :: [(Char, Integer)]
+units =
+ [ ('y', ysecs)
+ , ('d', dsecs)
+ , ('h', hsecs)
+ , ('m', msecs)
+ , ('s', 1)
+ ]
+
+unitmap :: M.Map Char Integer
+unitmap = M.fromList units
+
+ysecs :: Integer
+ysecs = dsecs * 365
+
+dsecs :: Integer
+dsecs = hsecs * 24
+
+hsecs :: Integer
+hsecs = msecs * 60
+
+msecs :: Integer
+msecs = 60
+
+-- Durations cannot be negative.
+instance Arbitrary Duration where
+ arbitrary = Duration <$> nonNegative arbitrary
+
+prop_duration_roundtrips :: Duration -> Bool
+prop_duration_roundtrips d = parseDuration (fromDuration d) == Just d
diff --git a/Utility/INotify.hs b/Utility/INotify.hs
new file mode 100644
index 000000000..ffdad8be3
--- /dev/null
+++ b/Utility/INotify.hs
@@ -0,0 +1,185 @@
+{- higher-level inotify interface
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Utility.INotify where
+
+import Common hiding (isDirectory)
+import Utility.ThreadLock
+import Utility.DirWatcher.Types
+
+import System.INotify
+import qualified System.Posix.Files as Files
+import System.IO.Error
+import Control.Exception (throw)
+
+{- Watches for changes to files in a directory, and all its subdirectories
+ - that are not ignored, using inotify. This function returns after
+ - its initial scan is complete, leaving a thread running. Callbacks are
+ - made for different events.
+ -
+ - Inotify is weak at recursive directory watching; the whole directory
+ - tree must be scanned and watches set explicitly for each subdirectory.
+ -
+ - To notice newly created subdirectories, inotify is used, and
+ - watches are registered for those directories. There is a race there;
+ - things can be added to a directory before the watch gets registered.
+ -
+ - To close the inotify race, each time a new directory is found, it also
+ - recursively scans it, assuming all files in it were just added,
+ - and registering each subdirectory.
+ -
+ - Note: Due to the race amelioration, multiple add events may occur
+ - for the same file.
+ -
+ - Note: Moving a file will cause events deleting it from its old location
+ - and adding it to the new location.
+ -
+ - Note: It's assumed that when a file that was open for write is closed,
+ - it's finished being written to, and can be added.
+ -
+ - Note: inotify has a limit to the number of watches allowed,
+ - /proc/sys/fs/inotify/max_user_watches (default 8192).
+ - So this will fail if there are too many subdirectories. The
+ - errHook is called when this happens.
+ -}
+watchDir :: INotify -> FilePath -> (FilePath -> Bool) -> WatchHooks -> IO ()
+watchDir i dir ignored hooks
+ | ignored dir = noop
+ | otherwise = do
+ -- Use a lock to make sure events generated during initial
+ -- scan come before real inotify events.
+ lock <- newLock
+ let handler event = withLock lock (void $ go event)
+ flip catchNonAsync failedwatch $ do
+ void (addWatch i watchevents dir handler)
+ `catchIO` failedaddwatch
+ withLock lock $
+ mapM_ scan =<< filter (not . dirCruft) <$>
+ getDirectoryContents dir
+ where
+ recurse d = watchDir i d ignored hooks
+
+ -- Select only inotify events required by the enabled
+ -- hooks, but always include Create so new directories can
+ -- be scanned.
+ watchevents = Create : addevents ++ delevents ++ modifyevents
+ addevents
+ | hashook addHook || hashook addSymlinkHook = [MoveIn, CloseWrite]
+ | otherwise = []
+ delevents
+ | hashook delHook || hashook delDirHook = [MoveOut, Delete]
+ | otherwise = []
+ modifyevents
+ | hashook modifyHook = [Modify]
+ | otherwise = []
+
+ scan f = unless (ignored f) $ do
+ ms <- getstatus f
+ case ms of
+ Nothing -> return ()
+ Just s
+ | Files.isDirectory s ->
+ recurse $ indir f
+ | Files.isSymbolicLink s ->
+ runhook addSymlinkHook f ms
+ | Files.isRegularFile s ->
+ runhook addHook f ms
+ | otherwise ->
+ noop
+
+ go (Created { isDirectory = isd, filePath = f })
+ | isd = recurse $ indir f
+ | otherwise = do
+ ms <- getstatus f
+ case ms of
+ Just s
+ | Files.isSymbolicLink s ->
+ when (hashook addSymlinkHook) $
+ runhook addSymlinkHook f ms
+ | Files.isRegularFile s ->
+ when (hashook addHook) $
+ runhook addHook f ms
+ _ -> noop
+ -- Closing a file is assumed to mean it's done being written,
+ -- so a new add event is sent.
+ go (Closed { isDirectory = False, maybeFilePath = Just f }) =
+ checkfiletype Files.isRegularFile addHook f
+ -- When a file or directory is moved in, scan it to add new
+ -- stuff.
+ go (MovedIn { filePath = f }) = scan f
+ go (MovedOut { isDirectory = isd, filePath = f })
+ | isd = runhook delDirHook f Nothing
+ | otherwise = runhook delHook f Nothing
+ -- Verify that the deleted item really doesn't exist,
+ -- since there can be spurious deletion events for items
+ -- in a directory that has been moved out, but is still
+ -- being watched.
+ go (Deleted { isDirectory = isd, filePath = f })
+ | isd = guarded $ runhook delDirHook f Nothing
+ | otherwise = guarded $ runhook delHook f Nothing
+ where
+ guarded = unlessM (filetype (const True) f)
+ go (Modified { isDirectory = isd, maybeFilePath = Just f })
+ | isd = noop
+ | otherwise = runhook modifyHook f Nothing
+ go _ = noop
+
+ hashook h = isJust $ h hooks
+
+ runhook h f s
+ | ignored f = noop
+ | otherwise = maybe noop (\a -> a (indir f) s) (h hooks)
+
+ indir f = dir </> f
+
+ getstatus f = catchMaybeIO $ getSymbolicLinkStatus $ indir f
+ checkfiletype check h f = do
+ ms <- getstatus f
+ case ms of
+ Just s
+ | check s -> runhook h f ms
+ _ -> noop
+ filetype t f = catchBoolIO $ t <$> getSymbolicLinkStatus (indir f)
+
+ failedaddwatch e
+ -- Inotify fails when there are too many watches with a
+ -- disk full error.
+ | isFullError e =
+ case errHook hooks of
+ Nothing -> error $ "failed to add inotify watch on directory " ++ dir ++ " (" ++ show e ++ ")"
+ Just hook -> tooManyWatches hook dir
+ -- The directory could have been deleted.
+ | isDoesNotExistError e = return ()
+ | otherwise = throw e
+
+ failedwatch e = hPutStrLn stderr $ "failed to add watch on directory " ++ dir ++ " (" ++ show e ++ ")"
+
+tooManyWatches :: (String -> Maybe FileStatus -> IO ()) -> FilePath -> IO ()
+tooManyWatches hook dir = do
+ sysctlval <- querySysctl [Param maxwatches] :: IO (Maybe Integer)
+ hook (unlines $ basewarning : maybe withoutsysctl withsysctl sysctlval) Nothing
+ where
+ maxwatches = "fs.inotify.max_user_watches"
+ basewarning = "Too many directories to watch! (Not watching " ++ dir ++")"
+ withoutsysctl = ["Increase the value in /proc/sys/fs/inotify/max_user_watches"]
+ withsysctl n = let new = n * 10 in
+ [ "Increase the limit permanently by running:"
+ , " echo " ++ maxwatches ++ "=" ++ show new ++
+ " | sudo tee -a /etc/sysctl.conf; sudo sysctl -p"
+ , "Or temporarily by running:"
+ , " sudo sysctl -w " ++ maxwatches ++ "=" ++ show new
+ ]
+
+querySysctl :: Read a => [CommandParam] -> IO (Maybe a)
+querySysctl ps = getM go ["sysctl", "/sbin/sysctl", "/usr/sbin/sysctl"]
+ where
+ go p = do
+ v <- catchMaybeIO $ readProcess p (toCommand ps)
+ case v of
+ Nothing -> return Nothing
+ Just s -> return $ parsesysctl s
+ parsesysctl s = readish =<< lastMaybe (words s)
diff --git a/Utility/InodeCache.hs b/Utility/InodeCache.hs
new file mode 100644
index 000000000..46ca87bd9
--- /dev/null
+++ b/Utility/InodeCache.hs
@@ -0,0 +1,94 @@
+{- Caching a file's inode, size, and modification time to see when it's changed.
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Utility.InodeCache where
+
+import Common
+import System.PosixCompat.Types
+import Utility.QuickCheck
+
+data InodeCachePrim = InodeCachePrim FileID FileOffset EpochTime
+ deriving (Show, Eq, Ord)
+
+newtype InodeCache = InodeCache InodeCachePrim
+ deriving (Show)
+
+{- Inode caches can be compared in two different ways, either weakly
+ - or strongly. -}
+data InodeComparisonType = Weakly | Strongly
+ deriving (Eq, Ord)
+
+{- Strong comparison, including inodes. -}
+compareStrong :: InodeCache -> InodeCache -> Bool
+compareStrong (InodeCache x) (InodeCache y) = x == y
+
+{- Weak comparison of the inode caches, comparing the size and mtime,
+ - but not the actual inode. Useful when inodes have changed, perhaps
+ - due to some filesystems being remounted. -}
+compareWeak :: InodeCache -> InodeCache -> Bool
+compareWeak (InodeCache (InodeCachePrim _ size1 mtime1)) (InodeCache (InodeCachePrim _ size2 mtime2)) =
+ size1 == size2 && mtime1 == mtime2
+
+compareBy :: InodeComparisonType -> InodeCache -> InodeCache -> Bool
+compareBy Strongly = compareStrong
+compareBy Weakly = compareWeak
+
+{- For use in a Map; it's determined at creation time whether this
+ - uses strong or weak comparison for Eq. -}
+data InodeCacheKey = InodeCacheKey InodeComparisonType InodeCachePrim
+ deriving (Ord)
+
+instance Eq InodeCacheKey where
+ (InodeCacheKey ctx x) == (InodeCacheKey cty y) =
+ compareBy (maximum [ctx,cty]) (InodeCache x ) (InodeCache y)
+
+inodeCacheToKey :: InodeComparisonType -> InodeCache -> InodeCacheKey
+inodeCacheToKey ct (InodeCache prim) = InodeCacheKey ct prim
+
+inodeCacheToMtime :: InodeCache -> EpochTime
+inodeCacheToMtime (InodeCache (InodeCachePrim _ _ mtime)) = mtime
+
+showInodeCache :: InodeCache -> String
+showInodeCache (InodeCache (InodeCachePrim inode size mtime)) = unwords
+ [ show inode
+ , show size
+ , show mtime
+ ]
+
+readInodeCache :: String -> Maybe InodeCache
+readInodeCache s = case words s of
+ (inode:size:mtime:_) ->
+ let prim = InodeCachePrim
+ <$> readish inode
+ <*> readish size
+ <*> readish mtime
+ in InodeCache <$> prim
+ _ -> Nothing
+
+genInodeCache :: FilePath -> IO (Maybe InodeCache)
+genInodeCache f = catchDefaultIO Nothing $ toInodeCache <$> getFileStatus f
+
+toInodeCache :: FileStatus -> Maybe InodeCache
+toInodeCache s
+ | isRegularFile s = Just $ InodeCache $ InodeCachePrim
+ (fileID s)
+ (fileSize s)
+ (modificationTime s)
+ | otherwise = Nothing
+
+instance Arbitrary InodeCache where
+ arbitrary =
+ let prim = InodeCachePrim
+ <$> arbitrary
+ <*> arbitrary
+ <*> arbitrary
+ in InodeCache <$> prim
+
+prop_read_show_inodecache :: InodeCache -> Bool
+prop_read_show_inodecache c = case readInodeCache (showInodeCache c) of
+ Nothing -> False
+ Just c' -> compareStrong c c'
diff --git a/Utility/JSONStream.hs b/Utility/JSONStream.hs
new file mode 100644
index 000000000..f3e93c3da
--- /dev/null
+++ b/Utility/JSONStream.hs
@@ -0,0 +1,44 @@
+{- Streaming JSON output.
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Utility.JSONStream (
+ start,
+ add,
+ end
+) where
+
+import Text.JSON
+
+{- Text.JSON does not support building up a larger JSON document piece by
+ - piece as a stream. To support streaming, a hack. The JSObject is converted
+ - to a string with its final "}" is left off, allowing it to be added to
+ - later. -}
+start :: JSON a => [(String, a)] -> String
+start l
+ | last s == endchar = init s
+ | otherwise = bad s
+ where
+ s = encodeStrict $ toJSObject l
+
+add :: JSON a => [(String, a)] -> String
+add l
+ | head s == startchar = ',' : drop 1 s
+ | otherwise = bad s
+ where
+ s = start l
+
+end :: String
+end = [endchar, '\n']
+
+startchar :: Char
+startchar = '{'
+
+endchar :: Char
+endchar = '}'
+
+bad :: String -> a
+bad s = error $ "Text.JSON returned unexpected string: " ++ s
diff --git a/Utility/Kqueue.hs b/Utility/Kqueue.hs
new file mode 100644
index 000000000..eb5feab00
--- /dev/null
+++ b/Utility/Kqueue.hs
@@ -0,0 +1,267 @@
+{- BSD kqueue file modification notification interface
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE ForeignFunctionInterface #-}
+
+module Utility.Kqueue (
+ Kqueue,
+ initKqueue,
+ stopKqueue,
+ waitChange,
+ Change(..),
+ changedFile,
+ runHooks,
+) where
+
+import Common
+import Utility.DirWatcher.Types
+
+import System.Posix.Types
+import Foreign.C.Types
+import Foreign.C.Error
+import Foreign.Ptr
+import Foreign.Marshal
+import qualified Data.Map as M
+import qualified Data.Set as S
+import qualified System.Posix.Files as Files
+import Control.Concurrent
+
+data Change
+ = Deleted FilePath
+ | DeletedDir FilePath
+ | Added FilePath
+ deriving (Show)
+
+isAdd :: Change -> Bool
+isAdd (Added _) = True
+isAdd (Deleted _) = False
+isAdd (DeletedDir _) = False
+
+changedFile :: Change -> FilePath
+changedFile (Added f) = f
+changedFile (Deleted f) = f
+changedFile (DeletedDir f) = f
+
+data Kqueue = Kqueue
+ { kqueueFd :: Fd
+ , kqueueTop :: FilePath
+ , kqueueMap :: DirMap
+ , _kqueuePruner :: Pruner
+ }
+
+type Pruner = FilePath -> Bool
+
+type DirMap = M.Map Fd DirInfo
+
+{- Enough information to uniquely identify a file in a directory,
+ - but not too much. -}
+data DirEnt = DirEnt
+ { dirEnt :: FilePath -- relative to the parent directory
+ , _dirInode :: FileID -- included to notice file replacements
+ , isSubDir :: Bool
+ }
+ deriving (Eq, Ord, Show)
+
+{- A directory, and its last known contents. -}
+data DirInfo = DirInfo
+ { dirName :: FilePath
+ , dirCache :: S.Set DirEnt
+ }
+ deriving (Show)
+
+getDirInfo :: FilePath -> IO DirInfo
+getDirInfo dir = do
+ l <- filter (not . dirCruft) <$> getDirectoryContents dir
+ contents <- S.fromList . catMaybes <$> mapM getDirEnt l
+ return $ DirInfo dir contents
+ where
+ getDirEnt f = catchMaybeIO $ do
+ s <- getSymbolicLinkStatus (dir </> f)
+ return $ DirEnt f (fileID s) (isDirectory s)
+
+{- Difference between the dirCaches of two DirInfos. -}
+(//) :: DirInfo -> DirInfo -> [Change]
+oldc // newc = deleted ++ added
+ where
+ deleted = calc gendel oldc newc
+ added = calc genadd newc oldc
+ gendel x = (if isSubDir x then DeletedDir else Deleted) $
+ dirName oldc </> dirEnt x
+ genadd x = Added $ dirName newc </> dirEnt x
+ calc a x y = map a $ S.toList $
+ S.difference (dirCache x) (dirCache y)
+
+{- Builds a map of directories in a tree, possibly pruning some.
+ - Opens each directory in the tree, and records its current contents. -}
+scanRecursive :: FilePath -> Pruner -> IO DirMap
+scanRecursive topdir prune = M.fromList <$> walk [] [topdir]
+ where
+ walk c [] = return c
+ walk c (dir:rest)
+ | prune dir = walk c rest
+ | otherwise = do
+ minfo <- catchMaybeIO $ getDirInfo dir
+ case minfo of
+ Nothing -> walk c rest
+ Just info -> do
+ mfd <- catchMaybeIO $
+ openFd dir ReadOnly Nothing defaultFileFlags
+ case mfd of
+ Nothing -> walk c rest
+ Just fd -> do
+ let subdirs = map (dir </>) . map dirEnt $
+ S.toList $ dirCache info
+ walk ((fd, info):c) (subdirs ++ rest)
+
+{- Adds a list of subdirectories (and all their children), unless pruned to a
+ - directory map. Adding a subdirectory that's already in the map will
+ - cause its contents to be refreshed. -}
+addSubDirs :: DirMap -> Pruner -> [FilePath] -> IO DirMap
+addSubDirs dirmap prune dirs = do
+ newmap <- foldr M.union M.empty <$>
+ mapM (\d -> scanRecursive d prune) dirs
+ return $ M.union newmap dirmap -- prefer newmap
+
+{- Removes a subdirectory (and all its children) from a directory map. -}
+removeSubDir :: DirMap -> FilePath -> IO DirMap
+removeSubDir dirmap dir = do
+ mapM_ closeFd $ M.keys toremove
+ return rest
+ where
+ (toremove, rest) = M.partition (dirContains dir . dirName) dirmap
+
+findDirContents :: DirMap -> FilePath -> [FilePath]
+findDirContents dirmap dir = concatMap absolutecontents $ search
+ where
+ absolutecontents i = map (dirName i </>)
+ (map dirEnt $ S.toList $ dirCache i)
+ search = map snd $ M.toList $
+ M.filter (\i -> dirName i == dir) dirmap
+
+foreign import ccall safe "libkqueue.h init_kqueue" c_init_kqueue
+ :: IO Fd
+foreign import ccall safe "libkqueue.h addfds_kqueue" c_addfds_kqueue
+ :: Fd -> CInt -> Ptr Fd -> IO ()
+foreign import ccall safe "libkqueue.h waitchange_kqueue" c_waitchange_kqueue
+ :: Fd -> IO Fd
+
+{- Initializes a Kqueue to watch a directory, and all its subdirectories. -}
+initKqueue :: FilePath -> Pruner -> IO Kqueue
+initKqueue dir pruned = do
+ dirmap <- scanRecursive dir pruned
+ h <- c_init_kqueue
+ let kq = Kqueue h dir dirmap pruned
+ updateKqueue kq
+ return kq
+
+{- Updates a Kqueue, adding watches for its map. -}
+updateKqueue :: Kqueue -> IO ()
+updateKqueue (Kqueue h _ dirmap _) =
+ withArrayLen (M.keys dirmap) $ \fdcnt c_fds -> do
+ c_addfds_kqueue h (fromIntegral fdcnt) c_fds
+
+{- Stops a Kqueue. Note: Does not directly close the Fds in the dirmap,
+ - so it can be reused. -}
+stopKqueue :: Kqueue -> IO ()
+stopKqueue = closeFd . kqueueFd
+
+{- Waits for a change on a Kqueue.
+ - May update the Kqueue.
+ -}
+waitChange :: Kqueue -> IO (Kqueue, [Change])
+waitChange kq@(Kqueue h _ dirmap _) = do
+ changedfd <- c_waitchange_kqueue h
+ if changedfd == -1
+ then ifM ((==) eINTR <$> getErrno)
+ (yield >> waitChange kq, nochange)
+ else case M.lookup changedfd dirmap of
+ Nothing -> nochange
+ Just info -> handleChange kq changedfd info
+ where
+ nochange = return (kq, [])
+
+{- The kqueue interface does not tell what type of change took place in
+ - the directory; it could be an added file, a deleted file, a renamed
+ - file, a new subdirectory, or a deleted subdirectory, or a moved
+ - subdirectory.
+ -
+ - So to determine this, the contents of the directory are compared
+ - with its last cached contents. The Kqueue is updated to watch new
+ - directories as necessary.
+ -}
+handleChange :: Kqueue -> Fd -> DirInfo -> IO (Kqueue, [Change])
+handleChange kq@(Kqueue _ _ dirmap pruner) fd olddirinfo =
+ go =<< catchMaybeIO (getDirInfo $ dirName olddirinfo)
+ where
+ go (Just newdirinfo) = do
+ let changes = filter (not . pruner . changedFile) $
+ olddirinfo // newdirinfo
+ let (added, deleted) = partition isAdd changes
+
+ -- Scan newly added directories to add to the map.
+ -- (Newly added files will fail getDirInfo.)
+ newdirinfos <- catMaybes <$>
+ mapM (catchMaybeIO . getDirInfo . changedFile) added
+ newmap <- addSubDirs dirmap pruner $ map dirName newdirinfos
+
+ -- Remove deleted directories from the map.
+ newmap' <- foldM removeSubDir newmap (map changedFile deleted)
+
+ -- Update the cached dirinfo just looked up.
+ let newmap'' = M.insertWith' const fd newdirinfo newmap'
+
+ -- When new directories were added, need to update
+ -- the kqueue to watch them.
+ let kq' = kq { kqueueMap = newmap'' }
+ unless (null newdirinfos) $
+ updateKqueue kq'
+
+ return (kq', changes)
+ go Nothing = do
+ -- The directory has been moved or deleted, so
+ -- remove it from our map.
+ newmap <- removeSubDir dirmap (dirName olddirinfo)
+ return (kq { kqueueMap = newmap }, [])
+
+{- Processes changes on the Kqueue, calling the hooks as appropriate.
+ - Never returns. -}
+runHooks :: Kqueue -> WatchHooks -> IO ()
+runHooks kq hooks = do
+ -- First, synthetic add events for the whole directory tree contents,
+ -- to catch any files created beforehand.
+ recursiveadd (kqueueMap kq) (Added $ kqueueTop kq)
+ loop kq
+ where
+ loop q = do
+ (q', changes) <- waitChange q
+ forM_ changes $ dispatch (kqueueMap q')
+ loop q'
+
+ dispatch _ change@(Deleted _) =
+ callhook delHook Nothing change
+ dispatch _ change@(DeletedDir _) =
+ callhook delDirHook Nothing change
+ dispatch dirmap change@(Added _) =
+ withstatus change $ dispatchadd dirmap
+
+ dispatchadd dirmap change s
+ | Files.isSymbolicLink s = callhook addSymlinkHook (Just s) change
+ | Files.isDirectory s = recursiveadd dirmap change
+ | Files.isRegularFile s = callhook addHook (Just s) change
+ | otherwise = noop
+
+ recursiveadd dirmap change = do
+ let contents = findDirContents dirmap $ changedFile change
+ forM_ contents $ \f ->
+ withstatus (Added f) $ dispatchadd dirmap
+
+ callhook h s change = case h hooks of
+ Nothing -> noop
+ Just a -> a (changedFile change) s
+
+ withstatus change a = maybe noop (a change) =<<
+ (catchMaybeIO (getSymbolicLinkStatus (changedFile change)))
diff --git a/Utility/LogFile.hs b/Utility/LogFile.hs
new file mode 100644
index 000000000..090ac60d0
--- /dev/null
+++ b/Utility/LogFile.hs
@@ -0,0 +1,68 @@
+{- log files
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Utility.LogFile where
+
+import Common
+
+import System.Posix.Types
+
+openLog :: FilePath -> IO Fd
+#ifndef mingw32_HOST_OS
+openLog logfile = do
+ rotateLog logfile
+ openFd logfile WriteOnly (Just stdFileMode)
+ defaultFileFlags { append = True }
+#else
+openLog = error "openLog TODO"
+#endif
+
+rotateLog :: FilePath -> IO ()
+rotateLog logfile = go 0
+ where
+ go num
+ | num > maxLogs = return ()
+ | otherwise = whenM (doesFileExist currfile) $ do
+ go (num + 1)
+ renameFile currfile nextfile
+ where
+ currfile = filename num
+ nextfile = filename (num + 1)
+ filename n
+ | n == 0 = logfile
+ | otherwise = rotatedLog logfile n
+
+rotatedLog :: FilePath -> Int -> FilePath
+rotatedLog logfile n = logfile ++ "." ++ show n
+
+{- Lists most recent logs last. -}
+listLogs :: FilePath -> IO [FilePath]
+listLogs logfile = filterM doesFileExist $ reverse $
+ logfile : map (rotatedLog logfile) [1..maxLogs]
+
+maxLogs :: Int
+maxLogs = 9
+
+redirLog :: Fd -> IO ()
+#ifndef mingw32_HOST_OS
+redirLog logfd = do
+ mapM_ (redir logfd) [stdOutput, stdError]
+ closeFd logfd
+#else
+redirLog _ = error "redirLog TODO"
+#endif
+
+redir :: Fd -> Fd -> IO ()
+#ifndef mingw32_HOST_OS
+redir newh h = do
+ closeFd h
+ void $ dupTo newh h
+#else
+redir _ _ = error "redir TODO"
+#endif
diff --git a/Utility/Lsof.hs b/Utility/Lsof.hs
new file mode 100644
index 000000000..63009f723
--- /dev/null
+++ b/Utility/Lsof.hs
@@ -0,0 +1,120 @@
+{- lsof interface
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE BangPatterns, CPP #-}
+
+module Utility.Lsof where
+
+import Common
+import Build.SysConfig as SysConfig
+import Utility.Env
+
+import System.Posix.Types
+
+data LsofOpenMode = OpenReadWrite | OpenReadOnly | OpenWriteOnly | OpenUnknown
+ deriving (Show, Eq)
+
+type CmdLine = String
+
+data ProcessInfo = ProcessInfo ProcessID CmdLine
+ deriving (Show)
+
+{- lsof is not in PATH on all systems, so SysConfig may have the absolute
+ - path where the program was found. Make sure at runtime that lsof is
+ - available, and if it's not in PATH, adjust PATH to contain it. -}
+setup :: IO ()
+setup = do
+ let cmd = fromMaybe "lsof" SysConfig.lsof
+ when (isAbsolute cmd) $ do
+ path <- getSearchPath
+ let path' = takeDirectory cmd : path
+ void $ setEnv "PATH" (intercalate [searchPathSeparator] path') True
+
+{- Checks each of the files in a directory to find open files.
+ - Note that this will find hard links to files elsewhere that are open. -}
+queryDir :: FilePath -> IO [(FilePath, LsofOpenMode, ProcessInfo)]
+queryDir path = query ["+d", path]
+
+{- Runs lsof with some parameters.
+ -
+ - Ignores nonzero exit code; lsof returns that when no files are open.
+ -
+ - Note: If lsof is not available, this always returns [] !
+ -}
+query :: [String] -> IO [(FilePath, LsofOpenMode, ProcessInfo)]
+query opts =
+ withHandle StdoutHandle (createProcessChecked checkSuccessProcess) p $ \h -> do
+ fileEncoding h
+ parse <$> hGetContentsStrict h
+ where
+ p = proc "lsof" ("-F0can" : opts)
+
+type LsofParser = String -> [(FilePath, LsofOpenMode, ProcessInfo)]
+
+parse :: LsofParser
+#ifdef __ANDROID__
+parse = parseDefault
+#else
+parse = parseFormatted
+#endif
+
+{- Parsing null-delimited output like:
+ -
+ - pPID\0cCMDLINE\0
+ - aMODE\0nFILE\0
+ - aMODE\0nFILE\0
+ - pPID\0[...]
+ -
+ - Where each new process block is started by a pid, and a process can
+ - have multiple files open.
+ -}
+parseFormatted :: LsofParser
+parseFormatted s = bundle $ go [] $ lines s
+ where
+ bundle = concatMap (\(fs, p) -> map (\(f, m) -> (f, m, p)) fs)
+
+ go c [] = c
+ go c ((t:r):ls)
+ | t == 'p' =
+ let (fs, ls') = parsefiles [] ls
+ in go ((fs, parseprocess r):c) ls'
+ | otherwise = parsefail
+ go _ _ = parsefail
+
+ parseprocess l = case splitnull l of
+ [pid, 'c':cmdline, ""] ->
+ case readish pid of
+ (Just n) -> ProcessInfo n cmdline
+ Nothing -> parsefail
+ _ -> parsefail
+
+ parsefiles c [] = (c, [])
+ parsefiles c (l:ls) = case splitnull l of
+ ['a':mode, 'n':file, ""] ->
+ parsefiles ((file, parsemode mode):c) ls
+ (('p':_):_) -> (c, l:ls)
+ _ -> parsefail
+
+ parsemode ('r':_) = OpenReadOnly
+ parsemode ('w':_) = OpenWriteOnly
+ parsemode ('u':_) = OpenReadWrite
+ parsemode _ = OpenUnknown
+
+ splitnull = split "\0"
+
+ parsefail = error $ "failed to parse lsof output: " ++ show s
+
+{- Parses lsof's default output format. -}
+parseDefault :: LsofParser
+parseDefault = catMaybes . map parseline . drop 1 . lines
+ where
+ parseline l = case words l of
+ (command : spid : _user : _fd : _type : _device : _size : _node : rest) ->
+ case readish spid of
+ Nothing -> Nothing
+ Just pid -> Just (unwords rest, OpenUnknown, ProcessInfo pid command)
+ _ -> Nothing
diff --git a/Utility/Matcher.hs b/Utility/Matcher.hs
new file mode 100644
index 000000000..e0a51ff6a
--- /dev/null
+++ b/Utility/Matcher.hs
@@ -0,0 +1,169 @@
+{- A generic matcher.
+ -
+ - Can be used to check if a user-supplied condition,
+ - like "foo and ( bar or not baz )" matches. The condition must already
+ - be tokenized, and can contain arbitrary operations.
+ -
+ - If operations are not separated by and/or, they are defaulted to being
+ - anded together, so "foo bar baz" all must match.
+ -
+ - Is forgiving about misplaced closing parens, so "foo and (bar or baz"
+ - will be handled, as will "foo and ( bar or baz ) )"
+ -
+ - Copyright 2011-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE Rank2Types, KindSignatures #-}
+
+module Utility.Matcher (
+ Token(..),
+ Matcher,
+ token,
+ tokens,
+ generate,
+ match,
+ matchM,
+ matchMrun,
+ isEmpty,
+
+ prop_matcher_sane
+) where
+
+import Common
+
+{- A Token can be an Operation of an arbitrary type, or one of a few
+ - predefined peices of syntax. -}
+data Token op = Operation op | And | Or | Not | Open | Close
+ deriving (Show, Eq)
+
+data Matcher op = MAny
+ | MAnd (Matcher op) (Matcher op)
+ | MOr (Matcher op) (Matcher op)
+ | MNot (Matcher op)
+ | MOp op
+ deriving (Show, Eq)
+
+{- Converts a word of syntax into a token. Doesn't handle operations. -}
+token :: String -> Token op
+token "and" = And
+token "or" = Or
+token "not" = Not
+token "(" = Open
+token ")" = Close
+token t = error $ "unknown token " ++ t
+
+tokens :: [String]
+tokens = words "and or not ( )"
+
+{- Converts a list of Tokens into a Matcher. -}
+generate :: [Token op] -> Matcher op
+generate = simplify . process MAny . tokenGroups
+ where
+ process m [] = m
+ process m ts = uncurry process $ consume m ts
+
+ consume m ((One And):rest) = term (m `MAnd`) rest
+ consume m ((One Or):rest) = term (m `MOr`) rest
+ consume m ((One Not):rest) = term (\p -> m `MAnd` (MNot p)) rest
+ consume m ((One (Operation o)):rest) = (m `MAnd` MOp o, rest)
+ consume m (Group g:rest) = (process m g, rest)
+ consume m (_:rest) = consume m rest
+ consume m [] = (m, [])
+
+ term a l =
+ let (p, l') = consume MAny l
+ in (a p, l')
+
+ simplify (MAnd MAny x) = simplify x
+ simplify (MAnd x MAny) = simplify x
+ simplify (MAnd x y) = MAnd (simplify x) (simplify y)
+ simplify (MOr x y) = MOr (simplify x) (simplify y)
+ simplify (MNot x) = MNot (simplify x)
+ simplify x = x
+
+data TokenGroup op = One (Token op) | Group [TokenGroup op]
+ deriving (Show, Eq)
+
+tokenGroups :: [Token op] -> [TokenGroup op]
+tokenGroups [] = []
+tokenGroups (t:ts) = go t
+ where
+ go Open =
+ let (gr, rest) = findClose ts
+ in gr : tokenGroups rest
+ go Close = tokenGroups ts -- not picky about missing Close
+ go _ = One t : tokenGroups ts
+
+findClose :: [Token op] -> (TokenGroup op, [Token op])
+findClose l =
+ let (g, rest) = go [] l
+ in (Group (reverse g), rest)
+ where
+ go c [] = (c, []) -- not picky about extra Close
+ go c (t:ts) = handle t
+ where
+ handle Close = (c, ts)
+ handle Open =
+ let (c', ts') = go [] ts
+ in go (Group (reverse c') : c) ts'
+ handle _ = go (One t:c) ts
+
+{- Checks if a Matcher matches, using a supplied function to check
+ - the value of Operations. -}
+match :: (op -> v -> Bool) -> Matcher op -> v -> Bool
+match a m v = go m
+ where
+ go MAny = True
+ go (MAnd m1 m2) = go m1 && go m2
+ go (MOr m1 m2) = go m1 || go m2
+ go (MNot m1) = not $ go m1
+ go (MOp o) = a o v
+
+{- Runs a monadic Matcher, where Operations are actions in the monad. -}
+matchM :: Monad m => Matcher (v -> m Bool) -> v -> m Bool
+matchM m v = matchMrun m $ \o -> o v
+
+{- More generic running of a monadic Matcher, with full control over running
+ - of Operations. Mostly useful in order to match on more than one
+ - parameter. -}
+matchMrun :: forall o (m :: * -> *). Monad m => Matcher o -> (o -> m Bool) -> m Bool
+matchMrun m run = go m
+ where
+ go MAny = return True
+ go (MAnd m1 m2) = go m1 <&&> go m2
+ go (MOr m1 m2) = go m1 <||> go m2
+ go (MNot m1) = liftM not (go m1)
+ go (MOp o) = run o
+
+{- Checks if a matcher contains no limits. -}
+isEmpty :: Matcher a -> Bool
+isEmpty MAny = True
+isEmpty _ = False
+
+prop_matcher_sane :: Bool
+prop_matcher_sane = all (\m -> match dummy m ()) $ map generate
+ [ [Operation True]
+ , []
+ , [Operation False, Or, Operation True, Or, Operation False]
+ , [Operation True, Or, Operation True]
+ , [Operation True, And, Operation True]
+ , [Not, Open, Operation True, And, Operation False, Close]
+ , [Not, Open, Not, Open, Not, Operation False, Close, Close]
+ , [Not, Open, Not, Open, Not, Open, Not, Operation True, Close, Close]
+ , [Operation True, And, Not, Operation False]
+ , [Operation True, Not, Operation False]
+ , [Operation True, Not, Not, Not, Operation False]
+ , [Operation True, Not, Not, Not, Operation False, And, Operation True]
+ , [Operation True, Not, Not, Not, Operation False, Operation True]
+ , [Not, Open, Operation True, And, Operation False, Close,
+ And, Open,
+ Open, Operation True, And, Operation False, Close,
+ Or,
+ Open, Operation True, And, Open, Not, Operation False, Close, Close,
+ Close, And,
+ Open, Not, Operation False, Close]
+ ]
+ where
+ dummy b _ = b
diff --git a/Utility/Metered.hs b/Utility/Metered.hs
new file mode 100644
index 000000000..f33ad443a
--- /dev/null
+++ b/Utility/Metered.hs
@@ -0,0 +1,116 @@
+{- Metered IO
+ -
+ - Copyright 2012, 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE TypeSynonymInstances #-}
+
+module Utility.Metered where
+
+import Common
+
+import qualified Data.ByteString.Lazy as L
+import qualified Data.ByteString as S
+import System.IO.Unsafe
+import Foreign.Storable (Storable(sizeOf))
+import System.Posix.Types
+
+{- An action that can be run repeatedly, updating it on the bytes processed.
+ -
+ - Note that each call receives the total number of bytes processed, so
+ - far, *not* an incremental amount since the last call. -}
+type MeterUpdate = (BytesProcessed -> IO ())
+
+{- Total number of bytes processed so far. -}
+newtype BytesProcessed = BytesProcessed Integer
+ deriving (Eq, Ord)
+
+class AsBytesProcessed a where
+ toBytesProcessed :: a -> BytesProcessed
+ fromBytesProcessed :: BytesProcessed -> a
+
+instance AsBytesProcessed Integer where
+ toBytesProcessed i = BytesProcessed i
+ fromBytesProcessed (BytesProcessed i) = i
+
+instance AsBytesProcessed Int where
+ toBytesProcessed i = BytesProcessed $ toInteger i
+ fromBytesProcessed (BytesProcessed i) = fromInteger i
+
+instance AsBytesProcessed FileOffset where
+ toBytesProcessed sz = BytesProcessed $ toInteger sz
+ fromBytesProcessed (BytesProcessed sz) = fromInteger sz
+
+addBytesProcessed :: AsBytesProcessed v => BytesProcessed -> v -> BytesProcessed
+addBytesProcessed (BytesProcessed i) v =
+ let (BytesProcessed n) = toBytesProcessed v
+ in BytesProcessed $! i + n
+
+zeroBytesProcessed :: BytesProcessed
+zeroBytesProcessed = BytesProcessed 0
+
+{- Sends the content of a file to an action, updating the meter as it's
+ - consumed. -}
+withMeteredFile :: FilePath -> MeterUpdate -> (L.ByteString -> IO a) -> IO a
+withMeteredFile f meterupdate a = withBinaryFile f ReadMode $ \h ->
+ hGetContentsMetered h meterupdate >>= a
+
+{- Sends the content of a file to a Handle, updating the meter as it's
+ - written. -}
+streamMeteredFile :: FilePath -> MeterUpdate -> Handle -> IO ()
+streamMeteredFile f meterupdate h = withMeteredFile f meterupdate $ L.hPut h
+
+{- Writes a ByteString to a Handle, updating a meter as it's written. -}
+meteredWrite :: MeterUpdate -> Handle -> L.ByteString -> IO ()
+meteredWrite meterupdate h = go zeroBytesProcessed . L.toChunks
+ where
+ go _ [] = return ()
+ go sofar (c:cs) = do
+ S.hPut h c
+ let sofar' = addBytesProcessed sofar $ S.length c
+ meterupdate sofar'
+ go sofar' cs
+
+meteredWriteFile :: MeterUpdate -> FilePath -> L.ByteString -> IO ()
+meteredWriteFile meterupdate f b = withBinaryFile f WriteMode $ \h ->
+ meteredWrite meterupdate h b
+
+{- This is like L.hGetContents, but after each chunk is read, a meter
+ - is updated based on the size of the chunk.
+ -
+ - Note that the meter update is run in unsafeInterleaveIO, which means that
+ - it can be run at any time. It's even possible for updates to run out
+ - of order, as different parts of the ByteString are consumed.
+ -
+ - All the usual caveats about using unsafeInterleaveIO apply to the
+ - meter updates, so use caution.
+ -}
+hGetContentsMetered :: Handle -> MeterUpdate -> IO L.ByteString
+hGetContentsMetered h meterupdate = lazyRead zeroBytesProcessed
+ where
+ lazyRead sofar = unsafeInterleaveIO $ loop sofar
+
+ loop sofar = do
+ c <- S.hGetSome h defaultChunkSize
+ if S.null c
+ then do
+ hClose h
+ return $ L.empty
+ else do
+ let sofar' = addBytesProcessed sofar $
+ S.length c
+ meterupdate sofar'
+ {- unsafeInterleaveIO causes this to be
+ - deferred until the data is read from the
+ - ByteString. -}
+ cs <- lazyRead sofar'
+ return $ L.append (L.fromChunks [c]) cs
+
+{- Same default chunk size Lazy ByteStrings use. -}
+defaultChunkSize :: Int
+defaultChunkSize = 32 * k - chunkOverhead
+ where
+ k = 1024
+ chunkOverhead = 2 * sizeOf (undefined :: Int) -- GHC specific
diff --git a/Utility/Misc.hs b/Utility/Misc.hs
new file mode 100644
index 000000000..68199c828
--- /dev/null
+++ b/Utility/Misc.hs
@@ -0,0 +1,153 @@
+{- misc utility functions
+ -
+ - Copyright 2010-2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Utility.Misc where
+
+import System.IO
+import Control.Monad
+import Foreign
+import Data.Char
+import Data.List
+import Control.Applicative
+import System.Exit
+#ifndef mingw32_HOST_OS
+import System.Posix.Process (getAnyProcessStatus)
+import Utility.Exception
+#endif
+
+import Utility.FileSystemEncoding
+import Utility.Monad
+
+{- A version of hgetContents that is not lazy. Ensures file is
+ - all read before it gets closed. -}
+hGetContentsStrict :: Handle -> IO String
+hGetContentsStrict = hGetContents >=> \s -> length s `seq` return s
+
+{- A version of readFile that is not lazy. -}
+readFileStrict :: FilePath -> IO String
+readFileStrict = readFile >=> \s -> length s `seq` return s
+
+{- Reads a file strictly, and using the FileSystemEncofing, so it will
+ - never crash on a badly encoded file. -}
+readFileStrictAnyEncoding :: FilePath -> IO String
+readFileStrictAnyEncoding f = withFile f ReadMode $ \h -> do
+ fileEncoding h
+ hClose h `after` hGetContentsStrict h
+
+{- Like break, but the item matching the condition is not included
+ - in the second result list.
+ -
+ - separate (== ':') "foo:bar" = ("foo", "bar")
+ - separate (== ':') "foobar" = ("foobar", "")
+ -}
+separate :: (a -> Bool) -> [a] -> ([a], [a])
+separate c l = unbreak $ break c l
+ where
+ unbreak r@(a, b)
+ | null b = r
+ | otherwise = (a, tail b)
+
+{- Breaks out the first line. -}
+firstLine :: String -> String
+firstLine = takeWhile (/= '\n')
+
+{- Splits a list into segments that are delimited by items matching
+ - a predicate. (The delimiters are not included in the segments.)
+ - Segments may be empty. -}
+segment :: (a -> Bool) -> [a] -> [[a]]
+segment p l = map reverse $ go [] [] l
+ where
+ go c r [] = reverse $ c:r
+ go c r (i:is)
+ | p i = go [] (c:r) is
+ | otherwise = go (i:c) r is
+
+prop_segment_regressionTest :: Bool
+prop_segment_regressionTest = all id
+ -- Even an empty list is a segment.
+ [ segment (== "--") [] == [[]]
+ -- There are two segements in this list, even though the first is empty.
+ , segment (== "--") ["--", "foo", "bar"] == [[],["foo","bar"]]
+ ]
+
+{- Includes the delimiters as segments of their own. -}
+segmentDelim :: (a -> Bool) -> [a] -> [[a]]
+segmentDelim p l = map reverse $ go [] [] l
+ where
+ go c r [] = reverse $ c:r
+ go c r (i:is)
+ | p i = go [] ([i]:c:r) is
+ | otherwise = go (i:c) r is
+
+{- Replaces multiple values in a string.
+ -
+ - Takes care to skip over just-replaced values, so that they are not
+ - mangled. For example, massReplace [("foo", "new foo")] does not
+ - replace the "new foo" with "new new foo".
+ -}
+massReplace :: [(String, String)] -> String -> String
+massReplace vs = go [] vs
+ where
+
+ go acc _ [] = concat $ reverse acc
+ go acc [] (c:cs) = go ([c]:acc) vs cs
+ go acc ((val, replacement):rest) s
+ | val `isPrefixOf` s =
+ go (replacement:acc) vs (drop (length val) s)
+ | otherwise = go acc rest s
+
+{- Given two orderings, returns the second if the first is EQ and returns
+ - the first otherwise.
+ -
+ - Example use:
+ -
+ - compare lname1 lname2 `thenOrd` compare fname1 fname2
+ -}
+thenOrd :: Ordering -> Ordering -> Ordering
+thenOrd EQ x = x
+thenOrd x _ = x
+{-# INLINE thenOrd #-}
+
+{- Wrapper around hGetBufSome that returns a String.
+ -
+ - The null string is returned on eof, otherwise returns whatever
+ - data is currently available to read from the handle, or waits for
+ - data to be written to it if none is currently available.
+ -
+ - Note on encodings: The normal encoding of the Handle is ignored;
+ - each byte is converted to a Char. Not unicode clean!
+ -}
+hGetSomeString :: Handle -> Int -> IO String
+hGetSomeString h sz = do
+ fp <- mallocForeignPtrBytes sz
+ len <- withForeignPtr fp $ \buf -> hGetBufSome h buf sz
+ map (chr . fromIntegral) <$> withForeignPtr fp (peekbytes len)
+ where
+ peekbytes :: Int -> Ptr Word8 -> IO [Word8]
+ peekbytes len buf = mapM (peekElemOff buf) [0..pred len]
+
+{- Reaps any zombie git processes.
+ -
+ - Warning: Not thread safe. Anything that was expecting to wait
+ - on a process and get back an exit status is going to be confused
+ - if this reap gets there first. -}
+reapZombies :: IO ()
+#ifndef mingw32_HOST_OS
+reapZombies = do
+ -- throws an exception when there are no child processes
+ catchDefaultIO Nothing (getAnyProcessStatus False True)
+ >>= maybe (return ()) (const reapZombies)
+
+#else
+reapZombies = return ()
+#endif
+
+exitBool :: Bool -> IO a
+exitBool False = exitFailure
+exitBool True = exitSuccess
diff --git a/Utility/Monad.hs b/Utility/Monad.hs
new file mode 100644
index 000000000..1ba43c5f8
--- /dev/null
+++ b/Utility/Monad.hs
@@ -0,0 +1,69 @@
+{- monadic stuff
+ -
+ - Copyright 2010-2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Utility.Monad where
+
+import Data.Maybe
+import Control.Monad
+
+{- Return the first value from a list, if any, satisfying the given
+ - predicate -}
+firstM :: Monad m => (a -> m Bool) -> [a] -> m (Maybe a)
+firstM _ [] = return Nothing
+firstM p (x:xs) = ifM (p x) (return $ Just x , firstM p xs)
+
+{- Runs the action on values from the list until it succeeds, returning
+ - its result. -}
+getM :: Monad m => (a -> m (Maybe b)) -> [a] -> m (Maybe b)
+getM _ [] = return Nothing
+getM p (x:xs) = maybe (getM p xs) (return . Just) =<< p x
+
+{- Returns true if any value in the list satisfies the predicate,
+ - stopping once one is found. -}
+anyM :: Monad m => (a -> m Bool) -> [a] -> m Bool
+anyM p = liftM isJust . firstM p
+
+allM :: Monad m => (a -> m Bool) -> [a] -> m Bool
+allM _ [] = return True
+allM p (x:xs) = p x <&&> allM p xs
+
+{- Runs an action on values from a list until it succeeds. -}
+untilTrue :: Monad m => [a] -> (a -> m Bool) -> m Bool
+untilTrue = flip anyM
+
+{- if with a monadic conditional. -}
+ifM :: Monad m => m Bool -> (m a, m a) -> m a
+ifM cond (thenclause, elseclause) = do
+ c <- cond
+ if c then thenclause else elseclause
+
+{- short-circuiting monadic || -}
+(<||>) :: Monad m => m Bool -> m Bool -> m Bool
+ma <||> mb = ifM ma ( return True , mb )
+
+{- short-circuiting monadic && -}
+(<&&>) :: Monad m => m Bool -> m Bool -> m Bool
+ma <&&> mb = ifM ma ( mb , return False )
+
+{- Same fixity as && and || -}
+infixr 3 <&&>
+infixr 2 <||>
+
+{- Runs an action, passing its value to an observer before returning it. -}
+observe :: Monad m => (a -> m b) -> m a -> m a
+observe observer a = do
+ r <- a
+ _ <- observer r
+ return r
+
+{- b `after` a runs first a, then b, and returns the value of a -}
+after :: Monad m => m b -> m a -> m a
+after = observe . const
+
+{- do nothing -}
+noop :: Monad m => m ()
+noop = return ()
diff --git a/Utility/Mounts.hsc b/Utility/Mounts.hsc
new file mode 100644
index 000000000..b6defda43
--- /dev/null
+++ b/Utility/Mounts.hsc
@@ -0,0 +1,93 @@
+{- Interface to mtab (and fstab)
+ -
+ - Derived from hsshellscript, originally written by
+ - Volker Wysk <hsss@volker-wysk.de>
+ -
+ - Modified to support BSD, Mac OS X, and Android by
+ - Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU LGPL version 2.1 or higher.
+ -}
+
+{-# LANGUAGE ForeignFunctionInterface #-}
+
+module Utility.Mounts (
+ Mntent(..),
+ getMounts
+) where
+
+#ifndef __ANDROID__
+import Control.Monad
+import Foreign
+import Foreign.C
+#include "libmounts.h"
+#else
+import Utility.Exception
+import Data.Maybe
+import Control.Applicative
+#endif
+
+{- This is a stripped down mntent, containing only
+ - fields available everywhere. -}
+data Mntent = Mntent
+ { mnt_fsname :: String
+ , mnt_dir :: FilePath
+ , mnt_type :: String
+ } deriving (Read, Show, Eq, Ord)
+
+#ifndef __ANDROID__
+
+getMounts :: IO [Mntent]
+getMounts = do
+ h <- c_mounts_start
+ when (h == nullPtr) $
+ throwErrno "getMounts"
+ mntent <- getmntent h []
+ _ <- c_mounts_end h
+ return mntent
+
+ where
+ getmntent h c = do
+ ptr <- c_mounts_next h
+ if (ptr == nullPtr)
+ then return $ reverse c
+ else do
+ mnt_fsname_str <- #{peek struct mntent, mnt_fsname} ptr >>= peekCString
+ mnt_dir_str <- #{peek struct mntent, mnt_dir} ptr >>= peekCString
+ mnt_type_str <- #{peek struct mntent, mnt_type} ptr >>= peekCString
+ let ent = Mntent
+ { mnt_fsname = mnt_fsname_str
+ , mnt_dir = mnt_dir_str
+ , mnt_type = mnt_type_str
+ }
+ getmntent h (ent:c)
+
+{- Using unsafe imports because the C functions are belived to never block.
+ - Note that getmntinfo is called with MNT_NOWAIT to avoid possibly blocking;
+ - while getmntent only accesses a file in /etc (or /proc) that should not
+ - block. -}
+foreign import ccall unsafe "libmounts.h mounts_start" c_mounts_start
+ :: IO (Ptr ())
+foreign import ccall unsafe "libmounts.h mounts_next" c_mounts_next
+ :: Ptr () -> IO (Ptr ())
+foreign import ccall unsafe "libmounts.h mounts_end" c_mounts_end
+ :: Ptr () -> IO CInt
+
+#else
+
+{- Android does not support getmntent (well, it's a no-op stub in Bionic).
+ -
+ - But, the linux kernel's /proc/mounts is available to be parsed.
+ -}
+getMounts :: IO [Mntent]
+getMounts = catchDefaultIO [] $
+ mapMaybe (parse . words) . lines <$> readFile "/proc/mounts"
+ where
+ parse (device:mountpoint:fstype:_rest) = Just $ Mntent
+ { mnt_fsname = device
+ , mnt_dir = mountpoint
+ , mnt_type = fstype
+ }
+ parse _ = Nothing
+
+#endif
diff --git a/Utility/Network.hs b/Utility/Network.hs
new file mode 100644
index 000000000..62523c9e9
--- /dev/null
+++ b/Utility/Network.hs
@@ -0,0 +1,21 @@
+{- network functions
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Utility.Network where
+
+import Utility.Process
+import Utility.Exception
+
+import Control.Applicative
+
+{- Haskell lacks uname(2) bindings, except in the
+ - Bindings.Uname addon. Rather than depend on that,
+ - use uname -n when available. -}
+getHostname :: IO (Maybe String)
+getHostname = catchMaybeIO uname_node
+ where
+ uname_node = takeWhile (/= '\n') <$> readProcess "uname" ["-n"]
diff --git a/Utility/NotificationBroadcaster.hs b/Utility/NotificationBroadcaster.hs
new file mode 100644
index 000000000..b873df655
--- /dev/null
+++ b/Utility/NotificationBroadcaster.hs
@@ -0,0 +1,86 @@
+{- notification broadcaster
+ -
+ - This is used to allow clients to block until there is a new notification
+ - that some thing occurred. It does not communicate what the change is,
+ - it only provides blocking reads to wait on notifications.
+ -
+ - Multiple clients are supported. Each has a unique id.
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Utility.NotificationBroadcaster (
+ NotificationBroadcaster,
+ NotificationHandle,
+ NotificationId,
+ newNotificationBroadcaster,
+ newNotificationHandle,
+ notificationHandleToId,
+ notificationHandleFromId,
+ sendNotification,
+ waitNotification,
+) where
+
+import Common
+
+import Control.Concurrent.STM
+import Control.Concurrent.MSampleVar
+
+{- One MSampleVar per client. The TMVar is never empty, so never blocks. -}
+type NotificationBroadcaster = TMVar [MSampleVar ()]
+
+newtype NotificationId = NotificationId Int
+ deriving (Read, Show, Eq, Ord)
+
+{- Handle given out to an individual client. -}
+data NotificationHandle = NotificationHandle NotificationBroadcaster NotificationId
+
+newNotificationBroadcaster :: IO NotificationBroadcaster
+newNotificationBroadcaster = atomically $ newTMVar []
+
+{- Allocates a notification handle for a client to use.
+ -
+ - An immediate notification can be forced the first time waitNotification
+ - is called on the handle. This is useful in cases where a notification
+ - may be sent while the new handle is being constructed. Normally,
+ - such a notification would be missed. Forcing causes extra work,
+ - but ensures such notifications get seen.
+ -}
+newNotificationHandle :: Bool -> NotificationBroadcaster -> IO NotificationHandle
+newNotificationHandle force b = NotificationHandle
+ <$> pure b
+ <*> addclient
+ where
+ addclient = do
+ s <- if force
+ then newSV ()
+ else newEmptySV
+ atomically $ do
+ l <- takeTMVar b
+ putTMVar b $ l ++ [s]
+ return $ NotificationId $ length l
+
+{- Extracts the identifier from a notification handle.
+ - This can be used to eg, pass the identifier through to a WebApp. -}
+notificationHandleToId :: NotificationHandle -> NotificationId
+notificationHandleToId (NotificationHandle _ i) = i
+
+notificationHandleFromId :: NotificationBroadcaster -> NotificationId -> NotificationHandle
+notificationHandleFromId = NotificationHandle
+
+{- Sends a notification to all clients. -}
+sendNotification :: NotificationBroadcaster -> IO ()
+sendNotification b = do
+ l <- atomically $ readTMVar b
+ mapM_ notify l
+ where
+ notify s = writeSV s ()
+
+{- Used by a client to block until a new notification is available since
+ - the last time it tried. -}
+waitNotification :: NotificationHandle -> IO ()
+waitNotification (NotificationHandle b (NotificationId i)) = do
+ l <- atomically $ readTMVar b
+ readSV (l !! i)
diff --git a/Utility/OSX.hs b/Utility/OSX.hs
new file mode 100644
index 000000000..f9d992575
--- /dev/null
+++ b/Utility/OSX.hs
@@ -0,0 +1,44 @@
+{- OSX stuff
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Utility.OSX where
+
+import Utility.UserInfo
+
+import System.FilePath
+
+autoStartBase :: String -> FilePath
+autoStartBase label = "Library" </> "LaunchAgents" </> label ++ ".plist"
+
+systemAutoStart :: String -> FilePath
+systemAutoStart label = "/" </> autoStartBase label
+
+userAutoStart :: String -> IO FilePath
+userAutoStart label = do
+ home <- myHomeDir
+ return $ home </> autoStartBase label
+
+{- Generates an OSX autostart plist file with a given label, command, and
+ - params to run at boot or login. -}
+genOSXAutoStartFile :: String -> String -> [String] -> String
+genOSXAutoStartFile label command params = unlines
+ [ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ , "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"
+ , "<plist version=\"1.0\">"
+ , "<dict>"
+ , "<key>Label</key>"
+ , "<string>" ++ label ++ "</string>"
+ , "<key>ProgramArguments</key>"
+ , "<array>"
+ , unlines $ map (\v -> "<string>" ++ v ++ "</string>") (command:params)
+ , "</array>"
+ , "<key>RunAtLoad</key>"
+ , "<true/>"
+ , "</dict>"
+ , "</plist>"
+ ]
+
diff --git a/Utility/Parallel.hs b/Utility/Parallel.hs
new file mode 100644
index 000000000..b39880355
--- /dev/null
+++ b/Utility/Parallel.hs
@@ -0,0 +1,35 @@
+{- parallel processing via threads
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Utility.Parallel where
+
+import Common
+
+import Control.Concurrent
+import Control.Exception
+
+{- Runs an action in parallel with a set of values, in a set of threads.
+ - In order for the actions to truely run in parallel, requires GHC's
+ - threaded runtime,
+ -
+ - Returns the values partitioned into ones with which the action succeeded,
+ - and ones with which it failed. -}
+inParallel :: (v -> IO Bool) -> [v] -> IO ([v], [v])
+inParallel a l = do
+ mvars <- mapM thread l
+ statuses <- mapM takeMVar mvars
+ return $ reduce $ partition snd $ zip l statuses
+ where
+ reduce (x,y) = (map fst x, map fst y)
+ thread v = do
+ mvar <- newEmptyMVar
+ _ <- forkIO $ do
+ r <- try (a v) :: IO (Either SomeException Bool)
+ case r of
+ Left _ -> putMVar mvar False
+ Right b -> putMVar mvar b
+ return mvar
diff --git a/Utility/PartialPrelude.hs b/Utility/PartialPrelude.hs
new file mode 100644
index 000000000..6efa093fd
--- /dev/null
+++ b/Utility/PartialPrelude.hs
@@ -0,0 +1,68 @@
+{- Parts of the Prelude are partial functions, which are a common source of
+ - bugs.
+ -
+ - This exports functions that conflict with the prelude, which avoids
+ - them being accidentially used.
+ -}
+
+module Utility.PartialPrelude where
+
+import qualified Data.Maybe
+
+{- read should be avoided, as it throws an error
+ - Instead, use: readish -}
+read :: Read a => String -> a
+read = Prelude.read
+
+{- head is a partial function; head [] is an error
+ - Instead, use: take 1 or headMaybe -}
+head :: [a] -> a
+head = Prelude.head
+
+{- tail is also partial
+ - Instead, use: drop 1 -}
+tail :: [a] -> [a]
+tail = Prelude.tail
+
+{- init too
+ - Instead, use: beginning -}
+init :: [a] -> [a]
+init = Prelude.init
+
+{- last too
+ - Instead, use: end or lastMaybe -}
+last :: [a] -> a
+last = Prelude.last
+
+{- Attempts to read a value from a String.
+ -
+ - Ignores leading/trailing whitespace, and throws away any trailing
+ - text after the part that can be read.
+ -
+ - readMaybe is available in Text.Read in new versions of GHC,
+ - but that one requires the entire string to be consumed.
+ -}
+readish :: Read a => String -> Maybe a
+readish s = case reads s of
+ ((x,_):_) -> Just x
+ _ -> Nothing
+
+{- Like head but Nothing on empty list. -}
+headMaybe :: [a] -> Maybe a
+headMaybe = Data.Maybe.listToMaybe
+
+{- Like last but Nothing on empty list. -}
+lastMaybe :: [a] -> Maybe a
+lastMaybe [] = Nothing
+lastMaybe v = Just $ Prelude.last v
+
+{- All but the last element of a list.
+ - (Like init, but no error on an empty list.) -}
+beginning :: [a] -> [a]
+beginning [] = []
+beginning l = Prelude.init l
+
+{- Like last, but no error on an empty list. -}
+end :: [a] -> [a]
+end [] = []
+end l = [Prelude.last l]
diff --git a/Utility/Path.hs b/Utility/Path.hs
new file mode 100644
index 000000000..b6214b247
--- /dev/null
+++ b/Utility/Path.hs
@@ -0,0 +1,254 @@
+{- path manipulation
+ -
+ - Copyright 2010-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE PackageImports, CPP #-}
+
+module Utility.Path where
+
+import Data.String.Utils
+import System.FilePath
+import System.Directory
+import Data.List
+import Data.Maybe
+import Data.Char
+import Control.Applicative
+
+#ifdef mingw32_HOST_OS
+import Data.Char
+import qualified System.FilePath.Posix as Posix
+#else
+import qualified "MissingH" System.Path as MissingH
+import System.Posix.Files
+#endif
+
+import Utility.Monad
+import Utility.UserInfo
+
+{- Makes a path absolute if it's not already.
+ - The first parameter is a base directory (ie, the cwd) to use if the path
+ - is not already absolute.
+ -
+ - On Unix, collapses and normalizes ".." etc in the path. May return Nothing
+ - if the path cannot be normalized.
+ -
+ - MissingH's absNormPath does not work on Windows, so on Windows
+ - no normalization is done.
+ -}
+absNormPath :: FilePath -> FilePath -> Maybe FilePath
+#ifndef mingw32_HOST_OS
+absNormPath dir path = MissingH.absNormPath dir path
+#else
+absNormPath dir path = Just $ combine dir path
+#endif
+
+{- Returns the parent directory of a path.
+ -
+ - To allow this to be easily used in loops, which terminate upon reaching the
+ - top, the parent of / is "" -}
+parentDir :: FilePath -> FilePath
+parentDir dir
+ | null dirs = ""
+ | otherwise = joinDrive drive (join s $ init dirs)
+ where
+ -- on Unix, the drive will be "/" when the dir is absolute, otherwise ""
+ (drive, path) = splitDrive dir
+ dirs = filter (not . null) $ split s path
+ s = [pathSeparator]
+
+prop_parentDir_basics :: FilePath -> Bool
+prop_parentDir_basics dir
+ | null dir = True
+ | dir == "/" = parentDir dir == ""
+ | otherwise = p /= dir
+ where
+ p = parentDir dir
+
+{- Checks if the first FilePath is, or could be said to contain the second.
+ - For example, "foo/" contains "foo/bar". Also, "foo", "./foo", "foo/" etc
+ - are all equivilant.
+ -}
+dirContains :: FilePath -> FilePath -> Bool
+dirContains a b = a == b || a' == b' || (a'++[pathSeparator]) `isPrefixOf` b'
+ where
+ norm p = fromMaybe "" $ absNormPath p "."
+ a' = norm a
+ b' = norm b
+
+{- Converts a filename into a normalized, absolute path.
+ -
+ - Unlike Directory.canonicalizePath, this does not require the path
+ - already exists. -}
+absPath :: FilePath -> IO FilePath
+absPath file = do
+ cwd <- getCurrentDirectory
+ return $ absPathFrom cwd file
+
+{- Converts a filename into a normalized, absolute path
+ - from the specified cwd. -}
+absPathFrom :: FilePath -> FilePath -> FilePath
+absPathFrom cwd file = fromMaybe bad $ absNormPath cwd file
+ where
+ bad = error $ "unable to normalize " ++ file
+
+{- Constructs a relative path from the CWD to a file.
+ -
+ - For example, assuming CWD is /tmp/foo/bar:
+ - relPathCwdToFile "/tmp/foo" == ".."
+ - relPathCwdToFile "/tmp/foo/bar" == ""
+ -}
+relPathCwdToFile :: FilePath -> IO FilePath
+relPathCwdToFile f = relPathDirToFile <$> getCurrentDirectory <*> absPath f
+
+{- Constructs a relative path from a directory to a file.
+ -
+ - Both must be absolute, and normalized (eg with absNormpath).
+ -}
+relPathDirToFile :: FilePath -> FilePath -> FilePath
+relPathDirToFile from to = join s $ dotdots ++ uncommon
+ where
+ s = [pathSeparator]
+ pfrom = split s from
+ pto = split s to
+ common = map fst $ takeWhile same $ zip pfrom pto
+ same (c,d) = c == d
+ uncommon = drop numcommon pto
+ dotdots = replicate (length pfrom - numcommon) ".."
+ numcommon = length common
+
+prop_relPathDirToFile_basics :: FilePath -> FilePath -> Bool
+prop_relPathDirToFile_basics from to
+ | from == to = null r
+ | otherwise = not (null r)
+ where
+ r = relPathDirToFile from to
+
+prop_relPathDirToFile_regressionTest :: Bool
+prop_relPathDirToFile_regressionTest = same_dir_shortcurcuits_at_difference
+ where
+ {- Two paths have the same directory component at the same
+ - location, but it's not really the same directory.
+ - Code used to get this wrong. -}
+ same_dir_shortcurcuits_at_difference =
+ relPathDirToFile (joinPath [pathSeparator : "tmp", "r", "lll", "xxx", "yyy", "18"])
+ (joinPath [pathSeparator : "tmp", "r", ".git", "annex", "objects", "18", "gk", "SHA256-foo", "SHA256-foo"])
+ == joinPath ["..", "..", "..", "..", ".git", "annex", "objects", "18", "gk", "SHA256-foo", "SHA256-foo"]
+
+{- Given an original list of paths, and an expanded list derived from it,
+ - generates a list of lists, where each sublist corresponds to one of the
+ - original paths. When the original path is a directory, any items
+ - in the expanded list that are contained in that directory will appear in
+ - its segment.
+ -}
+segmentPaths :: [FilePath] -> [FilePath] -> [[FilePath]]
+segmentPaths [] new = [new]
+segmentPaths [_] new = [new] -- optimisation
+segmentPaths (l:ls) new = [found] ++ segmentPaths ls rest
+ where
+ (found, rest)=partition (l `dirContains`) new
+
+{- This assumes that it's cheaper to call segmentPaths on the result,
+ - than it would be to run the action separately with each path. In
+ - the case of git file list commands, that assumption tends to hold.
+ -}
+runSegmentPaths :: ([FilePath] -> IO [FilePath]) -> [FilePath] -> IO [[FilePath]]
+runSegmentPaths a paths = segmentPaths paths <$> a paths
+
+{- Converts paths in the home directory to use ~/ -}
+relHome :: FilePath -> IO String
+relHome path = do
+ home <- myHomeDir
+ return $ if dirContains home path
+ then "~/" ++ relPathDirToFile home path
+ else path
+
+{- Checks if a command is available in PATH.
+ -
+ - The command may be fully-qualified, in which case, this succeeds as
+ - long as it exists. -}
+inPath :: String -> IO Bool
+inPath command = isJust <$> searchPath command
+
+{- Finds a command in PATH and returns the full path to it.
+ -
+ - The command may be fully qualified already, in which case it will
+ - be returned if it exists.
+ -}
+searchPath :: String -> IO (Maybe FilePath)
+searchPath command
+ | isAbsolute command = check command
+ | otherwise = getSearchPath >>= getM indir
+ where
+ indir d = check $ d </> command
+ check f = firstM doesFileExist
+#ifdef mingw32_HOST_OS
+ [f, f ++ ".exe"]
+#else
+ [f]
+#endif
+
+{- Checks if a filename is a unix dotfile. All files inside dotdirs
+ - count as dotfiles. -}
+dotfile :: FilePath -> Bool
+dotfile file
+ | f == "." = False
+ | f == ".." = False
+ | f == "" = False
+ | otherwise = "." `isPrefixOf` f || dotfile (takeDirectory file)
+ where
+ f = takeFileName file
+
+{- Converts a DOS style path to a Cygwin style path. Only on Windows.
+ - Any trailing '\' is preserved as a trailing '/' -}
+toCygPath :: FilePath -> FilePath
+#ifndef mingw32_HOST_OS
+toCygPath = id
+#else
+toCygPath p
+ | null drive = recombine parts
+ | otherwise = recombine $ "/cygdrive" : driveletter drive : parts
+ where
+ (drive, p') = splitDrive p
+ parts = splitDirectories p'
+ driveletter = map toLower . takeWhile (/= ':')
+ recombine = fixtrailing . Posix.joinPath
+ fixtrailing s
+ | hasTrailingPathSeparator p = Posix.addTrailingPathSeparator s
+ | otherwise = s
+#endif
+
+{- Maximum size to use for a file in a specified directory.
+ -
+ - Many systems have a 255 byte limit to the name of a file,
+ - so that's taken as the max if the system has a larger limit, or has no
+ - limit.
+ -}
+fileNameLengthLimit :: FilePath -> IO Int
+#ifdef mingw32_HOST_OS
+fileNameLengthLimit _ = return 255
+#else
+fileNameLengthLimit dir = do
+ l <- fromIntegral <$> getPathVar dir FileNameLimit
+ if l <= 0
+ then return 255
+ else return $ minimum [l, 255]
+ where
+#endif
+
+{- Given a string that we'd like to use as the basis for FilePath, but that
+ - was provided by a third party and is not to be trusted, returns the closest
+ - sane FilePath.
+ -
+ - All spaces and punctuation are replaced with '_', except for '.'
+ - "../" will thus turn into ".._", which is safe.
+ -}
+sanitizeFilePath :: String -> FilePath
+sanitizeFilePath = map sanitize
+ where
+ sanitize c
+ | c == '.' = c
+ | isSpace c || isPunctuation c || c == '/' = '_'
+ | otherwise = c
diff --git a/Utility/Percentage.hs b/Utility/Percentage.hs
new file mode 100644
index 000000000..d4b2da429
--- /dev/null
+++ b/Utility/Percentage.hs
@@ -0,0 +1,33 @@
+{- percentages
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Utility.Percentage (
+ Percentage,
+ percentage,
+ showPercentage
+) where
+
+import Data.Ratio
+
+import Utility.HumanNumber
+
+newtype Percentage = Percentage (Ratio Integer)
+
+instance Show Percentage where
+ show = showPercentage 0
+
+{- Normally the big number comes first. But 110% is allowed if desired. :) -}
+percentage :: Integer -> Integer -> Percentage
+percentage 0 _ = Percentage 0
+percentage full have = Percentage $ have * 100 % full
+
+{- Pretty-print a Percentage, with a specified level of precision. -}
+showPercentage :: Int -> Percentage -> String
+showPercentage precision (Percentage p) = v ++ "%"
+ where
+ v = showImprecise precision n
+ n = fromRational p :: Double
diff --git a/Utility/Process.hs b/Utility/Process.hs
new file mode 100644
index 000000000..398e8a352
--- /dev/null
+++ b/Utility/Process.hs
@@ -0,0 +1,356 @@
+{- System.Process enhancements, including additional ways of running
+ - processes, and logging.
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP, Rank2Types #-}
+
+module Utility.Process (
+ module X,
+ CreateProcess,
+ StdHandle(..),
+ readProcess,
+ readProcessEnv,
+ writeReadProcessEnv,
+ forceSuccessProcess,
+ checkSuccessProcess,
+ ignoreFailureProcess,
+ createProcessSuccess,
+ createProcessChecked,
+ createBackgroundProcess,
+ processTranscript,
+ withHandle,
+ withBothHandles,
+ withQuietOutput,
+ withNullHandle,
+ createProcess,
+ startInteractiveProcess,
+ stdinHandle,
+ stdoutHandle,
+ stderrHandle,
+) where
+
+import qualified System.Process
+import System.Process as X hiding (CreateProcess(..), createProcess, runInteractiveProcess, readProcess, readProcessWithExitCode, system, rawSystem, runInteractiveCommand, runProcess)
+import System.Process hiding (createProcess, readProcess)
+import System.Exit
+import System.IO
+import System.Log.Logger
+import Control.Concurrent
+import qualified Control.Exception as E
+import Control.Monad
+#ifndef mingw32_HOST_OS
+import System.Posix.IO
+#else
+import Control.Applicative
+#endif
+import Data.Maybe
+
+import Utility.Misc
+import Utility.Exception
+
+type CreateProcessRunner = forall a. CreateProcess -> ((Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle) -> IO a) -> IO a
+
+data StdHandle = StdinHandle | StdoutHandle | StderrHandle
+ deriving (Eq)
+
+{- Normally, when reading from a process, it does not need to be fed any
+ - standard input. -}
+readProcess :: FilePath -> [String] -> IO String
+readProcess cmd args = readProcessEnv cmd args Nothing
+
+readProcessEnv :: FilePath -> [String] -> Maybe [(String, String)] -> IO String
+readProcessEnv cmd args environ =
+ withHandle StdoutHandle createProcessSuccess p $ \h -> do
+ output <- hGetContentsStrict h
+ hClose h
+ return output
+ where
+ p = (proc cmd args)
+ { std_out = CreatePipe
+ , env = environ
+ }
+
+{- Runs an action to write to a process on its stdin,
+ - returns its output, and also allows specifying the environment.
+ -}
+writeReadProcessEnv
+ :: FilePath
+ -> [String]
+ -> Maybe [(String, String)]
+ -> (Maybe (Handle -> IO ()))
+ -> (Maybe (Handle -> IO ()))
+ -> IO String
+writeReadProcessEnv cmd args environ writestdin adjusthandle = do
+ (Just inh, Just outh, _, pid) <- createProcess p
+
+ maybe (return ()) (\a -> a inh) adjusthandle
+ maybe (return ()) (\a -> a outh) adjusthandle
+
+ -- fork off a thread to start consuming the output
+ output <- hGetContents outh
+ outMVar <- newEmptyMVar
+ _ <- forkIO $ E.evaluate (length output) >> putMVar outMVar ()
+
+ -- now write and flush any input
+ maybe (return ()) (\a -> a inh >> hFlush inh) writestdin
+ hClose inh -- done with stdin
+
+ -- wait on the output
+ takeMVar outMVar
+ hClose outh
+
+ -- wait on the process
+ forceSuccessProcess p pid
+
+ return output
+
+ where
+ p = (proc cmd args)
+ { std_in = CreatePipe
+ , std_out = CreatePipe
+ , std_err = Inherit
+ , env = environ
+ }
+
+{- Waits for a ProcessHandle, and throws an IOError if the process
+ - did not exit successfully. -}
+forceSuccessProcess :: CreateProcess -> ProcessHandle -> IO ()
+forceSuccessProcess p pid = do
+ code <- waitForProcess pid
+ case code of
+ ExitSuccess -> return ()
+ ExitFailure n -> fail $ showCmd p ++ " exited " ++ show n
+
+{- Waits for a ProcessHandle and returns True if it exited successfully.
+ - Note that using this with createProcessChecked will throw away
+ - the Bool, and is only useful to ignore the exit code of a process,
+ - while still waiting for it. -}
+checkSuccessProcess :: ProcessHandle -> IO Bool
+checkSuccessProcess pid = do
+ code <- waitForProcess pid
+ return $ code == ExitSuccess
+
+ignoreFailureProcess :: ProcessHandle -> IO Bool
+ignoreFailureProcess pid = do
+ void $ waitForProcess pid
+ return True
+
+{- Runs createProcess, then an action on its handles, and then
+ - forceSuccessProcess. -}
+createProcessSuccess :: CreateProcessRunner
+createProcessSuccess p a = createProcessChecked (forceSuccessProcess p) p a
+
+{- Runs createProcess, then an action on its handles, and then
+ - a checker action on its exit code, which must wait for the process. -}
+createProcessChecked :: (ProcessHandle -> IO b) -> CreateProcessRunner
+createProcessChecked checker p a = do
+ t@(_, _, _, pid) <- createProcess p
+ r <- tryNonAsync $ a t
+ _ <- checker pid
+ either E.throw return r
+
+{- Leaves the process running, suitable for lazy streaming.
+ - Note: Zombies will result, and must be waited on. -}
+createBackgroundProcess :: CreateProcessRunner
+createBackgroundProcess p a = a =<< createProcess p
+
+{- Runs a process, optionally feeding it some input, and
+ - returns a transcript combining its stdout and stderr, and
+ - whether it succeeded or failed. -}
+processTranscript :: String -> [String] -> (Maybe String) -> IO (String, Bool)
+#ifndef mingw32_HOST_OS
+{- This implementation interleves stdout and stderr in exactly the order
+ - the process writes them. -}
+processTranscript cmd opts input = do
+ (readf, writef) <- createPipe
+ readh <- fdToHandle readf
+ writeh <- fdToHandle writef
+ p@(_, _, _, pid) <- createProcess $
+ (proc cmd opts)
+ { std_in = if isJust input then CreatePipe else Inherit
+ , std_out = UseHandle writeh
+ , std_err = UseHandle writeh
+ }
+ hClose writeh
+
+ get <- mkreader readh
+
+ -- now write and flush any input
+ case input of
+ Just s -> do
+ let inh = stdinHandle p
+ unless (null s) $ do
+ hPutStr inh s
+ hFlush inh
+ hClose inh
+ Nothing -> return ()
+
+ transcript <- get
+
+ ok <- checkSuccessProcess pid
+ return (transcript, ok)
+#else
+{- This implementation for Windows puts stderr after stdout. -}
+processTranscript cmd opts input = do
+ p@(_, _, _, pid) <- createProcess $
+ (proc cmd opts)
+ { std_in = if isJust input then CreatePipe else Inherit
+ , std_out = CreatePipe
+ , std_err = CreatePipe
+ }
+
+ getout <- mkreader (stdoutHandle p)
+ geterr <- mkreader (stderrHandle p)
+
+ case input of
+ Just s -> do
+ let inh = stdinHandle p
+ unless (null s) $ do
+ hPutStr inh s
+ hFlush inh
+ hClose inh
+ Nothing -> return ()
+
+ transcript <- (++) <$> getout <*> geterr
+ ok <- checkSuccessProcess pid
+ return (transcript, ok)
+#endif
+ where
+ mkreader h = do
+ s <- hGetContents h
+ v <- newEmptyMVar
+ void $ forkIO $ do
+ void $ E.evaluate (length s)
+ putMVar v ()
+ return $ do
+ takeMVar v
+ return s
+
+{- Runs a CreateProcessRunner, on a CreateProcess structure, that
+ - is adjusted to pipe only from/to a single StdHandle, and passes
+ - the resulting Handle to an action. -}
+withHandle
+ :: StdHandle
+ -> CreateProcessRunner
+ -> CreateProcess
+ -> (Handle -> IO a)
+ -> IO a
+withHandle h creator p a = creator p' $ a . select
+ where
+ base = p
+ { std_in = Inherit
+ , std_out = Inherit
+ , std_err = Inherit
+ }
+ (select, p')
+ | h == StdinHandle =
+ (stdinHandle, base { std_in = CreatePipe })
+ | h == StdoutHandle =
+ (stdoutHandle, base { std_out = CreatePipe })
+ | h == StderrHandle =
+ (stderrHandle, base { std_err = CreatePipe })
+
+{- Like withHandle, but passes (stdin, stdout) handles to the action. -}
+withBothHandles
+ :: CreateProcessRunner
+ -> CreateProcess
+ -> ((Handle, Handle) -> IO a)
+ -> IO a
+withBothHandles creator p a = creator p' $ a . bothHandles
+ where
+ p' = p
+ { std_in = CreatePipe
+ , std_out = CreatePipe
+ , std_err = Inherit
+ }
+
+{- Forces the CreateProcessRunner to run quietly;
+ - both stdout and stderr are discarded. -}
+withQuietOutput
+ :: CreateProcessRunner
+ -> CreateProcess
+ -> IO ()
+withQuietOutput creator p = withNullHandle $ \nullh -> do
+ let p' = p
+ { std_out = UseHandle nullh
+ , std_err = UseHandle nullh
+ }
+ creator p' $ const $ return ()
+
+withNullHandle :: (Handle -> IO a) -> IO a
+withNullHandle = withFile devnull WriteMode
+ where
+#ifndef mingw32_HOST_OS
+ devnull = "/dev/null"
+#else
+ devnull = "NUL"
+#endif
+
+{- Extract a desired handle from createProcess's tuple.
+ - These partial functions are safe as long as createProcess is run
+ - with appropriate parameters to set up the desired handle.
+ - Get it wrong and the runtime crash will always happen, so should be
+ - easily noticed. -}
+type HandleExtractor = (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle) -> Handle
+stdinHandle :: HandleExtractor
+stdinHandle (Just h, _, _, _) = h
+stdinHandle _ = error "expected stdinHandle"
+stdoutHandle :: HandleExtractor
+stdoutHandle (_, Just h, _, _) = h
+stdoutHandle _ = error "expected stdoutHandle"
+stderrHandle :: HandleExtractor
+stderrHandle (_, _, Just h, _) = h
+stderrHandle _ = error "expected stderrHandle"
+bothHandles :: (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle) -> (Handle, Handle)
+bothHandles (Just hin, Just hout, _, _) = (hin, hout)
+bothHandles _ = error "expected bothHandles"
+
+{- Debugging trace for a CreateProcess. -}
+debugProcess :: CreateProcess -> IO ()
+debugProcess p = do
+ debugM "Utility.Process" $ unwords
+ [ action ++ ":"
+ , showCmd p
+ ]
+ where
+ action
+ | piped (std_in p) && piped (std_out p) = "chat"
+ | piped (std_in p) = "feed"
+ | piped (std_out p) = "read"
+ | otherwise = "call"
+ piped Inherit = False
+ piped _ = True
+
+{- Shows the command that a CreateProcess will run. -}
+showCmd :: CreateProcess -> String
+showCmd = go . cmdspec
+ where
+ go (ShellCommand s) = s
+ go (RawCommand c ps) = c ++ " " ++ show ps
+
+{- Starts an interactive process. Unlike runInteractiveProcess in
+ - System.Process, stderr is inherited. -}
+startInteractiveProcess
+ :: FilePath
+ -> [String]
+ -> Maybe [(String, String)]
+ -> IO (ProcessHandle, Handle, Handle)
+startInteractiveProcess cmd args environ = do
+ let p = (proc cmd args)
+ { std_in = CreatePipe
+ , std_out = CreatePipe
+ , std_err = Inherit
+ , env = environ
+ }
+ (Just from, Just to, _, pid) <- createProcess p
+ return (pid, to, from)
+
+{- Wrapper around System.Process function that does debug logging. -}
+createProcess :: CreateProcess -> IO (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
+createProcess p = do
+ debugProcess p
+ System.Process.createProcess p
diff --git a/Utility/QuickCheck.hs b/Utility/QuickCheck.hs
new file mode 100644
index 000000000..82af09f3d
--- /dev/null
+++ b/Utility/QuickCheck.hs
@@ -0,0 +1,48 @@
+{- QuickCheck with additional instances
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+{-# LANGUAGE TypeSynonymInstances #-}
+
+module Utility.QuickCheck
+ ( module X
+ , module Utility.QuickCheck
+ ) where
+
+import Test.QuickCheck as X
+import Data.Time.Clock.POSIX
+import System.Posix.Types
+import qualified Data.Map as M
+import Control.Applicative
+
+instance (Arbitrary k, Arbitrary v, Eq k, Ord k) => Arbitrary (M.Map k v) where
+ arbitrary = M.fromList <$> arbitrary
+
+{- Times before the epoch are excluded. -}
+instance Arbitrary POSIXTime where
+ arbitrary = nonNegative arbitrarySizedIntegral
+
+instance Arbitrary EpochTime where
+ arbitrary = nonNegative arbitrarySizedIntegral
+
+{- Pids are never negative, or 0. -}
+instance Arbitrary ProcessID where
+ arbitrary = arbitrarySizedBoundedIntegral `suchThat` (> 0)
+
+{- Inodes are never negative. -}
+instance Arbitrary FileID where
+ arbitrary = nonNegative arbitrarySizedIntegral
+
+{- File sizes are never negative. -}
+instance Arbitrary FileOffset where
+ arbitrary = nonNegative arbitrarySizedIntegral
+
+nonNegative :: (Num a, Ord a) => Gen a -> Gen a
+nonNegative g = g `suchThat` (>= 0)
+
+positive :: (Num a, Ord a) => Gen a -> Gen a
+positive g = g `suchThat` (> 0)
diff --git a/Utility/Quvi.hs b/Utility/Quvi.hs
new file mode 100644
index 000000000..4039167ac
--- /dev/null
+++ b/Utility/Quvi.hs
@@ -0,0 +1,133 @@
+{- querying quvi (import qualified)
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE OverloadedStrings #-}
+
+module Utility.Quvi where
+
+import Common
+import Utility.Url
+import Build.SysConfig (newquvi)
+
+import Data.Aeson
+import Data.ByteString.Lazy.UTF8 (fromString)
+import qualified Data.Map as M
+import Network.URI (uriAuthority, uriRegName)
+import Data.Char
+
+data Page = Page
+ { pageTitle :: String
+ , pageLinks :: [Link]
+ } deriving (Show)
+
+data Link = Link
+ { linkSuffix :: String
+ , linkUrl :: URLString
+ } deriving (Show)
+
+{- JSON instances for quvi 0.4. -}
+instance FromJSON Page where
+ parseJSON (Object v) = Page
+ <$> v .: "page_title"
+ <*> v .: "link"
+ parseJSON _ = mzero
+
+instance FromJSON Link where
+ parseJSON (Object v) = Link
+ <$> v .: "file_suffix"
+ <*> v .: "url"
+ parseJSON _ = mzero
+
+{- "enum" format used by quvi 0.9 -}
+parseEnum :: String -> Maybe Page
+parseEnum s = Page
+ <$> get "QUVI_MEDIA_PROPERTY_TITLE"
+ <*> ((:[]) <$>
+ ( Link
+ <$> get "QUVI_MEDIA_STREAM_PROPERTY_CONTAINER"
+ <*> get "QUVI_MEDIA_STREAM_PROPERTY_URL"
+ )
+ )
+ where
+ get = flip M.lookup m
+ m = M.fromList $ map (separate (== '=')) $ lines s
+
+type Query a = [CommandParam] -> URLString -> IO a
+
+{- Throws an error when quvi is not installed. -}
+forceQuery :: Query (Maybe Page)
+forceQuery ps url = query' ps url `catchNonAsync` onerr
+ where
+ onerr _ = ifM (inPath "quvi")
+ ( error "quvi failed"
+ , error "quvi is not installed"
+ )
+
+{- Returns Nothing if the page is not a video page, or quvi is not
+ - installed. -}
+query :: Query (Maybe Page)
+query ps url = flip catchNonAsync (const $ return Nothing) (query' ps url)
+
+query' :: Query (Maybe Page)
+query' ps url
+ | newquvi = parseEnum
+ <$> readProcess "quvi" (toCommand $ [Param "dump", Param "-p", Param "enum"] ++ ps ++ [Param url])
+ | otherwise = decode . fromString
+ <$> readProcess "quvi" (toCommand $ ps ++ [Param url])
+
+queryLinks :: Query [URLString]
+queryLinks ps url = maybe [] (map linkUrl . pageLinks) <$> query ps url
+
+{- Checks if quvi can still find a download link for an url.
+ - If quvi is not installed, returns False. -}
+check :: Query Bool
+check ps url = maybe False (not . null . pageLinks) <$> query ps url
+
+{- Checks if an url is supported by quvi, as quickly as possible
+ - (without hitting it if possible), and without outputting
+ - anything. Also returns False if quvi is not installed. -}
+supported :: URLString -> IO Bool
+supported url
+ {- Use quvi-info to see if the url's domain is supported.
+ - If so, have to do a online verification of the url. -}
+ | newquvi = (firstlevel <&&> secondlevel)
+ `catchNonAsync` (\_ -> return False)
+ | otherwise = boolSystem "quvi" [Params "--verbosity mute --support", Param url]
+ where
+ firstlevel = case uriAuthority =<< parseURIRelaxed url of
+ Nothing -> return False
+ Just auth -> do
+ let domain = map toLower $ uriRegName auth
+ let basedomain = intercalate "." $ reverse $ take 2 $ reverse $ split "." domain
+ any (\h -> domain `isSuffixOf` h || basedomain `isSuffixOf` h)
+ . map (map toLower) <$> listdomains
+ secondlevel = snd <$> processTranscript "quvi"
+ (toCommand [Param "dump", Param "-o", Param url]) Nothing
+
+listdomains :: IO [String]
+listdomains
+ | newquvi = concatMap (split ",")
+ . concatMap (drop 1 . words)
+ . filter ("domains: " `isPrefixOf`) . lines
+ <$> readProcess "quvi"
+ (toCommand [Param "info", Param "-p", Param "domains"])
+ | otherwise = return []
+
+{- Disables progress, but not information output. -}
+quiet :: CommandParam
+quiet
+ -- Cannot use quiet as it now disables informational output.
+ -- No way to disable progress.
+ | newquvi = Params "--verbosity verbose"
+ | otherwise = Params "--verbosity quiet"
+
+{- Only return http results, not streaming protocols. -}
+httponly :: CommandParam
+httponly
+ -- No way to do it with 0.9?
+ | newquvi = Params ""
+ | otherwise = Params "-c http"
diff --git a/Utility/Rsync.hs b/Utility/Rsync.hs
new file mode 100644
index 000000000..5f322a0cb
--- /dev/null
+++ b/Utility/Rsync.hs
@@ -0,0 +1,152 @@
+{- various rsync stuff
+ -
+ - Copyright 2010-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Utility.Rsync where
+
+import Common
+import Utility.Metered
+
+import Data.Char
+import System.Console.GetOpt
+import Data.Tuple.Utils
+
+{- Generates parameters to make rsync use a specified command as its remote
+ - shell. -}
+rsyncShell :: [CommandParam] -> [CommandParam]
+rsyncShell command = [Param "-e", Param $ unwords $ map escape (toCommand command)]
+ where
+ {- rsync requires some weird, non-shell like quoting in
+ - here. A doubled single quote inside the single quoted
+ - string is a single quote. -}
+ escape s = "'" ++ intercalate "''" (split "'" s) ++ "'"
+
+{- Runs rsync in server mode to send a file. -}
+rsyncServerSend :: [CommandParam] -> FilePath -> IO Bool
+rsyncServerSend options file = rsync $
+ rsyncServerParams ++ Param "--sender" : options ++ [File file]
+
+{- Runs rsync in server mode to receive a file. -}
+rsyncServerReceive :: [CommandParam] -> FilePath -> IO Bool
+rsyncServerReceive options file = rsync $
+ rsyncServerParams ++ options ++ [File file]
+
+rsyncServerParams :: [CommandParam]
+rsyncServerParams =
+ [ Param "--server"
+ -- preserve timestamps
+ , Param "-t"
+ -- allow resuming of transfers of big files
+ , Param "--inplace"
+ -- other options rsync normally uses in server mode
+ , Params "-e.Lsf ."
+ ]
+
+rsyncUseDestinationPermissions :: CommandParam
+rsyncUseDestinationPermissions = Param "--chmod=ugo=rwX"
+
+rsync :: [CommandParam] -> IO Bool
+rsync = boolSystem "rsync" . rsyncParamsFixup
+
+{- On Windows, rsync is from Cygwin, and expects to get Cygwin formatted
+ - paths to files. (It thinks that C:foo refers to a host named "C").
+ - Fix up all Files in the Params appropriately. -}
+rsyncParamsFixup :: [CommandParam] -> [CommandParam]
+rsyncParamsFixup = map fixup
+ where
+ fixup (File f) = File (toCygPath f)
+ fixup p = p
+
+{- Runs rsync, but intercepts its progress output and updates a meter.
+ - The progress output is also output to stdout.
+ -
+ - The params must enable rsync's --progress mode for this to work.
+ -}
+rsyncProgress :: MeterUpdate -> [CommandParam] -> IO Bool
+rsyncProgress meterupdate params = do
+ r <- withHandle StdoutHandle createProcessSuccess p (feedprogress 0 [])
+ {- For an unknown reason, piping rsync's output like this does
+ - causes it to run a second ssh process, which it neglects to wait
+ - on. Reap the resulting zombie. -}
+ reapZombies
+ return r
+ where
+ p = proc "rsync" (toCommand $ rsyncParamsFixup params)
+ feedprogress prev buf h = do
+ s <- hGetSomeString h 80
+ if null s
+ then return True
+ else do
+ putStr s
+ hFlush stdout
+ let (mbytes, buf') = parseRsyncProgress (buf++s)
+ case mbytes of
+ Nothing -> feedprogress prev buf' h
+ (Just bytes) -> do
+ when (bytes /= prev) $
+ meterupdate $ toBytesProcessed bytes
+ feedprogress bytes buf' h
+
+{- Checks if an rsync url involves the remote shell (ssh or rsh).
+ - Use of such urls with rsync requires additional shell
+ - escaping. -}
+rsyncUrlIsShell :: String -> Bool
+rsyncUrlIsShell s
+ | "rsync://" `isPrefixOf` s = False
+ | otherwise = go s
+ where
+ -- host::dir is rsync protocol, while host:dir is ssh/rsh
+ go [] = False
+ go (c:cs)
+ | c == '/' = False -- got to directory with no colon
+ | c == ':' = not $ ":" `isPrefixOf` cs
+ | otherwise = go cs
+
+{- Checks if a rsync url is really just a local path. -}
+rsyncUrlIsPath :: String -> Bool
+rsyncUrlIsPath s
+ | rsyncUrlIsShell s = False
+ | otherwise = ':' `notElem` s
+
+{- Parses the String looking for rsync progress output, and returns
+ - Maybe the number of bytes rsynced so far, and any any remainder of the
+ - string that could be an incomplete progress output. That remainder
+ - should be prepended to future output, and fed back in. This interface
+ - allows the output to be read in any desired size chunk, or even one
+ - character at a time.
+ -
+ - Strategy: Look for chunks prefixed with \r (rsync writes a \r before
+ - the first progress output, and each thereafter). The first number
+ - after the \r is the number of bytes processed. After the number,
+ - there must appear some whitespace, or we didn't get the whole number,
+ - and return the \r and part we did get, for later processing.
+ -}
+parseRsyncProgress :: String -> (Maybe Integer, String)
+parseRsyncProgress = go [] . reverse . progresschunks
+ where
+ go remainder [] = (Nothing, remainder)
+ go remainder (x:xs) = case parsebytes (findbytesstart x) of
+ Nothing -> go (delim:x++remainder) xs
+ Just b -> (Just b, remainder)
+
+ delim = '\r'
+ {- Find chunks that each start with delim.
+ - The first chunk doesn't start with it
+ - (it's empty when delim is at the start of the string). -}
+ progresschunks = drop 1 . split [delim]
+ findbytesstart s = dropWhile isSpace s
+ parsebytes s = case break isSpace s of
+ ([], _) -> Nothing
+ (_, []) -> Nothing
+ (b, _) -> readish b
+
+{- Filters options to those that are safe to pass to rsync in server mode,
+ - without causing it to eg, expose files. -}
+filterRsyncSafeOptions :: [String] -> [String]
+filterRsyncSafeOptions = fst3 . getOpt Permute
+ [ Option [] ["bwlimit"] (reqArgLong "bwlimit") "" ]
+ where
+ reqArgLong x = ReqArg (\v -> "--" ++ x ++ "=" ++ v) ""
diff --git a/Utility/SRV.hs b/Utility/SRV.hs
new file mode 100644
index 000000000..a2ee704f7
--- /dev/null
+++ b/Utility/SRV.hs
@@ -0,0 +1,112 @@
+{- SRV record lookup
+ -
+ - Uses either the ADNS Haskell library, or the standalone Haskell DNS
+ - package, or the host command.
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Utility.SRV (
+ mkSRVTcp,
+ mkSRV,
+ lookupSRV,
+ lookupSRVHost,
+ HostPort,
+) where
+
+import Utility.Process
+import Utility.Exception
+import Utility.PartialPrelude
+
+import Network
+import Data.Function
+import Data.List
+import Control.Applicative
+import Data.Maybe
+
+#ifdef WITH_ADNS
+import ADNS.Resolver
+import Data.Either
+#else
+#ifdef WITH_DNS
+import qualified Network.DNS.Lookup as DNS
+import Network.DNS.Resolver
+import qualified Data.ByteString.UTF8 as B8
+#endif
+#endif
+
+newtype SRV = SRV String
+ deriving (Show, Eq)
+
+type HostPort = (HostName, PortID)
+
+type PriorityWeight = (Int, Int) -- sort by priority first, then weight
+
+mkSRV :: String -> String -> HostName -> SRV
+mkSRV transport protocol host = SRV $ concat
+ ["_", protocol, "._", transport, ".", host]
+
+mkSRVTcp :: String -> HostName -> SRV
+mkSRVTcp = mkSRV "tcp"
+
+{- Returns an ordered list, with highest priority hosts first.
+ -
+ - On error, returns an empty list. -}
+lookupSRV :: SRV -> IO [HostPort]
+#ifdef WITH_ADNS
+lookupSRV (SRV srv) = initResolver [] $ \resolver -> do
+ r <- catchDefaultIO (Right []) $
+ resolveSRV resolver srv
+ return $ either (\_ -> []) id r
+#else
+#ifdef WITH_DNS
+lookupSRV (SRV srv) = do
+ seed <- makeResolvSeed defaultResolvConf
+ r <- withResolver seed $ flip DNS.lookupSRV $ B8.fromString srv
+ return $
+#if MIN_VERSION_dns(1,0,0)
+ either (const []) use r
+#else
+ maybe [] use r
+#endif
+ where
+ use = orderHosts . map tohosts
+ tohosts (priority, weight, port, hostname) =
+ ( (priority, weight)
+ , (B8.toString hostname, PortNumber $ fromIntegral port)
+ )
+#else
+lookupSRV = lookupSRVHost
+#endif
+#endif
+
+lookupSRVHost :: SRV -> IO [HostPort]
+lookupSRVHost (SRV srv) = catchDefaultIO [] $
+ parseSrvHost <$> readProcessEnv "host" ["-t", "SRV", "--", srv]
+ -- clear environment, to avoid LANG affecting output
+ (Just [])
+
+parseSrvHost :: String -> [HostPort]
+parseSrvHost = orderHosts . catMaybes . map parse . lines
+ where
+ parse l = case words l of
+ [_, _, _, _, spriority, sweight, sport, hostname] -> do
+ let v =
+ ( readish sport :: Maybe Int
+ , readish spriority :: Maybe Int
+ , readish sweight :: Maybe Int
+ )
+ case v of
+ (Just port, Just priority, Just weight) -> Just
+ ( (priority, weight)
+ , (hostname, PortNumber $ fromIntegral port)
+ )
+ _ -> Nothing
+ _ -> Nothing
+
+orderHosts :: [(PriorityWeight, HostPort)] -> [HostPort]
+orderHosts = map snd . sortBy (compare `on` fst)
diff --git a/Utility/SafeCommand.hs b/Utility/SafeCommand.hs
new file mode 100644
index 000000000..c8318ec2e
--- /dev/null
+++ b/Utility/SafeCommand.hs
@@ -0,0 +1,120 @@
+{- safely running shell commands
+ -
+ - Copyright 2010-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Utility.SafeCommand where
+
+import System.Exit
+import Utility.Process
+import System.Process (env)
+import Data.String.Utils
+import Control.Applicative
+import System.FilePath
+import Data.Char
+
+{- A type for parameters passed to a shell command. A command can
+ - be passed either some Params (multiple parameters can be included,
+ - whitespace-separated, or a single Param (for when parameters contain
+ - whitespace), or a File.
+ -}
+data CommandParam = Params String | Param String | File FilePath
+ deriving (Eq, Show, Ord)
+
+{- Used to pass a list of CommandParams to a function that runs
+ - a command and expects Strings. -}
+toCommand :: [CommandParam] -> [String]
+toCommand = concatMap unwrap
+ where
+ unwrap (Param s) = [s]
+ unwrap (Params s) = filter (not . null) (split " " s)
+ -- Files that start with a non-alphanumeric that is not a path
+ -- separator are modified to avoid the command interpreting them as
+ -- options or other special constructs.
+ unwrap (File s@(h:_))
+ | isAlphaNum h || h `elem` pathseps = [s]
+ | otherwise = ["./" ++ s]
+ unwrap (File s) = [s]
+ -- '/' is explicitly included because it's an alternative
+ -- path separator on Windows.
+ pathseps = pathSeparator:"./"
+
+{- Run a system command, and returns True or False
+ - if it succeeded or failed.
+ -}
+boolSystem :: FilePath -> [CommandParam] -> IO Bool
+boolSystem command params = boolSystemEnv command params Nothing
+
+boolSystemEnv :: FilePath -> [CommandParam] -> Maybe [(String, String)] -> IO Bool
+boolSystemEnv command params environ = dispatch <$> safeSystemEnv command params environ
+ where
+ dispatch ExitSuccess = True
+ dispatch _ = False
+
+{- Runs a system command, returning the exit status. -}
+safeSystem :: FilePath -> [CommandParam] -> IO ExitCode
+safeSystem command params = safeSystemEnv command params Nothing
+
+safeSystemEnv :: FilePath -> [CommandParam] -> Maybe [(String, String)] -> IO ExitCode
+safeSystemEnv command params environ = do
+ (_, _, _, pid) <- createProcess (proc command $ toCommand params)
+ { env = environ }
+ waitForProcess pid
+
+{- Wraps a shell command line inside sh -c, allowing it to be run in a
+ - login shell that may not support POSIX shell, eg csh. -}
+shellWrap :: String -> String
+shellWrap cmdline = "sh -c " ++ shellEscape cmdline
+
+{- Escapes a filename or other parameter to be safely able to be exposed to
+ - the shell.
+ -
+ - This method works for POSIX shells, as well as other shells like csh.
+ -}
+shellEscape :: String -> String
+shellEscape f = "'" ++ escaped ++ "'"
+ where
+ -- replace ' with '"'"'
+ escaped = join "'\"'\"'" $ split "'" f
+
+{- Unescapes a set of shellEscaped words or filenames. -}
+shellUnEscape :: String -> [String]
+shellUnEscape [] = []
+shellUnEscape s = word : shellUnEscape rest
+ where
+ (word, rest) = findword "" s
+ findword w [] = (w, "")
+ findword w (c:cs)
+ | c == ' ' = (w, cs)
+ | c == '\'' = inquote c w cs
+ | c == '"' = inquote c w cs
+ | otherwise = findword (w++[c]) cs
+ inquote _ w [] = (w, "")
+ inquote q w (c:cs)
+ | c == q = findword w cs
+ | otherwise = inquote q (w++[c]) cs
+
+{- For quickcheck. -}
+prop_idempotent_shellEscape :: String -> Bool
+prop_idempotent_shellEscape s = [s] == (shellUnEscape . shellEscape) s
+prop_idempotent_shellEscape_multiword :: [String] -> Bool
+prop_idempotent_shellEscape_multiword s = s == (shellUnEscape . unwords . map shellEscape) s
+
+{- Segements a list of filenames into groups that are all below the manximum
+ - command-line length limit. Does not preserve order. -}
+segmentXargs :: [FilePath] -> [[FilePath]]
+segmentXargs l = go l [] 0 []
+ where
+ go [] c _ r = c:r
+ go (f:fs) c accumlen r
+ | len < maxlen && newlen > maxlen = go (f:fs) [] 0 (c:r)
+ | otherwise = go fs (f:c) newlen r
+ where
+ len = length f
+ newlen = accumlen + len
+
+ {- 10k of filenames per command, well under Linux's 20k limit;
+ - allows room for other parameters etc. -}
+ maxlen = 10240
diff --git a/Utility/Scheduled.hs b/Utility/Scheduled.hs
new file mode 100644
index 000000000..acbee70ff
--- /dev/null
+++ b/Utility/Scheduled.hs
@@ -0,0 +1,350 @@
+{- scheduled activities
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Utility.Scheduled (
+ Schedule(..),
+ Recurrance(..),
+ ScheduledTime(..),
+ NextTime(..),
+ nextTime,
+ fromSchedule,
+ fromScheduledTime,
+ toScheduledTime,
+ fromRecurrance,
+ toRecurrance,
+ toSchedule,
+ parseSchedule,
+ prop_schedule_roundtrips
+) where
+
+import Common
+import Utility.QuickCheck
+
+import Data.Time.Clock
+import Data.Time.LocalTime
+import Data.Time.Calendar
+import Data.Time.Calendar.WeekDate
+import Data.Time.Calendar.OrdinalDate
+import Data.Tuple.Utils
+import Data.Char
+
+{- Some sort of scheduled event. -}
+data Schedule = Schedule Recurrance ScheduledTime
+ deriving (Eq, Read, Show, Ord)
+
+data Recurrance
+ = Daily
+ | Weekly (Maybe WeekDay)
+ | Monthly (Maybe MonthDay)
+ | Yearly (Maybe YearDay)
+ -- Days, Weeks, or Months of the year evenly divisible by a number.
+ -- (Divisible Year is years evenly divisible by a number.)
+ | Divisible Int Recurrance
+ deriving (Eq, Read, Show, Ord)
+
+type WeekDay = Int
+type MonthDay = Int
+type YearDay = Int
+
+data ScheduledTime
+ = AnyTime
+ | SpecificTime Hour Minute
+ deriving (Eq, Read, Show, Ord)
+
+type Hour = Int
+type Minute = Int
+
+{- Next time a Schedule should take effect. The NextTimeWindow is used
+ - when a Schedule is allowed to start at some point within the window. -}
+data NextTime
+ = NextTimeExactly LocalTime
+ | NextTimeWindow LocalTime LocalTime
+ deriving (Eq, Read, Show)
+
+startTime :: NextTime -> LocalTime
+startTime (NextTimeExactly t) = t
+startTime (NextTimeWindow t _) = t
+
+nextTime :: Schedule -> Maybe LocalTime -> IO (Maybe NextTime)
+nextTime schedule lasttime = do
+ now <- getCurrentTime
+ tz <- getTimeZone now
+ return $ calcNextTime schedule lasttime $ utcToLocalTime tz now
+
+{- Calculate the next time that fits a Schedule, based on the
+ - last time it occurred, and the current time. -}
+calcNextTime :: Schedule -> Maybe LocalTime -> LocalTime -> Maybe NextTime
+calcNextTime (Schedule recurrance scheduledtime) lasttime currenttime
+ | scheduledtime == AnyTime = do
+ next <- findfromtoday True
+ return $ case next of
+ NextTimeWindow _ _ -> next
+ NextTimeExactly t -> window (localDay t) (localDay t)
+ | otherwise = NextTimeExactly . startTime <$> findfromtoday False
+ where
+ findfromtoday anytime = findfrom recurrance afterday today
+ where
+ today = localDay currenttime
+ afterday = sameaslastday || toolatetoday
+ toolatetoday = not anytime && localTimeOfDay currenttime >= nexttime
+ sameaslastday = lastday == Just today
+ lastday = localDay <$> lasttime
+ nexttime = case scheduledtime of
+ AnyTime -> TimeOfDay 0 0 0
+ SpecificTime h m -> TimeOfDay h m 0
+ exactly d = NextTimeExactly $ LocalTime d nexttime
+ window startd endd = NextTimeWindow
+ (LocalTime startd nexttime)
+ (LocalTime endd (TimeOfDay 23 59 0))
+ findfrom r afterday day = case r of
+ Daily
+ | afterday -> Just $ exactly $ addDays 1 day
+ | otherwise -> Just $ exactly day
+ Weekly Nothing
+ | afterday -> skip 1
+ | otherwise -> case (wday <$> lastday, wday day) of
+ (Nothing, _) -> Just $ window day (addDays 6 day)
+ (Just old, curr)
+ | old == curr -> Just $ window day (addDays 6 day)
+ | otherwise -> skip 1
+ Monthly Nothing
+ | afterday -> skip 1
+ | maybe True (\old -> mnum day > mday old && mday day >= (mday old `mod` minmday)) lastday ->
+ -- Window only covers current month,
+ -- in case there is a Divisible requirement.
+ Just $ window day (endOfMonth day)
+ | otherwise -> skip 1
+ Yearly Nothing
+ | afterday -> skip 1
+ | maybe True (\old -> ynum day > ynum old && yday day >= (yday old `mod` minyday)) lastday ->
+ Just $ window day (endOfYear day)
+ | otherwise -> skip 1
+ Weekly (Just w)
+ | w < 0 || w > maxwday -> Nothing
+ | w == wday day -> if afterday
+ then Just $ exactly $ addDays 7 day
+ else Just $ exactly day
+ | otherwise -> Just $ exactly $
+ addDays (fromIntegral $ (w - wday day) `mod` 7) day
+ Monthly (Just m)
+ | m < 0 || m > maxmday -> Nothing
+ -- TODO can be done more efficiently than recursing
+ | m == mday day -> if afterday
+ then skip 1
+ else Just $ exactly day
+ | otherwise -> skip 1
+ Yearly (Just y)
+ | y < 0 || y > maxyday -> Nothing
+ | y == yday day -> if afterday
+ then skip 365
+ else Just $ exactly day
+ | otherwise -> skip 1
+ Divisible n r'@Daily -> handlediv n r' yday (Just maxyday)
+ Divisible n r'@(Weekly _) -> handlediv n r' wnum (Just maxwnum)
+ Divisible n r'@(Monthly _) -> handlediv n r' mnum (Just maxmnum)
+ Divisible n r'@(Yearly _) -> handlediv n r' ynum Nothing
+ Divisible _ r'@(Divisible _ _) -> findfrom r' afterday day
+ where
+ skip n = findfrom r False (addDays n day)
+ handlediv n r' getval mmax
+ | n > 0 && maybe True (n <=) mmax =
+ findfromwhere r' (divisible n . getval) afterday day
+ | otherwise = Nothing
+ findfromwhere r p afterday day
+ | maybe True (p . getday) next = next
+ | otherwise = maybe Nothing (findfromwhere r p True . getday) next
+ where
+ next = findfrom r afterday day
+ getday = localDay . startTime
+ divisible n v = v `rem` n == 0
+
+endOfMonth :: Day -> Day
+endOfMonth day =
+ let (y,m,_d) = toGregorian day
+ in fromGregorian y m (gregorianMonthLength y m)
+
+endOfYear :: Day -> Day
+endOfYear day =
+ let (y,_m,_d) = toGregorian day
+ in endOfMonth (fromGregorian y maxmnum 1)
+
+-- extracting various quantities from a Day
+wday :: Day -> Int
+wday = thd3 . toWeekDate
+wnum :: Day -> Int
+wnum = snd3 . toWeekDate
+mday :: Day -> Int
+mday = thd3 . toGregorian
+mnum :: Day -> Int
+mnum = snd3 . toGregorian
+yday :: Day -> Int
+yday = snd . toOrdinalDate
+ynum :: Day -> Int
+ynum = fromIntegral . fst . toOrdinalDate
+
+{- Calendar max and mins. -}
+maxyday :: Int
+maxyday = 366 -- with leap days
+minyday :: Int
+minyday = 365
+maxwnum :: Int
+maxwnum = 53 -- some years have more than 52
+maxmday :: Int
+maxmday = 31
+minmday :: Int
+minmday = 28
+maxmnum :: Int
+maxmnum = 12
+maxwday :: Int
+maxwday = 7
+
+fromRecurrance :: Recurrance -> String
+fromRecurrance (Divisible n r) =
+ fromRecurrance' (++ "s divisible by " ++ show n) r
+fromRecurrance r = fromRecurrance' ("every " ++) r
+
+fromRecurrance' :: (String -> String) -> Recurrance -> String
+fromRecurrance' a Daily = a "day"
+fromRecurrance' a (Weekly n) = onday n (a "week")
+fromRecurrance' a (Monthly n) = onday n (a "month")
+fromRecurrance' a (Yearly n) = onday n (a "year")
+fromRecurrance' a (Divisible _n r) = fromRecurrance' a r -- not used
+
+onday :: Maybe Int -> String -> String
+onday (Just n) s = "on day " ++ show n ++ " of " ++ s
+onday Nothing s = s
+
+toRecurrance :: String -> Maybe Recurrance
+toRecurrance s = case words s of
+ ("every":"day":[]) -> Just Daily
+ ("on":"day":sd:"of":"every":something:[]) -> withday sd something
+ ("every":something:[]) -> noday something
+ ("days":"divisible":"by":sn:[]) ->
+ Divisible <$> getdivisor sn <*> pure Daily
+ ("on":"day":sd:"of":something:"divisible":"by":sn:[]) ->
+ Divisible
+ <$> getdivisor sn
+ <*> withday sd something
+ ("every":something:"divisible":"by":sn:[]) ->
+ Divisible
+ <$> getdivisor sn
+ <*> noday something
+ (something:"divisible":"by":sn:[]) ->
+ Divisible
+ <$> getdivisor sn
+ <*> noday something
+ _ -> Nothing
+ where
+ constructor "week" = Just Weekly
+ constructor "month" = Just Monthly
+ constructor "year" = Just Yearly
+ constructor u
+ | "s" `isSuffixOf` u = constructor $ reverse $ drop 1 $ reverse u
+ | otherwise = Nothing
+ withday sd u = do
+ c <- constructor u
+ d <- readish sd
+ Just $ c (Just d)
+ noday u = do
+ c <- constructor u
+ Just $ c Nothing
+ getdivisor sn = do
+ n <- readish sn
+ if n > 0
+ then Just n
+ else Nothing
+
+fromScheduledTime :: ScheduledTime -> String
+fromScheduledTime AnyTime = "any time"
+fromScheduledTime (SpecificTime h m) =
+ show h' ++ (if m > 0 then ":" ++ pad 2 (show m) else "") ++ " " ++ ampm
+ where
+ pad n s = take (n - length s) (repeat '0') ++ s
+ (h', ampm)
+ | h == 0 = (12, "AM")
+ | h < 12 = (h, "AM")
+ | h == 12 = (h, "PM")
+ | otherwise = (h - 12, "PM")
+
+toScheduledTime :: String -> Maybe ScheduledTime
+toScheduledTime "any time" = Just AnyTime
+toScheduledTime v = case words v of
+ (s:ampm:[])
+ | map toUpper ampm == "AM" ->
+ go s h0
+ | map toUpper ampm == "PM" ->
+ go s (\h -> (h0 h) + 12)
+ | otherwise -> Nothing
+ (s:[]) -> go s id
+ _ -> Nothing
+ where
+ h0 h
+ | h == 12 = 0
+ | otherwise = h
+ go :: String -> (Int -> Int) -> Maybe ScheduledTime
+ go s adjust =
+ let (h, m) = separate (== ':') s
+ in SpecificTime
+ <$> (adjust <$> readish h)
+ <*> if null m then Just 0 else readish m
+
+fromSchedule :: Schedule -> String
+fromSchedule (Schedule recurrance scheduledtime) = unwords
+ [ fromRecurrance recurrance
+ , "at"
+ , fromScheduledTime scheduledtime
+ ]
+
+toSchedule :: String -> Maybe Schedule
+toSchedule = eitherToMaybe . parseSchedule
+
+parseSchedule :: String -> Either String Schedule
+parseSchedule s = do
+ r <- maybe (Left $ "bad recurrance: " ++ recurrance) Right
+ (toRecurrance recurrance)
+ t <- maybe (Left $ "bad time of day: " ++ scheduledtime) Right
+ (toScheduledTime scheduledtime)
+ Right $ Schedule r t
+ where
+ (rws, tws) = separate (== "at") (words s)
+ recurrance = unwords rws
+ scheduledtime = unwords tws
+
+instance Arbitrary Schedule where
+ arbitrary = Schedule <$> arbitrary <*> arbitrary
+
+instance Arbitrary ScheduledTime where
+ arbitrary = oneof
+ [ pure AnyTime
+ , SpecificTime
+ <$> choose (0, 23)
+ <*> choose (1, 59)
+ ]
+
+instance Arbitrary Recurrance where
+ arbitrary = oneof
+ [ pure Daily
+ , Weekly <$> arbday
+ , Monthly <$> arbday
+ , Yearly <$> arbday
+ , Divisible
+ <$> positive arbitrary
+ <*> oneof -- no nested Divisibles
+ [ pure Daily
+ , Weekly <$> arbday
+ , Monthly <$> arbday
+ , Yearly <$> arbday
+ ]
+ ]
+ where
+ arbday = oneof
+ [ Just <$> nonNegative arbitrary
+ , pure Nothing
+ ]
+
+prop_schedule_roundtrips :: Schedule -> Bool
+prop_schedule_roundtrips s = toSchedule (fromSchedule s) == Just s
diff --git a/Utility/Shell.hs b/Utility/Shell.hs
new file mode 100644
index 000000000..2227dc767
--- /dev/null
+++ b/Utility/Shell.hs
@@ -0,0 +1,26 @@
+{- /bin/sh handling
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Utility.Shell where
+
+shellPath_portable :: FilePath
+shellPath_portable = "/bin/sh"
+
+shellPath_local :: FilePath
+#ifndef __ANDROID__
+shellPath_local = shellPath_portable
+#else
+shellPath_local = "/system/bin/sh"
+#endif
+
+shebang_portable :: String
+shebang_portable = "#!" ++ shellPath_portable
+
+shebang_local :: String
+shebang_local = "#!" ++ shellPath_local
diff --git a/Utility/TList.hs b/Utility/TList.hs
new file mode 100644
index 000000000..e4bb95498
--- /dev/null
+++ b/Utility/TList.hs
@@ -0,0 +1,66 @@
+{- Transactional lists
+ -
+ - Based on DLists, a transactional list can quickly and efficiently
+ - have items inserted at either end, or a whole list appended to it.
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -}
+
+{-# LANGUAGE BangPatterns #-}
+
+module Utility.TList where
+
+import Common
+
+import Control.Concurrent.STM
+import qualified Data.DList as D
+
+type TList a = TMVar (D.DList a)
+
+newTList :: STM (TList a)
+newTList = newEmptyTMVar
+
+{- Gets the contents of the TList. Blocks when empty.
+ - TList is left empty. -}
+getTList :: TList a -> STM [a]
+getTList tlist = D.toList <$> getTDList tlist
+
+getTDList :: TList a -> STM (D.DList a)
+getTDList = takeTMVar
+
+{- Replaces the contents of the TList. -}
+setTList :: TList a -> [a] -> STM ()
+setTList tlist = setTDList tlist . D.fromList
+
+setTDList :: TList a -> D.DList a -> STM ()
+setTDList tlist = modifyTList tlist . const
+
+{- Takes anything currently in the TList, without blocking.
+ - TList is left empty. -}
+takeTList :: TList a -> STM [a]
+takeTList tlist = maybe [] D.toList <$> tryTakeTMVar tlist
+
+{- Reads anything in the list, without modifying it, or blocking. -}
+readTList :: TList a -> STM [a]
+readTList tlist = maybe [] D.toList <$> tryReadTMVar tlist
+
+{- Mutates a TList. -}
+modifyTList :: TList a -> (D.DList a -> D.DList a) -> STM ()
+modifyTList tlist a = do
+ dl <- fromMaybe D.empty <$> tryTakeTMVar tlist
+ let !dl' = a dl
+ {- The TMVar is left empty when the list is empty.
+ - Thus attempts to read it automatically block. -}
+ unless (emptyDList dl') $
+ putTMVar tlist dl'
+ where
+ emptyDList = D.list True (\_ _ -> False)
+
+consTList :: TList a -> a -> STM ()
+consTList tlist v = modifyTList tlist $ \dl -> D.cons v dl
+
+snocTList :: TList a -> a -> STM ()
+snocTList tlist v = modifyTList tlist $ \dl -> D.snoc dl v
+
+appendTList :: TList a -> [a] -> STM ()
+appendTList tlist l = modifyTList tlist $ \dl -> D.append dl (D.fromList l)
diff --git a/Utility/Tense.hs b/Utility/Tense.hs
new file mode 100644
index 000000000..60b3fa513
--- /dev/null
+++ b/Utility/Tense.hs
@@ -0,0 +1,57 @@
+{- Past and present tense text.
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE OverloadedStrings #-}
+
+module Utility.Tense where
+
+import qualified Data.Text as T
+import Data.Text (Text)
+import GHC.Exts( IsString(..) )
+
+data Tense = Present | Past
+ deriving (Eq)
+
+data TenseChunk = Tensed Text Text | UnTensed Text
+ deriving (Eq, Ord, Show)
+
+newtype TenseText = TenseText [TenseChunk]
+ deriving (Eq, Ord)
+
+{- Allows OverloadedStrings to be used, to build UnTensed chunks. -}
+instance IsString TenseChunk where
+ fromString = UnTensed . T.pack
+
+{- Allows OverloadedStrings to be used, to provide UnTensed TenseText. -}
+instance IsString TenseText where
+ fromString s = TenseText [fromString s]
+
+renderTense :: Tense -> TenseText -> Text
+renderTense tense (TenseText chunks) = T.concat $ map render chunks
+ where
+ render (Tensed present past)
+ | tense == Present = present
+ | otherwise = past
+ render (UnTensed s) = s
+
+{- Builds up a TenseText, separating chunks with spaces.
+ -
+ - However, rather than just intersperse new chunks for the spaces,
+ - the spaces are appended to the end of the chunks.
+ -}
+tenseWords :: [TenseChunk] -> TenseText
+tenseWords = TenseText . go []
+ where
+ go c [] = reverse c
+ go c (w:[]) = reverse (w:c)
+ go c ((UnTensed w):ws) = go (UnTensed (addspace w) : c) ws
+ go c ((Tensed w1 w2):ws) =
+ go (Tensed (addspace w1) (addspace w2) : c) ws
+ addspace w = T.append w " "
+
+unTensed :: Text -> TenseText
+unTensed t = TenseText [UnTensed t]
diff --git a/Utility/ThreadLock.hs b/Utility/ThreadLock.hs
new file mode 100644
index 000000000..c029a2b0c
--- /dev/null
+++ b/Utility/ThreadLock.hs
@@ -0,0 +1,19 @@
+{- locking between threads
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Utility.ThreadLock where
+
+import Control.Concurrent.MVar
+
+type Lock = MVar ()
+
+newLock :: IO Lock
+newLock = newMVar ()
+
+{- Runs an action with a lock held, so only one thread at a time can run it. -}
+withLock :: Lock -> IO a -> IO a
+withLock lock = withMVar lock . const
diff --git a/Utility/ThreadScheduler.hs b/Utility/ThreadScheduler.hs
new file mode 100644
index 000000000..c3e871cde
--- /dev/null
+++ b/Utility/ThreadScheduler.hs
@@ -0,0 +1,69 @@
+{- thread scheduling
+ -
+ - Copyright 2012, 2013 Joey Hess <joey@kitenet.net>
+ - Copyright 2011 Bas van Dijk & Roel van Dijk
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Utility.ThreadScheduler where
+
+import Common
+
+import Control.Concurrent
+#ifndef mingw32_HOST_OS
+import System.Posix.Signals
+#ifndef __ANDROID__
+import System.Posix.Terminal
+#endif
+#endif
+
+newtype Seconds = Seconds { fromSeconds :: Int }
+ deriving (Eq, Ord, Show)
+
+type Microseconds = Integer
+
+{- Runs an action repeatedly forever, sleeping at least the specified number
+ - of seconds in between. -}
+runEvery :: Seconds -> IO a -> IO a
+runEvery n a = forever $ do
+ threadDelaySeconds n
+ a
+
+threadDelaySeconds :: Seconds -> IO ()
+threadDelaySeconds (Seconds n) = unboundDelay (fromIntegral n * oneSecond)
+
+{- Like threadDelay, but not bounded by an Int.
+ -
+ - There is no guarantee that the thread will be rescheduled promptly when the
+ - delay has expired, but the thread will never continue to run earlier than
+ - specified.
+ -
+ - Taken from the unbounded-delay package to avoid a dependency for 4 lines
+ - of code.
+ -}
+unboundDelay :: Microseconds -> IO ()
+unboundDelay time = do
+ let maxWait = min time $ toInteger (maxBound :: Int)
+ threadDelay $ fromInteger maxWait
+ when (maxWait /= time) $ unboundDelay (time - maxWait)
+
+{- Pauses the main thread, letting children run until program termination. -}
+waitForTermination :: IO ()
+waitForTermination = do
+ lock <- newEmptyMVar
+#ifndef mingw32_HOST_OS
+ let check sig = void $
+ installHandler sig (CatchOnce $ putMVar lock ()) Nothing
+ check softwareTermination
+#ifndef __ANDROID__
+ whenM (queryTerminal stdInput) $
+ check keyboardSignal
+#endif
+#endif
+ takeMVar lock
+
+oneSecond :: Microseconds
+oneSecond = 1000000
diff --git a/Utility/Tmp.hs b/Utility/Tmp.hs
new file mode 100644
index 000000000..186cd121a
--- /dev/null
+++ b/Utility/Tmp.hs
@@ -0,0 +1,88 @@
+{- Temporary files and directories.
+ -
+ - Copyright 2010-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Utility.Tmp where
+
+import Control.Exception (bracket)
+import System.IO
+import System.Directory
+import Control.Monad.IfElse
+
+import Utility.Exception
+import System.FilePath
+import Utility.FileSystemEncoding
+
+type Template = String
+
+{- Runs an action like writeFile, writing to a temp file first and
+ - then moving it into place. The temp file is stored in the same
+ - directory as the final file to avoid cross-device renames. -}
+viaTmp :: (FilePath -> String -> IO ()) -> FilePath -> String -> IO ()
+viaTmp a file content = do
+ let (dir, base) = splitFileName file
+ createDirectoryIfMissing True dir
+ (tmpfile, handle) <- openTempFile dir (base ++ ".tmp")
+ hClose handle
+ a tmpfile content
+ renameFile tmpfile file
+
+{- Runs an action with a tmp file located in the system's tmp directory
+ - (or in "." if there is none) then removes the file. -}
+withTmpFile :: Template -> (FilePath -> Handle -> IO a) -> IO a
+withTmpFile template a = do
+ tmpdir <- catchDefaultIO "." getTemporaryDirectory
+ withTmpFileIn tmpdir template a
+
+{- Runs an action with a tmp file located in the specified directory,
+ - then removes the file. -}
+withTmpFileIn :: FilePath -> Template -> (FilePath -> Handle -> IO a) -> IO a
+withTmpFileIn tmpdir template a = bracket create remove use
+ where
+ create = openTempFile tmpdir template
+ remove (name, handle) = do
+ hClose handle
+ catchBoolIO (removeFile name >> return True)
+ use (name, handle) = a name handle
+
+{- Runs an action with a tmp directory located within the system's tmp
+ - directory (or within "." if there is none), then removes the tmp
+ - directory and all its contents. -}
+withTmpDir :: Template -> (FilePath -> IO a) -> IO a
+withTmpDir template a = do
+ tmpdir <- catchDefaultIO "." getTemporaryDirectory
+ withTmpDirIn tmpdir template a
+
+{- Runs an action with a tmp directory located within a specified directory,
+ - then removes the tmp directory and all its contents. -}
+withTmpDirIn :: FilePath -> Template -> (FilePath -> IO a) -> IO a
+withTmpDirIn tmpdir template = bracket create remove
+ where
+ remove d = whenM (doesDirectoryExist d) $
+ removeDirectoryRecursive d
+ create = do
+ createDirectoryIfMissing True tmpdir
+ makenewdir (tmpdir </> template) (0 :: Int)
+ makenewdir t n = do
+ let dir = t ++ "." ++ show n
+ either (const $ makenewdir t $ n + 1) (const $ return dir)
+ =<< tryIO (createDirectory dir)
+
+{- It's not safe to use a FilePath of an existing file as the template
+ - for openTempFile, because if the FilePath is really long, the tmpfile
+ - will be longer, and may exceed the maximum filename length.
+ -
+ - This generates a template that is never too long.
+ - (Well, it allocates 20 characters for use in making a unique temp file,
+ - anyway, which is enough for the current implementation and any
+ - likely implementation.)
+ -}
+relatedTemplate :: FilePath -> FilePath
+relatedTemplate f
+ | len > 20 = truncateFilePath (len - 20) f
+ | otherwise = f
+ where
+ len = length f
diff --git a/Utility/Touch.hsc b/Utility/Touch.hsc
new file mode 100644
index 000000000..53dd719fb
--- /dev/null
+++ b/Utility/Touch.hsc
@@ -0,0 +1,120 @@
+{- More control over touching a file.
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE ForeignFunctionInterface #-}
+
+module Utility.Touch (
+ TimeSpec(..),
+ touchBoth,
+ touch
+) where
+
+import Utility.FileSystemEncoding
+
+import Foreign
+import Foreign.C
+import Control.Monad (when)
+
+newtype TimeSpec = TimeSpec CTime
+
+{- Changes the access and modification times of an existing file.
+ Can follow symlinks, or not. Throws IO error on failure. -}
+touchBoth :: FilePath -> TimeSpec -> TimeSpec -> Bool -> IO ()
+
+touch :: FilePath -> TimeSpec -> Bool -> IO ()
+touch file mtime = touchBoth file mtime mtime
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/time.h>
+
+#ifndef _BSD_SOURCE
+#define _BSD_SOURCE
+#endif
+
+#if (defined UTIME_OMIT && defined UTIME_NOW && defined AT_FDCWD && defined AT_SYMLINK_NOFOLLOW)
+
+at_fdcwd :: CInt
+at_fdcwd = #const AT_FDCWD
+
+at_symlink_nofollow :: CInt
+at_symlink_nofollow = #const AT_SYMLINK_NOFOLLOW
+
+instance Storable TimeSpec where
+ -- use the larger alignment of the two types in the struct
+ alignment _ = max sec_alignment nsec_alignment
+ where
+ sec_alignment = alignment (undefined::CTime)
+ nsec_alignment = alignment (undefined::CLong)
+ sizeOf _ = #{size struct timespec}
+ peek ptr = do
+ sec <- #{peek struct timespec, tv_sec} ptr
+ return $ TimeSpec sec
+ poke ptr (TimeSpec sec) = do
+ #{poke struct timespec, tv_sec} ptr sec
+ #{poke struct timespec, tv_nsec} ptr (0 :: CLong)
+
+{- While its interface is beastly, utimensat is in recent
+ POSIX standards, unlike lutimes. -}
+foreign import ccall "utimensat"
+ c_utimensat :: CInt -> CString -> Ptr TimeSpec -> CInt -> IO CInt
+
+touchBoth file atime mtime follow =
+ allocaArray 2 $ \ptr ->
+ withFilePath file $ \f -> do
+ pokeArray ptr [atime, mtime]
+ r <- c_utimensat at_fdcwd f ptr flags
+ when (r /= 0) $ throwErrno "touchBoth"
+ where
+ flags
+ | follow = 0
+ | otherwise = at_symlink_nofollow
+
+#else
+#if 0
+{- Using lutimes is needed for BSD.
+ -
+ - TODO: test if lutimes is available. May have to do it in configure.
+ - TODO: TimeSpec uses a CTime, while tv_sec is a CLong. It is implementation
+ - dependent whether these are the same; need to find a cast that works.
+ - (Without the cast it works on linux i386, but
+ - maybe not elsewhere.)
+ -}
+
+instance Storable TimeSpec where
+ alignment _ = alignment (undefined::CLong)
+ sizeOf _ = #{size struct timeval}
+ peek ptr = do
+ sec <- #{peek struct timeval, tv_sec} ptr
+ return $ TimeSpec sec
+ poke ptr (TimeSpec sec) = do
+ #{poke struct timeval, tv_sec} ptr sec
+ #{poke struct timeval, tv_usec} ptr (0 :: CLong)
+
+foreign import ccall "utimes"
+ c_utimes :: CString -> Ptr TimeSpec -> IO CInt
+foreign import ccall "lutimes"
+ c_lutimes :: CString -> Ptr TimeSpec -> IO CInt
+
+touchBoth file atime mtime follow =
+ allocaArray 2 $ \ptr ->
+ withFilePath file $ \f -> do
+ pokeArray ptr [atime, mtime]
+ r <- syscall f ptr
+ when (r /= 0) $
+ throwErrno "touchBoth"
+ where
+ syscall
+ | follow = c_lutimes
+ | otherwise = c_utimes
+
+#else
+#warning "utimensat and lutimes not available; building without symlink timestamp preservation support"
+touchBoth _ _ _ _ = return ()
+#endif
+#endif
diff --git a/Utility/Url.hs b/Utility/Url.hs
new file mode 100644
index 000000000..03c311fd2
--- /dev/null
+++ b/Utility/Url.hs
@@ -0,0 +1,190 @@
+{- Url downloading.
+ -
+ - Copyright 2011,2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Utility.Url (
+ URLString,
+ UserAgent,
+ check,
+ checkBoth,
+ exists,
+ download,
+ downloadQuiet,
+ parseURIRelaxed
+) where
+
+import Common
+import Network.URI
+import qualified Network.Browser as Browser
+import Network.HTTP
+import Data.Either
+
+import qualified Build.SysConfig
+
+type URLString = String
+
+type Headers = [String]
+
+type UserAgent = String
+
+{- Checks that an url exists and could be successfully downloaded,
+ - also checking that its size, if available, matches a specified size. -}
+checkBoth :: URLString -> Headers -> Maybe Integer -> Maybe UserAgent -> IO Bool
+checkBoth url headers expected_size ua = do
+ v <- check url headers expected_size ua
+ return (fst v && snd v)
+check :: URLString -> Headers -> Maybe Integer -> Maybe UserAgent -> IO (Bool, Bool)
+check url headers expected_size = handle <$$> exists url headers
+ where
+ handle (False, _) = (False, False)
+ handle (True, Nothing) = (True, True)
+ handle (True, s) = case expected_size of
+ Just _ -> (True, expected_size == s)
+ Nothing -> (True, True)
+
+{- Checks that an url exists and could be successfully downloaded,
+ - also returning its size if available.
+ -
+ - For a file: url, check it directly.
+ -
+ - Uses curl otherwise, when available, since curl handles https better
+ - than does Haskell's Network.Browser.
+ -}
+exists :: URLString -> Headers -> Maybe UserAgent -> IO (Bool, Maybe Integer)
+exists url headers ua = case parseURIRelaxed url of
+ Just u
+ | uriScheme u == "file:" -> do
+ s <- catchMaybeIO $ getFileStatus (unEscapeString $ uriPath u)
+ case s of
+ Just stat -> return (True, Just $ fromIntegral $ fileSize stat)
+ Nothing -> dne
+ | otherwise -> if Build.SysConfig.curl
+ then do
+ output <- readProcess "curl" $ toCommand curlparams
+ case lastMaybe (lines output) of
+ Just ('2':_:_) -> return (True, extractsize output)
+ _ -> dne
+ else do
+ r <- request u headers HEAD ua
+ case rspCode r of
+ (2,_,_) -> return (True, size r)
+ _ -> return (False, Nothing)
+ Nothing -> dne
+ where
+ dne = return (False, Nothing)
+
+ curlparams = addUserAgent ua $
+ [ Param "-s"
+ , Param "--head"
+ , Param "-L", Param url
+ , Param "-w", Param "%{http_code}"
+ ] ++ concatMap (\h -> [Param "-H", Param h]) headers
+
+ extractsize s = case lastMaybe $ filter ("Content-Length:" `isPrefixOf`) (lines s) of
+ Just l -> case lastMaybe $ words l of
+ Just sz -> readish sz
+ _ -> Nothing
+ _ -> Nothing
+
+ size = liftM Prelude.read . lookupHeader HdrContentLength . rspHeaders
+
+-- works for both wget and curl commands
+addUserAgent :: Maybe UserAgent -> [CommandParam] -> [CommandParam]
+addUserAgent Nothing ps = ps
+addUserAgent (Just ua) ps = ps ++ [Param "--user-agent", Param ua]
+
+{- Used to download large files, such as the contents of keys.
+ -
+ - Uses wget or curl program for its progress bar. (Wget has a better one,
+ - so is preferred.) Which program to use is determined at run time; it
+ - would not be appropriate to test at configure time and build support
+ - for only one in.
+ -}
+download :: URLString -> Headers -> [CommandParam] -> FilePath -> Maybe UserAgent -> IO Bool
+download = download' False
+
+{- No output, even on error. -}
+downloadQuiet :: URLString -> Headers -> [CommandParam] -> FilePath -> Maybe UserAgent -> IO Bool
+downloadQuiet = download' True
+
+download' :: Bool -> URLString -> Headers -> [CommandParam] -> FilePath -> Maybe UserAgent -> IO Bool
+download' quiet url headers options file ua =
+ case parseURIRelaxed url of
+ Just u
+ | uriScheme u == "file:" -> do
+ -- curl does not create destination file
+ -- for an empty file:// url, so pre-create
+ writeFile file ""
+ curl
+ | otherwise -> ifM (inPath "wget") (wget , curl)
+ _ -> return False
+ where
+ headerparams = map (\h -> Param $ "--header=" ++ h) headers
+ wget = go "wget" $ headerparams ++ quietopt "-q" ++ [Params "--clobber -c -O"]
+ {- Uses the -# progress display, because the normal
+ - one is very confusing when resuming, showing
+ - the remainder to download as the whole file,
+ - and not indicating how much percent was
+ - downloaded before the resume. -}
+ curl = go "curl" $ headerparams ++ quietopt "-s" ++
+ [Params "-f -L -C - -# -o"]
+ go cmd opts = boolSystem cmd $
+ addUserAgent ua $ options++opts++[File file, File url]
+ quietopt s
+ | quiet = [Param s]
+ | otherwise = []
+
+{- Uses Network.Browser to make a http request of an url.
+ - For example, HEAD can be used to check if the url exists,
+ - or GET used to get the url content (best for small urls).
+ -
+ - This does its own redirect following because Browser's is buggy for HEAD
+ - requests.
+ -
+ - Unfortunately, does not handle https, so should only be used
+ - when curl is not available.
+ -}
+request :: URI -> Headers -> RequestMethod -> Maybe UserAgent -> IO (Response String)
+request url headers requesttype ua = go 5 url
+ where
+ go :: Int -> URI -> IO (Response String)
+ go 0 _ = error "Too many redirects "
+ go n u = do
+ rsp <- Browser.browse $ do
+ maybe noop Browser.setUserAgent ua
+ Browser.setErrHandler ignore
+ Browser.setOutHandler ignore
+ Browser.setAllowRedirects False
+ let req = mkRequest requesttype u :: Request_String
+ snd <$> Browser.request (addheaders req)
+ case rspCode rsp of
+ (3,0,x) | x /= 5 -> redir (n - 1) u rsp
+ _ -> return rsp
+ addheaders req = setHeaders req (rqHeaders req ++ userheaders)
+ userheaders = rights $ map parseHeader headers
+ ignore = const noop
+ redir n u rsp = case retrieveHeaders HdrLocation rsp of
+ [] -> return rsp
+ (Header _ newu:_) ->
+ case parseURIReference newu of
+ Nothing -> return rsp
+ Just newURI -> go n $
+#if defined VERSION_network
+#if ! MIN_VERSION_network(2,4,0)
+#define WITH_OLD_URI
+#endif
+#endif
+#ifdef WITH_OLD_URI
+ fromMaybe newURI (newURI `relativeTo` u)
+#else
+ newURI `relativeTo` u
+#endif
+
+{- Allows for spaces and other stuff in urls, properly escaping them. -}
+parseURIRelaxed :: URLString -> Maybe URI
+parseURIRelaxed = parseURI . escapeURIString isAllowedInURI
diff --git a/Utility/UserInfo.hs b/Utility/UserInfo.hs
new file mode 100644
index 000000000..9c3bfd42f
--- /dev/null
+++ b/Utility/UserInfo.hs
@@ -0,0 +1,55 @@
+{- user info
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+module Utility.UserInfo (
+ myHomeDir,
+ myUserName,
+ myUserGecos,
+) where
+
+import Control.Applicative
+import System.PosixCompat
+
+import Utility.Env
+
+{- Current user's home directory.
+ -
+ - getpwent will fail on LDAP or NIS, so use HOME if set. -}
+myHomeDir :: IO FilePath
+myHomeDir = myVal env homeDirectory
+ where
+#ifndef mingw32_HOST_OS
+ env = ["HOME"]
+#else
+ env = ["USERPROFILE", "HOME"] -- HOME is used in Cygwin
+#endif
+
+{- Current user's user name. -}
+myUserName :: IO String
+myUserName = myVal env userName
+ where
+#ifndef mingw32_HOST_OS
+ env = ["USER", "LOGNAME"]
+#else
+ env = ["USERNAME", "USER", "LOGNAME"]
+#endif
+
+myUserGecos :: IO String
+#ifdef __ANDROID__
+myUserGecos = return "" -- userGecos crashes on Android
+#else
+myUserGecos = myVal [] userGecos
+#endif
+
+myVal :: [String] -> (UserEntry -> String) -> IO String
+myVal envvars extract = maybe (extract <$> getpwent) return =<< check envvars
+ where
+ check [] = return Nothing
+ check (v:vs) = maybe (check vs) (return . Just) =<< getEnv v
+ getpwent = getUserEntryForID =<< getEffectiveUserID
diff --git a/Utility/Verifiable.hs b/Utility/Verifiable.hs
new file mode 100644
index 000000000..4f88cb9f2
--- /dev/null
+++ b/Utility/Verifiable.hs
@@ -0,0 +1,37 @@
+{- values verified using a shared secret
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Utility.Verifiable where
+
+import Data.Digest.Pure.SHA
+import Data.ByteString.Lazy.UTF8 (fromString)
+import qualified Data.ByteString.Lazy as L
+
+type Secret = L.ByteString
+type HMACDigest = String
+
+{- A value, verifiable using a HMAC digest and a secret. -}
+data Verifiable a = Verifiable
+ { verifiableVal :: a
+ , verifiableDigest :: HMACDigest
+ }
+ deriving (Eq, Read, Show)
+
+mkVerifiable :: Show a => a -> Secret -> Verifiable a
+mkVerifiable a secret = Verifiable a (calcDigest (show a) secret)
+
+verify :: (Eq a, Show a) => Verifiable a -> Secret -> Bool
+verify v secret = v == mkVerifiable (verifiableVal v) secret
+
+calcDigest :: String -> Secret -> HMACDigest
+calcDigest v secret = showDigest $ hmacSha1 secret $ fromString v
+
+{- for quickcheck -}
+prop_verifiable_sane :: String -> String -> Bool
+prop_verifiable_sane a s = verify (mkVerifiable a secret) secret
+ where
+ secret = fromString s
diff --git a/Utility/WebApp.hs b/Utility/WebApp.hs
new file mode 100644
index 000000000..421dadb39
--- /dev/null
+++ b/Utility/WebApp.hs
@@ -0,0 +1,281 @@
+{- Yesod webapp
+ -
+ - Copyright 2012 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE OverloadedStrings, CPP, RankNTypes #-}
+
+module Utility.WebApp where
+
+import Common
+import Utility.Tmp
+import Utility.FileMode
+import Utility.Hash
+
+import qualified Yesod
+import qualified Network.Wai as Wai
+import Network.Wai.Handler.Warp
+import Network.Wai.Logger
+import Control.Monad.IO.Class
+import Network.HTTP.Types
+import System.Log.Logger
+import qualified Data.CaseInsensitive as CI
+import Network.Socket
+import Control.Exception
+import "crypto-api" Crypto.Random
+import qualified Web.ClientSession as CS
+import qualified Data.ByteString.Lazy as L
+import qualified Data.ByteString.Lazy.UTF8 as L8
+import qualified Data.ByteString as B
+import qualified Data.Text as T
+import qualified Data.Text.Encoding as TE
+import Blaze.ByteString.Builder.Char.Utf8 (fromText)
+import Blaze.ByteString.Builder (Builder)
+import Data.Monoid
+import Control.Arrow ((***))
+import Control.Concurrent
+#ifdef __ANDROID__
+import Data.Endian
+#endif
+
+localhost :: HostName
+localhost = "localhost"
+
+{- Builds a command to use to start or open a web browser showing an url. -}
+browserProc :: String -> CreateProcess
+#ifdef darwin_HOST_OS
+browserProc url = proc "open" [url]
+#else
+#ifdef __ANDROID__
+-- Warning: The `am` command does not work very reliably on Android.
+browserProc url = proc "am"
+ ["start", "-a", "android.intent.action.VIEW", "-d", url]
+#else
+browserProc url = proc "xdg-open" [url]
+#endif
+#endif
+
+{- Binds to a socket on localhost, or possibly a different specified
+ - hostname or address, and runs a webapp on it.
+ -
+ - An IO action can also be run, to do something with the address,
+ - such as start a web browser to view the webapp.
+ -}
+runWebApp :: Maybe HostName -> Wai.Application -> (SockAddr -> IO ()) -> IO ()
+runWebApp h app observer = do
+ sock <- getSocket h
+ void $ forkIO $ runSettingsSocket webAppSettings sock app
+ sockaddr <- fixSockAddr <$> getSocketName sock
+ observer sockaddr
+
+fixSockAddr :: SockAddr -> SockAddr
+#ifdef __ANDROID__
+{- On Android, the port is currently incorrectly returned in network
+ - byte order, which is wrong on little endian systems. -}
+fixSockAddr (SockAddrInet (PortNum port) addr) = SockAddrInet (PortNum $ swapEndian port) addr
+#endif
+fixSockAddr addr = addr
+
+webAppSettings :: Settings
+webAppSettings = defaultSettings
+ -- disable buggy sloworis attack prevention code
+ { settingsTimeout = 30 * 60
+ }
+
+{- Binds to a local socket, or if specified, to a socket on the specified
+ - hostname or address. Selects any free port, unless the hostname ends with
+ - ":port"
+ -
+ - Prefers to bind to the ipv4 address rather than the ipv6 address
+ - of localhost, if it's available.
+ -}
+getSocket :: Maybe HostName -> IO Socket
+getSocket h = do
+#ifdef __ANDROID__
+ -- getAddrInfo currently segfaults on Android.
+ -- The HostName is ignored by this code.
+ when (isJust h) $
+ error "getSocket with HostName not supported on Android"
+ addr <- inet_addr "127.0.0.1"
+ sock <- socket AF_INET Stream defaultProtocol
+ preparesocket sock
+ bindSocket sock (SockAddrInet aNY_PORT addr)
+ use sock
+ where
+#else
+ addrs <- getAddrInfo (Just hints) (Just hostname) port
+ case (partition (\a -> addrFamily a == AF_INET) addrs) of
+ (v4addr:_, _) -> go v4addr
+ (_, v6addr:_) -> go v6addr
+ _ -> error "unable to bind to a local socket"
+ where
+ (hostname, port) = maybe (localhost, Nothing) splitHostPort h
+ hints = defaultHints { addrSocketType = Stream }
+ {- Repeated attempts because bind sometimes fails for an
+ - unknown reason on OSX. -}
+ go addr = go' 100 addr
+ go' :: Int -> AddrInfo -> IO Socket
+ go' 0 _ = error "unable to bind to local socket"
+ go' n addr = do
+ r <- tryIO $ bracketOnError (open addr) sClose (useaddr addr)
+ either (const $ go' (pred n) addr) return r
+ open addr = socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr)
+ useaddr addr sock = do
+ preparesocket sock
+ bindSocket sock (addrAddress addr)
+ use sock
+#endif
+ preparesocket sock = setSocketOption sock ReuseAddr 1
+ use sock = do
+ listen sock maxListenQueue
+ return sock
+
+{- Splits address:port. For IPv6, use [address]:port. The port is optional. -}
+splitHostPort :: String -> (HostName, Maybe ServiceName)
+splitHostPort s
+ | "[" `isPrefixOf` s = let (h, p) = break (== ']') (drop 1 s)
+ in if "]:" `isPrefixOf` p
+ then (h, Just $ drop 2 p)
+ else (h, Nothing)
+ | otherwise = let (h, p) = separate (== ':') s
+ in if null p
+ then (h, Nothing)
+ else (h, Just p)
+
+{- Checks if debugging is actually enabled. -}
+debugEnabled :: IO Bool
+debugEnabled = do
+ l <- getRootLogger
+ return $ getLevel l <= Just DEBUG
+
+{- WAI middleware that logs using System.Log.Logger at debug level.
+ -
+ - Recommend only inserting this middleware when debugging is actually
+ - enabled, as it's not optimised at all.
+ -}
+httpDebugLogger :: Wai.Middleware
+httpDebugLogger waiApp req = do
+ logRequest req
+ waiApp req
+
+logRequest :: MonadIO m => Wai.Request -> m ()
+logRequest req = do
+ liftIO $ debugM "WebApp" $ unwords
+ [ showSockAddr $ Wai.remoteHost req
+ , frombs $ Wai.requestMethod req
+ , frombs $ Wai.rawPathInfo req
+ --, show $ Wai.httpVersion req
+ --, frombs $ lookupRequestField "referer" req
+ , frombs $ lookupRequestField "user-agent" req
+ ]
+ where
+ frombs v = L8.toString $ L.fromChunks [v]
+
+lookupRequestField :: CI.CI B.ByteString -> Wai.Request -> B.ByteString
+lookupRequestField k req = fromMaybe "" . lookup k $ Wai.requestHeaders req
+
+{- Rather than storing a session key on disk, use a random key
+ - that will only be valid for this run of the webapp. -}
+#if MIN_VERSION_yesod(1,2,0)
+webAppSessionBackend :: Yesod.Yesod y => y -> IO (Maybe Yesod.SessionBackend)
+#else
+webAppSessionBackend :: Yesod.Yesod y => y -> IO (Maybe (Yesod.SessionBackend y))
+#endif
+webAppSessionBackend _ = do
+ g <- newGenIO :: IO SystemRandom
+ case genBytes 96 g of
+ Left e -> error $ "failed to generate random key: " ++ show e
+ Right (s, _) -> case CS.initKey s of
+ Left e -> error $ "failed to initialize key: " ++ show e
+ Right key -> use key
+ where
+ timeout = 120 * 60 -- 120 minutes
+ use key =
+#if MIN_VERSION_yesod(1,2,0)
+ Just . Yesod.clientSessionBackend key . fst
+ <$> Yesod.clientSessionDateCacher timeout
+#else
+#if MIN_VERSION_yesod(1,1,7)
+ Just . Yesod.clientSessionBackend2 key . fst
+ <$> Yesod.clientSessionDateCacher timeout
+#else
+ return $ Just $
+ Yesod.clientSessionBackend key timeout
+#endif
+#endif
+
+{- Generates a random sha512 string, suitable to be used for an
+ - authentication secret. -}
+genRandomToken :: IO String
+genRandomToken = do
+ g <- newGenIO :: IO SystemRandom
+ return $
+ case genBytes 512 g of
+ Left e -> error $ "failed to generate secret token: " ++ show e
+ Right (s, _) -> show $ sha512 $ L.fromChunks [s]
+
+{- A Yesod isAuthorized method, which checks the auth cgi parameter
+ - against a token extracted from the Yesod application.
+ -
+ - Note that the usual Yesod error page is bypassed on error, to avoid
+ - possibly leaking the auth token in urls on that page!
+ -}
+#if MIN_VERSION_yesod(1,2,0)
+checkAuthToken :: (Monad m, Yesod.MonadHandler m) => (Yesod.HandlerSite m -> T.Text) -> m Yesod.AuthResult
+#else
+checkAuthToken :: forall t sub. (t -> T.Text) -> Yesod.GHandler sub t Yesod.AuthResult
+#endif
+checkAuthToken extractToken = do
+ webapp <- Yesod.getYesod
+ req <- Yesod.getRequest
+ let params = Yesod.reqGetParams req
+ if lookup "auth" params == Just (extractToken webapp)
+ then return Yesod.Authorized
+ else Yesod.sendResponseStatus unauthorized401 ()
+
+{- A Yesod joinPath method, which adds an auth cgi parameter to every
+ - url matching a predicate, containing a token extracted from the
+ - Yesod application.
+ -
+ - A typical predicate would exclude files under /static.
+ -}
+insertAuthToken :: forall y. (y -> T.Text)
+ -> ([T.Text] -> Bool)
+ -> y
+ -> T.Text
+ -> [T.Text]
+ -> [(T.Text, T.Text)]
+ -> Builder
+insertAuthToken extractToken predicate webapp root pathbits params =
+ fromText root `mappend` encodePath pathbits' encodedparams
+ where
+ pathbits' = if null pathbits then [T.empty] else pathbits
+ encodedparams = map (TE.encodeUtf8 *** go) params'
+ go "" = Nothing
+ go x = Just $ TE.encodeUtf8 x
+ authparam = (T.pack "auth", extractToken webapp)
+ params'
+ | predicate pathbits = authparam:params
+ | otherwise = params
+
+{- Creates a html shim file that's used to redirect into the webapp,
+ - to avoid exposing the secret token when launching the web browser. -}
+writeHtmlShim :: String -> String -> FilePath -> IO ()
+writeHtmlShim title url file = viaTmp writeFileProtected file $ genHtmlShim title url
+
+{- TODO: generate this static file using Yesod. -}
+genHtmlShim :: String -> String -> String
+genHtmlShim title url = unlines
+ [ "<html>"
+ , "<head>"
+ , "<title>"++ title ++ "</title>"
+ , "<meta http-equiv=\"refresh\" content=\"1; URL="++url++"\">"
+ , "<body>"
+ , "<p>"
+ , "<a href=\"" ++ url ++ "\">" ++ title ++ "</a>"
+ , "</p>"
+ , "</body>"
+ , "</html>"
+ ]
diff --git a/Utility/Win32Notify.hs b/Utility/Win32Notify.hs
new file mode 100644
index 000000000..edde5309c
--- /dev/null
+++ b/Utility/Win32Notify.hs
@@ -0,0 +1,65 @@
+{- Win32-notify interface
+ -
+ - Copyright 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Utility.Win32Notify where
+
+import Common hiding (isDirectory)
+import Utility.DirWatcher.Types
+
+import System.Win32.Notify
+import qualified System.PosixCompat.Files as Files
+
+watchDir :: FilePath -> (FilePath -> Bool) -> WatchHooks -> IO WatchManager
+watchDir dir ignored hooks = do
+ scan dir
+ wm <- initWatchManager
+ void $ watchDirectory wm dir True [Create, Delete, Modify, Move] handle
+ return wm
+ where
+ handle evt
+ | ignoredPath ignored (filePath evt) = noop
+ | otherwise = case evt of
+ (Deleted _ _)
+ | isDirectory evt -> runhook delDirHook Nothing
+ | otherwise -> runhook delHook Nothing
+ (Created _ _)
+ | isDirectory evt -> noop
+ | otherwise -> runhook addHook Nothing
+ (Modified _ _)
+ | isDirectory evt -> noop
+ {- Add hooks are run when a file is modified for
+ - compatability with INotify, which calls the add
+ - hook when a file is closed, and so tends to call
+ - both add and modify for file modifications. -}
+ | otherwise -> do
+ runhook addHook Nothing
+ runhook modifyHook Nothing
+ where
+ runhook h s = maybe noop (\a -> a (filePath evt) s) (h hooks)
+
+ scan d = unless (ignoredPath ignored d) $
+ mapM_ go =<< dirContentsRecursive d
+ where
+ go f
+ | ignoredPath ignored f = noop
+ | otherwise = do
+ ms <- getstatus f
+ case ms of
+ Nothing -> noop
+ Just s
+ | Files.isRegularFile s ->
+ runhook addHook ms
+ | otherwise ->
+ noop
+ where
+ runhook h s = maybe noop (\a -> a f s) (h hooks)
+
+ getstatus = catchMaybeIO . getFileStatus
+
+{- Check each component of the path to see if it's ignored. -}
+ignoredPath :: (FilePath -> Bool) -> FilePath -> Bool
+ignoredPath ignored = any ignored . map dropTrailingPathSeparator . splitPath
diff --git a/Utility/Yesod.hs b/Utility/Yesod.hs
new file mode 100644
index 000000000..00424d191
--- /dev/null
+++ b/Utility/Yesod.hs
@@ -0,0 +1,71 @@
+{- Yesod stuff, that's typically found in the scaffolded site.
+ -
+ - Also a bit of a compatability layer to make it easier to support yesod
+ - 1.1 and 1.2 in the same code base.
+ -
+ - Copyright 2012, 2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP, RankNTypes, FlexibleContexts #-}
+
+module Utility.Yesod
+ ( module Y
+ , liftH
+#ifndef __ANDROID__
+ , widgetFile
+ , hamletTemplate
+#endif
+#if ! MIN_VERSION_yesod(1,2,0)
+ , giveUrlRenderer
+ , Html
+#endif
+ ) where
+
+#if MIN_VERSION_yesod(1,2,0)
+import Yesod as Y
+#else
+import Yesod as Y hiding (Html)
+#endif
+#ifndef __ANDROID__
+import Yesod.Default.Util
+import Language.Haskell.TH.Syntax (Q, Exp)
+#if MIN_VERSION_yesod_default(1,1,0)
+import Data.Default (def)
+import Text.Hamlet hiding (Html)
+#endif
+#endif
+
+#ifndef __ANDROID__
+widgetFile :: String -> Q Exp
+#if ! MIN_VERSION_yesod_default(1,1,0)
+widgetFile = widgetFileNoReload
+#else
+widgetFile = widgetFileNoReload $ def
+ { wfsHamletSettings = defaultHamletSettings
+ { hamletNewlines = AlwaysNewlines
+ }
+ }
+#endif
+
+hamletTemplate :: FilePath -> FilePath
+hamletTemplate f = globFile "hamlet" f
+#endif
+
+{- Lift Handler to Widget -}
+#if MIN_VERSION_yesod(1,2,0)
+liftH :: Monad m => HandlerT site m a -> WidgetT site m a
+liftH = handlerToWidget
+#else
+liftH :: MonadLift base m => base a -> m a
+liftH = lift
+#endif
+
+{- Misc new names for stuff. -}
+#if ! MIN_VERSION_yesod(1,2,0)
+giveUrlRenderer :: forall master sub. HtmlUrl (Route master) -> GHandler sub master RepHtml
+giveUrlRenderer = hamletToRepHtml
+
+type Html = RepHtml
+#endif
diff --git a/Utility/libdiskfree.c b/Utility/libdiskfree.c
new file mode 100644
index 000000000..d2843ed20
--- /dev/null
+++ b/Utility/libdiskfree.c
@@ -0,0 +1,73 @@
+/* disk free space checking, C mini-library
+ *
+ * Copyright 2012 Joey Hess <joey@kitenet.net>
+ *
+ * Licensed under the GNU GPL version 3 or higher.
+ */
+
+/* Include appropriate headers for the OS, and define what will be used to
+ * check the free space. */
+#if defined(__APPLE__)
+# include <sys/param.h>
+# include <sys/mount.h>
+/* In newer OSX versions, statfs64 is deprecated, in favor of statfs,
+ * which is 64 bit only with a build option -- but statfs64 still works,
+ * and this keeps older OSX also supported. */
+# define STATCALL statfs64
+# define STATSTRUCT statfs64
+#else
+#if defined (__FreeBSD__)
+# include <sys/param.h>
+# include <sys/mount.h>
+# define STATCALL statfs /* statfs64 not yet tested on a real FreeBSD machine */
+# define STATSTRUCT statfs
+#else
+#if defined __ANDROID__
+# warning free space checking code not available for Android
+# define UNKNOWN
+#else
+#if defined (__linux__) || defined (__FreeBSD_kernel__)
+/* Linux or Debian kFreeBSD */
+/* This is a POSIX standard, so might also work elsewhere too. */
+# include <sys/statvfs.h>
+# define STATCALL statvfs
+# define STATSTRUCT statvfs
+#else
+# warning free space checking code not available for this OS
+# define UNKNOWN
+#endif
+#endif
+#endif
+#endif
+
+#include <errno.h>
+#include <stdio.h>
+
+/* Checks the amount of disk that is available to regular (non-root) users.
+ * (If there's an error, or this is not supported,
+ * returns 0 and sets errno to nonzero.)
+ */
+unsigned long long int diskfree(const char *path) {
+#ifdef UNKNOWN
+ errno = 1;
+ return 0;
+#else
+ unsigned long long int available, blocksize;
+ struct STATSTRUCT buf;
+
+ if (STATCALL(path, &buf) != 0)
+ return 0; /* errno is set */
+ else
+ errno = 0;
+
+ available = buf.f_bavail;
+ blocksize = buf.f_bsize;
+ return available * blocksize;
+#endif
+}
+
+/*
+main () {
+ printf("%lli\n", diskfree("."));
+}
+*/
diff --git a/Utility/libdiskfree.h b/Utility/libdiskfree.h
new file mode 100644
index 000000000..e5b84754f
--- /dev/null
+++ b/Utility/libdiskfree.h
@@ -0,0 +1 @@
+unsigned long long int diskfree(const char *path);
diff --git a/Utility/libkqueue.c b/Utility/libkqueue.c
new file mode 100644
index 000000000..a87f65102
--- /dev/null
+++ b/Utility/libkqueue.c
@@ -0,0 +1,74 @@
+/* kqueue interface, C mini-library
+ *
+ * Copyright 2012 Joey Hess <joey@kitenet.net>
+ *
+ * Licensed under the GNU GPL version 3 or higher.
+ */
+
+#include <stdio.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/event.h>
+#include <sys/time.h>
+#include <errno.h>
+
+/* The specified fds are added to the set of fds being watched for changes.
+ * Fds passed to prior calls still take effect, so it's most efficient to
+ * not pass the same fds repeatedly.
+ *
+ * Returns the fd that changed, or -1 on error.
+ */
+signed int helper(const int kq, const int fdcnt, const int *fdlist, int nodelay) {
+ int i, nev;
+ struct kevent evlist[1];
+ struct kevent chlist[fdcnt];
+ struct timespec avoiddelay = {0, 0};
+ struct timespec *timeout = nodelay ? &avoiddelay : NULL;
+
+ for (i = 0; i < fdcnt; i++) {
+ EV_SET(&chlist[i], fdlist[i], EVFILT_VNODE,
+ EV_ADD | EV_ENABLE | EV_CLEAR,
+ NOTE_WRITE,
+ 0, 0);
+ }
+
+ nev = kevent(kq, chlist, fdcnt, evlist, 1, timeout);
+ if (nev == 1)
+ return evlist[0].ident;
+ else
+ return -1;
+}
+
+/* Initializes a new, empty kqueue. */
+int init_kqueue() {
+ int kq;
+ if ((kq = kqueue()) == -1) {
+ perror("kqueue");
+ exit(1);
+ }
+ return kq;
+}
+
+/* Adds fds to the set that should be watched. */
+void addfds_kqueue(const int kq, const int fdcnt, const int *fdlist) {
+ helper(kq, fdcnt, fdlist, 1);
+}
+
+/* Waits for a change event on a kqueue. */
+signed int waitchange_kqueue(const int kq) {
+ return helper(kq, 0, NULL, 0);
+}
+
+/*
+main () {
+ int list[1];
+ int kq;
+ list[0]=open(".", O_RDONLY);
+ kq = init_kqueue();
+ addfds_kqueue(kq, 1, list)
+ printf("change: %i\n", waitchange_kqueue(kq));
+}
+*/
diff --git a/Utility/libkqueue.h b/Utility/libkqueue.h
new file mode 100644
index 000000000..692b47f14
--- /dev/null
+++ b/Utility/libkqueue.h
@@ -0,0 +1,3 @@
+int init_kqueue();
+void addfds_kqueue(const int kq, const int fdcnt, const int *fdlist);
+signed int waitchange_kqueue(const int kq);
diff --git a/Utility/libmounts.c b/Utility/libmounts.c
new file mode 100644
index 000000000..8669f33ea
--- /dev/null
+++ b/Utility/libmounts.c
@@ -0,0 +1,103 @@
+/* mounted filesystems, C mini-library
+ *
+ * Copyright (c) 1980, 1989, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 2001
+ * David Rufino <daverufino@btinternet.com>
+ * Copyright 2012
+ * Joey Hess <joey@kitenet.net>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "libmounts.h"
+
+#ifdef GETMNTENT
+/* direct passthrough the getmntent */
+FILE *mounts_start (void) {
+ return setmntent("/etc/mtab", "r");
+}
+int mounts_end (FILE *fp) {
+ return endmntent(fp);
+}
+struct mntent *mounts_next (FILE *fp) {
+ return getmntent(fp);
+}
+#endif
+
+#ifdef GETMNTINFO
+/* getmntent emulation using getmntinfo */
+FILE *mounts_start (void) {
+ return ((FILE *)0x1); /* dummy non-NULL FILE pointer, not used */
+}
+int mounts_end (FILE *fp) {
+ return 1;
+}
+
+static struct mntent _mntent;
+
+static struct mntent *statfs_to_mntent (struct statfs *mntbuf) {
+ _mntent.mnt_fsname = mntbuf->f_mntfromname;
+ _mntent.mnt_dir = mntbuf->f_mntonname;
+ _mntent.mnt_type = mntbuf->f_fstypename;
+
+ _mntent.mnt_opts = '\0';
+ _mntent.mnt_freq = 0;
+ _mntent.mnt_passno = 0;
+
+ return (&_mntent);
+}
+
+static int pos = -1;
+static int mntsize = -1;
+struct statfs *mntbuf = NULL;
+
+struct mntent *mounts_next (FILE *fp) {
+
+ if (pos == -1 || mntsize == -1)
+ mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
+ ++pos;
+ if (pos == mntsize) {
+ pos = mntsize = -1;
+ mntbuf = NULL;
+ return NULL;
+ }
+
+ return (statfs_to_mntent(&mntbuf[pos]));
+}
+#endif
+
+#ifdef UNKNOWN
+/* dummy, do-nothing version */
+FILE *mounts_start (void) {
+ return ((FILE *)0x1);
+}
+int mounts_end (FILE *fp) {
+ return 1;
+}
+struct mntent *mounts_next (FILE *fp) {
+ return NULL;
+}
+#endif
diff --git a/Utility/libmounts.h b/Utility/libmounts.h
new file mode 100644
index 000000000..24df55f31
--- /dev/null
+++ b/Utility/libmounts.h
@@ -0,0 +1,38 @@
+/* Include appropriate headers for the OS, and define what will be used. */
+#if defined (__FreeBSD__) || defined (__APPLE__)
+# include <sys/param.h>
+# include <sys/ucred.h>
+# include <sys/mount.h>
+# define GETMNTINFO
+#else
+#if defined __ANDROID__
+/* Android is handled by the Haskell code, not here. */
+# define UNKNOWN
+#else
+#if defined (__linux__) || defined (__FreeBSD_kernel__)
+/* Linux or Debian kFreeBSD */
+#include <mntent.h>
+# define GETMNTENT
+#else
+# warning mounts listing code not available for this OS
+# define UNKNOWN
+#endif
+#endif
+#endif
+
+#include <stdio.h>
+
+#ifndef GETMNTENT
+struct mntent {
+ char *mnt_fsname;
+ char *mnt_dir;
+ char *mnt_type;
+ char *mnt_opts; /* not filled in */
+ int mnt_freq; /* not filled in */
+ int mnt_passno; /* not filled in */
+};
+#endif
+
+FILE *mounts_start (void);
+int mounts_end (FILE *fp);
+struct mntent *mounts_next (FILE *fp);
diff --git a/configure.hs b/configure.hs
new file mode 100644
index 000000000..15833e62a
--- /dev/null
+++ b/configure.hs
@@ -0,0 +1,6 @@
+{- configure program -}
+
+import Build.Configure
+
+main :: IO ()
+main = run tests
diff --git a/debian/NEWS b/debian/NEWS
new file mode 100644
index 000000000..1266bae20
--- /dev/null
+++ b/debian/NEWS
@@ -0,0 +1,44 @@
+git-annex (4.20131002) unstable; urgency=low
+
+ The layout of gcrypt repositories has changed, and
+ if you created one you must manually upgrade it.
+ See /usr/share/doc/git-annex/html/upgrades/gcrypt.html
+
+ -- Joey Hess <joeyh@debian.org> Tue, 24 Sep 2013 13:55:23 -0400
+
+git-annex (3.20120123) unstable; urgency=low
+
+ There was a bug in the handling of directory special remotes that
+ could cause partial file contents to be stored in them. If you use
+ a directory special remote, you should fsck it, to avoid potential
+ data loss.
+
+ Example: git annex fsck --from mydirectory
+
+ -- Joey Hess <joeyh@debian.org> Thu, 19 Jan 2012 15:24:23 -0400
+
+git-annex (3.20110624) experimental; urgency=low
+
+ There has been another change to the git-annex data store.
+ Use `git annex upgrade` to migrate your repositories to the new
+ layout. See <http://git-annex.branchable.com/upgrades/> or
+ /usr/share/doc/git-annex/html/upgrades.html
+
+ The significant change this time is that the .git-annex/ directory
+ is gone; instead there is a git-annex branch that is automatically
+ maintained by git-annex, and encapsulates all its state nicely out
+ of your way.
+
+ You should make sure you include the git-annex branch when
+ git pushing and pulling.
+
+ -- Joey Hess <joeyh@debian.org> Tue, 21 Jun 2011 20:18:00 -0400
+
+git-annex (0.20110316) experimental; urgency=low
+
+ This version reorganises the layout of git-annex's files in your repository.
+ There is an upgrade process to convert a repository from the old git-annex
+ to this version. See <http://git-annex.branchable.com/upgrades/> or
+ /usr/share/doc/git-annex/html/upgrades.html
+
+ -- Joey Hess <joeyh@debian.org> Wed, 16 Mar 2011 15:49:15 -0400
diff --git a/debian/changelog b/debian/changelog
new file mode 100644
index 000000000..0a84e9307
--- /dev/null
+++ b/debian/changelog
@@ -0,0 +1,2542 @@
+git-annex (5.20131127) unstable; urgency=low
+
+ * webapp: Detect when upgrades are available, and upgrade if the user
+ desires.
+ (Only when git-annex is installed using the prebuilt binaries
+ from git-annex upstream, not from eg Debian.)
+ * assistant: Detect when the git-annex binary is modified or replaced,
+ and either prompt the user to restart the program, or automatically
+ restart it.
+ * annex.autoupgrade configures both the above upgrade behaviors.
+ * Added support for quvi 0.9. Slightly suboptimal due to limitations in its
+ interface compared with the old version.
+ * Bug fix: annex.version did not get set on automatic upgrade to v5 direct
+ mode repo, so the upgrade was performed repeatedly, slowing commands down.
+ * webapp: Fix bug that broke switching between local repositories
+ that use the new guarded direct mode.
+ * Android: Fix stripping of the git-annex binary.
+ * Android: Make terminal app show git-annex version number.
+ * Android: Re-enable XMPP support.
+ * reinject: Allow to be used in direct mode.
+ * Futher improvements to git repo repair. Has now been tested in tens
+ of thousands of intentionally damaged repos, and successfully
+ repaired them all.
+ * Allow use of --unused in bare repository.
+
+ -- Joey Hess <joeyh@debian.org> Wed, 27 Nov 2013 18:41:44 -0400
+
+git-annex (5.20131120) unstable; urgency=low
+
+ * Fix Debian package to not try to run test suite, since haskell-tasty
+ is not out of new or in Build-Depends yet.
+ * dropunused, addunused: Allow "all" instead of a range to
+ act on all unused data.
+ * Ensure execute bit is set on directories when core.sharedrepository is set.
+ * Ensure that core.sharedrepository is honored when creating the .git/annex
+ directory.
+ * Improve repair code in the case where the index file is corrupt,
+ and this hides other problems from git fsck.
+
+ -- Joey Hess <joeyh@debian.org> Wed, 20 Nov 2013 12:54:18 -0400
+
+git-annex (5.20131118) unstable; urgency=low
+
+ * Direct mode repositories now have core.bare=true set, to prevent
+ accidentally running git commands that try to operate on the work tree,
+ and so do the wrong thing in direct mode.
+ * annex.version is now set to 5 for direct mode repositories.
+ This upgrade is handled fully automatically, no need to run
+ git annex upgrade
+ * The "status" command has been renamed to "info", to allow
+ "git annex status" to be used in direct mode repositories, now that
+ "git status" won't work in them.
+ * The -c option now not only modifies the git configuration seen by
+ git-annex, but it is passed along to every git command git-annex runs.
+ * watcher: Avoid loop when adding a file owned by someone else fails
+ in indirect mode because its permissions cannot be modified.
+ * webapp: Avoid encoding problems when displaying the daemon log file.
+ * webapp: Improve UI around remote that have no annex.uuid set,
+ either because setup of them is incomplete, or because the remote
+ git repository is not a git-annex repository.
+ * Include ssh-keygen in standalone bundle.
+ * Allow optionally configuring git-annex with -fEKG to enable awesome
+ remote monitoring interfaceat http://localhost:4242/
+ * Fix bug that caused bad information to be written to the git-annex branch
+ when running describe or other commands with a remote that has no uuid.
+ * Work around Android linker problem that had prevented git-annex from
+ running on Android 4.3 and 4.4.
+ * repair: Handle case where index file is corrupt, but all objects are ok.
+ * assistant: Notice on startup when the index file is corrupt, and
+ auto-repair.
+ * Fix direct mode merge bug when a direct mode file was deleted and replaced
+ with a directory. An ordering problem caused the directory to not get
+ created in this case.
+ Thanks to Tim for the test case.
+ * Direct mode .git/annex/objects directories are no longer left writable,
+ because that allowed writing to symlinks of files that are not present,
+ which followed the link and put bad content in an object location.
+ Thanks to Tim for the test case.
+ * fsck: Fix up .git/annex/object directory permissions.
+ * Switched to the tasty test framework.
+ * Android: Adjust default .gitignore to ignore .thumbnails at any location
+ in the tree, not just at its top.
+ * webapp: Check annex.version.
+
+ -- Joey Hess <joeyh@debian.org> Mon, 18 Nov 2013 10:45:43 -0400
+
+git-annex (4.20131106) unstable; urgency=low
+
+ * Improve local pairing behavior when two computers both try to start
+ the pairing process separately.
+ * sync: Work even when the local git repository is new and empty,
+ with no master branch.
+ * gcrypt, bup: Fix bug that prevented using these special remotes
+ with encryption=pubkey.
+ * Fix enabling of gcrypt repository accessed over ssh;
+ git-annex-shell gcryptsetup had a bug that caused it to fail
+ with permission denied.
+ * Fix zombie process that occurred when switching between repository
+ views in the webapp.
+ * map: Work when there are gcrypt remotes.
+ * Fix build w/o webapp.
+ * Fix exception handling bug that could cause .git/annex/index to be used
+ for git commits outside the git-annex branch. Known to affect git-annex
+ when used with the git shipped with Ubuntu 13.10.
+
+ -- Joey Hess <joeyh@debian.org> Wed, 06 Nov 2013 11:17:47 -0400
+
+git-annex (4.20131101) unstable; urgency=low
+
+ * The "git annex content" command is renamed to "git annex wanted".
+ * New --want-get and --want-drop options which can be used to
+ test preferred content settings.
+ For example, "git annex find --in . --want-drop"
+ * assistant: When autostarted, wait 5 seconds before running the startup
+ scan, to avoid contending with the user's desktop login process.
+ * webapp: When setting up a bare shared repository, enable non-fast-forward
+ pushes.
+ * sync: Show a hint about receive.denyNonFastForwards when a push fails.
+ * directory, webdav: Fix bug introduced in version 4.20131002 that
+ caused the chunkcount file to not be written. Work around repositories
+ without such a file, so files can still be retreived from them.
+ * assistant: Automatically repair damanged git repository, if it can
+ be done without losing data.
+ * assistant: Support repairing git remotes that are locally accessible
+ (eg, on removable drives).
+ * add: Fix reversion in 4.20130827 when adding unlocked files that have
+ not yet been committed.
+ * unannex: New, much slower, but more safe behavior: Copies files out of
+ the annex. This avoids an unannex of one file breaking other files that
+ link to the same content. Also, it means that the content
+ remains in the annex using up space until cleaned up with
+ "git annex unused".
+ (The behavior of unannex --fast has not changed; it still hard links
+ to content in the annex. --fast was not made the default because it is
+ potentially unsafe; editing such a hard linked file can unexpectedly
+ change content stored in the annex.)
+
+ -- Joey Hess <joeyh@debian.org> Fri, 01 Nov 2013 11:34:27 -0400
+
+git-annex (4.20131024) unstable; urgency=low
+
+ * webapp: Fix bug when adding a remote and git-remote-gcrypt
+ is not installed.
+ * The assitant can now run scheduled incremental fsck jobs on the local
+ repository and remotes. These can be configured using vicfg or with the
+ webapp.
+ * repair: New command, which can repair damaged git repositories
+ (even ones not using git-annex).
+ * webapp: When git repository damange is detected, repairs can be
+ done using the webapp UI.
+ * Automatically and safely detect and recover from dangling
+ .git/annex/index.lock files, which would prevent git from
+ committing to the git-annex branch, eg after a crash.
+ * assistant: Detect stale git lock files at startup time, and remove them.
+ * addurl: Better sanitization of generated filenames.
+ * Better sanitization of problem characters when generating URL and WORM
+ keys.
+ * The control socket path passed to ssh needs to be 17 characters
+ shorter than the maximum unix domain socket length, because ssh
+ appends stuff to it to make a temporary filename. Closes: #725512
+ * status: Fix space leak in local mode, introduced in version 4.20130920.
+ * import: Skip .git directories.
+ * Remove bogus runshell loop check.
+ * addurl: Improve message when adding url with wrong size to existing file.
+ * Fixed handling of URL keys that have no recorded size.
+ * status: Fix a crash if a temp file went away while its size was
+ being checked for status.
+ * Deal with git check-attr -z output format change in git 1.8.5.
+ * Work around sed output difference that led to version containing a newline
+ on OSX.
+ * sync: Fix automatic resolution of merge conflicts where one side is an
+ annexed file, and the other side is a non-annexed file, or a directory.
+ * S3: Try to ensure bucket name is valid for archive.org.
+ * assistant: Bug fix: When run in a subdirectory, files from incoming merges
+ were wrongly added to that subdirectory, and removed from their original
+ locations.
+ * Windows: Deal with strange msysgit 1.8.4 behavior of not understanding
+ DOS formatted paths for --git-dir and --work-tree.
+ * Removed workaround for bug in git 1.8.4r0.
+ * Added git-recover-repository command to git-annex source
+ (not built by default; this needs to move to someplace else).
+ * webapp: Move sidebar to the right hand side of the screen.
+
+ -- Joey Hess <joeyh@debian.org> Thu, 24 Oct 2013 12:59:55 -0400
+
+git-annex (4.20131002) unstable; urgency=low
+
+ * Note that the layout of gcrypt repositories has changed, and
+ if you created one you must manually upgrade it.
+ See http://git-annex.branchable.com/upgrades/gcrypt/
+ * webapp: Support setting up and using encrypted git repositories on
+ any ssh server, as well as on rsync.net.
+ * git-annex-shell: Added support for operating inside gcrypt repositories.
+ * Disable receive.denyNonFastForwards when setting up a gcrypt special
+ remote, since gcrypt needs to be able to fast-forward the master branch.
+ * import: Preserve top-level directory structure.
+ * Use cryptohash rather than SHA for hashing when no external hash program
+ is available. This is a significant speedup for SHA256 on OSX, for
+ example.
+ * Added SKEIN256 and SKEIN512 backends.
+ * Android build redone from scratch, many dependencies updated,
+ and entire build can now be done using provided scripts.
+ * assistant: Clear the list of failed transfers when doing a full transfer
+ scan. This prevents repeated retries to download files that are not
+ available, or are not referenced by the current git tree.
+ * indirect, direct: Better behavior when a file is not owned by
+ the user running the conversion.
+ * add, import, assistant: Better preserve the mtime of symlinks,
+ when when adding content that gets deduplicated.
+ * Send a git-annex user-agent when downloading urls.
+ Overridable with --user-agent option.
+ (Not yet done for S3 or WebDAV due to limitations of libraries used.)
+ * webapp: Fixed a bug where when a new remote is added, one file
+ may fail to sync to or from it due to the transferrer process not
+ yet knowing about the new remote.
+ * OSX: Bundled gpg upgraded, now compatible with config files
+ written by MacGPG.
+ * assistant: More robust inotify handling; avoid crashing if a directory
+ cannot be read.
+ * Moved list of backends and remote types from status to version
+ command.
+
+ -- Joey Hess <joeyh@debian.org> Wed, 02 Oct 2013 16:00:39 -0400
+
+git-annex (4.20130920) unstable; urgency=low
+
+ * webapp: Initial support for setting up encrypted removable drives.
+ * Recommend using my patched gcrypt, which fixes some bugs:
+ https://github.com/joeyh/git-remote-gcrypt
+ * Support hot-swapping of removable drives containing gcrypt repositories.
+ * list: New command, displays a compact table of remotes that
+ contain files.
+ (Thanks, anarcat for display code and mastensg for inspiration.)
+ * fsck: Fix detection and fixing of present direct mode files that are
+ wrongly represented as standin symlinks on crippled filesystems.
+ * sync: Fix bug that caused direct mode mappings to not be updated
+ when merging files into the tree on Windows.
+ * sync: Don't fail if the directory it is run in gets removed by the
+ sync.
+ * addurl: Fix quvi audodetection, broken in last release.
+ * status: In local mode, displays information about variance from configured
+ numcopies levels. (--fast avoids calculating these)
+ * gcrypt: Ensure that signing key is set to one of the participants keys.
+ * webapp: Show encryption information when editing a remote.
+ * Avoid unnecessarily catting non-symlink files from git, which can be
+ so large it runs out of memory.
+
+ -- Joey Hess <joeyh@debian.org> Fri, 20 Sep 2013 10:34:51 -0400
+
+git-annex (4.20130911) unstable; urgency=low
+
+ * Fix problem with test suite in non-unicode locale.
+
+ -- Joey Hess <joeyh@debian.org> Wed, 11 Sep 2013 12:14:16 -0400
+
+git-annex (4.20130909) unstable; urgency=low
+
+ * initremote: Syntax change when setting up an encrypted special remote.
+ Now use keyid=$KEYID rather than the old encryption=$KEYID
+ * 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.)
+ * forget --drop-dead: Completely removes mentions of repositories that
+ have been marked as dead from the git-annex branch.
+ * sync, assistant: Force push of the git-annex branch. Necessary
+ to ensure it gets pushed to remotes after being rewritten by forget.
+ * Added gcrypt support. This combines a fully encrypted git
+ repository (using git-remote-gcrypt) with an encrypted git-annex special
+ remote.
+ * sync: Support syncing with gcrypt remotes.
+ * importfeed: Also ignore transient problems with downloading content
+ from feeds.
+ * Honor core.sharedrepository when receiving and adding files in direct
+ mode.
+ * enableremote: gpg keys can be removed from those a remote encrypts
+ to by passing "keyid-=$KEYID". keyid+= is also provided.
+ (Thanks, guilhem for the patch.)
+ * Added encryption=pubkey scheme, which encrypts to public keys directly
+ rather than the hybrid approach. See documentation for advantages
+ and disadvantages, but encryption=hybrid is the recommended scheme still.
+ (Thanks, guilhem for the patch.)
+ * Fix Feeds display in build flags.
+ * Remind user when annex-ignore is set for some remotes, if unable to
+ get or drop a file, possibly because it's on an ignored remote.
+ * gpg: Force --no-textmode in case the user has it turned on in config.
+ * webapp: Improve javascript's handling of longpolling connection
+ failures, by reloading the current page in this case.
+ Works around chromium behavior where ajax connections to urls
+ that were already accessed are denied after navigating back to
+ a previous page.
+ * Allow building without quvi support.
+
+ -- Joey Hess <joeyh@debian.org> Mon, 09 Sep 2013 09:47:02 -0400
+
+git-annex (4.20130827) unstable; urgency=low
+
+ * Youtube support! (And 53 other video hosts). When quvi is installed,
+ git-annex addurl automatically uses it to detect when an page is
+ a video, and downloads the video file.
+ * web special remote: Also support using quvi, for getting files,
+ or checking if files exist in the web.
+ * unused: Is now a minimum of 30 times faster, and typically many
+ more times than that (when a repository has several branches).
+ (Thanks, guilhem for the patch.)
+ * unused: Fix bugs in two edge cases involving manually staged changes.
+ (Thanks, guilhem for the patch.)
+ * Android: Fix bug in terminal app that caused it to spin using much
+ CPU and battery. This problem was introduced in version 4.20130601.
+ * sync, merge: Bug fix: Don't try to merge into master when in a bare repo.
+ * import: Add options to control handling of duplicate files:
+ --duplicate, --deduplicate, and --clean-duplicates
+ * mirror: New command, makes two repositories contain the same set of files.
+ * Set --clobber when running wget to ensure resuming works properly.
+ * Unescape characters in 'file://...' URIs. (Thanks, guilhem for the patch.)
+ * Better error message when trying to use a git remote that has annex.ignore
+ set.
+ * Fix bug that caused typechanged symlinks to be assumed to be unlocked
+ files, so they were added to the annex by the pre-commit hook.
+ * Debian: Run the builtin test suite as an autopkgtest.
+ * Debian: Recommend ssh-askpass, which ssh will use when the assistant
+ is run w/o a tty. Closes: #719832
+
+ -- Joey Hess <joeyh@debian.org> Tue, 27 Aug 2013 11:03:00 -0400
+
+git-annex (4.20130815) unstable; urgency=low
+
+ * assistant, watcher: .gitignore files and other git ignores are now
+ honored, when git 1.8.4 or newer is installed.
+ (Thanks, Adam Spiers, for getting the necessary support into git for this.)
+ * importfeed: Ignores transient problems with feeds. Only exits nonzero
+ when a feed has repeatedly had a problems for at least 1 day.
+ * importfeed: Fix handling of dots in extensions.
+ * Windows: Added support for encrypted special remotes.
+ * Windows: Fixed permissions problem that prevented removing files
+ from directory special remote. Directory special remotes now fully usable.
+
+ -- Joey Hess <joeyh@debian.org> Thu, 15 Aug 2013 10:14:33 +0200
+
+git-annex (4.20130802) unstable; urgency=low
+
+ * dropunused behavior change: Now refuses to drop the last copy of a
+ file, unless you use the --force.
+ This was the last place in git-annex that could remove data referred
+ to by the git history, without being forced.
+ Like drop, dropunused checks remotes, and honors the global
+ annex.numcopies setting. (However, .gitattributes settings cannot
+ apply to unused files.)
+ * Fix inverted logic in last release's fix for data loss bug,
+ that caused git-annex sync on FAT or other crippled filesystems to add
+ symlink standin files to the annex.
+ * importfeed can be used to import files from podcast feeds.
+ * webapp: When setting up a dedicated ssh key to access the annex
+ on a host, set IdentitiesOnly to prevent the ssh-agent from forcing
+ use of a different ssh key. That could result in unncessary password
+ prompts, or prevent git-annex-shell from being run on the remote host.
+ * webapp: Improve handling of remotes whose setup has stalled.
+ * Add status message to XMPP presence tag, to identify to others that
+ the client is a git-annex client. Closes: #717652
+ * webapp: When creating a repository on a removable drive, set
+ core.fsyncobjectfiles, to help prevent data loss when the drive is yanked.
+ * Always build with -threaded, to avoid a deadlock when communicating with
+ gpg.
+ * unused: No longer shows as unused tmp files that are actively being
+ transferred.
+ * assistant: Fix NetWatcher to not sync with remotes that have
+ remote.<name>.annex-sync set to false.
+ * assistant: Fix deadlock that could occur when adding a lot of files
+ at once in indirect mode.
+ * assistant: Fix bug that caused it to stall when adding a very large
+ number of files at once (around 5 thousand).
+ * OSX: Make git-annex-webapp run in the background, so that the app icon
+ can be clicked on the open a new webapp when the assistant is already
+ running.
+ * Improve test suite on Windows; now tests git annex sync.
+ * Fix a few bugs involving filenames that are at or near the filesystem's
+ maximum filename length limit.
+ * find: Avoid polluting stdout with progress messages. Closes: #718186
+ * Escape ':' in file/directory names to avoid it being treated
+ as a pathspec by some git commands. Closes: #718185
+ * Slow and ugly work around for bug #718517 in git 1.8.4~rc0, which broke
+ git-cat-file --batch for filenames containing spaces.
+ (Will be reverted after next git pre-release fixes the problem.)
+
+ -- Joey Hess <joeyh@debian.org> Fri, 02 Aug 2013 11:35:16 -0400
+
+git-annex (4.20130723) unstable; urgency=low
+
+ * Fix data loss bug when adding an (uncompressed) tarball of a
+ git-annex repository, or other file that begins with something
+ that can be mistaken for a git-annex link. Closes: #717456
+ * New improved version of the git-annex logo, contributed by
+ John Lawrence.
+ * Rsync.net have committed to support git-annex and offer a special
+ discounted rate for git-annex users. Updated the webapp to reflect this.
+ http://www.rsync.net/products/git-annex-pricing.html
+ * Install XDG desktop icon files.
+ * Support unannex and uninit in direct mode.
+ * Support import in direct mode.
+ * webapp: Better display of added files.
+ * fix: Preserve the original mtime of fixed symlinks.
+ * uninit: Preserve .git/annex/objects at the end, if it still
+ has content, so that old versions of files and deleted files
+ are not deleted. Print a message with some suggested actions.
+ * When a transfer is already being run by another process,
+ proceed on to the next file, rather than dying.
+ * Fix checking when content is present in a non-bare repository
+ accessed via http.
+ * Display byte sizes with more precision.
+ * watcher: Fixed a crash that could occur when a directory was renamed
+ or deleted before it could be scanned.
+ * watcher: Partially worked around a bug in hinotify, no longer crashes
+ if hinotify cannot process a directory (but can't detect changes in it)
+ * directory special remote: Fix checking that there is enough disk space
+ to hold an object, was broken when using encryption.
+ * webapp: Differentiate between creating a new S3/Glacier/WebDav remote,
+ and initializing an existing remote. When creating a new remote, avoid
+ conflicts with other existing (or deleted) remotes with the same name.
+ * When an XMPP server has SRV records, try them, but don't then fall
+ back to the regular host if they all fail.
+ * For long hostnames, use a hash of the hostname to generate the socket
+ file for ssh connection caching.
+
+ -- Joey Hess <joeyh@debian.org> Tue, 23 Jul 2013 10:46:05 -0400
+
+git-annex (4.20130709) unstable; urgency=low
+
+ * --all: New switch that makes git-annex operate on all data stored
+ in the git annex, including old versions of files. Supported by
+ fsck, get, move, copy.
+ * --unused: New switch that makes git-annex operate on all data found
+ by the last run of git annex unused. Supported by fsck, move, copy.
+ * get, move, copy: Can now be run in a bare repository,
+ like fsck already could. --all is enabled automatically in this case.
+ * merge: Now also merges synced/master or similar branches, which
+ makes it useful to put in a post-receive hook to make a repository
+ automatically update its working copy when git annex sync or the assistant
+ sync with it.
+ * webapp: Fix ssh setup with nonstandard port, broken in last release.
+ * init: Detect systems on which git commit fails due to not being able to
+ determine the FQDN, and put in a workaround so committing to the git-annex
+ branch works.
+ * addurl --pathdepth: Fix failure when the pathdepth specified is deeper
+ than the urls's path.
+ * Windows: Look for .exe extension when searching for a command in path.
+ * Pass -f to curl when downloading a file with it, so it propigates failure.
+ * Windows: Fix url to object when using a http remote.
+ * webapp: Fix authorized_keys line added when setting up a rsync remote
+ on a server that also supports git-annex, to not force running
+ git-annex-shell.
+ * OSX Mountain Lion: Fixed gpg bundled in dmg to not fail due to a missing
+ gpg-agent.
+ * Android: gpg is built without --enable-minimal, so it interoperates
+ better with other gpg builds that may default to using other algorithms
+ for encryption.
+ * dropunused, addunused: Complain when asked to operate on a number that
+ does not correspond to any unused key.
+ * fsck: Don't claim to fix direct mode when run on a symlink whose content
+ is not present.
+ * Make --numcopies override annex.numcopies set in .gitattributes.
+
+ -- Joey Hess <joeyh@debian.org> Tue, 09 Jul 2013 13:55:39 -0400
+
+git-annex (4.20130627) unstable; urgency=low
+
+ * assistant --autostart: Automatically ionices the daemons it starts.
+ * assistant: Daily sanity check thread is run niced.
+ * bup: Handle /~/ in bup remote paths.
+ Thanks, Oliver Matthews
+ * fsck: Ensures that direct mode is used for files when it's enabled.
+ * webapp: Fix bug when setting up a remote ssh repo repeatedly on the same
+ server.
+ * webapp: Ensure that ssh keys generated for different directories
+ on a server are always different.
+ * webapp: Fix bug setting up ssh repo if the user enters "~/" at the start
+ of the path.
+ * assistant: Fix bug that prevented adding files written by gnucash,
+ and more generally support adding hard links to files. However,
+ other operations on hard links are still unsupported.
+ * webapp: Fix bug that caused the webapp to hang when built with yesod 1.2.
+
+ -- Joey Hess <joeyh@debian.org> Thu, 27 Jun 2013 14:21:55 -0400
+
+git-annex (4.20130621) unstable; urgency=low
+
+ * Supports indirect mode on encfs in paranoia mode, and other
+ filesystems that do not support hard links, but do support
+ symlinks and other POSIX filesystem features.
+ * Android: Add .thumbnails to .gitignore when setting up a camera
+ repository.
+ * Android: Make the "Open webapp" menu item open the just created
+ repository when a new repo is made.
+ * webapp: When the user switches to display a different repository,
+ that repository becomes the default repository to be displayed next time
+ the webapp gets started.
+ * glacier: Better handling of the glacier inventory, which avoids
+ duplicate uploads to the same glacier repository by `git annex copy`.
+ * Direct mode: No longer temporarily remove write permission bit of files
+ when adding them.
+ * 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.
+ * Android: Fix use of cp command to not try to use features present
+ only on build system.
+ * Windows: Fix hang when adding several files at once.
+ * assistant: In direct mode, objects are now only dropped when all
+ associated files are unwanted. This avoids a repreated drop/get loop
+ of a file that has a copy in an archive directory, and a copy not in an
+ archive directory. (Indirect mode still has some buggy behavior in this
+ area, since it does not keep track of associated files.)
+ Closes: #712060
+ * status: No longer shows dead repositories.
+ * annex.debug can now be set to enable debug logging by default.
+ The webapp's debugging check box does this.
+ * fsck: Avoid getting confused by Windows path separators
+ * Windows: Multiple bug fixes, including fixing the data written to the
+ git-annex branch.
+ * Windows: The test suite now passes on Windows (a few broken parts are
+ disabled).
+ * assistant: On Linux, the expensive transfer scan is run niced.
+ * Enable assistant and WebDAV support on powerpc and sparc architectures,
+ which now have the necessary dependencies built.
+
+ -- Joey Hess <joeyh@debian.org> Fri, 21 Jun 2013 10:18:41 -0400
+
+git-annex (4.20130601) unstable; urgency=medium
+
+ * XMPP: Git push over xmpp made much more robust.
+ * XMPP: Avoid redundant and unncessary pushes. Note that this breaks
+ compatibility with previous versions of git-annex, which will refuse
+ to accept any XMPP pushes from this version.
+ * XMPP: Send pings and use them to detect when contact with the server
+ is lost.
+ * hook special remote: Added combined hook program support.
+ * Android app: Avoid using hard links to app's lib directory, which
+ is sometimes on a different filesystem than the data directory.
+ * Fix bug in parsing of parens in some preferred content expressions.
+ This fixes the behavior of the manual mode group.
+ * assistant: Work around git-cat-file's not reloading the index after files
+ are staged.
+ * Improve error handling when getting uuid of http remotes to auto-ignore,
+ like with ssh remotes.
+ * content: New command line way to view and configure a repository's
+ preferred content settings.
+ * sync: Fix double merge conflict resolution handling.
+ * XMPP: Fix a file descriptor leak.
+ * Android: Added an "Open WebApp" item to the terminal's menu.
+ * Android: Work around Android devices where the `am` command doesn't work.
+ * Can now restart certain long-running git processes if they crash, and
+ continue working.
+
+ -- Joey Hess <joeyh@debian.org> Sat, 01 Jun 2013 19:16:04 -0400
+
+git-annex (4.20130521) unstable; urgency=low
+
+ * Sanitize debian changelog version before putting it into cabal file.
+ Closes: #708619
+ * Switch to MonadCatchIO-transformers for better handling of state while
+ catching exceptions.
+ * Fix a zombie that could result when running a process like gpg to
+ read and write to it.
+ * Allow building with gpg2.
+ * Disable building with the haskell threaded runtime when the webapp
+ is not built. This may fix builds on mips, s390x and sparc, which are
+ failing to link -lHSrts_thr
+ * Temporarily build without webapp on kfreebsd-i386, until yesod is
+ installable there again.
+ * Direct mode bug fix: After a conflicted merge was automatically resolved,
+ the content of a file that was already present could incorrectly
+ be replaced with a symlink.
+ * Fix a bug in the git-annex branch handling code that could
+ cause info from a remote to not be merged and take effect immediately.
+ * Direct mode is now fully tested by the test suite.
+ * Detect bad content in ~/.config/git-annex/program and look in PATH instead.
+ * OSX: Fixed gpg included in dmg.
+ * Linux standalone: Back to being built with glibc 2.13 for maximum
+ portability.
+
+ -- Joey Hess <joeyh@debian.org> Tue, 21 May 2013 13:10:26 -0400
+
+git-annex (4.20130516) unstable; urgency=low
+
+ * Android: The webapp is ported and working.
+ * Windows: There is a very rough Windows port. Do not trust it with
+ important data.
+ * git-annex-shell: Ensure that received files can be read. Files
+ transferred from some Android devices may have very broken permissions
+ as received.
+ * direct mode: Direct mode commands now work on files staged in the index,
+ they do not need to be committed to git.
+ * Temporarily add an upper bound to the version of yesod that can be built
+ with, since yesod 1.2 has a great many changes that will require extensive
+ work on the webapp.
+ * Disable building with the haskell threaded runtime when the assistant
+ is not built. This may fix builds on s390x and sparc, which are failing
+ to link -lHSrts_thr
+ * Avoid depending on regex-tdfa on mips, mipsel, and s390, where it fails
+ to build.
+ * direct: Fix a bug that could cause some files to be left in indirect mode.
+ * When initializing a directory special remote with a relative path,
+ the path is made absolute.
+ * SHA: Add a runtime sanity check that sha commands output something
+ that appears to be a real sha.
+ * configure: Better checking that sha commands output in the desired format.
+ * rsync special remotes: When sending from a crippled filesystem, use
+ the destination's default file permissions, as the local ones can
+ be arbitrarily broken. (Ie, ----rwxr-x for files on Android)
+ * migrate: Detect if a file gets corrupted while it's being migrated.
+ * Debian: Add a menu file.
+
+ -- Joey Hess <joeyh@debian.org> Thu, 16 May 2013 11:03:35 -0400
+
+git-annex (4.20130501) unstable; urgency=low
+
+ * sync, assistant: Behavior changes: Sync with remotes that have
+ annex-ignore set, so that git remotes on servers without git-annex
+ installed can be used to keep clients' git repos in sync.
+ * assistant: Work around misfeature in git 1.8.2 that makes
+ `git commit --alow-empty -m ""` run an editor.
+ * sync: Bug fix, avoid adding to the annex the
+ dummy symlinks used on crippled filesystems.
+ * Add public repository group.
+ (And inpreferreddir to preferred content expressions.)
+ * webapp: Can now set up Internet Archive repositories.
+ * S3: Dropping content from the Internet Archive doesn't work, but
+ their API indicates it does. Always refuse to drop from there.
+ * Automatically register public urls for files uploaded to the
+ Internet Archive.
+ * To enable an existing special remote, the new enableremote command
+ must be used. The initremote command now is used only to create
+ new special remotes.
+ * initremote: If two existing remotes have the same name,
+ prefer the one with a higher trust level.
+ * assistant: Improved XMPP protocol to better support multiple repositories
+ using the same XMPP account. Fixes bad behavior when sharing with a friend
+ when you or the friend have multiple reposotories on an XMPP account.
+ Note that XMPP pairing with your own devices still pairs with all
+ repositories using your XMPP account.
+ * assistant: Fix bug that could cause incoming pushes to not get
+ merged into the local tree. Particularly affected XMPP pushes.
+ * webapp: Display some additional information about a repository on
+ its edit page.
+ * webapp: Install FDO desktop menu file when started in standalone mode.
+ * webapp: Don't default to making repository in cwd when started
+ from within a directory containing a git-annex file (eg, standalone
+ tarball directory).
+ * Detect systems that have no user name set in GECOS, and also
+ don't have user.name set in git config, and put in a workaround
+ so that commits to the git-annex branch (and the assistant)
+ will still succeed despite git not liking the system configuration.
+ * webapp: When told to add a git repository on a remote server, and
+ the repository already exists as a non-bare repository, use it,
+ rather than initializing a bare repository in the same directory.
+ * direct, indirect: Refuse to do anything when the assistant
+ or git-annex watch daemon is running.
+ * assistant: When built with git before 1.8.0, use `git remote rm`
+ to delete a remote. Newer git uses `git remote remove`.
+ * rmurl: New command, removes one of the recorded urls for a file.
+ * Detect when the remote is broken like bitbucket is, and exits 0 when
+ it fails to run git-annex-shell.
+ * assistant: Several improvements to performance and behavior when
+ performing bulk adds of a large number of files (tens to hundreds
+ of thousands).
+ * assistant: Sanitize XMPP presence information logged for debugging.
+ * webapp: Now automatically fills in any creds used by an existing remote
+ when creating a new remote of the same type. Done for Internet Archive,
+ S3, Glacier, and Box.com remotes.
+ * Store an annex-uuid file in the bucket when setting up a new S3 remote.
+ * Support building with DAV 0.4.
+
+ -- Joey Hess <joeyh@debian.org> Wed, 01 May 2013 01:42:46 -0400
+
+git-annex (4.20130417) unstable; urgency=low
+
+ * initremote: Generates encryption keys with high quality entropy.
+ This can be disabled using --fast to get the old behavior.
+ The assistant still uses low-quality entropy when creating encrypted
+ remotes, to avoid delays. (Thanks, guilhem for the patch.)
+ * Bugfix: Direct mode no longer repeatedly checksums duplicated files.
+ * assistant: Work around horrible, terrible, very bad behavior of
+ gnome-keyring, by not storing special-purpose ssh keys in ~/.ssh/*.pub.
+ Apparently gnome-keyring apparently will load and indiscriminately use
+ such keys in some cases, even if they are not using any of the standard
+ ssh key names. Instead store the keys in ~/.ssh/annex/,
+ which gnome-keyring will not check.
+ * addurl: Bugfix: Did not properly add file in direct mode.
+ * assistant: Bug fix to avoid annexing the files that git uses
+ to stand in for symlinks on FAT and other filesystem not supporting
+ symlinks.
+ * Adjust preferred content expressions so that content in archive
+ directories is preferred until it has reached an archive or smallarchive
+ repository.
+ * webapp: New --listen= option allows running the webapp on one computer
+ and connecting to it from another. (Note: Does not yet use HTTPS.)
+ * Added annex.web-download-command setting.
+ * Added per-remote annex-rsync-transport option. (guilhem again)
+ * Ssh connection caching is now also used by rsync special remotes.
+ (guilhem yet again)
+ * The version number is now derived from git, unless built with
+ VERSION_FROM_CHANGELOG.
+ * assistant: Stop any transfers the assistant initiated on shutdown.
+ * assistant: Added sequence numbers to XMPP git push packets. (Not yet used.)
+ * addurl: Register transfer so the webapp can see it.
+ * addurl: Automatically retry downloads that fail, as long as some
+ additional content was downloaded.
+ * webapp: Much improved progress bar display for downloads from encrypted
+ remotes.
+ * Avoid using runghc, as that needs ghci.
+ * webapp: When a repository's group is changed, rescan for transfers.
+ * webapp: Added animations.
+ * webapp: Include the repository directory in the mangled hostname and
+ ssh key name, so that a locked down ssh key for one repository is not
+ re-used when setting up additional repositories on the same server.
+ * Fall back to internal url downloader when built without curl.
+ * fsck: Check content of direct mode files (only when the inode cache
+ thinks they are unmodified).
+
+ -- Joey Hess <joeyh@debian.org> Wed, 17 Apr 2013 09:07:38 -0400
+
+git-annex (4.20130405) unstable; urgency=low
+
+ * Group subcommands into sections in usage. Closes: #703797
+ * Per-command usage messages.
+ * webapp: Fix a race that sometimes caused alerts or other notifications
+ to be missed if they occurred while a page was loading.
+ * webapp: Progess bar fixes for many types of special remotes.
+ * Build debian package without using cabal, which writes to HOME.
+ Closes: #704205
+ * webapp: Run ssh server probes in a way that will work when the
+ login shell is a monstrosity that should have died 25 years ago,
+ such as csh.
+ * New annex.largefiles setting, which configures which files
+ `git annex add` and the assistant add to the annex.
+ * assistant: Check small files into git directly.
+ * Remotes can be configured to use other MAC algorithms than HMACSHA1
+ to encrypt filenames.
+ Thanks, guilhem for the patch.
+ * git-annex-shell: Passes rsync --bwlimit options on rsync.
+ Thanks, guilhem for the patch.
+ * webapp: Added UI to delete repositories. Closes: #689847
+ * Adjust built-in preferred content expressions to make most types
+ of repositories want content that is only located on untrusted, dead,
+ and unwanted repositories.
+ * drop --auto: Fix bug that prevented dropping files from untrusted
+ repositories.
+ * assistant: Fix bug that could cause direct mode files to be unstaged
+ from git.
+ * Update working tree files fully atomically.
+ * webapp: Improved transfer queue management.
+ * init: Probe whether the filesystem supports fifos, and if not,
+ disable ssh connection caching.
+ * Use lower case hash directories for storing files on crippled filesystems,
+ same as is already done for bare repositories.
+
+ -- Joey Hess <joeyh@debian.org> Fri, 05 Apr 2013 10:42:18 -0400
+
+git-annex (4.20130323) unstable; urgency=low
+
+ * webapp: Repository list is now included in the dashboard, and other
+ UI tweaks.
+ * webapp: Improved UI for pairing your own devices together using XMPP.
+ * webapp: Display an alert when there are XMPP remotes, and a cloud
+ transfer repository needs to be configured.
+ * Add incrementalbackup repository group.
+ * webapp: Encourage user to install git-annex on a server when adding
+ a ssh server, rather than just funneling them through to rsync.
+ * xmpp: --debug now enables a sanitized dump of the XMPP protocol
+ * xmpp: Try harder to detect presence of clients when there's a git push
+ to send.
+ * xmpp: Re-enable XA flag, since disabling it did not turn out to help
+ with the problems Google Talk has with not always sending presence
+ messages to clients.
+ * map: Combine duplicate repositories, for a nicer looking map.
+ * Fix several bugs caused by a bad Ord instance for Remote.
+ * webapp: Switch all forms to POST.
+ * assistant: Avoid syncing with annex-ignored remotes when reconnecting
+ to the network, or connecting a drive.
+ * assistant: Fix OSX bug that prevented committing changed files to a
+ repository when in indirect mode.
+ * webapp: Improved alerts displayed when syncing with remotes, and
+ when syncing with a remote fails.
+ * webapp: Force wrap long filenames in transfer display.
+ * assistant: The ConfigMonitor left one zombie behind each time
+ it checked for changes, now fixed.
+ * get, copy, move: Display an error message when an identical transfer
+ is already in progress, rather than failing with no indication why.
+ * assistant: Several optimisations to file transfers.
+ * OSX app and standalone Linux tarball now both support being added to
+ PATH; no need to use runshell to start git-annex.
+ * webapp: When adding a removable drive, you can now specify the
+ directory inside it to use.
+ * webapp: Confirm whether user wants to combine repositories when
+ adding a removable drive that already has a repository on it.
+
+ -- Joey Hess <joeyh@debian.org> Fri, 22 Mar 2013 18:54:05 -0400
+
+git-annex (4.20130314) unstable; urgency=low
+
+ * Bugfix: git annex add, when ran without any file or directory specified,
+ should add files in the current directory, but not act on unlocked files
+ elsewhere in the tree.
+ * Bugfix: drop --from an unavailable remote no longer updates the location
+ log, incorrectly, to say the remote does not have the key.
+ * Bugfix: If the UUID of a remote is not known, prevent --from, --to,
+ and other ways of specifying remotes by name from selecting it,
+ since it is not possible to sanely use it.
+ * Bugfix: Fix bug in inode cache sentinal check, which broke
+ copying to local repos if the repo being copied from had moved
+ to a different filesystem or otherwise changed all its inodes
+
+ * Switch from using regex-compat to regex-tdfa, as the C regex library
+ is rather buggy.
+ * status: Can now be run with a directory path to show only the
+ status of that directory, rather than the whole annex.
+ * Added remote.<name>.annex-gnupg-options setting.
+ Thanks, guilhem for the patch.
+ * addurl: Add --relaxed option.
+ * addurl: Escape invalid characters in urls, rather than failing to
+ use an invalid url.
+ * addurl: Properly handle url-escaped characters in file:// urls.
+
+ * assistant: Fix dropping content when a file is moved to an archive
+ directory, and getting contennt when a file is moved back out.
+ * assistant: Fix bug in direct mode that could occur when a symlink is
+ moved out of an archive directory, and resulted in the file not being
+ set to direct mode when it was transferred.
+ * assistant: Generate better commits for renames.
+ * assistant: Logs are rotated to avoid them using too much disk space.
+ * assistant: Avoid noise in logs from git commit about typechanged
+ files in direct mode repositories.
+ * assistant: Set gc.auto=0 when creating repositories to prevent
+ automatic commits from causing git-gc runs.
+ * assistant: If gc.auto=0, run git-gc once a day, packing loose objects
+ very non-aggressively.
+ * assistant: XMPP git pull and push requests are cached and sent when
+ presence of a new client is detected.
+ * assistant: Sync with all git remotes on startup.
+ * assistant: Get back in sync with XMPP remotes after network reconnection,
+ and on startup.
+ * assistant: Fix syncing after XMPP pairing.
+ * assistant: Optimised handling of renamed files in direct mode,
+ avoiding re-checksumming.
+ * assistant: Detects most renames, including directory renames, and
+ combines all their changes into a single commit.
+ * assistant: Fix ~/.ssh/git-annex-shell wrapper to work when the
+ ssh key does not force a command.
+ * assistant: Be smarter about avoiding unncessary transfers.
+
+ * webapp: Work around bug in Warp's slowloris attack prevention code,
+ that caused regular browsers to stall when they reuse a connection
+ after leaving it idle for 30 seconds.
+ (See https://github.com/yesodweb/wai/issues/146)
+ * webapp: New preferences page allows enabling/disabling debug logging
+ at runtime, as well as configuring numcopies and diskreserve.
+ * webapp: Repository costs can be configured by dragging repositories around
+ in the repository list.
+ * webapp: Proceed automatically on from "Configure jabber account"
+ to pairing.
+ * webapp: Only show up to 10 queued transfers.
+ * webapp: DTRT when told to create a git repo that already exists.
+ * webapp: Set locally paired repositories to a lower cost than other
+ network remotes.
+
+ * Run ssh with -T to avoid tty allocation and any login scripts that
+ may do undesired things with it.
+ * Several improvements to Makefile and cabal file. Thanks, Peter Simmons
+ * Stop depending on testpack.
+ * Android: Enable test suite.
+
+ -- Joey Hess <joeyh@debian.org> Thu, 14 Mar 2013 15:29:20 -0400
+
+git-annex (4.20130227) unstable; urgency=low
+
+ * annex.version is now set to 4 for direct mode repositories.
+ * Should now fully support git repositories with core.symlinks=false;
+ always using git's pseudosymlink files in such repositories.
+ * webapp: Allow creating repositories on filesystems that lack support for
+ symlinks.
+ * webapp: Can now add a new local repository, and make it sync with
+ the main local repository.
+ * Android: Bundle now includes openssh.
+ * Android: Support ssh connection caching.
+ * Android: Assistant is fully working. (But no webapp yet.)
+ * Direct mode: Support filesystems like FAT which can change their inodes
+ each time they are mounted.
+ * Direct mode: Fix support for adding a modified file.
+ * Avoid passing -p to rsync, to interoperate with crippled filesystems.
+ Closes: #700282
+ * Additional GIT_DIR support bugfixes. May actually work now.
+ * webapp: Display any error message from git init if it fails to create
+ a repository.
+ * Fix a reversion in matching globs introduced in the last release,
+ where "*" did not match files inside subdirectories. No longer uses
+ the Glob library.
+ * copy: Update location log when no copy was performed, if the location
+ log was out of date.
+ * Makefile now builds using cabal, taking advantage of cabal's automatic
+ detection of appropriate build flags.
+ * test: The test suite is now built into the git-annex binary, and can
+ be run at any time.
+
+ -- Joey Hess <joeyh@debian.org> Wed, 27 Feb 2013 14:07:24 -0400
+
+git-annex (3.20130216) unstable; urgency=low
+
+ * Now uses the Haskell uuid library, rather than needing a uuid program.
+ * Now uses the Haskell Glob library, rather than pcre-light, avoiding
+ the need to install libpcre. Currently done only for Cabal or when
+ the Makefile is made to use -DWITH_GLOB
+ * Android port now available (command-line only).
+ * New annex.crippledfilesystem setting, allows use of git-annex
+ repositories on FAT and even worse filesystems; avoiding use of
+ hard links and locked down permissions settings. (Support is incomplete.)
+ * init: Detect when the repository is on a filesystem that does not
+ support hard links, or symlinks, or unix permissions, and set
+ annex.crippledfilesystem, as well as annex.direct.
+ * add: Improved detection of files that are modified while being added.
+ * Fix a bug in direct mode, introduced in the previous release, where
+ if a file was dropped and then got back, it would be stored in indirect
+ mode.
+
+ -- Joey Hess <joeyh@debian.org> Sat, 16 Feb 2013 10:03:26 -0400
+
+git-annex (3.20130207) unstable; urgency=low
+
+ * webapp: Now allows restarting any threads that crash.
+ * Adjust debian package to only build-depend on DAV on architectures
+ where it is available.
+ * addurl --fast: Use curl, rather than haskell HTTP library, to support https.
+ * annex.autocommit: New setting, can be used to disable autocommit
+ of changed files by the assistant, while it still does data syncing
+ and other tasks.
+ * assistant: Ignore .DS_Store on OSX.
+ * assistant: Fix location log when adding new file in direct mode.
+ * Deal with stale mappings for deleted file in direct mode.
+ * pre-commit: Update direct mode mappings.
+ * uninit, unannex --fast: If hard link creation fails, fall back to slow
+ mode.
+ * Clean up direct mode cache and mapping info when dropping keys.
+ * dropunused: Clean up stale direct mode cache and mapping info not
+ removed before.
+
+ -- Joey Hess <joeyh@debian.org> Thu, 07 Feb 2013 12:45:25 -0400
+
+git-annex (3.20130124) unstable; urgency=low
+
+ * Added source repository group, that only retains files until they've
+ been transferred to another repository. Useful for things like
+ repositories on cameras.
+ * Added manual repository group. Use to prevent the assistant from
+ downloading any file contents to keep things in sync. Instead
+ `git annex get`, `git annex drop` etc can be used manually as desired.
+ * webapp: More adjustments to longpoll code to deal with changes in
+ variable quoting in different versions of shakespeare-js.
+ * webapp: Avoid an error if a transfer is stopped just as it finishes.
+ Closes: #698184
+ * webapp: Now always logs to .git/annex/daemon.log
+ * webapp: Has a page to view the log, accessed from the control menu.
+ * webapp: Fix crash adding removable drive that has an annex directory
+ in it that is not a git repository.
+ * Deal with incompatability in gpg2, which caused prompts for encryption
+ passphrases rather than using the supplied --passphrase-fd.
+ * bugfix: Union merges involving two or more repositories could sometimes
+ result in data from one repository getting lost. This could result
+ in the location log data becoming wrong, and fsck being needed to fix it.
+ * sync: Automatic merge conflict resolution now stages deleted files.
+ * Depend on git 1.7.7.6 for --no-edit. Closes: #698399
+ * Fix direct mode mapping code to always store direct mode filenames
+ relative to the top of the repository, even when operating inside a
+ subdirectory.
+ * fsck: Detect and fix consistency errors in direct mode mapping files.
+ * Avoid filename encoding errors when writing direct mode mappings.
+
+ -- Joey Hess <joeyh@debian.org> Tue, 22 Jan 2013 07:11:59 +1100
+
+git-annex (3.20130114) unstable; urgency=low
+
+ * Now handles the case where a file that's being transferred to a remote
+ is modified in place, which direct mode allows. When this
+ happens, the transfer now fails, rather than allow possibly corrupt
+ data into the remote.
+ * fsck: Better checking of file content in direct mode.
+ * drop: Suggest using git annex move when numcopies prevents dropping a file.
+ * webapp: Repo switcher filters out repos that do not exist any more
+ (or are on a drive that's not mounted).
+ * webapp: Use IP address, rather than localhost, since some systems may
+ have configuration problems or other issues that prevent web browsers
+ from connecting to the right localhost IP for the webapp.
+ * webapp: Adjust longpoll code to work with recent versions of
+ shakespeare-js.
+ * assistant: Support new gvfs dbus names used in Gnome 3.6.
+ * In direct mode, files with the same key are no longer hardlinked, as
+ that would cause a surprising behavior if modifying one, where the other
+ would also change.
+ * webapp: Avoid illegal characters in hostname when creating S3 or
+ Glacier remote.
+ * assistant: Avoid committer crashing if a file is deleted at the wrong
+ instant.
+
+ -- Joey Hess <joeyh@debian.org> Mon, 14 Jan 2013 15:25:18 -0400
+
+git-annex (3.20130107) unstable; urgency=low
+
+ * webapp: Add UI to stop and restart assistant.
+ * committer: Fix a file handle leak.
+ * assistant: Make expensive transfer scan work fully in direct mode.
+ * More commands work in direct mode repositories: find, whereis, move, copy,
+ drop, log, fsck, add, addurl.
+ * sync: No longer automatically adds files in direct mode.
+ * assistant: Detect when system is not configured with a user name,
+ and set environment to prevent git from failing.
+ * direct: Avoid hardlinking symlinks that point to the same content
+ when the content is not present.
+ * Fix transferring files to special remotes in direct mode.
+
+ -- Joey Hess <joeyh@debian.org> Mon, 07 Jan 2013 01:01:41 -0400
+
+git-annex (3.20130102) unstable; urgency=low
+
+ * direct, indirect: New commands, that switch a repository to and from
+ direct mode. In direct mode, files are accessed directly, rather than
+ via symlinks. Note that direct mode is currently experimental. Many
+ git-annex commands do not work in direct mode. Some git commands can
+ cause data loss when used in direct mode repositories.
+ * assistant: Now uses direct mode by default when setting up a new
+ local repository.
+ * OSX assistant: Uses the FSEvents API to detect file changes.
+ This avoids issues with running out of file descriptors on large trees,
+ as well as allowing detection of modification of files in direct mode.
+ Other BSD systems still use kqueue.
+ * kqueue: Fix bug that made broken symlinks not be noticed.
+ * vicfg: Quote filename. Closes: #696193
+ * Bugfix: Fixed bug parsing transfer info files, where the newline after
+ the filename was included in it. This was generally benign, but in
+ the assistant, it caused unexpected dropping of preferred content.
+ * Bugfix: Remove leading \ from checksums output by sha*sum commands,
+ when the filename contains \ or a newline. Closes: #696384
+ * fsck: Still accept checksums with a leading \ as valid, now that
+ above bug is fixed.
+ * SHA*E backends: Exclude non-alphanumeric characters from extensions.
+ * migrate: Remove leading \ in SHA* checksums, and non-alphanumerics
+ from extensions of SHA*E keys.
+
+ -- Joey Hess <joeyh@debian.org> Wed, 02 Jan 2013 13:21:34 -0400
+
+git-annex (3.20121211) unstable; urgency=low
+
+ * webapp: Defaults to sharing box.com account info with friends, allowing
+ one-click enabling of the repository.
+ * Fix broken .config/git-annex/program installed by standalone tarball.
+ * assistant: Retrival from glacier now handled.
+ * Include ssh in standalone tarball and OSX app.
+ * watch: Avoid leaving hard links to files behind in .git/annex/tmp
+ if a file is deleted or moved while it's being quarantined in preparation
+ to being added to the annex.
+ * Allow `git annex drop --from web`; of course this does not remove
+ any file from the web, but it does make git-annex remove all urls
+ associated with a file.
+ * webapp: S3 and Glacier forms now have a select list of all
+ currently-supported AWS regions.
+ * webdav: Avoid trying to set props, avoiding incompatability with
+ livedrive.com. Needs DAV version 0.3.
+ * webapp: Prettify error display.
+ * webapp: Fix bad interaction between required fields and modals.
+ * webapp: Added help buttons and links next to fields that require
+ explanations.
+ * webapp: Encryption can be disabled when setting up remotes.
+ * assistant: Avoid trying to drop content from remotes that don't have it.
+ * assistant: Allow periods in ssh key comments.
+ * get/copy --auto: Transfer data even if it would exceed numcopies,
+ when preferred content settings want it.
+ * drop --auto: Fix dropping content when there are no preferred content
+ settings.
+ * webapp: Allow user to specify the port when setting up a ssh or rsync
+ remote.
+ * assistant: Fix syncing to just created ssh remotes.
+ * Enable WebDAV support in Debian package. Closes: #695532
+
+ -- Joey Hess <joeyh@debian.org> Tue, 11 Dec 2012 11:25:03 -0400
+
+git-annex (3.20121127) unstable; urgency=low
+
+ * Fix dirContentsRecursive, which had missed some files in deeply nested
+ subdirectories. Could affect various parts of git-annex.
+ * rsync: Fix bug introduced in last release that broke encrypted rsync
+ special remotes.
+ * The standalone builds now unset their special path and library path
+ variables before running the system web browser.
+
+ -- Joey Hess <joeyh@debian.org> Tue, 27 Nov 2012 17:07:32 -0400
+
+git-annex (3.20121126) unstable; urgency=low
+
+ * New webdav and Amazon glacier special remotes.
+ * Display a warning when a non-existing file or directory is specified.
+ * webapp: Added configurator for Box.com.
+ * webapp: Show error messages to user when testing XMPP creds.
+ * Fix build of assistant without yesod.
+ * webapp: The list of repositiories refreshes when new repositories are
+ added, including when new repository configurations are pushed in from
+ remotes.
+ * OSX: Fix RunAtLoad value in plist file.
+ * Getting a file from chunked directory special remotes no longer buffers
+ it all in memory.
+ * S3: Added progress display for uploading and downloading.
+ * directory special remote: Made more efficient and robust.
+ * Bugfix: directory special remote could loop forever storing a key
+ when a too small chunksize was configured.
+ * Allow controlling whether login credentials for S3 and webdav are
+ committed to the repository, by setting embedcreds=yes|no when running
+ initremote.
+ * Added smallarchive repository group, that only archives files that are
+ in archive directories. Used by default for glacier when set up in the
+ webapp.
+ * assistant: Fixed handling of toplevel archive directory and
+ client repository group.
+ * assistant: Apply preferred content settings when a new symlink
+ is created, or a symlink gets renamed. Made archive directories work.
+
+ -- Joey Hess <joeyh@debian.org> Mon, 26 Nov 2012 11:37:49 -0400
+
+git-annex (3.20121112) unstable; urgency=low
+
+ * assistant: Can use XMPP to notify other nodes about pushes made to other
+ repositories, as well as pushing to them directly over XMPP.
+ * wepapp: Added an XMPP configuration interface.
+ * webapp: Supports pairing over XMPP, with both friends, and other repos
+ using the same account.
+ * assistant: Drops non-preferred content when possible.
+ * assistant: Notices, and applies config changes as they are made to
+ the git-annex branch, including config changes pushed in from remotes.
+ * git-annex-shell: GIT_ANNEX_SHELL_DIRECTORY can be set to limit it
+ to operating on a specified directory.
+ * webapp: When setting up authorized_keys, use GIT_ANNEX_SHELL_DIRECTORY.
+ * Preferred content path matching bugfix.
+ * Preferred content expressions cannot use "in=".
+ * Preferred content expressions can use "present".
+ * Fix handling of GIT_DIR when it refers to a git submodule.
+ * Depend on and use the Haskell SafeSemaphore library, which provides
+ exception-safe versions of SampleVar and QSemN.
+ Thanks, Ben Gamari for an excellent patch set.
+ * file:/// URLs can now be used with the web special remote.
+ * webapp: Allow dashes in ssh key comments when pairing.
+ * uninit: Check and abort if there are symlinks to annexed content that
+ are not checked into git.
+ * webapp: Switched to using the same multicast IP address that avahi uses.
+ * bup: Don't pass - to bup-split to make it read stdin; bup 0.25
+ does not accept that.
+ * bugfix: Don't fail transferring content from read-only repos.
+ Closes: #691341
+ * configure: Check that checksum programs produce correct checksums.
+ * Re-enable dbus, using a new version of the library that fixes the memory
+ leak.
+ * NetWatcher: When dbus connection is lost, try to reconnect.
+ * Use USER and HOME environment when set, and only fall back to getpwent,
+ which doesn't work with LDAP or NIS.
+ * rsync special remote: Include annex-rsync-options when running rsync
+ to test a key's presence.
+ * The standalone tarball's runshell now takes care of installing a
+ ~/.ssh/git-annex-shell wrapper the first time it's run.
+ * webapp: Make an initial, empty commit so there is a master branch
+ * assistant: Fix syncing local drives.
+ * webapp: Fix creation of rsync.net repositories.
+ * webapp: Fix renaming of special remotes.
+ * webapp: Generate better git remote names.
+ * webapp: Ensure that rsync special remotes are enabled using the same
+ name they were originally created using.
+ * Bugfix: Fix hang in webapp when setting up a ssh remote with an absolute
+ path.
+
+ -- Joey Hess <joeyh@debian.org> Mon, 12 Nov 2012 10:39:47 -0400
+
+git-annex (3.20121017) unstable; urgency=low
+
+ * Fix zombie cleanup reversion introduced in 3.20121009.
+ * Additional fix to support git submodules.
+
+ -- Joey Hess <joeyh@debian.org> Tue, 16 Oct 2012 21:10:14 -0400
+
+git-annex (3.20121016) unstable; urgency=low
+
+ * vicfg: New file format, avoids ambiguity with repos that have the same
+ description, or no description.
+ * Bug fix: A recent change caused git-annex-shell to crash.
+ * Better preferred content expression for transfer repos.
+ * webapp: Repository edit form can now edit the name of a repository.
+ * webapp: Make bare repositories on removable drives, as there is nothing
+ to ensure non-bare repos get updated when syncing.
+ * webapp: Better behavior when pausing syncing to a remote when a transfer
+ scan is running and queueing new transfers for that remote.
+ * The standalone binaries are now built to not use ssh connection caching,
+ in order to work with old versions of ssh.
+ * A relative core.worktree is relative to the gitdir. Now that this is
+ handled correctly, git-annex can be used in git submodules.
+ * Temporarily disable use of dbus, as the haskell dbus library blows up
+ when losing connection, which will need to be fixed upstream.
+
+ -- Joey Hess <joeyh@debian.org> Tue, 16 Oct 2012 15:25:22 -0400
+
+git-annex (3.20121010) unstable; urgency=low
+
+ * Renamed --ingroup to --inallgroup.
+ * Standard groups changed to client, transfer, archive, and backup.
+ Each of these has its own standard preferred content setting.
+ * dead: Remove dead repository from all groups.
+ * Avoid unsetting HOME when running certian git commands. Closes: #690193
+ * test: Fix threaded runtime hang.
+ * Makefile: Avoid building with -threaded if the ghc threaded runtime does
+ not exist.
+ * webapp: Improve wording of intro display. Closes: #689848
+ * webapp: Repositories can now be configured, to change their description,
+ their group, or even to disable syncing to them.
+ * git config remote.name.annex-sync can be used to control whether
+ a remote gets synced.
+ * Fix a crash when merging files in the git-annex branch that contain
+ invalid utf8.
+ * Automatically detect when a ssh remote does not have git-annex-shell
+ installed, and set annex-ignore.
+
+ -- Joey Hess <joeyh@debian.org> Fri, 12 Oct 2012 13:45:21 -0400
+
+git-annex (3.20121009) unstable; urgency=low
+
+ * watch, assistant: It's now safe to git annex unlock files while
+ the watcher is running, as well as modify files checked into git
+ as normal files. Additionally, .gitignore settings are now honored.
+ Closes: #689979
+ * group, ungroup: New commands to indicate groups of repositories.
+ * webapp: Adds newly created repositories to one of these groups:
+ clients, drives, servers
+ * vicfg: New command, allows editing (or simply viewing) most
+ of the repository configuration settings stored in the git-annex branch.
+ * Added preferred content expressions, configurable using vicfg.
+ * get --auto: If the local repository has preferred content
+ configured, only get that content.
+ * drop --auto: If the repository the content is dropped from has
+ preferred content configured, drop only content that is not preferred.
+ * copy --auto: Only transfer content that the destination repository prefers.
+ * assistant: Now honors preferred content settings when deciding what to
+ transfer.
+ * --copies=group:number can now be used to match files that are present
+ in a specified number of repositories in a group.
+ * Added --smallerthan, --largerthan, and --inall limits.
+ * Only build-depend on libghc-clientsession-dev on arches that will have
+ the webapp.
+ * uninit: Unset annex.version. Closes: #689852
+
+ -- Joey Hess <joeyh@debian.org> Tue, 09 Oct 2012 15:13:23 -0400
+
+git-annex (3.20121001) unstable; urgency=low
+
+ * fsck: Now has an incremental mode. Start a new incremental fsck pass
+ with git annex fsck --incremental. Now the fsck can be interrupted
+ as desired, and resumed with git annex fsck --more.
+ Thanks, Justin Azoff
+ * New --time-limit option, makes long git-annex commands stop after
+ a specified amount of time.
+ * fsck: New --incremental-schedule option which is nice for scheduling
+ eg, monthly incremental fsck runs in cron jobs.
+ * Fix fallback to ~/Desktop when xdg-user-dir is not available.
+ Closes: #688833
+ * S3: When using a shared cipher, S3 credentials are not stored encrypted
+ in the git repository, as that would allow anyone with access to
+ the repository access to the S3 account. Instead, they're stored
+ in a 600 mode file in the local git repo.
+ * webapp: Avoid crashing when ssh-keygen -F chokes on an invalid known_hosts
+ file.
+ * Always do a system wide installation when DESTDIR is set. Closes: #689052
+ * The Makefile now builds with the new yesod by default.
+ Systems like Debian that have the old yesod 1.0.1 should set
+ GIT_ANNEX_LOCAL_FEATURES=-DWITH_OLD_YESOD
+ * copy: Avoid updating the location log when no copy is performed.
+ * configure: Test that uuid -m works, falling back to plain uuid if not.
+ * Avoid building the webapp on Debian architectures that do not yet
+ have template haskell and thus yesod. (Should be available for arm soonish
+ I hope).
+
+ -- Joey Hess <joeyh@debian.org> Mon, 01 Oct 2012 13:56:55 -0400
+
+git-annex (3.20120924) unstable; urgency=low
+
+ * assistant: New command, a daemon which does everything watch does,
+ as well as automatically syncing file contents between repositories.
+ * webapp: An interface for managing and configuring the assistant.
+ * The default backend used when adding files to the annex is changed
+ from SHA256 to SHA256E, to simplify interoperability with OSX, media
+ players, and various programs that needlessly look at symlink targets.
+ To get old behavior, add a .gitattributes containing: * annex.backend=SHA256
+ * init: If no description is provided for a new repository, one will
+ automatically be generated, like "joey@gnu:~/foo"
+ * test: Set a lot of git environment variables so testing works in strange
+ environments that normally need git config to set names, etc.
+ Closes: #682351 Thanks, gregor herrmann
+ * Disable ssh connection caching if the path to the control socket would be
+ too long (and use relative path to minimise path to the control socket).
+ * migrate: Check content before generating the new key, to avoid generating
+ a key for corrupt data.
+ * Support repositories created with --separate-git-dir. Closes: #684405
+ * reinject: When the provided file doesn't match, leave it where it is,
+ rather than moving to .git/annex/bad/
+ * Avoid crashing on encoding errors in filenames when writing transfer info
+ files and reading from checksum commands.
+ * sync: Pushes the git-annex branch to remote/synced/git-annex, rather
+ than directly to remote/git-annex.
+ * Now supports matching files that are present on a number of remotes
+ with a specified trust level. Example: --copies=trusted:2
+ Thanks, Nicolas Pouillard
+
+ -- Joey Hess <joeyh@debian.org> Mon, 24 Sep 2012 13:47:48 -0400
+
+git-annex (3.20120825) unstable; urgency=low
+
+ * S3: Add fileprefix setting.
+ * Pass --use-agent to gpg when in no tty mode. Thanks, Eskild Hustvedt.
+ * Bugfix: Fix fsck in SHA*E backends, when the key contains composite
+ extensions, as added in 3.20120721.
+
+ -- Joey Hess <joeyh@debian.org> Sat, 25 Aug 2012 10:00:10 -0400
+
+git-annex (3.20120807) unstable; urgency=low
+
+ * initremote: Avoid recording remote's description before checking
+ that its config is valid.
+ * unused, status: Avoid crashing when ran in bare repo.
+ * Avoid crashing when "git annex get" fails to download from one
+ location, and falls back to downloading from a second location.
+
+ -- Joey Hess <joeyh@debian.org> Tue, 07 Aug 2012 13:35:07 -0400
+
+git-annex (3.20120721) unstable; urgency=low
+
+ * get, move, copy: Now refuse to do anything when the requested file
+ transfer is already in progress by another process.
+ * status: Lists transfers that are currently in progress.
+ * Fix passing --uuid to git-annex-shell.
+ * When shaNsum commands cannot be found, use the Haskell SHA library
+ (already a dependency) to do the checksumming. This may be slower,
+ but avoids portability problems.
+ * Use SHA library for files less than 50 kb in size, at which point it's
+ faster than forking the more optimised external program.
+ * SHAnE backends are now smarter about composite extensions, such as
+ .tar.gz Closes: #680450
+ * map: Write map.dot to .git/annex, which avoids watch trying to annex it.
+
+ -- Joey Hess <joeyh@debian.org> Sat, 21 Jul 2012 16:52:48 -0400
+
+git-annex (3.20120629) unstable; urgency=low
+
+ * cabal: Only try to use inotify on Linux.
+ * Version build dependency on STM, and allow building without it,
+ which disables the watch command.
+ * Avoid ugly failure mode when moving content from a local repository
+ that is not available.
+ * Got rid of the last place that did utf8 decoding.
+ * Accept arbitrarily encoded repository filepaths etc when reading
+ git config output. This fixes support for remotes with unusual characters
+ in their names.
+ * sync: Automatically resolves merge conflicts.
+
+ -- Joey Hess <joeyh@debian.org> Fri, 29 Jun 2012 10:17:49 -0400
+
+git-annex (3.20120624) unstable; urgency=low
+
+ * watch: New subcommand, a daemon which notices changes to
+ files and automatically annexes new files, etc, so you don't
+ need to manually run git commands when manipulating files.
+ Available on Linux, BSDs, and OSX!
+ * Enable diskfree on kfreebsd, using kqueue.
+ * unused: Fix crash when key names contain invalid utf8.
+ * sync: Avoid recent git's interactive merge.
+
+ -- Joey Hess <joeyh@debian.org> Sun, 24 Jun 2012 12:36:50 -0400
+
+git-annex (3.20120614) unstable; urgency=medium
+
+ * addurl: Was broken by a typo introduced 2 released ago, now fixed.
+ Closes: #677576
+ * Install man page when run by cabal, in a location where man will
+ find it, even when installing under $HOME. Thanks, Nathan Collins
+
+ -- Joey Hess <joeyh@debian.org> Thu, 14 Jun 2012 20:21:29 -0400
+
+git-annex (3.20120611) unstable; urgency=medium
+
+ * add: Prevent (most) modifications from being made to a file while it
+ is being added to the annex.
+ * initremote: Automatically describe a remote when creating it.
+ * uninit: Refuse to run in a subdirectory. Closes: #677076
+
+ -- Joey Hess <joeyh@debian.org> Mon, 11 Jun 2012 10:32:01 -0400
+
+git-annex (3.20120605) unstable; urgency=low
+
+ * sync: Show a nicer message if a user tries to sync to a special remote.
+ * lock: Reset unlocked file to index, rather than to branch head.
+ * import: New subcommand, pulls files from a directory outside the annex
+ and adds them.
+ * Fix display of warning message when encountering a file that uses an
+ unsupported backend.
+ * Require that the SHA256 backend can be used when building, since it's the
+ default.
+ * Preserve parent environment when running hooks of the hook special remote.
+
+ -- Joey Hess <joeyh@debian.org> Tue, 05 Jun 2012 14:03:39 -0400
+
+git-annex (3.20120522) unstable; urgency=low
+
+ * Pass -a to cp even when it supports --reflink=auto, to preserve
+ permissions.
+ * Clean up handling of git directory and git worktree.
+ * Add support for core.worktree, and fix support for GIT_WORK_TREE and
+ GIT_DIR.
+
+ -- Joey Hess <joeyh@debian.org> Tue, 22 May 2012 11:16:13 -0400
+
+git-annex (3.20120511) unstable; urgency=low
+
+ * Rsync special remotes can be configured with shellescape=no
+ to avoid shell quoting that is normally done when using rsync over ssh.
+ This is known to be needed for certian rsync hosting providers
+ (specificially hidrive.strato.com) that use rsync over ssh but do not
+ pass it through the shell.
+ * dropunused: Allow specifying ranges to drop.
+ * addunused: New command, the opposite of dropunused, it relinks unused
+ content into the git repository.
+ * Fix use of several config settings: annex.ssh-options,
+ annex.rsync-options, annex.bup-split-options. (And adjust types to avoid
+ the bugs that broke several config settings.)
+
+ -- Joey Hess <joeyh@debian.org> Fri, 11 May 2012 12:29:30 -0400
+
+git-annex (3.20120430) unstable; urgency=low
+
+ * Fix use of annex.diskreserve config setting.
+ * Directory special remotes now check annex.diskreserve.
+ * Support git's core.sharedRepository configuration.
+ * Add annex.http-headers and annex.http-headers-command config
+ settings, to allow custom headers to be sent with all HTTP requests.
+ (Requested by the Internet Archive)
+ * uninit: Clear annex.uuid from .git/config. Closes: #670639
+ * Added shared cipher mode to encryptable special remotes. This option
+ avoids gpg key distribution, at the expense of flexability, and with
+ the requirement that all clones of the git repository be equally trusted.
+
+ -- Joey Hess <joeyh@debian.org> Mon, 30 Apr 2012 13:16:10 -0400
+
+git-annex (3.20120418) unstable; urgency=low
+
+ * bugfix: Adding a dotfile also caused all non-dotfiles to be added.
+ * bup: Properly handle key names with spaces or other things that are
+ not legal git refs.
+ * git-annex (but not git-annex-shell) supports the git help.autocorrect
+ configuration setting, doing fuzzy matching using the restricted
+ Damerau-Levenshtein edit distance, just as git does. This adds a build
+ dependency on the haskell edit-distance library.
+ * Renamed diskfree.c to avoid OSX case insensativity bug.
+ * cabal now installs git-annex-shell as a symlink to git-annex.
+ * cabal file now autodetects whether S3 support is available.
+
+ -- Joey Hess <joeyh@debian.org> Wed, 18 Apr 2012 12:11:32 -0400
+
+git-annex (3.20120406) unstable; urgency=low
+
+ * Disable diskfree on kfreebsd, as I have a build failure on kfreebsd-i386
+ that is quite likely caused by it.
+
+ -- Joey Hess <joeyh@debian.org> Sat, 07 Apr 2012 15:50:36 -0400
+
+git-annex (3.20120405) unstable; urgency=low
+
+ * Rewrote free disk space checking code, moving the portability
+ handling into a small C library.
+ * status: Display amount of free disk space.
+
+ -- Joey Hess <joeyh@debian.org> Thu, 05 Apr 2012 16:19:10 -0400
+
+git-annex (3.20120315) unstable; urgency=low
+
+ * fsck: Fix up any broken links and misplaced content caused by the
+ directory hash calculation bug fixed in the last release.
+ * sync: Sync to lower cost remotes first.
+ * status: Fixed to run in constant space.
+ * status: More accurate display of sizes of tmp and bad keys.
+ * unused: Now uses a bloom filter, and runs in constant space.
+ Use of a bloom filter does mean it will not notice a small
+ number of unused keys. For repos with up to half a million keys,
+ it will miss one key in 1000.
+ * Added annex.bloomcapacity and annex.bloomaccuracy, which can be
+ adjusted as desired to tune the bloom filter.
+ * status: Display amount of memory used by bloom filter, and
+ detect when it's too small for the number of keys in a repository.
+ * git-annex-shell: Runs hooks/annex-content after content is received
+ or dropped.
+ * Work around a bug in rsync (IMHO) introduced by openSUSE's SIP patch.
+ * git-annex now behaves as git-annex-shell if symlinked to and run by that
+ name. The Makefile sets this up, saving some 8 mb of installed size.
+ * git-union-merge is a demo program, so it is no longer built by default.
+
+ -- Joey Hess <joeyh@debian.org> Thu, 15 Mar 2012 11:05:28 -0400
+
+git-annex (3.20120309) unstable; urgency=low
+
+ * Fix key directory hash calculation code to behave as it did before
+ version 3.20120227 when a key contains non-ascii characters (only
+ WORM backend is likely to have been affected).
+
+ -- Joey Hess <joeyh@debian.org> Fri, 09 Mar 2012 20:05:09 -0400
+
+git-annex (3.20120230) unstable; urgency=low
+
+ * "here" can be used to refer to the current repository,
+ which can read better than the old "." (which still works too).
+ * Directory special remotes now support chunking files written to them,
+ avoiding writing files larger than a specified size.
+ * Add progress bar display to the directory special remote.
+ * Add configurable hooks that are run when git-annex starts and stops
+ using a remote: remote.name.annex-start-command and
+ remote.name.annex-stop-command
+ * Fix a bug in symlink calculation code, that triggered in rare
+ cases where an annexed file is in a subdirectory that nearly
+ matched to the .git/annex/object/xx/yy subdirectories.
+
+ -- Joey Hess <joeyh@debian.org> Mon, 05 Mar 2012 13:38:13 -0400
+
+git-annex (3.20120229) unstable; urgency=low
+
+ * Fix test suite to not require a unicode locale.
+ * Fix cabal build failure. Thanks, Sergei Trofimovich
+
+ -- Joey Hess <joeyh@debian.org> Wed, 29 Feb 2012 02:31:31 -0400
+
+git-annex (3.20120227) unstable; urgency=low
+
+ * Modifications to support ghc 7.4's handling of filenames.
+ This version can only be built with ghc 7.4 or newer. See the ghc7.0
+ branch for older ghcs.
+ * S3: Fix irrefutable pattern failure when accessing encrypted S3
+ credentials.
+ * Use the haskell IfElse library.
+ * Fix teardown of stale cached ssh connections.
+ * Fixed to use the strict state monad, to avoid leaking all kinds of memory
+ due to lazy state update thunks when adding/fixing many files.
+ * Fixed some memory leaks that occurred when committing journal files.
+ * Added a annex.queuesize setting, useful when adding hundreds of thousands
+ of files on a system with plenty of memory.
+ * whereis: Prints the urls of files that the web special remote knows about.
+ * addurl --fast: Verifies that the url can be downloaded (only getting
+ its head), and records the size in the key.
+ * When checking that an url has a key, verify that the Content-Length,
+ if available, matches the size of the key.
+ * addurl: Added a --file option, which can be used to specify what
+ file the url is added to. This can be used to override the default
+ filename that is used when adding an url, which is based on the url.
+ Or, when the file already exists, the url is recorded as another
+ location of the file.
+ * addurl: Normalize badly encoded urls.
+ * addurl: Add --pathdepth option.
+ * rekey: New plumbing level command, can be used to change the keys used
+ for files en masse.
+ * Store web special remote url info in a more efficient location.
+ (Urls stored with this version will not be visible to older versions.)
+ * Deal with NFS problem that caused a failure to remove a directory
+ when removing content from the annex.
+ * Make a single location log commit after a remote has received or
+ dropped files. Uses a new "git-annex-shell commit" command when available.
+ * To avoid commits of data to the git-annex branch after each command
+ is run, set annex.alwayscommit=false. Its data will then be committed
+ less frequently, when a merge or sync is done.
+ * configure: Check if ssh connection caching is supported by the installed
+ version of ssh and default annex.sshcaching accordingly.
+ * move --from, copy --from: Now 10 times faster when scanning to find
+ files in a remote on a local disk; rather than go through the location log
+ to see which files are present on the remote, it simply looks at the
+ disk contents directly.
+
+ -- Joey Hess <joeyh@debian.org> Mon, 27 Feb 2012 12:58:21 -0400
+
+git-annex (3.20120123) unstable; urgency=low
+
+ * fsck --from: Fscking a remote is now supported. It's done by retrieving
+ the contents of the specified files from the remote, and checking them,
+ so can be an expensive operation. Still, if the remote is a special
+ remote, or a git repository that you cannot run fsck in locally, it's
+ nice to have the ability to fsck it.
+ * If you have any directory special remotes, now would be a good time to
+ fsck them, in case you were hit by the data loss bug fixed in the
+ previous release!
+ * fsck --from remote --fast: Avoids expensive file transfers, at the
+ expense of not checking file size and/or contents.
+ * Ssh connection caching is now enabled automatically by git-annex.
+ Only one ssh connection is made to each host per git-annex run, which
+ can speed some things up a lot, as well as avoiding repeated password
+ prompts. Concurrent git-annex processes also share ssh connections.
+ Cached ssh connections are shut down when git-annex exits.
+ * To disable the ssh caching (if for example you have your own broader
+ ssh caching configuration), set annex.sshcaching=false.
+
+ -- Joey Hess <joeyh@debian.org> Mon, 23 Jan 2012 13:48:48 -0400
+
+git-annex (3.20120116) unstable; urgency=medium
+
+ * Fix data loss bug in directory special remote, when moving a file
+ to the remote failed, and partially transferred content was left
+ behind in the directory, re-running the same move would think it
+ succeeded and delete the local copy.
+
+ -- Joey Hess <joeyh@debian.org> Mon, 16 Jan 2012 16:43:45 -0400
+
+git-annex (3.20120115) unstable; urgency=low
+
+ * Add a sanity check for bad StatFS results. On architectures
+ where StatFS does not currently work (s390, mips, powerpc, sparc),
+ this disables the diskreserve checking code, and attempting to
+ configure an annex.diskreserve will result in an error.
+ * Fix QuickCheck dependency in cabal file.
+ * Minor optimisations.
+
+ -- Joey Hess <joeyh@debian.org> Sun, 15 Jan 2012 13:54:20 -0400
+
+git-annex (3.20120113) unstable; urgency=low
+
+ * log: Add --gource mode, which generates output usable by gource.
+ * map: Fix display of remote repos
+ * Add annex-trustlevel configuration settings, which can be used to
+ override the trust level of a remote.
+ * git-annex, git-union-merge: Support GIT_DIR and GIT_WORK_TREE.
+ * Add libghc-testpack-dev to build depends on all arches.
+
+ -- Joey Hess <joeyh@debian.org> Fri, 13 Jan 2012 15:35:17 -0400
+
+git-annex (3.20120106) unstable; urgency=low
+
+ * Support unescaped repository urls, like git does.
+ * log: New command that displays the location log for files,
+ showing each repository they were added to and removed from.
+ * Fix overbroad gpg --no-tty fix from last release.
+
+ -- Joey Hess <joeyh@debian.org> Sat, 07 Jan 2012 13:16:23 -0400
+
+git-annex (3.20120105) unstable; urgency=low
+
+ * Added annex-web-options configuration settings, which can be
+ used to provide parameters to whichever of wget or curl git-annex uses
+ (depends on which is available, but most of their important options
+ suitable for use here are the same).
+ * Dotfiles, and files inside dotdirs are not added by "git annex add"
+ unless the dotfile or directory is explicitly listed. So "git annex add ."
+ will add all untracked files in the current directory except for those in
+ dotdirs.
+ * Added quickcheck to build dependencies, and fail if test suite cannot be
+ built.
+ * fsck: Do backend-specific check before checking numcopies is satisfied.
+ * Run gpg with --no-tty. Closes: #654721
+
+ -- Joey Hess <joeyh@debian.org> Thu, 05 Jan 2012 13:44:12 -0400
+
+git-annex (3.20111231) unstable; urgency=low
+
+ * sync: Improved to work well without a central bare repository.
+ Thanks to Joachim Breitner.
+ * Rather than manually committing, pushing, pulling, merging, and git annex
+ merging, we encourage you to give "git annex sync" a try.
+ * sync --fast: Selects some of the remotes with the lowest annex.cost
+ and syncs those, in addition to any specified at the command line.
+ * Union merge now finds the least expensive way to represent the merge.
+ * reinject: Add a sanity check for using an annexed file as the source file.
+ * Properly handle multiline git config values.
+ * Fix the hook special remote, which bitrotted a while ago.
+ * map: --fast disables use of dot to display map
+ * Test suite improvements. Current top-level test coverage: 75%
+ * Improve deletion of files from rsync special remotes. Closes: #652849
+ * Add --include, which is the same as --not --exclude.
+ * Format strings can be specified using the new --format option, to control
+ what is output by git annex find.
+ * Support git annex find --json
+ * Fixed behavior when multiple insteadOf configs are provided for the
+ same url base.
+ * Can now be built with older git versions (before 1.7.7); the resulting
+ binary should only be used with old git.
+ * Updated to build with monad-control 0.3.
+
+ -- Joey Hess <joeyh@debian.org> Sat, 31 Dec 2011 14:55:29 -0400
+
+git-annex (3.20111211) unstable; urgency=medium
+
+ * Fix bug in last version in getting contents from bare repositories.
+ * Ensure that git-annex branch changes are merged into git-annex's index,
+ which fixes a bug that could cause changes that were pushed to the
+ git-annex branch to get reverted. As a side effect, it's now safe
+ for users to check out and commit changes directly to the git-annex
+ branch.
+ * map: Fix a failure to detect a loop when both repositories are local
+ and refer to each other with relative paths.
+ * Prevent key names from containing newlines.
+ * add: If interrupted, add can leave files converted to symlinks but not
+ yet added to git. Running the add again will now clean up this situtation.
+ * Fix caching of decrypted ciphers, which failed when drop had to check
+ multiple different encrypted special remotes.
+ * unannex: Can be run on files that have been added to the annex, but not
+ yet committed.
+ * sync: New command that synchronises the local repository and default
+ remote, by running git commit, pull, and push for you.
+ * Version monad-control dependency in cabal file.
+
+ -- Joey Hess <joeyh@debian.org> Sun, 11 Dec 2011 21:24:39 -0400
+
+git-annex (3.20111203) unstable; urgency=low
+
+ * The VFAT filesystem on recent versions of Linux, when mounted with
+ shortname=mixed, does not get along well with git-annex's mixed case
+ .git/annex/objects hash directories. To avoid this problem, new content
+ is now stored in all-lowercase hash directories. Except for non-bare
+ repositories which would be a pain to transition and cannot be put on FAT.
+ (Old mixed-case hash directories are still tried for backwards
+ compatibility.)
+ * Flush json output, avoiding a buffering problem that could result in
+ doubled output.
+ * Avoid needing haskell98 and other fixes for new ghc. Thanks, Mark Wright.
+ * Bugfix: dropunused did not drop keys with two spaces in their name.
+ * Support for storing .git/annex on a different device than the rest of the
+ git repository.
+ * --inbackend can be used to make git-annex only operate on files
+ whose content is stored using a specified key-value backend.
+ * dead: A command which says that a repository is gone for good
+ and you don't want git-annex to mention it again.
+
+ -- Joey Hess <joeyh@debian.org> Sat, 03 Dec 2011 21:01:45 -0400
+
+git-annex (3.20111122) unstable; urgency=low
+
+ * merge: Improve commit messages to mention what was merged.
+ * Avoid doing auto-merging in commands that don't need fully current
+ information from the git-annex branch. In particular, git annex add
+ no longer needs to auto-merge.
+ * init: When run in an already initalized repository, and without
+ a description specified, don't delete the old description.
+ * Optimised union merging; now only runs git cat-file once, and runs
+ in constant space.
+ * status: Now displays trusted, untrusted, and semitrusted repositories
+ separately.
+ * status: Include all special remotes in the list of repositories.
+ * status: Fix --json mode.
+ * status: --fast is back
+ * Fix support for insteadOf url remapping. Closes: #644278
+ * When not run in a git repository, git-annex can still display a usage
+ message, and "git annex version" even works.
+ * migrate: Don't fall over a stale temp file.
+ * Avoid excessive escaping for rsync special remotes that are not accessed
+ over ssh.
+ * find: Support --print0
+
+ -- Joey Hess <joeyh@debian.org> Tue, 22 Nov 2011 14:31:45 -0400
+
+git-annex (3.20111111) unstable; urgency=low
+
+ * Handle a case where an annexed file is moved into a gitignored directory,
+ by having fix --force add its change.
+ * Avoid cyclic drop problems.
+ * Optimized copy --from and get --from to avoid checking the location log
+ for files that are already present.
+ * Automatically fix up badly formatted uuid.log entries produced by
+ 3.20111105, whenever the uuid.log is changed (ie, by init or describe).
+ * map: Support remotes with /~/ and /~user/
+
+ -- Joey Hess <joeyh@debian.org> Fri, 11 Nov 2011 13:44:18 -0400
+
+git-annex (3.20111107) unstable; urgency=low
+
+ * merge: Use fast-forward merges when possible.
+ Thanks Valentin Haenel for a test case showing how non-fast-forward
+ merges could result in an ongoing pull/merge/push cycle.
+ * Don't try to read config from repos with annex-ignore set.
+ * Bugfix: In the past two releases, git-annex init has written the uuid.log
+ in the wrong format, with the UUID and description flipped.
+
+ -- Joey Hess <joeyh@debian.org> Mon, 07 Nov 2011 12:47:44 -0400
+
+git-annex (3.20111105) unstable; urgency=low
+
+ * The default backend used when adding files to the annex is changed
+ from WORM to SHA256.
+ To get old behavior, add a .gitattributes containing: * annex.backend=WORM
+ * Sped up some operations on remotes that are on the same host.
+ * copy --to: Fixed leak when copying many files to a remote on the same
+ host.
+ * uninit: Add guard against being run with the git-annex branch checked out.
+ * Fail if --from or --to is passed to commands that do not support them.
+ * drop --from is now supported to remove file content from a remote.
+ * status: Now always shows the current repository, even when it does not
+ appear in uuid.log.
+ * fsck: Now works in bare repositories. Checks location log information,
+ and file contents. Does not check that numcopies is satisfied, as
+ .gitattributes information about numcopies is not available in a bare
+ repository.
+ * unused, dropunused: Now work in bare repositories.
+ * Removed the setkey command, and added a reinject command with a more
+ useful interface.
+ * The fromkey command now takes the key as its first parameter. The --key
+ option is no longer used.
+ * Built without any filename containing .git being excluded. Closes: #647215
+ * Record uuid when auto-initializing a remote so it shows in status.
+ * Bugfix: Fixed git-annex init crash in a bare repository when there was
+ already an existing git-annex branch.
+ * Pass -t to rsync to preserve timestamps.
+
+ -- Joey Hess <joeyh@debian.org> Sat, 05 Nov 2011 15:47:52 -0400
+
+git-annex (3.20111025) unstable; urgency=low
+
+ * A remote can have a annexUrl configured, that is used by git-annex
+ instead of its usual url. (Similar to pushUrl.)
+ * migrate: Copy url logs for keys when migrating.
+ * git-annex-shell: GIT_ANNEX_SHELL_READONLY and GIT_ANNEX_SHELL_LIMITED
+ environment variables can be set to limit what commands can be run.
+ This is used by gitolite's new git-annex support!
+
+ -- Joey Hess <joeyh@debian.org> Tue, 25 Oct 2011 13:03:08 -0700
+
+git-annex (3.20111011) unstable; urgency=low
+
+ * This version of git-annex only works with git 1.7.7 and newer.
+ The breakage with old versions is subtle, and affects the
+ annex.numcopies settings in .gitattributes, so be sure to upgrade git
+ to 1.7.7. (Debian package now depends on that version.)
+ * Don't pass absolute paths to git show-attr, as it started following
+ symlinks when that's done in 1.7.7. Instead, use relative paths,
+ which show-attr only handles 100% correctly in 1.7.7. Closes: #645046
+ * Fix referring to remotes by uuid.
+ * New or changed repository descriptions in uuid.log now have a timestamp,
+ which is used to ensure the newest description is used when the uuid.log
+ has been merged.
+ * Note that older versions of git-annex will display the timestamp as part
+ of the repository description, which is ugly but otherwise harmless.
+ * Add timestamps to trust.log and remote.log too.
+ * git-annex-shell: Added the --uuid option.
+ * git-annex now asks git-annex-shell to verify that it's operating in
+ the expected repository.
+ * Note that this git-annex will not interoperate with remotes using
+ older versions of git-annex-shell.
+ * Now supports git's insteadOf configuration, to modify the url
+ used to access a remote. Note that pushInsteadOf is not used;
+ that and pushurl are reserved for actual git pushes. Closes: #644278
+ * status: List all known repositories.
+ * When displaying a list of repositories, show git remote names
+ in addition to their descriptions.
+ * Add locking to avoid races when changing the git-annex branch.
+ * Various speed improvements gained by using ByteStrings.
+ * Contain the zombie hordes.
+
+ -- Joey Hess <joeyh@debian.org> Tue, 11 Oct 2011 23:00:02 -0400
+
+git-annex (3.20110928) unstable; urgency=low
+
+ * --in can be used to make git-annex only operate on files
+ believed to be present in a given repository.
+ * Arbitrarily complex expressions can be built to limit the files git-annex
+ operates on, by combining the options --not --and --or -( and -)
+ Example: git annex get --exclude '*.mp3' --and --not -( --in usbdrive --or --in archive -)
+ * --copies=N can be used to make git-annex only operate on files with
+ the specified number of copies. (And --not --copies=N for the inverse.)
+ * find: Rather than only showing files whose contents are present,
+ when used with --exclude --copies or --in, displays all files that
+ match the specified conditions.
+ * Note that this is a behavior change for git-annex find! Old behavior
+ can be gotten by using: git-annex find --in .
+ * status: Massively sped up; remove --fast mode.
+ * unused: File contents used by branches and tags are no longer
+ considered unused, even when not used by the current branch. This is
+ the final piece of the puzzle needed for git-annex to to play nicely
+ with branches.
+
+ -- Joey Hess <joeyh@debian.org> Wed, 28 Sep 2011 18:14:02 -0400
+
+git-annex (3.20110915) unstable; urgency=low
+
+ * whereis: Show untrusted locations separately and do not include in
+ location count.
+ * Fix build without S3.
+ * addurl: Always use whole url as destination filename, rather than
+ only its file component.
+ * get, drop, copy: Added --auto option, which decides whether
+ to get/drop content as needed to work toward the configured numcopies.
+ * bugfix: drop and fsck did not honor --exclude
+
+ -- Joey Hess <joeyh@debian.org> Thu, 15 Sep 2011 22:25:46 -0400
+
+git-annex (3.20110906) unstable; urgency=low
+
+ * Improve display of newlines around error and warning messages.
+ * Fix Makefile to work with cabal again.
+
+ -- Joey Hess <joeyh@debian.org> Tue, 06 Sep 2011 13:45:16 -0400
+
+git-annex (3.20110902) unstable; urgency=low
+
+ * Set EMAIL when running test suite so that git does not need to be
+ configured first. Closes: #638998
+ * The wget command will now be used in preference to curl, if available.
+ * init: Make description an optional parameter.
+ * unused, status: Sped up by avoiding unnecessary stats of annexed files.
+ * unused --remote: Reduced memory use to 1/4th what was used before.
+ * Add --json switch, to produce machine-consumable output.
+
+ -- Joey Hess <joeyh@debian.org> Fri, 02 Sep 2011 21:20:37 -0400
+
+git-annex (3.20110819) unstable; urgency=low
+
+ * Now "git annex init" only has to be run once, when a git repository
+ is first being created. Clones will automatically notice that git-annex
+ is in use and automatically perform a basic initalization. It's
+ still recommended to run "git annex init" in any clones, to describe them.
+ * Added annex-cost-command configuration, which can be used to vary the
+ cost of a remote based on the output of a shell command.
+ * Fix broken upgrade from V1 repository. Closes: #638584
+
+ -- Joey Hess <joeyh@debian.org> Fri, 19 Aug 2011 20:34:09 -0400
+
+git-annex (3.20110817) unstable; urgency=low
+
+ * Fix shell escaping in rsync special remote.
+ * addurl: --fast can be used to avoid immediately downloading the url.
+ * Added support for getting content from git remotes using http (and https).
+ * Added curl to Debian package dependencies.
+
+ -- Joey Hess <joeyh@debian.org> Wed, 17 Aug 2011 01:29:02 -0400
+
+git-annex (3.20110719) unstable; urgency=low
+
+ * add: Be even more robust to avoid ever leaving the file seemingly deleted.
+ Closes: #634233
+ * Bugfix: Make add ../ work.
+ * Support the standard git -c name=value
+ * unannex: Clean up use of git commit -a.
+
+ -- Joey Hess <joeyh@debian.org> Tue, 19 Jul 2011 23:39:53 -0400
+
+git-annex (3.20110707) unstable; urgency=low
+
+ * Fix sign bug in disk free space checking.
+ * Bugfix: Forgot to de-escape keys when upgrading. Could result in
+ bad location log data for keys that contain [&:%] in their names.
+ (A workaround for this problem is to run git annex fsck.)
+ * add: Avoid a failure mode that resulted in the file seemingly being
+ deleted (content put in the annex but no symlink present).
+
+ -- Joey Hess <joeyh@debian.org> Thu, 07 Jul 2011 19:29:39 -0400
+
+git-annex (3.20110705) unstable; urgency=low
+
+ * uninit: Delete the git-annex branch and .git/annex/
+ * unannex: In --fast mode, file content is left in the annex, and a
+ hard link made to it.
+ * uninit: Use unannex in --fast mode, to support unannexing multiple
+ files that link to the same content.
+ * Drop the dependency on the haskell curl bindings, use regular haskell HTTP.
+ * Fix a pipeline stall when upgrading (caused by #624389).
+
+ -- Joey Hess <joeyh@debian.org> Tue, 05 Jul 2011 14:37:39 -0400
+
+git-annex (3.20110702) unstable; urgency=low
+
+ * Now the web can be used as a special remote.
+ This feature replaces the old URL backend.
+ * addurl: New command to download an url and store it in the annex.
+ * Sped back up fsck, copy --from, and other commands that often
+ have to read a lot of information from the git-annex branch. Such
+ commands are now faster than they were before introduction of the
+ git-annex branch.
+ * Always ensure git-annex branch exists.
+ * Modify location log parser to allow future expansion.
+ * --force will cause add, etc, to operate on ignored files.
+ * Avoid mangling encoding when storing the description of repository
+ and other content.
+ * cabal can now be used to build git-annex. This is substantially
+ slower than using make, does not build or install documentation,
+ does not run the test suite, and is not particularly recommended,
+ but could be useful to some.
+
+ -- Joey Hess <joeyh@debian.org> Sat, 02 Jul 2011 15:00:18 -0400
+
+git-annex (3.20110624) experimental; urgency=low
+
+ * New repository format, annex.version=3. Use `git annex upgrade` to migrate.
+ * git-annex now stores its logs in a git-annex branch.
+ * merge: New subcommand. Auto-merges the new git-annex branch.
+ * Improved handling of bare git repos with annexes. Many more commands will
+ work in them.
+ * git-annex is now more robust; it will never leave state files
+ uncommitted when some other git process comes along and locks the index
+ at an inconvenient time.
+ * rsync is now used when copying files from repos on other filesystems.
+ cp is still used when copying file from repos on the same filesystem,
+ since --reflink=auto can make it significantly faster on filesystems
+ such as btrfs.
+ * Allow --trust etc to specify a repository by name, for temporarily
+ trusting repositories that are not configured remotes.
+ * unlock: Made atomic.
+ * git-union-merge: New git subcommand, that does a generic union merge
+ operation, and operates efficiently without touching the working tree.
+
+ -- Joey Hess <joeyh@debian.org> Fri, 24 Jun 2011 14:32:18 -0400
+
+git-annex (0.20110610) unstable; urgency=low
+
+ * Add --numcopies option.
+ * Add --trust, --untrust, and --semitrust options.
+ * get --from is the same as copy --from
+ * Bugfix: Fix fsck to not think all SHAnE keys are bad.
+
+ -- Joey Hess <joeyh@debian.org> Fri, 10 Jun 2011 11:48:40 -0400
+
+git-annex (0.20110601) unstable; urgency=low
+
+ * Minor bugfixes and error message improvements.
+ * Massively sped up `git annex lock` by avoiding use of the uber-slow
+ `git reset`, and only running `git checkout` once, even when many files
+ are being locked.
+ * Fix locking of files with staged changes.
+ * Somewhat sped up `git commit` of modifications to unlocked files.
+ * Build fix for older ghc.
+
+ -- Joey Hess <joeyh@debian.org> Wed, 01 Jun 2011 11:50:47 -0400
+
+git-annex (0.20110522) unstable; urgency=low
+
+ * Closer emulation of git's behavior when told to use "foo/.git" as a
+ git repository instead of just "foo". Closes: #627563
+ * Fix bug in --exclude introduced in 0.20110516.
+
+ -- Joey Hess <joeyh@debian.org> Fri, 27 May 2011 20:20:41 -0400
+
+git-annex (0.20110521) unstable; urgency=low
+
+ * status: New subcommand to show info about an annex, including its size.
+ * --backend now overrides any backend configured in .gitattributes files.
+ * Add --debug option. Closes: #627499
+
+ -- Joey Hess <joeyh@debian.org> Sat, 21 May 2011 11:52:53 -0400
+
+git-annex (0.20110516) unstable; urgency=low
+
+ * Add a few tweaks to make it easy to use the Internet Archive's variant
+ of S3. In particular, munge key filenames to comply with the IA's filename
+ limits, disable encryption, support their nonstandard way of creating
+ buckets, and allow x-archive-* headers to be specified in initremote to
+ set item metadata.
+ * Added filename extension preserving variant backends SHA1E, SHA256E, etc.
+ * migrate: Use current filename when generating new key, for backends
+ where the filename affects the key name.
+ * Work around a bug in Network.URI's handling of bracketed ipv6 addresses.
+
+ -- Joey Hess <joeyh@debian.org> Mon, 16 May 2011 14:16:52 -0400
+
+git-annex (0.20110503) unstable; urgency=low
+
+ * Fix hasKeyCheap setting for bup and rsync special remotes.
+ * Add hook special remotes.
+ * Avoid crashing when an existing key is readded to the annex.
+ * unused: Now also lists files fsck places in .git/annex/bad/
+ * S3: When encryption is enabled, the Amazon S3 login credentials
+ are stored, encrypted, in .git-annex/remotes.log, so environment
+ variables need not be set after the remote is initialized.
+
+ -- Joey Hess <joeyh@debian.org> Tue, 03 May 2011 20:56:01 -0400
+
+git-annex (0.20110427) unstable; urgency=low
+
+ * Switch back to haskell SHA library, so git-annex remains buildable on
+ Debian stable.
+ * Added rsync special remotes. This could be used, for example, to
+ store annexed content on rsync.net (encrypted naturally). Or anywhere else.
+ * Bugfix: Avoid pipeline stall when running git annex drop or fsck on a
+ lot of files. Possibly only occured with ghc 7.
+
+ -- Joey Hess <joeyh@debian.org> Wed, 27 Apr 2011 22:50:26 -0400
+
+git-annex (0.20110425) unstable; urgency=low
+
+ * Use haskell Crypto library instead of haskell SHA library.
+ * Remove testpack from build depends for non x86 architectures where it
+ is not available. The test suite will not be run if it cannot be compiled.
+ * Avoid using absolute paths when staging location log, as that can
+ confuse git when a remote's path contains a symlink. Closes: #621386
+
+ -- Joey Hess <joeyh@debian.org> Mon, 25 Apr 2011 15:47:00 -0400
+
+git-annex (0.20110420) unstable; urgency=low
+
+ * Update Debian build dependencies for ghc 7.
+ * Debian package is now built with S3 support.
+ Thanks Joachim Breitner for making this possible.
+ * Somewhat improved memory usage of S3, still work to do.
+ Thanks Greg Heartsfield for ongoing work to improve the hS3 library
+ for git-annex.
+
+ -- Joey Hess <joeyh@debian.org> Thu, 21 Apr 2011 15:00:48 -0400
+
+git-annex (0.20110419) unstable; urgency=low
+
+ * Don't run gpg in batch mode, so it can prompt for passphrase when
+ there is no agent.
+ * Add missing build dep on dataenc.
+ * S3: Fix stalls when transferring encrypted data.
+ * bup: Avoid memory leak when transferring encrypted data.
+
+ -- Joey Hess <joeyh@debian.org> Tue, 19 Apr 2011 21:26:51 -0400
+
+git-annex (0.20110417) unstable; urgency=low
+
+ * bup is now supported as a special type of remote.
+ * The data sent to special remotes (Amazon S3, bup, etc) can be encrypted
+ using GPG for privacy.
+ * Use lowercase hash directories for locationlog files, to avoid
+ some issues with git on OSX with the mixed-case directories.
+ No migration is needed; the old mixed case hash directories are still
+ read; new information is written to the new directories.
+ * Unused files on remotes, particulary special remotes, can now be
+ identified and dropped, by using "--from remote" with git annex unused
+ and git annex dropunused.
+ * Clear up short option confusion between --from and --force (-f is now
+ --from, and there is no short option for --force).
+ * Add build depend on perlmagick so docs are consistently built.
+ Closes: #621410
+ * Add doc-base file. Closes: #621408
+ * Periodically flush git command queue, to avoid boating memory usage
+ too much.
+ * Support "sha1" and "sha512" commands on FreeBSD, and allow building
+ if any/all SHA commands are not available. Thanks, Fraser Tweedale
+
+ -- Joey Hess <joeyh@debian.org> Sun, 17 Apr 2011 12:00:24 -0400
+
+git-annex (0.20110401) experimental; urgency=low
+
+ * Amazon S3 is now supported as a special type of remote.
+ Warning: Encrypting data before sending it to S3 is not yet supported.
+ * Note that Amazon S3 support is not built in by default on Debian yet,
+ as hS3 is not packaged.
+ * fsck: Ensure that files and directories in .git/annex/objects
+ have proper permissions.
+ * Added a special type of remote called a directory remote, which
+ simply stores files in an arbitrary local directory.
+ * Bugfix: copy --to --fast never really copied, fixed.
+
+ -- Joey Hess <joeyh@debian.org> Fri, 01 Apr 2011 21:27:22 -0400
+
+git-annex (0.20110328) experimental; urgency=low
+
+ * annex.diskreserve can be given in arbitrary units (ie "0.5 gigabytes")
+ * Generalized remotes handling, laying groundwork for remotes that are
+ not regular git remotes. (Think Amazon S3.)
+ * Provide a less expensive version of `git annex copy --to`, enabled
+ via --fast. This assumes that location tracking information is correct,
+ rather than contacting the remote for every file.
+ * Bugfix: Keys could be received into v1 annexes from v2 annexes, via
+ v1 git-annex-shell. This results in some oddly named keys in the v1
+ annex. Recognise and fix those keys when upgrading, instead of crashing.
+
+ -- Joey Hess <joeyh@debian.org> Mon, 28 Mar 2011 10:47:29 -0400
+
+git-annex (0.20110325) experimental; urgency=low
+
+ * Free space checking is now done, for transfers of data for keys
+ that have free space metadata. (Notably, not for SHA* keys generated
+ with git-annex 0.2x or earlier.) The code is believed to work on
+ Linux, FreeBSD, and OSX; check compile-time messages to see if it
+ is not enabled for your OS.
+ * Add annex.diskreserve config setting, to control how much free space
+ to reserve for other purposes and avoid using (defaults to 1 mb).
+ * Add --fast flag, that can enable less expensive, but also less thorough
+ versions of some commands.
+ * fsck: In fast mode, avoid checking checksums.
+ * unused: In fast mode, just show all existing temp files as unused,
+ and avoid expensive scan for other unused content.
+ * migrate: Support migrating v1 SHA keys to v2 SHA keys with
+ size information that can be used for free space checking.
+ * Fix space leak in fsck and drop commands.
+ * migrate: Bugfix for case when migrating a file results in a key that
+ is already present in .git/annex/objects.
+ * dropunused: Significantly sped up; only read unused log file once.
+
+ -- Joey Hess <joeyh@debian.org> Fri, 25 Mar 2011 00:47:37 -0400
+
+git-annex (0.20110320) experimental; urgency=low
+
+ * Fix dropping of files using the URL backend.
+ * Fix support for remotes with '.' in their names.
+ * Add version command to show git-annex version as well as repository
+ version information.
+ * No longer auto-upgrade to repository format 2, to avoid accidental
+ upgrades, etc. Use git-annex upgrade when you're ready to run this
+ version.
+
+ -- Joey Hess <joeyh@debian.org> Sun, 20 Mar 2011 16:36:33 -0400
+
+git-annex (0.20110316) experimental; urgency=low
+
+ * New repository format, annex.version=2.
+ * The first time git-annex is run in an old format repository, it
+ will automatically upgrade it to the new format, staging all
+ necessary changes to git. Also added a "git annex upgrade" command.
+ * Colons are now avoided in filenames, so bare clones of git repos
+ can be put on USB thumb drives formatted with vFAT or similar
+ filesystems.
+ * Added two levels of hashing to object directory and .git-annex logs,
+ to improve scalability with enormous numbers of annexed
+ objects. (With one hundred million annexed objects, each
+ directory would contain fewer than 1024 files.)
+ * The setkey, fromkey, and dropkey subcommands have changed how
+ the key is specified. --backend is no longer used with these.
+
+ -- Joey Hess <joeyh@debian.org> Wed, 16 Mar 2011 16:20:23 -0400
+
+git-annex (0.24) unstable; urgency=low
+
+ Branched the 0.24 series, which will be maintained for a while to
+ support v1 git-annex repos, while main development moves to the 0.2011
+ series, with v2 git-annex repos.
+
+ * Add Suggests on graphviz. Closes: #618039
+ * When adding files to the annex, the symlinks pointing at the annexed
+ content are made to have the same mtime as the original file.
+ While git does not preserve that information, this allows a tool
+ like metastore to be used with annexed files.
+ (Currently this is only done on systems supporting POSIX 200809.)
+
+ -- Joey Hess <joeyh@debian.org> Wed, 16 Mar 2011 18:35:13 -0400
+
+git-annex (0.23) unstable; urgency=low
+
+ * Support ssh remotes with a port specified.
+ * whereis: New subcommand to show where a file's content has gotten to.
+ * Rethink filename encoding handling for display. Since filename encoding
+ may or may not match locale settings, any attempt to decode filenames
+ will fail for some files. So instead, do all output in binary mode.
+
+ -- Joey Hess <joeyh@debian.org> Sat, 12 Mar 2011 15:02:49 -0400
+
+git-annex (0.22) unstable; urgency=low
+
+ * Git annexes can now be attached to bare git repositories.
+ (Both the local and remote host must have this version of git-annex
+ installed for it to work.)
+ * Support filenames that start with a dash; when such a file is passed
+ to a utility it will be escaped to avoid it being interpreted as an
+ option. (I went a little overboard and got the type checker involved
+ in this, so such files are rather comprehensively supported now.)
+ * New backends: SHA512 SHA384 SHA256 SHA224
+ (Supported on systems where corresponding shaNsum commands are available.)
+ * describe: New subcommand that can set or change the description of
+ a repository.
+ * Fix test suite to reap zombies.
+ (Zombies can be particularly annoying on OSX; thanks to Jimmy Tang
+ for his help eliminating the infestation... for now.)
+ * Make test suite not rely on a working cp -pr.
+ (The Unix wars are still ON!)
+ * Look for dir.git directories the same as git does.
+ * Support remote urls specified as relative paths.
+ * Support non-ssh remote paths that contain tilde expansions.
+ * fsck: Check for and repair location log damage.
+ * Bugfix: When fsck detected and moved away corrupt file content, it did
+ not update the location log.
+
+ -- Joey Hess <joeyh@debian.org> Fri, 04 Mar 2011 15:10:57 -0400
+
+git-annex (0.21) unstable; urgency=low
+
+ * test: Don't rely on chmod -R working.
+ * unannex: Fix recently introduced bug when attempting to unannex more
+ than one file at a time.
+ * test: Set git user name and email in case git can't guess values.
+ * Fix display of unicode filenames.
+
+ -- Joey Hess <joeyh@debian.org> Fri, 11 Feb 2011 23:21:08 -0400
+
+git-annex (0.20) unstable; urgency=low
+
+ * Preserve specified file ordering when instructed to act on multiple
+ files or directories. For example, "git annex get a b" will now always
+ get "a" before "b". Previously it could operate in either order.
+ * unannex: Commit staged changes at end, to avoid some confusing behavior
+ with the pre-commit hook, which would see some types of commits after
+ an unannex as checking in of an unlocked file.
+ * map: New subcommand that uses graphviz to display a nice map of
+ the git repository network.
+ * Deal with the mtl/monads-fd conflict.
+ * configure: Check for sha1sum.
+
+ -- Joey Hess <joeyh@debian.org> Tue, 08 Feb 2011 18:57:24 -0400
+
+git-annex (0.19) unstable; urgency=low
+
+ * configure: Support using the uuidgen command if the uuid command is
+ not available.
+ * Allow --exclude to be specified more than once.
+ * There are now three levels of repository trust.
+ * untrust: Now marks the current repository as untrusted.
+ * semitrust: Now restores the default trust level. (What untrust used to do.)
+ * fsck, drop: Take untrusted repositories into account.
+ * Bugfix: Files were copied from trusted remotes first even if their
+ annex.cost was higher than other remotes.
+ * Improved temp file handling. Transfers of content can now be resumed
+ from temp files later; the resume does not have to be the immediate
+ next git-annex run.
+ * unused: Include partially transferred content in the list.
+ * Bugfix: Running a second git-annex while a first has a transfer in
+ progress no longer deletes the first processes's temp file.
+
+ -- Joey Hess <joeyh@debian.org> Fri, 28 Jan 2011 14:31:37 -0400
+
+git-annex (0.18) unstable; urgency=low
+
+ * Bugfix: `copy --to` and `move --to` forgot to stage location log changes
+ after transferring the file to the remote repository.
+ (Did not affect ssh remotes.)
+ * fsck: Fix bug in moving of corrupted files to .git/annex/bad/
+ * migrate: Fix support for --backend option.
+ * unlock: Fix behavior when file content is not present.
+ * Test suite improvements. Current top-level test coverage: 80%
+
+ -- Joey Hess <joeyh@debian.org> Fri, 14 Jan 2011 14:17:44 -0400
+
+git-annex (0.17) unstable; urgency=low
+
+ * unannex: Now skips files whose content is not present, rather than
+ it being an error.
+ * New migrate subcommand can be used to switch files to using a different
+ backend, safely and with no duplication of content.
+ * bugfix: Fix crash caused by empty key name. (Thanks Henrik for reporting.)
+
+ -- Joey Hess <joeyh@debian.org> Sun, 09 Jan 2011 10:04:11 -0400
+
+git-annex (0.16) unstable; urgency=low
+
+ * git-annex-shell: Avoid exposing any git repo config except for the
+ annex.uuid when doing configlist.
+ * bugfix: Running `move --to` with a remote whose UUID was not yet known
+ could result in git-annex not recording on the local side where the
+ file was moved to. This could not result in data loss, or even a
+ significant problem, since the remote *did* record that it had the file.
+ * Also, add a general guard to detect attempts to record information
+ about repositories with missing UUIDs.
+ * bugfix: Running `move --to` with a non-ssh remote failed.
+ * bugfix: Running `copy --to` with a non-ssh remote actually did a move.
+ * Many test suite improvements. Current top-level test coverage: 65%
+
+ -- Joey Hess <joeyh@debian.org> Fri, 07 Jan 2011 14:33:13 -0400
+
+git-annex (0.15) unstable; urgency=low
+
+ * Support scp-style urls for remotes (host:path).
+ * Support ssh urls containing "~".
+ * Add trust and untrust subcommands, to allow configuring repositories
+ that are trusted to retain files without explicit checking.
+ * Fix bug in numcopies handling when multiple remotes pointed to the
+ same repository.
+ * Introduce the git-annex-shell command. It's now possible to make
+ a user have it as a restricted login shell, similar to git-shell.
+ * Note that git-annex will always use git-annex-shell when accessing
+ a ssh remote, so all of your remotes need to be upgraded to this
+ version of git-annex at the same time.
+ * Now rsync is exclusively used for copying files to and from remotes.
+ scp is not longer supported.
+
+ -- Joey Hess <joeyh@debian.org> Fri, 31 Dec 2010 22:00:52 -0400
+
+git-annex (0.14) unstable; urgency=low
+
+ * Bugfix to git annex unused in a repository with nothing yet annexed.
+ * Support upgrading from a v0 annex with nothing in it.
+ * Avoid multiple calls to git ls-files when passed eg, "*".
+
+ -- Joey Hess <joeyh@debian.org> Fri, 24 Dec 2010 17:38:48 -0400
+
+git-annex (0.13) unstable; urgency=low
+
+ * Makefile: Install man page and html (when built).
+ * Makefile: Add GHCFLAGS variable.
+ * Fix upgrade from 0.03.
+ * Support remotes using git+ssh and ssh+git as protocol.
+ Closes: #607056
+
+ -- Joey Hess <joeyh@debian.org> Tue, 14 Dec 2010 13:05:10 -0400
+
+git-annex (0.12) unstable; urgency=low
+
+ * Add --exclude option to exclude files from processing.
+ * mwdn2man: Fix a bug in newline supression. Closes: #606578
+ * Bugfix to git annex add of an unlocked file in a subdir. Closes: #606579
+ * Makefile: Add PREFIX variable.
+
+ -- Joey Hess <joeyh@debian.org> Sat, 11 Dec 2010 17:32:00 -0400
+
+git-annex (0.11) unstable; urgency=low
+
+ * If available, rsync will be used for file transfers from remote
+ repositories. This allows resuming interrupted transfers.
+ * Added remote.annex-rsync-options.
+ * Avoid deleting temp files when rsync fails.
+ * Improve detection of version 0 repos.
+ * Add uninit subcommand. Closes: #605749
+
+ -- Joey Hess <joeyh@debian.org> Sat, 04 Dec 2010 17:27:42 -0400
+
+git-annex (0.10) unstable; urgency=low
+
+ * In .gitattributes, the annex.numcopies attribute can be used
+ to control the number of copies to retain of different types of files.
+ * Bugfix: Always correctly handle gitattributes when in a subdirectory of
+ the repository. (Had worked ok for ones like "*.mp3", but failed for
+ ones like "dir/*".)
+ * fsck: Fix warning about not enough copies of a file, when locations
+ are known, but are not available in currently configured remotes.
+ * precommit: Optimise to avoid calling git-check-attr more than once.
+ * The git-annex-backend attribute has been renamed to annex.backend.
+
+ -- Joey Hess <joeyh@debian.org> Sun, 28 Nov 2010 19:28:05 -0400
+
+git-annex (0.09) unstable; urgency=low
+
+ * Add copy subcommand.
+ * Fix bug in setkey subcommand triggered by move --to.
+
+ -- Joey Hess <joeyh@debian.org> Sat, 27 Nov 2010 17:14:59 -0400
+
+git-annex (0.08) unstable; urgency=low
+
+ * Fix `git annex add ../foo` (when ran in a subdir of the repo).
+ * Add configure step to build process.
+ * Only use cp -a if it is supported, falling back to cp -p or plain cp
+ as needed for portability.
+ * cp --reflink=auto is used if supported, and will make git annex unlock
+ much faster on filesystems like btrfs that support copy on write.
+
+ -- Joey Hess <joeyh@debian.org> Sun, 21 Nov 2010 13:45:44 -0400
+
+git-annex (0.07) unstable; urgency=low
+
+ * find: New subcommand.
+ * unused: New subcommand, finds unused data. (Split out from fsck.)
+ * dropunused: New subcommand, provides for easy dropping of unused keys
+ by number, as listed by the unused subcommand.
+ * fsck: Print warnings to stderr; --quiet can now be used to only see
+ problems.
+
+ -- Joey Hess <joeyh@debian.org> Mon, 15 Nov 2010 18:41:50 -0400
+
+git-annex (0.06) unstable; urgency=low
+
+ * fsck: Check if annex.numcopies is satisfied.
+ * fsck: Verify the sha1 of files when the SHA1 backend is used.
+ * fsck: Verify the size of files when the WORM backend is used.
+ * fsck: Allow specifying individual files if fscking everything
+ is not desired.
+ * fsck: Fix bug, introduced in 0.04, in detection of unused data.
+
+ -- Joey Hess <joeyh@debian.org> Sat, 13 Nov 2010 16:24:29 -0400
+
+git-annex (0.05) unstable; urgency=low
+
+ * Optimize both pre-commit and lock subcommands to not call git diff
+ on every file being committed/locked.
+ (This actually also works around a bug in ghc, that caused
+ git-annex 0.04 pre-commit to sometimes corrupt filename being read
+ from git ls-files and fail.
+ See <http://hackage.haskell.org/trac/ghc/ticket/4493>
+ The excessive number of calls made by pre-commit exposed the ghc bug.
+ Thanks Josh Triplett for the debugging.)
+ * Build with -O2.
+
+ -- Joey Hess <joeyh@debian.org> Thu, 11 Nov 2010 18:31:09 -0400
+
+git-annex (0.04) unstable; urgency=low
+
+ * Add unlock subcommand, which replaces the symlink with a copy of
+ the file's content in preparation of changing it. The "edit" subcommand
+ is an alias for unlock.
+ * Add lock subcommand.
+ * Unlocked files will now automatically be added back into the annex when
+ committed (and the updated symlink committed), by some magic in the
+ pre-commit hook.
+ * The SHA1 backend is now fully usable.
+ * Add annex.version, which will be used to automate upgrades
+ between incompatible versions.
+ * Reorganised the layout of .git/annex/
+ * The new layout will be automatically upgraded to the first time
+ git-annex is used in a repository with the old layout.
+ * Note that git-annex 0.04 cannot transfer content from old repositories
+ that have not yet been upgraded.
+ * Annexed file contents are now made unwritable and put in unwriteable
+ directories, to avoid them accidentially being removed or modified.
+ (Thanks Josh Triplett for the idea.)
+ * Add build dep on libghc6-testpack-dev. Closes: #603016
+ * Avoid using runghc to run test suite as it is not available on all
+ architectures. Closes: #603006
+
+ -- Joey Hess <joeyh@debian.org> Wed, 10 Nov 2010 14:23:23 -0400
+
+git-annex (0.03) unstable; urgency=low
+
+ * Fix support for file:// remotes.
+ * Add --verbose
+ * Fix SIGINT handling.
+ * Fix handling of files with unusual characters in their name.
+ * Fixed memory leak; git-annex no longer reads the whole file list
+ from git before starting, and will be much faster with large repos.
+ * Fix crash on unknown symlinks.
+ * Added remote.annex-scp-options and remote.annex-ssh-options.
+ * The backends to use when adding different sets of files can be configured
+ via gitattributes.
+ * In .gitattributes, the git-annex-backend attribute can be set to the
+ names of backends to use when adding different types of files.
+ * Add fsck subcommand. (For now it only finds unused key contents in the
+ annex.)
+
+ -- Joey Hess <joeyh@debian.org> Sun, 07 Nov 2010 18:26:04 -0400
+
+git-annex (0.02) unstable; urgency=low
+
+ * Can scp annexed files from remote hosts, and check remote hosts for
+ file content when dropping files.
+ * New move subcommand, that makes it easy to move file contents from
+ or to a remote.
+ * New fromkey subcommand, for registering urls, etc.
+ * git-annex init will now set up a pre-commit hook that fixes up symlinks
+ before they are committed, to ensure that moving symlinks around does not
+ break them.
+ * More intelligent and fast staging of modified files; git add coalescing.
+ * Add remote.annex-ignore git config setting to allow completly disabling
+ a given remote.
+ * --from/--to can be used to control the remote repository that git-annex
+ uses.
+ * --quiet can be used to avoid verbose output
+ * New plumbing-level dropkey and addkey subcommands.
+ * Lots of bug fixes.
+
+ -- Joey Hess <joeyh@debian.org> Wed, 27 Oct 2010 16:39:29 -0400
+
+git-annex (0.01) unstable; urgency=low
+
+ * First prerelease.
+
+ -- Joey Hess <joeyh@debian.org> Wed, 20 Oct 2010 12:54:24 -0400
diff --git a/debian/compat b/debian/compat
new file mode 100644
index 000000000..ec635144f
--- /dev/null
+++ b/debian/compat
@@ -0,0 +1 @@
+9
diff --git a/debian/control b/debian/control
new file mode 100644
index 000000000..6fbd2a06a
--- /dev/null
+++ b/debian/control
@@ -0,0 +1,90 @@
+Source: git-annex
+Section: utils
+Priority: optional
+Build-Depends:
+ debhelper (>= 9),
+ ghc (>= 7.4),
+ libghc-mtl-dev (>= 2.1.1),
+ libghc-missingh-dev,
+ libghc-hslogger-dev,
+ libghc-pcre-light-dev,
+ libghc-sha-dev,
+ libghc-cryptohash-dev,
+ libghc-regex-tdfa-dev [!mips !mipsel !s390],
+ libghc-dataenc-dev,
+ libghc-utf8-string-dev,
+ libghc-hs3-dev (>= 0.5.6),
+ libghc-dav-dev (>= 0.3) [amd64 i386 kfreebsd-amd64 kfreebsd-i386 powerpc sparc],
+ libghc-quickcheck2-dev,
+ libghc-monad-control-dev (>= 0.3),
+ libghc-monadcatchio-transformers-dev,
+ libghc-unix-compat-dev,
+ libghc-dlist-dev,
+ libghc-uuid-dev,
+ libghc-json-dev,
+ libghc-aeson-dev,
+ libghc-ifelse-dev,
+ libghc-bloomfilter-dev,
+ libghc-edit-distance-dev,
+ libghc-extensible-exceptions-dev,
+ libghc-hinotify-dev [linux-any],
+ libghc-stm-dev (>= 2.3),
+ libghc-dbus-dev (>= 0.10.3) [linux-any],
+ libghc-yesod-dev [i386 amd64 kfreebsd-i386 kfreebsd-amd64 powerpc sparc],
+ libghc-yesod-static-dev [i386 amd64 kfreebsd-i386 kfreebsd-amd64 powerpc sparc],
+ libghc-yesod-default-dev [i386 amd64 kfreebsd-amd64 powerpc sparc],
+ libghc-hamlet-dev [i386 amd64 kfreebsd-i386 kfreebsd-amd64 powerpc sparc],
+ libghc-clientsession-dev [i386 amd64 kfreebsd-i386 kfreebsd-amd64 powerpc sparc],
+ libghc-warp-dev [i386 amd64 kfreebsd-i386 kfreebsd-amd64 powerpc sparc],
+ libghc-wai-dev [i386 amd64 kfreebsd-i386 kfreebsd-amd64 powerpc sparc],
+ libghc-wai-logger-dev [i386 amd64 kfreebsd-i386 kfreebsd-amd64 powerpc sparc],
+ libghc-case-insensitive-dev,
+ libghc-http-types-dev,
+ libghc-blaze-builder-dev,
+ libghc-crypto-api-dev,
+ libghc-network-multicast-dev,
+ libghc-network-info-dev [linux-any kfreebsd-any],
+ libghc-safesemaphore-dev,
+ libghc-network-protocol-xmpp-dev (>= 0.4.3-1+b1),
+ libghc-gnutls-dev (>= 0.1.4),
+ libghc-xml-types-dev,
+ libghc-async-dev,
+ libghc-http-dev,
+ libghc-feed-dev,
+ ikiwiki,
+ perlmagick,
+ git (>= 1:1.8.4),
+ rsync,
+ wget,
+ curl,
+ openssh-client,
+Maintainer: Joey Hess <joeyh@debian.org>
+Standards-Version: 3.9.4
+Vcs-Git: git://git.kitenet.net/git-annex
+Homepage: http://git-annex.branchable.com/
+XS-Testsuite: autopkgtest
+
+Package: git-annex
+Architecture: any
+Section: utils
+Depends: ${misc:Depends}, ${shlibs:Depends},
+ git (>= 1:1.8.4),
+ rsync,
+ wget,
+ curl,
+ openssh-client (>= 1:5.6p1)
+Recommends: lsof, gnupg, bind9-host, ssh-askpass, quvi, git-remote-gcrypt (>= 0.20130908-4)
+Suggests: graphviz, bup, libnss-mdns
+Description: manage files with git, without checking their contents into git
+ git-annex allows managing files with git, without checking the file
+ contents into git. While that may seem paradoxical, it is useful when
+ dealing with files larger than git can currently easily handle, whether due
+ to limitations in memory, time, or disk space.
+ .
+ Even without file content tracking, being able to manage files with git,
+ move files around and delete files with versioned directory trees, and use
+ branches and distributed clones, are all very handy reasons to use git. And
+ annexed files can co-exist in the same git repository with regularly
+ versioned files, which is convenient for maintaining documents, Makefiles,
+ etc that are associated with annexed files but that benefit from full
+ revision control.
diff --git a/debian/copyright b/debian/copyright
new file mode 100644
index 000000000..e91cddbb5
--- /dev/null
+++ b/debian/copyright
@@ -0,0 +1,780 @@
+Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Source: native package
+
+Files: *
+Copyright: © 2010-2013 Joey Hess <joey@kitenet.net>
+License: GPL-3+
+
+Files: Assistant/WebApp.hs Assistant/WebApp/* templates/* static/*
+Copyright: © 2012-2013 Joey Hess <joey@kitenet.net>
+License: AGPL-3+
+
+Files: Utility/ThreadScheduler.hs
+Copyright: 2011 Bas van Dijk & Roel van Dijk
+ 2012 Joey Hess <joey@kitenet.net>
+License: GPL-3+
+
+Files: doc/logo* */favicon.ico standalone/osx/git-annex.app/Contents/Resources/git-annex.icns standalone/android/icons/*
+Copyright: 2007 Henrik Nyh <http://henrik.nyh.se/>
+ 2010 Joey Hess <joey@kitenet.net>
+ 2013 John Lawrence
+License: other
+ Free to modify and redistribute with due credit, and obviously free to use.
+
+Files: Utility/Mounts.hsc
+Copyright: Volker Wysk <hsss@volker-wysk.de>
+License: LGPL-2.1+
+
+Files: Utility/libmounts.c
+Copyright: 1980, 1989, 1993, 1994 The Regents of the University of California
+ 2001 David Rufino <daverufino@btinternet.com>
+ 2012 Joey Hess <joey@kitenet.net>
+License: BSD-3-clause
+ * Copyright (c) 1980, 1989, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 2001
+ * David Rufino <daverufino@btinternet.com>
+ * Copyright 2012
+ * Joey Hess <joey@kitenet.net>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+
+Files: static/jquery*
+Copyright: © 2005-2011 by John Resig, Branden Aaron & Jörn Zaefferer
+ © 2011 The Dojo Foundation
+License: MIT or GPL-2
+ The full text of version 2 of the GPL is distributed in
+ /usr/share/common-licenses/GPL-2 on Debian systems. The text of the MIT
+ license follows:
+ .
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+ .
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+ .
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Files: static/*/bootstrap* static/img/glyphicons-halflings*
+Copyright: 2012 Twitter, Inc.
+License: Apache-2.0
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ .
+ http://www.apache.org/licenses/LICENSE-2.0
+ .
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ .
+ The complete text of the Apache License is distributed in
+ /usr/share/common-licenses/Apache-2.0 on Debian systems.
+
+License: GPL-3+
+ The full text of version 3 of the GPL is distributed as doc/license/GPL in
+ this package's source, or in /usr/share/common-licenses/GPL-3 on
+ Debian systems.
+
+License: LGPL-2.1+
+ The full text of version 2.1 of the LGPL is distributed as doc/license/LGPL
+ in this package's source, or in /usr/share/common-licenses/LGPL-2.1
+ on Debian systems.
+
+License: AGPL-3+
+ GNU AFFERO GENERAL PUBLIC LICENSE
+ Version 3, 19 November 2007
+ .
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+ .
+ Preamble
+ .
+ The GNU Affero General Public License is a free, copyleft license for
+ software and other kinds of works, specifically designed to ensure
+ cooperation with the community in the case of network server software.
+ .
+ The licenses for most software and other practical works are designed
+ to take away your freedom to share and change the works. By contrast,
+ our General Public Licenses are intended to guarantee your freedom to
+ share and change all versions of a program--to make sure it remains free
+ software for all its users.
+ .
+ When we speak of free software, we are referring to freedom, not
+ price. Our General Public Licenses are designed to make sure that you
+ have the freedom to distribute copies of free software (and charge for
+ them if you wish), that you receive source code or can get it if you
+ want it, that you can change the software or use pieces of it in new
+ free programs, and that you know you can do these things.
+ .
+ Developers that use our General Public Licenses protect your rights
+ with two steps: (1) assert copyright on the software, and (2) offer
+ you this License which gives you legal permission to copy, distribute
+ and/or modify the software.
+ .
+ A secondary benefit of defending all users' freedom is that
+ improvements made in alternate versions of the program, if they
+ receive widespread use, become available for other developers to
+ incorporate. Many developers of free software are heartened and
+ encouraged by the resulting cooperation. However, in the case of
+ software used on network servers, this result may fail to come about.
+ The GNU General Public License permits making a modified version and
+ letting the public access it on a server without ever releasing its
+ source code to the public.
+ .
+ The GNU Affero General Public License is designed specifically to
+ ensure that, in such cases, the modified source code becomes available
+ to the community. It requires the operator of a network server to
+ provide the source code of the modified version running there to the
+ users of that server. Therefore, public use of a modified version, on
+ a publicly accessible server, gives the public access to the source
+ code of the modified version.
+ .
+ An older license, called the Affero General Public License and
+ published by Affero, was designed to accomplish similar goals. This is
+ a different license, not a version of the Affero GPL, but Affero has
+ released a new version of the Affero GPL which permits relicensing under
+ this license.
+ .
+ The precise terms and conditions for copying, distribution and
+ modification follow.
+ .
+ TERMS AND CONDITIONS
+ .
+ 0. Definitions.
+ .
+ "This License" refers to version 3 of the GNU Affero General Public License.
+ .
+ "Copyright" also means copyright-like laws that apply to other kinds of
+ works, such as semiconductor masks.
+ .
+ "The Program" refers to any copyrightable work licensed under this
+ License. Each licensee is addressed as "you". "Licensees" and
+ "recipients" may be individuals or organizations.
+ .
+ To "modify" a work means to copy from or adapt all or part of the work
+ in a fashion requiring copyright permission, other than the making of an
+ exact copy. The resulting work is called a "modified version" of the
+ earlier work or a work "based on" the earlier work.
+ .
+ A "covered work" means either the unmodified Program or a work based
+ on the Program.
+ .
+ To "propagate" a work means to do anything with it that, without
+ permission, would make you directly or secondarily liable for
+ infringement under applicable copyright law, except executing it on a
+ computer or modifying a private copy. Propagation includes copying,
+ distribution (with or without modification), making available to the
+ public, and in some countries other activities as well.
+ .
+ To "convey" a work means any kind of propagation that enables other
+ parties to make or receive copies. Mere interaction with a user through
+ a computer network, with no transfer of a copy, is not conveying.
+ .
+ An interactive user interface displays "Appropriate Legal Notices"
+ to the extent that it includes a convenient and prominently visible
+ feature that (1) displays an appropriate copyright notice, and (2)
+ tells the user that there is no warranty for the work (except to the
+ extent that warranties are provided), that licensees may convey the
+ work under this License, and how to view a copy of this License. If
+ the interface presents a list of user commands or options, such as a
+ menu, a prominent item in the list meets this criterion.
+ .
+ 1. Source Code.
+ .
+ The "source code" for a work means the preferred form of the work
+ for making modifications to it. "Object code" means any non-source
+ form of a work.
+ .
+ A "Standard Interface" means an interface that either is an official
+ standard defined by a recognized standards body, or, in the case of
+ interfaces specified for a particular programming language, one that
+ is widely used among developers working in that language.
+ .
+ The "System Libraries" of an executable work include anything, other
+ than the work as a whole, that (a) is included in the normal form of
+ packaging a Major Component, but which is not part of that Major
+ Component, and (b) serves only to enable use of the work with that
+ Major Component, or to implement a Standard Interface for which an
+ implementation is available to the public in source code form. A
+ "Major Component", in this context, means a major essential component
+ (kernel, window system, and so on) of the specific operating system
+ (if any) on which the executable work runs, or a compiler used to
+ produce the work, or an object code interpreter used to run it.
+ .
+ The "Corresponding Source" for a work in object code form means all
+ the source code needed to generate, install, and (for an executable
+ work) run the object code and to modify the work, including scripts to
+ control those activities. However, it does not include the work's
+ System Libraries, or general-purpose tools or generally available free
+ programs which are used unmodified in performing those activities but
+ which are not part of the work. For example, Corresponding Source
+ includes interface definition files associated with source files for
+ the work, and the source code for shared libraries and dynamically
+ linked subprograms that the work is specifically designed to require,
+ such as by intimate data communication or control flow between those
+ subprograms and other parts of the work.
+ .
+ The Corresponding Source need not include anything that users
+ can regenerate automatically from other parts of the Corresponding
+ Source.
+ .
+ The Corresponding Source for a work in source code form is that
+ same work.
+ .
+ 2. Basic Permissions.
+ .
+ All rights granted under this License are granted for the term of
+ copyright on the Program, and are irrevocable provided the stated
+ conditions are met. This License explicitly affirms your unlimited
+ permission to run the unmodified Program. The output from running a
+ covered work is covered by this License only if the output, given its
+ content, constitutes a covered work. This License acknowledges your
+ rights of fair use or other equivalent, as provided by copyright law.
+ .
+ You may make, run and propagate covered works that you do not
+ convey, without conditions so long as your license otherwise remains
+ in force. You may convey covered works to others for the sole purpose
+ of having them make modifications exclusively for you, or provide you
+ with facilities for running those works, provided that you comply with
+ the terms of this License in conveying all material for which you do
+ not control copyright. Those thus making or running the covered works
+ for you must do so exclusively on your behalf, under your direction
+ and control, on terms that prohibit them from making any copies of
+ your copyrighted material outside their relationship with you.
+ .
+ Conveying under any other circumstances is permitted solely under
+ the conditions stated below. Sublicensing is not allowed; section 10
+ makes it unnecessary.
+ .
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+ .
+ No covered work shall be deemed part of an effective technological
+ measure under any applicable law fulfilling obligations under article
+ 11 of the WIPO copyright treaty adopted on 20 December 1996, or
+ similar laws prohibiting or restricting circumvention of such
+ measures.
+ .
+ When you convey a covered work, you waive any legal power to forbid
+ circumvention of technological measures to the extent such circumvention
+ is effected by exercising rights under this License with respect to
+ the covered work, and you disclaim any intention to limit operation or
+ modification of the work as a means of enforcing, against the work's
+ users, your or third parties' legal rights to forbid circumvention of
+ technological measures.
+ .
+ 4. Conveying Verbatim Copies.
+ .
+ You may convey verbatim copies of the Program's source code as you
+ receive it, in any medium, provided that you conspicuously and
+ appropriately publish on each copy an appropriate copyright notice;
+ keep intact all notices stating that this License and any
+ non-permissive terms added in accord with section 7 apply to the code;
+ keep intact all notices of the absence of any warranty; and give all
+ recipients a copy of this License along with the Program.
+ .
+ You may charge any price or no price for each copy that you convey,
+ and you may offer support or warranty protection for a fee.
+ .
+ 5. Conveying Modified Source Versions.
+ .
+ You may convey a work based on the Program, or the modifications to
+ produce it from the Program, in the form of source code under the
+ terms of section 4, provided that you also meet all of these conditions:
+ .
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+ .
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+ .
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+ .
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+ .
+ A compilation of a covered work with other separate and independent
+ works, which are not by their nature extensions of the covered work,
+ and which are not combined with it such as to form a larger program,
+ in or on a volume of a storage or distribution medium, is called an
+ "aggregate" if the compilation and its resulting copyright are not
+ used to limit the access or legal rights of the compilation's users
+ beyond what the individual works permit. Inclusion of a covered work
+ in an aggregate does not cause this License to apply to the other
+ parts of the aggregate.
+ .
+ 6. Conveying Non-Source Forms.
+ .
+ You may convey a covered work in object code form under the terms
+ of sections 4 and 5, provided that you also convey the
+ machine-readable Corresponding Source under the terms of this License,
+ in one of these ways:
+ .
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+ .
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+ .
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+ .
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+ .
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+ .
+ A separable portion of the object code, whose source code is excluded
+ from the Corresponding Source as a System Library, need not be
+ included in conveying the object code work.
+ .
+ A "User Product" is either (1) a "consumer product", which means any
+ tangible personal property which is normally used for personal, family,
+ or household purposes, or (2) anything designed or sold for incorporation
+ into a dwelling. In determining whether a product is a consumer product,
+ doubtful cases shall be resolved in favor of coverage. For a particular
+ product received by a particular user, "normally used" refers to a
+ typical or common use of that class of product, regardless of the status
+ of the particular user or of the way in which the particular user
+ actually uses, or expects or is expected to use, the product. A product
+ is a consumer product regardless of whether the product has substantial
+ commercial, industrial or non-consumer uses, unless such uses represent
+ the only significant mode of use of the product.
+ .
+ "Installation Information" for a User Product means any methods,
+ procedures, authorization keys, or other information required to install
+ and execute modified versions of a covered work in that User Product from
+ a modified version of its Corresponding Source. The information must
+ suffice to ensure that the continued functioning of the modified object
+ code is in no case prevented or interfered with solely because
+ modification has been made.
+ .
+ If you convey an object code work under this section in, or with, or
+ specifically for use in, a User Product, and the conveying occurs as
+ part of a transaction in which the right of possession and use of the
+ User Product is transferred to the recipient in perpetuity or for a
+ fixed term (regardless of how the transaction is characterized), the
+ Corresponding Source conveyed under this section must be accompanied
+ by the Installation Information. But this requirement does not apply
+ if neither you nor any third party retains the ability to install
+ modified object code on the User Product (for example, the work has
+ been installed in ROM).
+ .
+ The requirement to provide Installation Information does not include a
+ requirement to continue to provide support service, warranty, or updates
+ for a work that has been modified or installed by the recipient, or for
+ the User Product in which it has been modified or installed. Access to a
+ network may be denied when the modification itself materially and
+ adversely affects the operation of the network or violates the rules and
+ protocols for communication across the network.
+ .
+ Corresponding Source conveyed, and Installation Information provided,
+ in accord with this section must be in a format that is publicly
+ documented (and with an implementation available to the public in
+ source code form), and must require no special password or key for
+ unpacking, reading or copying.
+ .
+ 7. Additional Terms.
+ .
+ "Additional permissions" are terms that supplement the terms of this
+ License by making exceptions from one or more of its conditions.
+ Additional permissions that are applicable to the entire Program shall
+ be treated as though they were included in this License, to the extent
+ that they are valid under applicable law. If additional permissions
+ apply only to part of the Program, that part may be used separately
+ under those permissions, but the entire Program remains governed by
+ this License without regard to the additional permissions.
+ .
+ When you convey a copy of a covered work, you may at your option
+ remove any additional permissions from that copy, or from any part of
+ it. (Additional permissions may be written to require their own
+ removal in certain cases when you modify the work.) You may place
+ additional permissions on material, added by you to a covered work,
+ for which you have or can give appropriate copyright permission.
+ .
+ Notwithstanding any other provision of this License, for material you
+ add to a covered work, you may (if authorized by the copyright holders of
+ that material) supplement the terms of this License with terms:
+ .
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+ .
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+ .
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+ .
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+ .
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+ .
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+ .
+ All other non-permissive additional terms are considered "further
+ restrictions" within the meaning of section 10. If the Program as you
+ received it, or any part of it, contains a notice stating that it is
+ governed by this License along with a term that is a further
+ restriction, you may remove that term. If a license document contains
+ a further restriction but permits relicensing or conveying under this
+ License, you may add to a covered work material governed by the terms
+ of that license document, provided that the further restriction does
+ not survive such relicensing or conveying.
+ .
+ If you add terms to a covered work in accord with this section, you
+ must place, in the relevant source files, a statement of the
+ additional terms that apply to those files, or a notice indicating
+ where to find the applicable terms.
+ .
+ Additional terms, permissive or non-permissive, may be stated in the
+ form of a separately written license, or stated as exceptions;
+ the above requirements apply either way.
+ .
+ 8. Termination.
+ .
+ You may not propagate or modify a covered work except as expressly
+ provided under this License. Any attempt otherwise to propagate or
+ modify it is void, and will automatically terminate your rights under
+ this License (including any patent licenses granted under the third
+ paragraph of section 11).
+ .
+ However, if you cease all violation of this License, then your
+ license from a particular copyright holder is reinstated (a)
+ provisionally, unless and until the copyright holder explicitly and
+ finally terminates your license, and (b) permanently, if the copyright
+ holder fails to notify you of the violation by some reasonable means
+ prior to 60 days after the cessation.
+ .
+ Moreover, your license from a particular copyright holder is
+ reinstated permanently if the copyright holder notifies you of the
+ violation by some reasonable means, this is the first time you have
+ received notice of violation of this License (for any work) from that
+ copyright holder, and you cure the violation prior to 30 days after
+ your receipt of the notice.
+ .
+ Termination of your rights under this section does not terminate the
+ licenses of parties who have received copies or rights from you under
+ this License. If your rights have been terminated and not permanently
+ reinstated, you do not qualify to receive new licenses for the same
+ material under section 10.
+ .
+ 9. Acceptance Not Required for Having Copies.
+ .
+ You are not required to accept this License in order to receive or
+ run a copy of the Program. Ancillary propagation of a covered work
+ occurring solely as a consequence of using peer-to-peer transmission
+ to receive a copy likewise does not require acceptance. However,
+ nothing other than this License grants you permission to propagate or
+ modify any covered work. These actions infringe copyright if you do
+ not accept this License. Therefore, by modifying or propagating a
+ covered work, you indicate your acceptance of this License to do so.
+ .
+ 10. Automatic Licensing of Downstream Recipients.
+ .
+ Each time you convey a covered work, the recipient automatically
+ receives a license from the original licensors, to run, modify and
+ propagate that work, subject to this License. You are not responsible
+ for enforcing compliance by third parties with this License.
+ .
+ An "entity transaction" is a transaction transferring control of an
+ organization, or substantially all assets of one, or subdividing an
+ organization, or merging organizations. If propagation of a covered
+ work results from an entity transaction, each party to that
+ transaction who receives a copy of the work also receives whatever
+ licenses to the work the party's predecessor in interest had or could
+ give under the previous paragraph, plus a right to possession of the
+ Corresponding Source of the work from the predecessor in interest, if
+ the predecessor has it or can get it with reasonable efforts.
+ .
+ You may not impose any further restrictions on the exercise of the
+ rights granted or affirmed under this License. For example, you may
+ not impose a license fee, royalty, or other charge for exercise of
+ rights granted under this License, and you may not initiate litigation
+ (including a cross-claim or counterclaim in a lawsuit) alleging that
+ any patent claim is infringed by making, using, selling, offering for
+ sale, or importing the Program or any portion of it.
+ .
+ 11. Patents.
+ .
+ A "contributor" is a copyright holder who authorizes use under this
+ License of the Program or a work on which the Program is based. The
+ work thus licensed is called the contributor's "contributor version".
+ .
+ A contributor's "essential patent claims" are all patent claims
+ owned or controlled by the contributor, whether already acquired or
+ hereafter acquired, that would be infringed by some manner, permitted
+ by this License, of making, using, or selling its contributor version,
+ but do not include claims that would be infringed only as a
+ consequence of further modification of the contributor version. For
+ purposes of this definition, "control" includes the right to grant
+ patent sublicenses in a manner consistent with the requirements of
+ this License.
+ .
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+ patent license under the contributor's essential patent claims, to
+ make, use, sell, offer for sale, import and otherwise run, modify and
+ propagate the contents of its contributor version.
+ .
+ In the following three paragraphs, a "patent license" is any express
+ agreement or commitment, however denominated, not to enforce a patent
+ (such as an express permission to practice a patent or covenant not to
+ sue for patent infringement). To "grant" such a patent license to a
+ party means to make such an agreement or commitment not to enforce a
+ patent against the party.
+ .
+ If you convey a covered work, knowingly relying on a patent license,
+ and the Corresponding Source of the work is not available for anyone
+ to copy, free of charge and under the terms of this License, through a
+ publicly available network server or other readily accessible means,
+ then you must either (1) cause the Corresponding Source to be so
+ available, or (2) arrange to deprive yourself of the benefit of the
+ patent license for this particular work, or (3) arrange, in a manner
+ consistent with the requirements of this License, to extend the patent
+ license to downstream recipients. "Knowingly relying" means you have
+ actual knowledge that, but for the patent license, your conveying the
+ covered work in a country, or your recipient's use of the covered work
+ in a country, would infringe one or more identifiable patents in that
+ country that you have reason to believe are valid.
+ .
+ If, pursuant to or in connection with a single transaction or
+ arrangement, you convey, or propagate by procuring conveyance of, a
+ covered work, and grant a patent license to some of the parties
+ receiving the covered work authorizing them to use, propagate, modify
+ or convey a specific copy of the covered work, then the patent license
+ you grant is automatically extended to all recipients of the covered
+ work and works based on it.
+ .
+ A patent license is "discriminatory" if it does not include within
+ the scope of its coverage, prohibits the exercise of, or is
+ conditioned on the non-exercise of one or more of the rights that are
+ specifically granted under this License. You may not convey a covered
+ work if you are a party to an arrangement with a third party that is
+ in the business of distributing software, under which you make payment
+ to the third party based on the extent of your activity of conveying
+ the work, and under which the third party grants, to any of the
+ parties who would receive the covered work from you, a discriminatory
+ patent license (a) in connection with copies of the covered work
+ conveyed by you (or copies made from those copies), or (b) primarily
+ for and in connection with specific products or compilations that
+ contain the covered work, unless you entered into that arrangement,
+ or that patent license was granted, prior to 28 March 2007.
+ .
+ Nothing in this License shall be construed as excluding or limiting
+ any implied license or other defenses to infringement that may
+ otherwise be available to you under applicable patent law.
+ .
+ 12. No Surrender of Others' Freedom.
+ .
+ If conditions are imposed on you (whether by court order, agreement or
+ otherwise) that contradict the conditions of this License, they do not
+ excuse you from the conditions of this License. If you cannot convey a
+ covered work so as to satisfy simultaneously your obligations under this
+ License and any other pertinent obligations, then as a consequence you may
+ not convey it at all. For example, if you agree to terms that obligate you
+ to collect a royalty for further conveying from those to whom you convey
+ the Program, the only way you could satisfy both those terms and this
+ License would be to refrain entirely from conveying the Program.
+ .
+ 13. Remote Network Interaction; Use with the GNU General Public License.
+ .
+ Notwithstanding any other provision of this License, if you modify the
+ Program, your modified version must prominently offer all users
+ interacting with it remotely through a computer network (if your version
+ supports such interaction) an opportunity to receive the Corresponding
+ Source of your version by providing access to the Corresponding Source
+ from a network server at no charge, through some standard or customary
+ means of facilitating copying of software. This Corresponding Source
+ shall include the Corresponding Source for any work covered by version 3
+ of the GNU General Public License that is incorporated pursuant to the
+ following paragraph.
+ .
+ Notwithstanding any other provision of this License, you have
+ permission to link or combine any covered work with a work licensed
+ under version 3 of the GNU General Public License into a single
+ combined work, and to convey the resulting work. The terms of this
+ License will continue to apply to the part which is the covered work,
+ but the work with which it is combined will remain governed by version
+ 3 of the GNU General Public License.
+ .
+ 14. Revised Versions of this License.
+ .
+ The Free Software Foundation may publish revised and/or new versions of
+ the GNU Affero General Public License from time to time. Such new versions
+ will be similar in spirit to the present version, but may differ in detail to
+ address new problems or concerns.
+ .
+ Each version is given a distinguishing version number. If the
+ Program specifies that a certain numbered version of the GNU Affero General
+ Public License "or any later version" applies to it, you have the
+ option of following the terms and conditions either of that numbered
+ version or of any later version published by the Free Software
+ Foundation. If the Program does not specify a version number of the
+ GNU Affero General Public License, you may choose any version ever published
+ by the Free Software Foundation.
+ .
+ If the Program specifies that a proxy can decide which future
+ versions of the GNU Affero General Public License can be used, that proxy's
+ public statement of acceptance of a version permanently authorizes you
+ to choose that version for the Program.
+ .
+ Later license versions may give you additional or different
+ permissions. However, no additional obligations are imposed on any
+ author or copyright holder as a result of your choosing to follow a
+ later version.
+ .
+ 15. Disclaimer of Warranty.
+ .
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+ APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+ HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+ OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+ IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+ .
+ 16. Limitation of Liability.
+ .
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+ WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+ THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+ GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+ USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+ DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+ PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+ EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGES.
+ .
+ 17. Interpretation of Sections 15 and 16.
+ .
+ If the disclaimer of warranty and limitation of liability provided
+ above cannot be given local legal effect according to their terms,
+ reviewing courts shall apply local law that most closely approximates
+ an absolute waiver of all civil liability in connection with the
+ Program, unless a warranty or assumption of liability accompanies a
+ copy of the Program in return for a fee.
+ .
+ END OF TERMS AND CONDITIONS
+ .
+ How to Apply These Terms to Your New Programs
+ .
+ If you develop a new program, and you want it to be of the greatest
+ possible use to the public, the best way to achieve this is to make it
+ free software which everyone can redistribute and change under these terms.
+ .
+ To do so, attach the following notices to the program. It is safest
+ to attach them to the start of each source file to most effectively
+ state the exclusion of warranty; and each file should have at least
+ the "copyright" line and a pointer to where the full notice is found.
+ .
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+ .
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+ .
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+ .
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ .
+ Also add information on how to contact you by electronic and paper mail.
+ .
+ If your software can interact with users remotely through a computer
+ network, you should also make sure that it provides a way for users to
+ get its source. For example, if your program is a web application, its
+ interface could display a "Source" link that leads users to an archive
+ of the code. There are many ways you could offer source, and different
+ solutions will be better for different programs; see section 13 for the
+ specific requirements.
+ .
+ You should also get your employer (if you work as a programmer) or school,
+ if any, to sign a "copyright disclaimer" for the program, if necessary.
+ For more information on this, and how to apply and follow the GNU AGPL, see
+ <http://www.gnu.org/licenses/>.
diff --git a/debian/doc-base b/debian/doc-base
new file mode 100644
index 000000000..f71a23333
--- /dev/null
+++ b/debian/doc-base
@@ -0,0 +1,9 @@
+Document: git-annex
+Title: git-annex documentation
+Author: Joey Hess
+Abstract: All the documentation from git-annex's website.
+Section: File Management
+
+Format: HTML
+Index: /usr/share/doc/git-annex/html/index.html
+Files: /usr/share/doc/git-annex/html/*.html
diff --git a/debian/menu b/debian/menu
new file mode 100644
index 000000000..20790a94c
--- /dev/null
+++ b/debian/menu
@@ -0,0 +1,2 @@
+?package(git-annex):needs="X11" section="Applications/Network/File Transfer" \
+ title="git-annex assistant" command="git-annex webapp"
diff --git a/debian/rules b/debian/rules
new file mode 100755
index 000000000..91854aa15
--- /dev/null
+++ b/debian/rules
@@ -0,0 +1,17 @@
+#!/usr/bin/make -f
+
+# Avoid using cabal, as it writes to $HOME
+export CABAL=./Setup
+
+# Do use the changelog's version number, rather than making one up.
+export RELEASE_BUILD=1
+
+%:
+ dh $@
+
+override_dh_auto_test:
+ echo test suite currently disabled until haskell-tasty is out of NEW
+
+# Not intended for use by anyone except the author.
+announcedir:
+ @echo ${HOME}/src/git-annex/doc/news
diff --git a/debian/tests/basics b/debian/tests/basics
new file mode 100644
index 000000000..2e4ea43fc
--- /dev/null
+++ b/debian/tests/basics
@@ -0,0 +1,4 @@
+#!/bin/sh
+testdir="$(mktemp -d)"
+cd "$testdir"
+exec git-annex test
diff --git a/debian/tests/control b/debian/tests/control
new file mode 100644
index 000000000..928caf8e3
--- /dev/null
+++ b/debian/tests/control
@@ -0,0 +1,4 @@
+Tests: basics
+Depends: @, git, rsync, gnupg
+Restrictions: allow-stderr
+
diff --git a/doc/Android.mdwn b/doc/Android.mdwn
new file mode 100644
index 000000000..71263ea8d
--- /dev/null
+++ b/doc/Android.mdwn
@@ -0,0 +1,53 @@
+git-annex is now available for Android. This includes the
+[[git-annex assistant|/assistant]], for easy syncing between your Android
+and other devices. You do not need to root your Android to use git-annex.
+
+[[Android installation instructions|/install/android]]
+
+When you run the git-annex Android app, two windows will open. The first is
+a terminal window, and the second is a web browser showing the git-annex
+webapp.
+
+[[!img apps.png alt="two windows"]]
+
+[[!toc ]]
+
+## closing and reopening the webapp
+
+The webapp does not need to be left open after you've set up your
+repository. As long as the terminal window is left open, git-annex will
+remain running and sync your files. To re-open the webapp after closing it,
+use the [[!img newwindow.png alt="New Window"]] icon in the terminal window.
+
+## starting git-annex
+
+The app is not currently automatically started on boot, so you will need to
+manually open it to keep your files in sync. You do not need to leave the
+app running all the time, though. It will sync back up automatically when
+started.
+
+## stopping git-annex
+
+Simply close the terminal window to stop git-annex from running.
+
+## using the command line
+
+[[!img terminal.png alt="Android terminal"]]
+
+If you prefer to use `git-annex` at the command line, you can do so using the
+terminal. A fairly full set of tools is provided, including `git`, `ssh`,
+`rsync`, and `gpg`.
+
+To prevent the webapp from being automatically started
+when a terminal window opens, go into the terminal preferences, to "Inital
+Command", and clear out the default `git annex webapp` setting.
+
+Or, if you'd like to run the assistant automatically, but not open the
+webapp, change the "Initial Command" to: `git annex assistant --autostart`
+
+## using from adb shell
+
+To set up the git-annex environment from within `adb shell`, run:
+`/data/data/ga.androidterm/runshell`
+
+This will launch a shell that has git-annex, git, etc in PATH.
diff --git a/doc/Android/comment_15_77bafc01b47d4cf8f96bde2b6704ed71._comment b/doc/Android/comment_15_77bafc01b47d4cf8f96bde2b6704ed71._comment
new file mode 100644
index 000000000..0ecd59fe6
--- /dev/null
+++ b/doc/Android/comment_15_77bafc01b47d4cf8f96bde2b6704ed71._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://yarikoptic.myopenid.com/"
+ nickname="site-myopenid"
+ subject="asking for ssh password in the terminal (not in web ui)"
+ date="2013-05-24T23:49:40Z"
+ content="""
+not sure if that is a known issue: whenever \"remote server\" is added, password needs to be typed back in the original terminal... is a bit challenging to do on android and not straightforward user-wise
+"""]]
diff --git a/doc/Android/comment_19_dc7b428f525a082834cb87221fc627ff._comment b/doc/Android/comment_19_dc7b428f525a082834cb87221fc627ff._comment
new file mode 100644
index 000000000..009ada003
--- /dev/null
+++ b/doc/Android/comment_19_dc7b428f525a082834cb87221fc627ff._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://afoolishmanifesto.com/"
+ nickname="frioux"
+ subject="SSH Keys?"
+ date="2013-07-17T16:50:46Z"
+ content="""
+Is there a way I can use an SSH Key to connect to a remote server? What would be really cool, though maybe not feasible, would be to use connectbot as an ssh-agent.
+"""]]
diff --git a/doc/Android/comment_20_81940ea56ace3dcd5fa84dfccd88ad96._comment b/doc/Android/comment_20_81940ea56ace3dcd5fa84dfccd88ad96._comment
new file mode 100644
index 000000000..ed4d6e0b0
--- /dev/null
+++ b/doc/Android/comment_20_81940ea56ace3dcd5fa84dfccd88ad96._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.90"
+ subject="comment 20"
+ date="2013-07-17T19:06:31Z"
+ content="""
+@frioux the webapp has a \"ssh server\" option that will set up a ssh key and use it for passwordless data transfer to a ssh server. You have to enter your password twice in the git-annex terminal app, and then it's set up.
+
+The openssh included in the git-annex app fully supports everything you can usually do with ssh keys, so you can also set this up by hand.
+"""]]
diff --git a/doc/Android/comment_29_37aa87a451d4390ed367402eec740855._comment b/doc/Android/comment_29_37aa87a451d4390ed367402eec740855._comment
new file mode 100644
index 000000000..448050d12
--- /dev/null
+++ b/doc/Android/comment_29_37aa87a451d4390ed367402eec740855._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.21"
+ subject="comment 29"
+ date="2013-07-30T17:45:27Z"
+ content="""
+If you are experiencing a problem using git-annex on Android, please examine the list of [[bugs]] and add a new, detailed bug report if no-one has reported the problem. If you are not sure if you have a bug, or need help in filing a good bug report, ask for help in the [[forum]].
+
+I have moved to [[oldcomments]] a lot of old comments about problems that may be fixed or
+not (hard to tell without a bug report!) " This page cannot
+scale to handle every bug report that someone wants to paste into it.
+"""]]
diff --git a/doc/Android/comment_5_ba11b81c671d9bcd6f496fbd6f562b0f._comment b/doc/Android/comment_5_ba11b81c671d9bcd6f496fbd6f562b0f._comment
new file mode 100644
index 000000000..54053b43d
--- /dev/null
+++ b/doc/Android/comment_5_ba11b81c671d9bcd6f496fbd6f562b0f._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://mebus.myopenid.com/"
+ ip="2a01:198:3eb:0:4a5b:39ff:fea4:55b3"
+ subject="comment 5"
+ date="2013-10-19T18:05:52Z"
+ content="""
+Hallo,
+
+how can I use the app with public/private keys for SSH. Where can I add them?
+
+Thanks
+
+Mebus
+
+
+"""]]
diff --git a/doc/Android/oldcomments.mdwn b/doc/Android/oldcomments.mdwn
new file mode 100644
index 000000000..3566712cd
--- /dev/null
+++ b/doc/Android/oldcomments.mdwn
@@ -0,0 +1,2 @@
+If one of these comments is yours, and you are still experiencing the
+problem, please file a proper [[bug_report|bugs]]. --[[Joey]]
diff --git a/doc/Android/oldcomments/comment_10_20e3d513b8b97496d76aca4619026cd6._comment b/doc/Android/oldcomments/comment_10_20e3d513b8b97496d76aca4619026cd6._comment
new file mode 100644
index 000000000..cf7a4fdb5
--- /dev/null
+++ b/doc/Android/oldcomments/comment_10_20e3d513b8b97496d76aca4619026cd6._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://yarikoptic.myopenid.com/"
+ nickname="site-myopenid"
+ subject="comment 10"
+ date="2013-05-24T03:11:50Z"
+ content="""
+>you said before the error was \"Read-only file system\". Now you're saying it's \"Cross-device link\". I'm slightly confused.
+
+;-) Sorry for confusion, here are the details:
+
+\"Read-only file system\" -- that error appeared when I started \"stock git annex\", i.e. from running /data/data/ga.androidterm/lib/lib.start.so .
+Since you have suggested that it might be coming from hard linking command, I have ran that one manually, and that is when I got \"Cross-device link\" error, which suggests that hard linking is not the one at fault here.
+
+I will try fresh build now
+Cheers,
+"""]]
diff --git a/doc/Android/oldcomments/comment_11_c96b8f1cc1583a74eb2483f48357f023._comment b/doc/Android/oldcomments/comment_11_c96b8f1cc1583a74eb2483f48357f023._comment
new file mode 100644
index 000000000..2e1ba6560
--- /dev/null
+++ b/doc/Android/oldcomments/comment_11_c96b8f1cc1583a74eb2483f48357f023._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://yarikoptic.myopenid.com/"
+ nickname="site-myopenid"
+ subject="fresh build"
+ date="2013-05-24T03:21:29Z"
+ content="""
+With fresh build got:
+
+u0_a39@android:/ $ git annex webapp
+/system/bin/sh: git: not found
+
+the PATH is /sbin:/system/bin:/system/xbin
+
+where should git (and ga) reside now ? (/data somehow is not accessible now to u0_a39)
+"""]]
diff --git a/doc/Android/oldcomments/comment_12_6551f5fa081494b079c10a33c9b0d8ad._comment b/doc/Android/oldcomments/comment_12_6551f5fa081494b079c10a33c9b0d8ad._comment
new file mode 100644
index 000000000..39ce3e058
--- /dev/null
+++ b/doc/Android/oldcomments/comment_12_6551f5fa081494b079c10a33c9b0d8ad._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 12"
+ date="2013-05-24T03:26:33Z"
+ content="""
+You should be able to run /data/data/ga.androidterm/runshell even if you cannot ls /data. This adds /data/data/ga.androidterm/bin to PATH
+
+However, the shell that the app starts is started by runshell anyway, so I don't understand how this could happen.
+"""]]
diff --git a/doc/Android/oldcomments/comment_13_7c633d245651ec08f63194fe1fc194ae._comment b/doc/Android/oldcomments/comment_13_7c633d245651ec08f63194fe1fc194ae._comment
new file mode 100644
index 000000000..dae84414b
--- /dev/null
+++ b/doc/Android/oldcomments/comment_13_7c633d245651ec08f63194fe1fc194ae._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkwjBDXkP9HAQKhjTgThGOxUa1B99y_WRA"
+ nickname="Franck"
+ subject="Still problems with my old N1/CM7"
+ date="2013-05-24T06:01:18Z"
+ content="""
+Hi, thank you for addressing this issue! I installed the new release but now it fails in another way: the message is just \"In mgmain NJI_OnLoad\" then the terminal says that the session is closed.
+"""]]
diff --git a/doc/Android/oldcomments/comment_14_60c2403140085f9caf48a33b59a36ab4._comment b/doc/Android/oldcomments/comment_14_60c2403140085f9caf48a33b59a36ab4._comment
new file mode 100644
index 000000000..a6f4598f6
--- /dev/null
+++ b/doc/Android/oldcomments/comment_14_60c2403140085f9caf48a33b59a36ab4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://yarikoptic.myopenid.com/"
+ nickname="site-myopenid"
+ subject="It starts after uninstall/install"
+ date="2013-05-24T23:29:52Z"
+ content="""
+Hi Joey -- there is success here... previous installation was \"updated\" by installing the new package without uninstalling previous one, and that apparently didn't work correctly (I didn't even have bin/ directory you mentioned). So I have removed previous installation and reinstalled it again -- it starts now! Thanks ;)
+"""]]
diff --git a/doc/Android/oldcomments/comment_16_9af73451be09f03cfff81fdf9481ffc4._comment b/doc/Android/oldcomments/comment_16_9af73451be09f03cfff81fdf9481ffc4._comment
new file mode 100644
index 000000000..07923c172
--- /dev/null
+++ b/doc/Android/oldcomments/comment_16_9af73451be09f03cfff81fdf9481ffc4._comment
@@ -0,0 +1,27 @@
+[[!comment format=mdwn
+ username="http://yarikoptic.myopenid.com/"
+ nickname="site-myopenid"
+ subject="Few other issues"
+ date="2013-05-25T15:35:46Z"
+ content="""
+Hi again.
+
+talking about 4.20130523-gcfe07a2 version:
+
+- because working in the terminal to interact with git-annex probably should not be a common case on Android, may be it is worth making default type of new added repository to become a full backup? I have initiated a new one, attached a remote one, it said \"synced\" but all the files were just containing symlinks and were not usable. I had to switch to \"full backup\" (or whatever that name) to finally get directory synced
+
+- log file might grow too large simply because of containing numerous entries for attempting connect remote repository while offline, e.g.
+
+Please make sure you have the correct access rights
+and the repository exists.
+ssh: Could not resolve hostname onerussian.com: No address associated with hostname
+fatal: Could not read from remote repository.
+
+IMHO those should not be there at all, e.g. if it is known that ATM there is no network connectivity
+
+- In addition to two existing repositories (1 local /sdcard/annex, which is also avail at/storage/sdcard0/annex + 1 remote) I have added one more local (and said to keep it in sync with original local). But it didn't work -- it \"Synced with onerussian.com_annex but not with Annex\" and claimed that the /external/extSdCard/Annex doesn't exist, although it is there (and with .git generated etc). When I restarted the deamon I got into a \"new\" Repository: /storage/extSdCard/Annex which also listed the 1st local but with \"Failed to sync with localhost\" message -- no remote one listed. Whenever I try to \"Switch repository\" to /sdcard/annex (the original local) -- it starts loading a new page but gets stuck right there. The only way to revive webui is to go back to Dashboard. Log there says (retyping from the screen so typos might be there):
+
+error: cannot run git-receive-pack '/storage/sdcard0/annex': No such file or directory
+fatal: unable to fork
+
+"""]]
diff --git a/doc/Android/oldcomments/comment_17_f76561a654b534df3a807b1c045710b2._comment b/doc/Android/oldcomments/comment_17_f76561a654b534df3a807b1c045710b2._comment
new file mode 100644
index 000000000..bc4a64810
--- /dev/null
+++ b/doc/Android/oldcomments/comment_17_f76561a654b534df3a807b1c045710b2._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://yarikoptic.myopenid.com/"
+ nickname="site-myopenid"
+ subject="comment 17"
+ date="2013-05-29T02:43:29Z"
+ content="""
+joey -- any additional information could I provide to troubleshoot the issue? original repository seems to sync ok, but I can't \"administer\" it if I can't even switch to it...
+"""]]
diff --git a/doc/Android/oldcomments/comment_18_1b46cdf154ddadfe17e4b6e4054dc619._comment b/doc/Android/oldcomments/comment_18_1b46cdf154ddadfe17e4b6e4054dc619._comment
new file mode 100644
index 000000000..bf9d79060
--- /dev/null
+++ b/doc/Android/oldcomments/comment_18_1b46cdf154ddadfe17e4b6e4054dc619._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="http://aap.liquidid.net/"
+ nickname="AAP"
+ subject="comment 18"
+ date="2013-05-30T11:23:58Z"
+ content="""
+I too get the 'link busybox: Read-only file system' message. Here is my phone info:
+
+Phone: Samsung Galaxy Y GT-S5360 (rooted)
+Android: 2.3.6 Gingerbread
+BusyBox path: /system/xbin/
+
+
+Androids own terminal seems not to understand the d argument (-ld: No such file or directory) but over ssh 'ls -ld /data/data/ga.androidterm' returns
+
+ drwxr-x--x 1 app_97 app_97 0 May 30 12:57 /data/data/ga.androidterm/
+"""]]
diff --git a/doc/Android/oldcomments/comment_1_cc9caa5dd22dd67e5c1d22d697096dd2._comment b/doc/Android/oldcomments/comment_1_cc9caa5dd22dd67e5c1d22d697096dd2._comment
new file mode 100644
index 000000000..7fb38058c
--- /dev/null
+++ b/doc/Android/oldcomments/comment_1_cc9caa5dd22dd67e5c1d22d697096dd2._comment
@@ -0,0 +1,15 @@
+[[!comment format=txt
+ username="http://yarikoptic.myopenid.com/"
+ nickname="site-myopenid"
+ subject="Does it require the device to be rooted?"
+ date="2013-05-16T20:55:45Z"
+ content="""
+Following your news on kickstarter downloaded the .apk, and installed it. Upn start I just got a terminal window with
+
+ link busybox: Read-only file system
+
+ [Terminal session finished]
+
+That is on Galaxy Note
+
+"""]]
diff --git a/doc/Android/oldcomments/comment_21_5903f6a4a81a6534fa8cfafb3b6c37bb._comment b/doc/Android/oldcomments/comment_21_5903f6a4a81a6534fa8cfafb3b6c37bb._comment
new file mode 100644
index 000000000..1e247b96a
--- /dev/null
+++ b/doc/Android/oldcomments/comment_21_5903f6a4a81a6534fa8cfafb3b6c37bb._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://afoolishmanifesto.com/"
+ nickname="frioux"
+ subject="SSH Keys - 2"
+ date="2013-07-17T22:56:37Z"
+ content="""
+@joey should I be using the nightlies to see that? Under \"Adding a remote server using ssh\" I only see Host name, user name, directory, and port. Will it only be an option after I type in a password?
+"""]]
diff --git a/doc/Android/oldcomments/comment_22_36afd354f9669a154d7b6b2c4d43ded9._comment b/doc/Android/oldcomments/comment_22_36afd354f9669a154d7b6b2c4d43ded9._comment
new file mode 100644
index 000000000..e5b5f964a
--- /dev/null
+++ b/doc/Android/oldcomments/comment_22_36afd354f9669a154d7b6b2c4d43ded9._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.48"
+ subject="comment 22"
+ date="2013-07-17T23:25:21Z"
+ content="""
+@frioux it will automatically generate a new ssh key and configure the server to use it, once you submit the form and enter the password to let it into the server.
+"""]]
diff --git a/doc/Android/oldcomments/comment_23_de98154792e8611a134429f06d82bcb1._comment b/doc/Android/oldcomments/comment_23_de98154792e8611a134429f06d82bcb1._comment
new file mode 100644
index 000000000..1f34a775e
--- /dev/null
+++ b/doc/Android/oldcomments/comment_23_de98154792e8611a134429f06d82bcb1._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://afoolishmanifesto.com/"
+ nickname="frioux"
+ subject="comment 23"
+ date="2013-07-18T02:01:28Z"
+ content="""
+@joey: ok, I got it to connect and it indeed sent over a key etc. For some reason now though git-annex (on android) \"crashes\" shortly after starting. To be clear, the web app says that the program crashed, the console is still there. I suspect that it may have something to do with my largish remote repo and the time required to sync just the metadata, but I can't tell. Any ideas what I should do next? (Note that I *did* change it to manual mode because my phone doesn't have 30G of storage :)
+"""]]
diff --git a/doc/Android/oldcomments/comment_24_7ab509c25243009bfbffd796ec64e77b._comment b/doc/Android/oldcomments/comment_24_7ab509c25243009bfbffd796ec64e77b._comment
new file mode 100644
index 000000000..fdec15ac6
--- /dev/null
+++ b/doc/Android/oldcomments/comment_24_7ab509c25243009bfbffd796ec64e77b._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://afoolishmanifesto.com/"
+ nickname="frioux"
+ subject="comment 24"
+ date="2013-07-18T11:35:06Z"
+ content="""
+ok, it eventually got the details from the remote server, but now I'm getting some other oddities. here is some of my log that shows what I am running into
+
+Watcher crashed: addWatch: does not exist (No such file or directory) [2013-07-18 06:22:46 CDT] Watcher: warning Watcher crashed: addWatch: does not exist (No such file or directory) (scanning...) [2013-07-18 06:23:19 CDT] Watcher: Performing startup scan Watcher crashed: addWatch: does not exist (No such file or directory) [2013-07-18 06:24:28 CDT] Watcher: warning Watcher crashed: addWatch: does not exist (No such file or directory) (scanning...) [2013-07-18 06:24:31 CDT] Watcher: Performing startup scan Watcher crashed: addWatch: does not exist (No such file or directory) [2013-07-18 06:25:44 CDT] Watcher: warning Watcher crashed: addWatch: does not exist (No such file or directory)
+"""]]
diff --git a/doc/Android/oldcomments/comment_25_026d1a01d5753d71ac3dfc002f2a5eec._comment b/doc/Android/oldcomments/comment_25_026d1a01d5753d71ac3dfc002f2a5eec._comment
new file mode 100644
index 000000000..aa74230dc
--- /dev/null
+++ b/doc/Android/oldcomments/comment_25_026d1a01d5753d71ac3dfc002f2a5eec._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnRfQArYOmDd7r2DC7DkIJFOQgqXCVcAeU"
+ nickname="Frew"
+ subject="comment 25"
+ date="2013-07-18T13:14:46Z"
+ content="""
+frioux here (something messed up with myopenid or something)
+
+So I deleted the repo on my phone (via the CLI since the web app seemed hung) and recreated it; this time making sure that I set things to manual mode ASAP. It didn't have the problem it was having before, but now what seems to have happened is that it fetches from the remote, commits to the local repo, and then immediately fetches and commits again. It looks like it's about a 4s repeat loop. Any ideas what I should do next?
+"""]]
diff --git a/doc/Android/oldcomments/comment_26_f0a044fb649d43e32c96b08edbc336c3._comment b/doc/Android/oldcomments/comment_26_f0a044fb649d43e32c96b08edbc336c3._comment
new file mode 100644
index 000000000..c7c0e623f
--- /dev/null
+++ b/doc/Android/oldcomments/comment_26_f0a044fb649d43e32c96b08edbc336c3._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.140"
+ subject="comment 26"
+ date="2013-07-18T17:07:27Z"
+ content="""
+@Frew, you should file bug reports when you have a bug.
+
+One problem you mentioned had already had a bug report filed by someone
+else:
+<http://git-annex.branchable.com/bugs/Watcher_crashed:_addWatch:_does_not_exist/> So you can post your details there.
+"""]]
diff --git a/doc/Android/oldcomments/comment_27_6b9ae35b1ceeba14cd7a74e142870705._comment b/doc/Android/oldcomments/comment_27_6b9ae35b1ceeba14cd7a74e142870705._comment
new file mode 100644
index 000000000..b77e0873f
--- /dev/null
+++ b/doc/Android/oldcomments/comment_27_6b9ae35b1ceeba14cd7a74e142870705._comment
@@ -0,0 +1,34 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnaH44G3QbxBAYyDwy0PbvL0ls60XoaR3Y"
+ nickname="Nigel"
+ subject="Watcher crashed in Android on /storage/sdcard1 - bug?"
+ date="2013-07-29T11:50:46Z"
+ content="""
+In webapp UI, added on first install, the location for repository: /storage/sdcard1
+
+!warning
+
+Watcher crashed: addWatch:
+
+permission denied (Permission denied)
+
+[Restart Thread]
+
+:Performing startup scan
+
+
+In terminal Window 1:
+
+nex webapp <
+
+ Detected a crippled filesystem.
+
+ Enabling direct mode.
+
+ Detected a filesystem without fifo support.
+
+ Disabling ssh connection caching.
+
+
+Android 4.1.1 Huawei Y300 Annex.apk v1.0.52 version 4.20130723
+"""]]
diff --git a/doc/Android/oldcomments/comment_28_c91db1215f529aa68bfb0576c3c5eddc._comment b/doc/Android/oldcomments/comment_28_c91db1215f529aa68bfb0576c3c5eddc._comment
new file mode 100644
index 000000000..cf315c0d9
--- /dev/null
+++ b/doc/Android/oldcomments/comment_28_c91db1215f529aa68bfb0576c3c5eddc._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="Jonathan"
+ ip="63.131.117.194"
+ subject="link busybox: Read-only file system"
+ date="2013-07-29T20:08:12Z"
+ content="""
+Phone: HTC EVO 3d 4g
+Model Number: pg86100
+Android Version: 4.0.3
+"""]]
diff --git a/doc/Android/oldcomments/comment_2_c2422b7dd9d526b3616e49f48cf178c2._comment b/doc/Android/oldcomments/comment_2_c2422b7dd9d526b3616e49f48cf178c2._comment
new file mode 100644
index 000000000..bfa4decc4
--- /dev/null
+++ b/doc/Android/oldcomments/comment_2_c2422b7dd9d526b3616e49f48cf178c2._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-05-17T22:28:34Z"
+ content="""
+The Android app works on many non-rooted Android systems.
+
+The \"link busybox: Read-only file system\" means that `/data/data/ga.androidterm/lib/lib.busybox.so` cannot be hard linked to `/data/data/ga.androidterm/busybox`. That's not normal. I'd appreciate if you could provide more information on your Android device, like Android version and model number.
+"""]]
diff --git a/doc/Android/oldcomments/comment_3_0e4980c27b13dbc28477c02a82898248._comment b/doc/Android/oldcomments/comment_3_0e4980c27b13dbc28477c02a82898248._comment
new file mode 100644
index 000000000..fdbfac1c6
--- /dev/null
+++ b/doc/Android/oldcomments/comment_3_0e4980c27b13dbc28477c02a82898248._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://yarikoptic.myopenid.com/"
+ nickname="site-myopenid"
+ subject="Follow-up information on my system"
+ date="2013-05-18T01:23:28Z"
+ content="""
+Sorry for the delay: my android is stock Samsung-tuned Jelly beans.
+Android 4.1.2
+Baseband version N7000XXLSO
+
+not sure if that would be of any use :-/ nothing in the logs (aLogcat) if I filter by annex -- should there any debug output? what should be a key to search by?
+
+
+"""]]
diff --git a/doc/Android/oldcomments/comment_4_86f7b5444e2eaea7f8f7b9160f671a1d._comment b/doc/Android/oldcomments/comment_4_86f7b5444e2eaea7f8f7b9160f671a1d._comment
new file mode 100644
index 000000000..ad46a26be
--- /dev/null
+++ b/doc/Android/oldcomments/comment_4_86f7b5444e2eaea7f8f7b9160f671a1d._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnu1NYw8UF-NoDbKu8YKVGxi8FoZLH7JPs"
+ nickname="Chris"
+ subject="Not starting browser on Nexus 7, Android 4.2.2"
+ date="2013-05-19T14:04:28Z"
+ content="""
+I just tried to run this on my Nexus 7 which has Android 4.2.2, and I received the following: <http://hodapple.com/files/Screenshot_2013-05-19-09-49-53.png> <http://hodapple.com/files/git-annex-error.txt>
+
+In spite of that, though, the URL provided still worked.
+"""]]
diff --git a/doc/Android/oldcomments/comment_5_9d78009435736a178d5a3f5a9bc0ed6a._comment b/doc/Android/oldcomments/comment_5_9d78009435736a178d5a3f5a9bc0ed6a._comment
new file mode 100644
index 000000000..d29a59036
--- /dev/null
+++ b/doc/Android/oldcomments/comment_5_9d78009435736a178d5a3f5a9bc0ed6a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 5"
+ date="2013-05-19T19:46:14Z"
+ content="""
+@Chris, that is a known bug: [[bugs/Android_app_permission_denial_on_startup]]
+"""]]
diff --git a/doc/Android/oldcomments/comment_6_7b9523ddb20dc4a929e556c3ed0c7406._comment b/doc/Android/oldcomments/comment_6_7b9523ddb20dc4a929e556c3ed0c7406._comment
new file mode 100644
index 000000000..1c4aceaef
--- /dev/null
+++ b/doc/Android/oldcomments/comment_6_7b9523ddb20dc4a929e556c3ed0c7406._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 6"
+ date="2013-05-19T20:06:56Z"
+ content="""
+@yarikoptic, there is a process you can perform that will help me determine what's going on.
+
+You should be able to get the git-annex app to let you into a shell. You can do this by starting the app, and then going into its configuration menu, to Preferences, selecting \"Command Line\", and changing it to run \"/system/bin/sh\"
+
+Then when you open a new window in the git-annex app, you'll be at a shell prompt. From there, you can run:
+
+ls -ld /data/data/ga.androidterm
+
+I'm interested to know a) whether the directory exists and b) what permissions and owner it has. On my tablet, I get back \"drwxr-x--x app_39 app_39\" .. and if I run `id` in the shell, it tells me it's running as `app_39`.
+
+My guess is the directory probably does exist, but cannot be written to by the app. If you're able to verify that, the next step will be to investigate if there is some other directory that the app can write to. It needs to be able to write to someplace that is not on the `/sdcard` to install itself.
+"""]]
diff --git a/doc/Android/oldcomments/comment_7_a56628a622da752806c42c5b8b54ceef._comment b/doc/Android/oldcomments/comment_7_a56628a622da752806c42c5b8b54ceef._comment
new file mode 100644
index 000000000..df0c0a2de
--- /dev/null
+++ b/doc/Android/oldcomments/comment_7_a56628a622da752806c42c5b8b54ceef._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkwjBDXkP9HAQKhjTgThGOxUa1B99y_WRA"
+ nickname="Franck"
+ subject="Link issue"
+ date="2013-05-22T12:01:38Z"
+ content="""
+Hi, I have exactly the same problem with the link that fails on my phone. However, I checked the permissions and they are as you describe on your tablet (except for the app number). At the same time, everything is fine on my tablet... The phone runs an old Cyanogenmod 7.2.0 (Android 2.3.7) while the tablet is a more recent Asus TF700T (Android 4.1.1). Let me know if you want me to run tests.
+"""]]
diff --git a/doc/Android/oldcomments/comment_8_19656ec99b8f6aa64c1d01a3c9ae9bd0._comment b/doc/Android/oldcomments/comment_8_19656ec99b8f6aa64c1d01a3c9ae9bd0._comment
new file mode 100644
index 000000000..43ff8d64b
--- /dev/null
+++ b/doc/Android/oldcomments/comment_8_19656ec99b8f6aa64c1d01a3c9ae9bd0._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://yarikoptic.myopenid.com/"
+ nickname="site-myopenid"
+ subject="why ln failed"
+ date="2013-05-23T13:27:39Z"
+ content="""
+Finally got to check it out: so indeed hardlinking fails but not because of permissions but \"link failed Cross-device link\" that lib is -> /mnt/asec/ga.androidterm-1/lib which resides on a different partition (vfat, /dev/block/dm-2, ro) from /data (ext4, /dev/block/mmcblk0p10)
+"""]]
diff --git a/doc/Android/oldcomments/comment_9_55e703ae105d0c0ee9ac50df8cc59dfb._comment b/doc/Android/oldcomments/comment_9_55e703ae105d0c0ee9ac50df8cc59dfb._comment
new file mode 100644
index 000000000..0970412a4
--- /dev/null
+++ b/doc/Android/oldcomments/comment_9_55e703ae105d0c0ee9ac50df8cc59dfb._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 9"
+ date="2013-05-23T18:44:46Z"
+ content="""
+@yarikoptic you said before the error was \"Read-only file system\". Now you're saying it's \"Cross-device link\". I'm slightly confused.
+
+I've reworked the android app to not need any hard links. Try the current autobuild: <http://downloads.kitenet.net/git-annex/autobuild/android/git-annex.apk>
+"""]]
diff --git a/doc/android/DCIM.png b/doc/android/DCIM.png
new file mode 100644
index 000000000..3ac093323
--- /dev/null
+++ b/doc/android/DCIM.png
Binary files differ
diff --git a/doc/android/appinstalled.png b/doc/android/appinstalled.png
new file mode 100644
index 000000000..166120d48
--- /dev/null
+++ b/doc/android/appinstalled.png
Binary files differ
diff --git a/doc/android/apps.png b/doc/android/apps.png
new file mode 100644
index 000000000..310757f1e
--- /dev/null
+++ b/doc/android/apps.png
Binary files differ
diff --git a/doc/android/install.png b/doc/android/install.png
new file mode 100644
index 000000000..882455df1
--- /dev/null
+++ b/doc/android/install.png
Binary files differ
diff --git a/doc/android/newwindow.png b/doc/android/newwindow.png
new file mode 100644
index 000000000..4cca6ae09
--- /dev/null
+++ b/doc/android/newwindow.png
Binary files differ
diff --git a/doc/android/terminal.png b/doc/android/terminal.png
new file mode 100644
index 000000000..9afa2720f
--- /dev/null
+++ b/doc/android/terminal.png
Binary files differ
diff --git a/doc/android/webapp.png b/doc/android/webapp.png
new file mode 100644
index 000000000..edb5c5ccd
--- /dev/null
+++ b/doc/android/webapp.png
Binary files differ
diff --git a/doc/assistant.mdwn b/doc/assistant.mdwn
new file mode 100644
index 000000000..ccad08893
--- /dev/null
+++ b/doc/assistant.mdwn
@@ -0,0 +1,43 @@
+The git-annex assistant creates a synchronised folder on each of your
+OSX and Linux computers, Android devices, removable drives, and
+cloud services. The contents of the folder are the same everywhere.
+It's very easy to use, and has all the power of git and git-annex.
+
+## installation
+
+The git-annex assistant comes as part of git-annex.
+See [[install]] to get it installed.
+
+See the [[release_notes]] for an overview of the status, and upgrade
+instructions.
+
+## intro screencast
+
+[[!inline feeds=no template=bare pages=videos/git-annex_assistant_introduction]]
+
+## documentation
+
+* [[Basic usage|quickstart]]
+* [[Android documentation|/Android]]
+* Want to make two nearby computers share the same synchronised folder?
+ Follow the [[local_pairing_walkthrough]].
+* Or perhaps you want to share files between computers in different
+ locations, like home and work?
+ Follow the [[remote_sharing_walkthrough]].
+* Want to share a synchronised folder with a friend?
+ Follow the [[share_with_a_friend_walkthrough]].
+* Want to archive data to a drive or the cloud?
+ Follow the [[archival_walkthrough]].
+
+## colophon
+
+The git-annex assistant was [crowd funded on
+Kickstarter](http://www.kickstarter.com/projects/joeyh/git-annex-assistant-like-dropbox-but-with-your-own/).
+[[/assistant/Thanks]] to all my backers. This kickstarter is now closed,
+and there is a new home-made crowdfunding project to support the project
+for 2013-2014 [here](https://campaign.joeyh.name/).
+
+I blog about my work on git-annex and the assistant on a daily basis
+in [[this_blog|/devblog]]. Follow along!
+
+See also: The [[design|/design/assistant]] pages.
diff --git a/doc/assistant/addsshserver.png b/doc/assistant/addsshserver.png
new file mode 100644
index 000000000..80f5d5617
--- /dev/null
+++ b/doc/assistant/addsshserver.png
Binary files differ
diff --git a/doc/assistant/archival_walkthrough.mdwn b/doc/assistant/archival_walkthrough.mdwn
new file mode 100644
index 000000000..925e34944
--- /dev/null
+++ b/doc/assistant/archival_walkthrough.mdwn
@@ -0,0 +1,32 @@
+Normally, the git-annex assistant makes your files be available
+wherever you use it, and so a copy of each file is stored in each repository.
+That's perfect for files you're using right now, but what about files you're
+not using any more?
+
+You could just delete those files, but it's better to archive them, so
+you can access them later. All you need to get started archiving your old
+files is a USB drive, or an [Amazon Glacier](http://aws.amazon.com/glacier/)
+account.
+
+The webapp makes it easy to make a repository on either a USB drive,
+or on Amazon Glacier. Once the repository is created, be sure to
+put it in either the small archive, or full archive repository group.
+
+[[!img repogroups.png]]
+
+Now when you're done with a file, just move it into a directory named
+"archive". The assistant will notice you put it there, and next time it
+has the opportunity (when you plug in the USB drive, or when it can
+talk to Amazon Glacier over the network), will move the file's
+content to your archive repository.
+
+You'll no longer be able to open the file once it's been archived.
+If you later want to access it, you can just copy or move it out
+of the archive directory, and the assistant will retrieve its
+content from the archive.
+
+Note that retrieving data from Amazon Glacier takes 4 to 5 hours.
+
+### screencast
+
+[[!inline feeds=no template=bare pages=videos/git-annex_assistant_archiving]]
diff --git a/doc/assistant/brokenrepositoryalert.png b/doc/assistant/brokenrepositoryalert.png
new file mode 100644
index 000000000..ea001aec0
--- /dev/null
+++ b/doc/assistant/brokenrepositoryalert.png
Binary files differ
diff --git a/doc/assistant/buddylist.png b/doc/assistant/buddylist.png
new file mode 100644
index 000000000..40b5a9238
--- /dev/null
+++ b/doc/assistant/buddylist.png
Binary files differ
diff --git a/doc/assistant/cloudnudge.png b/doc/assistant/cloudnudge.png
new file mode 100644
index 000000000..b6f9a657e
--- /dev/null
+++ b/doc/assistant/cloudnudge.png
Binary files differ
diff --git a/doc/assistant/combinerepos.png b/doc/assistant/combinerepos.png
new file mode 100644
index 000000000..7beea71bc
--- /dev/null
+++ b/doc/assistant/combinerepos.png
Binary files differ
diff --git a/doc/assistant/comment_1_f2c4857b7b000e005f0c19279db14eaf._comment b/doc/assistant/comment_1_f2c4857b7b000e005f0c19279db14eaf._comment
new file mode 100644
index 000000000..1ed185e48
--- /dev/null
+++ b/doc/assistant/comment_1_f2c4857b7b000e005f0c19279db14eaf._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkYrMBMTCEFUKskhWGD-1pzcw2ITshsi_8"
+ nickname="Robert"
+ subject="Annex on OS X 10.6"
+ date="2013-06-04T23:10:03Z"
+ content="""
+I really hope they can get annex working on os x 10.6. This is a great effort. Thanks
+"""]]
diff --git a/doc/assistant/comment_2_befa1f48e5a43a7965060491430a6bc4._comment b/doc/assistant/comment_2_befa1f48e5a43a7965060491430a6bc4._comment
new file mode 100644
index 000000000..cbc955b07
--- /dev/null
+++ b/doc/assistant/comment_2_befa1f48e5a43a7965060491430a6bc4._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9smfyJFgp3f2WjqqZWY6b7vo5eZv7GGQ"
+ nickname="Bryan"
+ subject="Ooh. Do want on Windows"
+ date="2013-07-03T20:44:05Z"
+ content="""
+Sadly, I didn't know about this when the Kickstarter was underway - I'd be happy to chip in $100 if it means I can get annex assistant on Windows earlier.
+
+"""]]
diff --git a/doc/assistant/controlmenu.png b/doc/assistant/controlmenu.png
new file mode 100644
index 000000000..c1dac197b
--- /dev/null
+++ b/doc/assistant/controlmenu.png
Binary files differ
diff --git a/doc/assistant/crashrecovery.png b/doc/assistant/crashrecovery.png
new file mode 100644
index 000000000..fce3805d0
--- /dev/null
+++ b/doc/assistant/crashrecovery.png
Binary files differ
diff --git a/doc/assistant/dashboard.png b/doc/assistant/dashboard.png
new file mode 100644
index 000000000..c71558d79
--- /dev/null
+++ b/doc/assistant/dashboard.png
Binary files differ
diff --git a/doc/assistant/deleterepository.png b/doc/assistant/deleterepository.png
new file mode 100644
index 000000000..20db674ca
--- /dev/null
+++ b/doc/assistant/deleterepository.png
Binary files differ
diff --git a/doc/assistant/downloadupgrade.png b/doc/assistant/downloadupgrade.png
new file mode 100644
index 000000000..157eaddc7
--- /dev/null
+++ b/doc/assistant/downloadupgrade.png
Binary files differ
diff --git a/doc/assistant/encryptdrive.png b/doc/assistant/encryptdrive.png
new file mode 100644
index 000000000..1cb041dda
--- /dev/null
+++ b/doc/assistant/encryptdrive.png
Binary files differ
diff --git a/doc/assistant/example.png b/doc/assistant/example.png
new file mode 100644
index 000000000..bfcb9afa6
--- /dev/null
+++ b/doc/assistant/example.png
Binary files differ
diff --git a/doc/assistant/fsckconfig.png b/doc/assistant/fsckconfig.png
new file mode 100644
index 000000000..81ae755cf
--- /dev/null
+++ b/doc/assistant/fsckconfig.png
Binary files differ
diff --git a/doc/assistant/genkey.png b/doc/assistant/genkey.png
new file mode 100644
index 000000000..6c1e50971
--- /dev/null
+++ b/doc/assistant/genkey.png
Binary files differ
diff --git a/doc/assistant/iaitem.png b/doc/assistant/iaitem.png
new file mode 100644
index 000000000..2fcc1b4c8
--- /dev/null
+++ b/doc/assistant/iaitem.png
Binary files differ
diff --git a/doc/assistant/inotify_max_limit_alert.png b/doc/assistant/inotify_max_limit_alert.png
new file mode 100644
index 000000000..d8d334152
--- /dev/null
+++ b/doc/assistant/inotify_max_limit_alert.png
Binary files differ
diff --git a/doc/assistant/local_pairing_walkthrough.mdwn b/doc/assistant/local_pairing_walkthrough.mdwn
new file mode 100644
index 000000000..f6282ec28
--- /dev/null
+++ b/doc/assistant/local_pairing_walkthrough.mdwn
@@ -0,0 +1,90 @@
+So you have two computers in the same building, and you want them to share
+the same synchronised folder, communicating directly with each other.
+
+This is incredibly easy to set up with the git annex assistant.
+
+Let's say the two computers are your computer and your friend's computer.
+We'll start on your computer, where you open up your git annex dashboard.
+
+[[!img addrepository.png alt="Add another repository button"]]
+
+`*click*`
+
+[[!img pairing.png alt="Pair with another computer"]]
+
+`*click*`
+
+Now the hard bit. You have to think up a secret phrase, and type it in,
+(and perhaps get the spelling correct).
+
+[[!img secret.png alt="Enter secret phrase"]]
+
+Now your computer is in pairing mode. When your friend looks at her git
+annex dashboard, she sees something like this.
+
+[[!img pairrequest.png alt="Pair request"]]
+
+`*click*`
+
+[[!img secretempty.png alt="Enter same secret phrase"]]
+
+Now it's up to you to let her know what the secret is. As soon as she
+enters it, both your computers will be paired, and will begin to sync their
+git-annex folders. Just like that you can share files.
+
+----
+
+## Requirements
+
+For local pairing to work, you must have sshd (ssh server daemon) installed and working on all machines involved. That means you must allow at least local connections to sshd. On most Linux distributions, sshd is packaged in either openssh (openSUSE) or openssh-server (Debian).
+
+It is highly recommended that you disable root login, disable password login to sshd and just enable key based authentication instead. No one will be able to login without your key.
+
+To disable root, after installing sshd, edit the sshd config (usually /etc/ssh/sshd_config file) and disable root login by adding:
+
+ PermitRootLogin no
+
+Restart sshd. See man sshd_config for details.
+
+To disable password login and enable key based authentication, edit the sshd config (just like above) by uncommenting and changing the following options:
+
+ ChallengeResponseAuthentication no
+ PasswordAuthentication no
+ UsePAM no
+
+ PubkeyAuthentication yes
+
+Restart sshd. See man sshd_config for details.
+
+You can also restrict login to your local network only (not allow internet users from trying to log into your computer). Edit the hosts.deny file (usually /etc/hosts.deny) by adding the following:
+
+ sshd : ALL EXCEPT LOCAL
+
+Do note that restricting login to your local network may or may not block git-annex. Also note that this will not work on Mac OSX because Apple decided to disable this feature and replace it with a crippled version made by Apple.
+
+## Tips
+
+Something to keep in mind, especially if pairing doesn't seem to be
+working, is that the two computers need to be on the same network for this
+pairing process to work. Sometimes a building will have more than one
+network inside it, and you'll need to connect them both to the same one.
+Make sure the wireless network name is the same, or that they're both
+plugged into the same router.
+
+Also, the file sharing set up by this pairing only works when both
+computers are on the same network. If you go on a trip, any files you
+edit will not be visible to your friend until you get back.
+
+To get around this, you'll often also want to set up
+[[jabber_pairing|share_with_a_friend_walkthrough]], and a server
+in the cloud, which they can use to exchange files while away.
+
+And also, you can pair with as many other computers as you like, not just
+one!
+
+## What does pairing actually do behind the scenes?
+
+It ensures that both repositories have correctly configured
+[[remotes|walkthrough/adding_a_remote]] pointing to each other.
+If you have already configured this manually, you do not need to
+perform pairing.
diff --git a/doc/assistant/local_pairing_walkthrough/addrepository.png b/doc/assistant/local_pairing_walkthrough/addrepository.png
new file mode 100644
index 000000000..b82efdbea
--- /dev/null
+++ b/doc/assistant/local_pairing_walkthrough/addrepository.png
Binary files differ
diff --git a/doc/assistant/local_pairing_walkthrough/comment_1_b33deed054d3aa8cfa6c9e3958643f16._comment b/doc/assistant/local_pairing_walkthrough/comment_1_b33deed054d3aa8cfa6c9e3958643f16._comment
new file mode 100644
index 000000000..52bdc7f4e
--- /dev/null
+++ b/doc/assistant/local_pairing_walkthrough/comment_1_b33deed054d3aa8cfa6c9e3958643f16._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://launchpad.net/~mattharrison"
+ ip="69.193.72.98"
+ subject="Pairing"
+ date="2012-10-29T17:56:06Z"
+ content="""
+Is there a way to do this pairing with one machine being a desktop machine and one a headless machine?
+"""]]
diff --git a/doc/assistant/local_pairing_walkthrough/comment_2_39f1162b4d43b61e957e7497df4b9e2b._comment b/doc/assistant/local_pairing_walkthrough/comment_2_39f1162b4d43b61e957e7497df4b9e2b._comment
new file mode 100644
index 000000000..32d56c907
--- /dev/null
+++ b/doc/assistant/local_pairing_walkthrough/comment_2_39f1162b4d43b61e957e7497df4b9e2b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.194"
+ subject="easy peasy"
+ date="2012-10-29T19:09:43Z"
+ content="""
+A headless machine is probably a server. On the same page that has the \"local computer\" link, there's a \"remote server\" link that'll get you set up.
+"""]]
diff --git a/doc/assistant/local_pairing_walkthrough/comment_3_588869692b290483f58f3a7aa2bfb55f._comment b/doc/assistant/local_pairing_walkthrough/comment_3_588869692b290483f58f3a7aa2bfb55f._comment
new file mode 100644
index 000000000..6edaadb75
--- /dev/null
+++ b/doc/assistant/local_pairing_walkthrough/comment_3_588869692b290483f58f3a7aa2bfb55f._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="https://openid.fmarier.org/"
+ nickname="fmarier"
+ subject="Ports to open on the firewall?"
+ date="2013-05-04T03:56:55Z"
+ content="""
+I'm trying to get local pairing working between two local machines (same switch, both connected via cat5 cables) and they're not seeing each other, though I can happily ssh from one box to the other.
+
+In order to eliminate possible sources of problems, I tried these insecure settings:
+
+* add a `-A INPUT -j ACCEPT` to the top of my firewall rules
+* use `password` as the shared secret
+
+but I still can't get past \"pairing in progress\" when pairing with a \"Local computer\".
+
+Is there any way to get information as to where the two machines are failing to see one another?
+"""]]
diff --git a/doc/assistant/local_pairing_walkthrough/comment_4_f6bf82c263fefe38701709d9dbd974cc._comment b/doc/assistant/local_pairing_walkthrough/comment_4_f6bf82c263fefe38701709d9dbd974cc._comment
new file mode 100644
index 000000000..6a9637481
--- /dev/null
+++ b/doc/assistant/local_pairing_walkthrough/comment_4_f6bf82c263fefe38701709d9dbd974cc._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 4"
+ date="2013-05-04T16:39:23Z"
+ content="""
+Local pairing uses UDP port 55556. This is sent to multicast address 224.0.0.251 (same used by Avahi).
+
+(You also need TCP port 22 open for ssh.)
+"""]]
diff --git a/doc/assistant/local_pairing_walkthrough/comment_5_bada601ea4b7104f162a3e00def4be2b._comment b/doc/assistant/local_pairing_walkthrough/comment_5_bada601ea4b7104f162a3e00def4be2b._comment
new file mode 100644
index 000000000..989e80d8a
--- /dev/null
+++ b/doc/assistant/local_pairing_walkthrough/comment_5_bada601ea4b7104f162a3e00def4be2b._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="https://openid.fmarier.org/"
+ nickname="fmarier"
+ subject="Still stuck at &quot;pairing in progress&quot;"
+ date="2013-05-05T00:26:16Z"
+ content="""
+I hadn't thought of ssh. So here's what I've got now:
+
+* both laptop and desktop have `-A INPUT -d 224.0.0.251/32 -p udp --dport 55556 -j ACCEPT`
+* `git annex webapp` is running as user `francois` on both machines
+* laptop has `openssh-server` running on port 22 and its firewall allows desktop to connect
+* desktop has `openssh-server` running on port 22 and its firewall allows the whole internal network to connect
+* laptop's ssh pubkey is in francois' `~/.ssh/authorized_keys` on desktop and ssh'ing works
+* deskop's ssh pubkey is **not** in francois' `~/.ssh/authorized_keys` on laptop (is that required?)
+* (as mentioned before) both desktop and laptop are on the same switch and connected over CAT5
+* I'm using `password` as a pairing key just to rule out any typos there
+
+I don't see anything in the git-annex log on both of these machines. There's just a bunch of key generation stuff and then the last line is \"Pairing in progress\".
+"""]]
diff --git a/doc/assistant/local_pairing_walkthrough/comment_6_01ba0f9bfa0ed066c4b73d2d6028eecc._comment b/doc/assistant/local_pairing_walkthrough/comment_6_01ba0f9bfa0ed066c4b73d2d6028eecc._comment
new file mode 100644
index 000000000..1b2f66bd9
--- /dev/null
+++ b/doc/assistant/local_pairing_walkthrough/comment_6_01ba0f9bfa0ed066c4b73d2d6028eecc._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 6"
+ date="2013-05-06T15:14:06Z"
+ content="""
+It's quite possible that your router doesn't handle multicast traffic to 224.0.0.251. The best way to check is to a) see if avahi/zeroconf works, since it's sending similar traffic and b) run tcpdump on both machines and see if the packets being sent on port 55556 by one are seen by the other.
+"""]]
diff --git a/doc/assistant/local_pairing_walkthrough/comment_7_17d44229e4fa46c50815672b96a9735a._comment b/doc/assistant/local_pairing_walkthrough/comment_7_17d44229e4fa46c50815672b96a9735a._comment
new file mode 100644
index 000000000..84a921eab
--- /dev/null
+++ b/doc/assistant/local_pairing_walkthrough/comment_7_17d44229e4fa46c50815672b96a9735a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://openid.fmarier.org/"
+ nickname="fmarier"
+ subject="Make sure your network is correctly set up in the first place!"
+ date="2013-05-12T08:37:38Z"
+ content="""
+It turns out that my internal network had badly broken IPv6 configs between the boxes. That was interfering with the multicast packets but not with anything else since all of my other internal traffic is over IPv4.
+
+Getting rid of these static IPv6 addresses has solved my problem. Local pairing is now working as advertised :)
+"""]]
diff --git a/doc/assistant/local_pairing_walkthrough/comment_8_b9d4c29cf2cca0427808df6af08fb789._comment b/doc/assistant/local_pairing_walkthrough/comment_8_b9d4c29cf2cca0427808df6af08fb789._comment
new file mode 100644
index 000000000..31a0f9674
--- /dev/null
+++ b/doc/assistant/local_pairing_walkthrough/comment_8_b9d4c29cf2cca0427808df6af08fb789._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 8"
+ date="2013-05-13T17:22:17Z"
+ content="""
+I don't understand how IPv6 could affect local pairing. The assistant does not currently do pairing over ipv6 due to a limitation in the multicast library it's using.
+"""]]
diff --git a/doc/assistant/local_pairing_walkthrough/pairing.png b/doc/assistant/local_pairing_walkthrough/pairing.png
new file mode 100644
index 000000000..dfbbf0641
--- /dev/null
+++ b/doc/assistant/local_pairing_walkthrough/pairing.png
Binary files differ
diff --git a/doc/assistant/local_pairing_walkthrough/pairrequest.png b/doc/assistant/local_pairing_walkthrough/pairrequest.png
new file mode 100644
index 000000000..8d3f603bf
--- /dev/null
+++ b/doc/assistant/local_pairing_walkthrough/pairrequest.png
Binary files differ
diff --git a/doc/assistant/local_pairing_walkthrough/secret.png b/doc/assistant/local_pairing_walkthrough/secret.png
new file mode 100644
index 000000000..1eb805122
--- /dev/null
+++ b/doc/assistant/local_pairing_walkthrough/secret.png
Binary files differ
diff --git a/doc/assistant/local_pairing_walkthrough/secretempty.png b/doc/assistant/local_pairing_walkthrough/secretempty.png
new file mode 100644
index 000000000..491878784
--- /dev/null
+++ b/doc/assistant/local_pairing_walkthrough/secretempty.png
Binary files differ
diff --git a/doc/assistant/logs.png b/doc/assistant/logs.png
new file mode 100644
index 000000000..8e9e5b1ec
--- /dev/null
+++ b/doc/assistant/logs.png
Binary files differ
diff --git a/doc/assistant/makerepo.png b/doc/assistant/makerepo.png
new file mode 100644
index 000000000..e8f1b2621
--- /dev/null
+++ b/doc/assistant/makerepo.png
Binary files differ
diff --git a/doc/assistant/menu.png b/doc/assistant/menu.png
new file mode 100644
index 000000000..29a7c9d0f
--- /dev/null
+++ b/doc/assistant/menu.png
Binary files differ
diff --git a/doc/assistant/osx-app.png b/doc/assistant/osx-app.png
new file mode 100644
index 000000000..386fb832d
--- /dev/null
+++ b/doc/assistant/osx-app.png
Binary files differ
diff --git a/doc/assistant/preferences.png b/doc/assistant/preferences.png
new file mode 100644
index 000000000..74fb81418
--- /dev/null
+++ b/doc/assistant/preferences.png
Binary files differ
diff --git a/doc/assistant/quickstart.mdwn b/doc/assistant/quickstart.mdwn
new file mode 100644
index 000000000..0472ba48b
--- /dev/null
+++ b/doc/assistant/quickstart.mdwn
@@ -0,0 +1,30 @@
+## first run
+
+To get started with the git-annex assistant, just pick it from
+your system's list of applications.
+
+[[!img assistant/menu.png]]
+[[!img assistant/osx-app.png]]
+
+It'll prompt you to set up a folder:
+
+[[!img assistant/makerepo.png]]
+
+Then any changes you make to its folder will automatically be committed to
+git, and synced to repositories on other computers. You can use the
+interface to add repositories and control the git-annex assistant.
+
+[[!img assistant/running.png]]
+
+## starting on boot
+
+The git-annex assistant will automatically be started when you log in to
+desktop environments like Mac OS X, Gnome, XFCE, and KDE, and the menu item
+shown above can be used to open the webapp. On other systems, you may need
+to start it by hand.
+
+To start the webapp, run `git annex webapp` at the command line.
+
+To start the assistant without opening the webapp,
+you can run the command "git annex assistant --autostart". This is a
+good thing to configure your system to run automatically when you log in.
diff --git a/doc/assistant/release_notes.mdwn b/doc/assistant/release_notes.mdwn
new file mode 100644
index 000000000..1b1ece0a0
--- /dev/null
+++ b/doc/assistant/release_notes.mdwn
@@ -0,0 +1,365 @@
+## version 4.20131024
+
+This version fixes several different bugs that could cause the webapp to
+refuse to create a repository. Several other bugs are also fixed, including
+a bug that caused it to not add files on Android.
+
+New in this release is the ability to use the webapp to set up scheduled
+consistency checks of your repositories. Many problems with repositories
+are now automatically corrected, and it can even repair damaged git
+repositories.
+
+This is a recommended upgrade.
+
+## version 4.20131002
+
+Now you can use the webapp to set up an encrypted git repository on a
+remote ssh server, or on rsync.net, and use it as a live cloud backup. Or,
+use the webapp to make an encrypted git repository on a removable drive,
+and store it offsite as a secure backup.
+
+## version 4.20130920
+
+This release is the first to support fully encrypted git repositories
+stored on removable drives. This can be set up easily using the webapp.
+
+## version 4.20130909
+
+This release fixes a crash that could occur when using XMPP with the
+assitant. It has only been seen on OS X so far. The bug is not believed to
+be explitable, but upgrading is still recommended.
+
+## version 4.20130802
+
+This release fixes several bugs, including a reversion introduced in the last
+version that broke direct mode on Windows, Android, and other crippled
+filesystems. It contains a workaround for a bug in recent git pre-releases
+that broke handling of filenames containing spaces.
+It is a highly recommended upgrade.
+
+The webapp can now detect repositories that did not finish getting properly set
+up, and can recover from one common bug that broke local pairing and remote
+ssh server setups on systems using `ssh-agent`.
+
+## version 4.20130723
+
+This release fixes some bugs. Notably it fixes a bug that could result in data
+loss when adding a tarball of a git-annex repository to your git-annex
+repository.
+
+Rsync.net have committed to support git-annex and offer a special
+discounted rate for git-annex users.
+<http://www.rsync.net/products/git-annex-pricing.html>
+
+## version 4.20130709
+
+This release is mostly bug fixes.
+
+One of the bugs involved setting up rsync remotes on servers other than
+rsync.net. The wrong `.ssh/authorized_keys` line was deployed to the
+remote server. If you set up a rsync remote with a past release, and it does
+not work, you will need to manually edit the `.ssh/authorized_keys` file,
+and remove the `command=` forced command.
+
+## version 4.20130621, 4.20130627
+
+These releases mostly consist of bug fixes.
+
+## version 4.20130601
+
+This is a bugfix release, featuring significant XMPP improvements and
+more robustness thanks to automated fuzz testing. Recommended upgrade.
+
+This version changes its XMPP protocol, so it will fail to sync with older
+git-annex versions over XMPP.
+
+## version 4.20130521
+
+This is a bugfix release. Recommended upgrade.
+
+## version 4.20130516
+
+This version contains numerous bug fixes, and improvements.
+
+This is the first release with a fully usable Android app. No command-line
+typing needed to set up syncing to your Android phone or tablet!
+A few of the more advanced features may not work (or not work reliably)
+on Android. The Android app is still beta quality.
+
+This is also the first release with a Windows port! The Windows port
+is in an alpha quality state, and is missing many features.
+It does not yet include the assistant.
+
+## version 4.20130501
+
+This version contains numerous bug fixes, and improvements.
+
+## version 4.20130417
+
+This version contains numerous bug fixes, and improvements.
+
+One bug that was fixed can affect users of gnome-keyring who
+have set up remote repositories on ssh servers using the webapp.
+The gnome-keyring may load the restricted key that is set up
+for that, and make it be used for regular logins to the server;
+with the result that you'll get an error message about "git-annex-shell"
+when sshing to the server.
+
+If you experience this problem you can fix it by
+moving `.ssh/key.git-annex*` to `.ssh/git-annex/` (creating
+that directory first), and edit `.ssh/config` to reflect the new
+location of the key. You will also need to restart gnome-keyring.
+
+Another change relates to files in `archive/` directories. Client repositories
+now sync these files between themselves like any other files, until
+the files reach an archive repository. Only then are they removed from
+the client repositories. So you need to ensure you have at least one
+archive repository if you want to use the `archive/` directory feature.
+
+## version 4.20130323, 4.20130405
+
+These versions continue fixing bugs and adding features.
+
+## version 4.20130314
+
+This version makes a great many improvements and bugfixes, and is
+a recommended upgrade.
+
+If you have already used the webapp to locally pair two computers,
+a bug caused the paired repository to not be given an appropriate cost.
+To fix this, go into the Repositories page in the webapp, and drag the
+repository for the locally paired computer to come before any repositories
+that it's more expensive to transfer data to.
+
+## version 4.20130227
+
+This release fixes a bug with globbing that broke preferred content expressions.
+So, it is a recommended upgrade from the previous release, which introduced
+that bug.
+
+In this release, the assistant is fully working on Android, although
+it must be set up using the command line.
+
+Repositories can now be placed on filesystems that lack support for symbolic
+links; FAT support is complete.
+
+## version 3.20130216
+
+This adds a port to Android. Only usable at the command line so far;
+beta qualitty.
+
+Also a bugfix release, and improves support for FAT.
+
+The following are known limitations of this release of the git-annex
+assistant:
+
+* No Android app yet.
+* On BSD operating systems (but not on OS X), the assistant uses kqueue to
+ watch files. Kqueue has to open every directory it watches, so too many
+ directories will run it out of the max number of open files (typically
+ 1024), and fail. See [[this_bug|bugs/Issue_on_OSX_with_some_system_limits]]
+ for a workaround.
+* Also on systems with kqueue, modifications to existing files in direct
+ mode will not be noticed.
+
+## version 3.20130107, 3.20130114, 3.20130124, 3.20130207
+
+These are bugfix releases.
+
+## version 3.20130102
+
+This release makes several significant improvements to the git-annex
+assistant, which is still in beta.
+
+The main improvement is direct mode. This allows you to directly edit files
+in the repository, and the assistant will automatically commit and sync
+your changes. Direct mode is the default for new repositories created
+by the assistant. To convert your existing repository to use direct mode,
+manually run `git annex direct` inside the repository.
+
+## version 3.20121211
+
+This release of the git-annex assistant (which is still in beta)
+consists of mostly bugfixes, user interface improvements, and improvements
+to existing features.
+
+In general, anything you can configure with the assistant's web app
+will work. Some examples of use cases supported by this release include:
+
+* Using Box.com's 5 gigabytes of free storage space as a cloud transfer
+ point between between repositories that cannot directly contact
+ one-another. (Many other cloud providers are also supported, from Rsync.net
+ to Amazon S3, to your own ssh server.)
+* Archiving or backing up files to Amazon Glacier. See [[archival_walkthrough]].
+* [[Sharing repositories with friends|share_with_a_friend_walkthrough]]
+ contacted through a Jabber server (such as Google Talk).
+* [[Pairing|local_pairing_walkthrough]] two computers that are on the same local
+ network (or VPN) and automatically keeping the files in the annex in
+ sync as changes are made to them.
+* Cloning your repository to removable drives, USB keys, etc. The assistant
+ will notice when the drive is mounted and keep it in sync.
+ Such a drive can be stored as an offline backup, or transported between
+ computers to keep them in sync.
+
+The following are known limitations of this release of the git-annex
+assistant:
+
+* The Max OSX standalone app may not work on all versions of Max OSX.
+ Please test!
+* On Mac OSX and BSD operating systems, the assistant uses kqueue to watch
+ files. Kqueue has to open every directory it watches, so too many
+ directories will run it out of the max number of open files (typically
+ 1024), and fail. See [[bugs/Issue_on_OSX_with_some_system_limits]]
+ for a workaround.
+
+## version 3.20121126
+
+This adds several features to the git-annex assistant, which is still in beta.
+
+In general, anything you can configure with the assistant's web app
+will work. Some examples of use cases supported by this release include:
+
+* Using Box.com's 5 gigabytes of free storage space as a cloud transfer
+ point between between repositories that cannot directly contact
+ one-another. (Many other cloud providers are also supported, from Rsync.net
+ to Amazon S3, to your own ssh server.)
+* Archiving or backing up files to Amazon Glacier.
+* [[Sharing repositories with friends|share_with_a_friend_walkthrough]]
+ contacted through a Jabber server (such as Google Talk).
+* [[Pairing|local_pairing_walkthrough]] two computers that are on the same local
+ network (or VPN) and automatically keeping the files in the annex in
+ sync as changes are made to them.
+* Cloning your repository to removable drives, USB keys, etc. The assistant
+ will notice when the drive is mounted and keep it in sync.
+ Such a drive can be stored as an offline backup, or transported between
+ computers to keep them in sync.
+
+The following are known limitations of this release of the git-annex
+assistant:
+
+* The Max OSX standalone app does not work on all versions of Max OSX.
+* On Mac OSX and BSD operating systems, the assistant uses kqueue to watch
+ files. Kqueue has to open every directory it watches, so too many
+ directories will run it out of the max number of open files (typically
+ 1024), and fail. See [[bugs/Issue_on_OSX_with_some_system_limits]]
+ for a workaround.
+* Retrieval of files from Amazon Glacier is not fully automated; the
+ assistant does not automatically retry in the 4 to 5 hours period
+ when Glacier makes the files available.
+
+## version 3.20121112
+
+This is a major upgrade of the git-annex assistant, which is still in beta.
+
+In general, anything you can configure with the assistant's web app
+will work. Some examples of use cases supported by this release include:
+
+* [[Sharing repositories with friends|share_with_a_friend_walkthrough]]
+ contacted through a Jabber server (such as Google Talk).
+* Setting up cloud repositories, that are used as backups, archives,
+ or transfer points between repositories that cannot directly contact
+ one-another.
+* [[Pairing|local_pairing_walkthrough]] two computers that are on the same local
+ network (or VPN) and automatically keeping the files in the annex in
+ sync as changes are made to them.
+* Cloning your repository to removable drives, USB keys, etc. The assistant
+ will notice when the drive is mounted and keep it in sync.
+ Such a drive can be stored as an offline backup, or transported between
+ computers to keep them in sync.
+
+The following upgrade notes apply if you're upgrading from a previous version:
+
+* For best results, edit the configuration of repositories you set
+ up with older versions, and place them in a repository group.
+ This lets the assistant know how you want to use the repository; for backup,
+ archival, as a transfer point for clients, etc. Go to Configuration -&gt;
+ Manage Repositories, and click in the "configure" link to edit a repository's
+ configuration.
+* If you set up a cloud repository with an older version, and have multiple
+ clients using it, you are recommended to configure an Jabber account,
+ so that clients can use it to communicate when sending data to the
+ cloud repository. Configure Jabber by opening the webapp, and going to
+ Configuration -&gt; Configure jabber account
+* When setting up local pairing, the assistant did not limit the paired
+ computer to accessing a single git repository. This new version does,
+ by setting GIT_ANNEX_SHELL_DIRECTORY in `~/.ssh/authorized_keys`.
+
+The following are known limitations of this release of the git-annex
+assistant:
+
+* On Mac OSX and BSD operating systems, the assistant uses kqueue to watch
+ files. Kqueue has to open every directory it watches, so too many
+ directories will run it out of the max number of open files (typically
+ 1024), and fail. See [[bugs/Issue_on_OSX_with_some_system_limits]]
+ for a workaround.
+
+## version 3.20121009
+
+This is a maintenance release of the git-annex assistant, which is still in
+beta.
+
+In general, anything you can configure with the assistant's web app
+will work. Some examples of use cases supported by this release include:
+
+* [[Pairing|local_pairing_walkthrough]] two computers that are on the same local
+ network (or VPN) and automatically keeping the files in the annex in
+ sync as changes are made to them.
+* Cloning your repository to removable drives, USB keys, etc. The assistant
+ will notice when the drive is mounted and keep it in sync.
+ Such a drive can be stored as an offline backup, or transported between
+ computers to keep them in sync.
+* Cloning your repository to a remote server, running ssh, and uploading
+ changes made to your files to the server. There is special support
+ for using the rsync.net cloud provider this way, or any shell account
+ on a typical unix server, such as a Linode VPS can be used.
+
+The following are known limitations of this release of the git-annex
+assistant:
+
+* On Mac OSX and BSD operating systems, the assistant uses kqueue to watch
+ files. Kqueue has to open every directory it watches, so too many
+ directories will run it out of the max number of open files (typically
+ 1024), and fail. See [[bugs/Issue_on_OSX_with_some_system_limits]]
+ for a workaround.
+* In order to ensure that all multiple repositories are kept in sync,
+ each computer with a repository must be running the git-annex assistant.
+* The assistant does not yet always manage to keep repositories in sync
+ when some are hidden from others behind firewalls.
+
+## version 3.20120924
+
+This is the first beta release of the git-annex assistant.
+
+In general, anything you can configure with the assistant's web app
+will work. Some examples of use cases supported by this release include:
+
+* [[Pairing|local_pairing_walkthrough]] two computers that are on the same local
+ network (or VPN) and automatically keeping the files in the annex in
+ sync as changes are made to them.
+* Cloning your repository to removable drives, USB keys, etc. The assistant
+ will notice when the drive is mounted and keep it in sync.
+ Such a drive can be stored as an offline backup, or transported between
+ computers to keep them in sync.
+* Cloning your repository to a remote server, running ssh, and uploading
+ changes made to your files to the server. There is special support
+ for using the rsync.net cloud provider this way, or any shell account
+ on a typical unix server, such as a Linode VPS can be used.
+
+The following are known limitations of this release of the git-annex
+assistant:
+
+* On Mac OSX and BSD operating systems, the assistant uses kqueue to watch
+ files. Kqueue has to open every directory it watches, so too many
+ directories will run it out of the max number of open files (typically
+ 1024), and fail. See [[bugs/Issue_on_OSX_with_some_system_limits]]
+ for a workaround.
+* In order to ensure that all multiple repositories are kept in sync,
+ each computer with a repository must be running the git-annex assistant.
+* The assistant does not yet always manage to keep repositories in sync
+ when some are hidden from others behind firewalls.
+* If a file is checked into git as a normal file and gets modified
+ (or merged, etc), it will be converted into an annexed file. So you
+ should not mix use of the assistant with normal git files in the same
+ repository yet.
+* If you `git annex unlock` a file, it will immediately be re-locked.
+ See [[bugs/watcher_commits_unlocked_files]].
diff --git a/doc/assistant/release_notes/comment_1_bd8f376c9d0c1d5ed07fb013907a60ee._comment b/doc/assistant/release_notes/comment_1_bd8f376c9d0c1d5ed07fb013907a60ee._comment
new file mode 100644
index 000000000..04cdf4039
--- /dev/null
+++ b/doc/assistant/release_notes/comment_1_bd8f376c9d0c1d5ed07fb013907a60ee._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://wiggy.net/"
+ nickname="Wichert"
+ subject="OSX 10.8's gatekeeper does not like git-annex"
+ date="2012-11-13T14:47:52Z"
+ content="""
+Trying to run this release on OSX results in an error message from Gatekeeper:
+
+> \"git-annex\" can't be opened because it is from an unidentified developer.
+>
+> Your security preferences allow installation of only apps from the Mac App Store and identified developers.
+
+It would be nice if the binary could be signed to make Gatekeeper happy. Until then a note in the installation instructions might be useful.
+"""]]
diff --git a/doc/assistant/release_notes/comment_2_75e0774ad042717fbd059a8a9ec2db1e._comment b/doc/assistant/release_notes/comment_2_75e0774ad042717fbd059a8a9ec2db1e._comment
new file mode 100644
index 000000000..9033b1af6
--- /dev/null
+++ b/doc/assistant/release_notes/comment_2_75e0774ad042717fbd059a8a9ec2db1e._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://wiggy.net/"
+ nickname="Wichert"
+ subject="git-annex not runnable on OSX 10.8"
+ date="2012-11-13T14:49:35Z"
+ content="""
+After telling Gatekeeper that I really want to run git-annex it still fails:
+
+[fog;~]-131> open Applications/git-annex.app
+LSOpenURLsWithRole() failed with error -10810 for the file /Users/wichert/Applications/git-annex.app.
+
+"""]]
diff --git a/doc/assistant/release_notes/comment_3_b3bfd8e547e20c51f7c32c6c9424e936._comment b/doc/assistant/release_notes/comment_3_b3bfd8e547e20c51f7c32c6c9424e936._comment
new file mode 100644
index 000000000..73377c714
--- /dev/null
+++ b/doc/assistant/release_notes/comment_3_b3bfd8e547e20c51f7c32c6c9424e936._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.252.11.120"
+ subject="comment 3"
+ date="2012-11-13T17:11:51Z"
+ content="""
+This has been previously reported: [[bugs/OSX_git-annex.app_error:__LSOpenURLsWithRole()]]
+
+No clue what that error is supposed to mean.
+"""]]
diff --git a/doc/assistant/release_notes/comment_4_c6caa2b521b456bb4ce594d64919cffe._comment b/doc/assistant/release_notes/comment_4_c6caa2b521b456bb4ce594d64919cffe._comment
new file mode 100644
index 000000000..1ebaf504f
--- /dev/null
+++ b/doc/assistant/release_notes/comment_4_c6caa2b521b456bb4ce594d64919cffe._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 4"
+ date="2012-11-16T13:02:40Z"
+ content="""
+sadly i only have a 10.7 machine to create the builds, so I have no experience with 10.8. I haven't had a 10.6 machine in a while to create the builds. Anyone else want to work together in setting up another 10.6 or 10.8 builder for others?
+"""]]
diff --git a/doc/assistant/remote_sharing_walkthrough.mdwn b/doc/assistant/remote_sharing_walkthrough.mdwn
new file mode 100644
index 000000000..ec8f39d53
--- /dev/null
+++ b/doc/assistant/remote_sharing_walkthrough.mdwn
@@ -0,0 +1,12 @@
+So you have two computers that are not in the same place, and you want them
+to share the same synchronised folder, communicating directly with each other.
+
+[[!inline feeds=no template=bare pages=videos/git-annex_assistant_remote_sharing]]
+
+You can add even more computers using the same method shown here.
+
+----
+
+If you have a laptop that is sometimes near another computer, you can
+speed up file transfers when it is by also connecting it using the
+[[local_pairing_walkthrough]].
diff --git a/doc/assistant/remote_sharing_walkthrough/comment_1_e0187b0a926904b363065ab0f850f0b2._comment b/doc/assistant/remote_sharing_walkthrough/comment_1_e0187b0a926904b363065ab0f850f0b2._comment
new file mode 100644
index 000000000..cac5295a7
--- /dev/null
+++ b/doc/assistant/remote_sharing_walkthrough/comment_1_e0187b0a926904b363065ab0f850f0b2._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmG4rlD9k1ezNkYZ8jDbITrycUmHV-P8Qs"
+ nickname="Jeroen"
+ subject="Synced vs. unsynced"
+ date="2013-07-29T18:07:45Z"
+ content="""
+I've noticed that it is also possible to add an existing annex folder on a remote server without using syncing. Are there any dangers in doing this?
+
+Could you explain what syncing does and when it is needed? Thanks.
+"""]]
diff --git a/doc/assistant/remote_sharing_walkthrough/comment_2_dabcbc9aaf0bdb82716f5a5d55807a21._comment b/doc/assistant/remote_sharing_walkthrough/comment_2_dabcbc9aaf0bdb82716f5a5d55807a21._comment
new file mode 100644
index 000000000..b99d9e22b
--- /dev/null
+++ b/doc/assistant/remote_sharing_walkthrough/comment_2_dabcbc9aaf0bdb82716f5a5d55807a21._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.21"
+ subject="comment 2"
+ date="2013-07-30T18:08:38Z"
+ content="""
+I'm afraid I don't quite understand the question.
+"""]]
diff --git a/doc/assistant/remote_sharing_walkthrough/comment_4_978fab3cd165b4ca245e32fc48cf0970._comment b/doc/assistant/remote_sharing_walkthrough/comment_4_978fab3cd165b4ca245e32fc48cf0970._comment
new file mode 100644
index 000000000..ab0b19160
--- /dev/null
+++ b/doc/assistant/remote_sharing_walkthrough/comment_4_978fab3cd165b4ca245e32fc48cf0970._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.246"
+ subject="comment 4"
+ date="2013-11-12T18:18:16Z"
+ content="""
+You can easily use a removable drive as a transfer repository to sync two computers that have no network connection. Just use the webapp to add the drive on one computer. The drive will be set up as a transfer repository by default. The webapp will automatically start copying all your files to it. Then you can disconnect the drive, bring it to the other computer, and repeat the process. Everything from the first computer will then sync over from the drive to the second computer. And repeat moving the drive back and forth to keep things in sync.
+"""]]
diff --git a/doc/assistant/remote_sharing_walkthrough/comment_4_d7e879f7b098964040df2e27a18eda72._comment b/doc/assistant/remote_sharing_walkthrough/comment_4_d7e879f7b098964040df2e27a18eda72._comment
new file mode 100644
index 000000000..71f57e9b3
--- /dev/null
+++ b/doc/assistant/remote_sharing_walkthrough/comment_4_d7e879f7b098964040df2e27a18eda72._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmkXtBdMgE1d9nCz2iBc4f85xh4izZ_auU"
+ nickname="Ulrich"
+ subject="Using a portable drive as another transfer device?"
+ date="2013-11-12T16:52:12Z"
+ content="""
+I try to understand how to setup git-annex for the following use case:
+
+Two computers, that are paired via remote sharing, using some cloud repository for transfer, and a local NAS for backups.
+
+These two computers are sometimes in the same network, sometimes in different networks, and sometimes even without network at all. From what I read, it should be possible to bypass the cloud when these two machines are on the same network, which sounds great.
+
+Would it be possible to use a portable drive as \"another link\" between these two computers that can be used to sync them even if there is no network between them?
+
+And as you write, if the pairing has been set up manually, then everything is fine - so could it be that it is really easy and only necessary to setup the git-annex on the local drive as an additional remote on both (or only one?) machine?
+
+thanks for any insight!
+"""]]
diff --git a/doc/assistant/remote_sharing_walkthrough/comment_5_00852736d47c05772b15c5ff54ae7da7._comment b/doc/assistant/remote_sharing_walkthrough/comment_5_00852736d47c05772b15c5ff54ae7da7._comment
new file mode 100644
index 000000000..a66fcd098
--- /dev/null
+++ b/doc/assistant/remote_sharing_walkthrough/comment_5_00852736d47c05772b15c5ff54ae7da7._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmkXtBdMgE1d9nCz2iBc4f85xh4izZ_auU"
+ nickname="Ulrich"
+ subject="Using a portable drive as another transfer device? – cool."
+ date="2013-11-14T19:05:56Z"
+ content="""
+Thanks - I was hoping that it is that easy. I'll try that as soon as I have a working version of the latest git-annex (trying to build with brew for Mac OS X 10.9, but without success so far).
+"""]]
diff --git a/doc/assistant/repairrepository.png b/doc/assistant/repairrepository.png
new file mode 100644
index 000000000..d49ea9d95
--- /dev/null
+++ b/doc/assistant/repairrepository.png
Binary files differ
diff --git a/doc/assistant/repogroups.png b/doc/assistant/repogroups.png
new file mode 100644
index 000000000..06300ce66
--- /dev/null
+++ b/doc/assistant/repogroups.png
Binary files differ
diff --git a/doc/assistant/repoinfo.png b/doc/assistant/repoinfo.png
new file mode 100644
index 000000000..d43ffc9f9
--- /dev/null
+++ b/doc/assistant/repoinfo.png
Binary files differ
diff --git a/doc/assistant/repositories.png b/doc/assistant/repositories.png
new file mode 100644
index 000000000..2853683dc
--- /dev/null
+++ b/doc/assistant/repositories.png
Binary files differ
diff --git a/doc/assistant/rsync.net.encryption.png b/doc/assistant/rsync.net.encryption.png
new file mode 100644
index 000000000..ec751d10d
--- /dev/null
+++ b/doc/assistant/rsync.net.encryption.png
Binary files differ
diff --git a/doc/assistant/rsync.net.png b/doc/assistant/rsync.net.png
new file mode 100644
index 000000000..0e0940703
--- /dev/null
+++ b/doc/assistant/rsync.net.png
Binary files differ
diff --git a/doc/assistant/running.png b/doc/assistant/running.png
new file mode 100644
index 000000000..8c3b0eaf2
--- /dev/null
+++ b/doc/assistant/running.png
Binary files differ
diff --git a/doc/assistant/share_with_a_friend_walkthrough.mdwn b/doc/assistant/share_with_a_friend_walkthrough.mdwn
new file mode 100644
index 000000000..38544d111
--- /dev/null
+++ b/doc/assistant/share_with_a_friend_walkthrough.mdwn
@@ -0,0 +1,58 @@
+Want to share all the files in your repository with a friend?
+
+Let's suppose you use Google Mail, and so does your friend, and you
+sometimes also chat in Google Talk. The git-annex assistant will
+use your Google account to share with your friend. (This actually
+works with any Jabber account you use, not just Google Talk.)
+
+Start by opening up your git annex dashboard.
+
+[[!img local_pairing_walkthrough/addrepository.png alt="Add another repository button"]]
+
+`*click*`
+
+[[!img pairing.png alt="Share with a friend"]]
+
+`*click*`
+
+[[!img xmpp.png alt="Configuring Jabber account"]]
+
+Fill that out, and git-annex will be able to show you a list of your
+friends.
+
+[[!img buddylist.png alt="Buddy list"]]
+
+This list will refresh as friends log on and off, so you can
+leave it open in a tab until a friend is available to start pairing.
+
+(If your friend is not using git-annex yet, now's a great time to spread
+the word!)
+
+Once you click on "Start Pairing", your friend will see this pop up
+on their git annex dashboard.
+
+[[!img xmppalert.png alt="Pair request"]]
+
+Once your friend clicks on that, your repositories will be paired.
+
+### But, wait, there's one more step...
+
+Despite the repositories being paired now, you and your friend can't yet
+quite share files. You'll start to see your friend's files show up in your
+git-annex folder, but you won't be able to open them yet.
+
+What you need to do now is set up a repository out there in the cloud,
+that both you and your friend can access. This will be used to transfer
+files between the two of you.
+
+At the end of the pairing process, a number of cloud providers are
+suggested, and the git-annex assistant makes it easy to configure one of
+them. Once you or your friend sets it up, it'll show up in the other
+one's list of repositories:
+
+[[!img repolist.png alt="Repository list"]]
+
+The final step is to share the login information for the cloud repository
+with your friend, so they can enable it too.
+
+With that complete, you'll be able to open your friend's files!
diff --git a/doc/assistant/share_with_a_friend_walkthrough/buddylist.png b/doc/assistant/share_with_a_friend_walkthrough/buddylist.png
new file mode 100644
index 000000000..ce3d61a96
--- /dev/null
+++ b/doc/assistant/share_with_a_friend_walkthrough/buddylist.png
Binary files differ
diff --git a/doc/assistant/share_with_a_friend_walkthrough/pairing.png b/doc/assistant/share_with_a_friend_walkthrough/pairing.png
new file mode 100644
index 000000000..533f4aef5
--- /dev/null
+++ b/doc/assistant/share_with_a_friend_walkthrough/pairing.png
Binary files differ
diff --git a/doc/assistant/share_with_a_friend_walkthrough/repolist.png b/doc/assistant/share_with_a_friend_walkthrough/repolist.png
new file mode 100644
index 000000000..409da4aa4
--- /dev/null
+++ b/doc/assistant/share_with_a_friend_walkthrough/repolist.png
Binary files differ
diff --git a/doc/assistant/share_with_a_friend_walkthrough/xmppalert.png b/doc/assistant/share_with_a_friend_walkthrough/xmppalert.png
new file mode 100644
index 000000000..5e2d56289
--- /dev/null
+++ b/doc/assistant/share_with_a_friend_walkthrough/xmppalert.png
Binary files differ
diff --git a/doc/assistant/thanks.mdwn b/doc/assistant/thanks.mdwn
new file mode 100644
index 000000000..04159fdfc
--- /dev/null
+++ b/doc/assistant/thanks.mdwn
@@ -0,0 +1,243 @@
+The development of the git-annex assistant was made possible by the
+generous donations of many people. I want to say "Thank You!" to each of
+you individually, but until I meet all 951 of you, this page will have to
+do. You have my most sincere thanks. --[[Joey]]
+
+(If I got your name wrong, or you don't want it publically posted here,
+email <joey@kitenet.net>.)
+
+## Major Backers
+
+These people are just inspiring in their enthusiasm and generosity to this
+project.
+
+* Jason Scott
+* strager
+
+## Beta Testers
+
+Whole weeks of my time were made possible thanks to each of these
+people, and their testing is invaluable to the development of
+the git-annex assistant.
+
+* Jimmy Tang
+* David Pollak
+* Pater
+* Francois Marier
+* Paul Sherwood
+* Fred Epma
+* Robert Ristroph
+* Josh Triplett
+* David Haslem
+* AJ Ashton
+* Svenne Krap
+* Drew Hess
+* Peter van Westen
+
+## Prioritizers
+
+These forward-thinking people contributed generously just to help
+set my priorities in which parts of the git-annex assistant were most
+important to develop.
+
+Paul C. Bryan, Paul Tötterman, Don Marti, Dean Thompson, Djoume, David Johnston
+Asokan Pichai, Anders Østhus, Dominik Wagenknecht, Charlie Fox, Yazz D. Atlas,
+fenchel, Erik Penninga, Richard Hartmann, Graham, Stan Yamane, Ben Skelton,
+Ian McEwen, asc, Paul Tagliamonte, Sherif Abouseda, Igor Támara, Anne Wind,
+Mesar Hameed, Brandur K. Holm Petersen, Takahiro Inoue, Kai Hendry,
+Stephen Youndt, Lee Roberson, Ben Strawbridge, Andrew Greenberg, Alfred Adams
+Andrew, Aaron De Vries, Monti Knazze, Jorge Canseco, Hamish, Mark Eichin,
+Sherif Abouseda, Ben Strawbridge, chee rabbits, Pedro Côrte-Real
+
+And special thanks to Kevin McKenzie, who also gave me a login to a Mac OSX
+machine, which has proven invaluable, Jimmy Tang who has helped
+with Mac OSX autobuilding and packaging, and Yury V. Zaytsev who
+provides the Windows autobuilder.
+
+## Other Backers
+
+Most of the success of the Kickstarter is thanks to these folks. Some of
+them spent significant amounts of money in the guise of getting some
+swag. For others, being listed here, and being crucial to making the
+git-annex assistant happen was reward enough. Large or small, these
+contributions are, literally, my bread and butter this year.
+
+Amitai Schlair, mvime, Romain Lenglet, James Petts, Jouni Uuksulainen,
+Wichert Akkerman, Robert Bellus, Kasper Souren, rob, Michiel Buddingh',
+Kevin, Rob Avina, Alon Levy, Vikash, Michael Alan Dorman, Harley Pig,
+Andreas Olsson, Pietpiet, Christine Spang, Liz Young, Oleg Kosorukov,
+Allard Hoeve, Valentin Haenel, Joost Baaij, Nathan Yergler, Nathan Howell,
+Frédéric Schütz, Matti Eskelinen, Neil McGovern, Lane Lillquist, db48x,
+Stuart Prescott, Mark Matienzo, KarlTheGood, leonm, Drew Slininger,
+Andreas Fuchs, Conrad Parker, Johannes Engelke, Battlegarden, Justin Kelly,
+Robin Wagner, Thad Ward, crenquis, Trudy Goold, Mike Cochrane, Adam Venturella,
+Russell Foo, furankupan, Giorgio Occhioni, andy, mind, Mike Linksvayer,
+Stefan Strahl, Jelmer Vernooij, Markus Fix, David Hicks, Justin Azoff,
+Iain Nicol, Bob Ippolito, Thomas Lundstrøm, Jason Mandel, federico2,
+Edd Cochran, Jose Ortega, Emmett Agnew, Rudy Garcia, Kodi, Nick Rusnov,
+Michael Rubin, Tom de Grunt, Richard Murray, Peter, Suzanne Pierce, Jared
+Marcotte, folk, Eamon, Jeff Richards, Leo Sutedja, dann frazier, Mikkel
+kristiansen, Matt Thomas, Kilian Evang, Gergely Risko, Kristian Rumberg,
+Peter Kropf, Mark Hepburn, greymont, D. Joe Anderson, Jeremy Zunker, ctebo,
+Manuel Roumain, Jason Walsh, np, Shawn, Johan Tibell, Branden Tyree, Dinyar
+Rabady, Andrew Mason, damond armstead, Ethan Aubin, TomTom Tommie, Jimmy
+Kaplowitz, Steven Zakulec, mike smith, Jacob Kirkwood, Mark Hymers, Nathan
+Collins, Asbjørn Sloth Tønnesen, Misty De Meo, James Shubin,
+Jim Paris, Adam Sjøgren, miniBill, Taneli, Kumar Appaiah, Greg Grossmeier,
+Sten Turpin, Otavio Salvador, Teemu Hukkanen, Brian Stengaard, bob walker,
+bibeneus, andrelo, Yaroslav Halchenko, hesfalling, Tommy L, jlargentaye,
+Serafeim Zanikolas, Don Armstrong, Chris Cormack, shayne.oneill, Radu
+Raduta, Josh S, Robin Sheat, Henrik Mygind, kodx, Christian, Geoff
+Crompton, Brian May, Olivier Berger, Filippo Gadotti, Daniel Curto-Millet,
+Eskild Hustvedt, Douglas Soares de Andrade, Tom L, Michael Nacos, Michaël
+P., William Roe, Joshua Honeycutt, Brian Kelly, Nathan Rasch, jorge, Martin
+Galese, alex cox, Avery Brooks, David Whittington, Dan Martinez, Forrest
+Sutton, Jouni K. Seppänen, Arnold Cano, Robert Beaty, Daniel, Kevin Savetz,
+Randy, Ernie Braganza, Aaron Haviland, Brian Brunswick, asmw, sean, Michael
+Williams, Alexander, Dougal Campbell, Robert Bacchas, Michael Lewis, Collin
+Price, Wes Frazier, Matt Wall, Brandon Barclay, Derek van Vliet, Martin
+DeMello, kitt hodsden, Stephen Kitt, Leif Bergman, Simon Lilburn, Michael
+Prokop, Christiaan Conover, Nick Coombe, Tim Dysinger, Brandon Robinson,
+Philip Newborough, keith, Mike Fullerton, Kyle, Phil Windley, Tyler Head,
+George V. Reilly, Matthew, Ali Gündüz, Vasyl Diakonov, Paolo Capriotti,
+allanfranta, Martin Haeberli, msingle, Vincent Sanders, Steven King, Dmitry
+Gribanov, Brandon High, Ben Hughes, Mike Dank, JohnE, Diggory Hardy,
+Michael Hanke, valhalla, Samuli Tuomola, Jeff Rau, Benjamin Lebsanft, John
+Drago, James, Aidan Cooper, rondie, Paul Kohler, Matthew Knights, Aaron
+Junod, Patrick R McDonald, Christopher Browne, Daniel Engel, John SJ
+Anderson, Peter Sarossy, Mike Prasad, Christoph Ender, Jan Dittberner,
+Zohar, Alexander Jelinek, stefan, Danny O'Brien, Matthew Thode, Nicole
+Aptekar, maurice gaston, Chris Adams, Mike Klemencic, Reedy, Subito, Tobias
+Gruetzmacher, Ole-Morten Duesund, André Koot, mp, gdop, Cole Scott, Blaker,
+Matt Sottile, W. Craig Trader, Louis-Philippe Dubrule, Brian Boucheron,
+Duncan Smith, Brenton Buchbach, Kyle Stevenson, Eliot Lash, Egon Elbre,
+Praveen, williamji, Thomas Schreiber, Neil Ford, Ryan Pratt, Joshua Brand,
+Peter Cox, Markus Engstrom, John Sutherland, Dean Bailey, Ed Summers,
+Hillel Arnold, David Fiander, Kurt Yoder, Trevor Muñoz, keri, Ivan
+Sergeyenko, Shad Bolling, Tal Kelrich, Steve Presley, gerald ocker, Essex
+Taylor, Josh Thomson, Trevor Bramble, Lance Higgins, Frank Motta, Dirk
+Kraft, soundray, Joe Haskins, nmjk, Apurva Desai, Colin Dean, docwhat,
+Joseph Costello, Jst, flamsmark, Alex Lang, Bill Traynor, Anthony David,
+Marc-André Lureau, AlNapp, Giovanni Moretti, John Lawrence, João Paulo
+Pizani Flor, Jim Ray, Gregory Thrush, Alistair McGann, Andrew Wied,
+Koutarou Furukawa, Xiscu Ignacio, Aaron Sachs, Matt, Quirijn, Chet
+Williams, Chris Gray, Bruce Segal, Tom Conder, Louis Tovar, Alex Duryee,
+booltox, d8uv, Decklin Foster, Rafael Cervantes, Micah R Ledbetter, Kevin
+Sjöberg, Johan Strombom, Zachary Cohen, Jason Lewis, Yves Bilgeri, Ville
+Aine, Mark Hurley, Marco Bonetti, Maximilian Haack, Hynek Schlawack,
+Michael Leinartas, Andreas Liebschner, Duotrig, Nat Fairbanks, David
+Deutsch, Colin Hayhurst, calca, Kyle Goodrick, Marc Bobillier, Robert
+Snook, James Kim, Olivier Serres, Jon Redfern, Itai Tavor, Michael
+Fladischer, Rob, Jan Schmid, Thomas H., Anders Söderbäck, Abhishek
+Dasgupta, Jeff Goeke-Smith, Tommy Thorn, bonuswavepilot, Philipp Edelmann,
+Nick, Alejandro Navarro Fulleda, Yann Lallemant, andrew brennan,
+Dave Allen Barker Jr, Fabian, Lukas Anzinger, Carl Witty, Andy Taylor,
+Andre Klärner, Andrew Chilton, Adam Gibbins, Alexander Wauck, Shane O'Dea,
+Paul Waite, Iain McLaren, Maggie Ellen Robin Hess, Willard Korfhage,
+Nicolas, Eric Nikolaisen, Magnus Enger, Philipp Kern, Andrew Alderwick,
+Raphael Wimmer, Benjamin Schötz, Ana Guerrero, Pete, Pieter van der Eems,
+Aaron Suggs, Fred Benenson, Cedric Howe, Lance Ivy, Tieg Zaharia, Kevin
+Cooney, Jon Williams, Anton Kudris, Roman Komarov, Brad Hilton, Rick Dakan,
+Adam Whitcomb, Paul Casagrande, Evgueni Baldin, Robert Sanders, Kagan
+Kayal, Dean Gardiner, micah altman, Cameron Banga, Ross Mcnairn, Oscar
+Vilaplana, Robin Graham, Dan Gervais, Jon Åslund, Ragan Webber, Noble Hays,
+stephen brown, Sean True, Maciek Swiech, faser, eikenberry, Kai Laborenz,
+Sergey Fedoseev, Chris Fournier, Svend Sorensen, Greg K, wojtek, Johan
+Ribenfors, Anton, Benjamin, Oleg Tsarev, PsychoHazard, John Cochrane,
+Kasper Lauritzen, Patrick Naish, Rob, Keith Nasman, zenmaster, David Royer,
+Max Woolf, Dan Gabber, martin rhoads, Martin Schmidinger, Paul
+Scott-Wilson, Tom Gromak, Andy Webster, Dale Webb, Jim Watson, Stephen
+Hansen, Mircea, Dan Goodenberger, Matthias Fink, Andy Gott, Daniel, Jai
+Nelson, Shrayas Rajagopal, Vladimir Rutsky, Alexander, Thorben Westerhuys,
+hiruki, Tao Neuendorffer Flaherty, Elline, Marco Hegenberg, robert, Balda,
+Brennen Bearnes, Richard Parkins, David Gwilliam, Mark Johnson, Jeff Eaton,
+Reddawn90, Heather Pusey, Chris Heinz, Colin, Phatsaphong Thadabusapa,
+valunthar, Michael Martinez, redlukas, Yury V. Zaytsev, Blake, Tobias
+"betabrain" A., Leon, sopyer, Steve Burnett, bessarabov, sarble, krsch.com,
+Jack Self, Jeff Welch, Sam Pettiford, Jimmy Stridh, Diego Barberá, David
+Steele, Oscar Ciudad, John Braman, Jacob, Nick Jenkins, Ben Sullivan, Brian
+Cleary, James Brosnahan, Darryn Ten, Alex Brem, Jonathan Hitchcock, Jan
+Schmidle, Wolfrzx99, Steve Pomeroy, Matthew Sitton, Finkregh, Derek Reeve,
+GDR!, Cory Chapman, Marc Olivier Chouinard, Andreas Ryland, Justin, Andreas
+Persenius, Games That Teach, Walter Somerville, Bill Haecker, Brandon
+Phenix, Justin Shultz, Colin Scroggins, Tim Goddard, Ben Margolin, Michael
+Martinez, David Hobbs, Andre Le, Jason Roberts, Bob Lopez, Gert Van Gool,
+Robert Carnel, Anders Lundqvist, Aniruddha Sathaye, Marco Gillies, Basti
+von Bejga, Esko Arajärvi, Dominik Deobald, Pavel Yudaev, Fionn Behrens,
+Davide Favargiotti, Perttu Luukko, Silvan Jegen, Marcelo Bittencourt,
+Leonard Peris, smercer, Alexandre Dupas, Solomon Matthews, Peter Hogg,
+Richard E. Varian, Ian Oswald, James W. Sarvey, Ed Grether, Frederic
+Savard, Sebastian Nerz, Hans-Chr. Jehg, Matija Nalis, Josh DiMauro, Jason
+Harris, Adam Byrtek, Tellef, Magnus, Bart Schuurmans, Giel van Schijndel,
+Ryan, kiodos, Richard 'maddog' Collins, PawZubr, Jason Gassel, Alex
+Boisvert, Richard Thompson, maddi bolton, csights, Aaron Bryson, Jason Chu,
+Maxime Côté, Kineteka Systems, Joe Cabezas, Mike Czepiel, Rami Nasra,
+Christian Simonsen, Wouter Beugelsdijk, Adam Gibson, Gal Buki, James
+Marble, Alan Chambers, Bernd Wiehle, Simon Korzun, Daniel Glassey, Eero af
+Heurlin, Mikael, Timo Engelhardt, Wesley Faulkner, Jay Wo, Mike Belle,
+David Fowlkes Jr., Karl-Heinz Strass, Ed Mullins, Sam Flint,
+Hendrica, Mark Emer Anderson, Joshua Cole, Jan Gondol, Henrik Lindhe,
+Albert Delgado, Patrick, Alexa Avellar, Chris, sebsn1349, Maxim Kachur,
+Andrew Marshall, Navjot Narula, Alwin Mathew, Christian Mangelsdorf, Avi
+Shevin, Kevin S., Guillermo Sanchez Estrada, Alex Krieger, Luca Meier, Will
+Jessop, Nick Ruest, Lani Aung, Ulf Benjaminsson, Rudi Engelbrecht, Miles
+Matton, Cpt_Threepwood, Adam Kuyper, reacocard, David Kilsheimer, Peter
+Olson, Bill Fischofer, Prashant Shah, Simon Bonnick, Alexander Grudtsov,
+Antoine Boegli, Richard Warren, Sebastian Rust, AlmostHuman, Timmy
+Crawford, PC, Marek Belski, pontus, Douglas S Butts, Eric Wallmander, Joe
+Pelar, VIjay, Trahloc, Vernon Vantucci, Matthew baya, Viktor Štujber,
+Stephen Akiki, Daniil Zamoldinov, Atley, Chris Thomson, Jacob Briggs, Falko
+Richter, Andy Schmitz, Sergi Sagas, Peder Refsnes, Jonatan, Ben, Bill
+Niblock, Agustin Acuna, Jeff Curl, Tim Humphrey, bib, James Zarbock,
+Lachlan Devantier, Michal Berg, Jeff Lucas, Sid Irish, Franklyn, Jared
+Dickson, Olli Jarva, Adam Gibson, Lukas Loesche, Jukka Määttä, Alexander
+Lin, Dao Tran, Kirk, briankb, Ryan Villasenor, Daniel Wong, barista, Tomas
+Jungwirth, Jesper Hansen, Nivin Singh, Alessandro Tieghi, Billy Roessler,
+Peter Fetterer, Pallav Laskar, jcherney, Tyler Wang, Steve, Gigahost, Beat
+Wolf, Hannibal Skorepa, aktiveradio, Mark Nunnikhoven, Bret Comnes, Alan
+Ruttenberg, Anthony DiSanti, Adam Warkiewicz, Brian Bowman, Jonathan, Mark
+Filley, Tobias Mohr, Christian St. Cyr, j. faceless user, Karl Miller,
+Thomas Taimre, Vikram, Jason Mountcastle, Jason, Paul Elliott, Alexander,
+Stephen Farmer, rayslava, Peter Leurs, Sky Kruse, JP Reeves, John J Schatz,
+Martin Sandmair, Will Thompson, John Hergenroeder, Thomas, Christophe
+Ponsart, Wolfdog, Eagertolearn, LukasM, Federico Hernandez, Vincent Bernat,
+Christian Schmidt, Cameron Colby Thomson, Josh Duff, James Brown, Theron
+Trowbridge, Falke, Don Meares, tauu, Greg Cornford, Max Fenton, Kenneth
+Reitz, Bruce Bensetler, Mark Booth, Herb Mann, Sindre Sorhus, Chris
+Knadler, Daniel Digerås, Derek, Sin Valentine, Ben Gamari, david
+lampenscherf, fardles, Richard Burdeniuk, Tobias Kienzler, Dawid Humbla,
+Bruno Barbaroxa, D Malt, krivar, James Valleroy, Peter, Tim Geddings,
+Matthias Holzinger, Hanen, Petr Vacek, Raymond, Griff Maloney, Andreas
+Helveg Rudolph, Nelson Blaha, Colonel Fubar, Skyjacker Captain Gavin
+Phoenix, shaun, Michael, Kari Salminen, Rodrigo Miranda, Alan Chan, Justin
+Eugene Evans, Isaac, Ben Staffin, Matthew Loar, Magos, Roderik, Eugenio
+Piasini, Nico B, Scott Walter, Lior Amsalem, Thongrop Rodsavas, Alberto de
+Paola, Shawn Poulen, John Swiderski, lluks, Waelen, Mark Slosarek, Jim
+Cristol, mikesol, Bilal Quadri, LuP, Allan Nicolson, Kevin Washington,
+Isaac Wedin, Paul Anguiano, ldacruz, Jason Manheim, Sawyer, Jason
+Woofenden, Joe Danziger, Declan Morahan, KaptainUfolog, Vladron, bart, Jeff
+McNeill, Christian Schlotter, Ben McQuillan, Anthony, Julian, Martin O,
+altruism, Eric Solheim, MarkS, ndrwc, Matthew, David Lehn, Matthew
+Cisneros, Mike Skoglund, Kristy Carey, fmotta, Tom Lowenthal, Branden
+Tyree, Aaron Whitehouse
+
+## Also thanks to
+
+* The Kickstarter team, who have unleashed much good on the world.
+* The Haskell developers, who toiled for 20 years in obscurity
+ before most of us noticed them, and on whose giant shoulders I now stand,
+ in awe of the view.
+* The Git developers, for obvious reasons.
+* All of git-annex's early adopters, who turned it from a personal
+ toy project into something much more, and showed me the interest was there.
+* Rsync.net, for providing me a free account so I can make sure git-annex
+ works well with it.
+* LeastAuthority.com, for providing me a free Tahoe-LAFS grid account,
+ so I can test git-annex with that, and back up the git-annex assistant
+ screencasts.
+* Anna and Mark, for the loan of the video camera; as well as the rest of
+ my family, for your support. Even when I couldn't explain what I was
+ working on.
+* The Hodges, for providing such a congenial place for me to live and work
+ on these first world problems, while you're off helping people in the
+ third world.
diff --git a/doc/assistant/thumbnail.png b/doc/assistant/thumbnail.png
new file mode 100644
index 000000000..346c22f02
--- /dev/null
+++ b/doc/assistant/thumbnail.png
Binary files differ
diff --git a/doc/assistant/upgradecomplete.png b/doc/assistant/upgradecomplete.png
new file mode 100644
index 000000000..3f8c7f3c2
--- /dev/null
+++ b/doc/assistant/upgradecomplete.png
Binary files differ
diff --git a/doc/assistant/xmpp.png b/doc/assistant/xmpp.png
new file mode 100644
index 000000000..c3cc53ebf
--- /dev/null
+++ b/doc/assistant/xmpp.png
Binary files differ
diff --git a/doc/assistant/xmppnudge.png b/doc/assistant/xmppnudge.png
new file mode 100644
index 000000000..b3a0658cb
--- /dev/null
+++ b/doc/assistant/xmppnudge.png
Binary files differ
diff --git a/doc/assistant/xmpppairingend.png b/doc/assistant/xmpppairingend.png
new file mode 100644
index 000000000..f0c9e765d
--- /dev/null
+++ b/doc/assistant/xmpppairingend.png
Binary files differ
diff --git a/doc/automatic_conflict_resolution.mdwn b/doc/automatic_conflict_resolution.mdwn
new file mode 100644
index 000000000..f20138b19
--- /dev/null
+++ b/doc/automatic_conflict_resolution.mdwn
@@ -0,0 +1,23 @@
+Running `git annex sync` or using the [[assistant]] involves merging
+changes from elsewhere into your repository's currently checked out branch.
+This could lead to a merge conflict, perhaps because the same file
+got changed in two different ways. A nice feature is that these
+merge conflicts are automatically resolved, rather than leaving
+git in the middle of a conflicted merge, which would prevent further
+syncing from happening.
+
+When a conflict occurs, there will be several messages printed about the merge
+conflict, and the file that has the merge conflict will be renamed, with
+".variant-XXX" tacked onto it. So if there are two versions of file foo,
+you might end up with "foo.variant-AAA" and "foo.variant-BBB". It's then
+up to you to decide what to do with these two files. Perhaps you can
+manually combine them back into a single file. Or perhaps you choose to
+rename them to better names and keep two versions, or delete one version
+you don't want.
+
+The "AAA" and "BBB" in the above example are essentially arbitrary
+(technically they are the MD5 checksum of the key). The automatic merge
+conflict resoltuion is designed so that if two or more repositories both get
+a merge conflict, and resolve it, the resolved repositories will not
+themselves conflict. This is why it doesn't use something nicer, like
+perhaps the name of the remote that the file came from.
diff --git a/doc/backends.mdwn b/doc/backends.mdwn
new file mode 100644
index 000000000..79bacd68e
--- /dev/null
+++ b/doc/backends.mdwn
@@ -0,0 +1,42 @@
+When a file is annexed, a key is generated from its content and/or metadata.
+The file checked into git symlinks to the key. This key can later be used
+to retrieve the file's content (its value).
+
+Multiple pluggable key-value backends are supported, and a single repository
+can use different ones for different files.
+
+* `SHA256E` -- The default backend for new files, combines a SHA256 hash of
+ the file's content with the file's extension. This allows
+ verifying that the file content is right, and can avoid duplicates of
+ files with the same content. Its need to generate checksums
+ can make it slower for large files.
+* `SHA256` -- Does not include the file extension in the key, which can
+ lead to better deduplication but can confuse some programs.
+* `WORM` ("Write Once, Read Many") This assumes that any file with
+ the same basename, size, and modification time has the same content.
+ This is the least expensive backend, recommended for really large
+ files or slow systems.
+* `SHA512`, `SHA512E` -- Best currently available hash, for the very paranoid.
+* `SHA1`, `SHA1E` -- Smaller hash than `SHA256` for those who want a checksum
+ but are not concerned about security.
+* `SHA384`, `SHA384E`, `SHA224`, `SHA224E` -- Hashes for people who like
+ unusual sizes.
+* `SKEIN512`, `SKEIN256` -- [Skein hash](http://en.wikipedia.org/wiki/Skein_hash),
+ a well-regarded SHA3 hash competition finalist.
+
+The `annex.backends` git-config setting can be used to list the backends
+git-annex should use. The first one listed will be used by default when
+new files are added.
+
+For finer control of what backend is used when adding different types of
+files, the `.gitattributes` file can be used. The `annex.backend`
+attribute can be set to the name of the backend to use for matching files.
+
+For example, to use the SHA256E backend for sound files, which tend to be
+smallish and might be modified or copied over time,
+while using the WORM backend for everything else, you could set
+in `.gitattributes`:
+
+ * annex.backend=WORM
+ *.mp3 annex.backend=SHA256E
+ *.ogg annex.backend=SHA256E
diff --git a/doc/backends/comment_1_375bb1fb5973e8fa67b763f2dd6e404b._comment b/doc/backends/comment_1_375bb1fb5973e8fa67b763f2dd6e404b._comment
new file mode 100644
index 000000000..dc178a6fe
--- /dev/null
+++ b/doc/backends/comment_1_375bb1fb5973e8fa67b763f2dd6e404b._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://nanotech.nanotechcorp.net/"
+ nickname="NanoTech"
+ subject="SHA performance"
+ date="2012-08-10T04:37:32Z"
+ content="""
+It turns out that (at least on x86-64 machines) `SHA512` [is faster than][1] `SHA256`. In some benchmarks I performed<sup>1</sup> `SHA256` was 1.8–2.2x slower than `SHA1` while `SHA512` was only 1.5–1.6x slower.
+
+`SHA224` and `SHA384` are effectively just truncated versions of `SHA256` and `SHA512` so their performance characteristics are identical.
+
+[1]: https://community.emc.com/community/edn/rsashare/blog/2010/11/01/sha-2-algorithms-when-sha-512-is-more-secure-and-faster
+<sup>1</sup> `time head -c 100000000 /dev/zero | shasum -a 512`
+"""]]
diff --git a/doc/backends/comment_2_1f2626eca9004b31a0b7fc1a0df8027b._comment b/doc/backends/comment_2_1f2626eca9004b31a0b7fc1a0df8027b._comment
new file mode 100644
index 000000000..030887303
--- /dev/null
+++ b/doc/backends/comment_2_1f2626eca9004b31a0b7fc1a0df8027b._comment
@@ -0,0 +1,24 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm7eqCMh_B7mxE0tnchbr0JoYu11FUAFRY"
+ nickname="Stéphane"
+ subject="Tracking remote copies not even stored locally / URL backend turned into a &quot;special remote&quot;."
+ date="2013-01-03T10:59:35Z"
+ content="""
+In case you came here looking for the URL backend.
+
+## The URL backend
+
+Several documents on the web refer to a special \"URL backend\", e.g. [Large file management with git-annex [LWN.net]](http://lwn.net/Articles/419241/). Historical content will never be updated yet it drives people to living places.
+
+## Why a URL backend ?
+
+It is interesting because you can:
+
+* let `git-annex` rest on the fact that some documents are available as extra copies available at any time (but from something that is not a git repository).
+* track these documents like your own with all git features, which opens up some truly marvelous combinations, which this margin is too narrow to contain (Pierre d.F. wouldn't disapprove ;-).
+
+## How/Where now ?
+
+`git-annex` used to have a URL backend. It seems that the design changed into a \"special remote\" feature, not limited to the web. You can now track files available through plain directories, rsync, webdav, some cloud storage, etc, even clay tablets. For details see [[special remotes]].
+
+"""]]
diff --git a/doc/backends/comment_3_fdcbf8727fdefb9942a54689234b9698._comment b/doc/backends/comment_3_fdcbf8727fdefb9942a54689234b9698._comment
new file mode 100644
index 000000000..6f8b1ad7a
--- /dev/null
+++ b/doc/backends/comment_3_fdcbf8727fdefb9942a54689234b9698._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmicVKRM8vJX4wPuAwlLEoS2cjmFXQkjkE"
+ nickname="Thomas"
+ subject="Please be more specific about what information goes into the key"
+ date="2013-07-31T11:55:09Z"
+ content="""
+It's a bit confusing to read that SHA256 does not include the file extension from which I can deduct that SHA256E does include it. What else does it include? I used to \"seed\" my git-annex with localy available data by \"git-annex add\"-ing it in a temporary folder without doing a commit and than to initiate a copy from the slow remote annex repo. My theory was that remote copy sees the pre-seeded files and does not need to copy them again.
+
+But does this theory hold true for different file names, extensions, modification date, full path? Maybe you could also link to the code that implements the different backends so that curious readers can check for themselves.
+
+Thank you!
+"""]]
diff --git a/doc/backends/comment_4_46591a3ba888fb686b1b319b80ca2c22._comment b/doc/backends/comment_4_46591a3ba888fb686b1b319b80ca2c22._comment
new file mode 100644
index 000000000..94f25e996
--- /dev/null
+++ b/doc/backends/comment_4_46591a3ba888fb686b1b319b80ca2c22._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmTho3mActvetF1iQdmui6gH1t6WE6c284"
+ nickname="Michael"
+ subject="SHA256e"
+ date="2013-10-30T02:00:45Z"
+ content="""
+I'd really like to have a SHA256e backend -- same as SHA256E but making sure that extensions of the files in .git/annex are converted to lower case. I normally try to convert filenames from cameras etc to lower case, but not all people that I share annex with do so consistently.
+In my use case, I need to be able to find duplicates among files and .jpg vs .JPG throws git annex dedup off. Otherwise E backends are superior to non-E for me. Thanks, Michael.
+"""]]
diff --git a/doc/backends/comment_5_2210c7ff2d5812fb3b778ac172291656._comment b/doc/backends/comment_5_2210c7ff2d5812fb3b778ac172291656._comment
new file mode 100644
index 000000000..2a205604c
--- /dev/null
+++ b/doc/backends/comment_5_2210c7ff2d5812fb3b778ac172291656._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmWBvsZvSsAL8P2ye3F0OBStjFCVnOImzM"
+ nickname="Jarno"
+ subject="Non-E backend drawbacks?"
+ date="2013-10-30T21:25:00Z"
+ content="""
+The page states \"[non-E backends] can confuse some programs\". I like the ideal simplicity and recoverability of pure checksum backends but \"confusion\" sounds a bit worrying. Any practical examples of these problems to help me choose?
+"""]]
diff --git a/doc/backends/comment_6_82f239b58680a2681bd8074c7ef9584d._comment b/doc/backends/comment_6_82f239b58680a2681bd8074c7ef9584d._comment
new file mode 100644
index 000000000..cbd4682ab
--- /dev/null
+++ b/doc/backends/comment_6_82f239b58680a2681bd8074c7ef9584d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 6"
+ date="2013-11-01T15:47:26Z"
+ content="""
+Some examples of problems with the raw SHA backends include, IIRC, calibre, and many programs on OSX. These programs look at the extension of the filename the symlink points at.
+"""]]
diff --git a/doc/bare_repositories.mdwn b/doc/bare_repositories.mdwn
new file mode 100644
index 000000000..975a638b8
--- /dev/null
+++ b/doc/bare_repositories.mdwn
@@ -0,0 +1,48 @@
+Due to popular demand, git-annex can now be used with bare repositories.
+
+So, for example, you can stash a file away in the origin:
+`git annex move mybigfile --to origin`
+
+Of course, for that to work, the bare repository has to be on a system with
+[[git-annex-shell]] installed. If "origin" is on GitWeb, you still can't
+use git-annex to store stuff there.
+
+It took a while, but bare repositories are now supported exactly as well
+as non-bare repositories. Except for these caveats:
+
+* `git annex fsck` works in a bare repository, but does not display
+ warnings about insufficient
+ [[copies]]. To get those warnings, just run it in one of the non-bare
+ checkouts.
+* `git annex unused` in a bare repository only knows about keys used in
+ branches that have been pushed to the bare repository. So use it with care..
+* Commands that need a work tree, like `git annex add` won't work in a bare
+ repository, of course.
+* However, you can (with recent versions of git-annex) run `git annex copy`,
+ `git annex get`, and `git annex move` in a bare repository. These behave
+ as if the `--all` option were used, and just operate on every single
+ version of every single file that is present in the git repository
+ history.
+
+***
+
+Here is a quick example of how to set this up, using `origin` as the remote name, and assuming `~/annex` contains an annex:
+
+On the server:
+
+ git init --bare bare-annex.git
+ cd bare-annex.git && git annex init origin
+
+Now configure the remote and do the initial push:
+
+ cd ~/annex
+ git remote add origin example.com:bare-annex.git
+ git push origin master git-annex
+
+Now `git annex info` should show the configured bare remote. If it does not, you may have to pull from the remote first (older versions of `git-annex`)
+
+If you wish to configure git such that you can push/pull without arguments, set the upstream branch:
+
+ git branch master --set-upstream origin/master
+
+
diff --git a/doc/bare_repositories/comment_1_148e1da70d37d311634a0309a4ff8dcd._comment b/doc/bare_repositories/comment_1_148e1da70d37d311634a0309a4ff8dcd._comment
new file mode 100644
index 000000000..c1ba9f2f4
--- /dev/null
+++ b/doc/bare_repositories/comment_1_148e1da70d37d311634a0309a4ff8dcd._comment
@@ -0,0 +1,22 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmraN_ldJplGunVGmnjjLN6jL9s9TrVMGE"
+ nickname="Ævar Arnfjörð"
+ subject="How to convert bare repositories to non-bare"
+ date="2012-11-11T20:14:44Z"
+ content="""
+I made a repository bare and later wanted to convert it, this would have worked with just plain git:
+
+ cd bare-repo.git
+ mkdir .git
+ mv .??* * .git/
+ git config --unset core.bare
+ git reset --hard
+
+But because git-annex uses different hashing directories under bare repositories all the files in the repo will point to files you don't have. Here's how you can fix that up assuming you're using a backend that assigns unique hashes based on file content (e.g. the SHA256 backend):
+
+ mv .git/annex/objects from-bare-repo
+ git annex add from-bare-repo
+ git rm -f from-bare-repo
+
+
+"""]]
diff --git a/doc/bugs.mdwn b/doc/bugs.mdwn
new file mode 100644
index 000000000..1fdb1f49b
--- /dev/null
+++ b/doc/bugs.mdwn
@@ -0,0 +1,18 @@
+This is git-annex's bug list.
+
+[[!sidebar content="""
+[[!inline feeds=no template=bare pages=sidebar]]
+
+Categories:
+
+* [[Bugs_affecting_the_assistant|design/assistant/todo]]
+* [[Bugs_needing_more_info|moreinfo]]
+* [[Closed_bugs|bugs/done]]
+"""
+]]
+
+[[!inline pages="./bugs/* and !./bugs/*/* and !./bugs/done and !link(done)
+and !./bugs/moreinfo and !link(moreinfo)
+and !*/Discussion" actions=yes postform=yes show=0 archive=yes]]
+
+[[!edittemplate template=templates/bugtemplate match="bugs/*" silent=yes]]
diff --git a/doc/bugs/127.0.0.1_references_on_remote_assistant_access.mdwn b/doc/bugs/127.0.0.1_references_on_remote_assistant_access.mdwn
new file mode 100644
index 000000000..bf62df8d5
--- /dev/null
+++ b/doc/bugs/127.0.0.1_references_on_remote_assistant_access.mdwn
@@ -0,0 +1,20 @@
+### Please describe the problem.
+When I use git-annex webapp with a remote IP of a headless computer, I am sometimes redirected to a 127.0.0.1 address (with a different port as well)
+
+### What steps will reproduce the problem?
+1. Install git-annex as usual.
+2. Open git-annex assistant from a headless machine and access the webapp with the --listen option. (e.g. git annex webapp --listen=xxx.yyy.zzz.www)
+3. Create your first local repository. Then create a second local repository.
+4. When assistant asks you if you want to merge these 2 repositories, try to select the second option (to keep them separated).
+5. You are redirected from your remote IP to 127.0.0.1 to a new port number.
+
+(I also encountered the same error at another menu or function, but I don't remember where. Sorry.)
+
+### What version of git-annex are you using? On what operating system?
+4.20130815
+Ubuntu 13.10 64-bit (kernel 3.11.0-13-generic x86_64)
+
+### Please provide any additional information below.
+Please ask me for any additional information that may be useful.
+
+> [[dup]] of [[Hangs_on_creating_repository_when_using_--listen]]; [[done]] --[[Joey]]
diff --git a/doc/bugs/3.20121112:_build_error_in_assistant.mdwn b/doc/bugs/3.20121112:_build_error_in_assistant.mdwn
new file mode 100644
index 000000000..de11dfbf7
--- /dev/null
+++ b/doc/bugs/3.20121112:_build_error_in_assistant.mdwn
@@ -0,0 +1,432 @@
+Git-annex stopped compiling with GHC 7.4.2 after updating Yesod and friends to the respective latest version. The complete build log is attached below. I hope this helps. Further build logs are available at <http://hydra.nixos.org/job/nixpkgs/trunk/gitAndTools.gitAnnex>, too.
+
+ building
+ make flags: PREFIX=/nix/store/9az61h33v1j6fkdmwdfy7gi0rhspsb9k-git-annex-3.20121112
+ building Build/SysConfig.hs
+ ghc -O2 -Wall -outputdir tmp -IUtility -DWITH_ASSISTANT -DWITH_S3 -DWITH_WEBAPP -DWITH_PAIRING -DWITH_XMPP -DWITH_DNS -DWITH_INOTIFY -DWITH_DBUS -threaded --make configure
+ [1 of 7] Compiling Utility.Exception ( Utility/Exception.hs, tmp/Utility/Exception.o )
+ [2 of 7] Compiling Utility.Misc ( Utility/Misc.hs, tmp/Utility/Misc.o )
+ [3 of 7] Compiling Utility.Process ( Utility/Process.hs, tmp/Utility/Process.o )
+ [4 of 7] Compiling Utility.SafeCommand ( Utility/SafeCommand.hs, tmp/Utility/SafeCommand.o )
+ [5 of 7] Compiling Build.TestConfig ( Build/TestConfig.hs, tmp/Build/TestConfig.o )
+ [6 of 7] Compiling Build.Configure ( Build/Configure.hs, tmp/Build/Configure.o )
+ [7 of 7] Compiling Main ( configure.hs, tmp/Main.o )
+ Linking configure ...
+ ./configure
+ checking version... 3.20121112
+ checking git... yes
+ checking git version... 1.8.0
+ checking cp -a... yes
+ checking cp -p... yes
+ checking cp --reflink=auto... yes
+ checking uuid generator... uuidgen
+ checking xargs -0... yes
+ checking rsync... yes
+ checking curl... yes
+ checking wget... no
+ checking bup... no
+ checking gpg... no
+ checking lsof... no
+ checking ssh connection caching... yes
+ checking sha1... sha1sum
+ checking sha256... sha256sum
+ checking sha512... sha512sum
+ checking sha224... sha224sum
+ checking sha384... sha384sum
+ building Utility/Touch.hs
+ hsc2hs Utility/Touch.hsc
+ building Utility/Mounts.hs
+ hsc2hs Utility/Mounts.hsc
+ building Utility/libdiskfree.o
+ cc -Wall -c -o Utility/libdiskfree.o Utility/libdiskfree.c
+ building Utility/libmounts.o
+ cc -Wall -c -o Utility/libmounts.o Utility/libmounts.c
+ building git-annex
+ install -d tmp
+ ghc -O2 -Wall -outputdir tmp -IUtility -DWITH_ASSISTANT -DWITH_S3 -DWITH_WEBAPP -DWITH_PAIRING -DWITH_XMPP -DWITH_DNS -DWITH_INOTIFY -DWITH_DBUS -threaded --make git-annex -o tmp/git-annex Utility/libdiskfree.o Utility/libmounts.o
+ [ 1 of 279] Compiling Utility.Dot ( Utility/Dot.hs, tmp/Utility/Dot.o )
+ [ 2 of 279] Compiling Utility.ThreadLock ( Utility/ThreadLock.hs, tmp/Utility/ThreadLock.o )
+ [ 3 of 279] Compiling Utility.Mounts ( Utility/Mounts.hs, tmp/Utility/Mounts.o )
+ [ 4 of 279] Compiling Utility.Yesod ( Utility/Yesod.hs, tmp/Utility/Yesod.o )
+ [ 5 of 279] Compiling Utility.Tense ( Utility/Tense.hs, tmp/Utility/Tense.o )
+ [ 6 of 279] Compiling Utility.Verifiable ( Utility/Verifiable.hs, tmp/Utility/Verifiable.o )
+ [ 7 of 279] Compiling Assistant.Types.TransferSlots ( Assistant/Types/TransferSlots.hs, tmp/Assistant/Types/TransferSlots.o )
+ [ 8 of 279] Compiling Types.StandardGroups ( Types/StandardGroups.hs, tmp/Types/StandardGroups.o )
+ [ 9 of 279] Compiling Utility.Percentage ( Utility/Percentage.hs, tmp/Utility/Percentage.o )
+ [ 10 of 279] Compiling Utility.Base64 ( Utility/Base64.hs, tmp/Utility/Base64.o )
+ [ 11 of 279] Compiling Utility.DataUnits ( Utility/DataUnits.hs, tmp/Utility/DataUnits.o )
+ [ 12 of 279] Compiling Utility.JSONStream ( Utility/JSONStream.hs, tmp/Utility/JSONStream.o )
+ [ 13 of 279] Compiling Messages.JSON ( Messages/JSON.hs, tmp/Messages/JSON.o )
+ [ 14 of 279] Compiling Build.SysConfig ( Build/SysConfig.hs, tmp/Build/SysConfig.o )
+ [ 15 of 279] Compiling Types.KeySource ( Types/KeySource.hs, tmp/Types/KeySource.o )
+ [ 16 of 279] Compiling Utility.State ( Utility/State.hs, tmp/Utility/State.o )
+ [ 17 of 279] Compiling Types.UUID ( Types/UUID.hs, tmp/Types/UUID.o )
+ [ 18 of 279] Compiling Types.Messages ( Types/Messages.hs, tmp/Types/Messages.o )
+ [ 19 of 279] Compiling Types.Group ( Types/Group.hs, tmp/Types/Group.o )
+ [ 20 of 279] Compiling Types.TrustLevel ( Types/TrustLevel.hs, tmp/Types/TrustLevel.o )
+ [ 21 of 279] Compiling Types.BranchState ( Types/BranchState.hs, tmp/Types/BranchState.o )
+ [ 22 of 279] Compiling Utility.PartialPrelude ( Utility/PartialPrelude.hs, tmp/Utility/PartialPrelude.o )
+ [ 23 of 279] Compiling Utility.HumanTime ( Utility/HumanTime.hs, tmp/Utility/HumanTime.o )
+ [ 24 of 279] Compiling Utility.Format ( Utility/Format.hs, tmp/Utility/Format.o )
+ [ 25 of 279] Compiling Utility.FileSystemEncoding ( Utility/FileSystemEncoding.hs, tmp/Utility/FileSystemEncoding.o )
+ [ 26 of 279] Compiling Utility.Touch ( Utility/Touch.hs, tmp/Utility/Touch.o )
+ [ 27 of 279] Compiling Utility.Applicative ( Utility/Applicative.hs, tmp/Utility/Applicative.o )
+ [ 28 of 279] Compiling Utility.Monad ( Utility/Monad.hs, tmp/Utility/Monad.o )
+ [ 29 of 279] Compiling Utility.Exception ( Utility/Exception.hs, tmp/Utility/Exception.o )
+ [ 30 of 279] Compiling Utility.DBus ( Utility/DBus.hs, tmp/Utility/DBus.o )
+ [ 31 of 279] Compiling Utility.Misc ( Utility/Misc.hs, tmp/Utility/Misc.o )
+ [ 32 of 279] Compiling Utility.Process ( Utility/Process.hs, tmp/Utility/Process.o )
+ [ 33 of 279] Compiling Utility.SafeCommand ( Utility/SafeCommand.hs, tmp/Utility/SafeCommand.o )
+ [ 34 of 279] Compiling Utility.Network ( Utility/Network.hs, tmp/Utility/Network.o )
+ [ 35 of 279] Compiling Utility.SRV ( Utility/SRV.hs, tmp/Utility/SRV.o )
+
+ Utility/SRV.hs:88:1: Warning: Defined but not used: `lookupSRVHost'
+
+ Utility/SRV.hs:94:1: Warning: Defined but not used: `parseSrvHost'
+ [ 36 of 279] Compiling Git.Types ( Git/Types.hs, tmp/Git/Types.o )
+ [ 37 of 279] Compiling Utility.UserInfo ( Utility/UserInfo.hs, tmp/Utility/UserInfo.o )
+ [ 38 of 279] Compiling Utility.Path ( Utility/Path.hs, tmp/Utility/Path.o )
+ [ 39 of 279] Compiling Utility.TempFile ( Utility/TempFile.hs, tmp/Utility/TempFile.o )
+ [ 40 of 279] Compiling Utility.Directory ( Utility/Directory.hs, tmp/Utility/Directory.o )
+ [ 41 of 279] Compiling Utility.FreeDesktop ( Utility/FreeDesktop.hs, tmp/Utility/FreeDesktop.o )
+ [ 42 of 279] Compiling Assistant.Install.AutoStart ( Assistant/Install/AutoStart.hs, tmp/Assistant/Install/AutoStart.o )
+ [ 43 of 279] Compiling Common ( Common.hs, tmp/Common.o )
+ [ 44 of 279] Compiling Utility.FileMode ( Utility/FileMode.hs, tmp/Utility/FileMode.o )
+ [ 45 of 279] Compiling Git ( Git.hs, tmp/Git.o )
+ [ 46 of 279] Compiling Git.FilePath ( Git/FilePath.hs, tmp/Git/FilePath.o )
+ [ 47 of 279] Compiling Utility.Matcher ( Utility/Matcher.hs, tmp/Utility/Matcher.o )
+ [ 48 of 279] Compiling Utility.Gpg ( Utility/Gpg.hs, tmp/Utility/Gpg.o )
+ [ 49 of 279] Compiling Types.Crypto ( Types/Crypto.hs, tmp/Types/Crypto.o )
+ [ 50 of 279] Compiling Types.Key ( Types/Key.hs, tmp/Types/Key.o )
+ [ 51 of 279] Compiling Types.Backend ( Types/Backend.hs, tmp/Types/Backend.o )
+ [ 52 of 279] Compiling Types.Remote ( Types/Remote.hs, tmp/Types/Remote.o )
+ [ 53 of 279] Compiling Git.Sha ( Git/Sha.hs, tmp/Git/Sha.o )
+ [ 54 of 279] Compiling Utility.CoProcess ( Utility/CoProcess.hs, tmp/Utility/CoProcess.o )
+ [ 55 of 279] Compiling Git.Command ( Git/Command.hs, tmp/Git/Command.o )
+ [ 56 of 279] Compiling Git.Ref ( Git/Ref.hs, tmp/Git/Ref.o )
+ [ 57 of 279] Compiling Git.Branch ( Git/Branch.hs, tmp/Git/Branch.o )
+ [ 58 of 279] Compiling Git.UpdateIndex ( Git/UpdateIndex.hs, tmp/Git/UpdateIndex.o )
+ [ 59 of 279] Compiling Git.Queue ( Git/Queue.hs, tmp/Git/Queue.o )
+ [ 60 of 279] Compiling Git.HashObject ( Git/HashObject.hs, tmp/Git/HashObject.o )
+ [ 61 of 279] Compiling Git.CatFile ( Git/CatFile.hs, tmp/Git/CatFile.o )
+ [ 62 of 279] Compiling Git.UnionMerge ( Git/UnionMerge.hs, tmp/Git/UnionMerge.o )
+ [ 63 of 279] Compiling Git.Url ( Git/Url.hs, tmp/Git/Url.o )
+ [ 64 of 279] Compiling Git.Construct ( Git/Construct.hs, tmp/Git/Construct.o )
+ [ 65 of 279] Compiling Git.Config ( Git/Config.hs, tmp/Git/Config.o )
+ [ 66 of 279] Compiling Git.SharedRepository ( Git/SharedRepository.hs, tmp/Git/SharedRepository.o )
+ [ 67 of 279] Compiling Git.Version ( Git/Version.hs, tmp/Git/Version.o )
+ [ 68 of 279] Compiling Git.CheckAttr ( Git/CheckAttr.hs, tmp/Git/CheckAttr.o )
+ [ 69 of 279] Compiling Annex ( Annex.hs, tmp/Annex.o )
+ [ 70 of 279] Compiling Types.Option ( Types/Option.hs, tmp/Types/Option.o )
+ [ 71 of 279] Compiling Types ( Types.hs, tmp/Types.o )
+ [ 72 of 279] Compiling Messages ( Messages.hs, tmp/Messages.o )
+ [ 73 of 279] Compiling Types.Command ( Types/Command.hs, tmp/Types/Command.o )
+ [ 74 of 279] Compiling Locations ( Locations.hs, tmp/Locations.o )
+ [ 75 of 279] Compiling Common.Annex ( Common/Annex.hs, tmp/Common/Annex.o )
+ [ 76 of 279] Compiling Fields ( Fields.hs, tmp/Fields.o )
+ [ 77 of 279] Compiling Annex.BranchState ( Annex/BranchState.hs, tmp/Annex/BranchState.o )
+ [ 78 of 279] Compiling Annex.CatFile ( Annex/CatFile.hs, tmp/Annex/CatFile.o )
+ [ 79 of 279] Compiling Annex.Perms ( Annex/Perms.hs, tmp/Annex/Perms.o )
+ [ 80 of 279] Compiling Crypto ( Crypto.hs, tmp/Crypto.o )
+ [ 81 of 279] Compiling Annex.Exception ( Annex/Exception.hs, tmp/Annex/Exception.o )
+ [ 82 of 279] Compiling Annex.Journal ( Annex/Journal.hs, tmp/Annex/Journal.o )
+ [ 83 of 279] Compiling Annex.Branch ( Annex/Branch.hs, tmp/Annex/Branch.o )
+ [ 84 of 279] Compiling Usage ( Usage.hs, tmp/Usage.o )
+ [ 85 of 279] Compiling Annex.CheckAttr ( Annex/CheckAttr.hs, tmp/Annex/CheckAttr.o )
+ [ 86 of 279] Compiling Remote.Helper.Special ( Remote/Helper/Special.hs, tmp/Remote/Helper/Special.o )
+ [ 87 of 279] Compiling Logs.Presence ( Logs/Presence.hs, tmp/Logs/Presence.o )
+ [ 88 of 279] Compiling Logs.Location ( Logs/Location.hs, tmp/Logs/Location.o )
+ [ 89 of 279] Compiling Logs.Web ( Logs/Web.hs, tmp/Logs/Web.o )
+ [ 90 of 279] Compiling Annex.LockPool ( Annex/LockPool.hs, tmp/Annex/LockPool.o )
+ [ 91 of 279] Compiling Logs.Transfer ( Logs/Transfer.hs, tmp/Logs/Transfer.o )
+ [ 92 of 279] Compiling Backend.SHA ( Backend/SHA.hs, tmp/Backend/SHA.o )
+ [ 93 of 279] Compiling Backend.WORM ( Backend/WORM.hs, tmp/Backend/WORM.o )
+ [ 94 of 279] Compiling Backend.URL ( Backend/URL.hs, tmp/Backend/URL.o )
+ [ 95 of 279] Compiling Assistant.Types.ScanRemotes ( Assistant/Types/ScanRemotes.hs, tmp/Assistant/Types/ScanRemotes.o )
+ [ 96 of 279] Compiling Assistant.Types.ThreadedMonad ( Assistant/Types/ThreadedMonad.hs, tmp/Assistant/Types/ThreadedMonad.o )
+ [ 97 of 279] Compiling Assistant.Types.TransferQueue ( Assistant/Types/TransferQueue.hs, tmp/Assistant/Types/TransferQueue.o )
+ [ 98 of 279] Compiling Assistant.Types.Pushes ( Assistant/Types/Pushes.hs, tmp/Assistant/Types/Pushes.o )
+ [ 99 of 279] Compiling Assistant.Types.BranchChange ( Assistant/Types/BranchChange.hs, tmp/Assistant/Types/BranchChange.o )
+ [100 of 279] Compiling Logs.UUIDBased ( Logs/UUIDBased.hs, tmp/Logs/UUIDBased.o )
+ [101 of 279] Compiling Logs.Remote ( Logs/Remote.hs, tmp/Logs/Remote.o )
+ [102 of 279] Compiling Logs.Group ( Logs/Group.hs, tmp/Logs/Group.o )
+ [103 of 279] Compiling Utility.DiskFree ( Utility/DiskFree.hs, tmp/Utility/DiskFree.o )
+ [104 of 279] Compiling Utility.Url ( Utility/Url.hs, tmp/Utility/Url.o )
+ [105 of 279] Compiling Utility.CopyFile ( Utility/CopyFile.hs, tmp/Utility/CopyFile.o )
+ [106 of 279] Compiling Utility.Rsync ( Utility/Rsync.hs, tmp/Utility/Rsync.o )
+ [107 of 279] Compiling Git.LsFiles ( Git/LsFiles.hs, tmp/Git/LsFiles.o )
+ [108 of 279] Compiling Git.AutoCorrect ( Git/AutoCorrect.hs, tmp/Git/AutoCorrect.o )
+ [109 of 279] Compiling Git.CurrentRepo ( Git/CurrentRepo.hs, tmp/Git/CurrentRepo.o )
+ [110 of 279] Compiling Locations.UserConfig ( Locations/UserConfig.hs, tmp/Locations/UserConfig.o )
+ [111 of 279] Compiling Utility.ThreadScheduler ( Utility/ThreadScheduler.hs, tmp/Utility/ThreadScheduler.o )
+ [112 of 279] Compiling Git.Merge ( Git/Merge.hs, tmp/Git/Merge.o )
+ [113 of 279] Compiling Utility.Parallel ( Utility/Parallel.hs, tmp/Utility/Parallel.o )
+ [114 of 279] Compiling Git.Remote ( Git/Remote.hs, tmp/Git/Remote.o )
+ [115 of 279] Compiling Assistant.Ssh ( Assistant/Ssh.hs, tmp/Assistant/Ssh.o )
+ [116 of 279] Compiling Assistant.Pairing ( Assistant/Pairing.hs, tmp/Assistant/Pairing.o )
+ [117 of 279] Compiling Assistant.Types.NetMessager ( Assistant/Types/NetMessager.hs, tmp/Assistant/Types/NetMessager.o )
+ [118 of 279] Compiling Utility.NotificationBroadcaster ( Utility/NotificationBroadcaster.hs, tmp/Utility/NotificationBroadcaster.o )
+ [119 of 279] Compiling Assistant.Types.Buddies ( Assistant/Types/Buddies.hs, tmp/Assistant/Types/Buddies.o )
+ [120 of 279] Compiling Utility.TSet ( Utility/TSet.hs, tmp/Utility/TSet.o )
+ [121 of 279] Compiling Assistant.Types.Commits ( Assistant/Types/Commits.hs, tmp/Assistant/Types/Commits.o )
+ [122 of 279] Compiling Assistant.Types.Changes ( Assistant/Types/Changes.hs, tmp/Assistant/Types/Changes.o )
+ [123 of 279] Compiling Utility.WebApp ( Utility/WebApp.hs, tmp/Utility/WebApp.o )
+ [124 of 279] Compiling Utility.Daemon ( Utility/Daemon.hs, tmp/Utility/Daemon.o )
+ [125 of 279] Compiling Utility.LogFile ( Utility/LogFile.hs, tmp/Utility/LogFile.o )
+ [126 of 279] Compiling Git.Filename ( Git/Filename.hs, tmp/Git/Filename.o )
+ [127 of 279] Compiling Git.LsTree ( Git/LsTree.hs, tmp/Git/LsTree.o )
+ [128 of 279] Compiling Utility.Types.DirWatcher ( Utility/Types/DirWatcher.hs, tmp/Utility/Types/DirWatcher.o )
+ [129 of 279] Compiling Utility.INotify ( Utility/INotify.hs, tmp/Utility/INotify.o )
+ [130 of 279] Compiling Utility.DirWatcher ( Utility/DirWatcher.hs, tmp/Utility/DirWatcher.o )
+ [131 of 279] Compiling Utility.Lsof ( Utility/Lsof.hs, tmp/Utility/Lsof.o )
+ [132 of 279] Compiling Config ( Config.hs, tmp/Config.o )
+ [133 of 279] Compiling Annex.UUID ( Annex/UUID.hs, tmp/Annex/UUID.o )
+ [134 of 279] Compiling Logs.UUID ( Logs/UUID.hs, tmp/Logs/UUID.o )
+ [135 of 279] Compiling Backend ( Backend.hs, tmp/Backend.o )
+ [136 of 279] Compiling Remote.Helper.Hooks ( Remote/Helper/Hooks.hs, tmp/Remote/Helper/Hooks.o )
+ [137 of 279] Compiling Remote.Helper.Encryptable ( Remote/Helper/Encryptable.hs, tmp/Remote/Helper/Encryptable.o )
+ [138 of 279] Compiling Annex.Queue ( Annex/Queue.hs, tmp/Annex/Queue.o )
+ [139 of 279] Compiling Annex.Content ( Annex/Content.hs, tmp/Annex/Content.o )
+ [140 of 279] Compiling Remote.S3 ( Remote/S3.hs, tmp/Remote/S3.o )
+ [141 of 279] Compiling Remote.Directory ( Remote/Directory.hs, tmp/Remote/Directory.o )
+ [142 of 279] Compiling Remote.Rsync ( Remote/Rsync.hs, tmp/Remote/Rsync.o )
+ [143 of 279] Compiling Remote.Web ( Remote/Web.hs, tmp/Remote/Web.o )
+ [144 of 279] Compiling Remote.Hook ( Remote/Hook.hs, tmp/Remote/Hook.o )
+ [145 of 279] Compiling Upgrade.V2 ( Upgrade/V2.hs, tmp/Upgrade/V2.o )
+ [146 of 279] Compiling Annex.Ssh ( Annex/Ssh.hs, tmp/Annex/Ssh.o )
+ [147 of 279] Compiling Remote.Helper.Ssh ( Remote/Helper/Ssh.hs, tmp/Remote/Helper/Ssh.o )
+ [148 of 279] Compiling Remote.Bup ( Remote/Bup.hs, tmp/Remote/Bup.o )
+ [149 of 279] Compiling Annex.Version ( Annex/Version.hs, tmp/Annex/Version.o )
+ [150 of 279] Compiling Init ( Init.hs, tmp/Init.o )
+ [151 of 279] Compiling Checks ( Checks.hs, tmp/Checks.o )
+ [152 of 279] Compiling Remote.Git ( Remote/Git.hs, tmp/Remote/Git.o )
+ [153 of 279] Compiling Remote.List ( Remote/List.hs, tmp/Remote/List.o )
+ [154 of 279] Compiling Logs.Trust ( Logs/Trust.hs, tmp/Logs/Trust.o )
+ [155 of 279] Compiling Remote ( Remote.hs, tmp/Remote.o )
+ [156 of 279] Compiling Assistant.Alert ( Assistant/Alert.hs, tmp/Assistant/Alert.o )
+ Loading package ghc-prim ... linking ... done.
+ Loading package integer-gmp ... linking ... done.
+ Loading package base ... linking ... done.
+ Loading object (static) Utility/libdiskfree.o ... done
+ Loading object (static) Utility/libmounts.o ... done
+ final link ... done
+ Loading package pretty-1.1.1.0 ... linking ... done.
+ Loading package filepath-1.3.0.0 ... linking ... done.
+ Loading package old-locale-1.0.0.4 ... linking ... done.
+ Loading package old-time-1.1.0.0 ... linking ... done.
+ Loading package bytestring-0.9.2.1 ... linking ... done.
+ Loading package unix-2.5.1.0 ... linking ... done.
+ Loading package directory-1.1.0.2 ... linking ... done.
+ Loading package process-1.1.0.1 ... linking ... done.
+ Loading package array-0.4.0.0 ... linking ... done.
+ Loading package deepseq-1.3.0.0 ... linking ... done.
+ Loading package time-1.4 ... linking ... done.
+ Loading package containers-0.4.2.1 ... linking ... done.
+ Loading package text-0.11.2.0 ... linking ... done.
+ Loading package blaze-builder-0.3.1.0 ... linking ... done.
+ Loading package blaze-markup-0.5.1.1 ... linking ... done.
+ Loading package blaze-html-0.5.1.0 ... linking ... done.
+ Loading package hashable-1.1.2.5 ... linking ... done.
+ Loading package case-insensitive-0.4.0.3 ... linking ... done.
+ Loading package primitive-0.5.0.1 ... linking ... done.
+ Loading package vector-0.10.0.1 ... linking ... done.
+ Loading package random-1.0.1.1 ... linking ... done.
+ Loading package dlist-0.5 ... linking ... done.
+ Loading package data-default-0.5.0 ... linking ... done.
+ Loading package transformers-0.3.0.0 ... linking ... done.
+ Loading package mtl-2.1.1 ... linking ... done.
+ Loading package parsec-3.1.2 ... linking ... done.
+ Loading package network-2.3.0.13 ... linking ... done.
+ Loading package failure-0.2.0.1 ... linking ... done.
+ Loading package template-haskell ... linking ... done.
+ Loading package shakespeare-1.0.2 ... linking ... done.
+ Loading package hamlet-1.1.1.1 ... linking ... done.
+ Loading package http-types-0.7.3.0.1 ... linking ... done.
+ Loading package base-unicode-symbols-0.2.2.4 ... linking ... done.
+ Loading package transformers-base-0.4.1 ... linking ... done.
+ Loading package monad-control-0.3.1.4 ... linking ... done.
+ Loading package lifted-base-0.2 ... linking ... done.
+ Loading package resourcet-0.4.3 ... linking ... done.
+ Loading package semigroups-0.8.4.1 ... linking ... done.
+ Loading package void-0.5.8 ... linking ... done.
+ Loading package conduit-0.5.4.1 ... linking ... done.
+ Loading package unordered-containers-0.2.2.1 ... linking ... done.
+ Loading package vault-0.2.0.1 ... linking ... done.
+ Loading package wai-1.3.0.1 ... linking ... done.
+ Loading package date-cache-0.3.0 ... linking ... done.
+ Loading package unix-time-0.1.2 ... linking ... done.
+ Loading package fast-logger-0.3.1 ... linking ... done.
+ Loading package attoparsec-0.10.2.0 ... linking ... done.
+ Loading package cookie-0.4.0.1 ... linking ... done.
+ Loading package shakespeare-css-1.0.2 ... linking ... done.
+ Loading package syb-0.3.6.1 ... linking ... done.
+ Loading package aeson-0.6.0.2 ... linking ... done.
+ Loading package shakespeare-js-1.1.0 ... linking ... done.
+ Loading package ansi-terminal-0.5.5 ... linking ... done.
+ Loading package blaze-builder-conduit-0.5.0.2 ... linking ... done.
+ Loading package stringsearch-0.3.6.4 ... linking ... done.
+ Loading package byteorder-1.0.3 ... linking ... done.
+ Loading package wai-logger-0.3.0 ... linking ... done.
+ Loading package zlib-0.5.3.3 ... linking ... done.
+ Loading package zlib-bindings-0.1.1.1 ... linking ... done.
+ Loading package zlib-conduit-0.5.0.2 ... linking ... done.
+ Loading package wai-extra-1.3.0.4 ... linking ... done.
+ Loading package monad-logger-0.2.1 ... linking ... done.
+ Loading package cereal-0.3.5.2 ... linking ... done.
+ Loading package base64-bytestring-1.0.0.0 ... linking ... done.
+ Loading package cipher-aes-0.1.2 ... linking ... done.
+ Loading package entropy-0.2.1 ... linking ... done.
+ Loading package largeword-1.0.3 ... linking ... done.
+ Loading package tagged-0.4.4 ... linking ... done.
+ Loading package crypto-api-0.10.2 ... linking ... done.
+ Loading package cpu-0.1.1 ... linking ... done.
+ Loading package crypto-pubkey-types-0.1.1 ... linking ... done.
+ Loading package cryptocipher-0.3.5 ... linking ... done.
+ Loading package cprng-aes-0.2.4 ... linking ... done.
+ Loading package skein-0.1.0.9 ... linking ... done.
+ Loading package clientsession-0.8.0.1 ... linking ... done.
+ Loading package path-pieces-0.1.2 ... linking ... done.
+ Loading package shakespeare-i18n-1.0.0.2 ... linking ... done.
+ Loading package yesod-routes-1.1.1.1 ... linking ... done.
+ Loading package yesod-core-1.1.5 ... linking ... done.
+ [157 of 279] Compiling Assistant.Types.DaemonStatus ( Assistant/Types/DaemonStatus.hs, tmp/Assistant/Types/DaemonStatus.o )
+ [158 of 279] Compiling Assistant.Monad ( Assistant/Monad.hs, tmp/Assistant/Monad.o )
+ [159 of 279] Compiling Assistant.Types.NamedThread ( Assistant/Types/NamedThread.hs, tmp/Assistant/Types/NamedThread.o )
+ [160 of 279] Compiling Assistant.Common ( Assistant/Common.hs, tmp/Assistant/Common.o )
+ [161 of 279] Compiling Assistant.XMPP ( Assistant/XMPP.hs, tmp/Assistant/XMPP.o )
+ [162 of 279] Compiling Assistant.XMPP.Buddies ( Assistant/XMPP/Buddies.hs, tmp/Assistant/XMPP/Buddies.o )
+ [163 of 279] Compiling Assistant.NetMessager ( Assistant/NetMessager.hs, tmp/Assistant/NetMessager.o )
+
+ Assistant/NetMessager.hs:12:1:
+ Warning: The import of `Types.Remote' is redundant
+ except perhaps to import instances from `Types.Remote'
+ To import instances alone, use: import Types.Remote()
+
+ Assistant/NetMessager.hs:13:1:
+ Warning: The import of `Git' is redundant
+ except perhaps to import instances from `Git'
+ To import instances alone, use: import Git()
+
+ Assistant/NetMessager.hs:20:1:
+ Warning: The import of `Data.Text' is redundant
+ except perhaps to import instances from `Data.Text'
+ To import instances alone, use: import Data.Text()
+ [164 of 279] Compiling Assistant.Pushes ( Assistant/Pushes.hs, tmp/Assistant/Pushes.o )
+ [165 of 279] Compiling Assistant.ScanRemotes ( Assistant/ScanRemotes.hs, tmp/Assistant/ScanRemotes.o )
+ [166 of 279] Compiling Assistant.Install ( Assistant/Install.hs, tmp/Assistant/Install.o )
+ [167 of 279] Compiling Assistant.XMPP.Client ( Assistant/XMPP/Client.hs, tmp/Assistant/XMPP/Client.o )
+ [168 of 279] Compiling Assistant.Commits ( Assistant/Commits.hs, tmp/Assistant/Commits.o )
+ [169 of 279] Compiling Assistant.BranchChange ( Assistant/BranchChange.hs, tmp/Assistant/BranchChange.o )
+ [170 of 279] Compiling Assistant.Changes ( Assistant/Changes.hs, tmp/Assistant/Changes.o )
+ [171 of 279] Compiling Assistant.WebApp.Types ( Assistant/WebApp/Types.hs, tmp/Assistant/WebApp/Types.o )
+ Loading package unix-compat-0.4.0.0 ... linking ... done.
+ Loading package file-embed-0.0.4.6 ... linking ... done.
+ Loading package system-filepath-0.4.7 ... linking ... done.
+ Loading package system-fileio-0.3.10 ... linking ... done.
+ Loading package cryptohash-0.7.8 ... linking ... done.
+ Loading package crypto-conduit-0.4.0.1 ... linking ... done.
+ Loading package http-date-0.0.2 ... linking ... done.
+ Loading package mime-types-0.1.0.0 ... linking ... done.
+ Loading package wai-app-static-1.3.0.4 ... linking ... done.
+ Loading package yesod-static-1.1.1.1 ... linking ... done.
+ [172 of 279] Compiling Assistant.WebApp ( Assistant/WebApp.hs, tmp/Assistant/WebApp.o )
+ Loading package network-conduit-0.6.1.1 ... linking ... done.
+ Loading package safe-0.3.3 ... linking ... done.
+ Loading package simple-sendfile-0.2.8 ... linking ... done.
+ Loading package warp-1.3.4.4 ... linking ... done.
+ Loading package yaml-0.8.1 ... linking ... done.
+ Loading package yesod-default-1.1.2 ... linking ... done.
+ [173 of 279] Compiling Assistant.WebApp.OtherRepos ( Assistant/WebApp/OtherRepos.hs, tmp/Assistant/WebApp/OtherRepos.o )
+ [174 of 279] Compiling Limit ( Limit.hs, tmp/Limit.o )
+ [175 of 279] Compiling Option ( Option.hs, tmp/Option.o )
+ [176 of 279] Compiling Seek ( Seek.hs, tmp/Seek.o )
+ [177 of 279] Compiling Command ( Command.hs, tmp/Command.o )
+ [178 of 279] Compiling CmdLine ( CmdLine.hs, tmp/CmdLine.o )
+ [179 of 279] Compiling Command.ConfigList ( Command/ConfigList.hs, tmp/Command/ConfigList.o )
+ [180 of 279] Compiling Command.InAnnex ( Command/InAnnex.hs, tmp/Command/InAnnex.o )
+ [181 of 279] Compiling Command.DropKey ( Command/DropKey.hs, tmp/Command/DropKey.o )
+ [182 of 279] Compiling Command.SendKey ( Command/SendKey.hs, tmp/Command/SendKey.o )
+ [183 of 279] Compiling Command.RecvKey ( Command/RecvKey.hs, tmp/Command/RecvKey.o )
+ [184 of 279] Compiling Command.TransferInfo ( Command/TransferInfo.hs, tmp/Command/TransferInfo.o )
+ [185 of 279] Compiling Command.Commit ( Command/Commit.hs, tmp/Command/Commit.o )
+ [186 of 279] Compiling Command.Add ( Command/Add.hs, tmp/Command/Add.o )
+ [187 of 279] Compiling Command.Unannex ( Command/Unannex.hs, tmp/Command/Unannex.o )
+ [188 of 279] Compiling Command.FromKey ( Command/FromKey.hs, tmp/Command/FromKey.o )
+ [189 of 279] Compiling Command.ReKey ( Command/ReKey.hs, tmp/Command/ReKey.o )
+ [190 of 279] Compiling Command.Fix ( Command/Fix.hs, tmp/Command/Fix.o )
+ [191 of 279] Compiling Command.Describe ( Command/Describe.hs, tmp/Command/Describe.o )
+ [192 of 279] Compiling Command.InitRemote ( Command/InitRemote.hs, tmp/Command/InitRemote.o )
+ [193 of 279] Compiling Command.Unlock ( Command/Unlock.hs, tmp/Command/Unlock.o )
+ [194 of 279] Compiling Command.Lock ( Command/Lock.hs, tmp/Command/Lock.o )
+ [195 of 279] Compiling Command.PreCommit ( Command/PreCommit.hs, tmp/Command/PreCommit.o )
+ [196 of 279] Compiling Command.Log ( Command/Log.hs, tmp/Command/Log.o )
+ [197 of 279] Compiling Command.Merge ( Command/Merge.hs, tmp/Command/Merge.o )
+ [198 of 279] Compiling Command.Group ( Command/Group.hs, tmp/Command/Group.o )
+ [199 of 279] Compiling Command.Ungroup ( Command/Ungroup.hs, tmp/Command/Ungroup.o )
+ [200 of 279] Compiling Command.Import ( Command/Import.hs, tmp/Command/Import.o )
+ [201 of 279] Compiling Logs.Unused ( Logs/Unused.hs, tmp/Logs/Unused.o )
+ [202 of 279] Compiling Command.AddUnused ( Command/AddUnused.hs, tmp/Command/AddUnused.o )
+ [203 of 279] Compiling Command.Find ( Command/Find.hs, tmp/Command/Find.o )
+ [204 of 279] Compiling Logs.PreferredContent ( Logs/PreferredContent.hs, tmp/Logs/PreferredContent.o )
+ [205 of 279] Compiling Annex.Wanted ( Annex/Wanted.hs, tmp/Annex/Wanted.o )
+ [206 of 279] Compiling Command.Whereis ( Command/Whereis.hs, tmp/Command/Whereis.o )
+ [207 of 279] Compiling Command.Trust ( Command/Trust.hs, tmp/Command/Trust.o )
+ [208 of 279] Compiling Command.Untrust ( Command/Untrust.hs, tmp/Command/Untrust.o )
+ [209 of 279] Compiling Command.Semitrust ( Command/Semitrust.hs, tmp/Command/Semitrust.o )
+ [210 of 279] Compiling Command.Dead ( Command/Dead.hs, tmp/Command/Dead.o )
+ [211 of 279] Compiling Command.Vicfg ( Command/Vicfg.hs, tmp/Command/Vicfg.o )
+ [212 of 279] Compiling Command.Map ( Command/Map.hs, tmp/Command/Map.o )
+ [213 of 279] Compiling Command.Init ( Command/Init.hs, tmp/Command/Init.o )
+ [214 of 279] Compiling Command.Uninit ( Command/Uninit.hs, tmp/Command/Uninit.o )
+ [215 of 279] Compiling Command.Version ( Command/Version.hs, tmp/Command/Version.o )
+ [216 of 279] Compiling Upgrade.V1 ( Upgrade/V1.hs, tmp/Upgrade/V1.o )
+ [217 of 279] Compiling Upgrade.V0 ( Upgrade/V0.hs, tmp/Upgrade/V0.o )
+ [218 of 279] Compiling Upgrade ( Upgrade.hs, tmp/Upgrade.o )
+ [219 of 279] Compiling Command.Upgrade ( Command/Upgrade.hs, tmp/Command/Upgrade.o )
+ [220 of 279] Compiling Command.Drop ( Command/Drop.hs, tmp/Command/Drop.o )
+ [221 of 279] Compiling Command.Move ( Command/Move.hs, tmp/Command/Move.o )
+ [222 of 279] Compiling Command.Copy ( Command/Copy.hs, tmp/Command/Copy.o )
+ [223 of 279] Compiling Command.Get ( Command/Get.hs, tmp/Command/Get.o )
+ [224 of 279] Compiling Command.TransferKey ( Command/TransferKey.hs, tmp/Command/TransferKey.o )
+ [225 of 279] Compiling Command.DropUnused ( Command/DropUnused.hs, tmp/Command/DropUnused.o )
+ [226 of 279] Compiling Command.Fsck ( Command/Fsck.hs, tmp/Command/Fsck.o )
+ [227 of 279] Compiling Command.Reinject ( Command/Reinject.hs, tmp/Command/Reinject.o )
+ [228 of 279] Compiling Command.Migrate ( Command/Migrate.hs, tmp/Command/Migrate.o )
+ [229 of 279] Compiling Command.Unused ( Command/Unused.hs, tmp/Command/Unused.o )
+ [230 of 279] Compiling Command.Status ( Command/Status.hs, tmp/Command/Status.o )
+ [231 of 279] Compiling Command.Sync ( Command/Sync.hs, tmp/Command/Sync.o )
+ [232 of 279] Compiling Command.Help ( Command/Help.hs, tmp/Command/Help.o )
+ [233 of 279] Compiling Command.AddUrl ( Command/AddUrl.hs, tmp/Command/AddUrl.o )
+ [234 of 279] Compiling Assistant.DaemonStatus ( Assistant/DaemonStatus.hs, tmp/Assistant/DaemonStatus.o )
+ [235 of 279] Compiling Assistant.Sync ( Assistant/Sync.hs, tmp/Assistant/Sync.o )
+ [236 of 279] Compiling Assistant.MakeRemote ( Assistant/MakeRemote.hs, tmp/Assistant/MakeRemote.o )
+ [237 of 279] Compiling Assistant.XMPP.Git ( Assistant/XMPP/Git.hs, tmp/Assistant/XMPP/Git.o )
+ [238 of 279] Compiling Command.XMPPGit ( Command/XMPPGit.hs, tmp/Command/XMPPGit.o )
+ [239 of 279] Compiling Assistant.Threads.NetWatcher ( Assistant/Threads/NetWatcher.hs, tmp/Assistant/Threads/NetWatcher.o )
+ [240 of 279] Compiling Assistant.NamedThread ( Assistant/NamedThread.hs, tmp/Assistant/NamedThread.o )
+ [241 of 279] Compiling Assistant.WebApp.Notifications ( Assistant/WebApp/Notifications.hs, tmp/Assistant/WebApp/Notifications.o )
+
+ Assistant/WebApp/Notifications.hs:39:11:
+ No instances for (Text.Julius.ToJavascript String,
+ Text.Julius.ToJavascript Text)
+ arising from a use of `Text.Julius.toJavascript'
+ Possible fix:
+ add instance declarations for
+ (Text.Julius.ToJavascript String, Text.Julius.ToJavascript Text)
+ In the first argument of `Text.Julius.Javascript', namely
+ `Text.Julius.toJavascript delay'
+ In the expression:
+ Text.Julius.Javascript (Text.Julius.toJavascript delay)
+ In the first argument of `Data.Monoid.mconcat', namely
+ `[Text.Julius.Javascript
+ ((Data.Text.Lazy.Builder.fromText . Text.Shakespeare.pack')
+ "function longpoll_"),
+ Text.Julius.Javascript (Text.Julius.toJavascript ident),
+ Text.Julius.Javascript
+ ((Data.Text.Lazy.Builder.fromText . Text.Shakespeare.pack')
+ "() {\
+ \\tlongpoll(longpoll_"),
+ Text.Julius.Javascript (Text.Julius.toJavascript ident), ....]'
+ make: *** [git-annex] Error 1
+
+> Reproduced this and confirmed it's fixed in git. --[[Joey]] [[done]]
diff --git a/doc/bugs/3.20121112:_build_error_in_assistant/comment_1_b42f40ffd83321ab5cc0ef24ced15e98._comment b/doc/bugs/3.20121112:_build_error_in_assistant/comment_1_b42f40ffd83321ab5cc0ef24ced15e98._comment
new file mode 100644
index 000000000..9690885f0
--- /dev/null
+++ b/doc/bugs/3.20121112:_build_error_in_assistant/comment_1_b42f40ffd83321ab5cc0ef24ced15e98._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.252.11.120"
+ subject="comment 1"
+ date="2012-11-17T20:21:12Z"
+ content="""
+This looks rather like a bug in Yesod. I've made a change in git (b0a76592c313b4c8f51918d6469c40d1fd16a2b1) that *may* avoid the problem.
+"""]]
diff --git a/doc/bugs/3.20121112:_build_error_in_assistant/comment_2_b1d2aa10ea84c5c370b3e76507fc8761._comment b/doc/bugs/3.20121112:_build_error_in_assistant/comment_2_b1d2aa10ea84c5c370b3e76507fc8761._comment
new file mode 100644
index 000000000..0d4f3666c
--- /dev/null
+++ b/doc/bugs/3.20121112:_build_error_in_assistant/comment_2_b1d2aa10ea84c5c370b3e76507fc8761._comment
@@ -0,0 +1,476 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkHZw2Vx0VPtb9XM8vum7nEnh6gHGSCQvM"
+ nickname="Andrew"
+ subject="comment 2"
+ date="2012-11-24T18:48:23Z"
+ content="""
+Not quite. Though this might just be an artifact of me disabling WITH_WEBDAV on account of that not compiling on OS X (can't find module Network.Protocol.HTTP.DAV).
+OS: OS X 10.8.0
+
+ % git branch -v
+ * master d1ba407 Added a comment: git annex fix
+ % grep \"FEATURES?=\" Makefile
+ FEATURES?=$(GIT_ANNEX_LOCAL_FEATURES) -DWITH_ASSISTANT -DWITH_S3 -DWITH_WEBAPP -DWITH_PAIRING -DWITH_XMPP -DWITH_DNS
+ $ make
+ ghc -O2 -Wall -outputdir tmp -IUtility -DWITH_ASSISTANT -DWITH_S3 -DWITH_WEBAPP -DWITH_PAIRING -DWITH_XMPP -DWITH_DNS -DWITH_KQUEUE -threaded --make configure
+ [1 of 7] Compiling Utility.Exception ( Utility/Exception.hs, tmp/Utility/Exception.o )
+ [2 of 7] Compiling Utility.Misc ( Utility/Misc.hs, tmp/Utility/Misc.o )
+ [3 of 7] Compiling Utility.Process ( Utility/Process.hs, tmp/Utility/Process.o )
+ [4 of 7] Compiling Utility.SafeCommand ( Utility/SafeCommand.hs, tmp/Utility/SafeCommand.o )
+ [5 of 7] Compiling Build.TestConfig ( Build/TestConfig.hs, tmp/Build/TestConfig.o )
+ [6 of 7] Compiling Build.Configure ( Build/Configure.hs, tmp/Build/Configure.o )
+ [7 of 7] Compiling Main ( configure.hs, tmp/Main.o )
+ Linking configure ...
+ ./configure
+ checking version... 3.20121113
+ checking git... yes
+ checking git version... 1.7.10.2 (Apple Git-33)
+ checking cp -a... yes
+ checking cp -p... yes
+ checking cp --reflink=auto... no
+ checking uuid generator... uuidgen
+ checking xargs -0... yes
+ checking rsync... yes
+ checking curl... yes
+ checking wget... no
+ checking bup... no
+ checking gpg... no
+ checking lsof... yes
+ checking ssh connection caching... yes
+ checking sha1... sha1sum
+ checking sha256.../bin/sh: sha256sum: command not found
+ gsha256sum
+ checking sha512.../bin/sh: sha512sum: command not found
+ gsha512sum
+ checking sha224.../bin/sh: sha224sum: command not found
+ gsha224sum
+ checking sha384.../bin/sh: sha384sum: command not found
+ gsha384sum
+ hsc2hs Utility/Touch.hsc
+ Touch.hsc:117:2: warning: #warning \"utimensat and lutimes not available; building without symlink timestamp preservation support\"
+ Touch.hsc:117:2: warning: #warning \"utimensat and lutimes not available; building without symlink timestamp preservation support\"
+ Touch.hsc:117:2: warning: #warning \"utimensat and lutimes not available; building without symlink timestamp preservation support\"
+ hsc2hs Utility/Mounts.hsc
+ cc -Wall -c -o Utility/libdiskfree.o Utility/libdiskfree.c
+ Utility/libdiskfree.c:53:6: warning: 'statfs64' is deprecated: first deprecated in Mac OS X 10.6 [-Wdeprecated-declarations]
+ if (STATCALL(path, &buf) != 0)
+ ^
+ Utility/libdiskfree.c:16:19: note: expanded from macro 'STATCALL'
+ # define STATCALL statfs64
+ ^
+ /usr/include/sys/mount.h:381:5: note: 'statfs64' declared here
+ int statfs64(const char *, struct statfs64 *) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5,__MAC_10_6,__IPHONE_NA,__IPHONE_NA);
+ ^
+ 1 warning generated.
+ cc -Wall -c -o Utility/libmounts.o Utility/libmounts.c
+ cc -Wall -c -o Utility/libkqueue.o Utility/libkqueue.c
+ install -d tmp
+ ghc -O2 -Wall -outputdir tmp -IUtility -DWITH_ASSISTANT -DWITH_S3 -DWITH_WEBAPP -DWITH_PAIRING -DWITH_XMPP -DWITH_DNS -DWITH_KQUEUE -threaded --make git-annex -o tmp/git-annex Utility/libdiskfree.o Utility/libmounts.o Utility/libkqueue.o
+
+ Assistant/Threads/NetWatcher.hs:26:0:
+ warning: #warning Building without dbus support; will poll for network connection changes
+
+ Assistant/Threads/MountWatcher.hs:33:0:
+ warning: #warning Building without dbus support; will use mtab polling
+ [ 1 of 285] Compiling Utility.Dot ( Utility/Dot.hs, tmp/Utility/Dot.o )
+ [ 2 of 285] Compiling Utility.Mounts ( Utility/Mounts.hs, tmp/Utility/Mounts.o )
+ [ 3 of 285] Compiling Utility.Yesod ( Utility/Yesod.hs, tmp/Utility/Yesod.o )
+ [ 4 of 285] Compiling Utility.Tense ( Utility/Tense.hs, tmp/Utility/Tense.o )
+ [ 5 of 285] Compiling Utility.Verifiable ( Utility/Verifiable.hs, tmp/Utility/Verifiable.o )
+ [ 6 of 285] Compiling Assistant.Types.TransferSlots ( Assistant/Types/TransferSlots.hs, tmp/Assistant/Types/TransferSlots.o )
+ [ 7 of 285] Compiling Types.StandardGroups ( Types/StandardGroups.hs, tmp/Types/StandardGroups.o )
+ [ 8 of 285] Compiling Utility.Percentage ( Utility/Percentage.hs, tmp/Utility/Percentage.o )
+ [ 9 of 285] Compiling Utility.Observed ( Utility/Observed.hs, tmp/Utility/Observed.o )
+ [ 10 of 285] Compiling Utility.Base64 ( Utility/Base64.hs, tmp/Utility/Base64.o )
+ [ 11 of 285] Compiling Utility.DataUnits ( Utility/DataUnits.hs, tmp/Utility/DataUnits.o )
+ [ 12 of 285] Compiling Utility.JSONStream ( Utility/JSONStream.hs, tmp/Utility/JSONStream.o )
+ [ 13 of 285] Compiling Messages.JSON ( Messages/JSON.hs, tmp/Messages/JSON.o )
+ [ 14 of 285] Compiling Build.SysConfig ( Build/SysConfig.hs, tmp/Build/SysConfig.o )
+ [ 15 of 285] Compiling Types.KeySource ( Types/KeySource.hs, tmp/Types/KeySource.o )
+ [ 16 of 285] Compiling Types.Meters ( Types/Meters.hs, tmp/Types/Meters.o )
+ [ 17 of 285] Compiling Utility.State ( Utility/State.hs, tmp/Utility/State.o )
+ [ 18 of 285] Compiling Types.UUID ( Types/UUID.hs, tmp/Types/UUID.o )
+ [ 19 of 285] Compiling Types.Messages ( Types/Messages.hs, tmp/Types/Messages.o )
+ [ 20 of 285] Compiling Types.Group ( Types/Group.hs, tmp/Types/Group.o )
+ [ 21 of 285] Compiling Types.TrustLevel ( Types/TrustLevel.hs, tmp/Types/TrustLevel.o )
+ [ 22 of 285] Compiling Types.BranchState ( Types/BranchState.hs, tmp/Types/BranchState.o )
+ [ 23 of 285] Compiling Utility.PartialPrelude ( Utility/PartialPrelude.hs, tmp/Utility/PartialPrelude.o )
+ [ 24 of 285] Compiling Utility.HumanTime ( Utility/HumanTime.hs, tmp/Utility/HumanTime.o )
+ [ 25 of 285] Compiling Utility.Format ( Utility/Format.hs, tmp/Utility/Format.o )
+ [ 26 of 285] Compiling Utility.FileSystemEncoding ( Utility/FileSystemEncoding.hs, tmp/Utility/FileSystemEncoding.o )
+ [ 27 of 285] Compiling Utility.Touch ( Utility/Touch.hs, tmp/Utility/Touch.o )
+
+ Utility/Touch.hsc:17:1:
+ Warning: The import of `Utility.FileSystemEncoding' is redundant
+ except perhaps to import instances from `Utility.FileSystemEncoding'
+ To import instances alone, use: import Utility.FileSystemEncoding()
+
+ Utility/Touch.hsc:19:1:
+ Warning: The import of `Foreign' is redundant
+ except perhaps to import instances from `Foreign'
+ To import instances alone, use: import Foreign()
+
+ Utility/Touch.hsc:21:1:
+ Warning: The import of `Control.Monad' is redundant
+ except perhaps to import instances from `Control.Monad'
+ To import instances alone, use: import Control.Monad()
+ [ 28 of 285] Compiling Utility.Applicative ( Utility/Applicative.hs, tmp/Utility/Applicative.o )
+ [ 29 of 285] Compiling Utility.Monad ( Utility/Monad.hs, tmp/Utility/Monad.o )
+ [ 30 of 285] Compiling Utility.Exception ( Utility/Exception.hs, tmp/Utility/Exception.o )
+ [ 31 of 285] Compiling Utility.Misc ( Utility/Misc.hs, tmp/Utility/Misc.o )
+ [ 32 of 285] Compiling Utility.Process ( Utility/Process.hs, tmp/Utility/Process.o )
+ [ 33 of 285] Compiling Utility.SafeCommand ( Utility/SafeCommand.hs, tmp/Utility/SafeCommand.o )
+ [ 34 of 285] Compiling Utility.Network ( Utility/Network.hs, tmp/Utility/Network.o )
+ [ 35 of 285] Compiling Utility.SRV ( Utility/SRV.hs, tmp/Utility/SRV.o )
+
+ Utility/SRV.hs:88:1: Warning: Defined but not used: `lookupSRVHost'
+
+ Utility/SRV.hs:94:1: Warning: Defined but not used: `parseSrvHost'
+ [ 36 of 285] Compiling Git.Types ( Git/Types.hs, tmp/Git/Types.o )
+ [ 37 of 285] Compiling Utility.UserInfo ( Utility/UserInfo.hs, tmp/Utility/UserInfo.o )
+ [ 38 of 285] Compiling Utility.Path ( Utility/Path.hs, tmp/Utility/Path.o )
+ [ 39 of 285] Compiling Utility.TempFile ( Utility/TempFile.hs, tmp/Utility/TempFile.o )
+ [ 40 of 285] Compiling Utility.Directory ( Utility/Directory.hs, tmp/Utility/Directory.o )
+ [ 41 of 285] Compiling Utility.FreeDesktop ( Utility/FreeDesktop.hs, tmp/Utility/FreeDesktop.o )
+ [ 42 of 285] Compiling Utility.OSX ( Utility/OSX.hs, tmp/Utility/OSX.o )
+
+ Utility/OSX.hs:10:1:
+ Warning: The import of `Utility.Path' is redundant
+ except perhaps to import instances from `Utility.Path'
+ To import instances alone, use: import Utility.Path()
+ [ 43 of 285] Compiling Assistant.Install.AutoStart ( Assistant/Install/AutoStart.hs, tmp/Assistant/Install/AutoStart.o )
+ [ 44 of 285] Compiling Common ( Common.hs, tmp/Common.o )
+ [ 45 of 285] Compiling Utility.FileMode ( Utility/FileMode.hs, tmp/Utility/FileMode.o )
+ [ 46 of 285] Compiling Git ( Git.hs, tmp/Git.o )
+ [ 47 of 285] Compiling Git.FilePath ( Git/FilePath.hs, tmp/Git/FilePath.o )
+ [ 48 of 285] Compiling Utility.Matcher ( Utility/Matcher.hs, tmp/Utility/Matcher.o )
+ [ 49 of 285] Compiling Utility.Gpg ( Utility/Gpg.hs, tmp/Utility/Gpg.o )
+ [ 50 of 285] Compiling Types.Crypto ( Types/Crypto.hs, tmp/Types/Crypto.o )
+ [ 51 of 285] Compiling Types.Key ( Types/Key.hs, tmp/Types/Key.o )
+ [ 52 of 285] Compiling Types.Backend ( Types/Backend.hs, tmp/Types/Backend.o )
+ [ 53 of 285] Compiling Types.Remote ( Types/Remote.hs, tmp/Types/Remote.o )
+ [ 54 of 285] Compiling Meters ( Meters.hs, tmp/Meters.o )
+ [ 55 of 285] Compiling Git.Sha ( Git/Sha.hs, tmp/Git/Sha.o )
+ [ 56 of 285] Compiling Utility.CoProcess ( Utility/CoProcess.hs, tmp/Utility/CoProcess.o )
+ [ 57 of 285] Compiling Git.Command ( Git/Command.hs, tmp/Git/Command.o )
+ [ 58 of 285] Compiling Git.Ref ( Git/Ref.hs, tmp/Git/Ref.o )
+ [ 59 of 285] Compiling Git.Branch ( Git/Branch.hs, tmp/Git/Branch.o )
+ [ 60 of 285] Compiling Git.UpdateIndex ( Git/UpdateIndex.hs, tmp/Git/UpdateIndex.o )
+ [ 61 of 285] Compiling Git.Queue ( Git/Queue.hs, tmp/Git/Queue.o )
+ [ 62 of 285] Compiling Git.HashObject ( Git/HashObject.hs, tmp/Git/HashObject.o )
+ [ 63 of 285] Compiling Git.CatFile ( Git/CatFile.hs, tmp/Git/CatFile.o )
+ [ 64 of 285] Compiling Git.UnionMerge ( Git/UnionMerge.hs, tmp/Git/UnionMerge.o )
+ [ 65 of 285] Compiling Git.Url ( Git/Url.hs, tmp/Git/Url.o )
+ [ 66 of 285] Compiling Git.Construct ( Git/Construct.hs, tmp/Git/Construct.o )
+ [ 67 of 285] Compiling Git.Config ( Git/Config.hs, tmp/Git/Config.o )
+ [ 68 of 285] Compiling Git.SharedRepository ( Git/SharedRepository.hs, tmp/Git/SharedRepository.o )
+ [ 69 of 285] Compiling Git.Version ( Git/Version.hs, tmp/Git/Version.o )
+ [ 70 of 285] Compiling Git.CheckAttr ( Git/CheckAttr.hs, tmp/Git/CheckAttr.o )
+ [ 71 of 285] Compiling Annex ( Annex.hs, tmp/Annex.o )
+ [ 72 of 285] Compiling Types.Option ( Types/Option.hs, tmp/Types/Option.o )
+ [ 73 of 285] Compiling Types ( Types.hs, tmp/Types.o )
+ [ 74 of 285] Compiling Messages ( Messages.hs, tmp/Messages.o )
+ [ 75 of 285] Compiling Types.Command ( Types/Command.hs, tmp/Types/Command.o )
+ [ 76 of 285] Compiling Locations ( Locations.hs, tmp/Locations.o )
+ [ 77 of 285] Compiling Common.Annex ( Common/Annex.hs, tmp/Common/Annex.o )
+ [ 78 of 285] Compiling Fields ( Fields.hs, tmp/Fields.o )
+ [ 79 of 285] Compiling Annex.BranchState ( Annex/BranchState.hs, tmp/Annex/BranchState.o )
+ [ 80 of 285] Compiling Annex.CatFile ( Annex/CatFile.hs, tmp/Annex/CatFile.o )
+ [ 81 of 285] Compiling Annex.Perms ( Annex/Perms.hs, tmp/Annex/Perms.o )
+ [ 82 of 285] Compiling Crypto ( Crypto.hs, tmp/Crypto.o )
+ [ 83 of 285] Compiling Annex.Exception ( Annex/Exception.hs, tmp/Annex/Exception.o )
+ [ 84 of 285] Compiling Annex.Journal ( Annex/Journal.hs, tmp/Annex/Journal.o )
+ [ 85 of 285] Compiling Annex.Branch ( Annex/Branch.hs, tmp/Annex/Branch.o )
+ [ 86 of 285] Compiling Usage ( Usage.hs, tmp/Usage.o )
+ [ 87 of 285] Compiling Annex.CheckAttr ( Annex/CheckAttr.hs, tmp/Annex/CheckAttr.o )
+ [ 88 of 285] Compiling Remote.Helper.Special ( Remote/Helper/Special.hs, tmp/Remote/Helper/Special.o )
+ [ 89 of 285] Compiling Logs.Presence ( Logs/Presence.hs, tmp/Logs/Presence.o )
+ [ 90 of 285] Compiling Logs.Location ( Logs/Location.hs, tmp/Logs/Location.o )
+ [ 91 of 285] Compiling Logs.Web ( Logs/Web.hs, tmp/Logs/Web.o )
+ [ 92 of 285] Compiling Remote.Helper.Chunked ( Remote/Helper/Chunked.hs, tmp/Remote/Helper/Chunked.o )
+ [ 93 of 285] Compiling Annex.LockPool ( Annex/LockPool.hs, tmp/Annex/LockPool.o )
+ [ 94 of 285] Compiling Logs.Transfer ( Logs/Transfer.hs, tmp/Logs/Transfer.o )
+ [ 95 of 285] Compiling Backend.SHA ( Backend/SHA.hs, tmp/Backend/SHA.o )
+ [ 96 of 285] Compiling Backend.WORM ( Backend/WORM.hs, tmp/Backend/WORM.o )
+ [ 97 of 285] Compiling Backend.URL ( Backend/URL.hs, tmp/Backend/URL.o )
+ [ 98 of 285] Compiling Assistant.Types.ScanRemotes ( Assistant/Types/ScanRemotes.hs, tmp/Assistant/Types/ScanRemotes.o )
+ [ 99 of 285] Compiling Assistant.Types.ThreadedMonad ( Assistant/Types/ThreadedMonad.hs, tmp/Assistant/Types/ThreadedMonad.o )
+ [100 of 285] Compiling Assistant.Types.TransferQueue ( Assistant/Types/TransferQueue.hs, tmp/Assistant/Types/TransferQueue.o )
+ [101 of 285] Compiling Assistant.Types.Pushes ( Assistant/Types/Pushes.hs, tmp/Assistant/Types/Pushes.o )
+ [102 of 285] Compiling Assistant.Types.BranchChange ( Assistant/Types/BranchChange.hs, tmp/Assistant/Types/BranchChange.o )
+ [103 of 285] Compiling Logs.UUIDBased ( Logs/UUIDBased.hs, tmp/Logs/UUIDBased.o )
+ [104 of 285] Compiling Logs.Remote ( Logs/Remote.hs, tmp/Logs/Remote.o )
+ [105 of 285] Compiling Logs.Group ( Logs/Group.hs, tmp/Logs/Group.o )
+ [106 of 285] Compiling Utility.DiskFree ( Utility/DiskFree.hs, tmp/Utility/DiskFree.o )
+ [107 of 285] Compiling Utility.Url ( Utility/Url.hs, tmp/Utility/Url.o )
+ [108 of 285] Compiling Utility.CopyFile ( Utility/CopyFile.hs, tmp/Utility/CopyFile.o )
+ [109 of 285] Compiling Utility.Rsync ( Utility/Rsync.hs, tmp/Utility/Rsync.o )
+ [110 of 285] Compiling Git.LsFiles ( Git/LsFiles.hs, tmp/Git/LsFiles.o )
+ [111 of 285] Compiling Git.AutoCorrect ( Git/AutoCorrect.hs, tmp/Git/AutoCorrect.o )
+ [112 of 285] Compiling Git.CurrentRepo ( Git/CurrentRepo.hs, tmp/Git/CurrentRepo.o )
+ [113 of 285] Compiling Locations.UserConfig ( Locations/UserConfig.hs, tmp/Locations/UserConfig.o )
+ [114 of 285] Compiling Git.Merge ( Git/Merge.hs, tmp/Git/Merge.o )
+ [115 of 285] Compiling Utility.Parallel ( Utility/Parallel.hs, tmp/Utility/Parallel.o )
+ [116 of 285] Compiling Git.Remote ( Git/Remote.hs, tmp/Git/Remote.o )
+ [117 of 285] Compiling Assistant.Ssh ( Assistant/Ssh.hs, tmp/Assistant/Ssh.o )
+ [118 of 285] Compiling Assistant.Pairing ( Assistant/Pairing.hs, tmp/Assistant/Pairing.o )
+ [119 of 285] Compiling Assistant.Types.NetMessager ( Assistant/Types/NetMessager.hs, tmp/Assistant/Types/NetMessager.o )
+ [120 of 285] Compiling Utility.NotificationBroadcaster ( Utility/NotificationBroadcaster.hs, tmp/Utility/NotificationBroadcaster.o )
+ [121 of 285] Compiling Assistant.Types.Buddies ( Assistant/Types/Buddies.hs, tmp/Assistant/Types/Buddies.o )
+ [122 of 285] Compiling Utility.TSet ( Utility/TSet.hs, tmp/Utility/TSet.o )
+ [123 of 285] Compiling Assistant.Types.Commits ( Assistant/Types/Commits.hs, tmp/Assistant/Types/Commits.o )
+ [124 of 285] Compiling Assistant.Types.Changes ( Assistant/Types/Changes.hs, tmp/Assistant/Types/Changes.o )
+ [125 of 285] Compiling Utility.WebApp ( Utility/WebApp.hs, tmp/Utility/WebApp.o )
+ [126 of 285] Compiling Utility.Daemon ( Utility/Daemon.hs, tmp/Utility/Daemon.o )
+ [127 of 285] Compiling Utility.ThreadScheduler ( Utility/ThreadScheduler.hs, tmp/Utility/ThreadScheduler.o )
+ [128 of 285] Compiling Utility.LogFile ( Utility/LogFile.hs, tmp/Utility/LogFile.o )
+ [129 of 285] Compiling Git.Filename ( Git/Filename.hs, tmp/Git/Filename.o )
+ [130 of 285] Compiling Git.LsTree ( Git/LsTree.hs, tmp/Git/LsTree.o )
+ [131 of 285] Compiling Utility.Types.DirWatcher ( Utility/Types/DirWatcher.hs, tmp/Utility/Types/DirWatcher.o )
+ [132 of 285] Compiling Utility.Kqueue ( Utility/Kqueue.hs, tmp/Utility/Kqueue.o )
+ [133 of 285] Compiling Utility.DirWatcher ( Utility/DirWatcher.hs, tmp/Utility/DirWatcher.o )
+ [134 of 285] Compiling Utility.Lsof ( Utility/Lsof.hs, tmp/Utility/Lsof.o )
+ [135 of 285] Compiling Config ( Config.hs, tmp/Config.o )
+ [136 of 285] Compiling Annex.UUID ( Annex/UUID.hs, tmp/Annex/UUID.o )
+ [137 of 285] Compiling Logs.UUID ( Logs/UUID.hs, tmp/Logs/UUID.o )
+ [138 of 285] Compiling Backend ( Backend.hs, tmp/Backend.o )
+ [139 of 285] Compiling Remote.Helper.Hooks ( Remote/Helper/Hooks.hs, tmp/Remote/Helper/Hooks.o )
+ [140 of 285] Compiling Remote.Helper.Encryptable ( Remote/Helper/Encryptable.hs, tmp/Remote/Helper/Encryptable.o )
+ [141 of 285] Compiling Creds ( Creds.hs, tmp/Creds.o )
+ [142 of 285] Compiling Remote.Helper.AWS ( Remote/Helper/AWS.hs, tmp/Remote/Helper/AWS.o )
+ [143 of 285] Compiling Annex.Queue ( Annex/Queue.hs, tmp/Annex/Queue.o )
+ [144 of 285] Compiling Annex.Content ( Annex/Content.hs, tmp/Annex/Content.o )
+ [145 of 285] Compiling Remote.S3 ( Remote/S3.hs, tmp/Remote/S3.o )
+ [146 of 285] Compiling Remote.Directory ( Remote/Directory.hs, tmp/Remote/Directory.o )
+ [147 of 285] Compiling Remote.Rsync ( Remote/Rsync.hs, tmp/Remote/Rsync.o )
+ [148 of 285] Compiling Remote.Web ( Remote/Web.hs, tmp/Remote/Web.o )
+ [149 of 285] Compiling Remote.Glacier ( Remote/Glacier.hs, tmp/Remote/Glacier.o )
+ [150 of 285] Compiling Remote.Hook ( Remote/Hook.hs, tmp/Remote/Hook.o )
+ [151 of 285] Compiling Upgrade.V2 ( Upgrade/V2.hs, tmp/Upgrade/V2.o )
+ [152 of 285] Compiling Annex.Ssh ( Annex/Ssh.hs, tmp/Annex/Ssh.o )
+ [153 of 285] Compiling Remote.Helper.Ssh ( Remote/Helper/Ssh.hs, tmp/Remote/Helper/Ssh.o )
+ [154 of 285] Compiling Remote.Bup ( Remote/Bup.hs, tmp/Remote/Bup.o )
+ [155 of 285] Compiling Annex.Version ( Annex/Version.hs, tmp/Annex/Version.o )
+ [156 of 285] Compiling Init ( Init.hs, tmp/Init.o )
+ [157 of 285] Compiling Checks ( Checks.hs, tmp/Checks.o )
+ [158 of 285] Compiling Remote.Git ( Remote/Git.hs, tmp/Remote/Git.o )
+ [159 of 285] Compiling Remote.List ( Remote/List.hs, tmp/Remote/List.o )
+ [160 of 285] Compiling Logs.Trust ( Logs/Trust.hs, tmp/Logs/Trust.o )
+ [161 of 285] Compiling Remote ( Remote.hs, tmp/Remote.o )
+ [162 of 285] Compiling Assistant.Alert ( Assistant/Alert.hs, tmp/Assistant/Alert.o )
+ [163 of 285] Compiling Assistant.Types.DaemonStatus ( Assistant/Types/DaemonStatus.hs, tmp/Assistant/Types/DaemonStatus.o )
+ [164 of 285] Compiling Assistant.Monad ( Assistant/Monad.hs, tmp/Assistant/Monad.o )
+ [165 of 285] Compiling Assistant.Types.NamedThread ( Assistant/Types/NamedThread.hs, tmp/Assistant/Types/NamedThread.o )
+ [166 of 285] Compiling Assistant.Common ( Assistant/Common.hs, tmp/Assistant/Common.o )
+ [167 of 285] Compiling Assistant.XMPP ( Assistant/XMPP.hs, tmp/Assistant/XMPP.o )
+ [168 of 285] Compiling Assistant.XMPP.Buddies ( Assistant/XMPP/Buddies.hs, tmp/Assistant/XMPP/Buddies.o )
+ [169 of 285] Compiling Assistant.NetMessager ( Assistant/NetMessager.hs, tmp/Assistant/NetMessager.o )
+ [170 of 285] Compiling Assistant.Pushes ( Assistant/Pushes.hs, tmp/Assistant/Pushes.o )
+ [171 of 285] Compiling Assistant.ScanRemotes ( Assistant/ScanRemotes.hs, tmp/Assistant/ScanRemotes.o )
+ [172 of 285] Compiling Assistant.Install ( Assistant/Install.hs, tmp/Assistant/Install.o )
+ [173 of 285] Compiling Assistant.XMPP.Client ( Assistant/XMPP/Client.hs, tmp/Assistant/XMPP/Client.o )
+ [174 of 285] Compiling Assistant.Commits ( Assistant/Commits.hs, tmp/Assistant/Commits.o )
+ [175 of 285] Compiling Assistant.BranchChange ( Assistant/BranchChange.hs, tmp/Assistant/BranchChange.o )
+ [176 of 285] Compiling Assistant.Changes ( Assistant/Changes.hs, tmp/Assistant/Changes.o )
+ [177 of 285] Compiling Assistant.WebApp.Types ( Assistant/WebApp/Types.hs, tmp/Assistant/WebApp/Types.o )
+ Loading package ghc-prim ... linking ... done.
+ Loading package integer-gmp ... linking ... done.
+ Loading package base ... linking ... done.
+ Loading object (static) Utility/libdiskfree.o ... done
+ Loading object (static) Utility/libmounts.o ... done
+ Loading object (static) Utility/libkqueue.o ... done
+ final link ... done
+ Loading package bytestring-0.9.2.1 ... linking ... done.
+ Loading package zlib-0.5.4.0 ... linking ... done.
+ Loading package array-0.4.0.0 ... linking ... done.
+ Loading package deepseq-1.3.0.0 ... linking ... done.
+ Loading package primitive-0.5.0.1 ... linking ... done.
+ Loading package vector-0.10.0.1 ... linking ... done.
+ Loading package transformers-0.3.0.0 ... linking ... done.
+ Loading package text-0.11.2.3 ... linking ... done.
+ Loading package old-locale-1.0.0.4 ... linking ... done.
+ Loading package time-1.4 ... linking ... done.
+ Loading package random-1.0.1.1 ... linking ... done.
+ Loading package mtl-2.1.2 ... linking ... done.
+ Loading package parsec-3.1.3 ... linking ... done.
+ Loading package pretty-1.1.1.0 ... linking ... done.
+ Loading package filepath-1.3.0.0 ... linking ... done.
+ Loading package old-time-1.1.0.0 ... linking ... done.
+ Loading package unix-2.5.1.1 ... linking ... done.
+ Loading package directory-1.1.0.2 ... linking ... done.
+ Loading package process-1.1.0.1 ... linking ... done.
+ Loading package containers-0.4.2.1 ... linking ... done.
+ Loading package base64-bytestring-1.0.0.0 ... linking ... done.
+ Loading package cereal-0.3.5.2 ... linking ... done.
+ Loading package base-unicode-symbols-0.2.2.4 ... linking ... done.
+ Loading package transformers-base-0.4.1 ... linking ... done.
+ Loading package monad-control-0.3.1.4 ... linking ... done.
+ Loading package lifted-base-0.2 ... linking ... done.
+ Loading package resourcet-0.4.4 ... linking ... done.
+ Loading package semigroups-0.8.4.1 ... linking ... done.
+ Loading package void-0.5.8 ... linking ... done.
+ Loading package conduit-0.5.4.1 ... linking ... done.
+ Loading package entropy-0.2.1 ... linking ... done.
+ Loading package largeword-1.0.3 ... linking ... done.
+ Loading package tagged-0.4.4 ... linking ... done.
+ Loading package crypto-api-0.10.2 ... linking ... done.
+ Loading package crypto-conduit-0.4.1 ... linking ... done.
+ Loading package cryptohash-0.7.8 ... linking ... done.
+ Loading package template-haskell ... linking ... done.
+ Loading package file-embed-0.0.4.6 ... linking ... done.
+ Loading package blaze-builder-0.3.1.0 ... linking ... done.
+ Loading package hashable-1.1.2.5 ... linking ... done.
+ Loading package case-insensitive-0.4.0.3 ... linking ... done.
+ Loading package http-types-0.7.3.0.1 ... linking ... done.
+ Loading package system-filepath-0.4.7 ... linking ... done.
+ Loading package unix-compat-0.4.0.0 ... linking ... done.
+ Loading package network-2.4.0.1 ... linking ... done.
+ Loading package unordered-containers-0.2.2.1 ... linking ... done.
+ Loading package vault-0.2.0.1 ... linking ... done.
+ Loading package wai-1.3.0.1 ... linking ... done.
+ Loading package blaze-markup-0.5.1.1 ... linking ... done.
+ Loading package blaze-html-0.5.1.0 ... linking ... done.
+ Loading package attoparsec-0.10.2.0 ... linking ... done.
+ Loading package http-date-0.0.3 ... linking ... done.
+ Loading package mime-types-0.1.0.0 ... linking ... done.
+ Loading package system-fileio-0.3.10 ... linking ... done.
+ Loading package wai-app-static-1.3.0.4 ... linking ... done.
+ Loading package dlist-0.5 ... linking ... done.
+ Loading package syb-0.3.7 ... linking ... done.
+ Loading package aeson-0.6.0.2 ... linking ... done.
+ Loading package cpu-0.1.1 ... linking ... done.
+ Loading package crypto-pubkey-types-0.2.0 ... linking ... done.
+ Loading package cryptocipher-0.3.6 ... linking ... done.
+ Loading package cprng-aes-0.2.4 ... linking ... done.
+ Loading package skein-0.1.0.10 ... linking ... done.
+ Loading package clientsession-0.8.0.1 ... linking ... done.
+ Loading package data-default-0.5.0 ... linking ... done.
+ Loading package cookie-0.4.0.1 ... linking ... done.
+ Loading package failure-0.2.0.1 ... linking ... done.
+ Loading package date-cache-0.3.0 ... linking ... done.
+ Loading package unix-time-0.1.2 ... linking ... done.
+ Loading package fast-logger-0.3.1 ... linking ... done.
+ Loading package shakespeare-1.0.2 ... linking ... done.
+ Loading package hamlet-1.1.1.1 ... linking ... done.
+ Loading package monad-logger-0.2.1 ... linking ... done.
+ Loading package path-pieces-0.1.2 ... linking ... done.
+ Loading package shakespeare-css-1.0.2 ... linking ... done.
+ Loading package shakespeare-i18n-1.0.0.2 ... linking ... done.
+ Loading package shakespeare-js-1.1.0 ... linking ... done.
+ Loading package ansi-terminal-0.5.5 ... linking ... done.
+ Loading package blaze-builder-conduit-0.5.0.3 ... linking ... done.
+ Loading package stringsearch-0.3.6.4 ... linking ... done.
+ Loading package byteorder-1.0.3 ... linking ... done.
+ Loading package wai-logger-0.3.0 ... linking ... done.
+ Loading package zlib-bindings-0.1.1.2 ... linking ... done.
+ Loading package zlib-conduit-0.5.0.3 ... linking ... done.
+ Loading package wai-extra-1.3.0.4 ... linking ... done.
+ Loading package yesod-routes-1.1.1.1 ... linking ... done.
+ Loading package yesod-core-1.1.6 ... linking ... done.
+ Loading package yesod-static-1.1.1.1 ... linking ... done.
+ [178 of 285] Compiling Assistant.WebApp ( Assistant/WebApp.hs, tmp/Assistant/WebApp.o )
+ Loading package network-conduit-0.6.1.1 ... linking ... done.
+ Loading package safe-0.3.3 ... linking ... done.
+ Loading package simple-sendfile-0.2.8 ... linking ... done.
+ Loading package warp-1.3.5 ... linking ... done.
+ Loading package yaml-0.8.1.1 ... linking ... done.
+ Loading package yesod-default-1.1.2 ... linking ... done.
+ [179 of 285] Compiling Assistant.WebApp.OtherRepos ( Assistant/WebApp/OtherRepos.hs, tmp/Assistant/WebApp/OtherRepos.o )
+ [180 of 285] Compiling Limit ( Limit.hs, tmp/Limit.o )
+ [181 of 285] Compiling Option ( Option.hs, tmp/Option.o )
+ [182 of 285] Compiling Seek ( Seek.hs, tmp/Seek.o )
+ [183 of 285] Compiling Command ( Command.hs, tmp/Command.o )
+ [184 of 285] Compiling CmdLine ( CmdLine.hs, tmp/CmdLine.o )
+ [185 of 285] Compiling Command.ConfigList ( Command/ConfigList.hs, tmp/Command/ConfigList.o )
+ [186 of 285] Compiling Command.InAnnex ( Command/InAnnex.hs, tmp/Command/InAnnex.o )
+ [187 of 285] Compiling Command.DropKey ( Command/DropKey.hs, tmp/Command/DropKey.o )
+ [188 of 285] Compiling Command.SendKey ( Command/SendKey.hs, tmp/Command/SendKey.o )
+ [189 of 285] Compiling Command.RecvKey ( Command/RecvKey.hs, tmp/Command/RecvKey.o )
+ [190 of 285] Compiling Command.TransferInfo ( Command/TransferInfo.hs, tmp/Command/TransferInfo.o )
+ [191 of 285] Compiling Command.Commit ( Command/Commit.hs, tmp/Command/Commit.o )
+ [192 of 285] Compiling Command.Add ( Command/Add.hs, tmp/Command/Add.o )
+ [193 of 285] Compiling Command.Unannex ( Command/Unannex.hs, tmp/Command/Unannex.o )
+ [194 of 285] Compiling Command.FromKey ( Command/FromKey.hs, tmp/Command/FromKey.o )
+ [195 of 285] Compiling Command.ReKey ( Command/ReKey.hs, tmp/Command/ReKey.o )
+ [196 of 285] Compiling Command.Fix ( Command/Fix.hs, tmp/Command/Fix.o )
+ [197 of 285] Compiling Command.Describe ( Command/Describe.hs, tmp/Command/Describe.o )
+ [198 of 285] Compiling Command.InitRemote ( Command/InitRemote.hs, tmp/Command/InitRemote.o )
+ [199 of 285] Compiling Command.Unlock ( Command/Unlock.hs, tmp/Command/Unlock.o )
+ [200 of 285] Compiling Command.Lock ( Command/Lock.hs, tmp/Command/Lock.o )
+ [201 of 285] Compiling Command.PreCommit ( Command/PreCommit.hs, tmp/Command/PreCommit.o )
+ [202 of 285] Compiling Command.Log ( Command/Log.hs, tmp/Command/Log.o )
+ [203 of 285] Compiling Command.Merge ( Command/Merge.hs, tmp/Command/Merge.o )
+ [204 of 285] Compiling Command.Group ( Command/Group.hs, tmp/Command/Group.o )
+ [205 of 285] Compiling Command.Ungroup ( Command/Ungroup.hs, tmp/Command/Ungroup.o )
+ [206 of 285] Compiling Command.Import ( Command/Import.hs, tmp/Command/Import.o )
+ [207 of 285] Compiling Logs.Unused ( Logs/Unused.hs, tmp/Logs/Unused.o )
+ [208 of 285] Compiling Command.AddUnused ( Command/AddUnused.hs, tmp/Command/AddUnused.o )
+ [209 of 285] Compiling Command.Find ( Command/Find.hs, tmp/Command/Find.o )
+ [210 of 285] Compiling Logs.PreferredContent ( Logs/PreferredContent.hs, tmp/Logs/PreferredContent.o )
+ [211 of 285] Compiling Annex.Wanted ( Annex/Wanted.hs, tmp/Annex/Wanted.o )
+ [212 of 285] Compiling Command.Whereis ( Command/Whereis.hs, tmp/Command/Whereis.o )
+ [213 of 285] Compiling Command.Trust ( Command/Trust.hs, tmp/Command/Trust.o )
+ [214 of 285] Compiling Command.Untrust ( Command/Untrust.hs, tmp/Command/Untrust.o )
+ [215 of 285] Compiling Command.Semitrust ( Command/Semitrust.hs, tmp/Command/Semitrust.o )
+ [216 of 285] Compiling Command.Dead ( Command/Dead.hs, tmp/Command/Dead.o )
+ [217 of 285] Compiling Command.Vicfg ( Command/Vicfg.hs, tmp/Command/Vicfg.o )
+ [218 of 285] Compiling Command.Map ( Command/Map.hs, tmp/Command/Map.o )
+ [219 of 285] Compiling Command.Init ( Command/Init.hs, tmp/Command/Init.o )
+ [220 of 285] Compiling Command.Uninit ( Command/Uninit.hs, tmp/Command/Uninit.o )
+ [221 of 285] Compiling Command.Version ( Command/Version.hs, tmp/Command/Version.o )
+ [222 of 285] Compiling Upgrade.V1 ( Upgrade/V1.hs, tmp/Upgrade/V1.o )
+ [223 of 285] Compiling Upgrade.V0 ( Upgrade/V0.hs, tmp/Upgrade/V0.o )
+ [224 of 285] Compiling Upgrade ( Upgrade.hs, tmp/Upgrade.o )
+ [225 of 285] Compiling Command.Upgrade ( Command/Upgrade.hs, tmp/Command/Upgrade.o )
+ [226 of 285] Compiling Command.Drop ( Command/Drop.hs, tmp/Command/Drop.o )
+ [227 of 285] Compiling Command.Move ( Command/Move.hs, tmp/Command/Move.o )
+ [228 of 285] Compiling Command.Copy ( Command/Copy.hs, tmp/Command/Copy.o )
+ [229 of 285] Compiling Command.Get ( Command/Get.hs, tmp/Command/Get.o )
+ [230 of 285] Compiling Command.TransferKey ( Command/TransferKey.hs, tmp/Command/TransferKey.o )
+ [231 of 285] Compiling Command.DropUnused ( Command/DropUnused.hs, tmp/Command/DropUnused.o )
+ [232 of 285] Compiling Command.Fsck ( Command/Fsck.hs, tmp/Command/Fsck.o )
+ [233 of 285] Compiling Command.Reinject ( Command/Reinject.hs, tmp/Command/Reinject.o )
+ [234 of 285] Compiling Command.Migrate ( Command/Migrate.hs, tmp/Command/Migrate.o )
+ [235 of 285] Compiling Command.Unused ( Command/Unused.hs, tmp/Command/Unused.o )
+ [236 of 285] Compiling Command.Status ( Command/Status.hs, tmp/Command/Status.o )
+ [237 of 285] Compiling Command.Sync ( Command/Sync.hs, tmp/Command/Sync.o )
+ [238 of 285] Compiling Command.Help ( Command/Help.hs, tmp/Command/Help.o )
+ [239 of 285] Compiling Command.AddUrl ( Command/AddUrl.hs, tmp/Command/AddUrl.o )
+ [240 of 285] Compiling Assistant.DaemonStatus ( Assistant/DaemonStatus.hs, tmp/Assistant/DaemonStatus.o )
+ [241 of 285] Compiling Assistant.Sync ( Assistant/Sync.hs, tmp/Assistant/Sync.o )
+ [242 of 285] Compiling Assistant.MakeRemote ( Assistant/MakeRemote.hs, tmp/Assistant/MakeRemote.o )
+ [243 of 285] Compiling Assistant.XMPP.Git ( Assistant/XMPP/Git.hs, tmp/Assistant/XMPP/Git.o )
+ [244 of 285] Compiling Command.XMPPGit ( Command/XMPPGit.hs, tmp/Command/XMPPGit.o )
+ [245 of 285] Compiling Assistant.Threads.NetWatcher ( Assistant/Threads/NetWatcher.hs, tmp/Assistant/Threads/NetWatcher.o )
+ [246 of 285] Compiling Assistant.NamedThread ( Assistant/NamedThread.hs, tmp/Assistant/NamedThread.o )
+ [247 of 285] Compiling Assistant.WebApp.Notifications ( Assistant/WebApp/Notifications.hs, tmp/Assistant/WebApp/Notifications.o )
+ [248 of 285] Compiling Assistant.WebApp.SideBar ( Assistant/WebApp/SideBar.hs, tmp/Assistant/WebApp/SideBar.o )
+ [249 of 285] Compiling Assistant.WebApp.Configurators.Ssh ( Assistant/WebApp/Configurators/Ssh.hs, tmp/Assistant/WebApp/Configurators/Ssh.o )
+ [250 of 285] Compiling Assistant.WebApp.Configurators.S3 ( Assistant/WebApp/Configurators/S3.hs, tmp/Assistant/WebApp/Configurators/S3.o )
+ [251 of 285] Compiling Assistant.WebApp.Documentation ( Assistant/WebApp/Documentation.hs, tmp/Assistant/WebApp/Documentation.o )
+ [252 of 285] Compiling Assistant.WebApp.Configurators.XMPP ( Assistant/WebApp/Configurators/XMPP.hs, tmp/Assistant/WebApp/Configurators/XMPP.o )
+ [253 of 285] Compiling Assistant.Pairing.Network ( Assistant/Pairing/Network.hs, tmp/Assistant/Pairing/Network.o )
+ [254 of 285] Compiling Assistant.Pairing.MakeRemote ( Assistant/Pairing/MakeRemote.hs, tmp/Assistant/Pairing/MakeRemote.o )
+ [255 of 285] Compiling Assistant.TransferQueue ( Assistant/TransferQueue.hs, tmp/Assistant/TransferQueue.o )
+ [256 of 285] Compiling Assistant.Threads.Merger ( Assistant/Threads/Merger.hs, tmp/Assistant/Threads/Merger.o )
+ [257 of 285] Compiling Assistant.TransferSlots ( Assistant/TransferSlots.hs, tmp/Assistant/TransferSlots.o )
+ [258 of 285] Compiling Assistant.Threads.Transferrer ( Assistant/Threads/Transferrer.hs, tmp/Assistant/Threads/Transferrer.o )
+ [259 of 285] Compiling Assistant.Threads.DaemonStatus ( Assistant/Threads/DaemonStatus.hs, tmp/Assistant/Threads/DaemonStatus.o )
+ [260 of 285] Compiling Assistant.Threads.Pusher ( Assistant/Threads/Pusher.hs, tmp/Assistant/Threads/Pusher.o )
+ [261 of 285] Compiling Assistant.Threads.MountWatcher ( Assistant/Threads/MountWatcher.hs, tmp/Assistant/Threads/MountWatcher.o )
+ [262 of 285] Compiling Assistant.Threads.ConfigMonitor ( Assistant/Threads/ConfigMonitor.hs, tmp/Assistant/Threads/ConfigMonitor.o )
+ [263 of 285] Compiling Assistant.Threads.PairListener ( Assistant/Threads/PairListener.hs, tmp/Assistant/Threads/PairListener.o )
+ [264 of 285] Compiling Assistant.Threads.XMPPClient ( Assistant/Threads/XMPPClient.hs, tmp/Assistant/Threads/XMPPClient.o )
+ [265 of 285] Compiling Assistant.WebApp.Utility ( Assistant/WebApp/Utility.hs, tmp/Assistant/WebApp/Utility.o )
+ [266 of 285] Compiling Assistant.WebApp.Configurators.Edit ( Assistant/WebApp/Configurators/Edit.hs, tmp/Assistant/WebApp/Configurators/Edit.o )
+ [267 of 285] Compiling Assistant.WebApp.Configurators.Local ( Assistant/WebApp/Configurators/Local.hs, tmp/Assistant/WebApp/Configurators/Local.o )
+ [268 of 285] Compiling Assistant.WebApp.Configurators ( Assistant/WebApp/Configurators.hs, tmp/Assistant/WebApp/Configurators.o )
+ [269 of 285] Compiling Assistant.WebApp.DashBoard ( Assistant/WebApp/DashBoard.hs, tmp/Assistant/WebApp/DashBoard.o )
+ [270 of 285] Compiling Assistant.WebApp.Configurators.Pairing ( Assistant/WebApp/Configurators/Pairing.hs, tmp/Assistant/WebApp/Configurators/Pairing.o )
+ [271 of 285] Compiling Assistant.Threads.WebApp ( Assistant/Threads/WebApp.hs, tmp/Assistant/Threads/WebApp.o )
+
+ Assistant/Threads/WebApp.hs:47:1: Not in scope: `getAddBoxComR'
+
+ Assistant/Threads/WebApp.hs:47:1: Not in scope: `getEnableWebDAVR'
+ make: *** [git-annex] Error 1
+"""]]
diff --git a/doc/bugs/3.20121112:_build_error_in_assistant/comment_3_b38e40d36bba95b16afbce68e7f25a80._comment b/doc/bugs/3.20121112:_build_error_in_assistant/comment_3_b38e40d36bba95b16afbce68e7f25a80._comment
new file mode 100644
index 000000000..26bd0194b
--- /dev/null
+++ b/doc/bugs/3.20121112:_build_error_in_assistant/comment_3_b38e40d36bba95b16afbce68e7f25a80._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.49"
+ subject="comment 3"
+ date="2012-11-25T18:36:49Z"
+ content="""
+The webdav library should not be hard to install, but I've gotten the webapp to build without it.
+"""]]
diff --git a/doc/bugs/3.20121112_build_fails_on_Ubuntu_12.04.mdwn b/doc/bugs/3.20121112_build_fails_on_Ubuntu_12.04.mdwn
new file mode 100644
index 000000000..cd0897649
--- /dev/null
+++ b/doc/bugs/3.20121112_build_fails_on_Ubuntu_12.04.mdwn
@@ -0,0 +1,97 @@
+What steps will reproduce the problem?
+
+* Start with Ubuntu 12.04
+* sudo apt-get install haskell-platform libgsasl7-dev gsasl g2hs
+* cabal install git-annex --bindir=$HOME/bin
+
+What is the expected output? What do you see instead?
+
+Expected omething like "installation successful"
+
+Actual output, after build notices:
+
+
+Loading package IfElse-0.85 ... linking ... done.
+Loading object (static) dist/build/git-annex/git-annex-tmp/Utility/libdiskfree.o ... done
+Loading object (static) dist/build/git-annex/git-annex-tmp/Utility/libmounts.o ... done
+final link ... done
+[157 of 279] Compiling Assistant.Types.DaemonStatus ( Assistant/Types/DaemonStatus.hs, dist/build/git-annex/git-annex-tmp/Assistant/Types/DaemonStatus.o )
+[158 of 279] Compiling Assistant.Monad ( Assistant/Monad.hs, dist/build/git-annex/git-annex-tmp/Assistant/Monad.o )
+
+Assistant/Monad.hs:86:16:
+ Couldn't match expected type `Assistant a'
+ with actual type `Reader AssistantData a'
+ Expected type: (AssistantData -> a) -> Assistant a
+ Actual type: (AssistantData -> a) -> Reader AssistantData a
+ In the expression: reader
+ In an equation for `getAssistant': getAssistant = reader
+
+Assistant/Monad.hs:93:15:
+ Couldn't match expected type `Assistant t0'
+ with actual type `Reader r0 a0'
+ In the return type of a call of `reader'
+ In a stmt of a 'do' block: st <- reader threadState
+ In the expression:
+ do { st <- reader threadState;
+ liftIO $ runThreadState st a }
+
+Assistant/Monad.hs:99:14:
+ Couldn't match expected type `Assistant t0'
+ with actual type `Reader r0 a0'
+ In the return type of a call of `reader'
+ In a stmt of a 'do' block: d <- reader id
+ In the expression:
+ do { d <- reader id;
+ liftIO $ io $ runAssistant d a }
+
+Assistant/Monad.hs:105:14:
+ Couldn't match expected type `Assistant t0'
+ with actual type `Reader r0 a0'
+ In the return type of a call of `reader'
+ In a stmt of a 'do' block: d <- reader id
+ In the expression:
+ do { d <- reader id;
+ return $ runAssistant d a }
+
+Assistant/Monad.hs:110:14:
+ Couldn't match expected type `Assistant t0'
+ with actual type `Reader r0 a0'
+ In the return type of a call of `reader'
+ In a stmt of a 'do' block: d <- reader id
+ In the expression:
+ do { d <- reader id;
+ return $ \ v -> runAssistant d $ a v }
+
+Assistant/Monad.hs:115:14:
+ Couldn't match expected type `Assistant t0'
+ with actual type `Reader r0 a0'
+ In the return type of a call of `reader'
+ In a stmt of a 'do' block: d <- reader id
+ In the expression:
+ do { d <- reader id;
+ return $ \ v1 v2 -> runAssistant d (a v1 v2) }
+
+Assistant/Monad.hs:120:12:
+ Couldn't match expected type `Assistant a0'
+ with actual type `Reader r0 a1'
+ In the return type of a call of `reader'
+ In the first argument of `(>>=)', namely `reader v'
+ In the expression: reader v >>= liftIO . io
+cabal: Error: some packages failed to install:
+git-annex-3.20121112 failed during the building phase. The exception was:
+ExitFailure 1
+
+
+What version of git-annex are you using? On what operating system?
+
+git annex 3.20121112
+Ubuntu 12.04 (current "long term support", all packages up to date)
+
+Please provide any additional information below.
+
+No idea how important this is for git-annex in general but reporting in case it is. Thank you for working on git annex!
+
+> I was able to reproduce this build error when I force installed
+> an old version of the haskell mtl library. So git-annex needs version
+> 2.1.1 to build, and I have adjusted the build dependencies appropriately.
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/3.20121112_build_fails_on_Ubuntu_12.04/comment_1_ce2efd2196e7682f4cdbabdb0616d449._comment b/doc/bugs/3.20121112_build_fails_on_Ubuntu_12.04/comment_1_ce2efd2196e7682f4cdbabdb0616d449._comment
new file mode 100644
index 000000000..49f43149c
--- /dev/null
+++ b/doc/bugs/3.20121112_build_fails_on_Ubuntu_12.04/comment_1_ce2efd2196e7682f4cdbabdb0616d449._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.252.11.120"
+ subject="comment 1"
+ date="2012-11-15T17:53:25Z"
+ content="""
+I'm not quite sure what's going on here, but my guess is it's an out of date version of the haskell mtl library. Try installing a newer one with 'cabal install mtl'
+"""]]
diff --git a/doc/bugs/3.20121112_build_fails_on_Ubuntu_12.04/comment_2_2a6faf662ebb85a8f1c89adcdfb9adb6._comment b/doc/bugs/3.20121112_build_fails_on_Ubuntu_12.04/comment_2_2a6faf662ebb85a8f1c89adcdfb9adb6._comment
new file mode 100644
index 000000000..09e7688fe
--- /dev/null
+++ b/doc/bugs/3.20121112_build_fails_on_Ubuntu_12.04/comment_2_2a6faf662ebb85a8f1c89adcdfb9adb6._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnZEanlyzay_QlEAL0CWpyZcRTyN7vay8U"
+ nickname="Carlo"
+ subject="Not resolved"
+ date="2012-11-15T21:44:11Z"
+ content="""
+I did as instructed, same behavior though.
+
+I'll wait or keep trying things, whatever works better for you.
+"""]]
diff --git a/doc/bugs/3.20121112_build_fails_on_Ubuntu_12.04/comment_3_37f34baa34068def1adf794d0942e462._comment b/doc/bugs/3.20121112_build_fails_on_Ubuntu_12.04/comment_3_37f34baa34068def1adf794d0942e462._comment
new file mode 100644
index 000000000..88cd12df9
--- /dev/null
+++ b/doc/bugs/3.20121112_build_fails_on_Ubuntu_12.04/comment_3_37f34baa34068def1adf794d0942e462._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.252.11.120"
+ subject="comment 3"
+ date="2012-11-18T18:13:31Z"
+ content="""
+My other guess would be a too old version of ghc.
+"""]]
diff --git a/doc/bugs/3.20121112_build_fails_on_Ubuntu_12.04/comment_4_2f8a859fef9edc8eb93bf1cc74296702._comment b/doc/bugs/3.20121112_build_fails_on_Ubuntu_12.04/comment_4_2f8a859fef9edc8eb93bf1cc74296702._comment
new file mode 100644
index 000000000..781259e79
--- /dev/null
+++ b/doc/bugs/3.20121112_build_fails_on_Ubuntu_12.04/comment_4_2f8a859fef9edc8eb93bf1cc74296702._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlXlJDAF_lXaxbqeBdH4EGj6jsBjjrDODM"
+ nickname="Antoine"
+ subject="comment 4"
+ date="2012-11-21T07:33:43Z"
+ content="""
+I have the same problem (sorry, duplicate bug entry) on the same platform. The ghc version is 7.4.1 and is the one distributed by apt repos.
+"""]]
diff --git a/doc/bugs/3.20121113_build_error___39__not_in_scope_getAddBoxComR__39__.mdwn b/doc/bugs/3.20121113_build_error___39__not_in_scope_getAddBoxComR__39__.mdwn
new file mode 100644
index 000000000..59ca6b51f
--- /dev/null
+++ b/doc/bugs/3.20121113_build_error___39__not_in_scope_getAddBoxComR__39__.mdwn
@@ -0,0 +1,33 @@
+What steps will reproduce the problem?
+
+Building from latest source, Cabal update, cabal install --only dependencies, cabal configure, Cabal build
+
+What is the expected output? What do you see instead?
+
+Error message from build
+
+...
+
+Loading package DAV-0.2 ... linking ... done.
+
+Loading object (static) dist/build/git-annex/git-annex-tmp/Utility/libdiskfree.o ... done
+
+Loading object (static) dist/build/git-annex/git-annex-tmp/Utility/libmounts.o ... done
+
+final link ... done
+
+
+Assistant/Threads/WebApp.hs:47:1: Not in scope: `getAddBoxComR'
+
+Assistant/Threads/WebApp.hs:47:1: Not in scope: `getEnableWebDAVR'
+
+
+What version of git-annex are you using? On what operating system?
+
+Latest version via git from git-annex.branchable.com
+
+Debian Squeeze (6.0.6)
+
+Please provide any additional information below.
+
+> I noticed this earlier and fixed it. [[done]] --[[Joey]]
diff --git a/doc/bugs/4.20130227_won__39__t_build_on_OS_X_Lion__44___because_testpack_won__39__t_build.mdwn b/doc/bugs/4.20130227_won__39__t_build_on_OS_X_Lion__44___because_testpack_won__39__t_build.mdwn
new file mode 100644
index 000000000..5acc4d569
--- /dev/null
+++ b/doc/bugs/4.20130227_won__39__t_build_on_OS_X_Lion__44___because_testpack_won__39__t_build.mdwn
@@ -0,0 +1,57 @@
+What steps will reproduce the problem?
+
+install from a git checkout of tag 4.20130227; error comes up at the "cabal install" stage.
+
+
+What is the expected output? What do you see instead?
+
+Expected successful install; got:
+
+
+ git-annex.branchable.com$ cabal install --bindir=$HOME/bin
+ Resolving dependencies...
+ Configuring testpack-2.1.2...
+ Building testpack-2.1.2...
+ Preprocessing library testpack-2.1.2...
+ [1 of 3] Compiling Test.QuickCheck.Instances ( src/Test/QuickCheck/Instances.hs, dist/build/Test/QuickCheck/Instances.o )
+ [2 of 3] Compiling Test.QuickCheck.Tools ( src/Test/QuickCheck/Tools.hs, dist/build/Test/QuickCheck/Tools.o )
+
+ src/Test/QuickCheck/Tools.hs:33:9:
+ Warning: Fields of `MkResult' not initialised: abort
+ In the expression:
+ MkResult
+ {ok = Just (expected == actual), expect = True,
+ interrupted = False,
+ reason = "Result: expected "
+ ++ show expected ++ ", got " ++ show actual,
+ stamp = [], callbacks = []}
+ In an equation for `@=?':
+ expected @=? actual
+ = MkResult
+ {ok = Just (expected == actual), expect = True,
+ interrupted = False,
+ reason = "Result: expected "
+ ++ show expected ++ ", got " ++ show actual,
+ stamp = [], callbacks = []}
+ [3 of 3] Compiling Test.HUnit.Tools ( src/Test/HUnit/Tools.hs, dist/build/Test/HUnit/Tools.o )
+
+ src/Test/HUnit/Tools.hs:131:57:
+ `maxDiscard' is not a (visible) constructor field name
+
+ src/Test/HUnit/Tools.hs:177:40: Not in scope: `maxDiscard'
+ Failed to install testpack-2.1.2
+ cabal: Error: some packages failed to install:
+ git-annex-4.20130227 depends on testpack-2.1.2 which failed to install.
+ testpack-2.1.2 failed during the building phase. The exception was:
+ ExitFailure 1
+ git-annex.branchable.com$
+
+
+What version of git-annex are you using? On what operating system?
+
+trying to compile git checkout of 4.20130227 on OS X Lion.
+
+Please provide any additional information below.
+
+
+> removed dependency on testpack [[done]] --[[Joey]]
diff --git a/doc/bugs/4.20130227_won__39__t_build_on_OS_X_Lion__44___because_testpack_won__39__t_build/comment_1_b7140e2bf1ea9c73ecc9e214095968e7._comment b/doc/bugs/4.20130227_won__39__t_build_on_OS_X_Lion__44___because_testpack_won__39__t_build/comment_1_b7140e2bf1ea9c73ecc9e214095968e7._comment
new file mode 100644
index 000000000..b4e0c69f7
--- /dev/null
+++ b/doc/bugs/4.20130227_won__39__t_build_on_OS_X_Lion__44___because_testpack_won__39__t_build/comment_1_b7140e2bf1ea9c73ecc9e214095968e7._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-02-28T02:12:50Z"
+ content="""
+Pass -f-TestSuite to cabal to disable building the test suite.
+"""]]
diff --git a/doc/bugs/4.20130227_won__39__t_build_on_OS_X_Lion__44___because_testpack_won__39__t_build/comment_2_6be87b2fb2ed828e7b4bf785729e910e._comment b/doc/bugs/4.20130227_won__39__t_build_on_OS_X_Lion__44___because_testpack_won__39__t_build/comment_2_6be87b2fb2ed828e7b4bf785729e910e._comment
new file mode 100644
index 000000000..d2d1d6bac
--- /dev/null
+++ b/doc/bugs/4.20130227_won__39__t_build_on_OS_X_Lion__44___because_testpack_won__39__t_build/comment_2_6be87b2fb2ed828e7b4bf785729e910e._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 2"
+ date="2013-02-28T03:31:32Z"
+ content="""
+that fixed it, thank you!
+
+"""]]
diff --git a/doc/bugs/4.20130601_xmpp_sync_error.mdwn b/doc/bugs/4.20130601_xmpp_sync_error.mdwn
new file mode 100644
index 000000000..0e1f512d3
--- /dev/null
+++ b/doc/bugs/4.20130601_xmpp_sync_error.mdwn
@@ -0,0 +1,125 @@
+4.20130601 xmpp sync error.
+
+setup: A debian machine, with indirect fresh annex, android galaxy s3 with a
+fresh direct annex, both running ga-20130601.
+
+steps:
+- Start assistant on both, add jabber account to both.
+- Add box.com account on desktop with no encryption, (now correctly shows up on android, wasn't the case with 20130521).
+- Add hello.txt on desktop repo, filename is now visible on android, but content is not.
+- Add greeting.txt on desktop, nothing shows up on android, content still missing for hello.txt
+- Webapp shows uploading messages, but no errors.
+- Manually checking box.com confirms that files have been uploaded.
+
+debian desktop daemon.log:
+
+ [2013-06-02 17:57:03 CEST] main: starting assistant version 4.20130601
+ (scanning...) [2013-06-02 17:57:03 CEST] Watcher: Performing startup scan
+ (started...) [2013-06-02 17:57:52 CEST] XMPPClient: Pairing with myJabberAccount in progress
+ [2013-06-02 17:57:53 CEST] XMPPReceivePack: Syncing with myJabberAccount
+ [2013-06-02 17:58:03 CEST] XMPPClient: Pairing with myJabberAccount in progress
+ [2013-06-02 17:58:52 CEST] main: Syncing with box.com
+ warning: Not updating non-default fetch respec
+
+ Please update the configuration manually if necessary.
+ fatal: The remote end hung up unexpectedly
+ [2013-06-02 17:59:53 CEST] XMPPReceivePack: Syncing with myJabberAccount
+ [2013-06-02 18:00:02 CEST] Committer: Adding hello.txt
+
+ (testing WebDAV server...)
+ add hello.txt (checksum...) [2013-06-02 18:00:02 CEST] Committer: Committing changes to git
+ [2013-06-02 18:00:02 CEST] XMPPSendPack: Syncing with myJabberAccount
+ Already up-to-date.
+ [2013-06-02 18:00:03 CEST] Committer: Committing changes to git
+ fatal: The remote end hung up unexpectedly
+ fatal: The remote end hung up unexpectedly
+ [2013-06-02 18:00:03 CEST] XMPPSendPack: Syncing with myJabberAccount
+
+
+100% 1.0 B/s 0s
+
+[2013-06-02 18:00:19 CEST] Transferrer: Uploaded hello.txt
+ fatal: The remote end hung up unexpectedly
+ [2013-06-02 18:01:53 CEST] XMPPReceivePack: Syncing with myJabberAccount
+ fatal: The remote end hung up unexpectedly
+ [2013-06-02 18:02:04 CEST] XMPPSendPack: Syncing with myJabberAccount
+ fatal: The remote end hung up unexpectedly
+ [2013-06-02 18:03:53 CEST] XMPPReceivePack: Syncing with myJabberAccount
+ fatal: The remote end hung up unexpectedly
+ [2013-06-02 18:05:10 CEST] Committer: Adding greeting.txt
+ ok
+ (Recording state in git...)
+ (Recording state in git...)
+
+ (Recording state in git...)
+ add greeting.txt (checksum...) [2013-06-02 18:05:10 CEST] Committer: Committing changes to git
+ [2013-06-02 18:05:10 CEST] XMPPSendPack: Syncing with myJabberAccount
+ Already up-to-date.
+ [2013-06-02 18:05:11 CEST] Committer: Committing changes to git
+
+
+100% 9.0 B/s 0s
+
+[2013-06-02 18:05:24 CEST] Transferrer: Uploaded greeting.txt
+ fatal: The remote end hung up unexpectedly
+ [2013-06-02 18:06:13 CEST] XMPPReceivePack: Syncing with myJabberAccount
+ ok
+ (Recording state in git...)
+ (Recording state in git...)
+
+ (Recording state in git...)
+ fatal: The remote end hung up unexpectedly
+
+Thanks as always.
+
+
+Android daemon.log:
+ [2013-06-02 17:53:07 CEST] main: starting assistant version 4.20130601-g7483ca4
+ (scanning...) [2013-06-02 17:53:07 CEST] Watcher: Performing startup scan
+ (started...) [2013-06-02 17:57:51 CEST] XMPPClient: Pairing with myJabberAccount in progress
+ [2013-06-02 17:57:52 CEST] XMPPSendPack: Syncing with myJabberAccount
+ Already up-to-date.
+ [2013-06-02 17:58:00 CEST] XMPPSendPack: Unable to download files from your other devices.
+ [2013-06-02 17:58:00 CEST] XMPPSendPack: Syncing with myJabberAccount
+ [2013-06-02 17:58:02 CEST] XMPPClient: Pairing with myJabberAccount in progress
+ [2013-06-02 17:58:07 CEST] XMPPSendPack: Unable to download files from your other devices.
+ [2013-06-02 17:58:07 CEST] XMPPSendPack: Syncing with myJabberAccount
+ [2013-06-02 17:58:15 CEST] XMPPSendPack: Unable to download files from your other devices.
+ [2013-06-02 18:00:02 CEST] XMPPReceivePack: Syncing with myJabberAccount
+ [2013-06-02 18:00:03 CEST] XMPPReceivePack: Unable to download files from your other devices.
+ [2013-06-02 18:00:04 CEST] XMPPReceivePack: Syncing with myJabberAccount
+ Merge made by the 'recursive' strategy.
+ hello.txt | 1 +
+ 1 file changed, 1 insertion(+)
+ create mode 120000 hello.txt
+ [2013-06-02 18:00:05 CEST] Committer: Committing changes to git
+ [2013-06-02 18:00:06 CEST] XMPPSendPack: Syncing with myJabberAccount
+ Already up-to-date.
+ [2013-06-02 18:00:14 CEST] XMPPSendPack: Unable to download files from your other devices.
+ [2013-06-02 18:00:14 CEST] XMPPSendPack: Syncing with myJabberAccount
+ [2013-06-02 18:00:25 CEST] XMPPSendPack: Unable to download files from your other devices.
+ [2013-06-02 18:02:03 CEST] Committer: Committing changes to git
+ fatal: The remote end hung up unexpectedly
+ [2013-06-02 18:02:04 CEST] XMPPReceivePack: Unable to download files from your other devices.
+ [2013-06-02 18:02:04 CEST] XMPPSendPack: Syncing with myJabberAccount
+ [2013-06-02 18:02:04 CEST] XMPPReceivePack: Syncing with myJabberAccount
+ [2013-06-02 18:02:13 CEST] XMPPSendPack: Unable to download files from your other devices.
+ [2013-06-02 18:02:15 CEST] XMPPSendPack: Syncing with myJabberAccount
+ [2013-06-02 18:02:24 CEST] XMPPSendPack: Unable to download files from your other devices.
+ fatal: The remote end hung up unexpectedly
+ [2013-06-02 18:04:04 CEST] XMPPReceivePack: Unable to download files from your other devices.
+ [2013-06-02 18:05:10 CEST] XMPPReceivePack: Syncing with myJabberAccount
+ [2013-06-02 18:06:12 CEST] Committer: Committing changes to git
+ [2013-06-02 18:06:13 CEST] XMPPSendPack: Syncing with myJabberAccount
+ [2013-06-02 18:06:21 CEST] XMPPSendPack: Unable to download files from your other devices.
+ [2013-06-02 18:06:21 CEST] XMPPSendPack: Syncing with myJabberAccount
+ [2013-06-02 18:06:29 CEST] XMPPSendPack: Unable to download files from your other devices.
+ fatal: The remote end hung up unexpectedly
+ [2013-06-02 18:07:10 CEST] XMPPReceivePack: Unable to download files from your other devices.
+
+
+thanks
+
+> Since this seems clearly a lack of box.com being configured
+> to be used on the Android, I'm closing the bug: [[done]].
+> If I'm wrong, write back, and I'll reopen ;) --[[Joey]]
diff --git a/doc/bugs/4.20130601_xmpp_sync_error/comment_1_5b50d97e44cbd5b31ff24537ec3f8603._comment b/doc/bugs/4.20130601_xmpp_sync_error/comment_1_5b50d97e44cbd5b31ff24537ec3f8603._comment
new file mode 100644
index 000000000..9c5062780
--- /dev/null
+++ b/doc/bugs/4.20130601_xmpp_sync_error/comment_1_5b50d97e44cbd5b31ff24537ec3f8603._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-06-11T14:54:56Z"
+ content="""
+When you add the box.com repo on the desktop, it will show up on Android pretty quickly thanks to XMPP syncing. But this does not cause the repository to be enabled to be used on Android. You need to select it and enable it there.
+
+I can see this is the case thanks to the log you posted. The Android is constantly complaining:
+
+> XMPPSendPack: Unable to download files from your other devices.
+
+This message should also be appearing in an alert message in the sidebar of the webapp.
+"""]]
diff --git a/doc/bugs/400_mode_leakage.mdwn b/doc/bugs/400_mode_leakage.mdwn
new file mode 100644
index 000000000..63f0fb11d
--- /dev/null
+++ b/doc/bugs/400_mode_leakage.mdwn
@@ -0,0 +1,25 @@
+git-annex tends to preserve files that are added to an annex with
+a mode such as 400. (Happens to me sometimes with email attachments.)
+As these files are rsynced around, and end up on eg, a
+publically visible repo with a webserver frontend, or a repo that is
+acessible to a whole group of users, they will not be readable.
+
+I think it would make sense for git-annex to normalize file permissions
+when adding them. Of course, there's some tension here with generally
+storing file metadata when possible. Perhaps the normalization should only
+ensure that group and other have read access?
+
+(Security: We can assume that a repo that is not intended to be public is
+in a 700 directory. And since git-annex cannot preserve file modes when
+files transit through a special remote, using modes to limit access to
+individual files is not wise.)
+
+--[[Joey]]
+
+> Revisiting this, git-annex already honors core.sharedrepository settings,
+> so I just needed to set it to `world` to allow everyone to read.
+>
+> There was a code path in direct mode where that didn't work; fixed that.
+>
+> [[done]]
+> --[[Joey]]
diff --git a/doc/bugs/Add_another_repository_on_USB_drive_causes_sync_loop.mdwn b/doc/bugs/Add_another_repository_on_USB_drive_causes_sync_loop.mdwn
new file mode 100644
index 000000000..c5bff196e
--- /dev/null
+++ b/doc/bugs/Add_another_repository_on_USB_drive_causes_sync_loop.mdwn
@@ -0,0 +1,22 @@
+What steps will reproduce the problem?
+
+Mount USB drive formatted as FAT
+Make directory for repository in it.
+Set up another repository and choose to sync it with the existing one.
+
+What is the expected output? What do you see instead?
+The files should transfer from the main repository to the directory on the USB drive.
+This happens, but afterwards a new sync happens from the USB drive repository back to the other existing repositories, because the file date of all the files on the USB drive has been set to today.
+Further, git seemed to keep the USB key locked so umount was impossible until after killing it.
+
+What version of git-annex are you using? On what operating system?
+4.20130405
+Linux
+
+Please provide any additional information below.
+
+
+> Reproduced the core bug, which is that the assistant saw symlink standin
+> files as new files, and annexed them. Now it doesn't, and I have
+> it running on FAT with no trouble; can even rename symlink standin files
+> and it commits symlink changes. Calling this [[done]]. --[[Joey]]
diff --git a/doc/bugs/Add_another_repository_on_USB_drive_causes_sync_loop/comment_1_81839a6de7450734ee75b51e47a0898e._comment b/doc/bugs/Add_another_repository_on_USB_drive_causes_sync_loop/comment_1_81839a6de7450734ee75b51e47a0898e._comment
new file mode 100644
index 000000000..c90d67cc1
--- /dev/null
+++ b/doc/bugs/Add_another_repository_on_USB_drive_causes_sync_loop/comment_1_81839a6de7450734ee75b51e47a0898e._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-04-09T17:33:06Z"
+ content="""
+You seem to have told the assistant you want it to directly manage a git repository on the USB drive. So it keeps a git-annex assistant daemon running on that drive. Which yes, makes it impossible to unmount it.
+
+So, don't do that. Make the repository on the drive by selecting Add Repository -> Removable drive, which creates a bare repository and never runs the assistant in it.
+"""]]
diff --git a/doc/bugs/Add_another_repository_on_USB_drive_causes_sync_loop/comment_2_907ce31a31df94984c2bd7aaafe5b10b._comment b/doc/bugs/Add_another_repository_on_USB_drive_causes_sync_loop/comment_2_907ce31a31df94984c2bd7aaafe5b10b._comment
new file mode 100644
index 000000000..20de13ade
--- /dev/null
+++ b/doc/bugs/Add_another_repository_on_USB_drive_causes_sync_loop/comment_2_907ce31a31df94984c2bd7aaafe5b10b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/bBy7WkgQicYHIiiyj.Vm0TcMbxi2quzbPFef#6f9f7"
+ nickname="Frederik Vanrenterghem"
+ subject="comment 2"
+ date="2013-04-10T03:25:40Z"
+ content="""
+Thanks Joey, I will give that a try later today. How about the file last modified dates all having changed to the current date though - is that something that could have been avoided?
+"""]]
diff --git a/doc/bugs/Add_another_repository_on_USB_drive_causes_sync_loop/comment_3_d8a86ae0ae5fa1f91e0b40b8b2ba0406._comment b/doc/bugs/Add_another_repository_on_USB_drive_causes_sync_loop/comment_3_d8a86ae0ae5fa1f91e0b40b8b2ba0406._comment
new file mode 100644
index 000000000..76f2b12a1
--- /dev/null
+++ b/doc/bugs/Add_another_repository_on_USB_drive_causes_sync_loop/comment_3_d8a86ae0ae5fa1f91e0b40b8b2ba0406._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/bBy7WkgQicYHIiiyj.Vm0TcMbxi2quzbPFef#6f9f7"
+ nickname="Frederik Vanrenterghem"
+ subject="comment 3"
+ date="2013-04-10T13:37:38Z"
+ content="""
+The drawback of addding the extra repository as suggested is that the files can't be accessed on the USB drive when plugged into a Windows PC as far as I can tell,since they are stored in git. Isn't this a use case in scope of the assistant?
+
+Note that the setup I created yesterday effectively has resulted in all files being lost, also in the main repository. This because the files on the USB drive became links to their equivalent in the git directory on the usb drive, but they got transferred back to the laptop as 1kb files.
+"""]]
diff --git a/doc/bugs/Add_another_repository_on_USB_drive_causes_sync_loop/comment_4_1f08fd5dd4f5d8723c2b5391cc3b60f9._comment b/doc/bugs/Add_another_repository_on_USB_drive_causes_sync_loop/comment_4_1f08fd5dd4f5d8723c2b5391cc3b60f9._comment
new file mode 100644
index 000000000..6c5d259f2
--- /dev/null
+++ b/doc/bugs/Add_another_repository_on_USB_drive_causes_sync_loop/comment_4_1f08fd5dd4f5d8723c2b5391cc3b60f9._comment
@@ -0,0 +1,22 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 4"
+ date="2013-04-10T22:58:07Z"
+ content="""
+Accessing files from USB on Windows is in scope, but it needs a windows port. Then you could just run git-annex on windows and it would pull the files from USB into your main repository, like the assistant does now on Mac and Linux.
+
+-----
+
+I suspect you don't have actual irreparable data loss. Or, perhaps not. If you really need to get that data back I can try to help.
+
+As I understand what happened, files were sent over the the USB drive, and you had another assistant running in that repository. It seems to have done something wrong, and taken the 1-line standin files that git uses to represent symbolic links when on a FAT filesystem, and committed those to the annex. These new files were then sent back to your original repository.
+
+So, if you look at `git log --status`, you'll find a commit that touched every file, and if you `git revert` that commit, the tree would be returned to how it was before that rogue assistant chomped on it. The actual contents of the files, which is stored in the annex, will probably then have not been lost. Although if you're using direct mode for your repository it is possible to lose annexed content if a file is overrwitten by a newer version, so I can't guarantee that 100%, like I could for indirect mode.
+
+Anyway, I need to fix this misbehavior of the assistant when run on a FAT filesystem, it seems.
+
+------
+
+I have reproduced the bug that the assistant, in a FAT filesystem, commits symlink standin files. It seems to do this at least at startup, to all such standin files. Oddly, I did not see this behavior before when using the assistant on FAT filesystems on Android.
+"""]]
diff --git a/doc/bugs/Adding_a_repository_as_a___34__remote_server__34___creates_a_bare_repository_next_to_the_existing_one.mdwn b/doc/bugs/Adding_a_repository_as_a___34__remote_server__34___creates_a_bare_repository_next_to_the_existing_one.mdwn
new file mode 100644
index 000000000..c2e05dee0
--- /dev/null
+++ b/doc/bugs/Adding_a_repository_as_a___34__remote_server__34___creates_a_bare_repository_next_to_the_existing_one.mdwn
@@ -0,0 +1,21 @@
+**What steps will reproduce the problem?**
+
+I generated repositories on two machines an then tried to sync them via ssh (by adding a "Remote server") but I ended up with a third (bare) repository next to my data on the remote server.
+
+**What is the expected output? What do you see instead?**
+
+The assistant should recognize the existing repository (especially the .git directory) and then start syncing only the needed files.
+
+**What version of git-annex are you using? On what operating system?**
+
+git-annex version: 4.20130324, Ubuntu 11.04
+
+**Please provide any additional information below.**
+
+[[!tag /design/assistant]]
+
+> I have made it check for the .git directory and reuse the existing
+> repository if it's there. [[done]] --[[Joey]]
+>
+> (The comment about `git-annex-shell` is incorrect; it has nothing
+> to do with this.)
diff --git a/doc/bugs/Adding_a_repository_as_a___34__remote_server__34___creates_a_bare_repository_next_to_the_existing_one/comment_1_cb781d34889d583663e855c4074f8e0e._comment b/doc/bugs/Adding_a_repository_as_a___34__remote_server__34___creates_a_bare_repository_next_to_the_existing_one/comment_1_cb781d34889d583663e855c4074f8e0e._comment
new file mode 100644
index 000000000..1e36e21ba
--- /dev/null
+++ b/doc/bugs/Adding_a_repository_as_a___34__remote_server__34___creates_a_bare_repository_next_to_the_existing_one/comment_1_cb781d34889d583663e855c4074f8e0e._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="Xyem"
+ ip="87.194.19.134"
+ subject="comment 1"
+ date="2013-04-11T13:55:29Z"
+ content="""
+From what I understand, this happens when the assistant can't use git-annex-shell on the remote SSH server, as I have the same problem. The workaround I used was adding the remote SSH manually:
+
+ git remote add ssh://server/path/to/repo
+
+which the assistant recognises and uses properly.
+
+The actual fix is, obviously, get git-annex-shell working. A likely reason it is missing is that because the SSH connection the assistant uses is not interactive, git-annex-shell is not in $PATH.
+
+I think Joey's recommendation ([per our discussion here](http://git-annex.branchable.com/bugs/Can__39__t_access_files_from___39__Removable_drive__39___repo_even_if_set_as_client/#comment-8234271642283b51e173e20e217de3fc)) was to use local or XMPP pairing instead.
+"""]]
diff --git a/doc/bugs/Adding_a_repository_as_a___34__remote_server__34___creates_a_bare_repository_next_to_the_existing_one/comment_2_c0c87957d7c7a09664e60571a2ca0e8c._comment b/doc/bugs/Adding_a_repository_as_a___34__remote_server__34___creates_a_bare_repository_next_to_the_existing_one/comment_2_c0c87957d7c7a09664e60571a2ca0e8c._comment
new file mode 100644
index 000000000..881980240
--- /dev/null
+++ b/doc/bugs/Adding_a_repository_as_a___34__remote_server__34___creates_a_bare_repository_next_to_the_existing_one/comment_2_c0c87957d7c7a09664e60571a2ca0e8c._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl99Gxq3NPNvwZHp3PDufaknQH4rZb_KKY"
+ nickname="Florian"
+ subject="comment 2"
+ date="2013-04-12T15:21:11Z"
+ content="""
+I found a different workaround. I added the remote repo via the \"remote server\" option. After that I shut down the local assistant and deleted all the new bare repository stuff on the remote machine. After restarting the local assistant syncing worked as expected and no new bare repository was initialized.
+
+On an other machine I was able to transform the bare repository into a non-bare one and check out the files. After that syncing also still worked.
+
+The remote git-annex-shell is working well. I already described this in an other bug report, where I always ended up in it while trying to log into the machine manually.
+"""]]
diff --git a/doc/bugs/Adding_box.com_remote_on_Android_fails_for_me.mdwn b/doc/bugs/Adding_box.com_remote_on_Android_fails_for_me.mdwn
new file mode 100644
index 000000000..62c6a3796
--- /dev/null
+++ b/doc/bugs/Adding_box.com_remote_on_Android_fails_for_me.mdwn
@@ -0,0 +1,20 @@
+### Please describe the problem.
+
+After submitting the form in the webapp for adding a box.com remote, I get:
+
+ Internal Server Error - WEBDAV failed to write file: "Unauthorized": user error
+
+### What steps will reproduce the problem?
+
+Fill in the box.com add remote form. Username=username, password=password, "share..."=checked, directory=annex, Encryption="Encrypt all data" and hit the "Add repository" button.
+
+### What version of git-annex are you using? On what operating system?
+
+ git-annex version 4.20130513-g5185533 on Android 4.2.2
+
+### Please provide any additional information below.
+
+Didn't find a .git/annex/debug.log
+
+> This error seems entirely consistent with you entering the wrong password.
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/Adding_box.com_remote_on_Android_fails_for_me/comment_1_0303ce880415d7e043533551c2b24694._comment b/doc/bugs/Adding_box.com_remote_on_Android_fails_for_me/comment_1_0303ce880415d7e043533551c2b24694._comment
new file mode 100644
index 000000000..a55f4eeb2
--- /dev/null
+++ b/doc/bugs/Adding_box.com_remote_on_Android_fails_for_me/comment_1_0303ce880415d7e043533551c2b24694._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmmLfBDEDFfEOba8Ra46nsnTmoNHFsLObo"
+ nickname="Brian"
+ subject="It worked my second try"
+ date="2013-05-14T00:39:08Z"
+ content="""
+I enabled debug logging and tried again and this time the remote was successfully added! Maybe the first time I mistyped my password?
+
+Either way, it is working now and I created a file in my annex directory and the assistant successfully synced it to my box.com repo.
+"""]]
diff --git a/doc/bugs/Adding_git_ssh_remote_fails.mdwn b/doc/bugs/Adding_git_ssh_remote_fails.mdwn
new file mode 100644
index 000000000..392dc127b
--- /dev/null
+++ b/doc/bugs/Adding_git_ssh_remote_fails.mdwn
@@ -0,0 +1,32 @@
+### Please describe the problem.
+
+While trying to add a ssh remote, the webapp promts the error:
+
+ Reinitialized existing shared Git repository in /home/chris/annex-test/
+ git-annex: please specify a description of this repository
+
+resp.
+
+ Initialized empty shared Git repository in /home/chris/annex-test-2/
+ git-annex: please specify a description of this repository
+
+### What steps will reproduce the problem?
+
+Adding a ssh git remote.
+
+### What version of git-annex are you using? On what operating system?
+
+4.20130704-gaf18656 linux-amd64 and android
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+only successful ssh key generation in daemon.log
+
+# End of transcript or log.
+"""]]
+
+> [[done]]; bad installation. --[[Joey]]
diff --git a/doc/bugs/Adding_git_ssh_remote_fails/comment_1_05c0bd9ac7c6f0045217fd72fc1f0a1b._comment b/doc/bugs/Adding_git_ssh_remote_fails/comment_1_05c0bd9ac7c6f0045217fd72fc1f0a1b._comment
new file mode 100644
index 000000000..d976fcbb1
--- /dev/null
+++ b/doc/bugs/Adding_git_ssh_remote_fails/comment_1_05c0bd9ac7c6f0045217fd72fc1f0a1b._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.193"
+ subject="comment 1"
+ date="2013-07-05T16:04:04Z"
+ content="""
+Are you doing this on Android?
+
+Can you please enable debug logging, and post a debug log when this happens?
+"""]]
diff --git a/doc/bugs/Adding_git_ssh_remote_fails/comment_2_df05456cafdd89e8ceea830199f42d45._comment b/doc/bugs/Adding_git_ssh_remote_fails/comment_2_df05456cafdd89e8ceea830199f42d45._comment
new file mode 100644
index 000000000..89e9523b3
--- /dev/null
+++ b/doc/bugs/Adding_git_ssh_remote_fails/comment_2_df05456cafdd89e8ceea830199f42d45._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="Chris"
+ ip="89.14.216.1"
+ subject="Reason found"
+ date="2013-07-07T21:21:49Z"
+ content="""
+I found the reason for the behavior. On the server, for non-interactive login shells, the right path to git-annex was not set and an old version that was installed by the OS was used instead. I've put the \"export $PATH\" at the right position in .bashrc and now it works. Sorry for the noise.
+
+Best regards, Chris
+"""]]
diff --git a/doc/bugs/Adding_second_remote_repository_over_ssh_fails.mdwn b/doc/bugs/Adding_second_remote_repository_over_ssh_fails.mdwn
new file mode 100644
index 000000000..abb5226be
--- /dev/null
+++ b/doc/bugs/Adding_second_remote_repository_over_ssh_fails.mdwn
@@ -0,0 +1,41 @@
+What steps will reproduce the problem?
+
+Create a local and "remote server" repository
+
+Create another local repositorty and keep it seperate from the first one. Fails while creating second repository on the remote.
+
+What is the expected output? What do you see instead?
+
+Expected to get two seperate repositories on the client and server. Only first one works.
+
+Got an error:
+
+ Failed to make repository
+
+ Something went wrong setting up the repository on the remote server.
+
+ Transcript: fatal: unrecognized command 'sh -c 'mkdir -p '"'"'second'"'"'&&cd '"'"'second'"'"'&&git init --bare --shared&&git annex init&&mkdir -p ~/.ssh&&if [ ! -e ~/.ssh/git-annex-shell ]; then (echo '"'"'#!/bin/sh'"'"';echo '"'"'set -e'"'"';echo '"'"'if [ "x$SSH_ORIGINAL_COMMAND" != "x" ]; then'"'"';echo '"'"'exec git-annex-shell -c "$SSH_ORIGINAL_COMMAND"'"'"';echo '"'"'else'"'"';echo '"'"'exec git-annex-shell -c "$@"'"'"';echo '"'"'fi'"'"') > ~/.ssh/git-annex-shell; fi&&chmod 700 ~/.ssh/git-annex-shell&&touch ~/.ssh/authorized_keys&&chmod 600 ~/.ssh/authorized_keys&&echo '"'"'command="GIT_ANNEX_SHELL_DIRECTORY='"'"'"'"'"'"'"'"'second'"'"'"'"'"'"'"'"' ~/.ssh/git-annex-shell",no-agent-forwarding,no-port-forwarding,no-X11-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCvoTn+XBdlw/mQlu+NScAeuddUJqJaVXH6KUsO09OddnUvzv4W185ezbAjXfWDgN7ou0Q0xQzwiCzdoSl7T3USJQ1ywTG5Xt2sBV3RIqxyReNA7Nz0yhwWhZBJcFzof34ezNIsi9NVgEJcK2JEs2XqhO5wK5nxEDeays7ti2bqY6V21iOWSy9hlzjD4VTWTEFxQkDp4BCzDpPN934ztOtInwI8ayiTRJZlNQ+ej/AaA+/zOBWNvIFc/96iuMLKY6lLFThw1jNj5r5N7yPaysLdnwTJ3irtCzDygCpD4mau4frrOPvG90ZdcdrQSfIjRtM9nPZ5jIpohfvz0dIfgNFz marvin@marvin-U-100 '"'"' >>~/.ssh/authorized_keys'' git-annex-shell: git-shell failed
+
+
+What version of git-annex are you using? On what operating system?
+
+4.20130413-g5747bf4 ubuntu 12.10 local
+
+3.20120629 debian wheezy remote (also tried 4.20130413-g5747bf4)
+
+Please provide any additional information below.
+
+> This bug would appear to be the same as a bug I fixed today.
+>
+> Except this last bit:
+
+**Also noticed if a user has no full name set in unix account, creating
+remote repository always fails**
+
+> So, I'm going to repurpose this bug to track that problem. --[[Joey]]
+
+[[!meta title="assistant can fail to make git repository if remote server is lacking GECOS"]]
+
+>> [[done]]; git-annex always checks for missing gecos and enables
+>> a workaround. This does mean the server needs to be upgraded in order
+>> for the fix to work. --[[Joey]]
diff --git a/doc/bugs/Adding_second_remote_repository_over_ssh_fails/comment_1_308d5f517bf00c8edc53db438de52355._comment b/doc/bugs/Adding_second_remote_repository_over_ssh_fails/comment_1_308d5f517bf00c8edc53db438de52355._comment
new file mode 100644
index 000000000..6fcf8de7b
--- /dev/null
+++ b/doc/bugs/Adding_second_remote_repository_over_ssh_fails/comment_1_308d5f517bf00c8edc53db438de52355._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="marvin"
+ ip="91.152.75.65"
+ subject="comment 1"
+ date="2013-04-17T09:11:08Z"
+ content="""
+Here is the message from the nameless error:
+
+ Failed to make repository
+
+ Something went wrong setting up the repository on the remote server.
+
+ Transcript: Initialized empty shared Git repository in /home/marvin/first/ init *** Please tell me who you are. Run git config --global user.email \"you@example.com\" git config --global user.name \"Your Name\" to set your account's default identity. Omit --global to set the identity only in this repository. fatal: empty ident <marvin@testy.mydomain.fi > not allowed git-annex: user error (git [\"--git-dir=/home/marvin/first\",\"commit-tree\",\"4b825dc642cb6eb9a060e54bf8d69288fbee4904\"] exited 128) failed git-annex: init: 1 failed
+"""]]
diff --git a/doc/bugs/Adding_unencrypted_repo_on_drive_in_webapp_gives_internal_server_error__.mdwn b/doc/bugs/Adding_unencrypted_repo_on_drive_in_webapp_gives_internal_server_error__.mdwn
new file mode 100644
index 000000000..ab98c631e
--- /dev/null
+++ b/doc/bugs/Adding_unencrypted_repo_on_drive_in_webapp_gives_internal_server_error__.mdwn
@@ -0,0 +1,69 @@
+### Please describe the problem.
+
+"Internal Server Error This git repository is encrypted with a GnuPG key that you do not have" after having asked *not* to use encryption.
+
+### What steps will reproduce the problem?
+
+Here's what I did:
+
+On Ubuntu 10.4, install git-annex according to http://git-annex.branchable.com/install/Ubuntu/ then:
+
+$ git-annex webapp
+
+Create repo at suggested path Desktop/annex/.
+Add a file to that dir. Create subdir, move file there.
+Select "Add another repository" in webapp, "Removable drive", select external usb drive, leave suggested path "annex", "Use this drive", "Do not encrypt repository".
+
+-> shows "Internal Server Error
+This git repository is encrypted with a GnuPG key that you do not have.
+git-annex version 4.20131002"
+
+
+### What version of git-annex are you using? On what operating system?
+
+git-annex version 4.20131002, Ubuntu 12.04.3 LTS
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is wit[2013-10-19 00:33:55 BST] main: starting assistant version 4.20131002
+(Recording state in git...)
+(scanning...) [2013-10-19 00:33:55 BST] Watcher: Performing startup scan
+(started...)
+
+ The installed version of git is too old for .gitignores to be honored by git-annex.
+[2013-10-19 00:35:56 BST] Committer: Adding Git Annex..ation.odt
+add Git Annex installation.odt (checksum...) [2013-10-19 00:35:57 BST] Committer: Committing changes to git
+[2013-10-19 00:37:38 BST] Committer: Adding Git Annex..ation.odt
+[2013-10-19 00:37:38 BST] Committer: Committing changes to git
+git: 'remote-gcrypt' is not a git command. See 'git --help'.
+ok
+(Recording state in git...)
+(Recording state in git...)
+ok
+(Recording state in git...)
+(Recording state in git...)
+19/Oct/2013:00:38:54 +0100 [Error#yesod-core] This git repository is encrypted with a GnuPG key that you do not have. @(yesod-core-1.1.8.3:Yesod.Internal.Core ./Yesod/Internal/Core.hs:550:5)
+git: 'remote-gcrypt' is not a git command. See 'git --help'.
+19/Oct/2013:00:39:09 +0100 [Error#yesod-core] This git repository is encrypted with a GnuPG key that you do not have. @(yesod-core-1.1.8.3:Yesod.Internal.Core ./Yesod/Internal/Core.hs:550:5)
+.........+++++
+
+Not enough random bytes available. Please do some other work to give
+the OS a chance to collect more entropy! (Need 66 more bytes)
+.............+++++
+gpg: key E0424680 marked as ultimately trusted
+git: 'remote-gcrypt' is not a git command. See 'git --help'.
+19/Oct/2013:00:41:19 +0100 [Error#yesod-core] This git repository is encrypted with a GnuPG key that you do not have. @(yesod-core-1.1.8.3:Yesod.Internal.Core ./Yesod/Internal/Core.hs:550:5)
+git: 'remote-gcrypt' is not a git command. See 'git --help'.
+19/Oct/2013:00:54:33 +0100 [Error#yesod-core] This git repository is encrypted with a GnuPG key that you do not have. @(yesod-core-1.1.8.3:Yesod.Internal.Core ./Yesod/Internal/Core.hs:550:5)
+h the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
+
+I'm not at my computer, will check upstream Git later. Sorry if this has been reported before.
+
+> This only occurred when git-remote-gcrypt was not installed.
+> I've fixed the bug. [[done]] --[[Joey]]
diff --git a/doc/bugs/Addurl_downloads_but_does_not_checkout_files.mdwn b/doc/bugs/Addurl_downloads_but_does_not_checkout_files.mdwn
new file mode 100644
index 000000000..7038fe2e6
--- /dev/null
+++ b/doc/bugs/Addurl_downloads_but_does_not_checkout_files.mdwn
@@ -0,0 +1,74 @@
+What steps will reproduce the problem?
+
+Example below illustrates downloading a podcast with git annex addurl:
+
+list directory before...
+
+~/Podcasts/TuxRadar Linux Podcast (Ogg)$ ls
+folder.jpg tuxradar_s04e24.ogg
+tuxradar_s04e09.ogg tuxradar_s05e01.ogg
+tuxradar_s04e11.ogg tuxradar_s05e02.ogg
+tuxradar_s04e13.ogg tuxradar_s05e03.ogg
+tuxradar_s04e15.ogg tuxradar_s05e04.ogg
+tuxradar_s04e16.ogg www.tuxradar.com_files_podcast_tuxradar_s04e10.ogg
+tuxradar_s04e19.ogg www.tuxradar.com_files_podcast_tuxradar_s04e12.ogg
+tuxradar_s04e20.ogg www.tuxradar.com_files_podcast_tuxradar_s04e14.ogg
+tuxradar_s04e21.ogg www.tuxradar.com_files_podcast_tuxradar_s04e17.ogg
+tuxradar_s04e22.ogg www.tuxradar.com_files_podcast_tuxradar_s04e18.ogg
+tuxradar_s04e23.ogg
+
+download file...
+
+~/Podcasts/TuxRadar Linux Podcast (Ogg)$ git annex addurl http://www.tuxradar.com/files/podcast/tuxradar_s05e05.ogg
+addurl www.tuxradar.com_files_podcast_tuxradar_s05e05.ogg (downloading http://www.tuxradar.com/files/podcast/tuxradar_s05e05.ogg ...) --2013-04-10 21:18:12-- http://www.tuxradar.com/files/podcast/tuxradar_s05e05.ogg
+Resolving www.tuxradar.com (www.tuxradar.com)... 80.244.178.150
+Connecting to www.tuxradar.com (www.tuxradar.com)|80.244.178.150|:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 33249291 (32M) [application/ogg]
+Saving to: `/home/rob/Podcasts/.git/annex/tmp/URL--http&c%%www.tuxradar.com%files%podcast%tuxradar_s05e05.ogg'
+
+100%[===============================>] 33,249,291 404K/s in 81s
+
+2013-04-10 21:19:35 (399 KB/s) - `/home/rob/Podcasts/.git/annex/tmp/URL--http&c%%www.tuxradar.com%files%podcast%tuxradar_s05e05.ogg' saved [33249291/33249291]
+
+(checksum...) ok
+(Recording state in git...)
+
+file appears to have been downloaded, but isn't there...
+
+~/Podcasts/TuxRadar Linux Podcast (Ogg)$ ls
+folder.jpg tuxradar_s04e24.ogg
+tuxradar_s04e09.ogg tuxradar_s05e01.ogg
+tuxradar_s04e11.ogg tuxradar_s05e02.ogg
+tuxradar_s04e13.ogg tuxradar_s05e03.ogg
+tuxradar_s04e15.ogg tuxradar_s05e04.ogg
+tuxradar_s04e16.ogg www.tuxradar.com_files_podcast_tuxradar_s04e10.ogg
+tuxradar_s04e19.ogg www.tuxradar.com_files_podcast_tuxradar_s04e12.ogg
+tuxradar_s04e20.ogg www.tuxradar.com_files_podcast_tuxradar_s04e14.ogg
+tuxradar_s04e21.ogg www.tuxradar.com_files_podcast_tuxradar_s04e17.ogg
+tuxradar_s04e22.ogg www.tuxradar.com_files_podcast_tuxradar_s04e18.ogg
+tuxradar_s04e23.ogg
+
+What is the expected output? What do you see instead?
+
+File should exist in current directory. As you can see from above output, this has worked in the past (with older versions).
+
+What version of git-annex are you using? On what operating system?
+
+git-annex version: 4.20130405
+local repository version: 3
+default repository version: 3
+supported repository versions: 3 4
+upgrade supported from repository versions: 0 1 2
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP
+
+OS: Debian Testing/Unstable
+
+Please provide any additional information below.
+
+The repository in question was created by the assistant and I tried the above with the assistant both running and not running, with no difference. I have also tried downloading other files.
+
+EDIT: formatting
+
+> Bug only affected direct mode. I think it used to work but I broke
+> it when fixing another bug in direct mode. [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/Allow_syncing_to_a_specific_directory_on_a_USB_remote.mdwn b/doc/bugs/Allow_syncing_to_a_specific_directory_on_a_USB_remote.mdwn
new file mode 100644
index 000000000..9c6a0c9fc
--- /dev/null
+++ b/doc/bugs/Allow_syncing_to_a_specific_directory_on_a_USB_remote.mdwn
@@ -0,0 +1,30 @@
+This follows up to the [comment made by
+Laszlo](http://git-annex.branchable.com/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/#comment-f26d3b6b45bb66601ecfaa883ace161c)
+on the [recent
+poll](http://git-annex.branchable.com/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/).
+
+I too need to be able to select the directory on the remote drive that the
+annex will be synced to.
+
+If I just add a remote drive via the web app, it syncs the repository to
+`/mnt/usb/annex`, and it looks like it just creates a bare repository in
+that folder. I need the repository to be synced to something like
+`/mnt/usb/subfolder/myspecifiedfoldername` and I need that remote to be a
+full repository.
+
+My use case is that I use the USB drive to keep annexes in sync between two
+computers. I have multiple annexes that need to be synced between the two
+computers, and none of them are in a directory called `annex`. I also need
+to be able to plug the drive into other computers and access the files
+directly, without doing a `git clone` or anything like that. I have all of
+this setup and working fine with just plain old git annex, but the web app
+does not seem to support creating new repositories with this workflow.
+
+I think it makes a lot of sense to allow the web application to add a new
+remote that is simply a directory. People like me could specify the path of
+the directory to be on the mounted USB drive. Others may want to add a
+remote that is a mounted network share or something like that.
+
+> [[done]], the webapp now has a "Add another repository" option,
+> and you can just enter the path to whatever place you like inside a USB
+> drive. --[[Joey]]
diff --git a/doc/bugs/Allow_syncing_to_a_specific_directory_on_a_USB_remote/comment_1_13ecedfbb34c3564af3a790b8bf0f591._comment b/doc/bugs/Allow_syncing_to_a_specific_directory_on_a_USB_remote/comment_1_13ecedfbb34c3564af3a790b8bf0f591._comment
new file mode 100644
index 000000000..cf13d97c1
--- /dev/null
+++ b/doc/bugs/Allow_syncing_to_a_specific_directory_on_a_USB_remote/comment_1_13ecedfbb34c3564af3a790b8bf0f591._comment
@@ -0,0 +1,25 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmYiJgOvC4IDYkr2KIjMlfVD9r_1Sij_jY"
+ nickname="Douglas"
+ subject="Not limited to usb drives"
+ date="2013-01-23T02:08:38Z"
+ content="""
+I have a machine with multiple hard drives. One of these drives is strictly used for backups, ie /dev/sdc holds /home and /dev/sdd is a giant drive that i keep a backup of important items that I would like to have readily available in case of a drive failure. Somewhere in \"add more repositories\" the assistant should be able to create a copy of the repository on the same computer. When I saw the add a removable drive feature i thought it might work but it will not let me select a specific directory.
+
+Current setup, I have the assistant managing a group of repos:
+
+ /home/me/Videos.Annex
+ /home/me/Photos.Annex
+ /home/me/Documents.Annex
+
+
+I access these files via /home/me/DIRECTORY. However in case my /home drive breaks I would like to know that git-annex was faithfully keeping a copy in /mnt/bigdrive as well as on me@someothermachine. I would like to use the assistant to manage:
+
+ /mnt/bigdrive/Annex.Backups/Videos.Annex
+ /mnt/bigdrive/Annex.Backups/Photos.Annex
+ /mnt/bigdrive/Annex.Backups/Documents.Annex
+
+
+
+
+"""]]
diff --git a/doc/bugs/Android:_Clocking_on___34__Files__34___in_the_Dashboard_seems_to_do_nothing.mdwn b/doc/bugs/Android:_Clocking_on___34__Files__34___in_the_Dashboard_seems_to_do_nothing.mdwn
new file mode 100644
index 000000000..a13bb95e3
--- /dev/null
+++ b/doc/bugs/Android:_Clocking_on___34__Files__34___in_the_Dashboard_seems_to_do_nothing.mdwn
@@ -0,0 +1,21 @@
+### Please describe the problem.
+
+I expected at least a listing of files... ideally with basic navigation and options to select/deselect to be fetched/dropped
+
+### What steps will reproduce the problem?
+
+Click on "Files" link near "Repository: " on top right of the Dashboard
+
+### What version of git-annex are you using? On what operating system?
+
+last Android build from Nov 18 2013
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
diff --git a/doc/bugs/Android:_Clocking_on___34__Files__34___in_the_Dashboard_seems_to_do_nothing/comment_1_a9b03d4f4760fea2754a4dc93547f0a3._comment b/doc/bugs/Android:_Clocking_on___34__Files__34___in_the_Dashboard_seems_to_do_nothing/comment_1_a9b03d4f4760fea2754a4dc93547f0a3._comment
new file mode 100644
index 000000000..69cfaefd2
--- /dev/null
+++ b/doc/bugs/Android:_Clocking_on___34__Files__34___in_the_Dashboard_seems_to_do_nothing/comment_1_a9b03d4f4760fea2754a4dc93547f0a3._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.64"
+ subject="comment 1"
+ date="2013-11-26T16:12:42Z"
+ content="""
+git-annex does not have a built-in file manager. I don't know how to get android to display a file manager; if there's a command that can be run, or an intent that can be used to get one, git-annex could do that. But I don't think android typically includes a file manager, I have only seen them as OEM addons on some of the more laptop form factor android devices.
+
+I think that the android web browser also does not support browsing file:// uri, which is what git-annex falls back to when it cannot file a file manager to top.
+"""]]
diff --git a/doc/bugs/Android:_Clocking_on___34__Files__34___in_the_Dashboard_seems_to_do_nothing/comment_2_015e859a16b1ce4c0c7601df0594d555._comment b/doc/bugs/Android:_Clocking_on___34__Files__34___in_the_Dashboard_seems_to_do_nothing/comment_2_015e859a16b1ce4c0c7601df0594d555._comment
new file mode 100644
index 000000000..039acd440
--- /dev/null
+++ b/doc/bugs/Android:_Clocking_on___34__Files__34___in_the_Dashboard_seems_to_do_nothing/comment_2_015e859a16b1ce4c0c7601df0594d555._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://yarikoptic.myopenid.com/"
+ nickname="site-myopenid"
+ subject="comment 2"
+ date="2013-11-27T04:36:14Z"
+ content="""
+Thanks for the explanation! Might be better then to remove Files in Android build to prevent confusion?
+
+OI filemanager http://www.openintents.org/en/filemanager I believe is open source. according to app info it is only 1.53MB (thus negligible in comparison) and probably could be 'collaborated with' so they could ship basic support for annex (git annex get/drop)... I just don't know if it would be possible to start existing OI manager under annex user (that would be needed right?).
+"""]]
diff --git a/doc/bugs/Android___34__This_build_of_git-annex_does_not_support_XMPP_pairing__34__.mdwn b/doc/bugs/Android___34__This_build_of_git-annex_does_not_support_XMPP_pairing__34__.mdwn
new file mode 100644
index 000000000..08b44fc93
--- /dev/null
+++ b/doc/bugs/Android___34__This_build_of_git-annex_does_not_support_XMPP_pairing__34__.mdwn
@@ -0,0 +1,24 @@
+### Please describe the problem.
+
+Upon a new (re-)installation of Android ("proper" build as from http://downloads.kitenet.net/git-annex/android/current/4.0/git-annex.apk Last-Modified: Mon, 18 Nov 2013 11:57:25 GMT), as well as whatever was day before a daily build, I am getting a message in web ui "not supported This build of git-annex does not support XMPP pairing. Sorry!" whenever I am entering "Share with your other devices" among "Add more repositories".
+
+### What steps will reproduce the problem?
+
+I had some older and then freshier (yesterday daily build) installed. Then uninstalled and current "proper" build installed.
+it picked up initialized repository I did yesterday but when I went into "Share ..." link I saw the message without any option to add such another device
+
+### What version of git-annex are you using? On what operating system?
+
+Android
+
+About says 5.20131118-gc7e5cde.
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
diff --git a/doc/bugs/Android___34__This_build_of_git-annex_does_not_support_XMPP_pairing__34__/comment_1_c034bb84e58b2dda1038ba205ec78c56._comment b/doc/bugs/Android___34__This_build_of_git-annex_does_not_support_XMPP_pairing__34__/comment_1_c034bb84e58b2dda1038ba205ec78c56._comment
new file mode 100644
index 000000000..ef0661cb8
--- /dev/null
+++ b/doc/bugs/Android___34__This_build_of_git-annex_does_not_support_XMPP_pairing__34__/comment_1_c034bb84e58b2dda1038ba205ec78c56._comment
@@ -0,0 +1,273 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.64"
+ subject="comment 1"
+ date="2013-11-26T17:23:52Z"
+ content="""
+I think that older Android builds did support this (IIRC). However, I recently rebootstrapped my android dev environment, and when I enable the XMPP flag now:
+
+<pre>
+system.c:222:0: error: undefined reference to 'pthread_atfork'
+
+cipher.c:213:0: error: undefined reference to 'nettle_cbc_encrypt'
+
+cipher.c:213:0: error: undefined reference to 'nettle_cbc_decrypt'
+
+cipher.c:213:0: error: undefined reference to 'nettle_des_encrypt'
+
+cipher.c:213:0: error: undefined reference to 'nettle_des_decrypt'
+
+cipher.c:213:0:
+ error: undefined reference to 'nettle_arcfour_crypt'
+
+cipher.c:213:0:
+ error: undefined reference to 'nettle_des3_encrypt'
+
+cipher.c:213:0:
+ error: undefined reference to 'nettle_des3_decrypt'
+
+cipher.c:213:0:
+ error: undefined reference to 'nettle_arctwo_encrypt'
+
+cipher.c:213:0:
+ error: undefined reference to 'nettle_arctwo_decrypt'
+
+cipher.c:265:0:
+ error: undefined reference to 'nettle_arcfour_set_key'
+
+cipher.c:68:0:
+ error: undefined reference to 'nettle_aes_set_encrypt_key'
+
+cipher.c:69:0:
+ error: undefined reference to 'nettle_aes_invert_key'
+
+cipher.c:96:0:
+ error: undefined reference to 'nettle_camellia_set_encrypt_key'
+
+cipher.c:97:0:
+ error: undefined reference to 'nettle_camellia_invert_key'
+
+cipher.c:268:0:
+ error: undefined reference to 'nettle_arctwo_set_key'
+
+cipher.c:239:0:
+ error: undefined reference to 'nettle_des_fix_parity'
+
+cipher.c:242:0:
+ error: undefined reference to 'nettle_des3_set_key'
+
+cipher.c:255:0:
+ error: undefined reference to 'nettle_des_fix_parity'
+
+cipher.c:257:0: error: undefined reference to 'nettle_des_set_key'
+
+cipher.c:83:0: error: undefined reference to 'nettle_aes_decrypt'
+
+cipher.c:76:0: error: undefined reference to 'nettle_aes_encrypt'
+
+cipher.c:111:0:
+ error: undefined reference to 'nettle_camellia_crypt'
+
+cipher.c:104:0:
+ error: undefined reference to 'nettle_camellia_crypt'
+
+mac.c:146:0:
+ error: undefined reference to 'nettle_hmac_sha256_update'
+
+mac.c:146:0:
+ error: undefined reference to 'nettle_hmac_sha224_digest'
+
+mac.c:146:0:
+ error: undefined reference to 'nettle_hmac_sha224_set_key'
+
+mac.c:146:0:
+ error: undefined reference to 'nettle_hmac_md5_update'
+
+mac.c:146:0:
+ error: undefined reference to 'nettle_hmac_md5_digest'
+
+mac.c:146:0:
+ error: undefined reference to 'nettle_hmac_md5_set_key'
+
+mac.c:146:0:
+ error: undefined reference to 'nettle_hmac_sha1_update'
+
+mac.c:146:0:
+ error: undefined reference to 'nettle_hmac_sha1_digest'
+
+mac.c:146:0:
+ error: undefined reference to 'nettle_hmac_sha1_set_key'
+
+mac.c:146:0:
+ error: undefined reference to 'nettle_hmac_sha256_digest'
+
+mac.c:146:0:
+ error: undefined reference to 'nettle_hmac_sha256_set_key'
+
+mac.c:146:0:
+ error: undefined reference to 'nettle_hmac_sha512_update'
+
+mac.c:146:0:
+ error: undefined reference to 'nettle_hmac_sha384_digest'
+
+mac.c:146:0:
+ error: undefined reference to 'nettle_hmac_sha384_set_key'
+
+mac.c:146:0:
+ error: undefined reference to 'nettle_hmac_sha512_digest'
+
+mac.c:146:0:
+ error: undefined reference to 'nettle_hmac_sha512_set_key'
+
+mac.c:243:0: error: undefined reference to 'nettle_sha224_init'
+
+mac.c:222:0: error: undefined reference to 'nettle_md5_init'
+
+mac.c:229:0: error: undefined reference to 'nettle_sha1_init'
+
+mac.c:236:0: error: undefined reference to 'nettle_md2_init'
+
+mac.c:250:0: error: undefined reference to 'nettle_sha256_init'
+
+mac.c:257:0: error: undefined reference to 'nettle_sha384_init'
+
+mac.c:264:0: error: undefined reference to 'nettle_sha512_init'
+
+mac.c:278:0: error: undefined reference to 'nettle_sha256_update'
+
+mac.c:278:0: error: undefined reference to 'nettle_sha224_digest'
+
+mac.c:278:0: error: undefined reference to 'nettle_md5_update'
+
+mac.c:278:0: error: undefined reference to 'nettle_md5_digest'
+
+mac.c:278:0: error: undefined reference to 'nettle_sha1_update'
+
+mac.c:278:0: error: undefined reference to 'nettle_sha1_digest'
+
+mac.c:278:0: error: undefined reference to 'nettle_md2_update'
+
+mac.c:278:0: error: undefined reference to 'nettle_md2_digest'
+
+mac.c:278:0: error: undefined reference to 'nettle_sha256_digest'
+
+mac.c:278:0: error: undefined reference to 'nettle_sha512_update'
+
+mac.c:278:0: error: undefined reference to 'nettle_sha384_digest'
+
+mac.c:278:0: error: undefined reference to 'nettle_sha512_digest'
+
+mpi.c:48:0:
+ error: undefined reference to 'nettle_mpz_sizeinbase_256_u'
+
+mpi.c:80:0: error: undefined reference to 'nettle_mpz_get_str_256'
+
+mpi.c:76:0: error: undefined reference to 'nettle_mpz_get_str_256'
+
+mpi.c:52:0:
+ error: undefined reference to 'nettle_mpz_sizeinbase_256_s'
+
+mpi.c:56:0:
+ error: undefined reference to 'nettle_mpz_sizeinbase_256_u'
+
+mpi.c:142:0:
+ error: undefined reference to 'nettle_mpz_set_str_256_u'
+
+mpi.c:117:0:
+ error: undefined reference to 'nettle_mpz_set_str_256_u'
+
+mpi.c:121:0:
+ error: undefined reference to 'nettle_mpz_set_str_256_s'
+
+mpi.c:470:0:
+ error: undefined reference to 'nettle_mpz_set_str_256_u'
+
+mpi.c:496:0:
+ error: undefined reference to 'nettle_mpz_set_str_256_u'
+
+pk.c:505:0:
+ error: undefined reference to 'nettle_dsa_public_key_init'
+
+pk.c:506:0:
+ error: undefined reference to 'nettle_dsa_private_key_init'
+
+pk.c:515:0:
+ error: undefined reference to 'nettle_dsa_generate_keypair'
+
+pk.c:545:0:
+ error: undefined reference to 'nettle_dsa_private_key_clear'
+
+pk.c:546:0:
+ error: undefined reference to 'nettle_dsa_public_key_clear'
+
+pk.c:558:0:
+ error: undefined reference to 'nettle_rsa_public_key_init'
+
+pk.c:559:0:
+ error: undefined reference to 'nettle_rsa_private_key_init'
+
+pk.c:563:0:
+ error: undefined reference to 'nettle_rsa_generate_keypair'
+
+pk.c:598:0:
+ error: undefined reference to 'nettle_rsa_private_key_clear'
+
+pk.c:599:0:
+ error: undefined reference to 'nettle_rsa_public_key_clear'
+
+pk.c:598:0:
+ error: undefined reference to 'nettle_rsa_private_key_clear'
+
+pk.c:599:0:
+ error: undefined reference to 'nettle_rsa_public_key_clear'
+
+pk.c:545:0:
+ error: undefined reference to 'nettle_dsa_private_key_clear'
+
+pk.c:546:0:
+ error: undefined reference to 'nettle_dsa_public_key_clear'
+
+pk.c:286:0:
+ error: undefined reference to 'nettle_dsa_signature_init'
+
+pk.c:296:0: error: undefined reference to '_nettle_dsa_sign'
+
+pk.c:309:0:
+ error: undefined reference to 'nettle_dsa_signature_clear'
+
+pk.c:344:0:
+ error: undefined reference to 'nettle_rsa_compute_root'
+
+pk.c:309:0:
+ error: undefined reference to 'nettle_dsa_signature_clear'
+
+pk.c:231:0:
+ error: undefined reference to 'nettle_rsa_compute_root'
+
+pk.c:441:0: error: undefined reference to '_nettle_dsa_verify'
+
+rnd.c:222:0:
+ error: undefined reference to 'nettle_yarrow256_update'
+
+rnd.c:340:0:
+ error: undefined reference to 'nettle_yarrow256_update'
+
+rnd.c:284:0:
+ error: undefined reference to 'nettle_yarrow256_update'
+
+rnd.c:388:0:
+ error: undefined reference to 'nettle_yarrow256_slow_reseed'
+
+rnd.c:465:0:
+ error: undefined reference to 'nettle_yarrow256_random'
+
+rnd.c:421:0: error: undefined reference to 'nettle_yarrow256_init'
+
+rnd.c:437:0:
+ error: undefined reference to 'nettle_yarrow256_slow_reseed'
+collect2: error: ld returned 1 exit status
+make: *** [android] Error 1
+</pre>
+
+
+"""]]
diff --git a/doc/bugs/Android___34__This_build_of_git-annex_does_not_support_XMPP_pairing__34__/comment_2_99a754f41d59fdd401ba6d169945e7c9._comment b/doc/bugs/Android___34__This_build_of_git-annex_does_not_support_XMPP_pairing__34__/comment_2_99a754f41d59fdd401ba6d169945e7c9._comment
new file mode 100644
index 000000000..6c5f48d5c
--- /dev/null
+++ b/doc/bugs/Android___34__This_build_of_git-annex_does_not_support_XMPP_pairing__34__/comment_2_99a754f41d59fdd401ba6d169945e7c9._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.64"
+ subject="comment 2"
+ date="2013-11-26T19:40:55Z"
+ content="""
+Managed to get it to build with XMPP, but it was quite a hack job getting the C libraries to behave, and I have not been able to test it yet. The daily build has it if you want to give it a try.
+"""]]
diff --git a/doc/bugs/Android_app_permission_denial_on_startup.mdwn b/doc/bugs/Android_app_permission_denial_on_startup.mdwn
new file mode 100644
index 000000000..689d7a748
--- /dev/null
+++ b/doc/bugs/Android_app_permission_denial_on_startup.mdwn
@@ -0,0 +1,18 @@
+### Please describe the problem.
+
+Android app barfs on startup.
+
+### What steps will reproduce the problem?
+
+Download/install/start Android app :)
+
+### What version of git-annex are you using? On what operating system?
+
+Just downloaded the .apk (Friday May 3rd). Android 4.2.2 on Google/LG Nexus 4
+
+### Please provide any additional information below.
+
+See this [screenshot](https://docs.google.com/file/d/0B8tqeaAn45VORU1ET1ZpTWxLTjQ/edit?usp=sharing).
+Feel free to ping me on IRC if you need additional info or want to test a fix.
+
+> [[done]]; now comprehensively fixed. --[[Joey]]
diff --git a/doc/bugs/Android_app_permission_denial_on_startup/comment_10_dc06737997c8883ef0a12dbecd9ac30f._comment b/doc/bugs/Android_app_permission_denial_on_startup/comment_10_dc06737997c8883ef0a12dbecd9ac30f._comment
new file mode 100644
index 000000000..417d23e84
--- /dev/null
+++ b/doc/bugs/Android_app_permission_denial_on_startup/comment_10_dc06737997c8883ef0a12dbecd9ac30f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlcxKZHglATIiJXD7jcxfYhkhgeFmcVFqE"
+ nickname="James"
+ subject="21-May-2013 still broken"
+ date="2013-05-24T12:00:37Z"
+ content="""
+I downloaded the android app dated 21-May-2013. I get the same permission error as before on startup.
+"""]]
diff --git a/doc/bugs/Android_app_permission_denial_on_startup/comment_11_b444cd6717658116533745c51481dd3d._comment b/doc/bugs/Android_app_permission_denial_on_startup/comment_11_b444cd6717658116533745c51481dd3d._comment
new file mode 100644
index 000000000..b776c2e7d
--- /dev/null
+++ b/doc/bugs/Android_app_permission_denial_on_startup/comment_11_b444cd6717658116533745c51481dd3d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 11"
+ date="2013-05-29T17:01:55Z"
+ content="""
+Today's autobuild of git-annex for Android has a workaround for this problem. You can select \"Open WebApp\" from the menu in the terminal emulator app, and it should work. Would appreciate confirmation from someone who has seen this problem. If that menu item works, I may later be able to make it open automatically.
+"""]]
diff --git a/doc/bugs/Android_app_permission_denial_on_startup/comment_12_66181f34ed7496d1f6601b39e5ae3c65._comment b/doc/bugs/Android_app_permission_denial_on_startup/comment_12_66181f34ed7496d1f6601b39e5ae3c65._comment
new file mode 100644
index 000000000..5a099121c
--- /dev/null
+++ b/doc/bugs/Android_app_permission_denial_on_startup/comment_12_66181f34ed7496d1f6601b39e5ae3c65._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkGCmVc5qIJaQQgG82Hc5zzBdAVdhe2JEM"
+ nickname="Bruno"
+ subject="comment 12"
+ date="2013-05-29T17:20:40Z"
+ content="""
+It works!
+
+Note that the \"open webapp\" menu item is not available if my phone is set to French.
+
+French: http://i.imgur.com/cik0sIL.png
+English: http://i.imgur.com/8Oh6FEw.png
+"""]]
diff --git a/doc/bugs/Android_app_permission_denial_on_startup/comment_1_ddf5761bf14de30ac97030ad338601ae._comment b/doc/bugs/Android_app_permission_denial_on_startup/comment_1_ddf5761bf14de30ac97030ad338601ae._comment
new file mode 100644
index 000000000..0f72b661e
--- /dev/null
+++ b/doc/bugs/Android_app_permission_denial_on_startup/comment_1_ddf5761bf14de30ac97030ad338601ae._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-05-03T22:44:36Z"
+ content="""
+> startActivity asks to run as user -2 but is calling from user 0; this requires android.permission.INTERACT_ACROSS_USERS_FULL
+
+The webapp continues running despite this, so you can certainly work around this by copying and pasting the displayed url into the web browser.
+
+<http://stackoverflow.com/questions/14744578/how-could-a-root-app-call-apis-with-signature-level-protected-permission>
+
+Based on this post, I cannot simply modify the app to request this permission. I don't know why your Android is requiring this permission, which AFAICS is supposed to be used to switch which user is logged in, when I'm merely trying to open a web browser. You might try closing any web browser you have open and see if that avoids the problem.
+"""]]
diff --git a/doc/bugs/Android_app_permission_denial_on_startup/comment_2_8b9fafa73ebf5f803c7da9531cfb5b34._comment b/doc/bugs/Android_app_permission_denial_on_startup/comment_2_8b9fafa73ebf5f803c7da9531cfb5b34._comment
new file mode 100644
index 000000000..ca6a8b9ff
--- /dev/null
+++ b/doc/bugs/Android_app_permission_denial_on_startup/comment_2_8b9fafa73ebf5f803c7da9531cfb5b34._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkGCmVc5qIJaQQgG82Hc5zzBdAVdhe2JEM"
+ nickname="Bruno"
+ subject="comment 2"
+ date="2013-05-04T05:02:45Z"
+ content="""
+I have the same problem. Also with a Nexus 4 (4.2.2).
+
+The problem still happens if I start git annex before any browser is open. I tested after a reboot.
+"""]]
diff --git a/doc/bugs/Android_app_permission_denial_on_startup/comment_3_58501bb043b4c5836d7472ffd6baa72c._comment b/doc/bugs/Android_app_permission_denial_on_startup/comment_3_58501bb043b4c5836d7472ffd6baa72c._comment
new file mode 100644
index 000000000..419e6bceb
--- /dev/null
+++ b/doc/bugs/Android_app_permission_denial_on_startup/comment_3_58501bb043b4c5836d7472ffd6baa72c._comment
@@ -0,0 +1,23 @@
+[[!comment format=mdwn
+ username="https://launchpad.net/~subito"
+ nickname="subito"
+ subject="Galaxy Nexus: same here"
+ date="2013-05-05T10:46:12Z"
+ content="""
+ Falling back to hardcoded app location; cannot find expected files in /data/app-lib
+ git annex webapp
+ u0_a65@android:/sdcard/git-annex.home $ git annex webapp
+ Launching web browser on http://127.0.0.1:38549 /?auth=38bf9df739a9f1671fd99153e2ef1e81a54dece8b18469152692277c056208cda039e1d9486e3115144a3e3da14a51056b260400ee563cde30b28b10b25ca2d0
+ Starting: Intent { act=android.intent.action.VIEW dat=http://127.0.0.1:38549/?auth=38bf9df739a9f1671fd99153e2ef1e81a54dece8b18469152692277c056208cda039e1d9486e3115144a3e3da14a51056b260400ee563cde30b28b10b25ca2d0 }
+ java.lang.SecurityException: Permission Denial: startActivity asks to run as user -2 but is calling from user 0; this requires android.permission.INTERACT_ACROSS_USERS_FULL
+ at android.os.Parcel.readException(Parcel.java:1425)
+ at android.os.Parcel.readException(Parcel.java:1379)
+ at android.app.ActivityManagerProxy.startActivityAsUser(ActivityManagerNative.java:1921)
+ at com.android.commands.am.Am.runStart(Am.java:494)
+ at com.android.commands.am.Am.run(Am.java:109)
+ at com.android.commands.am.Am.main(Am.java:82)
+ at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
+ at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:235)
+ at dalvik.system.NativeStart.main(Native Method)
+ failed to start web browser
+"""]]
diff --git a/doc/bugs/Android_app_permission_denial_on_startup/comment_4_d3a04dc7bbc1816cccc8d85c73ffb689._comment b/doc/bugs/Android_app_permission_denial_on_startup/comment_4_d3a04dc7bbc1816cccc8d85c73ffb689._comment
new file mode 100644
index 000000000..5f6ce0b66
--- /dev/null
+++ b/doc/bugs/Android_app_permission_denial_on_startup/comment_4_d3a04dc7bbc1816cccc8d85c73ffb689._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn26WQjIP5fnMgQF_L_k3Q3UrR5v8mjRTY"
+ nickname="Ellis"
+ subject="comment 4"
+ date="2013-05-05T12:18:41Z"
+ content="""
+I'm also using a Samsung Galaxy Nexus with the latest Android and git-annex, and I'm getting the same error as above (with different port, auth id, and uid). Opening the url manually does work, as Joey said.
+"""]]
diff --git a/doc/bugs/Android_app_permission_denial_on_startup/comment_5_eeabbc0cc434ed84c36a3f4e03fcef36._comment b/doc/bugs/Android_app_permission_denial_on_startup/comment_5_eeabbc0cc434ed84c36a3f4e03fcef36._comment
new file mode 100644
index 000000000..cfd0e8663
--- /dev/null
+++ b/doc/bugs/Android_app_permission_denial_on_startup/comment_5_eeabbc0cc434ed84c36a3f4e03fcef36._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 5"
+ date="2013-05-06T14:13:51Z"
+ content="""
+I have also had a report that this happens on a galaxy nexus 4.2.1.
+
+So far, every reporter has had a galaxy nexus. Hmm...
+"""]]
diff --git a/doc/bugs/Android_app_permission_denial_on_startup/comment_6_4203b496bee1bdd424466ed63b5d31cf._comment b/doc/bugs/Android_app_permission_denial_on_startup/comment_6_4203b496bee1bdd424466ed63b5d31cf._comment
new file mode 100644
index 000000000..1f2179271
--- /dev/null
+++ b/doc/bugs/Android_app_permission_denial_on_startup/comment_6_4203b496bee1bdd424466ed63b5d31cf._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkGCmVc5qIJaQQgG82Hc5zzBdAVdhe2JEM"
+ nickname="Bruno"
+ subject="comment 6"
+ date="2013-05-06T14:29:59Z"
+ content="""
+The Galaxy Nexus (Samsung) is not the same as the Nexus 4 (LG).
+
+See: https://en.wikipedia.org/wiki/Google_Nexus#Comparison_of_phones
+"""]]
diff --git a/doc/bugs/Android_app_permission_denial_on_startup/comment_7_74373eb2cc46b76659e3c463d6682d15._comment b/doc/bugs/Android_app_permission_denial_on_startup/comment_7_74373eb2cc46b76659e3c463d6682d15._comment
new file mode 100644
index 000000000..12c1e3eed
--- /dev/null
+++ b/doc/bugs/Android_app_permission_denial_on_startup/comment_7_74373eb2cc46b76659e3c463d6682d15._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn26WQjIP5fnMgQF_L_k3Q3UrR5v8mjRTY"
+ nickname="Ellis"
+ subject="addendum to comment 4"
+ date="2013-05-06T15:32:51Z"
+ content="""
+As a side node, my device is rooted. The web browser starts properly when I start it as follows: adb shell; su; /data/data/ga.androidterm/runshell; git annex webapp
+
+However, with previous versions of git-annex for android, I had problems with git-annex when starting it this way; if I recall correctly, ``git annex get`` didn't work. Will test again when I have time.
+"""]]
diff --git a/doc/bugs/Android_app_permission_denial_on_startup/comment_8_0923d2a09df01d152ec4784c92689c96._comment b/doc/bugs/Android_app_permission_denial_on_startup/comment_8_0923d2a09df01d152ec4784c92689c96._comment
new file mode 100644
index 000000000..98e1e19ed
--- /dev/null
+++ b/doc/bugs/Android_app_permission_denial_on_startup/comment_8_0923d2a09df01d152ec4784c92689c96._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://adamspiers.myopenid.com/"
+ nickname="Adam"
+ subject="more info on original report"
+ date="2013-05-08T11:16:30Z"
+ content="""
+I should have said that I am running a recent-ish nightly of CyanogenMod 10.1. This means that my Nexus 4 is rooted. Bruno is quite correct to point out that the Nexus 4 (made by LG) is a very different beast to the Galaxy Nexus (made by Samsung).
+"""]]
diff --git a/doc/bugs/Android_app_permission_denial_on_startup/comment_9_b60928e54a5b620899cf29820b9b8e70._comment b/doc/bugs/Android_app_permission_denial_on_startup/comment_9_b60928e54a5b620899cf29820b9b8e70._comment
new file mode 100644
index 000000000..68ab46be1
--- /dev/null
+++ b/doc/bugs/Android_app_permission_denial_on_startup/comment_9_b60928e54a5b620899cf29820b9b8e70._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmSbJHbvlxbCjtPXk_Io3qP3MFqJr3pUgQ"
+ nickname="Christopher"
+ subject="New permission type"
+ date="2013-05-09T22:01:38Z"
+ content="""
+I observe that I am encountering the same on my Galaxy Nexus running CM10.1; I see indication that the \"INTERACT_ACROSS_USERS_FULL\" is a new permission in Android 4.2 that relates to the use of multiple users, which is one of the new features of 4.2.
+
+It's possible that there are bugs here... See: https://code.google.com/p/android/issues/detail?id=39801
+"""]]
diff --git a/doc/bugs/Android_daily_build_missing_webapp.mdwn b/doc/bugs/Android_daily_build_missing_webapp.mdwn
new file mode 100644
index 000000000..682186b73
--- /dev/null
+++ b/doc/bugs/Android_daily_build_missing_webapp.mdwn
@@ -0,0 +1,23 @@
+### Please describe the problem.
+
+The daily Android build is missing the webapp, raising a bug in case this is unexpected.
+
+### What steps will reproduce the problem?
+
+Down the daily APK, it is 9MB.
+
+### What version of git-annex are you using? On what operating system?
+
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
+
+> Probably several of them were. I've fixed the cabal file, re-running
+> android build now. [[done]] --[[Joey]]
diff --git a/doc/bugs/Annex_thinks_file_exists_afer_being_dropped.mdwn b/doc/bugs/Annex_thinks_file_exists_afer_being_dropped.mdwn
new file mode 100644
index 000000000..48be21cee
--- /dev/null
+++ b/doc/bugs/Annex_thinks_file_exists_afer_being_dropped.mdwn
@@ -0,0 +1,27 @@
+#### What steps will reproduce the problem?
+
+I've posted some code here:
+ https://gist.github.com/4552036
+
+
+#### What is the expected output? What do you see instead?
+
+I think I've found three bugs. If they aren't bugs then there is a usage issue that could do with some documentation improvements.
+
+Problem 1 - With 3 local annexes git-annex doesn't seem to search properly for them (See code)
+
+Problem 2 - Even after a sync an annex thinks another (local) annex has a file, even after it has been dropped (See code)
+
+SCARY bug - `whereis` seems to think that a locally dropped file still exists (See code)
+
+
+#### What version of git-annex are you using? On what operating system?
+
+git-annex version: 3.20130114
+
+OS: OSX 10.6.8
+
+
+#### Please provide any additional information below.
+
+> [[done]]; see comments --[[Joey]]
diff --git a/doc/bugs/Annex_thinks_file_exists_afer_being_dropped/comment_1_1d100441fd1ef529eb854b350fece9ee._comment b/doc/bugs/Annex_thinks_file_exists_afer_being_dropped/comment_1_1d100441fd1ef529eb854b350fece9ee._comment
new file mode 100644
index 000000000..7ddc9d2dd
--- /dev/null
+++ b/doc/bugs/Annex_thinks_file_exists_afer_being_dropped/comment_1_1d100441fd1ef529eb854b350fece9ee._comment
@@ -0,0 +1,29 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.238"
+ subject="comment 1"
+ date="2013-01-17T00:46:27Z"
+ content="""
+* Problem 1 - With 3 local annexes git-annex doesn't seem to search properly for them (See code)
+
+While test1 thinks test2 and test3 have the file, they don't; it was just dropped from them. So the check that the other repos have the file is done correctly here, and it correctly refuses to drop it. The message is confusing in that it suggests the repositories are not available.
+
+* Problem 2 - Even after a sync an annex thinks another (local) annex has a file, even after it has been dropped (See code)
+
+I have not fully analized this, but it does not have anything to do with direct mode, it's a location log bookeeping problem.
+
+The merge where this happens looks like this:
+
+<pre>
+ - 1358382328.617882s 0 620af8a6-603c-11e2-b332-f3ecf1856be4 (test2)
+ + 1358382324.420048s 1 620af8a6-603c-11e2-b332-f3ecf1856be4 (test2)
+ +1358382324.572356s 1 622cf3b6-603c-11e2-bb55-4fe0f1a02dee (test3)
+++ 1358382328.472266s 0 622cf3b6-603c-11e2-bb55-4fe0f1a02dee (test3)
+</pre>
+
+The first 2 lines are the problem, and in this merge, a newer line is deleted leaving behind an older, now incorrect line. Union merge should not be deleting lines at all, so this appears to be a bug in the union merge code.
+
+* SCARY bug - whereis seems to think that a locally dropped file still exists (See code)
+
+This is a consequence of problem 2; the bad location data gets synced back to test2. Of course fsck will fix this, and the location log's is not relied on when dropping files, so this cannot result in data loss at least.
+"""]]
diff --git a/doc/bugs/Annex_thinks_file_exists_afer_being_dropped/comment_2_166c459c2b27859cf457e17da685fe75._comment b/doc/bugs/Annex_thinks_file_exists_afer_being_dropped/comment_2_166c459c2b27859cf457e17da685fe75._comment
new file mode 100644
index 000000000..661386d8e
--- /dev/null
+++ b/doc/bugs/Annex_thinks_file_exists_afer_being_dropped/comment_2_166c459c2b27859cf457e17da685fe75._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.238"
+ subject="comment 2"
+ date="2013-01-17T01:35:44Z"
+ content="""
+All right, the bug here involves differing changes to location log info for the same file being synced from two repositories and merged. Which probably explains why this bug was not noticed before.
+
+The union merge code generates a stream of data to feed into a single call to update-index. For each ref being merged, it calculates a union merge between that ref and the index. However, this means that the merge data for test2 is fed into update-index, and this is followed by the merge data for test3, which overwrites the previous merge data, causing the unique line from it to be lost.
+
+A fix, although perhaps not the most efficient way, is to run update-index once for each ref to merge, so that each merge builds on the one before. I've put this in place and can confirm problems #2 and #3 are fixed. Leaving open for the minor wording problem #1.
+
+Thanks for an excellent test case for this most unusual bug! (Which I should haskell-ize and add to the regression test suite, when I have time..)
+"""]]
diff --git a/doc/bugs/Annex_thinks_file_exists_afer_being_dropped/comment_3_9d985b6e7973bfaaf8b4f5349d8c13ee._comment b/doc/bugs/Annex_thinks_file_exists_afer_being_dropped/comment_3_9d985b6e7973bfaaf8b4f5349d8c13ee._comment
new file mode 100644
index 000000000..7301dda92
--- /dev/null
+++ b/doc/bugs/Annex_thinks_file_exists_afer_being_dropped/comment_3_9d985b6e7973bfaaf8b4f5349d8c13ee._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.238"
+ subject="comment 3"
+ date="2013-01-17T01:45:59Z"
+ content="""
+Fixed problem #1; it now no longer says to make available repositories where it has confirmed the file is not present.
+"""]]
diff --git a/doc/bugs/Annex_thinks_file_exists_afer_being_dropped/comment_4_3e084cff454b95c7170c0225a53f0c30._comment b/doc/bugs/Annex_thinks_file_exists_afer_being_dropped/comment_4_3e084cff454b95c7170c0225a53f0c30._comment
new file mode 100644
index 000000000..a4fc5813a
--- /dev/null
+++ b/doc/bugs/Annex_thinks_file_exists_afer_being_dropped/comment_4_3e084cff454b95c7170c0225a53f0c30._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://a-or-b.myopenid.com/"
+ ip="203.45.2.230"
+ subject="comment 4"
+ date="2013-01-17T01:57:06Z"
+ content="""
+No problem. Glad to be of assistance.
+
+This was actually a bug that I ran into whilst testing direct mode. Quantifying the commands needed to reproduce was a bit of a challenge. :-)
+
+"""]]
diff --git a/doc/bugs/Assistant_does_not_actually_check_newly_annex-added_files_into_git_until_daily_sanity_check.mdwn b/doc/bugs/Assistant_does_not_actually_check_newly_annex-added_files_into_git_until_daily_sanity_check.mdwn
new file mode 100644
index 000000000..d4f58b44d
--- /dev/null
+++ b/doc/bugs/Assistant_does_not_actually_check_newly_annex-added_files_into_git_until_daily_sanity_check.mdwn
@@ -0,0 +1,106 @@
+What steps will reproduce the problem?
+
+Move any file into a git annex repository using "mv". The symlink is created, content is stored in .git/annex, content may even be moved to other repos, but the symlink is not checked into git. A day later, the daily sanity check will add and check-in the link.
+
+What is the expected output? What do you see instead?
+
+After adding content to git-annex, "git status" should show a clean repo with everything checked in.
+
+Instead it looks like this:
+
+ ~$ touch foobar
+ ~$ rm foobar
+ ~$ echo "foo" > bar
+ ~$ mv bar annex/Incoming/
+ ~$ cd annex
+ annex$ git status
+ # On branch master
+ # Untracked files:
+ # (use "git add <file>..." to include in what will be committed)
+ #
+ # Incoming/bar
+ nothing added to commit but untracked files present (use "git add" to track)
+ annex$
+
+
+
+I ran the assistant with the --debug option and this is what was in the daemon.log when this happened:
+
+ [2013-03-13 09:23:36 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","ls-files","--others","--exclude-standard","-z","--","/Users/ed/annex/Incoming/bar"]
+ [2013-03-13 09:23:37 EDT] read: lsof ["-F0can","+d","/Users/ed/annex/.git/annex/tmp/"]
+ [2013-03-13 09:23:39 EDT] Committer: Adding bar
+
+
+ (Recording state in git...)
+ (Recording state in git...)
+ (Recording state in git...)
+ (Recording state in git...)
+ add Incoming/bar (checksum...) recv: resource vanished (Connection reset by peer)
+ [2013-03-13 09:23:39 EDT] 127.0.0.1 GET /sidebar/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:19.0) Gecko/20100101 Firefox/19.0
+ [2013-03-13 09:23:40 EDT] 127.0.0.1 GET /sidebar/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:19.0) Gecko/20100101 Firefox/19.0
+
+
+What version of git-annex are you using? On what operating system?
+
+A fresh compile from last night (git hash fe2df85f0db08227556897db3b076ef321e4303a). OS X Lion.
+
+
+Please provide any additional information below.
+
+I get the same effect when doing this with a newly created "testannex" repo with nothing in it but a newly created file -- I just haven't left the assistant running in a test repo all day to confirm that the file doesn't get checked in till the next daily sanity check.
+
+Here it is on a newly-created, empty repo:
+
+ testannex$ git init
+ Initialized empty Git repository in /Users/ed/testannex/.git/
+ testannex$ git annex init
+ init ok
+ (Recording state in git...)
+ testannex$ git annex assistant --debug
+ [2013-03-13 09:31:10 EDT] read: git ["--git-dir=/Users/ed/testannex/.git","--work-tree=/Users/ed/testannex","show-ref","git-annex"]
+ [2013-03-13 09:31:10 EDT] read: git ["--git-dir=/Users/ed/testannex/.git","--work-tree=/Users/ed/testannex","show-ref","--hash","refs/heads/git-annex"]
+ [2013-03-13 09:31:10 EDT] read: git ["--git-dir=/Users/ed/testannex/.git","--work-tree=/Users/ed/testannex","log","refs/heads/git-annex..4aeceaff629c83c35c1244da9eeeac4b7c228fef","--oneline","-n1"]
+ [2013-03-13 09:31:10 EDT] chat: git ["--git-dir=/Users/ed/testannex/.git","--work-tree=/Users/ed/testannex","cat-file","--batch"]
+ testannex$ cd
+ ~$ echo "foo" > bar
+ ~$ mv bar testannex/
+ ~$ cd testannex/
+ testannex$ git status
+ # On branch master
+ #
+ # Initial commit
+ #
+ # Untracked files:
+ # (use "git add <file>..." to include in what will be committed)
+ #
+ # bar
+ nothing added to commit but untracked files present (use "git add" to track)
+
+
+ (meanwhile.....)
+
+ ~$ cd testannex/.git/annex/
+ annex$ tail -f daemon.log
+ [2013-03-13 09:31:10 EDT] TransferWatcher: watching for transfers
+ [2013-03-13 09:31:10 EDT] read: git ["--git-dir=/Users/ed/testannex/.git","--work-tree=/Users/ed/testannex","show-ref","git-annex"]
+ [2013-03-13 09:31:10 EDT] read: git ["--git-dir=/Users/ed/testannex/.git","--work-tree=/Users/ed/testannex","show-ref","--hash","refs/heads/git-annex"]
+ [2013-03-13 09:31:10 EDT] read: git ["--git-dir=/Users/ed/testannex/.git","--work-tree=/Users/ed/testannex","log","refs/heads/git-annex..4aeceaff629c83c35c1244da9eeeac4b7c228fef","--oneline","-n1"]
+ [2013-03-13 09:31:10 EDT] Merger: watching /Users/ed/testannex/.git/refs
+ [2013-03-13 09:31:10 EDT] read: git ["--git-dir=/Users/ed/testannex/.git","--work-tree=/Users/ed/testannex","ls-tree","-z","--","refs/heads/git-annex","uuid.log","remote.log","trust.log","group.log","preferred-content.log"]
+ [2013-03-13 09:31:10 EDT] read: git ["--git-dir=/Users/ed/testannex/.git","--work-tree=/Users/ed/testannex","ls-tree","-z","--","refs/heads/git-annex","uuid.log","remote.log","trust.log","group.log","preferred-content.log"]
+ (scanning...) [2013-03-13 09:31:10 EDT] Watcher: Performing startup scan
+ [2013-03-13 09:31:10 EDT] read: git ["--git-dir=/Users/ed/testannex/.git","--work-tree=/Users/ed/testannex","ls-files","--deleted","-z","--","/Users/ed/testannex"]
+ (started...) [2013-03-13 09:31:10 EDT] Watcher: watching .
+ [2013-03-13 09:31:48 EDT] read: git ["--git-dir=/Users/ed/testannex/.git","--work-tree=/Users/ed/testannex","ls-files","--others","--exclude-standard","-z","--","/Users/ed/testannex/bar"]
+ [2013-03-13 09:31:49 EDT] read: lsof ["-F0can","+d","/Users/ed/testannex/.git/annex/tmp/"]
+ [2013-03-13 09:31:51 EDT] Committer: Adding bar
+
+ add bar [2013-03-13 09:31:51 EDT] chat: git ["--git-dir=/Users/ed/testannex/.git","--work-tree=/Users/ed/testannex","check-attr","-z","--stdin","annex.backend","annex.numcopies","--"]
+ (checksum...) [2013-03-13 09:31:51 EDT] chat: git ["--git-dir=/Users/ed/testannex/.git","--work-tree=/Users/ed/testannex","cat-file","--batch"]
+
+> This bug affected OSX when indirect mode repositories were used.
+> Direct mode repositories were ok.
+> I expected to get an event from fsevents when I made the symlink,
+> and this event is not arriving (or at least not always). Switched
+> the code to use the same method for fsevents as for kqueue and that fixed
+> it. [[done]] --[[Joey]]
diff --git a/doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default.mdwn b/doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default.mdwn
new file mode 100644
index 000000000..c3810350b
--- /dev/null
+++ b/doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default.mdwn
@@ -0,0 +1,16 @@
+### Please describe the problem.
+
+I'm trying to use the assistant to replicate the basic dropbox functionality of having a synced folder between two machines. Instead of actually syncing file contents by default the assistant just creates broken symlinks.
+
+### What steps will reproduce the problem?
+
+I've setup two repositories with each other as ssh remotes and ran the assistant on each after setting them in direct mode. I can create files on each of the repositories and have them show up on the other but all that shows up is a broken link. Actual contents don't get transferred. If I do a "git annex get" I can get the contents just fine. I tried setting annex.numcopies to 2 and that didn't work either.
+
+What I'm missing here is some setting to tell the assistant "sync the contents of every new file". What it's doing instead is unacceptable. If I have the file in both repositories and change it in one, the other repository gets it's previous version of the file replaced by a broken symlink. From my point of view for the assistant to be a dropbox replacement it should never, under any circumstances, create a broken symlink in the sync folder. I had understood that that's what direct mode was, but it's not behaving that way right now at least.
+
+### What version of git-annex are you using? On what operating system?
+
+My basic setup for testing is two Ubuntu 12.04 LTS machines running git-annex 4.20130501
+
+> [[done]], broken ~/.config/git-annex/program file, which is now detected
+> and worked around. --[[Joey]]
diff --git a/doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default/comment_1_8577fdaa4d49e6241c4372b159694c9c._comment b/doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default/comment_1_8577fdaa4d49e6241c4372b159694c9c._comment
new file mode 100644
index 000000000..5e300d557
--- /dev/null
+++ b/doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default/comment_1_8577fdaa4d49e6241c4372b159694c9c._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 1"
+ date="2013-05-20T13:57:59Z"
+ content="""
+just fyi -- *broken* symlinks represent content which git-annex knows about, but is not present on that machine. They are there even in direct mode. In indirect mode, content which is present is represented by non-broken symlinks. In direct mode, content which is present is actual files.
+
+I'm not sure why your setup doesn't work. It seems as if it would, from your description of it.
+
+Your machines are successfully syncing their knowledge about what files exist (which is stored in git), but not actually transferring the content of those files. That's why symlinks are showing up (to show that those files exist) but not the content. I would think numcopies=2 would force that to happen.
+"""]]
diff --git a/doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default/comment_2_027521e48283c68b39315bb8213f6e45._comment b/doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default/comment_2_027521e48283c68b39315bb8213f6e45._comment
new file mode 100644
index 000000000..9d5e07eb7
--- /dev/null
+++ b/doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default/comment_2_027521e48283c68b39315bb8213f6e45._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkx5V3MTbzCXS3J7Mn9FEq8M9bPPYMkAHY"
+ nickname="Pedro"
+ subject="comment 2"
+ date="2013-05-20T14:37:37Z"
+ content="""
+I know what the broken symlinks are I just don't think they should ever happen in a direct mode repository. They're an artifact of the traditional way git-annex was run but the assistant in direct mode should never use them. Right now if one of the repositories changes a file and another finds out that has happened but hasn't synced the content yet you lose access to your file. That's not acceptable in a file sync utility. Dropbox certainly doesn't do that. What git-annex should do in this case is use the knowledge of the updated file to run a sync but before it can complete it maintain the file at its previous version. By definition direct mode should not be deleting my files and replacing them with symlinks, it should only replace existing files with newer versions of those same files.
+
+I also don't know why numcopies didn't work but it shouldn't be needed at all. What I want to do is to tell the assistant \"sync the contents of every file into this repository as soon as you can from whatever remote you happen to be able to copy it from\". I couldn't find a setting that would do that though.
+"""]]
diff --git a/doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default/comment_3_fd8f6938596aace60b04fb35c4069e37._comment b/doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default/comment_3_fd8f6938596aace60b04fb35c4069e37._comment
new file mode 100644
index 000000000..65bccfb76
--- /dev/null
+++ b/doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default/comment_3_fd8f6938596aace60b04fb35c4069e37._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-05-20T16:06:50Z"
+ content="""
+If git-annex did not update its working tree until all files referenced in it had been downloaded, then it would be possible, if you have a lot of files, for changes to take a long time, or forever, to show up. I prefer the current behavior.
+
+In any case, is this bug report about the mechanics of how the assistant choses to update its working tree, or is it about your configuration of two repositories that are not syncing with one-another? Conflating two entirely separate issues in one bug report is a good way to add so much noise to it that nothing gets done.
+"""]]
diff --git a/doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default/comment_4_ca908021ab5a2a50fd0d4a7e8d12498f._comment b/doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default/comment_4_ca908021ab5a2a50fd0d4a7e8d12498f._comment
new file mode 100644
index 000000000..035606957
--- /dev/null
+++ b/doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default/comment_4_ca908021ab5a2a50fd0d4a7e8d12498f._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 4"
+ date="2013-05-20T16:08:14Z"
+ content="""
+The broken symlinks are important to me, because they represent content in archive directories which is intentionally not present, and they allow me to prompt git annex to retrieve that content by dragging and dropping them out of the archive subdirectory. I'm not sure what the issue is with transferring content for you though.
+
+"""]]
diff --git a/doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default/comment_5_73532556cfc354ad5f37a3f3a048fb32._comment b/doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default/comment_5_73532556cfc354ad5f37a3f3a048fb32._comment
new file mode 100644
index 000000000..008ed98cb
--- /dev/null
+++ b/doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default/comment_5_73532556cfc354ad5f37a3f3a048fb32._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 5"
+ date="2013-05-20T16:09:47Z"
+ content="""
+\"What I want to do is to tell the assistant \"sync the contents of every file into this repository as soon as you can from whatever remote you happen to be able to copy it from\". I couldn't find a setting that would do that though.\"
+
+The reason you cannot find a setting that does this, is because that is the default behavior of the assistent, when correctly configured.
+
+Since it syncs files for everyone else, I conclude there must be an error in your configuration. You need to descibe it in detail and/or enable debugging and paste a debug log.
+"""]]
diff --git a/doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default/comment_6_ced397b9e6119a0798a282ee07e885df._comment b/doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default/comment_6_ced397b9e6119a0798a282ee07e885df._comment
new file mode 100644
index 000000000..61d5f9bd2
--- /dev/null
+++ b/doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default/comment_6_ced397b9e6119a0798a282ee07e885df._comment
@@ -0,0 +1,61 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 6"
+ date="2013-05-20T16:22:18Z"
+ content="""
+Here is a simple example of setting up 2 repositories in the way the bug reporter describes here and on IRC. As you can see, the assistant syncs file content without any configuration:
+
+[[!format sh \"\"\"
+joey@gnu:~/tmp/test>mkdir 1 2
+joey@gnu:~/tmp/test>cd 1; git init; git-annex init; git annex direct; echo \"file added to 1\" > file_from_1; cd ..
+Initialized empty Git repository in /home/joey/tmp/test/1/.git/
+init ok
+(Recording state in git...)
+commit
+# On branch master
+#
+# Initial commit
+#
+nothing to commit (create/copy files and use \"git add\" to track)
+ok
+direct ok
+joey@gnu:~/tmp/test>cd 2; git init; git-annex init; git annex direct; echo \"file added to 2\" > file_from_2; cd ..
+Initialized empty Git repository in /home/joey/tmp/test/2/.git/
+init ok
+(Recording state in git...)
+commit
+# On branch master
+#
+# Initial commit
+#
+nothing to commit (create/copy files and use \"git add\" to track)
+ok
+direct ok
+joey@gnu:~/tmp/test>cd 1; git remote add 2 ssh://localhost/~joey/tmp/test/2; git annex assistant; cd ..
+joey@gnu:~/tmp/test>cd 2; git remote add 1 ssh://localhost/~joey/tmp/test/1; git annex assistant; cd ..
+(merging synced/git-annex into git-annex...)
+(Recording state in git...)
+joey@gnu:~/tmp/test>cd 1
+joey@gnu:~/tmp/test/1>ls
+file_from_1
+joey@gnu:~/tmp/test/1>ls
+file_from_1 file_from_2
+joey@gnu:~/tmp/test/1>cat file_from_2
+file added to 2
+joey@gnu:~/tmp/test/1>cd ..
+joey@gnu:~/tmp/test>cd 2
+joey@gnu:~/tmp/test/2>cat file_from_1
+file added to 1
+joey@gnu:~/tmp/test/2>rm file_from_2
+joey@gnu:~/tmp/test/2>cd ..
+joey@gnu:~/tmp/test>cd 1
+joey@gnu:~/tmp/test/1>ls
+file_from_1
+joey@gnu:~/tmp/test/1>date > newfile
+joey@gnu:~/tmp/test/1>cd ..
+joey@gnu:~/tmp/test>cd 2
+joey@gnu:~/tmp/test/2>cat newfile
+Mon May 20 12:20:24 JEST 2013
+\"\"\"]]
+"""]]
diff --git a/doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default/comment_7_8acb66850e5db8337cf3f2b2dd236ccc._comment b/doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default/comment_7_8acb66850e5db8337cf3f2b2dd236ccc._comment
new file mode 100644
index 000000000..8bd901688
--- /dev/null
+++ b/doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default/comment_7_8acb66850e5db8337cf3f2b2dd236ccc._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkx5V3MTbzCXS3J7Mn9FEq8M9bPPYMkAHY"
+ nickname="Pedro"
+ subject="comment 7"
+ date="2013-05-20T19:52:30Z"
+ content="""
+Your example is pretty much what I've done. I'll enable a debug log as soon as possible. By the away \"git annex assistant --foreground\" still logs to .git/annex/daemon.log instead of stdout/stderr, which I assume was not the intended behavior.
+
+This bug was indeed about the assistant not syncing, the comments about the broken symlinks were just in response to edheil's comment. I can post a separate bug report about this but the reason I don't think this should be default behavior is that it breaks several simple uses of git-annex. One simple example is using it to store your configs across machines (things like .bashrc). If at any point the git-annex can't sync a file (a network problem or ssh breakage or whatever) but becomes aware of a file change (for example through xmpp) you now have a broken login shell. In general it breaks the user expectations of having a \"folder that just happens to also sync\" for something where his files randomly get replaced with strange broken things for odd technical reasons.
+"""]]
diff --git a/doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default/comment_8_7eb530851ae6fa1a69813725c4e8fcec._comment b/doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default/comment_8_7eb530851ae6fa1a69813725c4e8fcec._comment
new file mode 100644
index 000000000..157923a1e
--- /dev/null
+++ b/doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default/comment_8_7eb530851ae6fa1a69813725c4e8fcec._comment
@@ -0,0 +1,59 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkx5V3MTbzCXS3J7Mn9FEq8M9bPPYMkAHY"
+ nickname="Pedro"
+ subject="comment 8"
+ date="2013-05-20T19:59:22Z"
+ content="""
+Here's the same example you posted being followed by me and showing the problem
+
+[[!format sh \"\"\"
+$mkdir 1 2
+$cd 1; git init; git-annex init; git annex direct; echo \"file added to 1\" > file_from_1; cd ..
+Initialized empty Git repository in /home/pedrocr/Hacks/test-git-annex/1/.git/
+init ok
+(Recording state in git...)
+commit
+# On branch master
+#
+# Initial commit
+#
+nothing to commit (create/copy files and use \"git add\" to track)
+ok
+direct ok
+$cd 2; git init; git-annex init; git annex direct; echo \"file added to 2\" > file_from_2; cd ..
+Initialized empty Git repository in /home/pedrocr/Hacks/test-git-annex/2/.git/
+init ok
+(Recording state in git...)
+commit
+# On branch master
+#
+# Initial commit
+#
+nothing to commit (create/copy files and use \"git add\" to track)
+ok
+direct ok
+$cd 1; git remote add 2 ssh://localhost/~pedrocr/Hacks/test-git-annex/2; git annex assistant; cd ..
+$cd 2; git remote add 1 ssh://localhost/~pedrocr/Hacks/test-git-annex/1; git annex assistant; cd ..
+(merging synced/git-annex into git-annex...)
+$cd 1
+$ls
+file_from_1 file_from_2
+$ls -la
+total 20
+drwxrwxr-x 3 pedrocr pedrocr 4096 May 20 20:57 .
+drwxrwxr-x 4 pedrocr pedrocr 4096 May 20 20:55 ..
+-rw-r--r-- 1 pedrocr pedrocr 16 May 20 20:56 file_from_1
+lrwxrwxrwx 1 pedrocr pedrocr 180 May 20 20:57 file_from_2 -> .git/annex/objects/1P/8w/SHA256E-s16--b651aaa274225b617cb4d3033047ac6aee29dd6f2465f94ec38dc6630b7d48c8/SHA256E-s16--b651aaa274225b617cb4d3033047ac6aee29dd6f2465f94ec38dc6630b7d48c8
+drwxrwxr-x 9 pedrocr pedrocr 4096 May 20 20:57 .git
+$cd ..
+$cd 2
+$ls -la
+total 20
+drwxrwxr-x 3 pedrocr pedrocr 4096 May 20 20:57 .
+drwxrwxr-x 4 pedrocr pedrocr 4096 May 20 20:55 ..
+lrwxrwxrwx 1 pedrocr pedrocr 180 May 20 20:57 file_from_1 -> .git/annex/objects/qQ/x9/SHA256E-s16--cca8b6c2db480aa680e12c48f471a351de69978c7665fac5b63d9a765f4c16f4/SHA256E-s16--cca8b6c2db480aa680e12c48f471a351de69978c7665fac5b63d9a765f4c16f4
+-rw-r--r-- 1 pedrocr pedrocr 16 May 20 20:56 file_from_2
+drwxrwxr-x 9 pedrocr pedrocr 4096 May 20 20:57 .git
+$
+\"\"\"]]
+"""]]
diff --git a/doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default/comment_9_c7d51a26e1febc3894d02546940d64e5._comment b/doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default/comment_9_c7d51a26e1febc3894d02546940d64e5._comment
new file mode 100644
index 000000000..2f5e2d43d
--- /dev/null
+++ b/doc/bugs/Assistant_doesn__39__t_actually_sync_file_contents_by_default/comment_9_c7d51a26e1febc3894d02546940d64e5._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 9"
+ date="2013-05-20T21:43:04Z"
+ content="""
+Based on the log, it appears that you have a `~/.config/git-annex/program` file that contains \"/home/pedrocr/software/git-annex/git-annex.linux/git-annex\", but that is either not where git-annex is actually installed, or running that program
+(which git-annex does when it needs to transfer a file contents) fails.
+
+I am able to exactly replicate the failure to transfer file content, and the log output, when I set things up in that way.
+
+This would be consistent with you, for example, having previously installed git-annex from the standalone tarball, used it at least once, and then deleted that installation, and installed it from, say, a Ubuntu repository.
+
+I've put in a fix so if the programfile is wrong, git-annex just tries PATH.
+
+(BTW, I do not advocate storing config files in the git annex. Small files that you want to have fully versioned are best stored in git. The git-annex assistant can still be used for syncing files that are checked into git in the regular way. See [[tips/replacing_Sparkleshare_or_dvcs-autosync_with_the_assistant]].)
+
+(git annex assistant --foreground intentionally logs to the log file, because otherwise the \"view logs\" page in the webapp can't show any logs.)
+"""]]
diff --git a/doc/bugs/Assistant_dropping_files_it_has_just_transferred_elsewhere_again.mdwn b/doc/bugs/Assistant_dropping_files_it_has_just_transferred_elsewhere_again.mdwn
new file mode 100644
index 000000000..cb463ba07
--- /dev/null
+++ b/doc/bugs/Assistant_dropping_files_it_has_just_transferred_elsewhere_again.mdwn
@@ -0,0 +1,26 @@
+Setup:
+
+* fresh install of Debian Wheezy on machines A & B, git-annex 4.20130227 pulled in from unstable
+* clone repository onto A & B and pair them (manual SSH key setup), and plug USB backup drive, U, into A
+* U has repository group `backup` and preferred content string `standard`
+* A & B have repository group `client` and preferred content string `present or include=subdir1/* or ...`
+
+Steps:
+
+* Add a new file to B
+* On B, `git annex copy -t A newfile`
+
+Expected:
+
+* File arrives at B and is copied to U by B's assistant
+* File remains on B
+
+Actual:
+
+* File arrives on B and is copied to U
+* File is dropped from B
+
+Seems like a resurfacing of [[forum/assistant_overzealously_moving_stuff_to_other_repos]]? Thanks.
+
+> 4.20130227 used a regex library that was broken, at least for certian
+> filenames. I suspect that's what'd going on here. [[done]] --[[Joey]]
diff --git a/doc/bugs/Assistant_dropping_from_backup_repo.mdwn b/doc/bugs/Assistant_dropping_from_backup_repo.mdwn
new file mode 100644
index 000000000..0e0fd5909
--- /dev/null
+++ b/doc/bugs/Assistant_dropping_from_backup_repo.mdwn
@@ -0,0 +1,28 @@
+Setup:
+
+* fresh install of Debian Wheezy with git-annex 4.20130227 pulled in from unstable
+
+Steps:
+
+* clone existing repository and activate assistant
+* Have USB drive, U, with repository group `backup` and preferred content string `standard`
+
+Expected:
+
+* Assistant never ever tries to drop anything from U
+
+Actual:
+
+* Assistant immediately tries to drop files from U; fortunately I didn't have the USB drive plugged in
+* Changing the preferred content string of U to `present or include=*` stops the dropping, but this was never required before
+
+Additional information:
+
+* The files that the Assistant started trying to drop were, I believe, the first (alphabetically) files in my repository to contain non-ascii characters in their file names (some French accented letters)
+
+Thanks.
+
+> The non-ascii characters are the giveaway: For 1 version, git-annex used
+> a regex library that failed to ever match non-ascii characters. So it
+> thought backup repos, which match "*" with a regex, wanted no such files.
+> This is [[fixed|done]]. --[[Joey]]
diff --git a/doc/bugs/Assistant_dropping_from_backup_repo/comment_1_c13d86fb2541676ee4ca1446b99e0e68._comment b/doc/bugs/Assistant_dropping_from_backup_repo/comment_1_c13d86fb2541676ee4ca1446b99e0e68._comment
new file mode 100644
index 000000000..5e69655e0
--- /dev/null
+++ b/doc/bugs/Assistant_dropping_from_backup_repo/comment_1_c13d86fb2541676ee4ca1446b99e0e68._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 1"
+ date="2013-03-12T14:25:16Z"
+ content="""
+This sounds very similar to [[http://git-annex.branchable.com/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content/]]; my client was pulling in content prior to dropping it from a \"backup\" repo on a USB drive.
+"""]]
diff --git a/doc/bugs/Assistant_enters_eternal_loop_and_eats_up_all_of_RAM_after_X_restart.mdwn b/doc/bugs/Assistant_enters_eternal_loop_and_eats_up_all_of_RAM_after_X_restart.mdwn
new file mode 100644
index 000000000..d3f539431
--- /dev/null
+++ b/doc/bugs/Assistant_enters_eternal_loop_and_eats_up_all_of_RAM_after_X_restart.mdwn
@@ -0,0 +1,24 @@
+*What steps will reproduce the problem?*
+
+Log in to X, have the DE start the assistant with --autostart. Then kill X with ctrl+alt+backspace and log back in once X comes back up.
+
+*What is the expected output? What do you see instead?*
+
+It enters an eternal loop, quickly using up all of the available RAM as well as 100% of CPU. Initially noticed because the computer became extremely sluggish, at which point the assistant was using up over 7G (of the available 8G) of RAM, and all of the available power on one of the CPU cores.
+
+Killing the assistant and then starting it again results in it working normally again.
+
+*What version of git-annex are you using? On what operating system?*
+
+git-annex version: 3.20121010 on Debian Sid (under GNOME3/Gnome-Shell in case that's relevant).
+I've also seen it happen on another computer in similar circumstances. That one on Debian Testing, with git-annex from sid (so same git-annex version). In this case X was restarted while running with /etc/init.d/gdm3 restart, and again the issue appeared after logging out and then back in.
+
+*Please provide any additional information below.*
+
+Given that the assistant isn't really using X directly, I suppose this could be due to losing its connection to the gpg and ssh agents as a side-effect of X being shut down. I'm not sure if it happens immediately after X being killed, or once I log back in again.
+
+> Reproduced. Root caused to a bug in the haskell dbus library, which I can
+> reproduce with 2 line test case; basically anything using connectSession
+> will do this when the dbus session goes away. Sent test case and
+> profiling data to library author to get it fixed, and have disabled
+> dbus in git-annex in the meantime. [[done]] --[[Joey]]
diff --git a/doc/bugs/Assistant_has_created_155_semitrusted_repositories.mdwn b/doc/bugs/Assistant_has_created_155_semitrusted_repositories.mdwn
new file mode 100644
index 000000000..b1caf530d
--- /dev/null
+++ b/doc/bugs/Assistant_has_created_155_semitrusted_repositories.mdwn
@@ -0,0 +1,191 @@
+### Please describe the problem.
+git annex status reports 160 semitrusted repositories. Four of them are the ones I created (only via webapp, I think I never edited any git-annex config file). One is 00000000-0000-0000-0000-000000000001 -- web
+ and although I do not know what it is, it is not something new. The remaining 155 appeared spontaneously after several Gb of data (mostly many small files) were added to an Annex (in an 'archive' directory) operated in direct mode by the assistant.
+
+
+
+### What steps will reproduce the problem?
+Add several Gb of files was enough to trigger this problem, but I did not try to reproduce it. It happened the day I installed the 4.20131106~bpo70+1 version.
+
+### What version of git-annex are you using? On what operating system?
+
+4.20131106~bpo70+1 on debian squeeze (7.2), with git 1.8.4.rc3.
+
+
+### Please provide any additional information below.
+May be related or not: at some point the webapp displayed two warning boxes. One of them held a message that I did not wirte down and proposed to "Restart the thread". This apparently worked since the box disappeared. The other warning box indicated "NetWatcherFallback crashed: unknown response from git cat-file" and proposed to restart the thread. Trying to "restart the thread" via the provided button just did not trigger any response of the webapp which seemed dead at that point.
+
+In spite of the git annex status shown below, the webapp still shows only the expected four repositories.
+
+Output of git annex status (hostname and xmpp account name were edited away):
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+repository mode: direct
+trusted repositories:
+0
+semitrusted repositories: 160
+ 00000000-0000-0000-0000-000000000001 -- web
+ 0ab193eb-0c76-4559-a93c-2e30ed8630a8 -- someMachineIown_datadir (archive)
+ 1384784127.91222s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384784164.437824s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384784176.944372s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384784179.254498s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384785147.558938s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384785147.717223s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384785159.041203s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384785159.199504s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384785185.79485s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384785187.318128s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384785215.236504s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384785215.389096s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384785313.539843s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384785313.701305s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384785315.596206s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384785344.184461s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384785348.192805s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384785402.70316s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384785406.524044s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384785446.074236s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384873605.313126s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384873697.029999s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384873761.687234s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384873774.608376s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384926279.456728s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384926368.736s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384926454.99433s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384926494.152645s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384926504.438232s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384934790.89717s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384934848.757067s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384934899.087168s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384934908.238587s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384948772.14552s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384948805.441196s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384948813.397132s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384948921.45481s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384948924.855852s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384949073.988946s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384949082.298976s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384949399.608138s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384949581.12213s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384949583.9923s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384949700.22807s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384949765.484768s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384955202.85962s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384955230.953995s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384955402.534938s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384955457.1885s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384955524.603709s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384955611.891061s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384955677.84592s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384955689.293082s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384955894.057476s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384955910.723021s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384955914.732132s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384955968.717875s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384955969.634658s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384956004.284925s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384956029.567195s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384956188.628995s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384956379.844701s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384956381.613833s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384956387.923418s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384956395.418701s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384956408.792928s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384956504.019733s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384956519.578085s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384956524.419783s -- 1 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384965891.562742s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384965891.815119s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384965903.355602s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384965905.276128s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384965978.806653s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384965979.393089s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384966097.495566s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384966097.704474s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384966154.97658s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384966156.967406s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384966233.310488s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384966233.522324s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384966241.284523s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384966241.475381s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384966301.688497s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384966303.427685s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384966392.875983s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384966393.38718s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384966404.708568s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384966406.441164s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384966553.557387s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384966555.752786s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384966653.725847s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384966654.23288s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384966695.201885s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384966695.689398s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384966784.556877s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384966786.574886s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384966791.446852s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384966793.218318s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384966884.335685s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384966886.147083s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384967054.857465s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384967055.158871s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384967190.980027s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384967193.176584s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384967328.93796s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384967330.428095s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384967526.127311s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384967526.588491s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384967627.132549s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384967627.685201s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384967686.283694s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384967686.728086s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384967768.270887s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384967768.58402s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384967769.245615s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384967771.122238s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384967813.8197s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384967814.168477s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384967915.243469s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384967917.020051s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384968031.757775s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384968032.190452s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384968035.733635s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384968036.03299s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384968144.555556s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384968144.714535s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384968150.090148s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384968150.820567s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384968304.393177s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384968304.613624s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384968604.499519s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384968604.813256s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384968702.566939s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384968704.427767s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384968725.375289s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384968725.939271s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384968798.402904s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384968798.659754s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384969055.285004s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384969055.715448s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384969159.885115s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384969162.382266s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384969184.633052s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384969185.413769s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384969374.791849s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384969377.497842s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384969475.469111s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384969489.697737s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384969492.087023s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384969492.58214s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384969784.725195s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384969786.49773s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 1384969814.984624s -- 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+ 1384969815.397676s -- 0 391b0557-dc68-4e40-b6d0-da3033588753
+ 391b0557-dc68-4e40-b6d0-da3033588753 -- here (client)
+ 668ef9d8-68c6-484e-89e5-06634d590a11 -- rsync.net_datadir_annex (transfer)
+ b0d3c000-0ac9-4a05-aef4-47f826d5c759 -- user.name (client)
+
+
+# End of transcript or log.
+"""]]
diff --git a/doc/bugs/Assistant_has_created_155_semitrusted_repositories/comment_1_169b24b34cce3f5c8446c2150beb6827._comment b/doc/bugs/Assistant_has_created_155_semitrusted_repositories/comment_1_169b24b34cce3f5c8446c2150beb6827._comment
new file mode 100644
index 000000000..99bb737e4
--- /dev/null
+++ b/doc/bugs/Assistant_has_created_155_semitrusted_repositories/comment_1_169b24b34cce3f5c8446c2150beb6827._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.64"
+ subject="comment 1"
+ date="2013-11-22T16:54:53Z"
+ content="""
+Please post the output of `git show git-annex:uuid.log` run in the repository.
+"""]]
diff --git a/doc/bugs/Assistant_has_created_155_semitrusted_repositories/comment_2_6acd6f38297772a07d8d5fb999bd2eaa._comment b/doc/bugs/Assistant_has_created_155_semitrusted_repositories/comment_2_6acd6f38297772a07d8d5fb999bd2eaa._comment
new file mode 100644
index 000000000..6db2a8fca
--- /dev/null
+++ b/doc/bugs/Assistant_has_created_155_semitrusted_repositories/comment_2_6acd6f38297772a07d8d5fb999bd2eaa._comment
@@ -0,0 +1,183 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnNqLKszWk9EoD4CDCqNXJRIklKFBCN1Ao"
+ nickname="maurizio"
+ subject="comment 2"
+ date="2013-11-22T17:23:19Z"
+ content="""
+Here it is (user name edited):
+
+[[!format sh \"\"\"
+
+
+0ab193eb-0c76-4559-a93c-2e30ed8630a8 archive timestamp=1384664310.014349s
+0ab193eb-0c76-4559-a93c-2e30ed8630a8 datadir on st08 timestamp=1384522780.868451s
+0ab193eb-0c76-4559-a93c-2e30ed8630a8 username@st08:~/datadir_annex timestamp=1384540428.076617s
+0ab193eb-0c76-4559-a93c-2e30ed8630a8 username@st08:~/datadir_annex timestamp=1384541057.852874s
+0ab193eb-0c76-4559-a93c-2e30ed8630a8 username@st08:~/datadir_annex timestamp=1384548609.891111s
+1384784127.91222s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384784164.437824s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384784176.944372s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384784179.254498s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384785147.558938s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384785147.717223s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384785159.041203s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384785159.199504s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384785185.79485s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384785187.318128s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384785215.236504s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384785215.389096s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384785313.539843s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384785313.701305s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384785315.596206s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384785344.184461s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384785348.192805s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384785402.70316s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384785406.524044s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384785446.074236s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384873605.313126s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384873697.029999s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384873761.687234s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384873774.608376s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384926279.456728s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384926368.736s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384926454.99433s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384926494.152645s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384926504.438232s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384934790.89717s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384934848.757067s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384934899.087168s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384934908.238587s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384948772.14552s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384948805.441196s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384948813.397132s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384948921.45481s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384948924.855852s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384949073.988946s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384949082.298976s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384949399.608138s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384949581.12213s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384949583.9923s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384949700.22807s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384949765.484768s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384955202.85962s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384955230.953995s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384955402.534938s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384955457.1885s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384955524.603709s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384955611.891061s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384955677.84592s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384955689.293082s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384955894.057476s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384955910.723021s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384955914.732132s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384955968.717875s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384955969.634658s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384956004.284925s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384956029.567195s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384956188.628995s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384956379.844701s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384956381.613833s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384956387.923418s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384956395.418701s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384956408.792928s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384956504.019733s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384956519.578085s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384956524.419783s 1 391b0557-dc68-4e40-b6d0-da3033588753
+1384965891.562742s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384965891.815119s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384965903.355602s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384965905.276128s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384965978.806653s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384965979.393089s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384966097.495566s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384966097.704474s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384966154.97658s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384966156.967406s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384966233.310488s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384966233.522324s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384966241.284523s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384966241.475381s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384966301.688497s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384966303.427685s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384966392.875983s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384966393.38718s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384966404.708568s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384966406.441164s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384966553.557387s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384966555.752786s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384966653.725847s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384966654.23288s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384966695.201885s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384966695.689398s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384966784.556877s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384966786.574886s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384966791.446852s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384966793.218318s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384966884.335685s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384966886.147083s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384967054.857465s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384967055.158871s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384967190.980027s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384967193.176584s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384967328.93796s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384967330.428095s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384967526.127311s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384967526.588491s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384967627.132549s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384967627.685201s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384967686.283694s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384967686.728086s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384967768.270887s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384967768.58402s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384967769.245615s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384967771.122238s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384967813.8197s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384967814.168477s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384967915.243469s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384967917.020051s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384968031.757775s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384968032.190452s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384968035.733635s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384968036.03299s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384968144.555556s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384968144.714535s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384968150.090148s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384968150.820567s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384968304.393177s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384968304.613624s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384968604.499519s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384968604.813256s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384968702.566939s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384968704.427767s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384968725.375289s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384968725.939271s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384968798.402904s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384968798.659754s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384969055.285004s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384969055.715448s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384969159.885115s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384969162.382266s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384969184.633052s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384969185.413769s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384969374.791849s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384969377.497842s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384969475.469111s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384969489.697737s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384969492.087023s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384969492.58214s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384969784.725195s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384969786.49773s 0 391b0557-dc68-4e40-b6d0-da3033588753
+1384969814.984624s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+1384969815.397676s 0 391b0557-dc68-4e40-b6d0-da3033588753
+391b0557-dc68-4e40-b6d0-da3033588753 client timestamp=1384528843.958836s
+391b0557-dc68-4e40-b6d0-da3033588753 username@big:~/datadir/Annex timestamp=1384521164.194035s
+668ef9d8-68c6-484e-89e5-06634d590a11 cipher=dFpZLzI4M3ZqVUl1S0p3ajl5N25vUUJyTFJXand5T2pNSGliOGo5WXBkN2NNY3ZqR3pvNmN0L2tLOFFKZW1aWDdHYUpCMGF1UGxybk9zeUdQOEpsMGZ5RzgwTVo1S2N6Rlo1eTVnNXFGYjJmblV0bzRjT3lTb29uZnY1QmpwMVVwYlZEOGVlaVlNR0R5dTcxNW50TFcrU1dSVi9PUXk5RkR6Zm14UFJzZEEvOHB5MTZXbkp5TW13Qm5UZ2FkUEsrUTdVZ2cxVWZnai9mbGRDYWVXYlpDVzFQL2tzanNTMU16aGxuVktETXpOY04vR1lSZnEzNVdJSkpDUEtMV1pPWXczVUVNTEJCNGtmUldiTVZoWWdlYm9NTTN4T2c1RXRvTXEzTytXazNaaFNKeUtsSlNmOUFXdTIrYnZLbkgvSFljSFVPOVlid0lCSHFlSDk0ZVQ3M3E4eHR6ckM1SjdIbjF0dmRSTGVibFFSdzUrdnVMM3p6UDl5R0JOUWNhL3Q4MXVVVGF0RjFjNGoyditZUGRzOUEraHZ5Z29hNkk0SDNiaVdYVnJFQmxTRTdTd3hOcjR3amJzRkd3d1VEUXFFZDhLNTBhWGF6bUY5LzZCZ2F5U1lOZEFDdXdSU2pMOU9qVGJWM29wVGNhNEt1Z09jU1JXRnQ0QUhoZXMxZlpvN1Qzc1o4WTQ3S1dUNVdJM3FjK05aQm5kUk10Nm8zSG1Ccys3cFdDUWVaUGJCbUhwK2ozdGw0cmxhK3FydkF5b3ZOM0xmbEJKdVBpTHNxd3JSUEpXdndkSENzQjlteHovZW9JOUtWUGJKNGxoRExSRVloNDUrNFZ6YmFZQVNZdkcxV2JxSzZTc2ZING90cmRBREZtTFRlRnc3OW92ZXBxQ0pPa21UMFFuR0ZJNG89Cg== encryption=shared name=rsync.net_datadir_annex rsyncurl=rsusername@git-annex-ch-s011.rsync.net-rsusername_datadir_annex.2F:datadir_annex/ type=rsync timestamp=1384948273.302009s
+668ef9d8-68c6-484e-89e5-06634d590a11 cipher=dFpZLzI4M3ZqVUl1S0p3ajl5N25vUUJyTFJXand5T2pNSGliOGo5WXBkN2NNY3ZqR3pvNmN0L2tLOFFKZW1aWDdHYUpCMGF1UGxybk9zeUdQOEpsMGZ5RzgwTVo1S2N6Rlo1eTVnNXFGYjJmblV0bzRjT3lTb29uZnY1QmpwMVVwYlZEOGVlaVlNR0R5dTcxNW50TFcrU1dSVi9PUXk5RkR6Zm14UFJzZEEvOHB5MTZXbkp5TW13Qm5UZ2FkUEsrUTdVZ2cxVWZnai9mbGRDYWVXYlpDVzFQL2tzanNTMU16aGxuVktETXpOY04vR1lSZnEzNVdJSkpDUEtMV1pPWXczVUVNTEJCNGtmUldiTVZoWWdlYm9NTTN4T2c1RXRvTXEzTytXazNaaFNKeUtsSlNmOUFXdTIrYnZLbkgvSFljSFVPOVlid0lCSHFlSDk0ZVQ3M3E4eHR6ckM1SjdIbjF0dmRSTGVibFFSdzUrdnVMM3p6UDl5R0JOUWNhL3Q4MXVVVGF0RjFjNGoyditZUGRzOUEraHZ5Z29hNkk0SDNiaVdYVnJFQmxTRTdTd3hOcjR3amJzRkd3d1VEUXFFZDhLNTBhWGF6bUY5LzZCZ2F5U1lOZEFDdXdSU2pMOU9qVGJWM29wVGNhNEt1Z09jU1JXRnQ0QUhoZXMxZlpvN1Qzc1o4WTQ3S1dUNVdJM3FjK05aQm5kUk10Nm8zSG1Ccys3cFdDUWVaUGJCbUhwK2ozdGw0cmxhK3FydkF5b3ZOM0xmbEJKdVBpTHNxd3JSUEpXdndkSENzQjlteHovZW9JOUtWUGJKNGxoRExSRVloNDUrNFZ6YmFZQVNZdkcxV2JxSzZTc2ZING90cmRBREZtTFRlRnc3OW92ZXBxQ0pPa21UMFFuR0ZJNG89Cg== encryption=shared name=rsync.net_datadir_annex rsyncurl=rsusername@git-annex-ch-s011.rsync.net-rsusername_datadir_annex:datadir_annex/ type=rsync timestamp=1384547300.727425s
+668ef9d8-68c6-484e-89e5-06634d590a11 rsync.net_datadir_annex timestamp=1384547300.725734s
+668ef9d8-68c6-484e-89e5-06634d590a11 rsync.net_datadir_annex timestamp=1384948273.280063s
+668ef9d8-68c6-484e-89e5-06634d590a11 transfer timestamp=1384948273.352386s
+b0d3c000-0ac9-4a05-aef4-47f826d5c759 client timestamp=1384575989.965159s
+b0d3c000-0ac9-4a05-aef4-47f826d5c759 username@mezzo:~/datadir/Annex timestamp=1384547220.353298s
+
+\"\"\"]]
+"""]]
diff --git a/doc/bugs/Assistant_has_created_155_semitrusted_repositories/comment_3_6a4118e5c5fbe5e84d27094ac72b741b._comment b/doc/bugs/Assistant_has_created_155_semitrusted_repositories/comment_3_6a4118e5c5fbe5e84d27094ac72b741b._comment
new file mode 100644
index 000000000..2d31d1a7a
--- /dev/null
+++ b/doc/bugs/Assistant_has_created_155_semitrusted_repositories/comment_3_6a4118e5c5fbe5e84d27094ac72b741b._comment
@@ -0,0 +1,22 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.64"
+ subject="comment 3"
+ date="2013-11-22T17:47:30Z"
+ content="""
+Any chance I could get a copy of this git repository? (Excluding the .git/annex part)
+
+Feel free to email me id@joeyh.name to arrange a secure transfer.
+
+Otherwise, I need to see what the git-annex:uuid.log file looked like before this happened to it. The corruption may have occurred progressively in several commits, or all at once.
+
+You might also still have some logs in `.git/annex/daemon.log*`, and sending those might help, assuming the strange messages you mentioned are logged in there.
+
+> 1384785215.389096s 1 0ab193eb-0c76-4559-a93c-2e30ed8630a8
+
+This is pretty weird thing to be in the uuid.log. The \"1\" makes me think this might be a scrambled version of what's normally stored in the trust.log:
+
+> 511f4722-63d5-11e1-8b26-1bb951ea9f7b 1 timestamp=1330630786.417597s
+
+This seems to be the same bug as [[bugs/non-repos in repositories list (+ other weird output) from git annex status]]
+"""]]
diff --git a/doc/bugs/Assistant_has_created_155_semitrusted_repositories/comment_4_04daa20d5d7c74bb34ec48e752ed9fe8._comment b/doc/bugs/Assistant_has_created_155_semitrusted_repositories/comment_4_04daa20d5d7c74bb34ec48e752ed9fe8._comment
new file mode 100644
index 000000000..dd037bcc0
--- /dev/null
+++ b/doc/bugs/Assistant_has_created_155_semitrusted_repositories/comment_4_04daa20d5d7c74bb34ec48e752ed9fe8._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.64"
+ subject="comment 4"
+ date="2013-11-22T17:48:37Z"
+ content="""
+What hardware are you running git-annex on?
+"""]]
diff --git a/doc/bugs/Assistant_has_created_155_semitrusted_repositories/comment_5_11af8ab2587e6eeb671051ba8191995b._comment b/doc/bugs/Assistant_has_created_155_semitrusted_repositories/comment_5_11af8ab2587e6eeb671051ba8191995b._comment
new file mode 100644
index 000000000..de9d4fd71
--- /dev/null
+++ b/doc/bugs/Assistant_has_created_155_semitrusted_repositories/comment_5_11af8ab2587e6eeb671051ba8191995b._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnNqLKszWk9EoD4CDCqNXJRIklKFBCN1Ao"
+ nickname="maurizio"
+ subject="comment 5"
+ date="2013-11-22T18:22:55Z"
+ content="""
+One client is a thinkpad 121e, the other one a hp Z420 workstation. The archive is a basic Dell desktop. All of them run wheezy with git-annex and git from official backports. The transfer repository is at rsync.net.
+
+The daemon.log file was empty at the time I noticed the situation. Now git-annex has been scanning this repository for some time and the log has information again but it looks a bit too long to be posted here. I will email about the repository copy and the log.
+
+"""]]
diff --git a/doc/bugs/Assistant_has_created_155_semitrusted_repositories/comment_6_26236cdc2bce532017854791bcd727d1._comment b/doc/bugs/Assistant_has_created_155_semitrusted_repositories/comment_6_26236cdc2bce532017854791bcd727d1._comment
new file mode 100644
index 000000000..8b5c80f6b
--- /dev/null
+++ b/doc/bugs/Assistant_has_created_155_semitrusted_repositories/comment_6_26236cdc2bce532017854791bcd727d1._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnNqLKszWk9EoD4CDCqNXJRIklKFBCN1Ao"
+ nickname="maurizio"
+ subject="comment 6"
+ date="2013-11-22T19:29:08Z"
+ content="""
+Some additional information (useful at least from user's point of view): the data that was in the annex but outside of the archive is still accessible from both clients. Part of the data that was in the archive does not seem to be accessible on one client: ```git annex get``` says it gets data in an amount which seems correct but the link to the data remains broken. Fortunately I can still access the data on the other client. Some of the data in the archive is still accessible in both clients. The part that is still accessible was put in the annex a few days ago, only the last directory which was added and seems to have triggered the problem is \"broken\" on one client. It is possible (not sure, sorry) that this directory was first added in the annex, and then moved to the archive shortly after, before the first addition had propagated to the other client.
+"""]]
diff --git a/doc/bugs/Assistant_has_created_155_semitrusted_repositories/comment_7_3c532dd5b8a01ecdeda1300b49aba675._comment b/doc/bugs/Assistant_has_created_155_semitrusted_repositories/comment_7_3c532dd5b8a01ecdeda1300b49aba675._comment
new file mode 100644
index 000000000..00abc500b
--- /dev/null
+++ b/doc/bugs/Assistant_has_created_155_semitrusted_repositories/comment_7_3c532dd5b8a01ecdeda1300b49aba675._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnNqLKszWk9EoD4CDCqNXJRIklKFBCN1Ao"
+ nickname="maurizio"
+ subject="comment 7"
+ date="2013-11-23T13:16:10Z"
+ content="""
+OK, sorry but it will be difficult to provide you with a copy of this repository. I hope I can still help in spite of being only a very novice git user. I checked that the git-annex:uuid.log file at the first commit was identical to the one above. The only difference is that in this first commit file there is a mention at the bottom of who created the file (me@somedomain.com) with the mention \"created repository\".
+
+So it is very possible that these nonexisting remotes are present since day 1. It is possible that I did not notice it earlier (I am not sure I had ever run git annex status in this repository since I am looking for a dropbox-like experience). What triggered my curiosity was the difficulty I had to get some data. At that point it might be that there are two independent problems. One with these nonexisting repositories, and another one with the fact that I cannot get some data in this client.
+
+Would it be useful to you to have the full history (52 revisions) of the git-annex:uuid.log file?
+"""]]
diff --git a/doc/bugs/Assistant_has_created_155_semitrusted_repositories/comment_8_119142c5ebc499f0ee0926dbca265308._comment b/doc/bugs/Assistant_has_created_155_semitrusted_repositories/comment_8_119142c5ebc499f0ee0926dbca265308._comment
new file mode 100644
index 000000000..d50964f64
--- /dev/null
+++ b/doc/bugs/Assistant_has_created_155_semitrusted_repositories/comment_8_119142c5ebc499f0ee0926dbca265308._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.64"
+ subject="comment 8"
+ date="2013-11-26T16:34:13Z"
+ content="""
+Yes, it would be helpful to have the full history of the file.
+
+You might try running `git annex fsck` on the file in the client that it says it has gotten but that you cannot access.
+"""]]
diff --git a/doc/bugs/Assistant_redirects_to_127.0.0.1_in_some_cases__44___although_used_remotely.mdwn b/doc/bugs/Assistant_redirects_to_127.0.0.1_in_some_cases__44___although_used_remotely.mdwn
new file mode 100644
index 000000000..1b1738aec
--- /dev/null
+++ b/doc/bugs/Assistant_redirects_to_127.0.0.1_in_some_cases__44___although_used_remotely.mdwn
@@ -0,0 +1,29 @@
+### Please describe the problem.
+When I use git-annex webapp with a remote IP of a headless computer,
+I am sometimes redirected to a 127.0.0.1 address (with a different
+port as well)
+
+### What steps will reproduce the problem?
+1. Install git-annex as usual.
+2. Open git-annex assistant from a headless machine and access the
+webapp with the --listen option. (e.g. git annex webapp
+--listen=xxx.yyy.zzz.www)
+3. Create your first local repository. Then create a second local
+repository.
+4. When assistant asks you if you want to merge these 2
+repositories, try to select the second option (to keep them
+separated).
+5. You are redirected from your remote IP to 127.0.0.1 to a new port number.
+
+(I also encountered the same error at another menu or function, but
+I don't remember where. Sorry.)
+
+### What version of git-annex are you using? On what operating system?
+4.20130815
+Ubuntu 13.10 64-bit (kernel 3.11.0-13-generic x86_64)
+
+### Please provide any additional information below.
+Please ask me for any additional information that may be useful.
+
+> This is a duplicate of [[Switching_repositories_in_webapp_on_a_remote_server_is_not_honoring_--listen_parameter]]
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux.mdwn b/doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux.mdwn
new file mode 100644
index 000000000..a2f79aa6c
--- /dev/null
+++ b/doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux.mdwn
@@ -0,0 +1,75 @@
+### Please describe the problem.
+
+I am experiencing a weird issue with any install I've had on this one (and only) ArchLinux machine: all of aur/git-annex 4.20130516-1, aur/git-annex-bin-4.20130909-1, aur/git-annex-standalone-4.20130909-1 and a Cabal install just stall when trying to create the initial Git annex repo in the webapp.
+
+When started, it offers me to create the annex in ~/annex/ or ~/Desktop/annex/, where ~ gets turned into /home/USER when I press “Make repository”, but nothing else happens. This is regardless of if that repo exists when I try to create it or start the webapp.
+
+If I start the webapp from an existing annex (now in ~/annex), it seems to work a bit better, but any other remote (SSH) server that I try to add fails. I just get a fleeting Bootstrap message box when I click “Check this server”, and nothing in the logs of eithr git annex webapp or the ssh logs of the server.
+
+If an annex exists, but I start the webapp from another directory, it just behaves as if none were found.
+
+Calls to git annex assistant --autostart complain that "Nothing listed in /home/omehani/.config/git-annex/autostart". I have checked the permissions on that directory, and tried deleting it to let git-annex recreate it, which it did, to no avail.
+
+
+### What steps will reproduce the problem?
+
+Install any of the git-annex packages available from AUR
+
+### What version of git-annex are you using? On what operating system?
+
+* up-to-date ArchLinux, Linux cancey 3.10.10-1-ARCH #1 SMP PREEMPT Fri Aug 30 11:30:06 CEST 2013 x86_64 GNU/Linux
+* aur/git-annex 4.20130516-1, aur/git-annex-bin-4.20130909-1, aur/git-annex-standalone-4.20130909-1 or through Cabal (on 2013-09-12)
+
+### Please provide any additional information below.
+
+The following is the output of webapp --debug. Nothing actually appears when trying to add/edit a repo.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+~/annex (master)$ git annex webapp --debug
+[2013-09-16 10:26:55 EST] read: git ["--git-dir=/home/omehani/annex/.git","--work-tree=/home/omehani/annex","show-ref","git-annex"]
+[2013-09-16 10:26:55 EST] read: git ["--git-dir=/home/omehani/annex/.git","--work-tree=/home/omehani/annex","show-ref","--hash","refs/heads/git-annex"]
+[2013-09-16 10:26:55 EST] read: git ["--git-dir=/home/omehani/annex/.git","--work-tree=/home/omehani/annex","log","refs/heads/git-annex..27c891f84f6ea7a10c68c0dd696ab84d88ef0cec","--oneline","-n1"]
+[2013-09-16 10:26:55 EST] read: git ["--git-dir=/home/omehani/annex/.git","--work-tree=/home/omehani/annex","log","refs/heads/git-annex..d0a1cb518045af01b443694aa2cd9af6386de38a","--oneline","-n1"]
+[2013-09-16 10:26:55 EST] read: git ["--git-dir=/home/omehani/annex/.git","--work-tree=/home/omehani/annex","log","refs/heads/git-annex..3ff23e23d74ace008b03143120e84f07e52ed8ee","--oneline","-n1"]
+[2013-09-16 10:26:55 EST] chat: git ["--git-dir=/home/omehani/annex/.git","--work-tree=/home/omehani/annex","cat-file","--batch"]
+[2013-09-16 10:26:55 EST] logging to /home/omehani/annex/.git/annex/daemon.log
+[2013-09-16 10:26:55 EST] logging to /home/omehani/annex/.git/annex/daemon.log
+Launching web browser on file:///home/omehani/annex/.git/annex/webapp.html
+START /usr/lib/firefox/firefox "/home/omehani/annex/.git/annex/webapp.html"
+
+(process:2699): GLib-CRITICAL **: g_slice_set_config: assertion `sys_page_size == 0' failed
+
+
+# End of transcript or log.
+"""]]
+
+Running git annex from a different directory.
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+~$ git annex webapp --debug
+Launching web browser on file:///tmp/webapp3934.html
+START /usr/lib/firefox/firefox "/tmp/webapp3934.html"
+
+(process:4008): GLib-CRITICAL **: g_slice_set_config: assertion `sys_page_size == 0' failed
+
+# End of transcript or log.
+"""]]
+
+Trying the autostart:
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+~$ git annex assistant --autostart --debug
+git-annex: Nothing listed in /home/omehani/.config/git-annex/autostart
+
+
+# End of transcript or log.
+"""]]
+
+> workaround is in place [[done]] --[[Joey]]
diff --git a/doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_10_ec4a7388ea7106a953f599b664b37f1d._comment b/doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_10_ec4a7388ea7106a953f599b664b37f1d._comment
new file mode 100644
index 000000000..b0d0bdd55
--- /dev/null
+++ b/doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_10_ec4a7388ea7106a953f599b664b37f1d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://olivier.mehani.name/"
+ nickname="olivier-mehani"
+ subject="comment 10"
+ date="2013-10-23T03:30:17Z"
+ content="""
+Right, I actually have 4.20131023-g9898139. This makes more sense.
+"""]]
diff --git a/doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_1_6a60c23850a5e2a7bba355e1317abc69._comment b/doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_1_6a60c23850a5e2a7bba355e1317abc69._comment
new file mode 100644
index 000000000..ed9ace976
--- /dev/null
+++ b/doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_1_6a60c23850a5e2a7bba355e1317abc69._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://olivier.mehani.name/"
+ nickname="olivier-mehani"
+ subject="comment 1"
+ date="2013-09-16T01:27:14Z"
+ content="""
+The version with which the following tests were run (installed with Cabal)
+
+[[!format sh \"\"\"
+git-annex version: 4.20130827
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus DNS
+\"\"\"]]
+"""]]
diff --git a/doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_2_90b6ed232b2917b9fe041532284e1212._comment b/doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_2_90b6ed232b2917b9fe041532284e1212._comment
new file mode 100644
index 000000000..703be9a84
--- /dev/null
+++ b/doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_2_90b6ed232b2917b9fe041532284e1212._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.14.105"
+ subject="comment 2"
+ date="2013-09-19T17:12:39Z"
+ content="""
+Please send the content of the file /home/omehani/annex/.git/annex/daemon.log
+
+It would also help if you could better describe what happens. Perhaps make a screenshot?
+"""]]
diff --git a/doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_3_5a89d79395d96c43d7d8a6fd9dc275f1._comment b/doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_3_5a89d79395d96c43d7d8a6fd9dc275f1._comment
new file mode 100644
index 000000000..39f0f39b8
--- /dev/null
+++ b/doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_3_5a89d79395d96c43d7d8a6fd9dc275f1._comment
@@ -0,0 +1,248 @@
+[[!comment format=mdwn
+ username="http://olivier.mehani.name/"
+ nickname="olivier-mehani"
+ subject="comment 3"
+ date="2013-09-30T01:29:50Z"
+ content="""
+This is when having manually created the local annex, and trying to add a remote one. Surprisingly, I cannot find any reference to the remote server's address or username...
+
+ [2013-09-30 11:14:38 EST] main: starting assistant version 4.20130827
+ [2013-09-30 11:14:38 EST] read: git [\"--git-dir=/home/USERNAME/annex/.git\",\"--work-tree=/home/USERNAME/annex\",\"show-ref\",\"git-annex\"]
+ [2013-09-30 11:14:38 EST] read: xdg-open [\"file:///home/USERNAME/annex/.git/annex/webapp.html\"]
+ [2013-09-30 11:14:38 EST] read: git [\"--git-dir=/home/USERNAME/annex/.git\",\"--work-tree=/home/USERNAME/annex\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+ [2013-09-30 11:14:38 EST] read: git [\"--git-dir=/home/USERNAME/annex/.git\",\"--work-tree=/home/USERNAME/annex\",\"log\",\"refs/heads/git-annex..9d87789505628a2da8347574cc600e358ff76107\",\"--oneline\",\"-n1\"]
+ [2013-09-30 11:14:38 EST] Merger: watching /home/USERNAME/annex/.git/refs
+ [2013-09-30 11:14:38 EST] TransferWatcher: watching for transfers
+ [2013-09-30 11:14:38 EST] read: git [\"--git-dir=/home/USERNAME/annex/.git\",\"--work-tree=/home/USERNAME/annex\",\"ls-tree\",\"-z\",\"--\",\"refs/heads/git-annex\",\"uuid.log\",\"remote.log\",\"trust.log\",\"group.log\",\"preferred-content.log\"]
+
+ No known network monitor available through dbus; falling back to polling
+ [2013-09-30 11:14:38 EST] read: git [\"--git-dir=/home/USERNAME/annex/.git\",\"--work-tree=/home/USERNAME/annex\",\"ls-tree\",\"-z\",\"--\",\"refs/heads/git-annex\",\"uuid.log\",\"remote.log\",\"trust.log\",\"group.log\",\"preferred-content.log\"]
+ (scanning...) [2013-09-30 11:14:38 EST] Watcher: Performing startup scan
+ [2013-09-30 11:14:38 EST] read: git [\"--git-dir=/home/USERNAME/annex/.git\",\"--work-tree=/home/USERNAME/annex\",\"ls-files\",\"--deleted\",\"-z\",\"--\",\"/home/USERNAME/annex\"]
+ (started...) [2013-09-30 11:14:38 EST] Watcher: watching .
+ [2013-09-30 11:14:38 EST] MountWatcher: Started DBUS service org.gtk.Private.UDisks2VolumeMonitor to monitor mount events.
+ [2013-09-30 11:14:39 EST] 127.0.0.1 GET / Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:14:39 EST] read: git [\"--git-dir=/home/USERNAME/annex/.git\",\"--work-tree=/home/USERNAME/annex\",\"show-ref\",\"git-annex\"]
+ [2013-09-30 11:14:39 EST] read: git [\"--git-dir=/home/USERNAME/annex/.git\",\"--work-tree=/home/USERNAME/annex\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+ [2013-09-30 11:14:39 EST] read: git [\"--git-dir=/home/USERNAME/annex/.git\",\"--work-tree=/home/USERNAME/annex\",\"log\",\"refs/heads/git-annex..9d87789505628a2da8347574cc600e358ff76107\",\"--oneline\",\"-n1\"]
+ [2013-09-30 11:14:39 EST] chat: git [\"--git-dir=/home/USERNAME/annex/.git\",\"--work-tree=/home/USERNAME/annex\",\"cat-file\",\"--batch\"]
+ [2013-09-30 11:14:39 EST] 127.0.0.1 GET /static/css/bootstrap.css Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:14:39 EST] 127.0.0.1 GET /static/css/bootstrap-responsive.css Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:14:39 EST] 127.0.0.1 GET /static/jquery.full.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:14:39 EST] 127.0.0.1 GET /static/js/bootstrap-dropdown.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:14:39 EST] 127.0.0.1 GET /static/js/bootstrap-modal.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:14:39 EST] 127.0.0.1 GET /static/js/bootstrap-collapse.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:14:39 EST] 127.0.0.1 GET /static/longpolling.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:14:39 EST] 127.0.0.1 GET /static/jquery.ui.core.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:14:39 EST] 127.0.0.1 GET /static/jquery.ui.widget.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:14:39 EST] 127.0.0.1 GET /static/jquery.ui.mouse.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:14:39 EST] 127.0.0.1 GET /static/jquery.ui.sortable.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:14:39 EST] 127.0.0.1 GET /static/img/glyphicons-halflings-white.png Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:14:39 EST] 127.0.0.1 GET /static/img/glyphicons-halflings.png Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:14:39 EST] 127.0.0.1 GET /notifier/sidebar Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:14:39 EST] 127.0.0.1 GET /notifier/repolist/RepoSelector%20%7BonlyCloud%20=%20False,%20onlyConfigured%20=%20False,%20includeHere%20=%20True,%20nudgeAddMore%20=%20True%7D Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:14:39 EST] 127.0.0.1 GET /notifier/transfers Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:14:39 EST] 127.0.0.1 GET /static/favicon.ico Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:14:39 EST] 127.0.0.1 GET /sidebar/NotificationId%200 Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:14:39 EST] 127.0.0.1 GET /repolist/RepoListNotificationId%20(NotificationId%200)%20(RepoSelector%20%7BonlyCloud%20=%20False,%20onlyConfigured%20=%20False,%20includeHere%20=%20True,%20nudgeAddMore%20=%20True%7D) Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:14:39 EST] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:14:39 EST] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:14:39 EST] 127.0.0.1 GET /repolist/RepoListNotificationId%20(NotificationId%200)%20(RepoSelector%20%7BonlyCloud%20=%20False,%20onlyConfigured%20=%20False,%20includeHere%20=%20True,%20nudgeAddMore%20=%20True%7D) Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:14:40 EST] 127.0.0.1 GET /sidebar/NotificationId%200 Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:14:40 EST] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:14:40 EST] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:14:40 EST] 127.0.0.1 GET /static/favicon.ico Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:14:40 EST] 127.0.0.1 GET /static/favicon.ico Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:16 EST] 127.0.0.1 GET /config Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:16 EST] 127.0.0.1 GET /sidebar/NotificationId%200 Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:16 EST] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:16 EST] 127.0.0.1 GET /repolist/RepoListNotificationId%20(NotificationId%200)%20(RepoSelector%20%7BonlyCloud%20=%20False,%20onlyConfigured%20=%20False,%20includeHere%20=%20True,%20nudgeAddMore%20=%20True%7D) Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:16 EST] 127.0.0.1 GET /static/css/bootstrap.css Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:16 EST] 127.0.0.1 GET /static/css/bootstrap-responsive.css Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:16 EST] 127.0.0.1 GET /static/jquery.full.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:16 EST] 127.0.0.1 GET /static/js/bootstrap-dropdown.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:16 EST] 127.0.0.1 GET /static/js/bootstrap-modal.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:16 EST] 127.0.0.1 GET /static/js/bootstrap-collapse.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:16 EST] 127.0.0.1 GET /static/longpolling.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:16 EST] 127.0.0.1 GET /static/img/glyphicons-halflings-white.png Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:16 EST] 127.0.0.1 GET /static/img/glyphicons-halflings.png Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:16 EST] 127.0.0.1 GET /notifier/sidebar Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:17 EST] 127.0.0.1 GET /sidebar/NotificationId%201 Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:17 EST] 127.0.0.1 GET /static/favicon.ico Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:17 EST] 127.0.0.1 GET /sidebar/NotificationId%201 Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:19 EST] 127.0.0.1 GET /config/addrepository Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:19 EST] 127.0.0.1 GET /static/css/bootstrap.css Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:19 EST] 127.0.0.1 GET /static/css/bootstrap-responsive.css Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:19 EST] 127.0.0.1 GET /static/jquery.full.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:19 EST] 127.0.0.1 GET /static/js/bootstrap-dropdown.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:19 EST] 127.0.0.1 GET /static/js/bootstrap-modal.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:19 EST] 127.0.0.1 GET /static/js/bootstrap-collapse.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:19 EST] 127.0.0.1 GET /static/longpolling.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:19 EST] 127.0.0.1 GET /static/jquery.ui.core.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:19 EST] 127.0.0.1 GET /static/jquery.ui.widget.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:19 EST] 127.0.0.1 GET /static/jquery.ui.mouse.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:19 EST] 127.0.0.1 GET /static/jquery.ui.sortable.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:19 EST] 127.0.0.1 GET /static/img/glyphicons-halflings.png Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:19 EST] 127.0.0.1 GET /static/img/glyphicons-halflings-white.png Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:19 EST] 127.0.0.1 GET /notifier/sidebar Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:19 EST] 127.0.0.1 GET /notifier/repolist/RepoSelector%20%7BonlyCloud%20=%20False,%20onlyConfigured%20=%20False,%20includeHere%20=%20True,%20nudgeAddMore%20=%20False%7D Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:20 EST] 127.0.0.1 GET /sidebar/NotificationId%202 Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:20 EST] 127.0.0.1 GET /repolist/RepoListNotificationId%20(NotificationId%201)%20(RepoSelector%20%7BonlyCloud%20=%20False,%20onlyConfigured%20=%20False,%20includeHere%20=%20True,%20nudgeAddMore%20=%20False%7D) Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:20 EST] 127.0.0.1 GET /repolist/RepoListNotificationId%20(NotificationId%201)%20(RepoSelector%20%7BonlyCloud%20=%20False,%20onlyConfigured%20=%20False,%20includeHere%20=%20True,%20nudgeAddMore%20=%20False%7D) Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:20 EST] 127.0.0.1 GET /static/favicon.ico Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:20 EST] 127.0.0.1 GET /sidebar/NotificationId%202 Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:31 EST] 127.0.0.1 GET /config/repository/add/ssh Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:31 EST] 127.0.0.1 GET /repolist/RepoListNotificationId%20(NotificationId%201)%20(RepoSelector%20%7BonlyCloud%20=%20False,%20onlyConfigured%20=%20False,%20includeHere%20=%20True,%20nudgeAddMore%20=%20False%7D) Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:31 EST] 127.0.0.1 GET /sidebar/NotificationId%202 Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:31 EST] 127.0.0.1 GET /static/css/bootstrap.css Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:31 EST] 127.0.0.1 GET /static/css/bootstrap-responsive.css Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:31 EST] 127.0.0.1 GET /static/js/bootstrap-dropdown.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:31 EST] 127.0.0.1 GET /static/jquery.full.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:31 EST] 127.0.0.1 GET /static/js/bootstrap-modal.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:31 EST] 127.0.0.1 GET /static/js/bootstrap-collapse.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:31 EST] 127.0.0.1 GET /static/longpolling.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:32 EST] 127.0.0.1 GET /static/img/glyphicons-halflings-white.png Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:32 EST] 127.0.0.1 GET /static/img/glyphicons-halflings.png Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:32 EST] 127.0.0.1 GET /notifier/sidebar Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:32 EST] 127.0.0.1 GET /sidebar/NotificationId%203 Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:32 EST] 127.0.0.1 GET /static/favicon.ico Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:32 EST] 127.0.0.1 GET /sidebar/NotificationId%203 Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:37 EST] 127.0.0.1 GET / Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:37 EST] 127.0.0.1 GET /static/css/bootstrap.css Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:37 EST] 127.0.0.1 GET /static/css/bootstrap-responsive.css Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:37 EST] 127.0.0.1 GET /static/jquery.full.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:37 EST] 127.0.0.1 GET /static/js/bootstrap-dropdown.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:37 EST] 127.0.0.1 GET /static/js/bootstrap-modal.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:37 EST] 127.0.0.1 GET /static/js/bootstrap-collapse.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:37 EST] 127.0.0.1 GET /static/longpolling.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:37 EST] 127.0.0.1 GET /static/jquery.ui.core.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:37 EST] 127.0.0.1 GET /static/jquery.ui.widget.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:37 EST] 127.0.0.1 GET /static/jquery.ui.mouse.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:37 EST] 127.0.0.1 GET /static/jquery.ui.sortable.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:37 EST] 127.0.0.1 GET /static/img/glyphicons-halflings-white.png Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:37 EST] 127.0.0.1 GET /static/img/glyphicons-halflings.png Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:37 EST] 127.0.0.1 GET /notifier/sidebar Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:37 EST] 127.0.0.1 GET /notifier/repolist/RepoSelector%20%7BonlyCloud%20=%20False,%20onlyConfigured%20=%20False,%20includeHere%20=%20True,%20nudgeAddMore%20=%20True%7D Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:37 EST] 127.0.0.1 GET /notifier/transfers Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:37 EST] 127.0.0.1 GET /static/favicon.ico Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:37 EST] 127.0.0.1 GET /sidebar/NotificationId%204 Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:37 EST] 127.0.0.1 GET /repolist/RepoListNotificationId%20(NotificationId%202)%20(RepoSelector%20%7BonlyCloud%20=%20False,%20onlyConfigured%20=%20False,%20includeHere%20=%20True,%20nudgeAddMore%20=%20True%7D) Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:37 EST] 127.0.0.1 GET /transfers/NotificationId%202 Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:37 EST] 127.0.0.1 GET /repolist/RepoListNotificationId%20(NotificationId%202)%20(RepoSelector%20%7BonlyCloud%20=%20False,%20onlyConfigured%20=%20False,%20includeHere%20=%20True,%20nudgeAddMore%20=%20True%7D) Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:37 EST] 127.0.0.1 GET /transfers/NotificationId%202 Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:37 EST] 127.0.0.1 GET /sidebar/NotificationId%204 Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:47 EST] 127.0.0.1 GET /about Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:47 EST] 127.0.0.1 GET /sidebar/NotificationId%204 Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:47 EST] 127.0.0.1 GET /transfers/NotificationId%202 Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:47 EST] 127.0.0.1 GET /repolist/RepoListNotificationId%20(NotificationId%202)%20(RepoSelector%20%7BonlyCloud%20=%20False,%20onlyConfigured%20=%20False,%20includeHere%20=%20True,%20nudgeAddMore%20=%20True%7D) Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:47 EST] 127.0.0.1 GET /static/css/bootstrap.css Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:47 EST] 127.0.0.1 GET /static/css/bootstrap-responsive.css Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:47 EST] 127.0.0.1 GET /static/jquery.full.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:47 EST] 127.0.0.1 GET /static/js/bootstrap-dropdown.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:47 EST] 127.0.0.1 GET /static/js/bootstrap-modal.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:47 EST] 127.0.0.1 GET /static/js/bootstrap-collapse.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:47 EST] 127.0.0.1 GET /static/longpolling.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:47 EST] 127.0.0.1 GET /static/img/glyphicons-halflings-white.png Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:47 EST] 127.0.0.1 GET /static/img/glyphicons-halflings.png Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:47 EST] 127.0.0.1 GET /notifier/sidebar Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:47 EST] 127.0.0.1 GET /sidebar/NotificationId%205 Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:47 EST] 127.0.0.1 GET /static/favicon.ico Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:47 EST] 127.0.0.1 GET /sidebar/NotificationId%205 Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:50 EST] 127.0.0.1 GET /config Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:50 EST] 127.0.0.1 GET /static/css/bootstrap.css Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:50 EST] 127.0.0.1 GET /static/css/bootstrap-responsive.css Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:50 EST] 127.0.0.1 GET /static/jquery.full.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:50 EST] 127.0.0.1 GET /static/js/bootstrap-dropdown.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:50 EST] 127.0.0.1 GET /static/js/bootstrap-modal.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:50 EST] 127.0.0.1 GET /static/js/bootstrap-collapse.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:50 EST] 127.0.0.1 GET /static/longpolling.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:50 EST] 127.0.0.1 GET /static/img/glyphicons-halflings-white.png Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:50 EST] 127.0.0.1 GET /static/img/glyphicons-halflings.png Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:50 EST] 127.0.0.1 GET /notifier/sidebar Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:50 EST] 127.0.0.1 GET /sidebar/NotificationId%206 Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:50 EST] 127.0.0.1 GET /static/favicon.ico Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:50 EST] 127.0.0.1 GET /sidebar/NotificationId%206 Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:51 EST] 127.0.0.1 GET /config/addrepository Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:51 EST] 127.0.0.1 GET /static/css/bootstrap.css Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:51 EST] 127.0.0.1 GET /static/css/bootstrap-responsive.css Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:51 EST] 127.0.0.1 GET /static/jquery.full.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:51 EST] 127.0.0.1 GET /static/js/bootstrap-dropdown.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:51 EST] 127.0.0.1 GET /static/js/bootstrap-modal.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:51 EST] 127.0.0.1 GET /static/js/bootstrap-collapse.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:51 EST] 127.0.0.1 GET /static/longpolling.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:51 EST] 127.0.0.1 GET /static/jquery.ui.widget.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:51 EST] 127.0.0.1 GET /static/jquery.ui.mouse.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:51 EST] 127.0.0.1 GET /static/jquery.ui.core.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:51 EST] 127.0.0.1 GET /static/jquery.ui.sortable.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:51 EST] 127.0.0.1 GET /static/favicon.ico Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:51 EST] 127.0.0.1 GET /static/img/glyphicons-halflings.png Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:51 EST] 127.0.0.1 GET /static/img/glyphicons-halflings-white.png Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:51 EST] 127.0.0.1 GET /notifier/sidebar Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:51 EST] 127.0.0.1 GET /notifier/repolist/RepoSelector%20%7BonlyCloud%20=%20False,%20onlyConfigured%20=%20False,%20includeHere%20=%20True,%20nudgeAddMore%20=%20False%7D Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:51 EST] 127.0.0.1 GET /repolist/RepoListNotificationId%20(NotificationId%203)%20(RepoSelector%20%7BonlyCloud%20=%20False,%20onlyConfigured%20=%20False,%20includeHere%20=%20True,%20nudgeAddMore%20=%20False%7D) Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:51 EST] 127.0.0.1 GET /sidebar/NotificationId%207 Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:51 EST] 127.0.0.1 GET /repolist/RepoListNotificationId%20(NotificationId%203)%20(RepoSelector%20%7BonlyCloud%20=%20False,%20onlyConfigured%20=%20False,%20includeHere%20=%20True,%20nudgeAddMore%20=%20False%7D) Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:52 EST] 127.0.0.1 GET /sidebar/NotificationId%207 Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:56 EST] 127.0.0.1 GET /config/repository/add/ssh Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:56 EST] 127.0.0.1 GET /repolist/RepoListNotificationId%20(NotificationId%203)%20(RepoSelector%20%7BonlyCloud%20=%20False,%20onlyConfigured%20=%20False,%20includeHere%20=%20True,%20nudgeAddMore%20=%20False%7D) Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:56 EST] 127.0.0.1 GET /sidebar/NotificationId%207 Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:56 EST] 127.0.0.1 GET /static/css/bootstrap-responsive.css Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:56 EST] 127.0.0.1 GET /static/css/bootstrap.css Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:56 EST] 127.0.0.1 GET /static/jquery.full.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:56 EST] 127.0.0.1 GET /static/js/bootstrap-dropdown.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:56 EST] 127.0.0.1 GET /static/js/bootstrap-modal.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:56 EST] 127.0.0.1 GET /static/js/bootstrap-collapse.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:56 EST] 127.0.0.1 GET /static/longpolling.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:56 EST] 127.0.0.1 GET /static/favicon.ico Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:56 EST] 127.0.0.1 GET /static/img/glyphicons-halflings-white.png Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:56 EST] 127.0.0.1 GET /static/img/glyphicons-halflings.png Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:56 EST] 127.0.0.1 GET /notifier/sidebar Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:56 EST] 127.0.0.1 GET /sidebar/NotificationId%208 Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:15:56 EST] 127.0.0.1 GET /sidebar/NotificationId%208 Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:16:23 EST] 127.0.0.1 POST /config/repository/add/ssh Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:16:23 EST] 127.0.0.1 GET /sidebar/NotificationId%208 Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:16:23 EST] 127.0.0.1 GET /static/css/bootstrap.css Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:16:23 EST] 127.0.0.1 GET /static/css/bootstrap-responsive.css Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:16:23 EST] 127.0.0.1 GET /static/js/bootstrap-collapse.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:16:23 EST] 127.0.0.1 GET /static/jquery.full.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:16:23 EST] 127.0.0.1 GET /static/js/bootstrap-dropdown.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:16:23 EST] 127.0.0.1 GET /static/js/bootstrap-modal.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:16:23 EST] 127.0.0.1 GET /static/longpolling.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:16:23 EST] 127.0.0.1 GET /static/favicon.ico Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:16:23 EST] 127.0.0.1 GET /static/img/glyphicons-halflings-white.png Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:16:23 EST] 127.0.0.1 GET /static/img/glyphicons-halflings.png Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:16:23 EST] 127.0.0.1 GET /notifier/sidebar Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:16:23 EST] 127.0.0.1 GET /sidebar/NotificationId%209 Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:16:23 EST] 127.0.0.1 GET /sidebar/NotificationId%209 Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:16:44 EST] 127.0.0.1 POST /config/repository/add/ssh Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:16:44 EST] 127.0.0.1 GET /sidebar/NotificationId%209 Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:16:44 EST] 127.0.0.1 GET /static/css/bootstrap-responsive.css Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:16:44 EST] 127.0.0.1 GET /static/css/bootstrap.css Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:16:44 EST] 127.0.0.1 GET /static/jquery.full.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:16:44 EST] 127.0.0.1 GET /static/js/bootstrap-dropdown.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:16:44 EST] 127.0.0.1 GET /static/js/bootstrap-modal.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:16:44 EST] 127.0.0.1 GET /static/js/bootstrap-collapse.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:16:44 EST] 127.0.0.1 GET /static/longpolling.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:16:44 EST] 127.0.0.1 GET /static/favicon.ico Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:16:44 EST] 127.0.0.1 GET /static/img/glyphicons-halflings.png Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:16:44 EST] 127.0.0.1 GET /static/img/glyphicons-halflings-white.png Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:16:44 EST] 127.0.0.1 GET /notifier/sidebar Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:16:45 EST] 127.0.0.1 GET /sidebar/NotificationId%2010 Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:16:45 EST] 127.0.0.1 GET /sidebar/NotificationId%2010 Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:17:01 EST] 127.0.0.1 GET /shutdown Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:17:01 EST] 127.0.0.1 GET /static/css/bootstrap.css Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:17:01 EST] 127.0.0.1 GET /static/css/bootstrap-responsive.css Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:17:01 EST] 127.0.0.1 GET /static/jquery.full.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:17:01 EST] 127.0.0.1 GET /static/js/bootstrap-dropdown.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:17:01 EST] 127.0.0.1 GET /static/js/bootstrap-modal.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:17:01 EST] 127.0.0.1 GET /static/js/bootstrap-collapse.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:17:01 EST] 127.0.0.1 GET /static/longpolling.js Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:17:01 EST] 127.0.0.1 GET /static/img/glyphicons-halflings.png Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:17:01 EST] 127.0.0.1 GET /static/img/glyphicons-halflings-white.png Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:17:01 EST] 127.0.0.1 GET /notifier/sidebar Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:17:01 EST] 127.0.0.1 GET /sidebar/NotificationId%2011 Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:17:01 EST] 127.0.0.1 GET /sidebar/NotificationId%2011 Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+ [2013-09-30 11:17:02 EST] 127.0.0.1 GET /static/favicon.ico Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
+
+
+"""]]
diff --git a/doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_4_cdd26c71875428dbe3c100944a443d3f._comment b/doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_4_cdd26c71875428dbe3c100944a443d3f._comment
new file mode 100644
index 000000000..4ee062a80
--- /dev/null
+++ b/doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_4_cdd26c71875428dbe3c100944a443d3f._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://olivier.mehani.name/"
+ nickname="olivier-mehani"
+ subject="comment 4"
+ date="2013-09-30T01:31:26Z"
+ content="""
+Hum, I'm not allowed to upload images:
+ git-annex-webapp1.png prohibited by allowed_attachments (user is not an admin)
+"""]]
diff --git a/doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_5_76242f5d6c815acd5bd58213bd8bb0fe._comment b/doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_5_76242f5d6c815acd5bd58213bd8bb0fe._comment
new file mode 100644
index 000000000..28a0f7cc4
--- /dev/null
+++ b/doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_5_76242f5d6c815acd5bd58213bd8bb0fe._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.80"
+ subject="comment 5"
+ date="2013-09-30T16:13:20Z"
+ content="""
+I see a lot of activity, which looks like you started up the webapp and it ran displaying stuff for some minutes. I see that you clicked on pages to eg, add a ssh repository.
+
+So, what then do you mean by saying it stalls? You have still not described whatever problem you are having.
+"""]]
diff --git a/doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_6_10852171c0207ca61ea6df1082107353._comment b/doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_6_10852171c0207ca61ea6df1082107353._comment
new file mode 100644
index 000000000..452a898f6
--- /dev/null
+++ b/doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_6_10852171c0207ca61ea6df1082107353._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://olivier.mehani.name/"
+ nickname="olivier-mehani"
+ subject="comment 6"
+ date="2013-10-04T05:14:16Z"
+ content="""
+Right. By “it stalls”, I mean I get redirected to the same dialog page (either the one asking for the path to the repo to create, or the one asking for the details of the remote to add) that I just validated, rather than going further in the process.
+"""]]
diff --git a/doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_7_73e8a5696709f8154e63693ba5e569c3._comment b/doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_7_73e8a5696709f8154e63693ba5e569c3._comment
new file mode 100644
index 000000000..b6df85923
--- /dev/null
+++ b/doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_7_73e8a5696709f8154e63693ba5e569c3._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="64.134.31.139"
+ subject="comment 7"
+ date="2013-10-14T16:18:01Z"
+ content="""
+I just ran into this problem myself. Some investigating shows it is a problem with Yesod's XSRF token. Apparently yesod is not seeing the _token, or is seeing one it does not like. However, I verified in chromium inspector that the form post was including the token with the same value used on the page. Also, it would intermittently accept the form, if I kept posting it over and over again.
+
+It seems this must be a bug in yesod, or on something with how I'm using yesod, or possibly in deeper layers like WAI not seeing the form post include the token, but I have not been able to figure out what. As a workaround, since git-annex webapp does its own authentication and only listens to localhost, and so does not actually need XSRF protection, I am going to change it to bypass that.
+"""]]
diff --git a/doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_8_392fc344e5833b0eb665fcd38f956b7a._comment b/doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_8_392fc344e5833b0eb665fcd38f956b7a._comment
new file mode 100644
index 000000000..37acd5e9a
--- /dev/null
+++ b/doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_8_392fc344e5833b0eb665fcd38f956b7a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://olivier.mehani.name/"
+ nickname="olivier-mehani"
+ subject="comment 8"
+ date="2013-10-23T03:00:58Z"
+ content="""
+I just tried installing git-annex using Cabal today, but only got git-annex-4.20131002, even from source, which seems to predate your last comment, and no other branch seem to provide the yesod fix. Should I get the source from somewhere else than kitenet to try this out (if you think it is in shape to be tested)?
+"""]]
diff --git a/doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_9_9f0fc19a7fcaf7a5827e59e1495cf8c9._comment b/doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_9_9f0fc19a7fcaf7a5827e59e1495cf8c9._comment
new file mode 100644
index 000000000..1e7aa897b
--- /dev/null
+++ b/doc/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/comment_9_9f0fc19a7fcaf7a5827e59e1495cf8c9._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://olivier.mehani.name/"
+ nickname="olivier-mehani"
+ subject="comment 9"
+ date="2013-10-23T03:03:30Z"
+ content="""
+Strike that. It actually works. I could create the ~/annex store, and adding a remote also seems to work (I'm on a hotel Wi-Fi at the moment, so I fear the ssh connection will fail, but nothing to do with git-annex).
+"""]]
diff --git a/doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor.mdwn b/doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor.mdwn
new file mode 100644
index 000000000..c8110eaa0
--- /dev/null
+++ b/doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor.mdwn
@@ -0,0 +1,28 @@
+### What steps will reproduce the problem?
+
+Run `git annex assistant`.
+
+
+### What is the expected output? What do you see instead?
+
+git-annex complains:
+
+ dbus failed; falling back to mtab polling (ClientError {clientErrorMessage =
+ "Call failed: The name org.gtk.Private.GduVolumeMonitor was not provided
+ by any .service files", clientErrorFatal = False})
+
+This is because the `gvfs-gdu-volume-monitor` daemon has been obsoleted and removed from GNOME 3.6 (maybe even earlier).
+
+git-annex should start using `gvfs-udisks2-volume-monitor` at bus name `org.gtk.Private.UDisks2VolumeMonitor`.
+
+Alternatively, git-annex should stop relying on any per-user services, and use kernel interfaces directly when available. (This way, monitoring could work even if the user wasn't logged in and/or didn't have a DBus session bus.)
+
+ * On all Linux kernels since 2.6.15, the `/proc/self/mounts` file is pollable – you can use **select(), poll() or epoll** to detect new mounted filesystems, without having to rely on periodic checks. (Run `findmnt -p` to see it in action.)
+
+ * On BSD systems, kqueue on `/etc/mtab`.
+
+### What version of git-annex are you using? On what operating system?
+
+git-annex 3.20130102 on Linux 3.7.1, GNOME 3.7
+
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_10_0e1db417a5815ea903c1f7ccd07308c4._comment b/doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_10_0e1db417a5815ea903c1f7ccd07308c4._comment
new file mode 100644
index 000000000..37e2613a2
--- /dev/null
+++ b/doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_10_0e1db417a5815ea903c1f7ccd07308c4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://nullroute.eu.org/~grawity/"
+ nickname="Mantas"
+ subject="comment 10"
+ date="2013-01-10T21:51:29Z"
+ content="""
+Works now.
+"""]]
diff --git a/doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_1_28b0cfcba8902c9c16dbe6c4b07984c4._comment b/doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_1_28b0cfcba8902c9c16dbe6c4b07984c4._comment
new file mode 100644
index 000000000..fa71012d2
--- /dev/null
+++ b/doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_1_28b0cfcba8902c9c16dbe6c4b07984c4._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.238"
+ subject="comment 1"
+ date="2013-01-10T17:28:30Z"
+ content="""
+Thanks, excellent info.
+
+Any chance you could provide dbus-monitor output for the events generated by org.gtk.Private.UDisks2VolumeMonitor when a volume is mounted, and unmounted?
+"""]]
diff --git a/doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_2_952b3f78da756ff5f89235db94bec67f._comment b/doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_2_952b3f78da756ff5f89235db94bec67f._comment
new file mode 100644
index 000000000..2db95f8af
--- /dev/null
+++ b/doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_2_952b3f78da756ff5f89235db94bec67f._comment
@@ -0,0 +1,53 @@
+[[!comment format=mdwn
+ username="http://nullroute.eu.org/~grawity/"
+ nickname="Mantas"
+ subject="comment 2"
+ date="2013-01-10T17:38:47Z"
+ content="""
+When mounted:
+
+<pre>
+signal path=/org/gtk/Private/RemoteVolumeMonitor; interface=org.gtk.Private.RemoteVolumeMonitor; member=MountAdded
+ string \"org.gtk.Private.UDisks2VolumeMonitor\"
+ string \"0x1971ab0\"
+ struct {
+ string \"0x1971ab0\"
+ string \"grawpqi\"
+ string \". GThemedIcon media-removable media\"
+ string \". GThemedIcon media-removable-symbolic media-removable media\"
+ string \"\"
+ string \"file:///run/media/grawity/grawpqi\"
+ boolean true
+ string \"0x18f4e50\"
+ array [
+ ]
+ string \"gvfs.time_detected_usec.1357838999510252\"
+ array [
+ ]
+ }
+</pre>
+
+When unmounted:
+
+<pre>
+signal path=/org/gtk/Private/RemoteVolumeMonitor; interface=org.gtk.Private.RemoteVolumeMonitor; member=MountRemoved
+ string \"org.gtk.Private.UDisks2VolumeMonitor\"
+ string \"0x1971910\"
+ struct {
+ string \"0x1971910\"
+ string \"grawpqi\"
+ string \". GThemedIcon media-removable media\"
+ string \". GThemedIcon media-removable-symbolic media-removable media\"
+ string \"\"
+ string \"file:///run/media/grawity/grawpqi\"
+ boolean true
+ string \"\"
+ array [
+ ]
+ string \"gvfs.time_detected_usec.1357839107487969\"
+ array [
+ ]
+ }
+</pre>
+
+"""]]
diff --git a/doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_3_d86aba42d014c4b4f708dcb5fe86e055._comment b/doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_3_d86aba42d014c4b4f708dcb5fe86e055._comment
new file mode 100644
index 000000000..6256086c7
--- /dev/null
+++ b/doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_3_d86aba42d014c4b4f708dcb5fe86e055._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.238"
+ subject="comment 3"
+ date="2013-01-10T19:08:50Z"
+ content="""
+I've just committed support for using the new name. I've not been able to test it yet, as I don't have a new enough gnome here. Any testing you can do much appreciated.
+
+Leaving this bug open until it gets tested, and also because it's certainly appealing to just use poll rather than this fragile dbus stuff. And in any case, should add OSX support.
+"""]]
diff --git a/doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_4_9aaf296ef53da317d6dc6728705d5c56._comment b/doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_4_9aaf296ef53da317d6dc6728705d5c56._comment
new file mode 100644
index 000000000..6df6f40f2
--- /dev/null
+++ b/doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_4_9aaf296ef53da317d6dc6728705d5c56._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://nullroute.eu.org/~grawity/"
+ nickname="Mantas"
+ subject="comment 4"
+ date="2013-01-10T19:41:22Z"
+ content="""
+I'm getting:
+
+ dbus failed; falling back to mtab polling (ClientError {clientErrorMessage =
+ \"Call failed: The name org.gtk.Private.RemoteVolumeMonitor was not provided
+ by any .service files\", clientErrorFatal = False})
+
+The volume monitor's bus name should be `org.gtk.Private.UDisks2VolumeMonitor`.
+
+`org.gtk.Private.RemoteVolumeMonitor` is the interface name, which all Gvfs monitors implement.
+"""]]
diff --git a/doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_5_0d5f8a05a1505660f7ff1bc4ac6ff271._comment b/doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_5_0d5f8a05a1505660f7ff1bc4ac6ff271._comment
new file mode 100644
index 000000000..22b1d923c
--- /dev/null
+++ b/doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_5_0d5f8a05a1505660f7ff1bc4ac6ff271._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.238"
+ subject="oops.."
+ date="2013-01-10T20:09:56Z"
+ content="""
+Think I have the right name in there now.
+"""]]
diff --git a/doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_6_3dfdfd49597c85575cb689adb70d2de6._comment b/doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_6_3dfdfd49597c85575cb689adb70d2de6._comment
new file mode 100644
index 000000000..3320b77da
--- /dev/null
+++ b/doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_6_3dfdfd49597c85575cb689adb70d2de6._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://nullroute.eu.org/~grawity/"
+ nickname="Mantas"
+ subject="comment 6"
+ date="2013-01-10T20:13:42Z"
+ content="""
+It doesn't look completely right – the *service* name (in `checkMountMonitor`) is `org.gtk.Private.UDisks2VolumeMonitor`, but the *interface* name (in `mountChanged`) is `org.gtk.Private.RemoteVolumeMonitor`, so the fix changed too much.
+"""]]
diff --git a/doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_7_943a446c60ed9d7d4f240ba7f00fe925._comment b/doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_7_943a446c60ed9d7d4f240ba7f00fe925._comment
new file mode 100644
index 000000000..8f0cd64cc
--- /dev/null
+++ b/doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_7_943a446c60ed9d7d4f240ba7f00fe925._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.238"
+ subject="been a while.."
+ date="2013-01-10T20:19:33Z"
+ content="""
+Think I have it now.
+"""]]
diff --git a/doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_8_9563859850fb40b1cc2c20c516c12960._comment b/doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_8_9563859850fb40b1cc2c20c516c12960._comment
new file mode 100644
index 000000000..0a3ae95a7
--- /dev/null
+++ b/doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_8_9563859850fb40b1cc2c20c516c12960._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://nullroute.eu.org/~grawity/"
+ nickname="Mantas"
+ subject="build failure"
+ date="2013-01-10T20:24:09Z"
+ content="""
+<pre>
+$ cabal build
+Building git-annex-3.20130108...
+Preprocessing executable 'git-annex' for git-annex-3.20130108...
+[269 of 299] Compiling Assistant.Threads.MountWatcher ( Assistant/Threads/MountWatcher.hs,
+ dist/build/git-annex/git-annex-tmp/Assistant/Threads/MountWatcher.o )
+
+Assistant/Threads/MountWatcher.hs:122:17: Not in scope: `gvfs'
+</pre>
+"""]]
diff --git a/doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_9_cf6221c585ee3dbf039bdaea71842d9b._comment b/doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_9_cf6221c585ee3dbf039bdaea71842d9b._comment
new file mode 100644
index 000000000..b5b66b8ea
--- /dev/null
+++ b/doc/bugs/Assistant_uses_obsolete_GDU_volume_monitor/comment_9_cf6221c585ee3dbf039bdaea71842d9b._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.238"
+ subject="comment 9"
+ date="2013-01-10T20:44:37Z"
+ content="""
+Realized that'd happen while away on a walk.. fixed now.
+
+"""]]
diff --git a/doc/bugs/Browser_fails_to_launch_on_Android___39__git_annex_webapp__39__.mdwn b/doc/bugs/Browser_fails_to_launch_on_Android___39__git_annex_webapp__39__.mdwn
new file mode 100644
index 000000000..8178e6dbc
--- /dev/null
+++ b/doc/bugs/Browser_fails_to_launch_on_Android___39__git_annex_webapp__39__.mdwn
@@ -0,0 +1,35 @@
+### Please describe the problem.
+
+When I launch git annex Android application, it fails to open the web browser. Workaround is to copy the url and manually paste it into web browser url line.
+
+### What steps will reproduce the problem?
+
+See above
+
+### What version of git-annex are you using? On what operating system?
+
+git-annex version 4.20130513-g5185533 on Android 4.2.2
+
+### Please provide any additional information below.
+
+[[!format sh """
+u0_a126@android:/sdcard/git-annex.home $ git annex webapp
+Launching web browser on http://127.0.0.1:47557/?auth=[...snip...]
+Starting: Intent { act=android.intent.action.VIEW dat=http://127.0.0.1:47557/?auth=[...snip...] }
+java.lang.SecurityException: Permission Denial: startActivity asks to run as user -2 but is calling from user 0; this requires android.permission.INTERACT_ACROSS_USERS_FULL
+ at android.os.Parcel.readException(Parcel.java:1425)
+ at android.os.Parcel.readException(Parcel.java:1379)
+ at android.app.ActivityManagerProxy.startActivityAsUser(ActivityManagerNative.java:1921)
+ at com.android.commands.am.Am.runStart(Am.java:494)
+ at com.android.commands.am.Am.run(Am.java:109)
+ at com.android.commands.am.Am.main(Am.java:82)
+ at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
+ at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:235)
+ at dalvik.system.NativeStart.main(Native Method)
+failed to start web browser
+u0_a126@android:/sdcard/git-annex.home $
+
+# End of transcript or log.
+"""]]
+
+[[done]], duplicate bug
diff --git a/doc/bugs/Browser_fails_to_launch_on_Android___39__git_annex_webapp__39__/comment_1_173393b0b3d2d8c622c0d8a2eaace421._comment b/doc/bugs/Browser_fails_to_launch_on_Android___39__git_annex_webapp__39__/comment_1_173393b0b3d2d8c622c0d8a2eaace421._comment
new file mode 100644
index 000000000..6104e6e75
--- /dev/null
+++ b/doc/bugs/Browser_fails_to_launch_on_Android___39__git_annex_webapp__39__/comment_1_173393b0b3d2d8c622c0d8a2eaace421._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmmLfBDEDFfEOba8Ra46nsnTmoNHFsLObo"
+ nickname="Brian"
+ subject="Duplicate bug report"
+ date="2013-05-15T02:35:34Z"
+ content="""
+This report is a duplicate of [[Android app permission denial on startup]]
+"""]]
diff --git a/doc/bugs/Build-depends_needs___39__hxt__39___added_-_3.20121127.mdwn b/doc/bugs/Build-depends_needs___39__hxt__39___added_-_3.20121127.mdwn
new file mode 100644
index 000000000..83720cca2
--- /dev/null
+++ b/doc/bugs/Build-depends_needs___39__hxt__39___added_-_3.20121127.mdwn
@@ -0,0 +1,36 @@
+What steps will reproduce the problem?
+
+Install git-annex via cabal - either from Hackage or as a manual install. (i.e. <http://git-annex.branchable.com/install/cabal/>)
+
+What is the expected output? What do you see instead?
+
+Expect a clean install.
+
+However, get the following error:
+
+ Assistant/Install.hs:24:8:
+ Could not find module `Data.AssocList'
+ It is a member of the hidden package `hxt-9.3.1.1'.
+ Perhaps you need to add `hxt' to the build-depends in your .cabal file.
+ Use -v to see a list of the files searched for.
+
+
+What version of git-annex are you using? On what operating system?
+
+git-annex: 3.20121127
+OS: Mac OSX 10.6.8
+
+Please provide any additional information below.
+
+The fix seems to be as simple as adding 'htx' to the 'git-annex.cabal' file:
+
+ Executable git-annex
+ Main-Is: git-annex.hs
+ Build-Depends: MissingH, hslogger, directory, filepath,
+ unix, containers, utf8-string, network (>= 2.0), mtl (>= 2.1.1),
+ bytestring, old-locale, time,
+ -- Added htx here
+ hxt,
+ pcre-light, extensible-exceptions, dataenc, SHA, process, json, HTTP,
+
+> I removed the need for hxt, which was accidental. [[done]] --[[Joey]]
diff --git a/doc/bugs/Build_error_on_Linux.mdwn b/doc/bugs/Build_error_on_Linux.mdwn
new file mode 100644
index 000000000..af560788a
--- /dev/null
+++ b/doc/bugs/Build_error_on_Linux.mdwn
@@ -0,0 +1,29 @@
+### Please describe the problem.
+Building on Linux, with a particular combination of flags, failed due to missing `async`.
+
+### What steps will reproduce the problem?
+1. Configure with the following flag combination
+
+ cryptohash -quvi -feed tdfa -testsuite -android production -dns -xmpp -pairing -webapp -assistant dbus inotify -webdav s3
+
+2. Attempt to build and you'll get an error on line 16 of `Utility/Batch.hs` because `Control.Concurrent.Async` isn't available.
+
+### What version of git-annex are you using? On what operating system?
+Version 4.20131024 on Linux
+
+### Please provide any additional information below.
+
+This is the patch I applied to `git-annex.cabal`:
+
+ CPP-Options: -DWITH_KQUEUE
+ C-Sources: Utility/libkqueue.c
+
+ + if os(linux)
+ + Build-Depends: async
+ +
+ if os(linux) && flag(Dbus)
+ Build-Depends: dbus (>= 0.10.3)
+ CPP-Options: -DWITH_DBUS
+
+> Feel async is core enough it should depend on it unconditionally.
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/Build_error_on_Mac_OSX_10.6.mdwn b/doc/bugs/Build_error_on_Mac_OSX_10.6.mdwn
new file mode 100644
index 000000000..43fb0323c
--- /dev/null
+++ b/doc/bugs/Build_error_on_Mac_OSX_10.6.mdwn
@@ -0,0 +1,11 @@
+While following the instructions given at the OSX build page , I get this error:
+
+$ make
+ghc -O2 -Wall -ignore-package monads-fd -fspec-constr-count=5 --make git-annex
+
+Utility/JSONStream.hs:14:8:
+ Could not find module `Text.JSON':
+ Use -v to see a list of the files searched for.
+make: *** [git-annex] Error 1
+
+> Updated the instructions. [[done]] --[[Joey]]
diff --git a/doc/bugs/Build_failure_at_commit_1efe4f3.mdwn b/doc/bugs/Build_failure_at_commit_1efe4f3.mdwn
new file mode 100644
index 000000000..ba87b1191
--- /dev/null
+++ b/doc/bugs/Build_failure_at_commit_1efe4f3.mdwn
@@ -0,0 +1,45 @@
+Applying this
+
+<pre>
+laplace:git-annex jtang$ git diff
+diff --git a/Assistant/WebApp/Configurators.hs b/Assistant/WebApp/Configurators.hs
+index b9630b1..bf36e59 100644
+--- a/Assistant/WebApp/Configurators.hs
++++ b/Assistant/WebApp/Configurators.hs
+@@ -101,7 +101,7 @@ checkRepositoryPath p = do
+ -
+ - If run in another directory, the user probably wants to put it there. -}
+ defaultRepositoryPath :: Bool -> IO FilePath
+-defaultRepositoryPath firstrun = do
++defaultRepositoryPath firstRun = do
+ cwd <- liftIO $ getCurrentDirectory
+ home <- myHomeDir
+ if home == cwd && firstRun
+</pre>
+
+Causes this to occur,
+
+<pre>
+Assistant/WebApp/Configurators.hs:114:17:
+ Couldn't match expected type `Control.Monad.Trans.RWS.Lazy.RWST
+ (Maybe (Env, FileEnv), WebApp, [Yesod.Form.Types.Lang])
+ Enctype
+ Ints
+ (GHandler WebApp WebApp)
+ t0'
+ with actual type `Text'
+ Expected type: String
+ -> Control.Monad.Trans.RWS.Lazy.RWST
+ (Maybe (Env, FileEnv), WebApp, [Yesod.Form.Types.Lang])
+ Enctype
+ Ints
+ (GHandler WebApp WebApp)
+ t0
+ Actual type: String -> Text
+ In the first argument of `(.)', namely `T.pack'
+ In the first argument of `(<$>)', namely
+ `T.pack . addTrailingPathSeparator'
+make: *** [git-annex] Error 1
+</pre>
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/Building_fails:_Could_not_find_module___96__Text.Blaze__39__.mdwn b/doc/bugs/Building_fails:_Could_not_find_module___96__Text.Blaze__39__.mdwn
new file mode 100644
index 000000000..b75d92e18
--- /dev/null
+++ b/doc/bugs/Building_fails:_Could_not_find_module___96__Text.Blaze__39__.mdwn
@@ -0,0 +1,105 @@
+What steps will reproduce the problem?
+
+<pre>
+dominik@Atlantis:/var/tmp$ git clone git://github.com/joeyh/git-annex.git
+Cloning into 'git-annex'...
+remote: Counting objects: 40580, done.
+remote: Compressing objects: 100% (10514/10514), done.
+remote: Total 40580 (delta 29914), reused 40502 (delta 29837)
+Receiving objects: 100% (40580/40580), 9.17 MiB | 238 KiB/s, done.
+Resolving deltas: 100% (29914/29914), done.
+dominik@Atlantis:/var/tmp$ cd git-annex/
+dominik@Atlantis:/var/tmp/git-annex$ cabal update
+Downloading the latest package list from hackage.haskell.org
+dominik@Atlantis:/var/tmp/git-annex$ cabal install --only-dependencies
+Resolving dependencies...
+All the requested packages are already installed:
+Use --reinstall if you want to reinstall anyway.
+dominik@Atlantis:/var/tmp/git-annex$ cabal configure
+Resolving dependencies...
+[ 1 of 21] Compiling Utility.FileSystemEncoding ( Utility/FileSystemEncoding.hs, dist/setup/Utility/FileSystemEncoding.o )
+[ 2 of 21] Compiling Utility.Applicative ( Utility/Applicative.hs, dist/setup/Utility/Applicative.o )
+[ 3 of 21] Compiling Utility.PartialPrelude ( Utility/PartialPrelude.hs, dist/setup/Utility/PartialPrelude.o )
+[ 4 of 21] Compiling Utility.UserInfo ( Utility/UserInfo.hs, dist/setup/Utility/UserInfo.o )
+[ 5 of 21] Compiling Utility.Monad ( Utility/Monad.hs, dist/setup/Utility/Monad.o )
+[ 6 of 21] Compiling Utility.Path ( Utility/Path.hs, dist/setup/Utility/Path.o )
+[ 7 of 21] Compiling Utility.OSX ( Utility/OSX.hs, dist/setup/Utility/OSX.o )
+[ 8 of 21] Compiling Utility.Exception ( Utility/Exception.hs, dist/setup/Utility/Exception.o )
+[ 9 of 21] Compiling Utility.TempFile ( Utility/TempFile.hs, dist/setup/Utility/TempFile.o )
+[10 of 21] Compiling Utility.Misc ( Utility/Misc.hs, dist/setup/Utility/Misc.o )
+[11 of 21] Compiling Utility.Process ( Utility/Process.hs, dist/setup/Utility/Process.o )
+[12 of 21] Compiling Utility.FreeDesktop ( Utility/FreeDesktop.hs, dist/setup/Utility/FreeDesktop.o )
+[13 of 21] Compiling Assistant.Install.AutoStart ( Assistant/Install/AutoStart.hs, dist/setup/Assistant/Install/AutoStart.o )
+[14 of 21] Compiling Utility.SafeCommand ( Utility/SafeCommand.hs, dist/setup/Utility/SafeCommand.o )
+[15 of 21] Compiling Utility.Directory ( Utility/Directory.hs, dist/setup/Utility/Directory.o )
+[16 of 21] Compiling Common ( Common.hs, dist/setup/Common.o )
+[17 of 21] Compiling Locations.UserConfig ( Locations/UserConfig.hs, dist/setup/Locations/UserConfig.o )
+[18 of 21] Compiling Build.TestConfig ( Build/TestConfig.hs, dist/setup/Build/TestConfig.o )
+[19 of 21] Compiling Build.Configure ( Build/Configure.hs, dist/setup/Build/Configure.o )
+[20 of 21] Compiling Build.InstallDesktopFile ( Build/InstallDesktopFile.hs, dist/setup/Build/InstallDesktopFile.o )
+[21 of 21] Compiling Main ( Setup.hs, dist/setup/Main.o )
+Linking ./dist/setup/setup ...
+ checking version... 3.20121018
+ checking git... yes
+ checking git version... 1.7.10.4
+ checking cp -a... yes
+ checking cp -p... yes
+ checking cp --reflink=auto... yes
+ checking uuid generator... uuidgen
+ checking xargs -0... yes
+ checking rsync... yes
+ checking curl... yes
+ checking wget... yes
+ checking bup... no
+ checking gpg... yes
+ checking lsof... yes
+ checking host... no
+ checking ssh connection caching... yes
+ checking sha1... sha1sum
+ checking sha256... sha256sum
+ checking sha512... sha512sum
+ checking sha224... sha224sum
+ checking sha384... sha384sum
+Configuring git-annex-3.20121018...
+dominik@Atlantis:/var/tmp/git-annex$ cabal build
+Building git-annex-3.20121018...
+Preprocessing executable 'git-annex' for git-annex-3.20121018...
+
+Assistant/Alert.hs:21:8:
+ Could not find module `Text.Blaze'
+ It is a member of the hidden package `blaze-markup-0.5.1.1'.
+ Perhaps you need to add `blaze-markup' to the build-depends in your .cabal file.
+ Use -v to see a list of the files searched for.
+</pre>
+
+What is the expected output? What do you see instead?
+
+I expect the latest git HEAD to build without an error message or provide me with a package I need to install. Instead the error above is shown. In fact the package requested is installed:
+
+<pre>
+dominik@Atlantis:/var/tmp/git-annex$ cabal install blaze-markup
+Resolving dependencies...
+All the requested packages are already installed:
+blaze-markup-0.5.1.1
+Use --reinstall if you want to reinstall anyway.
+</pre>
+
+What version of git-annex are you using? On what operating system?
+
+git HEAD, Ubuntu 12.10
+
+Please provide any additional information below.
+
+<pre>
+$ cabal --version
+cabal-install version 0.14.0
+using version 1.14.0 of the Cabal library
+
+$ ghc --version
+The Glorious Glasgow Haskell Compilation System, version 7.4.2
+
+$ uname -a
+Linux Atlantis 3.5.0-17-generic #28-Ubuntu SMP Tue Oct 9 19:31:23 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
+</pre>
+
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/Building_fails:_Not_in_scope:___96__myHomeDir__39___.mdwn b/doc/bugs/Building_fails:_Not_in_scope:___96__myHomeDir__39___.mdwn
new file mode 100644
index 000000000..e1d2da4ce
--- /dev/null
+++ b/doc/bugs/Building_fails:_Not_in_scope:___96__myHomeDir__39___.mdwn
@@ -0,0 +1,56 @@
+What steps will reproduce the problem?
+
+Building of the current github HEAD fails with a strange error message regarding OSX. I'm not using OSX but Ubuntu 12.10, why is cabal trying to build these files?
+
+<pre>
+dominik@Atlantis:/var/tmp$ git clone git://github.com/joeyh/git-annex.git
+Cloning into 'git-annex'...
+remote: Counting objects: 40243, done.
+remote: Compressing objects: 100% (10568/10568), done.
+remote: Total 40243 (delta 29647), reused 40044 (delta 29449)
+Receiving objects: 100% (40243/40243), 9.12 MiB | 184 KiB/s, done.
+Resolving deltas: 100% (29647/29647), done.
+dominik@Atlantis:/var/tmp$ cd git-annex/
+dominik@Atlantis:/var/tmp/git-annex$ cabal update
+Downloading the latest package list from hackage.haskell.org
+dominik@Atlantis:/var/tmp/git-annex$ cabal install --only-dependencies
+Resolving dependencies...
+All the requested packages are already installed:
+Use --reinstall if you want to reinstall anyway.
+dominik@Atlantis:/var/tmp/git-annex$ cabal configure
+Resolving dependencies...
+[ 1 of 21] Compiling Utility.FileSystemEncoding ( Utility/FileSystemEncoding.hs, dist/setup/Utility/FileSystemEncoding.o )
+[ 2 of 21] Compiling Utility.Applicative ( Utility/Applicative.hs, dist/setup/Utility/Applicative.o )
+[ 3 of 21] Compiling Utility.PartialPrelude ( Utility/PartialPrelude.hs, dist/setup/Utility/PartialPrelude.o )
+[ 4 of 21] Compiling Utility.UserInfo ( Utility/UserInfo.hs, dist/setup/Utility/UserInfo.o )
+[ 5 of 21] Compiling Utility.Monad ( Utility/Monad.hs, dist/setup/Utility/Monad.o )
+[ 6 of 21] Compiling Utility.Path ( Utility/Path.hs, dist/setup/Utility/Path.o )
+[ 7 of 21] Compiling Utility.OSX ( Utility/OSX.hs, dist/setup/Utility/OSX.o )
+
+Utility/OSX.hs:22:17: Not in scope: `myHomeDir'
+</pre>
+
+What is the expected output? What do you see instead?
+
+I expect cabal to build git-annex.
+
+What version of git-annex are you using? On what operating system?
+
+github HEAD on Ubuntu 12.10
+
+Please provide any additional information below.
+
+<pre>
+$ cabal --version
+cabal-install version 0.14.0
+using version 1.14.0 of the Cabal library
+
+$ ghc --version
+The Glorious Glasgow Haskell Compilation System, version 7.4.2
+
+$ uname -a
+Linux Atlantis 3.5.0-17-generic #28-Ubuntu SMP Tue Oct 9 19:31:23 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
+
+</pre>
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/Building_fails:__Could_not_find_module___96__Data.XML.Types__39__.mdwn b/doc/bugs/Building_fails:__Could_not_find_module___96__Data.XML.Types__39__.mdwn
new file mode 100644
index 000000000..c03353436
--- /dev/null
+++ b/doc/bugs/Building_fails:__Could_not_find_module___96__Data.XML.Types__39__.mdwn
@@ -0,0 +1,82 @@
+What steps will reproduce the problem?
+
+<pre>
+dominik@Atlantis:/var/tmp$ git clone git://github.com/joeyh/git-annex.git
+Cloning into 'git-annex'...
+remote: Counting objects: 40841, done.
+remote: Compressing objects: 100% (10648/10648), done.
+remote: Total 40841 (delta 30135), reused 40669 (delta 29964)
+Receiving objects: 100% (40841/40841), 9.21 MiB | 517 KiB/s, done.
+Resolving deltas: 100% (30135/30135), done.
+dominik@Atlantis:/var/tmp/git-annex$ cabal install --only-dependencies
+Resolving dependencies...
+All the requested packages are already installed:
+Use --reinstall if you want to reinstall anyway.
+dominik@Atlantis:/var/tmp/git-annex$ cabal configure
+Resolving dependencies...
+[ 1 of 21] Compiling Utility.FileSystemEncoding ( Utility/FileSystemEncoding.hs, dist/setup/Utility/FileSystemEncoding.o )
+[ 2 of 21] Compiling Utility.Applicative ( Utility/Applicative.hs, dist/setup/Utility/Applicative.o )
+[ 3 of 21] Compiling Utility.PartialPrelude ( Utility/PartialPrelude.hs, dist/setup/Utility/PartialPrelude.o )
+[ 4 of 21] Compiling Utility.UserInfo ( Utility/UserInfo.hs, dist/setup/Utility/UserInfo.o )
+[ 5 of 21] Compiling Utility.Monad ( Utility/Monad.hs, dist/setup/Utility/Monad.o )
+[ 6 of 21] Compiling Utility.Path ( Utility/Path.hs, dist/setup/Utility/Path.o )
+[ 7 of 21] Compiling Utility.OSX ( Utility/OSX.hs, dist/setup/Utility/OSX.o )
+[ 8 of 21] Compiling Utility.Exception ( Utility/Exception.hs, dist/setup/Utility/Exception.o )
+[ 9 of 21] Compiling Utility.TempFile ( Utility/TempFile.hs, dist/setup/Utility/TempFile.o )
+[10 of 21] Compiling Utility.Misc ( Utility/Misc.hs, dist/setup/Utility/Misc.o )
+[11 of 21] Compiling Utility.Process ( Utility/Process.hs, dist/setup/Utility/Process.o )
+[12 of 21] Compiling Utility.FreeDesktop ( Utility/FreeDesktop.hs, dist/setup/Utility/FreeDesktop.o )
+[13 of 21] Compiling Assistant.Install.AutoStart ( Assistant/Install/AutoStart.hs, dist/setup/Assistant/Install/AutoStart.o )
+[14 of 21] Compiling Utility.SafeCommand ( Utility/SafeCommand.hs, dist/setup/Utility/SafeCommand.o )
+[15 of 21] Compiling Utility.Directory ( Utility/Directory.hs, dist/setup/Utility/Directory.o )
+[16 of 21] Compiling Common ( Common.hs, dist/setup/Common.o )
+[17 of 21] Compiling Locations.UserConfig ( Locations/UserConfig.hs, dist/setup/Locations/UserConfig.o )
+[18 of 21] Compiling Build.TestConfig ( Build/TestConfig.hs, dist/setup/Build/TestConfig.o )
+[19 of 21] Compiling Build.Configure ( Build/Configure.hs, dist/setup/Build/Configure.o )
+[20 of 21] Compiling Build.InstallDesktopFile ( Build/InstallDesktopFile.hs, dist/setup/Build/InstallDesktopFile.o )
+[21 of 21] Compiling Main ( Setup.hs, dist/setup/Main.o )
+Linking ./dist/setup/setup ...
+ checking version... 3.20121018
+ checking git... yes
+ checking git version... 1.7.10.4
+ checking cp -a... yes
+ checking cp -p... yes
+ checking cp --reflink=auto... yes
+ checking uuid generator... uuidgen
+ checking xargs -0... yes
+ checking rsync... yes
+ checking curl... yes
+ checking wget... yes
+ checking bup... no
+ checking gpg... yes
+ checking lsof... yes
+ checking ssh connection caching... yes
+ checking sha1... sha1sum
+ checking sha256... sha256sum
+ checking sha512... sha512sum
+ checking sha224... sha224sum
+ checking sha384... sha384sum
+Configuring git-annex-3.20121018...
+dominik@Atlantis:/var/tmp/git-annex$ cabal build
+Building git-annex-3.20121018...
+Preprocessing executable 'git-annex' for git-annex-3.20121018...
+
+Assistant/XMPP.hs:18:8:
+ Could not find module `Data.XML.Types'
+ It is a member of the hidden package `xml-types-0.3.3'.
+ Perhaps you need to add `xml-types' to the build-depends in your .cabal file.
+ Use -v to see a list of the files searched for.
+</pre>
+
+What is the expected output? What do you see instead?
+
+I exepect the current git HEAD to build without errors.
+
+What version of git-annex are you using? On what operating system?
+
+git-annex HEAD from git, Ubuntu 12.10
+
+Please provide any additional information below.
+
+> [[done]] --[[Joey]] (and tested the whole cabal build, which I usually
+> only do on releases)
diff --git a/doc/bugs/Building_fails:___Not_in_scope:_type_constructor_or_class___96__Html__39__.mdwn b/doc/bugs/Building_fails:___Not_in_scope:_type_constructor_or_class___96__Html__39__.mdwn
new file mode 100644
index 000000000..6459e3f2e
--- /dev/null
+++ b/doc/bugs/Building_fails:___Not_in_scope:_type_constructor_or_class___96__Html__39__.mdwn
@@ -0,0 +1,189 @@
+What steps will reproduce the problem?
+
+<pre>
+dominik@Atlantis:/var/tmp/git-annex$ cabal build
+Building git-annex-3.20121018...
+Preprocessing executable 'git-annex' for git-annex-3.20121018...
+
+Assistant/Threads/NetWatcher.hs:26:2:
+ warning: #warning Building without dbus support; will poll for network connection changes [-Wcpp]
+
+Assistant/Threads/MountWatcher.hs:33:2:
+ warning: #warning Building without dbus support; will use mtab polling [-Wcpp]
+[ 1 of 270] Compiling Utility.Dot ( Utility/Dot.hs, dist/build/git-annex/git-annex-tmp/Utility/Dot.o )
+[ 2 of 270] Compiling Utility.ThreadLock ( Utility/ThreadLock.hs, dist/build/git-annex/git-annex-tmp/Utility/ThreadLock.o )
+[ 3 of 270] Compiling Utility.Mounts ( dist/build/git-annex/git-annex-tmp/Utility/Mounts.hs, dist/build/git-annex/git-annex-tmp/Utility/Mounts.o )
+[ 4 of 270] Compiling Utility.Yesod ( Utility/Yesod.hs, dist/build/git-annex/git-annex-tmp/Utility/Yesod.o )
+[ 5 of 270] Compiling Utility.Tense ( Utility/Tense.hs, dist/build/git-annex/git-annex-tmp/Utility/Tense.o )
+[ 6 of 270] Compiling Utility.Verifiable ( Utility/Verifiable.hs, dist/build/git-annex/git-annex-tmp/Utility/Verifiable.o )
+[ 7 of 270] Compiling Assistant.Types.TransferSlots ( Assistant/Types/TransferSlots.hs, dist/build/git-annex/git-annex-tmp/Assistant/Types/TransferSlots.o )
+[ 8 of 270] Compiling Types.StandardGroups ( Types/StandardGroups.hs, dist/build/git-annex/git-annex-tmp/Types/StandardGroups.o )
+[ 9 of 270] Compiling Utility.Percentage ( Utility/Percentage.hs, dist/build/git-annex/git-annex-tmp/Utility/Percentage.o )
+[ 10 of 270] Compiling Utility.Base64 ( Utility/Base64.hs, dist/build/git-annex/git-annex-tmp/Utility/Base64.o )
+[ 11 of 270] Compiling Utility.DataUnits ( Utility/DataUnits.hs, dist/build/git-annex/git-annex-tmp/Utility/DataUnits.o )
+[ 12 of 270] Compiling Utility.JSONStream ( Utility/JSONStream.hs, dist/build/git-annex/git-annex-tmp/Utility/JSONStream.o )
+[ 13 of 270] Compiling Messages.JSON ( Messages/JSON.hs, dist/build/git-annex/git-annex-tmp/Messages/JSON.o )
+[ 14 of 270] Compiling Build.SysConfig ( Build/SysConfig.hs, dist/build/git-annex/git-annex-tmp/Build/SysConfig.o )
+[ 15 of 270] Compiling Types.KeySource ( Types/KeySource.hs, dist/build/git-annex/git-annex-tmp/Types/KeySource.o )
+[ 16 of 270] Compiling Utility.State ( Utility/State.hs, dist/build/git-annex/git-annex-tmp/Utility/State.o )
+[ 17 of 270] Compiling Types.UUID ( Types/UUID.hs, dist/build/git-annex/git-annex-tmp/Types/UUID.o )
+[ 18 of 270] Compiling Types.Messages ( Types/Messages.hs, dist/build/git-annex/git-annex-tmp/Types/Messages.o )
+[ 19 of 270] Compiling Types.Group ( Types/Group.hs, dist/build/git-annex/git-annex-tmp/Types/Group.o )
+[ 20 of 270] Compiling Types.TrustLevel ( Types/TrustLevel.hs, dist/build/git-annex/git-annex-tmp/Types/TrustLevel.o )
+[ 21 of 270] Compiling Types.BranchState ( Types/BranchState.hs, dist/build/git-annex/git-annex-tmp/Types/BranchState.o )
+[ 22 of 270] Compiling Utility.UserInfo ( Utility/UserInfo.hs, dist/build/git-annex/git-annex-tmp/Utility/UserInfo.o )
+[ 23 of 270] Compiling Utility.PartialPrelude ( Utility/PartialPrelude.hs, dist/build/git-annex/git-annex-tmp/Utility/PartialPrelude.o )
+[ 24 of 270] Compiling Utility.HumanTime ( Utility/HumanTime.hs, dist/build/git-annex/git-annex-tmp/Utility/HumanTime.o )
+[ 25 of 270] Compiling Utility.Format ( Utility/Format.hs, dist/build/git-annex/git-annex-tmp/Utility/Format.o )
+[ 26 of 270] Compiling Utility.FileSystemEncoding ( Utility/FileSystemEncoding.hs, dist/build/git-annex/git-annex-tmp/Utility/FileSystemEncoding.o )
+[ 27 of 270] Compiling Utility.Touch ( dist/build/git-annex/git-annex-tmp/Utility/Touch.hs, dist/build/git-annex/git-annex-tmp/Utility/Touch.o )
+[ 28 of 270] Compiling Utility.Applicative ( Utility/Applicative.hs, dist/build/git-annex/git-annex-tmp/Utility/Applicative.o )
+[ 29 of 270] Compiling Utility.Monad ( Utility/Monad.hs, dist/build/git-annex/git-annex-tmp/Utility/Monad.o )
+[ 30 of 270] Compiling Utility.Path ( Utility/Path.hs, dist/build/git-annex/git-annex-tmp/Utility/Path.o )
+[ 31 of 270] Compiling Utility.Exception ( Utility/Exception.hs, dist/build/git-annex/git-annex-tmp/Utility/Exception.o )
+[ 32 of 270] Compiling Utility.TempFile ( Utility/TempFile.hs, dist/build/git-annex/git-annex-tmp/Utility/TempFile.o )
+[ 33 of 270] Compiling Utility.Misc ( Utility/Misc.hs, dist/build/git-annex/git-annex-tmp/Utility/Misc.o )
+[ 34 of 270] Compiling Utility.Process ( Utility/Process.hs, dist/build/git-annex/git-annex-tmp/Utility/Process.o )
+[ 35 of 270] Compiling Utility.SafeCommand ( Utility/SafeCommand.hs, dist/build/git-annex/git-annex-tmp/Utility/SafeCommand.o )
+[ 36 of 270] Compiling Utility.Directory ( Utility/Directory.hs, dist/build/git-annex/git-annex-tmp/Utility/Directory.o )
+[ 37 of 270] Compiling Utility.Network ( Utility/Network.hs, dist/build/git-annex/git-annex-tmp/Utility/Network.o )
+[ 38 of 270] Compiling Utility.FreeDesktop ( Utility/FreeDesktop.hs, dist/build/git-annex/git-annex-tmp/Utility/FreeDesktop.o )
+[ 39 of 270] Compiling Assistant.Install.AutoStart ( Assistant/Install/AutoStart.hs, dist/build/git-annex/git-annex-tmp/Assistant/Install/AutoStart.o )
+[ 40 of 270] Compiling Utility.SRV ( Utility/SRV.hs, dist/build/git-annex/git-annex-tmp/Utility/SRV.o )
+[ 41 of 270] Compiling Git.Types ( Git/Types.hs, dist/build/git-annex/git-annex-tmp/Git/Types.o )
+[ 42 of 270] Compiling Common ( Common.hs, dist/build/git-annex/git-annex-tmp/Common.o )
+[ 43 of 270] Compiling Utility.FileMode ( Utility/FileMode.hs, dist/build/git-annex/git-annex-tmp/Utility/FileMode.o )
+[ 44 of 270] Compiling Git ( Git.hs, dist/build/git-annex/git-annex-tmp/Git.o )
+[ 45 of 270] Compiling Git.FilePath ( Git/FilePath.hs, dist/build/git-annex/git-annex-tmp/Git/FilePath.o )
+[ 46 of 270] Compiling Utility.Matcher ( Utility/Matcher.hs, dist/build/git-annex/git-annex-tmp/Utility/Matcher.o )
+[ 47 of 270] Compiling Utility.Gpg ( Utility/Gpg.hs, dist/build/git-annex/git-annex-tmp/Utility/Gpg.o )
+[ 48 of 270] Compiling Types.Crypto ( Types/Crypto.hs, dist/build/git-annex/git-annex-tmp/Types/Crypto.o )
+[ 49 of 270] Compiling Types.Key ( Types/Key.hs, dist/build/git-annex/git-annex-tmp/Types/Key.o )
+[ 50 of 270] Compiling Types.Backend ( Types/Backend.hs, dist/build/git-annex/git-annex-tmp/Types/Backend.o )
+[ 51 of 270] Compiling Types.Remote ( Types/Remote.hs, dist/build/git-annex/git-annex-tmp/Types/Remote.o )
+[ 52 of 270] Compiling Git.Sha ( Git/Sha.hs, dist/build/git-annex/git-annex-tmp/Git/Sha.o )
+[ 53 of 270] Compiling Utility.CoProcess ( Utility/CoProcess.hs, dist/build/git-annex/git-annex-tmp/Utility/CoProcess.o )
+[ 54 of 270] Compiling Git.Command ( Git/Command.hs, dist/build/git-annex/git-annex-tmp/Git/Command.o )
+[ 55 of 270] Compiling Git.Ref ( Git/Ref.hs, dist/build/git-annex/git-annex-tmp/Git/Ref.o )
+[ 56 of 270] Compiling Git.Branch ( Git/Branch.hs, dist/build/git-annex/git-annex-tmp/Git/Branch.o )
+[ 57 of 270] Compiling Git.UpdateIndex ( Git/UpdateIndex.hs, dist/build/git-annex/git-annex-tmp/Git/UpdateIndex.o )
+[ 58 of 270] Compiling Git.Queue ( Git/Queue.hs, dist/build/git-annex/git-annex-tmp/Git/Queue.o )
+[ 59 of 270] Compiling Git.HashObject ( Git/HashObject.hs, dist/build/git-annex/git-annex-tmp/Git/HashObject.o )
+[ 60 of 270] Compiling Git.CatFile ( Git/CatFile.hs, dist/build/git-annex/git-annex-tmp/Git/CatFile.o )
+[ 61 of 270] Compiling Git.UnionMerge ( Git/UnionMerge.hs, dist/build/git-annex/git-annex-tmp/Git/UnionMerge.o )
+[ 62 of 270] Compiling Git.Url ( Git/Url.hs, dist/build/git-annex/git-annex-tmp/Git/Url.o )
+[ 63 of 270] Compiling Git.Construct ( Git/Construct.hs, dist/build/git-annex/git-annex-tmp/Git/Construct.o )
+[ 64 of 270] Compiling Git.Config ( Git/Config.hs, dist/build/git-annex/git-annex-tmp/Git/Config.o )
+[ 65 of 270] Compiling Git.SharedRepository ( Git/SharedRepository.hs, dist/build/git-annex/git-annex-tmp/Git/SharedRepository.o )
+[ 66 of 270] Compiling Git.Version ( Git/Version.hs, dist/build/git-annex/git-annex-tmp/Git/Version.o )
+[ 67 of 270] Compiling Git.CheckAttr ( Git/CheckAttr.hs, dist/build/git-annex/git-annex-tmp/Git/CheckAttr.o )
+[ 68 of 270] Compiling Annex ( Annex.hs, dist/build/git-annex/git-annex-tmp/Annex.o )
+[ 69 of 270] Compiling Types.Option ( Types/Option.hs, dist/build/git-annex/git-annex-tmp/Types/Option.o )
+[ 70 of 270] Compiling Types ( Types.hs, dist/build/git-annex/git-annex-tmp/Types.o )
+[ 71 of 270] Compiling Messages ( Messages.hs, dist/build/git-annex/git-annex-tmp/Messages.o )
+[ 72 of 270] Compiling Types.Command ( Types/Command.hs, dist/build/git-annex/git-annex-tmp/Types/Command.o )
+[ 73 of 270] Compiling Locations ( Locations.hs, dist/build/git-annex/git-annex-tmp/Locations.o )
+[ 74 of 270] Compiling Common.Annex ( Common/Annex.hs, dist/build/git-annex/git-annex-tmp/Common/Annex.o )
+[ 75 of 270] Compiling Fields ( Fields.hs, dist/build/git-annex/git-annex-tmp/Fields.o )
+[ 76 of 270] Compiling Annex.BranchState ( Annex/BranchState.hs, dist/build/git-annex/git-annex-tmp/Annex/BranchState.o )
+[ 77 of 270] Compiling Annex.CatFile ( Annex/CatFile.hs, dist/build/git-annex/git-annex-tmp/Annex/CatFile.o )
+[ 78 of 270] Compiling Annex.Perms ( Annex/Perms.hs, dist/build/git-annex/git-annex-tmp/Annex/Perms.o )
+[ 79 of 270] Compiling Crypto ( Crypto.hs, dist/build/git-annex/git-annex-tmp/Crypto.o )
+[ 80 of 270] Compiling Annex.Exception ( Annex/Exception.hs, dist/build/git-annex/git-annex-tmp/Annex/Exception.o )
+[ 81 of 270] Compiling Annex.Journal ( Annex/Journal.hs, dist/build/git-annex/git-annex-tmp/Annex/Journal.o )
+[ 82 of 270] Compiling Annex.Branch ( Annex/Branch.hs, dist/build/git-annex/git-annex-tmp/Annex/Branch.o )
+[ 83 of 270] Compiling Usage ( Usage.hs, dist/build/git-annex/git-annex-tmp/Usage.o )
+[ 84 of 270] Compiling Annex.CheckAttr ( Annex/CheckAttr.hs, dist/build/git-annex/git-annex-tmp/Annex/CheckAttr.o )
+[ 85 of 270] Compiling Remote.Helper.Special ( Remote/Helper/Special.hs, dist/build/git-annex/git-annex-tmp/Remote/Helper/Special.o )
+[ 86 of 270] Compiling Logs.Presence ( Logs/Presence.hs, dist/build/git-annex/git-annex-tmp/Logs/Presence.o )
+[ 87 of 270] Compiling Logs.Location ( Logs/Location.hs, dist/build/git-annex/git-annex-tmp/Logs/Location.o )
+[ 88 of 270] Compiling Logs.Web ( Logs/Web.hs, dist/build/git-annex/git-annex-tmp/Logs/Web.o )
+[ 89 of 270] Compiling Annex.LockPool ( Annex/LockPool.hs, dist/build/git-annex/git-annex-tmp/Annex/LockPool.o )
+[ 90 of 270] Compiling Logs.Transfer ( Logs/Transfer.hs, dist/build/git-annex/git-annex-tmp/Logs/Transfer.o )
+[ 91 of 270] Compiling Backend.SHA ( Backend/SHA.hs, dist/build/git-annex/git-annex-tmp/Backend/SHA.o )
+[ 92 of 270] Compiling Backend.WORM ( Backend/WORM.hs, dist/build/git-annex/git-annex-tmp/Backend/WORM.o )
+[ 93 of 270] Compiling Backend.URL ( Backend/URL.hs, dist/build/git-annex/git-annex-tmp/Backend/URL.o )
+[ 94 of 270] Compiling Assistant.Ssh ( Assistant/Ssh.hs, dist/build/git-annex/git-annex-tmp/Assistant/Ssh.o )
+[ 95 of 270] Compiling Assistant.Types.ThreadedMonad ( Assistant/Types/ThreadedMonad.hs, dist/build/git-annex/git-annex-tmp/Assistant/Types/ThreadedMonad.o )
+[ 96 of 270] Compiling Assistant.Types.ScanRemotes ( Assistant/Types/ScanRemotes.hs, dist/build/git-annex/git-annex-tmp/Assistant/Types/ScanRemotes.o )
+[ 97 of 270] Compiling Assistant.Types.TransferQueue ( Assistant/Types/TransferQueue.hs, dist/build/git-annex/git-annex-tmp/Assistant/Types/TransferQueue.o )
+[ 98 of 270] Compiling Assistant.Types.BranchChange ( Assistant/Types/BranchChange.hs, dist/build/git-annex/git-annex-tmp/Assistant/Types/BranchChange.o )
+[ 99 of 270] Compiling Assistant.Pairing ( Assistant/Pairing.hs, dist/build/git-annex/git-annex-tmp/Assistant/Pairing.o )
+[100 of 270] Compiling Logs.UUIDBased ( Logs/UUIDBased.hs, dist/build/git-annex/git-annex-tmp/Logs/UUIDBased.o )
+[101 of 270] Compiling Logs.Remote ( Logs/Remote.hs, dist/build/git-annex/git-annex-tmp/Logs/Remote.o )
+[102 of 270] Compiling Logs.Group ( Logs/Group.hs, dist/build/git-annex/git-annex-tmp/Logs/Group.o )
+[103 of 270] Compiling Utility.DiskFree ( Utility/DiskFree.hs, dist/build/git-annex/git-annex-tmp/Utility/DiskFree.o )
+[104 of 270] Compiling Utility.Url ( Utility/Url.hs, dist/build/git-annex/git-annex-tmp/Utility/Url.o )
+[105 of 270] Compiling Utility.CopyFile ( Utility/CopyFile.hs, dist/build/git-annex/git-annex-tmp/Utility/CopyFile.o )
+[106 of 270] Compiling Utility.Rsync ( Utility/Rsync.hs, dist/build/git-annex/git-annex-tmp/Utility/Rsync.o )
+[107 of 270] Compiling Git.LsFiles ( Git/LsFiles.hs, dist/build/git-annex/git-annex-tmp/Git/LsFiles.o )
+[108 of 270] Compiling Git.AutoCorrect ( Git/AutoCorrect.hs, dist/build/git-annex/git-annex-tmp/Git/AutoCorrect.o )
+[109 of 270] Compiling Git.CurrentRepo ( Git/CurrentRepo.hs, dist/build/git-annex/git-annex-tmp/Git/CurrentRepo.o )
+[110 of 270] Compiling Git.Merge ( Git/Merge.hs, dist/build/git-annex/git-annex-tmp/Git/Merge.o )
+[111 of 270] Compiling Utility.WebApp ( Utility/WebApp.hs, dist/build/git-annex/git-annex-tmp/Utility/WebApp.o )
+[112 of 270] Compiling Utility.Daemon ( Utility/Daemon.hs, dist/build/git-annex/git-annex-tmp/Utility/Daemon.o )
+[113 of 270] Compiling Locations.UserConfig ( Locations/UserConfig.hs, dist/build/git-annex/git-annex-tmp/Locations/UserConfig.o )
+[114 of 270] Compiling Utility.TSet ( Utility/TSet.hs, dist/build/git-annex/git-annex-tmp/Utility/TSet.o )
+[115 of 270] Compiling Assistant.Types.Pushes ( Assistant/Types/Pushes.hs, dist/build/git-annex/git-annex-tmp/Assistant/Types/Pushes.o )
+[116 of 270] Compiling Assistant.Types.Commits ( Assistant/Types/Commits.hs, dist/build/git-annex/git-annex-tmp/Assistant/Types/Commits.o )
+[117 of 270] Compiling Assistant.Types.Changes ( Assistant/Types/Changes.hs, dist/build/git-annex/git-annex-tmp/Assistant/Types/Changes.o )
+[118 of 270] Compiling Utility.NotificationBroadcaster ( Utility/NotificationBroadcaster.hs, dist/build/git-annex/git-annex-tmp/Utility/NotificationBroadcaster.o )
+[119 of 270] Compiling Utility.Parallel ( Utility/Parallel.hs, dist/build/git-annex/git-annex-tmp/Utility/Parallel.o )
+[120 of 270] Compiling Utility.ThreadScheduler ( Utility/ThreadScheduler.hs, dist/build/git-annex/git-annex-tmp/Utility/ThreadScheduler.o )
+[121 of 270] Compiling Utility.LogFile ( Utility/LogFile.hs, dist/build/git-annex/git-annex-tmp/Utility/LogFile.o )
+[122 of 270] Compiling Git.Filename ( Git/Filename.hs, dist/build/git-annex/git-annex-tmp/Git/Filename.o )
+[123 of 270] Compiling Git.LsTree ( Git/LsTree.hs, dist/build/git-annex/git-annex-tmp/Git/LsTree.o )
+[124 of 270] Compiling Utility.Types.DirWatcher ( Utility/Types/DirWatcher.hs, dist/build/git-annex/git-annex-tmp/Utility/Types/DirWatcher.o )
+[125 of 270] Compiling Utility.INotify ( Utility/INotify.hs, dist/build/git-annex/git-annex-tmp/Utility/INotify.o )
+[126 of 270] Compiling Utility.DirWatcher ( Utility/DirWatcher.hs, dist/build/git-annex/git-annex-tmp/Utility/DirWatcher.o )
+[127 of 270] Compiling Utility.Lsof ( Utility/Lsof.hs, dist/build/git-annex/git-annex-tmp/Utility/Lsof.o )
+[128 of 270] Compiling Config ( Config.hs, dist/build/git-annex/git-annex-tmp/Config.o )
+[129 of 270] Compiling Annex.UUID ( Annex/UUID.hs, dist/build/git-annex/git-annex-tmp/Annex/UUID.o )
+[130 of 270] Compiling Logs.UUID ( Logs/UUID.hs, dist/build/git-annex/git-annex-tmp/Logs/UUID.o )
+[131 of 270] Compiling Backend ( Backend.hs, dist/build/git-annex/git-annex-tmp/Backend.o )
+[132 of 270] Compiling Remote.Helper.Hooks ( Remote/Helper/Hooks.hs, dist/build/git-annex/git-annex-tmp/Remote/Helper/Hooks.o )
+[133 of 270] Compiling Remote.Helper.Encryptable ( Remote/Helper/Encryptable.hs, dist/build/git-annex/git-annex-tmp/Remote/Helper/Encryptable.o )
+[134 of 270] Compiling Annex.Queue ( Annex/Queue.hs, dist/build/git-annex/git-annex-tmp/Annex/Queue.o )
+[135 of 270] Compiling Annex.Content ( Annex/Content.hs, dist/build/git-annex/git-annex-tmp/Annex/Content.o )
+[136 of 270] Compiling Remote.S3 ( Remote/S3.hs, dist/build/git-annex/git-annex-tmp/Remote/S3.o )
+[137 of 270] Compiling Remote.Directory ( Remote/Directory.hs, dist/build/git-annex/git-annex-tmp/Remote/Directory.o )
+[138 of 270] Compiling Remote.Rsync ( Remote/Rsync.hs, dist/build/git-annex/git-annex-tmp/Remote/Rsync.o )
+[139 of 270] Compiling Remote.Web ( Remote/Web.hs, dist/build/git-annex/git-annex-tmp/Remote/Web.o )
+[140 of 270] Compiling Remote.Hook ( Remote/Hook.hs, dist/build/git-annex/git-annex-tmp/Remote/Hook.o )
+[141 of 270] Compiling Upgrade.V2 ( Upgrade/V2.hs, dist/build/git-annex/git-annex-tmp/Upgrade/V2.o )
+[142 of 270] Compiling Annex.Ssh ( Annex/Ssh.hs, dist/build/git-annex/git-annex-tmp/Annex/Ssh.o )
+[143 of 270] Compiling Remote.Helper.Ssh ( Remote/Helper/Ssh.hs, dist/build/git-annex/git-annex-tmp/Remote/Helper/Ssh.o )
+[144 of 270] Compiling Remote.Bup ( Remote/Bup.hs, dist/build/git-annex/git-annex-tmp/Remote/Bup.o )
+[145 of 270] Compiling Annex.Version ( Annex/Version.hs, dist/build/git-annex/git-annex-tmp/Annex/Version.o )
+[146 of 270] Compiling Init ( Init.hs, dist/build/git-annex/git-annex-tmp/Init.o )
+[147 of 270] Compiling Checks ( Checks.hs, dist/build/git-annex/git-annex-tmp/Checks.o )
+[148 of 270] Compiling Remote.Git ( Remote/Git.hs, dist/build/git-annex/git-annex-tmp/Remote/Git.o )
+[149 of 270] Compiling Remote.List ( Remote/List.hs, dist/build/git-annex/git-annex-tmp/Remote/List.o )
+[150 of 270] Compiling Logs.Trust ( Logs/Trust.hs, dist/build/git-annex/git-annex-tmp/Logs/Trust.o )
+[151 of 270] Compiling Remote ( Remote.hs, dist/build/git-annex/git-annex-tmp/Remote.o )
+[152 of 270] Compiling Assistant.Alert ( Assistant/Alert.hs, dist/build/git-annex/git-annex-tmp/Assistant/Alert.o )
+
+Assistant/Alert.hs:60:26:
+ Not in scope: type constructor or class `Html'
+
+Assistant/Alert.hs:66:21: Not in scope: `preEscapedText'
+
+Assistant/Alert.hs:68:26:
+ Not in scope: type constructor or class `Html'
+
+Assistant/Alert.hs:69:19: Not in scope: `preEscapedText'
+</pre>
+
+What is the expected output? What do you see instead?
+
+The current git HEAD should build and not throw an error.
+
+What version of git-annex are you using? On what operating system?
+
+git-annex HEAD from git, Ubuntu 12.10.
+
+Please provide any additional information below.
+
+> Hmm, seems that Blaze's API is not stable, and I should avoid using it
+> directly. Converted this code to using Hamlet instead for its html
+> generation. [[done]] --[[Joey]]
diff --git a/doc/bugs/Building_in_cabal_using_--bindir___126____47__bin_breaks_the_desktop_link.mdwn b/doc/bugs/Building_in_cabal_using_--bindir___126____47__bin_breaks_the_desktop_link.mdwn
new file mode 100644
index 000000000..223568ca8
--- /dev/null
+++ b/doc/bugs/Building_in_cabal_using_--bindir___126____47__bin_breaks_the_desktop_link.mdwn
@@ -0,0 +1,15 @@
+What steps will reproduce the problem?
+
+Download the sourcecode, build using 'cabal build', then install using 'cabal install --bindir ~/bin'.
+
+What is the expected output? What do you see instead?
+
+The .desktop file contains `~/bin/git-annex webapp` as command which is of course a invalid command as ~ is not expanded when running the desktop file.
+
+What version of git-annex are you using? On what operating system?
+Latest Head from git, Ubuntu 12.04
+
+Please provide any additional information below.
+I'm not sure whether this is a bug or not. I just ran into problems because I did not expect the cabal build process to create my desktop file but instead thought that git-annex will create it by it-self taking its own path. Perhaps it would make sense to produce an error if the bindir is invalid. An automatic expansion of '~' in the build script would be even better.
+
+> [[done]], I think it was a typo. --[[Joey]]
diff --git a/doc/bugs/Building_in_cabal_using_--bindir___126____47__bin_breaks_the_desktop_link/comment_1_c0f0a2878070ed86900815c6b6a5fa5e._comment b/doc/bugs/Building_in_cabal_using_--bindir___126____47__bin_breaks_the_desktop_link/comment_1_c0f0a2878070ed86900815c6b6a5fa5e._comment
new file mode 100644
index 000000000..82dfa0d48
--- /dev/null
+++ b/doc/bugs/Building_in_cabal_using_--bindir___126____47__bin_breaks_the_desktop_link/comment_1_c0f0a2878070ed86900815c6b6a5fa5e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.60"
+ subject="comment 1"
+ date="2012-09-15T16:39:19Z"
+ content="""
+Something is going on that I don't understand. When I run `cabal install --bindir ~/bin`, my shell passes `/home/joey/bin` to cabal, so of course it works.
+"""]]
diff --git a/doc/bugs/Building_in_cabal_using_--bindir___126____47__bin_breaks_the_desktop_link/comment_2_53f2de3d3993821d8502fd08a0fcce12._comment b/doc/bugs/Building_in_cabal_using_--bindir___126____47__bin_breaks_the_desktop_link/comment_2_53f2de3d3993821d8502fd08a0fcce12._comment
new file mode 100644
index 000000000..69d795865
--- /dev/null
+++ b/doc/bugs/Building_in_cabal_using_--bindir___126____47__bin_breaks_the_desktop_link/comment_2_53f2de3d3993821d8502fd08a0fcce12._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-03-19T00:07:23Z"
+ content="""
+It seems to me that --bindir ~/bin will work, but --bindir=~/bin will not; it prevents the shell's tilde expansion from working.
+"""]]
diff --git a/doc/bugs/Cabal_cannot_solve_dependencies.mdwn b/doc/bugs/Cabal_cannot_solve_dependencies.mdwn
new file mode 100644
index 000000000..ac9738b03
--- /dev/null
+++ b/doc/bugs/Cabal_cannot_solve_dependencies.mdwn
@@ -0,0 +1,36 @@
+### Please describe the problem.
+
+This is a follow up of [[Problems building on Mac OS X]].
+As of 4.20130521.1, cabal still cannot resolve the dependencies.
+
+### What steps will reproduce the problem?
+
+ cabal update
+ cabal install git-annex-4.20130521.1 --user --only-dependencies
+
+### Please provide any additional information below.
+
+[[!format sh """
+Resolving dependencies...
+cabal: Could not resolve dependencies:
+trying: git-annex-4.20130521.1
+trying: git-annex-4.20130521.1:+webapp
+trying: yesod-form-1.3.0
+trying: yesod-core-1.2.1
+rejecting: yesod-default-1.2.0 (conflict: git-annex-4.20130521.1:webapp =>
+yesod-default(<1.2))
+rejecting: yesod-default-1.1.3.2, 1.1.3.1, 1.1.3, 1.1.2, 1.1.1, 1.1.0.2,
+1.1.0.1, 1.1.0 (conflict: yesod-core==1.2.1, yesod-default => yesod-core>=1.1
+&& <1.2)
+rejecting: yesod-default-1.0.1.1, 1.0.1, 1.0.0 (conflict: yesod-core==1.2.1,
+yesod-default => yesod-core>=1.0 && <1.1)
+rejecting: yesod-default-0.6.1 (conflict: yesod-core==1.2.1, yesod-default =>
+yesod-core>=0.10.1 && <0.11)
+rejecting: yesod-default-0.5.0 (conflict: yesod-core==1.2.1, yesod-default =>
+yesod-core>=0.9.4 && <0.10)
+rejecting: yesod-default-0.4.1, 0.4.0, 0.3.1 (conflict: yesod-core==1.2.1,
+yesod-default => yesod-core>=0.9 && <0.10
+"""]]
+
+> At the risk of closing early again, I have uploaded a .2 with
+> hints for the version of yesod-form and yesod-static. [[done]] --[[Joey]]
diff --git a/doc/bugs/Cabal_cannot_solve_dependencies/comment_1_1d41ac79867226dcb71f1c7b38da062d._comment b/doc/bugs/Cabal_cannot_solve_dependencies/comment_1_1d41ac79867226dcb71f1c7b38da062d._comment
new file mode 100644
index 000000000..91bcbe42f
--- /dev/null
+++ b/doc/bugs/Cabal_cannot_solve_dependencies/comment_1_1d41ac79867226dcb71f1c7b38da062d._comment
@@ -0,0 +1,21 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-05-24T14:21:03Z"
+ content="""
+Since I tested this release in a clean system, I suspect you have a ~/.ghc and ~/.cabal with something installed that is causing this dependency problem for you.
+
+<pre>
+# rm -rf .ghc .cabal
+# cabal update
+Config file path source is default config file.
+Config file /root/.cabal/config not found.
+Writing default configuration to /root/.cabal/config
+Downloading the latest package list from hackage.haskell.org
+# cabal install git-annex
+Resolving dependencies...
+Downloading HUnit-1.2.5.2...
+Configuring HUnit-1.2.5.2...
+</pre>
+"""]]
diff --git a/doc/bugs/Cabal_cannot_solve_dependencies/comment_2_50e72633a4462f6f6eb33d57b137fdcc._comment b/doc/bugs/Cabal_cannot_solve_dependencies/comment_2_50e72633a4462f6f6eb33d57b137fdcc._comment
new file mode 100644
index 000000000..78faa6732
--- /dev/null
+++ b/doc/bugs/Cabal_cannot_solve_dependencies/comment_2_50e72633a4462f6f6eb33d57b137fdcc._comment
@@ -0,0 +1,48 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmu416zAYgYzbXVZAe30MiXoOWO4z6nGX8"
+ nickname="Johannes"
+ subject="comment 2"
+ date="2013-05-24T14:59:54Z"
+ content="""
+Thanks for the quick comment. I was already trying to build this on a clean cabal system.
+
+However, as of 4.20130521.2, I now get this:
+
+[[!format sh \"\"\"
+Resolving dependencies...
+cabal: Could not resolve dependencies:
+trying: git-annex-4.20130521.2
+trying: git-annex-4.20130521.2:+webapp
+rejecting: yesod-1.2.0.1, 1.2.0 (conflict: git-annex-4.20130521.2:webapp =>
+yesod(<1.2))
+trying: yesod-1.1.9.3
+trying: http-conduit-1.9.3
+trying: certificate-1.3.7
+rejecting: crypto-pubkey-types-0.4.0 (conflict: certificate =>
+crypto-pubkey-types>=0.3 && <0.4)
+trying: crypto-pubkey-types-0.3.2
+trying: tls-extra-0.6.3
+rejecting: crypto-pubkey-0.1.4 (conflict: crypto-pubkey-types==0.3.2,
+crypto-pubkey => crypto-pubkey-types>=0.4 && <0.5)
+rejecting: crypto-pubkey-0.1.3, 0.1.2, 0.1.1, 0.1.0 (conflict: tls-extra =>
+crypto-pubkey>=0.1.4)
+\"\"\"]]
+
+Also tried adding a --constraint='tls-extra<0.6.3' with the following result:
+[[!format sh \"\"\"
+Resolving dependencies...
+cabal: Could not resolve dependencies:
+trying: git-annex-4.20130521.2
+trying: git-annex-4.20130521.2:+webapp
+trying: git-annex-4.20130521.2:+dns
+trying: dns-0.3.6
+trying: binary-0.7.1.0/installed-caa...
+rejecting: yesod-1.2.0.1, 1.2.0 (conflict: git-annex-4.20130521.2:webapp =>
+yesod(<1.2))
+trying: yesod-1.1.9.3
+trying: ghc-7.6.3/installed-875...
+rejecting: bin-package-db-0.0.0.0/installed-608... (conflict:
+binary==0.7.1.0/installed-caa..., bin-package-db =>
+binary==0.5.1.1/installed-72e...)
+\"\"\"]]
+"""]]
diff --git a/doc/bugs/Cabal_cannot_solve_dependencies/comment_3_886f2d1f7c47a3973b8dc7d7c412289a._comment b/doc/bugs/Cabal_cannot_solve_dependencies/comment_3_886f2d1f7c47a3973b8dc7d7c412289a._comment
new file mode 100644
index 000000000..a91a95953
--- /dev/null
+++ b/doc/bugs/Cabal_cannot_solve_dependencies/comment_3_886f2d1f7c47a3973b8dc7d7c412289a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-05-24T15:05:13Z"
+ content="""
+bin-package-db is shipped with ghc, so this may be down to your version of ghc. FWIW, I have tested .2 on OSX with ghc 7.4.2 & it works.
+
+(I can only support users cabal hell problems so far. Cabal is, unfortunately, basically buggy, and this is a large part of why I provide autobuilds.)
+"""]]
diff --git a/doc/bugs/Cabal_dependency_monadIO_missing.mdwn b/doc/bugs/Cabal_dependency_monadIO_missing.mdwn
new file mode 100644
index 000000000..13980dd29
--- /dev/null
+++ b/doc/bugs/Cabal_dependency_monadIO_missing.mdwn
@@ -0,0 +1,17 @@
+Just issuing the command `cabal install` results in the following error message.
+
+ Command/Add.hs:54:3:
+ No instance for (Control.Monad.IO.Control.MonadControlIO
+ (Control.Monad.State.Lazy.StateT Annex.AnnexState IO))
+ arising from a use of `handle' at Command/Add.hs:54:3-24
+
+Adding the dependency for `monadIO` to `git-annex.cabal` should fix this?
+-- Thomas
+
+> No, it's already satisfied by `monad-control` being listed as a
+> dependency in the cabal file. Your system might be old/new/or broken,
+> perhaps it's time to provide some details about the version of haskell
+> and of `monad-control` you have installed? --[[Joey]]
+
+>> Closing as apparently user error or a broken system.
+>> If you see this problem please do say. [[done]] --[[Joey]]
diff --git a/doc/bugs/Cabal_dependency_monadIO_missing/comment_1_14be660aa57fadec0d81b32a8b52c66f._comment b/doc/bugs/Cabal_dependency_monadIO_missing/comment_1_14be660aa57fadec0d81b32a8b52c66f._comment
new file mode 100644
index 000000000..8e38205f0
--- /dev/null
+++ b/doc/bugs/Cabal_dependency_monadIO_missing/comment_1_14be660aa57fadec0d81b32a8b52c66f._comment
@@ -0,0 +1,75 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmFgsNxmnGznb5bbmcoWhoQOoxZZ-io61s"
+ nickname="Thomas"
+ subject="comment 1"
+ date="2011-08-08T09:04:20Z"
+ content="""
+I use Debian Squeeze, I have the Debian package cabal-install 0.8.0-1 installed.
+
+ $ git clone git://git-annex.branchable.com/
+ $ cd git-annex.branchable.com
+ $ cabal update
+ $ cabal install cabal-install
+
+This installed: Cabal-1.10.2.0, zlib-0.5.3.1, cabal-install 0.10.2.
+No version of monad-control or monadIO installed.
+
+ $ ~/.cabal/bin/cabal install
+ Registering QuickCheck-2.4.1.1...
+ Registering Crypto-4.2.3...
+ Registering base-unicode-symbols-0.2.2.1...
+ Registering deepseq-1.1.0.2...
+ Registering hxt-charproperties-9.1.0...
+ Registering hxt-regex-xmlschema-9.0.0...
+ Registering hxt-unicode-9.0.1...
+ Registering hxt-9.1.2...
+ Registering stm-2.2.0.1...
+ Registering hS3-0.5.6...
+ Registering transformers-0.2.2.0...
+ Registering monad-control-0.2.0.1...
+ [1 of 1] Compiling Main ( Setup.hs, dist/setup/Main.o )
+ Linking ./dist/setup/setup ...
+ ghc -O2 -Wall -ignore-package monads-fd -fspec-constr-count=5 --make configure
+ [1 of 2] Compiling TestConfig ( TestConfig.hs, TestConfig.o )
+ [2 of 2] Compiling Main ( configure.hs, configure.o )
+ Linking configure ...
+ ./configure
+ checking version... 3.20110720
+ checking cp -a... yes
+ checking cp -p... yes
+ checking cp --reflink=auto... yes
+ checking uuid generator... uuid
+ checking xargs -0... yes
+ checking rsync... yes
+ checking curl... yes
+ checking bup... yes
+ checking gpg... yes
+ checking sha1... sha1sum
+ checking sha256... sha256sum
+ checking sha512... sha512sum
+ checking sha224... sha224sum
+ checking sha384... sha384sum
+
+ ...
+
+ Command/Add.hs:54:3:
+ No instance for (Control.Monad.IO.Control.MonadControlIO
+ (Control.Monad.State.Lazy.StateT Annex.AnnexState IO))
+ arising from a use of `handle' at Command/Add.hs:54:3-24
+ Possible fix:
+ add an instance declaration for
+ (Control.Monad.IO.Control.MonadControlIO
+ (Control.Monad.State.Lazy.StateT Annex.AnnexState IO))
+ In the first argument of `($)', namely `handle (undo file key)'
+ In a stmt of a 'do' expression:
+ handle (undo file key) $ moveAnnex key file
+ In the expression:
+ do { handle (undo file key) $ moveAnnex key file;
+ next $ cleanup file key }
+ cabal: Error: some packages failed to install:
+ git-annex-3.20110719 failed during the building phase. The exception was:
+ ExitFailure 1
+
+After I added a depencency for monadIO to the git-annex.cabal file, it installed correctly.
+-- Thomas
+"""]]
diff --git a/doc/bugs/Cabal_dependency_monadIO_missing/comment_2_4f4d8e1e00a2a4f7e8a8ab082e16adac._comment b/doc/bugs/Cabal_dependency_monadIO_missing/comment_2_4f4d8e1e00a2a4f7e8a8ab082e16adac._comment
new file mode 100644
index 000000000..adf7a34e6
--- /dev/null
+++ b/doc/bugs/Cabal_dependency_monadIO_missing/comment_2_4f4d8e1e00a2a4f7e8a8ab082e16adac._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 2"
+ date="2011-08-17T04:56:30Z"
+ content="""
+Finally got a chance to try to reproduce this. I followed your recipe exactly in a clean squeeze chroot. monadIO was not installed, but git-annex built ok, using monad-control.
+"""]]
diff --git a/doc/bugs/Calls_to_rsync_don__39__t_always_use__annex-rsync-options.mdwn b/doc/bugs/Calls_to_rsync_don__39__t_always_use__annex-rsync-options.mdwn
new file mode 100644
index 000000000..df1163b46
--- /dev/null
+++ b/doc/bugs/Calls_to_rsync_don__39__t_always_use__annex-rsync-options.mdwn
@@ -0,0 +1,35 @@
+What steps will reproduce the problem?
+
+Add a rsync special remote - one that you need a username/password to access (stored in text file $HOME/.rsync.password):
+
+ $ git annex initremote myrsync type=rsync rsyncurl=rsync://username@rsync.example.com/myrsync encryption=none
+ $ git annex describe myrsync "rsync server"
+ $ git config remote.myrsync.annex-rsync-options "--password-file=$HOME/.rsync.password"
+
+Copy a file to the remote:
+
+ $ git annex -d copy my-file --to myrsync
+
+What is the expected output? What do you see instead?
+
+Expect to see the file copied over to the rsync remote, but the check doesn't use the annex-rsync-options and asks for a password. The debug output is:
+
+ copy my-file (checking myrsync...) [2012-10-28 01:01:01 EST] call: sh ["-c","rsync --quiet 'rsync://username@rsync.example.com/myrsync/[...SNIP...]' 2>/dev/null"]
+
+However the actual copy does use annex-rsync-options and the copy works:
+
+ [2012-10-28 01:01:05 EST] read: rsync ["--password-file=/home/blah/.rsync.password","--progress","--recursive","--partial","--partial-dir=.rsync-partial","/home/blah/annex/.git/annex/tmp/rsynctmp/12345/","rsync://username@rsync.example.com/myrsync"]
+
+
+What version of git-annex are you using? On what operating system?
+
+git-annex: 3.20121017
+
+OS: Ubuntu 12.04
+
+Please provide any additional information below.
+
+I think this fix is as easy as including the annex-rsync-options wherever rsync is called.
+
+> I belive there was only the one place this was neglected. [[done]]
+> --[[Joey]]
diff --git a/doc/bugs/Can__39__t___34__git-annex_get__34___with_3.20111203.mdwn b/doc/bugs/Can__39__t___34__git-annex_get__34___with_3.20111203.mdwn
new file mode 100644
index 000000000..ea56c3732
--- /dev/null
+++ b/doc/bugs/Can__39__t___34__git-annex_get__34___with_3.20111203.mdwn
@@ -0,0 +1,27 @@
+Hi there,
+
+After updating to 3.20111203 (on Arch Linux) I noticed I was not able to use `git annex get` from a SSH remote (server running Arch Linux, same version of git-annex): "requested key is not present". Same behavior with current master (commit 6cf28585). I had no issue with the previous version (3.20111122).
+
+On this server, I was able to track down the issue using `git-annex-shell inannex` and `strace`:
+
+ $ strace -f -o log git-annex-shell inannex ~/photos-annex.git WORM-s369360-m1321602916--2011-11-17.jpg
+ $ echo $?
+ 1
+ $ tail -n20 log
+ [...]
+ 25623 chdir("/home/schnouki/git-annex") = 0
+ 25623 stat("/home/schnouki/photos-annex.git/annex/objects/082/676/WORM-s369360-m1321602916--2011-11-17.jpg/WORM-s369360-m1321602916--2011-11-17.jpg", {st_mode=S_IFREG|0400, st_size=369360, ...}) = 0
+ 25623 open("annex/objects/082/676/WORM-s369360-m1321602916--2011-11-17.jpg/WORM-s369360-m1321602916--2011-11-17.jpg", O_RDONLY) = -1 ENOENT (No such file or directory)
+ [...]
+
+Note there is a call to `stat()` with the full path to the requested file, and *then* a call to `open()` with a relative path -- which calls this call to fail, and git-annex-shell to return 1. With 3.20111122, there was no call to `stat()`, just a successful call to `open()` with a full absolute path.
+
+Using `git bisect` I was able to determine that this bug appeared in commit 64672c62 ("refactor"). Reverting it makes `git-annex-shell` work as expected, but I'm sure there are better ways to fix this. However I don't know enough Haskell to do it myself.
+
+Could you please try to fix this in a future version?
+
+> Thanks for a very good bug report.
+>
+> I've fixed this stupid mistake introduced in the code refactoring.
+> [[done]]
+> --[[Joey]]
diff --git a/doc/bugs/Can__39__t_access_files_from___39__Removable_drive__39___repo_even_if_set_as_client.mdwn b/doc/bugs/Can__39__t_access_files_from___39__Removable_drive__39___repo_even_if_set_as_client.mdwn
new file mode 100644
index 000000000..ef59954b7
--- /dev/null
+++ b/doc/bugs/Can__39__t_access_files_from___39__Removable_drive__39___repo_even_if_set_as_client.mdwn
@@ -0,0 +1,21 @@
+Note: This may not be a bug maybe the software doesn't work the way I think.
+
+What steps will reproduce the problem?
+
+Using the webapp, I created a normal repo on my desktop. I then added a 'Removable drive' repo on my usb stick.
+
+I want all my files to be synced and accessibles on both repos so I set the 'Removable drive' repo to 'client'.
+
+
+What is the expected output? What do you see instead?
+
+When I look in the 'annex' folder on my usb stick. I see a git repo (annex, branches, hooks) instead of seeing the files in the same way the 'annex' repo on my desktop is.
+
+
+What version of git-annex are you using? On what operating system?
+
+I'm using 9e57edff287ac53fc4b1cefef7271e9ed17f2285 (Fri Feb 22 15:19:25 2013 +0000).
+
+Ubuntu 12.10 x86_64
+
+[[!tag /design/assistant]]
diff --git a/doc/bugs/Can__39__t_access_files_from___39__Removable_drive__39___repo_even_if_set_as_client/comment_1_25eb2d7d0a9cdd1c55df0cec68472723._comment b/doc/bugs/Can__39__t_access_files_from___39__Removable_drive__39___repo_even_if_set_as_client/comment_1_25eb2d7d0a9cdd1c55df0cec68472723._comment
new file mode 100644
index 000000000..282e78298
--- /dev/null
+++ b/doc/bugs/Can__39__t_access_files_from___39__Removable_drive__39___repo_even_if_set_as_client/comment_1_25eb2d7d0a9cdd1c55df0cec68472723._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.253.75"
+ subject="comment 1"
+ date="2013-02-22T21:46:59Z"
+ content="""
+You have a bare git repository on your USB stick. The assistant uses bare repositories on USB sticks currently, although recent changes to support FAT make it possible to use non-bare repositories.
+
+For this to really work the way you want it to, the assistant would need to start updating local non-bare repositories whenever it pushed changes to them. Currently the assistant only updates the repository it's running in, so a non-bare repository on USB would lag behind and show an old version of the directory until manually updated with `git annex sync`.
+"""]]
diff --git a/doc/bugs/Can__39__t_access_files_from___39__Removable_drive__39___repo_even_if_set_as_client/comment_2_9e9b96e5113a50533251e946c2560d81._comment b/doc/bugs/Can__39__t_access_files_from___39__Removable_drive__39___repo_even_if_set_as_client/comment_2_9e9b96e5113a50533251e946c2560d81._comment
new file mode 100644
index 000000000..da1fcbc0f
--- /dev/null
+++ b/doc/bugs/Can__39__t_access_files_from___39__Removable_drive__39___repo_even_if_set_as_client/comment_2_9e9b96e5113a50533251e946c2560d81._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="Xyem"
+ ip="87.194.19.134"
+ subject="comment 2"
+ date="2013-02-27T00:02:01Z"
+ content="""
+Struggling to get the assistant to behave properly, including a similar situation to the above.
+
+I start the assistant with 'git annex webapp' and create an annex from the webapp.
+Adding an SSH remote (even if just a different directory on localhost) with \"Remote server\", creates the remote directory with what looks like what the contents of .git should be (annex, branches, hooks, objects etc.), regardless of the group chosen.
+
+Judging from your above comment, this means it is creating a bare repository. Why would it be doing this for an SSH remote, where git-annex-shell is available?
+
+System: Arch Linux
+git-annex version: 3.20130216
+Installed with: yaourt -S git-annex-bin
+"""]]
diff --git a/doc/bugs/Can__39__t_access_files_from___39__Removable_drive__39___repo_even_if_set_as_client/comment_3_6b091198ddd6ed709b076df1296aeb77._comment b/doc/bugs/Can__39__t_access_files_from___39__Removable_drive__39___repo_even_if_set_as_client/comment_3_6b091198ddd6ed709b076df1296aeb77._comment
new file mode 100644
index 000000000..48d1b2604
--- /dev/null
+++ b/doc/bugs/Can__39__t_access_files_from___39__Removable_drive__39___repo_even_if_set_as_client/comment_3_6b091198ddd6ed709b076df1296aeb77._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 3"
+ date="2013-02-27T01:12:29Z"
+ content="""
+Xyem, if you use git to clone a repo, instead of letting the assistant do it for you, you can get a non-bare repo. See the walkthrough for some examples. You can keep its working tree up to date with \"git annex sync\" run in that directory.
+
+Only helpful if you don't mind using git annex at the command line, I know.
+
+"""]]
diff --git a/doc/bugs/Can__39__t_access_files_from___39__Removable_drive__39___repo_even_if_set_as_client/comment_4_118b588685b535cca4c02eb6ef297c67._comment b/doc/bugs/Can__39__t_access_files_from___39__Removable_drive__39___repo_even_if_set_as_client/comment_4_118b588685b535cca4c02eb6ef297c67._comment
new file mode 100644
index 000000000..8ad0de3a5
--- /dev/null
+++ b/doc/bugs/Can__39__t_access_files_from___39__Removable_drive__39___repo_even_if_set_as_client/comment_4_118b588685b535cca4c02eb6ef297c67._comment
@@ -0,0 +1,21 @@
+[[!comment format=mdwn
+ username="Xyem"
+ ip="87.194.19.134"
+ subject="comment 4"
+ date="2013-02-27T12:16:45Z"
+ content="""
+@edheil:
+Yes, I have found that creating the repositories outside of the assistant (or directly on each machine through the assistant) and adding the remotes manually doesn't have this issue.. but as I am not setting this up for myself, so dropping to the command line is an issue (she's not averse to it, but also isn't a power user).
+
+It seems that the assistant/webapp is replacing dropbox functionality, while ignoring the functionality of git-annex. Perhaps I am misunderstanding the goal of it..?
+
+My intended use case in the situation where this issue comes up is:
+
+Repository on desktop has a copy of all files in indirect mode.
+Repository on netbook only has a copy of files added locally or fetched manually.
+Dropping a file in the netbook annex should cause it to be uploaded to the desktop repository (when it is available). Files should be fetchable/droppable (and unlockable) using the webapp from the desktop/netbook repository respectively.
+
+But it looks like this is (currently) unachievable as the webapp provides no method of fetching/dropping files, the assistant does not create the remote repositories correctly and requires dropping to the command line if worked around. Eep!
+
+Hope this doesn't come off as sour complaining. I was introduced to git-annex by a friend about a week ago (she only learned about it about 2-3 weeks ago and *loves* it) and it is a very nice and flexible tool which fits my own use case perfectly, meeting and exceeding every expectation.. until it came to the assistant and webapp (which makes me wonder why Joey is working on an Android port..).
+"""]]
diff --git a/doc/bugs/Can__39__t_access_files_from___39__Removable_drive__39___repo_even_if_set_as_client/comment_5_5cead277493e1c020e16be6f9245fe33._comment b/doc/bugs/Can__39__t_access_files_from___39__Removable_drive__39___repo_even_if_set_as_client/comment_5_5cead277493e1c020e16be6f9245fe33._comment
new file mode 100644
index 000000000..26b472dc7
--- /dev/null
+++ b/doc/bugs/Can__39__t_access_files_from___39__Removable_drive__39___repo_even_if_set_as_client/comment_5_5cead277493e1c020e16be6f9245fe33._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 5"
+ date="2013-02-27T17:05:07Z"
+ content="""
+There is a way to fetch/drop files if you don't want to use the command line, though it's not nearly as flexible as using a command line. If you've got a machine set as \"client\" then dragging files into a subdirectory named \"archive\" drops them, and dragging them out of that subdirectory fetches them.
+
+Honestly, moving files in and out of directories, and preferred content settings, have both been subject to the occasional regression, so there have been times this hasn't worked right, but in theory, that's how you do it.
+
+Unfortunately if you've got more than one \"client\" machine, this means adding/dropping files on one will affect them all, as file movements propagate.
+"""]]
diff --git a/doc/bugs/Can__39__t_access_files_from___39__Removable_drive__39___repo_even_if_set_as_client/comment_6_0f135f97c2808dce094628dc6608e617._comment b/doc/bugs/Can__39__t_access_files_from___39__Removable_drive__39___repo_even_if_set_as_client/comment_6_0f135f97c2808dce094628dc6608e617._comment
new file mode 100644
index 000000000..3fadb6219
--- /dev/null
+++ b/doc/bugs/Can__39__t_access_files_from___39__Removable_drive__39___repo_even_if_set_as_client/comment_6_0f135f97c2808dce094628dc6608e617._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 6"
+ date="2013-02-27T17:06:45Z"
+ content="""
+also... I've never used the feature where you have two local machines running git-annex and you tell one to share a repo with the other through the web interface, but maybe it would be helpful for this scenario? Apologies if you've already tried that.
+"""]]
diff --git a/doc/bugs/Can__39__t_access_files_from___39__Removable_drive__39___repo_even_if_set_as_client/comment_7_1d6f47f9e6cf935f19d68af6d5aa92fa._comment b/doc/bugs/Can__39__t_access_files_from___39__Removable_drive__39___repo_even_if_set_as_client/comment_7_1d6f47f9e6cf935f19d68af6d5aa92fa._comment
new file mode 100644
index 000000000..03d9950bc
--- /dev/null
+++ b/doc/bugs/Can__39__t_access_files_from___39__Removable_drive__39___repo_even_if_set_as_client/comment_7_1d6f47f9e6cf935f19d68af6d5aa92fa._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 7"
+ date="2013-02-27T17:43:45Z"
+ content="""
+The way this is supposed to (and does) work is that you use the webapp to create a repository on each computer, and then you pair them together using either local pairing or xmpp pairing.
+
+Today's release of git-annex also adds UI in the webapp to create additional local repositories that are connected to the current repository. However these are not really intended to be put on removable drives since the assistant needs to be running on them to keep them up-to-date.
+"""]]
diff --git a/doc/bugs/Can__39__t_access_files_from___39__Removable_drive__39___repo_even_if_set_as_client/comment_8_c5758fdb32348b9cd804ff17d27864e1._comment b/doc/bugs/Can__39__t_access_files_from___39__Removable_drive__39___repo_even_if_set_as_client/comment_8_c5758fdb32348b9cd804ff17d27864e1._comment
new file mode 100644
index 000000000..1ef87e6a6
--- /dev/null
+++ b/doc/bugs/Can__39__t_access_files_from___39__Removable_drive__39___repo_even_if_set_as_client/comment_8_c5758fdb32348b9cd804ff17d27864e1._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="Xyem"
+ ip="87.194.19.134"
+ subject="comment 8"
+ date="2013-02-27T18:36:16Z"
+ content="""
+@Joey:
+As my use case is 1 person using multiple machines, I didn't think local/XMPP pairing was appropriate.
+
+Local pairing because the netbook leaves the network the desktop machine is on, which is when transferring the files is wanted (otherwise, they would just use the desktop...).
+XMPP pairing description implies that it is for 2 different people (thus 2 different addresses). Can it be used where both annexes are using the same address? Or does the address also allow you to include the location (i.e. name@host.com/netbook)?
+
+It definitely sounds like I am misunderstanding how this is supposed to work so I apologise for that. Please keep up the excellent work. git-annex is one of those tools I wish I had learned about a long time ago!
+
+@edheil: Interesting workaround, thanks.
+"""]]
diff --git a/doc/bugs/Can__39__t_add_a_git_repo_to_git_annex:___34__Invalid_path_repo__47__.git__47__X__34___for_many_X.mdwn b/doc/bugs/Can__39__t_add_a_git_repo_to_git_annex:___34__Invalid_path_repo__47__.git__47__X__34___for_many_X.mdwn
new file mode 100644
index 000000000..5cb10fd49
--- /dev/null
+++ b/doc/bugs/Can__39__t_add_a_git_repo_to_git_annex:___34__Invalid_path_repo__47__.git__47__X__34___for_many_X.mdwn
@@ -0,0 +1,34 @@
+I have some git repositories I don't edit often that I'd like to back up. I'd like to add these to my git annex, so I don't have to resort to a time-consuming hack (such as setting up a proper submodule, or bundling the repositories).
+
+But when I try to add a .git directory to git annex, I get a bunch of errors of the form
+
+ git-annex: user error (xargs ["-0","git","--git-dir=/tmp/tmp.LhGN3nT9uM/annex/.git","--work-tree=/tmp/tmp.LhGN3nT9uM/annex","add","--"] exited 123)
+ failed
+ git-annex: add: 1 failed
+ add repo/.git/hooks/pre-push.sample ok
+ (Recording state in git...)
+ error: Invalid path 'repo/.git/hooks/pre-push.sample'
+ error: unable to add repo/.git/hooks/pre-push.sample to index
+ fatal: adding files failed
+
+STR:
+
+ $ mkdir annex
+ $ cd annex
+ annex$ git init
+ annex$ git annex init
+ annex$ cd ..
+
+ $ mkdir repo
+ $ cd repo
+ repo$ git init
+ repo$ cd ..
+
+ $ mv repo annex
+ $ cd annex
+ annex$ find repo | xargs -n1 git annex add
+ # Lots of errors of the form above.
+
+You can't simply do `git annex add repo` because that will ignore the .git directory. Similarly,` git annex add .git` (which I'd think really should try to add the contents of the .git directory) ignores everything.
+
+I don't know what this error means. Is there a right way to work around this?
diff --git a/doc/bugs/Can__39__t_add_a_git_repo_to_git_annex:___34__Invalid_path_repo__47__.git__47__X__34___for_many_X/comment_1_7f54e24c8e721d69bdb1e5a4181641b8._comment b/doc/bugs/Can__39__t_add_a_git_repo_to_git_annex:___34__Invalid_path_repo__47__.git__47__X__34___for_many_X/comment_1_7f54e24c8e721d69bdb1e5a4181641b8._comment
new file mode 100644
index 000000000..45eebe10f
--- /dev/null
+++ b/doc/bugs/Can__39__t_add_a_git_repo_to_git_annex:___34__Invalid_path_repo__47__.git__47__X__34___for_many_X/comment_1_7f54e24c8e721d69bdb1e5a4181641b8._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-05-13T17:36:31Z"
+ content="""
+It's a fairly fundamental limitation of git that you cannot check `.git` directories into a git repository.
+
+For backups and sneakernet transfers, `git bundle` is easy to use..
+"""]]
diff --git a/doc/bugs/Can__39__t_add_a_git_repo_to_git_annex:___34__Invalid_path_repo__47__.git__47__X__34___for_many_X/comment_2_6e91bc254f79ccf80d385ba7d35ffa9c._comment b/doc/bugs/Can__39__t_add_a_git_repo_to_git_annex:___34__Invalid_path_repo__47__.git__47__X__34___for_many_X/comment_2_6e91bc254f79ccf80d385ba7d35ffa9c._comment
new file mode 100644
index 000000000..c3be9b722
--- /dev/null
+++ b/doc/bugs/Can__39__t_add_a_git_repo_to_git_annex:___34__Invalid_path_repo__47__.git__47__X__34___for_many_X/comment_2_6e91bc254f79ccf80d385ba7d35ffa9c._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmUJBh1lYmvfCCiGr3yrdx-QhuLCSRnU5c"
+ nickname="Justin"
+ subject="comment 2"
+ date="2013-05-13T17:53:06Z"
+ content="""
+Be that as it may, the whole reason git-annex exists is to work around fundamental limitations of git!
+
+The issue is that I don't want to treat a folder which I happen to have applied version control to differently than a folder which happens not to be version controlled (aside from committing to the version-controlled folder, of course!). Both folders are in my git annex; I shouldn't have to worry about it. (My whole \"documents\" folder is in git annex, and it contains many small git repositories.)
+
+I guess I could write a script to unbundle and re-bundle on command. In fact, one could imagine integrating these scripts into git annex somehow.
+
+Is that something you'd consider taking upstream?
+"""]]
diff --git a/doc/bugs/Can__39__t_add_a_git_repo_to_git_annex:___34__Invalid_path_repo__47__.git__47__X__34___for_many_X/comment_3_4cf34da6050dd96f94ffc3652aa39715._comment b/doc/bugs/Can__39__t_add_a_git_repo_to_git_annex:___34__Invalid_path_repo__47__.git__47__X__34___for_many_X/comment_3_4cf34da6050dd96f94ffc3652aa39715._comment
new file mode 100644
index 000000000..f7b07d3b6
--- /dev/null
+++ b/doc/bugs/Can__39__t_add_a_git_repo_to_git_annex:___34__Invalid_path_repo__47__.git__47__X__34___for_many_X/comment_3_4cf34da6050dd96f94ffc3652aa39715._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-05-13T18:08:36Z"
+ content="""
+Well, git-annex is all about working around *1* limitation of git. There are several other limitations that it would be nice to have tools to deal with better, including storing metadata, and this one. I can't take everything on.
+
+I mostly worry about these limitations in the context of naive users using the git-annex assistant for file sync. I have heard that some people put their git repositories in dropbox.
+
+You don't sound at all naive, so I'll suggest another tool I wrote, mr <http://joeyh.name/code/mr>. With mr you can run a single command and operate on all repositories at or under a directory.
+"""]]
diff --git a/doc/bugs/Can__39__t_add_a_git_repo_to_git_annex:___34__Invalid_path_repo__47__.git__47__X__34___for_many_X/comment_4_cafcc24e98a89f10adaed5e09f75b659._comment b/doc/bugs/Can__39__t_add_a_git_repo_to_git_annex:___34__Invalid_path_repo__47__.git__47__X__34___for_many_X/comment_4_cafcc24e98a89f10adaed5e09f75b659._comment
new file mode 100644
index 000000000..6b7c9f33b
--- /dev/null
+++ b/doc/bugs/Can__39__t_add_a_git_repo_to_git_annex:___34__Invalid_path_repo__47__.git__47__X__34___for_many_X/comment_4_cafcc24e98a89f10adaed5e09f75b659._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkkyBDsfOB7JZvPZ4a8F3rwv0wk6Nb9n48"
+ nickname="Abdó"
+ subject="comment 4"
+ date="2013-05-28T19:21:57Z"
+ content="""
+This \"git is afraid of .git\" issue is the main blocker for finally getting rid of unison. My use case is as follows. Among other things, I have a `~/work` directory infested with little projects versioned by git. I want to sync it between my 3 machines and a cloud server. My current setup involves star-shaped unison syncs to the server. That's not bad, but it has its problems:
+
+ * unison keeps a file index for every pair of machines (laptop-server, office-server, etc). This means that I end up with 3 identical indexes on the server, indexing the same data. Every time I sync a pair, the server rechecks what has changed to update the corresponding index.
+ * also, every time I add a machine, or my disk explodes and I have to setup a new unison sync from scratch, the server has to reindex everything, which is slow.
+ * unison does not know about the entire history, only the current state of the replicas. This may lead to data loss if I delete something I shouldn't delete and propagate. Only in special cases, for instance when I delete everything in one replica, unison asks before throwing it all out the window.
+ * I sometimes want to sync laptop and desktop through the local network, instead of going through the server. Then I have to be very careful in which order I do the syncs + it adds a couple of new redundant indices.
+
+Now, git annex is not a sync tool. But as a side effect of its `git annex sync` feature, it happens to solve those issues in an elegant way, making it an extremely flexible sync tool, far superior to unison in many aspects!
+
+Still, my `~/work` directory is infested with little git repos, so I can't use git annex on `~/work`. Also, I treat my little git projects as things carrying their own history arround. Sometimes I move them, etc. I don't want to use mr in them, nor keep remotes for all my machines on all my little projects. That removes a lot of the flexibility I'd gain by moving to git annex.
+
+The thing is, I don't understand why this git limitation is fairly fundamental. I've been playing around nesting git repos. When I change the inner `.git` directory to `.bar`, the outer git swallows it all right, and after some playing around with commits and checkouts on the inner and outer repos, the internal repo survived the process. Also, I don't think versioning content inside `.git` may disorient git in any way. Every git call knows on which `.git` directory it operates, just go up through the path looking for the first `.git` dir which is NOT a part of the actual path. Is there anything else I am missing? Would it be feasible to patch git adding a config option that makes it treat `.git` dirs as regular dirs? I'd be willing to mess with git's source when I get the time to do it.
+"""]]
diff --git a/doc/bugs/Can__39__t_add_a_git_repo_to_git_annex:___34__Invalid_path_repo__47__.git__47__X__34___for_many_X/comment_5_118d61dea9ef0faa2960da6f2f62ec8b._comment b/doc/bugs/Can__39__t_add_a_git_repo_to_git_annex:___34__Invalid_path_repo__47__.git__47__X__34___for_many_X/comment_5_118d61dea9ef0faa2960da6f2f62ec8b._comment
new file mode 100644
index 000000000..28299c372
--- /dev/null
+++ b/doc/bugs/Can__39__t_add_a_git_repo_to_git_annex:___34__Invalid_path_repo__47__.git__47__X__34___for_many_X/comment_5_118d61dea9ef0faa2960da6f2f62ec8b._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://id.koumbit.net/anarcat"
+ ip="2001:1928:1:9::1"
+ subject="sources"
+ date="2013-11-21T18:41:12Z"
+ content="""
+I tried to find a canonical source for why (or if?) git ignores any \".git\" directory, and it turns out it also ignores .git *files*, according to [this stackoverflow thread](http://stackoverflow.com/questions/6839781/what-happens-when-you-run-git-add-git-in-a-git-repository). It's hardcoded in the source code and \"will likely not change\".
+
+I guess this should therefore be taken upstream, but I am not sure how this could justified there.
+
+I do think git-annex should support that. It's turning more and more as a \"generic backup solution\" or \"i want my files in the cloud\" kind of solution, which is awesome, but small things like this are making it harder to use... --[[anarcat]]
+"""]]
diff --git a/doc/bugs/Can__39__t_add_a_git_repo_to_git_annex:___34__Invalid_path_repo__47__.git__47__X__34___for_many_X/comment_6_3978557c6e85608243e5b4eb698ac5a5._comment b/doc/bugs/Can__39__t_add_a_git_repo_to_git_annex:___34__Invalid_path_repo__47__.git__47__X__34___for_many_X/comment_6_3978557c6e85608243e5b4eb698ac5a5._comment
new file mode 100644
index 000000000..da52be691
--- /dev/null
+++ b/doc/bugs/Can__39__t_add_a_git_repo_to_git_annex:___34__Invalid_path_repo__47__.git__47__X__34___for_many_X/comment_6_3978557c6e85608243e5b4eb698ac5a5._comment
@@ -0,0 +1,27 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkkyBDsfOB7JZvPZ4a8F3rwv0wk6Nb9n48"
+ nickname="Abdó"
+ subject="comment 6"
+ date="2013-11-21T20:04:22Z"
+ content="""
+After I wrote my last post in this thread I did write a patch for git doing two things:
+
+* make git ignore .git only at the root of the working tree, but not '.git' files or directories nested deeper into the working tree.
+* add config option to prevent git from converting directories containing .git into gitlinks. It turns out that git already has an internal setting for this, it only needed to be exposed in the config files!
+
+It kind of worked, but I've never used nor completed this, though (if I recall correctly, something had to be done regarding the default gitingores, which contains .git). I don't think upstream would accept these changes, though. It is a potentially risky change that does not gives them any benefit. Plus commiting a git repo inside an other is kind of crazy. I'm not convinced this is a good solution anymore.
+
+Being able to put a git repo inside an assistant-controled directory would be nice, though. Additionally, letting the outermost git repo recognize the internal git repo as a git repo, instead of moving files blindly, would also be nice, and probably more reasonable. And that leads to submodules...
+
+My particular problem is: I want to syncing a directory with lots of little git repos across several machines, without having to configure remotes for every single one of them (so no mr) and having someone take care of the files which are ignored by the little git repos, possibly as annexed files. Currently I just sync that folder containing the little git repos with unison.
+
+Now, instead of commiting git repos inside git repos, I'm more inclined to a potential solution using git-annex + submodules. Ideally I'd like something like this:
+
+1. A git-annex repo at ~/work
+2. All my little git repos inside ~/work are automatically recognized as submodules by git-annex
+3. The outermost git-annex takes care of the .gitignored files for the inner git repos
+4. git pull/push --recursive on the outermost annex repo pulls/pushes submodules (I think [something like this](https://github.com/jlehmann/git-submod-enhancements/wiki/Recursive-submodule-checkout) is written by Jens Lehmann)
+5. The urls in .gitmodules are relative paths from the outermost annex working tree. Then a git fetch --recursive from the outermost annex can use an outermost remote + the submodule relative path. No need to manually configure remotes for every machine on every submodule!
+
+The problem with this approach, is that 2,4,5 are science-fiction for now, and probably 3 too. Realizing this would imply a lot of work, and commiting a lot of submodule stuff to upstream git. But probably stuff that makes sense and they would accept. Anyway, I'd like to know what Joey thinks about all this...
+"""]]
diff --git a/doc/bugs/Can__39__t_add_a_git_repo_to_git_annex:___34__Invalid_path_repo__47__.git__47__X__34___for_many_X/comment_7_e6dfc41d2042402b40efb6f6139d5662._comment b/doc/bugs/Can__39__t_add_a_git_repo_to_git_annex:___34__Invalid_path_repo__47__.git__47__X__34___for_many_X/comment_7_e6dfc41d2042402b40efb6f6139d5662._comment
new file mode 100644
index 000000000..374d193c0
--- /dev/null
+++ b/doc/bugs/Can__39__t_add_a_git_repo_to_git_annex:___34__Invalid_path_repo__47__.git__47__X__34___for_many_X/comment_7_e6dfc41d2042402b40efb6f6139d5662._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.64"
+ subject="comment 7"
+ date="2013-11-22T16:50:31Z"
+ content="""
+I appreciate the investigation.
+
+Now that there's a direct mode guard, it would be possible to have git-annex translate .git directories to some other name when adding files to git. This seems more likely than getting git changed.
+
+However, I am not convinced *at all* that it makes any sense to try to sync git repositories in this way. I realize that some people drop git checkouts into dropbox and use that, but it's a fundamentally unsound thing to do, and those people are just lucky if they manage to avoid running into problems doing that.
+
+If you have two clones of a repo, and a git repository is checked into both, and they become partitioned for a while and larger re-merge, then there can be conflicts in the files that make up the git repository. Which git-annex would auto-resolve, with the effect that the checked-in git repository would appear to be broken.
+
+Also, this feature would only be used by a small number of users, on the border between people who can use git the Correct Way, and people who don't use git other than with the assistant.
+
+It would make sense to make git-annex refuse to add files inside nested git repositories though.
+"""]]
diff --git a/doc/bugs/Can__39__t_add_a_git_repo_to_git_annex:___34__Invalid_path_repo__47__.git__47__X__34___for_many_X/comment_8_33a84937c87dd2406bc090a0d2969683._comment b/doc/bugs/Can__39__t_add_a_git_repo_to_git_annex:___34__Invalid_path_repo__47__.git__47__X__34___for_many_X/comment_8_33a84937c87dd2406bc090a0d2969683._comment
new file mode 100644
index 000000000..df97625f7
--- /dev/null
+++ b/doc/bugs/Can__39__t_add_a_git_repo_to_git_annex:___34__Invalid_path_repo__47__.git__47__X__34___for_many_X/comment_8_33a84937c87dd2406bc090a0d2969683._comment
@@ -0,0 +1,30 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkkyBDsfOB7JZvPZ4a8F3rwv0wk6Nb9n48"
+ nickname="Abdó"
+ subject="comment 8"
+ date="2013-11-22T18:44:35Z"
+ content="""
+> I am not convinced at all that it makes any sense to try to sync git repositories in this way
+
+I agree this is not a good solution.
+
+
+> I realize that some people drop git checkouts into dropbox and use that, but it's a fundamentally unsound thing to do, and those people are just lucky if they manage to avoid running into problems doing that.
+
+Well, I don't use dropbox (nor annex assistant) but I sync a lot of git repos with unison. It is not luck, it is being careful not to create conflicts. I agree this is not ideal, and I'm looking for a better way to deal with this.
+
+
+> Also, this feature would only be used by a small number of users
+
+I'm not convinced of that. If done right, nested git repos inside annex could have value.
+
+Let's say you work with 40 git repos some private of yours, others tracking upstream, and you want to sync them across 4 machines (home, work, cloud server, backup). I imagine your preferred solution would be to configure the 4 machines as remotes on every git repo and use mr, am I right?
+
+This has its problems:
+
+1. The set of files you want in the project git repo may not be the same as the set of files you want synced across machines. For instance, I use a large software project that I compile from sources. I want to sync binaries across machines (it takes forever to compile!), but of course I don't want them commited into the project, not even as annexed files.
+2. Configuring remotes for every project is tedious. What if some remote changes url? what if I want to change the path of some of the git projects? Every time I add a new repo I need to configure all the 4 remotes. This can be scripted of course, but is not my ideal solution.
+
+What do you think about the submodules route I proposed? I don't like submodules very much, but in this case, I think it could become a good solution. In particular it would solve 1, 2 above and be able to merge conflicting changes on the nested repos.
+
+"""]]
diff --git a/doc/bugs/Can__39__t_clone_on_Windows_because_some_filenames_have_a_colon_in_them.mdwn b/doc/bugs/Can__39__t_clone_on_Windows_because_some_filenames_have_a_colon_in_them.mdwn
new file mode 100644
index 000000000..c3da3f5c1
--- /dev/null
+++ b/doc/bugs/Can__39__t_clone_on_Windows_because_some_filenames_have_a_colon_in_them.mdwn
@@ -0,0 +1,20 @@
+### Please describe the problem.
+Some filenames in doc have a colon `(:)` in them and it seems it's not allowed on Windows.
+
+There's no hurry with this since I was able to clone the repo by doing a fork on Github and removing `doc/`.
+
+### What steps will reproduce the problem?
+
+[[!format sh """
+D:\tmp> git clone git://git-annex.branchable.com/
+Cloning into 'git-annex.branchable.com'...
+remote: Counting objects: 72064, done.
+remote: Compressing objects: 100% (18759/18759), done.
+remote: Total 72064 (delta 52959), reused 72032 (delta 52944)
+Receiving objects: 100% (72064/72064), 18.05 MiB | 2.39 MiB/s, done.
+Resolving deltas: 100% (52959/52959), done.
+fatal: cannot create directory at 'doc/bugs/3.20121112:_build_error_in_assistant': Invalid argument
+D:\tmp>
+"""]]
+
+> [[wontfix|done]] --[[Joey]]
diff --git a/doc/bugs/Can__39__t_clone_on_Windows_because_some_filenames_have_a_colon_in_them/comment_1_5fc1347f4bcc13c9f8dbc5ecd4847fc7._comment b/doc/bugs/Can__39__t_clone_on_Windows_because_some_filenames_have_a_colon_in_them/comment_1_5fc1347f4bcc13c9f8dbc5ecd4847fc7._comment
new file mode 100644
index 000000000..59bfd629b
--- /dev/null
+++ b/doc/bugs/Can__39__t_clone_on_Windows_because_some_filenames_have_a_colon_in_them/comment_1_5fc1347f4bcc13c9f8dbc5ecd4847fc7._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-06-10T16:22:00Z"
+ content="""
+IMHO this is a bug in msysgit. It should support git repositories containing any legal filenames.
+
+Luckily, there is another git for Windows that does. It comes with Cygwin. You need Cygwin to build git-annex on Windows, anyway.
+
+So, I do not plan to do anything in git-annex to address this.
+"""]]
diff --git a/doc/bugs/Can__39__t_clone_on_Windows_because_some_filenames_have_a_colon_in_them/comment_2_38696178e658d1d32deec37dbea66a3d._comment b/doc/bugs/Can__39__t_clone_on_Windows_because_some_filenames_have_a_colon_in_them/comment_2_38696178e658d1d32deec37dbea66a3d._comment
new file mode 100644
index 000000000..fa9bd3dd3
--- /dev/null
+++ b/doc/bugs/Can__39__t_clone_on_Windows_because_some_filenames_have_a_colon_in_them/comment_2_38696178e658d1d32deec37dbea66a3d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnXm4VZC7ekVOXHGKjBObojiHB2E1kmMgA"
+ nickname="Leonardo"
+ subject="comment 2"
+ date="2013-08-11T21:21:56Z"
+ content="""
+Files with colon are not allowed in windows, they are interpreted as absolute path. The fact that you can checkout them \"fine\" (actually, their name get truncated to whatever was before the colon) using cygwin's GIT implementation is to be interpreted as a bug in cygwin's GIT in my opinion. I suggest renaming them before cygwin get fixed.
+"""]]
diff --git a/doc/bugs/Can__39__t_clone_on_Windows_because_some_filenames_have_a_colon_in_them/comment_3_f34d996827f5e7662bec409cbcce961b._comment b/doc/bugs/Can__39__t_clone_on_Windows_because_some_filenames_have_a_colon_in_them/comment_3_f34d996827f5e7662bec409cbcce961b._comment
new file mode 100644
index 000000000..14cfa2686
--- /dev/null
+++ b/doc/bugs/Can__39__t_clone_on_Windows_because_some_filenames_have_a_colon_in_them/comment_3_f34d996827f5e7662bec409cbcce961b._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 3"
+ date="2013-08-24T19:27:57Z"
+ content="""
+Leonardo, you made me boot up my windows machine just to check if cygwin git truncated files at the colon. It does not.
+
+AFAIK, Cygwin transliterates colons to another unicode character or something like that. I would be highly surprised if the Cygwin people consider this feature to be a bug.
+
+Since you need Cygwin to build git-annex on Windows anyway (though not to run it!), this remains WONTFIX.
+"""]]
diff --git a/doc/bugs/Can__39__t_rename___34__here__34___repository.mdwn b/doc/bugs/Can__39__t_rename___34__here__34___repository.mdwn
new file mode 100644
index 000000000..af3330670
--- /dev/null
+++ b/doc/bugs/Can__39__t_rename___34__here__34___repository.mdwn
@@ -0,0 +1,32 @@
+### Please describe the problem.
+Trying to rename the "here" repository fails
+
+### What steps will reproduce the problem?
+* Start git-annex webapp in the console (for the first time, or remove old annex directory + .config/git-annex)
+* In the browser window that opens click "Make repository"
+* The "here" repository should show up in the dashboard
+* Go to settings and select edit
+* Change the repository name (e.g. to here2) and click save changes
+* You should be back at the dashboard and the repository name is still "here"
+
+
+### What version of git-annex are you using? On what operating system?
+* git-annex version: 4.20130601
+* build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP DNS
+* built using cabal
+* on Ubuntu 13.04 32bit
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+[2013-06-12 22:22:57 CEST] main: starting assistant version 4.20130601
+(scanning...) [2013-06-12 22:22:57 CEST] Watcher: Performing startup scan
+(started...)
+
+# End of transcript or log.
+"""]]
+
+> Made text field for this repository disabled. The current repository has no remote name to edit. [[done]] --[[Joey]]
diff --git a/doc/bugs/Can__39__t_set_repositories_directory.mdwn b/doc/bugs/Can__39__t_set_repositories_directory.mdwn
new file mode 100644
index 000000000..f1ce5dea5
--- /dev/null
+++ b/doc/bugs/Can__39__t_set_repositories_directory.mdwn
@@ -0,0 +1,15 @@
+Can't set the repository directory
+
+
+At beginning during the webapp installation
+
+
+0.0.1 for OS X 10.8.2
+
+
+user error (git ["--git-dir=/Users/filippo/Desktop/annex/.git","--work-tree=/Users/filippo/Desktop/annex","commit-tree","4b825dc642cb6eb9a060e54bf8d69288fbee4904"] exited 128)
+
+[[!tag moreinfo assistant]]
+
+> [[done]]; based on the comment, this was a broken git email issue, which
+> git-annex now works around. --[[Joey]]
diff --git a/doc/bugs/Can__39__t_set_repositories_directory/comment_1_beb5d5b66a8d0fab12be44a7d877e9b0._comment b/doc/bugs/Can__39__t_set_repositories_directory/comment_1_beb5d5b66a8d0fab12be44a7d877e9b0._comment
new file mode 100644
index 000000000..d769219cc
--- /dev/null
+++ b/doc/bugs/Can__39__t_set_repositories_directory/comment_1_beb5d5b66a8d0fab12be44a7d877e9b0._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-05-19T20:12:18Z"
+ content="""
+There has never been a git-annex version 0.0.1. What is the real version you have installed?
+"""]]
diff --git a/doc/bugs/Can__39__t_set_repositories_directory/comment_2_366aa798a5e55350d32b63b31c19112b._comment b/doc/bugs/Can__39__t_set_repositories_directory/comment_2_366aa798a5e55350d32b63b31c19112b._comment
new file mode 100644
index 000000000..2af33522b
--- /dev/null
+++ b/doc/bugs/Can__39__t_set_repositories_directory/comment_2_366aa798a5e55350d32b63b31c19112b._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnGrQBFPptA2GU_Nx8KrxRGtyAS7PIlwjw"
+ nickname="Nathan"
+ subject="same problem here"
+ date="2013-06-27T12:32:28Z"
+ content="""
+Ran into this same problem just now. I can't start as I cant make a repository.
+
+Error:
+
+Internal Server Error
+user error (git [\"--git-dir=/Users/Nathan/annex/.git\",\"--work-tree=/Users/Nathan/annex\",\"commit-tree\",\"4b825dc642cb6eb9a060e54bf8d69288fbee4904\"] exited 128)
+
+git-annex version:
+
+4.20130626-g2dd6f84
+
+Could this have something to do with me first frigging around trying to get git-annex installed via homebrew? Maybe I broke something first?
+"""]]
diff --git a/doc/bugs/Can__39__t_set_repositories_directory/comment_3_812554d58ad9274a50b2a33d5f4d2ec3._comment b/doc/bugs/Can__39__t_set_repositories_directory/comment_3_812554d58ad9274a50b2a33d5f4d2ec3._comment
new file mode 100644
index 000000000..75145b709
--- /dev/null
+++ b/doc/bugs/Can__39__t_set_repositories_directory/comment_3_812554d58ad9274a50b2a33d5f4d2ec3._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.193"
+ subject="comment 3"
+ date="2013-06-27T18:19:57Z"
+ content="""
+Maybe git is broken somehow?
+
+What you can do is run `/Volumes/git-annex/git-annex.app/Contents/MacOS/git-annex-webapp` manually, in a console, and hopefully there will be a more informative error message displayed there.
+"""]]
diff --git a/doc/bugs/Can__39__t_set_repositories_directory/comment_4_bec5f147441ad18c97845b44c90c728b._comment b/doc/bugs/Can__39__t_set_repositories_directory/comment_4_bec5f147441ad18c97845b44c90c728b._comment
new file mode 100644
index 000000000..cdbcce515
--- /dev/null
+++ b/doc/bugs/Can__39__t_set_repositories_directory/comment_4_bec5f147441ad18c97845b44c90c728b._comment
@@ -0,0 +1,28 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnGrQBFPptA2GU_Nx8KrxRGtyAS7PIlwjw"
+ nickname="Nathan"
+ subject="comment 4"
+ date="2013-06-28T04:01:22Z"
+ content="""
+Okay I did that and got the following:
+
+
+
+ Launching web browser on file:///var/folders/7x/cmkqk6jn7ql7h_2wrc7kk4bc0000gn/T/webapp897.html
+
+ *** Please tell me who you are.
+
+ Run
+
+ git config --global user.email \"you@example.com\"
+ git config --global user.name \"Your Name\"
+
+ to set your account's default identity.
+ Omit --global to set the identity only in this repository.
+
+ fatal: unable to auto-detect email address (got 'Nathan@nathans-mac-pro.(none)')
+ 28/Jun/2013:13:54:04 +1000 [Error#yesod-core] user error (git [\"--git-dir=/Users/Nathan/Annex/.git\",\"--work-tree=/Users/Nathan/Annex\",\"commit-tree\",\"4b825dc642cb6eb9a060e54bf8d69288fbee4904\"] exited 128) @(yesod-core-1.1.8.3:Yesod.Internal.Core ./Yesod/Internal/Core.hs:550:5)
+
+
+So I did what it asked and now it's working. Thanks for your help!
+"""]]
diff --git a/doc/bugs/Can__39__t_start_on_Cyanogenmod_10.2_nightly.mdwn b/doc/bugs/Can__39__t_start_on_Cyanogenmod_10.2_nightly.mdwn
new file mode 100644
index 000000000..c28794622
--- /dev/null
+++ b/doc/bugs/Can__39__t_start_on_Cyanogenmod_10.2_nightly.mdwn
@@ -0,0 +1,158 @@
+### Please describe the problem.
+The android app won't start on Cyanogenmod 10.2. Not sure if this is cyanogenmod specific or if it is because the underlying android is now version 4.3
+
+### What steps will reproduce the problem?
+Install the apk and start the program
+
+### What version of git-annex are you using? On what operating system?
+A 7 day old nightly as of this post(can't get specific number since it won't run)
+
+### Please provide any additional information below.
+
+Tested this on both a samsung galaxy S and a samsung galaxy note 2. With different nightlies of cyanogenmod 10.2
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+Falling back to hardcoded app location; cannot find expected files in /data/app-lib
+git annex webapp
+u0_a115@android:/sdcard/git-annex.home $ git annex webapp
+CANNOT LINK EXECUTABLE: git-annex invalid R_ARM_COPY relocation against DT_SYMBOLIC shared library libc.so (built with -Bsymbolic?)
+1|u0_a115@android:/sdcard/git-annex.home $
+
+---
+
+
+cat git-annex-install.log
+
+Installation starting to /data/data/ga.androidterm
+34c88243533e9b0a725ebe33533d990e628dc44b
+installing busybox
+installing git-annex
+installing git-shell
+installing git-upload-pack
+installing git
+installing gpg
+installing rsync
+installing ssh
+installing ssh-keygen
+linking ./libexec/git-core/git-config to git
+linking ./libexec/git-core/git-fetch to git
+linking ./libexec/git-core/git-fsck to git
+linking ./libexec/git-core/git-unpack-file to git
+linking ./libexec/git-core/git-get-tar-commit-id to git
+linking ./libexec/git-core/git-fmt-merge-msg to git
+linking ./libexec/git-core/git-push to git
+linking ./libexec/git-core/git-for-each-ref to git
+linking ./libexec/git-core/git-pack-redundant to git
+linking ./libexec/git-core/git-mv to git
+linking ./libexec/git-core/git-ls-remote to git
+linking ./libexec/git-core/git-prune-packed to git
+linking ./libexec/git-core/git-apply to git
+linking ./libexec/git-core/git-check-ignore to git
+linking ./libexec/git-core/git-log to git
+linking ./libexec/git-core/git-cherry-pick to git
+linking ./libexec/git-core/git-diff-files to git
+linking ./libexec/git-core/git-commit-tree to git
+linking ./libexec/git-core/git-index-pack to git
+linking ./libexec/git-core/git-reflog to git
+linking ./libexec/git-core/git-merge-index to git
+linking ./libexec/git-core/git-column to git
+linking ./libexec/git-core/git-checkout-index to git
+linking ./libexec/git-core/git-diff-index to git
+linking ./libexec/git-core/git-count-objects to git
+linking ./libexec/git-core/git-fast-export to git
+linking ./libexec/git-core/git-fetch-pack to git
+linking ./libexec/git-core/git-merge-file to git
+linking ./libexec/git-core/git-init to git
+linking ./libexec/git-core/git-remote to git
+linking ./libexec/git-core/git-init-db to git
+linking ./libexec/git-core/git-ls-tree to git
+linking ./libexec/git-core/git-merge-subtree to git
+linking ./libexec/git-core/git-rev-parse to git
+linking ./libexec/git-core/git-bundle to git
+linking ./libexec/git-core/git-prune to git
+linking ./libexec/git-core/git-peek-remote to git
+linking ./libexec/git-core/git-tar-tree to git
+linking ./libexec/git-core/git-describe to git
+linking ./libexec/git-core/git-update-index to git
+linking ./libexec/git-core/git to git
+linking ./libexec/git-core/git-revert to git
+linking ./libexec/git-core/git-show-ref to git
+linking ./libexec/git-core/git-upload-archive to git
+linking ./libexec/git-core/git-add to git
+linking ./libexec/git-core/git-verify-tag to git
+linking ./libexec/git-core/git-format-patch to git
+linking ./libexec/git-core/git-show-branch to git
+linking ./libexec/git-core/git-remote-fd to git
+linking ./libexec/git-core/git-pack-refs to git
+linking ./libexec/git-core/git-replace to git
+linking ./libexec/git-core/git-pack-objects to git
+linking ./libexec/git-core/git-notes to git
+linking ./libexec/git-core/git-tag to git
+linking ./libexec/git-core/git-var to git
+linking ./libexec/git-core/git-help to git
+linking ./libexec/git-core/git-gc to git
+linking ./libexec/git-core/git-check-ref-format to git
+linking ./libexec/git-core/git-shortlog to git
+linking ./libexec/git-core/git-stage to git
+linking ./libexec/git-core/git-mktree to git
+linking ./libexec/git-core/git-merge-recursive to git
+linking ./libexec/git-core/git-grep to git
+linking ./libexec/git-core/git-clean to git
+linking ./libexec/git-core/git-merge-base to git
+linking ./libexec/git-core/git-repo-config to git
+linking ./libexec/git-core/git-hash-object to git
+linking ./libexec/git-core/git-read-tree to git
+linking ./libexec/git-core/git-rm to git
+linking ./libexec/git-core/git-fsck-objects to git
+linking ./libexec/git-core/git-ls-files to git
+linking ./libexec/git-core/git-mktag to git
+linking ./libexec/git-core/git-stripspace to git
+linking ./libexec/git-core/git-mailsplit to git
+linking ./libexec/git-core/git-diff-tree to git
+linking ./libexec/git-core/git-merge-ours to git
+linking ./libexec/git-core/git-cherry to git
+linking ./libexec/git-core/git-checkout to git
+linking ./libexec/git-core/git-rev-list to git
+linking ./libexec/git-core/git-write-tree to git
+linking ./libexec/git-core/git-update-ref to git
+linking ./libexec/git-core/git-blame to git
+linking ./libexec/git-core/git-archive to git
+linking ./libexec/git-core/git-update-server-info to git
+linking ./libexec/git-core/git-merge-tree to git
+linking ./libexec/git-core/git-show to git
+linking ./libexec/git-core/git-remote-ext to git
+linking ./libexec/git-core/git-merge to git
+linking ./libexec/git-core/git-name-rev to git
+linking ./libexec/git-core/git-bisect--helper to git
+linking ./libexec/git-core/git-clone to git
+linking ./libexec/git-core/git-symbolic-ref to git
+linking ./libexec/git-core/git-send-pack to git
+linking ./libexec/git-core/git-commit to git
+linking ./libexec/git-core/git-mailinfo to git
+linking ./libexec/git-core/git-credential to git
+linking ./libexec/git-core/git-diff to git
+linking ./libexec/git-core/git-patch-id to git
+linking ./libexec/git-core/git-rerere to git
+linking ./libexec/git-core/git-branch to git
+linking ./libexec/git-core/git-reset to git
+linking ./libexec/git-core/git-receive-pack to git
+linking ./libexec/git-core/git-verify-pack to git
+linking ./libexec/git-core/git-unpack-objects to git
+linking ./libexec/git-core/git-check-attr to git
+linking ./libexec/git-core/git-whatchanged to git
+linking ./libexec/git-core/git-status to git
+linking ./libexec/git-core/git-cat-file to git
+linking ./libexec/git-core/git-annotate to git
+linking ./bin/git-upload-archive to git
+linking ./bin/git-receive-pack to git
+linking ./libexec/git-core/git-shell to git-shell
+linking ./libexec/git-core/git-upload-pack to git-upload-pack
+Installation complete
+
+# End of transcript or log.
+"""]]
+
+> [[dup|done]] of [[git-annex_broken_on_Android_4.3]].--[[Joey]]
diff --git a/doc/bugs/Can__39__t_transfer_files_to_rsync_remote_with_encryption__61__shared.mdwn b/doc/bugs/Can__39__t_transfer_files_to_rsync_remote_with_encryption__61__shared.mdwn
new file mode 100644
index 000000000..31f37f6e5
--- /dev/null
+++ b/doc/bugs/Can__39__t_transfer_files_to_rsync_remote_with_encryption__61__shared.mdwn
@@ -0,0 +1,54 @@
+I'm trying to transfer 3 files to my rsync.net remote. It was set up a few months ago with encryption=shared.
+
+Here's what I get:
+
+ % LC_ALL=C git annex copy --to rsn 2012-11-26*
+ copy 2012-11-26 1.jpg (gpg) (checking rsn...) (to rsn...) gpg: no valid OpenPGP data found.
+ gpg: decrypt_message failed: Unknown system error
+ failed
+ copy 2012-11-26 2.jpg (checking rsn...) (to rsn...) gpg: no valid OpenPGP data found.
+ gpg: decrypt_message failed: Unknown system error
+ failed
+ copy 2012-11-26 3.jpg (checking rsn...) (to rsn...) gpg: no valid OpenPGP data found.
+ gpg: decrypt_message failed: Unknown system error
+ failed
+ git-annex: copy: 3 failed
+
+
+Here's the output with `--debug`:
+
+ % LC_ALL=C git annex --debug copy --to rsn 2012-11-26*
+ [2012-11-27 18:28:22 CET] read: git ["--git-dir=/home/schnouki/Photos/.git","--work-tree=/home/schnouki/Photos","show-ref","git-annex"]
+ [2012-11-27 18:28:22 CET] read: git ["--git-dir=/home/schnouki/Photos/.git","--work-tree=/home/schnouki/Photos","show-ref","--hash","refs/heads/git-annex"]
+ [2012-11-27 18:28:22 CET] read: git ["--git-dir=/home/schnouki/Photos/.git","--work-tree=/home/schnouki/Photos","log","refs/heads/git-annex..0164d6150fcd56e035926c72c9a519114735d2a1","--oneline","-n1"]
+ [2012-11-27 18:28:22 CET] read: git ["--git-dir=/home/schnouki/Photos/.git","--work-tree=/home/schnouki/Photos","log","refs/heads/git-annex..04bb9b87872200d5712b17463fc81d4de27b9acf","--oneline","-n1"]
+ [2012-11-27 18:28:22 CET] read: git ["--git-dir=/home/schnouki/Photos/.git","--work-tree=/home/schnouki/Photos","log","refs/heads/git-annex..59c38c176971cd6323817e568f4c32305ba708b0","--oneline","-n1"]
+ [2012-11-27 18:28:22 CET] chat: git ["--git-dir=/home/schnouki/Photos/.git","--work-tree=/home/schnouki/Photos","cat-file","--batch"]
+ [2012-11-27 18:28:22 CET] read: git ["--git-dir=/home/schnouki/Photos/.git","--work-tree=/home/schnouki/Photos","ls-files","--cached","-z","--","2012-11-26 1.jpg","2012-11-26 2.jpg","2012-11-26 3.jpg"]
+ copy 2012-11-26 1.jpg (gpg) (checking rsn...) [2012-11-27 18:28:22 CET] read: rsync ["rsn:photos/123/3a1/GPGHMACSHA1--4f4b2440da1f41aa42a590dc558fbfff39e44b5e/GPGHMACSHA1--4f4b2440da1f41aa42a590dc558fbfff39e44b5e"]
+ [2012-11-27 18:28:22 CET] read: rsync ["rsn:photos/jg/8p/GPGHMACSHA1--4f4b2440da1f41aa42a590dc558fbfff39e44b5e/GPGHMACSHA1--4f4b2440da1f41aa42a590dc558fbfff39e44b5e"]
+ (to rsn...) [2012-11-27 18:28:22 CET] chat: gpg ["--batch","--no-tty","--use-agent","--quiet","--trust-model","always","--passphrase-fd","11","--decrypt"]
+ gpg: no valid OpenPGP data found.
+ gpg: decrypt_message failed: Unknown system error
+ failed
+ copy 2012-11-26 2.jpg (checking rsn...) [2012-11-27 18:28:22 CET] read: rsync ["rsn:photos/61b/da7/GPGHMACSHA1--9c17b4b7414b830a0e7b86cbe08afd1e0878bdbd/GPGHMACSHA1--9c17b4b7414b830a0e7b86cbe08afd1e0878bdbd"]
+ [2012-11-27 18:28:23 CET] read: rsync ["rsn:photos/Z1/9V/GPGHMACSHA1--9c17b4b7414b830a0e7b86cbe08afd1e0878bdbd/GPGHMACSHA1--9c17b4b7414b830a0e7b86cbe08afd1e0878bdbd"]
+ (to rsn...) [2012-11-27 18:28:23 CET] chat: gpg ["--batch","--no-tty","--use-agent","--quiet","--trust-model","always","--passphrase-fd","10","--decrypt"]
+ gpg: no valid OpenPGP data found.
+ gpg: decrypt_message failed: Unknown system error
+ failed
+ copy 2012-11-26 3.jpg (checking rsn...) [2012-11-27 18:28:23 CET] read: rsync ["rsn:photos/340/2ec/GPGHMACSHA1--ce18f116ae33176c8387cecf9d62b0e694501a6e/GPGHMACSHA1--ce18f116ae33176c8387cecf9d62b0e694501a6e"]
+ [2012-11-27 18:28:23 CET] read: rsync ["rsn:photos/8f/V0/GPGHMACSHA1--ce18f116ae33176c8387cecf9d62b0e694501a6e/GPGHMACSHA1--ce18f116ae33176c8387cecf9d62b0e694501a6e"]
+ (to rsn...) [2012-11-27 18:28:23 CET] chat: gpg ["--batch","--no-tty","--use-agent","--quiet","--trust-model","always","--passphrase-fd","12","--decrypt"]
+ gpg: no valid OpenPGP data found.
+ gpg: decrypt_message failed: Unknown system error
+ failed
+ git-annex: copy: 3 failed
+
+I'm using git-annex 3.20121127. I think I was able to transfer files to that remote with the previous release.
+
+Any idea how to fix this? Am I doing something wrong?
+
+> Damn. This was a completely stupid bug, calling "decrypt" where it was
+> supposed to call "encrypt". [[done]] in git; I'll have to
+> make a new release to fix this. --[[Joey]]
diff --git a/doc/bugs/Can__39__t_transfer_files_to_rsync_remote_with_encryption__61__shared/comment_1_ca7ec2041bbec330476fb040b1e66a92._comment b/doc/bugs/Can__39__t_transfer_files_to_rsync_remote_with_encryption__61__shared/comment_1_ca7ec2041bbec330476fb040b1e66a92._comment
new file mode 100644
index 000000000..36061bac2
--- /dev/null
+++ b/doc/bugs/Can__39__t_transfer_files_to_rsync_remote_with_encryption__61__shared/comment_1_ca7ec2041bbec330476fb040b1e66a92._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://schnouki.net/"
+ nickname="Schnouki"
+ subject="comment 1"
+ date="2012-11-27T17:39:38Z"
+ content="""
+Downgraded to 3.20121112 and the transfer went fine. In both cases I used the [prebuilt tarball](http://downloads.kitenet.net/git-annex/linux/). So it must be a regression in the current release.
+"""]]
diff --git a/doc/bugs/Can__39__t_transfer_files_to_rsync_remote_with_encryption__61__shared/comment_2_c476847665a5320214721497d8fad15b._comment b/doc/bugs/Can__39__t_transfer_files_to_rsync_remote_with_encryption__61__shared/comment_2_c476847665a5320214721497d8fad15b._comment
new file mode 100644
index 000000000..def9d19c8
--- /dev/null
+++ b/doc/bugs/Can__39__t_transfer_files_to_rsync_remote_with_encryption__61__shared/comment_2_c476847665a5320214721497d8fad15b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://schnouki.net/"
+ nickname="Schnouki"
+ subject="comment 2"
+ date="2012-11-27T22:33:54Z"
+ content="""
+Thanks for the quick fix! :)
+"""]]
diff --git a/doc/bugs/Cannot_build_the_latest_with_GHC_7.6.1.mdwn b/doc/bugs/Cannot_build_the_latest_with_GHC_7.6.1.mdwn
new file mode 100644
index 000000000..f4ae47b32
--- /dev/null
+++ b/doc/bugs/Cannot_build_the_latest_with_GHC_7.6.1.mdwn
@@ -0,0 +1,18 @@
+What steps will reproduce the problem?
+
+cabal install git-annex
+
+What is the expected output? What do you see instead?
+
+I get this:
+
+ Assistant/WebApp/Configurators/Local.hs:55:11:
+ `fieldEnctype' is not a (visible) field of constructor `Field'
+
+What version of git-annex are you using? On what operating system?
+
+20121127
+
+Please provide any additional information below.
+
+> [[done]]; see comments. --[[Joey]]
diff --git a/doc/bugs/Cannot_build_the_latest_with_GHC_7.6.1/comment_1_b25859c159d62f2e92b92f505535131b._comment b/doc/bugs/Cannot_build_the_latest_with_GHC_7.6.1/comment_1_b25859c159d62f2e92b92f505535131b._comment
new file mode 100644
index 000000000..f01f4382a
--- /dev/null
+++ b/doc/bugs/Cannot_build_the_latest_with_GHC_7.6.1/comment_1_b25859c159d62f2e92b92f505535131b._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmLB39PC89rfGaA8SwrsnB6tbumezj-aC0"
+ nickname="Tobias"
+ subject="comment 1"
+ date="2012-11-27T15:48:33Z"
+ content="""
+I was told to my yesod was too old.
+
+Either upgrade yesod with cabal (After a \"cabal install yesod\" it worked on one of my computers, still failing on the other...)
+
+Or use the Makefile (failed on both the computers i tested).
+
+
+"""]]
diff --git a/doc/bugs/Cannot_build_the_latest_with_GHC_7.6.1/comment_2_4c9eab9120718457fdc1ae9051e44bca._comment b/doc/bugs/Cannot_build_the_latest_with_GHC_7.6.1/comment_2_4c9eab9120718457fdc1ae9051e44bca._comment
new file mode 100644
index 000000000..cca43f63e
--- /dev/null
+++ b/doc/bugs/Cannot_build_the_latest_with_GHC_7.6.1/comment_2_4c9eab9120718457fdc1ae9051e44bca._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmLB39PC89rfGaA8SwrsnB6tbumezj-aC0"
+ nickname="Tobias"
+ subject="comment 2"
+ date="2012-11-27T16:03:06Z"
+ content="""
+For reference here is a run of:
+
+cabal install yesod --force-reinstalls ; make
+
+http://pastebin.com/3Tr5BA0u
+
+Tried adding -DWITH_OLD_YESOD to the FEATURES in Makefile and got this after a \"make clean; make\":
+
+http://pastebin.com/GV84YgjZ
+"""]]
diff --git a/doc/bugs/Cannot_build_the_latest_with_GHC_7.6.1/comment_3_61aec9801e1f76db4a286536ffacc3ed._comment b/doc/bugs/Cannot_build_the_latest_with_GHC_7.6.1/comment_3_61aec9801e1f76db4a286536ffacc3ed._comment
new file mode 100644
index 000000000..32cdf6676
--- /dev/null
+++ b/doc/bugs/Cannot_build_the_latest_with_GHC_7.6.1/comment_3_61aec9801e1f76db4a286536ffacc3ed._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmLB39PC89rfGaA8SwrsnB6tbumezj-aC0"
+ nickname="Tobias"
+ subject="comment 3"
+ date="2012-11-27T16:06:22Z"
+ content="""
+For the machine that could compile and install the latest git-annex after updating yesod. \"make\" still fails.
+
+The first run here is without -DWITH_OLD_YESOD, the second is with.
+
+http://pastebin.com/T3RpPTX
+"""]]
diff --git a/doc/bugs/Cannot_build_the_latest_with_GHC_7.6.1/comment_4_6381ff0ea419831d9bbed27511cad1e9._comment b/doc/bugs/Cannot_build_the_latest_with_GHC_7.6.1/comment_4_6381ff0ea419831d9bbed27511cad1e9._comment
new file mode 100644
index 000000000..fb58e28ce
--- /dev/null
+++ b/doc/bugs/Cannot_build_the_latest_with_GHC_7.6.1/comment_4_6381ff0ea419831d9bbed27511cad1e9._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmLB39PC89rfGaA8SwrsnB6tbumezj-aC0"
+ nickname="Tobias"
+ subject="comment 4"
+ date="2012-11-27T16:10:31Z"
+ content="""
+cabal install yesod --force-reinstalls
+
+Then \"cabal configure, cabal build\" worked on my secondary machine...
+
+Woohooo, i have the latest git-annex running on both my machines now. Though neither can compile using the Makefile.
+
+Sorry for the spam here, just hoping it will help someone else jump through less hoops.
+
+
+"""]]
diff --git a/doc/bugs/Cannot_clone_an_annex.mdwn b/doc/bugs/Cannot_clone_an_annex.mdwn
new file mode 100644
index 000000000..77989ecb6
--- /dev/null
+++ b/doc/bugs/Cannot_clone_an_annex.mdwn
@@ -0,0 +1,69 @@
+I have an annex that I use to store my digital photos. I had a few false
+starts creating this annex, but now it's looking good on my server:
+
+ root@titan.local:/tank/Media/Pictures# git annex status
+ supported backends: SHA256E SHA1E SHA512E SHA224E SHA384E SHA256 SHA1 SHA512 SHA224 SHA384 WORM URL
+ supported remote types: git S3 bup directory rsync web hook
+ trusted repositories: 0
+ semitrusted repositories: 2
+ 00000000-0000-0000-0000-000000000001 -- web
+ be88bc5a-17e2-11e2-a99b-d388d4437350 -- here (titan)
+ untrusted repositories: 0
+ dead repositories: 5
+ 0A9F3136-A12A-43C7-9BE2-33F59954FD52 -- vulcan
+ 57349F02-E497-4420-9230-6B15D8AB14EE -- vulcan
+ 6195C912-2707-4B75-AC8C-11C51FAA8FE0 -- vulcan
+ D51DEDC4-9255-4A99-8520-2B1CED337674 -- hermes
+ EE327B34-3E20-4B5B-8F0E-D500CBC9738D -- hermes
+ transfers in progress: none
+ available local disk space: unknown
+ local annex keys: 20064
+ local annex size: 217 gigabytes
+ known annex keys: 21496
+ known annex size: 217 gigabytes
+ bloom filter size: 16 mebibytes (4% full)
+ backend usage:
+ SHA256E: 41560
+ root@titan.local:/tank/Media/Pictures# git annex unused
+ unused . (checking for unused data...) ok
+
+It passes `git annex fsck` without any problems. However, when I "git clone"
+this annex to my desktop machine and then do a `git annex sync`, I see this:
+
+ Vulcan /Volumes/tank/Media/Pictures (master) $ git annex status
+ supported backends: SHA256E SHA1E SHA512E SHA224E SHA384E SHA256 SHA1 SHA512 SHA224 SHA384 WORM URL
+ supported remote types: git S3 bup directory rsync web hook
+ trusted repositories: 0
+ semitrusted repositories: 5
+ 00000000-0000-0000-0000-000000000001 -- web
+ 0A9F3136-A12A-43C7-9BE2-33F59954FD52 -- vulcan
+ 274D3474-7A25-44CD-8368-CF11C451014F -- here (vulcan)
+ EE327B34-3E20-4B5B-8F0E-D500CBC9738D -- hermes
+ be88bc5a-17e2-11e2-a99b-d388d4437350 -- titan
+ untrusted repositories: 0
+ dead repositories: 3
+ 57349F02-E497-4420-9230-6B15D8AB14EE -- vulcan
+ 6195C912-2707-4B75-AC8C-11C51FAA8FE0 -- vulcan
+ D51DEDC4-9255-4A99-8520-2B1CED337674 -- hermes
+ transfers in progress: none
+ available local disk space: 1 terabyte (+1 megabyte reserved)
+ local annex keys: 0
+ local annex size: 0 bytes
+ known annex keys: 21025
+ known annex size: 217 gigabytes
+ bloom filter size: 16 mebibytes (0% full)
+ backend usage:
+ SHA256: 18707
+ SHA256E: 2318
+
+Where did all these `SHA256` keys come from?
+
+Why doesn't the known annex keys size match?
+
+Further, I cannot `git annex get` on most of the files, because it says that
+the `SHA256` key is not present.
+
+It looks like I'll have to rollback my ZFS snapshots and start over, but I'm
+wondering: how was I even able to create this situation?
+
+> [[Done]]; user error. --[[Joey]]
diff --git a/doc/bugs/Cannot_clone_an_annex/comment_1_b40a2652361a79c6c6eab0fc21be8e46._comment b/doc/bugs/Cannot_clone_an_annex/comment_1_b40a2652361a79c6c6eab0fc21be8e46._comment
new file mode 100644
index 000000000..44b93b1c2
--- /dev/null
+++ b/doc/bugs/Cannot_clone_an_annex/comment_1_b40a2652361a79c6c6eab0fc21be8e46._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.23"
+ subject="comment 1"
+ date="2012-10-22T13:53:06Z"
+ content="""
+The SHA256 keys are symlinks in your git repository with \"SHA256-\" as the prefix on the file linked to. You should be able to determine the rest by looking at the history of those files in git.
+"""]]
diff --git a/doc/bugs/Cannot_copy_to_a_git-annex_remote.mdwn b/doc/bugs/Cannot_copy_to_a_git-annex_remote.mdwn
new file mode 100644
index 000000000..c9e0309b8
--- /dev/null
+++ b/doc/bugs/Cannot_copy_to_a_git-annex_remote.mdwn
@@ -0,0 +1,14 @@
+What steps will reproduce the problem?
+
+I really have no way to reproduce. I have these two annex repository, both living on CentOS 6.3 machines, using SSH to copy from one to the other. Everything has always worked fine, and I've copied hundreds of gigabytes and tens of thousands of files so far without a problem.
+
+What is the expected output? What do you see instead?
+
+I do "git copy --to storage FILE" and it says "Copying FILE... failed". That's it.
+
+How do I fix things so that I can copy again? Nothing that I tried had any effect on the problem.
+
+Thanks!
+
+> Thanks to Jim's smart correlation of this with another bug, I've fixed
+> them both. [[done]] --[[Joey]]
diff --git a/doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_10_258a376cff4c62bc4be919322bb1bd88._comment b/doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_10_258a376cff4c62bc4be919322bb1bd88._comment
new file mode 100644
index 000000000..5150d9611
--- /dev/null
+++ b/doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_10_258a376cff4c62bc4be919322bb1bd88._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 10"
+ date="2013-03-19T00:14:59Z"
+ content="""
+Comment 7 was misplaced. Apologies.
+
+Hint for stracing: If you strace \"git-annex\" instead of \"git annex\", you don't need to strace -f, which keeps it a lot simpler.
+"""]]
diff --git a/doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_10_d9b830a1fdea8760cb7da1d36b3cd34d._comment b/doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_10_d9b830a1fdea8760cb7da1d36b3cd34d._comment
new file mode 100644
index 000000000..5fb3fe8ea
--- /dev/null
+++ b/doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_10_d9b830a1fdea8760cb7da1d36b3cd34d._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnBJ6Dv1glxzzi4qIzGFNa6F-mfHIvv9Ck"
+ nickname="Jim"
+ subject="Same bug"
+ date="2013-03-19T13:59:32Z"
+ content="""
+Hi,
+
+This looks like the exact same issue as [get failed, but remote has the file](http://git-annex.branchable.com/bugs/get_failed__44___but_remote_has_the_file/).
+I can reproduce your problem here by doing a `git annex copy --to bucket bigfile.gz`, then stopping that transfer with `^Z`, and finally running the `copy` command
+again. It will fail with the same debug output as you show here.
+"""]]
diff --git a/doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_1_09d76e5f9480b9a35644a8f08790cd97._comment b/doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_1_09d76e5f9480b9a35644a8f08790cd97._comment
new file mode 100644
index 000000000..cb750097c
--- /dev/null
+++ b/doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_1_09d76e5f9480b9a35644a8f08790cd97._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="enable debugging"
+ date="2013-03-18T15:13:53Z"
+ content="""
+try
+
+ git-annex --debug copy --to storage FILE
+"""]]
diff --git a/doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_2_7b586c705a937d09a1b44bd6af2d4686._comment b/doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_2_7b586c705a937d09a1b44bd6af2d4686._comment
new file mode 100644
index 000000000..c50bc905c
--- /dev/null
+++ b/doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_2_7b586c705a937d09a1b44bd6af2d4686._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-03-18T15:15:30Z"
+ content="""
+What version of git-annex are you using? Are your repositories using direct mode? What does --debug output?
+"""]]
diff --git a/doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_3_07dbd8f64982f1921077e23f468122cf._comment b/doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_3_07dbd8f64982f1921077e23f468122cf._comment
new file mode 100644
index 000000000..a86c68410
--- /dev/null
+++ b/doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_3_07dbd8f64982f1921077e23f468122cf._comment
@@ -0,0 +1,25 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/2grhJvAC049fJnvALDXek.6MRZMTlg--#eec89"
+ nickname="John"
+ subject="comment 3"
+ date="2013-03-18T15:32:31Z"
+ content="""
+git-annex version on both machines is 4.20130314. Here is the debug output:
+
+
+ [root@titan BoostPro]# git annex --verbose copy --to storage embt-virtual-machines.tar.xz
+ copy embt-virtual-machines.tar.xz (checking storage...) (to storage...) failed
+ git-annex: copy: 1 failed
+ [root@titan BoostPro]# git annex --debug copy --to storage embt-virtual-machines.tar.xz
+ [2013-03-18 10:31:33 CDT] read: git [\"--git-dir=/tank/Backups/BoostPro/.git\",\"--work-tree=/tank/Backups/BoostPro\",\"show-ref\",\"git-annex\"]
+ [2013-03-18 10:31:33 CDT] read: git [\"--git-dir=/tank/Backups/BoostPro/.git\",\"--work-tree=/tank/Backups/BoostPro\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+ [2013-03-18 10:31:33 CDT] read: git [\"--git-dir=/tank/Backups/BoostPro/.git\",\"--work-tree=/tank/Backups/BoostPro\",\"log\",\"refs/heads/git-annex..de30985dc380b49f50ae82046934457177b8d273\",\"--oneline\",\"-n1\"]
+ [2013-03-18 10:31:33 CDT] read: git [\"--git-dir=/tank/Backups/BoostPro/.git\",\"--work-tree=/tank/Backups/BoostPro\",\"log\",\"refs/heads/git-annex..678538248a63e4d4da706a4b703938f6b8e58657\",\"--oneline\",\"-n1\"]
+ [2013-03-18 10:31:33 CDT] read: git [\"--git-dir=/tank/Backups/BoostPro/.git\",\"--work-tree=/tank/Backups/BoostPro\",\"log\",\"refs/heads/git-annex..12346a2c23771268e2af5bfa3f813db172493354\",\"--oneline\",\"-n1\"]
+ [2013-03-18 10:31:33 CDT] chat: git [\"--git-dir=/tank/Backups/BoostPro/.git\",\"--work-tree=/tank/Backups/BoostPro\",\"cat-file\",\"--batch\"]
+ [2013-03-18 10:31:33 CDT] read: git [\"--git-dir=/tank/Backups/BoostPro/.git\",\"--work-tree=/tank/Backups/BoostPro\",\"ls-files\",\"--cached\",\"-z\",\"--\",\"embt-virtual-machines.tar.xz\"]
+ copy embt-virtual-machines.tar.xz (checking storage...) [2013-03-18 10:31:33 CDT] call: ssh [\"-T\",\"storage\",\"git-annex-shell 'inannex' '/tank/Backups/BoostPro' 'SHA256E-s51189502084--ad50567a43f10210e7cdae49f91dbfcc449b7f0629795da1fc268993ff59319b.tar.xz' --uuid ad6ef11f-ecad-48d5-af7c-43f8197ac124\"]
+ (to storage...) failed
+ git-annex: copy: 1 failed
+
+"""]]
diff --git a/doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_4_926fd494f0b27103a99083cd5d0702d5._comment b/doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_4_926fd494f0b27103a99083cd5d0702d5._comment
new file mode 100644
index 000000000..f33feffca
--- /dev/null
+++ b/doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_4_926fd494f0b27103a99083cd5d0702d5._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/2grhJvAC049fJnvALDXek.6MRZMTlg--#eec89"
+ nickname="John"
+ subject="comment 4"
+ date="2013-03-18T16:44:42Z"
+ content="""
+Oh, and neither repository is in direct mode.
+"""]]
diff --git a/doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_5_80444a509cc340f5eb3cd08b193fd389._comment b/doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_5_80444a509cc340f5eb3cd08b193fd389._comment
new file mode 100644
index 000000000..ecc4a93e1
--- /dev/null
+++ b/doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_5_80444a509cc340f5eb3cd08b193fd389._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 5"
+ date="2013-03-18T17:23:56Z"
+ content="""
+Does this only happen with one file, or with all files?
+
+I think you will need to strace git-annex to determine what the problem is. I cannot see how this could happen in indirect mode.
+"""]]
diff --git a/doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_6_4c6b99cd67b4aa742da5101fb1b379f7._comment b/doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_6_4c6b99cd67b4aa742da5101fb1b379f7._comment
new file mode 100644
index 000000000..977eed926
--- /dev/null
+++ b/doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_6_4c6b99cd67b4aa742da5101fb1b379f7._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/2grhJvAC049fJnvALDXek.6MRZMTlg--#eec89"
+ nickname="John"
+ subject="comment 6"
+ date="2013-03-18T18:42:14Z"
+ content="""
+It only happens with this one file, because it's the last file to be copied to the remote repository.
+"""]]
diff --git a/doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_8_f45cdd2b6acc5f458b67539fced0e529._comment b/doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_8_f45cdd2b6acc5f458b67539fced0e529._comment
new file mode 100644
index 000000000..59014a082
--- /dev/null
+++ b/doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_8_f45cdd2b6acc5f458b67539fced0e529._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 8"
+ date="2013-03-18T23:08:06Z"
+ content="""
+I don't understand what you're saying about it being the last file to be copied. This can't be stopping the copy from processing files after the one it fails on, and the order of the file in the list of files it's processing cannot be significant, unless you know something I don't know.
+
+What I meant to ask you is whether there is one, particular, specific file on your system that it refuses to copy, or whether it refuses to copy all files, or what.
+
+Anyway, you are going to need to send me a strace, I'm utterly stuck on this.
+"""]]
diff --git a/doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_9_5a455dd14fb9d3ff408bb3f81e366c38._comment b/doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_9_5a455dd14fb9d3ff408bb3f81e366c38._comment
new file mode 100644
index 000000000..145458120
--- /dev/null
+++ b/doc/bugs/Cannot_copy_to_a_git-annex_remote/comment_9_5a455dd14fb9d3ff408bb3f81e366c38._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/2grhJvAC049fJnvALDXek.6MRZMTlg--#eec89"
+ nickname="John"
+ subject="comment 9"
+ date="2013-03-18T23:46:39Z"
+ content="""
+I don't quite follow what comment 7 is trying to say, did you intend that to go to another bug report?
+
+As for strace, I'll give it a try tomorrow.
+"""]]
diff --git a/doc/bugs/Cannot_sync_repos_setup_using_webapp:___34__git-annex-shell:_Only_allowed_to_access___126____47__foo_not___126____47__bar__47____34__.mdwn b/doc/bugs/Cannot_sync_repos_setup_using_webapp:___34__git-annex-shell:_Only_allowed_to_access___126____47__foo_not___126____47__bar__47____34__.mdwn
new file mode 100644
index 000000000..4d1154650
--- /dev/null
+++ b/doc/bugs/Cannot_sync_repos_setup_using_webapp:___34__git-annex-shell:_Only_allowed_to_access___126____47__foo_not___126____47__bar__47____34__.mdwn
@@ -0,0 +1,29 @@
+###What steps will reproduce the problem?
+
+Suppose you have two types of folders you want to sync on two machines, e.g. Images and Documents.
+
+I already setup the Documents folders on both machines to sync using local pairing and they sync happily. Now I want to do the same and I execute the same steps again for the Images and I choose to not combine the Documents and Images repositories, but keep them separate.
+
+###What is the expected output? What do you see instead?
+
+The git repositories between both machines should be synced and all files should be transfered sucessfully between them.
+
+Instead the one machine shows a message "Failed to sync with host1_Images" and in the log it says
+
+ [2013-04-15 15:57:22 CEST] PairListener: Syncing with host1_Images
+ git-annex-shell: Only allowed to access ~/Documents not ~/Images/
+ fatal: The remote end hung up unexpectedly
+ Already up-to-date.
+
+I do not know how to debug this further cause I do not understand where this access-permission is configured.
+
+###What version of git-annex are you using? On what operating system?
+
+Machine 1: Gentoo Linux with Git-annex 4.20130405 from haskell-overlay.
+Machine 2: Ubuntu 12.04 with Git-Annex 4.20130405 installed using cabal.
+
+###Please provide any additional information below.
+
+> [[done]]; when setting up a new repo it will now use
+> a ssh key that is different for each repository on the host.
+> --[[Joey]]
diff --git a/doc/bugs/Cannot_sync_repos_setup_using_webapp:___34__git-annex-shell:_Only_allowed_to_access___126____47__foo_not___126____47__bar__47____34__/comment_1_6f7b5c164ff64f00b8814b2ee334709f._comment b/doc/bugs/Cannot_sync_repos_setup_using_webapp:___34__git-annex-shell:_Only_allowed_to_access___126____47__foo_not___126____47__bar__47____34__/comment_1_6f7b5c164ff64f00b8814b2ee334709f._comment
new file mode 100644
index 000000000..f2a5f1b9d
--- /dev/null
+++ b/doc/bugs/Cannot_sync_repos_setup_using_webapp:___34__git-annex-shell:_Only_allowed_to_access___126____47__foo_not___126____47__bar__47____34__/comment_1_6f7b5c164ff64f00b8814b2ee334709f._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-04-16T17:11:36Z"
+ content="""
+Yeah, this is indeed a bug. It sets up a locked down ssh key to use for the first repository, and then the second repository sees there is a key for that server already, and does not try to set up a new one.
+
+This is configured in `~/.ssh/authorized_keys` on the server. You will see a key in there with a `GIT_ANNEX_SHELL_DIRECTORY` environment variable specified, which is what prevents it from using other directories. The simplest fix in your situation is to
+remove that variable, and then that key can be used to access any repository on the server.
+
+What I need to do is include the path to the repository in the ssh key name, for new repositories created by the webapp.
+"""]]
diff --git a/doc/bugs/Cannot_sync_repos_setup_using_webapp:___34__git-annex-shell:_Only_allowed_to_access___126____47__foo_not___126____47__bar__47____34__/comment_2_807ef1250237bf4426e3a24c1f9ba357._comment b/doc/bugs/Cannot_sync_repos_setup_using_webapp:___34__git-annex-shell:_Only_allowed_to_access___126____47__foo_not___126____47__bar__47____34__/comment_2_807ef1250237bf4426e3a24c1f9ba357._comment
new file mode 100644
index 000000000..625c12fbf
--- /dev/null
+++ b/doc/bugs/Cannot_sync_repos_setup_using_webapp:___34__git-annex-shell:_Only_allowed_to_access___126____47__foo_not___126____47__bar__47____34__/comment_2_807ef1250237bf4426e3a24c1f9ba357._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://launchpad.net/~maestro-alubia"
+ nickname="maestro-alubia"
+ subject="Thanks!"
+ date="2013-04-17T22:55:24Z"
+ content="""
+Thank you very much for the fast fix! I will try that soon.
+
+I love git-annex, keep up the excellent work :)
+"""]]
diff --git a/doc/bugs/Committer_crashed.mdwn b/doc/bugs/Committer_crashed.mdwn
new file mode 100644
index 000000000..caa8b1c50
--- /dev/null
+++ b/doc/bugs/Committer_crashed.mdwn
@@ -0,0 +1,32 @@
+# What steps will reproduce the problem?
+
+Editing a text file with vim
+
+#What is the expected output? What do you see instead?
+
+ # On branch master
+ # Changes not staged for commit:
+
+ # (use "git add <file>..." to update what will be committed)
+ # (use "git checkout -- <file>..." to discard changes in working directory)
+ #
+ # typechange: test
+ #
+ # Untracked files:
+ # (use "git add <file>..." to include in what will be committed)
+ #
+ # .test.swp
+
+ no changes added to commit (use "git add" and/or "git commit -a")
+
+ /.test.swp still has writers, not adding
+
+ Committer crashed: ./test~: createLink: does not exist (No such file or directory)
+
+# What version of git-annex are you using? On what operating system?
+
+3.20130107 prebuilt tar ball on Debian testing
+
+> Could also fail in `getFileStatus`. In either case it's a race
+> with the file being deleted while it's still in the process of being
+> locked down. Fixed this [[done]] --[[Joey]]
diff --git a/doc/bugs/Compile_needs_more_than_1.5gb_of_memory.mdwn b/doc/bugs/Compile_needs_more_than_1.5gb_of_memory.mdwn
new file mode 100644
index 000000000..4fa9648c1
--- /dev/null
+++ b/doc/bugs/Compile_needs_more_than_1.5gb_of_memory.mdwn
@@ -0,0 +1,16 @@
+What steps will reproduce the problem?
+
+> cabal install git-annex
+
+What is the expected output? What do you see instead?
+
+> I would expect a working git-annex on my little linode. I have a linode 768 and trouble building the latest version. The process get's killed because of an out of memory condition.
+
+What version of git-annex are you using? On what operating system?
+
+> git-annex version: 4.20130314
+> Ubuntu 12.04
+
+Please provide any additional information below.
+
+[[done]]
diff --git a/doc/bugs/Compile_needs_more_than_1.5gb_of_memory/comment_1_0806b5132c55d7a5a17fbdad7e3f2291._comment b/doc/bugs/Compile_needs_more_than_1.5gb_of_memory/comment_1_0806b5132c55d7a5a17fbdad7e3f2291._comment
new file mode 100644
index 000000000..bc0853763
--- /dev/null
+++ b/doc/bugs/Compile_needs_more_than_1.5gb_of_memory/comment_1_0806b5132c55d7a5a17fbdad7e3f2291._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-03-15T21:49:49Z"
+ content="""
+You don't need a webapp on your linode, probably, so disable it:
+
+cabal install git-annex -f-WebApp
+
+The template haskell in the webapp about doubles the amount of memory needed to compile it.
+
+----
+
+Alternatively, since git-annex compiles down to a self-contained binary, you can build it on another machine of the same architecture, and just copy the binary over. Or there are all kinds of pre-compiled binaries available for Linux distributions that you can use on your linode.
+"""]]
diff --git a/doc/bugs/Complete_failure_trying_to_unannex_a_large_annex.mdwn b/doc/bugs/Complete_failure_trying_to_unannex_a_large_annex.mdwn
new file mode 100644
index 000000000..5531a1939
--- /dev/null
+++ b/doc/bugs/Complete_failure_trying_to_unannex_a_large_annex.mdwn
@@ -0,0 +1,56 @@
+I really don't know what's happened here, I just did `git annex unannex .` in a very large annex:
+
+ unannex Inbox/Lolcat.JPG (Recording state in git...)
+ ok
+ unannex Inbox/Lolcat.jpg (Recording state in git...)
+ ok
+ unannex Inbox/May 2012 Photo Stream/120502_0004.JPG (Recording state in git...)
+ ok
+ unannex Inbox/May 2012 Photo Stream/120518_0005.JPG (Recording state in git...)
+ ok
+ unannex Inbox/May 2012 Photo Stream/120523_0006.JPG (Recording state in git...)
+ ok
+ unannex Inbox/May 2012 Photo Stream/120523_0007.JPG (Recording state in git...)
+ ok
+ unannex Inbox/My boyfriend of 7 years and I are both physicists. Here's how he proposed to me. - Imgur.jpg (Recording state in git...)
+ ok
+ unannex Inbox/Nov 2012 Photo Stream/121102_0035.JPG (Recording state in git...)
+ ok
+ unannex Inbox/Nov 2012 Photo Stream/121102_0036.JPG (Recording state in git...)
+ ok
+ unannex Inbox/Nov 2012 Photo Stream/121102_0037.JPG (Recording state in git...)
+ ok
+ unannex Inbox/Nov 2012 Photo Stream/121102_0038.JPG (Recording state in git...)
+ ok
+ unannex Inbox/Nov 2012 Photo Stream/121102_0039.JPG (Recording state in git...)
+ ok
+ unannex Inbox/Nov 2012 Photo Stream/121103_0040.JPG (Recording state in git...)
+ ok
+ unannex Inbox/Nov 2012 Photo Stream/121104_0041.JPG (Recording state in git...)
+ ok
+ unannex Inbox/Nov 2012 Photo Stream/121105_0042.JPG (Recording state in git...)
+ error: bad index file sha1 signature
+ fatal: index file corrupt
+ git-annex: failed to read sha from git write-tree
+ git-annex: git commit [Param "-q",Params "-m",Param "content removed from git annex",Param "--",File "Inbox/Nov 2012 Photo Stream/121105_0042.JPG"] failed
+ Vulcan:~/Pictures $ ga unannex .
+ unannex Inbox/Nov 2012 Photo Stream/121109_0043.JPG error: bad index file sha1 signature
+ fatal: index file corrupt
+
+ git-annex: fd:12: hClose: resource vanished (Broken pipe)
+ failed
+ git-annex: pre-commit: 1 failed
+ git-annex: git commit [Param "-q",Params "-m",Param "content removed from git annex",Param "--",File "Inbox/Nov 2012 Photo Stream/121109_0043.JPG"] failed
+ Vulcan:~/Pictures $ ga -F unannex .
+ unannex Inbox/Nov 2012 Photo Stream/121124_0044.JPG error: bad index file sha1 signature
+ fatal: index file corrupt
+
+ git-annex: fd:12: hClose: resource vanished (Broken pipe)
+ failed
+ git-annex: pre-commit: 1 failed
+ git-annex: git commit [Param "-q",Params "-m",Param "content removed from git annex",Param "--",File "Inbox/Nov 2012 Photo Stream/121124_0044.JPG"] failed
+
+I guess now I'll just try to unlink the symlinks by hand, and drop the `.git` directory?
+
+> [[done]]; per my comment this seems like a corrupt git repository.
+> --[[Joey]]
diff --git a/doc/bugs/Complete_failure_trying_to_unannex_a_large_annex/comment_1_1c202695ab7fe62cdc8770e1fb428d0c._comment b/doc/bugs/Complete_failure_trying_to_unannex_a_large_annex/comment_1_1c202695ab7fe62cdc8770e1fb428d0c._comment
new file mode 100644
index 000000000..82acacd75
--- /dev/null
+++ b/doc/bugs/Complete_failure_trying_to_unannex_a_large_annex/comment_1_1c202695ab7fe62cdc8770e1fb428d0c._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-03-08T19:02:54Z"
+ content="""
+You seem to have a corrupt .git/index file, or .git/annex/index, or maybe a whole corrupt git repository. I'm not sure. I'd start by running `git fsck`, and if that's ok, remove `.git/annex/index` and `.git/annex/index.lck`. git-annex will recover from that automatically. If that still doesn't help, you might need to delete .git/index and do some reset to get it back.
+
+I don't see much evidence of an actual bug here, just bad data that is somehow on disk.
+"""]]
diff --git a/doc/bugs/Conflicting_archive_descriptions.mdwn b/doc/bugs/Conflicting_archive_descriptions.mdwn
new file mode 100644
index 000000000..832daa4ea
--- /dev/null
+++ b/doc/bugs/Conflicting_archive_descriptions.mdwn
@@ -0,0 +1,16 @@
+This is confusing:
+
+"Next we come to the archive repositories.The archive repositories coordinate together, so that each file is archived in only one place. **When you move files into a folder named "archive"**, they'll be moved to an archive repository, and removed from all your client repositories. This is handy if you have old files you don't need anymore, but want to keep archived for later. When you copy or move a file out of an "archive" folder, it'll be retrieved from the archive repository."
+
+"The small archive repositories are like other archive repositories, but smaller. While archive repositories normally accumulate every file they can, small archive repositories only accumulate files **once you put them in an "archive" directory.**"
+
+Based upon those descriptions, I don't know what the difference is.
+
+> Improved wording to not imply that files are only put into archive
+> repositories once the files are moved to archive directories.
+> (Which is how small archive repositories work.)
+>
+> If you're still confused about it, see
+> <http://git-annex.branchable.com/assistant/archival_walkthrough/>
+>
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/ControlPath_too_long_for_Unix_domain_socket.mdwn b/doc/bugs/ControlPath_too_long_for_Unix_domain_socket.mdwn
new file mode 100644
index 000000000..9cf453164
--- /dev/null
+++ b/doc/bugs/ControlPath_too_long_for_Unix_domain_socket.mdwn
@@ -0,0 +1,53 @@
+What steps will reproduce the problem?
+Pairing an existing git annex repository with a fresh repository on another computer in the git-annex webapp
+
+
+What is the expected output? What do you see instead?
+Expected result is that the two machines sync correctly.
+
+What i see are some "ControlPath <data> too long for unix domain socket" errors from ssh, but the computers do actually sync properly.
+
+Even though the data is synced properly, either the sender(or both of the clients) don't actually realize this. And the queue circles, all the transfers are being redone constantly(On every start of git-annex webapp on the original repository at least).
+
+
+What version of git-annex are you using? On what operating system?
+Latest git master as of this post. Debian sid and Ubuntu 12.04
+
+
+Please provide any additional information below.
+
+
+stdout snippet from git-annex webapp:
+
+
+ ControlPath "/home/alansmithee/Desktop/annex/.git/annex/ssh/alansmithee@git-annex-debbook.local-alansmithee.dxpXHVCkLhsxvWaH" too long for Unix domain socket
+ SHA256-s51233--0b4c59b3ab03b1ca6d95d4084fa6ff7220cf26695b6e3dd575f78af3dec6b701
+ 51233 100% 5.43MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 30 bytes received 51385 bytes 102830.00 bytes/sec
+ total size is 51233 speedup is 1.00
+ ok
+ (Recording state in git...)
+
+ ControlPath "/home/alansmithee/Desktop/annex/.git/annex/ssh/alansmithee@git-annex-debbook.local-alansmithee.9ZQwEjraTxi20B6W" too long for Unix domain socket
+ SHA256-s47883982--4b7cbb49506dcdd223a9db7b400cc41fc2e3ebbf5b2b17b75c9334bb949b6754
+ 47883982 100% 1.34MB/s 0:00:34 (xfer#1, to-check=0/1)
+
+ sent 30 bytes received 47889978 bytes 1388116.17 bytes/sec
+ total size is 47883982 speedup is 1.00
+ ok
+ (Recording state in git...)
+
+
+This data appears on both the sending and receiving git-annex stdout. At least for the initial sync. For later syncs it only appears on the sender, though the client system is using a lot of resources.
+
+> I've made git-annex detect if the control path would be too long,
+> and disable ssh connection caching. It also tries a relative path
+> to the file, which tends to make it shorter, and I think would
+> keep ssh connection caching working in your example.
+>
+> Please test and see if it works, and also if the "looping" problem
+> still happens. --[[Joey]]
+
+>> Closing; I'm pretty sure the looping is just transfer retrying, to be
+>> expected if they fail. [[done]] --[[Joey]]
diff --git a/doc/bugs/ControlPath_too_long_for_Unix_domain_socket/comment_1_60f58e205604eebe668b1e05dcfbf9a7._comment b/doc/bugs/ControlPath_too_long_for_Unix_domain_socket/comment_1_60f58e205604eebe668b1e05dcfbf9a7._comment
new file mode 100644
index 000000000..0cba1a693
--- /dev/null
+++ b/doc/bugs/ControlPath_too_long_for_Unix_domain_socket/comment_1_60f58e205604eebe668b1e05dcfbf9a7._comment
@@ -0,0 +1,24 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.30"
+ subject="comment 1"
+ date="2012-09-13T22:00:53Z"
+ content="""
+You can work around the ControlPath too long by running in your git repo:
+
+git config annex.sshcaching false
+
+While I could reproduce that part of your problem, I did *not* see any data actually be transferred when the ControlPath was too long. For example:
+
+<pre>
+joey@gnu:~/tmp/t/1>git annex transferkey --to foo SHA256E-s29--66ffceb8b7a1af9c2eb896f26fb8f3bdab0a606da59a7a2d71ae4f7d78ad13c4/SHA256E-s29--66ffceb8b7a1af9c2eb896f26fb8f3bdab0a606da59a7a2d71ae4f7d78ad13c4
+
+ControlPath too long
+rsync: connection unexpectedly closed (0 bytes received so far) [sender]
+rsync error: error in rsync protocol data stream (code 12) at io.c(605) [sender=3.0.9]
+
+ rsync failed -- run git annex again to resume file transfer
+failed
+git-annex: transferkey: 1 failed
+</pre>
+"""]]
diff --git a/doc/bugs/Corrupted_drive:_Assistant_seems_consider_files_deleted_and_deletes_them_elsewhere_too.mdwn b/doc/bugs/Corrupted_drive:_Assistant_seems_consider_files_deleted_and_deletes_them_elsewhere_too.mdwn
new file mode 100644
index 000000000..de879f522
--- /dev/null
+++ b/doc/bugs/Corrupted_drive:_Assistant_seems_consider_files_deleted_and_deletes_them_elsewhere_too.mdwn
@@ -0,0 +1,33 @@
+### Please describe the problem.
+
+On my raspberry pi, an SSH remote was in /var/lib/store (symlinked with /home/carlo/store), which contained a LVM volume spanning several USB drives. One of the drives got corrupted, which lead to this:
+
+$ cd /home/carlo/store
+$ ls
+Input/Output Error
+
+On my desktop machine, I then had a lot of transfers. After transfer, the file was turned into a symlink.
+
+### What steps will reproduce the problem?
+
+* Create an annex and a remote ssh server.
+* [Simulate a corrupted drive](http://stackoverflow.com/questions/1361518/how-can-i-simulate-a-failed-disk-during-testing) for the remote, creating an input output error.
+* Wait until the annex starts syncing on the desktop machine. If there were no further unidentified causes on my side, the assistant will start transfers that revert files to symlinks.
+
+### What version of git-annex are you using? On what operating system?
+
+Ubuntu 12.04 64bit
+git annex 3.20121017 ([from Ubuntu PPA](https://launchpad.net/~rubiojr/+archive/git-annex))
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+Please see [all my daemon.log](http://capocasa.name/daemon.tgz) files.
+
+I noticed the problem yesterday afternoon (Thu 24 Oct).
+
+# End of transcript or log.
+"""]]
diff --git a/doc/bugs/Corrupted_drive:_Assistant_seems_consider_files_deleted_and_deletes_them_elsewhere_too/comment_1_80ca50f5305eda71fe32f2b0bc922c34._comment b/doc/bugs/Corrupted_drive:_Assistant_seems_consider_files_deleted_and_deletes_them_elsewhere_too/comment_1_80ca50f5305eda71fe32f2b0bc922c34._comment
new file mode 100644
index 000000000..e47cbd327
--- /dev/null
+++ b/doc/bugs/Corrupted_drive:_Assistant_seems_consider_files_deleted_and_deletes_them_elsewhere_too/comment_1_80ca50f5305eda71fe32f2b0bc922c34._comment
@@ -0,0 +1,21 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 1"
+ date="2013-10-26T19:22:57Z"
+ content="""
+It seems to me that if a subdirectory of the repository is on a corrupted drive, and so it's not possible to list the files on it, this is basically the same as if you'd 'rm -rf' that subdirectory. So when it starts up, the assistant will see that these files are not present, and commit a removal to git.
+
+Then when another machine syncs with that, it would delete the files from its repository too. However, it actually keeps the contents of the files stashed away in `.git/annex`. So to recover from this, all you have to do is `git annex indirect` and `git revert` the commit that deleted the files. All your files would then be available again.
+
+However, what you describe is instead that the assistant chose to drop the content associated with the files, but kept the symlinks for them checked into git.
+I don't understand why it would do that. Can you show the output of running, on the desktop machine:
+
+ git annex whereis $somefile
+ git annex get $somefile
+
+Where $somefile is one of the files that has been reduced to a symlink.
+
+Looking at your logs, they appear to be the logs from the server. The strange thing that appears in one of them is \"git-annex: Not in a git repository.\"
+which was logged around 2013-10-24 20:07:25 CEST. I am not sure, but I think it might have been the rpi git-annex saying that, because there is also \"fatal: '~/store/annex/' does not appear to be a git repository\"
+"""]]
diff --git a/doc/bugs/Corrupted_drive:_Assistant_seems_consider_files_deleted_and_deletes_them_elsewhere_too/comment_2_e6bc6d1c0eb8c469e9e00b37bbcc9b86._comment b/doc/bugs/Corrupted_drive:_Assistant_seems_consider_files_deleted_and_deletes_them_elsewhere_too/comment_2_e6bc6d1c0eb8c469e9e00b37bbcc9b86._comment
new file mode 100644
index 000000000..18959ed68
--- /dev/null
+++ b/doc/bugs/Corrupted_drive:_Assistant_seems_consider_files_deleted_and_deletes_them_elsewhere_too/comment_2_e6bc6d1c0eb8c469e9e00b37bbcc9b86._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnZEanlyzay_QlEAL0CWpyZcRTyN7vay8U"
+ nickname="Carlo"
+ subject="comment 2"
+ date="2013-10-27T19:26:42Z"
+ content="""
+Thanks for looking into it and the recover instructions, will recover and post back when I'm back at work. I also have an another indirect mode repo on my home desktop as an extra backup so nothing real bad happened, but it's reassuring data's still there at work.
+
+"""]]
diff --git a/doc/bugs/Corrupted_drive:_Assistant_seems_consider_files_deleted_and_deletes_them_elsewhere_too/comment_5_0d0f6b6b46d0153433fead2bbd1bbe64._comment b/doc/bugs/Corrupted_drive:_Assistant_seems_consider_files_deleted_and_deletes_them_elsewhere_too/comment_5_0d0f6b6b46d0153433fead2bbd1bbe64._comment
new file mode 100644
index 000000000..a254b31a8
--- /dev/null
+++ b/doc/bugs/Corrupted_drive:_Assistant_seems_consider_files_deleted_and_deletes_them_elsewhere_too/comment_5_0d0f6b6b46d0153433fead2bbd1bbe64._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnZEanlyzay_QlEAL0CWpyZcRTyN7vay8U"
+ nickname="Carlo"
+ subject="comment 5"
+ date="2013-10-30T15:05:37Z"
+ content="""
+The assistant autorecovered my work repo before I noticed, so it looks like I can't provide the necessary info. There were a bunch of files missing that got re-synced from my home PC.
+
+For what it's worth, I noticed that on my phone, when cutting the internet connection while syncing, the assistant downloaded existing files into placeholder files, and then continued actually downloading files when the network connection was restored.
+
+
+"""]]
diff --git a/doc/bugs/Corrupted_drive:_Assistant_seems_consider_files_deleted_and_deletes_them_elsewhere_too/comment_5_6058a22b733cb02126286af950074ed4._comment b/doc/bugs/Corrupted_drive:_Assistant_seems_consider_files_deleted_and_deletes_them_elsewhere_too/comment_5_6058a22b733cb02126286af950074ed4._comment
new file mode 100644
index 000000000..33e85c772
--- /dev/null
+++ b/doc/bugs/Corrupted_drive:_Assistant_seems_consider_files_deleted_and_deletes_them_elsewhere_too/comment_5_6058a22b733cb02126286af950074ed4._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 5"
+ date="2013-11-03T01:17:39Z"
+ content="""
+I don't understand what you mean by \"The assistant autorecovered my work repo before I noticed\". What repo is the work repo, and how could the assistant \"autorecover\" it, and what did it do?
+
+At this point, I am completely in the dark about whether you're reporting a problem, and what the problem is.
+"""]]
diff --git a/doc/bugs/Corrupted_drive:_Assistant_seems_consider_files_deleted_and_deletes_them_elsewhere_too/comment_6_593a49669e2fadfb91773f8c84fbb031._comment b/doc/bugs/Corrupted_drive:_Assistant_seems_consider_files_deleted_and_deletes_them_elsewhere_too/comment_6_593a49669e2fadfb91773f8c84fbb031._comment
new file mode 100644
index 000000000..af31edcf8
--- /dev/null
+++ b/doc/bugs/Corrupted_drive:_Assistant_seems_consider_files_deleted_and_deletes_them_elsewhere_too/comment_6_593a49669e2fadfb91773f8c84fbb031._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnZEanlyzay_QlEAL0CWpyZcRTyN7vay8U"
+ nickname="Carlo"
+ subject="comment 6"
+ date="2013-10-31T10:03:01Z"
+ content="""
+Of course, the autorecovery wouldn't affect the daemon.log from the work machine... so here they are: http://capocasa.name/work-desktop-ubuntu-12.04-daemonlog.tgz
+"""]]
diff --git a/doc/bugs/Corrupted_drive:_Assistant_seems_consider_files_deleted_and_deletes_them_elsewhere_too/comment_6_5a348c5f327f16e1192ef6bd7f2880bb._comment b/doc/bugs/Corrupted_drive:_Assistant_seems_consider_files_deleted_and_deletes_them_elsewhere_too/comment_6_5a348c5f327f16e1192ef6bd7f2880bb._comment
new file mode 100644
index 000000000..7e611cebd
--- /dev/null
+++ b/doc/bugs/Corrupted_drive:_Assistant_seems_consider_files_deleted_and_deletes_them_elsewhere_too/comment_6_5a348c5f327f16e1192ef6bd7f2880bb._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnZEanlyzay_QlEAL0CWpyZcRTyN7vay8U"
+ nickname="Carlo"
+ subject="comment 6"
+ date="2013-11-19T09:48:26Z"
+ content="""
+Sorry, missed the comment.
+
+My work repo is the repository on my work laptop, where deletions got synced to.
+
+Git annex had then run repository repair automatically, so the odd symlinks where no longer there for me to check out.
+
+It is possible that I ran some git commands in direct mode I shouldn't have; I put the files back in and it's working nicely now. So this might have been a \"no direct mode guard\" issue.
+
+"""]]
diff --git a/doc/bugs/Could_not_find_module_Data.Default.mdwn b/doc/bugs/Could_not_find_module_Data.Default.mdwn
new file mode 100644
index 000000000..64202de42
--- /dev/null
+++ b/doc/bugs/Could_not_find_module_Data.Default.mdwn
@@ -0,0 +1,33 @@
+**What steps will reproduce the problem?**
+
+Manually building git-annex from git.
+
+**What is the expected output? What do you see instead?**
+
+ $ cabal update
+ ...
+ $ cabal install --only-dependencies
+ ...
+ $ cabal configure
+ ...
+ $ cabal build
+ Building git-annex-3.20120826...
+ Preprocessing executable 'git-annex' for git-annex-3.20120826...
+
+ Utility/Yesod.hs:15:8:
+ Could not find module `Data.Default'
+ It is a member of the hidden package `data-default-0.5.0'.
+ Perhaps you need to add `data-default' to the build-depends in your .cabal file.
+ Use -v to see a list of the files searched for.
+ $
+
+**What version of git-annex are you using? On what operating system?**
+
+commit e7d728672a5fc923be9ab1d6fe4b65f2058b49c7
+Arch Linux
+
+**Please provide any additional information below.**
+
+When I add data-default to git-annex.cabal's Build-Deps it works fine.
+
+> Thanks, [[done]]. --[[Joey]]
diff --git a/doc/bugs/Could_not_read_from_remote_repository.mdwn b/doc/bugs/Could_not_read_from_remote_repository.mdwn
new file mode 100644
index 000000000..e4f7b9c43
--- /dev/null
+++ b/doc/bugs/Could_not_read_from_remote_repository.mdwn
@@ -0,0 +1,24 @@
+### Please describe the problem.
+
+I've been using git-annex for a few weeks now, and everything was working fine until today. Now, when git-annex goes to sync my files, it will hang for a while, and then display a red box on the left side, saying `! Synced with adam.liter`. So, basically, it doesn't really sync. The logs say that it cannot read from the remote repository, which is set up on box.com and was working just fine until today.
+
+I've tried reconfiguring my jabber account on all my devices with git-annex as well as deleting and remaking the box.com repository, and none of these steps have solved the problem.
+
+### What steps will reproduce the problem?
+
+Making changes to any file located in the repository.
+
+### What version of git-annex are you using? On what operating system?
+
+Mac OS X 10.8.4 and git-annex version 4.20130801-gc88bbc4.
+
+### Please provide any additional information below.
+
+[[!format sh """
+[2013-09-09 01:33:03 EDT] XMPPSendPack: Syncing with adam.liter
+Already up-to-date.
+fatal: Could not read from remote repository.
+
+Please make sure you have the correct access rights
+and the repository exists.
+"""]]
diff --git a/doc/bugs/Could_not_read_from_remote_repository/comment_1_da842a9d146bcd5c7773b58364c25597._comment b/doc/bugs/Could_not_read_from_remote_repository/comment_1_da842a9d146bcd5c7773b58364c25597._comment
new file mode 100644
index 000000000..c236beacd
--- /dev/null
+++ b/doc/bugs/Could_not_read_from_remote_repository/comment_1_da842a9d146bcd5c7773b58364c25597._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.255.110"
+ subject="comment 1"
+ date="2013-09-09T06:01:18Z"
+ content="""
+From the small bit of log posted, it seems to be failing to sync over XMPP. Perhaps the XMPP server is down or it cannot connect? You can turn on debugging to get a lot more debugging about XMPP sync attempts.
+"""]]
diff --git a/doc/bugs/Could_not_read_from_remote_repository/comment_2_82746a0cf989d884cd0fd796db092b3c._comment b/doc/bugs/Could_not_read_from_remote_repository/comment_2_82746a0cf989d884cd0fd796db092b3c._comment
new file mode 100644
index 000000000..8312bb3a3
--- /dev/null
+++ b/doc/bugs/Could_not_read_from_remote_repository/comment_2_82746a0cf989d884cd0fd796db092b3c._comment
@@ -0,0 +1,36 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkgH7oNEqNbh3g-N1-UHXuqleXaRYDgj1U"
+ nickname="Adam"
+ subject="comment 2"
+ date="2013-09-09T06:12:44Z"
+ content="""
+This is what is in the logs after I turned on debugging:
+
+ [2013-09-09 02:04:22 EDT] XMPPSendPack: finished running push Pushing \"a29\" (PushRequest (UUID \"c96c8493-b702-4ca0-9a88-f8a38dd6c3f5\")) True
+ [2013-09-09 02:04:22 EDT] XMPPSendPack: started running push Pushing \"a29\" (PushRequest (UUID \"c96c8493-b702-4ca0-9a88-f8a38dd6c3f5\"))
+ [2013-09-09 02:04:22 EDT] read: git [\"--git-dir=/Users/adamliter/Library/texmf/.git\",\"--work-tree=/Users/adamliter/Library/texmf\",\"symbolic-ref\",\"HEAD\"]
+ [2013-09-09 02:04:22 EDT] read: git [\"--git-dir=/Users/adamliter/Library/texmf/.git\",\"--work-tree=/Users/adamliter/Library/texmf\",\"show-ref\",\"refs/heads/master\"]
+ [2013-09-09 02:04:22 EDT] call: git [\"--git-dir=/Users/adamliter/Library/texmf/.git\",\"--work-tree=/Users/adamliter/Library/texmf\",\"branch\",\"-f\",\"synced/master\"]
+ [2013-09-09 02:04:22 EDT] XMPPSendPack: Syncing with adam.liter
+ [2013-09-09 02:04:22 EDT] call: git [\"--git-dir=/Users/adamliter/Library/texmf/.git\",\"--work-tree=/Users/adamliter/Library/texmf\",\"push\",\"adam.liter\",\"git-annex:refs/synced/6258750b-9b0d-4f05-b443-61f4fb0a3f66/YWRhbS5saXRlckBnbWFpbC5jb20=/git-annex\",\"refs/heads/master:refs/synced/6258750b-9b0d-4f05-b443-61f4fb0a3f66/YWRhbS5saXRlckBnbWFpbC5jb20=/master\"]
+ [2013-09-09 02:04:22 EDT] XMPPClient: sending: Pushing \"a29\" (StartingPush (UUID \"6258750b-9b0d-4f05-b443-61f4fb0a3f66\"))
+ [2013-09-09 02:04:22 EDT] XMPPClient: to client: a10/F4E99F98
+ [2013-09-09 02:04:23 EDT] XMPPReceivePack: timeout waiting for git send-pack output via XMPP
+ fatal: The remote end hung up unexpectedly
+ [2013-09-09 02:04:23 EDT] XMPPReceivePack: finished running push Pushing \"a29\" (StartingPush (UUID \"c96c8493-b702-4ca0-9a88-f8a38dd6c3f5\")) True
+ [2013-09-09 02:04:23 EDT] XMPPClient: sending: Pushing \"a29\" (ReceivePackDone (ExitFailure 128))
+ [2013-09-09 02:04:23 EDT] XMPPReceivePack: started running push Pushing \"a29\" (StartingPush (UUID \"c96c8493-b702-4ca0-9a88-f8a38dd6c3f5\"))
+ [2013-09-09 02:04:23 EDT] XMPPClient: to client: a10/F4E99F98
+ [2013-09-09 02:04:23 EDT] XMPPReceivePack: Syncing with adam.liter
+ [2013-09-09 02:04:23 EDT] chat: git [\"receive-pack\",\"/Users/adamliter/Library/texmf\"]
+ [2013-09-09 02:04:23 EDT] XMPPClient: sending: Pushing \"a29\" (ReceivePackOutput 1 \"<elided>\")
+ [2013-09-09 02:04:23 EDT] XMPPClient: to client: a10/F4E99F98
+ [2013-09-09 02:04:23 EDT] XMPPClient: sending: Pushing \"a29\" (ReceivePackOutput 2 \"<elided>\")
+ [2013-09-09 02:04:23 EDT] XMPPClient: to client: a10/F4E99F98
+ [2013-09-09 02:04:23 EDT] XMPPClient: received: [\"Pushing \\"a29\\" (StartingPush (UUID \\"c96c8493-b702-4ca0-9a88-f8a38dd6c3f5\\"))\"]
+ [2013-09-09 02:04:23 EDT] XMPPClient: received: [\"Unknown message\"]
+
+
+
+
+"""]]
diff --git a/doc/bugs/Could_not_resolve_dependencies.mdwn b/doc/bugs/Could_not_resolve_dependencies.mdwn
new file mode 100644
index 000000000..9eb98f31e
--- /dev/null
+++ b/doc/bugs/Could_not_resolve_dependencies.mdwn
@@ -0,0 +1,40 @@
+I'm not able to install git-annex with cabal.
+
+What steps will reproduce the problem?
+
+ bbigras@bbigras-VirtualBox:~$ cabal update
+ Downloading the latest package list from hackage.haskell.org
+ bbigras@bbigras-VirtualBox:~$ cabal install git-annex --bindir=$HOME/bin
+ Resolving dependencies...
+ cabal: Could not resolve dependencies:
+ trying: git-annex-3.20130207 (user goal)
+ trying: git-annex-3.20130207:+webdav
+ trying: git-annex-3.20130207:+webapp
+ trying: git-annex-3.20130207:+assistant
+ trying: yesod-1.1.8.2 (dependency of git-annex-3.20130207:+assistant)
+ trying: yesod-auth-1.1.5.2 (dependency of yesod-1.1.8.2)
+ trying: authenticate-1.3.2.4 (dependency of yesod-auth-1.1.5.2)
+ trying: xml-conduit-1.1.0.1 (dependency of authenticate-1.3.2.4)
+ next goal: DAV (dependency of git-annex-3.20130207:+webdav)
+ rejecting: DAV-0.3 (conflict: xml-conduit==1.1.0.1, DAV => xml-conduit>=1.0 &&
+ <=1.1)
+ rejecting: DAV-0.2, 0.1, 0.0.1, 0.0 (conflict: git-annex-3.20130207:webdav =>
+ DAV(>=0.3))
+ bbigras@bbigras-VirtualBox:~$
+
+
+What version of git-annex are you using? On what operating system?
+
+Ubuntu 12.10 x86_64
+
+cabal-install version 0.14.0
+using version 1.14.0 of the Cabal library
+
+> The Haskell DAV library needs to be updated to build with
+> the newer version of xml-conduit. Library skew of this sort
+> is common when using cabal.
+>
+> You can work around this by building git-annex without webdav:
+> `cabal configure --flags=-WebDAV`
+>
+> This is not a git-annex bug. [[done]] --[[Joey]]
diff --git a/doc/bugs/Crash_trying_to_sync_with_a_repo_over_ssh.mdwn b/doc/bugs/Crash_trying_to_sync_with_a_repo_over_ssh.mdwn
new file mode 100644
index 000000000..38f54d2b6
--- /dev/null
+++ b/doc/bugs/Crash_trying_to_sync_with_a_repo_over_ssh.mdwn
@@ -0,0 +1,43 @@
+What steps will reproduce the problem?
+
+I create a new annex, added in a bunch of files.
+
+I cloned this annex to another machine, where I already had those files, so I copied them into a directory named "foo", did "git annex add foo", and then did "git rm -r foo", and git commit'd my clone of the annex.
+
+Then I try to "git annex sync" with the remote.
+
+What is the expected output? What do you see instead?
+
+I don't know, I've never used git-annex before. This is what I get each time:
+
+ Hermes ~/Products/tmp/Movies (master) $ ga sync
+ git-annex-shell: Prelude.(!!): index too large
+
+What version of git-annex are you using? On what operating system?
+
+It's the 'master' as of yesterday: c504f4025fec49e62601fbd4a3cd8f1270c7d221
+
+I'm on OS X 10.8.2, using GHC 7.6.1. The annex in question has 38G in a few hundred files.
+
+Please provide any additional information below.
+
+I'm willing to help track this down!
+
+> I've got it, October 9th's release
+> included commit bc649a35bacbecef93e378b1497f6a05b30bf452, which included a
+> change to a `segment` function. It was supposed to be a
+> rewrite in terms of a more general version, but it introduced a bug
+> in what it returned in an edge case and this in turn led git-annex-shell's
+> parameter parser to fail in a code path that was never reachable before.
+>
+> It'd fail both when a new repo was running `git-annex-shell configlist`,
+> and in `git-annex-shell commit`, although this latter crash was less
+> noticible and I'm sure you saw the former.
+>
+> Fixed the reversion; fixed insufficient guards around the partial code
+> (which I cannot see a way to entirely eliminate sadly; look at
+> GitAnnexShell.hs's `partitionParams` and weep or let me know if you have
+> any smart ideas..); added a regression test to check the non-obvious
+> behavior of segment with an empty segment. I'll be releasing a new
+> version with this fix as soon as I have bandwidth, ie tomorrow.
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/Crash_trying_to_sync_with_a_repo_over_ssh/comment_1_9705f295ad8101f3f0ede18e590b56ef._comment b/doc/bugs/Crash_trying_to_sync_with_a_repo_over_ssh/comment_1_9705f295ad8101f3f0ede18e590b56ef._comment
new file mode 100644
index 000000000..660b52e7f
--- /dev/null
+++ b/doc/bugs/Crash_trying_to_sync_with_a_repo_over_ssh/comment_1_9705f295ad8101f3f0ede18e590b56ef._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/2grhJvAC049fJnvALDXek.6MRZMTlg--#eec89"
+ nickname="John"
+ subject="I can confirm the fix"
+ date="2012-10-16T05:53:15Z"
+ content="""
+It's working great now, thanks Joey!
+"""]]
diff --git a/doc/bugs/Crash_trying_to_sync_with_a_repo_over_ssh/comment_2_0d751d81ac618f8d7e3f1dd20c830542._comment b/doc/bugs/Crash_trying_to_sync_with_a_repo_over_ssh/comment_2_0d751d81ac618f8d7e3f1dd20c830542._comment
new file mode 100644
index 000000000..5622bd6da
--- /dev/null
+++ b/doc/bugs/Crash_trying_to_sync_with_a_repo_over_ssh/comment_2_0d751d81ac618f8d7e3f1dd20c830542._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.8"
+ subject="comment 2"
+ date="2012-10-16T05:56:10Z"
+ content="""
+And I found a clean way to avoid that partial !! too. :) Down to 22 of the little monsters to clean up now.
+"""]]
diff --git a/doc/bugs/Crash_when_adding_jabber_account_.mdwn b/doc/bugs/Crash_when_adding_jabber_account_.mdwn
new file mode 100644
index 000000000..678890cad
--- /dev/null
+++ b/doc/bugs/Crash_when_adding_jabber_account_.mdwn
@@ -0,0 +1,32 @@
+*What steps will reproduce the problem?*
+
+1. Start git-annex webapp
+2. Configuration
+3. Configure Jabber Account
+4. Insert user and pass
+5. Click "User this account"
+
+Tryed 4 times, all the same.
+
+
+*What is the expected output? What do you see instead?*
+
+On Chrome I get "Error 101 (net::ERR_CONNECTION_RESET): The connection was reset." or "Error 324 (net::ERR_EMPTY_RESPONSE): The server closed the connection without sending any data."
+
+On the terminal where git-annex was running I get "Segmentation fault (core dumped)"
+
+
+*What version of git-annex are you using? On what operating system?*
+
+git-annex version: I downloaded 3.20130107 (twice to be sure), but for some reason 'git-annex version' reports 3.20130102
+
+OS: Ubuntu 12.04.1 LTS 3.2.0-35-generic-pae #55-Ubuntu SMP Wed Dec 5 18:04:39 UTC 2012 i686 i686 i386 GNU/Linux
+
+
+*Please provide any additional information below.*
+
+On dmesg:
+[45773.212717] git-annex[26779]: segfault at b724e840 ip 09699150 sp b4cfd038 error 7 in git-annex[8048000+1762000]
+
+[[!tag /design/assistant]]
+> [[done]], see comments --[[Joey]]
diff --git a/doc/bugs/Crash_when_adding_jabber_account_/comment_1_2dc61ebcfa8919fb839656999c155c52._comment b/doc/bugs/Crash_when_adding_jabber_account_/comment_1_2dc61ebcfa8919fb839656999c155c52._comment
new file mode 100644
index 000000000..c32ee75de
--- /dev/null
+++ b/doc/bugs/Crash_when_adding_jabber_account_/comment_1_2dc61ebcfa8919fb839656999c155c52._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.238"
+ subject="comment 1"
+ date="2013-01-14T16:39:00Z"
+ content="""
+Are you using the 64 bit or the 32 bit build? Did you download the standalone tarball? How are you running git-annex exactly? (Using runshell, or by hand?)
+
+A segfault here seems likely to involve the Haskell GNUTLS binding. At least, the only other time git-annex has segfaulted, which also involved jabber, it was a bug in the GNUTLS binding.
+"""]]
diff --git a/doc/bugs/Crash_when_adding_jabber_account_/comment_2_e49af3b8a937d82eda1509b6f67b21d4._comment b/doc/bugs/Crash_when_adding_jabber_account_/comment_2_e49af3b8a937d82eda1509b6f67b21d4._comment
new file mode 100644
index 000000000..03f7a2069
--- /dev/null
+++ b/doc/bugs/Crash_when_adding_jabber_account_/comment_2_e49af3b8a937d82eda1509b6f67b21d4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn-4QWOFI0QQ4n-yu-oFq3PHeuSPUv_-b4"
+ nickname="Rodrigo"
+ subject="comment 2"
+ date="2013-01-14T22:10:44Z"
+ content="""
+32 bit. Yes, the standalone tarball. From terminal, I'm simply running: git-annex webapp
+"""]]
diff --git a/doc/bugs/Crash_when_adding_jabber_account_/comment_3_e59f8813bf1a7c4e3c8c120fe82348b9._comment b/doc/bugs/Crash_when_adding_jabber_account_/comment_3_e59f8813bf1a7c4e3c8c120fe82348b9._comment
new file mode 100644
index 000000000..763f6fe53
--- /dev/null
+++ b/doc/bugs/Crash_when_adding_jabber_account_/comment_3_e59f8813bf1a7c4e3c8c120fe82348b9._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-03-18T23:42:55Z"
+ content="""
+I tried to reproduce this with the standalone i386 tarball for 4.20130314. Was able to add a jabber account using my google talk account with no crash.
+
+Given the age of this bug report, I'm just going to close it. But if you still see it with the current verison, please let me know! (And I guess you'd have to tell me which jabber server you're using then..)
+"""]]
diff --git a/doc/bugs/Crash_when_adding_jabber_account_/comment_4_716ac138cb69eecd0fb586699b4aeb2a._comment b/doc/bugs/Crash_when_adding_jabber_account_/comment_4_716ac138cb69eecd0fb586699b4aeb2a._comment
new file mode 100644
index 000000000..9039faca5
--- /dev/null
+++ b/doc/bugs/Crash_when_adding_jabber_account_/comment_4_716ac138cb69eecd0fb586699b4aeb2a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmu416zAYgYzbXVZAe30MiXoOWO4z6nGX8"
+ nickname="Johannes"
+ subject="signal 11"
+ date="2013-04-03T15:13:05Z"
+ content="""
+I'm getting a \"error: git-annex died of signal 11\" when trying to add a self-hosted jabber account. I'm using ejabberd and a self-signed SSL certificate.
+"""]]
diff --git a/doc/bugs/Creating_an_S3_repository_with_an_invalid_name_throws_an_exception.mdwn b/doc/bugs/Creating_an_S3_repository_with_an_invalid_name_throws_an_exception.mdwn
new file mode 100644
index 000000000..48b30eceb
--- /dev/null
+++ b/doc/bugs/Creating_an_S3_repository_with_an_invalid_name_throws_an_exception.mdwn
@@ -0,0 +1,18 @@
+What steps will reproduce the problem?
+
+Attempt to create an S3 repository called 'S3 (encrypted)' via the web app.
+
+What is the expected output? What do you see instead?
+
+Expected to either accept this input, or tell me that it's invalid. Instead, I see:
+
+Internal Server Error
+user error (openTCPConnection: host lookup failure for "S3 (encrypted)-610526e6-5ce2-11e2-997e-970cbca93f19.s3.amazonaws.com")
+
+What version of git-annex are you using? On what operating system?
+
+3.20130107 On Fedora 17 (64-bit).
+
+Please provide any additional information below.
+
+> [[done]], the name will now be sanitized. --[[Joey]]
diff --git a/doc/bugs/Creating_an_encrypted_S3_does_not_check_for_presence_of_GPG.mdwn b/doc/bugs/Creating_an_encrypted_S3_does_not_check_for_presence_of_GPG.mdwn
new file mode 100644
index 000000000..a4bfdcb39
--- /dev/null
+++ b/doc/bugs/Creating_an_encrypted_S3_does_not_check_for_presence_of_GPG.mdwn
@@ -0,0 +1,18 @@
+What steps will reproduce the problem?
+
+Don't have gpg installed/on your $PATH, and attempt to create an encrypted S3 remote via the web interface.
+
+What is the expected output? What do you see instead?
+
+Expected to be told to install GPG. Actual output was a Yesod error:
+
+Internal Server Error
+user error (gpg ["--batch","--no-tty","--use-agent","--quiet","--trust-model","always","--gen-random","--armor","1","512"] exited 127)
+
+What version of git-annex are you using? On what operating system?
+
+3.20130107 on Fedora 17 (64-bit).
+
+Please provide any additional information below.
+
+[[!tag /design/assistant]]
diff --git a/doc/bugs/Creating_second_repository_leads_to_wrong_ip___40__using_git-annex_webapp_--listen__41__.mdwn b/doc/bugs/Creating_second_repository_leads_to_wrong_ip___40__using_git-annex_webapp_--listen__41__.mdwn
new file mode 100644
index 000000000..28b74bd98
--- /dev/null
+++ b/doc/bugs/Creating_second_repository_leads_to_wrong_ip___40__using_git-annex_webapp_--listen__41__.mdwn
@@ -0,0 +1,35 @@
+### Please describe the problem.
+Using the git-annex webapp in remote mode will forward to the wrong IP (localhost) when creating the second repository
+
+### What steps will reproduce the problem?
+Needs two computers (C1, C2)
+
+- C1: run "git-annex webapp --listen=[IP of C1]
+- C2: use a browser to go to the address you just got on C1 (should contain IP of C1)
+- C2: create an repository as prompted (should work fine)
+- C2: In the dropdown on the top right select "Add another repository", choose desired location, select keep separate
+- C2: Browser forwards to new address, but instead of the IP of C1, 127.0.0.1 is used (which obviously fails)
+
+### What version of git-annex are you using? On what operating system?
+
+[[!format sh """
+$ git-annex version
+git-annex version: 4.20130802
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP
+$ lsb_release -d
+Description: Ubuntu 13.04
+$ uname -a
+Linux nas 3.8.0-27-generic #40-Ubuntu SMP Tue Jul 9 00:19:35 UTC 2013 i686 i686 i686 GNU/Linux
+"""]]
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
+
+> This is a different effect of the same bug in [[Hangs on creating repository when using --listen]]. Closing as [[dup|done]] --[[Joey]]
diff --git a/doc/bugs/DS__95__Store_not_gitignored.mdwn b/doc/bugs/DS__95__Store_not_gitignored.mdwn
new file mode 100644
index 000000000..269eb417a
--- /dev/null
+++ b/doc/bugs/DS__95__Store_not_gitignored.mdwn
@@ -0,0 +1,26 @@
+What steps will reproduce the problem?
+
+Create a new git repo on OS X. create a .gitignore file containing the line ".DS_Store". Check it into git. do "git annex init" to make the directory into a git annex repo. do "git annex direct" to put it in direct mode. do "git annex assistant" to start the assistant and watch it with "git annex webapp".
+
+Open the directory in the finder. Drag in some files and watch the assistant as it checks them in. Play with your window's viewing preferences, maybe view things as "icons" so that the finder is forced to store metadata about where you dragged the icons in the window in the .DS_Store file. As you do this, watch the webapp. .DS_Store will start to be checked into git annex, and rechecked in frequently as it is updated. Git annex assistant is not respecting the .gitignore file. Is there some other way to tell git annex assistant that certain files should be ignored than .gitignore?
+
+
+What is the expected output? What do you see instead?
+
+.DS_Store files are ignored by the assistant.
+
+
+What version of git-annex are you using? On what operating system?
+
+git-annex version: 3.20130124
+
+OS X Lion
+
+Please provide any additional information below.
+
+> Assistant does not support .gitignore yet. Requires an efficient query
+> interface for ignores, which git does not provide.
+>
+> However, I've added a special case, OSX only ignore for .DS_Store files.
+> [[done]] --[[Joey]]
+
diff --git a/doc/bugs/DS__95__Store_not_gitignored/comment_1_b93ac0ea3be82c361ceb4352e742ba39._comment b/doc/bugs/DS__95__Store_not_gitignored/comment_1_b93ac0ea3be82c361ceb4352e742ba39._comment
new file mode 100644
index 000000000..0bc821f87
--- /dev/null
+++ b/doc/bugs/DS__95__Store_not_gitignored/comment_1_b93ac0ea3be82c361ceb4352e742ba39._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 1"
+ date="2013-01-28T14:31:53Z"
+ content="""
+outstanding! Thank you.
+"""]]
diff --git a/doc/bugs/DS__95__Store_not_gitignored/comment_2_4136e1f4aba7aa7562dafcf6a213e10c._comment b/doc/bugs/DS__95__Store_not_gitignored/comment_2_4136e1f4aba7aa7562dafcf6a213e10c._comment
new file mode 100644
index 000000000..209e0545a
--- /dev/null
+++ b/doc/bugs/DS__95__Store_not_gitignored/comment_2_4136e1f4aba7aa7562dafcf6a213e10c._comment
@@ -0,0 +1,58 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmRFKwny4rArBaz-36xTcsJYqKIgdDaw5Q"
+ nickname="Andrew"
+ subject="comment 2"
+ date="2013-01-28T23:26:27Z"
+ content="""
+This actually explains an interesting quirk (I wouldn't necessarily call it a bug) that results because of annex's handling of .gitignore:
+
+ % › git annex import ~/Downloads/BoxcarMac.dmg
+ import BoxcarMac.dmg (checksum...) ok
+ (Recording state in git...)
+ The following paths are ignored by one of your .gitignore files:
+ BoxcarMac.dmg
+ Use -f if you really want to add them.
+ fatal: no files added
+
+ git-annex: user error (xargs [\"-0\",\"git\",\"--git-dir=/Users/akraut/Desktop/annexes/test/.git\",\"--work-tree=/Users/akraut/Desktop/annexes/test\",\"add\",\"--\"] exited 1)
+ failed
+ git-annex: import: 1 failed
+
+ % › ls -l
+ total 8
+ lrwxr-xr-x 1 akraut staff 198 Jan 28 15:01 BoxcarMac.dmg -> .git/annex/objects/K4/Q8/SHA256E-s6240024--2d3b032f29c8411f81f9379bd79abfa713b66b9783559ef48cd945ab418e97a3.dmg/SHA256E-s6240024--2d3b032f29c8411f81f9379bd79abfa713b66b9783559ef48cd945ab418e97a3.dmg
+ -rw-r--r-- 1 akraut staff 0 Jan 28 14:56 README
+ lrwxr-xr-x 1 akraut staff 200 Jan 28 14:58 Wireshark 1.8.4 Intel 64.dmg -> .git/annex/objects/vj/55/SHA256E-s21772874--eb01484d832a9dc5b8fdecacdccabc4ef28fb17a2e20bc2837ccc43a69df30c5.dmg/SHA256E-s21772874--eb01484d832a9dc5b8fdecacdccabc4ef28fb17a2e20bc2837ccc43a69df30c5.dmg
+
+ % › cp ~/Downloads/Wireshark\ 1.8.4\ Intel\ 64.dmg .
+
+ % › git annex add Wireshark\ 1.8.4\ Intel\ 64.dmg
+ (Recording state in git...)
+
+ % › ls -l
+ total 21264
+ -rw-r--r-- 1 akraut staff 0 Jan 28 14:56 README
+ -rw-r--r-- 1 akraut staff 21772874 Jan 28 14:58 Wireshark 1.8.4 Intel 64.dmg
+
+ % › git annex import Wireshark\ 1.8.4\ Intel\ 64.dmg
+ import Wireshark 1.8.4 Intel 64.dmg git-annex: not overwriting existing Wireshark 1.8.4 Intel 64.dmg (use --force to override)
+
+ % › git annex import --force Wireshark\ 1.8.4\ Intel\ 64.dmg
+ import Wireshark 1.8.4 Intel 64.dmg (checksum...) ok
+ (Recording state in git...)
+
+ % › ls
+ README Wireshark 1.8.4 Intel 64.dmg@
+
+ % › git annex sync
+ commit
+ [master 0a17811] git-annex automatic sync
+ 1 file changed, 1 insertion(+)
+ create mode 120000 Wireshark 1.8.4 Intel 64.dmg
+ ok
+
+ % › ls -l
+ total 4
+ -rw-r--r-- 1 akraut staff 0 Jan 28 14:56 README
+ lrwxr-xr-x 1 akraut staff 200 Jan 28 14:58 Wireshark 1.8.4 Intel 64.dmg -> .git/annex/objects/vj/55/SHA256E-s21772874--eb01484d832a9dc5b8fdecacdccabc4ef28fb17a2e20bc2837ccc43a69df30c5.dmg/SHA256E-s21772874--eb01484d832a9dc5b8fdecacdccabc4ef28fb17a2e20bc2837ccc43a69df30c5.dmg
+"""]]
diff --git a/doc/bugs/Deasn__39__t_clean_up_ssh_keys_after_removing_remote_repo.mdwn b/doc/bugs/Deasn__39__t_clean_up_ssh_keys_after_removing_remote_repo.mdwn
new file mode 100644
index 000000000..0899ea467
--- /dev/null
+++ b/doc/bugs/Deasn__39__t_clean_up_ssh_keys_after_removing_remote_repo.mdwn
@@ -0,0 +1,18 @@
+### Please describe the problem.
+I created a remote repo on ssh server with the same git-annex version, no personal ssh keys for the repo (password authentication). But I put ~ in front of the repo name so it created in different place than I wanted. I deleted it from assistant and then deleted the remote repo dir. When I added it with the correct path again it always asks for server password (it has some old annex pub key in authorized_keys, but not the new one; it might have been prompted for the password also with the initial repo). During the whole thing it failed to connect a few times due to wrong password or me realizing too late that it asks for yet another one and it generated keys few times, but ultimately didn't put the last one in remote's authorized_keys.
+
+### What steps will reproduce the problem?
+Create, delete and create again a new repo on remote ssh server with password auth.
+
+### What version of git-annex are you using? On what operating system?
+git-annex 4.20130601 Gentoo amd64
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
diff --git a/doc/bugs/Deasn__39__t_clean_up_ssh_keys_after_removing_remote_repo/comment_1_88fbf70eae48484988dbb433a437c717._comment b/doc/bugs/Deasn__39__t_clean_up_ssh_keys_after_removing_remote_repo/comment_1_88fbf70eae48484988dbb433a437c717._comment
new file mode 100644
index 000000000..84686f1e4
--- /dev/null
+++ b/doc/bugs/Deasn__39__t_clean_up_ssh_keys_after_removing_remote_repo/comment_1_88fbf70eae48484988dbb433a437c717._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.193"
+ subject="comment 1"
+ date="2013-06-25T18:20:05Z"
+ content="""
+It's true that deleting a ssh repository in the webapp does not delete any ssh keys that the webapp configured to access that repository. I'm a bit reluctant to try to clean it up entirely automatically, because the ssh configuration might have been manually altered, or might be used by another local repository. Particularly, if another local repo is set up to use the same ssh remote, the webapp will reuse the ssh key.
+
+> Create, delete and create again a new repo on remote ssh server with password auth.
+
+I tried doing this, and did not encounter any problem. Since the new repo had a different path on the ssh server, I simply ended up with two ssh keys configured in `~/.ssh/config` for two different repositories. The presence or absence of the first key did not affect the second key.
+
+I think you need to go into more detail about exactly what you did, or show the files in .ssh that were set up, so I can see what the actual problem is.
+"""]]
diff --git a/doc/bugs/Detection_assumes_that_shell_is_bash.mdwn b/doc/bugs/Detection_assumes_that_shell_is_bash.mdwn
new file mode 100644
index 000000000..9bb0629d3
--- /dev/null
+++ b/doc/bugs/Detection_assumes_that_shell_is_bash.mdwn
@@ -0,0 +1,24 @@
+###What steps will reproduce the problem?###
+
+"Adding a remote server using ssh" and try to add a remote server where the account has ex. tcsh as loginshell
+
+###What is the expected output? What do you see instead?###
+
+To discover remote programs, it dumps away some born-shell code like:
+"echo git-annex-probe loggedin;if which git-annex-shell; then echo git-annex-probe git-annex-shell; fi;if which rsync; then echo git-annex-probe rsync; fi;if which ~/.ssh/git-annex-shell; then echo git-annex-probe ~/.ssh/git-annex-shell; fi"
+
+just wrap it with a bash -c '..' and you know that its interpreted by bash.
+
+###What version of git-annex are you using? On what operating system?###
+
+git-annex version: 3.20121017
+
+###Please provide any additional information below.###
+
+Not everyone has bash as there login-shell.
+
+[[!tag /design/assistant]]
+
+> [[done]]; assistant now uses sh -c "sane shell stuff here" to work
+> around csh. (There are systems without bash, but probably fewer without sh)
+> --[[Joey]]
diff --git a/doc/bugs/Difficult_to_troubleshoot_XMPP_login_failures.mdwn b/doc/bugs/Difficult_to_troubleshoot_XMPP_login_failures.mdwn
new file mode 100644
index 000000000..3b1b74d16
--- /dev/null
+++ b/doc/bugs/Difficult_to_troubleshoot_XMPP_login_failures.mdwn
@@ -0,0 +1,11 @@
+### Please describe the problem.
+
+I have a jabber account on `jabber.ccc.de`. When trying to log in to that account, I get "Unable to connect to the Jabber server. Maybe you entered the wrong password? (Error message: AuthenticationFailure)" I've typed the password enough times that I'm relatively certain that I've typed it correctly at least once. It's difficult to see behind this error message. This is the only thing that shows up in the debug log:
+
+ [2013-05-26 21:40:16 EDT] read: host ["-t","SRV","--","_xmpp-client._tcp.jabber.ccc.de"]
+ [2013-05-26 21:40:16 EDT] read: host ["-t","SRV","--","_xmpp-client._tcp.jabber.ccc.de"]
+
+It'd be great if this error were a wee bit more verbose.
+
+> The XMPP library has been updated to include the actual error message from the server.
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/Difficult_to_troubleshoot_XMPP_login_failures/comment_1_4205bccf515169031e4a9ed8e905262c._comment b/doc/bugs/Difficult_to_troubleshoot_XMPP_login_failures/comment_1_4205bccf515169031e4a9ed8e905262c._comment
new file mode 100644
index 000000000..e1b38ac5b
--- /dev/null
+++ b/doc/bugs/Difficult_to_troubleshoot_XMPP_login_failures/comment_1_4205bccf515169031e4a9ed8e905262c._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-05-27T18:35:45Z"
+ content="""
+That's all I get back from the underlying library. I have asked the library's author to propigate up the actual error message from the XMPP server if possible. The only other information I could provide is which host and port it tried to connect to. I've added that to the error message.
+
+We recently tracked a \"AuthenticationFailure\" error back to a bug in the ejabberd server's implementation of SCRAM. If jabber.ccc.de is using ejabberd, it needs to be upgraded. See <https://support.process-one.net/browse/EJAB-1632>
+"""]]
diff --git a/doc/bugs/Direct_mode_keeps_re-checksuming_duplicated_files.mdwn b/doc/bugs/Direct_mode_keeps_re-checksuming_duplicated_files.mdwn
new file mode 100644
index 000000000..123786b65
--- /dev/null
+++ b/doc/bugs/Direct_mode_keeps_re-checksuming_duplicated_files.mdwn
@@ -0,0 +1,25 @@
+##What steps will reproduce the problem?
+
+ mkdir test
+ git init
+ git annex init "test"
+ echo "test" > a
+ echo "test" > b
+ git annex add a b
+ git annex sync
+ git annex direct
+ git annex sync | grep add
+ git annex sync | grep add
+
+##What is the expected output? What do you see instead?
+
+The last two syncs shouldn't need to add or checksum anything.
+Firstly, the output is very confusing because the files have already been added.
+Secondly, the sync can take quite a while if you have lots of duplicates or a lot of files that are incidentally similar.
+
+##What version of git-annex are you using? On what operating system?
+
+git-annex version: 4.20130227 on Archlinux
+
+> [[done]]; fixed inode caching code to support multiple files for the
+> same content. --[[Joey]]
diff --git a/doc/bugs/Direct_mode_keeps_re-checksuming_duplicated_files/comment_1_cb10385a4f046bfe676720ded3409379._comment b/doc/bugs/Direct_mode_keeps_re-checksuming_duplicated_files/comment_1_cb10385a4f046bfe676720ded3409379._comment
new file mode 100644
index 000000000..6a5178bb6
--- /dev/null
+++ b/doc/bugs/Direct_mode_keeps_re-checksuming_duplicated_files/comment_1_cb10385a4f046bfe676720ded3409379._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-03-11T06:31:09Z"
+ content="""
+It seems that, to fully fix this, direct mode will need to be changed to store multiple inode caches for each key.
+
+Since the files have the same content, but different inodes and/or mtimes, at least one of them is going to appear changed to sync each time.
+
+What currently happens is that the first is re-added, and so its inode cache gets stored, and then that means the second's inode cache no longer matches, and it's re-added, and its inode cache gets stored. Putting the inode cache right back in position to force re-adding the first again..
+
+Storing multiple inode caches appears easy enough, but I have not yet worked out exactly how to clear out old inode caches.
+"""]]
diff --git a/doc/bugs/Direct_mode_keeps_re-checksuming_duplicated_files/comment_2_4bcf1a897181e40c9c8969d597a844f0._comment b/doc/bugs/Direct_mode_keeps_re-checksuming_duplicated_files/comment_2_4bcf1a897181e40c9c8969d597a844f0._comment
new file mode 100644
index 000000000..68c8847ae
--- /dev/null
+++ b/doc/bugs/Direct_mode_keeps_re-checksuming_duplicated_files/comment_2_4bcf1a897181e40c9c8969d597a844f0._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnR7hb8IaKB3IKZptRukje0yahmhfLOO98"
+ nickname="Adam"
+ subject="comment 2"
+ date="2013-04-01T19:23:12Z"
+ content="""
+I think I hit this same issue when trying to work with a significant amount of files and data. It'd be good if git-annex were smarter about when a file is identical, especially if the file was copied through `rsync -a`.
+"""]]
diff --git a/doc/bugs/Direct_mode_keeps_re-checksuming_duplicated_files/comment_3_6a6d22d218f036c9977072973ed99aa8._comment b/doc/bugs/Direct_mode_keeps_re-checksuming_duplicated_files/comment_3_6a6d22d218f036c9977072973ed99aa8._comment
new file mode 100644
index 000000000..8f4e9bc86
--- /dev/null
+++ b/doc/bugs/Direct_mode_keeps_re-checksuming_duplicated_files/comment_3_6a6d22d218f036c9977072973ed99aa8._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="identical filename"
+ date="2013-04-06T09:09:17Z"
+ content="""
+Same happens, with identical filename+content just in a different subdirectory.
+
+ annex/a.txt
+ annex/back/a.txt
+"""]]
diff --git a/doc/bugs/Direct_mode_keeps_re-checksuming_duplicated_files/comment_4_eaa7ffb3a1d9ffd6d89de301bd2cd5b2._comment b/doc/bugs/Direct_mode_keeps_re-checksuming_duplicated_files/comment_4_eaa7ffb3a1d9ffd6d89de301bd2cd5b2._comment
new file mode 100644
index 000000000..413ad8612
--- /dev/null
+++ b/doc/bugs/Direct_mode_keeps_re-checksuming_duplicated_files/comment_4_eaa7ffb3a1d9ffd6d89de301bd2cd5b2._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="comment 4"
+ date="2013-04-18T05:56:41Z"
+ content="""
+Ok, seems like it is fixed in latest (2013.04.17) release.
+
+Laszlo
+
+"""]]
diff --git a/doc/bugs/Direct_mode_repositories_end_up_with_unstaged_changes.mdwn b/doc/bugs/Direct_mode_repositories_end_up_with_unstaged_changes.mdwn
new file mode 100644
index 000000000..839653e34
--- /dev/null
+++ b/doc/bugs/Direct_mode_repositories_end_up_with_unstaged_changes.mdwn
@@ -0,0 +1,46 @@
+### Please describe the problem.
+
+After running two repositories syncing with one another in direct mode "git status" shows unstaged changes in both.
+
+### What steps will reproduce the problem?
+
+1. Create two direct mode repositories with each other as ssh remotes
+2. Run "git annex assistant" on each
+3. Create files on each and they get synced
+4. Run "git status"
+
+In my current repository the output is:
+
+[[!format sh """
+$ git status
+# On branch master
+# Changes not staged for commit:
+# (use "git add <file>..." to update what will be committed)
+# (use "git checkout -- <file>..." to discard changes in working directory)
+#
+# typechange: fromgolias
+# typechange: fromwintermute
+#
+no changes added to commit (use "git add" and/or "git commit -a")
+"""]]
+
+### What version of git-annex are you using? On what operating system?
+
+[[!format sh """
+$ git annex version
+git-annex version: 4.20130516.1
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP
+local repository version: 4
+default repository version: 3
+supported repository versions: 3 4
+upgrade supported from repository versions: 0 1 2
+
+$ lsb_release -a
+No LSB modules are available.
+Distributor ID: Ubuntu
+Description: Ubuntu 12.04.2 LTS
+Release: 12.04
+Codename: precise
+"""]]
+
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/Direct_mode_repositories_end_up_with_unstaged_changes/comment_1_300a2b246182be3079db20a7e3322261._comment b/doc/bugs/Direct_mode_repositories_end_up_with_unstaged_changes/comment_1_300a2b246182be3079db20a7e3322261._comment
new file mode 100644
index 000000000..87e90ebe7
--- /dev/null
+++ b/doc/bugs/Direct_mode_repositories_end_up_with_unstaged_changes/comment_1_300a2b246182be3079db20a7e3322261._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-05-29T16:18:33Z"
+ content="""
+This does not indicate a problem. Nor are there any unstaged changes. `git status` simply does not know about git-annex's direct mode. Please see [[/direct_mode]] for caveats about this and other problems with using regular git commands with git-annex repositories in direct mode.
+"""]]
diff --git a/doc/bugs/Direct_mode_repositories_still_use_symlinks_sometimes.mdwn b/doc/bugs/Direct_mode_repositories_still_use_symlinks_sometimes.mdwn
new file mode 100644
index 000000000..782b80e5e
--- /dev/null
+++ b/doc/bugs/Direct_mode_repositories_still_use_symlinks_sometimes.mdwn
@@ -0,0 +1,32 @@
+### Please describe the problem.
+
+When a repository is set in direct mode it will still replace files with symlinks when it becomes aware of a change but still hasn't been able to sync the file contents. This can create repositories that are temporarily unusable with files replaced with broken symlinks.
+
+### What steps will reproduce the problem?
+
+1. Create two repositories with each other as remotes
+2. Run the assistant on both
+3. Create some file changes in one and watch the directory in another.
+4. For a brief (or sometimes long) time the destination repository will have it's old version of the file replaced by a broken symlink
+
+This is particularly noticeable when using XMPP as it can often be the case that the two repositories can't connect to each other directly but can talk through XMPP. This breaks using git-annex in direct mode for things like having a synced config directory across machines. Something like having "~/.bashrc" linked into "~/annex-repository/bashrc", doesn't work as there will be times when a machine is broken because .bashrc is linked to a broken symlink while it fetches a new version.
+
+The desired behavior would be to have git-annex in direct mode only replace older versions of files with newer versions of files.
+
+### What version of git-annex are you using? On what operating system?
+
+[[!format sh """
+$ git annex version
+git-annex version: 4.20130516.1
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP
+local repository version: 4
+default repository version: 3
+supported repository versions: 3 4
+upgrade supported from repository versions: 0 1 2
+$ lsb_release -a
+No LSB modules are available.
+Distributor ID: Ubuntu
+Description: Ubuntu 12.04.2 LTS
+Release: 12.04
+Codename: precise
+"""]]
diff --git a/doc/bugs/Disconcerting_warning_from_git-annex.mdwn b/doc/bugs/Disconcerting_warning_from_git-annex.mdwn
new file mode 100644
index 000000000..169dc26d1
--- /dev/null
+++ b/doc/bugs/Disconcerting_warning_from_git-annex.mdwn
@@ -0,0 +1,6 @@
+I did a "git annex add" of a bunch of files on a storage server with low IOPS, and saw this:
+
+ git-annex: /tank/Media/Pictures/.git/annex/tmp/430_32b_SHA256E-s4464838--c1785a76ee1451f602e93c99c147e214705004e541de8256d74a3be3717d15e5.jpg.log: openBinaryFile: resource busy (file is locked)
+failed
+
+How is that even possible, when the server is doing nothing else?
diff --git a/doc/bugs/Disconcerting_warning_from_git-annex/comment_1_58cebd377bfdf247b6c4fee27a3ba461._comment b/doc/bugs/Disconcerting_warning_from_git-annex/comment_1_58cebd377bfdf247b6c4fee27a3ba461._comment
new file mode 100644
index 000000000..3076b38de
--- /dev/null
+++ b/doc/bugs/Disconcerting_warning_from_git-annex/comment_1_58cebd377bfdf247b6c4fee27a3ba461._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.211"
+ subject="comment 1"
+ date="2013-01-05T21:13:09Z"
+ content="""
+Is this a Solaris system?
+"""]]
diff --git a/doc/bugs/Disconcerting_warning_from_git-annex/comment_2_dc7407044d4c739d05248300c58d8ef2._comment b/doc/bugs/Disconcerting_warning_from_git-annex/comment_2_dc7407044d4c739d05248300c58d8ef2._comment
new file mode 100644
index 000000000..96d495e66
--- /dev/null
+++ b/doc/bugs/Disconcerting_warning_from_git-annex/comment_2_dc7407044d4c739d05248300c58d8ef2._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/2grhJvAC049fJnvALDXek.6MRZMTlg--#eec89"
+ nickname="John"
+ subject="comment 2"
+ date="2013-01-20T03:38:43Z"
+ content="""
+No, it's CentOS 6.3 x86_64.,
+"""]]
diff --git a/doc/bugs/Discrepancy_between_git_annex_add_and_git_annex_watch.mdwn b/doc/bugs/Discrepancy_between_git_annex_add_and_git_annex_watch.mdwn
new file mode 100644
index 000000000..8e836e345
--- /dev/null
+++ b/doc/bugs/Discrepancy_between_git_annex_add_and_git_annex_watch.mdwn
@@ -0,0 +1,33 @@
+### Please describe the problem.
+
+`git annex add` does not add dotfiles (as per the man page) while `git annex watch` does (nothing on the man page). It's not a bug, but rather a surprise (at least to me).
+
+### What steps will reproduce the problem?
+
+[[!format sh """
+git init dotfiles
+cd dotfiles
+git annex init "my dotfiles"
+echo test > test.txt
+echo dottest > .dotest.txt
+git annex add
+git commit -a -m "initial dots"
+git annex whereis .dotest.txt # no answer, as expected
+git annex watch
+git annex whereis .dotest.txt # answers that .dotest.txt is here
+"""]]
+
+### What version of git-annex are you using? On what operating system?
+git-annex version: 4.20131101, ubuntu 12.04 with all updates.
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
+
+> Improved documentation. [[done]] --[[Joey]]
diff --git a/doc/bugs/Displayed_copy_speed_is_wrong.mdwn b/doc/bugs/Displayed_copy_speed_is_wrong.mdwn
new file mode 100644
index 000000000..cf3b31cf4
--- /dev/null
+++ b/doc/bugs/Displayed_copy_speed_is_wrong.mdwn
@@ -0,0 +1,8 @@
+When copying data to my remote, I regularly see speeds in excess of 100 MB/s on my home DSL line.
+
+ 2073939 100% 176.96MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+This is definitely not correct.
+
+> Closing, as rsync does this to show you when it's making your life
+> faster than it would be w/o rsync. [[done]] --[[Joey]]
diff --git a/doc/bugs/Displayed_copy_speed_is_wrong/comment_1_74de3091e8bfd7acd6795e61f39f07c6._comment b/doc/bugs/Displayed_copy_speed_is_wrong/comment_1_74de3091e8bfd7acd6795e61f39f07c6._comment
new file mode 100644
index 000000000..62a595be7
--- /dev/null
+++ b/doc/bugs/Displayed_copy_speed_is_wrong/comment_1_74de3091e8bfd7acd6795e61f39f07c6._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-04-03T01:37:29Z"
+ content="""
+That is displayed by rsync. It's not unheard of for rsync to resume a transfer and display extremely high speeds.
+"""]]
diff --git a/doc/bugs/Displayed_copy_speed_is_wrong/comment_2_8b240de1d5ae9229fa2d77d1cc15a552._comment b/doc/bugs/Displayed_copy_speed_is_wrong/comment_2_8b240de1d5ae9229fa2d77d1cc15a552._comment
new file mode 100644
index 000000000..28305d3ac
--- /dev/null
+++ b/doc/bugs/Displayed_copy_speed_is_wrong/comment_2_8b240de1d5ae9229fa2d77d1cc15a552._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 2"
+ date="2011-04-03T08:56:48Z"
+ content="""
+Pity. Mark as done/upstream (or similar) for house-keeping?
+"""]]
diff --git a/doc/bugs/During_synchronisation_top-level_folder_suddenly_appear_in_sub-sub-folder.mdwn b/doc/bugs/During_synchronisation_top-level_folder_suddenly_appear_in_sub-sub-folder.mdwn
new file mode 100644
index 000000000..d011e4416
--- /dev/null
+++ b/doc/bugs/During_synchronisation_top-level_folder_suddenly_appear_in_sub-sub-folder.mdwn
@@ -0,0 +1,3747 @@
+### Please describe the problem.
+Two repositories A and B. B carries the full data, A only carries a subset of the data by excluding a couple of directories with a preferred content expression. Both repos in direct mode. A was modified quite heavily (thousands of files moved, deleted) with git-annex assistant running but without a possibility to synchronise with B.
+
+During synchronisation (by starting the webapp on A and git-annex assistant on B) suddenly former top-level folders, e.g.
+
+ ./201207
+
+appear in
+
+ ./incoming/5d/201207
+
+in both repositories.
+
+Then deleting
+
+ ./incoming/5d/201207
+
+in repo A unfortunately removes the top-level directory
+
+ ./201207
+
+as well and removes them in both repositories.
+
+### What steps will reproduce the problem?
+I don't know how to reproduce apart from the description above.
+
+### What version of git-annex are you using? On what operating system?
+git-annex version: 4.20131002,
+Debian jessie, A: amd64, B: armhf
+
+### Please provide any additional information below.
+
+A paste of .git/annex/daemon.log of repoA below, as I haven't realised the problem immediatly I cannot tell whether this is the relevant log or not. If more is needed, I can provide additional logs.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+[2013-10-27 18:35:52 CET] main: Syncing with repoB
+From repoB:/media/srv/img
+ d1e3763..5eba12c git-annex -> repoB/git-annex
+ 611e4f5..a7b9fd7 master -> repoB/master
+ 714ed67..a7b9fd7 synced/master -> repoB/synced/master
+Auto packing the repository for optimum performance. You may also
+run "git gc" manually. See "git help gc" for more information.
+Updating 714ed67..a7b9fd7
+Fast-forward
+ 201109/jmg_7250.cr2 | 1 -
+ 201109/jmg_7250.jpg | 1 -
+ 201109/jmg_7251.cr2 | 1 -
+ 201109/jmg_7251.jpg | 1 -
+ 201109/jmg_7253.cr2 | 1 -
+ 201109/jmg_7253.jpg | 1 -
+ 201109/jmg_7256_raw.jpg | 1 -
+ 201109/jmg_7259.cr2 | 1 -
+ 201109/jmg_7259.jpg | 1 -
+ 201109/jmg_7261.cr2 | 1 -
+ 201109/jmg_7261.jpg | 1 -
+ 201109/jmg_7265.cr2 | 1 -
+ 201109/jmg_7265.jpg | 1 -
+ 201109/jmg_7272.jpg | 1 -
+ 201109/jmg_7274.jpg | 1 -
+ 201109/jmg_7275.jpg | 1 -
+ 201109/jmg_7276.jpg | 1 -
+ 201109/jmg_7280.jpg | 1 -
+ 201109/jmg_7284.jpg | 1 -
+ 201109/jmg_7286.jpg | 1 -
+ 201109/jmg_7288.jpg | 1 -
+ 201109/jmg_7289.jpg | 1 -
+ 201109/jmg_7292.jpg | 1 -
+ 201109/jmg_7293.jpg | 1 -
+ 201109/jmg_7295.cr2 | 1 -
+ 201109/jmg_7295.jpg | 1 -
+ 201109/jmg_7296.cr2 | 1 -
+ 201109/jmg_7296.jpg | 1 -
+ 201109/jmg_7299.cr2 | 1 -
+ 201109/jmg_7299.jpg | 1 -
+ 201109/jmg_7300.cr2 | 1 -
+ 201109/jmg_7300.jpg | 1 -
+ 201109/jmg_7304.jpg | 1 -
+ 201109/jmg_7305_raw.jpg | 1 -
+ 201109/jmg_7307_raw.jpg | 1 -
+ 201202/jmg_8528.jpg | 1 -
+ 201202/jmg_8529.jpg | 1 -
+ 201202/jmg_8595.jpg | 1 -
+ 201202/jmg_8596.jpg | 1 -
+ 201202/jmg_8597.jpg | 1 -
+ 201202/jmg_8601.jpg | 1 -
+ 201202/jmg_8602.cr2 | 1 -
+ 201202/jmg_8602.jpg | 1 -
+ 201202/jmg_8603.cr2 | 1 -
+ 201202/jmg_8603.jpg | 1 -
+ 201202/jmg_8604.jpg | 1 -
+ 201202/jmg_8605.jpg | 1 -
+ 201202/jmg_8606.jpg | 1 -
+ 201202/jmg_8607.jpg | 1 -
+ 201202/jmg_8608.jpg | 1 -
+ 201202/jmg_8609.jpg | 1 -
+ 201202/jmg_8610.jpg | 1 -
+ 201202/jmg_8611.jpg | 1 -
+ 201202/jmg_8612.cr2 | 1 -
+ 201202/jmg_8612.jpg | 1 -
+ 201202/jmg_8613.jpg | 1 -
+ 201202/jmg_8614.jpg | 1 -
+ 201202/jmg_8615.jpg | 1 -
+ 201202/jmg_8616_raw.jpg | 1 -
+ 201202/jmg_8617.jpg | 1 -
+ 201202/jmg_8618.jpg | 1 -
+ 201202/jmg_8619.jpg | 1 -
+ 201202/jmg_8620.jpg | 1 -
+ 201202/jmg_8621.jpg | 1 -
+ 201202/jmg_8622.jpg | 1 -
+ 201202/jmg_8624.jpg | 1 -
+ 201202/jmg_8625.cr2 | 1 -
+ 201202/jmg_8625.jpg | 1 -
+ 201202/jmg_8626.jpg | 1 -
+ 201202/jmg_8627.jpg | 1 -
+ 201202/jmg_8628.jpg | 1 -
+ 201202/jmg_8629.jpg | 1 -
+ 201202/jmg_8630.jpg | 1 -
+ 201202/jmg_8631.jpg | 1 -
+ 201202/jmg_8632.jpg | 1 -
+ 201202/jmg_8633.cr2 | 1 -
+ 201202/jmg_8633.jpg | 1 -
+ 201202/jmg_8634.jpg | 1 -
+ 201202/jmg_8637.jpg | 1 -
+ 201202/jmg_8639.jpg | 1 -
+ 201202/jmg_8640.jpg | 1 -
+ 201202/jmg_8641.jpg | 1 -
+ 201202/jmg_8642_raw.jpg | 1 -
+ 201202/jmg_8643.jpg | 1 -
+ 201202/jmg_8644.jpg | 1 -
+ 201202/jmg_8647.jpg | 1 -
+ 201202/jmg_8648.jpg | 1 -
+ 201202/jmg_8651.cr2 | 1 -
+ 201202/jmg_8651.jpg | 1 -
+ 201202/jmg_8652.jpg | 1 -
+ 201202/jmg_8653.jpg | 1 -
+ 201202/jmg_8654.jpg | 1 -
+ 201202/jmg_8655.jpg | 1 -
+ 201202/jmg_8657.jpg | 1 -
+ 201202/jmg_8665.jpg | 1 -
+ 201202/jmg_8670.jpg | 1 -
+ 201202/jmg_8671.jpg | 1 -
+ 201202/jmg_8673.cr2 | 1 -
+ 201202/jmg_8673.jpg | 1 -
+ 201202/jmg_8674.jpg | 1 -
+ 201202/jmg_8675.jpg | 1 -
+ 201202/jmg_8676.jpg | 1 -
+ 201202/jmg_8677.jpg | 1 -
+ 201202/jmg_8678.jpg | 1 -
+ 201202/jmg_8679.jpg | 1 -
+ 201202/jmg_8680.jpg | 1 -
+ 201202/jmg_8681.jpg | 1 -
+ 201203/jmg_8701.cr2 | 1 -
+ 201203/jmg_8702.jpg | 1 -
+ 201203/jmg_8705.jpg | 1 -
+ 201203/jmg_8711.jpg | 1 -
+ 201203/jmg_8717.jpg | 1 -
+ 201203/jmg_8718.jpg | 1 -
+ 201203/jmg_8719.jpg | 1 -
+ 201203/jmg_8721.jpg | 1 -
+ 201203/jmg_8725.jpg | 1 -
+ 201203/jmg_8726.jpg | 1 -
+ 201203/jmg_8731.jpg | 1 -
+ 201203/jmg_8739.jpg | 1 -
+ 201203/jmg_8745.jpg | 1 -
+ 201203/jmg_8747_raw.jpg | 1 -
+ 201203/jmg_8750.cr2 | 1 -
+ 201203/jmg_8750.jpg | 1 -
+ 201204/jmg_8751.jpg | 1 -
+ 201204/jmg_8752.jpg | 1 -
+ 201204/jmg_8755.jpg | 1 -
+ 201204/jmg_8756.jpg | 1 -
+ 201204/jmg_8757.jpg | 1 -
+ 201204/jmg_8759.jpg | 1 -
+ 201204/jmg_8760.jpg | 1 -
+ 201204/jmg_8761.jpg | 1 -
+ 201204/jmg_8762.jpg | 1 -
+ 201204/jmg_8763.cr2 | 1 -
+ 201204/jmg_8763.jpg | 1 -
+ 201204/jmg_8766.jpg | 1 -
+ 201204/jmg_8767.cr2 | 1 -
+ 201204/jmg_8767.jpg | 1 -
+ 201204/jmg_8768.jpg | 1 -
+ 201204/jmg_8769.jpg | 1 -
+ 201204/jmg_8770.jpg | 1 -
+ 201204/jmg_8771.jpg | 1 -
+ 201204/jmg_8772.jpg | 1 -
+ 201204/jmg_8773.jpg | 1 -
+ 201205/jmg_8822.jpg | 1 -
+ 201205/jmg_8823.jpg | 1 -
+ 201205/jmg_8824.jpg | 1 -
+ 201205/jmg_8826.jpg | 1 -
+ 201205/jmg_8831.jpg | 1 -
+ 201205/jmg_8834.jpg | 1 -
+ 201205/jmg_8835.jpg | 1 -
+ 201205/jmg_8835_raw.jpg | 1 -
+ 201205/jmg_8837.jpg | 1 -
+ 201205/jmg_8839.cr2 | 1 -
+ 201205/jmg_8839.jpg | 1 -
+ 201205/jmg_8839_raw.jpg | 1 -
+ 201205/jmg_8840.cr2 | 1 -
+ 201205/jmg_8840.jpg | 1 -
+ 201205/jmg_8840_raw.jpg | 1 -
+ 201205/jmg_8841.jpg | 1 -
+ 201205/jmg_8842.jpg | 1 -
+ 201205/jmg_8844.cr2 | 1 -
+ 201205/jmg_8844.jpg | 1 -
+ 201205/jmg_8844_raw.jpg | 1 -
+ 201205/jmg_8845.jpg | 1 -
+ 201205/jmg_8846.jpg | 1 -
+ 201205/jmg_8847.cr2 | 1 -
+ 201205/jmg_8847.jpg | 1 -
+ 201205/jmg_8847_raw.jpg | 1 -
+ 201205/jmg_8848.jpg | 1 -
+ 201205/jmg_8849.jpg | 1 -
+ 201205/jmg_8851.cr2 | 1 -
+ 201205/jmg_8851.jpg | 1 -
+ 201205/jmg_8851_raw.jpg | 1 -
+ 201205/jmg_8856.cr2 | 1 -
+ 201205/jmg_8856.jpg | 1 -
+ 201205/jmg_8856_raw.jpg | 1 -
+ 201205/jmg_8857.jpg | 1 -
+ 201205/jmg_8858.jpg | 1 -
+ 201205/jmg_8859.jpg | 1 -
+ 201205/jmg_8861.jpg | 1 -
+ 201205/jmg_8862.jpg | 1 -
+ 201205/jmg_8863.jpg | 1 -
+ 201205/jmg_8871.cr2 | 1 -
+ 201205/jmg_8871.jpg | 1 -
+ 201205/jmg_8872.jpg | 1 -
+ 201205/jmg_8873.jpg | 1 -
+ 201205/jmg_8875.jpg | 1 -
+ 201205/jmg_8876.cr2 | 1 -
+ 201205/jmg_8876.jpg | 1 -
+ 201205/jmg_8878.cr2 | 1 -
+ 201205/jmg_8878.jpg | 1 -
+ 201205/jmg_8879.cr2 | 1 -
+ 201205/jmg_8879.jpg | 1 -
+ 201205/jmg_8880.cr2 | 1 -
+ 201205/jmg_8880.jpg | 1 -
+ 201205/jmg_8881.cr2 | 1 -
+ 201205/jmg_8881.jpg | 1 -
+ 201205/jmg_8892.cr2 | 1 -
+ 201205/jmg_8892.jpg | 1 -
+ 201205/jmg_8893.cr2 | 1 -
+ 201205/jmg_8893.jpg | 1 -
+ 201205/jmg_8894.cr2 | 1 -
+ 201205/jmg_8894.jpg | 1 -
+ 201206/jmg_8989.cr2 | 1 -
+ 201206/jmg_8989.jpg | 1 -
+ 201206/jmg_8990.cr2 | 1 -
+ 201206/jmg_8990.jpg | 1 -
+ 201206/jmg_8995.jpg | 1 -
+ 201206/jmg_8996.jpg | 1 -
+ 201206/jmg_8998.jpg | 1 -
+ 201206/jmg_9001.jpg | 1 -
+ 201206/jmg_9003.jpg | 1 -
+ 201206/jmg_9006.jpg | 1 -
+ 201206/jmg_9007.jpg | 1 -
+ 201206/jmg_9011.jpg | 1 -
+ 201206/jmg_9014.jpg | 1 -
+ 201206/jmg_9014_raw.jpg | 1 -
+ 201206/jmg_9015.jpg | 1 -
+ 201206/jmg_9016.cr2 | 1 -
+ 201206/jmg_9016.jpg | 1 -
+ 201206/jmg_9017.cr2 | 1 -
+ 201206/jmg_9017.jpg | 1 -
+ 201206/jmg_9018.cr2 | 1 -
+ 201206/jmg_9018.jpg | 1 -
+ 201206/jmg_9019.cr2 | 1 -
+ 201206/jmg_9019.jpg | 1 -
+ 201206/jmg_9023.cr2 | 1 -
+ 201206/jmg_9023.jpg | 1 -
+ 201206/jmg_9024.cr2 | 1 -
+ 201206/jmg_9024.jpg | 1 -
+ 201206/jmg_9025.cr2 | 1 -
+ 201206/jmg_9025.jpg | 1 -
+ 201206/jmg_9028.jpg | 1 -
+ 201206/jmg_9029.jpg | 1 -
+ 201206/jmg_9030.jpg | 1 -
+ 201206/jmg_9031.jpg | 1 -
+ 201206/jmg_9032_raw.jpg | 1 -
+ 201206/jmg_9033.jpg | 1 -
+ 201206/jmg_9033_raw.jpg | 1 -
+ 201206/jmg_9034.jpg | 1 -
+ 201206/jmg_9035.jpg | 1 -
+ 201206/jmg_9035_raw.jpg | 1 -
+ 201206/jmg_9036.jpg | 1 -
+ 201206/jmg_9039.cr2 | 1 -
+ 201206/jmg_9039.jpg | 1 -
+ 201206/jmg_9040.cr2 | 1 -
+ 201206/jmg_9040.jpg | 1 -
+ 201206/jmg_9043.cr2 | 1 -
+ 201206/jmg_9043.jpg | 1 -
+ 201206/jmg_9047.cr2 | 1 -
+ 201206/jmg_9047.jpg | 1 -
+ 201207/jmg_9048.jpg | 1 -
+ 201207/jmg_9053.jpg | 1 -
+ 201207/jmg_9054.jpg | 1 -
+ 201207/jmg_9069.cr2 | 1 -
+ 201207/jmg_9069.jpg | 1 -
+ 201207/jmg_9070.cr2 | 1 -
+ 201207/jmg_9070.jpg | 1 -
+ 201207/jmg_9072.cr2 | 1 -
+ 201207/jmg_9072.jpg | 1 -
+ 201207/jmg_9076.cr2 | 1 -
+ 201207/jmg_9076.jpg | 1 -
+ 201208/jmg_9077.jpg | 1 -
+ 201208/jmg_9302_raw.jpg | 1 -
+ 201208/jmg_9303.jpg | 1 -
+ 201208/jmg_9304.cr2 | 1 -
+ 201208/jmg_9304.jpg | 1 -
+ 201208/jmg_9305.cr2 | 1 -
+ 201208/jmg_9305.jpg | 1 -
+ 201208/jmg_9306_raw.jpg | 1 -
+ 201208/jmg_9307.cr2 | 1 -
+ 201208/jmg_9307.jpg | 1 -
+ 201208/jmg_9308_raw.jpg | 1 -
+ 201208/jmg_9309_raw.jpg | 1 -
+ 201208/jmg_9310.cr2 | 1 -
+ 201208/jmg_9310.jpg | 1 -
+ 201208/jmg_9310_bw.jpg | 1 -
+ 201208/jmg_9310_raw.jpg | 1 -
+ 201208/jmg_9312.jpg | 1 -
+ 201208/jmg_9313.jpg | 1 -
+ 201208/jmg_9314.jpg | 1 -
+ 201208/jmg_9315.jpg | 1 -
+ 201208/jmg_9319.jpg | 1 -
+ 201208/jmg_9523.jpg | 1 -
+ 201208/jmg_9524.jpg | 1 -
+ 201208/jmg_9525.jpg | 1 -
+ 201208/jmg_9526.jpg | 1 -
+ 201208/jmg_9527.jpg | 1 -
+ 201208/jmg_9527_raw.jpg | 1 -
+ 201208/jmg_9528.jpg | 1 -
+ 201208/jmg_9529.jpg | 1 -
+ 201208/jmg_9530.jpg | 1 -
+ 201208/jmg_9531.jpg | 1 -
+ 201208/jmg_9532.jpg | 1 -
+ 201208/jmg_9533.cr2 | 1 -
+ 201208/jmg_9533.jpg | 1 -
+ 201208/jmg_9534.cr2 | 1 -
+ 201208/jmg_9534.jpg | 1 -
+ 201208/jmg_9535.jpg | 1 -
+ 201208/jmg_9536.jpg | 1 -
+ 201208/jmg_9537.cr2 | 1 -
+ 201208/jmg_9537.jpg | 1 -
+ 201208/jmg_9538.jpg | 1 -
+ 201208/jmg_9539.jpg | 1 -
+ 201208/jmg_9540.jpg | 1 -
+ 201208/jmg_9541.cr2 | 1 -
+ 201208/jmg_9542.jpg | 1 -
+ 201208/jmg_9543.cr2 | 1 -
+ 201208/jmg_9543.jpg | 1 -
+ 201208/jmg_9544.cr2 | 1 -
+ 201208/jmg_9544.jpg | 1 -
+ 201208/jmg_9545.jpg | 1 -
+ 201209/jmg_9547.jpg | 1 -
+ 201209/jmg_9548.jpg | 1 -
+ 201209/jmg_9549.jpg | 1 -
+ 201209/jmg_9550.jpg | 1 -
+ 201209/jmg_9551.jpg | 1 -
+ 201209/jmg_9552.jpg | 1 -
+ 201209/jmg_9553.jpg | 1 -
+ 201209/jmg_9555.jpg | 1 -
+ 201209/jmg_9556.jpg | 1 -
+ 201209/jmg_9558.jpg | 1 -
+ 201209/jmg_9559.cr2 | 1 -
+ 201209/jmg_9559.jpg | 1 -
+ 201209/jmg_9560.cr2 | 1 -
+ 201209/jmg_9560.jpg | 1 -
+ 201209/jmg_9561.jpg | 1 -
+ 201209/jmg_9562.jpg | 1 -
+ 201209/jmg_9568.jpg | 1 -
+ 201210/jmg_0001.jpg | 1 -
+ 201210/jmg_0021.jpg | 1 -
+ 201210/jmg_0022.cr2 | 1 -
+ 201210/jmg_0022.jpg | 1 -
+ 201210/jmg_0025.jpg | 1 -
+ 201210/jmg_0026.jpg | 1 -
+ 201210/jmg_0027.jpg | 1 -
+ 201210/jmg_0028.jpg | 1 -
+ 201210/jmg_0029.jpg | 1 -
+ 201210/jmg_0030.jpg | 1 -
+ 201210/jmg_0032.jpg | 1 -
+ 201210/jmg_0034.jpg | 1 -
+ 201210/jmg_0035.jpg | 1 -
+ 201210/jmg_0036.jpg | 1 -
+ 201210/jmg_0037.jpg | 1 -
+ 201210/jmg_0039.cr2 | 1 -
+ 201210/jmg_0039.jpg | 1 -
+ 201210/jmg_0040.jpg | 1 -
+ 201210/jmg_9572.jpg | 1 -
+ 201210/jmg_9573.jpg | 1 -
+ 201210/jmg_9574.jpg | 1 -
+ 201210/jmg_9575.jpg | 1 -
+ 201210/jmg_9576.jpg | 1 -
+ 201210/jmg_9578.jpg | 1 -
+ 201210/jmg_9580.jpg | 1 -
+ 201210/jmg_9581.jpg | 1 -
+ 201210/jmg_9582.cr2 | 1 -
+ 201210/jmg_9582.jpg | 1 -
+ 201210/jmg_9585.cr2 | 1 -
+ 201210/jmg_9585.jpg | 1 -
+ 201210/jmg_9587.cr2 | 1 -
+ 201210/jmg_9587.jpg | 1 -
+ 201210/jmg_9588.jpg | 1 -
+ 201210/jmg_9589.jpg | 1 -
+ 201210/jmg_9590.jpg | 1 -
+ 201210/jmg_9591.jpg | 1 -
+ 201210/jmg_9594.jpg | 1 -
+ 201210/jmg_9595.jpg | 1 -
+ 201210/jmg_9596.jpg | 1 -
+ 201210/jmg_9597.cr2 | 1 -
+ 201210/jmg_9597.jpg | 1 -
+ 201210/jmg_9598.cr2 | 1 -
+ 201210/jmg_9598.jpg | 1 -
+ 201210/jmg_9599.cr2 | 1 -
+ 201210/jmg_9599.jpg | 1 -
+ 201210/jmg_9600.jpg | 1 -
+ 201210/jmg_9602.jpg | 1 -
+ 201210/jmg_9603.jpg | 1 -
+ 201210/jmg_9604.jpg | 1 -
+ 201210/jmg_9605.cr2 | 1 -
+ 201210/jmg_9605.jpg | 1 -
+ 201210/jmg_9606.jpg | 1 -
+ 201210/jmg_9608.jpg | 1 -
+ 201210/jmg_9609.jpg | 1 -
+ 201210/jmg_9610.jpg | 1 -
+ 201210/jmg_9611.jpg | 1 -
+ 201210/jmg_9612.jpg | 1 -
+ 201210/jmg_9613.jpg | 1 -
+ 201210/jmg_9614.jpg | 1 -
+ 201210/jmg_9616.cr2 | 1 -
+ 201210/jmg_9616.jpg | 1 -
+ 201210/jmg_9617.jpg | 1 -
+ 201210/jmg_9619.jpg | 1 -
+ 201210/jmg_9620.jpg | 1 -
+ 201210/jmg_9621.jpg | 1 -
+ 201210/jmg_9622.jpg | 1 -
+ 201210/jmg_9623.cr2 | 1 -
+ 201210/jmg_9623.jpg | 1 -
+ 201210/jmg_9624.cr2 | 1 -
+ 201210/jmg_9624.jpg | 1 -
+ 201210/jmg_9736_raw.jpg | 1 -
+ 201210/jmg_9738_raw.jpg | 1 -
+ 201210/jmg_9740.cr2 | 1 -
+ 201210/jmg_9740.jpg | 1 -
+ 201210/jmg_9743.jpg | 1 -
+ 201210/jmg_9744.jpg | 1 -
+ 201210/jmg_9745.cr2 | 1 -
+ 201210/jmg_9745.jpg | 1 -
+ 201210/jmg_9746.cr2 | 1 -
+ 201210/jmg_9746.jpg | 1 -
+ 201210/jmg_9748.jpg | 1 -
+ 201210/jmg_9749_raw.jpg | 1 -
+ 201210/jmg_9751.jpg | 1 -
+ 201210/jmg_9752.jpg | 1 -
+ 201210/jmg_9754.jpg | 1 -
+ 201210/jmg_9755.jpg | 1 -
+ 201210/jmg_9756.jpg | 1 -
+ 201210/jmg_9760.cr2 | 1 -
+ 201210/jmg_9760.jpg | 1 -
+ 201210/jmg_9761.cr2 | 1 -
+ 201210/jmg_9761.jpg | 1 -
+ 201210/jmg_9763.jpg | 1 -
+ 201210/jmg_9764.jpg | 1 -
+ 201210/jmg_9766.jpg | 1 -
+ 201210/jmg_9767.cr2 | 1 -
+ 201210/jmg_9767.jpg | 1 -
+ 201210/jmg_9768.jpg | 1 -
+ 201210/jmg_9771.jpg | 1 -
+ 201210/jmg_9772.jpg | 1 -
+ 201210/jmg_9791.jpg | 1 -
+ 201210/jmg_9792.jpg | 1 -
+ 201210/jmg_9793.jpg | 1 -
+ 201210/jmg_9794.jpg | 1 -
+ 201210/jmg_9796.jpg | 1 -
+ 201210/jmg_9797.jpg | 1 -
+ 201210/jmg_9799.jpg | 1 -
+ 201210/jmg_9800.jpg | 1 -
+ 201210/jmg_9801.jpg | 1 -
+ 201210/jmg_9803.jpg | 1 -
+ 201210/jmg_9807.jpg | 1 -
+ 201210/jmg_9808.jpg | 1 -
+ 201210/jmg_9809.jpg | 1 -
+ 201210/jmg_9810.jpg | 1 -
+ 201210/jmg_9811.jpg | 1 -
+ 201210/jmg_9812.jpg | 1 -
+ 201210/jmg_9813.jpg | 1 -
+ 201210/jmg_9815.jpg | 1 -
+ 201210/jmg_9818.jpg | 1 -
+ 201210/jmg_9819.jpg | 1 -
+ 201210/jmg_9820.jpg | 1 -
+ 201210/jmg_9821.jpg | 1 -
+ 201210/jmg_9822.jpg | 1 -
+ 201210/jmg_9823.jpg | 1 -
+ 201210/jmg_9825.jpg | 1 -
+ 201210/jmg_9826.jpg | 1 -
+ 201210/jmg_9827.jpg | 1 -
+ 201210/jmg_9828.jpg | 1 -
+ 201210/jmg_9829.jpg | 1 -
+ 201210/jmg_9830.cr2 | 1 -
+ 201210/jmg_9830.jpg | 1 -
+ 201210/jmg_9832.cr2 | 1 -
+ 201210/jmg_9832.jpg | 1 -
+ 201210/jmg_9834.jpg | 1 -
+ 201210/jmg_9836.jpg | 1 -
+ 201210/jmg_9838.jpg | 1 -
+ 201210/jmg_9839.jpg | 1 -
+ 201210/jmg_9841.jpg | 1 -
+ 201210/jmg_9843.jpg | 1 -
+ 201210/jmg_9845.jpg | 1 -
+ 201210/jmg_9846.jpg | 1 -
+ 201210/jmg_9848.jpg | 1 -
+ 201210/jmg_9849.jpg | 1 -
+ 201210/jmg_9852.jpg | 1 -
+ 201210/jmg_9853.jpg | 1 -
+ 201210/jmg_9854.jpg | 1 -
+ 201210/jmg_9855.jpg | 1 -
+ 201210/jmg_9856.jpg | 1 -
+ 201210/jmg_9857.cr2 | 1 -
+ 201210/jmg_9857.jpg | 1 -
+ 201210/jmg_9858.cr2 | 1 -
+ 201210/jmg_9858.jpg | 1 -
+ 201210/jmg_9859.jpg | 1 -
+ 201210/jmg_9860.jpg | 1 -
+ 201210/jmg_9915.jpg | 1 -
+ 201210/jmg_9917.jpg | 1 -
+ 201210/jmg_9918.jpg | 1 -
+ 201210/jmg_9919.jpg | 1 -
+ 201210/jmg_9922.jpg | 1 -
+ 201210/jmg_9923.jpg | 1 -
+ 201210/jmg_9925.jpg | 1 -
+ 201210/jmg_9926.cr2 | 1 -
+ 201210/jmg_9926.jpg | 1 -
+ 201210/jmg_9928.jpg | 1 -
+ 201210/jmg_9975.cr2 | 1 -
+ 201210/jmg_9975.jpg | 1 -
+ 201210/jmg_9976.cr2 | 1 -
+ 201210/jmg_9976.jpg | 1 -
+ 201210/jmg_9978.jpg | 1 -
+ 201210/jmg_9986.jpg | 1 -
+ 201210/jmg_9987.jpg | 1 -
+ 201210/jmg_9988.jpg | 1 -
+ 201210/jmg_9989.jpg | 1 -
+ 201210/jmg_9991.jpg | 1 -
+ 201210/jmg_9993.jpg | 1 -
+ 201210/jmg_9994.cr2 | 1 -
+ 201210/jmg_9994.jpg | 1 -
+ 201210/jmg_9997.jpg | 1 -
+ 201210/jmg_9998.jpg | 1 -
+ 201210/jmg_9999.jpg | 1 -
+ 201212/jmg_0131.jpg | 1 -
+ 201212/jmg_0134.jpg | 1 -
+ 201212/jmg_0135.jpg | 1 -
+ 201212/jmg_0152.jpg | 1 -
+ 201212/jmg_0155.jpg | 1 -
+ 201212/jmg_0156.jpg | 1 -
+ 201212/jmg_0162.jpg | 1 -
+ 201212/jmg_0163.jpg | 1 -
+ 201212/jmg_0165.jpg | 1 -
+ 201212/jmg_0176.cr2 | 1 -
+ 201212/jmg_0176.jpg | 1 -
+ 201212/jmg_0177.cr2 | 1 -
+ 201212/jmg_0177.jpg | 1 -
+ 201212/jmg_0178.jpg | 1 -
+ 201212/jmg_0179.jpg | 1 -
+ 201212/jmg_0180.jpg | 1 -
+ 201212/jmg_0184.jpg | 1 -
+ 201212/jmg_0185.jpg | 1 -
+ 201212/jmg_0186.jpg | 1 -
+ 201212/jmg_0187.jpg | 1 -
+ 201212/jmg_0306.jpg | 1 -
+ 201212/jmg_0307.jpg | 1 -
+ 201212/jmg_0308.jpg | 1 -
+ 201212/jmg_0310.jpg | 1 -
+ 201212/jmg_0311.jpg | 1 -
+ 201212/jmg_0312.jpg | 1 -
+ 201212/jmg_0313.jpg | 1 -
+ 201212/jmg_0314.jpg | 1 -
+ 201212/jmg_0315.jpg | 1 -
+ 201212/jmg_0316.jpg | 1 -
+ 201212/jmg_0317.jpg | 1 -
+ 201212/jmg_0321.jpg | 1 -
+ 201212/jmg_0326.jpg | 1 -
+ 201212/jmg_0328.jpg | 1 -
+ 201212/jmg_0330.jpg | 1 -
+ 201212/jmg_0333.jpg | 1 -
+ 201212/jmg_0336.jpg | 1 -
+ 201212/jmg_0340.jpg | 1 -
+ 201212/jmg_0343.jpg | 1 -
+ 201212/jmg_0345.jpg | 1 -
+ 201212/jmg_0360.jpg | 1 -
+ 201212/jmg_0362.jpg | 1 -
+ 201212/jmg_0363.jpg | 1 -
+ 201212/jmg_0364.jpg | 1 -
+ 201212/jmg_0366.jpg | 1 -
+ 201212/jmg_0367.jpg | 1 -
+ 201212/jmg_0368.jpg | 1 -
+ 201212/jmg_0369.jpg | 1 -
+ 201212/jmg_0370.jpg | 1 -
+ 201212/jmg_0372.jpg | 1 -
+ 201212/jmg_0382.jpg | 1 -
+ 201212/jmg_0383.jpg | 1 -
+ 201212/jmg_0384.jpg | 1 -
+ 201212/jmg_0385.jpg | 1 -
+ 201212/jmg_0387.jpg | 1 -
+ 201212/jmg_0388.jpg | 1 -
+ 201212/jmg_0389.jpg | 1 -
+ 201212/jmg_0390.jpg | 1 -
+ 201212/jmg_0392.jpg | 1 -
+ 201212/jmg_0396.jpg | 1 -
+ 201212/jmg_0397.jpg | 1 -
+ 201212/jmg_0398.jpg | 1 -
+ 201212/jmg_0399.jpg | 1 -
+ 201212/jmg_0402.jpg | 1 -
+ 201212/jmg_0404.jpg | 1 -
+ 201212/jmg_0405.jpg | 1 -
+ 201212/jmg_0406.jpg | 1 -
+ 201212/jmg_0407.jpg | 1 -
+ 201212/jmg_0408.jpg | 1 -
+ 201212/jmg_0410.jpg | 1 -
+ 201212/jmg_0411.jpg | 1 -
+ 201212/jmg_0412.jpg | 1 -
+ 201212/jmg_0415.jpg | 1 -
+ 201212/jmg_0417.jpg | 1 -
+ 201212/jmg_0418.jpg | 1 -
+ 201302/jmg_0502.cr2 | 1 -
+ 201302/jmg_0502.jpg | 1 -
+ 201302/jmg_0503.jpg | 1 -
+ 201302/jmg_0507.jpg | 1 -
+ 201302/jmg_0510.jpg | 1 -
+ 201302/jmg_0512.jpg | 1 -
+ 201302/jmg_0513.jpg | 1 -
+ 201302/jmg_0514.jpg | 1 -
+ 201302/jmg_0516.jpg | 1 -
+ 201302/jmg_0517.jpg | 1 -
+ 201302/jmg_0518.jpg | 1 -
+ 201302/jmg_0521.jpg | 1 -
+ 201302/jmg_0522.jpg | 1 -
+ 201302/jmg_0523.jpg | 1 -
+ 201302/jmg_0524.jpg | 1 -
+ 201302/jmg_0526.jpg | 1 -
+ 201302/jmg_0527.jpg | 1 -
+ 201302/jmg_0528.jpg | 1 -
+ 201302/jmg_0532.cr2 | 1 -
+ 201302/jmg_0532.jpg | 1 -
+ 201302/jmg_0534.jpg | 1 -
+ 201302/jmg_0535.jpg | 1 -
+ 201302/jmg_0537.jpg | 1 -
+ 201302/jmg_0539.jpg | 1 -
+ 201302/jmg_0541.jpg | 1 -
+ 201302/jmg_0543.jpg | 1 -
+ 201304/bruecke_saeckingen.tif | 1 -
+ 201304/jmg_0685.cr2 | 1 -
+ 201304/jmg_0685.jpg | 1 -
+ 201304/jmg_0687.cr2 | 1 -
+ 201304/jmg_0687.jpg | 1 -
+ 201304/jmg_0699.jpg | 1 -
+ 201304/jmg_0700.jpg | 1 -
+ 201304/jmg_0726.jpg | 1 -
+ 201304/jmg_0727.jpg | 1 -
+ 201304/jmg_0728.jpg | 1 -
+ 201304/jmg_0729.cr2 | 1 -
+ 201304/jmg_0729.jpg | 1 -
+ 201304/jmg_0730.jpg | 1 -
+ 201304/jmg_0731.jpg | 1 -
+ 201304/jmg_0733.cr2 | 1 -
+ 201304/jmg_0733.jpg | 1 -
+ 201304/jmg_0734.cr2 | 1 -
+ 201304/jmg_0734.jpg | 1 -
+ 201304/jmg_0736.cr2 | 1 -
+ 201304/jmg_0736.jpg | 1 -
+ 201304/jmg_0737.cr2 | 1 -
+ 201304/jmg_0737.jpg | 1 -
+ 201304/jmg_0738.jpg | 1 -
+ 201304/jmg_0739.jpg | 1 -
+ 201304/jmg_0740.jpg | 1 -
+ 201304/jmg_0741.jpg | 1 -
+ 201304/jmg_0742.jpg | 1 -
+ 201304/jmg_0744.cr2 | 1 -
+ 201304/jmg_0744.jpg | 1 -
+ 201304/jmg_0749.jpg | 1 -
+ 201304/jmg_0750.jpg | 1 -
+ 201304/jmg_0751.jpg | 1 -
+ 201304/jmg_0752.jpg | 1 -
+ 201304/jmg_0753.jpg | 1 -
+ 201304/jmg_0755.cr2 | 1 -
+ 201304/jmg_0755.jpg | 1 -
+ 201304/jmg_0757.cr2 | 1 -
+ 201304/jmg_0757.jpg | 1 -
+ 201304/jmg_0758.jpg | 1 -
+ 201304/jmg_0759.jpg | 1 -
+ 201304/jmg_0760.cr2 | 1 -
+ 201304/jmg_0760.jpg | 1 -
+ 201304/jmg_0762.cr2 | 1 -
+ 201304/jmg_0762.jpg | 1 -
+ 201304/jmg_0763.jpg | 1 -
+ 201304/jmg_0764.jpg | 1 -
+ 201304/jmg_0765.jpg | 1 -
+ 201304/jmg_0766.jpg | 1 -
+ 201304/jmg_0769.jpg | 1 -
+ 201304/jmg_0770.jpg | 1 -
+ 201304/jmg_0771.jpg | 1 -
+ 201304/jmg_0785.cr2 | 1 -
+ 201304/jmg_0785.jpg | 1 -
+ 201304/jmg_0786.cr2 | 1 -
+ 201304/jmg_0786.jpg | 1 -
+ 201304/jmg_0787.cr2 | 1 -
+ 201304/jmg_0787.jpg | 1 -
+ 201304/jmg_0789.jpg | 1 -
+ 201304/jmg_0790.jpg | 1 -
+ 201304/jmg_0791.jpg | 1 -
+ 201304/jmg_0800.jpg | 1 -
+ 201304/jmg_0801.jpg | 1 -
+ 201304/jmg_0802.jpg | 1 -
+ 201304/jmg_0803.jpg | 1 -
+ 201304/jmg_0809.jpg | 1 -
+ 201304/jmg_0810.jpg | 1 -
+ 201304/jmg_0812.jpg | 1 -
+ 201304/jmg_0813.jpg | 1 -
+ 201304/jmg_0824.jpg | 1 -
+ 201304/jmg_0825.jpg | 1 -
+ 201304/jmg_0827.jpg | 1 -
+ 201304/jmg_0831.jpg | 1 -
+ 201304/jmg_0833.jpg | 1 -
+ 201304/jmg_0834.jpg | 1 -
+ 201304/jmg_0836.jpg | 1 -
+ 201304/jmg_0837.jpg | 1 -
+ 201304/jmg_0845.jpg | 1 -
+ 201304/jmg_0846.jpg | 1 -
+ 201304/jmg_0847.jpg | 1 -
+ 201304/jmg_0848.jpg | 1 -
+ 201304/jmg_0849.jpg | 1 -
+ 201304/jmg_0850.jpg | 1 -
+ 201304/jmg_0851.jpg | 1 -
+ 201304/jmg_0857.jpg | 1 -
+ 201304/jmg_0858.jpg | 1 -
+ 201304/jmg_0860.jpg | 1 -
+ 201304/jmg_0861.jpg | 1 -
+ 201304/jmg_0862.jpg | 1 -
+ 201304/jmg_0863.jpg | 1 -
+ 201304/jmg_0864.jpg | 1 -
+ 201304/jmg_0866.jpg | 1 -
+ 201304/jmg_0867.jpg | 1 -
+ 201304/jmg_0868.cr2 | 1 -
+ 201304/jmg_0868.jpg | 1 -
+ 201304/jmg_0869.cr2 | 1 -
+ 201304/jmg_0869.jpg | 1 -
+ 201304/jmg_0872.cr2 | 1 -
+ 201304/jmg_0872.jpg | 1 -
+ 201304/jmg_0874.cr2 | 1 -
+ 201304/jmg_0874.jpg | 1 -
+ 201304/jmg_0875.jpg | 1 -
+ 201304/jmg_0875_raw.jpg | 1 -
+ 201304/jmg_0876.jpg | 1 -
+ 201304/jmg_0877.jpg | 1 -
+ 201304/jmg_0878.jpg | 1 -
+ 201304/jmg_0880.jpg | 1 -
+ 201304/jmg_0881.jpg | 1 -
+ 201304/jmg_0882.jpg | 1 -
+ 201304/jmg_0884.jpg | 1 -
+ 201304/jmg_0885.jpg | 1 -
+ 201304/jmg_0886.jpg | 1 -
+ 201304/jmg_0888.jpg | 1 -
+ 201304/jmg_0889.jpg | 1 -
+ 201304/jmg_0890.jpg | 1 -
+ 201304/jmg_0891.jpg | 1 -
+ 201304/jmg_0892.jpg | 1 -
+ 201304/jmg_0893.cr2 | 1 -
+ 201304/jmg_0893.jpg | 1 -
+ 201304/jmg_0894.jpg | 1 -
+ 201304/jmg_0896.jpg | 1 -
+ 201304/jmg_0897.jpg | 1 -
+ 201304/jmg_0898.jpg | 1 -
+ 201304/jmg_0899.jpg | 1 -
+ 201304/jmg_0900.jpg | 1 -
+ 201304/jmg_0902.jpg | 1 -
+ 201304/jmg_0905.jpg | 1 -
+ 201304/jmg_0921.jpg | 1 -
+ 201304/jmg_0922.jpg | 1 -
+ 201304/jmg_0932.jpg | 1 -
+ 201304/jmg_0935.jpg | 1 -
+ 201304/jmg_0936.jpg | 1 -
+ 201304/jmg_0937.jpg | 1 -
+ 201304/jmg_0938.jpg | 1 -
+ 201304/jmg_0942.jpg | 1 -
+ 201304/jmg_0944.jpg | 1 -
+ 201304/jmg_0946.jpg | 1 -
+ 201304/jmg_0947.jpg | 1 -
+ 201304/jmg_0948.jpg | 1 -
+ 201304/jmg_0949.jpg | 1 -
+ 201304/jmg_0950.jpg | 1 -
+ 201304/jmg_0951.jpg | 1 -
+ 201304/jmg_0952.jpg | 1 -
+ 201304/jmg_0953.jpg | 1 -
+ 201304/jmg_0954.jpg | 1 -
+ 201304/jmg_0958.jpg | 1 -
+ 201304/jmg_0959.jpg | 1 -
+ 201304/jmg_0960.jpg | 1 -
+ 201304/jmg_0961.jpg | 1 -
+ 201304/jmg_0962.jpg | 1 -
+ 201304/jmg_0963.jpg | 1 -
+ 201304/jmg_0964.jpg | 1 -
+ 201304/jmg_0965.jpg | 1 -
+ 201304/jmg_0966.jpg | 1 -
+ 201304/jmg_0967.jpg | 1 -
+ 201304/jmg_0968.jpg | 1 -
+ 201304/jmg_0969.jpg | 1 -
+ 201304/jmg_0976.cr2 | 1 -
+ 201304/jmg_0976.jpg | 1 -
+ 201304/jmg_0978.jpg | 1 -
+ 201304/jmg_0979.jpg | 1 -
+ 201304/jmg_0980.jpg | 1 -
+ 201304/jmg_0981.cr2 | 1 -
+ 201304/jmg_0981.jpg | 1 -
+ 201304/jmg_0982.jpg | 1 -
+ 201304/jmg_0984.cr2 | 1 -
+ 201304/jmg_0984.jpg | 1 -
+ 201304/jmg_0987.jpg | 1 -
+ 201304/jmg_0988.jpg | 1 -
+ 201304/jmg_0989.jpg | 1 -
+ 201304/jmg_0990.jpg | 1 -
+ 201304/jmg_0991.jpg | 1 -
+ 201304/jmg_0992.jpg | 1 -
+ 201304/jmg_1206.jpg | 1 -
+ 201304/jmg_1207.jpg | 1 -
+ 201304/jmg_1208.jpg | 1 -
+ 201304/jmg_1209.jpg | 1 -
+ 201304/jmg_1210.cr2 | 1 -
+ 201304/jmg_1210.jpg | 1 -
+ 201304/jmg_1211.jpg | 1 -
+ 201304/jmg_1212.jpg | 1 -
+ 201304/jmg_1213.jpg | 1 -
+ 201304/jmg_1214.cr2 | 1 -
+ 201304/jmg_1214.jpg | 1 -
+ 201304/jmg_1215.jpg | 1 -
+ 201304/jmg_1216.cr2 | 1 -
+ 201304/jmg_1216.jpg | 1 -
+ 201304/jmg_1217.cr2 | 1 -
+ 201304/jmg_1217.jpg | 1 -
+ 201304/jmg_1220.cr2 | 1 -
+ 201304/jmg_1220.jpg | 1 -
+ 201304/jmg_1222.cr2 | 1 -
+ 201304/jmg_1222.jpg | 1 -
+ 201304/jmg_1223.jpg | 1 -
+ 201306/jmg_1465.jpg | 1 -
+ 201306/jmg_1466.jpg | 1 -
+ 201306/jmg_1467.jpg | 1 -
+ 201306/jmg_1468.jpg | 1 -
+ 201306/jmg_1469.jpg | 1 -
+ 201306/jmg_1470.jpg | 1 -
+ 201306/jmg_1471.jpg | 1 -
+ 201306/jmg_1472.jpg | 1 -
+ 201306/jmg_1473.jpg | 1 -
+ 201306/jmg_1475.jpg | 1 -
+ 201306/jmg_1476.jpg | 1 -
+ 201306/jmg_1477.jpg | 1 -
+ 201306/jmg_1478.jpg | 1 -
+ 201306/jmg_1479.jpg | 1 -
+ 201306/jmg_1480.jpg | 1 -
+ 201306/jmg_1481.jpg | 1 -
+ 201306/jmg_1482.jpg | 1 -
+ 201306/jmg_1483.jpg | 1 -
+ 201306/jmg_1484.jpg | 1 -
+ 201306/jmg_1485.jpg | 1 -
+ 201306/jmg_1486.jpg | 1 -
+ 201306/jmg_1487.jpg | 1 -
+ 201306/jmg_1488.jpg | 1 -
+ 201306/jmg_1489.jpg | 1 -
+ 201306/jmg_1490.jpg | 1 -
+ 201306/jmg_1491.jpg | 1 -
+ 201306/jmg_1492.jpg | 1 -
+ 201306/jmg_1495.jpg | 1 -
+ 201306/jmg_1496.jpg | 1 -
+ 201306/jmg_1498.jpg | 1 -
+ 201306/jmg_1499.jpg | 1 -
+ 201306/jmg_1500.jpg | 1 -
+ 201306/jmg_1501.jpg | 1 -
+ 201306/jmg_1502.jpg | 1 -
+ 201306/jmg_1504.jpg | 1 -
+ 201306/jmg_1506.jpg | 1 -
+ 201306/jmg_1510.jpg | 1 -
+ 201306/jmg_1512.jpg | 1 -
+ 201306/jmg_1513.jpg | 1 -
+ 201306/jmg_1514.jpg | 1 -
+ 201306/jmg_1515.jpg | 1 -
+ 201306/jmg_1517.jpg | 1 -
+ 201306/jmg_1520.jpg | 1 -
+ 201306/jmg_1521.jpg | 1 -
+ 201306/jmg_1526.jpg | 1 -
+ 201306/jmg_1533.jpg | 1 -
+ 201306/jmg_1540.jpg | 1 -
+ 201306/jmg_1546.jpg | 1 -
+ 201306/jmg_1547.jpg | 1 -
+ 201306/jmg_1549.jpg | 1 -
+ 201306/jmg_1550.jpg | 1 -
+ 201306/jmg_1551.jpg | 1 -
+ 201306/jmg_1552.jpg | 1 -
+ 201306/jmg_1553.jpg | 1 -
+ 201306/jmg_1555.jpg | 1 -
+ 201306/jmg_1556.jpg | 1 -
+ 201306/jmg_1557.jpg | 1 -
+ 201306/jmg_1558.jpg | 1 -
+ 201306/jmg_1559.jpg | 1 -
+ 201306/jmg_1560.jpg | 1 -
+ 201306/jmg_1562.jpg | 1 -
+ 201306/jmg_1566.jpg | 1 -
+ 201306/jmg_1568.jpg | 1 -
+ 201306/jmg_1570.jpg | 1 -
+ 201306/jmg_1571.jpg | 1 -
+ 201306/jmg_1572.jpg | 1 -
+ 201306/jmg_1574.jpg | 1 -
+ 201306/jmg_1575.jpg | 1 -
+ 201306/jmg_1576.jpg | 1 -
+ 201306/jmg_1577.jpg | 1 -
+ 201306/jmg_1578.jpg | 1 -
+ 201306/jmg_1579.jpg | 1 -
+ 201306/jmg_1579_raw.jpg | 1 -
+ 201306/jmg_1581.jpg | 1 -
+ 201306/jmg_1583.jpg | 1 -
+ 201306/jmg_1583_cut.jpg | 1 -
+ 201306/jmg_1583_raw.jpg | 1 -
+ 201306/jmg_1584.jpg | 1 -
+ 201306/jmg_1586.jpg | 1 -
+ 201306/jmg_1587.jpg | 1 -
+ 201306/jmg_1588.jpg | 1 -
+ 201306/jmg_1589.jpg | 1 -
+ 201306/jmg_1591.jpg | 1 -
+ 201306/jmg_1592.jpg | 1 -
+ 201306/jmg_1593.jpg | 1 -
+ 201306/jmg_1593_raw.jpg | 1 -
+ 201306/jmg_1594.jpg | 1 -
+ 201306/jmg_1594_raw.jpg | 1 -
+ 201306/jmg_1595.jpg | 1 -
+ 201306/jmg_1596.jpg | 1 -
+ 201306/jmg_1597.jpg | 1 -
+ 201306/jmg_1599.jpg | 1 -
+ 201306/jmg_1626.jpg | 1 -
+ 201306/jmg_1628.jpg | 1 -
+ 201306/jmg_1629.jpg | 1 -
+ 201306/jmg_1630.jpg | 1 -
+ 201306/jmg_1631.jpg | 1 -
+ 201306/jmg_1633.jpg | 1 -
+ 201306/jmg_1635.jpg | 1 -
+ 201306/jmg_1636.jpg | 1 -
+ 201306/jmg_1637.jpg | 1 -
+ 201306/jmg_1638.jpg | 1 -
+ 201306/jmg_1640.jpg | 1 -
+ 201306/jmg_1642.jpg | 1 -
+ 201306/jmg_1643.jpg | 1 -
+ 201306/jmg_1644.jpg | 1 -
+ 201306/jmg_1647.jpg | 1 -
+ 201306/jmg_1649.jpg | 1 -
+ 201306/jmg_1650.jpg | 1 -
+ 201306/jmg_1651.jpg | 1 -
+ 201306/jmg_1652.jpg | 1 -
+ 201306/jmg_1653.jpg | 1 -
+ 201306/jmg_1655.jpg | 1 -
+ 201306/jmg_1656.jpg | 1 -
+ 201306/jmg_1660.jpg | 1 -
+ 201306/jmg_1667.jpg | 1 -
+ 201306/jmg_1682.jpg | 1 -
+ 201306/jmg_1688.jpg | 1 -
+ 201306/jmg_1689.jpg | 1 -
+ 201306/jmg_1701.jpg | 1 -
+ 201306/jmg_1702.jpg | 1 -
+ 201306/jmg_1703.jpg | 1 -
+ 201306/jmg_1710.jpg | 1 -
+ 201306/jmg_1710_raw.jpg | 1 -
+ 201306/jmg_1715.jpg | 1 -
+ 201306/jmg_1716.jpg | 1 -
+ 201306/jmg_1719.jpg | 1 -
+ 201306/jmg_1722.jpg | 1 -
+ 201306/jmg_1723.jpg | 1 -
+ 201306/jmg_1729.cr2 | 1 -
+ 201308/jmg_2038.jpg | 1 -
+ 201308/jmg_2039.jpg | 1 -
+ 201308/jmg_2040.jpg | 1 -
+ 201308/jmg_2041.jpg | 1 -
+ 201308/jmg_2042.jpg | 1 -
+ 201308/jmg_2043.jpg | 1 -
+ 201308/jmg_2045.jpg | 1 -
+ 201308/jmg_2047.jpg | 1 -
+ 201308/jmg_2048.jpg | 1 -
+ 201308/jmg_2049.jpg | 1 -
+ 201308/jmg_2050.jpg | 1 -
+ 201308/jmg_2051.jpg | 1 -
+ 201308/jmg_2052.jpg | 1 -
+ 201308/jmg_2053.jpg | 1 -
+ 201308/jmg_2054.jpg | 1 -
+ 201308/jmg_2055.jpg | 1 -
+ 201308/jmg_2056.jpg | 1 -
+ 201308/jmg_2057.jpg | 1 -
+ 201308/jmg_2058.jpg | 1 -
+ 201308/jmg_2059.jpg | 1 -
+ 201308/jmg_2060.jpg | 1 -
+ 201308/jmg_2061.jpg | 1 -
+ 201308/jmg_2062.jpg | 1 -
+ 201308/jmg_2089.cr2 | 1 -
+ 201308/jmg_2089.jpg | 1 -
+ 201308/jmg_2089_raw.jpg | 1 -
+ 201308/jmg_2090.jpg | 1 -
+ 201308/jmg_2091.jpg | 1 -
+ 201308/jmg_2092.jpg | 1 -
+ 201308/jmg_2093.jpg | 1 -
+ 201308/jmg_2096.jpg | 1 -
+ 201308/jmg_2097.jpg | 1 -
+ 201308/jmg_2098.jpg | 1 -
+ 201308/jmg_2099.cr2 | 1 -
+ 201308/jmg_2099.jpg | 1 -
+ 201308/jmg_2099_raw.jpg | 1 -
+ 201308/jmg_2100.cr2 | 1 -
+ 201308/jmg_2100.jpg | 1 -
+ 201308/jmg_2100_raw.jpg | 1 -
+ 201308/jmg_2102.jpg | 1 -
+ 201308/jmg_2103.jpg | 1 -
+ 201308/jmg_2104.jpg | 1 -
+ 201308/jmg_2105.jpg | 1 -
+ 201308/jmg_2106.jpg | 1 -
+ 201308/jmg_2107.jpg | 1 -
+ 201308/jmg_2108.jpg | 1 -
+ 201308/jmg_2109.jpg | 1 -
+ 201308/jmg_2110.jpg | 1 -
+ 201308/jmg_2111.jpg | 1 -
+ 201308/jmg_2112.jpg | 1 -
+ 201308/jmg_2113.jpg | 1 -
+ 201308/jmg_2114.jpg | 1 -
+ 201308/jmg_2115.jpg | 1 -
+ 201308/jmg_2117.jpg | 1 -
+ 201308/jmg_2118.jpg | 1 -
+ 201308/jmg_2119.jpg | 1 -
+ 201308/jmg_2120.jpg | 1 -
+ 201308/jmg_2122.jpg | 1 -
+ 201308/jmg_2125.jpg | 1 -
+ 201308/jmg_2127.jpg | 1 -
+ 201308/jmg_2129.jpg | 1 -
+ 201308/jmg_2130.jpg | 1 -
+ 201308/jmg_2132.jpg | 1 -
+ 201308/jmg_2134.jpg | 1 -
+ 201308/jmg_2135.jpg | 1 -
+ 201308/jmg_2136.jpg | 1 -
+ 201308/jmg_2137.jpg | 1 -
+ 201308/jmg_2138.jpg | 1 -
+ 201308/jmg_2148.jpg | 1 -
+ 201308/jmg_2150.jpg | 1 -
+ 201308/jmg_2151.jpg | 1 -
+ 201308/jmg_2156.jpg | 1 -
+ 201308/jmg_2158.cr2 | 1 -
+ 201308/jmg_2158.jpg | 1 -
+ 201308/jmg_2159.jpg | 1 -
+ 201308/jmg_2160.jpg | 1 -
+ 201308/jmg_2161.jpg | 1 -
+ 201308/jmg_2162.jpg | 1 -
+ 201308/jmg_2165.jpg | 1 -
+ 201308/jmg_2166.jpg | 1 -
+ 201308/jmg_2168.jpg | 1 -
+ 201308/jmg_2169.jpg | 1 -
+ 201308/jmg_2171.jpg | 1 -
+ 201308/jmg_2173.jpg | 1 -
+ 201308/jmg_2174.jpg | 1 -
+ 201308/jmg_2175.jpg | 1 -
+ 201308/jmg_2177.jpg | 1 -
+ 201308/jmg_2178.jpg | 1 -
+ 201308/jmg_2180.jpg | 1 -
+ 201308/jmg_2181.jpg | 1 -
+ 201308/jmg_2182.jpg | 1 -
+ 201308/jmg_2183.jpg | 1 -
+ 201308/jmg_2184.jpg | 1 -
+ 201308/jmg_2187.jpg | 1 -
+ 201308/jmg_2188.jpg | 1 -
+ 201308/jmg_2189.jpg | 1 -
+ 201308/jmg_2191.cr2 | 1 -
+ 201308/jmg_2191.jpg | 1 -
+ 201308/jmg_2193.cr2 | 1 -
+ 201308/jmg_2193.jpg | 1 -
+ 201308/jmg_2194.cr2 | 1 -
+ 201308/jmg_2194.jpg | 1 -
+ 201308/jmg_2197.cr2 | 1 -
+ 201308/jmg_2197.jpg | 1 -
+ 201308/jmg_2200.cr2 | 1 -
+ 201308/jmg_2200.jpg | 1 -
+ 201308/jmg_2201.cr2 | 1 -
+ 201308/jmg_2201.jpg | 1 -
+ 201308/jmg_2202.cr2 | 1 -
+ 201308/jmg_2202.jpg | 1 -
+ 201308/jmg_2209.jpg | 1 -
+ 201308/jmg_2210.jpg | 1 -
+ 201308/jmg_2215.jpg | 1 -
+ 201308/jmg_2216.jpg | 1 -
+ 201308/jmg_2217.cr2 | 1 -
+ 201308/jmg_2217.jpg | 1 -
+ 201308/jmg_2219.cr2 | 1 -
+ 201308/jmg_2219.jpg | 1 -
+ 201308/jmg_2223.jpg | 1 -
+ 201308/jmg_2224.jpg | 1 -
+ 201308/jmg_2225.cr2 | 1 -
+ 201308/jmg_2225.jpg | 1 -
+ 201308/jmg_2227.jpg | 1 -
+ 201308/jmg_2228.jpg | 1 -
+ 201308/jmg_2235.jpg | 1 -
+ 201308/jmg_2237.jpg | 1 -
+ 201308/jmg_2238.jpg | 1 -
+ 201308/jmg_2239.cr2 | 1 -
+ 201308/jmg_2239.jpg | 1 -
+ 201308/jmg_2239_raw.jpg | 1 -
+ 201308/jmg_2240.jpg | 1 -
+ 201308/jmg_2243.jpg | 1 -
+ 201308/jmg_2244.jpg | 1 -
+ 201308/jmg_2245.jpg | 1 -
+ 201308/jmg_2247.cr2 | 1 -
+ 201308/jmg_2247.jpg | 1 -
+ 201308/jmg_2249.jpg | 1 -
+ 201308/jmg_2250.cr2 | 1 -
+ 201308/jmg_2250.jpg | 1 -
+ 201308/jmg_2252.jpg | 1 -
+ 201308/jmg_2253.jpg | 1 -
+ 201308/jmg_2254.jpg | 1 -
+ incoming/5d/201203/jmg_8701.cr2 | 1 +
+ incoming/5d/201203/jmg_8702.jpg | 1 +
+ incoming/5d/201203/jmg_8705.jpg | 1 +
+ incoming/5d/201203/jmg_8711.jpg | 1 +
+ incoming/5d/201203/jmg_8717.jpg | 1 +
+ incoming/5d/201203/jmg_8718.jpg | 1 +
+ incoming/5d/201203/jmg_8719.jpg | 1 +
+ incoming/5d/201203/jmg_8721.jpg | 1 +
+ incoming/5d/201203/jmg_8725.jpg | 1 +
+ incoming/5d/201203/jmg_8726.jpg | 1 +
+ incoming/5d/201203/jmg_8731.jpg | 1 +
+ incoming/5d/201203/jmg_8745.jpg | 1 +
+ incoming/5d/201203/jmg_8747_raw.jpg | 1 +
+ incoming/5d/201203/jmg_8750.cr2 | 1 +
+ incoming/5d/201203/jmg_8750.jpg | 1 +
+ incoming/5d/201207/jmg_9048.jpg | 1 +
+ incoming/5d/201207/jmg_9053.jpg | 1 +
+ incoming/5d/201207/jmg_9054.jpg | 1 +
+ incoming/5d/201207/jmg_9069.cr2 | 1 +
+ incoming/5d/201207/jmg_9069.jpg | 1 +
+ incoming/5d/201207/jmg_9070.cr2 | 1 +
+ incoming/5d/201207/jmg_9070.jpg | 1 +
+ incoming/5d/201207/jmg_9072.cr2 | 1 +
+ incoming/5d/201207/jmg_9072.jpg | 1 +
+ incoming/5d/201207/jmg_9076.cr2 | 1 +
+ incoming/5d/201207/jmg_9076.jpg | 1 +
+ incoming/5d/201302/jmg_0502.cr2 | 1 +
+ incoming/5d/201302/jmg_0502.jpg | 1 +
+ incoming/5d/201302/jmg_0503.jpg | 1 +
+ incoming/5d/201302/jmg_0507.jpg | 1 +
+ incoming/5d/201302/jmg_0510.jpg | 1 +
+ incoming/5d/201302/jmg_0512.jpg | 1 +
+ incoming/5d/201302/jmg_0513.jpg | 1 +
+ incoming/5d/201302/jmg_0514.jpg | 1 +
+ incoming/5d/201302/jmg_0516.jpg | 1 +
+ incoming/5d/201302/jmg_0517.jpg | 1 +
+ incoming/5d/201302/jmg_0518.jpg | 1 +
+ incoming/5d/201302/jmg_0521.jpg | 1 +
+ incoming/5d/201302/jmg_0522.jpg | 1 +
+ incoming/5d/201302/jmg_0523.jpg | 1 +
+ incoming/5d/201302/jmg_0524.jpg | 1 +
+ incoming/5d/201302/jmg_0526.jpg | 1 +
+ incoming/5d/201302/jmg_0527.jpg | 1 +
+ incoming/5d/201302/jmg_0528.jpg | 1 +
+ incoming/5d/201302/jmg_0532.cr2 | 1 +
+ incoming/5d/201302/jmg_0532.jpg | 1 +
+ incoming/5d/201302/jmg_0534.jpg | 1 +
+ incoming/5d/201302/jmg_0535.jpg | 1 +
+ incoming/5d/201302/jmg_0537.jpg | 1 +
+ incoming/5d/201302/jmg_0539.jpg | 1 +
+ incoming/5d/201302/jmg_0541.jpg | 1 +
+ incoming/5d/201302/jmg_0543.jpg | 1 +
+ incoming/5d/jmg_0021.jpg | 1 +
+ incoming/5d/jmg_0025.jpg | 1 +
+ incoming/5d/jmg_0026.jpg | 1 +
+ incoming/5d/jmg_0027.jpg | 1 +
+ incoming/5d/jmg_0034.jpg | 1 +
+ incoming/5d/jmg_0035.jpg | 1 +
+ incoming/5d/jmg_0036.jpg | 1 +
+ incoming/5d/jmg_0130.jpg | 1 +
+ incoming/5d/jmg_0131.jpg | 1 +
+ incoming/5d/jmg_0133.jpg | 1 +
+ incoming/5d/jmg_0155.jpg | 1 +
+ incoming/5d/jmg_0156.jpg | 1 +
+ incoming/5d/jmg_0158.cr2 | 1 +
+ incoming/5d/jmg_0165.cr2 | 1 +
+ incoming/5d/jmg_0166.cr2 | 1 +
+ incoming/5d/jmg_0178.cr2 | 1 +
+ incoming/5d/jmg_0179.jpg | 1 +
+ incoming/5d/jmg_0180.cr2 | 1 +
+ incoming/5d/jmg_0184.jpg | 1 +
+ incoming/5d/jmg_0185.cr2 | 1 +
+ incoming/5d/jmg_0187.cr2 | 1 +
+ incoming/5d/jmg_0310.jpg | 1 +
+ incoming/5d/jmg_0312.jpg | 1 +
+ incoming/5d/jmg_0315.jpg | 1 +
+ incoming/5d/jmg_0340.jpg | 1 +
+ incoming/5d/jmg_0357.jpg | 1 +
+ incoming/5d/jmg_0364.jpg | 1 +
+ incoming/5d/jmg_0365.jpg | 1 +
+ incoming/5d/jmg_0368.jpg | 1 +
+ incoming/5d/jmg_0374.jpg | 1 +
+ incoming/5d/jmg_0375.jpg | 1 +
+ incoming/5d/jmg_0386.jpg | 1 +
+ incoming/5d/jmg_0399.jpg | 1 +
+ incoming/5d/jmg_0411.jpg | 1 +
+ incoming/5d/jmg_0418.jpg | 1 +
+ incoming/5d/jmg_0476.cr2 | 1 +
+ incoming/5d/jmg_0476.jpg | 1 +
+ incoming/5d/jmg_0503.jpg | 1 +
+ incoming/5d/jmg_0507.cr2 | 1 +
+ incoming/5d/jmg_0513.cr2 | 1 +
+ incoming/5d/jmg_0513.jpg | 1 +
+ incoming/5d/jmg_0516.cr2 | 1 +
+ incoming/5d/jmg_0517.cr2 | 1 +
+ incoming/5d/jmg_0518.jpg | 1 +
+ incoming/5d/jmg_0522.cr2 | 1 +
+ incoming/5d/jmg_0524.cr2 | 1 +
+ incoming/5d/jmg_0524.jpg | 1 +
+ incoming/5d/jmg_0530.jpg | 1 +
+ incoming/5d/jmg_0541.cr2 | 1 +
+ incoming/5d/jmg_0550.jpg | 1 +
+ incoming/5d/jmg_0554.jpg | 1 +
+ incoming/5d/jmg_0555.jpg | 1 +
+ incoming/5d/jmg_0558.jpg | 1 +
+ incoming/5d/jmg_0563.jpg | 1 +
+ incoming/5d/jmg_0573.jpg | 1 +
+ incoming/5d/jmg_0575.cr2 | 1 +
+ incoming/5d/jmg_0578.cr2 | 1 +
+ incoming/5d/jmg_0579.cr2 | 1 +
+ incoming/5d/jmg_0582.jpg | 1 +
+ incoming/5d/jmg_0593.cr2 | 1 +
+ incoming/5d/jmg_0594.cr2 | 1 +
+ incoming/5d/jmg_0594.jpg | 1 +
+ incoming/5d/jmg_0595.cr2 | 1 +
+ incoming/5d/jmg_0600.jpg | 1 +
+ incoming/5d/jmg_0606.cr2 | 1 +
+ incoming/5d/jmg_0607.jpg | 1 +
+ incoming/5d/jmg_0610.cr2 | 1 +
+ incoming/5d/jmg_0610.jpg | 1 +
+ incoming/5d/jmg_0612.jpg | 1 +
+ incoming/5d/jmg_0613.cr2 | 1 +
+ incoming/5d/jmg_0614.jpg | 1 +
+ incoming/5d/jmg_0619.cr2 | 1 +
+ incoming/5d/jmg_0623.jpg | 1 +
+ incoming/5d/jmg_0628.cr2 | 1 +
+ incoming/5d/jmg_0628.jpg | 1 +
+ incoming/5d/jmg_0639.jpg | 1 +
+ incoming/5d/jmg_0645.cr2 | 1 +
+ incoming/5d/jmg_0646.jpg | 1 +
+ incoming/5d/jmg_0647.cr2 | 1 +
+ incoming/5d/jmg_0648.jpg | 1 +
+ incoming/5d/jmg_0649.jpg | 1 +
+ incoming/5d/jmg_0655.jpg | 1 +
+ incoming/5d/jmg_0667.jpg | 1 +
+ incoming/5d/jmg_0670.jpg | 1 +
+ incoming/5d/jmg_0673.jpg | 1 +
+ incoming/5d/jmg_0679.jpg | 1 +
+ incoming/5d/jmg_0685.jpg | 1 +
+ incoming/5d/jmg_0699.cr2 | 1 +
+ incoming/5d/jmg_0700.cr2 | 1 +
+ incoming/5d/jmg_0701.cr2 | 1 +
+ incoming/5d/jmg_0708.jpg | 1 +
+ incoming/5d/jmg_0718.jpg | 1 +
+ incoming/5d/jmg_0726.cr2 | 1 +
+ incoming/5d/jmg_0728.jpg | 1 +
+ incoming/5d/jmg_0730.jpg | 1 +
+ incoming/5d/jmg_0734.jpg | 1 +
+ incoming/5d/jmg_0740.jpg | 1 +
+ incoming/5d/jmg_0743.cr2 | 1 +
+ incoming/5d/jmg_0744.cr2 | 1 +
+ incoming/5d/jmg_0745.cr2 | 1 +
+ incoming/5d/jmg_0747.jpg | 1 +
+ incoming/5d/jmg_0750.cr2 | 1 +
+ incoming/5d/jmg_0755.cr2 | 1 +
+ incoming/5d/jmg_0759.cr2 | 1 +
+ incoming/5d/jmg_0760.cr2 | 1 +
+ incoming/5d/jmg_0761.jpg | 1 +
+ incoming/5d/jmg_0765.jpg | 1 +
+ incoming/5d/jmg_0768.jpg | 1 +
+ incoming/5d/jmg_0771.jpg | 1 +
+ incoming/5d/jmg_0778.jpg | 1 +
+ incoming/5d/jmg_0780.jpg | 1 +
+ incoming/5d/jmg_0782.cr2 | 1 +
+ incoming/5d/jmg_0786.cr2 | 1 +
+ incoming/5d/jmg_0787.cr2 | 1 +
+ incoming/5d/jmg_0788.cr2 | 1 +
+ incoming/5d/jmg_0794.jpg | 1 +
+ incoming/5d/jmg_0796.jpg | 1 +
+ incoming/5d/jmg_0801.cr2 | 1 +
+ incoming/5d/jmg_0803.cr2 | 1 +
+ incoming/5d/jmg_0804.cr2 | 1 +
+ incoming/5d/jmg_0812.jpg | 1 +
+ incoming/5d/jmg_0819.jpg | 1 +
+ incoming/5d/jmg_0827.jpg | 1 +
+ incoming/5d/jmg_0830.jpg | 1 +
+ incoming/5d/jmg_0842.jpg | 1 +
+ incoming/5d/jmg_0846.jpg | 1 +
+ incoming/5d/jmg_0857.cr2 | 1 +
+ incoming/5d/jmg_0863.jpg | 1 +
+ incoming/5d/jmg_0866.cr2 | 1 +
+ incoming/5d/jmg_0868.cr2 | 1 +
+ incoming/5d/jmg_0868.jpg | 1 +
+ incoming/5d/jmg_0870.jpg | 1 +
+ incoming/5d/jmg_0877.jpg | 1 +
+ incoming/5d/jmg_0882.cr2 | 1 +
+ incoming/5d/jmg_0883.jpg | 1 +
+ incoming/5d/jmg_0888.jpg | 1 +
+ incoming/5d/jmg_0891.jpg | 1 +
+ incoming/5d/jmg_0894.cr2 | 1 +
+ incoming/5d/jmg_0896.cr2 | 1 +
+ incoming/5d/jmg_0897.cr2 | 1 +
+ incoming/5d/jmg_0898.jpg | 1 +
+ incoming/5d/jmg_0899.cr2 | 1 +
+ incoming/5d/jmg_0900.jpg | 1 +
+ incoming/5d/jmg_0905.jpg | 1 +
+ incoming/5d/jmg_0908.jpg | 1 +
+ incoming/5d/jmg_0914.jpg | 1 +
+ incoming/5d/jmg_0915.jpg | 1 +
+ incoming/5d/jmg_0916.jpg | 1 +
+ incoming/5d/jmg_0923.jpg | 1 +
+ incoming/5d/jmg_0924.jpg | 1 +
+ incoming/5d/jmg_0926.jpg | 1 +
+ incoming/5d/jmg_0928.jpg | 1 +
+ incoming/5d/jmg_0929.jpg | 1 +
+ incoming/5d/jmg_0936.jpg | 1 +
+ incoming/5d/jmg_0942.jpg | 1 +
+ incoming/5d/jmg_0944.jpg | 1 +
+ incoming/5d/jmg_0948.jpg | 1 +
+ incoming/5d/jmg_0960.jpg | 1 +
+ incoming/5d/jmg_0966.jpg | 1 +
+ incoming/5d/jmg_0970.cr2 | 1 +
+ incoming/5d/jmg_0970.jpg | 1 +
+ incoming/5d/jmg_0972.jpg | 1 +
+ incoming/5d/jmg_0976.jpg | 1 +
+ incoming/5d/jmg_0983.cr2 | 1 +
+ incoming/5d/jmg_0985.cr2 | 1 +
+ incoming/5d/jmg_0985.jpg | 1 +
+ incoming/5d/jmg_0994.jpg | 1 +
+ incoming/5d/jmg_1005.jpg | 2 +-
+ incoming/5d/jmg_1009.jpg | 2 +-
+ incoming/5d/jmg_1012.jpg | 2 +-
+ incoming/5d/jmg_1020.jpg | 2 +-
+ incoming/5d/jmg_1021.jpg | 2 +-
+ incoming/5d/jmg_1032.jpg | 2 +-
+ incoming/5d/jmg_1033.jpg | 2 +-
+ incoming/5d/jmg_1037.jpg | 2 +-
+ incoming/5d/jmg_1039.jpg | 2 +-
+ incoming/5d/jmg_1048.jpg | 2 +-
+ incoming/5d/jmg_1051.jpg | 2 +-
+ incoming/5d/jmg_1063.jpg | 2 +-
+ incoming/5d/jmg_1064.jpg | 2 +-
+ incoming/5d/jmg_1067.jpg | 2 +-
+ incoming/5d/jmg_1116.jpg | 2 +-
+ incoming/5d/jmg_1118.jpg | 2 +-
+ incoming/5d/jmg_1125.jpg | 2 +-
+ incoming/5d/jmg_1126.jpg | 2 +-
+ incoming/5d/jmg_1129.jpg | 2 +-
+ incoming/5d/jmg_1133.jpg | 2 +-
+ incoming/5d/jmg_1138.jpg | 2 +-
+ incoming/5d/jmg_1139.jpg | 2 +-
+ incoming/5d/jmg_1143.jpg | 2 +-
+ incoming/5d/jmg_1149.jpg | 2 +-
+ incoming/5d/jmg_1150.jpg | 2 +-
+ incoming/5d/jmg_1155.jpg | 2 +-
+ incoming/5d/jmg_1160.jpg | 2 +-
+ incoming/5d/jmg_1168.jpg | 2 +-
+ incoming/5d/jmg_1173.jpg | 2 +-
+ incoming/5d/jmg_1175.jpg | 2 +-
+ incoming/5d/jmg_1177.jpg | 2 +-
+ incoming/5d/jmg_1179.jpg | 2 +-
+ incoming/5d/jmg_1183.jpg | 2 +-
+ incoming/5d/jmg_1185.jpg | 2 +-
+ incoming/5d/jmg_1189.jpg | 2 +-
+ incoming/5d/jmg_1192.jpg | 2 +-
+ incoming/5d/jmg_1199.jpg | 2 +-
+ incoming/5d/jmg_1205.jpg | 2 +-
+ incoming/5d/jmg_1209.cr2 | 1 +
+ incoming/5d/jmg_1209.jpg | 1 +
+ incoming/5d/jmg_1211.cr2 | 1 +
+ incoming/5d/jmg_1211.jpg | 1 +
+ incoming/5d/jmg_1217.cr2 | 1 +
+ incoming/5d/jmg_1467.cr2 | 1 +
+ incoming/5d/jmg_1469.jpg | 1 +
+ incoming/5d/jmg_1470.cr2 | 1 +
+ incoming/5d/jmg_1471.cr2 | 1 +
+ incoming/5d/jmg_1472.cr2 | 1 +
+ incoming/5d/jmg_1477.cr2 | 1 +
+ incoming/5d/jmg_1477.jpg | 1 +
+ incoming/5d/jmg_1481.cr2 | 1 +
+ incoming/5d/jmg_1483.cr2 | 1 +
+ incoming/5d/jmg_1485.jpg | 1 +
+ incoming/5d/jmg_1488.jpg | 1 +
+ incoming/5d/jmg_1491.jpg | 1 +
+ incoming/5d/jmg_1496.cr2 | 1 +
+ incoming/5d/jmg_1502.jpg | 1 +
+ incoming/5d/jmg_1503.cr2 | 1 +
+ incoming/5d/jmg_1504.jpg | 1 +
+ incoming/5d/jmg_1507.jpg | 1 +
+ incoming/5d/jmg_1515.jpg | 1 +
+ incoming/5d/jmg_1520.jpg | 1 +
+ incoming/5d/jmg_1523.jpg | 1 +
+ incoming/5d/jmg_1525.jpg | 1 +
+ incoming/5d/jmg_1539.jpg | 1 +
+ incoming/5d/jmg_1542.jpg | 1 +
+ incoming/5d/jmg_1546.jpg | 1 +
+ incoming/5d/jmg_1547.cr2 | 1 +
+ incoming/5d/jmg_1549.jpg | 1 +
+ incoming/5d/jmg_1552.jpg | 1 +
+ incoming/5d/jmg_1554.cr2 | 1 +
+ incoming/5d/jmg_1555.cr2 | 1 +
+ incoming/5d/jmg_1556.cr2 | 1 +
+ incoming/5d/jmg_1559.cr2 | 1 +
+ incoming/5d/jmg_1560.cr2 | 1 +
+ incoming/5d/jmg_1561.cr2 | 1 +
+ incoming/5d/jmg_1562.cr2 | 1 +
+ incoming/5d/jmg_1565.cr2 | 1 +
+ incoming/5d/jmg_1567.cr2 | 1 +
+ incoming/5d/jmg_1572.cr2 | 1 +
+ incoming/5d/jmg_1577.cr2 | 1 +
+ incoming/5d/jmg_1578.jpg | 1 +
+ incoming/5d/jmg_1583_cut.jpg | 1 +
+ incoming/5d/jmg_1583_raw.jpg | 1 +
+ incoming/5d/jmg_1592.cr2 | 1 +
+ incoming/5d/jmg_1593.jpg | 1 +
+ incoming/5d/jmg_1626.cr2 | 1 +
+ incoming/5d/jmg_1627.jpg | 1 +
+ incoming/5d/jmg_1628.cr2 | 1 +
+ incoming/5d/jmg_1629.jpg | 1 +
+ incoming/5d/jmg_1630.cr2 | 1 +
+ incoming/5d/jmg_1631.cr2 | 1 +
+ incoming/5d/jmg_1633.cr2 | 1 +
+ incoming/5d/jmg_1638.jpg | 1 +
+ incoming/5d/jmg_1639.cr2 | 1 +
+ incoming/5d/jmg_1646.cr2 | 1 +
+ incoming/5d/jmg_1646.jpg | 1 +
+ incoming/5d/jmg_1650.jpg | 1 +
+ incoming/5d/jmg_1651.cr2 | 1 +
+ incoming/5d/jmg_1654.cr2 | 1 +
+ incoming/5d/jmg_1656.jpg | 1 +
+ incoming/5d/jmg_1677.jpg | 1 +
+ incoming/5d/jmg_1689.jpg | 1 +
+ incoming/5d/jmg_1701.jpg | 1 +
+ incoming/5d/jmg_1703.jpg | 1 +
+ incoming/5d/jmg_1723.jpg | 1 +
+ incoming/5d/jmg_2039.jpg | 1 +
+ incoming/5d/jmg_2041.jpg | 1 +
+ incoming/5d/jmg_2048.cr2 | 1 +
+ incoming/5d/jmg_2052.jpg | 1 +
+ incoming/5d/jmg_2061.jpg | 1 +
+ incoming/5d/jmg_2064_raw.jpg | 1 -
+ incoming/5d/jmg_2065_mo.jpg | 1 -
+ incoming/5d/jmg_2065_raw.jpg | 1 -
+ incoming/5d/jmg_2066_mo.jpg | 1 -
+ incoming/5d/jmg_2066_raw.jpg | 1 -
+ incoming/5d/jmg_2090.jpg | 1 +
+ incoming/5d/jmg_2093.jpg | 1 +
+ incoming/5d/jmg_2100.cr2 | 1 +
+ incoming/5d/jmg_2103.jpg | 1 +
+ incoming/5d/jmg_2107.jpg | 1 +
+ incoming/5d/jmg_2108.jpg | 1 +
+ incoming/5d/jmg_2112.jpg | 1 +
+ incoming/5d/jmg_2118.jpg | 1 +
+ incoming/5d/jmg_2119.jpg | 1 +
+ incoming/5d/jmg_2122.jpg | 1 +
+ incoming/5d/jmg_2125.jpg | 1 +
+ incoming/5d/jmg_2137.jpg | 1 +
+ incoming/5d/jmg_2149.jpg | 1 +
+ incoming/5d/jmg_2150.jpg | 1 +
+ incoming/5d/jmg_2158.cr2 | 1 +
+ incoming/5d/jmg_2160.jpg | 1 +
+ incoming/5d/jmg_2165.jpg | 1 +
+ incoming/5d/jmg_2188.jpg | 1 +
+ incoming/5d/jmg_2189.jpg | 1 +
+ incoming/5d/jmg_2193.jpg | 1 +
+ incoming/5d/jmg_2194.cr2 | 1 +
+ incoming/5d/jmg_2200.jpg | 1 +
+ incoming/5d/jmg_2201.cr2 | 1 +
+ incoming/5d/jmg_2201.jpg | 1 +
+ incoming/5d/jmg_2210.jpg | 1 +
+ incoming/5d/jmg_2215.cr2 | 1 +
+ incoming/5d/jmg_2216.cr2 | 1 +
+ incoming/5d/jmg_2216.jpg | 1 +
+ incoming/5d/jmg_2224.jpg | 1 +
+ incoming/5d/jmg_2235.jpg | 1 +
+ incoming/5d/jmg_2238.jpg | 1 +
+ incoming/5d/jmg_2239.cr2 | 1 +
+ incoming/5d/jmg_2239.jpg | 1 +
+ incoming/5d/jmg_2240.jpg | 1 +
+ incoming/5d/jmg_2244.jpg | 1 +
+ incoming/5d/jmg_2247.jpg | 1 +
+ incoming/5d/jmg_7250.cr2 | 1 +
+ incoming/5d/jmg_7250.jpg | 1 +
+ incoming/5d/jmg_7256.jpg | 1 +
+ incoming/5d/jmg_7257.cr2 | 1 +
+ incoming/5d/jmg_7259.cr2 | 1 +
+ incoming/5d/jmg_7263.jpg | 1 +
+ incoming/5d/jmg_7265.cr2 | 1 +
+ incoming/5d/jmg_7269.cr2 | 1 +
+ incoming/5d/jmg_7270.cr2 | 1 +
+ incoming/5d/jmg_7279.cr2 | 1 +
+ incoming/5d/jmg_7286.cr2 | 1 +
+ incoming/5d/jmg_7286.jpg | 1 +
+ incoming/5d/jmg_7290.cr2 | 1 +
+ incoming/5d/jmg_7290.jpg | 1 +
+ incoming/5d/jmg_7293.cr2 | 1 +
+ incoming/5d/jmg_7296.cr2 | 1 +
+ incoming/5d/jmg_7299.jpg | 1 +
+ incoming/5d/jmg_7300.cr2 | 1 +
+ incoming/5d/jmg_7300.jpg | 1 +
+ incoming/5d/jmg_7305_raw.jpg | 1 +
+ incoming/5d/jmg_8532.cr2 | 1 +
+ incoming/5d/jmg_8533.cr2 | 1 +
+ incoming/5d/jmg_8534.cr2 | 1 +
+ incoming/5d/jmg_8536.jpg | 1 +
+ incoming/5d/jmg_8538.cr2 | 1 +
+ incoming/5d/jmg_8549.cr2 | 1 +
+ incoming/5d/jmg_8549.jpg | 1 +
+ incoming/5d/jmg_8552.cr2 | 1 +
+ incoming/5d/jmg_8557.cr2 | 1 +
+ incoming/5d/jmg_8560.cr2 | 1 +
+ incoming/5d/jmg_8565.cr2 | 1 +
+ incoming/5d/jmg_8566.cr2 | 1 +
+ incoming/5d/jmg_8569.jpg | 1 +
+ incoming/5d/jmg_8575.jpg | 1 +
+ incoming/5d/jmg_8576.jpg | 1 +
+ incoming/5d/jmg_8578.cr2 | 1 +
+ incoming/5d/jmg_8579.cr2 | 1 +
+ incoming/5d/jmg_8580.jpg | 1 +
+ incoming/5d/jmg_8583.cr2 | 1 +
+ incoming/5d/jmg_8588.cr2 | 1 +
+ incoming/5d/jmg_8589.cr2 | 1 +
+ incoming/5d/jmg_8595.jpg | 1 +
+ incoming/5d/jmg_8597.jpg | 1 +
+ incoming/5d/jmg_8599.jpg | 1 +
+ incoming/5d/jmg_8602.cr2 | 1 +
+ incoming/5d/jmg_8603.cr2 | 1 +
+ incoming/5d/jmg_8606.cr2 | 1 +
+ incoming/5d/jmg_8606.jpg | 1 +
+ incoming/5d/jmg_8609.jpg | 1 +
+ incoming/5d/jmg_8613.jpg | 1 +
+ incoming/5d/jmg_8615.cr2 | 1 +
+ incoming/5d/jmg_8617.jpg | 1 +
+ incoming/5d/jmg_8619.cr2 | 1 +
+ incoming/5d/jmg_8620.jpg | 1 +
+ incoming/5d/jmg_8625.jpg | 1 +
+ incoming/5d/jmg_8627.jpg | 1 +
+ incoming/5d/jmg_8628.jpg | 1 +
+ incoming/5d/jmg_8632.cr2 | 1 +
+ incoming/5d/jmg_8636.cr2 | 1 +
+ incoming/5d/jmg_8636.jpg | 1 +
+ incoming/5d/jmg_8637.cr2 | 1 +
+ incoming/5d/jmg_8639.jpg | 1 +
+ incoming/5d/jmg_8640.cr2 | 1 +
+ incoming/5d/jmg_8655.jpg | 1 +
+ incoming/5d/jmg_8657.jpg | 1 +
+ incoming/5d/jmg_8670.cr2 | 1 +
+ incoming/5d/jmg_8673.jpg | 1 +
+ incoming/5d/jmg_8674.cr2 | 1 +
+ incoming/5d/jmg_8676.cr2 | 1 +
+ incoming/5d/jmg_8676.jpg | 1 +
+ incoming/5d/jmg_8677.cr2 | 1 +
+ incoming/5d/jmg_8681.jpg | 1 +
+ incoming/5d/jmg_8682.cr2 | 1 +
+ incoming/5d/jmg_8702.cr2 | 1 +
+ incoming/5d/jmg_8702.jpg | 1 +
+ incoming/5d/jmg_8707.jpg | 1 +
+ incoming/5d/jmg_8714.jpg | 1 +
+ incoming/5d/jmg_8716.jpg | 1 +
+ incoming/5d/jmg_8717.cr2 | 1 +
+ incoming/5d/jmg_8719.jpg | 1 +
+ incoming/5d/jmg_8721.jpg | 1 +
+ incoming/5d/jmg_8727.cr2 | 1 +
+ incoming/5d/jmg_8730.jpg | 1 +
+ incoming/5d/jmg_8736.cr2 | 1 +
+ incoming/5d/jmg_8737.cr2 | 1 +
+ incoming/5d/jmg_8742.cr2 | 1 +
+ incoming/5d/jmg_8742.jpg | 1 +
+ incoming/5d/jmg_8745.jpg | 1 +
+ incoming/5d/jmg_8748.cr2 | 1 +
+ incoming/5d/jmg_8748.jpg | 1 +
+ incoming/5d/jmg_8751.cr2 | 1 +
+ incoming/5d/jmg_8755.cr2 | 1 +
+ incoming/5d/jmg_8757.cr2 | 1 +
+ incoming/5d/jmg_8760.cr2 | 1 +
+ incoming/5d/jmg_8760.jpg | 1 +
+ incoming/5d/jmg_8765.cr2 | 1 +
+ incoming/5d/jmg_8771.jpg | 1 +
+ incoming/5d/jmg_8801.jpg | 1 +
+ incoming/5d/jmg_8803.cr2 | 1 +
+ incoming/5d/jmg_8803.jpg | 1 +
+ incoming/5d/jmg_8804.jpg | 1 +
+ incoming/5d/jmg_8805.jpg | 1 +
+ incoming/5d/jmg_8813.jpg | 1 +
+ incoming/5d/jmg_8816.cr2 | 1 +
+ incoming/5d/jmg_8823.jpg | 1 +
+ incoming/5d/jmg_8827.cr2 | 1 +
+ incoming/5d/jmg_8829.cr2 | 1 +
+ incoming/5d/jmg_8832.jpg | 1 +
+ incoming/5d/jmg_8833.cr2 | 1 +
+ incoming/5d/jmg_8837.cr2 | 1 +
+ incoming/5d/jmg_8838.jpg | 1 +
+ incoming/5d/jmg_8840.jpg | 1 +
+ incoming/5d/jmg_8842.jpg | 1 +
+ incoming/5d/jmg_8844.cr2 | 1 +
+ incoming/5d/jmg_8850.cr2 | 1 +
+ incoming/5d/jmg_8850.jpg | 1 +
+ incoming/5d/jmg_8852.cr2 | 1 +
+ incoming/5d/jmg_8853.cr2 | 1 +
+ incoming/5d/jmg_8853.jpg | 1 +
+ incoming/5d/jmg_8856.cr2 | 1 +
+ incoming/5d/jmg_8859.jpg | 1 +
+ incoming/5d/jmg_8863.jpg | 1 +
+ incoming/5d/jmg_8870.jpg | 1 +
+ incoming/5d/jmg_8871.cr2 | 1 +
+ incoming/5d/jmg_8871.jpg | 1 +
+ incoming/5d/jmg_8881.jpg | 1 +
+ incoming/5d/jmg_8883.jpg | 1 +
+ incoming/5d/jmg_8886.jpg | 1 +
+ incoming/5d/jmg_8887.cr2 | 1 +
+ incoming/5d/jmg_8889.cr2 | 1 +
+ incoming/5d/jmg_8894.cr2 | 1 +
+ incoming/5d/jmg_8897.cr2 | 1 +
+ incoming/5d/jmg_8898.cr2 | 1 +
+ incoming/5d/jmg_8900.jpg | 1 +
+ incoming/5d/jmg_8901.cr2 | 1 +
+ incoming/5d/jmg_8902.cr2 | 1 +
+ incoming/5d/jmg_8904.cr2 | 1 +
+ incoming/5d/jmg_8906.jpg | 1 +
+ incoming/5d/jmg_8908.cr2 | 1 +
+ incoming/5d/jmg_8920.cr2 | 1 +
+ incoming/5d/jmg_8920.jpg | 1 +
+ incoming/5d/jmg_8922.cr2 | 1 +
+ incoming/5d/jmg_8922.jpg | 1 +
+ incoming/5d/jmg_8923.cr2 | 1 +
+ incoming/5d/jmg_8924.jpg | 1 +
+ incoming/5d/jmg_8925.cr2 | 1 +
+ incoming/5d/jmg_8929.jpg | 1 +
+ incoming/5d/jmg_8930.jpg | 1 +
+ incoming/5d/jmg_8937.cr2 | 1 +
+ incoming/5d/jmg_8939.cr2 | 1 +
+ incoming/5d/jmg_8940.jpg | 1 +
+ incoming/5d/jmg_8941.jpg | 1 +
+ incoming/5d/jmg_8943.cr2 | 1 +
+ incoming/5d/jmg_8944.jpg | 1 +
+ incoming/5d/jmg_8950.cr2 | 1 +
+ incoming/5d/jmg_8951.jpg | 1 +
+ incoming/5d/jmg_8955.jpg | 1 +
+ incoming/5d/jmg_8959.cr2 | 1 +
+ incoming/5d/jmg_8960.jpg | 1 +
+ incoming/5d/jmg_8962.cr2 | 1 +
+ incoming/5d/jmg_8964.cr2 | 1 +
+ incoming/5d/jmg_8965.jpg | 1 +
+ incoming/5d/jmg_8966.jpg | 1 +
+ incoming/5d/jmg_8971.jpg | 1 +
+ incoming/5d/jmg_8976.jpg | 1 +
+ incoming/5d/jmg_8978.cr2 | 1 +
+ incoming/5d/jmg_8981.jpg | 1 +
+ incoming/5d/jmg_8982.jpg | 1 +
+ incoming/5d/jmg_8985.jpg | 1 +
+ incoming/5d/jmg_8988.cr2 | 1 +
+ incoming/5d/jmg_8988.jpg | 1 +
+ incoming/5d/jmg_8992.cr2 | 1 +
+ incoming/5d/jmg_8995.jpg | 1 +
+ incoming/5d/jmg_8996.cr2 | 1 +
+ incoming/5d/jmg_8997.cr2 | 1 +
+ incoming/5d/jmg_8999.cr2 | 1 +
+ incoming/5d/jmg_9000.cr2 | 1 +
+ incoming/5d/jmg_9015.cr2 | 1 +
+ incoming/5d/jmg_9017.cr2 | 1 +
+ incoming/5d/jmg_9019.cr2 | 1 +
+ incoming/5d/jmg_9021.cr2 | 1 +
+ incoming/5d/jmg_9021.jpg | 1 +
+ incoming/5d/jmg_9022.cr2 | 1 +
+ incoming/5d/jmg_9027.cr2 | 1 +
+ incoming/5d/jmg_9028.jpg | 1 +
+ incoming/5d/jmg_9031.cr2 | 1 +
+ incoming/5d/jmg_9035.cr2 | 1 +
+ incoming/5d/jmg_9043.jpg | 1 +
+ incoming/5d/jmg_9057.cr2 | 1 +
+ incoming/5d/jmg_9064.cr2 | 1 +
+ incoming/5d/jmg_9077.jpg | 1 +
+ incoming/5d/jmg_9078.jpg | 1 +
+ incoming/5d/jmg_9081.jpg | 1 +
+ incoming/5d/jmg_9082.cr2 | 1 +
+ incoming/5d/jmg_9083.jpg | 1 +
+ incoming/5d/jmg_9086.cr2 | 1 +
+ incoming/5d/jmg_9088.jpg | 1 +
+ incoming/5d/jmg_9308.jpg | 1 +
+ incoming/5d/jmg_9312.cr2 | 1 +
+ incoming/5d/jmg_9313.jpg | 1 +
+ incoming/5d/jmg_9319.jpg | 1 +
+ incoming/5d/jmg_9521.cr2 | 1 +
+ incoming/5d/jmg_9522.cr2 | 1 +
+ incoming/5d/jmg_9533.jpg | 1 +
+ incoming/5d/jmg_9534.jpg | 1 +
+ incoming/5d/jmg_9535.cr2 | 1 +
+ incoming/5d/jmg_9538.cr2 | 1 +
+ incoming/5d/jmg_9538.jpg | 1 +
+ incoming/5d/jmg_9540.jpg | 1 +
+ incoming/5d/jmg_9542.cr2 | 1 +
+ incoming/5d/jmg_9545.jpg | 1 +
+ incoming/5d/jmg_9554.jpg | 1 +
+ incoming/5d/jmg_9555.jpg | 1 +
+ incoming/5d/jmg_9558.jpg | 1 +
+ incoming/5d/jmg_9561.cr2 | 1 +
+ incoming/5d/jmg_9585.cr2 | 1 +
+ incoming/5d/jmg_9587.jpg | 1 +
+ incoming/5d/jmg_9591.jpg | 1 +
+ incoming/5d/jmg_9595.jpg | 1 +
+ incoming/5d/jmg_9598.cr2 | 1 +
+ incoming/5d/jmg_9600.jpg | 1 +
+ incoming/5d/jmg_9604.jpg | 1 +
+ incoming/5d/jmg_9610.jpg | 1 +
+ incoming/5d/jmg_9613.cr2 | 1 +
+ incoming/5d/jmg_9613.jpg | 1 +
+ incoming/5d/jmg_9614.cr2 | 1 +
+ incoming/5d/jmg_9618.jpg | 1 +
+ incoming/5d/jmg_9619.jpg | 1 +
+ incoming/5d/jmg_9620.jpg | 1 +
+ incoming/5d/jmg_9621.jpg | 1 +
+ incoming/5d/jmg_9623.cr2 | 1 +
+ incoming/5d/jmg_9746.jpg | 1 +
+ incoming/5d/jmg_9763.cr2 | 1 +
+ incoming/5d/jmg_9763.jpg | 1 +
+ incoming/5d/jmg_9764.cr2 | 1 +
+ incoming/5d/jmg_9772.jpg | 1 +
+ incoming/5d/jmg_9773.jpg | 1 +
+ incoming/5d/jmg_9781.jpg | 1 +
+ incoming/5d/jmg_9790.jpg | 1 +
+ incoming/5d/jmg_9800.jpg | 1 +
+ incoming/5d/jmg_9808.jpg | 1 +
+ incoming/5d/jmg_9830.jpg | 1 +
+ incoming/5d/jmg_9834.cr2 | 1 +
+ incoming/5d/jmg_9843.jpg | 1 +
+ incoming/5d/jmg_9848.jpg | 1 +
+ incoming/5d/jmg_9849.jpg | 1 +
+ incoming/5d/jmg_9853.cr2 | 1 +
+ incoming/5d/jmg_9856.jpg | 1 +
+ incoming/5d/jmg_9857.cr2 | 1 +
+ incoming/5d/jmg_9859.cr2 | 1 +
+ incoming/5d/jmg_9860.jpg | 1 +
+ incoming/5d/jmg_9917.jpg | 1 +
+ incoming/5d/jmg_9923.jpg | 1 +
+ incoming/5d/jmg_9926.jpg | 1 +
+ incoming/5d/jmg_9975.cr2 | 1 +
+ incoming/5d/jmg_9976.cr2 | 1 +
+ incoming/5d/jmg_9978.jpg | 1 +
+ incoming/5d/jmg_9988.jpg | 1 +
+ incoming/5d/jmg_9997.cr2 | 1 +
+ incoming/5d/jmg_9998.jpg | 1 +
+ incoming/5d/jmg_9999.jpg | 1 +
+ list_5d_repoB | 1 -
+ only_on_repoB | 1 +
+ dir/2012/dir2/jmg_0128.cr2 | 1 -
+ dir/2012/dir2/jmg_0128.jpg | 1 -
+ dir/2012/dir2/jmg_0129.cr2 | 1 -
+ dir/2012/dir2/jmg_0129.jpg | 1 -
+ dir/2012/dir2/jmg_0353.jpg | 1 -
+ dir/2012/dir2/jmg_0354.jpg | 1 -
+ dir/2012/dir2/jmg_0375.jpg | 1 -
+ dir/2012/dir2/jmg_0376.jpg | 1 -
+ dir/2012/dir2/jmg_0378.jpg | 1 -
+ dir/2012/dir2/jmg_8707.cr2 | 1 -
+ dir/2012/dir2/jmg_8707.jpg | 1 -
+ dir/2012/dir2/jmg_8727.cr2 | 1 -
+ dir/2012/dir2/jmg_8727.jpg | 1 -
+ dir/2012/dir2/jmg_8728.cr2 | 1 -
+ dir/2012/dir2/jmg_8728.jpg | 1 -
+ dir/2012/dir2/jmg_8729.cr2 | 1 -
+ dir/2012/dir2/jmg_8729.jpg | 1 -
+ dir/2012/dir2/jmg_8740.cr2 | 1 -
+ dir/2012/dir2/jmg_8740.jpg | 1 -
+ dir/2012/dir2/jmg_8742.cr2 | 1 -
+ dir/2012/dir2/jmg_8742.jpg | 1 -
+ dir/2012/dir2/jmg_8825.cr2 | 1 -
+ dir/2012/dir2/jmg_8825.jpg | 1 -
+ dir/2012/dir2/jmg_8991.cr2 | 1 -
+ dir/2012/dir2/jmg_8991.jpg | 1 -
+ dir/2012/dir2/jmg_8992.cr2 | 1 -
+ dir/2012/dir2/jmg_8992.jpg | 1 -
+ dir/2012/dir2/jmg_8993.cr2 | 1 -
+ dir/2012/dir2/jmg_8993.jpg | 1 -
+ dir/2012/dir2/jmg_9059.cr2 | 1 -
+ dir/2012/dir2/jmg_9059.jpg | 1 -
+ dir/2012/dir2/jmg_9060.cr2 | 1 -
+ dir/2012/dir2/jmg_9060.jpg | 1 -
+ dir/2012/dir2/jmg_9064.cr2 | 1 -
+ dir/2012/dir2/jmg_9064.jpg | 1 -
+ dir/2012/dir2/jmg_9065.cr2 | 1 -
+ dir/2012/dir2/jmg_9065.jpg | 1 -
+ dir/2012/dir2/jmg_9081.cr2 | 1 -
+ dir/2012/dir2/jmg_9081.jpg | 1 -
+ dir/2012/dir2/jmg_9082.cr2 | 1 -
+ dir/2012/dir2/jmg_9082.jpg | 1 -
+ dir/2012/dir2/jmg_9083.cr2 | 1 -
+ dir/2012/dir2/jmg_9083.jpg | 1 -
+ dir/2012/dir1/jmg_0132.cr2 | 1 -
+ dir/2012/dir1/jmg_0132.jpg | 1 -
+ dir/2012/dir1/jmg_0133.cr2 | 1 -
+ dir/2012/dir1/jmg_0133.jpg | 1 -
+ dir/2012/dir1/jmg_0347.jpg | 1 -
+ dir/2012/dir1/jmg_0351.jpg | 1 -
+ dir/2012/dir1/jmg_0352.jpg | 1 -
+ dir/2012/dir1/jmg_0374.jpg | 1 -
+ dir/2012/dir1/jmg_8714.cr2 | 1 -
+ dir/2012/dir1/jmg_8714.jpg | 1 -
+ dir/2012/dir1/jmg_8716.cr2 | 1 -
+ dir/2012/dir1/jmg_8716.jpg | 1 -
+ dir/2012/dir1/jmg_8734.cr2 | 1 -
+ dir/2012/dir1/jmg_8734.jpg | 1 -
+ dir/2012/dir1/jmg_8735.cr2 | 1 -
+ dir/2012/dir1/jmg_8735.jpg | 1 -
+ dir/2012/dir1/jmg_8736.cr2 | 1 -
+ dir/2012/dir1/jmg_8736.jpg | 1 -
+ dir/2012/dir1/jmg_8743.cr2 | 1 -
+ dir/2012/dir1/jmg_8743.jpg | 1 -
+ dir/2012/dir1/jmg_8746.cr2 | 1 -
+ dir/2012/dir1/jmg_8746.jpg | 1 -
+ dir/2012/dir1/jmg_8828.cr2 | 1 -
+ dir/2012/dir1/jmg_8828.jpg | 1 -
+ dir/2012/dir1/jmg_8984.cr2 | 1 -
+ dir/2012/dir1/jmg_8984.jpg | 1 -
+ dir/2012/dir1/jmg_8985.cr2 | 1 -
+ dir/2012/dir1/jmg_8985.jpg | 1 -
+ dir/2012/dir1/jmg_8986.cr2 | 1 -
+ dir/2012/dir1/jmg_8986.jpg | 1 -
+ dir/2012/dir1/jmg_8988.cr2 | 1 -
+ dir/2012/dir1/jmg_8988.jpg | 1 -
+ dir/2012/dir1/jmg_9057.cr2 | 1 -
+ dir/2012/dir1/jmg_9057.jpg | 1 -
+ dir/2012/dir1/jmg_9058.cr2 | 1 -
+ dir/2012/dir1/jmg_9058.jpg | 1 -
+ dir/2012/dir1/jmg_9086.cr2 | 1 -
+ dir/2012/dir1/jmg_9086.jpg | 1 -
+ dir/2012/dir1/jmg_9087.cr2 | 1 -
+ dir/2012/dir1/jmg_9087.jpg | 1 -
+ dir/2013/dir2/jmg_0477.cr2 | 1 -
+ dir/2013/dir2/jmg_0477.jpg | 1 -
+ dir/2013/dir2/jmg_0478.cr2 | 1 -
+ dir/2013/dir2/jmg_0478.jpg | 1 -
+ dir/2013/dir2/jmg_0479.cr2 | 1 -
+ dir/2013/dir2/jmg_0479.jpg | 1 -
+ dir/2013/dir2/jmg_0604.cr2 | 1 -
+ dir/2013/dir2/jmg_0604.jpg | 1 -
+ dir/2013/dir2/jmg_0605.cr2 | 1 -
+ dir/2013/dir2/jmg_0605.jpg | 1 -
+ dir/2013/dir2/jmg_0606.cr2 | 1 -
+ dir/2013/dir2/jmg_0606.jpg | 1 -
+ dir/2013/dir2/jmg_0607.cr2 | 1 -
+ dir/2013/dir2/jmg_0607.jpg | 1 -
+ dir/2013/dir2/jmg_0608.cr2 | 1 -
+ dir/2013/dir2/jmg_0608.jpg | 1 -
+ dir/2013/dir2/jmg_0708.cr2 | 1 -
+ dir/2013/dir2/jmg_0708.jpg | 1 -
+ dir/2013/dir2/jmg_0709.cr2 | 1 -
+ dir/2013/dir2/jmg_0709.jpg | 1 -
+ dir/2013/dir2/jmg_0710.cr2 | 1 -
+ dir/2013/dir2/jmg_0710.jpg | 1 -
+ dir/2013/dir1/jmg_0475.cr2 | 1 -
+ dir/2013/dir1/jmg_0475.jpg | 1 -
+ dir/2013/dir1/jmg_0476.cr2 | 1 -
+ dir/2013/dir1/jmg_0476.jpg | 1 -
+ dir/2013/dir1/jmg_0718.cr2 | 1 -
+ dir/2013/dir1/jmg_0718.jpg | 1 -
+ dir/2013/dir1/jmg_0719.cr2 | 1 -
+ dir/2013/dir1/jmg_0719.jpg | 1 -
+ 1821 files changed, 628 insertions(+), 1231 deletions(-)
+ delete mode 120000 201109/jmg_7250.cr2
+ delete mode 120000 201109/jmg_7250.jpg
+ delete mode 120000 201109/jmg_7251.cr2
+ delete mode 120000 201109/jmg_7251.jpg
+ delete mode 120000 201109/jmg_7253.cr2
+ delete mode 120000 201109/jmg_7253.jpg
+ delete mode 120000 201109/jmg_7256_raw.jpg
+ delete mode 120000 201109/jmg_7259.cr2
+ delete mode 120000 201109/jmg_7259.jpg
+ delete mode 120000 201109/jmg_7261.cr2
+ delete mode 120000 201109/jmg_7261.jpg
+ delete mode 120000 201109/jmg_7265.cr2
+ delete mode 120000 201109/jmg_7265.jpg
+ delete mode 120000 201109/jmg_7272.jpg
+ delete mode 120000 201109/jmg_7274.jpg
+ delete mode 120000 201109/jmg_7275.jpg
+ delete mode 120000 201109/jmg_7276.jpg
+ delete mode 120000 201109/jmg_7280.jpg
+ delete mode 120000 201109/jmg_7284.jpg
+ delete mode 120000 201109/jmg_7286.jpg
+ delete mode 120000 201109/jmg_7288.jpg
+ delete mode 120000 201109/jmg_7289.jpg
+ delete mode 120000 201109/jmg_7292.jpg
+ delete mode 120000 201109/jmg_7293.jpg
+ delete mode 120000 201109/jmg_7295.cr2
+ delete mode 120000 201109/jmg_7295.jpg
+ delete mode 120000 201109/jmg_7296.cr2
+ delete mode 120000 201109/jmg_7296.jpg
+ delete mode 120000 201109/jmg_7299.cr2
+ delete mode 120000 201109/jmg_7299.jpg
+ delete mode 120000 201109/jmg_7300.cr2
+ delete mode 120000 201109/jmg_7300.jpg
+ delete mode 120000 201109/jmg_7304.jpg
+ delete mode 120000 201109/jmg_7305_raw.jpg
+ delete mode 120000 201109/jmg_7307_raw.jpg
+ delete mode 120000 201202/jmg_8528.jpg
+ delete mode 120000 201202/jmg_8529.jpg
+ delete mode 120000 201202/jmg_8595.jpg
+ delete mode 120000 201202/jmg_8596.jpg
+ delete mode 120000 201202/jmg_8597.jpg
+ delete mode 120000 201202/jmg_8601.jpg
+ delete mode 120000 201202/jmg_8602.cr2
+ delete mode 120000 201202/jmg_8602.jpg
+ delete mode 120000 201202/jmg_8603.cr2
+ delete mode 120000 201202/jmg_8603.jpg
+ delete mode 120000 201202/jmg_8604.jpg
+ delete mode 120000 201202/jmg_8605.jpg
+ delete mode 120000 201202/jmg_8606.jpg
+ delete mode 120000 201202/jmg_8607.jpg
+ delete mode 120000 201202/jmg_8608.jpg
+ delete mode 120000 201202/jmg_8609.jpg
+ delete mode 120000 201202/jmg_8610.jpg
+ delete mode 120000 201202/jmg_8611.jpg
+ delete mode 120000 201202/jmg_8612.cr2
+ delete mode 120000 201202/jmg_8612.jpg
+ delete mode 120000 201202/jmg_8613.jpg
+ delete mode 120000 201202/jmg_8614.jpg
+ delete mode 120000 201202/jmg_8615.jpg
+ delete mode 120000 201202/jmg_8616_raw.jpg
+ delete mode 120000 201202/jmg_8617.jpg
+ delete mode 120000 201202/jmg_8618.jpg
+ delete mode 120000 201202/jmg_8619.jpg
+ delete mode 120000 201202/jmg_8620.jpg
+ delete mode 120000 201202/jmg_8621.jpg
+ delete mode 120000 201202/jmg_8622.jpg
+ delete mode 120000 201202/jmg_8624.jpg
+ delete mode 120000 201202/jmg_8625.cr2
+ delete mode 120000 201202/jmg_8625.jpg
+ delete mode 120000 201202/jmg_8626.jpg
+ delete mode 120000 201202/jmg_8627.jpg
+ delete mode 120000 201202/jmg_8628.jpg
+ delete mode 120000 201202/jmg_8629.jpg
+ delete mode 120000 201202/jmg_8630.jpg
+ delete mode 120000 201202/jmg_8631.jpg
+ delete mode 120000 201202/jmg_8632.jpg
+ delete mode 120000 201202/jmg_8633.cr2
+ delete mode 120000 201202/jmg_8633.jpg
+ delete mode 120000 201202/jmg_8634.jpg
+ delete mode 120000 201202/jmg_8637.jpg
+ delete mode 120000 201202/jmg_8639.jpg
+ delete mode 120000 201202/jmg_8640.jpg
+ delete mode 120000 201202/jmg_8641.jpg
+ delete mode 120000 201202/jmg_8642_raw.jpg
+ delete mode 120000 201202/jmg_8643.jpg
+ delete mode 120000 201202/jmg_8644.jpg
+ delete mode 120000 201202/jmg_8647.jpg
+ delete mode 120000 201202/jmg_8648.jpg
+ delete mode 120000 201202/jmg_8651.cr2
+ delete mode 120000 201202/jmg_8651.jpg
+ delete mode 120000 201202/jmg_8652.jpg
+ delete mode 120000 201202/jmg_8653.jpg
+ delete mode 120000 201202/jmg_8654.jpg
+ delete mode 120000 201202/jmg_8655.jpg
+ delete mode 120000 201202/jmg_8657.jpg
+ delete mode 120000 201202/jmg_8665.jpg
+ delete mode 120000 201202/jmg_8670.jpg
+ delete mode 120000 201202/jmg_8671.jpg
+ delete mode 120000 201202/jmg_8673.cr2
+ delete mode 120000 201202/jmg_8673.jpg
+ delete mode 120000 201202/jmg_8674.jpg
+ delete mode 120000 201202/jmg_8675.jpg
+ delete mode 120000 201202/jmg_8676.jpg
+ delete mode 120000 201202/jmg_8677.jpg
+ delete mode 120000 201202/jmg_8678.jpg
+ delete mode 120000 201202/jmg_8679.jpg
+ delete mode 120000 201202/jmg_8680.jpg
+ delete mode 120000 201202/jmg_8681.jpg
+ delete mode 120000 201203/jmg_8701.cr2
+ delete mode 120000 201203/jmg_8702.jpg
+ delete mode 120000 201203/jmg_8705.jpg
+ delete mode 120000 201203/jmg_8711.jpg
+ delete mode 120000 201203/jmg_8717.jpg
+ delete mode 120000 201203/jmg_8718.jpg
+ delete mode 120000 201203/jmg_8719.jpg
+ delete mode 120000 201203/jmg_8721.jpg
+ delete mode 120000 201203/jmg_8725.jpg
+ delete mode 120000 201203/jmg_8726.jpg
+ delete mode 120000 201203/jmg_8731.jpg
+ delete mode 120000 201203/jmg_8739.jpg
+ delete mode 120000 201203/jmg_8745.jpg
+ delete mode 120000 201203/jmg_8747_raw.jpg
+ delete mode 120000 201203/jmg_8750.cr2
+ delete mode 120000 201203/jmg_8750.jpg
+ delete mode 120000 201204/jmg_8751.jpg
+ delete mode 120000 201204/jmg_8752.jpg
+ delete mode 120000 201204/jmg_8755.jpg
+ delete mode 120000 201204/jmg_8756.jpg
+ delete mode 120000 201204/jmg_8757.jpg
+ delete mode 120000 201204/jmg_8759.jpg
+ delete mode 120000 201204/jmg_8760.jpg
+ delete mode 120000 201204/jmg_8761.jpg
+ delete mode 120000 201204/jmg_8762.jpg
+ delete mode 120000 201204/jmg_8763.cr2
+ delete mode 120000 201204/jmg_8763.jpg
+ delete mode 120000 201204/jmg_8766.jpg
+ delete mode 120000 201204/jmg_8767.cr2
+ delete mode 120000 201204/jmg_8767.jpg
+ delete mode 120000 201204/jmg_8768.jpg
+ delete mode 120000 201204/jmg_8769.jpg
+ delete mode 120000 201204/jmg_8770.jpg
+ delete mode 120000 201204/jmg_8771.jpg
+ delete mode 120000 201204/jmg_8772.jpg
+ delete mode 120000 201204/jmg_8773.jpg
+ delete mode 120000 201205/jmg_8822.jpg
+ delete mode 120000 201205/jmg_8823.jpg
+ delete mode 120000 201205/jmg_8824.jpg
+ delete mode 120000 201205/jmg_8826.jpg
+ delete mode 120000 201205/jmg_8831.jpg
+ delete mode 120000 201205/jmg_8834.jpg
+ delete mode 120000 201205/jmg_8835.jpg
+ delete mode 120000 201205/jmg_8835_raw.jpg
+ delete mode 120000 201205/jmg_8837.jpg
+ delete mode 120000 201205/jmg_8839.cr2
+ delete mode 120000 201205/jmg_8839.jpg
+ delete mode 120000 201205/jmg_8839_raw.jpg
+ delete mode 120000 201205/jmg_8840.cr2
+ delete mode 120000 201205/jmg_8840.jpg
+ delete mode 120000 201205/jmg_8840_raw.jpg
+ delete mode 120000 201205/jmg_8841.jpg
+ delete mode 120000 201205/jmg_8842.jpg
+ delete mode 120000 201205/jmg_8844.cr2
+ delete mode 120000 201205/jmg_8844.jpg
+ delete mode 120000 201205/jmg_8844_raw.jpg
+ delete mode 120000 201205/jmg_8845.jpg
+ delete mode 120000 201205/jmg_8846.jpg
+ delete mode 120000 201205/jmg_8847.cr2
+ delete mode 120000 201205/jmg_8847.jpg
+ delete mode 120000 201205/jmg_8847_raw.jpg
+ delete mode 120000 201205/jmg_8848.jpg
+ delete mode 120000 201205/jmg_8849.jpg
+ delete mode 120000 201205/jmg_8851.cr2
+ delete mode 120000 201205/jmg_8851.jpg
+ delete mode 120000 201205/jmg_8851_raw.jpg
+ delete mode 120000 201205/jmg_8856.cr2
+ delete mode 120000 201205/jmg_8856.jpg
+ delete mode 120000 201205/jmg_8856_raw.jpg
+ delete mode 120000 201205/jmg_8857.jpg
+ delete mode 120000 201205/jmg_8858.jpg
+ delete mode 120000 201205/jmg_8859.jpg
+ delete mode 120000 201205/jmg_8861.jpg
+ delete mode 120000 201205/jmg_8862.jpg
+ delete mode 120000 201205/jmg_8863.jpg
+ delete mode 120000 201205/jmg_8871.cr2
+ delete mode 120000 201205/jmg_8871.jpg
+ delete mode 120000 201205/jmg_8872.jpg
+ delete mode 120000 201205/jmg_8873.jpg
+ delete mode 120000 201205/jmg_8875.jpg
+ delete mode 120000 201205/jmg_8876.cr2
+ delete mode 120000 201205/jmg_8876.jpg
+ delete mode 120000 201205/jmg_8878.cr2
+ delete mode 120000 201205/jmg_8878.jpg
+ delete mode 120000 201205/jmg_8879.cr2
+ delete mode 120000 201205/jmg_8879.jpg
+ delete mode 120000 201205/jmg_8880.cr2
+ delete mode 120000 201205/jmg_8880.jpg
+ delete mode 120000 201205/jmg_8881.cr2
+ delete mode 120000 201205/jmg_8881.jpg
+ delete mode 120000 201205/jmg_8892.cr2
+ delete mode 120000 201205/jmg_8892.jpg
+ delete mode 120000 201205/jmg_8893.cr2
+ delete mode 120000 201205/jmg_8893.jpg
+ delete mode 120000 201205/jmg_8894.cr2
+ delete mode 120000 201205/jmg_8894.jpg
+ delete mode 120000 201206/jmg_8989.cr2
+ delete mode 120000 201206/jmg_8989.jpg
+ delete mode 120000 201206/jmg_8990.cr2
+ delete mode 120000 201206/jmg_8990.jpg
+ delete mode 120000 201206/jmg_8995.jpg
+ delete mode 120000 201206/jmg_8996.jpg
+ delete mode 120000 201206/jmg_8998.jpg
+ delete mode 120000 201206/jmg_9001.jpg
+ delete mode 120000 201206/jmg_9003.jpg
+ delete mode 120000 201206/jmg_9006.jpg
+ delete mode 120000 201206/jmg_9007.jpg
+ delete mode 120000 201206/jmg_9011.jpg
+ delete mode 120000 201206/jmg_9014.jpg
+ delete mode 120000 201206/jmg_9014_raw.jpg
+ delete mode 120000 201206/jmg_9015.jpg
+ delete mode 120000 201206/jmg_9016.cr2
+ delete mode 120000 201206/jmg_9016.jpg
+ delete mode 120000 201206/jmg_9017.cr2
+ delete mode 120000 201206/jmg_9017.jpg
+ delete mode 120000 201206/jmg_9018.cr2
+ delete mode 120000 201206/jmg_9018.jpg
+ delete mode 120000 201206/jmg_9019.cr2
+ delete mode 120000 201206/jmg_9019.jpg
+ delete mode 120000 201206/jmg_9023.cr2
+ delete mode 120000 201206/jmg_9023.jpg
+ delete mode 120000 201206/jmg_9024.cr2
+ delete mode 120000 201206/jmg_9024.jpg
+ delete mode 120000 201206/jmg_9025.cr2
+ delete mode 120000 201206/jmg_9025.jpg
+ delete mode 120000 201206/jmg_9028.jpg
+ delete mode 120000 201206/jmg_9029.jpg
+ delete mode 120000 201206/jmg_9030.jpg
+ delete mode 120000 201206/jmg_9031.jpg
+ delete mode 120000 201206/jmg_9032_raw.jpg
+ delete mode 120000 201206/jmg_9033.jpg
+ delete mode 120000 201206/jmg_9033_raw.jpg
+ delete mode 120000 201206/jmg_9034.jpg
+ delete mode 120000 201206/jmg_9035.jpg
+ delete mode 120000 201206/jmg_9035_raw.jpg
+ delete mode 120000 201206/jmg_9036.jpg
+ delete mode 120000 201206/jmg_9039.cr2
+ delete mode 120000 201206/jmg_9039.jpg
+ delete mode 120000 201206/jmg_9040.cr2
+ delete mode 120000 201206/jmg_9040.jpg
+ delete mode 120000 201206/jmg_9043.cr2
+ delete mode 120000 201206/jmg_9043.jpg
+ delete mode 120000 201206/jmg_9047.cr2
+ delete mode 120000 201206/jmg_9047.jpg
+ delete mode 120000 201207/jmg_9048.jpg
+ delete mode 120000 201207/jmg_9053.jpg
+ delete mode 120000 201207/jmg_9054.jpg
+ delete mode 120000 201207/jmg_9069.cr2
+ delete mode 120000 201207/jmg_9069.jpg
+ delete mode 120000 201207/jmg_9070.cr2
+ delete mode 120000 201207/jmg_9070.jpg
+ delete mode 120000 201207/jmg_9072.cr2
+ delete mode 120000 201207/jmg_9072.jpg
+ delete mode 120000 201207/jmg_9076.cr2
+ delete mode 120000 201207/jmg_9076.jpg
+ delete mode 120000 201208/jmg_9077.jpg
+ delete mode 120000 201208/jmg_9302_raw.jpg
+ delete mode 120000 201208/jmg_9303.jpg
+ delete mode 120000 201208/jmg_9304.cr2
+ delete mode 120000 201208/jmg_9304.jpg
+ delete mode 120000 201208/jmg_9305.cr2
+ delete mode 120000 201208/jmg_9305.jpg
+ delete mode 120000 201208/jmg_9306_raw.jpg
+ delete mode 120000 201208/jmg_9307.cr2
+ delete mode 120000 201208/jmg_9307.jpg
+ delete mode 120000 201208/jmg_9308_raw.jpg
+ delete mode 120000 201208/jmg_9309_raw.jpg
+ delete mode 120000 201208/jmg_9310.cr2
+ delete mode 120000 201208/jmg_9310.jpg
+ delete mode 120000 201208/jmg_9310_bw.jpg
+ delete mode 120000 201208/jmg_9310_raw.jpg
+ delete mode 120000 201208/jmg_9312.jpg
+ delete mode 120000 201208/jmg_9313.jpg
+ delete mode 120000 201208/jmg_9314.jpg
+ delete mode 120000 201208/jmg_9315.jpg
+ delete mode 120000 201208/jmg_9319.jpg
+ delete mode 120000 201208/jmg_9523.jpg
+ delete mode 120000 201208/jmg_9524.jpg
+ delete mode 120000 201208/jmg_9525.jpg
+ delete mode 120000 201208/jmg_9526.jpg
+ delete mode 120000 201208/jmg_9527.jpg
+ delete mode 120000 201208/jmg_9527_raw.jpg
+ delete mode 120000 201208/jmg_9528.jpg
+ delete mode 120000 201208/jmg_9529.jpg
+ delete mode 120000 201208/jmg_9530.jpg
+ delete mode 120000 201208/jmg_9531.jpg
+ delete mode 120000 201208/jmg_9532.jpg
+ delete mode 120000 201208/jmg_9533.cr2
+ delete mode 120000 201208/jmg_9533.jpg
+ delete mode 120000 201208/jmg_9534.cr2
+ delete mode 120000 201208/jmg_9534.jpg
+ delete mode 120000 201208/jmg_9535.jpg
+ delete mode 120000 201208/jmg_9536.jpg
+ delete mode 120000 201208/jmg_9537.cr2
+ delete mode 120000 201208/jmg_9537.jpg
+ delete mode 120000 201208/jmg_9538.jpg
+ delete mode 120000 201208/jmg_9539.jpg
+ delete mode 120000 201208/jmg_9540.jpg
+ delete mode 120000 201208/jmg_9541.cr2
+ delete mode 120000 201208/jmg_9542.jpg
+ delete mode 120000 201208/jmg_9543.cr2
+ delete mode 120000 201208/jmg_9543.jpg
+ delete mode 120000 201208/jmg_9544.cr2
+ delete mode 120000 201208/jmg_9544.jpg
+ delete mode 120000 201208/jmg_9545.jpg
+ delete mode 120000 201209/jmg_9547.jpg
+ delete mode 120000 201209/jmg_9548.jpg
+ delete mode 120000 201209/jmg_9549.jpg
+ delete mode 120000 201209/jmg_9550.jpg
+ delete mode 120000 201209/jmg_9551.jpg
+ delete mode 120000 201209/jmg_9552.jpg
+ delete mode 120000 201209/jmg_9553.jpg
+ delete mode 120000 201209/jmg_9555.jpg
+ delete mode 120000 201209/jmg_9556.jpg
+ delete mode 120000 201209/jmg_9558.jpg
+ delete mode 120000 201209/jmg_9559.cr2
+ delete mode 120000 201209/jmg_9559.jpg
+ delete mode 120000 201209/jmg_9560.cr2
+ delete mode 120000 201209/jmg_9560.jpg
+ delete mode 120000 201209/jmg_9561.jpg
+ delete mode 120000 201209/jmg_9562.jpg
+ delete mode 120000 201209/jmg_9568.jpg
+ delete mode 120000 201210/jmg_0001.jpg
+ delete mode 120000 201210/jmg_0021.jpg
+ delete mode 120000 201210/jmg_0022.cr2
+ delete mode 120000 201210/jmg_0022.jpg
+ delete mode 120000 201210/jmg_0025.jpg
+ delete mode 120000 201210/jmg_0026.jpg
+ delete mode 120000 201210/jmg_0027.jpg
+ delete mode 120000 201210/jmg_0028.jpg
+ delete mode 120000 201210/jmg_0029.jpg
+ delete mode 120000 201210/jmg_0030.jpg
+ delete mode 120000 201210/jmg_0032.jpg
+ delete mode 120000 201210/jmg_0034.jpg
+ delete mode 120000 201210/jmg_0035.jpg
+ delete mode 120000 201210/jmg_0036.jpg
+ delete mode 120000 201210/jmg_0037.jpg
+ delete mode 120000 201210/jmg_0039.cr2
+ delete mode 120000 201210/jmg_0039.jpg
+ delete mode 120000 201210/jmg_0040.jpg
+ delete mode 120000 201210/jmg_9572.jpg
+ delete mode 120000 201210/jmg_9573.jpg
+ delete mode 120000 201210/jmg_9574.jpg
+ delete mode 120000 201210/jmg_9575.jpg
+ delete mode 120000 201210/jmg_9576.jpg
+ delete mode 120000 201210/jmg_9578.jpg
+ delete mode 120000 201210/jmg_9580.jpg
+ delete mode 120000 201210/jmg_9581.jpg
+ delete mode 120000 201210/jmg_9582.cr2
+ delete mode 120000 201210/jmg_9582.jpg
+ delete mode 120000 201210/jmg_9585.cr2
+ delete mode 120000 201210/jmg_9585.jpg
+ delete mode 120000 201210/jmg_9587.cr2
+ delete mode 120000 201210/jmg_9587.jpg
+ delete mode 120000 201210/jmg_9588.jpg
+ delete mode 120000 201210/jmg_9589.jpg
+ delete mode 120000 201210/jmg_9590.jpg
+ delete mode 120000 201210/jmg_9591.jpg
+ delete mode 120000 201210/jmg_9594.jpg
+ delete mode 120000 201210/jmg_9595.jpg
+ delete mode 120000 201210/jmg_9596.jpg
+ delete mode 120000 201210/jmg_9597.cr2
+ delete mode 120000 201210/jmg_9597.jpg
+ delete mode 120000 201210/jmg_9598.cr2
+ delete mode 120000 201210/jmg_9598.jpg
+ delete mode 120000 201210/jmg_9599.cr2
+ delete mode 120000 201210/jmg_9599.jpg
+ delete mode 120000 201210/jmg_9600.jpg
+ delete mode 120000 201210/jmg_9602.jpg
+ delete mode 120000 201210/jmg_9603.jpg
+ delete mode 120000 201210/jmg_9604.jpg
+ delete mode 120000 201210/jmg_9605.cr2
+ delete mode 120000 201210/jmg_9605.jpg
+ delete mode 120000 201210/jmg_9606.jpg
+ delete mode 120000 201210/jmg_9608.jpg
+ delete mode 120000 201210/jmg_9609.jpg
+ delete mode 120000 201210/jmg_9610.jpg
+ delete mode 120000 201210/jmg_9611.jpg
+ delete mode 120000 201210/jmg_9612.jpg
+ delete mode 120000 201210/jmg_9613.jpg
+ delete mode 120000 201210/jmg_9614.jpg
+ delete mode 120000 201210/jmg_9616.cr2
+ delete mode 120000 201210/jmg_9616.jpg
+ delete mode 120000 201210/jmg_9617.jpg
+ delete mode 120000 201210/jmg_9619.jpg
+ delete mode 120000 201210/jmg_9620.jpg
+ delete mode 120000 201210/jmg_9621.jpg
+ delete mode 120000 201210/jmg_9622.jpg
+ delete mode 120000 201210/jmg_9623.cr2
+ delete mode 120000 201210/jmg_9623.jpg
+ delete mode 120000 201210/jmg_9624.cr2
+ delete mode 120000 201210/jmg_9624.jpg
+ delete mode 120000 201210/jmg_9736_raw.jpg
+ delete mode 120000 201210/jmg_9738_raw.jpg
+ delete mode 120000 201210/jmg_9740.cr2
+ delete mode 120000 201210/jmg_9740.jpg
+ delete mode 120000 201210/jmg_9743.jpg
+ delete mode 120000 201210/jmg_9744.jpg
+ delete mode 120000 201210/jmg_9745.cr2
+ delete mode 120000 201210/jmg_9745.jpg
+ delete mode 120000 201210/jmg_9746.cr2
+ delete mode 120000 201210/jmg_9746.jpg
+ delete mode 120000 201210/jmg_9748.jpg
+ delete mode 120000 201210/jmg_9749_raw.jpg
+ delete mode 120000 201210/jmg_9751.jpg
+ delete mode 120000 201210/jmg_9752.jpg
+ delete mode 120000 201210/jmg_9754.jpg
+ delete mode 120000 201210/jmg_9755.jpg
+ delete mode 120000 201210/jmg_9756.jpg
+ delete mode 120000 201210/jmg_9760.cr2
+ delete mode 120000 201210/jmg_9760.jpg
+ delete mode 120000 201210/jmg_9761.cr2
+ delete mode 120000 201210/jmg_9761.jpg
+ delete mode 120000 201210/jmg_9763.jpg
+ delete mode 120000 201210/jmg_9764.jpg
+ delete mode 120000 201210/jmg_9766.jpg
+ delete mode 120000 201210/jmg_9767.cr2
+ delete mode 120000 201210/jmg_9767.jpg
+ delete mode 120000 201210/jmg_9768.jpg
+ delete mode 120000 201210/jmg_9771.jpg
+ delete mode 120000 201210/jmg_9772.jpg
+ delete mode 120000 201210/jmg_9791.jpg
+ delete mode 120000 201210/jmg_9792.jpg
+ delete mode 120000 201210/jmg_9793.jpg
+ delete mode 120000 201210/jmg_9794.jpg
+ delete mode 120000 201210/jmg_9796.jpg
+ delete mode 120000 201210/jmg_9797.jpg
+ delete mode 120000 201210/jmg_9799.jpg
+ delete mode 120000 201210/jmg_9800.jpg
+ delete mode 120000 201210/jmg_9801.jpg
+ delete mode 120000 201210/jmg_9803.jpg
+ delete mode 120000 201210/jmg_9807.jpg
+ delete mode 120000 201210/jmg_9808.jpg
+ delete mode 120000 201210/jmg_9809.jpg
+ delete mode 120000 201210/jmg_9810.jpg
+ delete mode 120000 201210/jmg_9811.jpg
+ delete mode 120000 201210/jmg_9812.jpg
+ delete mode 120000 201210/jmg_9813.jpg
+ delete mode 120000 201210/jmg_9815.jpg
+ delete mode 120000 201210/jmg_9818.jpg
+ delete mode 120000 201210/jmg_9819.jpg
+ delete mode 120000 201210/jmg_9820.jpg
+ delete mode 120000 201210/jmg_9821.jpg
+ delete mode 120000 201210/jmg_9822.jpg
+ delete mode 120000 201210/jmg_9823.jpg
+ delete mode 120000 201210/jmg_9825.jpg
+ delete mode 120000 201210/jmg_9826.jpg
+ delete mode 120000 201210/jmg_9827.jpg
+ delete mode 120000 201210/jmg_9828.jpg
+ delete mode 120000 201210/jmg_9829.jpg
+ delete mode 120000 201210/jmg_9830.cr2
+ delete mode 120000 201210/jmg_9830.jpg
+ delete mode 120000 201210/jmg_9832.cr2
+ delete mode 120000 201210/jmg_9832.jpg
+ delete mode 120000 201210/jmg_9834.jpg
+ delete mode 120000 201210/jmg_9836.jpg
+ delete mode 120000 201210/jmg_9838.jpg
+ delete mode 120000 201210/jmg_9839.jpg
+ delete mode 120000 201210/jmg_9841.jpg
+ delete mode 120000 201210/jmg_9843.jpg
+ delete mode 120000 201210/jmg_9845.jpg
+ delete mode 120000 201210/jmg_9846.jpg
+ delete mode 120000 201210/jmg_9848.jpg
+ delete mode 120000 201210/jmg_9849.jpg
+ delete mode 120000 201210/jmg_9852.jpg
+ delete mode 120000 201210/jmg_9853.jpg
+ delete mode 120000 201210/jmg_9854.jpg
+ delete mode 120000 201210/jmg_9855.jpg
+ delete mode 120000 201210/jmg_9856.jpg
+ delete mode 120000 201210/jmg_9857.cr2
+ delete mode 120000 201210/jmg_9857.jpg
+ delete mode 120000 201210/jmg_9858.cr2
+ delete mode 120000 201210/jmg_9858.jpg
+ delete mode 120000 201210/jmg_9859.jpg
+ delete mode 120000 201210/jmg_9860.jpg
+ delete mode 120000 201210/jmg_9915.jpg
+ delete mode 120000 201210/jmg_9917.jpg
+ delete mode 120000 201210/jmg_9918.jpg
+ delete mode 120000 201210/jmg_9919.jpg
+ delete mode 120000 201210/jmg_9922.jpg
+ delete mode 120000 201210/jmg_9923.jpg
+ delete mode 120000 201210/jmg_9925.jpg
+ delete mode 120000 201210/jmg_9926.cr2
+ delete mode 120000 201210/jmg_9926.jpg
+ delete mode 120000 201210/jmg_9928.jpg
+ delete mode 120000 201210/jmg_9975.cr2
+ delete mode 120000 201210/jmg_9975.jpg
+ delete mode 120000 201210/jmg_9976.cr2
+ delete mode 120000 201210/jmg_9976.jpg
+ delete mode 120000 201210/jmg_9978.jpg
+ delete mode 120000 201210/jmg_9986.jpg
+ delete mode 120000 201210/jmg_9987.jpg
+ delete mode 120000 201210/jmg_9988.jpg
+ delete mode 120000 201210/jmg_9989.jpg
+ delete mode 120000 201210/jmg_9991.jpg
+ delete mode 120000 201210/jmg_9993.jpg
+ delete mode 120000 201210/jmg_9994.cr2
+ delete mode 120000 201210/jmg_9994.jpg
+ delete mode 120000 201210/jmg_9997.jpg
+ delete mode 120000 201210/jmg_9998.jpg
+ delete mode 120000 201210/jmg_9999.jpg
+ delete mode 120000 201212/jmg_0131.jpg
+ delete mode 120000 201212/jmg_0134.jpg
+ delete mode 120000 201212/jmg_0135.jpg
+ delete mode 120000 201212/jmg_0152.jpg
+ delete mode 120000 201212/jmg_0155.jpg
+ delete mode 120000 201212/jmg_0156.jpg
+ delete mode 120000 201212/jmg_0162.jpg
+ delete mode 120000 201212/jmg_0163.jpg
+ delete mode 120000 201212/jmg_0165.jpg
+ delete mode 120000 201212/jmg_0176.cr2
+ delete mode 120000 201212/jmg_0176.jpg
+ delete mode 120000 201212/jmg_0177.cr2
+ delete mode 120000 201212/jmg_0177.jpg
+ delete mode 120000 201212/jmg_0178.jpg
+ delete mode 120000 201212/jmg_0179.jpg
+ delete mode 120000 201212/jmg_0180.jpg
+ delete mode 120000 201212/jmg_0184.jpg
+ delete mode 120000 201212/jmg_0185.jpg
+ delete mode 120000 201212/jmg_0186.jpg
+ delete mode 120000 201212/jmg_0187.jpg
+ delete mode 120000 201212/jmg_0306.jpg
+ delete mode 120000 201212/jmg_0307.jpg
+ delete mode 120000 201212/jmg_0308.jpg
+ delete mode 120000 201212/jmg_0310.jpg
+ delete mode 120000 201212/jmg_0311.jpg
+ delete mode 120000 201212/jmg_0312.jpg
+ delete mode 120000 201212/jmg_0313.jpg
+ delete mode 120000 201212/jmg_0314.jpg
+ delete mode 120000 201212/jmg_0315.jpg
+ delete mode 120000 201212/jmg_0316.jpg
+ delete mode 120000 201212/jmg_0317.jpg
+ delete mode 120000 201212/jmg_0321.jpg
+ delete mode 120000 201212/jmg_0326.jpg
+ delete mode 120000 201212/jmg_0328.jpg
+ delete mode 120000 201212/jmg_0330.jpg
+ delete mode 120000 201212/jmg_0333.jpg
+ delete mode 120000 201212/jmg_0336.jpg
+ delete mode 120000 201212/jmg_0340.jpg
+ delete mode 120000 201212/jmg_0343.jpg
+ delete mode 120000 201212/jmg_0345.jpg
+ delete mode 120000 201212/jmg_0360.jpg
+ delete mode 120000 201212/jmg_0362.jpg
+ delete mode 120000 201212/jmg_0363.jpg
+ delete mode 120000 201212/jmg_0364.jpg
+ delete mode 120000 201212/jmg_0366.jpg
+ delete mode 120000 201212/jmg_0367.jpg
+ delete mode 120000 201212/jmg_0368.jpg
+ delete mode 120000 201212/jmg_0369.jpg
+ delete mode 120000 201212/jmg_0370.jpg
+ delete mode 120000 201212/jmg_0372.jpg
+ delete mode 120000 201212/jmg_0382.jpg
+ delete mode 120000 201212/jmg_0383.jpg
+ delete mode 120000 201212/jmg_0384.jpg
+ delete mode 120000 201212/jmg_0385.jpg
+ delete mode 120000 201212/jmg_0387.jpg
+ delete mode 120000 201212/jmg_0388.jpg
+ delete mode 120000 201212/jmg_0389.jpg
+ delete mode 120000 201212/jmg_0390.jpg
+ delete mode 120000 201212/jmg_0392.jpg
+ delete mode 120000 201212/jmg_0396.jpg
+ delete mode 120000 201212/jmg_0397.jpg
+ delete mode 120000 201212/jmg_0398.jpg
+ delete mode 120000 201212/jmg_0399.jpg
+ delete mode 120000 201212/jmg_0402.jpg
+ delete mode 120000 201212/jmg_0404.jpg
+ delete mode 120000 201212/jmg_0405.jpg
+ delete mode 120000 201212/jmg_0406.jpg
+ delete mode 120000 201212/jmg_0407.jpg
+ delete mode 120000 201212/jmg_0408.jpg
+ delete mode 120000 201212/jmg_0410.jpg
+ delete mode 120000 201212/jmg_0411.jpg
+ delete mode 120000 201212/jmg_0412.jpg
+ delete mode 120000 201212/jmg_0415.jpg
+ delete mode 120000 201212/jmg_0417.jpg
+ delete mode 120000 201212/jmg_0418.jpg
+ delete mode 120000 201302/jmg_0502.cr2
+ delete mode 120000 201302/jmg_0502.jpg
+ delete mode 120000 201302/jmg_0503.jpg
+ delete mode 120000 201302/jmg_0507.jpg
+ delete mode 120000 201302/jmg_0510.jpg
+ delete mode 120000 201302/jmg_0512.jpg
+ delete mode 120000 201302/jmg_0513.jpg
+ delete mode 120000 201302/jmg_0514.jpg
+ delete mode 120000 201302/jmg_0516.jpg
+ delete mode 120000 201302/jmg_0517.jpg
+ delete mode 120000 201302/jmg_0518.jpg
+ delete mode 120000 201302/jmg_0521.jpg
+ delete mode 120000 201302/jmg_0522.jpg
+ delete mode 120000 201302/jmg_0523.jpg
+ delete mode 120000 201302/jmg_0524.jpg
+ delete mode 120000 201302/jmg_0526.jpg
+ delete mode 120000 201302/jmg_0527.jpg
+ delete mode 120000 201302/jmg_0528.jpg
+ delete mode 120000 201302/jmg_0532.cr2
+ delete mode 120000 201302/jmg_0532.jpg
+ delete mode 120000 201302/jmg_0534.jpg
+ delete mode 120000 201302/jmg_0535.jpg
+ delete mode 120000 201302/jmg_0537.jpg
+ delete mode 120000 201302/jmg_0539.jpg
+ delete mode 120000 201302/jmg_0541.jpg
+ delete mode 120000 201302/jmg_0543.jpg
+ delete mode 120000 201304/bruecke_saeckingen.tif
+ delete mode 120000 201304/jmg_0685.cr2
+ delete mode 120000 201304/jmg_0685.jpg
+ delete mode 120000 201304/jmg_0687.cr2
+ delete mode 120000 201304/jmg_0687.jpg
+ delete mode 120000 201304/jmg_0699.jpg
+ delete mode 120000 201304/jmg_0700.jpg
+ delete mode 120000 201304/jmg_0726.jpg
+ delete mode 120000 201304/jmg_0727.jpg
+ delete mode 120000 201304/jmg_0728.jpg
+ delete mode 120000 201304/jmg_0729.cr2
+ delete mode 120000 201304/jmg_0729.jpg
+ delete mode 120000 201304/jmg_0730.jpg
+ delete mode 120000 201304/jmg_0731.jpg
+ delete mode 120000 201304/jmg_0733.cr2
+ delete mode 120000 201304/jmg_0733.jpg
+ delete mode 120000 201304/jmg_0734.cr2
+ delete mode 120000 201304/jmg_0734.jpg
+ delete mode 120000 201304/jmg_0736.cr2
+ delete mode 120000 201304/jmg_0736.jpg
+ delete mode 120000 201304/jmg_0737.cr2
+ delete mode 120000 201304/jmg_0737.jpg
+ delete mode 120000 201304/jmg_0738.jpg
+ delete mode 120000 201304/jmg_0739.jpg
+ delete mode 120000 201304/jmg_0740.jpg
+ delete mode 120000 201304/jmg_0741.jpg
+ delete mode 120000 201304/jmg_0742.jpg
+ delete mode 120000 201304/jmg_0744.cr2
+ delete mode 120000 201304/jmg_0744.jpg
+ delete mode 120000 201304/jmg_0749.jpg
+ delete mode 120000 201304/jmg_0750.jpg
+ delete mode 120000 201304/jmg_0751.jpg
+ delete mode 120000 201304/jmg_0752.jpg
+ delete mode 120000 201304/jmg_0753.jpg
+ delete mode 120000 201304/jmg_0755.cr2
+ delete mode 120000 201304/jmg_0755.jpg
+ delete mode 120000 201304/jmg_0757.cr2
+ delete mode 120000 201304/jmg_0757.jpg
+ delete mode 120000 201304/jmg_0758.jpg
+ delete mode 120000 201304/jmg_0759.jpg
+ delete mode 120000 201304/jmg_0760.cr2
+ delete mode 120000 201304/jmg_0760.jpg
+ delete mode 120000 201304/jmg_0762.cr2
+ delete mode 120000 201304/jmg_0762.jpg
+ delete mode 120000 201304/jmg_0763.jpg
+ delete mode 120000 201304/jmg_0764.jpg
+ delete mode 120000 201304/jmg_0765.jpg
+ delete mode 120000 201304/jmg_0766.jpg
+ delete mode 120000 201304/jmg_0769.jpg
+ delete mode 120000 201304/jmg_0770.jpg
+ delete mode 120000 201304/jmg_0771.jpg
+ delete mode 120000 201304/jmg_0785.cr2
+ delete mode 120000 201304/jmg_0785.jpg
+ delete mode 120000 201304/jmg_0786.cr2
+ delete mode 120000 201304/jmg_0786.jpg
+ delete mode 120000 201304/jmg_0787.cr2
+ delete mode 120000 201304/jmg_0787.jpg
+ delete mode 120000 201304/jmg_0789.jpg
+ delete mode 120000 201304/jmg_0790.jpg
+ delete mode 120000 201304/jmg_0791.jpg
+ delete mode 120000 201304/jmg_0800.jpg
+ delete mode 120000 201304/jmg_0801.jpg
+ delete mode 120000 201304/jmg_0802.jpg
+ delete mode 120000 201304/jmg_0803.jpg
+ delete mode 120000 201304/jmg_0809.jpg
+ delete mode 120000 201304/jmg_0810.jpg
+ delete mode 120000 201304/jmg_0812.jpg
+ delete mode 120000 201304/jmg_0813.jpg
+ delete mode 120000 201304/jmg_0824.jpg
+ delete mode 120000 201304/jmg_0825.jpg
+ delete mode 120000 201304/jmg_0827.jpg
+ delete mode 120000 201304/jmg_0831.jpg
+ delete mode 120000 201304/jmg_0833.jpg
+ delete mode 120000 201304/jmg_0834.jpg
+ delete mode 120000 201304/jmg_0836.jpg
+ delete mode 120000 201304/jmg_0837.jpg
+ delete mode 120000 201304/jmg_0845.jpg
+ delete mode 120000 201304/jmg_0846.jpg
+ delete mode 120000 201304/jmg_0847.jpg
+ delete mode 120000 201304/jmg_0848.jpg
+ delete mode 120000 201304/jmg_0849.jpg
+ delete mode 120000 201304/jmg_0850.jpg
+ delete mode 120000 201304/jmg_0851.jpg
+ delete mode 120000 201304/jmg_0857.jpg
+ delete mode 120000 201304/jmg_0858.jpg
+ delete mode 120000 201304/jmg_0860.jpg
+ delete mode 120000 201304/jmg_0861.jpg
+ delete mode 120000 201304/jmg_0862.jpg
+ delete mode 120000 201304/jmg_0863.jpg
+ delete mode 120000 201304/jmg_0864.jpg
+ delete mode 120000 201304/jmg_0866.jpg
+ delete mode 120000 201304/jmg_0867.jpg
+ delete mode 120000 201304/jmg_0868.cr2
+ delete mode 120000 201304/jmg_0868.jpg
+ delete mode 120000 201304/jmg_0869.cr2
+ delete mode 120000 201304/jmg_0869.jpg
+ delete mode 120000 201304/jmg_0872.cr2
+ delete mode 120000 201304/jmg_0872.jpg
+ delete mode 120000 201304/jmg_0874.cr2
+ delete mode 120000 201304/jmg_0874.jpg
+ delete mode 120000 201304/jmg_0875.jpg
+ delete mode 120000 201304/jmg_0875_raw.jpg
+ delete mode 120000 201304/jmg_0876.jpg
+ delete mode 120000 201304/jmg_0877.jpg
+ delete mode 120000 201304/jmg_0878.jpg
+ delete mode 120000 201304/jmg_0880.jpg
+ delete mode 120000 201304/jmg_0881.jpg
+ delete mode 120000 201304/jmg_0882.jpg
+ delete mode 120000 201304/jmg_0884.jpg
+ delete mode 120000 201304/jmg_0885.jpg
+ delete mode 120000 201304/jmg_0886.jpg
+ delete mode 120000 201304/jmg_0888.jpg
+ delete mode 120000 201304/jmg_0889.jpg
+ delete mode 120000 201304/jmg_0890.jpg
+ delete mode 120000 201304/jmg_0891.jpg
+ delete mode 120000 201304/jmg_0892.jpg
+ delete mode 120000 201304/jmg_0893.cr2
+ delete mode 120000 201304/jmg_0893.jpg
+ delete mode 120000 201304/jmg_0894.jpg
+ delete mode 120000 201304/jmg_0896.jpg
+ delete mode 120000 201304/jmg_0897.jpg
+ delete mode 120000 201304/jmg_0898.jpg
+ delete mode 120000 201304/jmg_0899.jpg
+ delete mode 120000 201304/jmg_0900.jpg
+ delete mode 120000 201304/jmg_0902.jpg
+ delete mode 120000 201304/jmg_0905.jpg
+ delete mode 120000 201304/jmg_0921.jpg
+ delete mode 120000 201304/jmg_0922.jpg
+ delete mode 120000 201304/jmg_0932.jpg
+ delete mode 120000 201304/jmg_0935.jpg
+ delete mode 120000 201304/jmg_0936.jpg
+ delete mode 120000 201304/jmg_0937.jpg
+ delete mode 120000 201304/jmg_0938.jpg
+ delete mode 120000 201304/jmg_0942.jpg
+ delete mode 120000 201304/jmg_0944.jpg
+ delete mode 120000 201304/jmg_0946.jpg
+ delete mode 120000 201304/jmg_0947.jpg
+ delete mode 120000 201304/jmg_0948.jpg
+ delete mode 120000 201304/jmg_0949.jpg
+ delete mode 120000 201304/jmg_0950.jpg
+ delete mode 120000 201304/jmg_0951.jpg
+ delete mode 120000 201304/jmg_0952.jpg
+ delete mode 120000 201304/jmg_0953.jpg
+ delete mode 120000 201304/jmg_0954.jpg
+ delete mode 120000 201304/jmg_0958.jpg
+ delete mode 120000 201304/jmg_0959.jpg
+ delete mode 120000 201304/jmg_0960.jpg
+ delete mode 120000 201304/jmg_0961.jpg
+ delete mode 120000 201304/jmg_0962.jpg
+ delete mode 120000 201304/jmg_0963.jpg
+ delete mode 120000 201304/jmg_0964.jpg
+ delete mode 120000 201304/jmg_0965.jpg
+ delete mode 120000 201304/jmg_0966.jpg
+ delete mode 120000 201304/jmg_0967.jpg
+ delete mode 120000 201304/jmg_0968.jpg
+ delete mode 120000 201304/jmg_0969.jpg
+ delete mode 120000 201304/jmg_0976.cr2
+ delete mode 120000 201304/jmg_0976.jpg
+ delete mode 120000 201304/jmg_0978.jpg
+ delete mode 120000 201304/jmg_0979.jpg
+ delete mode 120000 201304/jmg_0980.jpg
+ delete mode 120000 201304/jmg_0981.cr2
+ delete mode 120000 201304/jmg_0981.jpg
+ delete mode 120000 201304/jmg_0982.jpg
+ delete mode 120000 201304/jmg_0984.cr2
+ delete mode 120000 201304/jmg_0984.jpg
+ delete mode 120000 201304/jmg_0987.jpg
+ delete mode 120000 201304/jmg_0988.jpg
+ delete mode 120000 201304/jmg_0989.jpg
+ delete mode 120000 201304/jmg_0990.jpg
+ delete mode 120000 201304/jmg_0991.jpg
+ delete mode 120000 201304/jmg_0992.jpg
+ delete mode 120000 201304/jmg_1206.jpg
+ delete mode 120000 201304/jmg_1207.jpg
+ delete mode 120000 201304/jmg_1208.jpg
+ delete mode 120000 201304/jmg_1209.jpg
+ delete mode 120000 201304/jmg_1210.cr2
+ delete mode 120000 201304/jmg_1210.jpg
+ delete mode 120000 201304/jmg_1211.jpg
+ delete mode 120000 201304/jmg_1212.jpg
+ delete mode 120000 201304/jmg_1213.jpg
+ delete mode 120000 201304/jmg_1214.cr2
+ delete mode 120000 201304/jmg_1214.jpg
+ delete mode 120000 201304/jmg_1215.jpg
+ delete mode 120000 201304/jmg_1216.cr2
+ delete mode 120000 201304/jmg_1216.jpg
+ delete mode 120000 201304/jmg_1217.cr2
+ delete mode 120000 201304/jmg_1217.jpg
+ delete mode 120000 201304/jmg_1220.cr2
+ delete mode 120000 201304/jmg_1220.jpg
+ delete mode 120000 201304/jmg_1222.cr2
+ delete mode 120000 201304/jmg_1222.jpg
+ delete mode 120000 201304/jmg_1223.jpg
+ delete mode 120000 201306/jmg_1465.jpg
+ delete mode 120000 201306/jmg_1466.jpg
+ delete mode 120000 201306/jmg_1467.jpg
+ delete mode 120000 201306/jmg_1468.jpg
+ delete mode 120000 201306/jmg_1469.jpg
+ delete mode 120000 201306/jmg_1470.jpg
+ delete mode 120000 201306/jmg_1471.jpg
+ delete mode 120000 201306/jmg_1472.jpg
+ delete mode 120000 201306/jmg_1473.jpg
+ delete mode 120000 201306/jmg_1475.jpg
+ delete mode 120000 201306/jmg_1476.jpg
+ delete mode 120000 201306/jmg_1477.jpg
+ delete mode 120000 201306/jmg_1478.jpg
+ delete mode 120000 201306/jmg_1479.jpg
+ delete mode 120000 201306/jmg_1480.jpg
+ delete mode 120000 201306/jmg_1481.jpg
+ delete mode 120000 201306/jmg_1482.jpg
+ delete mode 120000 201306/jmg_1483.jpg
+ delete mode 120000 201306/jmg_1484.jpg
+ delete mode 120000 201306/jmg_1485.jpg
+ delete mode 120000 201306/jmg_1486.jpg
+ delete mode 120000 201306/jmg_1487.jpg
+ delete mode 120000 201306/jmg_1488.jpg
+ delete mode 120000 201306/jmg_1489.jpg
+ delete mode 120000 201306/jmg_1490.jpg
+ delete mode 120000 201306/jmg_1491.jpg
+ delete mode 120000 201306/jmg_1492.jpg
+ delete mode 120000 201306/jmg_1495.jpg
+ delete mode 120000 201306/jmg_1496.jpg
+ delete mode 120000 201306/jmg_1498.jpg
+ delete mode 120000 201306/jmg_1499.jpg
+ delete mode 120000 201306/jmg_1500.jpg
+ delete mode 120000 201306/jmg_1501.jpg
+ delete mode 120000 201306/jmg_1502.jpg
+ delete mode 120000 201306/jmg_1504.jpg
+ delete mode 120000 201306/jmg_1506.jpg
+ delete mode 120000 201306/jmg_1510.jpg
+ delete mode 120000 201306/jmg_1512.jpg
+ delete mode 120000 201306/jmg_1513.jpg
+ delete mode 120000 201306/jmg_1514.jpg
+ delete mode 120000 201306/jmg_1515.jpg
+ delete mode 120000 201306/jmg_1517.jpg
+ delete mode 120000 201306/jmg_1520.jpg
+ delete mode 120000 201306/jmg_1521.jpg
+ delete mode 120000 201306/jmg_1526.jpg
+ delete mode 120000 201306/jmg_1533.jpg
+ delete mode 120000 201306/jmg_1540.jpg
+ delete mode 120000 201306/jmg_1546.jpg
+ delete mode 120000 201306/jmg_1547.jpg
+ delete mode 120000 201306/jmg_1549.jpg
+ delete mode 120000 201306/jmg_1550.jpg
+ delete mode 120000 201306/jmg_1551.jpg
+ delete mode 120000 201306/jmg_1552.jpg
+ delete mode 120000 201306/jmg_1553.jpg
+ delete mode 120000 201306/jmg_1555.jpg
+ delete mode 120000 201306/jmg_1556.jpg
+ delete mode 120000 201306/jmg_1557.jpg
+ delete mode 120000 201306/jmg_1558.jpg
+ delete mode 120000 201306/jmg_1559.jpg
+ delete mode 120000 201306/jmg_1560.jpg
+ delete mode 120000 201306/jmg_1562.jpg
+ delete mode 120000 201306/jmg_1566.jpg
+ delete mode 120000 201306/jmg_1568.jpg
+ delete mode 120000 201306/jmg_1570.jpg
+ delete mode 120000 201306/jmg_1571.jpg
+ delete mode 120000 201306/jmg_1572.jpg
+ delete mode 120000 201306/jmg_1574.jpg
+ delete mode 120000 201306/jmg_1575.jpg
+ delete mode 120000 201306/jmg_1576.jpg
+ delete mode 120000 201306/jmg_1577.jpg
+ delete mode 120000 201306/jmg_1578.jpg
+ delete mode 120000 201306/jmg_1579.jpg
+ delete mode 120000 201306/jmg_1579_raw.jpg
+ delete mode 120000 201306/jmg_1581.jpg
+ delete mode 120000 201306/jmg_1583.jpg
+ delete mode 120000 201306/jmg_1583_cut.jpg
+ delete mode 120000 201306/jmg_1583_raw.jpg
+ delete mode 120000 201306/jmg_1584.jpg
+ delete mode 120000 201306/jmg_1586.jpg
+ delete mode 120000 201306/jmg_1587.jpg
+ delete mode 120000 201306/jmg_1588.jpg
+ delete mode 120000 201306/jmg_1589.jpg
+ delete mode 120000 201306/jmg_1591.jpg
+ delete mode 120000 201306/jmg_1592.jpg
+ delete mode 120000 201306/jmg_1593.jpg
+ delete mode 120000 201306/jmg_1593_raw.jpg
+ delete mode 120000 201306/jmg_1594.jpg
+ delete mode 120000 201306/jmg_1594_raw.jpg
+ delete mode 120000 201306/jmg_1595.jpg
+ delete mode 120000 201306/jmg_1596.jpg
+ delete mode 120000 201306/jmg_1597.jpg
+ delete mode 120000 201306/jmg_1599.jpg
+ delete mode 120000 201306/jmg_1626.jpg
+ delete mode 120000 201306/jmg_1628.jpg
+ delete mode 120000 201306/jmg_1629.jpg
+ delete mode 120000 201306/jmg_1630.jpg
+ delete mode 120000 201306/jmg_1631.jpg
+ delete mode 120000 201306/jmg_1633.jpg
+ delete mode 120000 201306/jmg_1635.jpg
+ delete mode 120000 201306/jmg_1636.jpg
+ delete mode 120000 201306/jmg_1637.jpg
+ delete mode 120000 201306/jmg_1638.jpg
+ delete mode 120000 201306/jmg_1640.jpg
+ delete mode 120000 201306/jmg_1642.jpg
+ delete mode 120000 201306/jmg_1643.jpg
+ delete mode 120000 201306/jmg_1644.jpg
+ delete mode 120000 201306/jmg_1647.jpg
+ delete mode 120000 201306/jmg_1649.jpg
+ delete mode 120000 201306/jmg_1650.jpg
+ delete mode 120000 201306/jmg_1651.jpg
+ delete mode 120000 201306/jmg_1652.jpg
+ delete mode 120000 201306/jmg_1653.jpg
+ delete mode 120000 201306/jmg_1655.jpg
+ delete mode 120000 201306/jmg_1656.jpg
+ delete mode 120000 201306/jmg_1660.jpg
+ delete mode 120000 201306/jmg_1667.jpg
+ delete mode 120000 201306/jmg_1682.jpg
+ delete mode 120000 201306/jmg_1688.jpg
+ delete mode 120000 201306/jmg_1689.jpg
+ delete mode 120000 201306/jmg_1701.jpg
+ delete mode 120000 201306/jmg_1702.jpg
+ delete mode 120000 201306/jmg_1703.jpg
+ delete mode 120000 201306/jmg_1710.jpg
+ delete mode 120000 201306/jmg_1710_raw.jpg
+ delete mode 120000 201306/jmg_1715.jpg
+ delete mode 120000 201306/jmg_1716.jpg
+ delete mode 120000 201306/jmg_1719.jpg
+ delete mode 120000 201306/jmg_1722.jpg
+ delete mode 120000 201306/jmg_1723.jpg
+ delete mode 120000 201306/jmg_1729.cr2
+ delete mode 120000 201308/jmg_2038.jpg
+ delete mode 120000 201308/jmg_2039.jpg
+ delete mode 120000 201308/jmg_2040.jpg
+ delete mode 120000 201308/jmg_2041.jpg
+ delete mode 120000 201308/jmg_2042.jpg
+ delete mode 120000 201308/jmg_2043.jpg
+ delete mode 120000 201308/jmg_2045.jpg
+ delete mode 120000 201308/jmg_2047.jpg
+ delete mode 120000 201308/jmg_2048.jpg
+ delete mode 120000 201308/jmg_2049.jpg
+ delete mode 120000 201308/jmg_2050.jpg
+ delete mode 120000 201308/jmg_2051.jpg
+ delete mode 120000 201308/jmg_2052.jpg
+ delete mode 120000 201308/jmg_2053.jpg
+ delete mode 120000 201308/jmg_2054.jpg
+ delete mode 120000 201308/jmg_2055.jpg
+ delete mode 120000 201308/jmg_2056.jpg
+ delete mode 120000 201308/jmg_2057.jpg
+ delete mode 120000 201308/jmg_2058.jpg
+ delete mode 120000 201308/jmg_2059.jpg
+ delete mode 120000 201308/jmg_2060.jpg
+ delete mode 120000 201308/jmg_2061.jpg
+ delete mode 120000 201308/jmg_2062.jpg
+ delete mode 120000 201308/jmg_2089.cr2
+ delete mode 120000 201308/jmg_2089.jpg
+ delete mode 120000 201308/jmg_2089_raw.jpg
+ delete mode 120000 201308/jmg_2090.jpg
+ delete mode 120000 201308/jmg_2091.jpg
+ delete mode 120000 201308/jmg_2092.jpg
+ delete mode 120000 201308/jmg_2093.jpg
+ delete mode 120000 201308/jmg_2096.jpg
+ delete mode 120000 201308/jmg_2097.jpg
+ delete mode 120000 201308/jmg_2098.jpg
+ delete mode 120000 201308/jmg_2099.cr2
+ delete mode 120000 201308/jmg_2099.jpg
+ delete mode 120000 201308/jmg_2099_raw.jpg
+ delete mode 120000 201308/jmg_2100.cr2
+ delete mode 120000 201308/jmg_2100.jpg
+ delete mode 120000 201308/jmg_2100_raw.jpg
+ delete mode 120000 201308/jmg_2102.jpg
+ delete mode 120000 201308/jmg_2103.jpg
+ delete mode 120000 201308/jmg_2104.jpg
+ delete mode 120000 201308/jmg_2105.jpg
+ delete mode 120000 201308/jmg_2106.jpg
+ delete mode 120000 201308/jmg_2107.jpg
+ delete mode 120000 201308/jmg_2108.jpg
+ delete mode 120000 201308/jmg_2109.jpg
+ delete mode 120000 201308/jmg_2110.jpg
+ delete mode 120000 201308/jmg_2111.jpg
+ delete mode 120000 201308/jmg_2112.jpg
+ delete mode 120000 201308/jmg_2113.jpg
+ delete mode 120000 201308/jmg_2114.jpg
+ delete mode 120000 201308/jmg_2115.jpg
+ delete mode 120000 201308/jmg_2117.jpg
+ delete mode 120000 201308/jmg_2118.jpg
+ delete mode 120000 201308/jmg_2119.jpg
+ delete mode 120000 201308/jmg_2120.jpg
+ delete mode 120000 201308/jmg_2122.jpg
+ delete mode 120000 201308/jmg_2125.jpg
+ delete mode 120000 201308/jmg_2127.jpg
+ delete mode 120000 201308/jmg_2129.jpg
+ delete mode 120000 201308/jmg_2130.jpg
+ delete mode 120000 201308/jmg_2132.jpg
+ delete mode 120000 201308/jmg_2134.jpg
+ delete mode 120000 201308/jmg_2135.jpg
+ delete mode 120000 201308/jmg_2136.jpg
+ delete mode 120000 201308/jmg_2137.jpg
+ delete mode 120000 201308/jmg_2138.jpg
+ delete mode 120000 201308/jmg_2148.jpg
+ delete mode 120000 201308/jmg_2150.jpg
+ delete mode 120000 201308/jmg_2151.jpg
+ delete mode 120000 201308/jmg_2156.jpg
+ delete mode 120000 201308/jmg_2158.cr2
+ delete mode 120000 201308/jmg_2158.jpg
+ delete mode 120000 201308/jmg_2159.jpg
+ delete mode 120000 201308/jmg_2160.jpg
+ delete mode 120000 201308/jmg_2161.jpg
+ delete mode 120000 201308/jmg_2162.jpg
+ delete mode 120000 201308/jmg_2165.jpg
+ delete mode 120000 201308/jmg_2166.jpg
+ delete mode 120000 201308/jmg_2168.jpg
+ delete mode 120000 201308/jmg_2169.jpg
+ delete mode 120000 201308/jmg_2171.jpg
+ delete mode 120000 201308/jmg_2173.jpg
+ delete mode 120000 201308/jmg_2174.jpg
+ delete mode 120000 201308/jmg_2175.jpg
+ delete mode 120000 201308/jmg_2177.jpg
+ delete mode 120000 201308/jmg_2178.jpg
+ delete mode 120000 201308/jmg_2180.jpg
+ delete mode 120000 201308/jmg_2181.jpg
+ delete mode 120000 201308/jmg_2182.jpg
+ delete mode 120000 201308/jmg_2183.jpg
+ delete mode 120000 201308/jmg_2184.jpg
+ delete mode 120000 201308/jmg_2187.jpg
+ delete mode 120000 201308/jmg_2188.jpg
+ delete mode 120000 201308/jmg_2189.jpg
+ delete mode 120000 201308/jmg_2191.cr2
+ delete mode 120000 201308/jmg_2191.jpg
+ delete mode 120000 201308/jmg_2193.cr2
+ delete mode 120000 201308/jmg_2193.jpg
+ delete mode 120000 201308/jmg_2194.cr2
+ delete mode 120000 201308/jmg_2194.jpg
+ delete mode 120000 201308/jmg_2197.cr2
+ delete mode 120000 201308/jmg_2197.jpg
+ delete mode 120000 201308/jmg_2200.cr2
+ delete mode 120000 201308/jmg_2200.jpg
+ delete mode 120000 201308/jmg_2201.cr2
+ delete mode 120000 201308/jmg_2201.jpg
+ delete mode 120000 201308/jmg_2202.cr2
+ delete mode 120000 201308/jmg_2202.jpg
+ delete mode 120000 201308/jmg_2209.jpg
+ delete mode 120000 201308/jmg_2210.jpg
+ delete mode 120000 201308/jmg_2215.jpg
+ delete mode 120000 201308/jmg_2216.jpg
+ delete mode 120000 201308/jmg_2217.cr2
+ delete mode 120000 201308/jmg_2217.jpg
+ delete mode 120000 201308/jmg_2219.cr2
+ delete mode 120000 201308/jmg_2219.jpg
+ delete mode 120000 201308/jmg_2223.jpg
+ delete mode 120000 201308/jmg_2224.jpg
+ delete mode 120000 201308/jmg_2225.cr2
+ delete mode 120000 201308/jmg_2225.jpg
+ delete mode 120000 201308/jmg_2227.jpg
+ delete mode 120000 201308/jmg_2228.jpg
+ delete mode 120000 201308/jmg_2235.jpg
+ delete mode 120000 201308/jmg_2237.jpg
+ delete mode 120000 201308/jmg_2238.jpg
+ delete mode 120000 201308/jmg_2239.cr2
+ delete mode 120000 201308/jmg_2239.jpg
+ delete mode 120000 201308/jmg_2239_raw.jpg
+ delete mode 120000 201308/jmg_2240.jpg
+ delete mode 120000 201308/jmg_2243.jpg
+ delete mode 120000 201308/jmg_2244.jpg
+ delete mode 120000 201308/jmg_2245.jpg
+ delete mode 120000 201308/jmg_2247.cr2
+ delete mode 120000 201308/jmg_2247.jpg
+ delete mode 120000 201308/jmg_2249.jpg
+ delete mode 120000 201308/jmg_2250.cr2
+ delete mode 120000 201308/jmg_2250.jpg
+ delete mode 120000 201308/jmg_2252.jpg
+ delete mode 120000 201308/jmg_2253.jpg
+ delete mode 120000 201308/jmg_2254.jpg
+ create mode 120000 incoming/5d/201203/jmg_8701.cr2
+ create mode 120000 incoming/5d/201203/jmg_8702.jpg
+ create mode 120000 incoming/5d/201203/jmg_8705.jpg
+ create mode 120000 incoming/5d/201203/jmg_8711.jpg
+ create mode 120000 incoming/5d/201203/jmg_8717.jpg
+ create mode 120000 incoming/5d/201203/jmg_8718.jpg
+ create mode 120000 incoming/5d/201203/jmg_8719.jpg
+ create mode 120000 incoming/5d/201203/jmg_8721.jpg
+ create mode 120000 incoming/5d/201203/jmg_8725.jpg
+ create mode 120000 incoming/5d/201203/jmg_8726.jpg
+ create mode 120000 incoming/5d/201203/jmg_8731.jpg
+ create mode 120000 incoming/5d/201203/jmg_8745.jpg
+ create mode 120000 incoming/5d/201203/jmg_8747_raw.jpg
+ create mode 120000 incoming/5d/201203/jmg_8750.cr2
+ create mode 120000 incoming/5d/201203/jmg_8750.jpg
+ create mode 120000 incoming/5d/201207/jmg_9048.jpg
+ create mode 120000 incoming/5d/201207/jmg_9053.jpg
+ create mode 120000 incoming/5d/201207/jmg_9054.jpg
+ create mode 120000 incoming/5d/201207/jmg_9069.cr2
+ create mode 120000 incoming/5d/201207/jmg_9069.jpg
+ create mode 120000 incoming/5d/201207/jmg_9070.cr2
+ create mode 120000 incoming/5d/201207/jmg_9070.jpg
+ create mode 120000 incoming/5d/201207/jmg_9072.cr2
+ create mode 120000 incoming/5d/201207/jmg_9072.jpg
+ create mode 120000 incoming/5d/201207/jmg_9076.cr2
+ create mode 120000 incoming/5d/201207/jmg_9076.jpg
+ create mode 120000 incoming/5d/201302/jmg_0502.cr2
+ create mode 120000 incoming/5d/201302/jmg_0502.jpg
+ create mode 120000 incoming/5d/201302/jmg_0503.jpg
+ create mode 120000 incoming/5d/201302/jmg_0507.jpg
+ create mode 120000 incoming/5d/201302/jmg_0510.jpg
+ create mode 120000 incoming/5d/201302/jmg_0512.jpg
+ create mode 120000 incoming/5d/201302/jmg_0513.jpg
+ create mode 120000 incoming/5d/201302/jmg_0514.jpg
+ create mode 120000 incoming/5d/201302/jmg_0516.jpg
+ create mode 120000 incoming/5d/201302/jmg_0517.jpg
+ create mode 120000 incoming/5d/201302/jmg_0518.jpg
+ create mode 120000 incoming/5d/201302/jmg_0521.jpg
+ create mode 120000 incoming/5d/201302/jmg_0522.jpg
+ create mode 120000 incoming/5d/201302/jmg_0523.jpg
+ create mode 120000 incoming/5d/201302/jmg_0524.jpg
+ create mode 120000 incoming/5d/201302/jmg_0526.jpg
+ create mode 120000 incoming/5d/201302/jmg_0527.jpg
+ create mode 120000 incoming/5d/201302/jmg_0528.jpg
+ create mode 120000 incoming/5d/201302/jmg_0532.cr2
+ create mode 120000 incoming/5d/201302/jmg_0532.jpg
+ create mode 120000 incoming/5d/201302/jmg_0534.jpg
+ create mode 120000 incoming/5d/201302/jmg_0535.jpg
+ create mode 120000 incoming/5d/201302/jmg_0537.jpg
+ create mode 120000 incoming/5d/201302/jmg_0539.jpg
+ create mode 120000 incoming/5d/201302/jmg_0541.jpg
+ create mode 120000 incoming/5d/201302/jmg_0543.jpg
+ create mode 120000 incoming/5d/jmg_0021.jpg
+ create mode 120000 incoming/5d/jmg_0025.jpg
+ create mode 120000 incoming/5d/jmg_0026.jpg
+ create mode 120000 incoming/5d/jmg_0027.jpg
+ create mode 120000 incoming/5d/jmg_0034.jpg
+ create mode 120000 incoming/5d/jmg_0035.jpg
+ create mode 120000 incoming/5d/jmg_0036.jpg
+ create mode 120000 incoming/5d/jmg_0130.jpg
+ create mode 120000 incoming/5d/jmg_0131.jpg
+ create mode 120000 incoming/5d/jmg_0133.jpg
+ create mode 120000 incoming/5d/jmg_0155.jpg
+ create mode 120000 incoming/5d/jmg_0156.jpg
+ create mode 120000 incoming/5d/jmg_0158.cr2
+ create mode 120000 incoming/5d/jmg_0165.cr2
+ create mode 120000 incoming/5d/jmg_0166.cr2
+ create mode 120000 incoming/5d/jmg_0178.cr2
+ create mode 120000 incoming/5d/jmg_0179.jpg
+ create mode 120000 incoming/5d/jmg_0180.cr2
+ create mode 120000 incoming/5d/jmg_0184.jpg
+ create mode 120000 incoming/5d/jmg_0185.cr2
+ create mode 120000 incoming/5d/jmg_0187.cr2
+ create mode 120000 incoming/5d/jmg_0310.jpg
+ create mode 120000 incoming/5d/jmg_0312.jpg
+ create mode 120000 incoming/5d/jmg_0315.jpg
+ create mode 120000 incoming/5d/jmg_0340.jpg
+ create mode 120000 incoming/5d/jmg_0357.jpg
+ create mode 120000 incoming/5d/jmg_0364.jpg
+ create mode 120000 incoming/5d/jmg_0365.jpg
+ create mode 120000 incoming/5d/jmg_0368.jpg
+ create mode 120000 incoming/5d/jmg_0374.jpg
+ create mode 120000 incoming/5d/jmg_0375.jpg
+ create mode 120000 incoming/5d/jmg_0386.jpg
+ create mode 120000 incoming/5d/jmg_0399.jpg
+ create mode 120000 incoming/5d/jmg_0411.jpg
+ create mode 120000 incoming/5d/jmg_0418.jpg
+ create mode 120000 incoming/5d/jmg_0476.cr2
+ create mode 120000 incoming/5d/jmg_0476.jpg
+ create mode 120000 incoming/5d/jmg_0503.jpg
+ create mode 120000 incoming/5d/jmg_0507.cr2
+ create mode 120000 incoming/5d/jmg_0513.cr2
+ create mode 120000 incoming/5d/jmg_0513.jpg
+ create mode 120000 incoming/5d/jmg_0516.cr2
+ create mode 120000 incoming/5d/jmg_0517.cr2
+ create mode 120000 incoming/5d/jmg_0518.jpg
+ create mode 120000 incoming/5d/jmg_0522.cr2
+ create mode 120000 incoming/5d/jmg_0524.cr2
+ create mode 120000 incoming/5d/jmg_0524.jpg
+ create mode 120000 incoming/5d/jmg_0530.jpg
+ create mode 120000 incoming/5d/jmg_0541.cr2
+ create mode 120000 incoming/5d/jmg_0550.jpg
+ create mode 120000 incoming/5d/jmg_0554.jpg
+ create mode 120000 incoming/5d/jmg_0555.jpg
+ create mode 120000 incoming/5d/jmg_0558.jpg
+ create mode 120000 incoming/5d/jmg_0563.jpg
+ create mode 120000 incoming/5d/jmg_0573.jpg
+ create mode 120000 incoming/5d/jmg_0575.cr2
+ create mode 120000 incoming/5d/jmg_0578.cr2
+ create mode 120000 incoming/5d/jmg_0579.cr2
+ create mode 120000 incoming/5d/jmg_0582.jpg
+ create mode 120000 incoming/5d/jmg_0593.cr2
+ create mode 120000 incoming/5d/jmg_0594.cr2
+ create mode 120000 incoming/5d/jmg_0594.jpg
+ create mode 120000 incoming/5d/jmg_0595.cr2
+ create mode 120000 incoming/5d/jmg_0600.jpg
+ create mode 120000 incoming/5d/jmg_0606.cr2
+ create mode 120000 incoming/5d/jmg_0607.jpg
+ create mode 120000 incoming/5d/jmg_0610.cr2
+ create mode 120000 incoming/5d/jmg_0610.jpg
+ create mode 120000 incoming/5d/jmg_0612.jpg
+ create mode 120000 incoming/5d/jmg_0613.cr2
+ create mode 120000 incoming/5d/jmg_0614.jpg
+ create mode 120000 incoming/5d/jmg_0619.cr2
+ create mode 120000 incoming/5d/jmg_0623.jpg
+ create mode 120000 incoming/5d/jmg_0628.cr2
+ create mode 120000 incoming/5d/jmg_0628.jpg
+ create mode 120000 incoming/5d/jmg_0639.jpg
+ create mode 120000 incoming/5d/jmg_0645.cr2
+ create mode 120000 incoming/5d/jmg_0646.jpg
+ create mode 120000 incoming/5d/jmg_0647.cr2
+ create mode 120000 incoming/5d/jmg_0648.jpg
+ create mode 120000 incoming/5d/jmg_0649.jpg
+ create mode 120000 incoming/5d/jmg_0655.jpg
+ create mode 120000 incoming/5d/jmg_0667.jpg
+ create mode 120000 incoming/5d/jmg_0670.jpg
+ create mode 120000 incoming/5d/jmg_0673.jpg
+ create mode 120000 incoming/5d/jmg_0679.jpg
+ create mode 120000 incoming/5d/jmg_0685.jpg
+ create mode 120000 incoming/5d/jmg_0699.cr2
+ create mode 120000 incoming/5d/jmg_0700.cr2
+ create mode 120000 incoming/5d/jmg_0701.cr2
+ create mode 120000 incoming/5d/jmg_0708.jpg
+ create mode 120000 incoming/5d/jmg_0718.jpg
+ create mode 120000 incoming/5d/jmg_0726.cr2
+ create mode 120000 incoming/5d/jmg_0728.jpg
+ create mode 120000 incoming/5d/jmg_0730.jpg
+ create mode 120000 incoming/5d/jmg_0734.jpg
+ create mode 120000 incoming/5d/jmg_0740.jpg
+ create mode 120000 incoming/5d/jmg_0743.cr2
+ create mode 120000 incoming/5d/jmg_0744.cr2
+ create mode 120000 incoming/5d/jmg_0745.cr2
+ create mode 120000 incoming/5d/jmg_0747.jpg
+ create mode 120000 incoming/5d/jmg_0750.cr2
+ create mode 120000 incoming/5d/jmg_0755.cr2
+ create mode 120000 incoming/5d/jmg_0759.cr2
+ create mode 120000 incoming/5d/jmg_0760.cr2
+ create mode 120000 incoming/5d/jmg_0761.jpg
+ create mode 120000 incoming/5d/jmg_0765.jpg
+ create mode 120000 incoming/5d/jmg_0768.jpg
+ create mode 120000 incoming/5d/jmg_0771.jpg
+ create mode 120000 incoming/5d/jmg_0778.jpg
+ create mode 120000 incoming/5d/jmg_0780.jpg
+ create mode 120000 incoming/5d/jmg_0782.cr2
+ create mode 120000 incoming/5d/jmg_0786.cr2
+ create mode 120000 incoming/5d/jmg_0787.cr2
+ create mode 120000 incoming/5d/jmg_0788.cr2
+ create mode 120000 incoming/5d/jmg_0794.jpg
+ create mode 120000 incoming/5d/jmg_0796.jpg
+ create mode 120000 incoming/5d/jmg_0801.cr2
+ create mode 120000 incoming/5d/jmg_0803.cr2
+ create mode 120000 incoming/5d/jmg_0804.cr2
+ create mode 120000 incoming/5d/jmg_0812.jpg
+ create mode 120000 incoming/5d/jmg_0819.jpg
+ create mode 120000 incoming/5d/jmg_0827.jpg
+ create mode 120000 incoming/5d/jmg_0830.jpg
+ create mode 120000 incoming/5d/jmg_0842.jpg
+ create mode 120000 incoming/5d/jmg_0846.jpg
+ create mode 120000 incoming/5d/jmg_0857.cr2
+ create mode 120000 incoming/5d/jmg_0863.jpg
+ create mode 120000 incoming/5d/jmg_0866.cr2
+ create mode 120000 incoming/5d/jmg_0868.cr2
+ create mode 120000 incoming/5d/jmg_0868.jpg
+ create mode 120000 incoming/5d/jmg_0870.jpg
+ create mode 120000 incoming/5d/jmg_0877.jpg
+ create mode 120000 incoming/5d/jmg_0882.cr2
+ create mode 120000 incoming/5d/jmg_0883.jpg
+ create mode 120000 incoming/5d/jmg_0888.jpg
+ create mode 120000 incoming/5d/jmg_0891.jpg
+ create mode 120000 incoming/5d/jmg_0894.cr2
+ create mode 120000 incoming/5d/jmg_0896.cr2
+ create mode 120000 incoming/5d/jmg_0897.cr2
+ create mode 120000 incoming/5d/jmg_0898.jpg
+ create mode 120000 incoming/5d/jmg_0899.cr2
+ create mode 120000 incoming/5d/jmg_0900.jpg
+ create mode 120000 incoming/5d/jmg_0905.jpg
+ create mode 120000 incoming/5d/jmg_0908.jpg
+ create mode 120000 incoming/5d/jmg_0914.jpg
+ create mode 120000 incoming/5d/jmg_0915.jpg
+ create mode 120000 incoming/5d/jmg_0916.jpg
+ create mode 120000 incoming/5d/jmg_0923.jpg
+ create mode 120000 incoming/5d/jmg_0924.jpg
+ create mode 120000 incoming/5d/jmg_0926.jpg
+ create mode 120000 incoming/5d/jmg_0928.jpg
+ create mode 120000 incoming/5d/jmg_0929.jpg
+ create mode 120000 incoming/5d/jmg_0936.jpg
+ create mode 120000 incoming/5d/jmg_0942.jpg
+ create mode 120000 incoming/5d/jmg_0944.jpg
+ create mode 120000 incoming/5d/jmg_0948.jpg
+ create mode 120000 incoming/5d/jmg_0960.jpg
+ create mode 120000 incoming/5d/jmg_0966.jpg
+ create mode 120000 incoming/5d/jmg_0970.cr2
+ create mode 120000 incoming/5d/jmg_0970.jpg
+ create mode 120000 incoming/5d/jmg_0972.jpg
+ create mode 120000 incoming/5d/jmg_0976.jpg
+ create mode 120000 incoming/5d/jmg_0983.cr2
+ create mode 120000 incoming/5d/jmg_0985.cr2
+ create mode 120000 incoming/5d/jmg_0985.jpg
+ create mode 120000 incoming/5d/jmg_0994.jpg
+ create mode 120000 incoming/5d/jmg_1209.cr2
+ create mode 120000 incoming/5d/jmg_1209.jpg
+ create mode 120000 incoming/5d/jmg_1211.cr2
+ create mode 120000 incoming/5d/jmg_1211.jpg
+ create mode 120000 incoming/5d/jmg_1217.cr2
+ create mode 120000 incoming/5d/jmg_1467.cr2
+ create mode 120000 incoming/5d/jmg_1469.jpg
+ create mode 120000 incoming/5d/jmg_1470.cr2
+ create mode 120000 incoming/5d/jmg_1471.cr2
+ create mode 120000 incoming/5d/jmg_1472.cr2
+ create mode 120000 incoming/5d/jmg_1477.cr2
+ create mode 120000 incoming/5d/jmg_1477.jpg
+ create mode 120000 incoming/5d/jmg_1481.cr2
+ create mode 120000 incoming/5d/jmg_1483.cr2
+ create mode 120000 incoming/5d/jmg_1485.jpg
+ create mode 120000 incoming/5d/jmg_1488.jpg
+ create mode 120000 incoming/5d/jmg_1491.jpg
+ create mode 120000 incoming/5d/jmg_1496.cr2
+ create mode 120000 incoming/5d/jmg_1502.jpg
+ create mode 120000 incoming/5d/jmg_1503.cr2
+ create mode 120000 incoming/5d/jmg_1504.jpg
+ create mode 120000 incoming/5d/jmg_1507.jpg
+ create mode 120000 incoming/5d/jmg_1515.jpg
+ create mode 120000 incoming/5d/jmg_1520.jpg
+ create mode 120000 incoming/5d/jmg_1523.jpg
+ create mode 120000 incoming/5d/jmg_1525.jpg
+ create mode 120000 incoming/5d/jmg_1539.jpg
+ create mode 120000 incoming/5d/jmg_1542.jpg
+ create mode 120000 incoming/5d/jmg_1546.jpg
+ create mode 120000 incoming/5d/jmg_1547.cr2
+ create mode 120000 incoming/5d/jmg_1549.jpg
+ create mode 120000 incoming/5d/jmg_1552.jpg
+ create mode 120000 incoming/5d/jmg_1554.cr2
+ create mode 120000 incoming/5d/jmg_1555.cr2
+ create mode 120000 incoming/5d/jmg_1556.cr2
+ create mode 120000 incoming/5d/jmg_1559.cr2
+ create mode 120000 incoming/5d/jmg_1560.cr2
+ create mode 120000 incoming/5d/jmg_1561.cr2
+ create mode 120000 incoming/5d/jmg_1562.cr2
+ create mode 120000 incoming/5d/jmg_1565.cr2
+ create mode 120000 incoming/5d/jmg_1567.cr2
+ create mode 120000 incoming/5d/jmg_1572.cr2
+ create mode 120000 incoming/5d/jmg_1577.cr2
+ create mode 120000 incoming/5d/jmg_1578.jpg
+ create mode 120000 incoming/5d/jmg_1583_cut.jpg
+ create mode 120000 incoming/5d/jmg_1583_raw.jpg
+ create mode 120000 incoming/5d/jmg_1592.cr2
+ create mode 120000 incoming/5d/jmg_1593.jpg
+ create mode 120000 incoming/5d/jmg_1626.cr2
+ create mode 120000 incoming/5d/jmg_1627.jpg
+ create mode 120000 incoming/5d/jmg_1628.cr2
+ create mode 120000 incoming/5d/jmg_1629.jpg
+ create mode 120000 incoming/5d/jmg_1630.cr2
+ create mode 120000 incoming/5d/jmg_1631.cr2
+ create mode 120000 incoming/5d/jmg_1633.cr2
+ create mode 120000 incoming/5d/jmg_1638.jpg
+ create mode 120000 incoming/5d/jmg_1639.cr2
+ create mode 120000 incoming/5d/jmg_1646.cr2
+ create mode 120000 incoming/5d/jmg_1646.jpg
+ create mode 120000 incoming/5d/jmg_1650.jpg
+ create mode 120000 incoming/5d/jmg_1651.cr2
+ create mode 120000 incoming/5d/jmg_1654.cr2
+ create mode 120000 incoming/5d/jmg_1656.jpg
+ create mode 120000 incoming/5d/jmg_1677.jpg
+ create mode 120000 incoming/5d/jmg_1689.jpg
+ create mode 120000 incoming/5d/jmg_1701.jpg
+ create mode 120000 incoming/5d/jmg_1703.jpg
+ create mode 120000 incoming/5d/jmg_1723.jpg
+ create mode 120000 incoming/5d/jmg_2039.jpg
+ create mode 120000 incoming/5d/jmg_2041.jpg
+ create mode 120000 incoming/5d/jmg_2048.cr2
+ create mode 120000 incoming/5d/jmg_2052.jpg
+ create mode 120000 incoming/5d/jmg_2061.jpg
+ delete mode 120000 incoming/5d/jmg_2064_raw.jpg
+ delete mode 120000 incoming/5d/jmg_2065_mo.jpg
+ delete mode 120000 incoming/5d/jmg_2065_raw.jpg
+ delete mode 120000 incoming/5d/jmg_2066_mo.jpg
+ delete mode 120000 incoming/5d/jmg_2066_raw.jpg
+ create mode 120000 incoming/5d/jmg_2090.jpg
+ create mode 120000 incoming/5d/jmg_2093.jpg
+ create mode 120000 incoming/5d/jmg_2100.cr2
+ create mode 120000 incoming/5d/jmg_2103.jpg
+ create mode 120000 incoming/5d/jmg_2107.jpg
+ create mode 120000 incoming/5d/jmg_2108.jpg
+ create mode 120000 incoming/5d/jmg_2112.jpg
+ create mode 120000 incoming/5d/jmg_2118.jpg
+ create mode 120000 incoming/5d/jmg_2119.jpg
+ create mode 120000 incoming/5d/jmg_2122.jpg
+ create mode 120000 incoming/5d/jmg_2125.jpg
+ create mode 120000 incoming/5d/jmg_2137.jpg
+ create mode 120000 incoming/5d/jmg_2149.jpg
+ create mode 120000 incoming/5d/jmg_2150.jpg
+ create mode 120000 incoming/5d/jmg_2158.cr2
+ create mode 120000 incoming/5d/jmg_2160.jpg
+ create mode 120000 incoming/5d/jmg_2165.jpg
+ create mode 120000 incoming/5d/jmg_2188.jpg
+ create mode 120000 incoming/5d/jmg_2189.jpg
+ create mode 120000 incoming/5d/jmg_2193.jpg
+ create mode 120000 incoming/5d/jmg_2194.cr2
+ create mode 120000 incoming/5d/jmg_2200.jpg
+ create mode 120000 incoming/5d/jmg_2201.cr2
+ create mode 120000 incoming/5d/jmg_2201.jpg
+ create mode 120000 incoming/5d/jmg_2210.jpg
+ create mode 120000 incoming/5d/jmg_2215.cr2
+ create mode 120000 incoming/5d/jmg_2216.cr2
+ create mode 120000 incoming/5d/jmg_2216.jpg
+ create mode 120000 incoming/5d/jmg_2224.jpg
+ create mode 120000 incoming/5d/jmg_2235.jpg
+ create mode 120000 incoming/5d/jmg_2238.jpg
+ create mode 120000 incoming/5d/jmg_2239.cr2
+ create mode 120000 incoming/5d/jmg_2239.jpg
+ create mode 120000 incoming/5d/jmg_2240.jpg
+ create mode 120000 incoming/5d/jmg_2244.jpg
+ create mode 120000 incoming/5d/jmg_2247.jpg
+ create mode 120000 incoming/5d/jmg_7250.cr2
+ create mode 120000 incoming/5d/jmg_7250.jpg
+ create mode 120000 incoming/5d/jmg_7256.jpg
+ create mode 120000 incoming/5d/jmg_7257.cr2
+ create mode 120000 incoming/5d/jmg_7259.cr2
+ create mode 120000 incoming/5d/jmg_7263.jpg
+ create mode 120000 incoming/5d/jmg_7265.cr2
+ create mode 120000 incoming/5d/jmg_7269.cr2
+ create mode 120000 incoming/5d/jmg_7270.cr2
+ create mode 120000 incoming/5d/jmg_7279.cr2
+ create mode 120000 incoming/5d/jmg_7286.cr2
+ create mode 120000 incoming/5d/jmg_7286.jpg
+ create mode 120000 incoming/5d/jmg_7290.cr2
+ create mode 120000 incoming/5d/jmg_7290.jpg
+ create mode 120000 incoming/5d/jmg_7293.cr2
+ create mode 120000 incoming/5d/jmg_7296.cr2
+ create mode 120000 incoming/5d/jmg_7299.jpg
+ create mode 120000 incoming/5d/jmg_7300.cr2
+ create mode 120000 incoming/5d/jmg_7300.jpg
+ create mode 120000 incoming/5d/jmg_7305_raw.jpg
+ create mode 120000 incoming/5d/jmg_8532.cr2
+ create mode 120000 incoming/5d/jmg_8533.cr2
+ create mode 120000 incoming/5d/jmg_8534.cr2
+ create mode 120000 incoming/5d/jmg_8536.jpg
+ create mode 120000 incoming/5d/jmg_8538.cr2
+ create mode 120000 incoming/5d/jmg_8549.cr2
+ create mode 120000 incoming/5d/jmg_8549.jpg
+ create mode 120000 incoming/5d/jmg_8552.cr2
+ create mode 120000 incoming/5d/jmg_8557.cr2
+ create mode 120000 incoming/5d/jmg_8560.cr2
+ create mode 120000 incoming/5d/jmg_8565.cr2
+ create mode 120000 incoming/5d/jmg_8566.cr2
+ create mode 120000 incoming/5d/jmg_8569.jpg
+ create mode 120000 incoming/5d/jmg_8575.jpg
+ create mode 120000 incoming/5d/jmg_8576.jpg
+ create mode 120000 incoming/5d/jmg_8578.cr2
+ create mode 120000 incoming/5d/jmg_8579.cr2
+ create mode 120000 incoming/5d/jmg_8580.jpg
+ create mode 120000 incoming/5d/jmg_8583.cr2
+ create mode 120000 incoming/5d/jmg_8588.cr2
+ create mode 120000 incoming/5d/jmg_8589.cr2
+ create mode 120000 incoming/5d/jmg_8595.jpg
+ create mode 120000 incoming/5d/jmg_8597.jpg
+ create mode 120000 incoming/5d/jmg_8599.jpg
+ create mode 120000 incoming/5d/jmg_8602.cr2
+ create mode 120000 incoming/5d/jmg_8603.cr2
+ create mode 120000 incoming/5d/jmg_8606.cr2
+ create mode 120000 incoming/5d/jmg_8606.jpg
+ create mode 120000 incoming/5d/jmg_8609.jpg
+ create mode 120000 incoming/5d/jmg_8613.jpg
+ create mode 120000 incoming/5d/jmg_8615.cr2
+ create mode 120000 incoming/5d/jmg_8617.jpg
+ create mode 120000 incoming/5d/jmg_8619.cr2
+ create mode 120000 incoming/5d/jmg_8620.jpg
+ create mode 120000 incoming/5d/jmg_8625.jpg
+ create mode 120000 incoming/5d/jmg_8627.jpg
+ create mode 120000 incoming/5d/jmg_8628.jpg
+ create mode 120000 incoming/5d/jmg_8632.cr2
+ create mode 120000 incoming/5d/jmg_8636.cr2
+ create mode 120000 incoming/5d/jmg_8636.jpg
+ create mode 120000 incoming/5d/jmg_8637.cr2
+ create mode 120000 incoming/5d/jmg_8639.jpg
+ create mode 120000 incoming/5d/jmg_8640.cr2
+ create mode 120000 incoming/5d/jmg_8655.jpg
+ create mode 120000 incoming/5d/jmg_8657.jpg
+ create mode 120000 incoming/5d/jmg_8670.cr2
+ create mode 120000 incoming/5d/jmg_8673.jpg
+ create mode 120000 incoming/5d/jmg_8674.cr2
+ create mode 120000 incoming/5d/jmg_8676.cr2
+ create mode 120000 incoming/5d/jmg_8676.jpg
+ create mode 120000 incoming/5d/jmg_8677.cr2
+ create mode 120000 incoming/5d/jmg_8681.jpg
+ create mode 120000 incoming/5d/jmg_8682.cr2
+ create mode 120000 incoming/5d/jmg_8702.cr2
+ create mode 120000 incoming/5d/jmg_8702.jpg
+ create mode 120000 incoming/5d/jmg_8707.jpg
+ create mode 120000 incoming/5d/jmg_8714.jpg
+ create mode 120000 incoming/5d/jmg_8716.jpg
+ create mode 120000 incoming/5d/jmg_8717.cr2
+ create mode 120000 incoming/5d/jmg_8719.jpg
+ create mode 120000 incoming/5d/jmg_8721.jpg
+ create mode 120000 incoming/5d/jmg_8727.cr2
+ create mode 120000 incoming/5d/jmg_8730.jpg
+ create mode 120000 incoming/5d/jmg_8736.cr2
+ create mode 120000 incoming/5d/jmg_8737.cr2
+ create mode 120000 incoming/5d/jmg_8742.cr2
+ create mode 120000 incoming/5d/jmg_8742.jpg
+ create mode 120000 incoming/5d/jmg_8745.jpg
+ create mode 120000 incoming/5d/jmg_8748.cr2
+ create mode 120000 incoming/5d/jmg_8748.jpg
+ create mode 120000 incoming/5d/jmg_8751.cr2
+ create mode 120000 incoming/5d/jmg_8755.cr2
+ create mode 120000 incoming/5d/jmg_8757.cr2
+ create mode 120000 incoming/5d/jmg_8760.cr2
+ create mode 120000 incoming/5d/jmg_8760.jpg
+ create mode 120000 incoming/5d/jmg_8765.cr2
+ create mode 120000 incoming/5d/jmg_8771.jpg
+ create mode 120000 incoming/5d/jmg_8801.jpg
+ create mode 120000 incoming/5d/jmg_8803.cr2
+ create mode 120000 incoming/5d/jmg_8803.jpg
+ create mode 120000 incoming/5d/jmg_8804.jpg
+ create mode 120000 incoming/5d/jmg_8805.jpg
+ create mode 120000 incoming/5d/jmg_8813.jpg
+ create mode 120000 incoming/5d/jmg_8816.cr2
+ create mode 120000 incoming/5d/jmg_8823.jpg
+ create mode 120000 incoming/5d/jmg_8827.cr2
+ create mode 120000 incoming/5d/jmg_8829.cr2
+ create mode 120000 incoming/5d/jmg_8832.jpg
+ create mode 120000 incoming/5d/jmg_8833.cr2
+ create mode 120000 incoming/5d/jmg_8837.cr2
+ create mode 120000 incoming/5d/jmg_8838.jpg
+ create mode 120000 incoming/5d/jmg_8840.jpg
+ create mode 120000 incoming/5d/jmg_8842.jpg
+ create mode 120000 incoming/5d/jmg_8844.cr2
+ create mode 120000 incoming/5d/jmg_8850.cr2
+ create mode 120000 incoming/5d/jmg_8850.jpg
+ create mode 120000 incoming/5d/jmg_8852.cr2
+ create mode 120000 incoming/5d/jmg_8853.cr2
+ create mode 120000 incoming/5d/jmg_8853.jpg
+ create mode 120000 incoming/5d/jmg_8856.cr2
+ create mode 120000 incoming/5d/jmg_8859.jpg
+ create mode 120000 incoming/5d/jmg_8863.jpg
+ create mode 120000 incoming/5d/jmg_8870.jpg
+ create mode 120000 incoming/5d/jmg_8871.cr2
+ create mode 120000 incoming/5d/jmg_8871.jpg
+ create mode 120000 incoming/5d/jmg_8881.jpg
+ create mode 120000 incoming/5d/jmg_8883.jpg
+ create mode 120000 incoming/5d/jmg_8886.jpg
+ create mode 120000 incoming/5d/jmg_8887.cr2
+ create mode 120000 incoming/5d/jmg_8889.cr2
+ create mode 120000 incoming/5d/jmg_8894.cr2
+ create mode 120000 incoming/5d/jmg_8897.cr2
+ create mode 120000 incoming/5d/jmg_8898.cr2
+ create mode 120000 incoming/5d/jmg_8900.jpg
+ create mode 120000 incoming/5d/jmg_8901.cr2
+ create mode 120000 incoming/5d/jmg_8902.cr2
+ create mode 120000 incoming/5d/jmg_8904.cr2
+ create mode 120000 incoming/5d/jmg_8906.jpg
+ create mode 120000 incoming/5d/jmg_8908.cr2
+ create mode 120000 incoming/5d/jmg_8920.cr2
+ create mode 120000 incoming/5d/jmg_8920.jpg
+ create mode 120000 incoming/5d/jmg_8922.cr2
+ create mode 120000 incoming/5d/jmg_8922.jpg
+ create mode 120000 incoming/5d/jmg_8923.cr2
+ create mode 120000 incoming/5d/jmg_8924.jpg
+ create mode 120000 incoming/5d/jmg_8925.cr2
+ create mode 120000 incoming/5d/jmg_8929.jpg
+ create mode 120000 incoming/5d/jmg_8930.jpg
+ create mode 120000 incoming/5d/jmg_8937.cr2
+ create mode 120000 incoming/5d/jmg_8939.cr2
+ create mode 120000 incoming/5d/jmg_8940.jpg
+ create mode 120000 incoming/5d/jmg_8941.jpg
+ create mode 120000 incoming/5d/jmg_8943.cr2
+ create mode 120000 incoming/5d/jmg_8944.jpg
+ create mode 120000 incoming/5d/jmg_8950.cr2
+ create mode 120000 incoming/5d/jmg_8951.jpg
+ create mode 120000 incoming/5d/jmg_8955.jpg
+ create mode 120000 incoming/5d/jmg_8959.cr2
+ create mode 120000 incoming/5d/jmg_8960.jpg
+ create mode 120000 incoming/5d/jmg_8962.cr2
+ create mode 120000 incoming/5d/jmg_8964.cr2
+ create mode 120000 incoming/5d/jmg_8965.jpg
+ create mode 120000 incoming/5d/jmg_8966.jpg
+ create mode 120000 incoming/5d/jmg_8971.jpg
+ create mode 120000 incoming/5d/jmg_8976.jpg
+ create mode 120000 incoming/5d/jmg_8978.cr2
+ create mode 120000 incoming/5d/jmg_8981.jpg
+ create mode 120000 incoming/5d/jmg_8982.jpg
+ create mode 120000 incoming/5d/jmg_8985.jpg
+ create mode 120000 incoming/5d/jmg_8988.cr2
+ create mode 120000 incoming/5d/jmg_8988.jpg
+ create mode 120000 incoming/5d/jmg_8992.cr2
+ create mode 120000 incoming/5d/jmg_8995.jpg
+ create mode 120000 incoming/5d/jmg_8996.cr2
+ create mode 120000 incoming/5d/jmg_8997.cr2
+ create mode 120000 incoming/5d/jmg_8999.cr2
+ create mode 120000 incoming/5d/jmg_9000.cr2
+ create mode 120000 incoming/5d/jmg_9015.cr2
+ create mode 120000 incoming/5d/jmg_9017.cr2
+ create mode 120000 incoming/5d/jmg_9019.cr2
+ create mode 120000 incoming/5d/jmg_9021.cr2
+ create mode 120000 incoming/5d/jmg_9021.jpg
+ create mode 120000 incoming/5d/jmg_9022.cr2
+ create mode 120000 incoming/5d/jmg_9027.cr2
+ create mode 120000 incoming/5d/jmg_9028.jpg
+ create mode 120000 incoming/5d/jmg_9031.cr2
+ create mode 120000 incoming/5d/jmg_9035.cr2
+ create mode 120000 incoming/5d/jmg_9043.jpg
+ create mode 120000 incoming/5d/jmg_9057.cr2
+ create mode 120000 incoming/5d/jmg_9064.cr2
+ create mode 120000 incoming/5d/jmg_9077.jpg
+ create mode 120000 incoming/5d/jmg_9078.jpg
+ create mode 120000 incoming/5d/jmg_9081.jpg
+ create mode 120000 incoming/5d/jmg_9082.cr2
+ create mode 120000 incoming/5d/jmg_9083.jpg
+ create mode 120000 incoming/5d/jmg_9086.cr2
+ create mode 120000 incoming/5d/jmg_9088.jpg
+ create mode 120000 incoming/5d/jmg_9308.jpg
+ create mode 120000 incoming/5d/jmg_9312.cr2
+ create mode 120000 incoming/5d/jmg_9313.jpg
+ create mode 120000 incoming/5d/jmg_9319.jpg
+ create mode 120000 incoming/5d/jmg_9521.cr2
+ create mode 120000 incoming/5d/jmg_9522.cr2
+ create mode 120000 incoming/5d/jmg_9533.jpg
+ create mode 120000 incoming/5d/jmg_9534.jpg
+ create mode 120000 incoming/5d/jmg_9535.cr2
+ create mode 120000 incoming/5d/jmg_9538.cr2
+ create mode 120000 incoming/5d/jmg_9538.jpg
+ create mode 120000 incoming/5d/jmg_9540.jpg
+ create mode 120000 incoming/5d/jmg_9542.cr2
+ create mode 120000 incoming/5d/jmg_9545.jpg
+ create mode 120000 incoming/5d/jmg_9554.jpg
+ create mode 120000 incoming/5d/jmg_9555.jpg
+ create mode 120000 incoming/5d/jmg_9558.jpg
+ create mode 120000 incoming/5d/jmg_9561.cr2
+ create mode 120000 incoming/5d/jmg_9585.cr2
+ create mode 120000 incoming/5d/jmg_9587.jpg
+ create mode 120000 incoming/5d/jmg_9591.jpg
+ create mode 120000 incoming/5d/jmg_9595.jpg
+ create mode 120000 incoming/5d/jmg_9598.cr2
+ create mode 120000 incoming/5d/jmg_9600.jpg
+ create mode 120000 incoming/5d/jmg_9604.jpg
+ create mode 120000 incoming/5d/jmg_9610.jpg
+ create mode 120000 incoming/5d/jmg_9613.cr2
+ create mode 120000 incoming/5d/jmg_9613.jpg
+ create mode 120000 incoming/5d/jmg_9614.cr2
+ create mode 120000 incoming/5d/jmg_9618.jpg
+ create mode 120000 incoming/5d/jmg_9619.jpg
+ create mode 120000 incoming/5d/jmg_9620.jpg
+ create mode 120000 incoming/5d/jmg_9621.jpg
+ create mode 120000 incoming/5d/jmg_9623.cr2
+ create mode 120000 incoming/5d/jmg_9746.jpg
+ create mode 120000 incoming/5d/jmg_9763.cr2
+ create mode 120000 incoming/5d/jmg_9763.jpg
+ create mode 120000 incoming/5d/jmg_9764.cr2
+ create mode 120000 incoming/5d/jmg_9772.jpg
+ create mode 120000 incoming/5d/jmg_9773.jpg
+ create mode 120000 incoming/5d/jmg_9781.jpg
+ create mode 120000 incoming/5d/jmg_9790.jpg
+ create mode 120000 incoming/5d/jmg_9800.jpg
+ create mode 120000 incoming/5d/jmg_9808.jpg
+ create mode 120000 incoming/5d/jmg_9830.jpg
+ create mode 120000 incoming/5d/jmg_9834.cr2
+ create mode 120000 incoming/5d/jmg_9843.jpg
+ create mode 120000 incoming/5d/jmg_9848.jpg
+ create mode 120000 incoming/5d/jmg_9849.jpg
+ create mode 120000 incoming/5d/jmg_9853.cr2
+ create mode 120000 incoming/5d/jmg_9856.jpg
+ create mode 120000 incoming/5d/jmg_9857.cr2
+ create mode 120000 incoming/5d/jmg_9859.cr2
+ create mode 120000 incoming/5d/jmg_9860.jpg
+ create mode 120000 incoming/5d/jmg_9917.jpg
+ create mode 120000 incoming/5d/jmg_9923.jpg
+ create mode 120000 incoming/5d/jmg_9926.jpg
+ create mode 120000 incoming/5d/jmg_9975.cr2
+ create mode 120000 incoming/5d/jmg_9976.cr2
+ create mode 120000 incoming/5d/jmg_9978.jpg
+ create mode 120000 incoming/5d/jmg_9988.jpg
+ create mode 120000 incoming/5d/jmg_9997.cr2
+ create mode 120000 incoming/5d/jmg_9998.jpg
+ create mode 120000 incoming/5d/jmg_9999.jpg
+ delete mode 120000 list_5d_repoB
+ create mode 120000 only_on_repoB
+ delete mode 120000 dir/2012/dir2/jmg_0128.cr2
+ delete mode 120000 dir/2012/dir2/jmg_0128.jpg
+ delete mode 120000 dir/2012/dir2/jmg_0129.cr2
+ delete mode 120000 dir/2012/dir2/jmg_0129.jpg
+ delete mode 120000 dir/2012/dir2/jmg_0353.jpg
+ delete mode 120000 dir/2012/dir2/jmg_0354.jpg
+ delete mode 120000 dir/2012/dir2/jmg_0375.jpg
+ delete mode 120000 dir/2012/dir2/jmg_0376.jpg
+ delete mode 120000 dir/2012/dir2/jmg_0378.jpg
+ delete mode 120000 dir/2012/dir2/jmg_8707.cr2
+ delete mode 120000 dir/2012/dir2/jmg_8707.jpg
+ delete mode 120000 dir/2012/dir2/jmg_8727.cr2
+ delete mode 120000 dir/2012/dir2/jmg_8727.jpg
+ delete mode 120000 dir/2012/dir2/jmg_8728.cr2
+ delete mode 120000 dir/2012/dir2/jmg_8728.jpg
+ delete mode 120000 dir/2012/dir2/jmg_8729.cr2
+ delete mode 120000 dir/2012/dir2/jmg_8729.jpg
+ delete mode 120000 dir/2012/dir2/jmg_8740.cr2
+ delete mode 120000 dir/2012/dir2/jmg_8740.jpg
+ delete mode 120000 dir/2012/dir2/jmg_8742.cr2
+ delete mode 120000 dir/2012/dir2/jmg_8742.jpg
+ delete mode 120000 dir/2012/dir2/jmg_8825.cr2
+ delete mode 120000 dir/2012/dir2/jmg_8825.jpg
+ delete mode 120000 dir/2012/dir2/jmg_8991.cr2
+ delete mode 120000 dir/2012/dir2/jmg_8991.jpg
+ delete mode 120000 dir/2012/dir2/jmg_8992.cr2
+ delete mode 120000 dir/2012/dir2/jmg_8992.jpg
+ delete mode 120000 dir/2012/dir2/jmg_8993.cr2
+ delete mode 120000 dir/2012/dir2/jmg_8993.jpg
+ delete mode 120000 dir/2012/dir2/jmg_9059.cr2
+ delete mode 120000 dir/2012/dir2/jmg_9059.jpg
+ delete mode 120000 dir/2012/dir2/jmg_9060.cr2
+ delete mode 120000 dir/2012/dir2/jmg_9060.jpg
+ delete mode 120000 dir/2012/dir2/jmg_9064.cr2
+ delete mode 120000 dir/2012/dir2/jmg_9064.jpg
+ delete mode 120000 dir/2012/dir2/jmg_9065.cr2
+ delete mode 120000 dir/2012/dir2/jmg_9065.jpg
+ delete mode 120000 dir/2012/dir2/jmg_9081.cr2
+ delete mode 120000 dir/2012/dir2/jmg_9081.jpg
+ delete mode 120000 dir/2012/dir2/jmg_9082.cr2
+ delete mode 120000 dir/2012/dir2/jmg_9082.jpg
+ delete mode 120000 dir/2012/dir2/jmg_9083.cr2
+ delete mode 120000 dir/2012/dir2/jmg_9083.jpg
+ delete mode 120000 dir/2012/dir1/jmg_0132.cr2
+ delete mode 120000 dir/2012/dir1/jmg_0132.jpg
+ delete mode 120000 dir/2012/dir1/jmg_0133.cr2
+ delete mode 120000 dir/2012/dir1/jmg_0133.jpg
+ delete mode 120000 dir/2012/dir1/jmg_0347.jpg
+ delete mode 120000 dir/2012/dir1/jmg_0351.jpg
+ delete mode 120000 dir/2012/dir1/jmg_0352.jpg
+ delete mode 120000 dir/2012/dir1/jmg_0374.jpg
+ delete mode 120000 dir/2012/dir1/jmg_8714.cr2
+ delete mode 120000 dir/2012/dir1/jmg_8714.jpg
+ delete mode 120000 dir/2012/dir1/jmg_8716.cr2
+ delete mode 120000 dir/2012/dir1/jmg_8716.jpg
+ delete mode 120000 dir/2012/dir1/jmg_8734.cr2
+ delete mode 120000 dir/2012/dir1/jmg_8734.jpg
+ delete mode 120000 dir/2012/dir1/jmg_8735.cr2
+ delete mode 120000 dir/2012/dir1/jmg_8735.jpg
+ delete mode 120000 dir/2012/dir1/jmg_8736.cr2
+ delete mode 120000 dir/2012/dir1/jmg_8736.jpg
+ delete mode 120000 dir/2012/dir1/jmg_8743.cr2
+ delete mode 120000 dir/2012/dir1/jmg_8743.jpg
+ delete mode 120000 dir/2012/dir1/jmg_8746.cr2
+ delete mode 120000 dir/2012/dir1/jmg_8746.jpg
+ delete mode 120000 dir/2012/dir1/jmg_8828.cr2
+ delete mode 120000 dir/2012/dir1/jmg_8828.jpg
+ delete mode 120000 dir/2012/dir1/jmg_8984.cr2
+ delete mode 120000 dir/2012/dir1/jmg_8984.jpg
+ delete mode 120000 dir/2012/dir1/jmg_8985.cr2
+ delete mode 120000 dir/2012/dir1/jmg_8985.jpg
+ delete mode 120000 dir/2012/dir1/jmg_8986.cr2
+ delete mode 120000 dir/2012/dir1/jmg_8986.jpg
+ delete mode 120000 dir/2012/dir1/jmg_8988.cr2
+ delete mode 120000 dir/2012/dir1/jmg_8988.jpg
+ delete mode 120000 dir/2012/dir1/jmg_9057.cr2
+ delete mode 120000 dir/2012/dir1/jmg_9057.jpg
+ delete mode 120000 dir/2012/dir1/jmg_9058.cr2
+ delete mode 120000 dir/2012/dir1/jmg_9058.jpg
+ delete mode 120000 dir/2012/dir1/jmg_9086.cr2
+ delete mode 120000 dir/2012/dir1/jmg_9086.jpg
+ delete mode 120000 dir/2012/dir1/jmg_9087.cr2
+ delete mode 120000 dir/2012/dir1/jmg_9087.jpg
+ delete mode 120000 dir/2013/dir2/jmg_0477.cr2
+ delete mode 120000 dir/2013/dir2/jmg_0477.jpg
+ delete mode 120000 dir/2013/dir2/jmg_0478.cr2
+ delete mode 120000 dir/2013/dir2/jmg_0478.jpg
+ delete mode 120000 dir/2013/dir2/jmg_0479.cr2
+ delete mode 120000 dir/2013/dir2/jmg_0479.jpg
+ delete mode 120000 dir/2013/dir2/jmg_0604.cr2
+ delete mode 120000 dir/2013/dir2/jmg_0604.jpg
+ delete mode 120000 dir/2013/dir2/jmg_0605.cr2
+ delete mode 120000 dir/2013/dir2/jmg_0605.jpg
+ delete mode 120000 dir/2013/dir2/jmg_0606.cr2
+ delete mode 120000 dir/2013/dir2/jmg_0606.jpg
+ delete mode 120000 dir/2013/dir2/jmg_0607.cr2
+ delete mode 120000 dir/2013/dir2/jmg_0607.jpg
+ delete mode 120000 dir/2013/dir2/jmg_0608.cr2
+ delete mode 120000 dir/2013/dir2/jmg_0608.jpg
+ delete mode 120000 dir/2013/dir2/jmg_0708.cr2
+ delete mode 120000 dir/2013/dir2/jmg_0708.jpg
+ delete mode 120000 dir/2013/dir2/jmg_0709.cr2
+ delete mode 120000 dir/2013/dir2/jmg_0709.jpg
+ delete mode 120000 dir/2013/dir2/jmg_0710.cr2
+ delete mode 120000 dir/2013/dir2/jmg_0710.jpg
+ delete mode 120000 dir/2013/dir1/jmg_0475.cr2
+ delete mode 120000 dir/2013/dir1/jmg_0475.jpg
+ delete mode 120000 dir/2013/dir1/jmg_0476.cr2
+ delete mode 120000 dir/2013/dir1/jmg_0476.jpg
+ delete mode 120000 dir/2013/dir1/jmg_0718.cr2
+ delete mode 120000 dir/2013/dir1/jmg_0718.jpg
+ delete mode 120000 dir/2013/dir1/jmg_0719.cr2
+ delete mode 120000 dir/2013/dir1/jmg_0719.jpg
+Already up-to-date.
+[2013-10-27 18:36:44 CET] Committer: Committing changes to git
+[2013-10-27 18:36:44 CET] Pusher: Syncing with repoB
+Already up-to-date.
+fatal: Unable to create '/media/srv/img/.git/refs/heads/synced/git-annex.lock': File exists.
+
+If no other git process is currently running, this probably means a
+git process crashed in this repository earlier. Make sure no other git
+process is running and remove the file manually to continue.
+fatal: The remote end hung up unexpectedly
+fatal: The remote end hung up unexpectedly
+From repoB:/media/srv/img
+ 276f659..5eba12c synced/git-annex -> repoB/synced/git-annex
+Everything up-to-date
+[2013-10-27 18:36:50 CET] Committer: Committing changes to git
+[2013-10-27 18:36:51 CET] Pusher: Syncing with repoB
+[2013-10-27 18:36:52 CET] Transferrer: Downloaded only_on_repoB
+[2013-10-27 18:36:53 CET] Transferrer: Downloaded jmg_9077.jpg
+[2013-10-27 18:36:58 CET] Committer: Committing changes to git
+[2013-10-27 18:36:58 CET] Transferrer: Downloaded jmg_8676.cr2
+[2013-10-27 18:36:59 CET] Committer: Committing changes to git
+[2013-10-27 18:37:02 CET] Transferrer: Downloaded jmg_0021.jpg
+[2013-10-27 18:37:02 CET] Committer: Committing changes to git
+[2013-10-27 18:37:04 CET] Transferrer: Downloaded jmg_0025.jpg
+[2013-10-27 18:37:04 CET] Committer: Committing changes to git
+[2013-10-27 18:37:06 CET] Transferrer: Downloaded jmg_0026.jpg
+[2013-10-27 18:37:06 CET] Committer: Committing changes to git
+[2013-10-27 18:37:07 CET] Transferrer: Downloaded jmg_0027.jpg
+[2013-10-27 18:37:07 CET] Committer: Committing changes to git
+[2013-10-27 18:37:10 CET] Transferrer: Downloaded jmg_0034.jpg
+[2013-10-27 18:37:10 CET] Committer: Committing changes to git
+[2013-10-27 18:37:12 CET] Transferrer: Downloaded jmg_0035.jpg
+[2013-10-27 18:37:12 CET] Committer: Committing changes to git
+[2013-10-27 18:37:15 CET] Transferrer: Downloaded jmg_0036.jpg
+[2013-10-27 18:37:15 CET] Committer: Committing changes to git
+[2013-10-27 18:37:17 CET] Transferrer: Downloaded jmg_0130.jpg
+[2013-10-27 18:37:17 CET] Committer: Committing changes to git
+[2013-10-27 18:37:18 CET] Transferrer: Downloaded jmg_0131.jpg
+[2013-10-27 18:37:18 CET] Committer: Committing changes to git
+[2013-10-27 18:37:20 CET] Transferrer: Downloaded jmg_0155.jpg
+[2013-10-27 18:37:20 CET] Committer: Committing changes to git
+[2013-10-27 18:37:23 CET] Transferrer: Downloaded jmg_0156.jpg
+[2013-10-27 18:37:23 CET] Committer: Committing changes to git
+[2013-10-27 18:37:27 CET] Transferrer: Downloaded jmg_0158.cr2
+[2013-10-27 18:37:27 CET] Committer: Committing changes to git
+[2013-10-27 18:37:32 CET] Transferrer: Downloaded jmg_0165.cr2
+[2013-10-27 18:37:32 CET] Committer: Committing changes to git
+[2013-10-27 18:37:37 CET] Transferrer: Downloaded jmg_0166.cr2
+[2013-10-27 18:37:37 CET] Committer: Committing changes to git
+To repoB:/media/srv/img/
+ 276f659..5eba12c git-annex -> synced/git-annex
+To repoB:/media/srv/img/
+ 5eba12c..f00ee07 git-annex -> synced/git-annex
+(Recording state in git...)
+(Recording state in git...)
+(Recording state in git...)
+(Recording state in git...)
+(Recording state in git...)
+(Recording state in git...)
+(Recording state in git...)
+(Recording state in git...)
+(Recording state in git...)
+(Recording state in git...)
+(Recording state in git...)
+(Recording state in git...)
+(Recording state in git...)
+(Recording state in git...)
+(Recording state in git...)
+(merging repoB/git-annex into git-annex...)
+
+
+(Recording state in git...)
+
+(Recording state in git...)
+(Recording state in git...)
+(Recording state in git...)
+(Recording state in git...)
+(Recording state in git...)
+(Recording state in git...)
+(Recording state in git...)
+(Recording state in git...)
+(Recording state in git...)
+(Recording state in git...)
+(Recording state in git...)
+(Recording state in git...)
+(Recording state in git...)
+(Recording state in git...)
+(Recording state in git...)
+(Recording state in git...)
+(Recording state in git...)
+(Recording state in git...)
+(Recording state in git...)
+# End of transcript or log.
+"""]]
+
+> [[done]], seems this was caused by the bug I alread fixed. --[[Joey]]
diff --git a/doc/bugs/During_synchronisation_top-level_folder_suddenly_appear_in_sub-sub-folder/comment_1_ae4a13ff121d27f78904eee9bf5e716b._comment b/doc/bugs/During_synchronisation_top-level_folder_suddenly_appear_in_sub-sub-folder/comment_1_ae4a13ff121d27f78904eee9bf5e716b._comment
new file mode 100644
index 000000000..88b293284
--- /dev/null
+++ b/doc/bugs/During_synchronisation_top-level_folder_suddenly_appear_in_sub-sub-folder/comment_1_ae4a13ff121d27f78904eee9bf5e716b._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 1"
+ date="2013-10-28T22:02:30Z"
+ content="""
+So this sounds like [[bugs/direct_mode_assistant_in_subdir_confusion]], which was fixed in 4.20131024. Is there a possibility that you started the git-annex assistant (or webapp) from within `incoming/5d` ?
+
+I'm not sure if the bug could also cause the removal of directories to happen in the wrong location.
+
+
+----
+
+It should be possible to revert these changes and get your files back.
+
+1. `git annex indirect`
+2. `git log --stat` (find the commit that deleted files)
+3. `git revert $commit`
+4. `git annex direct`
+"""]]
diff --git a/doc/bugs/During_synchronisation_top-level_folder_suddenly_appear_in_sub-sub-folder/comment_2_32e360cd7b100ddb9a526e7833fc55e1._comment b/doc/bugs/During_synchronisation_top-level_folder_suddenly_appear_in_sub-sub-folder/comment_2_32e360cd7b100ddb9a526e7833fc55e1._comment
new file mode 100644
index 000000000..1a7e4e16c
--- /dev/null
+++ b/doc/bugs/During_synchronisation_top-level_folder_suddenly_appear_in_sub-sub-folder/comment_2_32e360cd7b100ddb9a526e7833fc55e1._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnh6wz0pMA3NLPFg2j_I3S5JeinaOVqnng"
+ nickname="Felix"
+ subject="comment 2"
+ date="2013-10-30T22:55:36Z"
+ content="""
+It's quite possible that I have started the assistant (on the armhf machine) or the webapp (on the amd64 machine) in one of the subfolders, so yes it looks like that specific bug hit me.
+
+Having looked at the logs, I'm pretty sure that the removal of the original directory was caused by removing the suddenly occuring \"mirror\" folders in a subdirectory.
+***
+Reverting proves to be difficult. I created a full copy of the git-annex repo and switched to indirect mode. There are around 500 commits that need to be reverted and about 6 of them are merges which I haven't been able to revert. I have only reverted the non-merge commits and after going back to direct mode there are now around 200 broken symlinks. I'm now assuming that those 200 are the ones that are lost and I need to restore from a backup. Can I rely on that? It's extremely difficult for me to do a full check.
+***
+How should I proceed to get this repo (after further repairs) again in sync with the second repo and have the second repo adopt the \"repaired\" state?
+
+"""]]
diff --git a/doc/bugs/During_synchronisation_top-level_folder_suddenly_appear_in_sub-sub-folder/comment_3_650dc9ede4e16ef668d96840f63dad47._comment b/doc/bugs/During_synchronisation_top-level_folder_suddenly_appear_in_sub-sub-folder/comment_3_650dc9ede4e16ef668d96840f63dad47._comment
new file mode 100644
index 000000000..4e7d6491c
--- /dev/null
+++ b/doc/bugs/During_synchronisation_top-level_folder_suddenly_appear_in_sub-sub-folder/comment_3_650dc9ede4e16ef668d96840f63dad47._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 3"
+ date="2013-11-02T20:03:33Z"
+ content="""
+I don't understand why there are so many commits that need to be reverted. I'd have thought that it would have only made one bad commit due to the bug, and reverting that would do. Or even just adding back any symlinks removed by any of the bad commits, without an explicit revert would accomplish the same.
+
+You should be able to check with `git annex whereis --not --in .` what git-annex thinks about the 200 broken symlinks. Clearly their content is not in the local repisitory; it may be present elsewhere, or you might have to restore those files from backup.
+
+Once you have the git tree of the repository back in good shape, assuming you did it by committing changes, and possibly committing git reverts, you should be able to just use normal git annex syncing to sync those changes to the second repo. Ie, `git annex sync` in both, or running the assistant.
+"""]]
diff --git a/doc/bugs/During_synchronisation_top-level_folder_suddenly_appear_in_sub-sub-folder/comment_4_721cf184fb5a5244ec5c15de3302ebf7._comment b/doc/bugs/During_synchronisation_top-level_folder_suddenly_appear_in_sub-sub-folder/comment_4_721cf184fb5a5244ec5c15de3302ebf7._comment
new file mode 100644
index 000000000..3876444cd
--- /dev/null
+++ b/doc/bugs/During_synchronisation_top-level_folder_suddenly_appear_in_sub-sub-folder/comment_4_721cf184fb5a5244ec5c15de3302ebf7._comment
@@ -0,0 +1,33 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnh6wz0pMA3NLPFg2j_I3S5JeinaOVqnng"
+ nickname="Felix"
+ subject="Number of commits"
+ date="2013-11-21T20:26:46Z"
+ content="""
+I have no idea where this large number of commits come from, but maybe the sheer number of files explains it:
+
+Files appearing in the wrong place (probably due to me starting the assistant in a subdirectory of the repo):
+
+ $ git log --stat | grep \"5d/20.*+$\" |wc -l
+ 1148
+
+Me wondering where they come from and deleting them manually step by step when I found them:
+
+ $ git log --stat | grep \"5d/20.*-$\" |wc -l
+ 1095
+
+git-annex removing the original files that have been mirrored in the wrong place (and maybe a few more as I was working on stuff there as well):
+
+ $ git log --stat | grep \"^ 20.*-$\" | wc -l
+ 1152
+
+Maybe this explains the large number (approx. 500) of commits?
+
+---
+
+The missing 200 files have not been in a different repo, so apart from 3 that were not available they have been restored from the backup.
+
+---
+
+As my setup needs some changes anyway I'm going to start from scratch.
+"""]]
diff --git a/doc/bugs/Enable__47__paus_syncing_to_remote_ssh_server_with_multiple_directories.mdwn b/doc/bugs/Enable__47__paus_syncing_to_remote_ssh_server_with_multiple_directories.mdwn
new file mode 100644
index 000000000..823466f65
--- /dev/null
+++ b/doc/bugs/Enable__47__paus_syncing_to_remote_ssh_server_with_multiple_directories.mdwn
@@ -0,0 +1,19 @@
+What steps will reproduce the problem?
+
+Add two remote repositories to same server using ssh. Each directory is added to repositories list and starts syncing.
+After both repositories are scanned click on "syncing enabled" to disable syncing for one of the two remote repositories.
+
+What is the expected output? What do you see instead?
+
+Only remote repository which i clicked should stop syncing, but both remote repos start to stop syncing.
+Its also working the other way around (enable -> pause -> enable -> ..)
+
+What version of git-annex are you using? On what operating system?
+
+Version: 4.20130314, Debian
+
+Please provide any additional information below.
+
+I am an "webinterface only" user.
+
+[[!tag /design/assistant moreinfo]]
diff --git a/doc/bugs/Enable__47__paus_syncing_to_remote_ssh_server_with_multiple_directories/comment_1_e8affeca873c2ef73255f8f77e0ac16f._comment b/doc/bugs/Enable__47__paus_syncing_to_remote_ssh_server_with_multiple_directories/comment_1_e8affeca873c2ef73255f8f77e0ac16f._comment
new file mode 100644
index 000000000..02e4826a3
--- /dev/null
+++ b/doc/bugs/Enable__47__paus_syncing_to_remote_ssh_server_with_multiple_directories/comment_1_e8affeca873c2ef73255f8f77e0ac16f._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-03-16T21:56:37Z"
+ content="""
+Hmm, I can't quite reproduce this, but I did just fix a bug that, amoung other manifestations, caused the display of whether syncing is enabled for a remote to be wrong sometimes.
+
+Can you send a copy of your repository's .git/config file to this bug report? (That's `annex/.git/config`)
+"""]]
diff --git a/doc/bugs/Endless_SSH_password_prompts.mdwn b/doc/bugs/Endless_SSH_password_prompts.mdwn
new file mode 100644
index 000000000..26def613f
--- /dev/null
+++ b/doc/bugs/Endless_SSH_password_prompts.mdwn
@@ -0,0 +1,15 @@
+### Please describe the problem.
+Yesterday I installed git-annex on two computers and paired their repos. Today I logged back in to one of them, and as soon as the webapp loaded (autostarted in the background), it popped up an OpenSSH prompt wanting my key's password. I typed it in, and it popped up another. This went on several times. When I hit Cancel instead, it popped up a prompt wanting the password for the user account on my other computer. Even with that, once wasn't enough.
+
+This is bad enough, but worse is that the password prompt captures the keyboard input so I can't even open my Yakuake console to kill git-annex. Well, it's difficult and requires hitting Escape rapidly over and over until I can squeeze in a keystroke to the rest of the system.
+
+I don't understand why this is happening.
+
+1. Shouldn't git-annex have installed a passwordless key on my paired system? It did that for my remote repo.
+
+2. The prompt it's using has no option to remember the pasword. I use ssh-agent, but usually by running ssh-add in a terminal. Maybe if it would use a prompt that works with the agent it wouldn't ask for the password multiple times.
+
+3. I think it's opening multiple SSH connections at once, before I've entered the password even once, so even after I enter the password, it will keep asking for it until I've entered it for every SSH process that was already started.
+
+### What version of git-annex are you using? On what operating system?
+1 Nov 2013 Linux tarball on Ubuntu Raring 13.04
diff --git a/doc/bugs/Endless_SSH_password_prompts/comment_1_b3a32d7a53c30478f409a47f856282ab._comment b/doc/bugs/Endless_SSH_password_prompts/comment_1_b3a32d7a53c30478f409a47f856282ab._comment
new file mode 100644
index 000000000..b1ea71526
--- /dev/null
+++ b/doc/bugs/Endless_SSH_password_prompts/comment_1_b3a32d7a53c30478f409a47f856282ab._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 1"
+ date="2013-11-03T00:29:14Z"
+ content="""
+Pairing sets up the same kind of dedicated passwordless ssh key that is used when adding a ssh server.
+
+It's not clear from your description what program is asking for the password, or even if it's asking for the password for a ssh key. You need to provide more details.
+"""]]
diff --git a/doc/bugs/Endless_SSH_password_prompts/comment_2_0a1fc4b4580d8be4c37064e0a16de99b._comment b/doc/bugs/Endless_SSH_password_prompts/comment_2_0a1fc4b4580d8be4c37064e0a16de99b._comment
new file mode 100644
index 000000000..fec729ddb
--- /dev/null
+++ b/doc/bugs/Endless_SSH_password_prompts/comment_2_0a1fc4b4580d8be4c37064e0a16de99b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmNu4V5fvpLlBhaCUfXXOB0MI5NXwh8SkU"
+ nickname="Adam"
+ subject="comment 2"
+ date="2013-11-03T00:39:38Z"
+ content="""
+I'm not sure which program is doing the asking either. The title bar says \"OpenSSH\". It is asking for the SSH key password, but if I dismiss the dialog without entering the password, it will open another dialog asking for the user account's password, e.g. me@laptop, indicating it's SSH falling back to password auth.
+"""]]
diff --git a/doc/bugs/Endless_SSH_password_prompts/comment_3_46210f7745b8c7c237fc8b08309390fe._comment b/doc/bugs/Endless_SSH_password_prompts/comment_3_46210f7745b8c7c237fc8b08309390fe._comment
new file mode 100644
index 000000000..aacf1cc01
--- /dev/null
+++ b/doc/bugs/Endless_SSH_password_prompts/comment_3_46210f7745b8c7c237fc8b08309390fe._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlHNJ7FpiXJNwSmojlwKwXhhF5QvwpNPmI"
+ nickname="Colin"
+ subject="Confirmed"
+ date="2013-11-14T17:57:23Z"
+ content="""
+I am seeing the same problem. It happened on a machine running git-annex on Debian Testing some weeks ago, and I eventually disabled the offending repository for my sanity (incidentally - it seems to have vanished so I don't know how to re-enable it apart from adding it again).
+
+It has just very recently (some days) started on this machine running Debian Unstable.
+
+"""]]
diff --git a/doc/bugs/Error___39__get__39__ting_files_from_rsync_remote__44___versions_3.20120315_and_3.20120430.mdwn b/doc/bugs/Error___39__get__39__ting_files_from_rsync_remote__44___versions_3.20120315_and_3.20120430.mdwn
new file mode 100644
index 000000000..85e243382
--- /dev/null
+++ b/doc/bugs/Error___39__get__39__ting_files_from_rsync_remote__44___versions_3.20120315_and_3.20120430.mdwn
@@ -0,0 +1,79 @@
+What steps will reproduce the problem?
+
+ $ git annex initremote rsyncremote type=rsync rsyncurl=myuser@rsync.hidrive.strato.com:/users/myuser/git-annex/Music/ encryption=0xC597DECC177AFD7C
+ $ git annex get --from rsyncremote "file"
+
+What is the expected output? What do you see instead?
+
+I expect that the requested file is copied as for every other remote, but instead I get this error:
+
+----------------------------------------
+ get <file> (from rsyncremote...) (gpg)
+ rsync: change_dir "/users/myuser/git-annex/Music/0e5/a5b/'GPGHMACSHA1--3afd32ab8e70ac329262adeb770c330b0845b1e0" failed: No such file or directory (2)
+
+ sent 8 bytes received 10 bytes 7.20 bytes/sec
+ total size is 0 speedup is 0.00
+ rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1518) [Receiver=3.0.9]
+
+ rsync failed -- run git annex again to resume file transfer
+
+ rsync: change_dir "/users/myuser/git-annex/Music/8k/QZ/'GPGHMACSHA1--3afd32ab8e70ac329262adeb770c330b0845b1e0" failed: No such file or directory (2)
+
+ sent 8 bytes received 10 bytes 36.00 bytes/sec
+ total size is 0 speedup is 0.00
+ rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1518) [Receiver=3.0.9]
+
+ rsync failed -- run git annex again to resume file transfer
+failed
+ git-annex: get: 1 failed
+----------------------------------------
+
+I can verify that the directory /users/myuser/git-annex/Music/0e5/a5b/GPGHMACSHA1--3afd32ab8e70ac329262adeb770c330b0845b1e0 exists in the rsync remote, without the ' character.
+
+What version of git-annex are you using? On what operating system?
+
+I tried versions 3.20120315 and 3.20120430 on Gentoo linux.
+
+ $ uname -a
+ Linux odin 3.3.1-gentoo-odin #1 SMP Sat Apr 7 21:18:11 CEST 2012 x86_64 Intel(R) Core(TM) i5 CPU M 560 @ 2.67GHz GenuineIntel GNU/Linux
+
+ $ ghc --version
+ The Glorious Glasgow Haskell Compilation System, version 7.4.1
+
+Please provide any additional information below.
+
+The rsync remote config in .git/config:
+
+ [remote "rsyncremote"]
+ annex-rsyncurl = myuser@rsync.hidrive.strato.com:/users/myuser/git-annex/Music/
+ annex-uuid = "UUID"
+
+> Here's what the --debug flag shows is being run: --[[Joey]]
+
+ Running: rsync ["--progress","--inplace","joey@localhost:/tmp/Music/d98/a3c/'GPGHMACSHA1--878c3a3f59965bd87b4738ab29562efd215b954c/GPGHMACSHA1--878c3a3f59965bd87b4738ab29562efd215b954c'","/home/joey/tmp/x/.git/annex/tmp/GPGHMACSHA1--878c3a3f59965bd87b4738ab29562efd215b954c"]
+
+> But, this works for me, here, despite containing the quoting!
+> That's because here it's using rsync over ssh, which actually requires
+> that quoting. Are you using rsync
+> over the rsync protocol? If so, the workaround is to explicitly make
+> the rsyncurl start with `rsync://`
+>
+> And if this is the case, I need
+> to adjust the code in git-annex that determines if it's using ssh or
+> the rsync protocol. It assumes that (and this is what the rsync man
+> says AFAICS) that the rsync protocol is only used if the url starts
+> with `rsync://` or contains `::`.
+>
+>> Nope, it is indeed using rsync over ssh as git-annex thought.
+>
+> Hmm, I see that `hidrive.strato.com` is some kind of rsync provider?
+> Perhaps they do something with rsync over ssh that
+> avoids the need for shell quoting. For example, they might pass incoming
+> ssh connections directly into rsync, bypassing the shell
+> -- which avoids the need for this quoting. Any details you can provide
+> about them would probably be useful then. Ie, do they really use rsync
+> over ssh, is it really a `rsync.net` type rsync provider?
+> --[[Joey]]
+>
+>> This was the case, and the shellescape=no config option has been added
+>> to rsync special remotes to deal with it. [[done]] --[[Joey]]
diff --git a/doc/bugs/Error_creating_encrypted_cloud_repository:___34__internal_server_error__34__.mdwn b/doc/bugs/Error_creating_encrypted_cloud_repository:___34__internal_server_error__34__.mdwn
new file mode 100644
index 000000000..a44ecc82e
--- /dev/null
+++ b/doc/bugs/Error_creating_encrypted_cloud_repository:___34__internal_server_error__34__.mdwn
@@ -0,0 +1,28 @@
+### Please describe the problem.
+When I try to add a box.com cloud repository with the encryption option selected, I get an error that says "internal server error".
+
+### What steps will reproduce the problem?
+Anytime I try to set up a cloud repository with box.com (and presumably others, since this seems to be a problem with gpg (see log)) that is encrypted, I get this error.
+
+
+### What version of git-annex are you using? On what operating system?
+The operating system is Mac OS X 10.8.4, and the version of git-annex is 4.20130801-gc88bbc4.
+
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+(encryption setup) gpg: /Users/adamliter/.gnupg/gpg.conf:233: invalid auto-key-locate list
+30/Aug/2013:02:27:11 -0400 [Error#yesod-core] user error (gpg ["--quiet","--trust-model","always","--gen-random","--armor","1","512"] exited 2) @(yesod-core-1.1.8.3:Yesod.Internal.Core ./Yesod/Internal/Core.hs:550:5)
+
+# End of transcript or log.
+"""]]
+
+[[!meta title="OSX bundled gpg does not work with gpg.conf created by MacGPG"]]
+
+> [[done]]; I have updated the gpg to version 1.4.14 which
+> manages to build with the missing features.
+> --[[Joey]]
diff --git a/doc/bugs/Error_creating_encrypted_cloud_repository:___34__internal_server_error__34__/comment_1_9be1b577fa4d5fe9754845073fdf5d32._comment b/doc/bugs/Error_creating_encrypted_cloud_repository:___34__internal_server_error__34__/comment_1_9be1b577fa4d5fe9754845073fdf5d32._comment
new file mode 100644
index 000000000..ec0234c2d
--- /dev/null
+++ b/doc/bugs/Error_creating_encrypted_cloud_repository:___34__internal_server_error__34__/comment_1_9be1b577fa4d5fe9754845073fdf5d32._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="guilhem"
+ ip="129.16.20.209"
+ subject="comment 1"
+ date="2013-08-30T11:39:51Z"
+ content="""
+gpg complains about an invalid parameter for the `auto-key-locate` option, which is not passed by git-annex but found in your gpg.conf.
+
+What is on line 233 of `/Users/adamliter/.gnupg/gpg.conf`?
+"""]]
diff --git a/doc/bugs/Error_creating_encrypted_cloud_repository:___34__internal_server_error__34__/comment_2_0da0d68b646f2b38be6ecf7c0fe13743._comment b/doc/bugs/Error_creating_encrypted_cloud_repository:___34__internal_server_error__34__/comment_2_0da0d68b646f2b38be6ecf7c0fe13743._comment
new file mode 100644
index 000000000..c8a1db228
--- /dev/null
+++ b/doc/bugs/Error_creating_encrypted_cloud_repository:___34__internal_server_error__34__/comment_2_0da0d68b646f2b38be6ecf7c0fe13743._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkgH7oNEqNbh3g-N1-UHXuqleXaRYDgj1U"
+ nickname="Adam"
+ subject="comment 2"
+ date="2013-08-30T15:39:16Z"
+ content="""
+\"auto-key-locate cert pka ldap hkp://keys.gnupg.net\" is on line 233
+"""]]
diff --git a/doc/bugs/Error_creating_encrypted_cloud_repository:___34__internal_server_error__34__/comment_3_09c56f5574931f2ebe903069f0731160._comment b/doc/bugs/Error_creating_encrypted_cloud_repository:___34__internal_server_error__34__/comment_3_09c56f5574931f2ebe903069f0731160._comment
new file mode 100644
index 000000000..3cfa9a829
--- /dev/null
+++ b/doc/bugs/Error_creating_encrypted_cloud_repository:___34__internal_server_error__34__/comment_3_09c56f5574931f2ebe903069f0731160._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="guilhem"
+ ip="129.16.20.209"
+ subject="comment 3"
+ date="2013-08-30T16:09:58Z"
+ content="""
+Hmm, it looks like a perfectly valid list. Interesting.
+But regardless, gpg doesn't seem to like that line; what gpg version
+are you using? Also, does it work directly on the command-line
+(`gpg -a --gen-random 1 1`)?
+
+Have you tried to setup the remote without that line in the gpg.conf? Of
+course it wouldn't solve the core of the issue, but it's irrelevant for
+random data generation anyway (the same goes for `--trust-model`);
+perhaps this very command should be run with `--no-options`.
+"""]]
diff --git a/doc/bugs/Error_creating_encrypted_cloud_repository:___34__internal_server_error__34__/comment_4_0c127396e682ca6ced43aec7deeb0335._comment b/doc/bugs/Error_creating_encrypted_cloud_repository:___34__internal_server_error__34__/comment_4_0c127396e682ca6ced43aec7deeb0335._comment
new file mode 100644
index 000000000..6d2bb451a
--- /dev/null
+++ b/doc/bugs/Error_creating_encrypted_cloud_repository:___34__internal_server_error__34__/comment_4_0c127396e682ca6ced43aec7deeb0335._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkgH7oNEqNbh3g-N1-UHXuqleXaRYDgj1U"
+ nickname="Adam"
+ subject="comment 4"
+ date="2013-08-30T21:39:26Z"
+ content="""
+`gpg -a --gen-random 1 1` on the command line seems to work. At least, when I just ran it it returned `Xg==`. I'm not super familiar with running gpg on the command line, so I'm not sure if that is the desired result when running that.
+
+The version of gpg is GnuPG/MacGPG2 version 2.0.20.
+
+I just tried deleting that line from the config file, and now it worked. Would I be able to replace the line after setting up the repository, or is that going to create problems? I'm not entirely sure what that line does, and I'm a little wary about messing with it in case it breaks the functionality of any of the other things that I use gpg for, like email encryption.
+"""]]
diff --git a/doc/bugs/Error_creating_encrypted_cloud_repository:___34__internal_server_error__34__/comment_5_6bc3eadefde4750eec67a55de6651b2d._comment b/doc/bugs/Error_creating_encrypted_cloud_repository:___34__internal_server_error__34__/comment_5_6bc3eadefde4750eec67a55de6651b2d._comment
new file mode 100644
index 000000000..998d67055
--- /dev/null
+++ b/doc/bugs/Error_creating_encrypted_cloud_repository:___34__internal_server_error__34__/comment_5_6bc3eadefde4750eec67a55de6651b2d._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="guilhem"
+ ip="129.16.20.209"
+ subject="comment 5"
+ date="2013-08-30T22:51:56Z"
+ content="""
+OK (you just generated 1 byte of base64-encoded random data).
+No, I'm afraid git-annex will croak for each operation using gpg on your remote (which includes get, push, fsck, ...).
+
+This lines specifies how gpg automatically retrieves public keys when you get a signed message for instance. If you don't want to mix configurations, it is easy to create a git-annex-specific GnuPG home directory, but it requires you to point the `GNUPGHOME` to this alternative directory before starting git-annex.
+
+That said, other MacOSX users have encountered the same problem, and it was [[reported_to_be_solved_recently|/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option/]].
+"""]]
diff --git a/doc/bugs/Error_creating_encrypted_cloud_repository:___34__internal_server_error__34__/comment_6_263ab9c1483438b1717c8061ac81a2fa._comment b/doc/bugs/Error_creating_encrypted_cloud_repository:___34__internal_server_error__34__/comment_6_263ab9c1483438b1717c8061ac81a2fa._comment
new file mode 100644
index 000000000..65e6275da
--- /dev/null
+++ b/doc/bugs/Error_creating_encrypted_cloud_repository:___34__internal_server_error__34__/comment_6_263ab9c1483438b1717c8061ac81a2fa._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.140"
+ subject="comment 6"
+ date="2013-09-05T16:30:52Z"
+ content="""
+I have verified the gpg build I am currently using on OSX fails with that line. MacGPG doesn't but I had problems including it in the build before.
+If you remove the \"cert\" and the \"pkg\" from the line it will work. It seems I need to update the gpg build to support these DNS based key finding methods.
+"""]]
diff --git a/doc/bugs/Error_creating_encrypted_cloud_repository:___34__internal_server_error__34__/comment_7_eccc10990dff37584f8e60cd481a7140._comment b/doc/bugs/Error_creating_encrypted_cloud_repository:___34__internal_server_error__34__/comment_7_eccc10990dff37584f8e60cd481a7140._comment
new file mode 100644
index 000000000..35d9c71e8
--- /dev/null
+++ b/doc/bugs/Error_creating_encrypted_cloud_repository:___34__internal_server_error__34__/comment_7_eccc10990dff37584f8e60cd481a7140._comment
@@ -0,0 +1,26 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.140"
+ subject="comment 7"
+ date="2013-09-05T16:54:36Z"
+ content="""
+./configure says:
+
+<pre>
+checking whether the resolver is usable... no
+checking whether I can make the resolver usable with BIND_8_COMPAT... no
+
+configure:7918: gcc -o conftest -g -O2 conftest.c >&5
+Undefined symbols for architecture x86_64:
+ \"_res_9_dn_expand\", referenced from:
+ _main in ccsJFrZc.o
+ \"_res_9_dn_skipname\", referenced from:
+ _main in ccsJFrZc.o
+ \"_res_9_query\", referenced from:
+ _main in ccsJFrZc.o
+ld: symbol(s) not found for architecture x86_64
+collect2: ld returned 1 exit status
+</pre>
+
+So no DNS stuff until I can find a way to build a gpg for OSX that supports it.
+"""]]
diff --git a/doc/bugs/Error_creating_encrypted_cloud_repository:___34__internal_server_error__34__/comment_8_f897d20cbe5e0f3f58ce1a0bacad3d71._comment b/doc/bugs/Error_creating_encrypted_cloud_repository:___34__internal_server_error__34__/comment_8_f897d20cbe5e0f3f58ce1a0bacad3d71._comment
new file mode 100644
index 000000000..741c5342f
--- /dev/null
+++ b/doc/bugs/Error_creating_encrypted_cloud_repository:___34__internal_server_error__34__/comment_8_f897d20cbe5e0f3f58ce1a0bacad3d71._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkgH7oNEqNbh3g-N1-UHXuqleXaRYDgj1U"
+ nickname="Adam"
+ subject="comment 8"
+ date="2013-09-05T17:30:07Z"
+ content="""
+Hmm, thanks for looking into it. I appreciate it.
+"""]]
diff --git a/doc/bugs/Error_creating_remote_repository_using_ssh_on_OSX.mdwn b/doc/bugs/Error_creating_remote_repository_using_ssh_on_OSX.mdwn
new file mode 100644
index 000000000..cf7dcc88e
--- /dev/null
+++ b/doc/bugs/Error_creating_remote_repository_using_ssh_on_OSX.mdwn
@@ -0,0 +1,36 @@
+What steps will reproduce the problem?
+
+1. Click "Remote server: Set up a repository on a remote server using ssh."
+2. Enter hostname and different username than currently logged in user
+3. Click check this server
+
+
+What is the expected output?
+
+> I expected to see the next step in the remote repo creration process.
+
+What do you see instead?
+
+
+> Failed to ssh to the server. Transcript: ssh_askpass: exec(/usr/libexec/ssh-askpass): No such file or directory Permission denied, please try again. ssh_askpass: exec(/usr/libexec/ssh-askpass): No such file or directory Permission denied, please try again. ssh_askpass: exec(/usr/libexec/ssh-askpass): No such file or directory Permission denied (publickey,password).
+
+
+What version of git-annex are you using?
+
+> git-annex: Version: 3.20130114
+
+
+On what operating system?
+
+> OSX: 10.8.2
+
+
+
+Please provide any additional information below.
+
+> I mentioned "with a different username" because the assistant will allow me to create a remote repository on the same target machine when I use my normal username. I think this is most likely because I have a ssh-key setup for the account on the remote machine. However I do not want to assume anything and send you down the wrong OSX rabbit hole.
+
+> After a little research it seems that OSX does not have a ssh-askpass
+
+[[!tag /design/assistant/OSX]]
+[[!meta title="ssh-askpass not available on OSX"]]
diff --git a/doc/bugs/Error_creating_remote_repository_using_ssh_on_OSX/comment_1_559555934d79ae6be383063abcaae22e._comment b/doc/bugs/Error_creating_remote_repository_using_ssh_on_OSX/comment_1_559555934d79ae6be383063abcaae22e._comment
new file mode 100644
index 000000000..8b701250c
--- /dev/null
+++ b/doc/bugs/Error_creating_remote_repository_using_ssh_on_OSX/comment_1_559555934d79ae6be383063abcaae22e._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.3.125"
+ subject="comment 1"
+ date="2013-02-05T19:45:24Z"
+ content="""
+It should be possible to use SSHPassKey as described here: <http://benno.id.au/docs/ssh_macosx.pml>
+
+However, this all seems pretty crummy, and so perhaps it would be worth it for the webapp to do its own ssh password prompting when setting up a remote.
+"""]]
diff --git a/doc/bugs/Error_creating_remote_repository_using_ssh_on_OSX/comment_2_a9f4f9db042ab6f6c15d6954651971b2._comment b/doc/bugs/Error_creating_remote_repository_using_ssh_on_OSX/comment_2_a9f4f9db042ab6f6c15d6954651971b2._comment
new file mode 100644
index 000000000..f0d25d778
--- /dev/null
+++ b/doc/bugs/Error_creating_remote_repository_using_ssh_on_OSX/comment_2_a9f4f9db042ab6f6c15d6954651971b2._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="Peng"
+ ip="171.37.79.254"
+ subject="Found an easy solution"
+ date="2013-06-15T03:34:52Z"
+ content="""
+Just install this script on OS X, and you'll get the ssh-askpass command.
+
+https://github.com/markcarver/mac-ssh-askpass
+
+Tested working successfully on OS X 10.8.3.
+"""]]
diff --git a/doc/bugs/Error_creating_remote_repository_using_ssh_on_OSX/comment_3_55a496d0a0be80ba723b17bf9faa3bc0._comment b/doc/bugs/Error_creating_remote_repository_using_ssh_on_OSX/comment_3_55a496d0a0be80ba723b17bf9faa3bc0._comment
new file mode 100644
index 000000000..e22ca1ff9
--- /dev/null
+++ b/doc/bugs/Error_creating_remote_repository_using_ssh_on_OSX/comment_3_55a496d0a0be80ba723b17bf9faa3bc0._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnb4NsPsSSHTniueRuVnBzTLrDiDqBZIfY"
+ nickname="Doug"
+ subject="Same problem but still does not work with askpass installed"
+ date="2013-07-24T18:19:25Z"
+ content="""
+So, I got askpass installed and I'm still getting the same error as everybody else. It's a strange thing as I have my public key dumped on the remote server and I can log in fine manually. It's an empty passphrase so there shouldn't be any prompting going on.
+"""]]
diff --git a/doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__.mdwn b/doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__.mdwn
new file mode 100644
index 000000000..d0b2c1538
--- /dev/null
+++ b/doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__.mdwn
@@ -0,0 +1,31 @@
+Running 3.20121112 on Debian Squeeze.
+
+Since adding a certain directory of files (just a bunch of PDFs) yesterday I am getting errors when I try to use `git annex drop .` when the files aren't present, rather doing nothing or saying 'ok', as it used to do/should do. The errors are of the form `git-annex: fd:10: hGetLine: end of file` and sometimes of the form `git-annex: fd:17: hFlush: resource vanished (Broken pipe)`. In my `daemon.log`, I have the errors
+
+ (scanning...) Already up-to-date.
+ Already up-to-date.
+ TransferScanner crashed: fd:26: hGetLine: end of file
+ Already up-to-date.
+ (started...) git-annex: fd:25: hGetLine: end of file
+ git-annex: fd:24: hFlush: resource vanished (Broken pipe)
+ git-annex: fd:24: hFlush: resource vanished (Broken pipe)
+ git-annex: fd:24: hFlush: resource vanished (Broken pipe)
+ git-annex: fd:24: hFlush: resource vanished (Broken pipe)
+ git-annex: fd:24: hFlush: resource vanished (Broken pipe)
+ git-annex: fd:24: hFlush: resource vanished (Broken pipe)
+ git-annex: fd:24: hFlush: resource vanished (Broken pipe)
+ git-annex: fd:24: hFlush: resource vanished (Broken pipe)
+ git-annex: fd:24: hFlush: resource vanished (Broken pipe)
+ git-annex: fd:24: hFlush: resource vanished (Broken pipe)
+ git-annex: fd:24: hFlush: resource vanished (Broken pipe)
+ [many more repetitions]
+
+If I `git annex get` the files and then drop them again, a further attempt at a drop gives all these errors again.
+
+> So in summary, a git-annex built against the old version of git in
+> debian stable fails to work with a newer version of git, and rebuilding
+> fixes it. FWIW, the git-annex backport to stable does not have this
+> problem, because it checks git version at runtime. But I want to avoid
+> the overhead of that check in git-annex mainline, because this old git
+> version is well, very old and increasingly unlikely to be used. So,
+> I don't think any changes to git-annex are warrented. [[done]] --[[Joey]]
diff --git a/doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_10_8742f7ac27b5f4ad6261d04a174a691c._comment b/doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_10_8742f7ac27b5f4ad6261d04a174a691c._comment
new file mode 100644
index 000000000..921a20024
--- /dev/null
+++ b/doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_10_8742f7ac27b5f4ad6261d04a174a691c._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.14.162"
+ subject="comment 10"
+ date="2012-12-06T22:00:45Z"
+ content="""
+Can you show me a transcript of git-check-attr? This is sounding like a git bug.
+
+(The build error is due to too old a version of yesod.)
+"""]]
diff --git a/doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_11_b8e720340000537de6713c49b7733b2f._comment b/doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_11_b8e720340000537de6713c49b7733b2f._comment
new file mode 100644
index 000000000..db964e58c
--- /dev/null
+++ b/doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_11_b8e720340000537de6713c49b7733b2f._comment
@@ -0,0 +1,21 @@
+[[!comment format=mdwn
+ username="spwhitton"
+ ip="163.1.167.50"
+ subject="comment 11"
+ date="2012-12-06T22:17:37Z"
+ content="""
+Upgrading yesod then git-annex removes the problem I was seeing. Thanks for your help with that. Here is a `git-check-attr` session:
+
+ backups $ git check-attr --stdin annex.backend annex.numcopies --
+ athena-etc.tar.gz
+ athena-etc.tar.gz: annex.backend: unspecified
+ athena-etc.tar.gz: annex.numcopies: 2
+ athena-mail.gz
+ athena-mail.gz: annex.backend: unspecified
+ athena-mail.gz: annex.numcopies: 2
+ athena-web.tar.gz
+ athena-web.tar.gz: annex.backend: unspecified
+ athena-web.tar.gz: annex.numcopies: 2
+ [^D pressed]
+ backups $
+"""]]
diff --git a/doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_1_489fa3a717519cd5d8b4c1a9d143d8c6._comment b/doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_1_489fa3a717519cd5d8b4c1a9d143d8c6._comment
new file mode 100644
index 000000000..902464317
--- /dev/null
+++ b/doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_1_489fa3a717519cd5d8b4c1a9d143d8c6._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.253.113"
+ subject="comment 1"
+ date="2012-12-06T15:04:12Z"
+ content="""
+Can you run it with --debug ?
+"""]]
diff --git a/doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_2_b0796d3b1913e1b6f7b34d75a591be42._comment b/doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_2_b0796d3b1913e1b6f7b34d75a591be42._comment
new file mode 100644
index 000000000..696bdb5aa
--- /dev/null
+++ b/doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_2_b0796d3b1913e1b6f7b34d75a591be42._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="spwhitton"
+ ip="163.1.167.50"
+ subject="comment 2"
+ date="2012-12-06T15:13:02Z"
+ content="""
+Sure, I've added --debug to the assistant autostart file and am running `git annex --debug drop`. For the first type of error given above I get output like
+
+ [2012-12-06 15:08:50 GMT] read: git [\"--git-dir=/home/swhitton/var/.git\",\"--work-tree=/home/swhitton/var\",\"ls-files\",\"--cached\",\"-z\",\"--\",\".\"]
+ [2012-12-06 15:08:50 GMT] chat: git [\"--git-dir=/home/swhitton/var/.git\",\"--work-tree=/home/swhitton/var\",\"check-attr\",\"-z\",\"--stdin\",\"annex.backend\",\"annex.numcopies\",\"--\"]
+
+ git-annex: fd:10: hGetLine: end of file
+ failed
+
+and for the \"resource vanished\" errors I get no further output. There is also nothing further in `daemon.log`.
+"""]]
diff --git a/doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_3_d8ca17ccaa5ee48d590736af8e77d88a._comment b/doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_3_d8ca17ccaa5ee48d590736af8e77d88a._comment
new file mode 100644
index 000000000..c59d60047
--- /dev/null
+++ b/doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_3_d8ca17ccaa5ee48d590736af8e77d88a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.253.113"
+ subject="comment 3"
+ date="2012-12-06T15:21:25Z"
+ content="""
+If you run `git annex find` instead of `git annex drop`, does it have any errors?
+"""]]
diff --git a/doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_4_aa7a690aaf75d21f52051a31d7fce70e._comment b/doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_4_aa7a690aaf75d21f52051a31d7fce70e._comment
new file mode 100644
index 000000000..a1baa47cd
--- /dev/null
+++ b/doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_4_aa7a690aaf75d21f52051a31d7fce70e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="spwhitton"
+ ip="163.1.167.50"
+ subject="comment 4"
+ date="2012-12-06T15:23:02Z"
+ content="""
+No, `git annex find --debug .` outputs just `[2012-12-06 15:22:14 GMT] read: git [\"--git-dir=/home/swhitton/var/.git\",\"--work-tree=/home/swhitton/var\",\"ls-files\",\"--cached\",\"-z\",\"--\",\".\"]`.
+"""]]
diff --git a/doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_5_dc235dc2d024b7f340721bb578630e00._comment b/doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_5_dc235dc2d024b7f340721bb578630e00._comment
new file mode 100644
index 000000000..af7750771
--- /dev/null
+++ b/doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_5_dc235dc2d024b7f340721bb578630e00._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.253.113"
+ subject="comment 5"
+ date="2012-12-06T15:26:27Z"
+ content="""
+What version of git do you have installed?
+
+How did you install this version of git-annex on squeeze?
+"""]]
diff --git a/doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_6_5d1e6ea5b5725c773acc6e288add812c._comment b/doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_6_5d1e6ea5b5725c773acc6e288add812c._comment
new file mode 100644
index 000000000..e208b3169
--- /dev/null
+++ b/doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_6_5d1e6ea5b5725c773acc6e288add812c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="spwhitton"
+ ip="163.1.167.50"
+ subject="comment 6"
+ date="2012-12-06T15:29:46Z"
+ content="""
+git is at 1.7.10.4 which I got from backports. I only upgraded a couple of days ago (to solve a strange error I was having with cloning to a removable drive); sorry for not mentioning that. I installed git-annex using cabal run as root.
+"""]]
diff --git a/doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_7_6389b4f03ebc916358bc6674398d70c4._comment b/doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_7_6389b4f03ebc916358bc6674398d70c4._comment
new file mode 100644
index 000000000..9d61f4ac0
--- /dev/null
+++ b/doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_7_6389b4f03ebc916358bc6674398d70c4._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.253.113"
+ subject="comment 7"
+ date="2012-12-06T15:39:26Z"
+ content="""
+The problem seems to involve git check-attr exiting unexpectedly. Does this happen only in a specific directory of files, or can you reproduce it elsewhere?
+
+You may be able to reproduce it exiting by running:
+
+`git check-attr --stdin annex.backend annex.numcopies --`
+
+And then entering filenames, pressing enter, and it should answer back with two attribute values and keep running.
+"""]]
diff --git a/doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_8_bcacc9fb3751042968118ebe33802e27._comment b/doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_8_bcacc9fb3751042968118ebe33802e27._comment
new file mode 100644
index 000000000..8e4e5cf91
--- /dev/null
+++ b/doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_8_bcacc9fb3751042968118ebe33802e27._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.253.113"
+ subject="comment 8"
+ date="2012-12-06T15:41:31Z"
+ content="""
+Have you rebuilt git-annex since you upgraded git?
+
+This seems most likely to be the problem; the version of git in squeeze requires git-annex behave differently when using git check-attr, and if you have a version of git-annex built for it, it will do things the new git dislikes.
+"""]]
diff --git a/doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_9_6d4c9f0e133ebd94fc11346df446402e._comment b/doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_9_6d4c9f0e133ebd94fc11346df446402e._comment
new file mode 100644
index 000000000..a48e98ebc
--- /dev/null
+++ b/doc/bugs/Error_when_dropping___34__hGetLine:_end_of_file__34__/comment_9_6d4c9f0e133ebd94fc11346df446402e._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="spwhitton"
+ ip="163.1.167.50"
+ subject="comment 9"
+ date="2012-12-06T21:37:52Z"
+ content="""
+Yes, running git-attr like that does indeed produce the problem. I attempted to rebuild git-annex using cabal, but the build failed with the following error:
+
+ [273 of 290] Compiling Assistant.WebApp.Configurators.Local ( Assistant/WebApp/Configurators/Local.hs, dist/build/git-annex/git-annex-tmp/Assistant/WebApp/Configurators/Local.o )
+
+ Assistant/WebApp/Configurators/Local.hs:55:11:
+ `fieldEnctype' is not a (visible) field of constructor `Field'
+ cabal: Error: some packages failed to install:
+ git-annex-3.20121127.1 failed during the building phase. The exception was:
+ ExitFailure 1
+"""]]
diff --git a/doc/bugs/Error_when_moving_annexed_file_to_a_.gitignored_location.mdwn b/doc/bugs/Error_when_moving_annexed_file_to_a_.gitignored_location.mdwn
new file mode 100644
index 000000000..34d05c0b1
--- /dev/null
+++ b/doc/bugs/Error_when_moving_annexed_file_to_a_.gitignored_location.mdwn
@@ -0,0 +1,21 @@
+I just noticed that if you move a git-annex symlink to a location ignored by git, it simply works. Upon committing that change, however, part of git-annex's `fix` function apparently tries to `git-add` the symlink. This fails because the new, ignored location requires a `git-add --force`.
+
+Considering that git proper doesn't fail or warn, I think git-annex shouldn't either.
+
+This is the error message:
+
+ $ git mv annexed-file ignored-dir/
+ $ git commit
+ fix ignored-dir/annexed-file ok
+ (Recording state in git...)
+ The following paths are ignored by one of your .gitignore files:
+ ignored-dir
+ Use -f if you really want to add them.
+ fatal: no files added
+ Command xargs ["-0","git","--git-dir=/home/[...]/repo/.git","--work-tree=/home/[...]/repo","add","--"] failed; exit code 123
+
+ git-annex: user error (Command xargs ["-0","git","--git-dir=/home/[...]/repo/.git","--work-tree=/home/[...]/repo","add","--"] failed; exit code 123)
+ failed
+ git-annex: 1 failed
+
+> Weird edge case.. ok, fixed. [[done]] --[[Joey]]
diff --git a/doc/bugs/Error_when_moving_annexed_file_to_a_.gitignored_location/comment_1_b524e70156e8bc1219d5c6741974ad99._comment b/doc/bugs/Error_when_moving_annexed_file_to_a_.gitignored_location/comment_1_b524e70156e8bc1219d5c6741974ad99._comment
new file mode 100644
index 000000000..6b741e85e
--- /dev/null
+++ b/doc/bugs/Error_when_moving_annexed_file_to_a_.gitignored_location/comment_1_b524e70156e8bc1219d5c6741974ad99._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlq4ClC5EMN1Vq1DpWXAqP5TiDnCK1mSfk"
+ nickname="Jonas"
+ subject="Happens with import, too"
+ date="2013-11-24T23:24:09Z"
+ content="""
+This happens to me when using git annex import, too (on version 4.20131106)
+
+ (Recording state in git...)
+ The following paths are ignored by one of your .gitignore files:
+ path/to/some/directory/.svn
+ Use -f if you really want to add them.
+ fatal: no files added
+
+ git-annex: user error (xargs [\"-0\",\"git\",\"--git-dir=/path/to/annex/.git\",\"--work-tree=/path/to/annex\",\"add\",\"--\"] exited 123)
+failed
+
+"""]]
diff --git a/doc/bugs/Error_when_moving_annexed_file_to_a_.gitignored_location/comment_2_ff7349c396d1249204d621e71f6a7a52._comment b/doc/bugs/Error_when_moving_annexed_file_to_a_.gitignored_location/comment_2_ff7349c396d1249204d621e71f6a7a52._comment
new file mode 100644
index 000000000..2ee7f79b6
--- /dev/null
+++ b/doc/bugs/Error_when_moving_annexed_file_to_a_.gitignored_location/comment_2_ff7349c396d1249204d621e71f6a7a52._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.64"
+ subject="comment 2"
+ date="2013-11-26T20:04:23Z"
+ content="""
+This bug was fixed, and closed 2 years ago. Posting a comment about another, related problem is not very useful.
+
+Yes, git annex import does not finish importing files if you've configured .gititnore to not allow those files to be added. If you need to do that, you could use `git annex import --force`, which will add the files despite the gitignore.
+"""]]
diff --git a/doc/bugs/Error_when_moving_annexed_file_to_a_.gitignored_location/comment_4_4bc7d4c51faea3fdafc977cb66b7f73a._comment b/doc/bugs/Error_when_moving_annexed_file_to_a_.gitignored_location/comment_4_4bc7d4c51faea3fdafc977cb66b7f73a._comment
new file mode 100644
index 000000000..a3a6fc10a
--- /dev/null
+++ b/doc/bugs/Error_when_moving_annexed_file_to_a_.gitignored_location/comment_4_4bc7d4c51faea3fdafc977cb66b7f73a._comment
@@ -0,0 +1,26 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlq4ClC5EMN1Vq1DpWXAqP5TiDnCK1mSfk"
+ nickname="Jonas"
+ subject="comment 4"
+ date="2013-11-27T17:36:39Z"
+ content="""
+Sorry, my bug triaging skills are limited. This one happened to have exactly the same error message...
+
+This might again be the wrong thread, but... how does git annex decide which files to ignore? In particular, it seems not always to agree with git:
+
+ $ cd /tmp
+ $ mkdir annex
+ $ cd annex
+ $ git init
+ $ git annex init \"Testing annex in /tmp\"
+ $ echo \"This file is hidden\" > .hidden_file
+ $ git status
+ shows .hidden_file as \"untracked\"
+ $ git annex add .
+ does nothing
+ $ git annex add --force .
+ does nothing, either
+ $ git add .
+ adds the file as expected
+
+"""]]
diff --git a/doc/bugs/Error_while_adding_a_file___34__createSymbolicLink:_already_exists__34__.mdwn b/doc/bugs/Error_while_adding_a_file___34__createSymbolicLink:_already_exists__34__.mdwn
new file mode 100644
index 000000000..21293af54
--- /dev/null
+++ b/doc/bugs/Error_while_adding_a_file___34__createSymbolicLink:_already_exists__34__.mdwn
@@ -0,0 +1,46 @@
+I'm importing a directory where some files are hard links of each other.
+
+This is confusing git-annex. Here's a small test of that:
+
+<pre>
+paulproteus@pathi:/tmp$ mkdir annex-test
+paulproteus@pathi:/tmp$ cd annex-test
+paulproteus@pathi:/tmp/annex-test$ git init
+Initialized empty Git repository in /tmp/annex-test/.git/
+paulproteus@pathi:/tmp/annex-test$ git annex init testing
+init testing ok
+paulproteus@pathi:/tmp/annex-test$ echo '* annex.backend=SHA1' >> .gitattributes
+paulproteus@pathi:/tmp/annex-test$ git commit .gitattributes -m 'Default to sha1'
+[master dd54b41] Default to sha1
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+paulproteus@pathi:/tmp/annex-test$ echo "Look at me" > file1
+paulproteus@pathi:/tmp/annex-test$ cp -l file1 file2
+paulproteus@pathi:/tmp/annex-test$ git annex add file1
+add file1 (checksum...) ok
+(Recording state in git...)
+paulproteus@pathi:/tmp/annex-test$ git commit -m 'So far, so good'
+[master eb43084] So far, so good
+ 2 files changed, 2 insertions(+), 0 deletions(-)
+ create mode 100644 .git-annex/9a3/f1f/SHA1-s11--b9c599d64212934582d676c722cf3ec61f60e09c.log
+ create mode 120000 file1
+paulproteus@pathi:/tmp/annex-test$ git annex add file2
+add file2 (checksum...)
+ git-annex: .git/annex/objects/PM/7p/SHA1-s11--b9c599d64212934582d676c722cf3ec61f60e09c/SHA1-s11--b9c599d64212934582d676c722cf3ec61f60e09c: createSymbolicLink: already exists (File exists)
+git-annex: 1 failed
+paulproteus@pathi:/tmp/annex-test$
+</pre>
+
+When trying to make a small test case for this bug, I noticed that if file1 and file2 have the same contents but are not hard links of each other, they both get annexed just fine.
+
+I think the right behavior here is to annex file2 just fine, as if they weren't hard links before.
+
+
+-- Asheesh.
+
+> The same thing happens anytime the key for a file collides with a key
+> already in the annex, AFAICS. (Including when the files have the same
+> content but are not hard links... unless you're using WORM backend.)
+>
+> I've fixed this bug. The first file in wins. See commit for some
+> interesting discussion about why it should not check for hash collisions
+> in this situation. [[done]] --[[Joey]]
diff --git a/doc/bugs/Every_new_file_gets_symlinked_to_a_git_object.mdwn b/doc/bugs/Every_new_file_gets_symlinked_to_a_git_object.mdwn
new file mode 100644
index 000000000..9788c8767
--- /dev/null
+++ b/doc/bugs/Every_new_file_gets_symlinked_to_a_git_object.mdwn
@@ -0,0 +1,78 @@
+### Please describe the problem.
+Every file I add to a watched repository (by git-annex assistant) becomes symlinked, and sub-subsequently write protected.
+
+Sorry if I'm missing something obvious.
+
+### What steps will reproduce the problem?
+1) Fresh install
+2) create directory, init repo and git-annex
+3) git annex assistant
+4) add a file
+5) ls -lsa to see the symlinked file
+6) trying to write to the file throws a write-protected error
+
+
+### What version of git-annex are you using? On what operating system?
+git-annex version: 4.20130725-g8140f7c
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP
+local repository version: 3
+default repository version: 3
+supported repository versions: 3 4
+upgrade supported from repository versions: 0 1 2
+
+Using the generic linux distribution with ./runshell on Ubuntu 13.04 (I saw this same behaviour from the ubuntu package, i.e. apt-get install git-annex)
+
+
+### Please provide any additional information below.
+
+Here is the output from my ls -lsa
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+ 4 drwxrwxr-x 3 jetaggart jetaggart 4096 Jul 27 20:38 .
+16 drwx------ 60 jetaggart jetaggart 16384 Jul 27 20:44 ..
+ 4 drwxrwxr-x 7 jetaggart jetaggart 4096 Jul 27 20:38 .git
+ 4 lrwxrwxrwx 1 jetaggart jetaggart 188 Jul 27 20:38 another.org -> .git/annex/objects/Qm/j7/SHA256E-s11--9484d4be897ca66ad4c9bbf299d12adfe37e089bbca1daecbbb49c375a9cf1e9.org/SHA256E-s11--9484d4be897ca66ad4c9bbf299d12adfe37e089bbca1daecbbb49c375a9cf1e9.org
+ 4 lrwxrwxrwx 1 jetaggart jetaggart 186 Jul 27 20:33 blah.org -> .git/annex/objects/kj/q5/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.org/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.org
+12 -rw-rw-r-- 1 jetaggart jetaggart 119 Jul 27 20:37 todo.org
+
+
+# End of transcript or log.
+"""]]
+
+Here is the daemon.log
+
+[[!format sh """
+
+[2013-07-27 20:32:55 BST] main: starting assistant version 4.20130725-g8140f7c
+(scanning...) [2013-07-27 20:32:55 BST] Watcher: Performing startup scan
+(started...)
+[2013-07-27 20:33:52 BST] Committer: Adding blah.org
+add blah.org (checksum...) ok
+[2013-07-27 20:33:52 BST] Committer: Committing changes to git
+(Recording state in git...)
+(Recording state in git...)
+[2013-07-27 20:35:59 BST] Committer: Committing changes to git
+(Recording state in git...)
+[2013-07-27 20:36:01 BST] Committer: Committing changes to git
+(Recording state in git...)
+[2013-07-27 20:37:52 BST] Committer: Committing changes to git
+(Recording state in git...)
+[2013-07-27 20:37:55 BST] Committer: Committing changes to git
+(Recording state in git...)
+[2013-07-27 20:38:44 BST] Committer: Committing changes to git
+(Recording state in git...)
+[2013-07-27 20:38:46 BST] Committer: Adding another.org
+add another.org (checksum...) ok
+[2013-07-27 20:38:46 BST] Committer: Committing changes to git
+(Recording state in git...)
+(Recording state in git...)
+[2013-07-27 20:38:51 BST] Committer: Committing changes to git
+(Recording state in git...)
+[2013-07-27 20:38:56 BST] Committer: Committing changes to git
+(Recording state in git...)
+
+# End of transcript or log.
+"""]]
+
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/Every_new_file_gets_symlinked_to_a_git_object/comment_1_d4e7ed56b16494a95e6c904c746cc91f._comment b/doc/bugs/Every_new_file_gets_symlinked_to_a_git_object/comment_1_d4e7ed56b16494a95e6c904c746cc91f._comment
new file mode 100644
index 000000000..e9dfda6fc
--- /dev/null
+++ b/doc/bugs/Every_new_file_gets_symlinked_to_a_git_object/comment_1_d4e7ed56b16494a95e6c904c746cc91f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.110"
+ subject="comment 1"
+ date="2013-07-27T19:55:38Z"
+ content="""
+This is how git-annex is intended to work in indirect mode. You must have created your repository by hand, and not enabled [[direct_mode]]. Stop the assistant and run `git annex direct`
+"""]]
diff --git a/doc/bugs/Every_new_file_gets_symlinked_to_a_git_object/comment_2_656b2a2cc44e9102c86bdd57045549d5._comment b/doc/bugs/Every_new_file_gets_symlinked_to_a_git_object/comment_2_656b2a2cc44e9102c86bdd57045549d5._comment
new file mode 100644
index 000000000..81323b16f
--- /dev/null
+++ b/doc/bugs/Every_new_file_gets_symlinked_to_a_git_object/comment_2_656b2a2cc44e9102c86bdd57045549d5._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmhGq_ii5HaDkp9nx2m9qIMe-xxI4HV5wo"
+ nickname="Jeff"
+ subject="comment 2"
+ date="2013-07-27T20:05:57Z"
+ content="""
+I did create it by hand, thanks for the quick feedback, sorry to waste your time.
+
+I'll stick to the forum unless I'm sure it's a bug :)
+"""]]
diff --git a/doc/bugs/Failed_to_make_repository___40__calling_nonexistant_shell__41__.mdwn b/doc/bugs/Failed_to_make_repository___40__calling_nonexistant_shell__41__.mdwn
new file mode 100644
index 000000000..634f3e501
--- /dev/null
+++ b/doc/bugs/Failed_to_make_repository___40__calling_nonexistant_shell__41__.mdwn
@@ -0,0 +1,28 @@
+### Please describe the problem.
+
+I get this error message:
+
+ Failed to make repository
+
+Something went wrong setting up the repository on the remote server.
+
+Transcript:
+
+/opt/git-annex.linux/runshell: line 73: /home/annex/sh -c 'mkdir -p '"'"'annex'"'"'&&cd '"'"'annex'"'"'&&if [ ! -d .git ]; then git init --bare --shared; fi&&git annex init&&mkdir -p ~/.ssh&&if [ ! -e ~/.ssh/git-annex-shell ]; then (echo '"'"'#!/bin/sh'"'"';echo '"'"'set -e'"'"';echo '"'"'if [ "x$SSH_ORIGINAL_COMMAND" != "x" ]; then'"'"';echo '"'"'exec git-annex-shell -c "$SSH_ORIGINAL_COMMAND"'"'"';echo '"'"'else'"'"';echo '"'"'exec git-annex-shell -c "$@"'"'"';echo '"'"'fi'"'"') > ~/.ssh/git-annex-shell; fi&&chmod 700 ~/.ssh/git-annex-shell&&touch ~/.ssh/authorized_keys&&chmod 600 ~/.ssh/authorized_keys&&echo '"'"'command="GIT_ANNEX_SHELL_DIRECTORY='"'"'"'"'"'"'"'"'annex'"'"'"'"'"'"'"'"' ~/.ssh/git-annex-shell",no-agent-forwarding,no-port-forwarding,no-X11-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA1RQLCJP/gY62xxTOHa4PlZSlSWD2kWBC2+o27SBpBaCVibFfxNKP+1CAgzbyzVygpE0XUXxDOA8dnrq7vPHkkdIlYUZ8JQxTO/zaVVRlzryhWb8QOjEE3ZG0CF+ZQVu14q/M/T4qZm1mtXBCIZMs1wpwTr9dRdf7e/5q5hHROd5sRj+v0PhdiyZ8e6egoq1gFAvspUF1VC74PvZwZ2NKd1s0iGOGGYvoD/nWGCeBUQzMcGk56243zI54tOcDePdZJnd7iIn8FHGprr9yGhc3KYKppWmG7vQU+DhO607FiVnW5aMWjz/msmQidCceIFvnmLFWSDQ5ZNdGVUvHlT9kQQ== p264360@pales
+'"'"' >>~/.ssh/authorized_keys': No such file or directory
+
+### What steps will reproduce the problem?
+
+I made a user annex on my server and set its shell to /opt/git-annex.linux/runshell, then used the webapp on my desktop PC to try and add a remote git repository on my server.
+
+### What version of git-annex are you using? On what operating system?
+
+The latest tarball: git-annex-standalone-amd64.tar.gz 2013-07-09 14:24 19M
+
+Ubuntu 10.04 on both desktop and server.
+
+### Please provide any additional information below.
+
+The problem seems to be runshell trying to call /home/annex/sh, which does not exist. Why would it do that?
+
+> [[done]]
diff --git a/doc/bugs/Failed_to_make_repository___40__calling_nonexistant_shell__41__/comment_1_fb8a379ed7f4b88bd55245ce5b18042c._comment b/doc/bugs/Failed_to_make_repository___40__calling_nonexistant_shell__41__/comment_1_fb8a379ed7f4b88bd55245ce5b18042c._comment
new file mode 100644
index 000000000..3a225a074
--- /dev/null
+++ b/doc/bugs/Failed_to_make_repository___40__calling_nonexistant_shell__41__/comment_1_fb8a379ed7f4b88bd55245ce5b18042c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.90"
+ subject="comment 1"
+ date="2013-07-16T19:30:55Z"
+ content="""
+That's not really how you're meant to use the standalone tarball. Just untar it somewhere, and add that directory to PATH (eg, in `~/.bash_profile`).
+"""]]
diff --git a/doc/bugs/Fails_to_create_remote_repo_if_no_global_email_set.mdwn b/doc/bugs/Fails_to_create_remote_repo_if_no_global_email_set.mdwn
new file mode 100644
index 000000000..ce9f5c3da
--- /dev/null
+++ b/doc/bugs/Fails_to_create_remote_repo_if_no_global_email_set.mdwn
@@ -0,0 +1,55 @@
+### Please describe the problem.
+Trying to create repo on ssh server failed because git didn't know my email.
+
+There were other issues I encountered:
+
+ - While connecting to the server assistant says that there will be a password prompt, but doesn't tell that one should expect it to appear in the terminal.
+
+ - When creating keys it says that I will be prompted for key password again, but it asks for password to remote server (I understood it wanted a password for its new key pair).. there is no telling for what those password prompts in terminal are for
+
+ - It actually requires password for remote server multiple times before it starts to use its own keys
+
+ - When failed to test the server or create the repo there the "Retry" button doesn't work (does nothing)
+
+ - Maybe it should strip leading ~ from repo name?
+
+ - Local pairing with annex 3.20121112ubuntu4 from Ubuntu 13.04 sort of works, but not quite.. it syncs the files, but assistant on Ubuntu doesn't show the name for repo on Gentoo (matching versions are important?)
+
+ - When pairing it doesn't check if localhost has running sshd
+
+ - I think that was the reason why progress bars were showing pending transfers even after the status message about syncing was green after starting sshd (synced, already up-to-date)
+
+### What steps will reproduce the problem?
+Create repo on remote ssh server without global git settings.
+
+### What version of git-annex are you using? On what operating system?
+git-annex-4.20130601, Gentoo amd64
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+Initialized empty shared Git repository in /home/reinis/~/Annex/Lit/
+init
+*** Please tell me who you are.
+
+Run
+
+ git config --global user.email "you@example.com"
+ git config --global user.name "Your Name"
+
+to set your account's default identity.
+Omit --global to set the identity only in this repository.
+
+fatal: unable to auto-detect email address (got 'reinis@RD-HC.(none)')
+
+git-annex: user error (git ["--git-dir=/home/me/~/Annex/Lit","commit-tree","4b825dc642cb6eb9a060e54bf8d69288fbee4904"] efailed
+xited 128)
+git-annex: init: 1 failed
+
+
+# End of transcript or log.
+"""]]
+
+> [[done]]; I've made git-annex detect such broken systems and configure them so git will work. (sigh!) --[[Joey]]
diff --git a/doc/bugs/Feature_request:___34__quvi__34___flag.mdwn b/doc/bugs/Feature_request:___34__quvi__34___flag.mdwn
new file mode 100644
index 000000000..950aad0fc
--- /dev/null
+++ b/doc/bugs/Feature_request:___34__quvi__34___flag.mdwn
@@ -0,0 +1,14 @@
+### Please describe the problem.
+git-annex v4.20130827 can't be built on ARM. Technically it's vector that can't be built due to a lack of Template Haskell compilers for this architecture. Vector is a dependency of aeson, which is a dependency of git-annex, which therefore fails to compile.
+
+The only functionality that relies on aeson is, to my knowledge, quvi. Thus my feature request: If you were to introduce a flag to switch quvi support on or off, ARM users like me could circumvent the aeson dependency at build time. In this case we weren't stuck with 4.20130815 (the latest version to not depend on aeson) and could use current and future versions of git-annex. I would appreciate it.
+
+
+### What steps will reproduce the problem?
+See above.
+
+
+### What version of git-annex are you using? On what operating system?
+I'm running Raspbian Wheezy on a Raspberry Pi. The git-annex version to be built is 4.20130827.
+
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/Feature_request:___34__quvi__34___flag/comment_1_908c38024fd252328566034608c2dec3._comment b/doc/bugs/Feature_request:___34__quvi__34___flag/comment_1_908c38024fd252328566034608c2dec3._comment
new file mode 100644
index 000000000..a5668f664
--- /dev/null
+++ b/doc/bugs/Feature_request:___34__quvi__34___flag/comment_1_908c38024fd252328566034608c2dec3._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.255.110"
+ subject="comment 1"
+ date="2013-09-09T05:25:39Z"
+ content="""
+Sorry, I didn't consider this dependency chain.
+
+FWIW, it is possible to build aeson without TH. See `standalone/android/haskell-patches/aeson_0.6.1.0_0001-disable-TH.patch` in the git-annex source tree.
+
+However, I will add a flag.
+"""]]
diff --git a/doc/bugs/Feature_request:___34__quvi__34___flag/comment_2_4b6822fe91aa865f2ac1297a3daa3fca._comment b/doc/bugs/Feature_request:___34__quvi__34___flag/comment_2_4b6822fe91aa865f2ac1297a3daa3fca._comment
new file mode 100644
index 000000000..ab4494c19
--- /dev/null
+++ b/doc/bugs/Feature_request:___34__quvi__34___flag/comment_2_4b6822fe91aa865f2ac1297a3daa3fca._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.255.110"
+ subject="comment 2"
+ date="2013-09-09T05:44:48Z"
+ content="""
+Also, note that libghc-aeson-dev is available for arm in Debian.
+"""]]
diff --git a/doc/bugs/Feature_request:___34__quvi__34___flag/comment_3_c72ef77e76b1c99b5e0c78d0742080e7._comment b/doc/bugs/Feature_request:___34__quvi__34___flag/comment_3_c72ef77e76b1c99b5e0c78d0742080e7._comment
new file mode 100644
index 000000000..bbbd5b597
--- /dev/null
+++ b/doc/bugs/Feature_request:___34__quvi__34___flag/comment_3_c72ef77e76b1c99b5e0c78d0742080e7._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="RaspberryPie"
+ ip="91.213.8.236"
+ subject="comment 3"
+ date="2013-09-09T05:52:48Z"
+ content="""
+Thanks for the quick answer, I will give these two options a try. A flag will be even better, though.
+"""]]
diff --git a/doc/bugs/Feature_request:___34__quvi__34___flag/comment_4_6092695d6afb1608447afe6f86e6fb83._comment b/doc/bugs/Feature_request:___34__quvi__34___flag/comment_4_6092695d6afb1608447afe6f86e6fb83._comment
new file mode 100644
index 000000000..10a84afda
--- /dev/null
+++ b/doc/bugs/Feature_request:___34__quvi__34___flag/comment_4_6092695d6afb1608447afe6f86e6fb83._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="RaspberryPie"
+ ip="96.44.189.102"
+ subject="comment 4"
+ date="2013-09-09T19:31:44Z"
+ content="""
+That was fast!
+"""]]
diff --git a/doc/bugs/Files_disappear_from_locally_paired_annexes_when_edited.mdwn b/doc/bugs/Files_disappear_from_locally_paired_annexes_when_edited.mdwn
new file mode 100644
index 000000000..16109fb23
--- /dev/null
+++ b/doc/bugs/Files_disappear_from_locally_paired_annexes_when_edited.mdwn
@@ -0,0 +1,36 @@
+**What steps will reproduce the problem?**
+
+Create two annexes from the command line on two separate machines:
+
+ mkdir ~/Files.annex
+ cd ~/Files.annex
+ git init
+ git annex init
+ git annex untrust .
+ git annex direct
+
+Add remote to each one pointing to the other:
+
+ git remote add [remote] [remote hostname]:Files.annex
+
+Start assistant on both repos:
+
+ git annex assistant
+
+Fill one repository with a few text files, and wait for them to propagate.
+
+Edit one of the text files using vim, and save.
+
+**What is the expected output? What do you see instead?**
+
+Edited file should remain in the repo, but a significant portion of the time, the file disappeared from the repo in which it was edited (the file is present and properly synced on the other repo).
+
+**What version of git-annex are you using? On what operating system?**
+
+git-annex 4.20130323, Mac OS X on the repo where the file was edited, Arch Linux for the other paired repo.
+
+**Please provide any additional information below.**
+
+I have observed this problem setting up the repos through the webapp as well, so I don't think it is related to setting up the repos manually. I think the way vim is writing the files seems to be tickling a race condition (both command-line vim and MacVim produce the behavior). I started trying to work around it by switching to emacs to edit those files, and the files haven't disappeared from the edited repo (so far at least).
+
+[[!tag /design/assistant moreinfo]]
diff --git a/doc/bugs/Files_disappear_from_locally_paired_annexes_when_edited/comment_1_bdc97db9dc9954331e4c400baf9e5541._comment b/doc/bugs/Files_disappear_from_locally_paired_annexes_when_edited/comment_1_bdc97db9dc9954331e4c400baf9e5541._comment
new file mode 100644
index 000000000..46b333271
--- /dev/null
+++ b/doc/bugs/Files_disappear_from_locally_paired_annexes_when_edited/comment_1_bdc97db9dc9954331e4c400baf9e5541._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-04-08T17:14:23Z"
+ content="""
+When you say that the file \"disappeared from the repo\", do you mean that the actual file is no longer present on disk, or that the file is present on disk, but is no longer staged in the git repository?
+
+Version 4.20130405 fixes a bug that can result in the latter behavior.
+"""]]
diff --git a/doc/bugs/Finding_an_Unused_file.mdwn b/doc/bugs/Finding_an_Unused_file.mdwn
new file mode 100644
index 000000000..c0e613163
--- /dev/null
+++ b/doc/bugs/Finding_an_Unused_file.mdwn
@@ -0,0 +1,152 @@
+### Please describe the problem.
+
+SHA256E makes it difficult or impossible to find the original filename
+
+### What steps will reproduce the problem?
+
+I have these unused files:
+
+ $ git annex unused
+ unused . (checking for unused data...) (checking master...) (checking backupbook/HEAD...) (checking b
+ aster...) (checking lang/a-...) (checking lang/master...)
+ Some annexed data is no longer used by any files:
+ NUMBER KEY
+ 1 SHA256-s9107031--2611c08c9822179c443f001f0bd7ecadf29adcd28edfa4cd1d8938d289cd3950
+ 2 SHA256E-s31131336--58c48adad8e5f091981549dfbb2d9ec1003c8c46d1a660673fabefe722358f9b.flac
+ 3 SHA256-s9941549--db12950459ba039e6e6f6102a0811213c11a717d140d6e2f169049b958a5e047
+ 4 SHA256-s11544438--174514684e03035cc741fa397a1b46f925899bd29189a98173f8f2a136d95ace
+ 5 SHA256E-s23445007--4659fae3eda6db7c528af6439fafab1496c740d02bdb67892450a8a2208fb29b.flac
+ 6 SHA256E-s47080709--7d331788ae7fee16bccce060c62cafa3cdafc9e0a2b387c0843cfe5871f51fa6.flac
+ 7 SHA256E-s33262563--3280607d6d397f84a02542c5ab2e5a9c44d60256b330e3d075078694f0c7f709.flac
+ 8 SHA256-s6522640--a1fa374afd62e8c85a115f18f78e679722f63980191c1e11ef84a49ae86f5b4f
+ 9 SHA256E-s29266138--27e792d64b6d4a4d44bdafe6867ca25ba79480d1b650cf385e67ff28a1fc5c31.flac
+ 10 SHA256-s14568326--023eb9fcefc063ee3ea495f4d382a8feac795d0e1a81c585781f5d369db2e00c
+ 11 SHA256-s11907175--73b66220bdbf0ca92209605b93d95d5f9e8247745f9c4367ff20cb53e11c24ac
+ 12 SHA256-s9193267--e159038b78c1b239d4cb8eeb892c7acf0e7b82feac7f5b5808dad477605e8478
+ 13 SHA256E-s39329047--880ffab99c4b4c48224f409acb0cd797737e4ee70eacdba9bc7d7628ba3d05d7.flac
+ 14 SHA256E-s31400468--17ad7b13757d4e4d6e5d193d8295a30f566e00eea82bc19f50dc14b2bbf79ef3.flac
+ 15 SHA256E-s51514687--f83eb092ddcdf35e7f729bfa2cc0914b404de60f0b42f69f207cf01766061f16.flac
+ 16 SHA256E-s36235648--54e3f893b498b205b0b96bd87d5f14c71712e891c518070a0e1c730d92b3b0ac.flac
+ 17 SHA256-s10001177--35afb0b91c8b9f711b2d3b0fe7433ecc3bb13aece78c6170a47323c94233133d
+ 18 SHA256-s11830142--3dabe97ccbb68045d9ea82036ddf7211a3925a1bf682e05a32bcdf9b07bec676
+ 19 SHA256E-s23102994--f848ed216e6ba17e6b539f31caa5af36266c367ed55dcff243445848b01fbeef.flac
+ 20 SHA256E-s38505547--967763ddd42daf782afa9299e67cb5c834153cb20242b50115dda566b24a68c4.flac
+ 21 SHA256-s11874975--14774a404526c4b68ede146f527202c59a4bee88376707c93df7da3bdb5345f2
+ 22 SHA256-s10188700--18fd4ee62c2b3b1d8944eae528b59de2a45d493a291440edc9b30881ba10ece3
+ 23 SHA256E-s53024109--eba924a26f7c602b60a83f208b2204ef3b570fd92ff39fbc067eeaec7c443ab6.flac
+ 24 SHA256-s11315225--0a8d2165166995e819e8c78302c45b1eeca9b79a5d77a3574885cbf8e18f265a
+ 25 SHA256-s12249573--79b9e551051232079f24902078e1fe5b7daed684e8acaa7cf29c191404a7c3c7
+ 26 SHA256E-s47991289--79cfd8db5b3cbe7f50c335bfe0d148c38ff36dbc97b17ea3aff23d642bd5d167.flac
+ 27 SHA256E-s76961343--80e91f73e2f3ae6790d752d380118b3fadc223f9f1449354daa0095b5713986c.flac
+ 28 SHA256E-s44706648--ce782096aa5c0d58a12f7cbd6dbfe032fa7b0b4810219e23f906bd7fa0d96336.flac
+ 29 SHA256-s9393784--1e0e0190030352b3583ce515cd6dfb0db9f2ae39809a462099482947193bfd0f
+ 30 SHA256E-s11534608--bfcc0fdcb1ed112b1737d4fe7d2aa88511187d4c1c132bf1b7ab2cda9a7d90ad.flac
+ 31 SHA256E-s27916580--1f196e1b6312421f9d9bcd227a3885a5dec299fc47748cd34d5e59fe26374187.flac
+ 32 SHA256-s12099941--0a33af0293acb7cffa1727cc04efa4d7abb29a39e8f2165bfd565e2b18879430
+ 33 SHA256E-s35578262--01d6f6022161bcaa825cb353012f85bacf3dcb930337ba506fc94b663b0d8043.flac
+ 34 SHA256E-s38880984--fa326bd0db5c9e400a4256e77acd488fede23ec714aeab7deb6952091a09e318.flac
+ 35 SHA256E-s27784704--a426f885d79d88d8b42b8a23ce267fb1c1855e8f7ff6833ec9ea61860b3c6819.flac
+ 36 SHA256-s11827390--17c1e84815805ea7e01555fdfa038a643a97621b84073679d5c649c020750652
+ 37 SHA256E-s16632423--9735e37261624360f6a54fd1bc8a893cb5344afdc910e6b9e00c5791036759b0.flac
+ 38 SHA256-s10809006--7dd7ff078bdf4571bee6ab06213df970f427a8a2af476d4511a9c08ed0fb814d
+ 39 SHA256E-s33043364--3603942143fa4b1c0082ab7ba1db9b536621402eea3ac94e08ef0197062a2ef6.flac
+ 40 SHA256E-s33278052--62e1038e26894c6c014af4e77d2d9f79074ff4fc1ca9ca8c16fcc98eee5277c7.flac
+ 41 SHA256E-s47299134--0b604bff3ce12d077691d6e6428648da879c021537c094c72633209d5302fd97.flac
+ 42 SHA256E-s14882445--16c6aa4aaf8e60da617701281dfdfa372cb049636ae0f10f5aefcd8ce6c472af.flac
+ 43 SHA256E-s18168736--dfd7bfe9a433daef89f6f0015dfddaf7ac3611dd31813b0aed049171ac008323.flac
+ 44 SHA256-s10060170--9e3b638c4f397d8dbaa2fa9fc2bfacf6f9e93f00c80ee1fdd26971d25aff86ce
+ 45 SHA256E-s25630107--26fedc816dee58cb999cd2be8a58f3e8726ff056ba9c2abfbb9d149e7a92a230.flac
+ 46 SHA256-s9148609--3f29a2ae1ebd2e4857bb5c92aefb2f50f39a5a984e14645f658d15795a7c72a5
+ 47 SHA256-s10576861--7d95469441ef205616ed795012d8a4c59acc00be00aca66bcacd8b041c2499c5
+ 48 SHA256E-s23806802--8725d04f04925f4cd456bdb2108a48682cf51a498d97af9f71c58a412b8db9ab.flac
+ 49 SHA256E-s43187837--e83648296fa4553556596464efd4ab313529c0062071c9a40113fecede7a5de6.flac
+ 50 SHA256-s10384945--055a01b7e06f3165dddd10beb3e98ba4ca47b35abf9d5b2f26187bf07b9aa401
+ 51 SHA256E-s54253300--b011eea8ec7ea51f22e0fe09645ffe83183e9589a9784ebc2d6dd0c559f07322.flac
+ 52 SHA256-s10335583--008c17c1a994884c6b9c52e10d17373b9160136ffab940992ef0f9d08eac45c1
+ 53 SHA256-s9769970--b36fcb01d9df7627106e3a3c283944457f3e282ab62878c186162d465530cfbc
+ 54 SHA256-s10329964--dc4d82e085af3ade48d33cf828f8e7eecc27d4c33c448965e1b8bb59832ec473
+ 55 SHA256-s10625243--2494e2ef2c64fc77dcb063f7b58079ad668cf46862b7f11eb28943d45f21b8dd
+ 56 SHA256E-s44585111--e35b0774729ccf547cd62e652425579781e3cbd76b33a17a0127bdbedb90606a.flac
+ 57 SHA256E-s42060728--9e0a533e640086fadefad7167d37d5b3c5de899e1ac5890bfd7a88524701ff14.flac
+ 58 SHA256E-s30013479--ae34a897e2f0e1124f04396e75dd41749511ce9930a2891ae3a066597ad518c5.flac
+ 59 SHA256E-s38896704--ca6211442c33d9c44b997bef8f1079f07cdd2eb0e9e3c1de1eda9ae8a705f137.flac
+ 60 SHA256-s13044938--8714a1db8781daa9f3993128dcda5a5ca904e075723cf38a11bc5e3695cf126f
+ 61 SHA256-s8814622--ba374e92c53ddb83605e2b500647117a00e4c6c463653cb0dd0311b76627c2ec
+ 62 SHA256E-s14900839--e94089b89629561ebf771543236f31439af1e6fcdce7ff56b9a183041e95e7ea.flac
+ 63 SHA256E-s27370218--a4717cf0615cda099ea5740194da8b4e349f2f38f6ebbf5f6111ced7f56d1736.flac
+ 64 SHA256E-s57686070--6d02689ccf91317bdfa4d8694ccbf7a9ccf00a7e00b92733769194908b4087d9.flac
+ 65 SHA256-s8707306--7f05e3e3dc4336eb7012d5bbb6d3d65047552901858ee4967e4a70d100fd1deb
+ 66 SHA256E-s42482194--bb7a968ec9bc0a8813974af9173c38cb39a43aa7d0c2aec203ddb358119e1f25.flac
+ 67 SHA256E-s31951334--b19789a9bbb98cb25df7b8a1b6d8856256bc2851cd892c91dddba7cf736542c5.flac
+ 68 SHA256E-s35901187--8eae2684aa3566b632a1797bd09d112dd5f438c98b649c000d71640983a549f2.flac
+ 69 SHA256E-s40659631--f6ca3227b14c7c050877ce4cc1218fea7582426649cd68fc82a74cae5d6962b4.flac
+ 70 SHA256E-s41415180--9c6f0000da119bd70422fe9529c41efb3103ca943697bdfb685f119f6b5ae6fd.flac
+ 71 SHA256E-s52313976--e4a59c65e05bd9450ef595b3c08365810205731952e45a68ee0c89bc76fbd9fc.flac
+ 72 SHA256E-s44925214--eabc5f7172d5c2e094ff84a5ecce784c172b175c8eeca861aa3996749668ea42.flac
+ (To see where data was previously used, try: git log --stat -S'KEY')
+
+ To remove unwanted data: git-annex dropunused NUMBER
+
+ ok
+
+And running:
+
+ $ git log --stat -S'SHA256-s13044938--8714a1db8781daa9f3993128dcda5a5ca904e075723cf38a11bc5e3695cf126f'
+ commit 767a63a54784139f13d69d12fcfbee8f6ca3df41
+ Author: Matthew Forrester <matt@keyboardwritescode.com>
+ Date: Fri Aug 23 21:38:31 2013 +0100
+
+ Remove Roger Shah - Openminded! as there is another copy in Unsorted with correct? filenames
+
+ Amazon/Roger Shah/Openminded!/1114 - Shine (Album Mix).mp3 | 1 -
+ 1 file changed, 1 deletion(-)
+
+ commit 6b04002c03287fb8918bdcdeaae393e862bebd4e
+ Author: Matthew Forrester <matt@keyboardwritescode.com>
+ Date: Thu Aug 8 21:30:14 2013 +0100
+
+ Initial checkin
+
+ Amazon/Roger Shah/Openminded!/1114 - Shine (Album Mix).mp3 | 1 +
+ 1 file changed, 1 insertion(+)
+
+Works but I cannot find out how to get the `.flac` files working:
+
+
+`$ git log --stat -S'SHA256E-s38896704--ca6211442c33d9c44b997bef8f1079f07cdd2eb0e9e3c1de1eda9ae8a705f137.flac'`
+
+`$ git log --stat -S'SHA256E-s38896704--ca6211442c33d9c44b997bef8f1079f07cdd2eb0e9e3c1de1eda9ae8a705f137'`
+
+`$ git log --stat -S'SHA256-s38896704--ca6211442c33d9c44b997bef8f1079f07cdd2eb0e9e3c1de1eda9ae8a705f137'`
+
+
+None of which give answers. I don't know if I'm doing it wrong (though I __think__ I'm doing what the instructions say), but I can't make it work.
+
+
+### What version of git-annex are you using? On what operating system?
+
+$ uname -a
+Linux fozz-desktop 3.8.0-31-generic #46-Ubuntu SMP Tue Sep 10 19:56:49 UTC 2013 i686 i686 i686 GNU/Linux
+
+$ git annex version
+git-annex version: 3.20121112ubuntu2
+local repository version: 3
+default repository version: 3
+supported repository versions: 3
+upgrade supported from repository versions: 0 1 2
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
+
+> If `git log -S` does not find the key, then it was not used for any
+> commit currently in the git repository. Which is certainly possible;
+> for example `git annex add file; git rm file`.
+>
+> This is a dup of [[todo/wishlist: option to print more info with 'unused']]; [[done]] --[[Joey]]
diff --git a/doc/bugs/Fix_for_opening_a_browser_on_a_mac___40__or_xdg-open_on_linux__47__bsd__63____41__.mdwn b/doc/bugs/Fix_for_opening_a_browser_on_a_mac___40__or_xdg-open_on_linux__47__bsd__63____41__.mdwn
new file mode 100644
index 000000000..428d62ab1
--- /dev/null
+++ b/doc/bugs/Fix_for_opening_a_browser_on_a_mac___40__or_xdg-open_on_linux__47__bsd__63____41__.mdwn
@@ -0,0 +1,26 @@
+Utility/WebApp.hs, didn't quite have the right definition to use 'open' instead of 'xdg-open' on OSX, the follow fixes that
+
+<pre>
+diff --git a/Utility/WebApp.hs b/Utility/WebApp.hs
+index 6936c66..0593dda 100644
+--- a/Utility/WebApp.hs
++++ b/Utility/WebApp.hs
+@@ -42,7 +42,7 @@ localhost = "localhost"
+ runBrowser :: String -> IO Bool
+ runBrowser url = boolSystem cmd [Param url]
+ where
+-#if MAC
++#if OSX
+ cmd = "open"
+ #else
+ cmd = "xdg-open"
+</pre>
+
+> [[done]], thanks
+
+I guess I should really clone the repo and submit a stream of minor changes
+:P, @joeyh please let me know if you're getting annoyed with copy and
+pasting the small fixes from the bug/forums section.
+
+> If you're going to be writing some patches, a git repo I can pull from
+> would make my life easier. --[[Joey]]
diff --git a/doc/bugs/Freshly_initialized_repo_has_staged_change___34__deleted:_uuid.log__34__.mdwn b/doc/bugs/Freshly_initialized_repo_has_staged_change___34__deleted:_uuid.log__34__.mdwn
new file mode 100644
index 000000000..d66196acd
--- /dev/null
+++ b/doc/bugs/Freshly_initialized_repo_has_staged_change___34__deleted:_uuid.log__34__.mdwn
@@ -0,0 +1,44 @@
+### Please describe the problem.
+Using the webapp to generate a new (local) repository instantly takes it to the following state:
+[[!format sh """
+user@local:~/Annex$ git status
+# On branch master
+# Changes to be committed:
+# (use "git reset HEAD <file>..." to unstage)
+#
+# deleted: uuid.log
+#
+user@local:~/Annex$ git branch
+ git-annex
+* master
+user@local:~/Annex$ git log
+commit 90bfcaf17b0576d8ecdc48ae44dda22d41464acc
+Author: local <user>
+Date: Sun Nov 3 15:30:17 2013 +0100
+
+ created repository
+user@local:~/Annex$ git show HEAD
+commit 90bfcaf17b0576d8ecdc48ae44dda22d41464acc
+Author: local <user>
+Date: Sun Nov 3 15:30:17 2013 +0100
+
+ created repository
+
+diff --git a/uuid.log b/uuid.log
+new file mode 100644
+index 0000000..9df3670
+--- /dev/null
++++ b/uuid.log
+@@ -0,0 +1 @@
++987e7b9a-aa9d-41db-ae92-23fcae7f6187 user@local:~/Annex timestamp=1383489017.181
+user@local:~/Annex$
+"""]]
+
+I'm new to git-annex, so I'm not quite sure, but looking at [[internals]] this file should only exist in the git-annex branch, not in master. Furthermore, from this state it seems impossible to get "sync with your other devices" to work, because of a merge conflict on this change.
+
+Perhaps some sort of a race-condition with the annex-assistant picking up the uuid.log file while the repository is being initialized?
+
+### What version of git-annex are you using? On what operating system?
+Ubuntu 13.10 with git-annex 4.20130815
+
+> [[fixed|done]]; see comments. (This fix needs to be backported to Ubuntu.) --[[Joey]]
diff --git a/doc/bugs/Freshly_initialized_repo_has_staged_change___34__deleted:_uuid.log__34__/comment_1_6441dd04adc158df22589c81746108a9._comment b/doc/bugs/Freshly_initialized_repo_has_staged_change___34__deleted:_uuid.log__34__/comment_1_6441dd04adc158df22589c81746108a9._comment
new file mode 100644
index 000000000..6080e88e4
--- /dev/null
+++ b/doc/bugs/Freshly_initialized_repo_has_staged_change___34__deleted:_uuid.log__34__/comment_1_6441dd04adc158df22589c81746108a9._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 1"
+ date="2013-11-03T16:48:25Z"
+ content="""
+I can't reproduce this at all. What version of git do you have installed? Did you install git-annex from ubuntu's repository? Does the same thing happen if you install the standalone linux tarball and use it to make a new repository?
+
+git-annex never creates a file named uuid.log on disk, so it's quite strange that it shows up in the initial commit to the master branch. It sort of looks like somehow git-annex's normal use of a separate index file to stage the uuid.log to the git-annex branch is failing. Since I have never seen any problem with that, I have to suspect that the ubuntu build is somehow badly broken. Or that the git in Ubuntu is for some reason ignoring `GIT_INDEX_FILE`.
+"""]]
diff --git a/doc/bugs/Freshly_initialized_repo_has_staged_change___34__deleted:_uuid.log__34__/comment_2_d1c5d7642284a375f9c455dbf76efa5c._comment b/doc/bugs/Freshly_initialized_repo_has_staged_change___34__deleted:_uuid.log__34__/comment_2_d1c5d7642284a375f9c455dbf76efa5c._comment
new file mode 100644
index 000000000..50bff5f41
--- /dev/null
+++ b/doc/bugs/Freshly_initialized_repo_has_staged_change___34__deleted:_uuid.log__34__/comment_2_d1c5d7642284a375f9c455dbf76efa5c._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 2"
+ date="2013-11-03T17:02:47Z"
+ content="""
+I made an Ubuntu saucy chroot, apt-get installed git-annex from universe, and ran the webapp in there. I did not reproduce this problem.
+
+The cause of the problem, it seems, must be something local to your system. Perhaps you have an environment variable set that is messing up git. Or perhaps you have a different, broken version of git installed.
+
+Can you \"git show git-annex\" in the repository? It should show a commit made to the git-annex branch that adds the uuid.log there.
+"""]]
diff --git a/doc/bugs/Freshly_initialized_repo_has_staged_change___34__deleted:_uuid.log__34__/comment_3_4b863da1c8ba73ad54da20f7d2ec6e5c._comment b/doc/bugs/Freshly_initialized_repo_has_staged_change___34__deleted:_uuid.log__34__/comment_3_4b863da1c8ba73ad54da20f7d2ec6e5c._comment
new file mode 100644
index 000000000..7acab1c37
--- /dev/null
+++ b/doc/bugs/Freshly_initialized_repo_has_staged_change___34__deleted:_uuid.log__34__/comment_3_4b863da1c8ba73ad54da20f7d2ec6e5c._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="tanen"
+ ip="83.128.159.25"
+ subject="comment 3"
+ date="2013-11-03T17:35:00Z"
+ content="""
+Very strange: this is on a machine that I wiped and reinstalled just a few hours ago, it's a completely fresh Ubuntu 13.10 install with barely anything installed but the defaults. Git version is 1.8.3.2-1
+
+I initially just pulled git-annex from the Ubuntu repo. After that I grabbed a more recent version from https://launchpad.net/ubuntu/+source/git-annex/4.20131101/+build/5189754 which is showing the same behavior.
+
+\"git show git-annex\" indeed shows the commit creating the uuid.log file on the git-annex branch. master has just one commit, with description \"created repository\" and creates a \"uuid.log\" file. The contents of the master uuid.log are identical to the one in the git-annex branch.
+
+I'm currently in the middle of trying out a git-annex setup so I can't switch versions again right now, but given the above I imagine a fresh 13.10 VM should show the same behavior.
+"""]]
diff --git a/doc/bugs/Freshly_initialized_repo_has_staged_change___34__deleted:_uuid.log__34__/comment_4_8e0f489305ce30ad578b9f8526e86416._comment b/doc/bugs/Freshly_initialized_repo_has_staged_change___34__deleted:_uuid.log__34__/comment_4_8e0f489305ce30ad578b9f8526e86416._comment
new file mode 100644
index 000000000..c020fc3a8
--- /dev/null
+++ b/doc/bugs/Freshly_initialized_repo_has_staged_change___34__deleted:_uuid.log__34__/comment_4_8e0f489305ce30ad578b9f8526e86416._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 4"
+ date="2013-11-06T15:09:19Z"
+ content="""
+Intriguing -- I was able to reproduce this bug after installing the Ubuntu server ISO in a VM.
+
+Which is really strange, the only difference between this and my debootstrapped chroot should be the kernel..
+"""]]
diff --git a/doc/bugs/Freshly_initialized_repo_has_staged_change___34__deleted:_uuid.log__34__/comment_5_c699034c8e02b2354516414d0ab73aab._comment b/doc/bugs/Freshly_initialized_repo_has_staged_change___34__deleted:_uuid.log__34__/comment_5_c699034c8e02b2354516414d0ab73aab._comment
new file mode 100644
index 000000000..a323d7835
--- /dev/null
+++ b/doc/bugs/Freshly_initialized_repo_has_staged_change___34__deleted:_uuid.log__34__/comment_5_c699034c8e02b2354516414d0ab73aab._comment
@@ -0,0 +1,53 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 5"
+ date="2013-11-06T16:27:49Z"
+ content="""
+Running the prebuilt tarball build of git-annex, the bug does not occur.
+
+However, if I remove the git shipped with the prebuilt tarball, so it uses the system git, I do see the bug. So, it's apparently git version dependent.
+
+Also, I was able to reproduce it in a amd64 chroot. My other chroot was i386. Somehow architecture specific bug?
+
+---
+
+Instrumenting all calls to git to be logged with the full environment and command, I found this:
+
+<pre>
+GIT_INDEX_FILE='/home/foo/annex/.git/annex/index'
+--git-dir=/home/foo/annex/.git --work-tree=/home/foo/annex commit --quiet --allow-empty -m created repository
+</pre>
+
+This certainly looks like the index file setting for the git-annex branch is somehow leaking out past the branch commit operations. It continued setting that while setting up `gc.auto`; the next call to git after that stopped setting the index file.
+
+The only way I can see offhand this could possibly happen is due to an exception. It may be that on ubuntu an exception is thrown by code that runs a git command with the index file set, for whatever reason, and this causes the code that normally resets it back to not run.
+
+----
+
+Ok, found it!
+
+<pre>
+\"withIndex entered\"
+
+*** Please tell me who you are.
+
+Run
+
+ git config --global user.email \"you@example.com\"
+ git config --global user.name \"Your Name\"
+
+to set your account's default identity.
+Omit --global to set the identity only in this repository.
+
+fatal: unable to auto-detect email address (got 'foo@darkstar.(none)')
+\"withIndex entered\"
+\"withIndex cleaned up\"
+</pre>
+
+Note lack of clean up after the first withIndex call. Thus leaving the environment passed to git polluted for further calls.
+
+This also explains why it's only happening on some systems, or with some versions of git. git's got all kinds of complexity around its username and email handling code.
+
+I have fixed this in git.
+"""]]
diff --git a/doc/bugs/Freshly_initialized_repo_has_staged_change___34__deleted:_uuid.log__34__/comment_6_786cb7e643811dfd2496ceeff8f34f44._comment b/doc/bugs/Freshly_initialized_repo_has_staged_change___34__deleted:_uuid.log__34__/comment_6_786cb7e643811dfd2496ceeff8f34f44._comment
new file mode 100644
index 000000000..ea3e97e8e
--- /dev/null
+++ b/doc/bugs/Freshly_initialized_repo_has_staged_change___34__deleted:_uuid.log__34__/comment_6_786cb7e643811dfd2496ceeff8f34f44._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 6"
+ date="2013-11-06T16:40:57Z"
+ content="""
+Ubuntu bug report about this: <https://bugs.launchpad.net/ubuntu/+source/git-annex/+bug/1248623>
+
+It should be pretty easy to backport the fix to the version in Ubuntu. The relevant git commits are ee23be55fd3e7e202bc721c124f78b79d1aba6df and 81117e8a9d19d4739d3773d0515006e1ea41c266
+"""]]
diff --git a/doc/bugs/GIT_DIR_support_incomplete.mdwn b/doc/bugs/GIT_DIR_support_incomplete.mdwn
new file mode 100644
index 000000000..1b9738c4f
--- /dev/null
+++ b/doc/bugs/GIT_DIR_support_incomplete.mdwn
@@ -0,0 +1,17 @@
+`GIT_DIR` support isn't right. Git does not look for `GIT_DIR/.git`;
+git-annex does.
+
+Also, to support this scenario, support for core.worktree needs to be added
+as well:
+
+ mkdir repo workdir
+ git --work-tree=$PWD/workdir --git-dir=$PWD/repo init
+ export GIT_DIR=$PWD/repo
+ git status
+ # ok
+ git annex init "new repo"
+ # fail
+
+--[[Joey]]
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/GPG_can__39__t_handle_some_files.mdwn b/doc/bugs/GPG_can__39__t_handle_some_files.mdwn
new file mode 100644
index 000000000..6c29a95b8
--- /dev/null
+++ b/doc/bugs/GPG_can__39__t_handle_some_files.mdwn
@@ -0,0 +1,23 @@
+### Please describe the problem.
+
+It looks like GPG is being used in text mode, or at least isn't overriding the GPG config.
+
+### What steps will reproduce the problem?
+
+Have a binary file with long lines, and attempt to copy it into git-annex.
+
+This will happen:
+
+ $ git-annex copy 09\ Into\ The\ Dissonance.mp3 -t rsync.net_annex
+ copy 09 Into The Dissonance.mp3 (gpg) (checking rsync.net_annex...) (to rsync.net_annex...) gpg: can't handle text lines longer than 19995 characters
+ failed
+ git-annex: copy: 1 failed
+
+A workaround is to remove "textmode" from your gpg.conf, but git-annex should force this.
+
+### What version of git-annex are you using? On what operating system?
+
+7ae625363bcb6e1fc8b3733c1d7814aca05a2368 on Ubuntu 13.04 x86_64
+
+> The sheer number of ways gpg offers of shooting yourself in the foot..
+> Ok [[done]] --[[Joey]]
diff --git a/doc/bugs/GPG_can__39__t_handle_some_files/comment_1_4388c971e991dbc0326e69c49994df1e._comment b/doc/bugs/GPG_can__39__t_handle_some_files/comment_1_4388c971e991dbc0326e69c49994df1e._comment
new file mode 100644
index 000000000..60c363fd9
--- /dev/null
+++ b/doc/bugs/GPG_can__39__t_handle_some_files/comment_1_4388c971e991dbc0326e69c49994df1e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://launchpad.net/~eythian"
+ nickname="eythian"
+ subject="comment 1"
+ date="2013-09-06T23:37:10Z"
+ content="""
+I also had a huge bunch of files come across corrupted, but the one that came after I made this change wasn't. This might be a sign that GPG is corrupting things on the way past.
+"""]]
diff --git a/doc/bugs/GPG_passphrase_repeated_prompt.mdwn b/doc/bugs/GPG_passphrase_repeated_prompt.mdwn
new file mode 100644
index 000000000..085aede92
--- /dev/null
+++ b/doc/bugs/GPG_passphrase_repeated_prompt.mdwn
@@ -0,0 +1,24 @@
+#### What steps will reproduce the problem?
+
+1. Create a new repository with a directory
+2. Add files
+3. Select "Store your data in the cloud" with the "Remote server" option
+4. Enter host, user, directory
+5. Select "Use an encrypted rsync repository on the server" (Will there be an option for unencrypted later?)
+6. GPG Passphrase prompt comes up for every file
+
+#### What is the expected output? What do you see instead?
+
+I expect to enter a passphase once and then it will sync all files with the remote server.
+
+Instead, it begins syncing the files to the server but prompts for a GPG passphase for every single file.
+
+#### What version of git-annex are you using? On what operating system?
+
+3.20121017 precompiled binary on Arch Linux
+
+#### Please provide any additional information below.
+
+Not sure if I'm just missing a setting for GPG, but I would think I should only need to use the web app to configure the remote server.
+
+[[!tag /design/assistant]]
diff --git a/doc/bugs/GPG_passphrase_repeated_prompt/comment_1_6ef1c9725befc84ad57bce196ef630ef._comment b/doc/bugs/GPG_passphrase_repeated_prompt/comment_1_6ef1c9725befc84ad57bce196ef630ef._comment
new file mode 100644
index 000000000..016ecb994
--- /dev/null
+++ b/doc/bugs/GPG_passphrase_repeated_prompt/comment_1_6ef1c9725befc84ad57bce196ef630ef._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.194"
+ subject="you should install a gpg agent"
+ date="2012-10-31T17:39:53Z"
+ content="""
+A gpg agent will cache your passphrase. It is beyond the scope of the git-annex package to provide one (though it does bundle gpg), but it should be easy to install gpg-agent on your distribution.
+
+That's all that's needed for normal git-annex use, but the assistant does seem to have a larger problem in this area, since it can need to unlock a remote's key at any time to sync files from it. Since a separate
+process is spawned for each transfer, this defeats git-annex's normal in-process caching of encryption keys of remotes. So I think it needs to unlock any encrypted special remotes at startup, or when first accessing them, and pass the cached keys to the transfer processes it spawns. This is now on my todo list.
+
+However, none of the special remotes set up by the assistant will use
+password protected gpg keys, even when it's using encryption it's using a
+non-password protected shared key. So only encrypted special remotes set up
+at the command line cause this problem.
+"""]]
diff --git a/doc/bugs/GPG_problem_on_Mac.mdwn b/doc/bugs/GPG_problem_on_Mac.mdwn
new file mode 100644
index 000000000..dc4cfaae0
--- /dev/null
+++ b/doc/bugs/GPG_problem_on_Mac.mdwn
@@ -0,0 +1,34 @@
+### Please describe the problem.
+Adding a box.com repository fails with an Internal server error and the message "user error (gpg ["--quiet","--trust-model","always","--batch","--passphrase-fd","48","--symmetric","--force-mdc"] exited 2)"
+
+Looking at the logfile it seems like git-annex is looking for gpg (gpg-agent) in /usr/local/MacGPG2/bin/. On my system it is in /usr/local/bin (installed using homebrew). I do not have the directory /usr/local/MacGPG2/.
+
+Not sure if what the git-annex philosophy is: detect the location of such external programs or ship them together with git-annex.
+
+### What steps will reproduce the problem?
+Add a box.com repository (I assume every repository type that uses gpg will fail in the same way) on a Mac.
+
+
+### What version of git-annex are you using? On what operating system?
+* git-annex version 4.20130626-g2dd6f84 (from https://downloads.kitenet.net/git-annex/OSX/current/10.8.2_Mountain_Lion/)
+* Mac OS 10.8.4
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+(Recording state in git...)
+
+(encryption setup) (shared cipher) (testing WebDAV server...)
+(gpg) gpg: error running `/usr/local/MacGPG2/bin/gpg-agent': probably not installed
+gpg: DBG: running `/usr/local/MacGPG2/bin/gpg-agent' for testing failed: Configuration error
+gpg: can't connect to the agent: IPC connect call failed
+gpg: problem with the agent: No agent running
+27/Jun/2013:13:41:37 +0200 [Error#yesod-core] user error (gpg ["--quiet","--trust-model","always","--batch","--passphrase-fd","21","--symmetric","--force-mdc"] exited 2) @(yesod-core-1.1.8.3:Yesod.Internal.Core ./Yesod/Internal/Core.hs:550:5)
+# End of transcript or log.
+"""]]
+
+> [[done]]; I've updated the OSX autobuild to
+> use a gpg that doesn't fail when gpg-agent is missing. --[[Joey]]
diff --git a/doc/bugs/GPG_problem_on_Mac/comment_1_9ccfa12e7a9569a7ae9a3b819917c275._comment b/doc/bugs/GPG_problem_on_Mac/comment_1_9ccfa12e7a9569a7ae9a3b819917c275._comment
new file mode 100644
index 000000000..ce04c73e1
--- /dev/null
+++ b/doc/bugs/GPG_problem_on_Mac/comment_1_9ccfa12e7a9569a7ae9a3b819917c275._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnrFnHRRNUQBB5RCDaIwhVmCcxQp8_yiYw"
+ nickname="Oliver"
+ subject="comment 1"
+ date="2013-06-28T08:42:27Z"
+ content="""
+Do you have any form of gpg installed?
+I.e. is it failing to detect your GPG or do you just not have GPG?
+"""]]
diff --git a/doc/bugs/GPG_problem_on_Mac/comment_2_a5e07131e2bc1a646c8439fc2506128b._comment b/doc/bugs/GPG_problem_on_Mac/comment_2_a5e07131e2bc1a646c8439fc2506128b._comment
new file mode 100644
index 000000000..bc81ebaff
--- /dev/null
+++ b/doc/bugs/GPG_problem_on_Mac/comment_2_a5e07131e2bc1a646c8439fc2506128b._comment
@@ -0,0 +1,29 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawk7iPiqWr3BVPLWEDvJhSSvcOqheLEbLNo"
+ nickname="Dirk"
+ subject="comment 2"
+ date="2013-06-28T16:45:08Z"
+ content="""
+Hi,
+
+I have gpg installed.
+[[!format sh \"\"\"
+$ which gpg
+/usr/local/bin/gpg
+$ which gpg-agent
+/usr/local/bin/gpg-agent
+\"\"\"]]
+(are there other \"programs\" besides gpg and gpg-agent I should check for?)
+
+/usr/local/bin is part of my PATH.
+
+I actually noticed some strange behavior now:
+
+ * At some point I was able add the box.com repository to my original annex dir. (I think it was caused by calling gpg-agent on the command line, but I am unsure here.)
+ * I created after a reboot then a second annex dir (annex2) (not connected to the first).
+ * I was again not able to add a new box.com repository for this new annex (annex2) while the original annex dir is still able to sync to box.com
+
+This seems to indicate that there is some annex specific configuration files influencing this gpg location problem.
+
+
+"""]]
diff --git a/doc/bugs/GPG_problem_on_Mac/comment_3_388238360f2423f84881e904443efb86._comment b/doc/bugs/GPG_problem_on_Mac/comment_3_388238360f2423f84881e904443efb86._comment
new file mode 100644
index 000000000..3e8b01d24
--- /dev/null
+++ b/doc/bugs/GPG_problem_on_Mac/comment_3_388238360f2423f84881e904443efb86._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.254.222"
+ subject="comment 3"
+ date="2013-07-08T17:10:53Z"
+ content="""
+The git-annex dmg includes a copy of gpg.
+
+It seems that the build machine has been switched to having MacGPG2 installed, which hard-codes the location of gpg-agent inside it. This did not used to be the case, and I don't want to use this MacGPG2 build in the dmg.
+
+Guess I'll have to build gpg from source myself on the mac to get a sane version to distribute..
+"""]]
diff --git a/doc/bugs/Git_annex_add_fails_on_read-only_files.mdwn b/doc/bugs/Git_annex_add_fails_on_read-only_files.mdwn
new file mode 100644
index 000000000..26ee29e6d
--- /dev/null
+++ b/doc/bugs/Git_annex_add_fails_on_read-only_files.mdwn
@@ -0,0 +1,37 @@
+### Please describe the problem.
+
+Git annex cannot add/import files in folders without w or x permission
+
+Note that (as stated in the comments) this might not be a bug. The problem might somewhere within Git, because Git does not manage file permissions very well. I was just hoping that I could import large directory trees into git-annex with a simple call to "git annex import"; now it seems I have to fix their permissions first.
+
+### What steps will reproduce the problem?
+
+ $ cd /tmp
+ $ mkdir -p folder/subfolder
+ $ echo "some text" > folder/subfolder/some_file.txt
+ $ chmod 500 folder/subfolder
+ $ mkdir annex
+ $ cd annex
+ $ git init
+ $ git annex init "Testing git annex"
+ $ git annex import ../folder
+ Fails
+ $ chmod 600 ../folder/subfolder
+ $ git annex import ../folder
+ Fails
+ $ chmod 700 ../folder/subfolder
+ $ git annex import ../folder
+ Works. Subfolder now has 755 permissions
+
+### What version of git-annex are you using? On what operating system?
+
+ git-annex version: 4.20131106
+ build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP Feeds Quvi TDFA CryptoHash
+ key/value backends: SHA256E SHA1E SHA512E SHA224E SHA384E SKEIN256E SKEIN512E SHA256 SHA1 SHA512 SHA224 SHA384 SKEIN256 SKEIN512 WORM URL
+ remote types: git gcrypt S3 bup directory rsync web webdav glacier hook
+ local repository version: 3
+ default repository version: 3
+ supported repository versions: 3 4
+ upgrade supported from repository versions: 0 1 2
+
+ git version 1.8.4.3
diff --git a/doc/bugs/Git_annex_add_fails_on_read-only_files/comment_1_d31018e8bf31d729ee9fee43a0a07934._comment b/doc/bugs/Git_annex_add_fails_on_read-only_files/comment_1_d31018e8bf31d729ee9fee43a0a07934._comment
new file mode 100644
index 000000000..0a4e61bc5
--- /dev/null
+++ b/doc/bugs/Git_annex_add_fails_on_read-only_files/comment_1_d31018e8bf31d729ee9fee43a0a07934._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.64"
+ subject="comment 1"
+ date="2013-11-26T19:47:28Z"
+ content="""
+I cannot reproduce this problem on Linux, with version 4.20131106. I tried in both direct and indirect mode, on Linux.
+
+I was, however, able to exactly reproduce the error message if I made the *directory* be not writable, and used indirect mode. This is because git-annex has to move the file the .git/annex/objects, and put a symlink in place, and so has to be allowed to write to the directory. Interestingly, direct mode does not have this limiation, although I doubt git-annex would ever be very useful when run in a directory you lack write permission to.
+"""]]
diff --git a/doc/bugs/Git_annex_add_fails_on_read-only_files/comment_2_e38e7048749f890169cd0be602be6ee7._comment b/doc/bugs/Git_annex_add_fails_on_read-only_files/comment_2_e38e7048749f890169cd0be602be6ee7._comment
new file mode 100644
index 000000000..610eea713
--- /dev/null
+++ b/doc/bugs/Git_annex_add_fails_on_read-only_files/comment_2_e38e7048749f890169cd0be602be6ee7._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlq4ClC5EMN1Vq1DpWXAqP5TiDnCK1mSfk"
+ nickname="Jonas"
+ subject="comment 2"
+ date="2013-11-27T18:05:02Z"
+ content="""
+Thank you for looking into this, and sorry about the low quality of the initial bug report. I now replaced the example by a better one.
+
+As you say, this might not be a bug. I was just not aware that migrating files into git-annex would mean forsaking their permissions.
+"""]]
diff --git a/doc/bugs/Git_annex_hangs_after_git_annex_add_on_vfat__47__sdcard__47__android.mdwn b/doc/bugs/Git_annex_hangs_after_git_annex_add_on_vfat__47__sdcard__47__android.mdwn
new file mode 100644
index 000000000..bf68208da
--- /dev/null
+++ b/doc/bugs/Git_annex_hangs_after_git_annex_add_on_vfat__47__sdcard__47__android.mdwn
@@ -0,0 +1,280 @@
+### Please describe the problem.
+git add hangs.
+Maybe because of encrypted sdcard?
+
+
+
+
+
+### What steps will reproduce the problem?
+
+ app_30@android:/sdcard $ mkdir annex;cd annex
+ app_30@android:/sdcard/annex $ git init
+ Initialized empty Git repository in /mnt/sdcard/annex/.git/
+ app_30@android:/sdcard/annex $ git annex init
+ init
+ Detected a crippled filesystem.
+
+ Enabling direct mode.
+
+ Detected a filesystem without fifo support.
+
+ Disabling ssh connection caching.
+ ok
+ (Recording state in git...)
+ app_30@android:/sdcard/annex $ touch lala
+ git annex add lala --debug <
+ [2013-10-13 22:05:17 CEST] read: git ["--git-dir=/mnt/sdcard/annex/.git","--work-tree=/mnt/sdcard/annex","ls-files","--others","--exclude-standard","-z","--","lala"]
+ [2013-10-13 22:05:17 CEST] read: git ["--git-dir=/mnt/sdcard/annex/.git","--work-tree=/mnt/sdcard/annex","ls-files","--modified","-z","--","lala"]
+ [2013-10-13 22:05:17 CEST] chat: git ["--git-dir=/mnt/sdcard/annex/.git","--work-tree=/mnt/sdcard/annex","cat-file","--batch"]
+ add lala [2013-10-13 22:05:17 CEST] chat: git ["--git-dir=/mnt/sdcard/annex/.git","--work-tree=/mnt/sdcard/annex","check-attr","-z","--stdin","annex.backend","annex.numcopies","--"]
+ ** HANGS **
+
+
+
+The same will happen when just running and asking assistant to create annex for camera.
+
+ps aux | grep -i git:
+
+ app_30 9870 8950 2512 464 c009cd2c 400456a4 S git
+ app_30 9871 9870 64900 7552 ffffffff 40108a38 S git-annex
+ app_30 9876 9871 0 0 ffffffff 00000000 Z git
+ app_30 9877 9871 0 0 ffffffff 00000000 Z git
+ app_30 9878 9871 2512 608 c0114a4c 400b2878 S git
+ app_30 9879 9871 2512 556 c0114a4c 40074878 S git
+
+lsof | grep git:
+
+ 1|app_30@android:/sdcard $ lsof | grep git
+ 9870 /data/data/ga.androidterm/lib/lib.git.so /dev/pts/2
+ 9870 /data/data/ga.androidterm/lib/lib.git.so /dev/pts/2
+ 9870 /data/data/ga.androidterm/lib/lib.git.so /dev/pts/2
+ 9870 /data/data/ga.androidterm/lib/lib.git.so /dev/log/main
+ 9870 /data/data/ga.androidterm/lib/lib.git.so /dev/log/radio
+ 9870 /data/data/ga.androidterm/lib/lib.git.so /dev/log/events
+ 9870 /data/data/ga.androidterm/lib/lib.git.so /dev/log/system
+ 9870 /data/data/ga.androidterm/lib/lib.git.so /dev/__properties__ (deleted)
+ 9870 /data/data/ga.androidterm/lib/lib.git.so /system/framework/framework-res.apk
+ 9870 /data/data/ga.androidterm/lib/lib.git.so /system/framework/com.htc.resources.apk
+ 9870 /data/data/ga.androidterm/lib/lib.git.so /system/framework/framework-htc-res.apk
+ 9870 /data/data/ga.androidterm/lib/lib.git.so /system/framework/framework.jar
+ 9870 /data/data/ga.androidterm/lib/lib.git.so /system/etc/system_fonts.xml
+ 9870 /data/data/ga.androidterm/lib/lib.git.so /system/etc/fallback_fonts.xml
+ 9870 /data/data/ga.androidterm/lib/lib.git.so /system/fonts/Roboto-Regular.ttf
+ 9870 /data/data/ga.androidterm/lib/lib.git.so /system/framework/core.jar
+ 9870 /data/data/ga.androidterm/lib/lib.git.so /dev/urandom
+ 9870 /data/data/ga.androidterm/lib/lib.git.so /dev/log/main
+ 9870 /data/data/ga.androidterm/lib/lib.git.so /dev/log/radio
+ 9870 /data/data/ga.androidterm/lib/lib.git.so /dev/log/events
+ 9870 /data/data/ga.androidterm/lib/lib.git.so /dev/log/system
+ 9870 /data/data/ga.androidterm/lib/lib.git.so /dev/cpuctl/tasks
+ 9870 /data/data/ga.androidterm/lib/lib.git.so socket:[1172354]
+ 9870 /data/data/ga.androidterm/lib/lib.git.so pipe:[1172355]
+ 9870 /data/data/ga.androidterm/lib/lib.git.so pipe:[1172355]
+ 9870 /data/data/ga.androidterm/lib/lib.git.so /dev/cpuctl/bg_non_interactive/tasks
+ 9870 /data/data/ga.androidterm/lib/lib.git.so pipe:[1172358]
+ 9870 /data/data/ga.androidterm/lib/lib.git.so pipe:[1172358]
+ 9870 /data/data/ga.androidterm/lib/lib.git.so anon_inode:[eventpoll]
+ 9870 /data/data/ga.androidterm/lib/lib.git.so /dev/ashmem
+ 9870 /data/data/ga.androidterm/lib/lib.git.so /dev/ashmem
+ 9870 /data/data/ga.androidterm/lib/lib.git.so /data/app/ga.androidterm-1.apk
+ 9870 /data/data/ga.androidterm/lib/lib.git.so /data/app/ga.androidterm-1.apk
+ 9870 /data/data/ga.androidterm/lib/lib.git.so /system/app/Aluminum.apk
+ 9870 /data/data/ga.androidterm/lib/lib.git.so pipe:[1172380]
+ 9870 /data/data/ga.androidterm/lib/lib.git.so pipe:[1172381]
+ 9870 /data/data/ga.androidterm/lib/lib.git.so /data/data/ga.androidterm/fifo
+ 9870 /data/data/ga.androidterm/lib/lib.git.so pipe:[1172382]
+ 9870 /data/data/ga.androidterm/lib/lib.git.so /dev/pts/2
+ 9870 /data/data/ga.androidterm/lib/lib.git.so /system/fonts/DroidSansMono.ttf
+ 9870 /data/data/ga.androidterm/lib/lib.git.so pipe:[1172407]
+ 9870 /data/data/ga.androidterm/lib/lib.git.so pipe:[1172407]
+ 9870 /data/data/ga.androidterm/lib/lib.git.so anon_inode:[eventpoll]
+ 9870 /data/data/ga.androidterm/lib/lib.git.so /dev/ashmem
+ 9870 /data/data/ga.androidterm/lib/lib.git.so pipe:[1177783]
+ 9870 /data/data/ga.androidterm/lib/lib.git.so pipe:[1177784]
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so /dev/pts/2
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so /dev/pts/2
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so /dev/pts/2
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so /dev/log/main
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so /dev/log/radio
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so /dev/log/events
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so /dev/log/system
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so anon_inode:[eventpoll]
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so pipe:[1184035]
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so /dev/__properties__ (deleted)
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so pipe:[1184035]
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so anon_inode:[eventfd]
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so pipe:[1184036]
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so pipe:[1184036]
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so anon_inode:[eventfd]
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so pipe:[1184039]
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so pipe:[1184043]
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so pipe:[1184044]
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so pipe:[1184046]
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so pipe:[1184047]
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so /system/framework/framework-res.apk
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so /system/framework/com.htc.resources.apk
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so /system/framework/framework-htc-res.apk
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so /system/framework/framework.jar
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so /system/etc/system_fonts.xml
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so /system/etc/fallback_fonts.xml
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so /system/fonts/Roboto-Regular.ttf
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so /system/framework/core.jar
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so /dev/urandom
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so /dev/log/main
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so /dev/log/radio
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so /dev/log/events
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so /dev/log/system
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so /dev/cpuctl/tasks
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so socket:[1172354]
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so pipe:[1172355]
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so pipe:[1172355]
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so /dev/cpuctl/bg_non_interactive/tasks
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so pipe:[1172358]
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so pipe:[1172358]
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so anon_inode:[eventpoll]
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so /dev/ashmem
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so /dev/ashmem
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so /data/app/ga.androidterm-1.apk
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so /data/app/ga.androidterm-1.apk
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so /system/app/Aluminum.apk
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so pipe:[1172380]
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so pipe:[1172381]
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so /data/data/ga.androidterm/fifo
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so pipe:[1172382]
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so /dev/pts/2
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so /system/fonts/DroidSansMono.ttf
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so pipe:[1172407]
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so pipe:[1172407]
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so anon_inode:[eventpoll]
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so /dev/ashmem
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so pipe:[1177783]
+ 9871 /data/data/ga.androidterm/lib/lib.git-annex.so pipe:[1177784]
+ 9878 /data/data/ga.androidterm/lib/lib.git.so pipe:[1184043]
+ 9878 /data/data/ga.androidterm/lib/lib.git.so pipe:[1184044]
+ 9878 /data/data/ga.androidterm/lib/lib.git.so /dev/pts/2
+ 9878 /data/data/ga.androidterm/lib/lib.git.so /dev/log/main
+ 9878 /data/data/ga.androidterm/lib/lib.git.so /dev/log/radio
+ 9878 /data/data/ga.androidterm/lib/lib.git.so /dev/log/events
+ 9878 /data/data/ga.androidterm/lib/lib.git.so /dev/log/system
+ 9878 /data/data/ga.androidterm/lib/lib.git.so /dev/__properties__ (deleted)
+ 9878 /data/data/ga.androidterm/lib/lib.git.so /system/framework/framework-res.apk
+ 9878 /data/data/ga.androidterm/lib/lib.git.so /system/framework/com.htc.resources.apk
+ 9878 /data/data/ga.androidterm/lib/lib.git.so /system/framework/framework-htc-res.apk
+ 9878 /data/data/ga.androidterm/lib/lib.git.so /system/framework/framework.jar
+ 9878 /data/data/ga.androidterm/lib/lib.git.so /system/etc/system_fonts.xml
+ 9878 /data/data/ga.androidterm/lib/lib.git.so /system/etc/fallback_fonts.xml
+ 9878 /data/data/ga.androidterm/lib/lib.git.so /system/fonts/Roboto-Regular.ttf
+ 9878 /data/data/ga.androidterm/lib/lib.git.so /system/framework/core.jar
+ 9878 /data/data/ga.androidterm/lib/lib.git.so /dev/urandom
+ 9878 /data/data/ga.androidterm/lib/lib.git.so /dev/log/main
+ 9878 /data/data/ga.androidterm/lib/lib.git.so /dev/log/radio
+ 9878 /data/data/ga.androidterm/lib/lib.git.so /dev/log/events
+ 9878 /data/data/ga.androidterm/lib/lib.git.so /dev/log/system
+ 9878 /data/data/ga.androidterm/lib/lib.git.so /dev/cpuctl/tasks
+ 9878 /data/data/ga.androidterm/lib/lib.git.so socket:[1172354]
+ 9878 /data/data/ga.androidterm/lib/lib.git.so pipe:[1172355]
+ 9878 /data/data/ga.androidterm/lib/lib.git.so pipe:[1172355]
+ 9878 /data/data/ga.androidterm/lib/lib.git.so /dev/cpuctl/bg_non_interactive/tasks
+ 9878 /data/data/ga.androidterm/lib/lib.git.so pipe:[1172358]
+ 9878 /data/data/ga.androidterm/lib/lib.git.so pipe:[1172358]
+ 9878 /data/data/ga.androidterm/lib/lib.git.so anon_inode:[eventpoll]
+ 9878 /data/data/ga.androidterm/lib/lib.git.so /dev/ashmem
+ 9878 /data/data/ga.androidterm/lib/lib.git.so /dev/ashmem
+ 9878 /data/data/ga.androidterm/lib/lib.git.so /data/app/ga.androidterm-1.apk
+ 9878 /data/data/ga.androidterm/lib/lib.git.so /data/app/ga.androidterm-1.apk
+ 9878 /data/data/ga.androidterm/lib/lib.git.so /system/app/Aluminum.apk
+ 9878 /data/data/ga.androidterm/lib/lib.git.so pipe:[1172380]
+ 9878 /data/data/ga.androidterm/lib/lib.git.so pipe:[1172381]
+ 9878 /data/data/ga.androidterm/lib/lib.git.so /data/data/ga.androidterm/fifo
+ 9878 /data/data/ga.androidterm/lib/lib.git.so pipe:[1172382]
+ 9878 /data/data/ga.androidterm/lib/lib.git.so /dev/pts/2
+ 9878 /data/data/ga.androidterm/lib/lib.git.so /system/fonts/DroidSansMono.ttf
+ 9878 /data/data/ga.androidterm/lib/lib.git.so pipe:[1172407]
+ 9878 /data/data/ga.androidterm/lib/lib.git.so pipe:[1172407]
+ 9878 /data/data/ga.androidterm/lib/lib.git.so anon_inode:[eventpoll]
+ 9878 /data/data/ga.androidterm/lib/lib.git.so /dev/ashmem
+ 9878 /data/data/ga.androidterm/lib/lib.git.so pipe:[1177783]
+ 9878 /data/data/ga.androidterm/lib/lib.git.so pipe:[1177784]
+ 9879 /data/data/ga.androidterm/lib/lib.git.so pipe:[1184046]
+ 9879 /data/data/ga.androidterm/lib/lib.git.so pipe:[1184047]
+ 9879 /data/data/ga.androidterm/lib/lib.git.so /dev/pts/2
+ 9879 /data/data/ga.androidterm/lib/lib.git.so /dev/log/main
+ 9879 /data/data/ga.androidterm/lib/lib.git.so /dev/log/radio
+ 9879 /data/data/ga.androidterm/lib/lib.git.so /dev/log/events
+ 9879 /data/data/ga.androidterm/lib/lib.git.so /dev/log/system
+ 9879 /data/data/ga.androidterm/lib/lib.git.so /dev/__properties__ (deleted)
+ 9879 /data/data/ga.androidterm/lib/lib.git.so /system/framework/framework-res.apk
+ 9879 /data/data/ga.androidterm/lib/lib.git.so /system/framework/com.htc.resources.apk
+ 9879 /data/data/ga.androidterm/lib/lib.git.so /system/framework/framework-htc-res.apk
+ 9879 /data/data/ga.androidterm/lib/lib.git.so /system/framework/framework.jar
+ 9879 /data/data/ga.androidterm/lib/lib.git.so /system/etc/system_fonts.xml
+ 9879 /data/data/ga.androidterm/lib/lib.git.so /system/etc/fallback_fonts.xml
+ 9879 /data/data/ga.androidterm/lib/lib.git.so /system/fonts/Roboto-Regular.ttf
+ 9879 /data/data/ga.androidterm/lib/lib.git.so /system/framework/core.jar
+ 9879 /data/data/ga.androidterm/lib/lib.git.so /dev/urandom
+ 9879 /data/data/ga.androidterm/lib/lib.git.so /dev/log/main
+ 9879 /data/data/ga.androidterm/lib/lib.git.so /dev/log/radio
+ 9879 /data/data/ga.androidterm/lib/lib.git.so /dev/log/events
+ 9879 /data/data/ga.androidterm/lib/lib.git.so /dev/log/system
+ 9879 /data/data/ga.androidterm/lib/lib.git.so /dev/cpuctl/tasks
+ 9879 /data/data/ga.androidterm/lib/lib.git.so socket:[1172354]
+ 9879 /data/data/ga.androidterm/lib/lib.git.so pipe:[1172355]
+ 9879 /data/data/ga.androidterm/lib/lib.git.so pipe:[1172355]
+ 9879 /data/data/ga.androidterm/lib/lib.git.so /dev/cpuctl/bg_non_interactive/tasks
+ 9879 /data/data/ga.androidterm/lib/lib.git.so pipe:[1172358]
+ 9879 /data/data/ga.androidterm/lib/lib.git.so pipe:[1172358]
+ 9879 /data/data/ga.androidterm/lib/lib.git.so anon_inode:[eventpoll]
+ 9879 /data/data/ga.androidterm/lib/lib.git.so /dev/ashmem
+ 9879 /data/data/ga.androidterm/lib/lib.git.so /dev/ashmem
+ 9879 /data/data/ga.androidterm/lib/lib.git.so /data/app/ga.androidterm-1.apk
+ 9879 /data/data/ga.androidterm/lib/lib.git.so /data/app/ga.androidterm-1.apk
+ 9879 /data/data/ga.androidterm/lib/lib.git.so /system/app/Aluminum.apk
+ 9879 /data/data/ga.androidterm/lib/lib.git.so pipe:[1172380]
+ 9879 /data/data/ga.androidterm/lib/lib.git.so pipe:[1172381]
+ 9879 /data/data/ga.androidterm/lib/lib.git.so /data/data/ga.androidterm/fifo
+ 9879 /data/data/ga.androidterm/lib/lib.git.so pipe:[1172382]
+ 9879 /data/data/ga.androidterm/lib/lib.git.so /dev/pts/2
+ 9879 /data/data/ga.androidterm/lib/lib.git.so /system/fonts/DroidSansMono.ttf
+ 9879 /data/data/ga.androidterm/lib/lib.git.so pipe:[1172407]
+ 9879 /data/data/ga.androidterm/lib/lib.git.so pipe:[1172407]
+ 9879 /data/data/ga.androidterm/lib/lib.git.so anon_inode:[eventpoll]
+ 9879 /data/data/ga.androidterm/lib/lib.git.so /dev/ashmem
+ 9879 /data/data/ga.androidterm/lib/lib.git.so pipe:[1177783]
+ 9879 /data/data/ga.androidterm/lib/lib.git.so pipe:[1177784]
+
+
+vfat/sdcard entry:
+ /dev/block/dm-2 /mnt/sdcard vfat rw,dirsync,nosuid,nodev,noexec,relatime,uid=1000,gid=1015,fmask=0702,dmask=0702, \
+ allow_utime=0020,codepage=cp437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro 0 0
+ tmpfs /mnt/sdcard/.android_secure tmpfs ro,relatime,size=0k,mode=000 0 0
+
+
+
+### What version of git-annex are you using? On what operating system?
+Version from git annex version:
+2a8136b6bd60a17d687eb800594ec7c37b872b3d
+
+I tried both daily build and most recent 'stable' with the same effect.
+
+Android 4.0.3 (Htc One V)
+
+The same happens on my another android device; Samsung tablet with... also 4.0.3.
+Tried to gather strace information on git, but couldn't. If anything more is necessary,
+please let me know.
+
+The same happens when I git annex add in /data/data/ga.androidterm/anntmp - so it's not sdcard nor vfat.
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
+
+> I have updated git-annex to work with the new git, which will be 1.8.5.
+> This fix should appear in the android autobuild within an hour if you
+> want to try it. [[done]] --[[Joey]]
diff --git a/doc/bugs/Git_annex_hangs_after_git_annex_add_on_vfat__47__sdcard__47__android/comment_1_2fc435d1c741f9fc422401f682e7c8b7._comment b/doc/bugs/Git_annex_hangs_after_git_annex_add_on_vfat__47__sdcard__47__android/comment_1_2fc435d1c741f9fc422401f682e7c8b7._comment
new file mode 100644
index 000000000..19b8ae1a6
--- /dev/null
+++ b/doc/bugs/Git_annex_hangs_after_git_annex_add_on_vfat__47__sdcard__47__android/comment_1_2fc435d1c741f9fc422401f682e7c8b7._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="64.134.31.139"
+ subject="I can reproduce this! (with 4.20130923-g78e9013)"
+ date="2013-10-15T19:57:19Z"
+ content="""
+Comparing straces from Android and Linux, it seems to be due to git check-attr outputting something different:
+
+<pre>
+read(16, \"andro\0annex.backend\0unspecified\0\"..., 8096) = 66
+read(10, \"linux: annex.backend: unspecifie\"..., 8096) = 70
+</pre>
+
+So, this is not actually Android specific, thankfully. It's just a breakage caused by a change in a newish version of git! I think it's not yet released, just Android is building from git head right now.
+
+I have reverted the Android stable build to the last version I think won't be affected by this.
+"""]]
diff --git a/doc/bugs/Git_annex_hangs_after_git_annex_add_on_vfat__47__sdcard__47__android/comment_2_b73fb99a75aef912f8286626c5bde66d._comment b/doc/bugs/Git_annex_hangs_after_git_annex_add_on_vfat__47__sdcard__47__android/comment_2_b73fb99a75aef912f8286626c5bde66d._comment
new file mode 100644
index 000000000..12b0f9f6e
--- /dev/null
+++ b/doc/bugs/Git_annex_hangs_after_git_annex_add_on_vfat__47__sdcard__47__android/comment_2_b73fb99a75aef912f8286626c5bde66d._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="bla"
+ ip="91.121.95.205"
+ subject="Testing"
+ date="2013-10-15T21:24:35Z"
+ content="""
+Last autobuild (installed by replacing existing)
+annex 89345b7 with git 1.8.4.474.g128a96c - also hangs on add in the same manner (in previously created tmp git in /data/data/ga.androidterm/anntmp). Not sure if I did something wrong.
+
+Current stable release - works just fine (deinstalled, installed again - replace failed somehow)
+
+
+
+"""]]
diff --git a/doc/bugs/Git_annex_hangs_after_git_annex_add_on_vfat__47__sdcard__47__android/comment_3_b7115f2c658439ff59a029f500697fc1._comment b/doc/bugs/Git_annex_hangs_after_git_annex_add_on_vfat__47__sdcard__47__android/comment_3_b7115f2c658439ff59a029f500697fc1._comment
new file mode 100644
index 000000000..eb3c993a8
--- /dev/null
+++ b/doc/bugs/Git_annex_hangs_after_git_annex_add_on_vfat__47__sdcard__47__android/comment_3_b7115f2c658439ff59a029f500697fc1._comment
@@ -0,0 +1,57 @@
+[[!comment format=mdwn
+ username="bla"
+ ip="91.121.95.205"
+ subject="More info on latest autobuild"
+ date="2013-10-15T21:42:52Z"
+ content="""
+Using adb shell, su app_30, runshell:
+
+ app_30@android:/data/data/ga.androidterm/anntmp $ head -n 3 /sdcard/git-annex.>
+ Installation starting to /data/data/ga.androidterm
+ 89345b7108f5c18eba0845f84780a26d069d011d
+ installing busybox
+
+ app_30@android:/data/data/ga.androidterm/anntmp $ git version
+ git version 1.8.4.474.g128a96c
+ app_30@android:/data/data/ga.androidterm/anntmp $ git annex version
+ git-annex version: 4.20131015-g89345b7
+ build flags: Assistant Webapp Testsuite S3 WebDAV Inotify DNS Feeds Quvi TDFA CryptoHash
+ key/value backends: SHA256E SHA1E SHA512E SHA224E SHA384E SKEIN256E SKEIN512E SHA256 SHA1 SHA512 SHA224 SHA384 SKEIN256 SKEIN512 WORM URL
+ remote types: git gcrypt S3 bup directory rsync web webdav glacier hook
+ local repository version: 3
+ default repository version: 3
+ supported repository versions: 3 4
+ upgrade supported from repository versions: 0 1 2
+
+ git init; git annex init; touch lala
+ 130|app_30@android:/data/data/ga.androidterm/anntmp $ git annex add lala --deb>
+ [2013-10-15 23:37:20 CEST] read: git [\"--git-dir=/data/data/ga.androidterm/anntmp/.git\",\"--work-tree=/data/data/ga.androidterm/anntmp\",\"ls-files\",\"--others\",\"--exclude-standard\",\"-z\",\"--\",\"lala\"]
+ [2013-10-15 23:37:20 CEST] read: git [\"--git-dir=/data/data/ga.androidterm/anntmp/.git\",\"--work-tree=/data/data/ga.androidterm/anntmp\",\"diff\",\"--name-only\",\"--diff-filter=T\",\"-z\",\"--\",\"lala\"]
+ add lala [2013-10-15 23:37:20 CEST] chat: git [\"--git-dir=/data/data/ga.androidterm/anntmp/.git\",\"--work-tree=/data/data/ga.androidterm/anntmp\",\"check-attr\",\"-z\",\"--stdin\",\"annex.backend\",\"annex.numcopies\",\"--\"]
+ *hangs*
+
+
+
+ echo lala | git check-attr -z --stdin annex.backend annex.numcopies | hexdump -C
+ 00000000 6c 61 6c 61 0a 00 61 6e 6e 65 78 2e 62 61 63 6b |lala..annex.back|
+ 00000010 65 6e 64 00 75 6e 73 70 65 63 69 66 69 65 64 00 |end.unspecified.|
+ 00000020 6c 61 6c 61 0a 00 61 6e 6e 65 78 2e 6e 75 6d 63 |lala..annex.numc|
+ 00000030 6f 70 69 65 73 00 75 6e 73 70 65 63 69 66 69 65 |opies.unspecifie|
+ 00000040 64 00 |d.|
+ 00000042
+
+While on my laptop (git 1.8.4.rc3)
+
+ feather annex % echo lala | git check-attr -z --stdin annex.backend annex.numcopies | hexdump -C
+ 00000000 22 6c 61 6c 61 5c 6e 22 3a 20 61 6e 6e 65 78 2e |\"lala\n\": annex.|
+ 00000010 62 61 63 6b 65 6e 64 3a 20 75 6e 73 70 65 63 69 |backend: unspeci|
+ 00000020 66 69 65 64 0a 22 6c 61 6c 61 5c 6e 22 3a 20 61 |fied.\"lala\n\": a|
+ 00000030 6e 6e 65 78 2e 6e 75 6d 63 6f 70 69 65 73 3a 20 |nnex.numcopies: |
+ 00000040 75 6e 73 70 65 63 69 66 69 65 64 0a |unspecified.|
+ 0000004c
+
+So in fact very different indeed.
+
+
+Hope it helps - assuming i didn't do some weird mistake. I'll happily use stable version for now. GREAT THANKS!
+"""]]
diff --git a/doc/bugs/Git_annex_hangs_after_git_annex_add_on_vfat__47__sdcard__47__android/comment_4_67de7a56ddb06fc0e31cc011d281c633._comment b/doc/bugs/Git_annex_hangs_after_git_annex_add_on_vfat__47__sdcard__47__android/comment_4_67de7a56ddb06fc0e31cc011d281c633._comment
new file mode 100644
index 000000000..4456e2cef
--- /dev/null
+++ b/doc/bugs/Git_annex_hangs_after_git_annex_add_on_vfat__47__sdcard__47__android/comment_4_67de7a56ddb06fc0e31cc011d281c633._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="64.134.31.139"
+ subject="comment 4"
+ date="2013-10-16T16:16:02Z"
+ content="""
+Thanks for testing that. I had a fencepost error, which I've fixed, and actually tested with problimatic git version now.
+"""]]
diff --git a/doc/bugs/Git_annex_hangs_after_git_annex_add_on_vfat__47__sdcard__47__android/comment_5_58fdb2a00f1737746cdbc804f831a0e7._comment b/doc/bugs/Git_annex_hangs_after_git_annex_add_on_vfat__47__sdcard__47__android/comment_5_58fdb2a00f1737746cdbc804f831a0e7._comment
new file mode 100644
index 000000000..7bbef0fdd
--- /dev/null
+++ b/doc/bugs/Git_annex_hangs_after_git_annex_add_on_vfat__47__sdcard__47__android/comment_5_58fdb2a00f1737746cdbc804f831a0e7._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://adamspiers.myopenid.com/"
+ nickname="Adam"
+ subject="any chance of a new release?"
+ date="2013-10-22T13:33:57Z"
+ content="""
+I just upgraded via cabal install to 4.20131002, which (unsurprisingly, I guess) still exhibits this issue. Would be great if a new release could be cut for this ...
+"""]]
diff --git a/doc/bugs/Git_annexed_files_symlink_are_wrong_when_submodule_is_not_in_the_same_path.mdwn b/doc/bugs/Git_annexed_files_symlink_are_wrong_when_submodule_is_not_in_the_same_path.mdwn
new file mode 100644
index 000000000..3f58bd889
--- /dev/null
+++ b/doc/bugs/Git_annexed_files_symlink_are_wrong_when_submodule_is_not_in_the_same_path.mdwn
@@ -0,0 +1,63 @@
+Hi,
+I already have told about that in a comment here <http://git-annex.branchable.com/bugs/submodule_path_problem/#comment-e86330d15b714a41a07b6548fbc79bb2>, but I am not sure it will be seen.
+
+Then here is an official bug report.
+### Please describe the problem.
+
+I have a problem with submodules when the git repository is not a submodule everywhere.
+
+For instance, if A is a git annexed repository and B another git repository. If B adds A as submodules. The symlinks added in A as submodule won't work in the original A.
+
+### What steps will reproduce the problem?
+
+ # creating the master repository
+ mkdir annex_master
+ cd annex_master/
+ git init
+ # hack: adding a file to create the master branch
+ touch start
+ git add start
+ git commit -m "start"
+ cd ..
+ # create another repository
+ mkdir annex_sub
+ cd annex_sub/
+ git init
+ # hack: adding a file to create the master branch
+ touch start
+ git add start
+ git commit -m "start"
+ # it is a annexed repository
+ git annex init sub
+ # add the other repository as submodule of the master one
+ cd ../annex_master/
+ git submodule add ../annex_sub/ module
+ cd module/
+ git annex init sub_module
+ git annex sync origin
+ # add an annexed file
+ echo test > test
+ git annex add
+ git annex sync
+ # go back to the origin repository
+ cd ../../annex_sub/
+ git annex sync
+ ls -l
+This returns test -> ../.git/modules/module/annex/objects/w8/pv/SHA256E-s5--f2ca1bb6c7e907d06dafe4687e579fce76b37e4e93b7605022da52e6ccc26fd2/SHA256E-s5--f2ca1bb6c7e907d06dafe4687e579fce76b37e4e93b7605022da52e6ccc26fd2
+
+Actually, the file committed is correct. But the fact it points to '../.git/modules/module/...' makes the link work only if the repository is also a submodule and if this submodule is also located in the modules folder in the parent git repository.
+
+I tried playing with making the repository direct and then indirect, hoping that would fix the symlinks, but it did not work.
+### What version of git-annex are you using? On what operating system?
+
+ $ git-annex version
+ git-annex version: 4.20130802
+ ...
+
+ $ git --version
+ git version 1.8.3.2
+
+ $ uname -a
+ Linux konixwork 3.9-1-amd64 #1 SMP Debian 3.9.8-1 x86_64 GNU/Linux
+
+### Please provide any additional information below.
diff --git a/doc/bugs/Git_annexed_files_symlink_are_wrong_when_submodule_is_not_in_the_same_path/comment_1_b3197993dbdfaf2db5e4651ac54a896e._comment b/doc/bugs/Git_annexed_files_symlink_are_wrong_when_submodule_is_not_in_the_same_path/comment_1_b3197993dbdfaf2db5e4651ac54a896e._comment
new file mode 100644
index 000000000..8ff232159
--- /dev/null
+++ b/doc/bugs/Git_annexed_files_symlink_are_wrong_when_submodule_is_not_in_the_same_path/comment_1_b3197993dbdfaf2db5e4651ac54a896e._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 1"
+ date="2013-08-24T18:49:18Z"
+ content="""
+git-annex assumes that it can make a stable symlink from a file in the working tree to a file in the .git directory. There are several ways to break this. One, as noted, is sometimes using a repository as a submodule, and sometimes not. Another would be to play around with `GIT_DIR`.
+
+I don't see a way git-annex can support those use cases, at least in indirect mode.
+
+It does seem like, in direct mode, it should just work. git-annex will commit various symlinks to git, but these symlinks will never be followed to get at the content of a file, since direct mode arranges for the content to be directly present in the working tree.
+"""]]
diff --git a/doc/bugs/Git_annexed_files_symlink_are_wrong_when_submodule_is_not_in_the_same_path/comment_2_1fbbd02e61ef524597dafd69460b00b4._comment b/doc/bugs/Git_annexed_files_symlink_are_wrong_when_submodule_is_not_in_the_same_path/comment_2_1fbbd02e61ef524597dafd69460b00b4._comment
new file mode 100644
index 000000000..b7aa61f17
--- /dev/null
+++ b/doc/bugs/Git_annexed_files_symlink_are_wrong_when_submodule_is_not_in_the_same_path/comment_2_1fbbd02e61ef524597dafd69460b00b4._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="konubinix"
+ ip="82.243.233.186"
+ subject="Thanks"
+ date="2013-08-26T06:25:19Z"
+ content="""
+Thanks for the reply.
+
+Also thanks for this great tool (Though I am not sure I truelly realize the true power of git annex yet).
+"""]]
diff --git a/doc/bugs/Glacier_remote_uploads_duplicates.mdwn b/doc/bugs/Glacier_remote_uploads_duplicates.mdwn
new file mode 100644
index 000000000..75014a5e0
--- /dev/null
+++ b/doc/bugs/Glacier_remote_uploads_duplicates.mdwn
@@ -0,0 +1,36 @@
+### Please describe the problem.
+
+Other references:
+
+https://github.com/basak/glacier-cli/pull/19
+http://git-annex.branchable.com/special_remotes/glacier/#comment-a2b05b8dc2d640ee498d90398f02931c
+
+#### Background
+
+ * Glacier doesn't support keys that the client selects, unlike S3. If you upload to Glacier, Glacier assigns a unique ID, not the client.
+ * Glacier does support an "archive description" which is immutable. It also provides this "archive description" in an inventory listing, together with the unique IDs.
+ * An "archive description" is not a unique key. It's perfectly possible to upload multiple archives to Glacier with the same "archive description".
+ * glacier-cli uses the "archive description" field as an upload identifier, since the unique IDs are unfriendly to users. However, since they are potentially ambiguous identifiers, it also supports disambiguation using the ID itself. See "Addressing Archives" in README.md for details.
+
+#### The Problem
+
+This what I believe is happening in the two reports referenced above. When git-annex is used without `--trust-glacier`, it can end up uploading the same data multiple times. From git-annex's point of view, it cannot verify that the data is already in Glacier, so it uploads again, expecting an overwrite operation if the key is already in Glacier. Since glacier-cli maps the key to an "archive description" that can be duplicated, this is not what happens. Instead, a second archive is uploaded.
+
+When git-annex later does a "checkpresent" operation, glacier-cli fails. This is because the request is ambiguous, since there are two archives in Glacier with the same "key". The error message could be better here, but I believe that the behaviour is correct.
+
+#### Discussion
+
+glacier-cli can find out what data Glacier claims to have using an inventory retrieval. However, this retrieval takes about four hours and can be out of date (eg. if someone else recently deleted the archive from another client). Thus, I can understand git-annex's desire not to trust this data or a cache of it.
+
+However, whatever we do, it is impossible to map an "upload or overwrite on key X" type command to Glacier. We'll always end up with duplicates. Even if git-annex stored the Glacier archive IDs, there is no API to replace an existing archive with the same ID, and inventories are out of date even before we retrieve them.
+
+#### Workaround
+
+If the problem is as I think it is, always applying `--trust-glacier` should prevent the problem from occurring in most cases, since git-annex will run "checkpresent" and glacier-cli will confirm that the archive exists.
+
+To fix the problem after it has occurred, it should be sufficient to delete duplicates using glacier-cli, since they _should_ be identical to each other. Some enhancement of the `glacier-cli archive list` command would help here.
+
+Update 10 June 2013: I've pushed a `glacier-cli` update and helper script in commit `b68835`. This adds a `--force-ids` option to `glacier archive list`, with which the helper script `glacier-list-duplicates.sh` uses to identify duplicates that can be removed. If you're affected by this issue, I suggest that you use this helper to identify and fix your problem by removing the duplicates. Please do so carefully by checking that the output of the helper is correct before you use it to delete the duplicates. See the comments at the top of the helper script for usage information.
+
+> [[fixed|done]], at least for the only well-working case for glacier, where
+> only one repository can access glacier directly. --[[Joey]]
diff --git a/doc/bugs/Glacier_remote_uploads_duplicates/comment_1_8aef582a0f0d0c7f764b425fc45de3b4._comment b/doc/bugs/Glacier_remote_uploads_duplicates/comment_1_8aef582a0f0d0c7f764b425fc45de3b4._comment
new file mode 100644
index 000000000..9e42d4cae
--- /dev/null
+++ b/doc/bugs/Glacier_remote_uploads_duplicates/comment_1_8aef582a0f0d0c7f764b425fc45de3b4._comment
@@ -0,0 +1,25 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-05-23T15:55:16Z"
+ content="""
+Please beware of the warning on the man page when using --trust-glacier-inventory:
+
+> Be careful using this, especially if you or someone else might
+> have recently removed a file from Glacier. If you try to drop
+> the only other copy of the file, and this switch is enabled, you
+> could lose data!
+
+While I'm inclined to want git-annex to store the necessary mappings from keys to glacier IDs in the git-annex branch, which would allow uploads/downloads from multiple repositories to the same glacier repository, it will not help with this problem. The git-annex branch can be out of date too.
+
+It seems that what's needed is a separate form of the checkpresent hook, that's used when deciding whether to copy data to glacier.
+We want this to trust the glacier inventory. But we don't want to trust the glacier inventory when moving data to glacier, or when running `git annex drop`! (unless --trust-glacier-inventory is specified). I think this would be easy to add. If you're up for testing a patch, I could do it today.
+
+BTW, there does seem to be a workaround that avoids duplicate copies to glacier:
+
+ git annex copy --to glacier --not --in glacier
+
+While normally copy checks the inventory to see if a key has been sent to glacier, and so will re-send, the `--not --in glacier`
+trusts the location tracking information, so if git-annex has sent the key before, it will skip the copy.
+"""]]
diff --git a/doc/bugs/Glacier_remote_uploads_duplicates/comment_2_150ce8b7c4424a83c4b1760da5a89d27._comment b/doc/bugs/Glacier_remote_uploads_duplicates/comment_2_150ce8b7c4424a83c4b1760da5a89d27._comment
new file mode 100644
index 000000000..859377308
--- /dev/null
+++ b/doc/bugs/Glacier_remote_uploads_duplicates/comment_2_150ce8b7c4424a83c4b1760da5a89d27._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-05-23T15:57:08Z"
+ content="""
+I suppose another way to fix it along similar lines would be to make `git annex copy` always trust location tracking information when deciding whether to copy. I'm not sure how I feel about this though -- it might make things less robust in situations where `git annex copy` is run as a backup, and location tracking could have gotten out of date.
+"""]]
diff --git a/doc/bugs/Glacier_remote_uploads_duplicates/comment_3_718af5048c5f894eee134547a2e0a644._comment b/doc/bugs/Glacier_remote_uploads_duplicates/comment_3_718af5048c5f894eee134547a2e0a644._comment
new file mode 100644
index 000000000..4091e258c
--- /dev/null
+++ b/doc/bugs/Glacier_remote_uploads_duplicates/comment_3_718af5048c5f894eee134547a2e0a644._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-05-23T15:59:37Z"
+ content="""
+It's also worth noting that the assistant always trusts the location log when deciding whether to send a key to a remote. So I think it will not trigger this bug. It seems only `git annex copy` will. (Well, maybe `git annex move` too in an edge case.)
+"""]]
diff --git a/doc/bugs/Glacier_remote_uploads_duplicates/comment_4_184ad0f8c2847309632f8c18b918cd42._comment b/doc/bugs/Glacier_remote_uploads_duplicates/comment_4_184ad0f8c2847309632f8c18b918cd42._comment
new file mode 100644
index 000000000..415103a01
--- /dev/null
+++ b/doc/bugs/Glacier_remote_uploads_duplicates/comment_4_184ad0f8c2847309632f8c18b918cd42._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmUJBh1lYmvfCCiGr3yrdx-QhuLCSRnU5c"
+ nickname="Justin"
+ subject="comment 4"
+ date="2013-05-27T22:24:44Z"
+ content="""
+> If you're up for testing a patch, I could do it today.
+
+I'm happy to test a patch. I haven't successfully compiled git-annex on my Mac, which is the only computer I have for the next month or so, but it wasn't too hard to get it to work on my Linux box.
+"""]]
diff --git a/doc/bugs/Glacier_remote_uploads_duplicates/comment_5_6980a912d3582c2f2511e4827e9e76b3._comment b/doc/bugs/Glacier_remote_uploads_duplicates/comment_5_6980a912d3582c2f2511e4827e9e76b3._comment
new file mode 100644
index 000000000..1d4bbf1fd
--- /dev/null
+++ b/doc/bugs/Glacier_remote_uploads_duplicates/comment_5_6980a912d3582c2f2511e4827e9e76b3._comment
@@ -0,0 +1,21 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 5"
+ date="2013-05-29T17:54:11Z"
+ content="""
+I started to make a branch with the change I suggested, but then I had another idea.
+
+The checkpresent hook can return either True or, False, or fail with a message if it cannot successfully check the remote. Currently for glacier, when --trust-glacier is not set, it always returns False. Crucially, in the case when a file is in glacier, this is telling git-annex it's not there, so copy re-uploads it. What if it instead, when the glacier inventory is missing a file, it returns False. And when the glacier inventory has a file, unless --trust-glacier is set, it *fails*.
+
+The result would be:
+
+* `git annex copy --to glacier` would only send things not listed in inventory. If a file is listed in the inventory, `copy`
+ would complain that --trust-glacier` is not set, and not re-upload the file.
+* `git annex drop` would only trust that glacier has a file when --trust-glacier is set. Behavior unchanged.
+* `git annex move --to glacier`, when the file is not listed in inventory, would send the file, and delete it locally. Behavior unchanged.
+* `git annex move --to glacier`, when the file is listed in inventory, would only trust that glacier has the file when --trust-glacier is set
+* `git annex copy --from glacier` / `git annex get`, when the file is located in glacier, would trust the location log, and attempt to get the file from glacier.
+
+This seems like it should do the right thing in all cases, but I have not tested it. I've pushed a `glacier` branch with this change.
+"""]]
diff --git a/doc/bugs/Glacier_remote_uploads_duplicates/comment_6_feea067d6856af2840604782b29af86a._comment b/doc/bugs/Glacier_remote_uploads_duplicates/comment_6_feea067d6856af2840604782b29af86a._comment
new file mode 100644
index 000000000..2a140eb49
--- /dev/null
+++ b/doc/bugs/Glacier_remote_uploads_duplicates/comment_6_feea067d6856af2840604782b29af86a._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkexhIpGcYa22aPQtLm-StpHiF-MHYPh5w"
+ nickname="Robie"
+ subject="comment 6"
+ date="2013-06-10T17:24:34Z"
+ content="""
+This seems reasonable to me.
+
+One other possibility that you could end up with a duplicate: if `glacier-cli`'s cache is not up to date. For example: hosts A and B both have (the same) annex with the same Glacier special remote defined. Host A copies a file to Glacier. On host B, the `glacier-cli` cache doesn't know about the file, and so a copy to Glacier on host B also succeeds. When the cache is later brought up to date `glacier vault sync`, then the duplicate appears.
+
+I'm not sure what we can do about this. Perhaps we need to accept that duplicates will occur, and handle them more gracefully.
+"""]]
diff --git a/doc/bugs/Glacier_remote_uploads_duplicates/comment_7_e96187bad3dae2f5f95118f6df87a1ec._comment b/doc/bugs/Glacier_remote_uploads_duplicates/comment_7_e96187bad3dae2f5f95118f6df87a1ec._comment
new file mode 100644
index 000000000..26cbb5a47
--- /dev/null
+++ b/doc/bugs/Glacier_remote_uploads_duplicates/comment_7_e96187bad3dae2f5f95118f6df87a1ec._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 7"
+ date="2013-06-11T14:38:19Z"
+ content="""
+Ok, I've merged the glacier branch into master. I would still be happy to see some testing of this before my next release (in a week).
+
+I guess I'll close this bug report. There are certainly still problems that can happen if there are multiple repositories all writing to glacier independently. Seems to me that one good way to deal with this is to set up a single remote that is configured to be a gateway to glacier.
+"""]]
diff --git a/doc/bugs/Glacier_remote_uploads_duplicates/comment_8_34216b514a6fca788cfacb8579ce5311._comment b/doc/bugs/Glacier_remote_uploads_duplicates/comment_8_34216b514a6fca788cfacb8579ce5311._comment
new file mode 100644
index 000000000..67fd5354b
--- /dev/null
+++ b/doc/bugs/Glacier_remote_uploads_duplicates/comment_8_34216b514a6fca788cfacb8579ce5311._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmZgZuUhZlHpd_AbbcixY0QQiutb2I7GWY"
+ nickname="Jimmy"
+ subject="For those on Mac OS X"
+ date="2013-11-18T00:00:32Z"
+ content="""
+The duplicates script fails because the BSD/MacOS version of uniq doesn't support the -D option.
+
+You can work around this by installing the GNU version using Homebrew ('brew install coreutils') and then replacing the 'uniq' in the script with 'guniq' (Homebrew prefixes the coreutils with \"g\" by default).
+
+I seem to still be running in to this bug using git annex version 4.20131106 and 'git annex copy --to glacier' without the '--not --in glacier' flags. It's not a problem to use the extra flags but I wasn't originally aware of this issue and the duplicates don't seem to always occur. I'll do some more testing and see whether I can reliably predict what will create duplicates and what won't.
+"""]]
diff --git a/doc/bugs/Handling_of_files_inside_and_outside_archive_directory_at_the_same_time.mdwn b/doc/bugs/Handling_of_files_inside_and_outside_archive_directory_at_the_same_time.mdwn
new file mode 100644
index 000000000..b3d6aa01f
--- /dev/null
+++ b/doc/bugs/Handling_of_files_inside_and_outside_archive_directory_at_the_same_time.mdwn
@@ -0,0 +1,16 @@
+Hi,
+
+some time ago, I accidentially copied some files from the archive to the non-archive part of my (indirect, type 'client') repository (instead of moving), with the effect that assistant always kept downloading and afterwards immediately dropping the files. Now this was not really suprising once I found the duplicate folder, but maybe git annex could detect this case and refuse to run in circles or at least complain about it.
+
+Best
+Karsten
+
+[[!tag /design/assistant]]
+
+> Update: Current status is this is fixed for direct mode.
+>
+> In indirect mode, the startup scan will still download and then drop
+> content if a file outside and inside the archive directory has the
+> same content. It doesn't loop like it did in direct mode, only
+> happens once (or once per duplicate file, really). Is still potentially
+> annoying and a bug. --[[Joey]]
diff --git a/doc/bugs/Handling_of_files_inside_and_outside_archive_directory_at_the_same_time/comment_1_e8bb3d6a2318402b985caed08282d473._comment b/doc/bugs/Handling_of_files_inside_and_outside_archive_directory_at_the_same_time/comment_1_e8bb3d6a2318402b985caed08282d473._comment
new file mode 100644
index 000000000..0606fdffb
--- /dev/null
+++ b/doc/bugs/Handling_of_files_inside_and_outside_archive_directory_at_the_same_time/comment_1_e8bb3d6a2318402b985caed08282d473._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-04-11T16:32:43Z"
+ content="""
+This is a known problem.
+
+It seems possible to fix it for direct mode. After all, direct mode tracks all files associated with a key, so it could expose this to preferred content expressions, and the expression check if any of the associated files was in an archive directory.
+
+Unsure how to deal with it in indirect mode. Short of making indirect mode do all the same tracking direct mode does, or otherwise build a key to file lookup table.
+"""]]
diff --git a/doc/bugs/Handling_of_files_inside_and_outside_archive_directory_at_the_same_time/comment_2_ead9fa75a12ef36be9a92637b144e74f._comment b/doc/bugs/Handling_of_files_inside_and_outside_archive_directory_at_the_same_time/comment_2_ead9fa75a12ef36be9a92637b144e74f._comment
new file mode 100644
index 000000000..2be39d451
--- /dev/null
+++ b/doc/bugs/Handling_of_files_inside_and_outside_archive_directory_at_the_same_time/comment_2_ead9fa75a12ef36be9a92637b144e74f._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-06-15T17:52:36Z"
+ content="""
+This turns out to be much worse in direct mode than in indirect mode.
+
+In indirect mode, it only does extra work during the full startup scan. Suppose there are 3 files with the same content, 1, archive/2, and 3. It will download 1, and then will drop archive/2, and then will download 3. This certainly is not ideal, especially when the file content is large.
+
+In indirect mode, it continally and repeatedly downloads the drops the files, as long as it's running. Which is beyond unacceptable.
+
+What seems to be going on is that when archive/2 gets dropped, it necessary needs to convert 1 and 3 to broken symlinks. But the watcher than sees those file changes, thinks these are new or renamed files that have appeared, and promptly re-downloads them. That, in turn triggers an update of archive/2, to convert it back from symlink to direct mode file, and that in turn is noticed by the watcher. Round and round we go!
+"""]]
diff --git a/doc/bugs/Hanging_on_install_on_Mountain_lion.mdwn b/doc/bugs/Hanging_on_install_on_Mountain_lion.mdwn
new file mode 100644
index 000000000..f18a0ef40
--- /dev/null
+++ b/doc/bugs/Hanging_on_install_on_Mountain_lion.mdwn
@@ -0,0 +1,26 @@
+### Please describe the problem.
+
+In trying to install git-annex on my mac OSX Mountain Lion, the program is hanging when I open the program.
+
+### What steps will reproduce the problem?
+
+Open the DMG, drag the app to applications folder, double-click on the application. Web browser opens with a localhost url. The webpage says "Starting webapp..." and doesn't go anywhere. Initialization seems to fail and I need to force quit the application.
+
+### What version of git-annex are you using? On what operating system?
+
+I'm not totally sure (since it hangs and I can't check a version number, but since I just downloaded it now and the homepage says the latest version is "version 4.20130621" which was released 2 days and 13 hours ago, I assume that is it.
+
+I'm using OSX 10.8.4.
+
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
+
+> Fixed root cause. [[done]] --[[Joey]]
diff --git a/doc/bugs/Hanging_on_install_on_Mountain_lion/comment_10_f57ff027b19ca16e2ecf1fc6aee9ef4a._comment b/doc/bugs/Hanging_on_install_on_Mountain_lion/comment_10_f57ff027b19ca16e2ecf1fc6aee9ef4a._comment
new file mode 100644
index 000000000..91de599c3
--- /dev/null
+++ b/doc/bugs/Hanging_on_install_on_Mountain_lion/comment_10_f57ff027b19ca16e2ecf1fc6aee9ef4a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.193"
+ subject="comment 10"
+ date="2013-06-26T22:10:39Z"
+ content="""
+Seems to be caused by an upgrade of the Mac the autobuilds run on. Particularly, downgrading yesod and warp to older versions seems to avoid the hang, so I've temporarily adjusted the deps so it will build with the old versions.
+
+I have updated the daily autobuild for OSX, as well as the dmg for the current release. Testing appreciated.
+"""]]
diff --git a/doc/bugs/Hanging_on_install_on_Mountain_lion/comment_11_2ff78d2090d0fd3418ab50b27c6028ce._comment b/doc/bugs/Hanging_on_install_on_Mountain_lion/comment_11_2ff78d2090d0fd3418ab50b27c6028ce._comment
new file mode 100644
index 000000000..cd67b45c3
--- /dev/null
+++ b/doc/bugs/Hanging_on_install_on_Mountain_lion/comment_11_2ff78d2090d0fd3418ab50b27c6028ce._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.193"
+ subject="not OSX specific"
+ date="2013-06-27T02:36:04Z"
+ content="""
+I was able to reproduce the hang on linux after upgrading to the newest version of warp and yesod.
+"""]]
diff --git a/doc/bugs/Hanging_on_install_on_Mountain_lion/comment_1_523d3c0c71f80536850a001b90fd0e9e._comment b/doc/bugs/Hanging_on_install_on_Mountain_lion/comment_1_523d3c0c71f80536850a001b90fd0e9e._comment
new file mode 100644
index 000000000..06ab0f904
--- /dev/null
+++ b/doc/bugs/Hanging_on_install_on_Mountain_lion/comment_1_523d3c0c71f80536850a001b90fd0e9e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnGrQBFPptA2GU_Nx8KrxRGtyAS7PIlwjw"
+ nickname="Nathan"
+ subject="me too."
+ date="2013-06-24T07:33:54Z"
+ content="""
+I'm having the exact same problem (OSX 10.8.2)
+"""]]
diff --git a/doc/bugs/Hanging_on_install_on_Mountain_lion/comment_2_6c360c64093b016c2150206dc3ad1709._comment b/doc/bugs/Hanging_on_install_on_Mountain_lion/comment_2_6c360c64093b016c2150206dc3ad1709._comment
new file mode 100644
index 000000000..46c53294c
--- /dev/null
+++ b/doc/bugs/Hanging_on_install_on_Mountain_lion/comment_2_6c360c64093b016c2150206dc3ad1709._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnrFnHRRNUQBB5RCDaIwhVmCcxQp8_yiYw"
+ nickname="Oliver"
+ subject="comment 2"
+ date="2013-06-25T11:19:34Z"
+ content="""
+Had that on snow leopard as well, using both the release and the nightlies. In the end I built it myself using cabal and that was OK.
+
+Possibly using the cli from inside the app to initialize the repo might fix it.
+"""]]
diff --git a/doc/bugs/Hanging_on_install_on_Mountain_lion/comment_3_7b77fd9b7dc236c345f2f6149c8138ee._comment b/doc/bugs/Hanging_on_install_on_Mountain_lion/comment_3_7b77fd9b7dc236c345f2f6149c8138ee._comment
new file mode 100644
index 000000000..823474f95
--- /dev/null
+++ b/doc/bugs/Hanging_on_install_on_Mountain_lion/comment_3_7b77fd9b7dc236c345f2f6149c8138ee._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnGrQBFPptA2GU_Nx8KrxRGtyAS7PIlwjw"
+ nickname="Nathan"
+ subject="comment 3"
+ date="2013-06-25T13:39:55Z"
+ content="""
+Hi there, I couldn't get it to build with cabal (likely my fault, ie. inexperience).
+
+Can I please confirm something: Theoretically I dont need to do *any* preparation to start using git-annex assistant, right? As in I dont need to first configure git separately, or set up any folder hierarchies or such? The idea is that the assistant itself does all that's required? I just wonder if through my naivety I am missing a basic step and making a rookie mistake.
+
+A couple of notes:
+
+Running **/Applications/git-annex.app/Contents/MacOS/git-annex init**
+
+Returns **git-annex: Not in a git repository.**
+
+Any further assistance you may offer woudl be great, because I'd love to start investigating the potential for using git-annex in a multi-user environment (managing motion design projects).
+"""]]
diff --git a/doc/bugs/Hanging_on_install_on_Mountain_lion/comment_5_08289596445d7588e43d35490fbfe5f4._comment b/doc/bugs/Hanging_on_install_on_Mountain_lion/comment_5_08289596445d7588e43d35490fbfe5f4._comment
new file mode 100644
index 000000000..d9700eab0
--- /dev/null
+++ b/doc/bugs/Hanging_on_install_on_Mountain_lion/comment_5_08289596445d7588e43d35490fbfe5f4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmxns2UBAMDbTwrwHq_Lx1sNKrVVayq1X4"
+ nickname="Darren"
+ subject="comment 5"
+ date="2013-06-25T14:54:47Z"
+ content="""
+same problem here, latest version from the website and running OSX 10.8.4.
+"""]]
diff --git a/doc/bugs/Hanging_on_install_on_Mountain_lion/comment_5_2a336fe7b8aed07cbdaa868bd34078f9._comment b/doc/bugs/Hanging_on_install_on_Mountain_lion/comment_5_2a336fe7b8aed07cbdaa868bd34078f9._comment
new file mode 100644
index 000000000..aceafcf9f
--- /dev/null
+++ b/doc/bugs/Hanging_on_install_on_Mountain_lion/comment_5_2a336fe7b8aed07cbdaa868bd34078f9._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.193"
+ subject="comment 5"
+ date="2013-06-25T17:14:02Z"
+ content="""
+To get this fixed, someone is going to need to do some investigation of what is happening. I do not have resources to debug OSX problems that cannot be reproduced using the command line.
+"""]]
diff --git a/doc/bugs/Hanging_on_install_on_Mountain_lion/comment_6_ea7a40c3b6748738421aed00a6f7ca10._comment b/doc/bugs/Hanging_on_install_on_Mountain_lion/comment_6_ea7a40c3b6748738421aed00a6f7ca10._comment
new file mode 100644
index 000000000..16ecca625
--- /dev/null
+++ b/doc/bugs/Hanging_on_install_on_Mountain_lion/comment_6_ea7a40c3b6748738421aed00a6f7ca10._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkQafKy7hNSEolLs6TvbgUnkklTctUY9LI"
+ nickname="Zellyn"
+ subject="Happy to debug"
+ date="2013-06-26T02:47:35Z"
+ content="""
+Hi Joey, I'm having the same problem. I'm currently trying the homebrew route.
+
+I would be happy to debug, but I'm not familiar at all with git annex or the assistant, so I don't even know where to start looking. Let me know what would be useful to try, and I'll try it and post the results.
+"""]]
diff --git a/doc/bugs/Hanging_on_install_on_Mountain_lion/comment_7_00962da9288976f8a48d0cbc08e1d9e2._comment b/doc/bugs/Hanging_on_install_on_Mountain_lion/comment_7_00962da9288976f8a48d0cbc08e1d9e2._comment
new file mode 100644
index 000000000..2bddffc70
--- /dev/null
+++ b/doc/bugs/Hanging_on_install_on_Mountain_lion/comment_7_00962da9288976f8a48d0cbc08e1d9e2._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkQafKy7hNSEolLs6TvbgUnkklTctUY9LI"
+ nickname="Zellyn"
+ subject="More info"
+ date="2013-06-26T04:21:47Z"
+ content="""
+Looking at what the browser is doing:
+
+1. Open file://localhost/var/folders/00/0wpr8000h01000cxqpysvccm003kv1/T/webapp72069.html
+2. Meta refresh to: http://127.0.0.1:64190/?auth=7b8464a1fe3ed0386520bd2b214dbb963864b345151edc0b5febc0310a7974d89fda2ab6464d5791e6b1a474bebb86026b7c90ebb920c51a8291940c75e7c1f9
+3. Redirect to: http://127.0.0.1:64190/config?auth=7b8464a1fe3ed0386520bd2b214dbb963864b345151edc0b5febc0310a7974d89fda2ab6464d5791e6b1a474bebb86026b7c90ebb920c51a8291940c75e7c1f9
+4. Redirect to: http://127.0.0.1:64190/config/repository/new/first?auth=7b8464a1fe3ed0386520bd2b214dbb963864b345151edc0b5febc0310a7974d89fda2ab6464d5791e6b1a474bebb86026b7c90ebb920c51a8291940c75e7c1f9
+5. hang indefinitely
+
+"""]]
diff --git a/doc/bugs/Hanging_on_install_on_Mountain_lion/comment_8_5d53d23e529f33f6e7deb10643831613._comment b/doc/bugs/Hanging_on_install_on_Mountain_lion/comment_8_5d53d23e529f33f6e7deb10643831613._comment
new file mode 100644
index 000000000..14cc3ec55
--- /dev/null
+++ b/doc/bugs/Hanging_on_install_on_Mountain_lion/comment_8_5d53d23e529f33f6e7deb10643831613._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.193"
+ subject="comment 8"
+ date="2013-06-26T19:06:42Z"
+ content="""
+Thanks, I've reproduced the hang using wget at the command line.
+
+Probably something has been broken in the switch to a new version of Yesod.
+
+"""]]
diff --git a/doc/bugs/Hanging_on_install_on_Mountain_lion/comment_9_f00c8761e3184975b6645c0c3e241365._comment b/doc/bugs/Hanging_on_install_on_Mountain_lion/comment_9_f00c8761e3184975b6645c0c3e241365._comment
new file mode 100644
index 000000000..2639fb350
--- /dev/null
+++ b/doc/bugs/Hanging_on_install_on_Mountain_lion/comment_9_f00c8761e3184975b6645c0c3e241365._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkQafKy7hNSEolLs6TvbgUnkklTctUY9LI"
+ nickname="Zellyn"
+ subject="Excellent"
+ date="2013-06-26T21:01:38Z"
+ content="""
+Excellent news. If you need any more help debugging, let me know.
+
+Out of curiosity, what would be the next step of useful information for you? lsof on the process didn't seem to show anything interesting...
+"""]]
diff --git a/doc/bugs/Hangs_on_creating_repository_when_using_--listen.mdwn b/doc/bugs/Hangs_on_creating_repository_when_using_--listen.mdwn
new file mode 100644
index 000000000..913e02cd5
--- /dev/null
+++ b/doc/bugs/Hangs_on_creating_repository_when_using_--listen.mdwn
@@ -0,0 +1,46 @@
+### Please describe the problem.
+When using the git-annex webapp with the --listen paramter it as usual asks one to create a new repository on first startup. Selecting a repository location here and clicking "Make repository" button leads to a never ending loading browser and some git zombies.
+
+### What steps will reproduce the problem?
+Two machines needed
+
+1. On machine one: git-annex webapp --listen=\<machine1-public-ip\>:34561 (you can choose another port as well)
+2. On machine two: use a browser to go to the url the last step gave you
+3. Click on make repository
+
+
+### What version of git-annex are you using? On what operating system?
+* git-annex version: 4.20130601
+* build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP DNS
+* built using cabal
+* on Ubuntu 13.04 32bit
+
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+[2013-06-12 21:59:37 CEST] main: starting assistant version 4.20130601
+WebApp crashed: unable to bind to local socket
+[2013-06-12 21:59:37 CEST] WebApp: warning WebApp crashed: unable to bind to local socket
+
+ dbus failed; falling back to mtab polling (ClientError {clientErrorMessage = "runClient: unable to determine DBUS address", clientErrorFatal = True})
+
+ No known network monitor available through dbus; falling back to polling
+(scanning...) [2013-06-12 21:59:37 CEST] Watcher: Performing startup scan
+(started...)
+
+
+# End of transcript or log.
+"""]]
+
+> The problem is that, when a port is specified, it is used for each web
+> server started, and the process of making a new repository unavoidably
+> requires it to start a second web server instance. This would also affect
+> switching between existing repositories in the webapp. I don't see
+> any way to make it not crash here, except for ignoring the port it was told
+> to use when something else is already listening there. --[[Joey]]
+
+[[!tag /design/assistant]]
diff --git a/doc/bugs/Hangs_on_creating_repository_when_using_--listen/comment_1_8cbe786de8cf8b407418149b9c811aab._comment b/doc/bugs/Hangs_on_creating_repository_when_using_--listen/comment_1_8cbe786de8cf8b407418149b9c811aab._comment
new file mode 100644
index 000000000..b0132de65
--- /dev/null
+++ b/doc/bugs/Hangs_on_creating_repository_when_using_--listen/comment_1_8cbe786de8cf8b407418149b9c811aab._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawk7iPiqWr3BVPLWEDvJhSSvcOqheLEbLNo"
+ nickname="Dirk"
+ subject="comment 1"
+ date="2013-06-15T11:39:15Z"
+ content="""
+Thanks for looking into this.
+
+Following your explanation there is no easy solution to this. I guess one could potentially grey out all actions in the webapp that lead to problems. But that might be overkill for a rare use case (which I assume the use of --listen with a given port is). Maybe just documenting for which use cases (repository creation, switching, ...?) the provided port will lead to problems (e.g. in the man page under the --listen section) is good enough (it is for me)?
+
+
+
+
+"""]]
diff --git a/doc/bugs/Hangs_on_creating_repository_when_using_--listen/comment_2_dc128eeddeaaf3f84e71aca0fb7d341f._comment b/doc/bugs/Hangs_on_creating_repository_when_using_--listen/comment_2_dc128eeddeaaf3f84e71aca0fb7d341f._comment
new file mode 100644
index 000000000..55d7efa1c
--- /dev/null
+++ b/doc/bugs/Hangs_on_creating_repository_when_using_--listen/comment_2_dc128eeddeaaf3f84e71aca0fb7d341f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 2"
+ date="2013-08-24T18:52:11Z"
+ content="""
+This also affects creating a second repository in the webapp, not just the repository creation at first startup.
+"""]]
diff --git a/doc/bugs/Hard_links_not_synced_in_direct_mode.mdwn b/doc/bugs/Hard_links_not_synced_in_direct_mode.mdwn
new file mode 100644
index 000000000..8b03134f1
--- /dev/null
+++ b/doc/bugs/Hard_links_not_synced_in_direct_mode.mdwn
@@ -0,0 +1,125 @@
+### Please describe the problem.
+
+Direct mode repositories seem to initially ignore hard linked files and then when changes are done to them sync them as separate files. However, changes to one file are only propagated to that file and not to any of the others that are hardlinked to it.
+
+### What steps will reproduce the problem?
+
+Inside a direct mode repository linked to a ssh remote:
+
+[[!format sh """
+$ ls -l
+total 0
+$ echo "something" > foo
+$ ln foo bar
+$ ls -l
+total 8
+-rw-r--r-- 2 pedrocr pedrocr 10 May 29 12:08 bar
+-rw-r--r-- 2 pedrocr pedrocr 10 May 29 12:08 foo
+$ tail .git/annex/daemon.log
+ 6c0fbd7..0bb8ef9 git-annex -> synced/git-annex
+ 0bae1b4..bfedc45 master -> synced/master
+
+sent 77 bytes received 31 bytes 72.00 bytes/sec
+total size is 10 speedup is 0.09
+[2013-05-29 12:08:03 WEST] Transferrer: Uploaded foo
+Already up-to-date.
+[2013-05-29 12:08:05 WEST] Pusher: Syncing with golias
+To ssh://golias.git-annex/home/pedrocr/testsync
+ 0bb8ef9..2ce5013 git-annex -> synced/git-annex
+$ git status
+# On branch master
+# Changes not staged for commit:
+# (use "git add <file>..." to update what will be committed)
+# (use "git checkout -- <file>..." to discard changes in working directory)
+#
+# typechange: foo
+#
+# Untracked files:
+# (use "git add <file>..." to include in what will be committed)
+#
+# bar
+no changes added to commit (use "git add" and/or "git commit -a")
+"""]]
+
+On the remote repository:
+
+[[!format sh """
+$ ls -l
+total 4
+-rw-r--r-- 1 pedrocr pedrocr 10 May 29 12:08 foo
+"""]]
+
+If I now just touch the linked file on the repository:
+
+[[!format sh """
+$ touch bar
+$ tail .git/annex/daemon.log
+
+(merging synced/git-annex into git-annex...)
+(Recording state in git...)
+add bar (checksum...) [2013-05-29 12:12:49 WEST] Committer: Committing changes to git
+[2013-05-29 12:12:49 WEST] Pusher: Syncing with golias
+Already up-to-date.
+To ssh://golias.git-annex/home/pedrocr/testsync
+ 2ce5013..d36166b git-annex -> synced/git-annex
+ bfedc45..ee3a7a1 master -> synced/master
+Already up-to-date.
+"""]]
+
+On the remote repository:
+
+[[!format sh """
+$ ls -l
+total 8
+-rw-r--r-- 1 pedrocr pedrocr 10 May 29 12:08 bar
+-rw-r--r-- 1 pedrocr pedrocr 10 May 29 12:08 foo
+"""]]
+
+Note that now bar has been synced as a new file and not a hardlink as it should be (the 1's after the permissions).
+
+The sync also isn't acting properly on the linked files. For example.
+
+First in the origin repository:
+
+[[!format sh """
+$ cat bar
+something
+$ cat foo
+something
+$ echo "someotherthing" > bar
+$ cat bar
+someotherthing
+$ cat foo
+someotherthing
+"""]]
+
+The result in the destination:
+
+[[!format sh """
+$ cat bar
+someotherthing
+$ cat foo
+something
+"""]]
+
+So even if the intended behavior is for hardlinked files to be synced as two separate files the sync isn't correct because the two files changed in the origin and only one of them changed in the destination. This probably needs to be fixed with actual hard links for real filesystems and with some copying for crippled filesystems.
+
+### What version of git-annex are you using? On what operating system?
+
+[[!format sh """
+$ git annex version
+git-annex version: 4.20130516.1
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP
+local repository version: 4
+default repository version: 3
+supported repository versions: 3 4
+upgrade supported from repository versions: 0 1 2
+$ lsb_release -a
+No LSB modules are available.
+Distributor ID: Ubuntu
+Description: Ubuntu 12.04.2 LTS
+Release: 12.04
+Codename: precise
+"""]]
+
+
diff --git a/doc/bugs/Hard_links_not_synced_in_direct_mode/comment_1_aaa781664ae0c62c4f6530cb075ed367._comment b/doc/bugs/Hard_links_not_synced_in_direct_mode/comment_1_aaa781664ae0c62c4f6530cb075ed367._comment
new file mode 100644
index 000000000..5d7422c08
--- /dev/null
+++ b/doc/bugs/Hard_links_not_synced_in_direct_mode/comment_1_aaa781664ae0c62c4f6530cb075ed367._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkx5V3MTbzCXS3J7Mn9FEq8M9bPPYMkAHY"
+ nickname="Pedro"
+ subject="comment 1"
+ date="2013-05-29T11:33:05Z"
+ content="""
+Implementing hard links will probably also require handling the edge case where the user has setup two repositories where one of them spans filesystems. So:
+
+- Repository A is all in a single filesystem
+- Repository B has it's root in one filesystem and them /someotherdirectory/ is another filesystem.
+
+If the user in repository A does a \"ln /somefile /someotherdirectory/otherfile\" you'd need to treat this as in the crippled case as repository B can't do the hardlink spanning filesystems.
+
+Another edge case may also be that OSX supports hardlinked directories for use with their TimeMachine feature. The feature isn't exposed through the normal ln command but users may sometimes hack around that[1]. Also, any TimeMachine backups will naturally have hardlinked directories.
+
+[1] http://stackoverflow.com/questions/1432540/creating-directory-hard-links-in-macos-x
+"""]]
diff --git a/doc/bugs/Hard_links_not_synced_in_direct_mode/comment_2_213aa10909d1fd0f20ed078a7ed93e79._comment b/doc/bugs/Hard_links_not_synced_in_direct_mode/comment_2_213aa10909d1fd0f20ed078a7ed93e79._comment
new file mode 100644
index 000000000..39d601dba
--- /dev/null
+++ b/doc/bugs/Hard_links_not_synced_in_direct_mode/comment_2_213aa10909d1fd0f20ed078a7ed93e79._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-05-29T15:39:48Z"
+ content="""
+git does not support hard linked files, so neither can git-annex.
+"""]]
diff --git a/doc/bugs/Hard_links_not_synced_in_direct_mode/comment_3_e6b783d9aaae20c0d35e9888d878716a._comment b/doc/bugs/Hard_links_not_synced_in_direct_mode/comment_3_e6b783d9aaae20c0d35e9888d878716a._comment
new file mode 100644
index 000000000..179d80b21
--- /dev/null
+++ b/doc/bugs/Hard_links_not_synced_in_direct_mode/comment_3_e6b783d9aaae20c0d35e9888d878716a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-05-29T16:11:46Z"
+ content="""
+It would be possible to make the assistant use the inotify CREATE event (which it currently ignores) to add a file to the repository when a hard link is created. However, when a hard linked file is modified, inotify only sends an event for the file that was changed, not for other hard links to it. So, without keeping track of all hard links that exist on my own, there's no way for the assistant to automatically handle that case. And even if it tried to, hard links to files in the repository from outside the repository would still allow modifying them without the assistant being able to detect it.
+
+Since hard links cannot be propigated over git anyway, I don't want to get into this mess. It's best to wontfix this I think.
+"""]]
diff --git a/doc/bugs/Hard_links_not_synced_in_direct_mode/comment_4_b008ae7b1cf8685d92c9a87a7609de1e._comment b/doc/bugs/Hard_links_not_synced_in_direct_mode/comment_4_b008ae7b1cf8685d92c9a87a7609de1e._comment
new file mode 100644
index 000000000..8e8acd9cb
--- /dev/null
+++ b/doc/bugs/Hard_links_not_synced_in_direct_mode/comment_4_b008ae7b1cf8685d92c9a87a7609de1e._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkx5V3MTbzCXS3J7Mn9FEq8M9bPPYMkAHY"
+ nickname="Pedro"
+ subject="comment 4"
+ date="2013-05-29T18:48:10Z"
+ content="""
+I agree with your assessment for the traditional git-annex, as it's an extension of git. For the assistant (in direct mode at least) it seems like broken behavior, there will be files that exist on one side but not the other and files that have the same content on one side but not the other.
+
+I just had a look and unfortunately there doesn't seem to be a general way to do inode to path lookup in UNIX, so an inode cache would really be needed. It would look something like:
+
+* On inotify CREATE detect that the file has other hardlinked instances, find out if they are in the repository by keeping a inode->path cache of all files
+* When the file is a hardlink to another file already in the repository commit some kind of special file to git that states \"hardlink to /path/to/otherfile\" and add metadata to the original file saying what files are hardlinks to it
+* When a remote gets a special file after a sync it will itself run a \"ln /path/to/otherfile /path/to/newfile\" or alteratively a copy when the two paths span filesystems or the filesystem is crippled
+* When a crippled remote gets a write to a file with hardlinks, it will replicate those writes to the other files (this is where the metadata is needed)
+* When a crippled remote does a write to a file with hardlinks that file becomes independent in the remotes with hardlinks since the content is now different between the two (or more) files.
+
+This does get pretty hairy with the corner cases. Right now the simple case of \"sync between two non-crippled filesystems\" shows pretty surprising results though so I'd argue something needs to change. I think that for direct mode to really be a \"transparent folder sync\" kind of solution this should be fixed.
+"""]]
diff --git a/doc/bugs/Hard_links_not_synced_in_direct_mode/comment_5_949c891209713a2c0a5e66af11ed4c79._comment b/doc/bugs/Hard_links_not_synced_in_direct_mode/comment_5_949c891209713a2c0a5e66af11ed4c79._comment
new file mode 100644
index 000000000..52f3e30f7
--- /dev/null
+++ b/doc/bugs/Hard_links_not_synced_in_direct_mode/comment_5_949c891209713a2c0a5e66af11ed4c79._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.193"
+ subject="comment 5"
+ date="2013-06-26T16:34:23Z"
+ content="""
+To fix [[Problems_with_syncing_gnucash]], I have made some changes to how hard links are dealt with.
+
+Assistant will now notice when a hard link is created, and add the same thing to git it would add for any other file. The hard link is not propigated to other repositories.
+
+Files remain hard linked locally. This means that a change to one will affect the contents of the other. The assistant, lacking a hard link cache, will not notice this, and so will commit the change to the file that was written to, but not commit its hard link. Running `git annex add` manually (or restarting the assistant) will make it finally notice the other file has changed.
+
+So, the assistant still does not keep hard links in sync on an ongoing basis. This bug is still unsolved.
+"""]]
diff --git a/doc/bugs/How_can_I_solve_a_non-fast-forward_push_without_using_the_assistant__63__.mdwn b/doc/bugs/How_can_I_solve_a_non-fast-forward_push_without_using_the_assistant__63__.mdwn
new file mode 100644
index 000000000..69b0c4116
--- /dev/null
+++ b/doc/bugs/How_can_I_solve_a_non-fast-forward_push_without_using_the_assistant__63__.mdwn
@@ -0,0 +1,295 @@
+### Please describe the problem.
+
+I use both the assistant and the command line. Unfortunately I often end up
+in a state where I cannot do a "git annex sync" (it fails as described below)
+and I have to use the assistant to synchronize things to make the sync work. I
+would like to know how to do the same thing using only the command line.
+
+### What steps will reproduce the problem?
+
+This problem involves two repos: a local, indirect mode, manual group, repo, and
+a ssh remote archive group bare repo (with full git annex available
+remotely). The local repo is "top" and the remote one is "mini_archive".
+
+I start with the assistant not running, and the two repos in sync. Note that the
+remote server cannot directly contact the local repo.
+
+local:
+
+ schmitta@top ~/D/annex (master)> git annex sync
+ commit
+ ok
+ pull mini_archive
+ ok
+
+remote:
+
+ schmitta@mini ~/a/archive> git annex sync
+ commit
+ ok
+
+I then add a file locally and try to sync, getting a problem on mini_archive:
+
+ schmitta@top ~/D/annex (master)> git annex add videos/Minecraft/Icy\ and\ FlowerChild\ Play\ -\ Better\ Than\ Wolves\ 3-qg6LVTcDl4Y.mp4
+ add videos/Minecraft/Icy and FlowerChild Play - Better Than Wolves 3-qg6LVTcDl4Y.mp4 (checksum...) ok
+ (Recording state in git...)
+ schmitta@top ~/D/annex (master)> git annex sync
+ commit
+ ok
+ pull mini_archive
+ ok
+ push mini_archive
+ Counting objects: 15, done.
+ Delta compression using up to 4 threads.
+ Compressing objects: 100% (10/10), done.
+ Writing objects: 100% (10/10), 1.01 KiB | 0 bytes/s, done.
+ Total 10 (delta 4), reused 0 (delta 0)
+ remote: error: denying non-fast-forward refs/heads/synced/git-annex (you should pull first)
+ To ssh://schmitta@git-annex-**.**.**.**-schmitta_annex.2Farchive/~/annex/archive/
+ a5b002b..dde2626 master -> synced/master
+ ! [remote rejected] git-annex -> synced/git-annex (non-fast-forward)
+ error: failed to push some refs to 'ssh://schmitta@git-annex-**.**.**.**-schmitta_annex.2Farchive/~/annex/archive/'
+ failed
+ git-annex: sync: 1 failed
+
+I try to merge and sync on the remote (I assume sync also does merge, but I'm
+not sure).
+
+ schmitta@mini ~/a/archive> git annex merge
+ merge git-annex ok
+ schmitta@mini ~/a/archive> git annex sync
+ commit
+ ok
+
+Back on the local machine, I still have the conflict.
+
+ schmitta@top ~/D/annex (master) [1]> git annex sync
+ commit
+ ok
+ pull mini_archive
+ ok
+ push mini_archive
+ Counting objects: 7, done.
+ Delta compression using up to 4 threads.
+ Compressing objects: 100% (5/5), done.
+ Writing objects: 100% (5/5), 513 bytes | 0 bytes/s, done.
+ Total 5 (delta 1), reused 0 (delta 0)
+ remote: error: denying non-fast-forward refs/heads/synced/git-annex (you should pull first)
+ To ssh://schmitta@git-annex-**.**.**.**-schmitta_annex.2Farchive/~/annex/archive/
+ ! [remote rejected] git-annex -> synced/git-annex (non-fast-forward)
+ error: failed to push some refs to 'ssh://schmitta@git-annex-**.**.**.**-schmitta_annex.2Farchive/~/annex/archive/'
+ failed
+ git-annex: sync: 1 failed
+
+From this state, the only way to resolve things is to launch the web app. It
+tells me "synced with mini_archive" (and it starts uploading the new file). Then
+on the server there is something to merge. (I haven't waited for the file to
+finish uploading in this case.)
+
+ schmitta@mini ~/a/archive> git annex merge
+ merge git-annex (merging refs/synced/1cdfb490-0660-41fb-b7ce-74b89abb9aac/git-annex into git-annex...)
+ ok
+ schmitta@mini ~/a/archive> git annex sync
+ commit
+ ok
+
+and I can then sync on the local repo:
+
+ schmitta@top ~/D/annex (master) [1]> git annex sync
+ commit
+ ok
+ pull mini_archive
+ From ssh://git-annex-**.**.**.**-schmitta_annex.2Farchive/~/annex/archive
+ 8f39d4c..cb7f6c3 git-annex -> mini_archive/git-annex
+ ok
+
+Note that I need to do the remote merge for things to work. After the file has
+finished uploading, I get back in a conflict:
+
+ schmitta@top ~/D/annex (master)> git annex sync
+ commit
+ ok
+ pull mini_archive
+ ok
+ push mini_archive
+ Total 0 (delta 0), reused 0 (delta 0)
+ remote: error: denying non-fast-forward refs/heads/synced/git-annex (you should pull first)
+ To ssh://schmitta@git-annex-**.**.**.**-schmitta_annex.2Farchive/~/annex/archive/
+ ! [remote rejected] git-annex -> synced/git-annex (non-fast-forward)
+ error: failed to push some refs to 'ssh://schmitta@git-annex-**.**.**.**-schmitta_annex.2Farchive/~/annex/archive/'
+ failed
+ git-annex: sync: 1 failed
+
+If I disable and re-enable the sync on the server (forcing a sync), I still have
+a conflict locally:
+
+ schmitta@top ~/D/annex (master) [1]> git annex sync
+ commit
+ ok
+ pull mini_archive
+ ok
+ push mini_archive
+ Total 0 (delta 0), reused 0 (delta 0)
+ remote: error: denying non-fast-forward refs/heads/synced/git-annex (you should pull first)
+ To ssh://schmitta@git-annex-**.**.**.**-schmitta_annex.2Farchive/~/annex/archive/
+ ! [remote rejected] git-annex -> synced/git-annex (non-fast-forward)
+ error: failed to push some refs to 'ssh://schmitta@git-annex-**.**.**.**-schmitta_annex.2Farchive/~/annex/archive/'
+ failed
+ git-annex: sync: 1 failed
+
+It only get solved by doing a merge on the server:
+
+ schmitta@mini ~/a/archive> git annex merge
+ merge git-annex (merging refs/synced/1cdfb490-0660-41fb-b7ce-74b89abb9aac/git-annex into git-annex...)
+ (Recording state in git...)
+ ok
+
+ schmitta@top ~/D/annex (master) [1]> git annex sync
+ commit
+ ok
+ pull mini_archive
+ remote: Counting objects: 13, done.
+ remote: Compressing objects: 100% (5/5), done.
+ remote: Total 5 (delta 3), reused 0 (delta 0)
+ Unpacking objects: 100% (5/5), done.
+ From ssh://git-annex-**.**.**.**-schmitta_annex.2Farchive/~/annex/archive
+ cb7f6c3..d177e1a git-annex -> mini_archive/git-annex
+ ok
+ (merging mini_archive/git-annex into git-annex...)
+
+
+### What version of git-annex are you using? On what operating system?
+
+Current version available on cabal:
+
+ schmitta@top ~/D/annex (master)> git annex version
+ git-annex version: 4.20131002
+ build flags: Assistant Webapp Pairing Testsuite S3 WebDAV FsEvents XMPP DNS Feeds Quvi
+ key/value backends: SHA256E SHA1E SHA512E SHA224E SHA384E SKEIN256E SKEIN512E SHA256 SHA1 SHA512 SHA224 SHA384 SKEIN256 SKEIN512 WORM URL
+ remote types: git gcrypt S3 bup directory rsync web webdav glacier hook
+ local repository version: 3
+ default repository version: 3
+ supported repository versions: 3 4
+ upgrade supported from repository versions: 0 1 2
+
+ schmitta@mini ~/a/archive> git annex version
+ git-annex version: 4.20131002
+ build flags: Assistant Webapp Pairing Testsuite S3 WebDAV FsEvents XMPP DNS Feeds Quvi
+ key/value backends: SHA256E SHA1E SHA512E SHA224E SHA384E SKEIN256E SKEIN512E SHA256 SHA1 SHA512 SHA224 SHA384 SKEIN256 SKEIN512 WORM URL
+ remote types: git gcrypt S3 bup directory rsync web webdav glacier hook
+ local repository version: 3
+ default repository version: 3
+ supported repository versions: 3 4
+ upgrade supported from repository versions: 0 1 2
+
+
+### Please provide any additional information below.
+
+Here is daemon.log. It mentions another repo which is an external
+hard drive not plugged it at the moment. I'm skipping the file transmission
+(...).
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+[2013-10-23 14:02:05 CEST] main: starting assistant version 4.20131002
+[2013-10-23 14:02:05 CEST] TransferScanner: Syncing with hole, mini_archive
+Already up-to-date.
+fatal: '/Volumes/hole/annex/' does not appear to be a git repository
+fatal: Could not read from remote repository.
+
+Please make sure you have the correct access rights
+and the repository exists.
+
+(scanning...) [2013-10-23 14:02:06 CEST] Watcher: Performing startup scan
+Already up-to-date.
+Already up-to-date.
+fatal: '/Volumes/hole/annex/' does not appear to be a git repository
+fatal: Could not read from remote repository.
+
+Please make sure you have the correct access rights
+and the repository exists.
+remote: error: denying non-fast-forward refs/heads/synced/git-annex (you should pull first)
+To ssh://schmitta@git-annex-**.**.**.**-schmitta_annex.2Farchive/~/annex/archive/
+ ! [remote rejected] git-annex -> synced/git-annex (non-fast-forward)
+error: failed to push some refs to 'ssh://schmitta@git-annex-**.**.**.**-schmitta_annex.2Farchive/~/annex/archive/'
+fatal: '/Volumes/hole/annex/' does not appear to be a git repository
+fatal: Could not read from remote repository.
+
+Please make sure you have the correct access rights
+and the repository exists.
+fatal: '/Volumes/hole/annex/' does not appear to be a git repository
+fatal: Could not read from remote repository.
+
+Please make sure you have the correct access rights
+and the repository exists.
+remote: error: denying non-fast-forward refs/heads/synced/git-annex (you should pull first)
+To ssh://schmitta@git-annex-**.**.**.**-schmitta_annex.2Farchive/~/annex/archive/
+ ! [remote rejected] git-annex -> synced/git-annex (non-fast-forward)
+error: failed to push some refs to 'ssh://schmitta@git-annex-**.**.**.**-schmitta_annex.2Farchive/~/annex/archive/'
+fatal: '/Volumes/hole/annex/' does not appear to be a git repository
+fatal: Could not read from remote repository.
+
+Please make sure you have the correct access rights
+and the repository exists.
+[2013-10-23 14:02:10 CEST] Committer: Committing changes to git
+[2013-10-23 14:02:10 CEST] Pusher: Syncing with mini_archive
+
+
+(Recording state in git...)
+(started...) To ssh://schmitta@git-annex-**.**.**.**-schmitta_annex.2Farchive/~/annex/archive/
+ 8f39d4c..cb7f6c3 git-annex -> refs/synced/1cdfb490-0660-41fb-b7ce-74b89abb9aac/git-annex
+ a5b002b..dde2626 master -> refs/synced/1cdfb490-0660-41fb-b7ce-74b89abb9aac/master
+remote: error: denying non-fast-forward refs/heads/synced/git-annex (you should pull first)
+To ssh://schmitta@git-annex-**.**.**.**-schmitta_annex.2Farchive/~/annex/archive/
+ ! [remote rejected] git-annex -> synced/git-annex (non-fast-forward)
+error: failed to push some refs to 'ssh://schmitta@git-annex-**.**.**.**-schmitta_annex.2Farchive/~/annex/archive/'
+remote: error: denying non-fast-forward refs/heads/synced/git-annex (you should pull first)
+To ssh://schmitta@git-annex-**.**.**.**-schmitta_annex.2Farchive/~/annex/archive/
+ ! [remote rejected] git-annex -> synced/git-annex (non-fast-forward)
+error: failed to push some refs to 'ssh://schmitta@git-annex-**.**.**.**-schmitta_annex.2Farchive/~/annex/archive/'
+Everything up-to-date
+(gpg)
+
+
+SHA256E-s608232213--d4d6e02e651b1d265ff1c041ee8e8c23db9d880140816d62b8cc82cee4db3a54.mp4
+
+...
+
+sent 608306626 bytes received 42 bytes 5133389.60 bytes/sec
+total size is 608232213 speedup is 1.00
+[2013-10-23 14:04:13 CEST] Transferrer: Uploaded Icy and F..cDl4Y.mp4
+[2013-10-23 14:04:13 CEST] Pusher: Syncing with mini_archive
+remote: error: denying non-fast-forward refs/heads/synced/git-annex (you should pull first)
+To ssh://schmitta@git-annex-**.**.**.**-schmitta_annex.2Farchive/~/annex/archive/
+ ! [remote rejected] git-annex -> synced/git-annex (non-fast-forward)
+error: failed to push some refs to 'ssh://schmitta@git-annex-**.**.**.**-schmitta_annex.2Farchive/~/annex/archive/'
+remote: error: denying non-fast-forward refs/heads/synced/git-annex (you should pull first)
+To ssh://schmitta@git-annex-**.**.**.**-schmitta_annex.2Farchive/~/annex/archive/
+ ! [remote rejected] git-annex -> synced/git-annex (non-fast-forward)
+error: failed to push some refs to 'ssh://schmitta@git-annex-**.**.**.**-schmitta_annex.2Farchive/~/annex/archive/'
+To ssh://schmitta@git-annex-**.**.**.**-schmitta_annex.2Farchive/~/annex/archive/
+ cb7f6c3..927cc1c git-annex -> refs/synced/1cdfb490-0660-41fb-b7ce-74b89abb9aac/git-annex
+[2013-10-23 14:05:35 CEST] main: Syncing with mini_archive
+remote: error: denying non-fast-forward refs/heads/synced/git-annex (you should pull first)
+To ssh://schmitta@git-annex-**.**.**.**-schmitta_annex.2Farchive/~/annex/archive/
+ ! [remote rejected] git-annex -> synced/git-annex (non-fast-forward)
+error: failed to push some refs to 'ssh://schmitta@git-annex-**.**.**.**-schmitta_annex.2Farchive/~/annex/archive/'
+remote: error: denying non-fast-forward refs/heads/synced/git-annex (you should pull first)
+To ssh://schmitta@git-annex-**.**.**.**-schmitta_annex.2Farchive/~/annex/archive/
+ ! [remote rejected] git-annex -> synced/git-annex (non-fast-forward)
+error: failed to push some refs to 'ssh://schmitta@git-annex-**.**.**.**-schmitta_annex.2Farchive/~/annex/archive/'
+Everything up-to-date
+
+
+# End of transcript or log.
+"""]]
+
+> So, receive.denyNonFastforwards was the problem. It turns out that
+> `git init --bare --shared` sets that by default, and the webapp
+> uses that to create repositories on ssh server. I have made the webapp
+> unset receive.denyNonFastforwards when setting up such a repository.
+>
+> Also added something to the assistant release notes about this
+> to handle existing repositories. [[done]] --[[Joey]]
diff --git a/doc/bugs/How_can_I_solve_a_non-fast-forward_push_without_using_the_assistant__63__/comment_1_0ddcbe0ccecdec1012964dfa436a3eee._comment b/doc/bugs/How_can_I_solve_a_non-fast-forward_push_without_using_the_assistant__63__/comment_1_0ddcbe0ccecdec1012964dfa436a3eee._comment
new file mode 100644
index 000000000..ef2399d81
--- /dev/null
+++ b/doc/bugs/How_can_I_solve_a_non-fast-forward_push_without_using_the_assistant__63__/comment_1_0ddcbe0ccecdec1012964dfa436a3eee._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="64.134.31.139"
+ subject="comment 1"
+ date="2013-10-23T15:21:34Z"
+ content="""
+<pre>
+To ssh://schmitta@git-annex-**.**.**.**-schmitta_annex.2Farchive/~/annex/archive/
+ ! [remote rejected] git-annex -> synced/git-annex (non-fast-forward)
+</pre>
+
+Since version 4.20130909, git-annex is supposed to have avoided this problem by forcing the push of the git-annex branch. If you run `git annex sync --debug`, you should see:
+
+[2013-10-23 11:12:54 EDT] call: git [\"--git-dir=annex/.git\",\"--work-tree=annex\",\"push\",\"foo\",\"+git-annex:synced/git-annex\",\"master:synced/master\"]
+
+The \"+\" flag before the branch name forces git push to update the remote branch even if it's not a fast-forward.
+
+You should be able to verify if git-annex is doing that, and run the same git push command manually to investigate why it might not be working. I have not seen this problem since putting in that fix, and I saw it before. Perhaps your server has an old or broken version of git that ignores this flag, or some git configuration setting I am not aware of that prevents it from working.
+"""]]
diff --git a/doc/bugs/How_can_I_solve_a_non-fast-forward_push_without_using_the_assistant__63__/comment_2_5765b849bcf045ead9f007bd50b2cfbd._comment b/doc/bugs/How_can_I_solve_a_non-fast-forward_push_without_using_the_assistant__63__/comment_2_5765b849bcf045ead9f007bd50b2cfbd._comment
new file mode 100644
index 000000000..44ccfe00b
--- /dev/null
+++ b/doc/bugs/How_can_I_solve_a_non-fast-forward_push_without_using_the_assistant__63__/comment_2_5765b849bcf045ead9f007bd50b2cfbd._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="http://alan.petitepomme.net/"
+ nickname="Alan Schmitt"
+ subject="comment 2"
+ date="2013-10-23T16:21:30Z"
+ content="""
+I think I found the problem, after much googling.
+
+The command line you suggest is indeed tried, and rejected by the server.
+
+The answer came from [here](http://stackoverflow.com/questions/253055/how-do-i-push-amended-commit-to-the-remote-git-repo) where it says (speaking of a forced push)
+
+> Even this may not work as git allows remote repositories to refuse non-fastforward pushes at the far end by using the config variable 'receive.denynonfastforwards'.
+
+Indeed this is set in my annex repository. Note that this is a local setting, and that repository was created by the assistant.
+
+I removed this setting, and I can now push. Could the setting of this bit be a bug in the assistant?
+
+In any case, thanks a lot for indicating where to look at.
+"""]]
diff --git a/doc/bugs/Huge_annex_out_of_memory_on_switch_to_indirect_mode_and_status.mdwn b/doc/bugs/Huge_annex_out_of_memory_on_switch_to_indirect_mode_and_status.mdwn
new file mode 100644
index 000000000..07d6f3eb3
--- /dev/null
+++ b/doc/bugs/Huge_annex_out_of_memory_on_switch_to_indirect_mode_and_status.mdwn
@@ -0,0 +1,69 @@
+### Please describe the problem.
+
+[[!tag moreinfo]]
+
+I added a lot of files to my annex in direct mode. Now I want to switch to indirect mode. git-annex status and indirect create an out-of-memory error.
+
+### What steps will reproduce the problem?
+
+I am not really sure, I added a lot of files to the annex, almost 3TB.
+Then either git-annex status or git-annex indirect cause a similar error (see below).
+
+
+### What version of git-annex are you using? On what operating system?
+
+git-annex version: 4.20130501-g4a5bfb3
+local repository version: 4
+default repository version: 3
+supported repository versions: 3 4
+upgrade supported from repository versions: 0 1 2
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP
+
+Ubuntu precise
+3.2.0-26-generic
+
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/debug.log
+git-annex status
+supported backends: SHA256E SHA1E SHA512E SHA224E SHA384E SHA256 SHA1 SHA512 SHA224 SHA384 WORM URL
+supported remote types: git S3 bup directory rsync web webdav glacier hook
+repository mode: direct
+trusted repositories: 0
+semitrusted repositories: 7
+ 00000000-0000-0000-0000-000000000001 -- web
+ 0b8e6666-80d5-11e2-adf3-6f4d3d6ef0aa -- marek@x4:~/tmp/annex
+ 65c057c6-6027-11e2-84b0-b77d71696e49 -- here (.)
+ 96b31c5e-6524-11e2-b136-fbd1a03b2799 -- BackupOnGlacier
+ b509c388-629a-11e2-be5f-d376e201ad86 -- marek@x201:~/AllData
+ c636e33c-6e31-11e2-a9c4-a3c5546d69d9 -- desktop
+ fbaa1c3a-60d7-11e2-842f-9348368d2f4c -- .
+untrusted repositories: 0
+dead repositories: 0
+transfers in progress: none
+available local disk space: 81 gigabytes (+1 megabyte reserved)
+temporary directory size: 9 megabytes (clean up with git-annex unused)
+local annex keys: 61396
+local annex size: 3 terabytes
+known annex keys: git-annex: out of memory (requested 985661440 bytes)
+
+OR
+
+git-annex indirect
+commit git-annex: out of memory (requested 985661440 bytes)
+
+
+
+
+
+# End of transcript or log.
+"""]]
+
+> [[fixed|done]]. However, if you saw this behavior,
+> you have large files checked directly into git. You may
+> want to examine your repository and use git filter-branch to clean
+> it up.
+> --[[Joey]]
diff --git a/doc/bugs/Huge_annex_out_of_memory_on_switch_to_indirect_mode_and_status/comment_1_94c678e1348280a96f11d7456c240d3a._comment b/doc/bugs/Huge_annex_out_of_memory_on_switch_to_indirect_mode_and_status/comment_1_94c678e1348280a96f11d7456c240d3a._comment
new file mode 100644
index 000000000..06b56c47f
--- /dev/null
+++ b/doc/bugs/Huge_annex_out_of_memory_on_switch_to_indirect_mode_and_status/comment_1_94c678e1348280a96f11d7456c240d3a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmp1ThsNNAbSn46ju-gwFELfStlhl8usJo"
+ nickname="Marek"
+ subject="comment 1"
+ date="2013-05-03T21:12:39Z"
+ content="""
+I have not yet commited after git-annex add.
+"""]]
diff --git a/doc/bugs/Huge_annex_out_of_memory_on_switch_to_indirect_mode_and_status/comment_2_09450d58df2373174a1f0d90b08e9eb3._comment b/doc/bugs/Huge_annex_out_of_memory_on_switch_to_indirect_mode_and_status/comment_2_09450d58df2373174a1f0d90b08e9eb3._comment
new file mode 100644
index 000000000..b0e5bb5c2
--- /dev/null
+++ b/doc/bugs/Huge_annex_out_of_memory_on_switch_to_indirect_mode_and_status/comment_2_09450d58df2373174a1f0d90b08e9eb3._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-05-06T15:59:00Z"
+ content="""
+Looks like you have around 61396 files, which is not really very many. Is that guess accurate?
+
+I have repositories with that many files, that do not run out of memory, or even use much memory at all when running `git annex status`. Just tried and it needed 15 mb, not 900.
+
+Since you're using Ubuntu precise with a current version of git-annex, I'll bet you installed from fmarier's PPA. Is that right?
+
+In case this is a problem only with the build in the PPA, can you please download the [[/install/Linux_standalone]] tarball, and try the same command using the git-annex from there?
+"""]]
diff --git a/doc/bugs/Huge_annex_out_of_memory_on_switch_to_indirect_mode_and_status/comment_3_a07105226ef3488b97731db004651976._comment b/doc/bugs/Huge_annex_out_of_memory_on_switch_to_indirect_mode_and_status/comment_3_a07105226ef3488b97731db004651976._comment
new file mode 100644
index 000000000..e4795e5a8
--- /dev/null
+++ b/doc/bugs/Huge_annex_out_of_memory_on_switch_to_indirect_mode_and_status/comment_3_a07105226ef3488b97731db004651976._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.14.105"
+ subject="comment 3"
+ date="2013-09-19T18:59:42Z"
+ content="""
+It turns out that if you are using direct mode and you manually `git commit some-file` that is really big, that file is checked directly into git. Which is why direct mode's docs say not to do that.
+
+Once you've got an enormous file in git, either on purpose on by mistake, it turns out that git-annex tries to buffer the whole file content in some situations. I am in the process of fixing those memory leaks.
+"""]]
diff --git a/doc/bugs/Impossible_to_enable_an_existing_gcrypt_repo_in_the_webapp.mdwn b/doc/bugs/Impossible_to_enable_an_existing_gcrypt_repo_in_the_webapp.mdwn
new file mode 100644
index 000000000..4a8006f06
--- /dev/null
+++ b/doc/bugs/Impossible_to_enable_an_existing_gcrypt_repo_in_the_webapp.mdwn
@@ -0,0 +1,21 @@
+### Please describe the problem.
+As described earlier in [[tips/fully_encrypted_git_repositories_with_gcrypt]]
+
+### What steps will reproduce the problem?
+- A: use the webapp to create a new repository
+- A: add a remote server to the repository using the 'gcrypt' method
+- A: add a jabber account
+
+- B: use the webapp to create a new repository
+- B: add the jabber account
+- B: see the previously created 'cloud repository' with status 'not enabled'
+- B: click enable, see that the stored credentials are correct, and press "verify this server"
+- B: enter the ssh password twice
+- B: get redirected to a blank screen (on the url /config/repository/enable/gcrypt/UUID "x"?auth=y)
+
+The assistent logfiles show nothing after the "Your public key has been saved in", the server shows that no public key for B was added to the account.
+
+This is with git-annex installed on the remote server; without it the process gets stuck after clicking "encrypt repository" in step 2, it will just indefinitely keep prompting for the SSH password.
+
+### What version of git-annex are you using? On what operating system?
+Latest nightly build on ubuntu 13.10
diff --git a/doc/bugs/Impossible_to_enable_an_existing_gcrypt_repo_in_the_webapp/comment_1_17814787e333d15da3ab4e57c7d31d4b._comment b/doc/bugs/Impossible_to_enable_an_existing_gcrypt_repo_in_the_webapp/comment_1_17814787e333d15da3ab4e57c7d31d4b._comment
new file mode 100644
index 000000000..5bd45d686
--- /dev/null
+++ b/doc/bugs/Impossible_to_enable_an_existing_gcrypt_repo_in_the_webapp/comment_1_17814787e333d15da3ab4e57c7d31d4b._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.246"
+ subject="comment 1"
+ date="2013-11-13T16:51:40Z"
+ content="""
+I've tried to reproduce this, and cannot; it enabled the repository without trouble.
+
+Also, I have never seen the webapp fail with a blank screen, so that's strange.
+
+I think you need to show your `~/annex/.git/annex/daemon.log` from B.
+"""]]
diff --git a/doc/bugs/Incorrect_merge__44___direct_repos___40__2__41__.mdwn b/doc/bugs/Incorrect_merge__44___direct_repos___40__2__41__.mdwn
new file mode 100644
index 000000000..9b5d52220
--- /dev/null
+++ b/doc/bugs/Incorrect_merge__44___direct_repos___40__2__41__.mdwn
@@ -0,0 +1,44 @@
+### Please describe the problem.
+Incorrect merge of direct repos.
+
+### What steps will reproduce the problem?
+
+[[!format sh """
+# setting up stuff
+test/a$ git init
+test/a$ git annex init
+test/a$ git annex direct
+test/a$ touch firstfile
+test/a$ git annex add firstfile
+$ git clone test/a
+$ mv a test/b
+test/b$ git annex direct
+
+# actual scenario
+test/b$ echo bbbb > f
+test/b$ git annex add f
+test/b$ git annex sync
+test/a$ mkdir f
+test/a$ echo aaaa > f/f
+test/a$ git annex add f/f
+test/a$ git annex sync
+test/b$ git annex sync
+test/b$ rm f
+test/b$ git annex sync
+test/b$ ls
+test/b$ firstfile
+test/b$ f.variant-SHA256E-s5--4551db5fd4d56e27be71a8a943070cfaa4342b8e960a326e2d6427b3aa0a5a48.variant-43f5
+test/a$ git annex sync # A's f/f is no longer to be found
+"""]]
+
+### What version of git-annex are you using? On what operating system?
+[[!format sh """
+git-annex version: 4.20131031-g7d99d14
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP DNS Feeds Quvi TDFA CryptoHash
+key/value backends: SHA256E SHA1E SHA512E SHA224E SHA384E SKEIN256E SKEIN512E SHA256 SHA1 SHA512 SHA224 SHA384 SKEIN256 SKEIN512 WORM URL
+remote types: git gcrypt S3 bup directory rsync web webdav glacier hook
+
+Linux ceilingcat 3.11.6-1-ARCH #1 SMP PREEMPT Fri Oct 18 23:22:36 CEST 2013 x86_64 GNU/Linux
+"""]]
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/Incorrect_merge__44___direct_repos___40__2__41__/comment_1_15c354c4841d364e78882d2b46a0a764._comment b/doc/bugs/Incorrect_merge__44___direct_repos___40__2__41__/comment_1_15c354c4841d364e78882d2b46a0a764._comment
new file mode 100644
index 000000000..53c9f7915
--- /dev/null
+++ b/doc/bugs/Incorrect_merge__44___direct_repos___40__2__41__/comment_1_15c354c4841d364e78882d2b46a0a764._comment
@@ -0,0 +1,66 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.246"
+ subject="comment 1"
+ date="2013-11-14T17:06:50Z"
+ content="""
+I verify this bug. And it's specific to direct mode as you say. Here is a shell script which automates the proccess:
+
+[[!format sh \"\"\"
+#!/bin/sh
+set -e
+mkdir test
+cd test
+git init a
+
+cd a
+git annex init
+git annex direct
+touch firstfile
+git annex add firstfile
+git annex sync # think this was left out of recipe
+
+cd ..
+
+git clone a b
+cd b
+git annex direct
+echo bbbb > f
+git annex add f
+git annex sync || true
+cd ..
+cd a
+mkdir f
+echo aaaa > f/f
+git annex add f/f
+git annex sync || true
+cd ..
+cd b
+git annex sync
+echo \"after merge:\"
+ls
+\"\"\"]]
+
+At this point, b only has the file version of f; the directory form has been removed. (Syncing to a of course then does the same thing there.)
+
+And from the trascript, we can see what's going on:
+
+<pre>
+Adding f/f
+CONFLICT (directory/file): There is a directory with name f in HEAD. Adding f as f~refs_heads_synced_master
+Automatic merge failed; fix conflicts and then commit the result.
+(Recording state in git...)
+f: needs merge
+[master 0600854] git-annex automatic merge conflict fix
+
+ Merge conflict was automatically resolved; you may want to examine the result.
+</pre>
+
+The problem seems to be that direct mode merge does not find the `f~refs_heads_synced_master` created by the merge, so fails to copy it from the temp merge tree into the work tree.
+
+`Command.Sync.cleanConflictCruft` is relevant, but was only made to work in indirect mode, it seems.
+
+----
+
+Obviously, if someone runs into this bug and seems to lose data, they can get the data back by reverting the changes from the automatic merge. Direct mode does preserve file contents when removing them from the work tree in a merge.
+"""]]
diff --git a/doc/bugs/Incorrect_merge__44___direct_repos___40__2__41__/comment_2_8bc496226a977dbeeb1ce3f06122f1c2._comment b/doc/bugs/Incorrect_merge__44___direct_repos___40__2__41__/comment_2_8bc496226a977dbeeb1ce3f06122f1c2._comment
new file mode 100644
index 000000000..f9d3c7ffe
--- /dev/null
+++ b/doc/bugs/Incorrect_merge__44___direct_repos___40__2__41__/comment_2_8bc496226a977dbeeb1ce3f06122f1c2._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.246"
+ subject="comment 2"
+ date="2013-11-15T17:39:37Z"
+ content="""
+My initial guess was wrong.. This is not actually a bug in conflicted merge resolution at all.
+
+The bug is that in direct mode, it diffs the old and new tree when doing a normal merge, so see what files in the work tree need to be changed. This was written to go through the diff and replay the deletes and adds. In this case, since f/f and f are different items, they can appear in either order in the diff But the code only worked when f was first deleted, and f/f was then added. And it turns out that in this case, the diff had the two items the other way around.
+
+So, I think it needs to do 2 passes, first deleting and then adding.
+"""]]
diff --git a/doc/bugs/Incorrect_merge___40__a_special_case__41__.mdwn b/doc/bugs/Incorrect_merge___40__a_special_case__41__.mdwn
new file mode 100644
index 000000000..8e25ed6cb
--- /dev/null
+++ b/doc/bugs/Incorrect_merge___40__a_special_case__41__.mdwn
@@ -0,0 +1,48 @@
+### Please describe the problem.
+(Minor issue.)
+
+Incorrect merge of direct repos in the special case where at repo A a symlink to a file whose contents aren't yet available, are overwritten, while at repo B the file is deleted.
+
+Result: file is deleted on both side.
+
+Expected: B.f is gone, A.f is still present
+
+### What steps will reproduce the problem?
+
+[[!format sh """
+# setting up stuff
+test/a$ git init
+test/a$ git annex init
+test/a$ git annex direct
+test/a$ touch firstfile
+test/a$ git annex add firstfile
+$ git clone test/a
+$ mv a test/b
+test/b$ git annex direct
+
+# actual scenario
+test/b$ echo bbbb > f
+test/b$ git annex add f
+test/b$ git annex sync
+test/a$ git annex sync
+test/a$ echo aaaa > f
+test/a$ git annex add f
+test/a$ git annex sync
+test/b$ rm f
+test/b$ git annex sync
+test/a$ git annex sync
+# test/a/f is now gone, lost
+"""]]
+
+### What version of git-annex are you using? On what operating system?
+[[!format sh """
+git-annex version: 4.20131031-g7d99d14
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP DNS Feeds Quvi TDFA CryptoHash
+key/value backends: SHA256E SHA1E SHA512E SHA224E SHA384E SKEIN256E SKEIN512E SHA256 SHA1 SHA512 SHA224 SHA384 SKEIN256 SKEIN512 WORM URL
+remote types: git gcrypt S3 bup directory rsync web webdav glacier hook
+
+Linux ceilingcat 3.11.6-1-ARCH #1 SMP PREEMPT Fri Oct 18 23:22:36 CEST 2013 x86_64 GNU/Linux
+"""]]
+
+> [[fixed|done]]; direct mode now freezes the content directory as indirect
+> mode already did. fsck will fix up the permissions too. --[[Joey]]
diff --git a/doc/bugs/Incorrect_merge___40__a_special_case__41__/comment_1_c80418d76b501c688e3a9fb4831520fd._comment b/doc/bugs/Incorrect_merge___40__a_special_case__41__/comment_1_c80418d76b501c688e3a9fb4831520fd._comment
new file mode 100644
index 000000000..0594ddabe
--- /dev/null
+++ b/doc/bugs/Incorrect_merge___40__a_special_case__41__/comment_1_c80418d76b501c688e3a9fb4831520fd._comment
@@ -0,0 +1,41 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.246"
+ subject="comment 1"
+ date="2013-11-14T17:10:55Z"
+ content="""
+I suspect this might be the same underlying problem as [[bugs/Incorrect merge, direct repos (2)]]. However, I cannot reproduce it using the recipe given.. perhaps something was left out?
+
+I wrote this shell script to try to codify the recipe in a runnable form:
+
+[[!format sh \"\"\"
+#!/bin/sh
+set -e
+mkdir test
+cd test
+git init a
+
+cd a
+git annex init
+git annex direct
+touch firstfile
+git annex add firstfile
+git annex sync # think this was left out of recipe
+
+cd ..
+
+git clone a b
+cd b
+git annex direct
+echo bbbb > f
+git annex add f
+git annex sync || true
+cd ..
+cd a
+echo aaaa > f
+git annex add f
+git annex sync
+\"\"\"]]
+
+At this point, a has 2 variants of f, and no amount of syncing in either repo will cause either variant to go away.
+"""]]
diff --git a/doc/bugs/Incorrect_merge___40__a_special_case__41__/comment_2_8b2a188696f46819f6e3f0e9660362d2._comment b/doc/bugs/Incorrect_merge___40__a_special_case__41__/comment_2_8b2a188696f46819f6e3f0e9660362d2._comment
new file mode 100644
index 000000000..39bb90877
--- /dev/null
+++ b/doc/bugs/Incorrect_merge___40__a_special_case__41__/comment_2_8b2a188696f46819f6e3f0e9660362d2._comment
@@ -0,0 +1,45 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlWskoNgUB7r70OXglR-4iKI4bOuPJb-xg"
+ nickname="Tim"
+ subject="comment 2"
+ date="2013-11-14T18:06:55Z"
+ content="""
+You were missing a: test/a$ git annex sync
+
+This did the trick on my system
+[[!format sh \"\"\"
+#!/bin/sh
+set -e
+mkdir test
+cd test
+git init a
+
+cd a
+git annex init
+git annex direct
+touch firstfile
+git annex add firstfile
+git annex sync # think this was left out of recipe # indeed it was
+
+cd ..
+
+git clone a b
+cd b
+git annex direct
+echo bbbb > f
+git annex add f
+git annex sync || true # why add a || true?
+cd ../a
+git annex sync
+echo aaaa > f
+git annex add f
+git annex sync
+cd ../b
+rm f
+git annex sync
+ls
+cd ../a
+git annex sync
+ls
+\"\"\"]]
+"""]]
diff --git a/doc/bugs/Incorrect_merge___40__a_special_case__41__/comment_3_8cdbb1fda506b9e53a0e9ab88b2569c1._comment b/doc/bugs/Incorrect_merge___40__a_special_case__41__/comment_3_8cdbb1fda506b9e53a0e9ab88b2569c1._comment
new file mode 100644
index 000000000..ce5c144e1
--- /dev/null
+++ b/doc/bugs/Incorrect_merge___40__a_special_case__41__/comment_3_8cdbb1fda506b9e53a0e9ab88b2569c1._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.246"
+ subject="comment 3"
+ date="2013-11-15T17:48:42Z"
+ content="""
+Hmm. In your script, when you run `git annex sync` in a and then `echo aaaa > f`, f already exists at that point as a symlink. This actually ends up following the link and writing to .git/annex/objects. (fsck will detect that junk has been written there)
+
+That's a bug on its own; seems like direct mode is neglecting to lock down the .git/annex/objects directories to prevent writing to them like this.
+
+----
+
+However, this means that your script does not demonstrate the bug you originally reported.
+You remove b/f and sync, and since a/f has not been changed, the deleting is correctly synced to a, removing a/f.
+"""]]
diff --git a/doc/bugs/Incorrect_merge___40__a_special_case__41__/comment_4_9d74e2854a5d77f0f793f56fa0cff9e2._comment b/doc/bugs/Incorrect_merge___40__a_special_case__41__/comment_4_9d74e2854a5d77f0f793f56fa0cff9e2._comment
new file mode 100644
index 000000000..c7bb02765
--- /dev/null
+++ b/doc/bugs/Incorrect_merge___40__a_special_case__41__/comment_4_9d74e2854a5d77f0f793f56fa0cff9e2._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.246"
+ subject="comment 4"
+ date="2013-11-15T17:52:38Z"
+ content="""
+Looking back at the original bug description:
+
+\"repo A a symlink to a file whose contents aren't yet available, are overwritten, while at repo B the file is deleted.\"
+
+I think the \"overwritten\" is key. I suspect you were always doing echo > f where f was a symlink, and this does not actually overwrite the symlink, it just puts data (that fsck will reject) into the annex.
+
+So, proceeding as if the real bug here is the ability to write through symlink in direct mode, unless told otherwise..
+"""]]
diff --git a/doc/bugs/Incorrect_version_of_Git_Annex___40__1.0.52__41___as_seen_by_Android.mdwn b/doc/bugs/Incorrect_version_of_Git_Annex___40__1.0.52__41___as_seen_by_Android.mdwn
new file mode 100644
index 000000000..95db65e25
--- /dev/null
+++ b/doc/bugs/Incorrect_version_of_Git_Annex___40__1.0.52__41___as_seen_by_Android.mdwn
@@ -0,0 +1,24 @@
+### Please describe the problem.
+
+Git Annex is listed as of version 1.0.52 if you check out its entry in the list of applications in the Android configuration. I guess that one is of the terminal app which kickstarts the annex.
+
+### What steps will reproduce the problem?
+
+install apk
+
+### What version of git-annex are you using? On what operating system?
+
+android
+5.2013whatever
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/Incorrect_version_on_64_Standalone_Build.mdwn b/doc/bugs/Incorrect_version_on_64_Standalone_Build.mdwn
new file mode 100644
index 000000000..d0f43f5b2
--- /dev/null
+++ b/doc/bugs/Incorrect_version_on_64_Standalone_Build.mdwn
@@ -0,0 +1,11 @@
+ $ wget https://downloads.kitenet.net/git-annex/linux/current/git-annex-standalone-amd64.tar.gz
+ $ tar xvzf git-annex-standalone-amd64.tar.gz
+ $ cd git-annex.linux
+ $ ./git-annex version
+ git-annex version: 4.20130324
+
+Shouldn't that be `4.20130405`?
+
+The md5sum of the build I downloaded is `aabbb3aa2397be206cae86f33db9eef4`.
+
+> [[done]]; new version will look like eg `4.20130410-gc149c67` --[[Joey]]
diff --git a/doc/bugs/Incorrect_version_on_64_Standalone_Build/comment_1_1964e4cad33a9f98b2eedbf095e899ff._comment b/doc/bugs/Incorrect_version_on_64_Standalone_Build/comment_1_1964e4cad33a9f98b2eedbf095e899ff._comment
new file mode 100644
index 000000000..03a39b928
--- /dev/null
+++ b/doc/bugs/Incorrect_version_on_64_Standalone_Build/comment_1_1964e4cad33a9f98b2eedbf095e899ff._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-04-10T20:38:28Z"
+ content="""
+Hmm, I think this is an artifact of my release process. I copy the nightly autobuild to there, and typically do this in the morning, so there are some commits from changes to this wiki. Until I commit a new version to `debian/changelog`, `git annex version` can report wrong information. In particular, in commit c709623ff8e56490bb5802cb53880ae237f9f1d9 I changed the version number from a placeholder 4.20130324 to 4.20130405.
+
+There's a tradeoff between waiting for the next autobuild (only run once a day because the server has other users), taking the time to manually run a build, and getting the new release out to users quickly when I announce it.
+
+I think the thing to do is make it use the date of the *last* commit as the version number for autobuilds, and include the git rev in there too. Then users will know exactly what they've gotten.
+"""]]
diff --git a/doc/bugs/Install_of_git-annex-3.20121112_fails.mdwn b/doc/bugs/Install_of_git-annex-3.20121112_fails.mdwn
new file mode 100644
index 000000000..f4f1c6c7d
--- /dev/null
+++ b/doc/bugs/Install_of_git-annex-3.20121112_fails.mdwn
@@ -0,0 +1,20 @@
+What steps will reproduce the problem?
+
+- rm -rf ~/.ghc/ && cabal update && cabal install git-annex --bindir=$HOME/bin
+
+What is the expected output? What do you see instead?
+
+- I would like to have the latest release installed
+
+What version of git-annex are you using? On what operating system?
+
+- git-annex-3.20121112
+- Ubuntu 12.04 LTS
+- The Glorious Glasgow Haskell Compilation System, version 7.4.1
+
+Please provide any additional information below.
+
+I use it heavily on 4 machines since a month and I really like it.
+
+> closing since this is a cabal library problem, and not something that
+> can be fixed by any change to git-annex. [[done]] --[[Joey]]
diff --git a/doc/bugs/Install_of_git-annex-3.20121112_fails/comment_1_80fc80151d4390bd8a4332f30723962e._comment b/doc/bugs/Install_of_git-annex-3.20121112_fails/comment_1_80fc80151d4390bd8a4332f30723962e._comment
new file mode 100644
index 000000000..b3889eca6
--- /dev/null
+++ b/doc/bugs/Install_of_git-annex-3.20121112_fails/comment_1_80fc80151d4390bd8a4332f30723962e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.252.11.120"
+ subject="comment 1"
+ date="2012-11-13T17:08:14Z"
+ content="""
+You forgot to say how it fails.
+"""]]
diff --git a/doc/bugs/Install_of_git-annex-3.20121112_fails/comment_2_2613320a41a74dc757a3277c8c328bd0._comment b/doc/bugs/Install_of_git-annex-3.20121112_fails/comment_2_2613320a41a74dc757a3277c8c328bd0._comment
new file mode 100644
index 000000000..fa2b326e9
--- /dev/null
+++ b/doc/bugs/Install_of_git-annex-3.20121112_fails/comment_2_2613320a41a74dc757a3277c8c328bd0._comment
@@ -0,0 +1,62 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnldTTAP8PAifJUmqhRar6RAWNWlRcencw"
+ nickname="Marco"
+ subject="The failure"
+ date="2012-11-13T17:24:40Z"
+ content="""
+Configuring certificate-1.2.2...
+Building certificate-1.2.2...
+Preprocessing library certificate-1.2.2...
+[1 of 9] Compiling Data.Certificate.KeyRSA ( Data/Certificate/KeyRSA.hs, dist/build/Data/Certificate/KeyRSA.o )
+
+Data/Certificate/KeyRSA.hs:29:27:
+ Constructor `RSA.PrivateKey' does not have field `RSA.private_size'
+ In the expression:
+ RSA.PrivateKey
+ {RSA.private_size = calculate_modulus p_modulus 1,
+ RSA.private_n = p_modulus, RSA.private_d = priv_exp,
+ RSA.private_p = p_p1, RSA.private_q = p_p2,
+ RSA.private_dP = p_exp1, RSA.private_dQ = p_exp2,
+ RSA.private_qinv = p_coef}
+ In an equation for `privkey':
+ privkey
+ = RSA.PrivateKey
+ {RSA.private_size = calculate_modulus p_modulus 1,
+ RSA.private_n = p_modulus, RSA.private_d = priv_exp,
+ RSA.private_p = p_p1, RSA.private_q = p_p2,
+ RSA.private_dP = p_exp1, RSA.private_dQ = p_exp2,
+ RSA.private_qinv = p_coef}
+ In an equation for `parsePrivate':
+ parsePrivate
+ [Start Sequence,
+ IntVal 0,
+ IntVal p_modulus,
+ IntVal pub_exp,
+ IntVal priv_exp,
+ IntVal p_p1,
+ IntVal p_p2,
+ IntVal p_exp1,
+ IntVal p_exp2,
+ IntVal p_coef,
+ End Sequence]
+ = Right (pubkey, privkey)
+ where
+ privkey
+ = RSA.PrivateKey
+ {RSA.private_size = calculate_modulus p_modulus 1,
+ RSA.private_n = p_modulus, RSA.private_d = priv_exp,
+ RSA.private_p = p_p1, RSA.private_q = p_p2,
+ RSA.private_dP = p_exp1, RSA.private_dQ = p_exp2,
+ RSA.private_qinv = p_coef}
+ pubkey
+ = RSA.PublicKey
+ {RSA.public_size = calculate_modulus p_modulus 1,
+ RSA.public_n = p_modulus, RSA.public_e = pub_exp}
+ calculate_modulus n i
+ = if (2 ^ (i * 8)) > n then i else calculate_modulus n (i + 1)
+cabal: Error: some packages failed to install:
+authenticate-1.3.2 depends on certificate-1.2.2 which failed to install.
+certificate-1.2.2 failed during the building phase. The exception was:
+ExitFailure 1
+git-annex-3.20121112 depends on certificate-1.2.2 which failed to install.
+"""]]
diff --git a/doc/bugs/Install_of_git-annex-3.20121112_fails/comment_3_c364764d0c56e8dc3cac276905d99841._comment b/doc/bugs/Install_of_git-annex-3.20121112_fails/comment_3_c364764d0c56e8dc3cac276905d99841._comment
new file mode 100644
index 000000000..e3478d03d
--- /dev/null
+++ b/doc/bugs/Install_of_git-annex-3.20121112_fails/comment_3_c364764d0c56e8dc3cac276905d99841._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.252.11.120"
+ subject="comment 3"
+ date="2012-11-13T17:54:30Z"
+ content="""
+Hmm, the current version of certificate is 1.3.1, and I installed it without trouble just now. I don't know why cabal is installing a much older version there.
+
+In any case, this is not a bug in git annex, but some problem with the library that a library it uses depends on. You can use the pre-built standalone binary until cabal sorts itself out, I suppose.
+"""]]
diff --git a/doc/bugs/Install_of_git-annex-3.20121112_fails/comment_4_f1057340dfa978071d3bbc9e2af1e612._comment b/doc/bugs/Install_of_git-annex-3.20121112_fails/comment_4_f1057340dfa978071d3bbc9e2af1e612._comment
new file mode 100644
index 000000000..2741daacf
--- /dev/null
+++ b/doc/bugs/Install_of_git-annex-3.20121112_fails/comment_4_f1057340dfa978071d3bbc9e2af1e612._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnldTTAP8PAifJUmqhRar6RAWNWlRcencw"
+ nickname="Marco"
+ subject="Assistant depends on Yesod"
+ date="2012-11-13T18:34:19Z"
+ content="""
+Thank you Joey. Than I tried a workaround. On one machine I don't need the Webapp.
+
+I was using
+
+cabal install --only-dependencies -f-Webapp
+cabal configure -f-Webapp
+
+mp/Utility/libdiskfree.o dist/build/git-annex/git-annex-tmp/Utility/libmounts.o ./git-annex.hs
+
+Assistant/Alert.hs:21:8:
+ Could not find module `Yesod'
+ Use -v to see a list of the files searched for.
+"""]]
diff --git a/doc/bugs/Install_of_git-annex-3.20121112_fails/comment_5_9007b1a3abd647945604968db19cb841._comment b/doc/bugs/Install_of_git-annex-3.20121112_fails/comment_5_9007b1a3abd647945604968db19cb841._comment
new file mode 100644
index 000000000..666eef28b
--- /dev/null
+++ b/doc/bugs/Install_of_git-annex-3.20121112_fails/comment_5_9007b1a3abd647945604968db19cb841._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.252.11.120"
+ subject="youch!"
+ date="2012-11-13T19:37:23Z"
+ content="""
+The assistant is indeed supposed to build w/o Yesod. I've fixed that in git!
+"""]]
diff --git a/doc/bugs/Install_of_git-annex-3.20121112_fails/comment_6_0bb3ac5375f29ce9d3d0be93879267e3._comment b/doc/bugs/Install_of_git-annex-3.20121112_fails/comment_6_0bb3ac5375f29ce9d3d0be93879267e3._comment
new file mode 100644
index 000000000..2aaf9cf43
--- /dev/null
+++ b/doc/bugs/Install_of_git-annex-3.20121112_fails/comment_6_0bb3ac5375f29ce9d3d0be93879267e3._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmLB39PC89rfGaA8SwrsnB6tbumezj-aC0"
+ nickname="Tobias"
+ subject="Bah, i missed this before making my own bug report"
+ date="2012-11-13T20:56:50Z"
+ content="""
+This line worked for me on ubuntu 12.10:
+
+cabal install --only-dependencies ./ --constraint=certificate==1.2.2 --constraint=crypto-pubkey-types==0.1.1
+
+"""]]
diff --git a/doc/bugs/Install_of_git-annex-3.20121112_fails/comment_7_ae4443b8cd069080d1f77fca16aa8b04._comment b/doc/bugs/Install_of_git-annex-3.20121112_fails/comment_7_ae4443b8cd069080d1f77fca16aa8b04._comment
new file mode 100644
index 000000000..99124ebe5
--- /dev/null
+++ b/doc/bugs/Install_of_git-annex-3.20121112_fails/comment_7_ae4443b8cd069080d1f77fca16aa8b04._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnldTTAP8PAifJUmqhRar6RAWNWlRcencw"
+ nickname="Marco"
+ subject="Works"
+ date="2012-11-14T07:01:34Z"
+ content="""
+Thanks Joey for fixing this. Now I got a working version.
+
+Btw would it make sense to reference a stable Yesod version in the cabal file? I'm new to the haskell universe so I don't know what problems would come up with it.
+"""]]
diff --git a/doc/bugs/Internal_Server_Error:_Unknown_UUID.mdwn b/doc/bugs/Internal_Server_Error:_Unknown_UUID.mdwn
new file mode 100644
index 000000000..e8e802455
--- /dev/null
+++ b/doc/bugs/Internal_Server_Error:_Unknown_UUID.mdwn
@@ -0,0 +1,37 @@
+### Please describe the problem.
+
+One of my repositories has no name:
+http://screencast.com/t/3OjxFzpz
+
+And when I try to disable it I get this error:
+
+ Internal Server Error
+ Unknown UUID
+
+When I try to delete it I get this error:
+
+ Internal Server Error
+ unknown UUID; cannot modify
+
+I think this was the result of adding a Local Computer Repo, and then that computer signed off. Maybe.
+
+### What version of git-annex are you using? On what operating system?
+
+git-annex version 4.20130601-g2b6c3f2
+Mac OS 10.7.5
+
+### Please provide any additional information below.
+
+Maybe it's a glitch that only will happen this once, the problem is I can't get rid of it! Are there anyways of manually getting rid of a repo with uid?
+
+> Also reported here:
+> [[Missing_repo_uuid_after_local_pairing_with_older_annex]] and
+> [[Internal_Server_Error_unknown_UUID;_cannot_modify]]
+> and [[Local_network___40__ssh__41___fails_to_pair__47__sync]]
+> and [[Internal_Server_Error:_Unknown_UUID]]
+> --[[Joey]]
+
+[[!meta title="local pairing leads to unknown UUID"]]
+
+> This bug is [[fixed|done]]. The webapp will detect the problem and
+> provides an interface to correct it. --[[Joey]]
diff --git a/doc/bugs/Internal_Server_Error:_Unknown_UUID/comment_1_f42f703a5d267557abf5e932f0890d4a._comment b/doc/bugs/Internal_Server_Error:_Unknown_UUID/comment_1_f42f703a5d267557abf5e932f0890d4a._comment
new file mode 100644
index 000000000..e8494ab17
--- /dev/null
+++ b/doc/bugs/Internal_Server_Error:_Unknown_UUID/comment_1_f42f703a5d267557abf5e932f0890d4a._comment
@@ -0,0 +1,37 @@
+[[!comment format=mdwn
+ username="carlo"
+ ip="118.208.1.126"
+ subject="comment 1"
+ date="2013-07-06T22:52:18Z"
+ content="""
+I got the same error. Local repo has no name but in the logs I can see that it's trying to make a local connection:
+
+ [2013-07-07 08:29:51 EST] main: starting assistant version 4.20130627
+ [2013-07-07 08:29:51 EST] TransferScanner: Syncing with arkham.local_annex
+
+(snip)
+
+ 07/Jul/2013:08:41:56 +1000 [Error#yesod-core] Unknown UUID @(yesod-core-1.2.3:Yesod.Core.Class.Yesod ./Yesod/Core/Class/Yesod.hs:471:5)
+ ssh: Could not resolve hostname arkham.local: Name or service not known
+ ssh: Could not resolve hostname arkham.local: Name or service not known
+ fatal: The remote end hung up unexpectedly
+ git-annex: Unknown UUID
+ ssh: Could not resolve hostname arkham.local: Name or service not known
+ ssh: Could not resolve hostname arkham.local: Name or service not known
+ fatal: The remote end hung up unexpectedly
+ git-annex: Unknown UUID
+ ssh: Could not resolve hostname arkham.local: Name or service not known
+ ssh: Could not resolve hostname arkham.local: Name or service not known
+ fatal: The remote end hung up unexpectedly
+ git-annex: Unknown UUID
+ ssh: Could not resolve hostname arkham.local: Name or service not known
+ 07/Jul/2013:08:42:32 +1000 [Error#yesod-core] Unknown UUID @(yesod-core-1.2.3:Yesod.Core.Class.Yesod ./Yesod/Core/Class/Yesod.hs:471:5)
+ ssh: Could not resolve hostname arkham.local: Name or service not known
+ fatal: The remote end hung up unexpectedly
+ git-annex: Unknown UUID
+ ssh: Could not resolve hostname arkham.local: Name or service not known
+
+When I turn on arkham (the other laptop) I see transfers start up:
+
+
+"""]]
diff --git a/doc/bugs/Internal_Server_Error:_Unknown_UUID/comment_2_eb1999f99c5babf3fcb1ff5d72ea6db6._comment b/doc/bugs/Internal_Server_Error:_Unknown_UUID/comment_2_eb1999f99c5babf3fcb1ff5d72ea6db6._comment
new file mode 100644
index 000000000..46fcc0898
--- /dev/null
+++ b/doc/bugs/Internal_Server_Error:_Unknown_UUID/comment_2_eb1999f99c5babf3fcb1ff5d72ea6db6._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkeyfC88gIU4fsEqqkvhzVlSKDUxbtZaTE"
+ nickname="Selem"
+ subject="comment 2"
+ date="2013-07-10T01:41:24Z"
+ content="""
+I got the same problem (Mac OS X 10.8.4, whatever the latest download package, local computers same network repos)
+
+To get rid of the noname repo, I just removed git remote in the annex dir.
+
+ # List remote
+ $ git remote -v
+ # Remove remote grabbed from running the previous command
+ $ git remote rm your_remote
+
+After that, I added the second computer repo successfully.
+
+"""]]
diff --git a/doc/bugs/Internal_Server_Error:_Unknown_UUID/comment_3_bda72b0d615843d18d6ef21f833432a8._comment b/doc/bugs/Internal_Server_Error:_Unknown_UUID/comment_3_bda72b0d615843d18d6ef21f833432a8._comment
new file mode 100644
index 000000000..3bdba306d
--- /dev/null
+++ b/doc/bugs/Internal_Server_Error:_Unknown_UUID/comment_3_bda72b0d615843d18d6ef21f833432a8._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.110"
+ subject="I can't reproduce this problem, but I see several people have reported it."
+ date="2013-07-27T22:11:15Z"
+ content="""
+It would be helpful for anyone who can reproduce this problem to do so with debugging enabled on both sides
+ (run with --debug or turn it on in the Configuration page in webapp), and then send the `.git/annex/daemon.log`
+"""]]
diff --git a/doc/bugs/Internal_Server_Error:_Unknown_UUID/comment_4_651440cda405ad40a04479f5d87d581e._comment b/doc/bugs/Internal_Server_Error:_Unknown_UUID/comment_4_651440cda405ad40a04479f5d87d581e._comment
new file mode 100644
index 000000000..87da8dc31
--- /dev/null
+++ b/doc/bugs/Internal_Server_Error:_Unknown_UUID/comment_4_651440cda405ad40a04479f5d87d581e._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://launchpad.net/~subito"
+ nickname="subito"
+ subject="Same here for SSH remotes"
+ date="2013-07-29T19:05:55Z"
+ content="""
+I get the problem while only adding an SSH remote. After deciding I want a git-repo on my server, it says \"Unknown UUID\" and created a remote with no name. I was unable to add any SSH remote (tried with two different servers and a couple different dirs - some completly unknown to my annex)
+
+I used the Android webapp btw - latest Version. The same version works fine on my Debian maschines.
+"""]]
diff --git a/doc/bugs/Internal_Server_Error:_Unknown_UUID/comment_5_21fa189b631c246ac5df16a49c3c0178._comment b/doc/bugs/Internal_Server_Error:_Unknown_UUID/comment_5_21fa189b631c246ac5df16a49c3c0178._comment
new file mode 100644
index 000000000..1f42daf5f
--- /dev/null
+++ b/doc/bugs/Internal_Server_Error:_Unknown_UUID/comment_5_21fa189b631c246ac5df16a49c3c0178._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.21"
+ subject="comment 5"
+ date="2013-07-30T16:59:50Z"
+ content="""
+@subito I have tried as hard as I can to reproduce this problem, and cannot. I need the debug information I asked for in my other comment to get any further on this bug report.
+"""]]
diff --git a/doc/bugs/Internal_Server_Error:_Unknown_UUID/comment_6_1f712693d2ded5abceb869fdb7f47ef3._comment b/doc/bugs/Internal_Server_Error:_Unknown_UUID/comment_6_1f712693d2ded5abceb869fdb7f47ef3._comment
new file mode 100644
index 000000000..9e28682b4
--- /dev/null
+++ b/doc/bugs/Internal_Server_Error:_Unknown_UUID/comment_6_1f712693d2ded5abceb869fdb7f47ef3._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.21"
+ subject="finally!"
+ date="2013-07-31T16:47:39Z"
+ content="""
+I've finally been clued in to the cause of this. If a ssh-agent is running, and has been configured to use a ssh key (by running `ssh-add`), this apparently prevents git-annex from using the key it sets up during local pairing. I have reproduced the described bug by this method.
+
+Something similar might also affect adding a remote ssh server, I'm not sure about that yet.
+
+
+"""]]
diff --git a/doc/bugs/Internal_Server_Error:_Unknown_UUID/comment_7_7a5ead0ce5c9429d4723ccce4f6a6d6c._comment b/doc/bugs/Internal_Server_Error:_Unknown_UUID/comment_7_7a5ead0ce5c9429d4723ccce4f6a6d6c._comment
new file mode 100644
index 000000000..136bca8f4
--- /dev/null
+++ b/doc/bugs/Internal_Server_Error:_Unknown_UUID/comment_7_7a5ead0ce5c9429d4723ccce4f6a6d6c._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.21"
+ subject="workaround"
+ date="2013-07-31T17:19:01Z"
+ content="""
+Looks like the fix is to edit ~/.ssh/config and in each stanza added by git-annex, add this line:
+
+ IdentitiesOnly yes
+
+This prevents the ssh-agent from using the normal key, and allows the git-annex key to be used instead.
+
+People experiencing this bug can manually make that change. Then if you edit your git-annex repository's `.git/config` and delete the `annex-ignore` line, the assistant should finally learn the UUID and start syncing.
+"""]]
diff --git a/doc/bugs/Internal_Server_Error:_Unknown_UUID/comment_8_a4683fd73ae452a9cd7f61d9930f6266._comment b/doc/bugs/Internal_Server_Error:_Unknown_UUID/comment_8_a4683fd73ae452a9cd7f61d9930f6266._comment
new file mode 100644
index 000000000..54bd855cf
--- /dev/null
+++ b/doc/bugs/Internal_Server_Error:_Unknown_UUID/comment_8_a4683fd73ae452a9cd7f61d9930f6266._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.21"
+ subject="comment 8"
+ date="2013-07-31T20:42:10Z"
+ content="""
+I've updated the webapp to display nicely when a repository has stalled being set up, rather than crashing.
+
+There's now an interface to check the status of such a stalled repository, and it will try to clean up after this bug too.
+"""]]
diff --git a/doc/bugs/Internal_Server_Error:_Unknown_UUID/comment_9_ced3516c3e7161e4d7e599232f62a511._comment b/doc/bugs/Internal_Server_Error:_Unknown_UUID/comment_9_ced3516c3e7161e4d7e599232f62a511._comment
new file mode 100644
index 000000000..4a99ee3ad
--- /dev/null
+++ b/doc/bugs/Internal_Server_Error:_Unknown_UUID/comment_9_ced3516c3e7161e4d7e599232f62a511._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnZEanlyzay_QlEAL0CWpyZcRTyN7vay8U"
+ nickname="Carlo"
+ subject="Tilde did it for me"
+ date="2013-10-06T21:59:43Z"
+ content="""
+I had exactly the same error message, \"Internal Server Error: Unknown UUID\", when I used a path starting with a tilde. Absolute path for home directory worked.
+"""]]
diff --git a/doc/bugs/Internal_Server_Error_unknown_UUID__59___cannot_modify.mdwn b/doc/bugs/Internal_Server_Error_unknown_UUID__59___cannot_modify.mdwn
new file mode 100644
index 000000000..7767b83e2
--- /dev/null
+++ b/doc/bugs/Internal_Server_Error_unknown_UUID__59___cannot_modify.mdwn
@@ -0,0 +1,26 @@
+### Please describe the problem.
+I was trying to use "Local Computer" option to sync up two machines on my local network. I was having some firewall issues and it failed on one machine.
+It still created a repository without a name in the web ui and i get that Error unknown UUID when trying to edit or delete it.
+
+### What steps will reproduce the problem?
+Machine A initiates pairing. Machine B accepts pairing. Machine A has a firewall blocking outgoing connections.
+Machine B times out. Machine A accepts outgoing connections for vnetd. Machine A starts syncing with Machine B.
+Machine B gets files but have a broken web ui.
+
+
+### What version of git-annex are you using? On what operating system?
+
+4.20130601-g2b6c3f2
+OSX 10.7.5 on both Machine A and B
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
+
+> [[dup|done]] of [[Internal_Server_Error:_Unknown_UUID]] --[[Joey]]
diff --git a/doc/bugs/Internal_Server_Error_when_adding_an_uncrypted_box.com_repo_after_deleted_an_encrypted_one..mdwn b/doc/bugs/Internal_Server_Error_when_adding_an_uncrypted_box.com_repo_after_deleted_an_encrypted_one..mdwn
new file mode 100644
index 000000000..9a838b58f
--- /dev/null
+++ b/doc/bugs/Internal_Server_Error_when_adding_an_uncrypted_box.com_repo_after_deleted_an_encrypted_one..mdwn
@@ -0,0 +1,28 @@
+### Please describe the problem.
+I got the following error message
+
+ Internal Server Error
+ Cannot change encryption type of existing remote.
+
+after deleted my encrypted box.com remote and tried to add the same box.com account as an uncrypted remote.
+
+### What steps will reproduce the problem?
+* Add a box.com remote with encryption.
+* Delete the remote.
+* Add with the same box.com account a remote without encryption.
+
+### What version of git-annex are you using? On what operating system?
+* 2013.07.09 release
+* Linux 3.9.9-1-ARCH x86_64
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
+
+> fixed this [[done]] --[[Joey]]
diff --git a/doc/bugs/Internal_server_error_adding_USB_drive_on_OS_X.mdwn b/doc/bugs/Internal_server_error_adding_USB_drive_on_OS_X.mdwn
new file mode 100644
index 000000000..575a63684
--- /dev/null
+++ b/doc/bugs/Internal_server_error_adding_USB_drive_on_OS_X.mdwn
@@ -0,0 +1,25 @@
+What steps will reproduce the problem?
+
+* Start with a clean setup.
+* Allow webapp to start; use it to create annex in ~/Documents/annex That works.
+* Go to add remote repo. Removable drive.
+* Select "/Volumes/G-DRIVE slim". Click next.
+
+What is the expected output? What do you see instead?
+Expected is something like "done". What I see is
+
+Internal Server Error
+
+git config [Param "annex.uuid",Param "6898F314-7817-4CD5-B1C3-588C55522A3B"] failed
+
+What version of git-annex are you using? On what operating system?
+
+git-annex version 3.20130107, OS X Mountain Lion. No MacPorts/homebrew/fink installed. gcc / git are installed.
+
+Please provide any additional information below.
+
+Maybe something to do with the drive name having spaces? "/Volumes/git-annex" worked fine.
+
+> Good thought in the comment. I was able to reproduce the failure
+> if the removable drive already had an "annex" directory that was not
+> a git repo. I've made it handle this case. [[done]] --[[Joey]]
diff --git a/doc/bugs/Internal_server_error_adding_USB_drive_on_OS_X/comment_1_b2ef077d87a9da624f20649c21401b5b._comment b/doc/bugs/Internal_server_error_adding_USB_drive_on_OS_X/comment_1_b2ef077d87a9da624f20649c21401b5b._comment
new file mode 100644
index 000000000..f46292c19
--- /dev/null
+++ b/doc/bugs/Internal_server_error_adding_USB_drive_on_OS_X/comment_1_b2ef077d87a9da624f20649c21401b5b._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.238"
+ subject="comment 1"
+ date="2013-01-14T16:07:18Z"
+ content="""
+Spaces in the name is a good guess, but does not seem to cause the problem. I just successfully set up a USB drive that has spaces in the name. (Also, git-annex is carefully coded to avoid such problems..)
+
+It seems that the repository is created, but then running `git config` in it fails for some reason. One thing you could do is look at `~/Documents/annex/.git/annex/daemon.log`. It should have any error message output by the command.
+
+Or, you could try, in a shell:
+
+cd \"/Volumes/G-DRIVE slim/annex\"
+git config annex.uuid 6898F314-7817-4CD5-B1C3-588C55522A3B
+
+And see how that is failing.
+"""]]
diff --git a/doc/bugs/Internal_server_error_adding_USB_drive_on_OS_X/comment_2_ef849e25b0264808bff800d9d3836119._comment b/doc/bugs/Internal_server_error_adding_USB_drive_on_OS_X/comment_2_ef849e25b0264808bff800d9d3836119._comment
new file mode 100644
index 000000000..ec7867653
--- /dev/null
+++ b/doc/bugs/Internal_server_error_adding_USB_drive_on_OS_X/comment_2_ef849e25b0264808bff800d9d3836119._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="arafel"
+ ip="94.174.218.177"
+ subject="comment 2"
+ date="2013-01-14T20:50:50Z"
+ content="""
+It did seem unlikely that you hadn't tested that. :-)
+
+Oddly, there doesn't seem to be a daemon.log file in that directory. I don't have the drive handy to test at the moment - when I do I'll try the commands you suggest and see what the output is.
+"""]]
diff --git a/doc/bugs/Internal_server_error_adding_USB_drive_on_OS_X/comment_3_ae3cbd0eb69cbeb9b349e0060d056d43._comment b/doc/bugs/Internal_server_error_adding_USB_drive_on_OS_X/comment_3_ae3cbd0eb69cbeb9b349e0060d056d43._comment
new file mode 100644
index 000000000..f2e5394ce
--- /dev/null
+++ b/doc/bugs/Internal_server_error_adding_USB_drive_on_OS_X/comment_3_ae3cbd0eb69cbeb9b349e0060d056d43._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="arafel"
+ ip="94.174.218.177"
+ subject="comment 3"
+ date="2013-01-14T21:19:12Z"
+ content="""
+Pauls-MacBook-Pro:annex Paul$ cd /Volumes/G-DRIVE\ slim/annex/
+
+Pauls-MacBook-Pro:annex Paul$ git config annex.uuid 6898F314-7817-4CD5-B1C3-588C55522A3B
+
+error: could not lock config file .git/config: No such file or directory
+
+Pauls-MacBook-Pro:annex Paul$ ls -a
+
+. ..
+
+Looks like it created the directory but never got as far as 'git init'. Is it safe to just run that command, and will that (followed by the config) be enough? Or is there more to it than that? e.g. creating the remotes
+"""]]
diff --git a/doc/bugs/Internal_server_error_adding_USB_drive_on_OS_X/comment_4_0ff2897805928b14829b7b369a3aed91._comment b/doc/bugs/Internal_server_error_adding_USB_drive_on_OS_X/comment_4_0ff2897805928b14829b7b369a3aed91._comment
new file mode 100644
index 000000000..7e6b621c8
--- /dev/null
+++ b/doc/bugs/Internal_server_error_adding_USB_drive_on_OS_X/comment_4_0ff2897805928b14829b7b369a3aed91._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.238"
+ subject="comment 4"
+ date="2013-01-14T22:54:30Z"
+ content="""
+Can you do this:
+
+* `rmdir /Volumes/G-DRIVE\ slim/annex/`
+
+* Stop any git-annex assistant you have running.
+
+* At the console, run \"git annex webapp\", and reproduce the bug again. When it fails you should see some error message at the console where you started it.
+
+(If you're using the git-annex.app built for OSX, you should instead run the `git-annex-webapp` script included in the app.)
+"""]]
diff --git a/doc/bugs/Internal_server_error_adding_USB_drive_on_OS_X/comment_5_414a45573aeb5201f4d80433955669d5._comment b/doc/bugs/Internal_server_error_adding_USB_drive_on_OS_X/comment_5_414a45573aeb5201f4d80433955669d5._comment
new file mode 100644
index 000000000..f5423f04f
--- /dev/null
+++ b/doc/bugs/Internal_server_error_adding_USB_drive_on_OS_X/comment_5_414a45573aeb5201f4d80433955669d5._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="arafel"
+ ip="94.174.218.177"
+ subject="comment 5"
+ date="2013-01-14T23:22:19Z"
+ content="""
+Hm. After removing the directory, I can't get the problem to happen. I've tried both running the webapp from the CLI, and the git-annex app from Spotlight, and it works.
+
+A thought - does annex check for the existence of .git in the target folder, or does it just assume (if the folder exists) that it's been set up with git? That's the only thing I can think of. From this experience it seems that would be a worthwhile check if it doesn't already do it.
+
+Other than that we may just have to close the bug as unreproducible. I'm not sure what happened there; I'm not aware of doing anything differently the other times. Apologies for wasting your time!
+"""]]
diff --git a/doc/bugs/Interrupted_switch_to_direct_mode_can_cause_all_following_switches_to_fail.mdwn b/doc/bugs/Interrupted_switch_to_direct_mode_can_cause_all_following_switches_to_fail.mdwn
new file mode 100644
index 000000000..432c72083
--- /dev/null
+++ b/doc/bugs/Interrupted_switch_to_direct_mode_can_cause_all_following_switches_to_fail.mdwn
@@ -0,0 +1,50 @@
+### What steps will reproduce the problem?
+
+How to reproduce:
+
+1. Check that the files involved are not available in the local repository.
+2. Force a switch to direct mode to fail, for example, due to a 'exotic' filename
+(first bug).
+3. Solve that problem.
+4. Make another switch to direct mode, but call that command in a subdirectory of
+the git-tree. Which will because some annexed file does not exists (second bug).
+Note: all subsequent switches to direct mode will now fail, no matter where started.
+
+
+Example:
+
+mkdir test1 test2 && cd test1 && git init . && git annex init
+mkdir umlaut something\ else
+date > umlaut/this_has_a_$'\201'
+date > something\ else/problem
+git annex add .
+git commit -m "Init"
+cd ../test2/
+
+git clone ../test1/ . && git annex init
+git annex move --from origin .
+
+cd ../test1/
+git annex direct #aborts with: commitBuffer: invalid argument (invalid character)
+cd umlaut
+git mv this_has_a_$'\201' this_has_a_o
+git commit -m "fix"
+git annex direct # fails with getSymbolicLinkStatus: does not exist (No such file or directory)
+
+### What is the expected output? What do you see instead?
+
+Expected is a repository switched to direct mode.
+The result is a repository which can't be switched to direct mode.
+
+### What version of git-annex are you using? On what operating system?
+
+git-annex version: 3.20130114
+OS: Arch Linux (3.7.2-2-ck)
+
+### Please provide any additional information below.
+
+The second bug seams to be very specific about folder- and/or filename.
+I believe that it has something to do with the space in the foldername.
+
+> Fixed both bugs. You should be able to upgrade git-annex and re-run the command
+> and end up with a working direct-mode repository. [[done]] --[[Joey]]
diff --git a/doc/bugs/Is_there_any_way_to_rate_limit_uploads_to_an_S3_backend__63__.mdwn b/doc/bugs/Is_there_any_way_to_rate_limit_uploads_to_an_S3_backend__63__.mdwn
new file mode 100644
index 000000000..64826c02a
--- /dev/null
+++ b/doc/bugs/Is_there_any_way_to_rate_limit_uploads_to_an_S3_backend__63__.mdwn
@@ -0,0 +1,19 @@
+What steps will reproduce the problem?
+
+Adding files to a local annex set up to sync to a remote S3 one
+
+
+What is the expected output? What do you see instead?
+
+It syncs, but maxes out the uplink
+
+
+What version of git-annex are you using? On what operating system?
+
+3.20121112 on Debian testing
+
+
+Please provide any additional information below.
+
+The man page lists how to configure rate limiting for rsync, not sure how to do it for this
+
diff --git a/doc/bugs/Is_there_any_way_to_rate_limit_uploads_to_an_S3_backend__63__/comment_1_ef97e735ce308f7bcc03f5d9fda588bf._comment b/doc/bugs/Is_there_any_way_to_rate_limit_uploads_to_an_S3_backend__63__/comment_1_ef97e735ce308f7bcc03f5d9fda588bf._comment
new file mode 100644
index 000000000..67de2becf
--- /dev/null
+++ b/doc/bugs/Is_there_any_way_to_rate_limit_uploads_to_an_S3_backend__63__/comment_1_ef97e735ce308f7bcc03f5d9fda588bf._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="comment 1"
+ date="2012-11-13T15:10:45Z"
+ content="""
+There's always trickle..
+
+ trickle -u 50 git annex ...
+"""]]
diff --git a/doc/bugs/Is_there_any_way_to_rate_limit_uploads_to_an_S3_backend__63__/comment_2_539b89de8743e435386b86119d1e982f._comment b/doc/bugs/Is_there_any_way_to_rate_limit_uploads_to_an_S3_backend__63__/comment_2_539b89de8743e435386b86119d1e982f._comment
new file mode 100644
index 000000000..122bafbba
--- /dev/null
+++ b/doc/bugs/Is_there_any_way_to_rate_limit_uploads_to_an_S3_backend__63__/comment_2_539b89de8743e435386b86119d1e982f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.252.11.120"
+ subject="comment 2"
+ date="2012-11-13T17:09:31Z"
+ content="""
+It's not there yet. I don't think it will be hard to add, most of the same things need to be done to support upload progress bars with S3.
+"""]]
diff --git a/doc/bugs/Issue_on_OSX_with_some_system_limits.mdwn b/doc/bugs/Issue_on_OSX_with_some_system_limits.mdwn
new file mode 100644
index 000000000..146323bb8
--- /dev/null
+++ b/doc/bugs/Issue_on_OSX_with_some_system_limits.mdwn
@@ -0,0 +1,26 @@
+I was dumping ~gigs of files of approximately 3-6megs a pop (my music collection) so I could track the files that I want to listen to when I'm on the go. I had the git watch command running from the assistant branch.
+
+I was getting something along the lines of...
+
+ /Users/jtang/annex/.git/annex/tmp/: openTempFile: resource exhausted (Too many open files)
+
+and
+
+ git-annex: createPipe: resource exhausted (Too many open files)
+
+I also noticed that I somehow ended up with 256 ssh-agent's running on one of my machines, I'm not sure if the two issues are related or not, I had not noticed this type of behaviour up until recently.
+
+Also this was appearing in the logs
+
+ x00:annex jtang$ tail -f .git/annex/daemon.log
+ (scanning...) Already up-to-date.
+ kqueue: Too many open files
+
+To be precise, I suspect that the kqueue limit is 256, I had 325 files in the 'queue', I ended up doing a _git annex add_ manually and all was fine.
+
+[[!meta title="kqueue system limits"]]
+
+> This affects BSD systems that use Kqueue. It no longer affects OSX,
+> since we use FSEvents there instead. --[[Joey]]
+
+[[!tag /design/assistant]]
diff --git a/doc/bugs/Issue_on_OSX_with_some_system_limits/comment_1_5fc1eedb5231edc37c87a2d9b91313b9._comment b/doc/bugs/Issue_on_OSX_with_some_system_limits/comment_1_5fc1eedb5231edc37c87a2d9b91313b9._comment
new file mode 100644
index 000000000..d30cddca5
--- /dev/null
+++ b/doc/bugs/Issue_on_OSX_with_some_system_limits/comment_1_5fc1eedb5231edc37c87a2d9b91313b9._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.2.25"
+ subject="comment 1"
+ date="2012-06-25T15:42:48Z"
+ content="""
+Yes, this is a known problem with kqueue, it has to keep every directory in the tree open. On [[design/assistant/inotify]] I have a note that it may need to fork off extra watcher processes to deal with this. Of course that adds significant complication.
+
+In the meantime, you may be able to increase your system's maximum allowed number of open files per process somehow.
+
+(I doubt that the ssh-agent is related; git-annex does not use ssh-agent directly anyway..)
+"""]]
diff --git a/doc/bugs/Issue_on_OSX_with_some_system_limits/comment_2_b14e697c211843163285aaa8de5bf4c6._comment b/doc/bugs/Issue_on_OSX_with_some_system_limits/comment_2_b14e697c211843163285aaa8de5bf4c6._comment
new file mode 100644
index 000000000..17dcf7634
--- /dev/null
+++ b/doc/bugs/Issue_on_OSX_with_some_system_limits/comment_2_b14e697c211843163285aaa8de5bf4c6._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 2"
+ date="2012-06-29T12:02:48Z"
+ content="""
+Doing,
+
+ sudo sysctl -w kern.maxfilesperproc=400000
+
+Somewhat works for me, git-annex watch at least starts up and takes a while to scan the directory, but it's not ideal. Also, creating files seems to work okay, when I remove a file the changes don't seem to get pushed across my other repos, running a sync on the remote repo fixes things.
+"""]]
diff --git a/doc/bugs/Issue_on_OSX_with_some_system_limits/comment_3_18ddf8b5934dd6fb1676cd6adc7d103b._comment b/doc/bugs/Issue_on_OSX_with_some_system_limits/comment_3_18ddf8b5934dd6fb1676cd6adc7d103b._comment
new file mode 100644
index 000000000..eb886acf6
--- /dev/null
+++ b/doc/bugs/Issue_on_OSX_with_some_system_limits/comment_3_18ddf8b5934dd6fb1676cd6adc7d103b._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ subject="comment 3"
+ date="2012-07-04T12:32:44Z"
+ content="""
+Jimmy, sounds like I could use something like this to get the current limit:
+
+ sysctl kern.maxfilesperproc
+
+Probably prints \"sysctl kern.maxfilesperproc = 256\" or such.. can you verify?
+Once I have the limit, I can make the kqueue code use subset of it, and print out a message when it needs to be increased, like the inotify code does.
+
+(Also, the kqueue code only opens directories, not files, so unless you have 400000 directories, that's
+a little high.)
+
+---
+
+On file removal not propigating, does this still happen? When you remove a file does a git commit automatically happen, or is that broken with kqueue?
+"""]]
diff --git a/doc/bugs/Issue_on_OSX_with_some_system_limits/comment_4_c25a8eb369e546f65e1a72d89f43066f._comment b/doc/bugs/Issue_on_OSX_with_some_system_limits/comment_4_c25a8eb369e546f65e1a72d89f43066f._comment
new file mode 100644
index 000000000..509752bf1
--- /dev/null
+++ b/doc/bugs/Issue_on_OSX_with_some_system_limits/comment_4_c25a8eb369e546f65e1a72d89f43066f._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ subject="comment 4"
+ date="2012-07-08T18:13:58Z"
+ content="""
+On kFreeBSD, I get this:
+
+ $ sysctl kern.maxfilesperproc
+ kern.maxfilesperproc: 11095
+
+But ulimit still has 1024 limit, so you'd need to adjust both, as root. Messy..
+"""]]
diff --git a/doc/bugs/Issue_on_OSX_with_some_system_limits/comment_5_6407a3e7aa0316cba2994bfef0e3c633._comment b/doc/bugs/Issue_on_OSX_with_some_system_limits/comment_5_6407a3e7aa0316cba2994bfef0e3c633._comment
new file mode 100644
index 000000000..30ea6b310
--- /dev/null
+++ b/doc/bugs/Issue_on_OSX_with_some_system_limits/comment_5_6407a3e7aa0316cba2994bfef0e3c633._comment
@@ -0,0 +1,37 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 4"
+ date="2012-07-04T13:17:05Z"
+ content="""
+In relation to the system limits,
+
+ laplace:~ jtang$ sysctl kern.maxfilesperproc
+ kern.maxfilesperproc: 10240
+
+Also, the maxfiles for the whole system is
+
+ laplace:~ jtang$ sysctl kern.maxfiles
+ kern.maxfiles: 12288
+
+the above was the defaults as far as I recall. What you probably would be interested is the ulimits that the user see
+
+ laplace:~ jtang$ ulimit -a
+ core file size (blocks, -c) 0
+ data seg size (kbytes, -d) unlimited
+ file size (blocks, -f) unlimited
+ max locked memory (kbytes, -l) unlimited
+ max memory size (kbytes, -m) unlimited
+ open files (-n) 256
+ pipe size (512 bytes, -p) 1
+ stack size (kbytes, -s) 8192
+ cpu time (seconds, -t) unlimited
+ max user processes (-u) 709
+ virtual memory (kbytes, -v) unlimited
+
+I would imagine the limit that you are looking for is 256. Hope this helps.
+
+----
+
+On the point about deletions not being propagated, it does do a commit. I suspect that the kqueue code is just not picking up the changes and pushing the changes out. The watch command on a single annex with no remotes functions as expected.
+"""]]
diff --git a/doc/bugs/Issue_on_OSX_with_some_system_limits/comment_6_f01887695e8b8386e125464c6d401565._comment b/doc/bugs/Issue_on_OSX_with_some_system_limits/comment_6_f01887695e8b8386e125464c6d401565._comment
new file mode 100644
index 000000000..cd5c73a7a
--- /dev/null
+++ b/doc/bugs/Issue_on_OSX_with_some_system_limits/comment_6_f01887695e8b8386e125464c6d401565._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 2"
+ date="2012-06-25T22:36:39Z"
+ content="""
+On the system limits side, I think if you want to make it more approachable by more users then adjusting system limits might scare users away. On the note of the ssh-agents spawning like no tomorrow on my machine, it turned out that i had a symlink from my .bashrc to .bash_profile, I guess I should not be too lazy and have two seperate files.
+"""]]
diff --git a/doc/bugs/Issue_on_OSX_with_some_system_limits/comment_7_c7776d5b2d073e0d2ae36515185c25aa._comment b/doc/bugs/Issue_on_OSX_with_some_system_limits/comment_7_c7776d5b2d073e0d2ae36515185c25aa._comment
new file mode 100644
index 000000000..b65dc4dfc
--- /dev/null
+++ b/doc/bugs/Issue_on_OSX_with_some_system_limits/comment_7_c7776d5b2d073e0d2ae36515185c25aa._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="Just encountered this today"
+ date="2012-11-29T19:21:50Z"
+ content="""
+& it's killing my assistant.
+
+Found a workaround here: https://github.com/mockko/livereload/issues/1
+
+This fixes it for now:
+
+ulimit -n 4096
+
+Just posting here in case anybody else runs into this issue and, like me, finds themselves here via search engine.
+
+"""]]
diff --git a/doc/bugs/It_is_very_easy_to_turn_git-annex_into_a_zombie.mdwn b/doc/bugs/It_is_very_easy_to_turn_git-annex_into_a_zombie.mdwn
new file mode 100644
index 000000000..914825209
--- /dev/null
+++ b/doc/bugs/It_is_very_easy_to_turn_git-annex_into_a_zombie.mdwn
@@ -0,0 +1,25 @@
+What steps will reproduce the problem?
+
+Run the git-annex assitant, and then "sudo kill" it.
+
+What is the expected output? What do you see instead?
+
+I expect it to die, instead I end up with:
+
+ 14604 ?? S 0:00.64 ga assistant
+ 14623 ?? Z 0:00.00 (git)
+ 14624 ?? Z 0:00.00 (git)
+ 14936 ?? Z 0:00.00 (git-annex)
+
+The only way to clear these zombies is to reboot. Perhaps there is some resource not being correctly terminated under exceptional conditions?
+
+Note that on OpenIndiana the problem is even more severe: Aborting git-annex at the wrong time leaves behind both zombie processes and lock files which cause the machine to suddenly halt if I try to access them in any way (via mv, rsync, etc)!
+
+What version of git-annex are you using? On what operating system?
+
+4d1e0c9 on OS X 10.8.2.
+
+Please provide any additional information below.
+
+[[!meta title="strange OSX behavior when killed"]]
+[[!tag /design/assistant/OSX moreinfo]]
diff --git a/doc/bugs/It_is_very_easy_to_turn_git-annex_into_a_zombie/comment_1_d5fba6c061fb21795021ea83070dbfa2._comment b/doc/bugs/It_is_very_easy_to_turn_git-annex_into_a_zombie/comment_1_d5fba6c061fb21795021ea83070dbfa2._comment
new file mode 100644
index 000000000..8d7eea6c5
--- /dev/null
+++ b/doc/bugs/It_is_very_easy_to_turn_git-annex_into_a_zombie/comment_1_d5fba6c061fb21795021ea83070dbfa2._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/2grhJvAC049fJnvALDXek.6MRZMTlg--#eec89"
+ nickname="John"
+ subject="Correction"
+ date="2012-10-20T05:34:47Z"
+ content="""
+If I \"sudo kill -9\" all the processes in the above group after deleting the annex directories, then they do go away without needing to reboot.
+"""]]
diff --git a/doc/bugs/It_is_very_easy_to_turn_git-annex_into_a_zombie/comment_2_12cba707239018989e8d5b6f456fa754._comment b/doc/bugs/It_is_very_easy_to_turn_git-annex_into_a_zombie/comment_2_12cba707239018989e8d5b6f456fa754._comment
new file mode 100644
index 000000000..2b552c6aa
--- /dev/null
+++ b/doc/bugs/It_is_very_easy_to_turn_git-annex_into_a_zombie/comment_2_12cba707239018989e8d5b6f456fa754._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.23"
+ subject="comment 2"
+ date="2012-10-22T14:01:42Z"
+ content="""
+It's not at all clear to me from this what process you killed.
+
+(I can't comment on files that somehow crash a kernel on access.. That's not in any UNIX spec I'm aware of.)
+"""]]
diff --git a/doc/bugs/JSON_output_broken_with___34__git_annex_sync__34__.mdwn b/doc/bugs/JSON_output_broken_with___34__git_annex_sync__34__.mdwn
new file mode 100644
index 000000000..f0809c568
--- /dev/null
+++ b/doc/bugs/JSON_output_broken_with___34__git_annex_sync__34__.mdwn
@@ -0,0 +1,21 @@
+What steps will reproduce the problem?
+
+ $ git annex -j sync | json_reformat
+
+What is the expected output? What do you see instead?
+
+Expecting valid JSON, instead this happens:
+
+ $ git annex -j sync | json_reformat
+ lexical error: invalid char in json text.
+ {"command":"commit","file":""# On branch master nothing to c
+ (right here) ------^
+ $
+
+
+What version of git-annex are you using? On what operating system?
+
+Newest standalone (3.20121126), Linux i386. The "json_reformat" program is from the "yajl-tools" .deb package.
+
+> [[done]]; I've updated the --json documentation to note that it only
+> works with some query commands. --[[Joey]]
diff --git a/doc/bugs/JSON_output_broken_with___34__git_annex_sync__34__/comment_1_380a49b3c132f9f529729a1cb5a69621._comment b/doc/bugs/JSON_output_broken_with___34__git_annex_sync__34__/comment_1_380a49b3c132f9f529729a1cb5a69621._comment
new file mode 100644
index 000000000..d1ad05842
--- /dev/null
+++ b/doc/bugs/JSON_output_broken_with___34__git_annex_sync__34__/comment_1_380a49b3c132f9f529729a1cb5a69621._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.49"
+ subject="comment 1"
+ date="2012-11-27T21:13:08Z"
+ content="""
+Yeah, so git-annex has --json as a option available to any command, but the set of commands where it's actually useful is rather smaller, and certainly does not include this one. In general there are quite a lot of places where third-party program output is allowed to show through to provide necessary progress or debugging output, and that of course makes the json mode invalid.
+"""]]
diff --git a/doc/bugs/JSON_output_broken_with___34__git_annex_sync__34__/comment_2_282f5f89fb4a46e1fad0980e0b2994a0._comment b/doc/bugs/JSON_output_broken_with___34__git_annex_sync__34__/comment_2_282f5f89fb4a46e1fad0980e0b2994a0._comment
new file mode 100644
index 000000000..b7b4d786e
--- /dev/null
+++ b/doc/bugs/JSON_output_broken_with___34__git_annex_sync__34__/comment_2_282f5f89fb4a46e1fad0980e0b2994a0._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://sunny256.sunbase.org/"
+ nickname="sunny256"
+ subject="comment 2"
+ date="2012-11-27T21:30:48Z"
+ content="""
+Yep, because of that I was in doubt if I should report it as a bug. Maybe it could be closed, as it's not a bug in git-annex, but git output leaking into the JSON. If there's not an easy way for git-annex to encapsulate the output or redirect the git output to stderr.
+"""]]
diff --git a/doc/bugs/JSON_output_broken_with___34__git_annex_sync__34__/comment_3_7ff98958146b7f6396226bdd878ec86e._comment b/doc/bugs/JSON_output_broken_with___34__git_annex_sync__34__/comment_3_7ff98958146b7f6396226bdd878ec86e._comment
new file mode 100644
index 000000000..e3b27dd0e
--- /dev/null
+++ b/doc/bugs/JSON_output_broken_with___34__git_annex_sync__34__/comment_3_7ff98958146b7f6396226bdd878ec86e._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.49"
+ subject="comment 3"
+ date="2012-11-27T21:32:26Z"
+ content="""
+I'd rather not abuse stderr.
+
+Do you have an actual use case for the json output for git annex sync? If there's a good one, the git output could be suppressed.
+"""]]
diff --git a/doc/bugs/JSON_output_broken_with___34__git_annex_sync__34__/comment_4_f9e460a09e7e5f53c16c20ded2649201._comment b/doc/bugs/JSON_output_broken_with___34__git_annex_sync__34__/comment_4_f9e460a09e7e5f53c16c20ded2649201._comment
new file mode 100644
index 000000000..d773ef2c7
--- /dev/null
+++ b/doc/bugs/JSON_output_broken_with___34__git_annex_sync__34__/comment_4_f9e460a09e7e5f53c16c20ded2649201._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://sunny256.sunbase.org/"
+ nickname="sunny256"
+ subject="comment 4"
+ date="2012-11-27T21:40:05Z"
+ content="""
+Actually not for the sync command, as I don't parse it in any scripts. Just meant as a heads-up, and not an especially important. Feel free to close it. :)
+"""]]
diff --git a/doc/bugs/Killing_the_assistant_daemon_leaves_ssh_mux_sessions_behind.mdwn b/doc/bugs/Killing_the_assistant_daemon_leaves_ssh_mux_sessions_behind.mdwn
new file mode 100644
index 000000000..12d1d7719
--- /dev/null
+++ b/doc/bugs/Killing_the_assistant_daemon_leaves_ssh_mux_sessions_behind.mdwn
@@ -0,0 +1,38 @@
+### Please describe the problem.
+
+If the assistant daemon is killed, ssh mux sessions are left behind. Incidentally there may be a better way to stop the assistant daemon besides "killall git-annex" but I haven't found it in the docs.
+
+### What steps will reproduce the problem?
+
+[[!format sh """
+$ ps aux | grep mux
+$ git-annex assistant
+$ date > fromwintermute # Just causing a change that needs to be pushed, any will do
+$ ps aux | grep mux
+pedrocr 32665 0.0 0.0 6396 948 ? Ss 11:06 0:00 ssh: /home/pedrocr/testsync/.git/annex/ssh/golias.git-annex [mux]
+$ killall git-annex
+$ ps aux | grep mux
+pedrocr 32665 0.0 0.0 6396 948 ? Ss 11:06 0:00 ssh: /home/pedrocr/testsync/.git/annex/ssh/golias.git-annex [mux]
+"""]]
+
+### What version of git-annex are you using? On what operating system?
+
+[[!format sh """
+$ git annex version
+git-annex version: 4.20130516.1
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP
+local repository version: 4
+default repository version: 3
+supported repository versions: 3 4
+upgrade supported from repository versions: 0 1 2
+$ lsb_release -a
+No LSB modules are available.
+Distributor ID: Ubuntu
+Description: Ubuntu 12.04.2 LTS
+Release: 12.04
+Codename: precise
+"""]]
+
+
+
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/Killing_the_assistant_daemon_leaves_ssh_mux_sessions_behind/comment_1_17879b98a5e79ace03b543064751e46e._comment b/doc/bugs/Killing_the_assistant_daemon_leaves_ssh_mux_sessions_behind/comment_1_17879b98a5e79ace03b543064751e46e._comment
new file mode 100644
index 000000000..17c91ca99
--- /dev/null
+++ b/doc/bugs/Killing_the_assistant_daemon_leaves_ssh_mux_sessions_behind/comment_1_17879b98a5e79ace03b543064751e46e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-05-29T15:36:48Z"
+ content="""
+There is a --stop option that can be used to stop the assistant. It will clean up ssh sessions. git-annex also automatically cleans up stale ssh sessions whenever it starts a new one.
+"""]]
diff --git a/doc/bugs/Killing_the_assistant_daemon_leaves_ssh_mux_sessions_behind/comment_2_2dc877e281750004b16619ea7b931160._comment b/doc/bugs/Killing_the_assistant_daemon_leaves_ssh_mux_sessions_behind/comment_2_2dc877e281750004b16619ea7b931160._comment
new file mode 100644
index 000000000..7c39be61b
--- /dev/null
+++ b/doc/bugs/Killing_the_assistant_daemon_leaves_ssh_mux_sessions_behind/comment_2_2dc877e281750004b16619ea7b931160._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkx5V3MTbzCXS3J7Mn9FEq8M9bPPYMkAHY"
+ nickname="Pedro"
+ subject="comment 2"
+ date="2013-05-29T18:08:51Z"
+ content="""
+I see the --stop option in the manpage now, it's under watch and not assistant, so that's why I missed it. I had a problem with the mux sessions not being cleaned up when I changed the remote's hostname. Only after killing old mux's and restarting the assistant did I get it to sync properly.
+"""]]
diff --git a/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss.mdwn b/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss.mdwn
new file mode 100644
index 000000000..2629a7d56
--- /dev/null
+++ b/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss.mdwn
@@ -0,0 +1,57 @@
+## What steps will reproduce the problem?
+
+Take a large sub-directory in a repository (e.g. `ccash`) with some files within,
+
+ $ tar -xzf ccash.tar.gz
+ $ du -sh ccash
+ 59M ccash
+ $ ls -l ccash/trunk/annotationinterface/src/edu/byu/nlp/annotationinterface/java/BasicAnnotation.java ccash/trunk/DataProvider/WebContent/WEB-INF/lib/dom4j.jar
+ -rw-r--r-- 1 dietz dietz 1748 Jul 27 2011 ccash/trunk/annotationinterface/src/edu/byu/nlp/annotationinterface/java/BasicAnnotation.java
+ -rw-r--r-- 1 dietz dietz 313898 May 22 18:36 ccash/trunk/DataProvider/WebContent/WEB-INF/lib/dom4j.jar
+
+Annex it,
+
+ $ git annex add ccash
+ ...
+ $ ls -l ccash/trunk/annotationinterface/src/edu/byu/nlp/annotationinterface/java/BasicAnnotation.java ccash/trunk/DataProvider/WebContent/WEB-INF/lib/dom4j.jar
+ lrwxrwxrwx 1 dietz dietz 215 Jul 27 2011 ccash/trunk/annotationinterface/src/edu/byu/nlp/annotationinterface/java/BasicAnnotation.java -> ../../../../../../../../../../../.git/annex/objects/mv/zf/SHA256-s1748--5c0d1cbf104214b6d0ab85c53a85cadb975ec208f42a7b33a76d85e175352486/SHA256-s1748--5c0d1cbf104214b6d0ab85c53a85cadb975ec208f42a7b33a76d85e175352486
+ lrwxrwxrwx 1 dietz dietz 210 Jul 27 2011 ccash/trunk/DataProvider/WebContent/WEB-INF/lib/dom4j.jar -> ../../../../../../../../.git/annex/objects/8G/gQ/SHA256-s313898--593552ffea3c5823c6602478b5002a7c525fd904a3c44f1abe4065c22edfac73/SHA256-s313898--593552ffea3c5823c6602478b5002a7c525fd904a3c44f1abe4065c22edfac73
+
+Unannex it (before or after committing),
+
+ $ git annex unannex ccash
+
+Note that some fraction of the files will still be symbolic links, now pointing to non-existent files. This data has apparently been lost forever.
+
+ $ ls -l ccash/trunk/annotationinterface/src/edu/byu/nlp/annotationinterface/java/BasicAnnotation.java ccash/trunk/DataProvider/WebContent/WEB-INF/lib/dom4j.jar
+ -rw-r--r-- 1 dietz dietz 1748 Jul 27 2011 ccash/trunk/annotationinterface/src/edu/byu/nlp/annotationinterface/java/BasicAnnotation.java
+ lrwxrwxrwx 1 dietz dietz 210 Jul 27 2011 ccash/trunk/DataProvider/WebContent/WEB-INF/lib/dom4j.jar -> ../../../../../../../../.git/annex/objects/8G/gQ/SHA256-s313898--593552ffea3c5823c6602478b5002a7c525fd904a3c44f1abe4065c22edfac73/SHA256-s313898--593552ffea3c5823c6602478b5002a7c525fd904a3c44f1abe4065c22edfac73
+
+It is unclear why some files are affected while others are not. That being said, unannexing small numbers of files at a time appears to avoid the issue,
+
+ $ tar -zxf ccash.tar.gz
+ $ git annex add ccash
+ $ ls -l ccash/trunk/annotationinterface/src/edu/byu/nlp/annotationinterface/java/BasicAnnotation.java ccash/trunk/DataProvider/WebContent/WEB-INF/lib/dom4j.jar
+ lrwxrwxrwx 1 dietz dietz 215 Jul 27 2011 ccash/trunk/annotationinterface/src/edu/byu/nlp/annotationinterface/java/BasicAnnotation.java -> ../../../../../../../../../../../.git/annex/objects/mv/zf/SHA256-s1748--5c0d1cbf104214b6d0ab85c53a85cadb975ec208f42a7b33a76d85e175352486/SHA256-s1748--5c0d1cbf104214b6d0ab85c53a85cadb975ec208f42a7b33a76d85e175352486
+ lrwxrwxrwx 1 dietz dietz 210 Jul 27 2011 ccash/trunk/DataProvider/WebContent/WEB-INF/lib/dom4j.jar -> ../../../../../../../../.git/annex/objects/8G/gQ/SHA256-s313898--593552ffea3c5823c6602478b5002a7c525fd904a3c44f1abe4065c22edfac73/SHA256-s313898--593552ffea3c5823c6602478b5002a7c525fd904a3c44f1abe4065c22edfac73
+ $ git annex unannex ccash/trunk/DataProvider/WebContent/WEB-INF
+ ...
+ $ ls -l ccash/trunk/annotationinterface/src/edu/byu/nlp/annotationinterface/java/BasicAnnotation.java ccash/trunk/DataProvider/WebContent/WEB-INF/lib/dom4j.jar
+ lrwxrwxrwx 1 dietz dietz 215 Jul 27 2011 ccash/trunk/annotationinterface/src/edu/byu/nlp/annotationinterface/java/BasicAnnotation.java -> ../../../../../../../../../../../.git/annex/objects/mv/zf/SHA256-s1748--5c0d1cbf104214b6d0ab85c53a85cadb975ec208f42a7b33a76d85e175352486/SHA256-s1748--5c0d1cbf104214b6d0ab85c53a85cadb975ec208f42a7b33a76d85e175352486
+ -rw-r--r-- 1 dietz dietz 313898 Jul 27 2011 ccash/trunk/DataProvider/WebContent/WEB-INF/lib/dom4j.jar
+
+For this reason, it seems likely this is due to some sort of race condition.
+
+
+## What version of git-annex are you using? On what operating system?
+
+This is on Ubuntu 12.04 with git-annex revision a1e2bc4.
+
+
+> There was no good soluton to this, so I picked a bad one that
+> will not have users complainging git-annex ate their data.
+> They will complain that `git annex unannex` is slow since it now copies
+> the file, and perhaps instead use --fast, and hopefully avoid destroying
+> their own data by editing the resulting hard links.
+>
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_10_52364dc5b1b43b51748453d1896e35c6._comment b/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_10_52364dc5b1b43b51748453d1896e35c6._comment
new file mode 100644
index 000000000..c0b286a2b
--- /dev/null
+++ b/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_10_52364dc5b1b43b51748453d1896e35c6._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmVV_nBwlsyCv53BXoJt8YpCX_wZPfzpyo"
+ nickname="Peter"
+ subject="Progress"
+ date="2013-10-10T01:17:08Z"
+ content="""
+Is there any type of script / tool / patch which does the --fast but with a copy instead of only a hard link? Can someone point me towards how I'm supposed to do this? I'm a technical user, however I don't really fancy having try to go learn the source code of git-annex to fix this really bad flaw :-/
+"""]]
diff --git a/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_11_99b4db1841f8630a9c5efd08910e87a3._comment b/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_11_99b4db1841f8630a9c5efd08910e87a3._comment
new file mode 100644
index 000000000..4e55bd020
--- /dev/null
+++ b/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_11_99b4db1841f8630a9c5efd08910e87a3._comment
@@ -0,0 +1,104 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmVV_nBwlsyCv53BXoJt8YpCX_wZPfzpyo"
+ nickname="Peter"
+ subject="Productive Annoyance"
+ date="2013-10-10T04:30:47Z"
+ content="""
+Ok, so I'm annoyed by this enough (and desperate enough to want to get my data back) that I wrote up a few scripts to help with this. I make no claims regarding how well these will work, but they seem to work with some minimal testing on a Fedora 17 machine.
+
+READ THROUGH THESE SCRIPTS BEFORE RUNNING THEM TO MAKE SURE YOU ARE OK WITH WHAT THEY ARE DOING!!!
+
+First, a script to create a bad git-annex: one with missing files (with a few corner case names) after a git unannex. Specify the directory you'd like to make the annex at the top of the file. ALL CONTENTS OF THIS DIRECTORY WILL BE REMOVED!!!
+
+ #!/bin/bash
+
+ #This is the folder you'd like to create and unannex
+ FOLDERTOUNANNEX='/tmp/badAnnex'
+
+ pushd .
+
+ if [ ! -d \"$FOLDERTOUNANNEX\" ] ; then
+ mkdir \"$FOLDERTOUNANNEX\"
+ fi
+
+ cd \"$FOLDERTOUNANNEX\"
+
+ rm -rf *
+
+ mkdir subdir
+ echo \"hi\" > 1one.txt
+ echo \"hi\" > 2two.txt
+ echo \"hi\" > \"3thr re ee.boo\"
+ echo \"hi\" > \"4f o u r.boo\"
+ echo \"hi\" > 5
+ echo \"hi\" > \"6\"
+ echo \"hi\" > \"subdir/7\"
+ echo \"hi\" > \"subdir/8.cat\"
+ echo \"hi\" > \"subdir/9.cat\"
+
+ echo \"* annex.backend=SHA512E\" > .gitattributes
+
+ chmod g-r 5 6
+ chmod o-r 6
+
+ ls -la
+
+ git init
+ git annex init \"stupid\"
+ git annex add *
+ ls -la
+ git annex unannex *
+ ls -la
+
+ popd
+
+
+Then, a script to recover the files left missing by the above script. Note this might be very slow as it has to generate SHA512 hashes for all the files in your annex. Again, change the paths at the top of this file to work in your environment:
+
+ #!/bin/bash
+
+ #Set this to some place outside your annex, where we can store our hashes while we search for them
+ #It will be fastest if this is on a different physical disk than the annexed folder
+ #You can manually delete the file afterwards
+ HASHFILE='/backup3/tmp.sha'
+ #This is the folder you'd like to unannex
+ FOLDERTOUNANNEX='/tmp/badAnnex'
+
+
+
+
+ HASHLEN=128
+
+ pushd .
+ cd \"$FOLDERTOUNANNEX\"
+
+ find \"$FOLDERTOUNANNEX\" ! -path '*.git*' -exec sha512sum \{\} \; > \"$HASHFILE\"
+
+ find -L \"$FOLDERTOUNANNEX\" -type l | while read BROKENFILE; do
+ POINTSTO=`file \"$BROKENFILE\" | sed -r 's/^.*broken symbolic link to .(.*).$/\1/g'`
+
+ HASH=`echo \"$POINTSTO\" | sed -r \"s/^.*--([^-\/.]{$HASHLEN}).*$/\1/g\"`
+
+ EXT=`echo \"$POINTSTO\" | sed -r \"s/^.*--[^-\/.]{$HASHLEN}(.[^.]+)?$/\1/g\"`
+
+ echo \"-\"
+ echo \"FILE:$BROKENFILE\"
+ echo \"POINTSTO:$POINTSTO\"
+ echo \"HASH:$HASH\"
+ echo \"EXT:$EXT\"
+
+ SOURCEFILE=`grep $HASH $HASHFILE | grep -m 1 \"$EXT\" | sed -r \"s/^.{$HASHLEN} (.*)$/\1/g\"`
+
+ echo \"SOURCEFILE:$SOURCEFILE\"
+ if [ -f \"$SOURCEFILE\" ];
+ then
+ cp --backup --suffix=\"~GIT_ANNEX_IS_DANGEROUS~\" -a \"$SOURCEFILE\" \"$BROKENFILE\"
+ else
+ echo \"ERROR: Cant find sourcefile\"
+ fi
+ done;
+
+ popd
+
+I have not yet run this repair script on my rather large broken annex. I cannot seem to figure out how to restore file ownership and permissions which seem to have been lost when the second file is just linked to the matching previously annexed file (note: this is visible after \"fixing\" the bad annex created by the first script above in that after \"fixing\" file \"6\" is readable by other, whereas originally he was NOT readable by other. The permissions of 6 have been copied from 5.) Any thoughts or improvements on this are appreciated.
+"""]]
diff --git a/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_1_fbb410a54bb0bd82d0953ef58a88600e._comment b/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_1_fbb410a54bb0bd82d0953ef58a88600e._comment
new file mode 100644
index 000000000..14172a3e5
--- /dev/null
+++ b/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_1_fbb410a54bb0bd82d0953ef58a88600e._comment
@@ -0,0 +1,24 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlup4hyZo4eCjF8T85vfRXMKBxGj9bMdl0"
+ nickname="Ben"
+ subject="comment 1"
+ date="2012-09-06T02:28:00Z"
+ content="""
+
+Here is a quick script which reproduces the issue on another Ubuntu 12.04 machine,
+
+ mkdir hi
+ cd hi
+ wget \"http://downloads.sourceforge.net/project/free-cad/FreeCAD%20Source/freecad-0.11.3729.tar.gz\"
+
+ git init
+ git annex init
+ tar -zxf freecad-0.11.3729.tar.gz
+ git annex add FreeCAD-0.11.3729
+ git annex unannex FreeCAD-0.11.3729
+ echo \"The following links are broken:\"
+ find -L . -type l
+
+This results in dozens of dead symlinks.
+
+"""]]
diff --git a/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_2_8007c9ba42a951a4426255ec3c37d961._comment b/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_2_8007c9ba42a951a4426255ec3c37d961._comment
new file mode 100644
index 000000000..e1f600d88
--- /dev/null
+++ b/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_2_8007c9ba42a951a4426255ec3c37d961._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.236"
+ subject="comment 2"
+ date="2012-09-06T14:55:58Z"
+ content="""
+What's going on here is you have multiple files with the same content, so the symlinks point to the same annexed file. When unannex processes the first symlink, it moves the annexed file to replace it. This breaks the other symlink that pointed to it. Notice that if you then re-add the file to the annex, the broken symlink automatically gets fixed -- there's no actual data loss going on here.
+
+This problem can be avoided by using `git annex unannex --fast`, which makes hardlinks to the annexed file.
+But then you are also left with the hard links in `.git/annex/objects`.. `git annex unused` can find and remove them.
+
+It may make sense to make the current \"--fast\" behavior the default for unannex..
+"""]]
diff --git a/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_3_73ecd4cb8ee58a8dfe7cab0e893dbe5b._comment b/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_3_73ecd4cb8ee58a8dfe7cab0e893dbe5b._comment
new file mode 100644
index 000000000..2a799fac0
--- /dev/null
+++ b/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_3_73ecd4cb8ee58a8dfe7cab0e893dbe5b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlup4hyZo4eCjF8T85vfRXMKBxGj9bMdl0"
+ nickname="Ben"
+ subject="comment 3"
+ date="2012-09-06T16:04:42Z"
+ content="""
+Frankly, even the --fast behavior has an element of surprise to it. For example, one might have two files with identical content. Upon annexing and unannex they suddenly become a hard link to the same file, correct? If this is the case, changes to one will result in changes to the other. I would consider this a very nasty sort of surprise.
+"""]]
diff --git a/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_4_e8a10886a564f35414c30a04335d9d32._comment b/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_4_e8a10886a564f35414c30a04335d9d32._comment
new file mode 100644
index 000000000..72b4c5c7f
--- /dev/null
+++ b/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_4_e8a10886a564f35414c30a04335d9d32._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.30"
+ subject="comment 4"
+ date="2012-09-09T16:53:35Z"
+ content="""
+Perhaps the solution is to make --fast the default and to make it copy files when the content in the annex already has a hard link to it.
+"""]]
diff --git a/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_5_6a318edfe45c80343d017dc7b4837acb._comment b/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_5_6a318edfe45c80343d017dc7b4837acb._comment
new file mode 100644
index 000000000..fbc30f17b
--- /dev/null
+++ b/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_5_6a318edfe45c80343d017dc7b4837acb._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlup4hyZo4eCjF8T85vfRXMKBxGj9bMdl0"
+ nickname="Ben"
+ subject="comment 5"
+ date="2012-09-09T20:47:04Z"
+ content="""
+That sounds far more reasonable.
+"""]]
diff --git a/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_6_f7a1d9f9d40aff531d873a95d2196edd._comment b/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_6_f7a1d9f9d40aff531d873a95d2196edd._comment
new file mode 100644
index 000000000..295411d25
--- /dev/null
+++ b/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_6_f7a1d9f9d40aff531d873a95d2196edd._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlup4hyZo4eCjF8T85vfRXMKBxGj9bMdl0"
+ nickname="Ben"
+ subject="comment 6"
+ date="2012-09-19T23:32:35Z"
+ content="""
+Has any progress been made here? While this issue may not result in data loss, the behavior documented in this bug is certainly surprising and does not instill confidence in new users.
+"""]]
diff --git a/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_7_1724ffdf986301bf37ef7a6d16b6ea8a._comment b/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_7_1724ffdf986301bf37ef7a6d16b6ea8a._comment
new file mode 100644
index 000000000..fd235321a
--- /dev/null
+++ b/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_7_1724ffdf986301bf37ef7a6d16b6ea8a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.14.141"
+ subject="comment 7"
+ date="2012-09-23T18:02:45Z"
+ content="""
+If unannex makes the file a hard link to the annexed content, it will be mode 444 or so. But if the user changes the permissions and modifys it, that will corrupt the content still in the annex!
+
+So the current --fast behavior seems no worse than the proposed behavior. And it's not at all clear to me that this would be a better default behavior for unannex than the current behavior, which at least ensures that data left in the annex (and referred to by another annexed file) cannot be corrupted.
+"""]]
diff --git a/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_8_5470e2f50e6506139ecb1b342371c509._comment b/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_8_5470e2f50e6506139ecb1b342371c509._comment
new file mode 100644
index 000000000..7ac71b6b8
--- /dev/null
+++ b/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_8_5470e2f50e6506139ecb1b342371c509._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnRai_qFYPVvEgC6i1nlM1bh-C__jbhqS0"
+ nickname="Matthew"
+ subject="comment 8"
+ date="2013-07-31T14:17:19Z"
+ content="""
+Filenames are the index which users use to find their data.
+
+Leaving a broken symlink may not result in technical data loss, but can quite possibly result in the user being unable to find the data which was referenced by that filename (symlink), so in that case that data _is_ lost, in the true sense of the word (the user cannot find it). Telling the user their data exists _somewhere_ is not actually making the situation any better.
+"""]]
diff --git a/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_9_e53148a9efa061a825f668a9492182f7._comment b/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_9_e53148a9efa061a825f668a9492182f7._comment
new file mode 100644
index 000000000..74aaa1e56
--- /dev/null
+++ b/doc/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/comment_9_e53148a9efa061a825f668a9492182f7._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/2grhJvAC049fJnvALDXek.6MRZMTlg--#eec89"
+ nickname="John"
+ subject="comment 9"
+ date="2013-08-30T05:59:28Z"
+ content="""
+I'll chime in and say that the non-fast behavior being the default seems wrong, and making hard-link invisibly seems wrong. What Joey proposed -- copying a file if there are multiple hard-links -- seems like the right solution.
+
+Just recently I tried to unannex a large repository and was bitten by now-dangling symlinks to files that I couldn't locate anymore. The fact is that the current unannex operation is too dangerous to be useful.
+"""]]
diff --git a/doc/bugs/Last_two_versions_didn__39__t_show_up_on_hackage.mdwn b/doc/bugs/Last_two_versions_didn__39__t_show_up_on_hackage.mdwn
new file mode 100644
index 000000000..f1d4ae2b2
--- /dev/null
+++ b/doc/bugs/Last_two_versions_didn__39__t_show_up_on_hackage.mdwn
@@ -0,0 +1,11 @@
+### Please describe the problem.
+I don't know how the packages at hackage are managed, but the last version there is 4.20130601 while in the mean time there have been two other releases.
+
+### What steps will reproduce the problem?
+Check [[http://hackage.haskell.org/packages/archive/git-annex/]]
+
+> Thanks for reporting. Turns out that hackage was rejecting
+> it since it doesn't know about the OS name for the hurd. Since I
+> am not sure I have the right name either, I have removed those bits
+> and re-uploaded.
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/Last_two_versions_didn__39__t_show_up_on_hackage/comment_1_74b56dea2100450e322e726bb55bb310._comment b/doc/bugs/Last_two_versions_didn__39__t_show_up_on_hackage/comment_1_74b56dea2100450e322e726bb55bb310._comment
new file mode 100644
index 000000000..bbb2231dc
--- /dev/null
+++ b/doc/bugs/Last_two_versions_didn__39__t_show_up_on_hackage/comment_1_74b56dea2100450e322e726bb55bb310._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://dzsino.myopenid.com/"
+ nickname="dzsino"
+ subject="me2"
+ date="2013-06-30T13:16:38Z"
+ content="""
+i'm using cabal on my mac to stay on the bleeding edge, but it still picks up version 0601, which it cannot install with yesod-1.1.9.3 failing to build (so it's not a git-annex problem). I hope a new release would fix that too..
+"""]]
diff --git a/doc/bugs/Linux_stand_alone_build_20130723_breaks_support_for_glibc_2.13_debian_stable.txt b/doc/bugs/Linux_stand_alone_build_20130723_breaks_support_for_glibc_2.13_debian_stable.txt
new file mode 100644
index 000000000..e4eef758a
--- /dev/null
+++ b/doc/bugs/Linux_stand_alone_build_20130723_breaks_support_for_glibc_2.13_debian_stable.txt
@@ -0,0 +1,43 @@
+### Please describe the problem.
+git-annex: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.14' not found (required by git-annex)
+git-annex: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.14' not found (required by /home/user/bin/usr/lib/x86_64-linux-gnu/libidn.so.11)
+git-annex: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.14' not found (required by /home/user/bin/usr/lib/x86_64-linux-gnu/libgnutls.so.26)
+git-annex: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.14' not found (required by /home/user/bin/usr/lib/x86_64-linux-gnu/libxml2.so.2)
+git-annex: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.15' not found (required by /home/user/bin/usr/lib/x86_64-linux-gnu/libxml2.so.2)
+git-annex: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.14' not found (required by /home/user/bin/usr/lib/x86_64-linux-gnu/libgmp.so.10)
+git-annex: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.14' not found (required by /home/user/bin/usr/lib/x86_64-linux-gnu/libffi.so.6)
+git-annex: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.14' not found (required by /home/user/bin/usr/lib/x86_64-linux-gnu/libntlm.so.0)
+git-annex: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.14' not found (required by /home/user/bin/usr/lib/x86_64-linux-gnu/libgssapi_krb5.so.2)
+git-annex: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.14' not found (required by /home/user/bin/usr/lib/x86_64-linux-gnu/libkrb5.so.3)
+git-annex: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.16' not found (required by /home/user/bin/usr/lib/x86_64-linux-gnu/libkrb5.so.3)
+git-annex: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.14' not found (required by /home/user/bin/usr/lib/x86_64-linux-gnu/libk5crypto.so.3)
+git-annex: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.17' not found (required by /home/user/bin/lib/x86_64-linux-gnu/libcom_err.so.2)
+git-annex: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.14' not found (required by /home/user/bin/lib/x86_64-linux-gnu/libgcrypt.so.11)
+git-annex: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.15' not found (required by /home/user/bin/lib/x86_64-linux-gnu/libgcrypt.so.11)
+git-annex: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.14' not found (required by /home/user/bin/usr/lib/x86_64-linux-gnu/libtasn1.so.3)
+git-annex: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.14' not found (required by /home/user/bin/usr/lib/x86_64-linux-gnu/libp11-kit.so.0)
+git-annex: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.14' not found (required by /home/user/bin/usr/lib/x86_64-linux-gnu/libstdc++.so.6)
+git-annex: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.17' not found (required by /home/user/bin/usr/lib/x86_64-linux-gnu/libstdc++.so.6)
+git-annex: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.14' not found (required by /home/user/bin/lib/x86_64-linux-gnu/libgcc_s.so.1)
+git-annex: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.14' not found (required by /home/user/bin/usr/lib/x86_64-linux-gnu/libkrb5support.so.0)
+
+### What steps will reproduce the problem?
+$git-annex
+
+### What version of git-annex are you using? On what operating system?
+v20130723, 64-bit, Debian Stable
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
+
+Also note, the last build 20130709 was compatible with glibc 2.13
+
+> [[fixed|done]]; builds are back to using debian stable.
+> also updated the autobuilds and last release's builds. --[[Joey]]
diff --git a/doc/bugs/Linux_stand_alone_build_20130723_breaks_support_for_glibc_2.13_debian_stable/comment_1_dc7f726a0b60f64392cbbd1b4317bab5._comment b/doc/bugs/Linux_stand_alone_build_20130723_breaks_support_for_glibc_2.13_debian_stable/comment_1_dc7f726a0b60f64392cbbd1b4317bab5._comment
new file mode 100644
index 000000000..f50471ca0
--- /dev/null
+++ b/doc/bugs/Linux_stand_alone_build_20130723_breaks_support_for_glibc_2.13_debian_stable/comment_1_dc7f726a0b60f64392cbbd1b4317bab5._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 1"
+ date="2013-07-25T17:00:53Z"
+ content="""
+Thank you for reminding me why I was using debian stable chroots for the autobuilds.
+
+Unfortunately, I forgot about this problem and upgraded the chroots. Rebuilding them with all the stuff I need is going to take a while.
+"""]]
diff --git a/doc/bugs/Linux_stand_alone_build_20130723_breaks_support_for_glibc_2.13_debian_stable/comment_2_4a0198d714bd3b52ba9baa68dc45f535._comment b/doc/bugs/Linux_stand_alone_build_20130723_breaks_support_for_glibc_2.13_debian_stable/comment_2_4a0198d714bd3b52ba9baa68dc45f535._comment
new file mode 100644
index 000000000..1d7685bb1
--- /dev/null
+++ b/doc/bugs/Linux_stand_alone_build_20130723_breaks_support_for_glibc_2.13_debian_stable/comment_2_4a0198d714bd3b52ba9baa68dc45f535._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://jamdev.myopenid.com/"
+ ip="117.195.168.15"
+ subject="well that was fast!"
+ date="2013-07-25T21:01:38Z"
+ content="""
+Hey Joey
+
+Confirming this as fixed, thanks.
+
+-have a nice weekend!
+"""]]
diff --git a/doc/bugs/Local_files_not_found.mdwn b/doc/bugs/Local_files_not_found.mdwn
new file mode 100644
index 000000000..b2843e35f
--- /dev/null
+++ b/doc/bugs/Local_files_not_found.mdwn
@@ -0,0 +1,50 @@
+### Please describe the problem.
+
+I have a git annex repo which cannot find the files with whereis, even though the files and contents are there. I have changed ownership of all the files. I am not sure, but I think that is when the problem was introduced. The current user that is invoking git annex owns and can access all files in the repository/annex)
+
+Creating a new repository from scratch works just fine.
+
+
+### What steps will reproduce the problem?
+
+ # (in my current, somehow corrupt annex)
+ $ echo hello > testfile
+ $ git annex add testfile
+ add testfile (checksum...) ok
+ (Recording state in git...)
+ $ git commit -am testfile
+ [master 73ed120] testfile
+ 1 file changed, 1 insertion(+)
+ create mode 120000 testfile
+ $ git annex whereis testfile
+ whereis testfile (0 copies) failed
+ git-annex: whereis: 1 failed
+
+
+ # The contents exists though
+ $ ls -l testfile
+ lrwxrwxrwx 1 ftp ftp 176 May 13 09:43 testfile -> .git/annex/objects/P5/4q/SHA256-s6--5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03/SHA256-s6--5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03
+ $ cat .git/annex/objects/P5/4q/SHA256-s6--5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03/SHA256-s6--5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03
+ hello
+ $ sha256sum testfile
+ 5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03 testfile
+
+
+ # the file can be found when unlocking/locking
+ $ git annex unlock testfile
+ unlock testfile (copying...) ok
+ $ git annex lock testfile
+ lock testfile ok
+ (Recording state in git...)
+
+### What version of git-annex are you using? On what operating system?
+I ran Debian squeeze, with git annex 3.20120629~bpo60+2 when the problem was introduced. I just upgraded to wheezy, but the same problem exists with 3.20120629 from wheezy.
+
+I also manually installed 4.20130501 from unstable, which also showed the same problem.
+
+
+### Please provide any additional information below.
+
+I am not sure what information to supply, please provide pointers on what information might be useful.
+
+> [[done]] per comment --[[Joey]]
diff --git a/doc/bugs/Local_files_not_found/comment_1_5e1fcc0597594fa493ffa28aa32e1df8._comment b/doc/bugs/Local_files_not_found/comment_1_5e1fcc0597594fa493ffa28aa32e1df8._comment
new file mode 100644
index 000000000..72ed1e42f
--- /dev/null
+++ b/doc/bugs/Local_files_not_found/comment_1_5e1fcc0597594fa493ffa28aa32e1df8._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawljcHBnBhazpDpk5k_9Wk9S_zA0hnjqdLQ"
+ nickname="Andreas"
+ subject="comment 1"
+ date="2013-05-13T08:24:50Z"
+ content="""
+Sorry for the noise - it turned out the local annex repository somehow had been marked as \"dead\" (as shown by git status).
+
+The fix was simply to git annex semitrust <repo uuid> and it went back to life.
+
+I am not sure how this bug tracker works, but this bug report can be closed as invalid. Thanks for git annex!
+"""]]
diff --git a/doc/bugs/Local_network___40__ssh__41___fails_to_pair__47__sync.mdwn b/doc/bugs/Local_network___40__ssh__41___fails_to_pair__47__sync.mdwn
new file mode 100644
index 000000000..6a66c553f
--- /dev/null
+++ b/doc/bugs/Local_network___40__ssh__41___fails_to_pair__47__sync.mdwn
@@ -0,0 +1,175 @@
+### Please describe the problem.
+I am trying to set out two computers on the same network to synchronise.
+
+### What steps will reproduce the problem?
+Install Git-Annex. Start the webapp. Try to connect. Enter a secret phrase on both. The Mythbuntu machine shows "Failed to sync with Inspiron 14z" (the laptop). The laptop shows "Pairing in progress" forever.
+
+The machines can normally connect together passwordlessly through ssh with public key encryption.
+
+### What version of git-annex are you using? On what operating system?
+Ubuntu Raring Version: 3.20121112ubuntu2 from the repos on my laptop. Install version 4.20130627 from the PPA on Mythbuntu Precise (which I use as a home server).
+
+### Please provide any additional information below.
+From the the laptop, where I started the pairing:
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+$ git-annex webapp
+
+(process:3084): GLib-CRITICAL **: g_slice_set_config: assertion `sys_page_size == 0' failed
+
+** (firefox:3084): WARNING **: Failed to find domain member of JSON manifest
+Running global cleanup code from study base classes.
+(Recording state in git...)
+
+Launching web browser on file:///tmp/webapp3075.html
+(scanning...)
+ dbus failed; falling back to mtab polling (ClientError {clientErrorMessage = "Call failed: The name org.gtk.Private.GduVolumeMonitor was not provided by any .service files", clientErrorFatal = False})
+(started...) Generating public/private rsa key pair.
+Your identification has been saved in /tmp/git-annex-keygen3075.0/key.
+Your public key has been saved in /tmp/git-annex-keygen3075.0/key.pub.
+The key fingerprint is:
+79:00:67:a4:f0:5f:62:26:78:ed:09:97:e4:c4:dd:56 aaron@Inspiron-14z
+The key's randomart image is:
++--[ RSA 2048]----+
+| . .o*. . .E |
+| + X... o |
+| . * X .. |
+| . O * |
+| S . |
+| . |
+| |
+| |
+| |
++-----------------+
+Control socket connect(/home/shared/annex/.git/annex/ssh/mythbuntu@git-annex-mythbuntu-server.local-mythbuntu): Connection refused
+Failed to connect to new control master
+warning: no common commits
+
+ Remote mythbuntuserver.local_annex does not have git-annex installed; setting remote.mythbuntuserver.local_annex.annex-ignore
+Already up-to-date.
+Counting objects: 13, done.
+Delta compression using up to 4 threads.
+Compressing objects: 100% (9/9), done.
+Writing objects: 100% (11/11), 1.06 KiB, done.
+Total 11 (delta 2), reused 0 (delta 0)
+To ssh://mythbuntu@git-annex-mythbuntu-server.local-mythbuntu/~/annex/
+ * [new branch] git-annex -> synced/git-annex
+ * [new branch] master -> synced/master
+Already up-to-date!
+Merge made by the 'recursive' strategy.
+Already up-to-date.
+Already up-to-date.
+Counting objects: 2, done.
+Delta compression using up to 4 threads.
+Compressing objects: 100% (2/2), done.
+Writing objects: 100% (2/2), 326 bytes, done.
+Total 2 (delta 1), reused 0 (delta 0)
+To ssh://mythbuntu@git-annex-mythbuntu-server.local-mythbuntu/~/annex/
+ 82bf946..dfe0bd1 master -> synced/master
+Already up-to-date.
+SendMessage (77594660, 0x101f, (nil), (nil))
+SendMessage (0, 0x1203, (nil), 0x7fffc68a1850)
+SendMessage (0, 0x1204, (nil), 0x7fffc68a1850)
+SendMessage (0, 0x1203, 0x1, 0x7fffc68a1850)
+SendMessage (0, 0x1204, 0x1, 0x7fffc68a1850)
+SendMessage (0, 0x1203, 0x2, 0x7fffc68a1850)
+SendMessage (0, 0x1204, 0x2, 0x7fffc68a1850)
+SendMessage (0, 0x1203, 0x3, 0x7fffc68a1850)
+SendMessage (0, 0x1204, 0x3, 0x7fffc68a1850)
+SendMessage (0, 0x1203, 0x4, 0x7fffc68a1850)
+SendMessage (0, 0x1204, 0x4, 0x7fffc68a1850)
+SendMessage (77594660, 0x101f, (nil), (nil))
+SendMessage (0, 0x1203, (nil), 0x7fffc68a1810)
+SendMessage (0, 0x1204, (nil), 0x7fffc68a1810)
+SendMessage (0, 0x1203, 0x1, 0x7fffc68a1810)
+SendMessage (0, 0x1204, 0x1, 0x7fffc68a1810)
+SendMessage (0, 0x1203, 0x2, 0x7fffc68a1810)
+SendMessage (0, 0x1204, 0x2, 0x7fffc68a1810)
+SendMessage (0, 0x1203, 0x3, 0x7fffc68a1810)
+SendMessage (0, 0x1204, 0x3, 0x7fffc68a1810)
+SendMessage (0, 0x1203, 0x4, 0x7fffc68a1810)
+SendMessage (0, 0x1204, 0x4, 0x7fffc68a1810)
+SendMessage (77594660, 0x101f, (nil), (nil))
+SendMessage (0, 0x1203, (nil), 0x7fffc68a2920)
+SendMessage (0, 0x1204, (nil), 0x7fffc68a2920)
+SendMessage (0, 0x1203, 0x1, 0x7fffc68a2920)
+SendMessage (0, 0x1204, 0x1, 0x7fffc68a2920)
+SendMessage (0, 0x1203, 0x2, 0x7fffc68a2920)
+SendMessage (0, 0x1204, 0x2, 0x7fffc68a2920)
+SendMessage (0, 0x1203, 0x3, 0x7fffc68a2920)
+SendMessage (0, 0x1204, 0x3, 0x7fffc68a2920)
+SendMessage (0, 0x1203, 0x4, 0x7fffc68a2920)
+SendMessage (0, 0x1204, 0x4, 0x7fffc68a2920)
+Redirection loop trying to set HTTPS on:
+ http://www.aol.com/favicon.ico
+(falling back to HTTP)
+SendMessage (77594652, 0x444, 0x1, 0x3652e00)
+SendMessage (77594652, 0x444, 0x1, 0x3647de0)
+SendMessage (77594652, 0x444, 0x1, 0x3667a80)
+SendMessage (77594652, 0x444, 0x1, 0x3667a80)
+
+# End of transcript or log.
+# End of transcript or log.
+"""]]
+
+On the Mythbuntu machine:
+[[!format sh """
+$ git-annex webapp
+Launching web browser on file:///tmp/webapp8399.html
+(Recording state in git...)
+"""]]
+
+Unless I'm going mad, there doesn't seem to be a daemon.log on my laptop.
+
+Daemon.log on the Mythbuntu machine:
+[[!format sh """
+[2013-07-14 10:38:56 BST] main: starting assistant version 4.20130627
+(scanning...) [2013-07-14 10:38:56 BST] Watcher: Performing startup scan
+(started...) [2013-07-14 10:38:57 BST] PairListener: aaron@Inspiron-14z:/home/shared/annex is sending a pair request.
+Generating public/private rsa key pair.
+Your identification has been saved in /tmp/git-annex-keygen.0/key.
+Your public key has been saved in /tmp/git-annex-keygen.0/key.pub.
+The key fingerprint is:
+bb:8c:66:05:22:8e:fa:e1:10:33:6d:cb:d6:57:e2:47 mythbuntu@mythbuntu-server
+The key's randomart image is:
++--[ RSA 2048]----+
+| |
+| |
+| |
+| .. . . |
+|+oo. ...E |
+|.*.o . +.. |
+|o = . o.o |
+|.+ . .o+ . |
+| .o o. o |
++-----------------+
+[2013-07-14 10:39:13 BST] main: Pairing with aaron@Inspiron-14z:/home/shared/annex in progress
+ssh: connect to host Inspiron-14z.local port 22: Connection refused
+ssh: connect to host Inspiron-14z.local port 22: Connection refused
+fatal: The remote end hung up unexpectedly
+[2013-07-14 10:39:17 BST] PairListener: Syncing with Inspiron14z.local__home_shared_annex
+ssh: connect to host Inspiron-14z.local port 22: Connection refused
+fatal: The remote end hung up unexpectedly
+ssh: connect to host Inspiron-14z.local port 22: Connection refused
+fatal: The remote end hung up unexpectedly
+ssh: connect to host Inspiron-14z.local port 22: Connection refused
+fatal: The remote end hung up unexpectedly
+Already up-to-date.
+Already up-to-date.
+ssh: connect to host Inspiron-14z.local port 22: Connection refused
+fatal: The remote end hung up unexpectedly
+ssh: connect to host Inspiron-14z.local port 22: Connection refused
+fatal: The remote end hung up unexpectedly
+Updating 82bf946..dfe0bd1
+Fast-forward
+[2013-07-14 10:39:56 BST] Pusher: Syncing with Inspiron14z.local__home_shared_annex
+ssh: connect to host Inspiron-14z.local port 22: Connection refused
+fatal: The remote end hung up unexpectedly
+ssh: connect to host Inspiron-14z.local port 22: Connection refused
+fatal: The remote end hung up unexpectedly
+ssh: connect to host Inspiron-14z.local port 22: Connection refused
+fatal: The remote end hung up unexpectedly
+ssh: connect to host Inspiron-14z.local port 22: Connection refused
+fatal: The remote end hung up unexpectedly
+"""]]
diff --git a/doc/bugs/Local_network___40__ssh__41___fails_to_pair__47__sync/comment_1_bab9cd5bdcffec3c48b9e8657cd9bbf7._comment b/doc/bugs/Local_network___40__ssh__41___fails_to_pair__47__sync/comment_1_bab9cd5bdcffec3c48b9e8657cd9bbf7._comment
new file mode 100644
index 000000000..272cf2684
--- /dev/null
+++ b/doc/bugs/Local_network___40__ssh__41___fails_to_pair__47__sync/comment_1_bab9cd5bdcffec3c48b9e8657cd9bbf7._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnFjuvfPpi1kf6l54bxfFUm0Aw_Gf_IO0o"
+ nickname="Aaron"
+ subject="Some things working"
+ date="2013-07-14T10:06:13Z"
+ content="""
+Oh, that's odd...
+
+The Mythbuntu machine says it fails and the laptop screen still says pairing, but a new window on the laptop says that it synced with the Mythbuntu server. On the Mythbuntu server, it has a blank entry for the laptop, which if you click to edit says \"Internal Server Error\" \"Unknown UUID\".
+
+When I add things on the laptop, they immediately become shortcuts and an equivalent shortcut appears on the Mythbuntu machine, though updates to the content (in this case a text file) are not sychronised.
+
+Adding a file on the Mythbuntu machine does not turn into a shortcut and nothing appears on the laptop.
+"""]]
diff --git a/doc/bugs/Local_network___40__ssh__41___fails_to_pair__47__sync/comment_2_104898dce3c67c082a9f2b36e2f45ff8._comment b/doc/bugs/Local_network___40__ssh__41___fails_to_pair__47__sync/comment_2_104898dce3c67c082a9f2b36e2f45ff8._comment
new file mode 100644
index 000000000..09d7a6d59
--- /dev/null
+++ b/doc/bugs/Local_network___40__ssh__41___fails_to_pair__47__sync/comment_2_104898dce3c67c082a9f2b36e2f45ff8._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.110"
+ subject="comment 2"
+ date="2013-07-28T00:27:23Z"
+ content="""
+Remote mythbuntuserver.local_annex does not have git-annex installed; setting remote.mythbuntuserver.local_annex.annex-ignore
+
+So, how did you install git-annex on mythbuntuserver? What does the `.ssh/authorized_keys` on mythbuntuserver look like? (In particular the key that git-annex adds to it, which should be set to run git-annex-shell.)
+"""]]
diff --git a/doc/bugs/Local_pairing_fails:_PairListener_crashed.mdwn b/doc/bugs/Local_pairing_fails:_PairListener_crashed.mdwn
new file mode 100644
index 000000000..371b923cf
--- /dev/null
+++ b/doc/bugs/Local_pairing_fails:_PairListener_crashed.mdwn
@@ -0,0 +1,18 @@
+What steps will reproduce the problem?
+
+Attempting to pair between a local repository and a repository on a remote computer on my LAN. Pairing is initiated from my local machine and I'm interacting with the webapp on the remote machine via firefox running over an ssh -X connection. Pairing appears to work up to a point: I enter the secret at one end, the pairing request shows up at the other end. I then enter the secret at that end.
+
+What is the expected output? What do you see instead?
+
+Pairing should complete successfully. Instead I get the error message "PairListener crashed: bad comment in public key", followed by the public key. The pairing process then does not move beyond the 'awaiting pairing' pages.
+
+What version of git-annex are you using? On what operating system?
+
+Local Machine: 3.20121127, Debian Wheezy/Sid (the only package from unstable is git-annex).
+Remote Machine: 3.20121113, Arch Linux (I installed the version from: https://aur.archlinux.org/packages/git-annex-bin/, which is supposedly the same as above, but reports the version specified here).
+
+Please provide any additional information below.
+
+None as yet. Let me know if there are any log files, etc. that I can post.
+
+> So it was the period in the hostname! [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/Local_pairing_fails:_PairListener_crashed/comment_1_d9c5d2147cf6d8d8477eb13b72081d46._comment b/doc/bugs/Local_pairing_fails:_PairListener_crashed/comment_1_d9c5d2147cf6d8d8477eb13b72081d46._comment
new file mode 100644
index 000000000..4dd77f04d
--- /dev/null
+++ b/doc/bugs/Local_pairing_fails:_PairListener_crashed/comment_1_d9c5d2147cf6d8d8477eb13b72081d46._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.72"
+ subject="comment 1"
+ date="2012-12-04T17:38:47Z"
+ content="""
+On the machine that didn't crash, run:
+
+ssh-keygen -P \"\" -f test; cat test.pub
+
+Probably the non-alphanumeric character is part of the machine's hostname, or perhaps your username. We'll see..
+"""]]
diff --git a/doc/bugs/Local_pairing_fails:_PairListener_crashed/comment_2_60a21105145ac228f486bc4beb2ea54d._comment b/doc/bugs/Local_pairing_fails:_PairListener_crashed/comment_2_60a21105145ac228f486bc4beb2ea54d._comment
new file mode 100644
index 000000000..851dfe9f8
--- /dev/null
+++ b/doc/bugs/Local_pairing_fails:_PairListener_crashed/comment_2_60a21105145ac228f486bc4beb2ea54d._comment
@@ -0,0 +1,32 @@
+[[!comment format=mdwn
+ username="robconnolly"
+ ip="118.90.115.19"
+ subject="comment 2"
+ date="2012-12-06T02:29:56Z"
+ content="""
+Hi Joey,
+
+Thanks for your response. Here is the output:
+
+[robert@laforge ~]$ ssh-keygen -P \"\" -f test; cat test.pub
+Generating public/private rsa key pair.
+Your identification has been saved in test.
+Your public key has been saved in test.pub.
+The key fingerprint is:
+84:43:aa:f0:ba:a7:f0:11:41:55:3b:c4:63:6a:71:e1 robert@laforge.enterprise
+The key's randomart image is:
++--[ RSA 2048]----+
+| ...o=. |
+| . .==o |
+|. . .=E.. |
+| o oo + |
+| +. S |
+| . . |
+|o . |
+|.o.. |
+|oo. |
++-----------------+
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDIeitbarby1thLPEyVpeT/vDaWt0MJwLPvhT7TEZv0FedYalvz/mm3enULHiYdxkjWGBaO/EEzfmz5bjhoJx2tsqSLsUj/UZVv0LxsSfZwTrk0SPuUerzWvAJAXKvtPobDXJoAxsNvzSJN392BMOLKqcjAQTqPA3vd5+EjUVIgJxguz5poGrP0ZRMQD5LmsDrPGUWNJ/EHaVkrqGobAE4DVr8vhJTY41h5Gk2ipnzx+GD6CDZTSNFwl8RorjFAV3mYTTjHc2Cz7GxTLSmwF0+qFZ/UkiO2tD1M37Y4/cPLY7GpVfKvpPHTC8pJUpvj+B4uujHxvZkBJLLz9XhH9KsZ robert@laforge.enterprise
+
+Let me know if you need any more info.
+"""]]
diff --git a/doc/bugs/Local_pairing_fails:_received_PairMsg_loop.mdwn b/doc/bugs/Local_pairing_fails:_received_PairMsg_loop.mdwn
new file mode 100644
index 000000000..63f423e2c
--- /dev/null
+++ b/doc/bugs/Local_pairing_fails:_received_PairMsg_loop.mdwn
@@ -0,0 +1,39 @@
+### Please describe the problem.
+Pairing over my local network doesn't work. The pairing process never finishes. The log shows that the same PairMsg messages are repeated endlessly.
+
+### What steps will reproduce the problem?
+
+
+### What version of git-annex are you using? On what operating system?
+I'm on Ubuntu Raring 13.04. I installed git-annex 4.20131024 from the Precise PPA. It is working fine with a remote ssh repo, just not local pairing.
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+[2013-11-01 16:55:21 CDT] main: Pairing in progress
+[2013-11-01 16:55:55 CDT] PairListener: received "PairMsg (Verifiable {verifiableVal = (PairReq,PairData {remoteHostName = Just \"Onyx\", remoteUserName = \"me\", remoteDirectory = \"~/annex\", remoteSshPubKey = \"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDBT0Y6TTzTg8nWwonmgUPPwJmPIaJzfEoJl8DbuylpgXqGCQ4doJXuvBODHIehPfyMr1xCWqNlNNLkcWg/a/eHFceyt3IlcD9XaZ1aKPzPmpjYKKf5amiYd6mAssw8zFaZUvwaXkNuHZpXVZyg6C6TkT6kdfln+6fOJZpSGQzksy0jka/Rzx0KXjsp3oqO4tQJbC7AX0nvmD0zvLtyCURzfGV+n2IqQxpPf2nP75Evt8jamcuqm6pWoe+hj9zjGytIXpSKe35wzRwUAUrjgmZ9NweuWfi2uMPJlDv8/n+Q3HyjygA+GzixBGuYXDt1CD8ISZvuoygS+9+jeY9uYH8b me@Onyx\\n\", pairUUID = UUID \"834b4f39-ca66-4baf-9323-57ef7058d7d0\"},IPv4Addr 2281744576), verifiableDigest = \"8d5d380542f7377f09a4584a38b0dbcea9ea215c\"})"
+[2013-11-01 16:55:56 CDT] PairListener: received "PairMsg (Verifiable {verifiableVal = (PairReq,PairData {remoteHostName = Just \"kubbie\", remoteUserName = \"me\", remoteDirectory = \"~/annex\", remoteSshPubKey = \"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCvBEWT+AiAmehOFyTQWlSdwDs7DDbkw7rfZ4W/IeG5awZjMgT5BefIv9cmar8vGIIEFMZLpf8cL3xIargDz0xE2wuqj5CLkdz+DKp5f2FGs11Ax/62DZr+eCiVtPnwijFw0Cz0wMRzkN93uedrvzP/KkNRcczgWh3aZqn8WxlkCia1fyykm/pP3W80MNkiJYX5vXpu1NCV5KLu+UXQzKhM2njOauJ3W5wsMvSl8faZIpEmKVCD3BMDDruxTIxggA3kt9GCGvIbPawy+fGOpp/j6pHqnX3GB2kkT47RIZKYEv99HuLyvea+oY5R11FsC2yYY3ujIdUU0fXnV8pvrqSv me@kubbie\\n\", pairUUID = UUID \"fd6a6858-76c9-4eea-b733-9359c7313e72\"},IPv4Addr 1879091392), verifiableDigest = \"cbd8197c3d78c8c68bb30f63aa974cd88dd0fb13\"})"
+[2013-11-01 16:55:57 CDT] PairListener: received "PairMsg (Verifiable {verifiableVal = (PairReq,PairData {remoteHostName = Just \"Onyx\", remoteUserName = \"me\", remoteDirectory = \"~/annex\", remoteSshPubKey = \"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDBT0Y6TTzTg8nWwonmgUPPwJmPIaJzfEoJl8DbuylpgXqGCQ4doJXuvBODHIehPfyMr1xCWqNlNNLkcWg/a/eHFceyt3IlcD9XaZ1aKPzPmpjYKKf5amiYd6mAssw8zFaZUvwaXkNuHZpXVZyg6C6TkT6kdfln+6fOJZpSGQzksy0jka/Rzx0KXjsp3oqO4tQJbC7AX0nvmD0zvLtyCURzfGV+n2IqQxpPf2nP75Evt8jamcuqm6pWoe+hj9zjGytIXpSKe35wzRwUAUrjgmZ9NweuWfi2uMPJlDv8/n+Q3HyjygA+GzixBGuYXDt1CD8ISZvuoygS+9+jeY9uYH8b me@Onyx\\n\", pairUUID = UUID \"834b4f39-ca66-4baf-9323-57ef7058d7d0\"},IPv4Addr 2281744576), verifiableDigest = \"8d5d380542f7377f09a4584a38b0dbcea9ea215c\"})"
+[2013-11-01 16:55:58 CDT] PairListener: received "PairMsg (Verifiable {verifiableVal = (PairReq,PairData {remoteHostName = Just \"kubbie\", remoteUserName = \"me\", remoteDirectory = \"~/annex\", remoteSshPubKey = \"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCvBEWT+AiAmehOFyTQWlSdwDs7DDbkw7rfZ4W/IeG5awZjMgT5BefIv9cmar8vGIIEFMZLpf8cL3xIargDz0xE2wuqj5CLkdz+DKp5f2FGs11Ax/62DZr+eCiVtPnwijFw0Cz0wMRzkN93uedrvzP/KkNRcczgWh3aZqn8WxlkCia1fyykm/pP3W80MNkiJYX5vXpu1NCV5KLu+UXQzKhM2njOauJ3W5wsMvSl8faZIpEmKVCD3BMDDruxTIxggA3kt9GCGvIbPawy+fGOpp/j6pHqnX3GB2kkT47RIZKYEv99HuLyvea+oY5R11FsC2yYY3ujIdUU0fXnV8pvrqSv me@kubbie\\n\", pairUUID = UUID \"fd6a6858-76c9-4eea-b733-9359c7313e72\"},IPv4Addr 1879091392), verifiableDigest = \"cbd8197c3d78c8c68bb30f63aa974cd88dd0fb13\"})"
+[2013-11-01 16:55:59 CDT] PairListener: received "PairMsg (Verifiable {verifiableVal = (PairReq,PairData {remoteHostName = Just \"Onyx\", remoteUserName = \"me\", remoteDirectory = \"~/annex\", remoteSshPubKey = \"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDBT0Y6TTzTg8nWwonmgUPPwJmPIaJzfEoJl8DbuylpgXqGCQ4doJXuvBODHIehPfyMr1xCWqNlNNLkcWg/a/eHFceyt3IlcD9XaZ1aKPzPmpjYKKf5amiYd6mAssw8zFaZUvwaXkNuHZpXVZyg6C6TkT6kdfln+6fOJZpSGQzksy0jka/Rzx0KXjsp3oqO4tQJbC7AX0nvmD0zvLtyCURzfGV+n2IqQxpPf2nP75Evt8jamcuqm6pWoe+hj9zjGytIXpSKe35wzRwUAUrjgmZ9NweuWfi2uMPJlDv8/n+Q3HyjygA+GzixBGuYXDt1CD8ISZvuoygS+9+jeY9uYH8b me@Onyx\\n\", pairUUID = UUID \"834b4f39-ca66-4baf-9323-57ef7058d7d0\"},IPv4Addr 2281744576), verifiableDigest = \"8d5d380542f7377f09a4584a38b0dbcea9ea215c\"})"
+[2013-11-01 16:56:00 CDT] PairListener: received "PairMsg (Verifiable {verifiableVal = (PairReq,PairData {remoteHostName = Just \"kubbie\", remoteUserName = \"me\", remoteDirectory = \"~/annex\", remoteSshPubKey = \"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCvBEWT+AiAmehOFyTQWlSdwDs7DDbkw7rfZ4W/IeG5awZjMgT5BefIv9cmar8vGIIEFMZLpf8cL3xIargDz0xE2wuqj5CLkdz+DKp5f2FGs11Ax/62DZr+eCiVtPnwijFw0Cz0wMRzkN93uedrvzP/KkNRcczgWh3aZqn8WxlkCia1fyykm/pP3W80MNkiJYX5vXpu1NCV5KLu+UXQzKhM2njOauJ3W5wsMvSl8faZIpEmKVCD3BMDDruxTIxggA3kt9GCGvIbPawy+fGOpp/j6pHqnX3GB2kkT47RIZKYEv99HuLyvea+oY5R11FsC2yYY3ujIdUU0fXnV8pvrqSv me@kubbie\\n\", pairUUID = UUID \"fd6a6858-76c9-4eea-b733-9359c7313e72\"},IPv4Addr 1879091392), verifiableDigest = \"cbd8197c3d78c8c68bb30f63aa974cd88dd0fb13\"})"
+[2013-11-01 16:56:01 CDT] PairListener: received "PairMsg (Verifiable {verifiableVal = (PairReq,PairData {remoteHostName = Just \"Onyx\", remoteUserName = \"me\", remoteDirectory = \"~/annex\", remoteSshPubKey = \"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDBT0Y6TTzTg8nWwonmgUPPwJmPIaJzfEoJl8DbuylpgXqGCQ4doJXuvBODHIehPfyMr1xCWqNlNNLkcWg/a/eHFceyt3IlcD9XaZ1aKPzPmpjYKKf5amiYd6mAssw8zFaZUvwaXkNuHZpXVZyg6C6TkT6kdfln+6fOJZpSGQzksy0jka/Rzx0KXjsp3oqO4tQJbC7AX0nvmD0zvLtyCURzfGV+n2IqQxpPf2nP75Evt8jamcuqm6pWoe+hj9zjGytIXpSKe35wzRwUAUrjgmZ9NweuWfi2uMPJlDv8/n+Q3HyjygA+GzixBGuYXDt1CD8ISZvuoygS+9+jeY9uYH8b me@Onyx\\n\", pairUUID = UUID \"834b4f39-ca66-4baf-9323-57ef7058d7d0\"},IPv4Addr 2281744576), verifiableDigest = \"8d5d380542f7377f09a4584a38b0dbcea9ea215c\"})"
+...and so on and so on...
+# End of transcript or log.
+"""]]
+
+> I was able to reproduce something very like this by starting
+> pairing separately on both computers under poor network conditions (ie,
+> weak wifi on my front porch).
+>
+> So, I've made a new PairReq message that has not been seen before
+> always make the alert pop up, even if the assistant thinks it is
+> in the middle of its own pairing process (or even another pairing process
+> with a different box on the LAN).
+>
+> (This shouldn't cause a rogue PairAck to disrupt a pairing process part
+> way through.)
+>
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/Local_pairing_fails:_received_PairMsg_loop/comment_1_b8c485bafd98be8c21595597af361255._comment b/doc/bugs/Local_pairing_fails:_received_PairMsg_loop/comment_1_b8c485bafd98be8c21595597af361255._comment
new file mode 100644
index 000000000..39587ee90
--- /dev/null
+++ b/doc/bugs/Local_pairing_fails:_received_PairMsg_loop/comment_1_b8c485bafd98be8c21595597af361255._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmNu4V5fvpLlBhaCUfXXOB0MI5NXwh8SkU"
+ nickname="Adam"
+ subject="comment 1"
+ date="2013-11-01T23:10:12Z"
+ content="""
+Also, when I initiate the pairing process on one computer only, I can see the PairMsg being constantly received in the other computer's log, but the prompt to finish pairing never appears.
+"""]]
diff --git a/doc/bugs/Local_pairing_fails:_received_PairMsg_loop/comment_2_bc63489334f44a423645021415ffe196._comment b/doc/bugs/Local_pairing_fails:_received_PairMsg_loop/comment_2_bc63489334f44a423645021415ffe196._comment
new file mode 100644
index 000000000..f10b16f3c
--- /dev/null
+++ b/doc/bugs/Local_pairing_fails:_received_PairMsg_loop/comment_2_bc63489334f44a423645021415ffe196._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmNu4V5fvpLlBhaCUfXXOB0MI5NXwh8SkU"
+ nickname="Adam"
+ subject="comment 2"
+ date="2013-11-01T23:27:24Z"
+ content="""
+Well I installed the 1 Nov release from the tarball and then it picked up the pair request from the other system. I don't know if it was a bug in the previous version or something to do with the PPA. It's weird that the assistant just wasn't doing anything about the pair request it received.
+
+Thanks for your work on git-annex assistant.
+"""]]
diff --git a/doc/bugs/Local_pairing_fails:_received_PairMsg_loop/comment_3_6345b174d04b6613c2c55a6ec9e50c21._comment b/doc/bugs/Local_pairing_fails:_received_PairMsg_loop/comment_3_6345b174d04b6613c2c55a6ec9e50c21._comment
new file mode 100644
index 000000000..a7eff6744
--- /dev/null
+++ b/doc/bugs/Local_pairing_fails:_received_PairMsg_loop/comment_3_6345b174d04b6613c2c55a6ec9e50c21._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 3"
+ date="2013-11-02T19:02:55Z"
+ content="""
+There is something a little strange in the logs. It shows both Onyx and kubbie are sending PairReqs. Probably one of those is the local computer, logging its own broadcast messages which loop back to it. But normally in pairing, one side starts the pairing process with a PairReq, and the other side pops up an alert and continues the process with a PairAck. It's not normal for both sides to request that pairing start.
+
+Is it possible that you started pairing on both computers separately?
+
+I tried doing that with gnu and darkstar. First I started pairing on gnu. darkstar saw the pair request, but I ignored the alert message about that, and went and started a separate pairing process on darkstar. gnu never showed an alert message for that; it ignored darkstar's PairReqs since it was sending its own.
+
+It's unlikely you'd ignore the alert, but the same thing could happen if the two computers were not able to communicate over the network initially, and pairing were started on both separately. So neither gets a chance to see the other's PairReq and show the alert. Even when they came into communication, they'd each ignore the other's PairReq.
+
+So, that seems like a bug..
+"""]]
diff --git a/doc/bugs/Local_pairing_fails:_received_PairMsg_loop/comment_4_f39ec6c3d5a016b3c5260162c0b42177._comment b/doc/bugs/Local_pairing_fails:_received_PairMsg_loop/comment_4_f39ec6c3d5a016b3c5260162c0b42177._comment
new file mode 100644
index 000000000..cacbad03f
--- /dev/null
+++ b/doc/bugs/Local_pairing_fails:_received_PairMsg_loop/comment_4_f39ec6c3d5a016b3c5260162c0b42177._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmNu4V5fvpLlBhaCUfXXOB0MI5NXwh8SkU"
+ nickname="Adam"
+ subject="comment 4"
+ date="2013-11-02T22:52:31Z"
+ content="""
+I did indeed try to pair from both systems. What happened was, after I started the pair request, I went to the other system, and there was no pair request listed. So I misunderstood the directions and thought I was supposed to go ahead and enter the same password into the other system. (It says that pairing will complete as soon as the password is entered on the other system, so it seems reasonable to try that.) Then both systems were constantly issuing pair requests, but neither system was responding to the requests, even though it was receiving them.
+
+Both systems were always on the network and always able to communicate over it. The bug went away when I upgraded to the 1 Nov release...but then I had some very confusing issues with partially-paired repos from different git-annex versions...I ended up having to start git-annex over from scratch on both systems with the 1 Nov build.
+
+So I'm not sure where to go from here with this bug. Thanks for your help.
+"""]]
diff --git a/doc/bugs/Local_pairing_fails:_received_PairMsg_loop/comment_5_ca0c5ef6e6a6d2c4b64430ac68370b6a._comment b/doc/bugs/Local_pairing_fails:_received_PairMsg_loop/comment_5_ca0c5ef6e6a6d2c4b64430ac68370b6a._comment
new file mode 100644
index 000000000..413ca952e
--- /dev/null
+++ b/doc/bugs/Local_pairing_fails:_received_PairMsg_loop/comment_5_ca0c5ef6e6a6d2c4b64430ac68370b6a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmNu4V5fvpLlBhaCUfXXOB0MI5NXwh8SkU"
+ nickname="Adam"
+ subject="comment 5"
+ date="2013-11-02T22:55:42Z"
+ content="""
+Oh, now I see your comment up there that you fixed it. Awesome. :)
+"""]]
diff --git a/doc/bugs/Lost_S3_Remote.mdwn b/doc/bugs/Lost_S3_Remote.mdwn
new file mode 100644
index 000000000..c359b5210
--- /dev/null
+++ b/doc/bugs/Lost_S3_Remote.mdwn
@@ -0,0 +1,59 @@
+Somehow I've lost my S3 remote... git-annex knows it's there, but its not associating it with the git remote in .git/config
+
+ $ git-annex whereis pebuilder.iso
+ whereis pebuilder.iso (3 copies)
+ 3b6fc6f6-3025-11e1-b496-33bffbc0f3ed -- housebackup (external seagate drive on /mnt/back/RemoteStore)
+ 6b1326d8-2abb-11e1-8f43-979159a7f900 -- synology
+ 9b297772-2ab2-11e1-a86f-2fd669cb2417 -- Amazon S3
+ ok
+
+Amazon S3 is the description from the remote. My .git/config file contains this block:
+
+ [remote "cloud"]
+ annex-s3 = true
+ annex-uuid = 9b297772-2ab2-11e1-a86f-2fd669cb2417
+ annex-cost = 70
+
+The UUID matches... But I cannot access it... see below:
+
+ [39532:39531 - 0:626] 08:20:38 [vivitron@tronlap:o +3] ~/annex/ISO
+ $ git-annex get pebuilder.iso --from=cloud
+ git-annex: there is no git remote named "cloud"
+
+ [39532:39531 - 0:627] 08:20:56 [vivitron@tronlap:o +3] ~/annex/ISO
+ $ git-annex get pebuilder.iso --from="Amazon S3"
+ git-annex: there is no git remote named "Amazon S3"
+
+ [39532:39531 - 0:628] 08:21:01 [vivitron@tronlap:o +3] ~/annex/ISO
+ $ git-annex get pebuilder.iso --from=9b297772-2ab2-11e1-a86f-2fd669cb2417
+ git-annex: there is no git remote named "9b297772-2ab2-11e1-a86f-2fd669cb2417"
+
+ [39532:39531 - 0:629] 08:21:08 [vivitron@tronlap:o +3] ~/annex/ISO
+ $
+
+git remote lists "cloud" as a remote:
+
+ $ git remote
+ all
+ cloud
+ cs
+ es3
+ origin
+
+git-annex status lists S3 support:
+
+ $ git-annex status
+ supported backends: SHA256 SHA1 SHA512 SHA224 SHA384 SHA256E SHA1E SHA512E SHA224E SHA384E WORM URL
+ supported remote types: git S3 bup directory rsync web hook
+
+
+
+I appreciate any help.... I've tested versions 3.20111211, 3.20111231, and 3.20120105
+
+ $ git --version
+ git version 1.7.8.1
+
+
+
+> [[done]]; I've fixed the build system so this confusing thing cannot
+> happen anymore. --[[Joey]]
diff --git a/doc/bugs/Lost_S3_Remote/comment_1_6e80e6db6671581d471fc9a54181c04c._comment b/doc/bugs/Lost_S3_Remote/comment_1_6e80e6db6671581d471fc9a54181c04c._comment
new file mode 100644
index 000000000..d6595ad5b
--- /dev/null
+++ b/doc/bugs/Lost_S3_Remote/comment_1_6e80e6db6671581d471fc9a54181c04c._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2012-01-06T03:04:35Z"
+ content="""
+Despite `status` listing S3 support, your git-annex is actually built with S3stub, probably because it failed to find the necessary S3 module at build time. Rebuild git-annex and watch closely, you'll see \"** building without S3 support\". Look above that for the error and fix it.
+
+It was certainly a bug that it showed S3 as supported when built without it. I've fixed that.
+"""]]
diff --git a/doc/bugs/Lost_S3_Remote/comment_2_c99c65882a3924f4890e500f9492b442._comment b/doc/bugs/Lost_S3_Remote/comment_2_c99c65882a3924f4890e500f9492b442._comment
new file mode 100644
index 000000000..6112bc089
--- /dev/null
+++ b/doc/bugs/Lost_S3_Remote/comment_2_c99c65882a3924f4890e500f9492b442._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 2"
+ date="2012-01-06T03:08:28Z"
+ content="""
+BTW, you'll want to \"make clean\", since the S3stub hack symlinks a file into place and it will continue building with S3stub even if you fix the problem until you clean.
+"""]]
diff --git a/doc/bugs/Lost_S3_Remote/comment_3_1e434d5a20a692cd9dc7f6f8f20f30dd._comment b/doc/bugs/Lost_S3_Remote/comment_3_1e434d5a20a692cd9dc7f6f8f20f30dd._comment
new file mode 100644
index 000000000..69063966c
--- /dev/null
+++ b/doc/bugs/Lost_S3_Remote/comment_3_1e434d5a20a692cd9dc7f6f8f20f30dd._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkey8WuXUh_x5JC2c9_it1CYRnVTgdGu1M"
+ nickname="Dustin"
+ subject="Thank you!"
+ date="2012-01-06T03:38:27Z"
+ content="""
+make clean and rebuild worked... Thank you
+"""]]
diff --git a/doc/bugs/Mac_OS_10.9_GPG_erro_when_creating_USB_repo___40__solved__41__.mdwn b/doc/bugs/Mac_OS_10.9_GPG_erro_when_creating_USB_repo___40__solved__41__.mdwn
new file mode 100644
index 000000000..2875e63e4
--- /dev/null
+++ b/doc/bugs/Mac_OS_10.9_GPG_erro_when_creating_USB_repo___40__solved__41__.mdwn
@@ -0,0 +1,23 @@
+### Please describe the problem.
+
+Creating a USB repo fails with a GPG error.
+
+### What steps will reproduce the problem?
+
+ * Build git-annex and git-annex assistant using the instructions at https://gist.github.com/calmyournerves/7144127
+ * Run git-annex app to launch web interface
+ * Create local repo using web interface
+ * Try to create USB repo using web interface
+
+### What version of git-annex are you using? On what operating system?
+
+git-annex version 4.20131105-g136b030 on Mac OS 10.9 Mavericks.
+
+### Please provide any additional information below.
+
+[[!format sh """
+07/Nov/2013:06:51:07 +1100 [Error#yesod-core] user error (gpg ["--batch","--no-tty","--use-agent","--quiet","--trust-model","always","--with-colons","--list-secret-keys","--fixed-list-mode"] exited 5) @(yesod-core-1.2.4.5:Yesod.Core.Class.Yesod ./Yesod/Core/Class/Yesod.hs:485:5)
+"""]]
+
+> [[fixed|done]]; it seems that this was a local build issue ad does not
+> affect the autobuild. --[[Joey]]
diff --git a/doc/bugs/Mac_OS_10.9_GPG_erro_when_creating_USB_repo___40__solved__41__/comment_1_0b4dcedc58e5071733e1239490aed2ea._comment b/doc/bugs/Mac_OS_10.9_GPG_erro_when_creating_USB_repo___40__solved__41__/comment_1_0b4dcedc58e5071733e1239490aed2ea._comment
new file mode 100644
index 000000000..34d8d94b1
--- /dev/null
+++ b/doc/bugs/Mac_OS_10.9_GPG_erro_when_creating_USB_repo___40__solved__41__/comment_1_0b4dcedc58e5071733e1239490aed2ea._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmZgZuUhZlHpd_AbbcixY0QQiutb2I7GWY"
+ nickname="Jimmy"
+ subject="Updated version 4.20131105-g136b030 seems to work"
+ date="2013-11-07T20:28:55Z"
+ content="""
+I've updated to the latest version as of 12 hours ago and I was able to create a USB repo on two computers. 4.20131105-g136b030 showing on the web app but 20131106 on the command line.
+
+Is there an easy way of checking the repo is correctly encrypted? I didn't see anything about encrypting (now the previous error has disappeared) when creating the repo - is this what I should expect?
+"""]]
diff --git a/doc/bugs/Mac_OS_10.9_GPG_erro_when_creating_USB_repo___40__solved__41__/comment_2_1cb1ef0292a3357874b461a77c13373e._comment b/doc/bugs/Mac_OS_10.9_GPG_erro_when_creating_USB_repo___40__solved__41__/comment_2_1cb1ef0292a3357874b461a77c13373e._comment
new file mode 100644
index 000000000..83e0b2317
--- /dev/null
+++ b/doc/bugs/Mac_OS_10.9_GPG_erro_when_creating_USB_repo___40__solved__41__/comment_2_1cb1ef0292a3357874b461a77c13373e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="108.236.230.124"
+ subject="comment 2"
+ date="2013-11-08T17:36:53Z"
+ content="""
+USB repos are not set up encryption unless you explicitly request it.
+"""]]
diff --git a/doc/bugs/Mac_OS_10.9_GPG_erro_when_creating_USB_repo___40__solved__41__/comment_3_e5ec1e3ab304d738e3b0847287a47af4._comment b/doc/bugs/Mac_OS_10.9_GPG_erro_when_creating_USB_repo___40__solved__41__/comment_3_e5ec1e3ab304d738e3b0847287a47af4._comment
new file mode 100644
index 000000000..0b3a804b9
--- /dev/null
+++ b/doc/bugs/Mac_OS_10.9_GPG_erro_when_creating_USB_repo___40__solved__41__/comment_3_e5ec1e3ab304d738e3b0847287a47af4._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmZgZuUhZlHpd_AbbcixY0QQiutb2I7GWY"
+ nickname="Jimmy"
+ subject="Yes, I just figured that out"
+ date="2013-11-08T22:09:40Z"
+ content="""
+I figured it out a couple of hours ago when I was able to use the existing USB repo on a new computer that doesn't have any of my private keys on it.
+
+I didn't see an option in the web interface to use encryption - is it command line only?
+"""]]
diff --git a/doc/bugs/Mac_OS_10.9_GPG_error_adding_S3_repo___40__solved__41__.mdwn b/doc/bugs/Mac_OS_10.9_GPG_error_adding_S3_repo___40__solved__41__.mdwn
new file mode 100644
index 000000000..5c70527fd
--- /dev/null
+++ b/doc/bugs/Mac_OS_10.9_GPG_error_adding_S3_repo___40__solved__41__.mdwn
@@ -0,0 +1,28 @@
+### Please describe the problem.
+
+Creating a remote S3 repository using the git-annex assistant web interface fails with a GPG error. (I'm also getting a GPG error trying to create a USB repo but it's slightly different so I'll post a different bug.)
+
+### What steps will reproduce the problem?
+
+ * Build git-annex and git-annex assistant using the instructions at https://gist.github.com/calmyournerves/7144127
+ * Run git-annex app to launch web interface
+ * Create local repo using web interface
+ * Try to create encrypted S3 remote repo using web interface
+
+### What version of git-annex are you using? On what operating system?
+
+git-annex version 4.20131105-g136b030 on MacOS 10.9 Mavericks.
+
+### Please provide any additional information below.
+
+[[!format sh """
+
+(encryption setup) dyld: Library not loaded: @rpath/libz.1.2.8.dylib
+ Referenced from: /Applications/git-annex.app/Contents/MacOS/bundle/gpg
+ Reason: image not found
+07/Nov/2013:06:38:27 +1100 [Error#yesod-core] user error (gpg ["--batch","--no-tty","--use-agent","--quiet","--trust-model","always","--gen-random","--armor","1","512"] exited 5) @(yesod-core-1.2.4.5:Yesod.Core.Class.Yesod ./Yesod/Core/Class/Yesod.hs:485:5)
+
+"""]]
+
+> [[fixed|done]]; it seems that this was a local build issue ad does not
+> affect the autobuild. --[[Joey]]
diff --git a/doc/bugs/Mac_OS_10.9_GPG_error_adding_S3_repo___40__solved__41__/comment_1_d95accb43bd18cc9acbbf1d4069f86b3._comment b/doc/bugs/Mac_OS_10.9_GPG_error_adding_S3_repo___40__solved__41__/comment_1_d95accb43bd18cc9acbbf1d4069f86b3._comment
new file mode 100644
index 000000000..0f1e34e31
--- /dev/null
+++ b/doc/bugs/Mac_OS_10.9_GPG_error_adding_S3_repo___40__solved__41__/comment_1_d95accb43bd18cc9acbbf1d4069f86b3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmZgZuUhZlHpd_AbbcixY0QQiutb2I7GWY"
+ nickname="Jimmy"
+ subject="S3 works without encryption"
+ date="2013-11-06T21:09:26Z"
+ content="""
+Not surprisingly, S3 repos work without encryption.
+"""]]
diff --git a/doc/bugs/Mac_OS_10.9_GPG_error_adding_S3_repo___40__solved__41__/comment_2_452a3c524974832f0742efb00df4d576._comment b/doc/bugs/Mac_OS_10.9_GPG_error_adding_S3_repo___40__solved__41__/comment_2_452a3c524974832f0742efb00df4d576._comment
new file mode 100644
index 000000000..6b3ca2a0b
--- /dev/null
+++ b/doc/bugs/Mac_OS_10.9_GPG_error_adding_S3_repo___40__solved__41__/comment_2_452a3c524974832f0742efb00df4d576._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmZgZuUhZlHpd_AbbcixY0QQiutb2I7GWY"
+ nickname="Jimmy"
+ subject="Still fails with git-annex version 4.20131105-g136b030"
+ date="2013-11-07T20:32:09Z"
+ content="""
+Updating seems to have fixed my other problem with creating a USB repo but still fails when trying to create an encrypted S3 repo.
+
+ (encryption setup) dyld: Library not loaded: @rpath/libz.1.2.8.dylib
+ Referenced from: /Applications/git-annex.app/Contents/MacOS/bundle/gpg
+ Reason: image not found
+ 08/Nov/2013:07:30:11 +1100 [Error#yesod-core] user error (gpg [\"--batch\",\"--no-tty\",\"--use-agent\",\"--quiet\",\"--trust-model\",\"always\",\"--gen-random\",\"--armor\",\"1\",\"512\"] exited 5) @(yesod-core-1.2.4.5:Yesod.Core.Class.Yesod ./Yesod/Core/Class/Yesod.hs:485:5)
+"""]]
diff --git a/doc/bugs/Mac_OS_10.9_GPG_error_adding_S3_repo___40__solved__41__/comment_3_f8f6d1e0065e5ba56cd405b1c021ca09._comment b/doc/bugs/Mac_OS_10.9_GPG_error_adding_S3_repo___40__solved__41__/comment_3_f8f6d1e0065e5ba56cd405b1c021ca09._comment
new file mode 100644
index 000000000..e2ae9c3dc
--- /dev/null
+++ b/doc/bugs/Mac_OS_10.9_GPG_error_adding_S3_repo___40__solved__41__/comment_3_f8f6d1e0065e5ba56cd405b1c021ca09._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="108.236.230.124"
+ subject="comment 3"
+ date="2013-11-08T17:38:40Z"
+ content="""
+Looks like it failed to include libz.1.2.8.dylib in the bundle for some reason despite gpg needing it.
+
+I don't really see the point in building an app bundle if you're going to install it back to the same machine you built it on. It's much easier to just `cabal install git-annex` in this case.
+"""]]
diff --git a/doc/bugs/Mac_OS_10.9_GPG_error_adding_S3_repo___40__solved__41__/comment_4_b524649cee751532d20a4894d71c5cf3._comment b/doc/bugs/Mac_OS_10.9_GPG_error_adding_S3_repo___40__solved__41__/comment_4_b524649cee751532d20a4894d71c5cf3._comment
new file mode 100644
index 000000000..8c7450ca6
--- /dev/null
+++ b/doc/bugs/Mac_OS_10.9_GPG_error_adding_S3_repo___40__solved__41__/comment_4_b524649cee751532d20a4894d71c5cf3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmZgZuUhZlHpd_AbbcixY0QQiutb2I7GWY"
+ nickname="Jimmy"
+ subject="Maybe I'm missing something..."
+ date="2013-11-08T22:12:04Z"
+ content="""
+But does cabal install git-annex install the assistant? On the Mac, I use the app bundle to launch the web interface from my applications folder.
+"""]]
diff --git a/doc/bugs/Mac_OS_10.9_GPG_error_adding_S3_repo___40__solved__41__/comment_5_8312ba868ef616ec00563446c9c3464f._comment b/doc/bugs/Mac_OS_10.9_GPG_error_adding_S3_repo___40__solved__41__/comment_5_8312ba868ef616ec00563446c9c3464f._comment
new file mode 100644
index 000000000..f94f2d9c8
--- /dev/null
+++ b/doc/bugs/Mac_OS_10.9_GPG_error_adding_S3_repo___40__solved__41__/comment_5_8312ba868ef616ec00563446c9c3464f._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmZgZuUhZlHpd_AbbcixY0QQiutb2I7GWY"
+ nickname="Jimmy"
+ subject="To answer my own question - &quot;git annex webapp&quot;"
+ date="2013-11-09T00:10:28Z"
+ content="""
+Will open the web app from the command line.
+
+But now I get a different error trying to create an encrypted S3 repo.
+
+ (encryption setup) 09/Nov/2013:11:08:56 +1100 [Error#yesod-core] user error (gpg [\"--quiet\",\"--trust-model\",\"always\",\"--gen-random\",\"--armor\",\"1\",\"512\"] exited 127) @(yesod-core-1.2.4.5:Yesod.Core.Class.Yesod ./Yesod/Core/Class/Yesod.hs:485:5)
+"""]]
diff --git a/doc/bugs/Mac_OS_10.9_GPG_error_adding_S3_repo___40__solved__41__/comment_6_1af75c691d27c97397f1901f7c2483b0._comment b/doc/bugs/Mac_OS_10.9_GPG_error_adding_S3_repo___40__solved__41__/comment_6_1af75c691d27c97397f1901f7c2483b0._comment
new file mode 100644
index 000000000..19313d9a7
--- /dev/null
+++ b/doc/bugs/Mac_OS_10.9_GPG_error_adding_S3_repo___40__solved__41__/comment_6_1af75c691d27c97397f1901f7c2483b0._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmZgZuUhZlHpd_AbbcixY0QQiutb2I7GWY"
+ nickname="Jimmy"
+ subject="Works with git annex on command line"
+ date="2013-11-09T20:18:38Z"
+ content="""
+git annex initremote cloud type=S3 keyid=key correct creates an encrypted S3 repo and I'm able to upload files.
+"""]]
diff --git a/doc/bugs/Mac_OS_10.9_GPG_error_adding_S3_repo___40__solved__41__/comment_7_e519df252875de87c4ef5b727f033bdf._comment b/doc/bugs/Mac_OS_10.9_GPG_error_adding_S3_repo___40__solved__41__/comment_7_e519df252875de87c4ef5b727f033bdf._comment
new file mode 100644
index 000000000..a67c59451
--- /dev/null
+++ b/doc/bugs/Mac_OS_10.9_GPG_error_adding_S3_repo___40__solved__41__/comment_7_e519df252875de87c4ef5b727f033bdf._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.246"
+ subject="comment 7"
+ date="2013-11-15T19:00:25Z"
+ content="""
+It would be useful if you could test with the 10.9 build now available in [[install/OSX]].
+"""]]
diff --git a/doc/bugs/Mac_OS_10.9_GPG_error_adding_S3_repo___40__solved__41__/comment_8_4bb959e2659991cd392853e8beacf708._comment b/doc/bugs/Mac_OS_10.9_GPG_error_adding_S3_repo___40__solved__41__/comment_8_4bb959e2659991cd392853e8beacf708._comment
new file mode 100644
index 000000000..cff7e9dee
--- /dev/null
+++ b/doc/bugs/Mac_OS_10.9_GPG_error_adding_S3_repo___40__solved__41__/comment_8_4bb959e2659991cd392853e8beacf708._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmZgZuUhZlHpd_AbbcixY0QQiutb2I7GWY"
+ nickname="Jimmy"
+ subject="comment 8"
+ date="2013-11-15T21:31:40Z"
+ content="""
+Thanks Joey - I was able to create an encrypted S3 repo using the new Mavericks build. Files are transferring across and are encrypted.
+"""]]
diff --git a/doc/bugs/Makefile_is_missing_dependancies.mdwn b/doc/bugs/Makefile_is_missing_dependancies.mdwn
new file mode 100644
index 000000000..3e9d6e903
--- /dev/null
+++ b/doc/bugs/Makefile_is_missing_dependancies.mdwn
@@ -0,0 +1,47 @@
+<pre>
+From e45c73e66fc18d27bdf5797876fbeb07786a4af1 Mon Sep 17 00:00:00 2001
+From: Jimmy Tang <jtang@tchpc.tcd.ie>
+Date: Tue, 22 Mar 2011 22:24:07 +0000
+Subject: [PATCH] Touch up Makefile to depend on StatFS.hs
+
+---
+ Makefile | 2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/Makefile b/Makefile
+index 08e2f59..4ae8392 100644
+--- a/Makefile
++++ b/Makefile
+@@ -15,7 +15,7 @@ SysConfig.hs: configure.hs TestConfig.hs
+ hsc2hs $<
+ perl -i -pe 's/^{-# INCLUDE.*//' $@
+
+-$(bins): SysConfig.hs Touch.hs
++$(bins): SysConfig.hs Touch.hs StatFS.hs
+ $(GHCMAKE) $@
+
+ git-annex.1: doc/git-annex.mdwn
+--
+1.7.4.1
+
+</pre>
+
+
+StatFS.hs never gets depended on and compiled, the makefile was just missing something
+
+> Thanks, [[done]]! Interested to hear if StatFS.hs works on OSX (no warning) or
+> is a no-op (with warning). --[[Joey]]
+
+>>
+>> for now it gives a warning, it looks like it should be easy enough to add OSX
+>> support, I guess it's a case of just digging around documentation to find the equivalent
+>> calls/headers. I'll give it a go at making this feature work on OSX and get back to you.
+>>
+
+<pre>
+jtang@exia:~/develop/git-annex $ make
+hsc2hs StatFS.hsc
+StatFS.hsc:85:2: warning: #warning free space checking code not available for this OS
+StatFS.hsc:85:2: warning: #warning free space checking code not available for this OS
+StatFS.hsc:85:2: warning: #warning free space checking code not available for this OS
+</pre>
diff --git a/doc/bugs/Makefile_is_missing_dependancies/comment_1_5a3da5f79c8563c7a450aa29728abe7c._comment b/doc/bugs/Makefile_is_missing_dependancies/comment_1_5a3da5f79c8563c7a450aa29728abe7c._comment
new file mode 100644
index 000000000..ab8493a7a
--- /dev/null
+++ b/doc/bugs/Makefile_is_missing_dependancies/comment_1_5a3da5f79c8563c7a450aa29728abe7c._comment
@@ -0,0 +1,47 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 1"
+ date="2011-03-23T08:21:30Z"
+ content="""
+Just did some minor digging around and checking, this seems to satisfy the compilers etc... I have yet to confirm that it *really* is working as expected. Also it might be better to check for a darwin operating system instead of apple I think, though I don't know of any one really using a pure darwin OS. But for now it works (I think)
+
+<pre>
+From fbfe27c2e19906ac02e3673b91bffa920f6dae5d Mon Sep 17 00:00:00 2001
+From: Jimmy Tang <jtang@tchpc.tcd.ie>
+Date: Wed, 23 Mar 2011 08:15:39 +0000
+Subject: [PATCH] Define (__APPLE__) in StatFS
+
+At least on OSX 10.6.6 it appears to have the same defintions as
+FreeBSD. The build process doesn't complain and the code is enabled,
+this needs to be tested and checked more.
+---
+ StatFS.hsc | 4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/StatFS.hsc b/StatFS.hsc
+index 8b453dc..45fd7e4 100644
+--- a/StatFS.hsc
++++ b/StatFS.hsc
+@@ -53,7 +53,7 @@ import Foreign.C.String
+ import Data.ByteString (useAsCString)
+ import Data.ByteString.Char8 (pack)
+
+-#if defined (__FreeBSD__)
++#if defined (__FreeBSD__) || defined(__APPLE__)
+ # include <sys/param.h>
+ # include <sys/mount.h>
+ #else
+@@ -84,7 +84,7 @@ data CStatfs
+ #ifdef UNKNOWN
+ #warning free space checking code not available for this OS
+ #else
+-#if defined(__FreeBSD__)
++#if defined(__FreeBSD__) || defined(__APPLE__)
+ foreign import ccall unsafe \"sys/mount.h statfs\"
+ #else
+ foreign import ccall unsafe \"sys/vfs.h statfs64\"
+--
+1.7.4.1
+</pre>
+"""]]
diff --git a/doc/bugs/Makefile_is_missing_dependancies/comment_2_416f12dbd0c2b841fac8164645b81df5._comment b/doc/bugs/Makefile_is_missing_dependancies/comment_2_416f12dbd0c2b841fac8164645b81df5._comment
new file mode 100644
index 000000000..d355514a3
--- /dev/null
+++ b/doc/bugs/Makefile_is_missing_dependancies/comment_2_416f12dbd0c2b841fac8164645b81df5._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 2"
+ date="2011-03-23T15:05:12Z"
+ content="""
+There's a simple test -- just configure annex.diskreserve to be say, 10 megabytes less than the total free space on your disk. Then try to git annex get a 11 mb file, and a 9 mb file. :)
+"""]]
diff --git a/doc/bugs/Makefile_is_missing_dependancies/comment_3_c38b6f4abc9b9ad413c3b83ca04386c3._comment b/doc/bugs/Makefile_is_missing_dependancies/comment_3_c38b6f4abc9b9ad413c3b83ca04386c3._comment
new file mode 100644
index 000000000..6b4cf5789
--- /dev/null
+++ b/doc/bugs/Makefile_is_missing_dependancies/comment_3_c38b6f4abc9b9ad413c3b83ca04386c3._comment
@@ -0,0 +1,25 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 3"
+ date="2011-03-23T15:13:33Z"
+ content="""
+Alternatively, you can just load it up in ghci and see if it reports numbers that make sense:
+
+<pre>
+joey@gnu:~/src/git-annex>make StatFS.hs
+hsc2hs StatFS.hsc
+perl -i -pe 's/^{-# INCLUDE.*//' StatFS.hs
+joey@gnu:~/src/git-annex>ghci StatFS.hs
+GHCi, version 6.12.1: http://www.haskell.org/ghc/ :? for help
+Loading package ghc-prim ... linking ... done.
+Loading package integer-gmp ... linking ... done.
+Loading package base ... linking ... done.
+[1 of 1] Compiling StatFS ( StatFS.hs, interpreted )
+Ok, modules loaded: StatFS.
+*StatFS> s <- getFileSystemStats \".\"
+Loading package bytestring-0.9.1.5 ... linking ... done.
+*StatFS> s
+Just (FileSystemStats {fsStatBlockSize = 4096, fsStatBlockCount = 7427989, fsStatByteCount = 30425042944, fsStatBytesFree = 2528489472, fsStatBytesAvailable = 2219384832, fsStatBytesUsed = 27896553472})
+</pre>
+"""]]
diff --git a/doc/bugs/Makefile_is_missing_dependancies/comment_4_cc13873175edf191047282700315beee._comment b/doc/bugs/Makefile_is_missing_dependancies/comment_4_cc13873175edf191047282700315beee._comment
new file mode 100644
index 000000000..c3ad2dafd
--- /dev/null
+++ b/doc/bugs/Makefile_is_missing_dependancies/comment_4_cc13873175edf191047282700315beee._comment
@@ -0,0 +1,30 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 4"
+ date="2011-03-23T16:02:34Z"
+ content="""
+Ok, well it looks like it isn't doing anything useful at all.
+
+<pre>
+jtang@x00:~/develop/git-annex $ make StatFS.hs
+hsc2hs StatFS.hsc
+perl -i -pe 's/^{-# INCLUDE.*//' StatFS.hs
+jtang@x00:~/develop/git-annex $ ghci StatFS.hs
+GHCi, version 6.12.3: http://www.haskell.org/ghc/ :? for help
+Loading package ghc-prim ... linking ... done.
+Loading package integer-gmp ... linking ... done.
+Loading package base ... linking ... done.
+Loading package ffi-1.0 ... linking ... done.
+[1 of 1] Compiling StatFS ( StatFS.hs, interpreted )
+Ok, modules loaded: StatFS.
+*StatFS> s <- getFileSystemStats \".\"
+Loading package bytestring-0.9.1.7 ... linking ... done.
+*StatFS> s
+Just (FileSystemStats {fsStatBlockSize = 0, fsStatBlockCount = 1048576, fsStatByteCount = 0, fsStatBytesFree = 0, fsStatBytesAvailable = 0, fsStatBytesUsed = 0})
+*StatFS> s <- getFileSystemStats \"/\"
+*StatFS> s
+Just (FileSystemStats {fsStatBlockSize = 0, fsStatBlockCount = 1048576, fsStatByteCount = 0, fsStatBytesFree = 0, fsStatBytesAvailable = 0, fsStatBytesUsed = 0})
+*StatFS>
+</pre>
+"""]]
diff --git a/doc/bugs/Makefile_is_missing_dependancies/comment_5_0a1c52e2c96d19b9c3eb7e99b8c2434f._comment b/doc/bugs/Makefile_is_missing_dependancies/comment_5_0a1c52e2c96d19b9c3eb7e99b8c2434f._comment
new file mode 100644
index 000000000..149aeeb75
--- /dev/null
+++ b/doc/bugs/Makefile_is_missing_dependancies/comment_5_0a1c52e2c96d19b9c3eb7e99b8c2434f._comment
@@ -0,0 +1,59 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 5"
+ date="2011-03-23T16:14:22Z"
+ content="""
+Actually I may have just been stupid and should have read the man page on statfs...
+
+<pre>
+jtang@x00:~/develop/git-annex $ git diff
+diff --git a/StatFS.hsc b/StatFS.hsc
+index 8b453dc..e10b2dd 100644
+--- a/StatFS.hsc
++++ b/StatFS.hsc
+@@ -53,7 +53,7 @@ import Foreign.C.String
+ import Data.ByteString (useAsCString)
+ import Data.ByteString.Char8 (pack)
+
+-#if defined (__FreeBSD__)
++#if defined (__FreeBSD__) || defined (__APPLE__)
+ # include <sys/param.h>
+ # include <sys/mount.h>
+ #else
+@@ -84,8 +84,8 @@ data CStatfs
+ #ifdef UNKNOWN
+ #warning free space checking code not available for this OS
+ #else
+-#if defined(__FreeBSD__)
+-foreign import ccall unsafe \"sys/mount.h statfs\"
++#if defined(__FreeBSD__) || defined (__APPLE__)
++foreign import ccall unsafe \"sys/mount.h statfs64\"
+ #else
+ foreign import ccall unsafe \"sys/vfs.h statfs64\"
+ #endif
+</pre>
+
+yields this...
+
+<pre>
+jtang@x00:~/develop/git-annex $ ghci StatFS.hs
+GHCi, version 6.12.3: http://www.haskell.org/ghc/ :? for help
+Loading package ghc-prim ... linking ... done.
+Loading package integer-gmp ... linking ... done.
+Loading package base ... linking ... done.
+Loading package ffi-1.0 ... linking ... done.
+[1 of 1] Compiling StatFS ( StatFS.hs, interpreted )
+Ok, modules loaded: StatFS.
+*StatFS> s <- getFileSystemStats \".\"
+Loading package bytestring-0.9.1.7 ... linking ... done.
+*StatFS> s
+Just (FileSystemStats {fsStatBlockSize = 4096, fsStatBlockCount = 244106668, fsStatByteCount = 999860912128, fsStatBytesFree = 423097798656, fsStatBytesAvailable = 422835654656, fsStatBytesUsed = 576763113472})
+*StatFS>
+</pre>
+
+
+we could just stick another if defined (__APPLE__) instead of what I previously had and it looks like it will do the right thing on OSX.
+
+
+"""]]
diff --git a/doc/bugs/Makefile_is_missing_dependancies/comment_6_24119fc5d5963ce9dd669f7dcf006859._comment b/doc/bugs/Makefile_is_missing_dependancies/comment_6_24119fc5d5963ce9dd669f7dcf006859._comment
new file mode 100644
index 000000000..714459fbe
--- /dev/null
+++ b/doc/bugs/Makefile_is_missing_dependancies/comment_6_24119fc5d5963ce9dd669f7dcf006859._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 6"
+ date="2011-03-23T16:23:56Z"
+ content="""
+I forgot to mention that the statfs64 stuff in OSX seems to be deprecated, see http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man2/statfs64.2.html
+
+on a slightly different note, is anonymous pushing to the \"wiki\" over git allowed? I'd prefer to be able to edit stuff inline for updating some of my own comments if I can :P
+"""]]
diff --git a/doc/bugs/Makefile_is_missing_dependancies/comment_7_96fd4725df4b54e670077a18d3ac4943._comment b/doc/bugs/Makefile_is_missing_dependancies/comment_7_96fd4725df4b54e670077a18d3ac4943._comment
new file mode 100644
index 000000000..8ba8e8d1f
--- /dev/null
+++ b/doc/bugs/Makefile_is_missing_dependancies/comment_7_96fd4725df4b54e670077a18d3ac4943._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 7"
+ date="2011-03-23T16:57:56Z"
+ content="""
+Try the changes I've pushed to use statfs64 on apple.
+
+There is actually a standardized statvfs that I'd rather use, but after the last time that I tried going with the POSIX option first only to find it was not broadly implemented, I was happy to find some already existing code that worked for some OSs.
+
+(While ikiwiki supports anonymous git push, it's a feature we have not rolled out on Branchable.com yet, and anyway, ikiwiki disallows editing existing comments that way. I would, however, be happy to git pull changes from somewhere.)
+"""]]
diff --git a/doc/bugs/Makefile_is_missing_dependancies/comment_8_a3555e3286cdc2bfeb9cde0ff727ba74._comment b/doc/bugs/Makefile_is_missing_dependancies/comment_8_a3555e3286cdc2bfeb9cde0ff727ba74._comment
new file mode 100644
index 000000000..63d188bcc
--- /dev/null
+++ b/doc/bugs/Makefile_is_missing_dependancies/comment_8_a3555e3286cdc2bfeb9cde0ff727ba74._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 8"
+ date="2011-03-23T17:03:51Z"
+ content="""
+The latest change looks good, it seems to be returning sensible numbers for me. Just tried it out on a few different mount points and it appears to be working.
+"""]]
diff --git a/doc/bugs/Manual_content_mode_isn__39__t_manual.mdwn b/doc/bugs/Manual_content_mode_isn__39__t_manual.mdwn
new file mode 100644
index 000000000..cb0247766
--- /dev/null
+++ b/doc/bugs/Manual_content_mode_isn__39__t_manual.mdwn
@@ -0,0 +1,89 @@
+### Please describe the problem.
+
+The `manual` content mode doesn't follow the description provided in the help page, instead it seems to collect content.
+
+### What steps will reproduce the problem?
+
+1. Create a new git annex repository using the webapp, set the content type to `client`.
+2. Create another repository, and set the content type to `manual`.
+3. Copy something into the `client` repository.
+4. It will be pushed/pulled into the `manual` repository.
+
+### What version of git-annex are you using? On what operating system?
+
+ git-annex version: 4.20130521-g25dba9d
+ Ubuntu 13.04 x64.
+
+### Please provide any additional information below.
+
+I have also noticed very weird behaviour that I have been unable to replicate in testing, but I will describe the setup that it currently happens in:
+I have 3x repositories, one a `client` repository, and the other two are set to `manual`. When put a new file into the `client` repository, it is pushed onto the two `manual` repositories. When these repositories have received it, the client drops the file and re-downloads it from one of the `manual` repositories. Once it's been pushed, deleted, and pulled, everything is happy... but the extra step makes no difference.
+
+[[!format sh """
+[2013-05-22 20:41:44 EST] main: starting assistant version 4.20130521-g25dba9d
+[2013-05-22 20:41:44 EST] TransferScanner: Syncing with test3, test2
+Already up-to-date.
+
+(scanning...) [2013-05-22 20:41:44 EST] Watcher: Performing startup scan
+Already up-to-date.
+Already up-to-date.
+
+
+(started...) From /home/valorin/workspace/tmp/test3
+ f285dc2..406c20c git-annex -> test3/git-annex
+ cdf2ad3..508983c master -> test3/master
+From /home/valorin/workspace/tmp/test2
+ 1e04829..1c03533 git-annex -> test2/git-annex
+ 8ad4bd3..18a5408 master -> test2/master
+Updating 508983c..18a5408
+Fast-forward
+Already up-to-date.
+To /home/valorin/workspace/tmp/test2
+ 4e49293..a66ce5d git-annex -> synced/git-annex
+ 508983c..18a5408 master -> synced/master
+To /home/valorin/workspace/tmp/test3
+ 4e49293..a66ce5d git-annex -> synced/git-annex
+ 508983c..18a5408 master -> synced/master
+Already up-to-date.
+Already up-to-date.
+[2013-05-22 20:42:07 EST] Committer: Adding Firefly S..acked.m4v
+
+(merging test3/git-annex into git-annex...)
+(merging test2/git-annex into git-annex...)
+(Recording state in git...)
+
+
+
+
+add Firefly S01E03 Bushwhacked.m4v (checksum...) [2013-05-22 20:42:15 EST] Committer: Committing changes to git
+[2013-05-22 20:42:15 EST] Pusher: Syncing with test3, test2
+Already up-to-date.
+To /home/valorin/workspace/tmp/test2
+ a66ce5d..a6773dd git-annex -> synced/git-annex
+ 18a5408..f9e7692 master -> synced/master
+To /home/valorin/workspace/tmp/test3
+ a66ce5d..a6773dd git-annex -> synced/git-annex
+ 18a5408..f9e7692 master -> synced/master
+Already up-to-date.
+Already up-to-date.
+[2013-05-22 20:42:26 EST] Transferrer: Uploaded Firefly S..acked.m4v
+[2013-05-22 20:42:26 EST] Pusher: Syncing with test3, test2
+To /home/valorin/workspace/tmp/test3
+ a6773dd..c35f992 git-annex -> synced/git-annex
+To /home/valorin/workspace/tmp/test2
+ a6773dd..c35f992 git-annex -> synced/git-annex
+[2013-05-22 20:42:35 EST] Transferrer: Uploaded Firefly S..acked.m4v
+[2013-05-22 20:42:35 EST] Pusher: Syncing with test3, test2
+To /home/valorin/workspace/tmp/test3
+ c35f992..9e47813 git-annex -> synced/git-annex
+To /home/valorin/workspace/tmp/test2
+ c35f992..9e47813 git-annex -> synced/git-annex
+[2013-05-22 20:42:44 EST] Pusher: Syncing with test3, test2
+Everything up-to-date
+Everything up-to-date
+"""]]
+
+> It turns out there was a bug in the preferred content expression parser,
+> that made it parse the expression for manual mode (but I think no other standard
+> expression) quite wrong, as if it had parens in the wrong place. This explains
+> the broken behavior. [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/Manual_mode_weirdness.mdwn b/doc/bugs/Manual_mode_weirdness.mdwn
new file mode 100644
index 000000000..efc88df2f
--- /dev/null
+++ b/doc/bugs/Manual_mode_weirdness.mdwn
@@ -0,0 +1,37 @@
+### Please describe the problem.
+
+I have an annex which contains all my photos. There are repositories on my laptop and my home server as well as an s3 backup (for which syncing is currently disabled). I switched the copy on my laptop to manual mode via 'git annex vicfg' (this correctly shows up in the webapp). I then proceeded to drop several folders (each containing a year's worth of photos). This works fine, however the assistant immediately starts downloading the dropped files from the server! Numcopies is set to 1 and the problem exists with the server in both the 'transfer' and 'backup' groups (haven't tried others).
+
+### What steps will reproduce the problem?
+
+1. Create a repo with some files.
+2. Create a bare-git remote on another machine.
+3. Make sure the assistant is running for the repo in question.
+4. Switch your local copy to manual mode.
+5. Drop some files.
+6. Watch as the assistant re-downloads them!
+
+### What version of git-annex are you using? On what operating system?
+
+git-annex version: 4.20130501
+local repository version: unknown
+default repository version: 3
+supported repository versions: 3 4
+upgrade supported from repository versions: 0 1 2
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP
+
+Debian Testing/Sid.
+
+### Please provide any additional information below.
+
+If it's relevant I switched the local repository to indirect mode by manually shutting down the assistant and running 'git annex indirect' before restarting the assistant. This was done before any of the steps above.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
+
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/Manual_mode_weirdness/comment_1_f8ab3bac9e9a6768e5fd5a052f0d920f._comment b/doc/bugs/Manual_mode_weirdness/comment_1_f8ab3bac9e9a6768e5fd5a052f0d920f._comment
new file mode 100644
index 000000000..fcacc3b33
--- /dev/null
+++ b/doc/bugs/Manual_mode_weirdness/comment_1_f8ab3bac9e9a6768e5fd5a052f0d920f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-05-29T16:13:10Z"
+ content="""
+Yes, 4.20130501 is broken WRT manual mode. This has been fixed for a while in the current git master branch and autobuilds and there will be a new release soon with the fix.
+"""]]
diff --git a/doc/bugs/Manual_mode_weirdness/comment_2_e810daa488fad32ca8bdaae620051da8._comment b/doc/bugs/Manual_mode_weirdness/comment_2_e810daa488fad32ca8bdaae620051da8._comment
new file mode 100644
index 000000000..3a4cd9881
--- /dev/null
+++ b/doc/bugs/Manual_mode_weirdness/comment_2_e810daa488fad32ca8bdaae620051da8._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="robconnolly"
+ ip="203.167.218.84"
+ subject="comment 2"
+ date="2013-05-29T23:18:23Z"
+ content="""
+Excellent, Thank you!
+"""]]
diff --git a/doc/bugs/Missing_dependancy_in_commit_6cecc26206c4a539999b04664136c6f785211a41.mdwn b/doc/bugs/Missing_dependancy_in_commit_6cecc26206c4a539999b04664136c6f785211a41.mdwn
new file mode 100644
index 000000000..2253c0f52
--- /dev/null
+++ b/doc/bugs/Missing_dependancy_in_commit_6cecc26206c4a539999b04664136c6f785211a41.mdwn
@@ -0,0 +1,35 @@
+Seems commit 6cecc26206c4a539999b04664136c6f785211a41 missed on dependancy, that is blaze-markup
+
+<pre>
+Assistant/Threads/WebApp.hs:25:8:
+ Could not find module `Text.Blaze.Renderer.String'
+ It is a member of the hidden package `blaze-markup-0.5.1.0'.
+ Perhaps you need to add `blaze-markup' to the build-depends in your .cabal file.
+ Use -v to see a list of the files searched for.
+cabal: Error: some packages failed to install:
+git-annex-3.20120721 failed during the building phase. The exception was:
+ExitFailure 1
+</pre>
+
+This should fix it
+
+<pre>
+x00:git-annex jtang$ git diff
+diff --git a/git-annex.cabal b/git-annex.cabal
+index c7d9bf5..4f98d2a 100644
+--- a/git-annex.cabal
++++ b/git-annex.cabal
+@@ -76,7 +76,7 @@ Executable git-annex
+ if flag(Webapp)
+ Build-Depends: yesod, yesod-static, case-insensitive, http-types,
+ transformers, wai, wai-logger, warp, blaze-builder, blaze-html,
+- crypto-api, hamlet
++ blaze-markup, crypto-api, hamlet
+ CPP-Options: -DWITH_WEBAPP
+
+ if (os(darwin))
+</pre>
+
+> [[done]].. interestingly, cabal had not complained about there here,
+> as in my version, it's in blaze, not blaze-markup. Added it anyway.
+> --[[Joey]]
diff --git a/doc/bugs/Missing_repo_uuid_after_local_pairing_with_older_annex.mdwn b/doc/bugs/Missing_repo_uuid_after_local_pairing_with_older_annex.mdwn
new file mode 100644
index 000000000..dc24ee18d
--- /dev/null
+++ b/doc/bugs/Missing_repo_uuid_after_local_pairing_with_older_annex.mdwn
@@ -0,0 +1,31 @@
+### Please describe the problem.
+I paired my repo running on Gentoo (git-annex 4.20130601) with Ubuntu 13.04 (git-annex 3.10121112ubuntu4). The repo on Ubuntu doesn't have uuid for the Gentoo remote, so:
+
+- There is no name in assistan's repo settings for it
+
+- Trying to access its settings gives Internal server error: Unknown UUID
+15/Jun/2013:12:39:10 +0300 [Error#yesod-core] Unknown UUID @(yesod-core-1.1.8.3:Yesod.Internal.Core ./Yesod/Internal/Core.hs:550:5)
+
+- In dashboard on Ubuntu all changes stay queued forever (although the syncing seems to work)
+
+### What steps will reproduce the problem?
+Pair local computers with different annex versions.
+
+### What version of git-annex are you using? On what operating system?
+Gentoo (git-annex 4.20130601)
+Ubuntu 13.04 (git-annex 3.10121112ubuntu4)
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
+
+> Others are reporting what seems to be the same problem here:
+> [[Internal_Server_Error:_Unknown_UUID]].
+>
+> [[dup|done]] --[[Joey]]
diff --git a/doc/bugs/Missing_repo_uuid_after_local_pairing_with_older_annex/comment_1_8229df64a872bee7590f75eb78f78c4a._comment b/doc/bugs/Missing_repo_uuid_after_local_pairing_with_older_annex/comment_1_8229df64a872bee7590f75eb78f78c4a._comment
new file mode 100644
index 000000000..26881f17b
--- /dev/null
+++ b/doc/bugs/Missing_repo_uuid_after_local_pairing_with_older_annex/comment_1_8229df64a872bee7590f75eb78f78c4a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.193"
+ subject="comment 1"
+ date="2013-06-25T18:08:55Z"
+ content="""
+As far as I know, there have been no changes to the local pairing protocol that would cause a problem like this. 3.20121112 is a few months after local pairing was first developed.
+
+Have you tried upgrading and re-pairing?
+"""]]
diff --git a/doc/bugs/Missing_repo_uuid_after_local_pairing_with_older_annex/comment_2_f37be896396915b1c85cff8811dceb4a._comment b/doc/bugs/Missing_repo_uuid_after_local_pairing_with_older_annex/comment_2_f37be896396915b1c85cff8811dceb4a._comment
new file mode 100644
index 000000000..d9ad17e79
--- /dev/null
+++ b/doc/bugs/Missing_repo_uuid_after_local_pairing_with_older_annex/comment_2_f37be896396915b1c85cff8811dceb4a._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm01ida6POv7vqyUYtOlymEbJTbrImAIzM"
+ nickname="Reinis"
+ subject="comment 2"
+ date="2013-06-25T18:50:00Z"
+ content="""
+I have not tried to upgrade, but I fixed it using annex describe followed by assistant restart as hinted in /usr/share/doc/git-annex/html/bugs/uuid.log_trust.log_and_remote.log_merge_wackiness.html.
+
+From that document I understood that at worst it should use one of the two uuids (from Ubuntu or Gentoo repo), but it should not leave it without uuid and hence this report.
+
+I have tried it a couple of times and it is perfectly reproducible.
+"""]]
diff --git a/doc/bugs/Missing_repo_uuid_after_local_pairing_with_older_annex/comment_3_df7fc1078059538a76f384a40541e91f._comment b/doc/bugs/Missing_repo_uuid_after_local_pairing_with_older_annex/comment_3_df7fc1078059538a76f384a40541e91f._comment
new file mode 100644
index 000000000..75fd81d46
--- /dev/null
+++ b/doc/bugs/Missing_repo_uuid_after_local_pairing_with_older_annex/comment_3_df7fc1078059538a76f384a40541e91f._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.193"
+ subject="comment 3"
+ date="2013-06-25T19:13:06Z"
+ content="""
+An old bug report that was fixed in 2011 seems very unlikely to have anything to do with your local pairing problem.
+
+Why don't you try upgrading?
+"""]]
diff --git a/doc/bugs/Missing_repo_uuid_after_local_pairing_with_older_annex/comment_4_70c444c61f41df2f59294c10f94f0c09._comment b/doc/bugs/Missing_repo_uuid_after_local_pairing_with_older_annex/comment_4_70c444c61f41df2f59294c10f94f0c09._comment
new file mode 100644
index 000000000..8e895be5f
--- /dev/null
+++ b/doc/bugs/Missing_repo_uuid_after_local_pairing_with_older_annex/comment_4_70c444c61f41df2f59294c10f94f0c09._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm01ida6POv7vqyUYtOlymEbJTbrImAIzM"
+ nickname="Reinis"
+ subject="comment 4"
+ date="2013-06-25T19:34:12Z"
+ content="""
+I was expecting the version in distribution which came out two months ago to be somewhat recent, probably unfounded expectation for non-rolling release distribution. I'll add PPA and try using that one.
+"""]]
diff --git a/doc/bugs/More_sync__39__ing_weirdness_with_the_assistant_branch_on_OSX.mdwn b/doc/bugs/More_sync__39__ing_weirdness_with_the_assistant_branch_on_OSX.mdwn
new file mode 100644
index 000000000..00f425307
--- /dev/null
+++ b/doc/bugs/More_sync__39__ing_weirdness_with_the_assistant_branch_on_OSX.mdwn
@@ -0,0 +1,15 @@
+Running the 'assistant' branch, I occassionally get
+
+To myhost1:/Users/jtang/annex
+ ! [rejected] master -> synced/master (non-fast-forward)
+error: failed to push some refs to 'myhost1:/Users/jtang/annex'
+hint: Updates were rejected because a pushed branch tip is behind its remote
+hint: counterpart. Check out this branch and merge the remote changes
+hint: (e.g. 'git pull') before pushing again.
+hint: See the 'Note about fast-forwards' in 'git push --help' for details.
+(Recording state in git...)
+
+manually running a 'git annex sync' usually fixes it, I guess once the sync command runs periodically this problem will go away, is this even OSX specific? I don't quite get the behaviour that is described in [[design/assistant/blog/day_15__its_aliiive]].
+
+> With my changes today, I've seen it successfully recover from this
+> situation. [[done]] --[[Joey]]
diff --git a/doc/bugs/More_sync__39__ing_weirdness_with_the_assistant_branch_on_OSX/comment_1_377525e70640751e1ead445aeed15efa._comment b/doc/bugs/More_sync__39__ing_weirdness_with_the_assistant_branch_on_OSX/comment_1_377525e70640751e1ead445aeed15efa._comment
new file mode 100644
index 000000000..77481789c
--- /dev/null
+++ b/doc/bugs/More_sync__39__ing_weirdness_with_the_assistant_branch_on_OSX/comment_1_377525e70640751e1ead445aeed15efa._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.2.25"
+ subject="comment 1"
+ date="2012-06-25T15:45:18Z"
+ content="""
+This is indeed the problem I've planned to work on today, as I see it too when things don't start off perfectly in sync.
+"""]]
diff --git a/doc/bugs/Most_recent_git-annex_will_not_build_on_OpenIndiana.mdwn b/doc/bugs/Most_recent_git-annex_will_not_build_on_OpenIndiana.mdwn
new file mode 100644
index 000000000..ee188eb2e
--- /dev/null
+++ b/doc/bugs/Most_recent_git-annex_will_not_build_on_OpenIndiana.mdwn
@@ -0,0 +1,36 @@
+Version 3.20120825 built on my OpenIndiana system just fine, but the latest release gives me this during setup:
+
+ Linking /tmp/git-annex-3.20121017-13013/git-annex-3.20121017/dist/setup/setup ...
+ checking version... 3.20121017
+ checking git... yes
+ checking git version... 1.7.8.2
+ checking cp -a... yes
+ checking cp -p... yes
+ checking cp --reflink=auto... yes
+ checking uuid generator... uuid -m
+ checking xargs -0... yes
+ checking rsync... yes
+ checking curl... yes
+ checking wget... yes
+ checking bup... no
+ checking gpg... no
+ checking lsof... no
+ checking ssh connection caching... yes
+ checking sha1... sha1sum
+ checking sha256... sha256sum
+ checking sha512... sha512sum
+ checking sha224... sha224sum
+ checking sha384... sha384sum
+ Configuring git-annex-3.20121017...
+ Building git-annex-3.20121017...
+ Preprocessing executable 'git-annex' for git-annex-3.20121017...
+ In file included from Mounts.hsc:25:0:
+ Utility/libmounts.h:13:3: warning: #warning mounts listing code not available for this OS [-Wcpp]
+
+ Utility/libkqueue.c:13:23:
+ fatal error: sys/event.h: No such file or directory
+ compilation terminated.
+
+Is it possible to remove the new requirement? Thanks!
+
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/Most_recent_git-annex_will_not_build_on_OpenIndiana/comment_1_f3c336ecfee51e074ea3a9fc95301de5._comment b/doc/bugs/Most_recent_git-annex_will_not_build_on_OpenIndiana/comment_1_f3c336ecfee51e074ea3a9fc95301de5._comment
new file mode 100644
index 000000000..bb1dc688f
--- /dev/null
+++ b/doc/bugs/Most_recent_git-annex_will_not_build_on_OpenIndiana/comment_1_f3c336ecfee51e074ea3a9fc95301de5._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 1"
+ date="2012-10-17T17:42:30Z"
+ content="""
+kqueue is used by the new assistant and watch features. It seems something else would need to be used for Solaris. I have modified the Makefile to (try to) detect Solaris and disable these features. I assumed your uname would be \"Solaris\", so you may need to modify it slightly.
+"""]]
diff --git a/doc/bugs/Most_recent_git-annex_will_not_build_on_OpenIndiana/comment_2_102c0e998934e84deca92fd1c90145fa._comment b/doc/bugs/Most_recent_git-annex_will_not_build_on_OpenIndiana/comment_2_102c0e998934e84deca92fd1c90145fa._comment
new file mode 100644
index 000000000..0a2a2641c
--- /dev/null
+++ b/doc/bugs/Most_recent_git-annex_will_not_build_on_OpenIndiana/comment_2_102c0e998934e84deca92fd1c90145fa._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/2grhJvAC049fJnvALDXek.6MRZMTlg--#eec89"
+ nickname="John"
+ subject="uname on OpenIndiana"
+ date="2012-10-17T22:19:04Z"
+ content="""
+The uname is actually SunOS, surprisingly enough. I'll give it a try!
+"""]]
diff --git a/doc/bugs/Most_recent_git-annex_will_not_build_on_OpenIndiana/comment_3_1449dd796ce9f2209f085d4b017a5f33._comment b/doc/bugs/Most_recent_git-annex_will_not_build_on_OpenIndiana/comment_3_1449dd796ce9f2209f085d4b017a5f33._comment
new file mode 100644
index 000000000..8feff78d9
--- /dev/null
+++ b/doc/bugs/Most_recent_git-annex_will_not_build_on_OpenIndiana/comment_3_1449dd796ce9f2209f085d4b017a5f33._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/2grhJvAC049fJnvALDXek.6MRZMTlg--#eec89"
+ nickname="John"
+ subject="Doesn't quite work"
+ date="2012-10-17T22:23:16Z"
+ content="""
+Your Makefile change, even with the uname corrected, had no impact at all. I'm running \"cabal install\". When I try just \"make\", I get this error:
+
+
+ Annex.hs:69:28:
+ No instance for (MonadBase IO (StateT AnnexState IO))
+ arising from a use of `liftBase'
+ Possible fix:
+ add an instance declaration for
+ (MonadBase IO (StateT AnnexState IO))
+ In the second argument of `(.)', namely `liftBase'
+ In the expression: Annex . liftBase
+ In an equation for `liftBase': liftBase = Annex . liftBase
+"""]]
diff --git a/doc/bugs/Most_recent_git-annex_will_not_build_on_OpenIndiana/comment_4_c4aa8a4379b2c056ca9b7afcff412bbc._comment b/doc/bugs/Most_recent_git-annex_will_not_build_on_OpenIndiana/comment_4_c4aa8a4379b2c056ca9b7afcff412bbc._comment
new file mode 100644
index 000000000..eb64afee2
--- /dev/null
+++ b/doc/bugs/Most_recent_git-annex_will_not_build_on_OpenIndiana/comment_4_c4aa8a4379b2c056ca9b7afcff412bbc._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.23"
+ subject="comment 4"
+ date="2012-10-18T02:04:47Z"
+ content="""
+You might be able to use the cabal file now. (Not sure.. the OS name used there is different from uname.)
+
+cabal may have better luck, the make error suggests that you have too old a version of the haskell transformers-base library installed.
+"""]]
diff --git a/doc/bugs/Most_recent_git-annex_will_not_build_on_OpenIndiana/comment_5_6ca4dd2ad51182edf7198f38b336b9b6._comment b/doc/bugs/Most_recent_git-annex_will_not_build_on_OpenIndiana/comment_5_6ca4dd2ad51182edf7198f38b336b9b6._comment
new file mode 100644
index 000000000..f37b1d227
--- /dev/null
+++ b/doc/bugs/Most_recent_git-annex_will_not_build_on_OpenIndiana/comment_5_6ca4dd2ad51182edf7198f38b336b9b6._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/2grhJvAC049fJnvALDXek.6MRZMTlg--#eec89"
+ nickname="John"
+ subject="Works great!"
+ date="2012-10-18T05:34:06Z"
+ content="""
+This can be moved to done.
+"""]]
diff --git a/doc/bugs/Name_scheme_does_not_follow_git__39__s_rules.mdwn b/doc/bugs/Name_scheme_does_not_follow_git__39__s_rules.mdwn
new file mode 100644
index 000000000..722dac50b
--- /dev/null
+++ b/doc/bugs/Name_scheme_does_not_follow_git__39__s_rules.mdwn
@@ -0,0 +1,31 @@
+I can create an annex remote named 'test:/test'. git itself does not allow colons in names, though. The name scheme for an annex should be the same as for git repos themselves.
+
+> What do you mean by "an annex remote"? git-annex uses the same
+> remotes configuration as does git. If you put invalid
+> stuff in .git/config it might handle it slightly different than
+> git, I don't know. Examples needed. --[[Joey]]
+
+>> What I mean is this:
+
+ % cd 1
+ % git init
+ % git annex init "my:colon"
+ % [...]
+ % cd ../2
+ % git init
+ % git annex init "second"
+ % git remote add "my:colon" ../1
+ fatal: 'my:colon' is not a valid remote name
+
+>> -- RichiH
+
+>>> I see.. Git annex init does not specifiy a remote's name, it specifies
+>>> an arbitrary human-readable description of the repository, which will
+>>> be displayed when there is no configured remote corresponding to the
+>>> repository. So this is not a bug unless some documentation of that is
+>>> unclear. --[[Joey]]
+
+>>>> Nobody spoke up to say it's unclear, so closing as PEBKAC :)
+>>>> [[done]] --[[Joey]]
+
+>>>>> I still think git-annex should follow the same rules as git in this regard, but if your design decision is different, I won't try to argue the point :) -- RichiH
diff --git a/doc/bugs/Need_to_manually_install_c2hs_-_3.20121127_and_previous.mdwn b/doc/bugs/Need_to_manually_install_c2hs_-_3.20121127_and_previous.mdwn
new file mode 100644
index 000000000..924ce06c7
--- /dev/null
+++ b/doc/bugs/Need_to_manually_install_c2hs_-_3.20121127_and_previous.mdwn
@@ -0,0 +1,37 @@
+What steps will reproduce the problem?
+
+Install git-annex via cabal - either from Hackage or as a manual install. (i.e. <http://git-annex.branchable.com/install/cabal/>)
+
+What is the expected output? What do you see instead?
+
+Expect a clean install.
+
+However, get the following error:
+
+ Configuring gnuidn-0.2...
+ cabal: The program c2hs is required but it could not be found.
+ Failed to install gnuidn-0.2
+ cabal: Error: some packages failed to install:
+ git-annex-3.20121127 depends on gnuidn-0.2 which failed to install.
+ gnuidn-0.2 failed during the configure step. The exception was:
+ ExitFailure 1
+ network-protocol-xmpp-0.4.4 depends on gnuidn-0.2 which failed to install.
+
+What version of git-annex are you using? On what operating system?
+
+git-annex: 3.20121127 (and previous versions)
+
+OS: Mac OSX 10.6.8
+
+
+Please provide any additional information below.
+
+The fix seems as easy as
+
+ cabal install c2hs
+
+Should c2hs be included as a dep got git-annex or is this a bug in gnuidn?
+
+> Apparently cabal does not support automatically installing programs
+> needed for the build. I've updated the cabal installation instructions
+> to document the need to install c2hs. [[done]] --[[Joey]]
diff --git a/doc/bugs/No_easy_way_to_re-inject_a_file_into_an_annex.mdwn b/doc/bugs/No_easy_way_to_re-inject_a_file_into_an_annex.mdwn
new file mode 100644
index 000000000..8df3bde48
--- /dev/null
+++ b/doc/bugs/No_easy_way_to_re-inject_a_file_into_an_annex.mdwn
@@ -0,0 +1,12 @@
+My local git index got corrupted and I needed to clone and annex get all data from my main repo.
+
+Some files were never copied anywhere so I am stuck with symlinks to nowhere.
+
+I tried to copy over the symlink with a copy of the actual file, which did not work. Trying to unlock, copying over the symlink, and relock did not work, either.
+
+Then, I copied the annex object to the correct place in .git/annex/objects/..., set all modes, re-ran fsck and the file re-appeared.
+
+
+Long story short, I think there should be a `git annex reinject $file` or similar which will take a file, either one replacing the symlink or with an arbitrary path, and put it into the correct place in the object store. Called normally, it should reject all reinjects where the checksum does not match. With --force, this should be overridden. For reasons of safety, WORM should always require --force.
+
+> [[closing|done]], seems addressed --[[Joey]]
diff --git a/doc/bugs/No_easy_way_to_re-inject_a_file_into_an_annex/comment_1_c871605e187f539f3bfe7478433e7fb5._comment b/doc/bugs/No_easy_way_to_re-inject_a_file_into_an_annex/comment_1_c871605e187f539f3bfe7478433e7fb5._comment
new file mode 100644
index 000000000..9688012a4
--- /dev/null
+++ b/doc/bugs/No_easy_way_to_re-inject_a_file_into_an_annex/comment_1_c871605e187f539f3bfe7478433e7fb5._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-04-03T01:46:16Z"
+ content="""
+Have you seen [[walkthrough/recover_data_from_lost+found]]? The method described there will also work in this scenario.
+"""]]
diff --git a/doc/bugs/No_easy_way_to_re-inject_a_file_into_an_annex/comment_2_e6f1e9eee8b8dfb60ca10c8cfd807ac9._comment b/doc/bugs/No_easy_way_to_re-inject_a_file_into_an_annex/comment_2_e6f1e9eee8b8dfb60ca10c8cfd807ac9._comment
new file mode 100644
index 000000000..c9b74d98f
--- /dev/null
+++ b/doc/bugs/No_easy_way_to_re-inject_a_file_into_an_annex/comment_2_e6f1e9eee8b8dfb60ca10c8cfd807ac9._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 2"
+ date="2011-04-03T09:00:17Z"
+ content="""
+I did not. Thanks :)
+
+This still means that you can't re-inject a new version of a file unless you have the old one if you are using a SHA* backend, but that might be a corner case anyway.
+"""]]
diff --git a/doc/bugs/No_easy_way_to_re-inject_a_file_into_an_annex/comment_3_be62be5fe819acc0cb8b878802decd46._comment b/doc/bugs/No_easy_way_to_re-inject_a_file_into_an_annex/comment_3_be62be5fe819acc0cb8b878802decd46._comment
new file mode 100644
index 000000000..9c56452e5
--- /dev/null
+++ b/doc/bugs/No_easy_way_to_re-inject_a_file_into_an_annex/comment_3_be62be5fe819acc0cb8b878802decd46._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 3"
+ date="2011-05-14T16:28:36Z"
+ content="""
+To re-inject new content for a file, you really want to get a new key for the file. Otherwise, other repos that have the old file will never get the new content. So:
+
+<pre>
+git rm file
+mv ~/newcontent file
+git annex add file
+</pre>
+"""]]
diff --git a/doc/bugs/No_easy_way_to_re-inject_a_file_into_an_annex/comment_4_480a4f72445a636eab1b1c0f816d365c._comment b/doc/bugs/No_easy_way_to_re-inject_a_file_into_an_annex/comment_4_480a4f72445a636eab1b1c0f816d365c._comment
new file mode 100644
index 000000000..fcca0561d
--- /dev/null
+++ b/doc/bugs/No_easy_way_to_re-inject_a_file_into_an_annex/comment_4_480a4f72445a636eab1b1c0f816d365c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 4"
+ date="2011-05-14T16:29:35Z"
+ content="""
+Now available as `git-annex reinject`.
+"""]]
diff --git a/doc/bugs/No_progress_bars_with_S3.mdwn b/doc/bugs/No_progress_bars_with_S3.mdwn
new file mode 100644
index 000000000..afa7ba5ee
--- /dev/null
+++ b/doc/bugs/No_progress_bars_with_S3.mdwn
@@ -0,0 +1,26 @@
+## What steps will reproduce the problem?
+
+Add new data to a repository with an S3 special remote. Monitor the repository with the web app.
+
+
+## What is the expected output? What do you see instead?
+
+I expect a changing status bar and percentage. Instead I see no changes when an upload becomes active.
+
+
+## What version of git-annex are you using? On what operating system?
+
+3.20130102 on Arch 64-bit.
+
+
+## Please provide any additional information below.
+
+
+When uploading local data to an S3 remote, I see no progress bars. The progress bar area on active uploads stays the same grey as the bar on queued uploads. The status does not change from "0% of...". The uploads are completing, but this makes it very difficult to judge their activity.
+
+The only remotes I currently have setup are S3 special remotes, so I cannot say whether progress bars are working for uploads to other remote types.
+
+> [[done]], this turned out to be a confusion in the progress code;
+> parts were expecting a full number of bytes since the start, while
+> other parts were sending the number of bytes in a chunk. Result was
+> progress bars stuck at 0% often. --[[Joey]]
diff --git a/doc/bugs/No_progress_bars_with_S3/comment_1_33a601201a9fdd2357f1c03e32fa6b9c._comment b/doc/bugs/No_progress_bars_with_S3/comment_1_33a601201a9fdd2357f1c03e32fa6b9c._comment
new file mode 100644
index 000000000..90d00807d
--- /dev/null
+++ b/doc/bugs/No_progress_bars_with_S3/comment_1_33a601201a9fdd2357f1c03e32fa6b9c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.238"
+ subject="comment 1"
+ date="2013-01-14T16:31:06Z"
+ content="""
+How large are your files? IIRC the S3 progress bar updated with a rather large granularity.
+"""]]
diff --git a/doc/bugs/No_progress_bars_with_S3/comment_2_52361805ced99c22d663b3b1e8a5b221._comment b/doc/bugs/No_progress_bars_with_S3/comment_2_52361805ced99c22d663b3b1e8a5b221._comment
new file mode 100644
index 000000000..04f823e0b
--- /dev/null
+++ b/doc/bugs/No_progress_bars_with_S3/comment_2_52361805ced99c22d663b3b1e8a5b221._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="annexuser"
+ ip="24.16.193.140"
+ subject="comment 2"
+ date="2013-01-14T21:26:18Z"
+ content="""
+4MB to 8MB
+"""]]
diff --git a/doc/bugs/No_progress_bars_with_S3/comment_3_5903c1c40c4562f4fbaccd1640fedb18._comment b/doc/bugs/No_progress_bars_with_S3/comment_3_5903c1c40c4562f4fbaccd1640fedb18._comment
new file mode 100644
index 000000000..c5ed8246f
--- /dev/null
+++ b/doc/bugs/No_progress_bars_with_S3/comment_3_5903c1c40c4562f4fbaccd1640fedb18._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="annexuser"
+ ip="50.125.41.100"
+ subject="comment 3"
+ date="2013-01-19T20:40:27Z"
+ content="""
+Progress bars do work with a USB remote.
+"""]]
diff --git a/doc/bugs/No_progress_bars_with_S3/comment_4_80799c33e513384894b390fe34ab312a._comment b/doc/bugs/No_progress_bars_with_S3/comment_4_80799c33e513384894b390fe34ab312a._comment
new file mode 100644
index 000000000..6c00c43d3
--- /dev/null
+++ b/doc/bugs/No_progress_bars_with_S3/comment_4_80799c33e513384894b390fe34ab312a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="annexuser"
+ ip="50.125.41.100"
+ subject="comment 4"
+ date="2013-01-19T20:41:48Z"
+ content="""
+I should also mention that I've uploaded a handful of 30MB files, and I've seen no progress bars on them.
+"""]]
diff --git a/doc/bugs/No_version_information_from_cli.mdwn b/doc/bugs/No_version_information_from_cli.mdwn
new file mode 100644
index 000000000..a0d30db41
--- /dev/null
+++ b/doc/bugs/No_version_information_from_cli.mdwn
@@ -0,0 +1,18 @@
+git-annex does not listen to -v, --version or version.
+
+At the very least, it should return both the version of the binary and the version of the object store it supports.
+If it supports several annex versions, they should be listed in a comma-separated fashion.
+If git-annex is called from within an annex, it should print the version of the local object store.
+
+Sample:
+
+ % git annex version
+ git-annex version : 0.24
+ default object store version : 3
+ supported object store versions : 2,3
+ local object store version : 2
+ %
+
+The above might look like overkill, but it's in a form that will, most likely, never need to be extended.
+
+> Great idea, [[done]] --[[Joey]]
diff --git a/doc/bugs/OSX_.dmg_unnecessarily_large_and_not_inherently_compressed.mdwn b/doc/bugs/OSX_.dmg_unnecessarily_large_and_not_inherently_compressed.mdwn
new file mode 100644
index 000000000..bf74aebe6
--- /dev/null
+++ b/doc/bugs/OSX_.dmg_unnecessarily_large_and_not_inherently_compressed.mdwn
@@ -0,0 +1,68 @@
+### Please describe the problem.
+
+The .dmg the OSX build is distributed in is unnecessarily large (fixed size) and is externally compressed.
+
+I did a quick survey of .dmg images used for distributing other pieces of software which I had downloaded to my Mac, and most of them seem to be the UDBZ or the (older) UDZO formats which are internally compressed with bzip2 or zlib. According to "man hdiutil", the UDBZ format is supported since 10.4 (Tiger).
+
+Below are a pair of patches: first to enable "make clean" to work on OSX, second to build the .dmg in the UDBZ format and without an explicit size (it seems to infer a correct size). When I tested building it, it results in a .dmg which is slightly smaller than the old .dmg.bz2
+
+(This will also require a change to remove the .bz2 from the download links elsewhere in the wiki.)
+
+<pre>
+From 251e23bbe66cc63e98089554f91b2528a097e818 Mon Sep 17 00:00:00 2001
+From: Mike Magin <git@mike.magin.org>
+Date: Sun, 17 Nov 2013 08:11:05 -0800
+Subject: [PATCH 1/2] Add explicit path to find invocation in "make clean" target.
+
+---
+ Makefile | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/Makefile b/Makefile
+index 3f3ed35..5a0cebb 100644
+--- a/Makefile
++++ b/Makefile
+@@ -83,8 +83,8 @@ clean:
+ Setup Build/InstallDesktopFile Build/EvilSplicer \
+ Build/Standalone Build/OSXMkLibs \
+ git-union-merge git-recover-repository
+- find -name \*.o -exec rm {} \;
+- find -name \*.hi -exec rm {} \;
++ find . -name \*.o -exec rm {} \;
++ find . -name \*.hi -exec rm {} \;
+
+ Build/InstallDesktopFile: Build/InstallDesktopFile.hs
+ $(GHC) --make $@
+--
+1.8.4.3
+
+From e66f767893b5ef70cbf69d420cb589071f88c784 Mon Sep 17 00:00:00 2001
+From: Mike Magin <git@mike.magin.org>
+Date: Sun, 17 Nov 2013 08:40:07 -0800
+Subject: [PATCH 2/2] Change .dmg build to include compression and not be fixed size.
+
+---
+ Makefile | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/Makefile b/Makefile
+index 5a0cebb..b6ac549 100644
+--- a/Makefile
++++ b/Makefile
+@@ -162,10 +162,9 @@ osxapp: Build/Standalone Build/OSXMkLibs
+
+ ./Build/OSXMkLibs $(OSXAPP_BASE)
+ rm -f tmp/git-annex.dmg
+- hdiutil create -size 640m -format UDRW -srcfolder tmp/build-dmg \
++ hdiutil create -format UDBZ -srcfolder tmp/build-dmg \
+ -volname git-annex -o tmp/git-annex.dmg
+ rm -f tmp/git-annex.dmg.bz2
+- bzip2 --fast tmp/git-annex.dmg
+
+ ANDROID_FLAGS?=-f-XMPP
+ # Cross compile for Android.
+--
+1.8.4.3
+</pre>
+
+> Ah, that never seemed optimal. [[done]] --[[Joey]]
diff --git a/doc/bugs/OSX_alias_permissions_and_versions_problem.mdwn b/doc/bugs/OSX_alias_permissions_and_versions_problem.mdwn
new file mode 100644
index 000000000..f4ebc9d1e
--- /dev/null
+++ b/doc/bugs/OSX_alias_permissions_and_versions_problem.mdwn
@@ -0,0 +1,37 @@
+What steps will reproduce the problem?
+
+Use assistant and create repository the a folder in home dir.
+Use textedit and save a new txt to the repository folder.
+
+What is the expected output? What do you see instead?
+
+The alias solution is broken. It should work more like Dropbox.
+Textedit saves the file initially, but it is immediately locked.
+Since it autosaves, it asks to unlock or duplicate.
+Then gives the error:
+"The file “Untitled 16.txt” cannot be unlocked."
+
+If the file exists:
+The document “Untitled 14” could not be saved as “Untitled 14.txt”. You don’t have permission.
+
+If you open a file from the repository (now replaced by a symlink) with textedit, there are other problems:
+- The filename will not be correct (will show the sha hash).
+- It will ask to unlock, then give the error "You don’t have permission to write to the folder that the file “SHA256E-s8--8985d9832de2e28b5e1af64258c391a34d7528709ef916bac496e698c139020c.txt” is in."
+
+What version of git-annex are you using? On what operating system?
+
+OSX Lion
+git-annex version: 3.20120924
+
+Please provide any additional information below.
+
+Even if you fix these problems, automatic versioning in lion will probably don't work, and the symlinks seem a hackish solution and don't seem intuitive or easy to the end user.
+The sync should be transparent but it's not, and it's error prone. It would even be best to keep file copies in the git repo and sync them with the original folder than make symlinks.
+
+Dropbox even allows to put a symlink in the dropbox directory, and it will sync the file.
+
+[[!tag /design/assistant/OSX]]
+
+> Now the assistant creates new repositories using direct mode on OSX.
+> In direct mode, there is no locking of files; they can be modified
+> directly. [[done]] --[[Joey]]
diff --git a/doc/bugs/OSX_alias_permissions_and_versions_problem/comment_1_4fabe32e7e626e6ca23aa0b6f449c4c6._comment b/doc/bugs/OSX_alias_permissions_and_versions_problem/comment_1_4fabe32e7e626e6ca23aa0b6f449c4c6._comment
new file mode 100644
index 000000000..74a20d08e
--- /dev/null
+++ b/doc/bugs/OSX_alias_permissions_and_versions_problem/comment_1_4fabe32e7e626e6ca23aa0b6f449c4c6._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlatTbI0K-qydpeYHl37iseqPNvERcdIMk"
+ nickname="Tiago"
+ subject="comment 1"
+ date="2012-09-26T23:38:51Z"
+ content="""
+After looking more into the git annex working, I understand the use of symlinks, but they are not always correctly handled by OSX.
+
+
+Apple's Timemachine uses hardlinks for example...
+
+
+Not being able to easily edit files that are in the repo without problems or quirks makes it unusable as a dropbox replacement and version control, which is a shame.
+"""]]
diff --git a/doc/bugs/OSX_alias_permissions_and_versions_problem/comment_2_064d60fcc8366a70958540bc145e611a._comment b/doc/bugs/OSX_alias_permissions_and_versions_problem/comment_2_064d60fcc8366a70958540bc145e611a._comment
new file mode 100644
index 000000000..78125262e
--- /dev/null
+++ b/doc/bugs/OSX_alias_permissions_and_versions_problem/comment_2_064d60fcc8366a70958540bc145e611a._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlatTbI0K-qydpeYHl37iseqPNvERcdIMk"
+ nickname="Tiago"
+ subject="comment 2"
+ date="2012-09-26T23:50:55Z"
+ content="""
+It seems many people complain about symlink behavior in Lion and Mountain Lion.
+I never used symlinks to files often, only to folders.
+I hope you can solve this problems and make it work correctly in OSX, or use hardlinks instead.
+Git annex sound awesome, but the people using the assistant will want KISS behavior, and don't even know what a symbolic link is.
+"""]]
diff --git a/doc/bugs/OSX_alias_permissions_and_versions_problem/comment_3_6c72d4f40ea0a9566a1185901beff5ba._comment b/doc/bugs/OSX_alias_permissions_and_versions_problem/comment_3_6c72d4f40ea0a9566a1185901beff5ba._comment
new file mode 100644
index 000000000..8ef5e6cc5
--- /dev/null
+++ b/doc/bugs/OSX_alias_permissions_and_versions_problem/comment_3_6c72d4f40ea0a9566a1185901beff5ba._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlatTbI0K-qydpeYHl37iseqPNvERcdIMk"
+ nickname="Tiago"
+ subject="comment 3"
+ date="2012-09-26T23:57:18Z"
+ content="""
+Ok, so it seems Sharebox solves all this problems...you might want to integrate sharebox into the assistant, so non-techie people can treat the repos as mutable.
+Maybe make a mutable/unmutable toggle in the gui or somethink like that?
+
+What I don't understand is the need for kqueue, if the files are not supposed to be written to without unlocking, why not use FSEvents and only monitor the folders for new files.
+
+http://git-annex.branchable.com/news/sharebox_a_FUSE_filesystem_for_git-annex
+
+"""]]
diff --git a/doc/bugs/OSX_alias_permissions_and_versions_problem/comment_4_8a11f404bb72a1aeb2290744cce2d00d._comment b/doc/bugs/OSX_alias_permissions_and_versions_problem/comment_4_8a11f404bb72a1aeb2290744cce2d00d._comment
new file mode 100644
index 000000000..aeacce31e
--- /dev/null
+++ b/doc/bugs/OSX_alias_permissions_and_versions_problem/comment_4_8a11f404bb72a1aeb2290744cce2d00d._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlatTbI0K-qydpeYHl37iseqPNvERcdIMk"
+ nickname="Tiago"
+ subject="comment 4"
+ date="2012-09-27T00:06:31Z"
+ content="""
+Seems sharebox development stopped a year ago...now that you are working on the assistant, which sound awesome, I think you really should consider pick up the sharebox development and integrate it.
+
+Too bad I missed kickstarter, but I might donate now.
+I just find it wierd that it said \"Like Dropbox\" on the title, but sharebox-like functionality is not on the roadmap, and being able to easily edit the files is a big feature of dropbox.
+
+"""]]
diff --git a/doc/bugs/OSX_alias_permissions_and_versions_problem/comment_5_30888607199d6a48b76d0c48f5aa4f64._comment b/doc/bugs/OSX_alias_permissions_and_versions_problem/comment_5_30888607199d6a48b76d0c48f5aa4f64._comment
new file mode 100644
index 000000000..d95d8f149
--- /dev/null
+++ b/doc/bugs/OSX_alias_permissions_and_versions_problem/comment_5_30888607199d6a48b76d0c48f5aa4f64._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/2grhJvAC049fJnvALDXek.6MRZMTlg--#eec89"
+ nickname="John"
+ subject="I agree"
+ date="2012-10-18T07:11:20Z"
+ content="""
+I really can't think of any way that Git annex + the assistant is like Dropbox. The Annex is not usable for even a single of the uses cases for which I also use Dropbox. I think this \"branding\" of annex should be dropped, or else it actually needs to acquire the features of Dropbox.
+"""]]
diff --git a/doc/bugs/OSX_app_issues.mdwn b/doc/bugs/OSX_app_issues.mdwn
new file mode 100644
index 000000000..95a34eff4
--- /dev/null
+++ b/doc/bugs/OSX_app_issues.mdwn
@@ -0,0 +1,6 @@
+This is a collection of problem reports for the standalone OSX app.
+If you have a problem using it, post it here. --[[Joey]]
+
+(Some things that should be fixed now have been moved to [[old]].)
+
+[[!tag /design/assistant/OSX]]
diff --git a/doc/bugs/OSX_app_issues/comment_10_54d8f3e429df9a9958370635c890abf0._comment b/doc/bugs/OSX_app_issues/comment_10_54d8f3e429df9a9958370635c890abf0._comment
new file mode 100644
index 000000000..cad356c67
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/comment_10_54d8f3e429df9a9958370635c890abf0._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.3.194"
+ subject="comment 10"
+ date="2013-01-19T16:13:20Z"
+ content="""
+The app uses the version of git included in it, because using the system's installed version if there is one is likely to run into other version incompatabilities.
+
+You can either install git-annex using cabal and homebrew, as documented, or you could go in and delete
+all the git programs out of the app, and then it'd use the system's git stuff instead.
+"""]]
diff --git a/doc/bugs/OSX_app_issues/comment_10_6d23232fbb15d0ee3ab532a4884f81ed._comment b/doc/bugs/OSX_app_issues/comment_10_6d23232fbb15d0ee3ab532a4884f81ed._comment
new file mode 100644
index 000000000..230b40758
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/comment_10_6d23232fbb15d0ee3ab532a4884f81ed._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 10"
+ date="2013-04-16T17:14:13Z"
+ content="""
+@Jeremy, it's been a long time since anyone reported having the \"LSOpenURLsWithRole()\". It seemed to go away when the dmg was fixed to include all the necessary libraries. So my guess is you installed it wrong, somehow, and perhaps it's not finding those libraries that are part of the dmg.
+
+You should be able to start the assistant by running it directly from the dmg.
+"""]]
diff --git a/doc/bugs/OSX_app_issues/comment_11_5db2baa771fd01a284eac8a16c1c8c67._comment b/doc/bugs/OSX_app_issues/comment_11_5db2baa771fd01a284eac8a16c1c8c67._comment
new file mode 100644
index 000000000..1760b1aa8
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/comment_11_5db2baa771fd01a284eac8a16c1c8c67._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlkAghrKEvslMcV2INKUhtPPMsfnzQyyd8"
+ nickname="Jeremy"
+ subject="comment 11"
+ date="2013-04-17T02:02:00Z"
+ content="""
+@joey, figured it out. There was a program added to the startup list, presumably from when I ran things from the dmg a while ago. Once I delete that, it started fine. Of course, I forgot to write down the name of the program... I remember it had an LW in the name.
+"""]]
diff --git a/doc/bugs/OSX_app_issues/comment_11_bb2ceb95a844449795addee6986d0763._comment b/doc/bugs/OSX_app_issues/comment_11_bb2ceb95a844449795addee6986d0763._comment
new file mode 100644
index 000000000..b3bbf6077
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/comment_11_bb2ceb95a844449795addee6986d0763._comment
@@ -0,0 +1,26 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlYy4BrJyV1PdfqzevCVziXRp89iUH6Xzw"
+ nickname="Christopher"
+ subject="Code signing errors in log on starting git-annex.app"
+ date="2013-01-19T22:30:32Z"
+ content="""
+When I run via the App and set up a fresh repo, i get some Console.app spam (looks like one per file added to the repo dir... or maybe one per git command?):
+
+ 2013-01-19 2:44:55.000 PM kernel[0]: CODE SIGNING: cs_invalid_page(0x1008b4000): p=73995[git] clearing CS_VALID
+ 2013-01-19 2:44:55.000 PM kernel[0]: CODE SIGNING: cs_invalid_page(0x10f99e000): p=73996[git] clearing CS_VALID
+ 2013-01-19 2:44:55.000 PM kernel[0]: CODE SIGNING: cs_invalid_page(0x102b44000): p=73997[git] clearing CS_VALID
+ 2013-01-19 2:44:55.000 PM kernel[0]: CODE SIGNING: cs_invalid_page(0x1029f4000): p=73998[git] clearing CS_VALID
+ ...
+
+and nothing seems to work. The page address and the pid increment steadily with each line. I'm using 10.8.2 (12C60) on a Mac Pro, and grabbed:
+
+ /git-annex/OSX/current/10.8.2_Mountain_Lion/git-annex.dmg.bz2
+
+(published 14-Jan-2013 15:19)
+
+It seems to be a code signing issue, perhaps with the vendored git binaries. While things are sort-of working, the web app shows the files flying by really fast.
+
+Using a fresh repo via `git annex webapp` works great (I built that after much teeth-knashing, brew install/link cycles, and then cabal install git-annex).
+
+I am very excited for this to work, this is exactly what I've been waiting for to replace dropbox. Came very close to writing it myself a few times (and in Haskell no less!!).
+"""]]
diff --git a/doc/bugs/OSX_app_issues/comment_12_62170597c7f441d84d48986857998858._comment b/doc/bugs/OSX_app_issues/comment_12_62170597c7f441d84d48986857998858._comment
new file mode 100644
index 000000000..597a1a195
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/comment_12_62170597c7f441d84d48986857998858._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkCw26IdxXXPBoLcZsQFslM67OJSJynb1w"
+ nickname="Alexander"
+ subject="standalone app dmg won't open in OSX 10.8.3"
+ date="2013-04-29T18:05:54Z"
+ content="""
+I downloaded the app build from [http://downloads.kitenet.net/git-annex/OSX/current/10.8.2_Mountain_Lion/](http://downloads.kitenet.net/git-annex/OSX/current/10.8.2_Mountain_Lion/) and unpacked it, but the .dmg won't open. I can run other dmg's successfully.
+
+Trying to install git-annex via cabal on the same machine led to this issue: [http://git-annex.branchable.com/tips/Building_git-annex_on_Debian_OR___37____164____35____34____164____37____38____34____35___Haskell__33__/#comment-7cc94df1bf9a75a6d03369f3897d6816](http://git-annex.branchable.com/tips/Building_git-annex_on_Debian_OR___37____164____35____34____164____37____38____34____35___Haskell__33__/#comment-7cc94df1bf9a75a6d03369f3897d6816)
+"""]]
diff --git a/doc/bugs/OSX_app_issues/comment_12_f3bc5a4e4895ac9351786f0bdd8005ba._comment b/doc/bugs/OSX_app_issues/comment_12_f3bc5a4e4895ac9351786f0bdd8005ba._comment
new file mode 100644
index 000000000..460465b81
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/comment_12_f3bc5a4e4895ac9351786f0bdd8005ba._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmYiJgOvC4IDYkr2KIjMlfVD9r_1Sij_jY"
+ nickname="Douglas"
+ subject="Error creating remote repository using ssh on OSX"
+ date="2013-01-25T13:18:40Z"
+ content="""
+There is an issue with creating remote repositories using ssh (the problem may require using a different account name.) I filed the following bug:
+
+
+<http://git-annex.branchable.com/bugs/Error_creating_remote_repository_using_ssh_on_OSX/>
+"""]]
diff --git a/doc/bugs/OSX_app_issues/comment_13_cb12d419459e5cac766022ee0697fedc._comment b/doc/bugs/OSX_app_issues/comment_13_cb12d419459e5cac766022ee0697fedc._comment
new file mode 100644
index 000000000..c9e199961
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/comment_13_cb12d419459e5cac766022ee0697fedc._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="John"
+ ip="109.242.130.160"
+ subject="runshell typo prevents execution"
+ date="2013-09-22T00:24:10Z"
+ content="""
+Using the latest Mountain Lion build available.
+
+>$ /Applications/git-annex.app/Contents/MacOS/git-annex
+
+>/Applications/git-annex.app/Contents/MacOS/runshell: line 25: syntax error near unexpected token `&'
+
+Line 25:
+>echo \"** runshell loop detected!\"> &2
+
+Fix (obvious but for the sake of completeness):
+>echo \"** runshell loop detected!\" >&2
+"""]]
diff --git a/doc/bugs/OSX_app_issues/comment_14_c966fa549bc73c52034ac9abc49de52a._comment b/doc/bugs/OSX_app_issues/comment_14_c966fa549bc73c52034ac9abc49de52a._comment
new file mode 100644
index 000000000..df45eb601
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/comment_14_c966fa549bc73c52034ac9abc49de52a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.1.250"
+ subject="comment 14"
+ date="2013-09-22T14:15:28Z"
+ content="""
+I have fixed the runshell typo and updated the builds.
+"""]]
diff --git a/doc/bugs/OSX_app_issues/comment_15_10f1df95266f1a8c9ef933183190f6e2._comment b/doc/bugs/OSX_app_issues/comment_15_10f1df95266f1a8c9ef933183190f6e2._comment
new file mode 100644
index 000000000..bdb0b55fa
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/comment_15_10f1df95266f1a8c9ef933183190f6e2._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="gueux"
+ ip="2a01:240:fe6d:0:8947:cf55:f955:49b9"
+ subject="same typo on Lion build"
+ date="2013-10-23T09:17:58Z"
+ content="""
+Could you please fix this typo on the Lion build?
+"""]]
diff --git a/doc/bugs/OSX_app_issues/comment_16_064e151da121f9c2ef13c19ecb4e7458._comment b/doc/bugs/OSX_app_issues/comment_16_064e151da121f9c2ef13c19ecb4e7458._comment
new file mode 100644
index 000000000..8569bda7c
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/comment_16_064e151da121f9c2ef13c19ecb4e7458._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="Remy"
+ ip="83.87.21.84"
+ subject="Crashes on OSX 10.9"
+ date="2013-10-23T20:30:12Z"
+ content="""
+I just installed OSX Mavericks. I also took the latest autobuild and copied it over the old git-annex.app to be sure it doesn't work.
+When I execute \"git-annex status\" I get the following message
+
+
+> dyld: Symbol not found: _objc_debug_taggedpointer_mask
+> Referenced from: /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
+> Expected in: /Applications/git-annex.app/Contents/MacOS/bundle/I
+> in /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
+> [1] 1361 trace trap git-annex status
+"""]]
diff --git a/doc/bugs/OSX_app_issues/comment_17_0e6ac5e0a54ce78bdc56c62e6fb92846._comment b/doc/bugs/OSX_app_issues/comment_17_0e6ac5e0a54ce78bdc56c62e6fb92846._comment
new file mode 100644
index 000000000..5d5c0237e
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/comment_17_0e6ac5e0a54ce78bdc56c62e6fb92846._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="calmyournerves"
+ ip="85.3.250.239"
+ subject="comment 17"
+ date="2013-10-24T21:43:37Z"
+ content="""
+For 10.9 Mavericks see http://git-annex.branchable.com/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/#comments
+"""]]
diff --git a/doc/bugs/OSX_app_issues/comment_2_fd560811c57df5cbc3976639642b8b19._comment b/doc/bugs/OSX_app_issues/comment_2_fd560811c57df5cbc3976639642b8b19._comment
new file mode 100644
index 000000000..2107390be
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/comment_2_fd560811c57df5cbc3976639642b8b19._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkN91jAhoesnVI9TtWANaBPaYjd1V9Pag8"
+ nickname="Benjamin"
+ subject="Package for older OS X"
+ date="2012-11-17T12:36:45Z"
+ content="""
+Is there an option to provide application bundle for older versions of OS X? The last time I tried the bundle wouldn't work under 10.5. If no specific features from newer OS X versions are required, it could be enough to add a simple switch when building.
+"""]]
diff --git a/doc/bugs/OSX_app_issues/comment_7_93e0bb53ac2d7daef53426fbdc5f92d9._comment b/doc/bugs/OSX_app_issues/comment_7_93e0bb53ac2d7daef53426fbdc5f92d9._comment
new file mode 100644
index 000000000..fccd9fb3f
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/comment_7_93e0bb53ac2d7daef53426fbdc5f92d9._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkurjhi0CRJvgm7QNaZDWS9hitBtavqIpc"
+ nickname="Bret"
+ subject="git-annex.app Not working on 32 bit machines"
+ date="2012-11-03T19:18:47Z"
+ content="""
+I tried running the git-annex.app on my Core Duo Macbook pro, and it does not run at all. I get an error on my system.log
+
+`Nov 3 12:13:26 Bret-Mac [0x0-0x15015].com.branchable.git-annex[155]: /Applications/git-annex.app/Contents/MacOS/runshell: line 52: /Applications/git-annex.app/Contents/MacOS/bin/git-annex: Bad CPU type in executable
+Nov 3 12:13:26 Bret-Mac com.apple.launchd.peruser.501[92] ([0x0-0x15015].com.branchable.git-annex[155]): Exited with exit code: 1`
+
+It works on my 64 bit machine, and this has become quite the problem for a while now, where people with newer macs dont compile back for a 32bit machine.
+
+Is there any hope for a pre-compiled binary that works on a 32 bit machine?
+"""]]
diff --git a/doc/bugs/OSX_app_issues/comment_8_141eac2f3fb25fe18b4268786f00ad6a._comment b/doc/bugs/OSX_app_issues/comment_8_141eac2f3fb25fe18b4268786f00ad6a._comment
new file mode 100644
index 000000000..f7b1f2281
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/comment_8_141eac2f3fb25fe18b4268786f00ad6a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 8"
+ date="2012-11-07T16:08:00Z"
+ content="""
+I've been updating my haskell platform install recently, i used to try and get the builder to spit out 32/64bit binaries, but recently it's just become too messy, I've just migrated to a full 64bit build system. I'm afraid I won't be able to provide 32bit builds any more.
+"""]]
diff --git a/doc/bugs/OSX_app_issues/comment_8_f4d5b2645d7f29b80925159efb94a998._comment b/doc/bugs/OSX_app_issues/comment_8_f4d5b2645d7f29b80925159efb94a998._comment
new file mode 100644
index 000000000..3a4ca0b57
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/comment_8_f4d5b2645d7f29b80925159efb94a998._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmOsimKUgz6rxpmsS_nrBQGavEYyUpDlsE"
+ nickname="Tim"
+ subject="OS X 10.8.2"
+ date="2013-01-11T00:07:54Z"
+ content="""
+Double click on the app, give permission for it to run and ... nothing
+"""]]
diff --git a/doc/bugs/OSX_app_issues/comment_9_2e6dfca0fd8df04066769653724eae28._comment b/doc/bugs/OSX_app_issues/comment_9_2e6dfca0fd8df04066769653724eae28._comment
new file mode 100644
index 000000000..8b9fcbc68
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/comment_9_2e6dfca0fd8df04066769653724eae28._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmRFKwny4rArBaz-36xTcsJYqKIgdDaw5Q"
+ nickname="Andrew"
+ subject="Prefer the system/path git binaries if they're a newer version"
+ date="2013-01-19T06:20:38Z"
+ content="""
+I have used homebrew to install git v1.8.0.2 but git-annex.app packages git v1.7.10.2. git 1.7 crashes due to some newer directives in my global git config.
+
+ error: Malformed value for push.default: simple
+ error: Must be one of nothing, matching, tracking or current.
+ fatal: bad config file line 38 in /Users/akraut/.gitconfig
+
+ git-annex: fd:13: hGetLine: end of file
+ failed
+ git-annex: webapp: 1 failed
+
+"""]]
diff --git a/doc/bugs/OSX_app_issues/comment_9_e1bbe83a1b9a7385ed6d443d0cc22bc7._comment b/doc/bugs/OSX_app_issues/comment_9_e1bbe83a1b9a7385ed6d443d0cc22bc7._comment
new file mode 100644
index 000000000..91df3c388
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/comment_9_e1bbe83a1b9a7385ed6d443d0cc22bc7._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlkAghrKEvslMcV2INKUhtPPMsfnzQyyd8"
+ nickname="Jeremy"
+ subject="Unable to start assistant"
+ date="2013-04-16T01:07:05Z"
+ content="""
+I got the git-annex assistant to work once a long time ago when I ran it the first time directly from the dmg. Ever since then (i.e., after putting it in my applications folder) I have never gotten it to run. Wondering if anyone else has experienced this?
+
+I am running OSX 10.7.5 and just pulled the latest app (05-Apr-2013 10:17).
+
+For reference, when I try to kick off the the assistant from the command line I get the error:
+
+ $ open /Applications/git-annex.app
+ LSOpenURLsWithRole() failed with error -10810 for the file /Applications/git-annex.app.
+
+I am wondering if there is some sort of file or modification that was made when I accidently kicked it off initially from the dmg, if so any thoughts on what to clear / change?
+
+"""]]
diff --git a/doc/bugs/OSX_app_issues/old.mdwn b/doc/bugs/OSX_app_issues/old.mdwn
new file mode 100644
index 000000000..42f77125d
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/old.mdwn
@@ -0,0 +1 @@
+These issues should be fixed now.
diff --git a/doc/bugs/OSX_app_issues/old/comment_10_bb823dc3cd6dc914ed14c176afa0b2f3._comment b/doc/bugs/OSX_app_issues/old/comment_10_bb823dc3cd6dc914ed14c176afa0b2f3._comment
new file mode 100644
index 000000000..857cf3a62
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/old/comment_10_bb823dc3cd6dc914ed14c176afa0b2f3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://wiggy.net/"
+ nickname="Wichert"
+ subject="Re: Trying to add remote server after failed attempt blocks forever"
+ date="2012-11-28T21:26:36Z"
+ content="""
+It appears to not just wait forever: there was also a **git config --null --list** process taking all CPU.
+"""]]
diff --git a/doc/bugs/OSX_app_issues/old/comment_11_a30e69fed14b0809184ffe05358ab871._comment b/doc/bugs/OSX_app_issues/old/comment_11_a30e69fed14b0809184ffe05358ab871._comment
new file mode 100644
index 000000000..a25514ba9
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/old/comment_11_a30e69fed14b0809184ffe05358ab871._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.49"
+ subject="comment 11"
+ date="2012-11-29T19:55:17Z"
+ content="""
+I've dealt with these ssh issues by including ssh in the app bundle.
+
+OTOH, I don't know how `git config --null --list` could possibly take any appreciable amount of CPU to run.
+"""]]
diff --git a/doc/bugs/OSX_app_issues/old/comment_12_23d47b3696e537d60df1d383f33f19e4._comment b/doc/bugs/OSX_app_issues/old/comment_12_23d47b3696e537d60df1d383f33f19e4._comment
new file mode 100644
index 000000000..73a5d1345
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/old/comment_12_23d47b3696e537d60df1d383f33f19e4._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnqQyhiNXdPIWWSuu232luY5nc-h5RS8bE"
+ nickname="Arve"
+ subject="Make Repository hangs (git consuming 100% cpu)"
+ date="2012-12-01T01:26:04Z"
+ content="""
+When starting git-annex from Applications first time (Finder or spotlight), pressing \"Make Repository\" hangs.
+
+\"ps aux | grep git\" shows
+arve 1723 100.0 0.0 2459668 3988 ?? R 2:00AM 0:31.30 git init --quiet /Users/arve/Desktop/annex/
+
+Strange enough, if i start the app from terminal (/Applications/git-annex.app/Contents/MacOS/git-annex-webapp), the creation of repository works. Though, if I kill it and start git-annex from spotlight, the web frontend doesn't show, and \"git config --null --list\" is consuming 100% cpu.
+
+My OSX version is 10.8.1
+"""]]
diff --git a/doc/bugs/OSX_app_issues/old/comment_13_be5738b42b13ec8cd828c5fa66f030e8._comment b/doc/bugs/OSX_app_issues/old/comment_13_be5738b42b13ec8cd828c5fa66f030e8._comment
new file mode 100644
index 000000000..8a9ee061a
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/old/comment_13_be5738b42b13ec8cd828c5fa66f030e8._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.49"
+ subject="comment 13"
+ date="2012-12-01T18:50:31Z"
+ content="""
+So it works with a controlling console, and git commands are somehow misbehaving without a controlling console. Very strange.
+
+Any chance you can `dtrace -p` the stuck git processes to see what they're doing or what resource they're blocked on?
+"""]]
diff --git a/doc/bugs/OSX_app_issues/old/comment_14_5783a4716cd104e1f1c276aa0b9cb153._comment b/doc/bugs/OSX_app_issues/old/comment_14_5783a4716cd104e1f1c276aa0b9cb153._comment
new file mode 100644
index 000000000..a88a0047e
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/old/comment_14_5783a4716cd104e1f1c276aa0b9cb153._comment
@@ -0,0 +1,41 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkfHTPsiAcHEEN7Xl7WxiZmYq-vX7azxFY"
+ nickname="Vincent"
+ subject="OS/X build 2012-12-12"
+ date="2012-12-13T00:59:51Z"
+ content="""
+I installed this today from the .dmg.bz2, md5sum 1bb50b3ee5eda3cd7f4b4a70cdae1855 on OS/X 10.8.2
+
+uname -a
+Darwin foo 12.2.0 Darwin Kernel Version 12.2.0: Sat Aug 25 00:48:52 PDT 2012; root:xnu-2050.18.24~1/RELEASE_X86_64 x86_64
+
+I installed the app to the Applications folder.
+
+I had chrome and firefox running, recent versions.
+
+Double-click and it opens a new chrome window. This came up behind the existing (iconified) window. A nit, but just so you know.
+
+The configuration part of the app is shown, so far so good.
+I type in the path I want it to use (~/work/annex) and press the create button.
+It hangs forever trying to access localhost:55163
+
+ $ ps aux|grep git
+ me 85291 100.0 0.0 2460884 4160 ?? R 11:42am 12:03.72 git init --quiet /Users/me/work/annex/
+ me 85233 0.0 0.3 2687204 44064 ?? S 11:42am 0:00.44 git-annex webapp -psn_0_50204638
+ me 85226 0.0 0.0 2433432 868 ?? S 11:42am 0:00.00 /bin/sh /Applications/git-annex.app/Contents/MacOS/git-annex-webapp -psn_0_50204638
+ me 85515 0.0 0.0 2432768 620 s000 S+ 11:54am 0:00.00 grep git
+
+ $ netstat -an |grep 55163
+ tcp4 0 0 127.0.0.1.55163 127.0.0.1.55207 CLOSE_WAIT
+ tcp4 0 0 127.0.0.1.55163 127.0.0.1.55206 CLOSE_WAIT
+ tcp4 0 0 127.0.0.1.55163 127.0.0.1.55205 CLOSE_WAIT
+ tcp4 0 0 127.0.0.1.55163 127.0.0.1.55201 ESTABLISHED
+ tcp4 0 0 127.0.0.1.55201 127.0.0.1.55163 ESTABLISHED
+ tcp4 0 0 127.0.0.1.55163 127.0.0.1.55199 CLOSE_WAIT
+ tcp4 0 0 127.0.0.1.55163 127.0.0.1.55197 CLOSE_WAIT
+ tcp4 0 0 127.0.0.1.55163 *.* LISTEN
+
+I was plugged into wired ethernet, no other interfaces up, no VPN.
+
+I have macports but no haskell packages, which ghc returns nothing.
+"""]]
diff --git a/doc/bugs/OSX_app_issues/old/comment_14_e126d87a263f3aa6261f72ee7ff086fc._comment b/doc/bugs/OSX_app_issues/old/comment_14_e126d87a263f3aa6261f72ee7ff086fc._comment
new file mode 100644
index 000000000..30e9c40cb
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/old/comment_14_e126d87a263f3aa6261f72ee7ff086fc._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnqQyhiNXdPIWWSuu232luY5nc-h5RS8bE"
+ nickname="Arve"
+ subject="comment 14"
+ date="2012-12-01T22:33:21Z"
+ content="""
+\"dtrace -p pid\" gives \"dtrace: no probes specified.\" I've tried to read man dtrace, and some online resources, dtrace is new to me. Any directions?
+"""]]
diff --git a/doc/bugs/OSX_app_issues/old/comment_15_56c7fcafc7dca8be28ebf9e37a8f6b71._comment b/doc/bugs/OSX_app_issues/old/comment_15_56c7fcafc7dca8be28ebf9e37a8f6b71._comment
new file mode 100644
index 000000000..1cf4916f5
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/old/comment_15_56c7fcafc7dca8be28ebf9e37a8f6b71._comment
@@ -0,0 +1,23 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkfHTPsiAcHEEN7Xl7WxiZmYq-vX7azxFY"
+ nickname="Vincent"
+ subject="comment 15"
+ date="2012-12-13T01:04:44Z"
+ content="""
+following up to #14.
+
+ dtruss -p <git --init process>
+
+shows the same symptom as reported earlier
+ SYSCALL(args) = return
+ workq_kernreturn(0x1, 0x10F31E000, 0x0) = -1 Err#22
+ workq_kernreturn(0x1, 0x10F31E000, 0x0) = -1 Err#22
+ workq_kernreturn(0x1, 0x10F31E000, 0x0) = -1 Err#22
+ workq_kernreturn(0x1, 0x10F31E000, 0x0) = -1 Err#22
+ workq_kernreturn(0x1, 0x10F31E000, 0x0) = -1 Err#22
+ workq_kernreturn(0x1, 0x10F31E000, 0x0) = -1 Err#22
+ ...
+ workq_kernreturn(0x1, 0x10F31E000, 0x0) = -1 Err#22
+ dtrace: 339527 drops on CPU 0
+
+"""]]
diff --git a/doc/bugs/OSX_app_issues/old/comment_15_e58bd3d66f0f43c159d2b37172f152de._comment b/doc/bugs/OSX_app_issues/old/comment_15_e58bd3d66f0f43c159d2b37172f152de._comment
new file mode 100644
index 000000000..2ae192646
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/old/comment_15_e58bd3d66f0f43c159d2b37172f152de._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.49"
+ subject="comment 15"
+ date="2012-12-01T22:49:54Z"
+ content="""
+Seems the command I was thinking of is really `dtruss -p`
+"""]]
diff --git a/doc/bugs/OSX_app_issues/old/comment_16_01f2c968bad66b0ff0c09eb468325deb._comment b/doc/bugs/OSX_app_issues/old/comment_16_01f2c968bad66b0ff0c09eb468325deb._comment
new file mode 100644
index 000000000..5c076012f
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/old/comment_16_01f2c968bad66b0ff0c09eb468325deb._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnqQyhiNXdPIWWSuu232luY5nc-h5RS8bE"
+ nickname="Arve"
+ subject="comment 16"
+ date="2012-12-01T22:53:29Z"
+ content="""
+Returns alot of \"workq_kernreturn(0x1, 0x107D27000, 0x0) = -1 Err#22\" and occasionally \"dtrace: 36244 drops on CPU 1\"
+"""]]
diff --git a/doc/bugs/OSX_app_issues/old/comment_16_0b7cd3d5952c5abf36a89a68a4afc1e7._comment b/doc/bugs/OSX_app_issues/old/comment_16_0b7cd3d5952c5abf36a89a68a4afc1e7._comment
new file mode 100644
index 000000000..0b110ce52
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/old/comment_16_0b7cd3d5952c5abf36a89a68a4afc1e7._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.117"
+ subject="comment 16"
+ date="2012-12-13T22:40:59Z"
+ content="""
+Today's daily build of the OSX app has a further change that *might* help. I removed the system library and frameworks from the bundle.
+"""]]
diff --git a/doc/bugs/OSX_app_issues/old/comment_17_82d9963e1fbf17644ce697e5a43943f5._comment b/doc/bugs/OSX_app_issues/old/comment_17_82d9963e1fbf17644ce697e5a43943f5._comment
new file mode 100644
index 000000000..f710878c2
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/old/comment_17_82d9963e1fbf17644ce697e5a43943f5._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.49"
+ subject="comment 17"
+ date="2012-12-01T23:08:50Z"
+ content="""
+Doesn't say anything to me..
+
+Using nohup might help, or at least get us an error message to see. Edit `git-annex.app/Contents/MacOS/git-annex-webapp` and make the last line:
+
+<pre>
+nohup \"$base/runshell\" git-annex webapp \"$@\"
+</pre>
+
+It'll put a nohup.out log file in your home directory, or somewhere like that.
+"""]]
diff --git a/doc/bugs/OSX_app_issues/old/comment_17_c2de94a48e7958b9efffd89dda9144ff._comment b/doc/bugs/OSX_app_issues/old/comment_17_c2de94a48e7958b9efffd89dda9144ff._comment
new file mode 100644
index 000000000..83c2023db
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/old/comment_17_c2de94a48e7958b9efffd89dda9144ff._comment
@@ -0,0 +1,59 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkfHTPsiAcHEEN7Xl7WxiZmYq-vX7azxFY"
+ nickname="Vincent"
+ subject="OS/X daily 2012-12-13"
+ date="2012-12-14T09:22:42Z"
+ content="""
+Thanks for the update - I tried again, similar results.
+
+same platform. installed image md5sum 1bb50b3ee5eda3cd7f4b4a70cdae1855
+
+Procedure was the same.
+ - download, bunzip2, mount, drag app to Applications.
+ - chrome had one tab open, iconified
+ - double-click application icon
+
+Chrome opens up and shows the config window. Type in the same path
+after checking that the final element of the path did not already exist.
+
+ ps aux|grep git
+ me 89194 99.0 0.0 2460884 4160 ?? R 8:03pm 0:12.58 git init --quiet /Users/me/me/annex/
+ me 89245 0.2 0.0 2423356 220 s001 R+ 8:07pm 0:00.00 grep git
+ me 89182 0.0 0.3 2668772 44208 ?? S 8:03pm 0:00.30 git-annex webapp -psn_0_55022710
+ me 89177 0.0 0.0 2433432 868 ?? S 8:03pm 0:00.00 /bin/sh /Applications/git-annex.app/Contents/MacOS/git-annex-webapp -psn_0_55022710
+
+I ran dtruss on the two processes of interest, including when I sent them kill -9 in case that showed anything of interest.
+Mail me if you need that but the gist is git init was doing
+
+ workq_kernreturn(0x1, 0x1019CC000, 0x0) = -1 Err#22
+ workq_kernreturn(0x1, 0x1019CC000, 0x0) = -1 Err#22
+ workq_kernreturn(0x1, 0x1019CC000, 0x0) = -1 Err#22
+ ...
+ workq_kernreturn(0x1, 0x1019CC000, 0x0) = -1 Err#22
+ dtrace: 2006687 drops on CPU 0
+ workq_kernreturn(0x1, 0x1019CC000, 0x0) = -1 Err#22
+
+and the git-annex webapp was doing stuff like
+
+ psynch_cvwait(0x7FD7F1418888, 0x2BE010002BF00, 0x600) = -1 Err#260
+ sigreturn(0x7FFF543DD810, 0x1E, 0x2) = 0 Err#-2
+ __pthread_canceled(0x0, 0x2BE010002BF00, 0x7FFF543DD8C8) = -1 Err#22
+ psynch_cvwait(0x7FD7F1418888, 0x2C8010002C900, 0x600) = -1 Err#260
+ sigreturn(0x7FFF543DD810, 0x1E, 0x2) = 0 Err#-2
+ __pthread_canceled(0x0, 0x2C8010002C900, 0x7FFF543DD8C8) = -1 Err#22
+ psynch_cvwait(0x7FD7F1418888, 0x2D0010002D100, 0x600) = -1 Err#260
+ sigreturn(0x7FFF543DD810, 0x1E, 0x2) = 0 Err#-2
+ __pthread_canceled(0x0, 0x2D0010002D100, 0x7FFF543DD8C8) = -1 Err#22
+ psynch_cvwait(0x7FD7F1418888, 0x2D7010002D800, 0x600) = -1 Err#260
+ sigreturn(0x7FFF543DD810, 0x1E, 0x10DCEDC00) = 0 Err#-2
+ __pthread_canceled(0x0, 0x2D7010002D800, 0x7FFF543DD8C8) = -1 Err#22
+ psynch_cvwait(0x7FD7F14189D8, 0x230100002400, 0x2300) = 0 0
+ read(0x6, \"\377\0\", 0x1000) = 1 0
+ setitimer(0x0, 0x116903E50, 0x0) = 0 0
+ write(0x7, \"\377\0\", 0x1) = 1 0
+ sigreturn(0x7FFF543DD810, 0x1E, 0x0) = 0 Err#-2
+ __pthread_canceled(0x0, 0x2BC010002BD00, 0x7FFF543DD8C8) = -1 Err#22
+
+which may be unrelated browser event loop stuff I guess.
+
+"""]]
diff --git a/doc/bugs/OSX_app_issues/old/comment_18_29af9df9ea295d114574e76e15b8e737._comment b/doc/bugs/OSX_app_issues/old/comment_18_29af9df9ea295d114574e76e15b8e737._comment
new file mode 100644
index 000000000..9a2bcfcd0
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/old/comment_18_29af9df9ea295d114574e76e15b8e737._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnqQyhiNXdPIWWSuu232luY5nc-h5RS8bE"
+ nickname="Arve"
+ subject="comment 18"
+ date="2012-12-02T00:02:51Z"
+ content="""
+Adding nohup doesn't produce any output (that I can find; sudo find / -name nohup.out) :/
+"""]]
diff --git a/doc/bugs/OSX_app_issues/old/comment_18_88ddc846eb4e4a2d54028a3412ba28d6._comment b/doc/bugs/OSX_app_issues/old/comment_18_88ddc846eb4e4a2d54028a3412ba28d6._comment
new file mode 100644
index 000000000..45c14024e
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/old/comment_18_88ddc846eb4e4a2d54028a3412ba28d6._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.117"
+ subject="comment 18"
+ date="2012-12-14T20:55:12Z"
+ content="""
+I've built the app on 10.8.2, let's hope that'll finally put this problem to rest.
+
+Temporarily available here: <http://downloads.kitenet.net/tmp/git-annex.dmg.bz2>
+
+(This build currently lacks XMPP support.)
+"""]]
diff --git a/doc/bugs/OSX_app_issues/old/comment_19_6d6341b05123cd317c4eac96353c8662._comment b/doc/bugs/OSX_app_issues/old/comment_19_6d6341b05123cd317c4eac96353c8662._comment
new file mode 100644
index 000000000..70e7e7daa
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/old/comment_19_6d6341b05123cd317c4eac96353c8662._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.2.244"
+ subject="comment 19"
+ date="2012-12-07T16:13:42Z"
+ content="""
+This hang seems not to occur on OSX 10.7, which is the version the autobuilder is running. So this is some sort of incompatability.
+
+So, building git-annex from source should avoid the problem. I'd like to get a version of the app built for 10.8, have not yet been able to arrange that.
+"""]]
diff --git a/doc/bugs/OSX_app_issues/old/comment_19_aff4ab761c4d196732baa046af45fe24._comment b/doc/bugs/OSX_app_issues/old/comment_19_aff4ab761c4d196732baa046af45fe24._comment
new file mode 100644
index 000000000..76fc993e4
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/old/comment_19_aff4ab761c4d196732baa046af45fe24._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkfHTPsiAcHEEN7Xl7WxiZmYq-vX7azxFY"
+ nickname="Vincent"
+ subject="comment 19"
+ date="2012-12-16T05:27:06Z"
+ content="""
+downloaded the 10.8.2 build, md5 9fc31ec6dcf0088d3723d1b25110f7f7.
+
+git --init works instantaneously.
+
+"""]]
diff --git a/doc/bugs/OSX_app_issues/old/comment_20_43bd5985d8a3a5e7f826a34e5dd9216e._comment b/doc/bugs/OSX_app_issues/old/comment_20_43bd5985d8a3a5e7f826a34e5dd9216e._comment
new file mode 100644
index 000000000..8e01d948e
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/old/comment_20_43bd5985d8a3a5e7f826a34e5dd9216e._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.117"
+ subject="comment 20"
+ date="2012-12-17T16:23:05Z"
+ content="""
+@Vincent OMG, it works!?!
+
+\o/
+"""]]
diff --git a/doc/bugs/OSX_app_issues/old/comment_3_08613b2e2318680508483d204a43da76._comment b/doc/bugs/OSX_app_issues/old/comment_3_08613b2e2318680508483d204a43da76._comment
new file mode 100644
index 000000000..24b6bde51
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/old/comment_3_08613b2e2318680508483d204a43da76._comment
@@ -0,0 +1,76 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ nickname="edheil"
+ subject="No luck running it on OS X Lion."
+ date="2012-11-21T06:07:55Z"
+ content="""
+here's the crash info:
+
+<pre>
+Process: git-annex [84369]
+Path: /Applications/git-annex.app/Contents/MacOS/bin/git-annex
+Identifier: git-annex
+Version: ??? (???)
+Code Type: X86-64 (Native)
+Parent Process: sh [84364]
+
+Date/Time: 2012-11-21 00:27:03.068 -0500
+OS Version: Mac OS X 10.7.5 (11G63)
+Report Version: 9
+
+Crashed Thread: 0
+
+Exception Type: EXC_BREAKPOINT (SIGTRAP)
+Exception Codes: 0x0000000000000002, 0x0000000000000000
+
+Application Specific Information:
+dyld: launch, loading dependent libraries
+
+Dyld Error Message:
+ Library not loaded: /opt/local/lib/libgss.3.dylib
+ Referenced from: /Applications/git-annex.app/Contents/MacOS/opt/local/lib/libgsasl.7.dylib
+ Reason: image not found
+
+Binary Images:
+ 0x105baa000 - 0x107b89fe7 +git-annex (??? - ???) <45311C82-015C-3F87-9F9B-01325EFBD0D9> /Applications/git-annex.app/Contents/MacOS/bin/git-annex
+ 0x10822d000 - 0x10823eff7 +libz.1.dylib (1.2.7 - compatibility 1.0.0) <57016CC1-AD54-337E-A983-457933B24D35> /Applications/git-annex.app/Contents/MacOS/opt/local/lib/libz.1.dylib
+ 0x108245000 - 0x10827dff7 +libpcre.1.dylib (2.1.0 - compatibility 2.0.0) <431BD758-FA7B-38B3-AB7E-6511EC06152E> /Applications/git-annex.app/Contents/MacOS/opt/local/lib/libpcre.1.dylib
+ 0x108283000 - 0x1083b3ff7 +libxml2.2.dylib (11.0.0 - compatibility 11.0.0) <0663F820-D436-3304-B12F-9158901087EB> /Applications/git-annex.app/Contents/MacOS/opt/local/lib/libxml2.2.dylib
+ 0x1083e9000 - 0x108400fef +libgsasl.7.dylib (16.6.0 - compatibility 16.0.0) <41503EE1-D58B-385C-AC2E-BEAA7D0D4E38> /Applications/git-annex.app/Contents/MacOS/opt/local/lib/libgsasl.7.dylib
+ 0x10840a000 - 0x1084a1fff +libgnutls.26.dylib (49.3.0 - compatibility 49.0.0) <0320352A-3336-3B6B-A7DE-F3069669AD27> /Applications/git-annex.app/Contents/MacOS/opt/local/lib/libgnutls.26.dylib
+ 0x1084c3000 - 0x1084f1ff7 +libidn.11.dylib (18.8.0 - compatibility 18.0.0) <97073970-9370-3F85-B943-1B989EA41148> /Applications/git-annex.app/Contents/MacOS/opt/local/lib/libidn.11.dylib
+ 0x1084fc000 - 0x1085f5ff7 +libiconv.2.dylib (8.1.0 - compatibility 8.0.0) <1B8D243B-F617-301E-97B1-EE78A72617AB> /Applications/git-annex.app/Contents/MacOS/opt/local/lib/libiconv.2.dylib
+ 0x108606000 - 0x108606fff +libcharset.1.dylib (2.0.0 - compatibility 2.0.0) <E3797413-2AA3-3698-B393-E1203B4799A0> /Applications/git-annex.app/Contents/MacOS/opt/local/lib/libcharset.1.dylib
+ 0x10860c000 - 0x108665fef +libgmp.10.dylib (11.5.0 - compatibility 11.0.0) <EE407B22-0F44-38B6-9937-10CA6A529F37> /Applications/git-annex.app/Contents/MacOS/opt/local/lib/libgmp.10.dylib
+ 0x108675000 - 0x1086a2fe7 +libSystem.B.dylib (159.1.0 - compatibility 1.0.0) <7BEBB139-50BB-3112-947A-F4AA168F991C> /Applications/git-annex.app/Contents/MacOS/usr/lib/libSystem.B.dylib
+ 0x1086b4000 - 0x1086c8fef +libgcc_s.1.dylib (??? - ???) <3C5BF0B8-B1E9-3B41-B52F-F7499687217C> /Applications/git-annex.app/Contents/MacOS/opt/local/lib/gcc47/libgcc_s.1.dylib
+ 0x1086d8000 - 0x1086f5ff7 +liblzma.5.dylib (6.4.0 - compatibility 6.0.0) <1D682E06-EB89-34CA-855A-AEF611C4DF86> /usr/local/lib/liblzma.5.dylib
+ 0x7fff657aa000 - 0x7fff657debaf dyld (195.6 - ???) <0CD1B35B-A28F-32DA-B72E-452EAD609613> /usr/lib/dyld
+ 0x7fff8b669000 - 0x7fff8b672ff7 libsystem_notify.dylib (80.1.0 - compatibility 1.0.0) <A4D651E3-D1C6-3934-AD49-7A104FD14596> /usr/lib/system/libsystem_notify.dylib
+ 0x7fff8b6e4000 - 0x7fff8b6e5ff7 libsystem_sandbox.dylib (??? - ???) <2A09E4DA-F47C-35CB-B70C-E0492BA9F20E> /usr/lib/system/libsystem_sandbox.dylib
+ 0x7fff8c000000 - 0x7fff8c006ff7 libunwind.dylib (30.0.0 - compatibility 1.0.0) <1E9C6C8C-CBE8-3F4B-A5B5-E03E3AB53231> /usr/lib/system/libunwind.dylib
+ 0x7fff8c1c4000 - 0x7fff8c1c5ff7 libremovefile.dylib (21.1.0 - compatibility 1.0.0) <739E6C83-AA52-3C6C-A680-B37FE2888A04> /usr/lib/system/libremovefile.dylib
+ 0x7fff8cf13000 - 0x7fff8cf4efff libsystem_info.dylib (??? - ???) <35F90252-2AE1-32C5-8D34-782C614D9639> /usr/lib/system/libsystem_info.dylib
+ 0x7fff8dbc3000 - 0x7fff8dbc8fff libcache.dylib (47.0.0 - compatibility 1.0.0) <1571C3AB-BCB2-38CD-B3B2-C5FC3F927C6A> /usr/lib/system/libcache.dylib
+ 0x7fff8dbc9000 - 0x7fff8dbd0fff libcopyfile.dylib (85.1.0 - compatibility 1.0.0) <0AB51EE2-E914-358C-AC19-47BC024BDAE7> /usr/lib/system/libcopyfile.dylib
+ 0x7fff8dbdf000 - 0x7fff8dbedfff libdispatch.dylib (187.10.0 - compatibility 1.0.0) <8E03C652-922A-3399-93DE-9EA0CBFA0039> /usr/lib/system/libdispatch.dylib
+ 0x7fff8dcf2000 - 0x7fff8dcf7ff7 libsystem_network.dylib (??? - ???) <5DE7024E-1D2D-34A2-80F4-08326331A75B> /usr/lib/system/libsystem_network.dylib
+ 0x7fff8e1bb000 - 0x7fff8e298fef libsystem_c.dylib (763.13.0 - compatibility 1.0.0) <41B43515-2806-3FBC-ACF1-A16F35B7E290> /usr/lib/system/libsystem_c.dylib
+ 0x7fff8e6e2000 - 0x7fff8e6eafff libsystem_dnssd.dylib (??? - ???) <584B321E-5159-37CD-B2E7-82E069C70AFB> /usr/lib/system/libsystem_dnssd.dylib
+ 0x7fff8fab6000 - 0x7fff8fab8fff libquarantine.dylib (36.7.0 - compatibility 1.0.0) <8D9832F9-E4A9-38C3-B880-E5210B2353C7> /usr/lib/system/libquarantine.dylib
+ 0x7fff8fc3e000 - 0x7fff8fc80ff7 libcommonCrypto.dylib (55010.0.0 - compatibility 1.0.0) <BB770C22-8C57-365A-8716-4A3C36AE7BFB> /usr/lib/system/libcommonCrypto.dylib
+ 0x7fff90fa3000 - 0x7fff90fa9fff libmacho.dylib (800.0.0 - compatibility 1.0.0) <165514D7-1BFA-38EF-A151-676DCD21FB64> /usr/lib/system/libmacho.dylib
+ 0x7fff90faa000 - 0x7fff90fabfff libunc.dylib (24.0.0 - compatibility 1.0.0) <337960EE-0A85-3DD0-A760-7134CF4C0AFF> /usr/lib/system/libunc.dylib
+ 0x7fff910b4000 - 0x7fff910b8fff libmathCommon.A.dylib (2026.0.0 - compatibility 1.0.0) <FF83AFF7-42B2-306E-90AF-D539C51A4542> /usr/lib/system/libmathCommon.A.dylib
+ 0x7fff916b9000 - 0x7fff916bdfff libdyld.dylib (195.6.0 - compatibility 1.0.0) <FFC59565-64BD-3B37-90A4-E2C3A422CFC1> /usr/lib/system/libdyld.dylib
+ 0x7fff916be000 - 0x7fff916defff libsystem_kernel.dylib (1699.32.7 - compatibility 1.0.0) <66C9F9BD-C7B3-30D4-B1A0-03C8A6392351> /usr/lib/system/libsystem_kernel.dylib
+ 0x7fff916df000 - 0x7fff916e0fff libdnsinfo.dylib (395.11.0 - compatibility 1.0.0) <853BAAA5-270F-3FDC-B025-D448DB72E1C3> /usr/lib/system/libdnsinfo.dylib
+ 0x7fff929f8000 - 0x7fff929fdfff libcompiler_rt.dylib (6.0.0 - compatibility 1.0.0) <98ECD5F6-E85C-32A5-98CD-8911230CB66A> /usr/lib/system/libcompiler_rt.dylib
+ 0x7fff93a3c000 - 0x7fff93a3cfff libkeymgr.dylib (23.0.0 - compatibility 1.0.0) <61EFED6A-A407-301E-B454-CD18314F0075> /usr/lib/system/libkeymgr.dylib
+ 0x7fff97139000 - 0x7fff9713aff7 libsystem_blocks.dylib (53.0.0 - compatibility 1.0.0) <8BCA214A-8992-34B2-A8B9-B74DEACA1869> /usr/lib/system/libsystem_blocks.dylib
+ 0x7fff9724f000 - 0x7fff9726cfff libxpc.dylib (77.19.0 - compatibility 1.0.0) <9F57891B-D7EF-3050-BEDD-21E7C6668248> /usr/lib/system/libxpc.dylib
+ 0x7fff97cfe000 - 0x7fff97d08ff7 liblaunch.dylib (392.39.0 - compatibility 1.0.0) <8C235D13-2928-30E5-9E12-2CC3D6324AE2> /usr/lib/system/liblaunch.dylib
+</pre>
+
+
+"""]]
diff --git a/doc/bugs/OSX_app_issues/old/comment_4_4cda124b57ddc87645d5822f14ed5c59._comment b/doc/bugs/OSX_app_issues/old/comment_4_4cda124b57ddc87645d5822f14ed5c59._comment
new file mode 100644
index 000000000..758140903
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/old/comment_4_4cda124b57ddc87645d5822f14ed5c59._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkBTVYS5lTecuenAB01eHgfUxE20vWVpU4"
+ nickname="Peng"
+ subject="Large Mountain Loin package size"
+ date="2012-12-28T22:17:43Z"
+ content="""
+I see that git-annex package file is 489.9MB on Mac Mountain Loin (git-annex.dmg.bz2). The file git-annex.dmg.bz2 is only of size 24M. Is there any way to reduce the package size?
+"""]]
diff --git a/doc/bugs/OSX_app_issues/old/comment_5_0d1df34f83a8dac9c438d93806236818._comment b/doc/bugs/OSX_app_issues/old/comment_5_0d1df34f83a8dac9c438d93806236818._comment
new file mode 100644
index 000000000..89078a7da
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/old/comment_5_0d1df34f83a8dac9c438d93806236818._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 5"
+ date="2013-01-02T19:52:28Z"
+ content="""
+The build for today's release is 24 mb.
+"""]]
diff --git a/doc/bugs/OSX_app_issues/old/comment_6_12bd83e7e2327c992448e87bdb85d17e._comment b/doc/bugs/OSX_app_issues/old/comment_6_12bd83e7e2327c992448e87bdb85d17e._comment
new file mode 100644
index 000000000..62851c15b
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/old/comment_6_12bd83e7e2327c992448e87bdb85d17e._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/6xTna_B_h.ECb6_ftC2dYLytAEwrv36etg_054U-#4c1e7"
+ nickname="Fake"
+ subject="libncurses on 10.7"
+ date="2012-10-17T21:24:24Z"
+ content="""
+I'm getting an error from gpg when I try to set up a repository on a remote server with encrypted rsync. Looks like libncurses in /usr/lib is 32 bit:
+
+ Dyld Error Message:
+ Library not loaded: /opt/local/lib/libncurses.5.dylib
+ Referenced from: /Applications/git-annex.app/Contents/MacOS/opt/local/lib/libreadline.6.2.dylib
+ Reason: no suitable image found. Did find:
+ /usr/lib/libncurses.5.dylib: mach-o, but wrong architecture
+ /usr/lib/libncurses.5.dylib: mach-o, but wrong architecture
+"""]]
diff --git a/doc/bugs/OSX_app_issues/old/comment_6_bc44d5aea5f77e331a32913ada293730._comment b/doc/bugs/OSX_app_issues/old/comment_6_bc44d5aea5f77e331a32913ada293730._comment
new file mode 100644
index 000000000..187197e81
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/old/comment_6_bc44d5aea5f77e331a32913ada293730._comment
@@ -0,0 +1,27 @@
+[[!comment format=mdwn
+ username="https://www.jsilence.org/"
+ nickname="jsilence"
+ subject="Setting up a repository fails on OSX 10.6"
+ date="2013-01-05T11:17:18Z"
+ content="""
+I installed Haskell via MacPorts and managed to compile git-annex as described via cabal.
+
+On the initial start, git-annex webapp starts just fine and the webapp opens in the browser. When I try to configure a local repository, the webapp crashes.
+
+ 1 jsilence@zeo ~ % git-annex webapp
+ (Recording state in git...)
+ WebApp crashed: watch mode is not available on this system
+
+ Launching web browser on file:///var/folders/6b/6bWnFAnbFXSPCLPvCnKNrE+++TI/-Tmp-/webapp1003.html
+ jsilence@zeo ~ %
+
+\"watch mode is not suported\" suggests that lsof is not in the PATH. lsof resides in /usr/sbin and can be found just fine:
+
+ jsilence@zeo ~ % which lsof
+ /usr/sbin/lsof
+
+Any help would be appreciated.
+
+-jsl
+
+"""]]
diff --git a/doc/bugs/OSX_app_issues/old/comment_6_cea97dbbfb566a9fe463365ca4511119._comment b/doc/bugs/OSX_app_issues/old/comment_6_cea97dbbfb566a9fe463365ca4511119._comment
new file mode 100644
index 000000000..6c968aa1e
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/old/comment_6_cea97dbbfb566a9fe463365ca4511119._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://nico.kaiser.me/"
+ nickname="Nico Kaiser"
+ subject="git-annex crashing on OS X 10.8.2"
+ date="2012-11-27T08:01:29Z"
+ content="""
+ $ /Applications/git-annex.app/Contents/MacOS/git-annex-webapp
+ dyld: Symbol not found: _OBJC_CLASS_$_NSObject
+ Referenced from: /usr/bin/open
+ Expected in: /Applications/git-annex.app/Contents/MacOS/usr/lib/libobjc.A.dylib
+ in /usr/bin/open
+ WebApp crashed: failed to start web browser
+
+ Launching web browser on file:///var/folders/8g/_fvs7jf572l4fj03q5mhrq9r0000gn/T/webapp1196.html
+
+"""]]
diff --git a/doc/bugs/OSX_app_issues/old/comment_7_911f187d46890093a54859032ada2442._comment b/doc/bugs/OSX_app_issues/old/comment_7_911f187d46890093a54859032ada2442._comment
new file mode 100644
index 000000000..636627959
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/old/comment_7_911f187d46890093a54859032ada2442._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.49"
+ subject="comment 7"
+ date="2012-11-27T21:13:18Z"
+ content="""
+@Nico, that's actually kind of promising; people have been reporting much earlier crashes with OSX. This later crash is one I think I can do something about! :)
+
+So, it looks like the standalone app build needs to run the web browser in a clean environment that doesn't use any of its bundled libraries. I've committed that change and it will be in a release later today.
+"""]]
diff --git a/doc/bugs/OSX_app_issues/old/comment_7_acd73cc5c4caa88099e2d2f19947aadf._comment b/doc/bugs/OSX_app_issues/old/comment_7_acd73cc5c4caa88099e2d2f19947aadf._comment
new file mode 100644
index 000000000..bdbdfc9ab
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/old/comment_7_acd73cc5c4caa88099e2d2f19947aadf._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.211"
+ subject="comment 7"
+ date="2013-01-05T17:48:52Z"
+ content="""
+@jsilence, this problem does not involve lsof. There was a typo in the cabal file that prevented cabal building it with hfsevents. I'm releasing a new version to cabal with this typo fixed.
+"""]]
diff --git a/doc/bugs/OSX_app_issues/old/comment_8_08b091a58106ca6050ac669579ed9ff4._comment b/doc/bugs/OSX_app_issues/old/comment_8_08b091a58106ca6050ac669579ed9ff4._comment
new file mode 100644
index 000000000..d32d9a024
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/old/comment_8_08b091a58106ca6050ac669579ed9ff4._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://wiggy.net/"
+ nickname="Wichert"
+ subject="Adding a remote server repository fails"
+ date="2012-11-28T21:17:23Z"
+ content="""
+The error message I get is:
+
+> Failed to ssh to the server. Transcript: dyld: Symbol not found: ___progname Referenced from: /usr/bin/ssh Expected in: /Users/wichert/Applications/git-annex.app/Contents/MacOS/usr/lib/libSystem.B.dylib in /usr/bin/ssh
+
+"""]]
diff --git a/doc/bugs/OSX_app_issues/old/comment_9_8464c839cb169a4c6e72bebdc2065e9a._comment b/doc/bugs/OSX_app_issues/old/comment_9_8464c839cb169a4c6e72bebdc2065e9a._comment
new file mode 100644
index 000000000..42aaa9bfe
--- /dev/null
+++ b/doc/bugs/OSX_app_issues/old/comment_9_8464c839cb169a4c6e72bebdc2065e9a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://wiggy.net/"
+ nickname="Wichert"
+ subject="Trying to add remote server after failed attempt blocks forever"
+ date="2012-11-28T21:23:54Z"
+ content="""
+Out of curiosity I checked what would happen if I tried to add a remote server repo again after it just failed with the missing library error (see previous comment). Surprisingly the webapp is now waiting forever at the *Testing server ...* message.
+"""]]
diff --git a/doc/bugs/OSX_git-annex.app_error:__LSOpenURLsWithRole__40____41__.mdwn b/doc/bugs/OSX_git-annex.app_error:__LSOpenURLsWithRole__40____41__.mdwn
new file mode 100644
index 000000000..ac5c66951
--- /dev/null
+++ b/doc/bugs/OSX_git-annex.app_error:__LSOpenURLsWithRole__40____41__.mdwn
@@ -0,0 +1,26 @@
+**What steps will reproduce the problem?**
+
+Either double click on the app or from the terminal
+
+ $ open /Applications/git-annex.app
+
+**What is the expected output? What do you see instead?**
+
+I'd expect to see git-annex run. "git-annex" doesn't run and what I see (in the terminal) is:
+
+ LSOpenURLsWithRole() failed with error -10810 for the file /Applications/git-annex.app.
+
+**What version of git-annex are you using? On what operating system?**
+
+*git-annex*: 3.20121017
+
+*git-annex.app*: ???
+
+*OS*: OSX 10.6.8 64 bit
+
+
+**Please provide any additional information below.**
+
+[[!tag /design/assistant/OSX]]
+
+> This was fixed a while ago. [[done]] --[[Joey]]
diff --git a/doc/bugs/OSX_git-annex.app_error:__LSOpenURLsWithRole__40____41__/comment_1_0dfa839f1ba689b23f811787515b8cff._comment b/doc/bugs/OSX_git-annex.app_error:__LSOpenURLsWithRole__40____41__/comment_1_0dfa839f1ba689b23f811787515b8cff._comment
new file mode 100644
index 000000000..896ae26ce
--- /dev/null
+++ b/doc/bugs/OSX_git-annex.app_error:__LSOpenURLsWithRole__40____41__/comment_1_0dfa839f1ba689b23f811787515b8cff._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://a-or-b.myopenid.com/"
+ ip="220.244.41.108"
+ subject="comment 1"
+ date="2012-10-28T06:46:40Z"
+ content="""
+My best advice to anyone running into this is simply install using cabal. It works. :-)
+"""]]
diff --git a/doc/bugs/OSX_git-annex.app_error:__LSOpenURLsWithRole__40____41__/comment_2_612b947eb5474f6d792a833e33105665._comment b/doc/bugs/OSX_git-annex.app_error:__LSOpenURLsWithRole__40____41__/comment_2_612b947eb5474f6d792a833e33105665._comment
new file mode 100644
index 000000000..0732cbfcf
--- /dev/null
+++ b/doc/bugs/OSX_git-annex.app_error:__LSOpenURLsWithRole__40____41__/comment_2_612b947eb5474f6d792a833e33105665._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 2"
+ date="2012-10-28T20:11:43Z"
+ content="""
+I sort of got a feeling that this build might have issues on OSX 10.6, I create the OSX builds on 10.7.
+"""]]
diff --git a/doc/bugs/OSX_git-annex.app_error:__LSOpenURLsWithRole__40____41__/comment_3_549b8bcae6f1f8b21932b734e32fbdd1._comment b/doc/bugs/OSX_git-annex.app_error:__LSOpenURLsWithRole__40____41__/comment_3_549b8bcae6f1f8b21932b734e32fbdd1._comment
new file mode 100644
index 000000000..c5ada3d1d
--- /dev/null
+++ b/doc/bugs/OSX_git-annex.app_error:__LSOpenURLsWithRole__40____41__/comment_3_549b8bcae6f1f8b21932b734e32fbdd1._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnKgoTWEDuAqxBT7LnQVNJBmI0wajSgORA"
+ nickname="Martin"
+ subject="Same on 10.8.2"
+ date="2012-10-31T20:17:17Z"
+ content="""
+I get the same error on OSX 10.8.2.
+"""]]
diff --git a/doc/bugs/OSX_git-annex.app_error:__LSOpenURLsWithRole__40____41__/comment_4_23078dfea127fa3ef20696eb10ce964c._comment b/doc/bugs/OSX_git-annex.app_error:__LSOpenURLsWithRole__40____41__/comment_4_23078dfea127fa3ef20696eb10ce964c._comment
new file mode 100644
index 000000000..6b0278fe8
--- /dev/null
+++ b/doc/bugs/OSX_git-annex.app_error:__LSOpenURLsWithRole__40____41__/comment_4_23078dfea127fa3ef20696eb10ce964c._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlfvsw_0TFUvMcHVBRw1D1UmAaOJ3VsNSU"
+ nickname="chee"
+ subject="comment 4"
+ date="2012-11-16T03:14:50Z"
+ content="""
+Same error here, 10.8.2
+
+https://snaek.org/resources/ff40b1c2fd9486614c7df72aaeca9755fb43d6ff.png
+"""]]
diff --git a/doc/bugs/OSX_git-annex.app_error:__LSOpenURLsWithRole__40____41__/comment_5_7da5ef8325b8787bbf1c6e2c17b1142e._comment b/doc/bugs/OSX_git-annex.app_error:__LSOpenURLsWithRole__40____41__/comment_5_7da5ef8325b8787bbf1c6e2c17b1142e._comment
new file mode 100644
index 000000000..2f7c1184b
--- /dev/null
+++ b/doc/bugs/OSX_git-annex.app_error:__LSOpenURLsWithRole__40____41__/comment_5_7da5ef8325b8787bbf1c6e2c17b1142e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.49"
+ subject="comment 5"
+ date="2012-11-26T23:52:52Z"
+ content="""
+The OSX app has been updated for today's release, and includes a lot of missing libraries. I don't understand this error message, but on the off chance it was caused by some of the missing libraries, it could conceviably be fixed. Your testing of it would be appreciated.
+"""]]
diff --git a/doc/bugs/OS_X_10.8:_Can__39__t_reopen_webapp.mdwn b/doc/bugs/OS_X_10.8:_Can__39__t_reopen_webapp.mdwn
new file mode 100644
index 000000000..3a93c3881
--- /dev/null
+++ b/doc/bugs/OS_X_10.8:_Can__39__t_reopen_webapp.mdwn
@@ -0,0 +1,31 @@
+### Please describe the problem.
+
+If the assistant is not running, I can successfully open the git-annex application, which will trigger my browser to open a new tab with the assistant interface.
+
+However, once that has been done one time, there appears to be no way to get back to the assistant if the tab is closed. Attempting to open the application again while the assistant is running in the background results in nothing happening at all.
+
+### What steps will reproduce the problem?
+
+1. Open git-annex.app
+2. See assistant and then close the browser tab
+3. Open git-annex.app again
+4. Nothing happens
+
+### What version of git-annex are you using? On what operating system?
+
+Version 4.20130723-ge023649 on OS X 10.8.4.
+
+### Please provide any additional information below.
+
+From .git/annex/daemon.log:
+
+[[!format sh """
+[2013-07-28 00:01:08 CDT] main: starting assistant version 4.20130723-ge023649
+
+(scanning...) [2013-07-28 00:01:08 CDT] Watcher: Performing startup scan
+(started...)
+"""]]
+
+> [[done]]; I added the `&` to git-annex-shell.
+> Hopefully that does not cause any other unwanted behavior..
+> --[[Joey]]
diff --git a/doc/bugs/OS_X_10.8:_Can__39__t_reopen_webapp/comment_1_2653fe701a1bb20254f3d6b90f10a43b._comment b/doc/bugs/OS_X_10.8:_Can__39__t_reopen_webapp/comment_1_2653fe701a1bb20254f3d6b90f10a43b._comment
new file mode 100644
index 000000000..7982f30f2
--- /dev/null
+++ b/doc/bugs/OS_X_10.8:_Can__39__t_reopen_webapp/comment_1_2653fe701a1bb20254f3d6b90f10a43b._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkfHTPsiAcHEEN7Xl7WxiZmYq-vX7azxFY"
+ nickname="Vincent"
+ subject="Having trouble reproducing"
+ date="2013-07-29T11:14:46Z"
+ content="""
+I have the same platform (os/x 10.8.4) and git-annex revision (4.20130723-ge023649) but am unable to reproduce this.
+I may have seen it in the last couple of months (http://git-annex.branchable.com/bugs/wishlist:_simple_url_for_webapp/) but it now does not seem to be affecting me; joey's prescription works.
+
+Additional info:
+
+If I stop the daemon via the webapp menu, close the tab and start again via the app icon (in the Dock), I get the tab opening as expected.
+
+Sometimes, if I have the assistant in an open tab and doubleclick the app icon again, I get another tab with the assistant in it and the same auth= string.
+Other times, I don't. It's unclear to me what the difference is. Possibly relevant - the time that I saw the second tab appear was when the existing tab was left over from the machine being in sleep mode, but it was definitely responding to mouse clicks etc (ie not a 'dead' page) and the daemon was still running in the background. After stopping and starting, I never saw the second tab instance appear again.
+
+Browser is chrome 28.0.1500.71.
+"""]]
diff --git a/doc/bugs/OS_X_10.8:_Can__39__t_reopen_webapp/comment_2_d9ce701d077e40f39b142ce2cc570a3b._comment b/doc/bugs/OS_X_10.8:_Can__39__t_reopen_webapp/comment_2_d9ce701d077e40f39b142ce2cc570a3b._comment
new file mode 100644
index 000000000..9f31c76d5
--- /dev/null
+++ b/doc/bugs/OS_X_10.8:_Can__39__t_reopen_webapp/comment_2_d9ce701d077e40f39b142ce2cc570a3b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnaH44G3QbxBAYyDwy0PbvL0ls60XoaR3Y"
+ nickname="Nigel"
+ subject=".git/annex/webapp.html"
+ date="2013-07-29T12:08:04Z"
+ content="""
+after accidentally closing the webapp tab, I reopened the link from the above file and it seemed to work
+"""]]
diff --git a/doc/bugs/OS_X_10.8:_Can__39__t_reopen_webapp/comment_3_14964ab68253dc1a8903d14a821b8b40._comment b/doc/bugs/OS_X_10.8:_Can__39__t_reopen_webapp/comment_3_14964ab68253dc1a8903d14a821b8b40._comment
new file mode 100644
index 000000000..6f66fdb70
--- /dev/null
+++ b/doc/bugs/OS_X_10.8:_Can__39__t_reopen_webapp/comment_3_14964ab68253dc1a8903d14a821b8b40._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl-BU4KfFktO2-bqaFmlArHta0Oy7zJrCs"
+ nickname="J. Ryan"
+ subject="Thanks!"
+ date="2013-07-29T14:44:42Z"
+ content="""
+I was unaware of both `git-annex-webapp` command as well as the `webapp.html` file it appears to open, so now I have two approaches to get back into the webapp.
+
+It does seem like it would be nice if future double-clicks on the app itself triggered the page to open, but at least now I have some way to get there.
+"""]]
diff --git a/doc/bugs/OS_X_10.8:_Can__39__t_reopen_webapp/comment_4_4a579e9a13305ab4157f4b3eba46b92d._comment b/doc/bugs/OS_X_10.8:_Can__39__t_reopen_webapp/comment_4_4a579e9a13305ab4157f4b3eba46b92d._comment
new file mode 100644
index 000000000..e8337926f
--- /dev/null
+++ b/doc/bugs/OS_X_10.8:_Can__39__t_reopen_webapp/comment_4_4a579e9a13305ab4157f4b3eba46b92d._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.21"
+ subject="comment 4"
+ date="2013-07-30T18:06:05Z"
+ content="""
+There's clearly something not quite right with how the program is started on OSX. I've had reports about the app icon \"bouncing\" for a long time, and now this.
+
+Since I do not own a Mac, and only have VNC access to a Mac desktop one for about 1 hour a week (and that's pretty slow), doing anything to improve this is quite a low priority background task for me.
+
+It seems that, as a non-Cocoa application, there are only a couple of behaviors that git-annex could have that play into this.
+
+Perhaps the problem is that if the git-annex assistant daemon is not already running (it's supposed to autostart on login, but this may not be working, or perhaps git-annex has only just been installed and has not started yet), git-annex-webapp runs the daemon, and keeps it running, in the foreground. Perhaps this is interpreted by the GUI as an app that has not finished starting up, or as an app that is already running so it does not re-run it when the icon is clicked on again (which would run git-annex webapp and have it open a new browser window). This should be easy to play around with, by just editing the `git-annex-webapp` shell script. For example, adding a \"&\" at the end of the last line in the file would make it instead run in the background.
+
+Or, the problem might be with the .plist file for the app. Perhaps there's some change that could be made to it that would clue OSX in on how git-annex works.
+"""]]
diff --git a/doc/bugs/OS_X_10.8:_Can__39__t_reopen_webapp/comment_5_2a710960dc3a177ce62ef92f8546c496._comment b/doc/bugs/OS_X_10.8:_Can__39__t_reopen_webapp/comment_5_2a710960dc3a177ce62ef92f8546c496._comment
new file mode 100644
index 000000000..f3505ba60
--- /dev/null
+++ b/doc/bugs/OS_X_10.8:_Can__39__t_reopen_webapp/comment_5_2a710960dc3a177ce62ef92f8546c496._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl-BU4KfFktO2-bqaFmlArHta0Oy7zJrCs"
+ nickname="J. Ryan"
+ subject="comment 5"
+ date="2013-07-30T18:44:00Z"
+ content="""
+Joey: Success! I was able to get things working properly by backgrounding the app by adding `&` at the end of `git-annex-webapp` like you suggested.
+
+After doing that, I am able to relaunch the OS X app as many times as I want, and each time I get a new tab in my browser as desired.
+
+I guess if it's left in the foreground, OS X thinks \"there's already an instance of that app running\" and does nothing. If it were a GUI app, it would focus the GUI app in that case, but with a shell script there's nothing really for it to do, so that sort of explains the behavior.
+"""]]
diff --git a/doc/bugs/OS_X_10.8:_Can__39__t_reopen_webapp/comment_6_a4ad73530cd0f6621bcc6394d5f39af7._comment b/doc/bugs/OS_X_10.8:_Can__39__t_reopen_webapp/comment_6_a4ad73530cd0f6621bcc6394d5f39af7._comment
new file mode 100644
index 000000000..a5f2d4fb1
--- /dev/null
+++ b/doc/bugs/OS_X_10.8:_Can__39__t_reopen_webapp/comment_6_a4ad73530cd0f6621bcc6394d5f39af7._comment
@@ -0,0 +1,41 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkfHTPsiAcHEEN7Xl7WxiZmYq-vX7azxFY"
+ nickname="Vincent"
+ subject="seems to work"
+ date="2013-07-31T09:37:36Z"
+ content="""
+I tried this as well.
+
+ % diff -u /Applications/git-annex.app/Contents/MacOS/git-annex-shell{.old,}
+ --- /Applications/git-annex.app/Contents/MacOS/git-annex-shell.old 2013-07-31 19:32:28.000000000 +1000
+ +++ /Applications/git-annex.app/Contents/MacOS/git-annex-shell 2013-07-23 14:12:36.000000000 +1000
+ @@ -22,4 +22,4 @@
+ export GIT_ANNEX_APP_BASE
+ fi
+
+ -\"$base/runshell\" git-annex-shell
+ +\"$base/runshell\" git-annex-shell \"$@\"
+
+ % ps ax|grep git|grep -v grep |wc
+ 0 0 0
+
+ <click the gui app icon>
+ <a new browser tab opens, running the assistant>
+ % ps ax|grep git |grep -v grep
+ 33124 ?? S 0:00.40 git-annex webapp -psn_0_31972988
+ 33133 ?? S 0:00.00 git --git-dir=/Users/me/annex/.git --work-tree=/Users/me/annex cat-file --batch
+ 33162 ?? S 0:00.00 git --git-dir=/Users/me/annex/.git --work-tree=/Users/me/annex cat-file --batch
+ 33174 ?? S 0:00.00 git --git-dir=/Users/me/annex/.git --work-tree=/Users/me/annex cat-file --batch
+ 33177 ?? S 0:00.00 git --git-dir=/Users/me/annex/.git --work-tree=/Users/me/annex check-attr -z --stdin annex.backend annex.numcopies --
+
+ <click the gui app icon again>
+ <a new browser tab opens, running the assistant. the original remains.>
+ % ps ax|grep git |grep -v grep
+ 33124 ?? S 0:00.46 git-annex webapp -psn_0_31972988
+ 33133 ?? S 0:00.00 git --git-dir=/Users/me/annex/.git --work-tree=/Users/me/annex cat-file --batch
+ 33162 ?? S 0:00.00 git --git-dir=/Users/me/annex/.git --work-tree=/Users/me/annex cat-file --batch
+ 33174 ?? S 0:00.00 git --git-dir=/Users/me/annex/.git --work-tree=/Users/me/annex cat-file --batch
+ 33177 ?? S 0:00.00 git --git-dir=/Users/me/annex/.git --work-tree=/Users/me/annex check-attr -z --stdin annex.backend annex.numcopies --
+
+HTH
+"""]]
diff --git a/doc/bugs/Of_identical_files__44___all_but_the_first_copy_are_lost_on_unannex.mdwn b/doc/bugs/Of_identical_files__44___all_but_the_first_copy_are_lost_on_unannex.mdwn
new file mode 100644
index 000000000..3860456d2
--- /dev/null
+++ b/doc/bugs/Of_identical_files__44___all_but_the_first_copy_are_lost_on_unannex.mdwn
@@ -0,0 +1,54 @@
+### Please describe the problem.
+
+(small) identical files fail to unannex, leaving broken symlinks, except for the first copy.
+
+### What steps will reproduce the problem?
+
+* Have multiple identical files. For example, run this, which creates four 6-byte files:
+
+> echo Hello>file1.txt && cp file1.txt file2.txt && cp file1.txt file3.txt && cp file1.txt file4.txt
+
+* Run this (git init needs credentials to have been specified though)
+
+> git init && git-annex init && git-annex add
+
+Now there are 4 symlinks, pointing to the same object:
+
+> lrwxrwxrwx 1 186 Aug 16 15:54 file1.txt -> .git/annex/objects/31/XV/SHA256E-s6--66a045b452102c59d840ec097d59d9467e13a3f34f6494e539ffd32c1bb35f18.txt/SHA256E-s6--66a045b452102c59d840ec097d59d9467e13a3f34f6494e539ffd32c1bb35f18.txt
+
+* Optionally run "git commit -a". It doesn't affect the outcome.
+
+* Run git-annex unannex
+
+> $ git annex unannex
+> unannex file1.txt ok
+> (Recording state in git...)
+> $
+
+Now file1.txt is a normal 6-byte file again, but 2, 3, and 4 are broken symlinks:
+
+ -rw-r----- 1 6 Aug 16 15:54 file1.txt
+ lrwxrwxrwx 1 186 Aug 16 15:54 file2.txt -> .git/annex/objects/31/XV/SHA256E-s6--66a045b452102c59d840ec097d59d9467e13a3f34f6494e539ffd32c1bb35f18.txt/SHA256E-s6--66a045b452102c59d840ec097d59d9467e13a3f34f6494e539ffd32c1bb35f18.txt
+ lrwxrwxrwx 1 186 Aug 16 15:54 file3.txt -> .git/annex/objects/31/XV/SHA256E-s6--66a045b452102c59d840ec097d59d9467e13a3f34f6494e539ffd32c1bb35f18.txt/SHA256E-s6--66a045b452102c59d840ec097d59d9467e13a3f34f6494e539ffd32c1bb35f18.txt
+ lrwxrwxrwx 1 186 Aug 16 15:54 file4.txt -> .git/annex/objects/31/XV/SHA256E-s6--66a045b452102c59d840ec097d59d9467e13a3f34f6494e539ffd32c1bb35f18.txt/SHA256E-s6--66a045b452102c59d840ec097d59d9467e13a3f34f6494e539ffd32c1bb35f18.txt
+
+ $ git-annex fsck
+ fsck file2.txt
+ ** No known copies exist of file2.txt
+ failed
+ fsck file3.txt
+ ** No known copies exist of file3.txt
+ failed
+ fsck file4.txt
+ ** No known copies exist of file4.txt
+ failed
+ git-annex: fsck: 3 failed
+
+
+### What version of git-annex are you using? On what operating system?
+
+git-annex 4.20130802 package
+
+on Debian GNU/Linux jessie/sid (testing), amd64.
+
+> [[dup|done]] --[[Joey]]
diff --git a/doc/bugs/Of_identical_files__44___all_but_the_first_copy_are_lost_on_unannex/comment_2_f7149b684a97070cff051b780c73be48._comment b/doc/bugs/Of_identical_files__44___all_but_the_first_copy_are_lost_on_unannex/comment_2_f7149b684a97070cff051b780c73be48._comment
new file mode 100644
index 000000000..ca3ad1229
--- /dev/null
+++ b/doc/bugs/Of_identical_files__44___all_but_the_first_copy_are_lost_on_unannex/comment_2_f7149b684a97070cff051b780c73be48._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://openid.yandex.ru/deletesoftware/"
+ nickname="deletesoftware"
+ subject="duplicate"
+ date="2013-08-16T14:52:23Z"
+ content="""
+It's the same as these:
+
+* [Large unannex operations result in stale symlinks and data loss](http://git-annex.branchable.com/bugs/Large_unannex_operations_result_in_stale_symlinks_and_data_loss/)
+* [unannex removes object even if referred to by others](http://git-annex.branchable.com/bugs/unannex_removes_object_even_if_referred_to_by_others/)
+* [annex unannex/uninit should handle copies](http://git-annex.branchable.com/bugs/annex_unannex__47__uninit_should_handle_copies/)
+
+and (as gernot mentioned) according to those, has a workaround of \"git annex unannex --fast\". Of course, it's not convenient to need to find a workaround, and to notice a potential dataloss issue…
+
+"""]]
diff --git a/doc/bugs/Old_repository_stuck.mdwn b/doc/bugs/Old_repository_stuck.mdwn
new file mode 100644
index 000000000..46b153eb2
--- /dev/null
+++ b/doc/bugs/Old_repository_stuck.mdwn
@@ -0,0 +1,9 @@
+I had created a test repository a time ago with an old version of git-annex. I didn't really used it so I simply deleted the directory by hand. Now I've installed a new version of git-annex and the old repository stills appears on the webapp, but there is no interface to delete it.
+
+* Old git-annex version: don't remember
+* New git-annex version: I downloaded 3.20130107 (twice to be sure), but for some reason 'git-annex version' reports 3.20130102
+* OS: Ubuntu 12.04.1 LTS 3.2.0-35-generic-pae #55-Ubuntu SMP Wed Dec 5 18:04:39 UTC 2012 i686 i686 i386 GNU/Linux
+
+> This is [[fixed|done]] in git; assuming the repo was showing up
+> in the upper-right menu for switching amoung local repositories.
+> --[[Joey]]
diff --git a/doc/bugs/Older_version_of_git_causes_Internal_Server_Error_when_push.default___61___simple.mdwn b/doc/bugs/Older_version_of_git_causes_Internal_Server_Error_when_push.default___61___simple.mdwn
new file mode 100644
index 000000000..46ae06f6d
--- /dev/null
+++ b/doc/bugs/Older_version_of_git_causes_Internal_Server_Error_when_push.default___61___simple.mdwn
@@ -0,0 +1,64 @@
+### Please describe the problem.
+Internal Server Error when setting up new annex and git push.default set to simple.
+
+### What steps will reproduce the problem?
+git v1.8.2.1 installed on mac os x 10.8.3 via brew
+
+Set push.default = simple (for 2.0-style push handling)
+Point git-annex-assistant at a directory.
+
+### What version of git-annex are you using? On what operating system?
+git-annex version 4.20130422-gb9341fd (from annex-assistant's footer)
+git version 1.8.2.1
+Mac OS X 10.8.3
+
+### Please provide any additional information below.
+
+Changing the push.default to "matching"
+
+The error message as shown was:
+
+Internal Server Error
+git init failed!
+Output:
+error: Malformed value for push.default: simple
+error: Must be one of nothing, matching, tracking or current.
+fatal: bad config file line 22 in /Users/nhyde/.gitconfig
+
+My .gitconfig is as follows:
+
+[user]
+ email = nhyde@example.com
+ #email = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+ name = Nathan Hyde
+[alias]
+ st = status
+ ci = commit
+ br = branch
+ co = checkout
+ df = diff
+ lg = log -p
+ who = shortlog -s --
+ fs = flow feature start
+ ff = flow feature finish
+[color]
+ ui = true
+[core]
+ excludesfile = /Users/nhyde/.gitignore_global
+ ignorecase = false
+ editor = vim
+[push]
+ default = matching
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/debug.log
+
+
+# End of transcript or log.
+"""]]
+
+> Closing this because all autobuilders have been upgraded
+> to a more recent version of git. done --[[Joey]]
+>> Reopened, because the Linux autobuilds have been downgraded to Debian
+>> stable and have this problem again. --[[Joey]]
diff --git a/doc/bugs/Older_version_of_git_causes_Internal_Server_Error_when_push.default___61___simple/comment_1_971224d2c0c0ce8d4530b1991508f849._comment b/doc/bugs/Older_version_of_git_causes_Internal_Server_Error_when_push.default___61___simple/comment_1_971224d2c0c0ce8d4530b1991508f849._comment
new file mode 100644
index 000000000..2d5bb923b
--- /dev/null
+++ b/doc/bugs/Older_version_of_git_causes_Internal_Server_Error_when_push.default___61___simple/comment_1_971224d2c0c0ce8d4530b1991508f849._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-05-13T19:02:38Z"
+ content="""
+I can't think of a way to make the assistant detect that `~/.gitconfig` contains settings not supported by the version of git bundled with git-annex. Even if I could detect it, what could it do? It could perhaps prevent the config file being used by git-annex, but that could have other unwanted consequences.
+
+An error message like this seems about as good as this situation can be handled. However, the version of git bundled with git-annex should be kept up-to-date to prevent this kind of problem as much as possible. I don't currently have a good way to ensure that happens; it takes whatever version of git is installed on the build system.
+
+I'm going to try to get the autobuilders all updated to git 1.8.2, at least.
+"""]]
diff --git a/doc/bugs/Older_version_of_git_causes_Internal_Server_Error_when_push.default___61___simple/comment_2_6866f96277dbe83a8aadcdeb426b6750._comment b/doc/bugs/Older_version_of_git_causes_Internal_Server_Error_when_push.default___61___simple/comment_2_6866f96277dbe83a8aadcdeb426b6750._comment
new file mode 100644
index 000000000..fc4f16500
--- /dev/null
+++ b/doc/bugs/Older_version_of_git_causes_Internal_Server_Error_when_push.default___61___simple/comment_2_6866f96277dbe83a8aadcdeb426b6750._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-05-13T19:08:09Z"
+ content="""
+Done for both Linux autobuilds. OSX still needs updating; emailed the owners of those builds.
+"""]]
diff --git a/doc/bugs/Older_version_of_git_causes_Internal_Server_Error_when_push.default___61___simple/comment_3_eaed9b5532e30e401f50193a72b98310._comment b/doc/bugs/Older_version_of_git_causes_Internal_Server_Error_when_push.default___61___simple/comment_3_eaed9b5532e30e401f50193a72b98310._comment
new file mode 100644
index 000000000..bee277aa6
--- /dev/null
+++ b/doc/bugs/Older_version_of_git_causes_Internal_Server_Error_when_push.default___61___simple/comment_3_eaed9b5532e30e401f50193a72b98310._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmTNrhkVQ26GBLaLD5-zNuEiR8syTj4mI8"
+ nickname="Juan"
+ subject="Still happening in the linux autobuild (08/22/2013)"
+ date="2013-08-23T02:04:42Z"
+ content="""
+I've seen that git-annex for linux is still coming with git 1.7, which causes problems with my installed git (1.8.1.2).
+Wasn't that corrected in autobuilds?
+Thanks in advance.
+Keep up the good work.
+Regards,
+ Juan
+"""]]
diff --git a/doc/bugs/Older_version_of_git_causes_Internal_Server_Error_when_push.default___61___simple/comment_4_1fab407f3823ce8cec87f5df55e49f8c._comment b/doc/bugs/Older_version_of_git_causes_Internal_Server_Error_when_push.default___61___simple/comment_4_1fab407f3823ce8cec87f5df55e49f8c._comment
new file mode 100644
index 000000000..2c9c33c8e
--- /dev/null
+++ b/doc/bugs/Older_version_of_git_causes_Internal_Server_Error_when_push.default___61___simple/comment_4_1fab407f3823ce8cec87f5df55e49f8c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 4"
+ date="2013-08-23T17:41:32Z"
+ content="""
+It was done for the autobuilds, but then I switched them to build using Debian stable, which still has git 1.7, and there is not currently a backport of a newer git to stable for me to use.
+"""]]
diff --git a/doc/bugs/On_Windows__44___annex_get_fails_with_HTTP_Remote__44___but_believes_it_has_succeeded..mdwn b/doc/bugs/On_Windows__44___annex_get_fails_with_HTTP_Remote__44___but_believes_it_has_succeeded..mdwn
new file mode 100644
index 000000000..b34befcc0
--- /dev/null
+++ b/doc/bugs/On_Windows__44___annex_get_fails_with_HTTP_Remote__44___but_believes_it_has_succeeded..mdwn
@@ -0,0 +1,180 @@
+### Please describe the problem.
+On Windows, with a remote annex configured for HTTP access, attempting to annex get a file will not result in the content being downloaded, but will download a 404 error page as the file.
+
+### What steps will reproduce the problem?
+1. Create an annex (A1) on a Linux system.
+2. "git update-server-info"
+3. run an HTTP server with, a directory up. python -m SimpleHTTPServer
+4. on a Windows system, clone the annex with 'git clone http://remote_host/annex_dir/.git'
+5. "git annex get <file>"
+
+the resulting file will not have the correct content, but rather a 404 error page. In addition, subsequent attempts to "git annex get <file>" will fail, unless you "git annex drop <file>" first. (it appears to believe it correctly retrieved the file).
+
+
+### What version of git-annex are you using? On what operating system?
+Windows 7: 4.20140627-g8a36ec5 (from the git-annex download page)
+
+Debian Linux: 3.20120629 (from the package manager)
+
+### Please provide any additional information below.
+After some debugging, I believe the issue is related to the way git-annex uses curl. it appears that git-annex uses the return code of curl or wget to determine if a download was successful, but curl by default will return status code 0 on a 404, unless the -f option is used (which it is not).
+
+getting git-annex on windows to use wget works around the issue.
+
+
+
+###Full Transcript
+
+#### 1. setup of linux repo
+[[!format sh """
+test-git-annex@linux_host:~/test_annex$ git version
+git version 1.7.10.4
+test-git-annex@linux_host:~/test_annex$ git annex version
+git-annex version: 3.20120629
+local repository version: 3
+default repository version: 3
+supported repository versions: 3
+upgrade supported from repository versions: 0 1 2
+test-git-annex@linux_host: ~test-git-annex@linux_host:~$ mkdir test_annex
+test-git-annex@linux_host: ~test-git-annex@linux_host:~$ cd test_annex/
+test-git-annex@linux_host:~/test_annex$ git init .
+Initialized empty Git repository in /home/test-git-annex/test_annex/.git/
+test-git-annex@linux_host:~/test_annex$ annex init laptop
+init laptop ok
+(Recording state in git...)
+~/test_annextest-git-annex@linux_host:~/test_annex$ echo "this is some content" > file1.txt
+test-git-annex@linux_host:~/test_annex$ git annex add file1.txt
+add file1.txt (checksum...) ok
+(Recording state in git...)
+test-git-annex@linux_host:~/test_annex$ git commit -a -m "initial commit"
+[master (root-commit) 821c6c1] initial commit
+ 1 file changed, 1 insertion(+)
+ create mode 120000 file1.txt
+test-git-annex@linux_host:~/test_annex$ ls -l
+total 4
+lrwxrwxrwx 1 test-git-annex test-git-annex 178 Jul 6 11:33 file1.txt -> .git/annex/objects/J9/m6/SHA256-s21--6ed275e9e01c84a57fdd99d6af793c5d587d02e699cd2c28b32b7dc90f73e729/SHA256-s21--6ed275e9e01c84a57fdd99d6af793c5d587d02e699cd2c28b32b7dc90f73e729
+test-git-annex@linux_host:~/test_annex$ cat file1.txt
+this is some content
+"""]]
+
+#### 2. set up and run http server
+[[!format sh """
+test-git-annex@MrLinuxTablet:~/test_annex$ git update-server-info
+cd ..
+test-git-annex@MrLinuxTablet:~$ python -m SimpleHTTPServer
+Serving HTTP on 0.0.0.0 port 8000 ...
+
+"""]]
+
+#### 3. Set up Windows, clone repo, init annex
+
+[[!format sh """
+
+#Windows 7
+#download and install git from git-scm.com/download/win
+#Git-1.8.3-preview20130601.exe
+#on install, selecting "Run Git from the Windows Command Prompt"
+#on install, selecting "checkout as-is, commit as-is"
+#installs to C:\Program Files (x86)\Git
+#download and install git-annex from http://git-annex.branchable.com/install/
+#git-annex-installer.exe
+#need to right-click 'run as administrator', per reported bug (link here)
+#installs to C:\Program Files (x86)\Git\cmd
+#also installs some utilities, including wget.exe
+
+C:\Users\test-git-annex>git clone http://192.168.0.8:8000/test_annex/.git
+Cloning into 'test_annex'...
+
+C:\Users\test-git-annex>cd test_annex
+
+C:\Users\test-git-annex\test_annex>dir
+ Volume in drive C has no label.
+
+ Directory of C:\Users\test-git-annex\test_annex
+
+<DIR> .
+<DIR> ..
+ 178 file1.txt
+ 1 File(s) 178 bytes
+
+C:\Users\test-git-annex\test_annex>type file1.txt
+.git/annex/objects/J9/m6/SHA256-s21--6ed275e9e01c84a57fdd99d6af793c5d587d02e699cd2c28b32b7dc90f73e729/SHA256-s21--6ed275e9e01c84a57fdd99d6af793c5d587d02e699cd2c28b32b7dc90f73e729
+
+C:\Users\test-git-annex\test_annex>git annex init windows
+init windows
+ Detected a crippled filesystem.
+
+ Enabling direct mode.
+
+ Detected a filesystem without fifo support.
+
+ Disabling ssh connection caching.
+ok
+(Recording state in git...)
+
+"""]]
+
+####4. annex get
+
+[[!format sh """
+#copy Git\bin\libcurl.dll to Git\bin\libcurl-4.dll
+
+C:\Users\test-git-annex\test_annex>git annex -vd get file1.txt
+[<datetime>] read: git ["--git-dir=C:\\Users\\test-git-annex\\test_annex\\.git","--work-tree=C:\\Users\\test-git-annex\\test_annex","ls-files","--cached","-z","--","file1.txt"]
+get file1.txt [<datetime>] read: git ["--git-dir=C:\\Users\\test-git-annex\\test_annex\\.git","--work-tree=C:\\Users\\test-git-annex\\test_annex","show-ref","git-annex"]
+[<datetime>] read: git ["--git-dir=C:\\Users\\test-git-annex\\test_annex\\.git","--work-tree=C:\\Users\\test-git-annex\\test_annex","show-ref","--hash","refs/heads/git-annex"]
+[<datetime>] read: git ["--git-dir=C:\\Users\\test-git-annex\\test_annex\\.git","--work-tree=C:\\Users\\test-git-annex\\test_annex","log","refs/heads/git-annex..36508d74a05fd93daee965f2f73c977852e4b626","--oneline","-n1"]
+[<datetime>] read: git ["--git-dir=C:\\Users\\test-git-annex\\test_annex\\.git","--work-tree=C:\\Users\\test-git-annex\\test_annex","log","refs/heads/git-annex..304263841906c0b4dda39d0fdbe54e4af4307cb8","--oneline","-n1"]
+(merging origin/git-annex into git-annex...)
+[<datetime>] chat: git ["--git-dir=C:\\Users\\test-git-annex\\test_annex\\.git","--work-tree=C:\\Users\\test-git-annex\\test_annex","cat-file","--batch"]
+[<datetime>] feed: git ["--git-dir=C:\\Users\\test-git-annex\\test_annex\\.git","--work-tree=C:\\Users\\test-git-annex\\test_annex","update-index","-z","--index-info"]
+[<datetime>] read: git ["--git-dir=C:\\Users\\test-git-annex\\test_annex\\.git","--work-tree=C:\\Users\\test-git-annex\\test_annex","diff-index","--raw","-z","-r","--no-renames","-l0","--cached","304263841906c0b4dda39d0fdbe54e4af4307cb8"]
+[<datetime>] chat: git ["--git-dir=C:\\Users\\test-git-annex\\test_annex\\.git","--work-tree=C:\\Users\\test-git-annex\\test_annex","hash-object","-t","blob","-w","--stdin","--no-filters"]
+[<datetime>] read: git ["--git-dir=C:\\Users\\test-git-annex\\test_annex\\.git","--work-tree=C:\\Users\\test-git-annex\\test_annex","log","304263841906c0b4dda39d0fdbe54e4af4307cb8..refs/heads/git-annex","--oneline","-n1"]
+(Recording state in git...)
+[<datetime>] read: git ["--git-dir=C:\\Users\\test-git-annex\\test_annex\\.git","--work-tree=C:\\Users\\test-git-annex\\test_annex","write-tree"]
+[<datetime>] chat: git ["--git-dir=C:\\Users\\test-git-annex\\test_annex\\.git","--work-tree=C:\\Users\\test-git-annex\\test_annex","commit-tree","103a0273cf24deec587295845f761b172a63ea19","-p","refs/heads/git-annex","-p","304263841906c0b4dda39d0fdbe54e4af4307cb8"]
+[<datetime>] call: git ["--git-dir=C:\\Users\\test-git-annex\\test_annex\\.git","--work-tree=C:\\Users\\test-git-annex\\test_annex","update-ref","refs/heads/git-annex","538f6b44a762be415ec6fef2b6644c10bc1f3780"]
+[<datetime>] call: curl ["-s","-L","-C","-","-#","-o","C:\\Users\\test-git-annex\\AppData\\Local\\Temp\\git-annex8156.tmp","http://192.168.0.8:8000/test_annex/.git/config"]
+[<datetime>] read: git ["config","--null","--list","--file","C:\\Users\\test-git-annex\\AppData\\Local\\Temp\\git-annex8156.tmp"]
+[<datetime>] call: git ["--git-dir=C:\\Users\\test-git-annex\\test_annex\\.git","--work-tree=C:\\Users\\test-git-annex\\test_annex","config","remote.origin.annex-uuid","64000156-e66a-11e2-aa76-131bb0a453f3"]
+[<datetime>] read: git ["config","--null","--list"]
+(from origin...) [<datetime>] call: curl ["-L","-C","-","-#","-o","C:\\Users\\test-git-annex\\test_annex\\.git\\annex\\tmp\\SHA256-s21--6ed275e9e01c84a57fdd99d6af793c5d587d02e699cd2c28b32b7dc90f73e729","http://192.168.0.8:8000/test_annex/.git/annex\\objects\\c96\\53e\\SHA256-s21--6ed275e9e01c84a57fdd99d6af793c5d587d02e699cd2c28b32b7dc90f73e729\\SHA256-s21--6ed275e9e01c84a57fdd99d6af793c5d587d02e699cd2c28b32b7dc90f73e729"]
+######################################################################## 100.0%
+ok
+[<datetime>] chat: git ["--git-dir=C:\\Users\\test-git-annex\\test_annex\\.git","--work-tree=C:\\Users\\test-git-annex\\test_annex","hash-object","-w","--stdin-paths","--no-filters"]
+[<datetime>] feed: git ["--git-dir=C:\\Users\\test-git-annex\\test_annex\\.git","--work-tree=C:\\Users\\test-git-annex\\test_annex","update-index","-z","--index-info"]
+[<datetime>] read: git ["--git-dir=C:\\Users\\test-git-annex\\test_annex\\.git","--work-tree=C:\\Users\\test-git-annex\\test_annex","show-ref","--hash","refs/heads/git-annex"]
+(Recording state in git...)
+[<datetime>] read: git ["--git-dir=C:\\Users\\test-git-annex\\test_annex\\.git","--work-tree=C:\\Users\\test-git-annex\\test_annex","write-tree"]
+[<datetime>] chat: git ["--git-dir=C:\\Users\\test-git-annex\\test_annex\\.git","--work-tree=C:\\Users\\test-git-annex\\test_annex","commit-tree","b81dc8e53f4c02d433288d7f073be501d27c3648","-p","refs/heads/git-annex"]
+[<datetime>] call: git ["--git-dir=C:\\Users\\test-git-annex\\test_annex\\.git","--work-tree=C:\\Users\\test-git-annex\\test_annex","update-ref","refs/heads/git-annex","949181f4978c2654e156f1e4250f67135ddc2774"]
+
+C:\Users\test-git-annex\test_annex>git annex find .
+file1.txt
+
+C:\Users\test-git-annex\test_annex>type file1.txt
+<head>
+<title>Error response</title>
+</head>
+<body>
+<h1>Error response</h1>
+<p>Error code 404.
+<p>Message: File not found.
+<p>Error code explanation: 404 = Nothing matches the given URI.
+</body>
+"""]]
+
+#### http server output from above
+
+[[!format sh """
+192.168.0.2 - - [<datetime>] "GET /test_annex/.git/annex\objects\c96\53e\SHA256-s21--6ed275e9e01c84a57fdd99d6af793c5d587d02e699cd2c28b32b7dc90f73e729\SHA256-s21--6ed275e9e01c84a57fdd99d6af793c5d587d02e699cd2c28b32b7dc90f73e729 HTTP/1.1" 404 -
+192.168.0.2 - - [<datetime>] code 404, message File not found
+"""]]
+
+> This seems to be two distinct bugs. First, curl was not propigating the exit
+> status. I already fixed that.
+>
+> Second, it's using DOS style path separators when constructing the url.
+> `http://192.168.0.8:8000/test_annex/.git/annex\\objects\\c96`
+> I've put in an (ugly) fix for that. [[done]] --[[Joey]]
diff --git a/doc/bugs/On_Windows__44___annex_get_over_HTTP_sends_URLs_with_incorrect_separator.mdwn b/doc/bugs/On_Windows__44___annex_get_over_HTTP_sends_URLs_with_incorrect_separator.mdwn
new file mode 100644
index 000000000..08bc76ed1
--- /dev/null
+++ b/doc/bugs/On_Windows__44___annex_get_over_HTTP_sends_URLs_with_incorrect_separator.mdwn
@@ -0,0 +1,186 @@
+### Please describe the problem.
+On Windows, attempting to annex get from a remote over HTTP fails. URLs which are nearly correct, but have incorrect slashes, are sent.
+
+### What steps will reproduce the problem?
+1. Create an annex on Linux.
+2. Configure repository for HTTP access
+3. Clone annex on Windows.
+4. "git annex get ."
+5. git annex makes requests for urls like the following: http://host/repo/.git/annex/objects\<3-char-hash>\<3-char-hash>\SHA<file hash>
+
+### What version of git-annex are you using? On what operating system?
+Windows 7: 4.20140627-g8a36ec5 (from the git-annex download page)
+
+Debian Linux: 3.20120629 (from the package manager)
+
+### Please provide any additional information below.
+placing a wrapper script in front of wget which replaces '\' with '/' works around the issue, and allows git annex get to complete.
+
+
+###Full Transcript
+
+#### 1. setup of linux repo
+[[!format sh """
+test-git-annex@linux_host:~/test_annex$ git version
+git version 1.7.10.4
+test-git-annex@linux_host:~/test_annex$ git annex version
+git-annex version: 3.20120629
+local repository version: 3
+default repository version: 3
+supported repository versions: 3
+upgrade supported from repository versions: 0 1 2
+test-git-annex@linux_host: ~test-git-annex@linux_host:~$ mkdir test_annex
+test-git-annex@linux_host: ~test-git-annex@linux_host:~$ cd test_annex/
+test-git-annex@linux_host:~/test_annex$ git init .
+Initialized empty Git repository in /home/test-git-annex/test_annex/.git/
+test-git-annex@linux_host:~/test_annex$ annex init laptop
+init laptop ok
+(Recording state in git...)
+~/test_annextest-git-annex@linux_host:~/test_annex$ echo "this is some content" > file1.txt
+test-git-annex@linux_host:~/test_annex$ git annex add file1.txt
+add file1.txt (checksum...) ok
+(Recording state in git...)
+test-git-annex@linux_host:~/test_annex$ git commit -a -m "initial commit"
+[master (root-commit) 821c6c1] initial commit
+ 1 file changed, 1 insertion(+)
+ create mode 120000 file1.txt
+test-git-annex@linux_host:~/test_annex$ ls -l
+total 4
+lrwxrwxrwx 1 test-git-annex test-git-annex 178 Jul 6 11:33 file1.txt -> .git/annex/objects/J9/m6/SHA256-s21--6ed275e9e01c84a57fdd99d6af793c5d587d02e699cd2c28b32b7dc90f73e729/SHA256-s21--6ed275e9e01c84a57fdd99d6af793c5d587d02e699cd2c28b32b7dc90f73e729
+test-git-annex@linux_host:~/test_annex$ cat file1.txt
+this is some content
+"""]]
+
+#### 2. set up and run http server
+[[!format sh """
+test-git-annex@MrLinuxTablet:~/test_annex$ git update-server-info
+cd ..
+test-git-annex@MrLinuxTablet:~$ python -m SimpleHTTPServer
+Serving HTTP on 0.0.0.0 port 8000 ...
+
+"""]]
+
+#### 3. Set up Windows, clone repo, init annex
+
+[[!format sh """
+
+#Windows 7
+#download and install git from git-scm.com/download/win
+#Git-1.8.3-preview20130601.exe
+#on install, selecting "Run Git from the Windows Command Prompt"
+#on install, selecting "checkout as-is, commit as-is"
+#installs to C:\Program Files (x86)\Git
+#download and install git-annex from http://git-annex.branchable.com/install/
+#git-annex-installer.exe
+#need to right-click 'run as administrator', per reported bug (link here)
+#installs to C:\Program Files (x86)\Git\cmd
+#also installs some utilities, including wget.exe
+
+C:\Users\test-git-annex>git clone http://192.168.0.8:8000/test_annex/.git
+Cloning into 'test_annex'...
+
+C:\Users\test-git-annex>cd test_annex
+
+C:\Users\test-git-annex\test_annex>dir
+ Volume in drive C has no label.
+
+ Directory of C:\Users\test-git-annex\test_annex
+
+<DIR> .
+<DIR> ..
+ 178 file1.txt
+ 1 File(s) 178 bytes
+
+C:\Users\test-git-annex\test_annex>type file1.txt
+.git/annex/objects/J9/m6/SHA256-s21--6ed275e9e01c84a57fdd99d6af793c5d587d02e699cd2c28b32b7dc90f73e729/SHA256-s21--6ed275e9e01c84a57fdd99d6af793c5d587d02e699cd2c28b32b7dc90f73e729
+
+C:\Users\test-git-annex\test_annex>git annex init windows
+init windows
+ Detected a crippled filesystem.
+
+ Enabling direct mode.
+
+ Detected a filesystem without fifo support.
+
+ Disabling ssh connection caching.
+ok
+(Recording state in git...)
+
+"""]]
+
+####4. annex get
+
+[[!format sh """
+#create empty file named 'wget' in Git\cmd, and install cygwin, add to path, to provide necessary DLLs
+C:\Users\test-git-annex\test_annex> git annex get file.txt
+
+C:\Users\test-git-annex\test_annex>git annex -vd get file1.txt
+[<datetime>] read: git ["--git-dir=C:\\Users\\test-git-annex\\test_annex\\.git","--work-tree=C:\\Users\\test-git-annex\\test_annex","ls-files","--cached","-z","--","file1.txt"]
+get file1.txt [<datetime>] read: git ["--git-dir=C:\\Users\\test-git-annex\\test_annex\\.git","--work-tree=C:\\Users\\test-git-annex\\test_annex","show-ref","git-annex"]
+[<datetime>] read: git ["--git-dir=C:\\Users\\test-git-annex\\test_annex\\.git","--work-tree=C:\\Users\\test-git-annex\\test_annex","show-ref","--hash","refs/heads/git-annex"]
+[<datetime>] read: git ["--git-dir=C:\\Users\\test-git-annex\\test_annex\\.git","--work-tree=C:\\Users\\test-git-annex\\test_annex","log","refs/heads/git-annex..98d1182bcee688b06307963dfea81aa70a3c8336","--oneline","-n1"]
+[<datetime>] read: git ["--git-dir=C:\\Users\\test-git-annex\\test_annex\\.git","--work-tree=C:\\Users\\test-git-annex\\test_annex","log","refs/heads/git-annex..304263841906c0b4dda39d0fdbe54e4af4307cb8","--oneline","-n1"]
+(merging origin/git-annex into git-annex...)
+[<datetime>] chat: git ["--git-dir=C:\\Users\\test-git-annex\\test_annex\\.git","--work-tree=C:\\Users\\test-git-annex\\test_annex","cat-file","--batch"]
+[<datetime>] feed: git ["--git-dir=C:\\Users\\test-git-annex\\test_annex\\.git","--work-tree=C:\\Users\\test-git-annex\\test_annex","update-index","-z","--index-info"]
+[<datetime>] read: git ["--git-dir=C:\\Users\\test-git-annex\\test_annex\\.git","--work-tree=C:\\Users\\test-git-annex\\test_annex","diff-index","--raw","-z","-r","--no-renames","-l0","--cached","304263841906c0b4dda39d0fdbe54e4af4307cb8"]
+[<datetime>] chat: git ["--git-dir=C:\\Users\\test-git-annex\\test_annex\\.git","--work-tree=C:\\Users\\test-git-annex\\test_annex","hash-object","-t","blob","-w","--stdin","--no-filters"]
+[<datetime>] read: git ["--git-dir=C:\\Users\\test-git-annex\\test_annex\\.git","--work-tree=C:\\Users\\test-git-annex\\test_annex","log","304263841906c0b4dda39d0fdbe54e4af4307cb8..refs/heads/git-annex","--oneline","-n1"]
+(Recording state in git...)
+[<datetime>] read: git ["--git-dir=C:\\Users\\test-git-annex\\test_annex\\.git","--work-tree=C:\\Users\\test-git-annex\\test_annex","write-tree"]
+[<datetime>] chat: git ["--git-dir=C:\\Users\\test-git-annex\\test_annex\\.git","--work-tree=C:\\Users\\test-git-annex\\test_annex","commit-tree","838284a4dbc1c57bea2595ac7636c32a7a86b745","-p","refs/heads/git-annex","-p","304263841906c0b4dda39d0fdbe54e4af4307cb8"]
+[<datetime>] call: git ["--git-dir=C:\\Users\\test-git-annex\\test_annex\\.git","--work-tree=C:\\Users\\test-git-annex\\test_annex","update-ref","refs/heads/git-annex","c594efcf08bd4de8963cc3fb6890275f623aee12"]
+[<datetime>] call: wget ["-q","-c","-O","C:\\Users\\test-git-annex\\AppData\\Local\\Temp\\git-annex4860.tmp","http://192.168.0.8:8000/test_annex/.git/config"]
+cygwin warning:
+ MS-DOS style path detected: C:\Users\test-git-annex\AppData\Local\Temp\git-annex4860.tmp
+ Preferred POSIX equivalent is: /cygdrive/c/Users/test-git-annex/AppData/Local/Temp/git-annex4860.tmp
+ CYGWIN environment variable option "nodosfilewarning" turns off this warning.
+ Consult the user's guide for more details about POSIX paths:
+ http://cygwin.com/cygwin-ug-net/using.html#using-pathnames
+[<datetime>] read: git ["config","--null","--list","--file","C:\\Users\\test-git-annex\\AppData\\Local\\Temp\\git-annex4860.tmp"]
+[<datetime>] call: git ["--git-dir=C:\\Users\\test-git-annex\\test_annex\\.git","--work-tree=C:\\Users\\test-git-annex\\test_annex","config","remote.origin.annex-uuid","64000156-e66a-11e2-aa76-131bb0a453f3"]
+[<datetime>] read: git ["config","--null","--list"]
+(from origin...) [<datetime>] call: wget ["-c","-O","C:\\Users\\test-git-annex\\test_annex\\.git\\annex\\tmp\\SHA256-s21--6ed275e9e01c84a57fdd99d6af793c5d587d02e699cd2c28b32b7dc90f73e729","http://192.168.0.8:8000/test_annex/.git/annex\\objects\\c96\\53e\\SHA256-s21--6ed275e9e01c84a57fdd99d6af793c5d587d02e699cd2c28b32b7dc90f73e729\\SHA256-s21--6ed275e9e01c84a57fdd99d6af793c5d587d02e699cd2c28b32b7dc90f73e729"]
+cygwin warning:
+ MS-DOS style path detected: C:\Users\test-git-annex\test_annex\.git\annex\tmp\SHA256-s21--6ed275e9e01c84a57fdd99d6af793c5d587d02e699cd2c28b32b7dc90f73e729
+ Preferred POSIX equivalent is: /cygdrive/c/Users/test-git-annex/test_annex/.git/annex/tmp/SHA256-s21--6ed275e9e01c84a57fdd99d6af793c5d587d02e699cd2c28b32b7dc90f73e729
+ CYGWIN environment variable option "nodosfilewarning" turns off this warning.
+ Consult the user's guide for more details about POSIX paths:
+ http://cygwin.com/cygwin-ug-net/using.html#using-pathnames
+--<datetime>--6ed275e9e01c84a57fdd99d6af793c5d587d02e699cd2c28b32b7dc90f73e729
+Connecting to 192.168.0.8:8000... connected.
+HTTP request sent, awaiting response... 404 File not found
+<datetime> ERROR 404: File not found.
+
+[<datetime>] call: wget ["-c","-O","C:\\Users\\test-git-annex\\test_annex\\.git\\annex\\tmp\\SHA256-s21--6ed275e9e01c84a57fdd99d6af793c5d587d02e699cd2c28b32b7dc90f73e729","http://192.168.0.8:8000/test_annex/.git/annex\\objects\\J9\\m6\\SHA256-s21--6ed275e9e01c84a57fdd99d6af793c5d587d02e699cd2c28b32b7dc90f73e729\\SHA256-s21--6ed275e9e01c84a57fdd99d6af793c5d587d02e699cd2c28b32b7dc90f73e729"]
+cygwin warning:
+ MS-DOS style path detected: C:\Users\test-git-annex\test_annex\.git\annex\tmp\SHA256-s21--6ed275e9e01c84a57fdd99d6af793c5d587d02e699cd2c28b32b7dc90f73e729
+ Preferred POSIX equivalent is: /cygdrive/c/Users/test-git-annex/test_annex/.git/annex/tmp/SHA256-s21--6ed275e9e01c84a57fdd99d6af793c5d587d02e699cd2c28b32b7dc90f73e729
+ CYGWIN environment variable option "nodosfilewarning" turns off this warning.
+ Consult the user's guide for more details about POSIX paths:
+ http://cygwin.com/cygwin-ug-net/using.html#using-pathnames
+--<datetime>--6ed275e9e01c84a57fdd99d6af793c5d587d02e699cd2c28b32b7dc90f73e729
+Connecting to 192.168.0.8:8000... connected.
+HTTP request sent, awaiting response... 404 File not found
+<datetime> ERROR 404: File not found.
+
+
+ Unable to access these remotes: origin
+
+ Try making some of these repositories available:
+ 64000156-e66a-11e2-aa76-131bb0a453f3 -- origin (laptop)
+failed
+git-annex: get: 1 failed
+
+"""]]
+
+#### http server output from above
+
+[[!format sh """
+192.168.0.2 - - [<datetime>] code 404, message File not found
+192.168.0.2 - - [<datetime>] "GET /test_annex/.git/annex%5Cobjects%5Cc96%5C53e%5CSHA256-s21--6ed275e9e01c84a57fdd99d6af793c5d587d02e699cd2c28b32b7dc90f73e729%5CSHA256-s21--6ed275e9e01c84a57fdd99d6af793c5d587d02e699cd2c28b32b7dc90f73e729 HTTP/1.1" 404 -
+192.168.0.2 - - [<datetime>] code 404, message File not found
+192.168.0.2 - - [<datetime>] "GET /test_annex/.git/annex%5Cobjects%5CJ9%5Cm6%5CSHA256-s21--6ed275e9e01c84a57fdd99d6af793c5d587d02e699cd2c28b32b7dc90f73e729%5CSHA256-s21--6ed275e9e01c84a57fdd99d6af793c5d587d02e699cd2c28b32b7dc90f73e729 HTTP/1.1" 404 -
+"""]]
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/On_Windows__44___can__39__t_use_a_USB_disk_annex_created_on_Linux.mdwn b/doc/bugs/On_Windows__44___can__39__t_use_a_USB_disk_annex_created_on_Linux.mdwn
new file mode 100644
index 000000000..b997a8c72
--- /dev/null
+++ b/doc/bugs/On_Windows__44___can__39__t_use_a_USB_disk_annex_created_on_Linux.mdwn
@@ -0,0 +1,18 @@
+### Please describe the problem.
+On Windows, git-annex is unable to 'annex get' from a repository hosted on an external USB disk.
+
+### What steps will reproduce the problem?
+1. Create an annex (A1) on a Linux system
+2. Clone A1 to a new annex (A2) to an external USB drive. add A1 as a remote, "annex get ."
+3. Mount the USB drive to a windows system. Clone A2 to a new annex (A3).
+4. add A2 as a remote to A3
+5. "git annex get ."
+6. annex get will fail with file not found errors. This appears to be due to case sensitivity on Windows.
+
+
+### What version of git-annex are you using? On what operating system?
+Windows 7: 4.20140627-g8a36ec5 (from the git-annex download page)
+
+Debian Linux: 3.20120629 (from the package manager)
+
+[[!tag moreinfo]]
diff --git a/doc/bugs/On_Windows__44___can__39__t_use_a_USB_disk_annex_created_on_Linux/comment_1_f224f4155d857a59595658357f97dac1._comment b/doc/bugs/On_Windows__44___can__39__t_use_a_USB_disk_annex_created_on_Linux/comment_1_f224f4155d857a59595658357f97dac1._comment
new file mode 100644
index 000000000..403c9a1b9
--- /dev/null
+++ b/doc/bugs/On_Windows__44___can__39__t_use_a_USB_disk_annex_created_on_Linux/comment_1_f224f4155d857a59595658357f97dac1._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.254.222"
+ subject="comment 1"
+ date="2013-07-07T17:50:40Z"
+ content="""
+Is A2 a bare or a non-bare git repository?
+
+What filesystem is used on the USB drive?
+
+Why do you think it has to do with case sensativity?
+"""]]
diff --git a/doc/bugs/On_Windows__44___can__39__t_use_repository_that_has_a_unix-style_local_remote_configured.mdwn b/doc/bugs/On_Windows__44___can__39__t_use_repository_that_has_a_unix-style_local_remote_configured.mdwn
new file mode 100644
index 000000000..92de1dce3
--- /dev/null
+++ b/doc/bugs/On_Windows__44___can__39__t_use_repository_that_has_a_unix-style_local_remote_configured.mdwn
@@ -0,0 +1,22 @@
+### Please describe the problem.
+On Windows, I try to "annex get" from a Linux based repository, but it fails with no useful error message.
+
+### What steps will reproduce the problem?
+1. Create annex (A1) on a Linux system.
+2. clone A1 to another annex (A2) on the same file tree (on a mounted USB drive, for example)
+3. add A2 as a remote to A1.
+4. clone A1 to an annex (A3) on a Windows 7 system.
+5. attempt to "git annex get ."
+6. annex reports that it can find no repositories, and asks to make one available.
+
+
+### What version of git-annex are you using? On what operating system?
+Windows 7: 4.20140627-g8a36ec5 (from the git-annex download page)
+Debian Linux: 3.20120629 (from the package manager)
+
+### Please provide any additional information below.
+I experienced this bug several times with a plain git-annex install, and the only workaround was removing the unix-style remotes from remote repos.
+
+After other hackery to get git-annex working on Windows, I can't currently reproduce the issue.
+
+[[!tag moreinfo]]
diff --git a/doc/bugs/On_Windows__44___can__39__t_use_repository_that_has_a_unix-style_local_remote_configured/comment_1_95655915ff6ba9fb5d873358ff047496._comment b/doc/bugs/On_Windows__44___can__39__t_use_repository_that_has_a_unix-style_local_remote_configured/comment_1_95655915ff6ba9fb5d873358ff047496._comment
new file mode 100644
index 000000000..d727bcafc
--- /dev/null
+++ b/doc/bugs/On_Windows__44___can__39__t_use_repository_that_has_a_unix-style_local_remote_configured/comment_1_95655915ff6ba9fb5d873358ff047496._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.2.134"
+ subject="comment 1"
+ date="2013-09-13T19:14:55Z"
+ content="""
+I don't understand what is meant by a \"unix-style\" remote.
+
+Generally it helps to provide some commands I can run on Windows to replicate the problem.
+"""]]
diff --git a/doc/bugs/On_Windows__44___wget_is_not_used__44___even_if_available.mdwn b/doc/bugs/On_Windows__44___wget_is_not_used__44___even_if_available.mdwn
new file mode 100644
index 000000000..5420b986c
--- /dev/null
+++ b/doc/bugs/On_Windows__44___wget_is_not_used__44___even_if_available.mdwn
@@ -0,0 +1,67 @@
+### Please describe the problem.
+On Windows, with a remote repository configured for HTTP access, wget is never used, even if it's available in the system. curl is always used.
+
+### What steps will reproduce the problem?
+1. Set up an annex on a remote system, configure it for HTTP access, run an HTTP server.
+2. over HTTP, clone it to Windows
+3. "annex get -vd <file>"
+4. note that curl is used.
+
+
+### What version of git-annex are you using? On what operating system?
+Windows 7: 4.20140627-g8a36ec5 (from the git-annex download page)
+
+### Additional Info
+After some debugging, it appears the issue is that git-annex looks to see if the file 'wget' is available in any directory on the PATH. on windows, wget is installed as 'wget.exe', and the file 'wget' does not exist anywhere. creating a file named 'wget' works around the issue. (wget.exe appears to still be the file used)
+
+###Full Transcript
+1. remote annex is created on host 192.168.0.8, with file "file1.txt"
+[[!format sh """
+#Windows 7
+#download and install git from git-scm.com/download/win
+#Git-1.8.3-preview20130601.exe
+#on install, selecting "Run Git from the Windows Command Prompt"
+#on install, selecting "checkout as-is, commit as-is"
+#installs to C:\Program Files (x86)\Git
+#download and install git-annex from http://git-annex.branchable.com/install/
+#git-annex-installer.exe
+#need to right-click 'run as administrator', per reported bug (link here)
+#installs to C:\Program Files (x86)\Git\cmd
+#also installs some utilities, including wget.exe
+
+C:\Users\test-git-annex>git clone http://192.168.0.8:8000/test_annex/.git
+Cloning into 'test_annex'...
+
+C:\Users\test-git-annex>cd test_annex
+
+C:\Users\test-git-annex\test_annex>dir
+ Volume in drive C has no label.
+
+ Directory of C:\Users\test-git-annex\test_annex
+
+<DIR> .
+<DIR> ..
+ 178 file1.txt
+ 1 File(s) 178 bytes
+
+C:\Users\test-git-annex\test_annex>type file1.txt
+.git/annex/objects/J9/m6/SHA256-s21--6ed275e9e01c84a57fdd99d6af793c5d587d02e699cd2c28b32b7dc90f73e729/SHA256-s21--6ed275e9e01c84a57fdd99d6af793c5d587d02e699cd2c28b32b7dc90f73e729
+
+C:\Users\test-git-annex\test_annex>git annex init windows
+init windows
+ Detected a crippled filesystem.
+
+ Enabling direct mode.
+
+ Detected a filesystem without fifo support.
+
+ Disabling ssh connection caching.
+ok
+(Recording state in git...)
+
+C:\Users\test-git-annex\test_annex> git annex get file.txt
+#fails, with error dialog box, indicating libcurl-4.dll is missing, indicating git-annex is trying to use curl.
+
+"""]]
+
+> I fixed this immediately after it was mentioned on IRC. [[done]] --[[Joey]]
diff --git a/doc/bugs/On_restart__44___most_repositories__44___including_original_one__44___gone..mdwn b/doc/bugs/On_restart__44___most_repositories__44___including_original_one__44___gone..mdwn
new file mode 100644
index 000000000..e01310336
--- /dev/null
+++ b/doc/bugs/On_restart__44___most_repositories__44___including_original_one__44___gone..mdwn
@@ -0,0 +1,230 @@
+### Please describe the problem.
+
+I had set up git-annex on a mac; I had created an initial repository at ~/annex; I had created a second repository on an external drive, at /Volumes/Biblio/annex; I had paired with three other machines on the same network, (two linux, one other mac) and set up a remote server as a backup-type repository. All seemed well. It had finally finished syncing everything to the remote server (my upload speeds are slow).
+
+I closed the firefox window showing the dashboard. I wanted to reopen it, so I ran the git-annex.app again, presuming on a running instance that that just opens the browser back at the webapp. Firefox window opened, but the only repository was the second one I'd made on the external drive.
+
+I restarted, as best as I could work out: git-annex assistant --stop, then because that left behind a process, killall git-annex. Then restarted the app.
+
+Firefox opened on the webapp. I had two repositories: The one on the external drive (now the "Here" repo) and the one on ~/annex but only as if it was paired from a different machine.
+
+ie: I see only "celestia.local (rachel@celestia.local~/annex)". This machine *is* celestia.local.
+
+That's it. Startup scan took a couple of minutes but didn't add anything. Then it decided to sync to celestia.local, which it took a little time over but didn't apparently do anything.
+
+If I drop files into ~/annex they are not synced anywhere. ~/annex still has a .git directory, populated with git files, it looks intact. It's just not being seen.
+
+Is it possible because the user is prompted to create their initial repo at ~/Desktop/annex it will by default only look there, then start looking in external drives for it? So the fact I didn't want it on my desktop, but put it directly in home, meant it got lost on restart?
+
+git-annex vicfg in ~/annex shows me this:
+
+[[!format sh """
+# git-annex configuration
+#
+# Changes saved to this file will be recorded in the git-annex branch.
+#
+# Lines in this file have the format:
+# setting uuid = value
+
+# Repository trust configuration
+# (Valid trust levels: trusted semitrusted untrusted dead)
+# (for web)
+#trust 00000000-0000-0000-0000-000000000001 = semitrusted
+# (for rachel@octavia:~/annex)
+#trust 161dec38-e8be-43b8-86c5-555d35ce3416 = semitrusted
+# (for rachel@celestia.local:~/annex)
+#trust 179fcddf-e247-4577-804b-267feed8abb1 = semitrusted
+# (for 192.168.1.103_annex (rachel@rainbow.local:~/annex))
+#trust 256d5762-150d-4d5d-9340-517de298c874 = semitrusted
+# (for twilight.local_annex (rachel@twilight:~/annex))
+#trust aeef7490-ce27-4255-b800-1947706c4a06 = semitrusted
+# (for rachel@octavia:~/annex)
+#trust c469fbce-f3b4-4e27-a54f-0b747797a7d5 = semitrusted
+# (for annex (Biblio's Copy))
+#trust c9e307e2-1189-47ed-8ad4-03b5c1b64e36 = semitrusted
+# (for luna.strangenoises.org_annex)
+#trust f36dbdf8-1bba-11e3-9dbe-f33cfb0e2bed = semitrusted
+# (for octavia.local_annex (rachel@octavia:~/annex))
+#trust f748a5ed-d870-48fb-b3ec-811488eb2faa = semitrusted
+# (for rachel@twilight:~/annex)
+#trust fcaba03e-1ba5-11e3-90f1-57fe1467e006 = semitrusted
+
+# Repository groups
+# (Standard groups: client transfer backup incrementalbackup smallarchive archive source manual public unwanted)
+# (Separate group names with spaces)
+# (for rachel@octavia:~/annex)
+group 161dec38-e8be-43b8-86c5-555d35ce3416 = client
+# (for rachel@celestia.local:~/annex)
+group 179fcddf-e247-4577-804b-267feed8abb1 = client
+# (for 192.168.1.103_annex (rachel@rainbow.local:~/annex))
+group 256d5762-150d-4d5d-9340-517de298c874 = client
+# (for twilight.local_annex (rachel@twilight:~/annex))
+group aeef7490-ce27-4255-b800-1947706c4a06 = client
+# (for rachel@octavia:~/annex)
+group c469fbce-f3b4-4e27-a54f-0b747797a7d5 = client
+# (for annex (Biblio's Copy))
+group c9e307e2-1189-47ed-8ad4-03b5c1b64e36 = client
+# (for octavia.local_annex (rachel@octavia:~/annex))
+group f748a5ed-d870-48fb-b3ec-811488eb2faa = client
+# (for rachel@twilight:~/annex)
+group fcaba03e-1ba5-11e3-90f1-57fe1467e006 = client
+# (for luna.strangenoises.org_annex)
+group f36dbdf8-1bba-11e3-9dbe-f33cfb0e2bed = transfer
+# (for web)
+#group 00000000-0000-0000-0000-000000000001 =
+
+# Repository preferred contents
+# (for rachel@octavia:~/annex)
+content 161dec38-e8be-43b8-86c5-555d35ce3416 = standard
+# (for rachel@celestia.local:~/annex)
+content 179fcddf-e247-4577-804b-267feed8abb1 = standard
+# (for 192.168.1.103_annex (rachel@rainbow.local:~/annex))
+content 256d5762-150d-4d5d-9340-517de298c874 = standard
+# (for twilight.local_annex (rachel@twilight:~/annex))
+content aeef7490-ce27-4255-b800-1947706c4a06 = standard
+# (for rachel@octavia:~/annex)
+content c469fbce-f3b4-4e27-a54f-0b747797a7d5 = standard
+# (for annex (Biblio's Copy))
+content c9e307e2-1189-47ed-8ad4-03b5c1b64e36 = standard
+# (for luna.strangenoises.org_annex)
+content f36dbdf8-1bba-11e3-9dbe-f33cfb0e2bed = standard
+# (for octavia.local_annex (rachel@octavia:~/annex))
+content f748a5ed-d870-48fb-b3ec-811488eb2faa = standard
+# (for rachel@twilight:~/annex)
+content fcaba03e-1ba5-11e3-90f1-57fe1467e006 = standard
+# (for web)
+#content 00000000-0000-0000-0000-000000000001 =
+"""]]
+
+while the same command in /Volumes/Biblio/annex gives:
+
+[[!format sh """
+# git-annex configuration
+#
+# Changes saved to this file will be recorded in the git-annex branch.
+#
+# Lines in this file have the format:
+# setting uuid = value
+
+# Repository trust configuration
+# (Valid trust levels: trusted semitrusted untrusted dead)
+# (for web)
+#trust 00000000-0000-0000-0000-000000000001 = semitrusted
+# (for rachel@octavia:~/annex)
+#trust 161dec38-e8be-43b8-86c5-555d35ce3416 = semitrusted
+# (for celestia.local (rachel@celestia.local:~/annex))
+#trust 179fcddf-e247-4577-804b-267feed8abb1 = semitrusted
+# (for rachel@rainbow.local:~/annex)
+#trust 256d5762-150d-4d5d-9340-517de298c874 = semitrusted
+# (for rachel@twilight:~/annex)
+#trust aeef7490-ce27-4255-b800-1947706c4a06 = semitrusted
+# (for rachel@octavia:~/annex)
+#trust c469fbce-f3b4-4e27-a54f-0b747797a7d5 = semitrusted
+# (for Biblio's Copy)
+#trust c9e307e2-1189-47ed-8ad4-03b5c1b64e36 = semitrusted
+# (for )
+#trust f36dbdf8-1bba-11e3-9dbe-f33cfb0e2bed = semitrusted
+# (for rachel@octavia:~/annex)
+#trust f748a5ed-d870-48fb-b3ec-811488eb2faa = semitrusted
+# (for rachel@twilight:~/annex)
+#trust fcaba03e-1ba5-11e3-90f1-57fe1467e006 = semitrusted
+
+# Repository groups
+# (Standard groups: client transfer backup incrementalbackup smallarchive archive source manual public unwanted)
+# (Separate group names with spaces)
+# (for rachel@octavia:~/annex)
+group 161dec38-e8be-43b8-86c5-555d35ce3416 = client
+# (for celestia.local (rachel@celestia.local:~/annex))
+group 179fcddf-e247-4577-804b-267feed8abb1 = client
+# (for rachel@rainbow.local:~/annex)
+group 256d5762-150d-4d5d-9340-517de298c874 = client
+# (for rachel@twilight:~/annex)
+group aeef7490-ce27-4255-b800-1947706c4a06 = client
+# (for rachel@octavia:~/annex)
+group c469fbce-f3b4-4e27-a54f-0b747797a7d5 = client
+# (for Biblio's Copy)
+group c9e307e2-1189-47ed-8ad4-03b5c1b64e36 = client
+# (for rachel@octavia:~/annex)
+group f748a5ed-d870-48fb-b3ec-811488eb2faa = client
+# (for rachel@twilight:~/annex)
+group fcaba03e-1ba5-11e3-90f1-57fe1467e006 = client
+# (for )
+group f36dbdf8-1bba-11e3-9dbe-f33cfb0e2bed = transfer
+# (for web)
+#group 00000000-0000-0000-0000-000000000001 =
+
+# Repository preferred contents
+# (for rachel@octavia:~/annex)
+content 161dec38-e8be-43b8-86c5-555d35ce3416 = standard
+# (for celestia.local (rachel@celestia.local:~/annex))
+content 179fcddf-e247-4577-804b-267feed8abb1 = standard
+# (for rachel@rainbow.local:~/annex)
+content 256d5762-150d-4d5d-9340-517de298c874 = standard
+# (for rachel@twilight:~/annex)
+content aeef7490-ce27-4255-b800-1947706c4a06 = standard
+# (for rachel@octavia:~/annex)
+content c469fbce-f3b4-4e27-a54f-0b747797a7d5 = standard
+# (for Biblio's Copy)
+content c9e307e2-1189-47ed-8ad4-03b5c1b64e36 = standard
+# (for )
+content f36dbdf8-1bba-11e3-9dbe-f33cfb0e2bed = standard
+# (for rachel@octavia:~/annex)
+content f748a5ed-d870-48fb-b3ec-811488eb2faa = standard
+# (for rachel@twilight:~/annex)
+content fcaba03e-1ba5-11e3-90f1-57fe1467e006 = standard
+# (for web)
+#content 00000000-0000-0000-0000-000000000001 =
+"""]]
+
+### What steps will reproduce the problem?
+
+As above. I have no idea what just happened, but apart from git-annex assistant --stop and having to mop up leftover processes, I didn't use the git-annex commandline for anything.
+
+### What version of git-annex are you using? On what operating system?
+
+Mac OS X 10.8.4
+
+ Version: 4.20130909-ga29f960
+ Build flags: Assistant Webapp Pairing Testsuite S3 WebDAV FsEvents XMPP DNS Feeds Quvi
+
+### Please provide any additional information below.
+
+The log on ~/annex/.git/annex/daemon.log is huge and full of transfers of files with my personal filenames. I'd rather not. It appears to end normally.
+
+Now there is a short log in /Volumes/Biblio/annex/.git/annex/daemon.log from, I guess, the time I tried to restart. For some reason therefore, after the successful session finished, on restart it only looks here. This log is appended.
+
+[[!format sh """
+[2013-09-12 21:35:39 BST] main: starting assistant version 4.20130909-ga29f960
+
+[2013-09-12 21:35:39 BST] TransferScanner: Syncing with celestia.local
+Already up-to-date.
+
+(scanning...) [2013-09-12 21:35:39 BST] Watcher: Performing startup scan
+From /Users/rachel/annex
+ * [new branch] git-annex -> celestia.local/git-annex
+ * [new branch] master -> celestia.local/master
+ * [new branch] synced/git-annex -> celestia.local/synced/git-annex
+ * [new branch] synced/master -> celestia.local/synced/master
+Updating 4f974a8..74770d9
+Fast-forward
+Already up-to-date.
+Already up-to-date.
+Already up-to-date.
+[2013-09-12 21:36:39 BST] Pusher: Syncing with celestia.local
+(merging celestia.local/git-annex celestia.local/synced/git-annex into git-annex...)
+(Recording state in git...)
+
+
+
+
+(started...) error: Ref refs/heads/synced/git-annex is at 5b4ed9b3098e936d60b61a1d3915fa29e8c823d0 but expected 792d2a5c14b0b6327d2089e174063c474ba5a764
+remote: error: failed to lock refs/heads/synced/git-annex
+To /Users/rachel/annex
+ 792d2a5..5b4ed9b git-annex -> synced/git-annex
+To /Users/rachel/annex
+ ! [remote rejected] git-annex -> synced/git-annex (failed to lock)
+error: failed to push some refs to '/Users/rachel/annex'
+Everything up-to-date
+"""]]
+
+Well, I see that thing about "failed to lock". I can imagine that my 'killall git-annex' to kill a leftover process that was hanging around after I'd done git-annex assistant --stop might have left stale lock files, somewhere... but of course I only got as far as doing that because I was already encountering problems, just trying to return to the webapp.
diff --git a/doc/bugs/On_restart__44___most_repositories__44___including_original_one__44___gone./comment_1_3a3891c9d7ee808f6a71780cb628f23d._comment b/doc/bugs/On_restart__44___most_repositories__44___including_original_one__44___gone./comment_1_3a3891c9d7ee808f6a71780cb628f23d._comment
new file mode 100644
index 000000000..a26db0870
--- /dev/null
+++ b/doc/bugs/On_restart__44___most_repositories__44___including_original_one__44___gone./comment_1_3a3891c9d7ee808f6a71780cb628f23d._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.51"
+ subject="comment 1"
+ date="2013-09-12T21:29:39Z"
+ content="""
+The git-annex webapp displays a view from \"inside\" one git repsitory at a time. It seems to me that you have two or more local git repositories; one in ~/annex and one on a removable drive. The webapp is coming up viewing from inside your removable drive's repository. You can change the repository that the webapp views by going to the Repository menu in the upper-right corner and selecting Switch repository. The webapp will remember which repository it viewed last, and come back up showing that same repository.
+
+It's BTW an unusual configuration to have the git-annex assistant directly running on a removable drive as you seem to have done. You must have previously went to the Repository menu and selected \"Add another local repository\", and then added the removable drive, and then connected that repository up to your ~/annex repository. Which would explain why the webapp was last showing the repository on the removable drive. The more usual way to add a removable drive is to use the \"Add another repository\" button and select \"Removable drive\".
+
+I think, but am not sure, that the error \"Ref refs/heads/synced/git-annex is at 5b4ed9b3098e936d60b61a1d3915fa29e8c823d0 but expected 792d2a5c14b0b6327d2089e174063c474ba5a764\" is due to having two git-annex assistants running in these two different repositories and both updating them both at the same time. You might want to stop all git-annex processes, edit `~/.config/git-annex/autostart` and remove the removable drive repository from that list, leaving only `~/annex` in the list.
+"""]]
diff --git a/doc/bugs/On_restart__44___most_repositories__44___including_original_one__44___gone./comment_2_2bc6efb1d9e872cc5d4fbfbaaf5cc10e._comment b/doc/bugs/On_restart__44___most_repositories__44___including_original_one__44___gone./comment_2_2bc6efb1d9e872cc5d4fbfbaaf5cc10e._comment
new file mode 100644
index 000000000..10fad2252
--- /dev/null
+++ b/doc/bugs/On_restart__44___most_repositories__44___including_original_one__44___gone./comment_2_2bc6efb1d9e872cc5d4fbfbaaf5cc10e._comment
@@ -0,0 +1,27 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlEhzszkzOIy8-Rx8b2mcr75QcnIc6O_OA"
+ nickname="Rachel"
+ subject="I don't know whether I've fixed it or confused things further"
+ date="2013-09-12T21:30:44Z"
+ content="""
+I shut down the daemon that was running from the webapp itself.
+
+Instead of launching by using the app, I did:
+
+[[!format txt \"\"\"
+celestia:~ rachel$ cd annex/
+celestia:annex rachel$ git-annex assistant
+(merging synced/git-annex into git-annex...)
+celestia:annex rachel$ git-annex webapp
+Launching web browser on file:///Users/rachel/annex/.git/annex/webapp.html
+celestia:annex rachel$
+\"\"\"]]
+
+It opened the webapp. I could see all the repos back again.
+
+It also seems to be syncing to everything else, sending the files all over again, even though they haven't changed.
+
+It's just about possible it's completing the job, as I'm not sure I saw the files syncing now, being synced earlier. But... in that earlier session it had run the queue dry, *it* thought it had completed syncing.
+
+What's going on?
+"""]]
diff --git a/doc/bugs/On_restart__44___most_repositories__44___including_original_one__44___gone./comment_3_fff1e778a6334258c173a96e6bf7ef6a._comment b/doc/bugs/On_restart__44___most_repositories__44___including_original_one__44___gone./comment_3_fff1e778a6334258c173a96e6bf7ef6a._comment
new file mode 100644
index 000000000..4d44aaf5c
--- /dev/null
+++ b/doc/bugs/On_restart__44___most_repositories__44___including_original_one__44___gone./comment_3_fff1e778a6334258c173a96e6bf7ef6a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.51"
+ subject="comment 3"
+ date="2013-09-12T21:33:18Z"
+ content="""
+See my explanation above. By manually starting the webapp inside your ~/annex repository you forced it to view that repository.
+
+It's not unusual for the webapp to display it syncing some files that have been synced before. This repository may not be up-to-date on which files have been sent where, and it will quickly notice the file has already been transferred and skip doing anything for that file.
+"""]]
diff --git a/doc/bugs/On_restart__44___most_repositories__44___including_original_one__44___gone./comment_4_2a86da97a89e28f0a0f5e160d4932ae6._comment b/doc/bugs/On_restart__44___most_repositories__44___including_original_one__44___gone./comment_4_2a86da97a89e28f0a0f5e160d4932ae6._comment
new file mode 100644
index 000000000..16a5a351f
--- /dev/null
+++ b/doc/bugs/On_restart__44___most_repositories__44___including_original_one__44___gone./comment_4_2a86da97a89e28f0a0f5e160d4932ae6._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlEhzszkzOIy8-Rx8b2mcr75QcnIc6O_OA"
+ nickname="Rachel"
+ subject="Last night's comment"
+ date="2013-09-13T10:28:02Z"
+ content="""
+> It's BTW an unusual configuration to have the git-annex assistant directly running on a removable drive as you seem to have done. You must have previously went to the Repository menu and selected \"Add another local repository\", and then added the removable drive, and then connected that repository up to your ~/annex repository. Which would explain why the webapp was last showing the repository on the removable drive. The more usual way to add a removable drive is to use the \"Add another repository\" button and select \"Removable drive\".
+
+That is exactly how I'd added that repository, yes. I didn't notice the dedicated \"removable drive\" option until later. :-) I thought it possibly appropriate to leave it that way because, while Biblio is an external drive and remov*able*, in practice I never remove it; it's a permanent fixture.
+
+After all, this is a mac mini server, originally (no longer running Server) so it has a second *internal* drive. It would have been even more logical for me to have added a second repo on there in the same manner, as it's most definitely not removable without extreme effort; but it still mounts inside /Volumes, and presumably if I'd added it as a non-removable repo, I'd have had the same problem?
+
+> It's not unusual for the webapp to display it syncing some files that have been synced before. This repository may not be up-to-date on which files have been sent where, and it will quickly notice the file has already been transferred and skip doing anything for that file.
+
+Yes, that's probably what happened. It finished pretty quickly, about a minute after sending my previous comment.
+
+Going to bed now, but tomorrow I'll follow the remaining suggestions; basically I'll remove the repo on the external drive then, if I still want it there, I'll add it back in the other way, so it thinks of it as removable.
+
+"""]]
diff --git a/doc/bugs/On_restart__44___most_repositories__44___including_original_one__44___gone./comment_5_41b8e8e58025cc8c8f12efb9a51acd29._comment b/doc/bugs/On_restart__44___most_repositories__44___including_original_one__44___gone./comment_5_41b8e8e58025cc8c8f12efb9a51acd29._comment
new file mode 100644
index 000000000..685d1b024
--- /dev/null
+++ b/doc/bugs/On_restart__44___most_repositories__44___including_original_one__44___gone./comment_5_41b8e8e58025cc8c8f12efb9a51acd29._comment
@@ -0,0 +1,50 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlEhzszkzOIy8-Rx8b2mcr75QcnIc6O_OA"
+ nickname="Rachel"
+ subject="And this morning..."
+ date="2013-09-13T10:38:35Z"
+ content="""
+I tried removing the second repo, by deleting it, it seemed to begin normally. Then it just hung, and hung.
+
+Looking at logs, it seemed to be hung on dropping one file - a very small file in fact, but it was probably the most recent file to be added. So the end of the log just looked like:
+
+[[!format txt \"\"\"
+drop annex old stuff/renegade/issue7back.pdf ok
+drop annex old stuff/renegade/issue7fiction.pdf ok
+drop annex postgresql 9.0->9.1 upgrade process
+\"\"\"]]
+
+After a while I started getting problems in other terminal shells where I was doing stuff unrelated to git annex. eg: on trying to open a new terminal window, it would open, then shut immediately, or it would open with just:
+
+[[!format txt \"\"\"
+forkpty: Resource temporarily unavailable
+Could not create a new process and open a pseudo-tty.
+\"\"\"]]
+
+Various other commands that would have resulted in a fork were failing too. In the end I shut down git annex (using the shutdown daemon open in the menu in the webapp), and everything went back to normal.
+
+This is the end of the daemon.log from this morning. I don't want to paste the whole thing, as essentially it lists all my private filenames, and there's a lot. In fact I wonder if the quantity of files may be a factor:
+
+[[!format txt \"\"\"
+drop annex old stuff/renegade/index.html ok
+drop annex old stuff/renegade/issue1.pdf ok
+drop annex old stuff/renegade/issue2.pdf ok
+drop annex old stuff/renegade/issue3.pdf ok
+drop annex old stuff/renegade/issue4.pdf ok
+drop annex old stuff/renegade/issue4coverpic.pdf ok
+drop annex old stuff/renegade/issue6articles.pdf ok
+drop annex old stuff/renegade/issue6cover.pdf ok
+drop annex old stuff/renegade/issue6fiction.pdf ok
+drop annex old stuff/renegade/issue7articles.pdf ok
+drop annex old stuff/renegade/issue7back.pdf ok
+drop annex old stuff/renegade/issue7fiction.pdf ok
+drop annex postgresql 9.0->9.1 upgrade process [2013-09-13 11:25:07 BST] NetWatcherFallback: Syncing with twilight.local_annex, octavia.local_annex, 192.168.1.103_annex, luna.strangenoises.org_annex
+NetWatcherFallback crashed: git: createProcess: resource exhausted (Resource temporarily unavailable)
+[2013-09-13 11:25:07 BST] NetWatcherFallback: warning NetWatcherFallback crashed: git: createProcess: resource exhausted (Resource temporarily unavailable)
+recv: resource vanisrhreeecdcv v:(: C rorenesnsoeoucurtrciceoe n v varanenisiseshthe edbd y ( (CpCoeonennrne)ec
+cttiioonn rreesseett bbyy ppeeeerr))
+
+[2013-09-13 11:26:32 BST] main: warning git-annex has been shut down
+\"\"\"]]
+
+"""]]
diff --git a/doc/bugs/On_restart__44___most_repositories__44___including_original_one__44___gone./comment_6_38afcd8e7fb278ca0ee2e9e0c9f6883e._comment b/doc/bugs/On_restart__44___most_repositories__44___including_original_one__44___gone./comment_6_38afcd8e7fb278ca0ee2e9e0c9f6883e._comment
new file mode 100644
index 000000000..c0923b22a
--- /dev/null
+++ b/doc/bugs/On_restart__44___most_repositories__44___including_original_one__44___gone./comment_6_38afcd8e7fb278ca0ee2e9e0c9f6883e._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlEhzszkzOIy8-Rx8b2mcr75QcnIc6O_OA"
+ nickname="Rachel"
+ subject="comment 6"
+ date="2013-09-13T10:52:07Z"
+ content="""
+FYI, if there's any relevance to the number of files in the annex, there are 1899 files in the annex at the moment, so that many in the one being deleted. The one it hung on, \"postgresql 9.0->9.1 upgrade process\" was indeed the last one that comes up in a find command, which I think means the most recently added to this dir.
+
+Creating too many threads?
+"""]]
diff --git a/doc/bugs/On_restart__44___most_repositories__44___including_original_one__44___gone./comment_7_06de36dcde4c52ab74c8134f3242ac02._comment b/doc/bugs/On_restart__44___most_repositories__44___including_original_one__44___gone./comment_7_06de36dcde4c52ab74c8134f3242ac02._comment
new file mode 100644
index 000000000..c11630ef7
--- /dev/null
+++ b/doc/bugs/On_restart__44___most_repositories__44___including_original_one__44___gone./comment_7_06de36dcde4c52ab74c8134f3242ac02._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlEhzszkzOIy8-Rx8b2mcr75QcnIc6O_OA"
+ nickname="Rachel"
+ subject="comment 7"
+ date="2013-09-13T10:54:37Z"
+ content="""
+... and resolved for myself by just deleting (dropping in the trash for now) the annex on the external volume, restarting git-annex assistant and *disabling* that repo from the menu rather than deleting it.
+
+"""]]
diff --git a/doc/bugs/Open_webapp_ask_to_create_new_repo___40__on_first_start__41___even_if_repo_exists_on_Android.mdwn b/doc/bugs/Open_webapp_ask_to_create_new_repo___40__on_first_start__41___even_if_repo_exists_on_Android.mdwn
new file mode 100644
index 000000000..8d1d3e8ec
--- /dev/null
+++ b/doc/bugs/Open_webapp_ask_to_create_new_repo___40__on_first_start__41___even_if_repo_exists_on_Android.mdwn
@@ -0,0 +1,40 @@
+### Please describe the problem.
+On the first run it seems "Open Webapp" always use the URL used to configure a new repo.
+
+### What steps will reproduce the problem?
+I'm using a /sdcard/DCIM annex.
+
+1. close the tabs in the git annex terminal to close git annex
+2. force close the application in the settings and delete data (not sure if it's needed)
+3. delete /sdcard/DCIM/.git/ and /sdcard/git-annex.home/ (I'm not sure I'm deleting everything, maybe I missed some dirs)
+4. start git annex
+
+(WebApp opens and ask to create a repo) see: [http://i.imgur.com/v0EUuir.png](http://i.imgur.com/v0EUuir.png)
+
+5. Click "Make Camera Repository"
+
+(WebApp scans and commits the files) see: [http://i.imgur.com/97rYfXa.png](http://i.imgur.com/97rYfXa.png) (note that the port changed)
+
+6. Return to the terminal. see: [http://i.imgur.com/edL5and.png](http://i.imgur.com/edL5and.png)
+7. Open WebApp using the menu
+
+(Git annex opens the URL to configure a new repo (the webapp is still accessible with the other url). see: [http://i.imgur.com/T8A5NTD.png](http://i.imgur.com/T8A5NTD.png)
+
+If I close and reopen the terminal, the good url is used when I use "open webapp"
+
+### What version of git-annex are you using? On what operating system?
+4.20130601-g7483ca4
+
+### Please provide any additional information below.
+
+[[!format sh """
+[2013-06-01 17:13:34 EDT] main: starting assistant version 4.20130601-g7483ca4
+(scanning...) [2013-06-01 17:13:34 EDT] Watcher: Performing startup scan
+(started...) [2013-06-01 17:13:42 EDT] Committer: Adding 123 files
+
+add Camera/IMG_20130223_111411.jpg (checksum...) ok
+[...]
+[2013-06-01 17:14:17 EDT] Committer: Committing changes to git
+"""]]
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/Open_webapp_ask_to_create_new_repo___40__on_first_start__41___even_if_repo_exists_on_Android/comment_1_9f10bf273b15e93f1eea029f091f26cb._comment b/doc/bugs/Open_webapp_ask_to_create_new_repo___40__on_first_start__41___even_if_repo_exists_on_Android/comment_1_9f10bf273b15e93f1eea029f091f26cb._comment
new file mode 100644
index 000000000..9ed036f84
--- /dev/null
+++ b/doc/bugs/Open_webapp_ask_to_create_new_repo___40__on_first_start__41___even_if_repo_exists_on_Android/comment_1_9f10bf273b15e93f1eea029f091f26cb._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-06-01T23:39:39Z"
+ content="""
+Ah yes, I see what's going on. It's not updating the url in the special file added for Android.
+
+Should be an easy fix one I return from vacation.
+
+Workaround: Open a new terminal tab and it will open the web browser viewing the repo you set up.
+"""]]
diff --git a/doc/bugs/Out_of_memory_error_in_fsck_whereis_find_and_status_cmds.mdwn b/doc/bugs/Out_of_memory_error_in_fsck_whereis_find_and_status_cmds.mdwn
new file mode 100644
index 000000000..c127bac15
--- /dev/null
+++ b/doc/bugs/Out_of_memory_error_in_fsck_whereis_find_and_status_cmds.mdwn
@@ -0,0 +1,84 @@
+Before I start on what's gone wrong, many thanks for a great program: finally a way of finding out where I've put all those files, and I enjoyed your talk in Australia. Not quite to New Zealand, but a good start :-)
+
+To play with git-annex, I decided to convert my ~/Downloads directory to a git-annex repository, as there were a wide variety of files in it, mostly easily replaceable, and also handy to have on multiple machines. In hindsight, probably wasn't a great idea, as I'd regularly forget it was a git-annex repo and move files and directories out manually, which caused all sorts of fun trying to sort out the dead symlinks. Then I after one update, the repository format changed, from WORM to xxx256 format which meant there were now both sorts in the GA object store.
+
+More recently I'd tried converting the repo to direct mode, you get the idea: lots of playing with git-annex commands, and now that I think about it, possibly some git commands too trying to repair missing files.
+
+Anyway I've ended up with a 27GB git-annex repo that now manages to kill git-annex whenever I try to check it using "git-annex fsck".
+
+Not only does the fsck subcommand cause it to die, but also "find", "whereis" and "status". It dies on the same file (for find/whereis/fsck).
+
+e.g.
+
+ ... lots of stuff deleted ...
+ whereis 1wolf14.zip (2 copies)
+ 051f0b00-e265-11e1-894e-3b0b3f3844f2 -- Laptop
+ 2c4e11e0-a1b4-11e1-9a02-73e17b04c00f -- here (myPC - Downloads)
+ ok
+ git-annex: out of memory (requested 2097152 bytes)
+
+Now "git status" for some repo data:
+
+ myPC:~/Downloads$ git annex status
+ supported backends: SHA256E SHA1E SHA512E SHA224E SHA384E SHA256 SHA1 SHA512 SHA224 SHA384 WORM URL
+ supported remote types: git S3 bup directory rsync web webdav glacier hook
+ repository mode: direct
+ trusted repositories: 0
+ semitrusted repositories: 4
+ 00000000-0000-0000-0000-000000000001 -- web
+ 051f0b00-e265-11e1-894e-3b0b3f3844f2 -- Laptop
+ 2c4e11e0-a1b4-11e1-9a02-73e17b04c00f -- here (myPC - Downloads)
+ 48fbe52a-a1b3-11e1-bb80-ebc15118871d -- netbk
+ untrusted repositories: 0
+ dead repositories: 0
+ transfers in progress: none
+ available local disk space: 100 gigabytes (+1 megabyte reserved)
+ local annex keys: 1719
+ local annex size: 27 gigabytes
+ known annex keys: git-annex: out of memory (requested 2097152 bytes)
+
+It always seems to die at about 3.5GB memory usage. This is running on Ubuntu 12.04, using the latest GA release built using cabal:
+
+ git-annex version: 4.20130227
+ local repository version: 3
+ default repository version: 3
+ supported repository versions: 3 4
+ upgrade supported from repository versions: 0 1 2
+
+There are also dead symlinks that point to directories that have meta-data but not the symlink target (manually line-wrapped):
+
+ myPC:~/Downloads$ ls -l precise*
+ lrwxrwxrwx 1 nino nino 194 Oct 21 12:48 precise-dvd-i386.iso ->
+ .git/annex/objects/0x/Xz/SHA256-s3590631424--
+ b08ecdd4846948ec076b23afae7f87be9cfba5218fb9ba4160f26c0b8d4b5dd0/
+ SHA256-s3590631424--b08ecdd4846948ec076b23afae7f87be9cfba5218fb9ba4160f26c0b8d4b5dd0
+
+But looking in the symlink destination directory, there's no corresponding object, only metadata:
+
+ myPC:~/Downloads/.git/annex/objects/0x/Xz/SHA256-s3590631424--b08ecdd4846948ec076b23afae7f87be9cfba5218fb9ba4160f26c0b8d4b5dd0$ ls -l
+ total 8
+ -rw-rw-r-- 1 nino nino 30 Jan 8 23:15 SHA256-s3590631424--b08ecdd4846948ec076b23afae7f87be9cfba5218fb9ba4160f26c0b8d4b5dd0.cache
+ -rw-rw-r-- 1 nino nino 49 Jan 8 23:15 SHA256-s3590631424--b08ecdd4846948ec076b23afae7f87be9cfba5218fb9ba4160f26c0b8d4b5dd0.map
+
+But there is another version somewhere else.
+
+ -r--r--r-- 1 nino nino 3590631424 Mar 18 2012 ./.git/annex/objects/Kj/wM/WORM-s3590631424-m1331991509
+ --precise-dvd-i386.iso/WORM-s3590631424-m1331991509--precise-dvd-i386.iso
+
+This actual file does exist in the "Used" directory:
+
+ -rw-r--r-- 1 nino nino 3.4G May 27 2012 precise-dvd-i386.iso
+
+I'm not so worried about the mangled repo - it's quite possibly because of clueless git/git-annex command usage - but the inability to use the fsck command is concerning
+
+I could just uninit everything, but as it dies prematurely, I'm not certain that all the contents would be restored.
+Any thoughts on how I can get git-annex (esp. fsck) to complete would be appreciated.
+
+Thanks
+Giovanni
+
+> [[fixed|done]]. However, if you saw this behavior,
+> you have large files checked directly into git. You may
+> want to examine your repository and use git filter-branch to clean
+> it up.
+> --[[Joey]]
diff --git a/doc/bugs/Out_of_memory_error_in_fsck_whereis_find_and_status_cmds/comment_1_3aef6ca929fad198f2dda0868f2d49cb._comment b/doc/bugs/Out_of_memory_error_in_fsck_whereis_find_and_status_cmds/comment_1_3aef6ca929fad198f2dda0868f2d49cb._comment
new file mode 100644
index 000000000..d410f960b
--- /dev/null
+++ b/doc/bugs/Out_of_memory_error_in_fsck_whereis_find_and_status_cmds/comment_1_3aef6ca929fad198f2dda0868f2d49cb._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-03-03T18:34:41Z"
+ content="""
+git-annex is designed to run in constant memory. It should never use a lot of memory.
+
+What file causes the problem? You show git-annex whereis successfully processing 1wolf14.zip, so that file is apparently not the problem. It's probably the *next* file you told whereis to run on. You can get a file list with `git ls-files`
+
+Apparently something bad is happening when it tries to calculate the key used by the problem file.
+
+What does the file look like? You're using direct mode so it may or may not be a symlink. If it's a symlink, show it. If not, show the output of: `echo HEAD:./$filename | git cat-file --batch`
+
+----
+
+The stuff about \"dead symlinks\" etc is all a distraction AFAICS. git-annex allows you to remove content from your repository in multiple ways. That content could be present in another repository (git annex whereis would tell you), or the last copy of it could have been deleted. You can run \"git annex log\" on a file to show where the content was located historically.
+"""]]
diff --git a/doc/bugs/Out_of_memory_error_in_fsck_whereis_find_and_status_cmds/comment_2_f2c1aa84a0d04e840cb34ae15eb1cb03._comment b/doc/bugs/Out_of_memory_error_in_fsck_whereis_find_and_status_cmds/comment_2_f2c1aa84a0d04e840cb34ae15eb1cb03._comment
new file mode 100644
index 000000000..937e9cf8e
--- /dev/null
+++ b/doc/bugs/Out_of_memory_error_in_fsck_whereis_find_and_status_cmds/comment_2_f2c1aa84a0d04e840cb34ae15eb1cb03._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-03-18T23:25:24Z"
+ content="""
+This is an important bug. Could you please get back to me so I can debug it?
+"""]]
diff --git a/doc/bugs/Out_of_memory_error_in_fsck_whereis_find_and_status_cmds/comment_3_480c39648e3ca6fc58c30377bdb25a8c._comment b/doc/bugs/Out_of_memory_error_in_fsck_whereis_find_and_status_cmds/comment_3_480c39648e3ca6fc58c30377bdb25a8c._comment
new file mode 100644
index 000000000..3e851faa4
--- /dev/null
+++ b/doc/bugs/Out_of_memory_error_in_fsck_whereis_find_and_status_cmds/comment_3_480c39648e3ca6fc58c30377bdb25a8c._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="Xyem"
+ ip="87.194.19.134"
+ subject="comment 3"
+ date="2013-03-22T11:18:53Z"
+ content="""
+I may have a bug along the same lines of this but I think it is in git, rather than git-annex.
+
+I've been using git-annex to sort and consolidate ~2TB files that have been spread across several machines. I probably failed to do an important step (such as committing to git, I'm not sure) while moving a lot of these files around which renders me unable to use the repository.
+
+For example, if I run any command that uses something like 'git status' in the background, it gradually consumes all available memory. I've not had an OOM error yet (8GB RAM, 2GB swap) but it also never seems to complete.
+
+I just did a quick test on this and running 'git status' in the annex results in, after a few minutes, a growing number of 'git status --porcelain' processes (quickly reaches 70+, currently at 94) and nearly all memory consumed. This would normally be triggered with 'git annex sync' or some other command which uses 'git status' to do some work.
+
+Hope this information is of some use. If I can help further, please let me know.
+"""]]
diff --git a/doc/bugs/Out_of_memory_error_in_fsck_whereis_find_and_status_cmds/comment_4_b31496b37046a9886f632ba4f11c56e3._comment b/doc/bugs/Out_of_memory_error_in_fsck_whereis_find_and_status_cmds/comment_4_b31496b37046a9886f632ba4f11c56e3._comment
new file mode 100644
index 000000000..272d2a759
--- /dev/null
+++ b/doc/bugs/Out_of_memory_error_in_fsck_whereis_find_and_status_cmds/comment_4_b31496b37046a9886f632ba4f11c56e3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 4"
+ date="2013-03-27T16:38:07Z"
+ content="""
+@Xyem, sounds like an unrelated bug. Also, no git-annex commands run `git status`. You can find other git commands that may be using a lot of memory by passing the --debug flag to git-annex.
+"""]]
diff --git a/doc/bugs/Out_of_memory_error_in_fsck_whereis_find_and_status_cmds/comment_5_d25ff424dda1f6021c1ba20f79d71ffc._comment b/doc/bugs/Out_of_memory_error_in_fsck_whereis_find_and_status_cmds/comment_5_d25ff424dda1f6021c1ba20f79d71ffc._comment
new file mode 100644
index 000000000..958eb7733
--- /dev/null
+++ b/doc/bugs/Out_of_memory_error_in_fsck_whereis_find_and_status_cmds/comment_5_d25ff424dda1f6021c1ba20f79d71ffc._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="Xyem"
+ ip="87.194.19.134"
+ subject="comment 5"
+ date="2013-03-27T16:50:58Z"
+ content="""
+@joey: Hm.. I'm sure it was 'git annex sync' that initially consumed all RAM by spawning a lot of 'git status' processes. However, I can't replicate it anymore as I found a way to make the repository useable again.
+
+I went low into the directory structure and added/committed from there. Now I can 'git annex sync' and 'git status' from the annex root without any problems.
+
+Sorry for cluttering this bug report up, thought it might be related/of some help.
+"""]]
diff --git a/doc/bugs/Out_of_memory_error_in_fsck_whereis_find_and_status_cmds/comment_6_9e3300b223dd54a3f07c650f5cf70ae0._comment b/doc/bugs/Out_of_memory_error_in_fsck_whereis_find_and_status_cmds/comment_6_9e3300b223dd54a3f07c650f5cf70ae0._comment
new file mode 100644
index 000000000..b648eb9a4
--- /dev/null
+++ b/doc/bugs/Out_of_memory_error_in_fsck_whereis_find_and_status_cmds/comment_6_9e3300b223dd54a3f07c650f5cf70ae0._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://churchkey.org/author/ian/"
+ ip="2001:470:8a52:67:a800:4ff:fe00:a04"
+ subject="Same problem, different user"
+ date="2013-09-18T22:20:09Z"
+ content="""
+@joey I appear to have run into this same problem through a similar series of repository operations. I began with the assistant, which caused some trouble while trying to set up on multiple machines, so I started using the git-annex commands directly, switched the client to direct mode, and at some point along the way I started getting the \"git-annex: out of memory (requested 1048576 bytes)\" error on my home client any time I try to run a find, whereis, status, or sync operation. On my work client I instead run into a \"fatal: write error: Invalid argument\" error. Both clients are in direct mode and both stop on the same files. I have tried to drop these files and the ones that follow them sequentially to try and clear out the grit from the machine, but to no avail. I'm available for diagnostics to help resolve this. The files in question are not symlinks and running \"echo HEAD:./$filename | git cat-file --batch\" simply produces binary blobs the same size as the original files. Running \"git ls-tree -r git-annex | wc -l\" gives \"41262\" for the client with the \"Out of memory\" error and \"41260\" for the \"write error\" client.
+"""]]
diff --git a/doc/bugs/Out_of_memory_error_in_fsck_whereis_find_and_status_cmds/comment_7_b91f4a87b6d29ae6b4262922fd65a79d._comment b/doc/bugs/Out_of_memory_error_in_fsck_whereis_find_and_status_cmds/comment_7_b91f4a87b6d29ae6b4262922fd65a79d._comment
new file mode 100644
index 000000000..c7832477c
--- /dev/null
+++ b/doc/bugs/Out_of_memory_error_in_fsck_whereis_find_and_status_cmds/comment_7_b91f4a87b6d29ae6b4262922fd65a79d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.14.105"
+ subject="comment 7"
+ date="2013-09-19T19:07:03Z"
+ content="""
+[[Huge_annex_out_of_memory_on_switch_to_indirect_mode_and_status]] is a duplicate of this bug.
+"""]]
diff --git a/doc/bugs/Pairing_locally_shows:___34__bad_comment_in_ssh_public_key_ssh-rsa__34__.mdwn b/doc/bugs/Pairing_locally_shows:___34__bad_comment_in_ssh_public_key_ssh-rsa__34__.mdwn
new file mode 100644
index 000000000..6999d714c
--- /dev/null
+++ b/doc/bugs/Pairing_locally_shows:___34__bad_comment_in_ssh_public_key_ssh-rsa__34__.mdwn
@@ -0,0 +1,23 @@
+Open two webapp sessions (in two different *screen* windows or whatever)
+
+ name@name-Computermodel-1000:~/test/annex1$ git-annex webapp
+ name@name-Computermodel-1000:~/test/annex2$ git-annex webapp
+
+In annex1's web UI, choose *Configuration* -> *Manage repositories* -> *Local computer*.
+
+Fill in the secret phrase and press *Start pairing*.
+
+In annex2's web UI, a pairing request will show on the left notifications bar. Choose *Respond*, fill in the phrase field and press *Finish pairing*.
+
+I was expecting a pairing between the two running session. But I got this after pressing *Finish pairing* in annex2's web UI:
+
+**start of output**
+# Internal Server Error
+
+bad comment in ssh public key ssh-rsa [very long GPG key jibber jabber] name@name-Computermodel-1000
+
+**end of output**
+
+git-annex version: 3.20121017, Ubuntu 12.04
+
+> [[Done]], allowed dash and underscore in there now.
diff --git a/doc/bugs/Partial_direct__47__indirect_repo.mdwn b/doc/bugs/Partial_direct__47__indirect_repo.mdwn
new file mode 100644
index 000000000..11cf7a1e8
--- /dev/null
+++ b/doc/bugs/Partial_direct__47__indirect_repo.mdwn
@@ -0,0 +1,24 @@
+Setup:
+
+* Fresh install of Debian Wheezy on machines A & B, git-annex 4.20130227 pulled in from unstable
+* On both machines, clone old repository which contains both annexed files and a three small files checked straight into git
+
+Steps:
+
+* On both machines, use webapp to create `~/.config/git-annex/autostart` by just firing it up and typing in location of existing repository
+* Move a new file into B's annex, in a subdirectory that is preferred on both A & B
+
+Expected:
+
+* The new file is copied over to A and everything remains in indirect mode
+* Three files checked straight into git remain checked straight into git (see below for why this is a variant on [[bugs/Switching_between_direct_and_indirect_stomps_on___39__regular__39___git_files/]])
+
+Actual:
+
+* New file copied over but seems to be in direct mode, while all the other content that is present is still symlinked
+* Files checked into git converted to direct mode files too (can tell this has happened by following step:)
+* Typing `git annex indirect` on A & B shows conversion of precisely four files (three files originally checked into git and new file added to B ) back to indirect
+
+Thanks.
+
+> [[done]], webapp now avoids changing existing repos here. --[[Joey]]
diff --git a/doc/bugs/Partial_direct__47__indirect_repo/comment_1_42344fce051d759f95215c985e9d1135._comment b/doc/bugs/Partial_direct__47__indirect_repo/comment_1_42344fce051d759f95215c985e9d1135._comment
new file mode 100644
index 000000000..0d903a13d
--- /dev/null
+++ b/doc/bugs/Partial_direct__47__indirect_repo/comment_1_42344fce051d759f95215c985e9d1135._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-03-12T11:23:47Z"
+ content="""
+This can happen if your repository gets annex.direct=true set in its .git/config, without `git annex direct` having been run to truely put it into direct mode.
+
+The proof that this was the case is that `git annex indirect` did anything at all. The first thing `git annex indirect` does is check if it's in a direct mode repository. If not, it steps without doing anything, and without outputting anything.
+
+I think this was user error.
+"""]]
diff --git a/doc/bugs/Partial_direct__47__indirect_repo/comment_2_8ba64f2750d0ef4adf595674c723bc65._comment b/doc/bugs/Partial_direct__47__indirect_repo/comment_2_8ba64f2750d0ef4adf595674c723bc65._comment
new file mode 100644
index 000000000..96a12e96d
--- /dev/null
+++ b/doc/bugs/Partial_direct__47__indirect_repo/comment_2_8ba64f2750d0ef4adf595674c723bc65._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-03-12T11:27:30Z"
+ content="""
+Oh, I see, you started up the webapp, and told it to make a repo that already existed. So it helpfully set its annex.direct, thinking it was a new repository.
+"""]]
diff --git a/doc/bugs/Partial_direct__47__indirect_repo/comment_3_bd4985864b7dcd70a609ca7bc2617e4a._comment b/doc/bugs/Partial_direct__47__indirect_repo/comment_3_bd4985864b7dcd70a609ca7bc2617e4a._comment
new file mode 100644
index 000000000..1a9e187cc
--- /dev/null
+++ b/doc/bugs/Partial_direct__47__indirect_repo/comment_3_bd4985864b7dcd70a609ca7bc2617e4a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="spwhitton"
+ ip="82.36.235.9"
+ subject="comment 3"
+ date="2013-03-12T11:37:50Z"
+ content="""
+That's right--I don't think it should do that for existing respositories. I didn't realise it wasn't standard to use the webapp to recreate the autostart file.
+"""]]
diff --git a/doc/bugs/Possible_data_loss_-_git_status___39__typechange__39___and_direct_mode.mdwn b/doc/bugs/Possible_data_loss_-_git_status___39__typechange__39___and_direct_mode.mdwn
new file mode 100644
index 000000000..4a3329326
--- /dev/null
+++ b/doc/bugs/Possible_data_loss_-_git_status___39__typechange__39___and_direct_mode.mdwn
@@ -0,0 +1,32 @@
+#### What steps will reproduce the problem?
+
+When moving to direct mode files get flagged in git as 'typechange'.
+
+ md test-directmode; cd test-directmode ; git init; git annex init
+ date > test.file ; git annex add test.file
+ git commit -m "Initial commit"
+ git status # All fine
+ git annex direct
+ git status # typechange: test.file
+ git add test.file && git commit -m "looks like I should commit this"
+ # And the symlink is now broken...
+
+#### What is the expected output? What do you see instead?
+
+Surprised to see the typechange status in git. Would not expect to see anything, however, if you `git add` and then commit you can get data loss. :-(
+
+
+#### What version of git-annex are you using? On what operating system?
+
+git-annex version: 3.20130114
+
+OS: OSX 10.6.8
+
+#### Please provide any additional information below.
+
+> This was the pre-commit hook, made it not run in direct mode. [[done]]
+>
+> However, it's normal to see typechanged files in direct mode, and many
+> git commands that manipulate files in the working tree *can* result in
+> data loss. This is documented on [[direct_mode]].
+> --[[Joey]]
diff --git a/doc/bugs/Possible_data_loss_-_git_status___39__typechange__39___and_direct_mode/comment_1_84cb8c651584ec2887f6e1b7dc107190._comment b/doc/bugs/Possible_data_loss_-_git_status___39__typechange__39___and_direct_mode/comment_1_84cb8c651584ec2887f6e1b7dc107190._comment
new file mode 100644
index 000000000..b06706374
--- /dev/null
+++ b/doc/bugs/Possible_data_loss_-_git_status___39__typechange__39___and_direct_mode/comment_1_84cb8c651584ec2887f6e1b7dc107190._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://a-or-b.myopenid.com/"
+ ip="203.45.2.230"
+ subject="comment 1"
+ date="2013-01-17T02:13:03Z"
+ content="""
+Should g-a encourage users to *not* `git add` files with the typechange attribute?
+"""]]
diff --git a/doc/bugs/Possible_issues_with_git_1.7.10_and_newer___40__merge_command_now_asks_for_a_commit_message__34__.mdwn b/doc/bugs/Possible_issues_with_git_1.7.10_and_newer___40__merge_command_now_asks_for_a_commit_message__34__.mdwn
new file mode 100644
index 000000000..05024ffe9
--- /dev/null
+++ b/doc/bugs/Possible_issues_with_git_1.7.10_and_newer___40__merge_command_now_asks_for_a_commit_message__34__.mdwn
@@ -0,0 +1,18 @@
+running 'git annex sync' doesn't merge the branches as expected (from the
+limited testing I have done) with git 1.7.10, the behaviour of merge has
+changed, it now asks for a commit message. I would expect setting
+_GIT_MERGE_AUTOEDIT=no_ should resolve this issue.
+
+I had to manually do a merge (or set that variable) to get the branches
+back in sync again, this confused me a bit when git-annex watch was running
+in the background on a remote and it did not pick up the changes.
+
+> Yeah, I tend to miss these since the first thing I did when this
+> misfeature was being posted was to write a mail discouraging them from
+> doing it (sadly ignored), and then set in ~/.environment:
+
+ # My time is more valuable than git's new, bad default
+ GIT_MERGE_AUTOEDIT=no
+ export GIT_MERGE_AUTOEDIT
+
+> Anyway, I've made sync run merge with --no-edit now. [[done]] --[[Joey]]
diff --git a/doc/bugs/Prevent_accidental_merges.mdwn b/doc/bugs/Prevent_accidental_merges.mdwn
new file mode 100644
index 000000000..3e30e0223
--- /dev/null
+++ b/doc/bugs/Prevent_accidental_merges.mdwn
@@ -0,0 +1,14 @@
+With the storage layout v3, pulling the git-annex branch into the master branch is... less than ideal.
+
+The fact that the two branches contain totally different data make an accidental merge worse, arguably.
+
+Adding a tiny binary file called .gitnomerge to both branches would solve that without any noticeable overhead.
+
+Yes, there is an argument to be made that this is too much hand-holding, but I still think it's worth it.
+
+-- Richard
+
+> It should be as easy to undo such an accidential merge
+> as it is to undo any other git commit, right? I quite like that git-annex
+> no longer adds any clutter to the master branch, and would be reluctant
+> to change that. --[[Joey]]
diff --git a/doc/bugs/Prevent_accidental_merges/comment_1_4c46a193915eab8f308a04175cb2e40a._comment b/doc/bugs/Prevent_accidental_merges/comment_1_4c46a193915eab8f308a04175cb2e40a._comment
new file mode 100644
index 000000000..3e28a28cb
--- /dev/null
+++ b/doc/bugs/Prevent_accidental_merges/comment_1_4c46a193915eab8f308a04175cb2e40a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 1"
+ date="2011-10-23T15:00:48Z"
+ content="""
+Having run into the same issue again, I still think git-annex should ensure no merges take place. The clutter introduced by a .gitnomerge is neglible, imo.
+"""]]
diff --git a/doc/bugs/Problem_when_dropping_unused_files.mdwn b/doc/bugs/Problem_when_dropping_unused_files.mdwn
new file mode 100644
index 000000000..2c15680b8
--- /dev/null
+++ b/doc/bugs/Problem_when_dropping_unused_files.mdwn
@@ -0,0 +1,21 @@
+### Please describe the problem.
+
+While dropping 19 unused files from an annex, I got this error:
+
+ error: invalid object 100644 c873416e78db4dd94b6ab40470d6fe99b2ecb8bd for '002/0a6/SHA256E-s427690--03aeabcde841b66168b72de80098d74e047f3ffc832d4bbefa1f2f70ee6c92f8.jpg.log'
+ fatal: git-write-tree: error building trees
+ git-annex: failed to read sha from git write-tree
+
+I've actually seen this before, a few months ago.
+
+### What steps will reproduce the problem?
+
+I have no idea, but once it happens I can't interact with unused files anymore. Also, `git annex fsck` now reports this same problem as well.
+
+### What version of git-annex are you using? On what operating system?
+
+git-annex version: 4.20130815, OS X 10.8.4
+
+> [[done]]; no indication this is anything other than a corrupt git
+> repository, which can be caused by system crash, disk data loss,
+> cosmic rays, etc. This is why we keep backups... --[[Joey]]
diff --git a/doc/bugs/Problem_when_dropping_unused_files/comment_10_d4f6bfe8e04560fc661a47b09ed8a5f4._comment b/doc/bugs/Problem_when_dropping_unused_files/comment_10_d4f6bfe8e04560fc661a47b09ed8a5f4._comment
new file mode 100644
index 000000000..9c0e25528
--- /dev/null
+++ b/doc/bugs/Problem_when_dropping_unused_files/comment_10_d4f6bfe8e04560fc661a47b09ed8a5f4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.251.174"
+ subject="comment 10"
+ date="2013-09-07T17:14:36Z"
+ content="""
+Again this error message has nothing to do with git-annex beyond it being a file in the git-annex branch that is corrupt. Your system seems to be repeatedly corrupting git repositories. You need to run `git fsck`, get the git repository in a clean state, and probably check the drive it's on, and run a memory test or otherwise deal with whatever is causing your system to corrupt files in the git repository.
+"""]]
diff --git a/doc/bugs/Problem_when_dropping_unused_files/comment_1_e1a99bd3eb8b3186653b52a52b1836de._comment b/doc/bugs/Problem_when_dropping_unused_files/comment_1_e1a99bd3eb8b3186653b52a52b1836de._comment
new file mode 100644
index 000000000..0e39a96fc
--- /dev/null
+++ b/doc/bugs/Problem_when_dropping_unused_files/comment_1_e1a99bd3eb8b3186653b52a52b1836de._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/2grhJvAC049fJnvALDXek.6MRZMTlg--#eec89"
+ nickname="John"
+ subject="comment 1"
+ date="2013-08-24T05:01:37Z"
+ content="""
+The following command restored some sanity:
+
+ find .git/annex/ -name '*.log' -delete
+"""]]
diff --git a/doc/bugs/Problem_when_dropping_unused_files/comment_2_dec3e5ffe5cfdc439f418ee00d7d9810._comment b/doc/bugs/Problem_when_dropping_unused_files/comment_2_dec3e5ffe5cfdc439f418ee00d7d9810._comment
new file mode 100644
index 000000000..e0c5a2882
--- /dev/null
+++ b/doc/bugs/Problem_when_dropping_unused_files/comment_2_dec3e5ffe5cfdc439f418ee00d7d9810._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="arand"
+ ip="130.243.226.21"
+ subject="comment 2"
+ date="2013-08-24T11:40:54Z"
+ content="""
+If I recall, such files being stored in the annex object store is a result of using direct mode?
+"""]]
diff --git a/doc/bugs/Problem_when_dropping_unused_files/comment_3_d106a87101db52f957da84d90dafcdbb._comment b/doc/bugs/Problem_when_dropping_unused_files/comment_3_d106a87101db52f957da84d90dafcdbb._comment
new file mode 100644
index 000000000..8c739552d
--- /dev/null
+++ b/doc/bugs/Problem_when_dropping_unused_files/comment_3_d106a87101db52f957da84d90dafcdbb._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 3"
+ date="2013-08-24T16:04:21Z"
+ content="""
+Unfortunately, the git error message you pasted suggests very strongly that your git repository has gotten corrupted. You can probably verify that by running `git annex fsck`. Assuming it is corrupted, the best thing to do is to make a new clone and move .git/annex and .git/config over from the corrupted repository to it, and finally run `git annex fsck`
+
+You then seem to have some reason decided to go delete git-annex's .git/annex/journal/*.log files, which are just files that have not yet been committed to the git-annex branch. The only reason this \"restored some sanity\" is that git-annex was trying to commit that data to git, and failing because your git repository is corrupted.
+
+(This has nothing at all to do with direct mode.)
+"""]]
diff --git a/doc/bugs/Problem_when_dropping_unused_files/comment_4_f28ed0635612693e437e64d872af5c37._comment b/doc/bugs/Problem_when_dropping_unused_files/comment_4_f28ed0635612693e437e64d872af5c37._comment
new file mode 100644
index 000000000..ba2e693ee
--- /dev/null
+++ b/doc/bugs/Problem_when_dropping_unused_files/comment_4_f28ed0635612693e437e64d872af5c37._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/2grhJvAC049fJnvALDXek.6MRZMTlg--#eec89"
+ nickname="John"
+ subject="comment 4"
+ date="2013-08-25T05:27:57Z"
+ content="""
+Do you have any thoughts on why it may have gotten corrupted, or why it seems to happen so commonly with large git-annex repositories? I've seen this exact same sort of error while processing log files maybe 5 or 6 times now.
+"""]]
diff --git a/doc/bugs/Problem_when_dropping_unused_files/comment_5_f0237075653768c84deb702442645f28._comment b/doc/bugs/Problem_when_dropping_unused_files/comment_5_f0237075653768c84deb702442645f28._comment
new file mode 100644
index 000000000..4ad874c08
--- /dev/null
+++ b/doc/bugs/Problem_when_dropping_unused_files/comment_5_f0237075653768c84deb702442645f28._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/2grhJvAC049fJnvALDXek.6MRZMTlg--#eec89"
+ nickname="John"
+ subject="comment 5"
+ date="2013-08-25T05:50:35Z"
+ content="""
+I meant to say, in 5 or 6 different repositories. Further, when I see it happen the next time, how do you recommend I track down the real problem, instead of always just cloning and starting over?
+"""]]
diff --git a/doc/bugs/Problem_when_dropping_unused_files/comment_6_b509006e1590480a104627369bc910f2._comment b/doc/bugs/Problem_when_dropping_unused_files/comment_6_b509006e1590480a104627369bc910f2._comment
new file mode 100644
index 000000000..60f2165e2
--- /dev/null
+++ b/doc/bugs/Problem_when_dropping_unused_files/comment_6_b509006e1590480a104627369bc910f2._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/2grhJvAC049fJnvALDXek.6MRZMTlg--#eec89"
+ nickname="John"
+ subject="comment 6"
+ date="2013-08-30T04:19:57Z"
+ content="""
+Just saw it happen again today, in a repository that passed \"fsck -A\" multiple times just yesterday. What is going on?
+"""]]
diff --git a/doc/bugs/Problem_when_dropping_unused_files/comment_7_fe261c074211ccb94bbcb32cfd8ee654._comment b/doc/bugs/Problem_when_dropping_unused_files/comment_7_fe261c074211ccb94bbcb32cfd8ee654._comment
new file mode 100644
index 000000000..6f3e42f5c
--- /dev/null
+++ b/doc/bugs/Problem_when_dropping_unused_files/comment_7_fe261c074211ccb94bbcb32cfd8ee654._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/2grhJvAC049fJnvALDXek.6MRZMTlg--#eec89"
+ nickname="John"
+ subject="comment 7"
+ date="2013-08-30T04:25:45Z"
+ content="""
+I tried your suggestion of cloning the repository and moving `.git/config` and `.git/annex`, and got this:
+
+ fsck Astronomy/12_ATM_2.jpg error: invalid object 100644 06f8fe222f052100101e5c2e77640f2ec3efff98 for '002/0a6/SHA256E-s427690--03aeabcde841b66168b72de80098d74e047f3ffc832d4bbefa1f2f70ee6c92f8.jpg.log'
+ fatal: git-write-tree: error building trees
+ git-annex: failed to read sha from git write-tree
+
+What else can I try? Note that I can't even find this `.log` anywhere under my `.git` directory for this repository.
+"""]]
diff --git a/doc/bugs/Problem_when_dropping_unused_files/comment_8_bc8e4dc7e0d6577ba5fcc98f56627b1f._comment b/doc/bugs/Problem_when_dropping_unused_files/comment_8_bc8e4dc7e0d6577ba5fcc98f56627b1f._comment
new file mode 100644
index 000000000..0b82af2f1
--- /dev/null
+++ b/doc/bugs/Problem_when_dropping_unused_files/comment_8_bc8e4dc7e0d6577ba5fcc98f56627b1f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/2grhJvAC049fJnvALDXek.6MRZMTlg--#eec89"
+ nickname="John"
+ subject="comment 8"
+ date="2013-08-30T04:30:14Z"
+ content="""
+The only thing that worked was nuking `.git/annex/index` and letting `git-annex sync` rebuild it.
+"""]]
diff --git a/doc/bugs/Problem_when_dropping_unused_files/comment_9_e9a22aa2ebcde5f6595b49dba9375761._comment b/doc/bugs/Problem_when_dropping_unused_files/comment_9_e9a22aa2ebcde5f6595b49dba9375761._comment
new file mode 100644
index 000000000..b75b3f61b
--- /dev/null
+++ b/doc/bugs/Problem_when_dropping_unused_files/comment_9_e9a22aa2ebcde5f6595b49dba9375761._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/2grhJvAC049fJnvALDXek.6MRZMTlg--#eec89"
+ nickname="John"
+ subject="comment 9"
+ date="2013-08-30T06:20:58Z"
+ content="""
+And yet again it happens:
+
+ error: invalid object 100644 3edb1d4a44ffba1ea1491693ae7d9faa82aad717 for '000/4ce/SHA256E-s175006724--a0edc4f880223028b3fa3a27b142c8e027ddf66db973b8272ca845a4a9e01d3e.mp4.log' fatal: git-write-tree: error building trees
+
+This was in a repository that was working perfectly well until I tried to `git-annex get`. The weird thing is that I don't even have any `SHA256E` files anymore.
+
+I think that after my recent migration, none of my repositories can be trusted. This is just happening too often (more than 10 times in the last week, across many repositories on many machines). I will just rebuild them all. But I do wish git-annex was more resilient about this.
+"""]]
diff --git a/doc/bugs/Problem_with_bup:_cannot_lock_refs.mdwn b/doc/bugs/Problem_with_bup:_cannot_lock_refs.mdwn
new file mode 100644
index 000000000..f8df1f082
--- /dev/null
+++ b/doc/bugs/Problem_with_bup:_cannot_lock_refs.mdwn
@@ -0,0 +1,52 @@
+Hi!
+
+Using bup for storing seems a good idea to save space, but I still have a problem when trying to copy files to my local git repo.
+I have two partitions:
+
+- /Data (NTFS)
+
+- / (ext4)
+
+I turned the directory /Data/Audio into a git-annex repo, and cloned it into /home/me/AudioClone.
+I added the remote bup to AudioClone by doing:
+
+ git annex initremote mybup type=bup encryption=none buprepo=
+
+But when I try to copy some files that I have previously got by "git annex get" by doing:
+
+ [~/AudioClone]$ git annex copy someartist/somealbum --to mybup
+
+it fails and tells me:
+
+ copy Order To Die/01 Morituri Te Salutant.flac (to mybup...)
+ fatal: Cannot lock the ref 'refs/heads/WORM-s7351771-m1318841909--01 Morituri Te Salutant.flac'.
+ Traceback (most recent call last):
+ File "/usr/lib/bup/cmd/bup-split", line 170, in <module>
+ git.update_ref(refname, commit, oldref)
+ File "/usr/lib/bup/bup/git.py", line 835, in update_ref
+ _git_wait('git update-ref', p)
+ File "/usr/lib/bup/bup/git.py", line 930, in _git_wait
+ raise GitError('%s returned %d' % (cmd, rv))
+ bup.git.GitError: git update-ref returned 128
+
+for each file, **except for the album cover file**, which is a simple JPG that bup doesn't try to split. This one gets copied nicely but the big FLAC files don't.
+
+I tried to restart my session, in case bup adds my username to a group or something.
+
+(I'm using Ubuntu 11.10)
+
+> Apparently bup-split does not allow storing data using filenames with
+> spaces in them. I can reproduce the same bug using the same filename;
+> if I remove the spaces all is well.
+>
+> Since bup-split -n uses git branches, I guess git-annex needs to avoid
+> giving it any names containing spaces, or anything else not allowed
+> in a git branch name. The rules for legal git branch names are quite complex
+> (see git-check-ref-format(1)) so it will take me some times to code
+> this up.
+>
+> A workaround is to switch to the SHA256 backend
+> (`git annex migrate --backend=SHA256`), which avoids spaces in its keys.
+> --[[Joey]]
+
+>> Now fixed in git. [[done]] --[[Joey]]
diff --git a/doc/bugs/Problems_building_on_Mac_OS_X.mdwn b/doc/bugs/Problems_building_on_Mac_OS_X.mdwn
new file mode 100644
index 000000000..39594773f
--- /dev/null
+++ b/doc/bugs/Problems_building_on_Mac_OS_X.mdwn
@@ -0,0 +1,62 @@
+### Please describe the problem.
+
+Installing via Cabal fails due to dependency conflicts with yesod. If I build without the webapp flag, the problem disappears.
+
+### What steps will reproduce the problem?
+Running `cabal install c2hs git-annex --bindir=$HOME/bin`.
+
+### What version of git-annex are you using? On what operating system?
+I was attempting to install 4.20130521 from Hackage. My operating system is Mac OS X 10.6.8. Cabal-install is at 0.14.0.
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/debug.log
+Resolving dependencies...
+cabal: Could not resolve dependencies:
+trying: git-annex-4.20130521 (user goal)
+trying: git-annex-4.20130521:+webapp
+trying: yesod-default-1.2.0 (dependency of git-annex-4.20130521:+webapp)
+trying: yesod-core-1.2.1 (dependency of yesod-default-1.2.0)
+trying: cookie-0.4.0.1/installed-9d9... (dependency of yesod-core-1.2.1)
+next goal: yesod (dependency of git-annex-4.20130521:+webapp)
+rejecting: yesod-1.2.0.1, 1.2.0 (conflict: git-annex-4.20130521:webapp =>
+yesod(<1.2))
+rejecting: yesod-1.1.9.3, 1.1.9.2, 1.1.9.1, 1.1.9, 1.1.8.2, 1.1.8.1, 1.1.8,
+1.1.7.2, 1.1.7.1, 1.1.7, 1.1.6, 1.1.5, 1.1.4.1, 1.1.4 (conflict:
+yesod-core==1.2.1, yesod => yesod-core>=1.1.5 && <1.2)
+rejecting: yesod-1.1.3.1, 1.1.3, 1.1.2, 1.1.1.2, 1.1.1, 1.1.0.3, 1.1.0.2,
+1.1.0.1, 1.1.0 (conflict: yesod-core==1.2.1, yesod => yesod-core>=1.1 && <1.2)
+rejecting: yesod-1.0.1.6, 1.0.1.5, 1.0.1.4, 1.0.1.3, 1.0.1.2, 1.0.1.1, 1.0.1,
+1.0.0.2, 1.0.0.1, 1.0.0 (conflict: yesod-core==1.2.1, yesod => yesod-core>=1.0
+&& <1.1)
+rejecting: yesod-0.10.2, 0.10.1.4, 0.10.1.3, 0.10.1.2, 0.10.1.1, 0.10.1
+(conflict: yesod-core==1.2.1, yesod => yesod-core>=0.10.1 && <0.11)
+rejecting: yesod-0.9.4.1, 0.9.4, 0.9.3.4, 0.9.3.3, 0.9.3.2 (conflict:
+yesod-core==1.2.1, yesod => yesod-core>=0.9.3.4 && <0.10)
+rejecting: yesod-0.9.3.1, 0.9.3, 0.9.2.2, 0.9.2.1, 0.9.2, 0.9.1.1 (conflict:
+yesod-core==1.2.1, yesod => yesod-core>=0.9.1.1 && <0.10)
+rejecting: yesod-0.9.1 (conflict: yesod-core==1.2.1, yesod => yesod-core>=0.9
+&& <0.10)
+rejecting: yesod-0.8.2.1, 0.8.2, 0.8.1 (conflict: yesod-core==1.2.1, yesod =>
+yesod-core>=0.8.1 && <0.9)
+rejecting: yesod-0.8.0 (conflict: yesod-core==1.2.1, yesod => yesod-core>=0.8
+&& <0.9)
+rejecting: yesod-0.7.3, 0.7.2 (conflict: yesod-core==1.2.1, yesod =>
+yesod-core>=0.7.0.2 && <0.8)
+rejecting: yesod-0.7.1 (conflict: yesod-core==1.2.1, yesod =>
+yesod-core>=0.7.0.1 && <0.8)
+rejecting: yesod-0.7.0 (conflict: yesod-core==1.2.1, yesod => yesod-core>=0.7
+&& <0.8)
+rejecting: yesod-0.6.7, 0.6.6, 0.6.5, 0.6.4, 0.6.3, 0.6.2, 0.6.1.2, 0.6.1.1,
+0.6.1, 0.6.0.2, 0.6.0.1, 0.6.0, 0.5.4.2, 0.5.4.1, 0.5.4, 0.5.3, 0.5.2, 0.5.1,
+0.5.0.3, 0.5.0.2, 0.5.0.1, 0.5.0, 0.4.1, 0.4.0.3, 0.4.0.2, 0.4.0.1, 0.4.0
+(conflict: cookie => time==1.4/installed-d61..., yesod => time>=1.1.4 && <1.3)
+rejecting: yesod-0.3.1.1, 0.3.1, 0.3.0, 0.2.0, 0.0.0.2, 0.0.0.1, 0.0.0
+(conflict: cookie => time==1.4/installed-d61..., yesod => time>=1.1.3 && <1.2)
+# End of transcript or log.
+"""]]
+
+> Not OSX specific. I have added a version hint that makes cabal work and uploaded
+> a point release with this fix. [[done]] --[[Joey]]
diff --git a/doc/bugs/Problems_building_on_Mac_OS_X/comment_1_1c199b826fdd84b5184b1466ad03a9a4._comment b/doc/bugs/Problems_building_on_Mac_OS_X/comment_1_1c199b826fdd84b5184b1466ad03a9a4._comment
new file mode 100644
index 000000000..f73808014
--- /dev/null
+++ b/doc/bugs/Problems_building_on_Mac_OS_X/comment_1_1c199b826fdd84b5184b1466ad03a9a4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmu416zAYgYzbXVZAe30MiXoOWO4z6nGX8"
+ nickname="Johannes"
+ subject="comment 1"
+ date="2013-05-23T10:02:55Z"
+ content="""
+Same problem on archlinux with cabal-install 1.16.0.2
+"""]]
diff --git a/doc/bugs/Problems_running_make_on_osx.mdwn b/doc/bugs/Problems_running_make_on_osx.mdwn
new file mode 100644
index 000000000..83b75fb54
--- /dev/null
+++ b/doc/bugs/Problems_running_make_on_osx.mdwn
@@ -0,0 +1,49 @@
+Followed the instructions over here: http://git-annex.branchable.com/forum/git-annex_on_OSX/
+
+and had to install the following extra packages to be able to get make to start:
+
+[realizes pcre-light is needed but pcre not installed on my mac]
+sudo port install pcre
+sudo cabal install pcre-light
+
+> Ah right, that is a new dependency. I've updated the forum page
+> with this info.
+> --[[Joey]]
+
+But then I got the following error:
+
+<pre>
+ghc -O2 -Wall --make git-annex
+[ 7 of 52] Compiling BackendTypes ( BackendTypes.hs, BackendTypes.o
+
+BackendTypes.hs:71:17:
+ No instance for (Arbitrary Char)
+ arising from a use of `arbitrary' at BackendTypes.hs:71:17-25
+ Possible fix: add an instance declaration for (Arbitrary Char)
+ In a stmt of a 'do' expression: backendname <- arbitrary
+ In the expression:
+ do backendname <- arbitrary
+ keyname <- arbitrary
+ return $ Key (backendname, keyname)
+ In the definition of `arbitrary':
+ arbitrary = do backendname <- arbitrary
+ keyname <- arbitrary
+ return $ Key (backendname, keyname)
+make: *** [git-annex] Error 1
+</pre>
+
+My knowledge of Haskell (had to lookup the spelling...) is more than rudimentary so any help would be appreciated.
+
+> Hmm, it seems you may be missing part of the quickcheck haskell
+> library, or have a different version than me.
+>
+> The easy fix is probably to just edit BackendTypes.hs and delete the
+> entire end of the file from line 68, "for quickcheck" down. This code
+> is only used by the test suite (so "make test" will fail),
+> but it should get it to build. --[[Joey]]
+
+---
+
+Closing this bug because the above problem now has a solution documented on
+the install page, and the below test suite failure problems should all be
+resolved on OSX. [[done]] --[[Joey]]
diff --git a/doc/bugs/Problems_running_make_on_osx/comment_10_94e4ac430140042a2d0fb5a16d86b4e5._comment b/doc/bugs/Problems_running_make_on_osx/comment_10_94e4ac430140042a2d0fb5a16d86b4e5._comment
new file mode 100644
index 000000000..95a9773e2
--- /dev/null
+++ b/doc/bugs/Problems_running_make_on_osx/comment_10_94e4ac430140042a2d0fb5a16d86b4e5._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 10"
+ date="2011-02-09T15:04:50Z"
+ content="""
+I don't know what these problems forking could be. Can you strace it?
+"""]]
diff --git a/doc/bugs/Problems_running_make_on_osx/comment_11_56f1143fa191361d63b441741699e17f._comment b/doc/bugs/Problems_running_make_on_osx/comment_11_56f1143fa191361d63b441741699e17f._comment
new file mode 100644
index 000000000..3fbe57ecd
--- /dev/null
+++ b/doc/bugs/Problems_running_make_on_osx/comment_11_56f1143fa191361d63b441741699e17f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 11"
+ date="2011-02-09T19:35:47Z"
+ content="""
+I got dtruss to give me a trace, the output is quite big to post here (~560kb gzip'd), do you mind if I emailed it or posted it somewhere else for you?
+"""]]
diff --git a/doc/bugs/Problems_running_make_on_osx/comment_12_ec5131624d0d2285d3b6880e47033f97._comment b/doc/bugs/Problems_running_make_on_osx/comment_12_ec5131624d0d2285d3b6880e47033f97._comment
new file mode 100644
index 000000000..beba5dc42
--- /dev/null
+++ b/doc/bugs/Problems_running_make_on_osx/comment_12_ec5131624d0d2285d3b6880e47033f97._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 12"
+ date="2011-02-09T19:47:30Z"
+ content="""
+joey@kitenet.net (hope I can make sense of dtruss output)
+"""]]
diff --git a/doc/bugs/Problems_running_make_on_osx/comment_13_88ed095a448096bf8a69015a04e64df1._comment b/doc/bugs/Problems_running_make_on_osx/comment_13_88ed095a448096bf8a69015a04e64df1._comment
new file mode 100644
index 000000000..dd25c3d0c
--- /dev/null
+++ b/doc/bugs/Problems_running_make_on_osx/comment_13_88ed095a448096bf8a69015a04e64df1._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 13"
+ date="2011-02-09T21:59:47Z"
+ content="""
+The dtrace puzzlingly does not have the same errors shown above, but a set of mostly new errors. I don't know what to make of that.
+
+> git-annex: git-annex/.t/repo/.git/hooks/pre-commit: fileAccess: permission denied (Operation not permitted)
+
+This seems to be caused by it setting the execute bit on the file. I don't know why that would fail; it's just written the file and renamed it into place so clearly should be able to write to it.
+
+> was able to modify annexed file's sha1foo content
+
+This also suggests something breaking with permissions.
+"""]]
diff --git a/doc/bugs/Problems_running_make_on_osx/comment_14_89a960b6706ed703b390a81a8bc4e311._comment b/doc/bugs/Problems_running_make_on_osx/comment_14_89a960b6706ed703b390a81a8bc4e311._comment
new file mode 100644
index 000000000..724fe5505
--- /dev/null
+++ b/doc/bugs/Problems_running_make_on_osx/comment_14_89a960b6706ed703b390a81a8bc4e311._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 14"
+ date="2011-02-12T21:19:24Z"
+ content="""
+I've been trying to dig around the trace and code, and used google to see if the forkProcess issue was a haskell thing or an OSX thing. It seems that <http://hackage.haskell.org/trac/ghc/ticket/4493> someone may have ran into a similar issue, though I am not sure if its related.
+"""]]
diff --git a/doc/bugs/Problems_running_make_on_osx/comment_15_6b8867b8e48bf807c955779c9f8f0909._comment b/doc/bugs/Problems_running_make_on_osx/comment_15_6b8867b8e48bf807c955779c9f8f0909._comment
new file mode 100644
index 000000000..733ec997a
--- /dev/null
+++ b/doc/bugs/Problems_running_make_on_osx/comment_15_6b8867b8e48bf807c955779c9f8f0909._comment
@@ -0,0 +1,71 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 15"
+ date="2011-02-13T02:45:51Z"
+ content="""
+It may be possible that OSX has some low resource limits, for user processes (266 per user I think) doing a
+
+ sudo sysctl -w kern.maxproc=2048
+ sudo sysctl -w kern.maxprocperuid=1024
+ sudo echo \"limit maxfiles 1024 unlimited\" >> /etc/launchd.conf
+ sudo echo \"limit maxproc 1024 2048\" >> /etc/launchd.conf
+
+seems to change the behaviour of the tests abit...
+
+<pre>
+Testing 1:blackbox:3:git-annex unannex:1:with content
+### Failure in: 1:blackbox:3:git-annex unannex:1:with content
+foo is not a symlink
+Testing 1:blackbox:4:git-annex drop:0:no remotes
+### Failure in: 1:blackbox:4:git-annex drop:0:no remotes
+drop wrongly succeeded with no known copy of file
+Testing 1:blackbox:4:git-annex drop:1:with remote
+Testing 1:blackbox:4:git-annex drop:2:untrusted remote
+Testing 1:blackbox:5:git-annex get
+Testing 1:blackbox:6:git-annex move
+Testing 1:blackbox:7:git-annex copy
+Testing 1:blackbox:8:git-annex unlock/lock
+Testing 1:blackbox:9:git-annex edit/commit:0
+Cases: 30 Tried: 20 Errors: 0 Failures: 2add foo ok
+ok
+Testing 1:blackbox:9:git-annex edit/commit:1
+Testing 1:blackbox:10:git-annex fix
+Testing 1:blackbox:11:git-annex trust/untrust/semitrust
+Testing 1:blackbox:12:git-annex fsck:0
+Cases: 30 Tried: 24 Errors: 0 Failures: 2 Only 1 of 2 trustworthy copies of foo exist.
+ Back it up with git-annex copy.
+ Only 1 of 2 trustworthy copies of sha1foo exist.
+ Back it up with git-annex copy.
+ Bad file size; moved to /Users/jtang/develop/git-annex/.t/tmprepo/.git/annex/bad/WORM:1297565141:20:foo
+ Bad file content; moved to /Users/jtang/develop/git-annex/.t/tmprepo/.git/annex/bad/SHA1:ee80d2cec57a3810db83b80e1b320df3a3721ffa
+Testing 1:blackbox:12:git-annex fsck:1
+### Failure in: 1:blackbox:12:git-annex fsck:1
+fsck failed to fail with content only available in untrusted (current) repository
+Testing 1:blackbox:12:git-annex fsck:2
+Cases: 30 Tried: 26 Errors: 0 Failures: 3 Only 1 of 2 trustworthy copies of foo exist.
+ Back it up with git-annex copy.
+ The following untrusted locations may also have copies:
+ 58e831c2-371b-11e0-bc1f-47d738dc52ee -- test repo
+ Only 1 of 2 trustworthy copies of sha1foo exist.
+ Back it up with git-annex copy.
+ The following untrusted locations may also have copies:
+ 58e831c2-371b-11e0-bc1f-47d738dc52ee -- test repo
+Testing 1:blackbox:13:git-annex migrate:0
+Cases: 30 Tried: 27 Errors: 0 Failures: 3 git-annex: user error (Error in fork: forkProcess: resource exhausted (Resource temporarily unavailable))
+### Failure in: 1:blackbox:13:git-annex migrate:0
+migrate annexedfile failed
+Testing 1:blackbox:13:git-annex migrate:1
+### Error in: 1:blackbox:13:git-annex migrate:1
+forkProcess: resource exhausted (Resource temporarily unavailable)
+Testing 1:blackbox:14:git-annex unused/dropunused
+### Error in: 1:blackbox:14:git-annex unused/dropunused
+forkProcess: resource exhausted (Resource temporarily unavailable)
+Cases: 30 Tried: 30 Errors: 2 Failures: 4
+test: failed
+</pre>
+
+
+the number of failures vary as I change the values of the maxprocs, I think I have narrowed it down to OSX just being stupid with limits thus causing the tests to fail.
+
+"""]]
diff --git a/doc/bugs/Problems_running_make_on_osx/comment_16_5c2dd6002aadaab30841b77a5f5aed34._comment b/doc/bugs/Problems_running_make_on_osx/comment_16_5c2dd6002aadaab30841b77a5f5aed34._comment
new file mode 100644
index 000000000..ca1b8e8cd
--- /dev/null
+++ b/doc/bugs/Problems_running_make_on_osx/comment_16_5c2dd6002aadaab30841b77a5f5aed34._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 16"
+ date="2011-02-13T04:52:26Z"
+ content="""
+I've fixed the test suite to not accumulate all those zombie processes. Now only 2 or 3 processes should run max. Am curious to see if that clears up all the problems.
+"""]]
diff --git a/doc/bugs/Problems_running_make_on_osx/comment_17_62fccb04b0e4b695312f7a3f32fb96ee._comment b/doc/bugs/Problems_running_make_on_osx/comment_17_62fccb04b0e4b695312f7a3f32fb96ee._comment
new file mode 100644
index 000000000..7c7200fb9
--- /dev/null
+++ b/doc/bugs/Problems_running_make_on_osx/comment_17_62fccb04b0e4b695312f7a3f32fb96ee._comment
@@ -0,0 +1,43 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 17"
+ date="2011-02-13T10:46:54Z"
+ content="""
+Yeap, that did the trick. I just tested a few separate OSX 10.6.6 systems and the tests are better behaved now, only 3 failures now.
+
+So the tests behave better (at least we don't get resource fork errors any more)
+
+ * after the commit c319a3 without modifying the system limits (of 266 procs per user)
+ * without the commit c319a3 and when I increase the system process limits to as much as OSX allows
+
+On all the systems I tested on, I'm down to 3 failures now.
+
+<pre>
+### Failure in: 1:blackbox:3:git-annex unannex:1:with content
+foo is not a symlink
+### Failure in: 1:blackbox:4:git-annex drop:0:no remotes
+drop wrongly succeeded with no known copy of file
+Cases: 30 Tried: 20 Errors: 0 Failures: 2add foo ok
+ok
+Cases: 30 Tried: 24 Errors: 0 Failures: 2 Only 1 of 2 trustworthy copies of foo exist.
+ Back it up with git-annex copy.
+ Only 1 of 2 trustworthy copies of sha1foo exist.
+ Back it up with git-annex copy.
+ Bad file size; moved to /Users/jtang/develop/git-annex/.t/tmprepo/.git/annex/bad/WORM:1297594011:20:foo
+ Bad file content; moved to /Users/jtang/develop/git-annex/.t/tmprepo/.git/annex/bad/SHA1:ee80d2cec57a3810db83b80e1b320df3a3721ffa
+### Failure in: 1:blackbox:12:git-annex fsck:1
+fsck failed to fail with content only available in untrusted (current) repository
+Cases: 30 Tried: 26 Errors: 0 Failures: 3 Only 1 of 2 trustworthy copies of foo exist.
+ Back it up with git-annex copy.
+ The following untrusted locations may also have copies:
+ 90d63906-375e-11e0-8867-abb8a6368269 -- test repo
+ Only 1 of 2 trustworthy copies of sha1foo exist.
+ Back it up with git-annex copy.
+ The following untrusted locations may also have copies:
+ 90d63906-375e-11e0-8867-abb8a6368269 -- test repo
+Cases: 30 Tried: 30 Errors: 0 Failures: 3
+</pre>
+
+It's the same set of failures across all the OSX systems that I have tested on. Now I just need to figure out why there are still these three failures.
+"""]]
diff --git a/doc/bugs/Problems_running_make_on_osx/comment_18_64fab50d95de619eb2e8f08f90237de1._comment b/doc/bugs/Problems_running_make_on_osx/comment_18_64fab50d95de619eb2e8f08f90237de1._comment
new file mode 100644
index 000000000..df76bb301
--- /dev/null
+++ b/doc/bugs/Problems_running_make_on_osx/comment_18_64fab50d95de619eb2e8f08f90237de1._comment
@@ -0,0 +1,24 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="maybe killed another osx bug in the test."
+ date="2011-02-13T15:12:10Z"
+ content="""
+I think I have figured out why
+
+ ### Failure in: 1:blackbox:3:git-annex unannex:1:with content
+ foo is not a symlink
+
+It goes back to the this piece of code (in test.hs)
+
+ copyrepo :: FilePath -> FilePath -> IO FilePath
+ copyrepo old new = do
+ cleanup new
+ ensuretmpdir
+ Utility.boolSystem \"cp\" [\"-pr\", old, new] @? \"cp -pr failed\"
+
+It seems that on OSX it does not preserve the symbolic link information, basically cp is not gnu cp on OSX, doing a \"cp -a SOURCE DEST\" seem's to the right thing on OSX. I tried it out on my archlinux workstation by replacing *-pr* with just *-a* and all the tests passed on archlinux.
+
+I'm not sure what the implications would be with changing the test with changing the cp command.
+
+"""]]
diff --git a/doc/bugs/Problems_running_make_on_osx/comment_19_4253988ed178054c8b6400beeed68a29._comment b/doc/bugs/Problems_running_make_on_osx/comment_19_4253988ed178054c8b6400beeed68a29._comment
new file mode 100644
index 000000000..090c991c3
--- /dev/null
+++ b/doc/bugs/Problems_running_make_on_osx/comment_19_4253988ed178054c8b6400beeed68a29._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 19"
+ date="2011-02-13T15:55:47Z"
+ content="""
+On second thought and after some messing (trying most of the options and combinations of options on OSX for).... I tried replacing cp with gnu cp from coreutils on my OSX install, and all the tests passed. *sigh* cp -a is preserving some permissions and attributes but not all, its not behaving in the same way as the gnu cp does... the closet thing that I have found on OSX that behaves in the same way as gnu \"cp -pr\" is to use \"ditto\".
+
+Just doing a \"ditto SOURCE DEST\" in the tests passes everything. I'm not sure if its a good idea to use this even though it works. Though this is just the tests, does it affect CopyFile.hs where \"cp\" is called?
+
+"""]]
diff --git a/doc/bugs/Problems_running_make_on_osx/comment_1_34120e82331ace01a6a4960862d38f2d._comment b/doc/bugs/Problems_running_make_on_osx/comment_1_34120e82331ace01a6a4960862d38f2d._comment
new file mode 100644
index 000000000..a33fef7d9
--- /dev/null
+++ b/doc/bugs/Problems_running_make_on_osx/comment_1_34120e82331ace01a6a4960862d38f2d._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmd3qri1pXEYktlxYGwj37wCnrM4FMEJCc"
+ nickname="Antoine"
+ subject="Got it going!"
+ date="2011-02-06T06:02:57Z"
+ content="""
+Thanks to your feedback, I got it going.
+
+Maybe those two should be added to the 'OSX how-to' in the forum
+
+[realizes pcre-light is needed but pcre not installed on my mac]
+sudo port install pcre
+sudo cabal install pcre-light
+
+[tests are failing, need haskell's quickcheck]
+sudo cabal install quickcheck
+"""]]
diff --git a/doc/bugs/Problems_running_make_on_osx/comment_20_7db27d1a22666c831848bc6c06d66a84._comment b/doc/bugs/Problems_running_make_on_osx/comment_20_7db27d1a22666c831848bc6c06d66a84._comment
new file mode 100644
index 000000000..b617da926
--- /dev/null
+++ b/doc/bugs/Problems_running_make_on_osx/comment_20_7db27d1a22666c831848bc6c06d66a84._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 20"
+ date="2011-02-13T17:54:09Z"
+ content="""
+Outside the test suite, git-annex's actual use of cp puts fairly low demands on it. It tries to use cp -a or cp -p if available just to preserve whatever attributes it can preserve, but the worst case if that you have a symlink pointing to a file that doesn't have the original timestamp or whatever. And there's little expectation git preserves that stuff anyway.
+
+I will probably try to make the test suite entirely use git clone rather than cp.
+"""]]
diff --git a/doc/bugs/Problems_running_make_on_osx/comment_2_cc53d1681d576186dbc868dd9801d551._comment b/doc/bugs/Problems_running_make_on_osx/comment_2_cc53d1681d576186dbc868dd9801d551._comment
new file mode 100644
index 000000000..91d3e89f0
--- /dev/null
+++ b/doc/bugs/Problems_running_make_on_osx/comment_2_cc53d1681d576186dbc868dd9801d551._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 2"
+ date="2011-02-06T17:39:52Z"
+ content="""
+Yes, I've moved it to [[install/OSX]] page where anyone can update it in this wiki, and added your improvements.
+"""]]
diff --git a/doc/bugs/Problems_running_make_on_osx/comment_3_68f0f8ae953589ae26d57310b40c878d._comment b/doc/bugs/Problems_running_make_on_osx/comment_3_68f0f8ae953589ae26d57310b40c878d._comment
new file mode 100644
index 000000000..39f32c244
--- /dev/null
+++ b/doc/bugs/Problems_running_make_on_osx/comment_3_68f0f8ae953589ae26d57310b40c878d._comment
@@ -0,0 +1,57 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="tests fail with more recent installs of haskell platform"
+ date="2011-02-07T12:43:43Z"
+ content="""
+I'm running ghc 6.12.3 with the corresponding haskell-platform package from the HP site which I installed in preference to the macports version of haskell-platform (it's quite old). it seems when you install quickcheck, the version that is installed is of version 2.4.0.1 and not 1.2.0 which git-annex depends on for its tests.
+
+<pre>
+jtang@x00:~ $ cabal install quickcheck --reinstall
+Resolving dependencies...
+Configuring QuickCheck-2.4.0.1...
+Preprocessing library QuickCheck-2.4.0.1...
+
+..
+and so on..
+..
+
+</pre>
+
+it fails with this
+
+<pre>
+[54 of 54] Compiling Main ( test.hs, test.o )
+
+test.hs:56:3:
+ No instance for (QuickCheck-1.2.0.1:Test.QuickCheck.Arbitrary Char)
+ arising from a use of `qctest' at test.hs:56:3-64
+ Possible fix:
+ add an instance declaration for
+ (QuickCheck-1.2.0.1:Test.QuickCheck.Arbitrary Char)
+ In the expression:
+ qctest \"prop_idempotent_deencode\" Git.prop_idempotent_deencode
+ In the first argument of `TestList', namely
+ `[qctest \"prop_idempotent_deencode\" Git.prop_idempotent_deencode,
+ qctest \"prop_idempotent_fileKey\" Locations.prop_idempotent_fileKey,
+ qctest
+ \"prop_idempotent_key_read_show\"
+ BackendTypes.prop_idempotent_key_read_show,
+ qctest
+ \"prop_idempotent_shellEscape\" Utility.prop_idempotent_shellEscape,
+ ....]'
+ In the second argument of `($)', namely
+ `TestList
+ [qctest \"prop_idempotent_deencode\" Git.prop_idempotent_deencode,
+ qctest \"prop_idempotent_fileKey\" Locations.prop_idempotent_fileKey,
+ qctest
+ \"prop_idempotent_key_read_show\"
+ BackendTypes.prop_idempotent_key_read_show,
+ qctest
+ \"prop_idempotent_shellEscape\" Utility.prop_idempotent_shellEscape,
+ ....]'
+</pre>
+
+I'd imagine if I could downgrade, it would compile and pass the tests (I hope)
+
+"""]]
diff --git a/doc/bugs/Problems_running_make_on_osx/comment_4_c52be386f79f14c8570a8f1397c68581._comment b/doc/bugs/Problems_running_make_on_osx/comment_4_c52be386f79f14c8570a8f1397c68581._comment
new file mode 100644
index 000000000..e245e139f
--- /dev/null
+++ b/doc/bugs/Problems_running_make_on_osx/comment_4_c52be386f79f14c8570a8f1397c68581._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 4"
+ date="2011-02-08T19:00:14Z"
+ content="""
+I doubt that git-annex can be used with QuickCheck 1.2.0. The QuickCheck I've tested it with is 2.1.0.3 actually.
+
+I suspect you have an old version of the TestPack haskell library on your system, that is linked against QuickCheck 1.2.0. Git-annex has been tested with TestPack 2.0.0, which uses QuickCheck 2.x.
+
+In any case, you don't have to run 'make test' to build git-annex, and my comments above should make the main program compile, I expect.
+"""]]
diff --git a/doc/bugs/Problems_running_make_on_osx/comment_5_7f1330a1e541b0f3e2192e596d7f7bee._comment b/doc/bugs/Problems_running_make_on_osx/comment_5_7f1330a1e541b0f3e2192e596d7f7bee._comment
new file mode 100644
index 000000000..9c83feb32
--- /dev/null
+++ b/doc/bugs/Problems_running_make_on_osx/comment_5_7f1330a1e541b0f3e2192e596d7f7bee._comment
@@ -0,0 +1,107 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 5"
+ date="2011-02-08T19:56:55Z"
+ content="""
+Ah, that gave me a good clue, my system just got pretty confused with a mixture of quickcheck and testpack installs. Would it be possible to put up a list of versions of the software you are using on your development environment? (at least the minimum tested version)
+
+I guess it shouldn't matter to most users who are going to rely on packagers to sort these dependancy issues, but it's nice to know.
+
+Anyway, the tests build now, and they seem to fail on my (rather messy) install of haskell platform + ghc 6.12 on osx 10.6.6.
+
+<pre>
+< output that passed some tests >
+Testing 1:blackbox:0:git-annex init
+Testing 1:blackbox:1:git-annex add:0
+Testing 1:blackbox:1:git-annex add:1
+Cases: 30 Tried: 9 Errors: 0 Failures: 0test: sha1sum: executeFile: does not exist (No such file or directory)
+ git-annex: <file descriptor: 6>: hGetLine: end of file
+### Failure in: 1:blackbox:1:git-annex add:1
+add with SHA1 failed
+Testing 1:blackbox:2:git-annex setkey/fromkey
+Cases: 30 Tried: 10 Errors: 0 Failures: 1(checksum...) test: sha1sum: executeFile: does not exist (No such file or directory)
+### Error in: 1:blackbox:2:git-annex setkey/fromkey
+<file descriptor: 3>: hGetLine: end of file
+Testing 1:blackbox:3:git-annex unannex:0:no content
+Cases: 30 Tried: 11 Errors: 1 Failures: 1chmod: -R: No such file or directory
+chmod: -R: No such file or directory
+Testing 1:blackbox:3:git-annex unannex:1:with content
+### Failure in: 1:blackbox:3:git-annex unannex:1:with content
+foo is not a symlink
+Testing 1:blackbox:4:git-annex drop:0:no remotes
+Cases: 30 Tried: 13 Errors: 1 Failures: 2chmod: -R: No such file or directory
+### Error in: 1:blackbox:4:git-annex drop:0:no remotes
+.t/tmprepo/.git/annex/objects/WORM:1297194705:20:foo/WORM:1297194705:20:foo: removeLink: permission denied (Permission denied)
+Testing 1:blackbox:4:git-annex drop:1:with remote
+Cases: 30 Tried: 14 Errors: 2 Failures: 2chmod: -R: No such file or directory
+### Error in: 1:blackbox:4:git-annex drop:1:with remote
+.t/tmprepo/.git/annex/objects/WORM:1297194705:20:foo/WORM:1297194705:20:foo: removeLink: permission denied (Permission denied)
+Testing 1:blackbox:4:git-annex drop:2:untrusted remote
+Cases: 30 Tried: 15 Errors: 3 Failures: 2chmod: -R: No such file or directory
+### Error in: 1:blackbox:4:git-annex drop:2:untrusted remote
+.t/tmprepo/.git/annex/objects/WORM:1297194705:20:foo/WORM:1297194705:20:foo: removeLink: permission denied (Permission denied)
+Testing 1:blackbox:5:git-annex get
+Cases: 30 Tried: 16 Errors: 4 Failures: 2chmod: -R: No such file or directory
+### Error in: 1:blackbox:5:git-annex get
+.t/tmprepo/.git/annex/objects/WORM:1297194705:20:foo/WORM:1297194705:20:foo: removeLink: permission denied (Permission denied)
+Testing 1:blackbox:6:git-annex move
+Cases: 30 Tried: 17 Errors: 5 Failures: 2chmod: -R: No such file or directory
+### Error in: 1:blackbox:6:git-annex move
+.t/tmprepo/.git/annex/objects/WORM:1297194705:20:foo/WORM:1297194705:20:foo: removeLink: permission denied (Permission denied)
+Testing 1:blackbox:7:git-annex copy
+Cases: 30 Tried: 18 Errors: 6 Failures: 2chmod: -R: No such file or directory
+### Error in: 1:blackbox:7:git-annex copy
+.t/tmprepo/.git/annex/objects/WORM:1297194705:20:foo/WORM:1297194705:20:foo: removeLink: permission denied (Permission denied)
+Testing 1:blackbox:8:git-annex unlock/lock
+Cases: 30 Tried: 19 Errors: 7 Failures: 2chmod: -R: No such file or directory
+### Error in: 1:blackbox:8:git-annex unlock/lock
+.t/tmprepo/.git/annex/objects/WORM:1297194705:20:foo/WORM:1297194705:20:foo: removeLink: permission denied (Permission denied)
+Testing 1:blackbox:9:git-annex edit/commit:0
+Cases: 30 Tried: 20 Errors: 8 Failures: 2chmod: -R: No such file or directory
+### Error in: 1:blackbox:9:git-annex edit/commit:0
+.t/tmprepo/.git/annex/objects/WORM:1297194705:20:foo/WORM:1297194705:20:foo: removeLink: permission denied (Permission denied)
+Testing 1:blackbox:9:git-annex edit/commit:1
+Cases: 30 Tried: 21 Errors: 9 Failures: 2chmod: -R: No such file or directory
+### Error in: 1:blackbox:9:git-annex edit/commit:1
+.t/tmprepo/.git/annex/objects/WORM:1297194705:20:foo/WORM:1297194705:20:foo: removeLink: permission denied (Permission denied)
+Testing 1:blackbox:10:git-annex fix
+Cases: 30 Tried: 22 Errors: 10 Failures: 2chmod: -R: No such file or directory
+### Error in: 1:blackbox:10:git-annex fix
+.t/tmprepo/.git/annex/objects/WORM:1297194705:20:foo/WORM:1297194705:20:foo: removeLink: permission denied (Permission denied)
+Testing 1:blackbox:11:git-annex trust/untrust/semitrust
+Cases: 30 Tried: 23 Errors: 11 Failures: 2chmod: -R: No such file or directory
+### Error in: 1:blackbox:11:git-annex trust/untrust/semitrust
+.t/tmprepo/.git/annex/objects/WORM:1297194705:20:foo/WORM:1297194705:20:foo: removeLink: permission denied (Permission denied)
+Testing 1:blackbox:12:git-annex fsck:0
+Cases: 30 Tried: 24 Errors: 12 Failures: 2chmod: -R: No such file or directory
+### Error in: 1:blackbox:12:git-annex fsck:0
+.t/tmprepo/.git/annex/objects/WORM:1297194705:20:foo/WORM:1297194705:20:foo: removeLink: permission denied (Permission denied)
+Testing 1:blackbox:12:git-annex fsck:1
+Cases: 30 Tried: 25 Errors: 13 Failures: 2chmod: -R: No such file or directory
+### Error in: 1:blackbox:12:git-annex fsck:1
+.t/tmprepo/.git/annex/objects/WORM:1297194705:20:foo/WORM:1297194705:20:foo: removeLink: permission denied (Permission denied)
+Testing 1:blackbox:12:git-annex fsck:2
+Cases: 30 Tried: 26 Errors: 14 Failures: 2chmod: -R: No such file or directory
+### Error in: 1:blackbox:12:git-annex fsck:2
+.t/tmprepo/.git/annex/objects/WORM:1297194705:20:foo/WORM:1297194705:20:foo: removeLink: permission denied (Permission denied)
+Testing 1:blackbox:13:git-annex migrate:0
+Cases: 30 Tried: 27 Errors: 15 Failures: 2chmod: -R: No such file or directory
+### Error in: 1:blackbox:13:git-annex migrate:0
+.t/tmprepo/.git/annex/objects/WORM:1297194705:20:foo/WORM:1297194705:20:foo: removeLink: permission denied (Permission denied)
+Testing 1:blackbox:13:git-annex migrate:1
+Cases: 30 Tried: 28 Errors: 16 Failures: 2chmod: -R: No such file or directory
+### Error in: 1:blackbox:13:git-annex migrate:1
+.t/tmprepo/.git/annex/objects/WORM:1297194705:20:foo/WORM:1297194705:20:foo: removeLink: permission denied (Permission denied)
+Testing 1:blackbox:14:git-annex unused/dropunused
+Cases: 30 Tried: 29 Errors: 17 Failures: 2chmod: -R: No such file or directory
+### Error in: 1:blackbox:14:git-annex unused/dropunused
+.t/tmprepo/.git/annex/objects/WORM:1297194705:20:foo/WORM:1297194705:20:foo: removeLink: permission denied (Permission denied)
+Cases: 30 Tried: 30 Errors: 18 Failures: 2
+chmod: -R: No such file or directory
+test: .t/repo/.git/annex/objects/WORM:1297194705:20:foo/WORM:1297194705:20:foo: removeLink: permission denied (Permission denied)
+make: *** [test] Error 1
+</pre>
+
+I assumed that since the tests built, then running them shouldn't be a problem. It looks like some argument isn't being passed about for the location of the .t directory that gets created. I will check the dependancies on my system again.
+"""]]
diff --git a/doc/bugs/Problems_running_make_on_osx/comment_6_0c46f5165ceb5a7b9ea9689c33b3a4f8._comment b/doc/bugs/Problems_running_make_on_osx/comment_6_0c46f5165ceb5a7b9ea9689c33b3a4f8._comment
new file mode 100644
index 000000000..afc3088d4
--- /dev/null
+++ b/doc/bugs/Problems_running_make_on_osx/comment_6_0c46f5165ceb5a7b9ea9689c33b3a4f8._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 6"
+ date="2011-02-08T23:20:08Z"
+ content="""
+You're missing the sha1sum command, everything else is a followon error from that. Added a hint about this to [[install]],
+and in the next version configure will check for sha1sum.
+"""]]
diff --git a/doc/bugs/Problems_running_make_on_osx/comment_7_237a137cce58a28abcc736cbf2c420b0._comment b/doc/bugs/Problems_running_make_on_osx/comment_7_237a137cce58a28abcc736cbf2c420b0._comment
new file mode 100644
index 000000000..8d8aefcb2
--- /dev/null
+++ b/doc/bugs/Problems_running_make_on_osx/comment_7_237a137cce58a28abcc736cbf2c420b0._comment
@@ -0,0 +1,22 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 7"
+ date="2011-02-09T00:45:31Z"
+ content="""
+That's odd, I have the md5sha1sum package installed and it still fails with pretty much the same error
+
+<pre>
+Testing 1:blackbox:0:git-annex init
+Cases: 30 Tried: 7 Errors: 0 Failures: 0chmod: -R: No such file or directory
+### Error in: 1:blackbox:0:git-annex init
+.t/repo/.git/annex/objects/SHA1:ee80d2cec57a3810db83b80e1b320df3a3721ffa/SHA1:ee80d2cec57a3810db83b80e1b320df3a3721ffa: removeLink: permission denied (Permission denied)
+Testing 1:blackbox:1:git-annex add:0
+### Error in: 1:blackbox:1:git-annex add:0
+foo: openFile: permission denied (Permission denied)
+
+< and so on >
+</pre>
+
+the configure script finds sha1sum, builds and starts to run.
+"""]]
diff --git a/doc/bugs/Problems_running_make_on_osx/comment_8_efafa203addf8fa79e33e21a87fb5a2b._comment b/doc/bugs/Problems_running_make_on_osx/comment_8_efafa203addf8fa79e33e21a87fb5a2b._comment
new file mode 100644
index 000000000..9401bd453
--- /dev/null
+++ b/doc/bugs/Problems_running_make_on_osx/comment_8_efafa203addf8fa79e33e21a87fb5a2b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 8"
+ date="2011-02-09T04:10:27Z"
+ content="""
+The chmod errors are because your chmod does not understand the -R argument. Only the test suite uses chmod -R. I've fixed it to modify modes manually.
+"""]]
diff --git a/doc/bugs/Problems_running_make_on_osx/comment_9_cc283b485b3c95ba7eebc8f0c96969b3._comment b/doc/bugs/Problems_running_make_on_osx/comment_9_cc283b485b3c95ba7eebc8f0c96969b3._comment
new file mode 100644
index 000000000..da6d7ca17
--- /dev/null
+++ b/doc/bugs/Problems_running_make_on_osx/comment_9_cc283b485b3c95ba7eebc8f0c96969b3._comment
@@ -0,0 +1,66 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 9"
+ date="2011-02-09T09:12:52Z"
+ content="""
+[a0826293][] fixed the last problem, there is coreutils available in macports, if they are installed you get the gnu equivalents but they are prefixed with a g (e.g. gchmod instead of chmod), I guess not everyone will have these install or prefer these on [[install/OSX]]
+
+Some more tests fail now...
+
+<pre>
+Testing 1:blackbox:3:git-annex unannex:1:with content
+### Failure in: 1:blackbox:3:git-annex unannex:1:with content
+foo is not a symlink
+Testing 1:blackbox:4:git-annex drop:0:no remotes
+### Failure in: 1:blackbox:4:git-annex drop:0:no remotes
+drop wrongly succeeded with no known copy of file
+Testing 1:blackbox:4:git-annex drop:1:with remote
+Testing 1:blackbox:4:git-annex drop:2:untrusted remote
+Testing 1:blackbox:5:git-annex get
+Testing 1:blackbox:6:git-annex move
+Testing 1:blackbox:7:git-annex copy
+### Failure in: 1:blackbox:7:git-annex copy
+move --to of file already there failed
+Testing 1:blackbox:8:git-annex unlock/lock
+### Error in: 1:blackbox:8:git-annex unlock/lock
+forkProcess: resource exhausted (Resource temporarily unavailable)
+Testing 1:blackbox:9:git-annex edit/commit:0
+### Error in: 1:blackbox:9:git-annex edit/commit:0
+forkProcess: resource exhausted (Resource temporarily unavailable)
+Testing 1:blackbox:9:git-annex edit/commit:1
+### Error in: 1:blackbox:9:git-annex edit/commit:1
+forkProcess: resource exhausted (Resource temporarily unavailable)
+Testing 1:blackbox:10:git-annex fix
+### Error in: 1:blackbox:10:git-annex fix
+forkProcess: resource exhausted (Resource temporarily unavailable)
+Testing 1:blackbox:11:git-annex trust/untrust/semitrust
+### Error in: 1:blackbox:11:git-annex trust/untrust/semitrust
+forkProcess: resource exhausted (Resource temporarily unavailable)
+Testing 1:blackbox:12:git-annex fsck:0
+### Error in: 1:blackbox:12:git-annex fsck:0
+forkProcess: resource exhausted (Resource temporarily unavailable)
+Testing 1:blackbox:12:git-annex fsck:1
+### Error in: 1:blackbox:12:git-annex fsck:1
+forkProcess: resource exhausted (Resource temporarily unavailable)
+Testing 1:blackbox:12:git-annex fsck:2
+### Error in: 1:blackbox:12:git-annex fsck:2
+forkProcess: resource exhausted (Resource temporarily unavailable)
+Testing 1:blackbox:13:git-annex migrate:0
+### Error in: 1:blackbox:13:git-annex migrate:0
+forkProcess: resource exhausted (Resource temporarily unavailable)
+Testing 1:blackbox:13:git-annex migrate:1
+### Error in: 1:blackbox:13:git-annex migrate:1
+forkProcess: resource exhausted (Resource temporarily unavailable)
+Testing 1:blackbox:14:git-annex unused/dropunused
+### Error in: 1:blackbox:14:git-annex unused/dropunused
+forkProcess: resource exhausted (Resource temporarily unavailable)
+Cases: 30 Tried: 30 Errors: 11 Failures: 3
+test: failed
+make: *** [test] Error 1
+</pre>
+
+On a side note, I think I found another bug in the testing. I had tested in a virtual machine in archlinux (a very recent updated version) Please see the report here [[tests fail when there is no global .gitconfig for the user]]
+
+[a0826293]: http://git.kitenet.net/?p=git-annex;a=commit;h=7a0826293e0ac6c0000f49a1618c1c613b909aa1
+"""]]
diff --git a/doc/bugs/Problems_with_syncing_gnucash.mdwn b/doc/bugs/Problems_with_syncing_gnucash.mdwn
new file mode 100644
index 000000000..6a1f96a9f
--- /dev/null
+++ b/doc/bugs/Problems_with_syncing_gnucash.mdwn
@@ -0,0 +1,568 @@
+### Please describe the problem.
+I am trying to sync gnucash between my server and my notebook. Both devices are connected via VPN to provide bidirectional SSH connectivity. After adding some data in gnucash the logfiles get synced properly but the changes to the gnucash.gnucash file are not recognized. Touching the file afterwards causes git-annex to immediately transfer the file.
+
+### What steps will reproduce the problem?
+
+Store your gnucash configuration in a git-annex repository. Add some transactions and wait for git-annex to sync your *.gnucash file.
+
+### What version of git-annex are you using? On what operating system?
+
+server and notebook -> Ubuntu 12.04.2 LTS:
+[[!format sh """
+florz@server:~$ git-annex version
+git-annex version: 4.20130601
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP DNS
+"""]]
+
+### Please provide any additional information below.
+
+before opening gnucash:
+[[!format sh """
+florz@notebook:~$ stat annex-sync/gnucash/gnucash.gnucash
+ Datei: »annex-sync/gnucash/gnucash.gnucash“
+ Größe: 113902 Blöcke: 240 EA Block: 4096 Normale Datei
+Gerät: 15h/21d Inode: 2974371 Verknüpfungen: 1
+Zugriff: (0600/-rw-------) Uid: ( 1000/ florz) Gid: ( 1000/ florz)
+Zugriff : 2013-06-22 19:32:37.974073365 +0200
+Modifiziert: 2013-06-22 19:32:37.846073367 +0200
+Geändert : 2013-06-22 19:32:37.970073365 +0200
+ Geburt : -
+
+florz@server:~$ stat annex-sync/gnucash/gnucash.gnucash
+ Datei: »annex-sync/gnucash/gnucash.gnucash“
+ Größe: 113902 Blöcke: 224 EA Block: 4096 Normale Datei
+Gerät: fc00h/64512d Inode: 401737579 Verknüpfungen: 1
+Zugriff: (0600/-rw-------) Uid: ( 1000/ florz) Gid: ( 1000/ florz)
+Zugriff : 2013-06-22 19:40:24.148876398 +0200
+Modifiziert: 2013-06-22 19:24:18.000000000 +0200
+Geändert : 2013-06-22 19:24:26.817865369 +0200
+ Geburt : -
+"""]]
+
+after doing some changes in gnucash:
+[[!format sh """
+florz@notebook:~$ stat annex-sync/gnucash/gnucash.gnucash
+ Datei: »annex-sync/gnucash/gnucash.gnucash“
+ Größe: 114039 Blöcke: 240 EA Block: 4096 Normale Datei
+Gerät: 15h/21d Inode: 2974990 Verknüpfungen: 1
+Zugriff: (0600/-rw-------) Uid: ( 1000/ florz) Gid: ( 1000/ florz)
+Zugriff : 2013-06-22 19:52:12.226049268 +0200
+Modifiziert: 2013-06-22 19:52:12.342049265 +0200
+Geändert : 2013-06-22 19:52:12.342049265 +0200
+ Geburt : -
+
+florz@server:~$ stat annex-sync/gnucash/gnucash.gnucash
+ Datei: »annex-sync/gnucash/gnucash.gnucash“
+ Größe: 113902 Blöcke: 224 EA Block: 4096 Normale Datei
+Gerät: fc00h/64512d Inode: 401737579 Verknüpfungen: 1
+Zugriff: (0600/-rw-------) Uid: ( 1000/ florz) Gid: ( 1000/ florz)
+Zugriff : 2013-06-22 19:40:24.148876398 +0200
+Modifiziert: 2013-06-22 19:24:18.000000000 +0200
+Geändert : 2013-06-22 19:24:26.817865369 +0200
+ Geburt : -
+
+# after some time -> still no transfer
+
+florz@server:~$ stat annex-sync/gnucash/gnucash.gnucash
+ Datei: »annex-sync/gnucash/gnucash.gnucash“
+ Größe: 113902 Blöcke: 224 EA Block: 4096 Normale Datei
+Gerät: fc00h/64512d Inode: 401737579 Verknüpfungen: 1
+Zugriff: (0600/-rw-------) Uid: ( 1000/ florz) Gid: ( 1000/ florz)
+Zugriff : 2013-06-22 19:40:24.148876398 +0200
+Modifiziert: 2013-06-22 19:24:18.000000000 +0200
+Geändert : 2013-06-22 19:24:26.817865369 +0200
+ Geburt : -
+"""]]
+
+doing a touch on the file:
+[[!format sh """
+florz@notebook:~$ touch annex-sync/gnucash/gnucash.gnucash
+florz@notebook:~$ stat annex-sync/gnucash/gnucash.gnucash
+ Datei: »annex-sync/gnucash/gnucash.gnucash“
+ Größe: 114039 Blöcke: 240 EA Block: 4096 Normale Datei
+Gerät: 15h/21d Inode: 2974990 Verknüpfungen: 1
+Zugriff: (0600/-rw-------) Uid: ( 1000/ florz) Gid: ( 1000/ florz)
+Zugriff : 2013-06-22 19:54:27.222046497 +0200
+Modifiziert: 2013-06-22 19:54:27.070046501 +0200
+Geändert : 2013-06-22 19:54:27.214046498 +0200
+ Geburt : -
+
+#it syncs immediately
+
+florz@server:~$ stat annex-sync/gnucash/gnucash.gnucash
+ Datei: »annex-sync/gnucash/gnucash.gnucash“
+ Größe: 114039 Blöcke: 224 EA Block: 4096 Normale Datei
+Gerät: fc00h/64512d Inode: 401737638 Verknüpfungen: 1
+Zugriff: (0600/-rw-------) Uid: ( 1000/ florz) Gid: ( 1000/ florz)
+Zugriff : 2013-06-22 19:54:35.307056482 +0200
+Modifiziert: 2013-06-22 19:54:27.000000000 +0200
+Geändert : 2013-06-22 19:54:34.787072264 +0200
+ Geburt : -
+"""]]
+
+on my notebook:
+[[!format sh """
+Everything up-to-date
+Everything up-to-date
+Everything up-to-date
+[2013-06-22 19:52:12 CEST] Watcher: file deleted gnucash/gnucash.gnucash.tmp-rFzA3U
+[2013-06-22 19:52:12 CEST] Committer: committing 1 changes
+[2013-06-22 19:52:12 CEST] Committer: Committing changes to git
+[2013-06-22 19:52:12 CEST] feed: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","update-index","-z","--index-info"]
+[2013-06-22 19:52:12 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","commit","--allow-empty-message","--no-edit","-m","","--quiet","--no-verify"]
+[2013-06-22 19:52:12 CEST] Pusher: Syncing with server192.168.2.2, home192.168.1.3
+[2013-06-22 19:52:12 CEST] Watcher: add direct gnucash/gnucash.gnucash.20130622195200.log
+[2013-06-22 19:52:12 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","symbolic-ref","HEAD"]
+[2013-06-22 19:52:12 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","refs/heads/master"]
+[2013-06-22 19:52:12 CEST] Pusher: pushing to [Remote { name ="server192.168.2.2" },Remote { name ="home192.168.1.3" }]
+[2013-06-22 19:52:12 CEST] call: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","branch","-f","synced/master"]
+[2013-06-22 19:52:12 CEST] call: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","push","home192.168.1.3","git-annex:synced/git-annex","master:synced/master"]
+[2013-06-22 19:52:12 CEST] call: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","push","server192.168.2.2","git-annex:synced/git-annex","master:synced/master"]
+[2013-06-22 19:52:13 CEST] read: lsof ["-F0can","+d","/home/florz/annex-sync/.git/annex/tmp/"]
+[2013-06-22 19:52:13 CEST] Committer: Adding gnucash.g..95200.log
+ok
+(Recording state in git...)
+(Recording state in git...)
+
+
+
+(Recording state in git...)
+add gnucash/gnucash.gnucash.20130622195200.log (checksum...) [2013-06-22 19:52:13 CEST] chat: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","hash-object","-t","blob","-w","--stdin"]
+[2013-06-22 19:52:13 CEST] Committer: committing 1 changes
+[2013-06-22 19:52:13 CEST] Committer: Committing changes to git
+[2013-06-22 19:52:13 CEST] feed: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","update-index","-z","--index-info"]
+[2013-06-22 19:52:13 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","commit","--allow-empty-message","--no-edit","-m","","--quiet","--no-verify"]
+[2013-06-22 19:52:13 CEST] Committer: queued Upload UUID "dc591dd7-2446-45c6-84dc-55bdf79e7512" gnucash/gnucash.gnucash.20130622195200.log Nothing : new file created
+[2013-06-22 19:52:13 CEST] Transferrer: Transferring: Upload UUID "dc591dd7-2446-45c6-84dc-55bdf79e7512" gnucash/gnucash.gnucash.20130622195200.log Nothing
+[2013-06-22 19:52:13 CEST] Committer: queued Upload UUID "84bab1ab-238f-4602-953a-a297aab6da44" gnucash/gnucash.gnucash.20130622195200.log Nothing : new file created
+[2013-06-22 19:52:13 CEST] call: /home/florz/bin/git-annex ["transferkeys","--readfd","29","--writefd","27"]
+[2013-06-22 19:52:13 CEST] TransferWatcher: transfer starting: Upload UUID "dc591dd7-2446-45c6-84dc-55bdf79e7512" gnucash/gnucash.gnucash.20130622195200.log Nothing
+[2013-06-22 19:52:14 CEST] Watcher: changed direct .gnucash/books/gnucash.gnucash.gcm
+[2013-06-22 19:52:14 CEST] Watcher: file deleted gnucash/gnucash.gnucash.7f0101.29284.LNK
+[2013-06-22 19:52:14 CEST] Watcher: file deleted gnucash/gnucash.gnucash.LCK
+[2013-06-22 19:52:14 CEST] Watcher: changed direct .gnucash/accelerator-map
+[2013-06-22 19:52:14 CEST] Watcher: changed direct .gnucash/expressions-2.0
+[2013-06-22 19:52:14 CEST] Watcher: changed direct .gnucash/stylesheets-2.0
+[2013-06-22 19:52:14 CEST] Watcher: add direct gnucash/gnucash.gnucash.20130622195212.log
+[2013-06-22 19:52:14 CEST] read: lsof ["-F0can","+d","/home/florz/annex-sync/.git/annex/tmp/"]
+[2013-06-22 19:52:14 CEST] Committer: Adding 5 files
+ok
+(Recording state in git...)
+add .gnucash/books/gnucash.gnucash.gcm (checksum...) [2013-06-22 19:52:15 CEST] chat: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","hash-object","-t","blob","-w","--stdin"]
+ok
+add .gnucash/accelerator-map (checksum...) [2013-06-22 19:52:15 CEST] chat: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","hash-object","-t","blob","-w","--stdin"]
+ok
+add .gnucash/expressions-2.0 (checksum...) [2013-06-22 19:52:15 CEST] chat: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","hash-object","-t","blob","-w","--stdin"]
+ok
+add .gnucash/stylesheets-2.0 (checksum...) [2013-06-22 19:52:15 CEST] chat: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","hash-object","-t","blob","-w","--stdin"]
+ok
+add gnucash/gnucash.gnucash.20130622195212.log (checksum...) [2013-06-22 19:52:15 CEST] chat: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","hash-object","-t","blob","-w","--stdin"]
+[2013-06-22 19:52:15 CEST] Committer: committing 7 changes
+[2013-06-22 19:52:15 CEST] Committer: Committing changes to git
+[2013-06-22 19:52:15 CEST] feed: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","update-index","-z","--index-info"]
+To ssh://florz@192.168.1.3/home/florz/annex-sync/
+ 7d4c30d..1954c7f master -> synced/master
+[2013-06-22 19:52:15 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","commit","--allow-empty-message","--no-edit","-m","","--quiet","--no-verify"]
+[2013-06-22 19:52:15 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","symbolic-ref","HEAD"]
+[2013-06-22 19:52:15 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","refs/heads/master"]
+[2013-06-22 19:52:15 CEST] Merger: merging refs/remotes/home192.168.1.3/synced/master into refs/heads/master
+[2013-06-22 19:52:15 CEST] Committer: queued Upload UUID "dc591dd7-2446-45c6-84dc-55bdf79e7512" gnucash/gnucash.gnucash.20130622195212.log Nothing : new file created
+[2013-06-22 19:52:15 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","symbolic-ref","HEAD"]
+[2013-06-22 19:52:15 CEST] Committer: queued Upload UUID "84bab1ab-238f-4602-953a-a297aab6da44" gnucash/gnucash.gnucash.20130622195212.log Nothing : new file created
+[2013-06-22 19:52:15 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","refs/heads/master"]
+[2013-06-22 19:52:15 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--hash","refs/heads/master"]
+[2013-06-22 19:52:15 CEST] call: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync/.git/annex/merge/","merge","--no-edit","refs/remotes/home192.168.1.3/synced/master"]
+Already up-to-date.
+[2013-06-22 19:52:15 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--hash","refs/heads/master"]
+[2013-06-22 19:52:15 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","diff-tree","-z","--raw","--no-renames","-l0","-r","e1cb6c3b8bc0c851e6dab51271a4cde04815c50c","e1cb6c3b8bc0c851e6dab51271a4cde04815c50c"]
+To ssh://florz@192.168.2.2/home/florz/annex-sync/
+ 7d4c30d..e1cb6c3 master -> synced/master
+[2013-06-22 19:52:16 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","symbolic-ref","HEAD"]
+[2013-06-22 19:52:16 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","refs/heads/master"]
+[2013-06-22 19:52:16 CEST] Merger: merging refs/remotes/server192.168.2.2/synced/master into refs/heads/master
+[2013-06-22 19:52:16 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","symbolic-ref","HEAD"]
+[2013-06-22 19:52:16 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","refs/heads/master"]
+[2013-06-22 19:52:16 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--hash","refs/heads/master"]
+[2013-06-22 19:52:16 CEST] call: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync/.git/annex/merge/","merge","--no-edit","refs/remotes/server192.168.2.2/synced/master"]
+Already up-to-date.
+[2013-06-22 19:52:16 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--hash","refs/heads/master"]
+[2013-06-22 19:52:16 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","diff-tree","-z","--raw","--no-renames","-l0","-r","e1cb6c3b8bc0c851e6dab51271a4cde04815c50c","e1cb6c3b8bc0c851e6dab51271a4cde04815c50c"]
+
+gnucash.gnucash.20130622195200.log
+
+ 778 100% 0.00kB/s 0:00:00
+ 778 100% 0.00kB/s 0:00:00 (xfer#1, to-check=0/1)
+[2013-06-22 19:52:17 CEST] TransferWatcher: transfer starting: Upload UUID "dc591dd7-2446-45c6-84dc-55bdf79e7512" gnucash/gnucash.gnucash.20130622195200.log Just 778
+
+sent 876 bytes received 31 bytes 201.56 bytes/sec
+total size is 778 speedup is 0.86
+[2013-06-22 19:52:17 CEST] TransferWatcher: transfer finishing: Transfer {transferDirection = Upload, transferUUID = UUID "dc591dd7-2446-45c6-84dc-55bdf79e7512", transferKey = Key {keyName = "8b8aa5c2cfe4466c6b897f7987246021468033301a696e2db0070386f7d0f3fd.log", keyBackendName = "SHA256E", keySize = Just 778, keyMtime = Nothing}}
+[2013-06-22 19:52:17 CEST] Transferrer: Uploaded gnucash.g..95200.log
+[2013-06-22 19:52:17 CEST] Transferrer: Transferring: Upload UUID "84bab1ab-238f-4602-953a-a297aab6da44" gnucash/gnucash.gnucash.20130622195212.log Nothing
+[2013-06-22 19:52:17 CEST] TransferWatcher: transfer starting: Upload UUID "84bab1ab-238f-4602-953a-a297aab6da44" gnucash/gnucash.gnucash.20130622195212.log Nothing
+[2013-06-22 19:52:18 CEST] Pusher: Syncing with server192.168.2.2, home192.168.1.3
+[2013-06-22 19:52:18 CEST] chat: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","hash-object","-w","--stdin-paths"]
+[2013-06-22 19:52:18 CEST] feed: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","update-index","-z","--index-info"]
+[2013-06-22 19:52:18 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--hash","refs/heads/git-annex"]
+[2013-06-22 19:52:18 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","write-tree"]
+[2013-06-22 19:52:18 CEST] chat: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","commit-tree","f2463d30e73fec86e14c9df4bcae5e568398a503","-p","refs/heads/git-annex"]
+[2013-06-22 19:52:18 CEST] call: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","update-ref","refs/heads/git-annex","776258f91d4245ffe13117a771dc8c7723867c1a"]
+[2013-06-22 19:52:18 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","symbolic-ref","HEAD"]
+[2013-06-22 19:52:18 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","refs/heads/master"]
+[2013-06-22 19:52:18 CEST] Pusher: pushing to [Remote { name ="server192.168.2.2" },Remote { name ="home192.168.1.3" }]
+[2013-06-22 19:52:18 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","git-annex"]
+[2013-06-22 19:52:18 CEST] call: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","branch","-f","synced/master"]
+[2013-06-22 19:52:18 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--hash","refs/heads/git-annex"]
+[2013-06-22 19:52:18 CEST] call: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","push","server192.168.2.2","git-annex:synced/git-annex","master:synced/master"]
+[2013-06-22 19:52:18 CEST] call: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","push","home192.168.1.3","git-annex:synced/git-annex","master:synced/master"]
+[2013-06-22 19:52:18 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..776258f91d4245ffe13117a771dc8c7723867c1a","--oneline","-n1"]
+[2013-06-22 19:52:18 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..e7d4504abea59b0b59659908ba771783acc6cd55","--oneline","-n1"]
+[2013-06-22 19:52:18 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..69a00fc4a2079b3a87725cc0e3e8b8a1e3a9ae20","--oneline","-n1"]
+[2013-06-22 19:52:18 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..3c87a082e3b5340597dc59b9d5963b191f24a936","--oneline","-n1"]
+[2013-06-22 19:52:18 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","ls-tree","-z","--","refs/heads/git-annex","uuid.log","remote.log","trust.log","group.log","preferred-content.log"]
+[2013-06-22 19:52:18 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","symbolic-ref","HEAD"]
+[2013-06-22 19:52:18 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","refs/heads/master"]
+[2013-06-22 19:52:18 CEST] Merger: merging refs/heads/synced/master into refs/heads/master
+[2013-06-22 19:52:18 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","symbolic-ref","HEAD"]
+[2013-06-22 19:52:18 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","refs/heads/master"]
+[2013-06-22 19:52:18 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--hash","refs/heads/master"]
+[2013-06-22 19:52:18 CEST] call: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync/.git/annex/merge/","merge","--no-edit","refs/heads/synced/master"]
+Already up-to-date.
+[2013-06-22 19:52:18 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--hash","refs/heads/master"]
+[2013-06-22 19:52:18 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","diff-tree","-z","--raw","--no-renames","-l0","-r","e1cb6c3b8bc0c851e6dab51271a4cde04815c50c","e1cb6c3b8bc0c851e6dab51271a4cde04815c50c"]
+
+gnucash.gnucash.20130622195212.log
+
+ 411 100% 0.00kB/s 0:00:00
+ 411 100% 0.00kB/s 0:00:00 (xfer#1, to-check=0/1)
+[2013-06-22 19:52:20 CEST] TransferWatcher: transfer starting: Upload UUID "84bab1ab-238f-4602-953a-a297aab6da44" gnucash/gnucash.gnucash.20130622195212.log Just 411
+
+sent 509 bytes received 31 bytes 154.29 bytes/sec
+total size is 411 speedup is 0.76
+[2013-06-22 19:52:20 CEST] Transferrer: Uploaded gnucash.g..95212.log
+[2013-06-22 19:52:20 CEST] TransferWatcher: transfer finishing: Transfer {transferDirection = Upload, transferUUID = UUID "84bab1ab-238f-4602-953a-a297aab6da44", transferKey = Key {keyName = "36e8842e91f7577d12992724c8f52586e9ea7cb0234312dc5544ea4dc6f6c39a.log", keyBackendName = "SHA256E", keySize = Just 411, keyMtime = Nothing}}
+[2013-06-22 19:52:20 CEST] Transferrer: Transferring: Upload UUID "dc591dd7-2446-45c6-84dc-55bdf79e7512" gnucash/gnucash.gnucash.20130622195212.log Nothing
+[2013-06-22 19:52:20 CEST] TransferWatcher: transfer starting: Upload UUID "dc591dd7-2446-45c6-84dc-55bdf79e7512" gnucash/gnucash.gnucash.20130622195212.log Nothing
+To ssh://florz@192.168.1.3/home/florz/annex-sync/
+ e7d4504..776258f git-annex -> synced/git-annex
+[2013-06-22 19:52:21 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","git-annex"]
+[2013-06-22 19:52:21 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--hash","refs/heads/git-annex"]
+[2013-06-22 19:52:21 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..776258f91d4245ffe13117a771dc8c7723867c1a","--oneline","-n1"]
+[2013-06-22 19:52:21 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..e7d4504abea59b0b59659908ba771783acc6cd55","--oneline","-n1"]
+[2013-06-22 19:52:21 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..69a00fc4a2079b3a87725cc0e3e8b8a1e3a9ae20","--oneline","-n1"]
+[2013-06-22 19:52:21 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..3c87a082e3b5340597dc59b9d5963b191f24a936","--oneline","-n1"]
+[2013-06-22 19:52:21 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","symbolic-ref","HEAD"]
+[2013-06-22 19:52:21 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","refs/heads/master"]
+[2013-06-22 19:52:21 CEST] Merger: merging refs/remotes/home192.168.1.3/synced/master into refs/heads/master
+[2013-06-22 19:52:21 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","symbolic-ref","HEAD"]
+[2013-06-22 19:52:21 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","refs/heads/master"]
+[2013-06-22 19:52:21 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--hash","refs/heads/master"]
+[2013-06-22 19:52:21 CEST] call: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync/.git/annex/merge/","merge","--no-edit","refs/remotes/home192.168.1.3/synced/master"]
+Already up-to-date.
+[2013-06-22 19:52:21 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--hash","refs/heads/master"]
+[2013-06-22 19:52:21 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","diff-tree","-z","--raw","--no-renames","-l0","-r","e1cb6c3b8bc0c851e6dab51271a4cde04815c50c","e1cb6c3b8bc0c851e6dab51271a4cde04815c50c"]
+
+gnucash.gnucash.20130622195212.log
+
+ 411 100% 0.00kB/s 0:00:00
+ 411 100% 0.00kB/s 0:00:00 (xfer#1, to-check=0/1)
+[2013-06-22 19:52:21 CEST] TransferWatcher: transfer starting: Upload UUID "dc591dd7-2446-45c6-84dc-55bdf79e7512" gnucash/gnucash.gnucash.20130622195212.log Just 411
+
+sent 509 bytes received 31 bytes 360.00 bytes/sec
+total size is 411 speedup is 0.76
+[2013-06-22 19:52:22 CEST] Transferrer: Uploaded gnucash.g..95212.log
+[2013-06-22 19:52:22 CEST] TransferWatcher: transfer finishing: Transfer {transferDirection = Upload, transferUUID = UUID "dc591dd7-2446-45c6-84dc-55bdf79e7512", transferKey = Key {keyName = "36e8842e91f7577d12992724c8f52586e9ea7cb0234312dc5544ea4dc6f6c39a.log", keyBackendName = "SHA256E", keySize = Just 411, keyMtime = Nothing}}
+[2013-06-22 19:52:22 CEST] Transferrer: Transferring: Upload UUID "84bab1ab-238f-4602-953a-a297aab6da44" gnucash/gnucash.gnucash.20130622195200.log Nothing
+[2013-06-22 19:52:22 CEST] TransferWatcher: transfer starting: Upload UUID "84bab1ab-238f-4602-953a-a297aab6da44" gnucash/gnucash.gnucash.20130622195200.log Nothing
+To ssh://florz@192.168.2.2/home/florz/annex-sync/
+ e7d4504..776258f git-annex -> synced/git-annex
+[2013-06-22 19:52:22 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","git-annex"]
+[2013-06-22 19:52:22 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--hash","refs/heads/git-annex"]
+[2013-06-22 19:52:22 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..776258f91d4245ffe13117a771dc8c7723867c1a","--oneline","-n1"]
+[2013-06-22 19:52:22 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..e7d4504abea59b0b59659908ba771783acc6cd55","--oneline","-n1"]
+[2013-06-22 19:52:22 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..69a00fc4a2079b3a87725cc0e3e8b8a1e3a9ae20","--oneline","-n1"]
+[2013-06-22 19:52:22 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..3c87a082e3b5340597dc59b9d5963b191f24a936","--oneline","-n1"]
+git-annex-shell: key is already present in annex
+rsync: connection unexpectedly closed (0 bytes received so far) [sender]
+rsync error: error in rsync protocol data stream (code 12) at io.c(605) [sender=3.0.9]
+[2013-06-22 19:52:22 CEST] TransferWatcher: transfer finishing: Transfer {transferDirection = Upload, transferUUID = UUID "84bab1ab-238f-4602-953a-a297aab6da44", transferKey = Key {keyName = "8b8aa5c2cfe4466c6b897f7987246021468033301a696e2db0070386f7d0f3fd.log", keyBackendName = "SHA256E", keySize = Just 778, keyMtime = Nothing}}
+git-annex-shell: key is already present in annex
+rsync: connection unexpectedly closed (0 bytes received so far) [sender]
+rsync error: error in rsync protocol data stream (code 12) at io.c(605) [sender=3.0.9]
+[2013-06-22 19:52:24 CEST] Pusher: Syncing with server192.168.2.2, home192.168.1.3
+[2013-06-22 19:52:24 CEST] chat: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","hash-object","-w","--stdin-paths"]
+[2013-06-22 19:52:24 CEST] feed: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","update-index","-z","--index-info"]
+[2013-06-22 19:52:24 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--hash","refs/heads/git-annex"]
+[2013-06-22 19:52:24 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","write-tree"]
+[2013-06-22 19:52:24 CEST] chat: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","commit-tree","1641422d48162f533f80693486d7c5a1208b9fcf","-p","refs/heads/git-annex"]
+[2013-06-22 19:52:24 CEST] call: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","update-ref","refs/heads/git-annex","48cfe2eb07d63d4a59c237994eb07896c92ef1c4"]
+[2013-06-22 19:52:24 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","symbolic-ref","HEAD"]
+[2013-06-22 19:52:24 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","refs/heads/master"]
+[2013-06-22 19:52:24 CEST] Pusher: pushing to [Remote { name ="server192.168.2.2" },Remote { name ="home192.168.1.3" }]
+[2013-06-22 19:52:24 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","git-annex"]
+[2013-06-22 19:52:24 CEST] call: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","branch","-f","synced/master"]
+[2013-06-22 19:52:24 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--hash","refs/heads/git-annex"]
+[2013-06-22 19:52:24 CEST] call: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","push","server192.168.2.2","git-annex:synced/git-annex","master:synced/master"]
+[2013-06-22 19:52:24 CEST] call: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","push","home192.168.1.3","git-annex:synced/git-annex","master:synced/master"]
+[2013-06-22 19:52:24 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..48cfe2eb07d63d4a59c237994eb07896c92ef1c4","--oneline","-n1"]
+[2013-06-22 19:52:24 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..e7d4504abea59b0b59659908ba771783acc6cd55","--oneline","-n1"]
+[2013-06-22 19:52:24 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..69a00fc4a2079b3a87725cc0e3e8b8a1e3a9ae20","--oneline","-n1"]
+[2013-06-22 19:52:24 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..776258f91d4245ffe13117a771dc8c7723867c1a","--oneline","-n1"]
+[2013-06-22 19:52:24 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..3c87a082e3b5340597dc59b9d5963b191f24a936","--oneline","-n1"]
+[2013-06-22 19:52:25 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","git-annex"]
+[2013-06-22 19:52:25 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--hash","refs/heads/git-annex"]
+[2013-06-22 19:52:25 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..48cfe2eb07d63d4a59c237994eb07896c92ef1c4","--oneline","-n1"]
+[2013-06-22 19:52:25 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..df87e3bef80902abc6d48ce0fbfe3432c790cd21","--oneline","-n1"]
+[2013-06-22 19:52:25 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..69a00fc4a2079b3a87725cc0e3e8b8a1e3a9ae20","--oneline","-n1"]
+[2013-06-22 19:52:25 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..776258f91d4245ffe13117a771dc8c7723867c1a","--oneline","-n1"]
+[2013-06-22 19:52:25 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..3c87a082e3b5340597dc59b9d5963b191f24a936","--oneline","-n1"]
+[2013-06-22 19:52:25 CEST] feed: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","update-index","-z","--index-info"]
+[2013-06-22 19:52:25 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","diff-index","--raw","-z","-r","--no-renames","-l0","--cached","df87e3bef80902abc6d48ce0fbfe3432c790cd21"]
+[2013-06-22 19:52:25 CEST] chat: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","hash-object","-t","blob","-w","--stdin"]
+[2013-06-22 19:52:25 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","df87e3bef80902abc6d48ce0fbfe3432c790cd21..refs/heads/git-annex","--oneline","-n1"]
+[2013-06-22 19:52:25 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","write-tree"]
+[2013-06-22 19:52:25 CEST] chat: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","commit-tree","5bf44cd143b2c35a44e609e083af23093eb02028","-p","refs/heads/git-annex","-p","df87e3bef80902abc6d48ce0fbfe3432c790cd21"]
+[2013-06-22 19:52:25 CEST] call: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","update-ref","refs/heads/git-annex","4cd264f192611f5a0d76e54d31329921a650f896"]
+[2013-06-22 19:52:25 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","git-annex"]
+[2013-06-22 19:52:25 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--hash","refs/heads/git-annex"]
+[2013-06-22 19:52:25 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..4cd264f192611f5a0d76e54d31329921a650f896","--oneline","-n1"]
+[2013-06-22 19:52:25 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..df87e3bef80902abc6d48ce0fbfe3432c790cd21","--oneline","-n1"]
+[2013-06-22 19:52:25 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..69a00fc4a2079b3a87725cc0e3e8b8a1e3a9ae20","--oneline","-n1"]
+[2013-06-22 19:52:25 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..776258f91d4245ffe13117a771dc8c7723867c1a","--oneline","-n1"]
+[2013-06-22 19:52:25 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..3c87a082e3b5340597dc59b9d5963b191f24a936","--oneline","-n1"]
+To ssh://florz@192.168.1.3/home/florz/annex-sync/
+ df87e3b..4cd264f git-annex -> synced/git-annex
+[2013-06-22 19:52:26 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","git-annex"]
+[2013-06-22 19:52:26 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--hash","refs/heads/git-annex"]
+[2013-06-22 19:52:27 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..4cd264f192611f5a0d76e54d31329921a650f896","--oneline","-n1"]
+[2013-06-22 19:52:27 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..df87e3bef80902abc6d48ce0fbfe3432c790cd21","--oneline","-n1"]
+[2013-06-22 19:52:27 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..69a00fc4a2079b3a87725cc0e3e8b8a1e3a9ae20","--oneline","-n1"]
+[2013-06-22 19:52:27 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..776258f91d4245ffe13117a771dc8c7723867c1a","--oneline","-n1"]
+[2013-06-22 19:52:27 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..3c87a082e3b5340597dc59b9d5963b191f24a936","--oneline","-n1"]
+To ssh://florz@192.168.2.2/home/florz/annex-sync/
+ 776258f..4cd264f git-annex -> synced/git-annex
+[2013-06-22 19:52:28 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","git-annex"]
+[2013-06-22 19:52:28 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--hash","refs/heads/git-annex"]
+[2013-06-22 19:52:28 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..4cd264f192611f5a0d76e54d31329921a650f896","--oneline","-n1"]
+[2013-06-22 19:52:28 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..df87e3bef80902abc6d48ce0fbfe3432c790cd21","--oneline","-n1"]
+[2013-06-22 19:52:28 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..69a00fc4a2079b3a87725cc0e3e8b8a1e3a9ae20","--oneline","-n1"]
+[2013-06-22 19:52:28 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..3c87a082e3b5340597dc59b9d5963b191f24a936","--oneline","-n1"]
+[2013-06-22 19:53:18 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","ls-tree","-z","--","refs/heads/git-annex","uuid.log","remote.log","trust.log","group.log","preferred-content.log"]
+[2013-06-22 19:54:27 CEST] Watcher: changed direct gnucash/gnucash.gnucash
+[2013-06-22 19:54:27 CEST] read: lsof ["-F0can","+d","/home/florz/annex-sync/.git/annex/tmp/"]
+[2013-06-22 19:54:27 CEST] Committer: Adding gnucash.gnucash
+ok
+(Recording state in git...)
+
+
+(Recording state in git...)
+
+
+(Recording state in git...)
+(merging synced/git-annex into git-annex...)
+(Recording state in git...)
+add gnucash/gnucash.gnucash (checksum...) [2013-06-22 19:54:27 CEST] read: sha256sum ["/home/florz/annex-sync/.git/annex/tmp/gnucash25536.gnucash"]
+[2013-06-22 19:54:27 CEST] chat: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","hash-object","-t","blob","-w","--stdin"]
+[2013-06-22 19:54:27 CEST] Committer: committing 1 changes
+[2013-06-22 19:54:27 CEST] Committer: Committing changes to git
+[2013-06-22 19:54:27 CEST] feed: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","update-index","-z","--index-info"]
+[2013-06-22 19:54:27 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","commit","--allow-empty-message","--no-edit","-m","","--quiet","--no-verify"]
+[2013-06-22 19:54:27 CEST] Committer: queued Upload UUID "dc591dd7-2446-45c6-84dc-55bdf79e7512" gnucash/gnucash.gnucash Nothing : new file created
+[2013-06-22 19:54:27 CEST] Pusher: Syncing with server192.168.2.2, home192.168.1.3
+[2013-06-22 19:54:27 CEST] Transferrer: Transferring: Upload UUID "dc591dd7-2446-45c6-84dc-55bdf79e7512" gnucash/gnucash.gnucash Nothing
+[2013-06-22 19:54:27 CEST] Committer: queued Upload UUID "84bab1ab-238f-4602-953a-a297aab6da44" gnucash/gnucash.gnucash Nothing : new file created
+[2013-06-22 19:54:27 CEST] chat: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","hash-object","-w","--stdin-paths"]
+[2013-06-22 19:54:27 CEST] feed: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","update-index","-z","--index-info"]
+[2013-06-22 19:54:27 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--hash","refs/heads/git-annex"]
+[2013-06-22 19:54:27 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","write-tree"]
+[2013-06-22 19:54:27 CEST] chat: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","commit-tree","4c81716cf1a0e0df472ffb43770ac8a27ca45420","-p","refs/heads/git-annex"]
+[2013-06-22 19:54:27 CEST] call: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","update-ref","refs/heads/git-annex","e9e2f951a5c1c645447ccc565bc3def9caeff93c"]
+[2013-06-22 19:54:27 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","symbolic-ref","HEAD"]
+[2013-06-22 19:54:27 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","refs/heads/master"]
+[2013-06-22 19:54:27 CEST] Pusher: pushing to [Remote { name ="server192.168.2.2" },Remote { name ="home192.168.1.3" }]
+[2013-06-22 19:54:27 CEST] TransferWatcher: transfer starting: Upload UUID "dc591dd7-2446-45c6-84dc-55bdf79e7512" gnucash/gnucash.gnucash Nothing
+[2013-06-22 19:54:27 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","git-annex"]
+[2013-06-22 19:54:27 CEST] call: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","branch","-f","synced/master"]
+[2013-06-22 19:54:27 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--hash","refs/heads/git-annex"]
+[2013-06-22 19:54:27 CEST] call: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","push","server192.168.2.2","git-annex:synced/git-annex","master:synced/master"]
+[2013-06-22 19:54:27 CEST] call: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","push","home192.168.1.3","git-annex:synced/git-annex","master:synced/master"]
+[2013-06-22 19:54:27 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..e9e2f951a5c1c645447ccc565bc3def9caeff93c","--oneline","-n1"]
+[2013-06-22 19:54:27 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..df87e3bef80902abc6d48ce0fbfe3432c790cd21","--oneline","-n1"]
+[2013-06-22 19:54:27 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..69a00fc4a2079b3a87725cc0e3e8b8a1e3a9ae20","--oneline","-n1"]
+[2013-06-22 19:54:27 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..4cd264f192611f5a0d76e54d31329921a650f896","--oneline","-n1"]
+[2013-06-22 19:54:27 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..3c87a082e3b5340597dc59b9d5963b191f24a936","--oneline","-n1"]
+[2013-06-22 19:54:27 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","ls-tree","-z","--","refs/heads/git-annex","uuid.log","remote.log","trust.log","group.log","preferred-content.log"]
+[2013-06-22 19:54:27 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","symbolic-ref","HEAD"]
+[2013-06-22 19:54:27 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","refs/heads/master"]
+[2013-06-22 19:54:27 CEST] Merger: merging refs/heads/synced/master into refs/heads/master
+[2013-06-22 19:54:27 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","symbolic-ref","HEAD"]
+[2013-06-22 19:54:27 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","refs/heads/master"]
+[2013-06-22 19:54:27 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--hash","refs/heads/master"]
+[2013-06-22 19:54:27 CEST] call: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync/.git/annex/merge/","merge","--no-edit","refs/heads/synced/master"]
+Already up-to-date.
+[2013-06-22 19:54:27 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--hash","refs/heads/master"]
+[2013-06-22 19:54:27 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","diff-tree","-z","--raw","--no-renames","-l0","-r","e41ffae310ed2a50058b2f963decde4f9bc10a14","e41ffae310ed2a50058b2f963decde4f9bc10a14"]
+
+
+
+gnucash.gnucash
+
+ 32768 28% 0.00kB/s 0:00:00 [2
+ 114039 100% 15.50MB/s 0:00:00 (xfer#1, to-check=0/1)
+013-06-22 19:54:28 CEST] TransferWatcher: transfer starting: Upload UUID "dc591dd7-2446-45c6-84dc-55bdf79e7512" gnucash/gnucash.gnucash Just 32768
+[2013-06-22 19:54:28 CEST] TransferWatcher: transfer starting: Upload UUID "dc591dd7-2446-45c6-84dc-55bdf79e7512" gnucash/gnucash.gnucash Just 114039
+To ssh://florz@192.168.1.3/home/florz/annex-sync/
+ 4cd264f..e9e2f95 git-annex -> synced/git-annex
+ e1cb6c3..e41ffae master -> synced/master
+[2013-06-22 19:54:33 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","git-annex"]
+[2013-06-22 19:54:33 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--hash","refs/heads/git-annex"]
+[2013-06-22 19:54:33 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..e9e2f951a5c1c645447ccc565bc3def9caeff93c","--oneline","-n1"]
+[2013-06-22 19:54:33 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..df87e3bef80902abc6d48ce0fbfe3432c790cd21","--oneline","-n1"]
+[2013-06-22 19:54:33 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..69a00fc4a2079b3a87725cc0e3e8b8a1e3a9ae20","--oneline","-n1"]
+[2013-06-22 19:54:33 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..4cd264f192611f5a0d76e54d31329921a650f896","--oneline","-n1"]
+[2013-06-22 19:54:33 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..3c87a082e3b5340597dc59b9d5963b191f24a936","--oneline","-n1"]
+[2013-06-22 19:54:33 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","symbolic-ref","HEAD"]
+[2013-06-22 19:54:33 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","refs/heads/master"]
+[2013-06-22 19:54:33 CEST] Merger: merging refs/remotes/home192.168.1.3/synced/master into refs/heads/master
+[2013-06-22 19:54:33 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","symbolic-ref","HEAD"]
+[2013-06-22 19:54:33 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","refs/heads/master"]
+[2013-06-22 19:54:33 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--hash","refs/heads/master"]
+[2013-06-22 19:54:33 CEST] call: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync/.git/annex/merge/","merge","--no-edit","refs/remotes/home192.168.1.3/synced/master"]
+Already up-to-date.
+[2013-06-22 19:54:33 CEST] read: git ["--git-dir=/home/florz/ann
+sent 114130 bytes received 31 bytes 20756.55 bytes/sec
+total size is 114039 espeedup is 1.00
+x-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--hash","refs/heads/master"]
+[2013-06-22 19:54:33 CEST] Transferrer: Uploaded gnucash.gnucash
+[2013-06-22 19:54:33 CEST] TransferWatcher: transfer finishing: Transfer {transferDirection = Upload, transferUUID = UUID "dc591dd7-2446-45c6-84dc-55bdf79e7512", transferKey = Key {keyName = "91ec950e4004863219ea33f1398ea4308e0969267c207272e046858ede8bf9d9", keyBackendName = "SHA256E", keySize = Just 114039, keyMtime = Nothing}}
+[2013-06-22 19:54:33 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","diff-tree","-z","--raw","--no-renames","-l0","-r","e41ffae310ed2a50058b2f963decde4f9bc10a14","e41ffae310ed2a50058b2f963decde4f9bc10a14"]
+[2013-06-22 19:54:33 CEST] Transferrer: Transferring: Upload UUID "84bab1ab-238f-4602-953a-a297aab6da44" gnucash/gnucash.gnucash Nothing
+[2013-06-22 19:54:33 CEST] TransferWatcher: transfer starting: Upload UUID "84bab1ab-238f-4602-953a-a297aab6da44" gnucash/gnucash.gnucash Nothing
+
+gnucash.gnucash
+
+ 32768 28% 0.00kB/s 0:00:00
+ 114039 100% 19.38MB/s 0:00:00 (xfer#1, to-check=0/1)
+[2013-06-22 19:54:33 CEST] TransferWatcher: transfer starting: Upload UUID "84bab1ab-238f-4602-953a-a297aab6da44" gnucash/gnucash.gnucash Just 32768
+[2013-06-22 19:54:33 CEST] TransferWatcher: transfer starting: Upload UUID "84bab1ab-238f-4602-953a-a297aab6da44" gnucash/gnucash.gnucash Just 114039
+To ssh://florz@192.168.2.2/home/florz/annex-sync/
+ 4cd264f..e9e2f95 git-annex -> synced/git-annex
+ e1cb6c3..e41ffae master -> synced/master
+[2013-06-22 19:54:34 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","git-annex"]
+[2013-06-22 19:54:34 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--hash","refs/heads/git-annex"]
+[2013-06-22 19:54:34 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..e9e2f951a5c1c645447ccc565bc3def9caeff93c","--oneline","-n1"]
+[2013-06-22 19:54:34 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..df87e3bef80902abc6d48ce0fbfe3432c790cd21","--oneline","-n1"]
+[2013-06-22 19:54:34 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..69a00fc4a2079b3a87725cc0e3e8b8a1e3a9ae20","--oneline","-n1"]
+[2013-06-22 19:54:34 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..3c87a082e3b5340597dc59b9d5963b191f24a936","--oneline","-n1"]
+[2013-06-22 19:54:34 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","symbolic-ref","HEAD"]
+[2013-06-22 19:54:34 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","refs/heads/master"]
+[2013-06-22 19:54:34 CEST] Merger: merging refs/remotes/server192.168.2.2/synced/master into refs/heads/master
+[2013-06-22 19:54:34 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","symbolic-ref","HEAD"]
+[2013-06-22 19:54:34 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","refs/heads/master"]
+[2013-06-22 19:54:34 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--hash","refs/heads/master"]
+[2013-06-22 19:54:34 CEST] call: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync/.git/annex/merge/","merge","--no-edit","refs/remotes/server192.168.2.2/synced/master"]
+Already up-to-date.
+[2013-06-22 19:54:34 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--hash","refs/heads/master"]
+[2013-06-22 19:54:34 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","diff-tree","-z","--raw","--no-renames","-l0","-r","e41ffae310ed2a50058b2f963decde4f9bc10a14","e41ffae310ed2a50058b2f963decde4f9bc10a14"]
+
+sent 114130 bytes received 31 bytes 45664.40 bytes/sec
+total size is 114039 speedup is 1.00
+[2013-06-22 19:54:35 CEST] Transferrer: Uploaded gnucash.gnucash
+[2013-06-22 19:54:35 CEST] TransferWatcher: transfer finishing: Transfer {transferDirection = Upload, transferUUID = UUID "84bab1ab-238f-4602-953a-a297aab6da44", transferKey = Key {keyName = "91ec950e4004863219ea33f1398ea4308e0969267c207272e046858ede8bf9d9", keyBackendName = "SHA256E", keySize = Just 114039, keyMtime = Nothing}}
+[2013-06-22 19:54:36 CEST] Pusher: Syncing with server192.168.2.2, home192.168.1.3
+[2013-06-22 19:54:36 CEST] chat: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","hash-object","-w","--stdin-paths"]
+[2013-06-22 19:54:36 CEST] feed: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","update-index","-z","--index-info"]
+[2013-06-22 19:54:36 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--hash","refs/heads/git-annex"]
+[2013-06-22 19:54:36 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","write-tree"]
+[2013-06-22 19:54:36 CEST] chat: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","commit-tree","fb43dcef4baa4b928faec6622a4f7889125c6c0a","-p","refs/heads/git-annex"]
+[2013-06-22 19:54:36 CEST] call: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","update-ref","refs/heads/git-annex","b74b3402e31d7394815733811b9668b00cc51aa9"]
+[2013-06-22 19:54:36 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","symbolic-ref","HEAD"]
+[2013-06-22 19:54:36 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","refs/heads/master"]
+[2013-06-22 19:54:36 CEST] Pusher: pushing to [Remote { name ="server192.168.2.2" },Remote { name ="home192.168.1.3" }]
+[2013-06-22 19:54:36 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","git-annex"]
+[2013-06-22 19:54:36 CEST] call: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","branch","-f","synced/master"]
+[2013-06-22 19:54:36 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--hash","refs/heads/git-annex"]
+[2013-06-22 19:54:36 CEST] call: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","push","server192.168.2.2","git-annex:synced/git-annex","master:synced/master"]
+[2013-06-22 19:54:36 CEST] call: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","push","home192.168.1.3","git-annex:synced/git-annex","master:synced/master"]
+[2013-06-22 19:54:36 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..b74b3402e31d7394815733811b9668b00cc51aa9","--oneline","-n1"]
+[2013-06-22 19:54:36 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..df87e3bef80902abc6d48ce0fbfe3432c790cd21","--oneline","-n1"]
+[2013-06-22 19:54:36 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..69a00fc4a2079b3a87725cc0e3e8b8a1e3a9ae20","--oneline","-n1"]
+[2013-06-22 19:54:36 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..e9e2f951a5c1c645447ccc565bc3def9caeff93c","--oneline","-n1"]
+[2013-06-22 19:54:36 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..3c87a082e3b5340597dc59b9d5963b191f24a936","--oneline","-n1"]
+[2013-06-22 19:54:39 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","git-annex"]
+[2013-06-22 19:54:39 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--hash","refs/heads/git-annex"]
+[2013-06-22 19:54:39 CEST] read: git ["--gitTo ssh://florz@192.168.1.3/home/florz/annex-sync/
+- ! [rejected] dgit-annex -> synced/git-annexi (r=/non-fast-forwardh)o
+me/florz/aerror: failed to push some refs to 'ssh://florz@192.168.1.3/home/florz/annex-sync/'
+nTo prevent you from losing history, non-fast-forward updates were rejected
+Merge the remote changes (e.g. 'git pull') before pushing again. See the
+'Note about fast-forwards' section of 'git push --help' for details.
+nex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..b74b3402e31d7394815733811b9668b00cc51aa9","--oneline","-n1"]
+[2013-06-22 19:54:39 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..89e2137442dfdb06facbaba3079873d90c7af281","--oneline","-n1"]
+[2013-06-22 19:54:39 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..69a00fc4a2079b3a87725cc0e3e8b8a1e3a9ae20","--oneline","-n1"]
+[2013-06-22 19:54:39 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..e9e2f951a5c1c645447ccc565bc3def9caeff93c","--oneline","-n1"]
+[2013-06-22 19:54:39 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..3c87a082e3b5340597dc59b9d5963b191f24a936","--oneline","-n1"]
+[2013-06-22 19:54:39 CEST] feed: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","update-index","-z","--index-info"]
+[2013-06-22 19:54:39 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","diff-index","--raw","-z","-r","--no-renames","-l0","--cached","89e2137442dfdb06facbaba3079873d90c7af281"]
+[2013-06-22 19:54:39 CEST] chat: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","hash-object","-t","blob","-w","--stdin"]
+[2013-06-22 19:54:39 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","89e2137442dfdb06facbaba3079873d90c7af281..refs/heads/git-annex","--oneline","-n1"]
+[2013-06-22 19:54:39 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","write-tree"]
+[2013-06-22 19:54:39 CEST] chat: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","commit-tree","f175a05b82160942363f46bf1af3e7af1660dfa1","-p","refs/heads/git-annex","-p","89e2137442dfdb06facbaba3079873d90c7af281"]
+[2013-06-22 19:54:39 CEST] call: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","update-ref","refs/heads/git-annex","fabac4b203dce9e812b4637f7e95375b15a3f739"]
+[2013-06-22 19:54:39 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","git-annex"]
+[2013-06-22 19:54:39 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--hash","refs/heads/git-annex"]
+[2013-06-22 19:54:39 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..fabac4b203dce9e812b4637f7e95375b15a3f739","--oneline","-n1"]
+[2013-06-22 19:54:39 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..89e2137442dfdb06facbaba3079873d90c7af281","--oneline","-n1"]
+[2013-06-22 19:54:39 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..69a00fc4a2079b3a87725cc0e3e8b8a1e3a9ae20","--oneline","-n1"]
+[2013-06-22 19:54:39 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..e9e2f951a5c1c645447ccc565bc3def9caeff93c","--oneline","-n1"]
+[2013-06-22 19:54:39 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..3c87a082e3b5340597dc59b9d5963b191f24a936","--oneline","-n1"]
+To ssh://florz@192.168.2.2/home/florz/annex-sync/
+ e9e2f95..fabac4b git-annex -> synced/git-annex
+[2013-06-22 19:54:40 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","git-annex"]
+[2013-06-22 19:54:40 CEST] Pusher: trying manual pull to resolve failed pushes
+[2013-06-22 19:54:40 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--hash","refs/heads/git-annex"]
+[2013-06-22 19:54:40 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..fabac4b203dce9e812b4637f7e95375b15a3f739","--oneline","-n1"]
+[2013-06-22 19:54:40 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..89e2137442dfdb06facbaba3079873d90c7af281","--oneline","-n1"]
+[2013-06-22 19:54:40 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..69a00fc4a2079b3a87725cc0e3e8b8a1e3a9ae20","--oneline","-n1"]
+[2013-06-22 19:54:40 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..e9e2f951a5c1c645447ccc565bc3def9caeff93c","--oneline","-n1"]
+[2013-06-22 19:54:40 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..3c87a082e3b5340597dc59b9d5963b191f24a936","--oneline","-n1"]
+[2013-06-22 19:54:40 CEST] call: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","fetch","home192.168.1.3"]
+From ssh://192.168.1.3/home/florz/annex-sync
+ e9e2f95..89e2137 synced/git-annex -> home192.168.1.3/synced/git-annex
+[2013-06-22 19:54:42 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","git-annex"]
+[2013-06-22 19:54:42 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--hash","refs/heads/git-annex"]
+[2013-06-22 19:54:42 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..fabac4b203dce9e812b4637f7e95375b15a3f739","--oneline","-n1"]
+[2013-06-22 19:54:42 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..89e2137442dfdb06facbaba3079873d90c7af281","--oneline","-n1"]
+[2013-06-22 19:54:42 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..69a00fc4a2079b3a87725cc0e3e8b8a1e3a9ae20","--oneline","-n1"]
+[2013-06-22 19:54:43 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..3c87a082e3b5340597dc59b9d5963b191f24a936","--oneline","-n1"]
+[2013-06-22 19:54:43 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","git-annex"]
+[2013-06-22 19:54:43 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--hash","refs/heads/git-annex"]
+[2013-06-22 19:54:43 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..fabac4b203dce9e812b4637f7e95375b15a3f739","--oneline","-n1"]
+[2013-06-22 19:54:43 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..89e2137442dfdb06facbaba3079873d90c7af281","--oneline","-n1"]
+[2013-06-22 19:54:43 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..69a00fc4a2079b3a87725cc0e3e8b8a1e3a9ae20","--oneline","-n1"]
+[2013-06-22 19:54:43 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..3c87a082e3b5340597dc59b9d5963b191f24a936","--oneline","-n1"]
+[2013-06-22 19:54:43 CEST] call: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--verify","-q","refs/remotes/home192.168.1.3/master"]
+[2013-06-22 19:54:43 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/master..refs/remotes/home192.168.1.3/master","--oneline","-n1"]
+[2013-06-22 19:54:43 CEST] call: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--verify","-q","refs/remotes/home192.168.1.3/synced/master"]
+[2013-06-22 19:54:43 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/synced/master..refs/remotes/home192.168.1.3/synced/master","--oneline","-n1"]
+[2013-06-22 19:54:43 CEST] Pusher: pushing to [Remote { name ="home192.168.1.3" }]
+[2013-06-22 19:54:43 CEST] call: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","branch","-f","synced/master"]
+[2013-06-22 19:54:43 CEST] call: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","push","home192.168.1.3","git-annex:synced/git-annex","master:synced/master"]
+[2013-06-22 19:54:45 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","git-annex"]
+[2013-06-22 19:54:45 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--hash","refs/heads/git-annex"]
+[2013-06-22 19:54:45 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..fabac4b203dce9e812b4637f7e95375b15a3f739","--oneline","-n1"]
+[2013-06-22 19:54:45 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..69a00fc4a2079b3a87725cc0e3e8b8a1e3a9ae20","--oneline","-n1"]
+[2013-06-22 19:54:45 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..89e2137442dfdb06facbaba3079873d90c7af281","--oneline","-n1"]
+[2013-06-22 19:54:45 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..3c87a082e3b5340597dc59b9d5963b191f24a936","--oneline","-n1"]
+Everything up-to-date
+[2013-06-22 19:54:46 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","git-annex"]
+[2013-06-22 19:54:46 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","show-ref","--hash","refs/heads/git-annex"]
+[2013-06-22 19:54:47 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..fabac4b203dce9e812b4637f7e95375b15a3f739","--oneline","-n1"]
+[2013-06-22 19:54:47 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..69a00fc4a2079b3a87725cc0e3e8b8a1e3a9ae20","--oneline","-n1"]
+[2013-06-22 19:54:47 CEST] read: git ["--git-dir=/home/florz/annex-sync/.git","--work-tree=/home/florz/annex-sync","log","refs/heads/git-annex..3c87a082e3b5340597dc59b9d5963b191f24a936","--oneline","-n1"]
+"""]]
+
+[[!tag /design/assistant]]
+[[!meta title="hard link to open file which is then deleted"]]
+
+> I have fixed this bug. [[done]] --[[Joey]]
diff --git a/doc/bugs/Problems_with_syncing_gnucash/comment_1_ca195af3ba4a286eb5ab687634192fa4._comment b/doc/bugs/Problems_with_syncing_gnucash/comment_1_ca195af3ba4a286eb5ab687634192fa4._comment
new file mode 100644
index 000000000..481f65d5b
--- /dev/null
+++ b/doc/bugs/Problems_with_syncing_gnucash/comment_1_ca195af3ba4a286eb5ab687634192fa4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.193"
+ subject="comment 1"
+ date="2013-06-25T17:30:05Z"
+ content="""
+First of all, are you sure that git-annex is even the right tool for this job? gnucash files tend to be pretty small, and are easy to check into git directly. What happens if two machines make conflicting edits, and the git-annex assistant automatically resolves the merge conflict by moving files around and making .variant copies of gnucash log files?
+"""]]
diff --git a/doc/bugs/Problems_with_syncing_gnucash/comment_2_754fb430381ad88e6248ecb902b32118._comment b/doc/bugs/Problems_with_syncing_gnucash/comment_2_754fb430381ad88e6248ecb902b32118._comment
new file mode 100644
index 000000000..ff81b4d98
--- /dev/null
+++ b/doc/bugs/Problems_with_syncing_gnucash/comment_2_754fb430381ad88e6248ecb902b32118._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.193"
+ subject="comment 2"
+ date="2013-06-25T17:49:08Z"
+ content="""
+I was able to reproduce this with gnucash, and came up with a small test case:
+
+[[!format perl \"\"\"
+my $foo=\"foo\";
+open(OUT, \">$foo.new\");
+link(\"$foo.new\", \"$foo\");
+unlink(\"$foo.new\");
+close OUT;
+\"\"\"]]
+
+This defeats the watcher, which sees the file be opened for write, and then deleted before it's closed. To fix this it would need to correlate the hard link with the original file, to know that when the original file is closed, the hard link can now be safely added to the annex.
+
+The daily sanity checker will find and eventually add these files, or the assistant will see them the next time it's started.
+"""]]
diff --git a/doc/bugs/Problems_with_syncing_gnucash/comment_4_25881998c6f149c70b1358f37b7c66ba._comment b/doc/bugs/Problems_with_syncing_gnucash/comment_4_25881998c6f149c70b1358f37b7c66ba._comment
new file mode 100644
index 000000000..509ef4a5c
--- /dev/null
+++ b/doc/bugs/Problems_with_syncing_gnucash/comment_4_25881998c6f149c70b1358f37b7c66ba._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl99Gxq3NPNvwZHp3PDufaknQH4rZb_KKY"
+ nickname="Florian"
+ subject="comment 4"
+ date="2013-06-27T01:52:03Z"
+ content="""
+Thanks for the quick fix! I'm always amazed how fasts you find fixes for such problems. This qualified you for a flattr subscription (I know it's not much but if more people did this...). I didn't test the fix but I'm nearly sure it will work with the next release :-)
+
+I know that my expectations in this project are a little bit high and I see how much work it was to get where we are now. Once again thank you for the excellent work done so far. I don't fear to synchronize important data with git-annex. I even use git-annex to backup and synchronize the member database for our club (wannabe hackerspace). As soon as cabal downloads an compiles your latest release my last problems will be gone (the locking problem).
+
+I know about the remaining problems and thus use git-annex with care. Of course you didn't imagine all use cases in the beginning and maybe some are impossible to realise but as I already said, we are on a very good way! :-)
+
+My vision is to get rid of any centralized service (even the XMPP part -> maybe you could add add a global polling/watchdog/keepalive option for SSH only setups (in case one node died/wasn't started) ). At the moment this already works as long as git-annex runs on all machines. I already synced several thousands of private photos just by using SSH so thanks again! :-)
+
+An other vision (I know I'm not speaking for the majority and this is still utopic...) is to decentralize my home directory and to enable collaboration (e.g. on our club database (of course not simultaneously)). At my university AFS is used to store home and project directories. This filesystem also suffers from race conditions and file locking is only as good as each application implemented it but we still use it because it is sufficient. I am sure that git-annex is not far from this state and it could even do more (-> lock files as long as they are opened on one machine).
+
+One last thing I can imagine for now is to improve the synchronization speed. At least for me git-annex seems quite slow in syncing smaller files over high latency connections. Do you close ssh connections after each file and do you use something like the the fuzzy option in rsync (for moved/renamed logfiles/backups (once again one of these little problem with the management tool for our club))?
+
+I hope you don't get me wrong for this. I never before wrote any bug reports so take this as an other success of your project. ;-) I really hope it will get to the point I described above and I can assure you that it is already way better than what I tried to use before. Keep up the good work!
+"""]]
diff --git a/doc/bugs/Provide_64-bit_standalone_build.mdwn b/doc/bugs/Provide_64-bit_standalone_build.mdwn
new file mode 100644
index 000000000..7f24e0055
--- /dev/null
+++ b/doc/bugs/Provide_64-bit_standalone_build.mdwn
@@ -0,0 +1,6 @@
+The 32-bit standalone build appears to require two libraries (lib32-libyaml and lib32-gsasl) that are not available on Arch Linux. [See the comments on the AUR package](https://aur.archlinux.org/packages/git-annex-bin/). I'd appreciate it if you could bring back the 64-bit build.
+
+> [[done]], based on <https://aur.archlinux.org/packages/git-annex-bin/>
+> they are managing with what I am providing. Also, Arch Linux has a
+> proper build of git-annex from source, so I'm not going to worry about
+> git-annex-bin, the rationalle for which I don't even understand. --[[Joey]]
diff --git a/doc/bugs/Provide_64-bit_standalone_build/comment_1_1850bb3eb464f1d3c122cfeb4ccaf265._comment b/doc/bugs/Provide_64-bit_standalone_build/comment_1_1850bb3eb464f1d3c122cfeb4ccaf265._comment
new file mode 100644
index 000000000..76e8d0d5c
--- /dev/null
+++ b/doc/bugs/Provide_64-bit_standalone_build/comment_1_1850bb3eb464f1d3c122cfeb4ccaf265._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-03-03T21:32:39Z"
+ content="""
+Thanks for the heads up.
+
+As far as I can see, the necessary libraries are included in the standalone build. So it should work when used as intended via `runshell`.
+
+But that's not what the AUR is doing. It's binary editing (!!) the git-annex binary to use different library sonames, and taking the git-annex binary and dropping it unprotected into a system it was not built for to fend for itself.
+That strikes me as a technique that is unlikely to continue working, and one that I cannot commit to support.
+
+I don't want to cause you Arch people unnecessary work, but building a 64 bit standalone build every time I release git-annex is unnecessary work on my part, as long as the 32 bit one works everywhere when used as designed. If someone has to do this 64 bit build, why not you? This would also avoid any further breakage, since you could build it against the actual library sonames it's going to be used with on Arch.
+"""]]
diff --git a/doc/bugs/Proxy_support.mdwn b/doc/bugs/Proxy_support.mdwn
new file mode 100644
index 000000000..d3ab3c601
--- /dev/null
+++ b/doc/bugs/Proxy_support.mdwn
@@ -0,0 +1,18 @@
+What steps will reproduce the problem?
+
+Adding a e.g box.com repository from behind a http proxy via webapp.
+
+What is the expected output? What do you see instead?
+
+Connection should be made. But there is an error message:
+
+"Internal Server Error
+connect: does not exist (Connection refused): user error"
+
+What version of git-annex are you using? On what operating system?
+
+3.20121127 on Archlinux
+
+Please provide any additional information below.
+
+I don't use networkmanager if proxy information is obtained from it. There should be a fallback to environment variables.
diff --git a/doc/bugs/Remote_repo_and_set_operation_with_find.mdwn b/doc/bugs/Remote_repo_and_set_operation_with_find.mdwn
new file mode 100644
index 000000000..3e1acd4a8
--- /dev/null
+++ b/doc/bugs/Remote_repo_and_set_operation_with_find.mdwn
@@ -0,0 +1,6 @@
+Currently, git annex find lists files that are present in the current repository, possibly restricted to a subdirectory. But it does not easily seem possible to get this information about a remote repository.
+
+I would find it useful if this command understood flags that makes it tell me what is present somewhere else (maybe "--on remote") and combinations of the flags ("--on remote1 --and --not-on remote2" or "--on disk1 --or --on disk2").
+
+> Almost. You're looking for `--in remote`, which was added 2 months ago.
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/Remote_repositories_have_to_be_setup_encrypted.mdwn b/doc/bugs/Remote_repositories_have_to_be_setup_encrypted.mdwn
new file mode 100644
index 000000000..f281fb1b9
--- /dev/null
+++ b/doc/bugs/Remote_repositories_have_to_be_setup_encrypted.mdwn
@@ -0,0 +1,27 @@
+What steps will reproduce the problem?
+
+Create a new remote repository in the webapp. Get to the final phase of the setup where it asks you if you want to encrypt it, yet no other option is given to continue.
+
+What is the expected output? What do you see instead?
+
+At least two options:
+
+1. Use an encrypted rsync repository on the server (the existing one)
+2. Use an unencrypted rsync repository on the server
+
+What version of git-annex are you using? On what operating system?
+
+ $ ./git-annex version
+ git-annex version: 3.20130102
+
+ $ uname -a
+ Linux wintermute 3.2.0-35-generic #55-Ubuntu SMP Wed Dec 5 17:45:18 UTC 2012 i686 i686 i386 GNU/Linux
+
+ $ lsb_release -a
+ Distributor ID: Ubuntu
+ Description: Ubuntu 12.04.1 LTS
+ Release: 12.04
+ Codename: precise
+
+[[!meta title="webapp does not allow disabling encryption on rsync special remotes"]]
+[[!tag /design/assistant]]
diff --git a/doc/bugs/Remote_repositories_have_to_be_setup_encrypted/comment_1_95f73315657bc35a8d3ff9b4ba207af0._comment b/doc/bugs/Remote_repositories_have_to_be_setup_encrypted/comment_1_95f73315657bc35a8d3ff9b4ba207af0._comment
new file mode 100644
index 000000000..f54b4626b
--- /dev/null
+++ b/doc/bugs/Remote_repositories_have_to_be_setup_encrypted/comment_1_95f73315657bc35a8d3ff9b4ba207af0._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.211"
+ subject="comment 1"
+ date="2013-01-03T18:02:21Z"
+ content="""
+Specifically, this affects only rsync special remotes. All the other ones have a check box that allows enabling encryption or not. I didn't get around to adding that for rsync due to some complications in the code. Of course, you can use `git annex initremote` at the command line to set up non-encrypted rsync remotes.
+"""]]
diff --git a/doc/bugs/Remotes_only_start_showing_changes_after_both_sides_have_written_to_the_repository.mdwn b/doc/bugs/Remotes_only_start_showing_changes_after_both_sides_have_written_to_the_repository.mdwn
new file mode 100644
index 000000000..a051a8170
--- /dev/null
+++ b/doc/bugs/Remotes_only_start_showing_changes_after_both_sides_have_written_to_the_repository.mdwn
@@ -0,0 +1,70 @@
+### Please describe the problem.
+
+I've setup two (actually more) direct mode repositories pointing at each other with ssh keys allowing them to talk to each other. I run the assistant in both repositories. Once I add a file to one repository I can see in the assistant log that it's been sent to the other side but it doesn't show up. Once I add a file to the other repository both repositories get both files.
+
+### What steps will reproduce the problem?
+
+In the first host:
+[[!format sh """
+$ ls -l
+total 0
+$ date | tee fromhostA
+Fri May 31 19:25:12 WEST 2013
+"""]]
+
+And then in the second host
+
+[[!format sh """
+$ ls
+$ date | tee fromhostB
+Fri May 31 19:25:27 WEST 2013
+$ ls
+fromhostB
+$ ls # After a little while
+fromhostA fromhostB
+"""]]
+
+Back at hostA
+
+[[!format sh """
+$ ls -l
+total 8
+-rw-r--r-- 1 pedrocr pedrocr 30 May 31 19:25 fromhostA
+-rw-r--r-- 1 pedrocr pedrocr 30 May 31 19:25 fromhostB
+"""]]
+
+I looked at the logs for hostA and it seemed like it was pushing the changes right away. In hostB this is the moment where fromhostB gets added:
+
+[[!format sh """
+[2013-05-31 19:22:04 WEST] Pusher: Syncing with zeus, wintermute, ulisses
+[2013-05-31 19:25:27 WEST] Committer: Adding fromhostB
+
+(merging zeus/git-annex into git-annex...)
+(Recording state in git...)
+(merging wintermute/git-annex into git-annex...)
+(Recording state in git...)
+(merging ulisses/git-annex into git-annex...)
+(Recording state in git...)
+"""]]
+
+It seems to be that merging in the remotes only gets done when there's an added file and that's why fromhostA didn't show up until fromhostB was there. I don't think this is the correct behavior. I want to be able to setup a new repository with other repositories as remotes and have it automatically pull in all the contents without having to create content itself.
+
+### What version of git-annex are you using? On what operating system?
+
+[[!format sh """
+$ git annex version
+git-annex version: 4.20130516.1
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP
+local repository version: 4
+default repository version: 3
+supported repository versions: 3 4
+upgrade supported from repository versions: 0 1 2
+$ lsb_release -a
+No LSB modules are available.
+Distributor ID: Ubuntu
+Description: Ubuntu 12.04.2 LTS
+Release: 12.04
+Codename: precise
+"""]]
+
+> [[done]]; see comment --[[Joey]]
diff --git a/doc/bugs/Remotes_only_start_showing_changes_after_both_sides_have_written_to_the_repository/comment_1_92211091daf9827a4ec7e5b5a6769d59._comment b/doc/bugs/Remotes_only_start_showing_changes_after_both_sides_have_written_to_the_repository/comment_1_92211091daf9827a4ec7e5b5a6769d59._comment
new file mode 100644
index 000000000..0daa25b7f
--- /dev/null
+++ b/doc/bugs/Remotes_only_start_showing_changes_after_both_sides_have_written_to_the_repository/comment_1_92211091daf9827a4ec7e5b5a6769d59._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-05-31T21:12:52Z"
+ content="""
+How are you creating the repositories? git cannot merge origin/master into master when master does not exist yet. The assistant, when it creates a repository, makes an empty commit, to create the master branch, which should avoid this problem.
+"""]]
diff --git a/doc/bugs/Remotes_only_start_showing_changes_after_both_sides_have_written_to_the_repository/comment_2_f0fa97a9eba1c624f6f8720ba8a160b7._comment b/doc/bugs/Remotes_only_start_showing_changes_after_both_sides_have_written_to_the_repository/comment_2_f0fa97a9eba1c624f6f8720ba8a160b7._comment
new file mode 100644
index 000000000..cee6bce0d
--- /dev/null
+++ b/doc/bugs/Remotes_only_start_showing_changes_after_both_sides_have_written_to_the_repository/comment_2_f0fa97a9eba1c624f6f8720ba8a160b7._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkx5V3MTbzCXS3J7Mn9FEq8M9bPPYMkAHY"
+ nickname="Pedro"
+ subject="comment 2"
+ date="2013-05-31T21:48:43Z"
+ content="""
+I'm doing everything by hand. I just do \"git init\" and \"git annex init\" in an empty directory, and then do \"git remote add ...\" to add the ssh remotes to each other. After that I launch \"git annex assistant\".
+"""]]
diff --git a/doc/bugs/Remotes_only_start_showing_changes_after_both_sides_have_written_to_the_repository/comment_3_e3d677ea4170c07cd31efe6dc85fa5f3._comment b/doc/bugs/Remotes_only_start_showing_changes_after_both_sides_have_written_to_the_repository/comment_3_e3d677ea4170c07cd31efe6dc85fa5f3._comment
new file mode 100644
index 000000000..1e563d409
--- /dev/null
+++ b/doc/bugs/Remotes_only_start_showing_changes_after_both_sides_have_written_to_the_repository/comment_3_e3d677ea4170c07cd31efe6dc85fa5f3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-06-11T14:23:31Z"
+ content="""
+This then explains your problem. If you're going to set things up by hand you need to do the same setup that the assistant does of making an initial commit, which can be empty.
+"""]]
diff --git a/doc/bugs/Renamed_special_remote_cannot_be_reactivated_by_the_webapp.mdwn b/doc/bugs/Renamed_special_remote_cannot_be_reactivated_by_the_webapp.mdwn
new file mode 100644
index 000000000..ccf6ef1ca
--- /dev/null
+++ b/doc/bugs/Renamed_special_remote_cannot_be_reactivated_by_the_webapp.mdwn
@@ -0,0 +1,30 @@
+Setup:
+
+* fresh install of Debian Wheezy with git-annex 4.20130227 pulled in from unstable
+* clone existing repository and activate assistant
+* repository has encrypted rsync remote originally setup with the name `metaarray`
+* this remote was renamed to `ma` a long time ago, using the webapp
+* had to perform this rename on each client
+
+Steps:
+
+* attempt to reactivate special remote using webapp repositories page, on reinstalled machine
+
+Expected:
+
+* special remote starts working
+* renaming special remotes ought to survive clones
+
+Actual:
+
+* firstly, special remote activation page has blank hostname box and the hostname of the machine is in the username box
+* form gives error "cannot change encryption type of existing remote"
+
+Workaround:
+
+* execute `git annex initremote metaarray`
+* rename `metaarray` to `ma` again using the webapp
+
+Perhaps the renaming of the remote not surviving clones is unavoidable, but the webapp should be able to cope with the situation. Thanks.
+
+[[!tag /design/assistant]]
diff --git a/doc/bugs/Repository_deletion_error.mdwn b/doc/bugs/Repository_deletion_error.mdwn
new file mode 100644
index 000000000..33142d8dd
--- /dev/null
+++ b/doc/bugs/Repository_deletion_error.mdwn
@@ -0,0 +1,46 @@
+**What steps will reproduce the problem?**
+
+On the dashboard, click settings > Delete on the repo you want to remove.
+Wait for the dropping to finish.
+Start final deletion when the message "The repository "repo" has been emptied, and can now be removed." pops up.
+
+**What is the expected output? What do you see instead?**
+
+The repository should be deleted, but I only see "Internal Server Error: git [Param "remote",Param "remove",Param "repo"] failed".
+
+**What version of git-annex are you using? On what operating system?**
+
+Standalone build, git-annex version 4.20130417-g4bb97d5
+
+**Please provide any additional information below.**
+
+The log shows:
+
+ [2013-04-22 22:17:22 CEST] TransferScanner: The repository "repo" has been emptied, and can now be removed.
+ error: Unknown subcommand: remove
+ usage: git remote [-v | --verbose]
+ or: git remote add [-t <branch>] [-m <master>] [-f] [--mirror=<fetch|push>] <name> <url>
+ or: git remote rename <old> <new>
+ or: git remote rm <name>
+ or: git remote set-head <name> (-a | -d | <branch>)
+ or: git remote [-v | --verbose] show [-n] <name>
+ or: git remote prune [-n | --dry-run] <name>
+ or: git remote [-v | --verbose] update [-p | --prune] [(<group> | <remote>)...]
+ or: git remote set-branches [--add] <name> <branch>...
+ or: git remote set-url <name> <newurl> [<oldurl>]
+ or: git remote set-url --add <name> <newurl>
+ or: git remote set-url --delete <name> <url>
+
+ -v, --verbose be verbose; must be placed before a subcommand
+
+
+
+> Seems that `git remote remove` is new as of git 1.8.0 or so.
+> Older gits only support `git remote rm`. Which newer gits
+> support as well. but it seems to be in the process
+> of being deprecated so I'd rather not use it.
+>
+> So, I've made the version of git it's
+> built for determine which subcommand it uses. [[done]] --[[Joey]]
+>
+> (You can run `git remote rm repo` by hand to clean up from this BTW.)
diff --git a/doc/bugs/Repository_deletion_error/comment_1_31673d0300986b6098d1af2cc4b180c6._comment b/doc/bugs/Repository_deletion_error/comment_1_31673d0300986b6098d1af2cc4b180c6._comment
new file mode 100644
index 000000000..1ed723d12
--- /dev/null
+++ b/doc/bugs/Repository_deletion_error/comment_1_31673d0300986b6098d1af2cc4b180c6._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-04-22T20:43:26Z"
+ content="""
+It's running `git remote remove` to remove it. Your git appears not to support this, but mine (1.8.2) does.
+
+What version of git do you have installed?
+"""]]
diff --git a/doc/bugs/Resource_exhausted.mdwn b/doc/bugs/Resource_exhausted.mdwn
new file mode 100644
index 000000000..3f125b08a
--- /dev/null
+++ b/doc/bugs/Resource_exhausted.mdwn
@@ -0,0 +1,45 @@
+What steps will reproduce the problem?
+My annex dir has 23459 files and uses 749MB disk space.
+Just create a repository put this dir inside, and git-annex will crash.
+
+What is the expected output? What do you see instead?
+I expect git-annex handles large number of files, and does not watch every single file of it.
+
+What version of git-annex are you using? On what operating system?
+I'm using git-annex linux build, version 2013.04.17.
+
+Please provide any additional information below.
+
+ [2013-04-17 23:52:35 CEST] Transferrer: Downloaded pappas_hu..di_44.jpg
+ git-annex: runInteractiveProcess: pipe: Too many open files
+ Committer crashed: lsof: createProcess: resource exhausted (Too many open files)
+ [2013-04-17 23:53:52 CEST] Committer: warning Committer crashed: lsof: createProcess: resource exhausted (Too many open files)
+ git-annex: runInteractiveProcess: pipe: Too many open files
+ git: createProcess: resource exhausted (Too many open files)
+ DaemonStatus crashed: /home/user/Desktop/down/annex_test/.git/annex/daemon.status.tmp21215: openFile: resource exhausted (Too many open files)
+ [2013-04-17 23:57:24 CEST] DaemonStatus: warning DaemonStatus crashed: /home/user/Desktop/down/annex_test/.git/annex/daemon.status.tmp21215: openFile: resource exhausted (Too many open files)
+ git-annex: runInteractiveProcess: pipe: Too many open files
+ git: createProcess: resource exhausted (Too many open files)
+ git-annex: runInteractiveProcess: pipe: Too many open files
+ NetWatcherFallback crashed: git: createProcess: resource exhausted (Too many open files)
+ [2013-04-18 00:27:17 CEST] NetWatcherFallback: warning NetWatcherFallback crashed: git: createProcess: resource exhausted (Too many open files)
+ git-annex: runInteractiveProcess: pipe: Too many open files
+ git-annex: git: createProcess: resource exhausted (Too many open files)
+ git-annex: accept: resource exhausted (Too many open files)
+
+Instead of raising system's limit (which is a neverending story), can we make git-annex only watch a directory and not every file of it?
+
+Or could the user specify some directory which he knows it is rarely change, to not be watched only check it once a day?
+
+The best would be if git annex could automatically adapt itself.
+Ie. it watches eg. 200 files, and if some of it does not change for three days, then it drops from the watching basket, and those who changed (noticed while sanity checked) it adds to the basket.
+
+I don't really want to raise the ulimit, because my ultimate goal is to have git-annex on multiple raspberry pi with external harddrive (one at my home, one at my mom's home, one at my friends home, etc, etc). And raspberry is fairly low on resource.
+
+I'm interested in your thoughts.
+
+Best,
+ Laszlo
+
+[[!tag /design/assistant]]
+[[!meta title="assistant can try to add too many files at once in batch add mode"]]
diff --git a/doc/bugs/Resource_exhausted/comment_10_bccf9528ffe963154c92ce49762e7ea6._comment b/doc/bugs/Resource_exhausted/comment_10_bccf9528ffe963154c92ce49762e7ea6._comment
new file mode 100644
index 000000000..da2a15ba2
--- /dev/null
+++ b/doc/bugs/Resource_exhausted/comment_10_bccf9528ffe963154c92ce49762e7ea6._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawln3ckqKx0x_xDZMYwa9Q1bn4I06oWjkog"
+ nickname="Michael"
+ subject="comment 10"
+ date="2013-08-26T18:33:40Z"
+ content="""
+@Joey: it was a \"pretty large\" transfer, several hundred gigabytes in perhaps ~100000 files. The copying was going to a GPG-encrypted directory remote.
+The error only happened once or twice so far. Point taken about find in /proc; I'll do that if it happens next time.
+
+"""]]
diff --git a/doc/bugs/Resource_exhausted/comment_1_a5ef7a62d4ed9365f9448520bb17e3b5._comment b/doc/bugs/Resource_exhausted/comment_1_a5ef7a62d4ed9365f9448520bb17e3b5._comment
new file mode 100644
index 000000000..9bd4b0779
--- /dev/null
+++ b/doc/bugs/Resource_exhausted/comment_1_a5ef7a62d4ed9365f9448520bb17e3b5._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="comment 1"
+ date="2013-04-18T06:20:13Z"
+ content="""
+Once resource exhausted git-annex has git [defunct] process too.
+
+"""]]
diff --git a/doc/bugs/Resource_exhausted/comment_2_cdba2015e603f3c21f3e1697dd6fafcd._comment b/doc/bugs/Resource_exhausted/comment_2_cdba2015e603f3c21f3e1697dd6fafcd._comment
new file mode 100644
index 000000000..fb0f4c16b
--- /dev/null
+++ b/doc/bugs/Resource_exhausted/comment_2_cdba2015e603f3c21f3e1697dd6fafcd._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-04-23T19:44:04Z"
+ content="""
+I have tried repeatedly to reproduce this problem, and I cannot.
+
+git-annex does *not* keep every file open. It tends to have less than 10 open file descriptors at any one time.
+
+I thought perhaps `lsof` opened every file, but it does not seem to, either.
+
+So far, I have no indication that the problem had to do with git-annex at all. If some other program on the system opened a great many files, it could cause this to happen to git-annex.
+
+You pasted a debug log that shows that the problem persisted for several minutes. So you should make it happen again, and in that time period, investigate what program has so many files open. You can do this with lsof, or, if lsof won't run, by looking in /proc/$pid/fd/
+
+Or, of course, give me enough information to reproduce the problem. \"I have 23459 files\" isn't much help..
+"""]]
diff --git a/doc/bugs/Resource_exhausted/comment_3_747d16d050fdcf69dd3d2bc5ca469a2e._comment b/doc/bugs/Resource_exhausted/comment_3_747d16d050fdcf69dd3d2bc5ca469a2e._comment
new file mode 100644
index 000000000..07badd83a
--- /dev/null
+++ b/doc/bugs/Resource_exhausted/comment_3_747d16d050fdcf69dd3d2bc5ca469a2e._comment
@@ -0,0 +1,39 @@
+[[!comment format=mdwn
+ username="http://adamspiers.myopenid.com/"
+ nickname="Adam"
+ subject="I just reproduced this"
+ date="2013-07-26T23:37:26Z"
+ content="""
+On openSUSE 12.3 with this version (which I'm sure is horribly old):
+
+ git-annex version: 4.20130314
+ local repository version: 3
+ default repository version: 3
+ supported repository versions: 3 4
+ upgrade supported from repository versions: 0 1 2
+ build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP DNS
+
+I ran 'git annex get' on a large repository, and got this:
+
+ [snipped]
+ git-annex: /home/adam/music/.git/annex/transfer/failed/download/9c930baf-6b25-4294-b1f9-a90ba9663fb7/SHA1-s7227476--49d203960b062ec00c0d1d7042c4b6aa6720b976: openFile: resource exhausted (Too many open files)
+ failed
+ git-annex: runInteractiveProcess: pipe: Too many open files
+
+ git-annex: git: runInteractiveProcess: resource exhausted (Too many open files)
+ failed
+ git-annex: get: 1207 failed
+
+Then I ran it again and saw that after every file retrieved, git-annex leaks another lockfile. lsof shows an ever increasing number of files like this:
+
+ [snipped]
+ git-annex 32498 adam 86rR REG 253,3 0 787353 /home/adam/music/.git/annex/ssh/adam@atlantic.lock
+ git-annex 32498 adam 87rR REG 253,3 0 787353 /home/adam/music/.git/annex/ssh/adam@atlantic.lock
+ git-annex 32498 adam 88rR REG 253,3 0 787353 /home/adam/music/.git/annex/ssh/adam@atlantic.lock
+ git-annex 32498 adam 89rR REG 253,3 0 787353 /home/adam/music/.git/annex/ssh/adam@atlantic.lock
+ git-annex 32498 adam 90rR REG 253,3 0 787353 /home/adam/music/.git/annex/ssh/adam@atlantic.lock
+ git-annex 32498 adam 91rR REG 253,3 0 787353 /home/adam/music/.git/annex/ssh/adam@atlantic.lock
+ git-annex 32498 adam 92rR REG 253,3 0 787353 /home/adam/music/.git/annex/ssh/adam@atlantic.lock
+ git-annex 32498 adam 93r FIFO 0,8 0t0 28752703 pipe
+ git-annex 32498 adam 94r FIFO 0,8 0t0 28765910 pipe
+"""]]
diff --git a/doc/bugs/Resource_exhausted/comment_4_1e9b74e60da57c3d5f08c1eb3801c1d2._comment b/doc/bugs/Resource_exhausted/comment_4_1e9b74e60da57c3d5f08c1eb3801c1d2._comment
new file mode 100644
index 000000000..eee206168
--- /dev/null
+++ b/doc/bugs/Resource_exhausted/comment_4_1e9b74e60da57c3d5f08c1eb3801c1d2._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.110"
+ subject="comment 4"
+ date="2013-07-28T00:23:08Z"
+ content="""
+Hmm, Adam your version is older than the bug reporter's version. OTOH, while there were several FD leak fixes after your version, none of them were to Annex.LockPool, which is what's used for the ssh lock files.
+
+I can't reproduce it with `git annex get` and the current release.. can you?
+"""]]
diff --git a/doc/bugs/Resource_exhausted/comment_5_f55d933bce77fd2185ebd0cc46fe57ec._comment b/doc/bugs/Resource_exhausted/comment_5_f55d933bce77fd2185ebd0cc46fe57ec._comment
new file mode 100644
index 000000000..19bcdb376
--- /dev/null
+++ b/doc/bugs/Resource_exhausted/comment_5_f55d933bce77fd2185ebd0cc46fe57ec._comment
@@ -0,0 +1,64 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawln3ckqKx0x_xDZMYwa9Q1bn4I06oWjkog"
+ nickname="Michael"
+ subject="I just reproduced this with the latest version"
+ date="2013-08-11T03:17:11Z"
+ content="""
+At some point during a large copy, there's an ever increasing number of pipes in /proc/git-annex-pid/fd
+As soon as it hits the limit (1023 in my case), copies start failing
+
+ etc
+ r-x------ 1 michael michael 64 Aug 10 20:14 851 -> pipe:[2250609]
+ l-wx------ 1 michael michael 64 Aug 10 20:14 852 -> pipe:[2251549]
+ lr-x------ 1 michael michael 64 Aug 10 20:14 853 -> pipe:[2251550]
+ l-wx------ 1 michael michael 64 Aug 10 20:14 854 -> pipe:[2250612]
+ lr-x------ 1 michael michael 64 Aug 10 20:14 855 -> pipe:[2250613]
+ l-wx------ 1 michael michael 64 Aug 10 20:14 856 -> pipe:[2246639]
+ lr-x------ 1 michael michael 64 Aug 10 20:14 857 -> pipe:[2246640]
+ l-wx------ 1 michael michael 64 Aug 10 20:14 858 -> pipe:[2246642]
+ lr-x------ 1 michael michael 64 Aug 10 20:14 859 -> pipe:[2246643]
+ l-wx------ 1 michael michael 64 Aug 10 20:13 86 -> pipe:[2241378]
+ l-wx------ 1 michael michael 64 Aug 10 20:14 860 -> pipe:[2246645]
+ lr-x------ 1 michael michael 64 Aug 10 20:14 861 -> pipe:[2246646]
+ l-wx------ 1 michael michael 64 Aug 10 20:14 862 -> pipe:[2246648]
+ lr-x------ 1 michael michael 64 Aug 10 20:14 863 -> pipe:[2246649]
+ l-wx------ 1 michael michael 64 Aug 10 20:14 864 -> pipe:[2246653]
+ lr-x------ 1 michael michael 64 Aug 10 20:14 865 -> pipe:[2246654]
+ lr-x------ 1 michael michael 64 Aug 10 20:14 866 -> pipe:[2249407]
+ l-wx------ 1 michael michael 64 Aug 10 20:14 867 -> pipe:[2251789]
+ l-wx------ 1 michael michael 64 Aug 10 20:14 868 -> pipe:[2250627]
+ lr-x------ 1 michael michael 64 Aug 10 20:14 869 -> pipe:[2250628]
+ lr-x------ 1 michael michael 64 Aug 10 20:13 87 -> pipe:[2241379]
+ l-wx------ 1 michael michael 64 Aug 10 20:14 870 -> pipe:[2251778]
+ lr-x------ 1 michael michael 64 Aug 10 20:14 871 -> pipe:[2251779]
+ l-wx------ 1 michael michael 64 Aug 10 20:14 872 -> pipe:[2251781]
+ lr-x------ 1 michael michael 64 Aug 10 20:14 873 -> pipe:[2251782]
+ l-wx------ 1 michael michael 64 Aug 10 20:14 874 -> pipe:[2250635]
+ lr-x------ 1 michael michael 64 Aug 10 20:14 875 -> pipe:[2250636]
+ l-wx------ 1 michael michael 64 Aug 10 20:14 876 -> pipe:[2251575]
+ lr-x------ 1 michael michael 64 Aug 10 20:14 877 -> pipe:[2251576]
+ l-wx------ 1 michael michael 64 Aug 10 20:14 878 -> pipe:[2251785]
+ lr-x------ 1 michael michael 64 Aug 10 20:14 879 -> pipe:[2251786]
+ l-wx------ 1 michael michael 64 Aug 10 20:13 88 -> pipe:[2247853]
+ l-wx------ 1 michael michael 64 Aug 10 20:14 880 -> pipe:[2249430]
+ lr-x------ 1 michael michael 64 Aug 10 20:14 881 -> pipe:[2249431]
+ l-wx------ 1 michael michael 64 Aug 10 20:14 882 -> pipe:[2251581]
+ lr-x------ 1 michael michael 64 Aug 10 20:14 883 -> pipe:[2251582]
+ l-wx------ 1 michael michael 64 Aug 10 20:14 884 -> pipe:[2250653]
+ lr-x------ 1 michael michael 64 Aug 10 20:14 885 -> pipe:[2250654]
+ lr-x------ 1 michael michael 64 Aug 10 20:14 886 -> pipe:[2251790]
+ l-wx------ 1 michael michael 64 Aug 10 20:14 887 -> pipe:[2250670]
+ l-wx------ 1 michael michael 64 Aug 10 20:14 888 -> pipe:[2250663]
+ lr-x------ 1 michael michael 64 Aug 10 20:14 889 -> pipe:[2250664]
+ lr-x------ 1 michael michael 64 Aug 10 20:13 89 -> pipe:[2247854]
+ l-wx------ 1 michael michael 64 Aug 10 20:14 890 -> pipe:[2250668]
+ lr-x------ 1 michael michael 64 Aug 10 20:14 891 -> pipe:[2250669]
+ lr-x------ 1 michael michael 64 Aug 10 20:14 892 -> pipe:[2250671]
+ l-wx------ 1 michael michael 64 Aug 10 20:14 894 -> pipe:[2251601]
+ lr-x------ 1 michael michael 64 Aug 10 20:14 895 -> pipe:[2251602]
+ lr-x------ 1 michael michael 64 Aug 10 20:13 9 -> pipe:[2241268]
+ lr-x------ 1 michael michael 64 Aug 10 20:13 90 -> pipe:[2242273]
+ l-wx------ 1 michael michael 64 Aug 10 20:13 91 -> pipe:[2245776]
+ etc
+
+"""]]
diff --git a/doc/bugs/Resource_exhausted/comment_6_26c98fca45b029a527f9684873db4be5._comment b/doc/bugs/Resource_exhausted/comment_6_26c98fca45b029a527f9684873db4be5._comment
new file mode 100644
index 000000000..b95b6cfa2
--- /dev/null
+++ b/doc/bugs/Resource_exhausted/comment_6_26c98fca45b029a527f9684873db4be5._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawln3ckqKx0x_xDZMYwa9Q1bn4I06oWjkog"
+ nickname="Michael"
+ subject="comment 6"
+ date="2013-08-11T03:20:37Z"
+ content="""
+with every
+
+ git annex
+ copy blah/blah/blah (to testremote...)
+ git-annex: runInteractiveProcess: pipe: Too many open files
+ failed
+
+The number of open fd's by git-annex increases by 1.
+
+4.20130802 built with cabal on Ubuntu 13.04
+
+"""]]
diff --git a/doc/bugs/Resource_exhausted/comment_7_8bab413b472f900e04977db2bc3951b6._comment b/doc/bugs/Resource_exhausted/comment_7_8bab413b472f900e04977db2bc3951b6._comment
new file mode 100644
index 000000000..1b050aa33
--- /dev/null
+++ b/doc/bugs/Resource_exhausted/comment_7_8bab413b472f900e04977db2bc3951b6._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawln3ckqKx0x_xDZMYwa9Q1bn4I06oWjkog"
+ nickname="Michael"
+ subject="comment 7"
+ date="2013-08-11T03:21:45Z"
+ content="""
+...increases in the failing case, that is. This doesn't happen all the time.
+"""]]
diff --git a/doc/bugs/Resource_exhausted/comment_8_e9bec0b80179b1229b6af0979a21c727._comment b/doc/bugs/Resource_exhausted/comment_8_e9bec0b80179b1229b6af0979a21c727._comment
new file mode 100644
index 000000000..2135211cd
--- /dev/null
+++ b/doc/bugs/Resource_exhausted/comment_8_e9bec0b80179b1229b6af0979a21c727._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawln3ckqKx0x_xDZMYwa9Q1bn4I06oWjkog"
+ nickname="Michael"
+ subject="comment 8"
+ date="2013-08-11T20:44:19Z"
+ content="""
+It also looks like the location log has got corrupted (files are actually present, but not recorded in the location log) somewhere along the lines as I was trying to get/drop to figure out what's going on.
+Explicitly dropping files then getting files fixes the location log issue.
+"""]]
diff --git a/doc/bugs/Resource_exhausted/comment_9_419e24e0b91f569294ece28c42daa246._comment b/doc/bugs/Resource_exhausted/comment_9_419e24e0b91f569294ece28c42daa246._comment
new file mode 100644
index 000000000..0e06f5af9
--- /dev/null
+++ b/doc/bugs/Resource_exhausted/comment_9_419e24e0b91f569294ece28c42daa246._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 9"
+ date="2013-08-24T19:10:21Z"
+ content="""
+@Michael how large a copy are you doing? And what kind of remote are you copying the files to?
+It would be helpful if you could be more specific about something I could do to reproduce the problem. Without a test case, I am unlikely to fix the bug. With a test case, I'd be surprised if it took long to fix it.
+
+If you have a process running that is experiencing the problem, you can also narrow it down a *lot* by looking at what these leaking pipe file descriptors are pipes to. For example, if you have:
+
+lr-x------ 1 michael michael 64 Aug 10 20:14 895 -> pipe:[2251602]
+
+You can run `find /proc/ -ls 2251602` and find the process at other end of the pipe, and look its pid up in ps to see what command it is.
+"""]]
diff --git a/doc/bugs/Resource_leak_somewhere_in_the___39__get__39___code.mdwn b/doc/bugs/Resource_leak_somewhere_in_the___39__get__39___code.mdwn
new file mode 100644
index 000000000..2746ade5c
--- /dev/null
+++ b/doc/bugs/Resource_leak_somewhere_in_the___39__get__39___code.mdwn
@@ -0,0 +1,24 @@
+What steps will reproduce the problem?
+
+I have an Annex with about 18k files in it. If I clone it and then run `git annex get .`, it gets a few thousand files and then starts reporting:
+
+ get 2004-2012/Originals/110414_0362.jpg (from titan...)
+ rsync: fork: Resource temporarily unavailable (35)
+ rsync error: error in IPC code (code 14) at pipe.c(63) [Receiver=3.0.9]
+
+I have to abort and re-run `git annex get .` several times to finally get all of the files.
+
+What is the expected output? What do you see instead?
+
+I didn't expect what I saw! I think there's a resource not being released in the `get` code.
+
+What version of git-annex are you using? On what operating system?
+
+master branch, d430fb1.
+
+Please provide any additional information below.
+
+OS X 10.8.2. The machine has tons of RAM and tons of process handles free. It's really not doing anything else but this git-annex at the time of my tests.
+
+> [[done]], this is a bug introduced in 3.20121009, and I've reverted the
+> buggy change. --[[Joey]]
diff --git a/doc/bugs/Resource_leak_somewhere_in_the___39__get__39___code/comment_1_66b21720cd1b2a4f66ef24252d3e6305._comment b/doc/bugs/Resource_leak_somewhere_in_the___39__get__39___code/comment_1_66b21720cd1b2a4f66ef24252d3e6305._comment
new file mode 100644
index 000000000..4bdc7943b
--- /dev/null
+++ b/doc/bugs/Resource_leak_somewhere_in_the___39__get__39___code/comment_1_66b21720cd1b2a4f66ef24252d3e6305._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 1"
+ date="2012-10-17T00:41:03Z"
+ content="""
+The resource in question appears to be processes. Do you get a lot of zombies or something?
+"""]]
diff --git a/doc/bugs/Resource_leak_somewhere_in_the___39__get__39___code/comment_2_18c9f55c5af1f4f690a7727df71ab561._comment b/doc/bugs/Resource_leak_somewhere_in_the___39__get__39___code/comment_2_18c9f55c5af1f4f690a7727df71ab561._comment
new file mode 100644
index 000000000..29214814b
--- /dev/null
+++ b/doc/bugs/Resource_leak_somewhere_in_the___39__get__39___code/comment_2_18c9f55c5af1f4f690a7727df71ab561._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 2"
+ date="2012-10-17T01:07:00Z"
+ content="""
+Urk. Seems I was making some recent changes lately to clean up zombies and I accidentually let them accumulate here. Fixed that.
+"""]]
diff --git a/doc/bugs/Rsync_encrypted_remote_asks_for_ssh_key_password_for_each_file.mdwn b/doc/bugs/Rsync_encrypted_remote_asks_for_ssh_key_password_for_each_file.mdwn
new file mode 100644
index 000000000..8239ae708
--- /dev/null
+++ b/doc/bugs/Rsync_encrypted_remote_asks_for_ssh_key_password_for_each_file.mdwn
@@ -0,0 +1,30 @@
+What steps will reproduce the problem?
+
+Add an encrypted rsync remote by it's 'Host' value in ~/.ssh/config.
+
+eg.:
+
+cat ~/.ssh/config | grep Host
+
+ Host serverNick
+
+git annex initremote rsyncRemote type=rsync rsyncurl=serverNick:/home/USER/Music encryption=USER@gmail.com
+
+git annex copy some\ artist --to serverNick
+
+
+What is the expected output? What do you see instead?
+
+I'd expect it to remember the key password like a normal ssh remote. Instead I get asked for the key password 3 times for each file in the folder.
+
+What version of git-annex are you using? On what operating system?
+
+3.20130216. Arch x64 (up to date as of 2013-03-07)
+
+Please provide any additional information below.
+
+
+[[!meta title="rsync special remote does not use ssh connection caching"]]
+
+> [[done]]; ssh connection caching is now done for these remotes.
+> --[[Joey]]
diff --git a/doc/bugs/Rsync_encrypted_remote_asks_for_ssh_key_password_for_each_file/comment_1_fd95e0bb61e80a72b4ac1304ef6c2e77._comment b/doc/bugs/Rsync_encrypted_remote_asks_for_ssh_key_password_for_each_file/comment_1_fd95e0bb61e80a72b4ac1304ef6c2e77._comment
new file mode 100644
index 000000000..5f55f356b
--- /dev/null
+++ b/doc/bugs/Rsync_encrypted_remote_asks_for_ssh_key_password_for_each_file/comment_1_fd95e0bb61e80a72b4ac1304ef6c2e77._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-03-08T18:59:27Z"
+ content="""
+git-annex does not use ssh connection caching for rsync special remotes, and so if you've configured ssh such that it needs to prompt for a password when making a connection, you'll be prompted twice for each file when using `git annex copy`: Once when it checks if the file is present, once when it rsyncs it. (One of those can be avoided by passing --fast)
+
+I don't see where a third password prompt can come from, other than gpg. But that would only prompt once per git-annex command, since git-annex caches the remote's encryption key.
+
+Of course, you can use a ssh-agent to avoid repeated ssh password prompts.
+
+----
+
+There's certainly a valid wishlist todo item that the rsync special remote should support ssh connection caching. It could be implemented using rsync -e. Although it would need to parse all valid rsync urls to determine which use ssh and which not, and what the user and hostname are.
+"""]]
diff --git a/doc/bugs/Rsync_remote_created_via_webapp_remains_empty.mdwn b/doc/bugs/Rsync_remote_created_via_webapp_remains_empty.mdwn
new file mode 100644
index 000000000..e961bd521
--- /dev/null
+++ b/doc/bugs/Rsync_remote_created_via_webapp_remains_empty.mdwn
@@ -0,0 +1,138 @@
+### Please describe the problem.
+The remote server, connected with rsync and with encryption enabled doesn't fill with files.
+
+### What steps will reproduce the problem?
+* Add remote server via webapp
+* Supply password when asked
+* both buttons turn green ('ready to add remote server')
+* Select encrypted rsync repository
+* When done, files will be queued for transfer, and the queue empties quickly. Afterwards, no files have actually been transferred, but a green message appears and says something like 'synced with xxx'.
+* Also, on the remote an empty directory (~/annex) is created.
+
+### What version of git-annex are you using? On what operating system?
+local: kubuntu 12.10, git-annex 4.20130621-g36258de
+remote: debian (linux 3.8.0-25), git-annex 4.20130621-g36258de
+Both are installed from tarball and PATH is set at the top of .bashrc.
+
+### Please provide any additional information below.
+
+[[!format sh """
+
+Here is what is put in the logs when the button is toggled from 'syncing disabled' to 'syncing enabled'.
+daemon.log:
+
+[2013-07-03 13:43:07 CEST] call: git ["--git-dir=/home/boris/annex/.git","--work-tree=/home/boris/annex","config","remote.mybox.annex-sync","true"]
+[2013-07-03 13:43:07 CEST] read: git ["config","--null","--list"]
+[2013-07-03 13:43:07 CEST] read: git ["config","--null","--list"]
+[2013-07-03 13:43:07 CEST] main: Syncing with mybox
+[2013-07-03 13:43:07 CEST] read: git ["--git-dir=/home/boris/annex/.git","--work-tree=/home/boris/annex","symbolic-ref","HEAD"]
+[2013-07-03 13:43:07 CEST] read: git ["--git-dir=/home/boris/annex/.git","--work-tree=/home/boris/annex","show-ref","refs/heads/master"]
+[2013-07-03 13:43:07 CEST] read: git ["--git-dir=/home/boris/annex/.git","--work-tree=/home/boris/annex","show-ref","git-annex"]
+[2013-07-03 13:43:07 CEST] read: git ["--git-dir=/home/boris/annex/.git","--work-tree=/home/boris/annex","show-ref","--hash","refs/heads/git-annex"]
+[2013-07-03 13:43:07 CEST] read: git ["--git-dir=/home/boris/annex/.git","--work-tree=/home/boris/annex","log","refs/heads/git-annex..4cc51b410f5257f60e4ea187ab0c29783effcc88","--oneline","-n1"]
+[2013-07-03 13:43:07 CEST] read: git ["--git-dir=/home/boris/annex/.git","--work-tree=/home/boris/annex","log","refs/heads/git-annex..6728d4d49ef97365eea0e2d379951acee9a9ded8","--oneline","-n1"]
+[2013-07-03 13:43:07 CEST] read: git ["--git-dir=/home/boris/annex/.git","--work-tree=/home/boris/annex","symbolic-ref","HEAD"]
+[2013-07-03 13:43:07 CEST] read: git ["--git-dir=/home/boris/annex/.git","--work-tree=/home/boris/annex","show-ref","refs/heads/master"]
+[2013-07-03 13:43:07 CEST] TransferScanner: starting scan of [Remote { name ="mybox" }]
+[2013-07-03 13:43:07 CEST] read: git ["--git-dir=/home/boris/annex/.git","--work-tree=/home/boris/annex","ls-files","--cached","-z","--"]
+[2013-07-03 13:43:07 CEST] TransferScanner: queued Upload UUID "32841e5f-1e4d-4c72-84c4-bbb54a335a23" afstuderen/TSPC_FF_R.png Nothing : expensive scan found missing object
+[2013-07-03 13:43:07 CEST] Transferrer: Transferring: Upload UUID "32841e5f-1e4d-4c72-84c4-bbb54a335a23" afstuderen/TSPC_FF_R.png Nothing
+[2013-07-03 13:43:07 CEST] TransferScanner: queued Upload UUID "32841e5f-1e4d-4c72-84c4-bbb54a335a23" afstuderen/Thumbs.db Nothing : expensive scan found missing object
+[2013-07-03 13:43:07 CEST] TransferWatcher: transfer starting: Upload UUID "32841e5f-1e4d-4c72-84c4-bbb54a335a23" afstuderen/TSPC_FF_R.png Nothing
+[2013-07-03 13:43:07 CEST] TransferScanner: queued Upload UUID "32841e5f-1e4d-4c72-84c4-bbb54a335a23" afstuderen/administratie/Aanmeldingsformulier Masterexamen.odt Nothing : expensive scan found missing object
+[2013-07-03 13:43:07 CEST] TransferScanner: queued Upload UUID "32841e5f-1e4d-4c72-84c4-bbb54a335a23" afstuderen/administratie/Intake_form_MSc_Electrical_Engineering_def dec 2011-1.pdf Nothing : expensive scan found missing object
+[2013-07-03 13:43:07 CEST] TransferScanner: queued Upload UUID "32841e5f-1e4d-4c72-84c4-bbb54a335a23" afstuderen/administratie/Opdrachtomschrijving Master.doc Nothing : expensive scan found missing object
+[2013-07-03 13:43:07 CEST] TransferScanner: queued Upload UUID "32841e5f-1e4d-4c72-84c4-bbb54a335a23" afstuderen/administratie/Opdrachtomschrijving Master.pdf Nothing : expensive scan found missing object
+[2013-07-03 13:43:07 CEST] TransferScanner: queued Upload UUID "32841e5f-1e4d-4c72-84c4-bbb54a335a23" afstuderen/administratie/uren.xls Nothing : expensive scan found missing object
+[2013-07-03 13:43:07 CEST] TransferScanner: queued Upload UUID "32841e5f-1e4d-4c72-84c4-bbb54a335a23" afstuderen/eldo_ur.pdf Nothing : expensive scan found missing object
+[2013-07-03 13:43:07 CEST] TransferScanner: queued Upload UUID "32841e5f-1e4d-4c72-84c4-bbb54a335a23" afstuderen/literatuur/ A 65J-Conversion-Step 0-to-50MS 0-to-0.7mW 9b Charge-Sharing SAR ADC in 90nm Digital CMOS.pdf Nothing : expensive scan found missing object
+[2013-07-03 13:43:07 CEST] TransferScanner: queued Upload UUID "32841e5f-1e4d-4c72-84c4-bbb54a335a23" afstuderen/literatuur/.directory Nothing : expensive scan found missing object
+[2013-07-03 13:43:07 CEST] TransferScanner: queued Upload UUID "32841e5f-1e4d-4c72-84c4-bbb54a335a23" afstuderen/literatuur/2009SOVC_A_0.92mW_10-bit_50-MSs_SAR_ADC_in_0.13um_CMOS_Process.pdf Nothing : expensive scan found missing object
+[2013-07-03 13:43:07 CEST] TransferScanner: queued Upload UUID "32841e5f-1e4d-4c72-84c4-bbb54a335a23" afstuderen/literatuur/A 8-bit 500-KSs Low Power SAR ADC for Biomedical Applications.pdf Nothing : expensive scan found missing object
+fatal: unrecognized command 'rsync --server -vre.iLsf --partial-dir .rsync-partial . annex/'
+git-annex-shell: git-shell failed
+rsync: connection unexpectedly closed (0 bytes received so far) [sender]
+rsync error: error in rsync protocol data stream (code 12) at io.c(605) [sender=3.0.9]
+[2013-07-03 13:43:07 CEST] TransferWatcher: transfer finishing: Transfer {transferDirection = Upload, transferUUID = UUID "32841e5f-1e4d-4c72-84c4-bbb54a335a23", transferKey = Key {keyName = "ea86501fb0db033a103ed2c0806a1bddc145224afc4eb5e17fceb70bf1f674da.png", keyBackendName = "SHA256E", keySize = Just 11004, keyMtime = Nothing}}
+fatal: unrecognized command 'rsync --server -vre.iLsf --partial-dir .rsync-partial . annex/'
+git-annex-shell: git-shell failed
+rsync: connection unexpectedly closed (0 bytes received so far) [sender]
+rsync error: error in rsync protocol data stream (code 12) at io.c(605) [sender=3.0.9]
+[2013-07-03 13:43:07 CEST] TransferScanner: queued Upload UUID "32841e5f-1e4d-4c72-84c4-bbb54a335a23" afstuderen/literatuur/A 9.2b 47fJ SAR with input range prediction DAC switching.pdf Nothing : expensive scan found missing object
+[2013-07-03 13:43:07 CEST] Transferrer: Transferring: Upload UUID "32841e5f-1e4d-4c72-84c4-bbb54a335a23" afstuderen/Thumbs.db Nothing
+[2013-07-03 13:43:07 CEST] TransferWatcher: transfer starting: Upload UUID "32841e5f-1e4d-4c72-84c4-bbb54a335a23" afstuderen/Thumbs.db Nothing
+fatal: unrecognized command 'rsync --server -vre.iLsf --partial-dir .rsync-partial . annex/'
+git-annex-shell: git-shell failed
+rsync: connection unexpectedly closed (0 bytes received so far) [sender]
+rsync error: error in rsync protocol data stream (code 12) at io.c(605) [sender=3.0.9]
+[2013-07-03 13:43:07 CEST] TransferWatcher: transfer finishing: Transfer {transferDirection = Upload, transferUUID = UUID "32841e5f-1e4d-4c72-84c4-bbb54a335a23", transferKey = Key {keyName = "23b9a2be728c8af402ededb3eef7e9238b38d54c0ca50a05cbdf4aeea8f03c76.db", keyBackendName = "SHA256E", keySize = Just 12800, keyMtime = Nothing}}
+fatal: unrecognized command 'rsync --server -vre.iLsf --partial-dir .rsync-partial . annex/'
+git-annex-shell: git-shell failed
+rsync: connection unexpectedly closed (0 bytes received so far) [sender]
+rsync error: error in rsync protocol data stream (code 12) at io.c(605) [sender=3.0.9]
+:
+[2013-07-03 13:43:07 CEST] TransferScanner: queued Upload UUID "32841e5f-1e4d-4c72-84c4-bbb54a335a23" afstuderen/literatuur/A Low-Power Static Dual Edge-Triggered Flip-Flop.pdf Nothing : expensive scan found missing object
+[2013-07-03 13:43:07 CEST] Transferrer: Transferring: Upload UUID "32841e5f-1e4d-4c72-84c4-bbb54a335a23" afstuderen/administratie/Aanmeldingsformulier Masterexamen.odt Nothing
+[2013-07-03 13:43:07 CEST] TransferWatcher: transfer starting: Upload UUID "32841e5f-1e4d-4c72-84c4-bbb54a335a23" afstuderen/administratie/Aanmeldingsformulier Masterexamen.odt Nothing
+fatal: unrecognized command 'rsync --server -vre.iLsf --partial-dir .rsync-partial . annex/'
+git-annex-shell: git-shell failed
+rsync: connection unexpectedly closed (0 bytes received so far) [sender]
+rsync error: error in rsync protocol data stream (code 12) at io.c(605) [sender=3.0.9]
+[2013-07-03 13:43:07 CEST] TransferWatcher: transfer finishing: Transfer {transferDirection = Upload, transferUUID = UUID "32841e5f-1e4d-4c72-84c4-bbb54a335a23", transferKey = Key {keyName = "f27ac57481c9eb0bf7bf1f6c99666aca5c8282137effa33791241b3d36b12de2.odt", keyBackendName = "SHA256E", keySize = Just 22041, keyMtime = Nothing}}
+fatal: unrecognized command 'rsync --server -vre.iLsf --partial-dir .rsync-partial . annex/'
+git-annex-shell: git-shell failed
+rsync: connection unexpectedly closed (0 bytes received so far) [sender]
+rsync error: error in rsync protocol data stream (code 12) at io.c(605) [sender=3.0.9]
+[2013-07-03 13:43:07 CEST] TransferScanner: queued Upload UUID "32841e5f-1e4d-4c72-84c4-bbb54a335a23" afstuderen/literatuur/An Energy-Efficient Charge Recycling Approach for a SAR Converter With Capacitive DAC.pdf Nothing : expensive scan found missing object
+[2013-07-03 13:43:07 CEST] Transferrer: Transferring: Upload UUID "32841e5f-1e4d-4c72-84c4-bbb54a335a23" afstuderen/administratie/Intake_form_MSc_Electrical_Engineering_def dec 2011-1.pdf Nothing
+[2013-07-03 13:43:07 CEST] TransferWatcher: transfer starting: Upload UUID "32841e5f-1e4d-4c72-84c4-bbb54a335a23" afstuderen/administratie/Intake_form_MSc_Electrical_Engineering_def dec 2011-1.pdf Nothing
+fatal: unrecognized command 'rsync --server -vre.iLsf --partial-dir .rsync-partial . annex/'
+git-annex-shell: git-shell failed
+rsync: connection unexpectedly closed (0 bytes received so far) [sender]
+rsync error: error in rsync protocol data stream (code 12) at io.c(605) [sender=3.0.9]
+[2013-07-03 13:43:07 CEST] TransferWatcher: transfer finishing: Transfer {transferDirection = Upload, transferUUID = UUID "32841e5f-1e4d-4c72-84c4-bbb54a335a23", transferKey = Key {keyName = "a261cb3835ed869c6ad2347d303ed10e94efa8a50cc9ff053d772c2158097244.pdf", keyBackendName = "SHA256E", keySize = Just 667666, keyMtime = Nothing}}
+fatal: unrecognized command 'rsync --server -vre.iLsf --partial-dir .rsync-partial . annex/'
+git-annex-shell: git-shell failed
+rsync: connection unexpectedly closed (0 bytes received so far) [sender]
+rsync error: error in rsync protocol data stream (code 12) at io.c(605) [sender=3.0.9]
+[2013-07-03 13:43:07 CEST] TransferScanner: queued Upload UUID "32841e5f-1e4d-4c72-84c4-bbb54a335a23" afstuderen/literatuur/Calibration Technique for SAR Analog-to-Digital Converters.pdf Nothing : expensive scan found missing object
+[2013-07-03 13:43:07 CEST] Transferrer: Transferring: Upload UUID "32841e5f-1e4d-4c72-84c4-bbb54a335a23" afstuderen/administratie/Opdrachtomschrijving Master.doc Nothing
+[2013-07-03 13:43:07 CEST] TransferWatcher: transfer starting: Upload UUID "32841e5f-1e4d-4c72-84c4-bbb54a335a23" afstuderen/administratie/Opdrachtomschrijving Master.doc Nothing
+fatal: unrecognized command 'rsync --server -vre.iLsf --partial-dir .rsync-partial . annex/'
+git-annex-shell: git-shell failed
+rsync: connection unexpectedly closed (0 bytes received so far) [sender]
+rsync error: error in rsync protocol data stream (code 12) at io.c(605) [sender=3.0.9]
+[2013-07-03 13:43:08 CEST] TransferWatcher: transfer finishing: Transfer {transferDirection = Upload, transferUUID = UUID "32841e5f-1e4d-4c72-84c4-bbb54a335a23", transferKey = Key {keyName = "cb69f2f4ae313277acd163b9bba19392ce50d3c5205ba8bbd90bf9c453088176.doc", keyBackendName = "SHA256E", keySize = Just 34304, keyMtime = Nothing}}
+[2013-07-03 13:43:08 CEST] call: git ["--git-dir=/home/boris/annex/.git","--work-tree=/home/boris/annex","config","remote.mybox.annex-sync","false"]
+[2013-07-03 13:43:08 CEST] read: git ["config","--null","--list"]
+[2013-07-03 13:43:08 CEST] read: git ["config","--null","--list"]
+fatal: unrecognized command 'rsync --server -vre.iLsf --partial-dir .rsync-partial . annex/'
+git-annex-shell: git-shell failed
+rsync: connection unexpectedly closed (0 bytes received so far) [sender]
+rsync error: error in rsync protocol data stream (code 12) at io.c(605) [sender=3.0.9]
+[2013-07-03 13:43:08 CEST] TransferScanner: queued Upload UUID "32841e5f-1e4d-4c72-84c4-bbb54a335a23" afstuderen/literatuur/D15_01.pdf Nothing : expensive scan found missing object
+[2013-07-03 13:43:08 CEST] Transferrer: Transferring: Upload UUID "32841e5f-1e4d-4c72-84c4-bbb54a335a23" afstuderen/administratie/Opdrachtomschrijving Master.pdf Nothing
+[2013-07-03 13:43:08 CEST] TransferWatcher: transfer starting: Upload UUID "32841e5f-1e4d-4c72-84c4-bbb54a335a23" afstuderen/administratie/Opdrachtomschrijving Master.pdf Nothing
+fatal: unrecognized command 'rsync --server -vre.iLsf --partial-dir .rsync-partial . annex/'
+git-annex-shell: git-shell failed
+rsync: connection unexpectedly closed (0 bytes received so far) [sender]
+rsync error: error in rsync protocol data stream (code 12) at io.c(605) [sender=3.0.9]
+[2013-07-03 13:43:08 CEST] TransferWatcher: transfer finishing: Transfer {transferDirection = Upload, transferUUID = UUID "32841e5f-1e4d-4c72-84c4-bbb54a335a23", transferKey = Key {keyName = "cea054d80cb5ca572b7055c0132ec2d13125534566ed4a79ab2514c9a60d8ee4.pdf", keyBackendName = "SHA256E", keySize = Just 19802, keyMtime = Nothing}}
+fatal: unrecognized command 'rsync --server -vre.iLsf --partial-dir .rsync-partial . annex/'
+git-annex-shell: git-shell failed
+rsync: connection unexpectedly closed (0 bytes received so far) [sender]
+rsync error: error in rsync protocol data stream (code 12) at io.c(605) [sender=3.0.9]
+[2013-07-03 13:43:08 CEST] Transferrer: Transferring: Upload UUID "32841e5f-1e4d-4c72-84c4-bbb54a335a23" afstuderen/literatuur/D15_01.pdf Nothing
+[2013-07-03 13:43:08 CEST] TransferWatcher: transfer starting: Upload UUID "32841e5f-1e4d-4c72-84c4-bbb54a335a23" afstuderen/literatuur/D15_01.pdf Nothing
+fatal: unrecognized command 'rsync --server -vre.iLsf --partial-dir .rsync-partial . annex/'
+git-annex-shell: git-shell failed
+rsync: connection unexpectedly closed (0 bytes received so far) [sender]
+rsync error: error in rsync protocol data stream (code 12) at io.c(605) [sender=3.0.9]
+
+
+
+# End of transcript or log.
+"""]]
+
+> [[fixed|done]], corrected logic error that caused `authorized_keys`
+> to incorrectly force the git-annex-shell command for rsync remotes. --[[Joey]]
diff --git a/doc/bugs/Rsync_remote_created_via_webapp_remains_empty/comment_1_cccf9d58c0ebb8d31cacdd029ea8e23a._comment b/doc/bugs/Rsync_remote_created_via_webapp_remains_empty/comment_1_cccf9d58c0ebb8d31cacdd029ea8e23a._comment
new file mode 100644
index 000000000..480a16243
--- /dev/null
+++ b/doc/bugs/Rsync_remote_created_via_webapp_remains_empty/comment_1_cccf9d58c0ebb8d31cacdd029ea8e23a._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.254.222"
+ subject="comment 1"
+ date="2013-07-08T16:55:09Z"
+ content="""
+Finally got a chance to look into this.
+
+The ~/.ssh/authorized_keys file on the server has been set up wrong by the webapp. If you look at it, it'll contain a part like: command=\"GIT_ANNEX_SHELL_DIRECTORY=... ~/.ssh/git-annex-shell\"
+
+That can't be used for rsync. If you delete that command= part, your remote should start working.
+"""]]
diff --git a/doc/bugs/S3_bucket_uses_the_same_key_for_encryption_and_hashing.mdwn b/doc/bugs/S3_bucket_uses_the_same_key_for_encryption_and_hashing.mdwn
new file mode 100644
index 000000000..2c0037c90
--- /dev/null
+++ b/doc/bugs/S3_bucket_uses_the_same_key_for_encryption_and_hashing.mdwn
@@ -0,0 +1,10 @@
+While using HMAC instead of "plain" hash functions is inherently more secure, it's still a bad idea to re-use keys for different purposes.
+
+Also, ttbomk, HMAC needs two keys, not one. Are you re-using the same key twice?
+
+Compability for old buckets and support for different ones can be maintained by introducing a new option and simply copying over the encryption key's identifier into this new option should it be missing.
+
+> Bug was filed prematurely, but was a good bit of paranoia, and gpg and
+> hmac are given different secret keys [[done]] --[[Joey]]
+
+>> Thanks :) -- RIchiH
diff --git a/doc/bugs/S3_bucket_uses_the_same_key_for_encryption_and_hashing/comment_1_dc5ae7af499203cfd903e866595b8fea._comment b/doc/bugs/S3_bucket_uses_the_same_key_for_encryption_and_hashing/comment_1_dc5ae7af499203cfd903e866595b8fea._comment
new file mode 100644
index 000000000..320fb5ef0
--- /dev/null
+++ b/doc/bugs/S3_bucket_uses_the_same_key_for_encryption_and_hashing/comment_1_dc5ae7af499203cfd903e866595b8fea._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-03-30T14:32:34Z"
+ content="""
+S3 doesn't support encryption at all, yet.
+
+It certainly makes sense to use a different portion of the encrypted secret key for HMAC than is uses as the gpg symmetric encryption key.
+
+The two keys used in HMAC would be the secret key and the key/value key for the content being stored.
+
+There is a difficult problem with encrypting filenames in S3 buckets, and that is determining when some data in the bucket is unused for dropunused. I've considered two choices:
+
+1. gpg encrypt the filenames. This would allow dropunused to recover the original filenames, and is probably more robust encryption. But it would double the number of times gpg is run when moving content in/out, and to check for unused content, gpg would have to be run once for every item in the bucket, which just feels way excessive, even though it would not be prompting for a passphrase. Still, haven't ruled this out.
+
+2. HMAC or other hash. To determine what data was unused the same hash and secret key would have to be used to hash all filenames currently used, and then that set of hashes could be interested with the set in the bucket. But then git-annex could only say \"here are some opaque hashes of content that appears unused by anything in your current git repository, but there's no way, short of downloading it and examining it to tell what it is\". (This could be improved by keeping a local mapping between filenames and S3 keys, but maintaining and committing that would bring pain of its own.)
+"""]]
diff --git a/doc/bugs/S3_bucket_uses_the_same_key_for_encryption_and_hashing/comment_2_c62daf5b3bfcd2f684262c96ef6628c1._comment b/doc/bugs/S3_bucket_uses_the_same_key_for_encryption_and_hashing/comment_2_c62daf5b3bfcd2f684262c96ef6628c1._comment
new file mode 100644
index 000000000..dec06c89f
--- /dev/null
+++ b/doc/bugs/S3_bucket_uses_the_same_key_for_encryption_and_hashing/comment_2_c62daf5b3bfcd2f684262c96ef6628c1._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 2"
+ date="2011-03-30T17:01:40Z"
+ content="""
+After mulling this over, I think actually encrypting the filenames is preferable.
+
+Did you consider encrypting the symmetric key with an asymmetric one? That's what TrueCrypt etc are using to allow different people access to a shared volume. This has the added benefit that you could, potentially, add new keys for data that new people should have access to while making access to old data impossible. Or keys per subdirectory, or, or, or.
+
+As an aside, could the same mechanism be extended to transparently encrypt data for a remote annex repo? A friend of mine is interested to host his data with me, but he wants to encrypt his data for obvious reasons.
+"""]]
diff --git a/doc/bugs/S3_bucket_uses_the_same_key_for_encryption_and_hashing/comment_3_e1f39c4af5bdb0daabf000da80858cd9._comment b/doc/bugs/S3_bucket_uses_the_same_key_for_encryption_and_hashing/comment_3_e1f39c4af5bdb0daabf000da80858cd9._comment
new file mode 100644
index 000000000..c5bb26f59
--- /dev/null
+++ b/doc/bugs/S3_bucket_uses_the_same_key_for_encryption_and_hashing/comment_3_e1f39c4af5bdb0daabf000da80858cd9._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 3"
+ date="2011-03-30T18:15:18Z"
+ content="""
+Yes, encrypting the symmetric key with users' regular gpg keys is the plan.
+
+I don't think that encryption of content in a git annex remote makes much sense; the filenames obviously cannot be encrypted there. It's more likely that the same encryption would get used for a bup remote, or with the [[special_remotes/directory]] remote I threw in today.
+"""]]
diff --git a/doc/bugs/S3_bucket_uses_the_same_key_for_encryption_and_hashing/comment_4_bb6b814ab961818d514f6553455d2bf3._comment b/doc/bugs/S3_bucket_uses_the_same_key_for_encryption_and_hashing/comment_4_bb6b814ab961818d514f6553455d2bf3._comment
new file mode 100644
index 000000000..09b7a8b1a
--- /dev/null
+++ b/doc/bugs/S3_bucket_uses_the_same_key_for_encryption_and_hashing/comment_4_bb6b814ab961818d514f6553455d2bf3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 4"
+ date="2011-03-30T18:20:56Z"
+ content="""
+Picking up the automagic encryption idea for annex remotes, this would allow you to host a branchable-esque git-annex hosting service. (Nexenta with ZFS is a cheap and reliable option until btrfs becomes stable in a year or five).
+"""]]
diff --git a/doc/bugs/S3_bucket_uses_the_same_key_for_encryption_and_hashing/comment_5_5bb128f6d2ca4b5e4d881fae297fa1f8._comment b/doc/bugs/S3_bucket_uses_the_same_key_for_encryption_and_hashing/comment_5_5bb128f6d2ca4b5e4d881fae297fa1f8._comment
new file mode 100644
index 000000000..49d43ffc6
--- /dev/null
+++ b/doc/bugs/S3_bucket_uses_the_same_key_for_encryption_and_hashing/comment_5_5bb128f6d2ca4b5e4d881fae297fa1f8._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 5"
+ date="2011-03-30T18:59:19Z"
+ content="""
+This is brain-storming only so the idea might be crap, but a branch could keep encrypted filenames while master keeps the real deal. This might fit into the whole scheme just nicely or break future stuff in a dozen places, I am not really sure yet. But at least I can't forget the idea, now.
+"""]]
diff --git a/doc/bugs/S3_bucket_uses_the_same_key_for_encryption_and_hashing/comment_6_63fb74da342751fc35e1850409c506f6._comment b/doc/bugs/S3_bucket_uses_the_same_key_for_encryption_and_hashing/comment_6_63fb74da342751fc35e1850409c506f6._comment
new file mode 100644
index 000000000..d994ca77f
--- /dev/null
+++ b/doc/bugs/S3_bucket_uses_the_same_key_for_encryption_and_hashing/comment_6_63fb74da342751fc35e1850409c506f6._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 6"
+ date="2011-03-30T19:02:20Z"
+ content="""
+OTOH, if encryption makes a bup backend more likely disregard the idea above ;)
+"""]]
diff --git a/doc/bugs/S3_buckets_with_capital_letters_breaks_authentication.mdwn b/doc/bugs/S3_buckets_with_capital_letters_breaks_authentication.mdwn
new file mode 100644
index 000000000..9a67db0c6
--- /dev/null
+++ b/doc/bugs/S3_buckets_with_capital_letters_breaks_authentication.mdwn
@@ -0,0 +1,32 @@
+### Please describe the problem.
+
+As described in [[tips/Internet_Archive_via_S3]], there is a problem using S3 with buckets that have capital letters. The bug lies either in the hS3 library or in archive.org itself.
+
+### What steps will reproduce the problem?
+
+Try to add an [[special_remotes/S3]] remote with capital letters in the bucket name.
+
+### What version of git-annex are you using? On what operating system?
+
+[[!format txt """
+git-annex version: 4.20130921-g434dc22
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP DNS Feeds Quvi
+local repository version: 3
+default repository version: 3
+supported repository versions: 3 4
+upgrade supported from repository versions: 0 1 2
+"""]]
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+anarcat@angela:video$ git annex initremote archive-moglenrepublica type=S3 host=s3.us.archive.org bucket=Republica2012-EbenMoglen-FreedomOfThoughtRequiresFreeMedia
+initremote archive-moglenrepublica (Internet Archive mode) git-annex: The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. For more information, see REST Authentication and SOAP Authentication for details.
+# End of transcript or log.
+"""]]
+
+Just thought it would be better to have a separate thread for this bug. :)
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/S3_memory_leaks.mdwn b/doc/bugs/S3_memory_leaks.mdwn
new file mode 100644
index 000000000..2f72b09ac
--- /dev/null
+++ b/doc/bugs/S3_memory_leaks.mdwn
@@ -0,0 +1,14 @@
+S3 has memory leaks
+
+Sending a file to S3 causes a slow memory increase toward the file size.
+
+Copying the file back from S3 causes a slow memory increase toward the
+file size.
+
+The author of hS3 is aware of the problem, and working on it. I think I
+have identified the root cause of the buffering; it's done by hS3 so it can
+resend the data if S3 sends it a 307 redirect. --[[Joey]]
+
+At least the send leak should be fixed by the patch in the s3-memory-leak
+branch in git. That needs a patch to hS3, which I have sent to its author.
+--[[Joey]]
diff --git a/doc/bugs/S3_memory_leaks/comment_1_a7268213b090bce6b1f1858a8e23d90e._comment b/doc/bugs/S3_memory_leaks/comment_1_a7268213b090bce6b1f1858a8e23d90e._comment
new file mode 100644
index 000000000..0523fd473
--- /dev/null
+++ b/doc/bugs/S3_memory_leaks/comment_1_a7268213b090bce6b1f1858a8e23d90e._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://schnouki.net/"
+ nickname="Schnouki"
+ subject="comment 1"
+ date="2013-10-18T08:36:45Z"
+ content="""
+Hi Joey,
+
+It looks like your patch hasn't been merged yet. And this bug is quite annoying for me (can't backup files bigger than 1.5 GB from my NAS).
+
+Would it be possible to include this fix in your standalone builds and Debian packages?
+
+Thanks!
+"""]]
diff --git a/doc/bugs/S3_upload_not_using_multipart.mdwn b/doc/bugs/S3_upload_not_using_multipart.mdwn
new file mode 100644
index 000000000..d242908f9
--- /dev/null
+++ b/doc/bugs/S3_upload_not_using_multipart.mdwn
@@ -0,0 +1,53 @@
+What steps will reproduce the problem?
+
+> Try to copy/move a file greater than 5G to S3.
+
+ git annex copy large_file.tgz --to cloud
+
+What is the expected output? What do you see instead?
+
+> Looks like git-annex may not be using the Multipart Upload API: http://docs.aws.amazon.com/AmazonS3/latest/dev/uploadobjusingmpu.html
+
+> Expected transfer to succeed, instead this error is output:
+
+ copy large-file.tgz (gpg) (checking cloud...) (to cloud...) Reading passphrase from file descriptor 12
+
+
+ Your proposed upload exceeds the maximum allowed size
+ failed
+ git-annex: copy: 1 failed
+
+What version of git-annex are you using? On what operating system?
+
+> OSX 10.8.2
+
+Please provide any additional information below.
+
+ annex [master●] % git annex status
+ supported backends: SHA256E SHA1E SHA512E SHA224E SHA384E SHA256 SHA1 SHA512 SHA224 SHA384 WORM URL
+ supported remote types: git S3 bup directory rsync web webdav glacier hook
+ repository mode: indirect
+ trusted repositories: 0
+ semitrusted repositories: 3
+ 00000000-0000-0000-0000-000000000001 -- web
+ BE1D8EC7-C64B-47DE-AD4E-2A50437532B4 -- cloud
+ E84568BA-6A4B-4AA1-B622-605B9248EDB1 -- here (eric laptop)
+ untrusted repositories: 0
+ dead repositories: 0
+ transfers in progress: none
+ available local disk space: 169 gigabytes (+1 megabyte reserved)
+ temporary directory size: 218 megabytes (clean up with git-annex unused)
+ local annex keys: 24
+ local annex size: 8 gigabytes
+ known annex keys: 25
+ known annex size: 8 gigabytes
+ bloom filter size: 16 mebibytes (0% full)
+ backend usage:
+ SHA256E: 49
+ annex [master●] % git annex version
+ git-annex version: 3.20130114
+ local repository version: 3
+ default repository version: 3
+ supported repository versions: 3
+ upgrade supported from repository versions: 0 1 2
+
diff --git a/doc/bugs/SSH:_command-line:_line_0:_Bad_configuration_option:_ControlPersist___40__SSH_too_old_on_OS_X_10.6.8__63____41__.mdwn b/doc/bugs/SSH:_command-line:_line_0:_Bad_configuration_option:_ControlPersist___40__SSH_too_old_on_OS_X_10.6.8__63____41__.mdwn
new file mode 100644
index 000000000..a3d27e404
--- /dev/null
+++ b/doc/bugs/SSH:_command-line:_line_0:_Bad_configuration_option:_ControlPersist___40__SSH_too_old_on_OS_X_10.6.8__63____41__.mdwn
@@ -0,0 +1,27 @@
+What steps will reproduce the problem?
+
+Try to get any file from a remote ssh repository on OS X 10.6.8
+
+What is the expected output? What do you see instead?
+
+Instead of retrieving the files, I get:
+
+ % git annex get .
+ get <filename> command-line: line 0: Bad configuration option: ControlPersist
+ command-line: line 0: Bad configuration option: ControlPersist
+ (not available)
+ Try making some of these repositories available:
+ 2efd46d2-0e32-11e2-95fe-f72f09c6615e -- office
+
+What version of git-annex are you using? On what operating system?
+ % git annex version
+ git-annex version: 3.20120925
+ local repository version: 3
+ default repository version: 3
+ supported repository versions: 3
+ upgrade supported from repository versions: 0 1 2
+
+I seems that this option is passed to SSH, but SSH is too old: OpenSSH_5.2p1, OpenSSL 0.9.8r 8 Feb
+
+> Future builds of the standalone binary will default annex.sshcaching to
+> false. [[done]] --[[Joey]]
diff --git a/doc/bugs/SSH:_command-line:_line_0:_Bad_configuration_option:_ControlPersist___40__SSH_too_old_on_OS_X_10.6.8__63____41__/comment_1_0c57a2196d35eb1ecfb0c51273bba05c._comment b/doc/bugs/SSH:_command-line:_line_0:_Bad_configuration_option:_ControlPersist___40__SSH_too_old_on_OS_X_10.6.8__63____41__/comment_1_0c57a2196d35eb1ecfb0c51273bba05c._comment
new file mode 100644
index 000000000..ec510ae30
--- /dev/null
+++ b/doc/bugs/SSH:_command-line:_line_0:_Bad_configuration_option:_ControlPersist___40__SSH_too_old_on_OS_X_10.6.8__63____41__/comment_1_0c57a2196d35eb1ecfb0c51273bba05c._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.8"
+ subject="comment 1"
+ date="2012-10-15T18:16:58Z"
+ content="""
+Here's a workaround, which you can run in the local repository:
+
+git config annex.sshcaching false
+"""]]
diff --git a/doc/bugs/Segfaults_on_Fedora_18_with_SELinux_enabled.mdwn b/doc/bugs/Segfaults_on_Fedora_18_with_SELinux_enabled.mdwn
new file mode 100644
index 000000000..39b860e7c
--- /dev/null
+++ b/doc/bugs/Segfaults_on_Fedora_18_with_SELinux_enabled.mdwn
@@ -0,0 +1,65 @@
+git-annex version: 4.20130323
+
+Running the webapp with SELinux enabled:
+
+ [0 zerodogg@browncoats annexed]$ git annex webapp --debug
+ Launching web browser on file:///home/zerodogg/Documents/annexed/.git/annex/webapp.html
+ /home/zerodogg/bin/git-annex: line 25: 5801 Segmentation fault (core dumped) "$base/runshell" git-annex "$@"
+
+After disabling SELinux it works just fine. This is on a freshly installed (default settings) Fedora 18 on x86-64.
+
+Running the assistant also works, but segfaults when attempting to open the webapp:
+
+ [0 zerodogg@browncoats annexed]$ git annex assistant &
+ [1] 6241
+ [0 zerodogg@browncoats annexed]$
+ [0 zerodogg@browncoats annexed]$ git annex webapp --debug
+ Launching web browser on file:///home/zerodogg/Documents/annexed/.git/annex/webapp.html
+ /home/zerodogg/bin/git-annex: line 25: 6322 Segmentation fault (core dumped) "$base/runshell" git-annex "$@"
+ [139 zerodogg@browncoats annexed]$ Created new window in existing browser session.
+
+Here's what `dmesg` says:
+
+ [ 71.488843] SELinux: initialized (dev proc, type proc), uses genfs_contexts
+ [ 115.443932] git-annex[3985]: segfault at e6e62984 ip 0000000009b8085a sp 00000000f4bfd028 error 4 in git-annex[8048000+1c75000]
+ [ 125.148819] SELinux: initialized (dev proc, type proc), uses genfs_contexts
+ [ 125.230155] git-annex[4043]: segfault at e6eda984 ip 0000000009b8085a sp 00000000f63fd028 error 4 in git-annex[8048000+1c75000]
+ [ 406.855659] SELinux: initialized (dev proc, type proc), uses genfs_contexts
+ [ 407.033966] git-annex[5806]: segfault at e6faa984 ip 0000000009b8085a sp 00000000f6dfd028 error 4 in git-annex[8048000+1c75000]
+ [ 462.368045] git-annex[6279]: segfault at e6f76984 ip 0000000009b8085a sp 00000000f49fd028 error 4 in git-annex[8048000+1c75000]
+ [ 465.714636] SELinux: initialized (dev proc, type proc), uses genfs_contexts
+ [ 465.930434] git-annex[6329]: segfault at e6e7a984 ip 0000000009b8085a sp 00000000f63fd028 error 4 in git-annex[8048000+1c75000]
+ [ 560.570480] git-annex[7050]: segfault at e7022984 ip 0000000009b8085a sp 00000000f54fd028 error 4 in git-annex[8048000+1c75000]
+ [ 565.510664] SELinux: initialized (dev proc, type proc), uses genfs_contexts
+ [ 565.688681] git-annex[7108]: segfault at e7196984 ip 0000000009b8085a sp 00000000f54fd028 error 4 in git-annex[8048000+1c75000]
+
+Running the whole thing with --debug doesn't appear to provide anything useful:
+
+ [0 zerodogg@browncoats annexed]$ git annex assistant --debug &
+ [1] 7018
+ [0 zerodogg@browncoats annexed]$ [2013-03-24 16:27:02 CET] read: git ["--git-dir=/home/zerodogg/Documents/annexed/.git","--work-tree=/home/zerodogg/Documents/annexed","show-ref","git-annex"]
+ [2013-03-24 16:27:02 CET] read: git ["--git-dir=/home/zerodogg/Documents/annexed/.git","--work-tree=/home/zerodogg/Documents/annexed","show-ref","--hash","refs/heads/git-annex"]
+ [2013-03-24 16:27:02 CET] read: git ["--git-dir=/home/zerodogg/Documents/annexed/.git","--work-tree=/home/zerodogg/Documents/annexed","log","refs/heads/git-annex..f2260840bd9563f3d9face53dddd6807813860cd","--oneline","-n1"]
+ [2013-03-24 16:27:02 CET] read: git ["--git-dir=/home/zerodogg/Documents/annexed/.git","--work-tree=/home/zerodogg/Documents/annexed","log","refs/heads/git-annex..798526ef1315811296b1ac95d4cf97c72141ad29","--oneline","-n1"]
+ [2013-03-24 16:27:02 CET] read: git ["--git-dir=/home/zerodogg/Documents/annexed/.git","--work-tree=/home/zerodogg/Documents/annexed","log","refs/heads/git-annex..0d827b1ef545a88e94ee8cc973e54a1b74d216f4","--oneline","-n1"]
+ [2013-03-24 16:27:02 CET] read: git ["--git-dir=/home/zerodogg/Documents/annexed/.git","--work-tree=/home/zerodogg/Documents/annexed","log","refs/heads/git-annex..1d8f91411b827c4d59735dbc572e7f278e870e43","--oneline","-n1"]
+ [2013-03-24 16:27:02 CET] read: git ["--git-dir=/home/zerodogg/Documents/annexed/.git","--work-tree=/home/zerodogg/Documents/annexed","log","refs/heads/git-annex..cc442416b325866139db6dbe374bddacda6fef91","--oneline","-n1"]
+ [2013-03-24 16:27:02 CET] read: git ["--git-dir=/home/zerodogg/Documents/annexed/.git","--work-tree=/home/zerodogg/Documents/annexed","log","refs/heads/git-annex..3c2f44ffd82df1a0ae8858bdf2610e933b105a09","--oneline","-n1"]
+ [2013-03-24 16:27:02 CET] read: git ["--git-dir=/home/zerodogg/Documents/annexed/.git","--work-tree=/home/zerodogg/Documents/annexed","log","refs/heads/git-annex..fb8819ca92d9a2ed39e6d329160b5f8da60df83f","--oneline","-n1"]
+ [2013-03-24 16:27:02 CET] read: git ["--git-dir=/home/zerodogg/Documents/annexed/.git","--work-tree=/home/zerodogg/Documents/annexed","log","refs/heads/git-annex..68d0f936ee044b0ca34cf4029bcd6274fed88499","--oneline","-n1"]
+ [2013-03-24 16:27:02 CET] read: git ["--git-dir=/home/zerodogg/Documents/annexed/.git","--work-tree=/home/zerodogg/Documents/annexed","log","refs/heads/git-annex..3ba3dfef6340196126f4fc630b5048188230d1ff","--oneline","-n1"]
+ [2013-03-24 16:27:02 CET] chat: git ["--git-dir=/home/zerodogg/Documents/annexed/.git","--work-tree=/home/zerodogg/Documents/annexed","cat-file","--batch"]
+
+ [1] + done GITWRAP annex assistant --debug
+ [0 zerodogg@browncoats annexed]$ git annex webapp --debug &
+ [1] 7082
+ [0 zerodogg@browncoats annexed]$ Launching web browser on file:///home/zerodogg/Documents/annexed/.git/annex/webapp.html
+ /home/zerodogg/bin/git-annex: line 25: 7088 Segmentation fault (core dumped) "$base/runshell" git-annex "$@"
+
+ [1] + exit 139 GITWRAP annex webapp --debug
+ [0 zerodogg@browncoats annexed]$ Created new window in existing browser session.
+
+> On IRC it developed that it segfaulted at other times, and gdb complained
+> of a library mismatch. Seems something changed in Fedora libc, and
+> the 32 bit binary is not working on 64 bit. I've brought back the 64 bit
+> standalone builds, which work. [[done]] --[[Joey]]
diff --git a/doc/bugs/Segfaults_on_Fedora_18_with_SELinux_enabled/comment_1_f708d87aa65cd38c20087859d3ab2dc7._comment b/doc/bugs/Segfaults_on_Fedora_18_with_SELinux_enabled/comment_1_f708d87aa65cd38c20087859d3ab2dc7._comment
new file mode 100644
index 000000000..458e31327
--- /dev/null
+++ b/doc/bugs/Segfaults_on_Fedora_18_with_SELinux_enabled/comment_1_f708d87aa65cd38c20087859d3ab2dc7._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-03-27T16:18:14Z"
+ content="""
+What is this GITWRAP? That is not part of git-annex, I suspect it's a locally set up wrapper around git of some sort.
+
+--debug causes the assistant to log to `.git/annex/daemon.log`, there may be useful information in there. In particular it's not at all clear whether the web browser is segfaulting, or whether the crash occurs before the web browser is started.
+
+Does your SE linux policy allow git-annex to run your web browser? What happens if you start the assistant and then manually open file:///home/zerodogg/Documents/annexed/.git/annex/webapp.html in your web browser?
+"""]]
diff --git a/doc/bugs/Segfaults_on_Fedora_18_with_SELinux_enabled/comment_2_fb7188db031147992f3c906783ebbee0._comment b/doc/bugs/Segfaults_on_Fedora_18_with_SELinux_enabled/comment_2_fb7188db031147992f3c906783ebbee0._comment
new file mode 100644
index 000000000..6b7e7ccc8
--- /dev/null
+++ b/doc/bugs/Segfaults_on_Fedora_18_with_SELinux_enabled/comment_2_fb7188db031147992f3c906783ebbee0._comment
@@ -0,0 +1,59 @@
+[[!comment format=mdwn
+ username="EskildHustvedt"
+ ip="84.48.83.221"
+ subject="comment 2"
+ date="2013-03-31T18:13:53Z"
+ content="""
+GITWRAP is just my shell function that sets GIT_PAGER to different values depending on the command.
+
+SELinux lets git-annex run the browser. Browser opens on the file, redirects to the git-annex localhost URL (which fails to connect at that point, since git-annex has crashed). So the crash is 1) in git-annex, and 2) after it has started the browser. The segfault also occurs if I directly start the browser on `/home/zerodogg/Documents/annexed/.git/annex/webapp.html`, so it would appear that the crash occurs when something tries to connect to the http server.
+
+There's nothing from --debug in `.git/annex/daemon.log`:
+
+ [2013-03-31 19:58:09 CEST] main: starting assistant version 4.20130323
+ [2013-03-31 19:58:09 CEST] read: host [\"-t\",\"SRV\",\"--\",\"_xmpp-client._tcp.dukgo.com\"]
+ [2013-03-31 19:58:09 CEST] read: git [\"--git-dir=/home/zerodogg/Documents/annexed/.git\",\"--work-tree=/home/zerodogg/Documents/annexed\",\"symbolic-ref\",\"HEAD\"]
+ [2013-03-31 19:58:09 CEST] TransferScanner: Syncing with serenity, river, hufsa, browncoats
+ [2013-03-31 19:58:09 CEST] read: git [\"--git-dir=/home/zerodogg/Documents/annexed/.git\",\"--work-tree=/home/zerodogg/Documents/annexed\",\"show-ref\",\"refs/heads/master\"]
+ [2013-03-31 19:58:09 CEST] NetWatcher: Using running DBUS service org.freedesktop.NetworkManager to monitor network connection events.
+ [2013-03-31 19:58:09 CEST] MountWatcher: Using running DBUS service org.gtk.Private.UDisks2VolumeMonitor to monitor mount events.
+ [2013-03-31 19:58:09 CEST] Merger: merging refs/remotes/browncoats/synced/master into refs/heads/master
+ [2013-03-31 19:58:09 CEST] read: git [\"--git-dir=/home/zerodogg/Documents/annexed/.git\",\"--work-tree=/home/zerodogg/Documents/annexed\",\"ls-tree\",\"-z\",\"--\",\"refs/heads/git-annex\",\"uuid.log\",\"remote.log\",\"trust.log\",\"group.log\",\"preferred-content.log\"]
+ [2013-03-31 19:58:09 CEST] read: git [\"--git-dir=/home/zerodogg/Documents/annexed/.git\",\"--work-tree=/home/zerodogg/Documents/annexed\",\"symbolic-ref\",\"HEAD\"]
+ [2013-03-31 19:58:09 CEST] read: git [\"--git-dir=/home/zerodogg/Documents/annexed/.git\",\"--work-tree=/home/zerodogg/Documents/annexed\",\"show-ref\",\"refs/heads/master\"]
+
+ [2013-03-31 19:58:09 CEST] call: git [\"--git-dir=/home/zerodogg/Documents/annexed/.git\",\"--work-tree=/home/zerodogg/Documents/annexed\",\"merge\",\"--no-edit\",\"refs/remotes/browncoats/synced/master\"]
+ Already up-to-date.
+ [2013-03-31 19:58:09 CEST] call: git [\"--git-dir=/home/zerodogg/Documents/annexed/.git\",\"--work-tree=/home/zerodogg/Documents/annexed\",\"fetch\",\"serenity\"]
+ [2013-03-31 19:58:09 CEST] read: git [\"--git-dir=/home/zerodogg/Documents/annexed/.git\",\"--work-tree=/home/zerodogg/Documents/annexed\",\"show-ref\",\"git-annex\"]
+ [2013-03-31 19:58:09 CEST] read: git [\"--git-dir=/home/zerodogg/Documents/annexed/.git\",\"--work-tree=/home/zerodogg/Documents/annexed\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+ [2013-03-31 19:58:09 CEST] read: git [\"--git-dir=/home/zerodogg/Documents/annexed/.git\",\"--work-tree=/home/zerodogg/Documents/annexed\",\"log\",\"refs/heads/git-annex..d5e18a083c7d0caeddc3da78f18b53fac0d56a7f\",\"--oneline\",\"-n1\"]
+ [2013-03-31 19:58:09 CEST] read: git [\"--git-dir=/home/zerodogg/Documents/annexed/.git\",\"--work-tree=/home/zerodogg/Documents/annexed\",\"log\",\"refs/heads/git-annex..f2260840bd9563f3d9face53dddd6807813860cd\",\"--oneline\",\"-n1\"]
+ [2013-03-31 19:58:09 CEST] read: git [\"--git-dir=/home/zerodogg/Documents/annexed/.git\",\"--work-tree=/home/zerodogg/Documents/annexed\",\"log\",\"refs/heads/git-annex..798526ef1315811296b1ac95d4cf97c72141ad29\",\"--oneline\",\"-n1\"]
+ [2013-03-31 19:58:10 CEST] read: git [\"--git-dir=/home/zerodogg/Documents/annexed/.git\",\"--work-tree=/home/zerodogg/Documents/annexed\",\"log\",\"refs/heads/git-annex..21a6361e598efd80e851276c17249e5c3284713f\",\"--oneline\",\"-n1\"]
+ [2013-03-31 19:58:10 CEST] read: git [\"--git-dir=/home/zerodogg/Documents/annexed/.git\",\"--work-tree=/home/zerodogg/Documents/annexed\",\"log\",\"refs/heads/git-annex..3c2f44ffd82df1a0ae8858bdf2610e933b105a09\",\"--oneline\",\"-n1\"]
+ [2013-03-31 19:58:10 CEST] read: git [\"--git-dir=/home/zerodogg/Documents/annexed/.git\",\"--work-tree=/home/zerodogg/Documents/annexed\",\"log\",\"refs/heads/git-annex..3b4fcc605fd4787084afe47e82eac6821cb2cd37\",\"--oneline\",\"-n1\"]
+ [2013-03-31 19:58:10 CEST] read: git [\"--git-dir=/home/zerodogg/Documents/annexed/.git\",\"--work-tree=/home/zerodogg/Documents/annexed\",\"ls-tree\",\"-z\",\"--\",\"refs/heads/git-annex\",\"uuid.log\",\"remote.log\",\"trust.log\",\"group.log\",\"preferred-content.log\"]
+ (scanning...) [2013-03-31 19:58:10 CEST] Watcher: Performing startup scan
+ [2013-03-31 19:58:10 CEST] read: git [\"--git-dir=/home/zerodogg/Documents/annexed/.git\",\"--work-tree=/home/zerodogg/Documents/annexed\",\"show-ref\",\"git-annex\"]
+ [2013-03-31 19:58:10 CEST] read: git [\"--git-dir=/home/zerodogg/Documents/annexed/.git\",\"--work-tree=/home/zerodogg/Documents/annexed\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+ [2013-03-31 19:58:10 CEST] read: git [\"--git-dir=/home/zerodogg/Documents/annexed/.git\",\"--work-tree=/home/zerodogg/Documents/annexed\",\"log\",\"refs/heads/git-annex..d5e18a083c7d0caeddc3da78f18b53fac0d56a7f\",\"--oneline\",\"-n1\"]
+ [2013-03-31 19:58:10 CEST] read: git [\"--git-dir=/home/zerodogg/Documents/annexed/.git\",\"--work-tree=/home/zerodogg/Documents/annexed\",\"log\",\"refs/heads/git-annex..f2260840bd9563f3d9face53dddd6807813860cd\",\"--oneline\",\"-n1\"]
+ [2013-03-31 19:58:10 CEST] read: git [\"--git-dir=/home/zerodogg/Documents/annexed/.git\",\"--work-tree=/home/zerodogg/Documents/annexed\",\"log\",\"refs/heads/git-annex..798526ef1315811296b1ac95d4cf97c72141ad29\",\"--oneline\",\"-n1\"]
+ [2013-03-31 19:58:10 CEST] read: git [\"--git-dir=/home/zerodogg/Documents/annexed/.git\",\"--work-tree=/home/zerodogg/Documents/annexed\",\"log\",\"refs/heads/git-annex..21a6361e598efd80e851276c17249e5c3284713f\",\"--oneline\",\"-n1\"]
+ [2013-03-31 19:58:10 CEST] read: git [\"--git-dir=/home/zerodogg/Documents/annexed/.git\",\"--work-tree=/home/zerodogg/Documents/annexed\",\"log\",\"refs/heads/git-annex..3c2f44ffd82df1a0ae8858bdf2610e933b105a09\",\"--oneline\",\"-n1\"]
+ [2013-03-31 19:58:10 CEST] read: git [\"--git-dir=/home/zerodogg/Documents/annexed/.git\",\"--work-tree=/home/zerodogg/Documents/annexed\",\"log\",\"refs/heads/git-annex..3b4fcc605fd4787084afe47e82eac6821cb2cd37\",\"--oneline\",\"-n1\"]
+ [2013-03-31 19:58:10 CEST] read: git [\"--git-dir=/home/zerodogg/Documents/annexed/.git\",\"--work-tree=/home/zerodogg/Documents/annexed\",\"symbolic-ref\",\"HEAD\"]
+ [2013-03-31 19:58:10 CEST] read: git [\"--git-dir=/home/zerodogg/Documents/annexed/.git\",\"--work-tree=/home/zerodogg/Documents/annexed\",\"show-ref\",\"refs/heads/master\"]
+ [2013-03-31 19:58:10 CEST] Merger: merging refs/remotes/serenity/synced/master into refs/heads/master
+
+ [2013-03-31 19:58:10 CEST] call: git [\"--git-dir=/home/zerodogg/Documents/annexed/.git\",\"--work-tree=/home/zerodogg/Documents/annexed\",\"merge\",\"--no-edit\",\"refs/remotes/serenity/synced/master\"]
+ Already up-to-date.
+ [2013-03-31 19:58:10 CEST] read: git [\"--git-dir=/home/zerodogg/Documents/annexed/.git\",\"--work-tree=/home/zerodogg/Documents/annexed\",\"show-ref\",\"git-annex\"]
+ [2013-03-31 19:58:10 CEST] read: git [\"--git-dir=/home/zerodogg/Documents/annexed/.git\",\"--work-tree=/home/zerodogg/Documents/annexed\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+ [2013-03-31 19:58:10 CEST] read: git [\"--git-dir=/home/zerodogg/Documents/annexed/.git\",\"--work-tree=/home/zerodogg/Documents/annexed\",\"log\",\"refs/heads/git-annex..d5e18a083c7d0caeddc3da78f18b53fac0d56a7f\",\"--oneline\",\"-n1\"]
+ [2013-03-31 19:58:10 CEST] read: git [\"--git-dir=/home/zerodogg/Documents/annexed/.git\",\"--work-tree=/home/zerodogg/Documents/annexed\",\"log\",\"refs/heads/git-annex..f2260840bd9563f3d9face53dddd6807813860cd\",\"--oneline\",\"-n1\"]
+ [2013-03-31 19:58:10 CEST] read: git [\"--git-dir=/home/zerodogg/Documents/annexed/.git\",\"--work-tree=/home/zerodogg/Documents/annexed\",\"log\",\"refs/heads/git-annex..798526ef1315811296b1ac95d4cf97c72141ad29\",\"--oneline\",\"-n1\"]
+ [2013-03-31 19:58:10 CEST] read: git [\"--git-dir=/home/zerodogg/Documents/annexed/.git\",\"--work-tree=/home/zerodogg/Documents/annexed\",\"log\",\"refs/heads/git-annex..21a6361e598efd80e851276c17249e5c3284713f\",\"--oneline\",\"-n1\"]
+ [2013-03-31 19:58:10 CEST] read: git [\"--git-dir=/home/zerodogg/Documents/annexed/.git\",\"--work-tree=/home/zerodogg/Documents/annexed\",\"log\",\"refs/heads/git-annex..3c2f44ffd82df1a0ae8858bdf2610e933b105a09\",\"--oneline\",\"-n1\"]
+"""]]
diff --git a/doc/bugs/Selfsigned_certificates_with_jabber_fail_miserably..mdwn b/doc/bugs/Selfsigned_certificates_with_jabber_fail_miserably..mdwn
new file mode 100644
index 000000000..86e93e1ad
--- /dev/null
+++ b/doc/bugs/Selfsigned_certificates_with_jabber_fail_miserably..mdwn
@@ -0,0 +1,22 @@
+### Please describe the problem.
+Entering a jabber address which's server got a selfsigned certificate, the process just fails, without asking for acceptance for that certificate. This is quite a showstopper.
+(for example: jabber.ccc.de)
+
+
+### What steps will reproduce the problem?
+Try with an account from e.g. jabber.ccc.de
+
+
+### What version of git-annex are you using? On what operating system?
+Arch Linux, aur/git-annex-standalone 4.20130709-1
+
+### Please provide any additional information below.
+There is no logoutput to add... I'm sorry.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
diff --git a/doc/bugs/Selfsigned_certificates_with_jabber_fail_miserably./comment_1_13d27ba41d9ef78c8db534b6bc26314e._comment b/doc/bugs/Selfsigned_certificates_with_jabber_fail_miserably./comment_1_13d27ba41d9ef78c8db534b6bc26314e._comment
new file mode 100644
index 000000000..a591b51e1
--- /dev/null
+++ b/doc/bugs/Selfsigned_certificates_with_jabber_fail_miserably./comment_1_13d27ba41d9ef78c8db534b6bc26314e._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.90"
+ subject="comment 1"
+ date="2013-07-16T17:33:23Z"
+ content="""
+Hmm, actually the XMPP library it's using does not fail on an invalid or self-signed cert. This is something that SSL using libraries sadly often get wrong, and yeah, I see I contacted the library author a while ago, and a \"sessionIsSecure\" has been added to it, which can be used to check if the cert was valid.
+
+This leaves open the question of what's happening with you on the CCC server. Did you get an error message?
+
+
+"""]]
diff --git a/doc/bugs/Selfsigned_certificates_with_jabber_fail_miserably./comment_2_018eed99e71680be9e7c0844020419bb._comment b/doc/bugs/Selfsigned_certificates_with_jabber_fail_miserably./comment_2_018eed99e71680be9e7c0844020419bb._comment
new file mode 100644
index 000000000..9caee8a73
--- /dev/null
+++ b/doc/bugs/Selfsigned_certificates_with_jabber_fail_miserably./comment_2_018eed99e71680be9e7c0844020419bb._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.90"
+ subject="comment 2"
+ date="2013-07-16T17:42:42Z"
+ content="""
+Actually, sessionIsSecure only tells me if it's using SSL at all; still waiting on the XMPP library to add cert checking..
+"""]]
diff --git a/doc/bugs/Selfsigned_certificates_with_jabber_fail_miserably./comment_3_1e7578dd1321f399b12197056495b0b6._comment b/doc/bugs/Selfsigned_certificates_with_jabber_fail_miserably./comment_3_1e7578dd1321f399b12197056495b0b6._comment
new file mode 100644
index 000000000..62d723c7b
--- /dev/null
+++ b/doc/bugs/Selfsigned_certificates_with_jabber_fail_miserably./comment_3_1e7578dd1321f399b12197056495b0b6._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://launchpad.net/~psycojoker"
+ nickname="psycojoker"
+ subject="comment 3"
+ date="2013-11-25T09:54:33Z"
+ content="""
+Just to confirm that I'm also affected. Maybe you should add the possibility in the error message next to \"is the password correct?\".
+"""]]
diff --git a/doc/bugs/Should_UUID__39__s_for_Remotes_be_case_sensitive__63__.txt b/doc/bugs/Should_UUID__39__s_for_Remotes_be_case_sensitive__63__.txt
new file mode 100644
index 000000000..7eaf2a71b
--- /dev/null
+++ b/doc/bugs/Should_UUID__39__s_for_Remotes_be_case_sensitive__63__.txt
@@ -0,0 +1,46 @@
+> git annex status
+supported backends: SHA256E SHA1E SHA512E SHA224E SHA384E SHA256 SHA1 SHA512 SHA224 SHA384 WORM URL
+supported remote types: git gcrypt S3 bup directory rsync web webdav glacier hook
+repository mode: indirect
+trusted repositories: 0
+semitrusted repositories: 8
+ 00000000-0000-0000-0000-000000000001 -- web
+ 44AF00F1-511F-4902-8235-DFF741B09400 -- here
+ 44af00f1-511f-4902-8235-dff741b09400 -- chrissy
+ 53499200-CA18-4B51-B6B3-651C18208349 -- stevedave
+ 56C56658-0995-4613-8A1B-B2FA534A834C -- olaf
+ 8FE9B19F-4FC8-4CFA-AD89-4B70EB432EDC -- passport
+ AFC75641-B34A-4644-B566-C8D3127823F7 -- glacier
+ B3238A12-D81B-40EA-BE89-3BDB318AE2B7 -- brodie
+untrusted repositories: 0
+transfers in progress: none
+available local disk space: 78.8 gigabytes (+1 gigabyte reserved)
+local annex keys: 3915
+local annex size: 81.37 gigabytes
+known annex keys: 5728
+known annex size: 641.36 gigabytes
+bloom filter size: 16 mebibytes (0.8% full)
+backend usage:
+ SHA256E: 8716
+ URL: 927
+
+> git annex version
+git-annex version: 4.20130909
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV FsEvents XMPP DNS Feeds Quvi
+local repository version: 3
+default repository version: 3
+supported repository versions: 3 4
+upgrade supported from repository versions: 0 1 2
+
+> git-annex intentionally treats UUIDs as opaque strings,
+> so it is not going to go to any bother to consider
+> different byte sequences to be the same UUID, sorry.
+> (The standard may be arbitrarily complicated, but I have arbitrarily
+> decided to ignore it.)
+>
+> Since git-annex only ever generates each UUID once, and copies
+> the exact sequence of bytes as necessary, the only way the situation
+> you show above can happen is if you have manually gone in and entered
+> UUIDs in two different cases.
+>
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/Should_UUID__39__s_for_Remotes_be_case_sensitive__63__/comment_1_00b52dba3bc30516e06c44cbfd3a05a2._comment b/doc/bugs/Should_UUID__39__s_for_Remotes_be_case_sensitive__63__/comment_1_00b52dba3bc30516e06c44cbfd3a05a2._comment
new file mode 100644
index 000000000..b1417816f
--- /dev/null
+++ b/doc/bugs/Should_UUID__39__s_for_Remotes_be_case_sensitive__63__/comment_1_00b52dba3bc30516e06c44cbfd3a05a2._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 1"
+ date="2013-09-12T09:44:54Z"
+ content="""
+There does not seem to be an actual bug description in here. Can you provide more info?
+
+To answer the actual question: RFC 4122 clearly answers no:
+
+ Each field is treated as an integer and has its value printed as a
+ zero-filled hexadecimal digit string with the most significant
+ digit first. The hexadecimal values \"a\" through \"f\" are output as
+ lower case characters and are case insensitive on input.
+
+Yes, that means that git-annex prints them wrongly as that's upper case.
+"""]]
diff --git a/doc/bugs/Should_UUID__39__s_for_Remotes_be_case_sensitive__63__/comment_2_8f5fa659c2ab91b1757bac31cd3b15eb._comment b/doc/bugs/Should_UUID__39__s_for_Remotes_be_case_sensitive__63__/comment_2_8f5fa659c2ab91b1757bac31cd3b15eb._comment
new file mode 100644
index 000000000..f07a7bf9d
--- /dev/null
+++ b/doc/bugs/Should_UUID__39__s_for_Remotes_be_case_sensitive__63__/comment_2_8f5fa659c2ab91b1757bac31cd3b15eb._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 2"
+ date="2013-09-12T09:49:56Z"
+ content="""
+What OS are you using?
+
+versions 4.20130827 and 4.20130911 on Debian Sid print UUIDs which are lower case, as should be expected.
+"""]]
diff --git a/doc/bugs/Should_UUID__39__s_for_Remotes_be_case_sensitive__63__/comment_3_ccf9623d60c58d036d8bf24757e50de3._comment b/doc/bugs/Should_UUID__39__s_for_Remotes_be_case_sensitive__63__/comment_3_ccf9623d60c58d036d8bf24757e50de3._comment
new file mode 100644
index 000000000..76f6c0742
--- /dev/null
+++ b/doc/bugs/Should_UUID__39__s_for_Remotes_be_case_sensitive__63__/comment_3_ccf9623d60c58d036d8bf24757e50de3._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmRFKwny4rArBaz-36xTcsJYqKIgdDaw5Q"
+ nickname="Andrew"
+ subject="comment 3"
+ date="2013-09-12T16:24:30Z"
+ content="""
+This is on OSX 10.8.4
+
+If you look at the remote \"chrissy\" and \"here\" they are the same uuid, but with different case.
+"""]]
diff --git a/doc/bugs/Should_ignore_.thumbnails__47___on_android.mdwn b/doc/bugs/Should_ignore_.thumbnails__47___on_android.mdwn
new file mode 100644
index 000000000..30dc5caee
--- /dev/null
+++ b/doc/bugs/Should_ignore_.thumbnails__47___on_android.mdwn
@@ -0,0 +1,28 @@
+### Please describe the problem.
+
+When creating a Camera repository on android, the .thumbnails/ directory (containing useless crushed JPGs and even more useless oodles of thumbnail metadata databases) is annexed. This leads to confusion (assistant tries to annex database and thumbnails in modification) and waste (uploading/annexing unusable/unneeded metadata).
+
+### What steps will reproduce the problem?
+
+Install git-annex on Android and choose the defaults for a camera repository.
+
+
+### What version of git-annex are you using? On what operating system?
+
+4.20130601, Android 4.2.2
+
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
+
+> I've [[done]] this, however the .gitignore file it writes will
+> not actually be used by the assistant until it gets support
+> for querying gitignore settings from git. There is already a
+> bug tracking that, and it's in process. --[[Joey]]
diff --git a/doc/bugs/Should_try_again_when_network_fails___40__esp._DNS__41__.mdwn b/doc/bugs/Should_try_again_when_network_fails___40__esp._DNS__41__.mdwn
new file mode 100644
index 000000000..988f986e5
--- /dev/null
+++ b/doc/bugs/Should_try_again_when_network_fails___40__esp._DNS__41__.mdwn
@@ -0,0 +1,50 @@
+### Please describe the problem.
+
+If you have a flaky connection big uploads and downloads will fail. git-annex should try again few times.
+
+This is an example of failed download.
+
+[[!format sh """
+$ git annex get --not --in here
+get File1.bin (from s3...) (gpg)
+You need a passphrase to unlock the secret key for
+user: "Gioele"
+4096-bit RSA key, ....
+
+gpg: gpg-agent is not available in this session
+
+ ErrorMisc "<socket: 14>: hGetBuf: resource vanished (Connection reset by peer)"
+
+ Unable to access these remotes: s3
+
+ Try making some of these repositories available:
+ 331fa184-799d-4511-1725-ef2a17ace8b4 -- s3
+ c2a0cfa0-8871-9721-9b81-5649281fabdc -- other
+failed
+get File2.bin (from s3...)
+
+ Unable to access these remotes: s3
+
+ Try making some of these repositories available:
+ 331fa184-799d-4511-1725-ef2a17ace8b4 -- s3
+ c2a0cfa0-8871-9721-9b81-5649281fabdc -- other
+failed
+git-annex: get: 2 failed
+"""]]
+
+This is especially annoying when the DNS is out of order for a few seconds every now and then. In such cases, git-annex will complain, skip very fast to the next file, and repeat this process until it runs out of files. In the end it will have uploaded or downloaded very few files.
+
+Please not that it may not possible to write a simple shell loop to try again as the are GPG passwords to be entered.
+
+Git-annex should try again to upload or download a file in case something goes wrong.
+
+### What version of git-annex are you using? On what operating system?
+
+ git-annex version: 4.20130709.1
+ build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP
+ local repository version: unknown
+ default repository version: 3
+ supported repository versions: 3 4
+ upgrade supported from repository versions: 0 1 2
+
+Ubuntu 12.04.2 LTS
diff --git a/doc/bugs/Should_try_again_when_network_fails___40__esp._DNS__41__/comment_1_dd792bd98a48554a65150c06401ed3e5._comment b/doc/bugs/Should_try_again_when_network_fails___40__esp._DNS__41__/comment_1_dd792bd98a48554a65150c06401ed3e5._comment
new file mode 100644
index 000000000..620f5e82e
--- /dev/null
+++ b/doc/bugs/Should_try_again_when_network_fails___40__esp._DNS__41__/comment_1_dd792bd98a48554a65150c06401ed3e5._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.90"
+ subject="comment 1"
+ date="2013-07-17T18:54:47Z"
+ content="""
+Trying again one time does not seem like it would help, given the example you show. Trying multiple times by default would, I think, be annoying in lots of use cases where one just wants to get whatever is available, and having it get stuck retrying to download a file from a remote that is offline would not be desired when it could move on and get another file from a remote that is online.
+
+I'm willing to consider some kind of option to control how much it retries on error. But I'm not 100% sold on it being better than a simple loop. At least in most cases, using a gpg agent and a loop would work. I suppose the case it would not work as well is if enough time has elapsed for the gpg agent to re-lock the key.
+
+One approach that might work well is to add a --retry-failures-at-end option. It turns out that all failed downloads are already logged (the assistant uses this to automatically retry them), and so it would be easy to add. And rather than retrying immediately after a failure, when transferring multiple files, this puts some space in between, in which the problem may correct itself.
+"""]]
diff --git a/doc/bugs/Small_archive_behaving_like_archive.mdwn b/doc/bugs/Small_archive_behaving_like_archive.mdwn
new file mode 100644
index 000000000..384a75baf
--- /dev/null
+++ b/doc/bugs/Small_archive_behaving_like_archive.mdwn
@@ -0,0 +1,33 @@
+### Please describe the problem.
+
+repos of group smallarchive have started trying to accumulate all files.
+
+I have an archive repo (rsync) and a smallarchive repo (glacier). The assistant is now trying to transfer everything up to glacier. This is new behavior as of this version of annex.
+
+### What steps will reproduce the problem?
+
+
+### What version of git-annex are you using? On what operating system?
+
+Mac OSX 10.8.3 (Build 12D78)
+
+ git-annex version: 4.20130501-ged2fc6f
+
+ local repository version: 4
+ default repository version: 3
+ supported repository versions: 3 4
+ upgrade supported from repository versions: 0 1 2
+ build flags: Assistant Webapp Pairing Testsuite S3 WebDAV FsEvents XMPP DNS
+
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/debug.log
+
+
+# End of transcript or log.
+"""]]
+
+[[!tag moreinfo]]
diff --git a/doc/bugs/Small_archive_behaving_like_archive/comment_1_718dc246cbbbeae04436fa033011ab12._comment b/doc/bugs/Small_archive_behaving_like_archive/comment_1_718dc246cbbbeae04436fa033011ab12._comment
new file mode 100644
index 000000000..dd509cdde
--- /dev/null
+++ b/doc/bugs/Small_archive_behaving_like_archive/comment_1_718dc246cbbbeae04436fa033011ab12._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-05-06T21:09:00Z"
+ content="""
+I have tested smallarchive and do not see any bug with its operation. Files not in an `archive` directory are not sent to the smallarchive repository. Files in `archive` directories are, unless they have already been sent to some other archive repository.
+
+There has, however, been a recent change that could have led you to see a change in behavior, though not one that is really a bug:
+Now smallarchive repositories will accept any content if it's only located on repositories that are untrusted or dead. So for example if your main client repo is for some reason marked as untrusted, the glacier repo would assume it's going away, and accept content from it.
+
+If that's not the explanation, you will need to provide more details..
+"""]]
diff --git a/doc/bugs/Specifying_a_filename_starting_with___34__-c__34___instead_applies_it_to_all_files.mdwn b/doc/bugs/Specifying_a_filename_starting_with___34__-c__34___instead_applies_it_to_all_files.mdwn
new file mode 100644
index 000000000..52db9e0ae
--- /dev/null
+++ b/doc/bugs/Specifying_a_filename_starting_with___34__-c__34___instead_applies_it_to_all_files.mdwn
@@ -0,0 +1,75 @@
+### Please describe the problem.
+Trying to apply certain commands - such as 'drop' - to a filename which starts with "-c" instead applies it to all files. In the instance where I found this, I was using "drop --force" and it caused it to indiscriminately get rid of everything in the directory instead of a single file.
+
+### What steps will reproduce the problem?
+1. Make a repository.
+2. Create several files and add them.
+3. Create a file whose name begins with "-c" and add it as well.
+4. Run "git annex drop <fname>" where 'fname' is the file from that last step.
+
+### What version of git-annex are you using? On what operating system?
+4.20130516-gedc4ccd on Arch Linux
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+[user@host ~]$ mkdir annex_test
+[user@host ~]$ cd annex_test/
+[user@host annex_test]$ ls
+[user@host annex_test]$ git init
+Initialized empty Git repository in /home/user/annex_test/.git/
+[user@host annex_test]$ git annex init "test"
+init test ok
+(Recording state in git...)
+[user@host annex_test]$
+[user@host annex_test]$ echo foo > foo
+[user@host annex_test]$ echo bar > bar
+[user@host annex_test]$ echo baz > baz
+[user@host annex_test]$ echo test > "-c-test"
+[user@host annex_test]$ git annex add *
+add bar (checksum...) ok
+add baz (checksum...) ok
+add foo (checksum...) ok
+(Recording state in git...)
+[user@host annex_test]$ git annex add -c-test
+add -c-test (checksum...) ok
+(Recording state in git...)
+[user@host annex_test]$ git annex drop -c-test
+drop -c-test (unsafe)
+ Could only verify the existence of 0 out of 1 necessary copies
+
+ Rather than dropping this file, try using: git annex move
+
+ (Use --force to override this check, or adjust annex.numcopies.)
+failed
+drop bar (unsafe)
+ Could only verify the existence of 0 out of 1 necessary copies
+
+ Rather than dropping this file, try using: git annex move
+
+ (Use --force to override this check, or adjust annex.numcopies.)
+failed
+drop baz (unsafe)
+ Could only verify the existence of 0 out of 1 necessary copies
+
+ Rather than dropping this file, try using: git annex move
+
+ (Use --force to override this check, or adjust annex.numcopies.)
+failed
+drop foo (unsafe)
+ Could only verify the existence of 0 out of 1 necessary copies
+
+ Rather than dropping this file, try using: git annex move
+
+ (Use --force to override this check, or adjust annex.numcopies.)
+failed
+git-annex: drop: 4 failed
+
+
+# End of transcript or log.
+"""]]
+
+> Closing, as this is basically user error. [[done]] --[[Joey]]
diff --git a/doc/bugs/Specifying_a_filename_starting_with___34__-c__34___instead_applies_it_to_all_files/comment_1_2fe6d735bc075275a6b8890fac48ee58._comment b/doc/bugs/Specifying_a_filename_starting_with___34__-c__34___instead_applies_it_to_all_files/comment_1_2fe6d735bc075275a6b8890fac48ee58._comment
new file mode 100644
index 000000000..39a469933
--- /dev/null
+++ b/doc/bugs/Specifying_a_filename_starting_with___34__-c__34___instead_applies_it_to_all_files/comment_1_2fe6d735bc075275a6b8890fac48ee58._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-06-10T20:30:27Z"
+ content="""
+This is the same as trying to rm a file named `-rf`
+
+In git-annex, as in git, -c sets a git configuration option. The text after the -c is supposed to be the option name and value. So -c-test is a valid command-line option.
+
+This leaves `git annex drop`, with no files specified to drop. As documented, git-annex commands default to acting on all relevant files in the current directory and subdirectories.
+
+Luckily, drop does check that numcopies other remotes have the file, so unless you also have a file named --force, you're not going to lose data doing this.
+
+I don't see any change I could make to prevent this kind of mistake. I checked and git also treats \"-c -test\" as valid input, despite \"-test\" not being a likely git config key (and no value being specified). I could make git-annex's option parser require the space between option and value (which git does require), which would perhaps reduce the set of files whose names are valid options.
+
+Fundamentally, this is a type of mistake that the design of unix command options allows to happen, if people use filenames starting with dashes -- so people generally don't do that. It's worth noting that git-annex is *very* careful itself, whenever passing a filename to a unix command, to check if it starts with a dash, and use \"./-file\" instead!
+"""]]
diff --git a/doc/bugs/Stale_lock_files_on_Android.mdwn b/doc/bugs/Stale_lock_files_on_Android.mdwn
new file mode 100644
index 000000000..b3451a153
--- /dev/null
+++ b/doc/bugs/Stale_lock_files_on_Android.mdwn
@@ -0,0 +1,44 @@
+### Please describe the problem.
+
+Both my Android devices where not processing git-annex updates due to stale lock files. While the lock files are different, I've reported them both together as they are related.
+
+### What steps will reproduce the problem?
+
+Unknown, perhaps the assistant crashed, or the battery ran flat on them.
+
+To resolve the issue I had to manually remove the lock files.
+
+### What version of git-annex are you using? On what operating system?
+
+On my Android phone, daily build 4.20130614-g221aea4
+On my Android tablet, daily build 4.20130621-g36258de
+
+### Please provide any additional information below.
+
+It seems to me that it'd be useful to have the assistant check to see if the lock files are still valid and remove them if they're stale.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+My phone:
+
+From ssh://git-annex-flick-andrewannex_phonecamera/~/phone-camera
+ 987dc25..682cdd1 git-annex -> flick_phonecamera/git-annex
+fatal: Unable to create '/storage/emulated/legacy/DCIM/.git/refs/remotes/flick_phonecamera/synced/git-annex.lock': File exists.
+
+My tablet:
+
+Committer: Adding Coleman-C..eedom.pdf
+Committer: Committing changes to git
+fatal: Unable to create '/mnt/sdcard/reference/.git/index.lock': File exists.
+
+# End of transcript or log.
+"""]]
+
+> The '/mnt/sdcard/reference/.git/index.lock' lock file will now be
+> automatically dealt with. Have not done anything about the refs/remotes
+> lock files yet. --[[Joey]]
+>
+> Now the assistant deals with all stale git lock files on startup.
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/Stress_test.mdwn b/doc/bugs/Stress_test.mdwn
new file mode 100644
index 000000000..3bc701bbd
--- /dev/null
+++ b/doc/bugs/Stress_test.mdwn
@@ -0,0 +1,45 @@
+What steps will reproduce the problem?
+
+mkdir annex_stress; cd annex_stress,
+then execute the following script:
+
+ #! /bin/sh
+
+ # creating a directory, in which we dump all the files.
+ mkdir probes; cd probes
+
+ for i in `seq -w 1 25769`; do
+ mkdir probe$i
+ echo "This is an important file, which saved also in backup ('back') directory too.\n Content changes: $i" > probe$i/probe$i.txt
+ echo "This is just an identical content file. Saved in each subdir." > probe$i/defaults.txt
+ echo "This is a variable ($i) content file, which is not backed up in 'back' directory." > probe$i/probe-nb$i.txt
+ mkdir probe$i/back
+ cp probe$i/probe$i.txt probe$i/back/probe$i.txt
+ done
+
+
+It creates about 25000 directory and 3 files in each, two of them are identical.
+
+What is the expected output? What do you see instead?
+
+I expect git annex could import the directory within 12 hours.
+Yet, it just crashes the gui (starting webapp, uses the cpu 100% and it does not finish after 28hours.)
+
+
+What version of git-annex are you using? On what operating system?
+
+version 2013.04.17
+
+Please provide any additional information below.
+
+I do hope git-annex can be fixed to handle large number of files.
+This stress test models well enough my own directory structure,
+relatively high number of files relatively low disk space usage
+(my own directory structure: 750MB, this test creates 605MB).
+
+
+Best,
+ Laszlo
+
+[[!meta title="assistant Stress test"]]
+[[!tag /design/assistant]]
diff --git a/doc/bugs/Stress_test/comment_10_1694e990eab6592159309c231c6dcc16._comment b/doc/bugs/Stress_test/comment_10_1694e990eab6592159309c231c6dcc16._comment
new file mode 100644
index 000000000..ec50b58c5
--- /dev/null
+++ b/doc/bugs/Stress_test/comment_10_1694e990eab6592159309c231c6dcc16._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 10"
+ date="2013-05-06T16:54:36Z"
+ content="""
+My estimate was indeed slightly optimistic. While I did not run the whole import, it did run slower for the later batches of files. As far as I can see, that slowdown is just because git gets slower as it has more files. So nothing I can do about it. git-annex is now scaling well itself, though.
+
+Re checksumming on startup: There was a bug that caused the assistant to re-checksum all direct mode files on startup. This bug was fixed in version 4.20130417. If you're using that version and still see it re-checksumming files, please file a new bug report about it, as this is not intended behavior.
+
+You seem to be saying that the assistant is failing to add some files, and then when stopped and restarted it finds and adds them. I don't quite know how that would happen. If you can provide a test case that I can use to reproduce that behavior, I will try to debug it.
+"""]]
diff --git a/doc/bugs/Stress_test/comment_11_ab4cb6eefd279e6c1f229e089f703581._comment b/doc/bugs/Stress_test/comment_11_ab4cb6eefd279e6c1f229e089f703581._comment
new file mode 100644
index 000000000..05c409a51
--- /dev/null
+++ b/doc/bugs/Stress_test/comment_11_ab4cb6eefd279e6c1f229e089f703581._comment
@@ -0,0 +1,25 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="comment 11"
+ date="2013-05-11T05:36:48Z"
+ content="""
+rechecksuming: it seem like it is indeed fixed in the newest (2013.05.01) version downloaded from here:
+http://downloads.kitenet.net/git-annex/linux/
+
+I tried to add the big stress test dir as a secondary repository into git-annex (along with my real data dir), but
+seems like some library is not matching on my system, so some curl is complaining:
+
+ curl: /lib/tls/i686/cmov/libc.so.6: version `GLIBC_2.12' not found (required by /home/user/Desktop/down/git-annex.linux//usr/lib/i386-linux-gnu/libldap_r-2.4.so.2)
+
+I'm on ubuntu 10.04.
+
+And the log file is starting to fill up, so maybe once a problem occur, it should only write into the log file once.
+
+I will redone this stress test next week, without combining with any repository.
+Thank you very much for your response, I do appreciate you are bothering/dealing with my complains!:)
+
+Best,
+ Laszlo
+
+"""]]
diff --git a/doc/bugs/Stress_test/comment_1_c4c764488ac082f5c48d3a6b4b5fba42._comment b/doc/bugs/Stress_test/comment_1_c4c764488ac082f5c48d3a6b4b5fba42._comment
new file mode 100644
index 000000000..42750808b
--- /dev/null
+++ b/doc/bugs/Stress_test/comment_1_c4c764488ac082f5c48d3a6b4b5fba42._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-04-23T20:00:31Z"
+ content="""
+Is this related or unrelated to the bug you filed at [[Resource_exhausted]]?
+
+I tried this test, and noticed that it was taking the assistant rather a long time to get to the 10 thousand file threshhold where it makes a batch commit. A small change to a better data structure for its queue reduced that time from probably 10 minutes to 2.5.
+
+I was unable to reproduce any problem with the webapp. Please provide lots of details to back up \"it just crashes the GUI\".
+
+The main problem with this directory tree is that it has more directories than inotify can watch, in the default configuration.
+So after it adds the first 8192 directories, it begins failing to watch any more, and printing a message about you needing to increase the inotify limits for each additional directory. I don't think that 51 thousand directories is a particularly realistic amount for any real-world usage of git-annex. (It will also break file manager, dropbox, etc, which all use inotify in the same way.)
+
+The other main time sink is that git-annex needs to run `git hash-object` once per file to stage its symlink. That is a lot of processes to run, and perhaps it could be sped up by using `git fast-import`.
+"""]]
diff --git a/doc/bugs/Stress_test/comment_2_42125bba09a0ea9821cda7183e458100._comment b/doc/bugs/Stress_test/comment_2_42125bba09a0ea9821cda7183e458100._comment
new file mode 100644
index 000000000..26ffe2d62
--- /dev/null
+++ b/doc/bugs/Stress_test/comment_2_42125bba09a0ea9821cda7183e458100._comment
@@ -0,0 +1,47 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="comment 2"
+ date="2013-04-24T06:30:16Z"
+ content="""
+Hi,
+
+First of all thank you for your time looking into my bug. I try to research more from my side.
+
+The 'Resource exhausted' bugreport
+(which lost its title, and could not click on it to add this testcase as a comment)
+was tested on real data, my own working directory (a copy of it).
+This bugreport is tested on the output of this small shell script.
+
+None of them succeeded to import, and I quickly assumed it is the exact same.
+
+So I will test again, raising the ulimit to 81920, and report.
+
+ The main problem with this directory tree is that it has more directories than inotify can watch, in the default configuration
+
+I would be perfectly fine if I could configure git-annex to sync those directory only once a month or once a week
+(ie. check for update once a week). So no need to watch it real time, those are my archived work files.
+
+ I don't think that 51 thousand directories is a particularly realistic amount for any real-world usage of git-annex.
+
+Well, it is not 25000 dir in a single a folder, but rather something like this:
+
+ work_done/2009/workname/back9/back8/back7/back6/back5
+
+Where each 'backX' contains a whole backup the work until it.
+So the directory structure is a bit more deep, and no 25000 subdirectory in a single dir.
+But the overall numbers are right.
+
+If I could somehow mark this **work_done** dir to not sync real time (or work_done/2008,work_done/2009,work_done/2010,work_done/2011,work_done/2012 subdir in them),
+then my whole issue would vanish.
+
+I only want to use git-annex to have a backup of this directory.
+In case of laptop theft, or misfunction I could have a backup.
+I dont need live sync anywhere, I have directories which I know I will not touch for months.
+
+Best,
+ Laszlo
+
+
+
+"""]]
diff --git a/doc/bugs/Stress_test/comment_3_8240e61106b494d3600ad91f16eb5b1c._comment b/doc/bugs/Stress_test/comment_3_8240e61106b494d3600ad91f16eb5b1c._comment
new file mode 100644
index 000000000..8469f489f
--- /dev/null
+++ b/doc/bugs/Stress_test/comment_3_8240e61106b494d3600ad91f16eb5b1c._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="comment 3"
+ date="2013-04-24T09:10:20Z"
+ content="""
+ (It will also break file manager, dropbox, etc, which all use inotify in the same way.)
+
+I beg to differ: with dropbox I handle my scrapbook(1) folder,
+which means 130 thousand files for over 2 years now without problem between three computers.
+
+ ~/Dropbox/scrapbook$ ls -R -1 |wc -l
+ 130263
+
+Don't get me wrong. I'm not complaining, I only give you a completely unrelated usecase,
+which requires also high number of files handling. And in that case the 81 thousand ulimit would not help either.
+
+(1): https://addons.mozilla.org/hu/firefox/addon/scrapbook/
+
+"""]]
diff --git a/doc/bugs/Stress_test/comment_4_c38d84e0dcc834931804c44bce7f7b7a._comment b/doc/bugs/Stress_test/comment_4_c38d84e0dcc834931804c44bce7f7b7a._comment
new file mode 100644
index 000000000..c7cdd4bfd
--- /dev/null
+++ b/doc/bugs/Stress_test/comment_4_c38d84e0dcc834931804c44bce7f7b7a._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 4"
+ date="2013-04-24T15:05:33Z"
+ content="""
+You're confusing number of files (inotify doesn't care) with number of directories (inotify does care).
+
+Dropbox is on record about being limited in the number of directories it can watch without adjusting the inotify limit.
+<https://www.dropbox.com/help/145>
+"""]]
diff --git a/doc/bugs/Stress_test/comment_5_60ce20ee255451c4ea809ba475561adb._comment b/doc/bugs/Stress_test/comment_5_60ce20ee255451c4ea809ba475561adb._comment
new file mode 100644
index 000000000..820f04ba9
--- /dev/null
+++ b/doc/bugs/Stress_test/comment_5_60ce20ee255451c4ea809ba475561adb._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 5"
+ date="2013-04-24T15:30:04Z"
+ content="""
+I found a bug in the webapp thanks to this stress test. When inotify goes over limit, it displays a message about how to fix it..
+But it displays that message over and over for each file. The result is a constantly updating very large web page.
+
+Unless you tell me differently, I'm going to assume that's what the GUI crash you referred to was, since it can make a web browser very slow.
+
+I've fixed this problem. Now when it goes over limit, the webapp will just display this:
+
+[[/assistant/inotify_max_limit_alert.png]]
+"""]]
diff --git a/doc/bugs/Stress_test/comment_6_1371562e201393986cd41597f6f288cb._comment b/doc/bugs/Stress_test/comment_6_1371562e201393986cd41597f6f288cb._comment
new file mode 100644
index 000000000..26f14ef09
--- /dev/null
+++ b/doc/bugs/Stress_test/comment_6_1371562e201393986cd41597f6f288cb._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 6"
+ date="2013-04-24T17:26:39Z"
+ content="""
+I put in a further change to reduce the number of alerts shown in the webapp when bulk adding files. This probably quadrupled the speed or more, even when the webapp was not running, as updating an alert every time a file was added was a lot of unnecessary work.
+
+After these changes, it adds the first 10 thousand files in 35 minutes, on my five year old netbook. It should scale linear
+(aside from git's own scalability issues with a lot of files, which I don't think are very bad under 1 million files),
+so adding all 100 thousand files should take 6 hours or so.
+
+I'm interested to see what results you get, compared with before..
+"""]]
diff --git a/doc/bugs/Stress_test/comment_7_a14be7699da224a8f6c9b34f1b911219._comment b/doc/bugs/Stress_test/comment_7_a14be7699da224a8f6c9b34f1b911219._comment
new file mode 100644
index 000000000..3d02a2718
--- /dev/null
+++ b/doc/bugs/Stress_test/comment_7_a14be7699da224a8f6c9b34f1b911219._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 7"
+ date="2013-04-24T21:02:55Z"
+ content="""
+A few more changes got the rate down to 21 minutes per 10 thousand files. Estimate 3.5 hours for all.
+"""]]
diff --git a/doc/bugs/Stress_test/comment_8_a01995bdca7ade7dde9842b53fbc4e0c._comment b/doc/bugs/Stress_test/comment_8_a01995bdca7ade7dde9842b53fbc4e0c._comment
new file mode 100644
index 000000000..d12b7ebfe
--- /dev/null
+++ b/doc/bugs/Stress_test/comment_8_a01995bdca7ade7dde9842b53fbc4e0c._comment
@@ -0,0 +1,57 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="Definite improvement"
+ date="2013-05-03T06:27:12Z"
+ content="""
+Hi,
+
+I have just tried it out again with the latest (20130501) version.
+
+It is really nice to see you have been working on it, and it have improved tremendously!
+The logging issue solved, and logrotates even, and it finished importing without crashing!
+
+Remaining polishing things:
+
+a)
+The import time is not as good (as you write), it slowes itself down.
+It is true the first 10000 files import in about an hour, but it finishes with everything
+in 9 hours 20 minutes.
+(on a normal laptop, the last 5000 file portion took more then 2 hours)
+
+b)
+Every startup means rechecksuming everything, so it means the second start took also around 8-12 hours.
+(I don't know exactly because it finished somewhere during the night, but it was longer then 8 hours)
+I don't think rechecksuming is necessary at all, if the filename, size and date have not modified,
+then why rechecksuming (sha) it?
+
+
+c)
+It is leaking.
+At the second startup, it reported it successfully added:
+ Added 2375 files 5 files probe25366.txt
+
+I have not touched the directory. ls confirms leaking:
+
+ After first start (importing):
+ annex_many/.git$ ls -lR |wc -l
+ 770199
+
+ After second startup:
+ annex_many/.git$ ls -lR |wc -l
+ 788351
+
+d) Without ulimit raise, it does not work at all.
+I think it could be solved by not watching each and every directory all the time.
+Every users will likely have a working directory and some which he don't intend to touch/modify at all.
+Some usecases: photo archiving, video archiving, finished work archiving, etc
+
+All the above results with the stress test script.
+I would love to have a confirmation by a thirdparty.
+
+Overall I'm impressed with the work you have done.
+
+Best,
+ Laszlo
+
+"""]]
diff --git a/doc/bugs/Stress_test/comment_9_9f7efe81b7e40aaa04a865394c53e20f._comment b/doc/bugs/Stress_test/comment_9_9f7efe81b7e40aaa04a865394c53e20f._comment
new file mode 100644
index 000000000..a82b98611
--- /dev/null
+++ b/doc/bugs/Stress_test/comment_9_9f7efe81b7e40aaa04a865394c53e20f._comment
@@ -0,0 +1,52 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="Maybe it is not leaking after all"
+ date="2013-05-03T18:37:48Z"
+ content="""
+I have been working the whole day zipping up (tar.gz) all the unused directories.
+Now my real data dir looks like this:
+
+ ./annex_real/work_done$ du -hs .
+ 1,1G .
+ Has 9088 files and 1608 directories in total:
+ ./annex_real/work_done$ ls -R1l |grep \\-r |wc -l
+ 9088
+ ./annex_real/work_done$ ls -R1l |grep ^d |wc -l
+ 1608
+
+When I first started git annex, it added 5492 files, then next time it added the missing 3596 files. Then it stopped adding files.
+From the gui everything looked fine even at the first start (performed startup scan), even in the log files (daemon.log.x) was nothing suspicious.
+
+ ./annex_real/work_done$ for i in ../.git/annex/daemon.log.*; do echo $i; cat $i |grep files; done
+ ../.git/annex/daemon.log.1
+ ../.git/annex/daemon.log.2
+ ../.git/annex/daemon.log.3
+ ../.git/annex/daemon.log.4
+ [2013-05-03 20:03:34 CEST] Committer: Adding 3596 files
+ ../.git/annex/daemon.log.5
+ [2013-05-03 19:15:22 CEST] Committer: Adding 5492 files
+
+As you can see, this case is not a stress test at all,
+it is really the minimal test case, 1.1GB diskspace, 9088 files and a thousand dirs.
+The real question is, why git-annex miss at the first startup 3492 files (ie. adding all the files).
+
+It would help tremendously, if it would display at startup how many files he found,
+and when it adds, then how many left to be added.
+Something like this:
+
+ (scanning...) [2013-05-03 20:03:14 CEST] Watcher: Performing startup scan
+ (started...)
+ [2013-05-03 20:03:34 CEST] Committer: Found 9088 files
+ [2013-05-03 20:03:34 CEST] Committer: Adding 3596 files of 9088 remaining files (9088 in total)
+ ....
+ [2013-05-03 20:05:04 CEST] Committer: Adding 1492 files of 5492 remaining files (9088 in total)
+ ....
+ [2013-05-03 20:06:02 CEST] Committer: Adding 4000 files of 4000 remaining files (9088 in total)
+
+So it is definietly a bug, and I stuck how to debug it further. Everything looks just fine.
+
+Best,
+ Laszlo
+
+"""]]
diff --git a/doc/bugs/Switching_between_direct_and_indirect_stomps_on___39__regular__39___git_files.mdwn b/doc/bugs/Switching_between_direct_and_indirect_stomps_on___39__regular__39___git_files.mdwn
new file mode 100644
index 000000000..db1889f81
--- /dev/null
+++ b/doc/bugs/Switching_between_direct_and_indirect_stomps_on___39__regular__39___git_files.mdwn
@@ -0,0 +1,27 @@
+# What steps will reproduce the problem?
+
+ git add file
+ git annex add file2
+ git annex direct
+ git annex indirect
+
+file and file2 are now both in the annex.
+
+# What is the expected output? What do you see instead?
+
+file should remain in the main repo, file2 should remain in the annex
+
+# What version of git-annex are you using? On what operating system?
+
+ git-annex version: 4.20130228
+ local repository version: 3
+ default repository version: 3
+ supported repository versions: 3 4
+ upgrade supported from repository versions: 0 1 2
+
+ git version 1.8.1.5
+
+Mac OSX 10.8.2 Build 12C60
+
+> Closing this bug, as I cannot reproduce it and the bug reporter is
+> not responding. [[done]] --[[Joey]]
diff --git a/doc/bugs/Switching_between_direct_and_indirect_stomps_on___39__regular__39___git_files/comment_1_0d2cb3b8509cd0eba50aafa14afefc02._comment b/doc/bugs/Switching_between_direct_and_indirect_stomps_on___39__regular__39___git_files/comment_1_0d2cb3b8509cd0eba50aafa14afefc02._comment
new file mode 100644
index 000000000..d4afd95c4
--- /dev/null
+++ b/doc/bugs/Switching_between_direct_and_indirect_stomps_on___39__regular__39___git_files/comment_1_0d2cb3b8509cd0eba50aafa14afefc02._comment
@@ -0,0 +1,63 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-03-08T19:44:29Z"
+ content="""
+I cannot reproduce this using the steps given. Transcript:
+
+<pre>
+joey@gnu:~/tmp>mkdir test
+joey@gnu:~/tmp>cd test
+joey@gnu:~/tmp/test>git init
+Initialized empty Git repository in /home/joey/tmp/test/.git/
+joey@gnu:~/tmp/test>git annex init
+init ok
+(Recording state in git...)
+joey@gnu:~/tmp/test>echo file > file
+joey@gnu:~/tmp/test>echo file2 > file2
+joey@gnu:~/tmp/test>git add file
+joey@gnu:~/tmp/test>git annex add file2
+add file2 (checksum...) ok
+(Recording state in git...)
+joey@gnu:~/tmp/test>git annex direct
+commit
+[master (root-commit) 8d49cac] commit before switching to direct mode
+ 2 files changed, 2 insertions(+)
+ create mode 100644 file
+ create mode 120000 file2
+ok
+direct file2 ok
+direct ok
+joey@gnu:~/tmp/test>git annex indirect
+commit (Recording state in git...)
+
+ok
+# On branch master
+# Changes not staged for commit:
+# (use \"git add <file>...\" to update what will be committed)
+# (use \"git checkout -- <file>...\" to discard changes in working directory)
+#
+# typechange: file2
+#
+no changes added to commit (use \"git add\" and/or \"git commit -a\")
+ok
+indirect file2 ok
+indirect ok
+ok
+joey@gnu:~/tmp/test>ls
+file file2@
+joey@gnu:~/tmp/test>file file
+file: ASCII text
+joey@gnu:~/tmp/test>file file2
+file2: symbolic link to `.git/annex/objects/ZV/w4/SHA256E-s6--67ee5478eaadb034ba59944eb977797b49ca6aa8d3574587f36ebcbeeb65f70e/SHA256E-s6--67ee5478eaadb034ba59944eb977797b49ca6aa8d3574587f36ebcbeeb65f70e'
+joey@gnu:~/tmp/test>git log --oneline file
+8d49cac commit before switching to direct mode
+</pre>
+
+I even tried to reproduce the bug on a mac in case it was somehow only happening on that OS, but still, no go. `file` remains checked into git as a normal file, it is not annexed.
+
+`git annex indirect` does not touch files unless they have a symlink committed to git. The code is pretty clear about that.
+
+Please post a complete transcript that goes all the way from repository creation to the bug happening.
+"""]]
diff --git a/doc/bugs/Switching_from_indirect_mode_to_direct_mode_breaks_duplicates.mdwn b/doc/bugs/Switching_from_indirect_mode_to_direct_mode_breaks_duplicates.mdwn
new file mode 100644
index 000000000..55d2b13b9
--- /dev/null
+++ b/doc/bugs/Switching_from_indirect_mode_to_direct_mode_breaks_duplicates.mdwn
@@ -0,0 +1,30 @@
+#What steps will reproduce the problem?
+
+1. Create a new repository in indirect mode.
+
+2. Add the same file twice under a different name. Now you have two symlinks pointing to the same file under .git/annex/objects/
+
+3. Switch to direct mode. The first symlink gets replaced by the actual file. The second stays unchanged, pointing to nowhere. But git annex whereis still reports it has a copy.
+
+4. Delete the first file. Git annex whereis still thinks it has a copy of file 2, which is not true -> data loss.
+
+#What is the expected output? What do you see instead?
+
+When switching to direct mode, both symlinks should be replaced by a copy (or at least a hardlink) of the actual file.
+
+> The typo that caused this bug is fixed. --[[Joey]]
+
+#What version of git-annex are you using? On what operating system?
+
+3.20130107 on Arch Linux x64
+
+#Please provide any additional information below.
+
+The deduplication performed by git-annex is very dangerous in itself
+because files with identical content become replaced by references to the
+same file without the user necessarily being aware. Think of the user
+making a copy of a file, than modifying it. He would expect to end up with
+two files, the unchanged original and the modified copy. But what he really
+gets is two symlinks pointing to the same modified file.
+
+> I agree, it now copies rather than hard linking. [[done]] --[[Joey]]
diff --git a/doc/bugs/Switching_repositories_in_webapp_on_a_remote_server_is_not_honoring_--listen_parameter.mdwn b/doc/bugs/Switching_repositories_in_webapp_on_a_remote_server_is_not_honoring_--listen_parameter.mdwn
new file mode 100644
index 000000000..4829cde08
--- /dev/null
+++ b/doc/bugs/Switching_repositories_in_webapp_on_a_remote_server_is_not_honoring_--listen_parameter.mdwn
@@ -0,0 +1,21 @@
+### Please describe the problem.
+I am running my "origin" repositories on a headless server. Managing these with webapp --listen=<server IP>:<port> is a very conveniant way. Now I am creating more repositories for different content on the same server. When I try to switch the webapp between these repositories webapp gives me a link with 127.0.0.1:<random port> in the URL.
+
+### What steps will reproduce the problem?
+1. Start webapp on a remote system with --listen parameter.
+2. Add an existing (did not try for a new repository) manually created annex to the webapp using "add another local repository" (btw. file select dialog is also not working remotely)
+3. You get asked if you want to combine the new annex with the current or to keep them separate (--> keep them separate)
+4. You get forwarded to the new webapp instance but with a localhost address (127.0.0.1). The same address is also used when you manually try to swich between repositories using the repository menu.
+
+### What version of git-annex are you using? On what operating system?
+4.20130501 on Ubuntu precise from the rubiojr PPA repository
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/debug.log
+
+
+# End of transcript or log.
+"""]]
diff --git a/doc/bugs/Switching_repositories_in_webapp_on_a_remote_server_is_not_honoring_--listen_parameter/comment_1_4dd773372979dd95538bfba6516a11eb._comment b/doc/bugs/Switching_repositories_in_webapp_on_a_remote_server_is_not_honoring_--listen_parameter/comment_1_4dd773372979dd95538bfba6516a11eb._comment
new file mode 100644
index 000000000..37b43d548
--- /dev/null
+++ b/doc/bugs/Switching_repositories_in_webapp_on_a_remote_server_is_not_honoring_--listen_parameter/comment_1_4dd773372979dd95538bfba6516a11eb._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="marvin"
+ ip="91.152.75.65"
+ subject="Comfirm"
+ date="2013-07-28T19:42:38Z"
+ content="""
+I'm seeing this too. Debian sid package 4.20130723
+
+"""]]
diff --git a/doc/bugs/Syncing_creates_broken_links_instead_of_proper_files.mdwn b/doc/bugs/Syncing_creates_broken_links_instead_of_proper_files.mdwn
new file mode 100644
index 000000000..b10df810c
--- /dev/null
+++ b/doc/bugs/Syncing_creates_broken_links_instead_of_proper_files.mdwn
@@ -0,0 +1,51 @@
+What steps will reproduce the problem?
+
+Create two repositories by running git annex webapp. Sync them by linking them to the same xmpp account. Add files on both sides.
+
+What is the expected output? What do you see instead?
+
+I expect the same file to show up on both sides with the same contents. Instead adding a file on any side creates a broken link with the same name on the other side. For example:
+
+Side A:
+
+ $ ls -la
+ total 20
+ drwxrwxr-x 3 pedrocr pedrocr 4096 Jan 3 19:24 .
+ drwxr-xr-x 55 pedrocr pedrocr 4096 Jan 3 19:19 ..
+ lrwxrwxrwx 1 pedrocr pedrocr 178 Jan 3 19:22 bar -> .git/annex/objects/FQ/vV/SHA256E-s8--12a61f4e173fb3a11c05d6471f74728f76231b4a5fcd9667cef3af87a3ae4dc2/SHA256E-s8--12a61f4e173fb3a11c05d6471f74728f76231b4a5fcd9667cef3af87a3ae4dc2
+ lrwxrwxrwx 1 pedrocr pedrocr 178 Jan 3 19:20 foo -> .git/annex/objects/g7/9v/SHA256E-s4--7d865e959b2466918c9863afca942d0fb89d7c9ac0c99bafc3749504ded97730/SHA256E-s4--7d865e959b2466918c9863afca942d0fb89d7c9ac0c99bafc3749504ded97730
+ drwxrwxr-x 7 pedrocr pedrocr 4096 Jan 3 19:24 .git
+ -rw-r--r-- 1 pedrocr pedrocr 0 Jan 3 19:24 testing
+
+"foo" and "bar" are broken links that were created on Side B
+
+Side B:
+
+ $ ls -la
+ total 24
+ drwxrwxr-x 3 pedrocr pedrocr 4096 Jan 3 19:24 .
+ drwx------ 42 pedrocr pedrocr 4096 Jan 3 19:18 ..
+ -rw-r--r-- 1 pedrocr pedrocr 8 Jan 3 19:22 bar
+ -rw-r--r-- 1 pedrocr pedrocr 4 Jan 3 19:20 foo
+ drwxrwxr-x 7 pedrocr pedrocr 4096 Jan 3 19:24 .git
+ lrwxrwxrwx 1 pedrocr pedrocr 178 Jan 3 19:24 testing -> .git/annex/objects/pX/ZJ/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+
+In this case "testing" is a broken link and was created on Side A.
+
+What version of git-annex are you using? On what operating system?
+
+ $ ./git-annex version
+ git-annex version: 3.20130102
+
+ $ uname -a
+ Linux wintermute 3.2.0-35-generic #55-Ubuntu SMP Wed Dec 5 17:45:18 UTC 2012 i686 i686 i386 GNU/Linux
+
+ $ lsb_release -a
+ Distributor ID: Ubuntu
+ Description: Ubuntu 12.04.1 LTS
+ Release: 12.04
+ Codename: precise
+
+> [[done]]; the webapp now detects when XMPP pairing has been used but no
+> transfer remote is available, and prompts the user to create one.
+> --[[Joey]]
diff --git a/doc/bugs/Syncing_creates_broken_links_instead_of_proper_files/comment_1_a2bedb2e77451b02fc66fc9ef5c4405c._comment b/doc/bugs/Syncing_creates_broken_links_instead_of_proper_files/comment_1_a2bedb2e77451b02fc66fc9ef5c4405c._comment
new file mode 100644
index 000000000..146a9b1d6
--- /dev/null
+++ b/doc/bugs/Syncing_creates_broken_links_instead_of_proper_files/comment_1_a2bedb2e77451b02fc66fc9ef5c4405c._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.211"
+ subject="comment 1"
+ date="2013-01-03T19:38:07Z"
+ content="""
+The broken links represent files whose contents have not yet arrived in the local repository.
+
+If you linked your repos by XMPP, they cannot ssh from one to the other to transfer file contents.
+In this case, you need to set up a transfer repository, that both your repositories can access.
+"""]]
diff --git a/doc/bugs/Test_failure_on_debian_dropunused.mdwn b/doc/bugs/Test_failure_on_debian_dropunused.mdwn
new file mode 100644
index 000000000..459c5f55b
--- /dev/null
+++ b/doc/bugs/Test_failure_on_debian_dropunused.mdwn
@@ -0,0 +1,31 @@
+### Please describe the problem.
+./git-annex test fails:
+
+ ### Failure in: git-annex unused/dropunused
+ dropunused failed
+ Cases: 1 Tried: 1 Errors: 0 Failures: 1
+
+### What steps will reproduce the problem?
+./git-annex test
+
+### What version of git-annex are you using? On what operating system?
+4.20130723-206-g1647361
+
+
+debian 7.1 i686
+
+### Please provide any additional information below.
+
+I'm not sure if there is a way to get extra information out of the test harness. I had a quick look at the code and couldn't see anything obvious.
+I've tried a clean and rebuild and it reappears, so if there is more information you need just let me know what.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
+
+> Forgot to update the test suite for this behavior change.
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/The_assistant_hangs_forever.mdwn b/doc/bugs/The_assistant_hangs_forever.mdwn
new file mode 100644
index 000000000..be8968ff8
--- /dev/null
+++ b/doc/bugs/The_assistant_hangs_forever.mdwn
@@ -0,0 +1,46 @@
+What steps will reproduce the problem?
+
+1. Open the assistant with git-annex webapp
+2. Click add another repository
+3. Choose "add another repository"
+4. Use "/home/pierre/testme" (try and get the problem with a new directory or an existing directory)
+5. Press "Make Repository"
+5. Choose "Keep the repository separate"
+
+What is the expected output? What do you see instead?
+
+Go to the created repository but the interface hangs forever
+I have 4 git-annex processes that use no CPUs.
+I can still use the UI by clicking around with success or even shutdown the daemon.
+If I shutdown the daemon, all git-annex process gets killed.
+
+What version of git-annex are you using? On what operating system?
+
+It is said to be git-annex version: 4.20130324 but it is actually 4.20130405 (known bug)
+
+Please provide any additional information below.
+
+
+OS: Arch linux, bin package (not installed from source)
+All tests are OK
+Nothing happens on the log pages
+
+This is so weird that I would like to see the log file but I cannot find it. I have looked at /var/log without success.
+I have tried other available version on Arch linux (AUR git-annex-bin, AUR git-annex-standalone, haskell-web git-annex) and they all exhibit the same problem.
+At that stage, what I would like to be able is to try to figure out what is going on using the log file.
+Thanks
+
+> This could happen when using the amd64 standalone build, because I
+> forgot to install curl into its chroot, so it was not included in the
+> bundle. If the host system also lacked curl, or something prevented
+> curl from working, it would fail like this.
+>
+> I've included curl into the amd64 standalone build. I've also made the
+> assistant fall back to using a built-in http client if it is built
+> without curl.
+>
+> None of which helps at all with the Arch git-annex-bin hack, since
+> that binary will be built with a working curl (when my amd64 standalone
+> builder builds it), and then installed onto a system, that,
+> apparently, has a broken curl. Which is one of many reasons I cannot
+> support that hack. [[done]] --[[Joey]]
diff --git a/doc/bugs/The_assistant_hangs_forever/comment_1_b0291e32860e0da0b66837d14ed5aab6._comment b/doc/bugs/The_assistant_hangs_forever/comment_1_b0291e32860e0da0b66837d14ed5aab6._comment
new file mode 100644
index 000000000..b22711b65
--- /dev/null
+++ b/doc/bugs/The_assistant_hangs_forever/comment_1_b0291e32860e0da0b66837d14ed5aab6._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://pradermecker.myopenid.com/"
+ ip="81.244.190.181"
+ subject="comment 1"
+ date="2013-04-14T09:45:35Z"
+ content="""
+Forgot to mention that this is my first attempt to work with the assistant on 64 bits (previous binary package were 32 bits only)
+"""]]
diff --git a/doc/bugs/The_assistant_hangs_forever/comment_2_a2950cf91b8a4e4f2951f5522ef0e9c4._comment b/doc/bugs/The_assistant_hangs_forever/comment_2_a2950cf91b8a4e4f2951f5522ef0e9c4._comment
new file mode 100644
index 000000000..90b93f0bb
--- /dev/null
+++ b/doc/bugs/The_assistant_hangs_forever/comment_2_a2950cf91b8a4e4f2951f5522ef0e9c4._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="saironiq"
+ ip="147.251.209.29"
+ subject="comment 2"
+ date="2013-04-14T12:09:11Z"
+ content="""
+Not sure if this is the real reason, but I get a bunch of
+
+>curl: symbol lookup error: /usr/lib/libssl.so.1.0.0: undefined symbol: EVP_idea_cbc
+
+errors in the git-annex log. Running nm on the lib produces the following:
+
+>$ nm /usr/lib/libssl.so.1.0.0 | grep EVP_idea_cbc<br>
+>&nbsp;&nbsp;&nbsp;&nbsp;U EVP_idea_cbc
+
+...where \"U\" means undefined. I think the reason 64-bit does not work is that there is no curl (and lsof) binaries and libs included.
+
+"""]]
diff --git a/doc/bugs/The_assistant_hangs_forever/comment_3_db95f78519d5ffbad793906028730dab._comment b/doc/bugs/The_assistant_hangs_forever/comment_3_db95f78519d5ffbad793906028730dab._comment
new file mode 100644
index 000000000..e9e76f5b2
--- /dev/null
+++ b/doc/bugs/The_assistant_hangs_forever/comment_3_db95f78519d5ffbad793906028730dab._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-04-14T17:57:47Z"
+ content="""
+The assistant's log file is stored in `.git/annex/daemon.log` within the git repository.
+
+I have to say I don't really understand the bug report. In one sentence you say the \"interface hangs forever\", and then in the next sentence you say you can \"still use the UI by clicking around\". These statements contradict one-another.
+
+(@saironiq, I don't see any connection between what you're saying and pradermecker's bug report. If you have a bug to report, you should file a separate bug report.)
+"""]]
diff --git a/doc/bugs/The_assistant_hangs_forever/comment_4_28b13fd3165b38a2fbc9e1a461c38921._comment b/doc/bugs/The_assistant_hangs_forever/comment_4_28b13fd3165b38a2fbc9e1a461c38921._comment
new file mode 100644
index 000000000..3bec70a7f
--- /dev/null
+++ b/doc/bugs/The_assistant_hangs_forever/comment_4_28b13fd3165b38a2fbc9e1a461c38921._comment
@@ -0,0 +1,22 @@
+[[!comment format=mdwn
+ username="saironiq"
+ ip="147.251.209.29"
+ subject="comment 4"
+ date="2013-04-15T10:35:36Z"
+ content="""
+These symbol lookup errors appear right after i click 'keep the repositories separate', so I think there indeed is a connection. There's nothing else in the log, except this one line repeating over and over again.
+
+>[2013-04-15 11:14:30 CEST] main: starting assistant version 4.20130324<br/>
+>Already up-to-date.</br>
+>
+>(scanning...) [2013-04-15 11:14:31 CEST] Watcher: Performing startup scan<br/>
+>Already up-to-date.<br/>
+>
+>(started...) [2013-04-15 12:14:30 CEST] NetWatcherFallback: Syncing with wolf, zyzyx<br/>
+>(Recording state in git...)<br/>
+>git-annex: Daemon is already running.<br/>
+>curl: symbol lookup error: /usr/lib/libssl.so.1.0.0: undefined symbol: EVP_idea_cbc<br/>
+>curl: symbol lookup error: /usr/lib/libssl.so.1.0.0: undefined symbol: EVP_idea_cbc<br/>
+>curl: symbol lookup error: /usr/lib/libssl.so.1.0.0: undefined symbol: EVP_idea_cbc<br/>
+>...
+"""]]
diff --git a/doc/bugs/The_assistant_hangs_forever/comment_5_81a79c8840ff26307a9c6edad5b850f9._comment b/doc/bugs/The_assistant_hangs_forever/comment_5_81a79c8840ff26307a9c6edad5b850f9._comment
new file mode 100644
index 000000000..f8b6a61bc
--- /dev/null
+++ b/doc/bugs/The_assistant_hangs_forever/comment_5_81a79c8840ff26307a9c6edad5b850f9._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="saironiq"
+ ip="147.251.209.29"
+ subject="comment 5"
+ date="2013-04-15T11:01:32Z"
+ content="""
+Here's a full strace output (first symbol lookup error is on line #102681):<br/>
+[[https://dl.dropboxusercontent.com/u/62238161/webapp.log]]
+"""]]
diff --git a/doc/bugs/The_assistant_hangs_forever/comment_6_b739719b14705f4d7e1d412b3cab090c._comment b/doc/bugs/The_assistant_hangs_forever/comment_6_b739719b14705f4d7e1d412b3cab090c._comment
new file mode 100644
index 000000000..0e05b5090
--- /dev/null
+++ b/doc/bugs/The_assistant_hangs_forever/comment_6_b739719b14705f4d7e1d412b3cab090c._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="https://pradermecker.myopenid.com/"
+ ip="81.244.149.180"
+ subject="comment 6"
+ date="2013-04-15T19:59:00Z"
+ content="""
+I can confirm I also get the error:
+curl: symbol lookup error: /usr/lib/libssl.so.1.0.0: undefined symbol: EVP_idea_cbc
+
+What I mean by the UI is hanging is that after the last action, I can see that the page is never fully re-loaded. So to be more precise the reloading of the page never stops.
+
+When I am bored waiting for the page to reload ;-) I can still use the UI in the situation I describe (left to assume the operation fails :-)
+
+I believe @saironiq is right: the problem is related to the 64 bits version.
+
+
+"""]]
diff --git a/doc/bugs/The_assistant_hangs_forever/comment_7_2b300d960697c5b967c1f109dfd6dfbf._comment b/doc/bugs/The_assistant_hangs_forever/comment_7_2b300d960697c5b967c1f109dfd6dfbf._comment
new file mode 100644
index 000000000..8203bbb66
--- /dev/null
+++ b/doc/bugs/The_assistant_hangs_forever/comment_7_2b300d960697c5b967c1f109dfd6dfbf._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://pradermecker.myopenid.com/"
+ ip="81.244.149.180"
+ subject="comment 7"
+ date="2013-04-15T20:39:20Z"
+ content="""
+@joey just to make the connection clear, both @saironiq and I use the same git-annex package (bin package) from Arch linux AUR (@saironiq is the maintainer of the package)
+
+I suspect all 64bits binary packages on Arch linux to exhibit problems.
+
+The package is fetching the bin archive from your repo: so I actually dare to suspect that all recent 64bits versions have similar problems.
+
+I have describe one problem but they are many, so it does not take long to realize that the apps is not working properly.
+
+I guess it is a packaging problem (something is missing in <http://downloads.kitenet.net/git-annex/linux/current/git-annex-standalone-amd64.tar.gz>), not an application bug ?
+"""]]
diff --git a/doc/bugs/The_assistant_hangs_forever/comment_8_8623220d08b1a72ed8b669a2d9cc0f75._comment b/doc/bugs/The_assistant_hangs_forever/comment_8_8623220d08b1a72ed8b669a2d9cc0f75._comment
new file mode 100644
index 000000000..cc275eb2c
--- /dev/null
+++ b/doc/bugs/The_assistant_hangs_forever/comment_8_8623220d08b1a72ed8b669a2d9cc0f75._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 8"
+ date="2013-04-16T18:39:30Z"
+ content="""
+Switching repositories uses curl to discover when the other daemon has started. If you installed <https://aur.archlinux.org/packages/git-annex-bin/> , it will use the curl binary provided by your distribution. It looks like yours is broken.
+
+> \"I have describe one problem but they are many, so it does not take long to realize that the apps is not working properly.\"
+
+Yes, that's the real problem, isn't it? <https://aur.archlinux.org/packages/git-annex-bin/>
+takes the binary built for the standalone tarball and dumps it into a filesystem without any of its support libraries, and just hopes it works. It's not at all surpising that it continually fails to work. Which is causing bug report noise that takes away from my time working on actual improvements to git-annex.
+
+I'm sorry, but I cannot support that package. Use <https://aur.archlinux.org/packages.php?ID=44272> or install using cabal or use the standalone tarball.
+"""]]
diff --git a/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible.mdwn b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible.mdwn
new file mode 100644
index 000000000..b98e09b32
--- /dev/null
+++ b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible.mdwn
@@ -0,0 +1,29 @@
+**What steps will reproduce the problem?**
+
+On my work computer I created a new repository and then added a directory on my home server to backup some of my files. The assistant created a new key pair which then made password login quite hard.
+On the commandline I could still login via ssh -o PreferredAuthentications=keyboard-interactive ... but all gui tools (e.g. gigolo) stop after connecting to the restricted shell.
+I don't want to allow full passwordless access to my server from this computer.
+
+**What is the expected output? What do you see instead?**
+
+It should be possible to use this private key with git-annex exclusively. Maybe a line like this in the [remote] block in .git/config would solve the problem:
+
+ IdentityFile = /home/user/.ssh/annex/id_rsa_annex
+
+I think it should be the default behaviour that git-annex uses its own key pair with restricted access. For portability the keys could be stored somewhere in the repository itself.
+
+**What version of git-annex are you using? On what operating system?**
+
+git-annex version: 4.20130324, Ubuntu 11.04
+
+**Please provide any additional information below.**
+
+> [[done]]. Although I have not 100% reproduced this, I have seen
+> enough of the source code to gnome-keyring to be pretty sure it's at
+> fault, and that my fix works.
+>
+> If this is happening to you, you can fix it by making a `~/.ssh/annex/`
+> directory and moving `~/.ssh/key.annex*` to it. Then you'll need to edit
+> `~/.ssh/config` to use the new path to the key. And you'll need to run
+> `ssh-add -D` to clear out the bogus keys from the ssh agent (or log out
+> and back in). --[[Joey]]
diff --git a/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_10_8305becdc6e70abdaf17e42f263173fc._comment b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_10_8305becdc6e70abdaf17e42f263173fc._comment
new file mode 100644
index 000000000..09c4802f7
--- /dev/null
+++ b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_10_8305becdc6e70abdaf17e42f263173fc._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="marvin"
+ ip="91.152.75.65"
+ subject="comment 10"
+ date="2013-04-14T02:34:50Z"
+ content="""
+Hopefully I haven't done anything stupid, wouldn't be the first time :)
+Retried with a different setup, same result.
+Pasted into pastebin as I wasn't sure about the formatting..
+
+<http://pastebin.com/vnnmiBeE>
+"""]]
diff --git a/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_11_d75896a6e204d1abdda04923aa668d04._comment b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_11_d75896a6e204d1abdda04923aa668d04._comment
new file mode 100644
index 000000000..31460ae5b
--- /dev/null
+++ b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_11_d75896a6e204d1abdda04923aa668d04._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 11"
+ date="2013-04-14T02:58:05Z"
+ content="""
+Thanks for that.. It's not verbose enough for me to see it choose the key to use. Can you add one more `v`? ssh -vvv , 3 v's..
+"""]]
diff --git a/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_12_a36a4a64a04c01c2db467b09300e6ebd._comment b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_12_a36a4a64a04c01c2db467b09300e6ebd._comment
new file mode 100644
index 000000000..428d5a43c
--- /dev/null
+++ b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_12_a36a4a64a04c01c2db467b09300e6ebd._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="marvin"
+ ip="91.152.75.65"
+ subject="comment 12"
+ date="2013-04-14T09:51:27Z"
+ content="""
+hmm.. I did use -vvv, even tried with 4 which doesen't change anything. Is there a ceartain version of ssh or debian live image I could test with? There shouldn't be anything extraordinary about my setup.
+"""]]
diff --git a/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_13_c9d6631c304acb289e485fb901e1f274._comment b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_13_c9d6631c304acb289e485fb901e1f274._comment
new file mode 100644
index 000000000..083c1e5a2
--- /dev/null
+++ b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_13_c9d6631c304acb289e485fb901e1f274._comment
@@ -0,0 +1,35 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 13"
+ date="2013-04-14T18:27:35Z"
+ content="""
+This should not be a hard problem to debug.
+
+* You have a local client, and a remote server.
+* The remote server has a `~/.ssh/authorized_keys` file that contains a public key that git-annex set up, which is restricted to only run \"command=git-annex-shell\".
+* The local client has that key in `~/.ssh/key.git-annex-$hostname-$username`
+* The local client is configured in `~/.ssh/config` to only use that key when sshing to the special hostname \"git-annex-$hostname-$username\"
+* The problem is either on the client, or on the server.
+* If the problem is on the client, then it must be, somehow, incorrectly sending the git-annex key to the server when you \"ssh $hostname\". You can see what keys it decides to send by looking at the messages it prints with -vvv :
+
+<pre>
+joey@gnu:~>ssh -vvv git-annex-kitenet.net-joey
+OpenSSH_6.0p1 Debian-4, OpenSSL 1.0.1e 11 Feb 2013
+debug1: Reading configuration data /home/joey/.ssh/config
+debug1: /home/joey/.ssh/config line 3: Applying options for git-annex-kitenet.net-joey
+debug1: Reading configuration data /etc/ssh/ssh_config
+debug1: /etc/ssh/ssh_config line 19: Applying options for *
+debug2: ssh_connect: needpriv 0
+debug1: Connecting to kitenet.net [80.68.85.49] port 22.
+debug1: Connection established.
+debug3: Incorrect RSA1 identifier
+debug3: Could not load \"/home/joey/.ssh/key.git-annex-kitenet.net-joey\" as a RSA1 public key
+debug1: identity file /home/joey/.ssh/key.git-annex-kitenet.net-joey type 1
+</pre>
+
+* If the problem is on the server, then it must be for some reason deciding to run `git-annex-shell` when you ssh in,
+ despite the client not sending it the special git-annex key. If this were the case, no change you made on the client could fix
+ the problem, but deleting `.ssh/authorized_keys` on the server probably would.
+
+"""]]
diff --git a/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_14_10282c4352075c8d148b8674973b7b16._comment b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_14_10282c4352075c8d148b8674973b7b16._comment
new file mode 100644
index 000000000..0b1da9029
--- /dev/null
+++ b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_14_10282c4352075c8d148b8674973b7b16._comment
@@ -0,0 +1,22 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="ssh agent?"
+ date="2013-04-14T18:34:45Z"
+ content="""
+The only other thing I can think of is that if you have a ssh-agent, it might somehow be caching the git-annex key and incorrectly sending it to ssh. If this were the case, then unsetting `SSH_AUTH_SOCK` or stopping the agent would presumably make the problem go away.
+
+In @marvin's log, I see:
+
+<pre>
+debug1: Offering RSA public key: marvin@marvin-U-100
+</pre>
+
+This is different from what I see when ssh is using a regular key in `.ssh/`:
+
+<pre>
+debug1: Offering RSA public key: /home/joey/.ssh/id_rsa
+</pre>
+
+Marvin's log does not show where it gets this \"marvin@marvin-U-100\".. which makes me suspect it comes from a ssh agent.
+"""]]
diff --git a/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_15_ceb68da01d9e2fe9a70fab6244116da0._comment b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_15_ceb68da01d9e2fe9a70fab6244116da0._comment
new file mode 100644
index 000000000..bbf5a45b5
--- /dev/null
+++ b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_15_ceb68da01d9e2fe9a70fab6244116da0._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 15"
+ date="2013-04-14T18:46:54Z"
+ content="""
+I tried the following experiment:
+
+1. Manually ran `ssh-add .ssh/key.git-annex-kitenet.net-joey`
+2. `ssh -vvv kitenet.net` did run git-annex-shell
+
+Guys, please paste the output of `ssh-add -l`
+
+Also, if you run `ssh-add -D`, the problem should go away, and the server should not run git-annex-shell. If that's the case, we've confirmed this is somehow a ssh agent problem. However, I still don't know what could be scanning `~/.ssh` for random keys and loading them into the agent.
+"""]]
diff --git a/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_16_cca4abde86a8be5e2919c4738f5bdd0c._comment b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_16_cca4abde86a8be5e2919c4738f5bdd0c._comment
new file mode 100644
index 000000000..2260917b3
--- /dev/null
+++ b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_16_cca4abde86a8be5e2919c4738f5bdd0c._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 16"
+ date="2013-04-14T19:04:11Z"
+ content="""
+Are you guys running Gnome? Using gnome-keyring?
+
+I found the following highly suspicious code inside gnome-keyring:
+
+[[!format C \"\"\"
+ if (!self->directory)
+ self->directory = g_strdup (\"~/.ssh\");
+ self->tracker = gkm_file_tracker_new (self->directory, \"*.pub\", NULL);
+\"\"\"]]
+
+This seems to load *all* keys, as described. Not keys in subdirectories of ~/.ssh/ either.
+"""]]
diff --git a/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_17_2fa5d7d9110c91b0a3a833cb3d9f53fd._comment b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_17_2fa5d7d9110c91b0a3a833cb3d9f53fd._comment
new file mode 100644
index 000000000..2b760bb55
--- /dev/null
+++ b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_17_2fa5d7d9110c91b0a3a833cb3d9f53fd._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="marvin"
+ ip="91.152.75.65"
+ subject="comment 17"
+ date="2013-04-14T20:07:33Z"
+ content="""
+YES! Straight from the tty console it works correctly. Seems this project unearths lots of bugs all over the place.
+
+Thank you!
+"""]]
diff --git a/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_18_bf21d28142e4c304aa0bc740955ddea0._comment b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_18_bf21d28142e4c304aa0bc740955ddea0._comment
new file mode 100644
index 000000000..67021d180
--- /dev/null
+++ b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_18_bf21d28142e4c304aa0bc740955ddea0._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 18"
+ date="2013-04-14T20:13:54Z"
+ content="""
+@Marvin, just to be clear, it was `ssh-add -D` that fixed it for you?
+
+To make the fix stick, you need to make a ~/.ssh/annex/ directory, and move the keys to there, and then edit ~/.ssh/config to use the new path to the key file. This should prevent gnome-keyring from seeing them.
+"""]]
diff --git a/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_19_45537758fa937f16fc82120bf8b234e8._comment b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_19_45537758fa937f16fc82120bf8b234e8._comment
new file mode 100644
index 000000000..3d0d4a45e
--- /dev/null
+++ b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_19_45537758fa937f16fc82120bf8b234e8._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="marvin"
+ ip="91.152.75.65"
+ subject="comment 19"
+ date="2013-04-14T20:47:37Z"
+ content="""
+nope, ssh-add -D doesn't seem to help. Killing gnome-keyring-daemon does.
+"""]]
diff --git a/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_1_a38497772834a4b12137390b461ce70b._comment b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_1_a38497772834a4b12137390b461ce70b._comment
new file mode 100644
index 000000000..fb7bd7420
--- /dev/null
+++ b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_1_a38497772834a4b12137390b461ce70b._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-04-09T17:29:00Z"
+ content="""
+The key pair that the assistant sets up is limited, in ~/.ssh/config to only be used when a mangled version of the hostname is used. That is, you have to \"ssh git-annex-hostname\" to use that key. So it should not be possible for this to impact your normal use of ssh to that host.
+
+(`.git/config` does not support an `IdentityFile` option TTBOMK.)
+
+You need to provide more details about the problem you have encountered.
+"""]]
diff --git a/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_20_b685050ee6fbb1a685e33f9656a10e84._comment b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_20_b685050ee6fbb1a685e33f9656a10e84._comment
new file mode 100644
index 000000000..83ab46051
--- /dev/null
+++ b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_20_b685050ee6fbb1a685e33f9656a10e84._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 20"
+ date="2013-04-14T20:59:26Z"
+ content="""
+Ok, I don't know how gnome-keyring communicates with ssh, but that's good enough evidence for me: It was certainly gnome-keyring that got us into this mess!
+"""]]
diff --git a/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_3_17bc0220c20553c848875475c5fd4ae6._comment b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_3_17bc0220c20553c848875475c5fd4ae6._comment
new file mode 100644
index 000000000..f8e07dd4a
--- /dev/null
+++ b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_3_17bc0220c20553c848875475c5fd4ae6._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-04-11T16:26:26Z"
+ content="""
+When git-annex uses an existing key (which is done automatically if it detects you have already set up passwordless login to the server using the default key), it does not configure the server to further restrict use of that key.
+
+I have just verified this to be sure. That would be a bad bug. Doesn't happen.
+
+So, I still don't understand what this bug report is about.
+"""]]
diff --git a/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_4_76472bc58bb790f773c46ec2c39fcf88._comment b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_4_76472bc58bb790f773c46ec2c39fcf88._comment
new file mode 100644
index 000000000..54bfc750b
--- /dev/null
+++ b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_4_76472bc58bb790f773c46ec2c39fcf88._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl99Gxq3NPNvwZHp3PDufaknQH4rZb_KKY"
+ nickname="Florian"
+ subject="comment 4"
+ date="2013-04-12T15:01:16Z"
+ content="""
+I think I found a part of the problem. I still don't know why there was this strange key setup in the beginning. Maybe i did this manually and forgot about it instantly...
+
+However, today I again had the problem with ending up in git-annex-shell on the commandline. To debug this I called ssh -vvv ... and found out that ssh somehow found the private key in ~/.ssh/key.git-annex-servername-username and ofcourse tried to use it.
+Moving the key to a subdirectory in ~/.ssh/ and fixing the path in ~/.ssh/config solved my problem again.
+"""]]
diff --git a/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_4_dcd9286e314779c25764484beff40561._comment b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_4_dcd9286e314779c25764484beff40561._comment
new file mode 100644
index 000000000..44df43339
--- /dev/null
+++ b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_4_dcd9286e314779c25764484beff40561._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl99Gxq3NPNvwZHp3PDufaknQH4rZb_KKY"
+ nickname="Florian"
+ subject="comment 4"
+ date="2013-04-10T12:39:49Z"
+ content="""
+OK, problem solved. I deleted the key on the server and then readded the repository. Now I have a separate git-annex key pair and the config is as you described. I don't know why an existing key pair was used in the setup before. I log into my home server frequently and don't remember that I added the public key manually (especially regarding the restriction to git-annex-shell that was applied).
+
+However, thanks for the great work so far!
+"""]]
diff --git a/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_5_2146eec77b87b615100d0d003e8dce75._comment b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_5_2146eec77b87b615100d0d003e8dce75._comment
new file mode 100644
index 000000000..8889c3adb
--- /dev/null
+++ b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_5_2146eec77b87b615100d0d003e8dce75._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="marvin"
+ ip="91.152.75.65"
+ subject="Seeing the same thing"
+ date="2013-04-13T22:36:00Z"
+ content="""
+So what I did on a clean ubuntu install was
+
+1. start git-annex-webapp Version: ( 4.20130413-g5747bf4 )
+2. set up local repository and remote ssh repository
+3. sync some files
+4. trying to ssh from the console to the remote now fails with error message \"git-annex-shell: bad parameters\"
+
+I do believe it has always done this (also on wheezy). Is this supposed to work this way? Hope to get a webdav / owncloud / some own hosted system not relying on ssh. Just want to sync files to a headless server. I'll gladly help if I can.
+"""]]
diff --git a/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_6_2bd6f4e04903ee251d43d0a97bd40b6e._comment b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_6_2bd6f4e04903ee251d43d0a97bd40b6e._comment
new file mode 100644
index 000000000..901798fe8
--- /dev/null
+++ b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_6_2bd6f4e04903ee251d43d0a97bd40b6e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 6"
+ date="2013-04-13T22:40:02Z"
+ content="""
+No, it is not supposed to do that. Can you take a look at the `.ssh/authorized_keys` file on the remote and see what key it has configured to run git-annex-shell? This should not be your main ssh key..
+"""]]
diff --git a/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_7_7db8ed002eb6313b07f09bd1a34019e3._comment b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_7_7db8ed002eb6313b07f09bd1a34019e3._comment
new file mode 100644
index 000000000..cf1e30824
--- /dev/null
+++ b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_7_7db8ed002eb6313b07f09bd1a34019e3._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 7"
+ date="2013-04-13T22:48:55Z"
+ content="""
+@Florian, it seems very unlikely that ssh would go off and pick a **utterly random file** to use as the key. ssh generally tries to be consistent, and secure, and that would be neither.
+
+Can you paste the `ssh -vv` output when it does it?
+"""]]
diff --git a/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_8_1bcb2a238006044bc78849e56cb21a01._comment b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_8_1bcb2a238006044bc78849e56cb21a01._comment
new file mode 100644
index 000000000..9cc054b39
--- /dev/null
+++ b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_8_1bcb2a238006044bc78849e56cb21a01._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="marvin"
+ ip="91.152.75.65"
+ subject="comment 8"
+ date="2013-04-14T00:37:21Z"
+ content="""
+The key in authorized file is the same as git-annex pub key ( key.git-annex-192.168.1.43-marvin.pub )
+Which is also the only ssh key in the authorized file. Is it assumed keys are always used instead of only passwords?
+"""]]
diff --git a/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_9_26c6937cf78e7141e0e3b20f25ed8f7a._comment b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_9_26c6937cf78e7141e0e3b20f25ed8f7a._comment
new file mode 100644
index 000000000..7f36e3c43
--- /dev/null
+++ b/doc/bugs/The_restricted_ssh_key_pair_makes_password_login___40__nearly__41___impossible/comment_9_26c6937cf78e7141e0e3b20f25ed8f7a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 9"
+ date="2013-04-14T00:46:32Z"
+ content="""
+Can you please paste the output of `ssh -vvv host
+"""]]
diff --git a/doc/bugs/The_tests_are_failing_to_build_now_on_commit_e0fdfb2e706da2cb1451193c658dc676b0530968.mdwn b/doc/bugs/The_tests_are_failing_to_build_now_on_commit_e0fdfb2e706da2cb1451193c658dc676b0530968.mdwn
new file mode 100644
index 000000000..be6db378c
--- /dev/null
+++ b/doc/bugs/The_tests_are_failing_to_build_now_on_commit_e0fdfb2e706da2cb1451193c658dc676b0530968.mdwn
@@ -0,0 +1,23 @@
+I only saw this just now, but the tests fail to link/build on OSX
+
+<pre>
+[181 of 181] Compiling Main ( git-annex.hs, tmp/Main.o )
+Linking git-annex ...
++ make -q test
++ '[' 1 = 1 ']'
++ ../maxtime 1800 make test
+[175 of 175] Compiling Main ( test.hs, tmp/Main.o )
+test.hs:175:17:
+Not in scope: data constructor `Types.Backend.KeySource'
+test.hs:175:43:
+`Types.Backend.keyFilename' is not a (visible) constructor field name
+test.hs:175:76:
+`Types.Backend.contentLocation' is not a (visible) constructor field name
+** failed to build the test suite
+make: *** [test] Error 1
++ exit 4
+</pre>
+
+this issue seems to got introduced at commit e0fdfb2e706da2cb1451193c658dc676b0530968
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/The_webapp_doesn__39__t_allow_deleting_repositories.mdwn b/doc/bugs/The_webapp_doesn__39__t_allow_deleting_repositories.mdwn
new file mode 100644
index 000000000..88e39efe9
--- /dev/null
+++ b/doc/bugs/The_webapp_doesn__39__t_allow_deleting_repositories.mdwn
@@ -0,0 +1,33 @@
+What steps will reproduce the problem?
+
+After creating new remote repositories in the webapp there's no option to delete them
+
+What is the expected output? What do you see instead?
+
+Some option to delete a repository, just like I can disable sync or change the config of a remote
+
+What version of git-annex are you using? On what operating system?
+
+ $ ./git-annex version
+ git-annex version: 3.20130102
+
+ $ uname -a
+ Linux wintermute 3.2.0-35-generic #55-Ubuntu SMP Wed Dec 5 17:45:18 UTC 2012 i686 i686 i386 GNU/Linux
+
+ $ lsb_release -a
+ Distributor ID: Ubuntu
+ Description: Ubuntu 12.04.1 LTS
+ Release: 12.04
+ Codename: precise
+
+[[!tag /design/assistant]]
+
+> Status: You can delete the current repository. You can also remove
+> repositories from the list of remotes (without deleting their content)
+> and you can tell it you want to stop using a remote, and it will
+> suck all content off that remote until it's empty.
+>
+> Still todo: Detect when a remote has been sucked dry, and actually delete
+> it. --[[Joey]]
+
+>> [[done]] --[[Joey]]
diff --git a/doc/bugs/The_webapp_doesn__39__t_allow_deleting_repositories/comment_1_1b80f9cfedd25e34997fa07e08d15012._comment b/doc/bugs/The_webapp_doesn__39__t_allow_deleting_repositories/comment_1_1b80f9cfedd25e34997fa07e08d15012._comment
new file mode 100644
index 000000000..5087b5f4e
--- /dev/null
+++ b/doc/bugs/The_webapp_doesn__39__t_allow_deleting_repositories/comment_1_1b80f9cfedd25e34997fa07e08d15012._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.211"
+ subject="comment 1"
+ date="2013-01-03T19:48:46Z"
+ content="""
+Something I would like to support, although complicated by what \"delete\" means. At its simplest it can mean removing the git remote configuration, but leaving the remote's data as-is, so it can be added back, or other repositories can continue to access it. More complicated, it could mean completely deleting the repository, and its data -- which would probably first need to move any data that was solely in that repository off to elsewhere.
+"""]]
diff --git a/doc/bugs/The_webapp_doesn__39__t_allow_deleting_repositories/comment_2_53499da1185c56d8fd25f86ba41d96ce._comment b/doc/bugs/The_webapp_doesn__39__t_allow_deleting_repositories/comment_2_53499da1185c56d8fd25f86ba41d96ce._comment
new file mode 100644
index 000000000..e84094738
--- /dev/null
+++ b/doc/bugs/The_webapp_doesn__39__t_allow_deleting_repositories/comment_2_53499da1185c56d8fd25f86ba41d96ce._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="it also doesn't recognize when a local repository has been deleted manually"
+ date="2013-01-09T16:13:41Z"
+ content="""
+I created a new local repository to play with the new Direct Mode features. I ended up deleting it (deleting the directory), but when I launched the assistant, I was still given the option of \"switching repository\" to the now-deleted one. It threw the error Internal Server Error (user error (git [\"config\",\"--null\",\"--list\"] exited 126)).
+
+> Fixed this. --[[Joey]]
+
+"""]]
diff --git a/doc/bugs/The_webapp_doesn__39__t_allow_deleting_repositories/comment_3_3e07b8386d2c7afce2a78d24b9c260b9._comment b/doc/bugs/The_webapp_doesn__39__t_allow_deleting_repositories/comment_3_3e07b8386d2c7afce2a78d24b9c260b9._comment
new file mode 100644
index 000000000..76342ec63
--- /dev/null
+++ b/doc/bugs/The_webapp_doesn__39__t_allow_deleting_repositories/comment_3_3e07b8386d2c7afce2a78d24b9c260b9._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://piotr.ozarowski.pl/"
+ nickname="p1otr"
+ subject="Re: comment 1"
+ date="2013-01-15T09:26:21Z"
+ content="""
+How about asking the user? Something like:
+
+Do you want to...
+
+* only remove configuration from annex
+* make sure there's a copy of all files from this repository somewhere and remove it (including remote files)
+* remove remote files (and remove them from annex if there's no other copy)
+"""]]
diff --git a/doc/bugs/Too_many_open_files.mdwn b/doc/bugs/Too_many_open_files.mdwn
new file mode 100644
index 000000000..3bb53e74d
--- /dev/null
+++ b/doc/bugs/Too_many_open_files.mdwn
@@ -0,0 +1,55 @@
+### Please describe the problem.
+
+The transferrer crashes after a while due to too many open files
+
+### What steps will reproduce the problem?
+
+Have a huge annex. Connect two local machines, one with the huge annex, the other one without. Let them copy files…
+
+### What version of git-annex are you using? On what operating system?
+
+latest version
+git-annex version: 5.20131117-gbd514dc
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV FsEvents XMPP DNS Feeds Quvi TDFA CryptoHash
+key/value backends: SHA256E SHA1E SHA512E SHA224E SHA384E SKEIN256E SKEIN512E SHA256 SHA1 SHA512 SHA224 SHA384 SKEIN256 SKEIN512 WORM URL
+remote types: git gcrypt S3 bup directory rsync web webdav glacier hook
+
+on Mac OS X 10.9
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+[2013-11-22 10:49:19 CET] Transferrer: Downloaded oktaeder.png
+[2013-11-22 10:49:19 CET] Transferrer: Downloaded oktaeder.png
+[2013-11-22 10:49:19 CET] Transferrer: Downloaded oktaeder.png
+[2013-11-22 10:49:20 CET] Transferrer: Downloaded klett-cover-neu.jpg
+[2013-11-22 10:49:20 CET] Transferrer: Downloaded klett-cover-neu.jpg
+[2013-11-22 10:49:20 CET] Transferrer: Downloaded kara-worl..ditor.gif
+git-annex: runInteractiveProcess: pipe: Too many open files
+Committer crashed: lsof: createProcess: resource exhausted (Too many open files)
+[2013-11-22 10:49:20 CET] Committer: warning Committer crashed: lsof: createProcess: resource exhausted (Too many open files)
+[2013-11-22 10:49:20 CET] Transferrer: Downloaded kara-worl..ditor.gif
+[2013-11-22 10:49:20 CET] Transferrer: Downloaded kara-worl..ditor.gif
+[2013-11-22 10:49:20 CET] Transferrer: Downloaded image1.png
+[2013-11-22 10:49:21 CET] Transferrer: Downloaded image1.png
+[2013-11-22 10:49:21 CET] Transferrer: Downloaded image.png
+[2013-11-22 10:49:21 CET] Transferrer: Downloaded image.png
+[2013-11-22 10:49:21 CET] Transferrer: Downloaded ikoseder.png
+[2013-11-22 10:49:21 CET] Transferrer: Downloaded ikoseder.png
+[2013-11-22 10:49:22 CET] Transferrer: Downloaded ikoseder.png
+[2013-11-22 10:49:22 CET] Transferrer: Downloaded ikosaeder.jpg
+git-annex: runInteractiveProcess: pipe: Too many open files
+ok
+(Recording state in git...)
+git-annex: socket: resource exhausted (Too many open files)
+[2013-11-22 10:49:22 CET] Transferrer: Downloaded ikosaeder.jpg
+Transferrer crashed: getCurrentDirectory: resource exhausted (Too many open files)
+[2013-11-22 10:49:22 CET] Transferrer: warning Transferrer crashed: getCurrentDirectory: resource exhausted (Too many open files)
+git-annex: runInteractiveProcess: pipe: Too many open files
+git-annex: runInteractiveProcess: pipe: Too many open files
+
+# End of transcript or log.
+"""]]
diff --git a/doc/bugs/Too_many_open_files/comment_1_d5d509b9b431d2ea6000ebc0aed62857._comment b/doc/bugs/Too_many_open_files/comment_1_d5d509b9b431d2ea6000ebc0aed62857._comment
new file mode 100644
index 000000000..477192692
--- /dev/null
+++ b/doc/bugs/Too_many_open_files/comment_1_d5d509b9b431d2ea6000ebc0aed62857._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.64"
+ subject="comment 1"
+ date="2013-11-26T16:28:25Z"
+ content="""
+You can use `lsof -c git-annex` to find out what files git-annex has open. (lsof is included in the git-annex.app bundle on OSX) That would be very helpful in tracking this down.
+"""]]
diff --git a/doc/bugs/Too_much_system_load_on_startup.mdwn b/doc/bugs/Too_much_system_load_on_startup.mdwn
new file mode 100644
index 000000000..fc514ca73
--- /dev/null
+++ b/doc/bugs/Too_much_system_load_on_startup.mdwn
@@ -0,0 +1,24 @@
+### Please describe the problem.
+When I log in, if git annex is monitoring a large repo, my desktop is very sluggish getting started. Git-annex causes moderate CPU load, but keeps the disk IO very busy -delaying the opening of desktop applications.
+
+### What steps will reproduce the problem?
+On Linux, with git-annex set to autostart and monitoring a folder with more than a few hundred files (I have a pdf library of a few thousand journal articles).
+
+### What version of git-annex are you using? On what operating system?
+4.20131002 Ubuntu, from Hess's PPA.
+
+### Please provide any additional information below.
+
+I solved this problem by changing the call to git-annex in /etc/xdg/autostart/git-annex.desktop from:
+
+Exec=/usr/bin/git-annex assistant --autostart
+
+to
+
+Exec=sleep 5 ionice -c 3 /usr/bin/git-annex assistant --autostart
+
+This delays the start of git-annex for 5 seconds, letting the desktop get started, and forces git-annex to yield IO to other programs -preventing it from slowing them down by forcing them to wait for disk access. Since this is a background daemon with potentially high IO usage, but no need for quick responsiveness, perhaps that would make a decent default?
+
+> Added 5 second delay to existing ionice. Provisionally [[done]],
+> although it does occur to me that the startup scan could add some delays
+> in between actions to run more as a batch job. --[[Joey]]
diff --git a/doc/bugs/Too_much_system_load_on_startup/comment_1_4470cddc0965062588acff1bc77285e9._comment b/doc/bugs/Too_much_system_load_on_startup/comment_1_4470cddc0965062588acff1bc77285e9._comment
new file mode 100644
index 000000000..31e735985
--- /dev/null
+++ b/doc/bugs/Too_much_system_load_on_startup/comment_1_4470cddc0965062588acff1bc77285e9._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 1"
+ date="2013-10-26T16:44:59Z"
+ content="""
+git-annex version 4.20131002 *already* ionices itself on startup, assuming it detects a system it can do that on. So the only relevant change you made is delaying it from starting. I have made the assistant wait 5 seconds before running the startup scan when autostarted.
+"""]]
diff --git a/doc/bugs/TransferScanner_crash_on_Android.mdwn b/doc/bugs/TransferScanner_crash_on_Android.mdwn
new file mode 100644
index 000000000..89ad1f824
--- /dev/null
+++ b/doc/bugs/TransferScanner_crash_on_Android.mdwn
@@ -0,0 +1,24 @@
+### Please describe the problem.
+
+TransferScanner crashes trying to add a file.
+
+### What steps will reproduce the problem?
+
+Start the web app.
+
+### What version of git-annex are you using? On what operating system?
+
+4.20130709-g339d1e0 on Android.
+
+### Please provide any additional information below.
+
+There was a whole stack of nulls in some of those log lines as well. I've
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+TransferScanner crashed: unknown response from git cat-file ("refs/heads/git-annex:289/20f/SHA256E-s85883241--3bf01cfd6a422f9b661ed335e6142bbdaf899cd71587bb3cc812256064c7071e missing",refs/heads/git-annex:289/20f/SHA256E-s85883241--3bf01cfd6a422f9b661ed335e6142bbdaf899cd71587bb3cc812256064c7071e\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00(7981 more elided)\00.log)
+[2013-07-16 15:19:26 NZST] TransferScanner: warning TransferScanner crashed: unknown response from git cat-file ("refs/heads/git-annex:289/20f/SHA256E-s85883241--3bf01cfd6a422f9b661ed335e6142bbdaf899cd71587bb3cc812256064c7071e missing",refs/heads/git-annex:289/20f/SHA256E-s85883241--3bf01cfd6a422f9b661ed335e6142bbdaf899cd71587bb3cc812256064c7071e\00\00\00\00\00(7991 more elided)\00.log)
+# End of transcript or log.
+"""]]
diff --git a/doc/bugs/TransferScanner_crash_on_Android/comment_1_6c3584ade1ee6cccddddeaa8e1697945._comment b/doc/bugs/TransferScanner_crash_on_Android/comment_1_6c3584ade1ee6cccddddeaa8e1697945._comment
new file mode 100644
index 000000000..c7622955b
--- /dev/null
+++ b/doc/bugs/TransferScanner_crash_on_Android/comment_1_6c3584ade1ee6cccddddeaa8e1697945._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.90"
+ subject="comment 1"
+ date="2013-07-16T18:16:52Z"
+ content="""
+Wow, that's a lot of NULs!
+
+Can you drop to a shell and run `git fsck` in the repository?
+
+I'm guessing that `git annex fsck` is going to fail with some of the same type errors, but you could also try it.
+
+It seems pretty clear there's damage somewhere. Like something (perhaps a compact flash glitch?) inserted a ton of NULs into the git repository, or corrupted a filename's length field or something.
+
+---
+
+Probably the best thing to do, to get back to a working repository is to move the current repo out of the way, re-setup the assistant on your Android from one of your other repositories (assuming you have another one). Or if this is your only clone of this git repository, you may be able to run `git annex uninit` in it.
+
+Then if necessary the contents of files can be rescued from `.git/annex/objects/` in the corrupt repository, by running `git annex import` in the new repository and passing it that directory. And finish up with a `git annex fsck`.
+"""]]
diff --git a/doc/bugs/TransferScanner_crash_on_Android/comment_2_06574e05149a677d666a722061586658._comment b/doc/bugs/TransferScanner_crash_on_Android/comment_2_06574e05149a677d666a722061586658._comment
new file mode 100644
index 000000000..12105342c
--- /dev/null
+++ b/doc/bugs/TransferScanner_crash_on_Android/comment_2_06574e05149a677d666a722061586658._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkF8_uQjLYm5Mf5F_JuVW-BxlvzpWjvR_o"
+ nickname="Andrew"
+ subject="git annex fsck"
+ date="2013-07-16T22:22:25Z"
+ content="""
+Running git annex fsck appears to have resolved the corruption, but it removed all the content and the assistant hasn't refetched them.
+
+I'm running git annex get . now to refetch all the content.
+"""]]
diff --git a/doc/bugs/TransferScanner_crash_on_Android/comment_3_54ae097d30bb7a49fe151f38c9bac033._comment b/doc/bugs/TransferScanner_crash_on_Android/comment_3_54ae097d30bb7a49fe151f38c9bac033._comment
new file mode 100644
index 000000000..bb31e7f86
--- /dev/null
+++ b/doc/bugs/TransferScanner_crash_on_Android/comment_3_54ae097d30bb7a49fe151f38c9bac033._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.90"
+ subject="comment 3"
+ date="2013-07-17T19:12:49Z"
+ content="""
+I don't see how git annex fsck could resolve the corruption, which appeared to be of data from the git repository, not the git-annex content store. Did you try `git fsck`?
+"""]]
diff --git a/doc/bugs/Transfers_continue_after_daemon_stopped.mdwn b/doc/bugs/Transfers_continue_after_daemon_stopped.mdwn
new file mode 100644
index 000000000..0d9b4f648
--- /dev/null
+++ b/doc/bugs/Transfers_continue_after_daemon_stopped.mdwn
@@ -0,0 +1,5 @@
+After creating a new pairing, I stopped the daemon through the webapp while it was syncing. The webapp shut down and was no longer accessible, but git-annex continued running in the background, along with git-annex-shell, and they continued to run new transfers with new rsync processes. This continued until I killed them all.
+
+I expected that when I stopped the daemon in the webapp, all git-annex processes and all transfers would stop.
+
+Using the 20131101 tarball.
diff --git a/doc/bugs/Transfers_continue_after_daemon_stopped/comment_1_39eb527d64367e6762281246f1d49b1f._comment b/doc/bugs/Transfers_continue_after_daemon_stopped/comment_1_39eb527d64367e6762281246f1d49b1f._comment
new file mode 100644
index 000000000..9d504f743
--- /dev/null
+++ b/doc/bugs/Transfers_continue_after_daemon_stopped/comment_1_39eb527d64367e6762281246f1d49b1f._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 1"
+ date="2013-11-05T16:01:14Z"
+ content="""
+I've checked, and shutting down the daemon does cause it to stop any transfers it is running.
+
+However, this does not stop other transfers initiated by the other paired computer.
+
+I'm ambivilant about whether local pairing should only allow transfers when both daemons are running.
+"""]]
diff --git a/doc/bugs/Tries_to_upload_to_remote_although_remote_is_dead.mdwn b/doc/bugs/Tries_to_upload_to_remote_although_remote_is_dead.mdwn
new file mode 100644
index 000000000..99055e7c5
--- /dev/null
+++ b/doc/bugs/Tries_to_upload_to_remote_although_remote_is_dead.mdwn
@@ -0,0 +1,51 @@
+What steps will reproduce the problem?
+
+I added a (encrypted) ssh remote and everything worked fine. Now I marked the remote as dead, but git-annex still tries to upload to this remote. I recognize this because it asks for my ssh and gpg keys passwords.
+
+While transfering (or asking for the password), `git annex status` shows the following:
+<pre>
+supported backends: SHA256E SHA1E SHA512E SHA224E SHA384E SHA256 SHA1 SHA512 SHA224 SHA384 WORM URL
+supported remote types: git S3 bup directory rsync web hook
+trusted repositories: 0
+semitrusted repositories: 2
+ 00000000-0000-0000-0000-000000000001 -- web
+ cd16b9c6-f464-11e1-9845-8749687232d2 -- here (Dell)
+untrusted repositories: 0
+dead repositories: 7
+ 11379fa0-ecd6-49e2-9bec-24fc19cc7b9f -- vserver.dbruhn.de_annex
+ 2195e036-d2ef-4357-8c89-a9aaec23ebdc -- vserver-plain
+ 4d066ea1-fb9f-45fd-990a-5c5c836f530e -- inTmp
+ bb276045-6ba6-488f-88d0-39a3c5f5134d -- vserver-enc
+ c49f3372-3fcf-49fc-b626-73ba4454c172 -- annexBare (bareAnnex)
+ e52645b3-bfb6-457d-b281-967353919e29 -- AnnexUSBFAT
+ ea3d6acc-716c-48e8-9b6b-993b90dcc1db -- vserver2
+transfers in progress:
+ uploading Schmidt/somefile.m4a
+
+
+ to vserver2
+available local disk space: 43 gigabytes (+1 megabyte reserved)
+temporary directory size: 389 megabytes (clean up with git-annex unused)
+local annex keys: 23
+local annex size: 396 megabytes
+known annex keys: 19
+known annex size: 396 megabytes
+bloom filter size: 16 mebibytes (0% full)
+backend usage:
+ SHA256E: 42
+</pre>
+
+As you can see, the `vserver2` remote is marked as dead but git-annex still tries to upload. This problem keeps occuring even after restarts.
+
+What is the expected output? What do you see instead?
+
+If I do not get the `dead` status wrong, git-annex should not use these remotes.
+
+
+What version of git-annex are you using? On what operating system?
+
+git-annex HEAD from yesterdays git. Ubuntu 12.10
+
+Please provide any additional information below.
+
+[[!tag /design/assistant moreinfo]]
diff --git a/doc/bugs/Tries_to_upload_to_remote_although_remote_is_dead/comment_1_108b3984891f82429430b503cddfb3c1._comment b/doc/bugs/Tries_to_upload_to_remote_although_remote_is_dead/comment_1_108b3984891f82429430b503cddfb3c1._comment
new file mode 100644
index 000000000..f8a85cb16
--- /dev/null
+++ b/doc/bugs/Tries_to_upload_to_remote_although_remote_is_dead/comment_1_108b3984891f82429430b503cddfb3c1._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.194"
+ subject="comment 1"
+ date="2012-11-04T20:01:35Z"
+ content="""
+Are you using the git-annex assistant? It's supposed to have code in it to prevent it from using dead remotes. Perhaps that is not working.
+
+When not using the git-annex assistant, nothing prevents git-annex from trying to continue to use dead remotes. I think this is ok; maybe the dead remote is not 100% dead yet; if it is, the remote can be removed from git's configuration to prevent it being used of course.
+"""]]
diff --git a/doc/bugs/Tries_to_upload_to_remote_although_remote_is_dead/comment_2_fa5b1bc26ed3e5bfe48441490c94fe3a._comment b/doc/bugs/Tries_to_upload_to_remote_although_remote_is_dead/comment_2_fa5b1bc26ed3e5bfe48441490c94fe3a._comment
new file mode 100644
index 000000000..fd0d9d2ab
--- /dev/null
+++ b/doc/bugs/Tries_to_upload_to_remote_although_remote_is_dead/comment_2_fa5b1bc26ed3e5bfe48441490c94fe3a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://www.dbruhn.de/"
+ nickname="Dominik"
+ subject="comment 2"
+ date="2012-11-08T14:13:00Z"
+ content="""
+Actually this happens when using the assistant.
+"""]]
diff --git a/doc/bugs/Tries_to_upload_to_remote_although_remote_is_dead/comment_3_0a785b5dfbf4eef30854d6bedb12b7d1._comment b/doc/bugs/Tries_to_upload_to_remote_although_remote_is_dead/comment_3_0a785b5dfbf4eef30854d6bedb12b7d1._comment
new file mode 100644
index 000000000..e839e7a15
--- /dev/null
+++ b/doc/bugs/Tries_to_upload_to_remote_although_remote_is_dead/comment_3_0a785b5dfbf4eef30854d6bedb12b7d1._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.252.11.120"
+ subject="comment 3"
+ date="2012-11-13T18:00:42Z"
+ content="""
+I've tried & failed to reproduce this using the assistant. When I mark a repo as dead, and go into Configuration -> Manage repositories, the repository is not shown in the list of repositories it'll sync to, and it certainly doesn't upload any files to it.
+
+
+"""]]
diff --git a/doc/bugs/Trouble_initializing_git_annex_on_NFS.mdwn b/doc/bugs/Trouble_initializing_git_annex_on_NFS.mdwn
new file mode 100644
index 000000000..8eb20baf9
--- /dev/null
+++ b/doc/bugs/Trouble_initializing_git_annex_on_NFS.mdwn
@@ -0,0 +1,16 @@
+The following occurs in a directory that is shared on an NFS server:
+
+ /media/mybook/movies $ git init
+ Initialized empty Git repository in /media/mybook/movies/.git/
+ /media/mybook/movies $ git annex init mybook-movies
+ init mybook-movies
+ git-annex: waitToSetLock: resource exhausted (No locks available)
+ failed
+ git-annex: init: 1 failed
+ /media/mybook/movies $
+
+This happens reliably. Is there any way around it? I have shell
+access on the NFS server, but it is a NAS, so I don't think it is
+capable of running git-annex.
+
+[[done]]
diff --git a/doc/bugs/Trouble_initializing_git_annex_on_NFS/comment_1_e26952373150d63b8a5d3643a2762de1._comment b/doc/bugs/Trouble_initializing_git_annex_on_NFS/comment_1_e26952373150d63b8a5d3643a2762de1._comment
new file mode 100644
index 000000000..8e951ab7c
--- /dev/null
+++ b/doc/bugs/Trouble_initializing_git_annex_on_NFS/comment_1_e26952373150d63b8a5d3643a2762de1._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-11-15T04:40:35Z"
+ content="""
+git-annex uses locking to avoid problems if multiple processes are run at the same time.
+
+I just tested on NFS, with Linux on the server and client, and it works ok. It seems your NFS client (or server) must not support fncl locking. What OS is your NAS running?
+"""]]
diff --git a/doc/bugs/Trouble_initializing_git_annex_on_NFS/comment_2_f80b10ed395738e50e345fc22c708ae5._comment b/doc/bugs/Trouble_initializing_git_annex_on_NFS/comment_2_f80b10ed395738e50e345fc22c708ae5._comment
new file mode 100644
index 000000000..bd302e6be
--- /dev/null
+++ b/doc/bugs/Trouble_initializing_git_annex_on_NFS/comment_2_f80b10ed395738e50e345fc22c708ae5._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 2"
+ date="2011-11-15T04:46:13Z"
+ content="""
+You might try mounting your NAS with the mount option `local_lock=all`
+
+This will keep the lock files on your (I assume linux) client. If you do this make sure you don't have another client using git-annex in the same NFS directory.
+"""]]
diff --git a/doc/bugs/Trouble_initializing_git_annex_on_NFS/comment_3_f99e0f05950fc2fc80fdecd35e17012c._comment b/doc/bugs/Trouble_initializing_git_annex_on_NFS/comment_3_f99e0f05950fc2fc80fdecd35e17012c._comment
new file mode 100644
index 000000000..b95c795ea
--- /dev/null
+++ b/doc/bugs/Trouble_initializing_git_annex_on_NFS/comment_3_f99e0f05950fc2fc80fdecd35e17012c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://cgray.myopenid.com/"
+ nickname="cgray"
+ subject="comment 3"
+ date="2011-11-15T05:14:03Z"
+ content="""
+I did a bit of research and my NAS had ancient NFS software on it. I upgraded that and things are now working as expected. Sorry for the noise.
+"""]]
diff --git a/doc/bugs/Trouble_initializing_git_annex_on_NFS/comment_4_e42146d2dcc4052266dd61d204aeb551._comment b/doc/bugs/Trouble_initializing_git_annex_on_NFS/comment_4_e42146d2dcc4052266dd61d204aeb551._comment
new file mode 100644
index 000000000..59919789e
--- /dev/null
+++ b/doc/bugs/Trouble_initializing_git_annex_on_NFS/comment_4_e42146d2dcc4052266dd61d204aeb551._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmnG4EuvZWse5hvgrl0XAK-U61e-0iGaao"
+ nickname="David"
+ subject="nolock option worked"
+ date="2012-10-01T20:31:18Z"
+ content="""
+I had the same problem on my NAS, updated the firmware but it didn't solve it. The remedy was to mount the NAS with the 'nolock' option.
+"""]]
diff --git a/doc/bugs/True_backup_support.mdwn b/doc/bugs/True_backup_support.mdwn
new file mode 100644
index 000000000..72fd9fb1f
--- /dev/null
+++ b/doc/bugs/True_backup_support.mdwn
@@ -0,0 +1,7 @@
+I'd like to be able to restore my data from S3/Glacier following a catastrophic loss of information.
+
+As I understand it, git-annex doesn't solve this problem for me because it only stores file *contents* in S3/Glacier. A restore-from-nothing requires both the file contents and also the file names and metadata, which git-annex doesn't store in S3.
+
+I'm still feeling my way around git-annex, but I think it will probably be sufficient for my purposes to set up a cron job to push my annex to github. But I think it would be helpful if git-annex could take care of this automatically.
+
+> Based on the comments, this is [[done]] --[[Joey]]
diff --git a/doc/bugs/True_backup_support/comment_1_50aa0bc1e2502622585682cb703e0b85._comment b/doc/bugs/True_backup_support/comment_1_50aa0bc1e2502622585682cb703e0b85._comment
new file mode 100644
index 000000000..33ad32eaa
--- /dev/null
+++ b/doc/bugs/True_backup_support/comment_1_50aa0bc1e2502622585682cb703e0b85._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnSenxKyE_2Z6Wb-EBMO8FciyRywjx1ZiQ"
+ nickname="Walter"
+ subject="I think this already works"
+ date="2013-05-01T03:09:13Z"
+ content="""
+I think this should already work in the latest git version, I have been using this feature for the last week or so.
+
+This change was described in [[/design/assistant/blog/day_245__misc/]], and I asked for it [[here|/forum/Automatically_syncronise_centralised_repository/]].
+"""]]
diff --git a/doc/bugs/True_backup_support/comment_2_d6030c6c49b227e022f05d590746d4ca._comment b/doc/bugs/True_backup_support/comment_2_d6030c6c49b227e022f05d590746d4ca._comment
new file mode 100644
index 000000000..f8059d5a7
--- /dev/null
+++ b/doc/bugs/True_backup_support/comment_2_d6030c6c49b227e022f05d590746d4ca._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmUJBh1lYmvfCCiGr3yrdx-QhuLCSRnU5c"
+ nickname="Justin"
+ subject="comment 2"
+ date="2013-05-01T03:12:23Z"
+ content="""
+Indeed, this looks like what I'm after. Thanks!
+"""]]
diff --git a/doc/bugs/Truncated_file_transferred_via_S3.mdwn b/doc/bugs/Truncated_file_transferred_via_S3.mdwn
new file mode 100644
index 000000000..9261c8a05
--- /dev/null
+++ b/doc/bugs/Truncated_file_transferred_via_S3.mdwn
@@ -0,0 +1,614 @@
+### Please describe the problem.
+
+I have two machines connected with annex assistant via XMPP and S3. I placed a file into the annex directory on one computer, and it fairly immediately transferred to the other, as expected. However the resulting file appears to be truncated.
+
+### What steps will reproduce the problem?
+
+Unknown, I haven't noticed this happen before.
+
+### What version of git-annex are you using? On what operating system?
+
+The sending end was from commit ef1fd09c5c1c3950727f0760df36075e45192b33 (Tue Jul 2 16:52:43 2013 +0000), the receiving end was at 1c16de8ebcef6c1920a8437af380f8aea5a2c535 (Wed Jun 12 20:31:43 2013 +0000). Both on Ubuntu 13.04.
+
+### Please provide any additional information below.
+
+Details of the file at the sending end:
+
+[[!format text """
+$ stat git-annex_4.20130627_amd64.deb
+ Bestand: ‘git-annex_4.20130627_amd64.deb’
+ Grootte: 10140744 Blokken: 19808 IO-blok: 4096 normaal bestand
+Apparaat: 801h/2049d Inode: 27394054 Koppelingen: 1
+Toegang: (0644/-rw-r--r--) UID: ( 1000/ robin) GID: ( 1000/ robin)
+Toegang: 2013-07-03 21:57:26.774297184 +1200
+Gewijzigd: 2013-07-03 21:57:25.526306867 +1200
+Veranderd: 2013-07-03 21:57:26.770297214 +1200
+"""]]
+
+and at the receiving end:
+
+[[!format text """
+ Bestand: ‘git-annex_4.20130627_amd64.deb’
+ Grootte: 10105870 Blokken: 19760 IO-blok: 4096 normaal bestand
+Apparaat: 16h/22d Inode: 6167474 Koppelingen: 1
+Toegang: (0664/-rw-rw-r--) UID: ( 1000/ robin) GID: ( 1000/ robin)
+Toegang: 2013-07-03 10:58:02.653724449 +0100
+Gewijzigd: 2013-07-03 10:58:02.365724461 +0100
+Veranderd: 2013-07-03 10:58:02.369724461 +0100
+"""]]
+
+(it was coincidence I expect that it was a deb of git-annex I'd just made :)
+
+Some more poking indicates that it's not strictly a truncation, not too far into the file, the content changes:
+
+Sent:
+
+[[!format text """
+00002a0 4ea6 bb1e 4c18 d54e b836 b19a d9a2 6314
+00002b0 4a0d 2954 d6aa fb42 2699 7437 df7f 6a6d
+00002c0 7f7f 4f1c bce5 5e0f 5cc3 d5b1 e896 2829
+00002d0 4ed2 8426 9496 a669 3dd1 d6ed 26dd 3b1d
+00002e0 4c2a 4ef2 e29b 778c 4818 0e49 990e 314c
+"""]]
+
+Received:
+
+[[!format text """
+00002a0 4ea6 bb1e 4c18 d54e b836 b19a d9a2 6314
+00002b0 544a aa29 42d6 99fb 3726 7f74 6ddf 7f6a
+00002c0 1c7f e54f 0fbc c35e b15c 96d5 29e8 d228
+00002d0 264e 9684 6994 d1a6 ed3d ddd6 1d26 2a3b
+00002e0 f24c 9b4e 8ce2 1877 4948 0e0e 4c99 1931
+"""]]
+
+Oddly, there seems to be a pattern in the difference of the first incorrect row, it looks like kind of like strange endian weirdness rearranging things.
+
+aabb ccdd eeff gghh
+
+becomes:
+
+bbdd ffcc hhee ..gg
+
+where the .. comes from further along the pattern.
+
+Deleting and re-adding the file doesn't cause the new version to appear, but that's presumably because it's addressing by SHA, so it doesn't see that as a change.
+
+[[!format text """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+Sending machine:
+
+(started...) [2013-07-03 21:57:17 NZST] XMPPSendPack: Syncing with eythian
+[2013-07-03 21:57:17 NZST] XMPPReceivePack: Syncing with eythian
+Everything up-to-date
+[2013-07-03 21:57:25 NZST] Committer: Adding git-annex..amd64.deb
+
+add git-annex_4.20130627_amd64.deb (checksum...) [2013-07-03 21:57:25 NZST] Committer: Committing changes to git
+[2013-07-03 21:57:25 NZST] Pusher: Syncing with backups
+To /mnt/backups/annex
+ 2783051..69b3503 git-annex -> synced/git-annex
+ 0b10576..e1b6f29 master -> synced/master
+(gpg) Already up-to-date.
+Already up-to-date.
+[2013-07-03 21:57:26 NZST] XMPPSendPack: Syncing with eythian
+[2013-07-03 21:57:26 NZST] Committer: Adding git-annex..amd64.deb
+ok
+(Recording state in git...)
+(Recording state in git...)
+
+
+add git-annex_4.20130627_amd64.deb (checksum...) [2013-07-03 21:57:26 NZST] Committer: Committing changes to git
+
+0% 96.0KB/s 1m42s[2013-07-03 21:57:27 NZST] Pusher: Syncing with backups
+To /mnt/backups/annex
+ 69b3503..026ba8e git-annex -> synced/git-annex
+To xmpp::eythian@jabber.kallisti.net.nz
+ 2783051..69b3503 git-annex -> refs/synced/9e67bebc-655c-47da-97a0-2bb02bbbc580/ZXl0aGlhbkBqYWJiZXIua2FsbGlzdGkubmV0Lm56/git-annex
+ 0b10576..e1b6f29 master -> refs/synced/9e67bebc-655c-47da-97a0-2bb02bbbc580/ZXl0aGlhbkBqYWJiZXIua2FsbGlzdGkubmV0Lm56/master
+1% 127.9KB/s 1m16s[2013-07-03 21:57:27 NZST] XMPPSendPack: Syncing with eythian
+25% 631.7KB/s 12sTo xmpp::eythian@jabber.kallisti.net.nz
+ 69b3503..35b3fd8 git-annex -> refs/synced/9e67bebc-655c-47da-97a0-2bb02bbbc580/ZXl0aGlhbkBqYWJiZXIua2FsbGlzdGkubmV0Lm56/git-annex
+[2013-07-03 21:57:30 NZST] XMPPSendPack: Syncing with eythian
+51% 1.2MB/s 4sEverything up-to-date
+[2013-07-03 21:57:34 NZST] Transferrer: Uploaded git-annex..amd64.deb
+[2013-07-03 21:57:34 NZST] Pusher: Syncing with backups
+To /mnt/backups/annex
+ 026ba8e..1eb67d8 git-annex -> synced/git-annex
+[2013-07-03 21:57:35 NZST] XMPPSendPack: Syncing with eythian
+To xmpp::eythian@jabber.kallisti.net.nz
+ 35b3fd8..1eb67d8 git-annex -> refs/synced/9e67bebc-655c-47da-97a0-2bb02bbbc580/ZXl0aGlhbkBqYWJiZXIua2FsbGlzdGkubmV0Lm56/git-annex
+[2013-07-03 21:57:36 NZST] XMPPSendPack: Syncing with eythian
+Everything up-to-date
+[2013-07-03 21:58:03 NZST] XMPPReceivePack: Syncing with eythian
+Already up-to-date.
+[2013-07-03 21:58:04 NZST] XMPPReceivePack: Syncing with eythian
+[2013-07-03 22:09:44 NZST] XMPPSendPack: Syncing with eythian
+To xmpp::eythian@jabber.kallisti.net.nz
+ 1eb67d8..822dbb1 git-annex -> refs/synced/9e67bebc-655c-47da-97a0-2bb02bbbc580/ZXl0aGlhbkBqYWJiZXIua2FsbGlzdGkubmV0Lm56/git-annex
+[2013-07-03 22:09:45 NZST] XMPPSendPack: Syncing with eythian
+Everything up-to-date
+
+Receiving machine:
+
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from 0/ Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from a18/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from a22/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from a20/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from b24/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from c27/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from c25/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from c16/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from c22/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from c21/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from d23/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from d24/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from d15/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from d27/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from d15/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from d21/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from d24/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from f21/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from h24/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from h24/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from h26/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from j22/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from j20/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from j23/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from k22/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from k26/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from k26/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from k22/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from l26/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from l17/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from m32/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from m23/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from m18/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from m21/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from o20/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from s24/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from s24/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from s19/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from s21/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from s25/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from s19/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from s20/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from s25/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from s16/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from s26/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from w23/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from w20/msn Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from e7/27209141331372845435882587 Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: sending to new client: e7/27209141331372845435882587 "Pushing \"e57\" (CanPush (UUID \"2c0b788e-7b2d-474b-8963-d889b9556229\") [0b10576100879220b2f50bf53f552befe2fda8de,27830516f221de09f7906954ba0bcc6b3dd31680])"
+[2013-07-03 10:57:16 BST] XMPPClient: sending to new client: e7/27209141331372845435882587 "Pushing \"e57\" (PushRequest (UUID \"2c0b788e-7b2d-474b-8963-d889b9556229\"))"
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from m9/Adium Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from p6/NEW_HOTNESS Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from 0/ Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from e7/27209141331372845435882587 Just (Element {elementName = Name {nameLocalName = \"git-annex\", nameNamespace = Just \"git-annex\", namePrefix = Nothing}, elementAttributes = [], elementNodes = []})"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from 0/ Nothing"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from e7/27209141331372845435882587 Just (Element {elementName = Name {nameLocalName = \"git-annex\", nameNamespace = Just \"git-annex\", namePrefix = Nothing}, elementAttributes = [(Name {nameLocalName = \"query\", nameNamespace = Nothing, namePrefix = Nothing},[ContentText \"\"])], elementNodes = []})","QueryPresence"]
+[2013-07-03 10:57:16 BST] XMPPClient: received: ["Presence from e7/27209141331372845435882587 Just (Element {elementName = Name {nameLocalName = \"git-annex\", nameNamespace = Just \"git-annex\", namePrefix = Nothing}, elementAttributes = [(Name {nameLocalName = \"push\", nameNamespace = Nothing, namePrefix = Nothing},[ContentText \"a23dd126-7bb7-42ce-b15a-b01990df5f2a\"])], elementNodes = []})","NotifyPush [UUID \"a23dd126-7bb7-42ce-b15a-b01990df5f2a\"]"]
+[2013-07-03 10:57:17 BST] XMPPClient: push notification for
+[2013-07-03 10:57:17 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","symbolic-ref","HEAD"]
+[2013-07-03 10:57:17 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","show-ref","refs/heads/master"]
+[2013-07-03 10:57:17 BST] XMPPClient: received: ["Presence from e7/27209141331372845435882587 Just (Element {elementName = Name {nameLocalName = \"git-annex\", nameNamespace = Just \"git-annex\", namePrefix = Nothing}, elementAttributes = [(Name {nameLocalName = \"query\", nameNamespace = Nothing, namePrefix = Nothing},[ContentText \"\"])], elementNodes = []})","QueryPresence"]
+[2013-07-03 10:57:17 BST] XMPPClient: received: ["Presence from 0/ Nothing"]
+[2013-07-03 10:57:17 BST] XMPPClient: received: ["Presence from 0/ Nothing"]
+[2013-07-03 10:57:17 BST] XMPPClient: received: ["Presence from 0/ Nothing"]
+[2013-07-03 10:57:17 BST] XMPPClient: received: ["Pushing \"e57\" (CanPush (UUID \"9e67bebc-655c-47da-97a0-2bb02bbbc580\") [0b10576100879220b2f50bf53f552befe2fda8de,27830516f221de09f7906954ba0bcc6b3dd31680])"]
+[2013-07-03 10:57:17 BST] XMPPClient: ignoring CanPush with known shas
+[2013-07-03 10:57:17 BST] XMPPClient: received: ["Pushing \"e57\" (PushRequest (UUID \"9e67bebc-655c-47da-97a0-2bb02bbbc580\"))"]
+[2013-07-03 10:57:17 BST] XMPPSendPack: started running push Pushing "e57" (PushRequest (UUID "9e67bebc-655c-47da-97a0-2bb02bbbc580"))
+[2013-07-03 10:57:17 BST] XMPPClient: received: ["Presence from 0/ Nothing"]
+[2013-07-03 10:57:17 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","symbolic-ref","HEAD"]
+[2013-07-03 10:57:17 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","show-ref","refs/heads/master"]
+[2013-07-03 10:57:17 BST] call: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","branch","-f","synced/master"]
+[2013-07-03 10:57:17 BST] XMPPSendPack: Syncing with eythian
+[2013-07-03 10:57:17 BST] XMPPClient: sending: Pushing "e57" (StartingPush (UUID "2c0b788e-7b2d-474b-8963-d889b9556229"))
+[2013-07-03 10:57:17 BST] call: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","push","eythian","git-annex:refs/synced/2c0b788e-7b2d-474b-8963-d889b9556229/ZXl0aGlhbkBqYWJiZXIua2FsbGlzdGkubmV0Lm56/git-annex","refs/heads/master:refs/synced/2c0b788e-7b2d-474b-8963-d889b9556229/ZXl0aGlhbkBqYWJiZXIua2FsbGlzdGkubmV0Lm56/master"]
+[2013-07-03 10:57:17 BST] XMPPClient: to client: e7/27209141331372845435882587
+[2013-07-03 10:57:17 BST] XMPPClient: received: ["Presence from 0/ Nothing"]
+[2013-07-03 10:57:17 BST] XMPPClient: received: ["Pushing \"e57\" (StartingPush (UUID \"9e67bebc-655c-47da-97a0-2bb02bbbc580\"))"]
+[2013-07-03 10:57:17 BST] XMPPReceivePack: started running push Pushing "e57" (StartingPush (UUID "9e67bebc-655c-47da-97a0-2bb02bbbc580"))
+[2013-07-03 10:57:17 BST] XMPPClient: received: ["Pushing \"e57\" (ReceivePackOutput 1 \"<elided>\")"]
+[2013-07-03 10:57:17 BST] XMPPReceivePack: Syncing with eythian
+[2013-07-03 10:57:17 BST] XMPPClient: NetMessager stored Pushing "e57" (ReceivePackOutput 1 "<elided>") in SendPack inbox "e57"
+[2013-07-03 10:57:17 BST] chat: git ["receive-pack","/home/robin/Bureaublad/annex"]
+[2013-07-03 10:57:17 BST] XMPPClient: received: ["Pushing \"e57\" (ReceivePackOutput 2 \"<elided>\")"]
+[2013-07-03 10:57:17 BST] XMPPClient: sending: Pushing "e57" (ReceivePackOutput 1 "<elided>")
+[2013-07-03 10:57:17 BST] XMPPClient: NetMessager stored Pushing "e57" (ReceivePackOutput 2 "<elided>") in SendPack inbox "e57"
+[2013-07-03 10:57:17 BST] XMPPClient: to client: e7/27209141331372845435882587
+[2013-07-03 10:57:17 BST] XMPPClient: sending: Pushing "e57" (ReceivePackOutput 2 "<elided>")
+[2013-07-03 10:57:17 BST] XMPPClient: to client: e7/27209141331372845435882587
+[2013-07-03 10:57:17 BST] XMPPClient: sending: Pushing "e57" (ReceivePackOutput 3 "<elided>")
+[2013-07-03 10:57:17 BST] XMPPClient: to client: e7/27209141331372845435882587
+[2013-07-03 10:57:17 BST] XMPPClient: received: ["Pushing \"e57\" (ReceivePackOutput 3 \"<elided>\")"]
+[2013-07-03 10:57:17 BST] XMPPClient: NetMessager stored Pushing "e57" (ReceivePackOutput 3 "<elided>") in SendPack inbox "e57"
+[2013-07-03 10:57:17 BST] XMPPClient: received: ["Pushing \"e57\" (ReceivePackOutput 4 \"<elided>\")"]
+[2013-07-03 10:57:17 BST] XMPPClient: NetMessager stored Pushing "e57" (ReceivePackOutput 4 "<elided>") in SendPack inbox "e57"
+[2013-07-03 10:57:17 BST] XMPPClient: received: ["Pushing \"e57\" (ReceivePackOutput 5 \"<elided>\")"]
+[2013-07-03 10:57:17 BST] XMPPClient: NetMessager stored Pushing "e57" (ReceivePackOutput 5 "<elided>") in SendPack inbox "e57"
+[2013-07-03 10:57:17 BST] XMPPClient: sending: Pushing "e57" (SendPackOutput 1 "<elided>")
+[2013-07-03 10:57:17 BST] XMPPClient: to client: e7/27209141331372845435882587
+[2013-07-03 10:57:18 BST] XMPPClient: received: ["Pushing \"e57\" (SendPackOutput 1 \"<elided>\")"]
+[2013-07-03 10:57:18 BST] XMPPClient: NetMessager stored Pushing "e57" (SendPackOutput 1 "<elided>") in ReceivePack inbox "e57"
+[2013-07-03 10:57:18 BST] XMPPReceivePack: finished running push Pushing "e57" (StartingPush (UUID "9e67bebc-655c-47da-97a0-2bb02bbbc580")) True
+[2013-07-03 10:57:18 BST] XMPPClient: sending: Pushing "e57" (ReceivePackDone ExitSuccess)
+[2013-07-03 10:57:18 BST] XMPPClient: to client: e7/27209141331372845435882587
+[2013-07-03 10:57:18 BST] XMPPClient: received: ["Pushing \"e57\" (ReceivePackDone ExitSuccess)"]
+[2013-07-03 10:57Everything up-to-date
+:18 BST] XMPPClient: NetMessager stored Pushing "e57" (ReceivePackDone ExitSuccess) in SendPack inbox "e57"
+[2013-07-03 10:57:18 BST] XMPPSendPack: finished running push Pushing "e57" (PushRequest (UUID "9e67bebc-655c-47da-97a0-2bb02bbbc580")) True
+[2013-07-03 10:57:21 BST] XMPPClient: received: ["Presence from a15/android_talk53f054b9e972 Nothing"]
+[2013-07-03 10:57:26 BST] XMPPClient: received: ["Presence from e7/27209141331372845435882587 Just (Element {elementName = Name {nameLocalName = \"git-annex\", nameNamespace = Just \"git-annex\", namePrefix = Nothing}, elementAttributes = [(Name {nameLocalName = \"push\", nameNamespace = Nothing, namePrefix = Nothing},[ContentText \"a23dd126-7bb7-42ce-b15a-b01990df5f2a\"])], elementNodes = []})","NotifyPush [UUID \"a23dd126-7bb7-42ce-b15a-b01990df5f2a\"]"]
+[2013-07-03 10:57:26 BST] XMPPClient: push notification for
+[2013-07-03 10:57:26 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","symbolic-ref","HEAD"]
+[2013-07-03 10:57:26 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","show-ref","refs/heads/master"]
+[2013-07-03 10:57:26 BST] XMPPClient: received: ["Presence from 0/ Nothing"]
+[2013-07-03 10:57:26 BST] XMPPClient: received: ["Presence from e7/27209141331372845435882587 Just (Element {elementName = Name {nameLocalName = \"git-annex\", nameNamespace = Just \"git-annex\", namePrefix = Nothing}, elementAttributes = [(Name {nameLocalName = \"query\", nameNamespace = Nothing, namePrefix = Nothing},[ContentText \"\"])], elementNodes = []})","QueryPresence"]
+[2013-07-03 10:57:26 BST] XMPPClient: received: ["Pushing \"e57\" (CanPush (UUID \"9e67bebc-655c-47da-97a0-2bb02bbbc580\") [e1b6f2944e7d082299cb1696c55d9064a11c4577,69b3503287d87c26989a755d0cc660c3c68f2c80])"]
+[2013-07-03 10:57:26 BST] XMPPClient: sending: Pushing "e57" (PushRequest (UUID "2c0b788e-7b2d-474b-8963-d889b9556229"))
+[2013-07-03 10:57:26 BST] XMPPClient: to client: e7/27209141331372845435882587
+[2013-07-03 10:57:26 BST] XMPPClient: received: ["Presence from 0/ Nothing"]
+[2013-07-03 10:57:26 BST] XMPPClient: received: ["Pushing \"e57\" (CanPush (UUID \"9e67bebc-655c-47da-97a0-2bb02bbbc580\") [e1b6f2944e7d082299cb1696c55d9064a11c4577,69b3503287d87c26989a755d0cc660c3c68f2c80])"]
+[2013-07-03 10:57:26 BST] XMPPClient: sending: Pushing "e57" (PushRequest (UUID "2c0b788e-7b2d-474b-8963-d889b9556229"))
+[2013-07-03 10:57:26 BST] XMPPClient: to client: e7/27209141331372845435882587
+[2013-07-03 10:57:26 BST] XMPPClient: received: ["Pushing \"e57\" (StartingPush (UUID \"9e67bebc-655c-47da-97a0-2bb02bbbc580\"))"]
+[2013-07-03 10:57:26 BST] XMPPReceivePack: started running push Pushing "e57" (StartingPush (UUID "9e67bebc-655c-47da-97a0-2bb02bbbc580"))
+[2013-07-03 10:57:26 BST] XMPPReceivePack: Syncing with eythian
+[2013-07-03 10:57:26 BST] chat: git ["receive-pack","/home/robin/Bureaublad/annex"]
+[2013-07-03 10:57:26 BST] XMPPClient: sending: Pushing "e57" (ReceivePackOutput 1 "<elided>")
+[2013-07-03 10:57:26 BST] XMPPClient: to client: e7/27209141331372845435882587
+[2013-07-03 10:57:26 BST] XMPPClient: sending: Pushing "e57" (ReceivePackOutput 2 "<elided>")
+[2013-07-03 10:57:26 BST] XMPPClient: to client: e7/27209141331372845435882587
+[2013-07-03 10:57:27 BST] XMPPClient: received: ["Pushing \"e57\" (SendPackOutput 1 \"<elided>\")"]
+[2013-07-03 10:57:27 BST] XMPPClient: NetMessager stored Pushing "e57" (SendPackOutput 1 "<elided>") in ReceivePack inbox "e57"
+[2013-07-03 10:57:27 BST] XMPPClient: received: ["Pushing \"e57\" (SendPackOutput 2 \"<elided>\")"]
+[2013-07-03 10:57:27 BST] XMPPClient: NetMessager stored Pushing "e57" (SendPackOutput 2 "<elided>") in ReceivePack inbox "e57"
+[2013-07-03 10:57:27 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","show-ref","git-annex"]
+[2013-07-03 10:57:27 BST] XMPPClient: sending: Pushing "e57" (ReceivePackOutput 3 "<elided>")
+[2013-07-03 10:57:27 BST] XMPPReceivePack: finished running push Pushing "e57" (StartingPush (UUID "9e67bebc-655c-47da-97a0-2bb02bbbc580")) True
+[2013-07-03 10:57:27 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","show-ref","--hash","refs/heads/git-annex"]
+[2013-07-03 10:57:27 BST] XMPPClient: to client: e7/27209141331372845435882587
+[2013-07-03 10:57:27 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","log","refs/heads/git-annex..27830516f221de09f7906954ba0bcc6b3dd31680","--oneline","-n1"]
+[2013-07-03 10:57:27 BST] XMPPClient: sending: Pushing "e57" (ReceivePackOutput 4 "<elided>")
+[2013-07-03 10:57:27 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","log","refs/heads/git-annex..69b3503287d87c26989a755d0cc660c3c68f2c80","--oneline","-n1"]
+[2013-07-03 10:57:27 BST] XMPPClient: to client: e7/27209141331372845435882587
+[2013-07-03 10:57:27 BST] feed: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","update-index","-z","--index-info"]
+[2013-07-03 10:57:27 BST] XMPPClient: sending: Pushing "e57" (ReceivePackDone ExitSuccess)
+[2013-07-03 10:57:27 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","diff-index","--raw","-z","-r","--no-renames","-l0","--cached","69b3503287d87c26989a755d0cc660c3c68f2c80"]
+[2013-07-03 10:57:27 BST] XMPPClient: to client: e7/27209141331372845435882587
+[2013-07-03 10:57:27 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","log","69b3503287d87c26989a755d0cc660c3c68f2c80..refs/heads/git-annex","--oneline","-n1"]
+[2013-07-03 10:57:27 BST] call: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","update-ref","refs/heads/git-annex","69b3503287d87c26989a755d0cc660c3c68f2c80"]
+[2013-07-03 10:57:27 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","ls-tree","-z","--","refs/heads/git-annex","uuid.log","remote.log","trust.log","group.log","preferred-content.log"]
+[2013-07-03 10:57:27 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","symbolic-ref","HEAD"]
+[2013-07-03 10:57:27 BST] TransferScanner: starting scan of [Remote { name ="eythian" }]
+[2013-07-03 10:57:27 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","show-ref","refs/heads/master"]
+[2013-07-03 10:57:27 BST] Merger: merging refs/synced/9e67bebc-655c-47da-97a0-2bb02bbbc580/ZXl0aGlhbkBqYWJiZXIua2FsbGlzdGkubmV0Lm56/master into refs/heads/master
+[2013-07-03 10:57:27 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","ls-files","--cached","-z","--"]
+[2013-07-03 10:57:27 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","symbolic-ref","HEAD"]
+[2013-07-03 10:57:27 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","show-ref","refs/heads/master"]
+[2013-07-03 10:57:27 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","show-ref","--hash","refs/heads/master"]
+[2013-07-03 10:57:27 BST] call: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex/.git/annex/merge/","merge","--no-edit","refs/synced/9e67bebc-655c-47da-97a0-2bb02bbbc580/ZXl0aGlhbkBqYWJiZXIua2FsbGlzdGkubmV0Lm56/master"]
+Updating 0b10576..e1b6f29
+Fast-forward
+ git-annex_4.20130627_amd64.deb | 1 +
+ 1 file changed, 1 insertion(+)
+ create mode 120000 git-annex_4.20130627_amd64.deb
+[2013-07-03 10:57:27 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","show-ref","--hash","refs/heads/master"]
+[2013-07-03 10:57:27 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","diff-tree","-z","--raw","--no-renames","-l0","-r","0b10576100879220b2f50bf53f552befe2fda8de","e1b6f2944e7d082299cb1696c55d9064a11c4577"]
+[2013-07-03 10:57:27 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","show-ref","git-annex"]
+[2013-07-03 10:57:27 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","show-ref","--hash","refs/heads/git-annex"]
+[2013-07-03 10:57:27 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","log","refs/heads/git-annex..69b3503287d87c26989a755d0cc660c3c68f2c80","--oneline","-n1"]
+[2013-07-03 10:57:27 BST] feed: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","update-index","-z","--index-info"]
+[2013-07-03 10:57:27 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","diff-index","--raw","-z","-r","--no-renames","-l0","--cached","refs/heads/git-annex"]
+[2013-07-03 10:57:28 BST] Watcher: add symlink git-annex_4.20130627_amd64.deb
+[2013-07-03 10:57:28 BST] chat: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","hash-object","-t","blob","-w","--stdin"]
+[2013-07-03 10:57:28 BST] Committer: committing 1 changes
+[2013-07-03 10:57:28 BST] Committer: Committing changes to git
+[2013-07-03 10:57:28 BST] XMPPClient: received: ["Presence from e7/27209141331372845435882587 Just (Element {elementName = Name {nameLocalName = \"git-annex\", nameNamespace = Just \"git-annex\", namePrefix = Nothing}, elementAttributes = [(Name {nameLocalName = \"push\", nameNamespace = Nothing, namePrefix = Nothing},[ContentText \"a23dd126-7bb7-42ce-b15a-b01990df5f2a\"])], elementNodes = []})","NotifyPush [UUID \"a23dd126-7bb7-42ce-b15a-b01990df5f2a\"]"]
+[2013-07-03 10:57:28 BST] feed: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","update-index","-z","--index-info"]
+[2013-07-03 10:57:28 BST] XMPPClient: push notification for
+[2013-07-03 10:57:28 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","commit","--allow-empty-message","--no-edit","-m","","--quiet","--no-verify"]
+[2013-07-03 10:57:28 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","symbolic-ref","HEAD"]
+[2013-07-03 10:57:28 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","show-ref","refs/heads/master"]
+[2013-07-03 10:57:28 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","symbolic-ref","HEAD"]
+[2013-07-03 10:57:28 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","show-ref","refs/heads/master"]
+[2013-07-03 10:57:28 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","show-ref","--head","refs/heads/git-annex","HEAD"]
+[2013-07-03 10:57:28 BST] XMPPClient: sending: Pushing "e30" (CanPush (UUID "2c0b788e-7b2d-474b-8963-d889b9556229") [e1b6f2944e7d082299cb1696c55d9064a11c4577,69b3503287d87c26989a755d0cc660c3c68f2c80])
+[2013-07-03 10:57:28 BST] XMPPClient: received: ["Presence from e7/27209141331372845435882587 Just (Element {elementName = Name {nameLocalName = \"git-annex\", nameNamespace = Just \"git-annex\", namePrefix = Nothing}, elementAttributes = [(Name {nameLocalName = \"query\", nameNamespace = Nothing, namePrefix = Nothing},[ContentText \"\"])], elementNodes = []})","QueryPresence"]
+[2013-07-03 10:57:28 BST] XMPPClient: exploded undirected message to clients e7/27209141331372845435882587
+[2013-07-03 10:57:28 BST] XMPPClient: sending to new client: e7/27209141331372845435882587 "Pushing \"e57\" (CanPush (UUID \"2c0b788e-7b2d-474b-8963-d889b9556229\") [e1b6f2944e7d082299cb1696c55d9064a11c4577,69b3503287d87c26989a755d0cc660c3c68f2c80])"
+[2013-07-03 10:57:28 BST] XMPPClient: received: ["Pushing \"e57\" (CanPush (UUID \"9e67bebc-655c-47da-97a0-2bb02bbbc580\") [e1b6f2944e7d082299cb1696c55d9064a11c4577,026ba8e7ba89bccd22f5ff31a26c82ee75641b55])"]
+[2013-07-03 10:57:28 BST] XMPPClient: sending: Pushing "e57" (PushRequest (UUID "2c0b788e-7b2d-474b-8963-d889b9556229"))
+[2013-07-03 10:57:28 BST] XMPPClient: received: ["Pushing \"e57\" (StartingPush (UUID \"9e67bebc-655c-47da-97a0-2bb02bbbc580\"))"]
+[2013-07-03 10:57:28 BST] XMPPClient: to client: e7/27209141331372845435882587
+[2013-07-03 10:57:28 BST] XMPPReceivePack: started running push Pushing "e57" (StartingPush (UUID "9e67bebc-655c-47da-97a0-2bb02bbbc580"))
+[2013-07-03 10:57:29 BST] XMPPClient: received: ["Pushing \"e57\" (CanPush (UUID \"9e67bebc-655c-47da-97a0-2bb02bbbc580\") [e1b6f2944e7d082299cb1696c55d9064a11c4577,026ba8e7ba89bccd22f5ff31a26c82ee75641b55])"]
+[2013-07-03 10:57:29 BST] XMPPReceivePack: Syncing with eythian
+[2013-07-03 10:57:29 BST] XMPPClient: sending: Pushing "e57" (PushRequest (UUID "2c0b788e-7b2d-474b-8963-d889b9556229"))
+[2013-07-03 10:57:29 BST] chat: git ["receive-pack","/home/robin/Bureaublad/annex"]
+[2013-07-03 10:57:29 BST] XMPPClient: received: ["Presence from e7/27209141331372845435882587 Just (Element {elementName = Name {nameLocalName = \"git-annex\", nameNamespace = Just \"git-annex\", namePrefix = Nothing}, elementAttributes = [], elementNodes = []})"]
+[2013-07-03 10:57:29 BST] XMPPClient: to client: e7/27209141331372845435882587
+[2013-07-03 10:57:29 BST] XMPPClient: sending: Pushing "e57" (ReceivePackOutput 1 "<elided>")
+[2013-07-03 10:57:29 BST] XMPPClient: to client: e7/27209141331372845435882587
+[2013-07-03 10:57:29 BST] TransferScanner: finished scan of [Remote { name ="eythian" }]
+[2013-07-03 10:57:29 BST] XMPPClient: received: ["Pushing \"e57\" (SendPackOutput 1 \"<elided>\")"]
+[2013-07-03 10:57:29 BST] XMPPClient: NetMessager stored Pushing "e57" (SendPackOutput 1 "<elided>") in ReceivePack inbox "e57"
+[2013-07-03 10:57:30 BST] XMPPClient: received: ["Pushing \"e57\" (SendPackOutput 2 \"<elided>\")"]
+[2013-07-03 10:57:30 BST] XMPPClient: NetMessager stored Pushing "e57" (SendPackOutput 2 "<elided>") in ReceivePack inbox "e57"
+[2013-07-03 10:57:30 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","show-ref","git-annex"]
+[2013-07-03 10:57:30 BST] XMPPClient: sending: Pushing "e57" (ReceivePackOutput 2 "<elided>")
+[2013-07-03 10:57:30 BST] XMPPReceivePack: finished running push Pushing "e57" (StartingPush (UUID "9e67bebc-655c-47da-97a0-2bb02bbbc580")) True
+[2013-07-03 10:57:30 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","show-ref","--hash","refs/heads/git-annex"]
+[2013-07-03 10:57:30 BST] XMPPClient: to client: e7/27209141331372845435882587
+[2013-07-03 10:57:30 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","log","refs/heads/git-annex..69b3503287d87c26989a755d0cc660c3c68f2c80","--oneline","-n1"]
+[2013-07-03 10:57:30 BST] XMPPClient: sending: Pushing "e57" (ReceivePackOutput 3 "<elided>")
+[2013-07-03 10:57:30 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","log","refs/heads/git-annex..35b3fd81218834a29b9f516b64b4671c0b0902d3","--oneline","-n1"]
+[2013-07-03 10:57:30 BST] XMPPClient: to client: e7/27209141331372845435882587
+[2013-07-03 10:57:30 BST] feed: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","update-index","-z","--index-info"]
+[2013-07-03 10:57:30 BST] XMPPClient: sending: Pushing "e57" (ReceivePackDone ExitSuccess)
+[2013-07-03 10:57:30 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","diff-index","--raw","-z","-r","--no-renames","-l0","--cached","35b3fd81218834a29b9f516b64b4671c0b0902d3"]
+[2013-07-03 10:57:30 BST] XMPPClient: to client: e7/27209141331372845435882587
+[2013-07-03 10:57:30 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","log","35b3fd81218834a29b9f516b64b4671c0b0902d3..refs/heads/git-annex","--oneline","-n1"]
+[2013-07-03 10:57:30 BST] call: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","update-ref","refs/heads/git-annex","35b3fd81218834a29b9f516b64b4671c0b0902d3"]
+[2013-07-03 10:57:30 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","show-ref","git-annex"]
+[2013-07-03 10:57:30 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","show-ref","--hash","refs/heads/git-annex"]
+[2013-07-03 10:57:30 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","log","refs/heads/git-annex..35b3fd81218834a29b9f516b64b4671c0b0902d3","--oneline","-n1"]
+[2013-07-03 10:57:30 BST] feed: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","update-index","-z","--index-info"]
+[2013-07-03 10:57:30 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","diff-index","--raw","-z","-r","--no-renames","-l0","--cached","refs/heads/git-annex"]
+[2013-07-03 10:57:30 BST] XMPPClient: received: ["Pushing \"e57\" (StartingPush (UUID \"9e67bebc-655c-47da-97a0-2bb02bbbc580\"))"]
+[2013-07-03 10:57:30 BST] XMPPReceivePack: started running push Pushing "e57" (StartingPush (UUID "9e67bebc-655c-47da-97a0-2bb02bbbc580"))
+[2013-07-03 10:57:30 BST] XMPPReceivePack: Syncing with eythian
+[2013-07-03 10:57:30 BST] chat: git ["receive-pack","/home/robin/Bureaublad/annex"]
+[2013-07-03 10:57:30 BST] XMPPClient: sending: Pushing "e57" (ReceivePackOutput 1 "<elided>")
+[2013-07-03 10:57:30 BST] XMPPClient: to client: e7/27209141331372845435882587
+[2013-07-03 10:57:30 BST] XMPPClient: sending: Pushing "e57" (ReceivePackOutput 2 "<elided>")
+[2013-07-03 10:57:30 BST] XMPPClient: to client: e7/27209141331372845435882587
+[2013-07-03 10:57:30 BST] XMPPClient: sending: Pushing "e57" (ReceivePackOutput 3 "<elided>")
+[2013-07-03 10:57:30 BST] XMPPClient: to client: e7/27209141331372845435882587
+[2013-07-03 10:57:31 BST] XMPPClient: received: ["Pushing \"e57\" (SendPackOutput 1 \"<elided>\")"]
+[2013-07-03 10:57:31 BST] XMPPClient: NetMessager stored Pushing "e57" (SendPackOutput 1 "<elided>") in ReceivePack inbox "e57"
+[2013-07-03 10:57:31 BST] XMPPReceivePack: finished running push Pushing "e57" (StartingPush (UUID "9e67bebc-655c-47da-97a0-2bb02bbbc580")) True
+[2013-07-03 10:57:31 BST] XMPPClient: sending: Pushing "e57" (ReceivePackDone ExitSuccess)
+[2013-07-03 10:57:31 BST] XMPPClient: to client: e7/27209141331372845435882587
+[2013-07-03 10:57:31 BST] TransferScanner: starting scan of [Remote { name ="eythian" }]
+[2013-07-03 10:57:31 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","ls-files","--cached","-z","--"]
+[2013-07-03 10:57:32 BST] TransferScanner: finished scan of [Remote { name ="eythian" }]
+[2013-07-03 10:57:34 BST] XMPPClient: received: ["Presence from e7/27209141331372845435882587 Just (Element {elementName = Name {nameLocalName = \"git-annex\", nameNamespace = Just \"git-annex\", namePrefix = Nothing}, elementAttributes = [(Name {nameLocalName = \"push\", nameNamespace = Nothing, namePrefix = Nothing},[ContentText \"a23dd126-7bb7-42ce-b15a-b01990df5f2a\"])], elementNodes = []})","NotifyPush [UUID \"a23dd126-7bb7-42ce-b15a-b01990df5f2a\"]"]
+[2013-07-03 10:57:34 BST] XMPPClient: push notification for
+[2013-07-03 10:57:34 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","symbolic-ref","HEAD"]
+[2013-07-03 10:57:34 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","show-ref","refs/heads/master"]
+[2013-07-03 10:57:35 BST] XMPPClient: received: ["Presence from e7/27209141331372845435882587 Just (Element {elementName = Name {nameLocalName = \"git-annex\", nameNamespace = Just \"git-annex\", namePrefix = Nothing}, elementAttributes = [(Name {nameLocalName = \"query\", nameNamespace = Nothing, namePrefix = Nothing},[ContentText \"\"])], elementNodes = []})","QueryPresence"]
+[2013-07-03 10:57:35 BST] XMPPClient: received: ["Pushing \"e57\" (CanPush (UUID \"9e67bebc-655c-47da-97a0-2bb02bbbc580\") [e1b6f2944e7d082299cb1696c55d9064a11c4577,1eb67d85f89c92345757805d83939d75e8ce54a0])"]
+[2013-07-03 10:57:35 BST] XMPPClient: sending: Pushing "e57" (PushRequest (UUID "2c0b788e-7b2d-474b-8963-d889b9556229"))
+[2013-07-03 10:57:35 BST] XMPPClient: to client: e7/27209141331372845435882587
+[2013-07-03 10:57:35 BST] XMPPClient: received: ["Pushing \"e57\" (CanPush (UUID \"9e67bebc-655c-47da-97a0-2bb02bbbc580\") [e1b6f2944e7d082299cb1696c55d9064a11c4577,1eb67d85f89c92345757805d83939d75e8ce54a0])"]
+[2013-07-03 10:57:35 BST] XMPPClient: sending: Pushing "e57" (PushRequest (UUID "2c0b788e-7b2d-474b-8963-d889b9556229"))
+[2013-07-03 10:57:35 BST] XMPPClient: to client: e7/27209141331372845435882587
+[2013-07-03 10:57:35 BST] XMPPClient: received: ["Pushing \"e57\" (StartingPush (UUID \"9e67bebc-655c-47da-97a0-2bb02bbbc580\"))"]
+[2013-07-03 10:57:35 BST] XMPPReceivePack: started running push Pushing "e57" (StartingPush (UUID "9e67bebc-655c-47da-97a0-2bb02bbbc580"))
+[2013-07-03 10:57:35 BST] XMPPReceivePack: Syncing with eythian
+[2013-07-03 10:57:35 BST] chat: git ["receive-pack","/home/robin/Bureaublad/annex"]
+[2013-07-03 10:57:35 BST] XMPPClient: sending: Pushing "e57" (ReceivePackOutput 1 "<elided>")
+[2013-07-03 10:57:35 BST] XMPPClient: to client: e7/27209141331372845435882587
+[2013-07-03 10:57:35 BST] XMPPClient: sending: Pushing "e57" (ReceivePackOutput 2 "<elided>")
+[2013-07-03 10:57:35 BST] XMPPClient: to client: e7/27209141331372845435882587
+[2013-07-03 10:57:36 BST] XMPPClient: received: ["Pushing \"e57\" (SendPackOutput 1 \"<elided>\")"]
+[2013-07-03 10:57:36 BST] XMPPClient: NetMessager stored Pushing "e57" (SendPackOutput 1 "<elided>") in ReceivePack inbox "e57"
+[2013-07-03 10:57:36 BST] XMPPClient: received: ["Pushing \"e57\" (SendPackOutput 2 \"<elided>\")"]
+[2013-07-03 10:57:36 BST] XMPPClient: NetMessager stored Pushing "e57" (SendPackOutput 2 "<elided>") in ReceivePack inbox "e57"
+[2013-07-03 10:57:36 BST] XMPPClient: sending: Pushing "e57" (ReceivePackOutput 3 "<elided>")
+[2013-07-03 10:57:36 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","show-ref","git-annex"]
+[2013-07-03 10:57:36 BST] XMPPReceivePack: finished running push Pushing "e57" (StartingPush (UUID "9e67bebc-655c-47da-97a0-2bb02bbbc580")) True
+[2013-07-03 10:57:36 BST] XMPPClient: to client: e7/27209141331372845435882587
+[2013-07-03 10:57:36 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","show-ref","--hash","refs/heads/git-annex"]
+[2013-07-03 10:57:36 BST] XMPPClient: sending: Pushing "e57" (ReceivePackOutput 4 "<elided>")
+[2013-07-03 10:57:36 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","log","refs/heads/git-annex..35b3fd81218834a29b9f516b64b4671c0b0902d3","--oneline","-n1"]
+[2013-07-03 10:57:36 BST] XMPPClient: to client: e7/27209141331372845435882587
+[2013-07-03 10:57:36 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","log","refs/heads/git-annex..1eb67d85f89c92345757805d83939d75e8ce54a0","--oneline","-n1"]
+[2013-07-03 10:57:36 BST] XMPPClient: sending: Pushing "e57" (ReceivePackDone ExitSuccess)
+[2013-07-03 10:57:36 BST] feed: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","update-index","-z","--index-info"]
+[2013-07-03 10:57:36 BST] XMPPClient: to client: e7/27209141331372845435882587
+[2013-07-03 10:57:36 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","diff-index","--raw","-z","-r","--no-renames","-l0","--cached","1eb67d85f89c92345757805d83939d75e8ce54a0"]
+[2013-07-03 10:57:36 BST] chat: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","hash-object","-t","blob","-w","--stdin"]
+[2013-07-03 10:57:36 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","log","1eb67d85f89c92345757805d83939d75e8ce54a0..refs/heads/git-annex","--oneline","-n1"]
+[2013-07-03 10:57:36 BST] call: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","update-ref","refs/heads/git-annex","1eb67d85f89c92345757805d83939d75e8ce54a0"]
+[2013-07-03 10:57:36 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","show-ref","git-annex"]
+[2013-07-03 10:57:36 BST] TransferScanner: starting scan of [Remote { name ="eythian" }]
+[2013-07-03 10:57:36 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","show-ref","--hash","refs/heads/git-annex"]
+[2013-07-03 10:57:36 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","log","refs/heads/git-annex..1eb67d85f89c92345757805d83939d75e8ce54a0","--oneline","-n1"]
+[2013-07-03 10:57:36 BST] feed: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","update-index","-z","--index-info"]
+[2013-07-03 10:57:36 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","diff-index","--raw","-z","-r","--no-renames","-l0","--cached","refs/heads/git-annex"]
+[2013-07-03 10:57:36 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","ls-files","--cached","-z","--"]
+[2013-07-03 10:57:37 BST] XMPPClient: received: ["Pushing \"e57\" (StartingPush (UUID \"9e67bebc-655c-47da-97a0-2bb02bbbc580\"))"]
+[2013-07-03 10:57:37 BST] XMPPReceivePack: started running push Pushing "e57" (StartingPush (UUID "9e67bebc-655c-47da-97a0-2bb02bbbc580"))
+[2013-07-03 10:57:37 BST] XMPPReceivePack: Syncing with eythian
+[2013-07-03 10:57:37 BST] chat: git ["receive-pack","/home/robin/Bureaublad/annex"]
+[2013-07-03 10:57:37 BST] XMPPClient: sending: Pushing "e57" (ReceivePackOutput 1 "<elided>")
+[2013-07-03 10:57:37 BST] XMPPClient: to client: e7/27209141331372845435882587
+[2013-07-03 10:57:37 BST] XMPPClient: received: ["Pushing \"e57\" (SendPackOutput 1 \"<elided>\")"]
+[2013-07-03 10:57:37 BST] XMPPClient: NetMessager stored Pushing "e57" (SendPackOutput 1 "<elided>") in ReceivePack inbox "e57"
+[2013-07-03 10:57:37 BST] XMPPReceivePack: finished running push Pushing "e57" (StartingPush (UUID "9e67bebc-655c-47da-97a0-2bb02bbbc580")) True
+[2013-07-03 10:57:37 BST] XMPPClient: sending: Pushing "e57" (ReceivePackDone ExitSuccess)
+[2013-07-03 10:57:37 BST] TransferScanner: queued Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Nothing : expensive scan found missing object
+[2013-07-03 10:57:37 BST] Transferrer: Transferring: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Nothing
+[2013-07-03 10:57:38 BST] XMPPClient: to client: e7/27209141331372845435882587
+[2013-07-03 10:57:38 BST] TransferScanner: finished scan of [Remote { name ="eythian" }]
+[2013-07-03 10:57:38 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Nothing
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 131008
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 262016
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 393024
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 524032
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 655040
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 786048
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 917056
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 1048064
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 1179072
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 1310080
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 1441088
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 1572096
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 1703104
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 1834112
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 1965120
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 2096128
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 2227136
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 2358144
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 2489152
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 2620160
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 2751168
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 2882176
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 3013184
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 3144192
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 3275200
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 3406208
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 3537216
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 3668224
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 3799232
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 3930240
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 4192256
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 4323264
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 4454272
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 4585280
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 4716288
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 4847296
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 5109312
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 5240320
+[2013-07-03 10:58:01 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 5371328
+[2013-07-03 10:58:02 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 5502336
+[2013-07-03 10:58:02 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 5633344
+[2013-07-03 10:58:02 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 5764352
+[2013-07-03 10:58:02 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 5895360
+[2013-07-03 10:58:02 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 6157376
+[2013-07-03 10:58:02 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 6288384
+[2013-07-03 10:58:02 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 6419392
+[2013-07-03 10:58:02 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 6550400
+[2013-07-03 10:58:02 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 6681408
+[2013-07-03 10:58:02 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 6943424
+[2013-07-03 10:58:02 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 7074432
+[2013-07-03 10:58:02 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 7205440
+[2013-07-03 10:58:02 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 7336448
+[2013-07-03 10:58:02 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 7598464
+[2013-07-03 10:58:02 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 7729472
+[2013-07-03 10:58:02 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 7860480
+[2013-07-03 10:58:02 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 7991488
+[2013-07-03 10:58:02 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 8122496
+[2013-07-03 10:58:02 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 8253504
+[2013-07-03 10:58:02 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 8384512
+[2013-07-03 10:58:02 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 8515520
+[2013-07-03 10:58:02 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 8646528
+[2013-07-03 10:58:02 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 8646528
+[2013-07-03 10:58:02 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 8777536
+[2013-07-03 10:58:02 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 8908544
+[2013-07-03 10:58:02 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 9039552
+[2013-07-03 10:58:02 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 9170560
+[2013-07-03 10:58:02 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 9301568
+[2013-07-03 10:58:02 BST] XMPPClient: received: ["Unknown message"]
+[2013-07-03 10:58:02 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 9432576
+[2013-07-03 10:58:02 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 9563584
+[2013-07-03 10:58:02 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 9694592
+[2013-07-03 10:58:02 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 9694592
+[2013-07-03 10:58:02 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 9825600
+[2013-07-03 10:58:02 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 9956608
+[2013-07-03 10:58:02 BST] TransferWatcher: transfer starting: Download UUID "971c808b-ce67-4edb-b317-21c0da6b5462" git-annex_4.20130627_amd64.deb Just 10087616
+[2013-07-03 10:58:02 BST] Watcher: add symlink git-annex_4.20130627_amd64.deb
+[2013-07-03 10:58:02 BST] Transferrer: Downloaded git-annex..amd64.deb
+[2013-07-03 10:58:02 BST] TransferWatcher: transfer finishing: Transfer {transferDirection = Download, transferUUID = UUID "971c808b-ce67-4edb-b317-21c0da6b5462", transferKey = Key {keyName = "8514472fd7c4ea28b385b0335db408ee28f58911b5ad0ba9d2e2cbfd1b99c86d.deb", keyBackendName = "SHA256E", keySize = Just 10140744, keyMtime = Nothing}}
+[2013-07-03 10:58:02 BST] chat: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","hash-object","-t","blob","-w","--stdin"]
+[2013-07-03 10:58:02 BST] chat: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","hash-object","-w","--stdin-paths"]
+[2013-07-03 10:58:02 BST] feed: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","update-index","-z","--index-info"]
+[2013-07-03 10:58:02 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","show-ref","--hash","refs/heads/git-annex"]
+[2013-07-03 10:58:02 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","write-tree"]
+[2013-07-03 10:58:02 BST] chat: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","commit-tree","9b6f9b59c19650e25f11e2d50acb3bf25b631150","-p","refs/heads/git-annex"]
+[2013-07-03 10:58:02 BST] call: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","update-ref","refs/heads/git-annex","822dbb101976fed8b775d04bba6da876c591a9f0"]
+[2013-07-03 10:58:02 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","symbolic-ref","HEAD"]
+[2013-07-03 10:58:02 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","show-ref","refs/heads/master"]
+[2013-07-03 10:58:02 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","show-ref","git-annex"]
+[2013-07-03 10:58:02 BST] Committer: committing 1 changes
+[2013-07-03 10:58:02 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","show-ref","--hash","refs/heads/git-annex"]
+[2013-07-03 10:58:02 BST] Committer: Committing changes to git
+[2013-07-03 10:58:02 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","log","refs/heads/git-annex..822dbb101976fed8b775d04bba6da876c591a9f0","--oneline","-n1"]
+[2013-07-03 10:58:02 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","log","refs/heads/git-annex..1eb67d85f89c92345757805d83939d75e8ce54a0","--oneline","-n1"]
+[2013-07-03 10:58:02 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","show-ref","--head","refs/heads/git-annex","HEAD"]
+[2013-07-03 10:58:02 BST] feed: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","update-index","-z","--index-info"]
+[2013-07-03 10:58:02 BST] XMPPClient: sending: Pushing "e30" (CanPush (UUID "2c0b788e-7b2d-474b-8963-d889b9556229") [e1b6f2944e7d082299cb1696c55d9064a11c4577,822dbb101976fed8b775d04bba6da876c591a9f0])
+[2013-07-03 10:58:02 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","commit","--allow-empty-message","--no-edit","-m","","--quiet","--no-verify"]
+[2013-07-03 10:58:02 BST] XMPPClient: exploded undirected message to clients e7/27209141331372845435882587
+[2013-07-03 10:58:03 BST] XMPPClient: received: ["Presence from 0/ Nothing"]
+[2013-07-03 10:58:03 BST] XMPPClient: received: ["Presence from e7/27209141331372845435882587 Just (Element {elementName = Name {nameLocalName = \"git-annex\", nameNamespace = Just \"git-annex\", namePrefix = Nothing}, elementAttributes = [], elementNodes = []})"]
+[2013-07-03 10:58:03 BST] XMPPClient: sending to new client: e7/27209141331372845435882587 "Pushing \"e57\" (CanPush (UUID \"2c0b788e-7b2d-474b-8963-d889b9556229\") [e1b6f2944e7d082299cb1696c55d9064a11c4577,822dbb101976fed8b775d04bba6da876c591a9f0])"
+[2013-07-03 10:58:03 BST] XMPPClient: received: ["Presence from 0/ Nothing"]
+[2013-07-03 10:58:03 BST] XMPPClient: received: ["Pushing \"e57\" (PushRequest (UUID \"9e67bebc-655c-47da-97a0-2bb02bbbc580\"))"]
+[2013-07-03 10:58:03 BST] XMPPSendPack: started running push Pushing "e57" (PushRequest (UUID "9e67bebc-655c-47da-97a0-2bb02bbbc580"))
+[2013-07-03 10:58:03 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","symbolic-ref","HEAD"]
+[2013-07-03 10:58:03 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","show-ref","refs/heads/master"]
+[2013-07-03 10:58:03 BST] call: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","branch","-f","synced/master"]
+[2013-07-03 10:58:03 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","symbolic-ref","HEAD"]
+[2013-07-03 10:58:03 BST] XMPPSendPack: Syncing with eythian
+[2013-07-03 10:58:03 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","show-ref","refs/heads/master"]
+[2013-07-03 10:58:03 BST] Merger: merging refs/heads/synced/master into refs/heads/master
+[2013-07-03 10:58:03 BST] XMPPClient: sending: Pushing "e57" (StartingPush (UUID "2c0b788e-7b2d-474b-8963-d889b9556229"))
+[2013-07-03 10:58:03 BST] call: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","push","eythian","git-annex:refs/synced/2c0b788e-7b2d-474b-8963-d889b9556229/ZXl0aGlhbkBqYWJiZXIua2FsbGlzdGkubmV0Lm56/git-annex","refs/heads/master:refs/synced/2c0b788e-7b2d-474b-8963-d889b9556229/ZXl0aGlhbkBqYWJiZXIua2FsbGlzdGkubmV0Lm56/master"]
+[2013-07-03 10:58:03 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","symbolic-ref","HEAD"]
+[2013-07-03 10:58:03 BST] XMPPClient: to client: e7/27209141331372845435882587
+[2013-07-03 10:58:03 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","show-ref","refs/heads/master"]
+[2013-07-03 10:58:03 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","show-ref","--hash","refs/heads/master"]
+[2013-07-03 10:58:03 BST] call: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex/.git/annex/merge/","merge","--no-edit","refs/heads/synced/master"]
+Already up-to-date.
+[2013-07-03 10:58:03 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","show-ref","--hash","refs/heads/master"]
+[2013-07-03 10:58:03 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","diff-tree","-z","--raw","--no-renames","-l0","-r","e1b6f2944e7d082299cb1696c55d9064a11c4577","e1b6f2944e7d082299cb1696c55d9064a11c4577"]
+[2013-07-03 10:58:03 BST] XMPPClient: received: ["Pushing \"e57\" (PushRequest (UUID \"9e67bebc-655c-47da-97a0-2bb02bbbc580\"))"]
+[2013-07-03 10:58:03 BST] XMPPClient: received: ["Pushing \"e57\" (ReceivePackOutput 1 \"<elided>\")"]
+[2013-07-03 10:58:03 BST] XMPPClient: NetMessager stored Pushing "e57" (ReceivePackOutput 1 "<elided>") in SendPack inbox "e57"
+[2013-07-03 10:58:03 BST] XMPPClient: received: ["Pushing \"e57\" (ReceivePackOutput 2 \"<elided>\")"]
+[2013-07-03 10:58:03 BST] XMPPClient: NetMessager stored Pushing "e57" (ReceivePackOutput 2 "<elided>") in SendPack inbox "e57"
+[2013-07-03 10:58:03 BST] XMPPClient: received: ["Pushing \"e57\" (ReceivePackOutput 3 \"<elided>\")"]
+[2013-07-03 10:58:03 BST] XMPPClient: NetMessager stored Pushing "e57" (ReceivePackOutput 3 "<elided>") in SendPack inbox "e57"
+[2013-07-03 10:58:03 BST] XMPPClient: received: ["Pushing \"e57\" (ReceivePackOutput 4 \"<elided>\")"]
+[2013-07-03 10:58:03 BST] XMPPClient: NetMessager stored Pushing "e57" (ReceivePackOutput 4 "<elided>") in SendPack inbox "e57"
+[2013-07-03 10:58:03 BST] XMPPClient: received: ["Pushing \"e57\" (ReceivePackOutput 5 \"<elided>\")"]
+[2013-07-03 10:58:03 BST] XMPPClient: NetMessager stored Pushing "e57" (ReceivePackOutput 5 "<elided>") in SendPack inbox "e57"
+[2013-07-03 10:58:03 BST] XMPPClient: sending: Pushing "e57" (SendPackOutput 1 "<elided>")
+[2013-07-03 10:58:03 BST] XMPPClient: to client: e7/27209141331372845435882587
+[2013-07-03 10:58:03 BST] XMPPClient: sending: Pushing "e57" (SendPackOutput 2 "<elided>")
+[2013-07-03 10:58:03 BST] XMPPClient: to client: e7/27209141331372845435882587
+[2013-07-03 10:58:04 BST] XMPPClient: received: ["Pushing \"e57\" (ReceivePackOutput 6 \"<elided>\")"]
+[2013-07-03 10:58:04 BST] XMPPClient: NetMessager stored Pushing "e57" (ReceivePackOutput 6 "<elided>") in SendPack inbox "e57"
+[2013-07-03 10:58:04 BST] XMPPClient: received: ["Pushing \"e57\" (ReceivePackOutput 7 \"<elided>\")"]
+[2013-07-03 10:58:04 BST] XMPPClient: NetMessager stored Pushing "e57" (ReceivePackOutput 7 "<elided>") in SendPack inbox "e57"
+[2013-07-03 10:58:04 BST] XMPPClient: received: ["Pushing \"e57\" (ReceivePackDone ExitSuccess)"]
+[2013-07-03 10:58To xmpp::eythian@jabber.kallisti.net.nz
+:0 2783051..822dbb1 4git-annex -> refs/synced/2c0b788e-7b2d-474b-8963-d889b9556229/ZXl0aGlhbkBqYWJiZXIua2FsbGlzdGkubmV0Lm56/git-annex
+BS 0b10576..e1b6f29 Tmaster -> refs/synced/2c0b788e-7b2d-474b-8963-d889b9556229/ZXl0aGlhbkBqYWJiZXIua2FsbGlzdGkubmV0Lm56/master]
+ XMPPClient: NetMessager stored Pushing "e57" (ReceivePackDone ExitSuccess) in SendPack inbox "e57"
+[2013-07-03 10:58:04 BST] XMPPSendPack: finished running push Pushing "e57" (PushRequest (UUID "9e67bebc-655c-47da-97a0-2bb02bbbc580")) True
+[2013-07-03 10:58:04 BST] XMPPSendPack: started running push Pushing "e57" (PushRequest (UUID "9e67bebc-655c-47da-97a0-2bb02bbbc580"))
+[2013-07-03 10:58:04 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","symbolic-ref","HEAD"]
+[2013-07-03 10:58:04 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","show-ref","refs/heads/master"]
+[2013-07-03 10:58:04 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","symbolic-ref","HEAD"]
+[2013-07-03 10:58:04 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","show-ref","refs/heads/master"]
+[2013-07-03 10:58:04 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","show-ref","--head","refs/heads/git-annex","HEAD"]
+[2013-07-03 10:58:04 BST] call: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","branch","-f","synced/master"]
+[2013-07-03 10:58:04 BST] XMPPClient: sending: Pushing "e30" (CanPush (UUID "2c0b788e-7b2d-474b-8963-d889b9556229") [e1b6f2944e7d082299cb1696c55d9064a11c4577,822dbb101976fed8b775d04bba6da876c591a9f0])
+[2013-07-03 10:58:04 BST] XMPPSendPack: Syncing with eythian
+[2013-07-03 10:58:04 BST] XMPPClient: exploded undirected message to clients e7/27209141331372845435882587
+[2013-07-03 10:58:04 BST] call: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","push","eythian","git-annex:refs/synced/2c0b788e-7b2d-474b-8963-d889b9556229/ZXl0aGlhbkBqYWJiZXIua2FsbGlzdGkubmV0Lm56/git-annex","refs/heads/master:refs/synced/2c0b788e-7b2d-474b-8963-d889b9556229/ZXl0aGlhbkBqYWJiZXIua2FsbGlzdGkubmV0Lm56/master"]
+[2013-07-03 10:58:04 BST] XMPPClient: sending: Pushing "e57" (StartingPush (UUID "2c0b788e-7b2d-474b-8963-d889b9556229"))
+[2013-07-03 10:58:04 BST] XMPPClient: to client: e7/27209141331372845435882587
+[2013-07-03 10:58:04 BST] XMPPClient: received: ["Presence from 0/ Nothing"]
+[2013-07-03 10:58:05 BST] XMPPClient: received: ["Presence from e7/27209141331372845435882587 Just (Element {elementName = Name {nameLocalName = \"git-annex\", nameNamespace = Just \"git-annex\", namePrefix = Nothing}, elementAttributes = [], elementNodes = []})"]
+[2013-07-03 10:58:05 BST] XMPPClient: sending to new client: e7/27209141331372845435882587 "Pushing \"e57\" (CanPush (UUID \"2c0b788e-7b2d-474b-8963-d889b9556229\") [e1b6f2944e7d082299cb1696c55d9064a11c4577,822dbb101976fed8b775d04bba6da876c591a9f0])"
+[2013-07-03 10:58:05 BST] XMPPClient: received: ["Presence from 0/ Nothing"]
+[2013-07-03 10:58:05 BST] XMPPClient: received: ["Pushing \"e57\" (ReceivePackOutput 1 \"<elided>\")"]
+[2013-07-03 10:58:05 BST] XMPPClient: NetMessager stored Pushing "e57" (ReceivePackOutput 1 "<elided>") in SendPack inbox "e57"
+[2013-07-03 10:58:05 BST] XMPPClient: sending: Pushing "e57" (SendPackOutput 1 "<elided>")
+[2013-07-03 10:58:05 BST] XMPPClient: to client: e7/27209141331372845435882587
+[2013-07-03 10:58:05 BST] XMPPClient: received: ["Pushing \"e57\" (ReceivePackDone ExitSuccess)"]
+[2013-07-03 10:58:05 Everything up-to-date
+BST] XMPPClient: NetMessager stored Pushing "e57" (ReceivePackDone ExitSuccess) in SendPack inbox "e57"
+[2013-07-03 10:58:05 BST] XMPPSendPack: finished running push Pushing "e57" (PushRequest (UUID "9e67bebc-655c-47da-97a0-2bb02bbbc580")) True
+[2013-07-03 10:58:27 BST] read: git ["--git-dir=/home/robin/Bureaublad/annex/.git","--work-tree=/home/robin/Bureaublad/annex","ls-tree","-z","--","refs/heads/git-annex","uuid.log","remote.log","trust.log","group.log","preferred-content.log"]
+
+
+# End of transcript or log.
+"""]]
diff --git a/doc/bugs/Truncated_file_transferred_via_S3/comment_1_5962358e6067448f633cc0eaf42f9ca7._comment b/doc/bugs/Truncated_file_transferred_via_S3/comment_1_5962358e6067448f633cc0eaf42f9ca7._comment
new file mode 100644
index 000000000..f3583d31b
--- /dev/null
+++ b/doc/bugs/Truncated_file_transferred_via_S3/comment_1_5962358e6067448f633cc0eaf42f9ca7._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.193"
+ subject="comment 1"
+ date="2013-07-05T16:49:33Z"
+ content="""
+Did you get a chance to run `git annex fsck` on the file? I'd hope it would detect this problem.
+
+It's certainly possible for data to get corrupted somehow in transit. git-annex does not check that it got the expected contents until a fsck happens.
+"""]]
diff --git a/doc/bugs/Truncated_file_transferred_via_S3/comment_2_75a2c272c36fc4fe8f9a79a3fd3ac4e5._comment b/doc/bugs/Truncated_file_transferred_via_S3/comment_2_75a2c272c36fc4fe8f9a79a3fd3ac4e5._comment
new file mode 100644
index 000000000..7eeb7ccaf
--- /dev/null
+++ b/doc/bugs/Truncated_file_transferred_via_S3/comment_2_75a2c272c36fc4fe8f9a79a3fd3ac4e5._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="https://launchpad.net/~eythian"
+ nickname="eythian"
+ subject="comment 2"
+ date="2013-07-11T12:44:24Z"
+ content="""
+I did it just then:
+
+ fsck git-annex_4.20130627_amd64.deb (checksum...) [2013-07-11 13:38:46 BST] read: sha256sum [\"git-annex_4.20130627_amd64.deb\"]
+
+ Bad file content; left in place for you to examine
+ failed
+
+however, more concerningly, this happened to almost all the files in the repo:
+
+ git-annex: fsck: 79 failed
+
+and they do seem to be a different size between the two computers.
+"""]]
diff --git a/doc/bugs/Truncated_file_transferred_via_S3/comment_3_3dae1914c8c90fdad0c21e1fc795f2ca._comment b/doc/bugs/Truncated_file_transferred_via_S3/comment_3_3dae1914c8c90fdad0c21e1fc795f2ca._comment
new file mode 100644
index 000000000..ecf3c4a1a
--- /dev/null
+++ b/doc/bugs/Truncated_file_transferred_via_S3/comment_3_3dae1914c8c90fdad0c21e1fc795f2ca._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.235"
+ subject="comment 3"
+ date="2013-07-11T16:16:03Z"
+ content="""
+Would all these files that wrong size have been transferred to this computer via S3 too? And can you spot the same weird endinaness problem in them too? Are the files only getting corrupted on one computer, or on both?
+"""]]
diff --git a/doc/bugs/Truncated_file_transferred_via_S3/comment_4_3c5fe109f2196cfc196c30da3b62bafd._comment b/doc/bugs/Truncated_file_transferred_via_S3/comment_4_3c5fe109f2196cfc196c30da3b62bafd._comment
new file mode 100644
index 000000000..b22380dc0
--- /dev/null
+++ b/doc/bugs/Truncated_file_transferred_via_S3/comment_4_3c5fe109f2196cfc196c30da3b62bafd._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://launchpad.net/~eythian"
+ nickname="eythian"
+ subject="comment 4"
+ date="2013-07-12T10:14:16Z"
+ content="""
+Yes, they would have gone via S3 too.
+
+However, it seems that running git annex fsck assumed the files on disk were correct, and they got resynched. So now both the computers have the incorrect version. I'll have a go pulling them out of backups and take a look.
+"""]]
diff --git a/doc/bugs/Truncated_file_transferred_via_S3/comment_5_f86f83c89300f255e730ddd23f876f61._comment b/doc/bugs/Truncated_file_transferred_via_S3/comment_5_f86f83c89300f255e730ddd23f876f61._comment
new file mode 100644
index 000000000..742d22e2d
--- /dev/null
+++ b/doc/bugs/Truncated_file_transferred_via_S3/comment_5_f86f83c89300f255e730ddd23f876f61._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://launchpad.net/~eythian"
+ nickname="eythian"
+ subject="comment 5"
+ date="2013-07-12T10:43:23Z"
+ content="""
+Good thing I set up obnam a while ago :)
+
+Anyway, yes, a very similar pattern of corruption can be seen here. It might be worth nothing that it starts in a different place in the file. The one I'm looking at now begins at byte 0x1C, whereas it was a little bit further into the file previously.
+
+I created a large file that'd make the issue really clear and synced it over, and of course, everything worked perfectly.
+
+Here is a pair of small files that shows the problem, from around the 0x4BC mark.
+
+<http://www.kallisti.net.nz/~robin/good-bad-annex-files.tar.gz>
+"""]]
diff --git a/doc/bugs/Unable_to_add_files_on_Android_due_to_weird_rename_error.mdwn b/doc/bugs/Unable_to_add_files_on_Android_due_to_weird_rename_error.mdwn
new file mode 100644
index 000000000..560597632
--- /dev/null
+++ b/doc/bugs/Unable_to_add_files_on_Android_due_to_weird_rename_error.mdwn
@@ -0,0 +1,37 @@
+### Please describe the problem.
+
+I am receiving a weird error when trying to add a file into a git annex repo on Android. I can't explain how it got into this state, and I can't figure out how to fix it.
+
+### What steps will reproduce the problem?
+
+See the output below - I'm happy to run any debugging commands that are required.
+
+### What version of git-annex are you using? On what operating system?
+
+ASUS Transformer Infinity Android Tablet, Android 4.2.1.
+
+[[!format sh """
+git-annex version: 4.20130601-g7483ca4
+build flags: Assistant Webapp Testsuite S3 WebDAV Inotify XMPP DNS
+local repository version: 3
+default repository version: 3
+supported repository versions: 3 4
+upgrade supported from repository versions: 0 1 2
+"""]]
+
+
+### Please provide any additional information below.
+
+[[!format sh """
+u0_a141@android:/sdcard/git-annex.home/Documents $ git annex add Music/MobileSheets/The\ New\ Real\ Book\ 1/New\ Real\ Book\ 1\ Eb_19.pdf
+add Music/MobileSheets/The New Real Book 1/New Real Book 1 Eb_19.pdf (checksum...) unknown option -- reflink=auto
+git-annex: /storage/emulated/legacy/git-annex.home/Documents/.git/annex/tmp/New Real Book 1 Eb15137.pdf: rename: does not exist (No such file or directory)
+failed
+git-annex: add: 1 failed
+1|u0_a141@android:/sdcard/git-annex.home/Documents $ ls -la .git/annex/tmp/
+drwxrwxr-x 2 root sdcard_r 4096 Jun 14 13:42 .
+drwxrwxr-x 6 root sdcard_r 4096 Jun 14 13:35 ..
+u0_a141@android:/sdcard/git-annex.home/Documents $
+"""]]
+
+> Should be [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/Unable_to_add_files_on_Android_due_to_weird_rename_error/comment_1_928289956111d1b22f9d55f15b54f72f._comment b/doc/bugs/Unable_to_add_files_on_Android_due_to_weird_rename_error/comment_1_928289956111d1b22f9d55f15b54f72f._comment
new file mode 100644
index 000000000..84a7498c4
--- /dev/null
+++ b/doc/bugs/Unable_to_add_files_on_Android_due_to_weird_rename_error/comment_1_928289956111d1b22f9d55f15b54f72f._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-06-14T16:20:57Z"
+ content="""
+I suspect you probably have another file already in the repository with the same content as the file you're trying to add. That, or something like it is why you're the lucky one who got to discover this bug in the build of the Android app! ;) The exact reason doesn't matter much -- It seems that it's trying to run `cp --reflink=auto`, which works on the build system, but not using the minimal busybox cp shipped with the Android app.
+
+I have put out a fix, and the Android daily build has been updated, so you can upgrade to that.
+"""]]
diff --git a/doc/bugs/Unable_to_add_files_on_Android_due_to_weird_rename_error/comment_2_6a0cb836b93ba4cb1e07b11d5d2a7094._comment b/doc/bugs/Unable_to_add_files_on_Android_due_to_weird_rename_error/comment_2_6a0cb836b93ba4cb1e07b11d5d2a7094._comment
new file mode 100644
index 000000000..52441b074
--- /dev/null
+++ b/doc/bugs/Unable_to_add_files_on_Android_due_to_weird_rename_error/comment_2_6a0cb836b93ba4cb1e07b11d5d2a7094._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawknOATcOkmzX4jKuET5Z2RsaFUNnLKnQsU"
+ nickname="Stephen"
+ subject="comment 2"
+ date="2013-06-14T23:01:35Z"
+ content="""
+Yep, it's fixed in the latest. Thanks!
+"""]]
diff --git a/doc/bugs/Unable_to_import_feed.mdwn b/doc/bugs/Unable_to_import_feed.mdwn
new file mode 100644
index 000000000..49dc21bfe
--- /dev/null
+++ b/doc/bugs/Unable_to_import_feed.mdwn
@@ -0,0 +1,27 @@
+Using `git-annex version: 4.20130802` on Debian unstable, when trying to add the feed at <http://www.ndr.de/fernsehen/sendungen/extra_3/videos/zum_mitnehmen/extradrei196_version-hq.xml>, I get:
+
+[[!format sh """
+importfeed http://www.ndr.de/fernsehen/sendungen/extra_3/videos/zum_mitnehmen/extradrei196_version-hq.xml
+--2013-08-16 09:14:13-- http://www.ndr.de/fernsehen/sendungen/extra_3/videos/zum_mitnehmen/extradrei196_version-hq.xml
+Auflösen des Hostnamen »www.ndr.de (www.ndr.de)«... 212.201.100.171, 212.201.100.187
+Verbindungsaufbau zu www.ndr.de (www.ndr.de)|212.201.100.171|:80... verbunden.
+HTTP-Anforderung gesendet, warte auf Antwort... 200 OK
+Länge: 61809 (60K) [application/xml]
+In »»/tmp/feed4404«« speichern.
+
+100%[============================================>] 61.809 --.-K/s in 0,03s
+
+2013-08-16 09:14:13 (2,20 MB/s) - »»/tmp/feed4404«« gespeichert [61809/61809]
+
+failed
+git-annex: importfeed: 1 failed
+"""]]
+
+(Oh, and using `format` with nono-ASCII seems to break down., at least in the preview.)
+
+> I'm going to close this since I've narrowed it down to a bug in the
+> upstream feed library. [[done]]. Of course, if we get a lot of reports of
+> the library not working, I may need to revisit using it, but for now this
+> seems an isolated problem. Also, I tried validating the feed, and it is
+> not 100% valid, and one of the validity problems is a missing enclosure
+> length. --[[Joey]]
diff --git a/doc/bugs/Unable_to_import_feed/comment_1_16230fbbb996e165b84787ed4d5f72ea._comment b/doc/bugs/Unable_to_import_feed/comment_1_16230fbbb996e165b84787ed4d5f72ea._comment
new file mode 100644
index 000000000..7c9c1e129
--- /dev/null
+++ b/doc/bugs/Unable_to_import_feed/comment_1_16230fbbb996e165b84787ed4d5f72ea._comment
@@ -0,0 +1,45 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 1"
+ date="2013-08-23T18:09:27Z"
+ content="""
+When I try this, without the German translation, I get:
+
+<pre>
+joey@gnu:~/tmp/newrepo>git annex importfeed 'http://www.ndr.de/fernsehen/sendungen/extra_3/videos/zum_mitnehmen/extradrei196_version-hq.xml'
+(checking known urls...)
+importfeed http://www.ndr.de/fernsehen/sendungen/extra_3/videos/zum_mitnehmen/extradrei196_version-hq.xml
+--2013-08-23 13:58:19-- http://www.ndr.de/fernsehen/sendungen/extra_3/videos/zum_mitnehmen/extradrei196_version-hq.xml
+Resolving www.ndr.de (www.ndr.de)... 23.73.180.154, 23.73.180.115
+Connecting to www.ndr.de (www.ndr.de)|23.73.180.154|:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 61865 (60K) [application/xml]
+Saving to: ‘/home/joey/tmp/feed31120’
+
+100%[======================================>] 61,865 151KB/s in 0.4s
+
+2013-08-23 13:58:25 (151 KB/s) - ‘/home/joey/tmp/feed31120’ saved [61865/61865]
+
+
+ warning: bad feed content
+</pre>
+
+It seems you left out the last line of the error.
+
+The feed library seems to fail to find any of the enclosures in this feed, although it is able to parse it as far as finding the individual items in the feed:
+
+<pre>
+Prelude Text.Feed.Query Text.Feed.Import> f <- parseFeedFromFile \"extradrei196_version-hq.xml\"
+Prelude Text.Feed.Query Text.Feed.Import> map getItemEnclosure $ feedItems f
+[Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing]
+</pre>
+
+The feed *appears* to contain enclosures, for example:
+
+<pre>
+<enclosure url=\"http://media.ndr.de/progressive/2013/0821/TV-20130821-2329-5942.hq.mp4\" type=\"video/mp4\"/>
+</pre>
+
+It may not be well-formed, or the feed library may have a bug. Assuming the latter, I have filed a bug report on the feed library: https://github.com/sof/feed/issues/3
+"""]]
diff --git a/doc/bugs/Unable_to_switch_back_to_direct_mode.mdwn b/doc/bugs/Unable_to_switch_back_to_direct_mode.mdwn
new file mode 100644
index 000000000..8144dfe4d
--- /dev/null
+++ b/doc/bugs/Unable_to_switch_back_to_direct_mode.mdwn
@@ -0,0 +1,55 @@
+### Please describe the problem.
+
+I seem to be unable to switch back and forth between git annex direct and git annex indirect mode in one of my repositories. I can in others just fine.
+
+### What steps will reproduce the problem?
+
+In the broken repository I can do:
+
+ cwebber@earlgrey:~/gfx-proj/mediagoblin_vid$ git annex direct
+ commit
+ add audio/part2.aup (checksum...) ok
+ ok
+ add images/campaign.png (checksum...) ok
+ ok
+ add images/transifex.png (checksum...) ok
+ ok
+ add script-lines.txt (checksum...) ok
+ ok
+ add vid_pitch.blend (checksum...) ok
+ ok
+ (Recording state in git...)
+ [master 9f13dc0] commit before switching to direct mode
+ 1 file changed, 145 insertions(+), 1 deletion(-)
+ rewrite audio/part2.aup (100%)
+ mode change 120000 => 100644
+ ok
+ direct gavroche-vid-shot.blend
+ git-annex: /home/cwebber/gfx-proj/mediagoblin_vid/.git/annex/objects/3M/mx/SHA256E-s2935980--3a1c838333a4a0ee1eaa837c3f08a910d3f29fc60baf41affd936fbefe11111f/SHA256E-s2935980--3a1c838333a4a0ee1eaa837c3f08a910d3f29fc60baf41affd936fbefe11111f: rename: permission denied (Permission denied)
+ failed
+ git-annex: direct: 1 failed
+
+looking at the files:
+
+ cwebber@earlgrey:~/gfx-proj/mediagoblin_vid$ ls -l gavroche-vid-shot.blend
+ lrwxrwxrwx 1 cwebber cwebber 190 Apr 28 18:27 gavroche-vid-shot.blend -> .git/annex/objects/3M/mx/SHA256E-s2935980--3a1c838333a4a0ee1eaa837c3f08a910d3f29fc60baf41affd936fbefe11111f/SHA256E-s2935980--3a1c838333a4a0ee1eaa837c3f08a910d3f29fc60baf41affd936fbefe11111f
+ cwebber@earlgrey:~/gfx-proj/mediagoblin_vid$ ls -l .git/annex/objects/3M/mx/SHA256E-s2935980--3a1c838333a4a0ee1eaa837c3f08a910d3f29fc60baf41affd936fbefe11111f/SHA256E-s2935980--3a1c838333a4a0ee1eaa837c3f08a910d3f29fc60baf41affd936fbefe11111f
+ -rw-r--r-- 1 cwebber cwebber 2935980 Apr 28 18:27 .git/annex/objects/3M/mx/SHA256E-s2935980--3a1c838333a4a0ee1eaa837c3f08a910d3f29fc60baf41affd936fbefe11111f/SHA256E-s2935980--3a1c838333a4a0ee1eaa837c3f08a910d3f29fc60baf41affd936fbefe11111f
+ cwebber@earlgrey:~/gfx-proj/mediagoblin_vid$
+
+... it looks like these permissions should be fine!
+
+Some notable things:
+
+* I believe Blender wrote directly to a file that was in "locked" somehow, despite it being in that state. It may have actually followed the symlink and overwritten that file, I'm not sure.
+* However, the file that git-annex is now reporting with "permission denied" is not the one it did previously... I did git checkout -- on all the files, switched them over, and it's a different set of broken things now!
+* It's actually easy enough to fix... in fact, I did fix it! I just did a fresh clone of the git repository and a git annex get and everything is fine now. However, it seemed like possibly a bug that might hit other people, hence my reporting it.
+
+### What version of git-annex are you using? On what operating system?
+
+git annex version 4.20130417 on debian wheezy
+
+### Please provide any additional information below.
+
+
+> [[done]]; see comments. --[[Joey]]
diff --git a/doc/bugs/Unable_to_switch_back_to_direct_mode/comment_1_4585b251f011a153c62f377c324cf963._comment b/doc/bugs/Unable_to_switch_back_to_direct_mode/comment_1_4585b251f011a153c62f377c324cf963._comment
new file mode 100644
index 000000000..6ba0111a7
--- /dev/null
+++ b/doc/bugs/Unable_to_switch_back_to_direct_mode/comment_1_4585b251f011a153c62f377c324cf963._comment
@@ -0,0 +1,24 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmRFKwny4rArBaz-36xTcsJYqKIgdDaw5Q"
+ nickname="Andrew"
+ subject="comment 1"
+ date="2013-04-30T02:31:31Z"
+ content="""
+I've had the same thing happen in reverse. I can not switch from direct to indirect mode. After receiving a similar error:
+
+ git-annex: /Users/akraut/Desktop/annexes/home/.git/annex/objects/ZV/kq/SHA256E-s207--4b4fa180ac4c16fe83eb2a5fed4c217c1d26195c876a4e0e700ae63605348d75.mp3/SHA256E-s207--4b4fa180ac4c16fe83eb2a5fed4c217c1d26195c876a4e0e700ae63605348d75.mp3.cache: removeLink: permission denied (Permission denied)
+ failed
+ git-annex: indirect: 1 failed
+
+ % > ls -la /Users/akraut/Desktop/annexes/home/.git/annex/objects/ZV/kq/SHA256E-s207--4b4fa180ac4c16fe83eb2a5fed4c217c1d26195c876a4e0e700ae63605348d75.mp3/SHA256E-s207--4b4fa180ac4c16fe83eb2a5fed4c217c1d26195c876a4e0e700ae63605348d75.mp3.cache
+ -rw-r--r-- 1 akraut staff 23 Mar 23 21:10 /Users/akraut/Desktop/annexes/home/.git/annex/objects/ZV/kq/SHA256E-s207--4b4fa180ac4c16fe83eb2a5fed4c217c1d26195c876a4e0e700ae63605348d75.mp3/SHA256E-s207--4b4fa180ac4c16fe83eb2a5fed4c217c1d26195c876a4e0e700ae63605348d75.mp3.cache
+
+After this error, annex things I'm in indirect mode:
+
+ % > git annex status
+ supported backends: SHA256E SHA1E SHA512E SHA224E SHA384E SHA256 SHA1 SHA512 SHA224 SHA384 WORM URL
+ supported remote types: git S3 bup directory rsync web webdav glacier hook
+ repository mode: indirect
+
+And git things that my repo has many uncommitted typechanges.
+"""]]
diff --git a/doc/bugs/Unable_to_switch_back_to_direct_mode/comment_2_5848ebbab38d1244347f7e7351b3a30d._comment b/doc/bugs/Unable_to_switch_back_to_direct_mode/comment_2_5848ebbab38d1244347f7e7351b3a30d._comment
new file mode 100644
index 000000000..2b13674a7
--- /dev/null
+++ b/doc/bugs/Unable_to_switch_back_to_direct_mode/comment_2_5848ebbab38d1244347f7e7351b3a30d._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-04-30T23:36:12Z"
+ content="""
+@andrew I've reproduced and fixed this problem. It does not seem to be related to cwebber's problem.
+
+Waiting on a test case from cwebber. His permissions seem ok, so I don't know what's causing that.
+"""]]
diff --git a/doc/bugs/Unable_to_switch_back_to_direct_mode/comment_3_1c5c7b0c7bc336e00f43e257b87a6208._comment b/doc/bugs/Unable_to_switch_back_to_direct_mode/comment_3_1c5c7b0c7bc336e00f43e257b87a6208._comment
new file mode 100644
index 000000000..b23697942
--- /dev/null
+++ b/doc/bugs/Unable_to_switch_back_to_direct_mode/comment_3_1c5c7b0c7bc336e00f43e257b87a6208._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmRFKwny4rArBaz-36xTcsJYqKIgdDaw5Q"
+ nickname="Andrew"
+ subject="comment 3"
+ date="2013-04-30T23:38:52Z"
+ content="""
+Ah, cool. What's the recommended way to recover from it?
+"""]]
diff --git a/doc/bugs/Unable_to_switch_back_to_direct_mode/comment_4_b0bfd68998bc3e11d8e089646b8292a6._comment b/doc/bugs/Unable_to_switch_back_to_direct_mode/comment_4_b0bfd68998bc3e11d8e089646b8292a6._comment
new file mode 100644
index 000000000..af406b1d2
--- /dev/null
+++ b/doc/bugs/Unable_to_switch_back_to_direct_mode/comment_4_b0bfd68998bc3e11d8e089646b8292a6._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 4"
+ date="2013-05-06T16:41:42Z"
+ content="""
+cwebber sent me a test case, and it turns out that while his problem was different, I fixed it in the same commit I fixed the problem described in the comment above. Both problems involved cases where the object storage directory was left with frozen permissions, and they needed to be unlocked before moving files in/out of it.
+
+Also, it seems that blender did not misbehave as thought. It only replaces the git-annex symlink with a new .blend file. Which is fine.
+
+Finally, there was an unrelated bug in `git annex direct` that chris's test case repo happened to have, which caused it to not convert 2 files to direct mode. I've fixed that bug as well.
+"""]]
diff --git a/doc/bugs/Unable_to_sync_a_second_machine_through_Box.mdwn b/doc/bugs/Unable_to_sync_a_second_machine_through_Box.mdwn
new file mode 100644
index 000000000..a4cac6ace
--- /dev/null
+++ b/doc/bugs/Unable_to_sync_a_second_machine_through_Box.mdwn
@@ -0,0 +1,46 @@
+What steps will reproduce the problem?
+
+Install 4.20130417 as packaged in Debian unstable.
+Using "git annex webapp", setup on first machine adding repository ~/annex. Add a Box.com repository in directory "annex", encrypted. Add a jabber account (apparently successful).
+Add test file to ~/annex. Login via website to box.com, notice that the "annex" directory is created and contains encrypted file.
+On second (remote machine), follow the same steps (add repository in ~/annex, Add a Box.com repository in directory "annex", encrypted, Add same jabber account).
+
+What is the expected output? What do you see instead?
+
+Expected the file to appear in the second machine's ~/annex. The webapp indicates: Synced with box.com
+Log file says:
+
+[2013-04-23 06:50:16 EDT] main: starting assistant version 4.20130417
+(scanning...) [2013-04-23 06:50:16 EDT] Watcher: Performing startup scan
+(started...)
+(encryption setup shared cipher) (testing WebDAV server...)
+(gpg) [2013-04-23 06:50:50 EDT] main: Syncing with box.com
+[2013-04-23 06:50:50 EDT] main: Share with friends, and keep your devices in sync across the cloud.
+[2013-04-23 06:51:03 EDT] main: Share with friends, and keep your devices in sync across the cloud.
+warning: Not updating non-default fetch respec
+
+ Please update the configuration manually if necessary.
+Initializing nautilus-gdu extension
+Shutting down nautilus-gdu extension
+git-annex: Daemon is already running.
+
+What version of git-annex are you using? On what operating system?
+
+4.20130417, debian testing with apt-pinning to unstable on both systems.
+
+Please provide any additional information below.
+
+When editing the Box.com repository, the option to select a directory no longer appears (and the configuration doesn't show the one selected at creation).
+There's no indication if the jabber communication is working successfully. It could be that signalling isn't working for some reason, but the user has no information to determine that.
+It would be helpful if there were some indication in the Dashboard as to the number of files/directories/objects that git annex believes exists in each location. It could be that it's not accessing the Box.com server successfully, but again, this is difficult to determine.
+
+It's great to see that git annex might make a box.com account useful for automatic upload and sync... looking forward to getting it to work on both sides! Thanks for making this!
+
+[[!tag /design/assistant moreinfo]]
+
+> The robustness of the XMPP support has massively improved since this bug
+> report was filed. Since no more information is forthcoming, I consider
+> this bug [[done]].
+>
+> (Incidentially, this bug got me to santize all information logged about
+> XMPP protocol, including the names/emails of buddies..) --[[Joey]]
diff --git a/doc/bugs/Unable_to_sync_a_second_machine_through_Box/comment_1_cb43a2bc976e3eb1cfc3ee9d4d34e78e._comment b/doc/bugs/Unable_to_sync_a_second_machine_through_Box/comment_1_cb43a2bc976e3eb1cfc3ee9d4d34e78e._comment
new file mode 100644
index 000000000..ae117f36f
--- /dev/null
+++ b/doc/bugs/Unable_to_sync_a_second_machine_through_Box/comment_1_cb43a2bc976e3eb1cfc3ee9d4d34e78e._comment
@@ -0,0 +1,22 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-04-23T17:54:14Z"
+ content="""
+Are files that you add in machine A showing up in machine B as broken symlinks? If so, jabber sync is working and the problem is with the Box.com remore. If not, the problem must be with the jabber sync.
+
+The log includes something like this when git is pulling over jabber:
+
+<pre>
+[2013-04-22 14:08:05 JEST] XMPPClient: Syncing with youraccount
+To xmpp::youraccount@gmail.com
+ 385f85c..3aae8b7 git-annex -> refs/synced/8ff0aa10-0a9d-4184-b16f-27b32ef87372/ZmFtaWx5QGtpdGVuZXQubmV0/git-annex
+</pre>
+
+You can turn on debugging (--debug at startup or Enable debug logging in Configuration -> Preferences) to get full XMPP protocol dumps in the log. If you do not see something like the above, please do so, and paste them, so I can debug why it's not working.
+
+> When editing the Box.com repository, the option to select a directory no longer appears
+
+This is normal; it doesn't make sense to change the directory the remote uses once the remote is in use.
+"""]]
diff --git a/doc/bugs/Unable_to_sync_a_second_machine_through_Box/comment_2_3375e9bfab3fed271413bd9bb5fa0121._comment b/doc/bugs/Unable_to_sync_a_second_machine_through_Box/comment_2_3375e9bfab3fed271413bd9bb5fa0121._comment
new file mode 100644
index 000000000..f3a39ef2f
--- /dev/null
+++ b/doc/bugs/Unable_to_sync_a_second_machine_through_Box/comment_2_3375e9bfab3fed271413bd9bb5fa0121._comment
@@ -0,0 +1,30 @@
+[[!comment format=mdwn
+ username="http://keverets.livejournal.com/"
+ ip="108.170.138.61"
+ subject="comment 2"
+ date="2013-04-23T19:04:15Z"
+ content="""
+I do see XMPP connecting after I enable logging (could the XMPP status be shown in the webapp directly?)
+
+It shows long, long lists of PresenceMessages:
+
+ [2013-04-23 14:55:56 EDT] XMPPClient: connected JID \"...\"
+ [2013-04-23 14:55:56 EDT] XMPPClient: received: [PresenceMessage (Presence {presenceType = PresenceAvailable, presenceTo = Just (JID ...
+
+Still no files gets transferred from Box.com to the second machine. I see:
+
+ [2013-04-23 14:53:41 EDT] main: Syncing with box.com
+
+but no:
+
+ XMPPClient: Syncing
+
+anywhere in the log.
+
+>> When editing the Box.com repository, the option to select a directory no longer appears
+> This is normal; it doesn't make sense to change the directory the remote uses once the remote is in use.
+
+It might not make sense to change it, but it would be useful to still see it (if disabled), especially when there are a few different Box.com directories that are shared with different repositories.
+
+Thanks again for any hints.
+"""]]
diff --git a/doc/bugs/Unable_to_sync_a_second_machine_through_Box/comment_3_c4420e1a3db321b4135b1626d3582adb._comment b/doc/bugs/Unable_to_sync_a_second_machine_through_Box/comment_3_c4420e1a3db321b4135b1626d3582adb._comment
new file mode 100644
index 000000000..1b66d12e9
--- /dev/null
+++ b/doc/bugs/Unable_to_sync_a_second_machine_through_Box/comment_3_c4420e1a3db321b4135b1626d3582adb._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="I am not a horse"
+ date="2013-04-23T20:05:25Z"
+ content="""
+A horse, when put in harness, is equipped with blinders, to prevent it from seeing scary things out of the corner of its eye, and panicing.
+
+I am not a horse. The more information I am presented with, the more likely I am to see and understand and fix a problem. ;)
+
+So, please paste the whole XMPP output, not 2 edited lines of it.
+"""]]
diff --git a/doc/bugs/Unable_to_sync_a_second_machine_through_Box/comment_4_f4b2c88bb5938dacdd04dfe9a68560de._comment b/doc/bugs/Unable_to_sync_a_second_machine_through_Box/comment_4_f4b2c88bb5938dacdd04dfe9a68560de._comment
new file mode 100644
index 000000000..32ceea2c0
--- /dev/null
+++ b/doc/bugs/Unable_to_sync_a_second_machine_through_Box/comment_4_f4b2c88bb5938dacdd04dfe9a68560de._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="http://keverets.livejournal.com/"
+ ip="108.170.138.61"
+ subject="Your users aren't horses, either"
+ date="2013-04-24T23:42:45Z"
+ content="""
+I appreciate the difficulty in responding to bug reports with incomplete logs.
+
+Please consider that the log file includes lists of email addresses (as XMPP contacts in the Presence messages) that are those of my contacts and not my own. In addition, these bug reports seem to be posted publicly in this wiki. As such, providing some other means of submitting logs would likely be a good idea (ideally from inside the webapp where they're being collected, so the user is less likely to miss some with a copy & paste through the browser; they should be sent to a more private destination such as an email address).
+
+I really do not want to be bothering you with bug reports if I could gather the information I need to solve the issue myself. That's why I suggested adding better notification in the webapp of the status of XMPP (there's just a brief \"Testing, this might take a minute\" message, and then never any indication afterwards as to the state), along with better information about the status of each repository as git annex sees them. If it's something that's tripping me up, and I'm willing to jump through the hoops (perhaps I am a horse) of hunting down and dealing with the bug reporting system, then there are likely others who will have the same issue but just give up.
+
+We're both left trying to sort out the problem partially blind, which is about as much fun for me as it is for you.
+
+I see a few ways to reduce the effort on both sides going forward. One (my preferred) is to give the users more information in the webapp as to what's going on with the sync so that the user can determine if it's the local git annex, the remote shared repository, the remote system, or the signalling in between. Another is to provide a more private means of submitting complete log data to help get quickly to the root of the problem without greatly compromising user's (and their contacts') privacy. And the last (my least preferred) is that you respond to bug reports in the manner above, resulting in the alienation of those who are trying to help, who are interested in what you're doing and trying to aid in improving the project so that it will be useful and pleasant-to-use for all. In doing so I'm fairly certain you'll get many fewer bug reports.
+
+That last one seems like less effort, but I really would prefer one of the two former solutions.
+"""]]
diff --git a/doc/bugs/Unable_to_sync_a_second_machine_through_Box/comment_5_6dcc95ffb3fc7bbbedd6be5df0111c85._comment b/doc/bugs/Unable_to_sync_a_second_machine_through_Box/comment_5_6dcc95ffb3fc7bbbedd6be5df0111c85._comment
new file mode 100644
index 000000000..5919a7206
--- /dev/null
+++ b/doc/bugs/Unable_to_sync_a_second_machine_through_Box/comment_5_6dcc95ffb3fc7bbbedd6be5df0111c85._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 5"
+ date="2013-04-24T23:46:11Z"
+ content="""
+<mailto:id@joeyh.name>
+"""]]
diff --git a/doc/bugs/Unable_to_use_remotes_with_space_in_the_path.mdwn b/doc/bugs/Unable_to_use_remotes_with_space_in_the_path.mdwn
new file mode 100644
index 000000000..6bb6c0782
--- /dev/null
+++ b/doc/bugs/Unable_to_use_remotes_with_space_in_the_path.mdwn
@@ -0,0 +1,35 @@
+### Please describe the problem.
+
+Git annex can't use remotes with the type "file://" if the path contains spaces
+
+### What steps will reproduce the problem?
+
+- Create one repository with a space in the path (and initialize annex in it)
+- Clone that repo to an other directory (and initialize annex also in that)
+- add a file to the first repository in the annex way
+- chdir to the second repository and try to get that file, it won't work (also after git pull or git sync pull)
+
+Check this typescripts for a more detailed description
+
+<http://uz.sns.it/~enrico/git-annex-bugreport.txt>
+
+<http://pastebin.com/f8wkDNrG> (thanks mhameed for that data)
+
+
+### What version of git-annex are you using? On what operating system?
+
+I'm using debian testing (jessie) on a i386 machine.
+
+`git-annex` version: 4.20130521 (according to apt data and `git annex version`)
+
+`git-annex` build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP
+
+`git` version: 1.7.10.4
+
+
+### Please provide any additional information below.
+
+I don't use git annex assistant nor the webapp
+
+> Tested and only file:// and not other urls have this problem.
+> guilhem provided a fix. [[done]] --[[Joey]]
diff --git a/doc/bugs/Unfortunate_interaction_with_Calibre.mdwn b/doc/bugs/Unfortunate_interaction_with_Calibre.mdwn
new file mode 100644
index 000000000..16921a06e
--- /dev/null
+++ b/doc/bugs/Unfortunate_interaction_with_Calibre.mdwn
@@ -0,0 +1,24 @@
+# Calibre
+
+Calibre is a somewhat popular eBook management package that's also free software. <http://calibre-ebook.com/>
+
+Install via
+ # apt-get install calibre
+
+There is a somewhat unfortunate interaction between Calibre and git-annex...
+
+* git-annex makes its files become read-only. By the way, that's not quite obvious from the documentation; I suggest making that more prominent.
+* Calibre modifies files (not quite sure of semantics, how, or why) when doing various operations, notably such as when copying a book from one's library to one's portable reading device.
+
+These don't play well together, sadly.
+
+I'd expect most of the issue to sit on the Calibre side, and have reported it as a bug.
+[Calibre bug #739045](https://bugs.launchpad.net/calibre/+bug/739045)
+Preliminary indication is that they're treating it as a functionality change they'll decline to fix. Which isn't entirely unreasonable - I anticipated as much, and I don't want to treat that as a bad/wrong decision.
+
+However, I think it's:
+* Unfortunate, as fitting Calibre together with git-annex seems like a neat idea.
+* Useful to make sure that this kind of "doesn't play well together" condition is documented, even if only as a bug report.
+
+> [[done]]; the assistant uses direct mode by default now to avoid
+> this kind of thing. --[[Joey]]
diff --git a/doc/bugs/Unfortunate_interaction_with_Calibre/comment_1_7cb5561f11dfc7726a537ddde2477489._comment b/doc/bugs/Unfortunate_interaction_with_Calibre/comment_1_7cb5561f11dfc7726a537ddde2477489._comment
new file mode 100644
index 000000000..35a2cdb3f
--- /dev/null
+++ b/doc/bugs/Unfortunate_interaction_with_Calibre/comment_1_7cb5561f11dfc7726a537ddde2477489._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 1"
+ date="2011-03-21T13:15:03Z"
+ content="""
+Maybe I will run into issues myself somewhere down the road, but generally speaking, I really really like the fact that files are immutable by default.
+"""]]
diff --git a/doc/bugs/Unfortunate_interaction_with_Calibre/comment_2_b8ae4bc589c787dacc08ab2ee5491d6e._comment b/doc/bugs/Unfortunate_interaction_with_Calibre/comment_2_b8ae4bc589c787dacc08ab2ee5491d6e._comment
new file mode 100644
index 000000000..719451976
--- /dev/null
+++ b/doc/bugs/Unfortunate_interaction_with_Calibre/comment_2_b8ae4bc589c787dacc08ab2ee5491d6e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 2"
+ date="2011-03-31T19:32:25Z"
+ content="""
+One option would be to use the new [[news/sharebox_a_FUSE_filesystem_for_git-annex]], which would hide the immutable file details from Calibre, and proxy any changes it made through to git-annex as a series of `git annex unlock; modify; git-annex lock`
+"""]]
diff --git a/doc/bugs/Unfortunate_interaction_with_Calibre/comment_3_977c5f6b82f9e18cdd81d57005bb8b89._comment b/doc/bugs/Unfortunate_interaction_with_Calibre/comment_3_977c5f6b82f9e18cdd81d57005bb8b89._comment
new file mode 100644
index 000000000..e23490ac4
--- /dev/null
+++ b/doc/bugs/Unfortunate_interaction_with_Calibre/comment_3_977c5f6b82f9e18cdd81d57005bb8b89._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.238"
+ subject="comment 3"
+ date="2013-01-17T20:59:03Z"
+ content="""
+I'd say that the best option now is to use [[direct_mode]] for repositories with files that you want to let programs modify directly.
+"""]]
diff --git a/doc/bugs/Unfortunate_interaction_with_Calibre/comment_4_ff7d2e9a39dfe12b975d04650ac57cc4._comment b/doc/bugs/Unfortunate_interaction_with_Calibre/comment_4_ff7d2e9a39dfe12b975d04650ac57cc4._comment
new file mode 100644
index 000000000..750ba8474
--- /dev/null
+++ b/doc/bugs/Unfortunate_interaction_with_Calibre/comment_4_ff7d2e9a39dfe12b975d04650ac57cc4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkvSZ1AFJdY_1FeutZr_KWeqtzjZta1PNE"
+ nickname="Thedward"
+ subject="comment 4"
+ date="2013-01-18T16:30:59Z"
+ content="""
+I couldn't get calibre to work with sharebox either, but I can confirm it works fine when I use git-annex in direct mode.
+"""]]
diff --git a/doc/bugs/Unfortunate_interaction_with_Calibre/comment_5_fc4d5301797589e92cc9a24697b2155d._comment b/doc/bugs/Unfortunate_interaction_with_Calibre/comment_5_fc4d5301797589e92cc9a24697b2155d._comment
new file mode 100644
index 000000000..a54d53c58
--- /dev/null
+++ b/doc/bugs/Unfortunate_interaction_with_Calibre/comment_5_fc4d5301797589e92cc9a24697b2155d._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="https://lot-of-stuff.info/"
+ nickname="__DL__"
+ subject="Another solution."
+ date="2013-08-13T16:39:17Z"
+ content="""
+calibre store all the metadata for safekeeping of the metadata
+(author, title...).
+
+If like me you do not like much direct mode (because of its not so
+cool interaction with plain git), you could use the largfiles config
+to let those files in plain git. You will then also need something for
+the database. See [[tips/Git_annex_and_Calibre]] for a full solution.
+
+"""]]
diff --git a/doc/bugs/Unknown_command___39__list__39__.mdwn b/doc/bugs/Unknown_command___39__list__39__.mdwn
new file mode 100644
index 000000000..f08fc6eef
--- /dev/null
+++ b/doc/bugs/Unknown_command___39__list__39__.mdwn
@@ -0,0 +1,15 @@
+### Please describe the problem.
+
+The man page claims there exists a query command 'list' but:
+
+ % git annex list somefile
+ git-annex: Unknown command 'list'
+
+### What version of git-annex are you using? On what operating system?
+
+man page online and git-annex version 4.20130909.
+
+> Your last line explains the problem. The online man page
+> documents the latest release, or in some cases
+> unrelased git version. You have a version 2 releases old installed.
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/Unknown_command___39__list__39__/comment_1_c625d03d1ed2019141ac9202f933466d._comment b/doc/bugs/Unknown_command___39__list__39__/comment_1_c625d03d1ed2019141ac9202f933466d._comment
new file mode 100644
index 000000000..7566dc1ef
--- /dev/null
+++ b/doc/bugs/Unknown_command___39__list__39__/comment_1_c625d03d1ed2019141ac9202f933466d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://cstork.org/"
+ nickname="Chris Stork"
+ subject="News page stopped listing latest releases?"
+ date="2013-09-30T16:08:18Z"
+ content="""
+Ah, cabal tells me that 4.20130927 is out now. I missed that because I thought that the [News](http://git-annex.branchable.com/news/) page is 'authoritative' :-) and it's still advertising 4.20130909. Sorry about that.
+"""]]
diff --git a/doc/bugs/Unknown_command___39__list__39__/comment_2_800e1b6417768bdadda311ebfb5df637._comment b/doc/bugs/Unknown_command___39__list__39__/comment_2_800e1b6417768bdadda311ebfb5df637._comment
new file mode 100644
index 000000000..f8592b571
--- /dev/null
+++ b/doc/bugs/Unknown_command___39__list__39__/comment_2_800e1b6417768bdadda311ebfb5df637._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.80"
+ subject="comment 2"
+ date="2013-09-30T16:23:31Z"
+ content="""
+I've had a bit of a mess with cabal. First my release scripts apparently broke and didn't upload the last 2 releases there. Then when I manually fixed that, hackage has been upgraded to a new version, which is broken and will not accept tarballs > 1 mb. So I had to re-upload git-annex hacked to fit in 1 mb (removing all documentation), and I did so from a current git snapshot. Meh.
+"""]]
diff --git a/doc/bugs/Unknown_command___39__list__39__/comment_3_35dfc75ce9efffff139f8929dc311e29._comment b/doc/bugs/Unknown_command___39__list__39__/comment_3_35dfc75ce9efffff139f8929dc311e29._comment
new file mode 100644
index 000000000..1899029ad
--- /dev/null
+++ b/doc/bugs/Unknown_command___39__list__39__/comment_3_35dfc75ce9efffff139f8929dc311e29._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://cstork.org/"
+ nickname="Chris Stork"
+ subject="comment 3"
+ date="2013-10-04T11:17:42Z"
+ content="""
+Ah, I could have sworn that I also tried to update via cabal but didn't see a new version and this explains why...
+
+Your release script might also have a problem with updating the [[News]] page...
+"""]]
diff --git a/doc/bugs/Unknown_remote_type_webdav.mdwn b/doc/bugs/Unknown_remote_type_webdav.mdwn
new file mode 100644
index 000000000..7c6f1ae36
--- /dev/null
+++ b/doc/bugs/Unknown_remote_type_webdav.mdwn
@@ -0,0 +1,8 @@
+When I attempt to setup a [box.com special remote](http://git-annex.branchable.com/tips/using_box.com_as_a_special_remote/) I get the following error:
+
+ git-annex: Unknown remote type webdav
+
+I'm using the Linux prebuilt tarball. Does it not include webdav support?
+
+> The amd64 standalone tarball was indeed built without it for the last
+> release. Fixed that. [[done]] --[[Joey]]
diff --git a/doc/bugs/Unnecessary_remote_transfers.mdwn b/doc/bugs/Unnecessary_remote_transfers.mdwn
new file mode 100644
index 000000000..9ae23e5a0
--- /dev/null
+++ b/doc/bugs/Unnecessary_remote_transfers.mdwn
@@ -0,0 +1,24 @@
+### Please describe the problem.
+This is related to [[http://git-annex.branchable.com/bugs/assistant_does_not_always_use_repo_cost_info_when_queueing_downloads/]]
+
+### What steps will reproduce the problem?
+1. Make a client repo on two machines on the local network.
+2. Pair them.
+3. Make a remote transfer repo.
+4. Set up Jabber on both local machines.
+5. Put a large file into the annex on one of the local machines.
+6. Watch as the source client repo copies the file directly to the local paired machine, but also copies it to the remote transfer repo.
+7. Wait for the local paired transfer to finish.
+8. Manually disable syncing to the remote transfer repo.
+9. Manually reenable it.
+10. Watch as the remote transfer is not resumed.
+
+### What version of git-annex are you using? On what operating system?
+Using the 1 Nov Linux tarball, Ubuntu Raring.
+
+### Please provide any additional information below.
+This is a problem because unless I manually disable the remote repo, it will continue uploading the large file until it finishes, which uses the limited upstream bandwidth on my Internet connection--and this could take hours depending on the size of the file.
+
+The remote transfer wasn't even necessary to begin with, because it already had a direct connection to the local paired repo. But even so, it should at least abort the remote transfer when the local transfer finishes.
+
+Thanks for your work on git-annex assistant.
diff --git a/doc/bugs/Unnecessary_remote_transfers/comment_10_b778fbb1386f0f51bf057ffacd590ebb._comment b/doc/bugs/Unnecessary_remote_transfers/comment_10_b778fbb1386f0f51bf057ffacd590ebb._comment
new file mode 100644
index 000000000..8c985243a
--- /dev/null
+++ b/doc/bugs/Unnecessary_remote_transfers/comment_10_b778fbb1386f0f51bf057ffacd590ebb._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmNu4V5fvpLlBhaCUfXXOB0MI5NXwh8SkU"
+ nickname="Adam"
+ subject="comment 10"
+ date="2013-11-03T02:19:04Z"
+ content="""
+Thanks, Joey. I didn't realize that there were two instances of the assistant running.
+
+Forgive my ignorance, but if I disable the assistant running in the backup repo, will the other assistant still backup files to it?
+
+Also, from a UI perspective, does the webapp currently not seem to support secondary internal drives, at least in a useful way?
+"""]]
diff --git a/doc/bugs/Unnecessary_remote_transfers/comment_11_55430eac842d0a192dc7f41d7730e4d5._comment b/doc/bugs/Unnecessary_remote_transfers/comment_11_55430eac842d0a192dc7f41d7730e4d5._comment
new file mode 100644
index 000000000..808c5bca6
--- /dev/null
+++ b/doc/bugs/Unnecessary_remote_transfers/comment_11_55430eac842d0a192dc7f41d7730e4d5._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 11"
+ date="2013-11-03T02:32:47Z"
+ content="""
+Yes, either of the assistants will still back up files to it, as long as they have it configured as a git remote. The same way that your transfer repository is (probably) not running the git-annex assistant.
+
+It does sound like using the removable drive UI would have saved you some trouble. I'm not sure why the webapp would not list a llvm device as a removable drive -- from inspecting the code, it seems like it would not be filtered out, as long as /proc/mounts shows the decive as /dev/something (I don't have a llvm device handy to check what it looks like).
+"""]]
diff --git a/doc/bugs/Unnecessary_remote_transfers/comment_1_00c18e07678dc513a02d974fe059df73._comment b/doc/bugs/Unnecessary_remote_transfers/comment_1_00c18e07678dc513a02d974fe059df73._comment
new file mode 100644
index 000000000..7baa58489
--- /dev/null
+++ b/doc/bugs/Unnecessary_remote_transfers/comment_1_00c18e07678dc513a02d974fe059df73._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 1"
+ date="2013-11-02T19:54:44Z"
+ content="""
+In what order does the webapp list your repositories?
+
+When a new file appears, it will always go through the list of repositories in order, and try to transfer the file to each in turn, unless the configuration indicates it shouldn't. So, if the remote transfer repo is listed before the local repo, it will first upload the file to the transfer repo, and then upload it to the local repo. (And then later on, remove it from the transfer repo, since the file has reached all clients, probably.) OTOH, if the local repo comes first, it will upload the file to it over the LAN, and then when it comes to the transfer repo, if the file has successfully been sent to all clients, the transfer repo will no longer want it, and so no expensive upload is done over the internet.
+
+You can re-order the repository list in the webapp by dragging them up and down. It should default to having your locally paired repos first, unless you've changed it. If you think it came up with the wrong order, paste in your .git/config before you re-order the repositories..
+"""]]
diff --git a/doc/bugs/Unnecessary_remote_transfers/comment_2_2e9992dbfceabd6df535a2770626de16._comment b/doc/bugs/Unnecessary_remote_transfers/comment_2_2e9992dbfceabd6df535a2770626de16._comment
new file mode 100644
index 000000000..cc0cb067e
--- /dev/null
+++ b/doc/bugs/Unnecessary_remote_transfers/comment_2_2e9992dbfceabd6df535a2770626de16._comment
@@ -0,0 +1,35 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmNu4V5fvpLlBhaCUfXXOB0MI5NXwh8SkU"
+ nickname="Adam"
+ subject="comment 2"
+ date="2013-11-02T22:48:18Z"
+ content="""
+The webapp has the remote repo at the bottom of the list. But here's .git/config. It has a high repo cost for the local paired repo, and no cost listed for the remote one:
+
+[[!format sh \"\"\"
+[core]
+ repositoryformatversion = 0
+ filemode = true
+ bare = false
+ logallrefupdates = true
+[annex]
+ uuid = 946f9095-588b-4421-b66a-4a1e5632ff6b
+ version = 3
+ direct = true
+ diskreserve = 1 megabyte
+ numcopies = 1
+ debug = false
+[gc]
+ auto = 0
+[remote \"Onyx\"]
+ url = ssh://me@git-annex-Onyx.local-me_annex/~/annex/
+ annex-uuid = 80709bc2-3cbe-434b-b7b9-306278b9a4e9
+ annex-cost = 125.0
+ fetch = +refs/heads/*:refs/remotes/Onyx/*
+[remote \"Remote\"]
+ annex-rsyncurl = username@git-annex-example.net-username_annex:annex/
+ annex-uuid = 33930bae-63d2-4a52-b330-58872aaeb1bf
+ fetch =
+ annex-sync = true
+\"\"\"]]
+"""]]
diff --git a/doc/bugs/Unnecessary_remote_transfers/comment_3_a98f3091a6a658919f0562cf396439c2._comment b/doc/bugs/Unnecessary_remote_transfers/comment_3_a98f3091a6a658919f0562cf396439c2._comment
new file mode 100644
index 000000000..b6900f339
--- /dev/null
+++ b/doc/bugs/Unnecessary_remote_transfers/comment_3_a98f3091a6a658919f0562cf396439c2._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmNu4V5fvpLlBhaCUfXXOB0MI5NXwh8SkU"
+ nickname="Adam"
+ subject="comment 3"
+ date="2013-11-02T22:59:18Z"
+ content="""
+Also, I just realized that it's uploading two large files to my remote transfer repo, even though I already have both files in my local paired repo on both systems; i.e. there's no need to send it to the transfer repo at all. And it was yesterday when the two files were transferred. So I have no idea why today it thinks it needs to upload them to the transfer repo. :/
+"""]]
diff --git a/doc/bugs/Unnecessary_remote_transfers/comment_4_417c1e8e27ee1a1f9ebf9160560605c5._comment b/doc/bugs/Unnecessary_remote_transfers/comment_4_417c1e8e27ee1a1f9ebf9160560605c5._comment
new file mode 100644
index 000000000..b0d4c1146
--- /dev/null
+++ b/doc/bugs/Unnecessary_remote_transfers/comment_4_417c1e8e27ee1a1f9ebf9160560605c5._comment
@@ -0,0 +1,96 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmNu4V5fvpLlBhaCUfXXOB0MI5NXwh8SkU"
+ nickname="Adam"
+ subject="Super confused"
+ date="2013-11-02T23:30:41Z"
+ content="""
+I think now I'm double- or triple-confused. Here is me@desktop:~/annex/.git/config:
+
+[[!format sh \"\"\"
+[core]
+ repositoryformatversion = 0
+ filemode = true
+ bare = false
+ logallrefupdates = true
+[annex]
+ uuid = 80709bc2-3cbe-434b-b7b9-306278b9a4e9
+ version = 3
+ direct = true
+ fscknudge = true
+[gc]
+ auto = 0
+[remote \"laptop\"]
+ url = ssh://me@git-annex-laptop-me_annex/~/annex/
+ annex-uuid = 946f9095-588b-4421-b66a-4a1e5632ff6b
+ annex-cost = 175.0
+ fetch = +refs/heads/*:refs/remotes/laptop/*
+[remote \"Remote\"]
+ annex-rsyncurl = username@example.net:annex/
+ annex-uuid = 33930bae-63d2-4a52-b330-58872aaeb1bf
+ fetch =
+ annex-sync = false
+[remote \"backupOndesktop\"]
+ url = /mnt/debian/home/me/annex-backup
+ annex-uuid = 86535965-6ca7-4bf3-89af-bca3a07f96f9
+ fetch = +refs/heads/*:refs/remotes/backupOndesktop/*
+\"\"\"]]
+
+What I have set up (or intended to set up) is:
+
+* Client: me@laptop:~/annex
+* Client: me@desktop:~/annex
+* Transfer: username@example.net:~/annex
+* Full Backup: me@desktop:/mnt/debian/home/me/annex-backup
+
+What I expected was that:
+
+1. The two Client repos would sync directly over the LAN whenever possible.
+2. The transfer repo would be used only to sync the laptop and desktop, and then only if my laptop were not on the LAN with my desktop.
+3. The Full Backup repo would be synced directly with the me@desktop Client repo, within the same system, from one hard disk to the other.
+
+But what I'm seeing is...not quite that.
+
+1. It's very confusing (to me, at least) that on my desktop system I can look at my annex setup from the \"perspective\" of both local repos. When I \"switch\" to the other repo, the setup looks different: even the same repos can have different names and descriptions, and can be enabled and disabled independently depending on the \"perspective\"...but their Type is still the same.
+
+2. Looking from the \"perspective\" of the Full Backup repo, I'm seeing files being transferred to the Transfer repo, even though those files are already present in both Client repos, and even though the webapp says that the Full Backup repo has been synced. When I disable and reenable the Transfer repo, it starts those transfers over again, even though they aren't necessary. For example, here is the log from disabling and reenabling the Transfer repo from the \"perspective\" of the Full Backup repo:
+
+[[!format sh \"\"\"
+[2013-11-02 18:24:35 CDT] main: Syncing with example.net_annex
+(gpg)
+gpg: Terminated caught ... exiting
+[2013-11-02 18:24:49 CDT] call: git [\"--git-dir=/mnt/debian/home/me/annex-backup/.git\",\"--work-tree=/mnt/debian/home/me/annex-backup\",\"config\",\"remote.example.net_annex.annex-sync\",\"true\"]
+[2013-11-02 18:24:49 CDT] read: git [\"config\",\"--null\",\"--list\"]
+[2013-11-02 18:24:49 CDT] read: git [\"config\",\"--null\",\"--list\"]
+[2013-11-02 18:24:49 CDT] read: git [\"config\",\"--null\",\"--list\"]
+[2013-11-02 18:24:49 CDT] main: Syncing with example.net_annex
+[2013-11-02 18:24:49 CDT] read: git [\"--git-dir=/mnt/debian/home/me/annex-backup/.git\",\"--work-tree=/mnt/debian/home/me/annex-backup\",\"symbolic-ref\",\"HEAD\"]
+[2013-11-02 18:24:49 CDT] read: git [\"--git-dir=/mnt/debian/home/me/annex-backup/.git\",\"--work-tree=/mnt/debian/home/me/annex-backup\",\"show-ref\",\"refs/heads/master\"]
+[2013-11-02 18:24:49 CDT] read: git [\"--git-dir=/mnt/debian/home/me/annex-backup/.git\",\"--work-tree=/mnt/debian/home/me/annex-backup\",\"show-ref\",\"git-annex\"]
+[2013-11-02 18:24:49 CDT] read: git [\"--git-dir=/mnt/debian/home/me/annex-backup/.git\",\"--work-tree=/mnt/debian/home/me/annex-backup\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+[2013-11-02 18:24:49 CDT] read: git [\"--git-dir=/mnt/debian/home/me/annex-backup/.git\",\"--work-tree=/mnt/debian/home/me/annex-backup\",\"log\",\"refs/heads/git-annex..2c42d607c099b6ec4a20603b809f44d161e42489\",\"--oneline\",\"-n1\"]
+[2013-11-02 18:24:49 CDT] read: git [\"--git-dir=/mnt/debian/home/me/annex-backup/.git\",\"--work-tree=/mnt/debian/home/me/annex-backup\",\"symbolic-ref\",\"HEAD\"]
+[2013-11-02 18:24:49 CDT] read: git [\"--git-dir=/mnt/debian/home/me/annex-backup/.git\",\"--work-tree=/mnt/debian/home/me/annex-backup\",\"show-ref\",\"refs/heads/master\"]
+[2013-11-02 18:24:49 CDT] TransferScanner: starting scan of [Remote { name =\"example.net_annex\" }]
+[2013-11-02 18:24:49 CDT] read: git [\"--git-dir=/mnt/debian/home/me/annex-backup/.git\",\"--work-tree=/mnt/debian/home/me/annex-backup\",\"ls-files\",\"--cached\",\"-z\",\"--\"]
+[2013-11-02 18:24:49 CDT] TransferScanner: queued Upload UUID \"33930bae-63d2-4a52-b330-58872aaeb1bf\" video.flv Nothing : expensive scan found missing object
+[2013-11-02 18:24:49 CDT] Transferrer: Transferring: Upload UUID \"33930bae-63d2-4a52-b330-58872aaeb1bf\" video.flv Nothing
+[2013-11-02 18:24:49 CDT] TransferScanner: queued Upload UUID \"33930bae-63d2-4a52-b330-58872aaeb1bf\" image.jpg Nothing : expensive scan found missing object
+[2013-11-02 18:24:49 CDT] call: /home/me/.bin/git-annex.linux/git-annex [\"transferkeys\",\"--readfd\",\"35\",\"--writefd\",\"34\"]
+[2013-11-02 18:24:49 CDT] TransferScanner: queued Upload UUID \"33930bae-63d2-4a52-b330-58872aaeb1bf\" linux-image-3.8.0-29-generic_3.8.0-29.42_i386.deb Nothing : expensive scan found missing object
+[2013-11-02 18:24:49 CDT] TransferScanner: finished scan of [Remote { name =\"example.net_annex\" }]
+[2013-11-02 18:24:49 CDT] read: git [\"--git-dir=/mnt/debian/home/me/annex-backup/.git\",\"--work-tree=/mnt/debian/home/me/annex-backup\",\"show-ref\",\"git-annex\"]
+[2013-11-02 18:24:49 CDT] read: git [\"--git-dir=/mnt/debian/home/me/annex-backup/.git\",\"--work-tree=/mnt/debian/home/me/annex-backup\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+[2013-11-02 18:24:49 CDT] read: git [\"--git-dir=/mnt/debian/home/me/annex-backup/.git\",\"--work-tree=/mnt/debian/home/me/annex-backup\",\"log\",\"refs/heads/git-annex..2c42d607c099b6ec4a20603b809f44d161e42489\",\"--oneline\",\"-n1\"]
+[2013-11-02 18:24:49 CDT] chat: git [\"--git-dir=/mnt/debian/home/me/annex-backup/.git\",\"--work-tree=/mnt/debian/home/me/annex-backup\",\"cat-file\",\"--batch\"]
+[2013-11-02 18:24:49 CDT] read: git [\"config\",\"--null\",\"--list\"]
+[2013-11-02 18:24:49 CDT] TransferWatcher: transfer starting: Upload UUID \"33930bae-63d2-4a52-b330-58872aaeb1bf\" video.flv Nothing
+(gpg) [2013-11-02 18:24:49 CDT] chat: gpg [\"--batch\",\"--no-tty\",\"--use-agent\",\"--quiet\",\"--trust-model\",\"always\",\"--batch\",\"--passphrase-fd\",\"20\",\"--symmetric\",\"--force-mdc\",\"--no-textmode\"]
+[2013-11-02 18:24:50 CDT] call: git [\"--git-dir=/mnt/debian/home/me/annex-backup/.git\",\"--work-tree=/mnt/debian/home/me/annex-backup\",\"config\",\"remote.example.net_annex.annex-sync\",\"false\"]
+[2013-11-02 18:24:50 CDT] read: git [\"config\",\"--null\",\"--list\"]
+[2013-11-02 18:24:50 CDT] read: git [\"config\",\"--null\",\"--list\"]
+[2013-11-02 18:24:50 CDT] read: git [\"config\",\"--null\",\"--list\"]
+
+gpg: Terminated caught ... exiting\"\"\"]]
+
+I have no idea why it's doing that, because all three of those files are already in both Client repos and the Full Backup repo.
+"""]]
diff --git a/doc/bugs/Unnecessary_remote_transfers/comment_5_eb5a2717a1f0c7bb761d2a7866b23def._comment b/doc/bugs/Unnecessary_remote_transfers/comment_5_eb5a2717a1f0c7bb761d2a7866b23def._comment
new file mode 100644
index 000000000..0e2ec4ec8
--- /dev/null
+++ b/doc/bugs/Unnecessary_remote_transfers/comment_5_eb5a2717a1f0c7bb761d2a7866b23def._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmNu4V5fvpLlBhaCUfXXOB0MI5NXwh8SkU"
+ nickname="Adam"
+ subject="Deleting repos from different perspectives"
+ date="2013-11-02T23:33:48Z"
+ content="""
+One other thing, sorry, but I think this is important: From the perspective of the Full Backup repo, I set the Transfer repo to be deleted, thinking that would prevent the desktop's Client and Full Backup repos from syncing through the Transfer repo. But then when I switch to the perspective of the desktop's Client repo, it is \"cleaning out\" the Transfer repo--but I wanted the Transfer repo to be used for syncing the two Client repos! So I set it back to Transfer instead of Unwanted...but then when I switch back to the Full Backup perspective, the Transfer repo is no longer Unwanted.
+"""]]
diff --git a/doc/bugs/Unnecessary_remote_transfers/comment_6_89f756db1f3f2e60a3bd1f35f55fee43._comment b/doc/bugs/Unnecessary_remote_transfers/comment_6_89f756db1f3f2e60a3bd1f35f55fee43._comment
new file mode 100644
index 000000000..509cc3f3f
--- /dev/null
+++ b/doc/bugs/Unnecessary_remote_transfers/comment_6_89f756db1f3f2e60a3bd1f35f55fee43._comment
@@ -0,0 +1,40 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmNu4V5fvpLlBhaCUfXXOB0MI5NXwh8SkU"
+ nickname="Adam"
+ subject="config from backup repo"
+ date="2013-11-03T00:20:11Z"
+ content="""
+Sorry for posting over and over again, just trying to provide info when I discover it.
+
+Here's **/mnt/debian/home/me/annex-backup/.git/config**
+
+[[!format sh \"\"\"
+[core]
+ repositoryformatversion = 0
+ filemode = true
+ bare = false
+ logallrefupdates = true
+[annex]
+ uuid = 86535965-6ca7-4bf3-89af-bca3a07f96f9
+ version = 3
+ direct = true
+ fscknudge = true
+ diskreserve = 100 megabyte
+ numcopies = 1
+ debug = false
+[gc]
+ auto = 0
+[remote \"desktop\"]
+ url = /home/me/annex
+ fetch = +refs/heads/*:refs/remotes/desktop/*
+ annex-uuid = 80709bc2-3cbe-434b-b7b9-306278b9a4e9
+[remote \"Remote\"]
+ annex-rsyncurl = username@example.net:annex/
+ annex-uuid = 33930bae-63d2-4a52-b330-58872aaeb1bf
+ annex-sync = false
+ fetch =\"\"\"]]
+
+1. Should I remove the \"Remote\" Transfer repo from this config file to prevent it from using the Transfer repo? I only want this repo to sync directly with the other internal hard disk.
+
+2. Is it correct for git-annex to add this Transfer repo to this config file in the first place?
+"""]]
diff --git a/doc/bugs/Unnecessary_remote_transfers/comment_7_5aaf8766a7ba05c4f92715e5d5175a8f._comment b/doc/bugs/Unnecessary_remote_transfers/comment_7_5aaf8766a7ba05c4f92715e5d5175a8f._comment
new file mode 100644
index 000000000..f117f15c1
--- /dev/null
+++ b/doc/bugs/Unnecessary_remote_transfers/comment_7_5aaf8766a7ba05c4f92715e5d5175a8f._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 7"
+ date="2013-11-03T00:45:09Z"
+ content="""
+* The costs you show look fine.
+* Yes, deleting a repository in the webapp actually deletes it. It doesn't just remove the remote from .git/config. Most people using the webapp don't want to draw such a fine distinction, I think.
+* It's not a very usual configuration to have 2 repositories on the same machine with the git-annex assistant running in both. You might just want to configure the assistant to not run in the backup repository.
+
+Some of the things you've said suggest that the backup repository might not be immediately noticing when changes are pushed to it. Since its location is shown as /mnt/debian/home/me, I have to wonder if that's some NFS mount or other network filesystem causing problems.
+
+"""]]
diff --git a/doc/bugs/Unnecessary_remote_transfers/comment_8_e856b350632cc865d16d1995a6cdf065._comment b/doc/bugs/Unnecessary_remote_transfers/comment_8_e856b350632cc865d16d1995a6cdf065._comment
new file mode 100644
index 000000000..1177205e3
--- /dev/null
+++ b/doc/bugs/Unnecessary_remote_transfers/comment_8_e856b350632cc865d16d1995a6cdf065._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmNu4V5fvpLlBhaCUfXXOB0MI5NXwh8SkU"
+ nickname="Adam"
+ subject="comment 8"
+ date="2013-11-03T01:07:31Z"
+ content="""
+> It's not a very usual configuration to have 2 repositories on the same machine with the git-annex assistant running in both. You might just want to configure the assistant to not run in the backup repository.
+
+Maybe that's the crux of the problem. But I'm not sure what I did wrong to make that happen. I have a second internal hard disk in my desktop system, and I wanted to put a Full Backup repo on it. I tried to add a \"Removable drive\" repo (since I sometimes unplug it to swap cables with a DVD drive), but since the assistant didn't detect any actual removable drives, that didn't work. So I used \"Add another repository\" and set it to a Full Backup repo. Is that the wrong way to do it? :)
+
+> Some of the things you've said suggest that the backup repository might not be immediately noticing when changes are pushed to it. Since its location is shown as /mnt/debian/home/me, I have to wonder if that's some NFS mount or other network filesystem causing problems.
+
+/mnt/debian is /dev/mapper/lvm-root, another internal disk. The disk is working fine. :)
+"""]]
diff --git a/doc/bugs/Unnecessary_remote_transfers/comment_9_64f831545b34b78452952cf49b5f5b05._comment b/doc/bugs/Unnecessary_remote_transfers/comment_9_64f831545b34b78452952cf49b5f5b05._comment
new file mode 100644
index 000000000..03127c4ad
--- /dev/null
+++ b/doc/bugs/Unnecessary_remote_transfers/comment_9_64f831545b34b78452952cf49b5f5b05._comment
@@ -0,0 +1,25 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 9"
+ date="2013-11-03T01:52:56Z"
+ content="""
+Ok, since we don't have NFS craziness, I'm going to put theories about it not noticing incoming syncs on hold. (I think I probably misunderstood [this comment](http://git-annex.branchable.com/bugs/Unnecessary_remote_transfers/#comment-39490c318620c141e7557b7bcba0e5c8) and anyway the assistant has some throttling so won't always immediately load config changes that have been synced to it if some other config changes were loaded a minute before.)
+
+I think this behavior can probably be explained without resorting to any bugs, now that I have, I think, a full picture of the repository network:
+
+<pre>
+laptop <-> desktop <-> backup
+ | | |
+ v v v
+ transfer (cloud)
+</pre>
+
+Now when a file is added to desktop, it immediately copies it to backup, which is on the same machine, so that happens quite quickly. Then it starts sending it across the LAN to laptop.
+
+Meanwhile, the assistant daemon running on backup wakes up, notices it's just received an object, and sees that this object is currently located on only desktop and backup, but not yet on laptop or transfer. Which means that it should send the object to transfer, from which it will eventually reach laptop.
+
+The only ways I can think of to avoid such an unnecessary transfer would be a) for desktop could somehow tell backup that it's in the process of sending the file to laptop or b) for a map of current state of the network to be constructed and maintained and analyzed automatically, so it it could conclude backup does not need to send files to transfer if they're already present on desktop. There is some discussion about this in [[design/assistant/syncing]]. Hard problem in general I think, although slightly less hard in this specific case since desktop and backup know they're in the same machine.
+
+But it should be easy to configure it so this doesn't happen. Just make backup not have the transfer repository configured as a remote (or just pause it syncing to there in the webapp). Or, don't run the assistant at all on backup (see `~/.config/git-annex/autostart`).
+"""]]
diff --git a/doc/bugs/Update_dependency_on_certificate___62____61___1.3.3.mdwn b/doc/bugs/Update_dependency_on_certificate___62____61___1.3.3.mdwn
new file mode 100644
index 000000000..2a2a1469d
--- /dev/null
+++ b/doc/bugs/Update_dependency_on_certificate___62____61___1.3.3.mdwn
@@ -0,0 +1,64 @@
+What steps will reproduce the problem?
+
+Run:
+
+ cabal install git-annex
+
+What is the expected output? What do you see instead?
+
+The current output is the following:
+
+ $ cabal install git-annex
+ Resolving dependencies...
+ Configuring certificate-1.3.2...
+ Building certificate-1.3.2...
+ Preprocessing library certificate-1.3.2...
+ [ 1 of 10] Compiling Data.Certificate.KeyDSA ( Data/Certificate/KeyDSA.hs, dist/build/Data/Certificate/KeyDSA.o )
+ [ 2 of 10] Compiling Data.Certificate.KeyRSA ( Data/Certificate/KeyRSA.hs, dist/build/Data/Certificate/KeyRSA.o )
+
+ Data/Certificate/KeyRSA.hs:64:27:
+ `RSA.private_pub' is not a (visible) field of constructor `RSA.PrivateKey'
+ cabal: Error: some packages failed to install:
+ DAV-0.3 depends on certificate-1.3.2 which failed to install.
+ authenticate-1.3.2 depends on certificate-1.3.2 which failed to install.
+ certificate-1.3.2 failed during the building phase. The exception was:
+ ExitFailure 1
+ git-annex-3.20130107 depends on certificate-1.3.2 which failed to install.
+ http-conduit-1.8.6.3 depends on certificate-1.3.2 which failed to install.
+ http-reverse-proxy-0.1.1.1 depends on certificate-1.3.2 which failed to install.
+ tls-1.0.3 depends on certificate-1.3.2 which failed to install.
+ tls-extra-0.5.1 depends on certificate-1.3.2 which failed to install.
+ yesod-1.1.7.2 depends on certificate-1.3.2 which failed to install.
+ yesod-auth-1.1.3 depends on certificate-1.3.2 which failed to install.
+
+I'd rather get a message stating how awesome the software I just installed is. :)
+
+What version of git-annex are you using? On what operating system?
+
+ * Debian (testing)
+ * GHC 7.4.1
+ * Cabal 1.14.0, cabal-install 0.14.0
+ * cabal list git-annex says the installing version is: 3.20130107
+
+Please provide any additional information below.
+
+The certificate package version 1.3.2 does not seem to install properly with
+this version of GHC (I think).
+
+Version 1.3.3 solves the issue. I don't know if there is a way for me to
+override the dependency tree to try to force the version update with
+cabal-install, so maybe it's worth filing a bug.
+
+Thanks a lot for git-annex.
+
+> Welcome to cabal hell! This problem is why haskell's cabal system is not
+> a sufficient way for users to install git-annex, and we have to provide
+> prebuilt builds.
+>
+> No change to git-annex can fix this problem. The problem is that
+> the old version of certificate got busted by some change to one of its
+> dependencies, and several libraries that git-annex depends on have not
+> yet been updated to use the new version of certificate. Once those
+> libraries get updated, it'll fix itself.
+>
+> [[done]]; not git-annex bug. --[[Joey]]
diff --git a/doc/bugs/Use_a_git_repository_on_the_server_don__39__t_work.mdwn b/doc/bugs/Use_a_git_repository_on_the_server_don__39__t_work.mdwn
new file mode 100644
index 000000000..1bb985891
--- /dev/null
+++ b/doc/bugs/Use_a_git_repository_on_the_server_don__39__t_work.mdwn
@@ -0,0 +1,49 @@
+What steps will reproduce the problem?
+1. Create a Repository
+2. Add a Remote Server
+
+What is the expected output? What do you see instead?
+The option "Use a git repository on the server" is marked as not available
+
+What version of git-annex are you using? On what operating system?
+Version: 4.20130405 but on Webapp ist shows: Version: 4.20130324
+Linux 64bit
+
+Please provide any additional information below.
+git and git-annex are available on the Remote Server
+
+> While this bug report was about a server that did not get git-annex-shell
+> installed in PATH (something trivially fixed by `apt-get install
+> git-annex`), the comments below would like to turn this into a bug report about
+> the error message "unknown UUID; cannot modify". All right then..
+> --[[Joey]]
+>
+> This can occur if a ssh key is locked down to use directory A, and a
+> new repo is added in directory B which uses the same ssh key. Things will
+> then fail when git-annex-shell rejects the attept to use directory B, and
+> this results in the webapp displaying an internal server error of
+> "unknown UUID; cannot modify" since NoUUID is retreived for the repo.
+>
+> In fact, I already dealt with this
+> once in 79561774450c8abf7c2cb42b08575a3ca27010dc; it used to not use
+> the directory name at all as part of the mangled hostname. Most of the
+> "me too" responses" predate that fix.
+>
+> Now, this can only happen
+> if the mangled hostname for directory A and B is the same. One way this can
+> happen is if the directories are "annex" and "~/annex". In other words,
+> I suspect that users are entering "annex" once, and "~/annex" another
+> time, when setting up what they intend to be the same repo. Perhaps the
+> first time something else fails (like the original problem of
+> git-annex-shell not being in path), or they want to set it up again,
+> and the next time the subtly different directory is entered.
+>
+> To fix this,
+> `mangleSshHostName` would need to be changed to generate different mangled
+> hostnames in all cases. Currently, it skips non-alpha-numeric
+> characters in the directory. [[done]] --[[Joey]]
+> --[[Joey]]
+>
+> Additionally, just entering a path starting with "~/" would cause this
+> error, since the webapp tacks on "/~/" to make a relative path absolute.
+> I've also fixed that. [[done]] --[[Joey]]
diff --git a/doc/bugs/Use_a_git_repository_on_the_server_don__39__t_work/comment_1_2143f0540fdcd7efeb25b5a3b54fe0fd._comment b/doc/bugs/Use_a_git_repository_on_the_server_don__39__t_work/comment_1_2143f0540fdcd7efeb25b5a3b54fe0fd._comment
new file mode 100644
index 000000000..aa8237c17
--- /dev/null
+++ b/doc/bugs/Use_a_git_repository_on_the_server_don__39__t_work/comment_1_2143f0540fdcd7efeb25b5a3b54fe0fd._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-04-06T16:38:46Z"
+ content="""
+Well, it works here. It checks that all of `git`, `rsync`, and `git-annex` are in the path on the remote server using `which`.
+
+I think the most likely reason would be if you've installed git-annex on the remote server but not in the PATH. If you're using the standalone tarball, for example, it's \"installed\", but it has no way to find it.
+
+Or, you could have installed from cabal, which puts it in ~/.cabal/bin or ~/bin or something like that, and perhaps you configured your shell to put that directory in the PATH, but you did it in a way that only works for login shells. If you set the PATH in `~/.bashrc`, for example, that would not work for a noninteractive shell.
+"""]]
diff --git a/doc/bugs/Use_a_git_repository_on_the_server_don__39__t_work/comment_2_bca95245b457631d08b47591da6163ad._comment b/doc/bugs/Use_a_git_repository_on_the_server_don__39__t_work/comment_2_bca95245b457631d08b47591da6163ad._comment
new file mode 100644
index 000000000..f93285611
--- /dev/null
+++ b/doc/bugs/Use_a_git_repository_on_the_server_don__39__t_work/comment_2_bca95245b457631d08b47591da6163ad._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="modules"
+ ip="31.150.97.85"
+ subject="comment 2"
+ date="2013-04-06T20:49:20Z"
+ content="""
+I have the same issue here and it seems to be the PATH problem with standalone tarball for noniteractive shell on remote server. Is there an easy way to setup right PATH or workaround for prebuilt tarballs?
+
+"""]]
diff --git a/doc/bugs/Use_a_git_repository_on_the_server_don__39__t_work/comment_3_f54bb003096752dae0442660267a1e37._comment b/doc/bugs/Use_a_git_repository_on_the_server_don__39__t_work/comment_3_f54bb003096752dae0442660267a1e37._comment
new file mode 100644
index 000000000..3a7158b80
--- /dev/null
+++ b/doc/bugs/Use_a_git_repository_on_the_server_don__39__t_work/comment_3_f54bb003096752dae0442660267a1e37._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-04-06T20:59:10Z"
+ content="""
+You can run this script as root, and it will install it to /usr/local/bin, which should always be in your path:
+<https://github.com/zerodogg/scriptbucket/blob/master/gitannex-install>
+
+However, I'd hope most people do not need to use the standalone tarball to install git-annex on a server. Most major linux distributions have their own way to install git-annex by now, and while most of them are too old versions to use the git annex assistant with, those old versions work fine on a server. The assistant will interoperate with them just fine.
+"""]]
diff --git a/doc/bugs/Use_a_git_repository_on_the_server_don__39__t_work/comment_4_38bb916ed5b90b92ffa91a452ff052a9._comment b/doc/bugs/Use_a_git_repository_on_the_server_don__39__t_work/comment_4_38bb916ed5b90b92ffa91a452ff052a9._comment
new file mode 100644
index 000000000..c9742b6e1
--- /dev/null
+++ b/doc/bugs/Use_a_git_repository_on_the_server_don__39__t_work/comment_4_38bb916ed5b90b92ffa91a452ff052a9._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnq5niDqUBoGE7cQ8MDQKtGYIfYtg3_MvY"
+ nickname="Tobias"
+ subject="comment 4"
+ date="2013-04-06T23:03:37Z"
+ content="""
+One Step forward. But now I get the error message \"Internal Server Error unknown UUID; cannot modify\" after click on the \"Use a git repository on the server\"-Button
+
+Thanks a lot for the link to the install-script. It works very well.
+"""]]
diff --git a/doc/bugs/Use_a_git_repository_on_the_server_don__39__t_work/comment_5_5b6ef464ab1ad061f27122db40191e26._comment b/doc/bugs/Use_a_git_repository_on_the_server_don__39__t_work/comment_5_5b6ef464ab1ad061f27122db40191e26._comment
new file mode 100644
index 000000000..f818a023e
--- /dev/null
+++ b/doc/bugs/Use_a_git_repository_on_the_server_don__39__t_work/comment_5_5b6ef464ab1ad061f27122db40191e26._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="EskildHustvedt"
+ ip="84.48.83.221"
+ subject="comment 5"
+ date="2013-04-08T07:41:38Z"
+ content="""
+Tobias, you may want to download the latest version of the install script and then run it as \"gitannex-install --force\", as its version of \"git-annex-shell\" was broken (linked to a missing file, fixed now).
+"""]]
diff --git a/doc/bugs/Use_a_git_repository_on_the_server_don__39__t_work/comment_6_3727bda5082cb1f2b1f746f9f80ced7d._comment b/doc/bugs/Use_a_git_repository_on_the_server_don__39__t_work/comment_6_3727bda5082cb1f2b1f746f9f80ced7d._comment
new file mode 100644
index 000000000..350139350
--- /dev/null
+++ b/doc/bugs/Use_a_git_repository_on_the_server_don__39__t_work/comment_6_3727bda5082cb1f2b1f746f9f80ced7d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnq5niDqUBoGE7cQ8MDQKtGYIfYtg3_MvY"
+ nickname="Tobias"
+ subject="comment 6"
+ date="2013-04-09T17:52:14Z"
+ content="""
+After update the script local and on the remote Server and run it on both with --force, I still get the same error.
+"""]]
diff --git a/doc/bugs/Use_a_git_repository_on_the_server_don__39__t_work/comment_7_a7139f19f0b73c024cd9218eb01e6104._comment b/doc/bugs/Use_a_git_repository_on_the_server_don__39__t_work/comment_7_a7139f19f0b73c024cd9218eb01e6104._comment
new file mode 100644
index 000000000..36547245e
--- /dev/null
+++ b/doc/bugs/Use_a_git_repository_on_the_server_don__39__t_work/comment_7_a7139f19f0b73c024cd9218eb01e6104._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnu1NYw8UF-NoDbKu8YKVGxi8FoZLH7JPs"
+ nickname="Chris"
+ subject="Same error with Android"
+ date="2013-05-21T02:15:25Z"
+ content="""
+I'm using git-annex version 4.20130516-g3240006 on Android, and when I attempt to add a cloud repo with SSH & git, I get that same error - \"unknown UUID: cannot modify\". My Linux box running 4.20130516-gedc4ccd handles the same server as a cloud repo without any problems.
+"""]]
diff --git a/doc/bugs/Using_Github_as_remote_throws_proxy_errors.mdwn b/doc/bugs/Using_Github_as_remote_throws_proxy_errors.mdwn
new file mode 100644
index 000000000..34d9eafb4
--- /dev/null
+++ b/doc/bugs/Using_Github_as_remote_throws_proxy_errors.mdwn
@@ -0,0 +1,27 @@
+What steps will reproduce the problem?
+
+1. cd to an already existing git repository that uses Github as a remote, with the remote format similar to git@github.com:user/repo.git
+2. git annex init
+3. git annex status
+
+What is the expected output? What do you see instead?
+
+ $ git annex status
+ supported backends: SHA256 SHA1 SHA512 SHA224 SHA384 SHA256E SHA1E SHA512E SHA224E SHA384E WORM URL
+ supported remote types: git S3 bup directory rsync web hook
+ trusted repositories: Invalid command: 'git-annex-shell 'configlist' '/~/dlo/objectifier.git''
+ You appear to be using ssh to clone a git:// URL.
+ Make sure your core.gitProxy config option and the
+ GIT_PROXY_COMMAND environment variable are NOT set.
+ Command ssh ["-S","/Users/dan/Documents/Web/objectifier/.git/annex/ssh/git@github.com","-o","ControlMaster=auto","-o","ControlPersist=yes","git@github.com","git-annex-shell 'configlist' '/~/dlo/objectifier.git'"] failed; exit code 1
+ 0
+ # ... other stuff that isn't relevant
+
+
+What version of git-annex are you using? On what operating system?
+
+git-annex-3.20120825
+
+Max OS X 10.8.1
+
+> [[done]]; see comments --[[Joey]]
diff --git a/doc/bugs/Using_Github_as_remote_throws_proxy_errors/comment_1_10616b17c3fb8286fdc64c841023f8a1._comment b/doc/bugs/Using_Github_as_remote_throws_proxy_errors/comment_1_10616b17c3fb8286fdc64c841023f8a1._comment
new file mode 100644
index 000000000..77ebcaa1a
--- /dev/null
+++ b/doc/bugs/Using_Github_as_remote_throws_proxy_errors/comment_1_10616b17c3fb8286fdc64c841023f8a1._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.14.141"
+ subject="comment 1"
+ date="2012-09-24T17:24:47Z"
+ content="""
+The proxy message is sent from github, so I can't do anything about that. `git@github.com:user/repo.git` is a ssh url, so git-annex tries to use it as a full git-annex remote. If you use a git:// url, git-annex will
+skip it. Or you can set `git config remote.origin.annex-ignore true` (replace origin with the name of the github remote).
+"""]]
diff --git a/doc/bugs/Using_Github_as_remote_throws_proxy_errors/comment_2_8a72887d33e492a041f8246d93d0c778._comment b/doc/bugs/Using_Github_as_remote_throws_proxy_errors/comment_2_8a72887d33e492a041f8246d93d0c778._comment
new file mode 100644
index 000000000..5fe4e6b5a
--- /dev/null
+++ b/doc/bugs/Using_Github_as_remote_throws_proxy_errors/comment_2_8a72887d33e492a041f8246d93d0c778._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmG8L2pP-i6QATf6pK9WCSGpl0O9twwh8Q"
+ nickname="Dan"
+ subject="comment 2"
+ date="2012-09-24T18:00:17Z"
+ content="""
+Ah, so with the full ssh URL, git annex thinks it's a \"real\" server and can run commands on it. Makes sense. Thanks!
+"""]]
diff --git a/doc/bugs/Using_a_revoked_GPG_key.mdwn b/doc/bugs/Using_a_revoked_GPG_key.mdwn
new file mode 100644
index 000000000..4e522ab78
--- /dev/null
+++ b/doc/bugs/Using_a_revoked_GPG_key.mdwn
@@ -0,0 +1,34 @@
+### Please describe the problem.
+git-annex refuses to use revoked GPG keys. This may be understandable for the initial remote setup, but it hit me when I tried to add a new key to a remote. The previous key has been revoked (because it has been superseded by the new one), and git-annex refused to reinvoke the shared key with both keys because one of them was revoked.
+
+Given the encryption model does not allow key replacement, it should not refuse to reencrypt using a revoked key. Maybe using `--expert` would help.
+
+### What steps will reproduce the problem?
+Encrypt a special remote with a key K1. Revoke key K1. Try to add key K2 with enableremote. git-annex will refuse to encrypt the shared key with the revoked one.
+
+### What version of git-annex are you using? On what operating system?
+git-annex version: 4.20130802-g1452ac3
+
+### Please provide any additional information below.
+
+[[!format sh """
+% git annex enableremote zoidberg-crypted encryption=42B8F7C2
+enableremote zoidberg-crypted (encryption update)
+You need a passphrase to unlock the secret key for
+user: "Samuel Tardieu <sam@rfc1149.net>"
+2048-bit ELG key, ID F0D70BAF, created 2002-05-31 (main key ID 1B80ADE6)
+
+gpg: NOTE: key has been revoked
+gpg: reason for revocation: Key is superseded
+gpg: revocation comment: Key superseded by 42B8F7C2
+gpg: revocation comment: (fingerprint 1D36 D924 8B33 DCAB 7BA5 BA44 7A30 BCF4 42B8 F7C2)
+gpg: F13322411B80ADE6: skipped: Unusable public key
+gpg: [stdin]: encryption failed: Unusable public key
+
+git-annex: user error (gpg ["--quiet","--trust-model","always","--encrypt","--no-encrypt-to","--no-default-recipient","--recipient","7A30BCF442B8F7C2","--recipient","F13322411B80ADE6"] exited 2)
+failed
+git-annex: enableremote: 1 failed
+"""]]
+
+> [[done]]; can now use: `git annex enableremote foo keyid-=REVOKEDKEY
+> keyid+=NEWKEY` to remove it, and add a new key. --[[Joey]]
diff --git a/doc/bugs/Using_a_revoked_GPG_key/comment_1_7bb01d081282e5b02b7720b2953fe5be._comment b/doc/bugs/Using_a_revoked_GPG_key/comment_1_7bb01d081282e5b02b7720b2953fe5be._comment
new file mode 100644
index 000000000..baddbbf49
--- /dev/null
+++ b/doc/bugs/Using_a_revoked_GPG_key/comment_1_7bb01d081282e5b02b7720b2953fe5be._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmWg4VvDTer9f49Y3z-R0AH16P4d1ygotA"
+ nickname="Tobias"
+ subject="comment 1"
+ date="2013-08-12T11:47:28Z"
+ content="""
+I'd be very unhappy indeed if I couldn't revoke access to my annex.
+"""]]
diff --git a/doc/bugs/Using_a_revoked_GPG_key/comment_2_9c0c40360f0058a4bd346c1362e302b6._comment b/doc/bugs/Using_a_revoked_GPG_key/comment_2_9c0c40360f0058a4bd346c1362e302b6._comment
new file mode 100644
index 000000000..003f9a34a
--- /dev/null
+++ b/doc/bugs/Using_a_revoked_GPG_key/comment_2_9c0c40360f0058a4bd346c1362e302b6._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://www.rfc1149.net/"
+ nickname="Sam"
+ subject="comment 2"
+ date="2013-08-13T07:28:30Z"
+ content="""
+Tobias: I don't understand what you mean. The issue here is that once an existing key is revoked, git-annex will refuse to add *another non-revoked* key.
+"""]]
diff --git a/doc/bugs/Using_a_revoked_GPG_key/comment_3_8f69f58107246595f5603f35c4aa7395._comment b/doc/bugs/Using_a_revoked_GPG_key/comment_3_8f69f58107246595f5603f35c4aa7395._comment
new file mode 100644
index 000000000..7f18cfe39
--- /dev/null
+++ b/doc/bugs/Using_a_revoked_GPG_key/comment_3_8f69f58107246595f5603f35c4aa7395._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmWg4VvDTer9f49Y3z-R0AH16P4d1ygotA"
+ nickname="Tobias"
+ subject="comment 3"
+ date="2013-08-13T08:47:45Z"
+ content="""
+Ah, sorry, i'm uncomprehending :)
+"""]]
diff --git a/doc/bugs/Using_a_revoked_GPG_key/comment_4_78b3c52ba85edfa6ee6e273bec3bea5c._comment b/doc/bugs/Using_a_revoked_GPG_key/comment_4_78b3c52ba85edfa6ee6e273bec3bea5c._comment
new file mode 100644
index 000000000..61b03c109
--- /dev/null
+++ b/doc/bugs/Using_a_revoked_GPG_key/comment_4_78b3c52ba85edfa6ee6e273bec3bea5c._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="guilhem"
+ ip="129.16.20.209"
+ subject="comment 4"
+ date="2013-08-16T07:14:12Z"
+ content="""
+The [[OpenPGP standard|https://tools.ietf.org/html/rfc4880]] specifies that revoked keys/subkeys \"are not to be used\". AFIK GnuPG, as any RFC-compliant implementation, will not let you encrypt to a revoked key no matter what. An extremely dirty workaround is to set up your system clock prior to the revocation date (but that might put your whole system at risk since other applications may rely synced clocks to work properly).
+
+That said, what you really wanted to do was to revoke access to K1 and add K2 instead. That seems to be a perfectly valid use-case, and it shouldn't be hard to add to git-annex; stay tunned ;-)
+
+
+Tobias: Not sure what you meant by \"revoke access to my annex\", but if you were thinking of the key owner, note that with the current [[encryption design|http://git-annex.branchable.com/design/encryption]], since that person may simply grab from the git repo and then at any time decrypt the passphrase for the symmetric cipher, it makes little sense to revoke access for that person unless you change that passphrase, and reencrypt all annexed files on the remote, which of course needs to be done locally for the encryption to make sense at all.
+"""]]
diff --git a/doc/bugs/Using_a_revoked_GPG_key/comment_5_a85ccf2f09ebe87147f8761b81a02326._comment b/doc/bugs/Using_a_revoked_GPG_key/comment_5_a85ccf2f09ebe87147f8761b81a02326._comment
new file mode 100644
index 000000000..ff441671f
--- /dev/null
+++ b/doc/bugs/Using_a_revoked_GPG_key/comment_5_a85ccf2f09ebe87147f8761b81a02326._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://www.rfc1149.net/"
+ nickname="Sam"
+ subject="comment 5"
+ date="2013-08-19T11:35:52Z"
+ content="""
+Indeed, removing the revoked key and putting the new one would be acceptable, there is no reason to keep the revoked one around.
+"""]]
diff --git a/doc/bugs/Using_a_revoked_GPG_key/comment_6_8b89eb5e6386acd0a922310c04f863ac._comment b/doc/bugs/Using_a_revoked_GPG_key/comment_6_8b89eb5e6386acd0a922310c04f863ac._comment
new file mode 100644
index 000000000..eb9cd0f54
--- /dev/null
+++ b/doc/bugs/Using_a_revoked_GPG_key/comment_6_8b89eb5e6386acd0a922310c04f863ac._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="guilhem"
+ ip="129.16.20.209"
+ subject="comment 6"
+ date="2013-08-19T13:22:59Z"
+ content="""
+All right, what would be a nice user interface, compatible with the current commands? I was thinking of something along the lines of `git annex enableremote +encryption=newKey -encryption=oldKey`, with an alias `+encryption=encryption` to be backward compatible. It's probably not optimal though, feel free to comment :-)
+
+Of course, `git-annex` should ensure that at any point in time the passphrase is always encrypted using an OpenPGP key. (Otherwise it might be stored clear in the git repository, which would void the encryption.) Also, anyone who can decrypt the passphrase can revoke all existing keys and reencrypt it using another key; this not really a big deal since the cipher is version-controlled anyway, so loosing access to the repo is unlikely.
+
+By the way, since we're about to amend the arguments for `enableremote`, it'd be nice to take advantage of the situation to allow pure asymmetric encryption. I propose `git annex initremote ... encryption=myKey crypto={none,hybrid,pubkey}` to use respectively no-encryption, an asymmetrically encrypted passphrase (the current design, default), and OpenPGP keys only.
+"""]]
diff --git a/doc/bugs/Using_a_revoked_GPG_key/comment_7_20dc5a7ce7cb6ca97ccdfb923c3b24bb._comment b/doc/bugs/Using_a_revoked_GPG_key/comment_7_20dc5a7ce7cb6ca97ccdfb923c3b24bb._comment
new file mode 100644
index 000000000..02be72e36
--- /dev/null
+++ b/doc/bugs/Using_a_revoked_GPG_key/comment_7_20dc5a7ce7cb6ca97ccdfb923c3b24bb._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="guilhem"
+ ip="129.16.20.209"
+ subject="comment 7"
+ date="2013-08-19T16:08:49Z"
+ content="""
+On second thought, I think it makes more sense to have something like `git annex initremote ... encryption={none,shared,hybrid,pubkey} keyid=whatever` and `git annex enableremote ... [+keyid=newkey] [-keyid=oldkey]`, where `keyid` can only be used when `encryption` is either `hybrid` (default) or `pubkey`.
+
+This would break compatibility with the current interpretation of `encryption`, but I believe it's not so invasive: People are not creating new remotes every day, and an error message could clarify the new behavior. It's also clearer, since key IDs can be added and deleted at will, whereas the encryption scheme cannot.
+"""]]
diff --git a/doc/bugs/Using_a_revoked_GPG_key/comment_8_9dc921dc6077f828454a4444088b9a43._comment b/doc/bugs/Using_a_revoked_GPG_key/comment_8_9dc921dc6077f828454a4444088b9a43._comment
new file mode 100644
index 000000000..a63ce1262
--- /dev/null
+++ b/doc/bugs/Using_a_revoked_GPG_key/comment_8_9dc921dc6077f828454a4444088b9a43._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 8"
+ date="2013-08-22T17:05:49Z"
+ content="""
+Note that the assistant generates initremote parameters so code there also needs to be changed if the syntax changes.
+
+I think I am ok with changing the syntax. However, it seems that `encryption=-oldkey encryption=newkey` could be used to remove the old revoked key and add a new one. Using `-keyid` as a parameter to initremote is a bit tricky since git-annex's regular option parser would see it, before the parameter could get to initremote. (Unless -keyid was defined as a regular option specific to initremote.) OR, git-annex could just try to detect when a key is revoked and automatically remove it when a new encryption key is specified.
+
+Hmm, it would be possible to have it just notice, when adding a new key, if one of the existing keys is revoked, and
+remove the revoked key automatically.
+
+The above doesn't deal with the case of wanting to add pure asymmetric encryption. It seems to me that from a user's point of view, what they really need to know about asymmetric encryption is that they can't easily give additional keyids access after the fact (without reencrypting and reuploading everything). So I think it would be good if the syntax made that obvious. Perhaps `encryptiononly=key`
+"""]]
diff --git a/doc/bugs/Using_a_revoked_GPG_key/comment_9_f50c802d78041fd1522f0e7599ce6a45._comment b/doc/bugs/Using_a_revoked_GPG_key/comment_9_f50c802d78041fd1522f0e7599ce6a45._comment
new file mode 100644
index 000000000..d86de4e1b
--- /dev/null
+++ b/doc/bugs/Using_a_revoked_GPG_key/comment_9_f50c802d78041fd1522f0e7599ce6a45._comment
@@ -0,0 +1,42 @@
+[[!comment format=mdwn
+ username="guilhem"
+ ip="129.16.20.209"
+ subject="comment 9"
+ date="2013-08-22T18:42:28Z"
+ content="""
+Hehe, I ran into the option parser issue when implementing that change
+;-) So I moved to `git annex enableremote ... [keyid+=newkey]
+[keyid-=oldkey]` (where `+` is optional, for consistency) which doesn't
+prevent users from specifying a key by something starting with a sign.
+
+While it's certainly possible to tell git-annex to manage the authorized
+keys itself, users may have other reasons to remove a key so I'm not
+sure it's a good idea. Also, what if someone forgets to add his/her new
+key after revocation (it's still possible to decrypt after all)? If
+another person updates the keyring afterwards, the first user will be
+denied further access, and will have to retrieve and reencrypt the
+\"cipher\" manually, which is not so trivial.
+
+
+I understand that asymmetric encryption needs special care, but Sam's
+use case could be reproduced with that scheme I believe. For instance a
+user may superseed and revoke his/her old key; then new files would be
+uploaded with the new one, but as long as the old key is not
+compromised, I don't see why s/he should reupload everything instead of
+using the old key when pulling from the remote. Of course one may argue
+that the key shouldn't be revoked at the first place, but if it's used
+for other purposes (e.g., it's publicly available on a key server) it's
+good practice to revoke it IMHO.
+
+As for the removal of keys with pure asymmetric encryption, it is just
+required I think: Otherwise revoking a key would prevent any further
+content to be encrypted. There I can't see any problem with git-annex
+managing the keyring itself (beside the extra code to write :-P).
+
+All in all if we are to allow deletion/addition of keyIDs (and I think
+we should!), I think it should be done for both `hybrid` and `pubkey`
+schemes. Do you really want another syntax? I'd say clarify the manage
+(plus maybe a warning when running the CLI) is enough, but true it's
+easy to shoot oneself in the foot there...
+
+"""]]
diff --git a/doc/bugs/WEBDAV_443.mdwn b/doc/bugs/WEBDAV_443.mdwn
new file mode 100644
index 000000000..cfde1a1a7
--- /dev/null
+++ b/doc/bugs/WEBDAV_443.mdwn
@@ -0,0 +1,307 @@
+What steps will reproduce the problem?
+
+```
+WEBDAV_USERNAME=pradermecker@yahoo.ca WEBDAV_PASSWORD=xxxxxx git annex initremote box.com type=webdav url=https://www.box.com/dav/git-annex chunksize=75mb encryption=none
+```
+
+What is the expected output? What do you see instead?
+
+I have:
+```
+git-annex: WebDAV failed to write file: FailedConnectionException "www.box.com" 443: user error
+```
+# What version of git-annex are you using? On what operating system?
+
+```
+git-annex version: 4.20130314
+local repository version: 3
+default repository version: 3
+supported repository versions: 3 4
+upgrade supported from repository versions: 0 1 2
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP DNS
+```
+Archlinux 64: https://aur.archlinux.org/packages/git-annex/
+
+# Please provide any additional information below.
+
+1. Try my password a couple of time. It works with Chrome, Firefox or cadaver
+2. I am using a zsh shell and try exporting both env. variables
+3. git-annex test has errors
+
+### Error in: git-annex add:1
+sha1foodup: openFile: does not exist (No such file or directory)
+Cases: 3 Tried: 2 Errors: 2 Failures: 0warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+git-annex: dir/foo: getFileStatus: does not exist (No such file or directory)
+### Failure in: git-annex add:2
+add of subdir failed
+Cases: 3 Tried: 3 Errors: 2 Failures: 1
+----------------------------------------------------------------------
+reinject
+Cases: 1 Tried: 0 Errors: 0 Failures: 0warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+git-annex: sha1foo not found
+### Failure in: git-annex reinject/fromkey
+reinject failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+----------------------------------------------------------------------
+unannex
+Cases: 2 Tried: 0 Errors: 0 Failures: 0warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+### Error in: git-annex unannex:0:no content
+foo: getSymbolicLinkStatus: does not exist (No such file or directory)
+Cases: 2 Tried: 1 Errors: 1 Failures: 0warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+git-annex: foo not found
+### Error in: git-annex unannex:1:with content
+foo: getSymbolicLinkStatus: does not exist (No such file or directory)
+Cases: 2 Tried: 2 Errors: 2 Failures: 0
+----------------------------------------------------------------------
+drop
+Cases: 3 Tried: 0 Errors: 0 Failures: 0warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+git-annex: foo not found
+git-annex: foo not found
+### Failure in: git-annex drop:0:no remotes
+drop wrongly succeeded with no known copy of file
+Cases: 3 Tried: 1 Errors: 0 Failures: 1warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+git-annex: foo not found
+### Error in: git-annex drop:1:with remote
+foo: getSymbolicLinkStatus: does not exist (No such file or directory)
+Cases: 3 Tried: 2 Errors: 1 Failures: 1warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+git-annex: foo not found
+### Error in: git-annex drop:2:untrusted remote
+foo: getSymbolicLinkStatus: does not exist (No such file or directory)
+Cases: 3 Tried: 3 Errors: 2 Failures: 1
+----------------------------------------------------------------------
+get
+Cases: 1 Tried: 0 Errors: 0 Failures: 0warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+### Error in: git-annex get
+foo: openFile: does not exist (No such file or directory)
+Cases: 1 Tried: 1 Errors: 1 Failures: 0
+----------------------------------------------------------------------
+move
+Cases: 1 Tried: 0 Errors: 0 Failures: 0warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+### Error in: git-annex move
+foo: getSymbolicLinkStatus: does not exist (No such file or directory)
+Cases: 1 Tried: 1 Errors: 1 Failures: 0
+----------------------------------------------------------------------
+copy
+Cases: 1 Tried: 0 Errors: 0 Failures: 0warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+### Error in: git-annex copy
+foo: getSymbolicLinkStatus: does not exist (No such file or directory)
+Cases: 1 Tried: 1 Errors: 1 Failures: 0
+----------------------------------------------------------------------
+lock
+Cases: 1 Tried: 0 Errors: 0 Failures: 0warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+### Error in: git-annex unlock/lock
+foo: getSymbolicLinkStatus: does not exist (No such file or directory)
+Cases: 1 Tried: 1 Errors: 1 Failures: 0
+----------------------------------------------------------------------
+edit
+Cases: 2 Tried: 0 Errors: 0 Failures: 0warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+git-annex: foo not found
+### Error in: git-annex edit/commit:0
+foo: getSymbolicLinkStatus: does not exist (No such file or directory)
+Cases: 2 Tried: 1 Errors: 1 Failures: 0warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+git-annex: foo not found
+### Error in: git-annex edit/commit:1
+foo: getSymbolicLinkStatus: does not exist (No such file or directory)
+Cases: 2 Tried: 2 Errors: 2 Failures: 0
+----------------------------------------------------------------------
+fix
+Cases: 1 Tried: 0 Errors: 0 Failures: 0warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+### Error in: git-annex fix
+foo: getSymbolicLinkStatus: does not exist (No such file or directory)
+Cases: 1 Tried: 1 Errors: 1 Failures: 0
+----------------------------------------------------------------------
+trust
+Cases: 1 Tried: 0 Errors: 0 Failures: 0warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+Cases: 1 Tried: 1 Errors: 0 Failures: 0
+----------------------------------------------------------------------
+fsck
+Cases: 4 Tried: 0 Errors: 0 Failures: 0warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+### Failure in: git-annex fsck:0
+fsck failed to fail with numcopies unsatisfied
+Cases: 4 Tried: 2 Errors: 0 Failures: 1warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+git-annex: foo not found
+### Failure in: git-annex fsck:2
+fsck failed to fail with content only available in untrusted (current) repository
+Cases: 4 Tried: 3 Errors: 0 Failures: 2warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+git-annex: foo not found
+git-annex: sha1foo not found
+### Failure in: git-annex fsck:3
+fsck failed to fail with content not replicated to enough non-untrusted repositories
+Cases: 4 Tried: 4 Errors: 0 Failures: 3
+----------------------------------------------------------------------
+migrate
+Cases: 2 Tried: 0 Errors: 0 Failures: 0warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+### Error in: git-annex migrate:0
+foo: getSymbolicLinkStatus: does not exist (No such file or directory)
+Cases: 2 Tried: 1 Errors: 1 Failures: 0warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+### Error in: git-annex migrate:1
+foo: getSymbolicLinkStatus: does not exist (No such file or directory)
+Cases: 2 Tried: 2 Errors: 2 Failures: 0
+----------------------------------------------------------------------
+ unused
+Cases: 1 Tried: 0 Errors: 0 Failures: 0warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+git-annex: foo not found
+git-annex: sha1foo not found
+fatal: pathspec 'foo' did not match any files
+### Failure in: git-annex unused/dropunused
+git rm failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+----------------------------------------------------------------------
+describe
+Cases: 1 Tried: 0 Errors: 0 Failures: 0warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+Cases: 1 Tried: 1 Errors: 0 Failures: 0
+----------------------------------------------------------------------
+find
+Cases: 1 Tried: 0 Errors: 0 Failures: 0warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+### Error in: git-annex find
+foo: getSymbolicLinkStatus: does not exist (No such file or directory)
+Cases: 1 Tried: 1 Errors: 1 Failures: 0
+----------------------------------------------------------------------
+merge
+Cases: 1 Tried: 0 Errors: 0 Failures: 0warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+Cases: 1 Tried: 1 Errors: 0 Failures: 0
+----------------------------------------------------------------------
+status
+Cases: 1 Tried: 0 Errors: 0 Failures: 0warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+{"command":"status","supported backends":["SHA256E","SHA1E","SHA512E","SHA224E","SHA384E","SHA256","SHA1","SHA512","SHA224","SHA384","WORM","URL"],"supported remote types":["git","S3","bup","directory","rsync","web","webdav","glacier","hook"],"repository mode":"indirect","trusted repositories":[],"semitrusted repositories":[{"uuid":"00000000-0000-0000-0000-000000000001","description":"web","here":false},{"uuid":"80db3ccc-8c73-4279-b803-1b02c91dd158","description":".t/tmprepo0","here":true},{"uuid":"c01ef662-caa7-46d1-95de-544bee8b08f1","description":"origin (test repo)","here":false}],"untrusted repositories":[],"dead repositories":[],"available local disk space":"75 gigabytes (+1 megabyte reserved)","local annex keys":0,"local annex size":"0 bytes","known annex keys":0,"known annex size":"0 bytes","bloom filter size":"16 mebibytes (0% full)","success":true}
+Cases: 1 Tried: 1 Errors: 0 Failures: 0
+----------------------------------------------------------------------
+version
+Cases: 1 Tried: 0 Errors: 0 Failures: 0warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+git-annex version: 4.20130314
+local repository version: 3
+default repository version: 3
+supported repository versions: 3 4
+upgrade supported from repository versions: 0 1 2
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP DNS
+Cases: 1 Tried: 1 Errors: 0 Failures: 0
+----------------------------------------------------------------------
+sync
+Cases: 1 Tried: 0 Errors: 0 Failures: 0warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+# On branch master
+#
+# Initial commit
+#
+nothing to commit (create/copy files and use "git add" to track)
+### Failure in: git-annex sync
+sync failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+----------------------------------------------------------------------
+sync regression
+Cases: 1 Tried: 0 Errors: 0 Failures: 0warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+git-annex: foo not found
+git-annex: foo not found
+git-annex: foo not found
+# On branch master
+#
+# Initial commit
+#
+nothing to commit (create/copy files and use "git add" to track)
+### Failure in: git-annex sync_regression
+sync failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+----------------------------------------------------------------------
+map
+Cases: 1 Tried: 0 Errors: 0 Failures: 0warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+Cases: 1 Tried: 1 Errors: 0 Failures: 0
+----------------------------------------------------------------------
+uninit
+Cases: 1 Tried: 0 Errors: 0 Failures: 0warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+### Error in: git-annex uninit
+foo: getSymbolicLinkStatus: does not exist (No such file or directory)
+Cases: 1 Tried: 1 Errors: 1 Failures: 0
+----------------------------------------------------------------------
+upgrade
+Cases: 1 Tried: 0 Errors: 0 Failures: 0warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+Cases: 1 Tried: 1 Errors: 0 Failures: 0
+----------------------------------------------------------------------
+whereis
+Cases: 1 Tried: 0 Errors: 0 Failures: 0warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+### Error in: git-annex whereis
+foo: getSymbolicLinkStatus: does not exist (No such file or directory)
+Cases: 1 Tried: 1 Errors: 1 Failures: 0
+----------------------------------------------------------------------
+hook remote
+Cases: 1 Tried: 0 Errors: 0 Failures: 0warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+git-annex: foo not found
+### Error in: git-annex hook remote
+foo: getSymbolicLinkStatus: does not exist (No such file or directory)
+Cases: 1 Tried: 1 Errors: 1 Failures: 0
+----------------------------------------------------------------------
+directory remote
+Cases: 1 Tried: 0 Errors: 0 Failures: 0warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+git-annex: foo not found
+### Error in: git-annex directory remote
+foo: getSymbolicLinkStatus: does not exist (No such file or directory)
+Cases: 1 Tried: 1 Errors: 1 Failures: 0
+----------------------------------------------------------------------
+rsync remote
+Cases: 1 Tried: 0 Errors: 0 Failures: 0warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+git-annex: foo not found
+### Error in: git-annex rsync remote
+foo: getSymbolicLinkStatus: does not exist (No such file or directory)
+Cases: 1 Tried: 1 Errors: 1 Failures: 0
+----------------------------------------------------------------------
+bup remote
+Cases: 1 Tried: 0 Errors: 0 Failures: 0warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+Cases: 1 Tried: 1 Errors: 0 Failures: 0
+----------------------------------------------------------------------
+crypto
+Cases: 1 Tried: 0 Errors: 0 Failures: 0warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+git-annex: foo not found
+### Error in: git-annex crypto
+foo: getSymbolicLinkStatus: does not exist (No such file or directory)
+Cases: 1 Tried: 1 Errors: 1 Failures: 0
+----------------------------------------------------------------------
+Some tests failed!
+ (This could be due to a bug in git-annex, or an incompatability
+ with utilities, such as git, installed on this system.)
+
+> (The test suite output suggests to me that it was run on a system
+> that does not support symlinks, and may be broken in some other way
+> as well, but is not relevant to this bug report.)
+> --[[Joey]]
+
+> Closing this bug since the bug submitter cannot reproduce it and
+> had many problems that seems to point at a bad build. [[done]] --[[Joey]]
diff --git a/doc/bugs/WEBDAV_443/comment_10_9ee2c5ed44295455af890caee7b06f1a._comment b/doc/bugs/WEBDAV_443/comment_10_9ee2c5ed44295455af890caee7b06f1a._comment
new file mode 100644
index 000000000..38c38e019
--- /dev/null
+++ b/doc/bugs/WEBDAV_443/comment_10_9ee2c5ed44295455af890caee7b06f1a._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="https://pradermecker.myopenid.com/"
+ ip="195.244.162.7"
+ subject="comment 10"
+ date="2013-03-18T15:47:19Z"
+ content="""
+Ok, I will try that.
+
+For your information, I have rebuild the aur package inside a VM using the latest master. All tests passed.
+
+Now I get a new error message with WEBDAV saying:
+
+```
+git-annex: WebDAV failed to write file: \"Conflict\": user error
+```
+
+As a note the current aur build is rather cumbersome because it needs to rebuild a lot of packages using cabal. I believe this is due to a few missing dependencies in the Arch repos [haskell-core] and [haskell-web] such as uuid, SafeSemaphore or c2hs.
+"""]]
diff --git a/doc/bugs/WEBDAV_443/comment_11_863a7d315212c9a8ab8f6fafa5d1b7f5._comment b/doc/bugs/WEBDAV_443/comment_11_863a7d315212c9a8ab8f6fafa5d1b7f5._comment
new file mode 100644
index 000000000..c58c70c21
--- /dev/null
+++ b/doc/bugs/WEBDAV_443/comment_11_863a7d315212c9a8ab8f6fafa5d1b7f5._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://pradermecker.myopenid.com/"
+ ip="195.244.162.7"
+ subject="comment 11"
+ date="2013-03-18T16:24:52Z"
+ content="""
+FYI, it is a bit heavy for me to try the standalone version as it is 32 bits only (I am on 64-bits)
+"""]]
diff --git a/doc/bugs/WEBDAV_443/comment_12_c17a4e23011e0a917dbe0ecf7e9f0cb5._comment b/doc/bugs/WEBDAV_443/comment_12_c17a4e23011e0a917dbe0ecf7e9f0cb5._comment
new file mode 100644
index 000000000..be045c407
--- /dev/null
+++ b/doc/bugs/WEBDAV_443/comment_12_c17a4e23011e0a917dbe0ecf7e9f0cb5._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 12"
+ date="2013-03-18T16:33:31Z"
+ content="""
+The standalone version works on either architecture, it does not depend on any system libraries, thus the name \"standalone\".
+"""]]
diff --git a/doc/bugs/WEBDAV_443/comment_13_3414416ff455d2fd1a7c7e7c4554b54d._comment b/doc/bugs/WEBDAV_443/comment_13_3414416ff455d2fd1a7c7e7c4554b54d._comment
new file mode 100644
index 000000000..0a3297f71
--- /dev/null
+++ b/doc/bugs/WEBDAV_443/comment_13_3414416ff455d2fd1a7c7e7c4554b54d._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://pradermecker.myopenid.com/"
+ ip="195.244.162.7"
+ subject="comment 13"
+ date="2013-03-18T16:39:58Z"
+ content="""
+I actually don't know if it has something to do with 32 or 64 bits but with the standalone I have got:
+/opt/git-annex.linux/runshell: line 69: /opt/git-annex.linux/bin/git-annex-shell: No such file or directory
+
+I have tried both the aur standalone and directly downloading the tarball.
+"""]]
diff --git a/doc/bugs/WEBDAV_443/comment_14_e1da141eefb0445c217e5f5c119356da._comment b/doc/bugs/WEBDAV_443/comment_14_e1da141eefb0445c217e5f5c119356da._comment
new file mode 100644
index 000000000..5097df183
--- /dev/null
+++ b/doc/bugs/WEBDAV_443/comment_14_e1da141eefb0445c217e5f5c119356da._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 14"
+ date="2013-03-18T16:54:02Z"
+ content="""
+Given that line 69 of runshell is a newline, and that runshell does not ever try to run git-annex-shell, I wonder what you downloaded exactly...
+"""]]
diff --git a/doc/bugs/WEBDAV_443/comment_15_41c3134bcc222b97bf183559723713d9._comment b/doc/bugs/WEBDAV_443/comment_15_41c3134bcc222b97bf183559723713d9._comment
new file mode 100644
index 000000000..5bf5bafe4
--- /dev/null
+++ b/doc/bugs/WEBDAV_443/comment_15_41c3134bcc222b97bf183559723713d9._comment
@@ -0,0 +1,27 @@
+[[!comment format=mdwn
+ username="https://pradermecker.myopenid.com/"
+ ip="195.244.162.7"
+ subject="comment 15"
+ date="2013-03-18T19:07:31Z"
+ content="""
+Euh. I actually feel stupid enough with this but ...
+
+I have try first with your link and it gives me:
+
+```
+./runshell: line 75: /home/vagrant/programs/git-annex.linux/bin/sh: No such file or directory
+```
+
+As I told you I then try the AUR package : https://aur.archlinux.org/packages/git-annex-standalone/
+
+And it does give me the same error on line 69.
+
+It is the same line (3 lines before the end):
+
+```
+exec \"$cmd\" \"$@\"
+```
+
+I really don't get it because the file is there ... and the first sanity checks of the script have pass.
+
+"""]]
diff --git a/doc/bugs/WEBDAV_443/comment_16_89621b526065b5bef753ce75db1af7b5._comment b/doc/bugs/WEBDAV_443/comment_16_89621b526065b5bef753ce75db1af7b5._comment
new file mode 100644
index 000000000..059a8ee00
--- /dev/null
+++ b/doc/bugs/WEBDAV_443/comment_16_89621b526065b5bef753ce75db1af7b5._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://pradermecker.myopenid.com/"
+ ip="195.244.162.7"
+ subject="comment 16"
+ date="2013-03-18T19:31:42Z"
+ content="""
+Actually it is even worse ...
+
+With your link, line 75 is actually 2 lines below (sh).
+
+So same command (runshell), same error, different places (I guess it is always the last line executed) ...
+
+Is it supposed to work fine in 64 bits also ?
+"""]]
diff --git a/doc/bugs/WEBDAV_443/comment_17_131a1b65c8008cf9f02c93d4fb75720b._comment b/doc/bugs/WEBDAV_443/comment_17_131a1b65c8008cf9f02c93d4fb75720b._comment
new file mode 100644
index 000000000..515976b85
--- /dev/null
+++ b/doc/bugs/WEBDAV_443/comment_17_131a1b65c8008cf9f02c93d4fb75720b._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 7"
+ date="2013-03-18T23:05:26Z"
+ content="""
+The standalone linux tarball will work on 64 or 32 bit systems, as long as they are capable of linking 32 bit elf executables. I cannot test if Arch Linux is incapable of this.
+
+I'm getting a bit tired of wild tangents, can we you just find someplace, be it a Debian chroot or whatever, to run the standalone linux tarball and test if DAV works there?
+"""]]
diff --git a/doc/bugs/WEBDAV_443/comment_18_b4f894a0b9ebb84ab73f6ffcf0778090._comment b/doc/bugs/WEBDAV_443/comment_18_b4f894a0b9ebb84ab73f6ffcf0778090._comment
new file mode 100644
index 000000000..fe25b98e6
--- /dev/null
+++ b/doc/bugs/WEBDAV_443/comment_18_b4f894a0b9ebb84ab73f6ffcf0778090._comment
@@ -0,0 +1,29 @@
+[[!comment format=mdwn
+ username="https://pradermecker.myopenid.com/"
+ ip="195.244.162.7"
+ subject="It works !"
+ date="2013-03-19T10:40:31Z"
+ content="""
+Sorry for the wild tangents.
+
+It is now working. I am not sure what went wrong.
+
+For the record here are the steps I took (all using the Git annex UI):
+
+* Set up removable media -> OK
+* Set up remote SSH -> missing lsof -> install it -> everything OK
+* Set up S3 -> had issue with time -> solve it with ntp -> everything OK
+* Try again WebDav -> \"Conflict\" message -> try using another dir -> everything OK
+
+There might be a \"cleanup after error problem\" somewhere that would explain the conflict message I have received.
+
+Again for the record, I made it works inside a VM using the AUR \"git-annex 4.20130314-1\" (not the standalone). The only change I made on the PKGBUILD was to install everything with cabal except for the packages in the [haskell-core] Arch repo. I know you are not aware with Arch but basically I choose not to rely on the [haskell-web] Arch repo.
+
+I will try again at home on my laptop and I will try the standalone as well.
+
+Thanks you so much for the wonderful product !
+
+Cheers
+
+
+"""]]
diff --git a/doc/bugs/WEBDAV_443/comment_1_c6572ca1eaaf89b01c0ed99a4058412f._comment b/doc/bugs/WEBDAV_443/comment_1_c6572ca1eaaf89b01c0ed99a4058412f._comment
new file mode 100644
index 000000000..f474fe488
--- /dev/null
+++ b/doc/bugs/WEBDAV_443/comment_1_c6572ca1eaaf89b01c0ed99a4058412f._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-03-16T15:35:05Z"
+ content="""
+The i386 standalone build for 4.20130314, which is IIRC repackaged by Arch linux, was made using a known broken webdav library. I've since updated that build to use a new version of webdav. Since it only affected that one build, I do not plan to do a full re-release with a new version number.
+
+Probably Arch needs to update their package.
+"""]]
diff --git a/doc/bugs/WEBDAV_443/comment_2_a357969cde382a91e13920ee1e9f711c._comment b/doc/bugs/WEBDAV_443/comment_2_a357969cde382a91e13920ee1e9f711c._comment
new file mode 100644
index 000000000..522685670
--- /dev/null
+++ b/doc/bugs/WEBDAV_443/comment_2_a357969cde382a91e13920ee1e9f711c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://pradermecker.myopenid.com/"
+ ip="81.244.205.197"
+ subject="Thanks"
+ date="2013-03-16T15:46:45Z"
+ content="""
+Thanks for your quick comment ! I was about to get crazy trying my password again and again ;-)
+"""]]
diff --git a/doc/bugs/WEBDAV_443/comment_3_213815d6b827d467c60f3e8af925813b._comment b/doc/bugs/WEBDAV_443/comment_3_213815d6b827d467c60f3e8af925813b._comment
new file mode 100644
index 000000000..60f7ef9d3
--- /dev/null
+++ b/doc/bugs/WEBDAV_443/comment_3_213815d6b827d467c60f3e8af925813b._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-03-17T21:07:50Z"
+ content="""
+Seems that I misdiagnosed this. The error message from the bad TLS library was about a had certificate, not \"user error\" (which, confusingly, does not mean what user error normally means!).
+
+Also, I see you reported this at <https://aur.archlinux.org/packages/git-annex/>, so you're using that build and not the \"git-annex-bin\" build at <https://aur.archlinux.org/packages.php?ID=63503>. The Arch Linux build that's done from source couldn't be affected by the Debian-spefific TLS bug anyway.
+
+I am reopening this bug report.
+
+Now, FailedConnectionException could be any of several things, but I noticed that someone else (perhaps cooindidentially using Arch Linux) reported the same error message here: [[Proxy_support]]. I wonder if you perhaps also have a http proxy that could be causing trouble.
+"""]]
diff --git a/doc/bugs/WEBDAV_443/comment_4_b775be4b722fc7124d9fbe2d5d01cc9f._comment b/doc/bugs/WEBDAV_443/comment_4_b775be4b722fc7124d9fbe2d5d01cc9f._comment
new file mode 100644
index 000000000..12767d961
--- /dev/null
+++ b/doc/bugs/WEBDAV_443/comment_4_b775be4b722fc7124d9fbe2d5d01cc9f._comment
@@ -0,0 +1,22 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 4"
+ date="2013-03-17T21:19:20Z"
+ content="""
+Digging into your error message a bit more, it looks like this is not a http proxy (or if it is, it's letting some connections through).
+
+git-annex is testing the box.com WebDAV server, by performing 3 actions:
+
+1. Creating the requested subdirectory on it, in your case \"git-annex\".
+2. Creating an empty file to that directory, named \"git-annex-test\"
+3. Deleting the file.
+
+Step 2 is failing. Which sort of suggests step 1 succeeded, but who knows..
+
+So, if you go look at your files on box.com, do you have a git-annex directory?
+
+Does git-annex/git-annex-test exist?
+
+Does it also fail if you use a different directory, like https://www.box.com/dav/git-annex2 ?
+"""]]
diff --git a/doc/bugs/WEBDAV_443/comment_5_c4ea745da437e56b2426d1c2c00dfcec._comment b/doc/bugs/WEBDAV_443/comment_5_c4ea745da437e56b2426d1c2c00dfcec._comment
new file mode 100644
index 000000000..e99f36524
--- /dev/null
+++ b/doc/bugs/WEBDAV_443/comment_5_c4ea745da437e56b2426d1c2c00dfcec._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="https://pradermecker.myopenid.com/"
+ ip="81.244.157.3"
+ subject="comment 5"
+ date="2013-03-17T22:03:22Z"
+ content="""
+No there is no directory created on box.com. I have actually tried with other names without success. I did even try to create the directory myself and use this one but it makes no difference.
+
+I am not sure to understand what 443 means.
+
+To be sure it is not a local config problem on my computer, I have tried to put a file to box using cadaver: cadaver works just fine (create dir, upload, delete file).
+
+After your comment, I actually rebuild the package using master. I still have the same error with WebDav but now all tests pass (git annex test)
+
+Let me know if you need me to do further investigation. Thanks.
+
+"""]]
diff --git a/doc/bugs/WEBDAV_443/comment_6_ef05c0ae88fee9c626922c6064ffdf1e._comment b/doc/bugs/WEBDAV_443/comment_6_ef05c0ae88fee9c626922c6064ffdf1e._comment
new file mode 100644
index 000000000..0d3261646
--- /dev/null
+++ b/doc/bugs/WEBDAV_443/comment_6_ef05c0ae88fee9c626922c6064ffdf1e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://pradermecker.myopenid.com/"
+ ip="81.244.157.3"
+ subject="comment 6"
+ date="2013-03-17T22:07:06Z"
+ content="""
+I have also tried with the gui and got the same error.
+"""]]
diff --git a/doc/bugs/WEBDAV_443/comment_7_eecabe8d5ed564cb540450770ca7d0b6._comment b/doc/bugs/WEBDAV_443/comment_7_eecabe8d5ed564cb540450770ca7d0b6._comment
new file mode 100644
index 000000000..d6d3241bf
--- /dev/null
+++ b/doc/bugs/WEBDAV_443/comment_7_eecabe8d5ed564cb540450770ca7d0b6._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 7"
+ date="2013-03-18T00:18:52Z"
+ content="""
+443 is the port used for https.
+"""]]
diff --git a/doc/bugs/WEBDAV_443/comment_8_7f77ba8ebd90186d3b3949ae529ba393._comment b/doc/bugs/WEBDAV_443/comment_8_7f77ba8ebd90186d3b3949ae529ba393._comment
new file mode 100644
index 000000000..68d6d5b83
--- /dev/null
+++ b/doc/bugs/WEBDAV_443/comment_8_7f77ba8ebd90186d3b3949ae529ba393._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://pradermecker.myopenid.com/"
+ ip="195.244.162.7"
+ subject="comment 8"
+ date="2013-03-18T08:33:04Z"
+ content="""
+Yes, of course, I know about 443.
+
+I was just surprised to see it in the error message (where as a code my mind was expecting a http error code).
+
+What I meant is that I don't really see how it fits in the current error message.
+"""]]
diff --git a/doc/bugs/WEBDAV_443/comment_9_87ebdc92b48d672964fb3f248c53600f._comment b/doc/bugs/WEBDAV_443/comment_9_87ebdc92b48d672964fb3f248c53600f._comment
new file mode 100644
index 000000000..eb51fe641
--- /dev/null
+++ b/doc/bugs/WEBDAV_443/comment_9_87ebdc92b48d672964fb3f248c53600f._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 9"
+ date="2013-03-18T15:04:00Z"
+ content="""
+I think what you need to do is try installing the [Linux standalone tarball](http://downloads.kitenet.net/git-annex/linux/current/) and see if it works with WebDAV. We need to rule out this being a bad build on the Arch side. The Linux standalone tarball works with box.com for me.
+
+"""]]
diff --git a/doc/bugs/WORM:_Handle_long_filenames_correctly.mdwn b/doc/bugs/WORM:_Handle_long_filenames_correctly.mdwn
new file mode 100644
index 000000000..3c9374100
--- /dev/null
+++ b/doc/bugs/WORM:_Handle_long_filenames_correctly.mdwn
@@ -0,0 +1,4 @@
+I have files with very long filenames on an xfs at home. On my laptop the annex should have been checked out on an encfs, but there filenames can't be as long as on the xfs. So perhaps it would be good to limit the keysize to a sane substring of the filename e.g. use only the first 120 characters.
+
+> Since there seems no strong argument for a WORM100, and better options
+> exist, closing. [[done]] --[[Joey]]
diff --git a/doc/bugs/WORM:_Handle_long_filenames_correctly/comment_1_77aa9cafbe20367a41377f3edccc9ddb._comment b/doc/bugs/WORM:_Handle_long_filenames_correctly/comment_1_77aa9cafbe20367a41377f3edccc9ddb._comment
new file mode 100644
index 000000000..41d3afb3e
--- /dev/null
+++ b/doc/bugs/WORM:_Handle_long_filenames_correctly/comment_1_77aa9cafbe20367a41377f3edccc9ddb._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-04-08T17:14:25Z"
+ content="""
+Seems like you probably have files in git with nearly as long filenames as the key files. Course, you can rename those yourself.
+
+This couldn't be changed directly in WORM without some ugly transition, but it would be possible to implement it as a WORM100 or so. OTOH, if you're going to git annex migrate, you might as well use SHA1.
+"""]]
diff --git a/doc/bugs/WORM:_Handle_long_filenames_correctly/comment_2_fe735d728878d889ccd34ec12b3a7dea._comment b/doc/bugs/WORM:_Handle_long_filenames_correctly/comment_2_fe735d728878d889ccd34ec12b3a7dea._comment
new file mode 100644
index 000000000..d00191f9d
--- /dev/null
+++ b/doc/bugs/WORM:_Handle_long_filenames_correctly/comment_2_fe735d728878d889ccd34ec12b3a7dea._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 2"
+ date="2011-04-08T22:02:41Z"
+ content="""
+What if your files have the same prefix and it happens to be 100 chars long? This can not be solved within WORM, but as Joey pointed out, SHA* exists.
+"""]]
diff --git a/doc/bugs/WORM:_Handle_long_filenames_correctly/comment_3_2bf0f02d27190578e8f4a32ddb195a0a._comment b/doc/bugs/WORM:_Handle_long_filenames_correctly/comment_3_2bf0f02d27190578e8f4a32ddb195a0a._comment
new file mode 100644
index 000000000..d9c291b17
--- /dev/null
+++ b/doc/bugs/WORM:_Handle_long_filenames_correctly/comment_3_2bf0f02d27190578e8f4a32ddb195a0a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 3"
+ date="2011-04-09T20:11:59Z"
+ content="""
+I wouldn't say it's completly impossible for a WORM100 to work. It would just have the contract that the pair of mtime+100chars has to be unique for each unique piece of data.
+
+But, I have yet to be convinced there's any point, since SHA1 exists.
+"""]]
diff --git a/doc/bugs/WORM:_Handle_long_filenames_correctly/comment_4_8f7ba9372463863dda5aae13205861bf._comment b/doc/bugs/WORM:_Handle_long_filenames_correctly/comment_4_8f7ba9372463863dda5aae13205861bf._comment
new file mode 100644
index 000000000..5c08cad6e
--- /dev/null
+++ b/doc/bugs/WORM:_Handle_long_filenames_correctly/comment_4_8f7ba9372463863dda5aae13205861bf._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 4"
+ date="2011-04-09T23:45:28Z"
+ content="""
+mtime+100chars can still get collisions and a _lot_ easier than even SHA1. This introduces more problems that it solves, imo.
+"""]]
diff --git a/doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults.mdwn b/doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults.mdwn
new file mode 100644
index 000000000..f3833b3b3
--- /dev/null
+++ b/doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults.mdwn
@@ -0,0 +1,31 @@
+After fixing a few things - see [[bugs/the tip at commit 6cecc26206c4a539999b04664136c6f785211a41 disables the watch command on OSX]], [[bugs/Missing dependancy in commit 6cecc26206c4a539999b04664136c6f785211a41]] and [[bugs/Fix for opening a browser on a mac (or xdg-open on linux/bsd?)]] I tried the watch command on my ~180gig annex of stuff. This might be yet again related to the issue of [[bugs/Issue on OSX with some system limits]]
+
+the watch command segfaults
+
+<pre>
+x00:annex jtang$ git annex watch --foreground -d
+watch . [2012-07-26 12:27:16 IST] read: git ["--git-dir=/Users/jtang/annex/.git","--work-tree=/Users/jtang/annex","show-ref","git-annex"]
+[2012-07-26 12:27:16 IST] read: git ["--git-dir=/Users/jtang/annex/.git","--work-tree=/Users/jtang/annex","show-ref","--hash","refs/heads/git-annex"]
+[2012-07-26 12:27:16 IST] read: git ["--git-dir=/Users/jtang/annex/.git","--work-tree=/Users/jtang/annex","log","refs/heads/git-annex..38d3f769ef004b96b6d640cfb59a45f7b4edf5f6","--oneline","-n1"]
+[2012-07-26 12:27:16 IST] read: git ["--git-dir=/Users/jtang/annex/.git","--work-tree=/Users/jtang/annex","log","refs/heads/git-annex..ebabe9c92516c350a30126037173080648f5930b","--oneline","-n1"]
+[2012-07-26 12:27:16 IST] read: git ["--git-dir=/Users/jtang/annex/.git","--work-tree=/Users/jtang/annex","log","refs/heads/git-annex..d36d8d88847decc2320f0be22892ad94a8abe594","--oneline","-n1"]
+[2012-07-26 12:27:16 IST] read: git ["--git-dir=/Users/jtang/annex/.git","--work-tree=/Users/jtang/annex","log","refs/heads/git-annex..aaa62a8191b3c964fdf546077049f626e8561b22","--oneline","-n1"]
+[2012-07-26 12:27:16 IST] chat: git ["--git-dir=/Users/jtang/annex/.git","--work-tree=/Users/jtang/annex","cat-file","--batch"]
+(scanning...) error: git-annex died of signal 11
+</pre>
+
+The above was done on the usual OSX 10.7 system that I have.
+
+---
+
+I'll try and bisect it and find out where the problem first appeared, does the tests currently test the watch command? (also my comments seem to get moderated whether i use my openid account with google or with the native ikiwiki account, so some comments might be hidden)
+
+> The test suite does not currently test the watch command, unfortunatly.
+>
+> Wow, I had not noticed the 30 pending moderated comments.. Let them all
+> thru, and I guess I'll turn off comment spam filtering for now, since
+> there has apparently been none. --[[Joey]]
+
+---
+
+> Seems this segfault is fixed. [[done]] --[[Joey]]
diff --git a/doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_10_6c872dff4fcc63c16bf69d1e96891c89._comment b/doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_10_6c872dff4fcc63c16bf69d1e96891c89._comment
new file mode 100644
index 000000000..952ffadc4
--- /dev/null
+++ b/doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_10_6c872dff4fcc63c16bf69d1e96891c89._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="jtang"
+ ip="79.97.135.214"
+ subject="comment 10"
+ date="2012-07-29T10:49:05Z"
+ content="""
+This is looking good, no more segfaulting.
+"""]]
diff --git a/doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_1_5cad24007f819e4be193123dab0d511a._comment b/doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_1_5cad24007f819e4be193123dab0d511a._comment
new file mode 100644
index 000000000..23a4165a4
--- /dev/null
+++ b/doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_1_5cad24007f819e4be193123dab0d511a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.2.189"
+ subject="not good.."
+ date="2012-07-26T17:09:16Z"
+ content="""
+Do you see the segfault in a repo with fewer files?
+
+
+"""]]
diff --git a/doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_2_d449bf656a59d424833f9ab5a7fb4e82._comment b/doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_2_d449bf656a59d424833f9ab5a7fb4e82._comment
new file mode 100644
index 000000000..04b7ed1ae
--- /dev/null
+++ b/doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_2_d449bf656a59d424833f9ab5a7fb4e82._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.2.189"
+ subject="comment 2"
+ date="2012-07-26T17:09:59Z"
+ content="""
+Also, you might try bisecting to find whatever commit it first started segfaulting on.
+"""]]
diff --git a/doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_3_ffb1ce41477ad60840abd7a89a133067._comment b/doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_3_ffb1ce41477ad60840abd7a89a133067._comment
new file mode 100644
index 000000000..42f59d1bc
--- /dev/null
+++ b/doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_3_ffb1ce41477ad60840abd7a89a133067._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="jtang"
+ ip="79.97.135.214"
+ subject="comment 3"
+ date="2012-07-26T17:11:55Z"
+ content="""
+It fails on repos with either no files or smaller repos.
+"""]]
diff --git a/doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_4_cebbc138c6861c086bb7937b54f5adbc._comment b/doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_4_cebbc138c6861c086bb7937b54f5adbc._comment
new file mode 100644
index 000000000..71e810291
--- /dev/null
+++ b/doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_4_cebbc138c6861c086bb7937b54f5adbc._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="jtang"
+ ip="79.97.135.214"
+ subject="comment 4"
+ date="2012-07-26T17:50:42Z"
+ content="""
+It just occurred to me that bisecting won't help much, as the watch command was disabled accidentally in earlier commits and doing a script for bisecting is going to be as much work as just stepping through and debugging the issue with a debugger (i might need to fire up gdb on a mac (this wont be fun))
+"""]]
diff --git a/doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_5_5e27737a5bb0e9e46c98708700318e67._comment b/doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_5_5e27737a5bb0e9e46c98708700318e67._comment
new file mode 100644
index 000000000..8f781ed97
--- /dev/null
+++ b/doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_5_5e27737a5bb0e9e46c98708700318e67._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 5"
+ date="2012-07-27T12:20:07Z"
+ content="""
+After some debugging, I looked at the Utility/libkqueue.c and used it as a test, it seems to be hanging/segfaulting around the call to that library. Annoyingly I get segfaults from the library every so often on OSX, it's pretty a random event.
+"""]]
diff --git a/doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_6_1f92da712232d050e085a4f39063d7a6._comment b/doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_6_1f92da712232d050e085a4f39063d7a6._comment
new file mode 100644
index 000000000..2aa866410
--- /dev/null
+++ b/doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_6_1f92da712232d050e085a4f39063d7a6._comment
@@ -0,0 +1,21 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.2.20"
+ subject="comment 6"
+ date="2012-07-27T16:34:45Z"
+ content="""
+Are you seeing libkqueue crash when it's called from a debugger or C program, rather than from Haskell?
+
+Are you building for 32 or 64 bit? You might try getting the 32 bit version of GCC (or The Haskell Platform) and see if it does better. There is a known GCC crashes on 64 bit OSX involving C libraries,
+although this bug report doesn't seem to apply, since we're not using ghci <http://hackage.haskell.org/trac/ghc/ticket/7040>.
+
+Are you building with cabal, or using the Makefile?
+
+You might try reverting git commit da4c506d61115236f3e43dd0bd17f30cd54df950
+
+You might try disabling the -threaded option in the cabal file or Makefile.
+
+I ssh'd to the OSX box I have an account on, and confirmed that git-annex watch still works there as of the current head of the `assistant` branch. That's a 64 bit GHC system, FWIW.
+
+Do you see the crash when building from the `master` branch, or only `assistant`? Master has the watch command, but it's much out of date, so this will tell if the problem was introduced recently... and you might still have to bisect it since I can't reproduce it. :(
+"""]]
diff --git a/doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_7_4153dc8029c545f8e86584a38bd536fb._comment b/doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_7_4153dc8029c545f8e86584a38bd536fb._comment
new file mode 100644
index 000000000..ccb4593ec
--- /dev/null
+++ b/doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_7_4153dc8029c545f8e86584a38bd536fb._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 7"
+ date="2012-07-27T17:23:24Z"
+ content="""
+I'm using make and a 64bit version of haskell-platform, it's fine on the master branch. It's just crashing on the assistant branch, I'm just thinking out loud, but could I share the binaries that I have with you (I'd like to grab your binaries too) to see see if its just some silly problem with my build environment.
+
+I'm seeing the crash when I'm running git-annex (in haskell), when I run libkqueue in a debugger it behaves randomly, is mostly succeeds, but every so often it fails. A back trace reveals nothing so I am a bit at a loss.
+
+I've tried disabling the threaded option, but it still crashes, I will give it another try later when I get home. The problem seems to occur on my desktop mac in work and my home mac, however it is fine on my linux machines.
+
+Could I ask which version of OSX do you have access to? is it 10.6 or 10.7 ?
+
+"""]]
diff --git a/doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_8_f85b6eb5bfd28ffc6973fb4ab0fe4337._comment b/doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_8_f85b6eb5bfd28ffc6973fb4ab0fe4337._comment
new file mode 100644
index 000000000..cbbd2933c
--- /dev/null
+++ b/doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_8_f85b6eb5bfd28ffc6973fb4ab0fe4337._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.2.20"
+ subject="comment 8"
+ date="2012-07-27T18:10:06Z"
+ content="""
+I've reproduced a crash on OSX, involving not kqueue, but the WebApp's use of getaddrinfo. I've fixed that, but several things you've said in this bug report don't 100% add up to this being the same crash you've been seeing (for one thing, this can't affect `git annex watch`), so I'll wait for you to confirm.
+"""]]
diff --git a/doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_9_c747c488461c98cd285b51d3afc2c3eb._comment b/doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_9_c747c488461c98cd285b51d3afc2c3eb._comment
new file mode 100644
index 000000000..b23ae0125
--- /dev/null
+++ b/doc/bugs/Watch_command_as_of_commit_6cecc26206c4a539999b04664136c6f785211a41_segfaults/comment_9_c747c488461c98cd285b51d3afc2c3eb._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="jtang"
+ ip="79.97.135.214"
+ subject="comment 9"
+ date="2012-07-27T18:17:45Z"
+ content="""
+Ah, it's alive, I'm testing on my home machine right now and it's functioning as expected. I've tested on my work machine as well and the watch command works as expected! (short of the existing system limits which fails for my bigger annexes).
+
+Apologies for sending you on the wrong path with the kqueue path. I reckon if I give this a good testing over the weekend is a good idea before closing this bug, I will report back in a few days on this after giving a thrashing of files!
+"""]]
diff --git a/doc/bugs/Watcher_crashed:_addWatch:_does_not_exist.mdwn b/doc/bugs/Watcher_crashed:_addWatch:_does_not_exist.mdwn
new file mode 100644
index 000000000..f798fe2ea
--- /dev/null
+++ b/doc/bugs/Watcher_crashed:_addWatch:_does_not_exist.mdwn
@@ -0,0 +1,25 @@
+### Please describe the problem.
+
+When starting an git annex webapp in my documents repository, i get the error message, that the watcher thread has died. The error message seems to be arising from the fact, that a watcher thread for an empty string should be started, which does not work.
+
+### What steps will reproduce the problem?
+
+I've no idea, how to reproduce this in another repostory.
+
+### What version of git-annex are you using? On what operating system?
+
+ii git-annex 4.20130709 i386 manage files with git, without checking their contents into git
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+Watcher crashed: addWatch: does not exist (No such file or directory)
+[2013-07-14 10:30:35 CEST] Watcher: warning Watcher crashed: addWatch: does not exist (No such file or directory)
+
+# End of transcript or log.
+"""]]
+
+> [[done]]; see my comment --[[Joey]]
diff --git a/doc/bugs/Watcher_crashed:_addWatch:_does_not_exist/comment_1_24f511a8103727894c6e96798a559870._comment b/doc/bugs/Watcher_crashed:_addWatch:_does_not_exist/comment_1_24f511a8103727894c6e96798a559870._comment
new file mode 100644
index 000000000..54808de57
--- /dev/null
+++ b/doc/bugs/Watcher_crashed:_addWatch:_does_not_exist/comment_1_24f511a8103727894c6e96798a559870._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.90"
+ subject="comment 1"
+ date="2013-07-17T19:33:43Z"
+ content="""
+Are you seeing this every time you start the webapp? Because I see a way it could crash, but only if, for example, a directory gets moved or deleted right when it's starting up. That would look just like the crash you've reported, but would seem to be an unusual case that would be unlikely to happen repeatedly.
+
+I've put in a fix for that crash.
+"""]]
diff --git a/doc/bugs/Watcher_crashed:_addWatch:_does_not_exist/comment_2_e14eddbc09cadbf1e4dbbb0c07e0e5b0._comment b/doc/bugs/Watcher_crashed:_addWatch:_does_not_exist/comment_2_e14eddbc09cadbf1e4dbbb0c07e0e5b0._comment
new file mode 100644
index 000000000..9f3dd80f5
--- /dev/null
+++ b/doc/bugs/Watcher_crashed:_addWatch:_does_not_exist/comment_2_e14eddbc09cadbf1e4dbbb0c07e0e5b0._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkptNW1PzrVjYlJWP_9e499uH0mjnBV6GQ"
+ nickname="Christian"
+ subject="comment 2"
+ date="2013-07-19T06:14:05Z"
+ content="""
+I see the problem always i start the assistant. Even when i don't touch the repository otherwise. But there is a funny observation: I have multiple seperate repositories: there are two old ones, that were created some months ago (upper bound: one year). Those two (seperate) repositories show the addWatch problem (on multiple machines). A newly created repository does not show the problem.
+
+So i suspect that those old repositories behave in some direction differently. Is this possible? I could also give you a clone of one repository.
+"""]]
diff --git a/doc/bugs/Watcher_crashed:_addWatch:_does_not_exist/comment_3_513fae4d379008f954a307be8df34976._comment b/doc/bugs/Watcher_crashed:_addWatch:_does_not_exist/comment_3_513fae4d379008f954a307be8df34976._comment
new file mode 100644
index 000000000..a85470f68
--- /dev/null
+++ b/doc/bugs/Watcher_crashed:_addWatch:_does_not_exist/comment_3_513fae4d379008f954a307be8df34976._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkptNW1PzrVjYlJWP_9e499uH0mjnBV6GQ"
+ nickname="Christian"
+ subject="comment 3"
+ date="2013-07-19T06:57:39Z"
+ content="""
+Oh, I think i found a problem with the inotify_add_watch. I checked the strace and:
+
+ [pid 19346] inotify_add_watch(63, \"./Perry Rhodan - Atlan\", IN_CLOSE_WRITE|IN_MOVED_FROM|IN_MOVED_TO|IN_CREATE|IN_DELETE) = 137
+ [pid 19346] inotify_add_watch(63, \"./Perry Rhodan - Atlan/Atlan Blaue- Silberbnde\", IN_CLOSE_WRITE|IN_MOVED_FROM|IN_MOVED_TO|IN_CREATE|IN_DELETE) = -1 ENOENT (No such file or directory)
+
+The problem is that there seems to be an encoding problem. There should be a german Umlaut in Silberb[ae]nde. The directory name is not valid encoded.
+"""]]
diff --git a/doc/bugs/Watcher_crashed:_addWatch:_does_not_exist/comment_4_172eaeb3bb8b502379695aba35f96120._comment b/doc/bugs/Watcher_crashed:_addWatch:_does_not_exist/comment_4_172eaeb3bb8b502379695aba35f96120._comment
new file mode 100644
index 000000000..84a84dfb8
--- /dev/null
+++ b/doc/bugs/Watcher_crashed:_addWatch:_does_not_exist/comment_4_172eaeb3bb8b502379695aba35f96120._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkptNW1PzrVjYlJWP_9e499uH0mjnBV6GQ"
+ nickname="Christian"
+ subject="comment 4"
+ date="2013-07-19T19:00:23Z"
+ content="""
+So it is probably not only an assumption. After fixing the filenames with a script from
+
+http://askubuntu.com/questions/113188/character-encoding-problem-with-filenames-find-broken-filenames
+
+The watcher thread did survive, and the assistant is syncing just fine.
+"""]]
diff --git a/doc/bugs/Watcher_crashed:_addWatch:_does_not_exist/comment_5_8adb9de82cc8581422734acc66dd094c._comment b/doc/bugs/Watcher_crashed:_addWatch:_does_not_exist/comment_5_8adb9de82cc8581422734acc66dd094c._comment
new file mode 100644
index 000000000..cb95ab913
--- /dev/null
+++ b/doc/bugs/Watcher_crashed:_addWatch:_does_not_exist/comment_5_8adb9de82cc8581422734acc66dd094c._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.140"
+ subject="comment 5"
+ date="2013-07-20T17:39:48Z"
+ content="""
+Ok, I was able to reproduce this problem, although only when using LANG=C.
+
+With a utf8 locale, it doesn't mind the Umlaut, and even works on directories containing invalid unicode characters
+(0xd801 and 0xffff)
+"""]]
diff --git a/doc/bugs/Watcher_crashed:_addWatch:_does_not_exist/comment_6_02f0beef1188bfa336bf4220eb5c6286._comment b/doc/bugs/Watcher_crashed:_addWatch:_does_not_exist/comment_6_02f0beef1188bfa336bf4220eb5c6286._comment
new file mode 100644
index 000000000..a21352693
--- /dev/null
+++ b/doc/bugs/Watcher_crashed:_addWatch:_does_not_exist/comment_6_02f0beef1188bfa336bf4220eb5c6286._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.140"
+ subject="comment 6"
+ date="2013-07-20T22:31:02Z"
+ content="""
+Isolated the bug to a problem with the upstream inotify library.
+<https://github.com/kolmodin/hinotify/issues/5> I've sent in a patch to that library that fixes the problem.
+
+Unfortunately, I cannot work around it in git-annex more than I already have. It'll no longer crash, but will skip over files or directories that contain characters not valid in the current locale.
+
+I have applied my patch to the haskell-hinotify package in Debian unstable, and have deployed fixed versions to all my linux autobuilds, including Android. (An Android user had mentioned also seeing this bug.)
+"""]]
diff --git a/doc/bugs/Watcher_crashed_in_Android_on___47__storage__47__sdcard1_-_bug__63__.mdwn b/doc/bugs/Watcher_crashed_in_Android_on___47__storage__47__sdcard1_-_bug__63__.mdwn
new file mode 100644
index 000000000..d8b70a66a
--- /dev/null
+++ b/doc/bugs/Watcher_crashed_in_Android_on___47__storage__47__sdcard1_-_bug__63__.mdwn
@@ -0,0 +1,43 @@
+### Please describe the problem.
+
+In webapp UI, added on first install, the location for repository: /storage/sdcard1
+
+!warning
+
+Watcher crashed: addWatch:
+
+permission denied (Permission denied)
+
+[Restart Thread]
+
+:Performing startup scan
+
+In terminal Window 1:
+
+nex webapp <
+
+Detected a crippled filesystem.
+
+Enabling direct mode.
+
+Detected a filesystem without fifo support.
+
+Disabling ssh connection caching.
+
+### What steps will reproduce the problem?
+
+In webapp UI, added on first install, the location for repository: /storage/sdcard1
+
+### What version of git-annex are you using? On what operating system?
+
+Android 4.1.1 Huawei Y300 Annex.apk v1.0.52 version 4.20130723
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
diff --git a/doc/bugs/Watcher_crashed_in_Android_on___47__storage__47__sdcard1_-_bug__63__/comment_1_71b052be40fbdaca09ca3ede8c59ac7a._comment b/doc/bugs/Watcher_crashed_in_Android_on___47__storage__47__sdcard1_-_bug__63__/comment_1_71b052be40fbdaca09ca3ede8c59ac7a._comment
new file mode 100644
index 000000000..0622a2439
--- /dev/null
+++ b/doc/bugs/Watcher_crashed_in_Android_on___47__storage__47__sdcard1_-_bug__63__/comment_1_71b052be40fbdaca09ca3ede8c59ac7a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.21"
+ subject="comment 1"
+ date="2013-07-30T18:42:32Z"
+ content="""
+You should have a `/storage/sdcard1/.git/annex/daemon.log` file. Please paste it here.
+"""]]
diff --git a/doc/bugs/Watcher_crashed_in_Android_on___47__storage__47__sdcard1_-_bug__63__/comment_3_0f7cc02e0193c969c9b6ceb27e71af8a._comment b/doc/bugs/Watcher_crashed_in_Android_on___47__storage__47__sdcard1_-_bug__63__/comment_3_0f7cc02e0193c969c9b6ceb27e71af8a._comment
new file mode 100644
index 000000000..0ea47dc40
--- /dev/null
+++ b/doc/bugs/Watcher_crashed_in_Android_on___47__storage__47__sdcard1_-_bug__63__/comment_3_0f7cc02e0193c969c9b6ceb27e71af8a._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnaH44G3QbxBAYyDwy0PbvL0ls60XoaR3Y"
+ nickname="Nigel"
+ subject="/storage/sdcard1/.git/annex/daemon.log"
+ date="2013-07-30T23:11:29Z"
+ content="""
+ [2013-07-30 23:17:43 BST] main: starting assistant version 4.20130723-ged05a63
+ (scanning...) [2013-07-30 23:17:44 BST] Watcher: Performing startup scan
+ Watcher crashed: addWatch: permission denied (Permission denied)
+ [2013-07-30 23:17:45 BST] Watcher: warning Watcher crashed: addWatch: permission denied (Permission denied)
+ [2013-07-30 23:17:45 BST] Committer: Adding 229286 229381
+ add LOST.DIR/229286 (checksum...) ok
+ add LOST.DIR/229381 (checksum...) [2013-07-30 23:17:47 BST] Committer: Committing changes to git
+ [2013-07-30 23:20:22 BST] Committer: Adding git-annex..stall.log
+ ok
+ (Recording state in git...)
+ (Recording state in git...)
+ add git-annex-install.log (checksum...) ok
+ add git-annex-install.log (checksum...) [2013-07-30 23:20:22 BST] Committer: Committing changes to git
+"""]]
diff --git a/doc/bugs/Watcher_crashed_in_Android_on___47__storage__47__sdcard1_-_bug__63__/comment_3_1a7542249b9c37507126e97441057c12._comment b/doc/bugs/Watcher_crashed_in_Android_on___47__storage__47__sdcard1_-_bug__63__/comment_3_1a7542249b9c37507126e97441057c12._comment
new file mode 100644
index 000000000..9bc0c90e6
--- /dev/null
+++ b/doc/bugs/Watcher_crashed_in_Android_on___47__storage__47__sdcard1_-_bug__63__/comment_3_1a7542249b9c37507126e97441057c12._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.246"
+ subject="comment 3"
+ date="2013-11-10T18:18:09Z"
+ content="""
+Seems to me this was probably fixed in [[!commit 6b37fcffd872b62fb78047a77e4cee5ab0bb57f1]].
+
+However, I don't know why permission problems would happen on Android, which typically uses a filesystem that does not have restricted permissions for the sdcard.
+
+If you upgrade, you should be able to see if it fixed the crash, and it will also mention any file or directory that it's unable to read in the log.
+"""]]
diff --git a/doc/bugs/WebDAV_HandshakeFailed_.mdwn b/doc/bugs/WebDAV_HandshakeFailed_.mdwn
new file mode 100644
index 000000000..69be0c4b5
--- /dev/null
+++ b/doc/bugs/WebDAV_HandshakeFailed_.mdwn
@@ -0,0 +1,7 @@
+When I attempt to add a Box.com special remote to my annex I get the following error:
+
+ git-annex: HandshakeFailed (Error_Protocol ("certificate rejected: certificate is not allowed to sign another certificate",True,CertificateUnknown))
+
+Running git-annex version: 3.20130207
+
+> Got that bug fixed in Debian and all builds updated. [[done]] --[[Joey]]
diff --git a/doc/bugs/WebDAV_HandshakeFailed_/comment_1_40499110ea43bc99ad9dd9f642da434c._comment b/doc/bugs/WebDAV_HandshakeFailed_/comment_1_40499110ea43bc99ad9dd9f642da434c._comment
new file mode 100644
index 000000000..9bcc489ee
--- /dev/null
+++ b/doc/bugs/WebDAV_HandshakeFailed_/comment_1_40499110ea43bc99ad9dd9f642da434c._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlqOu7P4tb4D-Xo2pYrjln2NsAObtErliM"
+ nickname="Alexander"
+ subject="Same problem"
+ date="2013-02-24T16:51:52Z"
+ content="""
+Hello,
+
+same problem with box.com and german telekom (https://webdav.mediencenter.t-online.de).
+I'm using git-annex (3.20130216) from debian/unstable on amd64.
+git annex --debug is not helpful I think. Any other trace I can help with?
+
+Regards,
+Alexander
+"""]]
diff --git a/doc/bugs/WebDAV_HandshakeFailed_/comment_2_506712e8cc5b47b9bd69edf67ae54da7._comment b/doc/bugs/WebDAV_HandshakeFailed_/comment_2_506712e8cc5b47b9bd69edf67ae54da7._comment
new file mode 100644
index 000000000..53642bce4
--- /dev/null
+++ b/doc/bugs/WebDAV_HandshakeFailed_/comment_2_506712e8cc5b47b9bd69edf67ae54da7._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.210"
+ subject="comment 2"
+ date="2013-02-24T19:09:14Z"
+ content="""
+This is a reversion in version haskell-tls-extra-0.4.6.1.
+
+Opened a bug about this: <https://github.com/vincenthz/hs-tls/issues/32>
+"""]]
diff --git a/doc/bugs/WebDAV_HandshakeFailed_/comment_3_5641481d9e9ed2b711b1516f1abc5c30._comment b/doc/bugs/WebDAV_HandshakeFailed_/comment_3_5641481d9e9ed2b711b1516f1abc5c30._comment
new file mode 100644
index 000000000..02bb0db11
--- /dev/null
+++ b/doc/bugs/WebDAV_HandshakeFailed_/comment_3_5641481d9e9ed2b711b1516f1abc5c30._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="annexuser"
+ ip="50.125.41.24"
+ subject="comment 3"
+ date="2013-03-15T18:45:49Z"
+ content="""
+The [day 210 update](http://git-annex.branchable.com/design/assistant/blog/day_210__spring/) said that WebDAV should be working in the next release. I just tried it in 4.20130314 (standalone) and get the same `HandshakeFailed` failed error.
+"""]]
diff --git a/doc/bugs/WebDAV_HandshakeFailed_/comment_4_1d609de93fa66ce9dc802e67b5922243._comment b/doc/bugs/WebDAV_HandshakeFailed_/comment_4_1d609de93fa66ce9dc802e67b5922243._comment
new file mode 100644
index 000000000..5b91e1d5e
--- /dev/null
+++ b/doc/bugs/WebDAV_HandshakeFailed_/comment_4_1d609de93fa66ce9dc802e67b5922243._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="which build?"
+ date="2013-03-15T21:47:34Z"
+ content="""
+Can you be more specific which build you are using?
+"""]]
diff --git a/doc/bugs/WebDAV_HandshakeFailed_/comment_5_62761882d30c1b02930c938cb8e30ed4._comment b/doc/bugs/WebDAV_HandshakeFailed_/comment_5_62761882d30c1b02930c938cb8e30ed4._comment
new file mode 100644
index 000000000..dbb1a7e80
--- /dev/null
+++ b/doc/bugs/WebDAV_HandshakeFailed_/comment_5_62761882d30c1b02930c938cb8e30ed4._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="annexuser"
+ ip="50.125.41.24"
+ subject="comment 5"
+ date="2013-03-15T22:23:44Z"
+ content="""
+ git-annex version: 4.20130314
+
+Linux i386 standalone build on Arch 64-bit.
+"""]]
diff --git a/doc/bugs/WebDAV_HandshakeFailed_/comment_6_acda8fae848ec486ce2a0b3dff3bd0a5._comment b/doc/bugs/WebDAV_HandshakeFailed_/comment_6_acda8fae848ec486ce2a0b3dff3bd0a5._comment
new file mode 100644
index 000000000..85678f1ac
--- /dev/null
+++ b/doc/bugs/WebDAV_HandshakeFailed_/comment_6_acda8fae848ec486ce2a0b3dff3bd0a5._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 6"
+ date="2013-03-15T23:49:27Z"
+ content="""
+Indeed, I forgot to upgrade that one. Did so and have replaced the autobuild.
+"""]]
diff --git a/doc/bugs/WebDAV_HandshakeFailed_/comment_7_6c51b6c7dd477d8911dd9a7a5c41ea2e._comment b/doc/bugs/WebDAV_HandshakeFailed_/comment_7_6c51b6c7dd477d8911dd9a7a5c41ea2e._comment
new file mode 100644
index 000000000..9a7036ff0
--- /dev/null
+++ b/doc/bugs/WebDAV_HandshakeFailed_/comment_7_6c51b6c7dd477d8911dd9a7a5c41ea2e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="annexuser"
+ ip="50.46.189.77"
+ subject="comment 7"
+ date="2013-03-17T01:29:48Z"
+ content="""
+It's working now! Thanks!
+"""]]
diff --git a/doc/bugs/WebDAV_HandshakeFailed_/comment_8_e834f791d3000669fab25732a7c72ab3._comment b/doc/bugs/WebDAV_HandshakeFailed_/comment_8_e834f791d3000669fab25732a7c72ab3._comment
new file mode 100644
index 000000000..8858c8c49
--- /dev/null
+++ b/doc/bugs/WebDAV_HandshakeFailed_/comment_8_e834f791d3000669fab25732a7c72ab3._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlqOu7P4tb4D-Xo2pYrjln2NsAObtErliM"
+ nickname="Alexander"
+ subject="box.com fixed"
+ date="2013-03-29T15:15:31Z"
+ content="""
+yes, box.com is now working. thanks.
+
+german telekom still doesn't work though, due to the lock/unlock issue; see http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=698379
+
+best regards,
+alexander
+"""]]
diff --git a/doc/bugs/Webapp_fails_to_resolve_ipv6_hostname.mdwn b/doc/bugs/Webapp_fails_to_resolve_ipv6_hostname.mdwn
new file mode 100644
index 000000000..da9bb4627
--- /dev/null
+++ b/doc/bugs/Webapp_fails_to_resolve_ipv6_hostname.mdwn
@@ -0,0 +1,15 @@
+What steps will reproduce the problem?
+
+From the webapp, go to Configuration > Manage repositories > Remote server. Enter a hostname that only has an IPv6 hostname (e.g. ipv6.google.com). Click Check this server.
+
+What is the expected output? What do you see instead?
+
+Expect the application to attempt to check the server via SSH. Instead, it results in error "cannot resolve host name".
+
+What version of git-annex are you using? On what operating system?
+
+git-annex 3.20120924 on Debian testing (amd64).
+
+Please provide any additional information below.
+
+> Thanks, [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/Weird_behaviour_of_direct_and_indirect_annexes.mdwn b/doc/bugs/Weird_behaviour_of_direct_and_indirect_annexes.mdwn
new file mode 100644
index 000000000..b3b0eea64
--- /dev/null
+++ b/doc/bugs/Weird_behaviour_of_direct_and_indirect_annexes.mdwn
@@ -0,0 +1,57 @@
+## What steps will reproduce the problem?
+
+ ~$ git annex webapp
+
+
+* Add Another Local Repository (~/Direct) "Direct", keep separate (from existing repo) no repo type
+* Add Repository, ~/Indirect "Indirect", combine (with Direct) , repo type client
+* Syncing enabled on both
+
+Then
+
+ ~/Indirect$ git annex indirect
+ commit ok
+ indirect ok
+ ok
+ ~/Indirect$ touch ../Direct/Test.File
+
+
+## What is the expected output? What do you see instead?
+
+That ~/Indirect/Test.File be a symlink into .git/annex/objects/.......
+
+Instead, it is not a symlink. However, doing
+
+ ~/Indirect$ git annex direct
+ ~/Indirect$ git annex indirect
+
+results in what I would expect (until the content of Direct/Test.File is changed, when it ceases to be a symlink in ~/Indirect once more)
+
+
+
+## What version of git-annex are you using? On what operating system?
+git-annex version: 4.20130405
+
+Ubuntu 12.10
+
+
+## Please provide any additional information below.
+
+Reading [[direct_mode]], I thought that I could have two repos on my computer, one direct, and one indirect, and if running the assistant, that I could gain the security of retaining old versions, as well as the convenience of direct mode. (I think I understand that correctly; if a direct-mode file only exists in one repository, and is edited, the old version is lost, but if it is in multiple repos, then the old versions will be retained).
+
+It seems to me that if I do
+
+ ~/Direct$ echo Content > Test.File
+ ~/Direct$ echo More Content > Test.File
+ ~/Direct$ echo Even More Content > Test.File
+
+that all three copies are stored in ~/Indirect, so the functionality I'm after seems to work. However, ~/Indirect/Test.File ends up not being a symlink, which I think is odd/unexpected.
+
+
+**Edit: Doing a git annex sync in ~/Indirect results in the continuing behaviour to be correct, so there's some issue telling Direct that Indirect is no longer in direct-mode?**
+This appears to fix it, but I guess shouldn't be necessary.
+
+> AFAICS, the entire problem is that the assistant does not notice when the
+> repository it's running in is changed from direct to indirect mode. Since this
+> has also been reported to cause problems with the assistant, I have added
+> a check to prevent it from being done. [[done]] --[[Joey]]
diff --git a/doc/bugs/Weird_behaviour_of_direct_and_indirect_annexes/comment_1_56474a69c2f174d83be9137d3c045a47._comment b/doc/bugs/Weird_behaviour_of_direct_and_indirect_annexes/comment_1_56474a69c2f174d83be9137d3c045a47._comment
new file mode 100644
index 000000000..d2a261b83
--- /dev/null
+++ b/doc/bugs/Weird_behaviour_of_direct_and_indirect_annexes/comment_1_56474a69c2f174d83be9137d3c045a47._comment
@@ -0,0 +1,33 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnSenxKyE_2Z6Wb-EBMO8FciyRywjx1ZiQ"
+ nickname="Walter"
+ subject="Commands to accomplish same"
+ date="2013-04-13T04:43:41Z"
+ content="""
+I feel that the following commands should do essentially the same (ie they do what I intend to do).
+More, they even display the correct (expected) behaviour, it seems the strangeness is introduced by the webapp (which, by the way, is really cool).
+
+ cd ~
+ mkdir Direct Indirect
+ git init Direct/
+ git init Indirect/
+ cd Direct/
+ git annex init Direct
+ git annex direct
+ cd ../Indirect
+ git annex init Indirect
+ git annex indirect
+ touch Indirect
+ git annex add Indirect
+ git commit -m 'Initial commit'
+ git remote add Direct ..//Direct/
+ git annex assistant
+ cd ../Direct/
+ touch Direct
+ git annex add Direct
+ git commit -m 'Initial commit'
+ git remote add Indirect ../Indirect
+ git annex assistant
+ touch Test
+ echo Test > Test
+"""]]
diff --git a/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace.mdwn b/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace.mdwn
new file mode 100644
index 000000000..d345cf4da
--- /dev/null
+++ b/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace.mdwn
@@ -0,0 +1,49 @@
+What steps will reproduce the problem?
+Created a repository (working directory), then an another one on the same computer,
+in a different folder for backup repository.
+
+The initial folder, what I imported, contained:
+741MB, 23381 files, most of the files are 30-150kB in sizes.
+
+After 18 hours of continous work
+(I started 28 hours ago, but the laptop died one time,
+and I needed to restart git-annex 4 times in total, and the laptop overheated once):
+The initial directory (/home/user/down) contains at this point (still not finished):
+8.1GB
+
+The target directory(/mnt/dat/annex2) contains:
+975MB
+
+
+What is the expected output? What do you see instead?
+I expect maximum three times the usefull data size. So I can calculate with (rule of thumb).
+(Ie. if I want to put 1GB data into annex, it would need maximum (at any point of time 3GB of data)
+
+Currently it uses 11x(!) times the original size, and still growing.
+
+I also expect to stop syncing, when it used up all the available disk space
+(ie. it should leave at least 200MB on the original partition,
+none of the other programs like to have 0 bytes left).
+The machine just freeze, ie. takes almost 10 minutes to kill process,
+and delete something to get back to life again.
+
+Also some kind of feedback how many files has been synchronized,
+because currently the dashboard does not indicate any useful info.
+Also the log page seems only growing, making firefox crashes.
+
+Self-controlled resource hogging. Ie. dont use more then 50% processor,
+or dont make heavy disk usage for 3-4 hours, because the laptop can overheat.
+
+What version of git-annex are you using? On what operating system?
+https://downloads.kitenet.net/git-annex/linux/current/git-annex-standalone-i386.tar.gz
+Version: 4.20130227
+Ubuntu 10.04, laptop Toshiba L300, Intel Core2Duo T5800@2.0Ghz, 3GB ram
+
+Please provide any additional information below.
+The syncing is still not finished.
+I hope it will finish within additional 24hours.
+
+Best,
+ Laszlo
+
+> [[done]] per comments
diff --git a/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_0._comment b/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_0._comment
new file mode 100644
index 000000000..87bec8530
--- /dev/null
+++ b/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_0._comment
@@ -0,0 +1,34 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="Tried to add a bug, but website fails"
+ date="2013-03-01T14:40:18Z"
+ content="""
+@joeyh: I tried to add a comment to my bugreport:
+http://git-annex.branchable.com/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace.Makefile/
+
+I get this error:
+Error: failed to create directory /home/b-git-annex/source/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace.Makefile/: File exists
+
+The comment I tried to add:
+Seems like the logging is the culprit:
+
+user@usermachine:~/down/annex$ du -ak . | sort -nr | cut -f2 | xargs -d '\n' du -sh |head -n 30 -
+8,2G .
+7,5G ./.git
+6,5G ./.git/annex
+2,7G ./.git/annex/daemon.log
+1,8G ./.git/annex/daemon.log.1
+1,5G ./.git/annex/daemon.log.5
+980M ./.git/objects
+742M ./mydir
+640M ./mydir/wp
+616M ./mydir/wp/wd
+314M ./mydir/wp/wd/2012
+278M ./.git/annex/daemon.log.4
+226M ./mydir/wp/wd/2011
+154M ./.git/annex/daemon.log.6
+109M ./.git/annex/objects
+
+
+"""]]
diff --git a/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_10_037a6dd6e15ef5f789a1f364f7507b53._comment b/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_10_037a6dd6e15ef5f789a1f364f7507b53._comment
new file mode 100644
index 000000000..f973238d8
--- /dev/null
+++ b/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_10_037a6dd6e15ef5f789a1f364f7507b53._comment
@@ -0,0 +1,45 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="comment 10"
+ date="2013-03-03T18:31:24Z"
+ content="""
+The problem with restarting, that it seems, it puts everything one more time into .git.
+(if we ignore the logging problem).
+
+Right now, here is the:
+ $ du -ak . | sort -nr | cut -f2 | xargs -d '\n' du -sh |head -n 30 -
+output:
+ 8,7G .
+ 8,0G ./.git
+ 6,3G ./.git/annex
+ 3,5G ./.git/annex/daemon.log.2
+ 2,5G ./.git/annex/daemon.log
+ 1,7G ./.git/objects
+ 742M ./mydir
+ 640M ./mydir/wp
+ 616M ./mydir/wp/wd
+ 314M ./mydir/wp/wd/2012
+ 226M ./mydir/wp/wd/2011
+ 227M ./.git/annex/daemon.log.1
+ 109M ./.git/annex/objects
+
+If you observe ./.git/objects dir, is 1,7G,
+while yesterday it was 742M (see my first comment).
+
+Other problem, that once it runs out of space, threads crashes:
+ Pusher crashed: user error (git [\"--git-dir=/home/user/down/annex/.git\",\"--work-tree=/home/user/down/annex\",\"update-index\",\"-z\",\"--index-info\"] exited 128)
+ NetWatcherFallback crashed: fd:28: hGetLine: end of file
+ DaemonStatus crashed: /home/user/down/annex/.git/annex/daemon.status.tmp7564: hClose: resource exhausted (No space left on device)
+
+Right now, I think I tested everything I could.
+
+Where is the autobuild? This one still is 2013 feb 27:
+http://downloads.kitenet.net/git-annex/linux/current/git-annex-standalone-i386.tar.gz
+
+Anyway, once the new version is out, I will retest this experiment.
+
+Best,
+ Laszlo
+
+"""]]
diff --git a/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_11_614e4110188fc6474e7da50fc4281e13._comment b/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_11_614e4110188fc6474e7da50fc4281e13._comment
new file mode 100644
index 000000000..38d9bb621
--- /dev/null
+++ b/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_11_614e4110188fc6474e7da50fc4281e13._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 11"
+ date="2013-03-03T18:36:31Z"
+ content="""
+The autobuild is linked to on [[install/Linux_standalone]]
+
+I don't understand how you're \"restarting\" and not deleting the old .git repository. The right way would be to stop the assistant, run \"git annex uninit\", and then remove \".git\"
+"""]]
diff --git a/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_12_dcb74fb91e1c2f0db4efd68c8bcbc96c._comment b/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_12_dcb74fb91e1c2f0db4efd68c8bcbc96c._comment
new file mode 100644
index 000000000..8bf20fc18
--- /dev/null
+++ b/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_12_dcb74fb91e1c2f0db4efd68c8bcbc96c._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="comment 12"
+ date="2013-03-03T21:24:18Z"
+ content="""
+restarting == Stop git-annex using the gui (Confirm shutdown daemon). Then check if there are running git process (ps -e |grep git),
+if there are kill it, if (defunct) process present, then restart computer. Then launch git-annex using \"git-annex-webapp\" script).
+
+So its a normal program usage (start-stop cycle).
+
+The .git directory is growing. Without a single file moving/deleting/renaming/editing in the working directory.
+
+So the .git directory just grows, and I think it is a bug, and a bad one. (if we ignore the logging problem, the slow startup, the failing of disk full).
+
+I'll give it a spin to the autobuild (http://downloads.kitenet.net/git-annex/autobuild/i386/git-annex-standalone-i386.tar.gz), and report back. It will take at least 2 day, to repeat my whole experience. So expect update from me wednesday the soonest.
+
+Best, Laszlo
+
+"""]]
diff --git a/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_14_38671ba8d302f4d32460d1478abd2111._comment b/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_14_38671ba8d302f4d32460d1478abd2111._comment
new file mode 100644
index 000000000..cb9abcf72
--- /dev/null
+++ b/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_14_38671ba8d302f4d32460d1478abd2111._comment
@@ -0,0 +1,45 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="version 20130314, still not improved"
+ date="2013-03-16T10:01:27Z"
+ content="""
+Hi,
+
+I promised you a feedback, once a newer version comes out.
+
+I started fresh (from the gui), created a new directory, and copied my files over it,
+deleted the old one (git-annex-webapp just silently quite, when I tried to use the old directory).
+
+Problems:
+> 1. each starts costs me an hour at least
+
+> 2. when computer starts git-annex starts too, and try to eat all the resources.
+ Resulting a 10 minute bootup. Would be nice to kick in, when computer idle,
+and others already finished booting up. (ie. I had a chance to start a webbrowser)
+
+> 3. .git objects still going.
+find `pwd` >../gitannexstartup[TIME].txt
+
+Some results:
+gitannexstartup1034.txt
+91179
+gitannexstartup1035.txt
+91566
+gitannexstartup1040.txt
+91938
+
+ diff between 1034 and 1035 (only 1 minute difference when the file created),
+ shows many entries like this:
+ /home/user/Desktop/down/annexnew/.git/objects/52/1ba05331f99585923f1724bb97c18a8f22837444843a45232
+ /home/user/Desktop/down/annexnew/.git/objects/52/7457c478a19f8f85c73b9f17c5640378cf307044868a45258
+
+So git objects keeps still adding.
+As I have many duplicates in my directory
+(backup of backups, I'm kind of paranoid, when comes to daily job), so it may be related to this bug:
+
+http://git-annex.branchable.com/bugs/Direct_mode_keeps_re-checksuming_duplicated_files/
+
+It is just a hunch. Please tell me what else to test.
+
+"""]]
diff --git a/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_14_483244b1ed5744308022465f45c091fd._comment b/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_14_483244b1ed5744308022465f45c091fd._comment
new file mode 100644
index 000000000..8594e5d75
--- /dev/null
+++ b/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_14_483244b1ed5744308022465f45c091fd._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="comment 14"
+ date="2013-04-18T05:54:09Z"
+ content="""
+Hi, these bugs (too detailed logging) and duplicated files issues are both solved in the latest (2013.04.17) release.
+
+Thank you very much, you can close this issue.
+
+Best,
+ Laszlo
+
+"""]]
diff --git a/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_1_d2c63723fa4bf828873770a42ffaab20._comment b/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_1_d2c63723fa4bf828873770a42ffaab20._comment
new file mode 100644
index 000000000..3096e596a
--- /dev/null
+++ b/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_1_d2c63723fa4bf828873770a42ffaab20._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-03-01T16:44:17Z"
+ content="""
+Can you please post a representative sample of the logs?
+"""]]
diff --git a/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_3_52f0db73dc38c3e3a73f6c7a420bf016._comment b/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_3_52f0db73dc38c3e3a73f6c7a420bf016._comment
new file mode 100644
index 000000000..b7b866dc6
--- /dev/null
+++ b/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_3_52f0db73dc38c3e3a73f6c7a420bf016._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-03-01T17:31:31Z"
+ content="""
+I have made the assistant check hourly if its logs are larger than one megabyte, and trim old logs.
+"""]]
diff --git a/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_4_93596b4d5a48ffcf4bc11ba9c83cf7ca._comment b/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_4_93596b4d5a48ffcf4bc11ba9c83cf7ca._comment
new file mode 100644
index 000000000..7efe77303
--- /dev/null
+++ b/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_4_93596b4d5a48ffcf4bc11ba9c83cf7ca._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="comment 4"
+ date="2013-03-01T19:52:13Z"
+ content="""
+Here is the last 300 lines of a 3.3GB daemon.log file:
+http://pastebin.com/TF35H5gu
+"""]]
diff --git a/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_5_de94e80dde6d12485140bb079d74d775._comment b/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_5_de94e80dde6d12485140bb079d74d775._comment
new file mode 100644
index 000000000..16f8cf65a
--- /dev/null
+++ b/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_5_de94e80dde6d12485140bb079d74d775._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 5"
+ date="2013-03-01T20:20:21Z"
+ content="""
+Aha, so it's a direct mode repository and all this \"typechange\" stuff git outputs in such repositories is presumably the main culprit for log bloat. I have made it suppress that output.
+
+Excessive repacking may also explain a lot of the CPU usage and slowness. What does this say?
+
+`grep \"Auto packing the repository for optimum performance.\" .git/annex/*.log |wc -l`
+
+It may make sense for the assistant to tune `gc.auto` to avoid repacks. You might try disabling repacking altogether and see if it helps: `git config gc.auto 0`
+"""]]
diff --git a/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_6_5f34c3d449247b4bce4665b3ea4d054c._comment b/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_6_5f34c3d449247b4bce4665b3ea4d054c._comment
new file mode 100644
index 000000000..8da24d60f
--- /dev/null
+++ b/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_6_5f34c3d449247b4bce4665b3ea4d054c._comment
@@ -0,0 +1,25 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="comment 6"
+ date="2013-03-02T10:05:38Z"
+ content="""
+ $ ls -lah daemon.log
+ -rw-r--r-- 1 user user 3,3G 2013-03-02 10:54 daemon.log
+
+ $ cat daemon.log |wc -l
+ 30746274
+
+ $ grep \"Auto packing the repository for optimum performance.\" daemon.log |wc -l
+ 568
+
+ $ grep \"typechange: \" daemon.log |wc -l
+ 30713158
+
+I'm not sure where should I issue the git command. Inside the annex/.git directory?
+The useful data is also in git repository locally.
+I try to RTFM over the internet, thanks for the pointer!
+
+
+
+"""]]
diff --git a/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_7_b43ae8aec23ba3acaf70edc0de058710._comment b/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_7_b43ae8aec23ba3acaf70edc0de058710._comment
new file mode 100644
index 000000000..4f53dedd1
--- /dev/null
+++ b/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_7_b43ae8aec23ba3acaf70edc0de058710._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="comment 7"
+ date="2013-03-02T11:03:46Z"
+ content="""
+ Ok, quick question: Should I issue git config gc.auto 0, in both repositories?
+ (it puts variable inside .git/config)
+
+ With this gc.auto 0, should the \"typechange: \" logging change? (because it still in the log)
+
+ I'm testing the whole experience, and report back,
+ also when new build is available i will switch to it, to report about the logging size.
+
+Thank you for your fast response!
+
+"""]]
diff --git a/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_8_13b8e0a62f6b6d02960687e206a8b016._comment b/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_8_13b8e0a62f6b6d02960687e206a8b016._comment
new file mode 100644
index 000000000..4d3f11f36
--- /dev/null
+++ b/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_8_13b8e0a62f6b6d02960687e206a8b016._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="comment 8"
+ date="2013-03-02T12:54:14Z"
+ content="""
+The startup time is somewhere between 4-5 hours
+(dunno exactly, its only running about 3 hours) with this gc.auto 0.
+
+I will try to relaunch git-annex-assistant once it finishes startup,
+but I can report back only tomorrow because it may take 5 hours/try.
+
+Laszlo
+
+"""]]
diff --git a/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_9_818b94a74b01a210d1106dd35bc932d8._comment b/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_9_818b94a74b01a210d1106dd35bc932d8._comment
new file mode 100644
index 000000000..11b3efec0
--- /dev/null
+++ b/doc/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/comment_9_818b94a74b01a210d1106dd35bc932d8._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 9"
+ date="2013-03-03T17:45:34Z"
+ content="""
+Well, that sounds like an improvement for sure with gc.auto=0. I have made that be done by default when committing.
+
+The typechange fix is available in the autobuilds already.
+"""]]
diff --git a/doc/bugs/Windows_and_Linux_in_direct_mode_confuses_git.mdwn b/doc/bugs/Windows_and_Linux_in_direct_mode_confuses_git.mdwn
new file mode 100644
index 000000000..dd4b6a921
--- /dev/null
+++ b/doc/bugs/Windows_and_Linux_in_direct_mode_confuses_git.mdwn
@@ -0,0 +1,384 @@
+### Please describe the problem.
+I try to share some files between a windows machine and a linux machine in direct mode, with a remote repository between the two. I can't seem to reproduce the problem in indirect mode...
+
+I add a file on the windows machine then copy it to the remote repository. I then get it on the linux machine and edit it there. If I `git annex sync` and copy the file's data to the remote repository, a `git annex sync` on windows will fail like this:
+
+[[!format sh """
+$ git annex sync
+commit
+ok
+pull origin
+remote: Counting objects: 41, done.
+remote: Compressing objects: 100% (24/24), done.
+remote: Total 31 (delta 9), reused 0 (delta 0)
+Unpacking objects: 100% (31/31), done.
+From ssh://192.168.1.29:/home/raz/work/test
+ b23cb44..9073cc3 git-annex -> origin/git-annex
+ 7d4f0e2..87438fc master -> origin/master
+ 57a661c..b33b025 synced/git-annex -> origin/synced/git-annex
+ 7d4f0e2..87438fc synced/master -> origin/synced/master
+ok
+(merging origin/git-annex origin/synced/git-annex into git-annex...)
+(Recording state in git...)
+push origin
+Counting objects: 17, done.
+Delta compression using up to 8 threads.
+Compressing objects: 100% (4/4), done.
+Writing objects: 100% (5/5), 565 bytes | 0 bytes/s, done.
+Total 5 (delta 2), reused 0 (delta 0)
+To ssh://192.168.1.29:/home/raz/work/test.git
+ b33b025..dcfaf23 git-annex -> synced/git-annex
+ ! [rejected] master -> synced/master (non-fast-forward)
+error: failed to push some refs to 'ssh://192.168.1.29:/home/raz/work/test.git'
+hint: Updates were rejected because a pushed branch tip is behind its remote
+hint: counterpart. Check out this branch and merge the remote changes
+hint: (e.g. 'git pull') before pushing again.
+hint: See the 'Note about fast-forwards' in 'git push --help' for details.
+failed
+git-annex: sync: 1 failed
+"""]]
+
+A `git log` tells me the master branch is not properly merged so I assume the pull failed silently (I paste the log in the transcript).
+
+I can then try to manually fix the windows working copy and sometimes it kind of work, but sometimes I have a hard time recovering and I am better off cloning a new version and moving data's around...
+
+### What steps will reproduce the problem?
+Create a repository on a windows.
+
+Add a file.
+
+`git clone --bare` the repository and put it on a remote machine.
+
+Clone the remote repository to a linux machine.
+
+Get the file's data.
+
+Edit the file on linux.
+
+Commit it and copy the data's to the remote machine.
+
+`git clone sync` on the windows machine --> Error.
+
+### What version of git-annex are you using? On what operating system?
+On Windows:
+[[!format sh """
+git-annex version: 4.20130827-g4f18612
+build flags: Pairing Testsuite S3 WebDAV DNS
+local repository version: 4
+default repository version: 3
+supported repository versions: 3 4
+upgrade supported from repository versions: 2
+"""]]
+
+On Linux
+[[!format sh """
+git-annex version: 4.20130815
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP
+local repository version: 4
+default repository version: 3
+supported repository versions: 3 4
+upgrade supported from repository versions: 0 1 2
+"""]]
+
+### Please provide any additional information below.
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+### On Windows
+
+$ mkdir test_windows
+
+$ cd test_windows/
+
+$ git init
+Initialized empty Git repository in c:/Users/raz/test_windows/.git/
+
+$ git annex init windows
+init windows
+ Detected a crippled filesystem.
+
+ Enabling direct mode.
+
+ Detected a filesystem without fifo support.
+
+ Disabling ssh connection caching.
+ok
+(Recording state in git...)
+
+$ echo "test 1" > test.txt
+
+$ git annex add test.txt
+add test.txt (checksum...) ok
+(Recording state in git...)
+
+$ git annex sync
+commit
+ok
+git-annex: no branch is checked out
+
+$ cd ..
+
+$ git clone --bare test_windows/ test.git
+Cloning into bare repository 'test.git'...
+done.
+
+$ scp -r test.git 192.168.1.29:/home/raz/work/
+config 100% 183 0.2KB/s 00:00
+description 100% 73 0.1KB/s 00:00
+HEAD 100% 23 0.0KB/s 00:00
+applypatch-msg.sample 100% 452 0.4KB/s 00:00
+commit-msg.sample 100% 896 0.9KB/s 00:00
+post-commit.sample 100% 160 0.2KB/s 00:00
+post-receive.sample 100% 552 0.5KB/s 00:00
+post-update.sample 100% 189 0.2KB/s 00:00
+pre-applypatch.sample 100% 398 0.4KB/s 00:00
+pre-commit.sample 100% 1704 1.7KB/s 00:00
+pre-push.sample 100% 1348 1.3KB/s 00:00
+pre-rebase.sample 100% 4951 4.8KB/s 00:00
+prepare-commit-msg.sample 100% 1239 1.2KB/s 00:00
+update.sample 100% 3611 3.5KB/s 00:00
+exclude 100% 240 0.2KB/s 00:00
+825dc642cb6eb9a060e54bf8d69288fbee4904 100% 15 0.0KB/s 00:00
+a31b7a55380d79248658d3fffff6d2dc41a726 100% 116 0.1KB/s 00:00
+dcabbf728abe62b6e2bcc06b8306eb3aa9a497 100% 176 0.2KB/s 00:00
+332ecbfe923879df51a7a3f9bb86ebdfb64273 100% 45 0.0KB/s 00:00
+4f0e20d38d6dc757340a8c569270b5a857fc67 100% 160 0.2KB/s 00:00
+62956bcf45c63b24a637b22a742db0d9458248 100% 86 0.1KB/s 00:00
+7ec519eb1b257a85ae8f9373d0835dea9ddc04 100% 82 0.1KB/s 00:00
+1d1559a050b4a2df2e653b1e7ac15bdf7d56b1 100% 51 0.1KB/s 00:00
+b74dbedfac4d6a0a90580cff2088a5d61f6675 100% 130 0.1KB/s 00:00
+0ca042f439ef997f04a25a449aa1f539b93cf4 100% 53 0.1KB/s 00:00
+bbce5e51e5a90ffd26900de3546fc4f9704181 100% 151 0.2KB/s 00:00
+18bd66316298fcc5c06af9865c30a2fe4d2476 100% 176 0.2KB/s 00:00
+edf8b5cc207e16ca0173785a2ba569c5d4208c 100% 71 0.1KB/s 00:00
+packed-refs 100% 160 0.2KB/s 00:00
+
+$ cd test_windows/
+
+$ git remote add origin ssh://192.168.1.29:/home/raz/work/test.git
+
+$ git annex copy --to origin
+copy test.txt (checking origin...) (to origin...)
+test.txt
+ 7 100% 0.00kB/s 0:00:00 (xfer#1, to-check=0/1)
+
+sent 79 bytes received 31 bytes 220.00 bytes/sec
+total size is 7 speedup is 0.06
+ok
+(Recording state in git...)
+
+$ git annex sync
+commit
+ok
+pull origin
+remote: Counting objects: 11, done.
+remote: Compressing objects: 100% (5/5), done.
+remote: Total 6 (delta 1), reused 0 (delta 0)
+Unpacking objects: 100% (6/6), done.
+From ssh://192.168.1.29:/home/raz/work/test
+ * [new branch] git-annex -> origin/git-annex
+ * [new branch] master -> origin/master
+ok
+(merging origin/git-annex into git-annex...)
+(Recording state in git...)
+push origin
+Counting objects: 18, done.
+Delta compression using up to 8 threads.
+Compressing objects: 100% (8/8), done.
+Writing objects: 100% (10/10), 874 bytes | 0 bytes/s, done.
+Total 10 (delta 4), reused 0 (delta 0)
+To ssh://192.168.1.29:/home/raz/work/test.git
+ * [new branch] git-annex -> synced/git-annex
+ * [new branch] master -> synced/master
+ok
+
+### On Linux
+
+$ git clone test.git test_linux
+Cloning into 'test_linux'...
+done.
+
+$ cd test_linux
+
+$ git annex init linux
+init linux ok
+(Recording state in git...)
+
+$ git annex sync
+(merging origin/git-annex origin/synced/git-annex into git-annex...)
+(Recording state in git...)
+commit
+ok
+pull origin
+ok
+push origin
+Counting objects: 11, done.
+Delta compression using up to 4 threads.
+Compressing objects: 100% (6/6), done.
+Writing objects: 100% (8/8), 775 bytes | 0 bytes/s, done.
+Total 8 (delta 3), reused 0 (delta 0)
+To /home/raz/work/test.git
+ 0b4f175..41fba1d git-annex -> synced/git-annex
+ok
+
+$ git annex get
+get test.txt (from origin...) ok
+(Recording state in git...)
+
+$ git annex direct
+commit
+# On branch master
+nothing to commit, working directory clean
+ok
+direct test.txt ok
+direct ok
+
+$ git annex sync
+commit
+ok
+pull origin
+ok
+push origin
+Counting objects: 9, done.
+Delta compression using up to 4 threads.
+Compressing objects: 100% (4/4), done.
+Writing objects: 100% (5/5), 492 bytes | 0 bytes/s, done.
+Total 5 (delta 1), reused 0 (delta 0)
+To /home/raz/work/test.git
+ 41fba1d..57a661c git-annex -> synced/git-annex
+ok
+
+$ cat test.txt
+test 1
+
+$ echo "test 2" > test.txt
+
+$ git annex sync
+add test.txt (checksum...) ok
+(Recording state in git...)
+commit
+(Recording state in git...)
+ok
+pull origin
+ok
+push origin
+Counting objects: 22, done.
+Delta compression using up to 4 threads.
+Compressing objects: 100% (12/12), done.
+Writing objects: 100% (16/16), 1.40 KiB | 0 bytes/s, done.
+Total 16 (delta 4), reused 0 (delta 0)
+To /home/raz/work/test.git
+ 57a661c..4883cad git-annex -> synced/git-annex
+ 7d4f0e2..87438fc master -> synced/master
+ok
+
+$ git annex copy --to origin
+copy test.txt (to origin...) ok
+(Recording state in git...)
+
+$ git annex sync
+commit
+ok
+pull origin
+remote: Counting objects: 6, done.
+remote: Compressing objects: 100% (4/4), done.
+remote: Total 5 (delta 0), reused 0 (delta 0)
+Unpacking objects: 100% (5/5), done.
+From /home/raz/work/test
+ b23cb44..9073cc3 git-annex -> origin/git-annex
+ok
+(merging origin/git-annex into git-annex...)
+(Recording state in git...)
+push origin
+Counting objects: 18, done.
+Delta compression using up to 4 threads.
+Compressing objects: 100% (8/8), done.
+Writing objects: 100% (10/10), 924 bytes | 0 bytes/s, done.
+Total 10 (delta 3), reused 0 (delta 0)
+To /home/raz/work/test.git
+ 4883cad..b33b025 git-annex -> synced/git-annex
+ok
+
+$
+
+
+### On Windows
+
+$ git annex sync
+commit
+ok
+pull origin
+remote: Counting objects: 41, done.
+remote: Compressing objects: 100% (24/24), done.
+remote: Total 31 (delta 9), reused 0 (delta 0)
+Unpacking objects: 100% (31/31), done.
+From ssh://192.168.1.29:/home/raz/work/test
+ b23cb44..9073cc3 git-annex -> origin/git-annex
+ 7d4f0e2..87438fc master -> origin/master
+ 57a661c..b33b025 synced/git-annex -> origin/synced/git-annex
+ 7d4f0e2..87438fc synced/master -> origin/synced/master
+ok
+(merging origin/git-annex origin/synced/git-annex into git-annex...)
+(Recording state in git...)
+push origin
+Counting objects: 17, done.
+Delta compression using up to 8 threads.
+Compressing objects: 100% (4/4), done.
+Writing objects: 100% (5/5), 565 bytes | 0 bytes/s, done.
+Total 5 (delta 2), reused 0 (delta 0)
+To ssh://192.168.1.29:/home/raz/work/test.git
+ b33b025..dcfaf23 git-annex -> synced/git-annex
+ ! [rejected] master -> synced/master (non-fast-forward)
+error: failed to push some refs to 'ssh://192.168.1.29:/home/raz/work/test.git'
+hint: Updates were rejected because a pushed branch tip is behind its remote
+hint: counterpart. Check out this branch and merge the remote changes
+hint: (e.g. 'git pull') before pushing again.
+hint: See the 'Note about fast-forwards' in 'git push --help' for details.
+failed
+git-annex: sync: 1 failed
+
+$ git log --graph --oneline --decorate --all
+* 87438fc (origin/synced/master, origin/master) git-annex automatic sync
+* 7d4f0e2 (HEAD, synced/master, master) git-annex automatic sync
+*-. dcfaf23 (origin/synced/git-annex, git-annex) merging origin/git-annex orig
+|\ \
+| | * b33b025 merging origin/git-annex into git-annex
+| | |\
+| | |/
+| |/|
+| * | 9073cc3 (origin/git-annex) update
+| | * 73518bc update
+| | * 4883cad update
+| | * 1b447f5 update
+| |/
+|/|
+* | 57a661c update
+| |
+| \
+*-. \ 41fba1d merging origin/git-annex origin/synced/git-annex into git-annex
+|\ \ \
+| | |/
+| |/|
+| | * 0b4f175 merging origin/git-annex into git-annex
+| | |\
+| | |/
+| |/|
+| * | b23cb44 update
+| | * b5755a2 update
+| |/
+| * 6adcabb update
+| * df18bd6 update
+| * dcbbce5 branch created
+* 0d138eb update
+* fe6bccc branch created
+
+$
+
+# End of transcript or log.
+"""]]
+
+> Apparently `test.git` had `receive.denyNonFastForwards`
+> set to true, which prevents the forced pushing `git annex sync`
+> needs to do. I have made it print out a hint about this setting
+> when a push failes. [[done]] --[[Joey]]
diff --git a/doc/bugs/Windows_and_Linux_in_direct_mode_confuses_git/comment_1_155e0c4d3aa41eebfe27533ab70a91d3._comment b/doc/bugs/Windows_and_Linux_in_direct_mode_confuses_git/comment_1_155e0c4d3aa41eebfe27533ab70a91d3._comment
new file mode 100644
index 000000000..1a443fb19
--- /dev/null
+++ b/doc/bugs/Windows_and_Linux_in_direct_mode_confuses_git/comment_1_155e0c4d3aa41eebfe27533ab70a91d3._comment
@@ -0,0 +1,68 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawknruiCHUcOh2mmpkh7OFJ4iNfAOOamRVs"
+ nickname="Renaud"
+ subject="comment 1"
+ date="2013-08-29T06:38:44Z"
+ content="""
+I wonder if it isn't related to the fact that even if I do `git annex drop` on windows, the file is still marked as modified in git.
+What is in repository is the path to the file's data using unix style folder separator but what is in my working directory is a file containing the path using windows style folder separator.
+
+I paste a transcript to describe what I mean:
+
+[[!format sh \"\"\"
+$ mkdir tmp
+
+$ cd tmp
+
+$ git init
+Initialized empty Git repository in c:/Users/raz/tmp/tmp/.git/
+
+$ git annex init test
+init test
+ Detected a crippled filesystem.
+
+ Enabling direct mode.
+
+ Detected a filesystem without fifo support.
+
+ Disabling ssh connection caching.
+ok
+(Recording state in git...)
+
+$ echo test > test
+
+$ git annex add
+add test (checksum...) ok
+(Recording state in git...)
+
+$ git annex sync
+commit
+ok
+git-annex: no branch is checked out
+
+$ git annex drop --force
+drop test ok
+(Recording state in git...)
+
+$ git status
+# On branch master
+# Changes not staged for commit:
+# (use \"git add <file>...\" to update what will be committed)
+# (use \"git checkout -- <file>...\" to discard changes in working directory)
+#
+# modified: test
+#
+no changes added to commit (use \"git add\" and/or \"git commit -a\")
+
+$ git diff
+diff --git a/test b/test
+index a9dd439..62343b2 120000
+--- a/test
++++ b/test
+@@ -1 +1 @@
+-.git/annex/objects/w8/pv/SHA256E-s5--f2ca1bb6c7e907d06dafe4687e579fce76b37e4e93
+\ No newline at end of file
++.git\annex\objects\w8\pv\SHA256E-s5--f2ca1bb6c7e907d06dafe4687e579fce76b37e4e93
+\ No newline at end of file
+\"\"\"]]
+"""]]
diff --git a/doc/bugs/Windows_build_test_failures.mdwn b/doc/bugs/Windows_build_test_failures.mdwn
new file mode 100644
index 000000000..ac4dce13c
--- /dev/null
+++ b/doc/bugs/Windows_build_test_failures.mdwn
@@ -0,0 +1,1232 @@
+Given that others can build+run OK I wonder if this is a build environment setup problem rather than a code issue.
+This might be two bugs, but I rather suspect the fix to one is the fix to the other.
+
+### Please describe the problem.
+Some tests fail with:
+ssh: Could not resolve hostname C: no address associated with name
+
+then if you try and do a copy to/from an ssh remote then it fails with simply 'copy: 1 failed'
+
+### What steps will reproduce the problem?
+
+For the tests, simply sh standalone/windows/build.sh
+
+For the other, I'm using a modified version of the other windows user's script, the set -x'd output is:
+
+<pre>
++ git-annex version
+git-annex version: 4.20130621-g36258de^M
+build flags: Pairing Testsuite S3 WebDAV DNS^M
++ ssh gitremote sh testrepo.sh
+git-annex version: 4.20130621-g36258de
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP DNS
+Initialized empty Git repository in /media/backup/git/repo.git/
+init origin ok
+(Recording state in git...)
+commit
+ok
+git-annex: no branch is checked out
++ rm -rf repo
++ git init repo
+Initialized empty Git repository in c:/Users/Oliver/repo/.git/
++ cd repo
++ git-annex init
+init ^M
+ Detected a crippled filesystem.^M
+^M
+ Enabling direct mode.^M
+^M
+ Detected a filesystem without fifo support.^M
+^M
+ Disabling ssh connection caching.^M
+ok^M
+(Recording state in git...)^M
++ git remote add origin ssh://git@remote/~/repo.git
++ echo hello
++ git-annex add .
+add foo.txt (checksum...) ok^M
+(Recording state in git...)^M
++ git commit -m .
+[master (root-commit) f34a076] .
+ 1 file changed, 1 insertion(+)
+ create mode 120000 foo.txt
++ git-annex sync
+commit ^M
+ok^M
+pull origin warning: no common commits
+From ssh://remote/~/repo
+ * [new branch] git-annex -> origin/git-annex
+^M
+ok^M
+(merging origin/git-annex into git-annex...)^M
+(Recording state in git...)^M
+push origin To ssh://git@remote/~/repo.git
+ * [new branch] git-annex -> synced/git-annex
+ * [new branch] master -> synced/master
+^M
+ok^M
++ git-annex copy --to origin
+copy foo.txt (checking origin...) (to origin...) ^M
+failed^M
+git-annex.exe: copy: 1 failed
+</pre>
+
+
+
+
+
+### What version of git-annex are you using? On what operating system?
+Windows (8 x64):
+git-annex version: 4.20130621-g36258de
+build flags: Pairing Testsuite S3 WebDAV DNS
+Linux (debian wheezy i386):
+git-annex version: 4.20130621-g36258de
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP DNS
+
+other versions
+git-bash: git(1.8.0.msysgit.0),ssh(ssh 4.6p1, ssl 0.9.8e 23 feb 2007)
+msys: git(none) ssh(ssh 5.4p1, ssl 1.0.0 29 Mar 2010)
+cygwin: git(1.7.9) ssh(none)
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+build.log:
++ set -e
++ HP='/c/Program Files (x86)/Haskell Platform/2012.4.0.0'
++ FLAGS='-Webapp -Assistant -XMPP'
++ PATH='/c/Program Files (x86)/Haskell Platform/2012.4.0.0/bin:/c/Program Files (x86)/Haskell Platform/2012.4.0.0/lib/extralibs/bin:/c/Program Files (x86)/NSIS:/home/Oliver/bin:.:/usr/local/bin:/mingw/bin:/bin:/c/Program Files (x86)/Haskell/bin:/c/Program Files (x86)/Haskell Platform/2013.2.0.0/lib/extralibs/bin:/c/Program Files (x86)/Haskell Platform/2013.2.0.0/bin:/c/Program Files (x86)/AMD APP/bin/x86_64:/c/Program Files (x86)/AMD APP/bin/x86:/c/Windows/system32:/c/Windows:/c/Windows/System32/Wbem:/c/Windows/System32/WindowsPowerShell/v1.0/:/c/Program Files (x86)/ATI Technologies/ATI.ACE/Core-Static:/c/Program Files (x86)/Windows Kits/8.0/Windows Performance Toolkit/:/c/Program Files/Microsoft/Web Platform Installer/:/c/Program Files (x86)/Haskell Platform/2013.2.0.0/mingw/bin:/c/Users/Oliver/AppData/Roaming/cabal/bin'
++ rm -f git-annex-installer.exe
++ cabal update
+Downloading the latest package list from hackage.haskell.org
++ rm -rf MissingH-1.2.0.0
++ cabal unpack MissingH
+Unpacking to MissingH-1.2.0.0\
++ cd MissingH-1.2.0.0
++ withcyg patch -p1
++ PATH='/c/Program Files (x86)/Haskell Platform/2012.4.0.0/bin:/c/Program Files (x86)/Haskell Platform/2012.4.0.0/lib/extralibs/bin:/c/Program Files (x86)/NSIS:/home/Oliver/bin:.:/usr/local/bin:/mingw/bin:/bin:/c/Program Files (x86)/Haskell/bin:/c/Program Files (x86)/Haskell Platform/2013.2.0.0/lib/extralibs/bin:/c/Program Files (x86)/Haskell Platform/2013.2.0.0/bin:/c/Program Files (x86)/AMD APP/bin/x86_64:/c/Program Files (x86)/AMD APP/bin/x86:/c/Windows/system32:/c/Windows:/c/Windows/System32/Wbem:/c/Windows/System32/WindowsPowerShell/v1.0/:/c/Program Files (x86)/ATI Technologies/ATI.ACE/Core-Static:/c/Program Files (x86)/Windows Kits/8.0/Windows Performance Toolkit/:/c/Program Files/Microsoft/Web Platform Installer/:/c/Program Files (x86)/Haskell Platform/2013.2.0.0/mingw/bin:/c/Users/Oliver/AppData/Roaming/cabal/bin:/c/cygwin/bin'
++ patch -p1
+patching file src/System/IO/WindowsCompat.hs
+Hunk #1 succeeded at 119 (offset -1 lines).
+Hunk #2 succeeded at 132 (offset -1 lines).
++ cabal install
+Resolving dependencies...
+In order, the following would be installed:
+MissingH-1.2.0.0 (reinstall)
+cabal.exe: The following packages are likely to be broken by the reinstalls:
+hS3-0.5.7
+Use --force-reinstalls if you want to install anyway.
++ true
++ cd ..
++ cabal install --only-dependencies '-f-Webapp -Assistant -XMPP'
+Resolving dependencies...
+All the requested packages are already installed:
+Use --reinstall if you want to reinstall anyway.
++ '[' -e last-incremental-failed ']'
++ touch last-incremental-failed
++ withcyg cabal configure '-f-Webapp -Assistant -XMPP'
++ PATH='/c/Program Files (x86)/Haskell Platform/2012.4.0.0/bin:/c/Program Files (x86)/Haskell Platform/2012.4.0.0/lib/extralibs/bin:/c/Program Files (x86)/NSIS:/home/Oliver/bin:.:/usr/local/bin:/mingw/bin:/bin:/c/Program Files (x86)/Haskell/bin:/c/Program Files (x86)/Haskell Platform/2013.2.0.0/lib/extralibs/bin:/c/Program Files (x86)/Haskell Platform/2013.2.0.0/bin:/c/Program Files (x86)/AMD APP/bin/x86_64:/c/Program Files (x86)/AMD APP/bin/x86:/c/Windows/system32:/c/Windows:/c/Windows/System32/Wbem:/c/Windows/System32/WindowsPowerShell/v1.0/:/c/Program Files (x86)/ATI Technologies/ATI.ACE/Core-Static:/c/Program Files (x86)/Windows Kits/8.0/Windows Performance Toolkit/:/c/Program Files/Microsoft/Web Platform Installer/:/c/Program Files (x86)/Haskell Platform/2013.2.0.0/mingw/bin:/c/Users/Oliver/AppData/Roaming/cabal/bin:/c/cygwin/bin'
++ cabal configure '-f-Webapp -Assistant -XMPP'
+Resolving dependencies...
+[ 1 of 24] Compiling Utility.Applicative ( Utility\Applicative.hs, dist\setup\Utility\Applicative.o )
+[ 2 of 24] Compiling Utility.PartialPrelude ( Utility\PartialPrelude.hs, dist\setup\Utility\PartialPrelude.o )
+[ 3 of 24] Compiling Utility.FileSystemEncoding ( Utility\FileSystemEncoding.hs, dist\setup\Utility\FileSystemEncoding.o )
+[ 4 of 24] Compiling Utility.Exception ( Utility\Exception.hs, dist\setup\Utility\Exception.o )
+[ 5 of 24] Compiling Utility.Misc ( Utility\Misc.hs, dist\setup\Utility\Misc.o )
+[ 6 of 24] Compiling Utility.Process ( Utility\Process.hs, dist\setup\Utility\Process.o )
+[ 7 of 24] Compiling Utility.Env ( Utility\Env.hs, dist\setup\Utility\Env.o )
+[ 8 of 24] Compiling Utility.UserInfo ( Utility\UserInfo.hs, dist\setup\Utility\UserInfo.o )
+[ 9 of 24] Compiling Utility.OSX ( Utility\OSX.hs, dist\setup\Utility\OSX.o )
+[10 of 24] Compiling Utility.Tmp ( Utility\Tmp.hs, dist\setup\Utility\Tmp.o )
+[11 of 24] Compiling Utility.Monad ( Utility\Monad.hs, dist\setup\Utility\Monad.o )
+[12 of 24] Compiling Utility.Path ( Utility\Path.hs, dist\setup\Utility\Path.o )
+[13 of 24] Compiling Utility.FreeDesktop ( Utility\FreeDesktop.hs, dist\setup\Utility\FreeDesktop.o )
+[16 of 24] Compiling Utility.SafeCommand ( Utility\SafeCommand.hs, dist\setup\Utility\SafeCommand.o )
+[17 of 24] Compiling Utility.ExternalSHA ( Utility\ExternalSHA.hs, dist\setup\Utility\ExternalSHA.o )
+[18 of 24] Compiling Utility.Directory ( Utility\Directory.hs, dist\setup\Utility\Directory.o )
+Linking .\dist\setup\setup.exe ...
+ checking version... 4.20130621-g36258de
+ checking git... yes
+ checking git version... 1.7.9
+ checking cp -a... yes
+ checking cp -p... yes
+ checking cp --reflink=auto... no
+ checking xargs -0... yes
+ checking rsync... yes
+ checking curl... no
+ checking wget... yes
+ checking bup... no
+ checking gpg... not available
+ checking lsof... not available
+ checking ssh connection caching... no
+ checking sha1... sha1sum
+ checking sha256... sha256sum
+ checking sha512... sha512sum
+ checking sha224... sha224sum
+ checking sha384... sha384sum
+Configuring git-annex-4.20130601...
++ withcyg cabal build
++ PATH='/c/Program Files (x86)/Haskell Platform/2012.4.0.0/bin:/c/Program Files (x86)/Haskell Platform/2012.4.0.0/lib/extralibs/bin:/c/Program Files (x86)/NSIS:/home/Oliver/bin:.:/usr/local/bin:/mingw/bin:/bin:/c/Program Files (x86)/Haskell/bin:/c/Program Files (x86)/Haskell Platform/2013.2.0.0/lib/extralibs/bin:/c/Program Files (x86)/Haskell Platform/2013.2.0.0/bin:/c/Program Files (x86)/AMD APP/bin/x86_64:/c/Program Files (x86)/AMD APP/bin/x86:/c/Windows/system32:/c/Windows:/c/Windows/System32/Wbem:/c/Windows/System32/WindowsPowerShell/v1.0/:/c/Program Files (x86)/ATI Technologies/ATI.ACE/Core-Static:/c/Program Files (x86)/Windows Kits/8.0/Windows Performance Toolkit/:/c/Program Files/Microsoft/Web Platform Installer/:/c/Program Files (x86)/Haskell Platform/2013.2.0.0/mingw/bin:/c/Users/Oliver/AppData/Roaming/cabal/bin:/c/cygwin/bin'
++ cabal build
+Building git-annex-4.20130601...
+Preprocessing executable 'git-annex' for git-annex-4.20130601...
+Touch.hsc:117:2: warning: #warning "utimensat and lutimes not available; building without symlink timestamp preservation support"
+Touch.hsc: In function 'main':
+Touch.hsc:117:2: warning: #warning "utimensat and lutimes not available; building without symlink timestamp preservation support"
+Touch.hsc:117:2: warning: #warning "utimensat and lutimes not available; building without symlink timestamp preservation support"
+In file included from Mounts.hsc:23:0:
+Utility/libmounts.h:17:3: warning: #warning mounts listing code not available for this OS
+
+Utility\libdiskfree.c:36:3:
+ warning: #warning free space checking code not available for this OS
+
+In file included from Utility\libmounts.c:35:0:
+
+Utility\libmounts.h:17:3:
+ warning: #warning mounts listing code not available for this OS
+[ 1 of 217] Compiling Utility.Dot ( Utility\Dot.hs, dist\build\git-annex\git-annex-tmp\Utility\Dot.o )
+[ 2 of 217] Compiling BuildFlags ( BuildFlags.hs, dist\build\git-annex\git-annex-tmp\BuildFlags.o )
+[ 3 of 217] Compiling Utility.Percentage ( Utility\Percentage.hs, dist\build\git-annex\git-annex-tmp\Utility\Percentage.o )
+[ 4 of 217] Compiling Utility.Base64 ( Utility\Base64.hs, dist\build\git-annex\git-annex-tmp\Utility\Base64.o )
+[ 5 of 217] Compiling Utility.JSONStream ( Utility\JSONStream.hs, dist\build\git-annex\git-annex-tmp\Utility\JSONStream.o )
+[ 6 of 217] Compiling Git.Types ( Git\Types.hs, dist\build\git-annex\git-annex-tmp\Git\Types.o )
+[ 7 of 217] Compiling Utility.DataUnits ( Utility\DataUnits.hs, dist\build\git-annex\git-annex-tmp\Utility\DataUnits.o )
+[ 8 of 217] Compiling Types.FileMatcher ( Types\FileMatcher.hs, dist\build\git-annex\git-annex-tmp\Types\FileMatcher.o )
+[ 9 of 217] Compiling Types.BranchState ( Types\BranchState.hs, dist\build\git-annex\git-annex-tmp\Types\BranchState.o )
+[ 10 of 217] Compiling Messages.JSON ( Messages\JSON.hs, dist\build\git-annex\git-annex-tmp\Messages\JSON.o )
+[ 11 of 217] Compiling Types.UUID ( Types\UUID.hs, dist\build\git-annex\git-annex-tmp\Types\UUID.o )
+[ 12 of 217] Compiling Types.Group ( Types\Group.hs, dist\build\git-annex\git-annex-tmp\Types\Group.o )
+[ 13 of 217] Compiling Utility.Shell ( Utility\Shell.hs, dist\build\git-annex\git-annex-tmp\Utility\Shell.o )
+[ 14 of 217] Compiling Utility.QuickCheck ( Utility\QuickCheck.hs, dist\build\git-annex\git-annex-tmp\Utility\QuickCheck.o )
+[ 15 of 217] Compiling Utility.PartialPrelude ( Utility\PartialPrelude.hs, dist\build\git-annex\git-annex-tmp\Utility\PartialPrelude.o )
+[ 16 of 217] Compiling Utility.HumanTime ( Utility\HumanTime.hs, dist\build\git-annex\git-annex-tmp\Utility\HumanTime.o )
+[ 17 of 217] Compiling Utility.FileSystemEncoding ( Utility\FileSystemEncoding.hs, dist\build\git-annex\git-annex-tmp\Utility\FileSystemEncoding.o )
+[ 18 of 217] Compiling Utility.Touch ( dist\build\git-annex\git-annex-tmp\Utility\Touch.hs, dist\build\git-annex\git-annex-tmp\Utility\Touch.o )
+
+UtilityTouch.hsc:17:1: Warning:
+ The import of `Utility.FileSystemEncoding' is redundant
+ except perhaps to import instances from `Utility.FileSystemEncoding'
+ To import instances alone, use: import Utility.FileSystemEncoding()
+
+UtilityTouch.hsc:19:1: Warning:
+ The import of `Foreign' is redundant
+ except perhaps to import instances from `Foreign'
+ To import instances alone, use: import Foreign()
+
+UtilityTouch.hsc:21:1: Warning:
+ The import of `Control.Monad' is redundant
+ except perhaps to import instances from `Control.Monad'
+ To import instances alone, use: import Control.Monad()
+[ 19 of 217] Compiling Utility.Applicative ( Utility\Applicative.hs, dist\build\git-annex\git-annex-tmp\Utility\Applicative.o )
+[ 20 of 217] Compiling Utility.Monad ( Utility\Monad.hs, dist\build\git-annex\git-annex-tmp\Utility\Monad.o )
+[ 21 of 217] Compiling Utility.Exception ( Utility\Exception.hs, dist\build\git-annex\git-annex-tmp\Utility\Exception.o )
+[ 22 of 217] Compiling Utility.Tmp ( Utility\Tmp.hs, dist\build\git-annex\git-annex-tmp\Utility\Tmp.o )
+[ 23 of 217] Compiling Utility.Env ( Utility\Env.hs, dist\build\git-annex\git-annex-tmp\Utility\Env.o )
+[ 24 of 217] Compiling Utility.UserInfo ( Utility\UserInfo.hs, dist\build\git-annex\git-annex-tmp\Utility\UserInfo.o )
+[ 25 of 217] Compiling Utility.Misc ( Utility\Misc.hs, dist\build\git-annex\git-annex-tmp\Utility\Misc.o )
+
+Utility\Misc.hs:22:1: Warning:
+ The import of `Utility.Exception' is redundant
+ except perhaps to import instances from `Utility.Exception'
+ To import instances alone, use: import Utility.Exception()
+[ 26 of 217] Compiling Utility.Process ( Utility\Process.hs, dist\build\git-annex\git-annex-tmp\Utility\Process.o )
+
+Utility\Process.hs:44:1: Warning:
+ The import of `Data.Maybe' is redundant
+ except perhaps to import instances from `Data.Maybe'
+ To import instances alone, use: import Data.Maybe()
+[ 27 of 217] Compiling Utility.Network ( Utility\Network.hs, dist\build\git-annex\git-annex-tmp\Utility\Network.o )
+[ 28 of 217] Compiling Utility.Verifiable ( Utility\Verifiable.hs, dist\build\git-annex\git-annex-tmp\Utility\Verifiable.o )
+[ 29 of 217] Compiling Utility.Format ( Utility\Format.hs, dist\build\git-annex\git-annex-tmp\Utility\Format.o )
+[ 30 of 217] Compiling Build.SysConfig ( Build\SysConfig.hs, dist\build\git-annex\git-annex-tmp\Build\SysConfig.o )
+[ 31 of 217] Compiling Utility.Path ( Utility\Path.hs, dist\build\git-annex\git-annex-tmp\Utility\Path.o )
+[ 32 of 217] Compiling Config.Cost ( Config\Cost.hs, dist\build\git-annex\git-annex-tmp\Config\Cost.o )
+[ 33 of 217] Compiling Types.Messages ( Types\Messages.hs, dist\build\git-annex\git-annex-tmp\Types\Messages.o )
+[ 34 of 217] Compiling Types.TrustLevel ( Types\TrustLevel.hs, dist\build\git-annex\git-annex-tmp\Types\TrustLevel.o )
+[ 35 of 217] Compiling Utility.SafeCommand ( Utility\SafeCommand.hs, dist\build\git-annex\git-annex-tmp\Utility\SafeCommand.o )
+[ 36 of 217] Compiling Utility.Directory ( Utility\Directory.hs, dist\build\git-annex\git-annex-tmp\Utility\Directory.o )
+[ 37 of 217] Compiling Utility.ExternalSHA ( Utility\ExternalSHA.hs, dist\build\git-annex\git-annex-tmp\Utility\ExternalSHA.o )
+[ 38 of 217] Compiling Common ( Common.hs, dist\build\git-annex\git-annex-tmp\Common.o )
+[ 39 of 217] Compiling Git.Filename ( Git\Filename.hs, dist\build\git-annex\git-annex-tmp\Git\Filename.o )
+[ 40 of 217] Compiling Logs.UUIDBased ( Logs\UUIDBased.hs, dist\build\git-annex\git-annex-tmp\Logs\UUIDBased.o )
+[ 41 of 217] Compiling Types.Key ( Types\Key.hs, dist\build\git-annex\git-annex-tmp\Types\Key.o )
+[ 42 of 217] Compiling Utility.FileMode ( Utility\FileMode.hs, dist\build\git-annex\git-annex-tmp\Utility\FileMode.o )
+[ 43 of 217] Compiling Git ( Git.hs, dist\build\git-annex\git-annex-tmp\Git.o )
+
+Git.hs:41:1: Warning:
+ The import of `Utility.FileMode' is redundant
+ except perhaps to import instances from `Utility.FileMode'
+ To import instances alone, use: import Utility.FileMode()
+[ 44 of 217] Compiling Utility.InodeCache ( Utility\InodeCache.hs, dist\build\git-annex\git-annex-tmp\Utility\InodeCache.o )
+[ 45 of 217] Compiling Types.KeySource ( Types\KeySource.hs, dist\build\git-annex\git-annex-tmp\Types\KeySource.o )
+[ 46 of 217] Compiling Types.Backend ( Types\Backend.hs, dist\build\git-annex\git-annex-tmp\Types\Backend.o )
+[ 47 of 217] Compiling Utility.Gpg ( Utility\Gpg.hs, dist\build\git-annex\git-annex-tmp\Utility\Gpg.o )
+
+Utility\Gpg.hs:12:1: Warning:
+ The import of `System.Posix.Types' is redundant
+ except perhaps to import instances from `System.Posix.Types'
+ To import instances alone, use: import System.Posix.Types()
+
+Utility\Gpg.hs:14:1: Warning:
+ The import of `Control.Concurrent' is redundant
+ except perhaps to import instances from `Control.Concurrent'
+ To import instances alone, use: import Control.Concurrent()
+
+Utility\Gpg.hs:15:1: Warning:
+ The import of `Control.Exception' is redundant
+ except perhaps to import instances from `Control.Exception'
+ To import instances alone, use: import Control.Exception()
+
+Utility\Gpg.hs:16:1: Warning:
+ The import of `System.Path' is redundant
+ except perhaps to import instances from `System.Path'
+ To import instances alone, use: import System.Path()
+
+Utility\Gpg.hs:19:1: Warning:
+ The import of `Utility.Env' is redundant
+ except perhaps to import instances from `Utility.Env'
+ To import instances alone, use: import Utility.Env()
+[ 48 of 217] Compiling Types.Crypto ( Types\Crypto.hs, dist\build\git-annex\git-annex-tmp\Types\Crypto.o )
+[ 49 of 217] Compiling Utility.Matcher ( Utility\Matcher.hs, dist\build\git-annex\git-annex-tmp\Utility\Matcher.o )
+[ 50 of 217] Compiling Utility.Metered ( Utility\Metered.hs, dist\build\git-annex\git-annex-tmp\Utility\Metered.o )
+[ 51 of 217] Compiling Git.FilePath ( Git\FilePath.hs, dist\build\git-annex\git-annex-tmp\Git\FilePath.o )
+[ 52 of 217] Compiling Git.Url ( Git\Url.hs, dist\build\git-annex\git-annex-tmp\Git\Url.o )
+[ 53 of 217] Compiling Git.Construct ( Git\Construct.hs, dist\build\git-annex\git-annex-tmp\Git\Construct.o )
+[ 54 of 217] Compiling Git.Config ( Git\Config.hs, dist\build\git-annex\git-annex-tmp\Git\Config.o )
+[ 55 of 217] Compiling Git.CurrentRepo ( Git\CurrentRepo.hs, dist\build\git-annex\git-annex-tmp\Git\CurrentRepo.o )
+
+Git\CurrentRepo.hs:16:1: Warning:
+ The import of `Utility.Env' is redundant
+ except perhaps to import instances from `Utility.Env'
+ To import instances alone, use: import Utility.Env()
+
+Git\CurrentRepo.hs:43:17: Warning: Defined but not used: `s'
+[ 56 of 217] Compiling Git.SharedRepository ( Git\SharedRepository.hs, dist\build\git-annex\git-annex-tmp\Git\SharedRepository.o )
+[ 57 of 217] Compiling Types.GitConfig ( Types\GitConfig.hs, dist\build\git-annex\git-annex-tmp\Types\GitConfig.o )
+[ 58 of 217] Compiling Types.Remote ( Types\Remote.hs, dist\build\git-annex\git-annex-tmp\Types\Remote.o )
+[ 59 of 217] Compiling Types.StandardGroups ( Types\StandardGroups.hs, dist\build\git-annex\git-annex-tmp\Types\StandardGroups.o )
+[ 60 of 217] Compiling Utility.Gpg.Types ( Utility\Gpg\Types.hs, dist\build\git-annex\git-annex-tmp\Utility\Gpg\Types.o )
+[ 61 of 217] Compiling Git.Sha ( Git\Sha.hs, dist\build\git-annex\git-annex-tmp\Git\Sha.o )
+[ 62 of 217] Compiling Utility.CoProcess ( Utility\CoProcess.hs, dist\build\git-annex\git-annex-tmp\Utility\CoProcess.o )
+[ 63 of 217] Compiling Git.Command ( Git\Command.hs, dist\build\git-annex\git-annex-tmp\Git\Command.o )
+[ 64 of 217] Compiling Git.LsFiles ( Git\LsFiles.hs, dist\build\git-annex\git-annex-tmp\Git\LsFiles.o )
+[ 65 of 217] Compiling Git.CatFile ( Git\CatFile.hs, dist\build\git-annex\git-annex-tmp\Git\CatFile.o )
+[ 66 of 217] Compiling Git.UpdateIndex ( Git\UpdateIndex.hs, dist\build\git-annex\git-annex-tmp\Git\UpdateIndex.o )
+[ 67 of 217] Compiling Git.Queue ( Git\Queue.hs, dist\build\git-annex\git-annex-tmp\Git\Queue.o )
+[ 68 of 217] Compiling Git.Version ( Git\Version.hs, dist\build\git-annex\git-annex-tmp\Git\Version.o )
+[ 69 of 217] Compiling Git.CheckAttr ( Git\CheckAttr.hs, dist\build\git-annex\git-annex-tmp\Git\CheckAttr.o )
+[ 70 of 217] Compiling Annex ( Annex.hs, dist\build\git-annex\git-annex-tmp\Annex.o )
+[ 71 of 217] Compiling Types.Option ( Types\Option.hs, dist\build\git-annex\git-annex-tmp\Types\Option.o )
+[ 72 of 217] Compiling Types ( Types.hs, dist\build\git-annex\git-annex-tmp\Types.o )
+[ 73 of 217] Compiling Locations ( Locations.hs, dist\build\git-annex\git-annex-tmp\Locations.o )
+[ 74 of 217] Compiling Messages ( Messages.hs, dist\build\git-annex\git-annex-tmp\Messages.o )
+[ 75 of 217] Compiling Common.Annex ( Common\Annex.hs, dist\build\git-annex\git-annex-tmp\Common\Annex.o )
+[ 76 of 217] Compiling Crypto ( Crypto.hs, dist\build\git-annex\git-annex-tmp\Crypto.o )
+[ 77 of 217] Compiling Annex.CatFile ( Annex\CatFile.hs, dist\build\git-annex\git-annex-tmp\Annex\CatFile.o )
+[ 78 of 217] Compiling Backend.SHA ( Backend\SHA.hs, dist\build\git-annex\git-annex-tmp\Backend\SHA.o )
+[ 79 of 217] Compiling Backend.WORM ( Backend\WORM.hs, dist\build\git-annex\git-annex-tmp\Backend\WORM.o )
+[ 80 of 217] Compiling Backend.URL ( Backend\URL.hs, dist\build\git-annex\git-annex-tmp\Backend\URL.o )
+[ 81 of 217] Compiling Annex.Exception ( Annex\Exception.hs, dist\build\git-annex\git-annex-tmp\Annex\Exception.o )
+[ 82 of 217] Compiling Remote.Helper.Special ( Remote\Helper\Special.hs, dist\build\git-annex\git-annex-tmp\Remote\Helper\Special.o )
+[ 83 of 217] Compiling Remote.Helper.Chunked ( Remote\Helper\Chunked.hs, dist\build\git-annex\git-annex-tmp\Remote\Helper\Chunked.o )
+[ 84 of 217] Compiling Annex.Environment ( Annex\Environment.hs, dist\build\git-annex\git-annex-tmp\Annex\Environment.o )
+
+Annex\Environment.hs:13:1: Warning:
+ The import of `Utility.Env' is redundant
+ except perhaps to import instances from `Utility.Env'
+ To import instances alone, use: import Utility.Env()
+
+Annex\Environment.hs:14:1: Warning:
+ The import of `Utility.UserInfo' is redundant
+ except perhaps to import instances from `Utility.UserInfo'
+ To import instances alone, use: import Utility.UserInfo()
+[ 85 of 217] Compiling Types.Command ( Types\Command.hs, dist\build\git-annex\git-annex-tmp\Types\Command.o )
+[ 86 of 217] Compiling Usage ( Usage.hs, dist\build\git-annex\git-annex-tmp\Usage.o )
+[ 87 of 217] Compiling Annex.Queue ( Annex\Queue.hs, dist\build\git-annex\git-annex-tmp\Annex\Queue.o )
+[ 88 of 217] Compiling Annex.BranchState ( Annex\BranchState.hs, dist\build\git-annex\git-annex-tmp\Annex\BranchState.o )
+[ 89 of 217] Compiling Remote.Helper.Encryptable ( Remote\Helper\Encryptable.hs, dist\build\git-annex\git-annex-tmp\Remote\Helper\Encryptable.o )
+[ 90 of 217] Compiling Fields ( Fields.hs, dist\build\git-annex\git-annex-tmp\Fields.o )
+[ 91 of 217] Compiling Annex.CheckAttr ( Annex\CheckAttr.hs, dist\build\git-annex\git-annex-tmp\Annex\CheckAttr.o )
+[ 92 of 217] Compiling Git.HashObject ( Git\HashObject.hs, dist\build\git-annex\git-annex-tmp\Git\HashObject.o )
+[ 93 of 217] Compiling Annex.Link ( Annex\Link.hs, dist\build\git-annex\git-annex-tmp\Annex\Link.o )
+[ 94 of 217] Compiling Utility.CopyFile ( Utility\CopyFile.hs, dist\build\git-annex\git-annex-tmp\Utility\CopyFile.o )
+[ 95 of 217] Compiling Git.Ref ( Git\Ref.hs, dist\build\git-annex\git-annex-tmp\Git\Ref.o )
+[ 96 of 217] Compiling Git.Branch ( Git\Branch.hs, dist\build\git-annex\git-annex-tmp\Git\Branch.o )
+[ 97 of 217] Compiling Git.UnionMerge ( Git\UnionMerge.hs, dist\build\git-annex\git-annex-tmp\Git\UnionMerge.o )
+[ 98 of 217] Compiling Git.Merge ( Git\Merge.hs, dist\build\git-annex\git-annex-tmp\Git\Merge.o )
+[ 99 of 217] Compiling Git.DiffTree ( Git\DiffTree.hs, dist\build\git-annex\git-annex-tmp\Git\DiffTree.o )
+[100 of 217] Compiling Utility.DiskFree ( Utility\DiskFree.hs, dist\build\git-annex\git-annex-tmp\Utility\DiskFree.o )
+[101 of 217] Compiling Utility.Url ( Utility\Url.hs, dist\build\git-annex\git-annex-tmp\Utility\Url.o )
+[102 of 217] Compiling Utility.Rsync ( Utility\Rsync.hs, dist\build\git-annex\git-annex-tmp\Utility\Rsync.o )
+[103 of 217] Compiling Utility.LogFile ( Utility\LogFile.hs, dist\build\git-annex\git-annex-tmp\Utility\LogFile.o )
+
+Utility\LogFile.hs:67:1: Warning:
+ Top-level binding with no type signature:
+ redir :: forall t t1 t2. t -> t1 -> t2
+[104 of 217] Compiling Utility.Daemon ( Utility\Daemon.hs, dist\build\git-annex\git-annex-tmp\Utility\Daemon.o )
+
+Utility\Daemon.hs:13:1: Warning:
+ The import of `Utility.LogFile' is redundant
+ except perhaps to import instances from `Utility.LogFile'
+ To import instances alone, use: import Utility.LogFile()
+
+Utility\Daemon.hs:19:1: Warning:
+ The import of `System.Posix.Types' is redundant
+ except perhaps to import instances from `System.Posix.Types'
+ To import instances alone, use: import System.Posix.Types()
+[105 of 217] Compiling Git.AutoCorrect ( Git\AutoCorrect.hs, dist\build\git-annex\git-annex-tmp\Git\AutoCorrect.o )
+[106 of 217] Compiling Utility.ThreadScheduler ( Utility\ThreadScheduler.hs, dist\build\git-annex\git-annex-tmp\Utility\ThreadScheduler.o )
+[107 of 217] Compiling Git.LsTree ( Git\LsTree.hs, dist\build\git-annex\git-annex-tmp\Git\LsTree.o )
+[108 of 217] Compiling Config ( Config.hs, dist\build\git-annex\git-annex-tmp\Config.o )
+[109 of 217] Compiling Annex.UUID ( Annex\UUID.hs, dist\build\git-annex\git-annex-tmp\Annex\UUID.o )
+[110 of 217] Compiling Backend ( Backend.hs, dist\build\git-annex\git-annex-tmp\Backend.o )
+[111 of 217] Compiling Annex.Version ( Annex\Version.hs, dist\build\git-annex\git-annex-tmp\Annex\Version.o )
+[112 of 217] Compiling Annex.Perms ( Annex\Perms.hs, dist\build\git-annex\git-annex-tmp\Annex\Perms.o )
+[113 of 217] Compiling Logs.Transfer ( Logs\Transfer.hs, dist\build\git-annex\git-annex-tmp\Logs\Transfer.o )
+
+Logs\Transfer.hs:126:20: Warning: Defined but not used: `mode'
+
+Logs\Transfer.hs:146:29: Warning: Defined but not used: `fd'
+[114 of 217] Compiling Annex.ReplaceFile ( Annex\ReplaceFile.hs, dist\build\git-annex\git-annex-tmp\Annex\ReplaceFile.o )
+[115 of 217] Compiling Annex.Journal ( Annex\Journal.hs, dist\build\git-annex\git-annex-tmp\Annex\Journal.o )
+
+Annex\Journal.hs:89:23: Warning: Defined but not used: `mode'
+[116 of 217] Compiling Annex.Branch ( Annex\Branch.hs, dist\build\git-annex\git-annex-tmp\Annex\Branch.o )
+[117 of 217] Compiling Logs.Remote ( Logs\Remote.hs, dist\build\git-annex\git-annex-tmp\Logs\Remote.o )
+[118 of 217] Compiling Logs.Presence ( Logs\Presence.hs, dist\build\git-annex\git-annex-tmp\Logs\Presence.o )
+[119 of 217] Compiling Logs.UUID ( Logs\UUID.hs, dist\build\git-annex\git-annex-tmp\Logs\UUID.o )
+[120 of 217] Compiling Logs.Location ( Logs\Location.hs, dist\build\git-annex\git-annex-tmp\Logs\Location.o )
+[121 of 217] Compiling Annex.Content.Direct ( Annex\Content\Direct.hs, dist\build\git-annex\git-annex-tmp\Annex\Content\Direct.o )
+[122 of 217] Compiling Annex.Content ( Annex\Content.hs, dist\build\git-annex\git-annex-tmp\Annex\Content.o )
+
+Annex\Content.hs:50:1: Warning:
+ The import of `Annex.Exception' is redundant
+ except perhaps to import instances from `Annex.Exception'
+ To import instances alone, use: import Annex.Exception()
+
+Annex\Content.hs:89:21: Warning: Defined but not used: `f'
+
+Annex\Content.hs:96:21: Warning: Defined but not used: `h'
+
+Annex\Content.hs:106:9: Warning: Defined but not used: `is_locked'
+
+Annex\Content.hs:113:13: Warning: Defined but not used: `key'
+[123 of 217] Compiling Annex.Direct ( Annex\Direct.hs, dist\build\git-annex\git-annex-tmp\Annex\Direct.o )
+[124 of 217] Compiling Init ( Init.hs, dist\build\git-annex\git-annex-tmp\Init.o )
+
+Init.hs:29:1: Warning:
+ The import of `Utility.UserInfo' is redundant
+ except perhaps to import instances from `Utility.UserInfo'
+ To import instances alone, use: import Utility.UserInfo()
+
+Init.hs:31:1: Warning:
+ The import of `Utility.FileMode' is redundant
+ except perhaps to import instances from `Utility.FileMode'
+ To import instances alone, use: import Utility.FileMode()
+[125 of 217] Compiling Logs.Web ( Logs\Web.hs, dist\build\git-annex\git-annex-tmp\Logs\Web.o )
+[126 of 217] Compiling Logs.Group ( Logs\Group.hs, dist\build\git-annex\git-annex-tmp\Logs\Group.o )
+[127 of 217] Compiling Upgrade.V2 ( Upgrade\V2.hs, dist\build\git-annex\git-annex-tmp\Upgrade\V2.o )
+[128 of 217] Compiling Upgrade ( Upgrade.hs, dist\build\git-annex\git-annex-tmp\Upgrade.o )
+[129 of 217] Compiling Creds ( Creds.hs, dist\build\git-annex\git-annex-tmp\Creds.o )
+
+Creds.hs:18:1: Warning:
+ The import of `Utility.Env' is redundant
+ except perhaps to import instances from `Utility.Env'
+ To import instances alone, use: import Utility.Env()
+[130 of 217] Compiling Remote.Helper.AWS ( Remote\Helper\AWS.hs, dist\build\git-annex\git-annex-tmp\Remote\Helper\AWS.o )
+[131 of 217] Compiling Annex.LockPool ( Annex\LockPool.hs, dist\build\git-annex\git-annex-tmp\Annex\LockPool.o )
+
+Annex\LockPool.hs:17:1: Warning:
+ The import of `Annex.Perms' is redundant
+ except perhaps to import instances from `Annex.Perms'
+ To import instances alone, use: import Annex.Perms()
+
+Annex\LockPool.hs:39:12: Warning: Defined but not used: `fd'
+[132 of 217] Compiling Remote.Helper.Hooks ( Remote\Helper\Hooks.hs, dist\build\git-annex\git-annex-tmp\Remote\Helper\Hooks.o )
+
+Remote\Helper\Hooks.hs:18:1: Warning:
+ The import of `Annex.Perms' is redundant
+ except perhaps to import instances from `Annex.Perms'
+ To import instances alone, use: import Annex.Perms()
+
+Remote\Helper\Hooks.hs:74:17: Warning: Defined but not used: `lck'
+[133 of 217] Compiling Remote.S3 ( Remote\S3.hs, dist\build\git-annex\git-annex-tmp\Remote\S3.o )
+[134 of 217] Compiling Remote.Directory ( Remote\Directory.hs, dist\build\git-annex\git-annex-tmp\Remote\Directory.o )
+[135 of 217] Compiling Remote.Web ( Remote\Web.hs, dist\build\git-annex\git-annex-tmp\Remote\Web.o )
+[136 of 217] Compiling Remote.WebDAV ( Remote\WebDAV.hs, dist\build\git-annex\git-annex-tmp\Remote\WebDAV.o )
+[137 of 217] Compiling Remote.Glacier ( Remote\Glacier.hs, dist\build\git-annex\git-annex-tmp\Remote\Glacier.o )
+[138 of 217] Compiling Remote.Hook ( Remote\Hook.hs, dist\build\git-annex\git-annex-tmp\Remote\Hook.o )
+[139 of 217] Compiling Annex.Ssh ( Annex\Ssh.hs, dist\build\git-annex\git-annex-tmp\Annex\Ssh.o )
+
+Annex\Ssh.hs:21:1: Warning:
+ The import of `Annex.Perms' is redundant
+ except perhaps to import instances from `Annex.Perms'
+ To import instances alone, use: import Annex.Perms()
+[140 of 217] Compiling Remote.Rsync ( Remote\Rsync.hs, dist\build\git-annex\git-annex-tmp\Remote\Rsync.o )
+[141 of 217] Compiling Remote.Helper.Ssh ( Remote\Helper\Ssh.hs, dist\build\git-annex\git-annex-tmp\Remote\Helper\Ssh.o )
+[142 of 217] Compiling Remote.Git ( Remote\Git.hs, dist\build\git-annex\git-annex-tmp\Remote\Git.o )
+
+Remote\Git.hs:20:1: Warning:
+ The import of `Utility.CopyFile' is redundant
+ except perhaps to import instances from `Utility.CopyFile'
+ To import instances alone, use: import Utility.CopyFile()
+
+Remote\Git.hs:360:21: Warning: Defined but not used: `r'
+
+Remote\Git.hs:360:23: Warning: Defined but not used: `key'
+
+Remote\Git.hs:360:27: Warning: Defined but not used: `file'
+[143 of 217] Compiling Remote.Bup ( Remote\Bup.hs, dist\build\git-annex\git-annex-tmp\Remote\Bup.o )
+[144 of 217] Compiling Remote.List ( Remote\List.hs, dist\build\git-annex\git-annex-tmp\Remote\List.o )
+[145 of 217] Compiling Logs.Trust ( Logs\Trust.hs, dist\build\git-annex\git-annex-tmp\Logs\Trust.o )
+[146 of 217] Compiling Remote ( Remote.hs, dist\build\git-annex\git-annex-tmp\Remote.o )
+[147 of 217] Compiling Limit ( Limit.hs, dist\build\git-annex\git-annex-tmp\Limit.o )
+[148 of 217] Compiling Option ( Option.hs, dist\build\git-annex\git-annex-tmp\Option.o )
+[149 of 217] Compiling Annex.FileMatcher ( Annex\FileMatcher.hs, dist\build\git-annex\git-annex-tmp\Annex\FileMatcher.o )
+[150 of 217] Compiling Logs.PreferredContent ( Logs\PreferredContent.hs, dist\build\git-annex\git-annex-tmp\Logs\PreferredContent.o )
+[151 of 217] Compiling Annex.Wanted ( Annex\Wanted.hs, dist\build\git-annex\git-annex-tmp\Annex\Wanted.o )
+[152 of 217] Compiling Seek ( Seek.hs, dist\build\git-annex\git-annex-tmp\Seek.o )
+[153 of 217] Compiling Checks ( Checks.hs, dist\build\git-annex\git-annex-tmp\Checks.o )
+[154 of 217] Compiling Command ( Command.hs, dist\build\git-annex\git-annex-tmp\Command.o )
+[155 of 217] Compiling Logs.Unused ( Logs\Unused.hs, dist\build\git-annex\git-annex-tmp\Logs\Unused.o )
+[156 of 217] Compiling CmdLine ( CmdLine.hs, dist\build\git-annex\git-annex-tmp\CmdLine.o )
+[157 of 217] Compiling Command.ConfigList ( Command\ConfigList.hs, dist\build\git-annex\git-annex-tmp\Command\ConfigList.o )
+[158 of 217] Compiling Command.InAnnex ( Command\InAnnex.hs, dist\build\git-annex\git-annex-tmp\Command\InAnnex.o )
+[159 of 217] Compiling Command.DropKey ( Command\DropKey.hs, dist\build\git-annex\git-annex-tmp\Command\DropKey.o )
+[160 of 217] Compiling Command.SendKey ( Command\SendKey.hs, dist\build\git-annex\git-annex-tmp\Command\SendKey.o )
+[161 of 217] Compiling Command.RecvKey ( Command\RecvKey.hs, dist\build\git-annex\git-annex-tmp\Command\RecvKey.o )
+[162 of 217] Compiling Command.TransferInfo ( Command\TransferInfo.hs, dist\build\git-annex\git-annex-tmp\Command\TransferInfo.o )
+[163 of 217] Compiling Command.Commit ( Command\Commit.hs, dist\build\git-annex\git-annex-tmp\Command\Commit.o )
+[164 of 217] Compiling GitAnnex.Options ( GitAnnex\Options.hs, dist\build\git-annex\git-annex-tmp\GitAnnex\Options.o )
+[165 of 217] Compiling Command.Unannex ( Command\Unannex.hs, dist\build\git-annex\git-annex-tmp\Command\Unannex.o )
+[166 of 217] Compiling Command.FromKey ( Command\FromKey.hs, dist\build\git-annex\git-annex-tmp\Command\FromKey.o )
+[167 of 217] Compiling Command.Fix ( Command\Fix.hs, dist\build\git-annex\git-annex-tmp\Command\Fix.o )
+[168 of 217] Compiling Command.Init ( Command\Init.hs, dist\build\git-annex\git-annex-tmp\Command\Init.o )
+[169 of 217] Compiling Command.Describe ( Command\Describe.hs, dist\build\git-annex\git-annex-tmp\Command\Describe.o )
+[170 of 217] Compiling Command.InitRemote ( Command\InitRemote.hs, dist\build\git-annex\git-annex-tmp\Command\InitRemote.o )
+[171 of 217] Compiling Command.EnableRemote ( Command\EnableRemote.hs, dist\build\git-annex\git-annex-tmp\Command\EnableRemote.o )
+[172 of 217] Compiling Command.Unused ( Command\Unused.hs, dist\build\git-annex\git-annex-tmp\Command\Unused.o )
+[173 of 217] Compiling Command.Unlock ( Command\Unlock.hs, dist\build\git-annex\git-annex-tmp\Command\Unlock.o )
+[174 of 217] Compiling Command.Lock ( Command\Lock.hs, dist\build\git-annex\git-annex-tmp\Command\Lock.o )
+[175 of 217] Compiling Command.Find ( Command\Find.hs, dist\build\git-annex\git-annex-tmp\Command\Find.o )
+[176 of 217] Compiling Command.Whereis ( Command\Whereis.hs, dist\build\git-annex\git-annex-tmp\Command\Whereis.o )
+[177 of 217] Compiling Command.Log ( Command\Log.hs, dist\build\git-annex\git-annex-tmp\Command\Log.o )
+[178 of 217] Compiling Command.Merge ( Command\Merge.hs, dist\build\git-annex\git-annex-tmp\Command\Merge.o )
+[179 of 217] Compiling Command.Uninit ( Command\Uninit.hs, dist\build\git-annex\git-annex-tmp\Command\Uninit.o )
+[180 of 217] Compiling Command.Trust ( Command\Trust.hs, dist\build\git-annex\git-annex-tmp\Command\Trust.o )
+[181 of 217] Compiling Command.Untrust ( Command\Untrust.hs, dist\build\git-annex\git-annex-tmp\Command\Untrust.o )
+[182 of 217] Compiling Command.Semitrust ( Command\Semitrust.hs, dist\build\git-annex\git-annex-tmp\Command\Semitrust.o )
+[183 of 217] Compiling Command.Dead ( Command\Dead.hs, dist\build\git-annex\git-annex-tmp\Command\Dead.o )
+[184 of 217] Compiling Command.Group ( Command\Group.hs, dist\build\git-annex\git-annex-tmp\Command\Group.o )
+[185 of 217] Compiling Command.Content ( Command\Content.hs, dist\build\git-annex\git-annex-tmp\Command\Content.o )
+[186 of 217] Compiling Command.Ungroup ( Command\Ungroup.hs, dist\build\git-annex\git-annex-tmp\Command\Ungroup.o )
+[187 of 217] Compiling Command.Vicfg ( Command\Vicfg.hs, dist\build\git-annex\git-annex-tmp\Command\Vicfg.o )
+[188 of 217] Compiling Command.RmUrl ( Command\RmUrl.hs, dist\build\git-annex\git-annex-tmp\Command\RmUrl.o )
+[189 of 217] Compiling Command.Map ( Command\Map.hs, dist\build\git-annex\git-annex-tmp\Command\Map.o )
+[190 of 217] Compiling Command.Upgrade ( Command\Upgrade.hs, dist\build\git-annex\git-annex-tmp\Command\Upgrade.o )
+[191 of 217] Compiling Command.Version ( Command\Version.hs, dist\build\git-annex\git-annex-tmp\Command\Version.o )
+[192 of 217] Compiling Command.Test ( Command\Test.hs, dist\build\git-annex\git-annex-tmp\Command\Test.o )
+[193 of 217] Compiling Command.Add ( Command\Add.hs, dist\build\git-annex\git-annex-tmp\Command\Add.o )
+[194 of 217] Compiling Command.ReKey ( Command\ReKey.hs, dist\build\git-annex\git-annex-tmp\Command\ReKey.o )
+[195 of 217] Compiling Command.AddUnused ( Command\AddUnused.hs, dist\build\git-annex\git-annex-tmp\Command\AddUnused.o )
+[196 of 217] Compiling Command.PreCommit ( Command\PreCommit.hs, dist\build\git-annex\git-annex-tmp\Command\PreCommit.o )
+[197 of 217] Compiling Command.Import ( Command\Import.hs, dist\build\git-annex\git-annex-tmp\Command\Import.o )
+[198 of 217] Compiling Command.Drop ( Command\Drop.hs, dist\build\git-annex\git-annex-tmp\Command\Drop.o )
+[199 of 217] Compiling Command.Move ( Command\Move.hs, dist\build\git-annex\git-annex-tmp\Command\Move.o )
+[200 of 217] Compiling Command.Copy ( Command\Copy.hs, dist\build\git-annex\git-annex-tmp\Command\Copy.o )
+[201 of 217] Compiling Command.Get ( Command\Get.hs, dist\build\git-annex\git-annex-tmp\Command\Get.o )
+[202 of 217] Compiling Command.TransferKey ( Command\TransferKey.hs, dist\build\git-annex\git-annex-tmp\Command\TransferKey.o )
+[203 of 217] Compiling Command.DropUnused ( Command\DropUnused.hs, dist\build\git-annex\git-annex-tmp\Command\DropUnused.o )
+[204 of 217] Compiling Command.Fsck ( Command\Fsck.hs, dist\build\git-annex\git-annex-tmp\Command\Fsck.o )
+[205 of 217] Compiling Command.Reinject ( Command\Reinject.hs, dist\build\git-annex\git-annex-tmp\Command\Reinject.o )
+[206 of 217] Compiling Command.Migrate ( Command\Migrate.hs, dist\build\git-annex\git-annex-tmp\Command\Migrate.o )
+[207 of 217] Compiling Command.Status ( Command\Status.hs, dist\build\git-annex\git-annex-tmp\Command\Status.o )
+[208 of 217] Compiling Command.Sync ( Command\Sync.hs, dist\build\git-annex\git-annex-tmp\Command\Sync.o )
+[209 of 217] Compiling Command.Help ( Command\Help.hs, dist\build\git-annex\git-annex-tmp\Command\Help.o )
+[210 of 217] Compiling Command.AddUrl ( Command\AddUrl.hs, dist\build\git-annex\git-annex-tmp\Command\AddUrl.o )
+[211 of 217] Compiling Command.Direct ( Command\Direct.hs, dist\build\git-annex\git-annex-tmp\Command\Direct.o )
+[212 of 217] Compiling Command.Indirect ( Command\Indirect.hs, dist\build\git-annex\git-annex-tmp\Command\Indirect.o )
+[213 of 217] Compiling Command.FuzzTest ( Command\FuzzTest.hs, dist\build\git-annex\git-annex-tmp\Command\FuzzTest.o )
+[214 of 217] Compiling Test ( Test.hs, dist\build\git-annex\git-annex-tmp\Test.o )
+[215 of 217] Compiling GitAnnexShell ( GitAnnexShell.hs, dist\build\git-annex\git-annex-tmp\GitAnnexShell.o )
+[216 of 217] Compiling GitAnnex ( GitAnnex.hs, dist\build\git-annex\git-annex-tmp\GitAnnex.o )
+[217 of 217] Compiling Main ( git-annex.hs, dist\build\git-annex\git-annex-tmp\Main.o )
+Linking dist\build\git-annex\git-annex.exe ...
++ cabal install nsis
+Resolving dependencies...
+All the requested packages are already installed:
+nsis-0.2.2
+Use --reinstall if you want to reinstall anyway.
++ ghc --make Build/NullSoftInstaller.hs
+[15 of 18] Compiling Build.SysConfig ( Build\SysConfig.hs, Build\SysConfig.o )
+Linking Build\NullSoftInstaller.exe ...
++ withcyg Build/NullSoftInstaller.exe
++ PATH='/c/Program Files (x86)/Haskell Platform/2012.4.0.0/bin:/c/Program Files (x86)/Haskell Platform/2012.4.0.0/lib/extralibs/bin:/c/Program Files (x86)/NSIS:/home/Oliver/bin:.:/usr/local/bin:/mingw/bin:/bin:/c/Program Files (x86)/Haskell/bin:/c/Program Files (x86)/Haskell Platform/2013.2.0.0/lib/extralibs/bin:/c/Program Files (x86)/Haskell Platform/2013.2.0.0/bin:/c/Program Files (x86)/AMD APP/bin/x86_64:/c/Program Files (x86)/AMD APP/bin/x86:/c/Windows/system32:/c/Windows:/c/Windows/System32/Wbem:/c/Windows/System32/WindowsPowerShell/v1.0/:/c/Program Files (x86)/ATI Technologies/ATI.ACE/Core-Static:/c/Program Files (x86)/Windows Kits/8.0/Windows Performance Toolkit/:/c/Program Files/Microsoft/Web Platform Installer/:/c/Program Files (x86)/Haskell Platform/2013.2.0.0/mingw/bin:/c/Users/Oliver/AppData/Roaming/cabal/bin:/c/cygwin/bin'
++ Build/NullSoftInstaller.exe
+MakeNSIS v2.46 - Copyright 1995-2009 Contributors
+See the file COPYING for license details.
+Credits can be found in the Users Manual.
+
+Processing config:
+Processing plugin dlls: "c:\Program Files (x86)\NSIS\Plugins\*.dll"
+ - AdvSplash::show
+ - Banner::destroy
+ - Banner::getWindow
+ - Banner::show
+ - BgImage::AddImage
+ - BgImage::AddText
+ - BgImage::Clear
+ - BgImage::Destroy
+ - BgImage::Redraw
+ - BgImage::SetBg
+ - BgImage::SetReturn
+ - BgImage::Sound
+ - Dialer::AttemptConnect
+ - Dialer::AutodialHangup
+ - Dialer::AutodialOnline
+ - Dialer::AutodialUnattended
+ - Dialer::GetConnectedState
+ - InstallOptions::dialog
+ - InstallOptions::initDialog
+ - InstallOptions::show
+ - LangDLL::LangDialog
+ - Math::Script
+ - NSISdl::download
+ - NSISdl::download_quiet
+ - Splash::show
+ - StartMenu::Init
+ - StartMenu::Select
+ - StartMenu::Show
+ - System::Alloc
+ - System::Call
+ - System::Copy
+ - System::Free
+ - System::Get
+ - System::Int64Op
+ - System::Store
+ - TypeLib::GetLibVersion
+ - TypeLib::Register
+ - TypeLib::UnRegister
+ - UserInfo::GetAccountType
+ - UserInfo::GetName
+ - UserInfo::GetOriginalAccountType
+ - VPatch::GetFileCRC32
+ - VPatch::GetFileMD5
+ - VPatch::vpatchfile
+ - nsDialogs::Create
+ - nsDialogs::CreateControl
+ - nsDialogs::CreateItem
+ - nsDialogs::CreateTimer
+ - nsDialogs::GetUserData
+ - nsDialogs::KillTimer
+ - nsDialogs::OnBack
+ - nsDialogs::OnChange
+ - nsDialogs::OnClick
+ - nsDialogs::OnNotify
+ - nsDialogs::SelectFileDialog
+ - nsDialogs::SelectFolderDialog
+ - nsDialogs::SetRTL
+ - nsDialogs::SetUserData
+ - nsDialogs::Show
+ - nsExec::Exec
+ - nsExec::ExecToLog
+ - nsExec::ExecToStack
+
+!define: "MUI_INSERT_NSISCONF"=""
+
+Changing directory to: "C:\MinGW\msys\1.0\home\Oliver\src\git-annex"
+
+Processing script file: "git-annex.nsi"
+!include: "c:\Program Files (x86)\NSIS\Include\MUI2.nsh"
+!include: "c:\Program Files (x86)\NSIS\Contrib\Modern UI 2\MUI2.nsh"
+NSIS Modern User Interface version 2.0 - Copyright 2002-2009 Joost Verburg (c:\Program Files (x86)\NSIS\Contrib\Modern UI 2\MUI2.nsh:8)
+!define: "MUI_INCLUDED"=""
+!define: "MUI_SYSVERSION"="2.0"
+!define: "MUI_VERBOSE"="3"
+!include: closed: "c:\Program Files (x86)\NSIS\Contrib\Modern UI 2\MUI2.nsh"
+!include: closed: "c:\Program Files (x86)\NSIS\Include\MUI2.nsh"
+Name: "git-annex"
+OutFile: "git-annex-installer.exe"
+InstallDir: "$PROGRAMFILES\Git\cmd"
+!insertmacro: MUI_PAGE_DIRECTORY
+!insertmacro: end of MUI_PAGE_DIRECTORY
+!insertmacro: MUI_PAGE_LICENSE
+!insertmacro: end of MUI_PAGEDECLARATION_LICENSE
+!insertmacro: end of MUI_PAGE_LICENSE
+!insertmacro: MUI_PAGE_INSTFILES
+!insertmacro: end of MUI_PAGE_INSTFILES
+!insertmacro: MUI_LANGUAGE
+!insertmacro: end of MUI_LANGUAGE
+Section: "main" ->(_sec10)
+SetOutPath: "$INSTDIR"
+File: "git-annex.exe" [compress] 7664822/31704766 bytes
+File: "git-annex-licenses.txt" [compress] 60509/237415 bytes
+File: "cp.exe" [compress] 62591/116736 bytes
+File: "xargs.exe" [compress] 17002/33280 bytes
+File: "rsync.exe" [compress] 188346/359424 bytes
+File: "ssh.exe" [compress] 157190/320000 bytes
+File: "wget.exe" [compress] 155666/349184 bytes
+File: "sha1sum.exe" [compress] 20337/39424 bytes
+File: "sha256sum.exe" [compress] 18279/37390 bytes
+File: "sha512sum.exe" [compress] 30393/92174 bytes
+File: "sha224sum.exe" [compress] 18279/37390 bytes
+File: "sha384sum.exe" [compress] 30392/92174 bytes
+File: "cygwin1.dll" [compress] 1036075/2874639 bytes
+File: "cygasn1-8.dll" [compress] 154881/459293 bytes
+File: "cygattr-1.dll" [compress] 5460/13838 bytes
+File: "cygheimbase-1.dll" [compress] 4441/10781 bytes
+File: "cygroken-18.dll" [compress] 26103/52253 bytes
+File: "cygcom_err-2.dll" [compress] 3984/9757 bytes
+File: "cygheimntlm-0.dll" [compress] 9018/20509 bytes
+File: "cygsqlite3-0.dll" [compress] 334366/601629 bytes
+File: "cygcrypt-0.dll" [compress] 3352/7182 bytes
+File: "cyghx509-5.dll" [compress] 95839/216093 bytes
+File: "cygssp-0.dll" [compress] 3377/8206 bytes
+File: "cygcrypto-1.0.0.dll" [compress] 652766/1553920 bytes
+File: "cygiconv-2.dll" [compress] 738899/1008654 bytes
+File: "cyggcc_s-1.dll" [compress] 40241/80910 bytes
+File: "cygintl-8.dll" [compress] 17737/35342 bytes
+File: "cygwind-0.dll" [compress] 73172/160797 bytes
+File: "cyggssapi-3.dll" [compress] 81662/183837 bytes
+File: "cygkrb5-26.dll" [compress] 170204/381469 bytes
+File: "cygz.dll" [compress] 42634/74269 bytes
+WriteUninstaller: "git-annex-uninstall.exe"
+SectionEnd
+Section: "Uninstall" ->(_sec11)
+Delete: /REBOOTOK "$INSTDIR\git-annex.exe"
+Delete: /REBOOTOK "$INSTDIR\git-annex-licenses.txt"
+Delete: /REBOOTOK "$INSTDIR\git-annex-uninstall.exe"
+Delete: /REBOOTOK "$INSTDIR\cp.exe"
+Delete: /REBOOTOK "$INSTDIR\xargs.exe"
+Delete: /REBOOTOK "$INSTDIR\rsync.exe"
+Delete: /REBOOTOK "$INSTDIR\ssh.exe"
+Delete: /REBOOTOK "$INSTDIR\wget.exe"
+Delete: /REBOOTOK "$INSTDIR\sha1sum.exe"
+Delete: /REBOOTOK "$INSTDIR\sha256sum.exe"
+Delete: /REBOOTOK "$INSTDIR\sha512sum.exe"
+Delete: /REBOOTOK "$INSTDIR\sha224sum.exe"
+Delete: /REBOOTOK "$INSTDIR\sha384sum.exe"
+Delete: /REBOOTOK "$INSTDIR\cygwin1.dll"
+Delete: /REBOOTOK "$INSTDIR\cygasn1-8.dll"
+Delete: /REBOOTOK "$INSTDIR\cygattr-1.dll"
+Delete: /REBOOTOK "$INSTDIR\cygheimbase-1.dll"
+Delete: /REBOOTOK "$INSTDIR\cygroken-18.dll"
+Delete: /REBOOTOK "$INSTDIR\cygcom_err-2.dll"
+Delete: /REBOOTOK "$INSTDIR\cygheimntlm-0.dll"
+Delete: /REBOOTOK "$INSTDIR\cygsqlite3-0.dll"
+Delete: /REBOOTOK "$INSTDIR\cygcrypt-0.dll"
+Delete: /REBOOTOK "$INSTDIR\cyghx509-5.dll"
+Delete: /REBOOTOK "$INSTDIR\cygssp-0.dll"
+Delete: /REBOOTOK "$INSTDIR\cygcrypto-1.0.0.dll"
+Delete: /REBOOTOK "$INSTDIR\cygiconv-2.dll"
+Delete: /REBOOTOK "$INSTDIR\cyggcc_s-1.dll"
+Delete: /REBOOTOK "$INSTDIR\cygintl-8.dll"
+Delete: /REBOOTOK "$INSTDIR\cygwind-0.dll"
+Delete: /REBOOTOK "$INSTDIR\cyggssapi-3.dll"
+Delete: /REBOOTOK "$INSTDIR\cygkrb5-26.dll"
+Delete: /REBOOTOK "$INSTDIR\cygz.dll"
+SectionEnd
+Function: ".onInit"
+IfFileExists: "$PROGRAMFILES\Git\cmd" ? _lbl3 : 0
+MessageBox: 48: "You need git installed to use git-annex. Looking at $PROGRAMFILES\Git\cmd , it seems to not be installed, or may be installed in another location. You can install git from http://git-scm.com/" (on IDOK goto 0)
+FunctionEnd
+
+Processed 1 file, writing output:
+Processing pages... Done!
+Removing unused resources... Done!
+Generating language tables... Done!
+Generating uninstaller... Done!
+
+Output: "C:\MinGW\msys\1.0\home\Oliver\src\git-annex\git-annex-installer.exe"
+Install: 4 pages (256 bytes), 1 section (1048 bytes), 98 instructions (2744 bytes), 133 strings (239643 bytes), 1 language table (278 bytes).
+Uninstall: 2 pages (128 bytes),
+1 section (1048 bytes), 33 instructions (924 bytes), 72 strings (1154 bytes), 1 language table (194 bytes).
+
+Using zlib compression.
+
+EXE header size: 48640 / 35840 bytes
+Install code: 63270 / 244345 bytes
+Install data: 11918141 / 41172867 bytes
+Uninstall code+data: 10537 / 14897 bytes
+CRC (0x090A4FD3): 4 / 4 bytes
+
+Total size: 12040592 / 41467953 bytes (29.0%)
++ rm -f last-incremental-failed
++ rm -rf .t
++ withcyg dist/build/git-annex/git-annex.exe test
++ PATH='/c/Program Files (x86)/Haskell Platform/2012.4.0.0/bin:/c/Program Files (x86)/Haskell Platform/2012.4.0.0/lib/extralibs/bin:/c/Program Files (x86)/NSIS:/home/Oliver/bin:.:/usr/local/bin:/mingw/bin:/bin:/c/Program Files (x86)/Haskell/bin:/c/Program Files (x86)/Haskell Platform/2013.2.0.0/lib/extralibs/bin:/c/Program Files (x86)/Haskell Platform/2013.2.0.0/bin:/c/Program Files (x86)/AMD APP/bin/x86_64:/c/Program Files (x86)/AMD APP/bin/x86:/c/Windows/system32:/c/Windows:/c/Windows/System32/Wbem:/c/Windows/System32/WindowsPowerShell/v1.0/:/c/Program Files (x86)/ATI Technologies/ATI.ACE/Core-Static:/c/Program Files (x86)/Windows Kits/8.0/Windows Performance Toolkit/:/c/Program Files/Microsoft/Web Platform Installer/:/c/Program Files (x86)/Haskell Platform/2013.2.0.0/mingw/bin:/c/Users/Oliver/AppData/Roaming/cabal/bin:/c/cygwin/bin'
++ dist/build/git-annex/git-annex.exe test
+(0 tests) (1 test) (2 tests) (3 tests) (4 tests) (5 tests) (6 tests) (7 tests) (8 tests) (9 tests) (10 tests) (11 tests) (12 tests) (13 tests) (14 tests) (15 tests) (16 tests) (17 tests) (18 tests) (19 tests) (20 tests) (21 tests) (22 tests) (23 tests) (24 tests) (25 tests) (26 tests) (27 tests) (28 tests) (29 tests) (30 tests) (31 tests) (32 tests) (33 tests) (34 tests) (35 tests) (36 tests) (37 tests) (38 tests) (39 tests) (40 tests) (41 tests) (42 tests) (43 tests) (44 tests) (45 tests) (46 tests) (47 tests) (48 tests) (49 tests) (50 tests) (51 tests) (52 tests) (53 tests) (54 tests) (55 tests) (56 tests) (57 tests) (58 tests) (59 tests) (60 tests) (61 tests) (62 tests) (63 tests) (64 tests) (65 tests) (66 tests) (67 tests) (68 tests) (69 tests) (70 tests) (71 tests) (72 tests) (73 tests) (74 tests) (75 tests) (76 tests) (77 tests) (78 tests) (79 tests) (80 tests) (81 tests) (82 tests) (83 tests) (84 tests) (85 tests) (86 tests) (87 tests) (88 tests) (89 tests) (90 tests) (91 tests) (92 tests) (93 tests) (94 tests) (95 tests) (96 tests) (97 tests) (98 tests) (99 tests) ----------------------------------------------------------------------
+First, some automated quick checks of properties ...
+----------------------------------------------------------------------
+prop_idempotent_deencode_git
++++ OK, passed 100 tests.
+(0 tests) (1 test) (2 tests) (3 tests) (4 tests) (5 tests) (6 tests) (7 tests) (8 tests) (9 tests) (10 tests) (11 tests) (12 tests) (13 tests) (14 tests) (15 tests) (16 tests) (17 tests) (18 tests) (19 tests) (20 tests) (21 tests) (22 tests) (23 tests) (24 tests) (25 tests) (26 tests) (27 tests) (28 tests) (29 tests) (30 tests) (31 tests) (32 tests) (33 tests) (34 tests) (35 tests) (36 tests) (37 tests) (38 tests) (39 tests) (40 tests) (41 tests) (42 tests) (43 tests) (44 tests) (45 tests) (46 tests) (47 tests) (48 tests) (49 tests) (50 tests) (51 tests) (52 tests) (53 tests) (54 tests) (55 tests) (56 tests) (57 tests) (58 tests) (59 tests) (60 tests) (61 tests) (62 tests) (63 tests) (64 tests) (65 tests) (66 tests) (67 tests) (68 tests) (69 tests) (70 tests) (71 tests) (72 tests) (73 tests) (74 tests) (75 tests) (76 tests) (77 tests) (78 tests) (79 tests) (80 tests) (81 tests) (82 tests) (83 tests) (84 tests) (85 tests) (86 tests) (87 tests) (88 tests) (89 tests) (90 tests) (91 tests) (92 tests) (93 tests) (94 tests) (95 tests) (96 tests) (97 tests) (98 tests) (99 tests) prop_idempotent_deencode
++++ OK, passed 100 tests.
+(0 tests) (1 test) (2 tests) (3 tests) (4 tests) (5 tests) (6 tests) (7 tests) (8 tests) (9 tests) (10 tests) (11 tests) (12 tests) (13 tests) (14 tests) (15 tests) (16 tests) (17 tests) (18 tests) (19 tests) (20 tests) (21 tests) (22 tests) (23 tests) (24 tests) (25 tests) (26 tests) (27 tests) (28 tests) (29 tests) (30 tests) (31 tests) (32 tests) (33 tests) (34 tests) (35 tests) (36 tests) (37 tests) (38 tests) (39 tests) (40 tests) (41 tests) (42 tests) (43 tests) (44 tests) (45 tests) (46 tests) (47 tests) (48 tests) (49 tests) (50 tests) (51 tests) (52 tests) (53 tests) (54 tests) (55 tests) (56 tests) (57 tests) (58 tests) (59 tests) (60 tests) (61 tests) (62 tests) (63 tests) (64 tests) (65 tests) (66 tests) (67 tests) (68 tests) (69 tests) (70 tests) (71 tests) (72 tests) (73 tests) (74 tests) (75 tests) (76 tests) (77 tests) (78 tests) (79 tests) (80 tests) (81 tests) (82 tests) (83 tests) (84 tests) (85 tests) (86 tests) (87 tests) (88 tests) (89 tests) (90 tests) (91 tests) (92 tests) (93 tests) (94 tests) (95 tests) (96 tests) (97 tests) (98 tests) (99 tests) prop_idempotent_fileKey
++++ OK, passed 100 tests.
+(0 tests) (1 test) (2 tests) (3 tests) (4 tests) (5 tests) (6 tests) (7 tests) (8 tests) (9 tests) (10 tests) (11 tests) (12 tests) (13 tests) (14 tests) (15 tests) (16 tests) (17 tests) (18 tests) (19 tests) (20 tests) (21 tests) (22 tests) (23 tests) (24 tests) (25 tests) (26 tests) (27 tests) (28 tests) (29 tests) (30 tests) (31 tests) (32 tests) (33 tests) (34 tests) (35 tests) (36 tests) (37 tests) (38 tests) (39 tests) (40 tests) (41 tests) (42 tests) (43 tests) (44 tests) (45 tests) (46 tests) (47 tests) (48 tests) (49 tests) (50 tests) (51 tests) (52 tests) (53 tests) (54 tests) (55 tests) (56 tests) (57 tests) (58 tests) (59 tests) (60 tests) (61 tests) (62 tests) (63 tests) (64 tests) (65 tests) (66 tests) (67 tests) (68 tests) (69 tests) (70 tests) (71 tests) (72 tests) (73 tests) (74 tests) (75 tests) (76 tests) (77 tests) (78 tests) (79 tests) (80 tests) (81 tests) (82 tests) (83 tests) (84 tests) (85 tests) (86 tests) (87 tests) (88 tests) (89 tests) (90 tests) (91 tests) (92 tests) (93 tests) (94 tests) (95 tests) (96 tests) (97 tests) (98 tests) (99 tests) prop_idempotent_key_encode
++++ OK, passed 100 tests.
+(0 tests) (1 test) (2 tests) (3 tests) (4 tests) (5 tests) (6 tests) (7 tests) (8 tests) (9 tests) (10 tests) (11 tests) (12 tests) (13 tests) (14 tests) (15 tests) (16 tests) (17 tests) (18 tests) (19 tests) (20 tests) (21 tests) (22 tests) (23 tests) (24 tests) (25 tests) (26 tests) (27 tests) (28 tests) (29 tests) (30 tests) (31 tests) (32 tests) (33 tests) (34 tests) (35 tests) (36 tests) (37 tests) (38 tests) (39 tests) (40 tests) (41 tests) (42 tests) (43 tests) (44 tests) (45 tests) (46 tests) (47 tests) (48 tests) (49 tests) (50 tests) (51 tests) (52 tests) (53 tests) (54 tests) (55 tests) (56 tests) (57 tests) (58 tests) (59 tests) (60 tests) (61 tests) (62 tests) (63 tests) (64 tests) (65 tests) (66 tests) (67 tests) (68 tests) (69 tests) (70 tests) (71 tests) (72 tests) (73 tests) (74 tests) (75 tests) (76 tests) (77 tests) (78 tests) (79 tests) (80 tests) (81 tests) (82 tests) (83 tests) (84 tests) (85 tests) (86 tests) (87 tests) (88 tests) (89 tests) (90 tests) (91 tests) (92 tests) (93 tests) (94 tests) (95 tests) (96 tests) (97 tests) (98 tests) (99 tests) prop_idempotent_shellEscape
++++ OK, passed 100 tests.
+(0 tests) (1 test) (2 tests) (3 tests) (4 tests) (5 tests) (6 tests) (7 tests) (8 tests) (9 tests) (10 tests) (11 tests) (12 tests) (13 tests) (14 tests) (15 tests) (16 tests) (17 tests) (18 tests) (19 tests) (20 tests) (21 tests) (22 tests) (23 tests) (24 tests) (25 tests) (26 tests) (27 tests) (28 tests) (29 tests) (30 tests) (31 tests) (32 tests) (33 tests) (34 tests) (35 tests) (36 tests) (37 tests) (38 tests) (39 tests) (40 tests) (41 tests) (42 tests) (43 tests) (44 tests) (45 tests) (46 tests) (47 tests) (48 tests) (49 tests) (50 tests) (51 tests) (52 tests) (53 tests) (54 tests) (55 tests) (56 tests) (57 tests) (58 tests) (59 tests) (60 tests) (61 tests) (62 tests) (63 tests) (64 tests) (65 tests) (66 tests) (67 tests) (68 tests) (69 tests) (70 tests) (71 tests) (72 tests) (73 tests) (74 tests) (75 tests) (76 tests) (77 tests) (78 tests) (79 tests) (80 tests) (81 tests) (82 tests) (83 tests) (84 tests) (85 tests) (86 tests) (87 tests) (88 tests) (89 tests) (90 tests) (91 tests) (92 tests) (93 tests) (94 tests) (95 tests) (96 tests) (97 tests) (98 tests) (99 tests) prop_idempotent_shellEscape_multiword
++++ OK, passed 100 tests.
+(0 tests) (1 test) (2 tests) (3 tests) (4 tests) (5 tests) (6 tests) (7 tests) (8 tests) (9 tests) (10 tests) (11 tests) (12 tests) (13 tests) (14 tests) (15 tests) (16 tests) (17 tests) (18 tests) (19 tests) (20 tests) (21 tests) (22 tests) (23 tests) (24 tests) (25 tests) (26 tests) (27 tests) (28 tests) (29 tests) (30 tests) (31 tests) (32 tests) (33 tests) (34 tests) (35 tests) (36 tests) (37 tests) (38 tests) (39 tests) (40 tests) (41 tests) (42 tests) (43 tests) (44 tests) (45 tests) (46 tests) (47 tests) (48 tests) (49 tests) (50 tests) (51 tests) (52 tests) (53 tests) (54 tests) (55 tests) (56 tests) (57 tests) (58 tests) (59 tests) (60 tests) (61 tests) (62 tests) (63 tests) (64 tests) (65 tests) (66 tests) (67 tests) (68 tests) (69 tests) (70 tests) (71 tests) (72 tests) (73 tests) (74 tests) (75 tests) (76 tests) (77 tests) (78 tests) (79 tests) (80 tests) (81 tests) (82 tests) (83 tests) (84 tests) (85 tests) (86 tests) (87 tests) (88 tests) (89 tests) (90 tests) (91 tests) (92 tests) (93 tests) (94 tests) (95 tests) (96 tests) (97 tests) (98 tests) (99 tests) prop_idempotent_configEscape
++++ OK, passed 100 tests.
+(0 tests) (1 test) (2 tests) (3 tests) (4 tests) (5 tests) (6 tests) (7 tests) (8 tests) (9 tests) (10 tests) (11 tests) (12 tests) (13 tests) (14 tests) (15 tests) (16 tests) (17 tests) (18 tests) (19 tests) (20 tests) (21 tests) (22 tests) (23 tests) (24 tests) (25 tests) (26 tests) (27 tests) (28 tests) (29 tests) (30 tests) (31 tests) (32 tests) (33 tests) (34 tests) (35 tests) (36 tests) (37 tests) (38 tests) (39 tests) (40 tests) (41 tests) (42 tests) (43 tests) (44 tests) (45 tests) (46 tests) (47 tests) (48 tests) (49 tests) (50 tests) (51 tests) (52 tests) (53 tests) (54 tests) (55 tests) (56 tests) (57 tests) (58 tests) (59 tests) (60 tests) (61 tests) (62 tests) (63 tests) (64 tests) (65 tests) (66 tests) (67 tests) (68 tests) (69 tests) (70 tests) (71 tests) (72 tests) (73 tests) (74 tests) (75 tests) (76 tests) (77 tests) (78 tests) (79 tests) (80 tests) (81 tests) (82 tests) (83 tests) (84 tests) (85 tests) (86 tests) (87 tests) (88 tests) (89 tests) (90 tests) (91 tests) (92 tests) (93 tests) (94 tests) (95 tests) (96 tests) (97 tests) (98 tests) (99 tests) prop_parse_show_Config
++++ OK, passed 100 tests.
+(0 tests) (1 test) (2 tests) (3 tests) (4 tests) (5 tests) (6 tests) (7 tests) (8 tests) (9 tests) (10 tests) (11 tests) (12 tests) (13 tests) (14 tests) (15 tests) (16 tests) (17 tests) (18 tests) (19 tests) (20 tests) (21 tests) (22 tests) (23 tests) (24 tests) (25 tests) (26 tests) (27 tests) (28 tests) (29 tests) (30 tests) (31 tests) (32 tests) (33 tests) (34 tests) (35 tests) (36 tests) (37 tests) (38 tests) (39 tests) (40 tests) (41 tests) (42 tests) (43 tests) (44 tests) (45 tests) (46 tests) (47 tests) (48 tests) (49 tests) (50 tests) (51 tests) (52 tests) (53 tests) (54 tests) (55 tests) (56 tests) (57 tests) (58 tests) (59 tests) (60 tests) (61 tests) (62 tests) (63 tests) (64 tests) (65 tests) (66 tests) (67 tests) (68 tests) (69 tests) (70 tests) (71 tests) (72 tests) (73 tests) (74 tests) (75 tests) (76 tests) (77 tests) (78 tests) (79 tests) (80 tests) (81 tests) (82 tests) (83 tests) (84 tests) (85 tests) (86 tests) (87 tests) (88 tests) (89 tests) (90 tests) (91 tests) (92 tests) (93 tests) (94 tests) (95 tests) (96 tests) (97 tests) (98 tests) (99 tests) prop_parentDir_basics
++++ OK, passed 100 tests.
+(0 tests) (1 test) (2 tests) (3 tests) (4 tests) (5 tests) (6 tests) (7 tests) (8 tests) (9 tests) (10 tests) (11 tests) (12 tests) (13 tests) (14 tests) (15 tests) (16 tests) (17 tests) (18 tests) (19 tests) (20 tests) (21 tests) (22 tests) (23 tests) (24 tests) (25 tests) (26 tests) (27 tests) (28 tests) (29 tests) (30 tests) (31 tests) (32 tests) (33 tests) (34 tests) (35 tests) (36 tests) (37 tests) (38 tests) (39 tests) (40 tests) (41 tests) (42 tests) (43 tests) (44 tests) (45 tests) (46 tests) (47 tests) (48 tests) (49 tests) (50 tests) (51 tests) (52 tests) (53 tests) (54 tests) (55 tests) (56 tests) (57 tests) (58 tests) (59 tests) (60 tests) (61 tests) (62 tests) (63 tests) (64 tests) (65 tests) (66 tests) (67 tests) (68 tests) (69 tests) (70 tests) (71 tests) (72 tests) (73 tests) (74 tests) (75 tests) (76 tests) (77 tests) (78 tests) (79 tests) (80 tests) (81 tests) (82 tests) (83 tests) (84 tests) (85 tests) (86 tests) (87 tests) (88 tests) (89 tests) (90 tests) (91 tests) (92 tests) (93 tests) (94 tests) (95 tests) (96 tests) (97 tests) (98 tests) (99 tests) prop_relPathDirToFile_basics
++++ OK, passed 100 tests.
+(0 tests) prop_relPathDirToFile_regressionTest
++++ OK, passed 1 tests.
+(0 tests) prop_cost_sane
++++ OK, passed 1 tests.
+(0 tests) prop_matcher_sane
++++ OK, passed 1 tests.
+(0 tests) prop_HmacSha1WithCipher_sane
++++ OK, passed 1 tests.
+(0 tests) prop_TimeStamp_sane
++++ OK, passed 1 tests.
+(0 tests) prop_addLog_sane
++++ OK, passed 1 tests.
+(0 tests) (1 test) (2 tests) (3 tests) (4 tests) (5 tests) (6 tests) (7 tests) (8 tests) (9 tests) (10 tests) (11 tests) (12 tests) (13 tests) (14 tests) (15 tests) (16 tests) (17 tests) (18 tests) (19 tests) (20 tests) (21 tests) (22 tests) (23 tests) (24 tests) (25 tests) (26 tests) (27 tests) (28 tests) (29 tests) (30 tests) (31 tests) (32 tests) (33 tests) (34 tests) (35 tests) (36 tests) (37 tests) (38 tests) (39 tests) (40 tests) (41 tests) (42 tests) (43 tests) (44 tests) (45 tests) (46 tests) (47 tests) (48 tests) (49 tests) (50 tests) (51 tests) (52 tests) (53 tests) (54 tests) (55 tests) (56 tests) (57 tests) (58 tests) (59 tests) (60 tests) (61 tests) (62 tests) (63 tests) (64 tests) (65 tests) (66 tests) (67 tests) (68 tests) (69 tests) (70 tests) (71 tests) (72 tests) (73 tests) (74 tests) (75 tests) (76 tests) (77 tests) (78 tests) (79 tests) (80 tests) (81 tests) (82 tests) (83 tests) (84 tests) (85 tests) (86 tests) (87 tests) (88 tests) (89 tests) (90 tests) (91 tests) (92 tests) (93 tests) (94 tests) (95 tests) (96 tests) (97 tests) (98 tests) (99 tests) prop_verifiable_sane
++++ OK, passed 100 tests.
+(0 tests) prop_segment_regressionTest
++++ OK, passed 1 tests.
+(0 tests) (1 test) (2 tests) (3 tests) (4 tests) (5 tests) (6 tests) (7 tests) (8 tests) (9 tests) (10 tests) (11 tests) (12 tests) (13 tests) (14 tests) (15 tests) (16 tests) (17 tests) (18 tests) (19 tests) (20 tests) (21 tests) (22 tests) (23 tests) (24 tests) (25 tests) (26 tests) (27 tests) (28 tests) (29 tests) (30 tests) (31 tests) (32 tests) (33 tests) (34 tests) (35 tests) (36 tests) (37 tests) (38 tests) (39 tests) (40 tests) (41 tests) (42 tests) (43 tests) (44 tests) (45 tests) (46 tests) (47 tests) (48 tests) (49 tests) (50 tests) (51 tests) (52 tests) (53 tests) (54 tests) (55 tests) (56 tests) (57 tests) (58 tests) (59 tests) (60 tests) (61 tests) (62 tests) (63 tests) (64 tests) (65 tests) (66 tests) (67 tests) (68 tests) (69 tests) (70 tests) (71 tests) (72 tests) (73 tests) (74 tests) (75 tests) (76 tests) (77 tests) (78 tests) (79 tests) (80 tests) (81 tests) (82 tests) (83 tests) (84 tests) (85 tests) (86 tests) (87 tests) (88 tests) (89 tests) (90 tests) (91 tests) (92 tests) (93 tests) (94 tests) (95 tests) (96 tests) (97 tests) (98 tests) (99 tests) prop_read_write_transferinfo
++++ OK, passed 100 tests.
+(0 tests) (1 test) (2 tests) (3 tests) (4 tests) (5 tests) (6 tests) (7 tests) (8 tests) (9 tests) (10 tests) (11 tests) (12 tests) (13 tests) (14 tests) (15 tests) (16 tests) (17 tests) (18 tests) (19 tests) (20 tests) (21 tests) (22 tests) (23 tests) (24 tests) (25 tests) (26 tests) (27 tests) (28 tests) (29 tests) (30 tests) (31 tests) (32 tests) (33 tests) (34 tests) (35 tests) (36 tests) (37 tests) (38 tests) (39 tests) (40 tests) (41 tests) (42 tests) (43 tests) (44 tests) (45 tests) (46 tests) (47 tests) (48 tests) (49 tests) (50 tests) (51 tests) (52 tests) (53 tests) (54 tests) (55 tests) (56 tests) (57 tests) (58 tests) (59 tests) (60 tests) (61 tests) (62 tests) (63 tests) (64 tests) (65 tests) (66 tests) (67 tests) (68 tests) (69 tests) (70 tests) (71 tests) (72 tests) (73 tests) (74 tests) (75 tests) (76 tests) (77 tests) (78 tests) (79 tests) (80 tests) (81 tests) (82 tests) (83 tests) (84 tests) (85 tests) (86 tests) (87 tests) (88 tests) (89 tests) (90 tests) (91 tests) (92 tests) (93 tests) (94 tests) (95 tests) (96 tests) (97 tests) (98 tests) (99 tests) prop_read_show_inodecache
++++ OK, passed 100 tests.
+(0 tests) (1 test) (2 tests) (3 tests) (4 tests) (5 tests) (6 tests) (7 tests) (8 tests) (9 tests) (10 tests) (11 tests) (12 tests) (13 tests) (14 tests) (15 tests) (16 tests) (17 tests) (18 tests) (19 tests) (20 tests) (21 tests) (22 tests) (23 tests) (24 tests) (25 tests) (26 tests) (27 tests) (28 tests) (29 tests) (30 tests) (31 tests) (32 tests) (33 tests) (34 tests) (35 tests) (36 tests) (37 tests) (38 tests) (39 tests) (40 tests) (41 tests) (42 tests) (43 tests) (44 tests) (45 tests) (46 tests) (47 tests) (48 tests) (49 tests) (50 tests) (51 tests) (52 tests) (53 tests) (54 tests) (55 tests) (56 tests) (57 tests) (58 tests) (59 tests) (60 tests) (61 tests) (62 tests) (63 tests) (64 tests) (65 tests) (66 tests) (67 tests) (68 tests) (69 tests) (70 tests) (71 tests) (72 tests) (73 tests) (74 tests) (75 tests) (76 tests) (77 tests) (78 tests) (79 tests) (80 tests) (81 tests) (82 tests) (83 tests) (84 tests) (85 tests) (86 tests) (87 tests) (88 tests) (89 tests) (90 tests) (91 tests) (92 tests) (93 tests) (94 tests) (95 tests) (96 tests) (97 tests) (98 tests) (99 tests) prop_parse_show_log
++++ OK, passed 100 tests.
+(0 tests) prop_read_show_TrustLevel
++++ OK, passed 1 tests.
+(0 tests) prop_parse_show_TrustLog
++++ OK, passed 1 tests.
+
+Cases: 1 Tried: 0 Errors: 0 Failures: 0init test repo
+ Detected a crippled filesystem.
+
+ Disabling core.symlinks.
+
+ Enabling direct mode.
+
+ Detected a filesystem without fifo support.
+
+ Disabling ssh connection caching.
+ok
+(Recording state in git...)
+
+
+Cases: 1 Tried: 1 Errors: 0 Failures: 0
+
+Cases: 3 Tried: 0 Errors: 0 Failures: 0add foo (checksum...) ok
+(Recording state in git...)
+add sha1foo (checksum...) ok
+(Recording state in git...)
+add apple ok
+(Recording state in git...)
+
+Cases: 3 Tried: 1 Errors: 0 Failures: 0ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex add:1
+git clone failed
+
+Cases: 3 Tried: 2 Errors: 0 Failures: 1ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex add:2
+git clone failed
+Cases: 3 Tried: 3 Errors: 0 Failures: 2
+
+Cases: 1 Tried: 0 Errors: 0 Failures: 0ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex reinject/fromkey
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+
+Cases: 2 Tried: 0 Errors: 0 Failures: 0ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex unannex:0:no content
+git clone failed
+
+Cases: 2 Tried: 1 Errors: 0 Failures: 1ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex unannex:1:with content
+git clone failed
+Cases: 2 Tried: 2 Errors: 0 Failures: 2
+
+Cases: 3 Tried: 0 Errors: 0 Failures: 0ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex drop:0:no remotes
+git clone failed
+
+Cases: 3 Tried: 1 Errors: 0 Failures: 1ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex drop:1:with remote
+git clone failed
+
+Cases: 3 Tried: 2 Errors: 0 Failures: 2ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex drop:2:untrusted remote
+git clone failed
+Cases: 3 Tried: 3 Errors: 0 Failures: 3
+
+Cases: 1 Tried: 0 Errors: 0 Failures: 0ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex get
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+
+Cases: 1 Tried: 0 Errors: 0 Failures: 0ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex move
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+
+Cases: 1 Tried: 0 Errors: 0 Failures: 0ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex copy
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+
+Cases: 1 Tried: 0 Errors: 0 Failures: 0ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex unlock/lock
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+
+Cases: 2 Tried: 0 Errors: 0 Failures: 0ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex edit/commit:0
+git clone failed
+
+Cases: 2 Tried: 1 Errors: 0 Failures: 1ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex edit/commit:1
+git clone failed
+Cases: 2 Tried: 2 Errors: 0 Failures: 2
+
+Cases: 1 Tried: 0 Errors: 0 Failures: 0ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex fix
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+
+Cases: 1 Tried: 0 Errors: 0 Failures: 0ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex trust/untrust/semitrust/dead
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+
+Cases: 4 Tried: 0 Errors: 0 Failures: 0ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex fsck:0
+git clone failed
+
+Cases: 4 Tried: 1 Errors: 0 Failures: 1ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex fsck:1
+git clone failed
+
+Cases: 4 Tried: 2 Errors: 0 Failures: 2ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex fsck:2
+git clone failed
+
+Cases: 4 Tried: 3 Errors: 0 Failures: 3ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex fsck:3
+git clone failed
+Cases: 4 Tried: 4 Errors: 0 Failures: 4
+
+Cases: 2 Tried: 0 Errors: 0 Failures: 0ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex migrate:0
+git clone failed
+
+Cases: 2 Tried: 1 Errors: 0 Failures: 1ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex migrate:1
+git clone failed
+Cases: 2 Tried: 2 Errors: 0 Failures: 2
+
+Cases: 1 Tried: 0 Errors: 0 Failures: 0ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex unused/dropunused
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+
+Cases: 1 Tried: 0 Errors: 0 Failures: 0ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex describe
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+
+Cases: 1 Tried: 0 Errors: 0 Failures: 0ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex find
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+
+Cases: 1 Tried: 0 Errors: 0 Failures: 0ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex merge
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+
+Cases: 1 Tried: 0 Errors: 0 Failures: 0ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex status
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+
+Cases: 1 Tried: 0 Errors: 0 Failures: 0ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex version
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+
+Cases: 1 Tried: 0 Errors: 0 Failures: 0ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex sync
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+
+Cases: 1 Tried: 0 Errors: 0 Failures: 0ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: union merge regression
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+
+Cases: 1 Tried: 0 Errors: 0 Failures: 0ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: automatic conflict resolution
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+
+Cases: 1 Tried: 0 Errors: 0 Failures: 0ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex map
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+
+Cases: 1 Tried: 0 Errors: 0 Failures: 0ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex uninit
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+
+Cases: 1 Tried: 0 Errors: 0 Failures: 0ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex upgrade
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+
+Cases: 1 Tried: 0 Errors: 0 Failures: 0ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex whereis
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+
+Cases: 1 Tried: 0 Errors: 0 Failures: 0ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex hook remote
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+
+Cases: 1 Tried: 0 Errors: 0 Failures: 0ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex directory remote
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+
+Cases: 1 Tried: 0 Errors: 0 Failures: 0ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex rsync remote
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+
+Cases: 1 Tried: 0 Errors: 0 Failures: 0ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex bup remote
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+
+Cases: 1 Tried: 0 Errors: 0 Failures: 0ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex crypto
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+
+Cases: 1 Tried: 0 Errors: 0 Failures: 0ssh: Could not resolve hostname C: no address associated with name
+fatal: The remote end hung up unexpectedly
+
+
+### Failure in: git-annex preferred-content
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+----------------------------------------------------------------------
+Now, some broader checks ...
+ (Do not be alarmed by odd output here; it's normal.
+ wait for the last line to see how it went.)
+----------------------------------------------------------------------
+init
+----------------------------------------------------------------------
+add
+----------------------------------------------------------------------
+reinject
+----------------------------------------------------------------------
+unannex
+----------------------------------------------------------------------
+drop
+----------------------------------------------------------------------
+get
+----------------------------------------------------------------------
+move
+----------------------------------------------------------------------
+copy
+----------------------------------------------------------------------
+lock
+----------------------------------------------------------------------
+edit
+----------------------------------------------------------------------
+fix
+----------------------------------------------------------------------
+trust
+----------------------------------------------------------------------
+fsck
+----------------------------------------------------------------------
+migrate
+----------------------------------------------------------------------
+ unused
+----------------------------------------------------------------------
+describe
+----------------------------------------------------------------------
+find
+----------------------------------------------------------------------
+merge
+----------------------------------------------------------------------
+status
+----------------------------------------------------------------------
+version
+----------------------------------------------------------------------
+sync
+----------------------------------------------------------------------
+union merge regression
+----------------------------------------------------------------------
+conflict resolution
+----------------------------------------------------------------------
+map
+----------------------------------------------------------------------
+uninit
+----------------------------------------------------------------------
+upgrade
+----------------------------------------------------------------------
+whereis
+----------------------------------------------------------------------
+hook remote
+----------------------------------------------------------------------
+directory remote
+----------------------------------------------------------------------
+rsync remote
+----------------------------------------------------------------------
+bup remote
+----------------------------------------------------------------------
+crypto
+----------------------------------------------------------------------
+preferred content
+----------------------------------------------------------------------
+Some tests failed!
+ (This could be due to a bug in git-annex, or an incompatability
+ with utilities, such as git, installed on this system.)
+
+
+# End of transcript or log.
+"""]]
+
+[[!tag moreinfo]]
diff --git a/doc/bugs/Windows_build_test_failures/comment_1_ea7523fdbafdc8be2971df52d9038826._comment b/doc/bugs/Windows_build_test_failures/comment_1_ea7523fdbafdc8be2971df52d9038826._comment
new file mode 100644
index 000000000..dc09fb89b
--- /dev/null
+++ b/doc/bugs/Windows_build_test_failures/comment_1_ea7523fdbafdc8be2971df52d9038826._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.2.134"
+ subject="comment 1"
+ date="2013-09-13T19:18:26Z"
+ content="""
+The Windows port has improved quite a lot since this bug was filed. Can you still reproduce it?
+
+If you install the pre-built git-annex for Windows, you can run `git annex test` to run the test suite. Does that work? It works for some others on Windows.
+"""]]
diff --git a/doc/bugs/Windows_installer_includes_curl_and_wget__44___but_not_required_DLLs.mdwn b/doc/bugs/Windows_installer_includes_curl_and_wget__44___but_not_required_DLLs.mdwn
new file mode 100644
index 000000000..a21813500
--- /dev/null
+++ b/doc/bugs/Windows_installer_includes_curl_and_wget__44___but_not_required_DLLs.mdwn
@@ -0,0 +1,17 @@
+### Please describe the problem.
+On a default, clean install on Windows, annex get over HTTP fails, as neither wget nor curl have all necessary DLLs.
+
+### What steps will reproduce the problem?
+1. Install git from git-scm.org, and git-annex from git-annex.branchable.com.
+2. Don't install, or remove if installed, Cygwin.
+3. clone an annex over HTTP
+4. attempt to 'annex get' a file
+5. get dialog box, explaining missing DLLs.
+
+### What version of git-annex are you using? On what operating system?
+Windows 7.
+
+### Please provide any additional information below.
+Installing Cygwin and adding to path seems to fix issue.
+
+[[!tag moreinfo]]
diff --git a/doc/bugs/Windows_installer_includes_curl_and_wget__44___but_not_required_DLLs/comment_1_a7bf0f027f2209e5632e292afd7214d0._comment b/doc/bugs/Windows_installer_includes_curl_and_wget__44___but_not_required_DLLs/comment_1_a7bf0f027f2209e5632e292afd7214d0._comment
new file mode 100644
index 000000000..05639ef3a
--- /dev/null
+++ b/doc/bugs/Windows_installer_includes_curl_and_wget__44___but_not_required_DLLs/comment_1_a7bf0f027f2209e5632e292afd7214d0._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.254.222"
+ subject="comment 1"
+ date="2013-07-07T17:47:54Z"
+ content="""
+The Windows installer includes numerous DLLs from Cygwin. I have tested it in a non-cygwin environment and it seems to work for me, and for other users. At least generally.. perhaps it *is* missing something used by wget or curl?
+
+Can you please provide the names of the DLLs that seem to be missing?
+"""]]
diff --git a/doc/bugs/Windows_to_Linux_clone_-_Windows_drive_letters_cause_git_annex_get_to_fail.mdwn b/doc/bugs/Windows_to_Linux_clone_-_Windows_drive_letters_cause_git_annex_get_to_fail.mdwn
new file mode 100644
index 000000000..64e95ca1b
--- /dev/null
+++ b/doc/bugs/Windows_to_Linux_clone_-_Windows_drive_letters_cause_git_annex_get_to_fail.mdwn
@@ -0,0 +1,131 @@
+[[!tag moreinfo]]
+
+### Please describe the problem.
+git annex get on a clone of a repository created on Windows fails.
+
+### What steps will reproduce the problem?
+On Windows:
+1. Create an annex using git annex init
+
+2. git add files
+
+3. git annex sync (because I forgot about commit)
+
+On Linux:
+
+1. Mount the Windows annex via SMB (mine was read only, but probably won't matter)
+
+2. git clone the folder (works fine)
+
+3. git annex get (fails, due to Windows drive letter)
+
+### What version of git-annex are you using? On what operating system?
+
+*Windows:*
+
+git-annex version: 4.20130802-g0a52f02
+
+build flags: Pairing Testsuite S3 WebDAV DNS
+
+*Linux: (Debian wheezy on ARMel)*
+
+git-annex version: 3.20120629
+
+local repository version: 3
+
+default repository version: 3
+
+supported repository versions: 3
+
+upgrade supported from repository versions: 0 1 2
+
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+#output of git annex get on the Linux side.
+
+get Purchased/Caravan Palace/Panic/01 Queens.mp3 (not available)
+ Try making some of these repositories available:
+ d6c78593-79d2-455a-8202-7be2133e2d48 -- ICARUS:E:\music
+failed
+get Purchased/Caravan Palace/Panic/02 Maniac.mp3 (not available)
+ Try making some of these repositories available:
+ d6c78593-79d2-455a-8202-7be2133e2d48 -- ICARUS:E:\music
+failed
+get Purchased/Caravan Palace/Panic/03 The Dirty Side of the Street.mp3 (not available)
+ Try making some of these repositories available:
+ d6c78593-79d2-455a-8202-7be2133e2d48 -- ICARUS:E:\music
+failed
+get Purchased/Caravan Palace/Panic/04 12 juin 3049.mp3 (not available)
+ Try making some of these repositories available:
+ d6c78593-79d2-455a-8202-7be2133e2d48 -- ICARUS:E:\music
+failed
+get Purchased/Caravan Palace/Panic/05 Rock It for Me.mp3 (not available)
+ Try making some of these repositories available:
+ d6c78593-79d2-455a-8202-7be2133e2d48 -- ICARUS:E:\music
+failed
+get Purchased/Caravan Palace/Panic/06 Clash.mp3 (not available)
+ Try making some of these repositories available:
+ d6c78593-79d2-455a-8202-7be2133e2d48 -- ICARUS:E:\music
+failed
+get Purchased/Caravan Palace/Panic/07 Newbop.mp3 (not available)
+ Try making some of these repositories available:
+ d6c78593-79d2-455a-8202-7be2133e2d48 -- ICARUS:E:\music
+failed
+get Purchased/Caravan Palace/Panic/08 Glory of Nelly.mp3 (not available)
+ Try making some of these repositories available:
+ d6c78593-79d2-455a-8202-7be2133e2d48 -- ICARUS:E:\music
+failed
+get Purchased/Caravan Palace/Panic/09 Dramophone.mp3 (not available)
+ Try making some of these repositories available:
+ d6c78593-79d2-455a-8202-7be2133e2d48 -- ICARUS:E:\music
+failed
+get Purchased/Caravan Palace/Panic/10 Cotton Heads.mp3 (not available)
+ Try making some of these repositories available:
+ d6c78593-79d2-455a-8202-7be2133e2d48 -- ICARUS:E:\music
+failed
+get Purchased/Caravan Palace/Panic/11 Panic.mp3 (not available)
+ Try making some of these repositories available:
+ d6c78593-79d2-455a-8202-7be2133e2d48 -- ICARUS:E:\music
+failed
+get Purchased/Caravan Palace/Panic/12 Pirates.mp3 (not available)
+ Try making some of these repositories available:
+ d6c78593-79d2-455a-8202-7be2133e2d48 -- ICARUS:E:\music
+failed
+get Purchased/Caravan Palace/Panic/13 Beatophone.mp3 (not available)
+ Try making some of these repositories available:
+ d6c78593-79d2-455a-8202-7be2133e2d48 -- ICARUS:E:\music
+failed
+get Purchased/Caravan Palace/Panic/14 Sydney.mp3 (not available)
+ Try making some of these repositories available:
+ d6c78593-79d2-455a-8202-7be2133e2d48 -- ICARUS:E:\music
+failed
+get Purchased/Caravan Palace/Panic/Thumbs.db (not available)
+ Try making some of these repositories available:
+ d6c78593-79d2-455a-8202-7be2133e2d48 -- ICARUS:E:\music
+
+
+And the (broken) symlinks:
+
+lrwxrwxrwx 1 voltagex voltagex 198 Aug 11 23:05 01 Queens.mp3 -> .git/annex/objects/5P/vq/SHA256E-s9886015--dfb8f452d47f997a9141de3f152de375fad1d5ccb4a20d5c022064a630eaba88.mp3/SHA256E-s9886015--dfb8f452d47f997a9141de3f152de375fad1d5ccb4a20d5c022064a630eaba88.mp3
+lrwxrwxrwx 1 voltagex voltagex 200 Aug 11 23:05 02 Maniac.mp3 -> .git/annex/objects/J0/WV/SHA256E-s10116938--7ce35f4a54c4f74bd2e3813445cb3a07fae76b2854df06ab00876cd0067f34a5.mp3/SHA256E-s10116938--7ce35f4a54c4f74bd2e3813445cb3a07fae76b2854df06ab00876cd0067f34a5.mp3
+lrwxrwxrwx 1 voltagex voltagex 198 Aug 11 23:05 03 The Dirty Side of the Street.mp3 -> .git/annex/objects/xz/4F/SHA256E-s8812949--9e15761ae8c6231d11d1f5a67de8a89142e2e4017b43b8ffac1088fd71842ca7.mp3/SHA256E-s8812949--9e15761ae8c6231d11d1f5a67de8a89142e2e4017b43b8ffac1088fd71842ca7.mp3
+lrwxrwxrwx 1 voltagex voltagex 198 Aug 11 23:05 04 12 juin 3049.mp3 -> .git/annex/objects/Kp/k6/SHA256E-s8236133--3a6465bea3272ae7a22b77b67e96a91ae389390cc95642fb1456ce80e3313033.mp3/SHA256E-s8236133--3a6465bea3272ae7a22b77b67e96a91ae389390cc95642fb1456ce80e3313033.mp3
+lrwxrwxrwx 1 voltagex voltagex 198 Aug 11 23:05 05 Rock It for Me.mp3 -> .git/annex/objects/Wk/Qv/SHA256E-s7701150--8197e499408e64601157df95927ac6b09bd37834a41eceecc5d12667bd7c66a4.mp3/SHA256E-s7701150--8197e499408e64601157df95927ac6b09bd37834a41eceecc5d12667bd7c66a4.mp3
+lrwxrwxrwx 1 voltagex voltagex 200 Aug 11 23:05 06 Clash.mp3 -> .git/annex/objects/ZQ/P4/SHA256E-s10201572--c2a1a8892fcaaab1ed59ca7f5ab9d45f0c3bb3c6d6450b95228039b9e8d7a0b4.mp3/SHA256E-s10201572--c2a1a8892fcaaab1ed59ca7f5ab9d45f0c3bb3c6d6450b95228039b9e8d7a0b4.mp3
+lrwxrwxrwx 1 voltagex voltagex 198 Aug 11 23:05 07 Newbop.mp3 -> .git/annex/objects/Fk/wV/SHA256E-s6850587--b5ba0347f6a09a7ff8bec2dd1fbe8076fdff645d4bc1909ddeadfc035bf19fda.mp3/SHA256E-s6850587--b5ba0347f6a09a7ff8bec2dd1fbe8076fdff645d4bc1909ddeadfc035bf19fda.mp3
+lrwxrwxrwx 1 voltagex voltagex 198 Aug 11 23:05 08 Glory of Nelly.mp3 -> .git/annex/objects/Pm/K3/SHA256E-s9002048--18149581cbfc3b4e3e72b784777fe34c53f1580e78e97f66058be0b1eb40e809.mp3/SHA256E-s9002048--18149581cbfc3b4e3e72b784777fe34c53f1580e78e97f66058be0b1eb40e809.mp3
+lrwxrwxrwx 1 voltagex voltagex 198 Aug 11 23:05 09 Dramophone.mp3 -> .git/annex/objects/k3/Jf/SHA256E-s8199558--925117d9fc47a65e8e5324f3d0638a3c24bf51fd6c0b5d8ac2f63951c893cc48.mp3/SHA256E-s8199558--925117d9fc47a65e8e5324f3d0638a3c24bf51fd6c0b5d8ac2f63951c893cc48.mp3
+lrwxrwxrwx 1 voltagex voltagex 198 Aug 11 23:05 10 Cotton Heads.mp3 -> .git/annex/objects/9f/32/SHA256E-s8801425--c6926238c0b1a3bbea1a5d17841ceac591e53e223e4c4c45a2077cabffc85d81.mp3/SHA256E-s8801425--c6926238c0b1a3bbea1a5d17841ceac591e53e223e4c4c45a2077cabffc85d81.mp3
+lrwxrwxrwx 1 voltagex voltagex 198 Aug 11 23:05 11 Panic.mp3 -> .git/annex/objects/XF/WF/SHA256E-s9833770--5e837c7fa3ec096f7c0507efbcf398067029749f8a0fc77a2badf864b9ffbb7c.mp3/SHA256E-s9833770--5e837c7fa3ec096f7c0507efbcf398067029749f8a0fc77a2badf864b9ffbb7c.mp3
+lrwxrwxrwx 1 voltagex voltagex 198 Aug 11 23:05 12 Pirates.mp3 -> .git/annex/objects/7Z/jz/SHA256E-s8017742--5fd49b2d89577266d2fb740e7e7def9338475af90c2ca99f9d6d513465b2bfac.mp3/SHA256E-s8017742--5fd49b2d89577266d2fb740e7e7def9338475af90c2ca99f9d6d513465b2bfac.mp3
+lrwxrwxrwx 1 voltagex voltagex 198 Aug 11 23:05 13 Beatophone.mp3 -> .git/annex/objects/81/xv/SHA256E-s9339544--a1eb8404ecf0503b9f635378fec4e2c95ec08bb1428c2cd4c0cedf492811577d.mp3/SHA256E-s9339544--a1eb8404ecf0503b9f635378fec4e2c95ec08bb1428c2cd4c0cedf492811577d.mp3
+lrwxrwxrwx 1 voltagex voltagex 198 Aug 11 23:05 14 Sydney.mp3 -> .git/annex/objects/3K/99/SHA256E-s8459731--4ff44b25c912e914c79124ff9074c576c0024152442fc96c9bad65f5a50a40d9.mp3/SHA256E-s8459731--4ff44b25c912e914c79124ff9074c576c0024152442fc96c9bad65f5a50a40d9.mp3
+lrwxrwxrwx 1 voltagex voltagex 192 Aug 11 23:05 Thumbs.db -> .git/annex/objects/28/Zv/SHA256E-s85504--3604669cd3a55234516191eb4f19434829c1634d6dd69a9981185f095d2bbaba.db/SHA256E-s85504--3604669cd3a55234516191eb4f19434829c1634d6dd69a9981185f095d2bbaba.db
+
+# End of transcript or log.
+"""]]
diff --git a/doc/bugs/Windows_to_Linux_clone_-_Windows_drive_letters_cause_git_annex_get_to_fail/comment_1_c87bae87b7902db60a3fef41e1fca85d._comment b/doc/bugs/Windows_to_Linux_clone_-_Windows_drive_letters_cause_git_annex_get_to_fail/comment_1_c87bae87b7902db60a3fef41e1fca85d._comment
new file mode 100644
index 000000000..0577531b7
--- /dev/null
+++ b/doc/bugs/Windows_to_Linux_clone_-_Windows_drive_letters_cause_git_annex_get_to_fail/comment_1_c87bae87b7902db60a3fef41e1fca85d._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlzWwnBfgJrkhPQakBo6DbPXutJIVDHkj0"
+ nickname="Adam"
+ subject="comment 1"
+ date="2013-08-11T14:15:40Z"
+ content="""
+Confirming the same errors happen with git-annex version: 4.20130802 from sid.
+
+"""]]
diff --git a/doc/bugs/Windows_to_Linux_clone_-_Windows_drive_letters_cause_git_annex_get_to_fail/comment_2_9e3c1f1ba05d8996b5a95829ce32c07e._comment b/doc/bugs/Windows_to_Linux_clone_-_Windows_drive_letters_cause_git_annex_get_to_fail/comment_2_9e3c1f1ba05d8996b5a95829ce32c07e._comment
new file mode 100644
index 000000000..d98e7976e
--- /dev/null
+++ b/doc/bugs/Windows_to_Linux_clone_-_Windows_drive_letters_cause_git_annex_get_to_fail/comment_2_9e3c1f1ba05d8996b5a95829ce32c07e._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="bad bug report title 101"
+ date="2013-08-24T19:17:29Z"
+ content="""
+I don't understand why you think the problem has something to do with Windows drive letters. There are no Windows drive letters in the symlinks you show. The only place I see any Windows drive letter is in the descripton of the remote that `git annex get` displays when it fails to get the file. That description is purely informative, it's not a path that git-annex is trying to use.
+
+I'd suggest that you run `git annex get --debug` to see if it is doing anything obviously wrong. The mostly likely culprit is your SMB setup, which I am not going to be able to replicate.
+"""]]
diff --git a/doc/bugs/Windows_to_Linux_clone_-_Windows_drive_letters_cause_git_annex_get_to_fail/comment_3_3a0787912f4a3a8797b7786f5ce38590._comment b/doc/bugs/Windows_to_Linux_clone_-_Windows_drive_letters_cause_git_annex_get_to_fail/comment_3_3a0787912f4a3a8797b7786f5ce38590._comment
new file mode 100644
index 000000000..16f240cf2
--- /dev/null
+++ b/doc/bugs/Windows_to_Linux_clone_-_Windows_drive_letters_cause_git_annex_get_to_fail/comment_3_3a0787912f4a3a8797b7786f5ce38590._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlzWwnBfgJrkhPQakBo6DbPXutJIVDHkj0"
+ nickname="Adam"
+ subject="comment 3"
+ date="2013-08-26T06:56:33Z"
+ content="""
+You're correct. I can see in .git/config that the remote references z:\ which of course will break on the Linux side. Maybe this is a case of the error messages not quite telling me the right thing?
+"""]]
diff --git a/doc/bugs/Windows_to_Linux_clone_-_Windows_drive_letters_cause_git_annex_get_to_fail/comment_4_c4249f32d65594d79ea01145b93ec948._comment b/doc/bugs/Windows_to_Linux_clone_-_Windows_drive_letters_cause_git_annex_get_to_fail/comment_4_c4249f32d65594d79ea01145b93ec948._comment
new file mode 100644
index 000000000..31bc7c1a1
--- /dev/null
+++ b/doc/bugs/Windows_to_Linux_clone_-_Windows_drive_letters_cause_git_annex_get_to_fail/comment_4_c4249f32d65594d79ea01145b93ec948._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.2.134"
+ subject="comment 4"
+ date="2013-09-13T19:29:25Z"
+ content="""
+I'd suggest that you run git annex get --debug to see if it is doing anything obviously wrong. The mostly likely culprit is your SMB setup, which I am not going to be able to replicate.
+
+"""]]
diff --git a/doc/bugs/With_S3__44___GPG_ask_for_a_new_passphrase.mdwn b/doc/bugs/With_S3__44___GPG_ask_for_a_new_passphrase.mdwn
new file mode 100644
index 000000000..e6f3524b2
--- /dev/null
+++ b/doc/bugs/With_S3__44___GPG_ask_for_a_new_passphrase.mdwn
@@ -0,0 +1,21 @@
+I'm using S3 special remote that I initialized like this:
+
+ git annex initremote s3 type=S3 encryption=EEF2B390 datacenter="EU" storageclass="REDUCED_REDUNDANCY"
+
+Instead of asking me my key passphrase (I have gpg-agent running), it ask me a new passphase an then repeat it. So it's not my passphrase because if I kill gpg-agent, it will ask me three passphrase for each file: one mine and two for the new one. If i don't put anything there it says:
+
+ copy GOPR1672.JPG (checking s3...) (to s3...) gpg: error creating passphrase: Invalid passphrase
+ gpg: symmetric encryption of `[stdin]' failed: Invalid passphrase
+ failed
+ git-annex: fd:13: hPutBuf: resource vanished (Broken pipe)
+ copy GOPR1673.JPG (checking s3...) (to s3...)
+
+So I create a new passphrase (two times) for each file I tried to upload. The problem is that I have more than 12000 files to upload!
+
+What's this new passphrase for?
+
+BTW: git-annex version: 3.20130102 same precompiled binary on Arch Linux.
+
+> I've reproduced this with gpg 2.0.19. It is a documented incompatability
+> between gpg 1.x and 2.x; the latter needs --batch included in its
+> parameters. I've put in a fix. [[done]]
diff --git a/doc/bugs/With_S3__44___GPG_ask_for_a_new_passphrase/comment_1_a4fc30bf7d39cae337286e9e815e6cba._comment b/doc/bugs/With_S3__44___GPG_ask_for_a_new_passphrase/comment_1_a4fc30bf7d39cae337286e9e815e6cba._comment
new file mode 100644
index 000000000..b006b3b44
--- /dev/null
+++ b/doc/bugs/With_S3__44___GPG_ask_for_a_new_passphrase/comment_1_a4fc30bf7d39cae337286e9e815e6cba._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="joksnet"
+ ip="193.253.37.245"
+ subject="Working now"
+ date="2013-01-16T01:36:43Z"
+ content="""
+Ok. I don't what happend, but it's working now. I restart gpg-agent a few times with the script found [here](https://wiki.archlinux.org/index.php/GPG#gpg-agent). And now it doesn't ask for any passphrase.
+
+Par contre, I need to export the AWS_* variables if I reboot my pc. I think is because I didn't set embedcreds=yes when initremote. Can I change it now? O I have to remote rm and initremote again?
+
+Thank you,
+Juan
+"""]]
diff --git a/doc/bugs/With_S3__44___GPG_ask_for_a_new_passphrase/comment_2_e5d42b623017acedf6a3890ce15680a3._comment b/doc/bugs/With_S3__44___GPG_ask_for_a_new_passphrase/comment_2_e5d42b623017acedf6a3890ce15680a3._comment
new file mode 100644
index 000000000..7b26ca738
--- /dev/null
+++ b/doc/bugs/With_S3__44___GPG_ask_for_a_new_passphrase/comment_2_e5d42b623017acedf6a3890ce15680a3._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.238"
+ subject="comment 2"
+ date="2013-01-16T02:17:26Z"
+ content="""
+Someone else reported what sounds like the same bug at [[encryption_given_a_gpg_keyid_still_uses_symmetric_encryption]]. It sounds like this is somehow an agent bug. I cannot reproduce it. I can hypothesise that, if this bug is occurring, you'll be prompted for a passphrase when running this command.. which if it happens would certainly be a bug in gpg or its agent
+
+touch foo; echo foo| gpg --symmetric --passphrase-fd=0 foo
+
+(You can run `git annex initremote $yourremote embedcreds=yes` and it'll modify the existing configuration.)
+"""]]
diff --git a/doc/bugs/With_S3__44___GPG_ask_for_a_new_passphrase/comment_3_e5150b65b514896e14b9ad3d951963f7._comment b/doc/bugs/With_S3__44___GPG_ask_for_a_new_passphrase/comment_3_e5150b65b514896e14b9ad3d951963f7._comment
new file mode 100644
index 000000000..4764dcd5d
--- /dev/null
+++ b/doc/bugs/With_S3__44___GPG_ask_for_a_new_passphrase/comment_3_e5150b65b514896e14b9ad3d951963f7._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="joksnet"
+ ip="193.253.37.245"
+ subject="comment 3"
+ date="2013-01-16T17:23:26Z"
+ content="""
+It's a GPG/GPG-Agent (2.0.19) bug because the command you give me ask me for a new passphrase.
+
+Thank you for the answer.
+"""]]
diff --git a/doc/bugs/With_S3__44___GPG_ask_for_a_new_passphrase/comment_4_47c2fc167b0c396edc40468fb7c7bfee._comment b/doc/bugs/With_S3__44___GPG_ask_for_a_new_passphrase/comment_4_47c2fc167b0c396edc40468fb7c7bfee._comment
new file mode 100644
index 000000000..20f6564c8
--- /dev/null
+++ b/doc/bugs/With_S3__44___GPG_ask_for_a_new_passphrase/comment_4_47c2fc167b0c396edc40468fb7c7bfee._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.238"
+ subject="comment 4"
+ date="2013-01-16T19:05:38Z"
+ content="""
+Does it ask for a passphrase if --batch is included in gpg's parameters?
+"""]]
diff --git a/doc/bugs/Won__39__t_drop_files__44___even_though_remote_annexes_have_at_least_numcopies.mdwn b/doc/bugs/Won__39__t_drop_files__44___even_though_remote_annexes_have_at_least_numcopies.mdwn
new file mode 100644
index 000000000..ec87cefbe
--- /dev/null
+++ b/doc/bugs/Won__39__t_drop_files__44___even_though_remote_annexes_have_at_least_numcopies.mdwn
@@ -0,0 +1,39 @@
+### Please describe the problem.
+On a Windows machine, I try to drop some files from an annex. These files exist in the origin annex. However, the drop fails, claiming it can't verify the existence of the remote copies.
+
+### What steps will reproduce the problem?
+1. Create annex, serve git repo over HTTP.
+2. clone repo. "git annex get ."
+3. "git annex drop <file>". This will fail.
+
+
+### What version of git-annex are you using? On what operating system?
+Windows: 4.20130709-gea6fdc7
+Debian: 3.20120629
+
+### Please provide any additional information below.
+
+[[!format sh """
+git annex -vd drop file2.txt
+[<datetime>] read: git ["--git-dir=C:\\Users\\<user>\\test_annex_2\\.git","--work-tree=C:\\Users\\<user>\\test_annex_2","ls-files","--cached","-z","--","file2.txt"]
+[<datetime>] chat: git ["--git-dir=C:\\Users\\<user>\\test_annex_2\\.git","--work-tree=C:\\Users\\<user>\\test_annex_2","check-attr","-z","--stdin","annex.backend","annex.numcopies","--"]
+drop file2.txt [<datetime>] read: git ["--git-dir=C:\\Users\\<user>\\test_annex_2\\.git","--work-tree=C:\\Users\\<user>\\test_annex_2","show-ref","git-annex"]
+[<datetime>] read: git ["--git-dir=C:\\Users\\<user>\\test_annex_2\\.git","--work-tree=C:\\Users\\<user>\\test_annex_2","show-ref","--hash","refs/heads/git-annex"]
+[<datetime>] read: git ["--git-dir=C:\\Users\\<user>\\test_annex_2\\.git","--work-tree=C:\\Users\\<user>\\test_annex_2","log","refs/heads/git-annex..37bdd895d74131fddbdb8d2e6ae707ee2097598e","--oneline","-n1"]
+[<datetime>] read: git ["--git-dir=C:\\Users\\<<user>>\\test_annex_2\\.git","--work-tree=C:\\Users\\<user>\\test_annex_2","log","refs/heads/git-annex..f0ba6f30c63a9d586642d828c37613894191931e","--oneline","-n1"]
+[<datetime>] chat: git ["--git-dir=C:\\Users\\<user>\\test_annex_2\\.git","--work-tree=C:\\Users\\<user>\\test_annex_2","cat-file","--batch"]
+[<datetime>] read: curl ["-s","--head","-L","http://192.168.0.8:8000/test_annex_2/.git/annex/objects/738/e2a/SHA256-s27--4fc887746d7ea6c9574f6735bd3dfd9b0485b30acaaf0727658cd1796991dd2d/SHA256-s27--4fc887746d7ea6c9574f6735bd3dfd9b0485b30acaaf0727658cd1796991dd2d","-w","%{http_code}"]
+(unsafe)
+ Could only verify the existence of 0 out of 1 necessary copies
+
+ Rather than dropping this file, try using: git annex move
+
+ (Use --force to override this check, or adjust annex.numcopies.)
+failed
+git-annex: drop: 1 failed
+"""]]
+
+the given curl command fails with a 404, because the remote annex isn't using the 3-character hash directory scheme, but the 2-character one, and it seems that 'annex drop' doesn't check both schemes (unlike annex get).
+
+> Ah, the http remote is a non-bare repository, that's why.
+> Ok, [[fixed|done]]! --[[Joey]]
diff --git a/doc/bugs/Wrong_port_while_configuring_ssh_remote.mdwn b/doc/bugs/Wrong_port_while_configuring_ssh_remote.mdwn
new file mode 100644
index 000000000..561cad199
--- /dev/null
+++ b/doc/bugs/Wrong_port_while_configuring_ssh_remote.mdwn
@@ -0,0 +1,35 @@
+### Please describe the problem.
+
+When the assistant connects the second time during adding a ssh remote, it assumes port 22 when different port is given.
+
+### What steps will reproduce the problem?
+
+Adding a ssh git remote with non-standard port.
+
+### What version of git-annex are you using? On what operating system?
+
+GNU/Linux, Ubuntu 12.10, amd64, git-annex 4.20130627-g728b27a
+
+Happens on android as well.
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+Error message (nothing related in daemon.log):
+
+Failed to make repository
+
+Something went wrong setting up the repository on the remote server.
+
+Transcript:
+
+ssh: connect to host xxxxx port 22: Connection refused
+
+# End of transcript or log.
+"""]]
+
+> [[Fixed|done]]; this bug was introcuded in version
+> 4.20130627 while making some other ssh fixes. --[[Joey]]
diff --git a/doc/bugs/Zombie_processes_and__47__or_stuck_git_processes.mdwn b/doc/bugs/Zombie_processes_and__47__or_stuck_git_processes.mdwn
new file mode 100644
index 000000000..e7ff53723
--- /dev/null
+++ b/doc/bugs/Zombie_processes_and__47__or_stuck_git_processes.mdwn
@@ -0,0 +1,44 @@
+### Please describe the problem.
+git-annex assistant is currently running. Here is the output of **ps -A u | grep -i git**:
+
+[[!format sh """
+5457 pts/2 Z+ 0:00 [git-annex] <defunct>
+5510 ? Sl 0:05 git-annex assistant
+5522 ? S 0:00 git --git-dir=/home/me/annex/.git --work-tree=/home/me/annex cat-file --batch
+5573 ? S 0:00 git --git-dir=/home/me/annex/.git --work-tree=/home/me/annex cat-file --batch
+5679 ? SN 0:00 git --git-dir=/home/me/annex/.git --work-tree=/home/me/annex check-attr -z --stdin annex.backend annex.numcopies --
+5680 ? Z 0:03 [git-annex] <defunct>
+5710 ? Z 0:00 [git-annex] <defunct>
+5732 pts/2 Z+ 0:00 [git-annex] <defunct>
+5752 pts/2 Z+ 0:00 [git-annex] <defunct>
+5785 ? Ss 0:00 ssh: .git/annex/ssh/example.net [mux]
+5905 ? Z 0:00 [git-annex] <defunct>
+5923 ? Z 0:00 [git-annex] <defunct>
+6513 pts/2 Z+ 0:00 [git-annex] <defunct>
+6552 ? Z 0:00 [git-annex] <defunct>
+7797 ? Z 0:00 [git-annex] <defunct>
+7873 pts/2 Z 0:00 [git-annex] <defunct>
+8708 pts/2 Z+ 0:00 [git-annex] <defunct>
+9821 ? Z 0:00 [git-annex] <defunct>
+9841 pts/2 Z+ 0:00 [git-annex] <defunct>
+10462 ? Z 0:00 [git-annex] <defunct>
+10522 pts/2 Z 0:00 [git-annex] <defunct>
+12777 pts/2 Z+ 0:00 [git-annex] <defunct>
+13878 pts/2 Z+ 0:00 [git-annex] <defunct>
+14254 ? Z 0:00 [git-annex] <defunct>
+14276 pts/2 Z+ 0:00 [git-annex] <defunct>
+15932 ? Sl 0:00 git-annex transferkeys --readfd 37 --writefd 20
+16022 pts/2 Sl 0:00 git-annex transferkeys --readfd 28 --writefd 22
+16079 pts/2 S 0:00 git --git-dir=/mnt/debian/home/me/annex-backup/.git --work-tree=/mnt/debian/home/me/annex-backup cat-file --batch
+16081 ? S 0:00 git --git-dir=/home/me/annex/.git --work-tree=/home/me/annex cat-file --batch
+31565 pts/2 Sl+ 0:20 git-annex webapp
+31580 pts/2 S+ 0:00 git --git-dir=/mnt/debian/home/me/annex-backup/.git --work-tree=/mnt/debian/home/me/annex-backup cat-file --batch
+31590 pts/2 S+ 0:00 git --git-dir=/mnt/debian/home/me/annex-backup/.git --work-tree=/mnt/debian/home/me/annex-backup cat-file --batch
+31618 pts/2 S+ 0:00 git --git-dir=/mnt/debian/home/me/annex-backup/.git --work-tree=/mnt/debian/home/me/annex-backup cat-file --batch
+31635 ? Sl 9:26 /usr/lib/firefox/firefox /mnt/debian/home/me/annex-backup/.git/annex/webapp.html
+31689 pts/2 SN+ 0:00 git --git-dir=/mnt/debian/home/me/annex-backup/.git --work-tree=/mnt/debian/home/me/annex-backup check-attr -z --stdin annex.backend annex.numcopies --
+31812 pts/2 Z 0:00 [git-annex] <defunct>
+31835 ? Ss 0:02 ssh: .git/annex/ssh/example.net [mux]
+"""]]
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/Zombie_processes_and__47__or_stuck_git_processes/comment_1_0f8b248025722309e9577d7dad74b76b._comment b/doc/bugs/Zombie_processes_and__47__or_stuck_git_processes/comment_1_0f8b248025722309e9577d7dad74b76b._comment
new file mode 100644
index 000000000..578fecb58
--- /dev/null
+++ b/doc/bugs/Zombie_processes_and__47__or_stuck_git_processes/comment_1_0f8b248025722309e9577d7dad74b76b._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 1"
+ date="2013-11-03T01:12:25Z"
+ content="""
+This is apparently the same repository where [[all_this_went_on|bugs/Unnecessary_remote_transfers]].
+
+I don't know if this is indicative of a problem. I see more zombies than I would normally expect, but I don't know if the number is growing, or shrinking, or staying the same. You should at least look at ps -f to see which of the multiple git-annex assistant daemons you have configured to run on this machine (not a usual configuration) is the parent of the zombies.
+"""]]
diff --git a/doc/bugs/Zombie_processes_and__47__or_stuck_git_processes/comment_2_f5f7db688a2a93ee7453674fb742043b._comment b/doc/bugs/Zombie_processes_and__47__or_stuck_git_processes/comment_2_f5f7db688a2a93ee7453674fb742043b._comment
new file mode 100644
index 000000000..ceb05ea0c
--- /dev/null
+++ b/doc/bugs/Zombie_processes_and__47__or_stuck_git_processes/comment_2_f5f7db688a2a93ee7453674fb742043b._comment
@@ -0,0 +1,52 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmNu4V5fvpLlBhaCUfXXOB0MI5NXwh8SkU"
+ nickname="Adam"
+ subject="comment 2"
+ date="2013-11-03T01:19:42Z"
+ content="""
+Indeed. I've been looking forward to setting up git-annex assistant for a long time, waiting until I had more free time, and was finally pushed to do it when I had a weird problem with Dropbox. I'm not sure what I did wrong to make such a mess, haha.
+
+I see \"5510 git-annex assistant\" and \"31565 git-annex webapp\"--does the \"webapp\" one count as an assistant process too?
+[[!format sh \"\"\"$ ps -ef | gi git
+UID PID PPID C STIME TTY TIME CMD
+me 3404 31565 0 17:44 pts/2 00:00:04 [git-annex] <defunct>
+me 5457 31565 0 17:59 pts/2 00:00:00 [git-annex] <defunct>
+me 5510 1 0 17:59 ? 00:00:06 git-annex assistant
+me 5522 5510 0 17:59 ? 00:00:00 git --git-dir=/home/me/annex/.git --work-tree=/home/me/annex cat-file --batch
+me 5573 5510 0 17:59 ? 00:00:00 git --git-dir=/home/me/annex/.git --work-tree=/home/me/annex cat-file --batch
+me 5679 5510 0 17:59 ? 00:00:00 git --git-dir=/home/me/annex/.git --work-tree=/home/me/annex check-attr -z --stdin annex.backend annex.numcopies --
+me 5680 5510 0 17:59 ? 00:00:03 [git-annex] <defunct>
+me 5710 5510 0 18:00 ? 00:00:00 [git-annex] <defunct>
+me 5732 31565 0 18:00 pts/2 00:00:00 [git-annex] <defunct>
+me 5752 31565 0 18:00 pts/2 00:00:00 [git-annex] <defunct>
+me 5785 1 0 18:01 ? 00:00:00 ssh: .git/annex/ssh/example.net [mux]
+me 5905 5510 0 18:02 ? 00:00:00 [git-annex] <defunct>
+me 5923 5510 0 18:02 ? 00:00:00 [git-annex] <defunct>
+me 6513 31565 0 18:05 pts/2 00:00:00 [git-annex] <defunct>
+me 6552 5510 0 18:06 ? 00:00:00 [git-annex] <defunct>
+me 7797 5510 0 18:09 ? 00:00:00 [git-annex] <defunct>
+me 7873 31565 0 18:09 pts/2 00:00:00 [git-annex] <defunct>
+me 8708 31565 0 18:10 pts/2 00:00:00 [git-annex] <defunct>
+me 9821 5510 0 18:12 ? 00:00:00 [git-annex] <defunct>
+me 9841 31565 0 18:14 pts/2 00:00:00 [git-annex] <defunct>
+me 10462 5510 0 18:23 ? 00:00:00 [git-annex] <defunct>
+me 10522 31565 0 18:24 pts/2 00:00:00 [git-annex] <defunct>
+me 12777 31565 0 18:34 pts/2 00:00:00 [git-annex] <defunct>
+me 13878 31565 0 18:35 pts/2 00:00:00 [git-annex] <defunct>
+me 14254 5510 0 18:36 ? 00:00:00 [git-annex] <defunct>
+me 14276 31565 0 18:36 pts/2 00:00:00 [git-annex] <defunct>
+me 15932 5510 0 18:55 ? 00:00:00 git-annex transferkeys --readfd 37 --writefd 20
+me 16022 31565 0 18:55 pts/2 00:00:00 git-annex transferkeys --readfd 28 --writefd 22
+me 16079 16022 0 18:55 pts/2 00:00:00 git --git-dir=/mnt/debian/home/me/annex-backup/.git --work-tree=/mnt/debian/home/me/annex-backup cat-file --batch
+me 16081 15932 0 18:55 ? 00:00:00 git --git-dir=/home/me/annex/.git --work-tree=/home/me/annex cat-file --batch
+me 25136 25135 0 20:15 pts/6 00:00:00 grep -i git
+me 31565 31478 0 17:42 pts/2 00:00:21 git-annex webapp
+me 31580 31565 0 17:42 pts/2 00:00:00 git --git-dir=/mnt/debian/home/me/annex-backup/.git --work-tree=/mnt/debian/home/me/annex-backup cat-file --batch
+me 31590 31565 0 17:42 pts/2 00:00:00 git --git-dir=/mnt/debian/home/me/annex-backup/.git --work-tree=/mnt/debian/home/me/annex-backup cat-file --batch
+me 31618 31565 0 17:42 pts/2 00:00:00 git --git-dir=/mnt/debian/home/me/annex-backup/.git --work-tree=/mnt/debian/home/me/annex-backup cat-file --batch
+me 31635 27578 8 17:42 ? 00:13:42 /usr/lib/firefox/firefox /mnt/debian/home/me/annex-backup/.git/annex/webapp.html
+me 31689 31565 0 17:42 pts/2 00:00:00 git --git-dir=/mnt/debian/home/me/annex-backup/.git --work-tree=/mnt/debian/home/me/annex-backup check-attr -z --stdin annex.backend annex.numcopies --
+me 31812 31565 0 17:42 pts/2 00:00:00 [git-annex] <defunct>
+me 31835 1 0 17:42 ? 00:00:02 ssh: .git/annex/ssh/example.net [mux]\"\"\"]]
+
+"""]]
diff --git a/doc/bugs/Zombie_processes_and__47__or_stuck_git_processes/comment_3_ffcae976aa3dc2426188797c1aaffb82._comment b/doc/bugs/Zombie_processes_and__47__or_stuck_git_processes/comment_3_ffcae976aa3dc2426188797c1aaffb82._comment
new file mode 100644
index 000000000..78e816f06
--- /dev/null
+++ b/doc/bugs/Zombie_processes_and__47__or_stuck_git_processes/comment_3_ffcae976aa3dc2426188797c1aaffb82._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 3"
+ date="2013-11-03T01:31:26Z"
+ content="""
+`ps fax` is much easier to read
+
+Yes, the assistant can be started by either `git annex assistant` or, if it's not already running, `git annex webapp`
+"""]]
diff --git a/doc/bugs/Zombie_processes_and__47__or_stuck_git_processes/comment_4_8a7ff6841ad7c27ead06bf12f46b20a0._comment b/doc/bugs/Zombie_processes_and__47__or_stuck_git_processes/comment_4_8a7ff6841ad7c27ead06bf12f46b20a0._comment
new file mode 100644
index 000000000..2bf32bd37
--- /dev/null
+++ b/doc/bugs/Zombie_processes_and__47__or_stuck_git_processes/comment_4_8a7ff6841ad7c27ead06bf12f46b20a0._comment
@@ -0,0 +1,49 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmNu4V5fvpLlBhaCUfXXOB0MI5NXwh8SkU"
+ nickname="Adam"
+ subject="comment 4"
+ date="2013-11-03T01:35:32Z"
+ content="""
+Ah, thank you. I get lost in ps's man page. :)
+
+[[!format sh \"\"\"
+31635 ? Rl 16:16 \_ /usr/lib/firefox/firefox /mnt/debian/home/me/annex-backup/.git/annex/webapp.html
+31565 pts/2 Sl+ 0:21 | \_ git-annex webapp
+31580 pts/2 S+ 0:00 | \_ git --git-dir=/mnt/debian/home/me/annex-backup/.git --work-tree=/mnt/debian/home/me/annex-backup cat-file --batch
+31590 pts/2 S+ 0:00 | \_ git --git-dir=/mnt/debian/home/me/annex-backup/.git --work-tree=/mnt/debian/home/me/annex-backup cat-file --batch
+31618 pts/2 S+ 0:00 | \_ git --git-dir=/mnt/debian/home/me/annex-backup/.git --work-tree=/mnt/debian/home/me/annex-backup cat-file --batch
+31689 pts/2 SN+ 0:00 | \_ git --git-dir=/mnt/debian/home/me/annex-backup/.git --work-tree=/mnt/debian/home/me/annex-backup check-attr -z --stdin annex.backend annex.numcopies --
+31812 pts/2 Z 0:00 | \_ [git-annex] <defunct>
+ 3404 pts/2 Z 0:04 | \_ [git-annex] <defunct>
+ 5457 pts/2 Z+ 0:00 | \_ [git-annex] <defunct>
+ 5732 pts/2 Z+ 0:00 | \_ [git-annex] <defunct>
+ 5752 pts/2 Z+ 0:00 | \_ [git-annex] <defunct>
+ 6513 pts/2 Z+ 0:00 | \_ [git-annex] <defunct>
+ 7873 pts/2 Z 0:00 | \_ [git-annex] <defunct>
+ 8708 pts/2 Z+ 0:00 | \_ [git-annex] <defunct>
+ 9841 pts/2 Z+ 0:00 | \_ [git-annex] <defunct>
+10522 pts/2 Z 0:00 | \_ [git-annex] <defunct>
+12777 pts/2 Z+ 0:00 | \_ [git-annex] <defunct>
+13878 pts/2 Z+ 0:00 | \_ [git-annex] <defunct>
+14276 pts/2 Z+ 0:00 | \_ [git-annex] <defunct>
+16022 pts/2 Sl 0:00 | \_ git-annex transferkeys --readfd 28 --writefd 22
+16079 pts/2 S 0:00 | \_ git --git-dir=/mnt/debian/home/me/annex-backup/.git --work-tree=/mnt/debian/home/me/annex-backup cat-file --batch
+26828 pts/6 S+ 0:00 | \_ grep -i git
+31835 ? Ss 0:02 ssh: .git/annex/ssh/example.net [mux]
+ 5510 ? Sl 0:06 git-annex assistant
+ 5522 ? S 0:00 \_ git --git-dir=/home/me/annex/.git --work-tree=/home/me/annex cat-file --batch
+ 5573 ? S 0:00 \_ git --git-dir=/home/me/annex/.git --work-tree=/home/me/annex cat-file --batch
+ 5679 ? SN 0:00 \_ git --git-dir=/home/me/annex/.git --work-tree=/home/me/annex check-attr -z --stdin annex.backend annex.numcopies --
+ 5680 ? Z 0:03 \_ [git-annex] <defunct>
+ 5710 ? Z 0:00 \_ [git-annex] <defunct>
+ 5905 ? Z 0:00 \_ [git-annex] <defunct>
+ 5923 ? Z 0:00 \_ [git-annex] <defunct>
+ 6552 ? Z 0:00 \_ [git-annex] <defunct>
+ 7797 ? Z 0:00 \_ [git-annex] <defunct>
+ 9821 ? Z 0:00 \_ [git-annex] <defunct>
+10462 ? Z 0:00 \_ [git-annex] <defunct>
+14254 ? Z 0:00 \_ [git-annex] <defunct>
+15932 ? Sl 0:00 \_ git-annex transferkeys --readfd 37 --writefd 20
+16081 ? S 0:00 \_ git --git-dir=/home/me/annex/.git --work-tree=/home/me/annex cat-file --batch
+ 5785 ? Ss 0:00 ssh: .git/annex/ssh/example.net [mux] \"\"\"]]
+"""]]
diff --git a/doc/bugs/Zombie_processes_and__47__or_stuck_git_processes/comment_5_406fdee0728680774a69d28446163f10._comment b/doc/bugs/Zombie_processes_and__47__or_stuck_git_processes/comment_5_406fdee0728680774a69d28446163f10._comment
new file mode 100644
index 000000000..f8f223524
--- /dev/null
+++ b/doc/bugs/Zombie_processes_and__47__or_stuck_git_processes/comment_5_406fdee0728680774a69d28446163f10._comment
@@ -0,0 +1,26 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 5"
+ date="2013-11-03T02:33:14Z"
+ content="""
+I believe that these zombies were all caused by switching between repository views in the webapp. I was able to reproduce 1 zombie per switch between repos.
+
+There are a few other places where git-annex execs itself, but not many, and most of them are often used and it would be noticed if they were crypts from which pour forth the living dead. (Oddly the TV show I was thinking about watching this evening.)
+
+<pre>
+joey@darkstar:~/src/git-annex>git grep readProgramFile
+Assistant/Repair.hs: program <- readProgramFile
+Assistant/Threads/Cronner.hs: program <- liftIO $ readProgramFile
+Assistant/Threads/Cronner.hs: program <- readProgramFile
+Assistant/Threads/Transferrer.hs: program <- liftIO readProgramFile
+Assistant/TransferSlots.hs: program <- liftIO readProgramFile
+Assistant/WebApp/Control.hs: program <- readProgramFile
+Assistant/WebApp/OtherRepos.hs: program <- readProgramFile
+Assistant/XMPP/Git.hs: program <- readProgramFile
+Command/Assistant.hs: program <- readProgramFile
+Config/Files.hs:readProgramFile :: IO FilePath
+Config/Files.hs:readProgramFile = do
+Remote/Git.hs: program <- readProgramFile
+</pre>
+"""]]
diff --git a/doc/bugs/__34__Adding_4923_files__34___is_really_slow.mdwn b/doc/bugs/__34__Adding_4923_files__34___is_really_slow.mdwn
new file mode 100644
index 000000000..148fa7325
--- /dev/null
+++ b/doc/bugs/__34__Adding_4923_files__34___is_really_slow.mdwn
@@ -0,0 +1,100 @@
+Wow, what a great archiving system. Thank you for all your work on git annex!
+
+### Please describe the problem.
+
+I was using 'git annex assistant' on a brand-new annex that I created today. I had previously added about 20GB of data and a couple thousand files, mostly MP4 videos and MP3 music.
+
+I then used regular 'mv' to add a folder containing about 20GB of music. This went well for a while—git annex assistant added two groups of files, containing roughly 700 and 1000 MP3s each. But the third group contained 4,923 files, and it's taking a really long time to import.
+
+CPU usage is pretty consistently near 100%. According to the log, the files are being processed slowly.
+
+### What steps will reproduce the problem?
+
+I don't want to try to reproduce this problem until the MP3s finish being imported. I can try again later with thousands of digital photos if that would help.
+
+### What version of git-annex are you using? On what operating system?
+
+Version: 4.20130709.1
+Build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP
+
+Ubuntu 12.04.2 LTS
+
+### Please provide any additional information below.
+
+Here's the 'top' output and a snippet of the log. Let me know if you need anything else.
+
+[[!format sh """
+# CPU usage
+
+ PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
+ 584 ...me... 20 0 776m 147m 16m S 100 0.9 181:16.87 git-annex
+
+
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+[201ok
+add music/Pop/Various/Like, Omigod! The 80s Pop Culture Box (totally)/._3-06 Words.mp3 3-0(checksum...) 7-22 14:52:14 EDT] TransferScanner: queued Upload UUID "8dbe75a4-b065-46fd-99f7-22599b2eaf06" music/Rock/Aerosmith/A Little South of Sanity/._2-08 Walk This Way.mp3 Nothing : expensive scan found missing object
+[2013-07-22 14:52:34 EDT] Transferrer: Transferring: Upload UUID "8dbe75a4-b065-46fd-99f7-22599b2eaf06" music/Rock/Aerosmith/A Little South of Sanity/._2-08 Walk This Way.mp3 Nothing
+[2013-07-22 14:52:34 EDT] chat: git ["--git-dir=/mnt/storage/private/annex/.git","--work-tree=/mnt/storage/private/annex","hash-object","-t","blob","-w","--stdin","--no-filters"]
+[ok
+add music/Pop/Various/Like, Omigod! The 80s Pop Culture Box (totally)/._4-05 Our House.mp3 2013-0(checksum...) 7-22 14:52:34 EDT] TransferWatcher: transfer starting: Upload UUID "8dbe75a4-b065-46fd-99f7-22599b2eaf06" music/Rock/Aerosmith/A Little South of Sanity/._2-08 Walk This Way.mp3 Nothing
+[2013-07-22 14:52:54 EDT] TransferWatcher: transfer finishing: Transfer {transferDirection = Upload, transferUUID = UUID "8dbe75a4-b065-46fd-99f7-22599b2eaf06", transferKey = Key {keyName = "a8ddf79be61cf4a5ab3c7c8e95d8c259ceb102410dff50eb1260e7d818f8c5a8.mp3", keyBackendName = "SHA256E", keySize = Just 70, keyMtime = Nothing}}
+[2013-07-22 14:52:54 EDT] chat: git ["--git-dir=/mnt/storage/private/annex/.git","--work-tree=/mnt/storage/private/annex","hash-object","-t","blob","-w","--stdin","--no-filters"]
+ok
+add music/Pop/Various/Like, Omigod! The 80s Pop Culture Box (totally)/7-15 Never Gonna Give You Up.mp3 (checksum...) [2013-07-22 14:52:54 EDT] read: sha256sum ["/mnt/storage/private/annex/.git/annex/tmp/7-15 Never Gonna Give You Up584.mp3"]
+[2013-07-22 14:52:55 EDT] chat: git ["--git-dir=/mnt/storage/private/annex/.git","--work-tree=/mnt/storage/private/annex","hash-object","-t","blob","-w","--stdin","--no-filters"]
+[ok
+add music/Pop/Various/Like, Omigod! The 80s Pop Culture Box (totally)/3-09 Down Under.mp3 2013-07-(checksum...) 22 14:52:55 EDT] TransferScanner: queued Upload UUID "8dbe75a4-b065-46fd-99f7-22599b2eaf06" music/Rock/Aerosmith/A Little South of Sanity/._2-09 Dude (Looks Like A Lady).mp3 Nothing : expensive scan found missing object
+[2013-07-22 14:52:55 EDT] read: sha256sum ["/mnt/storage/private/annex/.git/annex/tmp/3-09 Down Under584.mp3"]
+[2013-07-22 14:52:55 EDT] Transferrer: Transferring: Upload UUID "8dbe75a4-b065-46fd-99f7-22599b2eaf06" music/Rock/Aerosmith/A Little South of Sanity/._2-09 Dude (Looks Like A Lady).mp3 Nothing
+[2013-07-22 14:52:55 EDT] chat: git ["--git-dir=/mnt/storage/private/annex/.git","--work-tree=/mnt/storage/private/annex","hash-object","-t","blob","-w","--stdin","--no-filters"]
+[ok
+add music/Pop/Various/Like, Omigod! The 80s Pop Culture Box (totally)/7-19 Right Here Waiting.mp3 2013(checksum...) -07-22 14:52:55 EDT] TransferWatcher: transfer starting: Upload UUID "8dbe75a4-b065-46fd-99f7-22599b2eaf06" music/Rock/Aerosmith/A Little South of Sanity/._2-09 Dude (Looks Like A Lady).mp3 Nothing
+[2013-07-22 14:52:55 EDT] read: sha256sum ["/mnt/storage/private/annex/.git/annex/tmp/7-19 Right Here Waiting584.mp3"]
+[2013-07-22 14:52:55 EDT] TransferWatcher: transfer finishing: Transfer {transferDirection = Upload, transferUUID = UUID "8dbe75a4-b065-46fd-99f7-22599b2eaf06", transferKey = Key {keyName = "a8ddf79be61cf4a5ab3c7c8e95d8c259ceb102410dff50eb1260e7d818f8c5a8.mp3", keyBackendName = "SHA256E", keySize = Just 70, keyMtime = Nothing}}
+[2013-07-22 14:52:55 EDT] chat: git ["--git-dir=/mnt/storage/private/annex/.git","--work-tree=/mnt/storage/private/annex","hash-object","-t","blob","-w","--stdin","--no-filters"]
+ok
+add music/Pop/Various/Like, Omigod! The 80s Pop Culture Box (totally)/._1-04 Another One Bites The Dust.mp3 (checksum...) [2013-07-22 14:53:15 EDT] chat: git ["--git-dir=/mnt/storage/private/annex/.git","--work-tree=/mnt/storage/private/annex","hash-object","-t","blob","-w","--stdin","--no-filters"]
+[2013ok
+add music/Pop/Various/Like, Omigod! The 80s Pop Culture Box (totally)/2-08 Hold On Loosely.mp3 -07(checksum...) -22 14:53:15 EDT] TransferScanner: queued Upload UUID "8dbe75a4-b065-46fd-99f7-22599b2eaf06" music/Rock/Aerosmith/A Little South of Sanity/._2-10 What It Takes.mp3 Nothing : expensive scan found missing object
+[2013-07-22 14:53:15 EDT] read: sha256sum ["/mnt/storage/private/annex/.git/annex/tmp/2-08 Hold On Loosely584.mp3"]
+[2013-07-22 14:53:15 EDT] Transferrer: Transferring: Upload UUID "8dbe75a4-b065-46fd-99f7-22599b2eaf06" music/Rock/Aerosmith/A Little South of Sanity/._2-10 What It Takes.mp3 Nothing
+[2013-07-22 14:53:15 EDT] chat: git ["--git-dir=/mnt/storage/private/annex/.git","--work-tree=/mnt/storage/private/annex","hash-object","-t","blob","-w","--stdin","--no-filters"]
+[ok
+add music/Pop/Various/Like, Omigod! The 80s Pop Culture Box (totally)/._6-11 Kyrie.mp3 201(checksum...) 3-07-22 14:53:15 EDT] TransferWatcher: transfer starting: Upload UUID "8dbe75a4-b065-46fd-99f7-22599b2eaf06" music/Rock/Aerosmith/A Little South of Sanity/._2-10 What It Takes.mp3 Nothing
+[2013-07-22 14:53:36 EDT] TransferWatcher: transfer finishing: Transfer {transferDirection = Upload, transferUUID = UUID "8dbe75a4-b065-46fd-99f7-22599b2eaf06", transferKey = Key {keyName = "a8ddf79be61cf4a5ab3c7c8e95d8c259ceb102410dff50eb1260e7d818f8c5a8.mp3", keyBackendName = "SHA256E", keySize = Just 70, keyMtime = Nothing}}
+[2013-07-22 14:53:36 EDT] chat: git ["--git-dir=/mnt/storage/private/annex/.git","--work-tree=/mnt/storage/private/annex","hash-object","-t","blob","-w","--stdin","--no-filters"]
+ok
+add music/Pop/Various/Like, Omigod! The 80s Pop Culture Box (totally)/._5-03 I'm So Excited.mp3 (checksum...) [2013-07-22 14:53:56 EDT] chat: git ["--git-dir=/mnt/storage/private/annex/.git","--work-tree=/mnt/storage/private/annex","hash-object","-t","blob","-w","--stdin","--no-filters"]
+[2013ok
+add music/Pop/Various/Like, Omigod! The 80s Pop Culture Box (totally)/7-20 Roam.mp3 -07-(checksum...) 22 14:53:56 EDT] TransferScanner: queued Upload UUID "8dbe75a4-b065-46fd-99f7-22599b2eaf06" music/Rock/Aerosmith/A Little South of Sanity/._2-11 Sweet Emotion.mp3 Nothing : expensive scan found missing object
+[2013-07-22 14:53:56 EDT] read: sha256sum ["/mnt/storage/private/annex/.git/annex/tmp/7-20 Roam584.mp3"]
+[2013-07-22 14:53:57 EDT] Transferrer: Transferring: Upload UUID "8dbe75a4-b065-46fd-99f7-22599b2eaf06" music/Rock/Aerosmith/A Little South of Sanity/._2-11 Sweet Emotion.mp3 Nothing
+[2013-07-22 14:53:57 EDT] chat: git ["--git-dir=/mnt/storage/private/annex/.git","--work-tree=/mnt/storage/private/annex","hash-object","-t","blob","-w","--stdin","--no-filters"]
+[2ok
+add music/Pop/Various/Like, Omigod! The 80s Pop Culture Box (totally)/._3-20 Goodbye To You.mp3 013-07(checksum...) -22 14:53:57 EDT] TransferWatcher: transfer finishing: Transfer {transferDirection = Upload, transferUUID = UUID "8dbe75a4-b065-46fd-99f7-22599b2eaf06", transferKey = Key {keyName = "a8ddf79be61cf4a5ab3c7c8e95d8c259ceb102410dff50eb1260e7d818f8c5a8.mp3", keyBackendName = "SHA256E", keySize = Just 70, keyMtime = Nothing}}
+[2013-07-22 14:54:17 EDT] chat: git ["--git-dir=/mnt/storage/private/annex/.git","--work-tree=/mnt/storage/private/annex","hash-object","-t","blob","-w","--stdin","--no-filters"]
+ok
+add music/Pop/Various/Like, Omigod! The 80s Pop Culture Box (totally)/._7-18 Don't Worry Be Happy.mp3 (checksum...) [2013-07-22 14:54:37 EDT] chat: git ["--git-dir=/mnt/storage/private/annex/.git","--work-tree=/mnt/storage/private/annex","hash-object","-t","blob","-w","--stdin","--no-filters"]
+[ok
+add music/Pop/Various/Like, Omigod! The 80s Pop Culture Box (totally)/._3-04 Rock This Town.mp3 2013-(checksum...) 07-22 14:54:37 EDT] TransferScanner: queued Upload UUID "8dbe75a4-b065-46fd-99f7-22599b2eaf06" music/Rock/Aerosmith/A Little South of Sanity/1-01 Eat The Rich.mp3 Nothing : expensive scan found missing object
+[2013-07-22 14:54:57 EDT] Transferrer: Transferring: Upload UUID "8dbe75a4-b065-46fd-99f7-22599b2eaf06" music/Rock/Aerosmith/A Little South of Sanity/1-01 Eat The Rich.mp3 Nothing
+[2013-07-22 14:54:57 EDT] chat: git ["--git-dir=/mnt/storage/private/annex/.git","--work-tree=/mnt/storage/private/annex","hash-object","-t","blob","-w","--stdin","--no-filters"]
+ok
+add music/Pop/Various/Like, Omigod! The 80s Pop Culture Box (totally)/._7-13 Since You've Been Gone.mp3 [2013-(checksum...) 07-22 14:54:57 EDT] TransferWatcher: transfer finishing: Transfer {transferDirection = Upload, transferUUID = UUID "8dbe75a4-b065-46fd-99f7-22599b2eaf06", transferKey = Key {keyName = "2cb6e7b6ee77f9f98e01e942185265dfe18868503e93d78201485672e6939ab7.mp3", keyBackendName = "SHA256E", keySize = Just 6354105, keyMtime = Nothing}}
+[2013-07-22 14:55:18 EDT] chat: git ["--git-dir=/mnt/storage/private/annex/.git","--work-tree=/mnt/storage/private/annex","hash-object","-t","blob","-w","--stdin","--no-filters"]
+ok
+add music/Pop/Various/Like, Omigod! The 80s Pop Culture Box (totally)/._2-09 Believe It Or Not (Theme From _Greatest American Hero_).mp3 (checksum...) [2013-07-22 14:55:38 EDT] chat: git ["--git-dir=/mnt/storage/private/annex/.git","--work-tree=/mnt/storage/private/annex","hash-object","-t","blob","-w","--stdin","--no-filters"]
+[ok
+add music/Pop/Various/Like, Omigod! The 80s Pop Culture Box (totally)/7-14 Only In My Dreams.mp3 2013(checksum...) -07-22 14:55:38 EDT] TransferScanner: queued Upload UUID "8dbe75a4-b065-46fd-99f7-22599b2eaf06" music/Rock/Aerosmith/A Little South of Sanity/1-02 Love In An Elevator.mp3 Nothing : expensive scan found missing object
+[2013-07-22 14:55:38 EDT] read: sha256sum ["/mnt/storage/private/annex/.git/annex/tmp/7-14 Only In My Dreams584.mp3"]
+[2013-07-22 14:55:38 EDT] Transferrer: Transferring: Upload UUID "8dbe75a4-b065-46fd-99f7-22599b2eaf06" music/Rock/Aerosmith/A Little South of Sanity/1-02 Love In An Elevator.mp3 Nothing
+[2013-07-22 14:55:38 EDT] chat: git ["--git-dir=/mnt/storage/private/annex/.git","--work-tree=/mnt/storage/private/annex","hash-object","-t","blob","-w","--stdin","--no-filters"]
+[2013-ok
+add music/Pop/Various/Like, Omigod! The 80s Pop Culture Box (totally)/._4-08 Talking In Your Sleep.mp3 07-2(checksum...) 2 14:55:38 EDT] TransferWatcher: transfer finishing: Transfer {transferDirection = Upload, transferUUID = UUID "8dbe75a4-b065-46fd-99f7-22599b2eaf06", transferKey = Key {keyName = "7cd4b9aefb99f044c5f3b24e9890f45673a63ada3b71e7399e17eb1d710ea0f6.mp3", keyBackendName = "SHA256E", keySize = Just 7181660, keyMtime = Nothing}}
+
+# End of transcript or log.
+"""]]
+
+[[!meta title="direct mode mappings scale badly with thousands of identical files"]]
diff --git a/doc/bugs/__34__Adding_4923_files__34___is_really_slow/comment_2_5f3b9f00bc31ce71d695c008971ed7fd._comment b/doc/bugs/__34__Adding_4923_files__34___is_really_slow/comment_2_5f3b9f00bc31ce71d695c008971ed7fd._comment
new file mode 100644
index 000000000..9030d73f7
--- /dev/null
+++ b/doc/bugs/__34__Adding_4923_files__34___is_really_slow/comment_2_5f3b9f00bc31ce71d695c008971ed7fd._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://emk.myopenid.com/"
+ ip="24.2.150.84"
+ subject="Interesting speedup"
+ date="2013-07-22T19:45:58Z"
+ content="""
+I noticed that there were a lot of junk files with names of the form \"._*\" in the \"music\" directory I had added. These are created by older MacOS X systems storing Mac-related files on Unix file systems. (I think they're supposed to contain the old resource fork or something weird like that.)
+
+So while the endless import was running, I decided to live dangerous and delete the offending files:
+
+ find music/ -name ._\* -print0 | xargs -0 rm
+
+A few seconds later, the 4,923 file import finished.
+
+If I discover anything else interesting, I'll mention it. Once again, many thanks!
+"""]]
diff --git a/doc/bugs/__34__Adding_4923_files__34___is_really_slow/comment_2_708b02dd06a1eed6b5ded9eb7aa9e7a8._comment b/doc/bugs/__34__Adding_4923_files__34___is_really_slow/comment_2_708b02dd06a1eed6b5ded9eb7aa9e7a8._comment
new file mode 100644
index 000000000..8ad833ca9
--- /dev/null
+++ b/doc/bugs/__34__Adding_4923_files__34___is_really_slow/comment_2_708b02dd06a1eed6b5ded9eb7aa9e7a8._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.1.10"
+ subject="comment 2"
+ date="2013-07-22T20:15:03Z"
+ content="""
+I doubt that removing the junk files did anything, unless perhaps it deleted all the files that it had not yet gotten around to adding, and so short-circuited the slow part of the process.
+
+Adding a lot of files in a repository in direct mode can be slowed down some because it has to run `git hash-object` once per file to stage the symlink. It may be possible to speed this up by changing the code to write the symlink to disk in a temporary location, which would then allow it to use the single `git hash-object --batch` it keeps running, and just tell it to hash that file.
+
+It seems likely to me though that the sha256sum it has to run on every file before adding it is responsible for more of the slowdown. After all, that has to read every file from disk (here apparently from `/mnt` which, if it's a USB device etc could be pretty slow.) You can benchmark this at home: First look at the debug log to find the start and finish times of it adding all those files. Then clear all disk caches. Then run sha256sum on every file and time that. Compare & post here. ;)
+
+Adding to the overhead, the assistant is uploading every file it adds to the remote with uuid 8dbe75a4-b065-46fd-99f7-22599b2eaf06. Which means yet another read of the file, and more work depending on what kind of remote that is and how expensive it is to transfer to it.
+
+So, in summary, hashing, recording in git, and backing up a lot of files is really slow. It would be good to work out which parts are the slow parts, so we can think about whether that speed is acceptable for that part.
+"""]]
diff --git a/doc/bugs/__34__Adding_4923_files__34___is_really_slow/comment_3_6a735b7875d2a0c92df6786dd649985d._comment b/doc/bugs/__34__Adding_4923_files__34___is_really_slow/comment_3_6a735b7875d2a0c92df6786dd649985d._comment
new file mode 100644
index 000000000..f95c368d6
--- /dev/null
+++ b/doc/bugs/__34__Adding_4923_files__34___is_really_slow/comment_3_6a735b7875d2a0c92df6786dd649985d._comment
@@ -0,0 +1,28 @@
+[[!comment format=mdwn
+ username="http://emk.myopenid.com/"
+ ip="24.2.150.84"
+ subject="That particular &quot;Adding 4923 files&quot; was unusually slow"
+ date="2013-07-23T11:46:03Z"
+ content="""
+That particular add took most of an afternoon, and didn't complete until I deleted all the junk files.
+
+I later did \"adding ~10,000 files\" and \"adding ~15,000 files\", all of which ran in an hour or so at most, even though I had added a second remote. So this isn't solely a disk I/O bottleneck.
+
+One peculiar thing about the garbage files: There were 1,626 of them, and they were all tiny:
+
+```
+00000000 00 05 16 07 00 02 00 00 00 00 00 00 00 00 00 00 |................|
+00000010 00 00 00 00 00 00 00 00 00 01 00 00 00 09 00 00 |................|
+00000020 00 26 00 00 00 20 4d 50 47 33 68 6f 6f 6b 00 00 |.&... MPG3hook..|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+*
+00000046
+```
+
+1,581 of these files had the SHA1 hash code 5460c190ef495baf43e2cd001687be272cd6a9d2, and all but one of the rest had the hash code d4b1d36c67149c981ea4b3d8392050188673817c. So if there's anything weird about this repository, it was thousands of tiny identical files in the same 'git annex assistant' adding pass. Once I scrubbed those files on later imports, things were considerably faster even when the file count increased dramatically.
+
+You can go ahead and close this bug report if that seems reasonable—I just thought the weird behavior was worth reporting, in case somebody else runs it into again.
+
+And thank you for an awesome program!
+
+"""]]
diff --git a/doc/bugs/__34__Adding_4923_files__34___is_really_slow/comment_4_7e768908ba6983ea13af27635c4a947f._comment b/doc/bugs/__34__Adding_4923_files__34___is_really_slow/comment_4_7e768908ba6983ea13af27635c4a947f._comment
new file mode 100644
index 000000000..0971f1c34
--- /dev/null
+++ b/doc/bugs/__34__Adding_4923_files__34___is_really_slow/comment_4_7e768908ba6983ea13af27635c4a947f._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.110"
+ subject="comment 4"
+ date="2013-07-26T22:28:37Z"
+ content="""
+Did some playing around, and I am seeing a progressive slowdown when adding lots of identical files in direct mode.
+This does not happen when the files have different content, and thinking about it, it's pretty clear what's going on:
+
+When there are a ton of files with the same content, the map file that has to list all the files using this content
+get larger and larger. Each file added has to read and re-write the map file, which is obviously not going to scale well to thousands of duplicate files.
+"""]]
diff --git a/doc/bugs/__34__Configuring_Jabber_Account__34___fails_with_a___34__Network_unreachable__34___error..mdwn b/doc/bugs/__34__Configuring_Jabber_Account__34___fails_with_a___34__Network_unreachable__34___error..mdwn
new file mode 100644
index 000000000..9befd7c80
--- /dev/null
+++ b/doc/bugs/__34__Configuring_Jabber_Account__34___fails_with_a___34__Network_unreachable__34___error..mdwn
@@ -0,0 +1,39 @@
+### Please describe the problem.
+
+After setting the username (xyz@gmail.com) and the password the webapp takes several minutes until eventually an error message is displayed stating that:
+
+ Unable to connect to the Jabber server. Maybe you entered the wrong password? (Error message: host gmail.com:5222 failed: connect: does not exist (Network is unreachable))
+
+Testing with xyz@xmpp.l.gmail.com yields:
+
+ Unable to connect to the Jabber server. Maybe you entered the wrong password? (Error message: host xmpp.l.google.com:5222 failed: AuthenticationFailure)
+
+What's strange about that is that the exact same procedure works on a different (Ubuntu-) system with almost no time spend.
+
+### What steps will reproduce the problem?
+
+Trying to set up the jabber connection.
+
+### What version of git-annex are you using? On what operating system?
+
+ git-annex version: 4.20130922-g7dc188a
+ build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP Feeds Quvi
+ (actually a zeroinstall feed from here: http://f12n.de/0install/git-annex-webapp.xml which is based on the standalone build)
+
+OS: up-to-date ARCH system
+
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+[2013-09-23 19:24:04 CEST] main: starting assistant version 4.20130922-g7dc188a
+(scanning...) [2013-09-23 19:24:04 CEST] Watcher: Performing startup scan
+(started...)
+[2013-09-23 20:18:12 CEST] read: host ["-t","SRV","--","_xmpp-client._tcp.gmail.com"]
+.git/annex/daemon.log (END)
+
+# End of transcript or log.
+"""]]
diff --git a/doc/bugs/__34__Configuring_Jabber_Account__34___fails_with_a___34__Network_unreachable__34___error./comment_1_6d821af99ab3c83a5b0f52d3713ab8e2._comment b/doc/bugs/__34__Configuring_Jabber_Account__34___fails_with_a___34__Network_unreachable__34___error./comment_1_6d821af99ab3c83a5b0f52d3713ab8e2._comment
new file mode 100644
index 000000000..c2dd31f17
--- /dev/null
+++ b/doc/bugs/__34__Configuring_Jabber_Account__34___fails_with_a___34__Network_unreachable__34___error./comment_1_6d821af99ab3c83a5b0f52d3713ab8e2._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.220"
+ subject="comment 1"
+ date="2013-09-25T18:27:24Z"
+ content="""
+Sounds like the SRV lookup is failing. Does `git-annex version` list either DNS or ADNS in the build flags?
+
+Does `host -t SRV _xmpp-client._tcp.gmail.com` work?
+"""]]
diff --git a/doc/bugs/__34__Configuring_Jabber_Account__34___fails_with_a___34__Network_unreachable__34___error./comment_2_206b6c8cce8350fc088f01c42fc4715b._comment b/doc/bugs/__34__Configuring_Jabber_Account__34___fails_with_a___34__Network_unreachable__34___error./comment_2_206b6c8cce8350fc088f01c42fc4715b._comment
new file mode 100644
index 000000000..1cb191d8f
--- /dev/null
+++ b/doc/bugs/__34__Configuring_Jabber_Account__34___fails_with_a___34__Network_unreachable__34___error./comment_2_206b6c8cce8350fc088f01c42fc4715b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawknwkXgi8SnK4QT32ANl3GMKvFLyQGeHqo"
+ nickname="Florian"
+ subject="comment 2"
+ date="2013-09-25T21:19:23Z"
+ content="""
+Aaaah ok ... the *host* command is not installed by default on Arch Linux. I've installed it ... now it works ... will report it to the package maintainer.
+"""]]
diff --git a/doc/bugs/__34__Configuring_Jabber_Account__34___fails_with_a___34__Network_unreachable__34___error./comment_3_ed36f503f88611382b50687608b9b7e7._comment b/doc/bugs/__34__Configuring_Jabber_Account__34___fails_with_a___34__Network_unreachable__34___error./comment_3_ed36f503f88611382b50687608b9b7e7._comment
new file mode 100644
index 000000000..a69763af7
--- /dev/null
+++ b/doc/bugs/__34__Configuring_Jabber_Account__34___fails_with_a___34__Network_unreachable__34___error./comment_3_ed36f503f88611382b50687608b9b7e7._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="108.236.230.124"
+ subject="comment 3"
+ date="2013-11-08T18:42:22Z"
+ content="""
+Seems like I should fix the standalone linux tarball to either include the host program, or better, build git-annex with the Haskell [DNS library](https://hackage.haskell.org/package/dns). (I think that the Mac app and other builds are built with DNS by default, since they have dependencies installed using cabal directly).
+
+I need to first get that library included in Debian, so I can install it reliably on my build systems.
+"""]]
diff --git a/doc/bugs/__34__annex_sync__34___gets_confused_when_operating_in_a_symlink__39__ed_directory.mdwn b/doc/bugs/__34__annex_sync__34___gets_confused_when_operating_in_a_symlink__39__ed_directory.mdwn
new file mode 100644
index 000000000..96d1d4d2e
--- /dev/null
+++ b/doc/bugs/__34__annex_sync__34___gets_confused_when_operating_in_a_symlink__39__ed_directory.mdwn
@@ -0,0 +1,18 @@
+What steps will reproduce the problem?
+
+ * Create a symlink to a directory in your annex repository, like e.g. ~/Notes -> ~/annex/Notes
+ * cd into ~/Notes
+ * execute 'git annex sync <remote>', assuming that <remote> has made some changes
+
+What is the expected output? What do you see instead?
+
+If <remote> has made a change to, say, ~/annex/Documents/test.txt, the sync unexpectedly creates the new test.txt at ~/Notes/Documents/test.txt.
+It should either magically figure out that it has to create the file relative to the repository's root (i.e. ~/annex) or throw an error instead.
+
+What version of git-annex are you using? On what operating system?
+
+git-annex version: 4.20130323
+OS: Archlinux
+Shell: zsh
+
+
diff --git a/doc/bugs/__34__drop__34___deletes_all_files_with_identical_content.mdwn b/doc/bugs/__34__drop__34___deletes_all_files_with_identical_content.mdwn
new file mode 100644
index 000000000..bdf48760c
--- /dev/null
+++ b/doc/bugs/__34__drop__34___deletes_all_files_with_identical_content.mdwn
@@ -0,0 +1,49 @@
+# What steps will reproduce the problem?
+
+ echo "TEST CONTENT" > fileA
+ cp fileA fileB
+ git annex add file{A,B}
+ git annex drop fileA --force
+ cat fileB
+
+# What is the expected output? What do you see instead?
+
+## expected:
+
+--> TEST CONTENT
+
+## observed:
+
+--> cat: fileB: No such file or directory
+
+
+# What version of git-annex are you using? On what operating system?
+
+git-annex version: 3.20121017
+
+# Please provide any additional information below.
+
+I really like git annex's feature, to store the same content only once. But as this happens transparently (i.e. the user does not need to no, nor is he told, that contents are identical (which is very comfortable, of course)), the "git annex drop" function is broken. For it effectively deleting (seemingly) random files, WITHOUT notifying the user.
+
+
+# Possible solution?
+
+One simple solution would be to use "git annex find" functionality to see who else uses the file and NOT deleting it.
+
+But this still leaves a problem:
+
+Consider the following variation of the above example and assume, that "drop" does not delete content that is still used (i.e. implementing the above solution).
+
+ echo "TEST CONTENT" > fileA
+ cp fileA fileB
+ git annex add file{A,B}
+ git rm fileB
+ git annex drop fileA --force
+ git checkout --force
+ cat fileB
+--> cat: fileB: No such file or directory
+
+Here again, the problem is, that the user would probably (correct me if I am wrong) expect that the fileB still exists, because removing a file and checking it out again is expected to not mess with the annex contents (?). He does not know, that the "annex frop fileA" actually drop fileB's contents, because there was no additional file linking to it. It effectively performed a "git annex dropunused".
+
+> We seem to have agreed this is reasonable behavior, and a doc change was done.
+> Do feel free to suggest other doc changes.. [[done]] --[[Joey]]
diff --git a/doc/bugs/__34__drop__34___deletes_all_files_with_identical_content/comment_1_2eb20b65582fa7f271b1d0bb5560d08c._comment b/doc/bugs/__34__drop__34___deletes_all_files_with_identical_content/comment_1_2eb20b65582fa7f271b1d0bb5560d08c._comment
new file mode 100644
index 000000000..712657e82
--- /dev/null
+++ b/doc/bugs/__34__drop__34___deletes_all_files_with_identical_content/comment_1_2eb20b65582fa7f271b1d0bb5560d08c._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 1"
+ date="2012-10-28T17:13:32Z"
+ content="""
+You can avoid this by not using a deduplicating backend; for example you can use the WORM backend.
+
+However, the foot shooting actually occurs due to using drop --force, which is explicitly asking git-annex to be unsafe. If you want to be safe, simply don't use --force. If you want to safely delete a file, simply `git rm` it, and then `git annex unused` will come along and find content that can safely be removed.
+"""]]
diff --git a/doc/bugs/__34__drop__34___deletes_all_files_with_identical_content/comment_2_b14e1d31dd6a8fb930fcc0bec798e194._comment b/doc/bugs/__34__drop__34___deletes_all_files_with_identical_content/comment_2_b14e1d31dd6a8fb930fcc0bec798e194._comment
new file mode 100644
index 000000000..005c45be2
--- /dev/null
+++ b/doc/bugs/__34__drop__34___deletes_all_files_with_identical_content/comment_2_b14e1d31dd6a8fb930fcc0bec798e194._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlgyVag95OnpvSzQofjyX0WjW__MOMKsl0"
+ nickname="Sehr"
+ subject="comment 2"
+ date="2012-10-28T21:46:08Z"
+ content="""
+I onyl used \"--force\" for demonstration purposes. I could also set
+
+ annex.numcopies = 0
+
+which removes the need \"force\". While this setting can be totally reasonable in certain circumstancing it seems very dangerous, that completely unrelated files might unwillingly be deleted.
+
+I agree with you, that a possible solution could be to not use a deduplicating backend. But my point is, that this needs to be either changed or documented. Because even if the user can \"fix\" this by changing his behavior, he will probably only do so AFTER he lost something.
+
+Instead of changing the program (to include a check), I would at least suggest an addition to \"drop\"'s documentation:
+
+
+\"drop\": keep in mind, that on dedcupliocating backends, you might end up deleting more than one file. to be perfectly safe, use git-rm and git-annex dropunused.
+"""]]
diff --git a/doc/bugs/__34__drop__34___deletes_all_files_with_identical_content/comment_3_1892bcfbe3c462aa74552a241d65cad9._comment b/doc/bugs/__34__drop__34___deletes_all_files_with_identical_content/comment_3_1892bcfbe3c462aa74552a241d65cad9._comment
new file mode 100644
index 000000000..8dfc30a60
--- /dev/null
+++ b/doc/bugs/__34__drop__34___deletes_all_files_with_identical_content/comment_3_1892bcfbe3c462aa74552a241d65cad9._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 3"
+ date="2012-10-28T23:29:46Z"
+ content="""
+numcopies=0 is inherently unsafe, and unreasonable if you value your data at all. I've added some warnings about it to the man page.
+"""]]
diff --git a/doc/bugs/__34__drop__34___deletes_all_files_with_identical_content/comment_4_dfa0e31996eaa14e2945c1d11670c4d9._comment b/doc/bugs/__34__drop__34___deletes_all_files_with_identical_content/comment_4_dfa0e31996eaa14e2945c1d11670c4d9._comment
new file mode 100644
index 000000000..d82a3026d
--- /dev/null
+++ b/doc/bugs/__34__drop__34___deletes_all_files_with_identical_content/comment_4_dfa0e31996eaa14e2945c1d11670c4d9._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlgyVag95OnpvSzQofjyX0WjW__MOMKsl0"
+ nickname="Sehr"
+ subject="comment 4"
+ date="2012-10-29T00:00:33Z"
+ content="""
+Thanks, that's cool. Admittedly, I cannot think of too many scenarios, where there are two identical files without the user's knowloedge. And an even smaller subset of scenarios, where one would want to issue a \"drop\" on (only) one of these due to storage shortages.
+
+
+
+By the way, I LOVE git-annex.
+
+
+PS: I just realized, that the same applies to the \"move\" command.
+"""]]
diff --git a/doc/bugs/__34__drop__34___deletes_all_files_with_identical_content/comment_5_e2a9336cf1080c158765d4adfe72f26b._comment b/doc/bugs/__34__drop__34___deletes_all_files_with_identical_content/comment_5_e2a9336cf1080c158765d4adfe72f26b._comment
new file mode 100644
index 000000000..cc93b0f49
--- /dev/null
+++ b/doc/bugs/__34__drop__34___deletes_all_files_with_identical_content/comment_5_e2a9336cf1080c158765d4adfe72f26b._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 5"
+ date="2012-10-29T00:03:40Z"
+ content="""
+You're guaranteed to still have at least 1 copy of the file after move though, so you can get it back.
+
+"""]]
diff --git a/doc/bugs/__34__fatal:_bad_config_file__34__.mdwn b/doc/bugs/__34__fatal:_bad_config_file__34__.mdwn
new file mode 100644
index 000000000..baaa796db
--- /dev/null
+++ b/doc/bugs/__34__fatal:_bad_config_file__34__.mdwn
@@ -0,0 +1,14 @@
+### Please describe the problem.
+
+When running a command like `git annex copy --not --in bucket --to bucket`, I got:
+
+`fatal: bad config file line 1 in /home/jim/tmp/git-annex14898.tmp`
+
+I caught `git-annex14898.tmp` before it was deleted and it contained an HTML error page.
+I have a remote `https://git.example.com/jim/annex.git`, and it appears that git-annex
+is requesting `https://git.example.com/jim/annex.git/config`. My server returns a 401
+Forbidden and an error page for that URL, but git-annex tries to use the response as a config file anyway.
+
+Jim
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/__34__git_annex_watch__34___adds_map.dot.mdwn b/doc/bugs/__34__git_annex_watch__34___adds_map.dot.mdwn
new file mode 100644
index 000000000..94c495735
--- /dev/null
+++ b/doc/bugs/__34__git_annex_watch__34___adds_map.dot.mdwn
@@ -0,0 +1,23 @@
+"git annex watch" will add the file generated by "git annex map", which is
+probably not intended. Shouldn’t this file be created in /tmp or
+.git/annex/ or somewhere else?
+
+> Indeed, so [[done]] --[[Joey]]
+
+ /tmp $ cd test/
+ /tmp/test $ git init
+ Initialized empty Git repository in /tmp/test/.git/
+ /tmp/test $ git annex init
+ init ok
+ (Recording state in git...)
+ /tmp/test $ git annex watch
+ /tmp/test $ git annex map
+ map /tmp/test ok
+
+ running: dot -Tx11 map.dot
+
+ ok
+ /tmp/test $ ls -l
+ insgesamt 4
+ lrwxrwxrwx 1 jojo jojo 180 Jul 15 23:36 map.dot -> .git/annex/objects/P3/76/SHA256-s208--44199582b5948512ff12cf03de0b86fa1bebf09785dba2827fe52afee0afbe3d/SHA256-s208--44199582b5948512ff12cf03de0b86fa1bebf09785dba2827fe52afee0afbe3d
+
diff --git a/doc/bugs/__34__make_test__34___fails_silently.mdwn b/doc/bugs/__34__make_test__34___fails_silently.mdwn
new file mode 100644
index 000000000..8632f03f5
--- /dev/null
+++ b/doc/bugs/__34__make_test__34___fails_silently.mdwn
@@ -0,0 +1,4 @@
+`make test` fails silently when the test program cannot be built. This happens, for example, when attempting to compile git-annex with `QuickCheck-2.4.2`.
+
+> I've made "make test" exit nonzero if the test suite cannot be built.
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/__34__make_test__34___fails_silently/comment_1_f868e34f41d828d4571968d1ab07820a._comment b/doc/bugs/__34__make_test__34___fails_silently/comment_1_f868e34f41d828d4571968d1ab07820a._comment
new file mode 100644
index 000000000..00f67ad11
--- /dev/null
+++ b/doc/bugs/__34__make_test__34___fails_silently/comment_1_f868e34f41d828d4571968d1ab07820a._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2012-01-03T16:54:19Z"
+ content="""
+The code is:
+
+<pre>
+@if ! $(GHCMAKE) -O0 test; then \
+ echo \"** not running test suite\" >&2; \
+else \
+</pre>
+
+The error message from the compiler, followed by the above error message does not seem \"silent\". It does exit 0 without running the test suite if it cannot be built.
+"""]]
diff --git a/doc/bugs/__34__make_test__34___fails_silently/comment_2_fb9e8e2716b0dea15b0d4807ae7cd114._comment b/doc/bugs/__34__make_test__34___fails_silently/comment_2_fb9e8e2716b0dea15b0d4807ae7cd114._comment
new file mode 100644
index 000000000..3b76e3f14
--- /dev/null
+++ b/doc/bugs/__34__make_test__34___fails_silently/comment_2_fb9e8e2716b0dea15b0d4807ae7cd114._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://peter-simons.myopenid.com/"
+ ip="77.188.44.113"
+ subject="comment 2"
+ date="2012-01-03T18:09:38Z"
+ content="""
+When \"make test\" fails to run any tests at all, it should not return exit code 0. This behavior is quite misleading, and it means that automated build systems are not going to detect the fact that the test suit could not be run.
+"""]]
diff --git a/doc/bugs/__39__annex_add__39___fails_to___39__git_add__39___for_parent_relative_path.mdwn b/doc/bugs/__39__annex_add__39___fails_to___39__git_add__39___for_parent_relative_path.mdwn
new file mode 100644
index 000000000..f129abf62
--- /dev/null
+++ b/doc/bugs/__39__annex_add__39___fails_to___39__git_add__39___for_parent_relative_path.mdwn
@@ -0,0 +1,15 @@
+The following commands show the failure:
+
+$ mkdir d && touch d/f
+
+$ mkdir g && cd g && git annex add ../d/f
+
+add ... ok
+
+error: Invalid path '.git/annex/objects/Jx/...
+
+...
+
+Then it seems it is enough to 'git add ../d/f' to complete the operation.
+
+> Thanks for reporting, [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content.mdwn b/doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content.mdwn
new file mode 100644
index 000000000..6dcb1ec6b
--- /dev/null
+++ b/doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content.mdwn
@@ -0,0 +1,24 @@
+What steps will reproduce the problem?
+
+running the assistant on my setup, which is a central 'client' repo, and two 'backup' repos on a USB drive and an ssh connection to another server. Both of those backup repos are non-bare, and I occasionally manually run 'git annex sync' on them to keep them up to date. I have 'numcopies' set to 2.
+
+
+What is the expected output? What do you see instead?
+
+I expect everything to be copied to the 'backup' repos and content in the 'archive' subdirectories of the 'client' repo to be dropped.
+
+What happened instead: This morning, I started up the assistant without the USB drive present. I added one file to my client repo. The assistant began copying it to the SSH backup repo. I then plugged in the USB drive, and it began copying it to the USB repo; however, it *also* queued up large amounts of content in 'archive' subdirectories and started copying it down onto my client repo, which is unacceptable because there is not actually enough disk space on the client machine to hold everything in the 'archive' subdirectories! I stopped the assistant and started it up again. It started doing the same thing (queueing up archive content to transfer to client), and in addition started dropping content from my USB drive. This seems very similar to the bug in the previous version, where the globbing was broken. It's acting as if my usb remote preferred no content at all, and it transfers everything away from it and drops it -- and at the same time, brings in content which is not supposed to be there on my client machine. Strangely it's not doing the same thing on the ssh remote -- the ssh remote is fine. No anomalies there -- it has not been trying to drop content from there.
+
+This is just happening this morning -- I compiled 4.20130227 last night and ran the assistant and it behaved correctly, with no bugs at all. Now when I run it, it's going crazy.
+
+What version of git-annex are you using? On what operating system?
+
+4.20130227 on OS X.
+
+
+Please provide any additional information below.
+
+One thing that would be incredibly helpful with the kinds of bugs I've seen in the assistant is if the daemon.log contained info about *why* it is dropping or transferring content. "transferring content because there was only 1 copy and we need to fulfill numcopies" "transferring content because it matches such-and-such a preferred content expresson" "dropping content because it does not match this preferred content expression" -- that would remove a lot of mystery about the way the assistant is working.
+
+> The several bugs mentioned here seem to be fixed, so closing this report.
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content/comment_1_56f9cd5cc2e089b32cb076dc2e2a8ca5._comment b/doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content/comment_1_56f9cd5cc2e089b32cb076dc2e2a8ca5._comment
new file mode 100644
index 000000000..cf309b8b3
--- /dev/null
+++ b/doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content/comment_1_56f9cd5cc2e089b32cb076dc2e2a8ca5._comment
@@ -0,0 +1,22 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-03-01T19:59:23Z"
+ content="""
+I've added some debug info to the log for transfers and drops. You have to start the assistant with the --debug flag, then you'll get stuff like:
+
+<pre>
+[2013-03-01 15:23:10 JEST] Committer: queued Upload UUID \"a0cd7cb6-57ee-4551-955f-aa77738135cc\" myfile : newly added file
+[2013-03-01 15:25:00 JEST] Watcher: queued Download UUID \"a0cd7cb6-57ee-4551-955f-aa77738135cc\" ./foo : new or renamed file wanted
+[2013-03-01 15:54:00 JEST] Watcher: dropped ./archive/foo (from: here) (copies now: 1): file renamed
+</pre>
+
+It would take more work to show the preferred content expressions that caused the transfer or drop, but this is simple to determine:
+
+* for Uploads it should always be the preferred content expression of the remote being uploaded to
+* for Downloads it is always the preferred content expression of the local repository
+* for drops it is always the preferred content expression of the repository it is dropped from
+
+Have not managed to reproduce problem yet.
+"""]]
diff --git a/doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content/comment_2_21c0f7f328cb51080fbd97e086c47a30._comment b/doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content/comment_2_21c0f7f328cb51080fbd97e086c47a30._comment
new file mode 100644
index 000000000..5eb511b65
--- /dev/null
+++ b/doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content/comment_2_21c0f7f328cb51080fbd97e086c47a30._comment
@@ -0,0 +1,37 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="99.54.57.201"
+ subject="comment 2"
+ date="2013-03-03T18:44:35Z"
+ content="""
+I rebuilt and ran with --debug, and started up git annex. It behaved itself.
+
+I tried restarting it, unplugging and plugging back in my USB drive to see if it provoked any problems -- none.
+
+I decided to try adding something. I added a music video to my Movies/Music directory. It uploaded it to my ssh remote but not to the USB drive and, bizarrely, when I use \"git annex whereis\" it doesn't show it as existing *anywhere*:
+
+ annex$ git annex whereis Movies/Music/Tanlines\ -\ All\ Of\ Me.flv
+ annex$
+
+It does in fact exist in all three repos! The link is there:
+
+annex$ ls -l Movies/Music/Tanlines\ -\ All\ Of\ Me.flv
+lrwxr-xr-x 1 ed staff 206 Mar 3 13:18 Movies/Music/Tanlines - All Of Me.flv -> ../../.git/annex/objects/0k/j6/SHA256E-s37822147--c9df1d6c9f6d2d72e039de9705ea4673160da32eb0cc9ea87e65003506d9297d.flv/SHA256E-s37822147
+
+the object is there!
+
+annex$ ls -l .git/annex/objects/0k/j6/SHA256E-s37822147--c9df1d6c9f6d2d72e039de9705ea4673160da32eb0cc9ea87e65003506d9297d.flv/SHA256E-s37822147--c9df1d6c9f6d2d72e039de9705ea4673160da32eb0cc9ea87e65003506d9297d.flv
+-r--r--r-- 1 ed staff 37822147 Mar 3 13:17 .git/annex/objects/0k/j6/SHA256E-s37822147--c9df1d6c9f6d2d72e039de9705ea4673160da32eb0cc9ea87e65003506d9297d.flv/SHA256E-s37822147--c9df1d6c9f6d2d72e039de9705ea4673160da32eb0cc9ea87e65003506d9297d.flv
+
+The corresponding object also exists in the .git/annex/objects directory of the USB remote and the ssh remote.
+
+here's a pastebin of the daemon.log: http://pastebin.com/BGRBQ6Rx
+
+Shut down the daemon to see if that changed anything; nope. \"Whereis\" still comes up blank. Tried a git annex fsck --fast to see if that changed anything; nope. \"Whereis\" still comes up blank.
+
+Any ideas? Is the log revealing at all?
+
+
+
+
+"""]]
diff --git a/doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content/comment_3_3287b2f25f3b5ae4c27f4748694563ee._comment b/doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content/comment_3_3287b2f25f3b5ae4c27f4748694563ee._comment
new file mode 100644
index 000000000..e108052d7
--- /dev/null
+++ b/doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content/comment_3_3287b2f25f3b5ae4c27f4748694563ee._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-03-03T18:53:23Z"
+ content="""
+Are you sure the file in question is checked into git? Because git-annex ignores symlinks that are not checked into git.
+"""]]
diff --git a/doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content/comment_4_e515eca68a70d40c522805d7e0d7c0e6._comment b/doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content/comment_4_e515eca68a70d40c522805d7e0d7c0e6._comment
new file mode 100644
index 000000000..4a533fc92
--- /dev/null
+++ b/doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content/comment_4_e515eca68a70d40c522805d7e0d7c0e6._comment
@@ -0,0 +1,24 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="99.54.57.201"
+ subject="comment 4"
+ date="2013-03-03T18:58:42Z"
+ content="""
+Just to see what happened, I re-added that same file in another directory manually (not with the assistant).
+
+git annex whereis instantly showed that it was in all the other repositories.
+
+I finally thought to try a \"git status\" -- it showed that with for the original copy of this I added, the actual symlink was never checked into git.
+
+ annex$ git status
+ # On branch master
+ # Untracked files:
+ # (use \"git add <file>...\" to include in what will be committed)
+ #
+ # Movies/Music/Tanlines - All Of Me.flv
+ nothing added to commit but untracked files present (use \"git add\" to track)
+ annex$
+
+This is probably all unrelated to the original topic of the bug -- I am not seeing the \"client repo starts pulling in archive content, dropping it from backup remote\" issue anymore.
+
+"""]]
diff --git a/doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content/comment_5_b27f4c103dda050b6e9cf03ea3157abc._comment b/doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content/comment_5_b27f4c103dda050b6e9cf03ea3157abc._comment
new file mode 100644
index 000000000..434bcb1dd
--- /dev/null
+++ b/doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content/comment_5_b27f4c103dda050b6e9cf03ea3157abc._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 5"
+ date="2013-03-03T19:42:19Z"
+ content="""
+A symlink not added to git could happen with the assistant for various reasons. For example, if the assistant was shut down before it got a chance to stage a newly added file. The assistant detects such symlinks when started up and will add them then.
+
+Back to the original bug report..
+"""]]
diff --git a/doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content/comment_6_2cc7083dab944705bf91fc00319b75e6._comment b/doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content/comment_6_2cc7083dab944705bf91fc00319b75e6._comment
new file mode 100644
index 000000000..9f110d30d
--- /dev/null
+++ b/doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content/comment_6_2cc7083dab944705bf91fc00319b75e6._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="99.54.57.201"
+ subject="comment 6"
+ date="2013-03-04T00:20:25Z"
+ content="""
+Since I can't reproduce the \"copy archived content to the client repo then drop it from the backup repo\" anymore, I guess we can close. If I notice anything like that happening again I have the --debug flag available to investigate and open a new bug report.
+
+"""]]
diff --git a/doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content/comment_7_1175f9be789d4c1907f0be98e435bd2f._comment b/doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content/comment_7_1175f9be789d4c1907f0be98e435bd2f._comment
new file mode 100644
index 000000000..1f11f8bed
--- /dev/null
+++ b/doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content/comment_7_1175f9be789d4c1907f0be98e435bd2f._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 7"
+ date="2013-03-04T00:57:38Z"
+ content="""
+With the new Preferences page I added to the webapp today you can also enable debugging while the assistant is running if it starts to misbehave.
+
+However, I'm in no hurry to close this bug just yet.
+"""]]
diff --git a/doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content/comment_8_78e6164ef67a9560a3a9ead1f7a72473._comment b/doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content/comment_8_78e6164ef67a9560a3a9ead1f7a72473._comment
new file mode 100644
index 000000000..c49cbbeef
--- /dev/null
+++ b/doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content/comment_8_78e6164ef67a9560a3a9ead1f7a72473._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 8"
+ date="2013-03-08T14:46:55Z"
+ content="""
+I've not seen this kind of strange behavior happen again so far.
+
+But I have got another example of a file which I added to git-annex via the assistant not having its symlink added to git. Again, the content of the file is in git-annex and was even correctly transferred to a couple of remotes, but the symlink is still unstaged.
+
+I tried restarting the assistant to see if that would fix it but that didn't change anything.
+
+I imagine the symlink will be fixed during a daily scan, tomorrow maybe? Is it problematic for the symlink not to be checked into git for a day? Is this worth a bug report or is this really harmless behavior?
+
+"""]]
diff --git a/doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content/comment_9_1d578fd13022dcd6382b415a7f6e097a._comment b/doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content/comment_9_1d578fd13022dcd6382b415a7f6e097a._comment
new file mode 100644
index 000000000..9c2cd3c75
--- /dev/null
+++ b/doc/bugs/__39__client__39___repo_starts_pulling_in___39__archive__39___content/comment_9_1d578fd13022dcd6382b415a7f6e097a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 9"
+ date="2013-03-18T15:45:19Z"
+ content="""
+There turned out to be a bug specific to OSX that prevented symlinks being checked into git. The daily sanity check did eventually add them. I fixed this bug yesterday.
+"""]]
diff --git a/doc/bugs/__40__assistant__41___dependency_on_ssh-askpass_-_not_installed_automatically_on_xubuntu.mdwn b/doc/bugs/__40__assistant__41___dependency_on_ssh-askpass_-_not_installed_automatically_on_xubuntu.mdwn
new file mode 100644
index 000000000..7968d32cc
--- /dev/null
+++ b/doc/bugs/__40__assistant__41___dependency_on_ssh-askpass_-_not_installed_automatically_on_xubuntu.mdwn
@@ -0,0 +1,22 @@
+### Please describe the problem.
+Using assistant via xfce's "Internet -> Git annex" menu item, trying to connect to an ssh server fails
+
+### What steps will reproduce the problem?
+Use xubuntu 13.04 and git-annex
+
+### What version of git-annex are you using? On what operating system?
+git-annex version: 3.20121112ubuntu2
+
+xubuntu 13.04
+
+### Please provide any additional information below.
+if I "sudo apt-get install ssh-askpass", this gets resolved. I think this should be fixed in the ubuntu repository's program dependencies.
+
+Also if I run "git-annex webapp" from the terminal, this doesn't happen because it will ask me for the password in the terminal.
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+ Failed to ssh to the server. Transcript: ssh_askpass: exec(/usr/bin/ssh-askpass): No such file or directory Permission denied, please try again. ssh_askpass: exec(/usr/bin/ssh-askpass): No such file or directory Received disconnect from xxx.xxx.xxx.xxx: 2: Too many authentication failures for <user>
+
+# End of transcript or log.
+"""]]
diff --git a/doc/bugs/__40__assistant__41___dependency_on_ssh-askpass_-_not_installed_automatically_on_xubuntu/comment_1_f4656f8a0f36535def0772db06098c5f._comment b/doc/bugs/__40__assistant__41___dependency_on_ssh-askpass_-_not_installed_automatically_on_xubuntu/comment_1_f4656f8a0f36535def0772db06098c5f._comment
new file mode 100644
index 000000000..34a2ed325
--- /dev/null
+++ b/doc/bugs/__40__assistant__41___dependency_on_ssh-askpass_-_not_installed_automatically_on_xubuntu/comment_1_f4656f8a0f36535def0772db06098c5f._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.255.110"
+ subject="comment 1"
+ date="2013-09-09T20:08:57Z"
+ content="""
+It's not a dependency. It's a recommends.
+
+apt does not install new recommends that get added to a package. Adding that recommends only causes it to be installed by default when new users install the package
+
+This seems to be the best I can do, short of adding a separate git-annex-assistant package, which could depend on ssh-askpass.
+Might not be a bad idea..
+"""]]
diff --git a/doc/bugs/__91__Installation__93___There_is_no_available_version_of_quickcheck_that_satisfies___62____61__2.1.mdwn b/doc/bugs/__91__Installation__93___There_is_no_available_version_of_quickcheck_that_satisfies___62____61__2.1.mdwn
new file mode 100644
index 000000000..a6e2423a8
--- /dev/null
+++ b/doc/bugs/__91__Installation__93___There_is_no_available_version_of_quickcheck_that_satisfies___62____61__2.1.mdwn
@@ -0,0 +1,40 @@
+Hi,
+
+I just wanted to install git-annex via cabal, as described in the install document. More specifically, I did this on my Ubuntu Lucid box:
+
+ andreas@antares:~$ sudo aptitude install cabal-install
+ [...]
+ andreas@antares:~$ cabal update
+ andreas@antares:~$ cabal install quickcheck --bindir=$HOME/bin
+ andreas@antares:~$ cabal install git-annex -v --bindir=$HOME/bin
+
+However, I got this error:
+
+ /usr/bin/ghc --numeric-version
+ looking for package tool: ghc-pkg near compiler in /usr/bin
+ found package tool in /usr/bin/ghc-pkg
+ /usr/bin/ghc-pkg --version
+ /usr/bin/ghc --supported-languages
+ Reading installed packages...
+ /usr/bin/ghc-pkg dump --global
+ /usr/bin/ghc-pkg dump --user
+ Reading available packages...
+ Resolving dependencies...
+ selecting
+ cabal: cannot configure git-annex-3.20120113. It requires quickcheck >=2.1
+ There is no available version of quickcheck that satisfies >=2.1
+
+which is really strange, because quickcheck 2.4.2 is installed:
+
+ andreas@antares:~$ ls -a .cabal/lib/
+ . .. QuickCheck-2.4.2
+
+Any help is greatly appreciated :)
+Andreas.
+
+> QuickCheck has to be spelled in mixed case. --[[Joey]]
+
+Sorry to disagree, this doesn't fix my problem. cabal still complains that no version >= 2.1 is available, even though 2.4.2 is installed. This problem already occurred before I explicitly installed QuickCheck. According to [[install]], the `cabal install git-annex -v --bindir=$HOME/bin` should already take care of the dependencies.
+
+>> You need to `cabal update` to get the fixed version of git-annex which
+>> spells QuickCheck correctly. [[done]] --[[Joey]]
diff --git a/doc/bugs/__91__webapp__93___pause_syncing_with_specific_repository.mdwn b/doc/bugs/__91__webapp__93___pause_syncing_with_specific_repository.mdwn
new file mode 100644
index 000000000..dca16e4d3
--- /dev/null
+++ b/doc/bugs/__91__webapp__93___pause_syncing_with_specific_repository.mdwn
@@ -0,0 +1,8 @@
+[Due to some stupid issue on my and AT&T's part] one of my remote repositories is currently unreachable. I would like to tell the webapp/assistant to not attempt to sync with it, or, at least, modify this error message to be more specific (by telling me which repository is unreachable).
+
+In a red bubble it says: "Synced with rose 60justin"
+
+That verbage is the same if they all succeed. The only difference is the red instead of green. Would be nice to know exactly which machine to kick (if I didn't already know, eg I was syncing only with repositories not under my control).
+
+> Fixed alert display. Webapp has allowed pausing syncing with a repository
+> for a while. [[done]] --[[Joey]]
diff --git a/doc/bugs/__91__wishlistAndroid:_bundle_an_ssh_server___40__dropbear__63____41___and_add_an_option_to_start_it_easily_with_the_terminal_app_menu.mdwn b/doc/bugs/__91__wishlistAndroid:_bundle_an_ssh_server___40__dropbear__63____41___and_add_an_option_to_start_it_easily_with_the_terminal_app_menu.mdwn
new file mode 100644
index 000000000..7366e6ff2
--- /dev/null
+++ b/doc/bugs/__91__wishlistAndroid:_bundle_an_ssh_server___40__dropbear__63____41___and_add_an_option_to_start_it_easily_with_the_terminal_app_menu.mdwn
@@ -0,0 +1,21 @@
+### Please describe the problem.
+
+quite often is desired to fetch/navigate through the git annex installation under git annex user, e.g. to fetch the log to be provided here for the "additional information".
+Given already big size of the app bundling some lightweight ssh server should not be a major size hit, but would ease troubleshooting and bug reporting
+
+### What steps will reproduce the problem?
+
+
+### What version of git-annex are you using? On what operating system?
+
+Android from Nov 18
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
diff --git a/doc/bugs/__91__wishlistAndroid:_bundle_an_ssh_server___40__dropbear__63____41___and_add_an_option_to_start_it_easily_with_the_terminal_app_menu/comment_1_9bb53c45d685b368c7ba1758885f2874._comment b/doc/bugs/__91__wishlistAndroid:_bundle_an_ssh_server___40__dropbear__63____41___and_add_an_option_to_start_it_easily_with_the_terminal_app_menu/comment_1_9bb53c45d685b368c7ba1758885f2874._comment
new file mode 100644
index 000000000..36440eac5
--- /dev/null
+++ b/doc/bugs/__91__wishlistAndroid:_bundle_an_ssh_server___40__dropbear__63____41___and_add_an_option_to_start_it_easily_with_the_terminal_app_menu/comment_1_9bb53c45d685b368c7ba1758885f2874._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.64"
+ subject="comment 1"
+ date="2013-11-26T16:09:19Z"
+ content="""
+This was previously suggested in the forum: [[forum/Suggestion:_Put_ssh_server_back_into_android_version]]
+
+As said there, I feel that `adb` is a better option in these situations. Of course, the git-annex bundle already has a ssh client, so you can rsync files from it to other ssh servers too.
+
+Also, the bundle is too big, I don't want to make it any bigger.
+"""]]
diff --git a/doc/bugs/__91__wishlistAndroid:_bundle_an_ssh_server___40__dropbear__63____41___and_add_an_option_to_start_it_easily_with_the_terminal_app_menu/comment_2_251311a04f1a610e54ebe8e9b92de72e._comment b/doc/bugs/__91__wishlistAndroid:_bundle_an_ssh_server___40__dropbear__63____41___and_add_an_option_to_start_it_easily_with_the_terminal_app_menu/comment_2_251311a04f1a610e54ebe8e9b92de72e._comment
new file mode 100644
index 000000000..48707e82b
--- /dev/null
+++ b/doc/bugs/__91__wishlistAndroid:_bundle_an_ssh_server___40__dropbear__63____41___and_add_an_option_to_start_it_easily_with_the_terminal_app_menu/comment_2_251311a04f1a610e54ebe8e9b92de72e._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://yarikoptic.myopenid.com/"
+ nickname="site-myopenid"
+ subject="comment 2"
+ date="2013-11-27T04:30:53Z"
+ content="""
+we just shrinked the bundle by 60MB so there could be some space for sshd.
+
+adb might indeed be more powerful but would require usb connection (right?) -- at times not convenient
+
+syncing via ssh from phone: that is what I was trying to avoid -- working in the shell on the phone -- it is possible but a bit \"inconvenient\"
+sshd could be ran on any unprivileged port while letting the user who starts it know the IP and the port, thus making it easy to connect.
+"""]]
diff --git a/doc/bugs/__96__git_annex_add__96___changes_mtime_if_symlinks_are_fixed_in_the_background.mdwn b/doc/bugs/__96__git_annex_add__96___changes_mtime_if_symlinks_are_fixed_in_the_background.mdwn
new file mode 100644
index 000000000..eba11aa2d
--- /dev/null
+++ b/doc/bugs/__96__git_annex_add__96___changes_mtime_if_symlinks_are_fixed_in_the_background.mdwn
@@ -0,0 +1,51 @@
+### Please describe the problem.
+
+When `git annex add` is run on dangling symlinks which point to the annex, the pre-commit hook `git annex pre-commit .` is run which, in turn, runs `git annex fix`.
+
+During this fix, the mtime of the symlink changes. I assume the symlink is actually deleted and re-created in the background which would explain this behavior.
+
+### What steps will reproduce the problem?
+
+[[!format sh """
+# manual import of annexed data into new annex
+% mkdir repo1.annex
+% cd !$
+% git init; git annex init
+% echo hi > foo
+% git annex add foo; git commit -m bar
+% mkdir ../repo2
+% cd !$
+% git init; git annex init
+% mkdir .git/annex/objects/zQ/MQ/SHA256E-s3--98ea6e4f216f2fb4b69fff9b3a44842c38686ca685f3f55dc48c5d3fb1107be4/
+% cp -ax ../repo1/.git/annex/objects/zQ/MQ/SHA256E-s3--98ea6e4f216f2fb4b69fff9b3a44842c38686ca685f3f55dc48c5d3fb1107be4/SHA256E-s3--98ea6e4f216f2fb4b69fff9b3a44842c38686ca685f3f55dc48c5d3fb1107be4 .git/annex/objects/zQ/MQ/SHA256E-s3--98ea6e4f216f2fb4b69fff9b3a44842c38686ca685f3f55dc48c5d3fb1107be4/SHA256E-s3--98ea6e4f216f2fb4b69fff9b3a44842c38686ca685f3f55dc48c5d3fb1107be4
+% mkdir subdirectory
+% cd !$
+% cp -ax ../../repo1.annex/foo .
+% ls -l foo
+total 4
+lrwxrwxrwx 1 richih richih 194 Jul 11 12:20 foo -> .git/annex/objects/zQ/MQ/SHA256E-s3--98ea6e4f216f2fb4b69fff9b3a44842c38686ca685f3f55dc48c5d3fb1107be4/SHA256E-s3--98ea6e4f216f2fb4b69fff9b3a44842c38686ca685f3f55dc48c5d3fb1107be4
+% git annex fix # this does nothing
+% ls -l foo
+total 4
+lrwxrwxrwx 1 richih richih 194 Jul 11 12:20 foo -> ..git/annex/objects/zQ/MQ/SHA256E-s3--98ea6e4f216f2fb4b69fff9b3a44842c38686ca685f3f55dc48c5d3fb1107be4/SHA256E-s3--98ea6e4f216f2fb4b69fff9b3a44842c38686ca685f3f55dc48c5d3fb1107be4
+% git annex add foo
+add foo ok
+(Recording state in git...)
+% ls -l foo
+total 4
+lrwxrwxrwx 1 richih richih 197 Jul 11 12:23 foo -> ../.git/annex/objects/zQ/MQ/SHA256E-s3--98ea6e4f216f2fb4b69fff9b3a44842c38686ca685f3f55dc48c5d3fb1107be4/SHA256E-s3--98ea6e4f216f2fb4b69fff9b3a44842c38686ca685f3f55dc48c5d3fb1107be4
+%
+
+"""]]
+
+
+### What version of git-annex are you using? On what operating system?
+
+git-annex 4.20130709 on Debian unstable i386 and x64.
+
+### Please provide any additional information below.
+
+As noted in [[todo/wishlist:___96__git_annex_import__96___--_An_easy_way_to_get_data_into_an_annex/#comment-e0ea68b5f84cf4130001ad34e9f3b2ff]], `git annex import` does not seem to work on other repos which is why I tried to build this by hand. This works fine and retains mtime as long as I don't need to change the relative depth the symlinks.
+I think that the issue above should be fixed in and as of itself, though.
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/__96__git_annex_fix__96___run_on_non-annexed_files_is_no-op.mdwn b/doc/bugs/__96__git_annex_fix__96___run_on_non-annexed_files_is_no-op.mdwn
new file mode 100644
index 000000000..54920fa31
--- /dev/null
+++ b/doc/bugs/__96__git_annex_fix__96___run_on_non-annexed_files_is_no-op.mdwn
@@ -0,0 +1,15 @@
+### Please describe the problem.
+
+`git annex fix` only works on files that have been annexed, already.
+While that's a safety measure of course, an option like `--force` or similar would be nice if one is shuffling around data by hand.
+
+### What steps will reproduce the problem?
+
+Please see [[bugs/__96__git_annex_add__96___changes_mtime_if_symlinks_are_fixed_in_the_background/]] for details; I didn't want to spam exactly the same output twice.
+
+### What version of git-annex are you using? On what operating system?
+
+git-annex 4.20130709 on Debian unstable i386 and x64.
+
+> We've discussed this on IRC and there seems to be nothing more to do here.
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/__96__git_annex_fix__96___run_on_non-annexed_files_is_no-op/comment_1_9b671e583eec5adf870dccd1e97b5dbc._comment b/doc/bugs/__96__git_annex_fix__96___run_on_non-annexed_files_is_no-op/comment_1_9b671e583eec5adf870dccd1e97b5dbc._comment
new file mode 100644
index 000000000..f2db49dd4
--- /dev/null
+++ b/doc/bugs/__96__git_annex_fix__96___run_on_non-annexed_files_is_no-op/comment_1_9b671e583eec5adf870dccd1e97b5dbc._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.235"
+ subject="comment 1"
+ date="2013-07-11T15:26:52Z"
+ content="""
+I don't understand what you want fix to do when run on files that are not annexed.
+"""]]
diff --git a/doc/bugs/__96__git_annex_fix__96___run_on_non-annexed_files_is_no-op/comment_2_d11744202213d6f897f4234bc4c70c18._comment b/doc/bugs/__96__git_annex_fix__96___run_on_non-annexed_files_is_no-op/comment_2_d11744202213d6f897f4234bc4c70c18._comment
new file mode 100644
index 000000000..20b3a251e
--- /dev/null
+++ b/doc/bugs/__96__git_annex_fix__96___run_on_non-annexed_files_is_no-op/comment_2_d11744202213d6f897f4234bc4c70c18._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 2"
+ date="2013-07-11T20:18:44Z"
+ content="""
+I wanted to use it as a way to prepare the files before running `git annex add`. I like to have everything exactly how I want it before I add anything to git, or git-annex. Does git-annex do anything in the git-annex branch prior to running the pre-commit hook? I.e. is there any penalty, however slight, in running `git annex add` several times while moving stuff around?
+
+"""]]
diff --git a/doc/bugs/__96__git_annex_fix__96___run_on_non-annexed_files_is_no-op/comment_3_a729deb465ff44f5a9b87c963cd6235a._comment b/doc/bugs/__96__git_annex_fix__96___run_on_non-annexed_files_is_no-op/comment_3_a729deb465ff44f5a9b87c963cd6235a._comment
new file mode 100644
index 000000000..d4c65308d
--- /dev/null
+++ b/doc/bugs/__96__git_annex_fix__96___run_on_non-annexed_files_is_no-op/comment_3_a729deb465ff44f5a9b87c963cd6235a._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 3"
+ date="2013-07-13T15:05:53Z"
+ content="""
+With git-annex built from current Git (i.e. the mtime fix for `git annex fix/add` applied), I have imported directory structure and objects (I will write a blog post along with scripts and pitfalls about that once the process is totally finished) and been running `git annex add` and `git mv` repeatedly to keep things up to date.
+
+As I now need to rename a few files with globs (`zmv`/`rename`) where `git mv` does not really cut it, I am in between a rock and a hard place. Most likely, I will `git checkout -- .`, rename, and `git annex add` again. I am pretty sure that `git annex add` does not do anything other than staging in the current branch and does not touch the `git-annex` branch. But I don't _know_.
+
+Long story short, it would make both my workflow easier and give me more peace of mind if there was a `git annex fix --untracked` or similar which does exactly the same, but operates on files that are not checked in and/or staged.
+
+As an aside, `git annex fsck --untracked` which is basically `git annex fsck --numcopies=1` on untracked files would be.... awesome.
+
+"""]]
diff --git a/doc/bugs/__96__git_annex_fix__96___run_on_non-annexed_files_is_no-op/comment_4_3f735503df9a08472d42fabd219c2ec5._comment b/doc/bugs/__96__git_annex_fix__96___run_on_non-annexed_files_is_no-op/comment_4_3f735503df9a08472d42fabd219c2ec5._comment
new file mode 100644
index 000000000..41f4e9db8
--- /dev/null
+++ b/doc/bugs/__96__git_annex_fix__96___run_on_non-annexed_files_is_no-op/comment_4_3f735503df9a08472d42fabd219c2ec5._comment
@@ -0,0 +1,31 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.140"
+ subject="comment 4"
+ date="2013-07-18T19:27:41Z"
+ content="""
+It seems to me that what you're looking for is:
+
+<pre>
+git annex import /dir
+mv foo bar
+...
+git add .
+git annex fix
+git commit
+</pre>
+
+This avoids the minor overhead of `git annex add` when run on a symlink updating the location tracking information.
+
+(Note that the manual call to `git annex fix` there is entirely unnecessary, since the pre-commit hook does the same thing when you commit.)
+
+Alternatively:
+
+<pre>
+git annex import /dir -c annex.alwayscommit=false
+mv foo bar
+...
+git annex add
+git commit
+</pre>
+"""]]
diff --git a/doc/bugs/__96__git_annex_fix__96___run_on_non-annexed_files_is_no-op/comment_5_2c61eabbba7fd2a52ba02d59a0a76a42._comment b/doc/bugs/__96__git_annex_fix__96___run_on_non-annexed_files_is_no-op/comment_5_2c61eabbba7fd2a52ba02d59a0a76a42._comment
new file mode 100644
index 000000000..a417dac02
--- /dev/null
+++ b/doc/bugs/__96__git_annex_fix__96___run_on_non-annexed_files_is_no-op/comment_5_2c61eabbba7fd2a52ba02d59a0a76a42._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.140"
+ subject="comment 5"
+ date="2013-07-18T19:29:02Z"
+ content="""
+Note that the second option will work in direct mode; first one won't.
+"""]]
diff --git a/doc/bugs/__96__git_annex_import__96___clobbers_mtime.mdwn b/doc/bugs/__96__git_annex_import__96___clobbers_mtime.mdwn
new file mode 100644
index 000000000..7edebe584
--- /dev/null
+++ b/doc/bugs/__96__git_annex_import__96___clobbers_mtime.mdwn
@@ -0,0 +1,62 @@
+### Please describe the problem.
+
+mtimes are clobbered with what I think is the time of the first time `git annex` saw a file in that directory on all files which are `git annex import`ed.
+
+
+### What steps will reproduce the problem?
+
+ richih@eudyptes (git)-[master] ~/killme/target % date; stat ../source/*; date; git annex import ../source/*; date; stat *; date
+ Tue Jul 30 01:41:43 CEST 2013
+ File: ‘../source/foo’
+ Size: 0 Blocks: 0 IO Block: 4096 regular empty file
+ Device: 804h/2052d Inode: 110095 Links: 1
+ Access: (0644/-rw-r--r--) Uid: ( 1000/ richih) Gid: ( 1000/ richih)
+ Access: 2013-07-30 01:41:03.860703428 +0200
+ Modify: 2013-07-30 01:41:03.860703428 +0200
+ Change: 2013-07-30 01:41:03.860703428 +0200
+ Birth: -
+ File: ‘../source/foobar’
+ Size: 0 Blocks: 0 IO Block: 4096 regular empty file
+ Device: 804h/2052d Inode: 110104 Links: 1
+ Access: (0644/-rw-r--r--) Uid: ( 1000/ richih) Gid: ( 1000/ richih)
+ Access: 2013-07-30 01:41:05.512703349 +0200
+ Modify: 2013-07-30 01:41:05.512703349 +0200
+ Change: 2013-07-30 01:41:05.512703349 +0200
+ Birth: -
+ Tue Jul 30 01:41:43 CEST 2013
+ import foo (checksum...) ok
+ import foobar (checksum...) ok
+ (Recording state in git...)
+ Tue Jul 30 01:41:43 CEST 2013
+ File: ‘foo’ -> ‘.git/annex/objects/pX/ZJ/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855’
+ Size: 178 Blocks: 8 IO Block: 4096 symbolic link
+ Device: 804h/2052d Inode: 268638577 Links: 1
+ Access: (0777/lrwxrwxrwx) Uid: ( 1000/ richih) Gid: ( 1000/ richih)
+ Access: 2013-07-30 01:41:43.704701516 +0200
+ Modify: 2013-07-30 01:19:41.000000000 +0200
+ Change: 2013-07-30 01:41:43.700701516 +0200
+ Birth: -
+ File: ‘foobar’ -> ‘.git/annex/objects/pX/ZJ/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855’
+ Size: 178 Blocks: 8 IO Block: 4096 symbolic link
+ Device: 804h/2052d Inode: 268774374 Links: 1
+ Access: (0777/lrwxrwxrwx) Uid: ( 1000/ richih) Gid: ( 1000/ richih)
+ Access: 2013-07-30 01:41:43.704701516 +0200
+ Modify: 2013-07-30 01:19:41.000000000 +0200
+ Change: 2013-07-30 01:41:43.700701516 +0200
+ Birth: -
+ Tue Jul 30 01:41:43 CEST 2013
+ richih@eudyptes (git)-[master] ~/killme/target %
+
+
+### What version of git-annex are you using? On what operating system?
+
+ git-annex version: 4.20130709
+ build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP
+ local repository version: 3
+ default repository version: 3
+ supported repository versions: 3 4
+ upgrade supported from repository versions: 0 1 2
+
+Debian unstable amd64
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/__96__git_annex_import__96___clobbers_mtime/comment_1_d173f2903faf4bff115a0be02c146ce9._comment b/doc/bugs/__96__git_annex_import__96___clobbers_mtime/comment_1_d173f2903faf4bff115a0be02c146ce9._comment
new file mode 100644
index 000000000..acb266abe
--- /dev/null
+++ b/doc/bugs/__96__git_annex_import__96___clobbers_mtime/comment_1_d173f2903faf4bff115a0be02c146ce9._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 1"
+ date="2013-07-29T23:49:12Z"
+ content="""
+PS: Maybe adding tests that _all_ commands leave mtime in place would be an option? As it is, I keep (for some value of) finding places where mtimes are clobbered.
+"""]]
diff --git a/doc/bugs/__96__git_annex_import__96___clobbers_mtime/comment_2_3563d9eeb9806f8ca1b9b340925837f5._comment b/doc/bugs/__96__git_annex_import__96___clobbers_mtime/comment_2_3563d9eeb9806f8ca1b9b340925837f5._comment
new file mode 100644
index 000000000..842c713df
--- /dev/null
+++ b/doc/bugs/__96__git_annex_import__96___clobbers_mtime/comment_2_3563d9eeb9806f8ca1b9b340925837f5._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.21"
+ subject="comment 2"
+ date="2013-07-30T17:40:04Z"
+ content="""
+git-annex makes only a best-effort attempt to preserve mtime. There are multiple cases where it cannot:
+
+* filesystems that do not support changing the mtime of a symlink
+* special remotes
+* when 2 files with the same content get stored in the annex, the mtime of one must win over the other since we only have 1 inode
+
+This last seems to be what has happened in the example you show. Both `foo` and `foobar` are empty. I'm not sure where the 01:19:41 time came from -- perhaps you had a third empty file that was not shown?
+
+I've tested `git annex import` and it preserves mtimes otherwise.
+
+
+"""]]
diff --git a/doc/bugs/__96__git_annex_import__96___clobbers_mtime/comment_3_d5c7488db16b71c4f337662c897278ca._comment b/doc/bugs/__96__git_annex_import__96___clobbers_mtime/comment_3_d5c7488db16b71c4f337662c897278ca._comment
new file mode 100644
index 000000000..f3cfcfd2d
--- /dev/null
+++ b/doc/bugs/__96__git_annex_import__96___clobbers_mtime/comment_3_d5c7488db16b71c4f337662c897278ca._comment
@@ -0,0 +1,95 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 3"
+ date="2013-08-02T06:57:12Z"
+ content="""
+In this particular case
+
+* It's XFS
+* It's a normal repo
+* That the inode can have only one shared mtime is obvious, but the symlinks could have their own:
+
+Random line to make MarkDown happy
+
+ richih@eudyptes (git)-[master] ~/killme/target % stat * .git/annex/objects/pX/ZJ/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+ File: ‘foo’ -> ‘.git/annex/objects/pX/ZJ/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855’
+ Size: 178 Blocks: 8 IO Block: 4096 symbolic link
+ Device: 804h/2052d Inode: 268638577 Links: 1
+ Access: (0777/lrwxrwxrwx) Uid: ( 1000/ richih) Gid: ( 1000/ richih)
+ Access: 2013-08-02 08:51:35.976674954 +0200
+ Modify: 2013-07-30 01:19:41.000000000 +0200
+ Change: 2013-07-30 01:41:43.700701516 +0200
+ Birth: -
+ File: ‘foobar’ -> ‘.git/annex/objects/pX/ZJ/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855’
+ Size: 178 Blocks: 8 IO Block: 4096 symbolic link
+ Device: 804h/2052d Inode: 268774374 Links: 1
+ Access: (0777/lrwxrwxrwx) Uid: ( 1000/ richih) Gid: ( 1000/ richih)
+ Access: 2013-08-02 08:51:35.976674954 +0200
+ Modify: 2013-07-30 01:19:41.000000000 +0200
+ Change: 2013-07-30 01:41:43.700701516 +0200
+ Birth: -
+ File: ‘.git/annex/objects/pX/ZJ/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855’
+ Size: 0 Blocks: 0 IO Block: 4096 regular empty file
+ Device: 804h/2052d Inode: 73750 Links: 1
+ Access: (0444/-r--r--r--) Uid: ( 1000/ richih) Gid: ( 1000/ richih)
+ Access: 2013-07-30 01:20:11.915507749 +0200
+ Modify: 2013-07-30 01:19:41.131509226 +0200
+ Change: 2013-07-30 01:20:11.915507749 +0200
+ Birth: -
+ richih@eudyptes (git)-[master] ~/killme/target % touch foo
+ richih@eudyptes (git)-[master] ~/killme/target % stat * .git/annex/objects/pX/ZJ/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+ File: ‘foo’ -> ‘.git/annex/objects/pX/ZJ/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855’
+ Size: 178 Blocks: 8 IO Block: 4096 symbolic link
+ Device: 804h/2052d Inode: 268638577 Links: 1
+ Access: (0777/lrwxrwxrwx) Uid: ( 1000/ richih) Gid: ( 1000/ richih)
+ Access: 2013-08-02 08:51:35.976674954 +0200
+ Modify: 2013-07-30 01:19:41.000000000 +0200
+ Change: 2013-07-30 01:41:43.700701516 +0200
+ Birth: -
+ File: ‘foobar’ -> ‘.git/annex/objects/pX/ZJ/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855’
+ Size: 178 Blocks: 8 IO Block: 4096 symbolic link
+ Device: 804h/2052d Inode: 268774374 Links: 1
+ Access: (0777/lrwxrwxrwx) Uid: ( 1000/ richih) Gid: ( 1000/ richih)
+ Access: 2013-08-02 08:51:35.976674954 +0200
+ Modify: 2013-07-30 01:19:41.000000000 +0200
+ Change: 2013-07-30 01:41:43.700701516 +0200
+ Birth: -
+ File: ‘.git/annex/objects/pX/ZJ/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855’
+ Size: 0 Blocks: 0 IO Block: 4096 regular empty file
+ Device: 804h/2052d Inode: 73750 Links: 1
+ Access: (0444/-r--r--r--) Uid: ( 1000/ richih) Gid: ( 1000/ richih)
+ Access: 2013-08-02 08:54:34.464668766 +0200
+ Modify: 2013-08-02 08:54:34.464668766 +0200
+ Change: 2013-08-02 08:54:34.464668766 +0200
+ Birth: -
+ richih@eudyptes (git)-[master] ~/killme/target % touch --no-dereference foo
+ richih@eudyptes (git)-[master] ~/killme/target % stat * .git/annex/objects/pX/ZJ/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+ File: ‘foo’ -> ‘.git/annex/objects/pX/ZJ/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855’
+ Size: 178 Blocks: 8 IO Block: 4096 symbolic link
+ Device: 804h/2052d Inode: 268638577 Links: 1
+ Access: (0777/lrwxrwxrwx) Uid: ( 1000/ richih) Gid: ( 1000/ richih)
+ Access: 2013-08-02 08:55:07.796667610 +0200
+ Modify: 2013-08-02 08:55:07.796667610 +0200
+ Change: 2013-08-02 08:55:07.796667610 +0200
+ Birth: -
+ File: ‘foobar’ -> ‘.git/annex/objects/pX/ZJ/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855’
+ Size: 178 Blocks: 8 IO Block: 4096 symbolic link
+ Device: 804h/2052d Inode: 268774374 Links: 1
+ Access: (0777/lrwxrwxrwx) Uid: ( 1000/ richih) Gid: ( 1000/ richih)
+ Access: 2013-08-02 08:51:35.976674954 +0200
+ Modify: 2013-07-30 01:19:41.000000000 +0200
+ Change: 2013-07-30 01:41:43.700701516 +0200
+ Birth: -
+ File: ‘.git/annex/objects/pX/ZJ/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855’
+ Size: 0 Blocks: 0 IO Block: 4096 regular empty file
+ Device: 804h/2052d Inode: 73750 Links: 1
+ Access: (0444/-r--r--r--) Uid: ( 1000/ richih) Gid: ( 1000/ richih)
+ Access: 2013-08-02 08:54:34.464668766 +0200
+ Modify: 2013-08-02 08:54:34.464668766 +0200
+ Change: 2013-08-02 08:54:34.464668766 +0200
+ Birth: -
+ richih@eudyptes (git)-[master] ~/killme/target %
+
+As to where the initial time of 01:19:41 came from: Yes, those were earlier tests with other imports of empty files.
+"""]]
diff --git a/doc/bugs/__96__git_annex_import__96___clobbers_mtime/comment_4_7235130786e764ec3ad5facfecde62da._comment b/doc/bugs/__96__git_annex_import__96___clobbers_mtime/comment_4_7235130786e764ec3ad5facfecde62da._comment
new file mode 100644
index 000000000..8bc6274f9
--- /dev/null
+++ b/doc/bugs/__96__git_annex_import__96___clobbers_mtime/comment_4_7235130786e764ec3ad5facfecde62da._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 4"
+ date="2013-09-26T09:08:11Z"
+ content="""
+Fixed in http://source.git-annex.branchable.com/?p=source.git;a=commitdiff;h=98fc7e8
+"""]]
diff --git a/doc/bugs/__96__git_annex_import__96___does_not_work_on_other_git_annex_repositories.mdwn b/doc/bugs/__96__git_annex_import__96___does_not_work_on_other_git_annex_repositories.mdwn
new file mode 100644
index 000000000..1580cee81
--- /dev/null
+++ b/doc/bugs/__96__git_annex_import__96___does_not_work_on_other_git_annex_repositories.mdwn
@@ -0,0 +1,113 @@
+### Please describe the problem.
+
+`git annex import otherrepo` does not work.
+
+
+### What steps will reproduce the problem?
+
+ richih@eudyptes ~ % mcd killme/git-annex-source
+ richih@eudyptes ~/killme/git-annex-source % git init; git annex init
+ Initialized empty Git repository in /home/richih/killme/git-annex-source/.git/
+ init ok
+ (Recording state in git...)
+ richih@eudyptes (git)-[master] ~/killme/git-annex-source % dd if=/dev/urandom of=foo bs=1M count=1
+ 1+0 records in
+ 1+0 records out
+ 1048576 bytes (1.0 MB) copied, 0.281043 s, 3.7 MB/s
+ richih@eudyptes (git)-[master] ~/killme/git-annex-source % git annex add .
+ add foo (checksum...) ok
+ (Recording state in git...)
+ richih@eudyptes (git)-[master] ~/killme/git-annex-source % git commit -m files
+ [master (root-commit) 8054eeb] files
+ 1 file changed, 1 insertion(+)
+ create mode 120000 foo
+ richih@eudyptes (git)-[master] ~/killme/git-annex-source % mcd ../git-annex-import
+ richih@eudyptes ~/killme/git-annex-import % git init; git annex init
+ Initialized empty Git repository in /home/richih/killme/git-annex-import/.git/
+ init ok
+ (Recording state in git...)
+ richih@eudyptes (git)-[master] ~/killme/git-annex-import % git annex import ../git-annex-source/foo
+ richih@eudyptes (git)-[master] ~/killme/git-annex-import % ls
+
+### What version of git-annex are you using? On what operating system?
+
+4.20130920 on Debian Sid
+
+
+### PS:
+
+To add insult to injury, this does "work":
+
+ ih@eudyptes (git)-[master] ~/killme/git-annex-import % mcd bar
+ richih@eudyptes (git)-[master] ~/killme/git-annex-import/bar % git annex import ../../git-annex-source/
+ import .git/description (checksum...) ok
+ import .git/HEAD (checksum...) ok
+ import .git/config (checksum...) ok
+ import .git/index (checksum...) ok
+ import .git/COMMIT_EDITMSG (checksum...) ok
+ import .git/refs/heads/git-annex (checksum...) ok
+ import .git/refs/heads/master (checksum...) ok
+ import .git/hooks/update.sample (checksum...) ok
+ import .git/hooks/applypatch-msg.sample (checksum...) ok
+ import .git/hooks/pre-rebase.sample (checksum...) ok
+ import .git/hooks/pre-commit.sample (checksum...) ok
+ import .git/hooks/pre-applypatch.sample (checksum...) ok
+ import .git/hooks/prepare-commit-msg.sample (checksum...) ok
+ import .git/hooks/commit-msg.sample (checksum...) ok
+ import .git/hooks/post-update.sample (checksum...) ok
+ import .git/hooks/pre-push.sample (checksum...) ok
+ import .git/hooks/pre-commit (checksum...) ok
+ import .git/info/exclude (checksum...) ok
+ import .git/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 (checksum...) ok
+ import .git/objects/a2/6f9bdbe47ada699d537eaa8b6fbfc1e53ef214 (checksum...) ok
+ import .git/objects/30/4b790d132863d54313e2380bed17e557944f08 (checksum...) ok
+ import .git/objects/ab/09feaa1b55080f42ccfad8c8bb5612f2397c5a (checksum...) ok
+ import .git/objects/95/b73ee41ebe8abbd5d8c0c368d1148b5256d4f2 (checksum...) ok
+ import .git/objects/2e/96f9962c1baf83c563aa59dcc67e19f21d4b1f (checksum...) ok
+ import .git/objects/74/6306e594874907246b2300b3af22f2805dde3e (checksum...) ok
+ import .git/objects/5b/11e29d0ef96be4ee73f8dae9b2f525cb808ef1 (checksum...) ok
+ import .git/objects/fc/0c0dc4d0579a15c20be29186a27feb2ee77304 (checksum...) ok
+ import .git/objects/73/c38d817e0a9f1ef4699551ae83130edd166364 (checksum...) ok
+ import .git/objects/c9/80716b5b506515410ca3ad1d88ceae13d8f6f9 (checksum...) ok
+ import .git/objects/e2/6cb10dbce11f4065c249183bb085d0afc1b55d (checksum...) ok
+ import .git/objects/80/54eeb150b094b0d8483c43ccf2ddf182c71bd3 (checksum...) ok
+ import .git/annex/sentinal (checksum...) ok
+ import .git/annex/sentinal.cache (checksum...) ok
+ import .git/annex/index (checksum...) ok
+ import .git/annex/index.lck (checksum...) ok
+ import .git/annex/journal.lck (checksum...) ok
+ import .git/annex/objects/F7/zw/SHA256E-s1048576--74f3a1a65df608d1c8ae575f83c6ee21a5aeb1a914ca73f202a881f8c3ba8f59/SHA256E-s1048576--74f3a1a65df608d1c8ae575f83c6ee21a5aeb1a914ca73f202a881f8c3ba8f59
+ git-annex: ../../git-annex-source/.git/annex/objects/F7/zw/SHA256E-s1048576--74f3a1a65df608d1c8ae575f83c6ee21a5aeb1a914ca73f202a881f8c3ba8f59/SHA256E-s1048576--74f3a1a65df608d1c8ae575f83c6ee21a5aeb1a914ca73f202a881f8c3ba8f59: rename: permission denied (Permission denied)
+ failed
+ import .git/logs/HEAD (checksum...) ok
+ import .git/logs/refs/heads/git-annex (checksum...) ok
+ import .git/logs/refs/heads/master (checksum...) ok
+ (Recording state in git...)
+ error: Invalid path 'bar/.git/COMMIT_EDITMSG'
+ error: unable to add bar/.git/COMMIT_EDITMSG to index
+ fatal: adding files failed
+
+ git-annex: user error (xargs ["-0","git","--git-dir=/home/richih/killme/git-annex-import/.git","--work-tree=/home/richih/killme/git-annex-import","add","--"] exited 123)
+ failed
+ git-annex: import: 2 failed
+ richih@eudyptes (git)-[master] ~/killme/git-annex-import/bar % ls -la
+ total 0
+ drwxr-xr-x 3 richih richih 17 Sep 24 01:45 .
+ drwxr-xr-x 4 richih richih 38 Sep 24 01:45 ..
+ drwxr-xr-x 8 richih richih 152 Sep 24 01:45 .git
+ richih@eudyptes (git)-[master] ~/killme/git-annex-import/bar %
+
+> I have made git-annex import skip .git directories. Of course,
+> running it on *any* directory without the --duplicate option
+> will result in it moving data to git-annex, so is not advisable
+> to do that if you want to keep the data in the directory where it was.
+>
+> I am doubtful about special-casing git-annex import to do something
+> else when told to import a git-annex repository. It seems a bit of a
+> slippery slope to it getting very complicated, which we seem to already be
+> further down than I would like. If people are this pissed off about
+> git-annex import's behavior,
+> I would be inclined to *remove* it. Then you can use `mv` and `git annex
+> add`. I originally wrote git-annex import just to avoid needing to run
+> those 2 commands myself, and I can make my own local shell script
+> to do that... --[[Joey]]
diff --git a/doc/bugs/__96__git_annex_import__96___does_not_work_on_other_git_annex_repositories/comment_1_94ccd548c084286163eeb2af1ddc18e3._comment b/doc/bugs/__96__git_annex_import__96___does_not_work_on_other_git_annex_repositories/comment_1_94ccd548c084286163eeb2af1ddc18e3._comment
new file mode 100644
index 000000000..4de9cc10d
--- /dev/null
+++ b/doc/bugs/__96__git_annex_import__96___does_not_work_on_other_git_annex_repositories/comment_1_94ccd548c084286163eeb2af1ddc18e3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.220"
+ subject="comment 1"
+ date="2013-09-25T18:21:25Z"
+ content="""
+Import skips symlinks and other non-regular files. It would work if the source repository was in direct mode.
+"""]]
diff --git a/doc/bugs/__96__git_annex_import__96___does_not_work_on_other_git_annex_repositories/comment_2_befde3ef3d2b171ebb691915ff3af172._comment b/doc/bugs/__96__git_annex_import__96___does_not_work_on_other_git_annex_repositories/comment_2_befde3ef3d2b171ebb691915ff3af172._comment
new file mode 100644
index 000000000..9996882fc
--- /dev/null
+++ b/doc/bugs/__96__git_annex_import__96___does_not_work_on_other_git_annex_repositories/comment_2_befde3ef3d2b171ebb691915ff3af172._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://id.koumbit.net/anarcat"
+ ip="72.0.72.144"
+ subject="it's worse than not working, it kills! :)"
+ date="2013-10-07T12:06:22Z"
+ content="""
+so yeah, it doesn't really work well, and maybe that is to be expected because of symlinks, but it's much worse than that: the original git annex repo will actually be destroyed because git annex import will [[trash the .git metadata directory|bugs/git_annex_import_destroys_a_fellow_git_annex_repository]]. Recovering from that is... interesting, to say the least. :)
+"""]]
diff --git a/doc/bugs/__96__git_annex_sync__96___ignores_remotes.mdwn b/doc/bugs/__96__git_annex_sync__96___ignores_remotes.mdwn
new file mode 100644
index 000000000..825d9527b
--- /dev/null
+++ b/doc/bugs/__96__git_annex_sync__96___ignores_remotes.mdwn
@@ -0,0 +1,106 @@
+### Please describe the problem.
+
+A mere `git annex sync` does not go through the reachable remotes.
+
+### What steps will reproduce the problem?
+
+I do not know what could have put my repository in this state.
+
+### What version of git-annex are you using? On what operating system?
+
+git-annex version: 4.20130802-g1452ac3
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP
+local repository version: 4
+default repository version: 3
+supported repository versions: 3 4
+upgrade supported from repository versions: 0 1 2
+
+Linux dawn 3.10.3-1-ARCH #1 SMP PREEMPT Fri Jul 26 11:26:59 CEST 2013 x86_64 GNU/Linux
+
+### Please provide any additional information below.
+
+[[!format sh """
+% git annex status
+supported backends: SHA256E SHA1E SHA512E SHA224E SHA384E SHA256 SHA1 SHA512 SHA224 SHA384 WORM URL
+supported remote types: git S3 bup directory rsync web webdav glacier hook
+repository mode: direct
+trusted repositories: 1
+ f3cb4e8f-65f1-4ded-a6a1-abef64ddcff5 -- zoidberg (sam@git-annex:/media/git-annex/Music)
+semitrusted repositories: 5
+ 00000000-0000-0000-0000-000000000001 -- web
+ 063a31dc-542d-407f-a9ed-124479fa6354 -- here (dawn)
+ 22b72aa6-058b-4622-8132-27aa2d8950dc -- arrakis (sam@arrakis:~/Music)
+ 5b3a1abf-5e0b-41bc-a141-774d6236ec76 -- backup on old USB disk
+ 6affec3c-fd26-11e2-9ddd-53f02e5ca176 -- music on eeePC
+untrusted repositories: 0
+transfers in progress: none
+available local disk space: 9.83 gigabytes (+1 megabyte reserved)
+local annex keys: 3947
+local annex size: 23.51 gigabytes
+known annex keys: 3965
+known annex size: 23.56 gigabytes
+bloom filter size: 16 mebibytes (0.8% full)
+backend usage:
+ SHA256E: 7912
+
+% git remote -v
+arrakis arrakis:Music (fetch)
+arrakis arrakis:Music (push)
+zoidberg ssh://git-annex@zoidberg.rfc1149.net:2222/~/Music (fetch)
+zoidberg ssh://git-annex@zoidberg.rfc1149.net:2222/~/Music (push)
+
+# Note how here it does not seem to sync with any remote
+% git annex sync
+(Recording state in git...)
+commit
+ok
+
+% git annex sync zoidberg
+(Recording state in git...)
+commit
+ok
+pull zoidberg
+ok
+push zoidberg
+Everything up-to-date
+ok
+
+% git annex sync arrakis
+(Recording state in git...)
+commit
+ok
+pull arrakis
+From arrakis:Music
+ c1a24bd..ba060b7 git-annex -> arrakis/git-annex
+ 98b9a8e..be9c146 master -> arrakis/master
+ e0df2be..be9c146 synced/master -> arrakis/synced/master
+ok
+
+# A nameless sync with debug turned on
+% git annex sync --debug
+[2013-08-06 10:59:57 CEST] read: git ["--git-dir=/home/sam/Music/.git","--work-tree=/home/sam/Music","symbolic-ref","HEAD"]
+[2013-08-06 10:59:57 CEST] read: git ["--git-dir=/home/sam/Music/.git","--work-tree=/home/sam/Music","show-ref","refs/heads/master"]
+[2013-08-06 10:59:57 CEST] read: git ["--git-dir=/home/sam/Music/.git","--work-tree=/home/sam/Music","show-ref","git-annex"]
+[2013-08-06 10:59:57 CEST] read: git ["--git-dir=/home/sam/Music/.git","--work-tree=/home/sam/Music","show-ref","--hash","refs/heads/git-annex"]
+[2013-08-06 10:59:57 CEST] read: git ["--git-dir=/home/sam/Music/.git","--work-tree=/home/sam/Music","log","refs/heads/git-annex..ba060b7777413ab687d64771b5d6c2b36a072335","--oneline","-n1"]
+[2013-08-06 10:59:57 CEST] read: git ["--git-dir=/home/sam/Music/.git","--work-tree=/home/sam/Music","log","refs/heads/git-annex..f401f2b7b67567862df7c5b8d304f52c3af43f4b","--oneline","-n1"]
+[2013-08-06 10:59:57 CEST] read: git ["--git-dir=/home/sam/Music/.git","--work-tree=/home/sam/Music","log","refs/heads/git-annex..feaba7c5ea5f4ca73c123e6ea44ffd6333bf383e","--oneline","-n1"]
+[2013-08-06 10:59:57 CEST] chat: git ["--git-dir=/home/sam/Music/.git","--work-tree=/home/sam/Music","cat-file","--batch"]
+[2013-08-06 10:59:57 CEST] read: git ["--git-dir=/home/sam/Music/.git","--work-tree=/home/sam/Music","ls-files","--stage","-z","--others","--exclude-standard","--","/home/sam/Music"]
+[2013-08-06 10:59:57 CEST] chat: git ["--git-dir=/home/sam/Music/.git","--work-tree=/home/sam/Music","cat-file","--batch"]
+(Recording state in git...)
+[2013-08-06 11:00:16 CEST] feed: xargs ["-0","git","--git-dir=/home/sam/Music/.git","--work-tree=/home/sam/Music","add","-f"]
+commit
+[2013-08-06 11:00:16 CEST] read: git ["--git-dir=/home/sam/Music/.git","--work-tree=/home/sam/Music","commit","-m","git-annex automatic sync"]
+ok
+[2013-08-06 11:00:17 CEST] call: git ["--git-dir=/home/sam/Music/.git","--work-tree=/home/sam/Music","show-ref","--verify","-q","refs/heads/synced/master"]
+[2013-08-06 11:00:17 CEST] read: git ["--git-dir=/home/sam/Music/.git","--work-tree=/home/sam/Music","log","refs/heads/master..refs/heads/synced/master","--oneline","-n1"]
+[2013-08-06 11:00:17 CEST] read: git ["--git-dir=/home/sam/Music/.git","--work-tree=/home/sam/Music","show-ref","git-annex"]
+[2013-08-06 11:00:17 CEST] read: git ["--git-dir=/home/sam/Music/.git","--work-tree=/home/sam/Music","show-ref","--hash","refs/heads/git-annex"]
+[2013-08-06 11:00:17 CEST] read: git ["--git-dir=/home/sam/Music/.git","--work-tree=/home/sam/Music","log","refs/heads/git-annex..ba060b7777413ab687d64771b5d6c2b36a072335","--oneline","-n1"]
+[2013-08-06 11:00:17 CEST] read: git ["--git-dir=/home/sam/Music/.git","--work-tree=/home/sam/Music","log","refs/heads/git-annex..f401f2b7b67567862df7c5b8d304f52c3af43f4b","--oneline","-n1"]
+[2013-08-06 11:00:17 CEST] read: git ["--git-dir=/home/sam/Music/.git","--work-tree=/home/sam/Music","log","refs/heads/git-annex..feaba7c5ea5f4ca73c123e6ea44ffd6333bf383e","--oneline","-n1"]
+[2013-08-06 11:00:17 CEST] call: git ["--git-dir=/home/sam/Music/.git","--work-tree=/home/sam/Music","branch","-f","synced/master"]
+"""]]
+
+[[done]]
diff --git a/doc/bugs/__96__git_annex_sync__96___ignores_remotes/comment_1_39421e6935233cd8f45949ebdef369fe._comment b/doc/bugs/__96__git_annex_sync__96___ignores_remotes/comment_1_39421e6935233cd8f45949ebdef369fe._comment
new file mode 100644
index 000000000..a88baa834
--- /dev/null
+++ b/doc/bugs/__96__git_annex_sync__96___ignores_remotes/comment_1_39421e6935233cd8f45949ebdef369fe._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 1"
+ date="2013-08-07T16:13:31Z"
+ content="""
+It seems to me that you must have set `git config remote.zoidberg.annex-sync false`
+(or clicked around in the webapp and caused it to set that). If you set annex-sync back to true, it will sync with all remotes by default.
+"""]]
diff --git a/doc/bugs/__96__git_annex_sync__96___ignores_remotes/comment_2_53fb15d6fbf96d43564ff7c866239d18._comment b/doc/bugs/__96__git_annex_sync__96___ignores_remotes/comment_2_53fb15d6fbf96d43564ff7c866239d18._comment
new file mode 100644
index 000000000..1b870e1f7
--- /dev/null
+++ b/doc/bugs/__96__git_annex_sync__96___ignores_remotes/comment_2_53fb15d6fbf96d43564ff7c866239d18._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://www.rfc1149.net/"
+ nickname="Sam"
+ subject="Indeed"
+ date="2013-08-07T16:17:41Z"
+ content="""
+You are perfectly right. Every remote had this parameter set to false for a reason I do not know.
+"""]]
diff --git a/doc/bugs/_impossible_to_switch_repositories_on_android__in_webapp.mdwn b/doc/bugs/_impossible_to_switch_repositories_on_android__in_webapp.mdwn
new file mode 100644
index 000000000..21e7f7b9a
--- /dev/null
+++ b/doc/bugs/_impossible_to_switch_repositories_on_android__in_webapp.mdwn
@@ -0,0 +1,21 @@
+### Please describe the problem.
+I didn't spot this bugs page before so here is my report I have commented on android page
+
+In addition to two existing repositories (1 local /sdcard/annex, which is also avail at/storage/sdcard0/annex + 1 remote) I have added one more local (and said to keep it in sync with original local). But it didn't work -- it "Synced with onerussian.com_annex but not with Annex" and claimed that the /external/extSdCard/Annex doesn't exist, although it is there (and with .git generated etc). When I restarted the deamon I got into a "new" Repository: /storage/extSdCard/Annex which also listed the 1st local but with "Failed to sync with localhost" message -- no remote one listed. Whenever I try to "Switch repository" to /sdcard/annex (the original local) -- it starts loading a new page but gets stuck right there. The only way to revive webui is to go back to Dashboard. Log there says (retyping from the screen so typos might be there):
+
+error: cannot run git-receive-pack '/storage/sdcard0/annex': No such file or directory fatal: unable to fork
+### What steps will reproduce the problem?
+
+
+### What version of git-annex are you using? On what operating system?
+android
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
diff --git a/doc/bugs/_impossible_to_switch_repositories_on_android__in_webapp/comment_1_d488d71a72eb54d7711d2a867db6172f._comment b/doc/bugs/_impossible_to_switch_repositories_on_android__in_webapp/comment_1_d488d71a72eb54d7711d2a867db6172f._comment
new file mode 100644
index 000000000..aedeaabf3
--- /dev/null
+++ b/doc/bugs/_impossible_to_switch_repositories_on_android__in_webapp/comment_1_d488d71a72eb54d7711d2a867db6172f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnRai_qFYPVvEgC6i1nlM1bh-C__jbhqS0"
+ nickname="Matthew"
+ subject="comment 1"
+ date="2013-07-28T11:21:42Z"
+ content="""
+I can confirm it's virtually impossible to change repository on Android (Stock Galaxy Nexus GSM). you click on the files link (which is hard to see on phone as it is in the notification blocks) and then click click \"Switch repository\", on the next page, select a different one. I think it does actually change, occasionally, you have to kill and restart the daemon at least and I think you also have to restart the phone.
+"""]]
diff --git a/doc/bugs/_impossible_to_switch_repositories_on_android__in_webapp/comment_2_85b31db6d0fb2d20018db3d8c8258bf4._comment b/doc/bugs/_impossible_to_switch_repositories_on_android__in_webapp/comment_2_85b31db6d0fb2d20018db3d8c8258bf4._comment
new file mode 100644
index 000000000..0ee4e8166
--- /dev/null
+++ b/doc/bugs/_impossible_to_switch_repositories_on_android__in_webapp/comment_2_85b31db6d0fb2d20018db3d8c8258bf4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnRai_qFYPVvEgC6i1nlM1bh-C__jbhqS0"
+ nickname="Matthew"
+ subject="comment 2"
+ date="2013-07-28T11:46:30Z"
+ content="""
+For notification
+"""]]
diff --git a/doc/bugs/acl_not_honoured_in_rsync_remote.mdwn b/doc/bugs/acl_not_honoured_in_rsync_remote.mdwn
new file mode 100644
index 000000000..b5f92a9fb
--- /dev/null
+++ b/doc/bugs/acl_not_honoured_in_rsync_remote.mdwn
@@ -0,0 +1,57 @@
+in a setup where an rsync(+gnupg) remote is shared among different users of the same git-annex repository (ie, the people copying to there use different accounts on the rsync server), acls are not honored under some circumstances.
+
+the error message reads as follows:
+
+ copy …filename… (to prometheus...) Reading passphrase from file descriptor 11
+
+ sending incremental file list
+ rsync: recv_generator: mkdir "/home/shared/photos/encrypted_storage/9a6/0ff" failed: Permission denied (13)
+ *** Skipping any contents from this failed directory ***
+ 9a6/0ff/
+ rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1070) [sender=3.0.8]
+
+ sent 185 bytes received 18 bytes 135.33 bytes/sec
+ total size is 2119419 speedup is 10440.49
+
+ This could have failed because --fast is enabled.
+ failed
+
+the acl used in my particular case is:
+
+ # file: .
+ # owner: chrysn
+ # group: chrysn
+ user::rwx
+ group::rwx
+ group:family:rwx
+ mask::rwx
+ other::r-x
+ default:user::rwx
+ default:group::rwx
+ default:group:family:rwx
+ default:mask::rwx
+ default:other::r-x
+
+sub-directories are observed to have diverging permissions, though:
+
+ # file: 794
+ # owner: chrysn
+ # group: chrysn
+ user::rwx
+ group::rwx #effective:r-x
+ group:family:rwx #effective:r-x
+ mask::r-x
+ other::r-x
+ default:user::rwx
+ default:group::rwx
+ default:group:family:rwx
+ default:mask::rwx
+ default:other::r-x
+
+something seems to apply the umask (default 022) and revoke group write access from the files, overruling the acl. this is not what a umask is normally used for, and smells of [coreutils slavishly observing posix specs that don't consider all features](http://savannah.gnu.org/bugs/?19546) -- the observed effect is exactly what's described there.
+
+the git annex version used is 3.20121017 as in debian, the receiving site uses rsync 3.0.7; the affected directories come from a time when these very versions are known to have been used.
+
+this is probably not a bug of git-annex alone, but affects its operation and might be solvable by invoking rsync differently.
+
+(this is kind of a follow-up on [[forum/__34__permission_denied__34___in_fsck_on_shared_repo]])
diff --git a/doc/bugs/acl_not_honoured_in_rsync_remote/comment_1_aa6fe1d7b029eae7ee71c97e0f0937a6._comment b/doc/bugs/acl_not_honoured_in_rsync_remote/comment_1_aa6fe1d7b029eae7ee71c97e0f0937a6._comment
new file mode 100644
index 000000000..c24b02157
--- /dev/null
+++ b/doc/bugs/acl_not_honoured_in_rsync_remote/comment_1_aa6fe1d7b029eae7ee71c97e0f0937a6._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.27"
+ subject="comment 1"
+ date="2012-11-06T20:49:47Z"
+ content="""
+I don't know much about ACLs, but you might try setting `remote.prometheus.annex-rsync-options` with rsync options such as --acls or --no-acls
+"""]]
diff --git a/doc/bugs/acl_not_honoured_in_rsync_remote/comment_2_ffb9424e966ee10a4fe2d446b3042cb2._comment b/doc/bugs/acl_not_honoured_in_rsync_remote/comment_2_ffb9424e966ee10a4fe2d446b3042cb2._comment
new file mode 100644
index 000000000..96dbc6a2e
--- /dev/null
+++ b/doc/bugs/acl_not_honoured_in_rsync_remote/comment_2_ffb9424e966ee10a4fe2d446b3042cb2._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://christian.amsuess.com/chrysn"
+ nickname="chrysn"
+ subject="further tracking"
+ date="2012-11-11T01:15:41Z"
+ content="""
+the behavior is rooted in rsync, which behaves similar to `mkdir -p`. it can probably be worked around by configuring the rsync option `--chmod=775`, but that would add executability to files.
+
+i've opened a bug in rsync's bug tracker at <https://bugzilla.samba.org/show_bug.cgi?id=9377>, let's see what the developer says.
+"""]]
diff --git a/doc/bugs/add_range_argument_to___34__git_annex_dropunused__34___.mdwn b/doc/bugs/add_range_argument_to___34__git_annex_dropunused__34___.mdwn
new file mode 100644
index 000000000..471a698a0
--- /dev/null
+++ b/doc/bugs/add_range_argument_to___34__git_annex_dropunused__34___.mdwn
@@ -0,0 +1,21 @@
+The command `git annex dropunused` currently takes a number, as referenced in output of last `git annex unused` command.
+
+When you want to drop all, or a range, this may be annoying, as you have to specify each number on the command line.
+
+A range argument, such as `1-1845`, possibly combined with other argument types (Cf. many print dialogues: `1,3,5-7,9`) would be great.
+
+I work around this lack as I want to drop all unused files anyway by something like this:
+
+ git annex unused | grep -o -P "^ [0-9]+" | xargs git annex dropunused
+
+> It's designed to be used with `seq`. There's an example in the
+> [[walkthrough|walkthrough/unused_data]], and of course multiple seq calls can be used to
+> specifiy multiple ranges. So:
+
+ git annex dropunused `seq 1 9` `seq 11 1845`
+
+> I don't see adding my own range operations to be an improvement worth
+> making; it'd arguably only be a complication. --[[Joey]] [[done]]
+
+>> Actually, this did get implemented, since using seq could fall afoul
+>> of command-line length limits in extreme cases.
diff --git a/doc/bugs/add_script-friendly_output_options.mdwn b/doc/bugs/add_script-friendly_output_options.mdwn
new file mode 100644
index 000000000..7d7bdfc51
--- /dev/null
+++ b/doc/bugs/add_script-friendly_output_options.mdwn
@@ -0,0 +1,19 @@
+I have a need to use git-annex from a larger program. It'd be great if the information output by some of the commands that is descriptive (for example, whereis) could be sent to stdout in a machine-readable format like (preferably) JSON, or XML. That way I can simply read in the output of the command and use the data directly instead of having to parse it via regexes or other such string manipulation.
+
+This could perhaps be triggered by a --json or --xml flag to the relevant commands.
+
+> This is [[done]], --json is supported by all commands, more or less.
+>
+> Caveats:
+>
+> * the version, status, and find commands produce custom output and so
+> no json. This could change for version and status; find needs to just
+> be a simple list of files, I think
+> * The "note" fields may repeat multiple times per object with different
+> notes and are of course not machine readable, and subject to change.
+> * Output of helper commands like rsync is not diverted away, and
+> could clutter up the json output badly. Should only affect commands
+> that transfer data. And AFAICS, wget and rsync both output their
+> progress displays to stderr, so shouldn't be a problem.
+>
+> --[[Joey]]
diff --git a/doc/bugs/added_branches_makes___39__git_annex_unused__39___slow.mdwn b/doc/bugs/added_branches_makes___39__git_annex_unused__39___slow.mdwn
new file mode 100644
index 000000000..95751527b
--- /dev/null
+++ b/doc/bugs/added_branches_makes___39__git_annex_unused__39___slow.mdwn
@@ -0,0 +1,87 @@
+Creating additional branches in history seems to slow down the 'git annex unused' command quadratically, even if the location of the branches should be irrelevant as far as unused data goes.
+
+This was tested on:
+
+ $ git annex version
+ git-annex version: 3.20130216
+ local repository version: 3
+ default repository version: 3
+ supported repository versions: 3
+ upgrade supported from repository versions: 0 1 2
+
+What steps will reproduce the problem?
+
+ $ mkdir a
+ $ cd a
+ $ git init
+ $ git annex init
+ $ i=0 ; while test $i -lt 1000; do dd if=/dev/urandom of=$i.img bs=1M count=1; i=$(($i+1)); done
+ $ git annex add .
+ $ git commit -m"foo"
+ $ git rm 1*
+ $ git commit -m"bar"
+ $ git log --oneline --decorate
+ ffcca3a (HEAD, master) bar
+ 3e7793d foo
+ $ time -p git annex unused
+ unused . (checking for unused data...) (checking master...)
+ (...)
+ real 0.76
+ user 0.40
+ sys 0.06
+ git commit --allow-empty -m"baz"
+ $ git log --oneline --decorate
+ 4390c32 (HEAD, master) baz
+ ffcca3a bar
+ 3e7793d foo
+ $ time -p git annex unused
+ unused . (checking for unused data...) (checking master...)
+ (...)
+ real 0.75
+ user 0.38
+ sys 0.07
+ $ git branch boo HEAD^
+ $ time -p git annex unused
+ unused . (checking for unused data...) (checking boo...) (checking master...)
+ (...)
+ real 1.29
+ user 0.62
+ sys 0.08
+ arand@mas:~/tmp/more/a(master)$ git branch beeboo HEAD^
+ 4390c32 (HEAD, master) baz
+ ffcca3a (boo, beeboo) bar
+ 3e7793d foo
+ arand@mas:~/tmp/more/a(master)$ time -p git annex unused
+ unused . (checking for unused data...) (checking beeboo...) (checking master...)
+ (...)
+ real 2.50
+ user 1.12
+ sys 0.14
+ $ git branch -d boo beeboo
+ $ git log --oneline --decorate
+ 4390c32 (HEAD, master) baz
+ ffcca3a bar
+ 3e7793d foo
+ $ time -p git annex unused
+ unused . (checking for unused data...) (checking master...)
+ (...)
+ real 0.77
+ user 0.42
+ sys 0.04
+
+What is the expected output? What do you see instead?
+
+I would expect the time to be the same in all the above cases.
+
+What version of git-annex are you using? On what operating system?
+
+ $ git annex version
+ git-annex version: 3.20130216
+
+On current Debian sid/experimental
+
+> [[Done]], thanks to guilhem. We ended up using a different algorythm
+> which is faster yet, basically it now does a diff-index between the
+> index and each branch for its second stage bloom filter.
+> Speedup is 30x with 0 (or 1?) branch, and then massive for each
+> additional branch. --[[Joey]]
diff --git a/doc/bugs/added_branches_makes___39__git_annex_unused__39___slow/comment_1_d350c39c67031c500e3224e92c0029ea._comment b/doc/bugs/added_branches_makes___39__git_annex_unused__39___slow/comment_1_d350c39c67031c500e3224e92c0029ea._comment
new file mode 100644
index 000000000..f8b7e789b
--- /dev/null
+++ b/doc/bugs/added_branches_makes___39__git_annex_unused__39___slow/comment_1_d350c39c67031c500e3224e92c0029ea._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.210"
+ subject="comment 1"
+ date="2013-02-26T20:29:05Z"
+ content="""
+`git annex unused` finds content that is not used by the working tree or by *any* branch is unused. For the working tree, it can look at the symlinks on disk, which is the fastest option.
+
+For branches, it has to first use `git ls-tree` to find the files on the branch, and then use `git cat-file` to look up the key used by each file. It does this as fast as it can (eg, it runs a single `git cat-file --batch`, rather than one process per file). Still, this is pulling potentially a lot of data out of git, and it gets pretty slow.
+
+I've spent a lot of time optimising this as much as is possible with these constraints. One nice one is that, if it finds no unused keys after checking the working tree, it can stop, rather than checking any branches. Your example avoids this optimisation.
+
+Another optimisation is to only check each git ref once, even if multiple branches refer to it. You can see this optmisation firing in your transcript, when it only shows it's checking one branch of the two identical branches you've made.
+
+Indeed, if you go on and add 100 identical branches, you'll find it runs in just about the same time it ran with 2 branches. (There's a little overhead in getting the list of branches and throwing out the duplicates, but that's all.)
+
+What then explains your numbers? Well, I have no idea. I cannot replicate them; I tend to see about the same amount of time taken with two duplicate branches as with one branch. I suspect you just didn't get statistically valid results, which playing around with `time` at the command line often doesn't,
+due to caching, other active processes, etc.
+"""]]
diff --git a/doc/bugs/added_branches_makes___39__git_annex_unused__39___slow/comment_2_b2d2b1caa51ffec3d87c36b373cb8d4a._comment b/doc/bugs/added_branches_makes___39__git_annex_unused__39___slow/comment_2_b2d2b1caa51ffec3d87c36b373cb8d4a._comment
new file mode 100644
index 000000000..0954e8988
--- /dev/null
+++ b/doc/bugs/added_branches_makes___39__git_annex_unused__39___slow/comment_2_b2d2b1caa51ffec3d87c36b373cb8d4a._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="https://launchpad.net/~arand"
+ nickname="arand"
+ subject="comment 2"
+ date="2013-02-27T15:53:37Z"
+ content="""
+Hmm, indeed, after further testing it seems like the increased time due to the duplicate branch seems to have been a random quirk, bleh :(
+
+But shouldn't it theoretically be possible to optimize out much of the overhead of multiple very-similar (though not identical) branches though?
+
+I've experimented around with ls-tree and cat-file in a bash script[1], and in this primitive implementation the running time seems to be considerably lower (~0.3s vs ~4s), with much less overhead for extra very-similar branches (~0.7s vs ~37s)
+
+Am I missing some key element that's the reason for the time taken by git annex unused?
+
+
+[1] primitive annex unused script: [https://gitorious.org/arand-scripts/arand-scripts/blobs/master/annex-funused](https://gitorious.org/arand-scripts/arand-scripts/blobs/master/annex-funused)
+
+timing script: [https://gitorious.org/arand-scripts/arand-scripts/blobs/master/annex-testunused](https://gitorious.org/arand-scripts/arand-scripts/blobs/master/annex-testunused)
+
+"""]]
diff --git a/doc/bugs/added_branches_makes___39__git_annex_unused__39___slow/comment_3_12b20cbbc2b4cd1ab8af7e3eec9589b4._comment b/doc/bugs/added_branches_makes___39__git_annex_unused__39___slow/comment_3_12b20cbbc2b4cd1ab8af7e3eec9589b4._comment
new file mode 100644
index 000000000..9c1da8eea
--- /dev/null
+++ b/doc/bugs/added_branches_makes___39__git_annex_unused__39___slow/comment_3_12b20cbbc2b4cd1ab8af7e3eec9589b4._comment
@@ -0,0 +1,30 @@
+[[!comment format=mdwn
+ username="arand"
+ ip="130.243.226.21"
+ subject="comment 3"
+ date="2013-08-10T17:00:21Z"
+ content="""
+So, if I've understood it correctly (please correct me if that's not the case :) )
+
+Currently git-annex unused goes through this process
+
+* Look through all files in the index and find those which are git-annex keys (git ls-tree + git cat-file)
+* Look through all files the current ref and find those which are git-annex keys (git ls-tree + git cat-file)
+* For each ref in the repo
+ - Look through all files and find those which are git-annex keys (git ls-tree + git cat-file)
+* Then at the end
+ - Compare this list of keys with what is stored in .git/annex/objects
+ - Print out any objects which does not match a key.
+
+If that's the case, it means if that if you have multiple refs, even is they only differ by single empty commits, git-annex will end up doing a cat-file for the same file multiple times (one per ref), which is expensive.
+
+Would it be possible to change the algorithm for git-annex unused into instead something like:
+
+* For the index, HEAD, and all refs
+ - Create a list all files and remove those which are duplicates based on their sha1 hash (git ls-tree | uniq)
+* Then Look through this reduced list to find those which are git-annex keys (git cat-file)
+* Then check as before
+
+Unless this bypasses some safety or case I've overlooked, I think it should be possible to speed up git-annex unused quite a bit.
+
+"""]]
diff --git a/doc/bugs/added_branches_makes___39__git_annex_unused__39___slow/comment_4_a50b43c15d2650df90f0fa1ced47f532._comment b/doc/bugs/added_branches_makes___39__git_annex_unused__39___slow/comment_4_a50b43c15d2650df90f0fa1ced47f532._comment
new file mode 100644
index 000000000..3de85407e
--- /dev/null
+++ b/doc/bugs/added_branches_makes___39__git_annex_unused__39___slow/comment_4_a50b43c15d2650df90f0fa1ced47f532._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 4"
+ date="2013-08-11T12:48:47Z"
+ content="""
+I think that could work. It would probably tend to use more memory than the current method, but only a small constant multiplier more. And unused is already the one command that necessarily needs to hold information about the whole repository in memory.
+
+Note that git cat-file is only needed when dealing with branches other than the current working tree. In that special case, it can, and AFAIK does have the optimisation of looking directly at the symlink target instead. Your method may turn out to be both slower and use more memory in that case. It may make sense to special case handling of that case and keep the current code paths there (most of the necessary code for it is used by other stuff anyway).
+"""]]
diff --git a/doc/bugs/added_branches_makes___39__git_annex_unused__39___slow/comment_5_7328bc51bd001f2b732a92a2ae175839._comment b/doc/bugs/added_branches_makes___39__git_annex_unused__39___slow/comment_5_7328bc51bd001f2b732a92a2ae175839._comment
new file mode 100644
index 000000000..21890a4e1
--- /dev/null
+++ b/doc/bugs/added_branches_makes___39__git_annex_unused__39___slow/comment_5_7328bc51bd001f2b732a92a2ae175839._comment
@@ -0,0 +1,114 @@
+[[!comment format=mdwn
+ username="arand"
+ ip="130.243.226.21"
+ subject="comment 5"
+ date="2013-08-11T20:43:22Z"
+ content="""
+I've compared my bash/coreutils implementation mentioned above [annex-funused](https://gitorious.org/arand-scripts/arand-scripts/blobs/918cc79b99e22cbdca01ea4de10e2ca64abfc27a/annex-funused) with `git annex unused` in various situations, and from what I've seen `annex-funused` is pretty much always faster.
+
+In the case of no unused files they seem to be about the same.
+
+In all other cases there is a very considerable difference, for example, in my current main annex I get:
+
+ $ time git annex unused
+ unused . (checking for unused data...) (checking master...) (checking synced/master...) (checking barracuda160G/master...) ok
+
+ real 5m13.830s
+ user 2m0.444s
+ sys 0m28.344s
+
+
+whereas
+
+ $ time annex-funused
+ == WARNING ==
+ This program should NOT be trusted to reliably find unused files in the
+ git annex.
+
+
+ real 0m1.569s
+ user 0m2.024s
+ sys 0m0.184s
+
+I tried to check memory usage via `/usr/bin/time -v` as well, and that showed (re-running in the same annex as above)
+
+annex-funused
+
+ Maximum resident set size (kbytes): 13560
+
+git annex unused
+
+ Maximum resident set size (kbytes): 29120
+
+
+I've also written a comparison script [annex-testunused](https://gitorious.org/arand-scripts/arand-scripts/blobs/918cc79b99e22cbdca01ea4de10e2ca64abfc27a/annex-testunused) (needs annex-funused in $PATH) which creates an annex with a bunch of unused files and compares the running time for both versions:
+
+<pre>
+$ annex-testunused
+Initialized empty Git repository in /tmp/tmp.fmsAvsPTcd/.git/
+init ok
+(Recording state in git...)
+###
+* b2840d7 (HEAD, master) delete ~1100 files
+* c4a1e3a add 3000 files
+* bc19777 (git-annex) update
+* b3e6539 update
+* bec2c8f branch created
+annex unused
+real 0m4.154s
+real 0m2.029s
+real 0m2.044s
+annex funused
+real 0m0.923s
+real 0m0.933s
+real 0m0.905s
+Initialized empty Git repository in /tmp/tmp.7qFoCRWzB3/.git/
+init ok
+(Recording state in git...)
+###
+* a5ff392 (HEAD, master) empty
+* cca4810 (1) delete ~1100 files
+* 587c406 add 3000 files
+* de0afeb (git-annex) update
+* 37b7881 update
+* 1735062 branch created
+annex unused
+real 0m3.499s
+real 0m3.443s
+real 0m3.435s
+annex funused
+real 0m0.956s
+real 0m0.956s
+real 0m0.874s
+Initialized empty Git repository in /tmp/tmp.L5fjdAgnFv/.git/
+init ok
+(Recording state in git...)
+###
+* 94463a0 (HEAD, master) empty
+* e115619 (10) empty
+* 20686d4 (9) empty
+* 2e01a3f (8) empty
+* 043289d (7) empty
+* 6a52966 (6) empty
+* 0dc866d (5) empty
+* 35db331 (4) empty
+* 48504bc (3) empty
+* e25cac7 (2) empty
+* 655d026 (1) delete ~1100 files
+* 91a07d1 add 3000 files
+* 3c9ac62 (git-annex) update
+* c5736e0 update
+* 862d5b8 branch created
+annex unused
+real 0m16.242s
+real 0m16.277s
+real 0m16.246s
+annex funused
+real 0m0.960s
+real 0m0.960s
+real 0m0.927s
+</pre>
+
+So, unless I've missed something fundamental (I keep thinking I might have...), it seems to be very consistently faster, and scale ok where `git annex unused` scales rather poorly.
+
+"""]]
diff --git a/doc/bugs/added_branches_makes___39__git_annex_unused__39___slow/comment_6_880ef2ee797221332dbb629b2d55522f._comment b/doc/bugs/added_branches_makes___39__git_annex_unused__39___slow/comment_6_880ef2ee797221332dbb629b2d55522f._comment
new file mode 100644
index 000000000..a4fea313f
--- /dev/null
+++ b/doc/bugs/added_branches_makes___39__git_annex_unused__39___slow/comment_6_880ef2ee797221332dbb629b2d55522f._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 6"
+ date="2013-08-12T04:14:18Z"
+ content="""
+The memory usage is probably lower because `sort` and `comm` and bash's `<(command)` all have particularly well tuned memory usage with 37 years of history behind them. Particularly GNU `sort` will transparently use a temp file rather than storing too much data in memory, and does rather sophisticated stuff to make that work efficiently. It's rather harder to get that kind of behavior when not using the unix tools and instead using stock programming language primatives like sort() and hashes.
+
+I still suspect that `git cat-file` is slower than a direct readlink(2) of the symlink, when that can be done.
+"""]]
diff --git a/doc/bugs/added_branches_makes___39__git_annex_unused__39___slow/comment_7_826fd82cdf9b1c79c9b555ca26c2c176._comment b/doc/bugs/added_branches_makes___39__git_annex_unused__39___slow/comment_7_826fd82cdf9b1c79c9b555ca26c2c176._comment
new file mode 100644
index 000000000..c2dbd1810
--- /dev/null
+++ b/doc/bugs/added_branches_makes___39__git_annex_unused__39___slow/comment_7_826fd82cdf9b1c79c9b555ca26c2c176._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="arand"
+ ip="130.243.226.21"
+ subject="comment 7"
+ date="2013-08-12T18:07:44Z"
+ content="""
+Hmm, probably, do you think this way of getting everything and then doing the filtering could work reasonably in git-annex? Assuming \"git cat-file --batch\" is the main bottleneck, reducing the amount of runs for it would still likely be an improvement?
+"""]]
diff --git a/doc/bugs/adding_an_rsync.net_repo_give_an_gpg_error.mdwn b/doc/bugs/adding_an_rsync.net_repo_give_an_gpg_error.mdwn
new file mode 100644
index 000000000..bb340231f
--- /dev/null
+++ b/doc/bugs/adding_an_rsync.net_repo_give_an_gpg_error.mdwn
@@ -0,0 +1,22 @@
+### Please describe the problem.
+adding an rsync.net repo returns an internal server error "user error (gpg ["--quite","--trust-model","always","--gen-random","--armor","1","512"] exited 127)
+
+
+### What steps will reproduce the problem?
+add an rsync.net repo
+
+
+### What version of git-annex are you using? On what operating system?
+4.20130516-g8a26544 for OSX Mountain Lion
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/debug.log
+
+
+# End of transcript or log.
+"""]]
+
+> [[done]]; the OSX gpg was broken for a while, now fixed. --[[Joey]]
diff --git a/doc/bugs/adding_an_rsync.net_repo_give_an_gpg_error/comment_1_f55cfc133be72ac10cae93c877c487df._comment b/doc/bugs/adding_an_rsync.net_repo_give_an_gpg_error/comment_1_f55cfc133be72ac10cae93c877c487df._comment
new file mode 100644
index 000000000..7daf6b734
--- /dev/null
+++ b/doc/bugs/adding_an_rsync.net_repo_give_an_gpg_error/comment_1_f55cfc133be72ac10cae93c877c487df._comment
@@ -0,0 +1,21 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-05-19T21:09:54Z"
+ content="""
+I'm seeing some indications (this bug and also the [[git_annex_fork_bombs_on_gpg_file]] bug) that gpg is somehow broken on OSX.
+
+Aha. I just tried on my build box, and:
+
+<pre>
+oberon:~ joeyh$ gpg
+dyld: warning, LC_RPATH @loader_path/../lib in /usr/local/bin/gpg being ignored in restricted program because of @loader_path
+dyld: Library not loaded: @rpath/libz.1.2.7.dylib
+ Referenced from: /usr/local/bin/gpg
+ Reason: image not found
+</pre>
+
+So, I'm packing up a broken gpg. Need to fix that then..
+
+"""]]
diff --git a/doc/bugs/adding_an_rsync.net_repo_give_an_gpg_error/comment_2_24dd024ac4b21a82a781343b8fe3891e._comment b/doc/bugs/adding_an_rsync.net_repo_give_an_gpg_error/comment_2_24dd024ac4b21a82a781343b8fe3891e._comment
new file mode 100644
index 000000000..b1a4114a2
--- /dev/null
+++ b/doc/bugs/adding_an_rsync.net_repo_give_an_gpg_error/comment_2_24dd024ac4b21a82a781343b8fe3891e._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnmvJtM53ZX9h8OGQoU2t2OfGwrF7rxFX0"
+ nickname="Shawn"
+ subject="fixed"
+ date="2013-05-22T14:37:05Z"
+ content="""
+seems to be fix with 4.20130521-g25dba9d.
+
+
+Thanks
+"""]]
diff --git a/doc/bugs/addurl:___34__rename:_does_not_exist__34___and_reports_fail__44___but_succeeds.mdwn b/doc/bugs/addurl:___34__rename:_does_not_exist__34___and_reports_fail__44___but_succeeds.mdwn
new file mode 100644
index 000000000..3383dd52a
--- /dev/null
+++ b/doc/bugs/addurl:___34__rename:_does_not_exist__34___and_reports_fail__44___but_succeeds.mdwn
@@ -0,0 +1,197 @@
+### Please describe the problem.
+
+"git annex --pathdepth=3 addurl URL" displays this error message and reports "failed", even though the operation succeeds when using --fast:
+
+ git-annex: /media/usb32g-1/annex/musikk/.git/annex/tmp/2325: rename: does not exist (No such file or directory)
+
+### What steps will reproduce the problem?
+
+I have lots of downloaded files I'd like to add an URL to, so I'm doing this:
+
+ $ ga addurl --fast --pathdepth=3 $(for f in *.mp3; do echo http://traffic.libsyn.com/geologicpodcast/$f; done)
+ addurl
+ git-annex: /media/usb32g-1/annex/musikk/.git/annex/tmp/2325: rename: does not exist (No such file or directory)
+ failed
+ addurl
+ git-annex: /media/usb32g-1/annex/musikk/.git/annex/tmp/2325: rename: does not exist (No such file or directory)
+ failed
+ addurl
+ git-annex: /media/usb32g-1/annex/musikk/.git/annex/tmp/2325: rename: does not exist (No such file or directory)
+ [... Delete 166 lines ...]
+ addurl
+ git-annex: /media/usb32g-1/annex/musikk/.git/annex/tmp/2325: rename: does not exist (No such file or directory)
+ failed
+ addurl
+ git-annex: /media/usb32g-1/annex/musikk/.git/annex/tmp/2325: rename: does not exist (No such file or directory)
+ failed
+ (Recording state in git...)
+ git-annex: addurl: 60 failed
+ $
+
+This "ga" command is a wrapper around git-annex to make it work everywhere with the .tar.gz version:
+
+ #!/bin/bash
+
+ #=======================================================================
+ # ga
+ # File ID: e89047ce-29d1-11e2-bb6f-00c0a8deee11
+ #=======================================================================
+
+ if test "$1" = "sync"; then
+ stat_output="$(git status --porcelain | grep -v '^??')"
+ test -n "$stat_output" && { echo ga: Repo has modifications, will not git-annex sync >&2; exit 1; }
+ fi
+ /opt/git-annex/runshell /opt/git-annex/git-annex "$@"
+
+$PATH is also set up to include /opt/git-annex/bin/ , and all other operations work nicely. In my ~/bin/ directory I've also symlinked this script to "git-annex".
+
+When dropping "--fast", this happens:
+
+ $ ga addurl --pathdepth=3 $(for f in *.mp3; do echo http://traffic.libsyn.com/geologicpodcast/$f; done | tail -20 | head -1)
+ addurl (downloading http://traffic.libsyn.com/geologicpodcast/GeologicPodcast302-Feb28-13.mp3 ...) --2013-07-04 14:08:01-- http://traffic.libsyn.com/geologicpodcast/GeologicPodcast302-Feb28-13.mp3
+ Resolving traffic.libsyn.com (traffic.libsyn.com)... 204.16.245.39
+ Connecting to traffic.libsyn.com (traffic.libsyn.com)|204.16.245.39|:80... connected.
+ HTTP request sent, awaiting response... 302 Found
+ Location: http://ec.libsyn.com/p/6/9/b/69b9837556ed5238/GeologicPodcast302-Feb28-13.mp3?d13a76d516d9dec20c3d276ce028ed5089ab1ce3dae902ea1d01cf853ed5cd5c0f85&c_id=5440885 [following]
+ --2013-07-04 14:08:02-- http://ec.libsyn.com/p/6/9/b/69b9837556ed5238/GeologicPodcast302-Feb28-13.mp3?d13a76d516d9dec20c3d276ce028ed5089ab1ce3dae902ea1d01cf853ed5cd5c0f85&c_id=5440885
+ Resolving ec.libsyn.com (ec.libsyn.com)... 68.232.34.133
+ Connecting to ec.libsyn.com (ec.libsyn.com)|68.232.34.133|:80... connected.
+ HTTP request sent, awaiting response... 200 OK
+ Length: 53173384 (51M) [audio/mpeg]
+ Saving to: `/media/usb32g-1/annex/musikk/.git/annex/tmp/URL--http&c%%traffic.libsyn.com%geologicpodcast%GeologicPodcast302-Feb28-13.mp3'
+
+ 100%[==================================================================================================================================================================>] 53,173,384 3.50M/s in 45s
+
+ 2013-07-04 14:08:47 (1.13 MB/s) - `/media/usb32g-1/annex/musikk/.git/annex/tmp/URL--http&c%%traffic.libsyn.com%geologicpodcast%GeologicPodcast302-Feb28-13.mp3' saved [53173384/53173384]
+
+ (checksum...)
+ git-annex: /media/usb32g-1/annex/musikk/.git/annex/tmp/3970: rename: does not exist (No such file or directory)
+ failed
+ (Recording state in git...)
+ git-annex: addurl: 1 failed
+ $
+
+git-annex now believes that the file is stored locally, but an fsck shows how things really are:
+
+ $ ga fsck
+ fsck GeologicPodcast02-Feb21-07.mp3 ok
+ fsck GeologicPodcast03-Feb28-07.mp3 ok
+ [... Delete 35 lines ...]
+ fsck GeologicPodcast301-Feb22-13.mp3 ok
+ fsck GeologicPodcast302-Feb28-13.mp3 (fixing location log)
+ ** Based on the location log, GeologicPodcast302-Feb28-13.mp3
+ ** was expected to be present, but its content is missing.
+ failed
+ fsck GeologicPodcast303-Mar07-13.mp3 ok
+ fsck GeologicPodcast303.1_Fancast6-Mar09-13.mp3 ok
+ [... Delete 16 lines ...]
+ fsck GeologicPodcast72-Jul03-08.mp3 ok
+ (Recording state in git...)
+ git-annex: fsck: 3 failed
+ $
+
+After this fsck, everything is OK again; the location log is correct and "get" from this URL works.
+
+The file data didn't exist locally (it's stored on another disk) when doing this, but I also experimented what would happen if the file data did exist:
+
+ $ rm GeologicPodcast297-Jan24-13.mp3
+ $ wget http://traffic.libsyn.com/geologicpodcast/GeologicPodcast297-Jan24-13.mp3
+ --2013-07-04 14:35:15-- http://traffic.libsyn.com/geologicpodcast/GeologicPodcast297-Jan24-13.mp3
+ Resolving traffic.libsyn.com (traffic.libsyn.com)... 204.16.245.39
+ Connecting to traffic.libsyn.com (traffic.libsyn.com)|204.16.245.39|:80... connected.
+ HTTP request sent, awaiting response... 302 Found
+ Location: http://hwcdn.libsyn.com/p/9/d/f/9df13b1a6d622c46/GeologicPodcast297-Jan24-13.mp3?c_id=5341445&expiration=1372945406&hwt=476d03abba40d71119011bf7cb51f68a [following]
+ --2013-07-04 14:35:16-- http://hwcdn.libsyn.com/p/9/d/f/9df13b1a6d622c46/GeologicPodcast297-Jan24-13.mp3?c_id=5341445&expiration=1372945406&hwt=476d03abba40d71119011bf7cb51f68a
+ Resolving hwcdn.libsyn.com (hwcdn.libsyn.com)... 69.16.175.42, 69.16.175.10
+ Connecting to hwcdn.libsyn.com (hwcdn.libsyn.com)|69.16.175.42|:80... connected.
+ HTTP request sent, awaiting response... 200 OK
+ Length: 49299974 (47M) [audio/mpeg]
+ Saving to: ‘GeologicPodcast297-Jan24-13.mp3’
+
+ 100%[===========================================================================================================================================>] 49,299,974 5.88MB/s in 30s
+
+ $ ga add
+ add GeologicPodcast297-Jan24-13.mp3 (checksum...) ok
+ (Recording state in git...)
+ $ ga addurl --pathdepth=3 http://traffic.libsyn.com/geologicpodcast/GeologicPodcast297-Jan24-13.mp3
+
+At this stage, the data for this .mp3 file exist locally, but git-annex is either unaware of it, or it insists on verifying the data. Anyhow, it downloads the file:
+
+ $ ga addurl --pathdepth=3 http://traffic.libsyn.com/geologicpodcast/GeologicPodcast297-Jan24-13.mp3
+ addurl (downloading http://traffic.libsyn.com/geologicpodcast/GeologicPodcast297-Jan24-13.mp3 ...) --2013-07-04 14:42:40-- http://traffic.libsyn.com/geologicpodcast/GeologicPodcast297-Jan24-13.mp3
+ Resolving traffic.libsyn.com (traffic.libsyn.com)... 204.16.245.39
+ Connecting to traffic.libsyn.com (traffic.libsyn.com)|204.16.245.39|:80... connected.
+ HTTP request sent, awaiting response... 302 Found
+ Location: http://ec.libsyn.com/p/9/d/f/9df13b1a6d622c46/GeologicPodcast297-Jan24-13.mp3?d13a76d516d9dec20c3d276ce028ed5089ab1ce3dae902ea1d01cf853ed5cc54b707&c_id=5341445 [following]
+ --2013-07-04 14:42:41-- http://ec.libsyn.com/p/9/d/f/9df13b1a6d622c46/GeologicPodcast297-Jan24-13.mp3?d13a76d516d9dec20c3d276ce028ed5089ab1ce3dae902ea1d01cf853ed5cc54b707&c_id=5341445
+ Resolving ec.libsyn.com (ec.libsyn.com)... 68.232.34.133
+ Connecting to ec.libsyn.com (ec.libsyn.com)|68.232.34.133|:80... connected.
+ HTTP request sent, awaiting response... 206 Partial Content
+ Length: 49299974 (47M), 48727654 (46M) remaining [audio/mpeg]
+ Saving to: `/media/usb32g-1/annex/musikk/.git/annex/tmp/URL--http&c%%traffic.libsyn.com%geologicpodcast%GeologicPodcast297-Jan24-13.mp3'
+
+ 100%[====================================================================================================================================================================>] 49,299,974 2.07M/s in 88s
+
+ 2013-07-04 14:44:10 (538 KB/s) - `/media/usb32g-1/annex/musikk/.git/annex/tmp/URL--http&c%%traffic.libsyn.com%geologicpodcast%GeologicPodcast297-Jan24-13.mp3' saved [49299974/49299974]
+
+ (checksum...)
+ git-annex: /media/usb32g-1/annex/musikk/.git/annex/objects/gp/7Z/SHA256-s49299974--ff6758202d7168a0548b004d0c6e79a095b7738f442aa14d2603665914bee7e0/SHA256-s49299974--ff6758202d7168a0548b004d0c6e79a095b7738f442aa14d2603665914bee7e0: rename: does not exist (No such file or directory)
+ failed
+ (Recording state in git...)
+ git-annex: addurl: 1 failed
+ 2013-07-04 14:44:11 sunny@dg-vbox:/media/usb32g-1/annex/musikk/podcast/Geologic Podcast (master)
+ $
+
+The error message appears again, but because the data did exist from before, git-annex fsck has nothing to complain about:
+
+ $ ga fsck
+ [...]
+ fsck GeologicPodcast297-Jan24-13.mp3 (checksum...) ok
+ [...]
+ 2013-07-04 14:44:33 sunny@dg-vbox:/media/usb32g-1/annex/musikk/podcast/Geologic Podcast (master)
+ $
+
+### What version of git-annex are you using? On what operating system?
+
+v4.20130627 Linux i386 and AMD64. Both versions behave the same way. Tested on two computers:
+
+Computer #1 (AMD64 version):
+
+ $ uname -a
+ Linux dg-vbox 3.8.0-19-generic #30-Ubuntu SMP Wed May 1 16:35:23 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
+ $ lsb_release -a
+ No LSB modules are available.
+ Distributor ID: LinuxMint
+ Description: Linux Mint 15 Olivia
+ Release: 15
+ Codename: olivia
+
+Computer #2 (i386 version):
+
+ $ uname -a
+ Linux linode 2.6.39.1-linode34 #1 SMP Tue Jun 21 10:29:24 EDT 2011 i686 GNU/Linux
+ $ lsb_release -a
+ Distributor ID: Ubuntu
+ Description: Ubuntu 10.04.4 LTS
+ Release: 10.04
+ Codename: lucid
+ No LSB modules are available.
+
+Also tested with v4.20130601, same thing happens.
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+All interesting transcripts are posted above with cruft removed.
+
+# End of transcript or log.
+"""]]
+
+> The cause of this bug is using --pathdepth=3 when the url
+> only has two components in its path. So, kinda GIGO, but
+> let's fix this anyway. ;)
+>
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/addurl:___34__rename:_does_not_exist__34___and_reports_fail__44___but_succeeds/comment_1_1f5e0bc93631baf0f8c1bec2e68493c5._comment b/doc/bugs/addurl:___34__rename:_does_not_exist__34___and_reports_fail__44___but_succeeds/comment_1_1f5e0bc93631baf0f8c1bec2e68493c5._comment
new file mode 100644
index 000000000..6ea844f2e
--- /dev/null
+++ b/doc/bugs/addurl:___34__rename:_does_not_exist__34___and_reports_fail__44___but_succeeds/comment_1_1f5e0bc93631baf0f8c1bec2e68493c5._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="http://sunny256.sunbase.org/"
+ nickname="sunny256"
+ subject="comment 1"
+ date="2013-07-08T19:56:58Z"
+ content="""
+Aha, in other words, some kind of PEBCAC put in a polite way. :) I thought this should be correct, as the man page says
+
+> For example, --pathdepth=1 will use \"dir/subdir/bigfile\", while --pathdepth=3 will use \"bigfile\".
+
+This is how I thought it worked:
+
+* 0 = hostname, path, filename
+* 1 = path, filename
+* 2 = filename
+
+After reading your answer I first thought it was a typo in the documentation, but of course the number specify the level of subdirectories to use in the file name. D'oh!
+
+Thanks for the fix and information.
+"""]]
diff --git a/doc/bugs/addurl_--relaxed_with_--file_doesn__39__t_actually_relax.mdwn b/doc/bugs/addurl_--relaxed_with_--file_doesn__39__t_actually_relax.mdwn
new file mode 100644
index 000000000..9118a5041
--- /dev/null
+++ b/doc/bugs/addurl_--relaxed_with_--file_doesn__39__t_actually_relax.mdwn
@@ -0,0 +1,26 @@
+It appears like addurl --relaxed if used incombination with --file doesn't actually relax.
+
+(I'm interested in quickly adding links to an extremely large set of files (and for a large set of revisions), and the fact that addurl takes a second or so per file makes this impossible performance-wise.)
+
+What steps will reproduce the problem? (Well, this isn't the problem per see, but it illustrates that it does checking)
+
+ $ echo foo > foo
+ $ git annex add foo
+ $ git annex addurl --relaxed http://lambda.haskell.org/platform/download/2012.4.0.0/haskell-platform-2012.4.0.0.tar.gz --file foo
+ addurl foo
+ failed to verify url: http://lambda.haskell.org/platform/download/2012.4.0.0/haskell-platform-2012.4.0.0.tar.gz
+ failed
+ git-annex: addurl: 1 failed
+
+What version of git-annex are you using? On what operating system?
+
+Debian Sid
+
+ git-annex version: 4.20130228
+ local repository version: 3
+ default repository version: 3
+ supported repository versions: 3 4
+ upgrade supported from repository versions: 0 1 2
+ build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP DNS
+
+> Missed the case of adding an url to an existing file. [[done]] --[[Joey]]
diff --git a/doc/bugs/addurl_fails_on_the_internet_archive.mdwn b/doc/bugs/addurl_fails_on_the_internet_archive.mdwn
new file mode 100644
index 000000000..556575db6
--- /dev/null
+++ b/doc/bugs/addurl_fails_on_the_internet_archive.mdwn
@@ -0,0 +1,65 @@
+### Please describe the problem.
+
+`addurl` doesn't support the internet archive:
+
+1. it doesn't actually accept the proper URL as a secondary source of content
+2. it doesn't parse the HTML from the video page (the "details page")
+
+### What steps will reproduce the problem?
+
+ # download eben moglen's excellent re:publica presentation from youtube
+ git annex addurl https://www.youtube.com/watch?v=sKOk4Y4inVY
+ # copy that file aside
+ cp -L re_publica_2012___Eben_Moglen___Freedom_of_Thought_Requires_Free_Media.webm re_publica_2012___Eben_Moglen___Freedom_of_Thought_Requires_Free_Media.webm-bak
+ # drop it so we can try again
+ git annex drop re_publica_2012___Eben_Moglen___Freedom_of_Thought_Requires_Free_Media.webm
+ # add the IA URL for the same video, failing
+ git annex addurl --file=re_publica_2012___Eben_Moglen___Freedom_of_Thought_Requires_Free_Media.webm http://ia601009.us.archive.org/9/items/Republica2012-EbenMoglen-FreedomOfThoughtRequiresFreeMedia/re_publica_2012___Eben_Moglen___Freedom_of_Thought_Requires_Free_Media.webm
+ # try again with --relaxed to skip some checks
+ git annex addurl --relaxed --file=re_publica_2012___Eben_Moglen___Freedom_of_Thought_Requires_Free_Media.webm http://ia601009.us.archive.org/9/items/Republica2012-EbenMoglen-FreedomOfThoughtRequiresFreeMedia/re_publica_2012___Eben_Moglen___Freedom_of_Thought_Requires_Free_Media.webm
+ # observe both files are the same size and checksum
+
+The files should look like this:
+
+[[!format txt """
+anarcat@angela:presentations$ ls -alL re_publica_2012___Eben_Moglen___Freedom_of_Thought_Requires_Free_Media.webm*
+-r--r--r-- 1 anarcat anarcat 419359123 oct 9 23:41 re_publica_2012___Eben_Moglen___Freedom_of_Thought_Requires_Free_Media.webm
+-r--r--r-- 1 anarcat anarcat 419359123 oct 11 19:40 re_publica_2012___Eben_Moglen___Freedom_of_Thought_Requires_Free_Media.webm-bak
+anarcat@angela:presentations$ md5sum re_publica_2012___Eben_Moglen___Freedom_of_Thought_Requires_Free_Media.webm*
+7892df24a9e1c40e2587be1035728ef0 re_publica_2012___Eben_Moglen___Freedom_of_Thought_Requires_Free_Media.webm
+7892df24a9e1c40e2587be1035728ef0 re_publica_2012___Eben_Moglen___Freedom_of_Thought_Requires_Free_Media.webm-bak
+"""]]
+
+There are two separate bugs here: one is the above need to use --relaxed even though the file is the same.
+
+The second is probably simply that quvi doesn't support the internet archive, and maybe that one should be moved to a separate [[todo]]/[[wishlist]]. I was expecting this to "do the right thing" (ie. download the video):
+
+ git annex addurl http://archive.org/details/Republica2012-EbenMoglen-FreedomOfThoughtRequiresFreeMedia
+
+... but instead it downloads the HTML.
+### What version of git-annex are you using? On what operating system?
+
+my good old faithful `4.20130921-g434dc22` i compiled manually some time ago. :)
+
+This is [[done]] in git-annex version: 4.20131011-g2c0badc. Thanks!
+
+### Please provide any additional information below.
+
+[[!format sh """
+anarcat@marcos:presentations$ git annex addurl --file=re_publica_2012___Eben_Moglen___Freedom_of_Thought_Requires_Free_Media.webm http://archive.org/download/Republica2012-EbenMoglen-FreedomOfThoughtRequiresFreeMedia/re_publica_2012___Eben_Moglen___Freedom_of_Thought_Requires_Free_Media.webm
+addurl re_publica_2012___Eben_Moglen___Freedom_of_Thought_Requires_Free_Media.webm
+ failed to verify url exists: http://archive.org/download/Republica2012-EbenMoglen-FreedomOfThoughtRequiresFreeMedia/re_publica_2012___Eben_Moglen___Freedom_of_Thought_Requires_Free_Media.webm
+failed
+git-annex: addurl: 1 failed
+anarcat@marcos:presentations$ git annex addurl --debug --file=re_publica_2012___Eben_Moglen___Freedom_of_Thought_Requires_Free_Media.webm http://ia601009.us.archive.org/9/items/Republica2012-EbenMoglen-FreedomOfThoughtRequiresFreeMedia/re_publica_2012___Eben_Moglen___Freedom_of_Thought_Requires_Free_Media.webm
+[2013-10-09 18:26:30 EDT] call: quvi ["-v","mute","--support","http://ia601009.us.archive.org/9/items/Republica2012-EbenMoglen-FreedomOfThoughtRequiresFreeMedia/re_publica_2012___Eben_Moglen___Freedom_of_Thought_Requires_Free_Media.webm"]
+addurl re_publica_2012___Eben_Moglen___Freedom_of_Thought_Requires_Free_Media.webm [2013-10-09 18:26:30 EDT] read: curl ["-s","--head","-L","http://ia601009.us.archive.org/9/items/Republica2012-EbenMoglen-FreedomOfThoughtRequiresFreeMedia/re_publica_2012___Eben_Moglen___Freedom_of_Thought_Requires_Free_Media.webm","-w","%{http_code}"]
+
+ failed to verify url exists: http://ia601009.us.archive.org/9/items/Republica2012-EbenMoglen-FreedomOfThoughtRequiresFreeMedia/re_publica_2012___Eben_Moglen___Freedom_of_Thought_Requires_Free_Media.webm
+failed
+git-annex: addurl: 1 failed
+"""]]
+
+Originally reported in [[tips/Internet_Archive_via_S3]]. --[[anarcat]]
+
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/addurl_fails_on_the_internet_archive/comment_1_e227aa25eea0b41f1176037a601c5844._comment b/doc/bugs/addurl_fails_on_the_internet_archive/comment_1_e227aa25eea0b41f1176037a601c5844._comment
new file mode 100644
index 000000000..4754b8366
--- /dev/null
+++ b/doc/bugs/addurl_fails_on_the_internet_archive/comment_1_e227aa25eea0b41f1176037a601c5844._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.22"
+ subject="comment 1"
+ date="2013-10-11T18:49:25Z"
+ content="""
+Afaik this was fixed in 747f5b123cb3c6b3b87d4e79f8767e69d842b96b.
+
+Probably noone has bothered to add IA support to quvi, but it should be doable.
+"""]]
diff --git a/doc/bugs/addurl_fails_on_the_internet_archive/comment_2_6d4fd58f0caa1f75ee2dd3f0a909cd91._comment b/doc/bugs/addurl_fails_on_the_internet_archive/comment_2_6d4fd58f0caa1f75ee2dd3f0a909cd91._comment
new file mode 100644
index 000000000..f24d0583f
--- /dev/null
+++ b/doc/bugs/addurl_fails_on_the_internet_archive/comment_2_6d4fd58f0caa1f75ee2dd3f0a909cd91._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://id.koumbit.net/anarcat"
+ ip="72.0.72.144"
+ subject="awesome, fix confirmed, and IA+quvi forwarded upstream"
+ date="2013-10-12T11:23:31Z"
+ content="""
+Great! I confirm latest versions work properly.. I have [written the quvi-devel mailing list](http://sourceforge.net/mailarchive/forum.php?thread_name=20131012104904.GA11972%40angela.anarcat.ath.cx&forum_name=quvi-devel) to ask for help for archive.org support, we'll see where it goes...
+"""]]
diff --git a/doc/bugs/addurl_file_doesn__39__t_work_with_spaces_in_filenames_and_--fast.mdwn b/doc/bugs/addurl_file_doesn__39__t_work_with_spaces_in_filenames_and_--fast.mdwn
new file mode 100644
index 000000000..40a310df4
--- /dev/null
+++ b/doc/bugs/addurl_file_doesn__39__t_work_with_spaces_in_filenames_and_--fast.mdwn
@@ -0,0 +1,29 @@
+###What steps will reproduce the problem?
+ $ git annex addurl 'file:///$HOME/space file' --fast
+ addurl _$HOME_space%20file
+ unable to access url: file:///$HOME/space file
+ failed
+ git-annex: addurl: 1 failed
+
+ $ git annex addurl 'file:///home/arand/space\ file' --fast
+ addurl _home_arand_space%5C%20file
+ unable to access url: file:///home/arand/space\ file
+ failed
+ git-annex: addurl: 1 failed
+
+###What is the expected output? What do you see instead?
+
+I guess it's semi-expected to fail since spaces aren't supposed to be in urls, but with file:// it would be nice if that restriction was lessened.
+
+###What version of git-annex are you using? On what operating system?
+
+Debian sid/experimental
+
+ git-annex version: 4.20130227
+ local repository version: 4
+ default repository version: 3
+ supported repository versions: 3 4
+ upgrade supported from repository versions: 0 1 2
+
+> Relaxed url parsing so this will work, and also in http:// urls etc.
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/addurl_file_doesn__39__t_work_with_spaces_in_filenames_and_--fast/comment_1_eea9477ea1157cb88c8a07d8da5f0dba._comment b/doc/bugs/addurl_file_doesn__39__t_work_with_spaces_in_filenames_and_--fast/comment_1_eea9477ea1157cb88c8a07d8da5f0dba._comment
new file mode 100644
index 000000000..6e970322c
--- /dev/null
+++ b/doc/bugs/addurl_file_doesn__39__t_work_with_spaces_in_filenames_and_--fast/comment_1_eea9477ea1157cb88c8a07d8da5f0dba._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://launchpad.net/~arand"
+ nickname="arand"
+ subject="comment 1"
+ date="2013-03-10T21:56:04Z"
+ content="""
+This seems to only occur with the \"--fast\" option.
+
+And the first example above is obviously failing due to '$HOME' as well
+"""]]
diff --git a/doc/bugs/allows_repository_with_the_same_name_twice.mdwn b/doc/bugs/allows_repository_with_the_same_name_twice.mdwn
new file mode 100644
index 000000000..e32bfda61
--- /dev/null
+++ b/doc/bugs/allows_repository_with_the_same_name_twice.mdwn
@@ -0,0 +1,24 @@
+What steps will reproduce the problem?
+
+Unsure. I believe:
+
+* Add a git remote
+* Mark it as dead
+* Remove the git remote, re-add with the same name
+
+What is the expected output? What do you see instead?
+
+When I do a `git annex status` I see:
+
+ 04e701b5-8a22-4391-ad74-d75dde715c7b -- bigserver
+ 6ddfda5d-0f17-45a9-b41a-2a626a823101 -- bigserver
+
+What version of git-annex are you using? On what operating system?
+
+4.20130323 on OSX and Linux
+
+Please provide any additional information below.
+
+Trying to get a file from bigserver kept on failing with the message "Try making some of these repositories available". Which led me on a wild goose chases blaming SSH keys and PATH issues.
+
+> [[done]]; not a bug --[[Joey]]
diff --git a/doc/bugs/allows_repository_with_the_same_name_twice/comment_1_ba7801403e7138684704a3471c8bc4a6._comment b/doc/bugs/allows_repository_with_the_same_name_twice/comment_1_ba7801403e7138684704a3471c8bc4a6._comment
new file mode 100644
index 000000000..d307d4af6
--- /dev/null
+++ b/doc/bugs/allows_repository_with_the_same_name_twice/comment_1_ba7801403e7138684704a3471c8bc4a6._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-04-04T16:10:38Z"
+ content="""
+The \"bigserver\" shown there is not a repository name, it's a repository description. You can change it with `git annex describe 6ddfda5d-0f17-45a9-b41a-2a626a823101 otherbigserver`
+
+git-annex does not use these descriptions in any way, except for to show them to you. It also shows the UUID, so that if you have described two repositories the same way, you can still tell them apart.
+
+I don't see a bug here, unless you can be more specific about a problem.
+"""]]
diff --git a/doc/bugs/allows_repository_with_the_same_name_twice/comment_2_8c19a4ddedbe7ddb8bdcf84acac68cc8._comment b/doc/bugs/allows_repository_with_the_same_name_twice/comment_2_8c19a4ddedbe7ddb8bdcf84acac68cc8._comment
new file mode 100644
index 000000000..4d6905865
--- /dev/null
+++ b/doc/bugs/allows_repository_with_the_same_name_twice/comment_2_8c19a4ddedbe7ddb8bdcf84acac68cc8._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://danieroux.com/"
+ nickname="danie"
+ subject="Having difficulty recreating it"
+ date="2013-04-04T17:53:56Z"
+ content="""
+I got into a situation where:
+
+git annex get myfile.txt
+
+Would complain that I have to \"make bigserver available\" - even though it had a remote called that already.
+
+Will pay closer attention if I get into that corner next time.
+"""]]
diff --git a/doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit.mdwn b/doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit.mdwn
new file mode 100644
index 000000000..e739b9691
--- /dev/null
+++ b/doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit.mdwn
@@ -0,0 +1,28 @@
+### Please describe the problem.
+
+I installed git-annex on my android device (Nook HD+, with Cyanogenmod 10.1 installed) for the first time today and was excited to get it working. However, I noticed the device warming alarmingly, and, after installing a CPU usage monitor, it became clear that git annex was the problem, as it was hovering around 30-40% even when idle.
+
+I tried quitting git-annex using the webapp's "Shutdown Daemon" menu option, and it seemed to shut down successfully, but the CPU monitor still showed that process present and taking up high amounts of CPU (sometimes well over 50%). I used the android app switcher and noticed that the terminal emulator for git annex was still running; I tried to quit this by using the X button and it seemed to close, but the CPU monitor still showed the git-annex process consuming large amounts of CPU. Finally I had to quit the process forcefully from the monitor.
+
+### What steps will reproduce the problem?
+
+Install & run; observe CPU. I used a dedicated CPU monitor to stop it the first time; another time, I tried stopping it by going to Preferences, Apps, Running Applications, where it told me it had one process and one service running. I stopped the service without issue; it said the process could not be safely stopped but I stopped it anyway and that successfully stopped the app.
+
+
+### What version of git-annex are you using? On what operating system?
+
+the current (4.20130826-g46f422) version on Android.
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+(I'm not sure how to get a log out of the web app to paste here unfortunately.
+
+# End of transcript or log.
+"""]]
+
+> [[done]]; I fixed the bug which turned out to be a stupid
+> minunderstanding of how a java library worked. --[[Joey]]
diff --git a/doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_10_1d841ff0b0ffd814efed2449dc1f35f3._comment b/doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_10_1d841ff0b0ffd814efed2449dc1f35f3._comment
new file mode 100644
index 000000000..892894ad4
--- /dev/null
+++ b/doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_10_1d841ff0b0ffd814efed2449dc1f35f3._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 10"
+ date="2013-08-27T01:46:36Z"
+ content="""
+This seems to be a reversion instroduced in commit a48d340abdaf3296a2ddacd73c18adc9a13a02ef. With that backed out, I get 0% cpu usage for the terminal app. Even if I run top in the terminal, its CPU sits under 1%.
+
+Clearly the infinite loop in that patch is running faster than expected!
+"""]]
diff --git a/doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_10_cd101e0af45d8f463011fb0d04b3b822._comment b/doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_10_cd101e0af45d8f463011fb0d04b3b822._comment
new file mode 100644
index 000000000..d8ca9fb05
--- /dev/null
+++ b/doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_10_cd101e0af45d8f463011fb0d04b3b822._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 10"
+ date="2013-08-26T20:19:06Z"
+ content="""
+Yeah, that would definitely explain both what I'm seeing and why you haven't been seeing it.
+
+"""]]
diff --git a/doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_11_8595041cfe703d9bea49e792732dc15f._comment b/doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_11_8595041cfe703d9bea49e792732dc15f._comment
new file mode 100644
index 000000000..085f3d108
--- /dev/null
+++ b/doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_11_8595041cfe703d9bea49e792732dc15f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 11"
+ date="2013-08-27T02:27:08Z"
+ content="""
+Awesome! I'll grab a new nightly in a day or two and give it another shot.
+"""]]
diff --git a/doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_1_8e7bc6965ea967a8d43240791a30c5bc._comment b/doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_1_8e7bc6965ea967a8d43240791a30c5bc._comment
new file mode 100644
index 000000000..756b9d5c6
--- /dev/null
+++ b/doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_1_8e7bc6965ea967a8d43240791a30c5bc._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 1"
+ date="2013-08-26T18:34:44Z"
+ content="""
+Just noticed I was using the autobuild instead of the last release version; I'll try the release version and see if that makes any difference.
+
+"""]]
diff --git a/doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_2_891c1073f908b204651899d41599f944._comment b/doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_2_891c1073f908b204651899d41599f944._comment
new file mode 100644
index 000000000..c26c512ea
--- /dev/null
+++ b/doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_2_891c1073f908b204651899d41599f944._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 2"
+ date="2013-08-26T18:42:02Z"
+ content="""
+If you shut down the daemon, it seems to me that the process that was still running would probably be `git annex transferkey` which runs in its own process to upload/download file contents. I normally see 0% to 1% cpu use from git-annex when it is running on my android tablet. It's possible that the 1% use is due to it waking up every second, which got fixed in 9dc2373977d583b4c4aa6cf0555dc97309f89991.
+"""]]
diff --git a/doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_3_de02b8f1b5928fa1a7078c4aa2124bea._comment b/doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_3_de02b8f1b5928fa1a7078c4aa2124bea._comment
new file mode 100644
index 000000000..71ad88d74
--- /dev/null
+++ b/doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_3_de02b8f1b5928fa1a7078c4aa2124bea._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 3"
+ date="2013-08-26T19:03:45Z"
+ content="""
+OK, so I might have a rogue transferkey process going on, but one which starts over again when I restart the app?
+
+I've set this all up purely as a \"can I do this\" experiment right now; there is literally zero important data there to lose, either on the tablet or on the laptop, so maybe I could just write this off as a bad result of my first few shaky attempts to get the device paired with my laptop, wipe out both annexes, and start completely from scratch.
+
+"""]]
diff --git a/doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_6_506acc4275a81ed9e9b08e8a40fcf96a._comment b/doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_6_506acc4275a81ed9e9b08e8a40fcf96a._comment
new file mode 100644
index 000000000..553a135a0
--- /dev/null
+++ b/doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_6_506acc4275a81ed9e9b08e8a40fcf96a._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 6"
+ date="2013-08-26T19:38:12Z"
+ content="""
+a final note -- according to the process monitor, the process eating CPU is \"ga.androidterm\". There are also a small swarm of about 6 git processes none of which are consuming much CPU time at all.
+
+"""]]
diff --git a/doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_7_d38d6f40db4c9437764c7b2ddf36b5a9._comment b/doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_7_d38d6f40db4c9437764c7b2ddf36b5a9._comment
new file mode 100644
index 000000000..819d31672
--- /dev/null
+++ b/doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_7_d38d6f40db4c9437764c7b2ddf36b5a9._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 7"
+ date="2013-08-26T20:00:39Z"
+ content="""
+It's certainly possible that the terminal app eats cpu for some reason even when sitting idle. It's hard for me to tell since I've been measuring cpu use by running top inside that terminal, which necessarily seems to use a lot of the CPU just to draw the screen.
+
+If it's the terminal at fault, it would continue after you shutdown the git-annex daemon, since that doesn't close the terminal.
+"""]]
diff --git a/doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_8_9bb23e9cbc77ecca4b1209b0f66bc2b0._comment b/doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_8_9bb23e9cbc77ecca4b1209b0f66bc2b0._comment
new file mode 100644
index 000000000..3fce2f21f
--- /dev/null
+++ b/doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_8_9bb23e9cbc77ecca4b1209b0f66bc2b0._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="oh yeah, i can run top in adb.."
+ date="2013-08-26T20:14:13Z"
+ content="""
+So, I can tell that on my tablet, the terminal app is using 82% cpu while idle.
+"""]]
diff --git a/doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_9_d1ce7fc251db076da61eed5bb9d71b9a._comment b/doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_9_d1ce7fc251db076da61eed5bb9d71b9a._comment
new file mode 100644
index 000000000..ffd0a44be
--- /dev/null
+++ b/doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_9_d1ce7fc251db076da61eed5bb9d71b9a._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 9"
+ date="2013-08-26T20:49:34Z"
+ content="""
+(removed my earlier comments with debug info, since it wasn't relevant and I'd just as soon not display my gmail id and home machine's address on the web if I don't need to)
+
+"""]]
diff --git a/doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_9_feb71c1022ff65d82e66a3958a41dfb2._comment b/doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_9_feb71c1022ff65d82e66a3958a41dfb2._comment
new file mode 100644
index 000000000..8f32df035
--- /dev/null
+++ b/doc/bugs/android:_high_CPU_usage__44___unclear_how_to_quit/comment_9_feb71c1022ff65d82e66a3958a41dfb2._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 9"
+ date="2013-08-26T20:16:05Z"
+ content="""
+Strace doesn't show it doing anything. I suppose I should try building the terminal without the several patches I added to it to support git-annex to see if I somehow made it use all this cpu..
+"""]]
diff --git a/doc/bugs/android_4.2.1__44___galaxy_nexus_java.lang.SecurityException.mdwn b/doc/bugs/android_4.2.1__44___galaxy_nexus_java.lang.SecurityException.mdwn
new file mode 100644
index 000000000..e5f1873f0
--- /dev/null
+++ b/doc/bugs/android_4.2.1__44___galaxy_nexus_java.lang.SecurityException.mdwn
@@ -0,0 +1,41 @@
+### Please describe the problem.
+The app fails to open after the install
+
+### What steps will reproduce the problem?
+Downloaded, installed, chose open.
+
+### What version of git-annex are you using? On what operating system?
+today's version. android 4.2.1
+
+### Please provide any additional information below.
+
+I also sent this by email.
+
+Falling back to hardcoded app location; cannot find expected files in /data/app-lib
+git annex webapp
+u0_a72@android:/sdcard/git-annex.home $ git annex webapp
+Launching web browser on http://127.0.0.1:48812/?auth=cf45448c3690730f05f1a9567e62c6a3cf8d25c43ed14362c8ae78601de0e96d32d2b02923ba95962e80c9bd8ffab621918dd582741f18160f6e2565af61aba5
+Starting: Intent { act=android.intent.action.VIEW dat=http://127.0.0.1:48812/?auth=cf45448c3690730f05f1a9567e62c6a3cf8d25c43ed14362c8ae78601de0e96d32d2b02923ba95962e80c9bd8ffab621918dd582741f18160f6e2565af61aba5 }
+java.lang.SecurityException: Permission Denial: startActivity asks to run as user -2 but is calling from user 0; this requires android.permission.INTERACT_ACROSS_USERS_FULL
+ at android.os.Parcel.readException(Parcel.java:1425)
+ at android.os.Parcel.readException(Parcel.java:1379)
+ at android.app.ActivityManagerProxy.startActivityAsUser(ActivityManagerNative.java:1906)
+ at com.android.commands.am.Am.runStart(Am.java:494)
+ at com.android.commands.am.Am.run(Am.java:109)
+ at com.android.commands.am.Am.main(Am.java:82)
+ at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
+ at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:235)
+ at dalvik.system.NativeStart.main(Native Method)
+failed to start web browser
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/debug.log
+
+
+# End of transcript or log.
+"""]]
+
+This is a duplicate of [[Android_app_permission_denial_on_startup]]
+
+[[closing|done]] as dup. --[[Joey]]
diff --git a/doc/bugs/annex-rsync-options_shell-split_carelessly.mdwn b/doc/bugs/annex-rsync-options_shell-split_carelessly.mdwn
new file mode 100644
index 000000000..c8eeb7160
--- /dev/null
+++ b/doc/bugs/annex-rsync-options_shell-split_carelessly.mdwn
@@ -0,0 +1,16 @@
+with rsync, it is sometimes the case that one needs to specify ssh options -- typical examples from the rsync man page are `rsync -e 'ssh -p 2234'`. as git-annex does the shell splitting of the arguments in `annex-rsync-options` (see [[special remotes/rsync]]) itself by looking for whitespace, these options can't be passed directly. (`annex-rsync-options = -e 'ssh -p 2234'` gets split to `["rsync", "-e", "'ssh", "-p", "2234'"]` instead of `["rsync", "-e", "ssh -p 2234"]`).
+
+git-annex should respect shell splitting rules when looking at annex-rsync-options. (i suppose there is a haskell library or module for that; in python, we have the `shlex` module for that).
+
+## workaround
+
+put this in .git/ssh and mark it as executable:
+
+ #!/bin/sh
+ exec ssh -p 2234 $@
+
+put this in your git annex config in the particular remote's section:
+
+ annex-rsync-options = -e /local/path/to/your/repo/.git/ssh
+
+(typical bug report information: observed with git-annex 3.20121127 on debian)
diff --git a/doc/bugs/annex-rsync-options_shell-split_carelessly/comment_1_2636e0d224317f2e6db94658d8a094c4._comment b/doc/bugs/annex-rsync-options_shell-split_carelessly/comment_1_2636e0d224317f2e6db94658d8a094c4._comment
new file mode 100644
index 000000000..42b92ce28
--- /dev/null
+++ b/doc/bugs/annex-rsync-options_shell-split_carelessly/comment_1_2636e0d224317f2e6db94658d8a094c4._comment
@@ -0,0 +1,23 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.117"
+ subject="comment 1"
+ date="2012-12-13T17:03:08Z"
+ content="""
+Due to the way git-annex runs rsync, which involves a specific -e parameter it constructs that, you cannot pass -e in annex-rsync-options anyway; or if you do you'll bypass use of git-annex-shell, which is not desirable. I have not checked which, but would not recommend use of it.
+
+There is no need for ugly workarounds. Just use ~/.ssh/config to configure the hostname to use the nonstandard port it needs. For example:
+
+<pre>
+Host example.com
+Port 2234
+</pre>
+
+Or, to make a separate example.com-2234 host that can be used to use the nonstandard port:
+
+<pre>
+Host example.com-2234
+Hostname example.com
+Port 2234
+</pre>
+"""]]
diff --git a/doc/bugs/annex.numcopies_not_overriden_by_--numcopies_option.mdwn b/doc/bugs/annex.numcopies_not_overriden_by_--numcopies_option.mdwn
new file mode 100644
index 000000000..ba63897ba
--- /dev/null
+++ b/doc/bugs/annex.numcopies_not_overriden_by_--numcopies_option.mdwn
@@ -0,0 +1,16 @@
+### Please describe the problem.
+Using "--numcopies=N" on the command line doesn't overrides (as advertised) the annex.numcopies variable when set via .gitattributes.
+
+### What steps will reproduce the problem?
+
+$ echo '* annex.numcopies=2' > .gitattributes
+
+$ git annex drop --numcopies=1 somefile.txt
+
+Second line fails if only one other copy exists.
+
+### What version of git-annex are you using? On what operating system?
+git-annex version: 4.20130627
+
+> I don't think this was ever handled correctly.
+> I've fixed it now. [[done]] --[[Joey]]
diff --git a/doc/bugs/annex_add_in_annex.mdwn b/doc/bugs/annex_add_in_annex.mdwn
new file mode 100644
index 000000000..e12826f00
--- /dev/null
+++ b/doc/bugs/annex_add_in_annex.mdwn
@@ -0,0 +1,6 @@
+I accidentally annexed some files in the .git-annex directory and it cause git-annex/git to be very unhappy when i pulled the repo to somewhere else. It might be worth teaching git-annex to disallow annex'ing of files inside the .git-annex/.git directories.
+
+> There is a guard against `git annex add .git-annex/foo`, but it doesn't
+> notice `cd .git-annex; git annex add foo`. --[[Joey]]
+
+> Now fixed, by removing the .git-annex directory. [[done]] --[[Joey]]
diff --git a/doc/bugs/annex_get_fails:___34__No_such_file_or_directory__34__.mdwn b/doc/bugs/annex_get_fails:___34__No_such_file_or_directory__34__.mdwn
new file mode 100644
index 000000000..33ac259d9
--- /dev/null
+++ b/doc/bugs/annex_get_fails:___34__No_such_file_or_directory__34__.mdwn
@@ -0,0 +1,68 @@
+**What steps will reproduce the problem?**
+
+I did a basic git annex setup with two repositories talking to each other. They are on the same macine, but I identified them via the hostname, because I intend to set up my production systems on two machines. Since I am new to annex, I'll reproduce the full sequence of commands to create the repos and sync them. *I* noticed the trouble at the last step, when `git annex get` failed.
+
+Here is the full sequence of commands:
+
+ >>> cd /scr/wandschn/hackNtest/distributed/nyc/STU_files
+ >>> git init
+ >>> git annex init nyc
+ >>> cd /scr/wandschn/hackNtest/distributed/pdx
+
+ >>> git clone xerxes:/scr/wandschn/hackNtest/distributed/nyc/STU_files
+ >>> git annex init pdx
+ >>> git remote add nyc xerxes:/scr/wandschn/hackNtest/distributed/nyc/STU_files
+
+ >>> cd /scr/wandschn/hackNtest/distributed/nyc/STU_files
+ >>> git remote add pdx xerxes:/scr/wandschn/hackNtest/distributed/pdx/STU_files
+
+ >>> mkdir shared
+ >>> cp ../../../files/shared/* shared/.
+ >>> git annex add shared
+ >>> git commit -a -m "initial add of shared files"
+
+ >>> cd /scr/wandschn/hackNtest/distributed/pdx/STU_files
+ >>> git fetch nyc
+ >>> git merge nyc/master
+ >>> ls shared/135.mae
+ shared/135.mae
+ >>> git annex whereis shared/135.mae
+ whereis shared/135.mae (1 copy)
+ 6f0368db-f1b1-4192-9200-3575c16c2ef1 -- origin (nyc)
+ ok
+ >>> git annex get shared/135.mae
+ fatal: Could not switch to '../.git/annex/objects/KV/5f/SHA256-s1499628--4a7e2ba13096ee2d1a6b3c3b314efae623516d200c09d35ff0f695395b6ad47a': No such file or directory
+
+ git-annex: <file descriptor: 4>: hGetLine: end of file
+ failed
+ git-annex: get: 1 failed
+
+**What is the expected output? What do you see instead?**
+
+I expected the file shared/135.mae to be copied from the remote repo to the local repo. Instead, this command failed, and said that there was a missing file. This file path is the one that the broken link points to, and it exists on the remote repo.
+
+**What version of git-annex are you using? On what operating system?**
+
+git version 1.7.9.6
+
+git-annex 3.20120523
+
+CentOS 6.3 (kernel 2.6.32)
+
+64bit Xeon processor
+
+
+**Please provide any additional information below.**
+
+> Thanks for the command sequence, which I have tested here is ok with
+> a current version of git-annex (except for one cd you left out..).
+>
+> You version of git-annex is quite old, and this
+> particular bug was fixed in version 3.20120721.
+>
+> The bug is that it fails to correctly determine the git version at
+> compile time, and I think it thinks you have an old version of git
+> from before 1.7.7, which changed some behavior of `git check-attr`.
+>
+> Upgrading git-annex should fix this, please let me know if not. [[done]]
+> --[[Joey]]
diff --git a/doc/bugs/annex_get_over_SSH_is_very_slow.mdwn b/doc/bugs/annex_get_over_SSH_is_very_slow.mdwn
new file mode 100644
index 000000000..215e725e9
--- /dev/null
+++ b/doc/bugs/annex_get_over_SSH_is_very_slow.mdwn
@@ -0,0 +1,33 @@
+### Please describe the problem.
+Attempting to populate one annex from another over an SSH connection is very slow.
+
+### What steps will reproduce the problem?
+1. Create an annex on Linux
+2. Clone annex to Windows system
+3. Set up sshd on Linux system, access keys, etc.
+4. "git annex get ."
+5. Checking if an individual file exists takes a few seconds, and downloading it takes a few seconds. on a 100Mbps LAN, transfers at an average of 7Mbps.
+6. By comparison operating over a working HTTP connection transfers between 20~40 Mbps.
+
+
+### What version of git-annex are you using? On what operating system?
+Windows 7: 4.20140627-g8a36ec5 (from the git-annex download page)
+
+Debian Linux: 3.20120629 (from the package manager)
+
+> The problem is that git-annex is designed to be used with ssh connection
+> caching. However, I have not gotten ssh connection caching to work on
+> Windows. I did try getting this to work with IIRC, cygwin's ssh, but
+> it seems that the Unix sockets it expects to use with `-o ControlMaster`
+> don't work, or it's not been ported to use the Windows equivilant.
+>
+> It's not practical to make git-annex reuse a single ssh connection
+> itself, due to the way rsync is run over ssh.
+>
+> Since this is basically a bug in ssh for Windows, and not in git-annex
+> per se, I am going to close this bug report. However, I do mention
+> this in [[todo/windows_support]].
+>
+> [[done]] --[[Joey]]
+
+[[!meta title="No ssh connection caching support on Windows"]]
diff --git a/doc/bugs/annex_unannex__47__uninit_should_handle_copies.mdwn b/doc/bugs/annex_unannex__47__uninit_should_handle_copies.mdwn
new file mode 100644
index 000000000..e830f1156
--- /dev/null
+++ b/doc/bugs/annex_unannex__47__uninit_should_handle_copies.mdwn
@@ -0,0 +1,20 @@
+Just starting using v3, even more awesome, thanks!
+
+With git-annex, I take the habit to do copies of files without restriction, as they end up into (cheap) symlink copies.
+However, if 2 copies are unannexed, only one is restored, the other becomes a broken symlink, so I kind of loose some information
+(my use case: I have a repo on which I recently started using annex, but most of the files, which i would want to be annexed, are only in git,
+so my plan is to unninit this repo, delete the .git dir, and then annex everything, as I don't mind the history).
+
+Rafaël
+
+> The only way for git-annex to support this in its current state would be
+> for the unannex command to copy the file content from the annex, rather
+> than moving it out. Then multiple links to the same content could be
+> unannexed.
+>
+> But, this would be slower, and would depend on a later `unused` and
+> `dropunused` to actually remove the content. While doable, by use case
+> for unannex is more to quickly undo a mistaken add, and it's unlikely there
+> are multiple symlinks to the same content in this situation. --[[Joey]]
+
+[[!tag done]]
diff --git a/doc/bugs/annex_unannex__47__uninit_should_handle_copies/comment_1_c896ff6589f62178b60e606771e4f2bf._comment b/doc/bugs/annex_unannex__47__uninit_should_handle_copies/comment_1_c896ff6589f62178b60e606771e4f2bf._comment
new file mode 100644
index 000000000..839992477
--- /dev/null
+++ b/doc/bugs/annex_unannex__47__uninit_should_handle_copies/comment_1_c896ff6589f62178b60e606771e4f2bf._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnpdM9F8VbtQ_H5PaPMpGSxPe_d5L1eJ6w"
+ nickname="Rafaël"
+ subject="comment 1"
+ date="2011-07-04T16:57:25Z"
+ content="""
+You convince me for unannex, but isn't the goal of uninit to revert all annex operations? In the current state, a clean revert is not possible (because of the broken symlinks after uninit). Instead of copying, using hard links is out of question?
+
+For my needs, is the command \"git annex unlock .\" (from the root of the repo) a correct workaround?
+"""]]
diff --git a/doc/bugs/annex_unannex__47__uninit_should_handle_copies/comment_2_9249609f83f8e9c7521cd2f007c1a39e._comment b/doc/bugs/annex_unannex__47__uninit_should_handle_copies/comment_2_9249609f83f8e9c7521cd2f007c1a39e._comment
new file mode 100644
index 000000000..21c0c449b
--- /dev/null
+++ b/doc/bugs/annex_unannex__47__uninit_should_handle_copies/comment_2_9249609f83f8e9c7521cd2f007c1a39e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmJfIszzreLNvCqzqzvTayA9_9L6gb9RtY"
+ nickname="Joey"
+ subject="comment 2"
+ date="2011-07-04T20:25:38Z"
+ content="""
+Indeed, uninit needed to be improved. I've done so. Also, unannex --fast can be used to make hard links to content left in the annex.
+"""]]
diff --git a/doc/bugs/another_build_error_in_assistant.mdwn b/doc/bugs/another_build_error_in_assistant.mdwn
new file mode 100644
index 000000000..c21f1ac4e
--- /dev/null
+++ b/doc/bugs/another_build_error_in_assistant.mdwn
@@ -0,0 +1,79 @@
+What steps will reproduce the problem?
+Just trying to install git-annex last release (20121120) from cabal or from bundled sources
+
+What is the expected output? What do you see instead?
+Build stop like this :
+(doing cabal install or build from the bundle)
+...
+[161 of 284] Compiling Assistant.Alert ( Assistant/Alert.hs, dist/build/git-annex/git-annex-tmp/Assistant/Alert.o )
+[162 of 284] Compiling Assistant.Types.DaemonStatus ( Assistant/Types/DaemonStatus.hs, dist/build/git-annex/git-annex-tmp/Assistant/Types/DaemonStatus.o )
+[163 of 284] Compiling Assistant.Monad ( Assistant/Monad.hs, dist/build/git-annex/git-annex-tmp/Assistant/Monad.o )
+
+Assistant/Monad.hs:86:16:
+ Couldn't match expected type `Assistant a'
+ with actual type `Reader AssistantData a'
+ Expected type: (AssistantData -> a) -> Assistant a
+ Actual type: (AssistantData -> a) -> Reader AssistantData a
+ In the expression: reader
+ In an equation for `getAssistant': getAssistant = reader
+
+Assistant/Monad.hs:93:15:
+ Couldn't match expected type `Assistant t0'
+ with actual type `Reader r0 a0'
+ In the return type of a call of `reader'
+ In a stmt of a 'do' block: st <- reader threadState
+ In the expression:
+ do { st <- reader threadState;
+ liftIO $ runThreadState st a }
+
+Assistant/Monad.hs:99:14:
+ Couldn't match expected type `Assistant t0'
+ with actual type `Reader r0 a0'
+ In the return type of a call of `reader'
+ In a stmt of a 'do' block: d <- reader id
+ In the expression:
+ do { d <- reader id;
+ liftIO $ io $ runAssistant d a }
+
+Assistant/Monad.hs:105:14:
+ Couldn't match expected type `Assistant t0'
+ with actual type `Reader r0 a0'
+ In the return type of a call of `reader'
+ In a stmt of a 'do' block: d <- reader id
+ In the expression:
+ do { d <- reader id;
+ return $ runAssistant d a }
+
+Assistant/Monad.hs:110:14:
+ Couldn't match expected type `Assistant t0'
+ with actual type `Reader r0 a0'
+ In the return type of a call of `reader'
+ In a stmt of a 'do' block: d <- reader id
+ In the expression:
+ do { d <- reader id;
+ return $ \ v -> runAssistant d $ a v }
+
+Assistant/Monad.hs:115:14:
+ Couldn't match expected type `Assistant t0'
+ with actual type `Reader r0 a0'
+ In the return type of a call of `reader'
+ In a stmt of a 'do' block: d <- reader id
+ In the expression:
+ do { d <- reader id;
+ return $ \ v1 v2 -> runAssistant d (a v1 v2) }
+
+Assistant/Monad.hs:120:12:
+ Couldn't match expected type `Assistant a0'
+ with actual type `Reader r0 a1'
+ In the return type of a call of `reader'
+ In the first argument of `(>>=)', namely `reader v'
+ In the expression: reader v >>= liftIO . io
+
+
+
+
+What version of git-annex are you using? On what operating system?
+- version 3.20121112
+- Ubuntu 12.04 LTS, 64 bits
+
+> Dup of [[3.20121112_build_fails_on_Ubuntu_12.04]]. --[[Joey]] [[done]]
diff --git a/doc/bugs/archiving_git_repositories.mdwn b/doc/bugs/archiving_git_repositories.mdwn
new file mode 100644
index 000000000..1753c10ae
--- /dev/null
+++ b/doc/bugs/archiving_git_repositories.mdwn
@@ -0,0 +1 @@
+In a true dropbox-like fashion, I tried to import my entire homefolder into the git-annex assistant. However, it seems that git-annex breaks on the several git repositories I've got checked out in my "Projects" folder. Is this a possible use case, or should I look at other tools to perform this with?
diff --git a/doc/bugs/archiving_git_repositories/comment_1_51f546a571303118446a9e0b3e6482c9._comment b/doc/bugs/archiving_git_repositories/comment_1_51f546a571303118446a9e0b3e6482c9._comment
new file mode 100644
index 000000000..cec1398fc
--- /dev/null
+++ b/doc/bugs/archiving_git_repositories/comment_1_51f546a571303118446a9e0b3e6482c9._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.23"
+ subject="comment 1"
+ date="2012-10-19T21:01:44Z"
+ content="""
+The assistant is not ready to manage whole home directories, and the webapp refuses to allow you to do that.
+
+git doesn't allow checking a git repository into a git repository either. I archive old git repos inside one of my annexes by tarring them up.
+"""]]
diff --git a/doc/bugs/assistant_-_GTalk_collision.mdwn b/doc/bugs/assistant_-_GTalk_collision.mdwn
new file mode 100644
index 000000000..b814166ae
--- /dev/null
+++ b/doc/bugs/assistant_-_GTalk_collision.mdwn
@@ -0,0 +1,17 @@
+##What steps will reproduce the problem?
+
+Follow the [share with a friend walkthrough](http://git-annex.branchable.com/assistant/share_with_a_friend_walkthrough/). I use my Google Talk account to pair with myself. With the assistant running, log in to Google Talk on the web interface and set your status 'Invisible'.
+
+##What is the expected output? What do you see instead?
+
+I expect to remain invisible, but I get the following warning: "Oops! You are not invisible because you're logged into Google Talk from another client, device or location that doesn't support invisibility."
+
+##What version of git-annex are you using? On what operating system?
+
+4.20130314 on Linux.
+
+##Please provide any additional information below.
+
+Syncing between the repositories works ok.
+
+[[!tag /design/assistant]]
diff --git a/doc/bugs/assistant_-_GTalk_collision/comment_1_ab2c1f36113d40f27e1893d32f214296._comment b/doc/bugs/assistant_-_GTalk_collision/comment_1_ab2c1f36113d40f27e1893d32f214296._comment
new file mode 100644
index 000000000..4e66052cf
--- /dev/null
+++ b/doc/bugs/assistant_-_GTalk_collision/comment_1_ab2c1f36113d40f27e1893d32f214296._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://smcv.pseudorandom.co.uk/"
+ nickname="smcv"
+ subject="GTalk wants you to implement its &quot;shared status&quot; protocol"
+ date="2013-03-16T11:59:22Z"
+ content="""
+For invisibility to work, GTalk demands that every connected resource implements its \"shared status\" extension. Given that git-annex sets negative priority, this seems like a GTalk bug - it should ignore negative-priority resources when deciding whether it can be invisible - but it seems unlikely to be fixed.
+
+We implement shared status in telepathy-gabble (mostly in src/conn-presence.c, tests in tests/twisted/presence/shared-status.py) if it's any help.
+
+<http://code.google.com/apis/talk/jep_extensions/shared_status.html>
+"""]]
diff --git a/doc/bugs/assistant_-_GTalk_collision/comment_2_91dff34c629a3b3a97a2313ff077e4ae._comment b/doc/bugs/assistant_-_GTalk_collision/comment_2_91dff34c629a3b3a97a2313ff077e4ae._comment
new file mode 100644
index 000000000..1fbbadb05
--- /dev/null
+++ b/doc/bugs/assistant_-_GTalk_collision/comment_2_91dff34c629a3b3a97a2313ff077e4ae._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-03-16T15:39:14Z"
+ content="""
+Thanks for the link, that perhaps explains the continuing oddities I've seen with google talk and presence information sometimes not being sent.
+
+It's not clear to me if git-annex could use this extension at all. It seems to say that if I use it, my regular presence messages won't be sent. Which is a problem, since git-annex uses extended content in presence messages to indicate that they're coming from a git-annex client, which is important to make xmpp pairing work. (It's also used to send push notifications, but that's not essential.)
+
+Also, of course, I'm reluctant to implement a non-standard extension that may change at any time, especially when it's attached to a service that currently has the FSF unhappy <http://www.fsf.org/blogs/sysadmin/google-backslides-on-federated-instant-messaging-on-purpose>.
+
+Perhaps the real solution is to make the assistant encourage use of some other XMPP server.
+"""]]
diff --git a/doc/bugs/assistant_-_GTalk_collision/comment_3_fefb73f6e570f96b4d82779d6622f690._comment b/doc/bugs/assistant_-_GTalk_collision/comment_3_fefb73f6e570f96b4d82779d6622f690._comment
new file mode 100644
index 000000000..35f76bc5f
--- /dev/null
+++ b/doc/bugs/assistant_-_GTalk_collision/comment_3_fefb73f6e570f96b4d82779d6622f690._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-03-16T20:48:42Z"
+ content="""
+I don't know if it will help, but XA support was turned off in hope that it would alleviate the random presence message loss I keep seeing with Google Talk, and since it didn't seem to help solve that problem, I've turned it back on.
+"""]]
diff --git a/doc/bugs/assistant___40__OS_X_Lion__41___-___34__too_many_open_files__34___error.mdwn b/doc/bugs/assistant___40__OS_X_Lion__41___-___34__too_many_open_files__34___error.mdwn
new file mode 100644
index 000000000..1b3879e63
--- /dev/null
+++ b/doc/bugs/assistant___40__OS_X_Lion__41___-___34__too_many_open_files__34___error.mdwn
@@ -0,0 +1,32 @@
+What steps will reproduce the problem?
+
+I downloaded the most recent OS X Lion build of the Git Annex application bundle and ran it.
+
+I wanted to test the direct mode, as my existing annex is in the old style.
+So I set up a new (direct) repository, then added an SSH remote, then dropped a large number of files (170) in there.
+
+
+What is the expected output? What do you see instead?
+
+Expected: the files will be added to the repository in direct mode and stored on the ssh remote.
+Instead: the following error appeared in the webapp:
+
+Committer crashed: /Users/ed/directannex/.git/annex/tmp/: openTempFile: resource exhausted (Too many open files)
+
+nothing seems to have been synced to the remote -- I gather this from the fact that the annex directory in the remote git repo is only 70K instead of several hundred megs.
+
+
+What version of git-annex are you using? On what operating system?
+
+ Version: 3.20130102 on OS X lion, using the version bundled as an application bundle.
+
+
+Please provide any additional information below.
+
+I imagine I could avoid this error by using the "ulimit -n" command to increase number of files in a shell session and then running assistant manually, so this is really only a bug report about the bundled application.
+
+> This seems to be caused by Command.Add.lockdown not closing the
+> temporary file handle, so when called in a mapM by the committer
+> thread when there are a lot of files, it could build up a lot of
+> open handles before later GC closes them. Added a manual close,
+> so I think this is [[done]]. --[[Joey]]
diff --git a/doc/bugs/assistant___40__OS_X_Lion__41___-___34__too_many_open_files__34___error/comment_1_9904c30a4c24a699d71e90ce5e9b89cf._comment b/doc/bugs/assistant___40__OS_X_Lion__41___-___34__too_many_open_files__34___error/comment_1_9904c30a4c24a699d71e90ce5e9b89cf._comment
new file mode 100644
index 000000000..4db7bf9a8
--- /dev/null
+++ b/doc/bugs/assistant___40__OS_X_Lion__41___-___34__too_many_open_files__34___error/comment_1_9904c30a4c24a699d71e90ce5e9b89cf._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="99.54.57.201"
+ subject="comment 1"
+ date="2013-01-05T00:32:44Z"
+ content="""
+After I painstakingly killed off the assistant's processes (I didn't see a way to stop it in the web interface, and issuing \"git annex assistant --stop\" did not stop it), and restarted the assistant, it synced successfully, so the error seems to have been transient.
+"""]]
diff --git a/doc/bugs/assistant_always_assumes_port_22__63__.mdwn b/doc/bugs/assistant_always_assumes_port_22__63__.mdwn
new file mode 100644
index 000000000..27896acd4
--- /dev/null
+++ b/doc/bugs/assistant_always_assumes_port_22__63__.mdwn
@@ -0,0 +1,39 @@
+### Please describe the problem.
+git-annex assistant always assumes port 22 (I use a different port), despite my editing .ssh/config to correct this.
+
+Also, assistant doesn't give me a port option like it did in the intro screencast.
+
+### What steps will reproduce the problem?
+Using my version of git-annex, I assume.
+
+### What version of git-annex are you using? On what operating system?
+git-annex version: 3.20121112ubuntu2
+
+xubuntu 13.04
+
+### Please provide any additional information below.
+I don't see any .git/annex/daemon.log.
+
+I click the "remote server" link, sign in just fine [note below]. I click "Use a git repository on the server" (but "Use an encrypted rsync repository on the server" also does this), and eventually I get an error:
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+Failed to make repository
+
+Something went wrong setting up the repository on the remote server.
+
+Transcript: ssh: connect to host <host> port 22: Connection timed out
+
+# End of transcript or log.
+"""]]
+
+> Your version of git-annex is too old.
+> Support for setting the port was added in version 3.20121211 --
+> about a month after the version you have installed
+> (ah, the period where everything was 11 and 12.. I don't miss it!)
+>
+> I don't recommend using such an old version of the assistant,
+> *massive* numbers of bugs have been fixed since then. Upgrade to
+> the Ubuntu PPA. [[done]] --[[Joey]]
+
+note: if I use "git-annex webapp" in the terminal it works fine; if I use xfce's "internet -> git annex" menu, it errors trying to use ssh_askpass, which I don't have. I'm going to make a new thread about this.
diff --git a/doc/bugs/assistant_bails_when_adding_encrypted_usbdrive_repo_on_mac.mdwn b/doc/bugs/assistant_bails_when_adding_encrypted_usbdrive_repo_on_mac.mdwn
new file mode 100644
index 000000000..23babd797
--- /dev/null
+++ b/doc/bugs/assistant_bails_when_adding_encrypted_usbdrive_repo_on_mac.mdwn
@@ -0,0 +1,53 @@
+### Please describe the problem.
+Tried adding a removable drive repository through git-annex assistant on Mac, asked to encrypt it, got Internal server error with explanation: unable to determine gcrypt-id of remote
+
+### What steps will reproduce the problem?
+current (today's) version of git-annex build for Mountain Lion installed
+app launched
+default annex initialized, a couple file added
+a removable 2GB USB drive (ExFAT) mounted in OS
+click Add another repository
+choose removable drive
+choose to encrypt
+a window explaining the need to wait for entropy shows
+then we get the Internal server error: unable to determine gcrypt-id of remote
+
+### What version of git-annex are you using? On what operating system?
+git-annex version 4.20130922-g7dc188a
+Mac OS X 10.8.5
+
+### Please provide any additional information below.
+
+looking at transcript below, it appears the root cause is the lack of initial git/gcrypt configuration. perhaps this needs to be caught/addressed somehow
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+gpg: can't open `/usr/local/share/gnupg/options.skel': No such file or directory
+.......+++++
+.+++++
+gpg: key 71BFBC31 marked as ultimately trusted
+ok
+(Recording state in git...)
+(Recording state in git...)
+(encryption setup) (hybrid cipher with gpg key C4B2EA8D71BFBC31) gcrypt: Development version -- Repository format MAY CHANGE
+gpg: checking the trustdb
+gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
+gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
+gcrypt: WARNING: Skipping missing key C4B2EA8D71BFBC31
+gcrypt: You have not configured any keys you can encrypt to for this repository
+gcrypt: Use ::
+gcrypt: git config gcrypt.participants YOURKEYID
+gcrypt: Development version -- Repository format MAY CHANGE
+gcrypt: WARNING: Skipping missing key C4B2EA8D71BFBC31
+gcrypt: You have not configured any keys you can encrypt to for this repository
+gcrypt: Use ::
+gcrypt: git config gcrypt.participants YOURKEYID
+03/Oct/2013:00:05:24 +0400 [Error#yesod-core] unable to determine gcrypt-id of remote @(yesod-core-1.1.8.3:Yesod.Internal.Core ./Yesod/Internal/Core.hs:550:5)
+
+
+# End of transcript or log.
+"""]]
+
+[[!tag moreinfo]]
diff --git a/doc/bugs/assistant_bails_when_adding_encrypted_usbdrive_repo_on_mac/comment_1_4ea192e57f86a33087997746722e6acf._comment b/doc/bugs/assistant_bails_when_adding_encrypted_usbdrive_repo_on_mac/comment_1_4ea192e57f86a33087997746722e6acf._comment
new file mode 100644
index 000000000..2d0802cae
--- /dev/null
+++ b/doc/bugs/assistant_bails_when_adding_encrypted_usbdrive_repo_on_mac/comment_1_4ea192e57f86a33087997746722e6acf._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="108.236.230.124"
+ subject="comment 1"
+ date="2013-10-02T20:37:03Z"
+ content="""
+Can you take a look at ~/annex/.git/config and if there is an entry for this git remote, post it? (Or post the whole thing if unsure..)
+
+Also, can you get gpg to list your secret keys, and see if key 71BFBC31 is in the list? You can do so by running `gpg --list-secret-keys` ; if you don't have gpg in your path at the terminal, you can use the version from the git-annex DMG by first running `/Volumes/git-annex/git-annex.app/Contents/MacOS/runshell`
+"""]]
diff --git a/doc/bugs/assistant_bails_when_adding_encrypted_usbdrive_repo_on_mac/comment_2_622ad5b34780fc8468c5c515ad9f27fa._comment b/doc/bugs/assistant_bails_when_adding_encrypted_usbdrive_repo_on_mac/comment_2_622ad5b34780fc8468c5c515ad9f27fa._comment
new file mode 100644
index 000000000..2ba7a5984
--- /dev/null
+++ b/doc/bugs/assistant_bails_when_adding_encrypted_usbdrive_repo_on_mac/comment_2_622ad5b34780fc8468c5c515ad9f27fa._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnyMzZZLS1xGW1raqc_9Md6Ksdkvx5rUJU"
+ nickname="Michael"
+ subject="comment 2"
+ date="2013-10-04T10:59:30Z"
+ content="""
+Sorry Joey, I was tinkering around trying to get the assistant off the ground and have destroyed the evidence of the bug in the process. I will try to recreate it and post the details. (most of my problems are/were related to bundled git/gpg/other software, I posted a separate comment in OSX Install page)
+"""]]
diff --git a/doc/bugs/assistant_cannot_set_up_remote_repo_via_an_ssh_alias_or_an_ip_address/comment_1_1650539846521ae11837e4ac73348af6._comment b/doc/bugs/assistant_cannot_set_up_remote_repo_via_an_ssh_alias_or_an_ip_address/comment_1_1650539846521ae11837e4ac73348af6._comment
new file mode 100644
index 000000000..859810a44
--- /dev/null
+++ b/doc/bugs/assistant_cannot_set_up_remote_repo_via_an_ssh_alias_or_an_ip_address/comment_1_1650539846521ae11837e4ac73348af6._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="99.54.57.201"
+ subject="comment 1"
+ date="2013-01-06T05:23:25Z"
+ content="""
+Fair enough. :) Power user solution to power user whine!
+
+"""]]
diff --git a/doc/bugs/assistant_cannot_set_up_remote_repo_via_an_ssh_alias_or_an_ip_address/comment_2_b91415e4ee74eb12bc6e6faddd00af6e._comment b/doc/bugs/assistant_cannot_set_up_remote_repo_via_an_ssh_alias_or_an_ip_address/comment_2_b91415e4ee74eb12bc6e6faddd00af6e._comment
new file mode 100644
index 000000000..d910e016e
--- /dev/null
+++ b/doc/bugs/assistant_cannot_set_up_remote_repo_via_an_ssh_alias_or_an_ip_address/comment_2_b91415e4ee74eb12bc6e6faddd00af6e._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmcYryijvlF8bJvM_eZNSrUPEkMlxMDGTQ"
+ nickname="Thiago"
+ subject="Also relevant for machines behind pagekite.net"
+ date="2013-02-19T20:00:30Z"
+ content="""
+I'm running into this problem too. I need to use an ssh alias because machines behind pagekite have to be accessed using an HTTP connect proxy, which is done with the ProxyCommand option in the ssh config file. I'm mentioning this because IMHO it's much less of a power user problem than you seem to think.
+
+In fact, I'd argue that a power user is more likely to have access to a machine with a fixed IP address or FQDN. It is people which fall more into the \"mere mortal\" side of the spectrum that need to resort to ssh aliases to access machines behind NAT or dynamic IPs. :-)
+
+All that to say that it would be nice if this usecase was explicitly supported in the UI (maybe a checkbox saying \"this is an ssh alias\", or a textfield to enter a proxy through which the connection has to be routed).
+"""]]
diff --git a/doc/bugs/assistant_does_not_allow_adding_an_existing_repo.mdwn b/doc/bugs/assistant_does_not_allow_adding_an_existing_repo.mdwn
new file mode 100644
index 000000000..8a6218c04
--- /dev/null
+++ b/doc/bugs/assistant_does_not_allow_adding_an_existing_repo.mdwn
@@ -0,0 +1,8 @@
+The assistant does not allow adding an existing repo: I tried to add a "remote server", to enter the credits, and then I add to choose between "git-annex" or "rsync". Choosing "git-annex" tries to create a new repo and then fails. The repo on the server is a bare one, accessed via gitolite. Setting the remote manually ("git remote add origin git@example.org:my-annex.git" works (I can pull, push, ...))
+
+Mac OS 10.7 version 2013-09-10
+
+
+[[!meta title="assistant does not interoperate with gitolite when adding a repository"]]
+
+[2013-09-13 17:00:55 CEST] chat: ssh ["-p","22","git@example.org","sh -c 'mkdir -p '\"'\"'my-annex.git'\"'\"'&&cd '\"'\"'my-annex.git'\"'\"'&&if [ ! -d .git ]; then git init --bare --shared; fi&&git annex init'"]
diff --git a/doc/bugs/assistant_does_not_allow_adding_an_existing_repo/comment_1_87e84d56d56abefe8cac8a52b76c9003._comment b/doc/bugs/assistant_does_not_allow_adding_an_existing_repo/comment_1_87e84d56d56abefe8cac8a52b76c9003._comment
new file mode 100644
index 000000000..b260b8df5
--- /dev/null
+++ b/doc/bugs/assistant_does_not_allow_adding_an_existing_repo/comment_1_87e84d56d56abefe8cac8a52b76c9003._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.2.134"
+ subject="comment 1"
+ date="2013-09-13T18:19:03Z"
+ content="""
+I suppose the assistant could try to add a git remote and pull from it, and only if this pull fails go try to run shell commands to create it. This might work with gitolite, gitosis, github, etc. Although only partially for ones that don't support running git-annex-shell..
+"""]]
diff --git a/doc/bugs/assistant_does_not_always_use_repo_cost_info_when_queueing_downloads.mdwn b/doc/bugs/assistant_does_not_always_use_repo_cost_info_when_queueing_downloads.mdwn
new file mode 100644
index 000000000..c00c3448d
--- /dev/null
+++ b/doc/bugs/assistant_does_not_always_use_repo_cost_info_when_queueing_downloads.mdwn
@@ -0,0 +1,16 @@
+git-annex has nice repository cost tracking, but the assistant doesn't
+always use this when queuing downloads.
+
+For example, if a network comes up, it'll queue a lot of downloads from a
+remote, perhaps expensive server. If a removable drive is then attached,
+which has a lower cost, it'll queue downloads from there, but
+only once it works through all the ones it's already queued from the
+network.
+
+There is a workaround: Since the webapp allows disabling syncing to a
+remote, the user can go in and disable syncing to the network remote
+temporarily.
+
+[[!tag /design/assistant]]
+
+--[[Joey]]
diff --git a/doc/bugs/assistant_does_not_list_remote___39__origin__39__.mdwn b/doc/bugs/assistant_does_not_list_remote___39__origin__39__.mdwn
new file mode 100644
index 000000000..2266c5dc4
--- /dev/null
+++ b/doc/bugs/assistant_does_not_list_remote___39__origin__39__.mdwn
@@ -0,0 +1,26 @@
+What steps will reproduce the problem?
+
+1. create a git annex repo on a server
+2. clone it on workstation
+3. open the webapp on the workstation
+
+
+What is the expected output? What do you see instead?
+
+The webapp should show the 'origin' remote and the assistant should ensure syncing.
+Instead the remote does not show up in the webapp.
+I checked with `git annex status` and the remote is there.
+
+What version of git-annex are you using? On what operating system?
+
+3.20130207 on latest Ubuntu
+
+Please provide any additional information below.
+
+I tried both with direct and indirect mode for the local annex repo.
+
+I am sorry if I am missing the point. I checked the docs, however without much success.
+
+[[!tag /design/assistant]]
+
+[[done]]
diff --git a/doc/bugs/assistant_does_not_list_remote___39__origin__39__/comment_1_ffa008240c61b50396aa92f467731db6._comment b/doc/bugs/assistant_does_not_list_remote___39__origin__39__/comment_1_ffa008240c61b50396aa92f467731db6._comment
new file mode 100644
index 000000000..8f6cb5317
--- /dev/null
+++ b/doc/bugs/assistant_does_not_list_remote___39__origin__39__/comment_1_ffa008240c61b50396aa92f467731db6._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmaMxYm33s0H-nxBo5uzYUzdIECoyR8Ug8"
+ nickname="Stefan"
+ subject="an update"
+ date="2013-02-13T20:33:22Z"
+ content="""
+The remotes were not listed because git-annex-shell was not working (found in the path, however necessary *.so files were not found).
+
+Now all remotes are listed. `.git/config` is ok, with the uuid listed. `git annex status` returns all.
+
+However sync is not working. The webapp on the workstation states that it has synced with the server, however `ls` on the server returns empty. The server is set as archive, the workstation as client.
+"""]]
diff --git a/doc/bugs/assistant_does_not_list_remote___39__origin__39__/comment_2_a53f80090bc2a0f32b8d8307cb24b563._comment b/doc/bugs/assistant_does_not_list_remote___39__origin__39__/comment_2_a53f80090bc2a0f32b8d8307cb24b563._comment
new file mode 100644
index 000000000..5915fd844
--- /dev/null
+++ b/doc/bugs/assistant_does_not_list_remote___39__origin__39__/comment_2_a53f80090bc2a0f32b8d8307cb24b563._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.210"
+ subject="comment 2"
+ date="2013-02-26T19:51:47Z"
+ content="""
+You are probably not running the assistant on the server. This is fine, but it means that git pushes made to the server when files are added to the client are not merged into its working copy. Which is why you don't see the files. Running `git annex sync` on the server should make all the files that have been sent to it show up.
+"""]]
diff --git a/doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add.mdwn b/doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add.mdwn
new file mode 100644
index 000000000..6539dc9e8
--- /dev/null
+++ b/doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add.mdwn
@@ -0,0 +1,46 @@
+What steps will reproduce the problem?
+
+Unable to reproduce as it seems to happen randomly, to very few files (4/250).
+
+What is the expected output? What do you see instead?
+
+I expect to see the assistant warn if it attempts to add a file which fails to add to the annex.
+Instead, I see no output from the assistant, but lines like this in the log.
+
+daemon.log.2:add Indie Game Stand/Deadly 30/Deadly30_MAC.zip (checksum...) failed
+daemon.log.2:add Indie Game Stand/Wyv and Keep/xnafx40_redist.msi (checksum...) failed
+daemon.log.2:add Indie Game Stand/Blueberry Garden/Blueberry_Garden_1.1.zip (checksum...) failed
+daemon.log.2:add Indie Game Stand/Flatspace Bundle/fsmusicpack3setup.exe (checksum...) failed
+
+There is no reason given for the failure in the log file. The assistant also never tries to add them again in normal running (but did add them when it was started again after a reboot).
+
+What version of git-annex are you using? On what operating system?
+
+git-annex version: 4.20130314
+OS: Arch Linux
+
+Please provide any additional information below.
+
+The assistant in this case is being used as nothing more than a way for me to see which files have been added (--verbose, --foreground and --debug with 'watch' outputs nothing..). No remotes or anything like that.
+
+> I have made the assistant re-queue any file that it fails to add,
+> so it will retry it later. Typically within a few seconds. [[done]]
+>
+> I have only been able to think of one scenario in which this could
+> happen. It's pretty unusual:
+>
+> * Something writes to a file, and closes it.
+> * Assistant sees file has no writers, and locks it down in preparation
+> to add it.
+> * Something then re-opens the file to write to it some more.
+> Note that it would seem to need to bypass permissions that prevent
+> the file from being written to in order to do this. It makes a change
+> to the file.
+> * Assistant is checksumming file, reaches end, and detects it has been
+> tampered with and gives up.
+>
+> I would still like more information about circumstances that
+> cause this to happen, because while a possible scenario, the
+> above is too weird to believe anyone could run into it.
+>
+> --[[Joey]]
diff --git a/doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add/comment_1_13b2f93b7d09c8fd6c22829a0dc6428b._comment b/doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add/comment_1_13b2f93b7d09c8fd6c22829a0dc6428b._comment
new file mode 100644
index 000000000..02db48da7
--- /dev/null
+++ b/doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add/comment_1_13b2f93b7d09c8fd6c22829a0dc6428b._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-04-06T16:34:00Z"
+ content="""
+The assistant runs a daily sanity checker job which will clean up files like these. (`git annex watch` does not, however).
+
+I think the main reason add could fail is if a file gets modified while it's in the process of being added. It could retry right away, although it needs to do it in a way that does not loop if the file continually fails to be added.
+"""]]
diff --git a/doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add/comment_2_94e46bc0044b8a91a9fd51058825aa8f._comment b/doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add/comment_2_94e46bc0044b8a91a9fd51058825aa8f._comment
new file mode 100644
index 000000000..a8a5aad9a
--- /dev/null
+++ b/doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add/comment_2_94e46bc0044b8a91a9fd51058825aa8f._comment
@@ -0,0 +1,60 @@
+[[!comment format=mdwn
+ username="Xyem"
+ ip="87.194.19.134"
+ subject="comment 2"
+ date="2013-04-06T21:50:18Z"
+ content="""
+The sanity check never added the failed files:
+
+ daemon.log.2:add Indie Game Stand/Deadly 30/Deadly30_WINDOWS.zip (checksum...) [2013-03-24 20:44:10 GMT] Committer: Committing changes to git
+ daemon.log.2:add Indie Game Stand/Deadly 30/Deadly30_LINUX.zip (checksum...) [2013-03-24 20:44:34 GMT] Committer: Committing changes to git
+ daemon.log.2:add Indie Game Stand/Deadly 30/Deadly30_MAC.zip (checksum...) failed
+ daemon.log.2:add Indie Game Stand/Deadly 30/GonzoSSM_YouTube_Videos.zip (checksum...) [2013-03-24 20:51:05 GMT] Committer: Committing changes to git
+
+ daemon.log.2:[2013-03-25 14:48:01 GMT] SanityCheckerDaily: Running daily sanity check to make sure everything is ok.
+
+ daemon.log.2:add Indie Game Stand/Wyv and Keep/Wyvs_Cartographer.zip (checksum...) [2013-03-25 17:46:19 GMT] Committer: Committing changes to git
+ daemon.log.2:add Indie Game Stand/Wyv and Keep/WnK_Level_Pack.zip (checksum...) [2013-03-25 17:46:20 GMT] Committer: Committing changes to git
+ daemon.log.2:add Indie Game Stand/Wyv and Keep/SmashBox_OST_Mp3.zip (checksum...) [2013-03-25 17:56:37 GMT] Committer: Committing changes to git
+ daemon.log.2:add Indie Game Stand/Wyv and Keep/xnafx40_redist.msi (checksum...) failed
+ daemon.log.2:add Indie Game Stand/Wyv and Keep/WnK091_Win.zip (checksum...) [2013-03-25 18:04:53 GMT] Committer: Committing changes to git
+ daemon.log.2:add Indie Game Stand/Wyv and Keep/wyv_and_keep_OST_MP3.zip (checksum...) [2013-03-25 18:08:20 GMT] Committer: Committing changes to git
+ daemon.log.2:add Indie Game Stand/Wyv and Keep/SmashBox_OST_FLAC.zip (checksum...) [2013-03-25 18:08:43 GMT] Committer: Committing changes to git
+ daemon.log.2:add Indie Game Stand/Wyv and Keep/WnK0907_OSX.zip (checksum...) [2013-03-25 18:10:25 GMT] Committer: Committing changes to git
+ daemon.log.2:add Indie Game Stand/Wyv and Keep/dotNetFx40_Full_x86_x64.exe (checksum...) [2013-03-25 18:10:39 GMT] Committer: Committing changes to git
+ daemon.log.2:add Indie Game Stand/Wyv and Keep/wyv_and_keep_OST_FLAC.zip (checksum...) [2013-03-25 18:45:39 GMT] Committer: Committing changes to git
+ daemon.log.2:add Indie Game Stand/Blueberry Garden/BlueBerryGarden_Sheet_Music.zip (checksum...) [2013-03-25 19:08:04 GMT] Committer: Committing changes to git
+ daemon.log.2:add Indie Game Stand/Blueberry Garden/dotNetFx45_Full_setup.exe (checksum...) [2013-03-25 19:08:18 GMT] Committer: Committing changes to git
+ daemon.log.2:add Indie Game Stand/Blueberry Garden/Eriks_Prototypes.zip (checksum...) [2013-03-25 19:08:25 GMT] Committer: Committing changes to git
+ daemon.log.2:add Indie Game Stand/Blueberry Garden/xnafx40_redist.msi (checksum...) [2013-03-25 19:09:05 GMT] Committer: Committing changes to git
+
+ daemon.log.2:add Indie Game Stand/Blueberry Garden/Blueberry_Garden_1.1.zip (checksum...) failed
+ daemon.log.2:add Indie Game Stand/Blueberry Garden/daduk_Et_Apres.zip (checksum...) [2013-03-25 19:09:53 GMT] Committer: Committing changes to git
+
+ daemon.log.2:add Indie Game Stand/Flatspace Bundle/fsmusicpack3setup.exe (checksum...) failed
+ daemon.log.2:add Indie Game Stand/Flatspace Bundle/flatspaceiifullsetup.exe (checksum...) [2013-03-25 20:45:17 GMT] Committer: Committing changes to git
+ daemon.log.2:add Indie Game Stand/Flatspace Bundle/flatspacefullsetup.exe (checksum...) [2013-03-25 20:45:24 GMT] Committer: Committing changes to git
+
+ daemon.log.2:[2013-03-26 14:48:04 GMT] SanityCheckerDaily: Running daily sanity check to make sure everything is ok.
+ daemon.log.2:[2013-03-27 14:48:08 GMT] SanityCheckerDaily: Running daily sanity check to make sure everything is ok.
+ daemon.log.2:[2013-03-28 14:48:12 GMT] SanityCheckerDaily: Running daily sanity check to make sure everything is ok.
+ daemon.log.2:[2013-03-29 14:48:15 GMT] SanityCheckerDaily: Running daily sanity check to make sure everything is ok.
+ daemon.log.2:[2013-03-30 14:48:18 GMT] SanityCheckerDaily: Running daily sanity check to make sure everything is ok.
+ daemon.log.2:[2013-03-31 15:48:22 BST] SanityCheckerDaily: Running daily sanity check to make sure everything is ok.
+ daemon.log.2:[2013-04-01 15:48:25 BST] SanityCheckerDaily: Running daily sanity check to make sure everything is ok.
+ daemon.log.2:[2013-04-02 15:48:29 BST] SanityCheckerDaily: Running daily sanity check to make sure everything is ok.
+ daemon.log.2:[2013-04-03 15:48:33 BST] SanityCheckerDaily: Running daily sanity check to make sure everything is ok.
+ daemon.log.2:[2013-04-04 15:48:36 BST] SanityCheckerDaily: Running daily sanity check to make sure everything is ok.
+ daemon.log.2:[2013-04-05 15:48:40 BST] SanityCheckerDaily: Running daily sanity check to make sure everything is ok.
+
+ daemon.log.1:add Indie Game Stand/Blueberry Garden/Blueberry_Garden_1.1.zip (checksum...) [2013-04-05 21:21:15 BST] Committer: Adding Deadly30_MAC.zip
+ daemon.log.1:add Indie Game Stand/Deadly 30/Deadly30_MAC.zip (checksum...) [2013-04-05 21:21:16 BST] Committer: Adding fsmusicpa..setup.exe
+ daemon.log.1:add Indie Game Stand/Flatspace Bundle/fsmusicpack3setup.exe (checksum...) [2013-04-05 21:21:16 BST] Committer: Adding xnafx40_redist.msi
+ daemon.log.1:add Indie Game Stand/Wyv and Keep/xnafx40_redist.msi (checksum...) [2013-04-05 21:21:16 BST] Committer: Committing changes to git
+
+I just managed to trigger the issue again. The file has been chmod-ed to 440 but not added to the annex. The log, once again, shows that the checksum failed.
+
+ add CG Cookie/Modeling a Female Human Head/couse_female_head_05.zip (checksum...) failed
+
+The files are being downloaded directly into the directory with the DownThemAll. This downloads the file in a temporary name ending in .dtapart, which is ignored through \".gitignore\". I would have thought that there was nothing stopping the file from being checksummed as git-annex would only see it after the rename, where the file is no longer being written to by anything.
+"""]]
diff --git a/doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add/comment_3_10a38bdbf31dd4071e4bc4ac746d9c56._comment b/doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add/comment_3_10a38bdbf31dd4071e4bc4ac746d9c56._comment
new file mode 100644
index 000000000..3ad62a251
--- /dev/null
+++ b/doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add/comment_3_10a38bdbf31dd4071e4bc4ac746d9c56._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-04-08T17:17:54Z"
+ content="""
+The assistant does not yet support `.gitignore`
+
+Does `git annex add` work on these files?
+
+"""]]
diff --git a/doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add/comment_4_b8fdf502c7e80aece5a9544a2078c85c._comment b/doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add/comment_4_b8fdf502c7e80aece5a9544a2078c85c._comment
new file mode 100644
index 000000000..33b050070
--- /dev/null
+++ b/doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add/comment_4_b8fdf502c7e80aece5a9544a2078c85c._comment
@@ -0,0 +1,36 @@
+[[!comment format=mdwn
+ username="Xyem"
+ ip="87.194.19.134"
+ subject="comment 4"
+ date="2013-04-08T18:25:48Z"
+ content="""
+Interesting that you say .gitignore doesn't work with assistant because.. it definitely does.
+
+ $ git init /tmp/annex-test
+ $ cd /tmp/annex-test
+ $ git annex init
+ $ echo \"file.test\" > .gitignore
+ $ git annex assistant
+ $ echo \"test1\" > file.test
+ $ echo \"test2\" > file2.test
+
+yields this log file:
+
+ (scanning...) [2013-04-08 19:17:03 BST] Watcher: Performing startup scan
+ (started...)
+ [2013-04-08 19:17:10 BST] Committer: Adding file2.test
+ add file2.test (checksum...) [2013-04-08 19:17:10 BST] Committer: Committing changes to git
+ (Recording state in git...)
+ (Recording state in git...)
+ [2013-04-08 19:17:11 BST] Committer: Committing changes to git
+
+git annex find:
+
+ file2.test
+
+On the previous files, the log shows all failed files being added to the annex find after the assistant was restarted (daemon.log.1) so I would imagine 'git annex add' would have worked fine too.
+
+Right now, I'm just running
+ while true; do git annex add; sleep 1; done
+in the annex directory, which gives me (expensive) watch-like behaviour, with fairly clear output for me to confirm everything has been added.
+"""]]
diff --git a/doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add/comment_5_a2ff7668f2a0d549b362d7de97fac8a1._comment b/doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add/comment_5_a2ff7668f2a0d549b362d7de97fac8a1._comment
new file mode 100644
index 000000000..10c068f13
--- /dev/null
+++ b/doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add/comment_5_a2ff7668f2a0d549b362d7de97fac8a1._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 5"
+ date="2013-04-08T21:16:33Z"
+ content="""
+\"I would imagine\" is not a useful debugging method. I asked you to run `git annex add` so that if it succeeds, I have a verified data point that reduces the problem space to only code inside the assistant, and if it fails, I have an easy way to reproduce the problem to debug further. At the moment, I have neither. :P
+
+`.gitignore` is really, truely, not supported by the assistant. I just ran your test case, and it added `file.test` as soon as I created it. Also, I never wrote support for `.gitignore`; I know right where that support should go, and I have a dozen people who have complained it is not supported.
+"""]]
diff --git a/doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add/comment_6_60d72f34a6cfd1c081f74aa610f4305a._comment b/doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add/comment_6_60d72f34a6cfd1c081f74aa610f4305a._comment
new file mode 100644
index 000000000..c8a2730c2
--- /dev/null
+++ b/doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add/comment_6_60d72f34a6cfd1c081f74aa610f4305a._comment
@@ -0,0 +1,33 @@
+[[!comment format=mdwn
+ username="Xyem"
+ ip="87.194.19.134"
+ subject="comment 6"
+ date="2013-04-08T22:06:35Z"
+ content="""
+When you asked me if 'git annex add' worked, I wasn't in the position to test it as I didn't have any files in this failed state. All reported occurrences had been added by the assistant's startup scan on its second running...
+
+I've managed to reproduce the issue again and can confirm 'git annex add'ing the file that failed to checksum through the assistant works successfully. The only difference on this occurrence is that I downloaded the files from a local webserver, sharing the files from my disk as it was taking several gigabytes of download to occur. All other files were added successfully.
+
+daemon.log
+
+ [2013-04-08 22:41:13 BST] Committer: Adding blender_l.eos_04.zip
+ add blender_lowpoly_videos_04.zip (checksum...) failed
+
+git annex add
+
+ $ git annex add blender_lowpoly_videos_04.zip
+ add blender_lowpoly_videos_04.zip (checksum...) ok
+
+In case it matters at all, the workaround I am using below has not demonstrated the issue yet:
+
+ while true; do git annex add; sleep 1; done
+
+Still very interesting that .gitignore is not supposed to work. After running through the test case on my machine:
+Restarting the assistant doesn't add file.test
+'git annex add' doesn't add file.test
+'git annex add file.test' doesn't add file.test
+
+Looks like it works as one would expect from here. Perhaps I'm in some backwards dimension where what should work, doesn't, and what shouldn't work, does! :) Would certainly explain a lot..
+
+Thanks for your help. As you can probably tell, I really want to use git-annex!
+"""]]
diff --git a/doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add/comment_7_53a73e662c9356b759fbfa1e5a3bd927._comment b/doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add/comment_7_53a73e662c9356b759fbfa1e5a3bd927._comment
new file mode 100644
index 000000000..578870f0a
--- /dev/null
+++ b/doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add/comment_7_53a73e662c9356b759fbfa1e5a3bd927._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 7"
+ date="2013-04-23T22:11:32Z"
+ content="""
+I have added some messages when add fails to indicate why it failed. Going through the failure modes while doing this, the most likely reason does seem to be that the file is changed while it's in the process of being checksummed. You can upgrade to tonight's build to get a version with these added messages.
+
+Can you run the assistant with `--debug` and send a complete log of the problem happening?
+
+(The sanity checker not adding the files seems to be a red herring; I was wrong and it only adds any symlinks that failed to get staged.)
+
+(Re the .gitignore red herring, the one place in the assistant that *does* honor .gitignore is the startup scan. However this will not affect the assistant's behavior when files are added to the repository after it's started up and is running. I suspect that if you just look at `git log --stat` you will see that the temp files used by DownThemAll are being added, and then deleted from the git repository. But this is a red herring, so meh.)
+"""]]
diff --git a/doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add/comment_8_10b65168b6a54d960427966d7e3d05f5._comment b/doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add/comment_8_10b65168b6a54d960427966d7e3d05f5._comment
new file mode 100644
index 000000000..2cf9790e9
--- /dev/null
+++ b/doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add/comment_8_10b65168b6a54d960427966d7e3d05f5._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="Xyem"
+ ip="87.194.19.134"
+ subject="comment 8"
+ date="2013-05-12T22:59:37Z"
+ content="""
+Just reproduced this issue on 4.20130417-g4bb97d5. Looks like the digesting is the failing part, but no indication as to why.
+
+ [2013-05-12 23:23:21 BST] Watcher: file deleted test/SleepIsDeath_v16_UnixSource.tar.gz-{b8c941eb-baf0-46de-81fa-19d25aca05fb}.dtapart
+ [2013-05-12 23:23:21 BST] read: git [\"--git-dir=/home/xyem/annex/.git\",\"--work-tree=/home/xyem/annex\",\"ls-files\",\"--others\",\"--exclude-standard\",\"-z\",\"--\",\"test/SleepIsDeath_v16_UnixSource.tar.gz-{b8c941eb-baf0-46de-81fa-19d25aca05fb}.dtapart\",\"test/SleepIsDeath_v16_UnixSource.tar.gz\"]
+ [2013-05-12 23:23:21 BST] read: lsof [\"-F0can\",\"+d\",\"/home/xyem/annex/.git/annex/tmp/\"]
+ [2013-05-12 23:23:22 BST] Committer: Adding SleepIsDe..ce.tar.gz
+ add test/SleepIsDeath_v16_UnixSource.tar.gz (checksum...) [2013-05-12 23:23:22 BST] read: sha256sum [\"/home/xyem/annex/.git/annex/tmp/SleepIsDeath_v16_UnixSource.tar6479.gz\"]
+ failed
+ [2013-05-12 23:23:22 BST] Committer: committing 1 changes
+ [2013-05-12 23:23:22 BST] Committer: Committing changes to git
+ (Recording state in git...)
+
+"""]]
diff --git a/doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add/comment_9_b640e8fa6aafb041d66bbf8857a8fa3d._comment b/doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add/comment_9_b640e8fa6aafb041d66bbf8857a8fa3d._comment
new file mode 100644
index 000000000..738e1929f
--- /dev/null
+++ b/doc/bugs/assistant_does_not_warn_on_files_it_failed_to_add/comment_9_b640e8fa6aafb041d66bbf8857a8fa3d._comment
@@ -0,0 +1,44 @@
+[[!comment format=mdwn
+ username="Xyem"
+ ip="87.194.19.134"
+ subject="comment 9"
+ date="2013-05-12T23:34:51Z"
+ content="""
+Whoops. Upgraded to 4.20130501-g4a5bfb3 and reproduced it again. Looks like the file is being changed between the file being closed and git-annex trying to add it.
+
+Though I'm using DownThemAll, I have it set to \"1 segment\" so the file should only have 1 writer.
+Looks like the file gets retried immediately and is being added okay though.
+
+Would it be worth me trying to log filesystem accesses with a passthrough FUSE filesystem to try and figure out what it going on?
+
+ O'Reilly/Mind Performance Hacks/urn_x-domain_oreilly.com_product_9780596153113.EBOOK-{711cd6ac-12b9-4d4e-92d6-66caa9825cf4}.dtapart still has writers, not adding
+ [2013-05-13 00:18:29 BST] read: git [\"--git-dir=/home/xyem/annex/.git\",\"--work-tree=/home/xyem/annex\",\"ls-tree\",\"-z\",\"--\",\"refs/heads/git-annex\",\"uuid.log\",\"remote.log\",\"trust.log\",\"group.log\",\"preferred-content.log\"]
+ [2013-05-13 00:18:33 BST] Watcher: file deleted O'Reilly/Mind Performance Hacks/urn_x-domain_oreilly.com_product_9780596153113.EBOOK-{711cd6ac-12b9-4d4e-92d6-66caa9825cf4}.dtapart
+ [2013-05-13 00:18:33 BST] read: git [\"--git-dir=/home/xyem/annex/.git\",\"--work-tree=/home/xyem/annex\",\"ls-files\",\"--others\",\"--exclude-standard\",\"-z\",\"--\",\"O'Reilly/Mind Performance Hacks/urn_x-domain_oreilly.com_product_9780596153113.EBOOK-{711cd6ac-12b9-4d4e-92d6-66caa9825cf4}.dtapart\",\"O'Reilly/Mind Performance Hacks/Mind_Performance_Hacks.mobi\"]
+ [2013-05-13 00:18:33 BST] read: lsof [\"-F0can\",\"+d\",\"/home/xyem/annex/.git/annex/tmp/\"]
+ [2013-05-13 00:18:33 BST] Committer: Adding Mind_Perf..acks.mobi
+ add O'Reilly/Mind Performance Hacks/Mind_Performance_Hacks.mobi (checksum...) [2013-05-13 00:18:33 BST] read: sha256sum [\"/home/xyem/annex/.git/annex/tmp/Mind_Performance_Hacks13351.mobi\"]
+
+ O'Reilly/Mind Performance Hacks/Mind_Performance_Hacks.mobi changed while it was being added
+ [2013-05-13 00:18:33 BST] Committer: delaying commit of 1 changes
+ failed
+ [2013-05-13 00:18:33 BST] Committer: committing 1 changes
+ [2013-05-13 00:18:33 BST] Committer: Committing changes to git
+ (Recording state in git...)
+ [2013-05-13 00:18:33 BST] feed: git [\"--git-dir=/home/xyem/annex/.git\",\"--work-tree=/home/xyem/annex\",\"update-index\",\"-z\",\"--index-info\"]
+ [2013-05-13 00:18:33 BST] read: git [\"--git-dir=/home/xyem/annex/.git\",\"--work-tree=/home/xyem/annex\",\"commit\",\"--allow-empty-message\",\"--no-edit\",\"-m\",\"\",\"--quiet\",\"--no-verify\"]
+ [2013-05-13 00:18:33 BST] read: git [\"--git-dir=/home/xyem/annex/.git\",\"--work-tree=/home/xyem/annex\",\"symbolic-ref\",\"HEAD\"]
+ [2013-05-13 00:18:33 BST] read: git [\"--git-dir=/home/xyem/annex/.git\",\"--work-tree=/home/xyem/annex\",\"show-ref\",\"refs/heads/master\"]
+ [2013-05-13 00:18:34 BST] read: git [\"--git-dir=/home/xyem/annex/.git\",\"--work-tree=/home/xyem/annex\",\"ls-files\",\"--others\",\"--exclude-standard\",\"-z\",\"--\",\"O'Reilly/Mind Performance Hacks/Mind_Performance_Hacks.mobi\"]
+ [2013-05-13 00:18:34 BST] read: lsof [\"-F0can\",\"+d\",\"/home/xyem/annex/.git/annex/tmp/\"]
+ [2013-05-13 00:18:34 BST] Committer: Adding Mind_Perf..acks.mobi
+ add O'Reilly/Mind Performance Hacks/Mind_Performance_Hacks.mobi (checksum...) [2013-05-13 00:18:34 BST] read: sha256sum [\"/home/xyem/annex/.git/annex/tmp/Mind_Performance_Hacks13351.mobi\"]
+ [2013ok
+ -05-13 00:18:34 BST] Watcher: file deleted O'Reilly/Mind Performance Hacks/Mind_Performance_Hacks.mobi
+ [2013-05-13 00:18:34 BST] Watcher: add symlink O'Reilly/Mind Performance Hacks/Mind_Performance_Hacks.mobi
+ [2013-05-13 00:18:34 BST] Committer: committing 2 changes
+ [2013-05-13 00:18:34 BST] chat: git [\"--git-dir=/home/xyem/annex/.git\",\"--work-tree=/home/xyem/annex\",\"hash-object\",\"-t\",\"blob\",\"-w\",\"--stdin\"]
+ [2013-05-13 00:18:34 BST] Committer: Committing changes to git
+ (Recording state in git...)
+
+"""]]
diff --git a/doc/bugs/assistant_doesn__39__t_sync_empty_directories.mdwn b/doc/bugs/assistant_doesn__39__t_sync_empty_directories.mdwn
new file mode 100644
index 000000000..0b8b5bc1a
--- /dev/null
+++ b/doc/bugs/assistant_doesn__39__t_sync_empty_directories.mdwn
@@ -0,0 +1,30 @@
+### Please describe the problem.
+
+The assistant seems to only sync files and not directories, so empty directories will not be synced.
+
+### What steps will reproduce the problem?
+
+- Create an empty directory on HostA
+- See that nothing gets synced (daemon.log is silent) and the directory doesn't exist on the other HostB
+- Create an empty file inside the empty directory on HostA
+- See that now HostB has the empty file inside the directory
+
+I'm sure this comes directly from the git behavior but is at least surprising for a direct mode repository using the assistant.
+
+### What version of git-annex are you using? On what operating system?
+
+[[!format sh """
+$ git annex version
+git-annex version: 4.20130516.1
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP
+local repository version: 4
+default repository version: 3
+supported repository versions: 3 4
+upgrade supported from repository versions: 0 1 2
+$ lsb_release -a
+No LSB modules are available.
+Distributor ID: Ubuntu
+Description: Ubuntu 12.04.2 LTS
+Release: 12.04
+Codename: precise
+"""]]
diff --git a/doc/bugs/assistant_doesn__39__t_sync_empty_directories/comment_1_78a3bde607f43c0f518bd2d3d7196022._comment b/doc/bugs/assistant_doesn__39__t_sync_empty_directories/comment_1_78a3bde607f43c0f518bd2d3d7196022._comment
new file mode 100644
index 000000000..b31955ed3
--- /dev/null
+++ b/doc/bugs/assistant_doesn__39__t_sync_empty_directories/comment_1_78a3bde607f43c0f518bd2d3d7196022._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-05-31T21:14:11Z"
+ content="""
+Git does not have a concept of an empty directory. The typical workaround is to put a .gitignore file in the directory.
+"""]]
diff --git a/doc/bugs/assistant_doesn__39__t_sync_empty_directories/comment_2_83777384b72732b1d0a19b32686d3d1f._comment b/doc/bugs/assistant_doesn__39__t_sync_empty_directories/comment_2_83777384b72732b1d0a19b32686d3d1f._comment
new file mode 100644
index 000000000..a62cba1e3
--- /dev/null
+++ b/doc/bugs/assistant_doesn__39__t_sync_empty_directories/comment_2_83777384b72732b1d0a19b32686d3d1f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkx5V3MTbzCXS3J7Mn9FEq8M9bPPYMkAHY"
+ nickname="Pedro"
+ subject="comment 2"
+ date="2013-05-31T21:48:24Z"
+ content="""
+Adding .gitignore files makes sense for a git standpoint but whatever workaround is needed to make the assistant works properly should be done by the assistant itself no? Maybe having direct mode commit a shaddow \".this_is_a_magic_empty_file\" in empty directories and then not actually writing that file into direct mode repositories on the other side.
+"""]]
diff --git a/doc/bugs/assistant_doesn__39__t_sync_empty_directories/comment_3_f9b2a700c060707fae1bcb2ec0e4e4dc._comment b/doc/bugs/assistant_doesn__39__t_sync_empty_directories/comment_3_f9b2a700c060707fae1bcb2ec0e4e4dc._comment
new file mode 100644
index 000000000..757a1c727
--- /dev/null
+++ b/doc/bugs/assistant_doesn__39__t_sync_empty_directories/comment_3_f9b2a700c060707fae1bcb2ec0e4e4dc._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmOsy6nbvPyXLd--qqjPMLnVIzxgZwtKlQ"
+ nickname="Nicolas"
+ subject="comment 3"
+ date="2013-09-11T23:19:26Z"
+ content="""
+This behaviour is indeed very confusing when one attempts to use git-annex with the assistant only, without thinking about the underlying machinery.
+Having the assistant automatically put a .gitignore file in empty directories is a possible solution, but maybe printing a warning in the log when the watcher sees an empty directory could be an unobtrusive and helpful solution? (At least it would have helped me)
+"""]]
diff --git a/doc/bugs/assistant_doesn__39__t_sync_empty_directories/comment_4_014d213a959dd7993bdd247722a8817e._comment b/doc/bugs/assistant_doesn__39__t_sync_empty_directories/comment_4_014d213a959dd7993bdd247722a8817e._comment
new file mode 100644
index 000000000..f6be08ae4
--- /dev/null
+++ b/doc/bugs/assistant_doesn__39__t_sync_empty_directories/comment_4_014d213a959dd7993bdd247722a8817e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmOsy6nbvPyXLd--qqjPMLnVIzxgZwtKlQ"
+ nickname="Nicolas"
+ subject="comment 4"
+ date="2013-09-11T23:24:58Z"
+ content="""
+Another problem with the current behaviour is that when deleting a directory and its contents on a repository, the contents are deleted on the other repositories but empty directories are left behind...
+"""]]
diff --git a/doc/bugs/assistant_doesn__39__t_sync_empty_directories/comment_5_440f349781d7d9ca2d1ed81386f7dd26._comment b/doc/bugs/assistant_doesn__39__t_sync_empty_directories/comment_5_440f349781d7d9ca2d1ed81386f7dd26._comment
new file mode 100644
index 000000000..0d5f0aa29
--- /dev/null
+++ b/doc/bugs/assistant_doesn__39__t_sync_empty_directories/comment_5_440f349781d7d9ca2d1ed81386f7dd26._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmNu4V5fvpLlBhaCUfXXOB0MI5NXwh8SkU"
+ nickname="Adam"
+ subject="comment 5"
+ date="2013-11-01T22:12:04Z"
+ content="""
+I agree that this is very confusing. Also having to manually delete empty, renamed directories is...less than ideal. :)
+"""]]
diff --git a/doc/bugs/assistant_doesn__39__t_sync_file_permissions.mdwn b/doc/bugs/assistant_doesn__39__t_sync_file_permissions.mdwn
new file mode 100644
index 000000000..3acb402bf
--- /dev/null
+++ b/doc/bugs/assistant_doesn__39__t_sync_file_permissions.mdwn
@@ -0,0 +1,45 @@
+### Please describe the problem.
+
+The assistant does not sync file permissions so if you set something as executable it won't be set the same on the other repositories.
+
+### What steps will reproduce the problem?
+
+On the first host:
+
+[[!format sh """
+$ echo -e '#!/bin/sh\necho "Hello World!"' > testscript
+$ chmod ugo+x testscript
+$ ./testscript
+Hello World!
+$ ls -l
+total 4
+-rwxr-xr-x 1 pedrocr pedrocr 30 May 31 20:00 testscript
+"""]]
+
+And on the second host:
+
+[[!format sh """
+$ ls -l
+total 4
+-rw-r--r-- 1 pedrocr pedrocr 30 May 31 20:00 testscript
+$ ./testscript
+bash: ./testscript: Permission denied
+"""]]
+
+### What version of git-annex are you using? On what operating system?
+
+[[!format sh """
+$ git annex version
+git-annex version: 4.20130516.1
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP
+local repository version: 4
+default repository version: 3
+supported repository versions: 3 4
+upgrade supported from repository versions: 0 1 2
+$ lsb_release -a
+No LSB modules are available.
+Distributor ID: Ubuntu
+Description: Ubuntu 12.04.2 LTS
+Release: 12.04
+Codename: precise
+"""]]
diff --git a/doc/bugs/assistant_doesn__39__t_sync_file_permissions/comment_1_fc8d3ea209a2ab39c1aeff52452d4c58._comment b/doc/bugs/assistant_doesn__39__t_sync_file_permissions/comment_1_fc8d3ea209a2ab39c1aeff52452d4c58._comment
new file mode 100644
index 000000000..9e1b801a4
--- /dev/null
+++ b/doc/bugs/assistant_doesn__39__t_sync_file_permissions/comment_1_fc8d3ea209a2ab39c1aeff52452d4c58._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-05-31T21:17:17Z"
+ content="""
+More generally, symbolic links cannot have permissions of their own, and git in fact indicates a file is a symlink by setting the tree object's mode to a specific magic number. So there is no git metadata that git-annex can use to track whether a file is supposed to be executable.
+
+Therefore, this will only get fixed when there's some kind of full-fledged metadata storage for git.
+"""]]
diff --git a/doc/bugs/assistant_doesn__39__t_sync_file_permissions/comment_2_1a364c422e0dd7418f74e1cc3d543a3c._comment b/doc/bugs/assistant_doesn__39__t_sync_file_permissions/comment_2_1a364c422e0dd7418f74e1cc3d543a3c._comment
new file mode 100644
index 000000000..8585e309c
--- /dev/null
+++ b/doc/bugs/assistant_doesn__39__t_sync_file_permissions/comment_2_1a364c422e0dd7418f74e1cc3d543a3c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkx5V3MTbzCXS3J7Mn9FEq8M9bPPYMkAHY"
+ nickname="Pedro"
+ subject="comment 2"
+ date="2013-05-31T21:45:39Z"
+ content="""
+Note that the file I created wasn't a symlink. I assume you mention symlinks because git-annex itself checks in symlinks to git instead of actual files?
+"""]]
diff --git a/doc/bugs/assistant_doesn__39__t_sync_file_permissions/comment_3_4d5ae51b4c7e6177d934d7c9f21b912c._comment b/doc/bugs/assistant_doesn__39__t_sync_file_permissions/comment_3_4d5ae51b4c7e6177d934d7c9f21b912c._comment
new file mode 100644
index 000000000..6bf189414
--- /dev/null
+++ b/doc/bugs/assistant_doesn__39__t_sync_file_permissions/comment_3_4d5ae51b4c7e6177d934d7c9f21b912c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmNu4V5fvpLlBhaCUfXXOB0MI5NXwh8SkU"
+ nickname="Adam"
+ subject="comment 3"
+ date="2013-11-02T23:49:49Z"
+ content="""
+Dropbox handles permissions, e.g. if I \"chmod -x\" a file on one system, it does the same to my other systems. It would be a bit of a step backward if git-annex can't do this. :/ Just my two cents.
+"""]]
diff --git a/doc/bugs/assistant_fails_to_sync_in_preferred_content_mode_manual.mdwn b/doc/bugs/assistant_fails_to_sync_in_preferred_content_mode_manual.mdwn
new file mode 100644
index 000000000..c5a75b361
--- /dev/null
+++ b/doc/bugs/assistant_fails_to_sync_in_preferred_content_mode_manual.mdwn
@@ -0,0 +1,24 @@
+Thanks for git annex!
+
+### Please describe the problem.
+
+I've set up two computers A, B to sync to (and each other through) a remote server S. If I add files to A, it syncs with S. But B is not getting synced unless I run 'git annex sync' or restart the daemon in the webapp, i.e. I don't see these files on B at all, not even as broken symlinks.
+The same happens if I manually copy files from A to S. B is not updating the copy count in 'git annex whereis' until I manually sync on B.
+
+It would be great if B could automatically sync when S is changed, either file locations or contents.
+
+### What steps will reproduce the problem?
+
+Both computers' local repos were setup with annex assistant, and switched into indirect mode. The server contains git repo and file data. All systems, computers and server are set to manual in the preferred content mode.
+
+### What version of git-annex are you using? On what operating system?
+
+A is running Debian testing with git-annex 4.20130827, B and S are running Debian stable with the backports version of git-annex 4.20130815~bpo70+1. A and S are 64 bit, B is 32 bit. All are up to date.
+
+### Please provide any additional information below.
+
+I tried this setup before with direct mode and different preferred content settings (A, B as client, S as backup or archive), and syncing of git and file data was working then.
+
+Despite being able to run 'sync' it is at least inconvenient to not have automatically updated file location information when I run the assistant. (I could then just run without it, but I had it happen to me that I setup a local repo w/o assistant, and when I ran assistant, expecting it would tell me "there are no local repos, would you like to create one?" it somehow automatically found the manually created one and started copying files. But that's another problem.)
+
+> [[done]] unless my diagnosis is wrong. --[[Joey]]
diff --git a/doc/bugs/assistant_fails_to_sync_in_preferred_content_mode_manual/comment_1_37acb3afafb1b4c4da7c778130cf3035._comment b/doc/bugs/assistant_fails_to_sync_in_preferred_content_mode_manual/comment_1_37acb3afafb1b4c4da7c778130cf3035._comment
new file mode 100644
index 000000000..94dc51d0a
--- /dev/null
+++ b/doc/bugs/assistant_fails_to_sync_in_preferred_content_mode_manual/comment_1_37acb3afafb1b4c4da7c778130cf3035._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlQsgfXntaEvZPKgd_K0dfoFcYBJXKcaFE"
+ nickname="Sten"
+ subject="Direct oder indirect mode makes no difference"
+ date="2013-09-09T23:36:49Z"
+ content="""
+Direct or indirect mode does not make a difference. I created another setup like this, only different is direct mode, otherwise the same (in particular preferred content mode is manual). Result: Still no sync.
+"""]]
diff --git a/doc/bugs/assistant_fails_to_sync_in_preferred_content_mode_manual/comment_2_9d58887ee0184663852bde83b8d497c7._comment b/doc/bugs/assistant_fails_to_sync_in_preferred_content_mode_manual/comment_2_9d58887ee0184663852bde83b8d497c7._comment
new file mode 100644
index 000000000..8d388ceee
--- /dev/null
+++ b/doc/bugs/assistant_fails_to_sync_in_preferred_content_mode_manual/comment_2_9d58887ee0184663852bde83b8d497c7._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlQsgfXntaEvZPKgd_K0dfoFcYBJXKcaFE"
+ nickname="Sten"
+ subject="computer in manual mode seems to be the reason, not server"
+ date="2013-09-10T02:21:59Z"
+ content="""
+If I create a setup like originally described with the only difference being S set to full backup mode, I see no change in sync behavior.
+
+In detail, what happens is: A gets files added. These changes are committed and synced. Because S is in full backup mode, the file content is also sent from A to S (this is different, but expected). However, B still does not sync until manually run. I would expect that B's manual mode only applies to file content (it is the preferred content setting), not to changes to the git repo, thus I'd expect git changes to sync to all involved (and accessible) repos.
+"""]]
diff --git a/doc/bugs/assistant_fails_to_sync_in_preferred_content_mode_manual/comment_3_b70881c8026e30fd3ddc051bd01a888b._comment b/doc/bugs/assistant_fails_to_sync_in_preferred_content_mode_manual/comment_3_b70881c8026e30fd3ddc051bd01a888b._comment
new file mode 100644
index 000000000..d42cf6cd2
--- /dev/null
+++ b/doc/bugs/assistant_fails_to_sync_in_preferred_content_mode_manual/comment_3_b70881c8026e30fd3ddc051bd01a888b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlQsgfXntaEvZPKgd_K0dfoFcYBJXKcaFE"
+ nickname="Sten"
+ subject="available copies update need manual sync too"
+ date="2013-09-10T02:55:44Z"
+ content="""
+After copying files from S to B (as expected manually), I have to (unexpectedly) manually sync again on A to update the #copies on A.
+"""]]
diff --git a/doc/bugs/assistant_fails_to_sync_in_preferred_content_mode_manual/comment_4_43f756e2e6ff985c8e050da0e369d486._comment b/doc/bugs/assistant_fails_to_sync_in_preferred_content_mode_manual/comment_4_43f756e2e6ff985c8e050da0e369d486._comment
new file mode 100644
index 000000000..51e9cc135
--- /dev/null
+++ b/doc/bugs/assistant_fails_to_sync_in_preferred_content_mode_manual/comment_4_43f756e2e6ff985c8e050da0e369d486._comment
@@ -0,0 +1,25 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlQsgfXntaEvZPKgd_K0dfoFcYBJXKcaFE"
+ nickname="Sten"
+ subject="output of git annex sync "
+ date="2013-09-10T03:19:51Z"
+ content="""
+When running sync on B after copying file content from A to S (manually or automatically), I saw the following output (copied just the end of it):
+ ...
+ file.pdf | 1 +
+ file.txt | 1 +
+ 762 files changed, 762 insertions(+)
+ ...
+ create mode 120000 file.pdf
+ create mode 120000 file.txt
+
+git-annex: /home/sten/Documents/.git/annex/merge/: getDirectoryContents: does not exist (No such file or directory)
+failed
+push server
+Everything up-to-date
+ok
+git-annex: sync: 1 failed
+
+A subsequent sync worked without error.
+
+"""]]
diff --git a/doc/bugs/assistant_fails_to_sync_in_preferred_content_mode_manual/comment_5_eda947eb7f8c46b9a61d6430b5f9ebfd._comment b/doc/bugs/assistant_fails_to_sync_in_preferred_content_mode_manual/comment_5_eda947eb7f8c46b9a61d6430b5f9ebfd._comment
new file mode 100644
index 000000000..05a3d7f74
--- /dev/null
+++ b/doc/bugs/assistant_fails_to_sync_in_preferred_content_mode_manual/comment_5_eda947eb7f8c46b9a61d6430b5f9ebfd._comment
@@ -0,0 +1,25 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.2.134"
+ subject="comment 5"
+ date="2013-09-13T18:30:53Z"
+ content="""
+You have described the following git-annex network:
+
+ A --(ssh)-- S --(ssh)-- B
+
+So A automatically syncs to S. But there is no way at all for A to tell B that it has made changes. So B does not automatically sync.
+
+The git-annex webapp will detect this kind of situation, and display this alert:
+
+[[assistant/xmppnudge.png]]
+
+Once you set up an XMPP account, the network will look like:
+
+ A --(ssh)-- S --(ssh)-- B
+ \_________(XMPP)_______/
+
+And now B will immediatly know when A has pushed a change to S, and will go get it.
+
+(The `getDirectoryContents` error is probably because you are running git annex sync in a repository that the git-annex assistant is running in, and they are both using the same tmp directory for merging branches sync pulled. It does not seem to be worth worrying about.)
+"""]]
diff --git a/doc/bugs/assistant_hangs_during_commit.mdwn b/doc/bugs/assistant_hangs_during_commit.mdwn
new file mode 100644
index 000000000..12adf281d
--- /dev/null
+++ b/doc/bugs/assistant_hangs_during_commit.mdwn
@@ -0,0 +1,27 @@
+What steps will reproduce the problem?
+
+Use git-annex and add file to repo.
+
+
+What is the expected output? What do you see instead?
+
+File is committed and added to annex.
+
+Instead a command like this is run "git --git-dir=/home/jchu/annex/.git --work-tree=/home/jchu/annex commit --allow-empty-message -m --quiet" and for some reason git decides to open a COMMIT_EDITMSG file in my editor of choice "vim .git/COMMIT_EDITMSG". Since git annex doesn't give me access to the terminal, I don't see it.
+
+Depending on when it happens, the web interface could refuse to start (if the commit hang happens on startup) or if it happens during regular operation, then everything looks fine but the web interface doesn't update after that.
+
+
+What version of git-annex are you using? On what operating system?
+
+git-annex (binary release) 4.20130405
+git 1.8.2.1
+
+On Arch Linux.
+
+
+Please provide any additional information below.
+
+I'm not sure if the git interface has changed, but I do see that --allow-empty-message does still exist. If I run the git commit command (with a '' after the -m), it does indeed start up vim for me. Would we benefit from just making a custom commit message ("Commit from date YYYYMMDDTHHMMSSZ")?
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/assistant_hangs_during_commit/comment_1_aacc15c589d2795254387e427b3afe0c._comment b/doc/bugs/assistant_hangs_during_commit/comment_1_aacc15c589d2795254387e427b3afe0c._comment
new file mode 100644
index 000000000..a2d78d703
--- /dev/null
+++ b/doc/bugs/assistant_hangs_during_commit/comment_1_aacc15c589d2795254387e427b3afe0c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkZktNHFhxC1kYA9KKdKpYJO4clq9WDsjE"
+ nickname="Jason"
+ subject="comment 1"
+ date="2013-04-15T15:58:04Z"
+ content="""
+Or if that solution isn't acceptable, it seems that git commit has a --no-edit option that will guarantee that an editor isn't started.
+"""]]
diff --git a/doc/bugs/assistant_hangs_during_commit/comment_2_b9f1bf9fa919603dca28182c80d39a11._comment b/doc/bugs/assistant_hangs_during_commit/comment_2_b9f1bf9fa919603dca28182c80d39a11._comment
new file mode 100644
index 000000000..4f0a20a02
--- /dev/null
+++ b/doc/bugs/assistant_hangs_during_commit/comment_2_b9f1bf9fa919603dca28182c80d39a11._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-04-16T19:04:34Z"
+ content="""
+Proving a commit message with -m, which git-annex already does, should be enough to prevent git opening an editor. You appear to have some broken version of git there if that is not the case.
+
+I see that you're using Arch. Where exactly did you download git-annex from? Have you tried the standalone tarball?
+"""]]
diff --git a/doc/bugs/assistant_hangs_during_commit/comment_3_fb5be10fcf5e7c89da5c34f48539612f._comment b/doc/bugs/assistant_hangs_during_commit/comment_3_fb5be10fcf5e7c89da5c34f48539612f._comment
new file mode 100644
index 000000000..35377cbcf
--- /dev/null
+++ b/doc/bugs/assistant_hangs_during_commit/comment_3_fb5be10fcf5e7c89da5c34f48539612f._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkZktNHFhxC1kYA9KKdKpYJO4clq9WDsjE"
+ nickname="Jason"
+ subject="comment 3"
+ date="2013-04-17T02:19:02Z"
+ content="""
+I absolutely agree that the -m should stop git from requiring a commit message. I don't know if anything has changed in a newer version, but that's what I'm seeing.
+
+I'm using the git-annex-bin package from the AUR so it's already the standalone binary: https://aur.archlinux.org/packages/git-annex-bin/
+
+As you can see by the PKGBUILD, it just copies the git-annex binary to /usr/bin/git-annex and creates a symlink for git-annex-shell.
+"""]]
diff --git a/doc/bugs/assistant_hangs_during_commit/comment_4_9ba7efe9112578729d02ac4e6557b3cc._comment b/doc/bugs/assistant_hangs_during_commit/comment_4_9ba7efe9112578729d02ac4e6557b3cc._comment
new file mode 100644
index 000000000..6bd85505e
--- /dev/null
+++ b/doc/bugs/assistant_hangs_during_commit/comment_4_9ba7efe9112578729d02ac4e6557b3cc._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 4"
+ date="2013-04-17T05:09:42Z"
+ content="""
+AUR git-annex-bin is a very different thing from the standalone tarball. The tarball carefully puts together a program and a set of libraries and utilities it will work with. The git-annex-bin in AUR yanks that binary out and puts it in an entirely foreign system.
+
+So, try the standalone tarball.
+"""]]
diff --git a/doc/bugs/assistant_hangs_during_commit/comment_5_73b24c901c73d41e0e0abe91267d4920._comment b/doc/bugs/assistant_hangs_during_commit/comment_5_73b24c901c73d41e0e0abe91267d4920._comment
new file mode 100644
index 000000000..4c001c908
--- /dev/null
+++ b/doc/bugs/assistant_hangs_during_commit/comment_5_73b24c901c73d41e0e0abe91267d4920._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkZktNHFhxC1kYA9KKdKpYJO4clq9WDsjE"
+ nickname="Jason"
+ subject="comment 5"
+ date="2013-04-17T16:01:56Z"
+ content="""
+Using the git annex standalone binary has exactly the same action. It seems that the git annex standalone uses the system git instead of the one that's included.
+
+The git command \"git --git-dir=/home/jchu/annex/.git --work-tree=/home/jchu/annex commit --allow-empty-message -m --quiet\" hangs because it's waiting for a commit message \"vim .git/COMMIT_EDITMSG\".
+
+Having not looked too closely at the git source, I think I may have found what happened. The change happened in git 1.8.2 development. a24a41ea9a928ccde2db074ab0835c4817223c9d changed the code to only add \"\n\n\" to a commit message if it's entirely necessary, which means a completely blank commit message looks to the code on line 978 of commit.c \"if (logfile || message.len || use_message || fixup_message)\" as if it were actually empty instead of being considered \"\n\n\".
+
+Since this change only happened in 1.8.2, that's why when you run this code, it doesn't happen (any version before 1.8.2 shouldn't have this regression) but when I run it it does open the commit message editor. The --no-edit option has existed since 1.7.8 (ca1ba201). I don't know if you want to detect this case somehow or what, but I don't know if/when it's going to be fixed in git.
+
+As it stands, the git annex assistant is useless to me because it keeps hanging when trying to commit (the thing that I really wish I could trust it on!).
+"""]]
diff --git a/doc/bugs/assistant_hangs_during_commit/comment_6_1a30b8c82e58222f1366aa368c23e6d3._comment b/doc/bugs/assistant_hangs_during_commit/comment_6_1a30b8c82e58222f1366aa368c23e6d3._comment
new file mode 100644
index 000000000..874d0a938
--- /dev/null
+++ b/doc/bugs/assistant_hangs_during_commit/comment_6_1a30b8c82e58222f1366aa368c23e6d3._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 6"
+ date="2013-04-18T20:30:10Z"
+ content="""
+Thank you for that investigation. Have you confirmed that --no-edit actually fixes it? I've made it pass that parameter.
+
+(BTW, the standalone tarball contains a `runshell` script that you use to set up an environment before running git-annex. This includes putting its bundled version of git before the system one in PATH.)
+"""]]
diff --git a/doc/bugs/assistant_hangs_during_commit/comment_7_56868b2a504ad0a60e8a8c1928330175._comment b/doc/bugs/assistant_hangs_during_commit/comment_7_56868b2a504ad0a60e8a8c1928330175._comment
new file mode 100644
index 000000000..407fbd589
--- /dev/null
+++ b/doc/bugs/assistant_hangs_during_commit/comment_7_56868b2a504ad0a60e8a8c1928330175._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkZktNHFhxC1kYA9KKdKpYJO4clq9WDsjE"
+ nickname="Jason"
+ subject="comment 7"
+ date="2013-04-18T23:22:51Z"
+ content="""
+Yes, in my initial testing, I found that --no-edit fixes the problem.
+"""]]
diff --git a/doc/bugs/assistant_ignore_.gitignore.mdwn b/doc/bugs/assistant_ignore_.gitignore.mdwn
new file mode 100644
index 000000000..63d067e67
--- /dev/null
+++ b/doc/bugs/assistant_ignore_.gitignore.mdwn
@@ -0,0 +1,31 @@
+What steps will reproduce the problem?
+
+1. have an existing directory with a bunch of files
+2. create a `.gitignore` file that matches some files (*.log *.aux *~ etc.)
+3. `git init .`
+4. `git annex init work`
+5. `git remote add server server:Blabla`
+6. `ssh server`
+7. `@server $ mkdir Blabla`
+8. `@server $ cd Blabla`
+9. `@server $ git init .`
+10. `@server $ git annex init server`
+11. `@server $ exit`
+12. `git annex webapp`
+
+What is the expected output? What do you see instead?
+
+I expect that ingored files stay ignored,
+I see instead that all the files (including the ignored) are transfered to the server
+
+What version of git-annex are you using? On what operating system?
+
+3.20130124, debian sid (on both machines)
+
+> As noted in [[design/assistant/inotify]]'s TODO list, this
+> needs an efficient gitignore query interface in git (DNE)
+> or a gitignore parser. --[[Joey]]
+
+[[!tag /design/assistant]]
+
+> [[fixed|done]]; with git 1.8.4 the assistant honors .gitignore --[[Joey]]
diff --git a/doc/bugs/assistant_ignore_.gitignore/comment_1_3458b1342cb2e3ccc01eeedc7f0e48fc._comment b/doc/bugs/assistant_ignore_.gitignore/comment_1_3458b1342cb2e3ccc01eeedc7f0e48fc._comment
new file mode 100644
index 000000000..83cb22ccc
--- /dev/null
+++ b/doc/bugs/assistant_ignore_.gitignore/comment_1_3458b1342cb2e3ccc01eeedc7f0e48fc._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="Johannes"
+ ip="153.109.130.54"
+ subject="comment 1"
+ date="2013-07-30T11:34:15Z"
+ content="""
+Any news on this or this or any other way to exclude unwanted files? (e.g. all the temporary files created by latex)
+"""]]
diff --git a/doc/bugs/assistant_ignore_.gitignore/comment_2_22f75af80c779dcb4d6033b90373f74e._comment b/doc/bugs/assistant_ignore_.gitignore/comment_2_22f75af80c779dcb4d6033b90373f74e._comment
new file mode 100644
index 000000000..893be9055
--- /dev/null
+++ b/doc/bugs/assistant_ignore_.gitignore/comment_2_22f75af80c779dcb4d6033b90373f74e._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnNqLKszWk9EoD4CDCqNXJRIklKFBCN1Ao"
+ nickname="maurizio"
+ subject="git-annex from wheezy-backports should depend on a more recent git version on debian wheezy (7.2) "
+ date="2013-11-12T18:57:52Z"
+ content="""
+It is correct that the bug is solved on the git-annex package found on wheezy-backports, but this package does not force an update of git to a more recent version. Therefore the bug still affects wheezy users. The way to solve it is to install git also from wheezy-backports.
+
+
+"""]]
diff --git a/doc/bugs/assistant_ignore_.gitignore/comment_3_8b2a400e1d44a1c9b183e2b7861efbe3._comment b/doc/bugs/assistant_ignore_.gitignore/comment_3_8b2a400e1d44a1c9b183e2b7861efbe3._comment
new file mode 100644
index 000000000..e58d46084
--- /dev/null
+++ b/doc/bugs/assistant_ignore_.gitignore/comment_3_8b2a400e1d44a1c9b183e2b7861efbe3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.246"
+ subject="comment 3"
+ date="2013-11-12T19:10:48Z"
+ content="""
+Agreed, I've made the changes so the next update of the backport will do so.
+"""]]
diff --git a/doc/bugs/assistant_ignores___34__manual__34___group__44___tries_to_transfer_files.mdwn b/doc/bugs/assistant_ignores___34__manual__34___group__44___tries_to_transfer_files.mdwn
new file mode 100644
index 000000000..910796091
--- /dev/null
+++ b/doc/bugs/assistant_ignores___34__manual__34___group__44___tries_to_transfer_files.mdwn
@@ -0,0 +1,56 @@
+__What steps will reproduce the problem?__
+
+on server:
+
+* mkdir annex
+* cd annex
+* git init
+* git annex init "donkey"
+* git commit -m "CREATE GIT ANNEX" --allow-empty
+
+on desktop:
+
+* git clone ssh://donkey/home/xyem/annex
+* cd annex
+* git annex init "jaguar"
+* git annex vicfg
+(..change origin and 'here' to 'manual' group..)
+* git annex sync
+* git annex webapp
+
+on server:
+
+* git annex sync
+* git annex assistant
+
+(..download/move a file into the annex folder on the desktop..)
+
+__What is the expected output?__
+
+The server should be synced, gaining a broken symlink to the file. No file data transferred to the server (manual mode).
+
+__What do you see instead?__
+
+In addition to the expected/wanted behaviour above, the webapp shows the assistant trying to transfer the file contents to the server, despite it being in the manual group. This is also shown in 'ps aux | grep git' where there is a 'transferkey' operation for the file[1].
+
+__What version of git-annex are you using? On what operating system?__
+
+* server: 4.20130314
+* desktop: 4.20130314
+* OS: Arch Linux
+* Package: git-annex-bin (AUR)
+
+__Please provide any additional information below.__
+
+[1] The transfer itself doesn't work because the assistant is trying to use its own SSH connection caching, with no keys and without prompting for a password, rather than use my existing connection caching. Running the transferkey command manually seems to work though. This isn't a concern at the moment.
+
+Restarting the webapp has not effect. The file is still in the transfer queue and additional files also get added for transfer.
+
+This was working correctly on a previous version, but I'm not sure which one of these I was using at the time:
+
+* 3.20130114
+* 3.20130216
+* 4.20130227
+
+> Closing this bug report since my comment below seems a reasonable
+> explanation for the behavior you saw. [[done]] --[[Joey]]
diff --git a/doc/bugs/assistant_ignores___34__manual__34___group__44___tries_to_transfer_files/comment_1_e3f545d9adc27a4e7340bf16177c4fe0._comment b/doc/bugs/assistant_ignores___34__manual__34___group__44___tries_to_transfer_files/comment_1_e3f545d9adc27a4e7340bf16177c4fe0._comment
new file mode 100644
index 000000000..bad85478e
--- /dev/null
+++ b/doc/bugs/assistant_ignores___34__manual__34___group__44___tries_to_transfer_files/comment_1_e3f545d9adc27a4e7340bf16177c4fe0._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-03-24T12:45:23Z"
+ content="""
+You say you changed `origin` and `here` to be in the manual group, but did you set their preferred-content to `standard`? If you did not, the group setting will not influence which files they want, and the default behavior of wanting all files will be used.
+
+Since you are running the assistant on the server, it will automatically update to have symlinks to new files when the desktop does a git push to it. It sounds like the desktop is failing to push to the server for some reason. You can look at '.git/annex/daemon.log` to see any error messages from `git push`.
+
+If you have `ssh-askpass` installed on the client, it should use it to prompt for any necessary ssh password. Given your described configuration, git-annex will be using your regular ssh keys. You can disable its built-in ssh connection caching with `git config annex.sshcaching false` if desired.
+"""]]
diff --git a/doc/bugs/assistant_ignores___34__manual__34___group__44___tries_to_transfer_files/comment_2_1403076dbc47733607f0c8b2856e2381._comment b/doc/bugs/assistant_ignores___34__manual__34___group__44___tries_to_transfer_files/comment_2_1403076dbc47733607f0c8b2856e2381._comment
new file mode 100644
index 000000000..e30e99eee
--- /dev/null
+++ b/doc/bugs/assistant_ignores___34__manual__34___group__44___tries_to_transfer_files/comment_2_1403076dbc47733607f0c8b2856e2381._comment
@@ -0,0 +1,37 @@
+[[!comment format=mdwn
+ username="Xyem"
+ ip="87.194.19.134"
+ subject="comment 2"
+ date="2013-04-13T20:50:16Z"
+ content="""
+Ah I see. Bit of a misunderstanding on my end about what the groups did, by the looks of it. I was under the impression they controlled how files moved around, if at all (as described in the webapp), and the preferred-content was just fine-tuning controls.
+
+I just went to set this back up to see if setting it to \"standard\" in vicfg works how I want it to and now I've hit a different problem. The webapp/assistant isn't populating the git commit messages on it's own, it is launching $EDITOR (vi if unset on my system) in the background to prompt me for it (where I can't see it).
+
+ ├─xterm
+ │ └─bash
+ │ └─git annex webapp
+ │ └─git-annex webapp
+ │ ├─git --git-dir=/home/xyem/tmp/annex/.git --work-tree=/home/xyem/tmp/annex cat-file --batch
+ │ ├─git --git-dir=/home/xyem/tmp/annex/.git --work-tree=/home/xyem/tmp/annex cat-file --batch
+ │ ├─git --git-dir=/home/xyem/tmp/annex/.git --work-tree=/home/xyem/tmp/annex check-attr -z --stdin annex.backend annex.numcopies --
+ │ ├─git --git-dir=/home/xyem/tmp/annex/.git --work-tree=/home/xyem/tmp/annex commit --allow-empty-message -m --quiet --no-verify
+ │ │ └─nano .git/COMMIT_EDITMSG
+ │ └─6*[{git-annex}]
+
+If I do the steps manually, it seems to work fine:
+
+ $ echo \"testfile\" > testfile.txt
+ $ git annex add testfile.txt
+
+ add testfile.txt (checksum...) ok
+ (Recording state in git...)
+
+ $ git --git-dir=/home/xyem/tmp/annex/.git --work-tree=/home/xyem/tmp/annex commit --allow-empty-message -m --quiet --no-verify
+
+ [master 636605f] --quiet
+ 1 file changed, 1 insertion(+)
+ create mode 120000 testfile.txt
+
+This, to me, implies it is a bug with the assistant/webapp but I don't know how to isolate it any more than that (--debug doesn't output anything else). Should I report this as another bug?
+"""]]
diff --git a/doc/bugs/assistant_ignores___34__manual__34___group__44___tries_to_transfer_files/comment_3_af83717bfb260bea6d52ff71c6b34743._comment b/doc/bugs/assistant_ignores___34__manual__34___group__44___tries_to_transfer_files/comment_3_af83717bfb260bea6d52ff71c6b34743._comment
new file mode 100644
index 000000000..10216b5cc
--- /dev/null
+++ b/doc/bugs/assistant_ignores___34__manual__34___group__44___tries_to_transfer_files/comment_3_af83717bfb260bea6d52ff71c6b34743._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="Xyem"
+ ip="87.194.19.134"
+ subject="comment 3"
+ date="2013-04-13T22:02:09Z"
+ content="""
+Just noticed (while trying to commit in another annex) that the command I used above in the \"manual\" one commits with the message \"--quiet\". I guess pstree doesn't show all arguments!
+"""]]
diff --git a/doc/bugs/assistant_ignores___34__manual__34___group__44___tries_to_transfer_files/comment_4_b4f811611d14e7392009c539fa6b8574._comment b/doc/bugs/assistant_ignores___34__manual__34___group__44___tries_to_transfer_files/comment_4_b4f811611d14e7392009c539fa6b8574._comment
new file mode 100644
index 000000000..6ff6b3c16
--- /dev/null
+++ b/doc/bugs/assistant_ignores___34__manual__34___group__44___tries_to_transfer_files/comment_4_b4f811611d14e7392009c539fa6b8574._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 4"
+ date="2013-04-16T20:28:44Z"
+ content="""
+There's an open bug about this weird commit editor problem. Please follow up there: [[assistant_hangs_during_commit]]
+"""]]
diff --git a/doc/bugs/assistant_listens_on_127.0.0.1_not_::1_which_breaks_IPv6_enabled_hosts.mdwn b/doc/bugs/assistant_listens_on_127.0.0.1_not_::1_which_breaks_IPv6_enabled_hosts.mdwn
new file mode 100644
index 000000000..90034f7f5
--- /dev/null
+++ b/doc/bugs/assistant_listens_on_127.0.0.1_not_::1_which_breaks_IPv6_enabled_hosts.mdwn
@@ -0,0 +1,30 @@
+What steps will reproduce the problem?
+
+Using the Linux tarball (i386) with configured IPv6:
+
+* git-annex.linux/git-annex-webapp
+
+A browser is then started, pointing to file:///tmp/webapp313.html which in turn points to http://localhost:$port/$blah .
+
+On my box localhost resolves to ::1, but the webapp is only listening on 127.0.0.1 so . While I can work around this by specifying 127.0.0.1 as the hostname, the next page that is loaded goes back to localhost.
+
+What is the expected output? What do you see instead?
+
+I would expect that the webapp would bind to ::1 if possible.
+
+What version of git-annex are you using? On what operating system?
+
+3.20130102 fromt the Linux tarball release on Debian Squeeze.
+
+Please provide any additional information below.
+
+I've tested this with:
+
+* epiphany
+* iceweasel
+* chromium
+
+Iceweasel is the only one which correctly fell back to IPv4 and worked.
+
+> Ok, I've made it use the IP address in the URL. Ugly, but avoids
+> whatever mess results in this behavior. [[done]] --[[Joey]]
diff --git a/doc/bugs/assistant_listens_on_127.0.0.1_not_::1_which_breaks_IPv6_enabled_hosts/comment_1_91a62a2ce14a1027d2ac8b8e88df5f0c._comment b/doc/bugs/assistant_listens_on_127.0.0.1_not_::1_which_breaks_IPv6_enabled_hosts/comment_1_91a62a2ce14a1027d2ac8b8e88df5f0c._comment
new file mode 100644
index 000000000..540e06ee3
--- /dev/null
+++ b/doc/bugs/assistant_listens_on_127.0.0.1_not_::1_which_breaks_IPv6_enabled_hosts/comment_1_91a62a2ce14a1027d2ac8b8e88df5f0c._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.1.42"
+ subject="comment 1"
+ date="2013-01-09T23:21:58Z"
+ content="""
+I have a ipv6 enabled computer here, where the webapp works fine. I think you must have something odd in your network configuration if web browsers, when sent to \"http://localhost:port/ don't manage to connect to a web server running on ipv4.
+
+The webapp only uses 127.0.0.1 if \"localhost\" resolves to that address. If \"localhost\" resolves to both ipv6 and ipv4 addresses, the webapp uses the ipv4 and not the ipv6 address. If \"localhost\" resolves to only ipv6, the webapp uses ipv6.
+
+AFAIK it's not possible to bind to both an ipv4 and an ipv6 address, and get the same port number for both, and the webapp needs a port number to use to launch the web browser. Therefore, it has to choose one address. It choses ipv4 in preference to ipv6 because there are some things that still don't support ipv6. [This commit](http://source.git-annex.branchable.com/?p=source.git;a=commit;h=467844d7d3f703f99fcde1f951f33efda5e90074) is relevant.
+"""]]
diff --git a/doc/bugs/assistant_listens_on_127.0.0.1_not_::1_which_breaks_IPv6_enabled_hosts/comment_2_4982cd373eaaeee180be03c6e9fda7b1._comment b/doc/bugs/assistant_listens_on_127.0.0.1_not_::1_which_breaks_IPv6_enabled_hosts/comment_2_4982cd373eaaeee180be03c6e9fda7b1._comment
new file mode 100644
index 000000000..849bde6e4
--- /dev/null
+++ b/doc/bugs/assistant_listens_on_127.0.0.1_not_::1_which_breaks_IPv6_enabled_hosts/comment_2_4982cd373eaaeee180be03c6e9fda7b1._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkF8_uQjLYm5Mf5F_JuVW-BxlvzpWjvR_o"
+ nickname="Andrew"
+ subject="comment 2"
+ date="2013-01-09T23:51:18Z"
+ content="""
+Watching tcpdump on loopback I only see a request from Epiphany to ::1, after that it gives up. So not terribly helpful.
+
+It looks like it might be a bug in the browsers. :(
+"""]]
diff --git a/doc/bugs/assistant_listens_on_127.0.0.1_not_::1_which_breaks_IPv6_enabled_hosts/comment_3_85d264e311acaa91dac0597ee8deda82._comment b/doc/bugs/assistant_listens_on_127.0.0.1_not_::1_which_breaks_IPv6_enabled_hosts/comment_3_85d264e311acaa91dac0597ee8deda82._comment
new file mode 100644
index 000000000..91da74efc
--- /dev/null
+++ b/doc/bugs/assistant_listens_on_127.0.0.1_not_::1_which_breaks_IPv6_enabled_hosts/comment_3_85d264e311acaa91dac0597ee8deda82._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkF8_uQjLYm5Mf5F_JuVW-BxlvzpWjvR_o"
+ nickname="Andrew"
+ subject="comment 3"
+ date="2013-01-10T22:10:00Z"
+ content="""
+Cool, thanks Joey. Let's hope we can remove the ugly hack one day. ;)
+"""]]
diff --git a/doc/bugs/assistant_not_noticing_file_renames__44___not_fixing_files.mdwn b/doc/bugs/assistant_not_noticing_file_renames__44___not_fixing_files.mdwn
new file mode 100644
index 000000000..d009b55cd
--- /dev/null
+++ b/doc/bugs/assistant_not_noticing_file_renames__44___not_fixing_files.mdwn
@@ -0,0 +1,68 @@
+What steps will reproduce the problem?
+
+In one terminal, I created a new annex and started the assistant watching it.
+
+In another, I added a file file1; assistant noticed it and added it to the annex.
+
+I moved file1 to a directory directory1; the link broke and assistant did not fix it.
+
+I created a file called file2 inside directory 2; assistant noticed it and added it to the annex.
+
+I moved file2 back up to the annex root directory; the link broke and assistant did not fix it.
+
+I created a file file3 in the annex root directory; assistant noticed it and added it to the annex.
+
+Here is the content of the first terminal, where I created the annex and ran assistant:
+
+
+ ~$ mkdir testannex
+ ~$ cd testannex/
+ testannex$ git init .
+ Initialized empty Git repository in /Users/ed/testannex/.git/
+ testannex$ git annex init "test annex"
+ init test annex ok
+ (Recording state in git...)
+ testannex$ git annex assistant --foreground
+ assistant . (scanning...) (started...) add file1 (checksum...) ok
+ (Recording state in git...)
+ (Recording state in git...)
+ add directory1/file2 (checksum...) ok
+ (Recording state in git...)
+ (Recording state in git...)
+ add file3 (checksum...)
+
+here is the content of the second terminal, where I created and moved files:
+
+ ~$ cd testannex
+ testannex$ echo "file1 content" > file1
+ testannex$ mkdir directory1
+ testannex$ ls -l file1
+ lrwxr-xr-x 1 ed staff 180 Dec 13 15:40 file1 -> .git/annex/objects/FX/51/SHA256E-s14--edac79763e630b1b77aefb6c284bcb0362dea71c0548be0e793ffa8fd5907b80/SHA256E-s14--edac79763e630b1b77aefb6c284bcb0362dea71c0548be0e793ffa8fd5907b80
+ testannex$ mv file1 directory1/
+ testannex$ cd directory1/
+ directory1$ cat file1
+ cat: file1: No such file or directory
+ directory1$ echo "file2 content" > file2
+ directory1$ cat file2
+ file2 content
+ directory1$ cat file1
+ cat: file1: No such file or directory
+ directory1$ mv file2 ../
+ directory1$ cd ..
+ testannex$ echo "file3 content" > file3
+ testannex$
+
+
+What is the expected output? What do you see instead?
+
+The links do not break when moved to another directory.
+
+What version of git-annex are you using? On what operating system?
+
+One compiled using cabal from checkout 739c937
+
+Please provide any additional information below.
+
+> [[fixed|done]]; this turned out to be an kqueue specific bug,
+> the kqueue code statted new files, but that files for a broken symlink.
+> Using lstat instead fixed this. --[[Joey]]
diff --git a/doc/bugs/assistant_not_noticing_file_renames__44___not_fixing_files/comment_1_e0dafc410ffd617d445bb9403c7bfafe._comment b/doc/bugs/assistant_not_noticing_file_renames__44___not_fixing_files/comment_1_e0dafc410ffd617d445bb9403c7bfafe._comment
new file mode 100644
index 000000000..fef95243b
--- /dev/null
+++ b/doc/bugs/assistant_not_noticing_file_renames__44___not_fixing_files/comment_1_e0dafc410ffd617d445bb9403c7bfafe._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 1"
+ date="2012-12-13T20:50:18Z"
+ content="""
+(Operating system is OS X Lion)
+
+"""]]
diff --git a/doc/bugs/assistant_not_noticing_file_renames__44___not_fixing_files/comment_2_2af247c8a1fcbde10795a990ef3303e9._comment b/doc/bugs/assistant_not_noticing_file_renames__44___not_fixing_files/comment_2_2af247c8a1fcbde10795a990ef3303e9._comment
new file mode 100644
index 000000000..6d93d7e61
--- /dev/null
+++ b/doc/bugs/assistant_not_noticing_file_renames__44___not_fixing_files/comment_2_2af247c8a1fcbde10795a990ef3303e9._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 2"
+ date="2012-12-15T05:47:25Z"
+ content="""
+thanks, fix worked for me! Now the links are fixed virtually instantaneously when the file is moved.
+
+"""]]
diff --git a/doc/bugs/assistant_syncs_with_remotes_even_when_all_remotes_disabled.mdwn b/doc/bugs/assistant_syncs_with_remotes_even_when_all_remotes_disabled.mdwn
new file mode 100644
index 000000000..959620ba6
--- /dev/null
+++ b/doc/bugs/assistant_syncs_with_remotes_even_when_all_remotes_disabled.mdwn
@@ -0,0 +1,33 @@
+### Please describe the problem.
+
+I migrated a repo I set up by hand on my Android phone to use the assistant and webapp. That repo has two remotes, both full git-annex repos over SSH. I still want to control when I synchronize (cellular data is precious), so the vast majority of the time I disable syncing on both remotes. However, when I return to the webapp after it's been running for "a while," it shows a status message indicating it has synced with the remotes.
+
+It looks like it might be related to the NetWatcherFallback, because a NetWatcherFallback entry appears in the log approximately every hour, followed by the usual repo sync output.
+
+### What steps will reproduce the problem?
+
+1. Set up a repo with a git-annex over SSH remote, and set annex-sync on that remote to false.
+2. Run the webapp.
+3. Observe after a period of time that the webapp shows that the repo has been synced.
+
+### What version of git-annex are you using? On what operating system?
+
+git-annex 20130709 on Android (4.2)
+
+### Please provide any additional information below.
+
+[[!format sh """
+[2013-07-22 22:50:31 MST] NetWatcherFallback: Syncing with sigsegv, sigusr1
+Everything up-to-date
+Everything up-to-date
+[2013-07-22 23:52:57 MST] NetWatcherFallback: Syncing with sigsegv, sigusr1
+Everything up-to-date
+Everything up-to-date
+[2013-07-23 00:54:15 MST] NetWatcherFallback: Syncing with sigsegv, sigusr1
+Everything up-to-date
+Everything up-to-date
+"""]]
+
+> Excellent bug report! Especially useful that you tracked it
+> down to the NetWatcher. Indeed it was not honoring the
+> annex-sync setting. [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/assistant_wants_my_gpg_passphrase_when_it_has_nothing_to_drop_or_copy_to_that_remote.mdwn b/doc/bugs/assistant_wants_my_gpg_passphrase_when_it_has_nothing_to_drop_or_copy_to_that_remote.mdwn
new file mode 100644
index 000000000..657a4dd3d
--- /dev/null
+++ b/doc/bugs/assistant_wants_my_gpg_passphrase_when_it_has_nothing_to_drop_or_copy_to_that_remote.mdwn
@@ -0,0 +1,5 @@
+I am running 3.20121112 and this bug appeared when I upgraded to that from 3.20121017.
+
+After performing the startup scan after I login, git-annex gets GPG to sends me a pinentry pop-up asking for my GPG passphrase. However, I know that there is nothing to be dropped or copied to the encrypted SSH remote that I am being asked to provide access to. So I can't see any good reason why I would be asked for the passphrase.
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/assistant_wants_my_gpg_passphrase_when_it_has_nothing_to_drop_or_copy_to_that_remote/comment_1_10a9570a5d762ba2da271b38dc63edb6._comment b/doc/bugs/assistant_wants_my_gpg_passphrase_when_it_has_nothing_to_drop_or_copy_to_that_remote/comment_1_10a9570a5d762ba2da271b38dc63edb6._comment
new file mode 100644
index 000000000..548db2386
--- /dev/null
+++ b/doc/bugs/assistant_wants_my_gpg_passphrase_when_it_has_nothing_to_drop_or_copy_to_that_remote/comment_1_10a9570a5d762ba2da271b38dc63edb6._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.49"
+ subject="comment 1"
+ date="2012-11-29T20:13:53Z"
+ content="""
+Hmm, is this an encrypted rsync remote?
+
+I have not been able to reproduce the problem so fat.
+
+If you start the assistant with --debug, and look in .git/annex/daemon.log, you should find where it runs gpg, and the lines showing what it's doing just before/after that should provide a hint what it's doing.
+"""]]
diff --git a/doc/bugs/assistant_wants_my_gpg_passphrase_when_it_has_nothing_to_drop_or_copy_to_that_remote/comment_2_57d50955b038c2e2405068536c7e83f3._comment b/doc/bugs/assistant_wants_my_gpg_passphrase_when_it_has_nothing_to_drop_or_copy_to_that_remote/comment_2_57d50955b038c2e2405068536c7e83f3._comment
new file mode 100644
index 000000000..ce57194c9
--- /dev/null
+++ b/doc/bugs/assistant_wants_my_gpg_passphrase_when_it_has_nothing_to_drop_or_copy_to_that_remote/comment_2_57d50955b038c2e2405068536c7e83f3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="spwhitton"
+ ip="163.1.167.50"
+ subject="comment 2"
+ date="2012-12-01T18:34:10Z"
+ content="""
+Thanks for the log advice. I looked and it wants to drop a file `ttmik/TTMIK-Lesson-L1L1.mp3` from the encrypted rsync remote ma. So I did `git annex whereis ttmik/TTMIK-Lesson-L1L1.mp3` and learnt that the file is not on ma. I tried `git annex drop --from ma ttmik` to be sure, and the command was successful, but it still tries to drop the file from ma on startup. Presumably it would try all the other files in the ttmik directory if I gave it the chance to try to drop this first one. The only thing special about the ttmik directory is that every file in there was added using addurl, so I guess the problem has something to do with that.
+"""]]
diff --git a/doc/bugs/assistant_wants_my_gpg_passphrase_when_it_has_nothing_to_drop_or_copy_to_that_remote/comment_3_a66f34daaba421c87eb404ef933e5191._comment b/doc/bugs/assistant_wants_my_gpg_passphrase_when_it_has_nothing_to_drop_or_copy_to_that_remote/comment_3_a66f34daaba421c87eb404ef933e5191._comment
new file mode 100644
index 000000000..9bfade666
--- /dev/null
+++ b/doc/bugs/assistant_wants_my_gpg_passphrase_when_it_has_nothing_to_drop_or_copy_to_that_remote/comment_3_a66f34daaba421c87eb404ef933e5191._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.49"
+ subject="comment 3"
+ date="2012-12-01T18:59:45Z"
+ content="""
+How is this rsync remote configured? Is it configured as a transfer remote? If not, the assistant's default behavior is to sync all files to it, and since you say the file is not there, it'd make sense it would start transferring it to there on startup.
+
+OTOH, this could be a complete red herring. You haven't shown me the log file. Perhaps the drop you're seeing in the log is before the operation that is asking for the GPG passphrase. I can't tell until you show me the log.
+"""]]
diff --git a/doc/bugs/assistant_wants_my_gpg_passphrase_when_it_has_nothing_to_drop_or_copy_to_that_remote/comment_4_094a3272eca1c6d2b4d264911ffe96e5._comment b/doc/bugs/assistant_wants_my_gpg_passphrase_when_it_has_nothing_to_drop_or_copy_to_that_remote/comment_4_094a3272eca1c6d2b4d264911ffe96e5._comment
new file mode 100644
index 000000000..8f9f54610
--- /dev/null
+++ b/doc/bugs/assistant_wants_my_gpg_passphrase_when_it_has_nothing_to_drop_or_copy_to_that_remote/comment_4_094a3272eca1c6d2b4d264911ffe96e5._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="spwhitton"
+ ip="163.1.167.50"
+ subject="comment 4"
+ date="2012-12-02T18:27:09Z"
+ content="""
+The rsync remote is in the archive group but it has the preferred content string `exclude=video/* and exclude=ttmik/*`. So it ought to be dropping the files, but not over and over again.
+
+Here is the log file, showing me hitting Escape on the pinentry dialog:
+
+ (scanning...) Already up-to-date.
+ Already up-to-date.
+ Already up-to-date.
+ drop ma ttmik/TTMIK-Lesson-L1L1.mp3 (gpg) gpg: cancelled by user
+ gpg: decryption failed: secret key not available
+ TransferScanner crashed: user error (gpg [\"--batch\",\"--no-tty\",\"--use-agent\",\"--
+ quiet\",\"--trust-model\",\"always\",\"--decrypt\"] exited 2)
+ (started...)
+"""]]
diff --git a/doc/bugs/assistant_wants_my_gpg_passphrase_when_it_has_nothing_to_drop_or_copy_to_that_remote/comment_5_0161410d042a3421addd4a1fc7c1cd01._comment b/doc/bugs/assistant_wants_my_gpg_passphrase_when_it_has_nothing_to_drop_or_copy_to_that_remote/comment_5_0161410d042a3421addd4a1fc7c1cd01._comment
new file mode 100644
index 000000000..89ef87c2a
--- /dev/null
+++ b/doc/bugs/assistant_wants_my_gpg_passphrase_when_it_has_nothing_to_drop_or_copy_to_that_remote/comment_5_0161410d042a3421addd4a1fc7c1cd01._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.72"
+ subject="comment 5"
+ date="2012-12-05T16:34:24Z"
+ content="""
+Aha, I see the bug now. It is indeed trying to drop from every remote, even ones without the data.
+
+(Also, the thread should not crash here if the drop fails.. I've fixed that.)
+"""]]
diff --git a/doc/bugs/authentication_to_rsync.net_fails.mdwn b/doc/bugs/authentication_to_rsync.net_fails.mdwn
new file mode 100644
index 000000000..707f93d49
--- /dev/null
+++ b/doc/bugs/authentication_to_rsync.net_fails.mdwn
@@ -0,0 +1,30 @@
+### Please describe the problem.
+
+Used assistant to "Add a cloud repository". Supplied hostname, username in webapp. Directory "annex" port 22.
+Clicked on "Use this rsync.net repository" and got
+
+**********************
+ssh_askpass: exec(/usr/bin/ssh-askpass): No such file or directory
+ssh_askpass: exec(/usr/bin/ssh-askpass): No such file or directory
+ssh_askpass: exec(/usr/bin/ssh-askpass): No such file or directory
+Received disconnect from 69.43.165.7: 2: Too many authentication failures for 2440
+**********************
+
+### What steps will reproduce the problem?
+See above? A simple "ssh user@host.rsync.net ls /usr/bin" reveals that indeed no ssh-askpass is available in that namespace.
+
+### What version of git-annex are you using? On what operating system?
+git-annex version: 4.20130521 on debian linux 7.1.
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+That log is empty.
+# End of transcript or log.
+"""]]
+
+> I added ssh-askpass as a recommends, so I suppose
+> I can close this. [[done]] --[[Joey]]
diff --git a/doc/bugs/authentication_to_rsync.net_fails/comment_1_9db65f89415c8d825f268afb75244998._comment b/doc/bugs/authentication_to_rsync.net_fails/comment_1_9db65f89415c8d825f268afb75244998._comment
new file mode 100644
index 000000000..731d5148f
--- /dev/null
+++ b/doc/bugs/authentication_to_rsync.net_fails/comment_1_9db65f89415c8d825f268afb75244998._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawliqfHEW134uawIUPwyKiyOdoF-oI5TxnQ"
+ nickname="Ethan"
+ subject="Doh. /usr/bin/ssh-askpass needs to be on *local* machine."
+ date="2013-08-15T20:13:31Z"
+ content="""
+My mistake; the problem was the I was missing /usr/bin/ssh-askpass on my local machine, not the rsync.net host.
+
+I still think this is a bug. I'm on a debian machine and installed git-annex from its debian package, so seems like the ssh-askpass package should be listed as a dependency. But that's a debian packaging problem, not a git-annex bug per se, so I'll go file it elsewhere.
+"""]]
diff --git a/doc/bugs/backend_version_upgrade_leaves_repo_unusable.mdwn b/doc/bugs/backend_version_upgrade_leaves_repo_unusable.mdwn
new file mode 100644
index 000000000..122224a8f
--- /dev/null
+++ b/doc/bugs/backend_version_upgrade_leaves_repo_unusable.mdwn
@@ -0,0 +1,72 @@
+foo is a local repo, bar is a bare remote.
+
+I upgraded foo's git-annex to 0.20110325 and upgraded a local repo backend
+to version 2. I then ran `git annex copy . --to bar` and checked the
+remote. This created WORM:SHA512--123123 files in annex/objects.
+Understandable but unwanted. So I upgraded git-annex on bar's machine, as
+well.
+
+ % git annex copy . --to bar
+ copy quux (checking bar) git-annex-shell: Repository version 1 is not supported. Upgrade this repository: git-annex upgrade (to bar)
+ git-annex-shell: Repository version 1 is not supported. Upgrade this repository: git-annex upgrade
+ rsync: connection unexpectedly closed (0 bytes received so far) [sender]
+ rsync error: error in rsync protocol data stream (code 12) at io.c(601) [sender=3.0.7]
+
+ rsync failed -- run git annex again to resume file transfer
+ failed
+
+Running `git annex upgrade` on bar's machine I get:
+
+ % git annex upgrade
+ upgrade (v1 to v2) (moving content...) git-annex: Prelude.read: no parse
+
+Again, bar is a bare repo.
+Running the copy job again, I am still getting the same error as above (as expected). Partial contents of annex/objects on bar:
+
+ [...]
+ SHA512:123
+ WORM:SHA512--234
+ [...]
+
+
+-- RichiH
+
+> Upgrading bare repos to v2 generally works fine, so I actually need
+> to see the full content of annex/, not a fragment, in order to debug this.
+> (Filename contents I don't need to see.) Feel free to email me the details at
+> joey@kitenet.net if you don't want to post them here. --[[Joey]]
+
+>> Sent. -- RichiH
+
+>>> Ok, I'm going to go work on my reading comprehension. I see now
+>>> that you
+>>> explained the problem pretty well. The problem is caused by these
+>>> few weird v1 mixed with v2 keys in the annex.
+>>> Ones like "annex/objects/WORM:SHA512--$sha512".
+>>>
+>>> That's a v1 key, but a corrupt form of the key; it's missing the
+>>> size and mtime fields that all WORM keys have in v1. And
+>>> the filename is itself a key, a v2 SHA512 key. These were
+>>> created when you did the `git annex copy to the v1 bare repo.
+>>> In v2, git-annex-shell takes a full key object, while in v1,
+>>> it takes a key name and a backend name. This incompatability
+>>> leads to the weird behavior seen.
+>>>
+>>> I had suggested you delete data.. don't. On second thought,
+>>> you shouldn't delete anything. I'll simply make the v2 upgrade
+>>> detect and work around this bug.
+>>> --[[Joey]]
+
+>>>> This should be fixed in current git. The scambled keys will be
+>>>> fixed up on upgrade. Thanks for your patience! [[done]] --[[Joey]]
+
+>>>>> I should stop reading your answers via git; by the time I got to
+>>>>> "second thoughts", I had already deleted the files & directories
+>>>>> in question, upgraded the bare repo and was busy uploading from my
+>>>>> local repo. I agree that taking care of this in the upgrade code
+>>>>> is the cleanest approach, by the way.
+>>>>> No need to thank me for my patience; thank you for your quickness!
+>>>>> RichiH
+>>>>>
+>>>>> PS: If I get a handle on the mtime issue in the SHA backend, git
+>>>>> annex will be pretty much perfect :)
diff --git a/doc/bugs/bad_behaviour_with_file_names_with_newline_in_them.mdwn b/doc/bugs/bad_behaviour_with_file_names_with_newline_in_them.mdwn
new file mode 100644
index 000000000..530a8da5d
--- /dev/null
+++ b/doc/bugs/bad_behaviour_with_file_names_with_newline_in_them.mdwn
@@ -0,0 +1,5 @@
+Found this out the hard way. See the comment in the below post for what happens.
+
+[[/forum/git_annex_add_crash_and_subsequent_recovery/]]
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/bad_behaviour_with_file_names_with_newline_in_them/comment_1_92dfe6e9089c79eb64e2177fb135ef55._comment b/doc/bugs/bad_behaviour_with_file_names_with_newline_in_them/comment_1_92dfe6e9089c79eb64e2177fb135ef55._comment
new file mode 100644
index 000000000..7ff8f8e3d
--- /dev/null
+++ b/doc/bugs/bad_behaviour_with_file_names_with_newline_in_them/comment_1_92dfe6e9089c79eb64e2177fb135ef55._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-12-06T16:49:32Z"
+ content="""
+This only happens with the WORM backend (or possibly with SHA1E if the file's extension has a newline).
+
+The problem is not the newline in the file, but the newline in the key generated for the file. It's probably best to just disallow such keys being created.
+"""]]
diff --git a/doc/bugs/bad_comment_in_ssh_public_key_ssh-rsa.mdwn b/doc/bugs/bad_comment_in_ssh_public_key_ssh-rsa.mdwn
new file mode 100644
index 000000000..87e937d42
--- /dev/null
+++ b/doc/bugs/bad_comment_in_ssh_public_key_ssh-rsa.mdwn
@@ -0,0 +1,22 @@
+What steps will reproduce the problem?
+I was trying to pair two repositories on 2 different computers,
+but my public key had this email address at the end:
+bachir@Bachirs-iMac.local
+
+What is the expected output? What do you see instead?
+I was expecting successful pairing.
+I got:
+bad comment in ssh public key ssh-rsa
+AAB3....SAK
+bachir@Bachirs-iMac.local
+
+What version of git-annex are you using? On what operating system?
+I am using the package git-annex Version: 3.20120925
+on MacOSX Lion
+
+Please provide any additional information below.
+I've checked your code, seems to complain about the dash '-' in the email address
+bachir@Bachirs-iMac.local
+
+> This bug is already fixed, the fix is in the
+> 3.20121001 release. [[done]] --[[Joey]]
diff --git a/doc/bugs/bad_comment_in_ssh_public_key_ssh-rsa/comment_1_15cce6e6f455e83f4362a38c561bc973._comment b/doc/bugs/bad_comment_in_ssh_public_key_ssh-rsa/comment_1_15cce6e6f455e83f4362a38c561bc973._comment
new file mode 100644
index 000000000..5f2dcca85
--- /dev/null
+++ b/doc/bugs/bad_comment_in_ssh_public_key_ssh-rsa/comment_1_15cce6e6f455e83f4362a38c561bc973._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="https://lorrin.myopenid.com/"
+ nickname="Lorrin Nelson"
+ subject="Still seeing this"
+ date="2013-07-29T07:44:36Z"
+ content="""
+Trying to pair Ubuntu 13.04 (git-annex 3.20121112ubuntu4) with OS X 10.7.5 (not sure where to see version info, but it was marked 2013-07-23 on the download page).
+
+If the pairing is initiated on OS X and the Ubuntu machine tries to connect, the Ubuntu browser shows:
+Internal Server Error
+
+bad comment in ssh public key ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCr0uArI+Yfusf+jICdv2tSCVQdydtoUuQixBHUGj2QlUlip4zf94HnCBBlSUhMuWBeaGUAAojp05Y3PaxQNS95bX1wWlhraQBx/8w23M68Q1L5Je60PWYha1dLREApJjl5eGxuTIXUip8UcDXIH/esB7G/lMihTjniEBqS430NxrfO01uU9HuNgQfO9zvTcJhjG+myek1GU2bx8GzYc7HAZ8VA3TsYKLaWA63w8WyFC/Hz+kunp9X8dNE11KpmNFVSk/j1QGImUOVcnGd2WupMyjLtRAKL3ikL6tBK2YccZUKPSNYek657CFR8uVek5czzQQCY5bFRAH3Pw9htsPgv user@host.fqdn
+
+Where user@host.fqdn is the user and DNS locally-resolvable host name of the Mac. However, this isn't a key I recognize. Is it generating a new one on the fly? There already are key pairs set up between the machines in my ~/.ssh directory; not sure if relevant.
+
+
+"""]]
diff --git a/doc/bugs/bad_comment_in_ssh_public_key_ssh-rsa/comment_2_e9e1f38880a32610b3fbce475bffc3e4._comment b/doc/bugs/bad_comment_in_ssh_public_key_ssh-rsa/comment_2_e9e1f38880a32610b3fbce475bffc3e4._comment
new file mode 100644
index 000000000..6028f49ed
--- /dev/null
+++ b/doc/bugs/bad_comment_in_ssh_public_key_ssh-rsa/comment_2_e9e1f38880a32610b3fbce475bffc3e4._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.21"
+ subject="comment 2"
+ date="2013-07-30T18:16:06Z"
+ content="""
+Local pairing always sets up a dedicated ssh key that can only be used for git-annex syncing.
+
+I'm afraid that, unless your login is literally \"user@host.fqdn\", you've obfuscated exactly the information I'd need to diagnose the problem. If you don't feel comfortable including the real information here you can mail it to me; see [[privacy]]
+
+Also, you may want to file a new bug report, since I *did* fix and close this bug. You're probably seeing a slightly different bug.
+"""]]
diff --git a/doc/bugs/bad_comment_in_ssh_public_key_ssh-rsa/comment_3_51da7f5881f65422328d341e5ab0d250._comment b/doc/bugs/bad_comment_in_ssh_public_key_ssh-rsa/comment_3_51da7f5881f65422328d341e5ab0d250._comment
new file mode 100644
index 000000000..4cf86f646
--- /dev/null
+++ b/doc/bugs/bad_comment_in_ssh_public_key_ssh-rsa/comment_3_51da7f5881f65422328d341e5ab0d250._comment
@@ -0,0 +1,33 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlEhzszkzOIy8-Rx8b2mcr75QcnIc6O_OA"
+ nickname="Rachel"
+ subject="I'm afraid I'm getting this too"
+ date="2013-09-12T12:48:04Z"
+ content="""
+Very similar setup. Initially set up on a Mac, then tried to set up the first local pairing with a Linux system. Basically seeing exactly the same thing.
+
+ bad comment in ssh public key ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDa09lpmgLeRVF1KZn2gX6tmBH4Jpcou/rkPbhwLoFNLtQsdNrbjDKuyc4pDbUhexWVvub1YCLItLK0vYRdMvoJWjNzy926sHs8CxXFVg6PMQXw3wOHousSn0NkVfwUMNn5aS+1vz/WDlStmg7WzXgiPg1Whn6CKIomxA63rUMe3I+2nVkyO6jGlOkliPApVP2utURJbyxBDYDB+Ys7zUxvEcCekhxJO263myuo2gwI4A3mfTLRJMzbz8frRZJz5iuUIcOHaIDy6n0qKFq18BDux4SDwNjQ34yti5yqveRBMwFndHQYN6YHk1k26h0kyhb2T6lXaaAirSqa3dwfZuKp rachel@celestia.local
+
+
+# Versions and Stuff:
+
+## Mac:
+
+* OS X 10.8.4
+* git-annex 4.20130909-ga29f960 (downloaded about half an hour ago!)
+* BTW I have git installed from Homebrew, version 1.8.3.4 in my shell's $PATH, but obviously /usr/bin/git from the system is intact.
+* Hostname: celestia.local
+* Username: rachel
+
+## Linux:
+* Ubuntu 13.04
+* git-annex 3.20121112ubuntu4 (from Ubuntu's own repos)
+* I note that's later than the version you said this bug was fixed in, hence the report. :-)
+* Hostname: twilight.local (mDNS domain not appended even by hostname -f but avahi is working)
+* Username: rachel
+
+IPv6 is active, but I note a comment somewhere that that's probably not relevant for git-annex.
+
+Machines are very local to each other, in the same room, connected via a gigabit switch. They can definitely see each other. :-)
+
+"""]]
diff --git a/doc/bugs/bad_comment_in_ssh_public_key_ssh-rsa/comment_4_ba384314c1e47ec4b72e1843e0500df9._comment b/doc/bugs/bad_comment_in_ssh_public_key_ssh-rsa/comment_4_ba384314c1e47ec4b72e1843e0500df9._comment
new file mode 100644
index 000000000..4b9e27bba
--- /dev/null
+++ b/doc/bugs/bad_comment_in_ssh_public_key_ssh-rsa/comment_4_ba384314c1e47ec4b72e1843e0500df9._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmpBDWko1yZmngBYzm_CeBv8RjoIMXaINE"
+ nickname="Rachel"
+ subject="latest works"
+ date="2013-09-12T13:19:09Z"
+ content="""
+Downloaded the latest tarball (4.20130911-g6625d0e) and that seems to be able to pair ok.
+
+Different bug though: It objects to push.default = simple in ~/.gitconfig, but no such complaint on osx. But that's a different bug; i'll report separately when I'm a bit more up to speed.
+"""]]
diff --git a/doc/bugs/bare_git_repos.mdwn b/doc/bugs/bare_git_repos.mdwn
new file mode 100644
index 000000000..5e9100acf
--- /dev/null
+++ b/doc/bugs/bare_git_repos.mdwn
@@ -0,0 +1,29 @@
+It would be nice if git-annex could be used in bare git repos.
+However, that is not currently supported. Problems include:
+
+* git-annex often does not read a git repo's config before touching it,
+ so it doesn't know if the repo is bare or not
+ (reading the config when operating on ssh repos would be a pain and SLOW;
+ I had some of that code in as of 1aa19422ac8748eeff219ac4f46df166dae783c5,
+ but ripped it all out)
+* .. which results in creating `.git/annex` in a bare repo, which mightily
+ confuses git (so it will complain that the bare repo is not
+ a git repo at all!)
+* `.git-annex/` needs to have state recorded to it and committed, and that
+ is not possible with a bare repo. (If [[todo/branching]] were done,
+ that might be fixed.) (now fixed)
+
+----
+
+Update: Now that git-annex-shell is used for accessing remote repos,
+it would be possible to add smarts about bare repos there, and avoid
+some of the above problems. Probably only the state recording problem
+remains.
+
+A possible other approach to the state recording repo is to not
+record state changes on the remote in that case. Git-annex already
+records remote state changes locally whenever it modifies the state of a
+remote. --[[Joey]]
+
+> And... [[done]]! See [[/bare_repositories]] for current status
+> and gotchas. --[[Joey]]
diff --git a/doc/bugs/box.com_never_stops_syncing..mdwn b/doc/bugs/box.com_never_stops_syncing..mdwn
new file mode 100644
index 000000000..42b2eaf1a
--- /dev/null
+++ b/doc/bugs/box.com_never_stops_syncing..mdwn
@@ -0,0 +1,63 @@
+### Please describe the problem.
+Git-annex will constantly sync most(if not all) my files to box.com
+
+### What steps will reproduce the problem?
+1 - Use git-annex instead of Dropbox at work
+2 - Boot computer.
+3 - Watch it sync everything to box.com (even files i believe it has transferred each and every day for the last few months)
+
+### What version of git-annex are you using? On what operating system?
+git-annex version: 4.20130827
+
+But i have never seen it work satisfactory in any version.
+
+Also, i have seen this is 10+ different clean git-annexes. So it isn't annex specific.
+
+### Please provide any additional information below.
+
+I am going to add more debug to this bug constantly. (I intend to do a full 'git annex copy --to box.com --not --in box.com' daily, and see if the same files are transfered again and again)
+
+
+For now, i see a few different issues already:
+
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+tou@DSK1049:~/work-annex$ git annex copy --to box.com --not --in box.com 2>&1 | tee ../work-annex-copy-to-box.com-not-in-box.com-run1.log
+[2013-09-11 09:24:53 CEST] read: git ["--git-dir=/home/tou/work-annex/.git","--work-tree=/home/tou/work-annex","show-ref","git-annex"]
+[2013-09-11 09:24:53 CEST] read: git ["--git-dir=/home/tou/work-annex/.git","--work-tree=/home/tou/work-annex","show-ref","--hash","refs/heads/git-annex"]
+[2013-09-11 09:24:53 CEST] read: git ["--git-dir=/home/tou/work-annex/.git","--work-tree=/home/tou/work-annex","log","refs/heads/git-annex..dbe8b1cfa5f84126c45a39fdc7c7f26e272c71cc","--oneline","-n1"]
+[2013-09-11 09:24:53 CEST] read: git ["--git-dir=/home/tou/work-annex/.git","--work-tree=/home/tou/work-annex","log","refs/heads/git-annex..45e279375897a2cd7f5b893402e0ec25c1b23436","--oneline","-n1"]
+[2013-09-11 09:24:54 CEST] read: git ["--git-dir=/home/tou/work-annex/.git","--work-tree=/home/tou/work-annex","log","refs/heads/git-annex..c4921be4434f751493fce1c932ac759214abacd4","--oneline","-n1"]
+[2013-09-11 09:24:54 CEST] read: git ["--git-dir=/home/tou/work-annex/.git","--work-tree=/home/tou/work-annex","log","refs/heads/git-annex..d591398dc1cac824a5fc5bdacdcb82301a9b15a3","--oneline","-n1"]
+[2013-09-11 09:24:54 CEST] chat: git ["--git-dir=/home/tou/work-annex/.git","--work-tree=/home/tou/work-annex","cat-file","--batch"]
+[2013-09-11 09:24:54 CEST] read: git ["config","--null","--list"]
+[2013-09-11 09:24:54 CEST] read: git ["--git-dir=/home/tou/work-annex/.git","--work-tree=/home/tou/work-annex","ls-files","--cached","-z","--"]
+[2013-09-11 09:24:54 CEST] chat: git ["--git-dir=/home/tou/work-annex/.git","--work-tree=/home/tou/work-annex","cat-file","--batch"]
+copy Documents/Gamle catillo overførsler/Rapport b-bm.odt (gpg) (checking box.com...) ok
+copy Documents/Gamle catillo overførsler/Rapport brandt skorstensfejeren.odt (checking box.com...) (failed to read https://www.box.com/dav/work-annex/4a5/18e/GPGHMACSHA1--5f8660edac93899cf9adc5fadcc480ddc2992bb1/GPGHMACSHA1--5f8660edac93899cf9adc5fadcc480ddc2992bb1.chunkcount) failed
+copy Documents/Gamle catillo overførsler/Rapport teamkoege.odt (checking box.com...) (failed to read https://www.box.com/dav/work-annex/98d/ae7/GPGHMACSHA1--5253241407527aa6c980f1174fdbc32713c54c44/GPGHMACSHA1--5253241407527aa6c980f1174fdbc32713c54c44.chunkcount) failed
+copy Documents/Gamle catillo overførsler/Rapport vikarborsen.odt (checking box.com...) ok
+copy Documents/Gamle catillo overførsler/Rapport-terrariemesteren.odt (checking box.com...) ok
+copy Documents/Gamle catillo overførsler/catillo-efhandel.odt (checking box.com...) (failed to read https://www.box.com/dav/work-annex/9d9/aea/GPGHMACSHA1--1516eac1ec7b4ceaa840faebabde1f50f5db0a52/GPGHMACSHA1--1516eac1ec7b4ceaa840faebabde1f50f5db0a52.chunkcount) failed
+copy Documents/Nøgeordsanalyse catillo104.xlsx (checking box.com...) (ResponseTimeout) failed
+copy Documents/Søgeordsliste.txt (checking box.com...) ok
+copy Documents/catillo guide.odt (checking box.com...) ok
+copy Documents/guide bruger oprettelse.odt (checking box.com...) (failed to read https://www.box.com/dav/work-annex/49e/175/GPGHMACSHA1--2b47737f8de7faac7704eaa322785edad63a921c/GPGHMACSHA1--2b47737f8de7faac7704eaa322785edad63a921c.chunkcount) failed
+copy Documents/guide skift backup bånd.odt (checking box.com...) ok
+copy Documents/lilletest.csv (checking box.com...) (failed to read https://www.box.com/dav/work-annex/915/373/GPGHMACSHA1--49ba3d5f63c012ae2cd2c0fc3e729178b1023c33/GPGHMACSHA1--49ba3d5f63c012ae2cd2c0fc3e729178b1023c33.chunkcount) failed
+copy Dropbox/adams-scraper/CommonFunctions.py (checking box.com...) (ResponseTimeout) failed
+copy Dropbox/adams-scraper/__pycache__/CommonFunctions.cpython-33.pyc (checking box.com...) (to box.com...) [2013-09-11 09:28:30 CEST] chat: gpg ["--batch","--no-tty","--use-agent","--quiet","--trust-model","always","--batch","--passphrase-fd","14","--symmetric","--force-mdc"]
+
+100% 0.0 B/s 0sResponseTimeout
+ResponseTimeout
+failed
+
+
+# End of transcript or log.
+"""]]
+
+More to come(full log)
diff --git a/doc/bugs/box.com_never_stops_syncing./comment_1_124a5edcd89cc6b61e1a41f5b4d640d7._comment b/doc/bugs/box.com_never_stops_syncing./comment_1_124a5edcd89cc6b61e1a41f5b4d640d7._comment
new file mode 100644
index 000000000..ee1c88cc7
--- /dev/null
+++ b/doc/bugs/box.com_never_stops_syncing./comment_1_124a5edcd89cc6b61e1a41f5b4d640d7._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.51"
+ subject="comment 1"
+ date="2013-09-12T20:29:14Z"
+ content="""
+It seems you are getting a lot of timeouts from box.com, both when checking if content is present there and when uploading content that it does not have.
+
+I have heard some grumbles about box.com not being very reliable right now.
+"""]]
diff --git a/doc/bugs/box.com_never_stops_syncing./comment_2_42574181aa721319ba54eadf0a15ddff._comment b/doc/bugs/box.com_never_stops_syncing./comment_2_42574181aa721319ba54eadf0a15ddff._comment
new file mode 100644
index 000000000..5a0cde548
--- /dev/null
+++ b/doc/bugs/box.com_never_stops_syncing./comment_2_42574181aa721319ba54eadf0a15ddff._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmkBwMWvNKZZCge_YqobCSILPMeK6xbFw8"
+ nickname="develop"
+ subject="comment 2"
+ date="2013-09-12T20:54:33Z"
+ content="""
+The problem being. I've used box.com with one of my own hooks(owncloud), where it is completely stable!
+
+The instability is not a the box.com end.
+
+"""]]
diff --git a/doc/bugs/box.com_never_stops_syncing./comment_3_2ad727849070cfd52d6c719478e9cce3._comment b/doc/bugs/box.com_never_stops_syncing./comment_3_2ad727849070cfd52d6c719478e9cce3._comment
new file mode 100644
index 000000000..5eab58b3f
--- /dev/null
+++ b/doc/bugs/box.com_never_stops_syncing./comment_3_2ad727849070cfd52d6c719478e9cce3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.51"
+ subject="comment 3"
+ date="2013-09-12T20:56:44Z"
+ content="""
+git-annex is using box.com's WebDAV interface. Is owncloud?
+"""]]
diff --git a/doc/bugs/box.com_never_stops_syncing./comment_4_83ce23e45f5a5845d4f04519ee14ec65._comment b/doc/bugs/box.com_never_stops_syncing./comment_4_83ce23e45f5a5845d4f04519ee14ec65._comment
new file mode 100644
index 000000000..eb9dc5134
--- /dev/null
+++ b/doc/bugs/box.com_never_stops_syncing./comment_4_83ce23e45f5a5845d4f04519ee14ec65._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmkBwMWvNKZZCge_YqobCSILPMeK6xbFw8"
+ nickname="develop"
+ subject="comment 4"
+ date="2013-09-12T21:33:29Z"
+ content="""
+It uses the following url https://www.box.com/dav
+
+"""]]
diff --git a/doc/bugs/box.com_never_stops_syncing./comment_5_ef1c9d87b04db5047ab72167d3269687._comment b/doc/bugs/box.com_never_stops_syncing./comment_5_ef1c9d87b04db5047ab72167d3269687._comment
new file mode 100644
index 000000000..9d9c1329b
--- /dev/null
+++ b/doc/bugs/box.com_never_stops_syncing./comment_5_ef1c9d87b04db5047ab72167d3269687._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.51"
+ subject="comment 5"
+ date="2013-09-12T21:44:32Z"
+ content="""
+It may be that there is a timeout in the http library that I am using for webdav that is too low. See <https://github.com/snoyberg/http-conduit/issues/137>
+"""]]
diff --git a/doc/bugs/box.com_never_stops_syncing./comment_6_c9cb39eba941678035f9b2888da1085c._comment b/doc/bugs/box.com_never_stops_syncing./comment_6_c9cb39eba941678035f9b2888da1085c._comment
new file mode 100644
index 000000000..5eaf4f4bb
--- /dev/null
+++ b/doc/bugs/box.com_never_stops_syncing./comment_6_c9cb39eba941678035f9b2888da1085c._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmkBwMWvNKZZCge_YqobCSILPMeK6xbFw8"
+ nickname="develop"
+ subject="comment 6"
+ date="2013-09-12T21:49:05Z"
+ content="""
+That would probably do it. With other implementations(fuse mount) i've seen stalls and other bad behaviour with that DAV server.
+
+The owncloud hook doesn't have a timeout set. It probably should have one to prevent a total stall.
+"""]]
diff --git a/doc/bugs/box.com_never_stops_syncing./comment_7_4b0632a4e37c96959a8e6434e9fd86fb._comment b/doc/bugs/box.com_never_stops_syncing./comment_7_4b0632a4e37c96959a8e6434e9fd86fb._comment
new file mode 100644
index 000000000..2ac3f360e
--- /dev/null
+++ b/doc/bugs/box.com_never_stops_syncing./comment_7_4b0632a4e37c96959a8e6434e9fd86fb._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmkBwMWvNKZZCge_YqobCSILPMeK6xbFw8"
+ nickname="develop"
+ subject="Logs"
+ date="2013-09-13T11:43:22Z"
+ content="""
+So have two days of logs now, and it doesn't look like it is retrying old files.
+
+http://paste.ubuntu.com/6101255/ <- day 1
+
+http://paste.ubuntu.com/6101256/ <- day 2
+
+Setting the computer to do the following loop over the weekend, lets see if everything is done come monday.
+
+for i in `seq 3 2000`; do git annex copy --to box.com --not --in box.com 2>&1 | tee ../work-annex-copy-to-box.com-not-in-box.com-run$i.log; done
+
+"""]]
diff --git a/doc/bugs/box.com_never_stops_syncing./comment_8_d9d318b8c958de6031ae323da20af625._comment b/doc/bugs/box.com_never_stops_syncing./comment_8_d9d318b8c958de6031ae323da20af625._comment
new file mode 100644
index 000000000..8dfbd6944
--- /dev/null
+++ b/doc/bugs/box.com_never_stops_syncing./comment_8_d9d318b8c958de6031ae323da20af625._comment
@@ -0,0 +1,55 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmWg4VvDTer9f49Y3z-R0AH16P4d1ygotA"
+ nickname="Tobias"
+ subject="Update"
+ date="2013-09-18T11:17:33Z"
+ content="""
+Only just got back to work now. The script has done 10 iteration. This is the status:
+
+
+tou@DSK1049:~$ cat work-annex-copy-to-box.com-not-in-box.com-run1.log |grep \" ok\"| wc -l
+137
+
+tou@DSK1049:~$ cat work-annex-copy-to-box.com-not-in-box.com-run2.log |grep \" ok\"| wc -l
+77
+
+tou@DSK1049:~$ cat work-annex-copy-to-box.com-not-in-box.com-run3.log |grep \" ok\"| wc -l
+116
+
+tou@DSK1049:~$ cat work-annex-copy-to-box.com-not-in-box.com-run4.log |grep \" ok\"| wc -l
+70
+
+tou@DSK1049:~$ cat work-annex-copy-to-box.com-not-in-box.com-run5.log |grep \" ok\"| wc -l
+26
+
+tou@DSK1049:~$ cat work-annex-copy-to-box.com-not-in-box.com-run6.log |grep \" ok\"| wc -l
+6
+
+tou@DSK1049:~$ cat work-annex-copy-to-box.com-not-in-box.com-run7.log |grep \" ok\"| wc -l
+6
+
+tou@DSK1049:~$ cat work-annex-copy-to-box.com-not-in-box.com-run8.log |grep \" ok\"| wc -l
+0
+
+tou@DSK1049:~$ cat work-annex-copy-to-box.com-not-in-box.com-run9.log |grep \" ok\"| wc -l
+0
+
+tou@DSK1049:~$ cat work-annex-copy-to-box.com-not-in-box.com-run10.log |grep \" ok\"| wc -l
+0
+
+tou@DSK1049:~$ cat work-annex-copy-to-box.com-not-in-box.com-run11.log |grep \" ok\"| wc -l
+0
+
+tou@DSK1049:~$ cat work-annex-copy-to-box.com-not-in-box.com-run12.log |grep \" ok\"| wc -l
+0
+
+I have all the log files of course.
+
+tou@DSK1049:~/work-annex$ git annex find --not --in box.com| wc -l
+1639
+
+So, of the last 5 iteration 0 files of 1639 missing were transfered. Most of these files are <10kbyte
+
+http://paste.ubuntu.com/6123459/ <- pastebin of work-annex-copy-to-box.com-not-in-box.com-run11.log if it is of any use.
+
+"""]]
diff --git a/doc/bugs/box.com_never_stops_syncing./comment_9_689ac6a4a305197cf5566f98dab47b4b._comment b/doc/bugs/box.com_never_stops_syncing./comment_9_689ac6a4a305197cf5566f98dab47b4b._comment
new file mode 100644
index 000000000..99a0eb9ae
--- /dev/null
+++ b/doc/bugs/box.com_never_stops_syncing./comment_9_689ac6a4a305197cf5566f98dab47b4b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.80"
+ subject="comment 9"
+ date="2013-09-28T19:34:42Z"
+ content="""
+Filed a bug on the DAV library about this: <http://bugs.debian.org/724856>
+"""]]
diff --git a/doc/bugs/bug_in_download_prebuilt_linux_tarball__44___and_constraints_issues_with_3.20121112.mdwn b/doc/bugs/bug_in_download_prebuilt_linux_tarball__44___and_constraints_issues_with_3.20121112.mdwn
new file mode 100644
index 000000000..4a942ec9e
--- /dev/null
+++ b/doc/bugs/bug_in_download_prebuilt_linux_tarball__44___and_constraints_issues_with_3.20121112.mdwn
@@ -0,0 +1,45 @@
+What steps will reproduce the problem?
+
+First issue:
+* The prebuilt tarball doesn't synchronize properly.
+
+Reproduce:
+* Download and untar tarball
+* Start gitannex webapp on multiple computers(i had three in use)
+* Synchronize with xmpp and an ssh server backend.
+* The tarball versions don't push/get from ssh server backend.
+
+Second issue:
+* I can't install git-annex on ubuntu 12.10(Works fine in debian unstable)
+* http://hpaste.org/77684
+
+Reproduce:
+* cabal update
+* cabal install --only-dependencies
+* cabal configure
+* cabal build
+* cabal install --bindir=$HOME/bin
+
+With these constraints the cabal install can work:
+* cabal install --only-dependencies ./ --constraint=certificate==1.2.2 --constraint=crypto-pubkey-types==0.1.1
+
+What is the expected output? What do you see instead?
+* Tarball version doesn't push to ssh backend.
+* cabal install git-annex gives http://hpaste.org/77684
+
+What version of git-annex are you using? On what operating system?
+* git-annex 3.20121112 on debian unstale (working)
+* ubuntu 12.10(failing)
+
+Please provide any additional information below.
+
+With these constraints the cabal install can work:
+* cabal install --only-dependencies ./ --constraint=certificate==1.2.2 --constraint=crypto-pubkey-types==0.1.1
+
+NOTE:
+I couldn't get the markdown to cooperate, so using pl pagetype.
+
+> I suspect this is [[done]]..
+>
+> I fixed some bugs in the prebuilt tarball in the past 2 days that prevented it
+> from transferring files.
diff --git a/doc/bugs/build_fails_in_Assistant__47__WebApp__47__Gpg.hs.mdwn b/doc/bugs/build_fails_in_Assistant__47__WebApp__47__Gpg.hs.mdwn
new file mode 100644
index 000000000..172f28143
--- /dev/null
+++ b/doc/bugs/build_fails_in_Assistant__47__WebApp__47__Gpg.hs.mdwn
@@ -0,0 +1,57 @@
+### Please describe the problem.
+
+Building from git fails in Assistant/WebApp/Gpg.hs
+
+### What steps will reproduce the problem?
+
+Follow instructions at <http://git-annex.branchable.com/install/cabal/> for building from git:
+
+[[!format sh """
+cabal update
+PATH=$HOME/bin:$PATH
+cabal install c2hs --bindir=$HOME/bin
+cabal install --only-dependencies
+cabal configure
+cabal build
+"""]]
+
+### What version of git-annex are you using? On what operating system?
+
+git master (7da58f3ebf8), openSUSE 12.3
+
+### Please provide any additional information below.
+
+[[!format txt """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+Assistant/WebApp/Configurators/Fsck.hs:69:35:
+ Warning: This binding for `u' shadows the existing binding
+ bound at Assistant/WebApp/Configurators/Fsck.hs:60:17
+
+Assistant/WebApp/Configurators/Fsck.hs:126:11:
+ Warning: This binding for `check' shadows the existing binding
+ imported from `Assistant.WebApp.Common' at Assistant/WebApp/Configurators/Fsck.hs:16:1
+-30
+ (and originally defined in `Yesod.Form.Functions')
+[322 of 371] Compiling Assistant.TransferQueue ( Assistant/TransferQueue.hs, dist/build/git-annex/git
+-annex-tmp/Assistant/TransferQueue.o )
+[323 of 371] Compiling Assistant.Threads.Glacier ( Assistant/Threads/Glacier.hs, dist/build/git-annex
+/git-annex-tmp/Assistant/Threads/Glacier.o )
+[324 of 371] Compiling Assistant.Threads.Merger ( Assistant/Threads/Merger.hs, dist/build/git-annex/g
+it-annex-tmp/Assistant/Threads/Merger.o )
+[325 of 371] Compiling Assistant.Threads.Cronner ( Assistant/Threads/Cronner.hs, dist/build/git-annex
+/git-annex-tmp/Assistant/Threads/Cronner.o )
+[326 of 371] Compiling Assistant.MakeRemote ( Assistant/MakeRemote.hs, dist/build/git-annex/git-annex
+-tmp/Assistant/MakeRemote.o )
+[327 of 371] Compiling Assistant.WebApp.Gpg ( Assistant/WebApp/Gpg.hs, dist/build/git-annex/git-annex
+-tmp/Assistant/WebApp/Gpg.o )
+
+Assistant/WebApp/Gpg.hs:88:40:
+ Not in scope: type constructor or class `MonadIO'
+ Perhaps you meant `Monad' (imported from Assistant.WebApp.Common)
+
+# End of transcript or log.
+"""]]
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/build_failure_with_kqueue_code__44___first_commit_that_breaks_is_3dce75fb23fca94ad86c3f0ee816bb0ad2ecb27c.mdwn b/doc/bugs/build_failure_with_kqueue_code__44___first_commit_that_breaks_is_3dce75fb23fca94ad86c3f0ee816bb0ad2ecb27c.mdwn
new file mode 100644
index 000000000..d0551c151
--- /dev/null
+++ b/doc/bugs/build_failure_with_kqueue_code__44___first_commit_that_breaks_is_3dce75fb23fca94ad86c3f0ee816bb0ad2ecb27c.mdwn
@@ -0,0 +1,25 @@
+Here goes...
+
+<pre>
+laplace:git-annex jtang$ make
+ghc -O2 -threaded -Wall -ignore-package monads-fd -ignore-package monads-tf -outputdir tmp -IUtility -DWITH_ASSISTANT -DWITH_S3 -DWITH_WEBAPP -DWITH_KQUEUE -DOSX --make git-annex Utility/libdiskfree.o Utility/libmounts.o Utility/libkqueue.o
+
+Assistant/Threads/MountWatcher.hs:40:0:
+ warning: #warning Building without dbus support; will use mtab polling
+[165 of 208] Compiling Assistant.Alert ( Assistant/Alert.hs, tmp/Assistant/Alert.o )
+[173 of 208] Compiling Assistant.DaemonStatus ( Assistant/DaemonStatus.hs, tmp/Assistant/DaemonStatus.o )
+[174 of 208] Compiling Assistant.TransferQueue ( Assistant/TransferQueue.hs, tmp/Assistant/TransferQueue.o )
+[175 of 208] Compiling Assistant.Threads.Watcher ( Assistant/Threads/Watcher.hs, tmp/Assistant/Threads/Watcher.o )
+
+Assistant/Threads/Watcher.hs:61:43:
+ Couldn't match expected type `Utility.Kqueue.Kqueue'
+ with actual type `()'
+ Expected type: IO Utility.Kqueue.Kqueue -> IO Utility.Kqueue.Kqueue
+ Actual type: IO Utility.Kqueue.Kqueue -> IO ()
+ In the fourth argument of `watchDir', namely `startup'
+ In the second argument of `($)', namely
+ `watchDir "." ignored hooks startup'
+make: *** [git-annex] Error 1
+</pre>
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/build_is_broken_at_commit_cc0e5b7.mdwn b/doc/bugs/build_is_broken_at_commit_cc0e5b7.mdwn
new file mode 100644
index 000000000..43074915f
--- /dev/null
+++ b/doc/bugs/build_is_broken_at_commit_cc0e5b7.mdwn
@@ -0,0 +1,13 @@
+the build is currently borked with
+
+<pre>
+ghc -O2 -threaded -Wall -ignore-package monads-fd -ignore-package monads-tf -outputdir tmp -IUtility -DWITH_ASSISTANT -DWITH_S3 -DWITH_WEBAPP -DWITH_PAIRING -DWITH_KQUEUE -DOSX --make git-annex -o tmp/git-annex Utility/libdiskfree.o Utility/libmounts.o Utility/libkqueue.o
+Assistant/Install.hs:19:8:
+Could not find module `Utility'
+Use -v to see a list of the files searched for.
+make: *** [git-annex] Error 1
+</pre>
+
+This was first introduced at commit e88e3ba
+
+> oops, -DOSX is not a good idea. [[done]] --[[Joey]]
diff --git a/doc/bugs/build_issue_with_8baff14054e65ecbe801eb66786a55fa5245cb30.mdwn b/doc/bugs/build_issue_with_8baff14054e65ecbe801eb66786a55fa5245cb30.mdwn
new file mode 100644
index 000000000..34c2eef5f
--- /dev/null
+++ b/doc/bugs/build_issue_with_8baff14054e65ecbe801eb66786a55fa5245cb30.mdwn
@@ -0,0 +1,43 @@
+Building commit 8baff14054e65ecbe801eb66786a55fa5245cb30 yields this...
+
+
+<pre>
+[164 of 189] Compiling Command.Sync ( Command/Sync.hs, tmp/Command/Sync.o )
+Command/Sync.hs:268:34:
+Not in scope: `vermarker'
+Perhaps you meant `varmarker' (line 267)
+make: *** [git-annex] Error 1
+</pre>
+
+Supplied fix...
+
+<pre>
+
+From a23a1af99c7a95c316a87f9c6f5f67a6f8ff6937 Mon Sep 17 00:00:00 2001
+From: Jimmy Tang <jtang@tchpc.tcd.ie>
+Date: Wed, 27 Jun 2012 21:55:22 +0100
+Subject: [PATCH 14/14] fix build issue introduced in
+ 8baff14054e65ecbe801eb66786a55fa5245cb30
+
+---
+ Command/Sync.hs | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/Command/Sync.hs b/Command/Sync.hs
+index b2bf24d..dfaed59 100644
+--- a/Command/Sync.hs
++++ b/Command/Sync.hs
+@@ -265,7 +265,7 @@ mergeFile file key
+ | otherwise = go $ shortHash $ show key
+ where
+ varmarker = ".variant-"
+- doubleconflict = vermarker `isSuffixOf` (dropExtension file)
++ doubleconflict = varmarker `isSuffixOf` (dropExtension file)
+ go v = takeDirectory file
+ </> dropExtension (takeFileName file)
+ ++ varmarker ++ v
+--
+1.7.11.1
+</pre>
+
+[[fixed|done]]
diff --git a/doc/bugs/build_issue_with_latest_release_0.20110522-1-gde817ba.mdwn b/doc/bugs/build_issue_with_latest_release_0.20110522-1-gde817ba.mdwn
new file mode 100644
index 000000000..a7bae50b8
--- /dev/null
+++ b/doc/bugs/build_issue_with_latest_release_0.20110522-1-gde817ba.mdwn
@@ -0,0 +1,14 @@
+A recent checkout of git-annex fails to build for me (I've installed the new dependancies as well)
+
+<pre>
+[70 of 81] Compiling Command.DropUnused ( Command/DropUnused.hs, Command/DropUnused.o )
+[71 of 81] Compiling Command.Status ( Command/Status.hs, Command/Status.o )
+
+Command/Status.hs:133:37: Not in scope: `swap'
+make: *** [git-annex] Error 1
+</pre>
+
+it fails on OSX 10.6.x with ghc 6.12.3 and a corresponding haskell-platform install. I ran a bisect and found that commit 75a3f5027f74565d909fb940893636d081d9872a seems to have broken git-annex for me, reverting the commit allows me to build git-annex, I have not run the tests to verify everything is working correctly though.
+
+> Probably `swap` appeared only in a newer GHC. I've reverted to avoid a
+> versioned build dependency. [[done]] --[[Joey]]
diff --git a/doc/bugs/build_problem_on_OSX.mdwn b/doc/bugs/build_problem_on_OSX.mdwn
new file mode 100644
index 000000000..e859a1150
--- /dev/null
+++ b/doc/bugs/build_problem_on_OSX.mdwn
@@ -0,0 +1,18 @@
+I just squelched a bunch of build issues (to do with dependancies) on my autobuilder for OSX, this is currently happening
+
+<pre>
+install -d tmp
+ghc -O2 -Wall -outputdir tmp -IUtility -DWITH_ASSISTANT -DWITH_S3 -DWITH_WEBAPP -DWITH_PAIRING -DWITH_XMPP -DWITH_DNS -DWITH_KQUEUE -threaded --make git-annex -o tmp/git-annex Utility/libdiskfree.o Utility/libmounts.o Utility/libkqueue.o
+
+Assistant/Threads/NetWatcher.hs:29:0:
+ warning: #warning Building without dbus support; will poll for network connection changes
+
+Assistant/Threads/MountWatcher.hs:36:0:
+ warning: #warning Building without dbus support; will use mtab polling
+[ 29 of 259] Compiling Utility.OSX ( Utility/OSX.hs, tmp/Utility/OSX.o )
+
+Utility/OSX.hs:22:17: Not in scope: `myHomeDir'
+make: *** [git-annex] Error 1
+</pre>
+
+> Someone else reported that too; I fixed it. [[done]] --[[Joey]]
diff --git a/doc/bugs/building_on_lenny.mdwn b/doc/bugs/building_on_lenny.mdwn
new file mode 100644
index 000000000..48386bde4
--- /dev/null
+++ b/doc/bugs/building_on_lenny.mdwn
@@ -0,0 +1,80 @@
+hi,
+
+I am trying to build git annex on lenny.
+
+I checked out the latest from git c88d4939453845efee04da811d64aa41046f9c11,
+installed all the packages (some from backports) as required by dpkg-buildpackage
+
+Then I get this:
+
+ ...
+ mkdir -p build
+ ghc -odir build -hidir build --make git-annex
+ [ 1 of 19] Compiling Utility ( Utility.hs, build/Utility.o )
+ [ 2 of 19] Compiling GitRepo ( GitRepo.hs, build/GitRepo.o )
+ [ 3 of 19] Compiling GitQueue ( GitQueue.hs, build/GitQueue.o )
+ [ 4 of 19] Compiling TypeInternals ( TypeInternals.hs, build/TypeInternals.o )
+ [ 5 of 19] Compiling Types ( Types.hs, build/Types.o )
+ [ 6 of 19] Compiling Annex ( Annex.hs, build/Annex.o )
+ [ 7 of 19] Compiling Locations ( Locations.hs, build/Locations.o )
+ [ 8 of 19] Compiling UUID ( UUID.hs, build/UUID.o )
+ [ 9 of 19] Compiling LocationLog ( LocationLog.hs, build/LocationLog.o )
+ [10 of 19] Compiling Core ( Core.hs, build/Core.o )
+ [11 of 19] Compiling Backend.URL ( Backend/URL.hs, build/Backend/URL.o )
+ [12 of 19] Compiling Backend ( Backend.hs, build/Backend.o )
+
+ Backend.hs:114:50:
+ Not in scope: type constructor or class `SomeException'
+ make[1]: *** [git-annex] Error 1
+ make[1]: Leaving directory `/home/cstamas/tmp/git-annex'
+ dh_auto_build: make -j1 returned exit code 2
+ make: *** [build] Error 2
+ dpkg-buildpackage: failure: debian/rules build gave error exit status 2
+
+I will try to check the mentioned file for error, but I do not know how to program in haskell.
+
+Thanks for your help! --[[cstamas]]
+
+> Newer versions of ghc changed their exception handling types, and
+> I coded git-annex to use the new style and not the old. gch6 6.12 will
+> work. I do not think there is a backport available though. --[[Joey]]
+>
+> Ok, found and deployed a workaround. It is not tested. Let me know how it
+> works for you. --[[Joey]]
+
+>> I did a git pull and now I get:
+
+ mkdir -p build
+ ghc -cpp -odir build -hidir build --make git-annex
+ [ 1 of 20] Compiling Portability ( Portability.hs, build/Portability.o )
+
+ Portability.hs:13:21:
+ Not in scope: type constructor or class `Exception'
+ make[1]: *** [git-annex] Error 1
+ make[1]: Leaving directory `/home/cstamas/tmp/git-annex'
+ dh_auto_build: make -j1 returned exit code 2
+ make: *** [build] Error 2
+ dpkg-buildpackage: failure: debian/rules build gave error exit status 2
+
+>> --[[cstamas]]
+
+>>> Ok well, I'm not going to try to reimplement all of
+>>> Control.Exception.Extensible so I've made it use it. You will have to
+>>> figure out how to install that library yourself though, I don't know
+>>> how to use cabal with such an old ghc. Library is here:
+>>> <http://hackage.haskell.org/package/extensible-exceptions>
+>>> and I asked how to get it on stable here:
+>>> <http://ask.debian.net/questions/how-to-get-haskell-extensible-extceptions-on-stable> --[[Joey]]
+
+>>>> I made some effort with cabal on lenny. I can install (and I did it) cabal
+>>>> from squeeze as dependencies are ok. Then I installed extensible
+>>>> exceptions, but it places it in some local dir that git-annex's installer
+>>>> (or ghc itself) does not know about.
+>>>>
+>>>> Later I realized that *only* for the compilation ghc6 and its friends are
+>>>> needed. So I built the package on my other machine running squeeze. Then
+>>>> resulting deb packages cleanly installs on lenny
+>>>>
+>>>> For me this is OK. Thanks! --[[cstamas]]
+
+[[done]]
diff --git a/doc/bugs/bup_initremote_failed_with_localhost_+_username.mdwn b/doc/bugs/bup_initremote_failed_with_localhost_+_username.mdwn
new file mode 100644
index 000000000..c15de5b3e
--- /dev/null
+++ b/doc/bugs/bup_initremote_failed_with_localhost_+_username.mdwn
@@ -0,0 +1,49 @@
+### Please describe the problem.
+Attempted to create a bup remote on the current system via ssh. It appears to have created the bup remote fine, but fails when sshing to it and does not add the remote.
+This is a normal indirect annex (currently containing a single test jpg in its root)
+I'm presuming the error is "(storing uuid...) sh: 1: cd: can't cd to /~/archie"
+
+
+### What steps will reproduce the problem?
+git annex initremote bup type=bup encryption=none buprepo=sshservername:path
+
+I've tried using .ssh/config to remove the username from the servername passed to bup repo and it still fails.
+
+### What version of git-annex are you using? On what operating system?
+[[!format sh """
+>git-annex version
+git-annex version: 4.20130615-g29d5bb9
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP DNS
+local repository version: 3
+default repository version: 3
+supported repository versions: 3 4
+upgrade supported from repository versions: 0 1 2
+"""]]
+debian wheezy i686
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+> git annex initremote bup type=bup encryption=none buprepo=bup@localhost:archie
+initremote bup (bup init...)
+Reinitialized existing Git repository in /media/backup/home/archie/.bup/
+Initialized empty Git repository in /media/backup/bup/archie/
+(storing uuid...) sh: 1: cd: can't cd to /~/archie
+git-annex: ssh failed
+
+> ssh bup@localhost
+Last login: Mon Jun 17 10:35:45 2013 from localhost
+$ ls
+archie
+$ cd archie
+$ ls
+branches config description HEAD hooks info objects refs
+
+
+# End of transcript or log.
+"""]]
+
+> applied patchm, [[done]] --[[Joey]]
diff --git a/doc/bugs/bup_initremote_failed_with_localhost_+_username/comment_1_0e669c3039b089fa8a815d3ec11465d2._comment b/doc/bugs/bup_initremote_failed_with_localhost_+_username/comment_1_0e669c3039b089fa8a815d3ec11465d2._comment
new file mode 100644
index 000000000..b8bfb0c04
--- /dev/null
+++ b/doc/bugs/bup_initremote_failed_with_localhost_+_username/comment_1_0e669c3039b089fa8a815d3ec11465d2._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnrFnHRRNUQBB5RCDaIwhVmCcxQp8_yiYw"
+ nickname="Oliver"
+ subject="figured it out."
+ date="2013-06-19T14:21:08Z"
+ content="""
+It's failing because I am passing a relative url as buprepo - bup is expanding
+
+ host:dir
+
+to
+
+ ssh://host/~/dir
+
+but then onBupRemote isn't converting it back quite right.
+
+My haskell is rather rusty, but I have a working, if perhaps suboptimal patch; I'll email it across.
+
+
+"""]]
diff --git a/doc/bugs/cabal_build:___34__Could_not_find_module___96__Data.AssocList__39____34__.mdwn b/doc/bugs/cabal_build:___34__Could_not_find_module___96__Data.AssocList__39____34__.mdwn
new file mode 100644
index 000000000..a23930bd7
--- /dev/null
+++ b/doc/bugs/cabal_build:___34__Could_not_find_module___96__Data.AssocList__39____34__.mdwn
@@ -0,0 +1,23 @@
+What steps will reproduce the problem?
+
+Download current git head (fa5100d) and run cabal update; cabal install --only-dependencies; cabal configure; cabal build
+
+What is the expected output? What do you see instead?
+
+Expect succcessful build, get:
+
+Assistant/Install.hs:24:8:
+ Could not find module `Data.AssocList'
+ It is a member of the hidden package `hxt-9.3.1.1'.
+ Perhaps you need to add `hxt' to the build-depends in your .cabal file.
+ Use -v to see a list of the files searched for.
+
+
+What version of git-annex are you using? On what operating system?
+
+building using cabal from clone of git clone git://git-annex.branchable.com/, commit fa5100d (same problem happens with last release, 3.20121127). On OS X, "Lion".
+
+
+Please provide any additional information below.
+
+> [[done]], using Data.List instead now.
diff --git a/doc/bugs/cabal_build:___34__Could_not_find_module___96__Data.AssocList__39____34__/comment_1_0da9fd67c3cc01b316f95a1df4eb62ae._comment b/doc/bugs/cabal_build:___34__Could_not_find_module___96__Data.AssocList__39____34__/comment_1_0da9fd67c3cc01b316f95a1df4eb62ae._comment
new file mode 100644
index 000000000..967e203c1
--- /dev/null
+++ b/doc/bugs/cabal_build:___34__Could_not_find_module___96__Data.AssocList__39____34__/comment_1_0da9fd67c3cc01b316f95a1df4eb62ae._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="99.54.57.201"
+ subject="Could not find module `Data.AssocList' confirmed fixed."
+ date="2012-11-28T03:38:19Z"
+ content="""
+builds fine now, thank you!
+"""]]
diff --git a/doc/bugs/cabal_configure_is_broken_on_OSX_builds.mdwn b/doc/bugs/cabal_configure_is_broken_on_OSX_builds.mdwn
new file mode 100644
index 000000000..ddbbcb874
--- /dev/null
+++ b/doc/bugs/cabal_configure_is_broken_on_OSX_builds.mdwn
@@ -0,0 +1,14 @@
+Seems the last few commits have borked 'cabal configure' on OSX with the following error message
+
+<pre>
+[jtang@laplace git-annex (master)]$ cabal configure
+Resolving dependencies...
+
+Build/InstallDesktopFile.hs:19:8:
+ Could not find module `Assistant.OSX'
+ Use -v to see a list of the files searched for.
+</pre>
+
+Looks like a missing module.
+
+> Was broken everywhere really, so I fixed it. [[done]] --[[Joey]]
diff --git a/doc/bugs/cabal_install_fails_to_install_manpage.mdwn b/doc/bugs/cabal_install_fails_to_install_manpage.mdwn
new file mode 100644
index 000000000..265ad2432
--- /dev/null
+++ b/doc/bugs/cabal_install_fails_to_install_manpage.mdwn
@@ -0,0 +1,43 @@
+### Please describe the problem.
+
+The git-annex manual page is not installed when using [[install/cabal]] to install git-annex.
+
+### What steps will reproduce the problem?
+
+Follow [[install/cabal]] with `--bin-dir=/usr/local` and try `man git-annex`.
+
+I was expecting the manpage to be installed in `/usr/local/share/man`.
+
+### What version of git-annex are you using? On what operating system?
+
+git annex from a recent git build (4.20130909-g7f079d6) in Debian wheezy.
+
+### Please provide any additional information below.
+
+<del>This could be just a documentation problem...</del> Actually, the manpage can be read directly from the source tree in `doc/git-annex.mdwn`, but I still think it should be installed, for [[!wikipedia POLA]]'s sake. --[[anarcat]]
+
+I figured it out - that stuff is in the makefile, I updated [[install/cabal]] accordingly, so <del>done</del> - not done just yet. --[[anarcat]]
+
+> Doesn't seem right to me; Setup.hs has some stuff to do with
+> installing man pages. This does currently require that they
+> are distributed in pre-built form in the .tar.gz on hackage,
+> which I've just checked and they are.
+>
+> Perhaps cabal put the man pages somewhere else? After all, you
+> apparently did not set --datadir --[[Joey]]
+
+> > True, I didn't - the docs didn't say to. ;) But really, it's one of two things, either Setup.hs can install manpages, and then the Makefile shouldn't install it, or we should update documentation to use the makefile only. I'll try this again next time I reinstall through cabal i guess... -- [[anarcat]]a
+
+>>> The default location cabal installs man pages to is
+>>> `~/.cabal/share/man/man1`. That is insane, but it is not as
+>>> insane as not installing programs into PATH, which is why
+>>> the documentation tells how to set --bindir to fix that particular
+>>> cabal insanity. (Also, many systems don't have a good per-user
+>>> man directory anyway.)
+>>>
+>>> `make install` does not use `cabal install` because as noted, cabal
+>>> install is thurougly bat shit crazy. Not all systems that have
+>>> cabal have make, which is why the cabal documentation is the way it is.
+>>> --[[Joey]]
+
+[[done]]
diff --git a/doc/bugs/cabal_install_on_Ubuntu_12.04_fails_with_complaint_about_regex-base.mdwn b/doc/bugs/cabal_install_on_Ubuntu_12.04_fails_with_complaint_about_regex-base.mdwn
new file mode 100644
index 000000000..b84d930b4
--- /dev/null
+++ b/doc/bugs/cabal_install_on_Ubuntu_12.04_fails_with_complaint_about_regex-base.mdwn
@@ -0,0 +1,34 @@
+## What steps will reproduce the problem?
+
+I attempt
+
+ cabal install git-annex
+
+(already having installed `c2hs`)
+
+## What is the expected output? What do you see instead?
+
+I get
+
+ $ cabal install git-annex
+ Resolving dependencies...
+ cabal: Could not resolve dependencies:
+ trying: git-annex-3.20130216.1 (user goal)
+ trying: git-annex-3.20130216.1:+webapp
+ trying: git-annex-3.20130216.1:+assistant
+ trying: yesod-1.1.9 (dependency of git-annex-3.20130216.1:+assistant)
+ trying: http-conduit-1.9.0 (dependency of yesod-1.1.9)
+ trying: regex-compat-0.95.1/installed-851... (dependency of
+ http-conduit-1.9.0)
+ next goal: regex-base (dependency of regex-compat-0.95.1/installed-851...)
+ rejecting: regex-base-0.93.2/installed-999... (conflict: regex-base =>
+ mtl==2.0.1.0/installed-db1..., git-annex => mtl(>=2.1.1))
+ rejecting: regex-base-0.93.2, 0.93.1, 0.93, 0.92, 0.91, 0.90, 0.83, 0.72.0.2,
+ 0.72.0.1, 0.71 (conflict: regex-compat => regex-base==0.93.2/installed-999...)
+
+> This is a transient version skew in cabal, generally
+> known as "cabal hell". It will be fixed when the libraries
+> involved fix their versioned dependencies, which may have
+> already happened. Precompiled builds of git-annex are provided
+> so I do not have to chase every transient version skew
+> that occurs for every use who runs into it. [[done]] --[[Joey]]
diff --git a/doc/bugs/call_to_git-annex-shell_when_on_centralised___40__non-git-annex__41___repository.mdwn b/doc/bugs/call_to_git-annex-shell_when_on_centralised___40__non-git-annex__41___repository.mdwn
new file mode 100644
index 000000000..2a2832da3
--- /dev/null
+++ b/doc/bugs/call_to_git-annex-shell_when_on_centralised___40__non-git-annex__41___repository.mdwn
@@ -0,0 +1,208 @@
+What steps will reproduce the problem?
+
+Since syncing of non-git-annex repositories was enabled (thanks!), I see error messages
+
+ conq: invalid command syntax.
+
+in the output of git annex sync (and in the logs of the webapp), which I am fairly sure is an error from bitbucket, which I am using as the centralised repository. I know a similar thing has been reported before ([[conq:_invalid_command_syntax]]), but I really don't know how to tackle this. I have included the output from git annex sync --debug, and the ssh command which is causing this, at the end.
+
+If I strip out all the options from the ssh command, I get the same error. I don't know if this is some peculiarity from bitbucket, or a more general issue.
+
+
+Also, I don't know if this is even a problem. The syncing does seem to work properly.
+
+
+--Walter
+
+**edit** I have tried with another centralised annex-less git server, and the behaviour is better (more logs below). It realises that it doesn't have annex, modifies .git/config, and then afterwards doesn't try to run the problematic command. So, my first guess is that it isn't correctly determining that that command failed in some cases?
+
+
+What version of git-annex are you using? On what operating system?
+
+4.20130423-ge0f5abb, Ubuntu 12.10
+
+Please provide any additional information below.
+
+
+[[!format sh """
+~/annex$ git annex sync --debug
+[2013-04-24 10:21:39 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","symbolic-ref","HEAD"]
+[2013-04-24 10:21:39 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","show-ref","refs/heads/master"]
+[2013-04-24 10:21:39 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","show-ref","git-annex"]
+[2013-04-24 10:21:39 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","show-ref","--hash","refs/heads/git-annex"]
+[2013-04-24 10:21:39 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","log","refs/heads/git-annex..44700457a651992eb40ff67a148d77217e8aa1d7","--oneline","-n1"]
+[2013-04-24 10:21:39 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","log","refs/heads/git-annex..94392bcdad74257adaadb98ce85d17a83da7648c","--oneline","-n1"]
+[2013-04-24 10:21:39 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","log","refs/heads/git-annex..ff126032854d9ead0a096acae04f105628de0cc4","--oneline","-n1"]
+[2013-04-24 10:21:39 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","log","refs/heads/git-annex..62da8e99021b72a9255064385a75c5fe643e3711","--oneline","-n1"]
+[2013-04-24 10:21:39 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","log","refs/heads/git-annex..00cca957c30882c9dfaf494101251e4c634baa31","--oneline","-n1"]
+[2013-04-24 10:21:39 NZST] chat: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","cat-file","--batch"]
+[2013-04-24 10:21:39 NZST] read: git ["config","--null","--list"]
+[2013-04-24 10:21:39 NZST] read: ssh ["-S","/home/walter/annex/.git/annex/ssh/git@bitbucket.org","-o","ControlMaster=auto","-o","ControlPersist=yes","-T","git@bitbucket.org","git-annex-shell 'configlist' '/~/waltersom/annex.git'"]
+conq: invalid command syntax.
+[2013-04-24 10:21:39 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","ls-files","--others","--exclude-standard","--stage","-z","--","/home/walter/annex"]
+commit
+[2013-04-24 10:21:39 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","commit","-m","git-annex automatic sync"]
+ok
+[2013-04-24 10:21:39 NZST] call: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","show-ref","--verify","-q","refs/heads/synced/master"]
+[2013-04-24 10:21:39 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","log","refs/heads/master..refs/heads/synced/master","--oneline","-n1"]
+pull bitbucket
+[2013-04-24 10:21:39 NZST] call: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","fetch","bitbucket"]
+[2013-04-24 10:21:43 NZST] call: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","show-ref","--verify","-q","refs/remotes/bitbucket/master"]
+[2013-04-24 10:21:43 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","log","refs/heads/master..refs/remotes/bitbucket/master","--oneline","-n1"]
+[2013-04-24 10:21:43 NZST] call: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","show-ref","--verify","-q","refs/remotes/bitbucket/synced/master"]
+[2013-04-24 10:21:43 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","log","refs/heads/synced/master..refs/remotes/bitbucket/synced/master","--oneline","-n1"]
+ok
+[2013-04-24 10:21:43 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","show-ref","git-annex"]
+[2013-04-24 10:21:43 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","show-ref","--hash","refs/heads/git-annex"]
+[2013-04-24 10:21:43 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","log","refs/heads/git-annex..44700457a651992eb40ff67a148d77217e8aa1d7","--oneline","-n1"]
+[2013-04-24 10:21:43 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","log","refs/heads/git-annex..94392bcdad74257adaadb98ce85d17a83da7648c","--oneline","-n1"]
+[2013-04-24 10:21:43 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","log","refs/heads/git-annex..ff126032854d9ead0a096acae04f105628de0cc4","--oneline","-n1"]
+[2013-04-24 10:21:43 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","log","refs/heads/git-annex..62da8e99021b72a9255064385a75c5fe643e3711","--oneline","-n1"]
+[2013-04-24 10:21:43 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","log","refs/heads/git-annex..00cca957c30882c9dfaf494101251e4c634baa31","--oneline","-n1"]
+[2013-04-24 10:21:43 NZST] call: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","branch","-f","synced/master"]
+[2013-04-24 10:21:43 NZST] call: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","show-ref","--verify","-q","refs/remotes/bitbucket/synced/master"]
+[2013-04-24 10:21:43 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","log","refs/remotes/bitbucket/synced/master..refs/heads/synced/master","--oneline","-n1"]
+[2013-04-24 10:21:43 NZST] call: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","show-ref","--verify","-q","refs/remotes/bitbucket/git-annex"]
+[2013-04-24 10:21:43 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","log","refs/remotes/bitbucket/git-annex..git-annex","--oneline","-n1"]
+push bitbucket
+[2013-04-24 10:21:43 NZST] call: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","push","bitbucket","git-annex:synced/git-annex","master:synced/master"]
+Everything up-to-date
+ok
+"""]]
+
+
+[[!format sh """
+~/annex$ ssh -vvv -S /home/walter/annex/.git/annex/ssh/git@bitbucket.org -o ControlMaster=auto -o ControlPersist=yes -T git@bitbucket.org git-annex-shell 'configlist' '/~/waltersom/annex.git'
+OpenSSH_6.0p1 Debian-3ubuntu1, OpenSSL 1.0.1c 10 May 2012
+debug1: Reading configuration data /etc/ssh/ssh_config
+debug1: /etc/ssh/ssh_config line 19: Applying options for *
+debug1: auto-mux: Trying existing master
+debug2: fd 3 setting O_NONBLOCK
+debug2: mux_client_hello_exchange: master version 4
+debug3: mux_client_forwards: request forwardings: 0 local, 0 remote
+debug3: mux_client_request_session: entering
+debug3: mux_client_request_alive: entering
+debug3: mux_client_request_alive: done pid = 5213
+debug3: mux_client_request_session: session request sent
+debug1: mux_client_request_session: master session id: 2
+conq: invalid command syntax.
+debug3: mux_client_read_packet: read header failed: Broken pipe
+debug2: Received exit status from master 0
+"""]]
+
+
+Here is the output once I added another (non-bitbucket) repository, also without git-annex-shell
+
+[[!format sh """
+~/annex$ git annex sync --debug
+[2013-04-24 10:56:20 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","symbolic-ref","HEAD"]
+[2013-04-24 10:56:20 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","show-ref","refs/heads/master"]
+[2013-04-24 10:56:20 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","show-ref","git-annex"]
+[2013-04-24 10:56:20 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","show-ref","--hash","refs/heads/git-annex"]
+[2013-04-24 10:56:20 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","log","refs/heads/git-annex..44700457a651992eb40ff67a148d77217e8aa1d7","--oneline","-n1"]
+[2013-04-24 10:56:20 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","log","refs/heads/git-annex..94392bcdad74257adaadb98ce85d17a83da7648c","--oneline","-n1"]
+[2013-04-24 10:56:20 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","log","refs/heads/git-annex..ff126032854d9ead0a096acae04f105628de0cc4","--oneline","-n1"]
+[2013-04-24 10:56:20 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","log","refs/heads/git-annex..62da8e99021b72a9255064385a75c5fe643e3711","--oneline","-n1"]
+[2013-04-24 10:56:20 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","log","refs/heads/git-annex..00cca957c30882c9dfaf494101251e4c634baa31","--oneline","-n1"]
+[2013-04-24 10:56:20 NZST] chat: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","cat-file","--batch"]
+[2013-04-24 10:56:20 NZST] read: git ["config","--null","--list"]
+[2013-04-24 10:56:20 NZST] read: ssh ["-S","/home/walter/annex/.git/annex/ssh/waltersom_aaatos@ssh.phx.nearlyfreespeech.net","-o","ControlMaster=auto","-o","ControlPersist=yes","-T","waltersom_aaatos@ssh.phx.nearlyfreespeech.net","git-annex-shell 'configlist' '/home/protected/gitroot/test.git'"]
+waltersom_aaatos@ssh.phx.nearlyfreespeech.net's password:
+-bash: git-annex-shell: command not found
+[2013-04-24 10:56:25 NZST] call: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","fetch","--quiet","aaatos"]
+waltersom_aaatos@ssh.phx.nearlyfreespeech.net's password:
+
+ Remote aaatos does not have git-annex installed; setting remote.aaatos.annex-ignore
+[2013-04-24 10:56:30 NZST] call: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","config","remote.aaatos.annex-ignore","true"]
+[2013-04-24 10:56:30 NZST] read: ssh ["-S","/home/walter/annex/.git/annex/ssh/git@bitbucket.org","-o","ControlMaster=auto","-o","ControlPersist=yes","-T","git@bitbucket.org","git-annex-shell 'configlist' '/~/waltersom/annex.git'"]
+conq: invalid command syntax.
+[2013-04-24 10:56:30 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","ls-files","--others","--exclude-standard","--stage","-z","--","/home/walter/annex"]
+commit
+[2013-04-24 10:56:30 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","commit","-m","git-annex automatic sync"]
+ok
+[2013-04-24 10:56:30 NZST] call: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","show-ref","--verify","-q","refs/heads/synced/master"]
+[2013-04-24 10:56:30 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","log","refs/heads/master..refs/heads/synced/master","--oneline","-n1"]
+pull bitbucket
+[2013-04-24 10:56:30 NZST] call: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","fetch","bitbucket"]
+[2013-04-24 10:56:34 NZST] call: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","show-ref","--verify","-q","refs/remotes/bitbucket/master"]
+[2013-04-24 10:56:34 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","log","refs/heads/master..refs/remotes/bitbucket/master","--oneline","-n1"]
+[2013-04-24 10:56:34 NZST] call: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","show-ref","--verify","-q","refs/remotes/bitbucket/synced/master"]
+[2013-04-24 10:56:35 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","log","refs/heads/synced/master..refs/remotes/bitbucket/synced/master","--oneline","-n1"]
+ok
+pull aaatos
+[2013-04-24 10:56:35 NZST] call: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","fetch","aaatos"]
+waltersom_aaatos@ssh.phx.nearlyfreespeech.net's password:
+[2013-04-24 10:56:40 NZST] call: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","show-ref","--verify","-q","refs/remotes/aaatos/master"]
+[2013-04-24 10:56:40 NZST] call: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","show-ref","--verify","-q","refs/remotes/aaatos/synced/master"]
+[2013-04-24 10:56:40 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","log","refs/heads/synced/master..refs/remotes/aaatos/synced/master","--oneline","-n1"]
+ok
+[2013-04-24 10:56:40 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","show-ref","git-annex"]
+[2013-04-24 10:56:40 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","show-ref","--hash","refs/heads/git-annex"]
+[2013-04-24 10:56:40 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","log","refs/heads/git-annex..44700457a651992eb40ff67a148d77217e8aa1d7","--oneline","-n1"]
+[2013-04-24 10:56:40 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","log","refs/heads/git-annex..94392bcdad74257adaadb98ce85d17a83da7648c","--oneline","-n1"]
+[2013-04-24 10:56:40 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","log","refs/heads/git-annex..ff126032854d9ead0a096acae04f105628de0cc4","--oneline","-n1"]
+[2013-04-24 10:56:40 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","log","refs/heads/git-annex..62da8e99021b72a9255064385a75c5fe643e3711","--oneline","-n1"]
+[2013-04-24 10:56:40 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","log","refs/heads/git-annex..00cca957c30882c9dfaf494101251e4c634baa31","--oneline","-n1"]
+[2013-04-24 10:56:40 NZST] call: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","branch","-f","synced/master"]
+[2013-04-24 10:56:40 NZST] call: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","show-ref","--verify","-q","refs/remotes/bitbucket/synced/master"]
+[2013-04-24 10:56:40 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","log","refs/remotes/bitbucket/synced/master..refs/heads/synced/master","--oneline","-n1"]
+[2013-04-24 10:56:40 NZST] call: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","show-ref","--verify","-q","refs/remotes/bitbucket/git-annex"]
+[2013-04-24 10:56:40 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","log","refs/remotes/bitbucket/git-annex..git-annex","--oneline","-n1"]
+push bitbucket
+[2013-04-24 10:56:40 NZST] call: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","push","bitbucket","git-annex:synced/git-annex","master:synced/master"]
+Everything up-to-date
+ok
+[2013-04-24 10:56:44 NZST] call: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","show-ref","--verify","-q","refs/remotes/aaatos/synced/master"]
+[2013-04-24 10:56:44 NZST] read: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","log","refs/remotes/aaatos/synced/master..refs/heads/synced/master","--oneline","-n1"]
+[2013-04-24 10:56:44 NZST] call: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","show-ref","--verify","-q","refs/remotes/aaatos/git-annex"]
+push aaatos
+[2013-04-24 10:56:44 NZST] call: git ["--git-dir=/home/walter/annex/.git","--work-tree=/home/walter/annex","push","aaatos","git-annex:synced/git-annex","master:synced/master"]
+waltersom_aaatos@ssh.phx.nearlyfreespeech.net's password:
+Counting objects: 1363, done.
+Delta compression using up to 8 threads.
+Compressing objects: 100% (604/604), done.
+Writing objects: 100% (1363/1363), 96.41 KiB, done.
+Total 1363 (delta 709), reused 898 (delta 467)
+To waltersom_aaatos@ssh.phx.nearlyfreespeech.net:/home/protected/gitroot/test.git
+ * [new branch] git-annex -> synced/git-annex
+ * [new branch] master -> synced/master
+ok
+[2013-04-24 10:56:50 NZST] read: ssh ["-O","stop","-S","/home/walter/annex/.git/annex/ssh/waltersom_aaatos@ssh.phx.nearlyfreespeech.net","-o","ControlMaster=auto","-o","ControlPersist=yes","waltersom_aaatos@ssh.phx.nearlyfreespeech.net"]
+"""]]
+
+
+Here is the contents of .git/config (the last line was added by git annex sync)
+[[!format sh """
+[core]
+ repositoryformatversion = 0
+ filemode = true
+ bare = false
+ logallrefupdates = true
+[annex]
+ uuid = ef94eb2c-ebce-4419-900b-937c88df9aa1
+ version = 3
+ direct = true
+ diskreserve = 1 gigabyte
+ numcopies = 1
+ autocommit = true
+[gc]
+ auto = 0
+[remote "S3Sydney"]
+ annex-s3 = true
+ annex-uuid = 004d3b86-43db-4d82-9dec-347bc1b86420
+[remote "327D522A6727FE79"]
+ url = /media/walter/327D522A6727FE79/annex
+ fetch = +refs/heads/*:refs/remotes/327D522A6727FE79/*
+ annex-uuid = c9fe9266-3581-4608-aa3c-9322afd9b533
+ annex-cost = 125.0
+ annex-sync = true
+[remote "bitbucket"]
+ url = git@bitbucket.org:waltersom/annex.git
+ fetch = +refs/heads/*:refs/remotes/bitbucket/*
+[remote "aaatos"]
+ url = waltersom_aaatos@ssh.phx.nearlyfreespeech.net:/home/protected/gitroot/test.git
+ fetch = +refs/heads/*:refs/remotes/aaatos/*
+ annex-ignore = true
+"""]]
+
+> Reproduced and fixed. [[done]] --[[Joey]]
diff --git a/doc/bugs/call_to_git-annex-shell_when_on_centralised___40__non-git-annex__41___repository/comment_1_dd202a7764d9df998868d595a86ffb21._comment b/doc/bugs/call_to_git-annex-shell_when_on_centralised___40__non-git-annex__41___repository/comment_1_dd202a7764d9df998868d595a86ffb21._comment
new file mode 100644
index 000000000..50a133ac8
--- /dev/null
+++ b/doc/bugs/call_to_git-annex-shell_when_on_centralised___40__non-git-annex__41___repository/comment_1_dd202a7764d9df998868d595a86ffb21._comment
@@ -0,0 +1,30 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="you win at highlighting logs!"
+ date="2013-04-23T23:04:13Z"
+ content="""
+This weird message is coming from whatever equivilant bitbucket has of a login shell.
+
+I'd expect you would only see the message once. When git-annex notices it cannot run git-annex-shell on the remote, it automatically sets `remote.bitbucket.annex-ignore`. Once that is set, it will not try again to send/receive files from the remote. But due to the recent change I made, will still git push/pull to it.
+
+I don't see anything unexpected in the logs.. What would be unexpected is if `remote.bitbucket.annex-ignore` is set, and it tries to do this again next time it syncs. Or if `remote.bitbucket.annex-ignore` is not set to true in `.git/config`.
+
+Here is an example of how it's supposed to work:
+
+<pre>
+joey@gnu:~/tmp/rr>git annex sync
+fatal: unrecognized command 'git-annex-shell 'configlist' '/~/test.git''
+
+ Remote origin does not have git-annex installed; setting remote.origin.annex-ignore
+commit
+ok
+
+joey@gnu:~/tmp/rr>git config remote.origin.annex-ignore
+true
+
+joey@gnu:~/tmp/rr>git annex sync
+commit
+ok
+</pre>
+"""]]
diff --git a/doc/bugs/call_to_git-annex-shell_when_on_centralised___40__non-git-annex__41___repository/comment_2_ca065c82ac8e3215b581660f3e44f459._comment b/doc/bugs/call_to_git-annex-shell_when_on_centralised___40__non-git-annex__41___repository/comment_2_ca065c82ac8e3215b581660f3e44f459._comment
new file mode 100644
index 000000000..c7d4ad7c3
--- /dev/null
+++ b/doc/bugs/call_to_git-annex-shell_when_on_centralised___40__non-git-annex__41___repository/comment_2_ca065c82ac8e3215b581660f3e44f459._comment
@@ -0,0 +1,51 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnSenxKyE_2Z6Wb-EBMO8FciyRywjx1ZiQ"
+ nickname="Walter"
+ subject=":'( no format directive in comments?"
+ date="2013-04-23T23:13:02Z"
+ content="""
+That's right; `git config remote.bitbucket.annex-ignore true` does fix the problem.
+
+So, I guess if you're looking for more things to do, there is somehow a problem detecting that git-annex-shell isn't present sometimes.
+
+
+ ~/annex$ git config remote.bitbucket.annex-ignore
+ ~/annex$ git annex sync
+ conq: invalid command syntax.
+ commit
+ ok
+ pull bitbucket
+ ok
+ push bitbucket
+ Everything up-to-date
+ ok
+ ~/annex$ git annex sync
+ conq: invalid command syntax.
+ commit
+ ok
+ pull bitbucket
+ ok
+ push bitbucket
+ Everything up-to-date
+ ok
+ ~/annex$ git annex sync
+ conq: invalid command syntax.
+ commit
+ ok
+ pull bitbucket
+ ok
+ push bitbucket
+ Everything up-to-date
+ ok
+ ~/annex$ git config remote.bitbucket.annex-ignore true
+ ~/annex$ git annex sync
+ commit
+ ok
+ pull bitbucket
+ ok
+ push bitbucket
+ Everything up-to-date
+ ok
+
+
+"""]]
diff --git a/doc/bugs/call_to_git-annex-shell_when_on_centralised___40__non-git-annex__41___repository/comment_3_927a01f9961c71bedb42c519a31b5fe5._comment b/doc/bugs/call_to_git-annex-shell_when_on_centralised___40__non-git-annex__41___repository/comment_3_927a01f9961c71bedb42c519a31b5fe5._comment
new file mode 100644
index 000000000..e565eaf7a
--- /dev/null
+++ b/doc/bugs/call_to_git-annex-shell_when_on_centralised___40__non-git-annex__41___repository/comment_3_927a01f9961c71bedb42c519a31b5fe5._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-04-23T23:13:45Z"
+ content="""
+I noticed this:
+
+> debug2: Received exit status from master 0
+
+So, bitbucket prints an error message.. and exits successfully. Durrrrrr....
+
+I'll put in a fix for this if I can. FWIW, the behavior is nothing to worry about; everything will work as-is, it'll just annoyingly keep trying to ask bitbucket to please identify its repository via git-annex-shell.
+"""]]
diff --git a/doc/bugs/can__39__t_annex_get_from_annex_in_direct_mode.mdwn b/doc/bugs/can__39__t_annex_get_from_annex_in_direct_mode.mdwn
new file mode 100644
index 000000000..ca47d3a4c
--- /dev/null
+++ b/doc/bugs/can__39__t_annex_get_from_annex_in_direct_mode.mdwn
@@ -0,0 +1,23 @@
+### Please describe the problem.
+When trying to annex get *from* an annex on a Windows machine, over HTTP, annex get fails with 404 errors.
+
+### What steps will reproduce the problem?
+1. Create an annex on a Windows and Linux machine.
+2. annex add some content on Windows repository.
+3. Configure Windows repository for HTTP access
+4. on Linux machine, fetch updates. this succeeds.
+5. attempt to "annex get <new files>"
+6. requests for files of the format ".git/annex/objects/<3-char-hash>/<3-char-hash>/SHA<filehash>.<extension>" fail with 404 errors. the annex get fails.
+
+
+### What version of git-annex are you using? On what operating system?
+Windows 7: 4.20140627-g8a36ec5 (from the git-annex download page)
+
+Debian Linux: 3.20120629 (from the package manager)
+
+### Please provide any additional information below.
+there is no <filehash>.<extension> file in the relevant directories, there are only .map and .cache files. The Windows annex is in direct mode, and the Linux annex fails to annex get from this correctly.
+
+[[!meta title="can't use a direct mode repository as a http remote"]]
+
+> [[done]]; unsupported configuration. --[[Joey]]
diff --git a/doc/bugs/can__39__t_annex_get_from_annex_in_direct_mode/comment_1_20c31a844d8351a99cf69e05d2836e0e._comment b/doc/bugs/can__39__t_annex_get_from_annex_in_direct_mode/comment_1_20c31a844d8351a99cf69e05d2836e0e._comment
new file mode 100644
index 000000000..17665bd70
--- /dev/null
+++ b/doc/bugs/can__39__t_annex_get_from_annex_in_direct_mode/comment_1_20c31a844d8351a99cf69e05d2836e0e._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkxl76M-3zKZXFbFf6NY6c6y-78CSKGyJw"
+ nickname="T"
+ subject="comment 1"
+ date="2013-07-06T20:11:54Z"
+ content="""
+When I tried to duplicate these results today, it failed in a different fashion.
+
+adding a new file (file2.txt) to a test repo on windows, setting up an HTTP access, and fetching and merging onto linux leaves the following state:
+[[!format sh \"\"\"
+test-git-annex@linux_host:~/test_annex$ ls -l
+total 4
+lrwxrwxrwx 1 test-git-annex test-git-annex <datetime> file1.txt -> this is some content?
+lrwxrwxrwx 1 test-git-annex test-git-annex <datetime> file2.txt -> some new content, on a new annex
+\"\"\"]]
+
+it is treating the contents of the files as the name of a symlink. get annex get . is unable to retrieve them as contents.
+
+"""]]
diff --git a/doc/bugs/can__39__t_annex_get_from_annex_in_direct_mode/comment_2_f26e0f763f9027d9dfc08cd840ced153._comment b/doc/bugs/can__39__t_annex_get_from_annex_in_direct_mode/comment_2_f26e0f763f9027d9dfc08cd840ced153._comment
new file mode 100644
index 000000000..913f5304d
--- /dev/null
+++ b/doc/bugs/can__39__t_annex_get_from_annex_in_direct_mode/comment_2_f26e0f763f9027d9dfc08cd840ced153._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.254.222"
+ subject="comment 2"
+ date="2013-07-07T17:43:49Z"
+ content="""
+You generally cannot use a git-annex repository that is in direct mode as a remote over http. A remote git-annex does not have sufficient information to safely use a direct mode repository in that way. I don't think I can fix that. The http transport will work with indirect mode repositories (not supported on Windows), and with bare repositories (should work ok on Windows).
+
+I'm perplexed by what you show happening in the comment. It appears that the content of the files has been staged into the git repository as the symlink target on Windows. I have never seen that happen, cannot imagine how git-annex could do that. My best guess is you might have run `git commit -a` after `git annex add`, and on Windows, since it doesn't really have symlinks, that could leave the symlink bit set while staging the full content of the file. You should never run `git commit -a` in a direct mode repository (Windows always uses direct mode). See [[/direct_mode]] for caveats about git commands that are unsafe to run in direct mode.
+"""]]
diff --git a/doc/bugs/can__39__t_run_the_assistant_from_the_command_line_anymore__63__.mdwn b/doc/bugs/can__39__t_run_the_assistant_from_the_command_line_anymore__63__.mdwn
new file mode 100644
index 000000000..58828e8ca
--- /dev/null
+++ b/doc/bugs/can__39__t_run_the_assistant_from_the_command_line_anymore__63__.mdwn
@@ -0,0 +1,31 @@
+What steps will reproduce the problem?
+
+just compiled the latest version of git annex from git, checkout hash was c9c0042
+
+Tried running the assistant from the command line, got unexpected error
+
+What is the expected output? What do you see instead?
+
+Expected assistant to start, instead got:
+
+ annex$ git annex assistant
+ git-annex: watch mode is not available on this system
+
+
+What version of git-annex are you using? On what operating system?
+
+annex$ git annex version
+git-annex version: 3.20130103
+local repository version: 3
+default repository version: 3
+supported repository versions: 3
+upgrade supported from repository versions: 0 1 2
+annex$
+
+OS X Lion.
+
+
+Please provide any additional information below.
+
+> The cabal file had a typo that prevented it from using hfsevents. I'm
+> uploading a fix now. [[done]] --[[Joey]]
diff --git a/doc/bugs/can_not_add_ssh_remote_to_assistant_with___34__host:port__34___syntax.mdwn b/doc/bugs/can_not_add_ssh_remote_to_assistant_with___34__host:port__34___syntax.mdwn
new file mode 100644
index 000000000..dfe2738ef
--- /dev/null
+++ b/doc/bugs/can_not_add_ssh_remote_to_assistant_with___34__host:port__34___syntax.mdwn
@@ -0,0 +1,30 @@
+What steps will reproduce the problem?
+
+* Start the assistant
+* try to add a remote server (ssh) which is not on port 22. E.g. using myhost:1234
+* after a rather long time the connection fails
+
+
+What is the expected output? What do you see instead?
+
+it would be nice if this syntax was supported, or if an (optional) port field was provided.
+second best solution: inform the user that "myhost:1234" is not the expected format.
+third best solution (already in place) fail with "some error message".
+
+
+
+
+What version of git-annex are you using? On what operating system?
+
+3.20121016 on Ubuntu 12.04 (in future maybe also on home nas with wheezy)
+
+
+Please provide any additional information below.
+
+Thanks for a nice program and all your work on debian!
+this is not really a bug more of a wishlist feature.
+
+
+[[!tag /design/assistant]]
+
+> Ok, it has a port field now. [[done]] --[[Joey]]
diff --git a/doc/bugs/can_not_add_ssh_remote_to_assistant_with___34__host:port__34___syntax/comment_1_397eb359c3f8ef30460a9556b6f55848._comment b/doc/bugs/can_not_add_ssh_remote_to_assistant_with___34__host:port__34___syntax/comment_1_397eb359c3f8ef30460a9556b6f55848._comment
new file mode 100644
index 000000000..991a7483d
--- /dev/null
+++ b/doc/bugs/can_not_add_ssh_remote_to_assistant_with___34__host:port__34___syntax/comment_1_397eb359c3f8ef30460a9556b6f55848._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="comment 1"
+ date="2012-11-09T14:04:57Z"
+ content="""
+edit ~/.ssh/config. add
+
+ Host myhost
+ Port 1234
+
+
+now you never have to specify the port again(for ssh,scp,rsync,etc)
+"""]]
diff --git a/doc/bugs/cannot_add_file__44___get___34__user_error__34__.mdwn b/doc/bugs/cannot_add_file__44___get___34__user_error__34__.mdwn
new file mode 100644
index 000000000..398cda3b6
--- /dev/null
+++ b/doc/bugs/cannot_add_file__44___get___34__user_error__34__.mdwn
@@ -0,0 +1,32 @@
+What steps will reproduce the problem?
+
+I can reproduce it locally:
+
+ % annex -d add Eigene\ Bilder/
+ [2013-03-19 15:44:01 CET] read: git ["--git-dir=/Users/fschulze/Bilder/.git","--work-tree=/Users/fschulze/Bilder","ls-files","--others","--exclude-standard","-z","--","Eigene Bilder/"]
+ [2013-03-19 15:44:01 CET] read: git ["--git-dir=/Users/fschulze/Bilder/.git","--work-tree=/Users/fschulze/Bilder","diff","--name-only","--diff-filter=T","-z","--","Eigene Bilder/"]
+ add Eigene Bilder/20070311/Bild023.jpg [2013-03-19 15:44:01 CET] chat: git ["--git-dir=/Users/fschulze/Bilder/.git","--work-tree=/Users/fschulze/Bilder","check-attr","-z","-- stdin","annex.backend","annex.numcopies","--"]
+ (checksum...) [2013-03-19 15:44:01 CET] read: sha512sum ["/Users/fschulze/Bilder/.git/annex/tmp/Bild02366551.jpg"]
+
+git-annex: user error (sha512sum ["/Users/fschulze/Bilder/.git/annex/tmp/Bild02366551.jpg"] exited 127)
+failed
+
+What is the expected output? What do you see instead?
+
+The file isn't added.
+
+What version of git-annex are you using? On what operating system?
+
+OS X from dmg
+
+ git-annex version: 4.20130314
+ local repository version: 3
+ default repository version: 3
+ supported repository versions: 3 4
+ upgrade supported from repository versions: 0 1 2
+ build flags: Assistant Webapp Pairing Testsuite S3 WebDAV FsEvents XMPP DNS
+
+> The OSX app is now changed so that git-annex is a wrapper
+> script using runshell. This allows putting `git-annex.app/Contents/MacOS`
+> into PATH and using git-annex, and it will find all the libraries and
+> utilities bundled with it. [[done]] --[[Joey]]
diff --git a/doc/bugs/cannot_add_file__44___get___34__user_error__34__/comment_1_14aa717c1befcbbf526f25ca2f0af825._comment b/doc/bugs/cannot_add_file__44___get___34__user_error__34__/comment_1_14aa717c1befcbbf526f25ca2f0af825._comment
new file mode 100644
index 000000000..87855ab4b
--- /dev/null
+++ b/doc/bugs/cannot_add_file__44___get___34__user_error__34__/comment_1_14aa717c1befcbbf526f25ca2f0af825._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-03-19T17:19:32Z"
+ content="""
+What version of OSX is this? From what url did you download the dmg?
+
+Have you run \"runshell\" to get the shell you're using git-annex in?
+
+What happens if you run sha512sum on the file yourself?
+
+The SHA512 backend is not the default backend used by git-annex. Is the default SHA256 backend working?
+"""]]
diff --git a/doc/bugs/cannot_add_file__44___get___34__user_error__34__/comment_2_7f7ac59e7f3dce9d7a7d0c3379c2edcf._comment b/doc/bugs/cannot_add_file__44___get___34__user_error__34__/comment_2_7f7ac59e7f3dce9d7a7d0c3379c2edcf._comment
new file mode 100644
index 000000000..0e9b034c0
--- /dev/null
+++ b/doc/bugs/cannot_add_file__44___get___34__user_error__34__/comment_2_7f7ac59e7f3dce9d7a7d0c3379c2edcf._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawla3gLc6_rHuggFfy7o7eGMPvPztFZTrUQ"
+ nickname="Florian"
+ subject="comment 2"
+ date="2013-03-19T17:42:00Z"
+ content="""
+OS X Lion 10.7.5
+http://downloads.kitenet.net/git-annex/OSX/current/10.7.5_Lion/git-annex.dmg.bz2
+
+What is \"runshell\"? I used the binary from inside the app, maybe that's the issue? How am I supposed to use it from the command line? I had used a 2012 version installed via cabal before, but upgrading it didn't work anymore. I got lot's of errors from various cabal packages when I tried.
+
+Directly it seems to work fine:
+
+% ~/Applications/git-annex.app/Contents/MacOS/sha512sum Eigene\ Bilder/20070311/Bild023.jpg
+96d61ed877bcd5c9b5935aca77a1eae78bcb577d5c7aa049b247861bbcd4122ff3c2280ea6dc6152bc843e73c006281614c28d14bdd70aa1692f948e8f19bf4c Eigene Bilder/20070311/Bild023.jpg
+
+I'm actually using SHA512E. I will try later to reproduce with just that file in another repository. Is there anything else I can provide?
+"""]]
diff --git a/doc/bugs/cannot_add_file__44___get___34__user_error__34__/comment_3_5ebf03120b12edb3fbb8954546e7603e._comment b/doc/bugs/cannot_add_file__44___get___34__user_error__34__/comment_3_5ebf03120b12edb3fbb8954546e7603e._comment
new file mode 100644
index 000000000..8db2a8ea1
--- /dev/null
+++ b/doc/bugs/cannot_add_file__44___get___34__user_error__34__/comment_3_5ebf03120b12edb3fbb8954546e7603e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-03-19T18:17:23Z"
+ content="""
+`~/Applications/git-annex.app/Contents/MacOS/runshell` is a little program that sets up your shell to use the programs, and crucially, the libraries, included in the dmg. Running binaries from the app directly and not through runshell is not likely to work. I have updated [[the_OSX_page|/install/OSX]] with information about runshell.
+"""]]
diff --git a/doc/bugs/cannot_add_file__44___get___34__user_error__34__/comment_4_1ba6d2614778949520b47896fd98b598._comment b/doc/bugs/cannot_add_file__44___get___34__user_error__34__/comment_4_1ba6d2614778949520b47896fd98b598._comment
new file mode 100644
index 000000000..383f21f1c
--- /dev/null
+++ b/doc/bugs/cannot_add_file__44___get___34__user_error__34__/comment_4_1ba6d2614778949520b47896fd98b598._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawla3gLc6_rHuggFfy7o7eGMPvPztFZTrUQ"
+ nickname="Florian"
+ subject="comment 4"
+ date="2013-03-19T21:18:19Z"
+ content="""
+Using runshell solved the problem, but for my usecases I'm not happy with that. I guess I'll try with a clean cabal again.
+"""]]
diff --git a/doc/bugs/cannot_add_file__44___get___34__user_error__34__/comment_5_4a6e55861a63b350a02edb888b4da99b._comment b/doc/bugs/cannot_add_file__44___get___34__user_error__34__/comment_5_4a6e55861a63b350a02edb888b4da99b._comment
new file mode 100644
index 000000000..1baec9625
--- /dev/null
+++ b/doc/bugs/cannot_add_file__44___get___34__user_error__34__/comment_5_4a6e55861a63b350a02edb888b4da99b._comment
@@ -0,0 +1,21 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 5"
+ date="2013-03-19T22:53:30Z"
+ content="""
+Well, one way to use runshell without annoyance is to put a git-annex wrapper in ~/bin
+like this:
+
+<pre>
+#!/bin/sh
+~/Applications/git-annex.app/Contents/MacOS/runshell git-annex \"$@\"
+</pre>
+
+I think I will repurpose this bug report: The git-annex inside the dmg should
+be such a wrapper, so that it can just be put into PATH and used. The actual binaries in the dmg should be hidden away in a subdirectory where users won't stumble over them.
+
+----
+
+However, cabal is a fine choice.
+"""]]
diff --git a/doc/bugs/cannot_connect_to_xmpp_server.mdwn b/doc/bugs/cannot_connect_to_xmpp_server.mdwn
new file mode 100644
index 000000000..d64b64003
--- /dev/null
+++ b/doc/bugs/cannot_connect_to_xmpp_server.mdwn
@@ -0,0 +1,32 @@
+I cannot get the assistant to connect to my jabber account, db48x@db48x.net. I get the message stating that it may take a minute, which is never updated. At the very least I would expect some sort of error message.
+
+I get the same symptoms if I connect to an account @gmail.com, but type in the wrong password. If I put in the correct password, it connects quite quickly.
+
+### What version of git-annex are you using? On what operating system?
+
+[[!format txt """
+[db48x@celebdil ~]$ git annex version
+git-annex version: 4.20130709
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP DNS
+[db48x@celebdil ~]$ uname -a
+Linux celebdil 3.9.9-201.fc18.x86_64 #1 SMP Fri Jul 5 16:42:02 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
+"""]]
+
+(Fedora 18)
+
+I get exactly the same behavior on my phone, which is running Android 4.1.2
+
+
+### Please provide any additional information below.
+
+[[!format txt """
+[db48x@celebdil books]$ cat .git/annex/daemon.log
+[2013-07-20 16:21:28 PDT] main: starting assistant version 4.20130709
+(scanning...) [2013-07-20 16:21:28 PDT] Watcher: Performing startup scan
+(started...)
+"""]]
+
+> Closing this bug, since it's not something I can fix in git-annex,
+> but would have to be dealt with in the haskell XMPP library.
+> Which seems unlikely given John's reply, but you never know --
+> and the bug I filed is still open ;) [[done]] --[[Joey]]
diff --git a/doc/bugs/cannot_connect_to_xmpp_server/comment_10_5072de8fcca9fe70bc235ea8c8ee2877._comment b/doc/bugs/cannot_connect_to_xmpp_server/comment_10_5072de8fcca9fe70bc235ea8c8ee2877._comment
new file mode 100644
index 000000000..5e2839db2
--- /dev/null
+++ b/doc/bugs/cannot_connect_to_xmpp_server/comment_10_5072de8fcca9fe70bc235ea8c8ee2877._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.140"
+ subject="comment 10"
+ date="2013-07-21T03:58:35Z"
+ content="""
+Upstream bug report: <http://bugs.debian.org/717463>
+"""]]
diff --git a/doc/bugs/cannot_connect_to_xmpp_server/comment_11_dabd74bba1f38b326a2d0c86d3027cd9._comment b/doc/bugs/cannot_connect_to_xmpp_server/comment_11_dabd74bba1f38b326a2d0c86d3027cd9._comment
new file mode 100644
index 000000000..2ceb4c08f
--- /dev/null
+++ b/doc/bugs/cannot_connect_to_xmpp_server/comment_11_dabd74bba1f38b326a2d0c86d3027cd9._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="https://john-millikin.com/"
+ nickname="John Millikin"
+ subject="comment 11"
+ date="2013-07-22T01:52:41Z"
+ content="""
+(I'm the author of the XMPP library git-annex uses)
+
+The biggest issue I can think of with continuing in the absence of a &lt;features&gt; element is authentication. Without &lt;features&gt; the client library is not able to know which SASL mechanisms are supported, so it can't authenticate.
+
+It is possible to modify the XMPP library such that it can work around the problems exibited by this server software (adding a timeout to receipt, hardcoding a fallback SASL list), but I very much do not want to do that because it would almost certainly cause unexpected behavior when used with properly working servers.
+
+According to <a href=\"http://www.mail-archive.com/jdev@jabber.org/msg10598.html\">http://www.mail-archive.com/jdev@jabber.org/msg10598.html</a> , jabberd-1.4.3 was released in 2003. Since its release, there have been multiple severe security issues discovered, including a remote crash (see <a href=\"http://mail.jabber.org/pipermail/jabberd/2004-September/002004.html\">http://mail.jabber.org/pipermail/jabberd/2004-September/002004.html</a> and <a href=\"http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2004-1378\">http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2004-1378</a>).
+
+In my opinion, the best course of action is for Daniel to switch to a different Jabber server software, preferably one that is still actively maintained.
+
+"""]]
diff --git a/doc/bugs/cannot_connect_to_xmpp_server/comment_12_0245b426cc0ab64f8c167b8806b03f5d._comment b/doc/bugs/cannot_connect_to_xmpp_server/comment_12_0245b426cc0ab64f8c167b8806b03f5d._comment
new file mode 100644
index 000000000..18f956c3e
--- /dev/null
+++ b/doc/bugs/cannot_connect_to_xmpp_server/comment_12_0245b426cc0ab64f8c167b8806b03f5d._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5WyknJirJJridJjiPNgrlYxGG9xrZBvA"
+ nickname="Daniel"
+ subject="comment 12"
+ date="2013-07-23T00:59:33Z"
+ content="""
+oh, I agree that upgrading is sensible, but I don't actually control the server. Also, I don't see anything in the changelog that indicates that this bug has been fixed. The bug database is out of action as well. A brief examination of the source didn't answer any questions either. Very annoying all around.
+
+Just think of it as adding robustness in the face of a misbehaving server.
+"""]]
diff --git a/doc/bugs/cannot_connect_to_xmpp_server/comment_1_307df11b5bcf289d7999e1e7f7c461c9._comment b/doc/bugs/cannot_connect_to_xmpp_server/comment_1_307df11b5bcf289d7999e1e7f7c461c9._comment
new file mode 100644
index 000000000..1ad583ec7
--- /dev/null
+++ b/doc/bugs/cannot_connect_to_xmpp_server/comment_1_307df11b5bcf289d7999e1e7f7c461c9._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.140"
+ subject="comment 1"
+ date="2013-07-21T01:20:32Z"
+ content="""
+I've fixed the gmail.com problem. It was trying all the servers returned by the SRV query, which all failed due to the bad password, and then fell back to trying gmail.com directly. For whatever reason, gmail.com will accept XMPP connections, but never responds to traffic, so it hung.
+
+The hang with your own XMPP server does not seem related to that.
+"""]]
diff --git a/doc/bugs/cannot_connect_to_xmpp_server/comment_2_f24378cf30a7d32594da90749fabec3c._comment b/doc/bugs/cannot_connect_to_xmpp_server/comment_2_f24378cf30a7d32594da90749fabec3c._comment
new file mode 100644
index 000000000..39c69b5ea
--- /dev/null
+++ b/doc/bugs/cannot_connect_to_xmpp_server/comment_2_f24378cf30a7d32594da90749fabec3c._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.140"
+ subject="comment 2"
+ date="2013-07-21T01:26:49Z"
+ content="""
+It seems to start to connect to db48x.net, and hang. It may be failing to parse the response about the password being bad, or something like that, and be sitting around waiting for a response. I'm not sure.
+
+What XMPP server software are you using?
+
+The next step would probably be to get a tcpdump of the XMPP connection, ideally with SSL disabled. (Assuming the hang is not occuring during the SSL setup.)
+"""]]
diff --git a/doc/bugs/cannot_connect_to_xmpp_server/comment_3_4b07093be844ac62b611cee1dfde5aa7._comment b/doc/bugs/cannot_connect_to_xmpp_server/comment_3_4b07093be844ac62b611cee1dfde5aa7._comment
new file mode 100644
index 000000000..b396e97a1
--- /dev/null
+++ b/doc/bugs/cannot_connect_to_xmpp_server/comment_3_4b07093be844ac62b611cee1dfde5aa7._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5WyknJirJJridJjiPNgrlYxGG9xrZBvA"
+ nickname="Daniel"
+ subject="comment 3"
+ date="2013-07-21T02:26:38Z"
+ content="""
+I captured the connection attempt; the trace is at <http://db48x.net/temp/annex-xmpp-connection.pcap.gz>
+"""]]
diff --git a/doc/bugs/cannot_connect_to_xmpp_server/comment_4_fe1ed152a485c4aebfa9b9f300101835._comment b/doc/bugs/cannot_connect_to_xmpp_server/comment_4_fe1ed152a485c4aebfa9b9f300101835._comment
new file mode 100644
index 000000000..89c66d173
--- /dev/null
+++ b/doc/bugs/cannot_connect_to_xmpp_server/comment_4_fe1ed152a485c4aebfa9b9f300101835._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5WyknJirJJridJjiPNgrlYxGG9xrZBvA"
+ nickname="Daniel"
+ subject="comment 4"
+ date="2013-07-21T02:45:52Z"
+ content="""
+Comparing that to when I connect to gmail, I see that my server isn't sending any stream features; my server doesn't support TLS.
+"""]]
diff --git a/doc/bugs/cannot_connect_to_xmpp_server/comment_5_2d311f520aee04287df6bddfd8535734._comment b/doc/bugs/cannot_connect_to_xmpp_server/comment_5_2d311f520aee04287df6bddfd8535734._comment
new file mode 100644
index 000000000..62e038941
--- /dev/null
+++ b/doc/bugs/cannot_connect_to_xmpp_server/comment_5_2d311f520aee04287df6bddfd8535734._comment
@@ -0,0 +1,28 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.140"
+ subject="comment 5"
+ date="2013-07-21T02:55:36Z"
+ content="""
+Great. We can see git-annex opens the XMPP stream tag, and your server responds by opening its own tag.
+
+Compare with this similar conversation:
+
+ joey@gnu:~>telnet kite 5222
+ Trying 80.68.85.49...
+ Connected to wren.kitenet.net.
+ Escape character is '^]'.
+ <?xml version='1.0'?>
+ <stream:stream xmlns=\"jabber:client\" to=\"kitenet.net\" version=\"1.0\" xmlns:stream=\"http://etherx.jabber.org/streams\">
+ <?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' id='e7d73883-a362-4923-89f8-0531eb9d16a0' from='kitenet.net' version='1.0' xml:lang='en'><stream:features>
+
+So far it's the same as the conversation with your server, but now my server goes on to send another line:
+
+ <stream:features><starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/><mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'> <mechanism>SCRAM-SHA-1</mechanism><mechanism>DIGEST-MD5</mechanism></mechanisms></stream:features>
+
+While your server does not send anything.
+
+I see that my XMPP client library expects to receive a features tag at this point. Until it does, it won't continue. It may be that your server is not sending the features because it does not implement TLS or any of the other features that need to be advertised.
+
+I think I need to report this to the author of the XMPP client library. It would help to know what XMPP server software you're using, and if it has TLS support enabled.
+"""]]
diff --git a/doc/bugs/cannot_connect_to_xmpp_server/comment_6_d9f916f012184738446c5996ee9d2270._comment b/doc/bugs/cannot_connect_to_xmpp_server/comment_6_d9f916f012184738446c5996ee9d2270._comment
new file mode 100644
index 000000000..5bcc63d20
--- /dev/null
+++ b/doc/bugs/cannot_connect_to_xmpp_server/comment_6_d9f916f012184738446c5996ee9d2270._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.140"
+ subject="comment 6"
+ date="2013-07-21T03:07:41Z"
+ content="""
+If the initiating entity includes in the initial stream header the 'version' attribute set to a value of at least \"1.0\" (see Section 4.7.5), after sending the response stream header the receiving entity MUST send a <features/> child element
+
+-- <http://xmpp.org/rfcs/rfc6120.html#streams-negotiation>\"
+
+By my reading this XMPP server is not RFC compliant. It's not clear to me if there's a good way for the XMPP client
+to cater to XMPP servers that neglect to send at least an empty features tag.
+"""]]
diff --git a/doc/bugs/cannot_connect_to_xmpp_server/comment_7_0b5f9350e2367301241c7668a15815ef._comment b/doc/bugs/cannot_connect_to_xmpp_server/comment_7_0b5f9350e2367301241c7668a15815ef._comment
new file mode 100644
index 000000000..bcb47e20a
--- /dev/null
+++ b/doc/bugs/cannot_connect_to_xmpp_server/comment_7_0b5f9350e2367301241c7668a15815ef._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5WyknJirJJridJjiPNgrlYxGG9xrZBvA"
+ nickname="Daniel"
+ subject="comment 7"
+ date="2013-07-21T03:08:52Z"
+ content="""
+My server doesn't support TLS at all, and I don't really know what software it is (It's just a freebie that comes with the webhosting for the domain, I don't actually administer it myself). I'll try to find out, perhaps it's something an upgrade can fix.
+"""]]
diff --git a/doc/bugs/cannot_connect_to_xmpp_server/comment_8_f00b6ae154004e405f0bd23b7359962e._comment b/doc/bugs/cannot_connect_to_xmpp_server/comment_8_f00b6ae154004e405f0bd23b7359962e._comment
new file mode 100644
index 000000000..06311fb13
--- /dev/null
+++ b/doc/bugs/cannot_connect_to_xmpp_server/comment_8_f00b6ae154004e405f0bd23b7359962e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5WyknJirJJridJjiPNgrlYxGG9xrZBvA"
+ nickname="Daniel"
+ subject="comment 8"
+ date="2013-07-21T03:10:25Z"
+ content="""
+Oh, and I agree with your reading of the spec; I was just looking that up myself. I will point out that most other software apparently treats a missing features tag as if it were an empty one, so it's certainly doable :)
+"""]]
diff --git a/doc/bugs/cannot_connect_to_xmpp_server/comment_9_41b86468013da15f46be29da520afa10._comment b/doc/bugs/cannot_connect_to_xmpp_server/comment_9_41b86468013da15f46be29da520afa10._comment
new file mode 100644
index 000000000..67bec739e
--- /dev/null
+++ b/doc/bugs/cannot_connect_to_xmpp_server/comment_9_41b86468013da15f46be29da520afa10._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5WyknJirJJridJjiPNgrlYxGG9xrZBvA"
+ nickname="Daniel"
+ subject="comment 9"
+ date="2013-07-21T03:24:03Z"
+ content="""
+It's jabberd 1.4.3. Unfortunately the jabberd14 webpage is rather broken; I can't get to the bugzilla or even the svn or downloads page so I don't know if this is a known bug, something that's been fixed in a newer version, or anything.
+"""]]
diff --git a/doc/bugs/cannot_determine_uuid_for_origin.mdwn b/doc/bugs/cannot_determine_uuid_for_origin.mdwn
new file mode 100644
index 000000000..611a0f236
--- /dev/null
+++ b/doc/bugs/cannot_determine_uuid_for_origin.mdwn
@@ -0,0 +1,135 @@
+[[!toc]]
+
+### Please describe the problem.
+
+I get this error when trying to copy annexed files from my laptop to the bare repository on my server:
+
+ anarcat@angela:ohm2013$ git annex copy -t origin .
+ git-annex: cannot determine uuid for origin
+
+### What steps will reproduce the problem?
+
+Here's my setup:
+
+ * `angela`: regular git repository on my laptop (`angela`) where i ran `git annex init` and `git annex add`ed 4 big files (in `~anarcat/presentations/ohm2013`)
+ * `marcos-bare`: a bare git repository where i ran `git annex init` on a different server (`marcos`) (in `~anarcat/repos/presentations/ohm2013.git`)
+ * `marcos-checkout`: a checkout of the above repository on marcos (in `~anarcat/presentations/ohm2013`)
+
+I ran `git pull/push` everwhere in there, and still get the error.
+
+Remotes on all repos:
+
+ * `angela`: `origin anarcat.ath.cx:repos/presentations/ohm2013.git`
+ * `marcos-bare`: no remote
+ * `marcos-checkout`: `origin /home/anarcat/repos/presentations/ohm2013.git`
+
+Note that file added with `git annex addurl` on `marcos-checkout` properly gets propagated on `angela` once i do `git annex get` there.
+
+### What version of git-annex are you using? On what operating system?
+
+`angela` runs:
+
+[[!format txt """
+git-annex version: 4.20130730-ge59a8c6
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP DNS
+local repository version: 3
+default repository version: 3
+supported repository versions: 3 4
+upgrade supported from repository versions: 0 1 2
+"""]]
+
+I was able to reproduce with the backport version too.
+
+I compiled it by hand from git.
+
+`marcos` runs:
+
+[[!format txt """
+git-annex version: 3.20120629
+local repository version: unknown
+default repository version: 3
+supported repository versions: 3
+upgrade supported from repository versions: 0 1 2
+"""]]
+
+### Please provide any additional information below.
+
+In addition, there's this error on `marcos-bare`:
+
+[[!format sh """
+anarcat@marcos:ohm2013.git$ git annex status -d
+supported backends: SHA256 SHA1 SHA512 SHA224 SHA384 SHA256E SHA1E SHA512E SHA224E SHA384E WORM URL
+supported remote types: git S3 bup directory rsync web hook
+trusted repositories: git ["--git-dir=/home/anarcat/repos/presentations/ohm2013.git","show-ref","git-annex"]
+git ["--git-dir=/home/anarcat/repos/presentations/ohm2013.git","show-ref","--hash","refs/heads/git-annex"]
+git ["--git-dir=/home/anarcat/repos/presentations/ohm2013.git","log","refs/heads/git-annex..6063e958c02259a39b87d0f1dc44c9272c52df3f","--oneline","-n1"]
+git ["--git-dir=/home/anarcat/repos/presentations/ohm2013.git","cat-file","--batch"]
+0
+semitrusted repositories: 4
+ 00000000-0000-0000-0000-000000000001 -- web
+ 5868f840-02e7-11e3-94e9-9b3701bd28bb -- marcos-checkout
+ aafdd242-02e7-11e3-bb6a-6f16a5c6103e -- here (marcos-bare)
+ befc3057-d23d-4312-843a-0645e93107d8 -- angela
+untrusted repositories: 0
+dead repositories: 0
+available local disk space: 14 gigabytes (+1 megabyte reserved)
+local annex keys: 0
+local annex size: 0 bytes
+known annex keys: git ["--git-dir=/home/anarcat/repos/presentations/ohm2013.git","ls-files","--cached","-z","--","/home/anarcat/repos/presentations/ohm2013.git"]
+fatal: '/home/anarcat/repos/presentations/ohm2013.git' is outside repository
+0
+known annex size: 0 bytes
+bloom filter size: 16 mebibytes (0% full)
+backend usage:
+"""]]
+
+### Workaround!
+
+I found that I could succesfully push to the non-bare repo, like this:
+
+[[!format txt """
+anarcat@angela:ohm2013$ git remote add marcos-checkout ssh://anarcat.ath.cx/~/presentations/ohm2013
+anarcat@angela:ohm2013$ git fetch marcos-checkout
+From ssh://anarcat.ath.cx/~/presentations/ohm2013
+ * [new branch] git-annex -> marcos-checkout/git-annex
+ * [new branch] master -> marcos-checkout/master
+anarcat@angela:ohm2013$ git annex copy AlerteRouge.webm --to marcos-checkout
+copy AlerteRouge.webm (checking marcos-checkout...) (to marcos-checkout...)
+SHA256E-s138903105--a69db8d4c3835b03bdb08cb1cccfde5c76f586f934d63283694e7101b25352a8.webm
+[...]
+"""]]
+
+It seems that git-annex doesn't like bare repos at all...
+
+### Fix
+
+It seems that my problem was specifically related to [[bare repositories]], which are not well supported historically. There has been other reports of problems in the past, which I missed in my search because symptoms were different:
+
+ * [[bugs/bare git repos]]
+ * [[forum/get and copy with bare repositories]]
+
+Yet while I was able to do `git annex get --all` *from* the `marcos-bare` repository, I still get the original error message while trying to `git annex copy -t marcos-bare`, which is pretty annoying considering the original files are on my laptop, which is not publicly accessible. So I basically need to add the `marcos-checkout` as a remote, copy there, then get from the bare repo to make this work, which is a rather convoluted way of doing things. :)
+
+It seems to me a proper fix would be to be able to `git annex copy --to marcos-bare`. Thanks!
+
+Update: it seems te problem was that I had the following in my `.git/config`:
+
+ [remote "marcos-bare"]
+ url = ssh://anarcat.ath.cx/~/repos/presentations/ohm2013.git
+ annex-ignore = true
+ fetch = +refs/heads/*:refs/remotes/marcos-bare/*
+
+I have *no* idea how that `annex-ignore` got there, but that was the root of my problem. Removing it it allowed my to do `git annex copy`. I really don't know how this happened, but I guess this is [[done]], although I believe this error message is really confusing and could be improved. --[[anarcat]]
+
+> `annex-ignore` is set automatically by git-annex if it fails to query
+> the uuid of a remote the first time it tries to use it. It will say
+> when it does that. The assumption
+> is that a remote whose uuid cannot be looked up is a git remote
+> on a server w/o git-annex support (like github) and it would be annoying
+> to constantly be trying and failing to get that uuid.
+>
+> So, I've improved the error message. Now when annex-ignore is set
+> for a remote, the error you got will mention that.
+>
+> (Also, there is not currently anything lacking in git-annex's support
+> for bare repositories.) --[[Joey]]
diff --git a/doc/bugs/cannot_link_executable_on_android.mdwn b/doc/bugs/cannot_link_executable_on_android.mdwn
new file mode 100644
index 000000000..cb660dd9c
--- /dev/null
+++ b/doc/bugs/cannot_link_executable_on_android.mdwn
@@ -0,0 +1,28 @@
+### Please describe the problem.
+Then starting git-annex on my Galaxy Nexus Android device, in the terminal window I get:
+
+[[!format sh """
+Falling back to hardcoded app location: cannot find expected files in /data/app-lib
+git annex webapp
+u0_a123@maguro:/sdcad/git-annex.home $ git annex webapp
+CANNOT LINK EXECUTABLE: git-annex invalid R_ARM_COPY relocation against DT_SYMBOLIC shared library libc.so (built with -Bsymbolic?)
+u0_a123@maguro:/sdcad/git-annex.home $
+"""]]
+
+### What steps will reproduce the problem?
+Start git-annex.
+
+### What version of git-annex are you using? On what operating system?
+Nightly build and release from a few days ago - 1.0.52
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
+
+> [[dup|done]] of [[git-annex_broken_on_Android_4.3]].--[[Joey]]
diff --git a/doc/bugs/case-insensitive.mdwn b/doc/bugs/case-insensitive.mdwn
new file mode 100644
index 000000000..a917f64c2
--- /dev/null
+++ b/doc/bugs/case-insensitive.mdwn
@@ -0,0 +1,20 @@
+What steps will reproduce the problem?
+
+> Building git-annex on the ghc7.0 branch on a Mac with the default case-insensitive file system
+
+What is the expected output? What do you see instead?
+
+> Expected: build successfully; instead:
+
+ ld: duplicate symbol _UtilityziDiskFree_zdwa_info in dist/build/git-annex/git-annex-tmp/Utility/diskfree.o and dist/build/git-annex/git-annex-tmp/Utility/DiskFree.o for architecture x86_64
+
+What version of git-annex are you using? On what operating system?
+
+> commit `0bd5c90ef0518f75d52f0c5889422d8233df847d` on a Mac OS 10.6 and 10.7, using the Haskell Platform 2012.04
+
+Please provide any additional information below.
+
+> The problem is that since `DiskFree.hs` generates `DiskFree.o` and `diskfree.c` generates `diskfree.o`, a case-insensitive file system overwrites one object file with the other. Renaming `diskfree.c` to `diskfreec.c` and changing the corresponding filenames in `git-annex.cabal` fixes the problem.
+
+>> Man, not this again. The 80's called, they want their
+>> unix portability wars back. [[fixed|done]]. --[[Joey]]
diff --git a/doc/bugs/case_sensitivity_on_FAT.mdwn b/doc/bugs/case_sensitivity_on_FAT.mdwn
new file mode 100644
index 000000000..682acc71d
--- /dev/null
+++ b/doc/bugs/case_sensitivity_on_FAT.mdwn
@@ -0,0 +1,49 @@
+I was copying files to a directory remote with `git annex copy`. Out of 114 files, 9 of them failed with no message, just:
+
+ copy data/foo.dat (to usbdrive...) failed
+ copy data/bar.dat (to usbdrive...) failed
+
+According to strace:
+
+ 31338 mkdir("/media/annex/Zp/9v/SHA256-s1362999320--d650297c8cf8c2dc0575110a52d0c5cc0ff266f294a0599f85796a6b44b23492", 0777) = -1 ENOENT (No such file or directory)
+ 31338 mkdir("/media/annex/Zp/9v", 0777) = -1 ENOENT (No such file or directory)
+ 31338 mkdir("/media/annex/Zp", 0777) = -1 EEXIST (File exists)
+ 31338 stat("/media/annex/Zp", 0x7f8449f170d0) = -1 ENOENT (No such file or directory)
+
+The filesystem is FAT32 and has weird case semantics. This was mounted by udisks with its default options:
+
+ /dev/sdb1 on /media/annex type vfat (rw,nosuid,nodev,uhelper=udisks,uid=1000,gid=1000,shortname=mixed,dmask=0077,utf8=1,showexec)
+
+I wonder if the directory remote should use hashDirLower instead of hashDirMixed?
+
+> git-annex intentionally uses the same layout for directory and rsync
+> special remotes as it does for the .git/annex directory. As far
+> as I know it works ok on (truely) case-insensative filesystems.
+>
+> Based on your strace, if you `ls /media/annex/Zp`, you will see
+> "No such file or directory", but if you `mkdir /media/annex/Zp` it will
+> fail with "File exists". Doesn't make much sense to me.
+>
+> The (default) VFAT mount option shortname=mixed causes this behavior.
+> With shortname=lower it works ok. --[[Joey]]
+>
+>> So, the options for fixing this bug seem to be to fix Linux (which would
+>> be a good idea IMHO but I don't really want to go there), or generally
+>> convert git-annex to using lowercase for its hashing (which would be a
+>> large amount of pain to rewrite all the symlinks in every git repo),
+>> or some special hack around this problem.
+>>
+>> I've put in a workaround for the problem in the directory special
+>> remote; it will use mixed case but fall-back to lowercase as necessary.
+>>
+>> That does leave the case of a bare git repository with annexed content
+>> stored on VFAT. More special casing could fix it, but that is, I
+>> think, an unusual configuration. Leaving the bug open for that case,
+>> and for the even more unlikely configuration of a rsync special remote
+>> stored on VFAT. --[[Joey]]
+
+>>> Bare repositories now use lowercase. rsync is the only remaining
+>>> unsupported possibility. --[[Joey]]
+>>>> Everything now uses lowercase, with the exception of non-bare
+>>>> repos, which cannot be on FAT anyway due to using symlinks. [[done]]
+>>>> --[[Joey]]
diff --git a/doc/bugs/check_for_curl_in_configure.hs.mdwn b/doc/bugs/check_for_curl_in_configure.hs.mdwn
new file mode 100644
index 000000000..a880392bf
--- /dev/null
+++ b/doc/bugs/check_for_curl_in_configure.hs.mdwn
@@ -0,0 +1,92 @@
+[[!meta title="arbitrary/configurable backends"]]
+
+(Retitling as this has drifted..)
+
+---
+
+I thought this might be useful, since curl is being used for the URL backend, it might be worth checking for it's existence.
+
+<pre>
+diff --git a/configure.hs b/configure.hs
+index 772ba54..1a563e0 100644
+--- a/configure.hs
++++ b/configure.hs
+@@ -13,6 +13,7 @@ tests = [
+ , TestCase "uuid generator" $ selectCmd "uuid" ["uuid", "uuidgen"]
+ , TestCase "xargs -0" $ requireCmd "xargs_0" "xargs -0 </dev/null"
+ , TestCase "rsync" $ requireCmd "rsync" "rsync --version >/dev/null"
++ , TestCase "curl" $ requireCmd "curl" "curl --version >/dev/null"
+ , TestCase "unicode FilePath support" $ unicodeFilePath
+ ] ++ shaTestCases [1, 256, 512, 224, 384]
+</pre>
+
+> Well, curl is an optional extra, so requireCmd is too strong. Changed
+> to testCmd and applied, thank you!
+>
+> I thought about actually *using* the resulting SysConfig.curl
+> to disable the URL backend if False.. but probably it's better
+> to just let it fail if curl is not available. Although, if we wanted
+> to add a check for wget or something and use it when curl was not
+> available, that might be worth doing. --[[Joey]]
+
+>> I was thinking that is it worth doing a generic "stat", "delete", "get"
+>> and "put" options, I do like the idea of having the possibility of
+>> being about to use completely arbitrary storage systems or arbitrary
+>> transfer systems. If there was the capability of doing so it would be
+>> interesting to see possibilities of using aria2 for using something
+>> like bittorrent as backend, or using something like irods or some
+>> grid storage system as the storage archive. It's just an idea as
+>> I have seen it implemented quite well in irods.
+
+>>> I'm unsure about the idea of having a backend where that is
+>>> parameterized. It would mean that one annex's GENERIC-foo key
+>>> might be entirely different from another's key with the same backend
+>>> and details. And a misconfiguration could get data the wrong
+>>> way and get the wrong data, etc.
+>>>
+>>> I mostly look at the URL backend as an example that can be modified to
+>>> make this kind of custom backend. You already probably know enough to
+>>> make a TORRENT backend where keys are the urls to torrents to download
+>>> with `aria2c --follow-torrent=mem`.
+>>>
+>>> I am also interested in doing backends that use eg, cloud storage.
+>>> A S3 backend that could upload files to S3 in addition to downloading
+>>> them, for example, would be handy. --[[Joey]]
+
+>>>> So, rather than use backends to do this, it instead made more sense
+>>>> to make them [[special_remotes]]. The URL backend remains a bit
+>>>> of a special case, and a bittorrent backend that downloaded a file
+>>>> from a bittorrent url would still be a good use of backend, but for
+>>>> storing files in external data stores like S3, making it a remote
+>>>> makes better sense. I think I can close this bug now, [[done]]
+>>>> --[[Joey]]
+
+also in Backend/URL.hs is it worth making a minor change to the way curl is called (I'm not sure if the following is correct or not)
+
+> It's correct, typewise, but I don't see any real reason to bother
+> with the change. But I do appreciate patches, which have been rare
+> so far, probaby because of Haskell.. :) --[[Joey]]
+
+>> heh agreed
+
+<pre>
+diff --git a/Backend/URL.hs b/Backend/URL.hs
+index 29dc8fe..4afcf86 100644
+--- a/Backend/URL.hs
++++ b/Backend/URL.hs
+@@ -50,10 +50,13 @@ dummyFsck _ _ _ = return True
+ dummyOk :: Key -> Annex Bool
+ dummyOk _ = return True
+
++curl :: [CommandParam] -> IO Bool
++curl = boolSystem "curl"
++
+ downloadUrl :: Key -> FilePath -> Annex Bool
+ downloadUrl key file = do
+ showNote "downloading"
+ showProgress -- make way for curl progress bar
+- liftIO $ boolSystem "curl" [Params "-# -o", File file, File url]
++ liftIO $ curl [Params "-# -o", File file, File url]
+ where
+ url = join ":" $ drop 1 $ split ":" $ show key
+</pre>
diff --git a/doc/bugs/clicking_back_in_the_web_browser_crashes.mdwn b/doc/bugs/clicking_back_in_the_web_browser_crashes.mdwn
new file mode 100644
index 000000000..1b7e2ec71
--- /dev/null
+++ b/doc/bugs/clicking_back_in_the_web_browser_crashes.mdwn
@@ -0,0 +1,23 @@
+### Please describe the problem.
+
+When I click on the "back" button in my web browser, I get the following error message:
+
+ git-annex has shut down
+
+ You can now close this browser window.
+
+### What steps will reproduce the problem?
+
+ 1. git annex webapp
+ 2. click on "configuration" (or whatever)
+ 3. click on the back button of your web browser
+
+### What version of git-annex are you using? On what operating system?
+
+4.20130815~bpo70+1 on Debian Wheezy, with Chromium Version 29.0.1547.57 Debian 7.1 (217859)
+
+### Please provide any additional information below.
+
+Click "forward" actually brings us back to sanity, and the webapp doesn't actually *crash*. -- [[anarcat]]
+
+> I have applied the page reload fix/hack. [[done]] --[[Joey]]
diff --git a/doc/bugs/clicking_back_in_the_web_browser_crashes/comment_1_c962218657a28494ff837a471d71b43f._comment b/doc/bugs/clicking_back_in_the_web_browser_crashes/comment_1_c962218657a28494ff837a471d71b43f._comment
new file mode 100644
index 000000000..ece6ce0e3
--- /dev/null
+++ b/doc/bugs/clicking_back_in_the_web_browser_crashes/comment_1_c962218657a28494ff837a471d71b43f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.255.110"
+ subject="comment 1"
+ date="2013-09-09T04:23:36Z"
+ content="""
+This occurs when the javascript long polling code fails 4 times in a row attempting to communicate with git-annex's web server. Normally this will mean that the assistant has been stopped. I have seen it once or twice happen while the web server is still running -- possibly due to the browser killing the connection? I have never seen it happen when navigating between pages in the webapp, which is designed to allow use of back button etc. If you can reproduce it reliably, using the chromium inspector to modify the javascript code (look for \"longpoll\") and perhaps add some debug prints might track down what is going on.
+"""]]
diff --git a/doc/bugs/clicking_back_in_the_web_browser_crashes/comment_2_643b2c99ecfe851c576a023ce4385dbb._comment b/doc/bugs/clicking_back_in_the_web_browser_crashes/comment_2_643b2c99ecfe851c576a023ce4385dbb._comment
new file mode 100644
index 000000000..feac21ffe
--- /dev/null
+++ b/doc/bugs/clicking_back_in_the_web_browser_crashes/comment_2_643b2c99ecfe851c576a023ce4385dbb._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://id.koumbit.net/anarcat"
+ ip="2001:1928:1:9::1"
+ subject="comment 2"
+ date="2013-09-09T04:31:30Z"
+ content="""
+i can reproduce reliably alright. It's quite systematic. I have found the `longpolling.js` file in the inspector, but I am not very familiar with in-browser javascript debugging, so I am not sure where to go from here.
+
+Note that the assistant doesn't actually crash. This is also reproducable in Debian sid.
+"""]]
diff --git a/doc/bugs/clicking_back_in_the_web_browser_crashes/comment_3_6e85c50439da81212f4239c74947b75e._comment b/doc/bugs/clicking_back_in_the_web_browser_crashes/comment_3_6e85c50439da81212f4239c74947b75e._comment
new file mode 100644
index 000000000..a3dee1d52
--- /dev/null
+++ b/doc/bugs/clicking_back_in_the_web_browser_crashes/comment_3_6e85c50439da81212f4239c74947b75e._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.255.110"
+ subject="comment 3"
+ date="2013-09-09T05:22:49Z"
+ content="""
+Actually I am able to reproduce it. One thing I can see is that git-annex does not see any connection attempts from the browser when these longpolling attempts are made and fail. So this is all failing on the javascript side. Increasing the connection failure counter does not help. Every ajax request fails, no matter how many times it tries. Chromium has apparently decided that, because we've navigated back to a page, it should not be allowed to load any new resources. This seems to be new, buggy behavior.
+
+It seems the only way out of this bad state would be for the javacript to force a reload of the page. Of course, if git-annex has legitimately exited, that would fail to reload. I suppose the chromium \"this webpage is not available\" that would result is at least accurate...
+
+(At some point, I should probably try to add support for something more modern than long polling.)
+"""]]
diff --git a/doc/bugs/com.branchable.git-annex.assistant.plist_is_invalid.mdwn b/doc/bugs/com.branchable.git-annex.assistant.plist_is_invalid.mdwn
new file mode 100644
index 000000000..d67cdcd40
--- /dev/null
+++ b/doc/bugs/com.branchable.git-annex.assistant.plist_is_invalid.mdwn
@@ -0,0 +1,15 @@
+What steps will reproduce the problem?
+`cat com.branchable.git-annex.assistant`
+
+What version of git-annex are you using? On what operating system?
+ git-annex version: 3.20121112 on OS X Mountain Lion
+
+Please provide any additional information below.
+The '`RunAtLoad`' key is missing a value.
+
+It should say:
+
+`<key>RunAtLoad</key>`<br>
+`<true/>`
+
+> Fixed in git. [[done]] --[[Joey]]
diff --git a/doc/bugs/commitBuffer:_invalid_argument___40__invalid_character__41__.mdwn b/doc/bugs/commitBuffer:_invalid_argument___40__invalid_character__41__.mdwn
new file mode 100644
index 000000000..027d22431
--- /dev/null
+++ b/doc/bugs/commitBuffer:_invalid_argument___40__invalid_character__41__.mdwn
@@ -0,0 +1,228 @@
+What steps will reproduce the problem?
+
+ $ git init a.git
+ Initialized empty Git repository in /var/tmp/git-annex-bug/a.git/.git/
+ $ cd a.git
+ $ git annex init a
+ init a ok
+ (Recording state in git...)
+ $ touch Ren$'\351'
+ $ git annex add Ren$'\351'
+ add René (checksum...) ok
+ (Recording state in git...)
+ $ git ci -m "Added Rene'."
+ [master (root-commit) a61b796] Added Rene'.
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+ create mode 120000 "Ren\351"
+ $ cd ..
+ $ git clone -o a a.git b.git
+ Cloning into b.git...
+ remote: Counting objects: 13, done.
+ remote: Compressing objects: 100% (9/9), done.
+ remote: Total 13 (delta 1), reused 0 (delta 0)
+ Receiving objects: 100% (13/13), done.
+ Resolving deltas: 100% (1/1), done.
+ $ cd b.git
+ $ git annex copy --from=a --fast -v
+ (merging a/git-annex into git-annex...)
+ copy René
+ git-annex: /var/tmp/git-annex-bug/b.git/.git/annex/transfer/download/7c5ee764-e8c6-11e1-b0c5-67c6ec1236d6/SHA256-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855: commitBuffer: invalid argument (invalid character)
+ failed
+ (Recording state in git...)
+ git-annex: copy: 1 failed
+
+What is the expected output? What do you see instead?
+
+Expect that files will be copied, but they are not.
+
+What version of git-annex are you using? On what operating system?
+
+ $ echo $LANG
+ en_US.UTF-8
+ $ lsb_release -a
+ No LSB modules are available.
+ Distributor ID: Ubuntu
+ Description: Ubuntu 11.10
+ Release: 11.10
+ Codename: oneiric
+ $ uname -a
+ Linux pdx-desktop 3.0.0-23-generic #39-Ubuntu SMP Thu Jul 19 19:18:53 UTC 2012 i686 i686 i386 GNU/Linux
+ $ bash --version
+ GNU bash, version 4.2.10(1)-release (i686-pc-linux-gnu)
+ Copyright (C) 2011 Free Software Foundation, Inc.
+ License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
+
+ This is free software; you are free to change and redistribute it.
+ There is NO WARRANTY, to the extent permitted by law.
+ $ ghc --version
+ The Glorious Glasgow Haskell Compilation System, version 7.4.2
+ $ git annex version
+ git-annex version: 3.20120807
+ local repository version: 3
+ default repository version: 3
+ supported repository versions: 3
+ upgrade supported from repository versions: 0 1 2
+
+Please provide any additional information below.
+
+The problem is related to weird characters in file names. In the
+above example, the "weird character" is an accented 'e' (entered with
+$'\351' in bash and zsh). I am able to add the files with weird
+characters in their name to one annex, but I cannot copy them to other
+annexes using `git annex copy`.
+
+The above example is a simplification of a real problem I am
+experiencing. In my real scenario, the file is not empty. See the
+attachment for some variations, including with non-empty
+files. UPDATE: I'm not allowed to add attachments. See below.
+
+May be related to these (long-ago fixed) bugs:
+http://git-annex.branchable.com/todo/support-non-utf8-locales/
+
+
+"Attachment": Here are my notes, including more examples:
+
+ Programs I'm using:
+
+ $ echo $LANG
+ en_US.UTF-8
+ $ lsb_release -a
+ No LSB modules are available.
+ Distributor ID: Ubuntu
+ Description: Ubuntu 11.10
+ Release: 11.10
+ Codename: oneiric
+ $ uname -a
+ Linux pdx-desktop 3.0.0-23-generic #39-Ubuntu SMP Thu Jul 19 19:18:53 UTC 2012 i686 i686 i386 GNU/Linux
+ $ bash --version
+ GNU bash, version 4.2.10(1)-release (i686-pc-linux-gnu)
+ Copyright (C) 2011 Free Software Foundation, Inc.
+ License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
+
+ This is free software; you are free to change and redistribute it.
+ There is NO WARRANTY, to the extent permitted by law.
+ $ ghc --version
+ The Glorious Glasgow Haskell Compilation System, version 7.4.2
+ $ git annex version
+ git-annex version: 3.20120807
+ local repository version: 3
+ default repository version: 3
+ supported repository versions: 3
+ upgrade supported from repository versions: 0 1 2
+
+
+ Simplest way to see problem: one empty file with weird character
+ (accented e: $'\351') in name:
+
+ $ git init a.git
+ Initialized empty Git repository in /var/tmp/git-annex-bug/a.git/.git/
+ $ cd a.git
+ $ git annex init a
+ init a ok
+ (Recording state in git...)
+ $ touch Ren$'\351'
+ $ git annex add Ren$'\351'
+ add René (checksum...) ok
+ (Recording state in git...)
+ $ git ci -m "Added Rene'."
+ [master (root-commit) a61b796] Added Rene'.
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+ create mode 120000 "Ren\351"
+ $ cd ..
+ $ git clone -o a a.git b.git
+ Cloning into b.git...
+ remote: Counting objects: 13, done.
+ remote: Compressing objects: 100% (9/9), done.
+ remote: Total 13 (delta 1), reused 0 (delta 0)
+ Receiving objects: 100% (13/13), done.
+ Resolving deltas: 100% (1/1), done.
+ $ cd b.git
+ $ git annex copy --from=a --fast -v
+ (merging a/git-annex into git-annex...)
+ copy René
+ git-annex: /var/tmp/git-annex-bug/b.git/.git/annex/transfer/download/7c5ee764-e8c6-11e1-b0c5-67c6ec1236d6/SHA256-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855: commitBuffer: invalid argument (invalid character)
+ failed
+ (Recording state in git...)
+ git-annex: copy: 1 failed
+
+
+ Problem disappears with two empty files:
+
+ $ cd ..
+ $ git init a2.git
+ Initialized empty Git repository in /var/tmp/git-annex-bug/a2.git/.git/
+ $ cd a2.git
+ $ git annex init a2
+ init a2 ok
+ (Recording state in git...)
+ $ touch Ren$'\351'
+ $ git annex add Ren$'\351'
+ add René (checksum...) ok
+ (Recording state in git...)
+ $ git ci -m "Add Ren$'\351'."
+ [master (root-commit) 62ac1c8] Add Ren$'\351'.
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+ create mode 120000 "Ren\351"
+ $ touch Rene
+ $ git annex add Rene
+ add Rene (checksum...) ok
+ (Recording state in git...)
+ $ git ci -m "Add Rene."
+ [master c455523] Add Rene.
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+ create mode 120000 Rene
+ $ cd ..
+ $ git clone -o a2 a2.git b2.git
+ Cloning into b2.git...
+ done.
+ $ cd b2.git
+ $ git annex copy --from=a2 --fast -v
+ (merging a2/git-annex into git-annex...)
+ copy Rene (from a2...) ok
+ (Recording state in git...)
+
+
+ Problem returns with two non-empty files:
+
+ $ cd ..
+ $ git init a4.git
+ Initialized empty Git repository in /var/tmp/git-annex-bug/a4.git/.git/
+ $ cd a4.git
+ $ git annex init a4
+ init a4 ok
+ (Recording state in git...)
+ $ touch Ren$'\351'
+ $ rm Ren$'\351'
+ $ ls
+ $ echo "some content" > Ren$'\351'
+ $ git annex add Ren$'\351'
+ add René (checksum...) ok
+ (Recording state in git...)
+ $ git ci -m "Add Ren$'\351'."
+ [master (root-commit) f090d90] Add Ren$'\351'.
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+ create mode 120000 "Ren\351"
+ $ echo "some other content" > Rene
+ $ git annex add Rene
+ add Rene (checksum...) ok
+ (Recording state in git...)
+ $ git ci -m "Add Rene."
+ [master 97c20cd] Add Rene.
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+ create mode 120000 Rene
+ $ cd ..
+ $ git clone -o a4 a4.git b4.git
+ Cloning into b4.git...
+ done.
+ $ cd b4.git
+ $ git annex copy --from=a4 --fast -v
+ (merging a4/git-annex into git-annex...)
+ copy Rene (from a4...) ok
+ copy René
+ git-annex: /var/tmp/git-annex-bug/b4.git/.git/annex/transfer/download/a5fcd0d4-e8c8-11e1-bb41-43ce1cb9a9f1/SHA256-s13--1c87b6727f523662df714f06a94ea27fa4d9050c38f4f7712bd4663ffbfdfa01: commitBuffer: invalid argument (invalid character)
+ failed
+ (Recording state in git...)
+ git-annex: copy: 1 failed
+
+> [[Fixed|done]]. Sorry this took so long, I was at a very busy point when
+> you filed this and am only just getting caught up. --[[Joey]]
diff --git a/doc/bugs/commit_f20a40f_breaks_on_OSX_as_mntent.h_doesn__39__t_exist.mdwn b/doc/bugs/commit_f20a40f_breaks_on_OSX_as_mntent.h_doesn__39__t_exist.mdwn
new file mode 100644
index 000000000..dfd3ffb82
--- /dev/null
+++ b/doc/bugs/commit_f20a40f_breaks_on_OSX_as_mntent.h_doesn__39__t_exist.mdwn
@@ -0,0 +1,8 @@
+commit f20a40f breaks on OSX as mntent.h doesn't exist, the closet thing available to what mntent.h provides is getmntinfo(), it looks yet another bunch of ifdef's might be needed to work around OSX. This problem maybe similarly true with FreeBSD, libfam seems to have worked around the issue - <http://oss.sgi.com/projects/fam/download/contrib/freebsd-mntent.patch>
+
+hope the above report helps.
+
+> Thanks, that was a very useful pointer. I couldn't figure out how to
+> use Haskell's FFI to loop over the list of statfs structs returned by
+> getmntinfo, so I incorporated that C code into a little library,
+> and it seems to work ok. [[done]] --[[Joey]]
diff --git a/doc/bugs/concurrent_git-annex_processes_can_lead_to_locking_issues.mdwn b/doc/bugs/concurrent_git-annex_processes_can_lead_to_locking_issues.mdwn
new file mode 100644
index 000000000..2485e7b19
--- /dev/null
+++ b/doc/bugs/concurrent_git-annex_processes_can_lead_to_locking_issues.mdwn
@@ -0,0 +1,53 @@
+When two git-annex processes are running and both modifying the git-annex
+branch, it's possible one will fail due to git's locking. When this
+happens, git-annex has already recorded its state in the journal (so no
+data is lost), but git-annex does crash, which can be surprising.
+
+I feel that, in general, multiple git-annex processes should be able to run
+concurrently. A big lock around all commands, or even all
+repository-modifying commands is a bad idea. Also, it's probably best to
+only worry about locking conflicts editing the git-annex branch. While `git
+annex add` and a few other commands make changes to the main git repo,
+and can have similar locking issues, so can any git commands that stage
+changes (I think.. check).
+
+Probably should KISS. Just add a lock file that is taken before changes to
+the git-annex branch, and if it's locked, wait. Changes to the git-annex
+branch tend to happen quickly (unless it's committing an enormous set of
+changes, and even that is relatively fast), so waiting seems ok. --[[Joey]]
+
+----
+
+Commit 7981eb4cb512fbe3c49a3dd165c31be14ae4bc49 is more pessimistic,
+describes some other potential issues.
+
+* The journal needs to be emptied (done) and kept locked (not done) during
+ a merge, since a merge operates at a level below the journal, and any
+ changes that are journaled during a merge can overwrite changes merged
+ in from another branch.
+
+* Two git-annex processes can be doing conflicting things and inconsistent
+ information be written to the journal.
+
+ - One example would be concurrent get and drop of the same key.
+ But could this really race? If the key was already present, the get
+ would do nothing, so record no changes. If the key was not yet present,
+ the drop would do nothing, and record no changes.
+
+ - Instead, consider two copys of a key to different locations. If the
+ slower copy starts first and ends last, it could cache the location
+ info, add the new location, and lose the other location it was copied to.
+ Tested it and the location is not cached during the whole copy (logChange
+ reads the current log immediatly before writing), so this
+ race's window is very small -- but does exist.
+
+----
+
+## Updated plan
+
+Make Branch.change transactional, so it takes a lock, reads a file,
+applies a function to it, and writes the changed file.
+
+Make Branch.update hold the same lock.
+
+> [[Done]].
diff --git a/doc/bugs/configurable_path_to_git-annex-shell.mdwn b/doc/bugs/configurable_path_to_git-annex-shell.mdwn
new file mode 100644
index 000000000..af2474451
--- /dev/null
+++ b/doc/bugs/configurable_path_to_git-annex-shell.mdwn
@@ -0,0 +1,7 @@
+On one of my ssh remotes I had to install git-annex using cabal. No system-wide installation possible. Hence `git-annex` and `git-annex-shell` are not in the default `$PATH` but in `$HOME/.cabal/bin`.
+
+Right now the command run by git-annex when ssh'ing to a remote is hardcoded to "`git-annex-shell`", which doesn't work for me. It would be nice to be able to change this per remote, for example with an option named `annex.<remote>.annex-shell-command`. Changing "`git-annex-shell`" in `Remote/Helper/Ssh.hs` to "`~/.cabal/bin/git-annex-shell`" worked for me, but it's obviously very ugly :)
+
+Could you do that please? I'll try to hack it myself and send you a patch in the next few days, but I'm pretty new to Haskell so it may take me a while... Thanks!
+
+> [[closing|done]], see comments --[[Joey]]
diff --git a/doc/bugs/configurable_path_to_git-annex-shell/comment_1_fb6771f902b57f2b690e7cc46fdac47e._comment b/doc/bugs/configurable_path_to_git-annex-shell/comment_1_fb6771f902b57f2b690e7cc46fdac47e._comment
new file mode 100644
index 000000000..50349363b
--- /dev/null
+++ b/doc/bugs/configurable_path_to_git-annex-shell/comment_1_fb6771f902b57f2b690e7cc46fdac47e._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2012-03-22T22:26:02Z"
+ content="""
+It doesn't need to be installed into the system PATH; just the user PATH. Which you should be able to control.
+
+Exactly how to do this surely varies, but here I have a `~/.bashrc` containing `PATH=$HOME/bin:$PATH; export PATH` and I keep git-annex-shell in bin and it's available to eg \"ssh mybox git-annex-shell\"
+"""]]
diff --git a/doc/bugs/configurable_path_to_git-annex-shell/comment_2_2b856f4f0b65c2331be7d565f0e4e8a8._comment b/doc/bugs/configurable_path_to_git-annex-shell/comment_2_2b856f4f0b65c2331be7d565f0e4e8a8._comment
new file mode 100644
index 000000000..adea95ecf
--- /dev/null
+++ b/doc/bugs/configurable_path_to_git-annex-shell/comment_2_2b856f4f0b65c2331be7d565f0e4e8a8._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://schnouki.net/"
+ nickname="Schnouki"
+ subject="comment 2"
+ date="2012-03-23T13:27:12Z"
+ content="""
+Hmm, ok, solved. I'm using zsh, which is a little different: `.zshrc` is only read for interactive shells, so `ssh mybox 'echo $PATH'` displayed `/usr/bin:/bin:/usr/sbin:/sbin`. Using `.zshenv`, which is used even for non-interactive shells, did the trick. Thanks!
+"""]]
diff --git a/doc/bugs/configurable_path_to_git-annex-shell/comment_3_aea42acc039a82efc6bb3a8f173a632e._comment b/doc/bugs/configurable_path_to_git-annex-shell/comment_3_aea42acc039a82efc6bb3a8f173a632e._comment
new file mode 100644
index 000000000..399c46bc2
--- /dev/null
+++ b/doc/bugs/configurable_path_to_git-annex-shell/comment_3_aea42acc039a82efc6bb3a8f173a632e._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="carlo"
+ ip="130.102.158.18"
+ subject="comment 3"
+ date="2013-07-01T04:20:22Z"
+ content="""
+For anyone who comes across this, make sure that you modify your $PATH before these lines in ~/.bashrc:
+
+ # If not running interactively, don't do anything
+ [ -z \"$PS1\" ] && return
+
+"""]]
diff --git a/doc/bugs/configure_mistakes_hashalot_bins_for_sha__63____63____63__sum_and_builds_a_broken_git-annex_executable.mdwn b/doc/bugs/configure_mistakes_hashalot_bins_for_sha__63____63____63__sum_and_builds_a_broken_git-annex_executable.mdwn
new file mode 100644
index 000000000..b71f39e5a
--- /dev/null
+++ b/doc/bugs/configure_mistakes_hashalot_bins_for_sha__63____63____63__sum_and_builds_a_broken_git-annex_executable.mdwn
@@ -0,0 +1,57 @@
+git-annex's configure step finds hashalot's /usr/sbin/sha256, /usr/sbin/sha384, and /usr/sbin/sha512 executables and mistakes them for sha256sum, sha384sum, and sha512sum and prefers them over the correct executables. Hashalot is not compatible, but the build does not fail producing a broken git-annex executable which tries to use hashalot's programs instead of the appropriate shaXXXsum program and is non-functional.
+
+Hashalot can be found at: <http://www.paranoiacs.org/~sluskyb/hacks/hashalot/>
+
+
+What steps will reproduce the problem?
+
+Compile with hashalot's programs in the path.
+
+
+What is the expected output? What do you see instead?
+
+Expect to see configure output:
+
+[...]
+<pre>
+ checking sha1... sha1sum
+ checking sha512... sha512sum
+ checking sha224... sha224sum
+ checking sha384... sha384sum
+ checking sha256... sha256sum
+</pre>
+[...]
+
+
+Instead I see configure output:
+
+[...]
+<pre>
+ checking sha1... sha1sum
+ checking sha512... sha512
+ checking sha224... sha224sum
+ checking sha384... sha384
+ checking sha256... sha256
+</pre>
+[...]
+
+
+What version of git-annex are you using? On what operating system?
+
+I am using 3.20120605, but have checked out the latest GIT and confirmed the bug is still there.
+
+
+Please provide any additional information below.
+
+This is not a runtime bug, only compile time. Uninstalling Hashalot or simply removing it from the PATH is enough to work around this bug. The bug is, however, frustrating because at first glance there appears to be no problem. However any functions of git-annex which use the affected SHA hash functions will fail with the resulting executable and the failure gives no clear indication of why.
+
+I found this bug on Gentoo when I installed git-annex on a system which already had hashalot installed. In the case of Gentoo, git-annex is compiled with hashalot's executables in the path, but normal users don't have /usr/sbin/ in their path so git-annex just fails to find the executable. If you put hashalot in the path, then git annex still fails to work as hashalot is not a replacement for sha1sum and friends.
+
+It may be enough to just prefer sha???sum over sha??? if they both exist.
+
+> Grr. There is no consistency across unixes as to the names of these
+> programs and now something is installing shaN commands that don't
+> generate a checksum?!
+>
+> Ok, fine, configure now checks that the program it finds outputs a known
+> good checksum. [[done]] --[[Joey]]
diff --git a/doc/bugs/configure_script_should_detect_uuidgen_instead_of_just_uuid.mdwn b/doc/bugs/configure_script_should_detect_uuidgen_instead_of_just_uuid.mdwn
new file mode 100644
index 000000000..2b9c77367
--- /dev/null
+++ b/doc/bugs/configure_script_should_detect_uuidgen_instead_of_just_uuid.mdwn
@@ -0,0 +1,6 @@
+On RHEL5 (and clones) systems uuidgen is available as an alternative to
+uuid, the configure script fails, it should probably detect either uuid or
+uuidgen, or let the user decide? - also uuidgen behaves differently from
+uuid on debian.
+
+> uuidgen is now supported. --[[Joey]] [[done]]
diff --git a/doc/bugs/conflicting_haskell_packages.mdwn b/doc/bugs/conflicting_haskell_packages.mdwn
new file mode 100644
index 000000000..5528fad82
--- /dev/null
+++ b/doc/bugs/conflicting_haskell_packages.mdwn
@@ -0,0 +1,17 @@
+The compilation command should states which packages are used and avoid the default mechnasim that automatically search for them.
+
+This can be done by the flags -hide-packages and then -package foo
+
+> My ghc does not have a `--hide-packages` option.
+>
+> Could you just show the build problem that you are suggesting I work
+> around? --[[Joey]]
+
+
+> Thanks npouillard, I see the problem now.
+> <http://stackoverflow.com/questions/2048953/control-monad-state-found-in-multiple-packages-haskell>
+>
+> I've added "-ignore-package monads-fd" to GHCFLAGS. I hope I don't
+> really have to hide all packages and individually turn them back on;
+> surely this monads-fd/mtl conflict is an exception, and Haskell's module
+> system is not a mess of conflicting modules? --[[Joey]] [[done]]
diff --git a/doc/bugs/conflicting_haskell_packages/comment_1_e552a6cc6d7d1882e14130edfc2d6b3b._comment b/doc/bugs/conflicting_haskell_packages/comment_1_e552a6cc6d7d1882e14130edfc2d6b3b._comment
new file mode 100644
index 000000000..42f44bf9c
--- /dev/null
+++ b/doc/bugs/conflicting_haskell_packages/comment_1_e552a6cc6d7d1882e14130edfc2d6b3b._comment
@@ -0,0 +1,24 @@
+[[!comment format=mdwn
+ username="http://ertai.myopenid.com/"
+ nickname="npouillard"
+ subject="how to reproduce the package conflict issue"
+ date="2011-02-07T14:12:43Z"
+ content="""
+If you install the monads-fd package (with cabal install for instance), then you can no longer build git-annex:
+
+<pre>
+./configure
+ checking cp -a... yes
+ checking cp -p... yes
+ checking cp --reflink=auto... yes
+ checking uuid generator... uuid
+ checking xargs -0... yes
+ checking rsync... yes
+ghc -O2 -Wall --make git-annex
+
+Annex.hs:22:7:
+ Ambiguous module name `Control.Monad.State':
+ it was found in multiple packages: monads-fd-0.2.0.0 mtl-2.0.1.0
+make: *** [git-annex] Error 1
+</pre>
+"""]]
diff --git a/doc/bugs/conq:_invalid_command_syntax.mdwn b/doc/bugs/conq:_invalid_command_syntax.mdwn
new file mode 100644
index 000000000..82cd51d8d
--- /dev/null
+++ b/doc/bugs/conq:_invalid_command_syntax.mdwn
@@ -0,0 +1,30 @@
+I've been getting an occasional error from git-annex.
+
+The error is: 'conq: invalid command syntax.'
+
+For example, the last two commands I ran are:
+
+ $ git annex unused
+ unused . (checking for unused data...) (checking master...) (checking origin/master...)
+ Some annexed data is no longer used by any files:
+ NUMBER KEY
+ 1 SHA256-s.....
+ (To see where data was previously used, try: git log --stat -S'KEY')
+
+ To remove unwanted data: git-annex dropunused NUMBER
+
+ ok
+
+ $ git annex dropunused 1
+ dropunused 1 conq: invalid command syntax.
+ ok
+
+
+
+*OS:* OSX + port installs of the GNU tools
+
+*git-annex-version:* 3.20111211
+
+*git-version:* 1.7.7.4
+
+> [[done]], apparently not a git-annex bug --[[Joey]]
diff --git a/doc/bugs/conq:_invalid_command_syntax/comment_1_f33b83025ce974e496f83f248275a66a._comment b/doc/bugs/conq:_invalid_command_syntax/comment_1_f33b83025ce974e496f83f248275a66a._comment
new file mode 100644
index 000000000..62881bfc7
--- /dev/null
+++ b/doc/bugs/conq:_invalid_command_syntax/comment_1_f33b83025ce974e496f83f248275a66a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2012-01-03T00:34:59Z"
+ content="""
+AFAICs, you probably just have a \"conq\" program that is running in the background and emitted this error.
+
+The error message is not part of git-annex; it does not run any \"conq\" thing itself. Although you could try passing the --debug parameter to check the commands it does run to see if one of them somehow causes this conq thing.
+"""]]
diff --git a/doc/bugs/conq:_invalid_command_syntax/comment_2_195106ca8dedad5f4d755f625e38e8af._comment b/doc/bugs/conq:_invalid_command_syntax/comment_2_195106ca8dedad5f4d755f625e38e8af._comment
new file mode 100644
index 000000000..39ece1eca
--- /dev/null
+++ b/doc/bugs/conq:_invalid_command_syntax/comment_2_195106ca8dedad5f4d755f625e38e8af._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 2"
+ date="2012-01-03T00:41:08Z"
+ content="""
+A google search <http://www.google.com/search?hl=en&sclient=psy-ab&q=conq%3A+invalid+command+syntax&btnG=>
+finds other examples of this error message related to ssh, mercurial, and bitbucket. What that has to do with git is anyone's guess, but I'm pretty sure git-annex is not related to it at all.
+"""]]
diff --git a/doc/bugs/conq:_invalid_command_syntax/comment_3_55af43e2f43a4c373f7a0a33678d0b1c._comment b/doc/bugs/conq:_invalid_command_syntax/comment_3_55af43e2f43a4c373f7a0a33678d0b1c._comment
new file mode 100644
index 000000000..75132c1d6
--- /dev/null
+++ b/doc/bugs/conq:_invalid_command_syntax/comment_3_55af43e2f43a4c373f7a0a33678d0b1c._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://a-or-b.myopenid.com/"
+ ip="203.45.2.230"
+ subject="comment 3"
+ date="2012-01-03T00:49:41Z"
+ content="""
+Yeah, I saw those google links myself, but couldn't see why the bitbucket/ssh would be relevant.
+
+The strange thing is that I *only* get this message when running git-annex.
+
+I also don't have a conq in my path so I don't know where it is running from.
+
+
+Oh well, if I ever sort it out I'll post back here.
+"""]]
diff --git a/doc/bugs/copy_doesn__39__t_scale.mdwn b/doc/bugs/copy_doesn__39__t_scale.mdwn
new file mode 100644
index 000000000..a5ca9d9ee
--- /dev/null
+++ b/doc/bugs/copy_doesn__39__t_scale.mdwn
@@ -0,0 +1,38 @@
+It seems that git-annex copies every individual file in a separate
+transaction. This is quite costly for mass transfers: each file involves a
+separate rsync invocation and the creation of a new commit. Even with a
+meager thousand files or so in the annex, I have to wait for fifteen
+minutes to copy the contents to another disk, simply because every
+individual file involves some disk thrashing. Also, it seems suspicious
+that the git-annex branch would get a thousands commits of history from the
+simple procedure of copying everything to a new repository. Surely it would
+be better to first copy everything and then create only a single commit
+that registers the changes to the files' availability?
+
+> git-annex is very careful to commit as infrequently as possible,
+> and the current version makes *1* commit after all the copies are
+> complete, even if it transferred a billion files. The only overhead
+> incurred for each file is writing a journal file.
+> You must have an old version.
+> --[[Joey]]
+
+(I'm also not quite clear on why rsync is being used when both repositories
+are local. It seems to be just overhead.)
+
+> Even when copying to another disk it's often on
+> some slow bus, and the file is by definition large. So it's
+> nice to support resumes of interrupted transfers of files.
+> Also because rsync has a handy progress display that is hard to get with cp.
+>
+> (However, if the copy is to another directory in the same disk, it does
+> use cp, and even supports really fast copies on COW filesystems.)
+> --[[Joey]]
+
+---
+
+Oneshot mode is now implemented, making git-annex-shell and other
+short lifetime processes not bother with committing changes.
+[[done]] --[[Joey]]
+
+Update: Now it makes one commit at the very end of such a mass transfer.
+--[[Joey]]
diff --git a/doc/bugs/copy_doesn__39__t_scale/comment_1_7c12499c9ac28a9883c029f8c659eb57._comment b/doc/bugs/copy_doesn__39__t_scale/comment_1_7c12499c9ac28a9883c029f8c659eb57._comment
new file mode 100644
index 000000000..749b3ba10
--- /dev/null
+++ b/doc/bugs/copy_doesn__39__t_scale/comment_1_7c12499c9ac28a9883c029f8c659eb57._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawk6QAwUsFHpr3Km1yQbg8hf3S7RDYf7hX4"
+ nickname="Lauri"
+ subject="comment 1"
+ date="2012-01-28T00:17:37Z"
+ content="""
+To me it very much seems that a commit per file is indeed created at the remote end, although not at the local end. See the following transcript: <https://gist.github.com/1691714>.
+
+
+"""]]
diff --git a/doc/bugs/copy_doesn__39__t_scale/comment_2_f85d8023cdbc203bb439644cf7245d4e._comment b/doc/bugs/copy_doesn__39__t_scale/comment_2_f85d8023cdbc203bb439644cf7245d4e._comment
new file mode 100644
index 000000000..9a2bd92fa
--- /dev/null
+++ b/doc/bugs/copy_doesn__39__t_scale/comment_2_f85d8023cdbc203bb439644cf7245d4e._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 2"
+ date="2012-01-28T19:32:36Z"
+ content="""
+Ah, I see, I was not thinking about the location log update that's done on the remote side.
+
+For transfers over ssh, that's a separate git-annex-shell invoked per change. For local-local transfers, it's all done in a single process but it spins up a state to handle the remote and then immediately shuts it down, also generating a commit.
+
+In either case, I think there is a nice fix. Since git-annex *does* have a journal nowadays, and goes to all the bother to
+support recovery if a process was interrupted and journalled changes that did not get committed, there's really no reason in either of these cases for the remote end to do anything more than journal the change. The next time git-annex is actually run on the remote, and needs to look up location information, it will merge the journalled changes into the branch, in a single commit.
+
+My only real concern is that some remotes might *never* have git-annex run in them directly, and would just continue to accumulate journal files forever. Although due to the way the journal is structured, it can have, at a maximum, the number of files in the git-annex branch. However, the number of files in it is expected to be relatively smal and it might get a trifle innefficient, as it lacks directory hashing. These performance problems could certainly be dealt with if they do turn out to be a problem.
+"""]]
diff --git a/doc/bugs/copy_doesn__39__t_scale/comment_3_4592765c3d77bb5664b8d16867e9d79c._comment b/doc/bugs/copy_doesn__39__t_scale/comment_3_4592765c3d77bb5664b8d16867e9d79c._comment
new file mode 100644
index 000000000..aa9bf1e45
--- /dev/null
+++ b/doc/bugs/copy_doesn__39__t_scale/comment_3_4592765c3d77bb5664b8d16867e9d79c._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawk6QAwUsFHpr3Km1yQbg8hf3S7RDYf7hX4"
+ nickname="Lauri"
+ subject="comment 3"
+ date="2012-01-29T01:51:35Z"
+ content="""
+That sounds just fine, but indeed my use case was a bare backup/transfer repository that is meant to always be only at the remote end of git-annex operations. So why not as well do a single commit after everything has been copied and journaled? That's what's done at the other end too, after all. Or, if commits are to be minimized, just stage the journal into the index before finishing, but don't commit it yet?
+
+(I would actually prefer this mode of usage for other git-annex operations, too. In git you can add stuff little by little and commit them all in one go. In git-annex the add immediately creates a commit, which is unexpected and a bit annoying.)
+
+"""]]
diff --git a/doc/bugs/copy_fast_confusing_with_broken_locationlog.mdwn b/doc/bugs/copy_fast_confusing_with_broken_locationlog.mdwn
new file mode 100644
index 000000000..69fbc816f
--- /dev/null
+++ b/doc/bugs/copy_fast_confusing_with_broken_locationlog.mdwn
@@ -0,0 +1,6 @@
+Conversation moved from [[tips/recover_data_from_lost+found]]
+to a proper bug. --[[Joey]]
+
+(Unfortunatly that scrambled the comment creation times and thus order.)
+
+> Added a message [[done]] --[[Joey]]
diff --git a/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_10_435f87d54052f264096a8f23e99eae06._comment b/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_10_435f87d54052f264096a8f23e99eae06._comment
new file mode 100644
index 000000000..ec24c478d
--- /dev/null
+++ b/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_10_435f87d54052f264096a8f23e99eae06._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 10"
+ date="2011-05-15T16:47:53Z"
+ content="""
+The key is the basename of the symlink target.
+"""]]
diff --git a/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_11_9be0aef403a002c1706d17deee45763c._comment b/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_11_9be0aef403a002c1706d17deee45763c._comment
new file mode 100644
index 000000000..7bc54573e
--- /dev/null
+++ b/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_11_9be0aef403a002c1706d17deee45763c._comment
@@ -0,0 +1,24 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 11"
+ date="2011-05-15T18:53:26Z"
+ content="""
+It seems the objects are in the remote after all, but the remote is unaware of this fact. No idea where/why the remote lost that info, but.. Anyway, with the SHA backends, wouldn't it make sense to simply return \"OK\" and update the annex logs accordingly, no?
+
+Local:
+
+ % ls -l foo
+ lrwxrwxrwx 1 richih richih 312 Apr 3 01:18 foo -> .git/annex/objects/gG/VW/SHA512-s80781--cef3966a19c7435acceb8fbfbff1feebe6decab7c81a0c197f00932cf9ef0eac330784cc3f0d211bd4acf56a6d16daaebe9b598aa4dfd5bfec73f4e6df3f0491/SHA512-s80781--cef3966a19c7435acceb8fbfbff1feebe6decab7c81a0c197f00932cf9ef0eac330784cc3f0d211bd4acf56a6d16daaebe9b598aa4dfd5bfec73f4e6df3f0491
+ %
+
+Remote:
+
+ % git-annex-shell recvkey <remote> SHA512-s80781--cef3966a19c7435acceb8fbfbff1feebe6decab7c81a0c197f00932cf9ef0eac330784cc3f0d211bd4acf56a6d16daaebe9b598aa4dfd5bfec73f4e6df3f0491
+ git-annex-shell: key is already present in annex
+ % strace git-annex-shell recvkey /base/git-annex/fun SHA512-s80781--cef3966a19c7435acceb8fbfbff1feebe6decab7c81a0c197f00932cf9ef0eac330784cc3f0d211bd4acf56a6d16daaebe9b598aa4dfd5bfec73f4e6df3f0491 2>&1 | grep SHA512-s80781--cef3966a19c7435acceb8fbfbff1feebe6decab7c81a0c197f00932cf9ef0eac330784cc3f0d211bd4acf56a6d16daaebe9b598aa4dfd5bfec73f4e6df3f0491
+ stat64(\"/base/git-annex/fun/annex/objects/gG/VW/SHA512-s80781--cef3966a19c7435acceb8fbfbff1feebe6decab7c81a0c197f00932cf9ef0eac330784cc3f0d211bd4acf56a6d16daaebe9b598aa4dfd5bfec73f4e6df3f0491/SHA512-s80781--cef3966a19c7435acceb8fbfbff1feebe6decab7c81a0c197f00932cf9ef0eac330784cc3f0d211bd4acf56a6d16daaebe9b598aa4dfd5bfec73f4e6df3f0491\", {st_mode=S_IFREG|0444, st_size=80781, ...}) = 0
+ % ls -l /base/git-annex/fun/annex/objects/gG/VW/SHA512-s80781--cef3966a19c7435acceb8fbfbff1feebe6decab7c81a0c197f00932cf9ef0eac330784cc3f0d211bd4acf56a6d16daaebe9b598aa4dfd5bfec73f4e6df3f0491/SHA512-s80781--cef3966a19c7435acceb8fbfbff1feebe6decab7c81a0c197f00932cf9ef0eac330784cc3f0d211bd4acf56a6d16daaebe9b598aa4dfd5bfec73f4e6df3f0491
+ -r--r--r-- 1 richih richih 80781 2011-04-01 12:44 /base/git-annex/fun/annex/objects/gG/VW/SHA512-s80781--cef3966a19c7435acceb8fbfbff1feebe6decab7c81a0c197f00932cf9ef0eac330784cc3f0d211bd4acf56a6d16daaebe9b598aa4dfd5bfec73f4e6df3f0491/SHA512-s80781--cef3966a19c7435acceb8fbfbff1feebe6decab7c81a0c197f00932cf9ef0eac330784cc3f0d211bd4acf56a6d16daaebe9b598aa4dfd5bfec73f4e6df3f0491
+ %
+"""]]
diff --git a/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_12_26d60661196f63fd01ee4fbb6e2340e7._comment b/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_12_26d60661196f63fd01ee4fbb6e2340e7._comment
new file mode 100644
index 000000000..b458a37b6
--- /dev/null
+++ b/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_12_26d60661196f63fd01ee4fbb6e2340e7._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 12"
+ date="2011-05-15T19:40:47Z"
+ content="""
+So, it appears that you're using git annex copy --fast. As documented that assumes the location log is correct. So it avoids directly checking if the bare repo contains the file, and tries to upload it, and the bare repo is all like \"but I've already got this file!\". The only way to improve that behavior might be to let rsync go ahead and retransfer the file, which, with recovery, should require sending little data etc. But I can't say I like the idea much, as the repo already has the content, so unlocking it and letting rsync mess with it is an unnecessary risk. I think it's ok for --force to blow up
+if its assumptions turn out to be wrong.
+
+If you use git annex copy without --fast in this situation, it will do the right thing.
+"""]]
diff --git a/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_13_ead55b915d3b92a62549b2957ad211c8._comment b/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_13_ead55b915d3b92a62549b2957ad211c8._comment
new file mode 100644
index 000000000..d92ecbba0
--- /dev/null
+++ b/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_13_ead55b915d3b92a62549b2957ad211c8._comment
@@ -0,0 +1,35 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 13"
+ date="2011-05-15T20:25:25Z"
+ content="""
+Yes, makes sense. I am so used to using --fast, I forgot a non-fast mode existed. I still think it would be a good idea to fall back to non-fast mode if --fast runs into an error from the remote, but as that is well without my abilities how about this patch?
+
+
+ From 4855510c7a84eb5d28fdada429580a8a42b7112a Mon Sep 17 00:00:00 2001
+ From: Richard Hartmann <richih.mailinglist@gmail.com>
+ Date: Sun, 15 May 2011 22:20:42 +0200
+ Subject: [PATCH] Make error in RecvKey.hs suggest possible solution
+
+ ---
+ Command/RecvKey.hs | 2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+ diff --git a/Command/RecvKey.hs b/Command/RecvKey.hs
+ index 126608f..b917a1c 100644
+ --- a/Command/RecvKey.hs
+ +++ b/Command/RecvKey.hs
+ @@ -27,7 +27,7 @@ start :: CommandStartKey
+ start key = do
+ present <- inAnnex key
+ when present $
+ - error \"key is already present in annex\"
+ + error \"key is already present in annex. If you are running copy, try without '--fast'\"
+
+ ok <- getViaTmp key (liftIO . rsyncServerReceive)
+ if ok
+ --
+ 1.7.4.4
+
+"""]]
diff --git a/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_14_191de89d3988083d9cf001799818ff4a._comment b/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_14_191de89d3988083d9cf001799818ff4a._comment
new file mode 100644
index 000000000..f45bd7046
--- /dev/null
+++ b/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_14_191de89d3988083d9cf001799818ff4a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 14"
+ date="2011-05-15T20:50:26Z"
+ content="""
+Or, even better, wouldn't it make sense to have SHA backends always default to --fast and only use non-fast when any snags are hit, use non-fast mode for that file.
+
+Though if we continue here, we should probably move this to its own page.
+"""]]
diff --git a/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_15_b3e3b338ccfa0a32510c78ba1b1bb617._comment b/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_15_b3e3b338ccfa0a32510c78ba1b1bb617._comment
new file mode 100644
index 000000000..b4a00bd7e
--- /dev/null
+++ b/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_15_b3e3b338ccfa0a32510c78ba1b1bb617._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 15"
+ date="2011-05-15T21:38:47Z"
+ content="""
+PS: Just to make this clear, I am using a custom alias for all my copying needs and thus didn't even see that I used --fast. :p
+"""]]
diff --git a/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_16_04a9f4468c3246c8eff3dbe21dd90101._comment b/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_16_04a9f4468c3246c8eff3dbe21dd90101._comment
new file mode 100644
index 000000000..6d3dabb92
--- /dev/null
+++ b/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_16_04a9f4468c3246c8eff3dbe21dd90101._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 16"
+ date="2011-05-16T20:01:28Z"
+ content="""
+Thanks.
+"""]]
diff --git a/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_1_6a41bf7e2db83db3a01722b516fb6886._comment b/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_1_6a41bf7e2db83db3a01722b516fb6886._comment
new file mode 100644
index 000000000..59c30de53
--- /dev/null
+++ b/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_1_6a41bf7e2db83db3a01722b516fb6886._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 1"
+ date="2011-05-12T00:07:29Z"
+ content="""
+I followed this to re-inject files which git annex fsck listed as missing.
+
+For everyone of those files, I get
+
+ git-annex-shell: key is already present in annex
+ rsync: connection unexpectedly closed (0 bytes received so far) [sender]
+ rsync error: error in rsync protocol data stream (code 12) at io.c(601) [sender=3.0.8]
+
+when trying to copy the files to the remote.
+
+-- Richard
+"""]]
diff --git a/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_2_9f5f1dbffb2dd24f4fcf8c2027bf0384._comment b/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_2_9f5f1dbffb2dd24f4fcf8c2027bf0384._comment
new file mode 100644
index 000000000..44aab3baa
--- /dev/null
+++ b/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_2_9f5f1dbffb2dd24f4fcf8c2027bf0384._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 2"
+ date="2011-05-12T01:01:34Z"
+ content="""
+Sounds like you probably didn't commit after the fsck, or didn't push so the other repository did not know the first had the content again -- but I'm not 100% sure.
+"""]]
diff --git a/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_3_b596b5cfd3377e58dbbb5d509d026b90._comment b/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_3_b596b5cfd3377e58dbbb5d509d026b90._comment
new file mode 100644
index 000000000..4744db995
--- /dev/null
+++ b/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_3_b596b5cfd3377e58dbbb5d509d026b90._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 3"
+ date="2011-05-14T09:06:54Z"
+ content="""
+As my comment from work is stuck in moderation:
+
+I ran this twice:
+
+ git pull && git annex add . && git annex copy . --to <remote> --fast --quiet && git commit -a -m \"$HOST $(date +%F--%H-%M-%S-%Z)\" && git push
+
+but nothing changed
+"""]]
diff --git a/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_4_d7112c315fb016a8a399e24e9b6461d8._comment b/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_4_d7112c315fb016a8a399e24e9b6461d8._comment
new file mode 100644
index 000000000..1fb19ab19
--- /dev/null
+++ b/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_4_d7112c315fb016a8a399e24e9b6461d8._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 4"
+ date="2011-05-14T16:13:58Z"
+ content="""
+Hmm. Old versions may have forgotten to git add a .git-annex location log file when recovering content with fsck. That could be another reason things are out of sync.
+
+But I'm not clear on which repo is trying to copy files to which.
+
+(NB: If the files were recovered on a bare git repo, fsck cannot update the location log there, which could also explain this.)
+"""]]
diff --git a/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_5_4ea29a6f8152eddf806c536de33ef162._comment b/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_5_4ea29a6f8152eddf806c536de33ef162._comment
new file mode 100644
index 000000000..0a546bd88
--- /dev/null
+++ b/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_5_4ea29a6f8152eddf806c536de33ef162._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 5"
+ date="2011-05-14T19:03:43Z"
+ content="""
+Version: 0.20110503
+
+My local non-bare repo is copying to a remote bare repo.
+
+I have been recovering in a non-bare repo.
+
+If there is anything I can send you to help... If I removed said files and went through http://git-annex.branchable.com/bugs/No_easy_way_to_re-inject_a_file_into_an_annex/ -- would that help?
+"""]]
diff --git a/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_6_0d85f114a103bd6532a3b3b24466012e._comment b/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_6_0d85f114a103bd6532a3b3b24466012e._comment
new file mode 100644
index 000000000..1e3f32531
--- /dev/null
+++ b/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_6_0d85f114a103bd6532a3b3b24466012e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 6"
+ date="2011-05-14T19:23:45Z"
+ content="""
+Well, focus on a specific file that exhibits the problem. What does `git annex whereis` say about it? Is the content actually present in annex/objects/ on the bare repository? Does that contradict whereis?
+"""]]
diff --git a/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_7_d38d5bee6d360b0ea852f39e3a7b1bc6._comment b/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_7_d38d5bee6d360b0ea852f39e3a7b1bc6._comment
new file mode 100644
index 000000000..f7dfad68c
--- /dev/null
+++ b/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_7_d38d5bee6d360b0ea852f39e3a7b1bc6._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 7"
+ date="2011-05-14T23:13:15Z"
+ content="""
+It exists locally, whereis tells me it exists locally and locally, only.
+
+The object is _not_ in the bare repo.
+
+The file _might_ have gone missing before I upgraded my annex backend version to 2. Could this be a factor?
+"""]]
diff --git a/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_8_29c3de4bf5fbd990b230c443c0303cbe._comment b/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_8_29c3de4bf5fbd990b230c443c0303cbe._comment
new file mode 100644
index 000000000..01248914c
--- /dev/null
+++ b/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_8_29c3de4bf5fbd990b230c443c0303cbe._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 8"
+ date="2011-05-15T00:09:34Z"
+ content="""
+What you're describing should be impossible; the error message shown can only occur if the object is present in the annex where `git-annex-shell recvkey` is run. So something strange is going on.
+
+Try reproducing it by running on the remote system, `git-annex-shell recvkey /remote/repo.git $key` .. if you can reproduce it, I guess the next thing to do will be to strace the command and see why it's thinking the object is there.
+"""]]
diff --git a/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_9_2cee4f6bd6db7518fd61453c595162c6._comment b/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_9_2cee4f6bd6db7518fd61453c595162c6._comment
new file mode 100644
index 000000000..2755cf331
--- /dev/null
+++ b/doc/bugs/copy_fast_confusing_with_broken_locationlog/comment_9_2cee4f6bd6db7518fd61453c595162c6._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 9"
+ date="2011-05-15T09:16:49Z"
+ content="""
+Just to make sure: How do I get $key? What I did was look at the path in the object store of the local repo and see if that exact same path & file existed in the remote.
+"""]]
diff --git a/doc/bugs/copy_to_webdav_sometimes_doesn__39__t_work.mdwn b/doc/bugs/copy_to_webdav_sometimes_doesn__39__t_work.mdwn
new file mode 100644
index 000000000..190f3bb3b
--- /dev/null
+++ b/doc/bugs/copy_to_webdav_sometimes_doesn__39__t_work.mdwn
@@ -0,0 +1,74 @@
+### Please describe the problem.
+Copying to a gpg encrypted webdav remote (with davfs) seems to work, but fails.
+The command "git annex copy --to 1und1 some/file" returns ok, but a fsck fails and running
+the copy again copies the file again to the remote.
+
+### What steps will reproduce the problem?
+[[!format sh """
+git annex copy --to 1und1 some/file # seems ok
+git annex copy --to 1und1 some/file # copies again
+git annex fsck --from 1und1 some/file # fails
+"""]]
+
+### What version of git-annex are you using? On what operating system?
+4.20131002 on debian (mostly stable), armel.
+
+### Please provide any additional information below.
+
+I used strace to see what is going on. It seems the chunkcount file is not written. When I create that file by hand fsck is happy.
+(git annex seems to have two different locations for that file (dcf/85a and 3W/Qm). The second (3W/Qm) doesn't exist.)
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+copy to webdav (git annex copy --to 1und1 some/file)
+output of basically "strace git annex ... | grep media":
+
+9871 stat64("/media/1und1/git-annex/dcf/85a/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33.chunkcount", <unfinished ...>
+9871 stat64("/media/1und1/git-annex/3W/Qm/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33.chunkcount", 0xb65145d0) = -1 ENOENT (No such file or directory)
+9871 mkdir("/media/1und1/git-annex/tmp/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33", 0777 <unfinished ...>
+9871 statfs("/media/1und1/git-annex/tmp/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33/", <unfinished ...>
+9871 stat64("/media/1und1/git-annex/tmp/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33/", {st_mode=S_IFDIR|0755, st_size=0, ...}) = 0
+9871 open("/media/1und1/git-annex/tmp/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33.chunk1", O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK|O_LARGEFILE, 0666 <unfinished ...>
+9871 stat64("/media/1und1/git-annex/dcf/85a/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33/", <unfinished ...>
+9871 chmod("/media/1und1/git-annex/dcf/85a/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33/", 040755 <unfinished ...>
+9871 openat(AT_FDCWD, "/media/1und1/git-annex/dcf/85a/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33/", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC) = 15
+9871 unlink("/media/1und1/git-annex/dcf/85a/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33.chunk1" <unfinished ...>
+9871 rmdir("/media/1und1/git-annex/dcf/85a/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33/" <unfinished ...>
+9871 mkdir("/media/1und1/git-annex/dcf/85a", 0777) = -1 EEXIST (File exists)
+9871 stat64("/media/1und1/git-annex/dcf/85a", {st_mode=S_IFDIR|0755, st_size=64, ...}) = 0
+9871 stat64("/media/1und1/git-annex/tmp/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33/", {st_mode=S_IFDIR|0755, st_size=0, ...}) = 0
+9871 rename("/media/1und1/git-annex/tmp/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33/", "/media/1und1/git-annex/dcf/85a/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33/" <unfinished ...>
+9871 openat(AT_FDCWD, "/media/1und1/git-annex/dcf/85a/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33/", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC) = 15
+9871 stat64("/media/1und1/git-annex/dcf/85a/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33.chunk1", {st_mode=S_IFREG|0644, st_size=11705, ...}) = 0
+9871 chmod("/media/1und1/git-annex/dcf/85a/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33.chunk1", 0100444) = 0
+9871 stat64("/media/1und1/git-annex/dcf/85a/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33/", {st_mode=S_IFDIR|0755, st_size=152, ...}) = 0
+9871 chmod("/media/1und1/git-annex/dcf/85a/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33/", 040555 <unfinished ...>
+
+fsck webdav, but fails (git annex fsck --from 1und1 some/file):
+
+10208 stat64("/media/1und1/git-annex/dcf/85a/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33.chunkcount", <unfinished ...>
+10208 stat64("/media/1und1/git-annex/3W/Qm/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33.chunkcount", 0xb6428160) = -1 ENOENT (No such file or directory)
+
+
+manual file creation:
+chmod u+w ...
+echo -n 1 > /media/1und1/git-annex/dcf/85a/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33.chunkcount
+chmod u-w ...
+
+
+fsck webdav again, now all is fine ("fixing location log"):
+10670 stat64("/media/1und1/git-annex/dcf/85a/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33.chunkcount", {st_mode=S_IFREG|0444, st_size=1, ...}) = 0
+10670 open("/media/1und1/git-annex/dcf/85a/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33.chunkcount", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_LARGEFILE) = 14
+10670 stat64("/media/1und1/git-annex/dcf/85a/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33.chunk1", {st_mode=S_IFREG|0444, st_size=11705, ...}) = 0
+10670 stat64("/media/1und1/git-annex/dcf/85a/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33.chunkcount", {st_mode=S_IFREG|0444, st_size=1, ...}) = 0
+10670 open("/media/1und1/git-annex/dcf/85a/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33.chunkcount", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_LARGEFILE) = 14
+10670 stat64("/media/1und1/git-annex/dcf/85a/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33.chunk1", {st_mode=S_IFREG|0444, st_size=11705, ...}) = 0
+10672 open("/media/1und1/git-annex/dcf/85a/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33/GPGHMACSHA1--10ff9e1cc8191235670c2fd95375bccf62004f33.chunk1", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_LARGEFILE) = 20
+# End of transcript or log.
+"""]]
+
+> There was a bug that caused it not to write the chunkcount file.
+> I have fixed it, and put in a workaround so fsck, etc, will
+> see that the file is stored on the remote despite there being no
+> chunkcount file present. [[done]] --[[Joey]]
diff --git a/doc/bugs/copy_to_webdav_sometimes_doesn__39__t_work/comment_1_77629f620b28ac62364de44b41fa539d._comment b/doc/bugs/copy_to_webdav_sometimes_doesn__39__t_work/comment_1_77629f620b28ac62364de44b41fa539d._comment
new file mode 100644
index 000000000..d5ad2d88d
--- /dev/null
+++ b/doc/bugs/copy_to_webdav_sometimes_doesn__39__t_work/comment_1_77629f620b28ac62364de44b41fa539d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlqOu7P4tb4D-Xo2pYrjln2NsAObtErliM"
+ nickname="Alexander"
+ subject="comment 1"
+ date="2013-10-27T07:00:01Z"
+ content="""
+thanks!
+"""]]
diff --git a/doc/bugs/creating_a_plain_directory_where_a_mountpoint_should_have_been.mdwn b/doc/bugs/creating_a_plain_directory_where_a_mountpoint_should_have_been.mdwn
new file mode 100644
index 000000000..6f0947eef
--- /dev/null
+++ b/doc/bugs/creating_a_plain_directory_where_a_mountpoint_should_have_been.mdwn
@@ -0,0 +1,27 @@
+### Please describe the problem.
+
+This is a one-off thing, not a reproducible bug. It was just so weird that I wanted to make a note of it in case somebody else had the same problem and it was reproducible.
+
+I have a remote on the a USB drive which I mount once in a while on /Volumes/TOSHIBAEXT which has a remote on /Volumes/TOSHIBAEXT/annex. It's a remote which I created by hand using "git clone" a long time ago, not something the assistant set up for me.
+
+Anyway, today the assistant kept reporting that it could not sync to it. I didn't know why, because I checked in my Finder sidebar and it showed a mounted drive called TOSHIBAEXT. It's only when I checked with the command line that I noticed something was up! There was now an ordinary directory at /Volumes/TOSHIBAEXT/annex. This had apparently been created at some point when the drive was unmounted, so when it re-mounted, because there was a directory in the way, it re-mounted at "/Volumes/TOSHIBAEXT 1". But it was displayed in the finder sidebar as just "TOSHIBAEXT" anyway because the finder hides this workaround from the user for whatever reason.
+
+Presumably git-annex assistant at some point, for some reason, created an ordinary directory where it expected to find the annex.
+
+I wonder if this may have to do with the fact that this is a non-bare, created-by-hand repo, from before I was using the assistant, not a normal bare remote that the assistant would have created for me if I'd been using the webapp.
+
+### What steps will reproduce the problem?
+
+I've only seen it once, and report the bug not as an outstanding issue but only as a heads-up that this has ever happened.
+
+### What version of git-annex are you using? On what operating system?
+
+git-annex version: 4.20130501-gb61740e
+
+OS X lion (10.7)
+
+### Please provide any additional information below.
+
+I wasn't logging when this happened.
+
+Again, just a heads-up; I'll keep my eye open for this happening again and post more info if it does.
diff --git a/doc/bugs/creating_a_plain_directory_where_a_mountpoint_should_have_been/comment_1_41cfd5e48426a6ef52bef70a06a6f46a._comment b/doc/bugs/creating_a_plain_directory_where_a_mountpoint_should_have_been/comment_1_41cfd5e48426a6ef52bef70a06a6f46a._comment
new file mode 100644
index 000000000..a4d0a5895
--- /dev/null
+++ b/doc/bugs/creating_a_plain_directory_where_a_mountpoint_should_have_been/comment_1_41cfd5e48426a6ef52bef70a06a6f46a._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="99.54.57.201"
+ subject="comment 1"
+ date="2013-05-05T20:55:19Z"
+ content="""
+Huh. This happened a second time today. I'll try and catch it in the act, and make a proper bug report, when I get a chance.
+
+Still not sure this is a bug rather than just a peculiarity of how I have things set up.
+
+"""]]
diff --git a/doc/bugs/creating_a_plain_directory_where_a_mountpoint_should_have_been/comment_2_bd584ccbe128427fca99e61d66d301c9._comment b/doc/bugs/creating_a_plain_directory_where_a_mountpoint_should_have_been/comment_2_bd584ccbe128427fca99e61d66d301c9._comment
new file mode 100644
index 000000000..1d9e09ef9
--- /dev/null
+++ b/doc/bugs/creating_a_plain_directory_where_a_mountpoint_should_have_been/comment_2_bd584ccbe128427fca99e61d66d301c9._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-05-06T14:50:01Z"
+ content="""
+Hmm.. One way I can think that this could happen is if git-annex was running, and doing something in the repository on the drive that involved making a directory, and the drive was removed. There are several places in git-annex where it has code, like this:
+
+<pre>
+createAnnexDirectory
+-- some action here that expects to have the git-annex directory
+</pre>
+
+Is the repo you have on the drive a direct mode repo by any chance? This is the only obvious way I can see that would cause it to create just the top level directory of the repository, and not a deeper directory tree like `.git/annex/tmp/`
+
+The assistant also has a MountWatcher that detects when repositories that were not accessible get mounted, but it does not do anything to stop the repository being used when its drive gets unmounted. Even if it did, it couldn't go anything about code that is already running using the previously mounted repository. However, as things stand, it would probably also be possible for the drive to be removed, and some time to pass before an action was run that tried to do something to the no longer present repository.
+So making the mountwatcher disable repositories when drives are unmounted would at least make this window narrower.
+"""]]
diff --git a/doc/bugs/creating_a_plain_directory_where_a_mountpoint_should_have_been/comment_3_5bb0347215b321444643646f25a35759._comment b/doc/bugs/creating_a_plain_directory_where_a_mountpoint_should_have_been/comment_3_5bb0347215b321444643646f25a35759._comment
new file mode 100644
index 000000000..d16392542
--- /dev/null
+++ b/doc/bugs/creating_a_plain_directory_where_a_mountpoint_should_have_been/comment_3_5bb0347215b321444643646f25a35759._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 3"
+ date="2013-05-06T16:52:07Z"
+ content="""
+It's possible, even likely, that there were indeed more directories and I didn't notice because they were hidden and I just looked at them with a vanilla \"ls\" command with no flags like \"-a\".
+
+So it's probably exactly what you're thinking --t here was something going on, a transfer queued or something, that I didn't realize was happening and I removed it and it went and created the directory as if it were there.
+"""]]
diff --git a/doc/bugs/creating_a_plain_directory_where_a_mountpoint_should_have_been/comment_4_73848a9c783ecf3d9fccdd41b20fbe36._comment b/doc/bugs/creating_a_plain_directory_where_a_mountpoint_should_have_been/comment_4_73848a9c783ecf3d9fccdd41b20fbe36._comment
new file mode 100644
index 000000000..7b588ecc7
--- /dev/null
+++ b/doc/bugs/creating_a_plain_directory_where_a_mountpoint_should_have_been/comment_4_73848a9c783ecf3d9fccdd41b20fbe36._comment
@@ -0,0 +1,56 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkfHTPsiAcHEEN7Xl7WxiZmYq-vX7azxFY"
+ nickname="Vincent"
+ subject="comment 4"
+ date="2013-07-24T14:19:01Z"
+ content="""
+I saw this too, today. The repo in my case was created via the webapp, using the 'usb key' option.
+I was messing about with deleting repos and had turned off synchronisation for the repo on the key as I didn't have it inserted.
+
+I only just stumbled on this bug report after removing the repository from the key entirely, so it's difficult to define the reproduction steps.
+
+* create a 'usb key' repo via webapp, transfer type
+* let it sync
+* disable sync
+* change a file in another repo, so there is something to sync
+* unmount key, unplug key
+* turn on sync again - should see 'failed ot sync with ...' in webapp dashboard
+* reinsert key
+* let it sync
+* unplug key without properly unmounting
+* change a file in another repo, so there is something to sync
+
+I just did this. The key was mounting at /Volumes/VERBATIM4. Just after unplugging without unmounting, that directory was gone.
+When I made the change that could be synced, I got a /Volumes/VERBATIM4 directory. The directory tree structure is similar to but different
+from the structure on the usb key, see below.
+
+Now when I try to plug it in again os/x will spot the potential conflict and mount the key at /Volumes/VERBATIM4\ 1.
+
+If I instead rm -rf /Volumes/VERBATIM4 and then replug the usb key, everything syncs as expected.
+
+Version: 4.20130723-ge023649 (os/x 10.8)
+
+Build flags: Assistant Webapp Pairing Testsuite S3 WebDAV FsEvents XMPP DNS
+
+Tree structure of the phantom directory:
+
+ /Volumes/VERBATIM4/annex/
+ └── annex
+ ├── journal.lck
+ ├── objects
+ │   └── df3
+ │   └── 043
+ │   └── SHA256E-s17363--4c5ef74b4fcb9ecd962c6ecac694f87277e580836335e57924654762668a5448
+ │   └── SHA256E-s17363--4c5ef74b4fcb9ecd962c6ecac694f87277e580836335e57924654762668a5448
+ ├── tmp
+ └── transfer
+ ├── download
+ │   └── adf30a67-777a-45a6-a658-e2266770f01b
+ └── failed
+ └── download
+ └── adf30a67-777a-45a6-a658-e2266770f01b
+ └── SHA256E-s17363--4c5ef74b4fcb9ecd962c6ecac694f87277e580836335e57924654762668a5448
+
+ 12 directories, 3 files
+
+"""]]
diff --git a/doc/bugs/creating_a_remote_server_repository.mdwn b/doc/bugs/creating_a_remote_server_repository.mdwn
new file mode 100644
index 000000000..07367d773
--- /dev/null
+++ b/doc/bugs/creating_a_remote_server_repository.mdwn
@@ -0,0 +1,24 @@
+What steps will reproduce the problem?
+
+I was trying to add a remote server repository. Unfortunately, this didn't work. Enter Host name, user name, directory, port
+(left most of them at their default), but there is no way, to specify a password.) Clicking check this server failed:
+
+ Failed to ssh to the server. Transcript: Permission denied, please try again. Permission denied, please try again. Permission denied (publickey,password).
+
+(Problem was, I could never enter a password. Interestingly, on the konsole, I get a prompt for a password, but I can't enter anything there).
+
+
+What is the expected output? What do you see instead?
+
+Successfully create a connection and use the remote server.
+
+
+What version of git-annex are you using? On what operating system?
+Version: 3.20130124
+
+
+
+Please provide any additional information below.
+
+[[!tag /design/assistant done]]
+[[!meta title="ssh password prompting issue with assistant"]]
diff --git a/doc/bugs/creating_a_remote_server_repository/comment_1_de1a370347428245bcfca60eaca96779._comment b/doc/bugs/creating_a_remote_server_repository/comment_1_de1a370347428245bcfca60eaca96779._comment
new file mode 100644
index 000000000..aad008fd0
--- /dev/null
+++ b/doc/bugs/creating_a_remote_server_repository/comment_1_de1a370347428245bcfca60eaca96779._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.3.125"
+ subject="comment 1"
+ date="2013-02-05T19:22:04Z"
+ content="""
+You're not really intended to start the git-annex assistant from a console. If you do, ssh will go ahead and prompt for passwords using that controlling console.
+
+When the assistant is not started from a console, ssh should use the `ssh-askpass` to prompt for the password. Assuming your system has that installed.
+"""]]
diff --git a/doc/bugs/creds_directory_not_automatically_created.mdwn b/doc/bugs/creds_directory_not_automatically_created.mdwn
new file mode 100644
index 000000000..d4e436da4
--- /dev/null
+++ b/doc/bugs/creds_directory_not_automatically_created.mdwn
@@ -0,0 +1,3 @@
+I just compiled ff7810eb83d8372e6206d487c63482d678e0b3d4 and created a new git-annex repository through the setup steps of "git-annex webapp". Then I tried configuring a Jabber account from the webapp. It then failed to create $REPO/.git/annex/creds/xmpp with a "No such file or directory" message because $REPO/.git/annex/creds did not get created. After doing a manual mkdir the Jabber setup went through fine.
+
+> [[Fixed|done]], thanks. --[[Joey]]
diff --git a/doc/bugs/cross_platform_permissions_woes.mdwn b/doc/bugs/cross_platform_permissions_woes.mdwn
new file mode 100644
index 000000000..d67ca4ae0
--- /dev/null
+++ b/doc/bugs/cross_platform_permissions_woes.mdwn
@@ -0,0 +1,36 @@
+a little introduction:
+i am forced to use windows on my work laptop and workstation, also my wife needs windows.
+my "servers" would be linux, i am actually using fedora and i upgraded from fc17 since i was not able to get a recent version of git annex to compile there.
+
+what happens, is that once i try to copy from the windows machine where the file is to the linux through ssh+rsync, i receive this error - as long as the user owning the linux repository isn't root:
+
+ c:\locale>git annex copy --to linux myfile
+ copy myfile (checking linux...) (to linux...)
+ rsync: failed to open "/linux/annex/tmp/SHA256E-s10--937a89b559820f8658892"
+ myfile
+ 10 100% 0.00kB/s 0:00:00 (xfer#1, to-check=0/1)
+ rsync error: syntax or usage error (code 1) at /home/lapo/package/rsync-3.0.9-1/src/rsyn
+ total size is 10 speedup is 0.09
+ failed
+ git-annex: copy: 1 failed
+
+the file in tmp has no permissions at all:
+
+ me@linux annex]$ ls -lart tmp/SHA256E-s10--937a89b559820f86588921ef3eb12c13074d078b62ef205bb597bf2e895408c3
+ ----------. 1 me me 10 Oct 13 22:50 tmp/SHA256Es10--937a89b559820f86588921ef3eb12c13074d078b62ef205bb597bf2e895408c3
+
+(just consider the following if the above makes any sense:) in another case (i cannot reproduce it now, possibly due to having upgraded git annex from some 2012 release), it happened that a failed download via copy/move from linux to windows (failed for permissions) would not be recorded as failed (on windows side), causing files to possibly be killed at the first subsequent drop command.
+
+my question is: are these 0-permissions on tmp files a bug or just due to some ignorance i did put in setting up the git/annex repo ? is a git/annex repo to be run solely as root/sudoer ? or shall i take any other step in configuring it ?
+
+technicalities:
+
+"client": windows version:
+
+ git-annex version: 4.20131002-gf25991c
+
+"server": linux version:
+
+ git-annex version: 3.20130207
+
+> [[done]]; fixed in newer git-annex versions. --[[Joey]]
diff --git a/doc/bugs/cross_platform_permissions_woes/comment_1_7f01104de38a6a319a8f36aa1dc8b4b3._comment b/doc/bugs/cross_platform_permissions_woes/comment_1_7f01104de38a6a319a8f36aa1dc8b4b3._comment
new file mode 100644
index 000000000..a3116cdcf
--- /dev/null
+++ b/doc/bugs/cross_platform_permissions_woes/comment_1_7f01104de38a6a319a8f36aa1dc8b4b3._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="64.134.31.139"
+ subject="comment 1"
+ date="2013-10-15T18:29:10Z"
+ content="""
+Based on the '/linux/annex/' path, your \"linux\" git remote is set up using some sort of network mount of your Linux box to Windows.
+
+If that's the case, then rsync is running on Windows and probably doesn't know anything about permissions, to probably does something horrible when it's told to write a file to the linux filesystem.
+
+If I'm right about that, I can easily fix it, by making git-annex on Windows not use rsync for such file to file copies. But I first need you to verify if I'm right about how your \"linux\" git remote is configured.
+
+(Also, you should be able to work around the problem by changing the git remote to use a ssh:// url to the linux system.)
+"""]]
diff --git a/doc/bugs/cross_platform_permissions_woes/comment_2_0a34e11b466fad287325425e76487fa1._comment b/doc/bugs/cross_platform_permissions_woes/comment_2_0a34e11b466fad287325425e76487fa1._comment
new file mode 100644
index 000000000..8ee7c18a5
--- /dev/null
+++ b/doc/bugs/cross_platform_permissions_woes/comment_2_0a34e11b466fad287325425e76487fa1._comment
@@ -0,0 +1,73 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmCzVCPjgg_Un_114P8iiSwExms0G2csCA"
+ nickname="Michele"
+ subject="details about my problem"
+ date="2013-10-15T23:30:26Z"
+ content="""
+Thank for your answer, but unfortunately the remote is already an ssh (although i agree it should happen most certainly also via samba/cifs mount).
+it happens as long as the remote is NOT defined as root login.
+I suppose it could as well be something with my setup (although i've tried different windows/linux hosts) and I have no idea how to debug it.
+
+this is a transcript of recreating the problem (i've just edited user/hostname):
+
+ Microsoft Windows [Version 6.1.7601]
+ C:\>git init wintest
+ Initialized empty Git repository in C:/wintest/.git/
+ C:\>cd wintest
+ C:\wintest>git annex init wintest
+ init wintest
+ Detected a crippled filesystem.
+ Enabling direct mode.
+ Detected a filesystem without fifo support.
+ Disabling ssh connection caching.
+ ok
+ (Recording state in git...)
+ C:\wintest>echo \"thisisatest\">wintest
+ C:\wintest>git annex add wintest
+ add wintest (checksum...) ok
+ (Recording state in git...)
+ C:\wintest>git remote add remote ssh://me@linuxbox/home/me/testlinux
+ C:\wintest>ssh me@linuxbox
+ [me@home ~]$ git init --bare testlinux
+ Initialized empty Git repository in /home/me/testlinux/
+ [me@home ~]$ cd testlinux/
+ [me@home testlinux]$ git annex init linux
+ init linux ok
+ (Recording state in git...)
+ [me@home testlinux]$ exit
+ C:\wintest>git annex sync
+ commit
+ ok
+ pull remote
+ warning: no common commits
+ remote: Counting objects: 5, done.
+ remote: Compressing objects: 100% (3/3), done.
+ remote: Total 5 (delta 1), reused 0 (delta 0)
+ Unpacking objects: 100% (5/5), done.
+ From ssh://linux/home/me/testlinux
+ * [new branch] git-annex -> remote/git-annex
+ ok
+ (merging remote/git-annex into git-annex...)
+ (Recording state in git...)
+ push remote
+ Counting objects: 18, done.
+ Delta compression using up to 2 threads.
+ Compressing objects: 100% (12/12), done.
+ Writing objects: 100% (16/16), 1.45 KiB, done.
+ Total 16 (delta 2), reused 0 (delta 0)
+ To ssh://me@linux/home/michele/testlinux
+ * [new branch] git-annex -> synced/git-annex
+ * [new branch] master -> synced/master
+ ok
+ C:\wintest>git annex copy --to remote wintest
+ copy wintest (checking remote...) (to remote...)
+ wintest
+ 15 100% 0.00kB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ rsync error: syntax or usage error (code 1) at /home/lapo/package/rsync-3.0.9-1/src/rsync-3.0.9/main.c(1052) [sender=
+ total size is 15 speedup is 0.13
+ failed
+ git-annex: copy: 1 failed
+
+ C:\wintest>
+"""]]
diff --git a/doc/bugs/cross_platform_permissions_woes/comment_3_278f91b4bc4c32717ab1c39c2abf9305._comment b/doc/bugs/cross_platform_permissions_woes/comment_3_278f91b4bc4c32717ab1c39c2abf9305._comment
new file mode 100644
index 000000000..1cfed0a90
--- /dev/null
+++ b/doc/bugs/cross_platform_permissions_woes/comment_3_278f91b4bc4c32717ab1c39c2abf9305._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="64.134.31.139"
+ subject="comment 3"
+ date="2013-10-16T15:47:38Z"
+ content="""
+I think you will have better luck if you upgrade your server's git-annex version. I checked and some fixes for exactly this problem went in around May. Also, testing with the current version, I followed your procedure exactly and did not see the problem.
+"""]]
diff --git a/doc/bugs/cross_platform_permissions_woes/comment_4_eb6a271cb63c71341469c9ff89dc0eb9._comment b/doc/bugs/cross_platform_permissions_woes/comment_4_eb6a271cb63c71341469c9ff89dc0eb9._comment
new file mode 100644
index 000000000..08ebe1e6d
--- /dev/null
+++ b/doc/bugs/cross_platform_permissions_woes/comment_4_eb6a271cb63c71341469c9ff89dc0eb9._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmCzVCPjgg_Un_114P8iiSwExms0G2csCA"
+ nickname="Michele"
+ subject="solved"
+ date="2013-10-18T21:00:38Z"
+ content="""
+installing very recent version on linux solved the problem !!! indeed a bug, but an old one! (quite difficult to get an updated version with cabal on fc19 and so forth, i would add a couple suggestion to share in the fedora install page)
+thank you
+"""]]
diff --git a/doc/bugs/cyclic_drop.mdwn b/doc/bugs/cyclic_drop.mdwn
new file mode 100644
index 000000000..296d61aac
--- /dev/null
+++ b/doc/bugs/cyclic_drop.mdwn
@@ -0,0 +1,104 @@
+drop's verification that a remote still has content can fail
+if the remote is also dropping the content at the same time. Each
+repository checks that the other still has the content, and then both
+drop it. Could also happen with larger cycles of repositories.
+
+> Confirmed fixed now. All cases tested. [[done]]
+
+---
+
+Fixing this requires locking. (Well, there are other ways, like moving the
+content to a holding area when checking if it's safe to drop, but they
+seem complicated, and would be hard to implement for move --from.)
+
+Add per-content lock files. An exclusive lock is held on content when
+it's in the process of being dropped, or moved. The lock is taken
+nonblocking; if it cannot be obtained, something else is acting on the
+content and git-annex should refuse to do anything.
+
+Then when checking inannex, try to take a shared lock. Note that to avoid
+deadlock, this must be a nonblocking lock. (Actually, with fcntl locking,
+can just check if there is a lock, without needing to take one.)
+If it fails, the status of the content is unknown, so inannex should fail.
+Note that this failure needs to be distinguishable from "not in annex".
+
+> Thinking about these lock files, this would be a lot more files,
+> and would possibly break some assumptions that everything in
+> `.git/annex/objects` is a key's content. (Or would need lots more
+> directories to put the lock files elsewhere.) There would be more
+> overhead to manage these and have them on disk.
+>
+> What if it just locked the actual content file? The obvious limitation
+> is only content that was already inannex could be locked, but that
+> happens to be exactly what's needed here; if content is not present,
+> it's not going to get dropped or moved.
+>
+> Of course, if some consumer of a file locked it, then it could prevent it
+> from being dropped or moved. This could be considered a bug, or a feature. :)
+>
+> However, this would mean that such a hypothetical consumer could also
+> make inannex checks fail.
+>
+> The other downside is that, for fcntl exclusive locking, the file has to
+> be opened for write. Normally the modes of content files are locked down
+> to prevent modifcation. Dealt with, but oh so nasty. Almost makes flock
+> locking seem worth using.
+
+---
+
+drop --from could also cycle. Locking should fix.
+
+> Confirmed fixed now.
+
+---
+
+move --to can also be included in the cycle, since it can drop data.
+
+Consider move to a remote that already has the content and
+is at the same time doing a drop (or a move). The remote
+verifies the content is present on the movee, and removes its copy.
+The movee removes its copy.
+
+So move --to needs to take the content lock on start. Then the inannex
+will fail.
+
+This is why it's important for inannex to fail in a way that is
+distinguishable from "not in annex". Otherwise, move --to
+would see the cycle as the remote not having content, and try to
+redundantly send it, drop it locally, and still race.
+
+> Confirmed fixed now.
+
+--
+
+move --from is similar. Consider a case where both the local and the remote
+are doing a move --from. Both have the content, and confirm the other does,
+via inannex checks. Then both run git-annex-shell dropkey, removing both
+copies.
+
+So move --from needs to take the content lock on start, so the inannex will
+fail. NB: If the content is not locally present, don't take the lock.
+
+> Confirmed fixed now.
+
+---
+
+Another cycle might be running move --to and move --from on the same file,
+locally. The exclusivity of the content lock solves this, as only one can
+run at a time.
+
+Would it work with a shared lock? The --to would run git-annex-shell
+inannex. The --from would also be running, and would run git-annex-shell
+dropkey. So inannex and dropkey would end up running on the remote
+at the same time. Dropkey takes the content lock, and inannex checks it,
+but what if inannex runs first? Then it returns true, and then the content
+is removed, so both the --to and --from see success and the --to proceeds
+to remove the local content that the --from already caused to be removed
+from the remote. So, no, the nasty exclusive lock is needed.
+
+> Confirmed fixed now.
+
+---
+
+Another cycle might involve move --from and drop, both run on the same
+file, locally. Again, the exclusive lock solves this.
diff --git a/doc/bugs/data_loss:_incorrect_merge_upon_conflicting_directory-file_of_direct_repos.mdwn b/doc/bugs/data_loss:_incorrect_merge_upon_conflicting_directory-file_of_direct_repos.mdwn
new file mode 100644
index 000000000..8007ae11f
--- /dev/null
+++ b/doc/bugs/data_loss:_incorrect_merge_upon_conflicting_directory-file_of_direct_repos.mdwn
@@ -0,0 +1,199 @@
+### Please describe the problem.
+Data loss due to incorrect merge of repos in direct mode. (I tested the same scenario in indirect mode and it worked fine there)
+
+Given 2 repos A and B, in direct mode:
+
+1. in A: mkdir f, with a file f in it
+2. in B: touch f
+3. in B: sync
+
+Result: Only an f.variant-f###remains, which is file f of B, and the merge conflict has already been automatically resolved. I.e. Directory f containing file f, is lost.
+
+Expected result: remaining contents: f.variant-AAA which is file f of B, f.variant-BBB which is directory f of A, containing a file f. Merge conflict marked resolved.
+
+### What steps will reproduce the problem?
+Execute the script given below in additional information.
+
+### What version of git-annex are you using?
+git-annex version: 4.20130911-g6625d0e
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP Feeds Quvi
+
+### On what operating system?
+Linux basementcat 3.10.10-1-ARCH #1 SMP PREEMPT Fri Aug 30 11:30:06 CEST 2013 x86_64 GNU/Linux
+
+### Please provide any additional information below.
+
+[[!format sh """
+[~]$ mkdir test
+[~/test]$ mkdir a
+[~/test/a]$ git init
+Initialized empty Git repository in /home/limyreth/test/a/.git/
+[~/test/a]$ git annex init test
+init test ok
+(Recording state in git...)
+[~/test/a]$ touch firstfile
+[~/test/a]$ git annex add firstfile
+add firstfile (checksum...) ok
+(Recording state in git...)
+[~/test/a]$ git annex sync
+commit
+ok
+git-annex: no branch is checked out
+[~]$ git clone test/a
+Cloning into 'a'...
+done.
+[~]$ mv a test/b
+[~/test/a]$ git annex direct
+commit
+# On branch master
+nothing to commit, working directory clean
+ok
+direct firstfile ok
+direct ok
+[~/test/a]$ ls -l
+total 0
+-rw-r--r-- 1 limyreth users 0 Oct 12 15:09 firstfile
+[~/test/a]$ mkdir f
+[~/test/a]$ touch f/f
+[~/test/a]$ git annex add f/f
+add f/f (checksum...) ok
+(Recording state in git...)
+[~/test/a]$ git annex sync
+commit
+ok
+[~/test/b]$ git remote -v
+origin /home/limyreth/test/a (fetch)
+origin /home/limyreth/test/a (push)
+[~/test/b]$ ls
+firstfile
+[~/test/b]$ git annex direct
+commit
+(Recording state in git...)
+# On branch master
+nothing to commit, working directory clean
+ok
+direct ok
+[~/test/b]$ touch f
+[~/test/b]$ git annex add f
+add f (checksum...) ok
+(Recording state in git...)
+[~/test/b]$ git annex sync
+(merging origin/git-annex into git-annex...)
+(Recording state in git...)
+commit
+ok
+pull origin
+remote: Counting objects: 14, done.
+remote: Compressing objects: 100% (7/7), done.
+remote: Total 9 (delta 1), reused 0 (delta 0)
+Unpacking objects: 100% (9/9), done.
+From /home/limyreth/test/a
+ 2a8fa45..ad6802d master -> origin/master
+ 1f39016..19e3e12 git-annex -> origin/git-annex
+ * [new branch] synced/master -> origin/synced/master
+
+Adding f/f
+CONFLICT (file/directory): There is a directory with name f in refs/remotes/origin/master. Adding f as f~HEAD
+Automatic merge failed; fix conflicts and then commit the result.
+f: needs merge
+(Recording state in git...)
+ok
+[master 37a8019] git-annex automatic merge conflict fix
+
+Already up-to-date.
+ok
+(merging origin/git-annex into git-annex...)
+(Recording state in git...)
+push origin
+Counting objects: 36, done.
+Delta compression using up to 4 threads.
+Compressing objects: 100% (20/20), done.
+Writing objects: 100% (25/25), 2.16 KiB | 0 bytes/s, done.
+Total 25 (delta 5), reused 0 (delta 0)
+To /home/limyreth/test/a
+ ad6802d..37a8019 master -> synced/master
+ * [new branch] git-annex -> synced/git-annex
+ok
+[~/test/b]$ ls -l
+total 0
+-rw-r--r-- 1 limyreth users 0 Oct 12 15:11 firstfile
+-rw-r--r-- 1 limyreth users 0 Oct 12 15:11 f.variant-f874
+[~/test/b]$ git log --summary
+commit 37a80199abe3cf82100bbdb5dd2217ed6bcb4b62
+Merge: 5a8942a ad6802d
+Author: timdiels <timdiels.m@gmail.com>
+Date: Sat Oct 12 15:11:47 2013 +0200
+
+ git-annex automatic merge conflict fix
+
+commit 5a8942a9a1735cb313c1f6624cbd3f48b252d9d9
+Author: timdiels <timdiels.m@gmail.com>
+Date: Sat Oct 12 15:11:47 2013 +0200
+
+ git-annex automatic sync
+
+ create mode 120000 f
+
+commit ad6802dc231d389b86154e2df900a70b18e17b29
+Author: timdiels <timdiels.m@gmail.com>
+Date: Sat Oct 12 15:11:40 2013 +0200
+
+ git-annex automatic sync
+
+ create mode 120000 f/f
+
+commit 2a8fa45bea996ab5ae219a017d4b642153e6d9c9
+Author: timdiels <timdiels.m@gmail.com>
+Date: Sat Oct 12 15:09:40 2013 +0200
+
+ git-annex automatic sync
+
+ create mode 120000 firstfile
+[~/test/a]$ git annex sync
+(merging synced/git-annex into git-annex...)
+commit
+ok
+merge synced/master
+Updating ad6802d..37a8019
+Fast-forward
+ f.variant-f874 | 1 +
+ f/f | 1 -
+ 2 files changed, 1 insertion(+), 1 deletion(-)
+ create mode 120000 f.variant-f874
+ delete mode 120000 f/f
+ok
+[~/test/a]$ git log --summary
+commit 37a80199abe3cf82100bbdb5dd2217ed6bcb4b62
+Merge: 5a8942a ad6802d
+Author: timdiels <timdiels.m@gmail.com>
+Date: Sat Oct 12 15:11:47 2013 +0200
+
+ git-annex automatic merge conflict fix
+
+commit 5a8942a9a1735cb313c1f6624cbd3f48b252d9d9
+Author: timdiels <timdiels.m@gmail.com>
+Date: Sat Oct 12 15:11:47 2013 +0200
+
+ git-annex automatic sync
+
+ create mode 120000 f
+
+commit ad6802dc231d389b86154e2df900a70b18e17b29
+Author: timdiels <timdiels.m@gmail.com>
+Date: Sat Oct 12 15:11:40 2013 +0200
+
+ git-annex automatic sync
+
+ create mode 120000 f/f
+
+commit 2a8fa45bea996ab5ae219a017d4b642153e6d9c9
+Author: timdiels <timdiels.m@gmail.com>
+Date: Sat Oct 12 15:09:40 2013 +0200
+
+ git-annex automatic sync
+
+ create mode 120000 firstfile
+
+"""]]
+
+> Bug fixed; test case added; [[done]] --[[Joey]]
diff --git a/doc/bugs/data_loss:_incorrect_merge_upon_conflicting_directory-file_of_direct_repos/comment_1_294c33af08649256908a97894f93c05d._comment b/doc/bugs/data_loss:_incorrect_merge_upon_conflicting_directory-file_of_direct_repos/comment_1_294c33af08649256908a97894f93c05d._comment
new file mode 100644
index 000000000..1b22d2ce5
--- /dev/null
+++ b/doc/bugs/data_loss:_incorrect_merge_upon_conflicting_directory-file_of_direct_repos/comment_1_294c33af08649256908a97894f93c05d._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlWskoNgUB7r70OXglR-4iKI4bOuPJb-xg"
+ nickname="Tim"
+ subject="comment 1"
+ date="2013-10-13T12:35:47Z"
+ content="""
+I've just tested a similar scenario with 2 conflicting files, a file-file conflict, and then it works fine. That makes sense, as there's a test written for that.
+
+So the specific bits are: directory-file conflict of repos in direct mode.
+"""]]
diff --git a/doc/bugs/data_loss:_incorrect_merge_upon_conflicting_directory-file_of_direct_repos/comment_2_02a2b69adbb04b557146e713b70b34d2._comment b/doc/bugs/data_loss:_incorrect_merge_upon_conflicting_directory-file_of_direct_repos/comment_2_02a2b69adbb04b557146e713b70b34d2._comment
new file mode 100644
index 000000000..7df35b33d
--- /dev/null
+++ b/doc/bugs/data_loss:_incorrect_merge_upon_conflicting_directory-file_of_direct_repos/comment_2_02a2b69adbb04b557146e713b70b34d2._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="64.134.31.139"
+ subject="comment 2"
+ date="2013-10-16T18:04:27Z"
+ content="""
+I can confirm this bug, thanks for a good reproduction recipe.
+
+However, there is no actual data loss. If you switch to repo to indirect mode, you can use `git checkout` to check out the past versions from before the botched merge. When you do, you'll find that the files that the merge seemingly deleted in fact still have their contents present. It is preserved in `.git/annex/objects` by the automatic merge conflict resolution code, which does that whenever it deletes a file, whether for good reasons or for buggy reasons.
+
+So if you feel you lost data due to this, you can almost certainly get it back and I'm happy to help with that.
+
+
+"""]]
diff --git a/doc/bugs/data_loss:_incorrect_merge_upon_conflicting_directory-file_of_direct_repos/comment_3_d296ef26fc90f4e3166bba6d2de0a1ee._comment b/doc/bugs/data_loss:_incorrect_merge_upon_conflicting_directory-file_of_direct_repos/comment_3_d296ef26fc90f4e3166bba6d2de0a1ee._comment
new file mode 100644
index 000000000..4adee73bd
--- /dev/null
+++ b/doc/bugs/data_loss:_incorrect_merge_upon_conflicting_directory-file_of_direct_repos/comment_3_d296ef26fc90f4e3166bba6d2de0a1ee._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlWskoNgUB7r70OXglR-4iKI4bOuPJb-xg"
+ nickname="Tim"
+ subject="comment 3"
+ date="2013-10-17T16:04:03Z"
+ content="""
+I had a recent backup of the data so no real harm was done.
+"""]]
diff --git a/doc/bugs/data_loss:_incorrect_merge_upon_conflicting_directory-file_of_direct_repos/comment_4_33ba2c890c962a71ae9fadc417359f8e._comment b/doc/bugs/data_loss:_incorrect_merge_upon_conflicting_directory-file_of_direct_repos/comment_4_33ba2c890c962a71ae9fadc417359f8e._comment
new file mode 100644
index 000000000..bff93623c
--- /dev/null
+++ b/doc/bugs/data_loss:_incorrect_merge_upon_conflicting_directory-file_of_direct_repos/comment_4_33ba2c890c962a71ae9fadc417359f8e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlWskoNgUB7r70OXglR-4iKI4bOuPJb-xg"
+ nickname="Tim"
+ subject="comment 4"
+ date="2013-10-31T19:44:34Z"
+ content="""
+Has this issue been fixed? I checked out the repository today and compiled with cabal, but I don't see a f.variant-A and a f.variant-B pop up after sync.
+"""]]
diff --git a/doc/bugs/data_loss:_incorrect_merge_upon_conflicting_directory-file_of_direct_repos/comment_5_39eb0bb96fd271bd0de4a3a40814ae1b._comment b/doc/bugs/data_loss:_incorrect_merge_upon_conflicting_directory-file_of_direct_repos/comment_5_39eb0bb96fd271bd0de4a3a40814ae1b._comment
new file mode 100644
index 000000000..0e5d67f74
--- /dev/null
+++ b/doc/bugs/data_loss:_incorrect_merge_upon_conflicting_directory-file_of_direct_repos/comment_5_39eb0bb96fd271bd0de4a3a40814ae1b._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 5"
+ date="2013-11-01T15:48:21Z"
+ content="""
+AFAIK this bug is fixed, which is why I wrote above, \"Bug fixed; test case added; done\"
+
+If you have reason to think otherwise, better follow up.
+
+"""]]
diff --git a/doc/bugs/data_loss:_incorrect_merge_upon_conflicting_directory-file_of_direct_repos/comment_6_d80c4b631bdf58901a06f29a2c5682e2._comment b/doc/bugs/data_loss:_incorrect_merge_upon_conflicting_directory-file_of_direct_repos/comment_6_d80c4b631bdf58901a06f29a2c5682e2._comment
new file mode 100644
index 000000000..29457da8a
--- /dev/null
+++ b/doc/bugs/data_loss:_incorrect_merge_upon_conflicting_directory-file_of_direct_repos/comment_6_d80c4b631bdf58901a06f29a2c5682e2._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlWskoNgUB7r70OXglR-4iKI4bOuPJb-xg"
+ nickname="Tim"
+ subject="comment 6"
+ date="2013-11-14T14:58:10Z"
+ content="""
+Ah indeed, tried it again and it's indeed fixed. Tried some other things as well, and conflict resolution ended up doing just fine.
+"""]]
diff --git a/doc/bugs/data_loss_with___34__git_annex_add__34___on_android_in_direct_mode_.mdwn b/doc/bugs/data_loss_with___34__git_annex_add__34___on_android_in_direct_mode_.mdwn
new file mode 100644
index 000000000..65560f245
--- /dev/null
+++ b/doc/bugs/data_loss_with___34__git_annex_add__34___on_android_in_direct_mode_.mdwn
@@ -0,0 +1,19 @@
+**What steps will reproduce the problem?**
+
+> git annex add .
+
+**What is the expected output? What do you see instead?**
+
+This was with direct mode turned on. Distinct files should remain distinct. Instead, many of the original files were overwritten and became copies of one of the other files.
+
+**What version of git-annex are you using? On what operating system?**
+
+Running rooted android on a Samsung Galaxy Nexus. Working in a system directory which is not "crippled".
+The git-annex package was dated 2013-03-23 and downloaded from
+> https://downloads.kitenet.net/git-annex/android/current/
+
+**Please provide any additional information below.**
+
+I wish I could provide files that became duplicates, but I didn't make copies before adding them... Did this twice, first adding JPG and MP4 files, then adding WAVs. After that, I saw that of 100 JPGs and 8 MP4s, about half the JPGs and all of the MP4s had become copies of a single JPG. Of 11 WAV files, two had been replaced with copies of one of the others.
+
+> [[done]]; turned out to be Android bug unrelated to git-annex. --[[Joey]]
diff --git a/doc/bugs/data_loss_with___34__git_annex_add__34___on_android_in_direct_mode_/comment_1_eb6db7f6a156a065e2724c2de5fc4366._comment b/doc/bugs/data_loss_with___34__git_annex_add__34___on_android_in_direct_mode_/comment_1_eb6db7f6a156a065e2724c2de5fc4366._comment
new file mode 100644
index 000000000..a0af0bc8f
--- /dev/null
+++ b/doc/bugs/data_loss_with___34__git_annex_add__34___on_android_in_direct_mode_/comment_1_eb6db7f6a156a065e2724c2de5fc4366._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-04-01T18:28:21Z"
+ content="""
+Are you sure these files did not already have the same content before you ran git-annex on them?
+
+Can you show me the output of `git show` when run on some of these files?
+"""]]
diff --git a/doc/bugs/data_loss_with___34__git_annex_add__34___on_android_in_direct_mode_/comment_2_59a96cade9e4881767562a139fc7fb4b._comment b/doc/bugs/data_loss_with___34__git_annex_add__34___on_android_in_direct_mode_/comment_2_59a96cade9e4881767562a139fc7fb4b._comment
new file mode 100644
index 000000000..f62c2e69e
--- /dev/null
+++ b/doc/bugs/data_loss_with___34__git_annex_add__34___on_android_in_direct_mode_/comment_2_59a96cade9e4881767562a139fc7fb4b._comment
@@ -0,0 +1,40 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn26WQjIP5fnMgQF_L_k3Q3UrR5v8mjRTY"
+ nickname="Ellis"
+ subject="comment 2"
+ date="2013-04-02T20:18:05Z"
+ content="""
+*Are you sure these files did not already have the same content before you ran git-annex on them?*
+
+Yes, each one was a distinct photo, video, or audio recording. The only operation performed between creation and ``git annex add`` was moving them into the import directory from the command line via e.g. ``mv /sdcard/DCIM/Camera/* .``.
+
+If you'd like, I'll try to find a set of files to reproduce the problem with.
+
+*Can you show me the output of git show when run on some of these files?*
+
+Sure. Here are two WAV files. The first one was correctly stored, and the second one is now a duplicate of the first.
+
+ commit bb282af90745c8a50e74c1f724e6cc708bfa9591
+ Author: Ellis Whitehead <ellis@****>
+ Date: Mon Apr 1 17:05:19 2013 +0200
+
+ git-annex automatic sync
+
+ diff --git a/import/2013-03-02_13-57-08_jeromin.wav b/import/2013-03-02_13-57-08_jeromin.wav
+ new file mode 120000
+ index 0000000..55a8cf1
+ --- /dev/null
+ +++ b/import/2013-03-02_13-57-08_jeromin.wav
+ @@ -0,0 +1 @@
+ +../.git/annex/objects/VG/vf/SHA256E-s49222316--acd9b8f94981543c601461c4cb602dae4e7d9d9a72654a3915c6e9d0221791b7.wav/SHA256E-s49222316--acd9b8f94981543c601461c4cb602dae4e7d9d9a72654a3915c6e9d0221791b7.wav
+ \ No newline at end of file
+ diff --git a/import/2013-03-02_14-06-11_karina.wav b/import/2013-03-02_14-06-11_karina.wav
+ new file mode 120000
+ index 0000000..55a8cf1
+ --- /dev/null
+ +++ b/import/2013-03-02_14-06-11_karina.wav
+ @@ -0,0 +1 @@
+ +../.git/annex/objects/VG/vf/SHA256E-s49222316--acd9b8f94981543c601461c4cb602dae4e7d9d9a72654a3915c6e9d0221791b7.wav/SHA256E-s49222316--acd9b8f94981543c601461c4cb602dae4e7d9d9a72654a3915c6e9d0221791b7.wav
+ \ No newline at end of file
+
+"""]]
diff --git a/doc/bugs/data_loss_with___34__git_annex_add__34___on_android_in_direct_mode_/comment_3_bf9d2562d66f0f6a9478ac178606cf4e._comment b/doc/bugs/data_loss_with___34__git_annex_add__34___on_android_in_direct_mode_/comment_3_bf9d2562d66f0f6a9478ac178606cf4e._comment
new file mode 100644
index 000000000..2cc257839
--- /dev/null
+++ b/doc/bugs/data_loss_with___34__git_annex_add__34___on_android_in_direct_mode_/comment_3_bf9d2562d66f0f6a9478ac178606cf4e._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-04-02T21:34:50Z"
+ content="""
+The truely odd thing about this is that when git-annex adds a direct mode file, it does *not* touch the file at all. The file is left right where it is.
+
+This is even the case if two files have the same SHA checksum. I have just verified that even in this case; neither file is touched in any way by `git annex add`.
+
+(Obviously, I never saw anything like this when working with git-annex on Android. I hope this is not some evil April Fools prank.)
+"""]]
diff --git a/doc/bugs/data_loss_with___34__git_annex_add__34___on_android_in_direct_mode_/comment_4_ad0dbdc448fff2e126ffec9aac6d7463._comment b/doc/bugs/data_loss_with___34__git_annex_add__34___on_android_in_direct_mode_/comment_4_ad0dbdc448fff2e126ffec9aac6d7463._comment
new file mode 100644
index 000000000..47c53ac84
--- /dev/null
+++ b/doc/bugs/data_loss_with___34__git_annex_add__34___on_android_in_direct_mode_/comment_4_ad0dbdc448fff2e126ffec9aac6d7463._comment
@@ -0,0 +1,23 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn26WQjIP5fnMgQF_L_k3Q3UrR5v8mjRTY"
+ nickname="Ellis"
+ subject="comment 4"
+ date="2013-04-03T09:02:44Z"
+ content="""
+*The truely odd thing about this is that when git-annex adds a direct mode file, it does not touch the file at all. The file is left right where it is.*
+
+After further investigation, I've managed to reproduce the error, and it is **not** caused by git-annex, but by a limitation in my device's sdcard overlay (I can now see that I was using it in an unintended fashion). Sorry to have taken your time with this. However, the following information may be useful for others who might also want to use git-annex from the android console to manager their media.
+
+Some android devices don't have sdcards (they are the ones which want you to use MTP (Media Transfer Protocol) to transfer data via a USB cable). These devices emulate an sdcard for use by apps. On my Samsung Galaxy Nexus, the emulated sdcard is at ``/sdcard``. If your device is rooted, you will find the equivalent \"real\" filesystem at ``/data/media/0``. There is apparently a limitation in the sdcard emulator which causes ``mv`` commands involving multiple files to semi-randomly fail when moving files from ``/sdcard`` to ``/data/media/0``. What happens is that the command will randomly tend to replace some of the files in the move with a hardlink to another one of the files. I have encountered no problems when moving files from ``/sdcard`` any other destination.
+
+So **don't do this** (or variants of it):
+
+ $ mv /sdcard/DCIM/Camera/* /data/media/0/annex-on-a-good-fs/import
+
+My reason for placing the repository under ``/data/media/0/`` is so that git-annex can use a non-crippled filesystem, but at the same time other apps can access the data under ``/sdcard``. To get around the above problem, either of these two commands can be used:
+
+ $ mv /sdcard/DCIM/Camera/* /sdcard/annex-on-a-good-fs/import
+ $ mv /data/media/0/DCIM/Camera/* /data/media/0/annex-on-a-good-fs/import
+
+@joey: the instructions say to link this bug to ``done`` when it's closed, but I don't see how to do that? Or should it be deleted, since it wasn't a git-annex bug at all?
+"""]]
diff --git a/doc/bugs/data_loss_with___34__git_annex_add__34___on_android_in_direct_mode_/comment_5_e828585e56b10710598143483ce362b6._comment b/doc/bugs/data_loss_with___34__git_annex_add__34___on_android_in_direct_mode_/comment_5_e828585e56b10710598143483ce362b6._comment
new file mode 100644
index 000000000..847226699
--- /dev/null
+++ b/doc/bugs/data_loss_with___34__git_annex_add__34___on_android_in_direct_mode_/comment_5_e828585e56b10710598143483ce362b6._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 5"
+ date="2013-04-04T16:03:50Z"
+ content="""
+I'll close the bug.
+
+FWIW, I developed git-annex on an Android device with such an emulated filesystem for /sdcard. It's a FUSE filesystem with a terrible implementation. I found multiple syscalls that just failed, and was careful to avoid using them.
+
+Personally, the benefits of non-crippled filesystem do not seem worth the bother of doing what you're doing..
+"""]]
diff --git a/doc/bugs/direct_mode_assistant_in_subdir_confusion.mdwn b/doc/bugs/direct_mode_assistant_in_subdir_confusion.mdwn
new file mode 100644
index 000000000..a705e434f
--- /dev/null
+++ b/doc/bugs/direct_mode_assistant_in_subdir_confusion.mdwn
@@ -0,0 +1,37 @@
+I ran the assistant in a subdir in direct mode, and it seemed to move files from other places outside that subdir
+into it, and commit them there. These may have been files that needed to be committed, and it just staged them to the wrong place.
+
+I'm pretty sure this does not affect indirect mode.
+
+--[[Joey]]
+
+The relevant commit, in my family's annex is
+22e694549d698922389deb017c39c2b40371cdf0 --[[Joey]]
+
+Was able to reproduce this as follows:
+
+1. Make 2 repositories A and B, with B in direct mode.
+2. In A, touch topfile; git annex add topfile; git annex sync
+3. In B: mkdir subdir; cd subdir; git annex assistant
+
+Result is a subdir/topfile appearing in B, which is wrong.
+
+<pre>
+ subdir/topfile | 1 +
+ topfile | 1 -
+</pre>
+
+Note that manually doing a git-annex sync in B's subdir does not cause this
+to happen. It's specific to the assistant somehow.
+
+--[[Joey]]
+
+Before 2407170eaf78d9aa38d73d1af68c20da9882779b, git-annex sync in a subdir
+had the same problem. That made it always run from the top of the work
+tree, which its code actually assumes is the case.
+
+The assistant, however, does not do that, and it's useful in general to
+only run it in a subdir.
+
+> Made sync merge code handle this correctly. Conflicted merge handing code
+> was already ok. [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/direct_mode_assistant_in_subdir_confusion/comment_1_351143deec29e712f8718a373ad650d7._comment b/doc/bugs/direct_mode_assistant_in_subdir_confusion/comment_1_351143deec29e712f8718a373ad650d7._comment
new file mode 100644
index 000000000..aa134bd8e
--- /dev/null
+++ b/doc/bugs/direct_mode_assistant_in_subdir_confusion/comment_1_351143deec29e712f8718a373ad650d7._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.145"
+ subject="comment 1"
+ date="2013-08-03T20:15:17Z"
+ content="""
+Only seems to affect initial startup scan; files added outside the subdir after it was started up were not committed (which is the desired behavior when running the webapp in a subdir).
+"""]]
diff --git a/doc/bugs/direct_mode_renames.mdwn b/doc/bugs/direct_mode_renames.mdwn
new file mode 100644
index 000000000..60f449300
--- /dev/null
+++ b/doc/bugs/direct_mode_renames.mdwn
@@ -0,0 +1,15 @@
+When in direct mode, renaming a file with `git mv` does not update the
+direct mode mapping to use the new filename. --[[Joey]]
+
+Consistency checks now prevent anything bad happening when the mapping file
+contains old filenames. Still, missing the new filename will prevent that
+file working properly in direct mode.
+
+Perhaps the pre-commit hook needs to update the mapping for files that were
+deleted or added.
+
+This also affects moves of files when the assistant is being used.
+In this case, the assistant updates the mapping to add the new name,
+but does not delete the old name from the mapping.
+
+> [[done]]; the pre-commit hook now updates the mappings. --[[Joey]]
diff --git a/doc/bugs/direct_mode_renames/comment_1_f18c335e0d6f4259d2470935ef391cb8._comment b/doc/bugs/direct_mode_renames/comment_1_f18c335e0d6f4259d2470935ef391cb8._comment
new file mode 100644
index 000000000..aaf43a24e
--- /dev/null
+++ b/doc/bugs/direct_mode_renames/comment_1_f18c335e0d6f4259d2470935ef391cb8._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkZktNHFhxC1kYA9KKdKpYJO4clq9WDsjE"
+ nickname="Jason"
+ subject="comment 1"
+ date="2013-02-06T06:35:21Z"
+ content="""
+I'm not sure if this matters, but in my case I wasn't even using `git mv`, I was just using `mv`.
+"""]]
diff --git a/doc/bugs/direct_mode_sync_should_avoid_git_commit.mdwn b/doc/bugs/direct_mode_sync_should_avoid_git_commit.mdwn
new file mode 100644
index 000000000..ed4bb8f47
--- /dev/null
+++ b/doc/bugs/direct_mode_sync_should_avoid_git_commit.mdwn
@@ -0,0 +1,5 @@
+Per forum post linking to this bug, git commit can be very slow when run in a filesystem without symlink support, and seems to be reading the content of files just in order to show typechanged messages in the status.
+
+So, git annex sync should stop using git commit when in direct mode, and instead manually make its own commit. Git.Branch.commit and Git.Branch.update should be able to easily be used for this.
+
+PS: this page was created elsewhere, and therefore not listed in bugs page
diff --git a/doc/bugs/direct_repository_on_FAT32_fails_to_addurl_containing___63__.mdwn b/doc/bugs/direct_repository_on_FAT32_fails_to_addurl_containing___63__.mdwn
new file mode 100644
index 000000000..1afb9ac14
--- /dev/null
+++ b/doc/bugs/direct_repository_on_FAT32_fails_to_addurl_containing___63__.mdwn
@@ -0,0 +1,44 @@
+### Please describe the problem.
+
+git-annex attempts to create files with question marks in them on my direct repository on a FAT32 drive. This fails.
+
+### What steps will reproduce the problem?
+
+git annex addurl 'http://rf.proxycast.org/m/media/273073201426.mp3?c=culture&p=La+t%C3%AAte+au+carr%C3%A9_10212&l3=20131002&l4=&media_url=http%3A%2F%2Fmedia.radiofrance-podcast.net%2Fpodcast09%2F10212-02.10.2013-ITEMA_20531825-0.mp3'
+
+### What version of git-annex are you using? On what operating system?
+
+[[!format sh """
+$ cat /etc/lsb-release
+DISTRIB_ID=Ubuntu
+DISTRIB_RELEASE=12.04
+DISTRIB_CODENAME=precise
+DISTRIB_DESCRIPTION="Ubuntu 12.04.3 LTS"
+
+$ git annex version
+git-annex version: 4.20130922-g7dc188a
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP Feeds Quvi
+local repository version: 4
+default repository version: 3
+supported repository versions: 3 4
+upgrade supported from repository versions: 0 1 2
+"""]]
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+$ git annex addurl 'http://rf.proxycast.org/m/media/273073201426.mp3?c=culture&p=La+t%C3%AAte+au+carr%C3%A9_10212&l3=20131002&l4=&media_url=http%3A%2F%2Fmedia.radiofrance-podcast.net%2Fpodcast09%2F10212-02.10.2013-ITEMA_20531825-0.mp3'
+addurl rf.proxycast.org_m_media_273073201426.mp3_c=culture&p=La+t%C3%AAte+au+carr%C3%A9_10212&l3=20131002&l4=&media_url=http%3A%2F%2Fmedia.radiofrance-podcast.net%2Fpodcast09%2F10212-02.10.2013-ITEMA_20531825-0.mp3 (downloading http://rf.proxycast.org/m/media/273073201426.mp3?c=culture&p=La+t%C3%AAte+au+carr%C3%A9_10212&l3=20131002&l4=&media_url=http%3A%2F%2Fmedia.radiofrance-podcast.net%2Fpodcast09%2F10212-02.10.2013-ITEMA_20531825-0.mp3 ...)
+/media/sixtyfour/audio/.git/annex/tmp/URL--http&c%%rf.proxycast.org%m%media%273073201426.mp3?c=culture&ap=La+t&sC3&sAAte+au+carr&sC3&sA9_10212&al3=20131002&al4=&amedia_url=http&s3A-86e83c2aaa925b3bc337c1d6a27bd300: Argument invalide
+
+git-annex: /media/sixtyfour/audio/.git/annex/transfer/failed/download/00000000-0000-0000-0000-000000000001/URL--http&c%%rf.proxycast.org%m%media%273073201426.mp3?c=culture&ap=La+t&sC3&sAAte+au+carr&sC3&sA9_10212&al3=20131002&al4=&amedia_url=http&s3A-86e83c2aaa925b3bc337c1d6a27bd300: openFile: invalid argument (Invalid argument)
+failed
+git-annex: addurl: 1 failed
+
+# End of transcript or log.
+"""]]
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/directory_remote_+_shared_encryption_+_chunk_size___61___lost_files__63__.mdwn b/doc/bugs/directory_remote_+_shared_encryption_+_chunk_size___61___lost_files__63__.mdwn
new file mode 100644
index 000000000..8ee66da19
--- /dev/null
+++ b/doc/bugs/directory_remote_+_shared_encryption_+_chunk_size___61___lost_files__63__.mdwn
@@ -0,0 +1,51 @@
+### Please describe the problem.
+
+When I create a directory special remote, with encryption enabled (shared) and a chunk size restriction (any), I can copy files *to* the remote, but git annex can't find/access them afterwards.
+
+If I do the same, just without specifying chunk size, it works fine. Restricting chunk size on FAT filesystems to something less that 4GB is necessary (otherwise storing bigger files will just fail).
+
+### What steps will reproduce the problem?
+
+Assume `~/annex` is a normal git annex repository and it contains a file `data.file`.
+
+ # cd ~/annex
+ # mkdir /tmp/remote
+ # git annex initremote dirremote type=directory directory=/tmp/remote encryption=shared chunksize="300 megabytes"
+ initremote dirremote (encryption setup) (shared cipher) ok
+ (Recording state in git...)
+ # git annex copy --to dirremote data.file
+ copy data.file (gpg) (to dirremote...)
+ ok
+ (Recording state in git...)
+ # git annex fsck --from dirremote
+ fsck data.file (gpg) (fixing location log)
+ ** Based on the location log, data.file
+ ** was expected to be present, but its content is missing.
+ failed
+ (Recording state in git...)
+ git-annex: fsck: 1 failed
+
+The file is actually in the remote, e.g. `ls -R /tmp/remote` (shortened output):
+
+ /tmp/remote/be5/af7/GPGHMACSHA1--cb23b50579bf69be9cdc0243b6fda1f66218eb43:
+ GPGHMACSHA1--cb23b50579bf69be9cdc0243b6fda1f66218eb43
+ GPGHMACSHA1--cb23b50579bf69be9cdc0243b6fda1f66218eb43.chunkcount
+
+### What version of git-annex are you using? On what operating system?
+
+- mac OS X (10.8.5)
+- git-annex version: 4.20131002-gf25991c
+- `PATH` variable has `/Applications/git-annex.app/Contents/MacOS/bundle` at the front, so if git-annex comes with a binary, it is used
+
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
+
+> [[done]]; see my comment. --[[Joey]]
diff --git a/doc/bugs/directory_remote_+_shared_encryption_+_chunk_size___61___lost_files__63__/comment_1_69dfbf566c75396cdaaf5ad70f1a94a8._comment b/doc/bugs/directory_remote_+_shared_encryption_+_chunk_size___61___lost_files__63__/comment_1_69dfbf566c75396cdaaf5ad70f1a94a8._comment
new file mode 100644
index 000000000..e068501ad
--- /dev/null
+++ b/doc/bugs/directory_remote_+_shared_encryption_+_chunk_size___61___lost_files__63__/comment_1_69dfbf566c75396cdaaf5ad70f1a94a8._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 1"
+ date="2013-10-26T19:06:38Z"
+ content="""
+There was a bug that caused it not to write the chunkcount file.
+I have fixed it, and put in a workaround so fsck, etc, will
+see that the file is stored on the remote despite there being no
+chunkcount file present.
+
+I was initially puzzled by your output showing the chunkcount file being present.
+However, the bug also caused it to write a chunkcount file when chunking was disabled (ie, the logic for when to write the file was inverted).
+So, I think that the ls you show is after you set up the remote without specifying chunk size, and copied a file to it.
+
+Please test with the next autobuild of git-annex (should be one within an hour my my posting this comment) and verify it can now see the files you stored on the remote with chunking.
+
+
+"""]]
diff --git a/doc/bugs/directory_remote_+_shared_encryption_+_chunk_size___61___lost_files__63__/comment_2_8d09cc0e06548c4ebde7956edd1b5d85._comment b/doc/bugs/directory_remote_+_shared_encryption_+_chunk_size___61___lost_files__63__/comment_2_8d09cc0e06548c4ebde7956edd1b5d85._comment
new file mode 100644
index 000000000..81d6b35a3
--- /dev/null
+++ b/doc/bugs/directory_remote_+_shared_encryption_+_chunk_size___61___lost_files__63__/comment_2_8d09cc0e06548c4ebde7956edd1b5d85._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://jspk.clavid.com/"
+ nickname="flabbergast"
+ subject="comment 2"
+ date="2013-10-28T09:36:19Z"
+ content="""
+Thanks! I've checked now and the problem is gone.
+"""]]
diff --git a/doc/bugs/directory_remote_and_case_sensitivity_on_FAT/comment_1_bcac9fd7b3f4a2ac28bee59bae674fa0._comment b/doc/bugs/directory_remote_and_case_sensitivity_on_FAT/comment_1_bcac9fd7b3f4a2ac28bee59bae674fa0._comment
new file mode 100644
index 000000000..be8b8b0a7
--- /dev/null
+++ b/doc/bugs/directory_remote_and_case_sensitivity_on_FAT/comment_1_bcac9fd7b3f4a2ac28bee59bae674fa0._comment
@@ -0,0 +1,79 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnBJ6Dv1glxzzi4qIzGFNa6F-mfHIvv9Ck"
+ nickname="Jim"
+ subject="Case sensitivity"
+ date="2011-11-22T18:51:03Z"
+ content="""
+I agree, it's weird, but that's what I'm seeing:
+
+ #!/bin/sh
+
+ if [ $UID != 0 ] ; then echo \"need root\" ; exit 1 ; fi
+
+ set -x
+
+ # make image
+ cd /tmp
+ dd if=/dev/zero of=diskimage bs=1M count=40
+ DEV=$(losetup --find --show diskimage)
+
+ # make FAT32 fs
+ mkfs.vfat -F 32 $DEV
+
+ # mount it
+ mkdir annex
+ mount -o shortname=mixed,utf8=1 $DEV annex
+
+ # show bug
+ (
+ cd annex
+ mkdir zP
+ mkdir Zp
+ ls Zp
+ ls
+ touch zP
+ touch Zp
+ )
+
+ # cleanup
+ umount annex
+ rm -r annex
+ losetup -d $DEV
+ rm diskimage
+
+ # info
+ uname -a
+
+Output:
+
+ + cd /tmp
+ + dd if=/dev/zero of=diskimage bs=1M count=40
+ 40+0 records in
+ 40+0 records out
+ 41943040 bytes (42 MB) copied, 0.0847729 s, 495 MB/s
+ ++ losetup --find --show diskimage
+ + DEV=/dev/loop0
+ + mkfs.vfat -F 32 /dev/loop0
+ mkfs.vfat 3.0.9 (31 Jan 2010)
+ Loop device does not match a floppy size, using default hd params
+ + mkdir annex
+ + mount -o shortname=mixed,utf8=1 /dev/loop0 annex
+ + cd annex
+ + mkdir zP
+ + mkdir Zp
+ mkdir: cannot create directory `Zp': File exists
+ + ls Zp
+ ls: cannot access Zp: No such file or directory
+ + ls
+ zP
+ + touch zP
+ + touch Zp
+ touch: cannot touch `Zp': File exists
+ + umount annex
+ + rm -r annex
+ + losetup -d /dev/loop0
+ + rm diskimage
+ + uname -a
+ Linux pilot 3.0.3+ #1 SMP Mon Aug 29 15:21:18 EDT 2011 x86_64 GNU/Linux
+
+"""]]
diff --git a/doc/bugs/directory_remote_and_case_sensitivity_on_FAT/comment_2_c9088060fb9133b66951f1a3075981e8._comment b/doc/bugs/directory_remote_and_case_sensitivity_on_FAT/comment_2_c9088060fb9133b66951f1a3075981e8._comment
new file mode 100644
index 000000000..5040b3120
--- /dev/null
+++ b/doc/bugs/directory_remote_and_case_sensitivity_on_FAT/comment_2_c9088060fb9133b66951f1a3075981e8._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 2"
+ date="2011-11-22T19:56:55Z"
+ content="""
+All right, I see the same thing with linux 3.1.0. It seems this behavior has changed since linux 3.0.0. Mounting with shortname=lower avoids the problem.
+
+I feel a good case could be made that this new behavior is a linux bug. Your example with touch particularly shows how weird it is.
+
+<pre>
+$ touch Foo
+$ echo hi > foo
+sh: cannot create foo: File exists
+$ rm foo
+rm: cannot remove `foo': No such file or directory
+</pre>
+"""]]
diff --git a/doc/bugs/directory_remote_and_case_sensitivity_on_FAT/comment_3_5bf34466187cfc9b34bd3ca8c89a07c6._comment b/doc/bugs/directory_remote_and_case_sensitivity_on_FAT/comment_3_5bf34466187cfc9b34bd3ca8c89a07c6._comment
new file mode 100644
index 000000000..54d6ff50a
--- /dev/null
+++ b/doc/bugs/directory_remote_and_case_sensitivity_on_FAT/comment_3_5bf34466187cfc9b34bd3ca8c89a07c6._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnBJ6Dv1glxzzi4qIzGFNa6F-mfHIvv9Ck"
+ nickname="Jim"
+ subject="comment 3"
+ date="2011-11-22T20:35:01Z"
+ content="""
+I see the same results (\"`touch: cannot touch 'Zp': File exists`\") on these Debian systems:
+
+ Linux pilot 3.0.3+ #1 SMP Mon Aug 29 15:21:18 EDT 2011 x86_64 GNU/Linux
+ Linux neurosis 3.0.0-1-amd64 #1 SMP Sun Jul 24 02:24:44 UTC 2011 x86_64 GNU/Linux
+ Linux bucket 2.6.39-2-amd64 #1 SMP Tue Jul 5 02:51:22 UTC 2011 x86_64 GNU/Linux
+ Linux psychosis 2.6.37-trunk-amd64 #1 SMP Thu Jan 6 14:13:28 UTC 2011 x86_64 GNU/Linux
+ Linux bacon 2.6.32-5-amd64 #1 SMP Thu Aug 12 13:01:50 UTC 2010 x86_64 GNU/Linux
+
+It does NOT happen on this Ubuntu system:
+
+ Linux esensor 3.0.0-12-generic #20-Ubuntu SMP Fri Oct 7 14:56:25 UTC 2011 x86_64 x86_64 x86_64 GNU/Linux
+
+So really it seems like only the Ubuntu kernel is the outlier here? Maybe it has something to do with charsets or something; I think FAT is a mess in that regard and even long versus short filenames can behave differently.
+"""]]
diff --git a/doc/bugs/directory_remote_and_case_sensitivity_on_FAT/comment_4_d6201f2d86d5b44051a7fd7a8c9de583._comment b/doc/bugs/directory_remote_and_case_sensitivity_on_FAT/comment_4_d6201f2d86d5b44051a7fd7a8c9de583._comment
new file mode 100644
index 000000000..406a6b18e
--- /dev/null
+++ b/doc/bugs/directory_remote_and_case_sensitivity_on_FAT/comment_4_d6201f2d86d5b44051a7fd7a8c9de583._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 4"
+ date="2011-11-22T20:59:55Z"
+ content="""
+Your ubuntu system has 3.0.0 which as noted does not have the problem.
+"""]]
diff --git a/doc/bugs/directory_remote_and_case_sensitivity_on_FAT/comment_5_61c5f0889f30a68ac3b57c4ea564ee0e._comment b/doc/bugs/directory_remote_and_case_sensitivity_on_FAT/comment_5_61c5f0889f30a68ac3b57c4ea564ee0e._comment
new file mode 100644
index 000000000..1656ff207
--- /dev/null
+++ b/doc/bugs/directory_remote_and_case_sensitivity_on_FAT/comment_5_61c5f0889f30a68ac3b57c4ea564ee0e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 5"
+ date="2011-11-22T21:01:14Z"
+ content="""
+I am surprised if it happens on 2.6.x though. Debian 3.0.0 seemed to not have the problem but perhaps my test was bad.
+"""]]
diff --git a/doc/bugs/done.mdwn b/doc/bugs/done.mdwn
new file mode 100644
index 000000000..a35d42719
--- /dev/null
+++ b/doc/bugs/done.mdwn
@@ -0,0 +1,4 @@
+recently fixed [[bugs]]
+
+[[!inline pages="./* and link(./done) and !*/Discussion" sort=mtime show=10
+archive=yes]]
diff --git a/doc/bugs/dotdot_problem.mdwn b/doc/bugs/dotdot_problem.mdwn
new file mode 100644
index 000000000..cbefd5dae
--- /dev/null
+++ b/doc/bugs/dotdot_problem.mdwn
@@ -0,0 +1,4 @@
+cannot "git annex ../foo" (GitRepo.relative is buggy and
+git-ls-files also refuses w/o --full-name, which would need other changes)
+
+[[done]]
diff --git a/doc/bugs/drop_fails_to_see_copies_that_whereis_sees.mdwn b/doc/bugs/drop_fails_to_see_copies_that_whereis_sees.mdwn
new file mode 100644
index 000000000..59b76c92b
--- /dev/null
+++ b/doc/bugs/drop_fails_to_see_copies_that_whereis_sees.mdwn
@@ -0,0 +1,69 @@
+What steps will reproduce the problem?
+------------------------------------------------------
+
+I haven't tried doing this again, but here's what I did:
+
+I was copying files to my usb drive (hugex) with probably this command:
+
+ git annex copy --to=hugex .
+
+While doing that, I did something stupid in another window, and filled my local hard drive (the one I was copying from) and git annex spit out some errors about not being able to write to log files (because my local drive was full.)
+
+I suspended (^Z) git annex, made some hard drive space, then resumed (fg).
+
+At first, git annex whereis didn't see the copies of some of the files in hugex (apparently the ones where git annex had trouble writing the local log files). After a "git remote update hugex" and I think a ``git annex merge``, whereis was able to see both copies.
+
+But git drop can't see both copies, and won't let me drop my local copy. I ran ``git annex fsck .`` on the directory with the now files I was copying above, and that didn't seem to change anything (or report errors.)
+
+Here's a terminal session where I'm showing the problem and some hopefully useful text:
+
+ compy compy compy ~/video/tv/keen-eddie> git annex whereis 02-horse-heir.avi
+ whereis 02-horse-heir.avi (2 copies)
+ 5bfe091c-ed07-11df-842e-eb791a485889 -- here (compy)
+ e15161ec-f1bf-11df-a7b5-eb1f0e6921ee -- hugex
+ ok
+ compy compy compy ~/video/tv/keen-eddie> git annex drop 02-horse-heir.avi
+ drop 02-horse-heir.avi (unsafe)
+ Could only verify the existence of 1 out of 2 necessary copies
+
+ No other repository is known to contain the file.
+
+ (Use --force to override this check, or adjust annex.numcopies.)
+ failed
+ git-annex: drop: 1 failed
+ zsh: exit 1 git annex drop 02-horse-heir.avi
+ compy compy compy ~/video/tv/keen-eddie> ls -lh 02-horse-heir.avi
+ lrwxrwxrwx 1 jasonwoof jasonwoof 149 Nov 15 04:19 02-horse-heir.avi -> ../../../.git/annex/objects/KV/8G/SHA1-s358316330--7fcbf33b711e41def269f042842212d0bf3736a7/SHA1-s358316330--7fcbf33b711e41def269f042842212d0bf3736a7
+ compy compy compy ~/video/tv/keen-eddie> ls --dereference -lh 02-horse-heir.avi
+ -r--r--r-- 1 jasonwoof jasonwoof 342M Nov 15 04:19 02-horse-heir.avi
+ compy compy compy ~/video/tv/keen-eddie> ls -lh ../../../.git/annex/objects/KV/8G/SHA1-s358316330--7fcbf33b711e41def269f042842212d0bf3736a7/SHA1-s358316330--7fcbf33b711e41def269f042842212d0bf3736a7
+ -r--r--r-- 1 jasonwoof jasonwoof 342M Nov 15 04:19 ../../../.git/annex/objects/KV/8G/SHA1-s358316330--7fcbf33b711e41def269f042842212d0bf3736a7/SHA1-s358316330--7fcbf33b711e41def269f042842212d0bf3736a7
+ compy compy compy ~/video/tv/keen-eddie> ls -lh /media/hugex/jason/home.git/annex/objects/5bd/6a1/SHA1-s358316330--7fcbf33b711e41def269f042842212d0bf3736a7/SHA1-s358316330--7fcbf33b711e41def269f042842212d0bf3736a7
+ -r--r--r-- 1 jasonwoof jasonwoof 342M Jan 7 16:27 /media/hugex/jason/home.git/annex/objects/5bd/6a1/SHA1-s358316330--7fcbf33b711e41def269f042842212d0bf3736a7/SHA1-s358316330--7fcbf33b711e41def269f042842212d0bf3736a7
+
+That last command is showing that the file is indeed in hugex's annex/objects
+
+
+Oh, and another wrinkle. hugex is a bare repo. I tried to fsck hugex's video/tv directory, but it said that directory doesn't exist (I assume because there's no working copy.)
+
+
+What is the expected output? What do you see instead?
+------------------------------------------------------------------------------
+
+I'd like ``git annex drop`` to have the same kind of confidence in the copies of these files on hugex.
+
+How can I resolve this. I tried ``git annex copy --to=hugex .`` again, but that command knows that these files are already copied to hugex.
+
+What version of git-annex are you using? On what operating system?
+
+3.20130102 on debian unstable (thanks for packaging!)
+
+Please provide any additional information below.
+------------------------------------------------------------------
+
+You can also reach me at ``jason@jasonwoof.com``
+
+> [[done]]; the confusing message has been improved.
+>
+> BTW, you can use `git annex move` to ensure a file is on another repo and
+> drop it locally. --[[Joey]]
diff --git a/doc/bugs/drop_fails_to_see_copies_that_whereis_sees/comment_1_f5a9d99d90daf5eba4773d361fa1807a._comment b/doc/bugs/drop_fails_to_see_copies_that_whereis_sees/comment_1_f5a9d99d90daf5eba4773d361fa1807a._comment
new file mode 100644
index 000000000..647c6db3a
--- /dev/null
+++ b/doc/bugs/drop_fails_to_see_copies_that_whereis_sees/comment_1_f5a9d99d90daf5eba4773d361fa1807a._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.211"
+ subject="comment 1"
+ date="2013-01-08T18:43:33Z"
+ content="""
+So, the first part of this is git-annex behaving as designed. When there's a fatal disk problem and it cannot update its local location log, only the remote's location log gets updated. After a `git annex sync` (or your manual equivilant), the location log changes get propigated from the remote, and the local repository returns to a consistent state.
+
+As to the drop problem, look at it again. You have numcopies configured to 2, and there are currently 2 copies of the file. So dropping 1 would leave the numcopies constraint unsatisfied, and so it doesn't. You can override --numcopies 1 or --force the drop, but I don't see a bug here.
+
+(Perhaps the \"No other repository is known to contain the file.\" message is confusing in this context? It doesn't mean that no other repo has the file at all, but that there are no other repositories, that it was not able to check, that might have the file. If you had another removable drive with the file, and the drive was detached, this message would instead say \"Try making some of these repositories available: otherdrive\")
+
+(Re fscking in a bare repo, in a bare repository, you cannot fsck specific files/directories; fsck just checks every single key that git-annex knows about.)
+"""]]
diff --git a/doc/bugs/drop_fails_to_see_copies_that_whereis_sees/comment_2_040aa454cd8acd2857ef36884465576f._comment b/doc/bugs/drop_fails_to_see_copies_that_whereis_sees/comment_2_040aa454cd8acd2857ef36884465576f._comment
new file mode 100644
index 000000000..58f69646b
--- /dev/null
+++ b/doc/bugs/drop_fails_to_see_copies_that_whereis_sees/comment_2_040aa454cd8acd2857ef36884465576f._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://jasonwoof.com/"
+ nickname="JasonWoof"
+ subject="Thank you."
+ date="2013-01-08T23:02:33Z"
+ content="""
+First off, awesome that git annex auto-fixes itself after I make hard drive space and merge.
+
+The problem was that I didn't realize that my .gitattributes that were supposed to set numcopies to 1 didn't work. (Because I didn't realize that they don't apply recursively.) I fixed my .gitattributes, and then was able to drop those files.
+
+And you are right that the text \"No other repository is known to contain the file\" threw me off. Perhaps when numcopies > 1 you could change that message to \"Not enough other repositories are known to contain the file\".
+
+Thank you.
+
+-- Jason
+"""]]
diff --git a/doc/bugs/drop_fails_to_see_copies_that_whereis_sees/comment_3_f5d8faab325ee26800ecad5aba49b54b._comment b/doc/bugs/drop_fails_to_see_copies_that_whereis_sees/comment_3_f5d8faab325ee26800ecad5aba49b54b._comment
new file mode 100644
index 000000000..ca6287dd6
--- /dev/null
+++ b/doc/bugs/drop_fails_to_see_copies_that_whereis_sees/comment_3_f5d8faab325ee26800ecad5aba49b54b._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://jasonwoof.com/"
+ nickname="JasonWoof"
+ subject="language suggestions"
+ date="2013-01-09T04:31:40Z"
+ content="""
+Maybe it could read \"Could not verify that enough copies of the file exist to safely drop it\". Or \"Could not verify that enough other repositories contain this file to safely drop it.\"
+
+It might be cool (if this isn't supported already) if there was a command to drop a file that would automatically copy it to another repo first if needed to satisfy numcopies.
+"""]]
diff --git a/doc/bugs/dropping_and_re-adding_from_web_remotes_doesn__39__t_work.mdwn b/doc/bugs/dropping_and_re-adding_from_web_remotes_doesn__39__t_work.mdwn
new file mode 100644
index 000000000..30327ba1f
--- /dev/null
+++ b/doc/bugs/dropping_and_re-adding_from_web_remotes_doesn__39__t_work.mdwn
@@ -0,0 +1,139 @@
+In experimenting with the web remote, I found that dropping a URL gave an error, but still succeeded, while re-adding the same URL fails to work correctly.
+
+#What steps will reproduce the problem?
+
+<pre>
+/tmp $ dd if=/dev/zero of=/tmp/file.bin count=1024
+1024+0 records in
+1024+0 records out
+524288 bytes (524 kB) copied, 0.0135652 s, 38.6 MB/s
+/tmp $ mkdir /tmp/repo
+/tmp $ cd /tmp/repo
+/tmp/repo $ git init
+Initialized empty Git repository in /tmp/repo/.git/
+/tmp/repo $ git annex init "test"
+init test ok
+(Recording state in git...)
+/tmp/repo $ git annex addurl file:///tmp/file.bin --file annexed.bin
+######################################################################## 100.0%
+(checksum...) ok
+(Recording state in git...)
+/tmp/repo $ git annex drop annexed.bin
+drop annexed.bin (checking file:///tmp/file.bin...) ok
+(Recording state in git...)
+/tmp/repo $ mv /tmp/file.bin /tmp/file2.bin
+/tmp/repo $ git annex get annexed.bin
+get annexed.bin (from web...)
+curl: (37) Couldn't open file /tmp/file.bin
+
+ Unable to access these remotes: web
+
+ Try making some of these repositories available:
+ 00000000-0000-0000-0000-000000000001 -- web
+failed
+git-annex: get: 1 failed
+/tmp/repo $ git annex drop --from web annexed.bin --force
+drop web annexed.bin
+ removal from web not supported
+failed
+(Recording state in git...)
+git-annex: drop: 1 failed
+/tmp/repo $ git annex get annexed.bin
+get annexed.bin (not available)
+ No other repository is known to contain the file.
+failed
+git-annex: get: 1 failed
+/tmp/repo $ mv /tmp/file2.bin /tmp/file.bin
+/tmp/repo $ git annex addurl file:///tmp/file.bin --file annexed.bin
+addurl annexed.bin ok
+/tmp/repo $ git annex whereis annexed.bin
+whereis annexed.bin (0 copies) failed
+git-annex: whereis: 1 failed
+/tmp/repo $ git annex addurl file:///tmp/file.bin --file annexed2.bin
+######################################################################## 100.0%
+(checksum...) ok
+(Recording state in git...)
+/tmp/repo $ git annex whereis annexed.bin
+whereis annexed.bin (1 copy)
+ e2418e81-ec04-4091-aabe-ed75d65f93fa -- here (test)
+ok
+/tmp/repo $ git annex whereis annexed2.bin
+whereis annexed2.bin (1 copy)
+ e2418e81-ec04-4091-aabe-ed75d65f93fa -- here (test)
+ok
+/tmp/repo $ git annex drop annexed.bin
+drop annexed.bin (unsafe)
+ Could only verify the existence of 0 out of 1 necessary copies
+
+ No other repository is known to contain the file.
+
+ (Use --force to override this check, or adjust annex.numcopies.)
+failed
+git-annex: drop: 1 failed
+/tmp/repo $ git annex drop annexed2.bin
+drop annexed2.bin (unsafe)
+ Could only verify the existence of 0 out of 1 necessary copies
+
+ No other repository is known to contain the file.
+
+ (Use --force to override this check, or adjust annex.numcopies.)
+failed
+git-annex: drop: 1 failed
+/tmp/repo $ mv /tmp/file.bin /tmp/file2.bin
+/tmp/repo $ git annex addurl file:///tmp/file2.bin --file annexed.bin
+addurl annexed.bin ok
+(Recording state in git...)
+/tmp/repo $ git annex whereis annexed2.bin
+whereis annexed2.bin (2 copies)
+ 00000000-0000-0000-0000-000000000001 -- web
+ e2418e81-ec04-4091-aabe-ed75d65f93fa -- here (test)
+
+ web: file:///tmp/file.bin
+ web: file:///tmp/file2.bin
+ok
+/tmp/repo $ mv /tmp/file2.bin /tmp/file.bin
+/tmp/repo $ git annex drop annexed.bin
+drop annexed.bin (checking file:///tmp/file.bin...) ok
+(Recording state in git...)
+/tmp/repo $ git annex get annexed.bin
+get annexed.bin (from web...)
+######################################################################## 100.0%
+ok
+(Recording state in git...)
+/tmp/repo $ git annex drop annexed.bin
+drop annexed.bin (checking file:///tmp/file.bin...) ok
+(Recording state in git...)
+/tmp/repo $ mv /tmp/file.bin /tmp/file2.bin
+/tmp/repo $ git annex get annexed.bin
+get annexed.bin (from web...)
+curl: (37) Couldn't open file /tmp/file.bin
+######################################################################## 100.0%
+ok
+(Recording state in git...)
+</pre>
+
+#What is the expected output? What do you see inst
+
+
+When dropping one file and I see "git-annex: drop: 1 failed" I would expect the file to still be in the remote as far as git-annex is concerned.
+
+When re-adding the URL, I expect the file to be re-added to the web remote. (note that it re-appears after adding the same file via a different URL)
+
+
+#What version of git-annex are you using? On what operating system?
+
+
+3.20121112 on Gentoo Linux
+
+
+#Please provide any additional information below.
+
+This seems to be a corner case, and would probably have minimal impact on most people.
+
+> Yeah, dropping from the web is pretty weird.
+>
+> I guess it makes sense to do if a website stops having a file and you don't
+> want git-annex to try to download from it anymore. So, I've made dropping
+> from the web remove all urls associated with the file, rather than failing.
+>
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/dropping_files_with_a_URL_backend_fails.mdwn b/doc/bugs/dropping_files_with_a_URL_backend_fails.mdwn
new file mode 100644
index 000000000..c6ef13f84
--- /dev/null
+++ b/doc/bugs/dropping_files_with_a_URL_backend_fails.mdwn
@@ -0,0 +1,13 @@
+I was trying out the example with the walkthrough using_the_URL_backend. I tried dropping files that I had after doing an "git annex get ." which have the URL backend associated with the files it fails with
+
+
+<pre>
+[jtang@lenny gc]$ git annex drop -v curl-7.21.4.tar.gz
+drop curl-7.21.4.tar.gz
+failed
+git-annex: 1 failed
+</pre>
+
+At first I thought it was just my OSX machine not having the coreutils stuff load up before the BSD utils, but I then tried the same thing on my archlinux machine and it showed the same behaviour, that is I could not drop a file with the URL backend as shown in the walkthrough.
+
+> Whoops, got some logic backwards. [[fixed|done]]! --[[Joey]]
diff --git a/doc/bugs/dropunused_doesn__39__t_handle_double_spaces_in_filename.mdwn b/doc/bugs/dropunused_doesn__39__t_handle_double_spaces_in_filename.mdwn
new file mode 100644
index 000000000..a6b44cd2a
--- /dev/null
+++ b/doc/bugs/dropunused_doesn__39__t_handle_double_spaces_in_filename.mdwn
@@ -0,0 +1,87 @@
+Unused files with double spaces in their name are not removed by `dropunused`:
+
+Script:
+
+ #!/bin/bash
+
+ BASE=/tmp/unused-bug
+
+ # setup
+ set -x
+ chmod -R +w $BASE
+ rm -rf $BASE
+ mkdir -p $BASE
+ cd $BASE
+
+ # create annex
+ git init .
+ git annex init
+
+ # make a file with two spaces
+ echo hello > 'foo bar'
+
+ # add it
+ git annex add --backend WORM 'foo bar'
+ git commit -m 'add'
+
+ # remove it
+ git rm 'foo bar'
+ git commit -m 'remove'
+
+ # unused
+ git annex unused
+ git annex dropunused 1
+ git annex unused
+
+Output:
+
+ + chmod -R +w /tmp/unused-bug
+ + rm -rf /tmp/unused-bug
+ + mkdir -p /tmp/unused-bug
+ + cd /tmp/unused-bug
+ + git init .
+ Initialized empty Git repository in /tmp/unused-bug/.git/
+ + git annex init
+ init ok
+ + echo hello
+ + git annex add --backend WORM 'foo bar'
+ add foo bar ok
+ (Recording state in git...)
+ + git commit -m add
+ [master (root-commit) 926f7f5] add
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+ create mode 120000 foo bar
+ + git rm 'foo bar'
+ rm 'foo bar'
+ + git commit -m remove
+ [master d025e3f] remove
+ 1 files changed, 0 insertions(+), 1 deletions(-)
+ delete mode 120000 foo bar
+ + git annex unused
+ unused . (checking for unused data...) (checking master...)
+ Some annexed data is no longer used by any files:
+ NUMBER KEY
+ 1 WORM-s6-m1322200438--foo bar
+ (To see where data was previously used, try: git log --stat -S'KEY')
+
+ To remove unwanted data: git-annex dropunused NUMBER
+
+ ok
+ + git annex dropunused 1
+ dropunused 1 ok
+ + git annex unused
+ unused . (checking for unused data...) (checking master...)
+ Some annexed data is no longer used by any files:
+ NUMBER KEY
+ 1 WORM-s6-m1322200438--foo bar
+ (To see where data was previously used, try: git log --stat -S'KEY')
+
+ To remove unwanted data: git-annex dropunused NUMBER
+
+ ok
+
+Strange that `dropunused` still said "ok" when it didn't succeed at removing the file.
+
+> It was misparsing the unused file, so it thought you'd asked it to drop a
+> key that didn't exist (which means already dropped) so no error. I've
+> fixed the bug. [[done]] --[[Joey]]
diff --git a/doc/bugs/dropunused_doesn__39__t_work_in_my_case__63__.mdwn b/doc/bugs/dropunused_doesn__39__t_work_in_my_case__63__.mdwn
new file mode 100644
index 000000000..7428b091a
--- /dev/null
+++ b/doc/bugs/dropunused_doesn__39__t_work_in_my_case__63__.mdwn
@@ -0,0 +1,70 @@
+What steps will reproduce the problem?
+
+I am unable to create a minimal setup to reproduce this unfortunately. But my case is the following:
+
+* Two synced repos, I have switched between direct and indirect in both, currently they are indirect
+* I have two submodules in the repos (not related to the unuesd files)
+
+* I used "git rm -r" to remove a bunch of files along with "git mv" to move some
+* I have three commits of actions like this
+
+* In one repo, the one where I did the deletions, I have 172 unused files, and all seem to come from the first of the three commits
+* In the second repo, to which I synced, I have 188 unused files, which includes a couple of files from the third commit as well
+
+* If I try to dropunused either a single file or the whole range of the files, from either repo, I get git-annex telling me "ok, recording state" but when I run unused again the files are still there. And looking into .git/objects/annex/ the file is still present
+
+This is the debug from the drop command:
+
+ dropunused 9 [2013-02-07 12:47:24 CET] read: git ["--git-dir=/home/arand/.git","--work-tree=/home/arand","show-ref","git-annex"]
+ [2013-02-07 12:47:24 CET] read: git ["--git-dir=/home/arand/.git","--work-tree=/home/arand","show-ref","--hash","refs/heads/git-annex"]
+ [2013-02-07 12:47:24 CET] read: git ["--git-dir=/home/arand/.git","--work-tree=/home/arand","log","refs/heads/git-annex..5f3fc9db5c7badb5fb25c3159c20584f11dadaf9","--oneline","-n1"]
+ [2013-02-07 12:47:24 CET] read: git ["--git-dir=/home/arand/.git","--work-tree=/home/arand","log","refs/heads/git-annex..8e5674078706864f2eade86d8aa43027e05afc1d","--oneline","-n1"]
+ [2013-02-07 12:47:24 CET] read: git ["--git-dir=/home/arand/.git","--work-tree=/home/arand","log","refs/heads/git-annex..cbe492cfa79728698f5d891d7f716fbcd9fc29e2","--oneline","-n1"]
+ [2013-02-07 12:47:24 CET] read: git ["--git-dir=/home/arand/.git","--work-tree=/home/arand","log","refs/heads/git-annex..48a1bdf98a10ad9a81c0587f8909e94c1c0dccc4","--oneline","-n1"]
+ [2013-02-07 12:47:24 CET] chat: git ["--git-dir=/home/arand/.git","--work-tree=/home/arand","cat-file","--batch"]
+ [2013-02-07 12:47:24 CET] read: git ["config","--null","--list"]
+ [2013-02-07 12:47:24 CET] chat: git ["--git-dir=/home/arand/.git","--work-tree=/home/arand","hash-object","-w","--stdin-paths"]
+ [2013-02-07 12:47:24 CET] feed: git ["--git-dir=/home/arand/.git","--work-tree=/home/arand","update-index","-z","--index-info"]
+ [2013-02-07 12:47:24 CET] read: git ["--git-dir=/home/arand/.git","--work-tree=/home/arand","show-ref","--hash","refs/heads/git-annex"]
+ [2013-02-07 12:47:24 CET] read: git ["--git-dir=/home/arand/.git","--work-tree=/home/arand","write-tree"]
+ [2013-02-07 12:47:24 CET] chat: git ["--git-dir=/home/arand/.git","--work-tree=/home/arand","commit-tree","76f5041bc6e8a109e0309a09b5f36cd0da8b204a","-p","refs/heads/git-annex"]
+ [2013-02-07 12:47:24 CET] call: git ["--git-dir=/home/arand/.git","--work-tree=/home/arand","update-ref","refs/heads/git-annex","96de755475bdd8f0f948dd6421c3956803a63e66"]
+ ok
+ (Recording state in git...)
+
+If I run it again, I get:
+
+ dropunused 9 [2013-02-07 12:47:47 CET] read: git ["--git-dir=/home/arand/.git","--work-tree=/home/arand","show-ref","git-annex"]
+ [2013-02-07 12:47:47 CET] read: git ["--git-dir=/home/arand/.git","--work-tree=/home/arand","show-ref","--hash","refs/heads/git-annex"]
+ [2013-02-07 12:47:47 CET] read: git ["--git-dir=/home/arand/.git","--work-tree=/home/arand","log","refs/heads/git-annex..96de755475bdd8f0f948dd6421c3956803a63e66","--oneline","-n1"]
+ [2013-02-07 12:47:48 CET] read: git ["--git-dir=/home/arand/.git","--work-tree=/home/arand","log","refs/heads/git-annex..8e5674078706864f2eade86d8aa43027e05afc1d","--oneline","-n1"]
+ [2013-02-07 12:47:48 CET] read: git ["--git-dir=/home/arand/.git","--work-tree=/home/arand","log","refs/heads/git-annex..cbe492cfa79728698f5d891d7f716fbcd9fc29e2","--oneline","-n1"]
+ [2013-02-07 12:47:48 CET] read: git ["--git-dir=/home/arand/.git","--work-tree=/home/arand","log","refs/heads/git-annex..48a1bdf98a10ad9a81c0587f8909e94c1c0dccc4","--oneline","-n1"]
+ [2013-02-07 12:47:48 CET] chat: git ["--git-dir=/home/arand/.git","--work-tree=/home/arand","cat-file","--batch"]
+ [2013-02-07 12:47:48 CET] read: git ["config","--null","--list"]
+ [2013-02-07 12:47:48 CET] chat: git ["--git-dir=/home/arand/.git","--work-tree=/home/arand","hash-object","-w","--stdin-paths"]
+ [2013-02-07 12:47:48 CET] feed: git ["--git-dir=/home/arand/.git","--work-tree=/home/arand","update-index","-z","--index-info"]
+ [2013-02-07 12:47:48 CET] read: git ["--git-dir=/home/arand/.git","--work-tree=/home/arand","show-ref","--hash","refs/heads/git-annex"]
+ [2013-02-07 12:47:48 CET] read: git ["--git-dir=/home/arand/.git","--work-tree=/home/arand","write-tree"]
+ [2013-02-07 12:47:48 CET] chat: git ["--git-dir=/home/arand/.git","--work-tree=/home/arand","commit-tree","e40d82db10c60519f6a3a72055e9577850972fdf","-p","refs/heads/git-annex"]
+ [2013-02-07 12:47:48 CET] call: git ["--git-dir=/home/arand/.git","--work-tree=/home/arand","update-ref","refs/heads/git-annex","6cf49f629251f9b39fa8b457cf6590c71c1d509b"]
+ ok
+ (Recording state in git...)
+
+
+What version of git-annex are you using? On what operating system?
+
+git-annex: 3.20130124
+Debian: sid 2013-02-01
+
+> I put a fix in for this in 57780cb3a4dfe1292b72e1412ec4d2a70b6d04ce
+> but it was buggy and I had to revert it.
+>
+> The bug is caused by direct mode cache and mapping info.
+> This makes getKeysPresent find keys that are not present.
+> It would be expensive to make getKeysPresent check that the
+> actual key files are present (it just lists the directories).
+> But this seems to be needed, since direct mode can leave
+> cache and mapping files behind. --[[Joey]]
+
+>> Now fixed properly. [[done]] --[[Joey]]
diff --git a/doc/bugs/encfs_accused_of_being_crippled.mdwn b/doc/bugs/encfs_accused_of_being_crippled.mdwn
new file mode 100644
index 000000000..617233670
--- /dev/null
+++ b/doc/bugs/encfs_accused_of_being_crippled.mdwn
@@ -0,0 +1,41 @@
+### Please describe the problem.
+
+I tried to create an annex (``git annex init foo``) inside a ``encfs`` mount, and git-annex says that it's crippled, and disables core.symlinks and goes into direct mode
+
+### What steps will reproduce the problem?
+
+ apt-get install encfs
+ encfs -o kernel_cache empty_dir other_empty_dir
+ cd other_empty_dir
+ git init
+ git annex init foo
+
+### Expected results
+
+ init foo ok
+ (Recording state in git...)
+
+### Actual results
+
+ init foo
+ Detected a crippled filesystem.
+
+ Disabling core.symlinks.
+
+ Enabling direct mode.
+ ok
+ (Recording state in git...)
+
+### What version of git-annex are you using? On what operating system?
+
+4.20130601 on debian unstable
+
+
+### P.S.
+
+This was particularly annoying when I tried this on a bare repository. I'm pretty sure bare repositories don't need symlinks, and should definitely not be in direct mode. Hopefully you can fix it before I have time to file another bug report :)
+
+Thank you!
+
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/encfs_accused_of_being_crippled/comment_1_5c5be012e1171ef108f38825d72791b6._comment b/doc/bugs/encfs_accused_of_being_crippled/comment_1_5c5be012e1171ef108f38825d72791b6._comment
new file mode 100644
index 000000000..aa6eb9345
--- /dev/null
+++ b/doc/bugs/encfs_accused_of_being_crippled/comment_1_5c5be012e1171ef108f38825d72791b6._comment
@@ -0,0 +1,23 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-06-10T17:22:11Z"
+ content="""
+encfs appears to not allow creation of hard links to files:
+
+[[!format sh \"\"\"
+joey@gnu:~/tmp/other_empty_dir>ln me me2
+ln: failed to create hard link `me2' => `me': Operation not permitted
+\"\"\"]]
+
+According to the documentation, this is a limitation when using External IV Chaining. And only a problem if you choose paranoia mode when setting up encfs.
+
+git-annex uses hard links in a limited number of code paths, most notably `git annex add` uses them when locking down files.
+
+encfs seems like something I'd like to interoperate well with git-annex. So, it seems worthwhile to break out lack of hard links support from the other limitations currently lumped into \"cripped file system\". I've done so.
+
+----
+
+Also made it stop setting direct mode on bare repositories, although that configuration had no effect anyway.
+"""]]
diff --git a/doc/bugs/encrpyted_ssh_remote_on_macosx.mdwn b/doc/bugs/encrpyted_ssh_remote_on_macosx.mdwn
new file mode 100644
index 000000000..ed269277c
--- /dev/null
+++ b/doc/bugs/encrpyted_ssh_remote_on_macosx.mdwn
@@ -0,0 +1,42 @@
+### Please describe the problem.
+Could not get ssh-askpass running on macosx.
+Transfered the publich key with scp.
+certificate based ssh from macosx to ssh server (debian testing) works.
+After successfull login to ssh server git annex stops with the following errors:
+
+Browser Error Message:
+user error (gpg ["--batch","--no-tty","--use-agent","--quiet","--trust-model","always","--gen-random","--armor","1","512"] exited 2)
+
+### What steps will reproduce the problem?
+1. git annex on debian gnu linux
+2. git annex on macosx
+3. set up "share with a friend"
+4. create rsa keys on macosx "ssh-kegen -t rsa"
+5. scp public key to server with hosts encrypted ssh remote
+6. configure the server use a encrypted ssh remote in tranport mode
+
+### What version of git-annex are you using? On what operating system?
+current debian testing (20130827)
+macosx 20130827
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+(scanning...) [2013-09-28 17:39:25 CEST] Watcher: Performing startup scan
+(started...) [2013-09-28 17:39:26 CEST] XMPPSendPack: Syncing with jlueters
+Everything up-to-date
+[2013-09-28 17:39:30 CEST] XMPPSendPack: Unable to download files from jlueters.
+
+(encryption setup) gpg: /Users/lambert/.gnupg/gpg.conf:241: invalid auto-key-locate list
+28/Sep/2013:17:40:06 +0200 [Error#yesod-core] user error (gpg ["--batch","--no-tty","--use-agent","--quiet","--trust-model","always","--gen-random","--armor","1","512"] exited 2) @(yesod-core-1.1.8.3:Yesod.Internal.Core ./Yesod/Internal/Core.hs:550:5)
+(encryption setup) gpg: /Users/lambert/.gnupg/gpg.conf:241: invalid auto-key-locate list
+28/Sep/2013:17:40:48 +0200 [Error#yesod-core] user error (gpg ["--batch","--no-tty","--use-agent","--quiet","--trust-model","always","--gen-random","--armor","1","512"] exited 2) @(yesod-core-1.1.8.3:Yesod.Internal.Core ./Yesod/Internal/Core.hs:550:5)
+
+
+
+# End of transcript or log.
+"""]]
+
+> [[dup|done]] --[[Joey]]
diff --git a/doc/bugs/encrpyted_ssh_remote_on_macosx/comment_1_46c37aacb7ae41864488fb7c7d87d437._comment b/doc/bugs/encrpyted_ssh_remote_on_macosx/comment_1_46c37aacb7ae41864488fb7c7d87d437._comment
new file mode 100644
index 000000000..948b2c110
--- /dev/null
+++ b/doc/bugs/encrpyted_ssh_remote_on_macosx/comment_1_46c37aacb7ae41864488fb7c7d87d437._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.80"
+ subject="comment 1"
+ date="2013-09-29T19:13:59Z"
+ content="""
+This is a duplicate of this bug report: [[Error_creating_encrypted_cloud_repository: \"internal_server_error\"]]
+
+To work around, you need to edit ~/.gnupg/gpg.conf and remove or edit the `auto-key-locate` line.
+"""]]
diff --git a/doc/bugs/encrypted_S3_stalls.mdwn b/doc/bugs/encrypted_S3_stalls.mdwn
new file mode 100644
index 000000000..109e6e793
--- /dev/null
+++ b/doc/bugs/encrypted_S3_stalls.mdwn
@@ -0,0 +1,9 @@
+Sending large-ish (few megabytes) files to encrypted S3 remotes stalls out.
+It works for the tiny files I was using to test while developing it, on
+dialup.
+
+There was a similar issue with bup, which I fixed by forking a process
+rather than using a thread to do some IO. Probably need the same here.
+--[[Joey]]
+
+[[done]] --[[Joey]]
diff --git a/doc/bugs/encryption_given_a_gpg_keyid_still_uses_symmetric_encryption.mdwn b/doc/bugs/encryption_given_a_gpg_keyid_still_uses_symmetric_encryption.mdwn
new file mode 100644
index 000000000..15bc95f27
--- /dev/null
+++ b/doc/bugs/encryption_given_a_gpg_keyid_still_uses_symmetric_encryption.mdwn
@@ -0,0 +1,46 @@
+What steps will reproduce the problem?
+ % > git annex initremote glacier type=glacier encryption=E9053BDA
+ -- SNIP --
+ initremote glacier [2013-01-10 14:50:12 PST] read: gpg ["--quiet","--trust-model","always","--with-colons","--list-public-keys","E9053BDA"]
+ [2013-01-10 14:50:12 PST] chat: gpg ["--quiet","--trust-model","always","--decrypt"]
+
+ You need a passphrase to unlock the secret key for
+ user: "Andrew Mark Kraut <akraut@gmail.com>"
+ 4096-bit ELG key, ID 353E49B9, created 2008-11-11 (main key ID E9053BDA)
+
+ [2013-01-10 14:50:13 PST] chat: gpg ["--quiet","--trust-model","always","--encrypt","--no-encrypt-to","--no-default-recipient","--recipient","B608B8F6E9053BDA"]
+ (encryption updated with gpg key B608B8F6E9053BDA) [2013-01-10 14:50:13 PST] call: glacier ["--region=us-west-1","vault","create","glacier-06D927EC-5761-447B-86AC-CA66040BAC25"]
+ [2013-01-10 14:50:13 PST] call: git ["--git-dir=/Users/akraut/Desktop/annex/.git","--work-tree=/Users/akraut/Desktop/annex","config","remote.glacier.annex-glacier","true"]
+ [2013-01-10 14:50:13 PST] call: git ["--git-dir=/Users/akraut/Desktop/annex/.git","--work-tree=/Users/akraut/Desktop/annex","config","remote.glacier.annex-uuid","06D927EC-5761-447B-86AC-CA66040BAC25"]
+ (gpg) [2013-01-10 14:50:13 PST] chat: gpg ["--quiet","--trust-model","always","--decrypt"]
+
+ You need a passphrase to unlock the secret key for
+ user: "Andrew Mark Kraut <akraut@gmail.com>"
+ 4096-bit ELG key, ID 353E49B9, created 2008-11-11 (main key ID E9053BDA)
+
+ [2013-01-10 14:50:14 PST] chat: gpg ["--quiet","--trust-model","always","--passphrase-fd","8","--symmetric","--force-mdc"]
+ ok
+
+What is the expected output? What do you see instead?
+
+> I expect any transfers to this remote (glacier) to use the given gpg key, but instead it uses --symmetric, as you can see above.
+
+What version of git-annex are you using? On what operating system?
+
+ git-annex version: 3.20130107
+ local repository version: 3
+ default repository version: 3
+ supported repository versions: 3
+ upgrade supported from repository versions: 0 1 2
+
+
+Please provide any additional information below.
+
+> Symmetric encryption is used as described in [[design/encryption]],
+> with the symmetric key stored encrypted using your gpg key.
+>
+> The extra prompting described in the comments in the bug.
+>
+> I've reproduced this with gpg 2.0.19. It is a documented incompatability
+> between gpg 1.x and 2.x; the latter needs --batch included in its
+> parameters. I've put in a fix. [[done]]
diff --git a/doc/bugs/encryption_given_a_gpg_keyid_still_uses_symmetric_encryption/comment_1_2f4ec4b7b92a0f0a0c4c0758da4a05a5._comment b/doc/bugs/encryption_given_a_gpg_keyid_still_uses_symmetric_encryption/comment_1_2f4ec4b7b92a0f0a0c4c0758da4a05a5._comment
new file mode 100644
index 000000000..d4c537ed9
--- /dev/null
+++ b/doc/bugs/encryption_given_a_gpg_keyid_still_uses_symmetric_encryption/comment_1_2f4ec4b7b92a0f0a0c4c0758da4a05a5._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmRFKwny4rArBaz-36xTcsJYqKIgdDaw5Q"
+ nickname="Andrew"
+ subject="comment 1"
+ date="2013-01-11T00:01:08Z"
+ content="""
+Ok, I just reread [[design/encryption]] and perhaps this isn't a bug after all.
+Though, the annoyance I experience that made me dig into this a bit perhaps is a bug.
+
+In my example output above, if I 'git annex copy dir_full_of_files --to=glacier', I will get the GPG agent's passphrase prompt for each file, even if I have passphrase caching turned on and (on my mac) even if I have the passphrase saved in the keychain. Additionally, GPG will successfully encrypt the file if I enter anything at all into the passphrase prompt as long as I enter something. This leads me to believe that it either doesn't actually need to decrypt my GPG private key or it's using what I enter as the symmetric encryption key.
+
+Ideas?
+"""]]
diff --git a/doc/bugs/encryption_given_a_gpg_keyid_still_uses_symmetric_encryption/comment_2_7c0aeae6b1b2b0338735b0231c5db7d4._comment b/doc/bugs/encryption_given_a_gpg_keyid_still_uses_symmetric_encryption/comment_2_7c0aeae6b1b2b0338735b0231c5db7d4._comment
new file mode 100644
index 000000000..86dc2aa71
--- /dev/null
+++ b/doc/bugs/encryption_given_a_gpg_keyid_still_uses_symmetric_encryption/comment_2_7c0aeae6b1b2b0338735b0231c5db7d4._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.238"
+ subject="comment 2"
+ date="2013-01-16T02:17:44Z"
+ content="""
+What operating system is this?
+
+How did you install git-annex?
+
+Can you still reproduce the bug?
+
+What happens if you run this command; does it prompt for a passphrase?
+
+touch foo; echo foo| gpg --symmetric --passphrase-fd=0 foo
+"""]]
diff --git a/doc/bugs/encryption_key_is_surprising.mdwn b/doc/bugs/encryption_key_is_surprising.mdwn
new file mode 100644
index 000000000..5b18610b5
--- /dev/null
+++ b/doc/bugs/encryption_key_is_surprising.mdwn
@@ -0,0 +1,24 @@
+Crypto.hs seems to imply that the cipher key it's acting upon is 512 bytes long. Because of a probable programming mistake the key that's actually used is a bit surprising. The random key is generated by this snippet in Utility/Gpg.hs:
+
+ {- Creates a block of high-quality random data suitable to use as a cipher.
+ - It is armored, to avoid newlines, since gpg only reads ciphers up to the
+ - first newline. -}
+ genRandom :: Int -> IO String
+ genRandom size = readStrict
+ [ Params "--gen-random --armor"
+ , Param $ show randomquality
+ , Param $ show size
+ ]
+ where
+ -- 1 is /dev/urandom; 2 is /dev/random
+ randomquality = 1 :: Int
+
+This lets GPG generate the randomness and by passing armor, it avoids newlines. However, this base64 encoding is never undone on the way to Crypto.hs. Hence what cipherPassphrase and cipherHmac do is dropping or skipping the first 256 bytes of the base64 value. Base64, with its 6 bit per byte encoding, causes the Hmac function to operate on 192 bytes instead of 256 bytes. The key used by GPG will be larger. Some assertions that the resulting functions really operate on strings of the right length would've been helpful. Also GPG and HMAC get tested, the encryption/decryption part are not tested AFAICS.
+
+The encryption wiki page could have had more information. Enough code (sadly in Python, not reusing the Haskell code) to operate on the resulting files can be found in [this Gist](https://gist.github.com/pkern/5078559).
+
+-- Philipp Kern
+
+> In addition to the comment below, I have added a check that gpg outputs
+> the expected quantity of data, and the storage of the cipher is now
+> documented in [[internals]]. Think I can call this [[done]]. --[[Joey]]
diff --git a/doc/bugs/encryption_key_is_surprising/comment_1_5b172830ac31d51a1687bc8b1db489f9._comment b/doc/bugs/encryption_key_is_surprising/comment_1_5b172830ac31d51a1687bc8b1db489f9._comment
new file mode 100644
index 000000000..04854b3a4
--- /dev/null
+++ b/doc/bugs/encryption_key_is_surprising/comment_1_5b172830ac31d51a1687bc8b1db489f9._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-03-04T00:04:53Z"
+ content="""
+My first concern is if this means it's insecure. Luckily it seems not; HMAC SHA1 needs only 64 bytes of entropy, which are more than provided in the 256 bytes of base64 provided. As long as both gpg and the HMAC code use the full provided key (and not just the first 64 bytes of it, say), we're ok. And as far as I can tell, both do fully consume and use the key.
+
+So, I don't feel the need to change the code, aside from some minor improvements to variable names.
+"""]]
diff --git a/doc/bugs/encryption_key_is_surprising/comment_2_5b7e6bb36c3333dfd71808e8b4544746._comment b/doc/bugs/encryption_key_is_surprising/comment_2_5b7e6bb36c3333dfd71808e8b4544746._comment
new file mode 100644
index 000000000..24f8452c3
--- /dev/null
+++ b/doc/bugs/encryption_key_is_surprising/comment_2_5b7e6bb36c3333dfd71808e8b4544746._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://phil.0x539.de/"
+ nickname="Philipp Kern"
+ subject="comment 2"
+ date="2013-03-04T07:36:55Z"
+ content="""
+GPG also reduces the key material to the size of a SHA1 hash (because we're using the default option for s2k-digest-algo) to generate the symmetric key used with CAST5. So I wonder a bit why we bother with 512 bytes in the first place. Also they come from urandom (even on Linux), despite being generated once per remote. So maybe the strongness of the weakest link should be written down somewhere.
+"""]]
diff --git a/doc/bugs/encryption_key_is_surprising/comment_4_8ec86b8c35bce15337a143e275961cd5._comment b/doc/bugs/encryption_key_is_surprising/comment_4_8ec86b8c35bce15337a143e275961cd5._comment
new file mode 100644
index 000000000..ba5be68d4
--- /dev/null
+++ b/doc/bugs/encryption_key_is_surprising/comment_4_8ec86b8c35bce15337a143e275961cd5._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://phil.0x539.de/"
+ nickname="Philipp Kern"
+ subject="comment 4"
+ date="2013-03-05T07:17:08Z"
+ content="""
+You (presumably) hand over 320 bytes of entropy to GPG, but you don't control the encryption key directly. GPG assumes that what it's given as a symmetric key is not at all random. Hence, with the default options (for OpenPGP interop, apparently) it will derive a 128 bit from the given passphrase. For this it uses (again, by default) salted SHA1 on the whole passphrase. So the strength of the cipher is 128 bit CAST5 or an attack on salted SHA1 with a mostly known input length (but this does seem large).
+"""]]
diff --git a/doc/bugs/encryption_key_is_surprising/comment_4_c5e49b3a0eceabe6d14f5226d7ba4c7a._comment b/doc/bugs/encryption_key_is_surprising/comment_4_c5e49b3a0eceabe6d14f5226d7ba4c7a._comment
new file mode 100644
index 000000000..a685626e5
--- /dev/null
+++ b/doc/bugs/encryption_key_is_surprising/comment_4_c5e49b3a0eceabe6d14f5226d7ba4c7a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 4"
+ date="2013-03-04T17:29:28Z"
+ content="""
+What do you mean by \"reduces\"? I assume it doesn't just take the first N bytes?
+"""]]
diff --git a/doc/bugs/encryption_key_is_surprising/comment_5_cd7cbf0c0ee9cafec344dfbf1acd9590._comment b/doc/bugs/encryption_key_is_surprising/comment_5_cd7cbf0c0ee9cafec344dfbf1acd9590._comment
new file mode 100644
index 000000000..4e7635402
--- /dev/null
+++ b/doc/bugs/encryption_key_is_surprising/comment_5_cd7cbf0c0ee9cafec344dfbf1acd9590._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://kaizer.se/"
+ nickname="ulrik.sverdrup"
+ subject="GPG Cipher Algo"
+ date="2013-03-06T04:53:06Z"
+ content="""
+The GPG cipher algorithm is user configurable (unless annex overrides it) the best way to set it is personal-cipher-preferences. Annex' job is simply to provide enough key material for any viable GPG option (so 256 bits of random data). Also note that GPG's string-to-key \"s2k\" algorithm is an iterated application SHA-1 (also this can be configured). For a quick context, it will use a strength number (for example count=128*1024) and it will hash as many iterations as [count]/[key byte length].
+"""]]
diff --git a/doc/bugs/encryption_key_is_surprising/comment_6_01381524114d885961704acc3f172536._comment b/doc/bugs/encryption_key_is_surprising/comment_6_01381524114d885961704acc3f172536._comment
new file mode 100644
index 000000000..21898b522
--- /dev/null
+++ b/doc/bugs/encryption_key_is_surprising/comment_6_01381524114d885961704acc3f172536._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://kaizer.se/"
+ nickname="ulrik.sverdrup"
+ subject="comment 6"
+ date="2013-03-06T05:30:16Z"
+ content="""
+I'm not very clear, sorry. S2K is not iterative in the way for example PBKDF2 is. It will hash a very long repetition of salt + passphrase + salt + passphrase etc in one go. The repetition of this happens if more key bits than the hash digest size are needed.
+"""]]
diff --git a/doc/bugs/encryption_key_is_surprising/comment_7_c1eb59e1c5f583dcef7cea17623a2435._comment b/doc/bugs/encryption_key_is_surprising/comment_7_c1eb59e1c5f583dcef7cea17623a2435._comment
new file mode 100644
index 000000000..19863e8f8
--- /dev/null
+++ b/doc/bugs/encryption_key_is_surprising/comment_7_c1eb59e1c5f583dcef7cea17623a2435._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://phil.0x539.de/"
+ nickname="Philipp Kern"
+ subject="comment 7"
+ date="2013-03-07T15:21:55Z"
+ content="""
+For the default git-annex will pass plenty of key bytes to make this unnecessary. True, one could adjust <code>$HOME/.gnupg/gpg.conf</code> to select another s2k algorithm and another cipher for the data (the two relevant options being <code>s2k-digest-algo</code> and <code>cipher-algo</code>). To be honest, I'd also like a per-repository gpg options setting for the symmetric cipher. For instance I know that I always want compression with gpg unless I use it with annexed data (at least in certain repositories).
+"""]]
diff --git a/doc/bugs/error_building_git-annex_3.20120624_using_cabal.mdwn b/doc/bugs/error_building_git-annex_3.20120624_using_cabal.mdwn
new file mode 100644
index 000000000..df83f4e4e
--- /dev/null
+++ b/doc/bugs/error_building_git-annex_3.20120624_using_cabal.mdwn
@@ -0,0 +1,159 @@
+I am trying to install git-annex 3.20120624 using cabal. My currently installed version of git-annex is 3.20120615. After a "cabal update", the build of git-annex fails:
+
+ bram@falafel% cabal install git-annex
+ Resolving dependencies...
+ [1 of 4] Compiling Utility.SafeCommand ( /tmp/git-annex-3.20120624-4173/git-annex-3.20120624/Utility/SafeCommand.hs, /tmp/git-annex-3.20120624-4173/git-annex-3.20120624/dist/setup/Utility/SafeCommand.o )
+ [2 of 4] Compiling Build.TestConfig ( /tmp/git-annex-3.20120624-4173/git-annex-3.20120624/Build/TestConfig.hs, /tmp/git-annex-3.20120624-4173/git-annex-3.20120624/dist/setup/Build/TestConfig.o )
+ [3 of 4] Compiling Build.Configure ( /tmp/git-annex-3.20120624-4173/git-annex-3.20120624/Build/Configure.hs, /tmp/git-annex-3.20120624-4173/git-annex-3.20120624/dist/setup/Build/Configure.o )
+ [4 of 4] Compiling Main ( /tmp/git-annex-3.20120624-4173/git-annex-3.20120624/Setup.hs, /tmp/git-annex-3.20120624-4173/git-annex-3.20120624/dist/setup/Main.o )
+ Linking /tmp/git-annex-3.20120624-4173/git-annex-3.20120624/dist/setup/setup ...
+ checking version... 3.20120624
+ checking git... yes
+ checking git version... 1.7.9.5
+ checking cp -a... yes
+ checking cp -p... yes
+ checking cp --reflink=auto... yes
+ checking uuid generator... uuid
+ checking xargs -0... yes
+ checking rsync... yes
+ checking curl... no
+ checking wget... yes
+ checking bup... no
+ checking gpg... yes
+ checking lsof... yes
+ checking ssh connection caching... yes
+ checking sha1... sha1sum
+ checking sha512... sha512sum
+ checking sha224... sha224sum
+ checking sha384... sha384sum
+ checking sha256... sha256sum
+ Configuring git-annex-3.20120624...
+ Building git-annex-3.20120624...
+ Preprocessing executable 'git-annex' for git-annex-3.20120624...
+ [ 1 of 183] Compiling Utility.Percentage ( Utility/Percentage.hs, dist/build/git-annex/git-annex-tmp/Utility/Percentage.o )
+ [ 2 of 183] Compiling Utility.Dot ( Utility/Dot.hs, dist/build/git-annex/git-annex-tmp/Utility/Dot.o )
+ [ 3 of 183] Compiling Utility.ThreadLock ( Utility/ThreadLock.hs, dist/build/git-annex/git-annex-tmp/Utility/ThreadLock.o )
+ [ 4 of 183] Compiling Utility.Base64 ( Utility/Base64.hs, dist/build/git-annex/git-annex-tmp/Utility/Base64.o )
+ [ 5 of 183] Compiling Utility.DataUnits ( Utility/DataUnits.hs, dist/build/git-annex/git-annex-tmp/Utility/DataUnits.o )
+ [ 6 of 183] Compiling Utility.JSONStream ( Utility/JSONStream.hs, dist/build/git-annex/git-annex-tmp/Utility/JSONStream.o )
+ [ 7 of 183] Compiling Messages.JSON ( Messages/JSON.hs, dist/build/git-annex/git-annex-tmp/Messages/JSON.o )
+ [ 8 of 183] Compiling Build.SysConfig ( Build/SysConfig.hs, dist/build/git-annex/git-annex-tmp/Build/SysConfig.o )
+ [ 9 of 183] Compiling Types.KeySource ( Types/KeySource.hs, dist/build/git-annex/git-annex-tmp/Types/KeySource.o )
+ [ 10 of 183] Compiling Types.UUID ( Types/UUID.hs, dist/build/git-annex/git-annex-tmp/Types/UUID.o )
+ [ 11 of 183] Compiling Utility.State ( Utility/State.hs, dist/build/git-annex/git-annex-tmp/Utility/State.o )
+ [ 12 of 183] Compiling Types.Messages ( Types/Messages.hs, dist/build/git-annex/git-annex-tmp/Types/Messages.o )
+ [ 13 of 183] Compiling Types.TrustLevel ( Types/TrustLevel.hs, dist/build/git-annex/git-annex-tmp/Types/TrustLevel.o )
+ [ 14 of 183] Compiling Types.BranchState ( Types/BranchState.hs, dist/build/git-annex/git-annex-tmp/Types/BranchState.o )
+ [ 15 of 183] Compiling Git.Index ( Git/Index.hs, dist/build/git-annex/git-annex-tmp/Git/Index.o )
+ [ 16 of 183] Compiling Utility.PartialPrelude ( Utility/PartialPrelude.hs, dist/build/git-annex/git-annex-tmp/Utility/PartialPrelude.o )
+ [ 17 of 183] Compiling Utility.Format ( Utility/Format.hs, dist/build/git-annex/git-annex-tmp/Utility/Format.o )
+ [ 18 of 183] Compiling Utility.FileSystemEncoding ( Utility/FileSystemEncoding.hs, dist/build/git-annex/git-annex-tmp/Utility/FileSystemEncoding.o )
+ [ 19 of 183] Compiling Utility.Touch ( dist/build/git-annex/git-annex-tmp/Utility/Touch.hs, dist/build/git-annex/git-annex-tmp/Utility/Touch.o )
+ [ 20 of 183] Compiling Utility.Monad ( Utility/Monad.hs, dist/build/git-annex/git-annex-tmp/Utility/Monad.o )
+ [ 21 of 183] Compiling Utility.Path ( Utility/Path.hs, dist/build/git-annex/git-annex-tmp/Utility/Path.o )
+ [ 22 of 183] Compiling Utility.SafeCommand ( Utility/SafeCommand.hs, dist/build/git-annex/git-annex-tmp/Utility/SafeCommand.o )
+ [ 23 of 183] Compiling Utility.RsyncFile ( Utility/RsyncFile.hs, dist/build/git-annex/git-annex-tmp/Utility/RsyncFile.o )
+ [ 24 of 183] Compiling Utility.Exception ( Utility/Exception.hs, dist/build/git-annex/git-annex-tmp/Utility/Exception.o )
+ [ 25 of 183] Compiling Utility.TempFile ( Utility/TempFile.hs, dist/build/git-annex/git-annex-tmp/Utility/TempFile.o )
+ [ 26 of 183] Compiling Utility.Directory ( Utility/Directory.hs, dist/build/git-annex/git-annex-tmp/Utility/Directory.o )
+ [ 27 of 183] Compiling Utility.Misc ( Utility/Misc.hs, dist/build/git-annex/git-annex-tmp/Utility/Misc.o )
+ [ 28 of 183] Compiling Git.Types ( Git/Types.hs, dist/build/git-annex/git-annex-tmp/Git/Types.o )
+ [ 29 of 183] Compiling Common ( Common.hs, dist/build/git-annex/git-annex-tmp/Common.o )
+ [ 30 of 183] Compiling Utility.FileMode ( Utility/FileMode.hs, dist/build/git-annex/git-annex-tmp/Utility/FileMode.o )
+ [ 31 of 183] Compiling Git ( Git.hs, dist/build/git-annex/git-annex-tmp/Git.o )
+ [ 32 of 183] Compiling Git.Command ( Git/Command.hs, dist/build/git-annex/git-annex-tmp/Git/Command.o )
+ [ 33 of 183] Compiling Git.Ref ( Git/Ref.hs, dist/build/git-annex/git-annex-tmp/Git/Ref.o )
+ [ 34 of 183] Compiling Git.FilePath ( Git/FilePath.hs, dist/build/git-annex/git-annex-tmp/Git/FilePath.o )
+ [ 35 of 183] Compiling Utility.Matcher ( Utility/Matcher.hs, dist/build/git-annex/git-annex-tmp/Utility/Matcher.o )
+ [ 36 of 183] Compiling Utility.Gpg ( Utility/Gpg.hs, dist/build/git-annex/git-annex-tmp/Utility/Gpg.o )
+ [ 37 of 183] Compiling Types.Crypto ( Types/Crypto.hs, dist/build/git-annex/git-annex-tmp/Types/Crypto.o )
+ [ 38 of 183] Compiling Types.Key ( Types/Key.hs, dist/build/git-annex/git-annex-tmp/Types/Key.o )
+ [ 39 of 183] Compiling Types.Backend ( Types/Backend.hs, dist/build/git-annex/git-annex-tmp/Types/Backend.o )
+ [ 40 of 183] Compiling Types.Remote ( Types/Remote.hs, dist/build/git-annex/git-annex-tmp/Types/Remote.o )
+ [ 41 of 183] Compiling Git.Sha ( Git/Sha.hs, dist/build/git-annex/git-annex-tmp/Git/Sha.o )
+ [ 42 of 183] Compiling Git.Branch ( Git/Branch.hs, dist/build/git-annex/git-annex-tmp/Git/Branch.o )
+ [ 43 of 183] Compiling Git.UpdateIndex ( Git/UpdateIndex.hs, dist/build/git-annex/git-annex-tmp/Git/UpdateIndex.o )
+ [ 44 of 183] Compiling Git.Queue ( Git/Queue.hs, dist/build/git-annex/git-annex-tmp/Git/Queue.o )
+ [ 45 of 183] Compiling Git.Url ( Git/Url.hs, dist/build/git-annex/git-annex-tmp/Git/Url.o )
+ [ 46 of 183] Compiling Git.Construct ( Git/Construct.hs, dist/build/git-annex/git-annex-tmp/Git/Construct.o )
+ [ 47 of 183] Compiling Git.Config ( Git/Config.hs, dist/build/git-annex/git-annex-tmp/Git/Config.o )
+ [ 48 of 183] Compiling Git.SharedRepository ( Git/SharedRepository.hs, dist/build/git-annex/git-annex-tmp/Git/SharedRepository.o )
+ [ 49 of 183] Compiling Git.Version ( Git/Version.hs, dist/build/git-annex/git-annex-tmp/Git/Version.o )
+ [ 50 of 183] Compiling Utility.CoProcess ( Utility/CoProcess.hs, dist/build/git-annex/git-annex-tmp/Utility/CoProcess.o )
+ [ 51 of 183] Compiling Git.HashObject ( Git/HashObject.hs, dist/build/git-annex/git-annex-tmp/Git/HashObject.o )
+ [ 52 of 183] Compiling Git.CatFile ( Git/CatFile.hs, dist/build/git-annex/git-annex-tmp/Git/CatFile.o )
+ [ 53 of 183] Compiling Git.UnionMerge ( Git/UnionMerge.hs, dist/build/git-annex/git-annex-tmp/Git/UnionMerge.o )
+ [ 54 of 183] Compiling Git.CheckAttr ( Git/CheckAttr.hs, dist/build/git-annex/git-annex-tmp/Git/CheckAttr.o )
+ [ 55 of 183] Compiling Annex ( Annex.hs, dist/build/git-annex/git-annex-tmp/Annex.o )
+ [ 56 of 183] Compiling Types.Option ( Types/Option.hs, dist/build/git-annex/git-annex-tmp/Types/Option.o )
+ [ 57 of 183] Compiling Types ( Types.hs, dist/build/git-annex/git-annex-tmp/Types.o )
+ [ 58 of 183] Compiling Messages ( Messages.hs, dist/build/git-annex/git-annex-tmp/Messages.o )
+ [ 59 of 183] Compiling Types.Command ( Types/Command.hs, dist/build/git-annex/git-annex-tmp/Types/Command.o )
+ [ 60 of 183] Compiling Locations ( Locations.hs, dist/build/git-annex/git-annex-tmp/Locations.o )
+ [ 61 of 183] Compiling Common.Annex ( Common/Annex.hs, dist/build/git-annex/git-annex-tmp/Common/Annex.o )
+ [ 62 of 183] Compiling Annex.Exception ( Annex/Exception.hs, dist/build/git-annex/git-annex-tmp/Annex/Exception.o )
+ [ 63 of 183] Compiling Annex.BranchState ( Annex/BranchState.hs, dist/build/git-annex/git-annex-tmp/Annex/BranchState.o )
+ [ 64 of 183] Compiling Annex.CatFile ( Annex/CatFile.hs, dist/build/git-annex/git-annex-tmp/Annex/CatFile.o )
+ [ 65 of 183] Compiling Annex.Perms ( Annex/Perms.hs, dist/build/git-annex/git-annex-tmp/Annex/Perms.o )
+ [ 66 of 183] Compiling Annex.Journal ( Annex/Journal.hs, dist/build/git-annex/git-annex-tmp/Annex/Journal.o )
+ [ 67 of 183] Compiling Annex.Branch ( Annex/Branch.hs, dist/build/git-annex/git-annex-tmp/Annex/Branch.o )
+ [ 68 of 183] Compiling Crypto ( Crypto.hs, dist/build/git-annex/git-annex-tmp/Crypto.o )
+ [ 69 of 183] Compiling Usage ( Usage.hs, dist/build/git-annex/git-annex-tmp/Usage.o )
+ [ 70 of 183] Compiling Annex.CheckAttr ( Annex/CheckAttr.hs, dist/build/git-annex/git-annex-tmp/Annex/CheckAttr.o )
+ [ 71 of 183] Compiling Remote.Helper.Special ( Remote/Helper/Special.hs, dist/build/git-annex/git-annex-tmp/Remote/Helper/Special.o )
+ [ 72 of 183] Compiling Logs.Presence ( Logs/Presence.hs, dist/build/git-annex/git-annex-tmp/Logs/Presence.o )
+ [ 73 of 183] Compiling Logs.Location ( Logs/Location.hs, dist/build/git-annex/git-annex-tmp/Logs/Location.o )
+ [ 74 of 183] Compiling Logs.Web ( Logs/Web.hs, dist/build/git-annex/git-annex-tmp/Logs/Web.o )
+ [ 75 of 183] Compiling Annex.LockPool ( Annex/LockPool.hs, dist/build/git-annex/git-annex-tmp/Annex/LockPool.o )
+ [ 76 of 183] Compiling Backend.SHA ( Backend/SHA.hs, dist/build/git-annex/git-annex-tmp/Backend/SHA.o )
+ [ 77 of 183] Compiling Backend.WORM ( Backend/WORM.hs, dist/build/git-annex/git-annex-tmp/Backend/WORM.o )
+ [ 78 of 183] Compiling Backend.URL ( Backend/URL.hs, dist/build/git-annex/git-annex-tmp/Backend/URL.o )
+ [ 79 of 183] Compiling Assistant.ThreadedMonad ( Assistant/ThreadedMonad.hs, dist/build/git-annex/git-annex-tmp/Assistant/ThreadedMonad.o )
+ [ 80 of 183] Compiling Logs.UUIDBased ( Logs/UUIDBased.hs, dist/build/git-annex/git-annex-tmp/Logs/UUIDBased.o )
+ [ 81 of 183] Compiling Logs.Remote ( Logs/Remote.hs, dist/build/git-annex/git-annex-tmp/Logs/Remote.o )
+ [ 82 of 183] Compiling Utility.DiskFree ( Utility/DiskFree.hs, dist/build/git-annex/git-annex-tmp/Utility/DiskFree.o )
+ [ 83 of 183] Compiling Utility.Url ( Utility/Url.hs, dist/build/git-annex/git-annex-tmp/Utility/Url.o )
+ [ 84 of 183] Compiling Utility.CopyFile ( Utility/CopyFile.hs, dist/build/git-annex/git-annex-tmp/Utility/CopyFile.o )
+ [ 85 of 183] Compiling Git.LsFiles ( Git/LsFiles.hs, dist/build/git-annex/git-annex-tmp/Git/LsFiles.o )
+ [ 86 of 183] Compiling Git.AutoCorrect ( Git/AutoCorrect.hs, dist/build/git-annex/git-annex-tmp/Git/AutoCorrect.o )
+ [ 87 of 183] Compiling Git.CurrentRepo ( Git/CurrentRepo.hs, dist/build/git-annex/git-annex-tmp/Git/CurrentRepo.o )
+ [ 88 of 183] Compiling Utility.Daemon ( Utility/Daemon.hs, dist/build/git-annex/git-annex-tmp/Utility/Daemon.o )
+ [ 89 of 183] Compiling Utility.LogFile ( Utility/LogFile.hs, dist/build/git-annex/git-annex-tmp/Utility/LogFile.o )
+ [ 90 of 183] Compiling Utility.ThreadScheduler ( Utility/ThreadScheduler.hs, dist/build/git-annex/git-annex-tmp/Utility/ThreadScheduler.o )
+ [ 91 of 183] Compiling Assistant.DaemonStatus ( Assistant/DaemonStatus.hs, dist/build/git-annex/git-annex-tmp/Assistant/DaemonStatus.o )
+ [ 92 of 183] Compiling Utility.Types.DirWatcher ( Utility/Types/DirWatcher.hs, dist/build/git-annex/git-annex-tmp/Utility/Types/DirWatcher.o )
+ [ 93 of 183] Compiling Utility.INotify ( Utility/INotify.hs, dist/build/git-annex/git-annex-tmp/Utility/INotify.o )
+ [ 94 of 183] Compiling Utility.DirWatcher ( Utility/DirWatcher.hs, dist/build/git-annex/git-annex-tmp/Utility/DirWatcher.o )
+ [ 95 of 183] Compiling Utility.Lsof ( Utility/Lsof.hs, dist/build/git-annex/git-annex-tmp/Utility/Lsof.o )
+ [ 96 of 183] Compiling Git.Merge ( Git/Merge.hs, dist/build/git-annex/git-annex-tmp/Git/Merge.o )
+ [ 97 of 183] Compiling Git.Filename ( Git/Filename.hs, dist/build/git-annex/git-annex-tmp/Git/Filename.o )
+ [ 98 of 183] Compiling Git.LsTree ( Git/LsTree.hs, dist/build/git-annex/git-annex-tmp/Git/LsTree.o )
+ [ 99 of 183] Compiling Config ( Config.hs, dist/build/git-annex/git-annex-tmp/Config.o )
+ [100 of 183] Compiling Annex.UUID ( Annex/UUID.hs, dist/build/git-annex/git-annex-tmp/Annex/UUID.o )
+ [101 of 183] Compiling Logs.UUID ( Logs/UUID.hs, dist/build/git-annex/git-annex-tmp/Logs/UUID.o )
+ [102 of 183] Compiling Backend ( Backend.hs, dist/build/git-annex/git-annex-tmp/Backend.o )
+ [103 of 183] Compiling Remote.Helper.Hooks ( Remote/Helper/Hooks.hs, dist/build/git-annex/git-annex-tmp/Remote/Helper/Hooks.o )
+ [104 of 183] Compiling Remote.Helper.Encryptable ( Remote/Helper/Encryptable.hs, dist/build/git-annex/git-annex-tmp/Remote/Helper/Encryptable.o )
+ [105 of 183] Compiling Annex.Queue ( Annex/Queue.hs, dist/build/git-annex/git-annex-tmp/Annex/Queue.o )
+ [106 of 183] Compiling Annex.Content ( Annex/Content.hs, dist/build/git-annex/git-annex-tmp/Annex/Content.o )
+ [107 of 183] Compiling Remote.S3 ( Remote/S3.hs, dist/build/git-annex/git-annex-tmp/Remote/S3.o )
+ [108 of 183] Compiling Remote.Directory ( Remote/Directory.hs, dist/build/git-annex/git-annex-tmp/Remote/Directory.o )
+ [109 of 183] Compiling Remote.Rsync ( Remote/Rsync.hs, dist/build/git-annex/git-annex-tmp/Remote/Rsync.o )
+ [110 of 183] Compiling Remote.Web ( Remote/Web.hs, dist/build/git-annex/git-annex-tmp/Remote/Web.o )
+ [111 of 183] Compiling Remote.Hook ( Remote/Hook.hs, dist/build/git-annex/git-annex-tmp/Remote/Hook.o )
+ [112 of 183] Compiling Upgrade.V2 ( Upgrade/V2.hs, dist/build/git-annex/git-annex-tmp/Upgrade/V2.o )
+ [113 of 183] Compiling Assistant.Changes ( Assistant/Changes.hs, dist/build/git-annex/git-annex-tmp/Assistant/Changes.o )
+
+ Assistant/Changes.hs:73:30:
+ Not in scope: `tryReadTChan'
+ Perhaps you meant `readTChan' (imported from Control.Concurrent.STM)
+ cabal: Error: some packages failed to install:
+ git-annex-3.20120624 failed during the building phase. The exception was:
+ ExitFailure 1
+
+This is using haskell-platform 2012.1.0.0~debian1 on Ubuntu 12.04.
+
+> Turns out it needs version 2.3 of the STM library. (libghc-stm-dev
+> package). I've made cabal detect an older version and skip building
+> the new `git annex watch` command, so you'll be able to build the next
+> release. [[done]] --[[Joey]]
diff --git a/doc/bugs/error_on_only_repository_copy_deletion.mdwn b/doc/bugs/error_on_only_repository_copy_deletion.mdwn
new file mode 100644
index 000000000..7c7be888e
--- /dev/null
+++ b/doc/bugs/error_on_only_repository_copy_deletion.mdwn
@@ -0,0 +1,16 @@
+**What steps will reproduce the problem?**<br>
+Delete the last repository in the current repository (where it says: warning type in "yes please do as i say").
+Then try running git annex webapp
+<br><br>
+**What is the expected output? What do you see instead?**<br>
+Webapp starts. git-annex: Not in a git repository.
+<br><br>
+**What version of git-annex are you using? On what operating system?**<br>
+4.20130417. Debian wheezy/testing
+<br><br>
+**Please provide any additional information below.**<br>
+See also
+[[bugs/git-annex:_Not_in_a_git_repository._/]]
+where the same error message occurs
+
+[[!tag /design/assistant moreinfo]]
diff --git a/doc/bugs/error_on_only_repository_copy_deletion/comment_1_af394ac0956ab33a77256bcb02ef2a0f._comment b/doc/bugs/error_on_only_repository_copy_deletion/comment_1_af394ac0956ab33a77256bcb02ef2a0f._comment
new file mode 100644
index 000000000..a60eee137
--- /dev/null
+++ b/doc/bugs/error_on_only_repository_copy_deletion/comment_1_af394ac0956ab33a77256bcb02ef2a0f._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-04-23T16:39:08Z"
+ content="""
+Do you still have a `~/annex` or `~/Desktop/annex`? What's in there?
+
+Also, please show me the content of your `~/.config/git-annex/autostart` file.
+
+The only bug I have been able to track down is that it fails to remove the repository from the autostart file, and so if the repository directory still exists, this will happen. I've fixed it to properly remove the repository from the file, but hesitate to close this bug as I don't understand how the repository directory could still exist after it's supposed to be deleted.
+
+(When I try, it does get deleted, and starting the webapp again allows starting over with a new repository.)
+"""]]
diff --git a/doc/bugs/error_propigation.mdwn b/doc/bugs/error_propigation.mdwn
new file mode 100644
index 000000000..25998907e
--- /dev/null
+++ b/doc/bugs/error_propigation.mdwn
@@ -0,0 +1,3 @@
+If a subcommand fails w/o throwing an error, no error is propigated to the
+git-annex exit code. With --quiet, this makes it look like the command
+succeeded. [[done]]
diff --git a/doc/bugs/error_when_using_repositories_with_non-ASCII_characters.mdwn b/doc/bugs/error_when_using_repositories_with_non-ASCII_characters.mdwn
new file mode 100644
index 000000000..d88b86b44
--- /dev/null
+++ b/doc/bugs/error_when_using_repositories_with_non-ASCII_characters.mdwn
@@ -0,0 +1,62 @@
+*What steps will reproduce the problem?*
+
+ hactar% mkdir demonstração
+ hactar% cd demonstração
+ hactar% cp ~/tmp/*(.) .
+ hactar% git init
+ Initialized empty Git repository in /tmp/demonstração/.git/
+ hactar% git annex init
+ init ok
+ (Recording state in git...)
+ hactar% git annex add .
+ add Equipment Consumption.ods (checksum...) ok
+ add Personal.vcard (checksum...) ok
+ add Trampo.vcard (checksum...) ok
+ add blah.txt (checksum...) ok
+ [ more git output ]
+ hactar% git commit -m initial
+ [master (root-commit) d16bafb] initial
+ 42 files changed, 42 insertions(+)
+ [ more git output ]
+ hactar% cd /var/tmp
+ hactar% git clone ssh://localhost//tmp/demonstração demonstração
+ Cloning into 'demonstração'...
+ remote: Counting objects: 176, done.
+ remote: Compressing objects: 100% (134/134), done.
+ remote: Total 176 (delta 1), reused 0 (delta 0)
+ Receiving objects: 100% (176/176), 17.23 KiB, done.
+ Resolving deltas: 100% (1/1), done.
+ hactar% cd demonstração
+ hactar% git annex init
+ init ok
+ (Recording state in git...)
+ hactar% git annex status
+ supported backends: SHA256E SHA1E SHA512E SHA224E SHA384E SHA256 SHA1 SHA512 SHA224 SHA384 WORM URL
+ supported remote types: git S3 bup directory rsync web hook
+ trusted repositories: (merging origin/git-annex into git-annex...)
+
+ git-annex: fd:14: commitBuffer: invalid argument (invalid character)
+ failed
+ git-annex: status: 1 failed
+
+*What is the expected output? What do you see instead?*
+
+I expect that "git annex status" will complete successfuly and show information about all repositories.
+Instead of that I get the "git-annex: fd:14: commitBuffer: invalid argument (invalid character)" error above.
+
+*What version of git-annex are you using? On what operating system?*
+
+This is with Debian's git-annex_3.20121001_i386.deb installed on an Ubuntu 12.04 system.
+Using Ubuntu's original version (3.20120406) the error message is a bit different (here I used the name acentuação instead of demonstração):
+
+ trusted repositories: git-annex-shell: //tmp/acentuação: changeWorkingDirectory: does not exist (No such file or directory)
+ Command ssh ["-S","/var/tmp/acentua\231\227o/.git/annex/ssh/localhost","-o","ControlMaster=auto","-o","ControlPersist=yes","localhost","git-annex-shell 'configlist' '//tmp/acentua\195\167\195\163o'"] failed; exit code 1
+
+> I think this is the last unvalid utf-8 bug in git-annex. At least,
+> the last one I hypothesized exists. It's in the union merge code. I will
+> try to look at it again soon; the last 2 times I looked at that code
+> I could not see an easy way to make it allow invalid utf-8 encoded data.
+> --[[Joey]]
+
+>> [[done]], although I am no longer so sure this was the last utf-8
+>> encoding bug.. --[[Joey]]
diff --git a/doc/bugs/error_when_using_repositories_with_non-ASCII_characters/comment_1_38cc2d2ed907649df085de8ad83cb9dd._comment b/doc/bugs/error_when_using_repositories_with_non-ASCII_characters/comment_1_38cc2d2ed907649df085de8ad83cb9dd._comment
new file mode 100644
index 000000000..69d7f1da1
--- /dev/null
+++ b/doc/bugs/error_when_using_repositories_with_non-ASCII_characters/comment_1_38cc2d2ed907649df085de8ad83cb9dd._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmcYryijvlF8bJvM_eZNSrUPEkMlxMDGTQ"
+ nickname="Thiago"
+ subject="The bug is actually something completely different!"
+ date="2012-10-04T03:53:57Z"
+ content="""
+Ok, this is a mix of luser error and a bug.
+
+I noticed that I wasn't providing a description in git annex init. So if I do \"git annex init foo\" in the first repository and \"git annex init bar\" in the clone, then git annex status works!
+
+So the bug is actually that you need to provide a description in git annex init, even though the man page says a description will be generated otherwise.
+
+(In my defense I hit the non-ACII characters bug with the git annex version in Ubuntu, and that one still has the same error even if a description is provided so this was fixed later).
+"""]]
diff --git a/doc/bugs/error_with_file_names_starting_with_dash.mdwn b/doc/bugs/error_with_file_names_starting_with_dash.mdwn
new file mode 100644
index 000000000..84bf1cfa0
--- /dev/null
+++ b/doc/bugs/error_with_file_names_starting_with_dash.mdwn
@@ -0,0 +1,15 @@
+git annex add has problems if items start with dashes, example:
+
+-wut-a-directory-name-/file1
+
+leads to
+
+[[!format bash """
+add -wut-a-directory-name-/file1 (checksum...) sha1sum: invalid option -- 'u'
+„sha1sum --help“ gibt weitere Informationen.
+
+ git-annex: <file descriptor: 15>: hGetLine: end of file
+"""]]
+
+> This is fixed in git, at least I think I've found all cases where
+> filenames are passed to programs and escaped them. --[[Joey]] [[done]]
diff --git a/doc/bugs/extraneous_shell_escaping_for_rsync_remotes.mdwn b/doc/bugs/extraneous_shell_escaping_for_rsync_remotes.mdwn
new file mode 100644
index 000000000..c4ee8d5bd
--- /dev/null
+++ b/doc/bugs/extraneous_shell_escaping_for_rsync_remotes.mdwn
@@ -0,0 +1,15 @@
+When using `git annex get foo` where foo is available in a rsync remote with encryption I got an error saying that rsync cannot
+find the required file but extra ' are here.
+
+I attached a patch for this.
+
+> But you didn't, sadly. :(
+>
+> I don't seem to see the problem, set up a rsync over ssh with encryption
+> and sent over a file "foo", and then got it back from rsync, without
+> trouble.
+>
+> Ah, you're not using rsync over ssh, but just to a local directory,
+> right? --[[Joey]]
+
+>> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/fails_to_handle_lot_of_files.mdwn b/doc/bugs/fails_to_handle_lot_of_files.mdwn
new file mode 100644
index 000000000..470a5180f
--- /dev/null
+++ b/doc/bugs/fails_to_handle_lot_of_files.mdwn
@@ -0,0 +1,445 @@
+ git-annex version: 3.20111011
+ local repository version: 3
+ default repository version: 3
+ supported repository versions: 3
+ upgrade supported from repository versions: 0 1 2
+
+I just created a new remote on a USB drive and wanted to copy my files over. git-annex wasn't too happy about that ;)
+I included a few OK transfers as there was an error before git-annex ran into a wall. As I could easily access that temp file after it aborted, I suspect something went wrong internally before git-annex started to throw those errors.
+
+Please note the "_n TIMES_" comments. It's how often I got the same error message...
+
+
+
+ git annex copy . --to USB --fast
+
+ copy redacted.JPG (to USB...)
+ redacted
+ 4035668 100% 77.91MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 4036374 bytes received 31 bytes 8072810.00 bytes/sec
+ total size is 4035668 speedup is 1.00
+ ok
+ copy redacted.NEF (to USB...)
+ redacted
+ 18002094 100% 74.19MB/s 0:00:00 (xfer#1, to-check=0/1)
+ WARNING: redacted failed verification -- update retained (will try again).
+ redacted
+ 18002094 100% 19.60MB/s 0:00:00 (xfer#2, to-check=0/1)
+ rsync: open "copy_target/.git/annex/tmp/redacted_E13" failed: Permission denied (13)
+
+ sent 36008841 bytes received 52 bytes 24005928.67 bytes/sec
+ total size is 18002094 speedup is 0.50
+ rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1070) [sender=3.0.8]
+
+ rsync failed -- run git annex again to resume file transfer
+ failed
+ copy redacted.JPG (to USB...)
+ redacted
+ 3687111 100% 39.16MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 3687773 bytes received 31 bytes 2458536.00 bytes/sec
+ total size is 3687111 speedup is 1.00
+ ok
+ copy redacted.NEF (to USB...)
+ redacted
+ 17877177 100% 79.15MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 17879573 bytes received 31 bytes 11919736.00 bytes/sec
+ total size is 17877177 speedup is 1.00
+ ok
+ copy redacted.JPG (to USB...)
+ redacted
+ 3694921 100% 40.14MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 3695583 bytes received 31 bytes 2463742.67 bytes/sec
+ total size is 3694921 speedup is 1.00
+ ok
+ copy redacted.NEF (to USB...)
+ redacted
+ 17875448 100% 71.20MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 17877844 bytes received 31 bytes 11918583.33 bytes/sec
+ total size is 17875448 speedup is 1.00
+ ok
+ copy redacted.JPG (to USB...)
+ redacted
+ 3833377 100% 62.49MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 3834055 bytes received 31 bytes 2556057.33 bytes/sec
+ total size is 3833377 speedup is 1.00
+ ok
+ copy redacted.NEF (to USB...)
+ redacted
+ 17938200 100% 65.43MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 17940604 bytes received 31 bytes 11960423.33 bytes/sec
+ total size is 17938200 speedup is 1.00
+ ok
+ copy redacted.JPG (to USB...)
+ redacted
+ 4512557 100% 83.77MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 4513319 bytes received 31 bytes 3008900.00 bytes/sec
+ total size is 4512557 speedup is 1.00
+ ok
+ copy redacted.NEF (to USB...)
+ redacted
+ 18001641 100% 76.16MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 18004053 bytes received 31 bytes 12002722.67 bytes/sec
+ total size is 18001641 speedup is 1.00
+ ok
+ copy redacted.JPG (to USB...)
+ redacted
+ 4394272 100% 50.11MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 4395022 bytes received 31 bytes 8790106.00 bytes/sec
+ total size is 4394272 speedup is 1.00
+ ok
+ copy redacted.NEF (to USB...)
+ redacted
+ 18095781 100% 73.30MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 18098205 bytes received 31 bytes 12065490.67 bytes/sec
+ total size is 18095781 speedup is 1.00
+ ok
+ copy redacted.JPG (to USB...)
+ redacted
+ 4683795 100% 65.23MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 4684577 bytes received 31 bytes 9369216.00 bytes/sec
+ total size is 4683795 speedup is 1.00
+ ok
+ copy redacted.NEF (to USB...)
+ redacted
+ 18172801 100% 74.25MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 18175233 bytes received 31 bytes 36350528.00 bytes/sec
+ total size is 18172801 speedup is 1.00
+ ok
+ copy redacted.JPG (to USB...)
+ redacted
+ 4486231 100% 77.22MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 4486989 bytes received 31 bytes 8974040.00 bytes/sec
+ total size is 4486231 speedup is 1.00
+ ok
+ copy redacted.NEF (to USB...)
+ redacted
+ 17860427 100% 68.56MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 17862823 bytes received 31 bytes 35725708.00 bytes/sec
+ total size is 17860427 speedup is 1.00
+ ok
+ copy redacted.JPG (to USB...)
+ redacted
+ 4499768 100% 36.41MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 4500530 bytes received 31 bytes 9001122.00 bytes/sec
+ total size is 4499768 speedup is 1.00
+ ok
+ copy redacted.NEF (to USB...)
+ redacted
+ 17840132 100% 74.48MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 17842524 bytes received 31 bytes 11895036.67 bytes/sec
+ total size is 17840132 speedup is 1.00
+ ok
+ copy redacted.JPG (to USB...)
+ redacted
+ 4358032 100% 75.00MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 4358774 bytes received 31 bytes 8717610.00 bytes/sec
+ total size is 4358032 speedup is 1.00
+ ok
+ copy redacted.NEF (to USB...)
+ redacted
+ 18084753 100% 61.48MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 18087173 bytes received 31 bytes 12058136.00 bytes/sec
+ total size is 18084753 speedup is 1.00
+ ok
+ copy redacted.JPG (to USB...)
+ redacted
+ 4270213 100% 68.49MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 4270947 bytes received 31 bytes 2847318.67 bytes/sec
+ total size is 4270213 speedup is 1.00
+ ok
+ copy redacted.NEF (to USB...)
+ redacted
+ 17661246 100% 68.34MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 17663614 bytes received 31 bytes 11775763.33 bytes/sec
+ total size is 17661246 speedup is 1.00
+ ok
+ copy redacted.JPG (to USB...)
+ redacted
+ 4538305 100% 63.19MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 4539071 bytes received 31 bytes 9078204.00 bytes/sec
+ total size is 4538305 speedup is 1.00
+ ok
+ copy redacted.NEF (to USB...)
+ redacted
+ 18672466 100% 68.90MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 18674958 bytes received 31 bytes 12449992.67 bytes/sec
+ total size is 18672466 speedup is 1.00
+ ok
+ copy redacted.JPG (to USB...)
+ redacted
+ 4453445 100% 73.96MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 4454199 bytes received 31 bytes 8908460.00 bytes/sec
+ total size is 4453445 speedup is 1.00
+ ok
+ copy redacted.NEF (to USB...)
+ redacted
+ 18495494 100% 59.28MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 18497966 bytes received 31 bytes 12331998.00 bytes/sec
+ total size is 18495494 speedup is 1.00
+ ok
+ copy redacted.JPG (to USB...)
+ redacted
+ 4255858 100% 70.66MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 4256588 bytes received 31 bytes 1702647.60 bytes/sec
+ total size is 4255858 speedup is 1.00
+ ok
+ copy redacted.NEF (to USB...)
+ redacted
+ 18376531 100% 69.15MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 18378987 bytes received 31 bytes 36758036.00 bytes/sec
+ total size is 18376531 speedup is 1.00
+ ok
+ copy redacted.JPG (to USB...)
+ redacted
+ 4013365 100% 48.67MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 4014067 bytes received 31 bytes 8028196.00 bytes/sec
+ total size is 4013365 speedup is 1.00
+ ok
+ copy redacted.NEF (to USB...)
+ redacted
+ 17606341 100% 51.73MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 17608705 bytes received 31 bytes 11739157.33 bytes/sec
+ total size is 17606341 speedup is 1.00
+ ok
+ copy redacted.JPG (to USB...)
+ redacted
+ 4179869 100% 74.62MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 4180591 bytes received 31 bytes 8361244.00 bytes/sec
+ total size is 4179869 speedup is 1.00
+ ok
+ copy redacted.NEF (to USB...)
+ redacted
+ 18382569 100% 67.05MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 18385025 bytes received 31 bytes 12256704.00 bytes/sec
+ total size is 18382569 speedup is 1.00
+ ok
+ copy redacted.JPG (to USB...)
+ redacted
+ 4318363 100% 44.91MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 4319101 bytes received 31 bytes 8638264.00 bytes/sec
+ total size is 4318363 speedup is 1.00
+ ok
+ copy redacted.NEF (to USB...)
+ redacted
+ 17715958 100% 72.69MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 17718334 bytes received 31 bytes 11812243.33 bytes/sec
+ total size is 17715958 speedup is 1.00
+ ok
+ copy redacted.JPG (to USB...)
+ redacted
+ 4241893 100% 65.81MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 4242623 bytes received 31 bytes 8485308.00 bytes/sec
+ total size is 4241893 speedup is 1.00
+ ok
+ copy redacted.NEF (to USB...)
+ redacted
+ 17717287 100% 71.77MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 17719663 bytes received 31 bytes 11813129.33 bytes/sec
+ total size is 17717287 speedup is 1.00
+ ok
+ copy redacted.JPG (to USB...)
+ redacted
+ 4488380 100% 49.99MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 4489138 bytes received 31 bytes 2992779.33 bytes/sec
+ total size is 4488380 speedup is 1.00
+ ok
+ copy redacted.NEF (to USB...)
+ redacted
+ 17770208 100% 38.80MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 17772592 bytes received 31 bytes 11848415.33 bytes/sec
+ total size is 17770208 speedup is 1.00
+ ok
+ copy redacted.JPG (to USB...)
+ redacted
+ 4603958 100% 76.48MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 4604732 bytes received 31 bytes 9209526.00 bytes/sec
+ total size is 4603958 speedup is 1.00
+ ok
+ copy redacted.NEF (to USB...)
+ redacted
+ 18744380 100% 74.66MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 18746884 bytes received 31 bytes 12497943.33 bytes/sec
+ total size is 18744380 speedup is 1.00
+ ok
+ copy redacted.JPG (to USB...)
+ redacted
+ 4592098 100% 79.06MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 4592872 bytes received 31 bytes 3061935.33 bytes/sec
+ total size is 4592098 speedup is 1.00
+ ok
+ copy redacted.NEF (to USB...)
+ redacted
+ 18746205 100% 43.00MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 18748709 bytes received 31 bytes 12499160.00 bytes/sec
+ total size is 18746205 speedup is 1.00
+ ok
+ copy redacted.JPG (to USB...)
+ redacted
+ 7493353 100% 80.85MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 7494479 bytes received 31 bytes 14989020.00 bytes/sec
+ total size is 7493353 speedup is 1.00
+ ok
+ copy redacted.NEF (to USB...)
+ redacted
+ 19496768 100% 81.77MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 19499360 bytes received 31 bytes 12999594.00 bytes/sec
+ total size is 19496768 speedup is 1.00
+ ok
+ copy redacted.JPG (to USB...)
+ redacted
+ 5462482 100% 82.19MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 5463360 bytes received 31 bytes 10926782.00 bytes/sec
+ total size is 5462482 speedup is 1.00
+ ok
+ copy redacted.NEF (to USB...)
+ redacted
+ 19669815 100% 80.37MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 19672431 bytes received 31 bytes 13114974.67 bytes/sec
+ total size is 19669815 speedup is 1.00
+ ok
+ copy redacted.JPG (to USB...)
+ redacted
+ 5449487 100% 57.40MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 5450365 bytes received 31 bytes 3633597.33 bytes/sec
+ total size is 5449487 speedup is 1.00
+ ok
+ copy redacted.NEF (to USB...)
+ redacted
+ 19633259 100% 74.18MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 19635871 bytes received 31 bytes 13090601.33 bytes/sec
+ total size is 19633259 speedup is 1.00
+ ok
+ copy redacted.JPG (to USB...)
+ redacted
+ 5392184 100% 62.33MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 5393054 bytes received 31 bytes 3595390.00 bytes/sec
+ total size is 5392184 speedup is 1.00
+ ok
+ copy redacted.NEF (to USB...)
+ redacted
+ 18912104 100% 65.00MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 18914628 bytes received 31 bytes 12609772.67 bytes/sec
+ total size is 18912104 speedup is 1.00
+ ok
+ copy redacted.JPG (to USB...)
+ redacted
+ 4869300 100% 80.92MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 4870106 bytes received 31 bytes 9740274.00 bytes/sec
+ total size is 4869300 speedup is 1.00
+ ok
+ copy redacted.NEF (to USB...)
+ redacted
+ 20178932 100% 68.13MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 20181608 bytes received 31 bytes 13454426.00 bytes/sec
+ total size is 20178932 speedup is 1.00
+ ok
+ copy redacted.JPG (to USB...)
+ redacted
+ 4995425 100% 86.05MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 4996247 bytes received 31 bytes 9992556.00 bytes/sec
+ total size is 4995425 speedup is 1.00
+ ok
+ copy redacted.NEF (to USB...)
+ redacted
+ 19970679 100% 76.36MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 19973331 bytes received 31 bytes 13315574.67 bytes/sec
+ total size is 19970679 speedup is 1.00
+ ok
+ copy redacted.JPG (to USB...)
+ redacted
+ 7905795 100% 66.45MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 7906973 bytes received 31 bytes 15814008.00 bytes/sec
+ total size is 7905795 speedup is 1.00
+ ok
+ copy redacted.NEF (to USB...)
+ redacted
+ 21234069 100% 78.07MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 21236877 bytes received 31 bytes 8494763.20 bytes/sec
+ total size is 21234069 speedup is 1.00
+ ok
+ copy redacted.JPG (to USB...)
+ redacted
+ 7963979 100% 62.51MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 7965165 bytes received 31 bytes 5310130.67 bytes/sec
+ total size is 7963979 speedup is 1.00
+ git ["--git-dir=copy_target/.git","--work-tree=copy_target","update-index","-z","--index-info"]: Error in fork: forkProcess: resource exhausted (Resource temporarily unavailable)
+
+ git-annex: user error (git ["--git-dir=copy_target/.git","--work-tree=copy_target","update-index","-z","--index-info"]: Error in fork: forkProcess: resource exhausted (Resource temporarily unavailable))
+ failed
+ _506 TIMES_ (user error (Error in fork: forkProcess: resource exhausted (Resource temporarily unavailable))) failed
+ _11 TIMES_ copy foo (createPipe: resource exhausted (Too many open files)) failed
+ _2 TIMES_ (user error (Error in fork: forkProcess: resource exhausted (Resource temporarily unavailable))) failed
+ _8574 TIMES_: copy foo (createPipe: resource exhausted (Too many open files)) failed
+ git-annex: createPipe: resource exhausted (Too many open files)
+ failed
+ git-annex: 9101 failed
+
+ % ls copy_target/.git/annex/tmp/redacted_E13 copy_target/.git/annex/tmp/SHA512E-redacted_E13 # works
+ % find source -type l | wc -l
+ 13554
+ % find copy_target -type l | wc -l
+ 13554
+ % find copy_target/.git/annex/objects -type f | wc -l
+ 4455
+ % find source -type f | wc -l
+ 13554
+
+> Fixed unreaped process leak.
+> (This has nothing to do with NTFS). Ran test with 10k files
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/fails_to_handle_lot_of_files/comment_1_09d8e4e66d8273fab611bd29e82dc7fc._comment b/doc/bugs/fails_to_handle_lot_of_files/comment_1_09d8e4e66d8273fab611bd29e82dc7fc._comment
new file mode 100644
index 000000000..587b1fd97
--- /dev/null
+++ b/doc/bugs/fails_to_handle_lot_of_files/comment_1_09d8e4e66d8273fab611bd29e82dc7fc._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 1"
+ date="2011-10-26T17:16:52Z"
+ content="""
+After another run, i am at 8909 files in the remote, now.
+"""]]
diff --git a/doc/bugs/fails_to_handle_lot_of_files/comment_2_fd2ec05f4b5a7a6ae6bd9f5dbc3156de._comment b/doc/bugs/fails_to_handle_lot_of_files/comment_2_fd2ec05f4b5a7a6ae6bd9f5dbc3156de._comment
new file mode 100644
index 000000000..8e83fc19f
--- /dev/null
+++ b/doc/bugs/fails_to_handle_lot_of_files/comment_2_fd2ec05f4b5a7a6ae6bd9f5dbc3156de._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 2"
+ date="2011-10-26T18:22:34Z"
+ content="""
+In case this matters, I just realized that this disk has been formatted with NTFS instead of a sane FS.
+"""]]
diff --git a/doc/bugs/failure_to_find_file_that___34__should__34___exist_in_remote_is_silent.mdwn b/doc/bugs/failure_to_find_file_that___34__should__34___exist_in_remote_is_silent.mdwn
new file mode 100644
index 000000000..5718e5011
--- /dev/null
+++ b/doc/bugs/failure_to_find_file_that___34__should__34___exist_in_remote_is_silent.mdwn
@@ -0,0 +1,37 @@
+### Please describe the problem.
+
+One of my remotes (a USB drive) actually did not have a large number of files that should have been there, according to git annex's records. When the assistant would try to fetch files from there, it would silently fail and go get them from another remote. I noticed this behavior and was very puzzled by it. I eventually went to the command line and started trying to fetch these files. If I remember correctly, "getting" them would also fail silently. "git annex whereis" said they were there on the drive.
+
+Finally I did a "git annex fsck --fast" which quickly revealed the problem (several hundred files were gone, all in "archives")
+
+I am not sure how this happened, though I have some vague ideas -- it could be relics of a time when an ordinary directory had been created where a mountpoint for the USB drive should have existed, and it was trying to copy files there. Or it could have been a side effect of the somewhat confused process where I migrated to a new macbook using OS X's migration assistant and so I suddenly had two copies of the same archive, and some time was spent fiddling around trying to fix that situation up. Maybe during that point I accidentally flipped that USB repo into being a client instead of a backup repo, and it started dropping archive content, and maybe I stopped it from recording that by impatiently killing what seemed to be a hung git-annex process.... In any case, I don't know how the situation came into existence, but once it existed, the silent failures made it difficult for me to realize that it was happening. I thought the content really was there (trusting git annex whereis) and it was refusing to transfer it for some reason.
+
+It would have been useful to get some feedback, either in the assistant or the commandline, to the effect that the files which were supposed to be there according to git-annex's information, were not in fact there, and a fsck was called for.
+
+### What steps will reproduce the problem?
+
+Create an annex, with content. Clone the annex. Sync. Delete the files by force from the .git/annex/objects directory in the original. Go to the clone, and try and "git annex get" the content. It fails silently.
+
+
+### What version of git-annex are you using? On what operating system?
+
+ [12:17:03 PM]$ git annex version
+ git-annex version: 4.20130709-ga2269ee
+
+ build flags: Assistant Webapp Pairing Testsuite S3 WebDAV FsEvents XMPP DNS
+ local repository version: 3
+ default repository version: 3
+ supported repository versions: 3 4
+ upgrade supported from repository versions: 0 1 2
+
+My particular issue has probably existed through a few version upgrades though.
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
diff --git a/doc/bugs/failure_to_find_file_that___34__should__34___exist_in_remote_is_silent/comment_1_c686df2824d3f588c0bfb339c99168b7._comment b/doc/bugs/failure_to_find_file_that___34__should__34___exist_in_remote_is_silent/comment_1_c686df2824d3f588c0bfb339c99168b7._comment
new file mode 100644
index 000000000..64bc18b71
--- /dev/null
+++ b/doc/bugs/failure_to_find_file_that___34__should__34___exist_in_remote_is_silent/comment_1_c686df2824d3f588c0bfb339c99168b7._comment
@@ -0,0 +1,29 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.110"
+ subject="comment 1"
+ date="2013-07-26T21:08:02Z"
+ content="""
+Tried to reproduce this, following your instructions. It did not seem to work:
+
+<pre>
+joey@gnu:~/tmp/mydir2>git annex get disk2
+get disk2
+ Unable to access these remotes: origin
+
+ Try making some of these repositories available:
+ 21606444-98f9-4c40-aa60-3ebfba936758 -- origin (joey@gnu:~/tmp/mydir)
+failed
+git-annex: get: 1 failed
+- exit 1
+joey@gnu:~/tmp/mydir2>git annex whereis disk2
+whereis disk2 (1 copy)
+ 21606444-98f9-4c40-aa60-3ebfba936758 -- origin (joey@gnu:~/tmp/mydir)
+ok
+joey@gnu:~/tmp/mydir2>
+</pre>
+
+So, not a silent failure. It is a little unclear about why it can't get the file (in this case because I moved .git/annex/objects out of the way), but it's pretty clear it can't.
+
+AFAIK, the only way `git annex get` can silently not do anything is if you already have the file locally. Perhaps you got confused? OTOH, if you can provide a better way to reproduce this, I'm curious to see it.
+"""]]
diff --git a/doc/bugs/failure_to_find_file_that___34__should__34___exist_in_remote_is_silent/comment_2_22edfac4ce25cd9f4e4c85e0a8a52bc1._comment b/doc/bugs/failure_to_find_file_that___34__should__34___exist_in_remote_is_silent/comment_2_22edfac4ce25cd9f4e4c85e0a8a52bc1._comment
new file mode 100644
index 000000000..2d500288f
--- /dev/null
+++ b/doc/bugs/failure_to_find_file_that___34__should__34___exist_in_remote_is_silent/comment_2_22edfac4ce25cd9f4e4c85e0a8a52bc1._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="99.54.57.201"
+ subject="comment 2"
+ date="2013-07-27T06:03:55Z"
+ content="""
+I actually ran through the test I described to you and got the silent failure, but now I'm doing it again and getting the \"Try making some of these repositories available\" error. (Along with inaccurate \"whereis\" info, as you're seeing there.) I'm baffled. Unless something changed with respect to this behavior in the most recent version, which I've installed since then, I don't know what I was doing differently. Maybe I was confused.
+
+I can guarantee that I was getting silent failures in \"gets\" from my USB drive. I was \"getting\" \"--from\" my USB drive, nothing was showing up (the symlink was broken), and no error was printed to the console, including the \"try making it available\" one we're getting now. It's only when I went to the drive and did a \"git annex fsck\" that I realized that those files were actually missing from that remote, and it wasn't just a failure to \"get\" them. The behavior was alarming enough that I made sure of what was happening before I made the bug report. I wish I'd actually cut and pasted the demo, instead of just describing it!
+
+It'd still be nice to have some kind of feedback in the assistant (and maybe more understandable feedback in the command line) that something was amiss. What I would see in the assistant, because of this, is a bunch of queued downloads from the USB drive, but as each one was ready to execute, it would disappear (because it failed) and be replaced by a download from the (lower priority) SSH repo. This happened a number of times and I found it baffling.
+
+My first instinct in a situation like this is to say \"yeah, I must have been confused\" but I honestly did check this out pretty carefully before sending it in, so I wonder if a recent update improved matters, perhaps inadvertently? In any case, I'm glad there's some kind of error right now.
+"""]]
diff --git a/doc/bugs/failure_to_find_file_that___34__should__34___exist_in_remote_is_silent/comment_3_74fc0e41a6bd5c4d8c4b2f15e5ed8d2f._comment b/doc/bugs/failure_to_find_file_that___34__should__34___exist_in_remote_is_silent/comment_3_74fc0e41a6bd5c4d8c4b2f15e5ed8d2f._comment
new file mode 100644
index 000000000..5abbe99c3
--- /dev/null
+++ b/doc/bugs/failure_to_find_file_that___34__should__34___exist_in_remote_is_silent/comment_3_74fc0e41a6bd5c4d8c4b2f15e5ed8d2f._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.110"
+ subject="comment 3"
+ date="2013-07-27T22:39:12Z"
+ content="""
+The --from is the missing piece to reproduce:
+
+[[!format sh \"\"\"
+joey@gnu:~/tmp/old/mydir2>git annex get disk2 --from origin
+joey@gnu:~/tmp/old/mydir2>
+\"\"\"]]
+
+What's going on here is that `get --from` is essentially an alias to `copy --from`, and that skips copying files that it knows are not present on the remote. Since the remote is a local directory, it's inexpensive for it to check if the file is really there, rather than relying on the location log.
+
+This seems suboptimal, but I'm not sure which part of the behavior it makes sense to change. It seems nice for `copy --from` to silently skip files that the remote does not have, to avoid much unnecessary output when processing a lot of files. Maybe `get --from` should behave differently?
+"""]]
diff --git a/doc/bugs/failure_to_find_file_that___34__should__34___exist_in_remote_is_silent/comment_4_7d642fc65040a7b583cdece33db01826._comment b/doc/bugs/failure_to_find_file_that___34__should__34___exist_in_remote_is_silent/comment_4_7d642fc65040a7b583cdece33db01826._comment
new file mode 100644
index 000000000..18c9b6668
--- /dev/null
+++ b/doc/bugs/failure_to_find_file_that___34__should__34___exist_in_remote_is_silent/comment_4_7d642fc65040a7b583cdece33db01826._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.110"
+ subject="comment 4"
+ date="2013-07-27T22:40:58Z"
+ content="""
+I should add that it also seems to make sense to stat the file to see if it's present, like it does now. The location log can be out of date, and when more accurate info is right there, it should use it. And nor is the location log being out of date something that it should complain about, because it can easily happen eg when `git annex sync` has not been run recently.
+"""]]
diff --git a/doc/bugs/failure_to_find_file_that___34__should__34___exist_in_remote_is_silent/comment_5_49be366b6af6db595fa538373a61e650._comment b/doc/bugs/failure_to_find_file_that___34__should__34___exist_in_remote_is_silent/comment_5_49be366b6af6db595fa538373a61e650._comment
new file mode 100644
index 000000000..6ba31d562
--- /dev/null
+++ b/doc/bugs/failure_to_find_file_that___34__should__34___exist_in_remote_is_silent/comment_5_49be366b6af6db595fa538373a61e650._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="99.54.57.201"
+ subject="comment 5"
+ date="2013-07-28T05:29:00Z"
+ content="""
+Oh yeah! That makes sense now. It's not exactly that it's failing, it's just that the command \"git annex get --from=bar foo\" means \"get any copies of foo which might exist in the bar remote.\" Not \"get the copy of foo which I happen to know exists in the bar remote.\"
+
+I'm not sure either exactly what \"better\" behavior would be.
+"""]]
diff --git a/doc/bugs/failure_to_return_to_indirect_mode_on_usb.mdwn b/doc/bugs/failure_to_return_to_indirect_mode_on_usb.mdwn
new file mode 100644
index 000000000..f2a11eea8
--- /dev/null
+++ b/doc/bugs/failure_to_return_to_indirect_mode_on_usb.mdwn
@@ -0,0 +1,19 @@
+### Please describe the problem.
+In a usb drive with a repository in direct mode, when I converted to indirect mode it fails
+
+### What steps will reproduce the problem?
+cd /Volumes/usb
+git annex indirect
+
+### What version of git-annex are you using? On what operating system?
+git-annex version: 4.20130627
+
+### Please provide any additional information below.
+
+[[!format sh """
+openFile: resource busy (file is locked)
+failed
+git-annex: indirect: 1 failed
+"""]]
+
+[[!tag moreinfo]]
diff --git a/doc/bugs/failure_to_return_to_indirect_mode_on_usb/comment_1_d7822b90c68bf845572b0a04a378d0bb._comment b/doc/bugs/failure_to_return_to_indirect_mode_on_usb/comment_1_d7822b90c68bf845572b0a04a378d0bb._comment
new file mode 100644
index 000000000..e0cf8ca84
--- /dev/null
+++ b/doc/bugs/failure_to_return_to_indirect_mode_on_usb/comment_1_d7822b90c68bf845572b0a04a378d0bb._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.193"
+ subject="comment 1"
+ date="2013-07-02T16:38:14Z"
+ content="""
+What filesystem is in use on this USB drive? For example, is it a FAT filesystem?
+
+What operating system are you using?
+"""]]
diff --git a/doc/bugs/fat_support.mdwn b/doc/bugs/fat_support.mdwn
new file mode 100644
index 000000000..70ee3b369
--- /dev/null
+++ b/doc/bugs/fat_support.mdwn
@@ -0,0 +1,13 @@
+Klaus pointed out that there are two problems that keep
+git-annex from being used on USB keys, that would typically
+be VFAT formatted:
+
+- Use of symlinks, which VFAT does not support. Very hard to fix.
+ Instead, just use [[/bare_repositories]] on the key,
+ they're supported now.
+- Use of ":" in filenames of object files, also not supported.
+ Could easily be fixed by reorganizing the object directory.
+
+[[Done]]; in annex.version 2 repos, colons are entirely avoided in
+filenames. So a bare git clone can be put on VFAT, and git-annex
+used to move stuff --to and --from it, for sneakernet.
diff --git a/doc/bugs/fat_support/comment_1_04bcc4795d431e8cb32293aab29bbfe2._comment b/doc/bugs/fat_support/comment_1_04bcc4795d431e8cb32293aab29bbfe2._comment
new file mode 100644
index 000000000..510e44984
--- /dev/null
+++ b/doc/bugs/fat_support/comment_1_04bcc4795d431e8cb32293aab29bbfe2._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="fmarier"
+ ip="121.73.248.43"
+ subject="Exporting to a FAT filesystem?"
+ date="2011-04-04T07:40:41Z"
+ content="""
+I'm using git-annex to keep my music in sync between all of my different machines. What I'd love to be able to do is to also keep it in sync with my iRiver player. Unfortunately, the firmware, Rockbox, doesn't support ext3, so I'm stuck with a FAT filesystem.
+
+I can see how the design of git-annex makes it rather difficult to get rid of the symlinks, so how about taking a different approach: something like a \"git annex export DEST\" which would take a destination (not a git remote) and rsync the content over to there as regular files.
+
+Maybe \"git annex sync DEST\" or \"git annex rsync DEST\" would be better names if we want to convey the idea that the destination will be made to look like the source repo, including performing the necessary deletions.
+"""]]
diff --git a/doc/bugs/fat_support/comment_2_bb4a97ebadb5c53809fc78431eabd7c8._comment b/doc/bugs/fat_support/comment_2_bb4a97ebadb5c53809fc78431eabd7c8._comment
new file mode 100644
index 000000000..7618c9a7b
--- /dev/null
+++ b/doc/bugs/fat_support/comment_2_bb4a97ebadb5c53809fc78431eabd7c8._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 2"
+ date="2011-04-04T18:20:45Z"
+ content="""
+Hey @fmarier. Well, this bug report is closed because you can already get rid of the symlinks. Just put a bare git repo on your fat filesystem, and use git-annex copy --to/--from there.
+
+Now, that puts all the files that are on the device in .git/annex/objects/xx/yy/blah.mp3 -- how well rockbox would support that I don't know. And if it tries to modify or delete those files, git annex also can't help you manage those changes.
+
+Another recent option is the [[special_remotes/directory]] special remote type, which again uses \"xx/yy/blah.mp3\" and can't track changes made to the files. This could perhaps be extended in the direction you suggest, although trying to fit this into the special remote infrastructure might not be a good fit really.
+
+The most likely way this has to get dealt with is really by using [[todo/smudge]] filters, which would eliminate the symlinks and allow copying a non-bare git repo onto vfat.
+"""]]
diff --git a/doc/bugs/fat_support/comment_3_df3b943bc1081a8f3f7434ae0c8e061e._comment b/doc/bugs/fat_support/comment_3_df3b943bc1081a8f3f7434ae0c8e061e._comment
new file mode 100644
index 000000000..f3db75c2f
--- /dev/null
+++ b/doc/bugs/fat_support/comment_3_df3b943bc1081a8f3f7434ae0c8e061e._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="fmarier"
+ subject="comment 3"
+ date="2011-04-05T10:00:21Z"
+ content="""
+Thanks for the reply @joey.
+
+While it would certainly be possible for a bare repo to exist on my iRiver, the problem is that the music player uses the filesystem to organize files into directories like \"Artist/Album/Track.ogg\". So replacing that with \"..../xx/yy/Track.ogg\" would make it fairly difficult to browse my music collection and select the album/track I want to listen to :)
+
+So unless I have the files physically organized like the symlinks, then it's probably not going to work very for that particular workflow. Smudge filters are interesting though. In the meantime, I'll look into rsyncing from another box which has the right filesystem layout onto my iRiver directly.
+"""]]
diff --git a/doc/bugs/fat_support/comment_4_90a8a15bedd94480945a374f9d706b86._comment b/doc/bugs/fat_support/comment_4_90a8a15bedd94480945a374f9d706b86._comment
new file mode 100644
index 000000000..722cbdd9e
--- /dev/null
+++ b/doc/bugs/fat_support/comment_4_90a8a15bedd94480945a374f9d706b86._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://ethan.betacantrips.com/"
+ nickname="ethan.glasser.camp"
+ subject="no symlinks"
+ date="2011-06-08T20:59:38Z"
+ content="""
+If you try to clone a git repo that has a symlink over to a VFAT filesystem, you get (in its place) a regular file that contains the name of the symlink target. So why can't git-annex use that? I could still do git annex get on this file, git annex would still \"know\" that it's a symlink, and could replace it with a copy of the real file (instead of putting it in .git/annex).
+
+I know if it were that simple, someone would have done it already, so what am I missing? I guess trying to get the file FROM the repository would fail because it wouldn't find the file in .git/annex? Couldn't you store a reverse mapping? You wouldn't be able to move the file around, but you already lose that once you give up symlinks. It would also be a little harder to tell which symlinks were \"dangling\"; I don't see an easy way to get around that. It would still be better than a bare repo..
+"""]]
diff --git a/doc/bugs/fat_support/comment_5_64bbf89de0836673224b83fdefa0407b._comment b/doc/bugs/fat_support/comment_5_64bbf89de0836673224b83fdefa0407b._comment
new file mode 100644
index 000000000..1063b0f91
--- /dev/null
+++ b/doc/bugs/fat_support/comment_5_64bbf89de0836673224b83fdefa0407b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 5"
+ date="2011-06-10T16:41:43Z"
+ content="""
+@ethan the reason that wouldn't work is because git would then see a file that was checked in and had its one line symlinkish content replaced with a huge binary blob. And git commit would try to commit that etc. The potential for foot-shooting is too high.
+"""]]
diff --git a/doc/bugs/fat_support/comment_6_a3b6000330c9c376611c228d746a1d55._comment b/doc/bugs/fat_support/comment_6_a3b6000330c9c376611c228d746a1d55._comment
new file mode 100644
index 000000000..c7defd13e
--- /dev/null
+++ b/doc/bugs/fat_support/comment_6_a3b6000330c9c376611c228d746a1d55._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkZRoTRyW3tox-FD2DQWxskgI6_tkEtHL4"
+ nickname="Ben"
+ subject="comment 6"
+ date="2012-07-23T16:11:52Z"
+ content="""
+The above would work fine for me but the files in my annex (e.g. .git/annex/objects/xx/yy/blah.ogg) don't have extensions like that, so my media player doesn't recognize them as media files. How do I get the files under \"objects\" to keep the extensions of the original files like in Joey's example?
+"""]]
diff --git a/doc/bugs/fat_support/comment_7_a0ac7f2c44efc8116940c7b94b35e9d0._comment b/doc/bugs/fat_support/comment_7_a0ac7f2c44efc8116940c7b94b35e9d0._comment
new file mode 100644
index 000000000..11668615e
--- /dev/null
+++ b/doc/bugs/fat_support/comment_7_a0ac7f2c44efc8116940c7b94b35e9d0._comment
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ subject="comment 7"
+ date="2012-07-24T14:51:50Z"
+ content="""
+You can get the extensions by migrating to the SHA1E (or SHA256E) backend.
+"""]]
diff --git a/doc/bugs/fat_support/comment_8_acc947643a635eb10a1bff92083a3506._comment b/doc/bugs/fat_support/comment_8_acc947643a635eb10a1bff92083a3506._comment
new file mode 100644
index 000000000..558e0ca10
--- /dev/null
+++ b/doc/bugs/fat_support/comment_8_acc947643a635eb10a1bff92083a3506._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmcYryijvlF8bJvM_eZNSrUPEkMlxMDGTQ"
+ nickname="Thiago"
+ subject="POSIX layer on top of VFAT using FUSE"
+ date="2012-11-24T00:21:23Z"
+ content="""
+I just found out about this project and didn't try it, but it looks like it would allow using git-annex on an usb stick with a normal repository:
+
+<http://sourceforge.net/projects/posixovl/>
+"""]]
diff --git a/doc/bugs/fatal:_empty_ident_name.mdwn b/doc/bugs/fatal:_empty_ident_name.mdwn
new file mode 100644
index 000000000..241477287
--- /dev/null
+++ b/doc/bugs/fatal:_empty_ident_name.mdwn
@@ -0,0 +1,51 @@
+**What steps will reproduce the problem?**
+
+ stone@skynet ~/annex $ git init
+ Initialized empty Git repository in /home/stone/annex/.git/
+ stone@skynet ~/annex $ git annex init "work"
+ init work
+ *** Please tell me who you are.
+
+ Run
+
+ git config --global user.email "you@example.com"
+ git config --global user.name "Your Name"
+
+ to set your account's default identity.
+ Omit --global to set the identity only in this repository.
+
+ fatal: empty ident name (for <stone@skynet>) not allowed
+ git-annex: git ["--git-dir=/home/stone/annex/.git","--work-tree=/home/stone/annex","commit-tree","4b825dc652cb6eb9a060e64bf8d69288fbee4904"] exited 128
+ stone@skynet ~/annex $ git config -l
+ user.email=stone@nospam.hu
+ user.name=Stone
+ core.editor=nano
+ color.ui=auto
+ core.repositoryformatversion=0
+ core.filemode=true
+ core.bare=false
+ core.logallrefupdates=true
+ annex.uuid=499fb545-0b98-4bfc-816c-fb3704f3aaa0
+ stone@skynet ~/annex $ cat ~/.gitconfig
+ [user]
+ email = stone@nospam.hu
+ name = Stone
+ [core]
+ editor = nano
+ [color]
+ ui = auto
+ stone@skynet ~/annex $
+
+**What is the expected output? What do you see instead?**
+
+
+**What version of git-annex are you using? On what operating system?**
+
+commit 56c037c69e75def74d6ea90de8aa8a1954c52178 Arch Linux
+
+**Please provide any additional information below.**
+
+> [[done]] by adding name to the user, in /etc/passwd. --Stone
+
+>> Actually, [[done]] by avoiding clobbering HOME when running some git
+>> commands. --[[Joey]]
diff --git a/doc/bugs/fatal:_empty_ident_name/comment_1_ceae87308fb75a1f79c7c8d63ec47226._comment b/doc/bugs/fatal:_empty_ident_name/comment_1_ceae87308fb75a1f79c7c8d63ec47226._comment
new file mode 100644
index 000000000..798658a46
--- /dev/null
+++ b/doc/bugs/fatal:_empty_ident_name/comment_1_ceae87308fb75a1f79c7c8d63ec47226._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.16"
+ subject="comment 1"
+ date="2012-08-31T15:04:09Z"
+ content="""
+This is an error message from git. [Git faq](https://git.wiki.kernel.org/index.php/GitFaq#Git_commit_is_dying_telling_me_.22fatal:_empty_ident_.3Cuser.40myhost.3E_not_allowed.22.2C_what.27s_wrong.3F). I don't understand why git is doing it given the configuration shown, but I suppose it would do the same thing if you run git commit by hand.
+"""]]
diff --git a/doc/bugs/fatal:_empty_ident_name/comment_2_68832ee3e0e7244ce62bccabe2e52630._comment b/doc/bugs/fatal:_empty_ident_name/comment_2_68832ee3e0e7244ce62bccabe2e52630._comment
new file mode 100644
index 000000000..934fcdfaf
--- /dev/null
+++ b/doc/bugs/fatal:_empty_ident_name/comment_2_68832ee3e0e7244ce62bccabe2e52630._comment
@@ -0,0 +1,25 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl1yBP_JDsO1TWSC1usoHXpfDRU01u_GXY"
+ nickname="Péter Károly"
+ subject="comment 2"
+ date="2012-08-31T18:30:15Z"
+ content="""
+I use git on the same machine nearly every day, it does not complain on commit.
+
+(On the same session after \"git annex init\" failed...)
+
+ stone@skynet ~/annex $ echo stone > bu
+ stone@skynet ~/annex $ git add bu
+ stone@skynet ~/annex $ git commit -a
+ [master (root-commit) ae5d41f] ds
+ 1 file changed, 1 insertion(+)
+ create mode 100644 bu
+ stone@skynet ~/annex $ git log
+ commit ae5d41fdd0b7082740633cf7931bb5a07be0fc5e
+ Author: Stone <stone@nospam.hu>
+ Date: Fri Aug 31 20:26:45 2012 +0200
+
+ ds
+ stone@skynet ~/annex $
+
+"""]]
diff --git a/doc/bugs/fatal:_empty_ident_name/comment_3_ed31ad316747343d7730e4c2d7dacd24._comment b/doc/bugs/fatal:_empty_ident_name/comment_3_ed31ad316747343d7730e4c2d7dacd24._comment
new file mode 100644
index 000000000..ff7f39e44
--- /dev/null
+++ b/doc/bugs/fatal:_empty_ident_name/comment_3_ed31ad316747343d7730e4c2d7dacd24._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.16"
+ subject="comment 3"
+ date="2012-08-31T18:52:53Z"
+ content="""
+Why don't you try the identical command that git-annex is running that fails:
+
+`git --git-dir=/home/stone/annex/.git --work-tree=/home/stone/annex commit-tree 4b825dc652cb6eb9a060e64bf8d69288fbee4904`
+"""]]
diff --git a/doc/bugs/fatal:_empty_ident_name/comment_4_b812d6f30e8a866bce7260a9ee3218e3._comment b/doc/bugs/fatal:_empty_ident_name/comment_4_b812d6f30e8a866bce7260a9ee3218e3._comment
new file mode 100644
index 000000000..9e8a1900e
--- /dev/null
+++ b/doc/bugs/fatal:_empty_ident_name/comment_4_b812d6f30e8a866bce7260a9ee3218e3._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl1yBP_JDsO1TWSC1usoHXpfDRU01u_GXY"
+ nickname="Péter Károly"
+ subject="comment 4"
+ date="2012-09-01T15:05:52Z"
+ content="""
+Finally I managed to get it working.
+
+My use on the computer didn't had name, so the 5th colum of my /etc/password file was empty. After I filled in my name everything worked like charm.
+
+Interesting that not my user's name from /etc/passwd get into the git log but the one that was in my ~/.gitconfig.
+
+"""]]
diff --git a/doc/bugs/fatal:_unable_to_access___39__..__47__..__47__..__47__..__47__C:__92__Users__92____91__...__93____92__annex__92__.git__47__config__39__:_Invalid_argument___40__Windows__41__.mdwn b/doc/bugs/fatal:_unable_to_access___39__..__47__..__47__..__47__..__47__C:__92__Users__92____91__...__93____92__annex__92__.git__47__config__39__:_Invalid_argument___40__Windows__41__.mdwn
new file mode 100644
index 000000000..dae654d13
--- /dev/null
+++ b/doc/bugs/fatal:_unable_to_access___39__..__47__..__47__..__47__..__47__C:__92__Users__92____91__...__93____92__annex__92__.git__47__config__39__:_Invalid_argument___40__Windows__41__.mdwn
@@ -0,0 +1,63 @@
+### What steps will reproduce the problem?
+[[!format sh """
+C:\Users\Bruno>mkdir annex
+
+C:\Users\Bruno>cd annex
+
+C:\Users\Bruno\annex>git init
+Initialized empty Git repository in C:/Users/Bruno/annex/.git/
+
+C:\Users\Bruno\annex>git annex init
+init
+ Detected a crippled filesystem.
+
+ Enabling direct mode.
+
+ Detected a filesystem without fifo support.
+
+ Disabling ssh connection caching.
+ok
+(Recording state in git...)
+
+C:\Users\Bruno\annex>echo test > test
+
+C:\Users\Bruno\annex>git annex add .
+add test (checksum...) ok
+(Recording state in git...)
+
+C:\Users\Bruno\annex>git commit -a -m added
+[master (root-commit) 2eea610] added
+ 1 file changed, 1 insertion(+)
+ create mode 120000 test
+
+C:\Users\Bruno\annex>git annex sync
+(Recording state in git...)
+fatal: unable to access '../../../../C:\Users\Bruno\annex\.git/config': Invalid argument
+
+git-annex: user error (xargs ["-0","git","--git-dir=C:\\Users\\Bruno\\annex\\.git","--work-tree=C:\\Users\\Bruno\\annex","add","-f"] exited 123)
+failed
+git-annex: sync: 1 failed
+"""]]
+
+### What version of git-annex are you using? On what operating system?
+Windows 8 (64 bits)
+
+git version 1.8.4.msysgit.0
+
+[[!format sh """
+git-annex version: 4.20131008-ge115441
+build flags: Pairing Testsuite S3 WebDAV DNS Feeds Quvi TDFA CryptoHash
+key/value backends: SHA256E SHA1E SHA512E SHA224E SHA384E SKEIN256E SKEIN512E SHA256 SHA1 SHA512 SHA224 SHA384 SKEIN256 SKEIN512 WORM URL
+remote types: git gcrypt S3 bup directory rsync web webdav glacier hook
+local repository version: 4
+default repository version: 3
+supported repository versions: 3 4
+upgrade supported from repository versions: 2
+"""]]
+
+### Please provide any additional information below.
+C:\Users\Bruno\annex\.git\config exists
+
+> xargs was one problem; also msysgit seems to just not
+> accept DOS style paths anymore in --git-dir or --git-work-tree.
+> megaweird. [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/fatal:_unable_to_access___39__..__47__..__47__..__47__..__47__C:__92__Users__92____91__...__93____92__annex__92__.git__47__config__39__:_Invalid_argument___40__Windows__41__/comment_1_e6f39b2ef55b0daa491f4b6329a906bc._comment b/doc/bugs/fatal:_unable_to_access___39__..__47__..__47__..__47__..__47__C:__92__Users__92____91__...__93____92__annex__92__.git__47__config__39__:_Invalid_argument___40__Windows__41__/comment_1_e6f39b2ef55b0daa491f4b6329a906bc._comment
new file mode 100644
index 000000000..cc616aae9
--- /dev/null
+++ b/doc/bugs/fatal:_unable_to_access___39__..__47__..__47__..__47__..__47__C:__92__Users__92____91__...__93____92__annex__92__.git__47__config__39__:_Invalid_argument___40__Windows__41__/comment_1_e6f39b2ef55b0daa491f4b6329a906bc._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="64.134.31.139"
+ subject="comment 1"
+ date="2013-10-16T20:42:07Z"
+ content="""
+I don't know what to make of this bug report. You say that \"C:\Users\Bruno\annex.git\config\" exists, but you show the creation of a \"C:\Users\Bruno\annex\", and not the other repository. I cannot reproduce it, even if I first \"git init --bare annex.git\".
+"""]]
diff --git a/doc/bugs/fatal:_unable_to_access___39__..__47__..__47__..__47__..__47__C:__92__Users__92____91__...__93____92__annex__92__.git__47__config__39__:_Invalid_argument___40__Windows__41__/comment_2_b47d6d188f38a8e4ca5ef5f70afadf6a._comment b/doc/bugs/fatal:_unable_to_access___39__..__47__..__47__..__47__..__47__C:__92__Users__92____91__...__93____92__annex__92__.git__47__config__39__:_Invalid_argument___40__Windows__41__/comment_2_b47d6d188f38a8e4ca5ef5f70afadf6a._comment
new file mode 100644
index 000000000..a40e9cbe5
--- /dev/null
+++ b/doc/bugs/fatal:_unable_to_access___39__..__47__..__47__..__47__..__47__C:__92__Users__92____91__...__93____92__annex__92__.git__47__config__39__:_Invalid_argument___40__Windows__41__/comment_2_b47d6d188f38a8e4ca5ef5f70afadf6a._comment
@@ -0,0 +1,48 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkGCmVc5qIJaQQgG82Hc5zzBdAVdhe2JEM"
+ nickname="Bruno"
+ subject="comment 2"
+ date="2013-10-16T22:47:46Z"
+ content="""
+There's no other repo yet. I have the same problem when I try to sync between two repos but I simplified the instructions to reproduce the bug easily.
+
+Here's the instructions on Debian :
+[[!format sh \"\"\"
+bruno@debian:~$ mkdir annex
+bruno@debian:~$ cd annex
+bruno@debian:~/annex$ git init
+Initialized empty Dépôt git dans /home/bruno/annex/.git/
+bruno@debian:~/annex$ git annex init
+init ok
+(Recording state in git...)
+bruno@debian:~/annex$ echo test > test
+bruno@debian:~/annex$ git annex add .
+add test (checksum...) ok
+(Recording state in git...)
+bruno@debian:~/annex$ git commit -a -m added
+[master (root-commit) 631049d] added
+ 1 file changed, 1 insertion(+)
+ create mode 120000 test
+bruno@debian:~/annex$ git annex sync
+commit
+ok
+bruno@debian:~/annex$\"\"\"]]
+
+It seems --git-dir wants 'c:/...' instead of 'c:\\...'.
+
+[[!format sh \"\"\"
+C:\Users\Bruno\annex>git --git-dir=C:\\Users\\Bruno\\annex\\.git --work-tree=C:\\Users\\Bruno\\annex add -f test
+fatal: unable to access '../../../../C:\\Users\\Bruno\\annex\\.git/config': Invalid argument
+
+C:\Users\Bruno\annex>git --git-dir=C:/Users/Bruno/annex/.git --work-tree=C:\\Users\\Bruno\\annex add -f test
+
+C:\Users\Bruno\annex>\"\"\"]]
+
+It's weird that I don't have any problem with the following command:
+[[!format sh \"\"\"C:\Users\Bruno\annex>git --git-dir=C:\\Users\\Bruno\\annex\\.git --work-tree=C:\\Users\\Bruno\\annex config -l
+core.symlinks=false
+core.autocrlf=true
+[...]\"\"\"]]
+
+Maybe there's a problem with `git version 1.8.4.msysgit.0`.
+"""]]
diff --git a/doc/bugs/fatal:_unable_to_access___39__..__47__..__47__..__47__..__47__C:__92__Users__92____91__...__93____92__annex__92__.git__47__config__39__:_Invalid_argument___40__Windows__41__/comment_4_b533b1de535a057b7ebf99afc92691ed._comment b/doc/bugs/fatal:_unable_to_access___39__..__47__..__47__..__47__..__47__C:__92__Users__92____91__...__93____92__annex__92__.git__47__config__39__:_Invalid_argument___40__Windows__41__/comment_4_b533b1de535a057b7ebf99afc92691ed._comment
new file mode 100644
index 000000000..ac4a9e91a
--- /dev/null
+++ b/doc/bugs/fatal:_unable_to_access___39__..__47__..__47__..__47__..__47__C:__92__Users__92____91__...__93____92__annex__92__.git__47__config__39__:_Invalid_argument___40__Windows__41__/comment_4_b533b1de535a057b7ebf99afc92691ed._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="108.236.230.124"
+ subject="comment 4"
+ date="2013-10-17T21:49:10Z"
+ content="""
+So this is a problem with msysgit 1.8.4. I have been able to reproduce it with that version. 1.8.3 did not have the problem.
+
+Seems to perhaps be due to the cygwin xargs flipping git into cygwin path mode somehow. (How all this works is massively complex and confusing to me.)
+All the other calls to git with identical parameters work fine. I can also reproduce the problem using some old git 1.7.x in the cygwin terminal.
+
+BTW, I noticed in your example that you ran \"git commit -a\". You should **never** do that in a [[direct mode]] repository. Read the direct mode documentation to understand why.
+"""]]
diff --git a/doc/bugs/file_access__47__locking_issues_with_the_assitant.mdwn b/doc/bugs/file_access__47__locking_issues_with_the_assitant.mdwn
new file mode 100644
index 000000000..701536844
--- /dev/null
+++ b/doc/bugs/file_access__47__locking_issues_with_the_assitant.mdwn
@@ -0,0 +1,54 @@
+### Please describe the problem.
+
+I have a latex file which takes two passes to build. It is in a directory managed by git-annex assistant and configured to use a remote SSH server as a transfer back-end.
+
+If I use latexmk to build the file with the git-assistant on then the build fails. If I turn off the git-assistant it succeeds.
+
+### What steps will reproduce the problem?
+
+[[!format sh """
+~/current/www.cmt.mhs.man.ac.uk $ git-annex assistant --autostart
+~/current/www.cmt.mhs.man.ac.uk $ latexmk -c admin_guide_cmt.tex
+~/current/www.cmt.mhs.man.ac.uk $ latexmk -pdf -silent admin_guide_cmt.tex
+
+Latexmk: Run number 1 of rule 'pdflatex'
+This is pdfTeX, Version 3.1415926-2.5-1.40.13 (TeX Live 2013/dev)
+ restricted \write18 enabled.
+entering extended mode
+print() on closed filehandle GEN32 at /usr/bin/latexmk line 4742.
+print() on closed filehandle GEN32 at /usr/bin/latexmk line 4759.
+print() on closed filehandle GEN32 at /usr/bin/latexmk line 4761.
+"""]]
+
+Dropping the silent option shows that the admin_guide_cmt.aux file is not available for writing - despite being created. I suspect that the assistant is somehow locking the file, or using it between passes of latex. If the auxillary files all ready exist then there is no problem (i.e., don't do the cleanup via latexmk -c)
+
+Disabling the assistant makes everything work. Latexmk is doing something odd - I can't replicate with the native latex build commands.
+
+### What version of git-annex are you using? On what operating system?
+
+Latest version, via cabal, on Fedora 18.
+
+### Please provide any additional information below.
+
+Nothing appears wrong with the assistant transfer wise.
+[[!format sh """
+add www.cmt.mhs.man.ac.uk/admin_guide_cmt.aux (checksum...) ok
+add www.cmt.mhs.man.ac.uk/admin_guide_cmt.fdb_latexmk (checksum...) [2013-06-11 14:42:17 BST] Committer: Committing changes to g
+it
+admin_guide_cmt.fdb_latexmk
+ 264 100% 0.00kB/s 0:00:00 (xfer#1, to-check=0/1)
+
+sent 372 bytes received 42 bytes 828.00 bytes/sec
+total size is 264 speedup is 0.64
+[2013-06-11 14:42:17 BST] Transferrer: Uploaded admin_gui..b_latexmk
+[2013-06-11 14:42:18 BST] Committer: Adding 3 files
+ok
+(Recording state in git...)
+add www.cmt.mhs.man.ac.uk/admin_guide_cmt.fls (checksum...) ok
+add www.cmt.mhs.man.ac.uk/admin_guide_cmt.log (checksum...) ok
+
+# End of transcript or log.
+"""]]
+
+> Ok, I was able to remove the write bit fiddling in direct mode. [[done]]
+> --[[Joey]]
diff --git a/doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_10_fadf06f5ab34e36ab130536ec55afc8e._comment b/doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_10_fadf06f5ab34e36ab130536ec55afc8e._comment
new file mode 100644
index 000000000..79cfafa17
--- /dev/null
+++ b/doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_10_fadf06f5ab34e36ab130536ec55afc8e._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnXybLxkPMYpP3yw4b_I6IdC3cKTD-xEdU"
+ nickname="Matt"
+ subject="comment 10"
+ date="2013-06-11T19:27:04Z"
+ content="""
+First off, I really like git-annex :-)
+
+Secondly, if I make the change as suggested, what are the consequences? When you add files to the annex back-end it may still be open and being written to? But then the next hash-function will reveal the differences of an incomplete upload and fix things.... But it may be too late as it's sent to other repositories...hmmmmm...I guess I want to know if I do this will my data be safe? I suspect not.
+
+Perhaps the race condition could be mitigated against (not solved) by simply introducing a slight delay? If only 5 secs it will catch many of these cases. And longer would prevent git committing files that I save, realize I've slightly got wrong, tweak and save again.
+"""]]
diff --git a/doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_11_4a337f7b1140c45e5dd660b40202f696._comment b/doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_11_4a337f7b1140c45e5dd660b40202f696._comment
new file mode 100644
index 000000000..99787d4c6
--- /dev/null
+++ b/doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_11_4a337f7b1140c45e5dd660b40202f696._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 11"
+ date="2013-06-12T17:03:07Z"
+ content="""
+There's an annex.delayadd git config setting you can use that makes it wait a specified number of seconds before committing. So it would indeed be a workaround to set: `git config annex.delayadd 2`
+
+However, I'm pretty confident I can entirely avoid this problem, safely.
+"""]]
diff --git a/doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_1_05e1398e78218ced9c2da6a2510949e8._comment b/doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_1_05e1398e78218ced9c2da6a2510949e8._comment
new file mode 100644
index 000000000..8adb71b38
--- /dev/null
+++ b/doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_1_05e1398e78218ced9c2da6a2510949e8._comment
@@ -0,0 +1,21 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnXybLxkPMYpP3yw4b_I6IdC3cKTD-xEdU"
+ nickname="Matt"
+ subject="comment 1"
+ date="2013-06-11T13:59:53Z"
+ content="""
+Here's a sample latex document
+
+ \documentclass[twocolumn,a4paper]{article}
+ \title{Test}
+ \begin{document}
+ \maketitle
+ \begin{abstract}
+ Test
+ \end{abstract}
+
+ Some unresolved refs for two passes:
+ \ref{one:a} and \ref{two:b}
+
+ \end{document}
+"""]]
diff --git a/doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_2_9226f0adf091154c0d8a08b340b71869._comment b/doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_2_9226f0adf091154c0d8a08b340b71869._comment
new file mode 100644
index 000000000..c30d751a8
--- /dev/null
+++ b/doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_2_9226f0adf091154c0d8a08b340b71869._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnXybLxkPMYpP3yw4b_I6IdC3cKTD-xEdU"
+ nickname="Matt"
+ subject="comment 2"
+ date="2013-06-11T14:13:22Z"
+ content="""
+My temporary work around so that I may continue to use the assistant is to touch an appropriate test.aux before running latexmk.
+"""]]
diff --git a/doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_3_44d3e2096b7d45a1062222bee83a346d._comment b/doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_3_44d3e2096b7d45a1062222bee83a346d._comment
new file mode 100644
index 000000000..d12a09421
--- /dev/null
+++ b/doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_3_44d3e2096b7d45a1062222bee83a346d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnXybLxkPMYpP3yw4b_I6IdC3cKTD-xEdU"
+ nickname="Matt"
+ subject="comment 3"
+ date="2013-06-11T14:23:50Z"
+ content="""
+FYI - I replicated this bug on an OSX system using the latest pre-packaged build of git-annex and TexLive.
+"""]]
diff --git a/doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_4_f2e1d188b7b2d2daf0d832c59a68583e._comment b/doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_4_f2e1d188b7b2d2daf0d832c59a68583e._comment
new file mode 100644
index 000000000..438036e70
--- /dev/null
+++ b/doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_4_f2e1d188b7b2d2daf0d832c59a68583e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 4"
+ date="2013-06-11T14:42:09Z"
+ content="""
+Are you using direct mode in your repository?
+"""]]
diff --git a/doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_5_998fe58994ecf855310e4b8e6cce9e18._comment b/doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_5_998fe58994ecf855310e4b8e6cce9e18._comment
new file mode 100644
index 000000000..8d27f6b5e
--- /dev/null
+++ b/doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_5_998fe58994ecf855310e4b8e6cce9e18._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnXybLxkPMYpP3yw4b_I6IdC3cKTD-xEdU"
+ nickname="Matt"
+ subject="comment 5"
+ date="2013-06-11T14:47:40Z"
+ content="""
+hi, yes I am. Is this bad?
+"""]]
diff --git a/doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_6_4ce243cb0ea8ff810a4949a5320e4afc._comment b/doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_6_4ce243cb0ea8ff810a4949a5320e4afc._comment
new file mode 100644
index 000000000..54f533a92
--- /dev/null
+++ b/doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_6_4ce243cb0ea8ff810a4949a5320e4afc._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 6"
+ date="2013-06-11T15:09:44Z"
+ content="""
+No. Direct mode makes this kind of problem less likely to occur.
+
+Are you only seeing this problem on OSX?
+
+My guess, which is only a guess at this point is that while direct mode leaves files in-place etc, which should avoid this kind of problem, it does mess with their permissions berifly when ingesting them into the annex. The write bit is breifly turned off,
+while it checks that nothing currently has the file open to be written.
+"""]]
diff --git a/doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_7_c713f6316d889c8fc52326f21375c1c4._comment b/doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_7_c713f6316d889c8fc52326f21375c1c4._comment
new file mode 100644
index 000000000..754ffe774
--- /dev/null
+++ b/doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_7_c713f6316d889c8fc52326f21375c1c4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 7"
+ date="2013-06-11T15:14:44Z"
+ content="""
+Re-reading, I see you're using Fedora and OSX.
+"""]]
diff --git a/doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_8_6dd23bab7983b8b1f938dd4f21a16f5a._comment b/doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_8_6dd23bab7983b8b1f938dd4f21a16f5a._comment
new file mode 100644
index 000000000..400f7597f
--- /dev/null
+++ b/doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_8_6dd23bab7983b8b1f938dd4f21a16f5a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 8"
+ date="2013-06-11T15:17:56Z"
+ content="""
+I can reproduce the bug. Doesn't look likely to involve a race, since it happens every time.
+"""]]
diff --git a/doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_9_961c8f968eff0b39a85b607ee3f7630d._comment b/doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_9_961c8f968eff0b39a85b607ee3f7630d._comment
new file mode 100644
index 000000000..419abf698
--- /dev/null
+++ b/doc/bugs/file_access__47__locking_issues_with_the_assitant/comment_9_961c8f968eff0b39a85b607ee3f7630d._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 9"
+ date="2013-06-11T15:30:14Z"
+ content="""
+My guess about the write bit seems to be spot on. Which does mean it's a race, just one that happens to be easy to reproduce. It does not happen every time, but 1 time out of 10 or more often.
+
+You can try commenting out the `preventWrite` line in `Command/Add.hs` and rebuilding to see it fix it for you too. I will need to think long and hard about how to make files be ingested safely without turning off the write bit. But, I had been meaning to work on that at some point anyway, so good to have this bug to make it happen.
+
+I instrumented latexmk's call to `$out_handle->open` to see how it's failing:
+
+open failed: Permission denied 256
+
+Which confirms the problem. It seems that it first creates the file, and then closes it, and then re-opens it to write to it some more. git-annex gets in between these two calls and messes up the permissions behind its back.
+"""]]
diff --git a/doc/bugs/file_modification_times.mdwn b/doc/bugs/file_modification_times.mdwn
new file mode 100644
index 000000000..2f75dcab7
--- /dev/null
+++ b/doc/bugs/file_modification_times.mdwn
@@ -0,0 +1,13 @@
+### Please describe the problem.
+The files created in another remote when syncing is "now" rather than keeping the modification time of the source file. As such, git-annex assistant is removing an important bit of information about the file.
+
+### What steps will reproduce the problem?
+1) create two repositories in your computer using webapp
+2) add files to RepoA, see that they are synced to the RepoB.
+3) check the file modification times from any file manager. you will see that while files in RepoA carry correct modification time, synced file in RepoB carries current time.
+
+### What version of git-annex are you using? On what operating system?
+Ubuntu 13.10 32bit version 4.20130815 from apt-get.
+
+> duplicate of [[todo/add_metadata_to_annexed_files]] --[[Joey]]
+> [[done]]
diff --git a/doc/bugs/fix_for_makefile_to_check_if_OS_is_linux_or_not___40__relates_to_the_new_inotify_flag__41__.mdwn b/doc/bugs/fix_for_makefile_to_check_if_OS_is_linux_or_not___40__relates_to_the_new_inotify_flag__41__.mdwn
new file mode 100644
index 000000000..fee00855e
--- /dev/null
+++ b/doc/bugs/fix_for_makefile_to_check_if_OS_is_linux_or_not___40__relates_to_the_new_inotify_flag__41__.mdwn
@@ -0,0 +1,36 @@
+Since the watch branch is now merged into master, it doesn't quite build cleanly on non-linux systems anymore. So here's a small change to the Makefile to work around the problem for now.
+
+<pre>
+From 707cb47744775c324060febe11987db5f10ed9ff Mon Sep 17 00:00:00 2001
+From: Jimmy Tang <jtang@tchpc.tcd.ie>
+Date: Mon, 18 Jun 2012 09:20:35 +0100
+Subject: [PATCH] Teach _Makefile_ to only do _-DWITH_INOTIFY_ when on a Linux
+ machine.
+
+---
+ Makefile | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/Makefile b/Makefile
+index 6d36e8b..8884b5c 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,12 @@
++OS:=$(shell uname | sed 's/[-_].*//')
++
++ifeq ($(OS),Linux)
++BASEFLAGS_OPTS+=-DWITH_INOTIFY
++endif
++
+ PREFIX=/usr
+ IGNORE=-ignore-package monads-fd -ignore-package monads-tf
+-BASEFLAGS=-Wall $(IGNORE) -outputdir tmp -IUtility -DWITH_S3 -DWITH_INOTIFY
++BASEFLAGS=-Wall $(IGNORE) -outputdir tmp -IUtility -DWITH_S3 $(BASEFLAGS_OPTS)
+ GHCFLAGS=-O2 $(BASEFLAGS)
+
+ ifdef PROFILE
+--
+1.7.10.4
+</pre>
+
+[[done]], thanks --[[Joey]]
diff --git a/doc/bugs/free_space_checking.mdwn b/doc/bugs/free_space_checking.mdwn
new file mode 100644
index 000000000..92e8be40d
--- /dev/null
+++ b/doc/bugs/free_space_checking.mdwn
@@ -0,0 +1,21 @@
+Should check that there is enough free space before trying to copy a
+file around.
+
+* Need a way to tell how much free space is available on the disk containing
+ a given repository.
+
+* And, need a way to tell the size of a file before copying it from
+ a remote, to check local disk space.
+
+ As of annex.version 2, this metadata can be available for any type
+ of backend. Newly added files will always have file size metadata,
+ while files that used a SHA backend and were added before the upgrade
+ won't.
+
+ So, need a migration process from eg SHA1 to SHA1+filesize. It will
+ find files that lack size info, and rename their keys to add the size
+ info. Users with old repos can run this on them, to get the missing
+ info recorded.
+
+> [[done]]; no migtation process for old SHA1 keys from v1 repo though.
+> --[[Joey]]
diff --git a/doc/bugs/free_space_checking/comment_1_a868e805be43c5a7c19c41f1af8e41e6._comment b/doc/bugs/free_space_checking/comment_1_a868e805be43c5a7c19c41f1af8e41e6._comment
new file mode 100644
index 000000000..954433deb
--- /dev/null
+++ b/doc/bugs/free_space_checking/comment_1_a868e805be43c5a7c19c41f1af8e41e6._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 1"
+ date="2011-03-15T14:11:27Z"
+ content="""
+Keep in mind that lots of small files may have significant overhead, so a warning that it's not possible to make sure there's enough space would make sense for certain corner cases. Actually finding out the exact overhead is beyond git-annex' scope and, given transparent compression etc, ability, but a warning, optionally with a \"do you want to continue\" prompt can't hurt.
+
+-- RichiH
+"""]]
diff --git a/doc/bugs/free_space_checking/comment_2_8a65f6d3dcf5baa3f7f2dbe1346e2615._comment b/doc/bugs/free_space_checking/comment_2_8a65f6d3dcf5baa3f7f2dbe1346e2615._comment
new file mode 100644
index 000000000..9a43fe3f2
--- /dev/null
+++ b/doc/bugs/free_space_checking/comment_2_8a65f6d3dcf5baa3f7f2dbe1346e2615._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 2"
+ date="2011-03-16T03:04:50Z"
+ content="""
+Right. You probably don't want git-annex to fill up your entire drive anyway, so if it tries to reseve 10 mb or 1% or whatever (probably configurable) for overhead, that should be good enough.
+"""]]
diff --git a/doc/bugs/free_space_checking/comment_3_0fc6ff79a357b1619d13018ccacc7c10._comment b/doc/bugs/free_space_checking/comment_3_0fc6ff79a357b1619d13018ccacc7c10._comment
new file mode 100644
index 000000000..ea4fb6c23
--- /dev/null
+++ b/doc/bugs/free_space_checking/comment_3_0fc6ff79a357b1619d13018ccacc7c10._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 3"
+ date="2011-03-16T15:40:56Z"
+ content="""
+Sometimes, I might want to fill up the disk as much as possible. Thus, a warning is preferable to erroring out too early, imo -- Richard
+"""]]
diff --git a/doc/bugs/fsck__47__fix_should_check__47__fix_the_permissions_of_.git__47__annex.mdwn b/doc/bugs/fsck__47__fix_should_check__47__fix_the_permissions_of_.git__47__annex.mdwn
new file mode 100644
index 000000000..c649ff9f7
--- /dev/null
+++ b/doc/bugs/fsck__47__fix_should_check__47__fix_the_permissions_of_.git__47__annex.mdwn
@@ -0,0 +1,8 @@
+git annex carefully setup restrictive permissions of .git/annex directories and files.
+
+The fsck command should check that they are still correct.
+The fix command should fix them.
+
+PS: Thanks for this nice tool!
+
+> Good idea, [[done]] (actually, fsck just fixes them too)! --[[Joey]]
diff --git a/doc/bugs/fsck_claims_failed_checksum_when_less_copies_than_required_are_found.mdwn b/doc/bugs/fsck_claims_failed_checksum_when_less_copies_than_required_are_found.mdwn
new file mode 100644
index 000000000..fe6536b6a
--- /dev/null
+++ b/doc/bugs/fsck_claims_failed_checksum_when_less_copies_than_required_are_found.mdwn
@@ -0,0 +1,57 @@
+ (checksum...) failed
+ fsck foo (fixing location log)
+ Only 1 of 2 trustworthy copies exist of foo
+ Back it up with git-annex copy.
+
+> You've given me severely partial output, and no test case, but until
+> it says "fsck foo", the output is pertaining to some other file than foo.
+> As far as I can see, there is no bug here. --[[Joey]]
+
+>> Sorry, I thought it would be obvious, but that's no excuse for not
+>> providing additional explanation. The problem is that fsck tells me a
+>> file's fsck has failed without printing extra details. In this case, the
+>> checksum is OK while I don't have enough copies to satisfy the fsck. The
+>> fact that I don't have enough copies is obviously relevant, but I would
+>> still like to know if the checksums are OK. -- Richard
+
+>>> I think you're misreading the truncated output you posted. The actual,
+>>> full output would make much more sense. --[[Joey]]
+
+>>>> No. I have a total of 14908 annex keys, 3333 of which are on a remote. The only message other than 'checksum OK' and the above is 'git-annex: 11577 failed'.
+>>>> I checked several files manually, their checksums are OK so `git annex
+>>>> fsck` is reporting those files as completely failed when they "only" miss copies. -- Richard
+
+>>>>> fsck considers not enough copies to be a failure condition; it prints
+>>>>> error messages about it etc. That has nothing to do with checksums.
+>>>>> --[[Joey]]
+
+>>>>>> I get that. Still, I think it would be _extremely_ useful to know what failures occurred, exactly. Not having enough copies is Not Good, yet not having enough copies and a locally correct file is _lot_ better than having not enough copies and a broken file. I.e. I would prefer:
+
+ (checksum...) OK
+ Not enough copies: Only 1 of 2 trustworthy copies exist of foo
+
+>>>>>> or similar and at the end
+
+ git-annex: 0 wrong checksums
+ git-annex: 11577 with too few copies
+
+>>>>>> In the end, it comes down to the distinction of different failure classes. -- Richard
+
+>>>>>>> For the third, and final time:
+>>>>>>> # You are misreading the truncated output you posted
+>>>>>>> The "checksum" line is regarding **different** file than the
+>>>>>>> not enough copies message. fsck does not attempt to checksum a file
+>>>>>>> that is not present. [[done]] --[[Joey]]
+
+
+>>>>>>>> I realized early on that I pasted the wrong cross-passage, but as there is a ton of the same output, I didn't think it would matter. I wasn't aware that it does not try to checksum when there aren't enough copies. To be fair, you only just mentioned that.
+>>>>>>>> Personally, I think that's a bug as it makes ensuring local correctness before copying a file to remotes impossible.
+>>>>>>>> Either way, I really didn't know it actually _skipped_ checksumming; that part was missing.
+>>>>>>>> For the benefit of anyone else who might read this, this is the correct order:
+
+ fsck foo (fixing location log)
+ Only 1 of 2 trustworthy copies exist of foo
+ Back it up with git-annex copy.
+ (checksum...) failed
+
+>>>>>>>> If you would like to keep things this way, fine. I think it's less than ideal, but I don't want to argue, either. -- Richard
diff --git a/doc/bugs/fsck_output.mdwn b/doc/bugs/fsck_output.mdwn
new file mode 100644
index 000000000..1b00dd7b3
--- /dev/null
+++ b/doc/bugs/fsck_output.mdwn
@@ -0,0 +1,46 @@
+When you check several files and the fsck fails, you get confusing output:
+
+<pre>
+O fsck test1 (checksum...)
+E Only 1 of 2 trustworthy copies of test1 exist.
+E Back it up with git-annex copy.
+O
+O failed
+O fsck test2 (checksum...)
+E Only 1 of 2 trustworthy copies of test2 exist.
+E Back it up with git-annex copy.
+O
+O failed
+</pre>
+
+The newline is in the wrong place and confuses the user. It should be printed _after_ "failed".
+
+> This is a consequence of part of the output being printed to stderr, and
+> part to stdout. I've marked the lines above with E and O.
+>
+> Normally a "failed" is preceeded by a message output to stdout desribing
+> the problem; such a message will not be "\n" terminated, so a newline
+> is always displayed before "failed". In this case, since the message
+> is sent to stderr, it is newline terminated.
+>
+> Fixing this properly would involve storing state, or rethinking
+> when git-annex displays newlines (and I rather like its behavior
+> otherwise).
+>
+> A related problem occurs if an error message is unexpetedly printed.
+> Dummying up an example:
+>
+> O get test1 (from foo...) E git-annex: failed to run ssh
+> failed
+>
+> --[[Joey]]
+
+>> Well, I fixed this in all cases except a thrown non-IO error (last
+>> example aboce), which output is printed by haskell's runtime. I'd
+>> have to add a second error handler to handle those, and it's not
+>> clear what it would do. Often an error will occur before anything
+>> else is printed, and then the current behavior is right; if something
+>> has been printed it would be nice to have a newline before the error,
+>> but by the time the error is caught we'd be out of the annex monad
+>> and not really have any way to know if something has been printed.
+>> I think my fix is good enough [[done]] --[[Joey]]
diff --git a/doc/bugs/fsck_should_double-check_when_a_content-check_fails.mdwn b/doc/bugs/fsck_should_double-check_when_a_content-check_fails.mdwn
new file mode 100644
index 000000000..dba775d37
--- /dev/null
+++ b/doc/bugs/fsck_should_double-check_when_a_content-check_fails.mdwn
@@ -0,0 +1,3 @@
+git annex fsck marks files as bad when the checksumming fails. But this could also be due to a read error when the actual data stored is correct. So, fsck should check twice when a checksum fails.
+
+> [[done]]; apparently problem was caused by bad RAM. --[[Joey]]
diff --git a/doc/bugs/fsck_should_double-check_when_a_content-check_fails/comment_1_03af24b70adbcd9f4b94d009f6b71d0a._comment b/doc/bugs/fsck_should_double-check_when_a_content-check_fails/comment_1_03af24b70adbcd9f4b94d009f6b71d0a._comment
new file mode 100644
index 000000000..543777e26
--- /dev/null
+++ b/doc/bugs/fsck_should_double-check_when_a_content-check_fails/comment_1_03af24b70adbcd9f4b94d009f6b71d0a._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.238"
+ subject="comment 1"
+ date="2013-01-14T16:26:59Z"
+ content="""
+Why stop at checking twice? The second check could also fail with a read error, and perhaps the third one would succeed. :P
+
+Seriously, I doubt that this is likely to be a benefit with a modern drive. If the file has a read error once, then error correction has already failed, and it's likely to fail again. Even if it managed to succeed the second time, you have a file that is being read wrong some of the time, which is not a good thing for fsck to leave unnoticed.
+
+Fsck moves bad files to `.git/annex/bad`, so the data in them can be recovered if it comes to that. Hopefully
+though, there's a copy of the file in another repository, so git-annex can just get it from there instead.
+"""]]
diff --git a/doc/bugs/fsck_should_double-check_when_a_content-check_fails/comment_2_41214a7d18c66b694645248d6ebeadbf._comment b/doc/bugs/fsck_should_double-check_when_a_content-check_fails/comment_2_41214a7d18c66b694645248d6ebeadbf._comment
new file mode 100644
index 000000000..ea9518cb6
--- /dev/null
+++ b/doc/bugs/fsck_should_double-check_when_a_content-check_fails/comment_2_41214a7d18c66b694645248d6ebeadbf._comment
@@ -0,0 +1,25 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkHDm_DOFRcHYebCnnYKKyIwiPD4iOiiIU"
+ nickname="Jörn"
+ subject="comment 2"
+ date="2013-01-14T17:37:45Z"
+ content="""
+Maybe I was too quick in blaming the hard drive. It might be my problem is somewhere else. Let me do what I should have done in the first place and give you a detailed problem description:
+
+I have got three hard drives, two internal, one external connected via USB. I have got a couple of repositories with small files (mp3, JPEGs and so on). Those are fine, fsck never complains about them.
+But in one repository with video files (i.e. much bigger files than in the other repos), git-annex fsck will always find some broken files. I run git-annex get to retrieve the broken files from other sources. Then I run
+fsck again - and it complains about some other files. This happens on all drives.
+
+This could mean:
+
+- all my drives are broken. However, SMART data are unsuspicious, and one of the drives is just a couple of days old.
+- git-annex fsck is broken
+- read errors like I mentioned in my first post
+- some process actually _altering_ the files (should not happen when the files are locked, right?)
+- something completely different? Some possibly dangerous source of radiation? :)
+
+Any ideas on this? Maybe I should hash the data in .git/annex/bad and check which value I get - can I tell git-annex to do so?
+
+Thanks,
+Jörn
+"""]]
diff --git a/doc/bugs/fsck_should_double-check_when_a_content-check_fails/comment_3_e7ddd77ea35994f2051f840e9b4c7e0c._comment b/doc/bugs/fsck_should_double-check_when_a_content-check_fails/comment_3_e7ddd77ea35994f2051f840e9b4c7e0c._comment
new file mode 100644
index 000000000..f7d6221de
--- /dev/null
+++ b/doc/bugs/fsck_should_double-check_when_a_content-check_fails/comment_3_e7ddd77ea35994f2051f840e9b4c7e0c._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.238"
+ subject="comment 3"
+ date="2013-01-14T19:06:37Z"
+ content="""
+I would doubt you'd have three broken drives, or read errors from 3 drives.
+
+You can use `sha256sum` to checksum the files in `bad` yourself, and compare the results with their names.
+If it matches, that would point to some kind of bug in fsck.
+"""]]
diff --git a/doc/bugs/fsck_should_double-check_when_a_content-check_fails/comment_4_36a70d5a378983a76fcdbb7fba044044._comment b/doc/bugs/fsck_should_double-check_when_a_content-check_fails/comment_4_36a70d5a378983a76fcdbb7fba044044._comment
new file mode 100644
index 000000000..64df24bdb
--- /dev/null
+++ b/doc/bugs/fsck_should_double-check_when_a_content-check_fails/comment_4_36a70d5a378983a76fcdbb7fba044044._comment
@@ -0,0 +1,32 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkHDm_DOFRcHYebCnnYKKyIwiPD4iOiiIU"
+ nickname="Jörn"
+ subject="comment 4"
+ date="2013-01-14T20:04:48Z"
+ content="""
+On the internal disk some files match, others don't:
+
+ 42c95aee60c41157ee6d092eeea7fab73dff7b45a6e16ba77a02e2a6fec01c15 SHA256-s1099424853--42c95aee60c41157ee6d092eeea7fab73dff7b45a6e16ba77a02e2a6fec01c15
+ 44c4d3b0f29d86597ae09cf52563e0a2adec7074f5359901fde8dbf88f9bc8ad SHA256-s1173029201--bb981fddd750db1255cc1fda1f9612250f766e4da946eac4c294d8071196615c
+ a9d804fe633ae69d0c926dea41059c211f78cf891abfa275c579bcc8e12fa700 SHA256-s1363601770--a9d804fe633ae69d0c926dea41059c211f78cf891abfa275c579bcc8e12fa700
+ bac5f30b696b643c76a456e3018214ce64be7d289afaac96a7fdba03eccf73fd SHA256-s1422005768--5754211ac3e7e6314de9aa34f7b1cfd3c9aed432f52b26189c4587dc505a30e8
+ be953e962d9c6a2699f361e468023aae34b1f7c66ad93852d8f88846b60ecbcc SHA256-s1424026123--258dbe5704a46ecd3190d278efdd2adfeee9ad81843bfaa0ed7adbc10ccd5362
+ b9f06383c76a0161312aaf6298eb764dbfb8e1e51555ec06d8c85c9f5df9fe20 SHA256-s1448369674--a703dfd46c147396def6e1db22c7917dbdf010658aa32df1cf598e37a04d5897
+ e2d748ee5c5098316bbe20c3f771f7f552b07c394a1e9932cba2a90883b6fb5c SHA256-s1480008949--505c7d2685290069140b2f03fa72a5b5e3f59c14961c60c5fd6532be05ad1c84
+ ac0d49461ca67ca2de0588491c39089634ae194870594dd869fbc84d42831baa SHA256-s1489602933--f3ff3fc71b4f5493db476f29f373a4b3bf8808e9a7487589fee632ea58a415af
+ b9b1d133772c88a1c5f856e2d4bcb696a453c795337b9f97cfa4c00876f49b88 SHA256-s1512599506--78dc0bdf0b4e382283a770a36c7f699c83611a0436059e6bb44c8e94d26cca5f
+ 497af65e2d400e5651d9b850bc5efbaa006cec08f3f0dfce5d09b8e3f994a80b SHA256-s1524648153--85548bcb693491eeae1d1315a6037d5a9a15d2a10066f04f6e7ce75b6eb1ca47
+ cb793e7ac6df827e96f7dfa34a10f13a899140372c4db58b08650314596d30fa SHA256-s1541427964--16b8f7d5e5e12af88e947b26ca4d38d6b6692de92a77d9ffef0c8c1d560db727
+ 27ea446f928239ade9c3c1f38119fa38da50a74036f9987d57cce3b52ae632e9 SHA256-s1561020163--cfce86c309d16af772e68527ba365ceac5db447d5bbfc335e063a2a4e9d513d6
+ 940d2c7ff3bde5662d71a1a463f6949c6dd6cf244d43ab7d48014a10d0fa5d6a SHA256-s1562397113--a057d447b5b32d2f1a440247d9dc3c3ca697798d73dd740670a3033dd0fcbb68
+ [...]
+
+
+On the usb drive, hashes match:
+
+ [joern@heracles bad]$ sha256sum *
+ e306e07a09af9be9a974632c777935ddd0f5333b603b5f205dba03753619d682 SHA256-s1564783770--e306e07a09af9be9a974632c777935ddd0f5333b603b5f205dba03753619d682
+ 8fe78a325a08099e56df44ff46d482607723dfc9402bcd8f4850907327603f05 SHA256-s207925248--8fe78a325a08099e56df44ff46d482607723dfc9402bcd8f4850907327603f05
+ 8823bd4ccf5f6ff2fe0976de6a856490ef3de0ab1c1e128bde770b732e86d94c SHA256-s923668098--8823bd4ccf5f6ff2fe0976de6a856490ef3de0ab1c1e128bde770b732e86d94c
+
+"""]]
diff --git a/doc/bugs/fsck_should_double-check_when_a_content-check_fails/comment_5_899c4afbc988d81984c5c3397285bb01._comment b/doc/bugs/fsck_should_double-check_when_a_content-check_fails/comment_5_899c4afbc988d81984c5c3397285bb01._comment
new file mode 100644
index 000000000..fb3838511
--- /dev/null
+++ b/doc/bugs/fsck_should_double-check_when_a_content-check_fails/comment_5_899c4afbc988d81984c5c3397285bb01._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="comment 5"
+ date="2013-01-14T21:57:30Z"
+ content="""
+If you have both the corrupted file and the good file you can use the `cmp` command to show exactly how they differ:
+
+ cmp -l file1 file2
+
+If files are regularly marked as corrupted you might have bad ram.
+"""]]
diff --git a/doc/bugs/fsck_should_double-check_when_a_content-check_fails/comment_6_dbff51d00c5645eb1832aa4644889c5e._comment b/doc/bugs/fsck_should_double-check_when_a_content-check_fails/comment_6_dbff51d00c5645eb1832aa4644889c5e._comment
new file mode 100644
index 000000000..724be0df0
--- /dev/null
+++ b/doc/bugs/fsck_should_double-check_when_a_content-check_fails/comment_6_dbff51d00c5645eb1832aa4644889c5e._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkHDm_DOFRcHYebCnnYKKyIwiPD4iOiiIU"
+ nickname="Jörn"
+ subject="comment 6"
+ date="2013-01-15T09:38:34Z"
+ content="""
+That was a good advice. I have just run memtest, and it seems my memory is broken. So this was probably the cause for all this trouble.
+
+Thanks!
+"""]]
diff --git a/doc/bugs/fsck_thinks_file_content_is_bad_when_it_isn__39__t.mdwn b/doc/bugs/fsck_thinks_file_content_is_bad_when_it_isn__39__t.mdwn
new file mode 100644
index 000000000..e9051f9f3
--- /dev/null
+++ b/doc/bugs/fsck_thinks_file_content_is_bad_when_it_isn__39__t.mdwn
@@ -0,0 +1,35 @@
+What steps will reproduce the problem?
+What is the expected output? What do you see instead?
+
+I can reproduce it locally, but don't know what's causing it. The file content is the same, I checked with md5sum and sha512sum. But fsck still thinks the content is different. Are there other factors I could check which fsck looks at? I'm using SHA512E backend.
+
+What version of git-annex are you using? On what operating system?
+
+git-annex version: 3.20120807 Ubuntu 12.04 updated on Aug 20th annex was installed via cabal on Aug 20th, all other packages are from ubuntu.
+
+> What is the error message from fsck? --[[Joey]]
+
+This is the output:
+
+> reinject ....Moon.avi (checksum...)
+> Bad file content; moved to /mnt/.../.git/annex/bad/SHA512E-s94402560--ead9db1f34739014a216239d9624bce74d92fe723de06505f9b94cb4c063142ba42b04546f11d3d33869b736e40ded2ff779cb32b26aa10482f09407df0f3c8d.Moon.avi
+failed
+> (Recording state in git...)
+> git-annex: reinject: 1 failed
+
+The original file also has sha512 ead9db1f34739014a216239d9624bce74d92fe723de06505f9b94cb4c063142ba42b04546f11d3d33869b736e40ded2ff779cb32b26aa10482f09407df0f3c8d
+
+>> And what sha512 does the file in .git/annex/bad have **now**? (fsck
+>> preserves the original filename; this says nothing about what the
+>> current checksum is, if the file has been corrupted). --[[Joey]]
+
+The same, as it's the file I was trying to inject:
+
+ead9db1f34739014a216239d9624bce74d92fe723de06505f9b94cb4c063142ba42b04546f11d3d33869b736e40ded2ff779cb32b26aa10482f09407df0f3c8d .git/annex/bad/SHA512E-s94402560--ead9db1f34739014a216239d9624bce74d92fe723de06505f9b94cb4c063142ba42b04546f11d3d33869b736e40ded2ff779cb32b26aa10482f09407df0f3c8d.Moon.avi
+
+That's what puzzles me, it is the same file, but for some weird reason git annex thinks it's not.
+
+> Ok, reproduced and fixed the bug. The "E" backends recently got support
+> for 2 levels of filename extensions, but were not made to drop them both
+> when fscking. [[done]] (I'll release a fixed version probably tomorrow;
+> fix is in git now.) --[[Joey]]
diff --git a/doc/bugs/fsck_thinks_file_content_is_bad_when_it_isn__39__t/comment_1_cafb58eca97a0a66110ac39b169d8de3._comment b/doc/bugs/fsck_thinks_file_content_is_bad_when_it_isn__39__t/comment_1_cafb58eca97a0a66110ac39b169d8de3._comment
new file mode 100644
index 000000000..9f63dbfa9
--- /dev/null
+++ b/doc/bugs/fsck_thinks_file_content_is_bad_when_it_isn__39__t/comment_1_cafb58eca97a0a66110ac39b169d8de3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawla3gLc6_rHuggFfy7o7eGMPvPztFZTrUQ"
+ nickname="Florian"
+ subject="comment 1"
+ date="2012-08-27T08:59:23Z"
+ content="""
+Works!
+"""]]
diff --git a/doc/bugs/gcrypt_initremote_pushes_git-annex_but_not_master.mdwn b/doc/bugs/gcrypt_initremote_pushes_git-annex_but_not_master.mdwn
new file mode 100644
index 000000000..c256778c8
--- /dev/null
+++ b/doc/bugs/gcrypt_initremote_pushes_git-annex_but_not_master.mdwn
@@ -0,0 +1,19 @@
+git-annex 4.20130911 on Debian Wheezy.
+
+Using `git annex initremote type=gcrypt` as described [here](http://git-annex.branchable.com/tips/fully_encrypted_git_repositories_with_gcrypt/) creates the repository and pushes the `git-annex` branch to it. It doesn't push `master` (or more generally: the currently checked out branch), as I have verified using `git remote show`.
+
+Manually pushing the branch makes `git annex sync` sync both branches with the gcrypt remote.
+
+I think that it should push the current branch upon creation of the special remote, since for at least me, the whole reason for wanting `git-remote-gcrypt` is that metadata as well as data can be stored encrypted on an SSH server.
+
+Thanks for considering this.
+
+> The git-annex branch is pushed by initremote because I have to push
+> *something* to determine the gcrypt-id. However, this is an implementation
+> detail, and not a feature of initremote. (It's more like a bug of
+> git-remote-gcrypt.)
+>
+> `git annex sync` will always push your currently checked out branch,
+> as well as the git-annex branch, no matter what `initremote` has done.
+>
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/get_failed__44___but_remote_has_the_file.mdwn b/doc/bugs/get_failed__44___but_remote_has_the_file.mdwn
new file mode 100644
index 000000000..254e3d820
--- /dev/null
+++ b/doc/bugs/get_failed__44___but_remote_has_the_file.mdwn
@@ -0,0 +1,40 @@
+Not sure what caused this, but I have a file that exists on two remotes, but I can only get it from one of them. If I try to get it from the other, it fails immediately (without even connecting):
+
+ pilot:~/vid/tv/Show$ git annex whereis Show\ -\ S03E08.mp4
+ whereis Show - S03E08.mp4 (2 copies)
+ 09c0b436-f8de-11e0-842f-b7644539d57f -- psychosis
+ 82814942-f8e0-11e0-b053-e70a61e98e19 -- bucket
+ ok
+
+ pilot:~/vid/tv/Show$ git annex fsck Show\ -\ S03E08.mp4
+ fsck Show - S03E08.mp4 ok
+
+ pilot:~/vid/tv/Show$ git annex get --from bucket Show\ -\ S03E08.mp4
+ get Show - S03E08.mp4 failed
+ git-annex: get: 1 failed
+
+ pilot:~/vid/tv/Show$ git annex get --debug --from bucket Show\ -\ S03E08.mp4
+ [2013-01-17 19:05:13 EST] read: git ["--git-dir=/home/jim/vid/.git","--work-tree=/home/jim/vid","show-ref","git-annex"]
+ [2013-01-17 19:05:13 EST] read: git ["--git-dir=/home/jim/vid/.git","--work-tree=/home/jim/vid","show-ref","--hash","refs/heads/git-annex"]
+ [2013-01-17 19:05:13 EST] read: git ["--git-dir=/home/jim/vid/.git","--work-tree=/home/jim/vid","log","refs/heads/git-annex..e41c3b1ee9127129f2c9fc3fa5d4771afcb5ffd7","--oneline","-n1"]
+ [2013-01-17 19:05:13 EST] read: git ["--git-dir=/home/jim/vid/.git","--work-tree=/home/jim/vid","log","refs/heads/git-annex..a7ae08bccede282f46c2073f6c3e52685a593482","--oneline","-n1"]
+ [2013-01-17 19:05:13 EST] read: git ["--git-dir=/home/jim/vid/.git","--work-tree=/home/jim/vid","log","refs/heads/git-annex..ae0f84e906423f4da465e3d3df9d46545684d3f5","--oneline","-n1"]
+ [2013-01-17 19:05:13 EST] chat: git ["--git-dir=/home/jim/vid/.git","--work-tree=/home/jim/vid","cat-file","--batch"]
+ [2013-01-17 19:05:13 EST] read: git ["--git-dir=/home/jim/vid/.git","--work-tree=/home/jim/vid","ls-files","--cached","-z","--","Show - S03E08.mp4"]
+ get Show - S03E08.mp4 failed
+ git-annex: get: 1 failed
+
+Same `git annex version` on both `pilot` and `bucket`, and I ran `git annex sync` on both.
+
+ git-annex version: 3.20130114
+ local repository version: 3
+ default repository version: 3
+ supported repository versions: 3
+ upgrade supported from repository versions: 0 1 2
+
+How should I debug this?
+
+> [[done]], in c6fbed48 I had made some changes to allow transfers
+> to work from readonly filesystems, but a too broad error trapping
+> hid the "transfer already in progress" error it is supposed to display
+> in this case. --[[Joey]]
diff --git a/doc/bugs/get_failed__44___but_remote_has_the_file/comment_1_55c8b73ce05dfca11a393bb296b99b9a._comment b/doc/bugs/get_failed__44___but_remote_has_the_file/comment_1_55c8b73ce05dfca11a393bb296b99b9a._comment
new file mode 100644
index 000000000..24825b2eb
--- /dev/null
+++ b/doc/bugs/get_failed__44___but_remote_has_the_file/comment_1_55c8b73ce05dfca11a393bb296b99b9a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.3.194"
+ subject="comment 1"
+ date="2013-01-18T20:25:01Z"
+ content="""
+One completely legitimate way for this to happen would be if bucket is a removable drive or other filesystem, and it is not mounted (or its directory doesn't contain a git repo for whatever reason). It would look identical to what you showed happening.
+
+Otherwise, what kind of remote is bucket? Special remote or git remote?
+"""]]
diff --git a/doc/bugs/get_failed__44___but_remote_has_the_file/comment_2_474c67a421dca4c245e7bfe495d3f6d3._comment b/doc/bugs/get_failed__44___but_remote_has_the_file/comment_2_474c67a421dca4c245e7bfe495d3f6d3._comment
new file mode 100644
index 000000000..a7e3d6b17
--- /dev/null
+++ b/doc/bugs/get_failed__44___but_remote_has_the_file/comment_2_474c67a421dca4c245e7bfe495d3f6d3._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnBJ6Dv1glxzzi4qIzGFNa6F-mfHIvv9Ck"
+ nickname="Jim"
+ subject="comment 2"
+ date="2013-01-19T21:40:14Z"
+ content="""
+They're all git remotes:
+
+ pilot:~/vid/tv$ git remote -v show
+ bucket ssh://bucket/home/jim/private/vid (fetch)
+ bucket ssh://bucket/home/jim/private/vid (push)
+ origin https://git/jim/annex.git (fetch)
+ origin https://git/jim/annex.git (push)
+ psychosis ssh://psychosis/vid/annex (fetch)
+ psychosis ssh://psychosis/vid/annex (push)
+
+And it never even attempts a ssh connection to bucket.
+"""]]
diff --git a/doc/bugs/get_failed__44___but_remote_has_the_file/comment_3_845e8a23d63fb0b071c63ee736697d26._comment b/doc/bugs/get_failed__44___but_remote_has_the_file/comment_3_845e8a23d63fb0b071c63ee736697d26._comment
new file mode 100644
index 000000000..0ddbe14bf
--- /dev/null
+++ b/doc/bugs/get_failed__44___but_remote_has_the_file/comment_3_845e8a23d63fb0b071c63ee736697d26._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnBJ6Dv1glxzzi4qIzGFNa6F-mfHIvv9Ck"
+ nickname="Jim"
+ subject="comment 3"
+ date="2013-01-19T22:21:04Z"
+ content="""
+Wait, that's weird, it works today. I'm thinking that maybe there was another copy of `git-annex` backgrounded and holding a lock, since that reproduces this behavior:
+
+ pilot:~/vid/tv/Show$ git annex get --from bucket Show\ -\ S03E08.mp4
+ get Show - S03E08.mp4 (from bucket...)
+ Enter passphrase for key '/home/jim/.ssh/id_rsa':
+ SHA256E-s358393024--efda17d23d68b85d47ad342f8e41f79ac04d4a65d7ef654b4838b995b86bdefe.mp4
+ 96043008 26% 10.27MB/s 0:00:24 ^Z
+ [1]+ Stopped git annex get --from bucket Show\ -\ S03E08.mp4
+ pilot:~/vid/tv/Show$ git annex get --from bucket Show\ -\ S03E08.mp4
+ get Show - S03E08.mp4 failed
+ git-annex: get: 1 failed
+
+So, I guess this is probably \"not a bug\", but having a more specific error would be really helpful.
+"""]]
diff --git a/doc/bugs/get_failed__44___but_remote_has_the_file/comment_4_7dec21cb67e7f4dbdb49da97f2443e8f._comment b/doc/bugs/get_failed__44___but_remote_has_the_file/comment_4_7dec21cb67e7f4dbdb49da97f2443e8f._comment
new file mode 100644
index 000000000..fd9a1f6d3
--- /dev/null
+++ b/doc/bugs/get_failed__44___but_remote_has_the_file/comment_4_7dec21cb67e7f4dbdb49da97f2443e8f._comment
@@ -0,0 +1,35 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawla7u6eLKNYZ09Z7xwBffqLaXquMQC07fU"
+ nickname="Matthias"
+ subject="ssh stall triggers this"
+ date="2013-03-14T22:55:11Z"
+ content="""
+I experienced a very similar bug today.
+
+While retrieving a rather large file from a remote git repository my internet connection broke down such that the ssh connection stalled. I noticed this and killed the transfer on my side. After the connection was up again I restarted the transfer and got the following output:
+
+git annex get --debug backup.iso
+[2013-03-14 23:30:26 CET] read: git [\"--git-dir=/home/user/annex/.git\",\"--work-tree=/home/user/annex\",\"ls-files\",\"--cached\",\"-z\",\"--\",\"backup.iso\"]
+get backup.iso [2013-03-14 23:30:26 CET] read: git [\"--git-dir=/home/user/annex/.git\",\"--work-tree=/home/user/annex\",\"show-ref\",\"git-annex\"]
+[2013-03-14 23:30:26 CET] read: git [\"--git-dir=/home/user/annex/.git\",\"--work-tree=/home/user/annex\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+[2013-03-14 23:30:26 CET] read: git [\"--git-dir=/home/user/annex/.git\",\"--work-tree=/home/user/annex\",\"log\",\"refs/heads/git-annex..7a133679de4f30a0c9cc552b6c9c85e8120e88e6\",\"--oneline\",\"-n1\"]
+[2013-03-14 23:30:26 CET] read: git [\"--git-dir=/home/user/annex/.git\",\"--work-tree=/home/user/annex\",\"log\",\"refs/heads/git-annex..715af259c233713a420f670a134f4550ba67832a\",\"--oneline\",\"-n1\"]
+[2013-03-14 23:30:26 CET] read: git [\"--git-dir=/home/user/annex/.git\",\"--work-tree=/home/user/annex\",\"log\",\"refs/heads/git-annex..7a905bff06ee702886829ca4482330071549994d\",\"--oneline\",\"-n1\"]
+[2013-03-14 23:30:26 CET] read: git [\"--git-dir=/home/user/annex/.git\",\"--work-tree=/home/user/annex\",\"log\",\"refs/heads/git-annex..51ca0f25220b216b12a236c05d2e2a5c121a99b7\",\"--oneline\",\"-n1\"]
+[2013-03-14 23:30:26 CET] read: git [\"--git-dir=/home/user/annex/.git\",\"--work-tree=/home/user/annex\",\"log\",\"refs/heads/git-annex..02f889b99107ddc699f204f4628539112dd90b81\",\"--oneline\",\"-n1\"]
+[2013-03-14 23:30:26 CET] read: git [\"--git-dir=/home/user/annex/.git\",\"--work-tree=/home/user/annex\",\"log\",\"refs/heads/git-annex..01da68a6d86554532701fafb46242dd706e25499\",\"--oneline\",\"-n1\"]
+[2013-03-14 23:30:26 CET] chat: git [\"--git-dir=/home/user/annex/.git\",\"--work-tree=/home/user/annex\",\"cat-file\",\"--batch\"]
+(from origin...)
+[2013-03-14 23:30:26 CET] read: rsync [\"--progress\",\"--inplace\",\"-e\",\"'ssh' '-S' '/home/user/annex/.git/annex/ssh/server.com' '-o' 'ControlMaster=auto' '-o' 'ControlPersist=yes' 'server.com' 'git-annex-shell ''sendkey'' ''/~/annex'' ''SHA256E-s4628086525--9d8a04ebcfabbda5baa29dbd834cc7e4c3ac5d7b74fec7a23023025952e78686.iso'' --uuid a3b225c4-d832-11e0-b8a3-cbd1782bb1f4 ''--'' ''remoteuuid=e4e649ca-16f9-11e1-ac1d-5f8104ffa876'' ''direct='' ''associatedfile=backup.iso'' ''--'''\",\"--\",\"dummy:\",\"/home/user/annex/.git/annex/tmp/SHA256E-s4628086525--9d8a04ebcfabbda5baa29dbd834cc7e4c3ac5d7b74fec7a23023025952e78686.iso\"]
+rsync: connection unexpectedly closed (0 bytes received so far) [Receiver]
+rsync error: error in rsync protocol data stream (code 12) at io.c(605) [Receiver=3.0.9]
+
+ Unable to access these remotes: origin
+
+However, I could retrieve any other file from origin. The problem was that git-annex-shell was still running on the remote side and therefore preventing me from fetching the file and only this file. Once I logged into the remote server, killed the still running git-annex-shell, \"git annex get\" behaved as it should and fetched the file.
+
+However, there is definitely room for an improved error message which at least gives a hint what the problem could be. Of course, the best solution would be if the file was simply transfered.
+
+
+
+"""]]
diff --git a/doc/bugs/get_fails_for_file:__47____47___web_remotes_if_the_file_is_empty.mdwn b/doc/bugs/get_fails_for_file:__47____47___web_remotes_if_the_file_is_empty.mdwn
new file mode 100644
index 000000000..bb943fa86
--- /dev/null
+++ b/doc/bugs/get_fails_for_file:__47____47___web_remotes_if_the_file_is_empty.mdwn
@@ -0,0 +1,26 @@
+###What steps will reproduce the problem?
+ $ touch /home/arand/empty
+ $ git annex addurl 'file:///home/arand/empty'
+ addurl _home_arand_empty (downloading file:///home/arand/empty ...)
+
+ git-annex: /home/arand/tmp/c/.git/annex/tmp/URL--file&c%%%home%arand%empty: getFileStatus: does not exist (No such file or directory)
+ failed
+ git-annex: addurl: 1 failed
+
+###What is the expected output? What do you see instead?
+If it is possible to distinguish between empty files and files that just fail to open, it would be nice if Annex were able to handle it, or at least give a more obvious error message.
+
+###What version of git-annex are you using? On what operating system?
+
+Debian sid/experimental
+
+ git-annex version: 4.20130227
+ local repository version: 4
+ default repository version: 3
+ supported repository versions: 3 4
+ upgrade supported from repository versions: 0 1 2
+
+> Seems that curl doesn't write the file it was asked to
+> output to in this case. Crazy. Does not affect empty
+> http urls. Switched to using just cp for file://
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/get_from_bup-remote_with_pubkey_failing.mdwn b/doc/bugs/get_from_bup-remote_with_pubkey_failing.mdwn
new file mode 100644
index 000000000..5ec1aa9aa
--- /dev/null
+++ b/doc/bugs/get_from_bup-remote_with_pubkey_failing.mdwn
@@ -0,0 +1,93 @@
+### Please describe the problem.
+
+I'm unable to 'git annex get' a file from a bup-remote with encryption set to 'pubkey'.
+
+### What steps will reproduce the problem?
+
+I added a bup-remote using [these instructions](http://git-annex.branchable.com/walkthrough/using_bup/):
+
+ bash-3.2$ git annex initremote mybup type=bup encryption=pubkey keyid=0xABE8244505D63E81 buprepo=gumdrop:/home/gert/.bup
+
+ # now adding files and moving them:
+ bash-3.2$ mkdir orgmode && touch orgmode/some.org
+ bash-3.2$ git annex add orgmode/some.org
+ add orgmode/some.org (checksum...) ok
+ (Recording state in git...)
+ bash-3.2$ git commit
+ [master bce8c83] Some.org
+ 1 file changed, 1 insertion(+)
+ create mode 120000 orgmode/some.org
+ bash-3.2$ git annex move orgmode/ --to=mybup
+ move orgmode/another.org (gpg)
+ U moet een geheime zin opgeven om de geheime sleutel te gebruiken
+ van: “email”
+ 4096-bit RSA key, ID 0xFF8DE378DE223820, created 2013-11-10
+ (sub-sleutel bij hoofd sleutel ID 0xE9B90528FDA4E1E6)
+
+ (checking mybup...) ok
+ (Recording state in git...)
+ bash-3.2$ less orgmode/another.org
+ orgmode/another.org: No such file or directory
+ bash-3.2$ git annex get orgmode/another.org --debug
+ [2013-11-13 16:18:07 CET] read: git ["--git-dir=/Users/gert/annex/.git","--work-tree=/Users/gert/annex","ls-files","--cached","-z","--","orgmode/another.org"]
+ get orgmode/another.org [2013-11-13 16:18:08 CET] read: git ["--git-dir=/Users/gert/annex/.git","--work-tree=/Users/gert/annex","show-ref","git-annex"]
+ [2013-11-13 16:18:08 CET] read: git ["--git-dir=/Users/gert/annex/.git","--work-tree=/Users/gert/annex","show-ref","--hash","refs/heads/git-annex"]
+ [2013-11-13 16:18:08 CET] read: git ["--git-dir=/Users/gert/annex/.git","--work-tree=/Users/gert/annex","log","refs/heads/git-annex..f25f9bb2b78a8b9c4b64087f1378c68fb5c0a2f1","--oneline","-n1"]
+ [2013-11-13 16:18:08 CET] read: git ["--git-dir=/Users/gert/annex/.git","--work-tree=/Users/gert/annex","log","refs/heads/git-annex..1b0a3dd72be437d800e58d659837d6e528cbbc39","--oneline","-n1"]
+ [2013-11-13 16:18:08 CET] read: git ["--git-dir=/Users/gert/annex/.git","--work-tree=/Users/gert/annex","log","refs/heads/git-annex..f62419efea58245d232a52ceaf0eaefe3b0fdced","--oneline","-n1"]
+ [2013-11-13 16:18:08 CET] read: git ["--git-dir=/Users/gert/annex/.git","--work-tree=/Users/gert/annex","log","refs/heads/git-annex..eb6f0cd983d9a3637e984aa815537fe20a5c2a69","--oneline","-n1"]
+ [2013-11-13 16:18:08 CET] read: git ["--git-dir=/Users/gert/annex/.git","--work-tree=/Users/gert/annex","log","refs/heads/git-annex..5362118e643462a0875bfe31d493ffe64413f2d8","--oneline","-n1"]
+ [2013-11-13 16:18:08 CET] read: git ["--git-dir=/Users/gert/annex/.git","--work-tree=/Users/gert/annex","log","refs/heads/git-annex..e5afaf82ce25f60a108c0ae873b6fd57c5d28ca7","--oneline","-n1"]
+ [2013-11-13 16:18:08 CET] chat: git ["--git-dir=/Users/gert/annex/.git","--work-tree=/Users/gert/annex","cat-file","--batch"]
+ [2013-11-13 16:18:08 CET] read: git ["config","--null","--list"]
+ (from mybup...) (gpg) [2013-11-13 16:18:08 CET] chat: gpg ["--quiet","--trust-model","always","--decrypt"]
+
+ U moet een geheime zin opgeven om de geheime sleutel te gebruiken
+ van: “<email>”
+ 4096-bit RSA key, ID 0xFF8DE378DE223820, created 2013-11-10
+ (sub-sleutel bij hoofd sleutel ID 0xE9B90528FDA4E1E6)
+
+ [2013-11-13 16:18:15 CET] read: bup ["join","-r","gumdrop:/home/gert/.bup","GPGHMACSHA1--67aec1b62d05d000442cf8e7d9df8d327eaf26d5"]
+ [2013-11-13 16:18:15 CET] chat: gpg ["--quiet","--trust-model","always","--batch","--decrypt"]
+ gpg: kan geheime zin niet opvragen in batch modus
+ gpg: decoderen mislukt: secret key not available
+
+ Unable to access these remotes: mybup
+
+ Try making some of these repositories available:
+ 080e97d2-4f82-4292-acb7-a48d82009258 -- mybup (mybupmy bup repository at gumdrop)
+
+ (Note that these git remotes have annex-ignore set: origin)
+ failed
+ git-annex: get: 1 failed
+
+### What version of git-annex are you using? On what operating system?
+
+Running git-annex version 4.20131105-g136b030 on OSX 10.8.5.
+
+### Please provide any additional information below.
+
+My ideas:
+
+"Unable to access these remotes: mybup" is weird, I just moved files there.
+
+"secret key not available" makes me think it's looking for the primary secret key (which is indeed offline).
+When I encrypt a file with the same key I used to create the remote it just works:
+
+ $ gpg --armor --recipient 0xABE8244505D63E81 --encrypt file.txt
+ $ gpg --decrypt file.txt.asc
+
+When prompting for my passphrase it states "4096-bit RSA key, ID 0xFF8DE378DE223820, created 2013-11-10".
+That is a different subkey than what I entered when I setting up the remote.
+
+My keys/subkeys:
+
+ pub 4096R/0xE9B90528FDA4E1E6 aangemaakt: 2013-11-10 vervaldatum: 2014-11-10 gebruik: SC
+ vertrouwen: ultimate geldigheid: ultimate
+ sub 4096R/0x98816CFB398B4666 aangemaakt: 2013-11-10 vervaldatum: 2014-11-10 gebruik: E
+ sub 4096R/0x91951718D5F11CDD aangemaakt: 2013-11-10 vervaldatum: 2014-11-10 gebruik: S
+ sub 4096R/0xABE8244505D63E81 aangemaakt: 2013-11-10 vervaldatum: 2014-11-10 gebruik: E
+ sub 4096R/0xB44520A46B27144D aangemaakt: 2013-11-10 vervaldatum: 2014-11-10 gebruik: S
+ sub 4096R/0xFF8DE378DE223820 aangemaakt: 2013-11-10 vervaldatum: 2014-11-10 gebruik: E
+
+> This was already fixed in version 4.20131106. [[done]] --[[Joey]]
diff --git a/doc/bugs/git-annex-shell:_gcryptsetup_permission_denied.mdwn b/doc/bugs/git-annex-shell:_gcryptsetup_permission_denied.mdwn
new file mode 100644
index 000000000..260ab9981
--- /dev/null
+++ b/doc/bugs/git-annex-shell:_gcryptsetup_permission_denied.mdwn
@@ -0,0 +1,48 @@
+### Please describe the problem.
+I followed the tip on [fully encrypted git repositories with gcrypt](http://git-annex.branchable.com/tips/fully_encrypted_git_repositories_with_gcrypt/) to create encrypted git-annex repository on a ssh server. When I try to checkout the repository, things break as follows:
+
+`git clone gcrypt::ssh://my.server/home/me/encryptedrepo myrepo`
+
+works as expected but when in the myrepo directory,
+
+`git annex enableremote encryptedrepo gitrepo=ssh://my.server/home/me/encryptedrepo`
+
+issues the following text (among normal messages):
+
+`git-annex-shell: gcryptsetup permission denied`
+
+Then while the links are there,
+
+`git annex get --from encryptedrepo`
+
+does nothing (in the sense that the content is not retrieved).
+
+This seems to have everything to do with git-annex-shell as the exact same manipulations but with a local repository work perfectly. Unfortunately, I don't know haskell so [this code](https://github.com/joeyh/git-annex/blob/master/Command/GCryptSetup.hs) is cryptic to me. I can guess there is a problem getting the uuid of the repository, but as far as I can tell the bare distant repo looks fine.
+
+### What steps will reproduce the problem?
+
+Create a standard git annex local repository and then follow the [fully encrypted git repositories with gcrypt tip](http://git-annex.branchable.com/tips/fully_encrypted_git_repositories_with_gcrypt/) to create an encrypted git-annex repository on a ssh server. Then follow the instructions in the same tip to clone the remote repository.
+
+### What version of git-annex are you using? On what operating system?
+Both computers run ubuntu 12.04 with all updates and the latest git annex from the ppa, that is:
+
+git-annex version: 4.20131024
+
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP Feeds Quvi TDFA
+
+key/value backends: SHA256E SHA1E SHA512E SHA224E SHA384E SHA256 SHA1 SHA512 SHA224 SHA384 WORM URL
+
+remote types: git gcrypt S3 bup directory rsync web webdav glacier hook
+
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/git-annex-shell:_gcryptsetup_permission_denied/comment_1_f4584158b35b80ece1060308883e2dc4._comment b/doc/bugs/git-annex-shell:_gcryptsetup_permission_denied/comment_1_f4584158b35b80ece1060308883e2dc4._comment
new file mode 100644
index 000000000..6312a58a5
--- /dev/null
+++ b/doc/bugs/git-annex-shell:_gcryptsetup_permission_denied/comment_1_f4584158b35b80ece1060308883e2dc4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 1"
+ date="2013-11-02T19:46:28Z"
+ content="""
+It seems to me that the `git-annex-shell` on the remote system must be too old a version to support the gcryptsetup command. You can check this by running `git-annex-shell` there and seeing if it lists gcryptsetup in its usage message.
+"""]]
diff --git a/doc/bugs/git-annex-shell:_gcryptsetup_permission_denied/comment_2_a4d7aae848340771a9b8e2c87abeea42._comment b/doc/bugs/git-annex-shell:_gcryptsetup_permission_denied/comment_2_a4d7aae848340771a9b8e2c87abeea42._comment
new file mode 100644
index 000000000..f2fb4f14f
--- /dev/null
+++ b/doc/bugs/git-annex-shell:_gcryptsetup_permission_denied/comment_2_a4d7aae848340771a9b8e2c87abeea42._comment
@@ -0,0 +1,26 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkbpbjP5j8MqWt_K4NASwv0WvB8T4rQ-pM"
+ nickname="Fabrice"
+ subject="comment 2"
+ date="2013-11-02T21:53:37Z"
+ content="""
+The git-annex version on the remote server is the same as the one on the client, the latest one available from the ppa (4.20131024). When I run git-annex-shell on both computers, I obtain:
+[[!format sh \"\"\"
+git-annex-shell: bad parameters
+
+Usage: git-annex-shell [-c] command [parameters ...] [option ...]
+
+Plumbing commands:
+
+commit DIRECTORY commits any staged changes to the git-annex branch
+configlist DIRECTORY outputs relevant git configuration
+dropkey DIRECTORY KEY ... drops annexed content for specified keys
+gcryptsetup DIRECTORY VALUE sets up gcrypt repository
+inannex DIRECTORY KEY ... checks if keys are present in the annex
+recvkey DIRECTORY KEY runs rsync in server mode to receive content
+sendkey DIRECTORY KEY runs rsync in server mode to send content
+transferinfo DIRECTORY KEY updates sender on number of bytes of content received
+\"\"\"]]
+
+Both sides seem to understand the gcryptsetup action. Actually, the message gcryptsetup permission denied comes from git-annex-shell, as far as I understand (and from the haskell source linked in the report).
+"""]]
diff --git a/doc/bugs/git-annex-shell:_gcryptsetup_permission_denied/comment_3_06bda101ad584b4b882de8b2e202d679._comment b/doc/bugs/git-annex-shell:_gcryptsetup_permission_denied/comment_3_06bda101ad584b4b882de8b2e202d679._comment
new file mode 100644
index 000000000..863f401ce
--- /dev/null
+++ b/doc/bugs/git-annex-shell:_gcryptsetup_permission_denied/comment_3_06bda101ad584b4b882de8b2e202d679._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 3"
+ date="2013-11-02T23:51:13Z"
+ content="""
+I should have looked at that error message more closely. The gcryptsetup command will print a permission denied if the repository it's being run in already has a annex.uuid or already has a gcrypt id. Probably that latter needs to be relaxed for enableremote to work.
+"""]]
diff --git a/doc/bugs/git-annex-shell:_gcryptsetup_permission_denied/comment_4_4fc6b25401b645cabc04b510bdfa6863._comment b/doc/bugs/git-annex-shell:_gcryptsetup_permission_denied/comment_4_4fc6b25401b645cabc04b510bdfa6863._comment
new file mode 100644
index 000000000..e1049ce60
--- /dev/null
+++ b/doc/bugs/git-annex-shell:_gcryptsetup_permission_denied/comment_4_4fc6b25401b645cabc04b510bdfa6863._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 4"
+ date="2013-11-03T00:15:30Z"
+ content="""
+While I've fixed this bug, in my testing the bug only caused git-annex to fall back to accessing the remote repository using rsync, rather than using git-annex-shell to talk to it, and so `git annex get --from encryptedrepo` was able to retrieve files that were stored in that remote despite the bug. That may have failed for you for some other reason.
+
+You can set git.encryptedrepo.annex-gcrypt to to \"true\" to make it use the degraded rsync mode, or to \"shell\" to make it use git-annex-shell. Setting it to shell should be all that you need to do to recover from (or indeed, work around this bug).
+"""]]
diff --git a/doc/bugs/git-annex-shell:_gcryptsetup_permission_denied/comment_5_4e193306801680bba433e75eb4dcba05._comment b/doc/bugs/git-annex-shell:_gcryptsetup_permission_denied/comment_5_4e193306801680bba433e75eb4dcba05._comment
new file mode 100644
index 000000000..137638aa5
--- /dev/null
+++ b/doc/bugs/git-annex-shell:_gcryptsetup_permission_denied/comment_5_4e193306801680bba433e75eb4dcba05._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkbpbjP5j8MqWt_K4NASwv0WvB8T4rQ-pM"
+ nickname="Fabrice"
+ subject="comment 5"
+ date="2013-11-03T11:24:28Z"
+ content="""
+There is something very strange that I did not notice in my first report. When I try `git annex get --from encryptedrepo` nothing happens in the sense that git annex is not even trying to connect to the remote (no ssh connection attempt) while git.encryptedrepo.annex-gcrypt is set to true. When I set it to shell, nothing happens either.
+
+Another thing I did not report is that I tried the exact same manipulations with another server on which git annex is not installed. The `gcryptsetup permission denied` message was replaced by a `git-annex-shell not found` (or something similar), as expected. But the rest of the behavior was the same: no way to get the actual content with `git annex get --from`. Again, all of this is with 4.20131024, not with the ongoing version.
+
+I'll try got do more test with the new version.
+"""]]
diff --git a/doc/bugs/git-annex-shell:_gcryptsetup_permission_denied/comment_6_76ccdf0542e76e4dbd61f3b3228d40ba._comment b/doc/bugs/git-annex-shell:_gcryptsetup_permission_denied/comment_6_76ccdf0542e76e4dbd61f3b3228d40ba._comment
new file mode 100644
index 000000000..0ad9768f6
--- /dev/null
+++ b/doc/bugs/git-annex-shell:_gcryptsetup_permission_denied/comment_6_76ccdf0542e76e4dbd61f3b3228d40ba._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 6"
+ date="2013-11-04T17:12:05Z"
+ content="""
+It's entirely normal for `git annex get --from remote` to skip files that it does not think are present on the remote.
+
+What does `git annex whereis` say?
+"""]]
diff --git a/doc/bugs/git-annex-shell:_gcryptsetup_permission_denied/comment_7_cd964d0a375c5cba299bf2bbbbb86acb._comment b/doc/bugs/git-annex-shell:_gcryptsetup_permission_denied/comment_7_cd964d0a375c5cba299bf2bbbbb86acb._comment
new file mode 100644
index 000000000..3a24f4349
--- /dev/null
+++ b/doc/bugs/git-annex-shell:_gcryptsetup_permission_denied/comment_7_cd964d0a375c5cba299bf2bbbbb86acb._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkbpbjP5j8MqWt_K4NASwv0WvB8T4rQ-pM"
+ nickname="Fabrice"
+ subject="comment 7"
+ date="2013-11-04T18:54:54Z"
+ content="""
+`git annex whereis` says the files are not on the remote git, while they are because of the copy. If I do _exactly_ what's on the tip, that is if I clone the encrypted git just after having done `git annex copy --to encryptedbackup`, the remotes seems to ignore that it has the data. To have it working, I had to call `git annex sync` (push will do, I guess) in the original remote after doing the `git annex copy`. Then I can `git pull` and `git annex whereis` knows where the files are (or I can clone the encrypted remote after doing the sync/pull).
+
+It seems a bit strange that the copy command does not record the propagation of the file to the encrypted git. I guess this is because gcrypt is the only special remote that stores also the git part, right? Would that be a good idea (and possible) to handle it in a special way?
+
+Thanks Joey for everything, by the way, both the software and the amazing support via email and the website.
+"""]]
diff --git a/doc/bugs/git-annex-shell:_gcryptsetup_permission_denied/comment_8_9bac87c85deb5bb15795df28533d0cde._comment b/doc/bugs/git-annex-shell:_gcryptsetup_permission_denied/comment_8_9bac87c85deb5bb15795df28533d0cde._comment
new file mode 100644
index 000000000..da2fef585
--- /dev/null
+++ b/doc/bugs/git-annex-shell:_gcryptsetup_permission_denied/comment_8_9bac87c85deb5bb15795df28533d0cde._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 8"
+ date="2013-11-04T19:14:04Z"
+ content="""
+Right -- Normally a special remote doesn't include a git repository. And when using a regular git remote, `git-annex-shell` is used to receive files into the repository and it records immediately that the repo has the file so there's no need to sync in that case. So gcrypt is special in this way.
+
+For now, I have fixed the tip to show syncing after sending files to gcrypt. It might be the case that it would make sense to do a push of the git-annex branch automatically in that case, will have to think about that and see if people get tripped up on this.
+"""]]
diff --git a/doc/bugs/git-annex-shell:_internal_error:_evacuate__40__static__41__:_strange_closure_type_30799.mdwn b/doc/bugs/git-annex-shell:_internal_error:_evacuate__40__static__41__:_strange_closure_type_30799.mdwn
new file mode 100644
index 000000000..f9a61a859
--- /dev/null
+++ b/doc/bugs/git-annex-shell:_internal_error:_evacuate__40__static__41__:_strange_closure_type_30799.mdwn
@@ -0,0 +1,75 @@
+I ran git-annex (git version) on three machines with ghc-7.0.2 for about a month, but recently (no more than a week ago) I've started getting this error for every file on "git annex get":
+
+ git-annex-shell: internal error: evacuate(static): strange closure type 30799
+ (GHC version 7.0.2 for i386_unknown_linux)
+ Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug
+
+There were no changes to ghc or it's modules, so I assume something has changed in git-annex itself.
+
+strace shows "git annnex get" (on "host1") performing following exec's:
+
+ [pid 9481] execve("/usr/bin/rsync", ["rsync", "-p", "--progress", "--inplace", "-e", "'ssh' 'user@host2' 'git-annex-shell ''sendkey'' ''/remote/path'' ''SHA1-s6654080--abd8edec20648ade69351d68ae1c64c8074a6f0b'' ''--'''", ":", "/local/path/.git/annex/tmp/SHA1-s6654080--abd8edec20648ade69351d68ae1c64c8074a6f0b"], [/* 41 vars */]) = 0
+ [pid 9482] execve("/usr/bin/ssh", ["ssh", "user@host2", "git-annex-shell 'sendkey' '/remote/path' 'SHA1-s6654080--abd8edec20648ade69351d68ae1c64c8074a6f0b' '--'", "", "rsync", "--server", "--sender", "-vpe.Lsf", "--inplace", ".", ""], [/* 41 vars */] <unfinished ...>
+
+I've tried running the second command directly from the shell and got the same error message from a remote GHC.
+Adding strace before git-annex-shell to remote command yielded something like this in the end:
+
+ stat64("/local/path.git", 0xb727d610) = -1 ENOENT (No such file or directory)
+ stat64("/local/path.git", 0xb727d6b0) = -1 ENOENT (No such file or directory)
+ waitpid(7525, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0) = 7525
+ chdir("/home/user") = 0
+ rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0
+ write(2, "git-annex-shell: internal error: ", 33git-annex-shell: internal error: ) = 33
+ ...
+
+Note that "/local/path" here is not what's specified in rsync arguments at all, and git repo with files-to-be-fetched on "host2" is in "/remote/path", but "/local/path" is present in git remotes there since I mount it via nfs from "host1" (yes, to the same path as it's there):
+
+ [remote "nfs"]
+ url = /local/path
+ fetch = +refs/heads/*:refs/remotes/nfs/*
+ push = refs/heads/*:refs/remotes/host2/*
+ annex-uuid = 0a4e14ba-5236-11e0-9004-7f24452c0f05
+
+If I comment that remote out from "/remote/path/.git/config", "git annex get" works fine.
+The only git-command git-annex-shell seem to exec there (on "host2") is "git config --list", so it's shouldn't be git trying to do something with it's remotes - it's git-annex itself, right?
+
+Anyways, looks like a simple path-joining error, if "/local/path.git" should be "/local/path/.git" there.
+
+I'm actually quite confused about what it's trying to do with that path.
+Connect from "host1" to "host2" just to connect back to "host1"?
+What for, when it should just fetch files from "host2"?
+
+> git-annex (and git-annex shell) always start up by learning what git
+> remotes are locally configured, and this includes checking them to
+> try to look up their annex.uuid setting.
+>
+> Since git will, given a remote like "url = /foo", first look in
+> "/foo.git" for a bare git repository, so too does git-annex.
+> I do not think this is a path joining error. That seems likely to
+> be a red herring. --[[Joey]]
+
+Not sure if it's a bug or I'm doing something wrong, but if git-annex really need to check something in git remotes' paths, error message (the one at the top of this post) can be a more descriptive, I guess.
+Something like "error: failed to do something with git remote X on a remote host" would've been a lot less confusing than that GHC thing.
+
+Thanks!
+
+> I've never seen anything like this error message. I don't know if the
+> problem is caused by building with GHC 7, or what. You didn't say what
+> OS you're using. Searching for the error message, it seems to involve
+> Mac OS X.
+
+> For example: <http://hackage.haskell.org/trac/ghc/ticket/3771>
+>> The error "strange closure type" indicates some kind of memory corruption, which can have many different causes, from bugs in the GC to hardware failures.
+>
+> You said that you'd been using git-annex built with that version of GHC
+> successfully before. Perhaps you could use `git bisect` to see if you can
+> identify a point in git-annex's history where this started happening?
+> Since you can reproduce the problem by just running git-annex-shell at
+> the command line with the right parameters, it should be easy to bisect it.
+>
+> Probably your best bet will be changing to a different version or build of
+> GHC.. --[[Joey]]
+
+---
+
+forwarded to GHC upstream; closing [[done]] --[[Joey]]
diff --git a/doc/bugs/git-annex-shell:_internal_error:_evacuate__40__static__41__:_strange_closure_type_30799/comment_1_1c19e716069911f17bbebd196d9e4b61._comment b/doc/bugs/git-annex-shell:_internal_error:_evacuate__40__static__41__:_strange_closure_type_30799/comment_1_1c19e716069911f17bbebd196d9e4b61._comment
new file mode 100644
index 000000000..98f0adc3d
--- /dev/null
+++ b/doc/bugs/git-annex-shell:_internal_error:_evacuate__40__static__41__:_strange_closure_type_30799/comment_1_1c19e716069911f17bbebd196d9e4b61._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://fraggod.pip.verisignlabs.com.pip.verisignlabs.com/"
+ subject="Bisect it is, then"
+ date="2011-04-03T04:45:49Z"
+ content="""
+Hm, if path's ok, guess there's no way around git-bisect indeed. Wonder if there's some kind of ccache for haskell...
+
+OS is linux, amd64 on \"host1\" and i386 on \"host2\" where git-annex-shell is crashing.
+I'll try to come up with a commit, thanks for clarifications.
+"""]]
diff --git a/doc/bugs/git-annex-shell:_internal_error:_evacuate__40__static__41__:_strange_closure_type_30799/comment_2_a4d66f29d257044e548313e014ca3dc3._comment b/doc/bugs/git-annex-shell:_internal_error:_evacuate__40__static__41__:_strange_closure_type_30799/comment_2_a4d66f29d257044e548313e014ca3dc3._comment
new file mode 100644
index 000000000..fb3658191
--- /dev/null
+++ b/doc/bugs/git-annex-shell:_internal_error:_evacuate__40__static__41__:_strange_closure_type_30799/comment_2_a4d66f29d257044e548313e014ca3dc3._comment
@@ -0,0 +1,66 @@
+[[!comment format=mdwn
+ username="http://fraggod.pip.verisignlabs.com.pip.verisignlabs.com/"
+ subject="Bisect results"
+ date="2011-04-03T06:22:15Z"
+ content="""
+Completed git-bisect twice, getting roughly the same results:
+
+ 828a84ba3341d4b7a84292d8b9002a8095dd2382 is the first bad commit
+ commit 828a84ba3341d4b7a84292d8b9002a8095dd2382
+ Author: Joey Hess <joey@kitenet.net>
+ Date: Sat Mar 19 14:33:24 2011 -0400
+
+ Add version command to show git-annex version as well as repository version information.
+
+ :040000 040000 ed849b7b6e9b177d6887ecebd6a0f146357824f3 1c98699dfd3fc3a3e2ce6b55150c4ef917de96e9 M Command
+ :100644 100644 b9c22bdfb403b0bdb1999411ccfd34e934f45f5c adf07e5b3e6260b296c982a01a73116b8a9a023c M GitAnnex.hs
+ :100644 100644 76dd156f83f3d757e1c20c80d689d24d0c533e16 d201cc73edb31f833b6d00edcbe4cf3f48eaecb0 M Upgrade.hs
+ :100644 100644 5f414e93b84589473af5b093381694090c278e50 d4a58d77a29a6a02daf13cec0df08b5aab74f65e M Version.hs
+ :100644 100644 f5c2956488a7afafd20374873d79579fb09b1677 f8cd577e992d38c7ec1438ce5c141eb0eb410243 M configure.hs
+ :040000 040000 f9b7295e997c0a5b1dda352f151417564458bd6e a30008475c1889f4fd8d60d4d9c982563380a692 M debian
+ :040000 040000 9d87a5d8b9b9fe7b722df303252ffd5760d66f75 08834f61a10d36651b3cdcc38389f45991acdf5e M doc
+
+contents of final refs/bisect:
+
+ bad (828a84ba3341d4b7a84292d8b9002a8095dd2382)
+ good-33cb114be5135ce02671d8ce80440d40e97ca824
+ good-942480c47f69e13cf053b8f50c98c2ce4eaa256e
+ good-ca48255495e1b8ef4bda5f7f019c482d2a59b431
+
+\"roughly\" because second bisect gave two commits as a result, failing to build one of them (missing .o file on link, guess it's because of -j4 and bad deps in that version's build system):
+
+ There are only 'skip'ped commits left to test.
+ The first bad commit could be any of:
+ 828a84ba3341d4b7a84292d8b9002a8095dd2382
+ 5022a69e45a073046a2b14b6a4e798910c920ee9
+ We cannot bisect more!
+
+Also noticed that \"git-annex-shell ...\" command succeeds if ran as root user, while failing from unprivileged one.
+There are no permission/access errors in \"strace -f git-annex-shell ...\", so I guess it could be some bug in the GHC indeed.
+
+JIC, logged a whole second bisect operation.
+Resulting log: [http://fraggod.net/static/share/git-annex-bisect.log](http://fraggod.net/static/share/git-annex-bisect.log)
+
+Bisect script I've used (git-annex-shell dies with error code 134 - SIGABRT on GHC error):
+
+ res=
+ while true; do
+ if [[ -n \"$res\" ]]; then
+ cd /var/tmp/paludis/build/dev-scm-git-annex-scm.bak/work/git-annex-scm
+ echo \"---=== BISECT ($res) ===---\"; git bisect \"$res\" 2>&1; echo '---=== /BISECT ===---'
+ cd
+ rm -Rf /var/tmp/paludis/build/dev-scm-git-annex-scm
+ cp -a --reflink=auto /var/tmp/paludis/build/dev-scm-git-annex-scm{.bak,}
+ chown -R paludisbuild: /var/tmp/paludis/build/dev-scm-git-annex-scm
+ fi
+ res=
+ cave resolve -zx1 git-annex --skip-until-phase configure || res=skip
+ if [[ -z \"$res\" ]]; then
+ cd /remote/path
+ sudo -u user git-annex-shell 'sendkey' '/remote/path' 'SHA1-s6654080--abd8edec20648ade69351d68ae1c64c8074a6f0b' '--' rsync --server --sender -vpe.Lsf --inplace . ''
+ if [[ $? -eq 134 ]]; then res=bad; else res=good; fi
+ cd
+ fi
+ done 2>&1 | tee ~/git-annex-bisect.log
+
+"""]]
diff --git a/doc/bugs/git-annex-shell:_internal_error:_evacuate__40__static__41__:_strange_closure_type_30799/comment_3_f5f1081eb18143383b2fb1f57d8640f5._comment b/doc/bugs/git-annex-shell:_internal_error:_evacuate__40__static__41__:_strange_closure_type_30799/comment_3_f5f1081eb18143383b2fb1f57d8640f5._comment
new file mode 100644
index 000000000..491b53786
--- /dev/null
+++ b/doc/bugs/git-annex-shell:_internal_error:_evacuate__40__static__41__:_strange_closure_type_30799/comment_3_f5f1081eb18143383b2fb1f57d8640f5._comment
@@ -0,0 +1,38 @@
+[[!comment format=mdwn
+ username="http://fraggod.pip.verisignlabs.com.pip.verisignlabs.com/"
+ subject="comment 3"
+ date="2011-04-03T06:57:02Z"
+ content="""
+Repeated bisect with -j1, just to be sure it's not a random error, and it gave me 828a84ba3341d4b7a84292d8b9002a8095dd2382 again.
+Guess I'll look through the changes there a bit later and try to revert these until it works.
+
+Not sure if it's repeatable by anyone but me (and hence worth fixing), but here's a bit more of info about the system:
+
+ Exherbo linux
+ Linux sacrilege 2.6.38.2-fg.roam #4 SMP PREEMPT Mon Mar 28 21:08:47 YEKST 2011 i686 GNU/Linux
+
+ dev-lang/ghc-7.0.2:7.0.2::installed
+ dev-haskell/HUnit-1.2.2.3:1.2.2.3::installed
+ dev-haskell/MissingH-1.1.0.3:1.1.0.3::installed
+ dev-haskell/QuickCheck-2.4.0.1:2.4.0.1::installed
+ dev-haskell/array-0.3.0.2:0.3.0.2::installed
+ dev-haskell/bytestring-0.9.1.7:0.9.1.7::installed
+ dev-haskell/containers-0.4.0.0:0.4.0.0::installed
+ dev-haskell/extensible-exceptions-0.1.1.2:0.1.1.2::installed
+ dev-haskell/filepath-1.2.0.0:1.2.0.0::installed
+ dev-haskell/hslogger-1.1.3:0::installed
+ dev-haskell/mtl-2.0.1.0:2.0.1.0::installed
+ dev-haskell/network-2.3.0.1:2.3.0.1::installed
+ dev-haskell/old-locale-1.0.0.2:1.0.0.2::installed
+ dev-haskell/parsec-3.1.0:3.1.0::installed
+ dev-haskell/pcre-light-0.4:0::installed
+ dev-haskell/regex-base-0.93.2:0.93.2::installed
+ dev-haskell/regex-compat-0.93.1:0.93.1::installed
+ dev-haskell/regex-posix-0.94.4:0.94.4::installed
+ dev-haskell/syb-0.3:0.3::installed
+ dev-haskell/transformers-0.2.2.0:0.2.2.0::installed
+ dev-haskell/utf8-string-0.3.6:0.3.6::installed
+
+(some stuff listed here as ::installed, but contains no files, since these packages detect whether ghc-7.0.2 already comes with the same/newer package version)
+
+"""]]
diff --git a/doc/bugs/git-annex-shell:_internal_error:_evacuate__40__static__41__:_strange_closure_type_30799/comment_4_b1f818b85c3540591c48e7ba8560d070._comment b/doc/bugs/git-annex-shell:_internal_error:_evacuate__40__static__41__:_strange_closure_type_30799/comment_4_b1f818b85c3540591c48e7ba8560d070._comment
new file mode 100644
index 000000000..45d3d8bac
--- /dev/null
+++ b/doc/bugs/git-annex-shell:_internal_error:_evacuate__40__static__41__:_strange_closure_type_30799/comment_4_b1f818b85c3540591c48e7ba8560d070._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 4"
+ date="2011-04-03T16:06:34Z"
+ content="""
+Nice work on the bisection. It's obviously a compiler bug. Having two test cases that differ in only as trivial and innocous a commit as 828a84ba3341d4b7a84292d8b9002a8095dd2382 might help a GHC developer track it down.
+
+We should probably forward this as a GHC bug. I hope you can find a different version or build of GHC to build git-annex with.
+"""]]
diff --git a/doc/bugs/git-annex-shell:_internal_error:_evacuate__40__static__41__:_strange_closure_type_30799/comment_5_67406dd8d9bd4944202353508468c907._comment b/doc/bugs/git-annex-shell:_internal_error:_evacuate__40__static__41__:_strange_closure_type_30799/comment_5_67406dd8d9bd4944202353508468c907._comment
new file mode 100644
index 000000000..bffa9bb86
--- /dev/null
+++ b/doc/bugs/git-annex-shell:_internal_error:_evacuate__40__static__41__:_strange_closure_type_30799/comment_5_67406dd8d9bd4944202353508468c907._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://fraggod.pip.verisignlabs.com.pip.verisignlabs.com/"
+ subject="Reported the issue to GHC"
+ date="2011-04-07T13:44:36Z"
+ content="""
+Finally got around to [report the issue to GHC tracker](http://hackage.haskell.org/trac/ghc/ticket/5085#comment:7).
+
+Looks quite alike (at least to the haskell-illiterate person like me) to a highest-priority issue that's hanging right at the top of the list.
+There are other similar reports, but they seem to be either related to PowerPC Macs, closed as invalid or due to needinfo inactivity.
+
+Guess any further discussion belongs there, unless ghc developers will bounce it back.
+Thanks a lot for your help, Joey, and for sharing a great thing that git-annex is.
+"""]]
diff --git a/doc/bugs/git-annex-shell:_user_error___40__unrecognized_option___96__--uuid__39__.mdwn b/doc/bugs/git-annex-shell:_user_error___40__unrecognized_option___96__--uuid__39__.mdwn
new file mode 100644
index 000000000..174e8082a
--- /dev/null
+++ b/doc/bugs/git-annex-shell:_user_error___40__unrecognized_option___96__--uuid__39__.mdwn
@@ -0,0 +1,53 @@
+What steps will reproduce the problem?
+On Arch Linux, using a cabal installation or prebuilt binaries:
+
+ git-annex get foobar
+
+The remote is an ssh URL: ssh://user@host/path/to/repo.git. Fetching the URL worked just fine.
+
+
+What is the expected output? What do you see instead?
+I expect git-annex to retrieve the file from the remote.
+Insted I see this:
+
+ get foobar (from origin...)
+ git-annex-shell: user error (unrecognized option `--uuid'
+
+ Usage: git-annex-shell [-c] command [parameters ...] [option ..]
+
+ Options:
+ --force allow actions that may lose annexed data
+ -F --fast avoid slow operations
+ -q --quiet avoid verbose output
+ -v --verbose allow verbose output (default)
+ -d --debug show debug messages
+ -b NAME --backend=NAME specify key-value backend to use
+
+ Commands:
+ configlist DIRECTORY outputs relevant git configuration
+ inannex DIRECTORY KEY ... checks if keys are present in the annex
+ dropkey DIRECTORY KEY ... drops annexed content for specified keys
+ recvkey DIRECTORY KEY runs rsync in server mode to receive content
+ sendkey DIRECTORY KEY runs rsync in server mode to send content
+ )
+ rsync: connection unexpectedly closed (0 bytes received so far) [Receiver]
+ rsync error: error in rsync protocol data stream (code 12) at io.c(605) [Receiver=3.0.9]
+
+ Unable to access these remotes: origin
+
+ Try making some of these repositories available:
+ 5afcfc68-aa55-11e2-b5aa-73eac1531269 -- origin (my_remote)
+ failed
+ git-annex: get: 1 failed
+
+
+What version of git-annex are you using? On what operating system?
+git-annex does not understand a '--version' switch and I cannot find another option to print the version. It's the latest I just installed via cabal.
+OS is Arch Linux on kernel 3.8.8
+
+> This happens if the remote server has a very old version of
+> git-annex-shell. While I would not, today, add a new option like
+> --uuid that breaks backwards compatability as happened here,
+> I don't intend to try to make git-annex backwards compatible
+> with that old version. Not even Debian stable has such an old version of
+> git-annex anymore, so there's no excuse not to upgrade. [[done]]
diff --git a/doc/bugs/git-annex-shell:_user_error___40__unrecognized_option___96__--uuid__39__/comment_1_13510e954e36484e196e7395a3a9bf1f._comment b/doc/bugs/git-annex-shell:_user_error___40__unrecognized_option___96__--uuid__39__/comment_1_13510e954e36484e196e7395a3a9bf1f._comment
new file mode 100644
index 000000000..639e364d8
--- /dev/null
+++ b/doc/bugs/git-annex-shell:_user_error___40__unrecognized_option___96__--uuid__39__/comment_1_13510e954e36484e196e7395a3a9bf1f._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-04-23T17:57:10Z"
+ content="""
+`git annex version` is how you tell git-annex to print its version.
+
+The problem is not with the locally installed version of git-annex. You have a *very* old version of git-annex-shell installed on the server you're using as a remote. The last version of git-annex that did not support `git-annex-shell --uuid` was 3.20110928. You need to upgrade it to make it work with modern git-annex.
+"""]]
diff --git a/doc/bugs/git-annex-shell:_user_error___40__unrecognized_option___96__--uuid__39__/comment_2_7edc478a76983a3b3c68d01f24dce613._comment b/doc/bugs/git-annex-shell:_user_error___40__unrecognized_option___96__--uuid__39__/comment_2_7edc478a76983a3b3c68d01f24dce613._comment
new file mode 100644
index 000000000..86faca325
--- /dev/null
+++ b/doc/bugs/git-annex-shell:_user_error___40__unrecognized_option___96__--uuid__39__/comment_2_7edc478a76983a3b3c68d01f24dce613._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn8nmg2ti0tVOD215PNBmLKvf2S4kXkQAY"
+ nickname="Sören"
+ subject="comment 2"
+ date="2013-04-24T05:39:09Z"
+ content="""
+Thanks, for the response. You're correct.
+I finally have it working. But it's not really easy, dealing with Arch Linux and Ubuntu 11.10 and make them talk to each other.
+"""]]
diff --git a/doc/bugs/git-annex-shell_doesn__39__t_honour_Rsync__39__s_bwlimit_option.mdwn b/doc/bugs/git-annex-shell_doesn__39__t_honour_Rsync__39__s_bwlimit_option.mdwn
new file mode 100644
index 000000000..8d4a7c512
--- /dev/null
+++ b/doc/bugs/git-annex-shell_doesn__39__t_honour_Rsync__39__s_bwlimit_option.mdwn
@@ -0,0 +1,37 @@
+<h4>What steps will reproduce the problem?</h4>
+
+On <tt>host1.example.tld</tt>:
+<pre><code> git init /tmp/annex
+ cd /tmp/annex
+ git annex init
+ git config annex.rsync-options '--bwlimit=100'
+ dd if=/dev/urandom of=bigfile bs=1024 count=102400
+ git annex add bigfile
+ git commit -am bigfile
+</code></pre>
+
+On <tt>host2.example.tld</tt>:
+<pre><code> git clone ssh://host1.example.tld/tmp/annex /tmp/annex
+ cd /tmp/annex
+ git annex init
+ git config annex.rsync-options '--bwlimit=100'
+ git annex get --from=origin bigfile
+</code></pre>
+
+<h4>What is the expected output? What do you see instead?</h4>
+<tt>bigfile</tt> is retrieved full speed, despite the <tt>bwlimit</tt> option. In fact on the origin <tt>host1.example.tld</tt>, <tt>ps x | grep rsync</tt> shows:
+<pre><code>
+ 21386 ? Ssl 0:00 git-annex-shell sendkey /tmp/annex SHA256E-s104857600--3e87b769b88db67c56f8c8a0245203a1c22cdb027f0a1230dac8309b1a9fded0 --uuid 7002cb3d-2205-4
+f8d-892b-5c35c693d76c -- remoteuuid=67263f47-7a5f-4a75-937b-7cffafa85f56 direct= associatedfile=bigfile -- dummy rsync --server --sender -ve.Lsf --bwlimit=100 --inplace .
+ 21390 ? S 0:01 rsync --server -t --inplace -e.Lsf . --sender /tmp/annex/.git/annex/objects/jX/3W/SHA256E-s104857600--3e87b769b88db67c56f8c8a0245203a1c22cdb02
+7f0a1230dac8309b1a9fded0/SHA256E-s104857600--3e87b769b88db67c56f8c8a0245203a1c22cdb027f0a1230dac8309b1a9fded0
+</code></pre>
+
+On the first line the option is indeed there, but it's somehow not forwarded to the actual rsync command. (On the client <tt>host2.example.tld</tt> the option shows up, but the sender's bandwidth seems to take precedence.)
+
+<h4>What version of git-annex are you using? On what operating system?</h4>
+
+git-annex 4.20130227, on Debian GNU/Linux (sid, i386).
+
+> [[done]], --bwlimit is now passed through from the caller.
+> Thanks, guilhem
diff --git a/doc/bugs/git-annex-shell_doesn__39__t_honour_Rsync__39__s_bwlimit_option/comment_1_8cda861c11ef2fff3442e5a0df741939._comment b/doc/bugs/git-annex-shell_doesn__39__t_honour_Rsync__39__s_bwlimit_option/comment_1_8cda861c11ef2fff3442e5a0df741939._comment
new file mode 100644
index 000000000..8c82c7e36
--- /dev/null
+++ b/doc/bugs/git-annex-shell_doesn__39__t_honour_Rsync__39__s_bwlimit_option/comment_1_8cda861c11ef2fff3442e5a0df741939._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-03-09T06:13:17Z"
+ content="""
+git-annex-shell cannot pass arbitrary rsync parameters through as specified by the client, because this would be a security hole (eg, allows overwriting or exposing arbitrary files). I'd have to pick out and whitelist safe parameters to make that work.
+
+I'm also not sure if rsync --server does anything with --bwlimit, it's more of a client side option. When rsync is connecting to a rsync:// server, it can't tell the server to run with --bwlimit, AFAIK.
+
+Also, the bwlimit option works by stalling the connection occasionally, it's hardly very good and you'll sometime see it ramp back to full speed in between stalls.
+"""]]
diff --git a/doc/bugs/git-annex-shell_doesn__39__t_honour_Rsync__39__s_bwlimit_option/comment_2_15e06f6db9a14a8217dea25e24ddc23a._comment b/doc/bugs/git-annex-shell_doesn__39__t_honour_Rsync__39__s_bwlimit_option/comment_2_15e06f6db9a14a8217dea25e24ddc23a._comment
new file mode 100644
index 000000000..8c41b51f0
--- /dev/null
+++ b/doc/bugs/git-annex-shell_doesn__39__t_honour_Rsync__39__s_bwlimit_option/comment_2_15e06f6db9a14a8217dea25e24ddc23a._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="guilhem"
+ ip="46.239.117.180"
+ subject="comment 2"
+ date="2013-03-10T03:06:55Z"
+ content="""
+From my tests, Rsync actually seems to honor the bandwidth limit that's in the sender's options. In particular, a dirty hard-coding of the limit in <tt>Utility.Rsync.rsyncServerParams</tt> (forwarding the option from <tt>git-annex-shell</tt> to the actuall rsync command, and) did the trick for me.
+
+I know Rsync merely tries to respect <tt>bwlimit</tt> on average, but for large files it's good enough I think. And for those like me who have a volume quota on their connection, it'd a plus to make <tt>git-annex-shell</tt> respect that limit. Well of course I could ask my users to use something like <tt>trickle</tt>, but external commands are more likely to be forgotten than a config option ;-)
+
+I couldn't see where in the code you whitelist the list of safe commands; Did you mean there is already such a thing, or is it empty right now? In any case, my wish doesn't seem to be hard to implement, and I'd be happy to try to provide a patch in the next few days.
+"""]]
diff --git a/doc/bugs/git-annex-shell_doesn__39__t_honour_Rsync__39__s_bwlimit_option/comment_3_d36045e2b466882108c5bf09580755fa._comment b/doc/bugs/git-annex-shell_doesn__39__t_honour_Rsync__39__s_bwlimit_option/comment_3_d36045e2b466882108c5bf09580755fa._comment
new file mode 100644
index 000000000..2b39d4bfa
--- /dev/null
+++ b/doc/bugs/git-annex-shell_doesn__39__t_honour_Rsync__39__s_bwlimit_option/comment_3_d36045e2b466882108c5bf09580755fa._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-03-10T16:58:44Z"
+ content="""
+There is not yet a white list, no. Patch would be appreciated.
+"""]]
diff --git a/doc/bugs/git-annex:_Argument_list_too_long.mdwn b/doc/bugs/git-annex:_Argument_list_too_long.mdwn
new file mode 100644
index 000000000..f12d5da65
--- /dev/null
+++ b/doc/bugs/git-annex:_Argument_list_too_long.mdwn
@@ -0,0 +1,40 @@
+### Please describe the problem.
+
+Creating a SSH remote git-annex repository using the assisstant gives transcript:
+
+Initialized empty shared Git repository in /home/flindner/annex2/
+exec: 76: git-annex: Argument list too long
+
+### What steps will reproduce the problem?
+
+Using assistent: Creating a new empty local repository. Next, add another remote server repository using SSH. Checking the server went fine. I choose creating git repository. After about 5 minutes the error message above appears. In that time on the server runshell and git take plenty of CPU power but almost no memory. The directory on the server is created, but pairing was not successfull.
+
+### What version of git-annex are you using? On what operating system?
+
+Local: git-annex-standalone 4.20130909-1 from Archlinux AUR
+Remote: git-annex-standalone-i386.tar.gz as of 13. sept. 13. on Debian Squeeze.
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+daemon.log is empty.
+
+Log from the web GUI:
+
+[2013-09-13 12:34:11 CEST] main: starting assistant version 4.20130827-g4f18612
+
+ No known network monitor available through dbus; falling back to polling
+(scanning...) [2013-09-13 12:34:11 CEST] Watcher: Performing startup scan
+(started...)
+
+
+# End of transcript or log.
+"""]]
+
+> [[done]]; I have added a guard to runshell to detect when it has
+> started to loop. Although I don't understand how a system could be
+> misconfigured to let that happen, without going far out of your way to
+> mess it up, it's a failure mode that's worth guarding against. --[[Joey]]
diff --git a/doc/bugs/git-annex:_Argument_list_too_long/comment_1_3f83ea525436b2379ab29a0f860c4669._comment b/doc/bugs/git-annex:_Argument_list_too_long/comment_1_3f83ea525436b2379ab29a0f860c4669._comment
new file mode 100644
index 000000000..43f4aa98b
--- /dev/null
+++ b/doc/bugs/git-annex:_Argument_list_too_long/comment_1_3f83ea525436b2379ab29a0f860c4669._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.2.134"
+ subject="comment 1"
+ date="2013-09-13T15:31:35Z"
+ content="""
+Can you add set -x near the top of the server's runshell script and run this again also with debugging enabled in the local assistant, and post the log, please.
+"""]]
diff --git a/doc/bugs/git-annex:_Argument_list_too_long/comment_2_b417c94169378ef7d0d278ebae517fa1._comment b/doc/bugs/git-annex:_Argument_list_too_long/comment_2_b417c94169378ef7d0d278ebae517fa1._comment
new file mode 100644
index 000000000..cd90d9c3b
--- /dev/null
+++ b/doc/bugs/git-annex:_Argument_list_too_long/comment_2_b417c94169378ef7d0d278ebae517fa1._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnsuhFUIfWNT-Q-C02FDaSQqceFDge5M9w"
+ nickname="Florian"
+ subject="comment 2"
+ date="2013-09-14T08:49:23Z"
+ content="""
+Is there any way to get the transcript from a log file, not from the web page? The output is so enormous that it crashed my browser out of memory (which is 16 GiB) when I tried to paste it. daemon.log contains no interesting output.
+"""]]
diff --git a/doc/bugs/git-annex:_Argument_list_too_long/comment_3_fa925cca216cb810ad80482b19fc6053._comment b/doc/bugs/git-annex:_Argument_list_too_long/comment_3_fa925cca216cb810ad80482b19fc6053._comment
new file mode 100644
index 000000000..e182ca2c3
--- /dev/null
+++ b/doc/bugs/git-annex:_Argument_list_too_long/comment_3_fa925cca216cb810ad80482b19fc6053._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnsuhFUIfWNT-Q-C02FDaSQqceFDge5M9w"
+ nickname="Florian"
+ subject="comment 3"
+ date="2013-09-15T23:08:48Z"
+ content="""
+Ok, I managed to get the transcript. It is located at <http://xgm.de/upload/transcript.log> (partly) resp. <http://xgm.de/upload/transcript.log.gz> (complete). Looks like the same script is executed again and again with an ever growing LD_LIBRARY_PATH argument list. The same happens when I simply run \"git-annex\" on the shell of the server. \"runshell\" standalone works fine.
+"""]]
diff --git a/doc/bugs/git-annex:_Argument_list_too_long/comment_4_8bd2996107b2d272c32810658e07e715._comment b/doc/bugs/git-annex:_Argument_list_too_long/comment_4_8bd2996107b2d272c32810658e07e715._comment
new file mode 100644
index 000000000..033e695f5
--- /dev/null
+++ b/doc/bugs/git-annex:_Argument_list_too_long/comment_4_8bd2996107b2d272c32810658e07e715._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnsuhFUIfWNT-Q-C02FDaSQqceFDge5M9w"
+ nickname="Florian"
+ subject="comment 4"
+ date="2013-09-15T23:10:38Z"
+ content="""
+Addendum: git inside runshells works, git-annex not.
+"""]]
diff --git a/doc/bugs/git-annex:_Argument_list_too_long/comment_5_378de7d7503a64611eab62f2f5cffef3._comment b/doc/bugs/git-annex:_Argument_list_too_long/comment_5_378de7d7503a64611eab62f2f5cffef3._comment
new file mode 100644
index 000000000..b10c66c81
--- /dev/null
+++ b/doc/bugs/git-annex:_Argument_list_too_long/comment_5_378de7d7503a64611eab62f2f5cffef3._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnsuhFUIfWNT-Q-C02FDaSQqceFDge5M9w"
+ nickname="Florian"
+ subject="comment 5"
+ date="2013-09-16T09:00:34Z"
+ content="""
+Ok, bug can be closed, it was never a bug (at least not in git-annex). I was using the i386 build on a x86_64 machine.
+
+Server is virtual machine from Strato.
+
+$ uname -a
+Linux h1774498.stratoserver.net 2.6.32-042stab078.27 #1 SMP Mon Jul 1 20:48:07 MSK 2013 i686 GNU/Linux
+
+Since there was no x86_64 in the uname output, I thought it was a i386 machine. The git-annex binaries gave a \"File not found\" error message, the git binaries worked. Nothing I connected to a wrong architecture... Sorry for the hassle!
+"""]]
diff --git a/doc/bugs/git-annex:_Argument_list_too_long/comment_6_a94e17151348d02999442dd1219babfb._comment b/doc/bugs/git-annex:_Argument_list_too_long/comment_6_a94e17151348d02999442dd1219babfb._comment
new file mode 100644
index 000000000..a788f2c8e
--- /dev/null
+++ b/doc/bugs/git-annex:_Argument_list_too_long/comment_6_a94e17151348d02999442dd1219babfb._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.14.105"
+ subject="comment 6"
+ date="2013-09-19T17:31:46Z"
+ content="""
+I have tried to reproduce this bug, running the amd64 build on i386, and cannot. When I run the git-annex shell script included in the standalone bundle, it runs runshell, which in turn tries to run bin/git-annex. Since the architecture is wrong, that fails.
+
+I suppose your shell could instead, if presented with a binary of the wrong architecture, skip it and keep searching PATH for another one. That would be a most odd behavior, but if that were the case and you put the git-annex script into PATH, it would lead to what you describe.
+"""]]
diff --git a/doc/bugs/git-annex:_Cannot_decode_byte___39____92__xfc__39__.mdwn b/doc/bugs/git-annex:_Cannot_decode_byte___39____92__xfc__39__.mdwn
new file mode 100644
index 000000000..862259422
--- /dev/null
+++ b/doc/bugs/git-annex:_Cannot_decode_byte___39____92__xfc__39__.mdwn
@@ -0,0 +1,34 @@
+What steps will reproduce the problem?
+
+ alip@hayalet /tmp/aaa (git)-[master] % git annex init aaa
+ init aaa ok
+ (Recording state in git...)
+ alip@hayalet /tmp/aaa (git)-[master] % git remote add çüş /tmp/çüş
+ alip@hayalet /tmp/aaa (git)-[master] % git annex sync --debug
+ git ["--git-dir=/tmp/aaa/.git","--work-tree=/tmp/aaa","symbolic-ref","HEAD"]
+ git ["--git-dir=/tmp/aaa/.git","--work-tree=/tmp/aaa","show-ref","git-annex"]
+ git ["--git-dir=/tmp/aaa/.git","--work-tree=/tmp/aaa","show-ref","--hash","refs/heads/git-annex"]
+ git ["--git-dir=/tmp/aaa/.git","--work-tree=/tmp/aaa","log","refs/heads/git-annex..bc45cd9c2cb7c9b0c7a12a4c0210fe6a262abac9","--oneline","-n1"]
+ git ["--git-dir=/tmp/aaa/.git","--work-tree=/tmp/aaa","log","refs/heads/git-annex..9220bfedd1e13b2d791c918e2d59901af353825f","--oneline","-n1"]
+ (merging origin/git-annex into git-annex...)
+ git ["--git-dir=/tmp/aaa/.git","--work-tree=/tmp/aaa","cat-file","--batch"]
+ git ["--git-dir=/tmp/aaa/.git","--work-tree=/tmp/aaa","update-index","-z","--index-info"]
+ git ["--git-dir=/tmp/aaa/.git","--work-tree=/tmp/aaa","diff-index","--raw","-z","-r","--no-renames","-l0","--cached","9220bfedd1e13b2d791c918e2d59901af353825f"]
+ git-annex: Cannot decode byte '\xfc': Data.Text.Encoding.decodeUtf8: Invalid UTF-8 stream
+ 1 alip@hayalet /tmp/aaa (git)-[master] %
+
+What is the expected output? What do you see instead?
+
+Syncing a repository under a path with utf-8 characters in its name fails.
+
+What version of git-annex are you using? On what operating system?
+
+git-annex version: 3.20120624
+
+On Exherbo, linux-3.4
+
+Please provide any additional information below.
+
+'\xfc' is valid UTF-8: 'LATIN SMALL LETTER U WITH DIAERESIS'
+
+> closing as non-reproducible and presumably fixed. [[done]] --[[Joey]]
diff --git a/doc/bugs/git-annex:_Cannot_decode_byte___39____92__xfc__39__/comment_1_f1a7352b04f395e06e0094c1f51b6fff._comment b/doc/bugs/git-annex:_Cannot_decode_byte___39____92__xfc__39__/comment_1_f1a7352b04f395e06e0094c1f51b6fff._comment
new file mode 100644
index 000000000..28faa7b45
--- /dev/null
+++ b/doc/bugs/git-annex:_Cannot_decode_byte___39____92__xfc__39__/comment_1_f1a7352b04f395e06e0094c1f51b6fff._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.2.25"
+ subject="comment 1"
+ date="2012-06-27T02:48:31Z"
+ content="""
+I don't think this has to do with the path name of the repository containing utf-8 at all.
+
+Your recipe for reproducing this depends on some pre-existing repository that I don't know how to set up to reproduce this bug. All I can guess is that, based on the \"decodeUtf8\" in the error message, it's coming from the one part of the code that still uses that, the union merger.
+
+
+"""]]
diff --git a/doc/bugs/git-annex:_Cannot_decode_byte___39____92__xfc__39__/comment_2_c1890067079cd99667f31cbb4d2e4545._comment b/doc/bugs/git-annex:_Cannot_decode_byte___39____92__xfc__39__/comment_2_c1890067079cd99667f31cbb4d2e4545._comment
new file mode 100644
index 000000000..3486be733
--- /dev/null
+++ b/doc/bugs/git-annex:_Cannot_decode_byte___39____92__xfc__39__/comment_2_c1890067079cd99667f31cbb4d2e4545._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.2.25"
+ subject="comment 2"
+ date="2012-06-27T03:08:13Z"
+ content="""
+Since I can't reproduce it I am not sure, but it may be fixed by the commits I've just made.
+"""]]
diff --git a/doc/bugs/git-annex:_Cannot_decode_byte___39____92__xfc__39__/comment_3_213c96085c60c8e52cd803df07240158._comment b/doc/bugs/git-annex:_Cannot_decode_byte___39____92__xfc__39__/comment_3_213c96085c60c8e52cd803df07240158._comment
new file mode 100644
index 000000000..48a382029
--- /dev/null
+++ b/doc/bugs/git-annex:_Cannot_decode_byte___39____92__xfc__39__/comment_3_213c96085c60c8e52cd803df07240158._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkWzAq6TusMi9zI3FLkDOETRIAUTtmGZVg"
+ nickname="Ali"
+ subject="comment 3"
+ date="2012-06-27T12:56:37Z"
+ content="""
+Yes, the problem is fixed.
+
+The repository was a normal git repository with path /tmp/çüş (git init)
+and with annex description \"çüş\" (git annex init çüş)
+
+afaict, i can't reproduce the problem anymore either :-)
+"""]]
diff --git a/doc/bugs/git-annex:_Not_in_a_git_repository._.mdwn b/doc/bugs/git-annex:_Not_in_a_git_repository._.mdwn
new file mode 100644
index 000000000..a2817661e
--- /dev/null
+++ b/doc/bugs/git-annex:_Not_in_a_git_repository._.mdwn
@@ -0,0 +1,22 @@
+What steps will reproduce the problem?
+
+As a default user i want to start git-annex assistent with
+
+`$ git-annex webapp`
+
+`git-annex: Not in a git repository.`
+
+What is the expected output? What do you see instead?
+
+I would expect the assistent to popup in a opened browser window.
+
+What version of git-annex are you using? On what operating system?
+
+Debian wheezy with git-annex version: 3.20130114
+
+Please provide any additional information below.
+
+Its working if i start `git-annex webapp` as root. I had the same error on previous version.
+
+> I've made some improvements. Think this was user error. [[done]]
+> --[[Joey]]
diff --git a/doc/bugs/git-annex:_Not_in_a_git_repository._/comment_1_e10363a912953a646b87c824d1c6e5d4._comment b/doc/bugs/git-annex:_Not_in_a_git_repository._/comment_1_e10363a912953a646b87c824d1c6e5d4._comment
new file mode 100644
index 000000000..ea2b1fbf3
--- /dev/null
+++ b/doc/bugs/git-annex:_Not_in_a_git_repository._/comment_1_e10363a912953a646b87c824d1c6e5d4._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.238"
+ subject="comment 1"
+ date="2013-01-15T20:20:22Z"
+ content="""
+Sounds like a permissions error. Take a look at the repository in `~/Desktop/annex/` or `~/annex/` , and see if it contains files owned by root, or has bad directory permissions that would prevent your normal user from accessing it. Don't forget to check in its `.git` directory.
+
+I'd recommend not running the git-annex webapp as root. (There may be valid use cases for root to use git-annex in command-line mode.)
+"""]]
diff --git a/doc/bugs/git-annex:_Not_in_a_git_repository._/comment_2_9e96063a664b2be8a36d7940e7632d3f._comment b/doc/bugs/git-annex:_Not_in_a_git_repository._/comment_2_9e96063a664b2be8a36d7940e7632d3f._comment
new file mode 100644
index 000000000..4b054b120
--- /dev/null
+++ b/doc/bugs/git-annex:_Not_in_a_git_repository._/comment_2_9e96063a664b2be8a36d7940e7632d3f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmaMxYm33s0H-nxBo5uzYUzdIECoyR8Ug8"
+ nickname="Stefan"
+ subject="removing config"
+ date="2013-02-11T20:42:29Z"
+ content="""
+What fixed this for me was to remove .config/git-annex.
+"""]]
diff --git a/doc/bugs/git-annex:_Not_in_a_git_repository._/comment_3_8c9bd76b0e1200723ec13fbef943a2cc._comment b/doc/bugs/git-annex:_Not_in_a_git_repository._/comment_3_8c9bd76b0e1200723ec13fbef943a2cc._comment
new file mode 100644
index 000000000..403933886
--- /dev/null
+++ b/doc/bugs/git-annex:_Not_in_a_git_repository._/comment_3_8c9bd76b0e1200723ec13fbef943a2cc._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.183"
+ subject="comment 3"
+ date="2013-02-12T15:42:57Z"
+ content="""
+What can happen is that `.config/git-annex/autostart` can list a repository that is somehow trashed. For example, I've seen this when I let the webapp make a repository, and then manually deleted the directory, while the webapp was running. The webapp then re-creates the directory, but it's not a valid git repo, just a mostly empty directory.
+
+Tend to see this as user error though..
+"""]]
diff --git a/doc/bugs/git-annex:_Not_in_a_git_repository._/comment_4_8c49979b8a815f0d6f9de39ee9a88730._comment b/doc/bugs/git-annex:_Not_in_a_git_repository._/comment_4_8c49979b8a815f0d6f9de39ee9a88730._comment
new file mode 100644
index 000000000..3b7fee676
--- /dev/null
+++ b/doc/bugs/git-annex:_Not_in_a_git_repository._/comment_4_8c49979b8a815f0d6f9de39ee9a88730._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="modules"
+ ip="2.206.0.102"
+ subject="comment 4"
+ date="2013-04-03T07:45:53Z"
+ content="""
+Seems like a user error from my side. I removed repos while webapp was still running. Removing ~/.config/git-annex solved my problem. Thanks.
+"""]]
diff --git a/doc/bugs/git-annex:___60__socket:_16__62__:_hPutBuf:_resource_vanished___40__Broken_pipe__41__.mdwn b/doc/bugs/git-annex:___60__socket:_16__62__:_hPutBuf:_resource_vanished___40__Broken_pipe__41__.mdwn
new file mode 100644
index 000000000..2f4a6337e
--- /dev/null
+++ b/doc/bugs/git-annex:___60__socket:_16__62__:_hPutBuf:_resource_vanished___40__Broken_pipe__41__.mdwn
@@ -0,0 +1,14 @@
+### Please describe the problem.
+git-annex will randomly crash.
+
+### What steps will reproduce the problem?
+Unknown. Keeping git-annex running for an extended period, failing to sync properly on XMPP(not sure if that is relevant, but given this haven't been found before it might be)
+
+### What version of git-annex are you using? On what operating system?
+git-annex version: 4.20130521-g20710d4 (And multiple prior versions)
+
+### Please provide any additional information below.
+
+.git/annex/daemon.log upload: http://paste.ubuntu.com/5694813/
+
+I could find no debug.log?
diff --git a/doc/bugs/git-annex:___60__socket:_16__62__:_hPutBuf:_resource_vanished___40__Broken_pipe__41__/comment_1_e962317a939bf76097ae1a3b53b146e6._comment b/doc/bugs/git-annex:___60__socket:_16__62__:_hPutBuf:_resource_vanished___40__Broken_pipe__41__/comment_1_e962317a939bf76097ae1a3b53b146e6._comment
new file mode 100644
index 000000000..3300f17b9
--- /dev/null
+++ b/doc/bugs/git-annex:___60__socket:_16__62__:_hPutBuf:_resource_vanished___40__Broken_pipe__41__/comment_1_e962317a939bf76097ae1a3b53b146e6._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-05-24T15:50:45Z"
+ content="""
+I have seen this once on a similar system (family computer; XMPP being used). Unfortunatly it could be coming from anywhere -- and it's not at all clear how a crash in one thread could take it all down, since there are global top-level per-thread exception handlers that should run and log which thread crashed -- and normally seem to do this quite well.
+
+I may need to make a management process that ensures the assistant stays alive.
+
+I have also seen this happen when a computer is shutting down. But presumably in that case it's not really a bug.
+
+One thing you might try is see what is using socket 16 when it's running, assuming the socket will be the same. (Also, if you've had repeated crashes, it would be good to know if it's 16 each time..). You could do this by looking at `/proc/$pid/fd/16` Also, check the old logs, `.git/annex/daemon.log.*`
+"""]]
diff --git a/doc/bugs/git-annex:___60__socket:_16__62__:_hPutBuf:_resource_vanished___40__Broken_pipe__41__/comment_2_b32472b4c9b61e7a33dca802ecafb05b._comment b/doc/bugs/git-annex:___60__socket:_16__62__:_hPutBuf:_resource_vanished___40__Broken_pipe__41__/comment_2_b32472b4c9b61e7a33dca802ecafb05b._comment
new file mode 100644
index 000000000..b575ce977
--- /dev/null
+++ b/doc/bugs/git-annex:___60__socket:_16__62__:_hPutBuf:_resource_vanished___40__Broken_pipe__41__/comment_2_b32472b4c9b61e7a33dca802ecafb05b._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmLB39PC89rfGaA8SwrsnB6tbumezj-aC0"
+ nickname="Tobias"
+ subject="It did it again."
+ date="2013-05-25T09:31:23Z"
+ content="""
+And this time it was socket 27.
+
+Sadly happened during the night and I didn't monitor the socket when it happened.
+
+"""]]
diff --git a/doc/bugs/git-annex:___60__socket:_16__62__:_hPutBuf:_resource_vanished___40__Broken_pipe__41__/comment_3_fcfea3216831df9afbd855fbd842c27e._comment b/doc/bugs/git-annex:___60__socket:_16__62__:_hPutBuf:_resource_vanished___40__Broken_pipe__41__/comment_3_fcfea3216831df9afbd855fbd842c27e._comment
new file mode 100644
index 000000000..bccfae0d9
--- /dev/null
+++ b/doc/bugs/git-annex:___60__socket:_16__62__:_hPutBuf:_resource_vanished___40__Broken_pipe__41__/comment_3_fcfea3216831df9afbd855fbd842c27e._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-05-27T05:03:05Z"
+ content="""
+I got a similar crash:
+
+<pre>
+fd:19: hGetLine: end of file
+fd:18: hFlush: resource vanished (Broken pipe)
+fd:18: hFlush: resource vanished (Broken pipe)
+</pre>
+
+I was able to determine that fd 18/19 is reliably used for one of the git cat-file processes on this system. It's quite likely that fd 16/17 would be similar. fd 27 less likely. (But could easily be some other less long running git command.)
+
+This would be consistent with git cat-file crashing as it's trying to write to it and read from it.
+
+This took down the transferscanner thread, but the assistant continued running.
+"""]]
diff --git a/doc/bugs/git-annex:___60__socket:_16__62__:_hPutBuf:_resource_vanished___40__Broken_pipe__41__/comment_4_30d0b40efa59eeecb8a4be6d1baa1520._comment b/doc/bugs/git-annex:___60__socket:_16__62__:_hPutBuf:_resource_vanished___40__Broken_pipe__41__/comment_4_30d0b40efa59eeecb8a4be6d1baa1520._comment
new file mode 100644
index 000000000..aa3a2a307
--- /dev/null
+++ b/doc/bugs/git-annex:___60__socket:_16__62__:_hPutBuf:_resource_vanished___40__Broken_pipe__41__/comment_4_30d0b40efa59eeecb8a4be6d1baa1520._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 4"
+ date="2013-05-27T15:31:53Z"
+ content="""
+I tried, as an experiment, killing on of the `git cat-file` child processes of the assistant. As hypothesized, that led to the same thing I saw logged before.
+
+So, why might git commands be dying, and which commands? It would be pretty easy for git-annex to detect git cat-file dying, and restart it. Other commands would be more difficult. Still this might be a git bug which would best be fixed there. It would be good to get a core dump from git.
+"""]]
diff --git a/doc/bugs/git-annex:___60__socket:_16__62__:_hPutBuf:_resource_vanished___40__Broken_pipe__41__/comment_5_4af107f3184bc2abd2c9693167018628._comment b/doc/bugs/git-annex:___60__socket:_16__62__:_hPutBuf:_resource_vanished___40__Broken_pipe__41__/comment_5_4af107f3184bc2abd2c9693167018628._comment
new file mode 100644
index 000000000..2288b1d84
--- /dev/null
+++ b/doc/bugs/git-annex:___60__socket:_16__62__:_hPutBuf:_resource_vanished___40__Broken_pipe__41__/comment_5_4af107f3184bc2abd2c9693167018628._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 5"
+ date="2013-05-31T18:17:59Z"
+ content="""
+It will now detect if any of the long-running git processes crash, and automatically restart them. I don't know if this addresses the crash that was originally reported.
+"""]]
diff --git a/doc/bugs/git-annex:___60__socket:_16__62__:_hPutBuf:_resource_vanished___40__Broken_pipe__41__/comment_6_f96027f1e3c405809fae42ce8533c6d1._comment b/doc/bugs/git-annex:___60__socket:_16__62__:_hPutBuf:_resource_vanished___40__Broken_pipe__41__/comment_6_f96027f1e3c405809fae42ce8533c6d1._comment
new file mode 100644
index 000000000..447e9d80e
--- /dev/null
+++ b/doc/bugs/git-annex:___60__socket:_16__62__:_hPutBuf:_resource_vanished___40__Broken_pipe__41__/comment_6_f96027f1e3c405809fae42ce8533c6d1._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 6"
+ date="2013-06-14T18:15:27Z"
+ content="""
+Tobias, have you seen this at all since the last release.
+"""]]
diff --git a/doc/bugs/git-annex:___60__socket:_16__62__:_hPutBuf:_resource_vanished___40__Broken_pipe__41__/comment_7_b6fe89deb468a7e4f63f7faab147e3fb._comment b/doc/bugs/git-annex:___60__socket:_16__62__:_hPutBuf:_resource_vanished___40__Broken_pipe__41__/comment_7_b6fe89deb468a7e4f63f7faab147e3fb._comment
new file mode 100644
index 000000000..5d567ae8e
--- /dev/null
+++ b/doc/bugs/git-annex:___60__socket:_16__62__:_hPutBuf:_resource_vanished___40__Broken_pipe__41__/comment_7_b6fe89deb468a7e4f63f7faab147e3fb._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmkBwMWvNKZZCge_YqobCSILPMeK6xbFw8"
+ nickname="develop"
+ subject="comment 7"
+ date="2013-06-14T21:26:25Z"
+ content="""
+I'm sure i can still provoke it on some of my machines. But this weekend is completely blocked for me.
+
+I'll update everything to latest and give you an updated log. But will probably not happen till the middle of next week.
+
+
+"""]]
diff --git a/doc/bugs/git-annex:___60__socket:_16__62__:_hPutBuf:_resource_vanished___40__Broken_pipe__41__/comment_8_ebec5d9266604f03959dc16d933ff4a4._comment b/doc/bugs/git-annex:___60__socket:_16__62__:_hPutBuf:_resource_vanished___40__Broken_pipe__41__/comment_8_ebec5d9266604f03959dc16d933ff4a4._comment
new file mode 100644
index 000000000..b44164a89
--- /dev/null
+++ b/doc/bugs/git-annex:___60__socket:_16__62__:_hPutBuf:_resource_vanished___40__Broken_pipe__41__/comment_8_ebec5d9266604f03959dc16d933ff4a4._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmkBwMWvNKZZCge_YqobCSILPMeK6xbFw8"
+ nickname="develop"
+ subject="comment 8"
+ date="2013-06-29T09:34:02Z"
+ content="""
+I haven't been able to replicate this on two of my computers with the latest git-annex(as of this message).
+
+It seemed to happen more on my Mac OS X Lion though. And nightlies haven't been build for some time.
+
+So i'm waiting for a updated package for OS X. If you would rather clean up feel free to close this, I can just open it again if i hit it again.
+
+"""]]
diff --git a/doc/bugs/git-annex:_fd:14:_hGetLine:_end_of_file.mdwn b/doc/bugs/git-annex:_fd:14:_hGetLine:_end_of_file.mdwn
new file mode 100644
index 000000000..0d773b52c
--- /dev/null
+++ b/doc/bugs/git-annex:_fd:14:_hGetLine:_end_of_file.mdwn
@@ -0,0 +1,51 @@
+[[!tag moreinfo]]
+
+### Please describe the problem.
+
+git-annex webapp won't run
+
+### What steps will reproduce the problem?
+
+[[!format sh """
+arthur@machine:~/annex$ git-annex --debug webapp
+[2013-07-29 15:02:15 CEST] read: git ["--git-dir=/home/arthur/annex/.git","--work-tree=/home/arthur/annex","show-ref","git-annex"]
+[2013-07-29 15:02:15 CEST] read: git ["--git-dir=/home/arthur/annex/.git","--work-tree=/home/arthur/annex","show-ref","--hash","refs/heads/git-annex"]
+[2013-07-29 15:02:15 CEST] read: git ["--git-dir=/home/arthur/annex/.git","--work-tree=/home/arthur/annex","log","refs/heads/git-annex..a2b8f10ef258dff1a91e0354b2e2a58241631c9a","--oneline","-n1"]
+error: object file /home/arthur/annex/.git/objects/a2/b8f10ef258dff1a91e0354b2e2a58241631c9a is empty
+fatal: loose object a2b8f10ef258dff1a91e0354b2e2a58241631c9a (stored in /home/arthur/annex/.git/objects/a2/b8f10ef258dff1a91e0354b2e2a58241631c9a) is corrupt
+[2013-07-29 15:02:15 CEST] read: git ["--git-dir=/home/arthur/annex/.git","--work-tree=/home/arthur/annex","log","refs/heads/git-annex..8d4b8e04ccf0092d625f680b42e73d7bf15c6517","--oneline","-n1"]
+error: object file /home/arthur/annex/.git/objects/a2/b8f10ef258dff1a91e0354b2e2a58241631c9a is empty
+fatal: loose object a2b8f10ef258dff1a91e0354b2e2a58241631c9a (stored in /home/arthur/annex/.git/objects/a2/b8f10ef258dff1a91e0354b2e2a58241631c9a) is corrupt
+[2013-07-29 15:02:15 CEST] read: git ["--git-dir=/home/arthur/annex/.git","--work-tree=/home/arthur/annex","log","refs/heads/git-annex..6b2665208c11c9ecf969294bf45baac31894d8a7","--oneline","-n1"]
+error: object file /home/arthur/annex/.git/objects/a2/b8f10ef258dff1a91e0354b2e2a58241631c9a is empty
+fatal: loose object a2b8f10ef258dff1a91e0354b2e2a58241631c9a (stored in /home/arthur/annex/.git/objects/a2/b8f10ef258dff1a91e0354b2e2a58241631c9a) is corrupt
+[2013-07-29 15:02:15 CEST] read: git ["--git-dir=/home/arthur/annex/.git","--work-tree=/home/arthur/annex","log","refs/heads/git-annex..9d8429668f2148ea43760fb430e5950fbf42751e","--oneline","-n1"]
+error: object file /home/arthur/annex/.git/objects/a2/b8f10ef258dff1a91e0354b2e2a58241631c9a is empty
+fatal: loose object a2b8f10ef258dff1a91e0354b2e2a58241631c9a (stored in /home/arthur/annex/.git/objects/a2/b8f10ef258dff1a91e0354b2e2a58241631c9a) is corrupt
+[2013-07-29 15:02:15 CEST] chat: git ["--git-dir=/home/arthur/annex/.git","--work-tree=/home/arthur/annex","cat-file","--batch"]
+
+git-annex: fd:14: hGetLine: end of file
+failed
+[2013-07-29 15:02:15 CEST] read: ssh ["-O","stop","-S","/home/arthur/annex/.git/annex/ssh/arthur@git-annex-hostname-arthur_annex","-o","ControlMaster=auto","-o","ControlPersist=yes","arthur@git-annex-hostname-arthur_annex"]
+git-annex: webapp: 1 failed
+"""]]
+
+
+### What version of git-annex are you using? On what operating system?
+
+
+$ git-annex version
+git-annex version: 4.20130516.1
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP
+local repository version: 3
+default repository version: 3
+supported repository versions: 3 4
+upgrade supported from repository versions: 0 1 2
+
+$ git --version
+git version 1.7.9.5
+
+
+### Please provide any additional information below.
+
+
diff --git a/doc/bugs/git-annex:_fd:14:_hGetLine:_end_of_file/comment_1_36756f5d9d591cc52113c5cc0c1eae91._comment b/doc/bugs/git-annex:_fd:14:_hGetLine:_end_of_file/comment_1_36756f5d9d591cc52113c5cc0c1eae91._comment
new file mode 100644
index 000000000..b7fc68ffd
--- /dev/null
+++ b/doc/bugs/git-annex:_fd:14:_hGetLine:_end_of_file/comment_1_36756f5d9d591cc52113c5cc0c1eae91._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.21"
+ subject="comment 1"
+ date="2013-07-30T19:00:43Z"
+ content="""
+You have a somewhat out of date version there. Can you please try again with a newer version? There have been several fixes to bugs that could present like this.
+"""]]
diff --git a/doc/bugs/git-annex:_getUserEntryForID:_failed___40__Success__41__.mdwn b/doc/bugs/git-annex:_getUserEntryForID:_failed___40__Success__41__.mdwn
new file mode 100644
index 000000000..976109c79
--- /dev/null
+++ b/doc/bugs/git-annex:_getUserEntryForID:_failed___40__Success__41__.mdwn
@@ -0,0 +1,13 @@
+What steps will reproduce the problem?
+ Start "./git-annex-webapp"
+
+What is the expected output? What do you see instead?
+ The webapp should start, but I get the error "git-annex: getUserEntryForID: failed (Success)"
+
+What version of git-annex are you using? On what operating system?
+ 3.20121017 on "Ubuntu 10.04.4 LTS" 32-Bit
+
+Please provide any additional information below.
+
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/git-annex:_getUserEntryForID:_failed___40__Success__41__/comment_1_11a1615962325327466895d03e3d2379._comment b/doc/bugs/git-annex:_getUserEntryForID:_failed___40__Success__41__/comment_1_11a1615962325327466895d03e3d2379._comment
new file mode 100644
index 000000000..ef8800c21
--- /dev/null
+++ b/doc/bugs/git-annex:_getUserEntryForID:_failed___40__Success__41__/comment_1_11a1615962325327466895d03e3d2379._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.118"
+ subject="comment 1"
+ date="2012-10-25T18:52:52Z"
+ content="""
+This means it has been unable to look up your home directory in /etc/passwd. I wonder, are you using NIS or a similar thing that keeps your user entry out of /etc/passwd?
+"""]]
diff --git a/doc/bugs/git-annex:_getUserEntryForID:_failed___40__Success__41__/comment_2_eac51c3299e9fc04025675360969d537._comment b/doc/bugs/git-annex:_getUserEntryForID:_failed___40__Success__41__/comment_2_eac51c3299e9fc04025675360969d537._comment
new file mode 100644
index 000000000..dde7c0814
--- /dev/null
+++ b/doc/bugs/git-annex:_getUserEntryForID:_failed___40__Success__41__/comment_2_eac51c3299e9fc04025675360969d537._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawniayrgSdVLUc3c6bf93VbO-_HT4hzxmyo"
+ nickname="Tobias"
+ subject="comment 2"
+ date="2012-10-25T21:29:05Z"
+ content="""
+Yes, the system is using LDAP as user backend... Any idea how I can use git-annex with LDAP as user backend?
+"""]]
diff --git a/doc/bugs/git-annex:_getUserEntryForID:_failed___40__Success__41__/comment_3_c23dc02c7487d63b0905f1b7f3ca59f5._comment b/doc/bugs/git-annex:_getUserEntryForID:_failed___40__Success__41__/comment_3_c23dc02c7487d63b0905f1b7f3ca59f5._comment
new file mode 100644
index 000000000..3b358b7ea
--- /dev/null
+++ b/doc/bugs/git-annex:_getUserEntryForID:_failed___40__Success__41__/comment_3_c23dc02c7487d63b0905f1b7f3ca59f5._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.118"
+ subject="comment 3"
+ date="2012-10-25T22:18:55Z"
+ content="""
+Well, git-annex needs to know the user name, and the home directory. I've made it use
+USER, and HOME, when set, and only fall back to getpwent otherwise.
+"""]]
diff --git a/doc/bugs/git-annex:_getUserEntryForID:_failed___40__Success__41__/comment_4_0e8b28de5c173bc60ecc0126fb2209ca._comment b/doc/bugs/git-annex:_getUserEntryForID:_failed___40__Success__41__/comment_4_0e8b28de5c173bc60ecc0126fb2209ca._comment
new file mode 100644
index 000000000..63c3b474a
--- /dev/null
+++ b/doc/bugs/git-annex:_getUserEntryForID:_failed___40__Success__41__/comment_4_0e8b28de5c173bc60ecc0126fb2209ca._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawniayrgSdVLUc3c6bf93VbO-_HT4hzxmyo"
+ nickname="Tobias"
+ subject="comment 4"
+ date="2012-10-26T05:49:47Z"
+ content="""
+I think you mean the environment variables with \"use USER, and HOME\"? So I checked them I they are correct.
+Reading man(3) getpwent says \"from the password database (e.g., the local password file /etc/passwd, NIS, and LDAP)\", so it should be no problem with the LDAP backend I'm using to log-in...
+One other special thing: The home directory is on a NFS share.
+"""]]
diff --git a/doc/bugs/git-annex:_status:_1_failed.mdwn b/doc/bugs/git-annex:_status:_1_failed.mdwn
new file mode 100644
index 000000000..65f00469c
--- /dev/null
+++ b/doc/bugs/git-annex:_status:_1_failed.mdwn
@@ -0,0 +1,25 @@
+Hi
+
+I have a 1 To repository on my local linux box
+
+when i try :
+
+ git annex status
+
+i get :
+
+ git-annex: /media/malima/nazare/.git/annex/tmp/0723300. Everywhere I Dub --: getFileStatus: does not exist (No such file or directory)
+ failed
+
+how could i fix this issue ?
+
+many thanks for help
+
+> [[done]]; I managed to reproduce this bug by making a temp file named
+> ".git/annex/tmp/foo-", or indeed with any dash in it. This is enough
+> to make git-annex think it's a key, but badly formed enough that
+> it fails trying to use that key. Fixed to ignore such non-key files.
+>
+> I'm unsure why `.git/annex/tmp` would have such files in it.
+> Perhaps the assistant was running, but crashed while adding files?
+> --[[Joey]]
diff --git a/doc/bugs/git-annex:_status:_1_failed/comment_10_7cd9de88e55633fc75460f4fe0400f09._comment b/doc/bugs/git-annex:_status:_1_failed/comment_10_7cd9de88e55633fc75460f4fe0400f09._comment
new file mode 100644
index 000000000..556982e34
--- /dev/null
+++ b/doc/bugs/git-annex:_status:_1_failed/comment_10_7cd9de88e55633fc75460f4fe0400f09._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="RaspberryPie"
+ ip="204.8.156.142"
+ subject="comment 10"
+ date="2013-10-15T18:49:26Z"
+ content="""
+`git annex status` complains about `.git/annex/tmp/problematic_file--`. That file doesn't exist, but `.git/annex/tmp/problematic_file-` (with one dash) does. And the file itself (no dashes) does exist in a subdir of the annex.
+"""]]
diff --git a/doc/bugs/git-annex:_status:_1_failed/comment_11_504a944aab34155046f2fd82c2878f3e._comment b/doc/bugs/git-annex:_status:_1_failed/comment_11_504a944aab34155046f2fd82c2878f3e._comment
new file mode 100644
index 000000000..45ee3a050
--- /dev/null
+++ b/doc/bugs/git-annex:_status:_1_failed/comment_11_504a944aab34155046f2fd82c2878f3e._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="RaspberryPie"
+ ip="96.44.189.101"
+ subject="comment 11"
+ date="2013-10-27T00:59:56Z"
+ content="""
+I've tried a few things and found a workaround for the problem. TL;DR: `git annex dropunused`
+
+First I created a new annex with the same data. This time I used `git annex add` instead of having the assistant add the files. Adding went fine (no status error). Only when I started the assistant I got the error right away, with exactly the same file as the last time.
+
+When I removed the file from the annex, the error remained, but this time with a different problematic file in the same directory.
+
+Then I stumbled upon [this forum post](http://git-annex.branchable.com/forum/dot_git_slash_annex_slash_tmp/). It relates to this bug in that the files git-annex is complaining about are located in .git/annex/tmp. `git annex unused` returned about 130 entries (of about 1,200 files total). The last entry was my problematic file. The second-to-last entry was the file that gave me the same error when I removed the original problematic file. This lets me assume that the bug causes `git annex status' to produce 130 errors, of which only the last one gets displayed.
+
+So I ran `git annex dropunused 1-130 --force`. (The command wouldn't run without `--force`, saying that it couldn't make sure if numcopies were being met. This may or may not be related to network problems I'm having lately.) Anyway, now the error was finally gone and the status output didn't complain anymore.
+
+Weird stuff.
+"""]]
diff --git a/doc/bugs/git-annex:_status:_1_failed/comment_1_c235cc83c75474e6393e08d2d94b119d._comment b/doc/bugs/git-annex:_status:_1_failed/comment_1_c235cc83c75474e6393e08d2d94b119d._comment
new file mode 100644
index 000000000..a5a378c99
--- /dev/null
+++ b/doc/bugs/git-annex:_status:_1_failed/comment_1_c235cc83c75474e6393e08d2d94b119d._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.255.110"
+ subject="comment 1"
+ date="2013-09-09T19:38:50Z"
+ content="""
+You might try moving the .git/annex/transfer/ directory out of the way.
+
+What version of git-annex do you have installed?
+"""]]
diff --git a/doc/bugs/git-annex:_status:_1_failed/comment_2_932f6aaa712298a47868002872e16310._comment b/doc/bugs/git-annex:_status:_1_failed/comment_2_932f6aaa712298a47868002872e16310._comment
new file mode 100644
index 000000000..98fb1d805
--- /dev/null
+++ b/doc/bugs/git-annex:_status:_1_failed/comment_2_932f6aaa712298a47868002872e16310._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="eezec"
+ ip="93.21.246.236"
+ subject="comment 2"
+ date="2013-09-10T06:05:32Z"
+ content="""
+i have
+ git-annex version: 4.20130815
+
+"""]]
diff --git a/doc/bugs/git-annex:_status:_1_failed/comment_3_4bf55320439de152a65e2f21d4a0604b._comment b/doc/bugs/git-annex:_status:_1_failed/comment_3_4bf55320439de152a65e2f21d4a0604b._comment
new file mode 100644
index 000000000..0c3604ad6
--- /dev/null
+++ b/doc/bugs/git-annex:_status:_1_failed/comment_3_4bf55320439de152a65e2f21d4a0604b._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="eezec"
+ ip="93.21.246.236"
+ subject="comment 3"
+ date="2013-09-11T06:12:20Z"
+ content="""
+Joey .. moving transfer didn't work .. i have the same message when doing
+
+ git annex status
+ ....
+ getFileStatus: does not exist (No such file or directory)
+ ....
+ git-annex: status: 1 failed
+"""]]
diff --git a/doc/bugs/git-annex:_status:_1_failed/comment_4_cb2cfb798c6171f77eb7c4c4061c0f0c._comment b/doc/bugs/git-annex:_status:_1_failed/comment_4_cb2cfb798c6171f77eb7c4c4061c0f0c._comment
new file mode 100644
index 000000000..3e4ecb82f
--- /dev/null
+++ b/doc/bugs/git-annex:_status:_1_failed/comment_4_cb2cfb798c6171f77eb7c4c4061c0f0c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.51"
+ subject="comment 4"
+ date="2013-09-12T21:10:12Z"
+ content="""
+can you `strace git-annex status` ?
+"""]]
diff --git a/doc/bugs/git-annex:_status:_1_failed/comment_5_05c84dde377298adfd3fc20749b3108f._comment b/doc/bugs/git-annex:_status:_1_failed/comment_5_05c84dde377298adfd3fc20749b3108f._comment
new file mode 100644
index 000000000..61af9e9df
--- /dev/null
+++ b/doc/bugs/git-annex:_status:_1_failed/comment_5_05c84dde377298adfd3fc20749b3108f._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="RaspberryPie"
+ ip="213.61.149.100"
+ subject="comment 5"
+ date="2013-10-13T06:33:24Z"
+ content="""
+I use v4.20130909 and get the same error when running `git-annex status`. Does it matter that my filename in question is shown to have two dashes (--) at the end, just as in OP's case? Other files in .git/annex/tmp only have one dash at the end.
+
+Joey, I straced the command and sent the output to your kitenet e-mail address. Hope it helps.
+"""]]
diff --git a/doc/bugs/git-annex:_status:_1_failed/comment_6_bb5141e29c665bc0bb82611ea27d4be8._comment b/doc/bugs/git-annex:_status:_1_failed/comment_6_bb5141e29c665bc0bb82611ea27d4be8._comment
new file mode 100644
index 000000000..ab720b6ce
--- /dev/null
+++ b/doc/bugs/git-annex:_status:_1_failed/comment_6_bb5141e29c665bc0bb82611ea27d4be8._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.22"
+ subject="comment 6"
+ date="2013-10-13T17:35:20Z"
+ content="""
+What is the last line printed before this error message?
+
+My preliminary analysis is that it is checking the sizes of stale files in .git/annex/tmp, and could fail if a temp file was deleted just as it was running.
+But if so it would be unlikely to happen every time `git annex status` is run. Or even if it did happen every time (perhaps because you appear to be running the git-annex assistant and it might be adding a lot of files in the background), the filename in the error message would be different every time. I have just committed a fix for that problem to git, but am not 100% sure it's really the problem that you're seeing.
+"""]]
diff --git a/doc/bugs/git-annex:_status:_1_failed/comment_7_5fd39168c9e1bf43909ee0ab3c75c40c._comment b/doc/bugs/git-annex:_status:_1_failed/comment_7_5fd39168c9e1bf43909ee0ab3c75c40c._comment
new file mode 100644
index 000000000..54f87581c
--- /dev/null
+++ b/doc/bugs/git-annex:_status:_1_failed/comment_7_5fd39168c9e1bf43909ee0ab3c75c40c._comment
@@ -0,0 +1,35 @@
+[[!comment format=mdwn
+ username="RaspberryPie"
+ ip="37.130.227.133"
+ subject="comment 7"
+ date="2013-10-13T22:14:05Z"
+ content="""
+Yes, I run the assistant in the background. The error came up after I ran
+
+ git init
+ git annex init
+ git annex direct
+ git annex assistant
+
+in a directory containing a lot of files (around 80G). Right away, `git annex status` gave me the error below. The file name in question never changed during the process of adding files and hasn't changed after all files have been added.
+
+Here's the complete command line output:
+
+ $ git annex status
+ supported backends: SHA256E SHA1E SHA512E SHA224E SHA384E SHA256 SHA1 SHA512 SHA224 SHA384 WORM URL
+ supported remote types: git gcrypt S3 bup directory rsync web glacier hook
+ repository mode: direct
+ trusted repositories: 0
+ semitrusted repositories: 2
+ 00000000-0000-0000-0000-000000000001 -- web
+ c1bb8eb9-fb0c-4bac-b0df-37df25b2d1e7 -- here
+ untrusted repositories: 0
+ transfers in progress: none
+ available local disk space: 1.74 terabytes (+10 gigabytes reserved)
+
+ git-annex: /storage/media/.git/annex/tmp/problematic_file--: getFileStatus: does not exist (No such file or directory)
+ failed
+ git-annex: status: 1 failed
+
+
+"""]]
diff --git a/doc/bugs/git-annex:_status:_1_failed/comment_8_e493f6bddb0bfcd9478d5f4d9fc170e0._comment b/doc/bugs/git-annex:_status:_1_failed/comment_8_e493f6bddb0bfcd9478d5f4d9fc170e0._comment
new file mode 100644
index 000000000..e4fae1f31
--- /dev/null
+++ b/doc/bugs/git-annex:_status:_1_failed/comment_8_e493f6bddb0bfcd9478d5f4d9fc170e0._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="RaspberryPie"
+ ip="204.8.156.142"
+ subject="comment 8"
+ date="2013-10-14T17:49:05Z"
+ content="""
+Quick question: Is there any way to get rid of the error in the existing repository (e.g. remove the problematic tmp file entry) so I can get a complete status output? Bonus points if I don't have to annex every single file anew. `git annex fsck` doesn't work, as doesn't `git annex fix` (it's a direct repo).
+"""]]
diff --git a/doc/bugs/git-annex:_status:_1_failed/comment_9_573377d444aee0895b231082bc6839a4._comment b/doc/bugs/git-annex:_status:_1_failed/comment_9_573377d444aee0895b231082bc6839a4._comment
new file mode 100644
index 000000000..208f178a3
--- /dev/null
+++ b/doc/bugs/git-annex:_status:_1_failed/comment_9_573377d444aee0895b231082bc6839a4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="64.134.31.139"
+ subject="comment 9"
+ date="2013-10-15T17:51:04Z"
+ content="""
+Does the file that it's complaining about exist?
+"""]]
diff --git a/doc/bugs/git-annex_3.20130216.1_tests_are_broken.mdwn b/doc/bugs/git-annex_3.20130216.1_tests_are_broken.mdwn
new file mode 100644
index 000000000..6df6bf489
--- /dev/null
+++ b/doc/bugs/git-annex_3.20130216.1_tests_are_broken.mdwn
@@ -0,0 +1,43 @@
+ $ pwd
+ [bla]/git-annex-3.20130216.1
+ $ runhaskell Setup configure --prefix=/usr --libdir=/usr/lib64 --docdir=/usr/share/doc/git-annex-3.20130216.1-r2 \
+ --htmldir=/usr/share/doc/git-annex-3.20130216.1-r2/html --with-compiler=ghc-7.6.2 --enable-shared \
+ --disable-executable-stripping --global --verbose --enable-tests --flags=S3 --flags=-WebDAV --flags=-Inotify \
+ --flags=Dbus --flags=-Assistant --flags=-Webapp --flags=-Pairing --flags=-XMPP --flags=-DNS
+ $ runhaskell Setup.hs build
+ Building git-annex-3.20130217...
+ Preprocessing test suite 'test' for git-annex-3.20130217...
+
+ Annex/UUID.hs:30:8:
+ Could not find module `System.Random'
+ It is a member of the hidden package `random-1.0.1.1'.
+ Perhaps you need to add `random' to the build-depends in your .cabal file.
+ Use -v to see a list of the files searched for.
+
+Adding `random` to the dependencies of the test suite results in:
+
+ $ runhaskell Setup.hs build
+ Building git-annex-3.20130217...
+ Preprocessing test suite 'test' for git-annex-3.20130217...
+
+ Annex/UUID.hs:29:18:
+ Could not find module `Data.UUID'
+ It is a member of the hidden package `uuid-1.2.9'.
+ Perhaps you need to add `uuid' to the build-depends in your .cabal file.
+ Use -v to see a list of the files searched for.
+
+Adding `uuid` results in:
+
+ $ runhaskell Setup.hs build
+ Building git-annex-3.20130217...
+ Preprocessing test suite 'test' for git-annex-3.20130217...
+
+ Command/Add.hs:25:8:
+ Could not find module `Utility.Touch'
+ Use -v to see a list of the files searched for.
+
+
+Also: you included ".git-annex.cabal.swp" in the tarball.
+
+> These problems in the cabal file were fixed the other day. [[done]]
+> --[[Joey]]
diff --git a/doc/bugs/git-annex___38___rsync_can__39__t_copy_files_with___39__:__39___in_their_names.mdwn b/doc/bugs/git-annex___38___rsync_can__39__t_copy_files_with___39__:__39___in_their_names.mdwn
new file mode 100644
index 000000000..b55493dc4
--- /dev/null
+++ b/doc/bugs/git-annex___38___rsync_can__39__t_copy_files_with___39__:__39___in_their_names.mdwn
@@ -0,0 +1,38 @@
+What steps will reproduce the problem?
+
+Send a file with the character ':' in it. rsync fails to send those files from the command line as well
+confusing them with hostnames. As far as I know a workaround is prepending the pathname with './'
+(for rsync commandline invocation that is)
+
+What is the expected output? What do you see instead?
+
+ copy müzik/Mixxx/Recordings/2013-01-15_16h:13m:03s.mp3 (checking kaotik...) (to kaotik...)
+ git-annex: //home/alip/kaotika/.git/annex/transfer/download/effe4eef-926f-494c-a3b6-eeecdc208fb9/SHA256-s36349200--ce51eaf316b19c61831
+ 41f0bda1c54be7e590e5999753a4b1c16bafab93a3fc1: commitBuffer: invalid argument (invalid character)
+ git-annex-shell: recvkey: 1 failed
+ protocol version mismatch -- is your shell clean?
+ (see the rsync man page for an explanation)
+ rsync error: protocol incompatibility (code 2) at compat.c(174) [sender=3.0.9]
+
+
+What version of git-annex are you using? On what operating system?
+
+ git-annex version: 3.20120807
+ local repository version: 3
+ default repository version: 3
+ supported repository versions: 3
+ upgrade supported from repository versions: 0 1 2
+
+Operating system is Linux (Exherbo) although this isn't a packaged installation.
+I installed it by hand from git sources.
+
+Please provide any additional information below.
+
+Thanks for the wonderful tool!
+
+> This is a duplicate of
+> [[bugs/commitBuffer:_invalid_argument___40__invalid_character__41__]],
+> which was fixed in version 3.20120924. You need to upgrade the git-annex
+> on kaotik. [[done]]
+>
+> (It has nothing to do with rsync or colon in filenames.) --[[Joey]]
diff --git a/doc/bugs/git-annex_add_should_repack_as_it_goes.mdwn b/doc/bugs/git-annex_add_should_repack_as_it_goes.mdwn
new file mode 100644
index 000000000..e9c444857
--- /dev/null
+++ b/doc/bugs/git-annex_add_should_repack_as_it_goes.mdwn
@@ -0,0 +1,32 @@
+What steps will reproduce the problem?
+
+1. Create a fresh git-annex repository
+2. Add a directory tree to it with about 300,000 files in it
+3. wait
+4. change the tree; attempt a git commit
+
+What is the expected output? What do you see instead?
+
+git commit hangs due to the large number of loose objects created during the git annex add. If git annex had stopped to repack the git repo a few times along the way, I think this might have been avoided.
+
+What version of git-annex are you using? On what operating system?
+
+git-annex version: 4.20130323
+local repository version: 3
+default repository version: 3
+supported repository versions: 3 4
+upgrade supported from repository versions: 0 1 2
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV FsEvents XMPP DNS
+
+Darwin pluto.local 12.3.0 Darwin Kernel Version 12.3.0: Sun Jan 6 22:37:10 PST 2013; root:xnu-2050.22.13~1/RELEASE_X86_64 x86_64
+(Mac OS 10.8.3)
+
+git version 1.8.2
+
+> Based on the benchmarks below, repacking even once does not speed things
+> up; repacking repeatedly as `git annex add` runs would slow things down.
+>
+> It might be worth following up with the git developers why `git commit`
+> scans loose objects after it has already output the commit sha1sum.
+>
+> Don't see any improvements git-annex can make. [[done]] --[[Joey]]
diff --git a/doc/bugs/git-annex_add_should_repack_as_it_goes/comment_1_dbcaa0be4cd764128fb7263a95f73a32._comment b/doc/bugs/git-annex_add_should_repack_as_it_goes/comment_1_dbcaa0be4cd764128fb7263a95f73a32._comment
new file mode 100644
index 000000000..bdbeec108
--- /dev/null
+++ b/doc/bugs/git-annex_add_should_repack_as_it_goes/comment_1_dbcaa0be4cd764128fb7263a95f73a32._comment
@@ -0,0 +1,22 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-04-05T02:31:08Z"
+ content="""
+I created 300,000 files and added them. I found the following main cost centers:
+
+* Checksumming all those files has overhead. Can be avoided by using `--backend=WORM`
+* git-annex runs `git add` after every 10k files it processes. As the index file grows in size, `git add` gets slower (git has to rewrite the index file each time; which really needs to be improved on the git side in order for git to scale better to lots of files). Can be avoided by setting `annex.queuesize` to a larger value. If you have enough memory, git-annex can buffer all 300,000 files and only run `git add` once.
+* At the end of `git annex add`, it has to stage location logs for all files. This takes a few minutes; it probably on a par with the overhead of running `git add` once with an equal number of files.
+
+After `git annex add`, I ran `git commit -m add`. This commit took only 11 minutes. (5 year old netbook with a SSD.) That may seem like a long time, but the (un-optimised) `git annex add` took 4 hours or so.
+
+In that commit, I saw these cost centers:
+
+* The `pre-commit` hooks runs `git annex pre-commit`, which scans all 300,000 symlinks to make sure they don't need fixing. That took around 5 seconds. Can be disabled if you don't mind manually running `git annex fix` when moving files.
+* Calculating the commit took a while.
+* `git commit` did process all the loose object files. It did not create a pack, and I am not sure why it needed to look at them, especially since it had already printed the sha of the commit, and so had already created all the objects it needed to at that point.
+
+Next I will try again, and first run `git gc` before `git commit` ....
+"""]]
diff --git a/doc/bugs/git-annex_add_should_repack_as_it_goes/comment_2_6a27551c4fb7f62ed9f627134c755d01._comment b/doc/bugs/git-annex_add_should_repack_as_it_goes/comment_2_6a27551c4fb7f62ed9f627134c755d01._comment
new file mode 100644
index 000000000..6f2207a6a
--- /dev/null
+++ b/doc/bugs/git-annex_add_should_repack_as_it_goes/comment_2_6a27551c4fb7f62ed9f627134c755d01._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-04-05T06:33:54Z"
+ content="""
+`git repack` took 18 minutes. However, it actually only packed the objects for the commit `git annex add` makes to the git-annex branch. Objects for the staged symlinks are left loose, presumably because no commit refers to them.
+
+Unsurprisingly, then, `git commit` still took as long as before.
+
+I then ran `git repack` again. It packed all the loose objects this time. After this, `git commit` only takes 11 seconds. If I remove the `pre-commit` hook, it drops to a respectable 5 seconds.
+
+
+"""]]
diff --git a/doc/bugs/git-annex_add_should_repack_as_it_goes/comment_3_ff8b589fbcf25c98abd1c58830074650._comment b/doc/bugs/git-annex_add_should_repack_as_it_goes/comment_3_ff8b589fbcf25c98abd1c58830074650._comment
new file mode 100644
index 000000000..e60460443
--- /dev/null
+++ b/doc/bugs/git-annex_add_should_repack_as_it_goes/comment_3_ff8b589fbcf25c98abd1c58830074650._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-04-06T06:32:56Z"
+ content="""
+More testing shows that only the first git commit is slow. A second commit will be fast whether or not `git-repack` has been run in between.
+"""]]
diff --git a/doc/bugs/git-annex_branch_corruption.mdwn b/doc/bugs/git-annex_branch_corruption.mdwn
new file mode 100644
index 000000000..9c864d85f
--- /dev/null
+++ b/doc/bugs/git-annex_branch_corruption.mdwn
@@ -0,0 +1,95 @@
+Below is a test case which shows a way that the git-annex branch
+can become corrupted and lose data, including location log records and
+uuid.log lines.
+
+At the end, a commit on the git-annex branch removes one of the 2 lines
+from the uuid.log; which should never happen.
+
+The actual problem occurs earlier, at the "push point". Here a repo is
+cloned from the main one, initialized (adding the last uuid.log line),
+and then pushed back to the main one. That push is a fast-forward, so is
+allowed to directly update the git-annex branch in the main repo:
+
+ b884fe5..c497739 git-annex -> git-annex
+
+Now the git-annex branch has a change that is not reflected in
+`.git/annex/index`, so the next time a change is made, it's committed
+using the out of date index, which causes a reversion of the changes
+that were pushed to the branch.
+
+---
+
+## Thoughts
+
+This is essentially the same reason why git blocks pushes to the checked-out
+branch of a non-bare repository.
+
+This problem only affects workflows that involve pushing. Pulling workflows
+do not directly update the local git-annex branch, so avoid the problem.
+
+And while bare repos are pushed to, they rarely have changes made directly
+to their git-annex branches, so while I think the same problem could
+happen with pushing to a bare repo, it's unlikely.
+
+None of which is to say this is not a bad bug that needs to be comprehensively
+fixed.
+
+Probably git-annex needs to record which ref of the git-annex branch
+corresponds to its index, and if the branch is at a different ref,
+merge it into the index.
+
+> And now that's [[done]]. I managed to do it with very little slowdown.
+>
+> A side benefit is that users can now safely check out the git-annex
+> branch and commit changes to it, and git-annex will notice them.
+> Before, it was documented to ignore such changes.
+> --[[Joey]]
+
+---
+
+## Workaround
+
+Users who want to prevent this bug from occuring when pushing to their
+non-bare repositories can install this script as `.git/hooks/update`
+
+<pre>
+#!/bin/sh
+if [ "$1" = refs/heads/git-annex ]; then
+ exit 1
+fi
+</pre>
+
+--[[Joey]]
+
+---
+
+## Test Case
+<pre>
+#!/bin/sh
+mkdir annextest
+cd annextest
+
+git init dir1
+cd dir1
+git annex init
+touch foo
+echo hi > bar
+git annex add
+git commit -m add
+
+cd ..
+git clone dir1 dir2
+cd dir2
+git annex init otherdir
+git annex get
+# push point
+git push
+
+cd ..
+cd dir1
+echo "before"
+git show git-annex:uuid.log
+git annex drop foo --force
+echo "after"
+git show git-annex:uuid.log
+</pre>
diff --git a/doc/bugs/git-annex_branch_push_race.mdwn b/doc/bugs/git-annex_branch_push_race.mdwn
new file mode 100644
index 000000000..013ff70dd
--- /dev/null
+++ b/doc/bugs/git-annex_branch_push_race.mdwn
@@ -0,0 +1,45 @@
+The fix for the [[git-annex_branch_corruption]] bug is subject to a race.
+With that fix, git-annex does this when committing a change to the branch:
+
+1. lock the journal file (this avoids git-annex racing itself, FWIW)
+2. check what the head of the branch points to, to see if a newer branch
+ has appeared
+3. if so, updates the index file from the branch
+4. stages changes in the index
+5. commits to the branch using the index file
+
+If a push to the branch comes in during 2-5, then
+[[git-annex_branch_corruption]] could still occur.
+
+---
+
+## approach 1, using locking
+
+Add an update hook and a post-update hook. The update hook
+will use locking to ensure that no git-annex is currently running
+a commit, and block any git-annex's from starting one. It
+will background itself, and remain running during the push.
+The post-update hook will signal it to exit.
+
+I don't like this approach much, since it involves a daemon, two hooks,
+and lots of things to go wrong. And it blocks using git-annex during a
+push. This approach should be a last resort.
+
+## approach 2, lockless method
+
+After a commit is made to the branch, check to see if the parent of
+the commit is the same ref that the index file was last updated to. If it's
+not, then the race occurred.
+
+How to recover from the race? Well, just union merging the parent of the
+commit into the index file and re-committing should work, I think. When
+the race occurs, the commit reverts its parent's changes, and this will
+redo them.
+
+(Of course, this re-commit will also be subject to the race, and
+will need the same check for the race as the other commits. It won't loop
+forever, I hope.)
+
+> [[done]] and tested.
+
+--[[Joey]]
diff --git a/doc/bugs/git-annex_broken_on_Android_4.3.mdwn b/doc/bugs/git-annex_broken_on_Android_4.3.mdwn
new file mode 100644
index 000000000..4c1b356fb
--- /dev/null
+++ b/doc/bugs/git-annex_broken_on_Android_4.3.mdwn
@@ -0,0 +1,7 @@
+As per [[install/Android/#comment-e218073735d67691a2c3f66cc53ca6ac]] and [[install/Android/#comment-29bd13ab9cb830ffcd7850b84fb111c8]] :
+
+git-annex is broken on Android 4.3; both on Nexus 4 and Nexus 7.
+
+> [[Fixed|done]]. A 4.3 build of the apk is now available.
+> (Unfortunately the fix breaks support for older versions of Android,
+> so two versions of the apk have to be built now.) --[[Joey]]
diff --git a/doc/bugs/git-annex_broken_on_Android_4.3/comment_10_e47c073f1614f7b57f86acedeeb1cadc._comment b/doc/bugs/git-annex_broken_on_Android_4.3/comment_10_e47c073f1614f7b57f86acedeeb1cadc._comment
new file mode 100644
index 000000000..5d56dc84c
--- /dev/null
+++ b/doc/bugs/git-annex_broken_on_Android_4.3/comment_10_e47c073f1614f7b57f86acedeeb1cadc._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm7qEQF8yzbY0_PHq3QERHxUGuXmW6qw8o"
+ nickname="Anton"
+ subject="comment 10"
+ date="2013-11-10T22:10:49Z"
+ content="""
+I can confirm that the Hello World program works with the Nexus 7 2013, running Android 4.3.
+"""]]
diff --git a/doc/bugs/git-annex_broken_on_Android_4.3/comment_11_ce34578c45060b7c8b759efd1c1d8df8._comment b/doc/bugs/git-annex_broken_on_Android_4.3/comment_11_ce34578c45060b7c8b759efd1c1d8df8._comment
new file mode 100644
index 000000000..d84a59b76
--- /dev/null
+++ b/doc/bugs/git-annex_broken_on_Android_4.3/comment_11_ce34578c45060b7c8b759efd1c1d8df8._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnegApaT6kTI0Gxy9SNmI9Og-k_fC_aS7Y"
+ nickname="Michael Alan"
+ subject="Hooray!"
+ date="2013-11-10T22:21:46Z"
+ content="""
+I have a Nexus 7 (2013) with 4.3 that I'll test it on---I expect that my test will be successful.
+
+I'll also run the test on my Nexus 5, running 4.4.
+
+Getting git-annex working on 4.3 was the last thing keeping me from being able to ditch Dropbox entirely. I'm so glad to hear there's some potential progress.
+
+"""]]
diff --git a/doc/bugs/git-annex_broken_on_Android_4.3/comment_12_75965395dc33046ce34ac5ba972b7d64._comment b/doc/bugs/git-annex_broken_on_Android_4.3/comment_12_75965395dc33046ce34ac5ba972b7d64._comment
new file mode 100644
index 000000000..3f520d7e4
--- /dev/null
+++ b/doc/bugs/git-annex_broken_on_Android_4.3/comment_12_75965395dc33046ce34ac5ba972b7d64._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.246"
+ subject="comment 12"
+ date="2013-11-10T22:23:49Z"
+ content="""
+Full rebuild in progress (takes about 6 hours +- manual fixing).
+"""]]
diff --git a/doc/bugs/git-annex_broken_on_Android_4.3/comment_13_f07bc76dd3c5580fc0855a33ae835c8d._comment b/doc/bugs/git-annex_broken_on_Android_4.3/comment_13_f07bc76dd3c5580fc0855a33ae835c8d._comment
new file mode 100644
index 000000000..f2a57f731
--- /dev/null
+++ b/doc/bugs/git-annex_broken_on_Android_4.3/comment_13_f07bc76dd3c5580fc0855a33ae835c8d._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnegApaT6kTI0Gxy9SNmI9Og-k_fC_aS7Y"
+ nickname="Michael Alan"
+ subject="Oh, and if a 4.3 device would be helpful..."
+ date="2013-11-10T22:28:48Z"
+ content="""
+I have Samsung Epic 4G (epic_mtd) that I'm no longer using and would be quite happy to send you---it's older, and slow, but it is at least currently supported by CyanogenMod, so it should be possible to install 10.2 milestone builds on it and at least do basic testing.
+
+Hell, if it would really facilitate Android support, I'd happily pick up something like a B&N Nook HD+ and send it to you---that should be similarly amenable to CM installs and testing.
+
+Though I will also understand if you don't necessarily want to have a bunch of superfluous hardware laying around.
+"""]]
diff --git a/doc/bugs/git-annex_broken_on_Android_4.3/comment_14_637c59becc68a1e4f60069d8873489ff._comment b/doc/bugs/git-annex_broken_on_Android_4.3/comment_14_637c59becc68a1e4f60069d8873489ff._comment
new file mode 100644
index 000000000..6336a3bd4
--- /dev/null
+++ b/doc/bugs/git-annex_broken_on_Android_4.3/comment_14_637c59becc68a1e4f60069d8873489ff._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnegApaT6kTI0Gxy9SNmI9Og-k_fC_aS7Y"
+ nickname="Michael Alan"
+ subject="Works on KitKat"
+ date="2013-11-10T23:15:28Z"
+ content="""
+I skipped testing on my Nexus 7, figuring that would be duplicative, and instead ran it on my Nexus 5, and it worked great.
+"""]]
diff --git a/doc/bugs/git-annex_broken_on_Android_4.3/comment_15_d80b87055f72873f5678a01d2630bea4._comment b/doc/bugs/git-annex_broken_on_Android_4.3/comment_15_d80b87055f72873f5678a01d2630bea4._comment
new file mode 100644
index 000000000..6bca41b3a
--- /dev/null
+++ b/doc/bugs/git-annex_broken_on_Android_4.3/comment_15_d80b87055f72873f5678a01d2630bea4._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.246"
+ subject="comment 15"
+ date="2013-11-11T04:34:21Z"
+ content="""
+6 hours later, and: <http://downloads.kitenet.net/git-annex/autobuild/android/git-annex.apk>
+
+testing appreciated!
+"""]]
diff --git a/doc/bugs/git-annex_broken_on_Android_4.3/comment_16_57ac84868b223b30f005704eefa01b8d._comment b/doc/bugs/git-annex_broken_on_Android_4.3/comment_16_57ac84868b223b30f005704eefa01b8d._comment
new file mode 100644
index 000000000..204845eb5
--- /dev/null
+++ b/doc/bugs/git-annex_broken_on_Android_4.3/comment_16_57ac84868b223b30f005704eefa01b8d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://launchpad.net/~subito"
+ nickname="subito"
+ subject="Nexus 5 Android 4.4"
+ date="2013-11-11T10:07:07Z"
+ content="""
+Does not work for me. Same error as in the original Bug report.
+"""]]
diff --git a/doc/bugs/git-annex_broken_on_Android_4.3/comment_17_a41f4d8a72c07ad770e6479e9b8c7f1d._comment b/doc/bugs/git-annex_broken_on_Android_4.3/comment_17_a41f4d8a72c07ad770e6479e9b8c7f1d._comment
new file mode 100644
index 000000000..9712f5944
--- /dev/null
+++ b/doc/bugs/git-annex_broken_on_Android_4.3/comment_17_a41f4d8a72c07ad770e6479e9b8c7f1d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnegApaT6kTI0Gxy9SNmI9Og-k_fC_aS7Y"
+ nickname="Michael Alan"
+ subject="Same error as before, Nexus 5 and 7"
+ date="2013-11-11T13:06:17Z"
+ content="""
+Unfortunately, my experience mirrors subito's---same error as before on both 4.3 and 4.4.
+"""]]
diff --git a/doc/bugs/git-annex_broken_on_Android_4.3/comment_18_7d36637f11cda51de395303d5c1c6a3f._comment b/doc/bugs/git-annex_broken_on_Android_4.3/comment_18_7d36637f11cda51de395303d5c1c6a3f._comment
new file mode 100644
index 000000000..2dc32cf15
--- /dev/null
+++ b/doc/bugs/git-annex_broken_on_Android_4.3/comment_18_7d36637f11cda51de395303d5c1c6a3f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.246"
+ subject="comment 18"
+ date="2013-11-11T13:27:49Z"
+ content="""
+Hmm, maybe the problem is caused by stripping the program? If so, this should fail the same way: <http://tmp.kitenet.net/hello.stripped>
+"""]]
diff --git a/doc/bugs/git-annex_broken_on_Android_4.3/comment_19_c8609c3f7f62ae5427fd8c60bc9546ed._comment b/doc/bugs/git-annex_broken_on_Android_4.3/comment_19_c8609c3f7f62ae5427fd8c60bc9546ed._comment
new file mode 100644
index 000000000..2f22ad21c
--- /dev/null
+++ b/doc/bugs/git-annex_broken_on_Android_4.3/comment_19_c8609c3f7f62ae5427fd8c60bc9546ed._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnegApaT6kTI0Gxy9SNmI9Og-k_fC_aS7Y"
+ nickname="Michael Alan"
+ subject="Unfortunately, it would not appear that easy..."
+ date="2013-11-11T14:33:05Z"
+ content="""
+The stripped binary for hello worked fine.
+"""]]
diff --git a/doc/bugs/git-annex_broken_on_Android_4.3/comment_1_0ffb3833ce2c2e0320468dc9a09866d7._comment b/doc/bugs/git-annex_broken_on_Android_4.3/comment_1_0ffb3833ce2c2e0320468dc9a09866d7._comment
new file mode 100644
index 000000000..9b3b35c4b
--- /dev/null
+++ b/doc/bugs/git-annex_broken_on_Android_4.3/comment_1_0ffb3833ce2c2e0320468dc9a09866d7._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.21"
+ subject="comment 1"
+ date="2013-07-30T17:31:53Z"
+ content="""
+Given that the issue is it can't link against libc, it may need to be rebuilt with a newer version of the Android SDK and/or NDK.
+
+OTOH, for it to get as far as it does, the start.c has successfully run, using the system's libc. So perhaps this only affects Haskell binaries somehow?
+"""]]
diff --git a/doc/bugs/git-annex_broken_on_Android_4.3/comment_20_0886bca6d0c6a9415a7794d256be2e9d._comment b/doc/bugs/git-annex_broken_on_Android_4.3/comment_20_0886bca6d0c6a9415a7794d256be2e9d._comment
new file mode 100644
index 000000000..2b547d9a7
--- /dev/null
+++ b/doc/bugs/git-annex_broken_on_Android_4.3/comment_20_0886bca6d0c6a9415a7794d256be2e9d._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.246"
+ subject="comment 20"
+ date="2013-11-11T16:23:11Z"
+ content="""
+To bisect the problem space further, in case the apk build machinery is at fault, here's a git-annex binary not included in an apk. (Run same as the hello world.)
+
+<http://tmp.kitenet.net/git-annex.bin>
+
+And here's a more minimal git-annex binary (trying to look identical to hello world from the linker's perspective, just a bit larger..).
+
+<http://tmp.kitenet.net/git-annex-min.bin>
+"""]]
diff --git a/doc/bugs/git-annex_broken_on_Android_4.3/comment_21_2b39729f95c9c4bba620ecdd3d1558ed._comment b/doc/bugs/git-annex_broken_on_Android_4.3/comment_21_2b39729f95c9c4bba620ecdd3d1558ed._comment
new file mode 100644
index 000000000..551334819
--- /dev/null
+++ b/doc/bugs/git-annex_broken_on_Android_4.3/comment_21_2b39729f95c9c4bba620ecdd3d1558ed._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmqz6wCn-Q1vzrsHGvEJHOt_T5ZESilxhc"
+ nickname="Sören"
+ subject="Galaxy S4 Android 4.3"
+ date="2013-11-11T18:47:23Z"
+ content="""
+hello and hello.stripped both work here but the git-annex binaries don't (still the same error as in the bug report).
+"""]]
diff --git a/doc/bugs/git-annex_broken_on_Android_4.3/comment_22_8d90d92951919aa70638b31e9248bec5._comment b/doc/bugs/git-annex_broken_on_Android_4.3/comment_22_8d90d92951919aa70638b31e9248bec5._comment
new file mode 100644
index 000000000..e4937e0f8
--- /dev/null
+++ b/doc/bugs/git-annex_broken_on_Android_4.3/comment_22_8d90d92951919aa70638b31e9248bec5._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnegApaT6kTI0Gxy9SNmI9Og-k_fC_aS7Y"
+ nickname="Michael Alan"
+ subject="Both fail..."
+ date="2013-11-11T18:53:34Z"
+ content="""
+Same linking issue for both.
+
+I don't *think* it should make any difference at all, but to spare myself a little bit of typing on this soft keyboard, I'm using a small variation on your script; I'm sharing it so other testers can use it, too, and so someone can point out if I'm doing something wrong:
+
+ D=/data/data/ga/androidterm/tmp/gatest
+ cp <file> $D
+ chmod +x $D
+ $D
+
+"""]]
diff --git a/doc/bugs/git-annex_broken_on_Android_4.3/comment_23_6398271f5cd9e94996202ef3bce6f6ed._comment b/doc/bugs/git-annex_broken_on_Android_4.3/comment_23_6398271f5cd9e94996202ef3bce6f6ed._comment
new file mode 100644
index 000000000..05cb634e6
--- /dev/null
+++ b/doc/bugs/git-annex_broken_on_Android_4.3/comment_23_6398271f5cd9e94996202ef3bce6f6ed._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.246"
+ subject="comment 23"
+ date="2013-11-11T19:14:59Z"
+ content="""
+Script variation is ok.
+
+So, it's looking like perhaps a problem with the way cabal links the executable, which I notice is a two stage process, vs the way ghc links it with --make.
+
+To narrow down, here is hello built using cabal:
+
+<http://tmp.kitenet.net/hello-cabal>
+
+Here is git-annex built not using cabal:
+
+<http://tmp.kitenet.net/git-annex-byhand>
+
+(For my own reference, it's also built without WITH_CLIBS.)
+"""]]
diff --git a/doc/bugs/git-annex_broken_on_Android_4.3/comment_24_c9e399833cc6235077161f490dfa866f._comment b/doc/bugs/git-annex_broken_on_Android_4.3/comment_24_c9e399833cc6235077161f490dfa866f._comment
new file mode 100644
index 000000000..c8fea212b
--- /dev/null
+++ b/doc/bugs/git-annex_broken_on_Android_4.3/comment_24_c9e399833cc6235077161f490dfa866f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmqz6wCn-Q1vzrsHGvEJHOt_T5ZESilxhc"
+ nickname="Sören"
+ subject="comment 24"
+ date="2013-11-11T19:56:04Z"
+ content="""
+hello-cabal working, git-annex-byhand not.
+"""]]
diff --git a/doc/bugs/git-annex_broken_on_Android_4.3/comment_25_cf093737eefb2b99f6f0eac9bf3e74b3._comment b/doc/bugs/git-annex_broken_on_Android_4.3/comment_25_cf093737eefb2b99f6f0eac9bf3e74b3._comment
new file mode 100644
index 000000000..e28a9508b
--- /dev/null
+++ b/doc/bugs/git-annex_broken_on_Android_4.3/comment_25_cf093737eefb2b99f6f0eac9bf3e74b3._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnegApaT6kTI0Gxy9SNmI9Og-k_fC_aS7Y"
+ nickname="Michael Alan"
+ subject="I got the same results as Sören."
+ date="2013-11-11T20:37:08Z"
+ content="""
+cabal doesn't seem to be the culprit.
+
+"""]]
diff --git a/doc/bugs/git-annex_broken_on_Android_4.3/comment_26_c122ce53175fc9e0e114a8acd2385c0d._comment b/doc/bugs/git-annex_broken_on_Android_4.3/comment_26_c122ce53175fc9e0e114a8acd2385c0d._comment
new file mode 100644
index 000000000..1c72cd27b
--- /dev/null
+++ b/doc/bugs/git-annex_broken_on_Android_4.3/comment_26_c122ce53175fc9e0e114a8acd2385c0d._comment
@@ -0,0 +1,29 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.246"
+ subject="finally getting debugger spun up"
+ date="2013-11-12T01:08:24Z"
+ content="""
+<https://code.google.com/p/android/issues/detail?id=28598> seems relevant (and the patches to fix it seem likely to have led to the linker rejecting this).
+
+So I can probably stop torturing your soft keyboards. I need a binary where `arm-linux-androideabi-4.8/bin/arm-linux-androideabi-readelf -r` does not contain `R_ARM_COPY`. Checking against the binaries so far, this consistently matches the test results, all the git-annex binaries have:
+
+<pre>
+ Offset Info Type Sym.Value Sym. Name
+011d05f0 00004e14 R_ARM_COPY 011d05f0 environ
+</pre>
+
+(Which is itself interesting; I've had to work around some problems with the haskell port not supporting getting the environment (Annex.Branch.withIndex). Possibly because it was copied and the linker screwed that up? <https://github.com/neurocyte/ghc-android/issues/7>)
+
+Ok, here's a binary that meets those criteria. Obtained by passing -z nocopyreloc to the gold linker (ghc options -optl-z -optlnocopyreloc)
+
+<http://tmp.kitenet.net/git-annex-nocopy>
+
+Also, here's a hello world binary that *should* fail. It attempts to read and print the environment, and has the same `R_ARM_COPY` relocation.
+
+<http://tmp.kitenet.net/hello-env-copy>
+
+And, here's a hello world binary that *might* successfully print out the full environment (like `set` does). If it does, I can also remove the ugly hack in Annex.Branch.withIndex. Which would be an unexpected reward.
+
+<http://tmp.kitenet.net/hello-env-nocopy>
+"""]]
diff --git a/doc/bugs/git-annex_broken_on_Android_4.3/comment_27_237e41e61781bb058f5fd39362a904e4._comment b/doc/bugs/git-annex_broken_on_Android_4.3/comment_27_237e41e61781bb058f5fd39362a904e4._comment
new file mode 100644
index 000000000..dd911955a
--- /dev/null
+++ b/doc/bugs/git-annex_broken_on_Android_4.3/comment_27_237e41e61781bb058f5fd39362a904e4._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnegApaT6kTI0Gxy9SNmI9Og-k_fC_aS7Y"
+ nickname="Michael Alan"
+ subject="nocopy variants work!"
+ date="2013-11-12T03:17:09Z"
+ content="""
+I tested both the hello-env-nocopy and the git-annex-nocopy binaries successfully. hello-env-copy failed as you predicted.
+
+Yay!
+"""]]
diff --git a/doc/bugs/git-annex_broken_on_Android_4.3/comment_28_97f423a41ee9d2d74291594fae20dd4e._comment b/doc/bugs/git-annex_broken_on_Android_4.3/comment_28_97f423a41ee9d2d74291594fae20dd4e._comment
new file mode 100644
index 000000000..6341aae80
--- /dev/null
+++ b/doc/bugs/git-annex_broken_on_Android_4.3/comment_28_97f423a41ee9d2d74291594fae20dd4e._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.246"
+ subject="comment 28"
+ date="2013-11-12T03:58:56Z"
+ content="""
+This fix is now in place in the android autobuilds.
+
+Just to be sure, hello-env-nocopy managed to print out multiple environment variables?
+"""]]
diff --git a/doc/bugs/git-annex_broken_on_Android_4.3/comment_29_7b3fbe7e38f637fcea511441ac243d93._comment b/doc/bugs/git-annex_broken_on_Android_4.3/comment_29_7b3fbe7e38f637fcea511441ac243d93._comment
new file mode 100644
index 000000000..1cd4c356f
--- /dev/null
+++ b/doc/bugs/git-annex_broken_on_Android_4.3/comment_29_7b3fbe7e38f637fcea511441ac243d93._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmqz6wCn-Q1vzrsHGvEJHOt_T5ZESilxhc"
+ nickname="Sören"
+ subject="APK now works too"
+ date="2013-11-12T09:10:49Z"
+ content="""
+I got the same results as Michael. The output of hello-nocopy is a longer list of environment variables.
+Even better, the apk from the autobuilder now seems to work fine as well, including the webapp.
+Great work! Thanks for digging into this.
+"""]]
diff --git a/doc/bugs/git-annex_broken_on_Android_4.3/comment_2_53e2d095b2501844cadec910de286814._comment b/doc/bugs/git-annex_broken_on_Android_4.3/comment_2_53e2d095b2501844cadec910de286814._comment
new file mode 100644
index 000000000..3d5003504
--- /dev/null
+++ b/doc/bugs/git-annex_broken_on_Android_4.3/comment_2_53e2d095b2501844cadec910de286814._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 2"
+ date="2013-08-28T13:54:00Z"
+ content="""
+On a stock Nexus 7 running the latest OS (4.3), this is still the case as of release 4.20130827.
+
+ Falling back to hardcoded app location; cannot find expected files in /data/app-lib
+ git annex webapp
+ u0_a18@grouper:/sdcard/git-annex.home $ git annex webapp
+ CANNOT LINK EXECUTABLE: git-annex invalid R_ARM_COPY relocation against DT_SYMBOLIC shared library libc.so (built with -Bsymbolic?)
+ 1|u0_a18@grouper:/sdcard/git-annex.home $
+"""]]
diff --git a/doc/bugs/git-annex_broken_on_Android_4.3/comment_30_26c04584c3c6dacf59e1b6c82042c97c._comment b/doc/bugs/git-annex_broken_on_Android_4.3/comment_30_26c04584c3c6dacf59e1b6c82042c97c._comment
new file mode 100644
index 000000000..3409b9c4a
--- /dev/null
+++ b/doc/bugs/git-annex_broken_on_Android_4.3/comment_30_26c04584c3c6dacf59e1b6c82042c97c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnegApaT6kTI0Gxy9SNmI9Og-k_fC_aS7Y"
+ nickname="Michael Alan"
+ subject="Yep, the env was printed"
+ date="2013-11-12T10:18:56Z"
+ content="""
+I would recognize the output of a Show instance anywhere.
+"""]]
diff --git a/doc/bugs/git-annex_broken_on_Android_4.3/comment_3_ddc9cbae1a721400a9acf2153e18f4f0._comment b/doc/bugs/git-annex_broken_on_Android_4.3/comment_3_ddc9cbae1a721400a9acf2153e18f4f0._comment
new file mode 100644
index 000000000..14eed81c9
--- /dev/null
+++ b/doc/bugs/git-annex_broken_on_Android_4.3/comment_3_ddc9cbae1a721400a9acf2153e18f4f0._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkgedYqmQb4dJU7UdVuRLwsQE-KlKVrFto"
+ nickname="Chungy"
+ subject="comment 3"
+ date="2013-09-01T00:25:15Z"
+ content="""
+Just confirming the bug on my Verizon Galaxy S 3 with CyanogenMod 10.2 (Android 4.3), it's not Nexus-specific.
+"""]]
diff --git a/doc/bugs/git-annex_broken_on_Android_4.3/comment_4_593235735e32238094121b1f79355bbd._comment b/doc/bugs/git-annex_broken_on_Android_4.3/comment_4_593235735e32238094121b1f79355bbd._comment
new file mode 100644
index 000000000..ab721064a
--- /dev/null
+++ b/doc/bugs/git-annex_broken_on_Android_4.3/comment_4_593235735e32238094121b1f79355bbd._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawntVnR-Z5ghYInvsElbDeADPSuCsF18iTY"
+ nickname="Thomas"
+ subject="comment 4"
+ date="2013-09-01T20:02:59Z"
+ content="""
+Yet another confirmation of the bug on a Samsung Galaxy Note running 4.3 via Cyanogenmod as well.
+"""]]
diff --git a/doc/bugs/git-annex_broken_on_Android_4.3/comment_5_f806fd5930e90920db24456297465bae._comment b/doc/bugs/git-annex_broken_on_Android_4.3/comment_5_f806fd5930e90920db24456297465bae._comment
new file mode 100644
index 000000000..cfb75bdd8
--- /dev/null
+++ b/doc/bugs/git-annex_broken_on_Android_4.3/comment_5_f806fd5930e90920db24456297465bae._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 5"
+ date="2013-09-03T14:38:51Z"
+ content="""
+If there's anything we can do to help debug this, please let us know. Have just started using git-annex on android recently & would love to have it on all my devices.
+
+"""]]
diff --git a/doc/bugs/git-annex_broken_on_Android_4.3/comment_6_5741b6a5997328fdcd5cc99f841b18d3._comment b/doc/bugs/git-annex_broken_on_Android_4.3/comment_6_5741b6a5997328fdcd5cc99f841b18d3._comment
new file mode 100644
index 000000000..438e00454
--- /dev/null
+++ b/doc/bugs/git-annex_broken_on_Android_4.3/comment_6_5741b6a5997328fdcd5cc99f841b18d3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnRai_qFYPVvEgC6i1nlM1bh-C__jbhqS0"
+ nickname="Matthew"
+ subject="Definitely broken Galaxy Nexus GSM 4.3"
+ date="2013-09-12T11:11:34Z"
+ content="""
+Definitely broken in 4.3, stock Galaxy Nexus GSM \"maguro\" release `2013-09-09 12:46`
+"""]]
diff --git a/doc/bugs/git-annex_broken_on_Android_4.3/comment_7_3e0d9949dd810069af0b8076807e5924._comment b/doc/bugs/git-annex_broken_on_Android_4.3/comment_7_3e0d9949dd810069af0b8076807e5924._comment
new file mode 100644
index 000000000..4a3819472
--- /dev/null
+++ b/doc/bugs/git-annex_broken_on_Android_4.3/comment_7_3e0d9949dd810069af0b8076807e5924._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawknwkXgi8SnK4QT32ANl3GMKvFLyQGeHqo"
+ nickname="Florian"
+ subject="comment 7"
+ date="2013-10-08T16:18:07Z"
+ content="""
+Any comment from on this from one of the maintainers would be great. Apparently this was not fixed in the latest (2013-10-02 18:46) build.
+"""]]
diff --git a/doc/bugs/git-annex_broken_on_Android_4.3/comment_8_f58897eff6b4693f0c73474ccfe6e733._comment b/doc/bugs/git-annex_broken_on_Android_4.3/comment_8_f58897eff6b4693f0c73474ccfe6e733._comment
new file mode 100644
index 000000000..52326b8e2
--- /dev/null
+++ b/doc/bugs/git-annex_broken_on_Android_4.3/comment_8_f58897eff6b4693f0c73474ccfe6e733._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmhfodZquCI_EEl-f3h7HkROTszlsQL6yA"
+ nickname="Joe"
+ subject="Samsung Galaxy S4 also affected"
+ date="2013-11-09T02:47:54Z"
+ content="""
+Verizon just pushed out 4.3 to Samsung Galaxy S4 devices. This issue is affecting me now too.
+"""]]
diff --git a/doc/bugs/git-annex_broken_on_Android_4.3/comment_9_ddba87b2f20d8a63f7b8ebdb9bd13515._comment b/doc/bugs/git-annex_broken_on_Android_4.3/comment_9_ddba87b2f20d8a63f7b8ebdb9bd13515._comment
new file mode 100644
index 000000000..015efd7ce
--- /dev/null
+++ b/doc/bugs/git-annex_broken_on_Android_4.3/comment_9_ddba87b2f20d8a63f7b8ebdb9bd13515._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.246"
+ subject="comment 9"
+ date="2013-11-10T20:12:47Z"
+ content="""
+I have finally managed to get ghc to build with the newest version of the NDK. I hope this means it will make binaries that work with 4.3, but I don't have a device to test.
+
+Here is a hello world program built with it:
+<http://tmp.kitenet.net/hello>
+
+After downloading it to an Android device, you can test it by opening the
+git-annex terminal, and running: `D=/data/data/ga.androidterm/tmp; cp hello $D; chmod +x $D/hello; $D/hello`
+
+Tested working on android 4.0.4
+
+Also, I have filed a bug upstream about this at <https://github.com/neurocyte/ghc-android/issues/23>
+"""]]
diff --git a/doc/bugs/git-annex_direct_fails_on_repositories_with_a_partial_set_of_files.mdwn b/doc/bugs/git-annex_direct_fails_on_repositories_with_a_partial_set_of_files.mdwn
new file mode 100644
index 000000000..de88b0246
--- /dev/null
+++ b/doc/bugs/git-annex_direct_fails_on_repositories_with_a_partial_set_of_files.mdwn
@@ -0,0 +1,29 @@
+## What steps will reproduce the problem?
+
+Running the following in an annex with an archive directory with all the files dropped and located offsite
+
+ git annex direct
+
+It seems that if not all the files are in the annex, then the direct mode files.
+
+## What is the expected output? What do you see instead?
+
+The expectation is that either direct mode reverts its changes if it fails instead of
+
+ url: createLink: does not exist (No such file or directory)
+ failed
+ git-annex: direct: 1 failed
+
+It leaves the annex in the indirect mode, but there are a bunch of .map files lying around in git-annex's control directory.
+
+## What version of git-annex are you using? On what operating system?
+
+Running 3.20130102 on OSX
+
+## Please provide any additional information below.
+
+> More specifically, git annex direct fails, on OSX only, when there are two
+> files that both have the same content. Apparently OSX doesn't allow
+> hard linking two symbolic links together. There was no harm in it doing that
+> otherwise, but then again no reason for it to do so, so I've put in a fix.
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/git-annex_directory_hashing_problems_on_osx.mdwn b/doc/bugs/git-annex_directory_hashing_problems_on_osx.mdwn
new file mode 100644
index 000000000..db6a35293
--- /dev/null
+++ b/doc/bugs/git-annex_directory_hashing_problems_on_osx.mdwn
@@ -0,0 +1,100 @@
+Currently the hashed directories in .git-annex allow for upper and lower case directory names... on linux (or any case sensitive filesystem) the directory names such as 'Gg' and 'GG' are different and unique. However on systems like OSX (and probably windows if it is ever supported) the directory names 'Gg' is the same as 'GG'
+
+In one of the annex'd repos that I have this has occured...
+
+<pre>
+$ git add -i
+ staged unstaged path
+ 1: unchanged +1/-1 .git-annex/GM/GV/WORM-s183630166-m1301072171--somefile.log
+ 2: unchanged +1/-1 .git-annex/Gm/GV/WORM-s183630166-m1301072171--somefile.log
+</pre>
+
+
+this has somewhat confused git when it tries to stage/merge files, I didn't notice this at first, but it is definately a problem for someone using case insensitive filesystems like the default OSX HFS+ formats or vfat/fat32.
+
+> I feel a bit stupid to not have considered case-insensative filesystems.
+> They are just so far from where I have lived for 20 years that it's hard
+> to keep them in mind.
+>
+> I guess that
+> [[git-annex_has_issues_with_git_when_staging__47__commiting_logs]] is
+> somehow a consequence (or cause?) of this, but I don't quite understand
+> how this is causing git to fail to stage files, or stage the same file
+> twice under different capitalizations. git-annex always will run git add
+> on the path with the "correct" capitalization. So unless something else
+> has added the path with the other capitalization (perhaps git add
+> .git-annex manually?) I don't understand how you get to this state.
+> --[[Joey]]
+
+>> I think I got myself into this situation when I copied some files over from a HFS+ partition to a GPFS network share (which is pretty posix compliant) over samba. It probably is related to the [[git-annex_has_issues_with_git_when_staging__47__commiting_logs]]. I thought they were unique enough to have two bug reports logged as one is a git behavioural thing and the other is git-annex specific.
+
+>>> If you copied `.git/` over, perhaps you got a git repo without
+>>> core.ignorecase set right for the filesystem it landed on?
+
+>>>> I usually git clone or do a fresh repository and pull things in, I was also unaware of this ignorecase setting as well.
+
+>>>
+>>> Something like this might reproduce it:
+
+<pre>
+# mkdir test; cd test; git init
+# git config core.ignorecase false
+# mkdir Foo
+# touch Foo/bar
+# git add Foo/bar
+# git add foo/bar
+# git add fOo/bar
+# git status
+# touch foo/other
+# git add fOo/other
+# git status
+</pre>
+
+>>>> And then either git commit or git clone would probably get confused
+>>>> if it thought 3 distinct files had been committed.
+>>>> --[[Joey]]
+
+>>>>> Doing the above test on a HFS+ partition yields this
+
+<pre>
+## with ignorecase=false
+commit bb024c6fd7482b2d10f60ae899cb7a949aca1ad8
+Author: Jimmy Tang <jtang@exia>
+Date: Sun Mar 27 18:40:24 2011 +0100
+
+ commit
+
+diff --git a/Foo/bar b/Foo/bar
+new file mode 100644
+index 0000000..e69de29
+diff --git a/fOo/bar b/fOo/bar
+new file mode 100644
+index 0000000..e69de29
+diff --git a/fOo/other b/fOo/other
+new file mode 100644
+index 0000000..e69de29
+diff --git a/foo/bar b/foo/bar
+new file mode 100644
+index 0000000..e69de29
+</pre>
+
+>>>>> and without changing ignorecase
+
+<pre>
+commit 909a089158ffb98f8e91f98905e2bfdc7234666f
+Author: Jimmy Tang <jtang@exia>
+Date: Sun Mar 27 18:46:57 2011 +0100
+
+ commit
+
+diff --git a/Foo/bar b/Foo/bar
+new file mode 100644
+index 0000000..e69de29
+diff --git a/Foo/other b/Foo/other
+new file mode 100644
+index 0000000..e69de29
+</pre>
+
+> Closing this bug, as it seems I have dealt with it adequately now.
+> [[done]]
+> --[[Joey]]
diff --git a/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_10_f3594de3ba2ab17771a4b116031511bb._comment b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_10_f3594de3ba2ab17771a4b116031511bb._comment
new file mode 100644
index 000000000..c3e6b5e59
--- /dev/null
+++ b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_10_f3594de3ba2ab17771a4b116031511bb._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 10"
+ date="2011-04-01T16:11:52Z"
+ content="""
+No, I don't need a copy of your repo now.
+"""]]
diff --git a/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_11_97de7252bf5d2a4f1381f4b2b4e24ef8._comment b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_11_97de7252bf5d2a4f1381f4b2b4e24ef8._comment
new file mode 100644
index 000000000..db605f965
--- /dev/null
+++ b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_11_97de7252bf5d2a4f1381f4b2b4e24ef8._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 11"
+ date="2011-04-02T17:53:58Z"
+ content="""
+I have pushed out a preliminary fix. The old mixed-case directories will be left where they are, and still read from by git-annex. New data will be written to new, lower-case directories. I think that once git stops seeing changes being made
+to mixed-case, colliding directories, the bugs you ran into won't manifest any more.
+
+You will need to find a way to get your git repository out of the state where it complains about uncommitted files (and won't let you commit them). I have not found a reliable way to do that; git reset --hard worked in one case but not in another. May need to clone a fresh git repository.
+
+Let me know how it works out.
+"""]]
diff --git a/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_12_f1c53c3058a587185e7a78d84987539d._comment b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_12_f1c53c3058a587185e7a78d84987539d._comment
new file mode 100644
index 000000000..5f9a0ae27
--- /dev/null
+++ b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_12_f1c53c3058a587185e7a78d84987539d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 12"
+ date="2011-04-02T17:58:24Z"
+ content="""
+Also, you can delete `.git-annex/??` if you want to, then running `git annex fsck --fast` in each of your clones would regenerate the data using only the lower-case hash directories.
+"""]]
diff --git a/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_13_4f56aea35effe5c10ef37d7ad7adb48c._comment b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_13_4f56aea35effe5c10ef37d7ad7adb48c._comment
new file mode 100644
index 000000000..b4a5a72d0
--- /dev/null
+++ b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_13_4f56aea35effe5c10ef37d7ad7adb48c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 13"
+ date="2011-04-03T07:43:37Z"
+ content="""
+Ok, thanks for the fix. It seems the fix isn't too reliable with my repos, I get different numbers of \"** No known copies of...\" in the various cloned repos that I have. After all the \"messing\" that I have done to my repos I think git-annex has gotten very confused. I will just leave things as they are and let git-annex slowly migrate over to the new format or re-clone from a linux source and see how things go. I will report back on this issue in abit after I use it more to see.
+"""]]
diff --git a/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_14_cc2a53c31332fe4b828ef1e72c2a4d49._comment b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_14_cc2a53c31332fe4b828ef1e72c2a4d49._comment
new file mode 100644
index 000000000..b92c3ab4a
--- /dev/null
+++ b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_14_cc2a53c31332fe4b828ef1e72c2a4d49._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 14"
+ date="2011-04-03T08:24:17Z"
+ content="""
+I meant to say in it wasn't reliable when I was following the instructions for \"Comment 12\". I did find that just doing a \"git annex copy -t externalusb .\" then a \"git annex drop .\" from the root of my cloned and \"none trusted\" annexed repos to be more reliable, it just means I temporarily need a load of space to get myself out of my earlier mess.
+
+On testing this bug fix, I found a minor behavioural issue with [[git annex copy -f REMOTE . doesn't work as expected]]
+"""]]
diff --git a/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_15_37f1d669c1fa53ee371f781c7bb820ae._comment b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_15_37f1d669c1fa53ee371f781c7bb820ae._comment
new file mode 100644
index 000000000..d722d546a
--- /dev/null
+++ b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_15_37f1d669c1fa53ee371f781c7bb820ae._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="gernot"
+ ip="213.168.117.192"
+ subject="comment 15"
+ date="2011-04-03T15:41:00Z"
+ content="""
+I also ran into problems on a case-insensitive HFS+ file system, it seems. I
+tried following the instructions in comment 12:
+
+ 1. Remove everything in .git-annex besides uuid.log and trust.log
+ 2. git annex fsck --fast
+ 3. Commit
+
+However, I still see upper and lower case directories in .git-annex. Did I
+misunderstand that they should all be lower case now?
+
+"""]]
diff --git a/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_16_8a4ab1af59098f4950726cf53636c2b3._comment b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_16_8a4ab1af59098f4950726cf53636c2b3._comment
new file mode 100644
index 000000000..97eab78c9
--- /dev/null
+++ b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_16_8a4ab1af59098f4950726cf53636c2b3._comment
@@ -0,0 +1,22 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 16"
+ date="2011-04-03T16:02:33Z"
+ content="""
+I think the correct steps should be, make a backup first :) then ...
+
+1. git pull # update your clone, and commit everything so you don't lose anything
+2. git annex fsck --fast # check the repo first, just in case
+3. rm -rf .git-annex/?? # remove the old metadata
+4. git annex fsck --fast # get git annex to regenerate it all
+5. push your changes out to your other repos, you will need to make sure git-annex is updated everywhere if there are remotes in your setup.
+
+I eventually migrated all of my own annex'd repos and I no longer have the old hashed directories but the new ones in the form
+
+ .git/annex/aaa/bbb/foo.log
+
+I did lose some tracking information but not data (as far as I can see for now), but that was quickly fixed by pushing and pulling to my bare repo which tracks most of my data.
+
+I also found that it worked a bit more reliably for me on the copies of repos that were located on case sensitive filesystems, but I guess that was expected.
+"""]]
diff --git a/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_17_515d5c5fbf5bd0c188a4f1e936d913e2._comment b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_17_515d5c5fbf5bd0c188a4f1e936d913e2._comment
new file mode 100644
index 000000000..f7feac67c
--- /dev/null
+++ b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_17_515d5c5fbf5bd0c188a4f1e936d913e2._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 17"
+ date="2011-04-03T16:53:51Z"
+ content="""
+@gernot step 0 is to upgrade git-annex to current git, on all systems where you use it, in case that wasn't clear.
+
+"""]]
diff --git a/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_18_db64c91dd1322a0ab168190686db494f._comment b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_18_db64c91dd1322a0ab168190686db494f._comment
new file mode 100644
index 000000000..550558ec1
--- /dev/null
+++ b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_18_db64c91dd1322a0ab168190686db494f._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="gernot"
+ ip="213.168.117.192"
+ subject="comment 18"
+ date="2011-04-03T19:46:16Z"
+ content="""
+Joey, sorry, I got it wrong. I thought upgrading git didn't help and you
+adjusted things in git-annex instead.
+
+Anyway, can I get around upgrading on all hosts by reformatting the drive to
+case-sensitive HFS+? Or will I have to upgrade git (currently version 1.7.2.5)
+eventually anyway?
+
+"""]]
diff --git a/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_19_ff555c271637af065203ca99c9eeaf89._comment b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_19_ff555c271637af065203ca99c9eeaf89._comment
new file mode 100644
index 000000000..2676b3589
--- /dev/null
+++ b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_19_ff555c271637af065203ca99c9eeaf89._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 19"
+ date="2011-04-03T19:53:44Z"
+ content="""
+Git does not need to be upgraded. Git-annex needs to be upgraded to git rev 616e6f8a840ef4d99632d12a2e7ea15c3cfb1805 or newer, on all machines.
+"""]]
diff --git a/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_1_9a7b09de132097100c1a68ea7b846727._comment b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_1_9a7b09de132097100c1a68ea7b846727._comment
new file mode 100644
index 000000000..aa5e46ca2
--- /dev/null
+++ b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_1_9a7b09de132097100c1a68ea7b846727._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 1"
+ date="2011-03-28T07:23:41Z"
+ content="""
+One possible work around is to just create a loopback file system with a case sensitive filesystem. I think I might do that for anything that I really care about for now.
+"""]]
diff --git a/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_20_7e328b970169fffb8bce373d1522743b._comment b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_20_7e328b970169fffb8bce373d1522743b._comment
new file mode 100644
index 000000000..8f0f5ef18
--- /dev/null
+++ b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_20_7e328b970169fffb8bce373d1522743b._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="ssqq"
+ ip="208.70.196.4"
+ subject="Still a problem on 0.20110523"
+ date="2011-06-02T20:31:55Z"
+ content="""
+Hi,
+
+(I'm new to git and git annex, so please forgive any mistakes I make...)
+
+My repo is messed up right now. The fact that I copied the repo with rsync -a back and forth from a case insensitive filesystem to a case sensitive one, probably didn't help.
+
+I believe the annexed files in .git/annex/objects/ are still using a mixed case directory hashing scheme. That's the problem I'm having. The symlinks point to the wrong case and are now broken. I don't think the latest versions of git-annex changed that (it only changed the hashing under .git-annex, right?).
+
+Even if I clean up my repo, I think I'm still going to have a problem because I have one repo on an OS X case insensitive filesystem and my other repos on case sensitive Linux filesystems. Potentially the directory name under .git/annex/objects will have a different case. Then the symlink might have a different case than my Linux FS. Does git-annex track changes in git by the contents of the symlink? In which case the case difference would show up as a change even though there is no change?
+
+Is it possible to change the directory hashing scheme under .git/annex/objects to use lowercase names?
+
+"""]]
diff --git a/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_21_98f632652b0db9131b0173d3572f4d62._comment b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_21_98f632652b0db9131b0173d3572f4d62._comment
new file mode 100644
index 000000000..453a8be11
--- /dev/null
+++ b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_21_98f632652b0db9131b0173d3572f4d62._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 21"
+ date="2011-06-10T16:46:03Z"
+ content="""
+@seqq git-annex always uses the same case when creating and accessing the files pointed to by the symlinks. So it will not matter if it's used on a case-insensative, or case-insensative but preserving system like OSX.
+
+You need to fix up the cases of the files in .git/annex/objects to what it expects. I'm not sure what would be the best way to do that. The method described in [[walkthrough/recover_data_from_lost+found]] might work well.
+"""]]
diff --git a/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_22_52d41afd7fd0b71a4c8e84ab1b4df5bd._comment b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_22_52d41afd7fd0b71a4c8e84ab1b4df5bd._comment
new file mode 100644
index 000000000..7fa1e7468
--- /dev/null
+++ b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_22_52d41afd7fd0b71a4c8e84ab1b4df5bd._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawltmUlf_zHb-hDkjLLYeUxyd81YVoIgZew"
+ nickname="Jaen"
+ subject="Still somewhat broken"
+ date="2012-12-25T17:58:53Z"
+ content="""
+I moved an external HDD formatted with NTFS from Mac (case-insensitive) to Linux (case sensitive), and half of the links are broken now... What can I do to fix this?
+"""]]
diff --git a/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_23_c2cd8a69c37539c0511bae02016180ca._comment b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_23_c2cd8a69c37539c0511bae02016180ca._comment
new file mode 100644
index 000000000..8ec1abd89
--- /dev/null
+++ b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_23_c2cd8a69c37539c0511bae02016180ca._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawltmUlf_zHb-hDkjLLYeUxyd81YVoIgZew"
+ nickname="Jaen"
+ subject="comment 23"
+ date="2012-12-25T20:21:15Z"
+ content="""
+(to be clear, Mac put eg. hashes \"Gg\" and \"gg\" into the same directory, while Linux expects them to be in separate dirs)
+"""]]
diff --git a/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_2_174952fc3e3be12912e5fcfe78f2dd13._comment b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_2_174952fc3e3be12912e5fcfe78f2dd13._comment
new file mode 100644
index 000000000..6e6e5dc6b
--- /dev/null
+++ b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_2_174952fc3e3be12912e5fcfe78f2dd13._comment
@@ -0,0 +1,185 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 2"
+ date="2011-03-28T15:09:45Z"
+ content="""
+I think I know how I got myself into this mess... I was on my mac workstation and I had just pulled in a change set from another repo on a linux workstation after I had a made a bunch of moves. here's a bit of a log of what happened...
+
+
+<pre>
+jtang@x00:~/sources $ git pull cports-devel master
+Warning: untrusted X11 forwarding setup failed: xauth key data not generated
+Warning: No xauth data; using fake authentication data for X11 forwarding.
+remote: Counting objects: 4195, done.
+remote: Compressing objects: 100% (1135/1135), done.
+remote: Total 2582 (delta 866), reused 2576 (delta 860)
+Receiving objects: 100% (2582/2582), 229.42 KiB | 111 KiB/s, done.
+Resolving deltas: 100% (866/866), completed with 9 local objects.
+From cports-devel:/home/people/jtang/sources
+ * branch master -> FETCH_HEAD
+Updating 319df99..ab0a98c
+error: Your local changes to the following files would be overwritten by merge:
+ .git-annex/09/5X/WORM-s361516678-m1301310614--l_fcompxe_intel64_2011.2.137.tgz.log
+ .git-annex/43/2g/WORM-s19509673-m1301310496--l_fcompxe_2011.2.137_redist.tgz.log
+ .git-annex/4J/qF/WORM-s18891115-m1301310934--w_flm_p_1.0.011_ia64.zip.log
+ .git-annex/87/w1/WORM-s12212473-m1301310909--w_flm_p_1.0.011_ia32.zip.log
+ .git-annex/99/Jq/WORM-s194345957-m1301310926--l_mkl_10.3.2.137_ia32.log
+ .git-annex/99/kf/WORM-s9784531-m1301311680--l_ccompxe_2011.2.137_redist.log
+ .git-annex/FF/f3/WORM-s93033394-m1301311706--l_gen_ipp_7.0.2.137.log
+ .git-annex/MF/xZ/WORM-s515140733-m1301310936--l_cprof_p_11.1.075.log
+ .git-annex/XW/X8/WORM-s355559731-m1301310797--l_mkl_10.3.2.137.log
+ .git-annex/fJ/mZ/WORM-s1372886477-m1301313368--l_cproc_p_11.1.075.log
+ .git-annex/j7/Q9/WORM-s44423202-m1301310622--l_cprof_p_11.1.075_redist.log
+ .git-annex/k4/K7/WORM-s239539070-m1301310760--l_mkl_10.3.2.137_intel64.log
+ .git-annex/kz/01/WORM-s279573314-m1301310783--l_cprof_p_11.1.075_ia32.log
+ .git-annex/p6/Kq/WORM-s31199343-m1301311829--l_cproc_p_11.1.075_redist.log
+ .git-annex/pz/J5/WORM-s626995277-m1301312301--l_ccompxe_ia32_2011.2.137.log
+ .git-annex/v3/kX/WORM-s339693045-m1301310851--l_cprof_p_11.1.075_intel64.log
+Please, commit your changes or stash them before you can merge.
+error: Your local changes to the following files would be overwritten by merge:
+ .git-annex/12/3W/WORM-s3058814-m1276699694--Botan-1.8.9.tgz.log
+ .git-annex/1G/qV/WORM-s9122-m1251558854--Array-Compare-2.01.tar.gz.log
+ .git-annex/3W/W5/WORM-s231523-m1270740744--DBD-Pg-2.17.1.tar.gz.log
+ .git-annex/3x/PX/WORM-s380310-m1293025187--HTSeq-0.4.7.tar.gz.log
+ .git-annex/45/gk/WORM-s67337-m1248732018--ExtUtils-Install-1.54.tar.gz.log
+ .git-annex/4J/7Q/WORM-s8608-m1224694862--Algorithm-Munkres-0.08.tar.gz.log
+ .git-annex/4g/XQ/WORM-s89208-m1278682033--HTML-Parser-3.66.tar.gz.log
+ .git-annex/54/jw/WORM-s300163-m1226422051--AcePerl-1.92.tar.gz.log
+ .git-annex/63/kj/WORM-s1213460-m1262942058--DBD-SQLite-1.29.tar.gz.log
+ .git-annex/6Z/42/WORM-s4074-m943766010--File-Sync-0.09.tar.gz.log
+ .git-annex/8F/M5/WORM-s6989-m1263161127--Digest-HMAC-1.02.tar.gz.log
+ .git-annex/G2/FK/WORM-s3309-m1163872981--Bundle-BioPerl-2.1.8.tar.gz.log
+ .git-annex/Gk/XF/WORM-s23572243-m1279546902--EMBOSS-6.3.1.tar.gz.log
+ .git-annex/Jk/X6/WORM-s566429-m1279309002--DBI-1.612.tar.gz.log
+ .git-annex/K6/fV/WORM-s1561451-m1240055295--Convert-Binary-C-0.74.tar.gz.log
+ .git-annex/KM/4q/WORM-s146959-m1268515086--Graph-0.94.tar.gz.log
+ .git-annex/MF/m2/WORM-s425766-m1212514609--Data-Stag-0.11.tar.gz.log
+ .git-annex/QJ/P6/WORM-s1045868-m1282215033--9base-6.tar.gz.log
+ .git-annex/Qm/WG/WORM-s39078-m1278163547--Digest-SHA1-2.13.tar.gz.log
+ .git-annex/Wq/Fj/WORM-s45680640-m1297862101--BclConverter-1.7.1.tar.log
+ .git-annex/Wq/Wm/WORM-s263536640-m1295025537--CASAVA_v1.7.0.tar.log
+ .git-annex/XW/qm/WORM-s36609-m1276050470--Bio-ASN1-EntrezGene-1.10-withoutworldwriteables.tar.gz.log
+ .git-annex/f7/g0/WORM-s40872-m1278273227--ExtUtils-ParseXS-2.2206.tar.gz.log
+ .git-annex/j3/JF/WORM-s11753-m1232427595--Clone-0.31.tar.gz.log
+ .git-annex/kX/9g/WORM-s84690-m1229117599--GraphViz-2.04.tar.gz.log
+ .git-annex/km/z5/WORM-s44634-m1275505134--Authen-SASL-2.15.tar.gz.log
+ .git-annex/kw/J3/WORM-s132396-m1278780649--DBD-mysql-4.016.tar.gz.log
+ .git-annex/p5/1P/WORM-s53736-m1278673485--Archive-Tar-1.64.tar.gz.log
+ .git-annex/wv/zG/WORM-s30584-m1268774021--ExtUtils-CBuilder-0.2703.tar.gz.log
+ .git-annex/x5/7v/WORM-s10462526-m1254242591--BioPerl-1.6.1.tar.gz.log
+Please, commit your changes or stash them before you can merge.
+error: The following untracked working tree files would be overwritten by merge:
+ .git-annex/1g/X3/WORM-s309910751-m1301311322--l_fcompxe_ia32_2011.2.137.tgz.log
+ .git-annex/3w/Xf/WORM-s805764902-m1301312756--l_cproc_p_11.1.075_intel64.log
+ .git-annex/9Q/Wz/WORM-s1234430253-m1301311891--l_ccompxe_2011.2.137.log
+ .git-annex/FQ/4z/WORM-s318168323-m1301310848--l_cprof_p_11.1.075_ia64.log
+ .git-annex/FV/0P/WORM-s710135470-m1301311835--l_ccompxe_intel64_2011.2.137.log
+ .git-annex/Jx/qM/WORM-s599386592-m1301310731--l_fcompxe_2011.2.137.tgz.log
+ .git-annex/KX/w1/WORM-s35976002-m1301312193--l_tbb_3.0.6.174.log
+ .git-annex/Vw/jK/WORM-s15795178-m1301310913--w_flm_p_1.0.011_intel64.zip.log
+ .git-annex/jK/zK/WORM-s374617670-m1301312705--l_ipp_7.0.2.137_intel64.log
+ .git-annex/vK/kv/WORM-s584342291-m1301312669--l_cproc_p_11.1.075_ia64.log
+ .git-annex/vw/v1/WORM-s736986678-m1301312794--l_cproc_p_11.1.075_ia32.log
+ .git-annex/zq/7X/WORM-s343075585-m1301312233--l_ipp_7.0.2.137_ia32.log
+Please move or remove them before you can merge.
+Aborting
+1|jtang@x00:~/sources $ git status
+# On branch master
+# Your branch is ahead of 'origin/master' by 2 commits.
+#
+# Changes to be committed:
+# (use \"git reset HEAD <file>...\" to unstage)
+#
+# modified: .git-annex/09/5X/WORM-s361516678-m1301310614--l_fcompxe_intel64_2011.2.137.tgz.log
+# modified: .git-annex/43/2g/WORM-s19509673-m1301310496--l_fcompxe_2011.2.137_redist.tgz.log
+# modified: .git-annex/4J/qF/WORM-s18891115-m1301310934--w_flm_p_1.0.011_ia64.zip.log
+# modified: .git-annex/87/w1/WORM-s12212473-m1301310909--w_flm_p_1.0.011_ia32.zip.log
+# modified: .git-annex/99/Jq/WORM-s194345957-m1301310926--l_mkl_10.3.2.137_ia32.log
+# modified: .git-annex/99/kf/WORM-s9784531-m1301311680--l_ccompxe_2011.2.137_redist.log
+# modified: .git-annex/FF/f3/WORM-s93033394-m1301311706--l_gen_ipp_7.0.2.137.log
+# modified: .git-annex/MF/xZ/WORM-s515140733-m1301310936--l_cprof_p_11.1.075.log
+# modified: .git-annex/XW/X8/WORM-s355559731-m1301310797--l_mkl_10.3.2.137.log
+# modified: .git-annex/fJ/mZ/WORM-s1372886477-m1301313368--l_cproc_p_11.1.075.log
+# modified: .git-annex/j7/Q9/WORM-s44423202-m1301310622--l_cprof_p_11.1.075_redist.log
+# modified: .git-annex/k4/K7/WORM-s239539070-m1301310760--l_mkl_10.3.2.137_intel64.log
+# modified: .git-annex/kz/01/WORM-s279573314-m1301310783--l_cprof_p_11.1.075_ia32.log
+# modified: .git-annex/p6/Kq/WORM-s31199343-m1301311829--l_cproc_p_11.1.075_redist.log
+# modified: .git-annex/pz/J5/WORM-s626995277-m1301312301--l_ccompxe_ia32_2011.2.137.log
+# modified: .git-annex/v3/kX/WORM-s339693045-m1301310851--l_cprof_p_11.1.075_intel64.log
+#
+# Changes not staged for commit:
+# (use \"git add <file>...\" to update what will be committed)
+# (use \"git checkout -- <file>...\" to discard changes in working directory)
+#
+# modified: .git-annex/12/3W/WORM-s3058814-m1276699694--Botan-1.8.9.tgz.log
+# modified: .git-annex/1G/qV/WORM-s9122-m1251558854--Array-Compare-2.01.tar.gz.log
+# modified: .git-annex/3W/W5/WORM-s231523-m1270740744--DBD-Pg-2.17.1.tar.gz.log
+# modified: .git-annex/3x/PX/WORM-s380310-m1293025187--HTSeq-0.4.7.tar.gz.log
+# modified: .git-annex/45/gk/WORM-s67337-m1248732018--ExtUtils-Install-1.54.tar.gz.log
+# modified: .git-annex/4J/7Q/WORM-s8608-m1224694862--Algorithm-Munkres-0.08.tar.gz.log
+# modified: .git-annex/4g/XQ/WORM-s89208-m1278682033--HTML-Parser-3.66.tar.gz.log
+# modified: .git-annex/54/jw/WORM-s300163-m1226422051--AcePerl-1.92.tar.gz.log
+# modified: .git-annex/63/kj/WORM-s1213460-m1262942058--DBD-SQLite-1.29.tar.gz.log
+# modified: .git-annex/6Z/42/WORM-s4074-m943766010--File-Sync-0.09.tar.gz.log
+# modified: .git-annex/8F/M5/WORM-s6989-m1263161127--Digest-HMAC-1.02.tar.gz.log
+# modified: .git-annex/G2/FK/WORM-s3309-m1163872981--Bundle-BioPerl-2.1.8.tar.gz.log
+# modified: .git-annex/Gk/XF/WORM-s23572243-m1279546902--EMBOSS-6.3.1.tar.gz.log
+# modified: .git-annex/Jk/X6/WORM-s566429-m1279309002--DBI-1.612.tar.gz.log
+# modified: .git-annex/K6/fV/WORM-s1561451-m1240055295--Convert-Binary-C-0.74.tar.gz.log
+# modified: .git-annex/KM/4q/WORM-s146959-m1268515086--Graph-0.94.tar.gz.log
+# modified: .git-annex/MF/m2/WORM-s425766-m1212514609--Data-Stag-0.11.tar.gz.log
+# modified: .git-annex/QJ/P6/WORM-s1045868-m1282215033--9base-6.tar.gz.log
+# modified: .git-annex/Qm/WG/WORM-s39078-m1278163547--Digest-SHA1-2.13.tar.gz.log
+# modified: .git-annex/Wq/Fj/WORM-s45680640-m1297862101--BclConverter-1.7.1.tar.log
+# modified: .git-annex/Wq/Wm/WORM-s263536640-m1295025537--CASAVA_v1.7.0.tar.log
+# modified: .git-annex/XW/qm/WORM-s36609-m1276050470--Bio-ASN1-EntrezGene-1.10-withoutworldwriteables.tar.gz.log
+# modified: .git-annex/Zq/7X/WORM-s343075585-m1301312233--l_ipp_7.0.2.137_ia32.log
+# modified: .git-annex/f7/g0/WORM-s40872-m1278273227--ExtUtils-ParseXS-2.2206.tar.gz.log
+# modified: .git-annex/j3/JF/WORM-s11753-m1232427595--Clone-0.31.tar.gz.log
+# modified: .git-annex/kX/9g/WORM-s84690-m1229117599--GraphViz-2.04.tar.gz.log
+# modified: .git-annex/km/z5/WORM-s44634-m1275505134--Authen-SASL-2.15.tar.gz.log
+# modified: .git-annex/kw/J3/WORM-s132396-m1278780649--DBD-mysql-4.016.tar.gz.log
+# modified: .git-annex/p5/1P/WORM-s53736-m1278673485--Archive-Tar-1.64.tar.gz.log
+# modified: .git-annex/wv/zG/WORM-s30584-m1268774021--ExtUtils-CBuilder-0.2703.tar.gz.log
+# modified: .git-annex/x5/7v/WORM-s10462526-m1254242591--BioPerl-1.6.1.tar.gz.log
+#
+# Untracked files:
+# (use \"git add <file>...\" to include in what will be committed)
+#
+# .git-annex/1G/X3/
+# .git-annex/3W/Xf/
+# .git-annex/9q/Wz/
+# .git-annex/Fq/4z/
+# .git-annex/Jk/zK/
+# .git-annex/Kx/w1/
+# .git-annex/VK/kv/
+# .git-annex/fv/0P/
+# .git-annex/jX/qM/
+# .git-annex/vW/jK/
+# .git-annex/vW/v1/
+jtang@x00:~/sources $ git commit -a -m \"snap\"
+[master 45f254a] snap
+ 47 files changed, 64 insertions(+), 30 deletions(-)
+jtang@x00:~/sources $ git status
+# On branch master
+# Your branch is ahead of 'origin/master' by 3 commits.
+#
+# Untracked files:
+# (use \"git add <file>...\" to include in what will be committed)
+#
+# .git-annex/1G/X3/
+# .git-annex/3W/Xf/
+# .git-annex/9q/Wz/
+# .git-annex/Fq/4z/
+# .git-annex/Jk/zK/
+# .git-annex/Kx/w1/
+# .git-annex/VK/kv/
+# .git-annex/fv/0P/
+# .git-annex/jX/qM/
+# .git-annex/vW/jK/
+# .git-annex/vW/v1/
+nothing added to commit but untracked files present (use \"git add\" to track)
+jtang@x00:~/sources $ git pull
+</pre>
+"""]]
diff --git a/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_3_a18ada7ac74c63be5753fdb2fe68dae5._comment b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_3_a18ada7ac74c63be5753fdb2fe68dae5._comment
new file mode 100644
index 000000000..00988ab58
--- /dev/null
+++ b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_3_a18ada7ac74c63be5753fdb2fe68dae5._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 3"
+ date="2011-03-28T15:25:18Z"
+ content="""
+So, there is evidence here of a circumstance caused by the [[other_bug|git-annex_has_issues_with_git_when_staging__47__commiting_logs]], as I suspected.
+
+I don't think that manual `git commit -a` caused the problem. I suspect it was a subsequent `git add` that caused git to follow the wrong case paths and add the files in the wrong place. Ie, when you run \"git add .git-annex\", it recurses into `.git-annex/Gm/`, and adds files using that case, that were previously added from `.git-annex/GM/`.
+
+For completeness, can you verify this repo's core.ignorecase setting?
+
+---
+
+I hate that you are stuck using loop filesystems to work around this bug. If my guess is correct, you don't need to, as long as you avoid manually running \"git add .git-annex\". I take this bug seriously. While I'm currently very involved in adding Amazon S3 support to git-annex (which will take days more of solid work), I do plan to make a loop filesystem of my own, probably vfat, so I can try and reproduce this on a case-insensative filesystem. If you could confirm my above hypothesis, that would speed things up for me.
+
+It's possible I will have to tweak the hash directories. Hopefully if so, I will only tweak them for *new* keys; if I had to do a v3 backend just to fix this stupid thing, I'd be sad -- upgrading all my offline disks from v1 to v2 took me many days.
+"""]]
diff --git a/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_4_039e945617a6c1852c96974a402db29c._comment b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_4_039e945617a6c1852c96974a402db29c._comment
new file mode 100644
index 000000000..d045f7120
--- /dev/null
+++ b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_4_039e945617a6c1852c96974a402db29c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 4"
+ date="2011-03-28T15:41:56Z"
+ content="""
+In my \"sources\" repo on x00, the current setting is this \"ignorecase = true\" it was the first repo that I created before I clone it elsewhere and pull my changes back, it is on a HFS+ partition which is case insensitive and it is replicated on a portable hdd with a bare repo on a exfat partition. I wonder if my portable disk has a partially borked repo :P
+"""]]
diff --git a/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_5_eacd0b18475c05ab9feed8cf7290b79a._comment b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_5_eacd0b18475c05ab9feed8cf7290b79a._comment
new file mode 100644
index 000000000..7127a6eef
--- /dev/null
+++ b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_5_eacd0b18475c05ab9feed8cf7290b79a._comment
@@ -0,0 +1,37 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 5"
+ date="2011-03-28T15:51:11Z"
+ content="""
+I also failed to mention, that in the case when i have stray log files after what has happened in comment 2, I get this left over after a commit when git is confused...
+
+
+<pre>
+jtang@x00:~/sources $ git status
+# On branch master
+# Your branch is ahead of 'origin/master' by 1 commit.
+#
+# Changes not staged for commit:
+# (use \"git add <file>...\" to update what will be committed)
+# (use \"git checkout -- <file>...\" to discard changes in working directory)
+#
+# modified: .git-annex/1G/X3/WORM-s309910751-m1301311322--l_fcompxe_ia32_2011.2.137.tgz.log
+# modified: .git-annex/3W/Xf/WORM-s805764902-m1301312756--l_cproc_p_11.1.075_intel64.log
+# modified: .git-annex/9Q/Wz/WORM-s1234430253-m1301311891--l_ccompxe_2011.2.137.log
+# modified: .git-annex/FQ/4z/WORM-s318168323-m1301310848--l_cprof_p_11.1.075_ia64.log
+# modified: .git-annex/FV/0P/WORM-s710135470-m1301311835--l_ccompxe_intel64_2011.2.137.log
+# modified: .git-annex/Jk/zK/WORM-s374617670-m1301312705--l_ipp_7.0.2.137_intel64.log
+# modified: .git-annex/Jx/qM/WORM-s599386592-m1301310731--l_fcompxe_2011.2.137.tgz.log
+# modified: .git-annex/KX/w1/WORM-s35976002-m1301312193--l_tbb_3.0.6.174.log
+# modified: .git-annex/VK/kv/WORM-s584342291-m1301312669--l_cproc_p_11.1.075_ia64.log
+# modified: .git-annex/Vw/jK/WORM-s15795178-m1301310913--w_flm_p_1.0.011_intel64.zip.log
+# modified: .git-annex/Zq/7X/WORM-s343075585-m1301312233--l_ipp_7.0.2.137_ia32.log
+# modified: .git-annex/vW/v1/WORM-s736986678-m1301312794--l_cproc_p_11.1.075_ia32.log
+#
+no changes added to commit (use \"git add\" and/or \"git commit -a\")
+</pre>
+
+
+Up until now I have just been updating the status of the staged files by hand and commiting it on my mac x00, this probably isn't helping. I'd rather not lose the tracking information.
+"""]]
diff --git a/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_6_e55117cb628dc532e468519252571474._comment b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_6_e55117cb628dc532e468519252571474._comment
new file mode 100644
index 000000000..aae020972
--- /dev/null
+++ b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_6_e55117cb628dc532e468519252571474._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 6"
+ date="2011-03-31T18:02:42Z"
+ content="""
+Alright, I have created a case-insensative HFS+ filesystem here on my linux laptop.
+
+I have not been able to trick git into staging the same file with 2 different capitalizations yet.
+
+It might be helpful if you can send me a copy of a git repository where 'git add -i' shows the same file staged with two capitalizations. Leaving out .git/annex of course. (joey@kitenet.net; a tarball would probably work)
+
+It seems that `git add` only started properly working on case insensative filesystems quite recently. The commit in question is 5e738ae820ec53c45895b029baa3a1f63e654b1b, \"Support case folding for git add when core.ignorecase=true\", which was first released in git 1.7.4, January 30, 2011. If you don't yet have that version, that could explain the problem entirely. In about half an hour (dialup!) I will have downloaded an older git and will see if I can reproduce the problem with it.
+"""]]
diff --git a/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_7_0f4f471102e394ebb01da40e4d0fd9f6._comment b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_7_0f4f471102e394ebb01da40e4d0fd9f6._comment
new file mode 100644
index 000000000..92b205bc3
--- /dev/null
+++ b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_7_0f4f471102e394ebb01da40e4d0fd9f6._comment
@@ -0,0 +1,68 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 7"
+ date="2011-03-31T19:08:01Z"
+ content="""
+git 1.7.4 does not make things better. With it, if I add first \"X/foo\" and then \"x/bar\", it commits \"X/bar\".
+
+That will *certainly* cause problems when interoperating with a repo clone on a case-sensative filesystem, since
+git-annex there will not see the location log that git committed to the wrong case directory.
+
+It's possible there is some interoperability problem when pulling from linux like you did, onto HFS+, too. I am not quite sure. Ah, I did find one.. if I clone the repo with \"X/foo\" in it to a case-sensative filesystem, and add a \"x/foo\" there,
+and pull that commit back to HFS+, git says:
+
+<pre>
+ * branch master -> FETCH_HEAD
+Updating 8754149..e3d4640
+Fast-forward
+ x/foo | 1 +
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+ create mode 100644 x/foo
+joey@gnu:/mnt/r4>ls
+X/
+joey@gnu:/mnt/r4>git st
+# On branch master
+# Changes not staged for commit:
+# (use \"git add <file>...\" to update what will be committed)
+# (use \"git checkout -- <file>...\" to discard changes in working directory
+
+# modified: X/foo
+</pre>
+
+Aha -- that lets me reproduce your problem with the same file being staged twice with different capitalizations, too:
+
+<pre>
+joey@gnu:/mnt/r4>echo haaai >| x/foo
+joey@gnu:/mnt/r4>git st
+# On branch master
+# Changes not staged for commit:
+# (use \"git add <file>...\" to update what will be committed)
+# (use \"git checkout -- <file>...\" to discard changes in working directory)
+#
+# modified: X/bar
+# modified: X/foo
+# modified: x/foo
+#
+joey@gnu:/mnt/r4>git commit -a
+fatal: Will not add file alias 'X/Bar' ('x/Bar' already exists in index)
+</pre>
+
+And modified files that git refuses to commit, which entirely explains [[git-annex_has_issues_with_git_when_staging__47__commiting_logs]].
+
+<pre>
+joey@gnu:/mnt/r4>git add X/foo
+joey@gnu:/mnt/r4>git commit X/foo
+# On branch master
+# Changes not staged for commit:
+# (use \"git add <file>...\" to update what will be committed)
+# (use \"git checkout -- <file>...\" to discard changes in working directory)
+#
+# modified: X/bar
+# modified: X/foo
+#
+no changes added to commit (use \"git add\" and/or \"git commit -a\")
+</pre>
+
+I think git is frankly, buggy. It seems I will need to work around this by stopping using mixed case hashing for location logs.
+"""]]
diff --git a/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_8_68e2d6ccdb9622b879e4bc7005804623._comment b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_8_68e2d6ccdb9622b879e4bc7005804623._comment
new file mode 100644
index 000000000..05fe4658d
--- /dev/null
+++ b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_8_68e2d6ccdb9622b879e4bc7005804623._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 8"
+ date="2011-03-31T19:28:02Z"
+ content="""
+I've posted about this on the git mailing list. It's possible that these bugs, which can be shown to affect things other than just git-annex, will be fixed in git.
+
+I will wait a while to see. But am considering making git-annex use all-lowercase hash dirs for the log files. Maybe it could first look for .git-annex/aaaa/bbbb/foo.log, but also look for, read, and merge in any info from
+.git-annex/Aa/Bb/foo.log. And always write to the new style filenames. This would avoid confusing git with changes to
+mixed-case files, and avoid another massive transition.
+"""]]
diff --git a/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_9_45b11ddd200261115b653c7a14d28aa9._comment b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_9_45b11ddd200261115b653c7a14d28aa9._comment
new file mode 100644
index 000000000..8dfe74642
--- /dev/null
+++ b/doc/bugs/git-annex_directory_hashing_problems_on_osx/comment_9_45b11ddd200261115b653c7a14d28aa9._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 9"
+ date="2011-03-31T21:32:10Z"
+ content="""
+I'm was running git 1.7.4.1 at the time when I came across it, I have just upgraded to 1.7.4.2. I've also just moved to using a loopback fs for the stuff i care about. Do you still want a repo that exhibits the problem (excluding the .git/annex data) ??? I'm also not sure if 1.7.4.2 has corrected the problem yet as I haven't done much with my repos since. I suspect just making all the .git-annex hashed directories seems to be lower case might be better in the long run.
+"""]]
diff --git a/doc/bugs/git-annex_does_not_install_on_windows_without_admin_rights.mdwn b/doc/bugs/git-annex_does_not_install_on_windows_without_admin_rights.mdwn
new file mode 100644
index 000000000..b36d5e84c
--- /dev/null
+++ b/doc/bugs/git-annex_does_not_install_on_windows_without_admin_rights.mdwn
@@ -0,0 +1,19 @@
+### Please describe the problem.
+
+Installing on Windows requires installing git followed by git-annex. Installing the former works without admin rights, but the latter cannot be installed afterwards.
+
+### What steps will reproduce the problem?
+
+1. Create a Windows account without admin rights
+2. Install git
+3. Install git-annex
+
+### What version of git-annex are you using? On what operating system?
+
+Latest release on MS Windows.
+
+### Please provide any additional information below.
+
+
+Installing git creates read-only directories that cannot be used by the git-annex install afterwards. Without admin rights, the read-only flag of the git dir cannot be altered.
+
diff --git a/doc/bugs/git-annex_does_not_install_on_windows_without_admin_rights/comment_1_2533800ab5a95c5d71c3b47a630e751a._comment b/doc/bugs/git-annex_does_not_install_on_windows_without_admin_rights/comment_1_2533800ab5a95c5d71c3b47a630e751a._comment
new file mode 100644
index 000000000..32fc0311e
--- /dev/null
+++ b/doc/bugs/git-annex_does_not_install_on_windows_without_admin_rights/comment_1_2533800ab5a95c5d71c3b47a630e751a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.64"
+ subject="comment 1"
+ date="2013-11-26T16:19:41Z"
+ content="""
+Thanks, this had been reported in the forum before, but they did not point at the directory permissions as the problem.
+
+It would be possible to modify the installer to install git-annex somewhere else and add it to the PATH, but it seems this is a utter nightmare on windows and I'd have to pull in enormous NSIS scripts from their wiki, of unknown provenance. Which is why I am piggybacking on the git installation's PATH.
+"""]]
diff --git a/doc/bugs/git-annex_does_not_install_on_windows_without_admin_rights/comment_2_5b71785acf16a8d9ea457726599daef3._comment b/doc/bugs/git-annex_does_not_install_on_windows_without_admin_rights/comment_2_5b71785acf16a8d9ea457726599daef3._comment
new file mode 100644
index 000000000..4bd5c2c0e
--- /dev/null
+++ b/doc/bugs/git-annex_does_not_install_on_windows_without_admin_rights/comment_2_5b71785acf16a8d9ea457726599daef3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/bBy7WkgQicYHIiiyj.Vm0TcMbxi2quzbPFef#6f9f7"
+ nickname="Frederik Vanrenterghem"
+ subject="comment 2"
+ date="2013-11-26T21:57:28Z"
+ content="""
+Just wondering how git succeeds in installing as non-admin user. The folder it goes in is also read-only.
+"""]]
diff --git a/doc/bugs/git-annex_doesn__39__t_list_files_containing_ISO8859-15_characters.mdwn b/doc/bugs/git-annex_doesn__39__t_list_files_containing_ISO8859-15_characters.mdwn
new file mode 100644
index 000000000..382ca9a0c
--- /dev/null
+++ b/doc/bugs/git-annex_doesn__39__t_list_files_containing_ISO8859-15_characters.mdwn
@@ -0,0 +1,48 @@
+<h4>What steps will reproduce the problem?</h4>
+<pre><code> git init /tmp/test
+ cd /tmp/test
+ git annex init
+ touch òó ō
+ git annex add òó ō
+ git annex find --include='*'
+</code></pre>
+
+<h4>What is the expected output? What do you see instead?</h4>
+Only <tt>ō</tt> is listed. Files containing ISO8859-15 characters that are not in ASCII-7, such as <tt>òó</tt>, are not listed by
+<code>git annex find --include='*'</code>. On the other hand, <code>git annex find --in=here</code> lists both.
+
+<h4>What version of git-annex are you using? On what operating system?</h4>
+git-annex 4.20130227, on Debian GNU/Linux (sid, i386).
+
+<h4>Please provide any additional information below.</h4>
+<pre><code> ~$ locale
+ LANG=en_US.UTF-8
+ LANGUAGE=en
+ LC_CTYPE="en_US.UTF-8"
+ LC_NUMERIC=C
+ LC_TIME=en_DK.UTF-8
+ LC_COLLATE="en_US.UTF-8"
+ LC_MONETARY="en_US.UTF-8"
+ LC_MESSAGES="en_US.UTF-8"
+ LC_PAPER=sv_SE.UTF-8
+ LC_NAME=sv_SE.UTF-8
+ LC_ADDRESS=sv_SE.UTF-8
+ LC_TELEPHONE=sv_SE.UTF-8
+ LC_MEASUREMENT=sv_SE.UTF-8
+ LC_IDENTIFICATION="en_US.UTF-8"
+ LC_ALL=
+</code></pre>
+
+> Tracked this back to a bug in either the C library or the haskell
+> regex-posix wrpaper around it. I'm not sure which, but I emailed the
+> maintainer of the haskell library. It just doesn't think these
+> things are characters; even `.` fails to match them! Everything should
+> match that...
+>
+> There are apparently quite a lot of bugs on POSIX regex libraries
+> as implemented on different systems:
+> <http://www.haskell.org/haskellwiki/Regex_Posix>
+>
+> It seemed best to jettison this dependency entirely; I've switched it to
+> haskell's pure regex-tdfa library, which works nicely. [[done]]
+> --[[Joey]]
diff --git a/doc/bugs/git-annex_doesn__39__t_list_files_containing_ISO8859-15_characters/comment_1_b84e831298c03b12471fb75da597e365._comment b/doc/bugs/git-annex_doesn__39__t_list_files_containing_ISO8859-15_characters/comment_1_b84e831298c03b12471fb75da597e365._comment
new file mode 100644
index 000000000..17d3d398a
--- /dev/null
+++ b/doc/bugs/git-annex_doesn__39__t_list_files_containing_ISO8859-15_characters/comment_1_b84e831298c03b12471fb75da597e365._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="guilhem"
+ ip="129.16.20.212"
+ subject="comment 1"
+ date="2013-03-08T20:09:02Z"
+ content="""
+Wow, that was fast :-) Many thanks!
+"""]]
diff --git a/doc/bugs/git-annex_dropunused_has_no_effect.mdwn b/doc/bugs/git-annex_dropunused_has_no_effect.mdwn
new file mode 100644
index 000000000..b9b159e3d
--- /dev/null
+++ b/doc/bugs/git-annex_dropunused_has_no_effect.mdwn
@@ -0,0 +1,12 @@
+Hi Joey,
+
+I have a repository with many thousands of unused files. It's hard to know exactly how many because it takes up to 5 seconds to print the name of every single one, so I'm largely guessing based on my knowledge of what I've recently deleted.
+
+When I run `git annex dropunused FOO`, it doesn't matter what `FOO` is -- a number, a range, the word "foo" -- the `dropunused` command returns to the prompt instantly in all cases.
+
+What can I do to drop all these unused files eating up i-nodes? Is there a debug flag I can turn on?
+
+Thanks,
+ John
+
+> added a message [[done]] --[[Joey]]
diff --git a/doc/bugs/git-annex_dropunused_has_no_effect/comment_1_66b581eb7111a9e98c6406ec75b899cf._comment b/doc/bugs/git-annex_dropunused_has_no_effect/comment_1_66b581eb7111a9e98c6406ec75b899cf._comment
new file mode 100644
index 000000000..0624eb27c
--- /dev/null
+++ b/doc/bugs/git-annex_dropunused_has_no_effect/comment_1_66b581eb7111a9e98c6406ec75b899cf._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://launchpad.net/~arand"
+ nickname="arand"
+ subject="comment 1"
+ date="2013-03-03T22:34:27Z"
+ content="""
+Vhat kind of annex is this (direct/indirect, on what filesystem, etc.)?
+
+Also what version of git-annex?
+
+I know that direct mode didn't support dropunused, at least before, and on earlier versions of annex switching back to indirect after deleting things in direct didn't work either for dropunused, if I recall correctly.
+"""]]
diff --git a/doc/bugs/git-annex_dropunused_has_no_effect/comment_2_11c46cd2087511c3d22b7ce7c149b3e9._comment b/doc/bugs/git-annex_dropunused_has_no_effect/comment_2_11c46cd2087511c3d22b7ce7c149b3e9._comment
new file mode 100644
index 000000000..22a8a0c4f
--- /dev/null
+++ b/doc/bugs/git-annex_dropunused_has_no_effect/comment_2_11c46cd2087511c3d22b7ce7c149b3e9._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/2grhJvAC049fJnvALDXek.6MRZMTlg--#eec89"
+ nickname="John"
+ subject="comment 2"
+ date="2013-03-03T22:43:41Z"
+ content="""
+It's a ZFS filesystem, using indirect mode. Here are my version numbers:
+
+ Vulcan:~/src/fpco $ git annex version
+ git-annex version: 4.20130227
+ local repository version: 3
+ default repository version: 3
+ supported repository versions: 3 4
+ upgrade supported from repository versions: 0 1 2
+
+"""]]
diff --git a/doc/bugs/git-annex_dropunused_has_no_effect/comment_3_b1c3d8c6ec4b20727aaa9c4b746531b0._comment b/doc/bugs/git-annex_dropunused_has_no_effect/comment_3_b1c3d8c6ec4b20727aaa9c4b746531b0._comment
new file mode 100644
index 000000000..b1c2ce085
--- /dev/null
+++ b/doc/bugs/git-annex_dropunused_has_no_effect/comment_3_b1c3d8c6ec4b20727aaa9c4b746531b0._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-03-03T23:56:17Z"
+ content="""
+dropunused will do nothing if the number provided to drop is not listed in `.git/annex/unused`
+
+The file should be generated when you run `git annex unused`
+"""]]
diff --git a/doc/bugs/git-annex_dropunused_has_no_effect/comment_4_f05a9a3760858c5ee5c98dd8ab059c28._comment b/doc/bugs/git-annex_dropunused_has_no_effect/comment_4_f05a9a3760858c5ee5c98dd8ab059c28._comment
new file mode 100644
index 000000000..9e18696b1
--- /dev/null
+++ b/doc/bugs/git-annex_dropunused_has_no_effect/comment_4_f05a9a3760858c5ee5c98dd8ab059c28._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/2grhJvAC049fJnvALDXek.6MRZMTlg--#eec89"
+ nickname="John"
+ subject="comment 4"
+ date="2013-03-05T22:43:12Z"
+ content="""
+Ah, thanks Joey, that explains it. An error message to that effect would be great!
+"""]]
diff --git a/doc/bugs/git-annex_fix_not_noticing_file_renames.mdwn b/doc/bugs/git-annex_fix_not_noticing_file_renames.mdwn
new file mode 100644
index 000000000..a68533980
--- /dev/null
+++ b/doc/bugs/git-annex_fix_not_noticing_file_renames.mdwn
@@ -0,0 +1,36 @@
+What steps will reproduce the problem?
+
+ ~$ mkdir testannex
+ ~$ cd testannex/
+ testannex$ git init
+ Initialized empty Git repository in /Users/ed/testannex/.git/
+ testannex$ git annex init "test annex"
+ init test annex ok
+ (Recording state in git...)
+ testannex$ echo "file1" > file1
+ testannex$ git annex add file1
+ add file1 (checksum...) ok
+ (Recording state in git...)
+ testannex$ mkdir directory
+ testannex$ mv file1 directory/
+ testannex$ cat directory/file1
+ cat: directory/file1: No such file or directory
+ testannex$ git annex fix directory/file1
+ git-annex: directory/file1 not found
+
+
+What is the expected output? What do you see instead?
+
+ git annex fix should fix the symlink. It looks like maybe it's *following* the symlink?
+
+What version of git-annex are you using? On what operating system?
+
+ checkout: 20d195f compiled on OS X 10.7 using cabal.
+
+Please provide any additional information below.
+
+ git annex assistant is not noticing file renames either.
+
+> git-annex commands (other than `git annex add`) only operate on files
+> checked into git, which `directory/file1` is not, since you did not use
+> `git mv`. Once you `git add` the file, it'll work. [[done]] --[[Joey]]
diff --git a/doc/bugs/git-annex_fix_not_noticing_file_renames/comment_1_4edd95200d59ec5a5426167b8da8e3f9._comment b/doc/bugs/git-annex_fix_not_noticing_file_renames/comment_1_4edd95200d59ec5a5426167b8da8e3f9._comment
new file mode 100644
index 000000000..589dfbf06
--- /dev/null
+++ b/doc/bugs/git-annex_fix_not_noticing_file_renames/comment_1_4edd95200d59ec5a5426167b8da8e3f9._comment
@@ -0,0 +1,24 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 1"
+ date="2012-12-13T20:14:37Z"
+ content="""
+Thanks for the response! It's good to know how it works right now.
+
+The reason I was expecting it to work on the files even if I moved them without git rename, is this:
+
+Imaginary use case:
+
+I am using git annex assistant, and not using the command line at all. Maybe I don't know anything about git. I am on a machine in the \"client\" group, so it drops content in \"archive\" subdirectories after storing it safely in a repository in the \"backup\" group.
+
+To add content to git annex, I drag and drop it into the git annex directory. Assistant notices, and it gets added to the annex (it is now a symlink). Yay!
+
+To archive content, I drag and drop the file (its symlink actually) from the git annex directory to an annex/archive directory, assistant notices, and it gets moved off to backup directories, and this symlink becomes dead. This doesn't work because git annex assistant doesn't notice renames.
+
+To retrieve content from an archive, I drag and drop the dead link in the archive directory to a parent directory, and git annex notices and grabs the content from a backup somewhere. This doesn't work, because git annex assistant doesn't notice renames.
+
+These kinds of operations are necessary if I'm going to archive and unarchive files, or otherwise move and manage them, while the assistant is running, without using git from the command line.
+
+
+"""]]
diff --git a/doc/bugs/git-annex_fix_not_noticing_file_renames/comment_2_a9a44debefb3bdd4b8ed2d1cf53f2338._comment b/doc/bugs/git-annex_fix_not_noticing_file_renames/comment_2_a9a44debefb3bdd4b8ed2d1cf53f2338._comment
new file mode 100644
index 000000000..33f05eac7
--- /dev/null
+++ b/doc/bugs/git-annex_fix_not_noticing_file_renames/comment_2_a9a44debefb3bdd4b8ed2d1cf53f2338._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.117"
+ subject="comment 2"
+ date="2012-12-13T20:24:32Z"
+ content="""
+The assistant does notice renames, and also automatically fixes links.
+"""]]
diff --git a/doc/bugs/git-annex_fix_not_noticing_file_renames/comment_3_0efb11f35b872b75a3fbc4ebb71ac827._comment b/doc/bugs/git-annex_fix_not_noticing_file_renames/comment_3_0efb11f35b872b75a3fbc4ebb71ac827._comment
new file mode 100644
index 000000000..75c02dda1
--- /dev/null
+++ b/doc/bugs/git-annex_fix_not_noticing_file_renames/comment_3_0efb11f35b872b75a3fbc4ebb71ac827._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 3"
+ date="2012-12-13T20:39:57Z"
+ content="""
+The assistant doesn't seem to be noticing renames or fixing files anymore, for me; that was what got me started on this bug report, though it sounds like I took it in an irrelevant direction by focusing on the command line and \"git annex fix.\"
+
+I'll double check, and submit a new bug report if I can confirm that assistant isn't doing what it should.
+"""]]
diff --git a/doc/bugs/git-annex_get:_requested_key_is_not_present.mdwn b/doc/bugs/git-annex_get:_requested_key_is_not_present.mdwn
new file mode 100644
index 000000000..f4c5b3d09
--- /dev/null
+++ b/doc/bugs/git-annex_get:_requested_key_is_not_present.mdwn
@@ -0,0 +1,41 @@
+### Please describe the problem.
+
+I setup 3 repositories on my laptop and 3 on my server using the webapp, see the following scheme:
+
+Laptop <- sync with -> Server
+
+ /home/fabian/Dokumente (Client) <-> /mnt/raid/Dokumente (Full-Backup)
+ /home/fabian/Bilder (Client) <-> /mnt/raid/Bilder (Full-Backup)
+ /mnt/data-common/Audio (Manual) <-> /mnt/raid/Audio (Full-Backup)
+
+As you can see, the Audio folder is in manual mode on the laptop, so it does not get any files automatically.
+If I now want to get a folder with 'git-annex get' I get the following error:
+
+ fabian@fabian-thinkpad /mnt/data-common/Audio $ git-annex get Musik
+ get Musik/+⁄-/2003 - You Are Here (Bonus Disc)/01 - I've Been Lost.ogg (from eifel.fritz.box__mnt_raid_Audio...)
+ requested key is not present
+ rsync: connection unexpectedly closed (0 bytes received so far) [Receiver]
+ rsync error: error in rsync protocol data stream (code 12) at io.c(605) [Receiver=3.0.9]
+
+ Unable to access these remotes: eifel.fritz.box__mnt_raid_Audio
+
+ Try making some of these repositories available:
+ efe13d8c-2b02-455f-9874-b7043caa332f -- eifel.fritz.box__mnt_raid_Audio (fabian@eifel:/mnt/raid/Audio)
+ failed
+
+### What steps will reproduce the problem?
+
+I do not really know the minimal setup to reproduce this problem.
+
+### What version of git-annex are you using? On what operating system?
+
+git-annex 4.20130417 on Gentoo Linux using Ebuilds from Haskell overlay
+
+> I suspect this was some kind of misconfiguration, or
+> one of the kinds of data corruption that git-annex can automatically heal from.
+>
+> I am pretty sure I didn't make any changes to git-annex that caused
+> the problem to stop happening!
+>
+> While it would be very good to get to the bottom of this, I don't see
+> any benefit to keeping this report open without more info. [[done]] --[[Joey]]
diff --git a/doc/bugs/git-annex_get:_requested_key_is_not_present/comment_1_d4baa6607a61d0e6a7cea1325a5ddf95._comment b/doc/bugs/git-annex_get:_requested_key_is_not_present/comment_1_d4baa6607a61d0e6a7cea1325a5ddf95._comment
new file mode 100644
index 000000000..70c3f77d0
--- /dev/null
+++ b/doc/bugs/git-annex_get:_requested_key_is_not_present/comment_1_d4baa6607a61d0e6a7cea1325a5ddf95._comment
@@ -0,0 +1,26 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-04-27T19:54:42Z"
+ content="""
+This error message means that the file's content is not present on your server.
+
+It seems like git-annex *thinks* the file is there, so it sent it there. But something appears to have happened to it.
+
+You can investigate like this:
+
+* Get the file's key, by running `basename $(git cat-file p 'HEAD:Musik/+⁄-/2003 - You Are Here (Bonus Disc)/01 - I've Been Lost.ogg')`
+* Run `find` in /mnt/raid/Audio on the server, and grep for that key.
+
+If that finds any files, we may have a git-annex bug of some kind.
+
+If it finds an empty directory, that's an indication that the file's content was sent to the server before, but has now somehow gotten deleted.
+
+----
+
+You may also want to run, on the client: `git annex fsck --fast --from eifel.fritz.box__mnt_raid_Audio`
+That will check that all the files it thinks should be on the server are still there. If it says \"fixing location log\",
+then it's found other files that were expected to be on the server but don't seem to be any longer.
+
+"""]]
diff --git a/doc/bugs/git-annex_get:_requested_key_is_not_present/comment_2_b49725488c3db5e00ede7b65ed9d62fa._comment b/doc/bugs/git-annex_get:_requested_key_is_not_present/comment_2_b49725488c3db5e00ede7b65ed9d62fa._comment
new file mode 100644
index 000000000..46a488c20
--- /dev/null
+++ b/doc/bugs/git-annex_get:_requested_key_is_not_present/comment_2_b49725488c3db5e00ede7b65ed9d62fa._comment
@@ -0,0 +1,110 @@
+[[!comment format=mdwn
+ username="https://launchpad.net/~maestro-alubia"
+ nickname="maestro-alubia"
+ subject="comment 2"
+ date="2013-04-29T21:04:30Z"
+ content="""
+Thanks for explaining the error message.
+
+I did some investigation but I am not really understanding what is going on.
+
+But step by step, lets take a file without any confusing characters in filename (e.g. '/'), so we use the file \".directory\".
+
+1.) I run on the client:
+[[!format sh \"\"\"
+fabian@fabian-thinkpad /mnt/data-common/Audio $ ls -la .directory
+lrwxrwxrwx 1 fabian fabian 180 25. Apr 17:15 .directory -> .git/annex/objects/Ff/m9/SHA256E-s91--378daa8e2a232ae5a04d9f6c83003d8ccfe6c8b7547c1789a130ba94017283ed/SHA256E-s91--378daa8e2a232ae5a04d9f6c83003d8ccfe6c8b7547c1789a130ba94017283ed
+fabian@fabian-thinkpad /mnt/data-common/Audio $ basename $(git cat-file -p \"HEAD:.directory\")
+SHA256E-s91--378daa8e2a232ae5a04d9f6c83003d8ccfe6c8b7547c1789a130ba94017283ed
+\"\"\"]]
+
+2.) I run on the server:
+
+[[!format sh \"\"\"
+fabian@eifel:/mnt/raid/Audio$ ls -la .directory
+-rw----r-x 1 fabian fabian 91 Dez 13 17:35 .directory
+fabian@eifel:/mnt/raid/Audio$ basename $(git cat-file -p \"HEAD:.directory\")
+SHA256E-s91--378daa8e2a232ae5a04d9f6c83003d8ccfe6c8b7547c1789a130ba94017283ed
+fabian@eifel:/mnt/raid/Audio$ git-annex fsck .directory
+fsck .directory (checksum...) ok
+\"\"\"]]
+
+So obviously the file is present on the server (it is using direct mode).
+
+3.) On the client again:
+
+[[!format sh \"\"\"
+fabian@fabian-thinkpad /mnt/data-common/Audio $ git-annex get .directory
+get .directory (from eifel.fritz.box__mnt_raid_Audio...)
+ requested key is not present
+rsync: connection unexpectedly closed (0 bytes received so far) [Receiver]
+rsync error: error in rsync protocol data stream (code 12) at io.c(605) [Receiver=3.0.9]
+
+ Unable to access these remotes: eifel.fritz.box__mnt_raid_Audio
+
+ Try making some of these repositories available:
+ efe13d8c-2b02-455f-9874-b7043caa332f -- eifel.fritz.box__mnt_raid_Audio (fabian@eifel:/mnt/raid/Audio)
+failed
+git-annex: get: 1 failed
+fsck .directory (checking eifel.fritz.box__mnt_raid_Audio...) (fixing location log)
+ ** Based on the location log, .directory
+ ** was expected to be present, but its content is missing.
+
+ ** No known copies exist of .directory
+failed
+(Recording state in git...)
+git-annex: fsck: 1 failed
+fabian@fabian-thinkpad /mnt/data-common/Audio $ git-annex get .directory
+get .directory (not available)
+ No other repository is known to contain the file.
+failed
+git-annex: get: 1 failed
+\"\"\"]]
+
+Also running \"git annex sync\" on both sides does not help.
+
+This is the configuration:
+
+Client:
+[[!format sh \"\"\"
+fabian@fabian-thinkpad /mnt/data-common/Audio $ cat .git/config
+[core]
+ repositoryformatversion = 0
+ filemode = true
+ bare = false
+ logallrefupdates = true
+[annex]
+ uuid = a1f816fe-3fce-4887-a85c-b7b9e501a5d7
+ version = 3
+[remote \"eifel.fritz.box__mnt_raid_Audio\"]
+ url = ssh://fabian@git-annex-eifel.fritz.box-fabian_mntraidAudio/mnt/raid/Audio/
+ fetch = +refs/heads/*:refs/remotes/eifel.fritz.box__mnt_raid_Audio/*
+ annex-uuid = efe13d8c-2b02-455f-9874-b7043caa332f
+ annex-cost = 175.0
+\"\"\"]]
+
+Server:
+[[!format sh \"\"\"
+fabian@eifel:/mnt/raid/Audio$ cat .git/config
+[core]
+ repositoryformatversion = 0
+ filemode = true
+ bare = false
+ logallrefupdates = true
+[annex]
+ uuid = efe13d8c-2b02-455f-9874-b7043caa332f
+ version = 3
+ direct = true
+[gc]
+ auto = 0
+[remote \"fabianthinkpad.fritz.box__mnt_datacommon_Audio\"]
+ url = ssh://fabian@git-annex-fabian-thinkpad.fritz.box-fabian_mntdatacommonAudio/mnt/data-common/Audio/
+ fetch = +refs/heads/*:refs/remotes/fabianthinkpad.fritz.box__mnt_datacommon_Audio/*
+ annex-uuid = a1f816fe-3fce-4887-a85c-b7b9e501a5d7
+ annex-cost = 175.0
+\"\"\"]]
+
+Please let me know if you need more information.
+
+Btw: I sent some money to my flattr account so I can support you soon. Thanks again for your work!
+"""]]
diff --git a/doc/bugs/git-annex_get:_requested_key_is_not_present/comment_3_c17a7138579b93c6f14e3444c11664ac._comment b/doc/bugs/git-annex_get:_requested_key_is_not_present/comment_3_c17a7138579b93c6f14e3444c11664ac._comment
new file mode 100644
index 000000000..b43e2fbdc
--- /dev/null
+++ b/doc/bugs/git-annex_get:_requested_key_is_not_present/comment_3_c17a7138579b93c6f14e3444c11664ac._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://launchpad.net/~maestro-alubia"
+ nickname="maestro-alubia"
+ subject="Fixed"
+ date="2013-06-30T11:50:42Z"
+ content="""
+The bug seems to be fixed in recent versions of git-annex (tested with 4.20130601 on \"client\" and 4.20130621 on \"server\"). Everything is now working as expected. Thank you very much for your work!
+"""]]
diff --git a/doc/bugs/git-annex_happily_deleted_most_of_my_files___36____35____38____33__.mdwn b/doc/bugs/git-annex_happily_deleted_most_of_my_files___36____35____38____33__.mdwn
new file mode 100644
index 000000000..db8abfdce
--- /dev/null
+++ b/doc/bugs/git-annex_happily_deleted_most_of_my_files___36____35____38____33__.mdwn
@@ -0,0 +1,58 @@
+### Please describe the problem.
+
+When cloning/syncing a repository (and probably doing some nono's in the process),
+git annex will happily delete files.
+This cost me several files, which just by coincidence were not totally important, still its *very* unsettling.
+
+### What steps will reproduce the problem?
+
+I did not try to exactly reproduce it yet (sorry, no time right now), but here is vaguley what I did (sorry its been a process spread over
+several hours and i was doing lots of other things in parallel so I'm fuzzy about details):
+
+ * have a repository in direct mode on your local harddrive, say ~/myannex
+ * git clone ~/myannex to /usbhd/myannex, git annex init.
+ The usbhd is a FAT, git annex recognizes it as "crippled filessytem".
+ * Git annex get all from ~/myannex. So far, so good.
+ * create several files on ~/myannex, git annex add them
+ * do a git annex add on them, abort it (realizing SHA256E takes forever, so changing to WORM), repeat add
+ (not sure wheter i did a git annex sync here)
+ * create several files on /usbhd/myannex, git annex add them
+ (not sure wheter i did a git annex sync here again)
+
+All repos are in direct mode.
+
+From here on i don't remember the exact order of events, one definite -- probably important -- nono i did,
+was:
+I executed a git annex sync/get on the usbhd in a sub-directory (i.e. not in the git base dir), say /usbhd/myannex/foo/bar/,
+so it went on creating /usbhd/myannex/foo/bar/foo, which of course was not intended.
+However /usbhd/myannex/foo/bar/foo contained FAT-crippled-symlinks to the new files in ~/myannex (good).
+
+In order to avoid a potential messy situation i just renamed /usbhd/myannex/foo to /usbhd/myannex/foo_bak
+(which I just realize while writing this, saved me the hash values of my files, yay :))
+
+However when I tried to repeat the procedure, it seems that the new files would not appear on the usbhd (for a reason i totally don't get, maybe I synced back before realizing my sub-foo mistake).
+When I synced usbhd -> ~/myannex again, git-annex happily deleted my new files there which obviously quite upset me.
+
+Again, sorry for this horribly chaotic description,
+I'll try and deliver a more reproducible description, but for the next 2 weeks at least I'm too busy for that.
+
+
+
+### What version of git-annex are you using? On what operating system?
+
+Archlinux,
+3.9.2-1-ARCH #1 SMP PREEMPT Sat May 11 20:31:08 CEST 2013 x86_64 GNU/Linux
+
+aur/git-annex-bin 4.20131002-1
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
+
+[[!tag moreinfo]]
diff --git a/doc/bugs/git-annex_happily_deleted_most_of_my_files___36____35____38____33__/comment_1_5dd4d1cec069c13184f5dd9efca6721b._comment b/doc/bugs/git-annex_happily_deleted_most_of_my_files___36____35____38____33__/comment_1_5dd4d1cec069c13184f5dd9efca6721b._comment
new file mode 100644
index 000000000..a8994ba9a
--- /dev/null
+++ b/doc/bugs/git-annex_happily_deleted_most_of_my_files___36____35____38____33__/comment_1_5dd4d1cec069c13184f5dd9efca6721b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://droggl.myopenid.com/"
+ ip="92.76.150.86"
+ subject="comment 1"
+ date="2013-10-08T07:46:35Z"
+ content="""
+Just in case you wonder: the most important (in the sense of not backupped elswhere) files where some scripts which i did hash with SHA256E and not with WORM.
+"""]]
diff --git a/doc/bugs/git-annex_happily_deleted_most_of_my_files___36____35____38____33__/comment_2_d9b65fe4cb4bfd58f37e7da5350c6401._comment b/doc/bugs/git-annex_happily_deleted_most_of_my_files___36____35____38____33__/comment_2_d9b65fe4cb4bfd58f37e7da5350c6401._comment
new file mode 100644
index 000000000..8574d974b
--- /dev/null
+++ b/doc/bugs/git-annex_happily_deleted_most_of_my_files___36____35____38____33__/comment_2_d9b65fe4cb4bfd58f37e7da5350c6401._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://cstork.org/"
+ nickname="Chris Stork"
+ subject="git annex get/sync don't delete files"
+ date="2013-10-10T11:43:29Z"
+ content="""
+AFAIU it's impossible for the 'get' subcommand to delete anything because it only copies files to .git/annex/objects.
+
+'sync' should also never delete files because it only adds files to the annex (i.e. checksums them and sets up the links and directories in .git/annex), commits things to git and pulls/pushes the git-annex specific branches to/from other repos.
+
+So I think some other 'nono' must have messed up your files.
+
+If you ever used (maybe unintentionally) used indirect mode there seem to be a rather high chance that some of your otherwise lost content is still in .git/annex/objects. Did you check if there's are any files in .git/annex/objects ?
+"""]]
diff --git a/doc/bugs/git-annex_happily_deleted_most_of_my_files___36____35____38____33__/comment_3_1027187b203addd65af8cf1faf28727d._comment b/doc/bugs/git-annex_happily_deleted_most_of_my_files___36____35____38____33__/comment_3_1027187b203addd65af8cf1faf28727d._comment
new file mode 100644
index 000000000..d5c08fb4f
--- /dev/null
+++ b/doc/bugs/git-annex_happily_deleted_most_of_my_files___36____35____38____33__/comment_3_1027187b203addd65af8cf1faf28727d._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="64.134.31.139"
+ subject="comment 3"
+ date="2013-10-16T20:45:25Z"
+ content="""
+At least part of this sounds like [[direct_mode_assistant_in_subdir_confusion]]. The report is too confused for me to tell if that's the whole of the problem.
+
+Note that git-annex stores files in git, so if it did something wrong, you can switch to indirect mode, and use regular git commands to check out a tree from before the problem occurred.
+"""]]
diff --git a/doc/bugs/git-annex_happily_deleted_most_of_my_files___36____35____38____33__/comment_4_ac65028203ff0cbdb978200235fb4e9c._comment b/doc/bugs/git-annex_happily_deleted_most_of_my_files___36____35____38____33__/comment_4_ac65028203ff0cbdb978200235fb4e9c._comment
new file mode 100644
index 000000000..be972fa9a
--- /dev/null
+++ b/doc/bugs/git-annex_happily_deleted_most_of_my_files___36____35____38____33__/comment_4_ac65028203ff0cbdb978200235fb4e9c._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 4"
+ date="2013-10-26T19:26:22Z"
+ content="""
+I have moreinfoed this bug, until I hear back with a better problem description.
+
+Using `git log --stat` to investigate any commits where files were removed would probably be a useful way to get a handle on what happened.
+"""]]
diff --git a/doc/bugs/git-annex_has_issues_with_git_when_staging__47__commiting_logs.mdwn b/doc/bugs/git-annex_has_issues_with_git_when_staging__47__commiting_logs.mdwn
new file mode 100644
index 000000000..ed629c424
--- /dev/null
+++ b/doc/bugs/git-annex_has_issues_with_git_when_staging__47__commiting_logs.mdwn
@@ -0,0 +1,34 @@
+After a series of pretty convoluted copying files around between annex'd repos and pulling changes around between repos. I noticed that occassionally when git-annex tries to stage files (the `.git-annex/*/*/*logs`) git some times gets wedged and doing a "git commit -a" doesn't seem to work or files might not get added thus leaving a bunch of untracked files or modified files that aren't staged for a commit.
+
+I tried running a *`git rm --cached -f -r *`* then *git add -u .git-annex/* or the usual *git add* then a commit fixes things for me. If I don't do that then my subsequent merges/pulls will fail and result in *no known copies of files* I suspect git-annex might have just touched some file modes and git picked up the changes but got confused since there was no content change. It might also just be a git on OSX thing and it doesn't affect linux/bsd users.
+
+For now it's just a bit of extra work for me when it does occur but it does not seem to occur often.
+
+> What do you mean when you say that git "got wedged"? It hung somehow?
+>
+> If git-annex runs concurrently with another git command that locks
+> the repository, its git add of log files can fail.
+>
+> Update: Also, of course, if you are running a "got annex get" or
+> similar, and ctrl-c it after it has gotten some files, it can
+> end up with unstaged or in some cases un-added log files that git-annex
+> wrote -- since git-annex only stages log files in git on shutdown, and
+> ctrl-c bypasses that.
+> --[[Joey]]
+
+>> It "got wedged" as in git doesn't let me commit anything, even though it tells me that there is stuff to be committed in the staging area.
+
+>>> I've never seen git refuse to commit staged files. There would have to
+>>> be some error message? --[[Joey]]
+
+>>>> there were no error messages at all
+
+>>>>> Can I see a transcript? I'm having difficulty getting my head around
+>>>>> what git is doing. Sounds like the files could just not be `git
+>>>>> added` yet, but I get the impression from other things that you say
+>>>>> that it's not so simple. --[[Joey]]
+
+This turns out to be a bug in git, and I have posted a bug report on the mailing list.
+The git-annex behavior that causes this situation is being handled as
+another bug, [[git-annex directory hashing problems on osx]].
+So, closing this bug report. [[done]] --[[Joey]]
diff --git a/doc/bugs/git-annex_immediately_re-gets_dropped_files.mdwn b/doc/bugs/git-annex_immediately_re-gets_dropped_files.mdwn
new file mode 100644
index 000000000..2368df98d
--- /dev/null
+++ b/doc/bugs/git-annex_immediately_re-gets_dropped_files.mdwn
@@ -0,0 +1,27 @@
+### Please describe the problem.
+
+I have some files that I want to drop from my laptop. However, as soon as I drop them (git-annex drop), the assistant starts to download them again from another repository. At first glance, this seems like a variant of [[bugs/Handling_of_files_inside_and_outside_archive_directory_at_the_same_time]].
+
+I would expect that after an explicit drop command, the files would not be re-downloaded.
+
+The repository that this is happening on is a "client" type, direct-mode repository.
+
+### What steps will reproduce the problem?
+
+ git annex drop drop-test/TestFile.data
+
+### What version of git-annex are you using? On what operating system?
+ git-annex version: 4.20130618-g333cb8e
+ build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP DNS
+ local repository version: 4
+ default repository version: 3
+ supported repository versions: 3 4
+ upgrade supported from repository versions: 0 1 2
+
+ I am running Ubuntu 13.04
+
+### Please provide any additional information below.
+
+log emailed.
+
+> [[done]]; not a bug, should use manual mode if manually deciding which files are in a repository --[[Joey]]
diff --git a/doc/bugs/git-annex_immediately_re-gets_dropped_files/comment_1_09e616a4866e726a48be4febe6375cc8._comment b/doc/bugs/git-annex_immediately_re-gets_dropped_files/comment_1_09e616a4866e726a48be4febe6375cc8._comment
new file mode 100644
index 000000000..3976f08fa
--- /dev/null
+++ b/doc/bugs/git-annex_immediately_re-gets_dropped_files/comment_1_09e616a4866e726a48be4febe6375cc8._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-06-18T21:01:03Z"
+ content="""
+The assistant does not have information to guess why a file has changed, it just sees it has, and takes appropriate action to get it in sync. If you want to manually manage which files are present, you should enable manual mode.
+"""]]
diff --git a/doc/bugs/git-annex_incorrectly_parses_bare_IPv6_addresses.mdwn b/doc/bugs/git-annex_incorrectly_parses_bare_IPv6_addresses.mdwn
new file mode 100644
index 000000000..c94952b49
--- /dev/null
+++ b/doc/bugs/git-annex_incorrectly_parses_bare_IPv6_addresses.mdwn
@@ -0,0 +1,59 @@
+I have a git remote in a git-annex-enabled repository. Here's what it looks like in .git/config:
+
+<pre>
+[remote "renaissance"]
+ url = ssh://[2001:0:53aa:64c:24ef:5ce4:2ef9:cdda]/home/paulproteus/Music/annex/
+ fetch = +refs/heads/*:refs/remotes/renaissance/*
+ annex-uuid = 2992752e-1a13-11e0-ba68-57d3c800da64
+</pre>
+
+I wanted to "git annex get" some data. git-annex appears to pass incorrectly-formatted IPv6 addresses to rsync:
+
+<pre>
+get primary/emusiq/Arab Strap/Monday At The Hug And Pint/01-The Shy Retirer.mp3 (copying from renaissance...)
+ssh: Could not resolve hostname [2001:0:53aa:64c:24ef:5ce4:2ef9:cdda]: Name or service not known
+rsync: connection unexpectedly closed (0 bytes received so far) [Receiver]
+rsync error: unexplained error (code 255) at io.c(601) [Receiver=3.0.7]
+
+ rsync failed -- run git annex again to resume file transfer
+ Unable to access these remotes: renaissance
+ Try making some of these repositories available:
+ 2992752e-1a13-11e0-ba68-57d3c800da64
+failed
+</pre>
+
+In this case, the square brackets should not be there.
+
+I tried changing the .git/config syntax slightly, and got a different, also-incorrect behavior:
+
+<pre>
+[remote "renaissance"]
+ url = [2001:0:53aa:64c:24ef:5ce4:2ef9:cdda]:/home/paulproteus/Music/annex/
+ fetch = +refs/heads/*:refs/remotes/renaissance/*
+ annex-uuid = 2992752e-1a13-11e0-ba68-57d3c800da64
+</pre>
+
+<pre>
+paulproteus@pathi:~/Music/annex$ git annex get
+git-annex: bad url ssh://[2001/~/0:53aa:64c:24ef:5ce4:2ef9:cdda]:/home/paulproteus/Music/annex/
+</pre>
+
+(Note that both these .git/config entries work fine with "git fetch".)
+
+-- Asheesh.
+
+> Technically, this seems to be a bug in the haskell URI library; it honors
+> the `[]` in parsing, but does not remove them when the URI is queried for
+> the host part.
+
+<pre>
+Prelude Network.URI> let (Just u) = parseURI "http://foo@[2001:0:53aa:64c:24ef:5ce4:2ef9:cdda]/bar"
+Prelude Network.URI> let (Just a) = uriAuthority u
+Prelude Network.URI> uriRegName a
+"[2001:0:53aa:64c:24ef:5ce4:2ef9:cdda]"
+Prelude Network.URI> isIPv6address $ uriRegName a
+False
+</pre>
+
+> I have filed a [bug upstream](http://trac.haskell.org/network/ticket/40), and put a workaround in git-annex. [[done]]
+> --[[Joey]]
diff --git a/doc/bugs/git-annex_losing_rsync_remotes_with_encryption_enabled.mdwn b/doc/bugs/git-annex_losing_rsync_remotes_with_encryption_enabled.mdwn
new file mode 100644
index 000000000..8df3608db
--- /dev/null
+++ b/doc/bugs/git-annex_losing_rsync_remotes_with_encryption_enabled.mdwn
@@ -0,0 +1,103 @@
+Somehow git-annex has again lost a complete rsync remote with encryption enabled...
+
+git-annex version was 3.20111111
+
+> "once again" ? When did it do it before?
+
+>> It's the second time i uploaded all the files to an encrypted rsync remote and git-annex is not able to find it anymore. --[[gebi]]
+
+> "lost" ? How is the remote lost?
+
+>> git-annex is not able to find any files on the encrypted rsync remote anymore.
+>> Copy does not copy the content again but drop doesn't find it, thus it's somehow "lost" and in an strange state.
+>> I've also had the state where the content was already on the remote side but git-annex copy would copy it again,
+>> ignoring all the data on the remote side. --[[gebi]]
+
+Both *remoteserver* and *localserver* are rsync remotes with enabled encryption.
+All commands are executed on the git repository on my laptop.
+Target of origin is a gitolite repository without annex support (thus the two rsync remotes).
+
+Is there a way in git-annex to verify that all files fullfill the numcopies, in my case
+numcopies=2, and can be read from the remotes their are on?
+I thought that *copy* would verify that, but seems not.
+
+ % g a copy --to remoteserver tools
+ copy tools/md5_sha1_utility.exe (gpg) (checking remoteserver...) ok
+ copy tools/win32diskimager-RELEASE-0.2-r23-win32.zip (checking remoteserver...) ok
+
+ % g a copy --to localserver tools
+ copy tools/md5_sha1_utility.exe (gpg) (checking localserver...) ok
+ copy tools/win32diskimager-RELEASE-0.2-r23-win32.zip (checking localserver...) ok
+
+ % g a drop tools
+ drop tools/md5_sha1_utility.exe (gpg) (checking localserver...) (checking remoteserver...) (unsafe)
+ Could only verify the existence of 1 out of 2 necessary copies
+
+ Try making some of these repositories available:
+ 718a9b5c-1b4a-11e1-8211-6f094f20e050 -- remoteserver (remote backupserver)
+
+ (Use --force to override this check, or adjust annex.numcopies.)
+ failed
+ drop tools/win32diskimager-RELEASE-0.2-r23-win32.zip (checking localserver...) (checking remoteserver...) (unsafe)
+ Could only verify the existence of 1 out of 2 necessary copies
+
+ Try making some of these repositories available:
+ 718a9b5c-1b4a-11e1-8211-6f094f20e050 -- remoteserver (remote backupserver)
+
+ (Use --force to override this check, or adjust annex.numcopies.)
+ failed
+ git-annex: drop: 2 failed
+
+ % g a fsck tools
+ fsck tools/md5_sha1_utility.exe (checksum...) ok
+ fsck tools/win32diskimager-RELEASE-0.2-r23-win32.zip (checksum...) ok
+
+> Copy does do an explicit check that the content is present on remoteserver,
+> and based on the above, the content was found to be already there,
+> which is why it did not copy it again.
+>
+> Drop does an indentical check that the content is present, and
+> since it failed to find it, I am left thinking something must have
+> happened to the remove in between the copy and the drop to cause the
+> content to go away.
+>
+> What happens if you copy the data to remoteserver again? --[[Joey]]
+
+The commands above are executed within a few seconds and completely repeatable. --[[gebi]]
+
+> In that case, why don't you run the commands with `-d` to see the actual
+> rsync command it's running to check if the content is present.
+> Then you can try repeatedly running the command by hand and see why it
+> sometimes succeeds and sometimes fail.
+
+The commands fail and succeed consistently, not either or.
+git annex copy succeeds consistently with not copying the content to remote because it checks and it's already there.
+
+git annex drop fails consistently with error because content is missing on the exact same remote git annex copy checks
+and thinks the content is there. --[[gebi]]
+
+> The command will be something like this:
+> `rsync --quiet hostname:/dir/file 2>/dev/null`
+>
+> The exit status is what's used to see if content is present -- and
+> currently any failure even a failure to connect is taken to mean it's not
+> present. --[[Joey]]
+
+hm... thats interesting, git annex drop and git annex copy check for different hashes on the same file at the same remote...
+
+git annex drop -d tools/md5_sha1_utility.exe
+> Running: sh ["-c","rsync --quiet 'REMOVED_HOST:annex/work/JF/z7/'\"'\"'GPGHMACSHA1--7ffb3840f0e37aee964352e98808403655e8473a/GPGHMACSHA1--7ffb3840f0e37aee964352e98808403655e8473a'\"'\"'' 2>/dev/null"]
+
+git annex copy --to remoteserver -d tools/md5_sha1_utility.exe
+> Running: sh ["-c","rsync --quiet 'REMOVED_HOST:annex/work/1F/PQ/'\"'\"'GPGHMACSHA1--ff075e57f649300c5698e346be74fb6e22d70e35/GPGHMACSHA1--ff075e57f649300c5698e346be74fb6e22d70e35'\"'\"'' 2>/dev/null"]
+
+And yes, only the hash *annex copy* is checking for exists on the remote side. --[[gebi]]
+
+> Ok, this is due to too aggressive caching of the decrypted cipher
+> for a remote. When dopping, it decrypts localserver's cipher,
+> caches it, and then when checking remoteserver it says hey,
+> here's an already decrypted cipher -- it must be the right one!
+>
+> Problem reproduced here, and fixed. [[done]] --[[Joey]]
+
+THX Joey! -- [[gebi]]
diff --git a/doc/bugs/git-annex_merge_stalls.mdwn b/doc/bugs/git-annex_merge_stalls.mdwn
new file mode 100644
index 000000000..98615e352
--- /dev/null
+++ b/doc/bugs/git-annex_merge_stalls.mdwn
@@ -0,0 +1,16 @@
+### Please describe the problem.
+
+Running git-annex merge shows the output "git-annex merge ", followed by a blinking cursor. The command never seems to end.
+
+### What steps will reproduce the problem?
+
+
+### What version of git-annex are you using? On what operating system?
+
+4.20130827-gd04d9bb on MacOS X Mountain Lion
+
+### Please provide any additional information below.
+
+dtruss output at https://www.dropbox.com/s/4b3yqn7ajfz5el2/annex-merge.log
+
+[[!meta title="no indication when git-annex is stuck waiting for a lock"]]
diff --git a/doc/bugs/git-annex_merge_stalls/comment_1_31578a754945bdcb902c62ff58704bcb._comment b/doc/bugs/git-annex_merge_stalls/comment_1_31578a754945bdcb902c62ff58704bcb._comment
new file mode 100644
index 000000000..123212d5d
--- /dev/null
+++ b/doc/bugs/git-annex_merge_stalls/comment_1_31578a754945bdcb902c62ff58704bcb._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.255.110"
+ subject="comment 1"
+ date="2013-09-09T15:45:17Z"
+ content="""
+The relevant part of the log is:
+
+<pre>
+65332/0x53591a: open(\"/Users/gsolsberry/annex/.git/annex/journal.lck\0\", 0x601, 0x1B6) = 8 0
+65332/0x53591a: fcntl(0x8, 0x9, 0x107009D60) = -1 Err#-1
+</pre>
+
+waitToSetLock thinks fcntl is failing to lock the file due to something else having it locked, and retries, leading to the hang.
+
+I'm told on irc that this was installed using the prebuilt image, and that a previous version of it didn't have the problem.
+"""]]
diff --git a/doc/bugs/git-annex_merge_stalls/comment_2_f3b6bf180466b5931bfd20b2f0229422._comment b/doc/bugs/git-annex_merge_stalls/comment_2_f3b6bf180466b5931bfd20b2f0229422._comment
new file mode 100644
index 000000000..2fe9b8ac0
--- /dev/null
+++ b/doc/bugs/git-annex_merge_stalls/comment_2_f3b6bf180466b5931bfd20b2f0229422._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl8B4Ima-VCCJ4y32Gvfii8EmvTyN9tFGM"
+ nickname="Glendon"
+ subject="comment 2"
+ date="2013-09-09T15:54:59Z"
+ content="""
+With latest 20130909 version, the following log from git-annex merge:
+
+https://www.dropbox.com/s/3hklzfsflpxuk5s/annex-merge.log.1
+"""]]
diff --git a/doc/bugs/git-annex_merge_stalls/comment_3_ced9b0d724fb55c756106b64c3721003._comment b/doc/bugs/git-annex_merge_stalls/comment_3_ced9b0d724fb55c756106b64c3721003._comment
new file mode 100644
index 000000000..382f8c835
--- /dev/null
+++ b/doc/bugs/git-annex_merge_stalls/comment_3_ced9b0d724fb55c756106b64c3721003._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.255.110"
+ subject="comment 3"
+ date="2013-09-09T19:35:25Z"
+ content="""
+This problem cleared up after a reboot (and a crash, apparently).
+
+<pre>
+joeyh so, my thought is that perhaps you had a git-annex process before that was holding the lock.
+joeyh for example, if you ran it and ctrl-z'd at just the right time, it could be suspended and holding the lock
+joeyh (or the kernel coud have gotten confused, which given you also had a crash, who knows..)
+dp sounds logical
+joeyh forcing locks is always a problimatic thing
+joeyh but git-annex could certainly notice if it seems to be stalled and print some useful messages
+joeyh and maybe have a way to run with locks forced
+</pre>
+"""]]
diff --git a/doc/bugs/git-annex_on_crippled_filesystem_can_still_failed_due_to_case_.mdwn b/doc/bugs/git-annex_on_crippled_filesystem_can_still_failed_due_to_case_.mdwn
new file mode 100644
index 000000000..53b993de2
--- /dev/null
+++ b/doc/bugs/git-annex_on_crippled_filesystem_can_still_failed_due_to_case_.mdwn
@@ -0,0 +1,32 @@
+What steps will reproduce the problem?
+
+ $ git clone ~/corbeau/travail/ travail
+ Cloning into 'travail'...
+ done.
+ Checking out files: 100% (8670/8670), done.
+ $ cd travail
+ $ git annex init "portable USB drive"
+ init portable USB drive
+ Detected a crippled filesystem.
+
+ Enabling direct mode.
+
+ git-annex: /media/LACIE/travail/.git/annex/objects/k1: createDirectory: already exists (File exists)
+ failed
+ git-annex: init: 1 failed
+
+What version of git-annex are you using? On what operating system?
+ $ apt-cache policy git-annex
+ git-annex:
+ Installé : 3.20130216
+
+This on a amd64 debian sid recently updated
+
+
+Please provide any additional information below.
+
+The problem is that git annex already created a /media/LACIE/travail/.git/annex/objects/K1 file (same name in uppercase) and FAT isn't realy case sensitive.
+
+
+> I *think* I've found the place that used createDirectory
+> rather than createDirectoryIfMissing and fixed it. [[done]] --[[Joey]]
diff --git a/doc/bugs/git-annex_on_crippled_filesystem_can_still_failed_due_to_case_/comment_1_850695231926dfe94f11342d3af7f63c._comment b/doc/bugs/git-annex_on_crippled_filesystem_can_still_failed_due_to_case_/comment_1_850695231926dfe94f11342d3af7f63c._comment
new file mode 100644
index 000000000..a11bb3bf5
--- /dev/null
+++ b/doc/bugs/git-annex_on_crippled_filesystem_can_still_failed_due_to_case_/comment_1_850695231926dfe94f11342d3af7f63c._comment
@@ -0,0 +1,54 @@
+[[!comment format=mdwn
+ username="http://hands.com/~phil/"
+ nickname="fil"
+ subject="still seems to be a problem with 4.20130323"
+ date="2013-03-31T16:49:47Z"
+ content="""
+Hi Joey,
+
+Seems that I can still get this to choke on a VFAT system:
+
+ poker% sudo mount -o loop,gid=25,fmask=0117,dmask=0007 /home/phil/nobackup/annextest-image/vfat-annex-test.img /mnt
+ poker% mount | grep /mnt
+ /home/phil/nobackup/annextest-image/vfat-annex-test.img on /mnt type vfat (rw,relatime,gid=25,fmask=0117,dmask=0007,allow_utime=0020,codepage=cp437,iocharset=utf8,shortname=mixed,errors=remount-ro)
+ poker% cd /mnt
+ poker% git init
+ Initialized empty Git repository in /mnt/.git/
+ poker% git annex init simple\ test
+ init simple test
+ Detected a crippled filesystem.
+
+ Enabling direct mode.
+ ok
+ (Recording state in git...)
+ poker% for i in $(seq 1 42) ; do echo $i > $i.txt ; done
+ poker% git annex add *.txt
+ add 10.txt (checksum...) ok
+ add 11.txt (checksum...) ok
+ ...
+ add 40.txt (checksum...) ok
+ add 41.txt (checksum...) ok
+ add 42.txt (checksum...)
+ git-annex: /mnt/.git/annex/objects/Wj/56: createDirectory: does not exist (No such file or directory)
+ failed
+ add 4.txt (checksum...) ok
+ add 5.txt (checksum...) ok
+ add 6.txt (checksum...) ok
+ add 7.txt (checksum...) ok
+ add 8.txt (checksum...) ok
+ add 9.txt (checksum...) ok
+ (Recording state in git...)
+ git-annex: add: 1 failed
+ poker% ls -ld /mnt/.git/annex/objects/[wW][jJ]
+ drwxrwx--- 3 root floppy 4096 Mar 31 17:21 /mnt/.git/annex/objects/wJ
+ poker% git annex version
+ git-annex version: 4.20130323
+
+perhaps I shouldn't be trying that anyway -- I was wanting to create a direct mode repo on each of my camera's SD cards, which the camera will happily ignore, but allows me to add new photos to the repo by plugging the card into my laptop, and then copy them elsewhere using git annex magic. I'm hoping that would allow me to leave favourite photos on the camera, for showing off photos when without my laptop, while not becoming confused about which photos I've already got copies of and can safely delete (with annex's drop telling me when I try to delete things I shouldn't).
+
+The reason not to use a special directory remote (at least I think this is right judging from the wiki info) is that the camera won't grok the filenames under .git/annex/... so the photos need to be left with their names as created by the camera.
+
+Anyway, while experimenting with that idea, I bumped into the above, which seems like a continuation of this bug.
+
+_Update:_ Just tried that again, having cloned the git and rebuilt locally, and I'm still seeing the same behaviour with the very latest (i.e. 11b3942ef2aa13fe38d79e91392fc43d65a7e019)
+"""]]
diff --git a/doc/bugs/git-annex_on_crippled_filesystem_can_still_failed_due_to_case_/comment_2_c2a2f801a3e18ad597ff0acf2f104557._comment b/doc/bugs/git-annex_on_crippled_filesystem_can_still_failed_due_to_case_/comment_2_c2a2f801a3e18ad597ff0acf2f104557._comment
new file mode 100644
index 000000000..8ab32ede2
--- /dev/null
+++ b/doc/bugs/git-annex_on_crippled_filesystem_can_still_failed_due_to_case_/comment_2_c2a2f801a3e18ad597ff0acf2f104557._comment
@@ -0,0 +1,22 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-04-04T19:47:50Z"
+ content="""
+Whups, this bug report was closed; I almost missed this new bug and test case.
+
+So, on these filesystems that are horribly confused about case, it's possible for `mkdir FOO` to fail with \"already exists\", because there is a directory named `foo` ... but then `mkdir FOO/bar` fails with \"no such file or directory\".
+
+That is an intractable problem. It follows that it's simply not safe to use mixed case files on such a filesystem. You will always shoot your later self in the foot. (I personally think it's outright foolish to use a filesystem with such horrible semantics at all, but whatever.)
+
+So.. I took a good look at this, and it turns out that
+
+* since this is a crippled filesystem anyway, git-annex doesn't use symlinks on it
+* so there's no reason to use the mixed case hash directories that we're stuck using to avoid breaking everyone's symlinks to the content
+* so we can do what is already done for all bare repos, and make non-bare repos on crippled filesystems use the all-lower case hash directories
+* which are, happily, all 3 letters long, so they cannot conflict with mixed case hash directories
+* so I was able to 100% fix this and even resuming `git annex add` in the test case will recover and it will all just work.
+
+Yay!
+"""]]
diff --git a/doc/bugs/git-annex_opens_too_many_files.mdwn b/doc/bugs/git-annex_opens_too_many_files.mdwn
new file mode 100644
index 000000000..d5830be57
--- /dev/null
+++ b/doc/bugs/git-annex_opens_too_many_files.mdwn
@@ -0,0 +1,40 @@
+[[!meta title="network-muticast FD leak fix not deployed to Linux autobuilds yet"]]
+
+### Please describe the problem.
+After running git-annex some minutes, the websites is not responsible any more and it even crashes eventually.
+
+### What steps will reproduce the problem?
+Start the assistant.
+
+### What version of git-annex are you using? On what operating system?
+it-annex version: 4.20130802-g1452ac3
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+[2013-08-06 13:32:51 CEST] main: starting assistant version 4.20130802-g1452ac3
+
+Already up-to-date.
+(scanning...) [2013-08-06 13:32:51 CEST] Watcher: Performing startup scan
+
+Already up-to-date.
+(started...)
+git-annex: accept: resource exhausted (Too many open files)
+[2013-08-06 19:50:37 CEST] read: git ["--git-dir=/home/christian/git-annex/.git","--work-tree=/home/+christian/git-annex","symbolic-ref","HEAD"]
+git-annex: runInteractiveProcess: pipe: Too many open files
+[2013-08-06 19ND:ea5te1Wm:ao1tn1cS htCeaErtSFuTas]l lcNbreaatcsWkha etcdcr:ha es/rhh:eo dmd:ee /tgc+eihctrt:ie sdct rineaeantt/wegoPirrtko- cacenosnnsen:xe /cr.tegisiootnu/
+racnen[ e2ex0x/1h:3a -uo0sp8te-en0dT6 e (m1Tp9oF:oi5 l1me:a:1n 1yr eCosEpoSeuTnr] c feri eleaexdsh:+)a
+ugsitte d[ "(-T-ogoi tm-adniyr =o/pheonm ef/iclhersi)s
+tian/git-annex/.git","--work-tree=/home/christian/git-annex","symbolic-ref","HEAD"]
+git-annex: runInteractiveProcess: pipe: Too many open files
+git-annex: git: createProcess: resource exhausted (Too many open files)
+[2013-08-06 19:51:11 CEST] NetWatcherFallback: warning NetWatcherFallback crashed: git: createProces+s: resource exhausted (Too many open files)
+[2013-08-06 19:51:11 CEST] DaemonStatus: warning DaemonStatus crashed: /home/christian/git-annex/.gi+t/annex/: openTempFile: resource exhausted (Too many open files)
+
+(system was asleep from 14:00 until 19:50)
+
+# End of transcript or log.
+"""]]
diff --git a/doc/bugs/git-annex_opens_too_many_files/comment_1_37f6f5838c41c533df4be1f927b9b03d._comment b/doc/bugs/git-annex_opens_too_many_files/comment_1_37f6f5838c41c533df4be1f927b9b03d._comment
new file mode 100644
index 000000000..de5dde9b5
--- /dev/null
+++ b/doc/bugs/git-annex_opens_too_many_files/comment_1_37f6f5838c41c533df4be1f927b9b03d._comment
@@ -0,0 +1,26 @@
+[[!comment format=mdwn
+ username="chrisbra"
+ ip="80.149.220.45"
+ subject="sorry, added some wrapping signs from vim."
+ date="2013-08-06T18:01:40Z"
+ content="""
+[2013-08-06 13:32:51 CEST] main: starting assistant version 4.20130802-g1452ac3
+
+Already up-to-date.
+(scanning...) [2013-08-06 13:32:51 CEST] Watcher: Performing startup scan
+
+Already up-to-date.
+(started...)
+git-annex: accept: resource exhausted (Too many open files)
+[2013-08-06 19:50:37 CEST] read: git [\"--git-dir=/home/christian/git-annex/.git\",\"--work-tree=/home/christian/git-annex\",\"symbolic-ref\",\"HEAD\"]
+git-annex: runInteractiveProcess: pipe: Too many open files
+[2013-08-06 19ND:ea5te1Wm:ao1tn1cS htCeaErtSFuTas]l lcNbreaatcsWkha etcdcr:ha es/rhh:eo dmd:ee /tgceihctrt:ie sdct rineaeantt/wegoPirrtko- cacenosnnsen:xe /cr.tegisiootnu/
+racnen[ e2ex0x/1h:3a -uo0sp8te-en0dT6 e (m1Tp9oF:oi5 l1me:a:1n 1yr eCosEpoSeuTnr] c feri eleaexdsh:)a
+ugsitte d[ \"(-T-ogoi tm-adniyr =o/pheonm ef/iclhersi)s
+tian/git-annex/.git\",\"--work-tree=/home/christian/git-annex\",\"symbolic-ref\",\"HEAD\"]
+git-annex: runInteractiveProcess: pipe: Too many open files
+git-annex: git: createProcess: resource exhausted (Too many open files)
+[2013-08-06 19:51:11 CEST] NetWatcherFallback: warning NetWatcherFallback crashed: git: createProcess: resource exhausted (Too many open files)
+[2013-08-06 19:51:11 CEST] DaemonStatus: warning DaemonStatus crashed: /home/christian/git-annex/.git/annex/: openTempFile: resource exhausted (Too many open files)
+
+"""]]
diff --git a/doc/bugs/git-annex_opens_too_many_files/comment_2_347ef233b9845b84d7c4d49ed166e797._comment b/doc/bugs/git-annex_opens_too_many_files/comment_2_347ef233b9845b84d7c4d49ed166e797._comment
new file mode 100644
index 000000000..381d425fc
--- /dev/null
+++ b/doc/bugs/git-annex_opens_too_many_files/comment_2_347ef233b9845b84d7c4d49ed166e797._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 2"
+ date="2013-08-07T15:59:59Z"
+ content="""
+What operating system is this?
+
+Can you see which files the git-annex process has open?
+"""]]
diff --git a/doc/bugs/git-annex_opens_too_many_files/comment_3_d5f644d97cd2db471deb5dcd728cae60._comment b/doc/bugs/git-annex_opens_too_many_files/comment_3_d5f644d97cd2db471deb5dcd728cae60._comment
new file mode 100644
index 000000000..fbd3bce8f
--- /dev/null
+++ b/doc/bugs/git-annex_opens_too_many_files/comment_3_d5f644d97cd2db471deb5dcd728cae60._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="chrisbra"
+ ip="212.121.153.12"
+ subject="This is ubuntu 12.10"
+ date="2013-08-12T13:30:00Z"
+ content="""
+This is ubuntu 12.10 and seems to be the same problem which has been mentioned before (resource exhausted or similar)
+"""]]
diff --git a/doc/bugs/git-annex_opens_too_many_files/comment_4_c03bde64be8fdd962826bc7afa07d2a9._comment b/doc/bugs/git-annex_opens_too_many_files/comment_4_c03bde64be8fdd962826bc7afa07d2a9._comment
new file mode 100644
index 000000000..b4c458706
--- /dev/null
+++ b/doc/bugs/git-annex_opens_too_many_files/comment_4_c03bde64be8fdd962826bc7afa07d2a9._comment
@@ -0,0 +1,137 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlmRpGORNKWimtzqItvwm4I6cn16vx8OvU"
+ nickname="hayden"
+ subject="Many network sockets with associated fds hanging around"
+ date="2013-08-15T18:00:42Z"
+ content="""
+I see something similar in logs and after roughly 10 mins the web-apps dies.
+So I think I hit the same as the above user.
+Sometimes I get thread deaths and restart requests but the root cause appears to match the scenario mentioned over.
+Often the webapp just hangs. But always when it hits the fd ulimit... 1024 on this system.
+
+git-annex version is 4.20130802-g1452ac3 and I used the static-linked linux tar.gz linux-binary download.
+
+Test setup is a from scratch assistant startup on Ubuntu 12.04.
+Not exactly a clean ubuntu though, so maybe difficult to duplicate troubles at your end.
+
+I fired up the web-app with a cleaned out config. No signs of leaks until an annex is created.
+On creation of an empty annex I get fd leaks a about 1 per second after a repository is created.
+Strace'ing the main process only shows 8-bytes writes (see below) at the same rate as the leak.
+Sometimes the fd-leak stops before the resource limit, sometimes not.
+Creating a new annex on top of an existing directory tree with many files is pretty reliable trigger though.
+Startup scan finishes and fds leak away until the ulimit is hit.
+
+ hayden@orca:~/gamma$ ls /proc/26319/fd
+ 0 10 12 14 16 18 2 21 23 25 27 29 30 32 34 36 38 4 41 43 45 6 8
+ 1 11 13 15 17 19 20 22 24 26 28 3 31 33 35 37 39 40 42 44 5 7 9
+ hayden@orca:~/gamma$ ls /proc/26319/fd
+ 0 10 12 14 16 18 2 21 23 25 27 29 30 32 34 36 38 4 41 43 45 6 8
+ 1 11 13 15 17 19 20 22 24 26 28 3 31 33 35 37 39 40 42 44 5 7 9
+ hayden@orca:~/gamma$ ls /proc/26319/fd
+ 0 10 12 14 16 18 2 21 23 25 27 29 30 32 34 36 38 4 41 43 45 5 7 9
+ 1 11 13 15 17 19 20 22 24 26 28 3 31 33 35 37 39 40 42 44 46 6 8
+
+ hayden@orca:~/gamma$ ls /proc/26319/fd/43
+ /proc/26319/fd/43
+
+ hayden@orca:~/gamma$ ls -l /proc/26319/fd/43
+ ls -l /proc/26319/fd/43
+ lrwx------ 1 hayden hayden 64 Aug 14 21:10 /proc/26319/fd/43 -> socket:[568994]
+
+ hayden@orca:~/gamma$ lsof | grep 568994
+ git-annex 26319 hayden 43u IPv4 568994 0t0 UDP 224.0.0.251:55556
+
+ hayden@orca:~/gamma$ uname -a
+ Linux orca 3.2.0-25-generic #40-Ubuntu SMP Wed May 23 20:30:51 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
+
+ hayden@orca:~/gamma$ cat /etc/issue
+ Ubuntu 12.04 LTS \n \l
+
+ hayden@orca:~/gamma$ fuser 55556/udp -a
+ 55556/udp: 4415 26319 27080 27083
+
+ hayden@orca:~/gamma$ ps aux | grep 4415
+ hayden 4415 0.0 0.0 66716 3036 ? S Aug12 0:03 curl -s --head -L http://127.0.0.1:38464/?auth=da9c4aba4cc2db9cf78574753f6e94d8031c6a7bdf8bfe100bde868f57b81fd751965cc9d68a9afac79f826d257a256a04ce62615a7f23cd7c925969dda1c7b8 -w %{http_code}
+ hayden 27458 0.0 0.0 10612 924 pts/0 S+ 21:50 0:00 grep --color=auto 4415
+
+ hayden@orca:~/gamma$ ps aux | grep 26319
+ hayden 26319 0.1 0.7 497188 28560 pts/5 Sl 21:09 0:04 git-annex webapp
+ hayden 26338 3.4 3.4 1035572 137864 pts/5 Sl 21:09 1:25 /usr/lib/firefox/firefox /tmp/webapp26319.html
+ hayden 27460 0.0 0.0 10612 920 pts/0 S+ 21:50 0:00 grep --color=auto 26319
+
+ hayden@orca:~/gamma$ ps aux | grep 27080
+ hayden 27080 0.0 0.0 16476 1288 pts/5 S 21:33 0:00 git --git-dir=/home/hayden/boo/.git --work-tree=/home/hayden/boo cat-file --batch
+ hayden 27462 0.0 0.0 10612 924 pts/0 S+ 21:50 0:00 grep --color=auto 27080
+
+ hayden@orca:~/gamma$ ps aux | grep 27083
+ hayden 27083 0.0 0.0 16476 1060 pts/5 S 21:33 0:00 git --git-dir=/home/hayden/boo/.git --work-tree=/home/hayden/boo check-attr -z --stdin annex.backend annex.numcopies --
+ hayden 27464 0.0 0.0 10612 920 pts/0 S+ 21:51 0:00 grep --color=auto 27083
+
+----> has 579 open fds at this point but this number holds stable over 10 min
+(copy in new tree to provoke)
+(no change)
+----> restart daemon in gui to provoke
+(new process has open fds slowly climbing after startup scan)
+
+straces look like this repeating every second. (clipped down)
+
+ futex(0x34f001c, FUTEX_WAIT_PRIVATE, 51, NULL) = ? ERESTARTSYS (To be restarted)
+ --- SIGVTALRM (Virtual timer expired) @ 0 (0) ---
+ rt_sigreturn(0x1a) = 202
+ futex(0x34f001c, FUTEX_WAIT_PRIVATE, 51, NULL) = ? ERESTARTSYS (To be restarted)
+ --- SIGVTALRM (Virtual timer expired) @ 0 (0) ---
+ rt_sigreturn(0x1a) = 202
+ futex(0x34f001c, FUTEX_WAIT_PRIVATE, 51, NULL) = ? ERESTARTSYS (To be restarted)
+ --- SIGVTALRM (Virtual timer expired) @ 0 (0) ---
+ rt_sigreturn(0x1a) = 202
+ futex(0x34f001c, FUTEX_WAIT_PRIVATE, 51, NULL) = ? ERESTARTSYS (To be restarted)
+ --- SIGVTALRM (Virtual timer expired) @ 0 (0) ---
+ write(6, \"\377\0\0\0\0\0\0\0\", 8) = 8
+ rt_sigreturn(0x2) = 202
+ futex(0x34f001c, FUTEX_WAIT_PRIVATE, 51, NULL^C <unfinished ...>
+ Process 29803 detached
+
+Until after roughly 10 mins...
+
+ hayden@orca:~/boo$ ls /proc/29803/fd | wc -l
+ 1017
+ hayden@orca:~/boo$ ls /proc/29803/fd | wc -l
+ 1023
+ hayden@orca:~/boo$ ls /proc/29803/fd | wc -l
+ 1024
+ hayden@orca:~/boo$ ls /proc/29803/fd | wc -l
+ 1024
+ hayden@orca:~/boo$ ls /proc/29803/fd | wc -l
+ 1024
+ hayden@orca:~/boo$ ls /proc/29803/fd | wc -l
+ 1024
+
+ hayden@orca:~/boo$ ulimit -a
+ core file size (blocks, -c) 0
+ data seg size (kbytes, -d) unlimited
+ scheduling priority (-e) 0
+ file size (blocks, -f) unlimited
+ pending signals (-i) 31164
+ max locked memory (kbytes, -l) 64
+ max memory size (kbytes, -m) unlimited
+ open files (-n) 1024
+ pipe size (512 bytes, -p) 8
+ POSIX message queues (bytes, -q) 819200
+ real-time priority (-r) 0
+ stack size (kbytes, -s) 8192
+ cpu time (seconds, -t) unlimited
+ max user processes (-u) 31164
+ virtual memory (kbytes, -v) unlimited
+ file locks (-x) unlimited
+ hayden@orca:~/boo$
+
+At this point the webapp hangs but a number of interesting crashes may occur. I've also seen the particular error in the previous users log (on a big tree).
+
+ [2013-08-14 21:56:12 CEST] main: starting assistant version 4.20130802-g1452ac3
+ (scanning...) [2013-08-14 21:56:12 CEST] Watcher: Performing startup scan
+ (started...) DaemonStatus crashed: /home/hayden/boo/.git/annex/: openTempFile: resource exhausted (Too many open files)
+ [2013-08-14 22:06:12 CEST] DaemonStatus: warning DaemonStatus crashed: /home/hayden/boo/.git/annex/: openTempFile: resource exhausted (Too many open files)
+
+Is any of the above helpful? Anything else useful to kick for testing that you'd like done?
+I'd guess this is something weird with my ubuntu setup that provokes this as more users would see it otherwise.
+"""]]
diff --git a/doc/bugs/git-annex_opens_too_many_files/comment_5_33a2e783e5355e981497b9861997570b._comment b/doc/bugs/git-annex_opens_too_many_files/comment_5_33a2e783e5355e981497b9861997570b._comment
new file mode 100644
index 000000000..786672eb2
--- /dev/null
+++ b/doc/bugs/git-annex_opens_too_many_files/comment_5_33a2e783e5355e981497b9861997570b._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 5"
+ date="2013-08-24T17:09:43Z"
+ content="""
+Thanks for an excellent amount of debug information.
+
+I can see what's leaking is UDP connections to 224.0.0.251. That address is used for the \"local pairing\" option in the webapp.
+
+I was able to reproduce the problem by disabling all network interfaces except `lo`. The PairListener then failed to open a multicast listening socket. When it fails that way, it retried every second, as you noticed. And there is a socket leak in that failure mode.
+
+I wonder if you're seeing this even when on the network? If so, perhaps your Ubuntu system has something going on that prevents opening a multicast listening socket on even `eth0` or `wlan0` or whatever.
+
+Unfortunately, the actual socket leak bug is in the [network-multicast](http://hackage.haskell.org/package/network-multicast) library, and not in git-annex. I have filed an upstream bug report: <https://github.com/audreyt/network-multicast/issues/4>
+
+Hopefully that will be dealt with soon. There is a workaround I could do in git-annex: If it fails (leaking one socket), it could wait until the NetworkListener indicated a new network interface was opened, before trying again (possibly leaking one socket again). This would change it from a 1 per second leak to a 1 per change of network leak at worst, which is probably much less likely to cause problems.
+"""]]
diff --git a/doc/bugs/git-annex_opens_too_many_files/comment_6_b3a5a4e4ca29c5cd2840bfeb4c63ea68._comment b/doc/bugs/git-annex_opens_too_many_files/comment_6_b3a5a4e4ca29c5cd2840bfeb4c63ea68._comment
new file mode 100644
index 000000000..60c268fc0
--- /dev/null
+++ b/doc/bugs/git-annex_opens_too_many_files/comment_6_b3a5a4e4ca29c5cd2840bfeb4c63ea68._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 6"
+ date="2013-08-24T18:38:56Z"
+ content="""
+My NetListener workaround turned out to not be portable enough.
+
+However, I have sent a patch to fix the FD leak: <https://github.com/audreyt/network-multicast/pull/6>
+Hopefully it gets applied soon.
+
+I have also made the PairListener only retry every 60 seconds. Which makes the leak 1/60th as bad, for whatever that's worth.
+
+Once a fix for this gets into Debian, I need to remember to backport it to stable, and update the autobuilders to use it. Also need to remember to update the Android autobuilder. Leaving this bug report open until that happens.
+"""]]
diff --git a/doc/bugs/git-annex_quit_unexpectedly___40__macosx__41__.mdwn b/doc/bugs/git-annex_quit_unexpectedly___40__macosx__41__.mdwn
new file mode 100644
index 000000000..a682c12cc
--- /dev/null
+++ b/doc/bugs/git-annex_quit_unexpectedly___40__macosx__41__.mdwn
@@ -0,0 +1,358 @@
+### Please describe the problem.
+
+I installed the git-annex app for MacOSX (10.8.4)
+
+### What steps will reproduce the problem?
+
+- Created a repository
+- In the configuration, entered my google username/password
+
+### What version of git-annex are you using? On what operating system?
+
+bundle version: 0.0.1
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+Process: git-annex [12934]
+Path: /Applications/git-annex.app/Contents/MacOS/bundle/git-annex
+Identifier: git-annex
+Version: 0
+Code Type: X86-64 (Native)
+Parent Process: ??? [1]
+User ID: 502
+
+Date/Time: 2013-08-17 12:27:12.495 -0700
+OS Version: Mac OS X 10.8.4 (12E55)
+Report Version: 10
+Sleep/Wake UUID: 6DB42174-0147-4C8B-B83E-F305823297CA
+
+Interval Since Last Report: 294009 sec
+Crashes Since Last Report: 4
+Per-App Crashes Since Last Report: 4
+Anonymous UUID: 0D492F72-DAE5-360C-A6D6-ECB38FD53115
+
+Crashed Thread: 3
+
+Exception Type: EXC_BAD_ACCESS (SIGSEGV)
+Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000000
+
+VM Regions Near 0:
+-->
+ __TEXT 000000010b5e6000-000000010e08d000 [ 42.7M] r-x/rwx SM=COW /Applications/git-annex.app/Contents/MacOS/bundle/git-annex
+
+Thread 0:: Dispatch queue: com.apple.main-thread
+0 libsystem_kernel.dylib 0x00007fff931400fa __psynch_cvwait + 10
+1 libsystem_c.dylib 0x00007fff86adffe9 _pthread_cond_wait + 869
+2 git-annex 0x000000010df20179 0x10b5e6000 + 43229561
+3 git-annex 0x000000010defc8eb 0x10b5e6000 + 43084011
+4 git-annex 0x000000010df0bc86 0x10b5e6000 + 43146374
+5 git-annex 0x000000010df0c6fb 0x10b5e6000 + 43149051
+6 git-annex 0x000000010df07b46 0x10b5e6000 + 43129670
+7 git-annex 0x000000010df07c69 0x10b5e6000 + 43129961
+8 git-annex 0x000000010bcff518 0x10b5e6000 + 7443736
+9 libdyld.dylib 0x00007fff8c3e47e1 start + 1
+
+Thread 1:
+0 libsystem_kernel.dylib 0x00007fff931400fa __psynch_cvwait + 10
+1 libsystem_c.dylib 0x00007fff86adffe9 _pthread_cond_wait + 869
+2 git-annex 0x000000010df20179 0x10b5e6000 + 43229561
+3 git-annex 0x000000010defc8eb 0x10b5e6000 + 43084011
+4 git-annex 0x000000010df0bc86 0x10b5e6000 + 43146374
+5 git-annex 0x000000010df0c5e0 0x10b5e6000 + 43148768
+6 libsystem_c.dylib 0x00007fff86adb7a2 _pthread_start + 327
+7 libsystem_c.dylib 0x00007fff86ac81e1 thread_start + 13
+
+Thread 2:
+0 libsystem_kernel.dylib 0x00007fff931400fa __psynch_cvwait + 10
+1 libsystem_c.dylib 0x00007fff86adffe9 _pthread_cond_wait + 869
+2 git-annex 0x000000010df20179 0x10b5e6000 + 43229561
+3 git-annex 0x000000010defc8eb 0x10b5e6000 + 43084011
+4 git-annex 0x000000010df0bc86 0x10b5e6000 + 43146374
+5 git-annex 0x000000010df0c5e0 0x10b5e6000 + 43148768
+6 libsystem_c.dylib 0x00007fff86adb7a2 _pthread_start + 327
+7 libsystem_c.dylib 0x00007fff86ac81e1 thread_start + 13
+
+Thread 3 Crashed:
+0 libsystem_c.dylib 0x00007fff86ae0bf9 pthread_mutex_lock + 20
+1 H 0x000000010e9fd29f gnutls_system_mutex_lock + 12
+2 H 0x000000010ea7fa29 wrap_nettle_rnd_refresh + 20
+3 H 0x000000010e9fee89 gnutls_deinit + 42
+4 git-annex 0x000000010caf0a3a 0x10b5e6000 + 22063674
+
+Thread 4:
+0 libsystem_kernel.dylib 0x00007fff93140d2a kevent64 + 10
+1 git-annex 0x000000010deab5fa 0x10b5e6000 + 42751482
+
+Thread 5:
+0 libsystem_kernel.dylib 0x00007fff931400fa __psynch_cvwait + 10
+1 libsystem_c.dylib 0x00007fff86adffe9 _pthread_cond_wait + 869
+2 git-annex 0x000000010df20179 0x10b5e6000 + 43229561
+3 git-annex 0x000000010defc8eb 0x10b5e6000 + 43084011
+4 git-annex 0x000000010df0bc86 0x10b5e6000 + 43146374
+5 git-annex 0x000000010df0c5e0 0x10b5e6000 + 43148768
+6 libsystem_c.dylib 0x00007fff86adb7a2 _pthread_start + 327
+7 libsystem_c.dylib 0x00007fff86ac81e1 thread_start + 13
+
+Thread 6:: Dispatch queue: com.apple.libdispatch-manager
+0 libsystem_kernel.dylib 0x00007fff93140d16 kevent + 10
+1 libdispatch.dylib 0x00007fff8e6fedea _dispatch_mgr_invoke + 883
+2 libdispatch.dylib 0x00007fff8e6fe9ee _dispatch_mgr_thread + 54
+
+Thread 7:
+0 libsystem_kernel.dylib 0x00007fff9313e686 mach_msg_trap + 10
+1 libsystem_kernel.dylib 0x00007fff9313dc42 mach_msg + 70
+2 com.apple.CoreFoundation 0x00007fff8c1e2233 __CFRunLoopServiceMachPort + 195
+3 com.apple.CoreFoundation 0x00007fff8c1e7916 __CFRunLoopRun + 1078
+4 com.apple.CoreFoundation 0x00007fff8c1e70e2 CFRunLoopRunSpecific + 290
+5 com.apple.CoreFoundation 0x00007fff8c1f5dd1 CFRunLoopRun + 97
+6 git-annex 0x000000010c72b3ec 0x10b5e6000 + 18109420
+7 libsystem_c.dylib 0x00007fff86adb7a2 _pthread_start + 327
+8 libsystem_c.dylib 0x00007fff86ac81e1 thread_start + 13
+
+Thread 8:
+0 libsystem_kernel.dylib 0x00007fff9313e686 mach_msg_trap + 10
+1 libsystem_kernel.dylib 0x00007fff9313dc42 mach_msg + 70
+2 com.apple.CoreFoundation 0x00007fff8c1e2233 __CFRunLoopServiceMachPort + 195
+3 com.apple.CoreFoundation 0x00007fff8c1e7916 __CFRunLoopRun + 1078
+4 com.apple.CoreFoundation 0x00007fff8c1e70e2 CFRunLoopRunSpecific + 290
+5 com.apple.CoreFoundation 0x00007fff8c1f5dd1 CFRunLoopRun + 97
+6 git-annex 0x000000010c72b3ec 0x10b5e6000 + 18109420
+7 libsystem_c.dylib 0x00007fff86adb7a2 _pthread_start + 327
+8 libsystem_c.dylib 0x00007fff86ac81e1 thread_start + 13
+
+Thread 9:
+0 libsystem_kernel.dylib 0x00007fff9313e686 mach_msg_trap + 10
+1 libsystem_kernel.dylib 0x00007fff9313dc42 mach_msg + 70
+2 com.apple.CoreFoundation 0x00007fff8c1e2233 __CFRunLoopServiceMachPort + 195
+3 com.apple.CoreFoundation 0x00007fff8c1e7916 __CFRunLoopRun + 1078
+4 com.apple.CoreFoundation 0x00007fff8c1e70e2 CFRunLoopRunSpecific + 290
+5 com.apple.CoreFoundation 0x00007fff8c1f5dd1 CFRunLoopRun + 97
+6 git-annex 0x000000010c72b3ec 0x10b5e6000 + 18109420
+7 libsystem_c.dylib 0x00007fff86adb7a2 _pthread_start + 327
+8 libsystem_c.dylib 0x00007fff86ac81e1 thread_start + 13
+
+Thread 3 crashed with X86 Thread State (64-bit):
+ rax: 0x000000010eaaca28 rbx: 0x00007f9dc38000c0 rcx: 0x000000010f87ce00 rdx: 0x000000010e3c28f0
+ rdi: 0x0000000000000000 rsi: 0x001c4500001c4500 rbp: 0x000000010f87ce10 rsp: 0x000000010f87cdd0
+ r8: 0x0000000000002060 r9: 0x000000010f87ce00 r10: 0x000000010eabf328 r11: 0x000000010e9fee5f
+ r12: 0x000000010f5585d8 r13: 0x000000010e3c2798 r14: 0x0000000000000000 r15: 0x000000010f548140
+ rip: 0x00007fff86ae0bf9 rfl: 0x0000000000010202 cr2: 0x0000000000000000
+Logical CPU: 0
+
+Binary Images:
+ 0x10b5e6000 - 0x10e08cff7 +git-annex (0) <2C4C13B3-4830-322A-A144-9E51B386EB1E> /Applications/git-annex.app/Contents/MacOS/bundle/git-annex
+ 0x10e85a000 - 0x10e957ff7 +E (22.3) <47B09CB2-C636-3024-8B55-6040F7829B4C> /Applications/git-annex.app/Contents/MacOS/bundle/E
+ 0x10e990000 - 0x10e9a4fff +F (0) <FA90B1B1-A866-3A6C-BB97-06955F4C8C0B> /Applications/git-annex.app/Contents/MacOS/bundle/F
+ 0x10e9ab000 - 0x10e9d8ff7 +G (0) <D80652C0-9A55-351C-8EAF-2364359BA0A2> /Applications/git-annex.app/Contents/MacOS/bundle/G
+ 0x10e9de000 - 0x10eaabfdf +H (0) <29C3AFF5-8EFB-3A16-81F6-0DA6CF2675A6> /Applications/git-annex.app/Contents/MacOS/bundle/H
+ 0x10eadd000 - 0x10eaefff7 +B (43) <2A1551E8-A272-3DE5-B692-955974FE1416> /Applications/git-annex.app/Contents/MacOS/bundle/B
+ 0x10eaf7000 - 0x10ebecfff +D (34) <FEE8B996-EB44-37FA-B96E-D379664DEFE1> /Applications/git-annex.app/Contents/MacOS/bundle/D
+ 0x10ec01000 - 0x10ed1992f +I (532.2) <90D31928-F48D-3E37-874F-220A51FD9E37> /Applications/git-annex.app/Contents/MacOS/bundle/I
+ 0x10ed3d000 - 0x10ef3dfff +S (491.11.3) <5783D305-04E8-3D17-94F7-1CEAFA975240> /Applications/git-annex.app/Contents/MacOS/bundle/S
+ 0x10f048000 - 0x10f06dff7 +Z (26) <D86169F3-9F31-377A-9AF3-DB17142052E4> /Applications/git-annex.app/Contents/MacOS/bundle/Z
+ 0x10f0a1000 - 0x10f109ff7 +0A (65.1) <20E31B90-19B9-3C2A-A9EB-474E08F9FE05> /Applications/git-annex.app/Contents/MacOS/bundle/0A
+ 0x10f163000 - 0x10f1ccfff +0B (56) <EAA2B53E-EADE-39CF-A0EF-FB9D4940672A> /Applications/git-annex.app/Contents/MacOS/bundle/0B
+ 0x10f235000 - 0x10f248fff +T (0) <C8970714-4C86-3BE6-94D6-4835DCC8A003> /Applications/git-annex.app/Contents/MacOS/bundle/T
+ 0x10f257000 - 0x10f264ff7 +U (0) <DCFF385A-090B-3407-868C-91544A2EFEE1> /Applications/git-annex.app/Contents/MacOS/bundle/U
+ 0x10f26f000 - 0x10f291ff7 +V (0) <51B317C7-94CC-3C58-B515-924BB3AF0BCC> /Applications/git-annex.app/Contents/MacOS/bundle/V
+ 0x10f29b000 - 0x10f2a8ff7 +W (0) <91CF16BE-027F-3FE6-B1EE-6B8BFD51FC1B> /Applications/git-annex.app/Contents/MacOS/bundle/W
+ 0x10f2b4000 - 0x10f310fd7 +X (0) <84D934AF-A321-36C0-BBCF-CD3FDAEB0B95> /Applications/git-annex.app/Contents/MacOS/bundle/X
+ 0x7fff6b1e6000 - 0x7fff6b21a93f dyld (210.2.3) <36CAA36E-72BC-3E48-96D9-B96A2DF77730> /usr/lib/dyld
+ 0x7fff8652a000 - 0x7fff865d0ff7 com.apple.CoreServices.OSServices (557.6 - 557.6) <FFDDD2D8-690D-388F-A48F-4750A792D2CD> /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/OSServices.framework/Versions/A/OSServices
+ 0x7fff865d1000 - 0x7fff865e8fff libGL.dylib (8.9.2) <B8E5948D-BCF2-3727-B74E-D74B8EDC82D6> /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib
+ 0x7fff865e9000 - 0x7fff86610fff com.apple.framework.familycontrols (4.1 - 410) <50F5A52C-8FB6-300A-977D-5CFDE4D5796B> /System/Library/PrivateFrameworks/FamilyControls.framework/Versions/A/FamilyControls
+ 0x7fff86611000 - 0x7fff8663cfff libxslt.1.dylib (11.3) <441776B8-9130-3893-956F-39C85FFA644F> /usr/lib/libxslt.1.dylib
+ 0x7fff86649000 - 0x7fff86698ff7 libcorecrypto.dylib (106.2) <CE0C29A3-C420-339B-ADAA-52F4683233CC> /usr/lib/system/libcorecrypto.dylib
+ 0x7fff8669d000 - 0x7fff866a3fff com.apple.DiskArbitration (2.5.2 - 2.5.2) <C713A35A-360E-36CE-AC0A-25C86A3F50CA> /System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration
+ 0x7fff866a4000 - 0x7fff86ac1fff FaceCoreLight (2.4.1) <DDAFFD7A-D312-3407-A010-5AEF3E17831B> /System/Library/PrivateFrameworks/FaceCoreLight.framework/Versions/A/FaceCoreLight
+ 0x7fff86ac7000 - 0x7fff86b93ff7 libsystem_c.dylib (825.26) <4C9EB006-FE1F-3F8F-8074-DFD94CF2CE7B> /usr/lib/system/libsystem_c.dylib
+ 0x7fff86d50000 - 0x7fff86da1ff7 com.apple.SystemConfiguration (1.12.2 - 1.12.2) <581BF463-C15A-363B-999A-E830222FA925> /System/Library/Frameworks/SystemConfiguration.framework/Versions/A/SystemConfiguration
+ 0x7fff86dee000 - 0x7fff86deefff com.apple.Accelerate.vecLib (3.8 - vecLib 3.8) <B5A18EE8-DF81-38DD-ACAF-7076B2A26225> /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/vecLib
+ 0x7fff86def000 - 0x7fff86df4fff com.apple.OpenDirectory (10.8 - 151.10) <CF44120B-9B01-32DD-852E-C9C0E1243FC0> /System/Library/Frameworks/OpenDirectory.framework/Versions/A/OpenDirectory
+ 0x7fff86df5000 - 0x7fff86df6fff libDiagnosticMessagesClient.dylib (8) <8548E0DC-0D2F-30B6-B045-FE8A038E76D8> /usr/lib/libDiagnosticMessagesClient.dylib
+ 0x7fff86e0a000 - 0x7fff87201fff libLAPACK.dylib (1073.4) <D632EC8B-2BA0-3853-800A-20DA00A1091C> /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libLAPACK.dylib
+ 0x7fff87622000 - 0x7fff87650ff7 libsystem_m.dylib (3022.6) <B434BE5C-25AB-3EBD-BAA7-5304B34E3441> /usr/lib/system/libsystem_m.dylib
+ 0x7fff8766c000 - 0x7fff8769dff7 com.apple.DictionaryServices (1.2 - 184.4) <FB0540FF-5034-3591-A28D-6887FBC220F7> /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/DictionaryServices.framework/Versions/A/DictionaryServices
+ 0x7fff8769e000 - 0x7fff8769efff libkeymgr.dylib (25) <CC9E3394-BE16-397F-926B-E579B60EE429> /usr/lib/system/libkeymgr.dylib
+ 0x7fff87732000 - 0x7fff87754ff7 libxpc.dylib (140.43) <70BC645B-6952-3264-930C-C835010CCEF9> /usr/lib/system/libxpc.dylib
+ 0x7fff87755000 - 0x7fff877d7ff7 com.apple.Heimdal (3.0 - 2.0) <C94B0C6C-1320-35A1-8143-FE252E7B2A08> /System/Library/PrivateFrameworks/Heimdal.framework/Versions/A/Heimdal
+ 0x7fff877d8000 - 0x7fff87859fff com.apple.Metadata (10.7.0 - 707.11) <2DD25313-420D-351A-90F1-300E95C970CA> /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/Metadata.framework/Versions/A/Metadata
+ 0x7fff87cbf000 - 0x7fff87d19fff com.apple.print.framework.PrintCore (8.3 - 387.2) <5BA0CBED-4D80-386A-9646-F835C9805B71> /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/PrintCore.framework/Versions/A/PrintCore
+ 0x7fff87e27000 - 0x7fff87e34ff7 com.apple.NetAuth (4.0 - 4.0) <F5BC7D7D-AF28-3C83-A674-DADA48FF7810> /System/Library/PrivateFrameworks/NetAuth.framework/Versions/A/NetAuth
+ 0x7fff87f54000 - 0x7fff87f68fff com.apple.speech.synthesis.framework (4.1.12 - 4.1.12) <94EDF2AB-809C-3D15-BED5-7AD45B2A7C16> /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/SpeechSynthesis.framework/Versions/A/SpeechSynthesis
+ 0x7fff87f77000 - 0x7fff87f7dff7 libunwind.dylib (35.1) <21703D36-2DAB-3D8B-8442-EAAB23C060D3> /usr/lib/system/libunwind.dylib
+ 0x7fff87fab000 - 0x7fff87fabfff com.apple.Accelerate (1.8 - Accelerate 1.8) <6AD48543-0864-3D40-80CE-01F184F24B45> /System/Library/Frameworks/Accelerate.framework/Versions/A/Accelerate
+ 0x7fff88161000 - 0x7fff88162ff7 libSystem.B.dylib (169.3) <9089D72D-E714-31E1-80C8-698A8E8B05AD> /usr/lib/libSystem.B.dylib
+ 0x7fff88167000 - 0x7fff88205ff7 com.apple.ink.framework (10.8.2 - 150) <3D8D16A2-7E01-3EA1-B637-83A36D353308> /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/Ink.framework/Versions/A/Ink
+ 0x7fff88222000 - 0x7fff88223ff7 libsystem_sandbox.dylib (220.3) <B739DA63-B675-387A-AD84-412A651143C0> /usr/lib/system/libsystem_sandbox.dylib
+ 0x7fff88224000 - 0x7fff88228ff7 com.apple.TCC (1.0 - 1) <F2F3B753-FC73-3543-8BBE-859FDBB4D6A6> /System/Library/PrivateFrameworks/TCC.framework/Versions/A/TCC
+ 0x7fff88229000 - 0x7fff88230fff libcopyfile.dylib (89) <876573D0-E907-3566-A108-577EAD1B6182> /usr/lib/system/libcopyfile.dylib
+ 0x7fff88a6e000 - 0x7fff88a8dff7 libresolv.9.dylib (51) <0882DC2D-A892-31FF-AD8C-0BB518C48B23> /usr/lib/libresolv.9.dylib
+ 0x7fff88a8e000 - 0x7fff88aa1ff7 libbsm.0.dylib (32) <F497D3CE-40D9-3551-84B4-3D5E39600737> /usr/lib/libbsm.0.dylib
+ 0x7fff88bbd000 - 0x7fff88bbdfff com.apple.ApplicationServices (45 - 45) <A3ABF20B-ED3A-32B5-830E-B37831A45A80> /System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices
+ 0x7fff88bce000 - 0x7fff88bf6fff libJPEG.dylib (850) <DC750E1E-BD07-339B-A4A6-D86BFE969F68> /System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/libJPEG.dylib
+ 0x7fff88bf7000 - 0x7fff88bf9fff libquarantine.dylib (52.1) <143B726E-DF47-37A8-90AA-F059CFD1A2E4> /usr/lib/system/libquarantine.dylib
+ 0x7fff88fe0000 - 0x7fff8933ffff com.apple.Foundation (6.8 - 945.18) <1D7E58E6-FA3A-3CE8-AC85-B9D06B8C0AA0> /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation
+ 0x7fff89340000 - 0x7fff89575ff7 com.apple.CoreData (106.1 - 407.7) <A676E1A4-2144-376B-92B8-B450DD1D78E5> /System/Library/Frameworks/CoreData.framework/Versions/A/CoreData
+ 0x7fff89576000 - 0x7fff8957dfff libGFXShared.dylib (8.9.2) <398F8D57-EC82-3E13-AC8E-470BE19237D7> /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGFXShared.dylib
+ 0x7fff895d4000 - 0x7fff8a201fff com.apple.AppKit (6.8 - 1187.39) <199962F0-B06B-3666-8FD5-5C90374BA16A> /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit
+ 0x7fff8a202000 - 0x7fff8a519ff7 com.apple.CoreServices.CarbonCore (1037.6 - 1037.6) <1E567A52-677F-3168-979F-5FBB0818D52B> /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CarbonCore.framework/Versions/A/CarbonCore
+ 0x7fff8a5e0000 - 0x7fff8a5e7fff com.apple.NetFS (5.0 - 4.0) <82E24B9A-7742-3DA3-9E99-ED267D98C05E> /System/Library/Frameworks/NetFS.framework/Versions/A/NetFS
+ 0x7fff8a5e8000 - 0x7fff8a63fff7 com.apple.ScalableUserInterface (1.0 - 1) <F1D43DFB-1796-361B-AD4B-39F1EED3BE19> /System/Library/Frameworks/QuartzCore.framework/Versions/A/Frameworks/ScalableUserInterface.framework/Versions/A/ScalableUserInterface
+ 0x7fff8a71b000 - 0x7fff8a767ff7 libauto.dylib (185.4) <AD5A4CE7-CB53-313C-9FAE-673303CC2D35> /usr/lib/libauto.dylib
+ 0x7fff8a768000 - 0x7fff8a768fff libOpenScriptingUtil.dylib (148.3) <F8681222-0969-3B10-8BCE-C55A4B9C520C> /usr/lib/libOpenScriptingUtil.dylib
+ 0x7fff8a7e7000 - 0x7fff8a808ff7 libCRFSuite.dylib (33) <736ABE58-8DED-3289-A042-C25AF7AE5B23> /usr/lib/libCRFSuite.dylib
+ 0x7fff8a809000 - 0x7fff8a815fff com.apple.CrashReporterSupport (10.8.3 - 418) <DE6AFE16-D97E-399D-82ED-3522C773C36E> /System/Library/PrivateFrameworks/CrashReporterSupport.framework/Versions/A/CrashReporterSupport
+ 0x7fff8a816000 - 0x7fff8b1a64af com.apple.CoreGraphics (1.600.0 - 332) <5AB32E51-9154-3733-B83B-A9A748652847> /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/Versions/A/CoreGraphics
+ 0x7fff8b1a7000 - 0x7fff8b1befff com.apple.CFOpenDirectory (10.8 - 151.10) <10F41DA4-AD54-3F52-B898-588D9A117171> /System/Library/Frameworks/OpenDirectory.framework/Versions/A/Frameworks/CFOpenDirectory.framework/Versions/A/CFOpenDirectory
+ 0x7fff8b242000 - 0x7fff8b285ff7 com.apple.bom (12.0 - 192) <0BF1F2D2-3648-36B7-BE4B-551A0173209B> /System/Library/PrivateFrameworks/Bom.framework/Versions/A/Bom
+ 0x7fff8b286000 - 0x7fff8b2c3fef libGLImage.dylib (8.9.2) <C38649ED-E1C9-315E-9953-F33E8C6A3C89> /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGLImage.dylib
+ 0x7fff8b2c4000 - 0x7fff8b303ff7 com.apple.QD (3.42.1 - 285.1) <77A20C25-EBB5-341C-A05C-5D458B97AD5C> /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/QD.framework/Versions/A/QD
+ 0x7fff8b304000 - 0x7fff8b39efff libvMisc.dylib (380.6) <714336EA-1C0E-3735-B31C-19DFDAAF6221> /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libvMisc.dylib
+ 0x7fff8b3b8000 - 0x7fff8b566fff com.apple.QuartzCore (1.8 - 304.3) <F450F2DE-2F24-3557-98B6-310E05DAC17F> /System/Library/Frameworks/QuartzCore.framework/Versions/A/QuartzCore
+ 0x7fff8ba39000 - 0x7fff8ba4cff7 com.apple.LangAnalysis (1.7.0 - 1.7.0) <2F2694E9-A7BC-33C7-B4CF-8EC907DF0FEB> /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/LangAnalysis.framework/Versions/A/LangAnalysis
+ 0x7fff8bd12000 - 0x7fff8bd1cfff com.apple.speech.recognition.framework (4.1.5 - 4.1.5) <D803919C-3102-3515-A178-61E9C86C46A1> /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/SpeechRecognition.framework/Versions/A/SpeechRecognition
+ 0x7fff8c0d6000 - 0x7fff8c0d7ff7 libdnsinfo.dylib (453.19) <14202FFB-C3CA-3FCC-94B0-14611BF8692D> /usr/lib/system/libdnsinfo.dylib
+ 0x7fff8c179000 - 0x7fff8c17efff libcompiler_rt.dylib (30) <08F8731D-5961-39F1-AD00-4590321D24A9> /usr/lib/system/libcompiler_rt.dylib
+ 0x7fff8c1b2000 - 0x7fff8c39cff7 com.apple.CoreFoundation (6.8 - 744.19) <0F7403CA-2CB8-3D0A-992B-679701DF27CA> /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
+ 0x7fff8c39d000 - 0x7fff8c3c4ff7 com.apple.PerformanceAnalysis (1.16 - 16) <E4888388-F41B-313E-9CBB-5807D077BDA9> /System/Library/PrivateFrameworks/PerformanceAnalysis.framework/Versions/A/PerformanceAnalysis
+ 0x7fff8c3e2000 - 0x7fff8c3e5ff7 libdyld.dylib (210.2.3) <F59367C9-C110-382B-A695-9035A6DD387E> /usr/lib/system/libdyld.dylib
+ 0x7fff8c3e6000 - 0x7fff8c3e8fff libCVMSPluginSupport.dylib (8.9.2) <EF1192AC-3357-3A0B-BFAF-6594D7737892> /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libCVMSPluginSupport.dylib
+ 0x7fff8c3e9000 - 0x7fff8c484fff com.apple.CoreSymbolication (3.0 - 117) <50716F74-41C2-3BB9-AC16-12C4D4C2DD1E> /System/Library/PrivateFrameworks/CoreSymbolication.framework/Versions/A/CoreSymbolication
+ 0x7fff8c75b000 - 0x7fff8c75bfff com.apple.CoreServices (57 - 57) <9DD44CB0-C644-35C3-8F57-0B41B3EC147D> /System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices
+ 0x7fff8cf1f000 - 0x7fff8d094ff7 com.apple.CFNetwork (596.4.3 - 596.4.3) <A57B3308-2F08-3EC3-B4AC-39A3D9F0B9F7> /System/Library/Frameworks/CFNetwork.framework/Versions/A/CFNetwork
+ 0x7fff8d0ae000 - 0x7fff8d0e4fff libsystem_info.dylib (406.17) <4FFCA242-7F04-365F-87A6-D4EFB89503C1> /usr/lib/system/libsystem_info.dylib
+ 0x7fff8d0e5000 - 0x7fff8d148ff7 com.apple.audio.CoreAudio (4.1.1 - 4.1.1) <9ACD3AED-6C04-3BBB-AB2A-FC253B16D093> /System/Library/Frameworks/CoreAudio.framework/Versions/A/CoreAudio
+ 0x7fff8d156000 - 0x7fff8d16cfff com.apple.MultitouchSupport.framework (235.29 - 235.29) <617EC8F1-BCE7-3553-86DD-F857866E1257> /System/Library/PrivateFrameworks/MultitouchSupport.framework/Versions/A/MultitouchSupport
+ 0x7fff8d16d000 - 0x7fff8d171fff libGIF.dylib (850) <D4525F87-759C-338C-B283-BB8DE815D3D5> /System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/libGIF.dylib
+ 0x7fff8d264000 - 0x7fff8d2aeff7 libGLU.dylib (8.9.2) <1B5511FF-1064-3004-A245-972CE5687D37> /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGLU.dylib
+ 0x7fff8d2b2000 - 0x7fff8d2dcff7 com.apple.CoreVideo (1.8 - 99.4) <E5082966-6D81-3973-A05A-38AA5B85F886> /System/Library/Frameworks/CoreVideo.framework/Versions/A/CoreVideo
+ 0x7fff8d58d000 - 0x7fff8d591fff com.apple.IOSurface (86.0.4 - 86.0.4) <26F01CD4-B76B-37A3-989D-66E8140542B3> /System/Library/Frameworks/IOSurface.framework/Versions/A/IOSurface
+ 0x7fff8d6de000 - 0x7fff8d78ffff com.apple.LaunchServices (539.9 - 539.9) <07FC6766-778E-3479-8F28-D2C9917E1DD1> /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/LaunchServices
+ 0x7fff8d7bf000 - 0x7fff8d80eff7 libFontRegistry.dylib (100) <2E03D7DA-9B8F-31BB-8FB5-3D3B6272127F> /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ATS.framework/Versions/A/Resources/libFontRegistry.dylib
+ 0x7fff8d80f000 - 0x7fff8d88fff7 com.apple.ApplicationServices.ATS (332 - 341.1) <39B53565-FA31-3F61-B090-C787C983142E> /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ATS.framework/Versions/A/ATS
+ 0x7fff8d94e000 - 0x7fff8d95bfff com.apple.AppleFSCompression (49 - 1.0) <5508344A-2A7E-3122-9562-6F363910A80E> /System/Library/PrivateFrameworks/AppleFSCompression.framework/Versions/A/AppleFSCompression
+ 0x7fff8d95c000 - 0x7fff8d99fff7 com.apple.RemoteViewServices (2.0 - 80.6) <5CFA361D-4853-3ACC-9EFC-A2AC1F43BA4B> /System/Library/PrivateFrameworks/RemoteViewServices.framework/Versions/A/RemoteViewServices
+ 0x7fff8dac2000 - 0x7fff8dac8fff libmacho.dylib (829) <BF332AD9-E89F-387E-92A4-6E1AB74BD4D9> /usr/lib/system/libmacho.dylib
+ 0x7fff8dac9000 - 0x7fff8db03ff7 com.apple.GSS (3.0 - 2.0) <970CAE00-1437-3F4E-B677-0FDB3714C08C> /System/Library/Frameworks/GSS.framework/Versions/A/GSS
+ 0x7fff8db09000 - 0x7fff8db12ff7 com.apple.CommerceCore (1.0 - 26.1) <40A129A8-4E5D-3C7A-B299-8CB203C4C65D> /System/Library/PrivateFrameworks/CommerceKit.framework/Versions/A/Frameworks/CommerceCore.framework/Versions/A/CommerceCore
+ 0x7fff8db13000 - 0x7fff8db15fff com.apple.TrustEvaluationAgent (2.0 - 23) <A97D348B-32BF-3E52-8DF2-59BFAD21E1A3> /System/Library/PrivateFrameworks/TrustEvaluationAgent.framework/Versions/A/TrustEvaluationAgent
+ 0x7fff8de6c000 - 0x7fff8de6eff7 libunc.dylib (25) <92805328-CD36-34FF-9436-571AB0485072> /usr/lib/system/libunc.dylib
+ 0x7fff8de6f000 - 0x7fff8de8eff7 com.apple.ChunkingLibrary (2.0 - 133.3) <8BEC9AFB-DCAA-37E8-A5AB-24422B234ECF> /System/Library/PrivateFrameworks/ChunkingLibrary.framework/Versions/A/ChunkingLibrary
+ 0x7fff8de8f000 - 0x7fff8deeefff com.apple.AE (645.6 - 645.6) <44F403C1-660A-3543-AB9C-3902E02F936F> /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/AE.framework/Versions/A/AE
+ 0x7fff8deef000 - 0x7fff8dfecfff libsqlite3.dylib (138.1) <ADE9CB98-D77D-300C-A32A-556B7440769F> /usr/lib/libsqlite3.dylib
+ 0x7fff8e06b000 - 0x7fff8e076ff7 com.apple.bsd.ServiceManagement (2.0 - 2.0) <C12962D5-85FB-349E-AA56-64F4F487F219> /System/Library/Frameworks/ServiceManagement.framework/Versions/A/ServiceManagement
+ 0x7fff8e077000 - 0x7fff8e086fff com.apple.opengl (1.8.9 - 1.8.9) <6FD163A7-16CC-3D1F-B4B5-B0FDC4ADBF79> /System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL
+ 0x7fff8e087000 - 0x7fff8e092fff com.apple.CommonAuth (3.0 - 2.0) <7A953C1F-8B18-3E46-9BEA-26D9B5B7745D> /System/Library/PrivateFrameworks/CommonAuth.framework/Versions/A/CommonAuth
+ 0x7fff8e093000 - 0x7fff8e093fff com.apple.Cocoa (6.7 - 19) <1F77945C-F37A-3171-B22E-F7AB0FCBB4D4> /System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa
+ 0x7fff8e1f3000 - 0x7fff8e1f4fff libsystem_blocks.dylib (59) <D92DCBC3-541C-37BD-AADE-ACC75A0C59C8> /usr/lib/system/libsystem_blocks.dylib
+ 0x7fff8e23c000 - 0x7fff8e23cffd com.apple.audio.units.AudioUnit (1.9 - 1.9) <EC55FB59-2443-3F08-9142-7BCC93C76E4E> /System/Library/Frameworks/AudioUnit.framework/Versions/A/AudioUnit
+ 0x7fff8e23d000 - 0x7fff8e30fff7 com.apple.CoreText (260.0 - 275.16) <5BFC1D67-6A6F-38BC-9D90-9C712684EDAC> /System/Library/Frameworks/CoreText.framework/Versions/A/CoreText
+ 0x7fff8e310000 - 0x7fff8e31eff7 libkxld.dylib (2050.24.15) <A619A9AC-09AF-3FF3-95BF-F07CC530EC31> /usr/lib/system/libkxld.dylib
+ 0x7fff8e31f000 - 0x7fff8e38dff7 com.apple.framework.IOKit (2.0.1 - 755.24.1) <04BFB138-8AF4-310A-8E8C-045D8A239654> /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit
+ 0x7fff8e39f000 - 0x7fff8e525fff libBLAS.dylib (1073.4) <C102C0F6-8CB6-3B49-BA6B-2EB61F0B2784> /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
+ 0x7fff8e553000 - 0x7fff8e597fff libcups.2.dylib (327.6) <9C01D012-6F4C-3B69-B614-1B408B0ED4E3> /usr/lib/libcups.2.dylib
+ 0x7fff8e598000 - 0x7fff8e5a6fff libcommonCrypto.dylib (60027) <BAAFE0C9-BB86-3CA7-88C0-E3CBA98DA06F> /usr/lib/system/libcommonCrypto.dylib
+ 0x7fff8e6fa000 - 0x7fff8e70fff7 libdispatch.dylib (228.23) <D26996BF-FC57-39EB-8829-F63585561E09> /usr/lib/system/libdispatch.dylib
+ 0x7fff8e710000 - 0x7fff8e71eff7 libsystem_network.dylib (77.10) <0D99F24E-56FE-380F-B81B-4A4C630EE587> /usr/lib/system/libsystem_network.dylib
+ 0x7fff8e71f000 - 0x7fff8e741ff7 com.apple.Kerberos (2.0 - 1) <C49B8820-34ED-39D7-A407-A3E854153556> /System/Library/Frameworks/Kerberos.framework/Versions/A/Kerberos
+ 0x7fff8e788000 - 0x7fff8e797ff7 libxar.1.dylib (105) <370ED355-E516-311E-BAFD-D80633A84BE1> /usr/lib/libxar.1.dylib
+ 0x7fff8f144000 - 0x7fff8f1d1ff7 com.apple.SearchKit (1.4.0 - 1.4.0) <C7F43889-F8BF-3CB9-AD66-11AEFCBCEDE7> /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/SearchKit.framework/Versions/A/SearchKit
+ 0x7fff8f24c000 - 0x7fff8f24ffff libRadiance.dylib (850) <62E3F7FB-03E3-3937-A857-AF57A75EAF09> /System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/libRadiance.dylib
+ 0x7fff8f533000 - 0x7fff8f7d7ff7 com.apple.CoreImage (8.4.0 - 1.0.1) <CC6DD22B-FFC6-310B-BE13-2397A02C79EF> /System/Library/Frameworks/QuartzCore.framework/Versions/A/Frameworks/CoreImage.framework/Versions/A/CoreImage
+ 0x7fff8f7d8000 - 0x7fff8f840fff libvDSP.dylib (380.6) <CD4C5EEB-9E63-30C4-8103-7A5EAEA0BE60> /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libvDSP.dylib
+ 0x7fff8f8ab000 - 0x7fff8f8affff libpam.2.dylib (20) <C8F45864-5B58-3237-87E1-2C258A1D73B8> /usr/lib/libpam.2.dylib
+ 0x7fff8fabb000 - 0x7fff8fb28ff7 com.apple.datadetectorscore (4.1 - 269.3) <5775F0DB-87D6-310D-8B03-E2AD729EFB28> /System/Library/PrivateFrameworks/DataDetectorsCore.framework/Versions/A/DataDetectorsCore
+ 0x7fff8fc60000 - 0x7fff8fcbcff7 com.apple.Symbolication (1.3 - 93) <97F3B1D2-D81D-3F37-87B3-B9A686124CF5> /System/Library/PrivateFrameworks/Symbolication.framework/Versions/A/Symbolication
+ 0x7fff8fd91000 - 0x7fff8fe6bfff com.apple.backup.framework (1.4.3 - 1.4.3) <6B65C44C-7777-3331-AD9D-438D10AAC777> /System/Library/PrivateFrameworks/Backup.framework/Versions/A/Backup
+ 0x7fff8fe6c000 - 0x7fff8fe79fff libbz2.1.0.dylib (29) <CE9785E8-B535-3504-B392-82F0064D9AF2> /usr/lib/libbz2.1.0.dylib
+ 0x7fff8fe89000 - 0x7fff8ffdbfff com.apple.audio.toolbox.AudioToolbox (1.9 - 1.9) <62770C0F-5600-3EF9-A893-8A234663FFF5> /System/Library/Frameworks/AudioToolbox.framework/Versions/A/AudioToolbox
+ 0x7fff90071000 - 0x7fff90173fff libJP2.dylib (850) <2E43216C-3A5A-3693-820C-38B360698FA0> /System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/libJP2.dylib
+ 0x7fff90ab4000 - 0x7fff90b79ff7 com.apple.coreui (2.0 - 181.1) <83D2C92D-6842-3C9D-9289-39D5B4554C3A> /System/Library/PrivateFrameworks/CoreUI.framework/Versions/A/CoreUI
+ 0x7fff90e1a000 - 0x7fff90e1bfff liblangid.dylib (116) <864C409D-D56B-383E-9B44-A435A47F2346> /usr/lib/liblangid.dylib
+ 0x7fff90f20000 - 0x7fff90fddff7 com.apple.ColorSync (4.8.0 - 4.8.0) <6CE333AE-EDDB-3768-9598-9DB38041DC55> /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ColorSync.framework/Versions/A/ColorSync
+ 0x7fff90fde000 - 0x7fff9105dff7 com.apple.securityfoundation (6.0 - 55115.4) <8676E0DF-295F-3690-BDAA-6C9C1D210B88> /System/Library/Frameworks/SecurityFoundation.framework/Versions/A/SecurityFoundation
+ 0x7fff9105e000 - 0x7fff910b4fff com.apple.HIServices (1.20 - 417) <BCD36950-013F-35C2-918E-05A93A47BE8C> /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/HIServices.framework/Versions/A/HIServices
+ 0x7fff910b5000 - 0x7fff910d6fff com.apple.Ubiquity (1.2 - 243.15) <C9A7EE77-B637-3676-B667-C0843BBB0409> /System/Library/PrivateFrameworks/Ubiquity.framework/Versions/A/Ubiquity
+ 0x7fff910de000 - 0x7fff91133ff7 libTIFF.dylib (850) <EDAF0D99-70AF-3B3F-9EFA-9463C91D0E3C> /System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/libTIFF.dylib
+ 0x7fff9125c000 - 0x7fff9127cfff libPng.dylib (850) <203C43BF-FAD3-3CCB-81D5-F2770E36338B> /System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/libPng.dylib
+ 0x7fff9127f000 - 0x7fff91398fff com.apple.ImageIO.framework (3.2.1 - 850) <C3FFCEEB-AA0C-314B-9E94-7005EE48A403> /System/Library/Frameworks/ImageIO.framework/Versions/A/ImageIO
+ 0x7fff9139f000 - 0x7fff913b6fff com.apple.GenerationalStorage (1.1 - 132.3) <FD4A84B3-13A8-3C60-A59E-25A361447A17> /System/Library/PrivateFrameworks/GenerationalStorage.framework/Versions/A/GenerationalStorage
+ 0x7fff91582000 - 0x7fff91586fff libCoreVMClient.dylib (32.3) <AD8391D9-56DD-3A78-A294-6A30E6ECE1A2> /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libCoreVMClient.dylib
+ 0x7fff91587000 - 0x7fff915bdfff com.apple.DebugSymbols (98 - 98) <14E788B1-4EB2-3FD7-934B-849534DFC198> /System/Library/PrivateFrameworks/DebugSymbols.framework/Versions/A/DebugSymbols
+ 0x7fff915cd000 - 0x7fff915d5fff liblaunch.dylib (442.26.2) <2F71CAF8-6524-329E-AC56-C506658B4C0C> /usr/lib/system/liblaunch.dylib
+ 0x7fff915d6000 - 0x7fff915e1fff libsystem_notify.dylib (98.5) <C49275CC-835A-3207-AFBA-8C01374927B6> /usr/lib/system/libsystem_notify.dylib
+ 0x7fff91650000 - 0x7fff917ebfef com.apple.vImage (6.0 - 6.0) <FAE13169-295A-33A5-8E6B-7C2CC1407FA7> /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vImage.framework/Versions/A/vImage
+ 0x7fff917ec000 - 0x7fff917f4ff7 libsystem_dnssd.dylib (379.38.1) <BDCB8566-0189-34C0-9634-35ABD3EFE25B> /usr/lib/system/libsystem_dnssd.dylib
+ 0x7fff9182d000 - 0x7fff91938fff libFontParser.dylib (84.6) <96C42E49-79A6-3475-B5E4-6A782599A6DA> /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ATS.framework/Versions/A/Resources/libFontParser.dylib
+ 0x7fff919d8000 - 0x7fff919ddfff libcache.dylib (57) <65187C6E-3FBF-3EB8-A1AA-389445E2984D> /usr/lib/system/libcache.dylib
+ 0x7fff919de000 - 0x7fff919defff com.apple.vecLib (3.8 - vecLib 3.8) <794317C7-4E38-338A-A874-5E18001C8503> /System/Library/Frameworks/vecLib.framework/Versions/A/vecLib
+ 0x7fff919df000 - 0x7fff91cb0ff7 com.apple.security (7.0 - 55179.13) <F428E306-C407-3B55-BA82-E58755E8A76F> /System/Library/Frameworks/Security.framework/Versions/A/Security
+ 0x7fff91d3f000 - 0x7fff9206ffff com.apple.HIToolbox (2.0 - 626.1) <656D08C2-9068-3532-ABDD-32EC5057CCB2> /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/HIToolbox
+ 0x7fff92084000 - 0x7fff920deff7 com.apple.opencl (2.2.19 - 2.2.19) <3C7DFB2C-B3F9-3447-A1FC-EAAA42181A6E> /System/Library/Frameworks/OpenCL.framework/Versions/A/OpenCL
+ 0x7fff9216c000 - 0x7fff9216dff7 libremovefile.dylib (23.2) <6763BC8E-18B8-3AD9-8FFA-B43713A7264F> /usr/lib/system/libremovefile.dylib
+ 0x7fff9312e000 - 0x7fff93149ff7 libsystem_kernel.dylib (2050.24.15) <A9F97289-7985-31D6-AF89-151830684461> /usr/lib/system/libsystem_kernel.dylib
+ 0x7fff9314d000 - 0x7fff9326dfff com.apple.desktopservices (1.7.4 - 1.7.4) <ED3DA8C0-160F-3CDC-B537-BF2E766AB7C1> /System/Library/PrivateFrameworks/DesktopServicesPriv.framework/Versions/A/DesktopServicesPriv
+
+External Modification Summary:
+ Calls made by other processes targeting this process:
+ task_for_pid: 1
+ thread_create: 0
+ thread_set_state: 0
+ Calls made by this process:
+ task_for_pid: 0
+ thread_create: 0
+ thread_set_state: 0
+ Calls made by all processes on this machine:
+ task_for_pid: 168404
+ thread_create: 1
+ thread_set_state: 0
+
+VM Region Summary:
+ReadOnly portion of Libraries: Total=109.3M resident=31.8M(29%) swapped_out_or_unallocated=77.5M(71%)
+Writable regions: Total=90.9M written=16.1M(18%) resident=17.5M(19%) swapped_out=0K(0%) unallocated=73.4M(81%)
+
+REGION TYPE VIRTUAL
+=========== =======
+MALLOC 62.5M
+MALLOC guard page 48K
+STACK GUARD 56.0M
+Stack 12.6M
+VM_ALLOCATE 12.0M
+__DATA 13.8M
+__IMAGE 528K
+__LINKEDIT 58.6M
+__TEXT 134.3M
+__UNICODE 544K
+shared memory 308K
+=========== =======
+TOTAL 351.2M
+
+Model: MacBookPro10,1, BootROM MBP101.00EE.B03, 4 processors, Intel Core i7, 2.8 GHz, 16 GB, SMC 2.3f35
+Graphics: Intel HD Graphics 4000, Intel HD Graphics 4000, Built-In, 512 MB
+Graphics: NVIDIA GeForce GT 650M, NVIDIA GeForce GT 650M, PCIe, 1024 MB
+Memory Module: BANK 0/DIMM0, 8 GB, DDR3, 1600 MHz, 0x80AD, 0x484D5434314753364D465238432D50422020
+Memory Module: BANK 1/DIMM0, 8 GB, DDR3, 1600 MHz, 0x80AD, 0x484D5434314753364D465238432D50422020
+AirPort: spairport_wireless_card_type_airport_extreme (0x14E4, 0xEF), Broadcom BCM43xx 1.0 (5.106.98.100.17)
+Bluetooth: Version 4.1.4f2 12041, 2 service, 18 devices, 1 incoming serial ports
+Network Service: Wi-Fi, AirPort, en0
+Serial ATA Device: APPLE SSD SM768E, 751.28 GB
+USB Device: hub_device, 0x8087 (Intel Corporation), 0x0024, 0x1a100000 / 2
+USB Device: FaceTime HD Camera (Built-in), apple_vendor_id, 0x8510, 0x1a110000 / 3
+USB Device: USB Receiver, 0x046d (Logitech Inc.), 0xc52b, 0x14200000 / 1
+USB Device: hub_device, 0x8087 (Intel Corporation), 0x0024, 0x1d100000 / 2
+USB Device: hub_device, 0x0424 (SMSC), 0x2512, 0x1d180000 / 3
+USB Device: Apple Internal Keyboard / Trackpad, apple_vendor_id, 0x0262, 0x1d182000 / 5
+USB Device: BRCM20702 Hub, 0x0a5c (Broadcom Corp.), 0x4500, 0x1d181000 / 4
+USB Device: Bluetooth USB Host Controller, apple_vendor_id, 0x8286, 0x1d181300 / 6
+
+# End of transcript or log.
+"""]]
+
+> This got fixed in haskell gnutls 0.1.5. I have updated the Mtn Lion
+> autobuilder and it will be in tonight's build. [[done]]
+> --[[Joey]]
diff --git a/doc/bugs/git-annex_quit_unexpectedly___40__macosx__41__/comment_1_97abb8442329d19c9687002f43afac74._comment b/doc/bugs/git-annex_quit_unexpectedly___40__macosx__41__/comment_1_97abb8442329d19c9687002f43afac74._comment
new file mode 100644
index 000000000..4dcc5412c
--- /dev/null
+++ b/doc/bugs/git-annex_quit_unexpectedly___40__macosx__41__/comment_1_97abb8442329d19c9687002f43afac74._comment
@@ -0,0 +1,23 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 1"
+ date="2013-08-26T19:51:48Z"
+ content="""
+So this is a crash in the gnutls library used for XMPP. Someone else using OSX reported a similar crash to me by email, reproducible reliably by setting up xmpp with google. This is great debugging info:
+
+<pre>
+Thread 3 Crashed:
+0 libsystem_c.dylib 0x00007fff86ae0bf9 pthread_mutex_lock + 20
+1 H 0x000000010e9fd29f gnutls_system_mutex_lock + 12
+2 H 0x000000010ea7fa29 wrap_nettle_rnd_refresh + 20
+3 H 0x000000010e9fee89 gnutls_deinit + 42
+4 git-annex 0x000000010caf0a3a 0x10b5e6000 + 22063674
+</pre>
+
+Looks like `gnutls_deinit` was called and it crashed there, inside pthread code. So I think git-annex has already managed to connect to the XMPP server (to test it) and the cleanup is where it's crashing.
+
+This is the second time I have seen a gnutls-related crash using XMPP. The other one was tracked down by John Millikin to a resource allocation bug in haskell-gnutls and fixed.
+
+I have written a test case that reproduces the problem -- just forking a dozen threads that each try to connect to the google xmpp server and then close the connection. After a dozen or so succeed, one will reliably cause a segfault. Forwarded this test case to John.
+"""]]
diff --git a/doc/bugs/git-annex_quit_unexpectedly___40__macosx__41__/comment_2_3405f3cd699860ee239cf23ade19e92c._comment b/doc/bugs/git-annex_quit_unexpectedly___40__macosx__41__/comment_2_3405f3cd699860ee239cf23ade19e92c._comment
new file mode 100644
index 000000000..18b2b7a52
--- /dev/null
+++ b/doc/bugs/git-annex_quit_unexpectedly___40__macosx__41__/comment_2_3405f3cd699860ee239cf23ade19e92c._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.7"
+ subject="comment 2"
+ date="2013-08-29T18:15:08Z"
+ content="""
+I now have a test case that shows that this can happen reliably on OSX if you enter the wrong XMPP password repeatedly. It might also happen if you just enter the wrong password once, with a server like google's, since the assistant will try falling back to different servers. John is aware of this haskell-gnutls problem.
+
+John also found, and we hope fixed (but it's hard to tell) a bug in haskell-gnutls that caused a crash maybe 1 time in 10 under some conditions on OSX, when the right password was entered.
+"""]]
diff --git a/doc/bugs/git-annex_sync_broken_on_squeeze_backports.mdwn b/doc/bugs/git-annex_sync_broken_on_squeeze_backports.mdwn
new file mode 100644
index 000000000..4e307fd68
--- /dev/null
+++ b/doc/bugs/git-annex_sync_broken_on_squeeze_backports.mdwn
@@ -0,0 +1,20 @@
+What steps will reproduce the problem?
+
+ git-annex sync
+
+What is the expected output? What do you see instead?
+
+The following error is mixed in with the output, took me a while to notice it:
+
+ Running: git ["--git-dir=/spare/annex/.git","--work-tree=/spare/annex","merge","--no-edit","refs/remotes/pip/synced/master"]
+ error: unknown option `no-edit'
+
+What version of git-annex are you using? On what operating system?
+
+3.20120629~bpo60+1 on debian squeeze
+
+Please provide any additional information below.
+
+Installing git from backports as well cleared up the problem.
+
+> Uploading a fix for this now. [[done]] Thanks for reporting. --[[Joey]]
diff --git a/doc/bugs/git-annex_sync_may_fail_when_the_directory_I__39__m_in_disepeared.mdwn b/doc/bugs/git-annex_sync_may_fail_when_the_directory_I__39__m_in_disepeared.mdwn
new file mode 100644
index 000000000..7a2690be2
--- /dev/null
+++ b/doc/bugs/git-annex_sync_may_fail_when_the_directory_I__39__m_in_disepeared.mdwn
@@ -0,0 +1,15 @@
+### Please describe the problem.
+While running git annex sync, it may failed if one did run it on some deep directory, and the sync remove this direcory.
+
+### What version of git-annex are you using? On what operating system?
+
+git-annex version: 4.20130815
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP
+local repository version: 3
+default repository version: 3
+supported repository versions: 3 4
+upgrade supported from repository versions: 0 1 2
+
+on Debian Gnu Linux sid
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/git-annex_thinks_files_are_in_repositories_they_are_not.mdwn b/doc/bugs/git-annex_thinks_files_are_in_repositories_they_are_not.mdwn
new file mode 100644
index 000000000..cf54eea85
--- /dev/null
+++ b/doc/bugs/git-annex_thinks_files_are_in_repositories_they_are_not.mdwn
@@ -0,0 +1,29 @@
+###What steps will reproduce the problem?
+
+1. Start git annex webapp, and make new repository on two computers.
+1. Pair them as "Local computer"s, and they synchronize fine, a file created on one shows up on the other.
+1. Disconnect one of the computers from the network, and create a new file
+1. Check where the file is.
+
+###What is the expected output? What do you see instead?
+
+ git annex whereis new file
+
+shows the file being in both repositories, when in fact it has had no chance to get added to the one on the other computer, and is not in it.
+
+
+###What version of git-annex are you using? On what operating system?
+
+Both 4.20130405 on Ubuntu 12.10
+
+###Please provide any additional information below.
+
+I noticed this first when using a USB drive to communicate between work and home. Making changes at home, it thought that the new files were now present at work, when the computer there is off, and a long way away.
+--Walter
+
+> A little while ago, I made this change:
+
+ * direct mode: Direct mode commands now work on files staged in the index,
+ they do not need to be committed to git.
+
+> I think that fixes the confusing behavior described here. [[done]] --[[Joey]]
diff --git a/doc/bugs/git-annex_thinks_files_are_in_repositories_they_are_not/comment_1_6722fd627ec4add9f2b16546bd8ef341._comment b/doc/bugs/git-annex_thinks_files_are_in_repositories_they_are_not/comment_1_6722fd627ec4add9f2b16546bd8ef341._comment
new file mode 100644
index 000000000..fa8053660
--- /dev/null
+++ b/doc/bugs/git-annex_thinks_files_are_in_repositories_they_are_not/comment_1_6722fd627ec4add9f2b16546bd8ef341._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-04-16T19:26:49Z"
+ content="""
+Please show me the full output of `git annex whereis`, and also the contents of `.git/config`
+"""]]
diff --git a/doc/bugs/git-annex_thinks_files_are_in_repositories_they_are_not/comment_2_508e475f764e1cb453b756eb50bc3a15._comment b/doc/bugs/git-annex_thinks_files_are_in_repositories_they_are_not/comment_2_508e475f764e1cb453b756eb50bc3a15._comment
new file mode 100644
index 000000000..c6fea0dbf
--- /dev/null
+++ b/doc/bugs/git-annex_thinks_files_are_in_repositories_they_are_not/comment_2_508e475f764e1cb453b756eb50bc3a15._comment
@@ -0,0 +1,34 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnSenxKyE_2Z6Wb-EBMO8FciyRywjx1ZiQ"
+ nickname="Walter"
+ subject="comment 2"
+ date="2013-04-16T20:25:45Z"
+ content="""
+ walter@dionysus:~/presence$ echo 1 > Here.txt
+ walter@dionysus:~/presence$ git annex whereis
+ whereis Here.txt (2 copies)
+ 1c6ffc98-d12c-4844-920b-5e28bc8e8b60 -- here (walter@dionysus:~/presence)
+ 8da299b6-006c-4410-9b3d-a542766d40a4 -- kronos.local_presence (walter@kronos:~/presence)
+ ok
+
+This is while kronos is turned off.
+
+The contents of .git/config:
+
+ [core]
+ repositoryformatversion = 0
+ filemode = true
+ bare = false
+ logallrefupdates = true
+ [annex]
+ uuid = 1c6ffc98-d12c-4844-920b-5e28bc8e8b60
+ version = 3
+ direct = true
+ [gc]
+ auto = 0
+ [remote \"kronos.local_presence\"]
+ url = ssh://walter@git-annex-kronos.local-walter/~/presence/
+ fetch = +refs/heads/*:refs/remotes/kronos.local_presence/*
+ annex-uuid = 8da299b6-006c-4410-9b3d-a542766d40a4
+ annex-cost = 175.0
+"""]]
diff --git a/doc/bugs/git-annex_thinks_files_are_in_repositories_they_are_not/comment_3_1656ba18c519a262c57ef626a3449e77._comment b/doc/bugs/git-annex_thinks_files_are_in_repositories_they_are_not/comment_3_1656ba18c519a262c57ef626a3449e77._comment
new file mode 100644
index 000000000..3a33becb8
--- /dev/null
+++ b/doc/bugs/git-annex_thinks_files_are_in_repositories_they_are_not/comment_3_1656ba18c519a262c57ef626a3449e77._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-04-16T20:33:44Z"
+ content="""
+> walter@dionysus:~/presence$ echo 1 > Here.txt
+> walter@dionysus:~/presence$ git annex whereis
+> whereis Here.txt (2 copies)
+
+It seems the file Here.txt must already have been added to git-annex before this point ... or whereis would not show it. Did you leave out a step? Was the file already added? Are you using direct mode?
+"""]]
diff --git a/doc/bugs/git-annex_thinks_files_are_in_repositories_they_are_not/comment_4_347dc3b6e5bc6c4195ec09d54bc1398e._comment b/doc/bugs/git-annex_thinks_files_are_in_repositories_they_are_not/comment_4_347dc3b6e5bc6c4195ec09d54bc1398e._comment
new file mode 100644
index 000000000..2fc2b573d
--- /dev/null
+++ b/doc/bugs/git-annex_thinks_files_are_in_repositories_they_are_not/comment_4_347dc3b6e5bc6c4195ec09d54bc1398e._comment
@@ -0,0 +1,24 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnSenxKyE_2Z6Wb-EBMO8FciyRywjx1ZiQ"
+ nickname="Walter"
+ subject="comment 4"
+ date="2013-04-16T20:42:34Z"
+ content="""
+The repository is a direct mode one.
+
+I think there's something in your comment though; the content (\"1\") had already been added to a file (since deleted on dionysus),
+however it does seem a bit inconsistent.
+
+ walter@dionysus:~/presence$ echo 1 > New1
+ walter@dionysus:~/presence$ echo 1 > New1.txt
+ walter@dionysus:~/presence$ git annex whereis New1 New1.txt
+ whereis New1 (1 copy)
+ 1c6ffc98-d12c-4844-920b-5e28bc8e8b60 -- here (walter@dionysus:~/presence)
+ ok
+ whereis New1.txt (2 copies)
+ 1c6ffc98-d12c-4844-920b-5e28bc8e8b60 -- here (walter@dionysus:~/presence)
+ 8da299b6-006c-4410-9b3d-a542766d40a4 -- kronos.local_presence (walter@kronos:~/presence)
+ ok
+
+
+"""]]
diff --git a/doc/bugs/git-annex_thinks_files_are_in_repositories_they_are_not/comment_5_a9c93bfc3278ef8b1117eac2af859bc3._comment b/doc/bugs/git-annex_thinks_files_are_in_repositories_they_are_not/comment_5_a9c93bfc3278ef8b1117eac2af859bc3._comment
new file mode 100644
index 000000000..aa08f6024
--- /dev/null
+++ b/doc/bugs/git-annex_thinks_files_are_in_repositories_they_are_not/comment_5_a9c93bfc3278ef8b1117eac2af859bc3._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 5"
+ date="2013-04-16T21:25:45Z"
+ content="""
+In a direct mode repository, until you commit changes to a file, `git annex whereis` and most other git-annex commands will operate on the version that was last committed to git.
+
+That seems to be the source of your confusion.
+
+I think this can be confusing.. It might make sense for git-annex whereis to skip over modified files in direct mode.
+"""]]
diff --git a/doc/bugs/git-annex_thinks_files_are_in_repositories_they_are_not/comment_6_804dd62beef64f7d4e203bdb28cbe660._comment b/doc/bugs/git-annex_thinks_files_are_in_repositories_they_are_not/comment_6_804dd62beef64f7d4e203bdb28cbe660._comment
new file mode 100644
index 000000000..1cb046af9
--- /dev/null
+++ b/doc/bugs/git-annex_thinks_files_are_in_repositories_they_are_not/comment_6_804dd62beef64f7d4e203bdb28cbe660._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnSenxKyE_2Z6Wb-EBMO8FciyRywjx1ZiQ"
+ nickname="Walter"
+ subject="comment 6"
+ date="2013-04-16T22:40:04Z"
+ content="""
+I am running the webapp, and thought that changes get made immediately?
+Especially, these are files that I never manually commit/add/anything, and are not modified after creation even.
+
+Specifically, in my previous comment, files New1 and New1.txt are (to my eyes) created and treated identically, yet `git annex whereis` gives different results.
+"""]]
diff --git a/doc/bugs/git-annex_thinks_files_are_in_repositories_they_are_not/comment_7_4ef107d70647780eb5347cae6f467fed._comment b/doc/bugs/git-annex_thinks_files_are_in_repositories_they_are_not/comment_7_4ef107d70647780eb5347cae6f467fed._comment
new file mode 100644
index 000000000..f7ca0a5af
--- /dev/null
+++ b/doc/bugs/git-annex_thinks_files_are_in_repositories_they_are_not/comment_7_4ef107d70647780eb5347cae6f467fed._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnSenxKyE_2Z6Wb-EBMO8FciyRywjx1ZiQ"
+ nickname="Walter"
+ subject="comment 7"
+ date="2013-04-17T20:50:34Z"
+ content="""
+So looking in .git/annex/objects, it is obvious that the difference between New1 and New1.txt is the extension.
+
+So, I think that explains all the things I was seeing. I guess the main point of confusion (though I can't think of a better way) is the distinction between data stored in .git/annex/objects, and files in the working folder.
+If I thought in terms of hashes, that is all that would need to be shown in git annex whereis is which hashes are where (and then it would be obvious if several files have the same hash, that once one of them is present somewhere then all of them are).
+
+"""]]
diff --git a/doc/bugs/git-annex_webapp_command_not_found.mdwn b/doc/bugs/git-annex_webapp_command_not_found.mdwn
new file mode 100644
index 000000000..6854d541c
--- /dev/null
+++ b/doc/bugs/git-annex_webapp_command_not_found.mdwn
@@ -0,0 +1,25 @@
+###What steps will reproduce the problem?
+
+ greg@x220:~/Music$ git-annex version
+ git-annex version: 3.20121017
+
+ greg@x220:~/Documents$ git-annex watch
+ greg@x220:~/Documents$ git-annex: Daemon is already running.
+
+ greg@x220:~/Documents$ git-annex assistant
+ greg@x220:~/Documents$ git-annex: Daemon is already running.
+
+ greg@x220:~/Documents$ git-annex webapp
+ git-annex: unknown command webapp
+
+This is on an Ubuntu (12.10) machine, using git-annex from ubuntu+1 (13.04), which is just an autosync from sid:
+
+https://launchpad.net/ubuntu/+source/git-annex/3.20121017
+
+###What is the expected output? What do you see instead?
+I expect my browser to open the webapp.
+
+
+(Also, it is odd how the output of "Daemon is already running" appears after my prompt is given back to me)
+
+> [[closing|done]]; forwarded upstream --[[Joey]]
diff --git a/doc/bugs/git-annex_webapp_command_not_found/comment_1_6fa63ae1a7affb2351eda57ab3b4eda1._comment b/doc/bugs/git-annex_webapp_command_not_found/comment_1_6fa63ae1a7affb2351eda57ab3b4eda1._comment
new file mode 100644
index 000000000..d60432a8d
--- /dev/null
+++ b/doc/bugs/git-annex_webapp_command_not_found/comment_1_6fa63ae1a7affb2351eda57ab3b4eda1._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.49"
+ subject="comment 1"
+ date="2012-11-29T19:45:25Z"
+ content="""
+Ubuntu is apparently building git-annex without the webapp.
+
+(Message display fixed.)
+"""]]
diff --git a/doc/bugs/git-annex_webapp_command_not_found/comment_2_d25232bb5eaff725281869d7681e81ad._comment b/doc/bugs/git-annex_webapp_command_not_found/comment_2_d25232bb5eaff725281869d7681e81ad._comment
new file mode 100644
index 000000000..eaf95ceb1
--- /dev/null
+++ b/doc/bugs/git-annex_webapp_command_not_found/comment_2_d25232bb5eaff725281869d7681e81ad._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://grossmeier.net/"
+ nickname="greg"
+ subject="comment 2"
+ date="2012-11-29T19:55:25Z"
+ content="""
+Thanks, Joey. I've reported it [downstream in LP](https://bugs.launchpad.net/ubuntu/+source/git-annex/+bug/1084693).
+"""]]
diff --git a/doc/bugs/git_annex_add_..._adds_too_much.mdwn b/doc/bugs/git_annex_add_..._adds_too_much.mdwn
new file mode 100644
index 000000000..4eb46455f
--- /dev/null
+++ b/doc/bugs/git_annex_add_..._adds_too_much.mdwn
@@ -0,0 +1,25 @@
+When a hidden file (starting with a dot) is git-annex add'ed, other non-tracked files are also added
+
+What steps will reproduce the problem?
+
+$ touch a .b
+
+$ git annex add .b
+
+add a (checksum...) ok
+
+add .b (checksum...) ok
+
+(Recording state in git...)
+
+
+What is the expected output? What do you see instead?
+
+Only file .b should be added.
+
+What version of git-annex are you using? On what operating system?
+
+3.20120406
+(same problem with version 3.20120123) on Debian.
+
+> Thanks for reporting this bug, I've fixed it in git. [[done]] --[[Joey]]
diff --git a/doc/bugs/git_annex_add_eats_files_when_filename_is_too_long.mdwn b/doc/bugs/git_annex_add_eats_files_when_filename_is_too_long.mdwn
new file mode 100644
index 000000000..d17e569f1
--- /dev/null
+++ b/doc/bugs/git_annex_add_eats_files_when_filename_is_too_long.mdwn
@@ -0,0 +1,14 @@
+Recently I ran into the following situation under Ubuntu with an encrypted home directory (which shortens the length that filenames can be):
+
+ $ git annex add 687474703a2f2f6d656469612e74756d626c722e636f6d2f74756d626c725f6c656673756557324c703171663879656b2e676966.gif
+ add 687474703a2f2f6d656469612e74756d626c722e636f6d2f74756d626c725f6c656673756557324c703171663879656b2e676966.gif failed
+ git-annex: /home/lhuhn/annex/.git/annex/tmp/155_518_WORM-s426663-m1310064100--687474703a2f2f6d656469612e74756d626c722e636f6d2f74756d626c725f6c656673756557324c703171663879656b2e676966.gif.log: openBinaryFile: invalid argument (File name too long)
+ git-annex: 1 failed
+
+The file seems to be completely gone. It no longer exists in the current directory, or under .git/annex.
+
+I don't mind horribly that git-annex failed due to the name length limit, but it shouldn't have deleted my file in the process (fortunately the file wasn't very important, or hard to recover).
+
+> [[done]], as noted it did not delete content and now it makes the symlink
+> before trying to write to the location log, avoiding that gotcha.
+> --[[Joey]]
diff --git a/doc/bugs/git_annex_add_eats_files_when_filename_is_too_long/comment_1_9650284913bec2a00cf551b90ab5d8ff._comment b/doc/bugs/git_annex_add_eats_files_when_filename_is_too_long/comment_1_9650284913bec2a00cf551b90ab5d8ff._comment
new file mode 100644
index 000000000..1df159181
--- /dev/null
+++ b/doc/bugs/git_annex_add_eats_files_when_filename_is_too_long/comment_1_9650284913bec2a00cf551b90ab5d8ff._comment
@@ -0,0 +1,21 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-07-07T20:27:33Z"
+ content="""
+When I reproduce this, the file is not gone, it's been moved under .git/annex/objects. There is no way an add can delete a file, since all it does is rename it. It would be good for it to error unwind and move the file back though.
+
+<pre>
+joey@gnu:~/tmp/a>touch 663879656b2e676966687474703a2f2f6d656469612e74756d626c722e636f6d2f74756d626c725f6c656673756557324c703171663879656b2e676966687474703a2f2f6d656469612e74756d626c722e636f6d2f74756d626c725f6c656673756557324c703171663879656b2e676966.gif
+joey@gnu:~/tmp/a>git annex add *.gif
+add 663879656b2e676966687474703a2f2f6d656469612e74756d626c722e636f6d2f74756d626c725f6c656673756557324c703171663879656b2e676966687474703a2f2f6d656469612e74756d626c722e636f6d2f74756d626c725f6c656673756557324c703171663879656b2e676966.gif failed
+git-annex: /home/joey/tmp/a/.git/annex/tmp/8e2_6a4_WORM-s0-m1310069979--663879656b2e676966687474703a2f2f6d656469612e74756d626c722e636f6d2f74756d626c725f6c656673756557324c703171663879656b2e676966687474703a2f2f6d656469612e74756d626c722e636f6d2f74756d626c725f6c656673756557324c703171663879656b2e676966.gif.log: openBinaryFile: invalid argument (File name too long)
+joey@gnu:~/tmp/a>touch 663879656b2e676966687474703a2f2f6d656469612e74756d626c722e636f6d2f74756d626c725f6c656673756557324c703171663879656b2e676966687474703a2f2f6d656469612e74756d626c722e636f6d2f74756d626c725f6c656673756557324c703171663879656b2e676966.gif
+joey@gnu:~/tmp/a>git annex add *.gif
+add 663879656b2e676966687474703a2f2f6d656469612e74756d626c722e636f6d2f74756d626c725f6c656673756557324c703171663879656b2e676966687474703a2f2f6d656469612e74756d626c722e636f6d2f74756d626c725f6c656673756557324c703171663879656b2e676966.gif failed
+git-annex: /home/joey/tmp/a/.git/annex/tmp/8e2_6a4_WORM-s0-m1310069979--663879656b2e676966687474703a2f2f6d656469612e74756d626c722e636f6d2f74756d626c725f6c656673756557324c703171663879656b2e676966687474703a2f2f6d656469612e74756d626c722e636f6d2f74756d626c725f6c656673756557324c703171663879656b2e676966.gif.log: openBinaryFile: invalid argument (File name too long)
+joey@gnu:~/tmp/a>find .git/annex/objects -type f
+.git/annex/objects/Mk/92/WORM-s0-m1310069979--663879656b2e676966687474703a2f2f6d656469612e74756d626c722e636f6d2f74756d626c725f6c656673756557324c703171663879656b2e676966687474703a2f2f6d656469612e74756d626c722e636f6d2f74756d626c725f6c656673756557324c703171663879656b2e676966.gif/WORM-s0-m1310069979--663879656b2e676966687474703a2f2f6d656469612e74756d626c722e636f6d2f74756d626c725f6c656673756557324c703171663879656b2e676966687474703a2f2f6d656469612e74756d626c722e636f6d2f74756d626c725f6c656673756557324c703171663879656b2e676966.gif
+</pre>
+"""]]
diff --git a/doc/bugs/git_annex_add_eats_files_when_filename_is_too_long/comment_2_c6c8d2a1f444d85c582bc5396b08e148._comment b/doc/bugs/git_annex_add_eats_files_when_filename_is_too_long/comment_2_c6c8d2a1f444d85c582bc5396b08e148._comment
new file mode 100644
index 000000000..bd53627bb
--- /dev/null
+++ b/doc/bugs/git_annex_add_eats_files_when_filename_is_too_long/comment_2_c6c8d2a1f444d85c582bc5396b08e148._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnpdM9F8VbtQ_H5PaPMpGSxPe_d5L1eJ6w"
+ nickname="Rafaël"
+ subject="this happens also when the user has not the permission to set the file mode"
+ date="2011-07-08T00:21:31Z"
+ content="""
+For example if the file is owned by root, I guess git-annex fails when it tries to remove write permissions (I retested with the last version of today (whose \"version\" subcommand still outputs 3.20110702)).By the way, it would be nice to have a log file created containing the list of all failures, to avoid having to scan manually all the output of a long git-annex operation.
+"""]]
diff --git a/doc/bugs/git_annex_add_eats_files_when_filename_is_too_long/comment_3_5776864d78d56849001dd12e3adb9cbe._comment b/doc/bugs/git_annex_add_eats_files_when_filename_is_too_long/comment_3_5776864d78d56849001dd12e3adb9cbe._comment
new file mode 100644
index 000000000..f9d1b5d68
--- /dev/null
+++ b/doc/bugs/git_annex_add_eats_files_when_filename_is_too_long/comment_3_5776864d78d56849001dd12e3adb9cbe._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnpdM9F8VbtQ_H5PaPMpGSxPe_d5L1eJ6w"
+ nickname="Rafaël"
+ subject="comment 3"
+ date="2011-07-08T00:45:30Z"
+ content="""
+comment on the output of 'git-annex version' (from my last comment): now I get the right version 3.20110707. But I checked in my console that the three commands \"git checkout 3.20110707\", \"make\" and \"./git-annex version\" gave me before 3.20110702, I don't know why...
+"""]]
diff --git a/doc/bugs/git_annex_add_eats_files_when_filename_is_too_long/comment_4_371ec7b4ae73280ede31edfe90b42a95._comment b/doc/bugs/git_annex_add_eats_files_when_filename_is_too_long/comment_4_371ec7b4ae73280ede31edfe90b42a95._comment
new file mode 100644
index 000000000..1ba57c199
--- /dev/null
+++ b/doc/bugs/git_annex_add_eats_files_when_filename_is_too_long/comment_4_371ec7b4ae73280ede31edfe90b42a95._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 4"
+ date="2011-07-08T01:32:30Z"
+ content="""
+Indeed, I've made it even more robust now, handling the case where the file has weird permissions too, and undoing the failed add so the file is always back at the start state. Had to add a dependency on another haskell module to allow this, so it took some time to figure out how to do it..
+
+"""]]
diff --git a/doc/bugs/git_annex_add_eats_files_when_filename_is_too_long/comment_5_4fb04f646de591640f8504c0caf61acd._comment b/doc/bugs/git_annex_add_eats_files_when_filename_is_too_long/comment_5_4fb04f646de591640f8504c0caf61acd._comment
new file mode 100644
index 000000000..3ece2646f
--- /dev/null
+++ b/doc/bugs/git_annex_add_eats_files_when_filename_is_too_long/comment_5_4fb04f646de591640f8504c0caf61acd._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="ckeen"
+ ip="79.249.110.228"
+ subject="Maybe related to this bug?"
+ date="2013-07-30T14:50:35Z"
+ content="""
+I have noticed similar behaviour with the importfeed command: [[tips/downloading_podcasts/#comment-3e448e43830be7e6dbe59fff6bc81e75]]
+
+After the import fails, the symlinks are created and subsequent get command return with no ouput and error code 0.
+
+Or is this a different bug?
+"""]]
diff --git a/doc/bugs/git_annex_add_eats_files_when_filename_is_too_long/comment_6_b4055409fe48da95bb3101c0242ef0bc._comment b/doc/bugs/git_annex_add_eats_files_when_filename_is_too_long/comment_6_b4055409fe48da95bb3101c0242ef0bc._comment
new file mode 100644
index 000000000..bfdc3bcf9
--- /dev/null
+++ b/doc/bugs/git_annex_add_eats_files_when_filename_is_too_long/comment_6_b4055409fe48da95bb3101c0242ef0bc._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.21"
+ subject="comment 6"
+ date="2013-07-30T17:18:15Z"
+ content="""
+This is an unrelated bug that was fixed 2 years ago.
+"""]]
diff --git a/doc/bugs/git_annex_add_error_with_Andrew_File_System.mdwn b/doc/bugs/git_annex_add_error_with_Andrew_File_System.mdwn
new file mode 100644
index 000000000..bdddd96e2
--- /dev/null
+++ b/doc/bugs/git_annex_add_error_with_Andrew_File_System.mdwn
@@ -0,0 +1,28 @@
+### Please describe the problem.
+I have a git annex clone on Andrew File System. I obtain an error when I try
+to add a file to the annex:
+
+git-annex: test: createLink: unsupported operation (Invalid cross-device link)
+
+### What steps will reproduce the problem?
+Create a test file with touch and add it with git annex add.
+
+### What version of git-annex are you using? On what operating system?
+git-annex 4.20130723 on Debian sid.
+
+### Please provide any additional information below.
+
+[[!format sh """
+gio@crack:~/nobackup/archive$ touch test
+gio@crack:~/nobackup/archive$ git annex add test
+add test
+git-annex: test: createLink: unsupported operation (Invalid cross-device link)
+failed
+git-annex: add: 1 failed
+gio@crack:~/nobackup/archive$ logout
+"""]]
+
+It seems to me that AFS doesn't support hard links between different
+directories.
+
+> [[done]] per comments --[[Joey]]
diff --git a/doc/bugs/git_annex_add_error_with_Andrew_File_System/comment_1_bc783e551fc0e8da87bc95bff5b8f73a._comment b/doc/bugs/git_annex_add_error_with_Andrew_File_System/comment_1_bc783e551fc0e8da87bc95bff5b8f73a._comment
new file mode 100644
index 000000000..7a0d15842
--- /dev/null
+++ b/doc/bugs/git_annex_add_error_with_Andrew_File_System/comment_1_bc783e551fc0e8da87bc95bff5b8f73a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://launchpad.net/~giomasce"
+ nickname="giomasce"
+ subject="Reference"
+ date="2013-08-12T11:39:44Z"
+ content="""
+https://lists.openafs.org/pipermail/openafs-info/2007-December/028158.html
+"""]]
diff --git a/doc/bugs/git_annex_add_error_with_Andrew_File_System/comment_2_faefcf69bd61c47566131cb31b78cc19._comment b/doc/bugs/git_annex_add_error_with_Andrew_File_System/comment_2_faefcf69bd61c47566131cb31b78cc19._comment
new file mode 100644
index 000000000..a2301499c
--- /dev/null
+++ b/doc/bugs/git_annex_add_error_with_Andrew_File_System/comment_2_faefcf69bd61c47566131cb31b78cc19._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 2"
+ date="2013-08-24T19:48:46Z"
+ content="""
+I'm confused by this bug report, because it seems to me I already fixed this same problem in commit a64106dcef5c5aad825662ef115cb2a1cc6985a8. There the problem was that encfs in paranoia mode doesn't support hard links. So I made it detect when createLink fails, and fall back to a code path that doesn't need hard links.
+
+Can you re-check the version you have, and perhaps try with a current daily build?
+"""]]
diff --git a/doc/bugs/git_annex_add_error_with_Andrew_File_System/comment_3_d5014c8b78437b9fddbb1e83d3679081._comment b/doc/bugs/git_annex_add_error_with_Andrew_File_System/comment_3_d5014c8b78437b9fddbb1e83d3679081._comment
new file mode 100644
index 000000000..3d30cea41
--- /dev/null
+++ b/doc/bugs/git_annex_add_error_with_Andrew_File_System/comment_3_d5014c8b78437b9fddbb1e83d3679081._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://launchpad.net/~giomasce"
+ nickname="giomasce"
+ subject="comment 3"
+ date="2013-09-07T15:35:48Z"
+ content="""
+Apparently I wrote a wrong version number. The version actually running on the system I tested is much older. Probably I wrote the one of my own laptop instead.
+
+The bug can be closed, sorry for the noise.
+"""]]
diff --git a/doc/bugs/git_annex_add_memory_leak.mdwn b/doc/bugs/git_annex_add_memory_leak.mdwn
new file mode 100644
index 000000000..4bcffb17b
--- /dev/null
+++ b/doc/bugs/git_annex_add_memory_leak.mdwn
@@ -0,0 +1,39 @@
+For the record, `git annex add` has had a series of memory leaks.
+Mostly these are minor -- until you need to check in a few
+million files in a single operation.
+
+If this happens to you, git-annex will run out of memory and stop.
+(Generally well before your system runs out of memory, since it has some
+built-in ulimits.) You can recover by just re-running the `git annex add`
+-- it will automatically pick up where it left off.
+
+A history of the leaks:
+
+* Originally, `git annex add` remembered all the files
+ it had added, and fed them to git at the end. Of course
+ that made its memory use grow, so it was fixed to periodically
+ flush its buffer. Fixed in version 0.20110417.
+
+* Something called a "lazy state monad" caused "thunks" to build
+ up and memory to leak. Also affected other git annex commands
+ than `add`. Adding files using a SHA* backend hit the worst.
+ Fixed in versions afer 3.20120123.
+
+* Committing journal files turned out to have another memory leak.
+ After adding a lot of files ran out of memory, this left the journal
+ behind and could affect other git-annex commands. Fixed in versions afer
+ 3.20120123.
+
+* The count of the number of failed commands was updated lazily, which
+ caused a slow leak when running on a lot of files. Fixed in versions afer
+ 3.20120123.
+
+* (Note that `git ls-files --others`, which is used to find files to add,
+ also uses surpsisingly large amounts
+ of memory when you have a lot of files. It buffers
+ the entire list, so it can compare it with the files in the index,
+ before outputting anything.
+ This is Not Our Problem, but I'm sure the git developers
+ would appreciate a patch that fixes it.)
+
+[[done]]
diff --git a/doc/bugs/git_annex_add_removes_file_with_no_data_left.mdwn b/doc/bugs/git_annex_add_removes_file_with_no_data_left.mdwn
new file mode 100644
index 000000000..0256c8476
--- /dev/null
+++ b/doc/bugs/git_annex_add_removes_file_with_no_data_left.mdwn
@@ -0,0 +1,103 @@
+### Please describe the problem.
+Using git-annex from Debian (4.20130709), I attempted to add a 410M file named `Expressionlessm.tar`. It acted like it succeeded, but the link it created was broken. Other files would add correctly.
+
+### What steps will reproduce the problem?
+I can reliably cause the file to be removed and replaced with a dangling symlink by doing `git annex add Expressionlessm.tar`. The "addition" completes much faster than normal. Using the old version of git-annex that Ubuntu provides (3.20131112ubuntu4), the file adds correctly in at least one place it was having issues.
+
+### What version of git-annex are you using? On what operating system?
+I'm using the version of git-annex from Debian Sid on Ubuntu 13.04 (perhaps that's my issue?)
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+andrew@andrew-desktop:/media/MainStore/Projects$ git status
+# On branch master
+# Untracked files:
+# (use "git add <file>..." to include in what will be committed)
+#
+==========Snip!=================
+nothing added to commit but untracked files present (use "git add" to track)
+
+
+
+andrew@andrew-desktop:/media/MainStore/Projects$ ls
+==========Snip!=================
+Expressionlessm.tar
+Expressionlessm.tar.bkup
+==========Snip!=================
+
+
+
+andrew@andrew-desktop:/media/MainStore/Projects$ tar tf Expressionlessm.tar
+Expressionlessm/
+==========Snip!=================
+# Tar file is valid at this point
+
+
+andrew@andrew-desktop:/media/MainStore/Projects$ git annex add Expressionlessm.tar
+add Expressionlessm.tar ok
+(Recording state in git...)
+
+
+
+andrew@andrew-desktop:/media/MainStore/Projects$ ls
+==========Snip!=================
+Expressionlessm.tar
+Expressionlessm.tar.bkup
+==========Snip!=================
+
+
+
+andrew@andrew-desktop:/media/MainStore/Projects$ ls -l
+==========Snip!=================
+lrwxrwxrwx 1 andrew andrew 109 Jul 12 02:29 Expressionlessm.tar -> ../.git/annex/objects/vk/mF/SHA256-s3131909--a2808d850ba2e880ac58bf622cd68edd7e72ea2775b984d52b5d5266c43b03f0
+-rw-rw-r-- 1 andrew andrew 428759040 Jul 10 20:30 Expressionlessm.tar.bkup
+==========Snip!=================
+
+
+
+andrew@andrew-desktop:/media/MainStore/Projects$ tar tf Expressionlessm.tar
+tar: Expressionlessm.tar: Cannot open: No such file or directory
+tar: Error is not recoverable: exiting now
+
+
+=================================================================
+W O R K I N G V E R S I O N
+This is what it looks like when the add works.
+=================================================================
+andrew@andrew-desktop:/media/MainStore/Projects$ cp Expressionlessm.tar.bkup Expressionlessm.tar
+andrew@andrew-desktop:/media/MainStore/Projects$ git annex add Expressionlessm.tar
+add Expressionlessm.tar (checksum...) ok
+(Recording state in git...)
+andrew@andrew-desktop:/media/MainStore/Projects$ git status
+# On branch master
+# Changes to be committed:
+# (use "git reset HEAD <file>..." to unstage)
+#
+# new file: Expressionlessm.tar
+#
+# Untracked files:
+==========Snip!=================
+
+
+
+andrew@andrew-desktop:/media/MainStore/Projects$ ls -l
+==========Snip!=================
+lrwxrwxrwx 1 andrew andrew 195 Jul 12 02:20 Expressionlessm.tar -> ../.git/annex/objects/3v/Z7/SHA256-s428759040--133040f7b9d34ebce235aa24a0a16ab72af8f70e7a0722810d873815a2338eb2/SHA256-s428759040--133040f7b9d34ebce235aa24a0a16ab72af8f70e7a0722810d873815a2338eb2
+-rw-rw-r-- 1 andrew andrew 428759040 Jul 10 20:30 Expressionlessm.tar.bkup
+==========Snip!=================
+# Notice the link target is different this time.
+
+
+# End of transcript or log.
+"""]]
+
+> [[done]]; this bug is now prevented on several levels.
+>
+> BTW, the earlier behavior where it didn't even make a valid .git/annex/objects/
+> symlink is also explained by this bug I've fixed. It pulled a truncated
+> link out of the tarball, and used that.
+> --[[Joey]]
diff --git a/doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_10_9cc749a6efd4359a99316036f5bc867f._comment b/doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_10_9cc749a6efd4359a99316036f5bc867f._comment
new file mode 100644
index 000000000..aa3d2c79b
--- /dev/null
+++ b/doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_10_9cc749a6efd4359a99316036f5bc867f._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="andy"
+ ip="108.202.17.204"
+ subject="comment 10"
+ date="2013-07-20T23:50:50Z"
+ content="""
+Wow! Thanks!
+
+I'd be happy to help test something if you need.
+
+Also, I just want to say that I really appreciate your openness about the process of fixing this, and that you so quickly deleted the part of the file you didn't need. It's not particularly sensitive, but I really like how you handled that. Thank you.
+"""]]
diff --git a/doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_11_1fed5be9db29866e4dc3d3bb12907bf3._comment b/doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_11_1fed5be9db29866e4dc3d3bb12907bf3._comment
new file mode 100644
index 000000000..95309dcf6
--- /dev/null
+++ b/doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_11_1fed5be9db29866e4dc3d3bb12907bf3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.140"
+ subject="comment 11"
+ date="2013-07-21T00:25:04Z"
+ content="""
+I've updated the linux daily builds with this bug fix, so if you want to you can get the new standalone tarball and use that.
+"""]]
diff --git a/doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_12_06d517ac4ef8def4629a40d7c3549bac._comment b/doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_12_06d517ac4ef8def4629a40d7c3549bac._comment
new file mode 100644
index 000000000..30a6526f0
--- /dev/null
+++ b/doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_12_06d517ac4ef8def4629a40d7c3549bac._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="andy"
+ ip="108.202.17.204"
+ subject="comment 12"
+ date="2013-07-21T04:47:33Z"
+ content="""
+Thanks! Works great!
+"""]]
diff --git a/doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_1_8f081aeba7065d143a453dc128543f59._comment b/doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_1_8f081aeba7065d143a453dc128543f59._comment
new file mode 100644
index 000000000..89531ca16
--- /dev/null
+++ b/doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_1_8f081aeba7065d143a453dc128543f59._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.140"
+ subject="comment 1"
+ date="2013-07-18T19:37:33Z"
+ content="""
+Sorry about the delay getting to this, I've been overloaded.
+
+The link that you show:
+
+`Expressionlessm.tar -> ../.git/annex/objects/vk/mF/SHA256-s3131909--a2808d850ba2e880ac58bf622cd68edd7e72ea2775b984d52b5d5266c`
+
+.. That's not right at all. I don't understand in the least how this could happen, and am flummoxed how to try to debug it. It just doesn't match anything I know about how the code works.
+
+If I understand you correctly, it's only happening with one particular file content.
+
+I think you either need to rule out it being due to the way you've installed git-annex, perhaps by installing the linux standalone tarball, and seeing if you can get the same behavior with that. Or you could send me the repository by email (joey@kitenet.net) and I'll see if I can reproduce it, and if so, will certainly be able to debug and fix it.
+"""]]
diff --git a/doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_2_54a4b10723fd8a80dd486377ff15ce0d._comment b/doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_2_54a4b10723fd8a80dd486377ff15ce0d._comment
new file mode 100644
index 000000000..7ac34e751
--- /dev/null
+++ b/doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_2_54a4b10723fd8a80dd486377ff15ce0d._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.140"
+ subject="comment 2"
+ date="2013-07-18T19:46:12Z"
+ content="""
+Hmm, given the size of the repo, please don't email it directly, if you choose to do that. But getting me access to it would certainly be useful.
+
+
+"""]]
diff --git a/doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_3_f1964e4e07991a251c2795da0361a4e2._comment b/doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_3_f1964e4e07991a251c2795da0361a4e2._comment
new file mode 100644
index 000000000..68ca291d2
--- /dev/null
+++ b/doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_3_f1964e4e07991a251c2795da0361a4e2._comment
@@ -0,0 +1,28 @@
+[[!comment format=mdwn
+ username="andy"
+ ip="108.202.17.204"
+ subject="Further testing"
+ date="2013-07-19T06:02:53Z"
+ content="""
+I've just tried it again with the git-annex-standalone-amd64.tar.gz bundle. The problem seems to persist.
+
+I've got a typescript (with no timing info) of the problem occurring with the bundle that I could e-mail to you if it would be of any help. I could also get you the ~410M file that's having issues if you're interested. FWIW, its SHA256 according to `sha256sum` on Ubuntu is `133040f7b9d34ebce235aa24a0a16ab72af8f70e7a0722810d873815a2338eb2`.
+
+ andrew@andrew-desktop:/media/MainStore$ lsb_release -a
+ No LSB modules are available.
+ Distributor ID: Ubuntu
+ Description: Ubuntu 13.04
+ Release: 13.04
+ Codename: raring
+
+
+
+ andrew@andrew-desktop:/media/MainStore/testspace$ ls -l
+ total 8
+ lrwxrwxrwx 1 andrew andrew 180 Jul 18 22:09 demofile -> .git/annex/objects/10/8J/SHA256E-s11--896769fb2f15d59f398863a11f3e0aaafac022bb99dfd6db34d7c78e1da307e3/SHA256E-s11--896769fb2f15d59f398863a11f3e0aaafac022bb99dfd6db34d7c78e1da307e3
+ lrwxrwxrwx 1 andrew andrew 188 Jul 18 22:10 express.tar -> .git/annex/objects/vk/mF/SHA256-s3131909--a2808d850ba2e880ac58bf622cd68edd7e72ea2775b984d52b5d5266c43b03f0/SHA256-s3131909--a2808d850ba2e880ac58bf622cd68edd7e72ea2775b984d52b5d5266c43b03f0
+
+
+Notice that the path to the file has changed from the version posted before.
+--Andy
+"""]]
diff --git a/doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_4_73c38d843c30f00f6fd8883db8e55f62._comment b/doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_4_73c38d843c30f00f6fd8883db8e55f62._comment
new file mode 100644
index 000000000..9d68a431c
--- /dev/null
+++ b/doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_4_73c38d843c30f00f6fd8883db8e55f62._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.140"
+ subject="comment 4"
+ date="2013-07-20T19:54:59Z"
+ content="""
+You don't seem to be getting the broken symlink when using the bundle. Is the symlink still not pointing to the content of the file?
+
+I do think I will need the file to debug further, unless you'd like to go on a possibly hundred step round-trip debugging sage with me.
+"""]]
diff --git a/doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_5_7ede5ee312f3abdf78979c0d52a7871a._comment b/doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_5_7ede5ee312f3abdf78979c0d52a7871a._comment
new file mode 100644
index 000000000..ccf5e574f
--- /dev/null
+++ b/doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_5_7ede5ee312f3abdf78979c0d52a7871a._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="andy"
+ ip="108.202.17.204"
+ subject="comment 5"
+ date="2013-07-20T21:34:08Z"
+ content="""
+Yes, the symlink was still broken. Or rather, `tar -tf filename.tar` didn't like the file.
+
+The file's about 193 M bzipped. I'll be e-mailing you a link to an S3 copy with DojOsEf2 in the subject line of the email--once the upload finishes. :)
+
+I'm not sure if this is relevant, but the file is a tar of an annex and another git repo. Perhaps that is influencing something (although I presume it shouldn't)?
+"""]]
diff --git a/doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_6_e37cf18708f09619442c3a9532d12ed9._comment b/doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_6_e37cf18708f09619442c3a9532d12ed9._comment
new file mode 100644
index 000000000..c1056de9e
--- /dev/null
+++ b/doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_6_e37cf18708f09619442c3a9532d12ed9._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.140"
+ subject="comment 6"
+ date="2013-07-20T22:43:27Z"
+ content="""
+Got the file. Verified checksum.
+
+Reproduced bug!
+
+Wow, it really seems to be a bug specific to this one particular
+file content. That's crazy.
+"""]]
diff --git a/doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_7_a744ef7dd3a224a911ebb24858bc2fd6._comment b/doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_7_a744ef7dd3a224a911ebb24858bc2fd6._comment
new file mode 100644
index 000000000..aa60ef2fc
--- /dev/null
+++ b/doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_7_a744ef7dd3a224a911ebb24858bc2fd6._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.140"
+ subject="comment 7"
+ date="2013-07-20T23:00:59Z"
+ content="""
+Can be reproduced with first 500kb of file. I have deleted all the rest of the file, without looking at it. (Scout's honor!)
+"""]]
diff --git a/doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_8_f97141b255073b90120895148220c2d7._comment b/doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_8_f97141b255073b90120895148220c2d7._comment
new file mode 100644
index 000000000..8bde55470
--- /dev/null
+++ b/doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_8_f97141b255073b90120895148220c2d7._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.140"
+ subject="comment 8"
+ date="2013-07-20T23:07:17Z"
+ content="""
+Ok, it is in fact relevant that the file is a tarball of a git-annex repository, because git-annex add turns out to be looking at the beginning of the file, and seeing that it contains a git-annex link.
+
+I thought that code was only supposed to fire in repos on FAT filesystems that don't have symlinks. So, several issues to fix here, it seems..
+"""]]
diff --git a/doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_9_dd2be11dfd190129d491f5f891e7cd1a._comment b/doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_9_dd2be11dfd190129d491f5f891e7cd1a._comment
new file mode 100644
index 000000000..f7ae63cf8
--- /dev/null
+++ b/doc/bugs/git_annex_add_removes_file_with_no_data_left/comment_9_dd2be11dfd190129d491f5f891e7cd1a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.140"
+ subject="comment 9"
+ date="2013-07-20T23:26:09Z"
+ content="""
+Ok, I've put in 2 separate bug fixes, any one of which would have been sufficient to prevent this data loss. Am working on a third fix to detect this kind of problem at a higher level and avoid losing content even if it gets all confused.
+
+This bug may be a candidate to be backported to Debian stable, since it causes data loss.
+"""]]
diff --git a/doc/bugs/git_annex_assistant_--autostart_failed.mdwn b/doc/bugs/git_annex_assistant_--autostart_failed.mdwn
new file mode 100644
index 000000000..8833944ec
--- /dev/null
+++ b/doc/bugs/git_annex_assistant_--autostart_failed.mdwn
@@ -0,0 +1,39 @@
+**What steps will reproduce the problem?**
+
+Run *git annex assistant --autostart*
+
+ git-annex autostart in /home/tobru/annex/repo1
+ failed
+ git-annex autostart in /home/tobru/annex/repo2
+ failed
+ git-annex autostart in /home/tobru/annex/repo3
+ failed
+ git-annex autostart in /home/tobru/annex/repo4
+ failed
+ git-annex autostart in /home/tobru/annex/repo5
+ failed
+
+Running *git annex assistant* in each directory starts the assistant without errors.
+
+What could cause autostart to fail? Is there any log? Or a --debug parameter?
+
+
+**What is the expected output? What do you see instead?**
+
+The assistant should start on all known repositories
+
+**What version of git-annex are you using? On what operating system?**
+
+4.20130417-g4bb97d5 on Ubuntu
+
+**Please provide any additional information below.**
+
+The ~/.config/git-annex/autostart file looks like this:
+
+ /home/tobru/annex/repo1
+ /home/tobru/annex/repo2
+ /home/tobru/annex/repo3
+ /home/tobru/annex/repo4
+ /home/tobru/annex/repo5
+
+> Closing, seems local misconfiguration. --[[Joey]] [[done]]
diff --git a/doc/bugs/git_annex_assistant_--autostart_failed/comment_1_746545273b53849c42ff6272324e5155._comment b/doc/bugs/git_annex_assistant_--autostart_failed/comment_1_746545273b53849c42ff6272324e5155._comment
new file mode 100644
index 000000000..7267ec1c4
--- /dev/null
+++ b/doc/bugs/git_annex_assistant_--autostart_failed/comment_1_746545273b53849c42ff6272324e5155._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-04-18T20:08:12Z"
+ content="""
+The most likely cause of this error is a bad `~/.config/git-annex/program` file. Either the file is missing, or it points to the wrong location for the git-annex command. All that --autostart does is run the program listed on that file in each repository listed in the autostart file. Note that you don't need the file when git-annex is installed in your PATH.
+
+So, how did you install git-annex?
+"""]]
diff --git a/doc/bugs/git_annex_assistant_--autostart_failed/comment_2_5bdf6f94da12e551ae12e7f550a84d62._comment b/doc/bugs/git_annex_assistant_--autostart_failed/comment_2_5bdf6f94da12e551ae12e7f550a84d62._comment
new file mode 100644
index 000000000..6fb9fba9d
--- /dev/null
+++ b/doc/bugs/git_annex_assistant_--autostart_failed/comment_2_5bdf6f94da12e551ae12e7f550a84d62._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawniayrgSdVLUc3c6bf93VbO-_HT4hzxmyo"
+ nickname="Tobias"
+ subject="comment 2"
+ date="2013-04-19T06:48:39Z"
+ content="""
+You're right, this files was the problem. I recently removed my manually downloaded standalone tarball and switched to use gitannex-install. So the path was not correct anymore... Thanks a lot for the hint!
+"""]]
diff --git a/doc/bugs/git_annex_assistant_--autostart_failed/comment_3_bfd646f69946a5fe926b270cf94f87cb._comment b/doc/bugs/git_annex_assistant_--autostart_failed/comment_3_bfd646f69946a5fe926b270cf94f87cb._comment
new file mode 100644
index 000000000..e53a3115d
--- /dev/null
+++ b/doc/bugs/git_annex_assistant_--autostart_failed/comment_3_bfd646f69946a5fe926b270cf94f87cb._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn26WQjIP5fnMgQF_L_k3Q3UrR5v8mjRTY"
+ nickname="Ellis"
+ subject="comment 3"
+ date="2013-05-06T18:24:35Z"
+ content="""
+I just had the exact same issue. Thanks for posting the fix.
+"""]]
diff --git a/doc/bugs/git_annex_content_fails_with_a_parse_error.txt b/doc/bugs/git_annex_content_fails_with_a_parse_error.txt
new file mode 100644
index 000000000..38c8fa28d
--- /dev/null
+++ b/doc/bugs/git_annex_content_fails_with_a_parse_error.txt
@@ -0,0 +1,32 @@
+### Please describe the problem.
+
+I tried to use git annex content, but that failed with a parse error.
+
+
+### What steps will reproduce the problem?
+
+Type this anywhere:
+
+git annex --debug content . "exclude(foo.ml)"
+content . git-annex: Parse error: Parse failure: near "foo.ml"
+
+It fails with the example of the man page:
+ git annex content . "include(*.mp3) or include(*.ogg)"
+
+However, it works when trying: git annex content . "include()".
+
+### What version of git-annex are you using? On what operating system?
+
+git-annex version: 4.20130709.1, ubuntu quantal
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
+
+> Fixed the example, thanks. --[[Joey]] [[done]]
diff --git a/doc/bugs/git_annex_content_fails_with_a_parse_error/comment_1_2b60b6ae0115de13ecf837b34dadcd1d._comment b/doc/bugs/git_annex_content_fails_with_a_parse_error/comment_1_2b60b6ae0115de13ecf837b34dadcd1d._comment
new file mode 100644
index 000000000..75a157964
--- /dev/null
+++ b/doc/bugs/git_annex_content_fails_with_a_parse_error/comment_1_2b60b6ae0115de13ecf837b34dadcd1d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="Matt"
+ ip="78.251.139.64"
+ subject="Correct syntax"
+ date="2013-07-15T08:46:51Z"
+ content="""
+After some digging, it turned out that the correct syntax is git annex content . \"include=*.mp3 or include=*.ogg\". So it is more a documentation bug
+"""]]
diff --git a/doc/bugs/git_annex_copy_--fast_does_not_copy_files.mdwn b/doc/bugs/git_annex_copy_--fast_does_not_copy_files.mdwn
new file mode 100644
index 000000000..9b84c21fd
--- /dev/null
+++ b/doc/bugs/git_annex_copy_--fast_does_not_copy_files.mdwn
@@ -0,0 +1,22 @@
+Workflow:
+
+ % git annex add
+ # list new files
+ % git commit -a -m "foo"
+ # commit summary
+ % git annex copy . --to remote --fast
+ # all files listed with "ok"
+ % git annex copy . --to remote
+ # again, lists all files, _but the new ones are actually copied, this time_.
+
+This happens no matter if I
+
+ % git push
+
+before copy or not.
+
+PS: Arguably, a copy should push automagically.
+
+> Whups, not supposed to be that fast! [[Fixed|done]], and
+> you should run `git annex fsck --fast` on the repo you ran the
+> copy in. --[[Joey]]
diff --git a/doc/bugs/git_annex_copy_-f_REMOTE_._doesn__39__t_work_as_expected.mdwn b/doc/bugs/git_annex_copy_-f_REMOTE_._doesn__39__t_work_as_expected.mdwn
new file mode 100644
index 000000000..3bda45149
--- /dev/null
+++ b/doc/bugs/git_annex_copy_-f_REMOTE_._doesn__39__t_work_as_expected.mdwn
@@ -0,0 +1,18 @@
+I was testing out the fix/workaround for [[git-annex directory hashing problems on osx]] and I tried using the short forms of some of the commands i.e.
+
+ git annex copy -f externalusb .
+
+which gives me
+
+ git-annex: user error (option `-f' is ambiguous; could be one of:
+ -f --force allow actions that may lose annexed data
+ -f REMOTE --from=REMOTE specify from where to transfer content
+
+
+I would have expected that since *--to* is the same as *-t* and *--from* is the same as *-f* as the in program documentation suggests. But *-f* clashes with the force command, I would suggest that the short form of *--force* be changed to *-F* and possibly rename the *Fast* commands to *Quick* and use *-Q* as the short form of the *Quick* operations. I didn't try the *-f* option with the move command, but it probably suffers from the same issue. It's probably better to avoid clashing short forms of command options.
+
+I guess this issue is just a documentation issue and a minor interface change if needed and not a bug of git-annex, but a quirk.
+
+> Yeah, -f needs to be from; -F was already --fast. I have made --force not
+> have any short option abbreviation, I think it's entirely reasonable to
+> avoid fat-fingering an option that can lose data. [[done]] --[[Joey]]
diff --git a/doc/bugs/git_annex_copy_trying_to_connect_to_remotes_uninvolved.mdwn b/doc/bugs/git_annex_copy_trying_to_connect_to_remotes_uninvolved.mdwn
new file mode 100644
index 000000000..f41a80616
--- /dev/null
+++ b/doc/bugs/git_annex_copy_trying_to_connect_to_remotes_uninvolved.mdwn
@@ -0,0 +1,27 @@
+git-annex is trying to ssh (twice by the look of it) to a remote that is not involved in the copy. In this case, git-annex gives a usage error, but not before calling ssh twice:
+
+ $ git annex copy --from=hugex --to=h2 01-pilot.avi
+ ssh: connect to host 192.168.1.5 port 22: No route to host
+ ssh: connect to host 192.168.1.5 port 22: No route to host
+ fatal: Could not read from remote repository.
+
+ Please make sure you have the correct access rights
+ and the repository exists.
+ git-annex: only one of --from or --to can be specified
+
+git-annex shouldn't be running ssh before checking commandline arguments! Or, in this case at all, since both remotes mentioned on the commandline are local:
+
+ $ git config remote.hugex.url
+ /media/hugex/jason/home.git
+ $ git config remote.h2.url
+ /media/h2/backup/git/home.git
+
+
+I'm running git-annex 4.20130627 as shipped with debian unstable.
+
+--
+Jason
+
+P.S. 192.168.1.5 is set as the HostName for one of my other remotes in my ~/.ssh/config, so this isn't _totally_ out of the blue.
+
+> [[done]]; see comment's explanation. --[[Joey]]
diff --git a/doc/bugs/git_annex_copy_trying_to_connect_to_remotes_uninvolved/comment_1_f1330935a07460c9c8bc82ee8d4709c5._comment b/doc/bugs/git_annex_copy_trying_to_connect_to_remotes_uninvolved/comment_1_f1330935a07460c9c8bc82ee8d4709c5._comment
new file mode 100644
index 000000000..2595e083b
--- /dev/null
+++ b/doc/bugs/git_annex_copy_trying_to_connect_to_remotes_uninvolved/comment_1_f1330935a07460c9c8bc82ee8d4709c5._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.193"
+ subject="comment 1"
+ date="2013-06-30T17:27:07Z"
+ content="""
+git-annex needs to discover the uuid of each remote before it can use it. So it currently goes off the discover these uuids at startup time.
+
+If you have a remote that you do not want git-annex to use, you can set remote.name.annex-ignore and it will not do this discovery process for that remote.
+
+While it would be possible to defer the lookup until an operation that needs to know the remote's uuid, it would complicate the code quite a bit, so I have not tried to do so.
+"""]]
diff --git a/doc/bugs/git_annex_dead_does_not_work_as_expected_when_multiple_repos_exist_with_the_same_name___40__notably_including_dead_ones__41__.mdwn b/doc/bugs/git_annex_dead_does_not_work_as_expected_when_multiple_repos_exist_with_the_same_name___40__notably_including_dead_ones__41__.mdwn
new file mode 100644
index 000000000..7e26f63df
--- /dev/null
+++ b/doc/bugs/git_annex_dead_does_not_work_as_expected_when_multiple_repos_exist_with_the_same_name___40__notably_including_dead_ones__41__.mdwn
@@ -0,0 +1,42 @@
+### Please describe the problem.
+
+Creating two repos with the same name causes git annex dead to randomly choose one. This is reasonable except that it can choose to mark an already dead remote dead (as long as it shares the name), causing it to actually do nothing.
+
+I think preferring to mark live repos dead and printing a warning when multiple repos could have been chosen (or if the repo is already marked dead) would be a good solution.
+
+### What steps will reproduce the problem?
+
+[[!format sh """
+# Create a new repo /somecopy
+git clone /central /somecopy
+cd /somecopy
+git annex init somecopy
+git annex sync
+cd /
+
+# Now, git annex status shows somecopy as an existing repo.
+
+# Destroy the new repo
+rm -rf /somecopy
+cd /central
+git annex dead somecopy
+
+# git annex status correctly hides somecopy, and it is properly dead.
+
+# create it again with the same name, but new UUID
+git clone /central /somecopy
+cd /somecopy
+git annex init somecopy
+git annex sync
+cd /
+
+# Destroy the second repo
+rm -rf /somecopy
+cd /central
+"""]]
+
+Now, git annex dead somecopy will randomly (based on the order of the UUIDs?) choose to mark dead the already dead old repo or the new repo, in both cases showing success to the user.
+
+### What version of git-annex are you using? On what operating system?
+
+git-annex 4.20131024 on linux. Also occurs on OSX.
diff --git a/doc/bugs/git_annex_dead_does_not_work_as_expected_when_multiple_repos_exist_with_the_same_name___40__notably_including_dead_ones__41__/comment_1_7ee08a60e4b2516c010d3c2163049681._comment b/doc/bugs/git_annex_dead_does_not_work_as_expected_when_multiple_repos_exist_with_the_same_name___40__notably_including_dead_ones__41__/comment_1_7ee08a60e4b2516c010d3c2163049681._comment
new file mode 100644
index 000000000..3875affb7
--- /dev/null
+++ b/doc/bugs/git_annex_dead_does_not_work_as_expected_when_multiple_repos_exist_with_the_same_name___40__notably_including_dead_ones__41__/comment_1_7ee08a60e4b2516c010d3c2163049681._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 1"
+ date="2013-10-29T21:10:53Z"
+ content="""
+I don't think it's a good idea to give multiple repos the same description.
+
+You can use the uuid to refer to a repo unambiguously in this situation.
+
+I think it would add unncessary complication to make git-annex guess which repository you mean based on context
+(ie, choosing repositories that are not already dead). This would make commands that are currently idempotent not be.
+
+Perhaps git-annex should abort when multiple repositories match the given description? (Relevant code is Remote.nameToUUID's bydescription)
+"""]]
diff --git a/doc/bugs/git_annex_dead_does_not_work_as_expected_when_multiple_repos_exist_with_the_same_name___40__notably_including_dead_ones__41__/comment_2_c29525bfda08717f68aaac83014e6b08._comment b/doc/bugs/git_annex_dead_does_not_work_as_expected_when_multiple_repos_exist_with_the_same_name___40__notably_including_dead_ones__41__/comment_2_c29525bfda08717f68aaac83014e6b08._comment
new file mode 100644
index 000000000..17191be04
--- /dev/null
+++ b/doc/bugs/git_annex_dead_does_not_work_as_expected_when_multiple_repos_exist_with_the_same_name___40__notably_including_dead_ones__41__/comment_2_c29525bfda08717f68aaac83014e6b08._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmGxww5ON3nilm7moGQCWJPnMEdRwNvb7U"
+ nickname="Chris"
+ subject="comment 2"
+ date="2013-10-29T22:01:04Z"
+ content="""
+I didn't think about idempotency. Erroring out seems like the best option now.
+"""]]
diff --git a/doc/bugs/git_annex_describe_can_break_uuid.log.mdwn b/doc/bugs/git_annex_describe_can_break_uuid.log.mdwn
new file mode 100644
index 000000000..16e6981f5
--- /dev/null
+++ b/doc/bugs/git_annex_describe_can_break_uuid.log.mdwn
@@ -0,0 +1,46 @@
+### Please describe the problem.
+
+`uuid.log` can end up in a state where `git annex describe` (and probably other things) stops working.
+
+### What steps will reproduce the problem?
+
+Run `git annex describe` against a remote that is not a an initialized git-annex repo.
+
+### What version of git-annex are you using? On what operating system?
+
+debian-packaged git-annex 4.20131106 on Linux Mint 13/Maya (Ubuntu Precise/12.04)
+
+### Please provide any additional information below.
+
+I will follow comments, but can also be found at [[https://microca.st/clacke]].
+
+Full transcript to reproduce:
+
+[[!format sh """
+$ git init a
+Initialized empty Git repository in /tmp/annex/a/.git/
+$ git init b
+Initialized empty Git repository in /tmp/annex/b/.git/
+$ cd a/
+$ git annex init
+init ok
+(Recording state in git...)
+$ git remote add -f b ../b
+Updating b
+$ git annex describe b b # this should not be ok
+describe b ok
+(Recording state in git...)
+$ git annex describe b b
+describe b git-annex: Prelude.last: empty list
+$ git cat-file blob git-annex:uuid.log
+ b timestamp=1383987654.900868s
+...
+
+# End of transcript.
+"""]]
+
+> Fixed the bug and made git breakage not crash git-annex. [[done]]
+> --[[Joey]]
+
+> > Update: Also made it automatically clean up the cruft this put in the
+> > log. --[[Joey]]
diff --git a/doc/bugs/git_annex_describe_can_break_uuid.log/comment_2_9ead36f13cbde6c822b231441de636ae._comment b/doc/bugs/git_annex_describe_can_break_uuid.log/comment_2_9ead36f13cbde6c822b231441de636ae._comment
new file mode 100644
index 000000000..a5616234e
--- /dev/null
+++ b/doc/bugs/git_annex_describe_can_break_uuid.log/comment_2_9ead36f13cbde6c822b231441de636ae._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://id.clacke.se/"
+ nickname="clacke"
+ subject="comment 2"
+ date="2013-11-11T05:32:14Z"
+ content="""
+Great, thanks!
+"""]]
diff --git a/doc/bugs/git_annex_does_nothing_useful.mdwn b/doc/bugs/git_annex_does_nothing_useful.mdwn
new file mode 100644
index 000000000..b68e53da9
--- /dev/null
+++ b/doc/bugs/git_annex_does_nothing_useful.mdwn
@@ -0,0 +1,67 @@
+As you can see, I'm running a pretty recent build of git-annex (ac799c3f363e0008b23e9c174e6fedc35e6fa92a),
+
+ $ git annex version
+ git-annex version: 3.20120630
+ local repository version: 3
+ default repository version: 3
+ supported repository versions: 3
+ upgrade supported from repository versions: 0 1 2
+
+We have a file here which isn't currently available yet isn't
+currently available (the link is shown in red),
+
+ $ ls -l plot.py
+ lrwxrwxrwx 1 ben ben 77 Jul 6 14:01 plot.py -> ../.git/annex/objects/WORM:1301941019:720:plot.py/WORM:1301941019:720:plot.py
+ $
+
+Yet git-annex should be able to tell us where it is,
+
+ $ git-annex whereis plot.py
+ $
+
+Hmm, well that's strange. What's happening here,
+
+ $ git-annex whereis plot.py -d
+ git ["--git-dir=/home/ben/lori/analysis/data/.git","--work-tree=/home/ben/lori/analysis/data","show-ref","git-annex"]
+ git ["--git-dir=/home/ben/lori/analysis/data/.git","--work-tree=/home/ben/lori/analysis/data","show-ref","--hash","refs/heads/git-annex"]
+ git ["--git-dir=/home/ben/lori/analysis/data/.git","--work-tree=/home/ben/lori/analysis/data","log","refs/heads/git-annex..d5582e05f41011b571a17003934fe9e40859e4be","--oneline","-n1"]
+ git ["--git-dir=/home/ben/lori/analysis/data/.git","--work-tree=/home/ben/lori/analysis/data","cat-file","--batch"]
+ git ["--git-dir=/home/ben/lori/analysis/data/.git","--work-tree=/home/ben/lori/analysis/data","ls-files","--cached","-z","--","plot.py"]
+ $
+
+Alright, well maybe `git-annex get` will work,
+
+ $ git annex get plot.py -d
+ git ["--git-dir=/home/ben/lori/analysis/data/.git","--work-tree=/home/ben/lori/analysis/data","ls-files","--cached","-z","--","plot.py"]
+ $ ls -l plot.py
+ lrwxrwxrwx 1 ben ben 77 Jul 6 14:01 plot.py -> ../.git/annex/objects/WORM:1301941019:720:plot.py/WORM:1301941019:720:plot.py
+
+Nope, the link is still shown in red.
+
+Alright, what about `git-annex copy`?
+
+ $ git annex copy plot.py --from=goldnerlab --to=here -d
+ git ["--git-dir=/home/ben/lori/analysis/data/.git","--work-tree=/home/ben/lori/analysis/data","show-ref","git-annex"]
+ git ["--git-dir=/home/ben/lori/analysis/data/.git","--work-tree=/home/ben/lori/analysis/data","show-ref","--hash","refs/heads/git-annex"]
+ git ["--git-dir=/home/ben/lori/analysis/data/.git","--work-tree=/home/ben/lori/analysis/data","log","refs/heads/git-annex..d5582e05f41011b571a17003934fe9e40859e4be","--oneline","-n1"]
+ git ["--git-dir=/home/ben/lori/analysis/data/.git","--work-tree=/home/ben/lori/analysis/data","cat-file","--batch"]
+ git ["--git-dir=/home/ben/lori/analysis/data/.git","--work-tree=/home/ben/lori/analysis/data","ls-files","--cached","-z","--","plot.py"]
+ $ ls -l plot.py
+ lrwxrwxrwx 1 ben ben 77 Jul 6 14:01 plot.py -> ../.git/annex/objects/WORM:1301941019:720:plot.py/WORM:1301941019:720:plot.py
+
+Still red.
+
+Alright, what if I just try to get a non-existent file?
+
+ $ git annex get adsflkah -d
+ git ["--git-dir=/home/ben/lori/analysis/data/.git","--work-tree=/home/ben/lori/analysis/data","ls-files","--cached","-z","--","adsflkah"]
+ $
+
+Alright, it didn't fail with an error, that's very strange. What is going on here?
+
+[[!meta title="v1 file is ignored"]]
+
+> I don't think I want to make git-annex deal with v1 files, and
+> I doubt there are many repos left using them. This seems to be a case
+> of an upgrade not being done, for whatever reason. Closing [[done]]
+> --[[Joey]]
diff --git a/doc/bugs/git_annex_does_nothing_useful/comment_10_457354dc0018333002dc5049935c0feb._comment b/doc/bugs/git_annex_does_nothing_useful/comment_10_457354dc0018333002dc5049935c0feb._comment
new file mode 100644
index 000000000..266cff3db
--- /dev/null
+++ b/doc/bugs/git_annex_does_nothing_useful/comment_10_457354dc0018333002dc5049935c0feb._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlup4hyZo4eCjF8T85vfRXMKBxGj9bMdl0"
+ nickname="Ben"
+ subject="comment 10"
+ date="2012-07-10T14:17:42Z"
+ content="""
+Hmm, the commands above seem to have worked on both machines (both running 3.20120630). I guess I should probably just try rebuilding my data/ repository from scratch, eh?
+"""]]
diff --git a/doc/bugs/git_annex_does_nothing_useful/comment_11_8a6d244165dd238ddf9dd629795de2f6._comment b/doc/bugs/git_annex_does_nothing_useful/comment_11_8a6d244165dd238ddf9dd629795de2f6._comment
new file mode 100644
index 000000000..1de08ae60
--- /dev/null
+++ b/doc/bugs/git_annex_does_nothing_useful/comment_11_8a6d244165dd238ddf9dd629795de2f6._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="comment 11"
+ date="2012-07-10T14:26:06Z"
+ content="""
+I suppose.. joey can probably help you investigate exactly what went wrong. You might want to save an empty clone of the git repository for later..
+
+The easiest way to fix the data is probably to run a `git annex uninit` in the old repository which will put the files back how they were before and then `git-annex import` them into a new repository.
+"""]]
diff --git a/doc/bugs/git_annex_does_nothing_useful/comment_12_30d06bc0f1c37d988a1a31962b57533c._comment b/doc/bugs/git_annex_does_nothing_useful/comment_12_30d06bc0f1c37d988a1a31962b57533c._comment
new file mode 100644
index 000000000..3de157752
--- /dev/null
+++ b/doc/bugs/git_annex_does_nothing_useful/comment_12_30d06bc0f1c37d988a1a31962b57533c._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="165.98.113.100"
+ subject="comment 12"
+ date="2012-07-11T23:23:04Z"
+ content="""
+Looking at this a leetle more closely, you had:
+
+<pre>
+lrwxrwxrwx 1 ben ben 77 Jul 6 14:01 plot.py -> ../.git/annex/objects/WORM:1301941019:720:plot.py/WORM:1301941019:720:plot.py
+</pre>
+
+Well, that is not how a git-annex symlink currently looks, so it ignores it.
+
+Apparenly this repository was created with an old version of git-annex, possibly version 1, and you've dropped in the current version, but the normal upgrade machinery failed. This could happen if you made a new clone of a version 1 bare repository.
+
+I suggest you first find out what version of git-annex was originally used to create this repository (ie, version 0, 1, or 2 ... probably 1). Then make a clone, and \"git config annex.version $N\" where N=the version used). Then \"git annex upgrade\" and you should be good to go. Remember to push or sync the upgrade back to the bare repo so you don't need to do this again.
+"""]]
diff --git a/doc/bugs/git_annex_does_nothing_useful/comment_1_fc4f51ddcbc69631e2835b86c3489c8e._comment b/doc/bugs/git_annex_does_nothing_useful/comment_1_fc4f51ddcbc69631e2835b86c3489c8e._comment
new file mode 100644
index 000000000..6bf6e96f6
--- /dev/null
+++ b/doc/bugs/git_annex_does_nothing_useful/comment_1_fc4f51ddcbc69631e2835b86c3489c8e._comment
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ subject="comment 1"
+ date="2012-07-09T23:16:32Z"
+ content="""
+`git ls-files` is not listing your file. Perhaps your file is not checked into git?
+"""]]
diff --git a/doc/bugs/git_annex_does_nothing_useful/comment_2_9bb1647e6c59f1ed7b13b81ecc33f920._comment b/doc/bugs/git_annex_does_nothing_useful/comment_2_9bb1647e6c59f1ed7b13b81ecc33f920._comment
new file mode 100644
index 000000000..3423bfae4
--- /dev/null
+++ b/doc/bugs/git_annex_does_nothing_useful/comment_2_9bb1647e6c59f1ed7b13b81ecc33f920._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlup4hyZo4eCjF8T85vfRXMKBxGj9bMdl0"
+ nickname="Ben"
+ subject="comment 2"
+ date="2012-07-09T23:31:08Z"
+ content="""
+Not really sure what to say about that other than,
+
+ $ git --git-dir=/home/ben/lori/analysis/data/.git --work-tree=/home/ben/lori/analysis/data ls-files --cached -- plot.py
+ plot.py
+ $
+
+"""]]
diff --git a/doc/bugs/git_annex_does_nothing_useful/comment_3_d434f5c614a27b75d73530b5b918b851._comment b/doc/bugs/git_annex_does_nothing_useful/comment_3_d434f5c614a27b75d73530b5b918b851._comment
new file mode 100644
index 000000000..f03aa2745
--- /dev/null
+++ b/doc/bugs/git_annex_does_nothing_useful/comment_3_d434f5c614a27b75d73530b5b918b851._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="Remotes? "
+ date="2012-07-10T00:23:11Z"
+ content="""
+What does
+
+ git-annex status
+
+Show?
+
+Do you have any remotes configured? It looks like you don't somehow.
+"""]]
diff --git a/doc/bugs/git_annex_does_nothing_useful/comment_4_998e33219d29ea41b0b2a5d2955a9862._comment b/doc/bugs/git_annex_does_nothing_useful/comment_4_998e33219d29ea41b0b2a5d2955a9862._comment
new file mode 100644
index 000000000..fc9f6c30c
--- /dev/null
+++ b/doc/bugs/git_annex_does_nothing_useful/comment_4_998e33219d29ea41b0b2a5d2955a9862._comment
@@ -0,0 +1,46 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlup4hyZo4eCjF8T85vfRXMKBxGj9bMdl0"
+ nickname="Ben"
+ subject="comment 4"
+ date="2012-07-10T01:46:23Z"
+ content="""
+ $ git annex status
+ supported backends: SHA256 SHA1 SHA512 SHA224 SHA384 SHA256E SHA1E SHA512E SHA224E SHA384E WORM URL
+ supported remote types: git S3 bup directory rsync web hook
+ trusted repositories: 0
+ semitrusted repositories: 3
+ 00000000-0000-0000-0000-000000000001 -- web
+ 02e4ea72-a77c-11e1-bbd7-0749b04e4b59 -- goldnerlab (Data for Goldner)
+ 3c1fd026-c794-11e1-8ebb-dbe8684e8a73 -- here
+ untrusted repositories: 0
+ dead repositories: 0
+ transfers in progress: none
+ available local disk space: 16 gigabytes (+1 megabyte reserved)
+ local annex keys: 0
+ local annex size: 0 bytes
+ known annex keys: 0
+ known annex size: 0 bytes
+ bloom filter size: 16 mebibytes (0% full)
+ backend usage:
+ $ git remote
+ goldnerlab
+ $ git remote show goldnerlab
+ * remote goldnerlab
+ Fetch URL: goldnerlab:data
+ Push URL: goldnerlab:data
+ HEAD branch (remote HEAD is ambiguous, may be one of the following):
+ master
+ synced/master
+ Remote branches:
+ git-annex tracked
+ master tracked
+ synced/master tracked
+ Local branch configured for 'git pull':
+ master merges with remote master
+ Local refs configured for 'git push':
+ git-annex pushes to git-annex (up to date)
+ master pushes to master (up to date)
+ synced/master pushes to synced/master (up to date)
+
+
+"""]]
diff --git a/doc/bugs/git_annex_does_nothing_useful/comment_5_c72e2571e5b8c06bbfa2276a7ad1e8a6._comment b/doc/bugs/git_annex_does_nothing_useful/comment_5_c72e2571e5b8c06bbfa2276a7ad1e8a6._comment
new file mode 100644
index 000000000..90159b5b4
--- /dev/null
+++ b/doc/bugs/git_annex_does_nothing_useful/comment_5_c72e2571e5b8c06bbfa2276a7ad1e8a6._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="comment 5"
+ date="2012-07-10T03:03:27Z"
+ content="""
+Well that's odd. You have remotes but no annexed files..
+
+Can you post the commands you used to arrive at this situation? I'm not sure how you would have done that.. Maybe you just need a
+
+ git-annex sync
+
+to get things going?
+
+I think somehow you cloned the git repo but not the annex stuff.
+"""]]
diff --git a/doc/bugs/git_annex_does_nothing_useful/comment_6_bc8b42432ba25de8f972c192bc3cdff6._comment b/doc/bugs/git_annex_does_nothing_useful/comment_6_bc8b42432ba25de8f972c192bc3cdff6._comment
new file mode 100644
index 000000000..ad98e6874
--- /dev/null
+++ b/doc/bugs/git_annex_does_nothing_useful/comment_6_bc8b42432ba25de8f972c192bc3cdff6._comment
@@ -0,0 +1,44 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlup4hyZo4eCjF8T85vfRXMKBxGj9bMdl0"
+ nickname="Ben"
+ subject="comment 6"
+ date="2012-07-10T03:26:35Z"
+ content="""
+I can easily reproduce the issue as follows,
+
+ $ git clone goldnerlab:data
+ Cloning into 'data'...
+ remote: Counting objects: 61902, done.
+ remote: Compressing objects: 100% (61354/61354), done.
+ remote: Total 61902 (delta 356), reused 61902 (delta 356)
+ Receiving objects: 100% (61902/61902), 5.50 MiB | 894 KiB/s, done.
+ Resolving deltas: 100% (356/356), done.
+ $ cd data
+ $ git annex sync
+ (merging origin/git-annex into git-annex...)
+ commit
+ (Recording state in git...)
+ # On branch master
+ nothing to commit (working directory clean)
+ ok
+ pull origin
+ ok
+ push origin
+ Counting objects: 8, done.
+ Delta compression using up to 2 threads.
+ Compressing objects: 100% (5/5), done.
+ Writing objects: 100% (6/6), 726 bytes, done.
+ Total 6 (delta 1), reused 1 (delta 0)
+ Auto packing the repository for optimum performance.
+ warning: There are too many unreachable loose objects; run 'git prune' to remove them.
+ To goldnerlab:data
+ d5582e0..aaddf3c git-annex -> git-annex
+ ok
+
+Everything looks good so far. I verify that alex/plot.py doesn't exist. Now let's try getting it,
+
+ $ git annex get alex/plot.py -d
+ git [\"--git-dir=/home/ben/data/.git\",\"--work-tree=/home/ben/data\",\"ls-files\",\"--cached\",\"-z\",\"--\",\"alex/plot.py\"]
+
+Uh oh. ls confirms that get was unsucessful.
+"""]]
diff --git a/doc/bugs/git_annex_does_nothing_useful/comment_7_e7469a4c5e45078ade775f5cbdd17cfc._comment b/doc/bugs/git_annex_does_nothing_useful/comment_7_e7469a4c5e45078ade775f5cbdd17cfc._comment
new file mode 100644
index 000000000..c40e4e2cf
--- /dev/null
+++ b/doc/bugs/git_annex_does_nothing_useful/comment_7_e7469a4c5e45078ade775f5cbdd17cfc._comment
@@ -0,0 +1,67 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="comment 7"
+ date="2012-07-10T12:37:43Z"
+ content="""
+But how was the goldnerlab:data repository created? That looks to be where the problem is..
+
+I have a slightly older version, but in general it should work the same..
+you can see right away, when I do git annex status it shows \"known annex keys: 1\".
+if you do git annex status on goldnerlab, does it say you have any annex keys?
+
+
+ $ git-annex version
+ git-annex version: 3.20120614~bpo60+1
+ $ mkdir a
+ $ cd a
+ $ git init
+ Initialized empty Git repository in /tmp/a/.git/
+ $ git annex init a
+ init a ok
+ (Recording state in git...)
+ $ echo hi > file
+ $ git annex add file
+ add file (checksum...) ok
+ (Recording state in git...)
+ $ git commit -m added
+ fatal: No HEAD commit to compare with (yet)
+ fatal: No HEAD commit to compare with (yet)
+ [master (root-commit) cfa9049] added
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+ create mode 120000 file
+ $ cd ..
+ $ git clone a a_clone
+ Cloning into a_clone...
+ done.
+ $ cd a_clone
+ $ git annex status
+ (merging origin/git-annex into git-annex...)
+ supported backends: SHA256 SHA1 SHA512 SHA224 SHA384 SHA256E SHA1E SHA512E SHA224E SHA384E WORM URL
+ supported remote types: git bup directory rsync web hook
+ trusted repositories: 0
+ semitrusted repositories: 3
+ 00000000-0000-0000-0000-000000000001 -- web
+ 445d616e-ca8b-11e1-b170-ff8b03c54243 -- origin (a)
+ 5d3db51c-ca8b-11e1-bbc3-039dd06ab47b -- here
+ untrusted repositories: 0
+ dead repositories: 0
+ available local disk space: 63 megabytes (+1 megabyte reserved)
+ local annex keys: 0
+ local annex size: 0 bytes
+ known annex keys: 1
+ known annex size: 3 bytes
+ backend usage:
+ SHA256: 1
+ (Recording state in git...)
+ $ ls
+ file
+ $ cat file
+ cat: file: No such file or directory
+ $ git annex get file
+ get file (from origin...) ok
+ (Recording state in git...)
+ $ cat file
+ hi
+
+"""]]
diff --git a/doc/bugs/git_annex_does_nothing_useful/comment_8_bc9e6fd284440a59ffe4e4ed1f73f7d7._comment b/doc/bugs/git_annex_does_nothing_useful/comment_8_bc9e6fd284440a59ffe4e4ed1f73f7d7._comment
new file mode 100644
index 000000000..85d03f04b
--- /dev/null
+++ b/doc/bugs/git_annex_does_nothing_useful/comment_8_bc9e6fd284440a59ffe4e4ed1f73f7d7._comment
@@ -0,0 +1,30 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlup4hyZo4eCjF8T85vfRXMKBxGj9bMdl0"
+ nickname="Ben"
+ subject="comment 8"
+ date="2012-07-10T13:02:37Z"
+ content="""
+On goldnerlab,
+
+ $ git annex status
+ supported backends: SHA256 SHA1 SHA512 SHA224 SHA384 SHA256E SHA1E SHA512E SHA224E SHA384E WORM URL
+ supported remote types: git S3 bup directory rsync web hook
+ trusted repositories: 0
+ semitrusted repositories: 4
+ 00000000-0000-0000-0000-000000000001 -- web
+ 02e4ea72-a77c-11e1-bbd7-0749b04e4b59 -- here (Data for Goldner)
+ 351f3ddc-ca3e-11e1-a3fc-6338ef4724a7
+ 3c1fd026-c794-11e1-8ebb-dbe8684e8a73
+ untrusted repositories: 0
+ dead repositories: 0
+ transfers in progress: none
+ available local disk space: 2 terabytes (+1 megabyte reserved)
+ local annex keys: 19101
+ local annex size: 41 gigabytes
+ known annex keys: 19122
+ known annex size: 41 gigabytes
+ bloom filter size: 16 mebibytes (3.8% full)
+ backend usage:
+ WORM: 38223
+
+"""]]
diff --git a/doc/bugs/git_annex_does_nothing_useful/comment_9_38a2dbeee3750d79ca9a943a02fceb29._comment b/doc/bugs/git_annex_does_nothing_useful/comment_9_38a2dbeee3750d79ca9a943a02fceb29._comment
new file mode 100644
index 000000000..dc3206ac5
--- /dev/null
+++ b/doc/bugs/git_annex_does_nothing_useful/comment_9_38a2dbeee3750d79ca9a943a02fceb29._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="comment 9"
+ date="2012-07-10T14:08:10Z"
+ content="""
+Can you run the series of commands I had above on your two machines? I figure there are two possibilities:
+
+1. There is something wrong with the git-annex versions you are using.
+2. There is something wrong with your repository. (\"warning: There are too many unreachable loose objects\"?)
+
+so if you can make a temp repository on goldnerlab, then clone it on the other machine and see where it fails, that would be helpful.
+
+after cloning git-annex status should hopefully say that you have 1 known key, not 0.
+
+Obviously this won't fix the problem, but it will at least narrow it down.
+"""]]
diff --git a/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9.mdwn b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9.mdwn
new file mode 100644
index 000000000..2169372a2
--- /dev/null
+++ b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9.mdwn
@@ -0,0 +1,220 @@
+### Please describe the problem.
+git-annex crashes on Max OS X 10.9 at startup
+
+### What steps will reproduce the problem?
+- install Mac OS X 10.9 developer preview
+- download and install the latest git-annex from here http://downloads.kitenet.net/git-annex/OSX/current/10.8.2_Mountain_Lion/ (I tried with the 10.8 version)
+- attempt to start it, see it crashing
+
+### What version of git-annex are you using? On what operating system?
+- latest version that is available for 10.8, on 10.9 DP 2
+
+### Please provide any additional information below.
+
+I see the following in Console:
+
+15.07.2013 21:20:49,362 com.apple.launchd.peruser.501[259]: (com.branchable.git-annex.103872[67263]) Exited with code: 133
+15.07.2013 21:20:49,546 ReportCrash[67272]: Saved crash report for git-annex[67268] version ??? to /Users/stelianiancu/Library/Logs/DiagnosticReports/git-annex_2013-07-15-212049_poseidon-2.crash
+
+And the crash is as follows:
+
+Process: git-annex [67268]
+Path: /Applications/git-annex.app/Contents/MacOS/bundle/git-annex
+Identifier: git-annex
+Version: ???
+Code Type: X86-64 (Native)
+Parent Process: sh [67263]
+Responsible: sh [67263]
+User ID: 501
+
+Date/Time: 2013-07-15 21:20:48.946 +0200
+OS Version: Mac OS X 10.9 (13A497d)
+Report Version: 11
+Anonymous UUID: 634E8812-1F1A-11E0-61DA-7527061A194C
+
+Sleep/Wake UUID: AFC18477-57D2-4B69-8B0F-AE26BC3D9D0C
+
+Crashed Thread: 0
+
+Exception Type: EXC_BREAKPOINT (SIGTRAP)
+Exception Codes: 0x0000000000000002, 0x0000000000000000
+
+Application Specific Information:
+dyld: launch, loading dependent libraries
+
+Dyld Error Message:
+ Symbol not found: _objc_debug_taggedpointer_mask
+ Referenced from: /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
+ Expected in: /Applications/git-annex.app/Contents/MacOS/bundle/I
+ in /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
+
+Binary Images:
+ 0x104412000 - 0x10450fff7 +E (22.3) <47B09CB2-C636-3024-8B55-6040F7829B4C> /Applications/git-annex.app/Contents/MacOS/bundle/E
+ 0x104547000 - 0x10455bfff +F (0) <FA90B1B1-A866-3A6C-BB97-06955F4C8C0B> /Applications/git-annex.app/Contents/MacOS/bundle/F
+ 0x104567000 - 0x104594ff7 +G (0) <E276B5C2-6FAC-36A7-940B-7A75322F71AE> /Applications/git-annex.app/Contents/MacOS/bundle/G
+ 0x10459c000 - 0x104669fdf +H (0) <29C3AFF5-8EFB-3A16-81F6-0DA6CF2675A6> /Applications/git-annex.app/Contents/MacOS/bundle/H
+ 0x104699000 - 0x1046abff7 +B (43) <2A1551E8-A272-3DE5-B692-955974FE1416> /Applications/git-annex.app/Contents/MacOS/bundle/B
+ 0x1046b1000 - 0x1047a6fff +D (34) <FEE8B996-EB44-37FA-B96E-D379664DEFE1> /Applications/git-annex.app/Contents/MacOS/bundle/D
+ 0x1047b7000 - 0x1048cf92f +I (532.2) <90D31928-F48D-3E37-874F-220A51FD9E37> /Applications/git-annex.app/Contents/MacOS/bundle/I
+ 0x1048f6000 - 0x104af6fff +S (491.11.3) <5783D305-04E8-3D17-94F7-1CEAFA975240> /Applications/git-annex.app/Contents/MacOS/bundle/S
+ 0x104c06000 - 0x104c2bff7 +Z (26) <D86169F3-9F31-377A-9AF3-DB17142052E4> /Applications/git-annex.app/Contents/MacOS/bundle/Z
+ 0x104c5e000 - 0x104cc6ff7 +0A (65.1) <20E31B90-19B9-3C2A-A9EB-474E08F9FE05> /Applications/git-annex.app/Contents/MacOS/bundle/0A
+ 0x104d21000 - 0x104d8afff +0B (56) <EAA2B53E-EADE-39CF-A0EF-FB9D4940672A> /Applications/git-annex.app/Contents/MacOS/bundle/0B
+ 0x104df3000 - 0x104e06fff +T (0) <DB28CA35-537D-3644-A6BE-179D1A1E9785> /Applications/git-annex.app/Contents/MacOS/bundle/T
+ 0x104e0e000 - 0x104e1bff7 +U (0) <DCFF385A-090B-3407-868C-91544A2EFEE1> /Applications/git-annex.app/Contents/MacOS/bundle/U
+ 0x104e1f000 - 0x104e41ff7 +V (0) <51B317C7-94CC-3C58-B515-924BB3AF0BCC> /Applications/git-annex.app/Contents/MacOS/bundle/V
+ 0x104e4e000 - 0x104e5bff7 +W (0) <91CF16BE-027F-3FE6-B1EE-6B8BFD51FC1B> /Applications/git-annex.app/Contents/MacOS/bundle/W
+ 0x104e68000 - 0x104ec4fd7 +X (0) <84D934AF-A321-36C0-BBCF-CD3FDAEB0B95> /Applications/git-annex.app/Contents/MacOS/bundle/X
+ 0x7fff6ca9d000 - 0x7fff6cad04a7 dyld (237) <BB7160C2-117E-3369-87F0-866ED454490E> /usr/lib/dyld
+ 0x7fff8ba5b000 - 0x7fff8ba5dfff libCVMSPluginSupport.dylib (9.0.74) <11FCA581-0FFD-37B1-966A-E47F4722D297> /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libCVMSPluginSupport.dylib
+ 0x7fff8c053000 - 0x7fff8c05affb liblaunch.dylib (842.1.1) <7055DF9E-52CE-3746-96EB-3718DDBF0BD0> /usr/lib/system/liblaunch.dylib
+ 0x7fff8c11d000 - 0x7fff8c41cff7 com.apple.Foundation (6.9 - 1042) <CE00D0BB-1053-3EA0-A31F-C9F1E3FEFBF2> /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation
+ 0x7fff8c41d000 - 0x7fff8c444ff7 libsystem_network.dylib (241.3) <D518703F-4C71-3CC5-99EF-A15C8F41A834> /usr/lib/system/libsystem_network.dylib
+ 0x7fff8c445000 - 0x7fff8c47eff7 com.apple.QD (3.49 - 297) <EE1DD6BE-5881-35C7-A9E8-30CCB26E6CF3> /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/QD.framework/Versions/A/QD
+ 0x7fff8c483000 - 0x7fff8c864ffe libLAPACK.dylib (1094.4) <19E25957-74BA-3770-AAB5-B6A05F19BDC2> /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libLAPACK.dylib
+ 0x7fff8c8bc000 - 0x7fff8c8cbff8 com.apple.LangAnalysis (1.7.0 - 1.7.0) <ED300EBD-7AEF-34B4-B314-DFBD648214E1> /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/LangAnalysis.framework/Versions/A/LangAnalysis
+ 0x7fff8c8cc000 - 0x7fff8c8d9ff7 libxar.1.dylib (202) <E0BFCC9B-89D4-3F42-8460-4918573EFCA1> /usr/lib/libxar.1.dylib
+ 0x7fff8c8da000 - 0x7fff8cbaaff4 com.apple.CoreImage (9.0.33) <8BB17AEC-D09A-3173-8767-7DB5C982670E> /System/Library/Frameworks/QuartzCore.framework/Versions/A/Frameworks/CoreImage.framework/Versions/A/CoreImage
+ 0x7fff8cbab000 - 0x7fff8cbabff7 libkeymgr.dylib (28) <AB6DE146-DDC4-397B-9182-ECE54FCDF5D7> /usr/lib/system/libkeymgr.dylib
+ 0x7fff8d095000 - 0x7fff8d09eff7 com.apple.speech.synthesis.framework (4.5.3 - 4.5.3) <B4B4F401-701F-3A6E-AB39-65BDBB9F3FA0> /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/SpeechSynthesis.framework/Versions/A/SpeechSynthesis
+ 0x7fff8d21a000 - 0x7fff8d274ff8 com.apple.AE (665.2 - 665.2) <DB39E7DF-E5EA-3D5C-81A5-1BA2159A2694> /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/AE.framework/Versions/A/AE
+ 0x7fff8d2fb000 - 0x7fff8d342ff7 libcups.2.dylib (365) <49F3E642-D748-3A60-AF51-F9E90F65C543> /usr/lib/libcups.2.dylib
+ 0x7fff8d343000 - 0x7fff8d350ff0 libbz2.1.0.dylib (29) <C1100E81-9C9D-3E4E-B238-F4015BB35B15> /usr/lib/libbz2.1.0.dylib
+ 0x7fff8d489000 - 0x7fff8d489fff com.apple.Accelerate (1.9 - Accelerate 1.9) <94C28250-6BDB-30AD-B157-995D9C34A6FA> /System/Library/Frameworks/Accelerate.framework/Versions/A/Accelerate
+ 0x7fff8d75b000 - 0x7fff8d7a8fff com.apple.opencl (2.3.50 - 2.3.50) <33C1EC76-02A2-3474-BB9D-8F77B96E57CC> /System/Library/Frameworks/OpenCL.framework/Versions/A/OpenCL
+ 0x7fff8dd58000 - 0x7fff8dd5dff7 libunwind.dylib (35.3) <838CE69D-44F1-305C-8FA5-5E439D217F78> /usr/lib/system/libunwind.dylib
+ 0x7fff8dd5e000 - 0x7fff8dd61fff libCoreVMClient.dylib (58.1) <331C429A-3AE5-30B8-A4DE-1BF4EE4D8FA6> /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libCoreVMClient.dylib
+ 0x7fff8de3e000 - 0x7fff8de3fff7 libDiagnosticMessagesClient.dylib (100) <B28C426E-E826-3EC3-80AD-E69F2EABE46B> /usr/lib/libDiagnosticMessagesClient.dylib
+ 0x7fff8de40000 - 0x7fff8de6ffff com.apple.DebugSymbols (106 - 106) <545E5A48-3516-3398-A33D-D6FB4FED4B7B> /System/Library/PrivateFrameworks/DebugSymbols.framework/Versions/A/DebugSymbols
+ 0x7fff8e4b2000 - 0x7fff8e500fff libcorecrypto.dylib (161) <56048D2C-3668-3E15-AF02-5C5A377320F6> /usr/lib/system/libcorecrypto.dylib
+ 0x7fff8e501000 - 0x7fff8e5c7ff7 com.apple.LaunchServices (572.3 - 572.3.1) <39618733-CC97-3991-BD3B-485BD7247115> /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/LaunchServices
+ 0x7fff8e5ca000 - 0x7fff8e5caffd libOpenScriptingUtil.dylib (154) <9B8CECA0-360D-3C6D-A37D-95EE34AE2B16> /usr/lib/libOpenScriptingUtil.dylib
+ 0x7fff8e9ac000 - 0x7fff8e9b4ff7 com.apple.speech.recognition.framework (4.2.4 - 4.2.4) <1CE37DE8-BA4A-30CD-A802-18DAF42C328F> /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/SpeechRecognition.framework/Versions/A/SpeechRecognition
+ 0x7fff8ea01000 - 0x7fff8ea65ff6 com.apple.Heimdal (4.0 - 2.0) <463F41AC-39FF-30FC-B03A-4198E7A9321F> /System/Library/PrivateFrameworks/Heimdal.framework/Versions/A/Heimdal
+ 0x7fff8ea66000 - 0x7fff8ea6efff libsystem_dnssd.dylib (522.1.3) <29695A12-75FC-36EE-97AC-179F6E9DA419> /usr/lib/system/libsystem_dnssd.dylib
+ 0x7fff8eb28000 - 0x7fff8eb33fff libGL.dylib (9.0.74) <2DB19533-5983-3F59-93F3-2761DA6EEDA5> /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib
+ 0x7fff8eb37000 - 0x7fff8eb43ff3 com.apple.AppleFSCompression (56 - 1.0) <D80DF0B8-AC14-3686-9242-9750D6A8B8D3> /System/Library/PrivateFrameworks/AppleFSCompression.framework/Versions/A/AppleFSCompression
+ 0x7fff8eb44000 - 0x7fff8f44a043 com.apple.CoreGraphics (1.600.0 - 565) <81F84822-675E-3466-97A7-6FF69DF569E3> /System/Library/Frameworks/CoreGraphics.framework/Versions/A/CoreGraphics
+ 0x7fff8f44b000 - 0x7fff8f461fff com.apple.CFOpenDirectory (10.9 - 171) <A650D21D-D825-3C4E-AA2E-1218F8A5048E> /System/Library/Frameworks/OpenDirectory.framework/Versions/A/Frameworks/CFOpenDirectory.framework/Versions/A/CFOpenDirectory
+ 0x7fff9003c000 - 0x7fff900c5fe7 libsystem_c.dylib (997) <5BAB0B09-A39E-39B9-9552-48B540B3ABD0> /usr/lib/system/libsystem_c.dylib
+ 0x7fff9088e000 - 0x7fff908b2fff libJPEG.dylib (1029) <D161F451-9A14-31DD-83D8-C475F8576ACF> /System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/libJPEG.dylib
+ 0x7fff908b3000 - 0x7fff908f7ffe com.apple.HIServices (1.22 - 454) <3625AF2C-1965-349D-B831-1FCC9084B675> /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/HIServices.framework/Versions/A/HIServices
+ 0x7fff908f8000 - 0x7fff90bc7fdf com.apple.vImage (7.0 - 7.0) <C50F8737-E292-3D53-9AF7-F76797A1DDDD> /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vImage.framework/Versions/A/vImage
+ 0x7fff90ce8000 - 0x7fff90d03ff7 libsystem_kernel.dylib (2422.1.26.0.1) <5F99677C-C760-3877-AFF7-F60B5ECE365E> /usr/lib/system/libsystem_kernel.dylib
+ 0x7fff90d04000 - 0x7fff90d77ffb com.apple.securityfoundation (6.0 - 55122) <A946CA5A-1396-3467-94B1-E6A8FA0347FC> /System/Library/Frameworks/SecurityFoundation.framework/Versions/A/SecurityFoundation
+ 0x7fff90e98000 - 0x7fff91034fff com.apple.QuartzCore (1.8 - 329.0) <08CE1885-71E8-3A38-AEB6-4BBB1A43785F> /System/Library/Frameworks/QuartzCore.framework/Versions/A/QuartzCore
+ 0x7fff91035000 - 0x7fff91050ff7 libPng.dylib (1029) <AB7D23B2-CB41-3108-A19E-9F7BA6F37178> /System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/libPng.dylib
+ 0x7fff910c3000 - 0x7fff9113aff7 com.apple.CoreServices.OSServices (600 - 600) <73820122-62D4-359C-9312-CD49FCEDFE09> /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/OSServices.framework/Versions/A/OSServices
+ 0x7fff9115a000 - 0x7fff911e5fff com.apple.Metadata (10.7.0 - 778.1) <93F05A4E-6581-3CD5-8697-84783CEBF764> /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/Metadata.framework/Versions/A/Metadata
+ 0x7fff9139d000 - 0x7fff913a4ff3 libcopyfile.dylib (103) <54DD5730-3F05-3F18-B55C-24EA9546286F> /usr/lib/system/libcopyfile.dylib
+ 0x7fff9152c000 - 0x7fff91530ff7 libheimdal-asn1.dylib (323.3) <90100758-0CC6-3D00-90AB-D3C7DC8CCE45> /usr/lib/libheimdal-asn1.dylib
+ 0x7fff9193c000 - 0x7fff91947fff libkxld.dylib (2422.1.26.0.1) <CF43FD8E-E8FE-34F7-A3B1-286530AA9EFD> /usr/lib/system/libkxld.dylib
+ 0x7fff9194e000 - 0x7fff91950ff7 libquarantine.dylib (69) <1776AABC-F1D7-3CB0-B698-B0C70D4E535B> /usr/lib/system/libquarantine.dylib
+ 0x7fff91951000 - 0x7fff9195efff com.apple.Sharing (112 - 112) <24BA2112-4FFB-318A-B881-93FEB4648371> /System/Library/PrivateFrameworks/Sharing.framework/Versions/A/Sharing
+ 0x7fff919fb000 - 0x7fff91a02ff7 libsystem_pthread.dylib (53) <2160EC74-26FC-32CE-8161-B1A72D2B09B0> /usr/lib/system/libsystem_pthread.dylib
+ 0x7fff91a03000 - 0x7fff91a2cfff com.apple.DictionaryServices (1.2 - 197) <862F498E-3CB7-3087-BB07-AC185D5D08F8> /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/DictionaryServices.framework/Versions/A/DictionaryServices
+ 0x7fff91a3c000 - 0x7fff91b04ff7 libvDSP.dylib (423.29) <72A38066-D6F5-38EC-A8B9-0D025AFC6E2B> /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libvDSP.dylib
+ 0x7fff91b05000 - 0x7fff91b43ff7 libGLImage.dylib (9.0.74) <0DD99DA1-A8E7-3309-8DED-A2AB410E59C8> /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGLImage.dylib
+ 0x7fff92ade000 - 0x7fff92b00fff libxpc.dylib (300.1.4) <4F832032-9709-3E80-91C4-71914C67A32B> /usr/lib/system/libxpc.dylib
+ 0x7fff92b01000 - 0x7fff92b04ff7 libdyld.dylib (237) <EA2A0414-849F-3976-BA4E-A93D3206ECE5> /usr/lib/system/libdyld.dylib
+ 0x7fff92b05000 - 0x7fff92b05fff com.apple.ApplicationServices (48 - 48) <21188B7D-50E8-3C28-A15E-5345AE7BAFBB> /System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices
+ 0x7fff92b08000 - 0x7fff92b6cff7 com.apple.datadetectorscore (5.0 - 343.0) <7FE14856-0C85-3382-AD6C-1B9E21C276CB> /System/Library/PrivateFrameworks/DataDetectorsCore.framework/Versions/A/DataDetectorsCore
+ 0x7fff92b6d000 - 0x7fff92b6fff3 libsystem_configuration.dylib (596.1) <1E0FDEA3-8822-3E80-AA0D-57D0F4E30E2E> /usr/lib/system/libsystem_configuration.dylib
+ 0x7fff92e00000 - 0x7fff92e53fff com.apple.ScalableUserInterface (1.0 - 1) <A82F7DD8-1C79-3872-96D1-875B4ED121D4> /System/Library/Frameworks/QuartzCore.framework/Versions/A/Frameworks/ScalableUserInterface.framework/Versions/A/ScalableUserInterface
+ 0x7fff92e72000 - 0x7fff92e73fff libunc.dylib (28) <53C7CED6-55F5-3121-B00E-4339C29297C8> /usr/lib/system/libunc.dylib
+ 0x7fff92e91000 - 0x7fff92f53ff9 com.apple.CoreText (352.0 - 367.6) <CAFF0767-3351-3FE3-843F-6EA65B8264C8> /System/Library/Frameworks/CoreText.framework/Versions/A/CoreText
+ 0x7fff934c7000 - 0x7fff934e2ff7 libCRFSuite.dylib (34) <E2353929-97B1-356A-84A0-CC650BC734D5> /usr/lib/libCRFSuite.dylib
+ 0x7fff934e3000 - 0x7fff93508ffb com.apple.CoreVideo (1.8 - 117.0) <50587BF1-D111-3D49-9DAB-8F86B5E95808> /System/Library/Frameworks/CoreVideo.framework/Versions/A/CoreVideo
+ 0x7fff93509000 - 0x7fff93522ff7 com.apple.Kerberos (3.0 - 1) <13DDC487-95C0-379F-BD7F-E0FC5F5922D3> /System/Library/Frameworks/Kerberos.framework/Versions/A/Kerberos
+ 0x7fff93523000 - 0x7fff935a2fff com.apple.CoreSymbolication (3.0 - 137) <85C4F6E2-5039-3E53-9AB2-6D65CAC9AAC5> /System/Library/PrivateFrameworks/CoreSymbolication.framework/Versions/A/CoreSymbolication
+ 0x7fff935a3000 - 0x7fff935bdfff libsystem_malloc.dylib (23.1.1) <FBCF2C62-AA8D-322E-859E-B5D90C610A3F> /usr/lib/system/libsystem_malloc.dylib
+ 0x7fff935bf000 - 0x7fff93600ff7 com.apple.PerformanceAnalysis (1.45 - 45) <6C498B15-45DB-362F-983B-764ECC9B8E21> /System/Library/PrivateFrameworks/PerformanceAnalysis.framework/Versions/A/PerformanceAnalysis
+ 0x7fff9360f000 - 0x7fff93618ff3 libsystem_notify.dylib (121) <D34E9B17-297F-3C3F-BD16-69D1D9495B79> /usr/lib/system/libsystem_notify.dylib
+ 0x7fff93619000 - 0x7fff9362bff7 com.apple.MultitouchSupport.framework (245.12 - 245.12) <06CAA8FB-BEC6-3EF1-96FA-3D8A1EEB0959> /System/Library/PrivateFrameworks/MultitouchSupport.framework/Versions/A/MultitouchSupport
+ 0x7fff9367e000 - 0x7fff9368efff libbsm.0.dylib (33) <65C2FC5C-4B4B-3C1B-B935-D67A3BF96A79> /usr/lib/libbsm.0.dylib
+ 0x7fff937f6000 - 0x7fff937fafff libpam.2.dylib (20) <17E3DA0D-EE71-3398-BA30-BDD8514A6135> /usr/lib/libpam.2.dylib
+ 0x7fff93aea000 - 0x7fff93aedfff libsystem_stats.dylib (93.1.8.1.1) <CAC30E07-CE62-3536-8CD4-1A3CE44DD973> /usr/lib/system/libsystem_stats.dylib
+ 0x7fff93b96000 - 0x7fff93d79ff7 com.apple.CoreFoundation (6.9 - 842) <DC8875C4-DC2C-3ADC-B88B-D66722953255> /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
+ 0x7fff93d7a000 - 0x7fff93db9fff libGLU.dylib (9.0.74) <294F4F86-E900-356C-9A47-0C47A929F2FB> /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGLU.dylib
+ 0x7fff93dba000 - 0x7fff93e9cff7 com.apple.backup.framework (1.5 - 1.5) <70E20485-EDB6-3225-8AF6-6D9494CB98B7> /System/Library/PrivateFrameworks/Backup.framework/Versions/A/Backup
+ 0x7fff93edb000 - 0x7fff93ee6ff7 com.apple.NetAuth (5.0 - 5.0) <64D42204-C075-3440-8C29-BBD68A99A771> /System/Library/PrivateFrameworks/NetAuth.framework/Versions/A/NetAuth
+ 0x7fff93ee7000 - 0x7fff93ef3fff com.apple.OpenDirectory (10.9 - 171) <FDE80473-0ADF-363A-8111-43CAB01A3F61> /System/Library/Frameworks/OpenDirectory.framework/Versions/A/OpenDirectory
+ 0x7fff93f3a000 - 0x7fff93f48ff7 com.apple.opengl (9.0.74 - 9.0.74) <9BD0013A-E503-3DA2-9F94-C42A11D2E734> /System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL
+ 0x7fff93f56000 - 0x7fff93f85ff5 com.apple.GSS (4.0 - 2.0) <6765C9D7-8AC9-3694-B5D4-5C26B119851D> /System/Library/Frameworks/GSS.framework/Versions/A/GSS
+ 0x7fff943f6000 - 0x7fff943fdfff libcompiler_rt.dylib (35) <A0A9D62C-E1A5-39A0-A38E-B0B38762002D> /usr/lib/system/libcompiler_rt.dylib
+ 0x7fff943fe000 - 0x7fff94404fef libsystem_platform.dylib (24) <5D8FE8C3-2A62-3705-AB7D-FBD7C284AFBD> /usr/lib/system/libsystem_platform.dylib
+ 0x7fff94405000 - 0x7fff9440fff7 com.apple.CrashReporterSupport (10.9 - 529) <F3BB7C5D-0775-3A05-944A-3A061E62B107> /System/Library/PrivateFrameworks/CrashReporterSupport.framework/Versions/A/CrashReporterSupport
+ 0x7fff94428000 - 0x7fff9442bffc com.apple.IOSurface (91 - 91) <1B7746FC-3599-3BDB-A0DA-65795C999435> /System/Library/Frameworks/IOSurface.framework/Versions/A/IOSurface
+ 0x7fff9442c000 - 0x7fff944dbff7 libvMisc.dylib (423.29) <83CBEBB6-B9C2-3D83-A32A-CED47CDB65D6> /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libvMisc.dylib
+ 0x7fff9451b000 - 0x7fff9451cffb libremovefile.dylib (33) <D7EF6E8B-95D8-3D8E-918C-2D3F51D00060> /usr/lib/system/libremovefile.dylib
+ 0x7fff9465b000 - 0x7fff94898fff com.apple.CoreData (107 - 468) <51F9B655-84D2-3E88-991B-914C9017BB08> /System/Library/Frameworks/CoreData.framework/Versions/A/CoreData
+ 0x7fff948ab000 - 0x7fff948acfff com.apple.TrustEvaluationAgent (2.0 - 25) <644D981B-A5A7-31F5-99A6-9F180B9A5DE3> /System/Library/PrivateFrameworks/TrustEvaluationAgent.framework/Versions/A/TrustEvaluationAgent
+ 0x7fff948ad000 - 0x7fff948d0fff com.apple.IconServices (25 - 25.4) <525BAAE5-F45C-3A15-ACED-2AF4EFFED546> /System/Library/PrivateFrameworks/IconServices.framework/Versions/A/IconServices
+ 0x7fff948f6000 - 0x7fff94be0ff7 com.apple.CoreServices.CarbonCore (1077.6 - 1077.6) <C32B5E2A-3BD8-3D6C-A931-E05B47ECB3C9> /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CarbonCore.framework/Versions/A/CarbonCore
+ 0x7fff94be1000 - 0x7fff94c09ffb libxslt.1.dylib (13) <33D39746-6FCD-3F32-AFAE-2E45232BF6FB> /usr/lib/libxslt.1.dylib
+ 0x7fff94c0a000 - 0x7fff94c14ff7 com.apple.bsd.ServiceManagement (2.0 - 2.0) <3E92DCA9-DA23-34E1-8C38-DA7488621FFB> /System/Library/Frameworks/ServiceManagement.framework/Versions/A/ServiceManagement
+ 0x7fff94c15000 - 0x7fff94c1ffff libcommonCrypto.dylib (60049) <FC0D70F5-E485-32E6-BFC2-1E072047282B> /usr/lib/system/libcommonCrypto.dylib
+ 0x7fff94c94000 - 0x7fff94d82fff libJP2.dylib (1029) <720403F5-7863-30D6-AC09-F5A04F069E1B> /System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/libJP2.dylib
+ 0x7fff94daf000 - 0x7fff94dc8ff3 com.apple.Ubiquity (1.3 - 280) <581DAEFC-B314-3F92-93CF-7B70BF22AEEF> /System/Library/PrivateFrameworks/Ubiquity.framework/Versions/A/Ubiquity
+ 0x7fff95037000 - 0x7fff9513cfff com.apple.ImageIO.framework (3.2.0 - 1029) <FEF93B49-D136-3248-B46B-C026F7E906BD> /System/Library/Frameworks/ImageIO.framework/Versions/A/ImageIO
+ 0x7fff9513d000 - 0x7fff9526aff7 com.apple.desktopservices (1.8 - 1.8) <ACF9A2F5-6285-316E-958A-25C0AFDF3AEA> /System/Library/PrivateFrameworks/DesktopServicesPriv.framework/Versions/A/DesktopServicesPriv
+ 0x7fff9526b000 - 0x7fff95273ffc libGFXShared.dylib (9.0.74) <13A420C1-1B14-36F8-8F08-4698D423E52F> /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGFXShared.dylib
+ 0x7fff95274000 - 0x7fff9528cff7 com.apple.GenerationalStorage (2.0 - 158) <5BCFBEED-09D2-3BD3-8EE0-85E809C47380> /System/Library/PrivateFrameworks/GenerationalStorage.framework/Versions/A/GenerationalStorage
+ 0x7fff952b3000 - 0x7fff9533cff7 com.apple.ColorSync (4.9.0 - 4.9.0) <CBF9EA13-4FC4-34D8-812A-6A37189CD09E> /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ColorSync.framework/Versions/A/ColorSync
+ 0x7fff95361000 - 0x7fff953baff7 libTIFF.dylib (1029) <12303E45-734B-3D6C-A5C8-1495ECBC0344> /System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/libTIFF.dylib
+ 0x7fff9548c000 - 0x7fff954d9ff2 com.apple.print.framework.PrintCore (9.0 - 424) <B09BB55A-67C0-34F9-95DB-6F735842EAE5> /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/PrintCore.framework/Versions/A/PrintCore
+ 0x7fff954e4000 - 0x7fff95547ff3 com.apple.SystemConfiguration (1.13 - 1.13) <73B50935-DFE8-31B8-8583-27A28B5A9D1E> /System/Library/Frameworks/SystemConfiguration.framework/Versions/A/SystemConfiguration
+ 0x7fff955ac000 - 0x7fff955c6fff libdispatch.dylib (339.1.2) <A9C37B4E-B908-3212-BF59-CE336EC30E78> /usr/lib/system/libdispatch.dylib
+ 0x7fff95ca6000 - 0x7fff95ca7ff3 libSystem.B.dylib (1197) <7589D08E-9338-3E28-AA74-9734F0D51CE0> /usr/lib/libSystem.B.dylib
+ 0x7fff95cb3000 - 0x7fff95cfaff3 libFontRegistry.dylib (121.1) <C8BC9042-B3EA-35FB-B4D7-2B1A6E0E6AB5> /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ATS.framework/Versions/A/Resources/libFontRegistry.dylib
+ 0x7fff95cfb000 - 0x7fff95deafff libFontParser.dylib (106) <16B9215D-3244-365F-910F-FA033495E3F5> /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ATS.framework/Versions/A/Resources/libFontParser.dylib
+ 0x7fff95deb000 - 0x7fff95debfff com.apple.Cocoa (6.8 - 20) <B2519A80-93F8-3BEB-A6B2-780B0D291E89> /System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa
+ 0x7fff95e0f000 - 0x7fff95e10fff liblangid.dylib (117) <5146A22B-088F-3D8D-B245-F03DD3CDA2B0> /usr/lib/liblangid.dylib
+ 0x7fff95e11000 - 0x7fff9696ffff com.apple.AppKit (6.9 - 1240) <53CEC6E0-F928-32EC-919D-B34C0818C88C> /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit
+ 0x7fff96970000 - 0x7fff96977fff com.apple.NetFS (6.0 - 4.0) <553EA9F4-7B2C-371A-AF03-4B709A730582> /System/Library/Frameworks/NetFS.framework/Versions/A/NetFS
+ 0x7fff96978000 - 0x7fff969c8ffa com.apple.audio.CoreAudio (4.2.0 - 4.2.0) <548AC059-62DD-3CF6-B083-CABE454AFA38> /System/Library/Frameworks/CoreAudio.framework/Versions/A/CoreAudio
+ 0x7fff96a12000 - 0x7fff96a7cff7 com.apple.framework.IOKit (2.0.1 - 907.1.5) <BC9D0F47-DB6F-3AD0-B38F-267E891099D0> /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit
+ 0x7fff96add000 - 0x7fff96ae0fff com.apple.TCC (1.0 - 1) <1DF1D216-1355-3E4F-B4BE-3E3BA5A696EB> /System/Library/PrivateFrameworks/TCC.framework/Versions/A/TCC
+ 0x7fff96ae1000 - 0x7fff96b06ff7 com.apple.ChunkingLibrary (2.0 - 154) <EBFF01E3-D26B-3031-9E4C-670303B1086A> /System/Library/PrivateFrameworks/ChunkingLibrary.framework/Versions/A/ChunkingLibrary
+ 0x7fff96b07000 - 0x7fff96b0bff7 libGIF.dylib (1029) <000B8500-FC82-3016-8E59-9FA0D6395F04> /System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/libGIF.dylib
+ 0x7fff96b58000 - 0x7fff96b59ff7 libsystem_blocks.dylib (63) <7836104E-39B9-31B6-A0C7-C02ACD401ADE> /usr/lib/system/libsystem_blocks.dylib
+ 0x7fff96db9000 - 0x7fff96db9ffd com.apple.audio.units.AudioUnit (1.9 - 1.9) <BBAD4575-CE0A-34EF-A5AF-36CD66FF260C> /System/Library/Frameworks/AudioUnit.framework/Versions/A/AudioUnit
+ 0x7fff96df6000 - 0x7fff96e07fff libsystem_asl.dylib (217) <F8795719-7E14-3FB2-8F4D-FF814AFFB7F7> /usr/lib/system/libsystem_asl.dylib
+ 0x7fff96e2d000 - 0x7fff96e5cfd2 libsystem_m.dylib (3047.15) <8A6B4EC2-BB25-342B-B3FE-9585175225B8> /usr/lib/system/libsystem_m.dylib
+ 0x7fff96e5d000 - 0x7fff96fb3ff3 com.apple.audio.toolbox.AudioToolbox (1.9 - 1.9) <D3F44C67-987D-3955-B15F-74A27C7E59E3> /System/Library/Frameworks/AudioToolbox.framework/Versions/A/AudioToolbox
+ 0x7fff96fb4000 - 0x7fff9709ffff libsqlite3.dylib (155) <F60CCD67-FA68-379E-9D9C-4085E06F5665> /usr/lib/libsqlite3.dylib
+ 0x7fff970a0000 - 0x7fff97348ff9 com.apple.HIToolbox (2.1 - 681) <F25DDDC9-D3BC-3E80-A57D-EC1FE747B40B> /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/HIToolbox
+ 0x7fff97349000 - 0x7fff97383ffb com.apple.bom (12.0 - 192) <FE625F33-643C-310A-B931-14CEBC007302> /System/Library/PrivateFrameworks/Bom.framework/Versions/A/Bom
+ 0x7fff97758000 - 0x7fff97759ff7 libsystem_sandbox.dylib (278.1) <F723F1D9-5561-344A-A6F0-B1373D355DBA> /usr/lib/system/libsystem_sandbox.dylib
+ 0x7fff977fb000 - 0x7fff977fbfff com.apple.Accelerate.vecLib (3.9 - vecLib 3.9) <349BA8B4-1C72-30BE-B2BB-1898F51B9B5E> /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/vecLib
+ 0x7fff97939000 - 0x7fff97aa2ff3 com.apple.CFNetwork (657 - 657) <59A9476F-19A2-3F8B-A9B0-8531EA36A4AE> /System/Library/Frameworks/CFNetwork.framework/Versions/A/CFNetwork
+ 0x7fff97ac9000 - 0x7fff97b20fff com.apple.Symbolication (1.4 - 125) <C3269812-583B-3349-A675-CCCFDF3140DB> /System/Library/PrivateFrameworks/Symbolication.framework/Versions/A/Symbolication
+ 0x7fff97b24000 - 0x7fff97b93ff1 com.apple.ApplicationServices.ATS (360 - 360) <8A3AD47D-2777-3019-80BB-4B17AA055E13> /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ATS.framework/Versions/A/ATS
+ 0x7fff97c01000 - 0x7fff97c28ff3 libsystem_info.dylib (449) <B5F10962-3DA2-3557-A0B1-369BB80EA6A5> /usr/lib/system/libsystem_info.dylib
+ 0x7fff97d95000 - 0x7fff97e21ff7 com.apple.ink.framework (10.9 - 205) <A3B23363-D876-39CF-9290-F01520C484E3> /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/Ink.framework/Versions/A/Ink
+ 0x7fff97e22000 - 0x7fff97f04fff com.apple.coreui (2.1 - 224) <9F8C1983-1795-34DA-A0C1-7F126ECA0D8E> /System/Library/PrivateFrameworks/CoreUI.framework/Versions/A/CoreUI
+ 0x7fff97f4d000 - 0x7fff97fbafff com.apple.SearchKit (1.4.0 - 1.4.0) <EACE2CF5-06EA-3899-9208-F9914C1922BD> /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/SearchKit.framework/Versions/A/SearchKit
+ 0x7fff98062000 - 0x7fff982b6ff0 com.apple.security (7.0 - 55377) <2F4EFC9E-DD86-32E5-A2CB-E83A5DF34F8F> /System/Library/Frameworks/Security.framework/Versions/A/Security
+ 0x7fff982b7000 - 0x7fff982bbff7 libcache.dylib (61) <E9CD6B70-0553-3808-87DA-D16A1A6AC3FB> /usr/lib/system/libcache.dylib
+ 0x7fff982bc000 - 0x7fff982c1fff com.apple.DiskArbitration (2.6 - 2.6) <4D7487BB-C4A7-32DB-BEE2-CE55EA7F40B2> /System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration
+ 0x7fff9838e000 - 0x7fff9838efff com.apple.CoreServices (59 - 59) <D84FB78F-0F3C-3383-AE76-4BD6E3173F7F> /System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices
+ 0x7fff983e0000 - 0x7fff98418ff7 com.apple.RemoteViewServices (2.0 - 94) <7E7B5F1F-9F0E-3DF7-B6B9-152DFD2DFFC7> /System/Library/PrivateFrameworks/RemoteViewServices.framework/Versions/A/RemoteViewServices
+ 0x7fff987c8000 - 0x7fff987e4fff libresolv.9.dylib (54) <78D891A1-6F8B-34D4-8F0D-59DB6DF53411> /usr/lib/libresolv.9.dylib
+ 0x7fff987e5000 - 0x7fff987eafff libmacho.dylib (845) <0038681B-CEC4-348A-A7B8-4236C701F2F8> /usr/lib/system/libmacho.dylib
+ 0x7fff98802000 - 0x7fff98844ff7 libauto.dylib (185.4) <379FBDA3-DB2A-35A3-A637-3893C0F0E52F> /usr/lib/libauto.dylib
+ 0x7fff9890a000 - 0x7fff98d3dff7 com.apple.vision.FaceCore (3.0.0 - 3.0.0) <14255DCC-80BD-3690-9269-057D175A9FC5> /System/Library/PrivateFrameworks/FaceCore.framework/Versions/A/FaceCore
+ 0x7fff98d66000 - 0x7fff98ed4ff7 libBLAS.dylib (1094.4) <80E99B02-BD2D-3D88-97B6-0BE2D8973633> /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
+ 0x7fff98f6b000 - 0x7fff98f6dfff libRadiance.dylib (1029) <4E13C7E9-9B17-33D3-9142-B645B5BBCCD6> /System/Library/Frameworks/ImageIO.framework/Versions/A/Resources/libRadiance.dylib
+ 0x7fff98f6e000 - 0x7fff98f77ffe com.apple.CommonAuth (4.0 - 2.0) <3918EBA0-A124-37DC-9BA6-4D1370AF03A8> /System/Library/PrivateFrameworks/CommonAuth.framework/Versions/A/CommonAuth
+
+
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_10_141819a6b67de2602673698f6f148106._comment b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_10_141819a6b67de2602673698f6f148106._comment
new file mode 100644
index 000000000..db4d3e269
--- /dev/null
+++ b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_10_141819a6b67de2602673698f6f148106._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="calmyournerves"
+ ip="85.3.250.239"
+ subject="comment 10"
+ date="2013-10-24T20:47:19Z"
+ content="""
+I was able to successfully build git-annex on Mac OS X 10.9.
+
+See https://gist.github.com/calmyournerves/7144127 for instructions.
+I tried to document every step I made, but I'm not sure if I forgot to write down anything.
+
+Let me know if it works for you.
+"""]]
diff --git a/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_11_8be96359fd2bd33ed2961e499dc2685e._comment b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_11_8be96359fd2bd33ed2961e499dc2685e._comment
new file mode 100644
index 000000000..d166e8c67
--- /dev/null
+++ b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_11_8be96359fd2bd33ed2961e499dc2685e._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="warp"
+ ip="2001:4b98:dc0:45:216:3eff:fe83:3d9"
+ subject="comment 11"
+ date="2013-10-25T07:29:04Z"
+ content="""
+I was able to build git-annex on the work laptop with these steps:
+
+1. Make sure xcode is up-to-date.
+2. Download and install \"Command Line Tools (OS X Mavericks) for Xcode - Late October 2013\" from https://developer.apple.com/downloads/ after logging in as a developer.
+3. Follow the \"brew\" instructions at http://git-annex.branchable.com/install/OSX/
+"""]]
diff --git a/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_12_26950a37e86d4dd83dd59fb2564d0a2e._comment b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_12_26950a37e86d4dd83dd59fb2564d0a2e._comment
new file mode 100644
index 000000000..b05d26c0b
--- /dev/null
+++ b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_12_26950a37e86d4dd83dd59fb2564d0a2e._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="imagejan"
+ ip="134.99.222.172"
+ subject="comment 12"
+ date="2013-10-25T13:37:13Z"
+ content="""
+I was able to build the git-annex.app OSX app using @calmyournerves instructions (see comment 10), but only after adding the 'async' dependency to the git-annex.cabal file.
+
+Command line works great now, but I wasn't able to run the git-annex-assistant :(
+
+"""]]
diff --git a/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_13_cbf8150dbe0da64bde7f6af8e041eda8._comment b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_13_cbf8150dbe0da64bde7f6af8e041eda8._comment
new file mode 100644
index 000000000..94d962cd8
--- /dev/null
+++ b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_13_cbf8150dbe0da64bde7f6af8e041eda8._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkQafKy7hNSEolLs6TvbgUnkklTctUY9LI"
+ nickname="Zellyn"
+ subject="Mac hardware"
+ date="2013-10-25T17:30:38Z"
+ content="""
+If someone had time to set up a campaign to buy you a Mac Mini, I'd chip in $20 :-)
+"""]]
diff --git a/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_14_0c203f90d911cf6869894dae89575a49._comment b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_14_0c203f90d911cf6869894dae89575a49._comment
new file mode 100644
index 000000000..591123175
--- /dev/null
+++ b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_14_0c203f90d911cf6869894dae89575a49._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="calmyournerves"
+ ip="85.3.250.239"
+ subject="comment 14"
+ date="2013-10-25T18:43:01Z"
+ content="""
+@imagejan:
+What errors did you get before adding async to the cabal file?
+What's the problem with the assistant? Running git-annex webapp as well as simply opening git-annex.app both worked for me.
+
+@Zellyn:
+That's certainly a good idea and I would support it. But running multiple versions of OS X is tricky, Parallels allows this iirc (VM's).
+"""]]
diff --git a/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_15_68cbb7268bdad73357da2d11e05d73c4._comment b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_15_68cbb7268bdad73357da2d11e05d73c4._comment
new file mode 100644
index 000000000..07e76fcb8
--- /dev/null
+++ b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_15_68cbb7268bdad73357da2d11e05d73c4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="Remy"
+ ip="83.87.21.84"
+ subject="comment 15"
+ date="2013-10-25T18:51:32Z"
+ content="""
+I now got both the CLI and web app working but I had to switch to gcc-4.7 to work around a compiler preprocessing error and back to the default gcc to get fsevents to compile.
+"""]]
diff --git a/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_16_816d552f871a1b06306f04d575adb2e5._comment b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_16_816d552f871a1b06306f04d575adb2e5._comment
new file mode 100644
index 000000000..96f379dcf
--- /dev/null
+++ b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_16_816d552f871a1b06306f04d575adb2e5._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkQafKy7hNSEolLs6TvbgUnkklTctUY9LI"
+ nickname="Zellyn"
+ subject="Earmarked donations?"
+ date="2013-10-25T21:51:19Z"
+ content="""
+Joeyh, is it possible to earmark donations? We could set up a wiki page to track progress, and try to buy you a Mac Mini...
+"""]]
diff --git a/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_17_7905b097a9c582452fb04cdc88ed4285._comment b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_17_7905b097a9c582452fb04cdc88ed4285._comment
new file mode 100644
index 000000000..c67cc7add
--- /dev/null
+++ b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_17_7905b097a9c582452fb04cdc88ed4285._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 17"
+ date="2013-10-26T16:58:27Z"
+ content="""
+I'm glad that it's been gotten to build.
+
+Now all we need is for someone like @calmyournerves or @warp or @remy to put \"git pull; make osxapp\" in a cron job. I can provide a rsync account for publishing the DMG file, and help with setting up [gitbuilder](https://github.com/apenwarr/gitbuilder) which is one good way to automate it.
+
+Or, if someone else with a Mavericks desktop machine wants to install ssh and make me an account, I'm sure I can follow the instructions and set up an autobuilder on it.
+
+To be clear, I don't have time or interest in maintaining hardware to run the builds, even if I had the hardware. It's much better to let people who are passionate about it do it.
+"""]]
diff --git a/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_18_bd5ac9bb2eaab66af6aa13b39172b49d._comment b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_18_bd5ac9bb2eaab66af6aa13b39172b49d._comment
new file mode 100644
index 000000000..903a41364
--- /dev/null
+++ b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_18_bd5ac9bb2eaab66af6aa13b39172b49d._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://jspk.clavid.com/"
+ nickname="flabbergast"
+ subject="comment 18"
+ date="2013-10-27T19:29:01Z"
+ content="""
+I've also just upgraded and had to compile git-annex (following @calmyournerves' instructions). I've made a dmg, so if anyone out there doesn't feel like compiling, you can get 4.20131027-g9230b07 for Mavericks temporarily [here (7z for saving bandwidth)](https://freeshell.de/~teatime/git-annex-4.20131027-g9230b07.dmg.7z).
+(I've used my laptop, and I don't want to set it up for automatic building; I'll see if I can set up my work mac for that.)
+"""]]
diff --git a/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_19_9881db7bb6fef4e47c54cdc23e995f17._comment b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_19_9881db7bb6fef4e47c54cdc23e995f17._comment
new file mode 100644
index 000000000..96356e047
--- /dev/null
+++ b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_19_9881db7bb6fef4e47c54cdc23e995f17._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnt7phVzBQ0xO5rCO6sfmEmxQItmFMyqls"
+ nickname="Kevin"
+ subject="comment 19"
+ date="2013-11-02T00:58:31Z"
+ content="""
+I tried @flabbergast's dmg. It seems to work fine (including the web app) on my Air, but the web app fails on my iMac with
+
+ $ git annex webapp
+ Launching web browser on file:///Users/kw/Desktop/annex/.git/annex/webapp.html
+ error: git-annex died of signal 4
+ $
+"""]]
diff --git a/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_1_4fb9d3de245dddab65fb1a53a67a095c._comment b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_1_4fb9d3de245dddab65fb1a53a67a095c._comment
new file mode 100644
index 000000000..d73e8cb06
--- /dev/null
+++ b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_1_4fb9d3de245dddab65fb1a53a67a095c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://siancu.myopenid.com/"
+ nickname="siancu"
+ subject="I could help with this"
+ date="2013-07-15T19:29:26Z"
+ content="""
+I could help to track down this bug however I would need some assistance on where to start :)
+"""]]
diff --git a/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_20_41e2ea458669f59f96b5860825745910._comment b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_20_41e2ea458669f59f96b5860825745910._comment
new file mode 100644
index 000000000..fca9ba58e
--- /dev/null
+++ b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_20_41e2ea458669f59f96b5860825745910._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnt7phVzBQ0xO5rCO6sfmEmxQItmFMyqls"
+ nickname="Kevin"
+ subject="comment 20"
+ date="2013-11-02T01:02:18Z"
+ content="""
+Also, to avoid hurt feelings etc., it might be best to make it clear on your home page and kickstarter that you do not intend to support OS X yourself.
+"""]]
diff --git a/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_21_515039e321e0595f95430d8082bd54a5._comment b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_21_515039e321e0595f95430d8082bd54a5._comment
new file mode 100644
index 000000000..a0a175d30
--- /dev/null
+++ b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_21_515039e321e0595f95430d8082bd54a5._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="108.236.230.124"
+ subject="comment 21"
+ date="2013-11-08T19:22:17Z"
+ content="""
+Now that I can try running the 10.8 dmg on 10.9 myself, I get this failure:
+
+<pre>
+oberon:~ joeyh$ /Volumes/git-annex/git-annex.app/Contents/MacOS/git-annex
+dyld: Symbol not found: _objc_debug_taggedpointer_mask
+ Referenced from: /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
+ Expected in: /Volumes/git-annex/git-annex.app/Contents/MacOS/bundle/I
+ in /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
+</pre>
+
+This makes me think that that adding back the OSX frameworks might possibly yield a dmg that can work on both versions. Although that's probably more likely to work if it's built on 10.8 and used on 10.9 than the other way around. Might be worth a try to revert commit 900351ab8585c171486cef853eff4a95ec151e6f and commit 9b663c7f8cf82cee523b75be1a8786fa7d34b428 to try that.
+
+Oh well, I should have a native 10.9 dmg autobuild set up before too long. 10.8 autobuilder has built its last image unfortunately, due to being upgraded to 10.9.
+"""]]
diff --git a/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_22_9412236296871c570c66f5b4c7f9681e._comment b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_22_9412236296871c570c66f5b4c7f9681e._comment
new file mode 100644
index 000000000..e5942bfd4
--- /dev/null
+++ b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_22_9412236296871c570c66f5b4c7f9681e._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.246"
+ subject="comment 22"
+ date="2013-11-14T18:55:54Z"
+ content="""
+Native 10.9 autobuilder is now running. <https://downloads.kitenet.net/git-annex/autobuild/x86_64-apple-mavericks/git-annex.dmg.bz2>
+
+Lacks XMPP support until I get libxml2 linked on the autobuilder. Only tested on the build machine so far.
+"""]]
diff --git a/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_23_e4e7d13be6c0bc63f426e535de6172f8._comment b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_23_e4e7d13be6c0bc63f426e535de6172f8._comment
new file mode 100644
index 000000000..db8d835d2
--- /dev/null
+++ b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_23_e4e7d13be6c0bc63f426e535de6172f8._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnmF_9CAtfqdZkC4e-_dCX-rK5bqh4RWkw"
+ nickname="Carl"
+ subject="comment 23"
+ date="2013-11-14T19:22:16Z"
+ content="""
+Seems to work on my Mavericks Macbook Air. Thank you!
+"""]]
diff --git a/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_24_c73e1277c5f284b1019362fb2bef94a8._comment b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_24_c73e1277c5f284b1019362fb2bef94a8._comment
new file mode 100644
index 000000000..c3a0d3bec
--- /dev/null
+++ b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_24_c73e1277c5f284b1019362fb2bef94a8._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmL8pteP2jbYJUn1M3CbeLDvz2SWAA1wtg"
+ nickname="Kristian"
+ subject="comment 24"
+ date="2013-11-17T17:01:14Z"
+ content="""
+Thanks Joey! It works great
+"""]]
diff --git a/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_2_f513259a2641e00b049203014ab940c8._comment b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_2_f513259a2641e00b049203014ab940c8._comment
new file mode 100644
index 000000000..6bf0a17f4
--- /dev/null
+++ b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_2_f513259a2641e00b049203014ab940c8._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.90"
+ subject="comment 2"
+ date="2013-07-15T20:12:04Z"
+ content="""
+AIUI, the git-annex dmg bundles several libraries and things that are not portable between OSX versions. So, the fix is probably to build git-annex from source on OS X 10.9.
+
+Following the [[install/cabal]] instructions would be a good first step to see if that gets a working git-annex.
+
+It seems likely that an autobuilder machine will need to be added for OS X 10.9 eventually. Maybe the guy who's providing the Mtn Lion build machine plans to upgrade it, and I can use that. Otherwise, it'll probably depend on someone with a 10.9 machine either setting up an autobuilder, or giving me a ssh account so I can run one.
+"""]]
diff --git a/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_3_54ee7b90467fee8b0457e9c447747500._comment b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_3_54ee7b90467fee8b0457e9c447747500._comment
new file mode 100644
index 000000000..cdff138ad
--- /dev/null
+++ b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_3_54ee7b90467fee8b0457e9c447747500._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://siancu.myopenid.com/"
+ nickname="siancu"
+ subject="comment 3"
+ date="2013-07-16T07:18:35Z"
+ content="""
+I got some problems building gpm on 10.9, will have to dig a bit more and see what's going on. It might be my environment. But for now I can't build gpm, thus no gnutls. I could try to build and install git-annex only without the assistant and webapp.
+
+BTW, how is the .app file generated? Is there an Xcode project or something like that?
+"""]]
diff --git a/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_4_7e6223c2dae3346e17276c7bbb01d53e._comment b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_4_7e6223c2dae3346e17276c7bbb01d53e._comment
new file mode 100644
index 000000000..f613f296e
--- /dev/null
+++ b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_4_7e6223c2dae3346e17276c7bbb01d53e._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.90"
+ subject="comment 4"
+ date="2013-07-16T17:48:54Z"
+ content="""
+The dmg is built by running \"make osxapp\", once you've gotten git-annex to build.
+
+gnutls is only needed by the XMPP code. You can build without that, using `cabal configure -f-XMPP; cabal build`
+
+(If you're building from a git checkout, building w/o XMPP was broken the past couple days; make sure you update to current head.)
+"""]]
diff --git a/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_5_13b6e595d595da7f036e81258a65541e._comment b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_5_13b6e595d595da7f036e81258a65541e._comment
new file mode 100644
index 000000000..33c1319b3
--- /dev/null
+++ b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_5_13b6e595d595da7f036e81258a65541e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://siancu.myopenid.com/"
+ nickname="siancu"
+ subject="comment 5"
+ date="2013-07-16T19:52:28Z"
+ content="""
+Ok, I will try without XMPP. However I'm going to need it, because, if I understood correctly, it is needed to do remote pairings. But for now I can manage without as I can take the laptop with me to work and to syncing locally.
+"""]]
diff --git a/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_6_94144c0cbdbccc72c13e12daf7657a29._comment b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_6_94144c0cbdbccc72c13e12daf7657a29._comment
new file mode 100644
index 000000000..fbb519bdd
--- /dev/null
+++ b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_6_94144c0cbdbccc72c13e12daf7657a29._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlYsjf5dcZnzs0b9EPxnjVddx1rnrpZASs"
+ nickname="Duarte"
+ subject="Any news?"
+ date="2013-08-31T15:48:39Z"
+ content="""
+Has anyone made any progress on this? Just wondering...
+"""]]
diff --git a/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_7_9eb064ffdc3fdb70e85572185e151a3f._comment b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_7_9eb064ffdc3fdb70e85572185e151a3f._comment
new file mode 100644
index 000000000..db8e707cd
--- /dev/null
+++ b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_7_9eb064ffdc3fdb70e85572185e151a3f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBcKrChzs1mdF5pxnenPuMOaJBKfbeRVY"
+ nickname="Raffael"
+ subject="bump"
+ date="2013-10-24T07:03:56Z"
+ content="""
+As Mavericks is now the current version of Mac OS X, it would be cool to have a working DMG for it. Any news here?
+"""]]
diff --git a/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_8_cde756e8a9b18fe2ca9cda25967bc7fb._comment b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_8_cde756e8a9b18fe2ca9cda25967bc7fb._comment
new file mode 100644
index 000000000..708f21a79
--- /dev/null
+++ b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_8_cde756e8a9b18fe2ca9cda25967bc7fb._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="67.223.1.203"
+ subject="comment 8"
+ date="2013-10-24T17:14:06Z"
+ content="""
+As I don't own any mac hardware, and don't plan to buy any, and I don't know of a way to just spin up a OSX VM in the cloud, I'm reliant on git-annex users for running builds for the various versions of OS X.
+
+I think there's a chance that one of the two people currently doing builds for older versions will upgrade their system. Although of course then we lose builds for that older version. Alternatively, I'm waiting for someone to either volenteer to set up a builder for 10.9, or give me ssh access to a machine were I can do it.
+"""]]
diff --git a/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_9_1fd6a4374a334bc03914c3e0df95ef95._comment b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_9_1fd6a4374a334bc03914c3e0df95ef95._comment
new file mode 100644
index 000000000..d70d0a872
--- /dev/null
+++ b/doc/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/comment_9_1fd6a4374a334bc03914c3e0df95ef95._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="67.223.1.203"
+ subject="comment 9"
+ date="2013-10-24T17:27:04Z"
+ content="""
+Anyone trying to compile git-annex on OSX 10.9 will need to be aware of and work around this problem:
+<http://justtesting.org/post/64947952690/the-glasgow-haskell-compiler-ghc-on-os-x-10-9>
+<http://www.haskell.org/pipermail/haskell-cafe/2013-September/110320.html>
+"""]]
diff --git a/doc/bugs/git_annex_fork_bombs_on_gpg_file.mdwn b/doc/bugs/git_annex_fork_bombs_on_gpg_file.mdwn
new file mode 100644
index 000000000..9bfe3ee3b
--- /dev/null
+++ b/doc/bugs/git_annex_fork_bombs_on_gpg_file.mdwn
@@ -0,0 +1,25 @@
+### Please describe the problem.
+git-annex goes into a loop of I think Haskell's createProcess function and causes the entire operating system to starve of process creation.
+
+### What steps will reproduce the problem?
+The last file git-annex was processing was tinco.gpg, my gpg key exported with
+
+ gpg --export mail@tinco.nl --output tinco.gpg
+
+### What version of git-annex are you using? On what operating system?
+4.20130516-g8a26544 on OSX
+
+I had a remote setup using bup.
+
+### Please provide any additional information below.
+Unfortunately to fix the problem I have deleted the entire git repository and made a new init in the same directory, this time without the gpg file. Everything seems to be working now.
+
+What I remember about the log file is that the last thing it said was something along the lines of
+
+add tinco.gpg
+
+.. (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) ..etc
+
+recv (resource unavailable or something) ..
+
+> [[done]]; fixed 3 bugs! --[[Joey]]
diff --git a/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_10_6e29b60cd77f3288e33ad270f95f410e._comment b/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_10_6e29b60cd77f3288e33ad270f95f410e._comment
new file mode 100644
index 000000000..0338219ac
--- /dev/null
+++ b/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_10_6e29b60cd77f3288e33ad270f95f410e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://me.tinco.nl/"
+ nickname="Tinco"
+ subject="comment 10"
+ date="2013-05-19T20:45:53Z"
+ content="""
+Alright! So first the issue was that gpg was asking for a passphrase. I fixed that by installing gpgtools for mac, but that one doesn't have a gpg executable, instead it has gpg2. I hadn't noticed that, so that's why it was saying 'resource vanished' without a proper error message, it simply couldn't find the gpg executable. I did ln -s /usr/local/bin/gpg2 /usr/local/bin/gpg, and now it's happily copying files. Thanks for helping me find out what was wrong!
+"""]]
diff --git a/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_11_ad13e3221ae06086e86800316912d951._comment b/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_11_ad13e3221ae06086e86800316912d951._comment
new file mode 100644
index 000000000..301b0f973
--- /dev/null
+++ b/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_11_ad13e3221ae06086e86800316912d951._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 11"
+ date="2013-05-19T21:13:41Z"
+ content="""
+You're certainly welcome.
+
+So, you did not install git-annex from the dmg? That bundles its own gpg.
+
+I'm curious about this passphrase thing.. Does gpgtools + gpg2 on the Mac cause it to ask for a passphrase better, like in a dialog window? Perhaps I can improve the gpg stuff bundled in the dmg..
+"""]]
diff --git a/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_12_41746b731eae7f280bb668c776022bcb._comment b/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_12_41746b731eae7f280bb668c776022bcb._comment
new file mode 100644
index 000000000..ee27c5491
--- /dev/null
+++ b/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_12_41746b731eae7f280bb668c776022bcb._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://me.tinco.nl/"
+ nickname="Tinco"
+ subject="comment 12"
+ date="2013-05-19T21:24:48Z"
+ content="""
+Yes exactly, it spawns a dialog window and overall has a very nice interface for managing gpg keys. I switched from the DMG to cabal because I couldn't get the bundled gpg to ask for my password, setting up a gpg-agent seemed pretty complicated, so I just went for the packaged approach from https://gpgtools.org/.
+"""]]
diff --git a/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_13_56ca8590110abffeed6d826c54ca1136._comment b/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_13_56ca8590110abffeed6d826c54ca1136._comment
new file mode 100644
index 000000000..64ee5e876
--- /dev/null
+++ b/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_13_56ca8590110abffeed6d826c54ca1136._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 13"
+ date="2013-05-19T22:03:57Z"
+ content="""
+Ok, I've made a note that I should look into pulling in gpgtools rather than gpg into the DMG. At least if the webapp every gets a UI that allows setting up remotes that are encrypted to a gpg key. Currently the webapp avoids that because I know gpg password prompting is not sorted out everywhere.
+
+And also, I've made the configure script check for gpg2 if it can't find a gpg.
+"""]]
diff --git a/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_1_73ae438a37e4c5f56fe291448e1c64dd._comment b/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_1_73ae438a37e4c5f56fe291448e1c64dd._comment
new file mode 100644
index 000000000..e1c3ed279
--- /dev/null
+++ b/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_1_73ae438a37e4c5f56fe291448e1c64dd._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://me.tinco.nl/"
+ nickname="Tinco"
+ subject="comment 1"
+ date="2013-05-18T23:32:32Z"
+ content="""
+Nevermind the gpg file suspicion, it now crashes without that file too:
+
+[2013-05-19 01:30:36 CEST] main: starting assistant version 4.20130516-g8a26544
+
+(scanning...) [2013-05-19 01:30:36 CEST] Watcher: Performing startup scan
+(started...) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg) (gpg)
+"""]]
diff --git a/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_2_aa237adebe7674b8cdb9a967bb5f96a8._comment b/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_2_aa237adebe7674b8cdb9a967bb5f96a8._comment
new file mode 100644
index 000000000..f5358da98
--- /dev/null
+++ b/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_2_aa237adebe7674b8cdb9a967bb5f96a8._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://me.tinco.nl/"
+ nickname="Tinco"
+ subject="comment 2"
+ date="2013-05-18T23:36:22Z"
+ content="""
+So that probably means I have some problem with the gpg encryption, that is used by bup. Maybe it doesn't even have to do with git annex, I'll see if I can make it say more in the log.
+"""]]
diff --git a/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_3_ab403d7abbbbabd498b954b0b9742755._comment b/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_3_ab403d7abbbbabd498b954b0b9742755._comment
new file mode 100644
index 000000000..0ffbcccae
--- /dev/null
+++ b/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_3_ab403d7abbbbabd498b954b0b9742755._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-05-18T23:59:59Z"
+ content="""
+run it with `--debug`
+
+paste the whole log, not an except
+
+get a `ps lax` so we can see which programs are running which other programs and how many programs are running at the same time
+"""]]
diff --git a/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_4_a35d04440b1220faf9088107c3f17762._comment b/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_4_a35d04440b1220faf9088107c3f17762._comment
new file mode 100644
index 000000000..bd1fef019
--- /dev/null
+++ b/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_4_a35d04440b1220faf9088107c3f17762._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://me.tinco.nl/"
+ nickname="Tinco"
+ subject="comment 4"
+ date="2013-05-19T03:15:10Z"
+ content="""
+Ok I got some interesting data from the debug switch, posted it here: https://pastee.org/ kn2hv (remove space, TTL 1 month)
+
+And managed to get a ps lax in after launch but before I'm starved of processes: http://pastie.org/pastes/7928091/text?key=gdywhjzo8xm5etcgv8e8jw
+"""]]
diff --git a/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_5_8345331b9b313769ba401da2ffd89332._comment b/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_5_8345331b9b313769ba401da2ffd89332._comment
new file mode 100644
index 000000000..d0ff6f008
--- /dev/null
+++ b/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_5_8345331b9b313769ba401da2ffd89332._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://me.tinco.nl/"
+ nickname="Tinco"
+ subject="comment 5"
+ date="2013-05-19T12:37:22Z"
+ content="""
+Sorry, I just noticed that after I killed the process it created some more logs. The log I previously pasted is moved to log.3, here are the additional ones (all created in around the same minute:)
+
+http://pastie.org/7929225
+"""]]
diff --git a/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_6_7eb535ca38b3e84d44d0f8cbf5e61b8b._comment b/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_6_7eb535ca38b3e84d44d0f8cbf5e61b8b._comment
new file mode 100644
index 000000000..03f213c43
--- /dev/null
+++ b/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_6_7eb535ca38b3e84d44d0f8cbf5e61b8b._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 6"
+ date="2013-05-19T16:39:44Z"
+ content="""
+So there are a lot of uploads attempts being made (and apparently failing), and a lot of zombie git-annex processes are building up as children of the git-annex transferkeys process. That isolates the problem some.
+
+The repeated \"(gpg)\" is an interesting clue, since normally git-annex only runs gpg once, to unlock an encrypted special remote's encryption key, and then should retain the key, cached in memory. I was able to reproduce this part of the bug (but not the zombie processes) when I purposfully broke the bup special remote by making it throw an error when it was supposed to run bup to send a file. That defeats the caching, since the state, including the cache, is thrown away when there's an exception. Working on a fix for that..
+
+That doesn't explain what's actually causing the problem for you, but it does certainly suggest the bup special remote code is failing in some unusual way. What happens if rather than starting the assistant, you use git-annex manually to send files to the remote? Run:
+
+<pre>
+git annex copy --to ffe41272-608e-43c4-8f35-e9cd63087892 --debug
+</pre>
+
+(You may want to give it the name of just 1 file to send.)
+"""]]
diff --git a/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_7_a3aa4231a82917c56cbdf52b65db7133._comment b/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_7_a3aa4231a82917c56cbdf52b65db7133._comment
new file mode 100644
index 000000000..16961afd3
--- /dev/null
+++ b/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_7_a3aa4231a82917c56cbdf52b65db7133._comment
@@ -0,0 +1,21 @@
+[[!comment format=mdwn
+ username="http://me.tinco.nl/"
+ nickname="Tinco"
+ subject="comment 7"
+ date="2013-05-19T19:27:03Z"
+ content="""
+Hi Joey thanks for working with me on this. The result from copying one file over is 'resource vanished':
+
+ [2013-05-19 21:24:53 CEST] read: git [\"--git-dir=/Users/tinco/Documents/.git\",\"--work-tree=/Users/tinco/Documents\",\"show-ref\",\"git-annex\"]
+ [2013-05-19 21:24:53 CEST] read: git [\"--git-dir=/Users/tinco/Documents/.git\",\"--work-tree=/Users/tinco/Documents\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+ [2013-05-19 21:24:53 CEST] read: git [\"--git-dir=/Users/tinco/Documents/.git\",\"--work-tree=/Users/tinco/Documents\",\"log\",\"refs/heads/git-annex..f0523a06e2eb7217d98fe2b9f6ec5afa724ccd92\",\"--oneline\",\"-n1\"]
+ [2013-05-19 21:24:53 CEST] chat: git [\"--git-dir=/Users/tinco/Documents/.git\",\"--work-tree=/Users/tinco/Documents\",\"cat-file\",\"--batch\"]
+ [2013-05-19 21:24:53 CEST] read: git [\"--git-dir=/Users/tinco/Documents/.git\",\"--work-tree=/Users/tinco/Documents\",\"ls-files\",\"--cached\",\"-z\",\"--\",\"About Stacks.pdf\"]
+ copy About Stacks.pdf (gpg) [2013-05-19 21:24:53 CEST] chat: gpg [\"--quiet\",\"--trust-model\",\"always\",\"--decrypt\"]
+
+ git-annex: fd:12: hClose: resource vanished (Broken pipe)
+ failed
+ git-annex: copy: 1 failed
+
+
+"""]]
diff --git a/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_8_178fd4e4d6abbca192fcd6d592615fca._comment b/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_8_178fd4e4d6abbca192fcd6d592615fca._comment
new file mode 100644
index 000000000..38b136b37
--- /dev/null
+++ b/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_8_178fd4e4d6abbca192fcd6d592615fca._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 8"
+ date="2013-05-19T19:35:51Z"
+ content="""
+I've fixed the repeated \"(gpg)\" problem. But that is not the real problem...
+
+Looks to me like there is a problem with running gpg to extract the encryption key of the repository. I can cause the same \"resource vanished\" message if I make gpg exit 1 immediately when it starts. I also managed to get 3 zombies when failing to send 100 files. Although in my case they were gpg zombies, not git-annex zombies.
+
+Can you run `gpg` manually at the command line? If you installed git-annex from the OSX dmg file, you need to have used \"runshell\" to get the gpg that's included in it onto the PATH before you do this.
+"""]]
diff --git a/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_9_7d80f131f43312bb061df2be7fa956ef._comment b/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_9_7d80f131f43312bb061df2be7fa956ef._comment
new file mode 100644
index 000000000..ff81f53a4
--- /dev/null
+++ b/doc/bugs/git_annex_fork_bombs_on_gpg_file/comment_9_7d80f131f43312bb061df2be7fa956ef._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 9"
+ date="2013-05-19T19:53:04Z"
+ content="""
+I've fixed things so it will not pile up zombie processes. It'll still fail to send stuff if gpg is broken, but it'll fail more nicely now.
+
+We still need to find out why gpg is failing to run on your system..
+"""]]
diff --git a/doc/bugs/git_annex_fsck_in_direct_mode_does_not_checksum_files.mdwn b/doc/bugs/git_annex_fsck_in_direct_mode_does_not_checksum_files.mdwn
new file mode 100644
index 000000000..9563f0683
--- /dev/null
+++ b/doc/bugs/git_annex_fsck_in_direct_mode_does_not_checksum_files.mdwn
@@ -0,0 +1,18 @@
+What steps will reproduce the problem?
+
+Put some large files into a direct mode repository (so fsck time is noticeable). git annex add them, commit, run git annex fsck.
+
+What is the expected output? What do you see instead?
+
+Expected: files are checksummed, which should take considerable amount of time for each file. For reference, in indirect mode, fsck takes a while for files of ~1GB size.
+Actually: in direct mode, git annex fsck goes through all of the files in an instant and prints OK for each. I believe the file content is not verified.
+Multiple runs of git annex fsck do the same thing.
+
+What version of git-annex are you using? On what operating system?
+
+git-annex version: 4.20130405, Linux
+
+Please provide any additional information below.
+
+> I've fixed it, fsck is indeed checksumming direct mode files now, as long
+> as they're not known to be modified. [[done]] --[[Joey]]
diff --git a/doc/bugs/git_annex_fsck_in_direct_mode_does_not_checksum_files/comment_1_a6cde4aa495512344fa7f50e10749c68._comment b/doc/bugs/git_annex_fsck_in_direct_mode_does_not_checksum_files/comment_1_a6cde4aa495512344fa7f50e10749c68._comment
new file mode 100644
index 000000000..5aaebc342
--- /dev/null
+++ b/doc/bugs/git_annex_fsck_in_direct_mode_does_not_checksum_files/comment_1_a6cde4aa495512344fa7f50e10749c68._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-04-14T17:50:53Z"
+ content="""
+This is expected. The content of direct mode files can change at any time, so fsck does not have a locked down object with a known checksum that it can verify. Similarly, fsck skips unlocked files in indirect mode.
+"""]]
diff --git a/doc/bugs/git_annex_fsck_in_direct_mode_does_not_checksum_files/comment_2_4ac3b87ec0bc0514c4eff9f5a75b9f5d._comment b/doc/bugs/git_annex_fsck_in_direct_mode_does_not_checksum_files/comment_2_4ac3b87ec0bc0514c4eff9f5a75b9f5d._comment
new file mode 100644
index 000000000..1eb8b18e7
--- /dev/null
+++ b/doc/bugs/git_annex_fsck_in_direct_mode_does_not_checksum_files/comment_2_4ac3b87ec0bc0514c4eff9f5a75b9f5d._comment
@@ -0,0 +1,26 @@
+[[!comment format=txt
+ username="https://www.google.com/accounts/o8/id?id=AItOawln3ckqKx0x_xDZMYwa9Q1bn4I06oWjkog"
+ nickname="Michael"
+ subject="comment 2"
+ date="2013-04-15T01:32:52Z"
+ content="""
+I'm still somewhat confused about the following commit (which seems to suggest fsck in direct mode could actually checksum files):
+
+commit 0da2507fd622120217cf03038b851b47c47ace53
+Author: Joey Hess <joey@kitenet.net>
+Date: Tue Jan 8 15:07:00 2013 -0400
+
+ improve direct mode fsck
+
+ An earlier commit (mislabeled) made direct mode fsck check file checksums.
+ While it's expected for files to change at any time in direct mode, and so
+ fsck cannot complain every time there's a checksum mismatch, it is possible
+ for it to detect when a file does not *seem* to have changed, then check
+ its checksum, and so detect disk corruption or other problems.
+
+ This commit improves that, by checking a second time, if the checksum
+ fails, that the file is still not modified, before taking action. This way,
+ a direct mode file can be modified while being fscked.
+
+
+"""]]
diff --git a/doc/bugs/git_annex_fsck_in_direct_mode_does_not_checksum_files/comment_3_d18b1fdc866edf2786d2c6b7ec55119f._comment b/doc/bugs/git_annex_fsck_in_direct_mode_does_not_checksum_files/comment_3_d18b1fdc866edf2786d2c6b7ec55119f._comment
new file mode 100644
index 000000000..a7b2b38da
--- /dev/null
+++ b/doc/bugs/git_annex_fsck_in_direct_mode_does_not_checksum_files/comment_3_d18b1fdc866edf2786d2c6b7ec55119f._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-04-16T20:16:51Z"
+ content="""
+Thanks for digging that up!
+
+I'd forgotten I finessed the problem that way.. And it looks like that patch was broken and never checked the right file.
+
+"""]]
diff --git a/doc/bugs/git_annex_fsck_in_direct_mode_does_not_checksum_files/comment_4_31e4fcbf63c11cc374a849daf3ce1dbc._comment b/doc/bugs/git_annex_fsck_in_direct_mode_does_not_checksum_files/comment_4_31e4fcbf63c11cc374a849daf3ce1dbc._comment
new file mode 100644
index 000000000..57af75673
--- /dev/null
+++ b/doc/bugs/git_annex_fsck_in_direct_mode_does_not_checksum_files/comment_4_31e4fcbf63c11cc374a849daf3ce1dbc._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawln3ckqKx0x_xDZMYwa9Q1bn4I06oWjkog"
+ nickname="Michael"
+ subject="Thanks!"
+ date="2013-04-17T18:33:41Z"
+ content="""
+It does fsck for real now.
+"""]]
diff --git a/doc/bugs/git_annex_fsck_is_a_no-op_in_bare_repos.mdwn b/doc/bugs/git_annex_fsck_is_a_no-op_in_bare_repos.mdwn
new file mode 100644
index 000000000..9a044860a
--- /dev/null
+++ b/doc/bugs/git_annex_fsck_is_a_no-op_in_bare_repos.mdwn
@@ -0,0 +1,21 @@
+What is says on the tin:
+
+git annex fsck is a no-op in bare repos
+
+See http://lists.madduck.net/pipermail/vcs-home/2011-June/000433.html
+
+> Thinking about this some more, it would be difficult to do anything
+> when bad content is found, since it also cannot update the location log.
+>
+> So this may be another thing blocked by [[todo/branching]], assuming
+> that is fixed in a way that makes `.git-annex` available to bare repos.
+> --[[Joey]]
+
+>> Even if there is nothing it can _do_, knowing that the data is intact,
+>> or not, is valuable in and as of itself. -- RichiH
+
+>>> While storing the data is no longer an issue in bare repos, fsck would
+>>> need a special mode that examines all the location logs, since it
+>>> cannot run thru the checked out files. --[[Joey]]
+
+>>>> [[done]]! --[[Joey]]
diff --git a/doc/bugs/git_annex_fsck_is_a_no-op_in_bare_repos/comment_1_fc59fbd1cdf8ca97b0a4471d9914aaa1._comment b/doc/bugs/git_annex_fsck_is_a_no-op_in_bare_repos/comment_1_fc59fbd1cdf8ca97b0a4471d9914aaa1._comment
new file mode 100644
index 000000000..d50938a78
--- /dev/null
+++ b/doc/bugs/git_annex_fsck_is_a_no-op_in_bare_repos/comment_1_fc59fbd1cdf8ca97b0a4471d9914aaa1._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 1"
+ date="2011-06-13T16:58:52Z"
+ content="""
+And, maybe, a way to start a fsck from remote? At least when the other side is a ssh or git annex shell, this would work.
+"""]]
diff --git a/doc/bugs/git_annex_fsck_is_a_no-op_in_bare_repos/comment_2_273a45e6977d40d39e0d9ab924a83240._comment b/doc/bugs/git_annex_fsck_is_a_no-op_in_bare_repos/comment_2_273a45e6977d40d39e0d9ab924a83240._comment
new file mode 100644
index 000000000..b01590a7a
--- /dev/null
+++ b/doc/bugs/git_annex_fsck_is_a_no-op_in_bare_repos/comment_2_273a45e6977d40d39e0d9ab924a83240._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://ertai.myopenid.com/"
+ nickname="npouillard"
+ subject="git annex fsck --from remote"
+ date="2011-06-25T16:20:44Z"
+ content="""
+Currently fsck silently ignores --to/--from.
+It should at least complain if it is not supported.
+"""]]
diff --git a/doc/bugs/git_annex_get_choke_when_remote_is_an_ssh_url_with_a_port.mdwn b/doc/bugs/git_annex_get_choke_when_remote_is_an_ssh_url_with_a_port.mdwn
new file mode 100644
index 000000000..92cc9170f
--- /dev/null
+++ b/doc/bugs/git_annex_get_choke_when_remote_is_an_ssh_url_with_a_port.mdwn
@@ -0,0 +1,13 @@
+when i want to
+
+ git annex get file
+
+on repo ssh://host-without-port/annex, it works, but if i want to get a file from ssh://host:5122/annex, it tries to run command
+ssh ["host:5122", "git-annex-shell 'configlist' '/annex/file'"] and fails. ssh needs the -p option to set the default port, it doesn't support host:port notation.
+this is confusing because git can handle this url correctly, and will happily clone/push/pull to/from these url.
+
+temporary workaround is to use ssh://host/annex as url and define remote.name.annex-ssh-options to "-p 5122", but we need to use this workaround when doing annex get and undo the workaround when pushing/cloning.
+
+if i had more time, i would have learned haskell and provided a patch ;)
+
+> Fixed in git! --[[Joey]] [[done]]
diff --git a/doc/bugs/git_annex_gets_confused_about_remotes_with_dots_in_their_names.mdwn b/doc/bugs/git_annex_gets_confused_about_remotes_with_dots_in_their_names.mdwn
new file mode 100644
index 000000000..d35282e75
--- /dev/null
+++ b/doc/bugs/git_annex_gets_confused_about_remotes_with_dots_in_their_names.mdwn
@@ -0,0 +1,34 @@
+For test.com//test, I get this:
+
+ % git annex copy . --to test.com//test
+ (getting UUID for test...) git-annex: there is no git remote named "test.com//test"
+
+And my .git/config changes from
+
+ [remote "test.com//test"]
+ url = richih@test.com:/test
+ fetch = +refs/heads/*:refs/remotes/test.com//test/*
+
+to
+
+ [remote "test.com//test"]
+ url = richih@test.com:/test
+ fetch = +refs/heads/*:refs/remotes/test.com//test/*
+ annex-uuid = xyz
+ [remote "test"]
+ annex-uuid = xyz
+
+
+Unless I am misunderstanding something, git annex gets confused about what the name of the remote it supposed to be, truncates at the dot for some operations and uses the full name for others.
+
+> I've fixed this bug. [[done]]
+>
+> However, using "/" in a remote name seems likely to me to confuse
+> git's own remote branch handling. Although I've never tried it.
+> --[[Joey]]
+
+>> From what I can see, git handles / just fine, but would get upset about : which is why it's not allowed in a remote's name.
+>> My naming scheme is host//path/to/annex. It sorts nicely and gives all important information left to right with the most specific parts at the beginning and end.
+>> If you have any other ideas or scheme, I am all ears :)
+>> Either way, thanks for fixing this so quickly.
+>> -- RichiH
diff --git a/doc/bugs/git_annex_import_destroys_a_fellow_git_annex_repository.mdwn b/doc/bugs/git_annex_import_destroys_a_fellow_git_annex_repository.mdwn
new file mode 100644
index 000000000..c8307ca6b
--- /dev/null
+++ b/doc/bugs/git_annex_import_destroys_a_fellow_git_annex_repository.mdwn
@@ -0,0 +1,130 @@
+### Please describe the problem.
+
+`git annex import` not only [[does not work with git annex repositories|bugs/`git annex import` does not work on other git annex repositories]], it even destroys the meta-data in that repository, because it moves the `.git/*` metadata out of the remote repository.
+
+### What steps will reproduce the problem?
+
+[[!format txt """
+git init foo
+cd foo
+git annex init
+dd if=/dev/urandom of=foo bs=1M count=1
+git annex add foo
+git commit -m'files'
+cd ../
+git init bar
+cd bar
+git annex init
+mkdir foo
+cd foo
+git annex import ../../foo
+cd ../../foo
+git status
+"""]]
+
+
+### What version of git-annex are you using? On what operating system?
+
+[[!format txt """
+anarcat@angela:foo$ git annex version
+git-annex version: 4.20130921-g434dc22
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP DNS Feeds Quvi
+"""]]
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+anarcat@angela:~$ cd /tmp
+anarcat@angela:/tmp$ mkdir test
+anarcat@angela:/tmp$ cd test
+anarcat@angela:test$ ls
+anarcat@angela:test$ git init foo
+Initialized empty Git repository in /tmp/test/foo/.git/
+anarcat@angela:test$ cd foo
+anarcat@angela:foo$ git annex init
+init ok
+(Recording state in git...)
+anarcat@angela:foo$ dd if=/dev/urandom of=foo bs=1M count=1
+1+0 enregistrements lus
+1+0 enregistrements écrits
+1048576 octets (1,0 MB) copiés, 0,410384 s, 2,6 MB/s
+anarcat@angela:foo$ git annex add foo
+add foo (checksum...) ok
+(Recording state in git...)
+anarcat@angela:foo$ git commit -m'files'
+[master (root-commit) 83daa0b] files
+ 1 file changed, 1 insertion(+)
+ create mode 120000 foo
+anarcat@angela:foo$ cd ../
+anarcat@angela:test$ git init bar
+Initialized empty Git repository in /tmp/test/bar/.git/
+anarcat@angela:test$ cd bar
+anarcat@angela:bar$ git annex init
+init ok
+(Recording state in git...)
+anarcat@angela:bar$ mkdir foo
+anarcat@angela:bar$ cd foo
+anarcat@angela:foo$ git annex import ../../foo
+import .git/COMMIT_EDITMSG (checksum...) ok
+import .git/description (checksum...) ok
+import .git/config (checksum...) ok
+import .git/index (checksum...) ok
+import .git/HEAD (checksum...) ok
+import .git/annex/journal.lck (checksum...) ok
+import .git/annex/index.lck (checksum...) ok
+import .git/annex/sentinal (checksum...) ok
+import .git/annex/sentinal.cache (checksum...) ok
+import .git/annex/index (checksum...) ok
+import .git/annex/objects/w2/Kz/SHA256E-s1048576--f957108785c8dc30cf792948b89d61af257c40e5ef0e1d20ff6cf6aadaf6f66b/SHA256E-s1048576--f957108785c8dc30cf792948b89d61af257c40e5ef0e1d20ff6cf6aadaf6f66b
+git-annex: ../../foo/.git/annex/objects/w2/Kz/SHA256E-s1048576--f957108785c8dc30cf792948b89d61af257c40e5ef0e1d20ff6cf6aadaf6f66b/SHA256E-s1048576--f957108785c8dc30cf792948b89d61af257c40e5ef0e1d20ff6cf6aadaf6f66b: rename: permission denied (Permission denied)
+failed
+import .git/objects/0e/6881452189b7fc34809f101f075da7cca9d9d8 (checksum...) ok
+import .git/objects/03/c0163611cd061af17b2dd58a93c95ffbb05040 (checksum...) ok
+import .git/objects/39/10912eab082d015bface04ed3a8ed658b94893 (checksum...) ok
+import .git/objects/21/05f6aaf523510f25516b04a0c07d5900df2b0b (checksum...) ok
+import .git/objects/83/daa0b1d8290191f53d1d3b5e39e03653a89ce2 (checksum...) ok
+import .git/objects/83/8fa78626a6cdc4399186172df9109d321ca0bf (checksum...) ok
+import .git/objects/dc/1e1b7b811079e1c5826d44958b736fc3a3a458 (checksum...) ok
+import .git/objects/7b/4d3d6a3ee2286b2da15c1aca39353d63c16fa2 (checksum...) ok
+import .git/objects/86/2b2a09ebc7a1eb298dccc57be75bad897a7c10 (checksum...) ok
+import .git/objects/e1/61ad2ad1843e39937caaf6add6f690fd361126 (checksum...) ok
+import .git/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 (checksum...) ok
+import .git/objects/9b/47feee99b5f24e0dc96cf4a20fcb88c0ec007d (checksum...) ok
+import .git/objects/b0/8c838cfb09bafae40a05312092c37360c880b0 (checksum...) ok
+import .git/refs/heads/master (checksum...) ok
+import .git/refs/heads/git-annex (checksum...) ok
+import .git/logs/HEAD (checksum...) ok
+import .git/logs/refs/heads/master (checksum...) ok
+import .git/logs/refs/heads/git-annex (checksum...) ok
+import .git/info/exclude (checksum...) ok
+import .git/hooks/pre-applypatch.sample (checksum...) ok
+import .git/hooks/applypatch-msg.sample (checksum...) ok
+import .git/hooks/pre-rebase.sample (checksum...) ok
+import .git/hooks/update.sample (checksum...) ok
+import .git/hooks/commit-msg.sample (checksum...) ok
+import .git/hooks/pre-commit (checksum...) ok
+import .git/hooks/prepare-commit-msg.sample (checksum...) ok
+import .git/hooks/post-update.sample (checksum...) ok
+import .git/hooks/pre-commit.sample (checksum...) ok
+(Recording state in git...)
+error: Invalid path 'foo/.git/COMMIT_EDITMSG'
+error: unable to add foo/.git/COMMIT_EDITMSG to index
+fatal: adding files failed
+
+git-annex: user error (xargs ["-0","git","--git-dir=/tmp/test/bar/.git","--work-tree=/tmp/test/bar","add","--"] exited 123)
+failed
+git-annex: import: 2 failed
+anarcat@angela:foo$ cd ../../foo
+anarcat@angela:foo$ git status
+fatal: Not a git repository (or any of the parent directories): .git
+anarcat@angela:foo$
+# End of transcript or log.
+"""]]
+
+Thanks! --[[anarcat]]
+
+> Would have thought this was obviously something you shouldn't do
+> (sorta like running git-annex import on your home directory),
+> but ok, it can skip .git directories. [[done]] --[[Joey]]
diff --git a/doc/bugs/git_annex_importfeed_fails.mdwn b/doc/bugs/git_annex_importfeed_fails.mdwn
new file mode 100644
index 000000000..244ed769c
--- /dev/null
+++ b/doc/bugs/git_annex_importfeed_fails.mdwn
@@ -0,0 +1,64 @@
+### Please describe the problem.
+
+git annex importfeed fails
+
+### What steps will reproduce the problem?
+
+git annex importfeed http://www.tatw.co.uk/podcast.xml
+
+### On what operating system?
+
+Ubuntu 12.04, the prebuilt linux tarball
+
+[[!format sh """
+$ git annex version
+git-annex version: 4.20130922-g7dc188a
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP Feeds Quvi
+local repository version: 3
+default repository version: 3
+supported repository versions: 3 4
+upgrade supported from repository versions: 0 1 2
+"""]]
+
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+$ git annex importfeed http://www.tatw.co.uk/podcast.xml
+(checking known urls...)
+(Recording state in git...)
+importfeed http://www.tatw.co.uk/podcast.xml
+--2013-09-27 12:16:09-- http://www.tatw.co.uk/podcast.xml
+Résolution de www.tatw.co.uk (www.tatw.co.uk)... 88.190.26.130
+Connexion vers www.tatw.co.uk (www.tatw.co.uk)|88.190.26.130|:80... connecté.
+requête HTTP transmise, en attente de la réponse... 200 OK
+Longueur: 41267 (40K) [application/xml]
+Sauvegarde en : «/tmp/user/2166/feed10670»
+
+100%[==========================================================================>] 41 267 81,6K/s ds 0,5s
+
+2013-09-27 12:16:10 (81,6 KB/s) - «/tmp/user/2166/feed10670» sauvegardé [41267/41267]
+
+addurl Above___Beyond__Group_Therapy/_001_Group_Therapy_Radio_with_Above___Beyond (downloading ...)
+failed
+addurl Above___Beyond__Group_Therapy/_002_Group_Therapy_Radio_with_Above___Beyond (downloading ...)
+failed
+addurl Above___Beyond__Group_Therapy/_003_Group_Therapy_Radio_with_Above___Beyond (downloading ...)
+failed
+addurl Above___Beyond__Group_Therapy/_004_Group_Therapy_Radio_with_Above___Beyond (downloading ...)
+failed
+
+etc
+
+
+# End of transcript or log.
+"""]]
+
+> This is a bug in the feed library: <https://github.com/sof/feed/issues/7>
+> And already fixed upstream this morning, so if you need the fix
+> immediately, build with cabal. Otherwise fix will percolate out to
+> builds eventually.
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/git_annex_indirect_can_fail_catastrophically.mdwn b/doc/bugs/git_annex_indirect_can_fail_catastrophically.mdwn
new file mode 100644
index 000000000..3dc193683
--- /dev/null
+++ b/doc/bugs/git_annex_indirect_can_fail_catastrophically.mdwn
@@ -0,0 +1,78 @@
+### Please describe the problem.
+
+I have a repo that I initialized in direct mode because i felt unconfortable with the "symlink forest" approach.
+
+Now that I prefer that, i want to switch back to indirect mode. The problem is, when I did that, I realized that some files in the repo were not writable by my user, and git annex indirect crashed, and didn't "indirect" all the files. Now the repo is in a "half-direct" state, and I seem to be unable to recover.
+
+### What steps will reproduce the problem?
+
+[[!format txt """
+git init
+git annex init
+git annex direct
+git annex add . # make sure some files are not writable by your user
+git annex indirect
+"""]]
+
+The `indirect` step will stop at the file that is not writable and will fail to move some files to `.git/annex`. And then the repo is in `indirect` mode yet some files are still not symlinks.
+
+Doing a `git annex direct` will try to commit all those nasty files into git, as it does a `git commit -a`.
+
+### What version of git-annex are you using? On what operating system?
+
+ git-annex version: 4.20130912-ga1faca3
+ build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP DNS Feeds Quvi
+
+Debian wheezy.
+
+### Please provide any additional information below.
+
+Ideally, there would be a way to just tell git annex it's really still in direct mode and migrate the remaining files.
+
+The workaround is, obviously, to make sure you own all those files before messing around:
+
+ chown -R you *
+ chmod -R u+w *
+
+A [[patch]], maybe, that allows you to flip cleanly between the two modes:
+
+[[!format diff """
+From a21dfc97da96883b2a088bb5f3f466296f08d858 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Antoine=20Beaupr=C3=A9?= <anarcat@koumbit.org>
+Date: Mon, 16 Sep 2013 13:58:29 -0400
+Subject: [PATCH] do not commit -a when going back to direct mode
+
+without this, if we switched to indirect mode but failed doing so
+(because of a permission problem, for example), going back to
+direct mode will commit all files to git, which we really want
+to avoid.
+
+---
+ Command/Direct.hs | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/Command/Direct.hs b/Command/Direct.hs
+index 7835988..ed8ea6c 100644
+--- a/Command/Direct.hs
++++ b/Command/Direct.hs
+@@ -33,7 +33,6 @@ perform = do
+ showOutput
+ _ <- inRepo $ Git.Command.runBool
+ [ Param "commit"
+- , Param "-a"
+ , Param "-m"
+ , Param "commit before switching to direct mode"
+ ]
+--
+1.7.10.4
+
+"""]]
+
+Any update on this? Why is `-a` used here? -- [[anarcat]]
+
+> -a is not really the problem. You certainly do usually want
+> to commit your changes before converting to direct mode.
+>
+> [[done]]; now when this happens it catches the exception and
+> leaves the file in direct mode, which is the same as it being
+> unlocked. --[[Joey]]
diff --git a/doc/bugs/git_annex_indirect_can_fail_catastrophically/comment_1_0b085e7e8c8e364f479574bc00c7c394._comment b/doc/bugs/git_annex_indirect_can_fail_catastrophically/comment_1_0b085e7e8c8e364f479574bc00c7c394._comment
new file mode 100644
index 000000000..68814881d
--- /dev/null
+++ b/doc/bugs/git_annex_indirect_can_fail_catastrophically/comment_1_0b085e7e8c8e364f479574bc00c7c394._comment
@@ -0,0 +1,21 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.220"
+ subject="comment 1"
+ date="2013-09-25T18:57:25Z"
+ content="""
+Worse than being stuck partway converted, it fails in such a way that the file you can't write to is left stuck in .git/annex/objects/ without a symlink pointint to it.
+
+Here is how to recover:
+
+1. run `git annex direct`
+2. run `git annex indirect`
+3. run `git annex direct`
+4. run `git annex indirect`
+5. run `git revert HEAD`
+6. run `git annex direct`
+7. fix the permission of the file
+8. run `git annex indirect`
+
+Please don't ask me why this works, but it will..
+"""]]
diff --git a/doc/bugs/git_annex_initremote_needs_some___34__error_checking__34__.mdwn b/doc/bugs/git_annex_initremote_needs_some___34__error_checking__34__.mdwn
new file mode 100644
index 000000000..6b57f8ce5
--- /dev/null
+++ b/doc/bugs/git_annex_initremote_needs_some___34__error_checking__34__.mdwn
@@ -0,0 +1,65 @@
+_git annex initremote_ without a complete command set still adds an entry to the uuid.log etc... and thus clutters up the state of the annex. I would not have expected this behaviour as a user.
+
+_initremote_ should fail and not do anything if the commands that it has been given are incomplete or incorrect. I was initialising a few rsync repos and noticed that i ended up having mutiple rsync remotes with the same name but different uuid's. I know its hard if not impossible to remove these uuid's so I have just marked them as "dead" in my live annexes.
+
+Here's a transcript of the problem
+
+<pre>
+x00:sandbox jtang$ mkdir atest
+x00:sandbox jtang$ cd atest/
+x00:atest jtang$ git init
+Initialized empty Git repository in /Users/jtang/sandbox/atest/.git/
+x00:atest jtang$ git annex init
+init ok
+(Recording state in git...)
+x00:atest jtang$ git annex status
+supported backends: SHA256 SHA1 SHA512 SHA224 SHA384 SHA256E SHA1E SHA512E SHA224E SHA384E WORM URL
+supported remote types: git S3 bup directory rsync web hook
+trusted repositories: 0
+semitrusted repositories: 2
+ 00000000-0000-0000-0000-000000000001 -- web
+ cbb58e1c-d737-11e1-b682-83239d5ff2e0 -- here
+untrusted repositories: 0
+dead repositories: 0
+transfers in progress: none
+available local disk space: 185 gigabytes (+1 megabyte reserved)
+local annex keys: 0
+local annex size: 0 bytes
+known annex keys: 0
+known annex size: 0 bytes
+bloom filter size: 16 mebibytes (0% full)
+backend usage:
+x00:atest jtang$ git annex initremote foo
+git-annex: Specify the type of remote with type=
+x00:atest jtang$ git annex initremote foo type=rsync
+(Recording state in git...)
+initremote foo git-annex: Specify encryption=key or encryption=none or encryption=shared
+x00:atest jtang$ git annex initremote foo type=rsync
+(Recording state in git...)
+initremote foo git-annex: Specify encryption=key or encryption=none or encryption=shared
+x00:atest jtang$ git annex status
+supported backends: SHA256 SHA1 SHA512 SHA224 SHA384 SHA256E SHA1E SHA512E SHA224E SHA384E WORM URL
+supported remote types: git S3 bup directory rsync web hook
+trusted repositories: (Recording state in git...)
+0
+semitrusted repositories: 5
+ 00000000-0000-0000-0000-000000000001 -- web
+ cbb58e1c-d737-11e1-b682-83239d5ff2e0 -- here
+ d3adfcd0-d737-11e1-b15b-b7032388f8aa -- foo
+ d6d8e1e0-d737-11e1-956a-0b3d3451226a -- foo
+ d78d795c-d737-11e1-ac98-4fe3d6fdfd54 -- foo
+untrusted repositories: 0
+dead repositories: 0
+transfers in progress: none
+available local disk space: 185 gigabytes (+1 megabyte reserved)
+local annex keys: 0
+local annex size: 0 bytes
+known annex keys: 0
+known annex size: 0 bytes
+bloom filter size: 16 mebibytes (0% full)
+backend usage:
+x00:atest jtang$
+</pre>
+
+> Indeed, I broke that in June by making it record the name in a much too
+> early stage. Now fixed. [[done]] --[[Joey]]
diff --git a/doc/bugs/git_annex_initremote_walks_.git-annex.mdwn b/doc/bugs/git_annex_initremote_walks_.git-annex.mdwn
new file mode 100644
index 000000000..acd369bde
--- /dev/null
+++ b/doc/bugs/git_annex_initremote_walks_.git-annex.mdwn
@@ -0,0 +1,19 @@
+a <!-- (a suggestion for introducing severity tags on bugs,
+feel free to discard) --> issue: `git annex initremote` (in particular, adding
+a key as described in [[encryption]] -- `git annex initremote my_remote
+encryption=my_key`) seems to iterate over the `.git-annex/???/???/*.log` files
+with lstat (tested using strace).
+
+in a 50k key git-annex on a slow disk, this takes quite a while, while not
+seeming necessary (it's just re-encrypting the shared secret, is it?).
+
+could you verify the observed behavior?
+
+> This is due to `git commit` being called. `git commit` exposes git's
+> rather innefficient handling of the index; in order to make a commit
+> it has to write a new index file, and it does this by scanning every
+> file in the repository. I think that git generally needs its index
+> file handleing overhauled, particularly to deal with repositories with
+> large numbers of files. git-annex is seems to already be running
+> `git commit` in its most efficient mode, by specifying exactly what file
+> to commit. [[done]] --[[Joey]]
diff --git a/doc/bugs/git_annex_map_has_problems_with_urls_containing___126__.mdwn b/doc/bugs/git_annex_map_has_problems_with_urls_containing___126__.mdwn
new file mode 100644
index 000000000..24f04eeb5
--- /dev/null
+++ b/doc/bugs/git_annex_map_has_problems_with_urls_containing___126__.mdwn
@@ -0,0 +1,46 @@
+I discovered a problem with `git annex map` and relative urls containing `~`.
+In this case i have a remote `noam` configured with the the following urls:
+
+ zsh» git remote show noam | head -3
+ * remote noam
+ Fetch URL: noam:bare-annex
+ Push URL: noam:bare-annex
+
+If i try to run `git annex map` i get the following error:
+
+ zsh» git annex map
+ map /home/esc/annex ok
+ map noam (sshing...)
+ bash: line 0: cd: /~/bare-annex/: No such file or directory
+ Command ssh ["noam","cd '/~/bare-annex/' && git config --list"] failed; exit code 1
+ (sshing...)
+ ok
+
+ running: dot -Tx11 map.dot
+
+ ok
+
+If i run the failing command manually, i get:
+
+ zsh» ssh noam "cd ~/bare-annex && git config --list"
+ core.repositoryformatversion=0
+ core.filemode=true
+ core.bare=true
+ annex.uuid=f267f55c-0732-11e1-a93b-93119f9aaf54
+ annex.version=3
+
+Also i can change the remote url to an absolute one, in which case `git annex
+map` works too:
+
+ zsh» git remote set-url noam noam:/home/esc/bare-annex
+ zsh» git annex map
+ map /home/esc/annex ok
+ map noam (sshing...)
+ ok
+
+ running: dot -Tx11 map.dot
+
+ ok
+
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/git_annex_migrate_leaves_old_backend_versions_around.mdwn b/doc/bugs/git_annex_migrate_leaves_old_backend_versions_around.mdwn
new file mode 100644
index 000000000..263338d64
--- /dev/null
+++ b/doc/bugs/git_annex_migrate_leaves_old_backend_versions_around.mdwn
@@ -0,0 +1,19 @@
+`git annex migrate` leaves old, unlinked backend versions lying around. It
+would be great if these were purged automatically somehow.
+
+> Yes, this is an issue mentioned in the
+> [[tips/migrating_data_to_a_new_backend]].
+>
+> Since multiple files can point to the same content, it could be that
+> only one file has been migrated, and the content is still used. So
+> the content either has to be retained, or an operation as expensive
+> as `git annex unused` used to find if something else still uses it.
+>
+> Rather than adding such an
+> expensive operation to each call to migrate, I focused on hard-linking
+> the values for the old and new keys, so that the old keys don't actually
+> use any additional resources (beyond an extra inode).
+>
+> This way a lot of migrations can be done, and only when you're done you
+> can do the more expensive cleanup pass if you want to. --[[Joey]]
+> [[done]]
diff --git a/doc/bugs/git_annex_migrate_leaves_old_backend_versions_around/comment_1_f3e418144e5a5a9b3eda459546fc2bb0._comment b/doc/bugs/git_annex_migrate_leaves_old_backend_versions_around/comment_1_f3e418144e5a5a9b3eda459546fc2bb0._comment
new file mode 100644
index 000000000..dac018cfa
--- /dev/null
+++ b/doc/bugs/git_annex_migrate_leaves_old_backend_versions_around/comment_1_f3e418144e5a5a9b3eda459546fc2bb0._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://nicolas-schodet.myopenid.com/"
+ ip="2a01:e35:8ae6:f130:1e4b:d6ff:fe78:1ddb"
+ subject="Hardlink on remote repository?"
+ date="2013-08-15T06:58:16Z"
+ content="""
+Does the hardlink magic also work on the remote repository? If I understand correctly, the remote does not know that the new hash is the same file (and also, file needs to be transferred again) unless the migration is done on all remote before synchronizing. Is it right?
+"""]]
diff --git a/doc/bugs/git_annex_should_use___39__git_add_-f__39___internally.mdwn b/doc/bugs/git_annex_should_use___39__git_add_-f__39___internally.mdwn
new file mode 100644
index 000000000..a92f5871b
--- /dev/null
+++ b/doc/bugs/git_annex_should_use___39__git_add_-f__39___internally.mdwn
@@ -0,0 +1,11 @@
+I have this line in the .gitignore file of one of my repos:
+*log
+
+So the command 'git annex init name' fails to add the file ".git-annex/uuid.log", and the same problem happens when git-annex-add'ing files.
+
+> This is avoided on the v3 branch, which does not store these files in the
+> same branch as your repository.
+
+Also, when a file is git-ignored, it should be possible to 'git annex add' it with a -f/--force option, the same way git does it.
+
+> Reasonable, [[done]] --[[Joey]]
diff --git a/doc/bugs/git_annex_should_use___39__git_add_-f__39___internally/comment_1_7683bf02cf9e97830fb4690314501568._comment b/doc/bugs/git_annex_should_use___39__git_add_-f__39___internally/comment_1_7683bf02cf9e97830fb4690314501568._comment
new file mode 100644
index 000000000..c556fbd77
--- /dev/null
+++ b/doc/bugs/git_annex_should_use___39__git_add_-f__39___internally/comment_1_7683bf02cf9e97830fb4690314501568._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnpdM9F8VbtQ_H5PaPMpGSxPe_d5L1eJ6w"
+ nickname="Rafaël"
+ subject="comment 1"
+ date="2011-07-03T11:56:45Z"
+ content="""
+And what about emitting a warning, as git does, that some files were not annex-added (when not using --force)?
+"""]]
diff --git a/doc/bugs/git_annex_sync_in_direct_mode_does_not_honor_skip-worktree.mdwn b/doc/bugs/git_annex_sync_in_direct_mode_does_not_honor_skip-worktree.mdwn
new file mode 100644
index 000000000..4d60c96c8
--- /dev/null
+++ b/doc/bugs/git_annex_sync_in_direct_mode_does_not_honor_skip-worktree.mdwn
@@ -0,0 +1,35 @@
+### Please describe the problem.
+
+In a direct mode repo (crippled/uncrippled filesystem does not matter), when a symlink is marked using `git update-index --skip-worktree <FILE>` and removed, git annex sync still `git rm`s the symlink. This does not happen in indirect mode (git annex sync leaves the symlink in git intact).
+
+### What steps will reproduce the problem?
+
+[[!format sh """
+mkdir test-repo; cd test-repo
+git init
+git annex init
+echo file1 >file1
+git annex add
+git commit -m"update"
+cd ..
+git clone test-repo test-repo2; cd test-repo2
+git annex init
+git annex direct
+git update-index --skip-worktree file1
+rm file1
+git annex sync
+"""]]
+
+Output of `git annex sync` indicates file has been removed from git. Repeating these steps without the `git annex direct` above to set the second repo to direct mode will succeed in retaining the symlink in git.
+
+### What version of git-annex are you using? On what operating system?
+
+4.20130521 using git-annex-standalone AUR build (uses Linux executable tarball) on Arch Linux
+
+### Please provide any additional information below.
+
+I'd like to use the skip-worktree scheme in order to be able to rm the symlink files (from the filesystem, not git), specifically for my Android devices. Syncing my music annex creates .mp3 symlinks that aren't actually MP3s, which gives the stock apps some fits. This would only be for clearing out symlinks; I fully understand that trying to doing this for downloaded content in a direct repo would be a Class A no-no. :-)
+
+I did a little digging in the code, and it looks like the source of this is the stageDirect step done specifically by `git annex sync` in direct repos (which makes sense, since indirect repos work). It does `git ls-files --others --exclude-standard --stage`. This list includes files marked skip-worktree, which means skip-worktree files would be treated like normal, and deleted because it's no longer there. There is an additional `-t` argument that could be added to ls-files that would provide the tag field to indicate if a file was marked skip-worktree, and they could be filtered out of processing.
+
+I wonder if this would have side effects, or if there are other places in the code where skip-worktree files would need to be handled, though. I'm particularly motivated to solve this, so let me know if it doesn't look like it would get looked at right away, and I'll have an excuse to get a Haskell dev environment setup again and shake the rust off.
diff --git a/doc/bugs/git_annex_sync_in_direct_mode_does_not_honor_skip-worktree/comment_1_69baeb997086c885f34fd1dc385cf5d6._comment b/doc/bugs/git_annex_sync_in_direct_mode_does_not_honor_skip-worktree/comment_1_69baeb997086c885f34fd1dc385cf5d6._comment
new file mode 100644
index 000000000..e7baee584
--- /dev/null
+++ b/doc/bugs/git_annex_sync_in_direct_mode_does_not_honor_skip-worktree/comment_1_69baeb997086c885f34fd1dc385cf5d6._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-05-29T16:45:03Z"
+ content="""
+I'm a little worried about -t being \"semi-deprecated\". I don't know if it would be possible to use either of the other commands the man page suggests to get the info needed by `stageDirect`. (Particularly the Sha of their staged contents.)
+
+All of git-annex's access to the repository tree goes via Git.LsFiles and AFAICS, all the other git commands used there do respect skip-worktree.
+
+I encourage you to work on this, since you're motivated.
+"""]]
diff --git a/doc/bugs/git_annex_sync_in_direct_mode_does_not_honor_skip-worktree/comment_2_fb8c0bebb9aaa75ee7eaf6999b1db49e._comment b/doc/bugs/git_annex_sync_in_direct_mode_does_not_honor_skip-worktree/comment_2_fb8c0bebb9aaa75ee7eaf6999b1db49e._comment
new file mode 100644
index 000000000..a252c5ea9
--- /dev/null
+++ b/doc/bugs/git_annex_sync_in_direct_mode_does_not_honor_skip-worktree/comment_2_fb8c0bebb9aaa75ee7eaf6999b1db49e._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="EvanDeaubl"
+ ip="12.130.123.174"
+ subject="comment 2"
+ date="2013-05-31T13:38:43Z"
+ content="""
+I share the concerns about the semi-deprecated status, although it's probably safer than they make it sound in the man page. The git test suite for sparse checkouts uses the same command to find files with skip-worktree set, and there are other tools that use it as well (magit being one example). The git maintainers couldn't remove it, or even fully deprecate it for eventual removal. It's been semi-deprecated for almost 3 years.
+
+I have a patch that fixes `git annex sync` and `git annex get` (it retrieved files marked skip-worktree) and it passes `git annex test`, but I'm going to more rigorously test it out on my particular use case before calling it good. When it is ready, I didn't see instructions on how you would like patches submitted anywhere in the wiki. How would you like to receive it?
+"""]]
diff --git a/doc/bugs/git_annex_sync_in_direct_mode_does_not_honor_skip-worktree/comment_3_6bfd4e9a7853af93e72b717249de9439._comment b/doc/bugs/git_annex_sync_in_direct_mode_does_not_honor_skip-worktree/comment_3_6bfd4e9a7853af93e72b717249de9439._comment
new file mode 100644
index 000000000..b92ec0f13
--- /dev/null
+++ b/doc/bugs/git_annex_sync_in_direct_mode_does_not_honor_skip-worktree/comment_3_6bfd4e9a7853af93e72b717249de9439._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-05-31T18:22:12Z"
+ content="""
+I accept patches by email, or pull requests.
+"""]]
diff --git a/doc/bugs/git_annex_uninit_loses_content_when_interrupted.mdwn b/doc/bugs/git_annex_uninit_loses_content_when_interrupted.mdwn
new file mode 100644
index 000000000..e7698883f
--- /dev/null
+++ b/doc/bugs/git_annex_uninit_loses_content_when_interrupted.mdwn
@@ -0,0 +1,33 @@
+### Please describe the problem.
+
+When git annex uninit is interrupted, git status shows
+
+# On branch master
+# Changes to be committed:
+# (use "git reset HEAD <file>..." to unstage)
+
+deleted: file1
+
+file1 is the file that was being processed at the time of the interrupt.
+
+### What steps will reproduce the problem?
+
+git annex uninit
+
+Ctrl-C
+
+### What version of git-annex are you using? On what operating system?
+
+4.20130709
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
+
+> [[done]]; see my comment --[[Joey]]
diff --git a/doc/bugs/git_annex_uninit_loses_content_when_interrupted/comment_1_fd9d2abbc90fb4f470b2212bc1f4a2dd._comment b/doc/bugs/git_annex_uninit_loses_content_when_interrupted/comment_1_fd9d2abbc90fb4f470b2212bc1f4a2dd._comment
new file mode 100644
index 000000000..f9865ca69
--- /dev/null
+++ b/doc/bugs/git_annex_uninit_loses_content_when_interrupted/comment_1_fd9d2abbc90fb4f470b2212bc1f4a2dd._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.90"
+ subject="comment 1"
+ date="2013-07-16T18:29:37Z"
+ content="""
+All you have to do to get file1 back is check its symlink back out of git's history. `git checkout file1` should suffice to recover. \"Loses content\" is way overstating the severity of this bug.
+"""]]
diff --git a/doc/bugs/git_annex_uninit_loses_content_when_interrupted/comment_2_0e99f6ef4f8b342ef0ebc64dbf8e2ce6._comment b/doc/bugs/git_annex_uninit_loses_content_when_interrupted/comment_2_0e99f6ef4f8b342ef0ebc64dbf8e2ce6._comment
new file mode 100644
index 000000000..2b6fc4186
--- /dev/null
+++ b/doc/bugs/git_annex_uninit_loses_content_when_interrupted/comment_2_0e99f6ef4f8b342ef0ebc64dbf8e2ce6._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.90"
+ subject="comment 2"
+ date="2013-07-16T19:08:49Z"
+ content="""
+However, if you then run `git annex uninit` a second time, it goes ahead and deletes the content! That is a bug.
+
+I looked into trying to make uninit always replace the symlink atomically with the file content. It can't be done when using --fast, since it's not possible to atomically replace a symlink with a hard link (AFAIK). It should be possible to do it in the normal mode, but it would require manually constructing a commit, since git does not provide a way to delete a file from the index and commit that staged change without also committing any other changes that are staged -- and uninit should preseve any changes to non-annexed files that the user has staged. So, I don't think atomic operation is the right answer.
+
+Instead, I have made uninit refuse to delete .git/annex/objects unless it's empty, and if objects are still left in there, for whatever reason, it'll fail at the end with a nice message explaining some options. I think this is the right fix because it also avoids uninit removing historical versions of files that were stored in git-annex.g
+"""]]
diff --git a/doc/bugs/git_annex_uninit_removes_files_not_previously_added_to_annex.mdwn b/doc/bugs/git_annex_uninit_removes_files_not_previously_added_to_annex.mdwn
new file mode 100644
index 000000000..71fd408e2
--- /dev/null
+++ b/doc/bugs/git_annex_uninit_removes_files_not_previously_added_to_annex.mdwn
@@ -0,0 +1,32 @@
+### Please describe the problem.
+
+Suppose there are files not added/committed to git annex.
+Once git annex uninit is complete, these files are deleted.
+
+### What steps will reproduce the problem?
+
+cp big-file annex-dir;
+cd annex-dir;
+git annex uninit
+
+...
+big-file is gone
+
+### What version of git-annex are you using? On what operating system?
+
+4.20130709
+Linux Ubuntu 13.04
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
+
+[[!tag moreinfo]]
+
+> [[done]]; unreproducible by anyone. --[[Joey]]
diff --git a/doc/bugs/git_annex_uninit_removes_files_not_previously_added_to_annex/comment_1_ce4e3b1bf0d53119d049cf7dd621c5c4._comment b/doc/bugs/git_annex_uninit_removes_files_not_previously_added_to_annex/comment_1_ce4e3b1bf0d53119d049cf7dd621c5c4._comment
new file mode 100644
index 000000000..bf5f04a90
--- /dev/null
+++ b/doc/bugs/git_annex_uninit_removes_files_not_previously_added_to_annex/comment_1_ce4e3b1bf0d53119d049cf7dd621c5c4._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.90"
+ subject="comment 1"
+ date="2013-07-16T18:21:18Z"
+ content="""
+I can't reproduce that. uninit leaves alone files that are not checked into git. Indeed, it only ever does anything to files that are checked into git and are symlinks to git-annex content. So I don't see how it could possibly behave as described.
+
+Please provide a complete transcript of the problem you are seeing.
+"""]]
diff --git a/doc/bugs/git_annex_uninit_removes_files_not_previously_added_to_annex/comment_2_3aa125635609fce41ab0c98cefb81f98._comment b/doc/bugs/git_annex_uninit_removes_files_not_previously_added_to_annex/comment_2_3aa125635609fce41ab0c98cefb81f98._comment
new file mode 100644
index 000000000..dec43f390
--- /dev/null
+++ b/doc/bugs/git_annex_uninit_removes_files_not_previously_added_to_annex/comment_2_3aa125635609fce41ab0c98cefb81f98._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawln3ckqKx0x_xDZMYwa9Q1bn4I06oWjkog"
+ nickname="Michael"
+ subject="can't reproduce this anymore"
+ date="2013-07-17T17:04:05Z"
+ content="""
+This could have been a PEBKAC.
+
+"""]]
diff --git a/doc/bugs/git_annex_unlock_is_not_atomic.mdwn b/doc/bugs/git_annex_unlock_is_not_atomic.mdwn
new file mode 100644
index 000000000..6d324ff50
--- /dev/null
+++ b/doc/bugs/git_annex_unlock_is_not_atomic.mdwn
@@ -0,0 +1,7 @@
+Running a command like
+
+git annex unlock myfile
+
+is not atomic, that is if the execution is aborted you may end up with an incomplete version of myfile in the directory. If you don't notice this you may lock it again and then propagate this bad version of the file to your other repositories. A simple workaround is to simply name it something else while unlocking and then rename it to the correct filename once it's completely copied. I don't know Haskel yet so I can not fix this issue otherwise I would sure try. A part from this, I love git annex.
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/git_annex_unused_aborts_due_to_filename_encoding_problems.mdwn b/doc/bugs/git_annex_unused_aborts_due_to_filename_encoding_problems.mdwn
new file mode 100644
index 000000000..fb0bdb093
--- /dev/null
+++ b/doc/bugs/git_annex_unused_aborts_due_to_filename_encoding_problems.mdwn
@@ -0,0 +1,15 @@
+What steps will reproduce the problem?
+I don't know exactly when it started
+
+What is the expected output? What do you see instead?
+When I run git annex unused I get
+
+ unused . (checking for unused data...) (checking master...) git-annex: Cannot decode byte '\xb4': Data.Text.Encoding.decodeUtf8: Invalid UTF-8 stream
+
+Most likely I have added some file with a strange encoding that git-annex can't decode. The problem is that the unused process aborts because of this.
+
+What version of git-annex are you using? On what operating system?
+ 3.20120522, Debian testing
+
+> I've just fixed this bug in git, will be in the next release. --[[Joey]]
+> [[done]]
diff --git a/doc/bugs/git_annex_unused_aborts_due_to_filename_encoding_problems/comment_1_8ba4fdb9f2d3bd44db5e910526cb9124._comment b/doc/bugs/git_annex_unused_aborts_due_to_filename_encoding_problems/comment_1_8ba4fdb9f2d3bd44db5e910526cb9124._comment
new file mode 100644
index 000000000..ddea8225e
--- /dev/null
+++ b/doc/bugs/git_annex_unused_aborts_due_to_filename_encoding_problems/comment_1_8ba4fdb9f2d3bd44db5e910526cb9124._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.2.6"
+ subject="comment 1"
+ date="2012-06-20T14:30:27Z"
+ content="""
+Try running `git annex unused --debug`; this will tell us the git command that's outputing the data it cannot process. Then you can try running that git command and see what the problem filename is.
+"""]]
diff --git a/doc/bugs/git_annex_unused_aborts_due_to_filename_encoding_problems/comment_2_2a4a2b3e287a0444a1c8e8d98768a206._comment b/doc/bugs/git_annex_unused_aborts_due_to_filename_encoding_problems/comment_2_2a4a2b3e287a0444a1c8e8d98768a206._comment
new file mode 100644
index 000000000..8afe3143c
--- /dev/null
+++ b/doc/bugs/git_annex_unused_aborts_due_to_filename_encoding_problems/comment_2_2a4a2b3e287a0444a1c8e8d98768a206._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.2.6"
+ subject="comment 2"
+ date="2012-06-20T14:34:23Z"
+ content="""
+Your `locale` setting may also be relevant. FWIW, I've tried to create a file with `\xb4` in its name and have not gotten git-annex unused to crash on it.
+"""]]
diff --git a/doc/bugs/git_annex_unused_aborts_due_to_filename_encoding_problems/comment_3_dacfdb8322045fc4ceefc9128bf7c505._comment b/doc/bugs/git_annex_unused_aborts_due_to_filename_encoding_problems/comment_3_dacfdb8322045fc4ceefc9128bf7c505._comment
new file mode 100644
index 000000000..8e2aa285a
--- /dev/null
+++ b/doc/bugs/git_annex_unused_aborts_due_to_filename_encoding_problems/comment_3_dacfdb8322045fc4ceefc9128bf7c505._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnXgp-iIaBK5pnk22xqMVERQb97VyXaejs"
+ nickname="Kristian"
+ subject="comment 3"
+ date="2012-06-20T14:37:09Z"
+ content="""
+This is what happens when I add the debug parameter
+
+git annex unused --debug
+
+unused . (checking for unused data...) git [\"--git-dir=/home/kristian/AnnexMedia/.git\",\"--work-tree=/home/kristian/AnnexMedia\",\"ls-files\",\"--cached\",\"-z\",\"--\",\"/home/kristian/AnnexMedia\"]
+git [\"--git-dir=/home/kristian/AnnexMedia/.git\",\"--work-tree=/home/kristian/AnnexMedia\",\"show-ref\"]
+(checking master...) git [\"--git-dir=/home/kristian/AnnexMedia/.git\",\"--work-tree=/home/kristian/AnnexMedia\",\"ls-tree\",\"--full-tree\",\"-z\",\"-r\",\"--\",\"refs/heads/master\"]
+git [\"--git-dir=/home/kristian/AnnexMedia/.git\",\"--work-tree=/home/kristian/AnnexMedia\",\"cat-file\",\"--batch\"]
+git-annex: Cannot decode byte '\xb4': Data.Text.Encoding.decodeUtf8: Invalid UTF-8 stream
+
+"""]]
diff --git a/doc/bugs/git_annex_unused_aborts_due_to_filename_encoding_problems/comment_4_7889a3ff5ce80c6322448aa674df8525._comment b/doc/bugs/git_annex_unused_aborts_due_to_filename_encoding_problems/comment_4_7889a3ff5ce80c6322448aa674df8525._comment
new file mode 100644
index 000000000..da97b12f7
--- /dev/null
+++ b/doc/bugs/git_annex_unused_aborts_due_to_filename_encoding_problems/comment_4_7889a3ff5ce80c6322448aa674df8525._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.2.6"
+ subject="comment 4"
+ date="2012-06-20T14:49:09Z"
+ content="""
+Ah, reproduced it; need to use the WORM backend and have the file present in another branch..
+
+
+"""]]
diff --git a/doc/bugs/git_annex_unused_aborts_due_to_filename_encoding_problems/comment_5_6d28c2537ce24eeb3496ca349823defd._comment b/doc/bugs/git_annex_unused_aborts_due_to_filename_encoding_problems/comment_5_6d28c2537ce24eeb3496ca349823defd._comment
new file mode 100644
index 000000000..fafd1d248
--- /dev/null
+++ b/doc/bugs/git_annex_unused_aborts_due_to_filename_encoding_problems/comment_5_6d28c2537ce24eeb3496ca349823defd._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnXgp-iIaBK5pnk22xqMVERQb97VyXaejs"
+ nickname="Kristian"
+ subject="comment 5"
+ date="2012-06-20T14:55:33Z"
+ content="""
+I checkout out the git annex branch and using
+
+ find * | grep -P \"[\xb4]\"
+
+I found a file
+
+ 43e/b16/WORM-s4118528-m1245167306--Jerry Lee Lewis - Whole Lotta Shakin\302\264 Going\302\264 On.mp3.log
+
+The corresponding file also existed in the master branch (as a link).
+
+I moved both these files to a folder outside my repository and synched my git-annex branch with by master server. I still get the same error. Is there any other place where information about this file is stored?
+
+"""]]
diff --git a/doc/bugs/git_annex_unused_aborts_due_to_filename_encoding_problems/comment_6_4bf14ecef622988e80976c0fb55c24b9._comment b/doc/bugs/git_annex_unused_aborts_due_to_filename_encoding_problems/comment_6_4bf14ecef622988e80976c0fb55c24b9._comment
new file mode 100644
index 000000000..b35e31da6
--- /dev/null
+++ b/doc/bugs/git_annex_unused_aborts_due_to_filename_encoding_problems/comment_6_4bf14ecef622988e80976c0fb55c24b9._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.2.6"
+ subject="comment 6"
+ date="2012-06-20T16:59:53Z"
+ content="""
+git-annex was not crashing due to content in the git-annex branch, but due to a symlink in one of your regular git branches, probably master and origin/master.
+
+This bug is fixed in git master, if you need the fix before the next release.
+"""]]
diff --git a/doc/bugs/git_annex_unused_aborts_due_to_filename_encoding_problems/comment_7_d2e5382fe0f38fb9dd9ee69901c68151._comment b/doc/bugs/git_annex_unused_aborts_due_to_filename_encoding_problems/comment_7_d2e5382fe0f38fb9dd9ee69901c68151._comment
new file mode 100644
index 000000000..65a02fed9
--- /dev/null
+++ b/doc/bugs/git_annex_unused_aborts_due_to_filename_encoding_problems/comment_7_d2e5382fe0f38fb9dd9ee69901c68151._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmL8pteP2jbYJUn1M3CbeLDvz2SWAA1wtg"
+ nickname="Kristian"
+ subject="comment 7"
+ date="2012-06-20T20:49:06Z"
+ content="""
+Thank you
+"""]]
diff --git a/doc/bugs/git_annex_unused_aborts_due_to_filename_encoding_problems/comment_8_b282757537cda863d3dc6d0bbfd6b656._comment b/doc/bugs/git_annex_unused_aborts_due_to_filename_encoding_problems/comment_8_b282757537cda863d3dc6d0bbfd6b656._comment
new file mode 100644
index 000000000..ff1de6b2e
--- /dev/null
+++ b/doc/bugs/git_annex_unused_aborts_due_to_filename_encoding_problems/comment_8_b282757537cda863d3dc6d0bbfd6b656._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnXgp-iIaBK5pnk22xqMVERQb97VyXaejs"
+ nickname="Kristian"
+ subject="comment 8"
+ date="2012-06-21T07:08:22Z"
+ content="""
+Confirmed. I built the newest version of git-annex and it solved the issue :)
+"""]]
diff --git a/doc/bugs/git_annex_unused_considers_remote_branches_which_makes_it_inconsistent.mdwn b/doc/bugs/git_annex_unused_considers_remote_branches_which_makes_it_inconsistent.mdwn
new file mode 100644
index 000000000..86151d116
--- /dev/null
+++ b/doc/bugs/git_annex_unused_considers_remote_branches_which_makes_it_inconsistent.mdwn
@@ -0,0 +1,106 @@
+The "git annex unused" command considers remote branches as well as local branches. This means that an
+object may be considered unused or not depending on what remotes are present and when they were last synced.
+
+I ran into this issue when experimenting with using repos on removable storage. I'll post more about
+what I was trying to do in the forum. I'm posting this in bugs as I believe the inconsistent behavior
+should probably be considered a bug.
+
+#What steps will reproduce the problem?
+
+Here is a sample session illustrating the problem. At the end, you can see that the object is
+not shown as unused, then the remote is removed and it is shown as unused, then the remote is added
+back and the file is once again not shown as unused.
+
+ /tmp/git $ mkdir 1 2
+ /tmp/git $ cd 1
+ /tmp/git/1 $ git init
+ Initialized empty Git repository in /tmp/git/1/.git/
+ /tmp/git/1 $ git annex init 1
+ init 1 ok
+ (Recording state in git...)
+ /tmp/git/1 $ git remote add 2 ../2
+ /tmp/git/1 $ dd if=/dev/urandom of=file.bin count=100
+ 100+0 records in
+ 100+0 records out
+ 51200 bytes (51 kB) copied, 0.0113172 s, 4.5 MB/s
+ /tmp/git/1 $ git annex add file.bin
+ add file.bin (checksum...) ok
+ (Recording state in git...)
+ /tmp/git/1 $ git commit -m 'added file'
+ [master (root-commit) 3c1ad30] added file
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+ create mode 120000 file.bin
+ /tmp/git/1 $ cd ../2
+ /tmp/git/2 $ git init
+ Initialized empty Git repository in /tmp/git/2/.git/
+ /tmp/git/2 $ git annex init 2
+ init 2 ok
+ (Recording state in git...)
+ /tmp/git/2 $ git remote add 1 ../1
+ /tmp/git/2 $ git fetch 1
+ warning: no common commits
+ remote: Counting objects: 13, done.
+ remote: Compressing objects: 100% (9/9), done.
+ remote: Total 13 (delta 0), reused 0 (delta 0)
+ Unpacking objects: 100% (13/13), done.
+ From ../1
+ * [new branch] git-annex -> 1/git-annex
+ * [new branch] master -> 1/master
+ /tmp/git/2 $ git checkout -b master 1/master
+ Branch master set up to track remote branch master from 1.
+ Already on 'master'
+ /tmp/git/2 $ cd ../1
+ /tmp/git/1 $ git fetch 2
+ remote: Counting objects: 5, done.
+ remote: Compressing objects: 100% (3/3), done.
+ remote: Total 5 (delta 0), reused 0 (delta 0)
+ Unpacking objects: 100% (5/5), done.
+ From ../2
+ * [new branch] git-annex -> 2/git-annex
+ * [new branch] master -> 2/master
+ /tmp/git/1 $ git rm file.bin
+ rm 'file.bin'
+ /tmp/git/1 $ git commit -m 'rmed file'
+ [master ab242b0] rmed file
+ 1 files changed, 0 insertions(+), 1 deletions(-)
+ delete mode 120000 file.bin
+ /tmp/git/1 $ git annex unused
+ unused . (checking for unused data...) (checking master...) (checking 2/master...) ok
+ /tmp/git/1 $ git remote rm 2
+ /tmp/git/1 $ git annex unused
+ unused . (checking for unused data...) (checking master...)
+ Some annexed data is no longer used by any files:
+ NUMBER KEY
+ 1 SHA256E-s51200--e400e5abea095ad4364d8f97c5fe1a3f8a6db670b2dfee951d7c9674afc9a21d.bin
+ (To see where data was previously used, try: git log --stat -S'KEY')
+
+ To remove unwanted data: git-annex dropunused NUMBER
+
+ ok
+ /tmp/git/1 $ git remote add 2 ../2
+ /tmp/git/1 $ git fetch 2
+ From ../2
+ * [new branch] git-annex -> 2/git-annex
+ * [new branch] master -> 2/master
+ /tmp/git/1 $ git annex unused
+ unused . (checking for unused data...) (checking master...) (checking 2/master...) ok
+ /tmp/git/1 $
+
+
+#What is the expected output? What do you see instead?
+
+I expected that the object's unused status would not change based on which remotes this particular
+repo knows about. In other words, I expected the unused status to be based on the local branches
+and possibly information in the git-annex branch.
+
+#What version of git-annex are you using? On what operating system?
+
+Gentoo Linux, git annex version 3.20121211
+
+#Please provide any additional information below.
+
+The forum post describing what I was trying to accomplish is [[forum/Best way to manage files on removable media?]]
+
+> While it would be nice if git-annex unused could somehow know about
+> branches that exist on remotes that git doesn't have locally, this is
+> impossible. It does the best it can. [[done]] --[[Joey]]
diff --git a/doc/bugs/git_annex_unused_considers_remote_branches_which_makes_it_inconsistent/comment_1_a636ffe55b11c46a0afcc0b9a3a88cd4._comment b/doc/bugs/git_annex_unused_considers_remote_branches_which_makes_it_inconsistent/comment_1_a636ffe55b11c46a0afcc0b9a3a88cd4._comment
new file mode 100644
index 000000000..97af66bc7
--- /dev/null
+++ b/doc/bugs/git_annex_unused_considers_remote_branches_which_makes_it_inconsistent/comment_1_a636ffe55b11c46a0afcc0b9a3a88cd4._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.126"
+ subject="comment 1"
+ date="2012-12-23T19:51:52Z"
+ content="""
+The goal is not to consider an object unused that some other remote is known to rely on. We try as hard as we can to avoid losing data, at the expense of possibly not dropping unused content as early as possible.
+
+Running `git annex sync` or similar to get current with the state of all remotes before dropping objects they might still rely on seems reasonable from this perspective.
+"""]]
diff --git a/doc/bugs/git_annex_unused_considers_remote_branches_which_makes_it_inconsistent/comment_2_5e1ad57420efd16ae09c9e5cad55b5f2._comment b/doc/bugs/git_annex_unused_considers_remote_branches_which_makes_it_inconsistent/comment_2_5e1ad57420efd16ae09c9e5cad55b5f2._comment
new file mode 100644
index 000000000..ffc0359a8
--- /dev/null
+++ b/doc/bugs/git_annex_unused_considers_remote_branches_which_makes_it_inconsistent/comment_2_5e1ad57420efd16ae09c9e5cad55b5f2._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="Steve"
+ ip="92.104.175.136"
+ subject="comment 2"
+ date="2013-01-01T23:51:53Z"
+ content="""
+I filed the bug because I thought the inconsistent behavior was bad. For example; If you move the data to a repo which doesn't know about the unsynced remote, it'll happily get dropped with dropunused as opposed to being considered in use in the current repo.
+
+There probably aren't too many people who want to have remotes set that are usually unreachable, and I can work around it now that I know it exists.
+
+If it is expected behavior, feel free to close the bug.
+
+"""]]
diff --git a/doc/bugs/git_annex_unused_failes_on_empty_repository.mdwn b/doc/bugs/git_annex_unused_failes_on_empty_repository.mdwn
new file mode 100644
index 000000000..05aa69572
--- /dev/null
+++ b/doc/bugs/git_annex_unused_failes_on_empty_repository.mdwn
@@ -0,0 +1,15 @@
+[[!meta title="`git annex unused` fails on empty repository"]]
+
+The ``git annex unused`` command fails on a git-annex repository, if there are no objects yet:
+
+ $ git annex unused
+ unused (checking for unused data...)
+ git-annex: /tmp/annextest/other_annex/.git/annex/objects: getDirectoryContents: does not exist (No such file or directory)
+ git-annex: 1 failed
+ $
+
+This can give a user (especially one that wants to try out simple commands with his newly created repo) the impression that something is wrong, while it is not. I'd expect the program either to show the same message ``git annex unused`` shows when everything is ok (since it is, or should be).
+
+This can be a bug in the ``unused`` subcommand (that fails to accept the absence of an objects directory) or in the ``init`` subcommand (that fails to create it).
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/git_annex_unused_seems_to_check_for_current_path.mdwn b/doc/bugs/git_annex_unused_seems_to_check_for_current_path.mdwn
new file mode 100644
index 000000000..f2d301cd7
--- /dev/null
+++ b/doc/bugs/git_annex_unused_seems_to_check_for_current_path.mdwn
@@ -0,0 +1,39 @@
+When I run `git annex unused` from my repository's root it shows everything ok:
+
+ ~/annex$ git annex unused
+ unused (checking for unused data...) ok
+
+But... When I run it from a subdirectory, it shows a lot:
+
+ ~/annex/Software$ git annex unused
+ unused (checking for unused data...)
+ Some annexed data is no longer pointed to by any files in the repository:
+ NUMBER KEY
+ 1 SHA1:########################################
+ ...
+ 921 SHA1:########################################
+ (To see where data was previously used, try: git log --stat -S'KEY')
+ (To remove unwanted data: git-annex dropunused NUMBER)
+ ok
+
+Is this a bug or by design? By removing these "unused" files with `dropunused` I've just lost the only copy of 160 files.
+
+I am using git-annex version 836e71297b8e3b5bd6f89f7eb1198f59af985b0b
+
+> I'm very sorry you lost data.
+>
+> But, git annex unused absolutely does not let the current directory
+> influence what it does. It always scans the entire repo from the top.
+> And I've tested it just now to make sure that in a subdirectory
+> it does the same thing as at the top.
+>
+> There are only two ways this could happen that I can think of:
+>
+> 1. If "Software" were a separate git repository than "~/annex".
+> 2. If gitignores or something made `git ls-files`
+> not list the files when ran in the subdir. This seems *possible*,
+> but I don't know how to construct such an ignore.
+>
+> --[[Joey]]
+
+>> Closing as there is no followup. [[done]] --[[Joey]]
diff --git a/doc/bugs/git_annex_upgrade_loses_track_of_files_with___34____38____34___character___40__and_probably_others__41__.mdwn b/doc/bugs/git_annex_upgrade_loses_track_of_files_with___34____38____34___character___40__and_probably_others__41__.mdwn
new file mode 100644
index 000000000..9daf8a0cb
--- /dev/null
+++ b/doc/bugs/git_annex_upgrade_loses_track_of_files_with___34____38____34___character___40__and_probably_others__41__.mdwn
@@ -0,0 +1,33 @@
+"git annex upgrade" has lost track of some of my files. Most of them have "&" characters. The others contain "%" characters (I haven't tried the testcase below with "%" however).
+
+Testcase:
+
+ # (With git annex v2)
+ mkdir ~/testannex1
+ cd ~/testannex1
+ git init
+ git annex init "testannex1"
+ touch '02 - Afternoons & Coffeespoons.mp3'
+ touch 'no ampersand.mp3'
+ git annex add '02 - Afternoons & Coffeespoons.mp3'
+ git annex add 'no ampersand.mp3'
+ git commit -m added
+ git annex whereis '02 - Afternoons & Coffeespoons.mp3'
+ git annex whereis 'no ampersand.mp3'
+ # (Upgrade git-annex binary to v3 and then...)
+ git annex upgrade
+ git annex whereis '02 - Afternoons & Coffeespoons.mp3'
+ git annex whereis 'no ampersand.mp3'
+
+This produces:
+
+ 12:38:40 ~/testannex1 (master)$ git annex whereis '02 - Afternoons & Coffeespoons.mp3'
+ whereis 02 - Afternoons & Coffeespoons.mp3 (0 copies)
+ failed
+ git-annex: 1 failed
+ 12:38:40 ~/testannex1 (master)$ git annex whereis 'no ampersand.mp3'
+ whereis no ampersand.mp3 (1 copy)
+ a7b680fc-a8d0-11e0-b0fe-4f94e86d1fb7 -- testannex1 <-- here
+ ok
+
+[[!tag done]]
diff --git a/doc/bugs/git_annex_upgrade_loses_track_of_files_with___34____38____34___character___40__and_probably_others__41__/comment_1_861506e40e0d04d2be98bbfe9188be89._comment b/doc/bugs/git_annex_upgrade_loses_track_of_files_with___34____38____34___character___40__and_probably_others__41__/comment_1_861506e40e0d04d2be98bbfe9188be89._comment
new file mode 100644
index 000000000..194b36ac1
--- /dev/null
+++ b/doc/bugs/git_annex_upgrade_loses_track_of_files_with___34____38____34___character___40__and_probably_others__41__/comment_1_861506e40e0d04d2be98bbfe9188be89._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-07-07T21:04:23Z"
+ content="""
+What an evil little bug. In retrospect, this probably bit my own test upgrades, but I ran `git annex fsck` everywhere and so avoided the location log breakage.
+
+I've fixed the bug, which also involved files with other punctuation in their names [&:%] when using the WORM backend.
+
+The only way I have to recover repos that have already been upgraded is to run `git annex fsck --fast` in each clone of such a repo, which will let it rebuild the location log information. I think that is the best way to recover; ie I can't think of a way to recover that doesn't need to do everything fsck does anyway.
+"""]]
diff --git a/doc/bugs/git_annex_upgrade_output_is_inconsistent_and_spammy.mdwn b/doc/bugs/git_annex_upgrade_output_is_inconsistent_and_spammy.mdwn
new file mode 100644
index 000000000..ec8a10915
--- /dev/null
+++ b/doc/bugs/git_annex_upgrade_output_is_inconsistent_and_spammy.mdwn
@@ -0,0 +1,15 @@
+Upgrading from v1 to v3:
+
+ upgrade . (v1 to v2...) (moving content...) (updating symlinks...) (moving location logs...) (v2 to v3...) ..............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
+ git-annex branch created
+ Be sure to push this branch when pushing to remotes.
+ ok
+
+A whirly would be preferable, imo.
+
+> Erm, I'm pretty sure you were the one who asked for there to be some
+> progress dots, Richard.
+>
+> I'm not particularly interested in implementing a whirley that would only
+> be used in this one place, in code that very few users are going to run
+> again. I could remove the dots.. [[done]] --[[Joey]]
diff --git a/doc/bugs/git_annex_upgrade_output_is_inconsistent_and_spammy/comment_1_3a01c81efba321b0e46d1bc0426ad8d1._comment b/doc/bugs/git_annex_upgrade_output_is_inconsistent_and_spammy/comment_1_3a01c81efba321b0e46d1bc0426ad8d1._comment
new file mode 100644
index 000000000..4f9565517
--- /dev/null
+++ b/doc/bugs/git_annex_upgrade_output_is_inconsistent_and_spammy/comment_1_3a01c81efba321b0e46d1bc0426ad8d1._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 1"
+ date="2011-10-29T17:03:26Z"
+ content="""
+I could dig it out, but I am sure I said dots are fine and a whirly better.
+
+Still, WONTFIX is fine.
+"""]]
diff --git a/doc/bugs/git_annex_version_should_without_being_in_a_repo_.mdwn b/doc/bugs/git_annex_version_should_without_being_in_a_repo_.mdwn
new file mode 100644
index 000000000..5c995852b
--- /dev/null
+++ b/doc/bugs/git_annex_version_should_without_being_in_a_repo_.mdwn
@@ -0,0 +1,7 @@
+was checking the version of git-annex on a machine before cloning a repo...
+
+ $ git annex version
+ git-annex: Not in a git repository.
+
+> made difficult by the Annex monad, but I made it work! --[[Joey]]
+> [[done]]
diff --git a/doc/bugs/git_annex_version_should_without_being_in_a_repo_/comment_1_e7b26eeb1a765fd83280ef907c0deef2._comment b/doc/bugs/git_annex_version_should_without_being_in_a_repo_/comment_1_e7b26eeb1a765fd83280ef907c0deef2._comment
new file mode 100644
index 000000000..ab30d8a45
--- /dev/null
+++ b/doc/bugs/git_annex_version_should_without_being_in_a_repo_/comment_1_e7b26eeb1a765fd83280ef907c0deef2._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="comment 1"
+ date="2011-11-16T03:24:30Z"
+ content="""
+oh, and that probably goes for 'help' and other subcommands as well.
+"""]]
diff --git a/doc/bugs/git_annex_webapp_--listen_on_a_remote_linux_server.mdwn b/doc/bugs/git_annex_webapp_--listen_on_a_remote_linux_server.mdwn
new file mode 100644
index 000000000..f40fabd74
--- /dev/null
+++ b/doc/bugs/git_annex_webapp_--listen_on_a_remote_linux_server.mdwn
@@ -0,0 +1,50 @@
+### Please describe the problem.
+
+webapp needs to be killed and restarted to finish setting up a new repository
+
+### What steps will reproduce the problem?
+
+I run on a remote linux server
+
+git annex webapp --listen=10.222.0.1:4000
+
+I get a url printed
+
+click the url, it opens in my browser
+click make a repository, and it doesn't finish loading the web page
+if I ctrl-c git on the remote server and start it up again, click
+the url again, i can continue to set up the new repository
+
+
+### What version of git-annex are you using? On what operating system?
+
+git-annex version: 4.20130709
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP
+
+debian wheezy with git-annex pinned from sid
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+[2013-07-19 08:09:54 EST] main: starting assistant version 4.20130709
+WebApp crashed: unable to bind to local socket
+[2013-07-19 08:09:54 EST] WebApp: warning WebApp crashed: unable to bind to local socket
+
+ dbus failed; falling back to mtab polling (ClientError {clientErrorMessage = "runClient: unable to determine DBUS address", clientErrorFatal = True})
+
+ No known network monitor available through dbus; falling back to polling
+(scanning...) [2013-07-19 08:09:54 EST] Watcher: Performing startup scan
+(started...) Merge made by the 'recursive' strategy.
+ ...book.azw | 1 +
+ 1 file changed, 1 insertion(+)
+ create mode 120000 Books/book.azw
+[2013-07-19 08:13:03 EST] Committer: Committing changes to git
+
+
+# End of transcript or log.
+"""]]
+
+> Duplicate; [[closed|done]]. --[[Joey]]
diff --git a/doc/bugs/git_annex_webapp_--listen_on_a_remote_linux_server/comment_1_db99c00830d3f15ebe790c4dc8b60bd7._comment b/doc/bugs/git_annex_webapp_--listen_on_a_remote_linux_server/comment_1_db99c00830d3f15ebe790c4dc8b60bd7._comment
new file mode 100644
index 000000000..11c4c181b
--- /dev/null
+++ b/doc/bugs/git_annex_webapp_--listen_on_a_remote_linux_server/comment_1_db99c00830d3f15ebe790c4dc8b60bd7._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.140"
+ subject="comment 1"
+ date="2013-07-20T19:57:05Z"
+ content="""
+This is a known problem with using --listen with a forced port number. See [[Hangs_on_creating_repository_when_using_--listen]]
+"""]]
diff --git a/doc/bugs/git_annex_webapp_runs_on_wine.mdwn b/doc/bugs/git_annex_webapp_runs_on_wine.mdwn
new file mode 100644
index 000000000..c430239eb
--- /dev/null
+++ b/doc/bugs/git_annex_webapp_runs_on_wine.mdwn
@@ -0,0 +1,47 @@
+### Please describe the problem.
+I just installed git-annex-20130601 on Gentoo and when running git annex webapp it started to run things on wine.
+
+### What steps will reproduce the problem?
+On Gentoo ~amd64:
+[[!format sh """
+ ~$ layman -a haskell
+ ~$ USE=webapp emerge -1 git-annex
+ ~$ git annex webapp
+"""]]
+### What version of git-annex are you using? On what operating system?
+dev-vcs/git-annex-4.20130601 from https://github.com/gentoo-haskell/gentoo-haskell/tree/master/dev-vcs/git-annex
+
+On Gentoo ~amd64
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+~$ git annex webapp
+Launching web browser on file:///tmp/webapp14071.html
+libpng warning: Application built with libpng-1.6.2 but running with 1.5.13
+err:menubuilder:convert_to_native_icon error 0x80004005 initializing encoder
+libpng warning: Application built with libpng-1.6.2 but running with 1.5.13
+err:menubuilder:convert_to_native_icon error 0x80004005 initializing encoder
+libpng warning: Application built with libpng-1.6.2 but running with 1.5.13
+err:menubuilder:convert_to_native_icon error 0x80004005 initializing encoder
+...
+fixme:exec:SHELL_execute flags ignored: 0x00000100
+fixme:exec:SHELL_execute flags ignored: 0x00000100
+fixme:exec:SHELL_execute flags ignored: 0x00000100
+...
+
+22185 me 20 0 2580M 10196 8156 S 0.0 0.1 0:00.09 ├─ start /ProgIDOpen htmlfile /home/reinis/.wine/dosdevices/z:/tmp/webapp2554.html
+ 2597 me 21 1 2596M 10984 8764 S 0.0 0.1 0:01.23 ├─ c:\windows\system32\explorer.exe /desktop
+ 2589 me 20 0 2581M 2344 1932 S 0.0 0.0 0:00.00 ├─ c:\windows\system32\plugplay.exe
+ 2581 me 20 0 2593M 8900 7500 S 0.0 0.1 0:00.09 ├─ c:\windows\system32\winedevice.exe MountMgr
+ 2577 me 20 0 2583M 2776 2272 S 0.0 0.0 0:00.00 ├─ c:\windows\system32\services.exe
+ 2571 me 20 0 24960 7532 772 S 46.1 0.1 2:29.06 ├─ /usr/bin/wineserver
+
+# End of transcript or log.
+"""]]
+
+> [[done]]; this is a misconfigured system, not a git-annex bug,
+> and git-annex honors git config web.browser to allow working around
+> this. --[[Joey]]
diff --git a/doc/bugs/git_annex_webapp_runs_on_wine/comment_1_c71dfa42780c0fc78f88ce054e5f3ee3._comment b/doc/bugs/git_annex_webapp_runs_on_wine/comment_1_c71dfa42780c0fc78f88ce054e5f3ee3._comment
new file mode 100644
index 000000000..e94df5783
--- /dev/null
+++ b/doc/bugs/git_annex_webapp_runs_on_wine/comment_1_c71dfa42780c0fc78f88ce054e5f3ee3._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-06-14T18:10:11Z"
+ content="""
+I've had one other user report having this problem. It seems that wine installs some sort of .desktop file claiming it is the One True program to use to open urls. Since git-annex uses the `xdg-open` command, and in some desktop environments that command trusts these .desktop files to be accurate and not nonsensical. So it goes ahead and opens MSIE or whatever.
+
+Happily, git has a configuration setting that you can use to tell it exactly which web browser you want, bypassing all the xdg-open nonsense:
+
+git config web.browser w3m
+
+git-annex honors this configuration setting.
+
+You may also want to investigate the .desktop file that wine has installed on your system, and file appropriate bugs with either your distribution or wine package distributor to get that fixed. It seems that it would affect any program using xdg-open, not only git-annex.
+"""]]
diff --git a/doc/bugs/git_annex_webapp_runs_on_wine/comment_2_f28441b18b0be90c1e58348455ce09d9._comment b/doc/bugs/git_annex_webapp_runs_on_wine/comment_2_f28441b18b0be90c1e58348455ce09d9._comment
new file mode 100644
index 000000000..9853705b3
--- /dev/null
+++ b/doc/bugs/git_annex_webapp_runs_on_wine/comment_2_f28441b18b0be90c1e58348455ce09d9._comment
@@ -0,0 +1,23 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm01ida6POv7vqyUYtOlymEbJTbrImAIzM"
+ nickname="Reinis"
+ subject="comment 2"
+ date="2013-06-14T18:49:06Z"
+ content="""
+Thanks! It looks like it is a xdg issue, I can reproduce it by running xdg-open manually.
+
+Faulty file is:
+[[!format sh \"\"\"
+~$ grep -ri htmlfile .local/share/applications/
+.local/share/applications/wine-extension-htm.desktop
+~$ rm .local/share/applications/wine-extension-*
+~$ locate .desktop | parallel grep -ri htmlfile {}
+\"\"\"]]
+
+Then it tried to open with /usr/bin/emacsclient! In Gnome setting Firefox is listed as default browser, but xdg-settings thinks that it is Epiphany, what a mess..
+
+Anyways, this fixes it:
+[[!format sh \"\"\"
+~$ xdg-settings set default-web-browser firefox.desktop
+\"\"\"]]
+"""]]
diff --git a/doc/bugs/git_annex_won__39__t_copy_files_to_my_usb_drive.mdwn b/doc/bugs/git_annex_won__39__t_copy_files_to_my_usb_drive.mdwn
new file mode 100644
index 000000000..6e1c00781
--- /dev/null
+++ b/doc/bugs/git_annex_won__39__t_copy_files_to_my_usb_drive.mdwn
@@ -0,0 +1,60 @@
+One of my remotes, on a USB drive, is behaving exceedingly strangely. Files sometimes refuse to copy to it - whether I copy to it from my home annex, or whether I "cd" to that USB drive and try to "get" files to it.
+
+Note that the external HD is a FAT32 filesystem. This has never caused problems in the past, but I am wondering if some of the recent work on "crippled" filesystems might have caused breakage on existing repositories which had been working well on FAT32 filesystems?
+
+What steps will reproduce the problem?
+
+On my annex, something like this:
+
+<pre>
+Talislanta Books$ git annex whereis talislanta_fantasy_roleplaying.pdf
+whereis talislanta_fantasy_roleplaying.pdf (2 copies)
+ d16d0d1a-3cdd-11e2-9161-67c83599f720 -- homeworld
+ fa2bd02e-3ce2-11e2-a675-47389975a32e -- here (macbook)
+ok
+Talislanta Books$ git annex copy --to=toshiba talislanta_fantasy_roleplaying.pdf
+copy talislanta_fantasy_roleplaying.pdf ok
+Talislanta Books$ git annex whereis talislanta_fantasy_roleplaying.pdf
+whereis talislanta_fantasy_roleplaying.pdf (2 copies)
+ d16d0d1a-3cdd-11e2-9161-67c83599f720 -- homeworld
+ fa2bd02e-3ce2-11e2-a675-47389975a32e -- here (macbook)
+ok
+Talislanta Books$ cd /Volumes/TOSHIBAEXT/annex/Books/archive/Talislanta\ Books/
+Talislanta Books$ git annex whereis talislanta_fantasy_roleplaying.pdf
+whereis talislanta_fantasy_roleplaying.pdf (2 copies)
+ d16d0d1a-3cdd-11e2-9161-67c83599f720 -- homeworld
+ fa2bd02e-3ce2-11e2-a675-47389975a32e -- macbook
+ok
+Talislanta Books$ git annex get talislanta_fantasy_roleplaying.pdf
+Talislanta Books$ git annex whereis talislanta_fantasy_roleplaying.pdf
+whereis talislanta_fantasy_roleplaying.pdf (2 copies)
+ d16d0d1a-3cdd-11e2-9161-67c83599f720 -- homeworld
+ fa2bd02e-3ce2-11e2-a675-47389975a32e -- macbook
+ok
+Talislanta Books$
+</pre>
+
+
+What is the expected output? What do you see instead?
+
+I should be able to copy files to my external hard drive, /Volumes/TOSHIBAEXT/annex
+
+
+What version of git-annex are you using? On what operating system?
+
+<pre>
+Talislanta Books$ git annex version
+git-annex version: 3.20130216
+local repository version: 3
+default repository version: 3
+supported repository versions: 3
+upgrade supported from repository versions: 0 1 2
+</pre>
+
+OS X 10.6 (lion)
+
+Please provide any additional information below.
+
+Most files are affected by this, a few are not. I don't see any pattern to which is which.
+
+> Both bugs reported here are now [[done]]. --[[Joey]]
diff --git a/doc/bugs/git_annex_won__39__t_copy_files_to_my_usb_drive/comment_1_7707017fbf3d92ee21d600fe0aefce4f._comment b/doc/bugs/git_annex_won__39__t_copy_files_to_my_usb_drive/comment_1_7707017fbf3d92ee21d600fe0aefce4f._comment
new file mode 100644
index 000000000..2f157417f
--- /dev/null
+++ b/doc/bugs/git_annex_won__39__t_copy_files_to_my_usb_drive/comment_1_7707017fbf3d92ee21d600fe0aefce4f._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="99.54.57.201"
+ subject="comment 1"
+ date="2013-02-25T06:18:58Z"
+ content="""
+Just tried downgrading to 3.20130207 and the behavior is the same. :(
+
+
+"""]]
diff --git a/doc/bugs/git_annex_won__39__t_copy_files_to_my_usb_drive/comment_2_f3392ec3ca7392823cbad2cc9b77f54e._comment b/doc/bugs/git_annex_won__39__t_copy_files_to_my_usb_drive/comment_2_f3392ec3ca7392823cbad2cc9b77f54e._comment
new file mode 100644
index 000000000..17379f354
--- /dev/null
+++ b/doc/bugs/git_annex_won__39__t_copy_files_to_my_usb_drive/comment_2_f3392ec3ca7392823cbad2cc9b77f54e._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="99.54.57.201"
+ subject="comment 2"
+ date="2013-02-25T12:44:18Z"
+ content="""
+Update: git annex fsck --fast --from=toshiba fixed this. Guess I was up too late to think about the obvious. Sorry bout that.
+
+"""]]
diff --git a/doc/bugs/git_annex_won__39__t_copy_files_to_my_usb_drive/comment_3_b3d016a487b12748fe2c4d14300eb158._comment b/doc/bugs/git_annex_won__39__t_copy_files_to_my_usb_drive/comment_3_b3d016a487b12748fe2c4d14300eb158._comment
new file mode 100644
index 000000000..f891af92e
--- /dev/null
+++ b/doc/bugs/git_annex_won__39__t_copy_files_to_my_usb_drive/comment_3_b3d016a487b12748fe2c4d14300eb158._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="99.54.57.201"
+ subject="comment 3"
+ date="2013-02-25T14:24:29Z"
+ content="""
+This is still weird though.
+
+Setup: I have my home drive, an ssh remote, and a usb remote.
+
+Home drive is a \"client\" and the other two are \"backups.\" numcopies = 2.
+
+WHen I start the assistant and watch it in the webapp, it starts furiously copying content in \"archive\" subdirectories from the USB remote to the home drive, and then dropping it from the USB remote!
+
+I then kill the assistant because I do not want content dropped from my backup, that's why it's a backup.
+
+Is there any way to tell *why* the assistant is doing this crazy thing?
+
+
+"""]]
diff --git a/doc/bugs/git_annex_won__39__t_copy_files_to_my_usb_drive/comment_4_61f600511a3172f0707e5809fc444d0c._comment b/doc/bugs/git_annex_won__39__t_copy_files_to_my_usb_drive/comment_4_61f600511a3172f0707e5809fc444d0c._comment
new file mode 100644
index 000000000..c8b6788f3
--- /dev/null
+++ b/doc/bugs/git_annex_won__39__t_copy_files_to_my_usb_drive/comment_4_61f600511a3172f0707e5809fc444d0c._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="99.54.57.201"
+ subject="comment 4"
+ date="2013-02-25T14:57:20Z"
+ content="""
+Yeah, the assistant wants to drop *everything* on my USB drive. When I vicfg I see that the usb drive repo is \"untrusted/backup/standard\". Why in the world would the assistant want to drop everything on it?
+
+"""]]
diff --git a/doc/bugs/git_annex_won__39__t_copy_files_to_my_usb_drive/comment_5_8cf029ac7bf3c19dcb0b613eed3b52ac._comment b/doc/bugs/git_annex_won__39__t_copy_files_to_my_usb_drive/comment_5_8cf029ac7bf3c19dcb0b613eed3b52ac._comment
new file mode 100644
index 000000000..2c133e8d0
--- /dev/null
+++ b/doc/bugs/git_annex_won__39__t_copy_files_to_my_usb_drive/comment_5_8cf029ac7bf3c19dcb0b613eed3b52ac._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="99.54.57.201"
+ subject="comment 5"
+ date="2013-02-25T16:02:44Z"
+ content="""
+Downgrading to 3.20130207 and testing.... this seems to have been a regression since 3.20130207. 3.20130207 seems right now to be behaving normally, not trying to drop things it shouldn't. Is it possible something went terribly wrong with preferred content settings since 3.20130207?
+
+Still testing, but things look good so far.
+"""]]
diff --git a/doc/bugs/git_annex_won__39__t_copy_files_to_my_usb_drive/comment_6_e40d88eba7d8aec1530ce1d32d1c85f2._comment b/doc/bugs/git_annex_won__39__t_copy_files_to_my_usb_drive/comment_6_e40d88eba7d8aec1530ce1d32d1c85f2._comment
new file mode 100644
index 000000000..830a1c631
--- /dev/null
+++ b/doc/bugs/git_annex_won__39__t_copy_files_to_my_usb_drive/comment_6_e40d88eba7d8aec1530ce1d32d1c85f2._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.210"
+ subject="comment 6"
+ date="2013-02-26T17:20:13Z"
+ content="""
+The recent switch to using the Glob library seems to be responsible for this problem. It seems that
+with Glob, \"\*\" matches \"foo\", but not \"directory/foo\", so the \"\*\" in preferred content for backup repositories matches only files in the top directory!
+
+Writing test cases and fixing this now.
+"""]]
diff --git a/doc/bugs/git_annex_won__39__t_copy_files_to_my_usb_drive/comment_7_b101fab9e690d1b335a1a29abab68d6c._comment b/doc/bugs/git_annex_won__39__t_copy_files_to_my_usb_drive/comment_7_b101fab9e690d1b335a1a29abab68d6c._comment
new file mode 100644
index 000000000..178b62fa7
--- /dev/null
+++ b/doc/bugs/git_annex_won__39__t_copy_files_to_my_usb_drive/comment_7_b101fab9e690d1b335a1a29abab68d6c._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.210"
+ subject="comment 7"
+ date="2013-02-26T18:41:57Z"
+ content="""
+Getting back to the original problem, it seemed to be that the remote already had the files, but the local location log was not aware of this. Perhaps because the remote got the files from somewhere else and `git annex sync` or similar had not been run to get that into into the local repo recently? Anyway, copying files to the remote was correctly detected to be unnecessary.
+
+Currently, when that happens, it does not update the local location log. That is a change made fairly recently, in 40df26757a61d4f057bcbf38cd5fe949d1c9be95, as a kind of optimisation -- I'd seen it updating the location log during mass copies when it didn't need to, which just bloats `.git`. Seems that optimisation went too far: It should avoid updating the location log when it was correct, but if the location log is wrong, it should optimistically update it.
+"""]]
diff --git a/doc/bugs/git_annex_won__39__t_copy_files_to_my_usb_drive/comment_8_b30d32086314a7e357f3dd6608828ee5._comment b/doc/bugs/git_annex_won__39__t_copy_files_to_my_usb_drive/comment_8_b30d32086314a7e357f3dd6608828ee5._comment
new file mode 100644
index 000000000..32a801224
--- /dev/null
+++ b/doc/bugs/git_annex_won__39__t_copy_files_to_my_usb_drive/comment_8_b30d32086314a7e357f3dd6608828ee5._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 8"
+ date="2013-02-26T21:55:23Z"
+ content="""
+Cool, glad this led to an important fix, even if it turned out to be unrelated to the thing I opened the bug report for.
+
+"""]]
diff --git a/doc/bugs/git_annix_breaks_git_commit_after_uninstall.mdwn b/doc/bugs/git_annix_breaks_git_commit_after_uninstall.mdwn
new file mode 100644
index 000000000..a6fdab0fe
--- /dev/null
+++ b/doc/bugs/git_annix_breaks_git_commit_after_uninstall.mdwn
@@ -0,0 +1,42 @@
+Sorry to be reporting another vague bug, this one interferes with my work unfortunately.
+
+### Please describe the problem.
+After uninstalling git-annix, running git commit returns the following error:
+
+git: 'annex' is not a git command. See 'git --help'.
+
+### What steps will reproduce the problem?
+
+Install git-annex using the ubuntu ppa of fmarcier like so:
+
+ sudo apt-get install git-annex
+
+Then remove it:
+
+ sudo apt-get remove git-annex
+
+Then go to work in a git project, that is not in annex and has no relation to it. Add your changes and run commit:
+
+ git add my-new-file
+ git commit -m "added new file"
+
+I expect it to confirm the file is committed, instead I get the error message:
+
+ git: 'annex' is not a git command. See 'git --help'.
+
+### What version of git-annex are you using? On what operating system?
+
+Ubuntu 13.04, using the PPA by marcier linked on the branchable website.
+
+> I don't think this is something I want to change.. `git-annex init`
+> installs a pre-commit hook that runs `git annex fix`. If git-annex
+> is removed that hook is left behind to fail. However, if you were really
+> using git-annex in the repo, that's the least of your troubles. If you were
+> using git-annex in the repo and stopped, then you should run `git annex uninit` to remove the hook.
+>
+> The only change I could make is to have the hook check if git-annex
+> is in PATH before trying to run it. But this adds time and complexity
+> to the usual case for a edge case. And keeps cruft around in the edge case
+> rather than informing you of the problem.
+>
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/git_annix_breaks_git_commit_after_uninstall/comment_1_c8b1bab40d3bb2468a5bba7b116e854e._comment b/doc/bugs/git_annix_breaks_git_commit_after_uninstall/comment_1_c8b1bab40d3bb2468a5bba7b116e854e._comment
new file mode 100644
index 000000000..1494a876f
--- /dev/null
+++ b/doc/bugs/git_annix_breaks_git_commit_after_uninstall/comment_1_c8b1bab40d3bb2468a5bba7b116e854e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://me.tinco.nl/"
+ nickname="Tinco"
+ subject="comment 1"
+ date="2013-05-19T15:35:27Z"
+ content="""
+I'm sorry, there seems to be an annex directory in the .git of that repository.. apparently I have accidentily made it an annex repository. I'm going to find out how to remove it now :)
+"""]]
diff --git a/doc/bugs/git_annix_breaks_git_commit_after_uninstall/comment_2_4173770375fca51dcaf9b974296d041a._comment b/doc/bugs/git_annix_breaks_git_commit_after_uninstall/comment_2_4173770375fca51dcaf9b974296d041a._comment
new file mode 100644
index 000000000..a354c5516
--- /dev/null
+++ b/doc/bugs/git_annix_breaks_git_commit_after_uninstall/comment_2_4173770375fca51dcaf9b974296d041a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://me.tinco.nl/"
+ nickname="Tinco"
+ subject="comment 2"
+ date="2013-05-19T15:37:23Z"
+ content="""
+Alright, found there's a pre-commit hook that performed a git annex task. I removed it and now it all works again.
+"""]]
diff --git a/doc/bugs/git_command_line_constructed_by_unannex_command_has_tons_of_redundant_-a_paramters.mdwn b/doc/bugs/git_command_line_constructed_by_unannex_command_has_tons_of_redundant_-a_paramters.mdwn
new file mode 100644
index 000000000..181b02b5c
--- /dev/null
+++ b/doc/bugs/git_command_line_constructed_by_unannex_command_has_tons_of_redundant_-a_paramters.mdwn
@@ -0,0 +1,15 @@
+This doesn't look right:
+
+ simons 11148 0.0 0.0 15572 1268 pts/1 SN+ 04:00 0:00 | \_ git annex unannex stuff
+ simons 11150 0.5 0.0 130504 11212 pts/1 SN+ 04:00 3:40 | | \_ git-annex unannex stuff
+ simons 11152 0.0 0.1 39536 23932 pts/1 SN+ 04:00 0:00 | | \_ git --git-dir=/home/simons/annex/.git --work-tree=/home/simons/annex ls-files --cached -z -- stuff
+ simons 11288 0.0 0.0 0 0 pts/1 ZN+ 04:01 0:00 | | \_ [git] <defunct>
+ simons 11339 0.0 0.0 0 0 pts/1 ZN+ 04:02 0:00 | | \_ [git-annex] <defunct>
+ simons 11442 0.0 0.0 0 0 pts/1 ZN+ 04:06 0:00 | | \_ [git] <defunct>
+ simons 11443 0.0 0.0 0 0 pts/1 ZN+ 04:06 0:05 | | \_ [git] <defunct>
+ simons 16541 0.0 0.0 0 0 pts/1 ZN+ 04:14 0:00 | | \_ [git] <defunct>
+ simons 16543 0.3 0.0 15644 1744 pts/1 SN+ 04:14 2:13 | | \_ git --git-dir=/home/simons/annex/.git --work-tree=/home/simons/annex cat-file --batch
+ simons 14224 0.0 0.0 100744 796 pts/1 SN+ 14:10 0:00 | | \_ xargs -0 git --git-dir=/home/simons/annex/.git --work-tree=/home/simons/annex commit -a -m content removed from git annex
+ simons 14225 0.4 0.1 32684 18652 pts/1 DN+ 14:10 0:00 | | \_ git --git-dir=/home/simons/annex/.git --work-tree=/home/simons/annex commit -a -m content removed from git annex -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a -a
+
+> [[Fixed|done]] --[[Joey]]
diff --git a/doc/bugs/git_defunct_processes___40__child_of_git-annex_assistant__41__.mdwn b/doc/bugs/git_defunct_processes___40__child_of_git-annex_assistant__41__.mdwn
new file mode 100644
index 000000000..14eb3b329
--- /dev/null
+++ b/doc/bugs/git_defunct_processes___40__child_of_git-annex_assistant__41__.mdwn
@@ -0,0 +1,34 @@
+What steps will reproduce the problem?
+
+run git annex assistant, add a file, which is picked up and pushed by the assistant.
+
+What is the expected output? What do you see instead?
+
+a ps -ef shows a large number of defunct git processes.. for example:
+<pre>
+nelg 9622 1 0 02:01 ? 00:00:01 git-annex assistant
+nelg 9637 9622 0 02:01 ? 00:00:00 git --git-dir=/home/nelg/Downloads/test2/.git --work-tree=/home/nelg/Downloads/test2 cat-file --batch
+nelg 12080 9622 0 02:19 ? 00:00:00 [git] &lt;defunct&gt;
+nelg 12082 9622 0 02:19 ? 00:00:00 [git] &lt;defunct&gt;
+nelg 12083 9622 0 02:19 ? 00:00:00 [git] &lt;defunct&gt;
+nelg 12084 9622 0 02:19 ? 00:00:00 [git] &lt;defunct&gt;
+-----
+</pre>
+
+What version of git-annex are you using? On what operating system?
+
+Compiled git annex from git (cbcd208d158f8e42dda03a5eeaf1bac21045a140), on Mandriva 2010.2, 32 bit, using ghc-7.4.1.
+ git version 1.7.1
+
+
+Please provide any additional information below.
+
+I also found that the version of git I have does not support the option: --allow-empty-message
+So, suggest that if the version of git installed is an older version, that the params in Assistant/Threads/Committer.hs
+are changed to [ Param "-m", Param "git assistant".... or something like that.
+
+I have done this on my copy for testing it.
+
+For testing, I am also using two repositories on the same computer. I set this up from the command line, as the web app does not seem to support syncing to two different git folders on the same computer.
+
+> [[done]]; all zombies are squelched now in the assistant. --[[Joey]]
diff --git a/doc/bugs/git_defunct_processes___40__child_of_git-annex_assistant__41__/comment_1_5e3f4b63db5cd32b63fb3e6a78f9b093._comment b/doc/bugs/git_defunct_processes___40__child_of_git-annex_assistant__41__/comment_1_5e3f4b63db5cd32b63fb3e6a78f9b093._comment
new file mode 100644
index 000000000..f70cdd1bd
--- /dev/null
+++ b/doc/bugs/git_defunct_processes___40__child_of_git-annex_assistant__41__/comment_1_5e3f4b63db5cd32b63fb3e6a78f9b093._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.2.84"
+ subject="comment 1"
+ date="2012-09-19T17:02:47Z"
+ content="""
+Thanks for the note about --allow-empty-message. That appeared in 1.7.2, I've added a fallback for the old version.
+
+As far as I know, the assistant always reaps old children eventually, but it does it somewhat lazily. Effectively each time it starts up a new set of git children it reaps the old set. So you should not see them grow without bounds or anything like that.
+"""]]
diff --git a/doc/bugs/git_rename_detection_on_file_move.mdwn b/doc/bugs/git_rename_detection_on_file_move.mdwn
new file mode 100644
index 000000000..76f1e098e
--- /dev/null
+++ b/doc/bugs/git_rename_detection_on_file_move.mdwn
@@ -0,0 +1,13 @@
+It's unfortunate that git-annex sorta defeats git's rename detection.
+
+When an annexed file is moved to a different directory (specifically, a
+directory that is shallower or deeper than the old directory),
+the symlink often has to change. And so git log cannot --follow back
+through the rename history, since all it has to go on is that symlink,
+which it effectively sees as a one line file containing the symlink target.
+
+One way to fix this might be to do the `git annex fix` *after* the rename
+is committed. This would mean that a commit would result in new staged
+changes for another commit, which is perhaps startling behavior.
+
+The other way to fix it is to stop using symlinks, see [[todo/smudge]].
diff --git a/doc/bugs/git_rename_detection_on_file_move/comment_10_5ec2f965c80cc5dd31ee3c4edb695664._comment b/doc/bugs/git_rename_detection_on_file_move/comment_10_5ec2f965c80cc5dd31ee3c4edb695664._comment
new file mode 100644
index 000000000..6ea267728
--- /dev/null
+++ b/doc/bugs/git_rename_detection_on_file_move/comment_10_5ec2f965c80cc5dd31ee3c4edb695664._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnpdM9F8VbtQ_H5PaPMpGSxPe_d5L1eJ6w"
+ nickname="Rafael"
+ subject="comment 10"
+ date="2012-05-15T07:36:25Z"
+ content="""
+Won't git itself be fixed on this issue? It was on my plans to look into that, however I don't know how difficult it will be.
+"""]]
diff --git a/doc/bugs/git_rename_detection_on_file_move/comment_1_0531dcfa833b0321a7009526efe3df33._comment b/doc/bugs/git_rename_detection_on_file_move/comment_1_0531dcfa833b0321a7009526efe3df33._comment
new file mode 100644
index 000000000..8fec6bad7
--- /dev/null
+++ b/doc/bugs/git_rename_detection_on_file_move/comment_1_0531dcfa833b0321a7009526efe3df33._comment
@@ -0,0 +1,26 @@
+[[!comment format=mdwn
+ username="http://christian.amsuess.com/chrysn"
+ nickname="chrysn"
+ subject="use mini-branches"
+ date="2011-03-09T23:47:48Z"
+ content="""
+if you go for the two-commits version, small intermediate branches (or git-commit-tree) could be used to create a tree like this:
+
+
+ * commit 106eef2
+ |\ Merge: 436e46f 9395665
+ | |
+ | | the main commit
+ | |
+ | * commit 9395665
+ |/
+ | intermediate move
+ |
+ * commit 436e46f
+ |
+ | ...
+
+while the first commit (436e46f) has a \"`/subdir/foo → ../.git-annex/where_foo_is`\", the intermediate (9395665) has \"`/subdir/deeper/foo → ../.git-annex/where_foo_is`\", and the inal commit (106eef2) has \"`/subdir/deeper/foo → ../../.git-annex/where_foo_is`\".
+
+`--follow` uses the intermediate commit to find the history, but the intermediate commit would neither show up in `git log --first-parent` nor affect `git diff HEAD^..` & co. (there could still be confusion over `git show`, though).
+"""]]
diff --git a/doc/bugs/git_rename_detection_on_file_move/comment_2_7101d07400ad5935f880dc00d89bf90e._comment b/doc/bugs/git_rename_detection_on_file_move/comment_2_7101d07400ad5935f880dc00d89bf90e._comment
new file mode 100644
index 000000000..7d50c58d1
--- /dev/null
+++ b/doc/bugs/git_rename_detection_on_file_move/comment_2_7101d07400ad5935f880dc00d89bf90e._comment
@@ -0,0 +1,27 @@
+[[!comment format=mdwn
+ username="praet"
+ ip="81.240.159.215"
+ subject="Use variable symlinks, relative to the repo's root ?"
+ date="2011-03-10T16:50:28Z"
+ content="""
+It all boils down to the fact that the path to a relative symlink's target is determined relative to the symlink itself.
+
+Now, if we define the symlink's target relative to the git repo's root (eg. using the $GIT_DIR environment variable, which can be a relative or absolute path itself), this unfortunately results in an absolute symlink, which would -for obvious reasons- only be usable locally:
+
+ user@host:~$ mkdir -p tmp/{.git/annex,somefolder}
+ user@host:~$ export GIT_DIR=~/tmp
+ user@host:~$ touch $GIT_DIR/.git/annex/realfile
+ user@host:~$ ln -s $GIT_DIR/.git/annex/realfile $GIT_DIR/somefolder/file
+ user@host:~$ ls -al $GIT_DIR/somefolder/
+ total 12
+ drwxr-x--- 2 user group 4096 2011-03-10 16:54 .
+ drwxr-x--- 4 user group 4096 2011-03-10 16:53 ..
+ lrwxrwxrwx 1 user group 33 2011-03-10 16:54 file -> /home/user/tmp/.git/annex/realfile
+ user@host:~$
+
+So, what we need is the ability to record the actual variable name (instead of it's value) in our symlinks.
+
+It *is* possible, using [variable/variant symlinks](http://en.wikipedia.org/wiki/Symbolic_link#Variable_symbolic_links), yet I'm unsure as to whether or not this is available on Linux systems, and even if it is, it would introduce compatibility issues in multi-OS environments.
+
+Thoughts on this?
+"""]]
diff --git a/doc/bugs/git_rename_detection_on_file_move/comment_3_57010bcaca42089b451ad8659a1e018e._comment b/doc/bugs/git_rename_detection_on_file_move/comment_3_57010bcaca42089b451ad8659a1e018e._comment
new file mode 100644
index 000000000..534723254
--- /dev/null
+++ b/doc/bugs/git_rename_detection_on_file_move/comment_3_57010bcaca42089b451ad8659a1e018e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 3"
+ date="2011-03-16T03:03:19Z"
+ content="""
+Interesting, I had not heard of variable symlinks before. AFAIK linux does not have them.
+"""]]
diff --git a/doc/bugs/git_rename_detection_on_file_move/comment_4_79d96599f757757f34d7b784e6c0e81c._comment b/doc/bugs/git_rename_detection_on_file_move/comment_4_79d96599f757757f34d7b784e6c0e81c._comment
new file mode 100644
index 000000000..c265b5899
--- /dev/null
+++ b/doc/bugs/git_rename_detection_on_file_move/comment_4_79d96599f757757f34d7b784e6c0e81c._comment
@@ -0,0 +1,34 @@
+[[!comment format=mdwn
+ username="praet"
+ ip="81.240.27.89"
+ subject="Brainfart"
+ date="2011-03-20T20:11:27Z"
+ content="""
+Haven't given these any serious thought (which will become apparent in a moment) but hoping they will give birth to some less retarded ideas:
+
+---
+
+### Bait'n'switch
+
+- pre-commit: Replace all staged symlinks (when pointing to annexed files) with plaintext files containing the key of their respective annexed content, re-stage, and add their paths (relative to repo root) to .gitignore.
+- post-commit: Replace the plaintext files with (git annex fix'ed) symlinks.
+
+In doing so, the blobs to be committed can remain unaltered, irrespective of their related files' depth in the directory hierarchy.
+
+To prevent git from reporting ALL annexed files as unstaged changes after running post-commit hook, their paths would need to be added to .gitignore.
+
+This wouldn't cause any issues when adding files, very little when modifying files (would need some alterations to \"git annex unlock\"), BUT would make git totally oblivious to removals...
+
+---
+
+### Manifest-based (re)population
+- Keep a manifest of all annexed files (key + relative path)
+- DON'T track the symlinks (.gitignore)
+- Populate/update the directory structure using a post-commit hook.
+
+... thus circumventing the issue entirely, yet diffstats (et al.) would be rather uninformative.
+
+---
+
+***Wide open to suggestions, criticism, mocking laughter and finger-pointing :)***
+"""]]
diff --git a/doc/bugs/git_rename_detection_on_file_move/comment_5_d61f5693d947b9736b29fca1dbc7ad76._comment b/doc/bugs/git_rename_detection_on_file_move/comment_5_d61f5693d947b9736b29fca1dbc7ad76._comment
new file mode 100644
index 000000000..93db97e70
--- /dev/null
+++ b/doc/bugs/git_rename_detection_on_file_move/comment_5_d61f5693d947b9736b29fca1dbc7ad76._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="praet"
+ ip="81.242.56.203"
+ subject="comment 5"
+ date="2011-03-21T19:58:34Z"
+ content="""
+In the meantime, would it be acceptable to split the pre-commit hook
+into two discrete parts?
+
+This would allow to (if preferred) defer \"git annex fix\" until
+post-commit while still keeping the safety net for unlocked files.
+"""]]
diff --git a/doc/bugs/git_rename_detection_on_file_move/comment_6_f63de6fe2f7189c8c2908cc41c4bc963._comment b/doc/bugs/git_rename_detection_on_file_move/comment_6_f63de6fe2f7189c8c2908cc41c4bc963._comment
new file mode 100644
index 000000000..7398ac561
--- /dev/null
+++ b/doc/bugs/git_rename_detection_on_file_move/comment_6_f63de6fe2f7189c8c2908cc41c4bc963._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="http://adamspiers.myopenid.com/"
+ nickname="Adam"
+ subject="extra level of indirection"
+ date="2011-12-19T12:45:18Z"
+ content="""
+Surely this could be handled with an extra layer of indirection?
+
+git-annex would ensure that every directory containing annexed data contains a new symlink `.git-annex` which points to `$git_root/.git/annex`. Then every symlink to an annexed object uses a relative symlink via this: `.git_annex/objects/xx/yy/ZZZZZZZZZZ`. Even though this symlink is relative, moving it to a different directory would not break anything: if the move destination directory already contained other annexed data, it would also already contain `.git-annex` so git-annex wouldn't need to do anything. And if it didn't, git-annex would simply create a new `.git-annex` symlink there.
+
+These `.git-annex` symlinks could either be added to `.gitignore`, or manually/automatically checked in to the current branch - I'm not sure which would be best. There's also the option of using multiple levels of indirection:
+
+ foo/bar/baz/.git-annex -> ../.git-annex
+ foo/bar/.git-annex -> ../.git-annex
+ foo/.git-annex -> ../.git-annex
+ .git-annex -> .git/annex
+
+I'm not sure whether this would bring any advantages. It might bring a performance hit due to the kernel having to traverse more symlinks, but without benchmarking it's difficult to say how much. I'd expect it only to be an issue with a large number of deep directory trees.
+"""]]
diff --git a/doc/bugs/git_rename_detection_on_file_move/comment_7_7f20d0b2f6ed1c34021a135438037306._comment b/doc/bugs/git_rename_detection_on_file_move/comment_7_7f20d0b2f6ed1c34021a135438037306._comment
new file mode 100644
index 000000000..0a045feb6
--- /dev/null
+++ b/doc/bugs/git_rename_detection_on_file_move/comment_7_7f20d0b2f6ed1c34021a135438037306._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 7"
+ date="2011-12-19T18:22:25Z"
+ content="""
+That seems an excellent idea, also eliminating the need for git annex fix after moving.
+
+However, I think CVS and svn have taught us the pain associated with a version control system putting something in every subdirectory. Would this pain be worth avoiding the minor pain of needing git annex fix and sometimes being unable to follow renames?
+"""]]
diff --git a/doc/bugs/git_rename_detection_on_file_move/comment_8_6a00500b24ba53248c78e1ffc8d1a591._comment b/doc/bugs/git_rename_detection_on_file_move/comment_8_6a00500b24ba53248c78e1ffc8d1a591._comment
new file mode 100644
index 000000000..d53022302
--- /dev/null
+++ b/doc/bugs/git_rename_detection_on_file_move/comment_8_6a00500b24ba53248c78e1ffc8d1a591._comment
@@ -0,0 +1,21 @@
+[[!comment format=mdwn
+ username="http://adamspiers.myopenid.com/"
+ nickname="Adam"
+ subject="comment 8"
+ date="2011-12-20T12:00:11Z"
+ content="""
+Personally I'd rather have working rename detection but I agree it's not 100% ideal to be littering multiple directories like this, so perhaps you could make it optional, e.g. based on a git config setting?
+
+Here are a few more considerations, some in defence of the approach, some against it:
+
+* `.git-annex` is hidden; `CVS/` is not.
+* Unlike `CVS/` and `.svn/`, it's only a symlink, not a directory containing other files.
+* It doesn't contain any data specific to that directory and could easily be regenerated if deleted accidentally or otherwise.
+* If a whole directory containing `.git-annex` was moved within the repository:
+ * git-annex would need to fix up these symlinks if and only if it's moved to a different depth within the tree.
+ * However, if the multi-level indirection approach is used, `.git-annex` in any subdirectory is *always* a symlink to `../.git-annex` so instead you would need to check that all of the new ancestors contain this symlink too, and optionally remove any no longer needed symlinks.
+ * In either case, git-annex already goes to the trouble of fixing symlinks, and if anything, I *think* this approach would reduce the number of symlinks which need checking (right?)
+* find `$git_root/foo -follow`, `diff -r` etc. would traverse into `$git_root/.git/annex`
+
+This last point is the only downside to this approach I can think of which gives me any noticeable cause for concern. However, people are already use to working around this from CVS and svn days, e.g. `diff -r -x .svn` so I don't think it's anywhere near bad enough to rule it out.
+"""]]
diff --git a/doc/bugs/git_rename_detection_on_file_move/comment_9_75e0973f6d573df615e01005ebcea87d._comment b/doc/bugs/git_rename_detection_on_file_move/comment_9_75e0973f6d573df615e01005ebcea87d._comment
new file mode 100644
index 000000000..919455bdc
--- /dev/null
+++ b/doc/bugs/git_rename_detection_on_file_move/comment_9_75e0973f6d573df615e01005ebcea87d._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 9"
+ date="2011-12-20T14:56:12Z"
+ content="""
+Git can follow the rename fine if the file is committed before `git annex fix` (you can git commit -n to see this), so
+making git-annex pre-commit generate a fixup commit before the staged commit would be one way. Or the other two ways I originally mentioned when writing down this minor issue. I like all those approaches better than .git-annex clutter.
+"""]]
diff --git a/doc/bugs/git_version_in_prebuilt_linux_tarball_is_outdated.mdwn b/doc/bugs/git_version_in_prebuilt_linux_tarball_is_outdated.mdwn
new file mode 100644
index 000000000..e5960b62e
--- /dev/null
+++ b/doc/bugs/git_version_in_prebuilt_linux_tarball_is_outdated.mdwn
@@ -0,0 +1,11 @@
+### Please describe the problem.
+I created a .gitignore file and added it to git annex. In the assistant webapp log, the error "The installed version of git is too old for .gitignores to be honored by git-annex." shows up. According to [[bugs/assistant_ignore_.gitignore/]] this bug should be fixed in a later git version.
+
+### What steps will reproduce the problem?
+Download the current prebuilt linux tarball from [[/install]], extract it, run "./runshell", then "git --version" returns "git version 1.7.10.4"
+
+### What version of git-annex are you using? On what operating system?
+git-annex-standalone-amd64.tar.gz 2013-09-22 09:56 (Linux Ubuntu Precise)
+
+> Updated to wheezy backport 1.8.4. [[done]] for now, obviously it will go
+> out of date again eventually.. --[[Joey]]
diff --git a/doc/bugs/git_version_in_prebuilt_linux_tarball_is_outdated/comment_1_2a5a07498df9d38531d4570f7b463b9a._comment b/doc/bugs/git_version_in_prebuilt_linux_tarball_is_outdated/comment_1_2a5a07498df9d38531d4570f7b463b9a._comment
new file mode 100644
index 000000000..5287ea935
--- /dev/null
+++ b/doc/bugs/git_version_in_prebuilt_linux_tarball_is_outdated/comment_1_2a5a07498df9d38531d4570f7b463b9a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.220"
+ subject="comment 1"
+ date="2013-09-25T18:18:49Z"
+ content="""
+The tarballs are built on Debian stable in order to have an old enough libc to work most places. So I am limited to what is available in stable and backports. Once there is a backport available of git, I will use it.
+"""]]
diff --git a/doc/bugs/gitignore_for_DCIM_on_Android_misses_some_files.mdwn b/doc/bugs/gitignore_for_DCIM_on_Android_misses_some_files.mdwn
new file mode 100644
index 000000000..449a99753
--- /dev/null
+++ b/doc/bugs/gitignore_for_DCIM_on_Android_misses_some_files.mdwn
@@ -0,0 +1,17 @@
+### Please describe the problem.
+
+When git-annex assistant on Android setups up the DCIM repo a .gitignore file is dropped into place which ignores .thumbnails/* . Unfortunately this doesn't match .thumbnails/.thumbdata* - I have a 700MB file which matches this pattern.
+
+I suspect that making the pattern in .gitignore just .thumbnails should resolve this.
+
+### What steps will reproduce the problem?
+
+Create a repo
+
+### What version of git-annex are you using? On what operating system?
+
+Nightly build for Android from yesterday (2013-11-16)
+
+### Please provide any additional information below.
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/gitignore_for_DCIM_on_Android_misses_some_files/comment_1_f683ecf93e5a17c5c9c06225dbcce2a9._comment b/doc/bugs/gitignore_for_DCIM_on_Android_misses_some_files/comment_1_f683ecf93e5a17c5c9c06225dbcce2a9._comment
new file mode 100644
index 000000000..b90108bc4
--- /dev/null
+++ b/doc/bugs/gitignore_for_DCIM_on_Android_misses_some_files/comment_1_f683ecf93e5a17c5c9c06225dbcce2a9._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.64"
+ subject="comment 1"
+ date="2013-11-16T22:45:52Z"
+ content="""
+\".thumbnails/*\" in .gitignore makes git ignore dotfiles in the directory in my testing, and according to git's own documentation.
+
+However, it is the case that subdir/.thumbnails/* are not ignored by \".thumbnails/*\", but \".thumbnails\" will indeed ignore .thumbnails directories at any point in the tree. So, I've made the change you suggested.
+
+(I also tested on android, with 1.8.4.1.559 and the assistant was able to honor the .gitignore, and did not add any files from `.thumbnails/`.)
+"""]]
diff --git a/doc/bugs/gix-annex_help_is_homicidal.mdwn b/doc/bugs/gix-annex_help_is_homicidal.mdwn
new file mode 100644
index 000000000..f4a8d7213
--- /dev/null
+++ b/doc/bugs/gix-annex_help_is_homicidal.mdwn
@@ -0,0 +1,23 @@
+> What steps will reproduce the problem?
+
+Run 'git-annex help'
+
+> What is the expected output?
+
+Something similar to 'git-annex --help', or a pointer to --help.
+
+> What do you see instead?
+
+ git-annex: Unknown command 'help'
+ Did you mean one of these?
+ drop
+ dead
+
+> What version of git-annex are you using? On what operating system?
+
+git-annex version 3.20120825 on Arch Linux x86_64, installed from AUR package git-annex and using the [haskell] repository for dependencies.
+
+>> Lol, that's great! Also worth noting that with help.autocorrect=1, it'd
+>> actually run drop. Only with --force can you lose data however.
+>>
+>> I've added a help command. [[done]] --[[Joey]]
diff --git a/doc/bugs/glacier_from_multiple_repos.mdwn b/doc/bugs/glacier_from_multiple_repos.mdwn
new file mode 100644
index 000000000..f6ef2a4ac
--- /dev/null
+++ b/doc/bugs/glacier_from_multiple_repos.mdwn
@@ -0,0 +1,14 @@
+glacier-cli currently relies on a local cache of
+inventory information, and so other git-annexes using the same glacier
+repository are not able to access stuff in it, unless and until
+`glacier vault sync` is run.
+
+An example of this causing trouble is with the assistant. When a file is
+moved into archive/, the assistant that sends it to glacier is able to
+trust that it's in glacier and remove the local copy. But other assistants
+that also have a copy cannot trust that, and so don't remove their copies.
+
+I've discussed with glacier-cli's author making git-annex store enough info
+in its branch to be able to bootstrap glacier-cli to know about a file.
+This seems doable and he had a design; waiting on movement
+on the glacier-cli side.
diff --git a/doc/bugs/googlemail.mdwn b/doc/bugs/googlemail.mdwn
new file mode 100644
index 000000000..0995a9729
--- /dev/null
+++ b/doc/bugs/googlemail.mdwn
@@ -0,0 +1,16 @@
+### Please describe the problem.
+Git-Annex crashes when configuring jabber account with foo.bar@googlemail.com
+
+### What steps will reproduce the problem?
+Configure the Jabber Account with foo.bar@googlemail.com instead of foo.bar@gmail.com. The domain googlemail was used for a long time in germany because of a license issue.
+
+### What version of git-annex are you using? On what operating system?
+Mac OS X - 10.8.3 Mountain Lion
+
+Version: 4.20130709-g18e5f43
+
+Build flags: Assistant Webapp Pairing Testsuite S3 WebDAV FsEvents XMPP DNS
+
+
+[[!meta title="xmpp fails to work with googlemail domain"]]
+[[!tag design/assistant]]
diff --git a/doc/bugs/gpg_bundled_with_OSX_build_fails.mdwn b/doc/bugs/gpg_bundled_with_OSX_build_fails.mdwn
new file mode 100644
index 000000000..701e67cc5
--- /dev/null
+++ b/doc/bugs/gpg_bundled_with_OSX_build_fails.mdwn
@@ -0,0 +1,25 @@
+What steps will reproduce the problem?
+
+run
+
+ /Applications/git-annex.app/Contents/MacOS/bin/gpg
+
+from the terminal
+
+What is the expected output? What do you see instead?
+
+I expect to see typical gpg output. Instead, I see
+
+ dyld: Library not loaded: /opt/local/lib/libiconv.2.dylib
+ Referenced from: /Applications/git-annex.app/Contents/MacOS/bin/gpg
+ Reason: Incompatible library version: gpg requires version 8.0.0 or later, but libiconv.2.dylib provides version 7.0.0
+ Trace/BPT trap: 5
+
+What version of git-annex are you using? On what operating system?
+
+git annex Version: 3.20121017 on Mac OS X 10.7.5
+
+[[!tag /design/assistant/OSX]]
+
+> Libraries are now handled better in the OSX app and this should be able
+> to happen anymore. [[done]] --[[Joey]]
diff --git a/doc/bugs/gpg_bundled_with_OSX_build_fails/comment_1_ec911f920db6c354ba998ffbb5886606._comment b/doc/bugs/gpg_bundled_with_OSX_build_fails/comment_1_ec911f920db6c354ba998ffbb5886606._comment
new file mode 100644
index 000000000..574a25b5f
--- /dev/null
+++ b/doc/bugs/gpg_bundled_with_OSX_build_fails/comment_1_ec911f920db6c354ba998ffbb5886606._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.194"
+ subject="comment 1"
+ date="2012-11-01T02:36:07Z"
+ content="""
+You need to use runshell to run the commands included in the OSX app.
+
+(Also, using them outside of git-annex is not really something that is intended to be supported.)
+"""]]
diff --git a/doc/bugs/gpg_bundled_with_OSX_build_fails/comment_2_bf2a3ab1bbe258bd501ec4b776882adf._comment b/doc/bugs/gpg_bundled_with_OSX_build_fails/comment_2_bf2a3ab1bbe258bd501ec4b776882adf._comment
new file mode 100644
index 000000000..268a577ca
--- /dev/null
+++ b/doc/bugs/gpg_bundled_with_OSX_build_fails/comment_2_bf2a3ab1bbe258bd501ec4b776882adf._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/6xTna_B_h.ECb6_ftC2dYLytAEwrv36etg_054U-#4c1e7"
+ nickname="Fake"
+ subject="comment 2"
+ date="2012-11-01T11:49:55Z"
+ content="""
+Ok, thanks for the info. I actually tried running this directly because I was getting the same error from inside of git-annex assistant. When I add a remote server repository with encrypted rsync, I am able to add the server (\"Check this server\" works), but when I click on the \"Use an encrypted rsync repository on the server\" button, I get the following error:
+
+ Internal Server Error
+
+ user error (gpg [\"--quiet\",\"--trust-model\",\"always\",\"--gen-random\",\"--armor\",\"1\",\"512\"] exited 5)
+"""]]
diff --git a/doc/bugs/gpg_bundled_with_OSX_build_fails/comment_3_c0142427400323c00bd8294415ae32c5._comment b/doc/bugs/gpg_bundled_with_OSX_build_fails/comment_3_c0142427400323c00bd8294415ae32c5._comment
new file mode 100644
index 000000000..163ce66c0
--- /dev/null
+++ b/doc/bugs/gpg_bundled_with_OSX_build_fails/comment_3_c0142427400323c00bd8294415ae32c5._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/6xTna_B_h.ECb6_ftC2dYLytAEwrv36etg_054U-#4c1e7"
+ nickname="Fake"
+ subject="comment 3"
+ date="2012-11-01T11:52:30Z"
+ content="""
+A little more info. Here is the error from the console log when I try to add the remote server repository.
+
+ Dyld Error Message:
+ Library not loaded: /opt/local/lib/libncurses.5.dylib
+ Referenced from: /Applications/git-annex.app/Contents/MacOS/opt/local/lib/libreadline.6.2.dylib
+ Reason: no suitable image found. Did find:
+ /usr/lib/libncurses.5.dylib: mach-o, but wrong architecture
+ /usr/lib/libncurses.5.dylib: mach-o, but wrong architecture
+"""]]
diff --git a/doc/bugs/gpg_bundled_with_OSX_build_fails/comment_4_b56db4b5afc276f88a2b980e22fda8a0._comment b/doc/bugs/gpg_bundled_with_OSX_build_fails/comment_4_b56db4b5afc276f88a2b980e22fda8a0._comment
new file mode 100644
index 000000000..64946b41a
--- /dev/null
+++ b/doc/bugs/gpg_bundled_with_OSX_build_fails/comment_4_b56db4b5afc276f88a2b980e22fda8a0._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.194"
+ subject="comment 4"
+ date="2012-11-01T13:40:39Z"
+ content="""
+Ah ok, thanks for the info about this problem.
+
+Which URL did you download the app from? We have 2 builds.
+"""]]
diff --git a/doc/bugs/gpg_bundled_with_OSX_build_fails/comment_5_a4eda81e5f927c463593bc48fbe84077._comment b/doc/bugs/gpg_bundled_with_OSX_build_fails/comment_5_a4eda81e5f927c463593bc48fbe84077._comment
new file mode 100644
index 000000000..d5a583020
--- /dev/null
+++ b/doc/bugs/gpg_bundled_with_OSX_build_fails/comment_5_a4eda81e5f927c463593bc48fbe84077._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/6xTna_B_h.ECb6_ftC2dYLytAEwrv36etg_054U-#4c1e7"
+ nickname="Fake"
+ subject="comment 5"
+ date="2012-11-01T14:29:40Z"
+ content="""
+This is the beta release (http://downloads.kitenet.net/git-annex/OSX/git-annex.dmg.bz2) Right now the link to the daily build is broken.
+
+I found the link on this page: http://git-annex.branchable.com/install/OSX/
+
+Thanks!
+"""]]
diff --git a/doc/bugs/gpg_bundled_with_OSX_build_fails/comment_6_2f0b9331d16a208883bac586258a7b50._comment b/doc/bugs/gpg_bundled_with_OSX_build_fails/comment_6_2f0b9331d16a208883bac586258a7b50._comment
new file mode 100644
index 000000000..abcfb6fb2
--- /dev/null
+++ b/doc/bugs/gpg_bundled_with_OSX_build_fails/comment_6_2f0b9331d16a208883bac586258a7b50._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.49"
+ subject="comment 6"
+ date="2012-11-26T23:53:01Z"
+ content="""
+The OSX app has been updated for today's release, and includes a lot of missing libraries. Your testing of it would be appreciated.
+"""]]
diff --git a/doc/bugs/gpg_bundled_with_OSX_build_fails/comment_7_c05c484a6134f93796cff08de0f63e80._comment b/doc/bugs/gpg_bundled_with_OSX_build_fails/comment_7_c05c484a6134f93796cff08de0f63e80._comment
new file mode 100644
index 000000000..1e60e5d25
--- /dev/null
+++ b/doc/bugs/gpg_bundled_with_OSX_build_fails/comment_7_c05c484a6134f93796cff08de0f63e80._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlpOeCs7zZLR-PBGPxUgjWlg7bwAAzQZyk"
+ nickname="Seth"
+ subject="comment 7"
+ date="2013-06-29T17:26:54Z"
+ content="""
+I get this same internal server error when doing the encrypted rsync repo option:
+
+ user error (gpg [\"--quiet\",\"--trust-model\",\"always\",\"--gen-random\",\"--armor\",\"1\",\"512\"] exited 2)
+
+Currently using the file found here:
+
+http://downloads.kitenet.net/git-annex/OSX/current/10.7.5_Lion/
+
+Using MacOS 10.7.5 Lion
+"""]]
diff --git a/doc/bugs/gpg_bundled_with_OSX_build_fails/comment_8_f2cb5467ebe80cf67e1155b771b73978._comment b/doc/bugs/gpg_bundled_with_OSX_build_fails/comment_8_f2cb5467ebe80cf67e1155b771b73978._comment
new file mode 100644
index 000000000..5b2bf88b2
--- /dev/null
+++ b/doc/bugs/gpg_bundled_with_OSX_build_fails/comment_8_f2cb5467ebe80cf67e1155b771b73978._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.193"
+ subject="comment 8"
+ date="2013-06-30T18:02:03Z"
+ content="""
+That's not the same error (2 != 5), and posting comments to long-closed bugs is never a good idea if your goal is to report a current bug in a way that will ensure it's noticed and that anyone remembers to follow up on it. You should file a new bug report, and include whatever actual error message is output *before* the message you pasted.
+"""]]
diff --git a/doc/bugs/gpg_bundled_with_OSX_build_fails/comment_9_27bbda7e31f55b29e1473555ee17e613._comment b/doc/bugs/gpg_bundled_with_OSX_build_fails/comment_9_27bbda7e31f55b29e1473555ee17e613._comment
new file mode 100644
index 000000000..cd2002411
--- /dev/null
+++ b/doc/bugs/gpg_bundled_with_OSX_build_fails/comment_9_27bbda7e31f55b29e1473555ee17e613._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlpOeCs7zZLR-PBGPxUgjWlg7bwAAzQZyk"
+ nickname="Seth"
+ subject="comment 9"
+ date="2013-06-30T19:38:07Z"
+ content="""
+Just so you know, this post is what comes up on google when I search the error.
+"""]]
diff --git a/doc/bugs/gpg_error_on_android.mdwn b/doc/bugs/gpg_error_on_android.mdwn
new file mode 100644
index 000000000..3e69f05f2
--- /dev/null
+++ b/doc/bugs/gpg_error_on_android.mdwn
@@ -0,0 +1,39 @@
+### Please describe the problem.
+
+Adding an existing cloud repo on box.com results in an gpg error:
+
+ user error (gpg ["--quiet","--trust-model","always","--batch","--passphrase-fd","86","--decrypt"] exited 2)
+
+### What steps will reproduce the problem?
+
+Enabling an existing cloud repository.
+
+### What version of git-annex are you using? On what operating system?
+
+Latest Android (4.20130516-g32 40006) on a rooted Samsung Galaxy Note (CyanogenMod 10.1)
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/debug.log
+
+(merging refs/synced/de8a8792-70de-48c3-a646-a168ce1d9d35/c25hdXRoQGphYmJlci5vcmc=/git-annex into git-annex...)
+(Recording state in git...)
+(gpg) gpg: can't open `/usr/local/share/gnupg/options.skel': No such file or directory
+gpg: DBG: locking for `/sdcard/git-annex.home/.gnupg/secring.gpg.lock' done via O_EXCL
+gpg: DBG: locking for `/sdcard/git-annex.home/.gnupg/pubring.gpg.lock' done via O_EXCL
+gpg: encrypted with unknown algorithm 3
+gpg: decryption failed: secret key not available
+(gpg) gpg: encrypted with unknown algorithm 3
+gpg: decryption failed: secret key not available
+(gpg) gpg: encrypted with unknown algorithm 3
+gpg: decryption failed: secret key not available
+(gpg) gpg: encrypted with unknown algorithm 3
+gpg: decryption failed: secret key not available
+
+# End of transcript or log.
+"""]]
+
+> [[done]]; I have deployed the new gpg build for Android and the
+> nightly Android app build is now using it. --[[Joey]]
diff --git a/doc/bugs/gpg_error_on_android/comment_1_870583fd1b7a33b688b9a228077d1333._comment b/doc/bugs/gpg_error_on_android/comment_1_870583fd1b7a33b688b9a228077d1333._comment
new file mode 100644
index 000000000..b15500454
--- /dev/null
+++ b/doc/bugs/gpg_error_on_android/comment_1_870583fd1b7a33b688b9a228077d1333._comment
@@ -0,0 +1,629 @@
+[[!comment format=mdwn
+ username="carlo"
+ ip="118.208.45.43"
+ subject="comment 1"
+ date="2013-07-06T03:29:10Z"
+ content="""
+I see similar errors on my Samsung Galaxy S3, running Cyanogenmod 9. The phone is trying to sync with an encrypted rsync repository on my Linode. My laptop can sync with no problems.
+
+Here's a dump from daemon.log. Let me know if you need more details.
+
+ [2013-07-06 13:10:22 EST] main: starting assistant version 4.20130704-gaf18656
+ Already up-to-date.
+
+ (scanning...) [2013-07-06 13:10:23 EST] Watcher: Performing startup scan
+ Already up-to-date.
+ Already up-to-date.
+
+
+ (started...) (gpg) [2013-07-06 13:10:28 EST] XMPPSendPack: Syncing with nk
+ [2013-07-06 13:10:28 EST] XMPPReceivePack: Syncing with nk
+ [2013-07-06 13:10:29 EST] XMPPSendPack: Syncing with nk
+
+ <snip>
+
+ GPGHMACSHA1--cfa7bdccfada399b50f086901621ba66a789a4df
+ Already up-to-date.
+
+ 0 0% 0.00kB/s 0:00:00 [2013-07-06 13:10:36 EST] Committer: Committing changes to git
+ [2013-07-06 13:10:36 EST] XMPPSendPack: Syncing with nk
+
+ 262,144 0% 203.34kB/s 0:06:43 Already up-to-date.
+
+ 655,360 0% 211.99kB/s 0:06:25 [2013-07-06 13:10:38 EST] XMPPSendPack: Syncing with nk
+ [2013-07-06 13:10:39 EST] XMPPSendPack: Syncing with nk
+
+ 1,638,400 1% 395.65kB/s 0:03:23
+ 2,424,832 2% 464.04kB/s 0:02:52
+ 2,981,888 3% 546.05kB/s 0:02:25
+ 3,538,944 4% 682.17kB/s 0:01:55
+ 4,096,000 4% 581.68kB/s 0:02:14
+ 4,653,056 5% 529.05kB/s 0:02:26
+ 5,210,112 6% 525.60kB/s 0:02:26
+ 5,767,168 7% 526.24kB/s 0:02:25
+ 6,324,224 7% 526.75kB/s 0:02:24
+ 6,881,280 8% 529.83kB/s 0:02:22
+ 7,438,336 9% 532.94kB/s 0:02:20 (gpg)
+ 7,798,784 9% 486.16kB/s 0:02:33
+ 8,519,680 10% 525.75kB/s 0:02:20
+ 9,076,736 11% 526.01kB/s 0:02:19
+ 9,502,720 11% 459.23kB/s 0:02:38
+ 10,354,688 12% 556.40kB/s 0:02:09
+ 10,911,744 13% 514.20kB/s 0:02:18 (gpg)
+ 11,501,568 13% 508.81kB/s 0:02:19 (gpg)
+ 12,091,392 14% 585.73kB/s 0:01:59
+ GPGHMACSHA1--15b3dbca166df23b9b14e88bcfb08dceeeeaade9
+
+ 0 0% 0.00kB/s 0:00:00
+ 12,615,680 15% 521.25kB/s 0:02:13
+ 294,912 26% 266.17kB/s 0:00:03
+ 12,910,592 15% 459.84kB/s 0:02:30
+ 589,824 52% 266.67kB/s 0:00:01
+ 13,205,504 16% 396.57kB/s 0:02:54
+ 884,736 79% 266.42kB/s 0:00:00
+ 13,500,416 16% 321.72kB/s 0:03:33
+ 1,116,373 100% 275.58kB/s 0:00:03 (xfr#1, to-chk=0/1)
+
+ 13,860,864 16% 285.92kB/s 0:03:59
+ 14,221,312 17% 304.91kB/s 0:03:43
+ 14,909,440 18% 403.88kB/s 0:02:46
+ GPGHMACSHA1--ec1cbd34a82fe0997354669b2c7b38419f73d07e
+
+ 0 0% 0.00kB/s 0:00:00
+ 15,400,960 18% 450.59kB/s 0:02:28 gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ 294,912 26% 266.42kB/s 0:00:03
+ GPGHMACSHA1--b979ec76f3b12b63db8ee540fc9a018cffb82aa8
+
+ 15,663,104 19% 426.46kB/s 0:02:36
+ 0 0% 0.00kB/s 0:00:00
+ 393,216 35% 178.19kB/s 0:00:03
+ 15,761,408 19% 364.08kB/s 0:03:02
+ 131,072 11% 115.21kB/s 0:00:08
+ 688,128 62% 206.52kB/s 0:00:01
+ 16,056,320 19% 262.23kB/s 0:04:12
+ 393,216 34% 176.71kB/s 0:00:04
+ 884,736 80% 199.40kB/s 0:00:01
+ 16,252,928 19% 194.67kB/s 0:05:39
+ 589,824 51% 177.01kB/s 0:00:03
+ 1,095,420 100% 205.52kB/s 0:00:05 (xfr#1, to-chk=0/1)
+
+ 16,482,304 20% 183.44kB/s 0:05:58
+ 819,200 70% 185.96kB/s 0:00:01
+ 16,777,216 20% 224.84kB/s 0:04:51
+ 1,114,112 96% 227.27kB/s 0:00:00
+ 1,154,143 100% 211.07kB/s 0:00:05 (xfr#1, to-chk=0/1)
+
+ 17,334,272 21% 289.96kB/s 0:03:44
+ 17,891,328 21% 376.91kB/s 0:02:50 gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+ send: resource vanisheds e(nBdr:o kreens opuirpcee)
+ vanished (Broken pipe)
+
+ 18,448,384 22% 461.76kB/s 0:02:18 gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+ se
+ 19,005,440 23% 531.25kB/s 0:01:59 nd: resource vanished (Broken pipe)
+
+ 19,562,496 23% 532.81kB/s 0:01:57
+ 19,922,944 24% 484.14kB/s 0:02:08
+ 20,643,840 25% 525.36kB/s 0:01:57
+ 21,200,896 25% 525.62kB/s 0:01:56
+ 21,757,952 26% 526.13kB/s 0:01:55
+ 22,085,632 26% 518.16kB/s 0:01:56
+ 22,872,064 27% 529.05kB/s 0:01:52
+ 23,429,120 28% 528.80kB/s 0:01:51
+ 23,953,408 29% 516.75kB/s 0:01:52
+ 24,543,232 29% 583.66kB/s 0:01:38
+ 25,034,752 30% 516.51kB/s 0:01:50
+ 25,460,736 30% 466.71kB/s 0:02:01
+ 26,050,560 31% 481.20kB/s 0:01:56
+ 26,607,616 32% 471.25kB/s 0:01:58
+ 27,164,672 33% 486.21kB/s 0:01:53
+ 27,721,728 33% 536.44kB/s 0:01:41
+ 28,278,784 34% 533.33kB/s 0:01:41
+ 28,835,840 35% 533.59kB/s 0:01:40
+ 29,392,896 35% 529.44kB/s 0:01:39
+ 29,982,720 36% 532.95kB/s 0:01:38
+ 30,539,776 37% 533.46kB/s 0:01:37
+ 31,096,832 37% 533.46kB/s 0:01:35
+ 31,653,888 38% 537.23kB/s 0:01:34
+ 31,752,192 38% 409.87kB/s 0:02:03
+ 32,800,768 39% 524.96kB/s 0:01:34
+ 33,357,824 40% 524.84kB/s 0:01:33
+ 33,914,880 41% 524.96kB/s 0:01:32
+ 34,471,936 41% 652.74kB/s 0:01:13
+ 35,028,992 42% 533.33kB/s 0:01:28
+ 35,586,048 43% 533.46kB/s 0:01:27
+ 36,143,104 43% 533.07kB/s 0:01:26
+ 36,700,160 44% 533.33kB/s 0:01:25
+ 37,257,216 45% 533.33kB/s 0:01:24
+ 37,814,272 45% 533.20kB/s 0:01:23
+ 38,240,256 46% 467.37kB/s 0:01:34
+ 39,059,456 47% 525.19kB/s 0:01:22
+ 39,616,512 48% 525.31kB/s 0:01:21
+ 40,173,568 48% 525.43kB/s 0:01:20
+ 40,632,320 49% 574.52kB/s 0:01:12
+ 41,254,912 50% 527.82kB/s 0:01:17
+ 41,811,968 50% 528.08kB/s 0:01:16
+ 42,369,024 51% 527.82kB/s 0:01:15
+ 42,926,080 52% 549.15kB/s 0:01:11
+ 43,483,136 52% 533.59kB/s 0:01:12
+ 44,040,192 53% 533.20kB/s 0:01:11
+ 44,597,248 54% 533.20kB/s 0:01:10
+ 45,121,536 54% 525.49kB/s 0:01:10
+ 45,678,592 55% 525.49kB/s 0:01:09
+ 46,039,040 55% 476.68kB/s 0:01:16
+ 46,792,704 56% 520.89kB/s 0:01:08
+ 47,349,760 57% 528.41kB/s 0:01:06
+ 47,906,816 58% 520.20kB/s 0:01:06
+ 48,431,104 58% 500.32kB/s 0:01:07
+ 49,020,928 59% 406.05kB/s 0:01:21
+ 49,807,360 60% 446.10kB/s 0:01:12
+ 50,364,416 61% 451.55kB/s 0:01:10
+ 50,921,472 61% 504.88kB/s 0:01:02
+ 51,412,992 62% 569.76kB/s 0:00:54
+ 51,970,048 63% 515.00kB/s 0:00:58
+ 52,527,104 63% 514.87kB/s 0:00:57
+ 53,084,160 64% 515.25kB/s 0:00:56
+ 53,641,216 65% 530.47kB/s 0:00:54
+ 54,198,272 65% 532.94kB/s 0:00:52
+ 54,755,328 66% 533.46kB/s 0:00:51
+ 55,312,384 67% 533.20kB/s 0:00:50
+ 55,869,440 67% 533.33kB/s 0:00:49
+ 56,426,496 68% 533.46kB/s 0:00:48
+ 56,983,552 69% 533.20kB/s 0:00:47
+ 57,409,536 69% 466.09kB/s 0:00:53
+ 58,228,736 70% 525.79kB/s 0:00:45
+ 58,785,792 71% 525.67kB/s 0:00:44
+ 59,342,848 72% 520.68kB/s 0:00:44
+ 59,736,064 72% 547.60kB/s 0:00:41
+ 60,489,728 73% 528.10kB/s 0:00:41
+ 61,046,784 74% 528.48kB/s 0:00:40
+ 61,603,840 74% 533.72kB/s 0:00:38
+ 62,128,128 75% 567.40kB/s 0:00:35
+ 62,226,432 75% 399.53kB/s 0:00:50
+ 62,652,416 76% 369.81kB/s 0:00:53
+ 62,947,328 76% 300.78kB/s 0:01:04
+ 63,438,848 77% 292.97kB/s 0:01:04
+ 63,963,136 77% 400.66kB/s 0:00:45
+ 64,520,192 78% 426.27kB/s 0:00:41
+ 65,110,016 79% 495.54kB/s 0:00:34
+ 65,601,536 79% 497.76kB/s 0:00:33
+ 66,158,592 80% 506.62kB/s 0:00:31
+ 66,715,648 81% 511.33kB/s 0:00:30
+ 67,207,168 81% 452.20kB/s 0:00:33
+ 68,059,136 82% 527.01kB/s 0:00:27
+ 68,616,192 83% 526.55kB/s 0:00:26
+ 69,173,248 84% 527.24kB/s 0:00:24
+ 69,500,928 84% 529.30kB/s 0:00:24
+ 70,320,128 85% 527.98kB/s 0:00:22
+ 70,877,184 86% 527.60kB/s 0:00:21
+ 71,434,240 86% 526.84kB/s 0:00:20
+ 71,991,296 87% 595.93kB/s 0:00:17
+ 72,548,352 88% 529.70kB/s 0:00:18
+ 73,105,408 88% 528.16kB/s 0:00:17 [2013-07-06 13:13:01 EST] XMPPSendPack: Syncing with ch
+
+ 73,662,464 89% 527.39kB/s 0:00:16 [2013-07-06 13:13:02 EST] XMPPSendPack: Syncing with ch
+
+ 74,219,520 90% 524.08kB/s 0:00:15
+ 74,743,808 90% 511.21kB/s 0:00:14
+ 75,104,256 91% 410.00kB/s 0:00:17
+ 75,497,472 91% 377.34kB/s 0:00:18
+ 76,152,832 92% 402.22kB/s 0:00:15
+ 76,709,888 93% 413.44kB/s 0:00:13
+ 77,201,408 93% 458.58kB/s 0:00:11
+ 78,020,608 94% 552.96kB/s 0:00:07
+ 78,577,664 95% 528.45kB/s 0:00:07
+ 79,134,720 96% 528.34kB/s 0:00:06
+ 79,691,776 96% 597.25kB/s 0:00:04
+ 80,248,832 97% 532.42kB/s 0:00:03
+ 80,805,888 98% 533.33kB/s 0:00:02
+ 81,362,944 98% 533.07kB/s 0:00:01
+ 81,920,000 99% 533.07kB/s 0:00:00
+ 82,307,694 100% 491.43kB/s 0:02:43 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+ send: resource vanished (Broken pipe)
+
+ GPGHMACSHA1--836e8cdf7c23d119e08f9d9cb3377abb438f2312
+
+ 0 0% 0.00kB/s 0:00:00
+ 131,072 11% 115.84kB/s 0:00:08
+ 229,376 19% 106.41kB/s 0:00:08
+ 393,216 34% 118.08kB/s 0:00:06
+ 655,360 56% 149.46kB/s 0:00:03
+ 917,504 79% 180.24kB/s 0:00:01
+ 1,154,559 100% 184.38kB/s 0:00:06 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--c34a27463185c59e8cb7df7f647333072e18ddb9
+
+ 0 0% 0.00kB/s 0:00:00
+ 294,912 16% 272.73kB/s 0:00:05
+ 655,360 36% 304.18kB/s 0:00:03
+ 1,114,112 62% 343.54kB/s 0:00:01
+ 1,441,792 81% 335.32kB/s 0:00:00
+ 1,772,175 100% 351.61kB/s 0:00:04 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--7bc715e8c49feb30ba974b246ad8b69bcef8f407
+
+ 0 0% 0.00kB/s 0:00:00
+ 393,216 31% 373.18kB/s 0:00:02
+ 819,200 66% 340.43kB/s 0:00:01
+ 1,234,572 100% 411.48kB/s 0:00:02 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--dbc6af27d9b732f3ea7b29f7316cf67986db8ff0
+
+ 0 0% 0.00kB/s 0:00:00
+ 557,056 60% 532.81kB/s 0:00:00
+ 913,536 100% 540.03kB/s 0:00:01 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--84ce3dc5fe676eb10cfe595564482d48daceeb33
+
+ 0 0% 0.00kB/s 0:00:00
+ 557,056 44% 532.29kB/s 0:00:01
+ 1,114,112 88% 532.29kB/s 0:00:00
+ 1,256,801 100% 548.90kB/s 0:00:02 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--9d042d017e8efc60f82ee3789edbbd8422ddbf1c
+
+ 0 0% 0.00kB/s 0:00:00
+ 491,520 42% 469.67kB/s 0:00:01
+ 950,272 81% 458.50kB/s 0:00:00
+ 1,165,242 100% 483.81kB/s 0:00:02 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--951b2f84c011debef9e6dc213d859cc6366f8e01
+
+ 0 0% 0.00kB/s 0:00:00
+ 557,056 44% 535.96kB/s 0:00:01
+ 983,040 78% 460.21kB/s 0:00:00
+ 1,257,173 100% 468.23kB/s 0:00:02 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--88b8021104955c3ff14da53cdf5c8dd445719bfa
+
+ 0 0% 0.00kB/s 0:00:00
+ 589,824 38% 544.94kB/s 0:00:01
+ 1,146,880 75% 536.66kB/s 0:00:00
+ 1,518,637 100% 493.03kB/s 0:00:03 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--89a254b76c1dd92c3bcf6c2db0745287ca306ae6
+
+ 0 0% 0.00kB/s 0:00:00
+ 393,216 29% 367.11kB/s 0:00:02
+ 819,200 61% 391.01kB/s 0:00:01
+ 1,277,952 96% 404.01kB/s 0:00:00
+ 1,326,036 100% 417.32kB/s 0:00:03 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--b975ff334766d744ce6827be273ad7f46dddcdeb
+
+ 0 0% 0.00kB/s 0:00:00
+ 524,288 52% 496.61kB/s 0:00:00
+ 996,592 100% 480.85kB/s 0:00:02 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--e828d8bbe5d34598fef577170a9fa9187d09e312
+
+ 0 0% 0.00kB/s 0:00:00
+ 557,056 35% 529.18kB/s 0:00:01
+ 1,114,112 70% 529.96kB/s 0:00:00
+ 1,581,185 100% 542.18kB/s 0:00:02 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--f6b7fc900cd45830afe01711e369d17453a997dd
+
+ 0 0% 0.00kB/s 0:00:00
+ 557,056 35% 538.61kB/s 0:00:01
+ 1,114,112 70% 535.17kB/s 0:00:00
+ 1,573,373 100% 547.97kB/s 0:00:02 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--d7a0413362aff13ce23c76d05d684df1fa884635
+
+ 0 0% 0.00kB/s 0:00:00
+ 524,288 30% 504.93kB/s 0:00:02
+ 950,272 55% 397.94kB/s 0:00:01
+ 1,699,965 100% 524.36kB/s 0:00:03 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--f98f1613a3b8f160ea4029eb9fa3c45f9a2a1bc6
+
+ 0 0% 0.00kB/s 0:00:00
+ 557,056 37% 532.81kB/s 0:00:01
+ 1,114,112 75% 525.10kB/s 0:00:00
+ 1,478,031 100% 548.19kB/s 0:00:02 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--1d35cc37e4a83908a29c0651448a96269458218d
+
+ 0 0% 0.00kB/s 0:00:00
+ 589,824 39% 558.14kB/s 0:00:01
+ 1,146,880 77% 544.75kB/s 0:00:00
+ 1,475,738 100% 556.00kB/s 0:00:02 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--41779d89d985def50ee52dbb1abaf41cfb248f02
+
+ 0 0% 0.00kB/s 0:00:00
+ 524,288 77% 509.45kB/s 0:00:00
+ 680,795 100% 500.25kB/s 0:00:01 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--0ac2341072949bd0d26df145e3cef8d39ba177ad
+
+ 0 0% 0.00kB/s 0:00:00
+ 851,968 78% 794.65kB/s 0:00:00
+ 1,085,714 100% 758.96kB/s 0:00:01 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--96239a54b31856d30e50eedb2a3352ec87fd6d1e
+
+ 0 0% 0.00kB/s 0:00:00
+ 557,056 47% 528.16kB/s 0:00:01
+ 1,114,112 95% 529.96kB/s 0:00:00
+ 1,166,134 100% 549.88kB/s 0:00:02 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--e40a7caa66fa1656428cbec103645089579065f8
+
+ 0 0% 0.00kB/s 0:00:00
+ 98,304 7% 95.05kB/s 0:00:13
+ 622,592 45% 297.02kB/s 0:00:02
+ 753,664 55% 232.91kB/s 0:00:02
+ 884,736 64% 204.74kB/s 0:00:02
+ 1,310,720 95% 280.97kB/s 0:00:00
+ 1,369,673 100% 251.94kB/s 0:00:05 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--4907edd5704e1a3540e946cfc80b29226599e466
+
+ 0 0% 0.00kB/s 0:00:00
+ 327,680 25% 310.98kB/s 0:00:03
+ 688,128 52% 328.77kB/s 0:00:01
+ 1,114,112 85% 350.74kB/s 0:00:00
+ 1,303,313 100% 369.78kB/s 0:00:03 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--2a0a0f546f08334d8cd90f2930057837dcf5ba09
+
+ 0 0% 0.00kB/s 0:00:00
+ 491,520 39% 475.25kB/s 0:00:01
+ 917,504 73% 438.57kB/s 0:00:00
+ 1,146,880 92% 359.67kB/s 0:00:00
+ 1,246,084 100% 344.82kB/s 0:00:03 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--9eb761916db3868a5ffe7b310ae5ac3cc7046ae5
+
+ 0 0% 0.00kB/s 0:00:00
+ 557,056 44% 517.60kB/s 0:00:01
+ 786,432 62% 329.05kB/s 0:00:01
+ 1,254,828 100% 515.31kB/s 0:00:02 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--e644608fd731b8eaf6d5d04e78e165300eb25f98
+
+ 0 0% 0.00kB/s 0:00:00
+ 589,824 52% 561.40kB/s 0:00:00
+ 1,048,576 93% 503.19kB/s 0:00:00
+ 1,116,566 100% 522.47kB/s 0:00:02 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--58e2af2853f65840a6e16eb7c03d005ed2e79c40
+
+ 0 0% 0.00kB/s 0:00:00
+ 557,056 42% 530.21kB/s 0:00:01
+ 1,114,112 85% 531.25kB/s 0:00:00
+ 1,300,115 100% 546.79kB/s 0:00:02 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--c5c714419a2d7c0f4699f31862e7011a15014482
+
+ 0 0% 0.00kB/s 0:00:00
+ 589,824 38% 547.53kB/s 0:00:01
+ 1,146,880 75% 538.46kB/s 0:00:00
+ 1,521,103 100% 550.17kB/s 0:00:02 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--15df191feeb70009d1babbf45edfd895c7ed16fe
+
+ 0 0% 0.00kB/s 0:00:00
+ 557,056 43% 541.29kB/s 0:00:01
+ 1,114,112 87% 536.22kB/s 0:00:00
+ 1,277,262 100% 550.70kB/s 0:00:02 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--da82fe427bcc275851fcff2406702bdf711a0d05
+
+ 0 0% 0.00kB/s 0:00:00
+ 557,056 39% 539.68kB/s 0:00:01
+ 1,114,112 79% 535.43kB/s 0:00:00
+ 1,394,802 100% 546.16kB/s 0:00:02 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--d4a3cd0a0cdfb63e0c822c2971bec47351f0d691
+
+ 0 0% 0.00kB/s 0:00:00
+ 557,056 43% 542.37kB/s 0:00:01
+ 1,114,112 86% 535.17kB/s 0:00:00
+ 1,284,784 100% 550.05kB/s 0:00:02 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--b97860268c7d4811de5d0529fcb6964e72404e77
+
+ 0 0% 0.00kB/s 0:00:00
+ 40,966 100% 13.02MB/s 0:00:00 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--a8b3e383f310580bb6c1035144763ec7db044f78
+
+ 0 0% 0.00kB/s 0:00:00
+ 557,056 75% 538.08kB/s 0:00:00
+ 733,303 100% 564.76kB/s 0:00:01 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--29011935e74ac079fcb329a43739baeaa17d098c
+
+ 0 0% 0.00kB/s 0:00:00
+ 89,335 100% 1.11MB/s 0:00:00 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--fd6e992885ee3c8305d01166eecf3c464627c4f7
+
+ 0 0% 0.00kB/s 0:00:00
+ 41,462 100% 13.18MB/s 0:00:00 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--a2069f368ff8402a2cb1418bd4b9732af7c4d4a9
+
+ 0 0% 0.00kB/s 0:00:00
+ 170,729 100% 706.47kB/s 0:00:00 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--6792222db461942b05679e53db4e54fa789ca01f
+
+ 0 0% 0.00kB/s 0:00:00
+ 592 100% 578.13kB/s 0:00:00 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--d18187ee562acebfc027ae87ca256ee76291ebc9
+
+ 0 0% 0.00kB/s 0:00:00
+ 92,078 100% 1.16MB/s 0:00:00 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--099750d6c62696356befb2d9f0c6eced87d44982
+
+ 0 0% 0.00kB/s 0:00:00
+ 17,889 100% 17.06MB/s 0:00:00 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--5bfba3f4483f32f614082626cb19c9a80dcef47f
+
+ 0 0% 0.00kB/s 0:00:00
+ 557,056 34% 542.37kB/s 0:00:01
+ 1,114,112 68% 529.44kB/s 0:00:00
+ 1,572,864 96% 493.89kB/s 0:00:00
+ 1,636,134 100% 511.29kB/s 0:00:03 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--c63f95ff9e5e7162324f198763d82135a782a672
+
+ 0 0% 0.00kB/s 0:00:00
+ 11,074 100% 10.56MB/s 0:00:00 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--d5355ccf4f2f48a8adf698d00416569996408c99
+
+ 0 0% 0.00kB/s 0:00:00
+ 17,389 100% 16.58MB/s 0:00:00 (xfr#1, to-chk=0/1)
+ gpg: encrypted with unknown algorithm 3
+ gpg: decryption failed: secret key not available
+
+ GPGHMACSHA1--cd50fc92525ee650189b89373a4791be4c7ffa24
+
+ 0 0% 0.00kB/s 0:00:00
+ 131,072 0% 91.30kB/s 0:06:06
+ 294,912 0% 110.85kB/s 0:05:00
+ 491,520 1% 133.37kB/s 0:04:08
+ 819,200 2% 173.24kB/s 0:03:09
+ 1,343,488 3% 277.48kB/s 0:01:56
+ 1,900,544 5% 383.00kB/s 0:01:22
+ 2,359,296 7% 438.88kB/s 0:01:11
+ 2,785,280 8% 456.82kB/s 0:01:07
+ 3,244,032 9% 390.90kB/s 0:01:17
+ 3,637,248 10% 356.83kB/s 0:01:24
+ 4,259,840 12% 388.28kB/s 0:01:15
+ 4,718,592 14% 395.97kB/s 0:01:13
+ 5,046,272 15% 385.54kB/s 0:01:14
+ 5,210,112 15% 326.18kB/s 0:01:27
+ 6,094,848 18% 385.21kB/s 0:01:11
+ 6,488,064 19% 372.65kB/s 0:01:12 [2013-07-06 13:16:29 EST] XMPPReceivePack: Syncing with ch
+
+ 6,914,048 20% 403.45kB/s 0:01:06
+ 7,143,424 21% 409.28kB/s 0:01:04
+ 7,667,712 22% 334.06kB/s 0:01:17
+ 8,126,464 24% 347.75kB/s 0:01:13
+ 8,683,520 25% 398.80kB/s 0:01:02
+ 9,240,576 27% 500.86kB/s 0:00:48
+ 9,797,632 29% 507.32kB/s 0:00:46
+ 10,256,384 30% 511.31kB/s 0:00:45
+ 10,682,368 31% 479.25kB/s 0:00:47
+ 11,206,656 33% 471.63kB/s 0:00:47
+ 11,763,712 34% 471.86kB/s 0:00:46
+ 12,320,768 36% 494.24kB/s 0:00:43
+ 12,615,680 37% 460.15kB/s 0:00:45
+ 13,434,880 39% 526.37kB/s 0:00:38
+ 13,991,936 41% 527.39kB/s 0:00:37
+ 14,548,992 43% 527.77kB/s 0:00:36
+ 14,843,904 44% 528.54kB/s 0:00:35
+ 15,663,104 46% 528.54kB/s 0:00:33
+ 16,220,160 48% 528.54kB/s 0:00:32
+ 16,777,216 49% 527.90kB/s 0:00:31
+ 17,334,272 51% 592.02kB/s 0:00:27
+ 17,891,328 53% 533.33kB/s 0:00:29
+ 18,448,384 54% 533.20kB/s 0:00:28
+ 19,005,440 56% 533.73kB/s 0:00:27
+ 19,562,496 58% 533.46kB/s 0:00:26
+ 20,119,552 59% 533.20kB/s 0:00:25
+ 20,414,464 60% 467.95kB/s 0:00:28
+ 21,233,664 63% 528.28kB/s 0:00:23
+ 21,790,720 64% 528.67kB/s 0:00:22
+ 22,347,776 66% 528.67kB/s 0:00:21
+ 22,740,992 67% 492.20kB/s 0:00:22
+ 23,494,656 69% 477.61kB/s 0:00:21
+ 24,051,712 71% 477.41kB/s 0:00:20
+ 24,608,768 73% 477.30kB/s 0:00:18
+ 25,165,824 74% 577.28kB/s 0:00:14
+ 25,722,880 76% 532.81kB/s 0:00:14
+ 26,279,936 78% 533.20kB/s 0:00:13
+ 26,804,224 79% 522.80kB/s 0:00:13
+
+"""]]
diff --git a/doc/bugs/gpg_error_on_android/comment_2_9ce5511a109bde50d8cf87bad0268b4a._comment b/doc/bugs/gpg_error_on_android/comment_2_9ce5511a109bde50d8cf87bad0268b4a._comment
new file mode 100644
index 000000000..f1cd47296
--- /dev/null
+++ b/doc/bugs/gpg_error_on_android/comment_2_9ce5511a109bde50d8cf87bad0268b4a._comment
@@ -0,0 +1,26 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.235"
+ subject="comment 2"
+ date="2013-07-08T19:57:10Z"
+ content="""
+Based on <http://pthree.org/2009/06/08/gnupg-up-and-close/> and <http://www.faqs.org/rfcs/rfc4880.html>, symmetric encryption algorithm 3 is CAST5.
+
+When I run `gpg -v --version` on Android, I get a very short list of Cipher algorithms, just \"3DES (S2)\".
+
+Compare with on Linux, where it supports:
+
+<pre>
+Cipher: 3DES (S2), CAST5 (S3), BLOWFISH (S4), AES (S7), AES192 (S8),
+ AES256 (S9), TWOFISH (S10), CAMELLIA128 (S11), CAMELLIA192 (S12),
+ CAMELLIA256 (S13)
+</pre>
+
+I suspect that you guys have a gpg on your non-android side that either defaults to CAST5, or has been configured, via the default-preference-list setting in gpg.conf, to use it. It should be possible to adjust your gpg.conf to use 3DES by default, and then things will interoperate (anything already encrypted by git-annex still won't be visible on Android of course).
+
+The gpg shipped with git-annex on Android could be rebuilt to include these. However, it would probably need porting of more libraries to Android. I stopped once I got gpg to compile at all, and had to pass several configure flags to disable features,
+
+This is something that anyone interested could work on. (Ie, no Haskell!) See `standalone/android/Makefile` in the git-annex source tree, which uses the Android SDK and NDK to cross-compile gnupg for Android.
+
+I think that getting it to build without `--enable-minimal` would probably get most of the way there. Aha.. I just tried this, and the new binary seems to support nearly everything the linux one does, no extra libraries needed!
+"""]]
diff --git a/doc/bugs/gpg_error_on_android/comment_3_b345e80f38d38f82cfcfce3102138fb8._comment b/doc/bugs/gpg_error_on_android/comment_3_b345e80f38d38f82cfcfce3102138fb8._comment
new file mode 100644
index 000000000..14cd6070c
--- /dev/null
+++ b/doc/bugs/gpg_error_on_android/comment_3_b345e80f38d38f82cfcfce3102138fb8._comment
@@ -0,0 +1,46 @@
+[[!comment format=mdwn
+ username="carlo"
+ ip="118.208.1.126"
+ subject="comment 3"
+ date="2013-07-09T00:34:45Z"
+ content="""
+I downloaded the daily build and the errors \"gpg: encrypted with
+unknown algorithm 3\" and \"gpg: decryption failed: secret key not
+available\" have gone, but now there is the problem \"gpg: decryption
+failed: bad key\". Logs are below.
+
+I'm in the process of setting up an Android build environment so I
+can debug this in more detail (I haven't done any Android development
+before but I do have Haskell experience).
+
+ [2013-07-09 10:21:22 EST] main: starting assistant version 4.20130708-g207c9f3
+ Already up-to-date.
+
+ (scanning...) [2013-07-09 10:21:23 EST] Watcher: Performing startup scan
+ Already up-to-date.
+ Already up-to-date.
+ (gpg)
+
+ (started...) [2013-07-09 10:21:28 EST] XMPPSendPack: Syncing with carlo.hamalainen
+
+ GPGHMACSHA1--15b3dbca166df23b9b14e88bcfb08dceeeeaade9
+ 1,116,373 100% 421.09kB/s 0:00:02 (xfr#1, to-chk=0/1)
+ gpg: decryption failed: bad key
+
+ GPGHMACSHA1--ec1cbd34a82fe0997354669b2c7b38419f73d07e
+ 1,095,420 100% 236.15kB/s 0:00:04 (xfr#1, to-chk=0/1)
+ gpg: decryption failed: bad key
+
+ GPGHMACSHA1--b979ec76f3b12b63db8ee540fc9a018cffb82aa8
+ 1,154,143 100% 412.85kB/s 0:00:02 (xfr#1, to-chk=0/1)
+ gpg: decryption failed: bad key
+
+ GPGHMACSHA1--836e8cdf7c23d119e08f9d9cb3377abb438f2312
+ 1,154,559 100% 411.95kB/s 0:00:02 (xfr#1, to-chk=0/1)
+ gpg: decryption failed: bad key
+
+ GPGHMACSHA1--c34a27463185c59e8cb7df7f647333072e18ddb9
+ 1,772,175 100% 401.63kB/s 0:00:04 (xfr#1, to-chk=0/1)
+ gpg: decryption failed: bad key
+
+"""]]
diff --git a/doc/bugs/gpg_error_on_android/comment_4_032f42235b7f26854e725041ca33384b._comment b/doc/bugs/gpg_error_on_android/comment_4_032f42235b7f26854e725041ca33384b._comment
new file mode 100644
index 000000000..5fdfa8211
--- /dev/null
+++ b/doc/bugs/gpg_error_on_android/comment_4_032f42235b7f26854e725041ca33384b._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.235"
+ subject="comment 4"
+ date="2013-07-09T18:03:12Z"
+ content="""
+So, I am able to get the \"bad\" key message out of gpg if I encrypt with --symmetric with a passphrase and then enter the wrong passphrase when decrypting.
+
+Perhaps git-annex is sending gpg the wrong encryption key, or perhaps the git repo it's operating in has an old version of the key for this remote somehow?
+"""]]
diff --git a/doc/bugs/gpg_fails_on_Mac_OS_10.9_when_creating_a_new_remote_repository_via_assistant.mdwn b/doc/bugs/gpg_fails_on_Mac_OS_10.9_when_creating_a_new_remote_repository_via_assistant.mdwn
new file mode 100644
index 000000000..1a0680c79
--- /dev/null
+++ b/doc/bugs/gpg_fails_on_Mac_OS_10.9_when_creating_a_new_remote_repository_via_assistant.mdwn
@@ -0,0 +1,55 @@
+### Please describe the problem.
+
+When I use the web app and try to create a remote on a remote server (via ssh connection) the assistant shows a gpg error.
+
+### What steps will reproduce the problem?
+
+1. Start the the web app using git-annex web app
+2. create a local repository
+3. create a new repository on a Remote server (Set up a repository on a remote server using ssh).
+4. provide correct server address, user, port, etc.
+
+Then gpg fails.
+
+### What version of git-annex are you using? On what operating system?
+
+git-annex version: 4.20131106
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV FsEvents XMPP DNS Feeds Quvi TDFA CryptoHash
+key/value backends: SHA256E SHA1E SHA512E SHA224E SHA384E SKEIN256E SKEIN512E SHA256 SHA1 SHA512 SHA224 SHA384 SKEIN256 SKEIN512 WORM URL
+remote types: git gcrypt S3 bup directory rsync web webdav glacier hook
+local repository version: unknown
+default repository version: 3
+supported repository versions: 3 4
+upgrade supported from repository versions: 0 1 2
+
+On Mac OS X 10.9 Mavericks, build 13A603.
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+[2013-11-14 21:03:47 CET] main: starting assistant version 4.20131106
+[2013-11-14 21:03:47 CET] Cronner: You should enable consistency checking to protect your data.
+(Recording state in git...)
+(scanning...) [2013-11-14 21:03:47 CET] Watcher: Performing startup scan
+(started...) [2013-11-14 21:04:47 CET] Cronner: Consistency check in progress
+[2013-11-14 21:05:21 CET] Committer: Adding sunflower.html test.html cindy.css d3.js d3.min.js Accessors.js Essentials.js List.js Namespace.js and 6 other files
+
+(Recording state in git...)
+
+add /Users/ulli/Documents/annex/test.html (checksum...) ok
+### several similar adds removed for privacy reasons.
+
+[2013-11-14 21:05:22 CET] Committer: Committing changes to git
+ok
+(Recording state in git...)
+(Recording state in git...)
+14/Nov/2013:21:21:05 +0100 [Error#yesod-core] user error (gpg ["--quiet","--trust-model","always","--with-colons","--list-secret-keys","--fixed-list-mode"] exited 127) @(yesod-core-1.2.5:Yesod.Core.Class.Yesod ./Yesod/Core/Class/Yesod.hs:485:5)
+
+# End of transcript or log.
+"""]]
+
+> I've had reports from others that gpg works when installing from the
+> bundle. [[done]] --[[Joey]]
diff --git a/doc/bugs/gpg_fails_on_Mac_OS_10.9_when_creating_a_new_remote_repository_via_assistant/comment_1_7b409701c650b55b3472accd70555f16._comment b/doc/bugs/gpg_fails_on_Mac_OS_10.9_when_creating_a_new_remote_repository_via_assistant/comment_1_7b409701c650b55b3472accd70555f16._comment
new file mode 100644
index 000000000..7b1ed7420
--- /dev/null
+++ b/doc/bugs/gpg_fails_on_Mac_OS_10.9_when_creating_a_new_remote_repository_via_assistant/comment_1_7b409701c650b55b3472accd70555f16._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmkXtBdMgE1d9nCz2iBc4f85xh4izZ_auU"
+ nickname="Ulrich"
+ subject="Easy to fix."
+ date="2013-11-14T20:36:17Z"
+ content="""
+Well, this only happens when gpg is not available. Everything works fine after a quick \"brew install gpg\".
+"""]]
diff --git a/doc/bugs/gpg_fails_on_Mac_OS_10.9_when_creating_a_new_remote_repository_via_assistant/comment_2_40b00f7258512677516ec5036b89090f._comment b/doc/bugs/gpg_fails_on_Mac_OS_10.9_when_creating_a_new_remote_repository_via_assistant/comment_2_40b00f7258512677516ec5036b89090f._comment
new file mode 100644
index 000000000..ecc9717d2
--- /dev/null
+++ b/doc/bugs/gpg_fails_on_Mac_OS_10.9_when_creating_a_new_remote_repository_via_assistant/comment_2_40b00f7258512677516ec5036b89090f._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.246"
+ subject="comment 2"
+ date="2013-11-14T22:10:32Z"
+ content="""
+gpg is included in the bundle though:
+
+<pre>
+oberon:tmp joeyh$ /Volumes/git-annex/git-annex.app/Contents/MacOS/runshell
+bash-3.2$ which gpg
+/Volumes/git-annex/git-annex.app/Contents/MacOS/bundle/gpg
+</pre>
+"""]]
diff --git a/doc/bugs/gpg_goes_to_100__37___cpu_on_bad_input_data.mdwn b/doc/bugs/gpg_goes_to_100__37___cpu_on_bad_input_data.mdwn
new file mode 100644
index 000000000..5f36a7cd0
--- /dev/null
+++ b/doc/bugs/gpg_goes_to_100__37___cpu_on_bad_input_data.mdwn
@@ -0,0 +1,18 @@
+### Please describe the problem.
+Bad input data given to gpg will make it lock.
+
+### What steps will reproduce the problem?
+Trying to download gpg encrypted data from remote with bad/incorrect data
+
+### What version of git-annex are you using? On what operating system?
+4.20130501-gd9e288b, on ubuntu 13.04
+
+### Please provide any additional information below.
+Transcript
+http://paste.ubuntu.com/5626517/
+
+Note: The problem is most likely caused by bad data from either the nntp hooks program, or the nntp server itself.
+
+I also have one file with bad data that consistently is NOT a problem for gpg to handle(lines 24-25 of log).
+
+[[!tag moreinfo]]
diff --git a/doc/bugs/gpg_goes_to_100__37___cpu_on_bad_input_data/comment_1_889218fb7c0115b03d9bad0c07296097._comment b/doc/bugs/gpg_goes_to_100__37___cpu_on_bad_input_data/comment_1_889218fb7c0115b03d9bad0c07296097._comment
new file mode 100644
index 000000000..43211bdd8
--- /dev/null
+++ b/doc/bugs/gpg_goes_to_100__37___cpu_on_bad_input_data/comment_1_889218fb7c0115b03d9bad0c07296097._comment
@@ -0,0 +1,36 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-05-06T17:09:58Z"
+ content="""
+What version of gnupg do you have installed?
+
+<pre>
+gpg: block_filter 0x946320: read error (size=12864,a->size=12864)
+gpg: [don't know]: invalid packet (ctb=68)
+gpg: [don't know]: invalid packet (ctb=21)
+gpg: mdc_packet with invalid encoding
+gpg: decryption failed: invalid packet
+gpg: [don't know]: invalid packet (ctb=00)
+gpg: block_filter: pending bytes!
+</pre>
+
+I don't see how git-annex can possibly guard against gpg behaving this way when given bad data. So the best thing to do would be to get a test case file that causes gpg to behave this way, and then I could file a bug on gpg and get it fixed to immediately exit.
+
+I tried to reproduce this by encrypting a 1 mb file with gpg. This yeilded a 1.1 mb file. I then truncated it back to 1 mb, and tried to decrypt it.
+
+[[!format sh \"\"\"
+joey@gnu:~>gpg --decrypt me2.gpg > x
+gpg: encrypted with 1 passphrase
+gpg: block_filter 0x9d6fda0: read error (size=15680,a->size=15680)
+gpg: Problem reading source (8570 bytes remaining)
+gpg: handle plaintext failed: file read error
+gpg: mdc_packet with invalid encoding
+gpg: decryption failed: invalid packet
+gpg: block_filter: pending bytes!
+zsh: exit 2 gpg --decrypt
+\"\"\"]]
+
+gpg exited immediately on error, which is what it should do. So it doesn't seem likely I can guess at a test case file that causes gpg to behave this way. You will need to provide one for me to help.
+"""]]
diff --git a/doc/bugs/gpg_hangs_on_glacier_remote_creation.mdwn b/doc/bugs/gpg_hangs_on_glacier_remote_creation.mdwn
new file mode 100644
index 000000000..b4aaa57ea
--- /dev/null
+++ b/doc/bugs/gpg_hangs_on_glacier_remote_creation.mdwn
@@ -0,0 +1,78 @@
+### Please describe the problem.
+when attempting to create a glacier special remote one of the gpg sub-commands hangs without returning.
+
+### What steps will reproduce the problem?
+I'm not sure what will reproduce this issue. I recently upgraded from the apt-get version of git-annex (version 3) to the cabal version (version 4 shown below), but I'm not sure if that is relevant at all).
+
+### What version of git-annex are you using? On what operating system?
+
+git version: 1.7.9.5
+
+(git annex was installed using cabal)
+[[!format sh """
+$> git-annex version
+git-annex version: 4.20130709
+build flags: Testsuite S3 Inotify DBus
+local repository version: 3
+default repository version: 3
+supported repository versions: 3 4
+upgrade supported from repository versions: 0 1 2
+"""]]
+
+OS version:
+
+12.04.2 LTS, Precise Pangolin
+
+GPG version:
+
+[[!format sh """
+$> gpg --version
+gpg (GnuPG) 1.4.11
+Copyright (C) 2010 Free Software Foundation, Inc.
+License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
+This is free software: you are free to change and redistribute it.
+There is NO WARRANTY, to the extent permitted by law.
+
+Home: ~/.gnupg
+Supported algorithms:
+Pubkey: RSA, RSA-E, RSA-S, ELG-E, DSA
+Cipher: 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH, CAMELLIA128,
+ CAMELLIA192, CAMELLIA256
+Hash: MD5, SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
+Compression: Uncompressed, ZIP, ZLIB, BZIP2
+"""]]
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+$> git annex initremote glacier type=glacier encryption=annex-l1@ggg.local embedcreds=yes vault=some-vault-name --verbose --debug
+[2013-07-20 22:45:13 MDT] read: git ["--git-dir=/home/cantora/annex-l1/.git","--work-tree=/home/cantora/annex-l1","show-ref","git-annex"]
+[2013-07-20 22:45:13 MDT] read: git ["--git-dir=/home/cantora/annex-l1/.git","--work-tree=/home/cantora/annex-l1","show-ref","--hash","refs/heads/git-annex"]
+[2013-07-20 22:45:13 MDT] read: git ["--git-dir=/home/cantora/annex-l1/.git","--work-tree=/home/cantora/annex-l1","log","refs/heads/git-annex..181aa86dfd264557ab73285220d70c67f868b349","--oneline","-n1"]
+[2013-07-20 22:45:13 MDT] read: git ["--git-dir=/home/cantora/annex-l1/.git","--work-tree=/home/cantora/annex-l1","log","refs/heads/git-annex..1dc6e1c4bca2102fc25e86491ab89338750ee1f6","--oneline","-n1"]
+[2013-07-20 22:45:13 MDT] read: git ["--git-dir=/home/cantora/annex-l1/.git","--work-tree=/home/cantora/annex-l1","log","refs/heads/git-annex..b919b83cafeff420d23af24ff7de35b4ff955c8c","--oneline","-n1"]
+[2013-07-20 22:45:13 MDT] chat: git ["--git-dir=/home/cantora/annex-l1/.git","--work-tree=/home/cantora/annex-l1","cat-file","--batch"]
+[2013-07-20 22:45:13 MDT] read: git ["config","--null","--list"]
+initremote glacier (encryption setup) [2013-07-20 22:45:13 MDT] read: gpg ["--batch","--no-tty","--use-agent","--quiet","--trust-model","always","--with-colons","--list-public-keys","annex-l1@ggg.local"]
+[2013-07-20 22:45:13 MDT] read: gpg ["--batch","--no-tty","--use-agent","--quiet","--trust-model","always","--gen-random","--armor","2","512"]
+[2013-07-20 22:47:37 MDT] chat: gpg ["--batch","--no-tty","--use-agent","--quiet","--trust-model","always","--encrypt","--no-encrypt-to","--no-default-recipient","--recipient","DF31708872834ABA"]
+(with gpg key DF31708872834ABA) [2013-07-20 22:47:37 MDT] call: glacier ["--region=us-east-1","vault","create","some-vault-name"]
+[2013-07-20 22:47:38 MDT] call: git ["--git-dir=/home/cantora/annex-l1/.git","--work-tree=/home/cantora/annex-l1","config","remote.glacier.annex-glacier","true"]
+[2013-07-20 22:47:38 MDT] call: git ["--git-dir=/home/cantora/annex-l1/.git","--work-tree=/home/cantora/annex-l1","config","remote.glacier.annex-uuid","a9739087-7860-4ed0-bc38-0b6031b1afd3"]
+(gpg) [2013-07-20 22:47:38 MDT] chat: gpg ["--batch","--no-tty","--use-agent","--quiet","--trust-model","always","--decrypt"]
+[2013-07-20 22:47:38 MDT] chat: gpg ["--batch","--no-tty","--use-agent","--quiet","--trust-model","always","--batch","--passphrase-fd","3","--symmetric","--force-mdc"]
+#at this point it simply waits forever. not sure what it's waiting for, stdin maybe? maybe fd 3 is empty??
+
+#[on a different terminal]
+$> ps ax | grep gpg | grep -v ssh
+ 2024 ? Ss 0:00 /usr/bin/gpg-agent --daemon --sh --write-env-file=/home/cantora/.gnupg/gpg-agent-info-ggg /usr/bin/dbus-launch --exit-with-session gnome-session --session=ubuntu
+ 8341 pts/4 SL+ 0:00 gpg --batch --no-tty --use-agent --quiet --trust-model always --batch --passphrase-fd 3 --symmetric --force-mdc
+ 8652 pts/5 S+ 0:00 grep --color=auto gpg
+
+# End of transcript or log.
+"""]]
+
+> [[done]]; see comments --[[Joey]]
diff --git a/doc/bugs/gpg_hangs_on_glacier_remote_creation/comment_1_41ca74a4e4aaf4f6b012a92677037651._comment b/doc/bugs/gpg_hangs_on_glacier_remote_creation/comment_1_41ca74a4e4aaf4f6b012a92677037651._comment
new file mode 100644
index 000000000..2dae713b0
--- /dev/null
+++ b/doc/bugs/gpg_hangs_on_glacier_remote_creation/comment_1_41ca74a4e4aaf4f6b012a92677037651._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.1.10"
+ subject="comment 1"
+ date="2013-07-22T21:41:01Z"
+ content="""
+I have tried but have not had any luck reproducing this when initializing a glacier remote.
+
+Do you also get this problem if you initialize a special remote of another type, such as the directory special remote, that's encrypted to the same gpg key?
+
+Can you reproduce the hang using the [[/install/Linux_standalone]] tarball?
+
+You should be able to tell which file descriptor gpg is blocking on. Just attach strace to the gpg process, and see what file descriptor it says gpg is reading from (or perhaps writing to). Since git-annex feeds it both a passphrase and data to encrypt, knowing the number of the file descriptor will narrow down the bug's cause.
+"""]]
diff --git a/doc/bugs/gpg_hangs_on_glacier_remote_creation/comment_2_dd11fd25c8bb1f2d7e1292c07abf553e._comment b/doc/bugs/gpg_hangs_on_glacier_remote_creation/comment_2_dd11fd25c8bb1f2d7e1292c07abf553e._comment
new file mode 100644
index 000000000..7749bed1e
--- /dev/null
+++ b/doc/bugs/gpg_hangs_on_glacier_remote_creation/comment_2_dd11fd25c8bb1f2d7e1292c07abf553e._comment
@@ -0,0 +1,591 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkiAsTXFXZbLE8iyy6yDtvz4MPFbzsk3c0"
+ nickname="Tony"
+ subject="strace of gpg process"
+ date="2013-07-24T00:02:22Z"
+ content="""
+Hello, here is some trace information on the gpg process, I hope it helps.
+
+the initremote command used:
+[[!format sh \"\"\"
+$> strace -o /tmp/git-annex.trace -e trace=file -e trace=read -f git annex initremote glacier type=glacier encryption=testA@ggg.local embedcreds=yes vault=test-vault --verbose --debug
+[2013-07-23 15:36:06 MDT] read: git [\"--git-dir=/home/cantora/annex-test/.git\",\"--work-tree=/home/cantora/annex-test\",\"show-ref\",\"git-annex\"]
+[2013-07-23 15:36:06 MDT] read: git [\"--git-dir=/home/cantora/annex-test/.git\",\"--work-tree=/home/cantora/annex-test\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+[2013-07-23 15:36:06 MDT] read: git [\"--git-dir=/home/cantora/annex-test/.git\",\"--work-tree=/home/cantora/annex-test\",\"log\",\"refs/heads/git-annex..55754a54c5777336d594af0a173805d150deb828\",\"--oneline\",\"-n1\"]
+[2013-07-23 15:36:06 MDT] chat: git [\"--git-dir=/home/cantora/annex-test/.git\",\"--work-tree=/home/cantora/annex-test\",\"cat-file\",\"--batch\"]
+initremote glacier (encryption setup) [2013-07-23 15:36:07 MDT] read: gpg [\"--batch\",\"--no-tty\",\"--use-agent\",\"--quiet\",\"--trust-model\",\"always\",\"--with-colons\",\"--list-public-keys\",\"testA@ggg.local\"]
+[2013-07-23 15:36:07 MDT] read: gpg [\"--batch\",\"--no-tty\",\"--use-agent\",\"--quiet\",\"--trust-model\",\"always\",\"--gen-random\",\"--armor\",\"2\",\"512\"]
+[2013-07-23 15:39:12 MDT] chat: gpg [\"--batch\",\"--no-tty\",\"--use-agent\",\"--quiet\",\"--trust-model\",\"always\",\"--encrypt\",\"--no-encrypt-to\",\"--no-default-recipient\",\"--recipient\",\"05E4CF57CBCAD77C\"]
+(with gpg key 05E4CF57CBCAD77C) [2013-07-23 15:39:12 MDT] call: glacier [\"--region=us-east-1\",\"vault\",\"create\",\"test-vault\"]
+[2013-07-23 15:39:14 MDT] call: git [\"--git-dir=/home/cantora/annex-test/.git\",\"--work-tree=/home/cantora/annex-test\",\"config\",\"remote.glacier.annex-glacier\",\"true\"]
+[2013-07-23 15:39:14 MDT] call: git [\"--git-dir=/home/cantora/annex-test/.git\",\"--work-tree=/home/cantora/annex-test\",\"config\",\"remote.glacier.annex-uuid\",\"397411b1-30be-4bdc-b3dd-6ab0d8f8ae8b\"]
+(gpg) [2013-07-23 15:39:14 MDT] chat: gpg [\"--batch\",\"--no-tty\",\"--use-agent\",\"--quiet\",\"--trust-model\",\"always\",\"--decrypt\"]
+[2013-07-23 15:39:14 MDT] chat: gpg [\"--batch\",\"--no-tty\",\"--use-agent\",\"--quiet\",\"--trust-model\",\"always\",\"--batch\",\"--passphrase-fd\",\"3\",\"--symmetric\",\"--force-mdc\"]
+^C
+gpg: Interrupt caught ... exiting
+\"\"\"]]
+
+the hanging gpg process:
+[[!format sh \"\"\"
+$> ps ax | grep gpg | grep -v ssh
+ 2017 ? Ss 0:02 /usr/bin/gpg-agent --daemon --sh --write-env-file=/home/cantora/.gnupg/gpg-agent-info-ggg /usr/bin/dbus-launch --exit-with-session gnome-session --session=ubuntu
+ 8268 pts/3 SL+ 0:00 gpg --batch --no-tty --use-agent --quiet --trust-model always --batch --passphrase-fd 3 --symmetric --force-mdc
+ 8357 pts/4 S+ 0:00 grep --color=auto gpg
+\"\"\"]]
+
+and the content of the trace (only the end where the gpg process is created):
+
+[[!format txt \"\"\"
+[...]
+8265 read(5, \"[core]\n\trepositoryformatversion \"..., 4096) = 199
+8265 read(5, \"\", 4096) = 0
+8245 --- SIGVTALRM (Virtual timer expired) @ 0 (0) ---
+8245 --- SIGCHLD (Child exited) @ 0 (0) ---
+8245 --- SIGVTALRM (Virtual timer expired) @ 0 (0) ---
+8245 --- SIGVTALRM (Virtual timer expired) @ 0 (0) ---
+8266 read(3, \"\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\2209\0\0\0\0\0\0\"..., 832) = 832
+8266 read(3, \"\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P \0\0\0\0\0\0\"..., 832) = 832
+8266 read(3, \"\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260\26\0\0\0\0\0\0\"..., 832) = 832
+8266 read(3, \"\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\200\\"\1\0\0\0\0\0\"..., 832) = 832
+8266 read(3, \"\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\340\r\0\0\0\0\0\0\"..., 832) = 832
+8266 read(3, \"\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260\25\0\0\0\0\0\0\"..., 832) = 832
+8266 read(3, \"\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\200\30\2\0\0\0\0\0\"..., 832) = 832
+8245 --- SIGVTALRM (Virtual timer expired) @ 0 (0) ---
+8266 read(3, \"\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\320\301\0\0\0\0\0\0\"..., 832) = 832
+8266 read(3, \"# Options for GnuPG\n# Copyright \"..., 4096) = 4096
+8266 read(3, \"ost servers (with the notable ex\"..., 4096) = 4096
+8266 read(3, \"t during gpg-agent startup.\n# In\"..., 4096) = 1206
+8266 read(3, \"\", 4096) = 0
+8266 read(3, \"\225\7>\4Q\340r!\1\20\0\313B\370D\25\275g\317\270\3>\356\243H\230w\303\252\303\2712\"..., 4096) = 4096
+8266 read(3, \"\231\2\r\4M\370\317\334\1\20\0\223\337X\257\366/\t\307\376\214\207,\26\233+R\31j#K\266\"..., 4096) = 4096
+8266 read(0, <unfinished ...>
+8245 --- SIGVTALRM (Virtual timer expired) @ 0 (0) ---
+8245 --- SIGVTALRM (Virtual timer expired) @ 0 (0) ---
+8266 <... read resumed> \"\205\1\f\3Xp+\246\227\277\336\3\1\7\376 B3K\224\352T\373$\30\246\f?h\272\266\21\"..., 8192) = 889
+8266 read(3, <unfinished ...>
+8245 read(7, <unfinished ...>
+8266 <... read resumed> \"\225\7>\4Q\340r!\1\20\0\313B\370D\25\275g\317\270\3>\356\243H\230w\303\252\303\2712\"..., 8192) = 8192
+8245 <... read resumed> 0x7fbc17ead010, 8096) = -1 EAGAIN (Resource temporarily unavailable)
+8266 read(3, \": \351R\326\342Y\325Sk\3~\31X\252d\24\357{+\17\237m\35\273\201\250T\10\200n\226\"..., 8192) = 4129
+8266 read(3, \"\225\7>\4Q\340r!\1\20\0\313B\370D\25\275g\317\270\3>\356\243H\230w\303\252\303\2712\"..., 8192) = 8192
+8245 --- SIGVTALRM (Virtual timer expired) @ 0 (0) ---
+8266 read(3, \": \351R\326\342Y\325Sk\3~\31X\252d\24\357{+\17\237m\35\273\201\250T\10\200n\226\"..., 8192) = 4129
+8266 read(4, \"\225\3\276\4Q\354\214U\1\10\0\351 NjDf\31\305\16~$\272i#\321\325\10\276\307\273{\"..., 8192) = 2560
+8266 read(4, \"\", 8192) = 0
+8266 read(5, \"\231\2\r\4M\370\317\334\1\20\0\223\337X\257\366/\t\307\376\214\207,\26\233+R\31j#K\266\"..., 8192) = 7836
+8266 read(6, \"\231\1\r\4Q\354\214U\1\10\0\351 NjDf\31\305\16~$\272i#\321\325\10\276\307\273{\"..., 8192) = 1182
+8266 read(6, \"\", 8192) = 0
+8266 read(5, \"\231\2\r\4M\370\317\334\1\20\0\223\337X\257\366/\t\307\376\214\207,\26\233+R\31j#K\266\"..., 8192) = 7836
+8266 read(6, \"\231\1\r\4Q\354\214U\1\10\0\351 NjDf\31\305\16~$\272i#\321\325\10\276\307\273{\"..., 8192) = 1182
+8266 read(6, \"\", 8192) = 0
+8266 read(7, \"OK your orders please\n\", 1002) = 22
+8266 read(7, \"OK \n\", 1002) = 4
+8266 read(7, \"OK \n\", 1002) = 4
+8266 read(7, \"OK \n\", 1002) = 4
+8266 read(7, \"OK \n\", 1002) = 4
+8266 read(7, \"OK \n\", 1002) = 4
+8266 read(8, \"# Locale name alias data base.\n#\"..., 4096) = 2570
+8266 read(8, \"\", 4096) = 0
+8266 read(8, \"TZif2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\0\0\0\4\0\0\0\0\"..., 4096) = 2427
+8266 read(8, \"TZif2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\5\0\0\0\5\0\0\0\0\"..., 4096) = 1550
+8245 --- SIGVTALRM (Virtual timer expired) @ 0 (0) ---
+8266 read(7, \"OK 616e746f7831616e746f78\n\", 1002) = 26
+8245 --- SIGVTALRM (Virtual timer expired) @ 0 (0) ---
+8245 --- SIGVTALRM (Virtual timer expired) @ 0 (0) ---
+8245 --- SIGVTALRM (Virtual timer expired) @ 0 (0) ---
+8266 read(6, \"\231\2\r\4M\370\317\334\1\20\0\223\337X\257\366/\t\307\376\214\207,\26\233+R\31j#K\266\"..., 8192) = 7836
+8266 read(5, \"\231\1\r\4Q\354\214U\1\10\0\351 NjDf\31\305\16~$\272i#\321\325\10\276\307\273{\"..., 8192) = 1182
+8266 read(5, \"\", 8192) = 0
+8266 read(0, \"\", 8192) = 0
+8245 read(7, \"hssHvXB6YTHPFmwu0uliVVZlm+olG/Do\"..., 8096) = 685
+8245 read(7, 0x7fbc17ead010, 8096) = -1 EAGAIN (Resource temporarily unavailable)
+8245 --- SIGCHLD (Child exited) @ 0 (0) ---
+8245 read(7, \"\", 8096) = 0
+8245 --- SIGVTALRM (Virtual timer expired) @ 0 (0) ---
+8245 --- SIGVTALRM (Virtual timer expired) @ 0 (0) ---
+8245 --- SIGVTALRM (Virtual timer expired) @ 0 (0) ---
+8268 read(4, \"\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\2209\0\0\0\0\0\0\"..., 832) = 832
+8268 read(4, \"\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P \0\0\0\0\0\0\"..., 832) = 832
+8268 read(4, \"\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260\26\0\0\0\0\0\0\"..., 832) = 832
+8268 read(4, \"\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\200\\"\1\0\0\0\0\0\"..., 832) = 832
+8268 read(4, \"\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\340\r\0\0\0\0\0\0\"..., 832) = 832
+8268 read(4, \"\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260\25\0\0\0\0\0\0\"..., 832) = 832
+8268 read(4, \"\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\200\30\2\0\0\0\0\0\"..., 832) = 832
+8268 read(4, \"\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\320\301\0\0\0\0\0\0\"..., 832) = 832
+8268 read(4, \"# Options for GnuPG\n# Copyright \"..., 4096) = 4096
+8268 read(4, \"ost servers (with the notable ex\"..., 4096) = 4096
+8268 read(4, \"t during gpg-agent startup.\n# In\"..., 4096) = 1206
+8268 read(4, \"\", 4096) = 0
+8268 read(4, \"\231\2\r\4M\370\317\334\1\20\0\223\337X\257\366/\t\307\376\214\207,\26\233+R\31j#K\266\"..., 4096) = 4096
+8268 read(3, \"0\", 1) = 1
+8268 read(3, \"5\", 1) = 1
+8268 read(3, \"B\", 1) = 1
+8268 read(3, \"5\", 1) = 1
+8268 read(3, \"7\", 1) = 1
+8268 read(3, \"u\", 1) = 1
+8268 read(3, \"N\", 1) = 1
+8268 read(3, \"X\", 1) = 1
+8268 read(3, \"N\", 1) = 1
+8268 read(3, \"X\", 1) = 1
+8268 read(3, \"u\", 1) = 1
+8268 read(3, \"R\", 1) = 1
+8268 read(3, \"D\", 1) = 1
+8268 read(3, \"n\", 1) = 1
+8268 read(3, \"f\", 1) = 1
+8268 read(3, \"T\", 1) = 1
+8268 read(3, \"h\", 1) = 1
+8268 read(3, \"d\", 1) = 1
+8268 read(3, \"Q\", 1) = 1
+8268 read(3, \"t\", 1) = 1
+8268 read(3, \"k\", 1) = 1
+8268 read(3, \"1\", 1) = 1
+8268 read(3, \"6\", 1) = 1
+8268 read(3, \"F\", 1) = 1
+8268 read(3, \"7\", 1) = 1
+8268 read(3, \"K\", 1) = 1
+8268 read(3, \"/\", 1) = 1
+8268 read(3, \"o\", 1) = 1
+8268 read(3, \"v\", 1) = 1
+8268 read(3, \"A\", 1) = 1
+8268 read(3, \"8\", 1) = 1
+8268 read(3, \"8\", 1) = 1
+8268 read(3, \"5\", 1) = 1
+8268 read(3, \"Y\", 1) = 1
+8268 read(3, \"6\", 1) = 1
+8268 read(3, \"u\", 1) = 1
+8268 read(3, \"R\", 1) = 1
+8268 read(3, \"V\", 1) = 1
+8268 read(3, \"k\", 1) = 1
+8268 read(3, \"M\", 1) = 1
+8268 read(3, \"n\", 1) = 1
+8268 read(3, \"a\", 1) = 1
+8268 read(3, \"f\", 1) = 1
+8268 read(3, \"u\", 1) = 1
+8268 read(3, \"Q\", 1) = 1
+8268 read(3, \"o\", 1) = 1
+8268 read(3, \"9\", 1) = 1
+8268 read(3, \"E\", 1) = 1
+8268 read(3, \"u\", 1) = 1
+8268 read(3, \"9\", 1) = 1
+8268 read(3, \"N\", 1) = 1
+8268 read(3, \"l\", 1) = 1
+8268 read(3, \"q\", 1) = 1
+8268 read(3, \"+\", 1) = 1
+8268 read(3, \"f\", 1) = 1
+8268 read(3, \"3\", 1) = 1
+8268 read(3, \"3\", 1) = 1
+8268 read(3, \"v\", 1) = 1
+8268 read(3, \"t\", 1) = 1
+8268 read(3, \"K\", 1) = 1
+8268 read(3, \"c\", 1) = 1
+8268 read(3, \"b\", 1) = 1
+8268 read(3, \"a\", 1) = 1
+8268 read(3, \"8\", 1) = 1
+8268 read(3, \"q\", 1) = 1
+8268 read(3, \"4\", 1) = 1
+8268 read(3, \"N\", 1) = 1
+8268 read(3, \"y\", 1) = 1
+8268 read(3, \"b\", 1) = 1
+8268 read(3, \"i\", 1) = 1
+8268 read(3, \"k\", 1) = 1
+8268 read(3, \"n\", 1) = 1
+8268 read(3, \"i\", 1) = 1
+8268 read(3, \"A\", 1) = 1
+8268 read(3, \"N\", 1) = 1
+8268 read(3, \"V\", 1) = 1
+8268 read(3, \"L\", 1) = 1
+8268 read(3, \"X\", 1) = 1
+8268 read(3, \"Q\", 1) = 1
+8268 read(3, \"y\", 1) = 1
+8268 read(3, \"L\", 1) = 1
+8268 read(3, \"6\", 1) = 1
+8268 read(3, \"K\", 1) = 1
+8268 read(3, \"C\", 1) = 1
+8268 read(3, \"d\", 1) = 1
+8268 read(3, \"d\", 1) = 1
+8268 read(3, \"C\", 1) = 1
+8268 read(3, \"3\", 1) = 1
+8268 read(3, \"d\", 1) = 1
+8268 read(3, \"0\", 1) = 1
+8268 read(3, \"Q\", 1) = 1
+8268 read(3, \"X\", 1) = 1
+8268 read(3, \"c\", 1) = 1
+8268 read(3, \"T\", 1) = 1
+8268 read(3, \"+\", 1) = 1
+8268 read(3, \"a\", 1) = 1
+8268 read(3, \"u\", 1) = 1
+8268 read(3, \"A\", 1) = 1
+8268 read(3, \"h\", 1) = 1
+8268 read(3, \"G\", 1) = 1
+8268 read(3, \"q\", 1) = 1
+8268 read(3, \"1\", 1) = 1
+8268 read(3, \"v\", 1) = 1
+8268 read(3, \"L\", 1) = 1
+8268 read(3, \"4\", 1) = 1
+8268 read(3, \"o\", 1) = 1
+8268 read(3, \"T\", 1) = 1
+8268 read(3, \"Z\", 1) = 1
+8268 read(3, \"l\", 1) = 1
+8268 read(3, \"5\", 1) = 1
+8268 read(3, \"L\", 1) = 1
+8268 read(3, \"j\", 1) = 1
+8268 read(3, \"W\", 1) = 1
+8268 read(3, \"y\", 1) = 1
+8268 read(3, \"i\", 1) = 1
+8268 read(3, \"l\", 1) = 1
+8268 read(3, \"r\", 1) = 1
+8268 read(3, \"5\", 1) = 1
+8268 read(3, \"m\", 1) = 1
+8268 read(3, \"G\", 1) = 1
+8268 read(3, \"b\", 1) = 1
+8268 read(3, \"0\", 1) = 1
+8268 read(3, \"v\", 1) = 1
+8268 read(3, \"9\", 1) = 1
+8268 read(3, \"U\", 1) = 1
+8268 read(3, \"p\", 1) = 1
+8268 read(3, \"F\", 1) = 1
+8268 read(3, \"R\", 1) = 1
+8268 read(3, \"c\", 1) = 1
+8268 read(3, \"/\", 1) = 1
+8268 read(3, \"+\", 1) = 1
+8268 read(3, \"F\", 1) = 1
+8268 read(3, \"4\", 1) = 1
+8268 read(3, \"g\", 1) = 1
+8268 read(3, \"G\", 1) = 1
+8268 read(3, \"E\", 1) = 1
+8268 read(3, \"D\", 1) = 1
+8268 read(3, \"E\", 1) = 1
+8268 read(3, \"t\", 1) = 1
+8268 read(3, \"B\", 1) = 1
+8268 read(3, \"z\", 1) = 1
+8268 read(3, \"q\", 1) = 1
+8268 read(3, \"a\", 1) = 1
+8268 read(3, \"u\", 1) = 1
+8268 read(3, \"9\", 1) = 1
+8268 read(3, \"S\", 1) = 1
+8268 read(3, \"W\", 1) = 1
+8268 read(3, \"2\", 1) = 1
+8268 read(3, \"r\", 1) = 1
+8268 read(3, \"E\", 1) = 1
+8268 read(3, \"2\", 1) = 1
+8268 read(3, \"d\", 1) = 1
+8268 read(3, \"j\", 1) = 1
+8268 read(3, \"T\", 1) = 1
+8268 read(3, \"D\", 1) = 1
+8268 read(3, \"w\", 1) = 1
+8268 read(3, \"R\", 1) = 1
+8268 read(3, \"1\", 1) = 1
+8268 read(3, \"d\", 1) = 1
+8268 read(3, \"j\", 1) = 1
+8268 read(3, \"D\", 1) = 1
+8268 read(3, \"a\", 1) = 1
+8268 read(3, \"Y\", 1) = 1
+8268 read(3, \"b\", 1) = 1
+8268 read(3, \"f\", 1) = 1
+8268 read(3, \"v\", 1) = 1
+8268 read(3, \"x\", 1) = 1
+8268 read(3, \"g\", 1) = 1
+8268 read(3, \"L\", 1) = 1
+8268 read(3, \"E\", 1) = 1
+8268 read(3, \"V\", 1) = 1
+8268 read(3, \"m\", 1) = 1
+8268 read(3, \"+\", 1) = 1
+8268 read(3, \"U\", 1) = 1
+8268 read(3, \"K\", 1) = 1
+8268 read(3, \"p\", 1) = 1
+8268 read(3, \"e\", 1) = 1
+8268 read(3, \"l\", 1) = 1
+8268 read(3, \"R\", 1) = 1
+8268 read(3, \"4\", 1) = 1
+8268 read(3, \"Y\", 1) = 1
+8268 read(3, \"C\", 1) = 1
+8268 read(3, \"w\", 1) = 1
+8268 read(3, \"o\", 1) = 1
+8268 read(3, \"4\", 1) = 1
+8268 read(3, \"c\", 1) = 1
+8268 read(3, \"C\", 1) = 1
+8268 read(3, \"i\", 1) = 1
+8268 read(3, \"U\", 1) = 1
+8268 read(3, \"q\", 1) = 1
+8268 read(3, \"A\", 1) = 1
+8268 read(3, \"b\", 1) = 1
+8268 read(3, \"K\", 1) = 1
+8268 read(3, \"p\", 1) = 1
+8268 read(3, \"9\", 1) = 1
+8268 read(3, \"T\", 1) = 1
+8268 read(3, \"/\", 1) = 1
+8268 read(3, \"2\", 1) = 1
+8268 read(3, \"R\", 1) = 1
+8268 read(3, \"s\", 1) = 1
+8268 read(3, \"O\", 1) = 1
+8268 read(3, \"P\", 1) = 1
+8268 read(3, \"L\", 1) = 1
+8268 read(3, \"a\", 1) = 1
+8268 read(3, \"e\", 1) = 1
+8268 read(3, \"L\", 1) = 1
+8268 read(3, \"M\", 1) = 1
+8268 read(3, \"N\", 1) = 1
+8268 read(3, \"I\", 1) = 1
+8268 read(3, \"h\", 1) = 1
+8268 read(3, \"T\", 1) = 1
+8268 read(3, \"c\", 1) = 1
+8268 read(3, \"E\", 1) = 1
+8268 read(3, \"w\", 1) = 1
+8268 read(3, \"D\", 1) = 1
+8268 read(3, \"e\", 1) = 1
+8268 read(3, \"O\", 1) = 1
+8268 read(3, \"g\", 1) = 1
+8268 read(3, \"c\", 1) = 1
+8268 read(3, \"M\", 1) = 1
+8268 read(3, \"+\", 1) = 1
+8268 read(3, \"n\", 1) = 1
+8268 read(3, \"U\", 1) = 1
+8268 read(3, \"C\", 1) = 1
+8268 read(3, \"O\", 1) = 1
+8268 read(3, \"H\", 1) = 1
+8268 read(3, \"I\", 1) = 1
+8268 read(3, \"w\", 1) = 1
+8268 read(3, \"h\", 1) = 1
+8268 read(3, \"I\", 1) = 1
+8268 read(3, \"Z\", 1) = 1
+8268 read(3, \"W\", 1) = 1
+8268 read(3, \"c\", 1) = 1
+8268 read(3, \"T\", 1) = 1
+8268 read(3, \"1\", 1) = 1
+8268 read(3, \"n\", 1) = 1
+8268 read(3, \"p\", 1) = 1
+8268 read(3, \"Y\", 1) = 1
+8268 read(3, \"+\", 1) = 1
+8268 read(3, \"U\", 1) = 1
+8268 read(3, \"9\", 1) = 1
+8268 read(3, \"H\", 1) = 1
+8268 read(3, \"N\", 1) = 1
+8268 read(3, \"g\", 1) = 1
+8268 read(3, \"D\", 1) = 1
+8268 read(3, \"G\", 1) = 1
+8268 read(3, \"l\", 1) = 1
+8268 read(3, \"5\", 1) = 1
+8268 read(3, \"B\", 1) = 1
+8268 read(3, \"m\", 1) = 1
+8268 read(3, \"V\", 1) = 1
+8268 read(3, \"w\", 1) = 1
+8268 read(3, \"Q\", 1) = 1
+8268 read(3, \"d\", 1) = 1
+8268 read(3, \"B\", 1) = 1
+8268 read(3, \"r\", 1) = 1
+8268 read(3, \"L\", 1) = 1
+8268 read(3, \"n\", 1) = 1
+8268 read(3, \"f\", 1) = 1
+8268 read(3, \"s\", 1) = 1
+8268 read(3, \"N\", 1) = 1
+8268 read(3, \"X\", 1) = 1
+8268 read(3, \"+\", 1) = 1
+8268 read(3, \"m\", 1) = 1
+8268 read(3, \"A\", 1) = 1
+8268 read(3, \"f\", 1) = 1
+8268 read(3, \"t\", 1) = 1
+8268 read(3, \"X\", 1) = 1
+8268 read(3, \"S\", 1) = 1
+8268 read(3, \"R\", 1) = 1
+8268 read(3, \"+\", 1) = 1
+8268 read(3, \"n\", 1) = 1
+8268 read(3, \"N\", 1) = 1
+8268 read(3, \"U\", 1) = 1
+8268 read(3, \"S\", 1) = 1
+8268 read(3, \"v\", 1) = 1
+8268 read(3, \"i\", 1) = 1
+8268 read(3, \"Z\", 1) = 1
+8268 read(3, \"S\", 1) = 1
+8268 read(3, \"N\", 1) = 1
+8268 read(3, \"5\", 1) = 1
+8268 read(3, \"L\", 1) = 1
+8268 read(3, \"8\", 1) = 1
+8268 read(3, \"3\", 1) = 1
+8268 read(3, \"K\", 1) = 1
+8268 read(3, \"v\", 1) = 1
+8268 read(3, \"O\", 1) = 1
+8268 read(3, \"x\", 1) = 1
+8268 read(3, \"q\", 1) = 1
+8268 read(3, \"v\", 1) = 1
+8268 read(3, \"5\", 1) = 1
+8268 read(3, \"6\", 1) = 1
+8268 read(3, \"d\", 1) = 1
+8268 read(3, \"Y\", 1) = 1
+8268 read(3, \"Z\", 1) = 1
+8268 read(3, \"l\", 1) = 1
+8268 read(3, \"h\", 1) = 1
+8268 read(3, \"V\", 1) = 1
+8268 read(3, \"a\", 1) = 1
+8268 read(3, \"l\", 1) = 1
+8268 read(3, \"d\", 1) = 1
+8268 read(3, \"z\", 1) = 1
+8268 read(3, \"P\", 1) = 1
+8268 read(3, \"y\", 1) = 1
+8268 read(3, \"A\", 1) = 1
+8268 read(3, \"f\", 1) = 1
+8268 read(3, \"2\", 1) = 1
+8268 read(3, \"0\", 1) = 1
+8268 read(3, \"n\", 1) = 1
+8268 read(3, \"U\", 1) = 1
+8268 read(3, \"P\", 1) = 1
+8268 read(3, \"0\", 1) = 1
+8268 read(3, \"j\", 1) = 1
+8268 read(3, \"A\", 1) = 1
+8268 read(3, \"F\", 1) = 1
+8268 read(3, \"g\", 1) = 1
+8268 read(3, \"4\", 1) = 1
+8268 read(3, \"N\", 1) = 1
+8268 read(3, \"f\", 1) = 1
+8268 read(3, \"B\", 1) = 1
+8268 read(3, \"C\", 1) = 1
+8268 read(3, \"J\", 1) = 1
+8268 read(3, \"A\", 1) = 1
+8268 read(3, \"T\", 1) = 1
+8268 read(3, \"H\", 1) = 1
+8268 read(3, \"x\", 1) = 1
+8268 read(3, \"E\", 1) = 1
+8268 read(3, \"k\", 1) = 1
+8268 read(3, \"o\", 1) = 1
+8268 read(3, \"Y\", 1) = 1
+8268 read(3, \"L\", 1) = 1
+8268 read(3, \"X\", 1) = 1
+8268 read(3, \"X\", 1) = 1
+8268 read(3, \"/\", 1) = 1
+8268 read(3, \"e\", 1) = 1
+8268 read(3, \"j\", 1) = 1
+8268 read(3, \"g\", 1) = 1
+8268 read(3, \"8\", 1) = 1
+8268 read(3, \"j\", 1) = 1
+8268 read(3, \"o\", 1) = 1
+8268 read(3, \"E\", 1) = 1
+8268 read(3, \"h\", 1) = 1
+8268 read(3, \"w\", 1) = 1
+8268 read(3, \"f\", 1) = 1
+8268 read(3, \"C\", 1) = 1
+8268 read(3, \"/\", 1) = 1
+8268 read(3, \"0\", 1) = 1
+8268 read(3, \"I\", 1) = 1
+8268 read(3, \"r\", 1) = 1
+8268 read(3, \"r\", 1) = 1
+8268 read(3, \"5\", 1) = 1
+8268 read(3, \"p\", 1) = 1
+8268 read(3, \"w\", 1) = 1
+8268 read(3, \"I\", 1) = 1
+8268 read(3, \"c\", 1) = 1
+8268 read(3, \"H\", 1) = 1
+8268 read(3, \"S\", 1) = 1
+8268 read(3, \"C\", 1) = 1
+8268 read(3, \"d\", 1) = 1
+8268 read(3, \"l\", 1) = 1
+8268 read(3, \"Y\", 1) = 1
+8268 read(3, \"W\", 1) = 1
+8268 read(3, \"N\", 1) = 1
+8268 read(3, \"E\", 1) = 1
+8268 read(3, \"U\", 1) = 1
+8268 read(3, \"+\", 1) = 1
+8268 read(3, \"O\", 1) = 1
+8268 read(3, \"s\", 1) = 1
+8268 read(3, \"Y\", 1) = 1
+8268 read(3, \"m\", 1) = 1
+8268 read(3, \"+\", 1) = 1
+8268 read(3, \"f\", 1) = 1
+8268 read(3, \"Z\", 1) = 1
+8268 read(3, \"q\", 1) = 1
+8268 read(3, \"l\", 1) = 1
+8268 read(3, \"2\", 1) = 1
+8268 read(3, \"V\", 1) = 1
+8268 read(3, \"f\", 1) = 1
+8268 read(3, \"h\", 1) = 1
+8268 read(3, \"E\", 1) = 1
+8268 read(3, \"j\", 1) = 1
+8268 read(3, \"K\", 1) = 1
+8268 read(3, \"I\", 1) = 1
+8268 read(3, \"O\", 1) = 1
+8268 read(3, \"9\", 1) = 1
+8268 read(3, \"B\", 1) = 1
+8268 read(3, \"y\", 1) = 1
+8268 read(3, \"T\", 1) = 1
+8268 read(3, \"N\", 1) = 1
+8268 read(3, \"V\", 1) = 1
+8268 read(3, \"L\", 1) = 1
+8268 read(3, \"A\", 1) = 1
+8268 read(3, \"W\", 1) = 1
+8268 read(3, \"u\", 1) = 1
+8268 read(3, \"0\", 1) = 1
+8268 read(3, \"s\", 1) = 1
+8268 read(3, \"6\", 1) = 1
+8268 read(3, \"k\", 1) = 1
+8268 read(3, \"7\", 1) = 1
+8268 read(3, \"U\", 1) = 1
+8268 read(3, \"0\", 1) = 1
+8268 read(3, \"j\", 1) = 1
+8268 read(3, \"k\", 1) = 1
+8268 read(3, \"M\", 1) = 1
+8268 read(3, \"k\", 1) = 1
+8268 read(3, \"y\", 1) = 1
+8268 read(3, \"R\", 1) = 1
+8268 read(3, \"3\", 1) = 1
+8268 read(3, \"a\", 1) = 1
+8268 read(3, \"m\", 1) = 1
+8268 read(3, \"J\", 1) = 1
+8268 read(3, \"0\", 1) = 1
+8268 read(3, \"a\", 1) = 1
+8268 read(3, \"A\", 1) = 1
+8268 read(3, \"g\", 1) = 1
+8268 read(3, \"t\", 1) = 1
+8268 read(3, \"z\", 1) = 1
+8268 read(3, \"Y\", 1) = 1
+8268 read(3, \"l\", 1) = 1
+8268 read(3, \"F\", 1) = 1
+8268 read(3, \"L\", 1) = 1
+8268 read(3, \"S\", 1) = 1
+8268 read(3, \"J\", 1) = 1
+8268 read(3, \"Q\", 1) = 1
+8268 read(3, \"z\", 1) = 1
+8268 read(3, \"6\", 1) = 1
+8268 read(3, \"k\", 1) = 1
+8268 read(3, \"=\", 1) = 1
+8268 read(3, \"\n\", 1) = 1
+8268 read(4, \"q\224R\236\341\264\336\23\315FTD\341\253\372\6o\206\326\376\243\326\34L\1\245;\tb\361v\\\"..., 600) = 600
+8268 read(4, \"\2548\332\257\334\237\343\354\23\224\377\377\302\264\352\21\", 16) = 16
+8268 read(0, 0x1911620, 8192) = ? ERESTARTSYS (To be restarted)
+8250 <... read resumed> 0x7fb8e76a4000, 4096) = ? ERESTARTSYS (To be restarted)
+8268 --- SIGINT (Interrupt) @ 0 (0) ---
+8250 --- SIGINT (Interrupt) @ 0 (0) ---
+8268 --- SIGINT (Interrupt) @ 0 (0) ---
+8245 --- SIGINT (Interrupt) @ 0 (0) ---
+8244 --- SIGINT (Interrupt) @ 0 (0) ---
+8244 --- SIGINT (Interrupt) @ 0 (0) ---
+8244 +++ killed by SIGINT +++
+
+\"\"\"]]
+
+So it looks like its waiting on fd 0.
+
+Also, here is what happens when I create a directory special remote with encryption:
+[[!format sh \"\"\"
+$> git annex initremote test-remote type=directory directory=/tmp/test-remote encryption=testA@ggg.local --verbose --debug
+[2013-07-23 16:07:10 MDT] read: git [\"--git-dir=/home/cantora/annex-test/.git\",\"--work-tree=/home/cantora/annex-test\",\"show-ref\",\"git-annex\"]
+[2013-07-23 16:07:10 MDT] read: git [\"--git-dir=/home/cantora/annex-test/.git\",\"--work-tree=/home/cantora/annex-test\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+[2013-07-23 16:07:10 MDT] read: git [\"--git-dir=/home/cantora/annex-test/.git\",\"--work-tree=/home/cantora/annex-test\",\"log\",\"refs/heads/git-annex..27b816334be0c912ae8a4e3811fda0db397974c1\",\"--oneline\",\"-n1\"]
+[2013-07-23 16:07:10 MDT] chat: git [\"--git-dir=/home/cantora/annex-test/.git\",\"--work-tree=/home/cantora/annex-test\",\"cat-file\",\"--batch\"]
+initremote test-remote (encryption setup) [2013-07-23 16:07:10 MDT] read: gpg [\"--batch\",\"--no-tty\",\"--use-agent\",\"--quiet\",\"--trust-model\",\"always\",\"--with-colons\",\"--list-public-keys\",\"testA@ggg.local\"]
+[2013-07-23 16:07:10 MDT] read: gpg [\"--batch\",\"--no-tty\",\"--use-agent\",\"--quiet\",\"--trust-model\",\"always\",\"--gen-random\",\"--armor\",\"2\",\"512\"]
+[2013-07-23 16:10:43 MDT] chat: gpg [\"--batch\",\"--no-tty\",\"--use-agent\",\"--quiet\",\"--trust-model\",\"always\",\"--encrypt\",\"--no-encrypt-to\",\"--no-default-recipient\",\"--recipient\",\"05E4CF57CBCAD77C\"]
+(with gpg key 05E4CF57CBCAD77C) [2013-07-23 16:10:43 MDT] call: git [\"--git-dir=/home/cantora/annex-test/.git\",\"--work-tree=/home/cantora/annex-test\",\"config\",\"remote.test-remote.annex-directory\",\"/tmp/test-remote\"]
+[2013-07-23 16:10:43 MDT] call: git [\"--git-dir=/home/cantora/annex-test/.git\",\"--work-tree=/home/cantora/annex-test\",\"config\",\"remote.test-remote.annex-uuid\",\"c3fdb6be-2a3b-4bc0-a4df-0fbf7216fd85\"]
+ok
+[2013-07-23 16:10:43 MDT] chat: git [\"--git-dir=/home/cantora/annex-test/.git\",\"--work-tree=/home/cantora/annex-test\",\"hash-object\",\"-w\",\"--stdin-paths\",\"--no-filters\"]
+[2013-07-23 16:10:43 MDT] feed: git [\"--git-dir=/home/cantora/annex-test/.git\",\"--work-tree=/home/cantora/annex-test\",\"update-index\",\"-z\",\"--index-info\"]
+[2013-07-23 16:10:43 MDT] read: git [\"--git-dir=/home/cantora/annex-test/.git\",\"--work-tree=/home/cantora/annex-test\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+(Recording state in git...)
+[2013-07-23 16:10:43 MDT] read: git [\"--git-dir=/home/cantora/annex-test/.git\",\"--work-tree=/home/cantora/annex-test\",\"write-tree\"]
+[2013-07-23 16:10:43 MDT] chat: git [\"--git-dir=/home/cantora/annex-test/.git\",\"--work-tree=/home/cantora/annex-test\",\"commit-tree\",\"19dff833a084fa6b36c9438d6ee77f0122ce9bfd\",\"-p\",\"refs/heads/git-annex\"]
+[2013-07-23 16:10:43 MDT] call: git [\"--git-dir=/home/cantora/annex-test/.git\",\"--work-tree=/home/cantora/annex-test\",\"update-ref\",\"refs/heads/git-annex\",\"f06b1b83b38adc7692adedebc10d03daf584dbbb\"]
+$> git remote
+test-remote
+\"\"\"]]
+So the directory special remote seems to work just fine.
+
+Ill try using the standalone linux install later when I have some more time and post the results back here.
+"""]]
diff --git a/doc/bugs/gpg_hangs_on_glacier_remote_creation/comment_3_543d8a13756c1355a5752867bdcbefd3._comment b/doc/bugs/gpg_hangs_on_glacier_remote_creation/comment_3_543d8a13756c1355a5752867bdcbefd3._comment
new file mode 100644
index 000000000..1e23e881a
--- /dev/null
+++ b/doc/bugs/gpg_hangs_on_glacier_remote_creation/comment_3_543d8a13756c1355a5752867bdcbefd3._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkiAsTXFXZbLE8iyy6yDtvz4MPFbzsk3c0"
+ nickname="Tony"
+ subject="unable to run standalone linux install"
+ date="2013-07-24T17:57:22Z"
+ content="""
+i was unable to test for this bug with the standalone install; this is what happens when i try:
+
+[[!format sh \"\"\"
+$> ./runshell
+$ which git-annex
+/home/cantora/install/git-annex.linux/bin/git-annex
+$ git-annex version
+git-annex: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.16' not found (required by /home/cantora/install/git-annex.linux//usr/lib/x86_64-linux-gnu/libkrb5.so.3)
+git-annex: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.17' not found (required by /home/cantora/install/git-annex.linux//lib/x86_64-linux-gnu/libcom_err.so.2)
+git-annex: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.17' not found (required by /home/cantora/install/git-annex.linux//usr/lib/x86_64-linux-gnu/libstdc++.so.6)
+$
+\"\"\"]]
+
+"""]]
diff --git a/doc/bugs/gpg_hangs_on_glacier_remote_creation/comment_4_6441cf25e6bd62c96d7e766da9bdd7fb._comment b/doc/bugs/gpg_hangs_on_glacier_remote_creation/comment_4_6441cf25e6bd62c96d7e766da9bdd7fb._comment
new file mode 100644
index 000000000..d7e278416
--- /dev/null
+++ b/doc/bugs/gpg_hangs_on_glacier_remote_creation/comment_4_6441cf25e6bd62c96d7e766da9bdd7fb._comment
@@ -0,0 +1,25 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 4"
+ date="2013-07-25T17:38:38Z"
+ content="""
+Hmm, that strace exposes the full symmetric encryption key that git-annex has created. Thankfully, it is a single use key which will only be used for this glacier remote, so if you avoid using that remote (which is probably not usable anyway due to initremote not finishing!), the exposure won't matter.
+
+But, it is possible that this part is where it reads your personal gpg private key file. Hopefully the 55 bytes exposed out of the full 616 byte file are before the actual secret key data, or not enough to weaken your key. :/
+
+8268 read(4, \"q\224R\236\341\264\336\23\315FTD\341\253\372\6o\206\326\376\243\326\34L\1\245;\tb\361v\\\"..., 600) = 600
+8268 read(4, \"\2548\332\257\334\237\343\354\23\224\377\377\302\264\352\21\", 16) = 16
+
+It seems to be easier to social engineer people into stracing gpg and exposing data than I'd have hoped. Actually, I didn't plan to do that at all, I just wanted you to attach to gpg after this point.
+
+----
+
+So yeah, your gpg is hanging on stdin after git-annex has sent it the \"passphrase\" (really a symmetric gpg key) on fd 3.
+
+The reason the directory special remote doesn't hang is because it does not use gpg to encrypt anything during the initremote process.
+
+I think I have a theory of what's going on with your git-annex build. It does not include the assistant, so will be built without -threaded. Using the non-threaded runtime system may be leading to a deadlock when git-annex is supposed to be simulantaneously feeding stdin to gpg and processing its stdout. I have historically had some trouble around this, and it has probably not been well tested without the threaded runtime.
+
+(The standalone tarball problem is due to this bug, which will hopefully be fixed soon: [[Linux_stand_alone_build_20130723_breaks_support_for_glibc_2.13_debian_stable]])
+"""]]
diff --git a/doc/bugs/gpg_hangs_on_glacier_remote_creation/comment_5_72e152294e36bc5f2d78e8e2ebed6a23._comment b/doc/bugs/gpg_hangs_on_glacier_remote_creation/comment_5_72e152294e36bc5f2d78e8e2ebed6a23._comment
new file mode 100644
index 000000000..4fe1cfb85
--- /dev/null
+++ b/doc/bugs/gpg_hangs_on_glacier_remote_creation/comment_5_72e152294e36bc5f2d78e8e2ebed6a23._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 5"
+ date="2013-07-25T17:44:59Z"
+ content="""
+I was able to reproduce the bug by building without -threaded
+"""]]
diff --git a/doc/bugs/gpg_hangs_on_glacier_remote_creation/comment_6_890e85df05903795e01efbd7879f9c87._comment b/doc/bugs/gpg_hangs_on_glacier_remote_creation/comment_6_890e85df05903795e01efbd7879f9c87._comment
new file mode 100644
index 000000000..352adf714
--- /dev/null
+++ b/doc/bugs/gpg_hangs_on_glacier_remote_creation/comment_6_890e85df05903795e01efbd7879f9c87._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 6"
+ date="2013-07-25T17:57:31Z"
+ content="""
+I've made it always build with -threaded. Did not see anything obvious I could do to not make it hang with the non-threaded runtime, other than forking a separate feeder process. -threaded may make it not build on a few systems with sustandard ghc support (like sparc).
+"""]]
diff --git a/doc/bugs/gpg_hangs_on_glacier_remote_creation/comment_7_042047f9fcc45abbfa47c3973d79f08e._comment b/doc/bugs/gpg_hangs_on_glacier_remote_creation/comment_7_042047f9fcc45abbfa47c3973d79f08e._comment
new file mode 100644
index 000000000..cd88ac9ce
--- /dev/null
+++ b/doc/bugs/gpg_hangs_on_glacier_remote_creation/comment_7_042047f9fcc45abbfa47c3973d79f08e._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkiAsTXFXZbLE8iyy6yDtvz4MPFbzsk3c0"
+ nickname="Tony"
+ subject="thanks!"
+ date="2013-07-27T05:33:34Z"
+ content="""
+thanks it works now (i installed the latest github version using cabal).
+
+btw i created a temporary fake gpg key for the strace i posted, as it seemed likely something would leak from posting it.
+"""]]
diff --git a/doc/bugs/gpg_needs_--use-agent.mdwn b/doc/bugs/gpg_needs_--use-agent.mdwn
new file mode 100644
index 000000000..d9977909b
--- /dev/null
+++ b/doc/bugs/gpg_needs_--use-agent.mdwn
@@ -0,0 +1,53 @@
+git-annex gpg encryption fails here when GPG_AGENT_INFO is set, it needs to be supplied --use-agent to work.
+
+Output from git-annex:
+
+ copy file (to origin...) (gpg) gpg: can't query passphrase in batch mode
+ gpg: decryption failed: secret key not available
+ Command gpg ["--batch","--no-tty","--quiet","--trust-model","always","--decrypt"] failed; exit code 2
+
+ git-annex: user error (Command gpg ["--batch","--no-tty","--quiet","--trust-model","always","--decrypt"] failed; exit code 2)
+ failed
+
+Reproduced on command-line:
+
+ [0 zerodogg@browncoats ~]$ echo test > testfile
+ [0 zerodogg@browncoats ~]$ gpg -e testfile
+ [0 zerodogg@browncoats ~]$ gpg --batch --no-tty --quiet --trust-model always --decrypt testfile.gpg
+ gpg: can't query passphrase in batch mode
+ gpg: decryption failed: secret key not available
+ [2 zerodogg@browncoats ~]$ gpg --use-agent --batch --no-tty --quiet --trust-model always --decrypt testfile.gpg
+ test
+ [0 zerodogg@browncoats ~]$
+
+A patch to fix this issue:
+
+
+ From 77cb02d15245e9ad6e127388adcda960000fb3b8 Mon Sep 17 00:00:00 2001
+ From: Eskild Hustvedt <code@zerodogg.org>
+ Date: Fri, 17 Aug 2012 09:21:44 +0200
+ Subject: [PATCH] Explicitly enable agent to ensure decryption works
+
+ Otherwise gpg will fail when GPG_AGENT_INFO is set in certain cases.
+ ---
+ Utility/Gpg.hs | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+ diff --git a/Utility/Gpg.hs b/Utility/Gpg.hs
+ index e13afe5..c28b209 100644
+ --- a/Utility/Gpg.hs
+ +++ b/Utility/Gpg.hs
+ @@ -29,7 +29,7 @@ stdParams params = do
+ b <- getEnv "GPG_BATCH"
+ let batch = if isNothing e && isNothing b
+ then []
+ - else ["--batch", "--no-tty"]
+ + else ["--batch", "--no-tty", "--use-agent"]
+ return $ batch ++ defaults ++ toCommand params
+ where
+ -- be quiet, even about checking the trustdb
+ --
+ 1.7.10.4
+
+> Thanks, [[done]].. I never noticed this since I have use-agent set in
+> gpg.conf. --[[Joey]
diff --git a/doc/bugs/hGetContents:_user_error.mdwn b/doc/bugs/hGetContents:_user_error.mdwn
new file mode 100644
index 000000000..3f7467037
--- /dev/null
+++ b/doc/bugs/hGetContents:_user_error.mdwn
@@ -0,0 +1,38 @@
+### Please describe the problem.
+My server is on debian testing. After an upgrade (git annex: 3.20120629 → 4.20130521) I can't do anything in my repository anymore. git itself works, but invoking any git-annex command leads to:
+
+ git-annex: fd:6: hGetContents: user error (Pattern match failure in do expression at libraries/base/GHC/Event/Thread.hs:90:3-10)
+
+This repo is handled by a script, which invokes only the following git/git-annex commands:
+
+ $ git annex sync
+ $ git annex add
+ $ git commit -m "…"
+
+I realized this after trying to move files from my server to my local repo. My local machine runs debian sid. When trying to transfer files, this happens:
+
+ $ git annex sync
+ → ok
+ $ git annex move --from origin .
+ move x.zip (from origin...)
+ user@host's password: ← pw ok
+ git-annex-shell: fd:6: hGetContents: user error (Pattern match failure in do expression at libraries/base/GHC/Event/Thread.hs:90:3-10)
+ rsync: connection unexpectedly closed (0 bytes received so far) [Receiver]
+ rsync error: error in rsync protocol data stream (code 12) at io.c(605) [Receiver=3.0.9]
+ failed
+
+I updated git-annex on both machines to 4.20130627 (rest of server is still on debian testing), but it didn't change anything.
+
+The server was not down since the last successful transfer, so I can't imagine anything interrupting any git-annex process.
+
+### What steps will reproduce the problem?
+See above.
+
+### What version of git-annex are you using? On what operating system?
+Server: 4.20130521 on debian testing (now: 4.20130627)
+Local: 4.20130621 on debian sid (now: 4.20130627)
+
+[[!meta title="fails to run on Linux with libc 2.17 and old kernel 2.6.32"]]
+
+> Closing this since it's a bad kernel and there is a workaround to build
+> a git-annex that will work with this kernel (see comments). [[done]] --[[Joey]]
diff --git a/doc/bugs/hGetContents:_user_error/comment_1_30178f151f8c60d2ff856ca543dc506c._comment b/doc/bugs/hGetContents:_user_error/comment_1_30178f151f8c60d2ff856ca543dc506c._comment
new file mode 100644
index 000000000..cc0ba50d2
--- /dev/null
+++ b/doc/bugs/hGetContents:_user_error/comment_1_30178f151f8c60d2ff856ca543dc506c._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.193"
+ subject="comment 1"
+ date="2013-06-30T17:31:26Z"
+ content="""
+This looks uncomfortably like a bug in the ghc compiler's threaded runtime.
+
+What architecture is the server?
+"""]]
diff --git a/doc/bugs/hGetContents:_user_error/comment_2_f74eeed4a007058a22183fd678ecd6c6._comment b/doc/bugs/hGetContents:_user_error/comment_2_f74eeed4a007058a22183fd678ecd6c6._comment
new file mode 100644
index 000000000..e718ff90e
--- /dev/null
+++ b/doc/bugs/hGetContents:_user_error/comment_2_f74eeed4a007058a22183fd678ecd6c6._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.193"
+ subject="comment 2"
+ date="2013-06-30T17:33:55Z"
+ content="""
+See this upstream bug report: <http://hackage.haskell.org/trac/ghc/ticket/7653>
+"""]]
diff --git a/doc/bugs/hGetContents:_user_error/comment_3_515e562228a89a13d6d857a874f4a468._comment b/doc/bugs/hGetContents:_user_error/comment_3_515e562228a89a13d6d857a874f4a468._comment
new file mode 100644
index 000000000..70f45e6da
--- /dev/null
+++ b/doc/bugs/hGetContents:_user_error/comment_3_515e562228a89a13d6d857a874f4a468._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://m-f-k.myopenid.com/"
+ ip="84.138.125.150"
+ subject="server's architecture"
+ date="2013-06-30T23:37:00Z"
+ content="""
+It's a i686 virtual server at strato.de. Running kernel 2.6.32.
+"""]]
diff --git a/doc/bugs/hGetContents:_user_error/comment_4_8c6ed5e459c5c66b77db446c6317114c._comment b/doc/bugs/hGetContents:_user_error/comment_4_8c6ed5e459c5c66b77db446c6317114c._comment
new file mode 100644
index 000000000..f3729d341
--- /dev/null
+++ b/doc/bugs/hGetContents:_user_error/comment_4_8c6ed5e459c5c66b77db446c6317114c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.193"
+ subject="comment 4"
+ date="2013-07-02T16:41:51Z"
+ content="""
+I wonder if this could be a glibc/kernel mismatch somehow. Any chance you can upgrade your kernel to something more recent?
+"""]]
diff --git a/doc/bugs/hGetContents:_user_error/comment_5_f80bce48c3f96b0cd6892af43ee88a96._comment b/doc/bugs/hGetContents:_user_error/comment_5_f80bce48c3f96b0cd6892af43ee88a96._comment
new file mode 100644
index 000000000..0d5bf0f52
--- /dev/null
+++ b/doc/bugs/hGetContents:_user_error/comment_5_f80bce48c3f96b0cd6892af43ee88a96._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://m-f-k.myopenid.com/"
+ ip="84.138.125.150"
+ subject="comment 5"
+ date="2013-07-04T15:24:51Z"
+ content="""
+No, I can't. The kernel is handled by strato. :(
+"""]]
diff --git a/doc/bugs/hGetContents:_user_error/comment_6_69dc09e4ae726856dafbeec34170671c._comment b/doc/bugs/hGetContents:_user_error/comment_6_69dc09e4ae726856dafbeec34170671c._comment
new file mode 100644
index 000000000..956ae733c
--- /dev/null
+++ b/doc/bugs/hGetContents:_user_error/comment_6_69dc09e4ae726856dafbeec34170671c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.193"
+ subject="comment 6"
+ date="2013-07-05T15:29:11Z"
+ content="""
+Is there any chance I could get an account on this or a similar server, so I can investigate this in detail?
+"""]]
diff --git a/doc/bugs/hGetContents:_user_error/comment_7_3f66b03f773341fad94ec16b4f55edaa._comment b/doc/bugs/hGetContents:_user_error/comment_7_3f66b03f773341fad94ec16b4f55edaa._comment
new file mode 100644
index 000000000..2a64e57b1
--- /dev/null
+++ b/doc/bugs/hGetContents:_user_error/comment_7_3f66b03f773341fad94ec16b4f55edaa._comment
@@ -0,0 +1,32 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.254.222"
+ subject="comment 7"
+ date="2013-07-07T02:48:05Z"
+ content="""
+Thanks for providing me an account.
+
+I was able to reproduce the problem:
+
+<pre>
+$ git-annex-shell recvkey `pwd`
+git-annex-shell: fd:6: hGetContents: user error (Pattern match failure in do expression at libraries/base/GHC/Event/Thread.hs:90:3-10)
+</pre>
+
+Here's another one:
+
+<pre>
+$ git annex init
+
+git-annex: eventfd: unsupported operation (Function not implemented)
+failed
+init
+git-annex: fd:10: hGetContents: user error (Pattern match failure in do expression at libraries/base/GHC/Event/Thread.hs:90:3-10)
+failed
+</pre>
+
+Aha! I found a more relevant bug in GHC's bug tracker. This has the same error message including the eventfd problem. <http://ghc.haskell.org/trac/ghc/ticket/7926>
+
+After some more digging around, it's definitely a kernel/glibc incompatability. I have filed a bug on glibc: <http://bugs.debian.org/715212>
+
+"""]]
diff --git a/doc/bugs/hGetContents:_user_error/comment_8_a697e2d36abfc999e65c9f587c0de56e._comment b/doc/bugs/hGetContents:_user_error/comment_8_a697e2d36abfc999e65c9f587c0de56e._comment
new file mode 100644
index 000000000..d635ba6a7
--- /dev/null
+++ b/doc/bugs/hGetContents:_user_error/comment_8_a697e2d36abfc999e65c9f587c0de56e._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.254.222"
+ subject="workaround"
+ date="2013-07-07T16:38:09Z"
+ content="""
+This bug only affects programs built with the threaded haskell runtime.
+
+git-annex can be built without the threaded runtime, by simply disabling the webapp. So a workaround is to pass the flag -f-WebApp to cabal when building git-annex with cabal.
+"""]]
diff --git a/doc/bugs/hGetContents:_user_error/comment_9_da7c5905a64bb6779970f9394155e629._comment b/doc/bugs/hGetContents:_user_error/comment_9_da7c5905a64bb6779970f9394155e629._comment
new file mode 100644
index 000000000..1a4e97744
--- /dev/null
+++ b/doc/bugs/hGetContents:_user_error/comment_9_da7c5905a64bb6779970f9394155e629._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://openid.stackexchange.com/user/7891307e-4b76-4697-8e71-083669c26e9f"
+ nickname="MichaelK"
+ subject="comment 9"
+ date="2013-07-07T16:54:34Z"
+ content="""
+Thanks a lot for investigating this!
+
+(myopenid.com seems to be down, so I had to use another account.)
+"""]]
diff --git a/doc/bugs/haskell-dbus_problems_on_OSX___40__or_this_a_general_problem__41__.mdwn b/doc/bugs/haskell-dbus_problems_on_OSX___40__or_this_a_general_problem__41__.mdwn
new file mode 100644
index 000000000..dfc9c4cef
--- /dev/null
+++ b/doc/bugs/haskell-dbus_problems_on_OSX___40__or_this_a_general_problem__41__.mdwn
@@ -0,0 +1,113 @@
+Building commit 805d50c69d40be97baa28735371778df63b5fed6
+
+<pre>
+x00:git-annex jtang$ cabal install
+Resolving dependencies...
+Configuring dbus-0.10...
+Building dbus-0.10...
+Preprocessing library dbus-0.10...
+[1 of 9] Compiling DBus.Types ( lib/DBus/Types.hs, dist/build/DBus/Types.o )
+[2 of 9] Compiling DBus.Message ( lib/DBus/Message.hs, dist/build/DBus/Message.o )
+[3 of 9] Compiling DBus.Wire ( lib/DBus/Wire.hs, dist/build/DBus/Wire.o )
+[4 of 9] Compiling DBus.Address ( lib/DBus/Address.hs, dist/build/DBus/Address.o )
+[5 of 9] Compiling DBus ( lib/DBus.hs, dist/build/DBus.o )
+[6 of 9] Compiling DBus.Introspection ( lib/DBus/Introspection.hs, dist/build/DBus/Introspection.o )
+[7 of 9] Compiling DBus.Transport ( lib/DBus/Transport.hs, dist/build/DBus/Transport.o )
+
+lib/DBus/Transport.hs:196:72: Not in scope: `getPeerCred'
+cabal: Error: some packages failed to install:
+dbus-0.10 failed during the building phase. The exception was:
+ExitFailure 1
+git-annex-3.20120721 depends on dbus-0.10 which failed to install.
+</pre>
+
+The above isn't a git-annex problem but a dbus problem, at first I thought I didn't have the network package installed, but did. I should probably report this problem to the haskell dbus author.
+
+On a slightly different note, based on the makefile DBUS is not enabled on OSX/BSD so I did not expect the cabal file to use dbus as well, I'm currently interested in poking at the webapp stuff ;)
+
+Although DBUS is available on OSX from macports I get the feeling that the haskell-dbus package might need some poking before it works properly.
+
+To continue, pulling, installing the dependancies (dbus is still boned) and building commit 6cecc26206c4a539999b04664136c6f785211a41
+
+<pre>
+[ 92 of 205] Compiling Utility.Url ( Utility/Url.hs, tmp/Utility/Url.o )
+
+Utility/Url.hs:39:14: Not in scope: `parseURI'
+
+Utility/Url.hs:73:14: Not in scope: `parseURI'
+
+Utility/Url.hs:88:12: Not in scope: type constructor or class `URI'
+
+Utility/Url.hs:91:30: Not in scope: type constructor or class `URI'
+
+Utility/Url.hs:107:38: Not in scope: `parseURIReference'
+
+Utility/Url.hs:111:95: Not in scope: `relativeTo'
+make: *** [git-annex] Error 1
+</pre>
+
+Which then lead me to doing a "cabal install -f-DBus" which spits out the following when trying to link the binary
+
+<pre>
+[206 of 206] Compiling Main ( git-annex.hs, dist/build/git-annex/git-annex-tmp/Main.o )
+Linking dist/build/git-annex/git-annex ...
+Undefined symbols for architecture x86_64:
+ "_addfds_kqueue", referenced from:
+ _s16v6_info in Kqueue.o
+ "_init_kqueue", referenced from:
+ _s16v3_info in Kqueue.o
+ "_waitchange_kqueue", referenced from:
+ _UtilityziKqueue_zdwa1_info in Kqueue.o
+ld: symbol(s) not found for architecture x86_64
+collect2: ld returned 1 exit status
+cabal: Error: some packages failed to install:
+git-annex-3.20120721 failed during the building phase. The exception was:
+ExitFailure 1
+</pre>
+
+I then just tried to build commit with 6cecc26206c4a539999b04664136c6f785211a41 (i have the needed dependancies installed), gives me this...
+
+<pre>
+x00:git-annex jtang$ make
+ghc -O2 -threaded -Wall -ignore-package monads-fd -ignore-package monads-tf -outputdir tmp -IUtility -DWITH_ASSISTANT -DWITH_S3 -DWITH_WEBAPP --make git-annex Utility/libdiskfree.o Utility/libmounts.o Utility/libkqueue.o
+
+Assistant/Threads/MountWatcher.hs:39:0:
+ warning: #warning Building without dbus support; will use mtab polling
+[ 92 of 205] Compiling Utility.Url ( Utility/Url.hs, tmp/Utility/Url.o )
+
+Utility/Url.hs:98:65:
+ Couldn't match expected type `network-2.3.0.13:Network.URI.URI'
+ with actual type `URI'
+ In the second argument of `mkRequest', namely `u'
+ In the expression: mkRequest requesttype u :: Request_String
+ In an equation for `req':
+ req = mkRequest requesttype u :: Request_String
+make: *** [git-annex] Error 1
+</pre>
+
+The latest version of the network package in hackage is network-2.3.0.14 which I have installed, this might also be the reason why dbus is broken. removing network-2.3.0.14 at least makes it happy again.
+
+to remove the network-2.3.0.14 package
+
+<pre>
+ghc-pkg unregister network-2.3.0.14
+</pre>
+
+Hope the above isn't too random of bug/issue report.
+
+----
+
+going through <http://hackage.haskell.org/packages/archive/network/2.3.0.14/doc/html/Network-Socket.html> shows that getPeerCred is only available on systems where SO_PEERCRED is supported, *sigh* OSX isn't supported and thus haskell-dbus is broken. Apparently getpeerid is more portable but it isnt supported in the network package. It looks like dbus support on OSX isn't really going to work too well till haskell-dbus gets fixed on OSX (or BSD?)
+
+> Does OSX acually come with dbus by default, and can you
+> use something like `dbus-monitor` to see events when
+> plugging in removable drives? If so, this might be worth spending time
+> on.
+
+>> No OSX does not come with dbus by default, the user must install it
+
+>
+> Currently though, dbus is not supposed to be built on non-Linux systems.
+> (Well, it might work on Freebsd or something, but I've not tried it.)
+> I've fixed the cabal file to only enable it on Linux. [[done]] --[[Joey]]
+
diff --git a/doc/bugs/host_with_rysnc_installed__44___not_recognized.mdwn b/doc/bugs/host_with_rysnc_installed__44___not_recognized.mdwn
new file mode 100644
index 000000000..4513ad9db
--- /dev/null
+++ b/doc/bugs/host_with_rysnc_installed__44___not_recognized.mdwn
@@ -0,0 +1,19 @@
+What steps will reproduce the problem?
+Set up a remote server using ssh to a FreeNAS box
+
+What is the expected output? What do you see instead?
+Neither rsync nor git-annex are installed
+rsync is in the path, user with permissions is able to run it
+
+What version of git-annex are you using? On what operating system?
+4.20130227 OSX
+
+Please provide any additional information below.
+ssh keys were installed to allow login, when ssh-askpass was not found on osx version
+
+[[!meta title="webapp rsync probe command failed on FreeNAS box"]]
+[[!tag /design/assistant]]
+
+> [[done]]; based on the error message it's using csh and
+> the assistant will now wrap its shell commands to work with csh.
+> --[[Joey]]
diff --git a/doc/bugs/host_with_rysnc_installed__44___not_recognized/comment_1_3ff000eb3efde41426c7b086ae627dcf._comment b/doc/bugs/host_with_rysnc_installed__44___not_recognized/comment_1_3ff000eb3efde41426c7b086ae627dcf._comment
new file mode 100644
index 000000000..6d6fe2ac6
--- /dev/null
+++ b/doc/bugs/host_with_rysnc_installed__44___not_recognized/comment_1_3ff000eb3efde41426c7b086ae627dcf._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-03-18T15:55:05Z"
+ content="""
+The git-annex webapp runs some shell commands on the remote it's setting up, in this case the FreeNAS box. It's difficult to do this entirely portably. I have tried to use only POSIX shell compatable commands, that should also work with embedded systems using busybox.
+
+You can try running the probe yourself at the prompt on the FreeNAS and see how it fails. The command run is:
+
+ echo loggedin;if which git-annex-shell; then echo git-annex-shell; fi;if which rsync; then echo rsync; fi
+"""]]
diff --git a/doc/bugs/host_with_rysnc_installed__44___not_recognized/comment_2_34e592ab057df2df54e13d3f5cae64f0._comment b/doc/bugs/host_with_rysnc_installed__44___not_recognized/comment_2_34e592ab057df2df54e13d3f5cae64f0._comment
new file mode 100644
index 000000000..1616c7c84
--- /dev/null
+++ b/doc/bugs/host_with_rysnc_installed__44___not_recognized/comment_2_34e592ab057df2df54e13d3f5cae64f0._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmaygIuV4bIfp-U5IRH51FwKHq-i7_os0c"
+ nickname="Mike"
+ subject="comment 2"
+ date="2013-03-25T02:20:05Z"
+ content="""
+I copied and pasted your suggestion into a shell script, and this is what I got back:
+
+ #./test.sh
+
+ loggedin
+ /usr/local/bin/rsync
+ rsync
+"""]]
diff --git a/doc/bugs/host_with_rysnc_installed__44___not_recognized/comment_3_05ffbae13d8f9b08315f40bb9b206f46._comment b/doc/bugs/host_with_rysnc_installed__44___not_recognized/comment_3_05ffbae13d8f9b08315f40bb9b206f46._comment
new file mode 100644
index 000000000..0dd7a7ee1
--- /dev/null
+++ b/doc/bugs/host_with_rysnc_installed__44___not_recognized/comment_3_05ffbae13d8f9b08315f40bb9b206f46._comment
@@ -0,0 +1,21 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-03-27T19:22:06Z"
+ content="""
+Hmm, the message you got indicates it saw the \"loggedin\", but not the \"rsync\".
+
+Actually, the command it runs is closer to this:
+
+<pre>
+echo git-annex-probe loggedin;if which git-annex-shell; then echo git-annex-probe git-annex-shell; fi;if which rsync; then echo git-annex-probe rsync; fi
+</pre>
+
+It's possible that ssh is somehow truncating or not running all of that. The ssh command
+would be something like this:
+
+<pre>
+ssh $HOSTNAME -n 'echo git-annex-probe loggedin;if which git-annex-shell; then echo git-annex-probe git-annex-shell; fi;if which rsync; then echo git-annex-probe rsync; fi'
+<pre>
+"""]]
diff --git a/doc/bugs/host_with_rysnc_installed__44___not_recognized/comment_4_99d1f151263ca3433dd4afa8a928b1fe._comment b/doc/bugs/host_with_rysnc_installed__44___not_recognized/comment_4_99d1f151263ca3433dd4afa8a928b1fe._comment
new file mode 100644
index 000000000..ed377251c
--- /dev/null
+++ b/doc/bugs/host_with_rysnc_installed__44___not_recognized/comment_4_99d1f151263ca3433dd4afa8a928b1fe._comment
@@ -0,0 +1,30 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmaygIuV4bIfp-U5IRH51FwKHq-i7_os0c"
+ nickname="Mike"
+ subject="comment 4"
+ date="2013-03-29T04:03:44Z"
+ content="""
+running the shell script directly:
+ > ./test.sh 23:43:25
+
+ git-annex-probe loggedin
+
+ /usr/local/bin/rsync
+
+ git-annex-probe rsync
+
+Running your ssh command:
+
+ git-annex-probe loggedin
+
+ if: Expression Syntax.
+
+Running the shell script through ssh:
+ ssh $HOSTNAME ./test.sh 23:54:39
+
+ git-annex-probe loggedin
+
+ /usr/local/bin/rsync
+
+ git-annex-probe rsync
+"""]]
diff --git a/doc/bugs/host_with_rysnc_installed__44___not_recognized/comment_5_6ef1a377b0b4d3efeffdf9693d0b496b._comment b/doc/bugs/host_with_rysnc_installed__44___not_recognized/comment_5_6ef1a377b0b4d3efeffdf9693d0b496b._comment
new file mode 100644
index 000000000..b62c8a9ec
--- /dev/null
+++ b/doc/bugs/host_with_rysnc_installed__44___not_recognized/comment_5_6ef1a377b0b4d3efeffdf9693d0b496b._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 5"
+ date="2013-03-29T16:47:28Z"
+ content="""
+Sounds like it may not provide a POSIX shell for interactive use (based on the error message, I think it's csh), in which case this could work:
+
+ ssh $HOSTNAME -n 'sh -c \"echo git-annex-probe loggedin;if which git-annex-shell; then echo git-annex-probe git-annex-shell; fi;if which rsync; then echo git-annex-probe rsync; fi\"'
+
+
+"""]]
diff --git a/doc/bugs/host_with_rysnc_installed__44___not_recognized/comment_6_d9e36828ad55f3181a1c650010f23d6b._comment b/doc/bugs/host_with_rysnc_installed__44___not_recognized/comment_6_d9e36828ad55f3181a1c650010f23d6b._comment
new file mode 100644
index 000000000..020408e5b
--- /dev/null
+++ b/doc/bugs/host_with_rysnc_installed__44___not_recognized/comment_6_d9e36828ad55f3181a1c650010f23d6b._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmaygIuV4bIfp-U5IRH51FwKHq-i7_os0c"
+ nickname="Mike"
+ subject="comment 6"
+ date="2013-03-31T03:45:45Z"
+ content="""
+i ran your new command, and got this back:
+
+ git-annex-probe loggedin
+
+ /usr/local/bin/rsync
+
+ git-annex-probe rsync
+"""]]
diff --git a/doc/bugs/immediately_drops_files.mdwn b/doc/bugs/immediately_drops_files.mdwn
new file mode 100644
index 000000000..70f7faa46
--- /dev/null
+++ b/doc/bugs/immediately_drops_files.mdwn
@@ -0,0 +1,222 @@
+### Please describe the problem.
+When I `git annex get` files in a certain directory, they are got, then are dropped.
+When I do the same in a different directory, then the files there remains (as expected).
+
+`git annex fsck` also fails on these files, but after that the problem persists.
+
+I'm not really sure where to look to see why this is happening, especially why only on some directories.
+The filesystem (ext4) this is on has several GB free.
+
+Looking at the (broken) symlinks, they are strange:
+
+[[!format sh """
+git annex fsck IMG_4230.JPG > /dev/null
+ls -l IMG_4230.JPG
+lrwxrwxrwx 1 walter walter 207 Aug 13 12:14 IMG_4230.JPG -> ../../../.git/annex/objects/86/KF/SHA256E-s4209479--bba2489f526ed1288d23157b2b985bfda99321c52d05d3f4ddb92144b301318e.JPG/SHA256E-s4209479--bba2489f526ed1288d23157b2b985bfda99321c52d05d3f4ddb92144b301318e.JPG
+"""]]
+
+But then after getting it (and it being dropped somehow), the symlink is different (the number of ..s)
+
+[[!format sh """
+git annex get IMG_4230.JPG > /dev/null
+ls -l IMG_4230.JPG
+lrwxrwxrwx 1 walter walter 210 Aug 13 12:16 IMG_4230.JPG -> ../../../../.git/annex/objects/86/KF/SHA256E-s4209479--bba2489f526ed1288d23157b2b985bfda99321c52d05d3f4ddb92144b301318e.JPG/SHA256E-s4209479--bba2489f526ed1288d23157b2b985bfda99321c52d05d3f4ddb92144b301318e.JPG
+"""]]
+
+
+
+### What steps will reproduce the problem?
+
+I'm not really sure; I will test later whether this happens on other computers.
+
+### What version of git-annex are you using? On what operating system?
+ git-annex version: 4.20130812-gc590455
+ build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP DNS
+ local repository version: 3
+ default repository version: 3
+ supported repository versions: 3 4
+ upgrade supported from repository versions: 0 1 2
+
+On ubuntu 12.10
+
+
+--Walter
+
+### Please provide any additional information below.
+
+*output of git annex fsck*
+[[!format sh """
+git annex fsck 2013/08/01/IMG_4230.JPG
+[2013-08-13 12:01:25 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","ls-files","--cached","-z","--","2013/08/01/IMG_4230.JPG"]
+[2013-08-13 12:01:25 NZST] chat: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","check-attr","-z","--stdin","annex.backend","annex.numcopies","--"]
+fsck 2013/08/01/IMG_4230.JPG [2013-08-13 12:01:25 NZST] chat: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","cat-file","--batch"]
+[2013-08-13 12:01:25 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","show-ref","git-annex"]
+[2013-08-13 12:01:25 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","show-ref","--hash","refs/heads/git-annex"]
+[2013-08-13 12:01:25 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..3afd101dade8be4e1ed7ac48fdf4173274d3ecd7","--oneline","-n1"]
+[2013-08-13 12:01:25 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..9be78e75db197a26db6aaaffbcddf5057e30d23f","--oneline","-n1"]
+[2013-08-13 12:01:25 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..2bae49a6e1ce85ad501b0fa85439da7cde8c8597","--oneline","-n1"]
+[2013-08-13 12:01:25 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..b5858e25b7f7c45564ab463ecf3e74ecd8979609","--oneline","-n1"]
+[2013-08-13 12:01:25 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..cad75ea77d513a24006ee0b56ff0aad12b7aa805","--oneline","-n1"]
+[2013-08-13 12:01:25 NZST] read: git ["config","--null","--list"]
+ok
+[2013-08-13 12:01:25 NZST] chat: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","hash-object","-w","--stdin-paths","--no-filters"]
+[2013-08-13 12:01:25 NZST] feed: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","update-index","-z","--index-info"]
+[2013-08-13 12:01:25 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","show-ref","--hash","refs/heads/git-annex"]
+(Recording state in git...)
+[2013-08-13 12:01:25 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","write-tree"]
+[2013-08-13 12:01:25 NZST] chat: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","commit-tree","78aca82f86ffb91bc841a3978f410e55aa6e0efe","-p","refs/heads/git-annex"]
+[2013-08-13 12:01:25 NZST] call: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","update-ref","refs/heads/git-annex","14908fedbd44917815dd013125b69def1f7f8f7c"]
+
+"""]]
+
+*output of git annex get* (output taken from daemon.log, as output from command does not include the dropping part)
+[[!format sh """
+git annex get 2013/08/01/IMG_4230.JPG
+[2013-08-13 12:03:46 NZST] TransferWatcher: transfer starting: Download UUID "e6bb2ef2-b2b5-11e1-bd1b-3fd40e5e767d" 2013/08/01/IMG_4230.JPG Nothing
+[2013-08-13 12:03:46 NZST] TransferWatcher: transfer starting: Download UUID "e6bb2ef2-b2b5-11e1-bd1b-3fd40e5e767d" 2013/08/01/IMG_4230.JPG Nothing
+[2013-08-13 12:03:46 NZST] TransferWatcher: transfer finishing: Transfer {transferDirection = Download, transferUUID = UUID "e6bb2ef2-b2b5-11e1-bd1b-3fd40e5e767d", transferKey = Key {keyName = "bba2489f526ed1288d23157b2b985bfda99321c52d05d3f4ddb92144b301318e.JPG", keyBackendName = "SHA256E", keySize = Just 4209479, keyMtime = Nothing}}
+[2013-08-13 12:03:46 NZST] Watcher: add symlink 01/IMG_4230.JPG
+[2013-08-13 12:03:46 NZST] chat: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","hash-object","-t","blob","-w","--stdin","--no-filters"]
+[2013-08-13 12:03:46 NZST] Committer: committing 1 changes
+[2013-08-13 12:03:46 NZST] Committer: Committing changes to git
+[2013-08-13 12:03:46 NZST] feed: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","update-index","-z","--index-info"]
+[2013-08-13 12:03:46 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","commit","--allow-empty-message","--no-edit","-m","","--quiet","--no-verify"]
+[2013-08-13 12:03:46 NZST] Pusher: Synok
+(Recording state in git...)
+(Recording state in git...)
+(Recording state in git...)
+(Recording state in git...)
+(Recording state in git...)
+(Recording state in git...)
+drop 01/IMG_4230.JPG cing with Adata, b(checking cloud...) itbucket
+[2013-08-13 12:03:46 NZST] Committer: dropped 01/IMG_4230.JPG (from here) (copies now 4) : file renamed
+[2013-08-13 12:03:46 NZST] chat: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","hash-object","-w","--stdin-paths","--no-filters"]
+[2013-08-13 12:03:46 NZST] feed: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","update-index","-z","--index-info"]
+[2013-08-13 12:03:47 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","show-ref","--hash","refs/heads/git-annex"]
+[2013-08-13 12:03:47 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","write-tree"]
+[2013-08-13 12:03:47 NZST] chat: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","commit-tree","f288bfce8d133cc0ce00b65d48ca726809da34e6","-p","refs/heads/git-annex"]
+[2013-08-13 12:03:47 NZST] call: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","update-ref","refs/heads/git-annex","5a188246bda51207d12adf86c6d87568ca7076d7"]
+[2013-08-13 12:03:47 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","symbolic-ref","HEAD"]
+[2013-08-13 12:03:47 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","show-ref","refs/heads/master"]
+[2013-08-13 12:03:47 NZST] Pusher: pushing to [Remote { name ="Adata" },Remote { name ="bitbucket" }]
+[2013-08-13 12:03:47 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","show-ref","git-annex"]
+[2013-08-13 12:03:47 NZST] call: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","branch","-f","synced/master"]
+[2013-08-13 12:03:47 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","show-ref","--hash","refs/heads/git-annex"]
+[2013-08-13 12:03:47 NZST] call: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","push","bitbucket","git-annex:synced/git-annex","master:synced/master"]
+[2013-08-13 12:03:47 NZST] call: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","push","Adata","git-annex:synced/git-annex","master:synced/master"]
+[2013-08-13 12:03:47 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..5a188246bda51207d12adf86c6d87568ca7076d7","--oneline","-n1"]
+[2013-08-13 12:03:47 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..9be78e75db197a26db6aaaffbcddf5057e30d23f","--oneline","-n1"]
+[2013-08-13 12:03:47 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..2bae49a6e1ce85ad501b0fa85439da7cde8c8597","--oneline","-n1"]
+[2013-08-13 12:03:47 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..b5858e25b7f7c45564ab463ecf3e74ecd8979609","--oneline","-n1"]
+[2013-08-13 12:03:47 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..3afd101dade8be4e1ed7ac48fdf4173274d3ecd7","--oneline","-n1"]
+[2013-08-13 12:03:47 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..cad75ea77d513a24006ee0b56ff0aad12b7aa805","--oneline","-n1"]
+[2013-08-13 12:03:47 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","ls-tree","-z","--","refs/heads/git-annex","uuid.log","remote.log","trust.log","group.log","preferred-content.log"]
+[2013-08-13 12:03:47 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","show-ref","git-annex"]
+[2013-08-13 12:03:47 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","show-ref","--hash","refs/heads/git-annex"]
+[2013-08-13 12:03:47 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..5a188246bda51207d12adf86c6d87568ca7076d7","--oneline","-n1"]
+[2013-08-13 12:03:47 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..9be78e75db197a26db6aaaffbcddf5057e30d23f","--oneline","-n1"]
+[2013-08-13 12:03:47 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..2bae49a6e1ce85ad501b0fa85439da7cde8c8597","--oneline","-n1"]
+[2013-08-13 12:03:47 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..b5858e25b7f7c45564ab463ecf3e74ecd8979609","--oneline","-n1"]
+[2013-08-13 12:03:47 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..3afd101dade8be4e1ed7ac48fdf4173274d3ecd7","--oneline","-n1"]
+[2013-08-13 12:03:47 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..cad75ea77d513a24006ee0b56ff0aad12b7aa805","--oneline","-n1"]
+[2013-08-13 12:03:47 NZST] Watcher: add symlink 01/IMG_4230.JPG
+[2013-08-13 12:03:47 NZST] chat: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","hash-object","-t","blob","-w","--stdin","--no-filters"]
+To /media/walter/327D522A6727FE79/Pictures
+ 3afd101..5a18824 git-annex -> synced/git-annex
+[2013-08-13 12:03:48 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","show-ref","git-annex"]
+[2013-08-13 12:03:48 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","push","Adata","git-annex:synced/git-annex","master"]
+[2013-08-13 12:03:48 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","show-ref","--hash","refs/heads/git-annex"]
+[2013-08-13 12:03:48 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..5a188246bda51207d12adf86c6d87568ca7076d7","--oneline","-n1"]
+[2013-08-13 12:03:48 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..9be78e75db197a26db6aaaffbcddf5057e30d23f","--oneline","-n1"]
+[2013-08-13 12:03:48 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..2bae49a6e1ce85ad501b0fa85439da7cde8c8597","--oneline","-n1"]
+[2013-08-13 12:03:48 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..b5858e25b7f7c45564ab463ecf3e74ecd8979609","--oneline","-n1"]
+[2013-08-13 12:03:48 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..cad75ea77d513a24006ee0b56ff0aad12b7aa805","--oneline","-n1"]
+[2013-08-13 12:03:48 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..3afd101dade8be4e1ed7ac48fdf4173274d3ecd7","--oneline","-n1"]
+[2013-08-13 12:03:48 NZST] Committer: committing 1 changes
+[2013-08-13 12:03:48 NZST] Committer: Committing changes to git
+[2013-08-13 12:03:48 NZST] feed: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","update-index","-z","--index-info"]
+[2013-08-13 12:03:48 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","commit","--allow-empty-message","--no-edit","-m","","--quiet","--no-verify"]
+To git@bitbucket.org:waltersom/Pictures.git
+ 3afd101..5a18824 git-annex -> synced/git-annex
+[2013-08-13 12:03:52 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","show-ref","git-annex"]
+[2013-08-13 12:03:52 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","push","bitbucket","git-annex:synced/git-annex","master"]
+[2013-08-13 12:03:52 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","show-ref","--hash","refs/heads/git-annex"]
+[2013-08-13 12:03:52 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..5a188246bda51207d12adf86c6d87568ca7076d7","--oneline","-n1"]
+[2013-08-13 12:03:52 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..9be78e75db197a26db6aaaffbcddf5057e30d23f","--oneline","-n1"]
+[2013-08-13 12:03:52 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..2bae49a6e1ce85ad501b0fa85439da7cde8c8597","--oneline","-n1"]
+[2013-08-13 12:03:52 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..b5858e25b7f7c45564ab463ecf3e74ecd8979609","--oneline","-n1"]
+[2013-08-13 12:03:52 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..cad75ea77d513a24006ee0b56ff0aad12b7aa805","--oneline","-n1"]
+[2013-08-13 12:03:58 NZST] Pusher: Syncing with Adata, bitbucket
+[2013-08-13 12:03:58 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","symbolic-ref","HEAD"]
+[2013-08-13 12:03:58 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","show-ref","refs/heads/master"]
+[2013-08-13 12:03:58 NZST] Pusher: pushing to [Remote { name ="Adata" },Remote { name ="bitbucket" }]
+[2013-08-13 12:03:58 NZST] call: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","branch","-f","synced/master"]
+[2013-08-13 12:03:58 NZST] call: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","push","Adata","git-annex:synced/git-annex","master:synced/master"]
+[2013-08-13 12:03:58 NZST] call: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","push","bitbucket","git-annex:synced/git-annex","master:synced/master"]
+Everything up-to-date
+[2013-08-13 12:03:58 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","push","Adata","git-annex:synced/git-annex","master"]
+Everything up-to-date
+[2013-08-13 12:04:02 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","push","bitbucket","git-annex:synced/git-annex","master"]
+
+"""
+]]
+
+
+
+I tried removing the USB drive I had plugged in, and was able to get the file from S3, and it wasn't dropped.
+However, checking the logs, I see that it did try to drop the file, but was unable to verify numcopies, so gives up.
+Also odd, is that it doesn't suggest making the USB drive available, but `git annex whereis` knows that the drive does have it. Also, annex.numcopies is 1, and it got it from S3, so why can't it drop it on the computer?
+Or, why does it say that it needs two copies? `git config annex.numcopies` gives 1.
+
+[[!format sh """
+[2013-08-13 16:52:08 NZST] TransferWatcher: transfer starting: Download UUID "be992080-b1db-11e1-8f79-1b10bb4092ef" 01/IMG_4230.JPG Nothing
+[2013-08-13 16:54:06 NZST] TransferWatcher: transfer starting: Download UUID "be992080-b1db-11e1-8f79-1b10bb4092ef" 01/IMG_4230.JPG Just 65504
+[...]
+[2013-08-13 16:54:06 NZST] TransferWatcher: transfer starting: Download UUID "be992080-b1db-11e1-8f79-1b10bb4092ef" 01/IMG_4230.JPG Just 4192256
+[2013-08-13 16:54:06 NZST] TransferWatcher: transfer finishing: Transfer {transferDirection = Download, transferUUID = UUID "be992080-b1db-11e1-8f79-1b10bb4092ef", transferKey = Key {keyName = "bba2489f526ed1288d23157b2b985bfda99321c52d05d3f4ddb92144b301318e.JPG", keyBackendName = "SHA256E", keySize = Just 4209479, keyMtime = Nothing}}
+[2013-08-13 16:54:06 NZST] Watcher: add symlink 01/IMG_4230.JPG
+[2013-08-13 16:54:06 NZST] chat: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","hash-object","-t","blob","-w","--stdin","--no-filters"]
+[2013-08-13 16:54:06 NZST] Committer: committing 1 changes
+[2013-08-13 16:54:06 NZST] Committer: Committing changes to git
+[2013-08-13 16:54:06 NZST] feed: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","update-index","-z","--index-info"]
+[2013-08-13 16:54:06 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","commit","--allow-empty-message","--no-edit","-m","","--quiet","--no-verify"]
+[2013-08-13 16:54:06
+ Could only verify the existence of 1 out of 2 necessary copies
+
+ Try making some of these repositories available:
+ 416aa28e-b1d4-11e1-9539-c39b14a3f7d2 -- timeline laptop
+ f42d30a0-b1d2-11e1-8b32-3bdd169e3280 -- my desktop
+
+ (Use --force to override this check, or adjust annex.numcopies.)
+failed
+(Recording state in git...)
+(Recording state in git...)
+(Recording state in git...)
+drop 01/IMG_4230.JPG NZST] Pusher:(checking cloud...) Syncing with bitbucket
+(unsafe) [2013-08-13 16:54:07 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","symbolic-ref","HEAD"]
+[2013-08-13 16:54:07 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","show-ref","refs/heads/master"]
+[2013-08-13 16:54:07 NZST] Pusher: pushing to [Remote { name ="bitbucket" }]
+[2013-08-13 16:54:07 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","show-ref","git-annex"]
+[2013-08-13 16:54:07 NZST] call: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","branch","-f","synced/master"]
+[2013-08-13 16:54:07 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","show-ref","--hash","refs/heads/git-annex"]
+[2013-08-13 16:54:07 NZST] call: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","push","bitbucket","git-annex:synced/git-annex","master:synced/master"]
+[2013-08-13 16:54:07 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..7b6b1c6c479a13f9d4ece135bdf3ba31bc484b31","--oneline","-n1"]
+[2013-08-13 16:54:07 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..9be78e75db197a26db6aaaffbcddf5057e30d23f","--oneline","-n1"]
+[2013-08-13 16:54:07 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..2bae49a6e1ce85ad501b0fa85439da7cde8c8597","--oneline","-n1"]
+[2013-08-13 16:54:07 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..b5858e25b7f7c45564ab463ecf3e74ecd8979609","--oneline","-n1"]
+[2013-08-13 16:54:07 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..11a0c19d7c79f3e574b81295782ab2820caea232","--oneline","-n1"]
+[2013-08-13 16:54:07 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..cad75ea77d513a24006ee0b56ff0aad12b7aa805","--oneline","-n1"]
+[2013-08-13 16:54:07 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..5ebb3e46b8fc109c2966ceccdd716f469d94fcad","--oneline","-n1"]
+[2013-08-13 16:54:07 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","ls-tree","-z","--","refs/heads/git-annex","uuid.log","remote.log","trust.log","group.log","preferred-content.log"]
+To git@bitbucket.org:waltersom/Pictures.git
+ 5ebb3e4..7b6b1c6 git-annex -> synced/git-annex
+[2013-08-13 16:54:12 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","show-ref","git-annex"]
+[2013-08-13 16:54:12 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","push","bitbucket","git-annex:synced/git-annex","master"]
+[2013-08-13 16:54:12 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","show-ref","--hash","refs/heads/git-annex"]
+[2013-08-13 16:54:12 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..7b6b1c6c479a13f9d4ece135bdf3ba31bc484b31","--oneline","-n1"]
+[2013-08-13 16:54:12 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..9be78e75db197a26db6aaaffbcddf5057e30d23f","--oneline","-n1"]
+[2013-08-13 16:54:12 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..2bae49a6e1ce85ad501b0fa85439da7cde8c8597","--oneline","-n1"]
+[2013-08-13 16:54:12 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..b5858e25b7f7c45564ab463ecf3e74ecd8979609","--oneline","-n1"]
+[2013-08-13 16:54:12 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..11a0c19d7c79f3e574b81295782ab2820caea232","--oneline","-n1"]
+[2013-08-13 16:54:12 NZST] read: git ["--git-dir=/home/walter/Photos/.git","--work-tree=/home/walter/Photos","log","refs/heads/git-annex..cad75ea77d513a24006ee0b56ff0aad12b7aa805","--oneline","-n1"]
+"""]]
diff --git a/doc/bugs/immediately_drops_files/comment_1_9ef6e694ef8a8eee7a42f88554475db7._comment b/doc/bugs/immediately_drops_files/comment_1_9ef6e694ef8a8eee7a42f88554475db7._comment
new file mode 100644
index 000000000..9d630e385
--- /dev/null
+++ b/doc/bugs/immediately_drops_files/comment_1_9ef6e694ef8a8eee7a42f88554475db7._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 1"
+ date="2013-08-24T16:41:04Z"
+ content="""
+You are running the git annex assistant, which takes care of getting and dropping files as it's configured to do, and you are then going in and manually running `git annex get`. If the assistant sees a file's content has appeared, and that file is in a directory that it has been configured to not want the content of file in (the `archive` directory by default), it will immediately try to drop it.
+
+The only thing I don't understand is why the number of `..` in the symlink would change.
+"""]]
diff --git a/doc/bugs/immediately_drops_files/comment_2_76e4f8b73ab60b2540dd2a3e5379791d._comment b/doc/bugs/immediately_drops_files/comment_2_76e4f8b73ab60b2540dd2a3e5379791d._comment
new file mode 100644
index 000000000..274090c63
--- /dev/null
+++ b/doc/bugs/immediately_drops_files/comment_2_76e4f8b73ab60b2540dd2a3e5379791d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 2"
+ date="2013-08-24T16:41:47Z"
+ content="""
+BTW if you don't want the assistant to automatically get and drop files in your repository, you can edit the repository in the webapp and select \"manual mode\".
+"""]]
diff --git a/doc/bugs/immediately_drops_files/comment_3_788db083f5ba2e5589c3b952203ec954._comment b/doc/bugs/immediately_drops_files/comment_3_788db083f5ba2e5589c3b952203ec954._comment
new file mode 100644
index 000000000..9253caa1a
--- /dev/null
+++ b/doc/bugs/immediately_drops_files/comment_3_788db083f5ba2e5589c3b952203ec954._comment
@@ -0,0 +1,21 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnSenxKyE_2Z6Wb-EBMO8FciyRywjx1ZiQ"
+ nickname="Walter"
+ subject="comment 3"
+ date="2013-08-24T21:59:12Z"
+ content="""
+I have all of my repositories set to either manual (all the computers), or full backup (the usb drive and s3).
+So, this is happening in a manual repository.
+
+
+Also, I still don't understand why it would be confused over the annex.numcopies setting (why does it claim it needs 2 copies, when numcopies is 1?)
+
+I just tested between desktop and laptop. File is also present in s3.
+
+File on desktop. Copy to laptop --> desktop drops (why? both are set to manual, and both have the other set as manual as well)
+
+Get on desktop. Works, it gets it from laptop. But then, desktop makes laptop drop it (why? again, both are manual repositories)
+
+
+
+"""]]
diff --git a/doc/bugs/immediately_drops_files/comment_4_425b79865eb77d69d0b7a71a14639f81._comment b/doc/bugs/immediately_drops_files/comment_4_425b79865eb77d69d0b7a71a14639f81._comment
new file mode 100644
index 000000000..aacf2f2dc
--- /dev/null
+++ b/doc/bugs/immediately_drops_files/comment_4_425b79865eb77d69d0b7a71a14639f81._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.2.134"
+ subject="comment 4"
+ date="2013-09-13T19:27:51Z"
+ content="""
+> both are set to manual, and both have the other set as manual as well
+
+I'm not sure what you mean by that. Do you mean that when you run git annex vicfg, it is in group manual?
+"""]]
diff --git a/doc/bugs/immediately_drops_files/comment_5_7c9f660b6bcec31827a44a650e9d4622._comment b/doc/bugs/immediately_drops_files/comment_5_7c9f660b6bcec31827a44a650e9d4622._comment
new file mode 100644
index 000000000..bb2569893
--- /dev/null
+++ b/doc/bugs/immediately_drops_files/comment_5_7c9f660b6bcec31827a44a650e9d4622._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnSenxKyE_2Z6Wb-EBMO8FciyRywjx1ZiQ"
+ nickname="Walter"
+ subject="comment 5"
+ date="2013-09-13T21:58:30Z"
+ content="""
+I had checked in the webapps, and they were all set to manual.
+
+Looking in `git annex vicfg`, the groups are set to manual, and the content is set to standard.
+"""]]
diff --git a/doc/bugs/importfeed_fails__44___bad_feed_content.mdwn b/doc/bugs/importfeed_fails__44___bad_feed_content.mdwn
new file mode 100644
index 000000000..4ee312be0
--- /dev/null
+++ b/doc/bugs/importfeed_fails__44___bad_feed_content.mdwn
@@ -0,0 +1,36 @@
+### Please describe the problem.
+
+I just added a new podcast to my feeds list and it is complaining of "bad feed content" when trying to import.
+
+### What steps will reproduce the problem?
+
+1. git-annex importfeed --fast http://redecentralize.org/podcast/feed.rss
+3. see the sad error "warning: bad feed content"
+
+### What version of git-annex are you using? On what operating system?
+
+git-annex version: 4.20130827
+
+### Please provide any additional information below.
+
+[[!format sh """
+greg@x200s:~/annex/Podcasts$ git-annex importfeed --fast http://redecentralize.org/podcast/feed.rss
+(checking known urls...)
+importfeed http://redecentralize.org/podcast/feed.rss
+--2013-09-09 15:05:17-- http://redecentralize.org/podcast/feed.rss
+Resolving redecentralize.org (redecentralize.org)... 204.232.175.78
+Connecting to redecentralize.org (redecentralize.org)|204.232.175.78|:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 4331 (4.2K) [text/xml]
+Saving to: ‘/tmp/feed12649’
+
+100%[==============================================================>] 4,331 --.-K/s in 0.08s
+
+2013-09-09 15:05:17 (56.0 KB/s) - ‘/tmp/feed12649’ saved [4331/4331]
+
+
+ warning: bad feed content
+ok
+"""]]
+
+> upstream bug <https://github.com/sof/feed/issues/5> ; [[done]] --[[Joey]]
diff --git a/doc/bugs/importfeed_fails_when_using_the_option_--lazy_for_specific_podcast.mdwn b/doc/bugs/importfeed_fails_when_using_the_option_--lazy_for_specific_podcast.mdwn
new file mode 100644
index 000000000..0d6bcb05c
--- /dev/null
+++ b/doc/bugs/importfeed_fails_when_using_the_option_--lazy_for_specific_podcast.mdwn
@@ -0,0 +1,77 @@
+### Please describe the problem.
+
+importfeed responds with "failed" when using the option --lazy for specific podcast and no symbolic links get created. However when I don't use the --fast option the podcast enclosures do download and links get created as expected.
+
+### What steps will reproduce the problem?
+
+git-annex importfeed --fast http://schoolsucksproject.com/category/podcast/feed/
+
+### What version of git-annex are you using? On what operating system?
+
+ Ubuntu
+ git-annex version: 4.20130802-g1452ac3
+ build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP
+ local repository version: 3
+ default repository version: 3
+ supported repository versions: 3 4
+ upgrade supported from repository versions: 0 1 2
+
+### Please provide any additional information below.
+
+ git-annex importfeed --fast http://schoolsucksproject.com/category/podcast/feed/
+ (checking known urls...)
+ (Recording state in git...)
+ importfeed http://schoolsucksproject.com/category/podcast/feed/
+ --2013-09-28 00:27:25-- http://schoolsucksproject.com/category/podcast/feed/
+ Resolving schoolsucksproject.com (schoolsucksproject.com)... 108.162.199.17, 108.162.198.17
+ Connecting to schoolsucksproject.com (schoolsucksproject.com)|108.162.199.17|:80... connected.
+ HTTP request sent, awaiting response... 200 OK
+ Length: unspecified [text/xml]
+ Saving to: `/tmp/feed16555'
+
+ 2013-09-28 00:27:28 (217 KB/s) - `/tmp/feed16555' saved [423071]
+
+ addurl School_Sucks_Project___Podcasts/238f__Presence_and_Productivity__6___Tools_For_A_Freed_Mind_and_A_Voluntary_Life_mp3
+ unable to access url: http://schoolsucks.podomatic.com/enclosure/2013-09-21T08_21_33-07_00.mp3
+ failed
+ addurl School_Sucks_Project___Podcasts/238e__Presence_and_Productivity__5___Habit_Change_mp3
+ unable to access url: http://schoolsucks.podomatic.com/enclosure/2013-09-18T20_40_40-07_00.mp3
+ failed
+ addurl School_Sucks_Project___Podcasts/238d__Presence_and_Productivity__4___Next_Actions__Projects__and_Procrastination_mp3
+ unable to access url: http://schoolsucks.podomatic.com/enclosure/2013-09-16T10_10_06-07_00.mp3
+ failed
+ ...
+
+> (There is no --lazy option. You seem to mean --fast.)
+>
+> This fine web server rejects the User-Agent used by curl:
+
+<pre>
+joey@darkstar:~>curl http://schoolsucks.podomatic.com/enclosure/2013-09-18T20_40_40-07_00.mp3
+Forbidden
+joey@darkstar:~>wget http://schoolsucks.podomatic.com/enclosure/2013-09-18T20_40_40-07_00.mp3
+--2013-09-28 11:18:36-- http://schoolsucks.podomatic.com/enclosure/2013-09-18T20_40_40-07_00.mp3
+Resolving schoolsucks.podomatic.com (schoolsucks.podomatic.com)... 38.99.42.46, 38.110.155.212
+Connecting to schoolsucks.podomatic.com (schoolsucks.podomatic.com)|38.99.42.46|:80... connected.
+HTTP request sent, awaiting response... 200 OK
+<pre>
+
+> git-annex always uses curl for checking file sizes. So the workaround
+> is to use `git annex addurl --relaxed` on this url, which will skip
+> the size check. However, if you only had curl installed, `git-annex get`
+> would again try to use curl to get the file, and would still fail.
+> It only happens to successfully download because git-annex chose
+> to use wget and this site has apparently forgotten to block that.
+>
+> I don't know if it makes sense for git-annex to vary the user-agent
+> to get around such (incredibly stupid) blocking. It could retry
+> with a random user-agent, but that could be construed as abusive
+> behavior; this site has asked us to go away. The only choices
+> that seem really defensible would be to add a --user-agent
+> switch, and/or to make git-annex set a default user agent header
+> of "git-annex", rather than relying on the curl/wget defaults.
+> --[[Joey]]
+
+> I've [[done]] what's discussed above, and verified it fixes
+> behavior for this specific server too.
+> --[[Joey]]
diff --git a/doc/bugs/importfeed_fails_when_using_the_option_--lazy_for_specific_podcast/comment_1_4ccfabbaf75e139b32f6fa6f7bc6a7fe._comment b/doc/bugs/importfeed_fails_when_using_the_option_--lazy_for_specific_podcast/comment_1_4ccfabbaf75e139b32f6fa6f7bc6a7fe._comment
new file mode 100644
index 000000000..26430ec91
--- /dev/null
+++ b/doc/bugs/importfeed_fails_when_using_the_option_--lazy_for_specific_podcast/comment_1_4ccfabbaf75e139b32f6fa6f7bc6a7fe._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="Remy"
+ ip="82.94.186.146"
+ subject="Thank you very much"
+ date="2013-09-30T08:49:33Z"
+ content="""
+Thank you very much for looking into this! This issue was holding me back from using git-annex as my podcatcher. Hope it helps somebody else as well.
+"""]]
diff --git a/doc/bugs/importfeed_should_allow_pubdate_in_the_template.mdwn b/doc/bugs/importfeed_should_allow_pubdate_in_the_template.mdwn
new file mode 100644
index 000000000..44d25b02d
--- /dev/null
+++ b/doc/bugs/importfeed_should_allow_pubdate_in_the_template.mdwn
@@ -0,0 +1,5 @@
+importfeed is a great feature, but it doesn't allow templating the filename with the publish date.
+
+I would suggest adding pubdate option, which would fix this problem.
+
+> duplicate of [[todo/importfeed: allow ${itemdate} with --template]] [[done]] --[[Joey]]
diff --git a/doc/bugs/importfeed_uses___34____95__foo__34___as_extension.mdwn b/doc/bugs/importfeed_uses___34____95__foo__34___as_extension.mdwn
new file mode 100644
index 000000000..5f09e2636
--- /dev/null
+++ b/doc/bugs/importfeed_uses___34____95__foo__34___as_extension.mdwn
@@ -0,0 +1,17 @@
+### Please describe the problem.
+When running importfeed on gitminutes <http://feeds.gitminutes.com/gitminutes-podcast> git-annex interprets the extension as "_mp3" rather than ".mp3" which means that renaming is needed for various audio players to accept the files.
+
+### What steps will reproduce the problem?
+git annex importfeed http://feeds.gitminutes.com/gitminutes-podcast --fast
+
+### What version of git-annex are you using? On what operating system?
+git-annex version: 4.20130802
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP
+local repository version: 3
+default repository version: 3
+supported repository versions: 3 4
+upgrade supported from repository versions: 0 1 2
+
+on Debian Sid
+
+> Already fixed in git. [[done]] --[[Joey]]
diff --git a/doc/bugs/inconsistent_use_of_SI_prefixes.mdwn b/doc/bugs/inconsistent_use_of_SI_prefixes.mdwn
new file mode 100644
index 000000000..df7fc5fb2
--- /dev/null
+++ b/doc/bugs/inconsistent_use_of_SI_prefixes.mdwn
@@ -0,0 +1,55 @@
+### Please describe the problem.
+
+`git annex status` inconsistently uses mebi (SI) and giga (informal) prefixes.
+
+### What steps will reproduce the problem?
+
+Example:
+
+[[!format txt """
+anarcat@marcos:mp3$ git annex status
+supported backends: SHA256E SHA1E SHA512E SHA224E SHA384E SHA256 SHA1 SHA512 SHA224 SHA384 WORM URL
+supported remote types: git S3 bup directory rsync web glacier hook
+repository mode: direct
+trusted repositories: 0
+semitrusted repositories: 2
+ 00000000-0000-0000-0000-000000000001 -- web
+ b7802161-c984-4c9f-8d05-787a29c41cfe -- here (anarcat@marcos:/srv/mp3)
+untrusted repositories: 0
+transfers in progress: none
+available local disk space: 31.93 gigabytes (+1 megabyte reserved)
+local annex keys: 19913
+local annex size: 111.08 gigabytes
+known annex keys: 20085
+known annex size: 111.38 gigabytes
+bloom filter size: 16 mebibytes (3.1% full)
+backend usage:
+ SHA256E: 39998
+"""]]
+
+Notice `mebibytes` and `gigabytes`. It is unclear whether those are gigabytes (1000^3) or gibibytes (1024^3).
+
+### What version of git-annex are you using? On what operating system?
+
+4.20130802~bpo70+2, Debian wheezy.
+
+### Please provide any additional information below.
+
+nil. --[[anarcat]]
+
+> git-annex consistently uses the powers of ten units
+> for disk storage sizes. Its "gigabyte" is the SI gigabyte.
+>
+> It uses the absurdly named units for powers of 2 for memory sizes,
+> in the few places it deals with memory (probably only the above bloom
+> filter size number).
+>
+> AFAIK I am complying with all relevant standards and best practices.
+> Even though I consider them rather dumb, as is clear if you
+> [read the opionated source code I wrote to handle this]().
+>
+> If git-annex used "gibibyte", the numbers it reports for disk size
+> would not match the numbers disk vendors and most tools use.
+>
+> [[bug_is_in_world_not_in_git-annex|done]] --[[Joey]]
+
diff --git a/doc/bugs/internal_server_error:_hGetContents:_invalid_argument___40__invalid_byte_sequence__41__.mdwn b/doc/bugs/internal_server_error:_hGetContents:_invalid_argument___40__invalid_byte_sequence__41__.mdwn
new file mode 100644
index 000000000..8c9703ed2
--- /dev/null
+++ b/doc/bugs/internal_server_error:_hGetContents:_invalid_argument___40__invalid_byte_sequence__41__.mdwn
@@ -0,0 +1,29 @@
+### Please describe the problem.
+
+Some logs fail to be displayed, and instead of displaying parts of the log, no logs at all are displayed in the webapp.
+
+The problem character is, I believe, a latin-1 encoded filename (as opposed to UTF-8). --[[anarcat]]
+
+### What steps will reproduce the problem?
+
+1. download [this logfile](http://paste.anarc.at/daemon.log.1)
+2. install it in .git/annex/daemon.log
+3. load the webapp
+4. visit the logs page
+
+### What version of git-annex are you using? On what operating system?
+
+4.20131105-g8efdc1a
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+Internal Server Error
+/srv/video/.git/annex/daemon.log.1: hGetContents: invalid argument (invalid byte sequence)
+git-annex version 4.20131105-g8efdc1a
+# End of transcript or log.
+"""]]
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/internal_server_error:_unknown_UUID_on_webapp.mdwn b/doc/bugs/internal_server_error:_unknown_UUID_on_webapp.mdwn
new file mode 100644
index 000000000..307eed308
--- /dev/null
+++ b/doc/bugs/internal_server_error:_unknown_UUID_on_webapp.mdwn
@@ -0,0 +1,147 @@
+### Please describe the problem.
+
+I am having trouble using the webapp with a setup I did on the commandline that was working fine.
+
+I have two machines: one, a server called `marcos`, is available on the internetz and I cloned a repo from there into `markov`, a workstation that is hidden behind a NAT connexion (so I can't add it as a remote).
+
+It seems that because the remote is not locally available as a git remote, the webapp is freaking out because it doesn't recognize `markov` as a proper remote.
+
+### What steps will reproduce the problem?
+
+1. setup git annex locally (on `marcos`) in a repository (probably `git annex init; git annex direct; git annex add .` i somewhat followed [[tips/Git_annex_and_Calibre/]])
+2. `git clone` that repo on a remote, unaccessible (NAT'd) server (`markov`)
+3. start doing some git annex get, get tired, run the web app on `markov`
+4. let that run over there, go back to `marcos`
+5. be curious about what is going on on `markov`, run the webapp and enter the path to the repository created in step one when prompted (it's the first time i run the webapp)
+6. it starts up fine, but doesn't seem to detect `markov`, marking transfers as going to the remote named `unknown`
+7. click on the `unknown` link, crash
+8. go back to the dashboard, crash
+
+From there on, the webapp is pretty much crashed, starting it from scratch asks me if i want to create a git annex repo.
+
+### What version of git-annex are you using? On what operating system?
+
+4.20130921-gd4739c5 compiled and installed by hand on debian wheezy.
+
+### Please provide any additional information below.
+
+[[!format sh """
+# Here's everything that has been logged by the git-annex assistant, as well as by programs it has run.
+
+[2013-11-04 22:42:50 EST] main: starting assistant version 4.20130921-gd4739c5
+(merging synced/git-annex into git-annex...)
+(Recording state in git...)
+
+ No known network monitor available through dbus; falling back to polling
+Already up-to-date.
+
+(scanning...) [2013-11-04 22:42:50 EST] Watcher: Performing startup scan
+04/Nov/2013:22:42:51 -0500 [Error#yesod-core] Unknown UUID @(yesod-core-1.2.4.2:Yesod.Core.Class.Yesod ./Yesod/Core/Class/Yesod.hs:485:5)
+04/Nov/2013:22:42:52 -0500 [Error#yesod-core] Unknown UUID @(yesod-core-1.2.4.2:Yesod.Core.Class.Yesod ./Yesod/Core/Class/Yesod.hs:485:5)
+04/Nov/2013:22:42:52 -0500 [Error#yesod-core] Unknown UUID @(yesod-core-1.2.4.2:Yesod.Core.Class.Yesod ./Yesod/Core/Class/Yesod.hs:485:5)
+(Recording state in git...)
+(Recording state in git...)
+(started...)
+
+ metadata.db still has writers, not adding
+[2013-11-04 22:42:59 EST] Committer: Adding cover.jpg Ars Techn..ibre.epub Cyberpres..ibre.epub cover.jpg cover.jpg Ars Techn..ibre.epub cover.jpg Democracy..ibre.epub cover.jpg and 11 other files
+add Calibre/Ars Technica [dim., 03 nov. 2013] (645)/cover.jpg (checksum...) ok
+add Calibre/Ars Technica [dim., 03 nov. 2013] (645)/Ars Technica [dim., 03 nov. 2013] - Calibre.epub (checksum...) ok
+add Calibre/Cyberpresse [lun., 04 nov. 2013] (647)/Cyberpresse [lun., 04 nov. 2013] - Calibre.epub (checksum...) ok
+add Calibre/Cyberpresse [lun., 04 nov. 2013] (647)/cover.jpg (checksum...) ok
+add Calibre/Ars Technica [sam., 02 nov. 2013] (642)/cover.jpg (checksum...) ok
+add Calibre/Ars Technica [sam., 02 nov. 2013] (642)/Ars Technica [sam., 02 nov. 2013] - Calibre.epub (checksum...) ok
+add Calibre/Democracy now! [lun., 04 nov. 2013] (649)/cover.jpg (checksum...) ok
+add Calibre/Democracy now! [lun., 04 nov. 2013] (649)/Democracy now! [lun., 04 nov. 2013] - Calibre.epub (checksum...) ok
+add Calibre/xkcd [lun., 04 nov. 2013] (646)/cover.jpg (checksum...) ok
+add Calibre/xkcd [lun., 04 nov. 2013] (646)/xkcd [lun., 04 nov. 2013] - Calibre.epub (checksum...) ok
+add Calibre/Cyberpresse [dim., 03 nov. 2013] (644)/cover.jpg (checksum...) ok
+add Calibre/Cyberpresse [dim., 03 nov. 2013] (644)/Cyberpresse [dim., 03 nov. 2013] - Calibre.epub (checksum...) ok
+add Calibre/Le Devoir [sam., 02 nov., 2013] (640)/cover.jpg (checksum...) ok
+add Calibre/Le Devoir [sam., 02 nov., 2013] (640)/Le Devoir [sam., 02 nov., 2013] - Calibre.epub (checksum...) ok
+add Calibre/Le Devoir [lun., 04 nov., 2013] (648)/cover.jpg (checksum...) ok
+add Calibre/Le Devoir [lun., 04 nov., 2013] (648)/Le Devoir [lun., 04 nov., 2013] - Calibre.epub (checksum...) ok
+add Calibre/Cyberpresse [sam., 02 nov. 2013] (641)/cover.jpg (checksum...) ok
+add Calibre/Cyberpresse [sam., 02 nov. 2013] (641)/Cyberpresse [sam., 02 nov. 2013] - Calibre.epub (checksum...) ok
+add Calibre/Le Devoir [dim., 03 nov., 2013] (643)/cover.jpg (checksum...) ok
+add Calibre/Le Devoir [dim., 03 nov., 2013] (643)/Le Devoir [dim., 03 nov., 2013] - Calibre.epub (checksum...) [2013-11-04 22:43:01 EST] Committer: Committing changes to git
+ok
+(Recording state in git...)
+(Recording state in git...)
+04/Nov/2013:22:43:51 -0500 [Error#yesod-core] Unknown UUID @(yesod-core-1.2.4.2:Yesod.Core.Class.Yesod ./Yesod/Core/Class/Yesod.hs:485:5)
+04/Nov/2013:22:47:24 -0500 [Error#yesod-core] Unknown UUID @(yesod-core-1.2.4.2:Yesod.Core.Class.Yesod ./Yesod/Core/Class/Yesod.hs:485:5)
+04/Nov/2013:22:47:24 -0500 [Error#yesod-core] Unknown UUID @(yesod-core-1.2.4.2:Yesod.Core.Class.Yesod ./Yesod/Core/Class/Yesod.hs:485:5)
+04/Nov/2013:22:47:24 -0500 [Error#yesod-core] Unknown UUID @(yesod-core-1.2.4.2:Yesod.Core.Class.Yesod ./Yesod/Core/Class/Yesod.hs:485:5)
+04/Nov/2013:22:52:29 -0500 [Error#yesod-core] Unknown UUID @(yesod-core-1.2.4.2:Yesod.Core.Class.Yesod ./Yesod/Core/Class/Yesod.hs:485:5)
+04/Nov/2013:22:52:30 -0500 [Error#yesod-core] Unknown UUID @(yesod-core-1.2.4.2:Yesod.Core.Class.Yesod ./Yesod/Core/Class/Yesod.hs:485:5)
+04/Nov/2013:22:52:30 -0500 [Error#yesod-core] Unknown UUID @(yesod-core-1.2.4.2:Yesod.Core.Class.Yesod ./Yesod/Core/Class/Yesod.hs:485:5)
+04/Nov/2013:22:56:47 -0500 [Error#yesod-core] Unknown UUID @(yesod-core-1.2.4.2:Yesod.Core.Class.Yesod ./Yesod/Core/Class/Yesod.hs:485:5)
+[2013-11-04 22:57:08 EST] Committer: Adding metadata.db-journal
+add metadata.db-journal (checksum...) [2013-11-04 22:57:08 EST] Committer: Committing changes to git
+[2013-11-04 22:57:09 EST] Committer: Adding metadata.db-journal metadata.db
+ok
+(Recording state in git...)
+(Recording state in git...)
+add metadata.db (checksum...) [2013-11-04 22:57:09 EST] Committer: Committing changes to git
+ok
+(Recording state in git...)
+(Recording state in git...)
+04/Nov/2013:22:57:12 -0500 [Error#yesod-core] Unknown UUID @(yesod-core-1.2.4.2:Yesod.Core.Class.Yesod ./Yesod/Core/Class/Yesod.hs:485:5)
+04/Nov/2013:22:57:15 -0500 [Error#yesod-core] Unknown UUID @(yesod-core-1.2.4.2:Yesod.Core.Class.Yesod ./Yesod/Core/Class/Yesod.hs:485:5)
+04/Nov/2013:22:57:18 -0500 [Error#yesod-core] Unknown UUID @(yesod-core-1.2.4.2:Yesod.Core.Class.Yesod ./Yesod/Core/Class/Yesod.hs:485:5)
+04/Nov/2013:22:57:20 -0500 [Error#yesod-core] Unknown UUID @(yesod-core-1.2.4.2:Yesod.Core.Class.Yesod ./Yesod/Core/Class/Yesod.hs:485:5)
+"""]]
+
+> I wonder if this couldn't be related to [[cannot determine uuid for origin]], although in this case the remote is just not added to `.git/config`. --[[anarcat]]
+
+> This was fixed in commit 44e1524be53373ddbf28d643bedf5455433c2b2e
+> on Sep 29th. You should update. [[done]]
+>
+> (It also sounds like your repository on markov is for some reason not
+> able to push its git repository to marcos. You might need to fix
+> something in your setup to get syncing working) --[[Joey]]
+>
+> > Humm.. Weird. Upgrading fixes the crash, but `marcos` still sees only
+> > one repository. It sees some syncs going on from `unknown`, and when
+> > I click on that `unknown` link, I get to edit that repository, and
+> > it sees it as `here`. So I am not sure I understand what is going
+> > on here.
+> >
+> > (As for the repo on `markov`, it does sync properly:
+> >
+> > anarcat@desktop008:books$ git annex sync
+> > commit
+> > ok
+> > pull origin
+> > From anarc.at:/srv/books
+> > 3b4fa7b..c35b13e git-annex -> origin/git-annex
+> > ok
+> >
+> > Or rather - it doesn't fail. But it doesn't push!
+> >
+> > anarcat@desktop008:books$ git push
+> > Everything up-to-date
+> >
+> > Note that git on `marcos` is the 1.8.4 backport for some reason.
+> > I know that branch tracking changed with that release, maybe
+> > that's the problem? --[[anarcat]])
+> >
+> > > So yep, I confirm that even in 4.20131105-g8efdc1a, the webapp
+> > > doesn't find the `markov` remote properly, even though
+> > > `git annex status` can:
+> > >
+> > > $ git annex status
+> > > repository mode: direct
+> > > trusted repositories: 0
+> > > semitrusted repositories: 3
+> > > 00000000-0000-0000-0000-000000000001 -- web
+> > > a75cbbf7-e055-423e-b375-443e0552c9e2 -- here (anarcat@marcos:/srv/books)
+> > > aa500f29-42d9-4777-ae02-4a2c3d47db44 -- anarcat@markov:~/books
+> > >
+> > > I see transfers happening, but they go to "unknown". The link is:
+> > >
+> > > http://127.0.0.1:56577/config/repository/edit/UUID%20%22aa500f29-42d9-4777-ae02-4a2c3d47db44%22?auth=...
+> > >
+> > > -- [[anarcat]]
+> > >
+> > > > I have filed this as a separate bug to close the discussion properly here, sorry for the noise. :) see [[bugs/remote_not_showing_up_in_webapp]] --[[anarcat]]
diff --git a/doc/bugs/internal_server_error_creating_repo_on_ssh_server.mdwn b/doc/bugs/internal_server_error_creating_repo_on_ssh_server.mdwn
new file mode 100644
index 000000000..7235757bf
--- /dev/null
+++ b/doc/bugs/internal_server_error_creating_repo_on_ssh_server.mdwn
@@ -0,0 +1,26 @@
+What steps will reproduce the problem?
+
+I downloaded the os x assistant today.
+
+I'd previously installed it but hadn't linked it to another repo.
+
+I tried to create a remote repo on an ssh server using the assistant.
+
+What is the expected output? What do you see instead?
+
+Creating a remote repo or giving an understandable error message.
+
+What version of git-annex are you using? On what operating system?
+
+3.20121212
+OS X 10.8.2 (Mountain Lion)
+
+The remote machine is running debian stable.
+
+Please provide any additional information below.
+
+Internal Server Error
+user error (gpg ["--quiet","--trust-model","always","--gen-random","--armor","1","512"] exited 127)
+git-annex version 3.20121212
+
+> [[done]], see comments --[[Joey]]
diff --git a/doc/bugs/internal_server_error_creating_repo_on_ssh_server/comment_1_4a2c9338d5c779496049d78e29cf5cbd._comment b/doc/bugs/internal_server_error_creating_repo_on_ssh_server/comment_1_4a2c9338d5c779496049d78e29cf5cbd._comment
new file mode 100644
index 000000000..04b25ecc2
--- /dev/null
+++ b/doc/bugs/internal_server_error_creating_repo_on_ssh_server/comment_1_4a2c9338d5c779496049d78e29cf5cbd._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlcxKZHglATIiJXD7jcxfYhkhgeFmcVFqE"
+ nickname="James"
+ subject="ignore"
+ date="2013-01-24T16:33:27Z"
+ content="""
+I had downloaded and installed the new version of git annex but not restarted the assistant. I rebooting my computer and started the new version (3.20130114) of the assistant and I was able to create a repo.
+"""]]
diff --git a/doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option.mdwn b/doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option.mdwn
new file mode 100644
index 000000000..d0ffaf083
--- /dev/null
+++ b/doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option.mdwn
@@ -0,0 +1,28 @@
+### Please describe the problem.
+I get this same internal server error when doing the encrypted rsync repo option:
+
+ user error (gpg ["--quiet","--trust-model","always","--gen-random","--armor","1","512"] exited 2)
+
+### What steps will reproduce the problem?
+
+1. click Configuration > repositories
+2. click Remote Server
+3. On "Ready to add remote server" screen click Use an encrypted repo
+
+Error pops up:
+
+Internal Server Error
+
+ user error (gpg ["--quiet","--trust-model","always","--gen-random","--armor","1","512"] exited 2)
+
+### What version of git-annex are you using? On what operating system?
+Currently using the file found here:
+
+http://downloads.kitenet.net/git-annex/OSX/current/10.7.5_Lion/
+
+Using MacOS 10.7.5 Lion
+
+[[!meta title="OSX gpg.conf auto-key-locate cert line breaks gpg in git-annex app"]]
+
+> [[done]]; all OSX builds now include a recent gpg that supports
+> this option. --[[Joey]]
diff --git a/doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option/comment_1_14a2f775f43a86129ce3649a06f8ba0b._comment b/doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option/comment_1_14a2f775f43a86129ce3649a06f8ba0b._comment
new file mode 100644
index 000000000..fd59b3e05
--- /dev/null
+++ b/doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option/comment_1_14a2f775f43a86129ce3649a06f8ba0b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.193"
+ subject="comment 1"
+ date="2013-06-30T20:36:02Z"
+ content="""
+There should be a more useful error message in the repository's debug.log, please post it.
+"""]]
diff --git a/doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option/comment_2_7b277320fcffd8d03e0d3d31398eb571._comment b/doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option/comment_2_7b277320fcffd8d03e0d3d31398eb571._comment
new file mode 100644
index 000000000..a99040871
--- /dev/null
+++ b/doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option/comment_2_7b277320fcffd8d03e0d3d31398eb571._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlpOeCs7zZLR-PBGPxUgjWlg7bwAAzQZyk"
+ nickname="Seth"
+ subject="comment 2"
+ date="2013-06-30T21:32:54Z"
+ content="""
+Here it is, with personal info redacted:
+
+(Recording state in git...)
+(encryption setup) gpg: /Users/bokeh/.gnupg/gpg.conf:233: invalid auto-key-locate list
+[2013-06-30 17:31:18 EDT] read: ssh-keygen [\"-F\",\"XXXXXXXXXXXX.com\"]
+[2013-06-30 17:31:18 EDT] read: ssh [\"-oNumberOfPasswordPrompts=0\",\"-n\",\"-p\",\"22\",\"XXXXXXXXXXXX@XXXXXXXXXXXX.com\",\"sh -c 'echo git-annex-probe loggedin;if which git-annex-shell; then echo git-annex-probe git-annex-shell; fi;if which rsync; then echo git-annex-probe rsync; fi;if which ~/.ssh/git-annex-shell; then echo git-annex-probe ~/.ssh/git-annex-shell; fi'\"]
+[2013-06-30 17:31:23 EDT] chat: ssh [\"XXXXXXXXXXXX@XXXXXXXXXXXX.com\",\"sh -c 'mkdir -p '\\"'\\"'annex'\\"'\\"'&&cd '\\"'\\"'annex'\\"'\\"''\"]
+(encryption setup) [2013-06-30 17:31:25 EDT] read: gpg [\"--quiet\",\"--trust-model\",\"always\",\"--gen-random\",\"--armor\",\"1\",\"512\"]
+gpg: /Users/bokeh/.gnupg/gpg.conf:233: invalid auto-key-locate list
+"""]]
diff --git a/doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option/comment_3_ba9dd8f2cc46640383d4339a3661571f._comment b/doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option/comment_3_ba9dd8f2cc46640383d4339a3661571f._comment
new file mode 100644
index 000000000..59ac0d158
--- /dev/null
+++ b/doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option/comment_3_ba9dd8f2cc46640383d4339a3661571f._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlpOeCs7zZLR-PBGPxUgjWlg7bwAAzQZyk"
+ nickname="Seth"
+ subject="comment 3"
+ date="2013-06-30T21:36:39Z"
+ content="""
+WOO!!! Found a \"solution\" here:
+
+http://eureka.ykyuen.info/2011/10/26/mac-gnupg-installation/
+
+Basically I commented out this line:
+
+ auto-key-locate cert pka ldap hkp://keys.gnupg.net
+
+Any clue why this would solve the problem?
+"""]]
diff --git a/doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option/comment_4_274ae39d55545bde0be931d7a6c42c94._comment b/doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option/comment_4_274ae39d55545bde0be931d7a6c42c94._comment
new file mode 100644
index 000000000..e89e8449d
--- /dev/null
+++ b/doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option/comment_4_274ae39d55545bde0be931d7a6c42c94._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.193"
+ subject="comment 4"
+ date="2013-07-02T16:52:43Z"
+ content="""
+The question is, where did this line in .gnupg/gpg.conf come from?
+
+It seems likely to me that something else put it there, and perhaps that has a version of gpg that supports some of the options, like ldap, while the version of gpg bundled with git-annex for OSX Lion does not.
+
+(I tried enabling that line on a Mountian Lion machine, and the gpg in git-annex accepts it.)
+"""]]
diff --git a/doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option/comment_5_242291d46acc61bdfc112e3316de528b._comment b/doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option/comment_5_242291d46acc61bdfc112e3316de528b._comment
new file mode 100644
index 000000000..12277738a
--- /dev/null
+++ b/doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option/comment_5_242291d46acc61bdfc112e3316de528b._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlpOeCs7zZLR-PBGPxUgjWlg7bwAAzQZyk"
+ nickname="Seth"
+ subject="comment 5"
+ date="2013-07-02T18:15:35Z"
+ content="""
+Hmm.. well I've used gpg before, so maybe this put it there? https://gpgtools.org/
+
+Installed that well before using git-annex.
+"""]]
diff --git a/doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option/comment_6_76b936263e82ca6c415a16ed57e770b4._comment b/doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option/comment_6_76b936263e82ca6c415a16ed57e770b4._comment
new file mode 100644
index 000000000..919027842
--- /dev/null
+++ b/doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option/comment_6_76b936263e82ca6c415a16ed57e770b4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 6"
+ date="2013-07-04T08:32:54Z"
+ content="""
+Just wondering if its because I have gnupg 1.1.0 on the Lion build machine thats causing the problem. I could try installing gnupg 2.0.19 if that will fix the problem. What version of gnupg is on the Mountain Lion build?
+"""]]
diff --git a/doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option/comment_7_9ccd3749fd9f32b0906c0b9428cc514f._comment b/doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option/comment_7_9ccd3749fd9f32b0906c0b9428cc514f._comment
new file mode 100644
index 000000000..57ca6cb79
--- /dev/null
+++ b/doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option/comment_7_9ccd3749fd9f32b0906c0b9428cc514f._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.193"
+ subject="comment 7"
+ date="2013-07-05T15:28:33Z"
+ content="""
+@Jimmy it has version 2.0.19 of MacGPG2.
+
+I think an upgrade is a great idea!
+"""]]
diff --git a/doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option/comment_8_4e8982668b5044b2286d55c90adb9da3._comment b/doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option/comment_8_4e8982668b5044b2286d55c90adb9da3._comment
new file mode 100644
index 000000000..b91884642
--- /dev/null
+++ b/doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option/comment_8_4e8982668b5044b2286d55c90adb9da3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.254.222"
+ subject="comment 8"
+ date="2013-07-08T18:03:54Z"
+ content="""
+Actually MacGPG caused problems on mountian lion and I have switched to gpg 1.4.13 from brew.
+"""]]
diff --git a/doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option/comment_9_aaf0ee250972d737a2ca57de5b5f1c0a._comment b/doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option/comment_9_aaf0ee250972d737a2ca57de5b5f1c0a._comment
new file mode 100644
index 000000000..611c3ebb9
--- /dev/null
+++ b/doc/bugs/internal_server_error_when_choosing_encrypted_rsync_repo_option/comment_9_aaf0ee250972d737a2ca57de5b5f1c0a._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkfHTPsiAcHEEN7Xl7WxiZmYq-vX7azxFY"
+ nickname="Vincent"
+ subject="comment 9"
+ date="2013-07-24T13:26:07Z"
+ content="""
+I was seeing this too in os/x until I upgraded to the version published on 2nd July.
+
+I was and am using macports gnupg, v1.4.13.
+
+Seems to be fixed for me now.
+"""]]
diff --git a/doc/bugs/interrupting_migration_causes_problems.mdwn b/doc/bugs/interrupting_migration_causes_problems.mdwn
new file mode 100644
index 000000000..68426e54a
--- /dev/null
+++ b/doc/bugs/interrupting_migration_causes_problems.mdwn
@@ -0,0 +1,52 @@
+Killing a migration from WORM to SHA256 with ^C breaks things; future attempts to do the migration fail:
+
+ #!/bin/bash
+
+ BASE=/tmp/migrate-bug
+
+ set -x
+
+ chmod -R +w $BASE
+ rm -rf $BASE
+ mkdir -p $BASE
+ cd $BASE
+
+ # create annex
+ git init .
+ git annex init
+
+ # make a big (sparse) file and add it
+ dd if=/dev/zero of=bigfile bs=1 count=0 seek=1G
+ git annex add --backend WORM bigfile
+ git commit -m 'added bigfile'
+
+ # look at status
+ git annex status
+
+ # now migrate it, but kill migration during checksum
+ # Simulate ^C by making a new process group and sending SIGINT
+ setsid git annex migrate --backend SHA256 bigfile &
+ PID=$!
+ sleep 1
+ kill -INT -$PID
+ wait
+
+ # look at status
+ git annex status
+
+ # this migration fails
+ git annex migrate --backend SHA256 bigfile
+
+ # but fsck says everything's OK
+ git annex fsck
+
+The error:
+
+ migrate bigfile
+ git-annex: /tmp/migrate-bug/.git/annex/objects/K9/V1/WORM-s1073741824-m1321566308--bigfile/WORM-s1073741824-m1321566308--bigfile: createLink: already exists (File exists)
+ failed
+ git-annex: migrate: 1 failed
+
+> Fixed it to delete the stale temp file. [[done]]
+>
+> Thanks for making such clear test cases, Jim! --[[Joey]]
diff --git a/doc/bugs/javascript_functions_qouting_issue.mdwn b/doc/bugs/javascript_functions_qouting_issue.mdwn
new file mode 100644
index 000000000..7f16462f5
--- /dev/null
+++ b/doc/bugs/javascript_functions_qouting_issue.mdwn
@@ -0,0 +1,44 @@
+**What is the expected output? What do you see instead?**
+
+SyntaxError: missing ( before formal parameters
+
+function longpoll_"sidebar"() {
+
+reposi...c5e0ead (строка 5, столбец 18)
+
+
+**Please provide any additional information below.**
+
+functions have illegal characters in their names: *function longpoll_"sidebar"*
+
+ <script>function longpoll_"sidebar"() {
+ longpoll(longpoll_"sidebar"_url, '"sidebar"'
+ , function() { setTimeout(longpoll_"sidebar", "10"); }
+ , function() { webapp_disconnected(); }
+ );
+ }
+ $(function() {
+ $.get("/notifier/sidebar?auth=bd717e7499f2c42363719c833d3df2d25b77cf42184aacbcd0f969895911a0208ba17fd4f468c4b97274d5e3f7f419260e5df7d83d2e7642524a89325c5e0ead", function(url){
+ longpoll_"sidebar"_url = url;
+ setTimeout(longpoll_"sidebar", "10");
+ });
+ });
+ function longpoll_"repolist"() {
+ longpoll(longpoll_"repolist"_url, '"repolist"'
+ , function() { setTimeout(longpoll_"repolist", "10"); }
+ , function() { webapp_disconnected(); }
+ );
+ }
+ $(function() {
+ $.get("/notifier/repolist/RepoSelector%20%7BonlyCloud%20=%20False,%20onlyConfigured%20=%20False,%20includeHere%20=%20True%7D?auth=bd717e7499f2c42363719c833d3df2d25b77cf42184aacbcd0f969895911a0208ba17fd4f468c4b97274d5e3f7f419260e5df7d83d2e7642524a89325c5e0ead", function(url){
+ longpoll_"repolist"_url = url;
+ setTimeout(longpoll_"repolist", "10");
+ });
+ });
+
+> This is already fixed in the 3.20130124 release. [[done]]
+>
+> (Standalone builds of that release are not yet available for Mountian
+> Lion.
+>
+> --[[Joey]]
diff --git a/doc/bugs/journal_commit_error_when_using_annex.mdwn b/doc/bugs/journal_commit_error_when_using_annex.mdwn
new file mode 100644
index 000000000..fe1928229
--- /dev/null
+++ b/doc/bugs/journal_commit_error_when_using_annex.mdwn
@@ -0,0 +1,21 @@
+Sorry for the noise - notabug - [[done]]
+
+Setup:
+
+* git-annex version: 3.20120629 on Debian unstable.
+* external RAID1 array connected via usb
+
+I did: <code> git-annex add \<a specific album of ogg files\> </code>
+
+When it gets to the fourth song, there is a long delay and a bunch of "journal commit I/O error" from the kernel start appearing. Then GNOME helpfully tells me that my drive was just connected (implying that it thought it was disconnected momentarily)
+
+Log outputs:
+
+Both trying to add whole album, failing at song 4
+
+* <http://paste.mitechie.com/show/745/>
+* <http://paste.mitechie.com/show/746/>
+
+Just trying to add song 4 individually
+
+* <http://paste.mitechie.com/show/747/> (lots o' journal commit I/O errors that time)
diff --git a/doc/bugs/journal_commit_error_when_using_annex/comment_1_38f60ca3503ea1530c4bd2cde5c9182f._comment b/doc/bugs/journal_commit_error_when_using_annex/comment_1_38f60ca3503ea1530c4bd2cde5c9182f._comment
new file mode 100644
index 000000000..de39249a8
--- /dev/null
+++ b/doc/bugs/journal_commit_error_when_using_annex/comment_1_38f60ca3503ea1530c4bd2cde5c9182f._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="comment 1"
+ date="2012-08-01T23:06:03Z"
+ content="""
+That's not a git-annex error, your drive is dying.
+
+I'm sure if you tried just playing the song you'll get the same errors.
+"""]]
diff --git a/doc/bugs/journal_commit_error_when_using_annex/comment_2_6de455a67f37d9ee0a307a78123781bf._comment b/doc/bugs/journal_commit_error_when_using_annex/comment_2_6de455a67f37d9ee0a307a78123781bf._comment
new file mode 100644
index 000000000..dd1e1c92b
--- /dev/null
+++ b/doc/bugs/journal_commit_error_when_using_annex/comment_2_6de455a67f37d9ee0a307a78123781bf._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://creativecommons.net/greg/identity"
+ ip="64.79.125.70"
+ subject="comment 2"
+ date="2012-08-01T23:22:03Z"
+ content="""
+Probably right, the song in question is not playing fully and causing same error.
+
+Time to go into crises mode...
+"""]]
diff --git a/doc/bugs/long_running_assistant_causes_resource_starvation_on_OSX.mdwn b/doc/bugs/long_running_assistant_causes_resource_starvation_on_OSX.mdwn
new file mode 100644
index 000000000..f556d16e9
--- /dev/null
+++ b/doc/bugs/long_running_assistant_causes_resource_starvation_on_OSX.mdwn
@@ -0,0 +1,30 @@
+What steps will reproduce the problem?
+
+leave the assistant running for multiple days
+
+What is the expected output?
+
+Glorious git-annex enlightenment
+
+What do you see instead?
+
+After ~2-3 days, there are hundreds of zombied git processes and the system is unable to fork new processes. This has occurred on 3 differently hardware configured mac's (macbooks and imacs) all running Mountain Lion 10.8.2 Build 12C3006
+In each case, once the system gets to this point, the only solution is forcing a reboot by holding down the power button as not even kill can spin up it's process.
+
+What version of git-annex are you using?
+
+ git-annex version: 3.20130122
+
+On what operating system?
+
+Mac OSX 10.8.2 Mountain Lion Build 12C3006
+
+Please provide any additional information below.
+
+I'm really not sure what to look for next. Happy to take suggestions.
+
+[!tag /design/assistant]]
+
+> [[done]], I found the zombie leak; the ConfigMonitor was
+> leaving one zombie every time it checked a push/pull.
+> Not a fast leak, but over time they would add up. --[[Joey]]
diff --git a/doc/bugs/long_running_assistant_causes_resource_starvation_on_OSX/comment_1_91c911c29fd126ddc365c561591f627e._comment b/doc/bugs/long_running_assistant_causes_resource_starvation_on_OSX/comment_1_91c911c29fd126ddc365c561591f627e._comment
new file mode 100644
index 000000000..d4e47b4eb
--- /dev/null
+++ b/doc/bugs/long_running_assistant_causes_resource_starvation_on_OSX/comment_1_91c911c29fd126ddc365c561591f627e._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.3.125"
+ subject="comment 1"
+ date="2013-02-05T19:27:35Z"
+ content="""
+Are you sure about that version number?
+
+A lot of work was done to avoid excessive numbers of zombie processes back in version 3.20111011. There should be no zombies anymore.
+"""]]
diff --git a/doc/bugs/long_running_assistant_causes_resource_starvation_on_OSX/comment_2_c316aead931a6a2377a4515bbb34ac5b._comment b/doc/bugs/long_running_assistant_causes_resource_starvation_on_OSX/comment_2_c316aead931a6a2377a4515bbb34ac5b._comment
new file mode 100644
index 000000000..4172a7ee8
--- /dev/null
+++ b/doc/bugs/long_running_assistant_causes_resource_starvation_on_OSX/comment_2_c316aead931a6a2377a4515bbb34ac5b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmRFKwny4rArBaz-36xTcsJYqKIgdDaw5Q"
+ nickname="Andrew"
+ subject="comment 2"
+ date="2013-02-05T21:33:12Z"
+ content="""
+That was compiled from the source tree in git. I'm letting it run again today to see if I can see it happen.
+"""]]
diff --git a/doc/bugs/lsof__47__committer_thread_loops_occassionally.mdwn b/doc/bugs/lsof__47__committer_thread_loops_occassionally.mdwn
new file mode 100644
index 000000000..335581e20
--- /dev/null
+++ b/doc/bugs/lsof__47__committer_thread_loops_occassionally.mdwn
@@ -0,0 +1,53 @@
+I've noticed this to occur occassionally
+
+<pre>
+laplace:atest jtang$ ls
+1@ 2@ 3@ 4@ 5@ readme.txt@
+laplace:atest jtang$ git annex watch -d --foreground
+watch . [2012-07-29 11:49:26 IST] read: git ["--git-dir=/Users/jtang/sandbox/atest/.git","--work-tree=/Users/jtang/sandbox/atest","show-ref","git-annex"]
+[2012-07-29 11:49:26 IST] read: git ["--git-dir=/Users/jtang/sandbox/atest/.git","--work-tree=/Users/jtang/sandbox/atest","show-ref","--hash","refs/heads/git-annex"]
+[2012-07-29 11:49:26 IST] read: git ["--git-dir=/Users/jtang/sandbox/atest/.git","--work-tree=/Users/jtang/sandbox/atest","log","refs/heads/git-annex..f85faa60e73efabc2e92f837b19c3918d3ab030f","--oneline","-n1"]
+[2012-07-29 11:49:26 IST] chat: git ["--git-dir=/Users/jtang/sandbox/atest/.git","--work-tree=/Users/jtang/sandbox/atest","cat-file","--batch"]
+(scanning...) [2012-07-29 11:49:26 IST] Assistant: all threads started
+[2012-07-29 11:49:26 IST] Merger: watching /Users/jtang/sandbox/atest/.git/refs/heads/synced
+[2012-07-29 11:49:26 IST] TransferWatcher: watching for transfers
+[2012-07-29 11:49:26 IST] read: git ["--git-dir=/Users/jtang/sandbox/atest/.git","--work-tree=/Users/jtang/sandbox/atest","symbolic-ref","HEAD"]
+[2012-07-29 11:49:26 IST] call: git ["--git-dir=/Users/jtang/sandbox/atest/.git","--work-tree=/Users/jtang/sandbox/atest","add","--update"]
+[2012-07-29 11:49:26 IST] Merger: merging changes into Just refs/heads/master
+[2012-07-29 11:49:26 IST] call: git ["--git-dir=/Users/jtang/sandbox/atest/.git","--work-tree=/Users/jtang/sandbox/atest","merge","--no-edit","refs/heads/synced/master"]
+(started...) [2012-07-29 11:49:26 IST] Watcher: watching .
+[2012-07-29 11:49:26 IST] WebApp: running on port 60042
+Already up-to-date.
+[2012-07-29 11:49:26 IST] Watcher: add symlink ./1
+[2012-07-29 11:49:26 IST] chat: git ["--git-dir=/Users/jtang/sandbox/atest/.git","--work-tree=/Users/jtang/sandbox/atest","cat-file","--batch"]
+[2012-07-29 11:49:26 IST] Watcher: add symlink ./2
+[2012-07-29 11:49:26 IST] Watcher: add symlink ./3
+[2012-07-29 11:49:26 IST] Watcher: add symlink ./4
+[2012-07-29 11:49:26 IST] Watcher: add symlink ./5
+[2012-07-29 11:49:26 IST] Watcher: add symlink ./readme.txt
+[2012-07-29 11:49:27 IST] Committer: committing 6 changes
+(Recording state in git...)
+[2012-07-29 11:49:27 IST] feed: git ["--git-dir=/Users/jtang/sandbox/atest/.git","--work-tree=/Users/jtang/sandbox/atest","update-index","-z","--index-info"]
+[2012-07-29 11:49:27 IST] call: git ["--git-dir=/Users/jtang/sandbox/atest/.git","--work-tree=/Users/jtang/sandbox/atest","commit","--allow-empty-message","-m","","--allow-empty","--quiet"]
+[2012-07-29 11:49:28 IST] read: git ["--git-dir=/Users/jtang/sandbox/atest/.git","--work-tree=/Users/jtang/sandbox/atest","symbolic-ref","HEAD"]
+[2012-07-29 11:49:28 IST] Pusher: pushing to []
+[2012-07-29 11:49:28 IST] call: git ["--git-dir=/Users/jtang/sandbox/atest/.git","--work-tree=/Users/jtang/sandbox/atest","branch","-f","synced/master"]
+[2012-07-29 11:49:28 IST] read: git ["--git-dir=/Users/jtang/sandbox/atest/.git","--work-tree=/Users/jtang/sandbox/atest","symbolic-ref","HEAD"]
+[2012-07-29 11:49:28 IST] Merger: merging changes into Just refs/heads/master
+[2012-07-29 11:49:28 IST] call: git ["--git-dir=/Users/jtang/sandbox/atest/.git","--work-tree=/Users/jtang/sandbox/atest","merge","--no-edit","refs/heads/synced/master"]
+Already up-to-date.
+[2012-07-29 11:49:43 IST] Watcher: file added ./.gitignore
+[2012-07-29 11:49:43 IST] read: lsof ["-F0can","+d","/Users/jtang/sandbox/atest/.git/annex/tmp/"]
+[2012-07-29 11:49:44 IST] Committer: delaying commit of 0 changes
+[2012-07-29 11:49:45 IST] read: lsof ["-F0can","+d","/Users/jtang/sandbox/atest/.git/annex/tmp/"]
+[2012-07-29 11:49:46 IST] Committer: delaying commit of 0 changes
+[2012-07-29 11:49:47 IST] read: lsof ["-F0can","+d","/Users/jtang/sandbox/atest/.git/annex/tmp/"]
+[2012-07-29 11:49:48 IST] Committer: delaying commit of 0 changes
+[2012-07-29 11:49:49 IST] read: lsof ["-F0can","+d","/Users/jtang/sandbox/atest/.git/annex/tmp/"]
+</pre>
+
+I ran " git annex watch -d --foreground" to watch what was going one, and just created a .gitignore file and the the commiter/lsof thread just loops over and over.... I only noticed as my laptop battery had drained at somepoint when git-annex was running in the background.
+
+[[!meta title="assistant: lsof/committer thread loops occassionally"]]
+
+> Closing this since it doesn't seem reproducible. [[done]] --[[Joey]]
diff --git a/doc/bugs/lsof__47__committer_thread_loops_occassionally/comment_1_f8d1720aa26c719609720acf0772606e._comment b/doc/bugs/lsof__47__committer_thread_loops_occassionally/comment_1_f8d1720aa26c719609720acf0772606e._comment
new file mode 100644
index 000000000..521d2e0cb
--- /dev/null
+++ b/doc/bugs/lsof__47__committer_thread_loops_occassionally/comment_1_f8d1720aa26c719609720acf0772606e._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.133"
+ subject="probably a kqueue specific problem..."
+ date="2012-07-29T18:10:12Z"
+ content="""
+I don't think this would eat your battery badly; it's looping for sure, but with a hardcoded 1 second delay I put in to guard against it eating all CPU.
+
+I tried to fix this in commit c4023f785834bc237e5fcdb69e275bbae10dd40b, but I sort of doubt I did.
+I made one more commit that will at least tell us what file it is trying to check over and over with lsof.
+"""]]
diff --git a/doc/bugs/lsof__47__committer_thread_loops_occassionally/comment_2_0527569ea2924721d19dadcf4fe0ec5a._comment b/doc/bugs/lsof__47__committer_thread_loops_occassionally/comment_2_0527569ea2924721d19dadcf4fe0ec5a._comment
new file mode 100644
index 000000000..438fdcb3c
--- /dev/null
+++ b/doc/bugs/lsof__47__committer_thread_loops_occassionally/comment_2_0527569ea2924721d19dadcf4fe0ec5a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.2.84"
+ subject="comment 2"
+ date="2012-09-19T17:33:20Z"
+ content="""
+Have you seen this anymore?
+"""]]
diff --git a/doc/bugs/lsof__47__committer_thread_loops_occassionally/comment_3_5b67ff08a897ea3d2266ccc910ab4278._comment b/doc/bugs/lsof__47__committer_thread_loops_occassionally/comment_3_5b67ff08a897ea3d2266ccc910ab4278._comment
new file mode 100644
index 000000000..a89b12596
--- /dev/null
+++ b/doc/bugs/lsof__47__committer_thread_loops_occassionally/comment_3_5b67ff08a897ea3d2266ccc910ab4278._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 3"
+ date="2012-09-19T20:17:00Z"
+ content="""
+No, I've not noticed this recently, I would consider this issue to be closed for now.
+"""]]
diff --git a/doc/bugs/make_SHA512E_the_default.mdwn b/doc/bugs/make_SHA512E_the_default.mdwn
new file mode 100644
index 000000000..46f18130c
--- /dev/null
+++ b/doc/bugs/make_SHA512E_the_default.mdwn
@@ -0,0 +1,29 @@
+What steps will reproduce the problem?
+
+As described in
+http://git-annex.branchable.com/backends/#comment-3c1cd45d2a015b4fc412dd813293ad7d
+, sha512 is faster. On my 64-bit system, the speed difference is about
+1.5times.
+
+What is the expected output? What do you see instead?
+
+
+What version of git-annex are you using? On what operating system?
+
+
+Please provide any additional information below.
+
+> You are free to change the default in your own annexes. This is very easy
+> to do: `echo '* annex.backend=SHA512E' > .gitattributes`
+>
+> I don't anticipate moving to SHA512, because
+>
+> 1. It makes `ls -l` really ugly. Each symlink takes like 4 lines
+> on an 80 column terminal.
+> 2. There are better hashes coming. Particularly SHA3. That should be
+> faster and/or more secure. And without adding so much length to the
+> hash.
+>
+> --[[Joey]]
+
+[[done]]
diff --git a/doc/bugs/make_install_can__39__t_be_used_with_sudo.mdwn b/doc/bugs/make_install_can__39__t_be_used_with_sudo.mdwn
new file mode 100644
index 000000000..c43075e58
--- /dev/null
+++ b/doc/bugs/make_install_can__39__t_be_used_with_sudo.mdwn
@@ -0,0 +1,20 @@
+What steps will reproduce the problem?
+In the git-annex tree,
+
+ $ make
+ $ sudo make install
+
+What is the expected output? What do you see instead?
+
+One would expect git-annex to be installed in the configured prefix. Unfortunately, make tries to rebuild the "all" target before "install". This fails (presumably) due to incorrect environment state,
+
+ ghc -O2 -Wall -ignore-package monads-fd -ignore-package monads-tf -outputdir tmp -IUtility -DWITH_ASSISTANT -DWITH_S3 -DWITH_INOTIFY --make git-annex Utility/libdiskfree.o
+
+ Utility/FileSystemEncoding.hs:17:8:
+ Could not find module `Data.Bits.Utils':
+ Use -v to see a list of the files searched for.
+ make: *** [git-annex] Error 1
+
+Removing "all" from the dependencies of "install" allows the process to run to completion, although this is clearly not a satisfactory solution.
+
+> [[fixed|done]] using an ugly stamp file. --[[Joey]]
diff --git a/doc/bugs/make_install_doesn__39__t_create_git-annex-shell.mdwn b/doc/bugs/make_install_doesn__39__t_create_git-annex-shell.mdwn
new file mode 100644
index 000000000..471c91e9d
--- /dev/null
+++ b/doc/bugs/make_install_doesn__39__t_create_git-annex-shell.mdwn
@@ -0,0 +1,62 @@
+### Please describe the problem.
+There is no git-annex-shell command in path and thus sync with ssh server fails. If I symlink /usr/bin/git-annex-shell -> /usr/bin/git-annex, it complains that key is already present in annex and errors out. There is executable git-annex-shell in server's ~/.ssh/
+
+### What steps will reproduce the problem?
+Start webapp to sync local repo with ssh server.
+
+### What version of git-annex are you using? On what operating system?
+git-annex 4.20130627 on Gentoo
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+[2013-07-08 17:28:48 EEST] main: starting assistant version 4.20130627
+[2013-07-08 17:28:49 EEST] TransferScanner: Syncing with netbook_Lit, sigma_Lit
+
+ dbus failed; falling back to mtab polling (SocketError {socketErrorMessage = "connect: does not exist (Connection refused)", socketErrorFatal = True, socketErrorAddress = Just (Address "unix:abstract=/tmp/dbus-HBxh6EyMJ3,guid=adc3101676daede2a128013351daa535")})
+Already up-to-date.
+
+(scanning...) [2013-07-08 17:28:49 EEST] Watcher: Performing startup scan
+Already up-to-date.
+Already up-to-date.
+
+
+(started...) Everything up-to-date
+Everything up-to-date
+bash: git-annex-shell: command not found
+rsync: connection unexpectedly closed (0 bytes received so far) [sender]
+rsync error: remote command not found (code 127) at io.c(605) [sender=3.0.9]
+bash: git-annex-shell: command not found
+rsync: connection unexpectedly closed (0 bytes received so far) [sender]
+rsync error: remote command not found (code 127) at io.c(605) [sender=3.0.9]
+
+
+[2013-07-08 17:50:23 EEST] main: starting assistant version 4.20130627
+[2013-07-08 17:50:23 EEST] TransferScanner: Syncing with netbook_Lit, sigma_Lit
+
+ dbus failed; falling back to mtab polling (SocketError {socketErrorMessage = "connect: does not exist (Connection refused)", socketErrorFatal = True, socketErrorAddress = Just (Address "unix:abstract=/tmp/dbus-HBxh6EyMJ3,guid=adc3101676daede2a128013351daa535")})
+Already up-to-date.
+
+(scanning...) [2013-07-08 17:50:23 EEST] Watcher: Performing startup scan
+Already up-to-date.
+Already up-to-date.
+
+
+(started...) Everything up-to-date
+Everything up-to-date
+git-annex-shell: key is already present in annex
+rsync: connection unexpectedly closed (0 bytes received so far) [sender]
+rsync error: error in rsync protocol data stream (code 12) at io.c(605) [sender=3.0.9]
+git-annex-shell: key is already present in annex
+rsync: connection unexpectedly closed (0 bytes received so far) [sender]
+rsync error: error in rsync protocol data stream (code 12) at io.c(605) [sender=3.0.9]
+
+
+
+# End of transcript or log.
+"""]]
+
+[[!tag done]]
diff --git a/doc/bugs/make_install_doesn__39__t_create_git-annex-shell/comment_1_8c20edd8c6483500f807528d616c6dfd._comment b/doc/bugs/make_install_doesn__39__t_create_git-annex-shell/comment_1_8c20edd8c6483500f807528d616c6dfd._comment
new file mode 100644
index 000000000..ad3273723
--- /dev/null
+++ b/doc/bugs/make_install_doesn__39__t_create_git-annex-shell/comment_1_8c20edd8c6483500f807528d616c6dfd._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.254.222"
+ subject="comment 1"
+ date="2013-07-08T16:14:37Z"
+ content="""
+The Makefile contains, for the install target:
+
+[[!format sh \"\"\"
+ ln -sf git-annex $(DESTDIR)$(PREFIX)/bin/git-annex-shell
+\"\"\"]]
+
+How was git-annex installed on your server?
+"""]]
diff --git a/doc/bugs/make_install_doesn__39__t_create_git-annex-shell/comment_2_8b2cf0fe7219e0bc83fd326adbf26c8a._comment b/doc/bugs/make_install_doesn__39__t_create_git-annex-shell/comment_2_8b2cf0fe7219e0bc83fd326adbf26c8a._comment
new file mode 100644
index 000000000..452b55d40
--- /dev/null
+++ b/doc/bugs/make_install_doesn__39__t_create_git-annex-shell/comment_2_8b2cf0fe7219e0bc83fd326adbf26c8a._comment
@@ -0,0 +1,31 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm01ida6POv7vqyUYtOlymEbJTbrImAIzM"
+ nickname="Reinis"
+ subject="comment 2"
+ date="2013-07-08T18:09:50Z"
+ content="""
+That is Gentoo box and git-annex is installed using the following ebuild:
+
+[[https://github.com/gentoo-haskell/gentoo-haskell/blob/master/dev-vcs/git-annex/git-annex-4.20130627.ebuild]]
+
+which uses cabal to install it. It uses also the following eclass:
+
+[[http://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/eclass/haskell-cabal.eclass?revision=1.40&view=markup]]
+
+The main functions of interest there are cabal-bootstrap(), cabal-copy() and cabal_src_install(). I'm not familiar enough with haskell nor with cabal to follow trough in detail how the setup program is constructed and how it works, but the end result is that this is all that is installed. I don't know if normal cabal installs work as intended, maybe something there needs to be adjusted?
+
+[[!format sh \"\"\"
+ * Contents of dev-vcs/git-annex-4.20130627:
+/usr
+/usr/bin
+/usr/bin/git-annex
+/usr/lib64
+/usr/lib64/ghc-7.6.3
+/usr/lib64/ghc-7.6.3/gentoo
+/usr/lib64/ghc-7.6.3/gentoo/git-annex-4.20130627.conf
+/usr/share
+/usr/share/doc
+/usr/share/doc/git-annex-4.20130627
+/usr/share/doc/git-annex-4.20130627/COPYRIGHT.bz2
+\"\"\" ]]
+"""]]
diff --git a/doc/bugs/make_install_doesn__39__t_create_git-annex-shell/comment_3_25fe06eb127e59a4a07aeb52a5cfeabe._comment b/doc/bugs/make_install_doesn__39__t_create_git-annex-shell/comment_3_25fe06eb127e59a4a07aeb52a5cfeabe._comment
new file mode 100644
index 000000000..fd97f6a21
--- /dev/null
+++ b/doc/bugs/make_install_doesn__39__t_create_git-annex-shell/comment_3_25fe06eb127e59a4a07aeb52a5cfeabe._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.235"
+ subject="comment 3"
+ date="2013-07-08T18:22:18Z"
+ content="""
+`cabal install` also creates the git-annex-shell symlink. I have filed a bug on the ebuild: <https://github.com/gentoo-haskell/gentoo-haskell/issues/247>
+"""]]
diff --git a/doc/bugs/make_install_doesn__39__t_create_git-annex-shell/comment_4_ec78032ba62d6918baa2c0b07ead5b50._comment b/doc/bugs/make_install_doesn__39__t_create_git-annex-shell/comment_4_ec78032ba62d6918baa2c0b07ead5b50._comment
new file mode 100644
index 000000000..86f1b46f0
--- /dev/null
+++ b/doc/bugs/make_install_doesn__39__t_create_git-annex-shell/comment_4_ec78032ba62d6918baa2c0b07ead5b50._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm01ida6POv7vqyUYtOlymEbJTbrImAIzM"
+ nickname="Reinis"
+ subject="comment 4"
+ date="2013-07-08T18:44:59Z"
+ content="""
+Thanks! That leaves the issue that even when manually creating the symlink it still errors out (second half of the log in original report), but that probably is another issue. Should I open separate report for it? There was something similar in [[http://git-annex.branchable.com/bugs/Rsync_remote_created_via_webapp_remains_empty/]], but the command= part was in the file on my local computer only and removing it didn't make any difference.
+"""]]
diff --git a/doc/bugs/making_annex-merge_try_a_fast-forward.mdwn b/doc/bugs/making_annex-merge_try_a_fast-forward.mdwn
new file mode 100644
index 000000000..41a5a2a58
--- /dev/null
+++ b/doc/bugs/making_annex-merge_try_a_fast-forward.mdwn
@@ -0,0 +1,35 @@
+While merging the git-annex branch, annex-merge does not end up in a fast-forward even when it would be possible.
+But as sometimes annex-merge takes time, it would probably be worth it
+(but maybe I miss something with my workflow...).
+
+> I don't think a fast-forward will make things much faster.
+>
+> git-annex needs its index file to be updated to reflect the merge.
+> With the union merge it does now, this can be accomplished by using
+> `git-diff-index` to efficiently get a list of files that have changed,
+> and only merge those changes into the index with `git-update-index`.
+> Then the index gets committed, generating the merge.
+>
+> To fast-forward, it would just reset the git-annex branch to the new
+> head of the remote it's merging to. But then the index needs to be
+> updated to reflect this new head too. To do that needs the same method
+> described above, essentially (with the difference that it can replace
+> files in the index with the version from the git-annex branch, rather
+> than merging in the changes... but only if the index is known to be
+> already committed and have no other changes, which would require both
+> an attempt to commit it first, and
+> locking).
+>
+> So will take basically the same amount of time, except
+> it would not need to commit the index at the end of the merge. The
+> most expensive work is the `git-diff-index` and `git-update-index`,
+> which are not avoided.
+>
+> Although, perhaps fast-forward merge would use slightly
+> less space. --[[Joey]]
+
+>> To avoid the ladder-merge between two repositories described at
+>> <http://sprunge.us/LOMU>, seems a fast-forward should be detected and
+>> written to git, even if the index is still updated the current way.
+>> [[done]]
+>> --[[Joey]]
diff --git a/doc/bugs/manpage_has_slight_indentation_error.mdwn b/doc/bugs/manpage_has_slight_indentation_error.mdwn
new file mode 100644
index 000000000..56d9d2266
--- /dev/null
+++ b/doc/bugs/manpage_has_slight_indentation_error.mdwn
@@ -0,0 +1,38 @@
+### Please describe the problem.
+
+The "import" section of the manpage has an indentation error.
+
+### What steps will reproduce the problem?
+
+man git-annex
+
+### What version of git-annex are you using? On what operating system?
+
+anything after 20130827, i believe.
+
+### Please provide any additional information below.
+
+silly patch:
+
+[[!format diff """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+diff --git a/Build/mdwn2man b/Build/mdwn2man
+index ba5919b..b3ee404 100755
+--- a/Build/mdwn2man
++++ b/Build/mdwn2man
+@@ -25,7 +25,7 @@ while (<>) {
+ $inlist=1;
+ $spippara=0;
+ }
+- elsif (/.SH/) {
++ elsif (/^.SH/) {
+ $skippara=0;
+ $inlist=0;
+ }
+# End of transcript or log.
+"""]]
+
+-- [[anarcat]]
+
+> [[applied|done]] --[[Joey]]
diff --git a/doc/bugs/map_not_respecting_annex_ssh_options__63__.mdwn b/doc/bugs/map_not_respecting_annex_ssh_options__63__.mdwn
new file mode 100644
index 000000000..63dfec4ac
--- /dev/null
+++ b/doc/bugs/map_not_respecting_annex_ssh_options__63__.mdwn
@@ -0,0 +1,38 @@
+### What steps will reproduce the problem?
+
+1. Have a remote that uses annex-ssh-options to specify an sshkey which is needed to invoke git-annex-shell on that remote.
+2. Run git-annex map.
+
+### What is the expected output? What do you see instead?
+
+I expect to see a map without any errors complaining of commands not recognized.
+
+Instead I see:
+
+ greg@x200s:~/Pictures/Photos$ git-annex map
+ map /home/greg/Pictures/Photos ok
+ map 60justin (sshing...)
+ ok
+ map rose (sshing...)
+ fatal: unrecognized command 'cd '/home/greg/Media/Pictures/Photos/' && git config --null --list'
+ git-annex-shell: git-shell failed
+
+relevant part of .git/config:
+
+ [remote "rose"]
+ url = greg@rose.makesad.us:/home/greg/Media/Pictures/Photos/
+ fetch = +refs/heads/*:refs/remotes/rose/*
+ annex-ssh-options = "-i /home/greg/.ssh/annex.x200s_rsa"
+ annex-trustlevel = trusted
+ annex-uuid = c0e4106e-2631-11e2-9749-1bfa37a61069
+
+
+### What version of git-annex are you using? On what operating system?
+
+ git-annex version: 3.20121017
+ local repository version: 3
+ default repository version: 3
+ supported repository versions: 3
+ upgrade supported from repository versions: 0 1 2
+
+> [[done]], see comment --[[Joey]]
diff --git a/doc/bugs/map_not_respecting_annex_ssh_options__63__/comment_1_c63a1ed5909d53f116f06e60aba74dc6._comment b/doc/bugs/map_not_respecting_annex_ssh_options__63__/comment_1_c63a1ed5909d53f116f06e60aba74dc6._comment
new file mode 100644
index 000000000..029373945
--- /dev/null
+++ b/doc/bugs/map_not_respecting_annex_ssh_options__63__/comment_1_c63a1ed5909d53f116f06e60aba74dc6._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.72"
+ subject="comment 1"
+ date="2012-12-05T17:00:21Z"
+ content="""
+To map a remote, it needs to run `git config --list` on the remote, and the remote may be a non-git-annex git remote. So mapping does a regular ssh first, and cannot use annex.ssh-options (because that would dump it into git-annex-shell). If that fails, it *does* fall back to using git-annex-shell, and will then use annex.ssh-options.
+
+So, not a bug, I believe.
+"""]]
diff --git a/doc/bugs/merge_causes_out_of_memory_on_large_repos.mdwn b/doc/bugs/merge_causes_out_of_memory_on_large_repos.mdwn
new file mode 100644
index 000000000..c081f9799
--- /dev/null
+++ b/doc/bugs/merge_causes_out_of_memory_on_large_repos.mdwn
@@ -0,0 +1,26 @@
+### Please describe the problem.
+
+`git annex merge` goes out of memory on a large repo.
+
+
+### What steps will reproduce the problem?
+
+ $ git annex merge
+ merge git-annex git-annex: out of memory (requested 1048576 bytes)
+
+### What version of git-annex are you using? On what operating system?
+
+ git-annex version: 4.20130827
+ build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP DNS
+
+On debian wheezy i386
+
+### Please provide any additional information below.
+
+The repository contains a lot of files:
+
+ $ cd .git/objects
+ $ find . -type f | wc -l
+ 1091548
+
+[[!tag moreinfo]]
diff --git a/doc/bugs/merge_causes_out_of_memory_on_large_repos/comment_1_6d47485728ea65a9b555f8be7159dea5._comment b/doc/bugs/merge_causes_out_of_memory_on_large_repos/comment_1_6d47485728ea65a9b555f8be7159dea5._comment
new file mode 100644
index 000000000..f87a9a84d
--- /dev/null
+++ b/doc/bugs/merge_causes_out_of_memory_on_large_repos/comment_1_6d47485728ea65a9b555f8be7159dea5._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnxlx1UrzVhdy6_gFjzmF42x6QXxBUxg00"
+ nickname="Jakukyo"
+ subject="pre-commit hook of git annex"
+ date="2013-09-11T00:58:09Z"
+ content="""
+The pre-commit hook of git annex throws an 'out of memory' error, too.
+
+As a workaround, I've deleted ~/.git/hooks/pre-commit, and use `git merge` manually.
+"""]]
diff --git a/doc/bugs/merge_causes_out_of_memory_on_large_repos/comment_2_06723d13ecdaf87de5ff2b209e3c5198._comment b/doc/bugs/merge_causes_out_of_memory_on_large_repos/comment_2_06723d13ecdaf87de5ff2b209e3c5198._comment
new file mode 100644
index 000000000..76a0d2fd4
--- /dev/null
+++ b/doc/bugs/merge_causes_out_of_memory_on_large_repos/comment_2_06723d13ecdaf87de5ff2b209e3c5198._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.2.134"
+ subject="comment 2"
+ date="2013-09-13T18:38:11Z"
+ content="""
+Can you run this so I can get a better idea of the size of this repository:
+
+git ls-tree -r git-annex | wc -l
+"""]]
diff --git a/doc/bugs/merge_causes_out_of_memory_on_large_repos/comment_3_9f83ef190547b291a715cda55b7977d4._comment b/doc/bugs/merge_causes_out_of_memory_on_large_repos/comment_3_9f83ef190547b291a715cda55b7977d4._comment
new file mode 100644
index 000000000..11f03b39d
--- /dev/null
+++ b/doc/bugs/merge_causes_out_of_memory_on_large_repos/comment_3_9f83ef190547b291a715cda55b7977d4._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.14.105"
+ subject="comment 3"
+ date="2013-09-19T18:53:14Z"
+ content="""
+I just fixed a memory leak that occurred when large files were checked directly into git (perhaps by accident by committing files manually when using direct mode). However, I don't think it affected `git annex merge`.
+
+Still need information about how to reproduce this bug...
+"""]]
diff --git a/doc/bugs/merge_causes_out_of_memory_on_large_repos/comment_4_0e32ae0300472c56079cfbcd78a3e386._comment b/doc/bugs/merge_causes_out_of_memory_on_large_repos/comment_4_0e32ae0300472c56079cfbcd78a3e386._comment
new file mode 100644
index 000000000..d1c447980
--- /dev/null
+++ b/doc/bugs/merge_causes_out_of_memory_on_large_repos/comment_4_0e32ae0300472c56079cfbcd78a3e386._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnxlx1UrzVhdy6_gFjzmF42x6QXxBUxg00"
+ nickname="Jakukyo"
+ subject="size of repo"
+ date="2013-09-21T09:32:03Z"
+ content="""
+ $ git ls-tree -r git-annex | wc -l
+ 29273
+"""]]
diff --git a/doc/bugs/merge_causes_out_of_memory_on_large_repos/comment_5_e8998716107e7ae8d0e8d332812517ad._comment b/doc/bugs/merge_causes_out_of_memory_on_large_repos/comment_5_e8998716107e7ae8d0e8d332812517ad._comment
new file mode 100644
index 000000000..272dc2fd2
--- /dev/null
+++ b/doc/bugs/merge_causes_out_of_memory_on_large_repos/comment_5_e8998716107e7ae8d0e8d332812517ad._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.220"
+ subject="comment 5"
+ date="2013-09-25T18:36:39Z"
+ content="""
+That doesn't look very big, I merge one 3x that large on a 128 mb machine.
+
+I think you will need to either email me privately so I can get a copy of your repository to investigate with ... or you can try to investigate on your own.
+
+I think the first things I would try to debug this are to look over `git annex merge --debug` and see if I see anything unusual, and then I would probably `git checkout git-annex` in the repository, and wc -l on all the files and see if any file has a lot of lines, or is otherwise very large.
+
+If that found nothing, my next step would be to rebuild git-annex from source with memory profiling enabled, as explained in this book, and try to get a memory profiling graph that explained what was using up the memory. <http://book.realworldhaskell.org/read/profiling-and-optimization.html>
+"""]]
diff --git a/doc/bugs/microsd__47__thumbdrives_seem_to_die_when_using_the_ARM_build.mdwn b/doc/bugs/microsd__47__thumbdrives_seem_to_die_when_using_the_ARM_build.mdwn
new file mode 100644
index 000000000..c10176463
--- /dev/null
+++ b/doc/bugs/microsd__47__thumbdrives_seem_to_die_when_using_the_ARM_build.mdwn
@@ -0,0 +1,36 @@
+### Please describe the problem.
+
+1 thumb drive became corrupted when using as a server on raspberry pi, and 2 microSD cards when using as a client in my phone. Both happened during syncing largish repository. (corrupted = permanent input/output error)
+
+* Put git annex on my android phone with a 64GB (FAT) micro SD, fired up git annex, it got reported as corrupted half on hour later, reformatting worked but got reported as corrupted again.
+
+* Put git annex assistant on my raspberry pi, one of the thumbdrives in my LVM (ext4) got corrupted shortly after I began using the assistant. I replaced them with a cheap real SSD drive, and had no problem since.
+
+* Put git annex back on my android phone. Kept it going for an extended sync session, but it never started syncing. I kept it going for an hour or so, and my new 32GB microSD (FAT) got corrupted.
+
+The pattern is nothing like proof, but it seems to be too regular to be completely coincidental. The pattern seems to be: ARM + (SDcard|USBstick) + Assistant = drive corruption.
+
+My guess is that the ARM build might have some kind of unlucky write pattern or loop that causes increased wear, but I know very little of the interna.
+
+### What steps will reproduce the problem?
+
+* Get a raspberry pi and a USB stick, or an android phone and a microSD card
+* Get an [ARM build of the assistant](https://github.com/tradloff/git-annex-RPi)
+* Sync a largish (12GB) repository
+
+### What version of git-annex are you using? On what operating system?
+
+4.20131002 on the pi, 20131024 for the 32GB SD, and 20131015 for the 64GB SD.
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+Unfortunately, daemon.log was unrecoverable along with the other files on the SD card.
+
+I can try and autosync the daemon.log somewhere if I happen to come along a bunch of scrap flash storage (not impossible).
+
+# End of transcript or log.
+"""]]
diff --git a/doc/bugs/microsd__47__thumbdrives_seem_to_die_when_using_the_ARM_build/comment_1_0527581ea60d28bb28504fa2a355ed87._comment b/doc/bugs/microsd__47__thumbdrives_seem_to_die_when_using_the_ARM_build/comment_1_0527581ea60d28bb28504fa2a355ed87._comment
new file mode 100644
index 000000000..52324a5a8
--- /dev/null
+++ b/doc/bugs/microsd__47__thumbdrives_seem_to_die_when_using_the_ARM_build/comment_1_0527581ea60d28bb28504fa2a355ed87._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnZEanlyzay_QlEAL0CWpyZcRTyN7vay8U"
+ nickname="Carlo"
+ subject="salvaged logs"
+ date="2013-10-31T10:00:40Z"
+ content="""
+The previously corrupt memory drive magically reappeared, so this might indicate a phone bug. In any case, I was able to salvage the logs from the phone.
+
+[Salvaged Logs](http://capocasa.name/android-4.2-lenovo-daemonlog.tar.gz)
+"""]]
diff --git a/doc/bugs/microsd__47__thumbdrives_seem_to_die_when_using_the_ARM_build/comment_2_926a87b60e20d286d49639c8dad13a1a._comment b/doc/bugs/microsd__47__thumbdrives_seem_to_die_when_using_the_ARM_build/comment_2_926a87b60e20d286d49639c8dad13a1a._comment
new file mode 100644
index 000000000..878e8fd7d
--- /dev/null
+++ b/doc/bugs/microsd__47__thumbdrives_seem_to_die_when_using_the_ARM_build/comment_2_926a87b60e20d286d49639c8dad13a1a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="correlation does not imply causation"
+ date="2013-11-01T16:37:31Z"
+ content="""
+I've been using git-annex on thumbdrives for years without problems. It seems more likely to me that you have a general problem with your hardware than that one program that does nothing special is somehow at fault.
+"""]]
diff --git a/doc/bugs/microsd__47__thumbdrives_seem_to_die_when_using_the_ARM_build/comment_3_c509fba1a9adacfd26a2bd12b4aea988._comment b/doc/bugs/microsd__47__thumbdrives_seem_to_die_when_using_the_ARM_build/comment_3_c509fba1a9adacfd26a2bd12b4aea988._comment
new file mode 100644
index 000000000..01ab119d2
--- /dev/null
+++ b/doc/bugs/microsd__47__thumbdrives_seem_to_die_when_using_the_ARM_build/comment_3_c509fba1a9adacfd26a2bd12b4aea988._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnZEanlyzay_QlEAL0CWpyZcRTyN7vay8U"
+ nickname="Carlo"
+ subject="comment 3"
+ date="2013-11-02T17:29:55Z"
+ content="""
+True, and good to know. Didn't necessarily want to trigger a big bug hunt here anyway, just some data/logs in case any more correlation comes up.
+"""]]
diff --git a/doc/bugs/migrated_files_not_showing_up_in_unused_list.mdwn b/doc/bugs/migrated_files_not_showing_up_in_unused_list.mdwn
new file mode 100644
index 000000000..33776d13a
--- /dev/null
+++ b/doc/bugs/migrated_files_not_showing_up_in_unused_list.mdwn
@@ -0,0 +1,62 @@
+Word summary: After migrating from SHA256 to SHA256E I still have a ton of SHA256 files around that aren't being found by unused.
+
+Command outputs (see, specifically, the output of status showing number of SHA256 and SHA256E files):
+
+
+ greg@eeepc:/mnt/blackbox/Media/Pictures/Photos$ less .gitattributes
+ * annex.backend=SHA256E
+
+ greg@eeepc:/mnt/blackbox/Media/Pictures/Photos$ git-annex migrate .
+ (Recording state in git...)
+
+ greg@eeepc:/mnt/blackbox/Media/Pictures/Photos$ git-annex unused
+ unused . (checking for unused data...) (checking master...) (checking rose/master...) (checking x200s/master...)
+ Some partially transferred data exists in temporary files:
+ NUMBER KEY
+ 1 SHA256E-s15766010--8132a02a8b245eb9842e89c5e696df4e9c82d676f8dec3c6bb96892c19f99d51.jpg
+
+ To remove unwanted data: git-annex dropunused NUMBER
+
+ ok
+ (Recording state in git...)
+
+ greg@eeepc:/mnt/blackbox/Media/Pictures/Photos$ git-annex status
+ supported backends: SHA256E SHA1E SHA512E SHA224E SHA384E SHA256 SHA1 SHA512 SHA224 SHA384 WORM URL
+ supported remote types: git S3 bup directory rsync web hook
+ trusted repositories: 1
+ c0e4106e-2631-11e2-9749-1bfa37a61069 -- rose
+ semitrusted repositories: 3
+ 00000000-0000-0000-0000-000000000001 -- web
+ 9bd4077e-196c-11e2-9cc9-9faafb3e34ee -- x200s
+ c69d6fcc-18d1-11e2-9487-2fe6dbf0516b -- here (photos on eeepc)
+ untrusted repositories: 0
+ dead repositories: 1
+ 3ebd5ac2-2092-11e2-856a-bb0203cce179 -- Photos on Rose
+ transfers in progress:
+ downloading 2011/06/30/IMG_8180.jpg
+ from rose
+ available local disk space: 2 terabytes (+1 megabyte reserved)
+ temporary directory size: 9 megabytes (clean up with git-annex unused)
+ local annex keys: 36210
+ local annex size: 136 gigabytes
+ known annex keys: 23388
+ known annex size: 102 gigabytes
+ bloom filter size: 16 mebibytes (7.2% full)
+ backend usage:
+ SHA256E: 37453
+ SHA256: 22145
+ (Recording state in git...)
+
+ greg@eeepc:/mnt/blackbox/Media/Pictures/Photos$ apt-cache policy git-annex
+ git-annex:
+ Installed: 3.20121017
+ Candidate: 3.20121017
+ Version table:
+ *** 3.20121017 0
+ 600 http://ftp.us.debian.org/debian/ unstable/main i386 Packages
+ 100 /var/lib/dpkg/status
+ 3.20120629 0
+ 650 http://ftp.us.debian.org/debian/ wheezy/main i386 Packages
+
+
+As Joey predicted, this took care of itself over time. Marking as [[bugs/done]].
diff --git a/doc/bugs/migrated_files_not_showing_up_in_unused_list/comment_1_2cfbf6693b051c758fe5efa5ee885829._comment b/doc/bugs/migrated_files_not_showing_up_in_unused_list/comment_1_2cfbf6693b051c758fe5efa5ee885829._comment
new file mode 100644
index 000000000..ee5f05617
--- /dev/null
+++ b/doc/bugs/migrated_files_not_showing_up_in_unused_list/comment_1_2cfbf6693b051c758fe5efa5ee885829._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.27"
+ subject="comment 1"
+ date="2012-11-07T19:02:45Z"
+ content="""
+Notice where it says:
+
+> (checking master...) (checking rose/master...) (checking x200s/master...)
+
+AFAICS, every one of those branches still refers to the migrated keys. For one thing, `git annex migrate` makes changes, but it doesn't commit them to master. And then you need to wait until the other remote are updated to.
+
+Also, there's not really any point in worrying about getting rid of migrated keys, since `git-annex migrate` hard links the new key to the old key, so the old ones don't take up any additional disk space.
+
+In other words: This should take care of itself as you continue to use the repository.
+"""]]
diff --git a/doc/bugs/migrated_files_not_showing_up_in_unused_list/comment_2_acb1abeb32c3aba8ba65151afbea753c._comment b/doc/bugs/migrated_files_not_showing_up_in_unused_list/comment_2_acb1abeb32c3aba8ba65151afbea753c._comment
new file mode 100644
index 000000000..ccb711588
--- /dev/null
+++ b/doc/bugs/migrated_files_not_showing_up_in_unused_list/comment_2_acb1abeb32c3aba8ba65151afbea753c._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://grossmeier.net/"
+ nickname="greg"
+ subject="comment 2"
+ date="2012-11-15T04:11:55Z"
+ content="""
+You were right, this has taken care of itself.
+
+Thanks much for the solid piece of software.
+"""]]
diff --git a/doc/bugs/minor_bug:_errors_are_not_verbose_enough.mdwn b/doc/bugs/minor_bug:_errors_are_not_verbose_enough.mdwn
new file mode 100644
index 000000000..a6620f425
--- /dev/null
+++ b/doc/bugs/minor_bug:_errors_are_not_verbose_enough.mdwn
@@ -0,0 +1,26 @@
+Current:
+
+ % git annex status
+ git-annex: unknown command
+
+Better:
+
+ % git annex status
+ git-annex: status: unknown command
+
+Current:
+
+ % git annex fsck
+ [...]
+ git-annex: 18 failed
+
+Better:
+
+ % git annex fsck
+ [...]
+ git-annex: fsck: 18 failed
+
+
+etc pp.
+
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/missing_dependency_in_git-annex-3.20130216.mdwn b/doc/bugs/missing_dependency_in_git-annex-3.20130216.mdwn
new file mode 100644
index 000000000..7c7664c67
--- /dev/null
+++ b/doc/bugs/missing_dependency_in_git-annex-3.20130216.mdwn
@@ -0,0 +1,29 @@
+What steps will reproduce the problem?
+
+build git-annex-3.20130216 on OS X lion
+
+
+What is the expected output? What do you see instead?
+
+successful compile; error was:
+
+```
+Annex/UUID.hs:30:8:
+ Could not find module `System.Random'
+ It is a member of the hidden package `random-1.0.1.1'.
+ Perhaps you need to add `random' to the build-depends in your .cabal file.
+ Use -v to see a list of the files searched for.
+```
+
+
+What version of git-annex are you using? On what operating system?
+
+building git-annex-3.20130216 on OS X Lion
+
+
+Please provide any additional information below.
+
+
+adding 'random' to the BuildDepends in git-annex.cabal does indeed fix the error.
+
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/missing_kde__47__gnome_menu_item..mdwn b/doc/bugs/missing_kde__47__gnome_menu_item..mdwn
new file mode 100644
index 000000000..c09cdf374
--- /dev/null
+++ b/doc/bugs/missing_kde__47__gnome_menu_item..mdwn
@@ -0,0 +1,29 @@
+What steps will reproduce the problem?
+ apt-get install git-annex
+
+
+
+What is the expected output?
+ a menu item at kde or gnome at internet> Git Annex , as
+http://git-annex.branchable.com/assistant/ shows.
+
+ What do you see instead? no menu item.
+
+
+What version of git-annex are you using?
+Version: 1:1.7.10.4-1+wheezy1
+
+ On what operating system?
+Wheezy
+
+
+ Also
+I just installed git-annex on a squeeze system and had the same result.
+
+same with ubuntu precise 12.04
+
+> git-annex ships a /usr/share/applications/git-annex.desktop
+> file that provies the menu item. But there has never been a version
+> 1.7.10. I suspect this is user error; installing a version of git-annex
+> that predates the git-annex assistant and expecting it to have the
+> assistant and its menu item. [[done]] --[[Joey]]
diff --git a/doc/bugs/moreinfo.mdwn b/doc/bugs/moreinfo.mdwn
new file mode 100644
index 000000000..8581a2c91
--- /dev/null
+++ b/doc/bugs/moreinfo.mdwn
@@ -0,0 +1,6 @@
+If your bug report is listed here, it has been flagged as needing more
+information. Please respond to the bug and provide the requested
+information.
+
+[[!inline pages="./* and link(./moreinfo) and !link(./done) and !*/Discussion" sort=mtime show=10
+archive=yes]]
diff --git a/doc/bugs/network___62____61___2.4.0.1_is_not_in_Haskell_Platform_2012.4.0.0.mdwn b/doc/bugs/network___62____61___2.4.0.1_is_not_in_Haskell_Platform_2012.4.0.0.mdwn
new file mode 100644
index 000000000..1b90f593f
--- /dev/null
+++ b/doc/bugs/network___62____61___2.4.0.1_is_not_in_Haskell_Platform_2012.4.0.0.mdwn
@@ -0,0 +1,12 @@
+git-annex requires version 2.4.0.1 or later of the 'network' library. Unfortunately,
+the current version of the Haskell Platform mandates version 2.3.1.0 of that library.
+This means that git-annex cannot be compiled on the Haskell Platform 2012.4.0.0 (which
+is going to remain the HP version of choice until May next year or so).
+
+Do you think it's possible to support *both* versions of the network library, maybe?
+That would increase the portability of git-annex quite a bit.
+
+Thank you for your consideration.
+
+> Ok, I think I've figured out how to use the CPP macros defined by cabal
+> to deal with this. [[done]], will be in next release. --[[Joey]]
diff --git a/doc/bugs/network___62____61___2.4.0.1_is_not_in_Haskell_Platform_2012.4.0.0/comment_1_2c4b3757bb8de563edca65aeabcbbc5a._comment b/doc/bugs/network___62____61___2.4.0.1_is_not_in_Haskell_Platform_2012.4.0.0/comment_1_2c4b3757bb8de563edca65aeabcbbc5a._comment
new file mode 100644
index 000000000..a6df44da9
--- /dev/null
+++ b/doc/bugs/network___62____61___2.4.0.1_is_not_in_Haskell_Platform_2012.4.0.0/comment_1_2c4b3757bb8de563edca65aeabcbbc5a._comment
@@ -0,0 +1,29 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.27"
+ subject="comment 1"
+ date="2012-11-11T21:49:10Z"
+ content="""
+My code already supports using either, but I don't know how to tell cabal to set -DWITH_OLD_URI to build with the old one, when it's installed. I've in the past tried to deal with this by defining cabal flags, and it didn't work out too well, tending to land users solidly in cabal hell.
+
+You can patch the cabal file like so to make it build with the old network:
+
+<pre>
+--- a/git-annex.cabal
++++ b/git-annex.cabal
+@@ -52,7 +52,7 @@ Flag DNS
+ Executable git-annex
+ Main-Is: git-annex.hs
+ Build-Depends: MissingH, hslogger, directory, filepath,
+- unix, containers, utf8-string, network (>= 2.4.0.1), mtl,
++ unix, containers, utf8-string, network (< 2.4.0.1), mtl,
+ bytestring, old-locale, time,
+ pcre-light, extensible-exceptions, dataenc, SHA, process, json, HTTP,
+ base (>= 4.5 && < 4.7), monad-control, transformers-base, lifted-base,
+@@ -64,6 +64,7 @@ Executable git-annex
+ C-Sources: Utility/libdiskfree.c Utility/libmounts.c
+ Extensions: CPP
+ GHC-Options: -threaded
++ CPP-Options: -DWITH_OLD_URI
+</pre>
+"""]]
diff --git a/doc/bugs/nfs_mounted_repo_results_in_errors_on_drop_move.mdwn b/doc/bugs/nfs_mounted_repo_results_in_errors_on_drop_move.mdwn
new file mode 100644
index 000000000..761ee5b25
--- /dev/null
+++ b/doc/bugs/nfs_mounted_repo_results_in_errors_on_drop_move.mdwn
@@ -0,0 +1,59 @@
+I'm on an nfs mounted filesystem (some netapp somewhere). This is repeatable, every time.
+
+ git init repo; cd repo;
+ git annex init repo
+ truncate -s 20M big
+ git annex add big
+ git commit -m "annexed file"
+ cd ..
+ git clone repo repo_copy
+ cd repo_copy;
+ git annex get .
+ git annex whereis big
+
+ #whereis big (2 copies)
+ # 9310b242-6021-4621-8cef-4548a00907ff -- here
+ # b3526e4d-38d7-4781-a9c3-436007899f1b -- origin (repo)
+ #ok
+
+ git annex drop big
+
+ #git-annex: /nfspath/repo_copy/.git/annex/objects/fM/4k/SHA1-s20971520--9674344c90c2f0646f0b78026e127c9b86e3ad77: removeDirectory: unsatisified constraints (Directory not empty)
+ #failed
+ #git-annex: drop: 1 failed
+
+ git annex drop big # no error second time, I suspect nfs has caught up by now.
+ git annex fsck # Doesn't know that the second drop succeeded.
+
+ #fsck big (fixing location log)
+ # ** Based on the location log, big
+ # ** was expected to be present, but its content is missing.
+ #failed
+ #git-annex: fsck: 1 failed
+
+ git annex fsck
+
+ #fsck big ok
+
+ git annex whereis big
+
+ #whereis big (1 copy)
+ # b3526e4d-38d7-4781-a9c3-436007899f1b -- origin (repo)
+ #ok
+
+I suspect git-annex is just too fast and optimistic for big slow nfs directories.
+
+> git-annex locks files while it is operating on their content
+> to avoid race conditions with other git-annex processes.
+> Quite likely this problem (which I can reproduce) is due to
+> NFS having bad (non-POSIX) locking semantics.
+>
+> Probably the
+> lock is represented on the NFS server as some form of lock file
+> next to the file being locked, and so when that file is deleted, with
+> the lock still held, the directory, which should then be empty, still
+> contains this lock file.
+>
+> So, this can be worked around by it not failing when the directory
+> unexpectedly cannot be removed. I've made that change. [[done]]
+> --[[Joey]]
diff --git a/doc/bugs/non-annexed_file_changed_to_annexed_on_typechange.mdwn b/doc/bugs/non-annexed_file_changed_to_annexed_on_typechange.mdwn
new file mode 100644
index 000000000..1dca84346
--- /dev/null
+++ b/doc/bugs/non-annexed_file_changed_to_annexed_on_typechange.mdwn
@@ -0,0 +1,40 @@
+### Please describe the problem.
+
+Changing a file in a repository from a symlink to a normal file causes annex to create an annexed file from that typechange regardless of weather or not it was an annexed file.
+
+
+### What steps will reproduce the problem?
+
+ git init newrepo
+ cd newrepo && git annex init
+ touch realfile
+ git add .
+ git commit -m "added realfile"
+ mkdir newdir && cd newdir
+ ln -s ../realfile newfile
+ git add .
+ git commit -m "Added placeholder until we get assets from designers"
+ rm newfile
+ dd bs=1024 count=10000 if=/dev/zero of=newfile
+ git add .
+ git commit -m "Finally got assets from designers"
+ ls -la newfile
+ # lrwxrwxrwx 1 user user <date> newfile -> ../.git/annex/objects/XX/XX/UUID/UUID
+
+### What version of git-annex are you using? On what operating system?
+
+git-annex version: 4.20130802
+
+Ubuntu 12.04 LTS
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/non-annexed_file_changed_to_annexed_on_typechange/comment_1_6ac691645edb483797bee05043fd83b3._comment b/doc/bugs/non-annexed_file_changed_to_annexed_on_typechange/comment_1_6ac691645edb483797bee05043fd83b3._comment
new file mode 100644
index 000000000..a3c162d61
--- /dev/null
+++ b/doc/bugs/non-annexed_file_changed_to_annexed_on_typechange/comment_1_6ac691645edb483797bee05043fd83b3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="arand"
+ ip="130.243.226.21"
+ subject="comment 1"
+ date="2013-08-12T20:19:37Z"
+ content="""
+It looks like all the \"add\" operations are missing from the log, which makes it a bit hard to follow...
+"""]]
diff --git a/doc/bugs/non-annexed_file_changed_to_annexed_on_typechange/comment_2_5d67e3a60b7cc30c2b1857f50895d363._comment b/doc/bugs/non-annexed_file_changed_to_annexed_on_typechange/comment_2_5d67e3a60b7cc30c2b1857f50895d363._comment
new file mode 100644
index 000000000..c122bd92f
--- /dev/null
+++ b/doc/bugs/non-annexed_file_changed_to_annexed_on_typechange/comment_2_5d67e3a60b7cc30c2b1857f50895d363._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://caust1c.myopenid.com/"
+ nickname="asbraithwaite"
+ subject="comment 2"
+ date="2013-08-12T20:41:34Z"
+ content="""
+Sorry about that. I forgot that -a doesn't add files.
+"""]]
diff --git a/doc/bugs/non-annexed_file_changed_to_annexed_on_typechange/comment_3_78f1e081b92f418c20893d86a8715501._comment b/doc/bugs/non-annexed_file_changed_to_annexed_on_typechange/comment_3_78f1e081b92f418c20893d86a8715501._comment
new file mode 100644
index 000000000..d00556c75
--- /dev/null
+++ b/doc/bugs/non-annexed_file_changed_to_annexed_on_typechange/comment_3_78f1e081b92f418c20893d86a8715501._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="arand"
+ ip="130.243.226.21"
+ subject="comment 3"
+ date="2013-08-12T20:48:42Z"
+ content="""
+There are still no git-annex actions in the log, except for the init. So the end result for ls -la is not possible with those commands. You may want to try to reproduce it again and write down the exact command sequence used ;)
+"""]]
diff --git a/doc/bugs/non-annexed_file_changed_to_annexed_on_typechange/comment_4_1e2a59e0eec89ef1a57d1488ff40dcf0._comment b/doc/bugs/non-annexed_file_changed_to_annexed_on_typechange/comment_4_1e2a59e0eec89ef1a57d1488ff40dcf0._comment
new file mode 100644
index 000000000..d68b3ea35
--- /dev/null
+++ b/doc/bugs/non-annexed_file_changed_to_annexed_on_typechange/comment_4_1e2a59e0eec89ef1a57d1488ff40dcf0._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://caust1c.myopenid.com/"
+ nickname="asbraithwaite"
+ subject="comment 4"
+ date="2013-08-12T21:07:45Z"
+ content="""
+@arand: That's precisely the problem! I think you'll find if you run those commands exactly, that's what you'll get.
+
+It's got something to do with the git annex pre-commit hook that runs and checks for typechanges.
+
+I shortened the output on the last command to be less verbose, but if the full output is needed, I'll add it.
+"""]]
diff --git a/doc/bugs/non-annexed_file_changed_to_annexed_on_typechange/comment_5_5e74431048b07631e0dbeca90fdb365b._comment b/doc/bugs/non-annexed_file_changed_to_annexed_on_typechange/comment_5_5e74431048b07631e0dbeca90fdb365b._comment
new file mode 100644
index 000000000..b2f525648
--- /dev/null
+++ b/doc/bugs/non-annexed_file_changed_to_annexed_on_typechange/comment_5_5e74431048b07631e0dbeca90fdb365b._comment
@@ -0,0 +1,47 @@
+[[!comment format=mdwn
+ username="arand"
+ ip="130.243.226.21"
+ subject="comment 5"
+ date="2013-08-12T21:50:47Z"
+ content="""
+Hmm, I think I see it now, you were missing a `rm` command in the log, and I had no idea the pre-commit hook existed :)
+
+This reproduces the issue, and it seems to indeed be a bug in the git-annex pre-commit handling, nice catch.
+
+<pre>
+$ git init temp
+Initialized empty Git repository in /home/arand/tmp/temp/.git/
+$ cd temp && git annex init
+init ok
+(Recording state in git...)
+$ ln -s broken link
+$ git add .
+$ git commit -m\"add broken link\"
+[master (root-commit) 8125488] add broken link
+ 1 file changed, 1 insertion(+)
+ create mode 120000 link
+$ rm link
+$ echo \"actual file\" >link
+$ git add .
+$ git commit -m\"replace link with real file\"
+add link (checksum...) ok
+ok
+(Recording state in git...)
+[master b58b068] replace link with real file
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+$ git diff HEAD~ | cat
+diff --git a/link b/link
+index 86a410d..4104f6e 120000
+--- a/link
++++ b/link
+@@ -1 +1 @@
+-broken
+\ No newline at end of file
++.git/annex/objects/v4/GQ/SHA256E-s12--ef29ded6f5ae80d89a838d37e01ed3efaade7a2994aff87d1100697554b7327b/SHA256E-s12--ef29ded6f5ae80d89a838d37e01ed3efaade7a2994aff87d1100697554b7327b
+\ No newline at end of file
+$
+</pre>
+
+
+
+"""]]
diff --git a/doc/bugs/non-annexed_file_changed_to_annexed_on_typechange/comment_6_3724e1c1a5fc6d3589452478249792ec._comment b/doc/bugs/non-annexed_file_changed_to_annexed_on_typechange/comment_6_3724e1c1a5fc6d3589452478249792ec._comment
new file mode 100644
index 000000000..9c558e05e
--- /dev/null
+++ b/doc/bugs/non-annexed_file_changed_to_annexed_on_typechange/comment_6_3724e1c1a5fc6d3589452478249792ec._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://caust1c.myopenid.com/"
+ nickname="asbraithwaite"
+ subject="comment 6"
+ date="2013-08-12T21:53:17Z"
+ content="""
+Ah, you're very right. Thank you.
+"""]]
diff --git a/doc/bugs/non-annexed_file_changed_to_annexed_on_typechange/comment_7_7f841ea7bf7d44f3d810ca097ac9eb47._comment b/doc/bugs/non-annexed_file_changed_to_annexed_on_typechange/comment_7_7f841ea7bf7d44f3d810ca097ac9eb47._comment
new file mode 100644
index 000000000..e781beae1
--- /dev/null
+++ b/doc/bugs/non-annexed_file_changed_to_annexed_on_typechange/comment_7_7f841ea7bf7d44f3d810ca097ac9eb47._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://caust1c.myopenid.com/"
+ nickname="asbraithwaite"
+ subject="comment 7"
+ date="2013-08-12T21:53:56Z"
+ content="""
+I updated the issue with the `rm` statement I forgot.
+"""]]
diff --git a/doc/bugs/non-annexed_file_changed_to_annexed_on_typechange/comment_8_c53ce2274388711ffbde1595b64f932b._comment b/doc/bugs/non-annexed_file_changed_to_annexed_on_typechange/comment_8_c53ce2274388711ffbde1595b64f932b._comment
new file mode 100644
index 000000000..b4ef6b5c7
--- /dev/null
+++ b/doc/bugs/non-annexed_file_changed_to_annexed_on_typechange/comment_8_c53ce2274388711ffbde1595b64f932b._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 8"
+ date="2013-08-22T17:25:48Z"
+ content="""
+Yay for the git-annex community for another fine bug testcase!
+
+The problem is simply that it assumes any typechanged link was an annexed file, and doesn't doublecheck. Fixing that now..
+"""]]
diff --git a/doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status.mdwn b/doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status.mdwn
new file mode 100644
index 000000000..a66d8635a
--- /dev/null
+++ b/doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status.mdwn
@@ -0,0 +1,89 @@
+### Please describe the problem.
+
+when running ```git annex status``` i get 'alien' content in the list of repositories (some timestamps, something looking like git status messages, and a long list of ```(recovery from race)``` messages. the actual content seems fine and the list of repositories in the assistant looks ok, but the CLI status messages show this unusual content (full dump below).
+
+### What steps will reproduce the problem?
+
+not sure how i would go about reproducing this: i only noticed this weird output just now and i'm pretty sure it was fine 24h ago - in the meanwhile the single non-ordinary operation was deleting via the assistant's webapp an SSH remote, rsync+encryption, then creating it again as bare repo without encryption.
+
+after the assistant finished removing all the content from the previous annex directory, it stalled reporting deletion in progress (the annex directory's parent on the remote server was not writeable for the user used for the ssh connection - perhaps that was the cause). even after chowning the parent dir and restarting the assistant on my local workstation, the assistant would still show the remote as pending deletion.
+
+after a while i could add the remote again, setting it to be a git bare repo, and content was copied over.
+
+from the assistant's webapp, i still see the correct list of remotes, but the output of ```git annex status``` is as below.
+
+```.git/config``` also looks ok, listing some core settings, some annex settings and my three real remotes for this annex.
+
+the part of logs relevant to the above change (deletion of remote, creation of new one + content sync) is unfortunately gone from the annex logs (including the rotated ones in ```.git/annex/daemon.log*```).
+
+### What version of git-annex are you using? On what operating system?
+
+4.20130709:amd64 on Debian testing (linux 3.9.8-1)
+
+
+### Please provide any additional information below.
+
+[[!format sh """
+$ git annex status
+supported backends: SHA256E SHA1E SHA512E SHA224E SHA384E SHA256 SHA1 SHA512 SHA224 SHA384 WORM URL
+supported remote types: git S3 bup directory rsync web webdav glacier hook
+repository mode: direct
+trusted repositories: 7
+ 1359161911.638435s -- 1
+ 1359161913.173474s -- 1
+ 1359161913.288686s -- 1
+ 1359332402.294867s -- 1
+ 1359332406.839623s -- 1
+ 1359332407.454511s -- 1
+ 1359332411.932021s -- 1
+semitrusted repositories: 36
+ 00000000-0000-0000-0000-000000000001 -- web
+ 00511808-8d7c-11e2-a252-43e07a9aaa3c -- client
+ 12527a3a-a21d-4cc7-a7ea-074e8fd0260f -- annex_on_rpi00 (standard)
+ 12a7b66c-e681-4dcc-bf75-b995512e5e76 -- client
+ 1359159154.357141s -- 1 2ce1be52-6745-11e2-83e5-e7d111798afd
+ 1359159155.817851s -- 1 2ce1be52-6745-11e2-83e5-e7d111798afd
+ 1359159155.931382s -- 1 e08336a0-6742-11e2-8a53-17c5ab00507f
+ 1359161255.198519s -- 1 2ce1be52-6745-11e2-83e5-e7d111798afd
+ 1359161256.72633s -- 1 2ce1be52-6745-11e2-83e5-e7d111798afd
+ 1359161256.952372s -- 1 e08336a0-6742-11e2-8a53-17c5ab00507f
+ 1359332437.573825s -- 1 2e71af50-674c-11e2-b542-6397738d1182
+ 1359332440.782882s -- 0 2e71af50-674c-11e2-b542-6397738d1182
+ 1359332441.153755s -- 1 42c358c4-6741-11e2-ba3f-8bdecec02757
+ 1359332448.091981s -- 0 2ce1be52-6745-11e2-83e5-e7d111798afd
+ 1359332507.354892s -- 1 2e71af50-674c-11e2-b542-6397738d1182
+ 1359332512.553832s -- 1 2e71af50-674c-11e2-b542-6397738d1182
+ 1359332512.666779s -- 1 42c358c4-6741-11e2-ba3f-8bdecec02757
+ 1359332517.773994s -- 1 42c358c4-6741-11e2-ba3f-8bdecec02757
+ 1359332523.112182s -- 0 2ce1be52-6745-11e2-83e5-e7d111798afd
+ 1374091795.70517s -- 1 2e71af50-674c-11e2-b542-6397738d1182
+ 1374507271.515001s -- 0 8d243fde-0c4c-4a19-8bce-ac1beb48eef0
+ 1374507272.066961s -- 0 8d243fde-0c4c-4a19-8bce-ac1beb48eef0
+ 1a76c11b-b359-4606-be1d-cc3b17dc684e -- client
+ 2ce1be52-6745-11e2-83e5-e7d111798afd -- git.services__data_annex_ (transfer)
+ 2e71af50-674c-11e2-b542-6397738d1182 -- here (client)
+ 42c358c4-6741-11e2-ba3f-8bdecec02757 -- x11miel.local_data_annex (em@10.10.10.100:~/data/annex)
+ 4eb75def-169c-45f8-b9b0-a0aa52017bd6 -- client
+ 92aa538c-8d7b-11e2-9ae1-3fd2531928c1 -- client
+ author -- nnnn nnnn <em@a.il> 1374509958 +0100
+ committer -- nnnn nnnn <em@a.il> 1374509958 +0100
+ d83e4134-8d7a-11e2-8822-7f2218f2cc42 -- client
+ e08336a0-6742-11e2-8a53-17c5ab00507f -- backup
+ f7969bd0-d5dc-11e2-b362-cbb323f72415 -- transfer
+ merging -- 10.10.10.10__mnt_annex_00_annex/git-annex into git-annex (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race)
+ parent -- fcde6fd44ff2ad2aaca895bca1b32fb398d76545
+ tree -- b6d4b49d9b67b296b0a0d9a800b96f88d480f923
+untrusted repositories: 2
+ 1359332417.999925s -- 0
+ 1374507270.94356s -- 0
+transfers in progress: none
+available local disk space: 6 gigabytes (+1 megabyte reserved)
+local annex keys: 1984
+local annex size: 6 gigabytes
+known annex keys: 1989
+known annex size: 6 gigabytes
+bloom filter size: 16 mebibytes (0.3% full)
+backend usage:
+ SHA256E: 3973
+$
+"""]]
diff --git a/doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status/comment_1_fcd230cbb2ac363c469b98021042c011._comment b/doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status/comment_1_fcd230cbb2ac363c469b98021042c011._comment
new file mode 100644
index 000000000..c9aa34806
--- /dev/null
+++ b/doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status/comment_1_fcd230cbb2ac363c469b98021042c011._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://mey.vn/"
+ ip="46.65.14.106"
+ subject="git annex status output on connected nodes"
+ date="2013-07-25T16:42:04Z"
+ content="""
+i have now updated the git-annex package to the latest 4.20130723:amd64 still on Debian testing (linux 3.9.8-1) - i see the same issue (while files keep synchronising fine across the various connected nodes).
+
+i have noticed that the same output appears when i issue ```git annex status``` on the other nodes (an Ubuntu 13.04 with kernel 3.9.7 amd64 and a Debian stable with 3.10.1-1 amd64, all with latest Debian 4.20130723:amd64 package).
+"""]]
diff --git a/doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status/comment_2_23207ecabd4b41d9551d0491fa71e96b._comment b/doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status/comment_2_23207ecabd4b41d9551d0491fa71e96b._comment
new file mode 100644
index 000000000..3c9d1f36f
--- /dev/null
+++ b/doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status/comment_2_23207ecabd4b41d9551d0491fa71e96b._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 2"
+ date="2013-07-25T20:12:06Z"
+ content="""
+Please paste the output of: `git show git-annex:uuid.log`
+
+The file seems to have a lot of garbage in it. The \"merging -- 10.10.10.10__mnt_annex_00_annex/git-annex into git-annex (recovery from race)\" in particular is only ever passed to git as the commit message. It should not be possible for it to appear in a file unless data has somehow become corrupted.
+
+So, I think you should also run `git fsck`. You may also find that it helps to shut down any running git-annex, and move `.git/annex/index` away to a backup location. A corrupted index file would be kind of be the best scenario since git-annex can automatically rebuild it from the git repository..
+"""]]
diff --git a/doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status/comment_3_6ea92adfe955b6a5cd2a39fea78b3bf6._comment b/doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status/comment_3_6ea92adfe955b6a5cd2a39fea78b3bf6._comment
new file mode 100644
index 000000000..56ae258a7
--- /dev/null
+++ b/doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status/comment_3_6ea92adfe955b6a5cd2a39fea78b3bf6._comment
@@ -0,0 +1,119 @@
+[[!comment format=mdwn
+ username="http://mey.vn/"
+ ip="46.65.14.106"
+ subject="comment 3"
+ date="2013-07-26T14:54:23Z"
+ content="""
+thanks Joey.
+
+output from ```git show git-annex:uuid.log``` is below.
+
+```git fsck``` shows me 4201 lines of ```dangling blob <sha>```.
+
+```git annex fsck``` instead checksums all the files and only reports a single error about no known copies of an individual file. i guess this can be relied upon to confirm that the actual data is fine?
+
+i have also tried shutting down any running git-annex and moving the index file away - it was rebuilt when i restarted the assistant, but i still get the same output from ```git annex status```.
+
+i should probably work around this by just copying the annex folder's contents to a new folder and create a new annex there (perhaps in indirect mode rather than direct as it is now, as this is mostly a document archive with no further changes to files except some occasional renaming) and create my remotes from scratch, but now i'm quite curious about trying to track down what happened and to understand if the annex is reliably storing and syncing content even though the status message contains alien data.
+
+
+(output from ```git show git-annex:uuid.log``` follows)
+
+ 00511808-8d7c-11e2-a252-43e07a9aaa3c client timestamp=1363357452.108251s
+ 12527a3a-a21d-4cc7-a7ea-074e8fd0260f pi@pi0:/mnt/annex/00/annex timestamp=1374508625.460693s
+ 12527a3a-a21d-4cc7-a7ea-074e8fd0260f standard timestamp=1374508627.738835s
+ 12527a3a-a21d-4cc7-a7ea-074e8fd0260f transfer timestamp=1374508627.731088s
+ 12a7b66c-e681-4dcc-bf75-b995512e5e76 client timestamp=1363469702.545491s
+ 1359159154.357141s 1 2ce1be52-6745-11e2-83e5-e7d111798afd
+ 1359159155.817851s 1 2ce1be52-6745-11e2-83e5-e7d111798afd
+ 1359159155.931382s 1 e08336a0-6742-11e2-8a53-17c5ab00507f
+ 1359161255.198519s 1 2ce1be52-6745-11e2-83e5-e7d111798afd
+ 1359161256.72633s 1 2ce1be52-6745-11e2-83e5-e7d111798afd
+ 1359161256.952372s 1 e08336a0-6742-11e2-8a53-17c5ab00507f
+ 1359161911.638435s 1
+ 1359161913.173474s 1
+ 1359161913.288686s 1
+ 1359332402.294867s 1
+ 1359332406.839623s 1
+ 1359332407.454511s 1
+ 1359332411.932021s 1
+ 1359332417.999925s 0
+ 1359332437.573825s 1 2e71af50-674c-11e2-b542-6397738d1182
+ 1359332440.782882s 0 2e71af50-674c-11e2-b542-6397738d1182
+ 1359332441.153755s 1 42c358c4-6741-11e2-ba3f-8bdecec02757
+ 1359332448.091981s 0 2ce1be52-6745-11e2-83e5-e7d111798afd
+ 1359332507.354892s 1 2e71af50-674c-11e2-b542-6397738d1182
+ 1359332512.553832s 1 2e71af50-674c-11e2-b542-6397738d1182
+ 1359332512.666779s 1 42c358c4-6741-11e2-ba3f-8bdecec02757
+ 1359332517.773994s 1 42c358c4-6741-11e2-ba3f-8bdecec02757
+ 1359332523.112182s 0 2ce1be52-6745-11e2-83e5-e7d111798afd
+ 1374091795.70517s 1 2e71af50-674c-11e2-b542-6397738d1182
+ 1374507270.94356s 0
+ 1374507271.515001s 0 8d243fde-0c4c-4a19-8bce-ac1beb48eef0
+ 1374507272.066961s 0 8d243fde-0c4c-4a19-8bce-ac1beb48eef0
+ 1a76c11b-b359-4606-be1d-cc3b17dc684e client timestamp=1370536281.421365s
+ 2ce1be52-6745-11e2-83e5-e7d111798afd timestamp=1359155758.081281s
+ 2ce1be52-6745-11e2-83e5-e7d111798afd transfer timestamp=1359155760.243544s
+ 2e71af50-674c-11e2-b542-6397738d1182 em@x12yad:~/data/annex timestamp=1359158766.916677s
+ 2e71af50-674c-11e2-b542-6397738d1182 client timestamp=1359158766.994574s
+ 42c358c4-6741-11e2-ba3f-8bdecec02757 em@10.10.10.100:~/data/annex timestamp=1359314998.998417s
+ 42c358c4-6741-11e2-ba3f-8bdecec02757 em@x11miel:~/data/annex timestamp=1359154076.554768s
+ 42c358c4-6741-11e2-ba3f-8bdecec02757 client timestamp=1359154076.649004s
+ 4eb75def-169c-45f8-b9b0-a0aa52017bd6 client timestamp=1363467301.827658s
+ 8d243fde-0c4c-4a19-8bce-ac1beb48eef0 X timestamp=1374508357.215776s
+ 8d243fde-0c4c-4a19-8bce-ac1beb48eef0 backup on rPi Zero timestamp=1374398146.433271s
+ 8d243fde-0c4c-4a19-8bce-ac1beb48eef0 standard timestamp=1374508303.429835s
+ 8d243fde-0c4c-4a19-8bce-ac1beb48eef0 unwanted timestamp=1374506712.447376s
+ 8d243fde-0c4c-4a19-8bce-ac1beb48eef0 unwanted timestamp=1374508303.426075s
+ 92aa538c-8d7b-11e2-9ae1-3fd2531928c1 client timestamp=1363357265.665495s
+ author nnnn nnnn <em@a.il> 1374508641 +0100
+ author nnnn nnnn <em@a.il> 1374508642 +0100
+ author nnnn nnnn <em@a.il> 1374508643 +0100
+ author nnnn nnnn <em@a.il> 1374508644 +0100
+ author nnnn nnnn <em@a.il> 1374508645 +0100
+ author nnnn nnnn <em@a.il> 1374509958 +0100
+ committer nnnn nnnn <em@a.il> 1374508641 +0100
+ committer nnnn nnnn <em@a.il> 1374508642 +0100
+ committer nnnn nnnn <em@a.il> 1374508643 +0100
+ committer nnnn nnnn <em@a.il> 1374508644 +0100
+ committer nnnn nnnn <em@a.il> 1374508645 +0100
+ committer nnnn nnnn <em@a.il> 1374509958 +0100
+ d83e4134-8d7a-11e2-8822-7f2218f2cc42 em@x11miel:~/data/photos timestamp=1363356952.82141s
+ d83e4134-8d7a-11e2-8822-7f2218f2cc42 client timestamp=1363356952.865265s
+ e08336a0-6742-11e2-8a53-17c5ab00507f backup timestamp=1359154795.94703s
+ f7969bd0-d5dc-11e2-b362-cbb323f72415 timestamp=1371315579.82712s
+ f7969bd0-d5dc-11e2-b362-cbb323f72415 transfer timestamp=1371315580.420388s
+ merging 10.10.10.10__mnt_annex_00_annex/git-annex into git-annex (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race)
+ merging 10.10.10.10__mnt_annex_00_annex/git-annex into git-annex (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race)
+ merging 10.10.10.10__mnt_annex_00_annex/git-annex into git-annex (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race)
+ merging 10.10.10.10__mnt_annex_00_annex/git-annex into git-annex (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race)
+ merging 10.10.10.10__mnt_annex_00_annex/git-annex into git-annex (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race)
+ merging 10.10.10.10__mnt_annex_00_annex/git-annex into git-annex (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race)
+ merging 10.10.10.10__mnt_annex_00_annex/git-annex into git-annex (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race)
+ merging 10.10.10.10__mnt_annex_00_annex/git-annex into git-annex (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race)
+ merging 10.10.10.10__mnt_annex_00_annex/git-annex into git-annex (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race)
+ merging 10.10.10.10__mnt_annex_00_annex/git-annex into git-annex (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race)
+ merging 10.10.10.10__mnt_annex_00_annex/git-annex into git-annex (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race)
+ merging 10.10.10.10__mnt_annex_00_annex/git-annex into git-annex (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race)
+ parent 02683b204119ba5668286ef6aa803bb52d3515d0
+ parent 07e2a9755790cefa6004496570bc8094aa757afa
+ parent 09199d3870ae53d6a602c26f4b9d59f62411236c
+ parent 0d436b9b3c3766dec276f32fdb80251c2159c154
+ parent 5aca77f1f93d2f34b521e7844b0608242a70f68f
+ parent 5e3331cc8f28603e4cb8ce890fbe221d3857717c
+ parent 92b9cacae1f40a23a2e8d5feea2b058e39806bd4
+ parent bc52e17b49503d598347bc7ddb1fa05a1ca6eba2
+ parent bfc242d6cfc27ec5fb7ec5fdb745ef8e08028fd9
+ parent d7867e1afaa32a829cb875589764e921a92bde5b
+ parent ecab3543a69ac98a1509933fa25600ac3f9c091b
+ parent fcde6fd44ff2ad2aaca895bca1b32fb398d76545
+ tree 14dc2bb1ff7682d7c2f4d14ae1e5c378b0b89d47
+ tree 59d730a282fa721332a4a2686061d6ee11024e72
+ tree 5a452c8e00eb1d1fb67ef63ed74381b8f80b2ae0
+ tree 80cc5887614c1d5dd200b2ea6a90ee6b881b966b
+ tree af2b572801e828df16c195d4dfd368a1f37db33f
+ tree b026659bb4b1bf02bf146c0b873244230c7cea06
+ tree b33eaa96e7f04c014c93b4e388d831d6ec7c3746
+ tree b6d4b49d9b67b296b0a0d9a800b96f88d480f923
+
+"""]]
diff --git a/doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status/comment_4_d0e55585f1612148163039d157253258._comment b/doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status/comment_4_d0e55585f1612148163039d157253258._comment
new file mode 100644
index 000000000..1e2a8fe24
--- /dev/null
+++ b/doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status/comment_4_d0e55585f1612148163039d157253258._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 4"
+ date="2013-07-26T16:52:26Z"
+ content="""
+The 4201 dangling blobs is a little bit strange, although it could certainly happen in some normal scenarios.
+Overall, your repository seems to be ok except for this weird data in the one file. I do not anticipate the extra garbage causing any problems at all.
+
+To track this down, we need to find the commit that added the garbage. One way, assuming you're using indirect mode, is to `git checkout git-annex; git blame uuid.log` and `git show` the commit that added the garbage. If you're using direct mode, you should first `git clone` the repository and do that in the clone.
+"""]]
diff --git a/doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status/comment_6_5506dc1b08516677886da4aa97263864._comment b/doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status/comment_6_5506dc1b08516677886da4aa97263864._comment
new file mode 100644
index 000000000..1aaeff404
--- /dev/null
+++ b/doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status/comment_6_5506dc1b08516677886da4aa97263864._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.110"
+ subject="comment 6"
+ date="2013-07-26T20:59:42Z"
+ content="""
+I think that the whole `git show $sha` for each commit will provide useful context.
+
+I want to understand what happened here, because there are multiple weird things going on, and it's important to root cause this sort of bug.
+
+What version of git-annex is on the rPi and how was it installed? Is there a simple operation you can do that segfaults every time?
+"""]]
diff --git a/doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status/comment_7_073449cc2cb73efd2b2d3d778a5573de._comment b/doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status/comment_7_073449cc2cb73efd2b2d3d778a5573de._comment
new file mode 100644
index 000000000..f7046a349
--- /dev/null
+++ b/doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status/comment_7_073449cc2cb73efd2b2d3d778a5573de._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://mey.vn/"
+ ip="46.65.14.106"
+ subject="comment 7"
+ date="2013-07-26T22:31:15Z"
+ content="""
+thanks Joey. i'm sending the output of ```git show $sha``` separately as it contains some non-public data; according to apt/dpkg logs, the rPi was actually using git-annex:armhf 4.20130521 from Debian testing at the time these commits were done. i did in fact install 4.20130709 and then 4.20130723 a couple of days after the issue showed up, but only yesterday i realised that both versions were segfaulting all the time (just invoking ```git-annex``` would segfault); 4.20130521 works reliably, instead (i have just downgraded to test), so my previous question about an interrupted operation possibly causing the metadata corruption is not valid as the git-annex executable in use at the time of the issue was not segfaulting (at least not under every circumstance as the more recent versions *in my setup* - but i'll dig into this separately - probably some library issue or so).
+
+the only change i can't really trace in terms of timing is when i deleted the remote i had originally set up on my rPi (using encrypted rsync) via the assistant's web interface on my laptop, and set it up again as plain unencrypted ssh remote (bare repo). i'm pretty sure this operation was done the day the commits in the ```git blame``` for ```uuid.log``` were done, but i'm not sure about the time and don't have logs going back to that moment.
+
+i could disconnect all the remotes from my laptop and redo the setup on the rPi to see if i can reproduce the issue, but i would need some pointers on how to revert my main annex on my laptop to the state it was in before i first started using the rPi as remote: can i just ```git reset --hard <some_sha>``` while on the ```git-annex``` branch? the annex is currently in direct mode (and as been so for a few months now).
+
+otherwise, i could easily copy all the data (or a subset, to start with) to a clean folder, set up a fresh annex there and pair the rPi again - if the corruption was due to some issue on the rPi it may not depend on the exact status the annex was at when the metadata corruption happened (although my full setup includes other remotes and i see some back-and-forth of merging going on throughout the history of the annex around the time the metadata issue started, so it may be hard to reproduce the exact same context).
+"""]]
diff --git a/doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status/comment_7_3516e71ba3b07427a10cbb4965712aa6._comment b/doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status/comment_7_3516e71ba3b07427a10cbb4965712aa6._comment
new file mode 100644
index 000000000..d8e91fdd4
--- /dev/null
+++ b/doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status/comment_7_3516e71ba3b07427a10cbb4965712aa6._comment
@@ -0,0 +1,24 @@
+[[!comment format=mdwn
+ username="http://mey.vn/"
+ ip="46.65.14.106"
+ subject="comment 7"
+ date="2013-07-26T18:11:25Z"
+ content="""
+thanks; the current ```uuid.log``` file carries content from 8 distinct commits :
+
+ 335cb49c 2013-07-22 16:57:32 +0100
+ 4ec397f7 2013-07-22 16:57:26 +0100
+ 50542096 2013-07-22 17:19:21 +0100
+ 621a1a03 2013-07-22 16:57:28 +0100
+ 63dd4509 2013-07-22 16:57:26 +0100
+ 8c2d3ff7 2013-07-22 16:57:19 +0100
+ 9ba4166d 2013-07-22 18:38:29 +0100
+ e182ee60 2013-07-22 16:57:26 +0100
+
+would the whole diff for each commit be useful, or just the part related to uuid.log?
+
+all these commits were done by git-annex on my laptop; the earliest of these commits come seconds after two commits done on another node - a raspberry pi running armhf Raspbian, although i now see that ```git-annex``` and ```git-annex-shell``` on this rPi are constantly segfaulting (though i can't understand the reason from the strace output): perhaps a segfault while dealing with a git operation on the rPi started the metadata corruption somehow?
+
+btw - if this could be useful to track down a possible bug in git-annex (although only involving some metadata, not the actual data), i am happy to dig further to provide all the information needed to understand what might have happened, but if it's not something worth investigating further in the bigger scheme of things, from my point of view i'm ok with restarting a fresh annex with content moved from this annex, and pristine metadata :)
+
+"""]]
diff --git a/doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status/comment_8_ea2e4704adb2f304f9c11c61eb62e919._comment b/doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status/comment_8_ea2e4704adb2f304f9c11c61eb62e919._comment
new file mode 100644
index 000000000..a87e4cab2
--- /dev/null
+++ b/doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status/comment_8_ea2e4704adb2f304f9c11c61eb62e919._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://mey.vn/"
+ ip="46.65.14.106"
+ subject="comment 8"
+ date="2013-07-26T22:38:51Z"
+ content="""
+forgot to mention - git-annex:armhf 4.20130521 was installed on the rPi via apt-get after having added testing as extra source besides the base stable of Raspbian; the other two versions (the segfaulting ones) were installed via ```dpkg -i``` on the packages downloaded directly from packages.d.o.
+"""]]
diff --git a/doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status/comment_9_4d17fedead7977541371a3f2c192e030._comment b/doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status/comment_9_4d17fedead7977541371a3f2c192e030._comment
new file mode 100644
index 000000000..f2d9f56d8
--- /dev/null
+++ b/doc/bugs/non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status/comment_9_4d17fedead7977541371a3f2c192e030._comment
@@ -0,0 +1,46 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.110"
+ subject="comment 9"
+ date="2013-07-27T17:37:11Z"
+ content="""
+Here's an excerpt of the first commit where uuid.log got garbage into it. It seems that some other log files got garbage put in them before this point, and it will be interesting to see if every time new garbage gets in it's doing a \"(recovery from race)\" commit. If so, that would point pretty strongly at that code as a culprit.
+
+(Of course, it's intriguing that the race recovery commit itself seemed to encounter a race and this repeated dozens of times. An exceptionally unlikely thing to happen if everything is behaving correctly.)
+
+<pre>
+commit 8c2d3ff75431873d99c512bcae007d68ff0b565e
+Author: REDACTED AUTHOR
+Date: Mon Jul 22 16:57:19 2013 +0100
+
+ merging 10.4.10.106__mnt_annex_00_annex/git-annex into git-annex (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race)
+
+diff --git a/uuid.log b/uuid.log
+index 7e7e0f9..0423e02 100644
+--- a/uuid.log
++++ b/uuid.log
+@@ -1,4 +1,6 @@
++
+ 00511808-8d7c-11e2-a252-43e07a9aaa3c client timestamp=1363357452.108251s
++12527a3a-a21d-4cc7-a7ea-074e8fd0260f pi@pi0:/mnt/annex/00/annex timestamp=1374508625.460693s
+ 12527a3a-a21d-4cc7-a7ea-074e8fd0260f transfer timestamp=1374508627.731088s
+ 12a7b66c-e681-4dcc-bf75-b995512e5e76 client timestamp=1363469702.545491s
+ 1359159154.357141s 1 2ce1be52-6745-11e2-83e5-e7d111798afd
+@@ -28,6 +30,13 @@
+ 8d243fde-0c4c-4a19-8bce-ac1beb48eef0 unwanted timestamp=1374506712.447376s
+ 8d243fde-0c4c-4a19-8bce-ac1beb48eef0 unwanted timestamp=1374508303.426075s
+ 92aa538c-8d7b-11e2-9ae1-3fd2531928c1 client timestamp=1363357265.665495s
++author REDACTED AUTHOR 1374508635 +0100
++committer REDACTED AUTHOR 1374508635 +0100
+ d83e4134-8d7a-11e2-8822-7f2218f2cc42 client timestamp=1363356952.865265s
+ e08336a0-6742-11e2-8a53-17c5ab00507f backup timestamp=1359154795.94703s
+ f7969bd0-d5dc-11e2-b362-cbb323f72415 transfer timestamp=1371315580.420388s
++merging 10.4.10.106__mnt_annex_00_annex/git-annex into git-annex (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race)
++merging 10.4.10.106__mnt_annex_00_annex/git-annex into git-annex (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race) (recovery from race)
++parent 059104588cc3c45a762586843e8ae375473993af
++parent 21a14d1ed6ea5afa11eb07c7f16fb2dd03f5d64c
++tree c4ebf18a3d1d7862484b1378124c8cb7d2c704da
+</pre>
+
+Looks a lot like a whole git commit object was union merged into the file, doesn't it?
+"""]]
diff --git a/doc/bugs/not_possible_to_have_annex_on_a_separate_filesystem.mdwn b/doc/bugs/not_possible_to_have_annex_on_a_separate_filesystem.mdwn
new file mode 100644
index 000000000..7daf03284
--- /dev/null
+++ b/doc/bugs/not_possible_to_have_annex_on_a_separate_filesystem.mdwn
@@ -0,0 +1,32 @@
+I belive I have found a regression.
+
+Inspired by
+<http://git-annex.branchable.com/forum/performance_improvement:_git_on_ssd__44___annex_on_spindle_disk/>
+I tried to only have .git/annex/objects (also tested moving .git/annex) on NFS while having the rest on local SSD disk.
+
+But when trying to add files i get:
+
+ > git annex add testfile
+ add testfile (checksum...)
+ git-annex: testfile: rename: unsupported operation (Invalid cross-device link)
+ failed
+ git-annex: add: 1 failed
+
+I have tried both using bind-mount and with a sym-link.
+
+> Grepping for `renameFile` and `createLink` will find all the places
+> in git-annex that assume one filesystem. These would have to be changed
+> to catch errors and fall back to expensive copying.
+>
+> Putting a separate repository on the file server could work better
+> depending on what you're trying to do. --[[Joey]]
+
+>> I've added support for putting `.git/annex` on a separate filesystem
+>> from the rest of the git repository.
+>>
+>> Putting individual subdirectories like `.git/annex/objects` on separate
+>> filesystems from other subdirectories is not fully supported; it may
+>> work but it may be slow and a few things (like `git annex migrate`) are
+>> known to fail due to using hard links. I don't think this is worth
+>> supporting. [[done]]
+>> --[[Joey]]
diff --git a/doc/bugs/old_data_isn__39__t_unused_after_migration.mdwn b/doc/bugs/old_data_isn__39__t_unused_after_migration.mdwn
new file mode 100644
index 000000000..9d468bdc7
--- /dev/null
+++ b/doc/bugs/old_data_isn__39__t_unused_after_migration.mdwn
@@ -0,0 +1,66 @@
+Old data isn't listed as unused after migrating backends:
+
+ #!/bin/bash
+
+ BASE=/tmp/migrate-bug-2
+ set -x
+ chmod -R +w $BASE
+ rm -rf $BASE
+ mkdir -p $BASE
+ cd $BASE
+
+ # create annex
+ git init .
+ git annex init
+
+ # make a big (sparse) file and add it
+ dd if=/dev/zero of=bigfile bs=1 count=0 seek=1G
+ git annex add --backend WORM bigfile
+ git commit -m 'added bigfile'
+
+ # migrate it
+ git annex migrate --backend SHA256 bigfile
+
+ # status shows 2 keys taking up 2G
+ git annex status
+
+ # but nothing is unused
+ git annex unused
+
+Output:
+
+ ++ git annex status
+ supported backends: SHA256 SHA1 SHA512 SHA224 SHA384 SHA256E SHA1E SHA512E SHA224E SHA384E WORM URL
+ supported remote types: git S3 bup directory rsync web hook
+ known repositories:
+ ede95a82-1166-11e1-a475-475d55eb0f8f -- here
+ local annex keys: 2
+ local annex size: 2 gigabytes
+ visible annex keys: 1
+ visible annex size: 1 gigabyte
+ backend usage:
+ WORM: 1
+ SHA256: 1
+ ++ git annex unused
+ unused . (checking for unused data...) (checking master...) ok
+
+The two files are hardlinked, so it's not taking up extra space, but it would be nice to be able to remove the old keys.
+
+> `git annex unused` checks the content of all branches, and assumes that,
+> when a branch contains a file that points to a key, that key is still
+> used. In this case, the migration has staged a change to the file,
+> but it is not yet committed, so when it checks the master branch, it
+> still finds a file referring to the old key.
+>
+> So, slightly surprising, but not a bug. --[[Joey]] [[done]]
+
+>> Thanks for the explanation. In my real repository, it was a bit trickier:
+>> the migration was commited to `master`, but other *remote* branches still
+>> referenced those keys. I was just doing a `git pull` from a central repo, but
+>> needed a `git remote update` to remove those references from `remotes/foo/master` too.
+>> --Jim
+
+>>> I have considered making unused ignore remote tracking branches.
+>>> On the one hand, it can be a little bit confusing, and those branches
+>>> can be out of date. On the other hand, it can be useful to know you're
+>>> not dropping anything that some remote might still refer to. --[[Joey]]
diff --git a/doc/bugs/on--git-dir_and_--work-tree_options.mdwn b/doc/bugs/on--git-dir_and_--work-tree_options.mdwn
new file mode 100644
index 000000000..0bcefbb5d
--- /dev/null
+++ b/doc/bugs/on--git-dir_and_--work-tree_options.mdwn
@@ -0,0 +1,31 @@
+git-annex does not take into account the --git-dir and --work-tree command line options (while they can be useful when scripting).
+
+ > mkdir /tmp/test
+ > cd /tmp/test
+ > git init
+ Initialized empty Git repository in /tmp/test/.git/
+ > git annex init test
+ init test ok
+ > touch foo
+ > cd
+ > git --git-dir=/tmp/test/.git --work-tree=/tmp/test annex add foo
+ git-annex: Not in a git repository.
+
+regular git add works:
+
+ > git --git-dir=/tmp/test/.git --work-tree=/tmp/test add foo
+ > git --git-dir=/tmp/test/.git --work-tree=/tmp/test status
+ # On branch master
+ #
+ # Initial commit
+ #
+ # Changes to be committed:
+ # (use "git rm --cached <file>..." to unstage)
+ #
+ # new file: foo
+ #
+
+git-annex version: 3.20110702
+
+> [[done]], git-annex now honors `GIT_DIR` and `GIT_WORK_TREE` like other
+> git commands do. --[[Joey]]
diff --git a/doc/bugs/optinally_transfer_file_unencryptedly/comment_1_13a7653d96ddf91f4492a9f3555a69aa._comment b/doc/bugs/optinally_transfer_file_unencryptedly/comment_1_13a7653d96ddf91f4492a9f3555a69aa._comment
new file mode 100644
index 000000000..5e72d5f0a
--- /dev/null
+++ b/doc/bugs/optinally_transfer_file_unencryptedly/comment_1_13a7653d96ddf91f4492a9f3555a69aa._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="comment 1"
+ date="2012-12-23T17:40:13Z"
+ content="""
+Using a plain tcp connection would be simpler than HTTP, the sending side would just need to tell the receiver to listen on a port and write any data received to a file(or the reverse). Basically what you can do with netcat.
+
+I had a similar problem, but I found that using arcfour was fast enough:
+
+.ssh/config:
+
+ Host slow
+ Ciphers arcfour
+
+"""]]
diff --git a/doc/bugs/optinally_transfer_file_unencryptedly/comment_2_31f154011ec26a463de7b1e307e49cb6._comment b/doc/bugs/optinally_transfer_file_unencryptedly/comment_2_31f154011ec26a463de7b1e307e49cb6._comment
new file mode 100644
index 000000000..2050da575
--- /dev/null
+++ b/doc/bugs/optinally_transfer_file_unencryptedly/comment_2_31f154011ec26a463de7b1e307e49cb6._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.126"
+ subject="comment 2"
+ date="2012-12-23T19:26:23Z"
+ content="""
+You can configure multiple git remotes that access the same repository using different transports, and use an un-encrypted transport when necessary for speed. I sometimes use an NFS mount for this.
+"""]]
diff --git a/doc/bugs/optinally_transfer_file_unencryptedly/comment_3_33433bcfb1946b52f1f41b9158ab452d._comment b/doc/bugs/optinally_transfer_file_unencryptedly/comment_3_33433bcfb1946b52f1f41b9158ab452d._comment
new file mode 100644
index 000000000..6b51701a0
--- /dev/null
+++ b/doc/bugs/optinally_transfer_file_unencryptedly/comment_3_33433bcfb1946b52f1f41b9158ab452d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.126"
+ subject="comment 3"
+ date="2012-12-23T19:29:27Z"
+ content="""
+BTW, I have yet to find any Haskell http library that can upload files without buffering their full contents in memory. (Not, not even http-conduit.) If someone fixes that, git-annex's S3 and WebDAV support will get a lot better and I could consider adding something like what's suggested.
+"""]]
diff --git a/doc/bugs/ordering.mdwn b/doc/bugs/ordering.mdwn
new file mode 100644
index 000000000..536bfce36
--- /dev/null
+++ b/doc/bugs/ordering.mdwn
@@ -0,0 +1,12 @@
+One would expect "git annex get foo bar" to first retrieve foo, and then
+bar. Actually though, it will operate on them in alphabetical order
+(probably). This is annoying when you wanted to 1st list the most important
+files to get. Maybe you'll run out of time before all can be gotten. The
+workaround of course is to run "git annex get" twice.
+
+This ordering comes from "git ls-files". git-annex passes it all the files
+the user specified. This is a useful optimisation -- earlier it would
+run "git ls-files" once per parameter, and so "git annex get *" could be
+rather slow. But, it produces this ordering problem.
+
+[[done]]
diff --git a/doc/bugs/pasting_into_annex_on_OSX.mdwn b/doc/bugs/pasting_into_annex_on_OSX.mdwn
new file mode 100644
index 000000000..4ea4851af
--- /dev/null
+++ b/doc/bugs/pasting_into_annex_on_OSX.mdwn
@@ -0,0 +1,28 @@
+What steps will reproduce the problem?
+
+Try pasting file into annex directory while assistant is running.
+
+
+What is the expected output? What do you see instead?
+
+Expect file to successfully paste into directory, then be annexed. Instead, see a permissions error, and file disappears.
+
+
+What version of git-annex are you using? On what operating system?
+
+OSX - 10.6. zsh. git-annex version: 3.20120826
+
+Please provide any additional information below.
+
+> Ok, I've put in the one second delay to adding by default on OSX.
+> I consider this bug done, at least for now..
+
+>> Reopening since I've heard from someone else that it can still happen.
+>> --[[Joey]]
+
+>>> Closing again, since the assistant now makes new repositories on OSX
+>>> using direct mode, which should avoid this problem. NB: any existing
+>>> repositories you have on OSX should be switched to use direct mode by
+>>> manually running `git annex direct` in them. [[done]] --[[Joey]]
+
+[[!tag /design/assistant/OSX]]
diff --git a/doc/bugs/pasting_into_annex_on_OSX/comment_1_4eab52bb6eda92e39bdaa8eee8f31a7f._comment b/doc/bugs/pasting_into_annex_on_OSX/comment_1_4eab52bb6eda92e39bdaa8eee8f31a7f._comment
new file mode 100644
index 000000000..5c2c64a23
--- /dev/null
+++ b/doc/bugs/pasting_into_annex_on_OSX/comment_1_4eab52bb6eda92e39bdaa8eee8f31a7f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.60"
+ subject="comment 1"
+ date="2012-09-18T16:35:36Z"
+ content="""
+What is the error message?
+"""]]
diff --git a/doc/bugs/pasting_into_annex_on_OSX/comment_2_f1b58adfec179b75c1fc2bf578a3b5c4._comment b/doc/bugs/pasting_into_annex_on_OSX/comment_2_f1b58adfec179b75c1fc2bf578a3b5c4._comment
new file mode 100644
index 000000000..ed38c2ca2
--- /dev/null
+++ b/doc/bugs/pasting_into_annex_on_OSX/comment_2_f1b58adfec179b75c1fc2bf578a3b5c4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://www.davidhaslem.com/"
+ nickname="David"
+ subject="comment 2"
+ date="2012-09-18T22:49:09Z"
+ content="""
+Exact error message is: \"The operation can’t be completed because you don’t have permission to access some of the items.\" Looks like it starts symlinking and committing before the file is fully copied over.
+"""]]
diff --git a/doc/bugs/pasting_into_annex_on_OSX/comment_3_270aa7680c3b899a92ce6543eaba666a._comment b/doc/bugs/pasting_into_annex_on_OSX/comment_3_270aa7680c3b899a92ce6543eaba666a._comment
new file mode 100644
index 000000000..51c06ba12
--- /dev/null
+++ b/doc/bugs/pasting_into_annex_on_OSX/comment_3_270aa7680c3b899a92ce6543eaba666a._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.2.84"
+ subject="comment 3"
+ date="2012-09-19T17:32:13Z"
+ content="""
+I can only guess what this paste operation entails, but as far as I can tell, the error message and the deletion of the file both come from the paste program, not git-annex.
+
+I know that git-annex assistant will not annex a file while it's still open to be written to. So my hypothesis is that the file is written to, closed, and then the paste program tries to do something else -- perhaps set the mode of the file -- and by that point git-annex has annexed it, and the program deletes the symlink. (So the content is probably buried in the git annex.)
+
+Could you build from git master and in your annex, run:
+
+ git config annex.delayadd 10
+
+That'll add a 10 second grace period for things to finish with files before they get added to the annex.
+Perhaps this will be enough to avoid the problem. Feel free to play with the number of seconds..
+"""]]
diff --git a/doc/bugs/pasting_into_annex_on_OSX/comment_4_ec11a80d5b0f78c7a927f8aa71a6c57a._comment b/doc/bugs/pasting_into_annex_on_OSX/comment_4_ec11a80d5b0f78c7a927f8aa71a6c57a._comment
new file mode 100644
index 000000000..3f4d9b87c
--- /dev/null
+++ b/doc/bugs/pasting_into_annex_on_OSX/comment_4_ec11a80d5b0f78c7a927f8aa71a6c57a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://www.davidhaslem.com/"
+ nickname="David"
+ subject="comment 4"
+ date="2012-09-21T04:05:20Z"
+ content="""
+Looks like that did it. I started with 5 seconds, which seems to be more than enough - turned it down to 1 and it still seems to work. The mode change sounds like a likely guess for what it's doing after it is doing writing the file - so even a second is probably more than enough.
+"""]]
diff --git a/doc/bugs/pasting_into_annex_on_OSX/comment_5_1928bd25e5e6874a3b83c2f2adc776f5._comment b/doc/bugs/pasting_into_annex_on_OSX/comment_5_1928bd25e5e6874a3b83c2f2adc776f5._comment
new file mode 100644
index 000000000..73eb3fa1e
--- /dev/null
+++ b/doc/bugs/pasting_into_annex_on_OSX/comment_5_1928bd25e5e6874a3b83c2f2adc776f5._comment
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ subject="comment 5"
+ date="2012-09-21T04:12:54Z"
+ content="""
+Ok.. My concern with this kind of \"fix\" is it could theoretically break under heavy load, and I get to pick a tradeoff between a timeout that's unlikely to break and one that'll make git-annex appear sluggish. OTOH, I can't think of anything better to do to address this. How common is \"pasting a file\" on OSX?
+"""]]
diff --git a/doc/bugs/pasting_into_annex_on_OSX/comment_6_0fe288f54b781a0c51395cb32f0e2f9d._comment b/doc/bugs/pasting_into_annex_on_OSX/comment_6_0fe288f54b781a0c51395cb32f0e2f9d._comment
new file mode 100644
index 000000000..a3199d6d8
--- /dev/null
+++ b/doc/bugs/pasting_into_annex_on_OSX/comment_6_0fe288f54b781a0c51395cb32f0e2f9d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://www.davidhaslem.com/"
+ nickname="David"
+ subject="comment 6"
+ date="2012-09-21T14:06:45Z"
+ content="""
+Well, it's not super common - but in the initial import where I'm first trying out git-annex, I'm copy-pasting my files in from my dropbox, keeping them both as separate folders to try out.
+"""]]
diff --git a/doc/bugs/problem_commit_normal_links.mdwn b/doc/bugs/problem_commit_normal_links.mdwn
new file mode 100644
index 000000000..6dbd41fb4
--- /dev/null
+++ b/doc/bugs/problem_commit_normal_links.mdwn
@@ -0,0 +1,59 @@
+Dear All,
+
+thank you for this wonderful tool!
+
+I am having an issue when I try to commit a normal link
+
+diokletian*194-> mkdir test
+
+diokletian*195-> cd test
+
+diokletian*196-> git init
+
+Initialized empty Git repository in /home/henrus/test/.git/
+
+diokletian*197-> git annex init new
+
+init new [master (root-commit) 49f5f91] git-annex setup
+
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+
+ create mode 100644 .gitattributes
+
+[master 76496ff] git annex init
+
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+
+ create mode 100644 .git-annex/uuid.log
+
+ok
+
+diokletian*198-> mkdir subdir
+
+diokletian*199-> ln -s subdir link
+
+diokletian*200-> git add link
+
+diokletian*201-> git commit -m "ok"
+
+[master f12f62d] ok
+
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+
+ create mode 120000 link
+
+diokletian*202-> ln -s subdir/ link2
+
+diokletian*203-> git add link2
+
+diokletian*204-> git commit -m "not ok"
+
+git-annex: Prelude.head: empty list
+
+The trailing slash seems to make a difference!
+
+Best Regards,
+
+Henrik
+
+> Thanks for the bug report. This is fixed in 0.17. --[[Joey]] [[!tag done]]
diff --git a/doc/bugs/problem_with_upgrade_v2_-__62___v3.mdwn b/doc/bugs/problem_with_upgrade_v2_-__62___v3.mdwn
new file mode 100644
index 000000000..7f37668ad
--- /dev/null
+++ b/doc/bugs/problem_with_upgrade_v2_-__62___v3.mdwn
@@ -0,0 +1,3 @@
+On several of my repos, the upgrade to v3 seemed to take forever. A Crl-C followed by another "git annex upgrade" "solved" the problem in some cases. Sometimes, I had to also delete the .git/annex/journal dir to have the upgrade. I didn't notice anything special about the non-working repos to help diagnose the problem.
+
+[[!tag done]]
diff --git a/doc/bugs/problem_with_upgrade_v2_-__62___v3/comment_1_5f60006c9bb095167d817f234a14d20b._comment b/doc/bugs/problem_with_upgrade_v2_-__62___v3/comment_1_5f60006c9bb095167d817f234a14d20b._comment
new file mode 100644
index 000000000..0cf0ad461
--- /dev/null
+++ b/doc/bugs/problem_with_upgrade_v2_-__62___v3/comment_1_5f60006c9bb095167d817f234a14d20b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-07-04T22:58:46Z"
+ content="""
+Well if it happens again why don't you use `ps` or `strace` to see what it's doing.
+"""]]
diff --git a/doc/bugs/problem_with_upgrade_v2_-__62___v3/comment_2_cd0123392b16d89db41b45464165c247._comment b/doc/bugs/problem_with_upgrade_v2_-__62___v3/comment_2_cd0123392b16d89db41b45464165c247._comment
new file mode 100644
index 000000000..4bef5f645
--- /dev/null
+++ b/doc/bugs/problem_with_upgrade_v2_-__62___v3/comment_2_cd0123392b16d89db41b45464165c247._comment
@@ -0,0 +1,23 @@
+[[!comment format=mdwn
+ username="https://lithitux.org/openidserver/users/pavel"
+ nickname="pavel"
+ subject="&quot;Me too&quot;"
+ date="2011-07-05T15:54:19Z"
+ content="""
+I've also seen this apparent hang during upgrade to v3. A few more details:
+
+The annex in question has just under 18k files (and hence that many log files), which can slow down directory operations when they're all in the same place (like, for example, .git/annex/journal).
+
+git-annex uses virtually no CPU time and disk IO when it's hanging like this; the first time it happened, 'ps' showed three defunct git processes, with two \"git-annex\" processes and three \"git\" procs:
+
+ * git --git-dir=/mnt/annex/.git --work-tree=/mnt/annex cat-file --batch
+ * git --git-dir=/mnt/annex/.git --work-tree=/mnt/annex hash-object -w --stdin-paths
+ * git --git-dir=/mnt/annex/.git --work-tree=/mnt/annex update-index -z --index-info
+
+I Ctrl+C'd that and tried again, but it hung again -- this time without the defunct gits.
+
+An strace of the process and its children at the time of hang can be found at http://pastebin.com/4kNh4zEJ . It showed somewhat weird behaviour: When I attached with strace, it would scroll through a whole bunch of syscalls making up the open-fstat-read-close-write loop on .git/annex/journal files, but then would block on a write (sorry, don't have that in my scrollback any more so can't give more details) until I Ctrl+C'd strace; when attaching again, it would again scroll through the syscalls for a second or so and then hang with no output.
+
+Ultimately I detached/reattached with strace about two dozen times and that caused it (?) to finish the upgrade; not really sure how to explain it, but it seems like too much of a timing coincidence.
+
+"""]]
diff --git a/doc/bugs/problem_with_upgrade_v2_-__62___v3/comment_3_86d9e7244ae492bcbe62720b8c4fc4a9._comment b/doc/bugs/problem_with_upgrade_v2_-__62___v3/comment_3_86d9e7244ae492bcbe62720b8c4fc4a9._comment
new file mode 100644
index 000000000..e314e73fa
--- /dev/null
+++ b/doc/bugs/problem_with_upgrade_v2_-__62___v3/comment_3_86d9e7244ae492bcbe62720b8c4fc4a9._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 3"
+ date="2011-07-05T17:31:22Z"
+ content="""
+I've seen this kind of piping stall that is unblocked by strace before. It can vary with versions of GHC, so it would be good to know what version built git-annex (and on what OS version). I filed a bug report upstream before at <http://bugs.debian.org/624389>.
+
+I really need a full strace -f from the top, or at least a complete `strace -o log` of git-annex from one hang through to another hang. The strace you pastebinned does not seem complete. If I can work out which specific git command is being written to when it hangs I can lift the writing out into a separate thread or process to fix it.
+
+@pavel, you mentioned three defunct git processes, and then showed ps output for 3 git processes. Were there 6 git processes in total? And then when you ran it again you said there were no defunct gits -- where the other 3 git processes running once again?
+
+As best I can make out from the (apparently) running git processes, it seems like the journal files for the upgrade had all been written, and the hang occurred when staging them all into the index in preparation for a commit. I have committed a change that lifts the code that does that write out into a new process, which, if I am guessing right on the limited info I have, will avoid the hang.
+
+However, since I can't reproduce it, even when I put 200 thousand files in the journal and have git-annex process them, I can't be sure.
+"""]]
diff --git a/doc/bugs/problem_with_upgrade_v2_-__62___v3/comment_4_91439d4dbbf1461e281b276eb0003691._comment b/doc/bugs/problem_with_upgrade_v2_-__62___v3/comment_4_91439d4dbbf1461e281b276eb0003691._comment
new file mode 100644
index 000000000..7bc32c259
--- /dev/null
+++ b/doc/bugs/problem_with_upgrade_v2_-__62___v3/comment_4_91439d4dbbf1461e281b276eb0003691._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 4"
+ date="2011-07-05T18:37:21Z"
+ content="""
+I've managed to reproduce this and confirmed my fix works.
+"""]]
diff --git a/doc/bugs/problem_with_upgrade_v2_-__62___v3/comment_5_ca33a9ca0df33f7c1b58353d7ffb943d._comment b/doc/bugs/problem_with_upgrade_v2_-__62___v3/comment_5_ca33a9ca0df33f7c1b58353d7ffb943d._comment
new file mode 100644
index 000000000..8649dc77a
--- /dev/null
+++ b/doc/bugs/problem_with_upgrade_v2_-__62___v3/comment_5_ca33a9ca0df33f7c1b58353d7ffb943d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 5"
+ date="2011-07-05T19:06:48Z"
+ content="""
+By the way, the original bug reporter mentioned deleting .git/annex/journal. This is not recommended, and doing it during an upgrade can result in git-annex losing location tracking information. You should probably run `git annex fsck` or reset to the old git tree (and `git config annex.version 2`) and upgrade again.
+"""]]
diff --git a/doc/bugs/problem_with_upgrade_v2_-__62___v3/comment_6_f360f0006bc9115bc5a3e2eb9fe58abd._comment b/doc/bugs/problem_with_upgrade_v2_-__62___v3/comment_6_f360f0006bc9115bc5a3e2eb9fe58abd._comment
new file mode 100644
index 000000000..0852db079
--- /dev/null
+++ b/doc/bugs/problem_with_upgrade_v2_-__62___v3/comment_6_f360f0006bc9115bc5a3e2eb9fe58abd._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://lithitux.org/openidserver/users/pavel"
+ nickname="pavel"
+ subject="comment 6"
+ date="2011-07-06T08:14:26Z"
+ content="""
+Ah, great, thanks very much for the quick fix!
+
+Yes, when I mentioned three defunct git processes, there were three processes shown as \"git [defunct]\", plus the three git processes I listed, plus two \"git-annex\" processes. Upon cancel/resume, there were no defunct git processes when I checked, but by the time I found the bug report on the forum and commented I'd already successfully upgraded by annex (by repeatedly attaching strace) and couldn't really easily get at either additional 'ps' info or a fuller strace than what I posted (that was just the log from one of the attach/detach cycles), so it's a relief you managed to pinpoint the problem.
+"""]]
diff --git a/doc/bugs/problems_with_utf8_names.mdwn b/doc/bugs/problems_with_utf8_names.mdwn
new file mode 100644
index 000000000..aeeb16be6
--- /dev/null
+++ b/doc/bugs/problems_with_utf8_names.mdwn
@@ -0,0 +1,81 @@
+This bug is reopened to track some new UTF-8 filename issues caused by GHC
+7.4. In this version of GHC, git-annex's hack to support filenames in any
+encoding no longer works. Even unicode filenames fail to work when
+git-annex is built with 7.4. --[[Joey]]
+
+This bug is now fixed in current master. Once again, git-annex will work
+for all filename encodings, and all system encodings. It will
+only build with the new GHC. [[done]] --[[Joey]]
+
+----
+
+Old, now fixed bug report follows:
+
+There are problems with displaying filenames in UTF8 encoding, as shown here:
+
+ $ echo $LANG
+ en_GB.UTF-8
+ $ git init
+ $ git annex init test
+ [...]
+ $ touch "Umlaut Ü.txt"
+ $ git annex add Uml*
+ add Umlaut Ã.txt ok
+ (Recording state in git...)
+ $ find -name U\* | hexdump -C
+ 00000000 2e 2f 55 6d 6c 61 75 74 20 c3 9c 2e 74 78 74 0a |./Umlaut ...txt.|
+ 00000010
+ $ git annex find | hexdump -C
+ 00000000 55 6d 6c 61 75 74 20 c3 83 c2 9c 2e 74 78 74 0a |Umlaut .....txt.|
+ 00000010
+ $
+
+It looks like the common latin1-to-UTF8 encoding. Functionality other than otuput seems not to be affected.
+
+> Yes, I believe that git-annex is reading filename data from git
+> as a stream of char8s, and not decoding unicode in it into logical
+> characters.
+> Haskell then I guess, tries to unicode encode it when it's output to
+> the console.
+> This only seems to matter WRT its output to the console; the data
+> does not get mangled internally and so it accesses the right files
+> under the hood.
+>
+> I am too new to haskell to really have a handle on how to handle
+> unicode and other encodings issues with it. In general, there are three
+> valid approaches: --[[Joey]]
+>
+> 1. Convert all input data to unicode and be unicode clean end-to-end
+> internally. Problimatic here since filenames may not necessarily be
+> encoded in utf-8 (an archive could have historical filenames using
+> varying encodings), and you don't want which files are accessed to
+> depend on locale settings.
+> > I tried to do this by making parts of GitRepo call
+> > Codec.Binary.UTF8.String.decodeString when reading filenames from
+> > git. This seemed to break attempts to operate on the files,
+> > weirdly encoded strings were seen in syscalls in strace.
+> 1. Keep input and internal data un-decoded, but decode it when
+> outputting a filename (assuming the filename is encoded using the
+> user's configured encoding), and allow haskell's output encoding to then
+> encode it according to the user's locale configuration.
+> > This is now implemented. I'm not very happy that I have to watch
+> > out for any place that a filename is output and call `filePathToString`
+> > on it, but there are really not too many such places in git-annex.
+> >
+> > Note that this only affects filenames apparently.
+> > (Names of files in the annex, and also some places where names
+> > of keys are displayed.) Utf-8 in the uuid.map file etc seems
+> > to be handled cleanly.
+> 1. Avoid encodings entirely. Mostly what I'm doing now; probably
+> could find a way to disable encoding of console output. Then the raw
+> filename would be displayed, which should work ok. git-annex does
+> not really need to pull apart filenames; they are almost entirely
+> opaque blobs. I guess that the `--exclude` option is the exception
+> to that, but it is currently not unicode safe anyway. (Update: tried
+> `--exclude` again, seems it is unicode clean..)
+> One other possible
+> issue would be that this could cause problems if git-annex were
+> translated.
+> > On second thought, I switched to this. Any decoding of a filename
+> > is going to make someone unhappy; the previous approach broke
+> > non-utf8 filenames.
diff --git a/doc/bugs/problems_with_utf8_names/comment_1_3c7e3f021c2c94277eecf9c8af6cec5f._comment b/doc/bugs/problems_with_utf8_names/comment_1_3c7e3f021c2c94277eecf9c8af6cec5f._comment
new file mode 100644
index 000000000..692b5d537
--- /dev/null
+++ b/doc/bugs/problems_with_utf8_names/comment_1_3c7e3f021c2c94277eecf9c8af6cec5f._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="http://adamspiers.myopenid.com/"
+ nickname="Adam"
+ subject="Any update on this?"
+ date="2011-12-24T01:05:07Z"
+ content="""
+I just noticed this issue, and was wondering what the current status is.
+
+ % ls -l 04\ -\ Orixás.mp3
+ -rw-r--r-- 1 adam users 8377816 Jul 12 2007 04 - Orixás.mp3
+ % echo 04\ -\ Orixás.mp3 | od -c
+ 0000000 0 4 - O r i x 303 241 s . m p 3
+ 0000020 \n
+ 0000021
+ % git annex add 04\ -\ Orixás.mp3
+ git-annex: /home/adam/music/RotC/transcribe/04 - Orixás.mp3: getSymbolicLinkStatus: does not exist (No such file or directory)
+"""]]
diff --git a/doc/bugs/problems_with_utf8_names/comment_2_bad4c4c5f54358d1bc0ab2adc713782a._comment b/doc/bugs/problems_with_utf8_names/comment_2_bad4c4c5f54358d1bc0ab2adc713782a._comment
new file mode 100644
index 000000000..a45706e4a
--- /dev/null
+++ b/doc/bugs/problems_with_utf8_names/comment_2_bad4c4c5f54358d1bc0ab2adc713782a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://www.joachim-breitner.de/"
+ nickname="nomeata"
+ subject="comment 2"
+ date="2011-12-24T12:49:40Z"
+ content="""
+This (rather longish) thread discusses the current situation, the planned changes for 7.2 and the various issues: http://haskell.org/pipermail/glasgow-haskell-users/2011-November/021115.html
+
+The summary seems to be: From 7.2 on, getDirectoryContents _will_ return proper Strings, i.e. where a Char represents a Unicode code point, and not a Word8, which will fix the problem of outputting them.
+"""]]
diff --git a/doc/bugs/problems_with_utf8_names/comment_3_4f936a5d3f9c7df64c8a87e62b7fbfdc._comment b/doc/bugs/problems_with_utf8_names/comment_3_4f936a5d3f9c7df64c8a87e62b7fbfdc._comment
new file mode 100644
index 000000000..9fef2eb1f
--- /dev/null
+++ b/doc/bugs/problems_with_utf8_names/comment_3_4f936a5d3f9c7df64c8a87e62b7fbfdc._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://www.joachim-breitner.de/"
+ nickname="nomeata"
+ subject="comment 3"
+ date="2011-12-24T12:51:43Z"
+ content="""
+An alternative that is available from ghc 7.4 on is a pure ByteString based unix API: http://thread.gmane.org/gmane.comp.lang.haskell.libraries/16556
+"""]]
diff --git a/doc/bugs/problems_with_utf8_names/comment_4_93bee35f5fa7744834994bc7a253a6f9._comment b/doc/bugs/problems_with_utf8_names/comment_4_93bee35f5fa7744834994bc7a253a6f9._comment
new file mode 100644
index 000000000..5e11af6ab
--- /dev/null
+++ b/doc/bugs/problems_with_utf8_names/comment_4_93bee35f5fa7744834994bc7a253a6f9._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 4"
+ date="2011-12-24T16:49:13Z"
+ content="""
+Adam, this bug was fixed a long time ago, first using option #2 above, but later switching to option #3 -- git-annex treats filenames as opaque binary blobs and never decodes them in any encoding; haskell's normal encoding support for stdio is disabled.
+
+And it never resulted in a failure like you show. I cannot reproduce your problem, but it is a different bug, please open a new bug report.
+"""]]
diff --git a/doc/bugs/problems_with_utf8_names/comment_5_519cda534c7aea7f5ad5acd3f76e21fa._comment b/doc/bugs/problems_with_utf8_names/comment_5_519cda534c7aea7f5ad5acd3f76e21fa._comment
new file mode 100644
index 000000000..96b0ffed0
--- /dev/null
+++ b/doc/bugs/problems_with_utf8_names/comment_5_519cda534c7aea7f5ad5acd3f76e21fa._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawk6QAwUsFHpr3Km1yQbg8hf3S7RDYf7hX4"
+ nickname="Lauri"
+ subject="comment 5"
+ date="2012-01-26T22:13:18Z"
+ content="""
+I also encountered Adam's bug. The problem seems to be that communication with the git process is done with `Char8`-bytestrings. So, when `L.unpack` is called, all filenames that git outputs (with `ls-files` or `ls-tree`) are interpreted to be in latin-1, which wreaks havoc if they are really in UTF-8.
+
+I suspect that it would be enough to just switch to standard `String`s (or `Data.Text.Text`) instead of bytestrings for textual data, and to `Word8`-bytestrings for pure binary data. GHC should nowadays handle locale-dependent encoding of `String`s transparently.
+
+"""]]
diff --git a/doc/bugs/problems_with_utf8_names/comment_6_52e0bfff2b177b6f92e226b25d2f3ff1._comment b/doc/bugs/problems_with_utf8_names/comment_6_52e0bfff2b177b6f92e226b25d2f3ff1._comment
new file mode 100644
index 000000000..093616d47
--- /dev/null
+++ b/doc/bugs/problems_with_utf8_names/comment_6_52e0bfff2b177b6f92e226b25d2f3ff1._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 6"
+ date="2012-01-27T21:00:06Z"
+ content="""
+Lauri, what version of GHC do you have that behaves this way? 7.0.4 does not.
+"""]]
diff --git a/doc/bugs/problems_with_utf8_names/comment_7_0cc588f787d6eecfa19a8f6cee4b07b5._comment b/doc/bugs/problems_with_utf8_names/comment_7_0cc588f787d6eecfa19a8f6cee4b07b5._comment
new file mode 100644
index 000000000..5a929940d
--- /dev/null
+++ b/doc/bugs/problems_with_utf8_names/comment_7_0cc588f787d6eecfa19a8f6cee4b07b5._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawk6QAwUsFHpr3Km1yQbg8hf3S7RDYf7hX4"
+ nickname="Lauri"
+ subject="comment 7"
+ date="2012-01-28T00:21:40Z"
+ content="""
+7.2. nomeata already explained the issue. I got utf-8 filenames to work on a utf-8 locale by switching from Char8-bytestrings to UTF8-bytestrings, and adding `hSetEncoding h localeEncoding` to suitable places. Making things work properly with an arbitrary locale encoding would be more complicated.
+"""]]
diff --git a/doc/bugs/problems_with_utf8_names/comment_8_ff5c6da9eadfee20c18c86b648a62c47._comment b/doc/bugs/problems_with_utf8_names/comment_8_ff5c6da9eadfee20c18c86b648a62c47._comment
new file mode 100644
index 000000000..dcfd59bce
--- /dev/null
+++ b/doc/bugs/problems_with_utf8_names/comment_8_ff5c6da9eadfee20c18c86b648a62c47._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 8"
+ date="2012-01-28T19:40:34Z"
+ content="""
+Lauri a scratch patch would be very helpful. Encoding stuff makes my head explode.
+
+However, I am very worried by haskell's changes WRT unicode and filenames. Based on user input, git-annex users like to use it on diverse sets of files, with diverse and ill-defined encodings. Faffing about with converting between encodings seems likely to speactacularly fail.
+"""]]
diff --git a/doc/bugs/random_files_vanishing_when_assistant_gets_restarted.mdwn b/doc/bugs/random_files_vanishing_when_assistant_gets_restarted.mdwn
new file mode 100644
index 000000000..aa34a8056
--- /dev/null
+++ b/doc/bugs/random_files_vanishing_when_assistant_gets_restarted.mdwn
@@ -0,0 +1,34 @@
+#What steps will reproduce the problem?
+
+Running assistant in foreground on one repository that is paired to another repository, than killing it using CTRL-C and restarting it
+
+
+#What is the expected output? What do you see instead?
+
+I get messages like:
+
+ (Recording state in git...)
+ # Auf Zweig master
+ # Änderungen, die nicht zum Eintragen bereitgestellt sind:
+ # (benutze "git add/rm <Datei>..." zum Bereitstellen)
+ # (benutze "git checkout -- <Datei>..." um die Änderungen im Arbeitsverzeichnis zu verwerfen)
+ #
+ # gelöscht: "path/to/file"
+ #
+ keine Änderungen zum Eintragen hinzugefügt (benutze "git add" und/oder "git commit -a")
+ Total 0 (delta 0), reused 0 (delta 0)
+ To ssh://stormking@git-annex-volyova-stormking/data/repository/
+ 4e2c631..911b80c git-annex -> synced/git-annex
+
+ Already up-to-date.
+
+Sorry for the german language, I'll try to reproduce it in english, later.
+After that, the symlinks for the file in the repository are gone. I can get
+them back by reverting the commit but things like that make me very nervous.
+
+
+#What version of git-annex are you using? On what operating system?
+
+3.20130102 on Arch Linux x64
+
+[[!tag /design/assistant moreinfo]]
diff --git a/doc/bugs/random_files_vanishing_when_assistant_gets_restarted/comment_1_53b4f388c47c1b3f6ffa4fc2155b30fc._comment b/doc/bugs/random_files_vanishing_when_assistant_gets_restarted/comment_1_53b4f388c47c1b3f6ffa4fc2155b30fc._comment
new file mode 100644
index 000000000..aafd42649
--- /dev/null
+++ b/doc/bugs/random_files_vanishing_when_assistant_gets_restarted/comment_1_53b4f388c47c1b3f6ffa4fc2155b30fc._comment
@@ -0,0 +1,21 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.238"
+ subject="comment 1"
+ date="2013-01-17T18:30:06Z"
+ content="""
+AFAICS, the German message is the equivilant of `git status` when a file has been deleted:
+
+<pre>
+# On branch master
+# Changes not staged for commit:
+# (use \"git add/rm <file>...\" to update what will be committed)
+# (use \"git checkout -- <file>...\" to discard changes in working directory)
+#
+# deleted: bigfile
+#
+no changes added to commit (use \"git add\" and/or \"git commit -a\")
+</pre>
+
+There's no indication here of when the file was deleted, or what deleted it. I need a way to reproduce this to be able to help. At this point it's not clear if the file is deleted by the old assistant that you ctrl-c'd, or if it was deleted while the assistant was not running, or if it somehow gets deleted when the new assistant is started up.
+"""]]
diff --git a/doc/bugs/random_files_vanishing_when_assistant_gets_restarted/comment_2_e66532b23b089c9ea61122d6664cddb9._comment b/doc/bugs/random_files_vanishing_when_assistant_gets_restarted/comment_2_e66532b23b089c9ea61122d6664cddb9._comment
new file mode 100644
index 000000000..66c038f61
--- /dev/null
+++ b/doc/bugs/random_files_vanishing_when_assistant_gets_restarted/comment_2_e66532b23b089c9ea61122d6664cddb9._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnjjCyhVEcTRM5m4iIBqL3ZCooPx7ZYB_E"
+ nickname="Marcus"
+ subject="comment 2"
+ date="2013-01-18T09:08:05Z"
+ content="""
+> At this point it's not clear if the file is deleted by the old assistant that you ctrl-c'd, or if it was deleted while the assistant was not running, or if it somehow gets deleted when the new assistant is started up.
+
+So how can I help to track this down? So far I can only rule out the file being deleted by some other process.
+"""]]
diff --git a/doc/bugs/random_files_vanishing_when_assistant_gets_restarted/comment_3_c9d692c867acc076f64f1213ea03ca11._comment b/doc/bugs/random_files_vanishing_when_assistant_gets_restarted/comment_3_c9d692c867acc076f64f1213ea03ca11._comment
new file mode 100644
index 000000000..65dcb6b00
--- /dev/null
+++ b/doc/bugs/random_files_vanishing_when_assistant_gets_restarted/comment_3_c9d692c867acc076f64f1213ea03ca11._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.3.194"
+ subject="comment 3"
+ date="2013-01-18T20:18:36Z"
+ content="""
+If you can reproduce the problem, you should be able to see if the file is there when you've ctrl-c the assistant.
+"""]]
diff --git a/doc/bugs/regression_in_direct_mode_on_windows_:_weird___96__git_annex_sync__96___behavior.mdwn b/doc/bugs/regression_in_direct_mode_on_windows_:_weird___96__git_annex_sync__96___behavior.mdwn
new file mode 100644
index 000000000..4c1f0971d
--- /dev/null
+++ b/doc/bugs/regression_in_direct_mode_on_windows_:_weird___96__git_annex_sync__96___behavior.mdwn
@@ -0,0 +1,113 @@
+### Please describe the problem.
+In latest git-annex version for windows (4.2130723), after a fresh clone, git annex sync considers dummy symlinks as recently modified files and commits the content.
+
+Alternatively, to try and avoid this problem, I tried manually merging branches (git-annex and master) but if I do that, I can't retrieve files anymore. That is, `git annex get .` downloads files but doesn't replace the dummy symlinks (I am guessing the same as `http://git-annex.branchable.com/bugs/windows_port_-_can__39__t_directly_access_files/`. Tell me if this is a different bug, I'll file a new bug report)
+
+
+### What steps will reproduce the problem?
+Create a new repository (on windows or on linux), create a file and commit it.
+
+Clone this repository (on windows), then `git annex init` it. The file is here, containing the path to the real file (like a symlink but the crippled filesystem's version).
+
+At this point, if you perform `git annex sync`, git-annex thinks the dummy symlink is the new content of the file and commits it.
+
+
+### What version of git-annex are you using? On what operating system?
+This problem occurs on git-annex for windows version 4.20130723 (the latest version as of now) although it worked well in version 4.20130709.
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+$ mkdir test1
+
+$ cd test1
+
+$ git init
+Initialized empty Git repository in c:/Users/raz/test1/.git/
+
+$ git annex init test1
+init test1
+ Detected a crippled filesystem.
+
+ Enabling direct mode.
+
+ Detected a filesystem without fifo support.
+
+ Disabling ssh connection caching.
+ok
+(Recording state in git...)
+
+$ echo "This is the content of the file" > file.txt
+
+$ git annex add
+add file.txt (checksum...) ok
+(Recording state in git...)
+
+$ git annex sync
+commit
+ok
+git-annex: no branch is checked out
+
+$ cat file.txt
+This is the content of the file
+
+$ cd ..
+
+$ git clone test1 test2
+Cloning into 'test2'...
+done.
+
+$ cd test2
+
+$ git annex init test2
+init test2
+ Detected a crippled filesystem.
+
+ Enabling direct mode.
+
+ Detected a filesystem without fifo support.
+
+ Disabling ssh connection caching.
+ok
+(Recording state in git...)
+
+$ cat file.txt # File is only a dummy file, it contains the path to the real file (which doesn't yet exist here, this is expected behavior)
+.git/annex/objects/33/43/SHA256E-s32--a50017c6136930a142cfca6ee34b700d96dcf0ba59cf7007c27c2924f80dfa7a.txt/SHA256E-s32--a50017c6136930a142cfca6ee34b700d96dcf0ba59cf7007c27c2924f80dfa7a.txt
+
+$ git annex sync
+(merging origin/git-annex into git-annex...)
+(Recording state in git...)
+add file.txt (checksum...) ok # ??? The dummy file is added to the index -> shouldn't happen
+(Recording state in git...)
+commit
+(Recording state in git...)
+ok
+pull origin
+ok
+push origin
+Counting objects: 26, done.
+Delta compression using up to 4 threads.
+Compressing objects: 100% (14/14), done.
+Writing objects: 100% (19/19), 1.78 KiB | 0 bytes/s, done.
+Total 19 (delta 2), reused 0 (delta 0)
+To c:/Users/Renaud Casenave-Pere/test1
+ * [new branch] git-annex -> synced/git-annex
+ * [new branch] master -> synced/master
+ok
+
+$ git annex whereis # File should be in origin repository, not here
+whereis file.txt (1 copy)
+ e6e1c558-7127-4ffa-a79b-2161b44ec44b -- here (test2)
+ok
+
+$ cat file.txt # The committed content, discarding the real content
+.git/annex/objects/33/43/SHA256E-s32--a50017c6136930a142cfca6ee34b700d96dcf0ba59cf7007c27c2924f80dfa7a.txt/SHA256E-s32--a50017c6136930a142cfca6ee34b700d96dcf0ba59cf7007c27c2924f80dfa7a.txt
+
+# End of transcript or log.
+"""]]
+
+Tell me if you need further information.
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/regression_in_direct_mode_on_windows_:_weird___96__git_annex_sync__96___behavior/comment_1_1a0b964f93c753838d6ccbdc8f79b39e._comment b/doc/bugs/regression_in_direct_mode_on_windows_:_weird___96__git_annex_sync__96___behavior/comment_1_1a0b964f93c753838d6ccbdc8f79b39e._comment
new file mode 100644
index 000000000..f3e8ec690
--- /dev/null
+++ b/doc/bugs/regression_in_direct_mode_on_windows_:_weird___96__git_annex_sync__96___behavior/comment_1_1a0b964f93c753838d6ccbdc8f79b39e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.21"
+ subject="re: workaround"
+ date="2013-07-30T19:17:11Z"
+ content="""
+The problem with manually merging the branches and not using sync is that the file mappings get out of date. You should be able to correct them by running `git annex fsck`
+"""]]
diff --git a/doc/bugs/regression_in_direct_mode_on_windows_:_weird___96__git_annex_sync__96___behavior/comment_2_d22dcd7f95c5dc1c381c3c746781efce._comment b/doc/bugs/regression_in_direct_mode_on_windows_:_weird___96__git_annex_sync__96___behavior/comment_2_d22dcd7f95c5dc1c381c3c746781efce._comment
new file mode 100644
index 000000000..6af5a06a6
--- /dev/null
+++ b/doc/bugs/regression_in_direct_mode_on_windows_:_weird___96__git_annex_sync__96___behavior/comment_2_d22dcd7f95c5dc1c381c3c746781efce._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.21"
+ subject="comment 2"
+ date="2013-07-30T19:55:04Z"
+ content="""
+This reversion affects direct mode on FAT, not just on Windows! It was probably caused by commit ecdfa40cbea1ae213ab84913d8f011027967a610 or commit ae341c1a37eecc1724517e3e025d144badb5abfe. Investigating.
+"""]]
diff --git a/doc/bugs/regression_in_direct_mode_on_windows_:_weird___96__git_annex_sync__96___behavior/comment_3_a25140eb90f6b24c1a3ca39c901694e2._comment b/doc/bugs/regression_in_direct_mode_on_windows_:_weird___96__git_annex_sync__96___behavior/comment_3_a25140eb90f6b24c1a3ca39c901694e2._comment
new file mode 100644
index 000000000..b608efdbe
--- /dev/null
+++ b/doc/bugs/regression_in_direct_mode_on_windows_:_weird___96__git_annex_sync__96___behavior/comment_3_a25140eb90f6b24c1a3ca39c901694e2._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.21"
+ subject="comment 3"
+ date="2013-07-30T20:07:09Z"
+ content="""
+Yeah, I inverted some logic. This also affects, for example, git-annex on Android. Sigh. Sorry about this.
+
+I suppose that, if you run into this bug, the best way to fix up after it is to `git-revert -n` the bad commit that sync made. Then run `git annex sync` with the fixed git-annex to commit the reversion.
+"""]]
diff --git a/doc/bugs/regression_in_direct_mode_on_windows_:_weird___96__git_annex_sync__96___behavior/comment_4_825e15183008ff7d97a81cacc3f55fb4._comment b/doc/bugs/regression_in_direct_mode_on_windows_:_weird___96__git_annex_sync__96___behavior/comment_4_825e15183008ff7d97a81cacc3f55fb4._comment
new file mode 100644
index 000000000..7b503ac9a
--- /dev/null
+++ b/doc/bugs/regression_in_direct_mode_on_windows_:_weird___96__git_annex_sync__96___behavior/comment_4_825e15183008ff7d97a81cacc3f55fb4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.21"
+ subject="fixed"
+ date="2013-07-30T20:11:19Z"
+ content="""
+Seems like the test suite should have caught this on Windows. Unfortunately, the part of the test suite that tests sync is commented out due to it not working at all from within the test suite for reasons I don't understand. Pity.
+"""]]
diff --git a/doc/bugs/regression_in_direct_mode_on_windows_:_weird___96__git_annex_sync__96___behavior/comment_5_e858fc7c729cd39740354fb12627d556._comment b/doc/bugs/regression_in_direct_mode_on_windows_:_weird___96__git_annex_sync__96___behavior/comment_5_e858fc7c729cd39740354fb12627d556._comment
new file mode 100644
index 000000000..9b3aa7c17
--- /dev/null
+++ b/doc/bugs/regression_in_direct_mode_on_windows_:_weird___96__git_annex_sync__96___behavior/comment_5_e858fc7c729cd39740354fb12627d556._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.21"
+ subject="comment 5"
+ date="2013-07-30T21:12:54Z"
+ content="""
+All Windows and Android builds have been updated with the bug fixed.
+
+Test suite fixed to test `git annex sync` on Windows.. although the test suite is still failing for unknown reasons in the autobuilder environment and so does not stop the build. I have added a recommendation to the Windows install page that users run `git annex test` themselves to make sure they have a good build that works on their Windows system.
+"""]]
diff --git a/doc/bugs/regression_in_direct_mode_on_windows_:_weird___96__git_annex_sync__96___behavior/comment_6_9881b0f2dfb0907a60c0da296bc3da3f._comment b/doc/bugs/regression_in_direct_mode_on_windows_:_weird___96__git_annex_sync__96___behavior/comment_6_9881b0f2dfb0907a60c0da296bc3da3f._comment
new file mode 100644
index 000000000..f1509b395
--- /dev/null
+++ b/doc/bugs/regression_in_direct_mode_on_windows_:_weird___96__git_annex_sync__96___behavior/comment_6_9881b0f2dfb0907a60c0da296bc3da3f._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawknruiCHUcOh2mmpkh7OFJ4iNfAOOamRVs"
+ nickname="Renaud"
+ subject="comment 6"
+ date="2013-07-31T05:34:33Z"
+ content="""
+Great, thank you very much!
+
+I successfully ran the test suite and it's now working fine.
+"""]]
diff --git a/doc/bugs/regression_in_direct_mode_on_windows_:_weird___96__git_annex_sync__96___behavior/comment_7_ca017b9d3bafea4cb31448c802f3834e._comment b/doc/bugs/regression_in_direct_mode_on_windows_:_weird___96__git_annex_sync__96___behavior/comment_7_ca017b9d3bafea4cb31448c802f3834e._comment
new file mode 100644
index 000000000..48173bff9
--- /dev/null
+++ b/doc/bugs/regression_in_direct_mode_on_windows_:_weird___96__git_annex_sync__96___behavior/comment_7_ca017b9d3bafea4cb31448c802f3834e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="Remy"
+ ip="82.94.186.146"
+ subject="comment 7"
+ date="2013-07-31T13:55:07Z"
+ content="""
+I got the same problem with the dummy symlinks while syncing to an annex on an EncFS mount on Ubuntu so I hope the fix doesn't just apply to Windows and Android.
+"""]]
diff --git a/doc/bugs/reinject_should_leave_file_in_place_on_checksum_mismatch.mdwn b/doc/bugs/reinject_should_leave_file_in_place_on_checksum_mismatch.mdwn
new file mode 100644
index 000000000..a487b2d3d
--- /dev/null
+++ b/doc/bugs/reinject_should_leave_file_in_place_on_checksum_mismatch.mdwn
@@ -0,0 +1,15 @@
+What steps will reproduce the problem?
+
+Run git annex reinject source dest with a file that has the wrong content and thus a wrong checksum.
+
+What is the expected output? What do you see instead?
+
+The file should stay in it's original location. Currently it's moved to .git/annex/bad with a mangled filename.
+
+What version of git-annex are you using? On what operating system?
+
+git-annex version: 3.20120807
+Ubuntu 12.04 updated on Aug 20th
+annex was installed via cabal on Aug 20th, all other packages are from ubuntu.
+
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist.mdwn b/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist.mdwn
new file mode 100644
index 000000000..e90fb6a5f
--- /dev/null
+++ b/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist.mdwn
@@ -0,0 +1,65 @@
+### Please describe the problem.
+
+I created somelargefile on host1. A file with that name appears in the right place on host2 but I can't use it:
+
+
+ host2:~/annex% cat somelargefile
+ cat: somelargefile: No such file or directory
+
+
+### What steps will reproduce the problem?
+
+I am running http://downloads.kitenet.net/git-annex/linux/current/git-annex-standalone-amd64.tar.gz and I connected two hosts with the 'Local computer' workflow. I run assistant on both sides.
+
+I make a file on either side, wait a minute for it to sync, and then observe this on the remote side:
+
+ lrwxrwxrwx 1 drewp drewp 178 Jul 9 23:58 somelargefile -> .git/annex/objects/Pw/vw/SHA256E-s8--bf87165d313027621936809a01da1994f9bd20ff9580c1380e7636e2443fe4ed/SHA256E-s8--bf87165d313027621936809a01da1994f9bd20ff9580c1380e7636e2443fe4ed
+
+ host2:~/annex% ls -l .git/annex/objects/Pw/vw/SHA256E-s8--bf87165d313027621936809a01da1994f9bd20ff9580c1380e7636e2443fe4ed/
+ total 4
+ -rw------- 1 drewp drewp 14 Jul 9 23:58 SHA256E-s8--bf87165d313027621936809a01da1994f9bd20ff9580c1380e7636e2443fe4ed.map
+
+My "large file" is in fact 8 bytes long. The .map file contains the string "somelargefile\n"
+
+
+### What version of git-annex are you using? On what operating system?
+
+git-annex version: 4.20130709-g339d1e0
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP
+local repository version: 3
+default repository version: 3
+supported repository versions: 3 4
+upgrade supported from repository versions: 0 1 2
+
+ubuntu 12.10 64-bit
+
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+New lines in .git/annex/daemon.log when I add another new file:
+
+
+ (merging synced/git-annex into git-annex...)
+
+ Updating bac8b65..0422d27
+ Fast-forward
+ newfile2 | 1 +
+ 1 file changed, 1 insertion(+)
+ create mode 120000 newfile2
+ [2013-07-10 00:08:38 PDT] Committer: Committing changes to git
+ (Recording state in git...)
+ [2013-07-10 00:08:38 PDT] Pusher: Syncing with host1.local_annex
+ To ssh://drewp@git-annex-host1.local-drewp_annex/~/annex/
+ a80b6f5..72c0865 git-annex -> synced/git-annex
+
+ Already up-to-date.
+
+
+# End of transcript or log.
+"""]]
+
+[[!meta title="local pairing git-annex-shell issue when using standalone tarball"]]
diff --git a/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_10_8a1d16b2aaba224e94be3d9dcc036d91._comment b/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_10_8a1d16b2aaba224e94be3d9dcc036d91._comment
new file mode 100644
index 000000000..9cfc0ebee
--- /dev/null
+++ b/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_10_8a1d16b2aaba224e94be3d9dcc036d91._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://bigasterisk.com/"
+ nickname="Drew Perttula"
+ subject="comment 10"
+ date="2013-07-27T07:42:26Z"
+ content="""
+Sorry, I meant to get those logs earlier but I got distracted.
+
+One confounding thing in the previous runs is that I may have had accidental instances of git-annex assistant running on at least one of the machines. I killed them all for this next attempt, and named the dir annex2 just in case.
+
+daemon.log files are now at http://bigasterisk.com/post/git-annex/logs1/
+"""]]
diff --git a/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_11_434ed328a22a6657dba3b2929a56e499._comment b/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_11_434ed328a22a6657dba3b2929a56e499._comment
new file mode 100644
index 000000000..13bfc4468
--- /dev/null
+++ b/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_11_434ed328a22a6657dba3b2929a56e499._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.110"
+ subject="comment 11"
+ date="2013-07-28T00:06:53Z"
+ content="""
+From the log on bang:
+
+<pre>
+[2013-07-27 00:33:15 PDT] read: ssh [\"-S\",\"/home/drewp/annex2/.git/annex/ssh/drewp@git-annex-dash.local-drewp_annex2\",\"-o\",\"ControlMaster=auto\",\"-o\",\"ControlPersist=yes\",\"-T\",\"drewp@git-annex-dash.local-drewp_annex2\",\"git-annex-shell 'configlist' '/~/annex2/'\"]
+zsh:1: command not found: git-annex-shell
+Remote dash.local_annex2 does not have git-annex installed; setting remote.dash.local_annex2.annex-ignore
+</pre>
+
+You said you're running from the standalone tarball. I think that's the problem, probably if you get git-annex-shell into your path it'll just work.
+
+Can you paste the line git-annex added to \"dash\"'s .ssh/authorized_keys?
+"""]]
diff --git a/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_12_1837b70ace42882db3ab82e001680934._comment b/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_12_1837b70ace42882db3ab82e001680934._comment
new file mode 100644
index 000000000..54ba310b5
--- /dev/null
+++ b/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_12_1837b70ace42882db3ab82e001680934._comment
@@ -0,0 +1,29 @@
+[[!comment format=mdwn
+ username="http://bigasterisk.com/"
+ nickname="Drew Perttula"
+ subject="comment 12"
+ date="2013-07-28T05:36:39Z"
+ content="""
+Thanks for finding that. I added git-annex-shell to my path and ran again. The repo lists look good now.
+
+For the record, here's what I am getting in authorized_keys on dash:
+
+ command=\"GIT_ANNEX_SHELL_DIRECTORY='/home/drewp/annex2' ~/.ssh/git-annex-shell\",no-agent-forwarding,no-port-forwarding,no-X11-forwarding ssh-rsa AAAAB3NzaC1y.......0c2ilnh drewp@bang
+
+
+When I went to the settings on each box, all 4 repository group select boxes were blank. I set them all to 'client'.
+
+How do we make this long ticket worth your time by improving the code so people don't hit the same trap in the future? I think I would have looked in the right direction if, instead of saying nothing and not having a uuid to make the links work, the web ui said something like this:
+
+ 'command not found: git-annex-shell' on remote host. Sync disabled with this host.
+
+
+--------
+
+Next, I ran \"date > annex2/file1\" on bang. The web consoles said they synced, but no file appeared on dash. There was a ~/annex2/.git/annex/objects/../../SHA256.../SHA256... file on dash with the right contents, but no symlink showed up in dash:~/annex2.
+
+I ran \"date > annex2/file2\" on dash, and then I got both file1 and file2 on both boxes.
+
+In the new logs at http://bigasterisk.com/post/git-annex/logs2/, the surprise is at [2013-07-27 22:10:49 PDT] where I thought dash would make a symlink called 'file1' but instead it reports no attempt or error. Later at [2013-07-27 22:12:08 PDT], while dealing with the upload of file2, dash finally makes the symlink for file1.
+
+"""]]
diff --git a/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_13_ca9c87a10f29e41572540edeb99652f2._comment b/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_13_ca9c87a10f29e41572540edeb99652f2._comment
new file mode 100644
index 000000000..07cf64865
--- /dev/null
+++ b/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_13_ca9c87a10f29e41572540edeb99652f2._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.21"
+ subject="comment 13"
+ date="2013-07-30T18:51:38Z"
+ content="""
+I'm more interested in fixing core problems, like why it was not able to find git-annex-shell, than in fixing bugs in the web UI that follow on from those problems.
+
+When you're using the standalone tarball, it's supposed to set up `~/.ssh/git-annex-shell` to point to wherever you've unpacked the tarball. The assistant does this the first time you run it, and any time it sees the file is out of date.
+I've tested this, and it appears to be working ok. I don't understand what happened in your case to prevent this from happening.
+"""]]
diff --git a/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_1_69eafc4201e3014ef1b5d74fe319e462._comment b/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_1_69eafc4201e3014ef1b5d74fe319e462._comment
new file mode 100644
index 000000000..03d14c586
--- /dev/null
+++ b/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_1_69eafc4201e3014ef1b5d74fe319e462._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.235"
+ subject="comment 1"
+ date="2013-07-10T16:31:40Z"
+ content="""
+Everything you've described is expected behavior, when the content of the file has not yet been transferred to the repository.
+
+There should be something in daemon.log about the transfer of the file. If there's an error message for the transfer, it will certainly show up there. You can enable debugging to get more information in daemon.log about file transfers.
+"""]]
diff --git a/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_2_b7a64db9abe006af8c30169ad849efe9._comment b/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_2_b7a64db9abe006af8c30169ad849efe9._comment
new file mode 100644
index 000000000..954d6e375
--- /dev/null
+++ b/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_2_b7a64db9abe006af8c30169ad849efe9._comment
@@ -0,0 +1,76 @@
+[[!comment format=mdwn
+ username="http://bigasterisk.com/"
+ nickname="Drew Perttula"
+ subject="debug log"
+ date="2013-07-16T04:02:40Z"
+ content="""
+receiver side logs again, with --debug mode on. I don't see anything weird.
+
+
+ [2013-07-15 20:53:02 PDT] read: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"show-ref\",\"git-annex\"]
+ [2013-07-15 20:53:02 PDT] read: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+ [2013-07-15 20:53:02 PDT] read: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"log\",\"refs/heads/git-annex..a7cb1b3f2a3f2a7d24827e10f9f3ac5848fd11d9\",\"--oneline\",\"-n1\"]
+ [2013-07-15 20:53:02 PDT] read: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"log\",\"refs/heads/git-annex..4a2771e15cb5c7a0a8d70443e76b65c12115a8cd\",\"--oneline\",\"-n1\"]
+ [2013-07-15 20:53:02 PDT] read: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"log\",\"refs/heads/git-annex..ddf6aa74d771521b11657edfae558858b60e8368\",\"--oneline\",\"-n1\"]
+ (merging synced/git-annex into git-annex...)
+ [2013-07-15 20:53:02 PDT] feed: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"update-index\",\"-z\",\"--index-info\"]
+ [2013-07-15 20:53:02 PDT] read: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"diff-index\",\"--raw\",\"-z\",\"-r\",\"--no-renames\",\"-l0\",\"--cached\",\"4a2771e15cb5c7a0a8d70443e76b65c12115a8cd\"]
+ [2013-07-15 20:53:02 PDT] read: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"log\",\"4a2771e15cb5c7a0a8d70443e76b65c12115a8cd..refs/heads/git-annex\",\"--oneline\",\"-n1\"]
+ [2013-07-15 20:53:02 PDT] call: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"update-ref\",\"refs/heads/git-annex\",\"4a2771e15cb5c7a0a8d70443e76b65c12115a8cd\"]
+ [2013-07-15 20:53:02 PDT] read: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"symbolic-ref\",\"HEAD\"]
+ [2013-07-15 20:53:02 PDT] read: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"show-ref\",\"refs/heads/master\"]
+ [2013-07-15 20:53:02 PDT] Merger: merging refs/heads/synced/master into refs/heads/master
+
+ [2013-07-15 20:53:02 PDT] read: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"symbolic-ref\",\"HEAD\"]
+ [2013-07-15 20:53:02 PDT] read: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"show-ref\",\"refs/heads/master\"]
+ [2013-07-15 20:53:02 PDT] read: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"show-ref\",\"--hash\",\"refs/heads/master\"]
+ [2013-07-15 20:53:02 PDT] call: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex/.git/annex/merge/\",\"merge\",\"--no-edit\",\"refs/heads/synced/master\"]
+ Updating 6f8cbe0..18cea18
+ Fast-forward
+ test-2013-07-15e | 1 +
+ 1 file changed, 1 insertion(+)
+ create mode 120000 test-2013-07-15e
+ [2013-07-15 20:53:02 PDT] read: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"show-ref\",\"--hash\",\"refs/heads/master\"]
+ [2013-07-15 20:53:02 PDT] read: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"diff-tree\",\"-z\",\"--raw\",\"--no-renames\",\"-l0\",\"-r\",\"6f8cbe0a34d70e70a6365385bbd4338d97047d4b\",\"18cea18855143095a872a463eb0a7cf5dd81de4c\"]
+ [2013-07-15 20:53:02 PDT] read: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"show-ref\",\"git-annex\"]
+ [2013-07-15 20:53:02 PDT] read: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+ [2013-07-15 20:53:02 PDT] read: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"log\",\"refs/heads/git-annex..4a2771e15cb5c7a0a8d70443e76b65c12115a8cd\",\"--oneline\",\"-n1\"]
+ [2013-07-15 20:53:02 PDT] read: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"log\",\"refs/heads/git-annex..ddf6aa74d771521b11657edfae558858b60e8368\",\"--oneline\",\"-n1\"]
+ [2013-07-15 20:53:02 PDT] read: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"log\",\"refs/heads/git-annex..a7cb1b3f2a3f2a7d24827e10f9f3ac5848fd11d9\",\"--oneline\",\"-n1\"]
+ [2013-07-15 20:53:02 PDT] feed: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"update-index\",\"-z\",\"--index-info\"]
+ [2013-07-15 20:53:02 PDT] read: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"diff-index\",\"--raw\",\"-z\",\"-r\",\"--no-renames\",\"-l0\",\"--cached\",\"refs/heads/git-annex\"]
+ [2013-07-15 20:53:02 PDT] Watcher: add symlink test-2013-07-15e
+ [2013-07-15 20:53:02 PDT] chat: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"hash-object\",\"-t\",\"blob\",\"-w\",\"--stdin\",\"--no-filters\"]
+ [2013-07-15 20:53:02 PDT] Committer: committing 1 changes
+ [2013-07-15 20:53:02 PDT] Committer: Committing changes to git
+ (Recording state in git...)
+ [2013-07-15 20:53:02 PDT] feed: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"update-index\",\"-z\",\"--index-info\"]
+ [2013-07-15 20:53:02 PDT] read: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"commit\",\"--allow-empty-message\",\"--no-edit\",\"-m\",\"\",\"--quiet\",\"--no-verify\"]
+ [2013-07-15 20:53:02 PDT] Pusher: Syncing with host1.local_annex
+ [2013-07-15 20:53:02 PDT] read: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"symbolic-ref\",\"HEAD\"]
+ [2013-07-15 20:53:02 PDT] read: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"show-ref\",\"refs/heads/master\"]
+ [2013-07-15 20:53:02 PDT] Pusher: pushing to [Remote { name =\"host1.local_annex\" }]
+ [2013-07-15 20:53:02 PDT] call: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"branch\",\"-f\",\"synced/master\"]
+ [2013-07-15 20:53:02 PDT] call: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"push\",\"host1.local_annex\",\"git-annex:synced/git-annex\",\"master:synced/master\"]
+ To ssh://drewp@git-annex-host1.local-drewp_annex/~/annex/
+ a7cb1b3..4a2771e git-annex -> synced/git-annex
+ [2013-07-15 20:53:02 PDT] read: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"show-ref\",\"git-annex\"]
+ [2013-07-15 20:53:02 PDT] read: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"push\",\"host1.local_annex\",\"git-annex:synced/git-annex\",\"master\"]
+ [2013-07-15 20:53:02 PDT] read: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+ [2013-07-15 20:53:02 PDT] read: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"log\",\"refs/heads/git-annex..4a2771e15cb5c7a0a8d70443e76b65c12115a8cd\",\"--oneline\",\"-n1\"]
+ [2013-07-15 20:53:02 PDT] read: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"log\",\"refs/heads/git-annex..ddf6aa74d771521b11657edfae558858b60e8368\",\"--oneline\",\"-n1\"]
+ [2013-07-15 20:53:02 PDT] read: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"symbolic-ref\",\"HEAD\"]
+ [2013-07-15 20:53:02 PDT] read: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"show-ref\",\"refs/heads/master\"]
+ [2013-07-15 20:53:02 PDT] Merger: merging refs/remotes/host1.local_annex/synced/master into refs/heads/master
+
+ [2013-07-15 20:53:02 PDT] read: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"symbolic-ref\",\"HEAD\"]
+ [2013-07-15 20:53:02 PDT] read: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"show-ref\",\"refs/heads/master\"]
+ [2013-07-15 20:53:02 PDT] read: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"show-ref\",\"--hash\",\"refs/heads/master\"]
+ [2013-07-15 20:53:02 PDT] call: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex/.git/annex/merge/\",\"merge\",\"--no-edit\",\"refs/remotes/host1.local_annex/synced/master\"]
+ Already up-to-date.
+ [2013-07-15 20:53:02 PDT] read: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"show-ref\",\"--hash\",\"refs/heads/master\"]
+ [2013-07-15 20:53:02 PDT] read: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"diff-tree\",\"-z\",\"--raw\",\"--no-renames\",\"-l0\",\"-r\",\"18cea18855143095a872a463eb0a7cf5dd81de4c\",\"18cea18855143095a872a463eb0a7cf5dd81de4c\"]
+ [2013-07-15 20:53:28 PDT] read: git [\"--git-dir=/home/drewp/annex/.git\",\"--work-tree=/home/drewp/annex\",\"ls-tree\",\"-z\",\"--\",\"refs/heads/git-annex\",\"uuid.log\",\"remote.log\",\"trust.log\",\"group.log\",\"preferred-content.log\"]
+
+I also noticed on host1 where the file was made, there is a git node in gitk that says 'Local uncommitted changes, not checked in to index' and this node appears to have all my file contents as diffs. So the problem is maybe not the transfer, but the failure of the originating side to commit the file contents properly?
+"""]]
diff --git a/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_3_197ac6070f256131c6e18a07aa3834fa._comment b/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_3_197ac6070f256131c6e18a07aa3834fa._comment
new file mode 100644
index 000000000..d772de5af
--- /dev/null
+++ b/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_3_197ac6070f256131c6e18a07aa3834fa._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.90"
+ subject="comment 3"
+ date="2013-07-16T18:03:40Z"
+ content="""
+It's normal for git diff and gitk to look like that in a repository that's using direct mode.
+
+In your log, I see you added a file \"test-2013-07-15e\". And I don't see any indication that it tried to transfer it.
+
+There are a few reasons that could happen. If you've \"paused\" syncing with a remote in the webapp, it could do that.
+
+I think more likely would be if you've put the remote repository in a repository group that doesn't want the file. If it's configured to be in the Manual group or the Source group (or the Transfer, Public, or Small Archive group for that matter), the assistant won't try to send files to it. You can check this by editing the repository in the webapp. It should probably be set to be in the Client group.
+"""]]
diff --git a/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_4_fe07832333b536c71b7dcb46a4a44bd0._comment b/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_4_fe07832333b536c71b7dcb46a4a44bd0._comment
new file mode 100644
index 000000000..2201db88e
--- /dev/null
+++ b/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_4_fe07832333b536c71b7dcb46a4a44bd0._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="http://bigasterisk.com/"
+ nickname="Drew Perttula"
+ subject="comment 4"
+ date="2013-07-25T05:02:16Z"
+ content="""
+I saw the 'syncing enabled'/'syncing disabled' switch in the webapp, which I think is what you're calling pause. That was always enabled.
+
+I never adjusted the groups, but I see in the webapp that my remote is busted in other ways. It has no title, and settings->edit makes an error page. The edit link is like this:
+
+http://127.0.0.1:38187/config/repository/edit/NoUUID?auth=4294a...333c
+
+and the error is
+
+ Internal Server Error
+ Unknown UUID
+
+I'll try re-configuring that remote. I wish the webapp could tell me more about what is broken with the remote repo and where I might go to repair it.
+"""]]
diff --git a/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_5_540bca4e6fdfc10eeab875ecc0f2b3f3._comment b/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_5_540bca4e6fdfc10eeab875ecc0f2b3f3._comment
new file mode 100644
index 000000000..8e00198ef
--- /dev/null
+++ b/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_5_540bca4e6fdfc10eeab875ecc0f2b3f3._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://bigasterisk.com/"
+ nickname="Drew Perttula"
+ subject="comment 5"
+ date="2013-07-25T05:14:12Z"
+ content="""
+BTW \"go enter it into the computer you want to pair with\" is a very frustrating instruction to read. Every time I try to do a pairing and I encounter that, it's telling me \"now it's time for you to guess what to do, so this is probably where you'll screw things up.\" I have no idea where to enter that secret phrase. I would also like to know if 'asdfasdf' is a good secret phrase or not, presuming the two computers are both on my internal network. Does the secret matter later or is it just used for a minute?
+
+So far, I keep getting blank repo names with the NoUUID edit url, or I fail to accomplish a pairing at all.
+"""]]
diff --git a/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_6_3f236b35e9820cd88bb77fcd57d6975e._comment b/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_6_3f236b35e9820cd88bb77fcd57d6975e._comment
new file mode 100644
index 000000000..63261fb9d
--- /dev/null
+++ b/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_6_3f236b35e9820cd88bb77fcd57d6975e._comment
@@ -0,0 +1,43 @@
+[[!comment format=mdwn
+ username="http://bigasterisk.com/"
+ nickname="Drew Perttula"
+ subject="comment 6"
+ date="2013-07-25T05:36:07Z"
+ content="""
+Here's how little it takes for things to go wrong:
+
+----
+First host:
+
+bang(pts/17):~/annex% git init
+Initialized empty Git repository in /home/drewp/annex/.git/
+
+bang(pts/17):~/annex% git-annex init
+init ok
+(Recording state in git...)
+
+bang(pts/17):~/annex% git-annex webapp --listen 10.1.0.1:9999
+http://10.1.0.1:9999/?auth=6f9a8b...
+
+
+----
+Second host:
+
+dash(pts/34):~/annex% git init
+Initialized empty Git repository in /home/drewp/annex/.git/
+
+dash(pts/34):~/annex% git-annex init
+init ok
+(Recording state in git...)
+
+dash(pts/34):~/annex% git-annex webapp --listen 10.1.0.229:9999
+http://10.1.0.229:9999/?auth=f28bd56b456....
+
+
+Browse to first URI. Add another repo. Local computer. Enter 'qwerty'.
+Browse to second URI. Respond to pairing request. Enter 'qwerty' again.
+View both dashboards: http://bigasterisk.com/post/git-annex-bad-pair.png
+
+
+
+"""]]
diff --git a/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_7_3cc5dae0351201522711a7caeecd60d5._comment b/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_7_3cc5dae0351201522711a7caeecd60d5._comment
new file mode 100644
index 000000000..832f38fa5
--- /dev/null
+++ b/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_7_3cc5dae0351201522711a7caeecd60d5._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 7"
+ date="2013-07-25T20:02:18Z"
+ content="""
+What settings does `.git/config` have for the git remote created by the local pairing process?
+
+Since I can't reproduce any problems with local pairing -- it works great on this network -- you will need to enable debugging, reproduce the bug, and send a debug log for me to debug this any further.
+"""]]
diff --git a/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_8_3c3883cb66d02a15d5de84d22aa113da._comment b/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_8_3c3883cb66d02a15d5de84d22aa113da._comment
new file mode 100644
index 000000000..bf14ad573
--- /dev/null
+++ b/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_8_3c3883cb66d02a15d5de84d22aa113da._comment
@@ -0,0 +1,38 @@
+[[!comment format=mdwn
+ username="http://bigasterisk.com/"
+ nickname="Drew Perttula"
+ subject="~/annex/.git/config files (after running the steps above)"
+ date="2013-07-26T13:20:29Z"
+ content="""
+ dash(pts/32):~/annex% cat .git/config
+ [core]
+ repositoryformatversion = 0
+ filemode = true
+ bare = false
+ logallrefupdates = true
+ [annex]
+ uuid = ddbb5112-3cff-46d3-b42a-f3a6826827a5
+ version = 3
+ [remote \"bang.local_annex\"]
+ url = ssh://drewp@git-annex-bang.local-drewp_annex/~/annex/
+ fetch = +refs/heads/*:refs/remotes/bang.local_annex/*
+ annex-ignore = true
+ annex-cost = 175.0
+
+
+ bang(pts/16):~/annex% cat .git/config
+ [core]
+ repositoryformatversion = 0
+ filemode = true
+ bare = false
+ logallrefupdates = true
+ [annex]
+ uuid = c8a6c420-0567-4f33-8abb-e44b2012ad55
+ version = 3
+ [remote \"dash.local_annex\"]
+ url = ssh://drewp@git-annex-dash.local-drewp_annex/~/annex/
+ fetch = +refs/heads/*:refs/remotes/dash.local_annex/*
+ annex-ignore = true
+ annex-cost = 175.0
+
+"""]]
diff --git a/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_9_c8cece9559bd2dc6154cd28772369e48._comment b/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_9_c8cece9559bd2dc6154cd28772369e48._comment
new file mode 100644
index 000000000..0fd052a4c
--- /dev/null
+++ b/doc/bugs/remote_files_appear_but_are_unreadable_because_their_symlink_targets_don__39__t_exist/comment_9_c8cece9559bd2dc6154cd28772369e48._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 9"
+ date="2013-07-26T16:55:08Z"
+ content="""
+Like I sort of expected, this is missing a remote.$foo.annex-uuid setting. But I don't know why yet. I need a debug log to figure this out.
+
+Can you enable debugging (run git-annex webapp --debug), reproduce the problem again, and send me the log?
+"""]]
diff --git a/doc/bugs/remote_not_showing_up_in_webapp.mdwn b/doc/bugs/remote_not_showing_up_in_webapp.mdwn
new file mode 100644
index 000000000..f8b4da7b1
--- /dev/null
+++ b/doc/bugs/remote_not_showing_up_in_webapp.mdwn
@@ -0,0 +1,88 @@
+### Please describe the problem.
+
+This is a followup on [[bugs/internal_server_error:_unknown_UUID_on_webapp]]. In that issue, webapps previous to 20130929 would crash with `internal server error: unknown UUID`. This was fixed at that date, but some problems remain, namely that the remote that is recognized on the commandline doesn't show up in the webapp.
+
+`markov` is able to push to `marcos`, but not the reverse because `markov` is hidden behind a NAT. `git annex sync` seems to do the right thing accordingly on both ends (which is: `marcos` doesn't try to push to `markov` but `markov` pushes to `marcos`).
+
+### What steps will reproduce the problem?
+
+See [[bugs/internal_server_error:_unknown_UUID_on_webapp]]. I didn't do any further changes other than upgrade `git-annex` on both ends.
+
+### What version of git-annex are you using? On what operating system?
+
+`marcos` is now running `Version: 4.20131105-g8efdc1a Build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP DNS Feeds Quvi TDFA CryptoHash`
+
+`markov` is now running the wheezy backport, `4.20131002~bpo70+1`.
+
+### Please provide any additional information below.
+
+#### On `marcos`
+
+Here's the output of `git annex status` on `marcos`:
+
+[[!format sh """
+anarcat@marcos:books$ git annex status
+repository mode: direct
+trusted repositories: 0
+semitrusted repositories: 3
+ 00000000-0000-0000-0000-000000000001 -- web
+ a75cbbf7-e055-423e-b375-443e0552c9e2 -- here (anarcat@marcos:/srv/books)
+ aa500f29-42d9-4777-ae02-4a2c3d47db44 -- anarcat@markov:~/books
+untrusted repositories: 0
+transfers in progress: none
+available local disk space: 7.04 gigabytes (+1 megabyte reserved)
+local annex keys: 736
+local annex size: 3.92 gigabytes
+annexed files in working tree: 721
+size of annexed files in working tree: 3.92 gigabytes
+bloom filter size: 16 mebibytes (0.1% full)
+backend usage:
+ SHA256E: 1457
+# End of transcript or log.
+"""]]
+
+Here's a screenshot of the idle webapp on marcos:
+
+<img src="http://i.imgur.com/3HFgj3w.png" />
+
+You can clearly see that the webapp doesn't see the `markov` remote.
+
+When `markov` transfers stuff, `marcos` sees the transfers happening, but marks it as going to the `unknown` remote:
+
+<img src="http://i.imgur.com/YOu9GbA.png" />
+
+Clicking on that link is what was previously triggering [[bugs/internal_server_error:_unknown_UUID_on_webapp]] but now yields a "Unknown remote" error.
+
+<img src="http://i.imgur.com/y7JxULi.png" />
+
+#### On `markov`:
+
+Here is a screenshot from `markov` that shows *it* knows about both repositories and seem to behave properly:
+
+<img src="http://i.imgur.com/fTMslVT.png" />
+
+And here's the output of `git annex status` on markov:
+
+[[!format sh """
+anarcat@desktop008:books$ git annex status
+repository mode: indirect
+trusted repositories: 0
+semitrusted repositories: 3
+ 00000000-0000-0000-0000-000000000001 -- web
+ a75cbbf7-e055-423e-b375-443e0552c9e2 -- origin (anarcat@marcos:/srv/books)
+ aa500f29-42d9-4777-ae02-4a2c3d47db44 -- here (anarcat@markov:~/books)
+untrusted repositories: 0
+transfers in progress:
+ downloading Patrick K. O'Brien/Philip's Atlas of World History, Concise Edition (115)/Philip's Atlas of World History, Concise Edition - Patrick K. O'Brien.pdf from origin
+available local disk space: 93.25 gigabytes (+1 megabyte reserved)
+temporary directory size: 50.07 megabytes (clean up with git-annex unused)
+local annex keys: 708
+local annex size: 3.81 gigabytes
+known annex keys: 721
+known annex size: 3.92 gigabytes
+bloom filter size: 16 mebibytes (0.1% full)
+backend usage:
+ SHA256E: 1429
+"""]]
+
+Finally, note that you sometimes see `desktop008` above: it turns out I am running `git annex` from my workstation, which NFS-mounts the `/home` directory of `markov` into `/srv/musique`. --[[anarcat]]
diff --git a/doc/bugs/remote_not_showing_up_in_webapp/comment_1_2a269732fd528f505777542d3556437a._comment b/doc/bugs/remote_not_showing_up_in_webapp/comment_1_2a269732fd528f505777542d3556437a._comment
new file mode 100644
index 000000000..4582a3071
--- /dev/null
+++ b/doc/bugs/remote_not_showing_up_in_webapp/comment_1_2a269732fd528f505777542d3556437a._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 1"
+ date="2013-11-06T16:38:47Z"
+ content="""
+marcov does not show up in the webapp because there is no configured git remote for it.
+
+This is a slightly confusing corner of the webapp. The webapp will show repositories that do not have a configured remote, but it only does it for special remotes. ssh repos, being regular git remotes, don't currently show up in the webapp unless that repository is actually set up as a remote.
+
+It should certainly not show it as \"unknown\"; it would be much better to use the full repo description here, since it does not have a remote name.
+(Unless the description is really long!)
+
+I think you'll also get the \"unknown uuid\" screen even for a special remote that is not configured in the local repository. So that needs to be fixed.
+
+Finally, it would probably be good for the webapp to show ssh repos that don't have remotes as existing, and let the user enter a ssh address to configure them. The problem with trying to do this is it actually has no idea that this is a ssh repo. It could just as easily be a local directory. The UI to configure it would be pretty elaborate.
+"""]]
diff --git a/doc/bugs/removable_device_configurator_chokes_on_spaces.mdwn b/doc/bugs/removable_device_configurator_chokes_on_spaces.mdwn
new file mode 100644
index 000000000..e114877ec
--- /dev/null
+++ b/doc/bugs/removable_device_configurator_chokes_on_spaces.mdwn
@@ -0,0 +1,18 @@
+# What steps will reproduce the problem?
+
+1. Get a removable device and create a filesystem with a label containing a space, e.g.:
+ # mkfs.ext4 -L "Backup Home" /dev/sdb1
+2. Open the webapp and add a new repository on a removabledevice
+3. Select the devices mountpoint, e.g. /media/Backup\ Home
+
+# What is the expected output? What do you see instead?
+
+The configurator should remove spaces for branch names, but it actually seems to call git remote add with "Backup Home" as argument which is invalid.
+
+The assistant produces an internal server error and subsequently crashes completely.
+
+# What version of git-annex are you using? On what operating system?
+
+git-annex 3.20120924 from the Debian package in sid on Debian wheezy, amd64.
+
+> Thanks for reporting this, I've fixed it in git. [[done]] --[[Joey]]
diff --git a/doc/bugs/rename:_permission_denied__44___after_direct_mode_switch.mdwn b/doc/bugs/rename:_permission_denied__44___after_direct_mode_switch.mdwn
new file mode 100644
index 000000000..c315d4789
--- /dev/null
+++ b/doc/bugs/rename:_permission_denied__44___after_direct_mode_switch.mdwn
@@ -0,0 +1,81 @@
+### Please describe the problem.
+
+On Mac OS X, I tried to switch a repository to direct mode, but there was a
+problem in the middle of the switch (permission denied) and the switch
+aborted, leaving the repository in a half switched state.
+
+I tried different manipulations, one of which was a checkout (oops), switch
+back to indirect, then direct again, and now I have the repository in direct
+mode except one file which caused the permission denied error.
+
+### What steps will reproduce the problem?
+
+Do not know exactly why this file is special. I still have the repository, and
+each time I try to get this file, it fails with the same error message.
+
+### What version of git-annex are you using? On what operating system?
+
+On Umba, git-annex version: 4.20130723, on Mac OS X 10.6.8.
+
+### Please provide any additional information below.
+
+Umba is the Mac OS X, camaar and riva are Debian machines.
+
+[[!format sh """
+Umba$ git annex version
+git-annex version: 4.20130723
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV FsEvents XMPP DNS
+Umba$
+
+Umba$ git annex get --from riva --not --in here
+get 2013-07-31/2013-07-31_180411.jpg (from riva...)
+Password:
+SHA256-s2819887--987f9811d7b5c7a287a74b7adbb852be4d18eeda61c3507f4e08c534d2356f4c
+ 2819887 100% 943.08kB/s 0:00:02 (xfer#1, to-check=0/1)
+
+sent 42 bytes received 2820397 bytes 433913.69 bytes/sec
+total size is 2819887 speedup is 1.00
+failed
+git-annex: get: 1 failed
+Umba$ find . -name SHA256-s2819887-\*
+./.git/annex/objects/wq/3j/SHA256-s2819887--987f9811d7b5c7a287a74b7adbb852be4d18eeda61c3507f4e08c534d2356f4c
+./.git/annex/objects/wq/3j/SHA256-s2819887--987f9811d7b5c7a287a74b7adbb852be4d18eeda61c3507f4e08c534d2356f4c/SHA256-s2819887--987f9811d7b5c7a287a74b7adbb852be4d18eeda61c3507f4e08c534d2356f4c.cache
+./.git/annex/objects/wq/3j/SHA256-s2819887--987f9811d7b5c7a287a74b7adbb852be4d18eeda61c3507f4e08c534d2356f4c/SHA256-s2819887--987f9811d7b5c7a287a74b7adbb852be4d18eeda61c3507f4e08c534d2356f4c.map
+./.git/annex/transfer/failed/download/13fd5d5a-ed97-11e2-9178-574d3b1c0618/SHA256-s2819887--987f9811d7b5c7a287a74b7adbb852be4d18eeda61c3507f4e08c534d2356f4c
+./.git/annex/transfer/failed/download/95443f2e-ed96-11e2-9d3f-8ffa5b1aae7a/SHA256-s2819887--987f9811d7b5c7a287a74b7adbb852be4d18eeda61c3507f4e08c534d2356f4c
+Umba$ git annex fsck
+fsck 2013-07-31/2013-07-31_180411.jpg ok
+(Recording state in git...)
+Umba$ git annex drop 2013-07-31/2013-07-31_180411.jpg
+Umba$ git annex get --from riva --not --in here
+get 2013-07-31/2013-07-31_180411.jpg (from riva...)
+Password:
+SHA256-s2819887--987f9811d7b5c7a287a74b7adbb852be4d18eeda61c3507f4e08c534d2356f4c
+ 2819887 100% 949.58kB/s 0:00:02 (xfer#1, to-check=0/1)
+
+sent 42 bytes received 2820397 bytes 512807.09 bytes/sec
+total size is 2819887 speedup is 1.00
+failed
+git-annex: get: 1 failed
+Umba$
+
+camaar% git annex copy --to umba --not --in umba
+copy 2013-07-31/2013-07-31_180411.jpg (checking umba...) (to umba...)
+SHA256-s2819887--987f9811d7b5c7a287a74b7adbb852be4d18eeda61c3507f4e08c534d2356f4c
+ 2819887 100% 4.19MB/s 0:00:00 (xfer#1, to-check=0/1)
+git-annex: //Users/nicolas/Pictures/Petites Boutes/.git/annex/tmp/2013-07-31_18041141700.jpg: rename: permission denied (Operation not permitted)
+git-annex-shell: recvkey: 1 failed
+
+sent 2820393 bytes received 42 bytes 1128174.00 bytes/sec
+total size is 2819887 speedup is 1.00
+rsync error: syntax or usage error (code 1) at main.c(1070) [sender=3.0.9]
+
+ rsync failed -- run git annex again to resume file transfer
+failed
+git-annex: copy: 1 failed
+camaar%
+"""]]
+
+> Put in a fix that works, although perhaps not ideal as I do not
+> understand how the repo got into the original problem state. [[done]]
+> --[[Joey]]
diff --git a/doc/bugs/rename:_permission_denied__44___after_direct_mode_switch/comment_1_14cec6448831c67794b62926a03b2fc5._comment b/doc/bugs/rename:_permission_denied__44___after_direct_mode_switch/comment_1_14cec6448831c67794b62926a03b2fc5._comment
new file mode 100644
index 000000000..1aef52076
--- /dev/null
+++ b/doc/bugs/rename:_permission_denied__44___after_direct_mode_switch/comment_1_14cec6448831c67794b62926a03b2fc5._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.80"
+ subject="comment 1"
+ date="2013-09-30T16:47:42Z"
+ content="""
+I was able to cause a permission denied on `git annex direct` if I made the file in .git/annex/objects be owned by an different user than me. I do not know how that could happen in normal operation of git-annex.
+
+
+I have made `git annex direct` catch this exception and continue. So you will get a repository that is switched to direct mode, but with one file that is still a symlink to the content, and if you fix the permissions problem, `git annex fsck` will fix it.
+
+I am curious about any details of how your repository got into the original state..
+"""]]
diff --git a/doc/bugs/rename:_permission_denied__44___after_direct_mode_switch/comment_2_93af8f48a01b6e2d011bd6f60499ccd2._comment b/doc/bugs/rename:_permission_denied__44___after_direct_mode_switch/comment_2_93af8f48a01b6e2d011bd6f60499ccd2._comment
new file mode 100644
index 000000000..a0e73cc5e
--- /dev/null
+++ b/doc/bugs/rename:_permission_denied__44___after_direct_mode_switch/comment_2_93af8f48a01b6e2d011bd6f60499ccd2._comment
@@ -0,0 +1,23 @@
+[[!comment format=mdwn
+ username="http://nicolas-schodet.myopenid.com/"
+ ip="81.56.19.53"
+ subject="comment 2"
+ date="2013-11-23T14:38:21Z"
+ content="""
+Here are the files in details:
+
+[[!format sh \"\"\"
+Umba:.../.git$ ls -ld $(find . -name SHA256-s2819887-\*) # the bad file
+drwxr-xr-t 4 marie-eve staff 136 Aug 17 17:05 ./annex/objects/wq/3j/SHA256-s2819887--987f9811d7b5c7a287a74b7adbb852be4d18eeda61c3507f4e08c534d2356f4c/
+-rw-r--r-- 1 marie-eve staff 560 Nov 23 15:25 ./annex/objects/wq/3j/SHA256-s2819887--987f9811d7b5c7a287a74b7adbb852be4d18eeda61c3507f4e08c534d2356f4c/SHA256-s2819887--987f9811d7b5c7a287a74b7adbb852be4d18eeda61c3507f4e08c534d2356f4c.cache
+-rw------- 1 marie-eve staff 33 Aug 17 17:05 ./annex/objects/wq/3j/SHA256-s2819887--987f9811d7b5c7a287a74b7adbb852be4d18eeda61c3507f4e08c534d2356f4c/SHA256-s2819887--987f9811d7b5c7a287a74b7adbb852be4d18eeda61c3507f4e08c534d2356f4c.map
+-rw-r--r-- 1 marie-eve staff 52 Aug 17 17:06 ./annex/transfer/failed/download/13fd5d5a-ed97-11e2-9178-574d3b1c0618/SHA256-s2819887--987f9811d7b5c7a287a74b7adbb852be4d18eeda61c3507f4e08c534d2356f4c
+-rw-r--r-- 1 marie-eve staff 51 Aug 17 10:13 ./annex/transfer/failed/download/95443f2e-ed96-11e2-9d3f-8ffa5b1aae7a/SHA256-s2819887--987f9811d7b5c7a287a74b7adbb852be4d18eeda61c3507f4e08c534d2356f4c
+Umba:.../.git$ ls -ld $(find . -name SHA256-s5066556-\*) # a good file
+dr-xr-xr-x 3 marie-eve staff 102 Nov 23 15:27 ./annex/objects/Fx/w0/SHA256-s5066556--0e4a47efdc14c884d07c017ba5506a56affb136d87bef5700145774fd9089f25/
+-r--r--r-- 1 marie-eve staff 5066556 Nov 6 17:43 ./annex/objects/Fx/w0/SHA256-s5066556--0e4a47efdc14c884d07c017ba5506a56affb136d87bef5700145774fd9089f25/SHA256-s5066556--0e4a47efdc14c884d07c017ba5506a56affb136d87bef5700145774fd9089
+Umba:.../.git$
+\"\"\"]]
+
+No more idea on how it reached this situation.
+"""]]
diff --git a/doc/bugs/rename:_permission_denied__44___after_direct_mode_switch/comment_3_f8fba1955e62360061613e5898b3d74e._comment b/doc/bugs/rename:_permission_denied__44___after_direct_mode_switch/comment_3_f8fba1955e62360061613e5898b3d74e._comment
new file mode 100644
index 000000000..d7d05da85
--- /dev/null
+++ b/doc/bugs/rename:_permission_denied__44___after_direct_mode_switch/comment_3_f8fba1955e62360061613e5898b3d74e._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://nicolas-schodet.myopenid.com/"
+ ip="81.56.19.53"
+ subject="comment 3"
+ date="2013-11-23T15:42:26Z"
+ content="""
+The link seems to be special:
+
+[[!format sh \"\"\"
+Umba:2013-07-31$ ls -lO 2013-07-31_180411.jpg
+lrwxr-xr-x 1 marie-eve staff uchg 191 Aug 12 21:45 2013-07-31_180411.jpg@ -> ../.git/annex/objects/wq/3j/SHA256-s2819887--987f9811d7b5c7a287a74b7adbb852be4d18eeda61c3507f4e08c534d2356f4c/SHA256-s2819887--987f9811d7b5c7a287a74b7adbb852be4d18eeda61c3507f4e08c534d2356f4c
+Umba:2013-07-31$
+\"\"\"]]
+
+I tried the chflags command with no success... I suppose I need a MAC specialist.
+"""]]
diff --git a/doc/bugs/renaming_a_file_makes_annex_get_the_file__39__s_content_from_remote.mdwn b/doc/bugs/renaming_a_file_makes_annex_get_the_file__39__s_content_from_remote.mdwn
new file mode 100644
index 000000000..c2ca43da5
--- /dev/null
+++ b/doc/bugs/renaming_a_file_makes_annex_get_the_file__39__s_content_from_remote.mdwn
@@ -0,0 +1,27 @@
+# What steps will reproduce the problem?
+
+1. Use assistant to setup a local repository (client group) and a remote repository (via ssh, backup group).
+
+2. Add some big files and wait for them to be syncronized.
+
+3. Manually switch to indirect mode (to make 'drop' work)
+
+4. Drop the file's content from the local repository.
+
+5. Rename the file using any file manager or mv on the command line.
+
+
+# What is the expected output? What do you see instead?
+
+* Expected outcome was the file being renamed and that name change being propagated to the remote repository without re-transferring the whole file. I didn't drop it for nothing!
+
+* Instead, the file was renamed and the file's content was retrieved from the remote repository.
+
+
+# What version of git-annex are you using? On what operating system?
+
+Git-Annex 3.20130102
+
+Arch Linux on x64.
+
+[[done]]; was not a bug and also the webapp now offers a "manual mode" option that can be chosen instead of "client" to get the desired behavior. --[[Joey]]
diff --git a/doc/bugs/renaming_a_file_makes_annex_get_the_file__39__s_content_from_remote/comment_1_d6aad1831674586fe4cdf61dd2a4bbb9._comment b/doc/bugs/renaming_a_file_makes_annex_get_the_file__39__s_content_from_remote/comment_1_d6aad1831674586fe4cdf61dd2a4bbb9._comment
new file mode 100644
index 000000000..21954076e
--- /dev/null
+++ b/doc/bugs/renaming_a_file_makes_annex_get_the_file__39__s_content_from_remote/comment_1_d6aad1831674586fe4cdf61dd2a4bbb9._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.211"
+ subject="comment 1"
+ date="2013-01-08T18:35:58Z"
+ content="""
+Since your local repository is in the client group, this behavior is actually as intended. Client group means the [[preferred_content]] settings will try to get the content of all files, unlless they're in a directory named \"archive\". This happens not just when you rename a dropped file, but on startup, when the network comes up, or even just periodically it'll notice if some file's content is missing and download it.
+
+So, your choices are
+
+1. Make an `archive` directory, and move files into it when you don't want them available locally. The assistant will even automatically drop them when you move them.
+2. Use `git annex vicfg` to set up your own [[preferred content]] expression that makes it behave how you want. For example, you could use `present` to make the assistant not prefer to have the content of files, unless the content is already present, and then manually `git annex get` and `git annex drop` files as desired.
+
+(BTW, you can use \"drop\" in direct mode with yesterday's release.)
+"""]]
diff --git a/doc/bugs/renaming_a_file_makes_annex_get_the_file__39__s_content_from_remote/comment_2_8591e174c1a8cddfae9371407a58ff1c._comment b/doc/bugs/renaming_a_file_makes_annex_get_the_file__39__s_content_from_remote/comment_2_8591e174c1a8cddfae9371407a58ff1c._comment
new file mode 100644
index 000000000..5dc891c46
--- /dev/null
+++ b/doc/bugs/renaming_a_file_makes_annex_get_the_file__39__s_content_from_remote/comment_2_8591e174c1a8cddfae9371407a58ff1c._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnjjCyhVEcTRM5m4iIBqL3ZCooPx7ZYB_E"
+ nickname="Marcus"
+ subject="comment 2"
+ date="2013-01-08T21:27:39Z"
+ content="""
+Thank you for your answer. In the mean time I already changed the preferred content setting to \"present\" and it's good to know that this issue should be resolved by that as well. Will check later.
+
+Ciao, Marcus
+"""]]
diff --git a/doc/bugs/repair_fails_when_home_on_seperate_partition.mdwn b/doc/bugs/repair_fails_when_home_on_seperate_partition.mdwn
new file mode 100644
index 000000000..19780c7de
--- /dev/null
+++ b/doc/bugs/repair_fails_when_home_on_seperate_partition.mdwn
@@ -0,0 +1,60 @@
+### Please describe the problem.
+
+
+### What steps will reproduce the problem?
+
+(1) Place a broken repo on a different mount point than the root partition.
+
+(2) Run
+ git annex repair.
+
+### What version of git-annex are you using? On what operating system?
+
+ 5.20131118-gc7e5cde on Ubuntu 12.04
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+$ git annex repair --force
+
+Running git fsck ...
+git fsck found 74 broken objects.
+Unpacking all pack files.
+Unpacking objects: 100% (2307/2307), done.
+Unpacking objects: 100% (241565/241565), done.
+Re-running git fsck to see if it finds more problems.
+Initialized empty Git repository in /tmp/tmprepo.0/.git/
+Trying to recover missing objects from remote pi.fritz.box__var_lib_store_annex
+Trying to recover missing objects from remote pi.fritz.box__var_lib_store_annex
+74 missing objects could not be recovered!
+
+
+Deleted remote branch pi.fritz.box__var_lib_store_annex/master (was dffa056).
+error: Could not read 4e01bbdc7ce31247ad66ab13ca46925ac2c8db9a
+fatal: Failed to traverse parents of commit 718525a48b4d6b3404eda5e189332d73c968a2be
+Deleted remote branch pi.fritz.box__var_lib_store_annex/synced/git-annex (was 718525a).
+Deleted remote branch pi.fritz.box__var_lib_store_annex/synced/master (was 9aedf69).
+Deleted remote branch pi.fritz.box_annex/synced/master (was 92b1042).
+Deleted remote branch store/master (was b059380).
+removed 5 remote tracking branches that referred to missing objects
+fatal: bad object refs/heads/git-annex
+fatal: bad object refs/heads/git-annex
+fatal: bad object refs/heads/git-annex
+error: remote branch 'git-annex' not found.
+
+git-annex: /tmp/packed-refs19813: rename: unsupported operation (Invalid cross-device link)
+failed
+git-annex: repair: 1 failed
+
+
+# End of transcript or log.
+"""]]
+
+> Thanks for reporting. As far as I can see, this was fixed
+> accidentially, when I rewrote the packed refs file handling code to not
+> re-write the file. It had been using a temp file, and renaming it, thus
+> the problem. I checked the repair code and can find no other probems
+> of this sort currently in it. [[done]] --[[Joey]]
diff --git a/doc/bugs/restart_daemon_required.mdwn b/doc/bugs/restart_daemon_required.mdwn
new file mode 100644
index 000000000..fe765e24f
--- /dev/null
+++ b/doc/bugs/restart_daemon_required.mdwn
@@ -0,0 +1,22 @@
+Git annex refuses to get/drop files until it's manually relaunched.
+
+I'm trying to setup a basic dropbox like system where a couple of computers sync with a local server I have constantly running ubuntu with ssh.
+
+I think I've setup git annex correctly: when I put files in the repo folder they get uploaded to the bare git repo on the server over ssh automatically and the other computer updates with a broken alias to the file. However the file does not then download from the server despite it being available without a manual restart of the daemon or a git-annex get command from the terminal.
+
+Additionally, files inside archive folders do not get dropped once uploaded to the server without a restart of the daemon.
+
+
+My computers are each setup with the ssh server as a 2nd repository (fullarchive), they are both OSX, and running Version: 4.20130521-g25dba9d according to the webapp. I have also entered my gmail/jabber account on each mac which I believe allows them to communicate indirectly when using the ssh repo.
+
+
+I don't know if this is a setup/misconfiguration error or a bug but I can't see how I've setup the assistant wrong, I did manually change the remote url in the config file, as the assistant was having issues connecting (I'm sshing on 21 for various reasons, although I thought this was supported and I no longer receive errors in the webapp now I've specified my remote.
+
+Should I put the corresponding computers as a repositories of each other? I thought each syncing independently with a centralised git would be a more reliable/simple situation than a potential 3 way sync?
+
+
+I hope this is enough information, I'm usually good at working out issues myself, however this is just frustrating me and the git-annex solution is so nearly perfect if it would work reliably that I can't bring myself to give up on it!
+
+Thanks!
+
+> [[done]], release notes updated; see my comment --[[Joey]]
diff --git a/doc/bugs/restart_daemon_required/comment_1_f79ac16cc9f1e3b08cd121bf5efb29c3._comment b/doc/bugs/restart_daemon_required/comment_1_f79ac16cc9f1e3b08cd121bf5efb29c3._comment
new file mode 100644
index 000000000..bd3fc74c8
--- /dev/null
+++ b/doc/bugs/restart_daemon_required/comment_1_f79ac16cc9f1e3b08cd121bf5efb29c3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-05-31T18:15:03Z"
+ content="""
+Enabling debugging, and send a log. XMPP may not be working.
+"""]]
diff --git a/doc/bugs/restart_daemon_required/comment_2_50c1b268a3cc4514681059eabca674e3._comment b/doc/bugs/restart_daemon_required/comment_2_50c1b268a3cc4514681059eabca674e3._comment
new file mode 100644
index 000000000..439d7ae1a
--- /dev/null
+++ b/doc/bugs/restart_daemon_required/comment_2_50c1b268a3cc4514681059eabca674e3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-05-31T18:20:26Z"
+ content="""
+You could also try upgrading to a current nightly build. There have been a lot of XMPP improvements recently.
+"""]]
diff --git a/doc/bugs/restart_daemon_required/comment_3_1716e0f3c7c44dc77ebf7f00fdd8f9e3._comment b/doc/bugs/restart_daemon_required/comment_3_1716e0f3c7c44dc77ebf7f00fdd8f9e3._comment
new file mode 100644
index 000000000..61423066a
--- /dev/null
+++ b/doc/bugs/restart_daemon_required/comment_3_1716e0f3c7c44dc77ebf7f00fdd8f9e3._comment
@@ -0,0 +1,310 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmxns2UBAMDbTwrwHq_Lx1sNKrVVayq1X4"
+ nickname="Darren"
+ subject="comment 3"
+ date="2013-06-01T01:19:02Z"
+ content="""
+Thanks Joey for the quick reply, I've just updated both clients to the latest versions I could find, one is running Lion so the version is slightly behind as the autobuilds are currently failing to compile. The mountain lion system I believe is running one of the latest builds.
+
+I've captured the error here as best I can, I didn't know what to leave out so apologies for the length of the logs.
+
+===
+Sending Repo (added sync.mov)
+===
+
+ [2013-06-01 01:59:56 BST] main: starting assistant version 4.20130522-g933ba09
+ [2013-06-01 01:59:56\"_xmpp-client._tcp.gmail.com\"
+ BST] TransferScanner: Syncing with Cloud
+ Already up-to-date.
+ Just [(20,0,5222,\"alt1.xmpp.l.google.com.\"),(20,0,5222,\"alt2.xmpp.l.google.com.\"),(20,0,5222,\"alt3.xmpp.l.google.com.\"),(20,0,5222,\"alt4.xmpp.l.google.com.\"),(5,0,5222,\"xmpp.l.google.com.\")]
+
+ (scanning...) [2013-06-01 01:59:56 BST] Watcher: Performing startup scan
+ Already up-to-date.
+ Everything up-to-date
+
+ (started...) [2013-06-01 01:59:58 BST] Committer: Committing changes to git
+ [2013-06-01 01:59:58 BST] Pusher: Syncing with Cloud
+ Everything up-to-date
+ From ssh://cloud.rhymeorange.com:21/tank/git-annex/projects
+ da9a4d5..4142ae6 synced/git-annex -> Cloud/synced/git-annex
+ [2013-06-01 02:00:56 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"ls-tree\",\"-z\",\"--\",\"refs/heads/git-annex\",\"uuid.log\",\"remote.log\",\"trust.log\",\"group.log\",\"preferred-content.log\"]
+ [2013-06-01 02:01:19 BST] Watcher: add direct /Volumes/StoragePool/Projects/init/sync.mov
+ [2013-06-01 02:01:19 BST] read: lsof [\"-F0can\",\"+d\",\"/Volumes/StoragePool/Projects/init/.git/annex/tmp/\"]
+ [2013-06-01 02:01:19 BST] Committer: Adding sync.mov
+
+ (Recording state in git...)
+ (merging Cloud/synced/git-annex into git-annex...)
+ add /Volumes/StoragePool/Projects/init/sync.mov (checksum...) [2013-06-01 02:01:19 BST] read: sha256sum [\"/Volumes/StoragePool/Projects/init/.git/annex/tmp/sync1693.mov\"]
+ recv: resource vanished (Connection reset by peer)
+ [2013-06-01 02:01:20 BST] chat: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"hash-object\",\"-t\",\"blob\",\"-w\",\"--stdin\"]
+ [2013-06-01 02:01:20 BST] Committer: committing 1 changes
+ [2013-06-01 02:01:20 BST] Committer: Committing changes to git
+ [2013-06-01 02:01:20 BST] feed: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"update-index\",\"-z\",\"--index-info\"]
+ [2013-06-01 02:01:20 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"commit\",\"--allow-empty-message\",\"--no-edit\",\"-m\",\"\",\"--quiet\",\"--no-verify\"]
+ [2013-06-01 02:01:20 BST] Pusher: Syncing with Cloud
+ [2013-06-01 02:01:20 BST] Committer: queued Upload UUID \"e393d45e-c8b7-11e2-a1f9-f7c95b1b45ae\" /Volumes/StoragePool/Projects/init/sync.mov Nothing : new file created
+ [2013-06-01 02:01:20 rBeScTv]: Trreasnosufrecrer evra:n iTsrhaends f(eCrorninnegc:t iUopnl oraeds eUtU IbDy \"pee3e9r3)d
+ 45e-c8b7-11e2-a1f9-f7c95b1b45ae\" /Volumes/StoragePool/Projects/init/sync.mov Nothing
+ [2013-06-01 02:01:20 BST] chat: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"hash-object\",\"-w\",\"--stdin-paths\"]
+ [2013-06-01 02:01:20 BST] call: /Applications/git-annex.app/Contents/MacOS/git-annex [\"transferkeys\",\"--readfd\",\"82\",\"--writefd\",\"81\"]
+ [2013-06-01 02:01:20 BST] feed: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"update-index\",\"-z\",\"--index-info\"]
+ [2013-06-01 02:01:20 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+ [2013-06-01 02:01:20 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"write-tree\"]
+ [2013-06-01 02:01:20 BST] chat: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"commit-tree\",\"181162ed25fb1bec4d077e359a5f0e60344e735e\",\"-p\",\"refs/heads/git-annex\"]
+ [2013-06-01 02:01:20 BST] call: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"update-ref\",\"refs/heads/git-annex\",\"ef8dc3b251fbf6baa8149ed077703b2363b3dbc9\"]
+ [2013-06-01 02:01:20 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"symbolic-ref\",\"HEAD\"]
+ [2013-06-01 02:01:20 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"show-ref\",\"refs/heads/master\"]
+ [2013-06-01 02:01:20 BST] Pusher: pushing to [Remote { name =\"Cloud\" }]
+ [2013-06-01 02:01:20 BST] call: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"branch\",\"-f\",\"synced/master\"]
+ [2013-06-01 02:01:20 BST] call: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"push\",\"Cloud\",\"git-annex:synced/git-annex\",\"master:synced/master\"]
+ [2013-06-01 02:01:20 BST] TransferWatcher: transfer starting: Upload UUID \"e393d45e-c8b7-11e2-a1f9-f7c95b1b45ae\" /Volumes/StoragePool/Projects/init/sync.mov Nothing
+ [2013-06-01 02:01:20 BST] TransferWatcher: transfer starting: Upload UUID \"e393d45e-c8b7-11e2-a1f9-f7c95b1b45ae\" /Volumes/StoragePool/Projects/init/sync.mov Nothing
+ [2013-06-01 02:01:21 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"show-ref\",\"git-annex\"]
+ [2013-06-01 02:01:21 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+
+ sync.mov
+ 32768 0% 0.00kB/s 0:00:00
+ [2013-06-01 02:01:21 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"log\",\"refs/heads/git-annex..ef8dc3b251fbf6baa8149ed077703b2363b3dbc9\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:21 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"log\",\"refs/heads/git-annex..8c35b10f8f42367fddc5c12fe39b30014358cd4d\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:21 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"log\",\"refs/heads/git-annex..4142ae6e3befdff987748a92feb65a11aecf4b63\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:21 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"symbolic-ref\",\"HEAD\"]
+ [2013-06-01 02:01:21 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"show-ref\",\"refs/heads/master\"]
+ [2013-06-01 02:01:21 BST] Merger: merging refs/heads/synced/master into refs/heads/master
+ [2013-06-01 02:01:21 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"symbolic-ref\",\"HEAD\"]
+ [2013-06-01 02:01:21 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"show-ref\",\"refs/heads/master\"]
+ [2013-06-01 02:01:21 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"show-ref\",\"--hash\",\"refs/heads/master\"]
+ [2013-06-01 02:01:21 BST] call: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init/.git/annex/merge/\",\"merge\",\"--no-edit\",\"refs/heads/synced/master\"]
+ To ssh://darren@cloud.rhymeorange.com:21/tank/git-annex/projects/
+ 4142ae6..ef8dc3b2 git-annex -> synced/git-annex
+ 1723064..75aa568 master -> synced/master
+ [2013-06-01 02:01:21 BST] XMPPClient: sending: NotifyPush [UUID \"e393d45e-c8b7-11e2-a1f9-f7c95b1b45ae\"]
+ Already up-to-date.
+ [2013-06-01 02:01:21 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"show-ref\",\"--hash\",\"refs/heads/master\"]
+ [2013-06-01 02:01:21 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"diff-tree\",\"-z\",\"--raw\",\"--no-renames\",\"-l0\",\"-r\",\"75aa568fb7f484609a36abdf6afd84ab5aeb0f06\",\"75aa568fb7f484609a36abdf6afd84ab5aeb0f06\"]
+ [2013-06-01 02:01:22 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"show-ref\",\"git-annex\"]
+ [2013-06-01 02:01:22 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+ [2013-06-01 02:01:22 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"log\",\"refs/heads/git 7602176 11% 7.17MB/s 0:00:08
+ -annex..ef8dc3b251fbf6baa8149ed077703b2363b3dbc9\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:22 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"log\",\"refs/heads/git-annex..8c35b10f8f42367fddc5c12fe39b30014358cd4d\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:22 BST] TransferWatcher: transfer starting: Upload UUID \"e393d45e-c8b7-11e2-a1f9-f7c95b1b45ae\" /Volumes/StoragePool/Projects/init/sync.mov Just 7602176
+ [2013-06-01 02:01:22 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"symbolic-ref\",\"HEAD\"]
+ [2013-06-01 02:01:22 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"show-ref\",\"refs/heads/master\"]
+ [2013-06-01 02:01:22 BST] Merger: merging refs/remotes/Cloud/synced/master into refs/heads/master
+ [2013-06-01 02:01:22 BST] TransferWatcher: transfer starting: Upload UUID \"e393d45e-c8b7-11e2-a1f9-f7c95b1b45ae\" /Volumes/StoragePool/Projects/init/sync.mov Just 7602176
+ [2013-06-01 02:01:22 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"symbolic-ref\",\"HEAD\"]
+ [2013-06-01 02:01:22 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"show-ref\",\"refs/heads/master\"]
+ [2013-06-01 02:01:22 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"show-ref\",\"--hash\",\"refs/heads/master\"]
+ [2013-06-01 02:01:22 BST] call: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init/.git/annex/merge/\",\"merge\",\"--no-edit\",\"refs/remotes/Cloud/synced/master\"]
+ Already up-to-date.
+ [2013-06-01 02:01:22 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"show-ref\",\"--hash\",\"refs/heads/master\"]
+ [2013-06-01 02:01:22 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"diff-tree\",\"-z\",\"--raw\",\"--no-renames\",\"-l0\",\"-r\",\"75aa568fb7f484609a36abdf6afd84ab5aeb0f06\",\"75aa568fb7f484609a36abdf6afd84ab5aeb0f06\"]
+ 12943360 19% 6.11MB/s 0:00:08
+ [2013-06-01 02:01:23 BST] TransferWatcher: transfer starting: Upload UUID \"e393d45e-c8b7-11e2-a1f9-f7c95b1b45ae\" /Volumes/StoragePool/Projects/init/sync.mov Just 12943360
+ [2013-06-01 02:01:23 BST] TransferWatcher: transfer starting: Upload UUID \"e393d45e-c8b7-11e2-a1f9-f7c95b1b45ae\" /Volumes/StoragePool/Projects/init/sync.mov Just 12943360
+ 18710528 27% 5.90MB/s 0:00:08
+ [2013-06-01 02:01:24 BST] TransferWatcher: transfer starting: Upload UUID \"e393d45e-c8b7-11e2-a1f9-f7c95b1b45ae\" /Volumes/StoragePool/Projects/init/sync.mov Just 18710528
+ [2013-06-01 02:01:24 BST] TransferWatcher: transfer starting: Upload UUID \"e393d45e-c8b7-11e2-a1f9-f7c95b1b45ae\" /Volumes/StoragePool/Projects/init/sync.mov Just 18710528
+ 24477696 36% 5.79MB/s 0:00:07
+ [2013-06-01 02:01:25 BST] TransferWatcher: transfer starting: Upload UUID \"e393d45e-c8b7-11e2-a1f9-f7c95b1b45ae\" /Volumes/StoragePool/Projects/init/sync.mov Just 24477696
+ [2013-06-01 02:01:25 BST] TransferWatcher: transfer starting: Upload UUID \"e393d45e-c8b7-11e2-a1f9-f7c95b1b45ae\" /Volumes/StoragePool/Projects/init/sync.mov Just 24477696
+ 30375936 44% 5.39MB/s 0:00:06
+ [2013-06-01 02:01:26 BST] TransferWatcher: transfer starting: Upload UUID \"e393d45e-c8b7-11e2-a1f9-f7c95b1b45ae\" /Volumes/StoragePool/Projects/init/sync.mov Just 30375936
+ [2013-06-01 02:01:26 BST] TransferWatcher: transfer starting: Upload UUID \"e393d45e-c8b7-11e2-a1f9-f7c95b1b45ae\" /Volumes/StoragePool/Projects/init/sync.mov Just 30375936
+ 36143104 53% 5.49MB/s 0:00:05
+ [2013-06-01 02:01:27 BST] TransferWatcher: transfer starting: Upload UUID \"e393d45e-c8b7-11e2-a1f9-f7c95b1b45ae\" /Volumes/StoragePool/Projects/init/sync.mov Just 36143104
+ [2013-06-01 02:01:27 BST] TransferWatcher: transfer starting: Upload UUID \"e393d45e-c8b7-11e2-a1f9-f7c95b1b45ae\" /Volumes/StoragePool/Projects/init/sync.mov Just 36143104
+ 42008576 61% 5.51MB/s 0:00:04
+ [2013-06-01 02:01:28 BST] TransferWatcher: transfer starting: Upload UUID \"e393d45e-c8b7-11e2-a1f9-f7c95b1b45ae\" /Volumes/StoragePool/Projects/init/sync.mov Just 42008576
+ [2013-06-01 02:01:28 BST] TransferWatcher: transfer starting: Upload UUID \"e393d45e-c8b7-11e2-a1f9-f7c95b1b45ae\" /Volumes/StoragePool/Projects/init/sync.mov Just 42008576
+ 47906816 70% 5.52MB/s 0:00:03
+ [2013-06-01 02:01:29 BST] TransferWatcher: transfer starting: Upload UUID \"e393d45e-c8b7-11e2-a1f9-f7c95b1b45ae\" /Volumes/StoragePool/Projects/init/sync.mov Just 47906816
+ [2013-06-01 02:01:29 BST] TransferWatcher: transfer starting: Upload UUID \"e393d45e-c8b7-11e2-a1f9-f7c95b1b45ae\" /Volumes/StoragePool/Projects/init/sync.mov Just 47906816
+ 53805056 79% 5.51MB/s 0:00:02
+ [2013-06-01 02:01:30 BST] TransferWatcher: transfer starting: Upload UUID \"e393d45e-c8b7-11e2-a1f9-f7c95b1b45ae\" /Volumes/StoragePool/Projects/init/sync.mov Just 53805056
+ 59572224 87% 5.52MB/s 0:00:01
+ [2013-06-01 02:01:31 BST] TransferWatcher: transfer starting: Upload UUID \"e393d45e-c8b7-11e2-a1f9-f7c95b1b45ae\" /Volumes/StoragePool/Projects/init/sync.mov Just 59572224
+ 65339392 96% 5.50MB/s 0:00:00
+ [2013-06-01 02:01:32 BST] TransferWatcher: transfer starting: Upload UUID \"e393d45e-c8b7-11e2-a1f9-f7c95b1b45ae\" /Volumes/StoragePool/Projects/init/sync.mov Just 65339392
+ 67924272 100% 5.61MB/s 0:00:11 (xfer#1, to-check=0/1)
+ [2013-06-01 02:01:33 BST] TransferWatcher: transfer starting: Upload UUID \"e393d45e-c8b7-11e2-a1f9-f7c95b1b45ae\" /Volumes/StoragePool/Projects/init/sync.mov Just 67924272
+
+ sent 67932633 bytes received 31 bytes 5032049.19 bytes/sec
+ total size is 67924272 speedup is 1.00
+ [2013-06-01 02:01:33 BST] Transferrer: Uploaded sync.mov
+ [2013-06-01 02:01:33 BST] Pusher: Syncing with Cloud
+ [2013-06-01 02:01:33 BST] chat: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"hash-object\",\"-w\",\"--stdin-paths\"]
+ [2013-06-01 02:01:33 BST] feed: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"update-index\",\"-z\",\"--index-info\"]
+ [2013-06-01 02:01:33 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+ [2013-06-01 02:01:33 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"write-tree\"]
+ [2013-06-01 02:01:33 BST] chat: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"commit-tree\",\"45ae1694ed9a7f54bab38405fa963859fd1c1918\",\"-p\",\"refs/heads/git-annex\"]
+ [2013-06-01 02:01:33 BST] call: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"update-ref\",\"refs/heads/git-annex\",\"c22f52548a6fa05418d655906d8f182fb2d1bced\"]
+ [2013-06-01 02:01:33 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"symbolic-ref\",\"HEAD\"]
+ [2013-06-01 02:01:33 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"show-ref\",\"refs/heads/master\"]
+ [2013-06-01 02:01:33 BST] Pusher: pushing to [Remote { name =\"Cloud\" }]
+ [2013-06-01 02:01:33 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"show-ref\",\"git-annex\"]
+ [2013-06-01 02:01:33 BST] call: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"branch\",\"-f\",\"synced/master\"]
+ [2013-06-01 02:01:33 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+ [2013-06-01 02:01:33 BST] call: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"push\",\"Cloud\",\"git-annex:synced/git-annex\",\"master:synced/master\"]
+ [2013-06-01 02:01:33 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"log\",\"refs/heads/git-annex..c22f52548a6fa05418d655906d8f182fb2d1bced\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:33 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"log\",\"refs/heads/git-annex..8c35b10f8f42367fddc5c12fe39b30014358cd4d\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:33 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"log\",\"refs/heads/git-annex..ef8dc3b251fbf6baa8149ed077703b2363b3dbc9\",\"--oneline\",\"-n1\"]
+ To ssh://darren@cloud.rhymeorange.com:21/tank/git-annex/projects/
+ ef8dc3b2..c22f525 git-annex -> synced/git-annex
+ [2013-06-01 02:01:34 BST] XMPPClient: sending: NotifyPush [UUID \"e393d45e-c8b7-11e2-a1f9-f7c95b1b45ae\"]
+ [2013-06-01 02:01:34 BST] TransferWatcher: transfer finishing: Transfer {transferDirection = Upload, transferUUID = UUID \"e393d45e-c8b7-11e2-a1f9-f7c95b1b45ae\", transferKey = Key {keyName = \"48acd7e4d52f823c679d5adc2a1f52d18a8d1e05faecd779ec362d2f50c521dd.mov\", keyBackendName = \"SHA256E\", keySize = Just 67924272, keyMtime = Nothing}}
+ [2013-06-01 02:01:34 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"show-ref\",\"git-annex\"]
+ [2013-06-01 02:01:34 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+ [2013-06-01 02:01:34 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"log\",\"refs/heads/git-annex..c22f52548a6fa05418d655906d8f182fb2d1bced\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:34 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"log\",\"refs/heads/git-annex..8c35b10f8f42367fddc5c12fe39b30014358cd4d\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:56 BST] read: git [\"--git-dir=/Volumes/StoragePool/Projects/init/.git\",\"--work-tree=/Volumes/StoragePool/Projects/init\",\"ls-tree\",\"-z\",\"--\",\"refs/heads/git-annex\",\"uuid.log\",\"remote.log\",\"trust.log\",\"group.log\",\"preferred-content.log\"]
+
+
+
+
+
+
+
+
+
+
+====
+Receiving Repo (recognises sync.mov but does not download)
+====
+
+
+ [2013-06-01 02:00:04 BST] main: starting assistant version 4.20130530-g8100cad
+
+ [2013-06-01 02:00:04 BST] TransferScanner: Syncing with Cloud
+ Already up-to-date.
+
+ (scanning...) [2013-06-01 02:00:04 BST] Watcher: Performing startup scan
+ Already up-to-date.
+ Already up-to-date.
+ Already up-to-date.
+ Already up-to-date.
+ [2013-06-01 02:00:05 BST] Committer: Committing changes to git
+ Already up-to-date.
+ Already up-to-date.
+ To ssh://darren@cloud.rhymeorange.com:21/tank/git-annex/projects/
+ da9a4d5..4142ae6 git-annex -> synced/git-annex
+
+
+
+
+
+ (Recording state in git...)
+
+ (started...) [2013-06-01 02:00:06 BST] Pusher: Syncing with Cloud
+ Everything up-to-date
+ [2013-06-01 02:00:07 BST] Committer: Committing changes to git
+ [2013-06-01 02:00:08 BST] Pusher: Syncing with Cloud
+ Everything up-to-date
+ [2013-06-01 02:01:04 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"ls-tree\",\"-z\",\"--\",\"refs/heads/git-annex\",\"uuid.log\",\"remote.log\",\"trust.log\",\"group.log\",\"preferred-content.log\"]
+ [2013-06-01 02:01:21 BST] XMPPClient: received: [\"Presence from d15/BB5939E1 Just (Element {elementName = Name {nameLocalName = \\"git-annex\\", nameNamespace = Just \\"git-annex\\", namePrefix = Nothing}, elementAttributes = [(Name {nameLocalName = \\"push\\", nameNamespace = Nothing, namePrefix = Nothing},[ContentText \\"e393d45e-c8b7-11e2-a1f9-f7c95b1b45ae\\"])], elementNodes = []})\",\"NotifyPush [UUID \\"e393d45e-c8b7-11e2-a1f9-f7c95b1b45ae\\"]\"]
+ [2013-06-01 02:01:21 BST] XMPPClient: push notification for e393d45e-c8b7-11e2-a1f9-f7c95b1b45ae
+ [2013-06-01 02:01:21 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"symbolic-ref\",\"HEAD\"]
+ [2013-06-01 02:01:21 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"show-ref\",\"refs/heads/master\"]
+ [2013-06-01 02:01:21 BST] call: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"fetch\",\"Cloud\"]
+ From ssh://cloud.rhymeorange.com:21/tank/git-annex/projects
+ 4142ae6..ef8dc3b2 synced/git-annex -> Cloud/synced/git-annex
+ 1723064..75aa568 synced/master -> Cloud/synced/master
+ [2013-06-01 02:01:22 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"show-ref\",\"git-annex\"]
+ [2013-06-01 02:01:22 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+ [2013-06-01 02:01:22 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"log\",\"refs/heads/git-annex..4142ae6e3befdff987748a92feb65a11aecf4b63\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:22 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"log\",\"refs/heads/git-annex..8c35b10f8f42367fddc5c12fe39b30014358cd4d\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:22 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"log\",\"refs/heads/git-annex..ef8dc3b251fbf6baa8149ed077703b2363b3dbc9\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:22 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"log\",\"refs/heads/git-annex..3ddff95f0fdc37a75e0124ba5f965606b2f81bea\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:22 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"log\",\"refs/heads/git-annex..5e6dd0a555a5f67879e66ca1d83fe1312e87a0e1\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:22 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"log\",\"refs/heads/git-annex..8a0e3fb46d23acdfe9a30e6e85823b37bfae182c\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:22 BST] feed: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"update-index\",\"-z\",\"--index-info\"]
+ [2013-06-01 02:01:22 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"diff-index\",\"--raw\",\"-z\",\"-r\",\"--no-renames\",\"-l0\",\"--cached\",\"ef8dc3b251fbf6baa8149ed077703b2363b3dbc9\"]
+ [2013-06-01 02:01:22 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"log\",\"ef8dc3b251fbf6baa8149ed077703b2363b3dbc9..refs/heads/git-annex\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:22 BST] call: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"update-ref\",\"refs/heads/git-annex\",\"ef8dc3b251fbf6baa8149ed077703b2363b3dbc9\"]
+ [2013-06-01 02:01:22 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"show-ref\",\"git-annex\"]
+ [2013-06-01 02:01:22 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+ [2013-06-01 02:01:22 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"log\",\"refs/heads/git-annex..ef8dc3b251fbf6baa8149ed077703b2363b3dbc9\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:22 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"log\",\"refs/heads/git-annex..8c35b10f8f42367fddc5c12fe39b30014358cd4d\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:22 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"log\",\"refs/heads/git-annex..3ddff95f0fdc37a75e0124ba5f965606b2f81bea\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:22 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"log\",\"refs/heads/git-annex..5e6dd0a555a5f67879e66ca1d83fe1312e87a0e1\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:23 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"log\",\"refs/heads/git-annex..8a0e3fb46d23acdfe9a30e6e85823b37bfae182c\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:23 BST] feed: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"update-index\",\"-z\",\"--index-info\"]
+ [2013-06-01 02:01:23 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"diff-index\",\"--raw\",\"-z\",\"-r\",\"--no-renames\",\"-l0\",\"--cached\",\"refs/heads/git-annex\"]
+ [2013-06-01 02:01:23 BST] call: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"show-ref\",\"--verify\",\"-q\",\"refs/remotes/Cloud/master\"]
+ [2013-06-01 02:01:23 BST] call: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"show-ref\",\"--verify\",\"-q\",\"refs/remotes/Cloud/synced/master\"]
+ [2013-06-01 02:01:23 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"log\",\"refs/heads/synced/master..refs/remotes/Cloud/synced/master\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:23 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"symbolic-ref\",\"HEAD\"]
+ [2013-06-01 02:01:23 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"show-ref\",\"refs/heads/master\"]
+ [2013-06-01 02:01:23 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"show-ref\",\"--hash\",\"refs/heads/master\"]
+ [2013-06-01 02:01:23 BST] call: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects/.git/annex/merge/\",\"merge\",\"--no-edit\",\"refs/remotes/Cloud/synced/master\"]
+ Updating 1723064..75aa568
+ Fast-forward
+ sync.mov | 1 +
+ 1 file changed, 1 insertion(+)
+ create mode 120000 sync.mov
+ [2013-06-01 02:01:23 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"show-ref\",\"--hash\",\"refs/heads/master\"]
+ [2013-06-01 02:01:23 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"diff-tree\",\"-z\",\"--raw\",\"--no-renames\",\"-l0\",\"-r\",\"172306459777930560a2cbbfd5c39ad596d93a0e\",\"75aa568fb7f484609a36abdf6afd84ab5aeb0f06\"]
+ [2013-06-01 02:01:23 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"symbolic-ref\",\"HEAD\"]
+ [2013-06-01 02:01:23 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"show-ref\",\"refs/heads/master\"]
+ [2013-06-01 02:01:23 BST] Merger: merging refs/remotes/Cloud/synced/master into refs/heads/master
+ [2013-06-01 02:01:23 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"symbolic-ref\",\"HEAD\"]
+ [2013-06-01 02:01:23 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"show-ref\",\"refs/heads/master\"]
+ [2013-06-01 02:01:23 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"show-ref\",\"--hash\",\"refs/heads/master\"]
+ [2013-06-01 02:01:23 BST] call: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects/.git/annex/merge/\",\"merge\",\"--no-edit\",\"refs/remotes/Cloud/synced/master\"]
+ Already up-to-date.
+ [2013-06-01 02:01:23 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"show-ref\",\"--hash\",\"refs/heads/master\"]
+ [2013-06-01 02:01:23 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"diff-tree\",\"-z\",\"--raw\",\"--no-renames\",\"-l0\",\"-r\",\"75aa568fb7f484609a36abdf6afd84ab5aeb0f06\",\"75aa568fb7f484609a36abdf6afd84ab5aeb0f06\"]
+ [2013-06-01 02:01:23 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"show-ref\",\"git-annex\"]
+ [2013-06-01 02:01:23 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+ [2013-06-01 02:01:23 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"log\",\"refs/heads/git-annex..ef8dc3b251fbf6baa8149ed077703b2363b3dbc9\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:23 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"log\",\"refs/heads/git-annex..8c35b10f8f42367fddc5c12fe39b30014358cd4d\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:23 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"log\",\"refs/heads/git-annex..3ddff95f0fdc37a75e0124ba5f965606b2f81bea\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:23 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"log\",\"refs/heads/git-annex..5e6dd0a555a5f67879e66ca1d83fe1312e87a0e1\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:23 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"log\",\"refs/heads/git-annex..8a0e3fb46d23acdfe9a30e6e85823b37bfae182c\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:34 BST] XMPPClient: received: [\"Presence from d15/BB5939E1 Just (Element {elementName = Name {nameLocalName = \\"git-annex\\", nameNamespace = Just \\"git-annex\\", namePrefix = Nothing}, elementAttributes = [(Name {nameLocalName = \\"push\\", nameNamespace = Nothing, namePrefix = Nothing},[ContentText \\"e393d45e-c8b7-11e2-a1f9-f7c95b1b45ae\\"])], elementNodes = []})\",\"NotifyPush [UUID \\"e393d45e-c8b7-11e2-a1f9-f7c95b1b45ae\\"]\"]
+ [2013-06-01 02:01:34 BST] XMPPClient: push notification for e393d45e-c8b7-11e2-a1f9-f7c95b1b45ae
+ [2013-06-01 02:01:34 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"symbolic-ref\",\"HEAD\"]
+ [2013-06-01 02:01:34 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"show-ref\",\"refs/heads/master\"]
+ [2013-06-01 02:01:34 BST] call: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"fetch\",\"Cloud\"]
+ From ssh://cloud.rhymeorange.com:21/tank/git-annex/projects
+ ef8dc3b2..c22f525 synced/git-annex -> Cloud/synced/git-annex
+ [2013-06-01 02:01:34 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"show-ref\",\"git-annex\"]
+ [2013-06-01 02:01:34 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+ [2013-06-01 02:01:34 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"log\",\"refs/heads/git-annex..ef8dc3b251fbf6baa8149ed077703b2363b3dbc9\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:34 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"log\",\"refs/heads/git-annex..8c35b10f8f42367fddc5c12fe39b30014358cd4d\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:34 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"log\",\"refs/heads/git-annex..c22f52548a6fa05418d655906d8f182fb2d1bced\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:34 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"log\",\"refs/heads/git-annex..3ddff95f0fdc37a75e0124ba5f965606b2f81bea\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:34 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"log\",\"refs/heads/git-annex..5e6dd0a555a5f67879e66ca1d83fe1312e87a0e1\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:34 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"log\",\"refs/heads/git-annex..8a0e3fb46d23acdfe9a30e6e85823b37bfae182c\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:34 BST] feed: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"update-index\",\"-z\",\"--index-info\"]
+ [2013-06-01 02:01:34 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"diff-index\",\"--raw\",\"-z\",\"-r\",\"--no-renames\",\"-l0\",\"--cached\",\"c22f52548a6fa05418d655906d8f182fb2d1bced\"]
+ [2013-06-01 02:01:34 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"log\",\"c22f52548a6fa05418d655906d8f182fb2d1bced..refs/heads/git-annex\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:34 BST] call: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"update-ref\",\"refs/heads/git-annex\",\"c22f52548a6fa05418d655906d8f182fb2d1bced\"]
+ [2013-06-01 02:01:34 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"show-ref\",\"git-annex\"]
+ [2013-06-01 02:01:34 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+ [2013-06-01 02:01:34 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"log\",\"refs/heads/git-annex..c22f52548a6fa05418d655906d8f182fb2d1bced\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:34 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"log\",\"refs/heads/git-annex..8c35b10f8f42367fddc5c12fe39b30014358cd4d\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:34 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"log\",\"refs/heads/git-annex..3ddff95f0fdc37a75e0124ba5f965606b2f81bea\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:34 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"log\",\"refs/heads/git-annex..5e6dd0a555a5f67879e66ca1d83fe1312e87a0e1\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:35 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"log\",\"refs/heads/git-annex..8a0e3fb46d23acdfe9a30e6e85823b37bfae182c\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:35 BST] feed: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"update-index\",\"-z\",\"--index-info\"]
+ [2013-06-01 02:01:35 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"diff-index\",\"--raw\",\"-z\",\"-r\",\"--no-renames\",\"-l0\",\"--cached\",\"refs/heads/git-annex\"]
+ [2013-06-01 02:01:35 BST] call: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"show-ref\",\"--verify\",\"-q\",\"refs/remotes/Cloud/master\"]
+ [2013-06-01 02:01:35 BST] call: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"show-ref\",\"--verify\",\"-q\",\"refs/remotes/Cloud/synced/master\"]
+ [2013-06-01 02:01:35 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"log\",\"refs/heads/synced/master..refs/remotes/Cloud/synced/master\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:35 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"symbolic-ref\",\"HEAD\"]
+ [2013-06-01 02:01:35 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"show-ref\",\"refs/heads/master\"]
+ [2013-06-01 02:01:35 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"show-ref\",\"--hash\",\"refs/heads/master\"]
+ [2013-06-01 02:01:35 BST] call: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects/.git/annex/merge/\",\"merge\",\"--no-edit\",\"refs/remotes/Cloud/synced/master\"]
+ Already up-to-date.
+ [2013-06-01 02:01:35 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"show-ref\",\"--hash\",\"refs/heads/master\"]
+ [2013-06-01 02:01:35 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"diff-tree\",\"-z\",\"--raw\",\"--no-renames\",\"-l0\",\"-r\",\"75aa568fb7f484609a36abdf6afd84ab5aeb0f06\",\"75aa568fb7f484609a36abdf6afd84ab5aeb0f06\"]
+ [2013-06-01 02:01:35 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"show-ref\",\"git-annex\"]
+ [2013-06-01 02:01:35 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+ [2013-06-01 02:01:35 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"log\",\"refs/heads/git-annex..c22f52548a6fa05418d655906d8f182fb2d1bced\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:35 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"log\",\"refs/heads/git-annex..8c35b10f8f42367fddc5c12fe39b30014358cd4d\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:35 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"log\",\"refs/heads/git-annex..3ddff95f0fdc37a75e0124ba5f965606b2f81bea\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:35 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"log\",\"refs/heads/git-annex..5e6dd0a555a5f67879e66ca1d83fe1312e87a0e1\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:01:35 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"log\",\"refs/heads/git-annex..8a0e3fb46d23acdfe9a30e6e85823b37bfae182c\",\"--oneline\",\"-n1\"]
+ [2013-06-01 02:02:04 BST] read: git [\"--git-dir=/Users/darren/Projects/.git\",\"--work-tree=/Users/darren/Projects\",\"ls-tree\",\"-z\",\"--\",\"refs/heads/git-annex\",\"uuid.log\",\"remote.log\",\"trust.log\",\"group.log\",\"preferred-content.log\"]
+ [2013-06-01 02:02:05 BST] XMPPClient: received: [\"Unknown message\"]
+"""]]
diff --git a/doc/bugs/restart_daemon_required/comment_4_3ce776786eca83fcb8ff94c8f6ff3eb9._comment b/doc/bugs/restart_daemon_required/comment_4_3ce776786eca83fcb8ff94c8f6ff3eb9._comment
new file mode 100644
index 000000000..1163fcbcf
--- /dev/null
+++ b/doc/bugs/restart_daemon_required/comment_4_3ce776786eca83fcb8ff94c8f6ff3eb9._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 4"
+ date="2013-06-10T21:31:04Z"
+ content="""
+Darren, I'm sorry about the delay getting back to you -- I've been on vacation.
+
+> XMPPClient: received: [\"Unknown message\"]
+
+This and the versions tell me what the problem is. Version 4.20130601 made a backwards-incompatable change in its XMPP protocol.
+You need to upgrade the one that's using 4.20130522, and that'll solve that. The current build for Lion is 4.20130601, which will do. (The Lion autobuild is also building again for some time.)
+
+I forgot to mention this protocol change in the release notes, it was only in the changelog. Am doing that now.
+"""]]
diff --git a/doc/bugs/rsync_remote_shows_no_progress.mdwn b/doc/bugs/rsync_remote_shows_no_progress.mdwn
new file mode 100644
index 000000000..0192291f2
--- /dev/null
+++ b/doc/bugs/rsync_remote_shows_no_progress.mdwn
@@ -0,0 +1,15 @@
+What steps will reproduce the problem?
+Init a annex, add rsync remote (with or without encryption, does not matter), launch annex assistant
+
+What is the expected output? What do you see instead?
+In the dashboard, no progress is recorded for the transfer. Each file stays at 0% and then disappears as it is fully transfered. I expect the progressbar to move and show the actual transfer progress.
+
+What version of git-annex are you using? On what operating system?
+git head of today, Ubuntu 12.04
+
+Please provide any additional information below.
+I looked in the source code and found some hints that the rsync progress should actually be evaluated and shown, I'm opening a bug report for this reason.
+
+[[!meta title="assistant: No progress bars for file uploads"]]
+
+> now upload progress bars work! [[done]] --[[Joey]]
diff --git a/doc/bugs/rsync_remote_shows_no_progress/comment_1_a7f5d646a924c462b987561cf6fc4318._comment b/doc/bugs/rsync_remote_shows_no_progress/comment_1_a7f5d646a924c462b987561cf6fc4318._comment
new file mode 100644
index 000000000..09afec65a
--- /dev/null
+++ b/doc/bugs/rsync_remote_shows_no_progress/comment_1_a7f5d646a924c462b987561cf6fc4318._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.30"
+ subject="comment 1"
+ date="2012-09-09T20:01:53Z"
+ content="""
+Yes, progress bars for uploads are not implemented yet. See [[design/assistant/progressbars]]
+"""]]
diff --git a/doc/bugs/rsync_special_remote_fails_to___96__get__96___files_which_have_names_containing_spaces.mdwn b/doc/bugs/rsync_special_remote_fails_to___96__get__96___files_which_have_names_containing_spaces.mdwn
new file mode 100644
index 000000000..040d86bb8
--- /dev/null
+++ b/doc/bugs/rsync_special_remote_fails_to___96__get__96___files_which_have_names_containing_spaces.mdwn
@@ -0,0 +1,50 @@
+ ~$ mkdir test annex
+ ~$ cd test
+ ~$ git init
+ Initialized empty Git repository in /home/user/test/.git/
+ ~$ git annex init test
+ init test ok
+ ~$ git annex initremote localrsync encryption=none type=rsync rsyncurl=localhost:annex/
+ initremote localrsync ok
+ ~$ cp /home/user/Music/Charming\ Hostess/Eat/03\ Mi\ Nuera.ogg ./
+ ~$ git annex add 03\ Mi\ Nuera.ogg
+ add 03 Mi Nuera.ogg ok
+ (Recording state in git...)
+ ~$ git commit -m "add ogg"
+ fatal: No HEAD commit to compare with (yet)
+ fatal: No HEAD commit to compare with (yet)
+ [master (root-commit) 12608af] add ogg
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+ create mode 120000 03 Mi Nuera.ogg
+ ~$ git annex move 03\ Mi\ Nuera.ogg --to localrsync
+ move 03 Mi Nuera.ogg (checking localrsync...) (to localrsync...)
+ sending incremental file list
+ 1X/
+ 1X/39/
+ 1X/39/WORM-s6296772-m1311874383--03 Mi Nuera.ogg/
+ 1X/39/WORM-s6296772-m1311874383--03 Mi Nuera.ogg/WORM-s6296772-m1311874383--03 Mi Nuera.ogg
+ 6296772 100% 42.98MB/s 0:00:00 (xfer#1, to-check=0/5)
+
+ sent 6297754 bytes received 43 bytes 4198531.33 bytes/sec
+ total size is 6296772 speedup is 1.00
+ ok
+ ~$ git annex get 03\ Mi\ Nuera.ogg
+ get 03 Mi Nuera.ogg (from localrsync...)
+ rsync: link_stat "/home/user/annex/1X/39/WORM-s6296772-m1311874383--03" failed: No such file or directory (2)
+ rsync: link_stat "/home/user/Mi" failed: No such file or directory (2)
+ rsync: change_dir "/home/user/Nuera.ogg" failed: No such file or directory (2)
+ rsync: link_stat "/home/user/Mi" failed: No such file or directory (2)
+ rsync: link_stat "/home/user/Nuera.ogg" failed: No such file or directory (2)
+
+ sent 8 bytes received 12 bytes 13.33 bytes/sec
+ total size is 0 speedup is 0.00
+ rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1526) [Receiver=3.0.7]
+
+ rsync failed -- run git annex again to resume file transfer
+ Unable to access these remotes: localrsync
+ Try making some of these repositories available:
+ b8b1ea7a-b93f-11e0-b712-d7bffb6e61e6 -- localrsync
+ failed
+ git-annex: 1 failed
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/scp_interrupt_to_background.mdwn b/doc/bugs/scp_interrupt_to_background.mdwn
new file mode 100644
index 000000000..381f5cd73
--- /dev/null
+++ b/doc/bugs/scp_interrupt_to_background.mdwn
@@ -0,0 +1,2 @@
+When getting a file with scp, SIGINT is blocked, exposing the git
+subcommand fork to background bug again. [[done]]
diff --git a/doc/bugs/show_version_without_having_to_be_in_a_git_repo.mdwn b/doc/bugs/show_version_without_having_to_be_in_a_git_repo.mdwn
new file mode 100644
index 000000000..98b9ced22
--- /dev/null
+++ b/doc/bugs/show_version_without_having_to_be_in_a_git_repo.mdwn
@@ -0,0 +1,11 @@
+It'd be nice to be able to run "git annex version" -- and maybe some other
+commands, like "git annex" itself for the help text, without having to be
+inside a git repo. Right now it requires you to be in a git repo even if
+it's not a git-annex repo.
+
+> You need a newer verison of git-annex. --[[Joey]]
+
+ joey@gnu:/>git annex version
+ git-annex version: 3.20120124
+
+[[done]]
diff --git a/doc/bugs/signal_weirdness.mdwn b/doc/bugs/signal_weirdness.mdwn
new file mode 100644
index 000000000..1942a924a
--- /dev/null
+++ b/doc/bugs/signal_weirdness.mdwn
@@ -0,0 +1,48 @@
+For the record, there is a slight weirdness with how git-annex
+handles a signal like ctrl-c.
+
+For example:
+
+ joey@gnu:~/tmp/b>git annex copy a b --to origin
+ copy a (checking origin...) (to origin...)
+ SHA256-s104857600--20492a4d0d84f8beb1767f6616229f85d44c2827b64bdbfb260ee12fa1109e0e
+ 3272 0% 0.00kB/s 0:00:00 ^C
+ zsh: interrupt git annex copy a --to origin
+ joey@gnu:~/tmp/b>
+ rsync error: unexplained error (code 130) at rsync.c(549) [sender=3.0.9]
+
+Here git-annex exits before rsync has fully exited. Not a large problem
+but sorta weird.
+
+The culprit is `CmdLine.startup` in Utility.SafeCommand, which installs
+a default signal handler for SIGINT, which causes it to immediatly
+terminate git-annex. rsync, in turn, has its own SIGINT handler, which
+prints the message, typically later.
+
+(Why it prints that message and not its more usual message about having
+received a signal, I'm not sure?)
+
+It's more usual for a `system` like thing to block SIGINT, letting the child
+catch it and exit, and then detecting the child's exit status and terminating.
+However, since rsync *is* trapping SIGINT, and exiting nonzero explicitly,
+git-annex can't tell that rsync failed due to a SIGINT by examining the
+`waitpid` result.
+And, git-annex typically doesn't stop when a single child fails. In the
+example above, it would go on to copy `b` after a ctrl-c!
+
+A further complication is that git-annex is itself a child process
+of git, which does not block SIGINT either. So if git-annex blocks SIGINT,
+it will be left running in the background after git exits, and continuing
+with further actions too. (Perhaps its SIGINT handling is a bug in git.)
+
+Now, rsync does have a documented exit code it uses after a SIGINT.
+But other programs git-annex runs generally do not. So it would be possible
+to special case in support for rsync, blocking SIGINT while running it,
+noticing it exited with 20, and git-annex then stopping. But this is
+ugly and failure prone if rsync's code 20 changes. And it only
+would fix the rsync case, not helping with other commands like wget, unless
+it assumes they never trap SIGINT on their own.
+
+Which is why the current behavior of not blocking SIGINT was chosen,
+as a less bad alternative. Still, I'd like to find a better one.
+--[[Joey]]
diff --git a/doc/bugs/size_of_the_Android_installation_is_HUGE_--_please_seek_possibility_to_shrink.mdwn b/doc/bugs/size_of_the_Android_installation_is_HUGE_--_please_seek_possibility_to_shrink.mdwn
new file mode 100644
index 000000000..3f8c7fc48
--- /dev/null
+++ b/doc/bugs/size_of_the_Android_installation_is_HUGE_--_please_seek_possibility_to_shrink.mdwn
@@ -0,0 +1,41 @@
+### Please describe the problem.
+
+ATM git annex assistant app is the largest one installed on my phone. I simply keep hitting the available storage space limits and keep pruning some apps
+
+According to file
+$> file lib/armeabi/lib.git-annex.so
+lib/armeabi/lib.git-annex.so: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), not stripped
+so largest annex's .so is 133M and is not stripped. stripping it seems to half its size:
+
+$> ls -l lib.git-annex.so
+62052 -rw------- 1 yoh yoh 63468304 Nov 25 22:21 lib.git-annex.so
+$> file lib.git-annex.so
+lib.git-annex.so: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), stripped
+
+so may be it could be the first step to make the .apk and installation itself more lightweight and thus easier to "manage"
+
+thanks in advance
+
+### What steps will reproduce the problem?
+
+install provided .apk on Android
+
+### What version of git-annex are you using? On what operating system?
+
+Android, just fetched the most recent "release" apk from the
+http://downloads.kitenet.net/git-annex/android/current/4.0/git-annex.apk
+Last-Modified: Mon, 18 Nov 2013 11:57:25 GMT
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
+
+> Seems that I lost stripping of the git-annex binary when adding the build
+> for the newer android versions. [[fixed|done]] (There is not otherwise
+> much way to shrink the size.) --[[Joey]]
diff --git a/doc/bugs/size_of_the_Android_installation_is_HUGE_--_please_seek_possibility_to_shrink/comment_1_d2faaff98386433110dcf7aae87916b7._comment b/doc/bugs/size_of_the_Android_installation_is_HUGE_--_please_seek_possibility_to_shrink/comment_1_d2faaff98386433110dcf7aae87916b7._comment
new file mode 100644
index 000000000..894c48784
--- /dev/null
+++ b/doc/bugs/size_of_the_Android_installation_is_HUGE_--_please_seek_possibility_to_shrink/comment_1_d2faaff98386433110dcf7aae87916b7._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://yarikoptic.myopenid.com/"
+ nickname="site-myopenid"
+ subject="sure there is no other ways to shrink?"
+ date="2013-11-27T04:26:35Z"
+ content="""
+Might be quite a stretch but it is hard to grasp that all 60MB are really needed... although with haskell -- it might indeed be the case, but I thought that may be there could be some symbols pulled in which aren't used, and for which when in gcc/ld world there are ways to get rid of them, e.g. -dead_strip (just excercising ideas)
+
+"""]]
diff --git a/doc/bugs/size_of_the_Android_installation_is_HUGE_--_please_seek_possibility_to_shrink/comment_2_1359ddf1b5db4303f8bd219d3f07df3a._comment b/doc/bugs/size_of_the_Android_installation_is_HUGE_--_please_seek_possibility_to_shrink/comment_2_1359ddf1b5db4303f8bd219d3f07df3a._comment
new file mode 100644
index 000000000..5f7688d1f
--- /dev/null
+++ b/doc/bugs/size_of_the_Android_installation_is_HUGE_--_please_seek_possibility_to_shrink/comment_2_1359ddf1b5db4303f8bd219d3f07df3a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.64"
+ subject="comment 2"
+ date="2013-11-27T04:55:51Z"
+ content="""
+The git-annex binary is around 45 mb on Linux. The android binary statically links a few additional C libraries, so is slightly larger.
+
+The only way I know of to potentially shrink it is to fix certian ghc / ld interactions that, in my limited understanding, cause functions that are never used to be linked into the binary if another function in the same file (or module) is used. That might half its size or something.
+"""]]
diff --git a/doc/bugs/smarter_flood_filling.mdwn b/doc/bugs/smarter_flood_filling.mdwn
new file mode 100644
index 000000000..47b6942c7
--- /dev/null
+++ b/doc/bugs/smarter_flood_filling.mdwn
@@ -0,0 +1,31 @@
+The assistant performs a flood fill, sending every file to every remote
+that will have it. This is naive, but it's a good way to ensure the file
+gets to every corner of the repo network that it possibly can.
+
+However, this means that locally paired computers will still upload files
+to a transfer repo, even when they're next to each other and that
+is a massive waste of bandwidth.
+
+It occurred to me this morning that there is a simple change that can avoid
+this.
+
+1. Ensure that locally paired computers have a lower cost than network
+ transfer remotes. (done)
+2. When queuing uploads, queue transfers to the lowest cost remotes first.
+ (already done)
+3. Just before starting a transfer, re-check if the transfer is still wanted.
+ (done)
+
+> [[done]]
+
+Now, unnecessary transfers to tranfer repos are avoided if it can send
+the file locally instead.
+
+It doesn't solve it for all network topologies of course. If there
+are three computers paired in a line "A --- B --- C", and all 3 share
+a transfer repo, A will still send to both B and the transfer repo
+even though B can reach C via a faster route.
+
+See also: [[assistant does not always use repo cost info when queueing downloads]]
+
+[[!tag /design/assistant]]
diff --git a/doc/bugs/softlink_mtime.mdwn b/doc/bugs/softlink_mtime.mdwn
new file mode 100644
index 000000000..1427fc714
--- /dev/null
+++ b/doc/bugs/softlink_mtime.mdwn
@@ -0,0 +1,54 @@
+When adding files to git annex, softlinks are created with current atime (and ctime, etc). Instead, the atime of the added file should be used and added to the meta-data, restoring it everywhere an annex is cloned to. -- RichiH
+
+Optionally, editing the meta-data should change the times in all annexes.
+
+> Thing is, git does not preserve file timestamps much at all.
+> It's not uncommon for a `git checkout` to or `git update` to
+> mess up timestamps. This is why things like metastore exist (and
+> metastore should work ok with git annexed files too). Trying to
+> make annexed file symlinks have better timestamp handling than regular
+> files in git seems pointless. --[[Joey]]
+
+> > Improving an area where git is (not yet?) good at still makes sense, imo. Photos and the like need absolute timestamps more than source code which is fine with relative timestamps (local builds & updates). Maintaining global timestamps for source code could even cause a lot of unwanted effects. As it is, this issue is the only, but a major, blocker for me before I can start adapting git-annex. As I have three different use cases for it, this is a shame. Unfortunately, I don't speak any Haskell so scratching my own itch isn't do-able (without major effort and not soon, at least). Is there a realistic chance that you will tackle this nonetheless or is this WONTFIX? -- RichiH
+
+>>> Not quite WONTFIX. git-annex should at least, when adding new files,
+>>> preserve their timestamp in the symlink it creates.
+>>>
+>>> Since it doesn't have anything to do with maintaining the symlinks
+>>> during an update, or a clone, etc, maintaining the permissions of them
+>>> is also out of scope, and it's best to just use metastore if you need
+>>> it. Otherwise, git-annex would have to reimplement metastore, and is
+>>> unlikely to do it better.
+
+>>>> OK, thanks for the clarification. Would it be acceptable for you to put the timestamps into the metastore with vanilla git? If such an option existed, everyone would be able to benefit and not just me. -- RichiH
+
+>>>>> I've now committed to git changes to make git-annex add make
+>>>>> symlinks that reflect the original file's mtime. (It's not possible
+>>>>> to set the ctime of a symlink; nor would you want to as messing with
+>>>>> ctimes can break backup software ... and atime doesn't much matter.)
+>>>>>
+>>>>> So all you have to do is make the pre-commit hook call
+>>>>> [metastore](http://david.hardeman.nu/software.php). The hook
+>>>>> would look like this: ---[[Joey]]
+
+ #!/bin/sh
+ git annex pre-commit .
+ metastore --save
+ git add .metadata
+
+>>>>>> Thanks a lot. Doing this in a new git-annex repo from the start should at least ensure local consistency and I assume I can simply add a post-pull hook to restore the mtimes on all all other repositories? -- RichiH
+
+>>>>>>> This is even better:
+
+ #!/bin/sh
+ if ! type metastore >/dev/null; then echo "$0: metastore is not installed; exiting"; exit 1; fi
+ git annex pre-commit .
+ metastore --save
+ git add .metadata
+
+>>>>>>> -- RichiH
+
+>>>>>>>> After getting to actually play with this from different machines with a bare git as central instance for several distributed repos, the metastore trick does not work. The .metadata is causing merge conflicts for every pull. I removed the "done" tag from this issue. -- RichiH
+
+>>>>>>>>> softbox sounds _really_ nice. File systems need to preserve mtimes. Oviously, it would be nice if git-annex exposed this to the upper layer instead of relying on this FUSE implementation, or the next, or the other totally cool thing around the corner to implement it again and again.
+>>>>>>>>> I talked to the author of metastore; he is aware that the format is merge-unfriendly but never needed merges for himself. He is aware that this is not ideal for something like git. He does not have the time to implement a text storage instead of binary and I lack the skills to do it. If metastore is used, all it would need to do is introduce a new version of the store (it's versioned, apparently) and save metadata in text, one file per line. xattr would need to be ASCII-armoured, the rest could be plain text. I still think storing this directly in git-annex would make the most sense. Introducing a metadata storage file per storage object in .git/annex and using the object file's name as index is impossible because several softlinks might point to one object so it would need to be done per-softlink :/ -- RichiH
diff --git a/doc/bugs/ssh-keygen_failed_when_adding_remote_server_repo.mdwn b/doc/bugs/ssh-keygen_failed_when_adding_remote_server_repo.mdwn
new file mode 100644
index 000000000..3aa3188af
--- /dev/null
+++ b/doc/bugs/ssh-keygen_failed_when_adding_remote_server_repo.mdwn
@@ -0,0 +1,44 @@
+### Please describe the problem.
+
+When I try to add remote ssh server repository it fails with an error:
+
+Internal Server Error
+ssh-keygen failed"
+
+
+### What steps will reproduce the problem?
+1. Select "Add another repository", then choose "Remote server", enter credentials.
+2. On the page "Ready to add remote server" click any choice ("Use a git repository on the server" or "Use an encrypted rsync repository on the server")
+3. Error is raised
+
+### What version of git-annex are you using? On what operating system?
+git-annex version 4.20130922-g7dc188a
+
+Fedora 18 x86_64
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+[2013-10-03 19:27:27 NOVT] main: starting assistant version 4.20130922-g7dc188a
+(scanning...) [2013-10-03 19:27:27 NOVT] Watcher: Performing startup scan
+(started...)
+ssh-keygen: symbol lookup error: /lib64/libldap-2.4.so.2: undefined symbol: ber_sockbuf_io_udp
+ssh-keygen: symbol lookup error: /lib64/libldap-2.4.so.2: undefined symbol: ber_sockbuf_io_udp
+ssh-keygen: symbol lookup error: /lib64/libldap-2.4.so.2: undefined symbol: ber_sockbuf_io_udp
+ssh-keygen: symbol lookup error: /lib64/libldap-2.4.so.2: undefined symbol: ber_sockbuf_io_udp
+ssh-keygen: symbol lookup error: /lib64/libldap-2.4.so.2: undefined symbol: ber_sockbuf_io_udp
+ssh-keygen: symbol lookup error: /lib64/libldap-2.4.so.2: undefined symbol: ber_sockbuf_io_udp
+ssh-keygen: symbol lookup error: /lib64/libldap-2.4.so.2: undefined symbol: ber_sockbuf_io_udp
+ssh-keygen: symbol lookup error: /lib64/libldap-2.4.so.2: undefined symbol: ber_sockbuf_io_udp
+ssh-keygen: symbol lookup error: /lib64/libldap-2.4.so.2: undefined symbol: ber_sockbuf_io_udp
+[2013-10-03 19:55:23 NOVT] call: ssh-keygen ["-P","","-f","/tmp/git-annex-keygen.0/key"]
+ssh-keygen: symbol lookup error: /lib64/libldap-2.4.so.2: undefined symbol: ber_sockbuf_io_udp
+
+
+# End of transcript or log.
+"""]]
+
+> Added ssh-keygen to bundle. [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/ssh-keygen_failed_when_adding_remote_server_repo/comment_1_52180983b59c247389a55a9523ec435b._comment b/doc/bugs/ssh-keygen_failed_when_adding_remote_server_repo/comment_1_52180983b59c247389a55a9523ec435b._comment
new file mode 100644
index 000000000..f0f50151a
--- /dev/null
+++ b/doc/bugs/ssh-keygen_failed_when_adding_remote_server_repo/comment_1_52180983b59c247389a55a9523ec435b._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="108.236.230.124"
+ subject="comment 1"
+ date="2013-11-08T18:28:37Z"
+ content="""
+Apologies for not following up on this bug sooner..
+
+It seems to me that your system has a broken ssh-keygen program. You didn't say how you installed git-annex, but based on the git rev in the version number, I'm guessing you either built it yourself, or you're using the standalone tarball I build.
+
+In the case of the latter, it didn't include ssh-keygen, so would try to use the one that comes with fedora. It seems likely that the problem comes from the libraries included in the bundle being used with a binary not in the bundle, that in turn is also using additional libraries.
+
+So, I think I should add ssh-keygen to the standalone bundle!
+"""]]
diff --git a/doc/bugs/ssh_connection_caching_broken_on_NTFS.mdwn b/doc/bugs/ssh_connection_caching_broken_on_NTFS.mdwn
new file mode 100644
index 000000000..fc3168e0f
--- /dev/null
+++ b/doc/bugs/ssh_connection_caching_broken_on_NTFS.mdwn
@@ -0,0 +1,66 @@
+TL;DNR ssh connection caching seems to cause git-annex to not work on NTFS volumes. Setting `annex.sshcaching` to `false` seems to solve the problem.
+
+## What version of git-annex are you using? On what operating system? Please provide any additional information below.
+
+* git-annex version: 3.20120629 on Debian Testing.
+* `the-repo` is located on an NTFS volume on a USB HDD.
+* `the-remote` is on the server `example.com`.
+* `example.com` is running gitolite3 v3.2-19-gb9bbb78, git 1.7.2.5, and git-annex 3.20120629~bpo60+2
+
+
+## What steps will reproduce the problem? What is the expected output? What do you see instead?
+
+Create or clone a repo onto an NTFS volume.
+Make sure `git annex` is initialized.
+Run some regular git operations. These always seem to work.
+Try git-annex operations.
+
+Some operations work despite the error messages:
+
+ $ git annex sync
+ Control socket connect(/media/NTFSVOL/the-repo/.git/annex/ssh/git@example.com): Connection refused
+ Failed to connect to new control master
+ Command ssh ["-S","/media/NTFSVOL/the-repo/.git/annex/ssh/git@example.com","-o","ControlMaster=auto","-o","ControlPersist=yes","git@example.com","git-annex-shell 'configlist' '/~/the-repo.git'"] failed; exit code 255
+ Control socket connect(/media/NTFSVOL/the-repo/.git/annex/ssh/git@example.com): Connection refused
+ Failed to connect to new control master
+ Command ssh ["-S","/media/NTFSVOL/the-repo/.git/annex/ssh/git@example.com","-o","ControlMaster=auto","-o","ControlPersist=yes","git@example.com","git-annex-shell 'configlist' '/~/the-repo'"] failed; exit code 255
+ commit
+ # On branch master
+ nothing to commit (working directory clean)
+ ok
+ pull the-remote
+ ok
+ pull origin
+ ok
+
+Other operations fail:
+
+ $ git annex copy -t the-remote the-file.jpg
+ Control socket connect(/media/NTFSVOL/the-repo/.git/annex/ssh/git@example.com): Connection refused
+ Failed to connect to new control master
+ Command ssh ["-S","/media/NTFSVOL/the-repo/.git/annex/ssh/git@example.com","-o","ControlMaster=auto","-o","ControlPersist=yes","git@example.com","git-annex-shell 'configlist' '/~/the-repo.git'"] failed; exit code 255
+ Control socket connect(/media/NTFSVOL/the-repo/.git/annex/ssh/git@example.com): Connection refused
+ Failed to connect to new control master
+ Command ssh ["-S","/media/NTFSVOL/the-repo/.git/annex/ssh/git@example.com","-o","ControlMaster=auto","-o","ControlPersist=yes","git@example.com","git-annex-shell 'configlist' '/~/the-repo'"] failed; exit code 255
+ copy the-file.jpg (checking the-remote...) Control socket connect(/media/NTFSVOL/the-repo/.git/annex/ssh/git@example.com): Connection refused
+ Failed to connect to new control master
+ (unable to check the-remote) failed
+ git-annex: copy: 1 failed
+
+Some googling revealed the errors to be stale socket files.
+- [Three SSH Tips](http://shallowsky.com/blog/tags/ssh/)
+- [Improving SSH (OpenSSH) connection speed with shared connections](http://protempore.net/~calvins/howto/ssh-connection-sharing/#section-03)
+
+It appears that SSH connection caching was implemented in response to this wishlist item:
+[wishlist: Prevent repeated password prompts for one command](http://git-annex.branchable.com/todo/wishlist:_Prevent_repeated_password_prompts_for_one_command/)
+
+However ssh connection caching breaks things on NTFS volumes. If I turn off connection caching, it seems to work fine
+
+ $ git config annex.sshcaching false
+
+but it would be nifty if git-annex could detect the filesystem type and do The Right Thing.
+
+Thanks for all the work on git-annex -- it's an awesome project!
+
+> [[done]], `git annex init` now probes for fifo support and disables ssh
+> connection caching if it cannot make one. --[[Joey]]
diff --git a/doc/bugs/ssh_connection_caching_broken_on_NTFS/comment_1_54e7e12514f4c109fd57a4eb744b731a._comment b/doc/bugs/ssh_connection_caching_broken_on_NTFS/comment_1_54e7e12514f4c109fd57a4eb744b731a._comment
new file mode 100644
index 000000000..9219e96d3
--- /dev/null
+++ b/doc/bugs/ssh_connection_caching_broken_on_NTFS/comment_1_54e7e12514f4c109fd57a4eb744b731a._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-03-16T20:47:02Z"
+ content="""
+This failed because ssh connection caching needs fifos,
+which are not supported on NTFS. Also, the linux NTFS code behaves most strangly when asked to make a fifo; creating an empty file instead and then failing with EEXIST.
+
+In more recent versions of git-annex, you can set the `GIT_ANNEX_TMP_DIR` to point somewhere that supports fifos.
+
+Recent versions also try to detect crippled filesystems, and disable use of unix sockets along with symlinks etc.
+However, since ntfs supports symlinks, and it does not probe specially for fifo support, this won't help.
+"""]]
diff --git a/doc/bugs/submodule_path_problem.mdwn b/doc/bugs/submodule_path_problem.mdwn
new file mode 100644
index 000000000..664e246bc
--- /dev/null
+++ b/doc/bugs/submodule_path_problem.mdwn
@@ -0,0 +1,56 @@
+If a submodule isn't toplevel, git-annex breaks
+
+**What steps will reproduce the problem?**
+
+Make two non-empty repositories:
+
+ mkdir submod
+ cd submod
+ git init
+ touch README && git add README
+ git commit -a -m "first import of submodule"
+ cd ..
+
+ mkdir test
+ cd test
+ git init
+ touch README && git add README
+ git commit -a -m "first import of master"
+
+Add first repository as a non-toplevel submodule:
+
+ git submodule add ../submod lib/submod
+
+Setup git-annex for the submodule inside the other repository:
+
+ cd lib/submod
+ git annex init
+
+**What is the expected output? What do you see instead?**
+
+Expected:
+
+ init ok
+ (Recording state in git...)
+
+Got:
+
+ init fatal: Could not switch to '../../../../lib': No such file or directory
+ git-annex: git config [Param "annex.uuid",Param "55D974D1-73E8-489E-B454-03D164664C82"] failed
+
+
+**What version of git-annex are you using? On what operating system?**
+
+3.20121011 compiled from git on Mac OS X 10.8
+
+
+**Please provide any additional information below.**
+
+* git-annex read the path from the "worktree" variable in the git config.
+* The git config for a submodule is storen in the main repository, e.g. "../../.git/modules/lib/submod/config"
+* The path in that config is relative to the config file: "worktree = ../../../../lib/submod"
+* Git-annex expect the path to be relative to the current directory, which is why it fails.
+
+> Impressive analysis, thanks. I've fixed handling of relative
+> core.worktree. [[done]] --[[Joey]]
+
diff --git a/doc/bugs/submodule_path_problem/comment_1_69aec9207d2e9da4bc042d3f4963d80e._comment b/doc/bugs/submodule_path_problem/comment_1_69aec9207d2e9da4bc042d3f4963d80e._comment
new file mode 100644
index 000000000..1ff33e36a
--- /dev/null
+++ b/doc/bugs/submodule_path_problem/comment_1_69aec9207d2e9da4bc042d3f4963d80e._comment
@@ -0,0 +1,48 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkywesyg6tKBZcmxJ2EMUO89DZL1LZ7Sng"
+ nickname="Peter"
+ subject="comment 1"
+ date="2012-10-16T12:02:27Z"
+ content="""
+Not quite there yet.
+
+git-annex init works now, but there is still a problem with paths:
+
+Using the same setup as previously, git-annex init now works:
+
+ cd lib/submod
+ git annex init
+
+But adding a file failes:
+
+ git annex add big-file
+
+Output:
+
+ add big-file (checksum...)
+ git-annex: big-file: getFileStatus: does not exist (No such file or directory)
+ failed
+ (Recording state in git...)
+ git-annex: add: 1 failed
+
+Debug:
+
+
+[2012-10-16 13:59:26 CEST] read: git [\"--git-dir=../../.git/modules/lib/submod\",\"--work-tree=/Users/ptx/tmp/test-annex/test/lib/submod\",\"ls-files\",\"--others\",\"--exclude-standard\",\"-z\",\"--\",\"big-file\"]
+[2012-10-16 13:59:26 CEST] read: git [\"--git-dir=../../.git/modules/lib/submod\",\"--work-tree=/Users/ptx/tmp/test-annex/test/lib/submod\",\"diff\",\"--name-only\",\"--diff-filter=T\",\"-z\",\"--\",\"big-file\"]
+add big-file [2012-10-16 13:59:26 CEST] chat: git [\"--git-dir=../../.git/modules/lib/submod\",\"--work-tree=/Users/ptx/tmp/test-annex/test/lib/submod\",\"check-attr\",\"-z\",\"--stdin\",\"annex.backend\",\"annex.numcopies\",\"--\"]
+(checksum...) [2012-10-16 13:59:26 CEST] chat: git [\"--git-dir=../../.git/modules/lib/submod\",\"--work-tree=/Users/ptx/tmp/test-annex/test/lib/submod\",\"cat-file\",\"--batch\"]
+
+git-annex: big-file: getFileStatus: does not exist (No such file or directory)
+failed
+
+ [2012-10-16 13:59:26 CEST] chat: git [\"--git-dir=../../.git/modules/lib/submod\",\"--work-tree=/Users/ptx/tmp/test-annex/test/lib/submod\",\"hash-object\",\"-w\",\"--stdin-paths\"]
+ [2012-10-16 13:59:26 CEST] feed: git [\"--git-dir=../../.git/modules/lib/submod\",\"--work-tree=/Users/ptx/tmp/test-annex/test/lib/submod\",\"update-index\",\"-z\",\"--index-info\"]
+ [2012-10-16 13:59:26 CEST] read: git [\"--git-dir=../../.git/modules/lib/submod\",\"--work-tree=/Users/ptx/tmp/test-annex/test/lib/submod\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+ (Recording state in git...)
+ [2012-10-16 13:59:26 CEST] read: git [\"--git-dir=../../.git/modules/lib/submod\",\"--work-tree=/Users/ptx/tmp/test-annex/test/lib/submod\",\"write-tree\"]
+ [2012-10-16 13:59:26 CEST] chat: git [\"--git-dir=../../.git/modules/lib/submod\",\"--work-tree=/Users/ptx/tmp/test-annex/test/lib/submod\",\"commit-tree\",\"ed2f98d7105deed7482b3dde43426c177b360131\",\"-p\",\"refs/heads/git-annex\"]
+ [2012-10-16 13:59:26 CEST] call: git [\"--git-dir=../../.git/modules/lib/submod\",\"--work-tree=/Users/ptx/tmp/test-annex/test/lib/submod\",\"update-ref\",\"refs/heads/git-annex\",\"df49e7bef8409dff450ce549c40f4ab429ea3144\"]
+ [2012-10-16 13:59:26 CEST] chat: git [\"--git-dir=../../.git/modules/lib/submod\",\"--work-tree=/Users/ptx/tmp/test-annex/test/lib/submod\",\"cat-file\",\"--batch\"]
+ git-annex: add: 1 failed
+"""]]
diff --git a/doc/bugs/submodule_path_problem/comment_2_53d9eb28cb70b51637470175a80ddf35._comment b/doc/bugs/submodule_path_problem/comment_2_53d9eb28cb70b51637470175a80ddf35._comment
new file mode 100644
index 000000000..a60a096e8
--- /dev/null
+++ b/doc/bugs/submodule_path_problem/comment_2_53d9eb28cb70b51637470175a80ddf35._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 2"
+ date="2012-10-16T20:28:03Z"
+ content="""
+Cute, it was making the wrong symlink and then noticed it was broken and reverted the add. At least my error unwind works! Anyway, fixed this too.
+"""]]
diff --git a/doc/bugs/submodule_path_problem/comment_3_aa5e0f99000a5b4988bccbb2ca28353b._comment b/doc/bugs/submodule_path_problem/comment_3_aa5e0f99000a5b4988bccbb2ca28353b._comment
new file mode 100644
index 000000000..3f446a777
--- /dev/null
+++ b/doc/bugs/submodule_path_problem/comment_3_aa5e0f99000a5b4988bccbb2ca28353b._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkywesyg6tKBZcmxJ2EMUO89DZL1LZ7Sng"
+ nickname="Peter"
+ subject="comment 3"
+ date="2012-10-17T11:41:54Z"
+ content="""
+One step closer, but still not perfect:
+
+ git annex add big-file
+ > add big-file (checksum...) ok
+ > (Recording state in git...)
+
+ git commit -a -m \"Added file\"
+ > git-annex: /Users/ptx/tmp/test-annex/test/.git/lib/submod: changeWorkingDirectory: does not exist (No such file or directory)
+
+So when applying the post-hook, git-annex is getting the wrong directory.
+
+`test/.git/lib/submod` should be `test/.git/modules/lib/submod`
+
+"""]]
diff --git a/doc/bugs/submodule_path_problem/comment_4_ab1508a5a04e2106aad5e7985775a6fa._comment b/doc/bugs/submodule_path_problem/comment_4_ab1508a5a04e2106aad5e7985775a6fa._comment
new file mode 100644
index 000000000..c46eedf8e
--- /dev/null
+++ b/doc/bugs/submodule_path_problem/comment_4_ab1508a5a04e2106aad5e7985775a6fa._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 4"
+ date="2012-10-17T18:29:24Z"
+ content="""
+Ok, fixed that.
+"""]]
diff --git a/doc/bugs/submodule_path_problem/comment_5_8c7539d1c11b81f5d46aa8e1c61745ae._comment b/doc/bugs/submodule_path_problem/comment_5_8c7539d1c11b81f5d46aa8e1c61745ae._comment
new file mode 100644
index 000000000..088517c5b
--- /dev/null
+++ b/doc/bugs/submodule_path_problem/comment_5_8c7539d1c11b81f5d46aa8e1c61745ae._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkywesyg6tKBZcmxJ2EMUO89DZL1LZ7Sng"
+ nickname="Peter"
+ subject="comment 5"
+ date="2012-11-08T10:32:26Z"
+ content="""
+Great!
+
+Everything is working now, unfortunately the package in cabal and the prebuild linux packages are one day too old.
+
+Are you going to release a newer build soon?
+
+/ptx
+"""]]
diff --git a/doc/bugs/submodule_path_problem/comment_6_cacc91afcb1739dfca3a60590bb70356._comment b/doc/bugs/submodule_path_problem/comment_6_cacc91afcb1739dfca3a60590bb70356._comment
new file mode 100644
index 000000000..1cae4ea98
--- /dev/null
+++ b/doc/bugs/submodule_path_problem/comment_6_cacc91afcb1739dfca3a60590bb70356._comment
@@ -0,0 +1,67 @@
+[[!comment format=mdwn
+ username="konubinix"
+ ip="82.243.233.186"
+ subject="Git annexed files symlink are wrong when submodule is not in the same path "
+ date="2013-08-08T06:36:10Z"
+ content="""
+Hi,
+
+First, thanks for the great tool that is git-annex!
+
+I have a problem with submodules when the git repository is not a submodule everywhere.
+
+ $ git-annex version
+ git-annex version: 4.20130802
+ ...
+
+ $ git --version
+ git version 1.8.3.2
+
+I try to have a repository has a submodule of another.
+
+ # creating the master repository
+ mkdir annex_master
+ cd annex_master/
+ git init
+ # hack: adding a file to create the master branch
+ touch start
+ git add start
+ git commit -m \"start\"
+ cd ..
+ # create another repository
+ mkdir annex_sub
+ cd annex_sub/
+ git init
+ # hack: adding a file to create the master branch
+ touch start
+ git add start
+ git commit -m \"start\"
+ # it is a annexed repository
+ git annex init sub
+ # add the other repository as submodule of the master one
+ cd ../annex_master/
+ git submodule add ../annex_sub/ module
+ cd module/
+ git annex init sub_module
+ git annex sync origin
+ # add an annexed file
+ echo test > test
+ git annex add
+ git annex sync
+ # go back to the origin repository
+ cd ../../annex_sub/
+ git annex sync
+ ls -l
+
+This returns
+test -> ../.git/modules/module/annex/objects/w8/pv/SHA256E-s5--f2ca1bb6c7e907d06dafe4687e579fce76b37e4e93b7605022da52e6ccc26fd2/SHA256E-s5--f2ca1bb6c7e907d06dafe4687e579fce76b37e4e93b7605022da52e6ccc26fd2
+
+Actually, the file committed is correct. But the fact it points to '../.git/modules/module/...' makes the link work only if the repository is also a submodule and if this submodule is also located in the modules folder in the parent git repository.
+
+I would expect, since this repository is not an annex:
+test -> .git/annex/objects/w8/pv/SHA256E-s5--f2ca1bb6c7e907d06dafe4687e579fce76b37e4e93b7605022da52e6ccc26fd2/SHA256E-s5--f2ca1bb6c7e907d06dafe4687e579fce76b37e4e93b7605022da52e6ccc26fd2
+
+Do you think that is possible?
+
+Thanks.
+"""]]
diff --git a/doc/bugs/subtle_build_issue_on_OSX_10.7_and_Haskell_Platform___40__if_you_have_the_32bit_version_installed__41__.mdwn b/doc/bugs/subtle_build_issue_on_OSX_10.7_and_Haskell_Platform___40__if_you_have_the_32bit_version_installed__41__.mdwn
new file mode 100644
index 000000000..3a50256db
--- /dev/null
+++ b/doc/bugs/subtle_build_issue_on_OSX_10.7_and_Haskell_Platform___40__if_you_have_the_32bit_version_installed__41__.mdwn
@@ -0,0 +1,50 @@
+I've just come across a subtle build issue (as haskell-platform just
+got updated, I thought I might give it a try) The scenario is
+
+* OSX 10.7 (everything is up to date with xcode etc... the usual)
+* The 32bit version of Haskell Platform 2012.2
+
+The issue is when libdiskfree.c is compiled and linked to git-annex,
+OSX defaults to a 64bit binary, thus...
+
+ Linking git-annex ...
+ ld: warning: ignoring file Utility/libdiskfree.o, file was built for unsupported file format which is not the architecture being linked (i386)
+ Undefined symbols for architecture i386:
+ "_diskfree", referenced from:
+ _UtilityziDiskFree_zdwa_info in DiskFree.o
+ ld: symbol(s) not found for architecture i386
+ collect2: ld returned 1 exit status
+ make: *** [git-annex] Error 1
+
+You can either compile up the c library in a 32bit mode if you have the 32bit
+version of Haskell Platform installed as in the following example
+
+ laplace:git-annex jtang$ cc -m32 -c -o Utility/libdiskfree.o Utility/libdiskfree.c
+ Utility/libdiskfree.c: In function ‘diskfree’:
+ Utility/libdiskfree.c:61: warning: ‘statfs64’ is deprecated (declared at /usr/include/sys/mount.h:379)
+ laplace:git-annex jtang$ make
+ ghc -O2 -Wall -ignore-package monads-fd -outputdir tmp -IUtility -DWITH_S3 --make git-annex Utility/libdiskfree.o
+
+ Utility/Touch.hs:1:12:
+ Warning: -#include and INCLUDE pragmas are deprecated: They no longer have any effect
+
+ Utility/Touch.hs:2:12:
+ Warning: -#include and INCLUDE pragmas are deprecated: They no longer have any effect
+
+ Utility/Touch.hs:3:12:
+ Warning: -#include and INCLUDE pragmas are deprecated: They no longer have any effect
+
+ Utility/Touch.hs:4:12:
+ Warning: -#include and INCLUDE pragmas are deprecated: They no longer have any effect
+ Linking git-annex ...
+
+Or else just install the 64bit haskell platform. I'm not too sure where
+you would but the intelligence to detect 32 or 64 outputs from the
+different compilers. I suspect checking what ghc outputs then putting in
+the appropriate -m32 or -m64 for the c compiler is the right thing to do.
+Or just telling users to use the 64bit version of the haskell platform?
+It may also be possible to get osx's c compiler to output a universal binary
+to give you everything, but that be going down the _being too platform
+specific route_.
+
+> [[done]], it'll detect this and force -m32. --[[Joey]]
diff --git a/doc/bugs/subtle_build_issue_on_OSX_10.7_and_Haskell_Platform___40__if_you_have_the_32bit_version_installed__41__/comment_1_6208e70a21a048d5423926d16e32d421._comment b/doc/bugs/subtle_build_issue_on_OSX_10.7_and_Haskell_Platform___40__if_you_have_the_32bit_version_installed__41__/comment_1_6208e70a21a048d5423926d16e32d421._comment
new file mode 100644
index 000000000..11d135251
--- /dev/null
+++ b/doc/bugs/subtle_build_issue_on_OSX_10.7_and_Haskell_Platform___40__if_you_have_the_32bit_version_installed__41__/comment_1_6208e70a21a048d5423926d16e32d421._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ subject="comment 1"
+ date="2012-06-04T20:02:23Z"
+ content="""
+Seems you built it using `make` .. could you try instead building with cabal, ie run `cabal install git-annex` or `cabal build` in the source tree. I think cabal will probably do the right thing.
+
+I could fix the Makefile, I suppose. What does this say: `ghc -e 'print System.Info.arch'
+"""]]
diff --git a/doc/bugs/subtle_build_issue_on_OSX_10.7_and_Haskell_Platform___40__if_you_have_the_32bit_version_installed__41__/comment_2_8765b6190e79251637bb59ba28f245c1._comment b/doc/bugs/subtle_build_issue_on_OSX_10.7_and_Haskell_Platform___40__if_you_have_the_32bit_version_installed__41__/comment_2_8765b6190e79251637bb59ba28f245c1._comment
new file mode 100644
index 000000000..cad802a88
--- /dev/null
+++ b/doc/bugs/subtle_build_issue_on_OSX_10.7_and_Haskell_Platform___40__if_you_have_the_32bit_version_installed__41__/comment_2_8765b6190e79251637bb59ba28f245c1._comment
@@ -0,0 +1,21 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 2"
+ date="2012-06-05T14:07:26Z"
+ content="""
+FYI, (the follow is on OSX 10.7 on two different machines)
+
+On my 64bit install of haskell platform...
+
+ laplace:~ jtang$ ghc -e 'print System.Info.arch'
+ \"x86_64\"
+
+On my 32bit install of haskell platform...
+
+ x00:git-annex jtang$ ghc -e 'print System.Info.arch'
+ \"i386\"
+
+Running _cabal build_ or _cabal install git-annex_ as you suggest with the 32bit install does do the right thing.
+
+"""]]
diff --git a/doc/bugs/support_bare_git_repo__44___with_the_annex_directory_exposed_to_http.mdwn b/doc/bugs/support_bare_git_repo__44___with_the_annex_directory_exposed_to_http.mdwn
new file mode 100644
index 000000000..ba7dcad30
--- /dev/null
+++ b/doc/bugs/support_bare_git_repo__44___with_the_annex_directory_exposed_to_http.mdwn
@@ -0,0 +1,20 @@
+Let's say that http://people.collabora.com/~alsuren/git/fate-suite.git/ is a bare git repo. It has been 'git update-server-info'd so that it can be served on a dumb http server.
+
+The repo is also a git annex remote, created using the following commands:
+
+* git remote add alsuren git+ssh://people.collabora.co.uk/user/alsuren/public_html/fate-suite.git
+* git push alsuren --all
+* git annex copy --to=alsuren
+
+so http://people.collabora.com/~alsuren/git/fate-suite.git/annex is a valid git annex (though listing dirs is forbidden, so you need to know the filenames ahead of time).
+
+I would like to be able to use the following commands to get a clone of the repo:
+
+* git clone http://people.collabora.com/~alsuren/git/fate-suite.git/
+* cd fate-suite
+* git annex get
+
+This would allow contributors to quickly get a copy of our upstream repo and start contributing with minimal bandwidth/effort.
+
+> This is now supported.. I look forward to seeing your project using it!
+> --[[Joey]] [[!tag done]]
diff --git a/doc/bugs/test_failures_on_window_for_5.20131118.mdwn b/doc/bugs/test_failures_on_window_for_5.20131118.mdwn
new file mode 100644
index 000000000..490bdf2c8
--- /dev/null
+++ b/doc/bugs/test_failures_on_window_for_5.20131118.mdwn
@@ -0,0 +1,20 @@
+### Please describe the problem.
+
+git annex test reports failures
+
+### What steps will reproduce the problem?
+
+running git annex test (from standard cmd, with: git version: 1.7.11.msysgit.1)
+
+### What version of git-annex are you using? On what operating system?
+
+5.20131118 from installers
+
+### Please provide any additional information below.
+
+operating system:
+
+windows XP, NTFS = 1 FAIL
+windows 7, NTFS = 2 FAILs
+
+see attachment for full log of git annex test output
diff --git a/doc/bugs/test_failures_on_window_for_5.20131118/comment_1_5a7a284625c12d54390fe4a4ec1d4211._comment b/doc/bugs/test_failures_on_window_for_5.20131118/comment_1_5a7a284625c12d54390fe4a4ec1d4211._comment
new file mode 100644
index 000000000..d27e69b30
--- /dev/null
+++ b/doc/bugs/test_failures_on_window_for_5.20131118/comment_1_5a7a284625c12d54390fe4a4ec1d4211._comment
@@ -0,0 +1,188 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkJafmCf-sg9_OM0pynFYM3AO4WCgJiaMI"
+ nickname="Michele"
+ subject="seems i'm not allowed to attach full logs."
+ date="2013-11-23T16:06:17Z"
+ content="""
+here's an excerpt (the context of FAIL), hopefully i've interpreted correctely the test begin message.
+
+win7:
+
+ unannex (with copy): Detected a filesystem without fifo support.
+ Disabling ssh connection caching.
+ Detected a crippled filesystem.
+ Enabling direct mode.
+get foo (merging origin/git-annex into git-annex...)
+(Recording state in git...)
+(from origin...)
+foo
+ 20 100% 0.00kB/s 0:00:00
+ 20 100% 0.00kB/s 0:00:00 (xfer#1, to-check=0/1)
+
+sent 87 bytes received 31 bytes 236.00 bytes/sec
+total size is 20 speedup is 0.17
+ok
+(Recording state in git...)
+unannex foo
+git-annex: M:\gitannex.test\.t\tmprepo4\.git\annex\objects\6cd\e82\SHA256E-s20--e394a389d787383843decc5d3d99b6d184ffa5fddeec23b911f9ee7fc8b9ea77\SHA256E-s20--e394a389d787383843decc5d3d99b6d184ffa5fddeec23b911f9ee7fc8b9ea77.map4432.tmp: MoveFileEx \"M:\\gitannex.test\\.t\\tmprepo4\\.git\\annex\\objects\\6cd\\e82\\SHA256E-s20--e394a389d787383843decc5d3d99b6d184ffa5fddeec23b911f9ee7fc8b9ea77\\SHA256E-s20--e394a389d787383843decc5d3d99b6d184ffa5fddeec23b911f9ee7fc8b9ea77.map4432.tmp\" \"M:\\gitannex.test\\.t\\tmprepo4\\.git\\annex\\objects\\6cd\\e82\\SHA256E-s20--e394a389d787383843decc5d3d99b6d184ffa5fddeec23b911f9ee7fc8b9ea77\\SHA256E-s20--e394a389d787383843decc5d3d99b6d184ffa5fddeec23b911f9ee7fc8b9ea77.map\": permission denied (Access is denied.)
+failed
+git-annex: unannex: 1 failed
+FAIL
+
+ conflict_resolution (mixed directory and file): Detected a filesystem without fifo support.
+ Disabling ssh connection caching.
+ Detected a crippled filesystem.
+ Enabling direct mode.
+ Detected a filesystem without fifo support.
+ Disabling ssh connection caching.
+ Detected a crippled filesystem.
+ Enabling direct mode.
+ add conflictor (checksum...) ok
+ (Recording state in git...)
+ (merging origin/git-annex origin/synced/git-annex into git-annex...)
+ (Recording state in git...)
+ commit
+ ok
+ pull origin bash.exe: warning: could not find /tmp, please create!
+
+ ok
+ push origin bash.exe: warning: could not find /tmp, please create!
+ To M:/gitannex.test/.t\repo
+ 32fb7c0..38147e0 git-annex -> synced/git-annex
+ 7684984..4116595 annex/direct/master -> synced/master
+
+ ok
+ add conflictor/subfile (checksum...) ok
+ (Recording state in git...)
+ (merging origin/git-annex origin/synced/git-annex into git-annex...)
+ (Recording state in git...)
+ commit
+ ok
+ pull origin bash.exe: warning: could not find /tmp, please create!
+ From M:/gitannex.test/.t\repo
+ 7684984..4116595 master -> origin/master
+ 32fb7c0..38147e0 synced/git-annex -> origin/synced/git-annex
+ 7684984..4116595 synced/master -> origin/synced/master
+ Adding conflictor/subfile
+ CONFLICT (directory/file): There is a directory with name conflictor in HEAD. Adding conflictor as conflictor~refs_remotes_origin_synced_master
+ Automatic merge failed; fix conflicts and then commit the result.
+ Ignoring path ./conflictor.variant-cc12
+ conflictor: needs merge
+ [annex/direct/master 27c52e4] git-annex automatic merge conflict fix
+
+
+ (Recording state in git...)
+
+ Merge conflict was automatically resolved; you may want to examine the result.
+ ok
+ (merging origin/synced/git-annex into git-annex...)
+ (Recording state in git...)
+ push origin bash.exe: warning: could not find /tmp, please create!
+ To M:/gitannex.test/.t\repo
+ 38147e0..02916ee git-annex -> synced/git-annex
+ 4116595..27c52e4 annex/direct/master -> synced/master
+
+ ok
+ commit
+ ok
+ pull r2 bash.exe: warning: could not find /tmp, please create!
+ From ../../.t\tmprepo35
+ * [new branch] annex/direct/master -> r2/annex/direct/master
+ * [new branch] git-annex -> r2/git-annex
+ * [new branch] master -> r2/master
+ * [new branch] synced/master -> r2/synced/master
+ Updating 4116595..27c52e4
+ Fast-forward
+ conflictor | 1 -
+ conflictor/subfile | 1 +
+ 2 files changed, 1 insertion(+), 1 deletion(-)
+ delete mode 120000 conflictor
+ create mode 120000 conflictor/subfile
+ Already up-to-date.
+
+
+
+ ok
+ (merging r2/git-annex into git-annex...)
+ FAIL
+
+
+windowsXP:
+
+ conflict_resolution (mixed directory and file): Detected a filesystem without fifo support.
+ Disabling ssh connection caching.
+ Detected a crippled filesystem.
+ Enabling direct mode.
+ Detected a filesystem without fifo support.
+ Disabling ssh connection caching.
+ Detected a crippled filesystem.
+ Enabling direct mode.
+add conflictor (checksum...) ok
+(Recording state in git...)
+(merging origin/git-annex origin/synced/git-annex into git-annex...)
+(Recording state in git...)
+commit
+ok
+pull origin bash.exe: warning: could not find /tmp, please create!
+
+ok
+push origin bash.exe: warning: could not find /tmp, please create!
+To C:/Documents and Settings/Silvia/.t\repo
+ edd69f1..83c6a5a git-annex -> synced/git-annex
+ bed393e..978ac14 annex/direct/master -> synced/master
+
+ok
+add conflictor/subfile (checksum...) ok
+(Recording state in git...)
+(merging origin/git-annex origin/synced/git-annex into git-annex...)
+(Recording state in git...)
+commit
+ok
+pull origin bash.exe: warning: could not find /tmp, please create!
+From C:/Documents and Settings/Silvia/.t\repo
+ bed393e..978ac14 master -> origin/master
+ edd69f1..83c6a5a synced/git-annex -> origin/synced/git-annex
+ bed393e..978ac14 synced/master -> origin/synced/master
+Adding conflictor/subfile
+CONFLICT (directory/file): There is a directory with name conflictor in HEAD. Adding conflictor as conflictor~refs_remotes_origin_synced_master
+Automatic merge failed; fix conflicts and then commit the result.
+Ignoring path ./conflictor.variant-cc12
+conflictor: needs merge
+[annex/direct/master e3e39fc] git-annex automatic merge conflict fix
+
+
+(Recording state in git...)
+
+ Merge conflict was automatically resolved; you may want to examine the result.
+ok
+(merging origin/synced/git-annex into git-annex...)
+(Recording state in git...)
+push origin bash.exe: warning: could not find /tmp, please create!
+To C:/Documents and Settings/Silvia/.t\repo
+ 83c6a5a..e1a1678 git-annex -> synced/git-annex
+ 978ac14..e3e39fc annex/direct/master -> synced/master
+
+ok
+commit
+ok
+pull r2 bash.exe: warning: could not find /tmp, please create!
+From ../../.t\tmprepo35
+ * [new branch] annex/direct/master -> r2/annex/direct/master
+ * [new branch] git-annex -> r2/git-annex
+ * [new branch] master -> r2/master
+ * [new branch] synced/master -> r2/synced/master
+Updating 978ac14..e3e39fc
+Fast-forward
+ conflictor | 1 -
+ conflictor/subfile | 1 +
+ 2 files changed, 1 insertion(+), 1 deletion(-)
+ delete mode 120000 conflictor
+ create mode 120000 conflictor/subfile
+Already up-to-date.
+
+
+
+ok
+(merging r2/git-annex into git-annex...)
+FAIL
+"""]]
diff --git a/doc/bugs/test_suite_failure_on_samba_mount.mdwn b/doc/bugs/test_suite_failure_on_samba_mount.mdwn
new file mode 100644
index 000000000..ab3990c32
--- /dev/null
+++ b/doc/bugs/test_suite_failure_on_samba_mount.mdwn
@@ -0,0 +1,278 @@
+### Please describe the problem.
+
+`git annex test` show multiple failures on a samba mounted partition.
+
+### What steps will reproduce the problem?
+
+just run `git annex test` (in the mounted dir)
+
+### What version of git-annex are you using? On what operating system?
+
+4.20130521, built for architecture `armhf` by the Raspbian maintainers ("jessie" suite at the time of writing)
+
+### Please provide any additional information below.
+
+Here are the last lines of `git annex test` output; AFAICT they are the only lines mentioning failures. Before them the output mentions `+++ OK, passed 100 tests.`.
+
+[[!format text """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+Cases: 1 Tried: 0 Errors: 0 Failures: 0----------------------------------------------------------------------
+Now, some broader checks ...
+ (Do not be alarmed by odd output here; it's normal.
+ wait for the last line to see how it went.)
+----------------------------------------------------------------------
+init
+ Detected a crippled filesystem.
+ Enabling direct mode.
+ Detected a filesystem without fifo support.
+ Disabling ssh connection caching.
+ Cases: 1 Tried: 1 Errors: 0 Failures: 0
+Cases: 3 Tried: 0 Errors: 0 Failures: 0Cases: 3 Tried: 1 Errors: 0 Failures: 0----------------------------------------------------------------------
+add
+ Detected a crippled filesystem.
+ Enabling direct mode.
+ Detected a filesystem without fifo support.
+ Disabling ssh connection caching.
+Cases: 3 Tried: 2 Errors: 0 Failures: 0 Detected a crippled filesystem.
+ Enabling direct mode.
+ Detected a filesystem without fifo support.
+ Disabling ssh connection caching.
+error: unable to create temporary sha1 filename : No such file or directory
+
+git-annex: user error (git ["--git-dir=/media/freebox/.t/tmprepo0/.git","--work-tree=/media/freebox/.t/tmprepo0","commit-tree","4b825dc642cb6eb9a060e54bf8d69288fbee4904"] exited 1)
+ ### Failure in: git-annex add:2
+git annex init failed
+Cases: 3 Tried: 3 Errors: 0 Failures: 1
+Cases: 1 Tried: 0 Errors: 0 Failures: 0----------------------------------------------------------------------
+reinject
+ Detected a crippled filesystem.
+ Enabling direct mode.
+ Detected a filesystem without fifo support.
+ Disabling ssh connection caching.
+ Detected a crippled filesystem.
+ Detected a filesystem without fifo support.
+ Disabling ssh connection caching.
+ Cases: 1 Tried: 1 Errors: 0 Failures: 0
+Cases: 2 Tried: 0 Errors: 0 Failures: 0not supported in direct mode; skipping
+----------------------------------------------------------------------
+unannex
+ Detected a crippled filesystem.
+ Enabling direct mode.
+ Detected a filesystem without fifo support.
+ Disabling ssh connection caching.
+error: unable to create temporary sha1 filename : No such file or directory
+
+git-annex: user error (git ["--git-dir=/media/freebox/.t/tmprepo1/.git","--work-tree=/media/freebox/.t/tmprepo1","commit-tree","4b825dc642cb6eb9a060e54bf8d69288fbee4904"] exited 1)
+ ### Failure in: git-annex unannex:0:no content
+git annex init failed
+Cases: 2 Tried: 1 Errors: 0 Failures: 1 Detected a crippled filesystem.
+ Enabling direct mode.
+ Detected a filesystem without fifo support.
+ Disabling ssh connection caching.
+ Detected a crippled filesystem.
+ Detected a filesystem without fifo support.
+ Disabling ssh connection caching.
+ Cases: 2 Tried: 2 Errors: 0 Failures: 1
+Cases: 3 Tried: 0 Errors: 0 Failures: 0not supported in direct mode; skipping
+----------------------------------------------------------------------
+drop
+ Detected a crippled filesystem.
+ Enabling direct mode.
+ Detected a filesystem without fifo support.
+ Disabling ssh connection caching.
+error: unable to create temporary sha1 filename : No such file or directory
+
+git-annex: user error (git ["--git-dir=/media/freebox/.t/tmprepo2/.git","--work-tree=/media/freebox/.t/tmprepo2","commit-tree","4b825dc642cb6eb9a060e54bf8d69288fbee4904"] exited 1)
+ ### Failure in: git-annex drop:0:no remotes
+git annex init failed
+Cases: 3 Tried: 1 Errors: 0 Failures: 1 Detected a crippled filesystem.
+ Enabling direct mode.
+ Detected a filesystem without fifo support.
+ Disabling ssh connection caching.
+Cases: 3 Tried: 2 Errors: 0 Failures: 1/media/freebox/.t/tmprepo3/.git: No such file or directory
+ ### Failure in: git-annex drop:2:untrusted remote
+git clone failed
+Cases: 3 Tried: 3 Errors: 0 Failures: 2
+Cases: 1 Tried: 0 Errors: 0 Failures: 0/media/freebox/.t/tmprepo3/.git: No such file or directory
+ ### Failure in: git-annex get
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+Cases: 1 Tried: 0 Errors: 0 Failures: 0/media/freebox/.t/tmprepo3/.git: No such file or directory
+ ### Failure in: git-annex move
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+Cases: 1 Tried: 0 Errors: 0 Failures: 0/media/freebox/.t/tmprepo3/.git: No such file or directory
+ ### Failure in: git-annex copy
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+Cases: 1 Tried: 0 Errors: 0 Failures: 0/media/freebox/.t/tmprepo3/.git: No such file or directory
+ ### Failure in: git-annex unlock/lock
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+Cases: 2 Tried: 0 Errors: 0 Failures: 0/media/freebox/.t/tmprepo3/.git: No such file or directory
+ ### Failure in: git-annex edit/commit:0
+git clone failed
+Cases: 2 Tried: 1 Errors: 0 Failures: 1/media/freebox/.t/tmprepo3/.git: No such file or directory
+ ### Failure in: git-annex edit/commit:1
+git clone failed
+Cases: 2 Tried: 2 Errors: 0 Failures: 2
+Cases: 1 Tried: 0 Errors: 0 Failures: 0/media/freebox/.t/tmprepo3/.git: No such file or directory
+ ### Failure in: git-annex fix
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+Cases: 1 Tried: 0 Errors: 0 Failures: 0/media/freebox/.t/tmprepo3/.git: No such file or directory
+ ### Failure in: git-annex trust/untrust/semitrust/dead
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+Cases: 4 Tried: 0 Errors: 0 Failures: 0/media/freebox/.t/tmprepo3/.git: No such file or directory
+ ### Failure in: git-annex fsck:0
+git clone failed
+Cases: 4 Tried: 1 Errors: 0 Failures: 1/media/freebox/.t/tmprepo3/refs: No such file or directory
+ ### Failure in: git-annex fsck:1
+git clone failed
+Cases: 4 Tried: 2 Errors: 0 Failures: 2/media/freebox/.t/tmprepo3/.git: No such file or directory
+ ### Failure in: git-annex fsck:2
+git clone failed
+Cases: 4 Tried: 3 Errors: 0 Failures: 3/media/freebox/.t/tmprepo3/.git: No such file or directory
+ ### Failure in: git-annex fsck:3
+git clone failed
+Cases: 4 Tried: 4 Errors: 0 Failures: 4
+Cases: 2 Tried: 0 Errors: 0 Failures: 0/media/freebox/.t/tmprepo3/.git: No such file or directory
+ ### Failure in: git-annex migrate:0
+git clone failed
+Cases: 2 Tried: 1 Errors: 0 Failures: 1/media/freebox/.t/tmprepo3/.git: No such file or directory
+ ### Failure in: git-annex migrate:1
+git clone failed
+Cases: 2 Tried: 2 Errors: 0 Failures: 2
+Cases: 1 Tried: 0 Errors: 0 Failures: 0/media/freebox/.t/tmprepo3/.git: No such file or directory
+ ### Failure in: git-annex unused/dropunused
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+Cases: 1 Tried: 0 Errors: 0 Failures: 0/media/freebox/.t/tmprepo3/.git: No such file or directory
+ ### Failure in: git-annex describe
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+Cases: 1 Tried: 0 Errors: 0 Failures: 0/media/freebox/.t/tmprepo3/.git: No such file or directory
+ ### Failure in: git-annex find
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+Cases: 1 Tried: 0 Errors: 0 Failures: 0/media/freebox/.t/tmprepo3/.git: No such file or directory
+ ### Failure in: git-annex merge
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+Cases: 1 Tried: 0 Errors: 0 Failures: 0/media/freebox/.t/tmprepo3/.git: No such file or directory
+ ### Failure in: git-annex status
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+Cases: 1 Tried: 0 Errors: 0 Failures: 0/media/freebox/.t/tmprepo3/.git: No such file or directory
+ ### Failure in: git-annex version
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+Cases: 1 Tried: 0 Errors: 0 Failures: 0/media/freebox/.t/tmprepo3/.git: No such file or directory
+ ### Failure in: git-annex sync
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+Cases: 1 Tried: 0 Errors: 0 Failures: 0/media/freebox/.t/tmprepo3/.git: No such file or directory
+ ### Failure in: union merge regression
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+Cases: 1 Tried: 0 Errors: 0 Failures: 0/media/freebox/.t/tmprepo3/.git: No such file or directory
+ ### Failure in: automatic conflict resolution
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+Cases: 1 Tried: 0 Errors: 0 Failures: 0/media/freebox/.t/tmprepo3/.git: No such file or directory
+ ### Failure in: git-annex map
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+Cases: 1 Tried: 0 Errors: 0 Failures: 0/media/freebox/.t/tmprepo3/.git: No such file or directory
+ ### Failure in: git-annex uninit
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+Cases: 1 Tried: 0 Errors: 0 Failures: 0/media/freebox/.t/tmprepo3/.git: No such file or directory
+ ### Failure in: git-annex upgrade
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+Cases: 1 Tried: 0 Errors: 0 Failures: 0/media/freebox/.t/tmprepo3/.git: No such file or directory
+ ### Failure in: git-annex whereis
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+Cases: 1 Tried: 0 Errors: 0 Failures: 0/media/freebox/.t/tmprepo3/.git: No such file or directory
+ ### Failure in: git-annex hook remote
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+Cases: 1 Tried: 0 Errors: 0 Failures: 0/media/freebox/.t/tmprepo3/.git: No such file or directory
+ ### Failure in: git-annex directory remote
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+Cases: 1 Tried: 0 Errors: 0 Failures: 0/media/freebox/.t/tmprepo3/.git: No such file or directory
+ ### Failure in: git-annex rsync remote
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+Cases: 1 Tried: 0 Errors: 0 Failures: 0/media/freebox/.t/tmprepo3/.git: No such file or directory
+ ### Failure in: git-annex bup remote
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+Cases: 1 Tried: 0 Errors: 0 Failures: 0/media/freebox/.t/tmprepo3/.git: No such file or directory
+ ### Failure in: git-annex crypto
+git clone failed
+Cases: 1 Tried: 1 Errors: 0 Failures: 1
+----------------------------------------------------------------------
+get
+----------------------------------------------------------------------
+move
+----------------------------------------------------------------------
+copy
+----------------------------------------------------------------------
+lock
+----------------------------------------------------------------------
+edit
+----------------------------------------------------------------------
+fix
+----------------------------------------------------------------------
+trust
+----------------------------------------------------------------------
+fsck
+----------------------------------------------------------------------
+migrate
+----------------------------------------------------------------------
+ unused
+----------------------------------------------------------------------
+describe
+----------------------------------------------------------------------
+find
+----------------------------------------------------------------------
+merge
+----------------------------------------------------------------------
+status
+----------------------------------------------------------------------
+version
+----------------------------------------------------------------------
+sync
+----------------------------------------------------------------------
+union merge regression
+----------------------------------------------------------------------
+conflict resolution
+----------------------------------------------------------------------
+map
+----------------------------------------------------------------------
+uninit
+----------------------------------------------------------------------
+upgrade
+----------------------------------------------------------------------
+whereis
+----------------------------------------------------------------------
+hook remote
+----------------------------------------------------------------------
+directory remote
+----------------------------------------------------------------------
+rsync remote
+----------------------------------------------------------------------
+bup remote
+----------------------------------------------------------------------
+crypto
+git-annex: .t/repo/.git/annex: removeDirectory: unsatisified constraints (Directory not empty)
+
+# End of transcript or log.
+"""]]
diff --git a/doc/bugs/test_suite_failure_on_samba_mount/comment_1_e074b20801b921ee2661025a050a8af2._comment b/doc/bugs/test_suite_failure_on_samba_mount/comment_1_e074b20801b921ee2661025a050a8af2._comment
new file mode 100644
index 000000000..623028c80
--- /dev/null
+++ b/doc/bugs/test_suite_failure_on_samba_mount/comment_1_e074b20801b921ee2661025a050a8af2._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="seems like a general git problem"
+ date="2013-08-24T19:55:56Z"
+ content="""
+\"unable to create temporary sha1 filename\" is a git error message. I don't actually see any git-annex failure here, just a git failure that seems to lead to a cascade of other failures.
+
+I'm not sure if the \"/media/freebox/.t/tmprepo3/.git: No such file or directory\" is because git clone has failed due to the other errors, or if git clone somehow failed to set up the .git directory.
+
+It would probably be helpful to have a play around with git on this filesystem and see what breaks. Alternatively, you can use git-annex with `--debug` to see the git commands it's running that fail, and try them yourself and perhaps strace or gdb them or something to see where they go wrong.
+"""]]
diff --git a/doc/bugs/test_suite_shouldn__39__t_fail_silently.mdwn b/doc/bugs/test_suite_shouldn__39__t_fail_silently.mdwn
new file mode 100644
index 000000000..2f486ad65
--- /dev/null
+++ b/doc/bugs/test_suite_shouldn__39__t_fail_silently.mdwn
@@ -0,0 +1,3 @@
+When the test suite cannot be compiled, the build just fails silenty. This means that in automated builds there is no easy way to ensure that the generated binaries have passed the test suite, because it may not even have been run! IMHO, "make test" should fail (i.e. return a non-zero exit code) when it can't succeeed.
+
+> Ok, fixed. --[[Joey]] [[done]]
diff --git a/doc/bugs/tests_fail_when_there_is_no_global_.gitconfig_for_the_user.mdwn b/doc/bugs/tests_fail_when_there_is_no_global_.gitconfig_for_the_user.mdwn
new file mode 100644
index 000000000..b90b501e3
--- /dev/null
+++ b/doc/bugs/tests_fail_when_there_is_no_global_.gitconfig_for_the_user.mdwn
@@ -0,0 +1,50 @@
+Make test fails when git doesn't know what identity to give to commits
+
+<pre>
+
+Testing 1:blackbox:0:git-annex init
+Cases: 30 Tried: 7 Errors: 0 Failures: 0
+*** Please tell me who you are.
+
+Run
+
+ git config --global user.email "you@example.com"
+ git config --global user.name "Your Name"
+
+to set your account's default identity.
+Omit --global to set the identity only in this repository.
+
+fatal: empty ident <jtang@lenny.localdomain> not allowed
+### Failure in: 1:blackbox:0:git-annex init
+init failed
+Testing 1:blackbox:1:git-annex add:0
+Cases: 30 Tried: 8 Errors: 0 Failures: 1
+*** Please tell me who you are.
+</pre>
+
+I guess most users testing git-annex probably have a .gitconfig sitting in their home directories already so the above never cropped up. This failure was initially found in a clean and fresh install of a virtual machine with archlinux and repeated again on my archlinux laptop.
+
+Update: I pulled the master on my rhel5 test machine and moved my .gitconfig out of the way, the tests passes and continues but I still get a "warning message" from git.
+
+<pre>
+Testing 1:blackbox:3:git-annex unannex:1:with content
+Cases: 30 Tried: 12 Errors: 0 Failures: 0[master fce0cde] content removed from git annex
+ Committer: Jimmy Tang <jtang@removed.removed.tcd.ie>
+Your name and email address were configured automatically based
+on your username and hostname. Please check that they are accurate.
+You can suppress this message by setting them explicitly:
+
+ git config --global user.name "Your Name"
+ git config --global user.email you@example.com
+
+After doing this, you may fix the identity used for this commit with:
+
+ git commit --amend --reset-author
+
+ 2 files changed, 1 insertions(+), 2 deletions(-)
+ delete mode 120000 foo
+</pre>
+
+I guess it also depends a bit on how git figures out who it is is committing and how the machine in question is configured with hostnames and domain names.
+
+> Fixed that. [[done]] --[[Joey]]
diff --git a/doc/bugs/tests_failed_to_build_-_after_an_update_of_haskell_platform.mdwn b/doc/bugs/tests_failed_to_build_-_after_an_update_of_haskell_platform.mdwn
new file mode 100644
index 000000000..4088162e7
--- /dev/null
+++ b/doc/bugs/tests_failed_to_build_-_after_an_update_of_haskell_platform.mdwn
@@ -0,0 +1,23 @@
+I updated haskell platform, and now
+
+<pre>
+[jtang@x00 git-annex (master)]$ make test
+
+Assistant/Threads/NetWatcher.hs:26:2:
+ warning: #warning Building without dbus support; will poll for network connection changes [-Wcpp]
+
+Assistant/Threads/MountWatcher.hs:33:2:
+ warning: #warning Building without dbus support; will use mtab polling [-Wcpp]
+
+test.hs:11:8:
+ Could not find module `Test.HUnit.Tools'
+ Perhaps you meant Test.HUnit.Text (from HUnit-1.2.5.1)
+ Use -v to see a list of the files searched for.
+** failed to build the test suite
+make: *** [test] Error 1
+</pre>
+
+Looks like a missing dep somewhere with testpack or quickcheck... I haven't had time to figure it out yet, its not git-annex specific but I thought I might log it as a reminder for myself just in case if the osxapp is more borked than usual, I probably need to flush my .cabal directory of installed userland dependancies.
+
+> The testpack library has been broken by some other library changes. I
+> made changes in git yesterday to avoid using it. [[done]] --[[Joey]]
diff --git a/doc/bugs/tests_failed_to_build_-_after_an_update_of_haskell_platform/comment_1_20a6fe046111e9ae56fd4d9c9f41f536._comment b/doc/bugs/tests_failed_to_build_-_after_an_update_of_haskell_platform/comment_1_20a6fe046111e9ae56fd4d9c9f41f536._comment
new file mode 100644
index 000000000..cff4254c9
--- /dev/null
+++ b/doc/bugs/tests_failed_to_build_-_after_an_update_of_haskell_platform/comment_1_20a6fe046111e9ae56fd4d9c9f41f536._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.117"
+ subject="comment 1"
+ date="2012-12-10T19:18:59Z"
+ content="""
+Test.HUnit.Tools is part of testpack: <http://hackage.haskell.org/package/testpack>
+"""]]
diff --git a/doc/bugs/tests_failed_to_build_-_after_an_update_of_haskell_platform/comment_2_6fdc5f8b07908c6eda8a97690408f44e._comment b/doc/bugs/tests_failed_to_build_-_after_an_update_of_haskell_platform/comment_2_6fdc5f8b07908c6eda8a97690408f44e._comment
new file mode 100644
index 000000000..a8ed998cd
--- /dev/null
+++ b/doc/bugs/tests_failed_to_build_-_after_an_update_of_haskell_platform/comment_2_6fdc5f8b07908c6eda8a97690408f44e._comment
@@ -0,0 +1,45 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 2"
+ date="2012-12-11T08:29:07Z"
+ content="""
+yea its a problem with testpack rather than git-annex's test suite,
+
+<pre>
+[jtang@laplace git-annex (master)]$ cabal install testpack
+Resolving dependencies...
+Configuring testpack-2.1.2...
+Building testpack-2.1.2...
+Preprocessing library testpack-2.1.2...
+[1 of 3] Compiling Test.QuickCheck.Instances ( src/Test/QuickCheck/Instances.hs, dist/build/Test/QuickCheck/Instances.o )
+[2 of 3] Compiling Test.QuickCheck.Tools ( src/Test/QuickCheck/Tools.hs, dist/build/Test/QuickCheck/Tools.o )
+
+src/Test/QuickCheck/Tools.hs:33:9:
+ Warning: Fields of `MkResult' not initialised: abort
+ In the expression:
+ MkResult
+ {ok = Just (expected == actual), expect = True,
+ interrupted = False,
+ reason = \"Result: expected \"
+ ++ show expected ++ \", got \" ++ show actual,
+ stamp = [], callbacks = []}
+ In an equation for `@=?':
+ expected @=? actual
+ = MkResult
+ {ok = Just (expected == actual), expect = True,
+ interrupted = False,
+ reason = \"Result: expected \"
+ ++ show expected ++ \", got \" ++ show actual,
+ stamp = [], callbacks = []}
+[3 of 3] Compiling Test.HUnit.Tools ( src/Test/HUnit/Tools.hs, dist/build/Test/HUnit/Tools.o )
+
+src/Test/HUnit/Tools.hs:131:57:
+ `maxDiscard' is not a (visible) constructor field name
+
+src/Test/HUnit/Tools.hs:177:40: Not in scope: `maxDiscard'
+cabal: Error: some packages failed to install:
+testpack-2.1.2 failed during the building phase. The exception was:
+ExitFailure 1
+</pre>
+"""]]
diff --git a/doc/bugs/tests_failed_to_build_-_after_an_update_of_haskell_platform/comment_3_014474a133c7ff0131029d8721afc710._comment b/doc/bugs/tests_failed_to_build_-_after_an_update_of_haskell_platform/comment_3_014474a133c7ff0131029d8721afc710._comment
new file mode 100644
index 000000000..58bbbd91f
--- /dev/null
+++ b/doc/bugs/tests_failed_to_build_-_after_an_update_of_haskell_platform/comment_3_014474a133c7ff0131029d8721afc710._comment
@@ -0,0 +1,46 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn7gQ1zZDdWhXy9H51W2krZYShNmKL3qfM"
+ nickname="Karsten"
+ subject="Testpack install fails on ubuntu 12.04"
+ date="2013-02-28T10:42:36Z"
+ content="""
+The current release (git-annex-4.20130227, via cabal) fails to install because testpack-2.1.2 fails to install:
+
+ karsten@vdr1:~$ cabal install --bindir $HOME/bin git-annex
+ Resolving dependencies...
+ Configuring testpack-2.1.2...
+ Building testpack-2.1.2...
+ Preprocessing library testpack-2.1.2...
+ [1 of 3] Compiling Test.QuickCheck.Instances ( src/Test/QuickCheck/Instances.hs, dist/build/Test/QuickCheck/Instances.o )
+ [2 of 3] Compiling Test.QuickCheck.Tools ( src/Test/QuickCheck/Tools.hs, dist/build/Test/QuickCheck/Tools.o )
+
+ src/Test/QuickCheck/Tools.hs:33:9:
+ Warning: Fields of `MkResult' not initialised: abort
+ In the expression:
+ MkResult
+ {ok = Just (expected == actual), expect = True,
+ interrupted = False,
+ reason = \"Result: expected \"
+ ++ show expected ++ \", got \" ++ show actual,
+ stamp = [], callbacks = []}
+ In an equation for `@=?':
+ expected @=? actual
+ = MkResult
+ {ok = Just (expected == actual), expect = True,
+ interrupted = False,
+ reason = \"Result: expected \"
+ ++ show expected ++ \", got \" ++ show actual,
+ stamp = [], callbacks = []}
+ [3 of 3] Compiling Test.HUnit.Tools ( src/Test/HUnit/Tools.hs, dist/build/Test/HUnit/Tools.o )
+
+ src/Test/HUnit/Tools.hs:131:57:
+ `maxDiscard' is not a (visible) constructor field name
+
+ src/Test/HUnit/Tools.hs:177:40: Not in scope: `maxDiscard'
+ cabal: Error: some packages failed to install:
+ git-annex-4.20130227 depends on testpack-2.1.2 which failed to install.
+ testpack-2.1.2 failed during the building phase. The exception was:
+ ExitFailure 1
+
+Manually installing testpack gives Version testpack-2.1.2.1 which installs correctly. Maybe the dependencies should be updated?
+"""]]
diff --git a/doc/bugs/tests_failed_to_build_-_after_an_update_of_haskell_platform/comment_4_9c537e251dc99667fe87870804d802c2._comment b/doc/bugs/tests_failed_to_build_-_after_an_update_of_haskell_platform/comment_4_9c537e251dc99667fe87870804d802c2._comment
new file mode 100644
index 000000000..0a122efaf
--- /dev/null
+++ b/doc/bugs/tests_failed_to_build_-_after_an_update_of_haskell_platform/comment_4_9c537e251dc99667fe87870804d802c2._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 4"
+ date="2013-02-28T19:40:11Z"
+ content="""
+This is a closed bug from 2 months ago, it's the wrong place to report current problems.
+
+Anyway, I made changes in git last night to avoid using testpack, so breakage with it is no longer a concern.
+"""]]
diff --git a/doc/bugs/the_tip_at_commit_6cecc26206c4a539999b04664136c6f785211a41_disables_the_watch_command_on_OSX.mdwn b/doc/bugs/the_tip_at_commit_6cecc26206c4a539999b04664136c6f785211a41_disables_the_watch_command_on_OSX.mdwn
new file mode 100644
index 000000000..1ee4781d1
--- /dev/null
+++ b/doc/bugs/the_tip_at_commit_6cecc26206c4a539999b04664136c6f785211a41_disables_the_watch_command_on_OSX.mdwn
@@ -0,0 +1,22 @@
+The recent commit 6cecc26206c4a539999b04664136c6f785211a41 seems to have disabled the watch command on OSX, this certainly is the case when I try to run the webapp.
+
+The following fixes the makefile
+
+<pre>
+x00:git-annex jtang$ git diff
+diff --git a/Makefile b/Makefile
+index 9f312dc..4a74e71 100644
+--- a/Makefile
++++ b/Makefile
+@@ -27,7 +27,7 @@ endif
+ endif
+
+ PREFIX=/usr
+-GHCFLAGS=-O2 $(BASEFLAGS) $(FEATURES)
++GHCFLAGS=-O2 $(BASEFLAGS) $(FEATURES) $(OPTFLAGS)
+
+ ifdef PROFILE
+ GHCFLAGS=-prof -auto-all -rtsopts -caf-all -fforce-recomp $(BASEFLAGS) $(FEATURES) $(OPTFLAGS)
+</pre>
+
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/three_character_directories_created.mdwn b/doc/bugs/three_character_directories_created.mdwn
new file mode 100644
index 000000000..658ad3c20
--- /dev/null
+++ b/doc/bugs/three_character_directories_created.mdwn
@@ -0,0 +1,56 @@
+What steps will reproduce the problem?
+
+I don't know how, but this happened already a second time, I don't know how to reproduce this yet.
+
+What is the expected output? What do you see instead?
+
+There are many three character name directories created that look like the parts of a hash - and each contains a logfile.
+
+ % ls
+ 027
+ 1d1
+ 1e3
+ 232
+ 36e
+ 583
+ 5f6
+ 69c
+ 9ea
+ bd7
+ c46
+ d20
+ d48
+ f31
+ f88
+ uuid.log
+ [+the intended data directories]
+
+ % find 027/
+ 027/
+ 027//b73
+ 027//b73/SHA256-s10108928--3c3766aed8b66de9d0ef37820e0ddfba25f9463b37f30e25ceb5ce3cdf12db36.log
+
+ % cat f88/7c3/SHA256-s4100608--903530747dfdc7bc9d487d7cbd8ab09ddc1ffad52c08849d049c8a5ff5cfb854.log
+ 1351711677.187589s 1 2efd46d2-0e32-11e2-95fe-f73f09c6615e
+ 1351971337.667243s 1 ab50cd8a-11c0-11e2-934c-87e45f64e5c6
+
+What version of git-annex are you using? On what operating system?
+
+% git-annex version
+git-annex version: 3.20121017
+local repository version: 3
+default repository version: 3
+supported repository versions: 3
+upgrade supported from repository versions: 0 1 2
+
+OS X 10.6.8
+
+Please provide any additional information below.
+
+I use a symlink to the repository to change into it.
+
+> Closing this bug as user error. If the `git-annex` branch
+> gets merged into master by the user, then that adds all its log files
+> to master, and so they're visible as regular files. Solution: Don't do
+> that, or if you do that, use `git log --stat` to find the commit that
+> adds all those files, and `git revery` the commit. [[done]] --[[Joey]]
diff --git a/doc/bugs/three_character_directories_created/comment_1_dd91de24dab4f2eaded1f7d659869d4d._comment b/doc/bugs/three_character_directories_created/comment_1_dd91de24dab4f2eaded1f7d659869d4d._comment
new file mode 100644
index 000000000..158fa8e9e
--- /dev/null
+++ b/doc/bugs/three_character_directories_created/comment_1_dd91de24dab4f2eaded1f7d659869d4d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.27"
+ subject="comment 1"
+ date="2012-11-10T00:36:49Z"
+ content="""
+The three character directories, as well as the uuid.log file are supposed to stay in the git-annex branch. Perhaps you have somehow merged that branch into your master branch? I recommend you look at the history of your git repository to see how it happened. It seems very unlikely that git-annex did this.
+"""]]
diff --git a/doc/bugs/three_character_directories_created/comment_2_f6375964a6c8bb1e6c5b7238effca66d._comment b/doc/bugs/three_character_directories_created/comment_2_f6375964a6c8bb1e6c5b7238effca66d._comment
new file mode 100644
index 000000000..800a276f2
--- /dev/null
+++ b/doc/bugs/three_character_directories_created/comment_2_f6375964a6c8bb1e6c5b7238effca66d._comment
@@ -0,0 +1,62 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmmPHsszTlpa3s3x_LEzmEYkZfEmqq7IjU"
+ nickname="Jan"
+ subject="happened again"
+ date="2012-11-12T15:57:20Z"
+ content="""
+It just happened again to me, on another computer:
+
+<pre>
+ % git annex sync
+ (merging synced/git-annex into git-annex...)
+ commit
+ add PATH/FILE (checksum...) ok
+ ok
+ add PATH/SUBPATH/FILE (checksum...) ok
+ ok
+ (Recording state in git...)
+ [master 93c4526] git-annex automatic sync
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+ ok
+ merge synced/master
+ CONFLICT (modify/delete): PATH/FILE deleted in refs/heads/synced/master and modified in HEAD. Version HEAD of PATH/FILE left in tree.
+ Automatic merge failed; fix conflicts and then commit the result.
+ failed
+ pull origin
+ remote: Counting objects: 71, done.
+ remote: Compressing objects: 100% (51/51), done.
+ remote: Total 64 (delta 25), reused 52 (delta 13)
+ Unpacking objects: 100% (64/64), done.
+ From host:git/repo
+ 03d4b1f..c800e83 master -> origin/master
+ 61239fb..6d8ae6b git-annex -> origin/git-annex
+ 69914b0..61239fb synced/git-annex -> origin/synced/git-annex
+ 03d4b1f..2137ab9 synced/master -> origin/synced/master
+
+ error: 'merge' is not possible because you have unmerged files.
+ hint: Fix them up in the work tree,
+ hint: and then use 'git add/rm <file>' as
+ hint: appropriate to mark resolution and make a commit,
+ hint: or use 'git commit -a'.
+ fatal: Exiting because of an unresolved conflict.
+ failed
+ push origin
+ Counting objects: 26, done.
+ Delta compression using up to 4 threads.
+ Compressing objects: 100% (14/14), done.
+ Writing objects: 100% (17/17), 1.47 KiB, done.
+ Total 17 (delta 5), reused 0 (delta 0)
+ To host:git/repo.git
+ 6d8ae6b..37eb875 git-annex -> git-annex
+ ! [rejected] master -> synced/master (non-fast-forward)
+ error: failed to push some refs to 'host:git/repo.git'
+ To prevent you from losing history, non-fast-forward updates were rejected
+ Merge the remote changes (e.g. 'git pull') before pushing again. See the
+ 'Note about fast-forwards' section of 'git push --help' for details.
+ failed
+ git-annex: sync: 3 failed
+</pre>
+
+git status was showing all the 3 character directories and new files. I commited to git the path I actually wanted to commit, ran a git annex sync again and now my status is clean, but the directories are there. Am I doing something wrong this way?
+
+"""]]
diff --git a/doc/bugs/three_character_directories_created/comment_3_776e0a9b938d8b260a5111594b442536._comment b/doc/bugs/three_character_directories_created/comment_3_776e0a9b938d8b260a5111594b442536._comment
new file mode 100644
index 000000000..92f8f8892
--- /dev/null
+++ b/doc/bugs/three_character_directories_created/comment_3_776e0a9b938d8b260a5111594b442536._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn9JRcJ_69McoLFe5-dvTMdfS9rJpGy6JI"
+ nickname="Warren"
+ subject="this just happened to me as well"
+ date="2013-03-29T23:28:05Z"
+ content="""
+I was trying to undo some changes from another bare repo, and then all of a sudden the three letter directories popped up. I think the way I did this was to hard reset the master and git-annex branches to the same commit. I take it that was the wrong thing to do? I take it the git-annex and master branch should never be merged?
+"""]]
diff --git a/doc/bugs/three_character_directories_created/comment_4_e288bacdb336c4886adb6eeb4dca1e92._comment b/doc/bugs/three_character_directories_created/comment_4_e288bacdb336c4886adb6eeb4dca1e92._comment
new file mode 100644
index 000000000..b7ca8bc03
--- /dev/null
+++ b/doc/bugs/three_character_directories_created/comment_4_e288bacdb336c4886adb6eeb4dca1e92._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn9JRcJ_69McoLFe5-dvTMdfS9rJpGy6JI"
+ nickname="Warren"
+ subject="solved the problem"
+ date="2013-03-30T00:13:29Z"
+ content="""
+Just wanted to let future searchers know that I solved this problem by finding the most recent commit of the master that was not merged with the git-annex branch and hard resetting to that. I hard reset the git-annex branch to its most recent separate commit and now things seem to working again. By hard reset I mean the command \"git reset --hard <commit>\".
+"""]]
diff --git a/doc/bugs/three_character_directories_created/comment_5_359b80948ac92a0f1eb695599456486c._comment b/doc/bugs/three_character_directories_created/comment_5_359b80948ac92a0f1eb695599456486c._comment
new file mode 100644
index 000000000..6942efe52
--- /dev/null
+++ b/doc/bugs/three_character_directories_created/comment_5_359b80948ac92a0f1eb695599456486c._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 5"
+ date="2013-03-30T18:01:28Z"
+ content="""
+Clearly this can happen if the git-annex branch is merged into the master branch. I cannot think of any valid reason to want to do that. reset --hard git-annex would also do it; ditto.
+
+Inclined to close this bug as user error; I'm pretty sure git-annex does not contain a bug that makes it merge in the git-annex branch on its own. Basically the only change that could be made to git-annex to prevent this kind of user error is to move the git-annex branch so it's not under refs/heads, and so is not a visible branch. But then `git push` would not push it either, which needs to happen.
+"""]]
diff --git a/doc/bugs/three_way_sync_via_S3_and_Jabber.mdwn b/doc/bugs/three_way_sync_via_S3_and_Jabber.mdwn
new file mode 100644
index 000000000..e67291ca9
--- /dev/null
+++ b/doc/bugs/three_way_sync_via_S3_and_Jabber.mdwn
@@ -0,0 +1,119 @@
+## What steps will reproduce the problem?
+
+I wanted to setup a `~/Desktop/annex` synchronised between three machines, my home desktop (`dagon`), my work desktop (`zakaz`) and my laptop (`hastur`).
+
+I set this up via the annex interface, using my gmail account and Amazon S3.
+
+## What is the expected output? What do you see instead?
+
+I expected that anything dropped into `~/Desktop/annex` on any of the three machines would be synced to the other 2.
+
+I ran:
+<pre>
+ $ echo Created on `hostname` > `hostname`.txt on each of the three machines.
+</pre>
+
+What I ended up with was:
+
+* Home desktop (`dagon`): dagon.txt (ok)
+* Work desktop (`zakaz`): zakaz.txt (ok) and hastur.txt (broken link)
+* Laptop (`hastur`): hastur.txt (ok) and zakaz.txt (broken link)
+
+In each case the local file had been detected and annexed -- "(ok)" means it is a symlink to the annex.
+
+Manually running `git annex sync` on any of the machines didn't change anything. Running `git annex copy --auto --from=DesktopAnnex` on the Work desktop synced the broken hastur.txt but dagon.txt didn't appear. Running the same on my laptop did nothing. Likewise on my home desktop it did nothing. (I'm not sure if running stuff from the CLI is valid when the assistant is running, but I couldn't see a "force refresh" option in the UI)
+
+In the `git log --oneline` my laptop and Work machines both have:
+<pre>
+3f541e5 Merge commit 'refs/synced/552d29fe-4a86-11e2-819a-9f61585ee7a2/master'
+cbee12b
+dddc4f0
+d8854e7 Merge commit 'refs/synced/1167ef76-4791-11e2-9bfe-4319f44b8a5f/master'
+</pre>
+
+While my home desktop has:
+<pre>
+43a80d5 git-annex automatic sync
+46328db
+d8854e7 Merge commit 'refs/synced/1167ef76-4791-11e2-9bfe-4319f44b8a5f/master'
+</pre>
+
+There are other commits prior to d8854e7 which appear to be the same on all hosts. d8854e7 was committed in December when I first played with this stuff. All the commits after that were made today as part of the experiment above, with the exception of 43a80d5 on my home desktop with was the removal of a "Test.txt" created last year. This removal also didn't sync to the other two machines.
+
+git-annex status on my home desktop (dagon) shows:
+<pre>
+semitrusted repositories: 5
+ 00000000-0000-0000-0000-000000000001 -- web
+ 1167ef76-4791-11e2-9bfe-4319f44b8a5f -- annex on hastur
+ 54f6febc-4791-11e2-952f-13bd7a1c79f1 -- here (annex on dagon)
+ 552d29fe-4a86-11e2-819a-9f61585ee7a2 -- ian.james.campbell (annex on zakaz)
+ ad5c6a4c-4791-11e2-b9f0-53f8af10a9e6 -- DesktopAnnex
+</pre>
+(DesktopAnnex is the S3 remote, ian.james.campbell is my gmail username)
+
+However the webapp only shows 3 repos:
+<pre>
+ here (annex on dagon)
+ ian.james.campbell (annex on zakaz)
+ DesktopAnnex
+</pre>
+
+git-annex status on my laptop (hastur) shows only:
+<pre>
+ 00000000-0000-0000-0000-000000000001 -- web
+ 1167ef76-4791-11e2-9bfe-4319f44b8a5f -- here (ijc@hastur:~/Desktop/annex)
+ 54f6febc-4791-11e2-952f-13bd7a1c79f1 -- ian.james.campbell (ijc@dagon:~/Desktop/annex)
+ ad5c6a4c-4791-11e2-b9f0-53f8af10a9e6 -- DesktopAnnex
+</pre>
+
+while the webapp shows:
+<pre>
+ here (ijc@hastur:~/Desktop/annex)
+ ian.james.campbell (ijc@dagon:~/Desktop/annex)
+ DesktopAnnex
+</pre>
+
+Lastly on my work desktop (zakaz) annex status shows:
+<pre>
+ 00000000-0000-0000-0000-000000000001 -- web
+ 1167ef76-4791-11e2-9bfe-4319f44b8a5f -- annex on hastur
+ 54f6febc-4791-11e2-952f-13bd7a1c79f1 -- ian.james.campbell (annex on dagon)
+ 552d29fe-4a86-11e2-819a-9f61585ee7a2 -- here (annex on zakaz)
+ ad5c6a4c-4791-11e2-b9f0-53f8af10a9e6 -- DesktopAnnex
+</pre>
+
+The webapp shows:
+<pre>
+ here (annex on zakaz)
+ ian.james.campbell (annex on dagon)
+ DesktopAnnex
+</pre>
+
+git-annex sync on any of them shows:
+<pre>
+$ git annex sync
+commit
+# On branch master
+nothing to commit (working directory clean)
+ok
+pull ian.james.campbell
+fatal: Unable to find remote helper for 'xmpp'
+failed
+push ian.james.campbell
+fatal: Unable to find remote helper for 'xmpp'
+failed
+git-annex: sync: 2 failed
+</pre>
+
+## What version of git-annex are you using? On what operating system?
+
+3.20121211 on Debian Sid. All machines are amd64
+
+## Please provide any additional information below.
+
+I'm not 100% sure this sort of multiway synching is supposed to work, so maybe this is just as expected. If this isn't a bug you could consider it a feature request though ;-)
+
+This issue also made me wonder about how one would go about syncing multiple unrelated annexes via XMPP. Would you need a different gmail account for each? Maybe there is a trick similar to the email local+foo@ thing?
+
+> [[done]], turned out I left XMPP git push working,
+> but had not done all the stuff around it to get reliable syncing. Now have. --[[Joey]]
diff --git a/doc/bugs/three_way_sync_via_S3_and_Jabber/comment_10_fc5ec5505f141bb9135e772d1094bc4d._comment b/doc/bugs/three_way_sync_via_S3_and_Jabber/comment_10_fc5ec5505f141bb9135e772d1094bc4d._comment
new file mode 100644
index 000000000..c611b7d6e
--- /dev/null
+++ b/doc/bugs/three_way_sync_via_S3_and_Jabber/comment_10_fc5ec5505f141bb9135e772d1094bc4d._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 10"
+ date="2013-03-06T20:35:43Z"
+ content="""
+I've been revisiting the XMPP stuff this week, and today I fixed at least 3 problems that would keep XMPP sync from happening reliably. This would affect machines that are using XMPP and are sometimes disconnected from the net (or suspended). Nothing caused a sync to happen when restarting the assistant, or resuming from a network disconnection. This could result in both files not showing up, and file contents not being transferred, depending on the case hit.
+
+I think it explains everything in this bug report, hopefully.
+
+(All XMPP nodes sync with all other nodes, BTW.)
+"""]]
diff --git a/doc/bugs/three_way_sync_via_S3_and_Jabber/comment_11_0df2210c30dec6d88d7858d93eec19a3._comment b/doc/bugs/three_way_sync_via_S3_and_Jabber/comment_11_0df2210c30dec6d88d7858d93eec19a3._comment
new file mode 100644
index 000000000..0ed43cc41
--- /dev/null
+++ b/doc/bugs/three_way_sync_via_S3_and_Jabber/comment_11_0df2210c30dec6d88d7858d93eec19a3._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmhjlfoU21OiXKH_MXw75Uq5EsX7LJW5p0"
+ nickname="Ian"
+ subject="comment 11"
+ date="2013-03-10T08:33:26Z"
+ content="""
+Thanks Joey! I'll hopefully manage to give the new version a try after my current batch of traveling.
+
+From the sounds of things I can expect it to just work now, rather than requiring some manual step to kick it out of its current state?
+"""]]
diff --git a/doc/bugs/three_way_sync_via_S3_and_Jabber/comment_1_41682b2e72e657e0f23af244f8345e85._comment b/doc/bugs/three_way_sync_via_S3_and_Jabber/comment_1_41682b2e72e657e0f23af244f8345e85._comment
new file mode 100644
index 000000000..382dcee6a
--- /dev/null
+++ b/doc/bugs/three_way_sync_via_S3_and_Jabber/comment_1_41682b2e72e657e0f23af244f8345e85._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="comment 1"
+ date="2013-01-12T14:34:34Z"
+ content="""
+ fatal: Unable to find remote helper for 'xmpp'
+
+is probably why things are not working for you. git annex sync is not actually syncing because of that.
+"""]]
diff --git a/doc/bugs/three_way_sync_via_S3_and_Jabber/comment_2_c7b4ea9aea6839763eb8b89e8d6a5ad5._comment b/doc/bugs/three_way_sync_via_S3_and_Jabber/comment_2_c7b4ea9aea6839763eb8b89e8d6a5ad5._comment
new file mode 100644
index 000000000..5eea53d19
--- /dev/null
+++ b/doc/bugs/three_way_sync_via_S3_and_Jabber/comment_2_c7b4ea9aea6839763eb8b89e8d6a5ad5._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmhjlfoU21OiXKH_MXw75Uq5EsX7LJW5p0"
+ nickname="Ian"
+ subject="comment 2"
+ date="2013-01-12T14:47:07Z"
+ content="""
+@Justin,
+
+It seems to be synching a least something over this channel, e.g. my work desktop and laptop seem to be keeping the git side in sync at least (I think the broken symlinks appearing and the copy --from working show this?).
+
+In the pairing window (under Config->Share with a friend) it shows ian.james.campbell as being \"paired\" on all three machines.
+
+I have a feeling there isn't supposed to be a remote helper for xmpp and the assistant is expected to take care of this through other means, IOW I shouldn't be running `git annex sync` by hand at all.
+"""]]
diff --git a/doc/bugs/three_way_sync_via_S3_and_Jabber/comment_3_063f5e5e554ad6710f16394906d87616._comment b/doc/bugs/three_way_sync_via_S3_and_Jabber/comment_3_063f5e5e554ad6710f16394906d87616._comment
new file mode 100644
index 000000000..fd129a468
--- /dev/null
+++ b/doc/bugs/three_way_sync_via_S3_and_Jabber/comment_3_063f5e5e554ad6710f16394906d87616._comment
@@ -0,0 +1,33 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.238"
+ subject="comment 3"
+ date="2013-01-14T17:40:51Z"
+ content="""
+`git annex sync` cannot sync xmpp remotes. Only the assistant can do that. So that's a red herring indeed..
+
+I've replicated the same setup with 3 repositories all paired using a single jabber account.
+In my test, all 3 stay in sync, with any change to one git repository being synced to the other 2.
+
+I checked the XMPP sync protocol, and it doesn't use the UUIDs at all for XMPP syncing, so the fact that `.git/config` only has the UUID of one of the two repositories that is accessible via XMPP in this case, should not matter. That is, though, why the webapp only shows one of the other two repositories; it's using that UUID information.
+
+Dagon seems to be where the problem is occuring; it's not managing to sync out its changes via XMPP.
+I think the thing to do is create another new file on dagon, and look at its `.git/annex/daemon.log`.
+You should see two xmpp pushes happen, which would look rather like this:
+
+<pre>
+To xmpp::you@gmail.com
+ a7549be..011ccc2 git-annex -> refs/synced/9346f5a8-5e63-11e2-bd8b-77356d7f5bd0/git-annex
+ 3acca89..5123067 master -> refs/synced/9346f5a8-5e63-11e2-bd8b-77356d7f5bd0/master
+Counting objects: 12, done.
+Delta compression using up to 2 threads.
+Compressing objects: 100% (6/6), done.
+Writing objects: 100% (7/7), 622 bytes, done.
+Total 7 (delta 3), reused 0 (delta 0)
+To xmpp::you@gmail.com
+ a7549be..011ccc2 git-annex -> refs/synced/9346f5a8-5e63-11e2-bd8b-77356d7f5bd0/git-annex
+ 3acca89..5123067 master -> refs/synced/9346f5a8-5e63-11e2-bd8b-77356d7f5bd0/master
+</pre>
+
+If you don't see both pushes, maybe you'll see a useful error message.
+"""]]
diff --git a/doc/bugs/three_way_sync_via_S3_and_Jabber/comment_4_197ad39b4a46936afeeb04eb26cf1ef3._comment b/doc/bugs/three_way_sync_via_S3_and_Jabber/comment_4_197ad39b4a46936afeeb04eb26cf1ef3._comment
new file mode 100644
index 000000000..113e5f911
--- /dev/null
+++ b/doc/bugs/three_way_sync_via_S3_and_Jabber/comment_4_197ad39b4a46936afeeb04eb26cf1ef3._comment
@@ -0,0 +1,138 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmhjlfoU21OiXKH_MXw75Uq5EsX7LJW5p0"
+ nickname="Ian"
+ subject="comment 4"
+ date="2013-01-14T19:52:16Z"
+ content="""
+Looking at the annex on dagon this evening (before trying the experiment you suggested) I see that dagon.txt and hastur.txt are present and correct while zakaz.txt is a broken symlink. On both hastur and zakaz dagon.txt has appeared as a broken link. The git history is now in sync across all three devices (according to `git log`)
+
+I hadn't touched anything since I reported the bug. Looking in the .git/annex/daemon.log on dagon I see:
+
+<pre>
+scanning...) (started...)
+ No known network monitor available through dbus; falling back to polling
+Already up-to-date.
+Already up-to-date.
+Already up-to-date.
+fatal: unresolved deltas left after unpacking
+fatal: Unable to find remote helper for 'xmpp'
+To xmpp::ian.james.campbell@gmail.com
+ 794532e..ea12017 git-annex -> refs/synced/54f6febc-4791-11e2-952f-13bd7a1c79f1/git-annex
+ d8854e7..43a80d5 master -> refs/synced/54f6febc-4791-11e2-952f-13bd7a1c79f1/master
+(merging refs/synced/552d29fe-4a86-11e2-819a-9f61585ee7a2/git-annex into git-annex...)
+Updating 43a80d5..81afdca
+Fast-forward
+ hastur.txt | 1 +
+ zakaz.txt | 1 +
+ 2 files changed, 2 insertions(+)
+ create mode 120000 hastur.txt
+ create mode 120000 zakaz.txt
+(Recording state in git...)
+# On branch master
+nothing to commit (working directory clean)
+Already up-to-date.
+(Recording state in git...)
+# On branch master
+nothing to commit (working directory clean)
+To xmpp::ian.james.campbell@gmail.com
+ ea12017..a6efff5 git-annex -> refs/synced/54f6febc-4791-11e2-952f-13bd7a1c79f1/git-annex
+ 43a80d5..81afdca master -> refs/synced/54f6febc-4791-11e2-952f-13bd7a1c79f1/master
+(Recording state in git...)
+To xmpp::ian.james.campbell@gmail.com
+ a6efff5..931c11b git-annex -> refs/synced/54f6febc-4791-11e2-952f-13bd7a1c79f1/git-annex
+fatal: Unable to find remote helper for 'xmpp'
+Everything up-to-date
+fatal: Unable to find remote helper for 'xmpp'
+Everything up-to-date
+fatal: Unable to find remote helper for 'xmpp'
+Everything up-to-date
+fatal: Unable to find remote helper for 'xmpp'
+git-annex: /home/ijc/Desktop/annex/.git/annex/tmp/xmppgit/git-remote-xmpp: openFile: resource busy (file is locked)
+fatal: The remote end hung up unexpectedly
+error: Ref refs/synced/552d29fe-4a86-11e2-819a-9f61585ee7a2/git-annex is at 931c11bc8f974934026f005ac63596d078e044ea but expected 8da50426cced18713b1deb8ea6bb0420cadf1076
+error: Ref refs/synced/552d29fe-4a86-11e2-819a-9f61585ee7a2/master is at 81afdca7c69e689d34cc3fc729e1e4ec5d0fcc33 but expected 3f541e58b726ef2f46bd55bfb8e955e1418b33cb
+Already up-to-date.
+fatal: Unable to find remote helper for 'xmpp'
+fatal: cannot exec 'git-remote-xmpp': Text file busy
+fatal: The remote end hung up unexpectedly
+error: Ref refs/synced/552d29fe-4a86-11e2-819a-9f61585ee7a2/git-annex is at 931c11bc8f974934026f005ac63596d078e044ea but expected 8da50426cced18713b1deb8ea6bb0420cadf1076
+error: Ref refs/synced/552d29fe-4a86-11e2-819a-9f61585ee7a2/master is at 81afdca7c69e689d34cc3fc729e1e4ec5d0fcc33 but expected 3f541e58b726ef2f46bd55bfb8e955e1418b33cb
+fatal: Unable to find remote helper for 'xmpp'
+Everything up-to-date
+fatal: Unable to find remote helper for 'xmpp'
+Everything up-to-date
+fatal: Unable to find remote helper for 'xmpp'
+git-annex: <socket: 8>: hWaitForInput: resource vanished (Connection reset by peer)
+fatal: Unable to find remote helper for 'xmpp'
+git-annex: <socket: 8>: hPutBuf: resource vanished (Broken pipe)
+git-annex: forkProcess: interrupted
+</pre>
+
+I also notice that the annex assistant doesn't seem to be running on dagon any more and the webapp window says \"git annex has shutdown, you can now close this window\". The assistant is running on zakaz and hastur.
+
+On dagon I ran `/usr/bin/git-annex assistant --autostart`. THe daemon.log now contains:
+<pre>
+(scanning...) (started...)
+ No known network monitor available through dbus; falling back to polling
+Already up-to-date.
+Already up-to-date.
+Already up-to-date.
+drop DesktopAnnex hastur.txt (gpg) ok
+</pre>
+I suppose this makes sense since hastur.txt is the only file present on all three devices, so it makes sense to remove it from the transfer repo.
+
+On zakaz the daemon.log is full of things like:
+<pre>
+gpg: cannot open tty `/dev/tty': No such device or address
+Already up-to-date.
+gpg: cannot open tty `/dev/tty': No such device or address
+fatal: protocol error: expected sha/ref, got '^A000eunpack ok
+0042ok refs/synced/552d29fe-4a86-11e2-819a-9f61585ee7a2/git-annex
+003fok refs/synced/552d29fe-4a86-11e2-819a-9f61585ee7a2/master
+0000'
+send-pack: protocol error: bad band #56
+fatal: The remote end hung up unexpectedly
+fatal: The remote end hung up unexpectedly
+fatal: Unable to find remote helper for 'xmpp'
+gpg: cannot open tty `/dev/tty': No such device or address
+gpg: cannot open tty `/dev/tty': No such device or address
+fatal: The remote end hung up unexpectedly
+</pre>
+There are lots of the tty message and also some `git-annex: fd:97: hClose: resource vanished (Broken pipe)`.
+
+Hastur doesn't seem to have a daemon.log, although the daemon is running AFAICT.
+
+BTW something else I noticed is that there are quite a few defunct git children of the annex processes.
+
+e.g. on dagon `ps auxf | grep [g]it`:
+<pre>
+ijc 8792 0.0 0.3 157396 29752 ? Sl 19:40 0:00 git-annex assistant
+ijc 8795 0.0 0.0 0 0 ? Z 19:40 0:00 \_ [git] <defunct>
+ijc 8817 0.0 0.0 0 0 ? Z 19:40 0:00 \_ [git] <defunct>
+ijc 8874 0.0 0.0 14156 1332 ? S 19:41 0:00 \_ git --git-dir=/home/ijc/Desktop/annex/.git --work-tree=/home/ijc/Desktop/annex cat-file --batch
+ijc 8875 0.0 0.0 14132 1100 ? S 19:41 0:00 \_ git --git-dir=/home/ijc/Desktop/annex/.git --work-tree=/home/ijc/Desktop/annex check-attr -z --stdin annex.backend annex.numcopies --
+ijc 8908 0.0 0.0 0 0 ? Z 19:41 0:00 \_ [git] <defunct>
+</pre>
+
+(I only restarted the daemon just now)
+
+On zakaz:
+<pre>
+ianc 32004 0.0 0.5 229620 21708 ? Sl Jan12 3:04 git-annex assistant
+ianc 32007 0.0 0.0 0 0 ? Z Jan12 0:00 \_ [git] <defunct>
+ianc 32021 0.0 0.0 0 0 ? Z Jan12 0:00 \_ [git] <defunct>
+ianc 32106 0.0 0.0 0 0 ? Z Jan12 0:00 \_ [git] <defunct>
+ianc 32107 0.0 0.0 13652 924 ? S Jan12 0:00 \_ git --git-dir=/home/ianc/Desktop/annex/.git --work-tree=/home/ianc/Desktop/annex check-attr -z --stdin annex.backend annex.numcopies --
+ianc 32113 0.0 0.0 13652 1156 ? S Jan12 0:00 \_ git --git-dir=/home/ianc/Desktop/annex/.git --work-tree=/home/ianc/Desktop/annex cat-file --batch
+ianc 32258 0.0 0.0 0 0 ? Z Jan12 0:00 \_ [git] <defunct>
+ianc 32377 0.0 0.0 0 0 ? Z Jan12 0:00 \_ [git] <defunct>
+ianc 453 0.0 0.0 0 0 ? Z Jan12 0:00 \_ [git] <defunct>
+ianc 530 0.0 0.0 0 0 ? Z Jan12 0:00 \_ [git] <defunct>
+ianc 6681 0.0 0.0 0 0 ? Z Jan13 0:00 \_ [git] <defunct>
+ianc 6697 0.0 0.0 0 0 ? Z Jan13 0:00 \_ [git] <defunct>
+ianc 32232 0.0 0.4 128952 16340 ? Sl Jan12 0:00 git-annex xmppgit
+ianc 32239 0.0 0.4 128952 16340 ? Sl Jan12 0:00 git-annex xmppgit
+</pre>
+
+I'm going to create a new file on dagon as requested now. I'll post the results in a separate comment.
+"""]]
diff --git a/doc/bugs/three_way_sync_via_S3_and_Jabber/comment_5_0b0d829ccd255be0177ae9d8f6b10e63._comment b/doc/bugs/three_way_sync_via_S3_and_Jabber/comment_5_0b0d829ccd255be0177ae9d8f6b10e63._comment
new file mode 100644
index 000000000..045139544
--- /dev/null
+++ b/doc/bugs/three_way_sync_via_S3_and_Jabber/comment_5_0b0d829ccd255be0177ae9d8f6b10e63._comment
@@ -0,0 +1,61 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmhjlfoU21OiXKH_MXw75Uq5EsX7LJW5p0"
+ nickname="Ian"
+ subject="comment 5"
+ date="2013-01-14T20:04:02Z"
+ content="""
+Here is the result of running `echo Foo > ~/Desktop/annex/dagon2.txt` on dagon.
+
+In dagon's daemon.log:
+<pre>
+add dagon2.txt (checksum...) (Recording state in git...)
+(Recording state in git...)
+Already up-to-date.
+To xmpp::ian.james.campbell@gmail.com
+ 0bf7dc2..0182e26 git-annex -> refs/synced/54f6febc-4791-11e2-952f-13bd7a1c79f1/git-annex
+ c1e1f70..2711f11 master -> refs/synced/54f6febc-4791-11e2-952f-13bd7a1c79f1/master
+(merging refs/synced/1167ef76-4791-11e2-9bfe-4319f44b8a5f/git-annex into git-annex...)
+Already up-to-date.
+</pre>
+
+Nothing appeared in zakaz's log. As I mentioned in the previous comment hastur doesn't seem to have a log (should this worry me?).
+
+The new file appeared on dagon and hastur but not zakaz (not even as a broken link).
+
+I tried a couple more times (dagon3 and dagon4) with the same effect.
+
+Since zakaz now appears to be the host which is playing up I then tried `echo Foo > zakaz2.2txt` on zakaz.
+
+The log on zakaz said:
+<pre>
+add zakaz2.2txt (checksum...) gpg: cannot open tty `/dev/tty': No such device or address
+gpg: cannot open tty `/dev/tty': No such device or address
+(Recording state in git...)
+(Recording state in git...)
+gpg: cannot open tty `/dev/tty': No such device or address
+gpg: cannot open tty `/dev/tty': No such device or address
+</pre>
+
+and dagon:
+<pre>
+(merging refs/synced/552d29fe-4a86-11e2-819a-9f61585ee7a2/git-annex into git-annex...)
+(Recording state in git...)
+Merge made by the 'recursive' strategy.
+ zakaz2.2txt | 1 +
+ 1 file changed, 1 insertion(+)
+ create mode 120000 zakaz2.2txt
+(Recording state in git...)
+# On branch master
+nothing to commit (working directory clean)
+(merging refs/synced/1167ef76-4791-11e2-9bfe-4319f44b8a5f/git-annex into git-annex...)
+(Recording state in git...)
+Already up-to-date!
+Merge made by the 'recursive' strategy.
+Already up-to-date.
+To xmpp::ian.james.campbell@gmail.com
+ d220ce6..4e8647f git-annex -> refs/synced/54f6febc-4791-11e2-952f-13bd7a1c79f1/git-annex
+ b2a84e4..ef0a200 master -> refs/synced/54f6febc-4791-11e2-952f-13bd7a1c79f1/master
+</pre>
+
+However zakaz2.2txt is a broken symlink on both hastur and dagon.
+"""]]
diff --git a/doc/bugs/three_way_sync_via_S3_and_Jabber/comment_6_37a8e19440c764317589bc4248cbccdf._comment b/doc/bugs/three_way_sync_via_S3_and_Jabber/comment_6_37a8e19440c764317589bc4248cbccdf._comment
new file mode 100644
index 000000000..827ca8f63
--- /dev/null
+++ b/doc/bugs/three_way_sync_via_S3_and_Jabber/comment_6_37a8e19440c764317589bc4248cbccdf._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmhjlfoU21OiXKH_MXw75Uq5EsX7LJW5p0"
+ nickname="Ian"
+ subject="comment 6"
+ date="2013-01-14T20:14:57Z"
+ content="""
+FYI I've waited a bit and zakaz2.2txt hasn't been syned to either of the other two machines (as appeared to happen after the initial report). Obviously I could wait longer
+
+Just thought I'd mention it since I'm going offline now which is going to involve hibernating hastur (I suppose I should have mentioned that I do this quite regularly in case it matters). dagon and zakaz will remain on and connected to the net (just me and hastur which are going offline).
+"""]]
diff --git a/doc/bugs/three_way_sync_via_S3_and_Jabber/comment_7_12eb333327d31ca2bfee3f3c5e26d641._comment b/doc/bugs/three_way_sync_via_S3_and_Jabber/comment_7_12eb333327d31ca2bfee3f3c5e26d641._comment
new file mode 100644
index 000000000..e93738bd9
--- /dev/null
+++ b/doc/bugs/three_way_sync_via_S3_and_Jabber/comment_7_12eb333327d31ca2bfee3f3c5e26d641._comment
@@ -0,0 +1,24 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmhjlfoU21OiXKH_MXw75Uq5EsX7LJW5p0"
+ nickname="Ian"
+ subject="comment 7"
+ date="2013-01-28T19:51:06Z"
+ content="""
+I've upgraded to 3.20130124 and everything appears to be fine now.
+
+However .git/annex/daemon.log has loads of
+<pre>
+usage: git rm [options] [--] <file>...
+
+ -n, --dry-run dry run
+ -q, --quiet do not list removed files
+ --cached only remove from the index
+ -f, --force override the up-to-date check
+ -r allow recursive removal
+ --ignore-unmatch exit with a zero status even if nothing matched
+
+user error (xargs [\"-0\",\"git\",\"--git-dir=/home/ianc/Desktop/annex/.git\",\"--work-tree=/home/ianc/Desktop/annex\",\"rm\",\"--quiet\",\"-f\",\"--\"] exited 123)
+</pre>
+
+I suspect you might want xargs --no-run-if-empty?
+"""]]
diff --git a/doc/bugs/three_way_sync_via_S3_and_Jabber/comment_8_e6b1084b2f18d8e536c8692e165754a3._comment b/doc/bugs/three_way_sync_via_S3_and_Jabber/comment_8_e6b1084b2f18d8e536c8692e165754a3._comment
new file mode 100644
index 000000000..0e91f47fb
--- /dev/null
+++ b/doc/bugs/three_way_sync_via_S3_and_Jabber/comment_8_e6b1084b2f18d8e536c8692e165754a3._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.3.125"
+ subject="comment 8"
+ date="2013-02-05T19:13:34Z"
+ content="""
+I don't know of anything that changed in XMPP handling between 3.20121211 and 3.20130124, so am hesitant to close this bug report.
+
+
+
+(I did put in a fix to avoid it queueing `git rm` when there were no files to remove.)
+"""]]
diff --git a/doc/bugs/three_way_sync_via_S3_and_Jabber/comment_9_2120a1c3e5f490a55f68bb1bef5efd0d._comment b/doc/bugs/three_way_sync_via_S3_and_Jabber/comment_9_2120a1c3e5f490a55f68bb1bef5efd0d._comment
new file mode 100644
index 000000000..78ec89935
--- /dev/null
+++ b/doc/bugs/three_way_sync_via_S3_and_Jabber/comment_9_2120a1c3e5f490a55f68bb1bef5efd0d._comment
@@ -0,0 +1,183 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmhjlfoU21OiXKH_MXw75Uq5EsX7LJW5p0"
+ nickname="Ian"
+ subject="comment 9"
+ date="2013-02-07T21:11:39Z"
+ content="""
+It seems I may have spoken to soon, currently zakaz (the work machine) is out of sync with the other two again.
+
+daemon.log has a bunch of these:
+<pre>
+ [2013-02-07 19:42:56 GMT] NetWatcherFallback: Syncing with ian.james.campbell DesktopAnnex web
+ fatal: Unable to find remote helper for 'xmpp'
+</pre>
+on zakaz and dagon.
+
+hastur does not have these messages in daemon.log but I just had to restart the assistant because it seems to have crashed. daemon.log.1 ends:
+<pre>
+ [2013-02-03 14:07:51 GMT] NetWatcherFallback: Syncing with ian.james.campbell DesktopAnnex web
+ fatal: Unable to find remote helper for 'xmpp'
+ git-annex: <socket: 99>: hPutBuf: resource vanished (Broken pipe)
+ git-annex: forkProcess: interrupted
+</pre>
+
+zakaz is stuck at commit 81768b7, dagon and hastur have 8240e2b, with a few commits in between:
+<pre>
+$ git log --oneline 81768b74892ee5ec7f5a9ae15fb65d81c8a4d29d^..master
+8240e2b Merge commit 'refs/synced/1167ef76-4791-11e2-9bfe-4319f44b8a5f/master'
+e6ae87e Merge commit 'refs/synced/1167ef76-4791-11e2-9bfe-4319f44b8a5f/master'
+7bee777
+3871031
+c86bed3
+81768b7
+</pre>
+
+Before all the \"cannot find remote helper messages\" in zakaz's daemon.log I see:
+<pre>
+[2013-01-30 14:54:29 GMT] Pusher: Syncing with ian.james.campbell
+(Recording state in git...)
+
+Already up-to-date.
+To xmpp::ian.james.campbell@gmail.com
+ 871b9c0..4585d72 git-annex -> refs/synced/552d29fe-4a86-11e2-819a-9f61585ee7a2/git-annex
+ 6dadc6d..81768b7 master -> refs/synced/552d29fe-4a86-11e2-819a-9f61585ee7a2/master
+To xmpp::ian.james.campbell@gmail.com
+ 871b9c0..4585d72 git-annex -> refs/synced/552d29fe-4a86-11e2-819a-9f61585ee7a2/git-annex
+ 6dadc6d..81768b7 master -> refs/synced/552d29fe-4a86-11e2-819a-9f61585ee7a2/master
+(merging refs/synced/54f6febc-4791-11e2-952f-13bd7a1c79f1/git-annex into git-annex...)
+
+Already up-to-date.
+(merging refs/synced/54f6febc-4791-11e2-952f-13bd7a1c79f1/git-annex into git-annex...)
+[2013-01-30 15:48:10 GMT] NetWatcherFallback: Syncing with ian.james.campbell DesktopAnnex web
+fatal: Unable to find remote helper for 'xmpp'
+fatal: The remote end hung up unexpectedly
+To xmpp::ian.james.campbell@gmail.com
+ 4585d72..7d0d48f git-annex -> refs/synced/552d29fe-4a86-11e2-819a-9f61585ee7a2/git-annex
+error: failed to push some refs to 'xmpp::ian.james.campbell@gmail.com'
+[2013-01-30 16:48:10 GMT] NetWatcherFallback: Syncing with ian.james.campbell DesktopAnnex web
+fatal: Unable to find remote helper for 'xmpp'
+Everything up-to-date
+</pre>
+
+The last 3 lines are repeated, interspersed with the daily sanity checks (no errors).
+
+On hastur I see:
+<pre>
+[2013-01-30 15:33:44 GMT] NetWatcherFallback: Syncing with ian.james.campbell DesktopAnnex web
+fatal: Unable to find remote helper for 'xmpp'
+To xmpp::ian.james.campbell@gmail.com
+ cec23e5..4585d72 git-annex -> refs/synced/1167ef76-4791-11e2-9bfe-4319f44b8a5f/git-annex
+To xmpp::ian.james.campbell@gmail.com
+ 871b9c0..4585d72 git-annex -> refs/synced/1167ef76-4791-11e2-9bfe-4319f44b8a5f/git-annex
+ 6dadc6d..81768b7 master -> refs/synced/1167ef76-4791-11e2-9bfe-4319f44b8a5f/master
+fatal: The remote end hung up unexpectedly
+[2013-01-31 10:46:18 GMT] NetWatcherFallback: Syncing with ian.james.campbell DesktopAnnex web
+fatal: Unable to find remote helper for 'xmpp'
+[2013-01-31 10:46:25 GMT] NetWatcher: Syncing with ian.james.campbell DesktopAnnex web
+fatal: Unable to find remote helper for 'xmpp'
+(Recording state in git...)
+(Recording state in git...)
+(Recording state in git...)
+
+(merging refs/synced/552d29fe-4a86-11e2-819a-9f61585ee7a2/git-annex into git-annex...)
+
+git-annex: <socket: 52>: hWaitForInput: resource vanished (Connection reset by peer)
+</pre>
+
+and on dagon
+<pre>
+[2013-01-30 14:28:41 GMT] NetWatcherFallback: Syncing with ian.james.campbell DesktopAnnex web
+fatal: Unable to find remote helper for 'xmpp'
+Everything up-to-date
+fatal: The remote end hung up unexpectedly
+Updating 6dadc6d..81768b7
+Fast-forward
+ 2013-02-fosdem-evolving-xen-paravirtualisation.txt | 1 +
+ 1 file changed, 1 insertion(+)
+ create mode 120000 2013-02-fosdem-evolving-xen-paravirtualisation.txt
+[2013-01-30 14:56:34 GMT] Committer: Committing changes to git
+# On branch master
+nothing to commit (working directory clean)
+[2013-01-30 14:56:36 GMT] Pusher: Syncing with ian.james.campbell
+[2013-01-30 14:56:36 GMT] Transferr: Downloaded 2013-02-f..ation.txt
+[2013-01-30 14:56:38 GMT] Pusher: Syncing with ian.james.campbell
+fatal: Unable to create '/home/ijc/Desktop/annex/.git/refs/heads/synced/master.lock': File exists.
+
+If no other git process is currently running, this probably means a
+git process crashed in this repository earlier. Make sure no other git
+process is running and remove the file manually to continue.
+(merging refs/synced/552d29fe-4a86-11e2-819a-9f61585ee7a2/git-annex into git-annex...)
+
+(Recording state in git...)
+(Recording state in git...)
+git-annex: failed to update refs/heads/synced/master
+fatal: Unable to create '/home/ijc/Desktop/annex/.git/refs/heads/synced/master.lock': File exists.
+If no other git process is currently running, this probably means a
+git process crashed in this repository earlier. Make sure no other git
+process is running and remove the file manually to continue.
+fatal: Unable to create '/home/ijc/Desktop/annex/.git/refs/heads/synced/master.lock': File exists.
+
+If no other git process is currently running, this probably means a
+git process crashed in this repository earlier. Make sure no other git
+process is running and remove the file manually to continue.
+git-annex: failed to update refs/heads/synced/master
+git-annex: failed to update refs/heads/synced/master
+Already up-to-date.
+To xmpp::ian.james.campbell@gmail.com
+ 871b9c0..8b8b935 git-annex -> refs/synced/54f6febc-4791-11e2-952f-13bd7a1c79f1/git-annex
+ 6dadc6d..81768b7 master -> refs/synced/54f6febc-4791-11e2-952f-13bd7a1c79f1/master
+
+drop DesktopAnnex ./2013-02-fosdem-evolving-xen-paravirtualisation.txt (gpg) [2013-01-30 15:28:41 GMT] NetWatcherFallback: Syncing with ian.james.campbell DesktopAnnex web
+fatal: Unable to find remote helper for 'xmpp'
+To xmpp::ian.james.campbell@gmail.com
+ 8b8b935..7d0d48f git-annex -> refs/synced/54f6febc-4791-11e2-952f-13bd7a1c79f1/git-annex
+Already up-to-date.
+</pre>
+
+It seems like something was up here but it recovered? All 3 managed to sync on 81768b7.
+
+Next on hastur I see:
+<pre>
+[2013-02-01 10:43:18 GMT] Committer: Committing changes to git
+[2013-02-01 10:43:18 GMT] Pusher: Syncing with ian.james.campbell
+Already up-to-date.
+[2013-02-01 10:43:19 GMT] Committer: Committing changes to git
+To xmpp::ian.james.campbell@gmail.com
+ 81768b7..3871031 master -> refs/synced/1167ef76-4791-11e2-9bfe-4319f44b8a5f/master
+[2013-02-01 10:43:20 GMT] Pusher: Syncing with ian.james.campbell
+Already up-to-date.
+To xmpp::ian.james.campbell@gmail.com
+ 3871031..7bee777 master -> refs/synced/1167ef76-4791-11e2-9bfe-4319f44b8a5f/master
+Updating 7bee777..8240e2b
+Fast-forward
+ Xen at FOSDEM.docx | 1 +
+ 1 file changed, 1 insertion(+)
+ create mode 120000 Xen at FOSDEM.docx
+</pre>
+
+And on dagon
+<pre>
+[2013-02-01 10:45:52 GMT] Committer: Committing changes to git
+(Recording state in git...)
+# On branch master
+nothing to commit (working directory clean)
+[2013-02-01 10:45:53 GMT] Pusher: Syncing with ian.james.campbell
+To xmpp::ian.james.campbell@gmail.com
+ fc4ad88..70a6877 git-annex -> refs/synced/54f6febc-4791-11e2-952f-13bd7a1c79f1/git-annex
+ 5e83708..8240e2b master -> refs/synced/54f6febc-4791-11e2-952f-13bd7a1c79f1/master
+
+Already up-to-date.
+Everything up-to-date
+(merging refs/synced/1167ef76-4791-11e2-9bfe-4319f44b8a5f/git-annex into git-annex...)
+
+Already up-to-date.
+
+</pre>
+(5e83708 is 81768b7~2)
+
+However there is nothing in the logs on zakaz about moving on from 81768b7. The last interesting message is the \"[2013-01-30 15:48:10 GMT\" one above.
+
+is the XMPP peering supposed to be fully connected (i.e. each node is talking to both the others) or would it be expected that one of the nodes would be in the middle of the other two acting as a relay?
+
+I'm wondering about that because hastur is frequently suspended. I can't quite remember but I think when I set this up I peered dagon<->hastur at home and then while I was at work I peered zakaz<->hastur. That would seem to suggest that hastur would have ended up as the man in the middle. TBH I can't quite recall what the setup process involves, so maybe I'm talking nonsense. I think I went into the \"Share with a friend\" page and shared with myself.
+"""]]
diff --git a/doc/bugs/tmp_file_handling.mdwn b/doc/bugs/tmp_file_handling.mdwn
new file mode 100644
index 000000000..9db932e57
--- /dev/null
+++ b/doc/bugs/tmp_file_handling.mdwn
@@ -0,0 +1,13 @@
+git-annex deletes all tmp files on shutdown, if everything succeeded.
+This presents 2 problems:
+
+1. If git-annex is rsyncing something and another one is run, it will
+ delete the running instance's tmp files.
+2. If a long-running rsync transfer is interrupted partway through, the
+ tmp file was expensive to obtain, and one needs to avoid running
+ git-annex to do anything else until that transfer can be resumed and
+ finished.
+
+--[[Joey]]
+
+[[done]]
diff --git a/doc/bugs/tmp_file_handling/comment_1_0300c11ee3f94a9e7c832671e16f5511._comment b/doc/bugs/tmp_file_handling/comment_1_0300c11ee3f94a9e7c832671e16f5511._comment
new file mode 100644
index 000000000..244e580b2
--- /dev/null
+++ b/doc/bugs/tmp_file_handling/comment_1_0300c11ee3f94a9e7c832671e16f5511._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://www.openid.albertlash.com/openid/"
+ ip="74.96.185.87"
+ subject="What to do?"
+ date="2012-10-24T15:47:16Z"
+ content="""
+I've got a stale .git/annex/tmp/rsynctmp file that just won't go away, and I think its because I cancelled an in-progress rsync, then did something else, as you describe.
+
+Is it ok to manually remove the file?
+
+Thanks!
+Albert
+"""]]
diff --git a/doc/bugs/tmp_file_handling/comment_2_cc14c7a79a544e47654e4cd8abc85edd._comment b/doc/bugs/tmp_file_handling/comment_2_cc14c7a79a544e47654e4cd8abc85edd._comment
new file mode 100644
index 000000000..d6ae5bcf0
--- /dev/null
+++ b/doc/bugs/tmp_file_handling/comment_2_cc14c7a79a544e47654e4cd8abc85edd._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.23"
+ subject="comment 2"
+ date="2012-10-24T15:50:40Z"
+ content="""
+`rsynctmp` is only used when sending files to a rsync special remote. You can certainly delete it if you got a stale one, but the next time a file is sent to a rsync special remote it should delete it anyway.
+"""]]
diff --git a/doc/bugs/touch.hsc_has_problems_on_non-linux_based_systems.mdwn b/doc/bugs/touch.hsc_has_problems_on_non-linux_based_systems.mdwn
new file mode 100644
index 000000000..118f6fbb7
--- /dev/null
+++ b/doc/bugs/touch.hsc_has_problems_on_non-linux_based_systems.mdwn
@@ -0,0 +1,19 @@
+It seems that commit bc5c54c987f548505a3877e8a0e460abe0b2a081 introduced some linux specific things...
+
+<pre>
+hsc2hs Touch.hsc
+Touch.hsc: In function ‘main’:
+Touch.hsc:46: error: ‘UTIME_OMIT’ undeclared (first use in this function)
+Touch.hsc:46: error: (Each undeclared identifier is reported only once
+Touch.hsc:46: error: for each function it appears in.)
+Touch.hsc:48: error: ‘UTIME_NOW’ undeclared (first use in this function)
+Touch.hsc:67: error: ‘AT_FDCWD’ undeclared (first use in this function)
+Touch.hsc:68: error: ‘AT_SYMLINK_NOFOLLOW’ undeclared (first use in this function)
+compiling Touch_hsc_make.c failed
+command was: /usr/bin/gcc -c -m32 -I/Library/Frameworks/GHC.framework/Versions/612/usr/lib/ghc-6.12.3/include/ Touch_hsc_make.c -o Touch_hsc_make.o
+make: *** [Touch.hs] Error 1
+</pre>
+
+I dug around the OSX documentation and fcntl.h header file and it seems that UTIME_OMIT, UTIME_NOW, AT_FDCWD and AT_SYMLINK_NOFOLLOW aren't defined (at least on OSX). I suspect the BSD's in general will have problems compiling git-annex.
+
+[[!meta title="annexed symlink mtime matching code is disabled on non-linux systems; needs testing"]]
diff --git a/doc/bugs/touch.hsc_has_problems_on_non-linux_based_systems/comment_1_1d38283c9ea87174f3bbef9a58f5cb88._comment b/doc/bugs/touch.hsc_has_problems_on_non-linux_based_systems/comment_1_1d38283c9ea87174f3bbef9a58f5cb88._comment
new file mode 100644
index 000000000..f26239c3e
--- /dev/null
+++ b/doc/bugs/touch.hsc_has_problems_on_non-linux_based_systems/comment_1_1d38283c9ea87174f3bbef9a58f5cb88._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-03-16T16:07:26Z"
+ content="""
+Hmm.. is utimensat available at all?
+
+I've committed an update that may convince at least some compilers to expose this newer POSIX stuff. I don't know if it will help, please let me know.
+"""]]
diff --git a/doc/bugs/touch.hsc_has_problems_on_non-linux_based_systems/comment_2_bf112edd075fbebe4fc959a387946eb9._comment b/doc/bugs/touch.hsc_has_problems_on_non-linux_based_systems/comment_2_bf112edd075fbebe4fc959a387946eb9._comment
new file mode 100644
index 000000000..0222e645b
--- /dev/null
+++ b/doc/bugs/touch.hsc_has_problems_on_non-linux_based_systems/comment_2_bf112edd075fbebe4fc959a387946eb9._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 2"
+ date="2011-03-16T16:49:18Z"
+ content="""
+Just pulled the changes, it still fails to build. utimensat doesn't seem to exist on OSX 10.6.6.
+"""]]
diff --git a/doc/bugs/touch.hsc_has_problems_on_non-linux_based_systems/comment_3_a46080fbe82adf0986c5dc045e382501._comment b/doc/bugs/touch.hsc_has_problems_on_non-linux_based_systems/comment_3_a46080fbe82adf0986c5dc045e382501._comment
new file mode 100644
index 000000000..7e79dea88
--- /dev/null
+++ b/doc/bugs/touch.hsc_has_problems_on_non-linux_based_systems/comment_3_a46080fbe82adf0986c5dc045e382501._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 3"
+ date="2011-03-16T17:46:40Z"
+ content="""
+Alright, I've added #idefs and the symlink timestamp mirroring feature will be unavailable on OSX until I get a version that works there.
+"""]]
diff --git a/doc/bugs/touch.hsc_has_problems_on_non-linux_based_systems/comment_4_760437bf3ba972a775bb190fb4b38202._comment b/doc/bugs/touch.hsc_has_problems_on_non-linux_based_systems/comment_4_760437bf3ba972a775bb190fb4b38202._comment
new file mode 100644
index 000000000..6b1e03b02
--- /dev/null
+++ b/doc/bugs/touch.hsc_has_problems_on_non-linux_based_systems/comment_4_760437bf3ba972a775bb190fb4b38202._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 4"
+ date="2011-03-16T20:32:01Z"
+ content="""
+Just tried it out on my mac and it's working again. I guess this issue could be closed for now.
+"""]]
diff --git a/doc/bugs/touch.hsc_has_problems_on_non-linux_based_systems/comment_5_060ba5ea88dcab2f4a0c199f13ef4f67._comment b/doc/bugs/touch.hsc_has_problems_on_non-linux_based_systems/comment_5_060ba5ea88dcab2f4a0c199f13ef4f67._comment
new file mode 100644
index 000000000..aeb576be3
--- /dev/null
+++ b/doc/bugs/touch.hsc_has_problems_on_non-linux_based_systems/comment_5_060ba5ea88dcab2f4a0c199f13ef4f67._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 5"
+ date="2011-03-20T18:12:59Z"
+ content="""
+I'm leaving this bug open because this feature, however minor is not available on OSX and BSD.
+
+I have added a partial implementation using lutimes(3), which should be available on the BSDs. However, it's ifdefed out due to a casting problem: The TimeSpec uses a CTime, while lutimes uses a CLong. These data types may be internally the same on some or all platforms, so if you want this feature you can try changing the \"ifdef 0\" in Touch.hsc to 1 and try it, see if \"git annex add\" mirrors file modification time in created symlinks, and let me know.
+"""]]
diff --git a/doc/bugs/touch.hsc_has_problems_on_non-linux_based_systems/comment_6_548303d6ffb21a9370b6904f41ff49c1._comment b/doc/bugs/touch.hsc_has_problems_on_non-linux_based_systems/comment_6_548303d6ffb21a9370b6904f41ff49c1._comment
new file mode 100644
index 000000000..cd116c232
--- /dev/null
+++ b/doc/bugs/touch.hsc_has_problems_on_non-linux_based_systems/comment_6_548303d6ffb21a9370b6904f41ff49c1._comment
@@ -0,0 +1,42 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 6"
+ date="2011-03-20T20:48:41Z"
+ content="""
+ok, pulling the latest master and building on OSX now does this...
+
+<pre>
+ghc -O2 -Wall -ignore-package monads-fd --make git-annex
+[ 1 of 63] Compiling Touch ( Touch.hs, Touch.o )
+
+Touch.hsc:24:0:
+ The type signature for `touchBoth' lacks an accompanying binding
+
+Touch.hsc:27:26: Not in scope: `touchBoth'
+make: *** [git-annex] Error 1
+</pre>
+
+changing the #if 0 to 1 gives this...
+
+<pre>
+ghc -O2 -Wall -ignore-package monads-fd --make git-annex
+[ 1 of 63] Compiling Touch ( Touch.hs, Touch.o )
+
+Touch.hsc:95:43:
+ Couldn't match expected type `CLong' against inferred type `CTime'
+ In the second argument of `(\ hsc_ptr
+ -> pokeByteOff hsc_ptr 0)', namely
+ `(sec :: CLong)'
+ In a stmt of a 'do' expression:
+ (\ hsc_ptr -> pokeByteOff hsc_ptr 0) ptr (sec :: CLong)
+ In the expression:
+ do { (\ hsc_ptr -> pokeByteOff hsc_ptr 0) ptr (sec :: CLong);
+ (\ hsc_ptr -> pokeByteOff hsc_ptr 4) ptr (0 :: CLong) }
+make: *** [git-annex] Error 1
+</pre>
+
+
+it seems that commit 6634b6a6b84a924f6f6059b5bea61f449d056eee has broken support for OSX.
+
+"""]]
diff --git a/doc/bugs/touch.hsc_has_problems_on_non-linux_based_systems/comment_7_7ca00527ab5db058aadec4fe813e51fd._comment b/doc/bugs/touch.hsc_has_problems_on_non-linux_based_systems/comment_7_7ca00527ab5db058aadec4fe813e51fd._comment
new file mode 100644
index 000000000..e35dc8a82
--- /dev/null
+++ b/doc/bugs/touch.hsc_has_problems_on_non-linux_based_systems/comment_7_7ca00527ab5db058aadec4fe813e51fd._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 7"
+ date="2011-03-20T22:06:25Z"
+ content="""
+Fixed that, and removed the impossible cast so it can be built with #if 1
+"""]]
diff --git a/doc/bugs/touch.hsc_has_problems_on_non-linux_based_systems/comment_8_881aecb9ae671689453f6d5d780d844b._comment b/doc/bugs/touch.hsc_has_problems_on_non-linux_based_systems/comment_8_881aecb9ae671689453f6d5d780d844b._comment
new file mode 100644
index 000000000..56a7eb360
--- /dev/null
+++ b/doc/bugs/touch.hsc_has_problems_on_non-linux_based_systems/comment_8_881aecb9ae671689453f6d5d780d844b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 8"
+ date="2011-03-21T08:52:18Z"
+ content="""
+Just tried building both of the code paths, and they seem to build and somewhat function on OSX. I have yet to confirm the functionality is working correctly, but so far it's looking good. (I somewhat care less about the utimes/mtimes of my files since I care more about the content :) )
+"""]]
diff --git a/doc/bugs/transferkey_fails_due_to_gpg.mdwn b/doc/bugs/transferkey_fails_due_to_gpg.mdwn
new file mode 100644
index 000000000..26bd0443e
--- /dev/null
+++ b/doc/bugs/transferkey_fails_due_to_gpg.mdwn
@@ -0,0 +1,51 @@
+What steps will reproduce the problem?
+Create a new annex, add a new repository:
+
+ git annex initremote vserver2 type=rsync rsyncurl=vserver.dbruhn.de:/annex encryption=dominik@dbruhn.de
+
+Add some files, add them to annex, try to transfer them:
+ git annex transferkey SHA256-s6486446--df84b11a0e9543134224d0ac1e0f2567bcd79d86605117c5af008a1b133cee3a --to vserver2 --file MKBD/OB.mp3 --debug
+
+What is the expected output? What do you see instead?
+
+I expect the file to be transfered to my remote server. Instead I see a 'gpg>' prompt with nothing happening. When pressing CTRL+C, the following mesage is shown:
+
+gpg: Interrupt caught ... exiting
+
+There must be some faults when interfacing gpg. The other console-output is:
+
+-----
+ [2012-09-08 18:50:12 CEST] read: git ["--git-dir=/home/dominik/Annex/.git","--work-tree=/home/dominik/Annex","show-ref","git-annex"]
+ [2012-09-08 18:50:12 CEST] read: git ["--git-dir=/home/dominik/Annex/.git","--work-tree=/home/dominik/Annex","show-ref","--hash","refs/heads/git-annex"]
+ [2012-09-08 18:50:12 CEST] read: git ["--git-dir=/home/dominik/Annex/.git","--work-tree=/home/dominik/Annex","log","refs/heads/gitannex..245fa80db6733dbbeff6c40d46bd65ed00811548","--oneline","-n1"]
+ [2012-09-08 18:50:12 CEST] chat: git ["--git-dir=/home/dominik/Annex/.git","--work-tree=/home/dominik/Annex","cat-file","--batch"]
+ (gpg) [2012-09-08 18:50:12 CEST] chat: gpg ["--batch","--no-tty","--use-agent","--quiet","--trust-model","always","--decrypt"]
+ [2012-09-08 18:50:12 CEST] chat: gpg ["--batch","--no-tty","--use-agent","--quiet","--trust-model","always","--passphrase-fd","8","--symmetric","--force-mdc"]
+ sdgdg
+ dsgdgs
+ ^C
+ gpg: Interrupt caught ... exiting
+-----
+
+What version of git-annex are you using? On what operating system?
+git-annex version: 3.20120826
+Ubuntu 12.04, GHC 7.4.1
+gpg is 'gpg (GnuPG) 1.4.11'
+
+Please provide any additional information below.
+
+The key which is used for the remote is password protected. The GnuPG Agent asks me for the password, so this seems to work. I do not know what content the gpg expects but does not recieve. The .git/config entry for the remote looks reasonable:
+
+ [remote "vserver2"]
+ annex-rsyncurl = vserver.dbruhn.de:/annex
+ annex-uuid = ea3d6acc-716c-48e8-9b6b-993b90dcc1db
+
+When adding a new rsync-remote with encryption set to 'none' (therefore disabled), everything works, so it really seems a gpg issue.
+
+How can I help debugging?
+
+> Thanks, I reproduced a deadlock in the gpg code, which was introduced
+> with some of my earlier changes to use threading. No released version of
+> git-annex was affected, and I have developed a fix, which works for me
+> and is now committed to master. Marking this [[done]]; please do check
+> that my fix works for you! --[[Joey]]
diff --git a/doc/bugs/transferkey_fails_due_to_gpg/comment_1_f6434400d528a0fa59c056995ff2e6f3._comment b/doc/bugs/transferkey_fails_due_to_gpg/comment_1_f6434400d528a0fa59c056995ff2e6f3._comment
new file mode 100644
index 000000000..1fb9d2a0b
--- /dev/null
+++ b/doc/bugs/transferkey_fails_due_to_gpg/comment_1_f6434400d528a0fa59c056995ff2e6f3._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.30"
+ subject="comment 1"
+ date="2012-09-09T16:45:20Z"
+ content="""
+This is very strange behavior for gpg, it's being told several ways not to be interactive (--batch, --no-tty, --passphrase-fd); the mode it's being run in should, even without those options, only prompt for a password.
+
+I'm left wondering what settings you have in gpg.conf, and even wondering if you have some kind of wrapper around gpg that makes it more interactive, or some odd gpg agent that's interactive, or something.
+
+(I'm also confused that you mention a \"gpg>\" prompt, but your transcript doesn't show one.)
+"""]]
diff --git a/doc/bugs/transferkey_fails_due_to_gpg/comment_2_c540b05b62a3186a87efcb180ea2a52d._comment b/doc/bugs/transferkey_fails_due_to_gpg/comment_2_c540b05b62a3186a87efcb180ea2a52d._comment
new file mode 100644
index 000000000..7203f45df
--- /dev/null
+++ b/doc/bugs/transferkey_fails_due_to_gpg/comment_2_c540b05b62a3186a87efcb180ea2a52d._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.30"
+ subject="comment 2"
+ date="2012-09-09T16:50:40Z"
+ content="""
+Perhaps you mistook the \"(gpg)\" that git-annex prints out for a gpg prompt? If your transcript is accurate, things seem to be stalled, and gpg is not behaving like you're at a prompt when you type stuff to it, just the terminal is echoing back what you typed.
+
+This then looks like it might be the same bug someone else mentioned here <http://git-annex.branchable.com/design/assistant/blog/day_70__adding_ssh_remotes/#comment-048f7fad45dc545f9d5a560491b275a1>
+
+I have not managed to reproduce that problem. Are you seeing stalls with any particular size of file? Does it happen with very small files?
+"""]]
diff --git a/doc/bugs/transferkey_fails_due_to_gpg/comment_3_9ad2ef73169dbd2866da2f4259ab0f00._comment b/doc/bugs/transferkey_fails_due_to_gpg/comment_3_9ad2ef73169dbd2866da2f4259ab0f00._comment
new file mode 100644
index 000000000..3838e70f0
--- /dev/null
+++ b/doc/bugs/transferkey_fails_due_to_gpg/comment_3_9ad2ef73169dbd2866da2f4259ab0f00._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.30"
+ subject="comment 3"
+ date="2012-09-09T16:55:02Z"
+ content="""
+I've replicated a stall with current git-annex head and gpg. Doesn't happen with an older build. bisecting..
+"""]]
diff --git a/doc/bugs/transferkey_fails_due_to_gpg/comment_4_7631b8842efba6a4aad87386ce9443a7._comment b/doc/bugs/transferkey_fails_due_to_gpg/comment_4_7631b8842efba6a4aad87386ce9443a7._comment
new file mode 100644
index 000000000..6c7a3f2d4
--- /dev/null
+++ b/doc/bugs/transferkey_fails_due_to_gpg/comment_4_7631b8842efba6a4aad87386ce9443a7._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://www.dbruhn.de/"
+ nickname="Dominik"
+ subject="comment 4"
+ date="2012-09-09T19:45:07Z"
+ content="""
+Thanks, your recent changes fixed the bug!
+"""]]
diff --git a/doc/bugs/typo_in___34__ready_to_add_remote_server__34___message.mdwn b/doc/bugs/typo_in___34__ready_to_add_remote_server__34___message.mdwn
new file mode 100644
index 000000000..9d370b640
--- /dev/null
+++ b/doc/bugs/typo_in___34__ready_to_add_remote_server__34___message.mdwn
@@ -0,0 +1,16 @@
+What steps will reproduce the problem?
+Add a ssh remote to an existing git annex repository. The word "sensitive" is misspelled.
+
+What is the expected output? What do you see instead?
+I expect to see:
+"The contents of your files will be stored, fully encrypted, on the server. The server will not store other information about your git repository. This is the best choice if you don't run the server yourself, or have sensitive data."
+
+But instead I see:
+"The contents of your files will be stored, fully encrypted, on the server. The server will not store other information about your git repository. This is the best choice if you don't run the server yourself, or have sensative data."
+
+What version of git-annex are you using? On what operating system?
+3.20130102, Fedora 17 x86_64
+
+Please provide any additional information below.
+
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/typo_on_the_Mac_OS_10.7.5_Lion_build.mdwn b/doc/bugs/typo_on_the_Mac_OS_10.7.5_Lion_build.mdwn
new file mode 100644
index 000000000..8f5e8c324
--- /dev/null
+++ b/doc/bugs/typo_on_the_Mac_OS_10.7.5_Lion_build.mdwn
@@ -0,0 +1,11 @@
+As told in http://git-annex.branchable.com/bugs/OSX_app_issues/#comment-2a69d531bd3bb593c1a49dc8cdb34b1e the Mac OS 10.7.5 (Lion) build fails to run.
+
+ $ /Applications/git-annex.app/Contents/MacOS/git-annex
+
+ /Applications/git-annex.app/Contents/MacOS/runshell: line 25: syntax error near unexpected token `&'
+
+Manually editing /Applications/git-annex.app/Contents/MacOS/runshell as told in http://git-annex.branchable.com/bugs/OSX_app_issues/#comment-5579c2150ad4d2ccc207a253fe57612a fixes the issue.
+
+Furthermore, this build is quite outdated...
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/typo_on_the_Mac_OS_10.7.5_Lion_build/comment_1_e8df4b36a89b37edd94f3a318ae93a32._comment b/doc/bugs/typo_on_the_Mac_OS_10.7.5_Lion_build/comment_1_e8df4b36a89b37edd94f3a318ae93a32._comment
new file mode 100644
index 000000000..d67330a22
--- /dev/null
+++ b/doc/bugs/typo_on_the_Mac_OS_10.7.5_Lion_build/comment_1_e8df4b36a89b37edd94f3a318ae93a32._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.246"
+ subject="comment 1"
+ date="2013-11-14T15:26:01Z"
+ content="""
+This is unfortunate.. The Lion autobuilder is running, but has been failing for various reasons for some time, and I have not managed to get ahold of Jimmy to fix them. Also, that machine may be upgraded from Lion before too long.
+"""]]
diff --git a/doc/bugs/typo_on_the_Mac_OS_10.7.5_Lion_build/comment_2_3b2c3c84bd1910280c549a2ee1c622b9._comment b/doc/bugs/typo_on_the_Mac_OS_10.7.5_Lion_build/comment_2_3b2c3c84bd1910280c549a2ee1c622b9._comment
new file mode 100644
index 000000000..bd1763ca0
--- /dev/null
+++ b/doc/bugs/typo_on_the_Mac_OS_10.7.5_Lion_build/comment_2_3b2c3c84bd1910280c549a2ee1c622b9._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 2"
+ date="2013-11-15T20:57:27Z"
+ content="""
+The builder is back, I was away from the office when it broke. It should be spitting out builds on a daily basis again.
+"""]]
diff --git a/doc/bugs/unable_to_change_repository_group_of___34__here__34__.mdwn b/doc/bugs/unable_to_change_repository_group_of___34__here__34__.mdwn
new file mode 100644
index 000000000..4098f8acf
--- /dev/null
+++ b/doc/bugs/unable_to_change_repository_group_of___34__here__34__.mdwn
@@ -0,0 +1,13 @@
+### Please describe the problem.
+(I assume) following your change to disallow changing the name of "here", I am unable to change the repository group of "here"
+
+
+### What steps will reproduce the problem?
+In webapp, edit "here", and try and change repository group.
+It highlights the (now empty) name field, and says "value is required".
+
+### What version of git-annex are you using? On what operating system?
+git-annex version: 4.20130618-g333cb8e
+Ubuntu 13.04
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/unannex_and_uninit_do_not_work_when_git_index_is_broken.mdwn b/doc/bugs/unannex_and_uninit_do_not_work_when_git_index_is_broken.mdwn
new file mode 100644
index 000000000..c31205ede
--- /dev/null
+++ b/doc/bugs/unannex_and_uninit_do_not_work_when_git_index_is_broken.mdwn
@@ -0,0 +1,17 @@
+git's index broke and I was unable to restore it. While this is not git-annex' problem, it should still be possible to get my data in an un-annexed state.
+
+ % git status
+ fatal: index file smaller than expected
+ % git annex unannex foo
+ fatal: index file smaller than expected
+ % git annex uninit
+ fatal: index file smaller than expected
+ uninit
+ pre-commit hook (/path/to/git-annex/.git/hooks/pre-commit) contents modified; not deleting. Edit it to remove call to git annex.
+ ok
+ %
+
+Ttbomk, the softlinks and objects are enough to un-annex the files; side-stepping git's index if necessary.
+
+> `git annex repair` can now repair broken index files and other
+> git repository corruption. [[done]] --[[Joey]]
diff --git a/doc/bugs/unannex_and_uninit_do_not_work_when_git_index_is_broken/comment_1_1931e733f0698af5603a8b92267203d4._comment b/doc/bugs/unannex_and_uninit_do_not_work_when_git_index_is_broken/comment_1_1931e733f0698af5603a8b92267203d4._comment
new file mode 100644
index 000000000..84b68bb7b
--- /dev/null
+++ b/doc/bugs/unannex_and_uninit_do_not_work_when_git_index_is_broken/comment_1_1931e733f0698af5603a8b92267203d4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-04-03T01:40:50Z"
+ content="""
+They rely on git-ls-files to get a list of files that are checked into git, in order to tell what to unannex.
+"""]]
diff --git a/doc/bugs/unannex_and_uninit_do_not_work_when_git_index_is_broken/comment_2_40920b88537b7715395808d8aa94bf03._comment b/doc/bugs/unannex_and_uninit_do_not_work_when_git_index_is_broken/comment_2_40920b88537b7715395808d8aa94bf03._comment
new file mode 100644
index 000000000..215619043
--- /dev/null
+++ b/doc/bugs/unannex_and_uninit_do_not_work_when_git_index_is_broken/comment_2_40920b88537b7715395808d8aa94bf03._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 2"
+ date="2011-04-03T08:55:18Z"
+ content="""
+Given that the softlinks contain all needed information (if the object exists, locally), an emergency way to get files \"out\" of git-annex would be nice. I am aware that one can script it, but a canonical way is always better, especially when things go south.
+"""]]
diff --git a/doc/bugs/unannex_command_doesn__39__t_all_files.mdwn b/doc/bugs/unannex_command_doesn__39__t_all_files.mdwn
new file mode 100644
index 000000000..a6500c377
--- /dev/null
+++ b/doc/bugs/unannex_command_doesn__39__t_all_files.mdwn
@@ -0,0 +1,30 @@
+ $ git init ; git annex init test ; dd if=/dev/urandom of=file1 count=128 ; cp file1 file2 ; git annex add --backend=SHA1 file? ; git commit -m init ; git annex unannex ; ls -l
+ Initialized empty Git repository in /tmp/annex/.git/
+ init test ok
+ 128+0 records in
+ 128+0 records out
+ 65536 bytes (66 kB) copied, 0.007173 s, 9.1 MB/s
+ add file1 (checksum...) ok
+ add file2 (checksum...) ok
+ (Recording state in git...)
+ [master (root-commit) 2177b10] init
+ 2 files changed, 2 insertions(+), 0 deletions(-)
+ create mode 120000 file1
+ create mode 120000 file2
+ unannex file1 ok
+ (Recording state in git...)
+ [master bef78b1] content removed from git annex
+ 1 files changed, 0 insertions(+), 1 deletions(-)
+ delete mode 120000 file1
+ total 72
+ -rw-r--r-- 1 simons users 65536 Jul 15 17:29 file1
+ lrwxrwxrwx 1 simons users 132 Jul 15 17:29 file2 -> .git/annex/objects/jp/Fk/SHA1-s65536--795b58cc4e5190b02e7026fd9e94a10c98c6475f/SHA1-s65536--795b58cc4e5190b02e7026fd9e94a10c98c6475f
+
+> This was recently discussed in
+> [[annex_unannex__47__uninit_should_handle_copies]] and `unannex --fast`
+> added to leave contents behind in the annex, which allows handling
+> copies. But needs manual cleanup later with dropunused. --[[Joey]]
+
+> This is basically a dup of [[Large unannex operations result in stale symlinks and data loss]],
+> or at least the ideas in there will also deal with this. Closing as dupe.
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/unannex_removes_object_even_if_referred_to_by_others.mdwn b/doc/bugs/unannex_removes_object_even_if_referred_to_by_others.mdwn
new file mode 100644
index 000000000..874e5c27f
--- /dev/null
+++ b/doc/bugs/unannex_removes_object_even_if_referred_to_by_others.mdwn
@@ -0,0 +1,20 @@
+##What steps will reproduce the problem?
+
+ echo text > foo
+ echo text > bar
+ git annex add foo bar
+ git annex unannex foo
+
+##What is the expected output? What do you see instead?
+
+I would expect that the object behind 'bar' remained intact, what happens is that the object is moved out of the annex and 'bar' is left as a dangling symlink, if you are unlucky and don't spot this, it could be potentially dangerous, since you can easily lose data.
+
+##What version of git-annex are you using? On what operating system?
+
+git-annex built from git on Tue Mar 12 15:58:36 2013 -0400
+
+From commit: 70b7555eaf9ac5f88bb137985d93bed8d5a434e8
+
+On Debian Sid
+
+> [[done]]; duplicate bug report
diff --git a/doc/bugs/unannex_removes_object_even_if_referred_to_by_others/comment_1_0ce72d0f67082f202cfa58b7c00f2fd3._comment b/doc/bugs/unannex_removes_object_even_if_referred_to_by_others/comment_1_0ce72d0f67082f202cfa58b7c00f2fd3._comment
new file mode 100644
index 000000000..da80a8f01
--- /dev/null
+++ b/doc/bugs/unannex_removes_object_even_if_referred_to_by_others/comment_1_0ce72d0f67082f202cfa58b7c00f2fd3._comment
@@ -0,0 +1,39 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnRai_qFYPVvEgC6i1nlM1bh-C__jbhqS0"
+ nickname="Matthew"
+ subject="git annex uninit does this too..."
+ date="2013-07-27T07:55:49Z"
+ content="""
+Here are my files from a backup...
+
+ fozz@cobol:/mnt/store/Music/Jukebox/Markus Schulz/Miami'05 Euro Trance $ md5sum AlbumArt_{85E86538-46E1-412C-9D94-A67FC108ED97}_Small.jpg AlbumArtSmall.jpg
+ 9cfd8347becf87da8b1c5962e77267ad AlbumArt_{85E86538-46E1-412C-9D94-A67FC108ED97}_Small.jpg
+ 9cfd8347becf87da8b1c5962e77267ad AlbumArtSmall.jpg
+
+Here is how git annex unannex left my files...
+
+ fozz@markdown:/exports/music$ ls -alh Jukebox/Markus\ Schulz/Miami\'05\ Euro\ Trance/
+ total 127M
+ drwxr-x---+ 2 fozz audio 4.0K Jul 27 03:04 .
+ drwxr-x---+ 9 fozz audio 4.0K Feb 8 20:03 ..
+ -rwxr-x---+ 1 fozz audio 13M Mar 24 2008 01 - Hydroid Blue Tubes (Intro Mix).mp3
+ -rwxr-x---+ 1 fozz audio 9.8M Mar 24 2008 02 - Interstate I Found U (Harry Lemon Remix).mp3
+ -rwxr-x---+ 1 fozz audio 15M Mar 24 2008 03 - Kalafut & Fygle '3579 Km.mp3
+ -rwxr-x---+ 1 fozz audio 11M Mar 24 2008 04 - Hammer & Bennett Baltic Sea.mp3
+ -rwxr-x---+ 1 fozz audio 11M Mar 24 2008 05 - Fluid In Motion Soul Dimension.mp3
+ -rwxr-x---+ 1 fozz audio 12M Mar 24 2008 06 - Keo Close Enough (Noel Sanger Mix).mp3
+ -rwxr-x---+ 1 fozz audio 9.4M Mar 24 2008 08 - Lens Let The Light In.mp3
+ -rwxr-x---+ 1 fozz audio 11M Mar 24 2008 09 - Aronek Free Yourself.mp3
+ -rwxr-x---+ 1 fozz audio 14M Mar 24 2008 10 - Ava Mea In The End.mp3
+ -rwxr-x---+ 1 fozz audio 13M Mar 24 2008 11 - Sean Walsh Pres- Jagermaestro Quarter Century.mp3
+ -rwxr-x---+ 1 fozz audio 12M Mar 24 2008 12 - Max Graham Feat- Jessica Jacobs Gone.mp3
+ -rwxr-x---+ 1 fozz audio 6.9K Mar 24 2008 AlbumArt_{85E86538-46E1-412C-9D94-A67FC108ED97}_Large.jpg
+ lrwxrwxrwx 1 fozz fozz 191 Mar 24 2008 AlbumArt_{85E86538-46E1-412C-9D94-A67FC108ED97}_Small.jpg -> ../../../.git/annex/objects/ZZ/86/SHA256-s2067-- b870f34a1eee9fdfae8a488626b51d17f25f17788655fe8924d598109a95104a/SHA256-s2067--b870f34a1eee9fdfae8a488626b51d17f25f17788655fe8924d598109a95104a
+ -rwxr-x---+ 1 fozz audio 2.1K Mar 24 2008 AlbumArtSmall.jpg
+ -rwxr-x---+ 1 fozz audio 361 Mar 24 2008 desktop.ini
+ lrwxrwxrwx 1 fozz fozz 191 Mar 24 2008 Folder.jpg -> ../../../.git/annex/objects/k7/xp/SHA256-s7024--8d5778605b211e0971824df9a970f16b38dee97a6a529f41113c31378ef83f3f/SHA256-s7024--8d5778605b211e0971824df9a970f16b38dee97a6a529f41113c31378ef83f3f
+
+The symlinks are now broken links
+
+
+"""]]
diff --git a/doc/bugs/unannex_removes_object_even_if_referred_to_by_others/comment_2_647f49ffcaa348660659f9954a59b3ae._comment b/doc/bugs/unannex_removes_object_even_if_referred_to_by_others/comment_2_647f49ffcaa348660659f9954a59b3ae._comment
new file mode 100644
index 000000000..041d700dd
--- /dev/null
+++ b/doc/bugs/unannex_removes_object_even_if_referred_to_by_others/comment_2_647f49ffcaa348660659f9954a59b3ae._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnRai_qFYPVvEgC6i1nlM1bh-C__jbhqS0"
+ nickname="Matthew"
+ subject="comment 2"
+ date="2013-07-27T08:14:33Z"
+ content="""
+Sorry, that was an unannex . not a uninit, which I used first briefly. Version information:
+
+ git-annex version: 4.20130725-gd10dfef
+ build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP
+ local repository version: 3
+ default repository version: 3
+ supported repository versions: 3 4
+ upgrade supported from repository versions: 0 1 2
+
+"""]]
diff --git a/doc/bugs/unannex_removes_object_even_if_referred_to_by_others/comment_3_3f7f4b55b7ec2641a70109788e0b5672._comment b/doc/bugs/unannex_removes_object_even_if_referred_to_by_others/comment_3_3f7f4b55b7ec2641a70109788e0b5672._comment
new file mode 100644
index 000000000..890e96fea
--- /dev/null
+++ b/doc/bugs/unannex_removes_object_even_if_referred_to_by_others/comment_3_3f7f4b55b7ec2641a70109788e0b5672._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.110"
+ subject="comment 3"
+ date="2013-07-27T23:51:38Z"
+ content="""
+uninit does not do this. Nor does unannex --fast FWIW.
+
+
+"""]]
diff --git a/doc/bugs/unannex_removes_object_even_if_referred_to_by_others/comment_4_313d393c416495aa0f8573113e41c2f7._comment b/doc/bugs/unannex_removes_object_even_if_referred_to_by_others/comment_4_313d393c416495aa0f8573113e41c2f7._comment
new file mode 100644
index 000000000..0f691059d
--- /dev/null
+++ b/doc/bugs/unannex_removes_object_even_if_referred_to_by_others/comment_4_313d393c416495aa0f8573113e41c2f7._comment
@@ -0,0 +1,431 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnRai_qFYPVvEgC6i1nlM1bh-C__jbhqS0"
+ nickname="Matthew"
+ subject="Yes it does"
+ date="2013-07-28T12:04:18Z"
+ content="""
+I think it does, I just tested it with Ubuntu default version and the newest linux tarball on your site...
+
+See Log:
+
+ fozz@cobol:~ $ cd /tmp
+
+ fozz@cobol:/tmp $ tar -zxf ~/Downloads/git-annex-standalone-amd64.tar.gz
+
+ fozz@cobol:/tmp $ export PATH=/tmp/git-annex.linux/:$PATH
+
+ fozz@cobol:/tmp $ cp -R /mnt/store/Music/Jukebox/Markus\ Schulz/
+ Amsterdam 08/ Progression/
+ Do You Dream/ Thoughts Become Things II/
+ June 2005 Promo Mix/ Track/
+ Miami'05 Euro Trance/ Without You Near/
+ Mysteryland 2007 Haarlemmermeermeer 25-08-2007/
+
+ fozz@cobol:/tmp $ cp -R /mnt/store/Music/Jukebox/Markus\ Schulz/Miami\'05\ Euro\ Trance/ .
+
+ fozz@cobol:/tmp $ cd Miami\'05\ Euro\ Trance/
+
+ fozz@cobol:/tmp/Miami'05 Euro Trance $ ls -alh
+ total 127M
+ drwx------ 2 fozz fozz 4.0K Jul 28 12:52 .
+ drwxrwxrwt 23 root root 4.0K Jul 28 12:52 ..
+ -rwx------ 1 fozz fozz 13M Jul 28 12:52 01 - Hydroid Blue Tubes (Intro Mix).mp3
+ -rwx------ 1 fozz fozz 9.8M Jul 28 12:52 02 - Interstate I Found U (Harry Lemon Remix).mp3
+ -rwx------ 1 fozz fozz 15M Jul 28 12:52 03 - Kalafut & Fygle '3579 Km.mp3
+ -rwx------ 1 fozz fozz 11M Jul 28 12:52 04 - Hammer & Bennett Baltic Sea.mp3
+ -rwx------ 1 fozz fozz 11M Jul 28 12:52 05 - Fluid In Motion Soul Dimension.mp3
+ -rwx------ 1 fozz fozz 12M Jul 28 12:52 06 - Keo Close Enough (Noel Sanger Mix).mp3
+ -rwx------ 1 fozz fozz 9.4M Jul 28 12:52 08 - Lens Let The Light In.mp3
+ -rwx------ 1 fozz fozz 11M Jul 28 12:52 09 - Aronek Free Yourself.mp3
+ -rwx------ 1 fozz fozz 14M Jul 28 12:52 10 - Ava Mea In The End.mp3
+ -rwx------ 1 fozz fozz 13M Jul 28 12:52 11 - Sean Walsh Pres- Jagermaestro Quarter Century.mp3
+ -rwx------ 1 fozz fozz 12M Jul 28 12:52 12 - Max Graham Feat- Jessica Jacobs Gone.mp3
+ -rwx------ 1 fozz fozz 6.9K Jul 28 12:52 AlbumArt_{85E86538-46E1-412C-9D94-A67FC108ED97}_Large.jpg
+ -rwx------ 1 fozz fozz 2.1K Jul 28 12:52 AlbumArt_{85E86538-46E1-412C-9D94-A67FC108ED97}_Small.jpg
+ -rwx------ 1 fozz fozz 2.1K Jul 28 12:52 AlbumArtSmall.jpg
+ -rwx------ 1 fozz fozz 361 Jul 28 12:52 desktop.ini
+ -rwx------ 1 fozz fozz 6.9K Jul 28 12:52 Folder.jpg
+
+ fozz@cobol:/tmp/Miami'05 Euro Trance $ mkdir Files
+
+ fozz@cobol:/tmp/Miami'05 Euro Trance $ mv * Files/
+ mv: cannot move ‘Files’ to a subdirectory of itself, ‘Files/Files’
+
+ fozz@cobol:/tmp/Miami'05 Euro Trance $ ls
+ Files
+
+ fozz@cobol:/tmp/Miami'05 Euro Trance $ git annex version
+ git-annex version: 4.20130725-g8140f7c
+ build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP
+
+ fozz@cobol:/tmp/Miami'05 Euro Trance $ git init
+ Initialised empty Git repository in /tmp/Miami'05 Euro Trance/.git/
+
+ fozz@cobol:/tmp/Miami'05 Euro Trance $ git annex init TEST
+ init TEST error: Malformed value for push.default: simple
+ error: Must be one of nothing, matching, tracking or current.
+ fatal: bad config file line 19 in /home/fozz/.gitconfig
+ error: Malformed value for push.default: simple
+ error: Must be one of nothing, matching, tracking or current.
+ fatal: bad config file line 19 in /home/fozz/.gitconfig
+ git-annex: failed to read sha from git write-tree
+
+ fozz@cobol:/tmp/Miami'05 Euro Trance $ vim ~/.gitconfig
+
+ fozz@cobol:/tmp/Miami'05 Euro Trance $ git annex init TEST
+ init TEST ok
+ (Recording state in git...)
+
+ fozz@cobol:/tmp/Miami'05 Euro Trance $ git annex add .
+ add Files/01 - Hydroid Blue Tubes (Intro Mix).mp3 (checksum...) ok
+ add Files/02 - Interstate I Found U (Harry Lemon Remix).mp3 (checksum...) ok
+ add Files/03 - Kalafut & Fygle '3579 Km.mp3 (checksum...) ok
+ add Files/04 - Hammer & Bennett Baltic Sea.mp3 (checksum...) ok
+ add Files/05 - Fluid In Motion Soul Dimension.mp3 (checksum...) ok
+ add Files/06 - Keo Close Enough (Noel Sanger Mix).mp3 (checksum...) ok
+ add Files/08 - Lens Let The Light In.mp3 (checksum...) ok
+ add Files/09 - Aronek Free Yourself.mp3 (checksum...) ok
+ add Files/10 - Ava Mea In The End.mp3 (checksum...) ok
+ add Files/11 - Sean Walsh Pres- Jagermaestro Quarter Century.mp3 (checksum...) ok
+ add Files/12 - Max Graham Feat- Jessica Jacobs Gone.mp3 (checksum...) ok
+ add Files/AlbumArtSmall.jpg (checksum...) ok
+ add Files/AlbumArt_{85E86538-46E1-412C-9D94-A67FC108ED97}_Large.jpg (checksum...) ok
+ add Files/AlbumArt_{85E86538-46E1-412C-9D94-A67FC108ED97}_Small.jpg (checksum...) ok
+ add Files/Folder.jpg (checksum...) ok
+ add Files/desktop.ini (checksum...) ok
+ (Recording state in git...)
+
+ fozz@cobol:/tmp/Miami'05 Euro Trance $ ls
+ Files
+
+ fozz@cobol:/tmp/Miami'05 Euro Trance $ ls Files
+ 01 - Hydroid Blue Tubes (Intro Mix).mp3
+ 02 - Interstate I Found U (Harry Lemon Remix).mp3
+ 03 - Kalafut & Fygle '3579 Km.mp3
+ 04 - Hammer & Bennett Baltic Sea.mp3
+ 05 - Fluid In Motion Soul Dimension.mp3
+ 06 - Keo Close Enough (Noel Sanger Mix).mp3
+ 08 - Lens Let The Light In.mp3
+ 09 - Aronek Free Yourself.mp3
+ 10 - Ava Mea In The End.mp3
+ 11 - Sean Walsh Pres- Jagermaestro Quarter Century.mp3
+ 12 - Max Graham Feat- Jessica Jacobs Gone.mp3
+ AlbumArt_{85E86538-46E1-412C-9D94-A67FC108ED97}_Large.jpg
+ AlbumArt_{85E86538-46E1-412C-9D94-A67FC108ED97}_Small.jpg
+ AlbumArtSmall.jpg
+ desktop.ini
+ Folder.jpg
+
+ fozz@cobol:/tmp/Miami'05 Euro Trance $ git annex uninit .
+ fatal: ambiguous argument 'HEAD': unknown revision or path not in the working tree.
+ Use '--' to separate paths from revisions
+ git-annex: This command takes no parameters.
+
+ fozz@cobol:/tmp/Miami'05 Euro Trance $ git annex uninit
+ fatal: ambiguous argument 'HEAD': unknown revision or path not in the working tree.
+ Use '--' to separate paths from revisions
+ unannex Files/01 - Hydroid Blue Tubes (Intro Mix).mp3 ok
+ unannex Files/02 - Interstate I Found U (Harry Lemon Remix).mp3 ok
+ unannex Files/03 - Kalafut & Fygle '3579 Km.mp3 ok
+ unannex Files/04 - Hammer & Bennett Baltic Sea.mp3 ok
+ unannex Files/05 - Fluid In Motion Soul Dimension.mp3 ok
+ unannex Files/06 - Keo Close Enough (Noel Sanger Mix).mp3 ok
+ unannex Files/08 - Lens Let The Light In.mp3 ok
+ unannex Files/09 - Aronek Free Yourself.mp3 ok
+ unannex Files/10 - Ava Mea In The End.mp3 ok
+ unannex Files/11 - Sean Walsh Pres- Jagermaestro Quarter Century.mp3 ok
+ unannex Files/12 - Max Graham Feat- Jessica Jacobs Gone.mp3 ok
+ unannex Files/AlbumArtSmall.jpg ok
+ unannex Files/AlbumArt_{85E86538-46E1-412C-9D94-A67FC108ED97}_Large.jpg ok
+ unannex Files/AlbumArt_{85E86538-46E1-412C-9D94-A67FC108ED97}_Small.jpg ok
+ unannex Files/Folder.jpg ok
+ unannex Files/desktop.ini ok
+ Deleted branch git-annex (was 1b098e2).
+
+ fozz@cobol:/tmp/Miami'05 Euro Trance $ ls
+ Files
+
+ fozz@cobol:/tmp/Miami'05 Euro Trance $ ls -alh Files
+ total 127M
+ drwxrwxr-x 2 fozz fozz 4.0K Jul 28 12:54 .
+ drwx------ 4 fozz fozz 4.0K Jul 28 12:53 ..
+ -rwx------ 1 fozz fozz 13M Jul 28 12:52 01 - Hydroid Blue Tubes (Intro Mix).mp3
+ -rwx------ 1 fozz fozz 9.8M Jul 28 12:52 02 - Interstate I Found U (Harry Lemon Remix).mp3
+ -rwx------ 1 fozz fozz 15M Jul 28 12:52 03 - Kalafut & Fygle '3579 Km.mp3
+ -rwx------ 1 fozz fozz 11M Jul 28 12:52 04 - Hammer & Bennett Baltic Sea.mp3
+ -rwx------ 1 fozz fozz 11M Jul 28 12:52 05 - Fluid In Motion Soul Dimension.mp3
+ -rwx------ 1 fozz fozz 12M Jul 28 12:52 06 - Keo Close Enough (Noel Sanger Mix).mp3
+ -rwx------ 1 fozz fozz 9.4M Jul 28 12:52 08 - Lens Let The Light In.mp3
+ -rwx------ 1 fozz fozz 11M Jul 28 12:52 09 - Aronek Free Yourself.mp3
+ -rwx------ 1 fozz fozz 14M Jul 28 12:52 10 - Ava Mea In The End.mp3
+ -rwx------ 1 fozz fozz 13M Jul 28 12:52 11 - Sean Walsh Pres- Jagermaestro Quarter Century.mp3
+ -rwx------ 1 fozz fozz 12M Jul 28 12:52 12 - Max Graham Feat- Jessica Jacobs Gone.mp3
+ -rwx------ 2 fozz fozz 6.9K Jul 28 12:52 AlbumArt_{85E86538-46E1-412C-9D94-A67FC108ED97}_Large.jpg
+ -rwx------ 2 fozz fozz 2.1K Jul 28 12:52 AlbumArt_{85E86538-46E1-412C-9D94-A67FC108ED97}_Small.jpg
+ -rwx------ 2 fozz fozz 2.1K Jul 28 12:52 AlbumArtSmall.jpg
+ -rwx------ 1 fozz fozz 361 Jul 28 12:52 desktop.ini
+ -rwx------ 2 fozz fozz 6.9K Jul 28 12:52 Folder.jpg
+
+ fozz@cobol:/tmp/Miami'05 Euro Trance $ ls
+ Files
+
+ fozz@cobol:/tmp/Miami'05 Euro Trance $ cd ../
+
+ fozz@cobol:/tmp $ mkdir TEST2
+
+ fozz@cobol:/tmp $ cd TEST2
+
+ fozz@cobol:/tmp/TEST2 $ echo $PATH
+ /tmp/git-annex.linux/:node_modules/.bin:node_modules/.bin:/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/home/fozz/.scripts:/home/fozz/.bin:/sbin:/usr/sbin:/usr/local/sbin:/home/fozz/.scripts:/home/fozz/.bin:/sbin:/usr/sbin:/usr/local/sbin
+
+ fozz@cobol:/tmp/TEST2 $ export PATH=node_modules/.bin:node_modules/.bin:/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/home/fozz/.scripts:/home/fozz/.bin:/sbin:/usr/sbin:/usr/local/sbin:/home/fozz/.scripts:/home/fozz/.bin:/sbin:/usr/sbin:/usr/local/sbin
+
+ fozz@cobol:/tmp/TEST2 $ git annex version
+ git-annex version: 3.20121112ubuntu2
+
+ fozz@cobol:/tmp/TEST2 $ cp -R /mnt/store/Music/Jukebox/Markus\ Schulz/Miami\'05\ Euro\ Trance/ .
+
+ fozz@cobol:/tmp/TEST2 $ ls
+ Miami'05 Euro Trance
+
+ fozz@cobol:/tmp/TEST2 $ git init
+ Initialised empty Git repository in /tmp/TEST2/.git/
+
+ fozz@cobol:/tmp/TEST2 $ git annex init TEST2
+ init TEST2 ok
+ (Recording state in git...)
+
+ fozz@cobol:/tmp/TEST2 $ git add .
+
+ fozz@cobol:/tmp/TEST2 $ ls
+ Miami'05 Euro Trance
+
+ fozz@cobol:/tmp/TEST2 $ ls -alh Miami\'05\ Euro\ Trance/
+ total 127M
+ drwx------ 2 fozz fozz 4.0K Jul 28 12:56 .
+ drwxrwxr-x 4 fozz fozz 4.0K Jul 28 12:56 ..
+ -rwx------ 1 fozz fozz 13M Jul 28 12:56 01 - Hydroid Blue Tubes (Intro Mix).mp3
+ -rwx------ 1 fozz fozz 9.8M Jul 28 12:56 02 - Interstate I Found U (Harry Lemon Remix).mp3
+ -rwx------ 1 fozz fozz 15M Jul 28 12:56 03 - Kalafut & Fygle '3579 Km.mp3
+ -rwx------ 1 fozz fozz 11M Jul 28 12:56 04 - Hammer & Bennett Baltic Sea.mp3
+ -rwx------ 1 fozz fozz 11M Jul 28 12:56 05 - Fluid In Motion Soul Dimension.mp3
+ -rwx------ 1 fozz fozz 12M Jul 28 12:56 06 - Keo Close Enough (Noel Sanger Mix).mp3
+ -rwx------ 1 fozz fozz 9.4M Jul 28 12:56 08 - Lens Let The Light In.mp3
+ -rwx------ 1 fozz fozz 11M Jul 28 12:56 09 - Aronek Free Yourself.mp3
+ -rwx------ 1 fozz fozz 14M Jul 28 12:56 10 - Ava Mea In The End.mp3
+ -rwx------ 1 fozz fozz 13M Jul 28 12:56 11 - Sean Walsh Pres- Jagermaestro Quarter Century.mp3
+ -rwx------ 1 fozz fozz 12M Jul 28 12:56 12 - Max Graham Feat- Jessica Jacobs Gone.mp3
+ -rwx------ 1 fozz fozz 6.9K Jul 28 12:56 AlbumArt_{85E86538-46E1-412C-9D94-A67FC108ED97}_Large.jpg
+ -rwx------ 1 fozz fozz 2.1K Jul 28 12:56 AlbumArt_{85E86538-46E1-412C-9D94-A67FC108ED97}_Small.jpg
+ -rwx------ 1 fozz fozz 2.1K Jul 28 12:56 AlbumArtSmall.jpg
+ -rwx------ 1 fozz fozz 361 Jul 28 12:56 desktop.ini
+ -rwx------ 1 fozz fozz 6.9K Jul 28 12:56 Folder.jpg
+
+ fozz@cobol:/tmp/TEST2 $ cd ../
+
+ fozz@cobol:/tmp $ mkdir TEST3
+
+ fozz@cobol:/tmp $ cd TEST3
+
+ fozz@cobol:/tmp/TEST3 $ cp -R /mnt/store/Music/Jukebox/Markus\ Schulz/Miami\'05\ Euro\ Trance/ .
+
+ fozz@cobol:/tmp/TEST3 $ git init
+ Initialised empty Git repository in /tmp/TEST3/.git/
+
+ fozz@cobol:/tmp/TEST3 $ git annex init TEST3
+ init TEST3 ok
+ (Recording state in git...)
+
+ fozz@cobol:/tmp/TEST3 $ git annex add .
+ add Miami'05 Euro Trance/01 - Hydroid Blue Tubes (Intro Mix).mp3 (checksum...) ok
+ add Miami'05 Euro Trance/02 - Interstate I Found U (Harry Lemon Remix).mp3 (checksum...) ok
+ add Miami'05 Euro Trance/03 - Kalafut & Fygle '3579 Km.mp3 (checksum...) ok
+ add Miami'05 Euro Trance/04 - Hammer & Bennett Baltic Sea.mp3 (checksum...) ok
+ add Miami'05 Euro Trance/05 - Fluid In Motion Soul Dimension.mp3 (checksum...) ok
+ add Miami'05 Euro Trance/06 - Keo Close Enough (Noel Sanger Mix).mp3 (checksum...) ok
+ add Miami'05 Euro Trance/08 - Lens Let The Light In.mp3 (checksum...) ok
+ add Miami'05 Euro Trance/09 - Aronek Free Yourself.mp3 (checksum...) ok
+ add Miami'05 Euro Trance/10 - Ava Mea In The End.mp3 (checksum...) ok
+ add Miami'05 Euro Trance/11 - Sean Walsh Pres- Jagermaestro Quarter Century.mp3 (checksum...) ok
+ add Miami'05 Euro Trance/12 - Max Graham Feat- Jessica Jacobs Gone.mp3 (checksum...) ok
+ add Miami'05 Euro Trance/AlbumArtSmall.jpg (checksum...) ok
+ add Miami'05 Euro Trance/AlbumArt_{85E86538-46E1-412C-9D94-A67FC108ED97}_Large.jpg (checksum...) ok
+ add Miami'05 Euro Trance/AlbumArt_{85E86538-46E1-412C-9D94-A67FC108ED97}_Small.jpg (checksum...) ok
+ add Miami'05 Euro Trance/Folder.jpg (checksum...) ok
+ add Miami'05 Euro Trance/desktop.ini (checksum...) ok
+ (Recording state in git...)
+
+ fozz@cobol:/tmp/TEST3 $ md5sum Miami\'05\ Euro\ Trance/*
+ d764c06c5fc26f600842f4a9f2270696 Miami'05 Euro Trance/01 - Hydroid Blue Tubes (Intro Mix).mp3
+ 79879d4343a159fb391bd7eef691be03 Miami'05 Euro Trance/02 - Interstate I Found U (Harry Lemon Remix).mp3
+ cc440d6dfaa0f6ef736b51b972f91c8d Miami'05 Euro Trance/03 - Kalafut & Fygle '3579 Km.mp3
+ ff0e52278bb69b2e8e44aa318e486ca7 Miami'05 Euro Trance/04 - Hammer & Bennett Baltic Sea.mp3
+ 73ec88f2f09b825bef3d9b876e0fc876 Miami'05 Euro Trance/05 - Fluid In Motion Soul Dimension.mp3
+ d7790cde98696eb7f5e6a8b1d6949e1d Miami'05 Euro Trance/06 - Keo Close Enough (Noel Sanger Mix).mp3
+ 0734d432e0ae67155c4b0363d2336bfa Miami'05 Euro Trance/08 - Lens Let The Light In.mp3
+ 527335f6b173e13dacfa66f458df1a29 Miami'05 Euro Trance/09 - Aronek Free Yourself.mp3
+ b859ead1712e144a1e3fd64c1e36e493 Miami'05 Euro Trance/10 - Ava Mea In The End.mp3
+ a7771b91fbe8f0593e5c6ac51ccba4d8 Miami'05 Euro Trance/11 - Sean Walsh Pres- Jagermaestro Quarter Century.mp3
+ b167beaafe3fd95b06a1aa574affa355 Miami'05 Euro Trance/12 - Max Graham Feat- Jessica Jacobs Gone.mp3
+ 900bb78b629eab30c16d565562b3880a Miami'05 Euro Trance/AlbumArt_{85E86538-46E1-412C-9D94-A67FC108ED97}_Large.jpg
+ 9cfd8347becf87da8b1c5962e77267ad Miami'05 Euro Trance/AlbumArt_{85E86538-46E1-412C-9D94-A67FC108ED97}_Small.jpg
+ 9cfd8347becf87da8b1c5962e77267ad Miami'05 Euro Trance/AlbumArtSmall.jpg
+ 00e8488c206ad9a7ccb6d7f4bc66d05e Miami'05 Euro Trance/desktop.ini
+ 900bb78b629eab30c16d565562b3880a Miami'05 Euro Trance/Folder.jpg
+
+ fozz@cobol:/tmp/TEST3 $ git annex unadd .
+ git-annex: Unknown command 'unadd'
+
+ Did you mean one of these?
+ unused
+ unannex
+ upgrade
+
+
+ fozz@cobol:/tmp/TEST3 $ git annex unannex .
+ unannex Miami'05 Euro Trance/01 - Hydroid Blue Tubes (Intro Mix).mp3 ok
+ unannex Miami'05 Euro Trance/02 - Interstate I Found U (Harry Lemon Remix).mp3 ok
+ unannex Miami'05 Euro Trance/03 - Kalafut & Fygle '3579 Km.mp3 ok
+ unannex Miami'05 Euro Trance/04 - Hammer & Bennett Baltic Sea.mp3 ok
+ unannex Miami'05 Euro Trance/05 - Fluid In Motion Soul Dimension.mp3 ok
+ unannex Miami'05 Euro Trance/06 - Keo Close Enough (Noel Sanger Mix).mp3 ok
+ unannex Miami'05 Euro Trance/08 - Lens Let The Light In.mp3 ok
+ unannex Miami'05 Euro Trance/09 - Aronek Free Yourself.mp3 ok
+ unannex Miami'05 Euro Trance/10 - Ava Mea In The End.mp3 ok
+ unannex Miami'05 Euro Trance/11 - Sean Walsh Pres- Jagermaestro Quarter Century.mp3 ok
+ unannex Miami'05 Euro Trance/12 - Max Graham Feat- Jessica Jacobs Gone.mp3 ok
+ unannex Miami'05 Euro Trance/AlbumArtSmall.jpg ok
+ unannex Miami'05 Euro Trance/AlbumArt_{85E86538-46E1-412C-9D94-A67FC108ED97}_Large.jpg ok
+ unannex Miami'05 Euro Trance/desktop.ini ok
+ (Recording state in git...)
+
+ fozz@cobol:/tmp/TEST3 $ ls -alh
+ total 16K
+ drwxrwxr-x 4 fozz fozz 4.0K Jul 28 12:57 .
+ drwxrwxrwt 25 root root 4.0K Jul 28 12:56 ..
+ drwxrwxr-x 9 fozz fozz 4.0K Jul 28 12:57 .git
+ drwx------ 2 fozz fozz 4.0K Jul 28 12:57 Miami'05 Euro Trance
+
+ fozz@cobol:/tmp/TEST3 $ ls -alh Miami\'05\ Euro\ Trance/
+ total 127M
+ drwx------ 2 fozz fozz 4.0K Jul 28 12:57 .
+ drwxrwxr-x 4 fozz fozz 4.0K Jul 28 12:57 ..
+ -rwx------ 1 fozz fozz 13M Jul 28 12:56 01 - Hydroid Blue Tubes (Intro Mix).mp3
+ -rwx------ 1 fozz fozz 9.8M Jul 28 12:56 02 - Interstate I Found U (Harry Lemon Remix).mp3
+ -rwx------ 1 fozz fozz 15M Jul 28 12:56 03 - Kalafut & Fygle '3579 Km.mp3
+ -rwx------ 1 fozz fozz 11M Jul 28 12:56 04 - Hammer & Bennett Baltic Sea.mp3
+ -rwx------ 1 fozz fozz 11M Jul 28 12:56 05 - Fluid In Motion Soul Dimension.mp3
+ -rwx------ 1 fozz fozz 12M Jul 28 12:56 06 - Keo Close Enough (Noel Sanger Mix).mp3
+ -rwx------ 1 fozz fozz 9.4M Jul 28 12:56 08 - Lens Let The Light In.mp3
+ -rwx------ 1 fozz fozz 11M Jul 28 12:56 09 - Aronek Free Yourself.mp3
+ -rwx------ 1 fozz fozz 14M Jul 28 12:56 10 - Ava Mea In The End.mp3
+ -rwx------ 1 fozz fozz 13M Jul 28 12:56 11 - Sean Walsh Pres- Jagermaestro Quarter Century.mp3
+ -rwx------ 1 fozz fozz 12M Jul 28 12:56 12 - Max Graham Feat- Jessica Jacobs Gone.mp3
+ -rwx------ 1 fozz fozz 6.9K Jul 28 12:56 AlbumArt_{85E86538-46E1-412C-9D94-A67FC108ED97}_Large.jpg
+ lrwxrwxrwx 1 fozz fozz 195 Jul 28 12:56 AlbumArt_{85E86538-46E1-412C-9D94-A67FC108ED97}_Small.jpg -> ../.git/annex/objects/QF/JK/SHA256E-s2067--b870f34a1eee9fdfae8a488626b51d17f25f17788655fe8924d598109a95104a.jpg/SHA256E-s2067--b870f34a1eee9fdfae8a488626b51d17f25f17788655fe8924d598109a95104a.jpg
+ -rwx------ 1 fozz fozz 2.1K Jul 28 12:56 AlbumArtSmall.jpg
+ -rwx------ 1 fozz fozz 361 Jul 28 12:56 desktop.ini
+ lrwxrwxrwx 1 fozz fozz 195 Jul 28 12:56 Folder.jpg -> ../.git/annex/objects/1f/Xk/SHA256E-s7024--8d5778605b211e0971824df9a970f16b38dee97a6a529f41113c31378ef83f3f.jpg/SHA256E-s7024--8d5778605b211e0971824df9a970f16b38dee97a6a529f41113c31378ef83f3f.jpg
+
+ fozz@cobol:/tmp/TEST3 $ cd ../
+
+ fozz@cobol:/tmp $ mkdir TEST4
+
+ fozz@cobol:/tmp $ cd TEST4
+
+ fozz@cobol:/tmp/TEST4 $ export PATH=/tmp/git-annex.linux/:$PATH
+
+ fozz@cobol:/tmp/TEST4 $ git annex version
+ git-annex version: 4.20130725-g8140f7c
+ build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP
+
+ fozz@cobol:/tmp/TEST4 $ cp -R /mnt/store/Music/Jukebox/Markus\ Schulz/Miami\'05\ Euro\ Trance/ .
+
+ fozz@cobol:/tmp/TEST4 $ git init
+ Initialised empty Git repository in /tmp/TEST4/.git/
+
+ fozz@cobol:/tmp/TEST4 $ git annex init TEST4
+ init TEST4 ok
+ (Recording state in git...)
+
+ fozz@cobol:/tmp/TEST4 $ git annex add .
+ add Miami'05 Euro Trance/01 - Hydroid Blue Tubes (Intro Mix).mp3 (checksum...) ok
+ add Miami'05 Euro Trance/02 - Interstate I Found U (Harry Lemon Remix).mp3 (checksum...) ok
+ add Miami'05 Euro Trance/03 - Kalafut & Fygle '3579 Km.mp3 (checksum...) ok
+ add Miami'05 Euro Trance/04 - Hammer & Bennett Baltic Sea.mp3 (checksum...) ok
+ add Miami'05 Euro Trance/05 - Fluid In Motion Soul Dimension.mp3 (checksum...) ok
+ add Miami'05 Euro Trance/06 - Keo Close Enough (Noel Sanger Mix).mp3 (checksum...) ok
+ add Miami'05 Euro Trance/08 - Lens Let The Light In.mp3 (checksum...) ok
+ add Miami'05 Euro Trance/09 - Aronek Free Yourself.mp3 (checksum...) ok
+ add Miami'05 Euro Trance/10 - Ava Mea In The End.mp3 (checksum...) ok
+ add Miami'05 Euro Trance/11 - Sean Walsh Pres- Jagermaestro Quarter Century.mp3 (checksum...) ok
+ add Miami'05 Euro Trance/12 - Max Graham Feat- Jessica Jacobs Gone.mp3 (checksum...) ok
+ add Miami'05 Euro Trance/AlbumArtSmall.jpg (checksum...) ok
+ add Miami'05 Euro Trance/AlbumArt_{85E86538-46E1-412C-9D94-A67FC108ED97}_Large.jpg (checksum...) ok
+ add Miami'05 Euro Trance/AlbumArt_{85E86538-46E1-412C-9D94-A67FC108ED97}_Small.jpg (checksum...) ok
+ add Miami'05 Euro Trance/Folder.jpg (checksum...) ok
+ add Miami'05 Euro Trance/desktop.ini (checksum...) ok
+ (Recording state in git...)
+
+ fozz@cobol:/tmp/TEST4 $ ls -alh Miami\'05\ Euro\ Trance/
+ total 72K
+ drwx------ 2 fozz fozz 4.0K Jul 28 12:59 .
+ drwxrwxr-x 4 fozz fozz 4.0K Jul 28 12:59 ..
+ lrwxrwxrwx 1 fozz fozz 203 Jul 28 12:59 01 - Hydroid Blue Tubes (Intro Mix).mp3 -> ../.git/annex/objects/6k/g1/SHA256E-s13016103--3eb29d6f0a529ccb2717b6e2b108c8adb681c47430bdcd45526279fabcfd1be4.mp3/SHA256E-s13016103--3eb29d6f0a529ccb2717b6e2b108c8adb681c47430bdcd45526279fabcfd1be4.mp3
+ lrwxrwxrwx 1 fozz fozz 203 Jul 28 12:59 02 - Interstate I Found U (Harry Lemon Remix).mp3 -> ../.git/annex/objects/5X/5J/SHA256E-s10172374--12a9af95efbb5c4928b1ce0750eb25b85b2889a74798cac24165be5b0a085e38.mp3/SHA256E-s10172374--12a9af95efbb5c4928b1ce0750eb25b85b2889a74798cac24165be5b0a085e38.mp3
+ lrwxrwxrwx 1 fozz fozz 203 Jul 28 12:59 03 - Kalafut & Fygle '3579 Km.mp3 -> ../.git/annex/objects/6g/FX/SHA256E-s15400659--adce5bdcc75242c3e996dcac7df309fcd2cc32fd5ed04ddcfbbf3c82147de85d.mp3/SHA256E-s15400659--adce5bdcc75242c3e996dcac7df309fcd2cc32fd5ed04ddcfbbf3c82147de85d.mp3
+ lrwxrwxrwx 1 fozz fozz 203 Jul 28 12:59 04 - Hammer & Bennett Baltic Sea.mp3 -> ../.git/annex/objects/jV/z0/SHA256E-s10980459--d1ea5664b2c093dcf964f02760a76e8b23b4cadbd7d9e372281f1888b6813c95.mp3/SHA256E-s10980459--d1ea5664b2c093dcf964f02760a76e8b23b4cadbd7d9e372281f1888b6813c95.mp3
+ lrwxrwxrwx 1 fozz fozz 203 Jul 28 12:59 05 - Fluid In Motion Soul Dimension.mp3 -> ../.git/annex/objects/q4/5m/SHA256E-s10850525--250366b97e4383fdcc34ffdfa4f5d4231471da4beb600e16c7fb994341241b94.mp3/SHA256E-s10850525--250366b97e4383fdcc34ffdfa4f5d4231471da4beb600e16c7fb994341241b94.mp3
+ lrwxrwxrwx 1 fozz fozz 203 Jul 28 12:59 06 - Keo Close Enough (Noel Sanger Mix).mp3 -> ../.git/annex/objects/mW/kF/SHA256E-s11686327--b6fd86d3db9b3ea47338c968f8ba00e8ed263f4c6d17ae148f25802edfc0d743.mp3/SHA256E-s11686327--b6fd86d3db9b3ea47338c968f8ba00e8ed263f4c6d17ae148f25802edfc0d743.mp3
+ lrwxrwxrwx 1 fozz fozz 201 Jul 28 12:59 08 - Lens Let The Light In.mp3 -> ../.git/annex/objects/Mx/Wv/SHA256E-s9854587--29c1bf00c9bf9076770a1be5c6d697f50a606ad4fcd4a2ada638a12984b38137.mp3/SHA256E-s9854587--29c1bf00c9bf9076770a1be5c6d697f50a606ad4fcd4a2ada638a12984b38137.mp3
+ lrwxrwxrwx 1 fozz fozz 203 Jul 28 12:59 09 - Aronek Free Yourself.mp3 -> ../.git/annex/objects/6j/X5/SHA256E-s11110678--9b4744767261bc373c310d423dbd8eeebe8bf88355d88229a5ff1e7036fa845b.mp3/SHA256E-s11110678--9b4744767261bc373c310d423dbd8eeebe8bf88355d88229a5ff1e7036fa845b.mp3
+ lrwxrwxrwx 1 fozz fozz 203 Jul 28 12:59 10 - Ava Mea In The End.mp3 -> ../.git/annex/objects/gf/5w/SHA256E-s14527761--ee711177de4d2d3375edf6d1b25c5b0adcb22c16b89dc0ed1bcca5e65e9d916b.mp3/SHA256E-s14527761--ee711177de4d2d3375edf6d1b25c5b0adcb22c16b89dc0ed1bcca5e65e9d916b.mp3
+ lrwxrwxrwx 1 fozz fozz 203 Jul 28 12:59 11 - Sean Walsh Pres- Jagermaestro Quarter Century.mp3 -> ../.git/annex/objects/g7/j8/SHA256E-s12639172--1e348a80570a09d0df8ea5c1ca66743529b6c79b358aae8a661f536a6c6fd412.mp3/SHA256E-s12639172--1e348a80570a09d0df8ea5c1ca66743529b6c79b358aae8a661f536a6c6fd412.mp3
+ lrwxrwxrwx 1 fozz fozz 203 Jul 28 12:59 12 - Max Graham Feat- Jessica Jacobs Gone.mp3 -> ../.git/annex/objects/0g/g7/SHA256E-s12031267--85094321ce9f272935bcf370d7a6fb9d4f8d3f02d0dffaa30edcf7199b3b1929.mp3/SHA256E-s12031267--85094321ce9f272935bcf370d7a6fb9d4f8d3f02d0dffaa30edcf7199b3b1929.mp3
+ lrwxrwxrwx 1 fozz fozz 195 Jul 28 12:59 AlbumArt_{85E86538-46E1-412C-9D94-A67FC108ED97}_Large.jpg -> ../.git/annex/objects/1f/Xk/SHA256E-s7024--8d5778605b211e0971824df9a970f16b38dee97a6a529f41113c31378ef83f3f.jpg/SHA256E-s7024--8d5778605b211e0971824df9a970f16b38dee97a6a529f41113c31378ef83f3f.jpg
+ lrwxrwxrwx 1 fozz fozz 195 Jul 28 12:59 AlbumArt_{85E86538-46E1-412C-9D94-A67FC108ED97}_Small.jpg -> ../.git/annex/objects/QF/JK/SHA256E-s2067--b870f34a1eee9fdfae8a488626b51d17f25f17788655fe8924d598109a95104a.jpg/SHA256E-s2067--b870f34a1eee9fdfae8a488626b51d17f25f17788655fe8924d598109a95104a.jpg
+ lrwxrwxrwx 1 fozz fozz 195 Jul 28 12:59 AlbumArtSmall.jpg -> ../.git/annex/objects/QF/JK/SHA256E-s2067--b870f34a1eee9fdfae8a488626b51d17f25f17788655fe8924d598109a95104a.jpg/SHA256E-s2067--b870f34a1eee9fdfae8a488626b51d17f25f17788655fe8924d598109a95104a.jpg
+ lrwxrwxrwx 1 fozz fozz 193 Jul 28 12:59 desktop.ini -> ../.git/annex/objects/Kk/Fj/SHA256E-s361--9762858358f71b43e0dc89f54cf53342ec1c626ee17922b80fa4f981d0bc3a1b.ini/SHA256E-s361--9762858358f71b43e0dc89f54cf53342ec1c626ee17922b80fa4f981d0bc3a1b.ini
+ lrwxrwxrwx 1 fozz fozz 195 Jul 28 12:59 Folder.jpg -> ../.git/annex/objects/1f/Xk/SHA256E-s7024--8d5778605b211e0971824df9a970f16b38dee97a6a529f41113c31378ef83f3f.jpg/SHA256E-s7024--8d5778605b211e0971824df9a970f16b38dee97a6a529f41113c31378ef83f3f.jpg
+
+ fozz@cobol:/tmp/TEST4 $ git annex unannex .
+ unannex Miami'05 Euro Trance/01 - Hydroid Blue Tubes (Intro Mix).mp3 ok
+ unannex Miami'05 Euro Trance/02 - Interstate I Found U (Harry Lemon Remix).mp3 ok
+ unannex Miami'05 Euro Trance/03 - Kalafut & Fygle '3579 Km.mp3 ok
+ unannex Miami'05 Euro Trance/04 - Hammer & Bennett Baltic Sea.mp3 ok
+ unannex Miami'05 Euro Trance/05 - Fluid In Motion Soul Dimension.mp3 ok
+ unannex Miami'05 Euro Trance/06 - Keo Close Enough (Noel Sanger Mix).mp3 ok
+ unannex Miami'05 Euro Trance/08 - Lens Let The Light In.mp3 ok
+ unannex Miami'05 Euro Trance/09 - Aronek Free Yourself.mp3 ok
+ unannex Miami'05 Euro Trance/10 - Ava Mea In The End.mp3 ok
+ unannex Miami'05 Euro Trance/11 - Sean Walsh Pres- Jagermaestro Quarter Century.mp3 ok
+ unannex Miami'05 Euro Trance/12 - Max Graham Feat- Jessica Jacobs Gone.mp3 ok
+ unannex Miami'05 Euro Trance/AlbumArtSmall.jpg ok
+ unannex Miami'05 Euro Trance/AlbumArt_{85E86538-46E1-412C-9D94-A67FC108ED97}_Large.jpg ok
+ unannex Miami'05 Euro Trance/desktop.ini ok
+ (Recording state in git...)
+
+ fozz@cobol:/tmp/TEST4 $ ls -alh Miami\'05\ Euro\ Trance/
+ total 127M
+ drwx------ 2 fozz fozz 4.0K Jul 28 13:00 .
+ drwxrwxr-x 4 fozz fozz 4.0K Jul 28 12:59 ..
+ -rwx------ 1 fozz fozz 13M Jul 28 12:59 01 - Hydroid Blue Tubes (Intro Mix).mp3
+ -rwx------ 1 fozz fozz 9.8M Jul 28 12:59 02 - Interstate I Found U (Harry Lemon Remix).mp3
+ -rwx------ 1 fozz fozz 15M Jul 28 12:59 03 - Kalafut & Fygle '3579 Km.mp3
+ -rwx------ 1 fozz fozz 11M Jul 28 12:59 04 - Hammer & Bennett Baltic Sea.mp3
+ -rwx------ 1 fozz fozz 11M Jul 28 12:59 05 - Fluid In Motion Soul Dimension.mp3
+ -rwx------ 1 fozz fozz 12M Jul 28 12:59 06 - Keo Close Enough (Noel Sanger Mix).mp3
+ -rwx------ 1 fozz fozz 9.4M Jul 28 12:59 08 - Lens Let The Light In.mp3
+ -rwx------ 1 fozz fozz 11M Jul 28 12:59 09 - Aronek Free Yourself.mp3
+ -rwx------ 1 fozz fozz 14M Jul 28 12:59 10 - Ava Mea In The End.mp3
+ -rwx------ 1 fozz fozz 13M Jul 28 12:59 11 - Sean Walsh Pres- Jagermaestro Quarter Century.mp3
+ -rwx------ 1 fozz fozz 12M Jul 28 12:59 12 - Max Graham Feat- Jessica Jacobs Gone.mp3
+ -rwx------ 1 fozz fozz 6.9K Jul 28 12:59 AlbumArt_{85E86538-46E1-412C-9D94-A67FC108ED97}_Large.jpg
+ lrwxrwxrwx 1 fozz fozz 195 Jul 28 12:59 AlbumArt_{85E86538-46E1-412C-9D94-A67FC108ED97}_Small.jpg -> ../.git/annex/objects/QF/JK/SHA256E-s2067--b870f34a1eee9fdfae8a488626b51d17f25f17788655fe8924d598109a95104a.jpg/SHA256E-s2067--b870f34a1eee9fdfae8a488626b51d17f25f17788655fe8924d598109a95104a.jpg
+ -rwx------ 1 fozz fozz 2.1K Jul 28 12:59 AlbumArtSmall.jpg
+ -rwx------ 1 fozz fozz 361 Jul 28 12:59 desktop.ini
+ lrwxrwxrwx 1 fozz fozz 195 Jul 28 12:59 Folder.jpg -> ../.git/annex/objects/1f/Xk/SHA256E-s7024--8d5778605b211e0971824df9a970f16b38dee97a6a529f41113c31378ef83f3f.jpg/SHA256E-s7024--8d5778605b211e0971824df9a970f16b38dee97a6a529f41113c31378ef83f3f.jpg
+
+Obviously the remaining symlinks in TEST3 and TEST4 are now broken and show up red on my terminal.
+
+"""]]
diff --git a/doc/bugs/unannex_removes_object_even_if_referred_to_by_others/comment_5_c0e7742672db2629bd906cebefe74f72._comment b/doc/bugs/unannex_removes_object_even_if_referred_to_by_others/comment_5_c0e7742672db2629bd906cebefe74f72._comment
new file mode 100644
index 000000000..4b6ae9349
--- /dev/null
+++ b/doc/bugs/unannex_removes_object_even_if_referred_to_by_others/comment_5_c0e7742672db2629bd906cebefe74f72._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.21"
+ subject="comment 5"
+ date="2013-07-30T18:39:58Z"
+ content="""
+Your transcript shows unannex without --fast having the problem, and uninit not having the problem. Which is just what I said. Although I had to spend 15 minutes reading and replicating your transcript to figure that out.
+
+This has been previously reported and discussed at [[Large_unannex_operations_result_in_stale_symlinks_and_data_loss]]. There does not seem to be a single entirely satesfactory solution. unannex --fast seems to be what you're looking for.
+"""]]
diff --git a/doc/bugs/unannex_removes_object_even_if_referred_to_by_others/comment_6_c56171665db3ed14109a09097d49ac5d._comment b/doc/bugs/unannex_removes_object_even_if_referred_to_by_others/comment_6_c56171665db3ed14109a09097d49ac5d._comment
new file mode 100644
index 000000000..692813fbd
--- /dev/null
+++ b/doc/bugs/unannex_removes_object_even_if_referred_to_by_others/comment_6_c56171665db3ed14109a09097d49ac5d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnRai_qFYPVvEgC6i1nlM1bh-C__jbhqS0"
+ nickname="Matthew"
+ subject="comment 6"
+ date="2013-07-30T19:01:31Z"
+ content="""
+You're right, sorry, I missed the \"--fast\", I'd spent all morning replicating the n~ bug on my phone and recovering from unannex wasn't a short job either.
+"""]]
diff --git a/doc/bugs/unannex_vs_unlock_hook_confusion.mdwn b/doc/bugs/unannex_vs_unlock_hook_confusion.mdwn
new file mode 100644
index 000000000..c03990c20
--- /dev/null
+++ b/doc/bugs/unannex_vs_unlock_hook_confusion.mdwn
@@ -0,0 +1,15 @@
+See [[forum/unannex_alternatives]] for problem description.
+
+If an unannex is followed by a "git add; git commit", git-annex's hook thinks
+that you have used git annex unlock on the file and are
+now committing a changed version, and the right thing to do there is to add the
+new content to the annex and update the symlink accordingly.
+
+Can we tell the difference between an unannexed file that has yet to be committed
+and has been re-added as a normal file, vs an unlocked file? --[[Joey||
+
+> Hmm, not really. An unannexed file's content will have been dropped from
+> the backend, but that's about the only difference. Perhaps unannex should
+> just commit the removal of the file itself? --[[Joey]]
+
+> [[done]], staged changes committed at end.
diff --git a/doc/bugs/undefined.mdwn b/doc/bugs/undefined.mdwn
new file mode 100644
index 000000000..8ee37f034
--- /dev/null
+++ b/doc/bugs/undefined.mdwn
@@ -0,0 +1,5 @@
+Trying to move files from a local remote that is not mounted:
+
+ git-annex: Prelude.undefined
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/unfinished_repos_in_webapp.mdwn b/doc/bugs/unfinished_repos_in_webapp.mdwn
new file mode 100644
index 000000000..b3e667c61
--- /dev/null
+++ b/doc/bugs/unfinished_repos_in_webapp.mdwn
@@ -0,0 +1,31 @@
+### Please describe the problem.
+
+Hi, all excited that the new release fixes the unknown UUID issue in the Webapp I hurridly installed the latest versions.
+
+Some progress in that the webapp now reports my missing/non-existent repo as an "unfinished repository" in the process of being setup. I see a check status box that when clicked says "in progress please be patient". Also I see the ssh config has changed to use IdentitiesOnly option.
+
+I had a go a deleting details via git-annex vicfg and directly editing the git-annex branch log files as detailed [here](http://git-annex.branchable.com/forum/Reappearing_repos_in_webapp_and_vicfg/). But still no joy.
+
+Any hints on what to do? Nothing in the log seems to help...
+
+### What steps will reproduce the problem?
+
+Not sure anymore.
+
+### What version of git-annex are you using? On what operating system?
+
+Latest.
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
+
+> This seems to be [[done]], at least the bug reporter didn't feel the need
+> to follow up with the info I asked for and says the problem does not
+> affect him. --[[Joey]]
diff --git a/doc/bugs/unfinished_repos_in_webapp/comment_1_9628b100e39489be9f28ef75276a7341._comment b/doc/bugs/unfinished_repos_in_webapp/comment_1_9628b100e39489be9f28ef75276a7341._comment
new file mode 100644
index 000000000..e17c1b899
--- /dev/null
+++ b/doc/bugs/unfinished_repos_in_webapp/comment_1_9628b100e39489be9f28ef75276a7341._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 1"
+ date="2013-08-07T16:07:56Z"
+ content="""
+It seems to me that it has already finished applying the workaround. That IdentitiesOnly change could only be made
+if you clicked on a Retry button once it detected a problem.
+
+You may be experiencing a different problem that it cannot recover from. Paste your .git/config file.
+"""]]
diff --git a/doc/bugs/unfinished_repos_in_webapp/comment_2_ba0fbff536b1d067c4098db401dc49f2._comment b/doc/bugs/unfinished_repos_in_webapp/comment_2_ba0fbff536b1d067c4098db401dc49f2._comment
new file mode 100644
index 000000000..8170a0175
--- /dev/null
+++ b/doc/bugs/unfinished_repos_in_webapp/comment_2_ba0fbff536b1d067c4098db401dc49f2._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnXybLxkPMYpP3yw4b_I6IdC3cKTD-xEdU"
+ nickname="Matt"
+ subject="comment 2"
+ date="2013-08-08T08:33:32Z"
+ content="""
+Hi, I've sorted this now. The IP address of my laptop had changed on the local network. Fixing it then let the new fix fully work and the in-progress status of the bad repo went away.
+
+Is it right that in the UI I don't see the local LAN configured branch (which I setup for speed) - it all seems to come under the jabber account now and makes an appropriate choice?
+"""]]
diff --git a/doc/bugs/unfinished_repos_in_webapp/comment_3_fd554aa7d93117177784a29270ccf790._comment b/doc/bugs/unfinished_repos_in_webapp/comment_3_fd554aa7d93117177784a29270ccf790._comment
new file mode 100644
index 000000000..cd21af092
--- /dev/null
+++ b/doc/bugs/unfinished_repos_in_webapp/comment_3_fd554aa7d93117177784a29270ccf790._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawniayrgSdVLUc3c6bf93VbO-_HT4hzxmyo"
+ nickname="Tobias"
+ subject="comment 3"
+ date="2013-08-08T12:22:28Z"
+ content="""
+I also see `unfinished repository` in the assistant, but only at git remotes which don't have git-annex installed (f.e. gitlab). annex-ignore is set to true: `git config remote.gitlab.annex-ignore true`.
+
+Clicking on `check status` says `Setting up this repository seems to have stalled! Make sure the remote system is available and retry`
+
+git-annex version: 4.20130802-g1452ac3
+"""]]
diff --git a/doc/bugs/unfinished_repository_when_using_annex-ignore_true_.mdwn b/doc/bugs/unfinished_repository_when_using_annex-ignore_true_.mdwn
new file mode 100644
index 000000000..848f1b30b
--- /dev/null
+++ b/doc/bugs/unfinished_repository_when_using_annex-ignore_true_.mdwn
@@ -0,0 +1,25 @@
+### Please describe the problem.
+
+When using a git remote which doesn't support git-annex (f.e. gitlab) and is configured with `annex-ignore true` the remote is shown as `unfinished repository` in the webapp.
+
+It would be nice if the webapp would recognize this and show the remote as git-only remote including sync-state and remote name (or even better: the remote details, like the URL to the remote)
+
+### What steps will reproduce the problem?
+
+Add a normal git remote and configure `git config remote.<name>.annex-ignore true`.
+Start the webapp.
+
+### What version of git-annex are you using? On what operating system?
+
+ git-annex version: 4.20131101-gf59a6d1
+ build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP Feeds Quvi TDFA
+ key/value backends: SHA256E SHA1E SHA512E SHA224E SHA384E SHA256 SHA1 SHA512 SHA224 SHA384 WORM URL
+ remote types: git gcrypt S3 bup directory rsync web webdav glacier hook
+ local repository version: 3
+ default repository version: 3
+ supported repository versions: 3 4
+ upgrade supported from repository versions: 0 1 2
+
+Kubuntu 13.10 x86_64
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/unhappy_without_UTF8_locale.mdwn b/doc/bugs/unhappy_without_UTF8_locale.mdwn
new file mode 100644
index 000000000..8d22b9ee4
--- /dev/null
+++ b/doc/bugs/unhappy_without_UTF8_locale.mdwn
@@ -0,0 +1,41 @@
+Try unsetting LANG and passing git-annex unicode filenames.
+
+ joey@gnu:~/tmp/aa>git annex add ./Üa
+ add add add add git-annex: <stdout>: commitAndReleaseBuffer: invalid
+ argument (Invalid or incomplete multibyte or wide character)
+
+> Interestingly, I can get the same crash in the de_DE.UTF-8 locale
+> with certian input filenames, while in en_US.UTF-8, it's ok.
+> The workaround below avoided the problem in de_DE.UTF-8. --[[Joey]]
+
+> Put in the utf-8 forcing workaround for now. [[done]] --[[Joey]]
+
+## underlying haskell problem and workaround
+
+The same problem can be seen with a simple haskell program:
+
+ import System.Environment
+ import Codec.Binary.UTF8.String
+ main = do
+ args <- getArgs
+ putStrLn $ decodeString $ args !! 0
+
+ joey@gnu:~/src/git-annex>LANG= runghc ~/foo.hs Ü
+ foo.hs: <stdout>: hPutChar: invalid argument (Invalid or incomplete multibyte or wide character)
+
+(The call to `decodeString` is necessary to make the input
+unicode string be displayed properly in a utf8 locale, but
+does not contribute to this problem.)
+
+I guess that haskell is setting the IO encoding to latin1, which
+is [documented](http://haskell.org/ghc/docs/latest/html/libraries/base/System-IO.html#v:latin1)
+to error out on characters > 255.
+
+So this program doesn't have the problem -- but may output garbage
+on non-utf-8 capable terminals:
+
+ import System.IO
+ main = do
+ hSetEncoding stdout utf8
+ args <- getArgs
+ putStrLn $ decodeString $ args !! 0
diff --git a/doc/bugs/uninit_and_indirect_don__39__t_work_on_android.mdwn b/doc/bugs/uninit_and_indirect_don__39__t_work_on_android.mdwn
new file mode 100644
index 000000000..b3a2ba37c
--- /dev/null
+++ b/doc/bugs/uninit_and_indirect_don__39__t_work_on_android.mdwn
@@ -0,0 +1,23 @@
+### Please describe the problem.
+I am unable to restore a git-annex dir to its pre init state.
+
+### What steps will reproduce the problem?
+init a git-annex dir on android with a file system with out symlinks.
+use for a while.
+Run: "git-annex uninit" -> You cannot run this command in a direct mode repository.
+Run: "git-annex indirect" -> Git is configured to not use symlinks, so you must use direct mode.
+
+### What version of git-annex are you using? On what operating system?
+git-annex version: 4.20130601-g7483ca4
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
+
+> [[done]]; added support for direct mode --[[Joey]]
diff --git a/doc/bugs/uninit_and_indirect_don__39__t_work_on_android/comment_1_fec69c4c41987b9469eaa8f745c0a124._comment b/doc/bugs/uninit_and_indirect_don__39__t_work_on_android/comment_1_fec69c4c41987b9469eaa8f745c0a124._comment
new file mode 100644
index 000000000..e310c1afd
--- /dev/null
+++ b/doc/bugs/uninit_and_indirect_don__39__t_work_on_android/comment_1_fec69c4c41987b9469eaa8f745c0a124._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.140"
+ subject="comment 1"
+ date="2013-07-20T23:20:48Z"
+ content="""
+There's no way to make indirect mode work on a filesystem w/o symlinks, but it should be possible to make unannex (required for uninit) work in direct mode. Just has not been done yet.
+"""]]
diff --git a/doc/bugs/uninit_and_indirect_don__39__t_work_on_android/comment_2_54c3fa77a069b36d03c41aad08fee9af._comment b/doc/bugs/uninit_and_indirect_don__39__t_work_on_android/comment_2_54c3fa77a069b36d03c41aad08fee9af._comment
new file mode 100644
index 000000000..ad6d65191
--- /dev/null
+++ b/doc/bugs/uninit_and_indirect_don__39__t_work_on_android/comment_2_54c3fa77a069b36d03c41aad08fee9af._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm_cen0223TLcWCTPwCPecCQC5JxGnPO04"
+ nickname="Eric"
+ subject="comment 2"
+ date="2013-07-20T23:26:23Z"
+ content="""
+unannex an uninit are the main thing, so that people have an exit strategy for git-annex on android.
+"""]]
diff --git a/doc/bugs/uninit_does_not_abort_when_hard_link_creation_fails.mdwn b/doc/bugs/uninit_does_not_abort_when_hard_link_creation_fails.mdwn
new file mode 100644
index 000000000..2d98929ab
--- /dev/null
+++ b/doc/bugs/uninit_does_not_abort_when_hard_link_creation_fails.mdwn
@@ -0,0 +1,47 @@
+> What steps will reproduce the problem?
+
+Issue the following commands on a file system where hard links are disabled:
+
+ $ touch foo
+
+ $ ln foo bar # just to check that hard links are disabled
+ ln: failed to create hard link `bar' => `foo': Operation not permitted
+
+ $ git init && git annex init
+
+ $ git annex add .
+
+ $ git annex uninit
+ unannex foo
+ git-annex: [...]: createLink: permission denied (Operation not permitted)
+ failed
+ Deleted branch git-annex [...].
+
+ $ echo $? # exit status of last command
+ 0
+
+ $ ls foo
+ ls: cannot access foo: No such file or directory
+
+
+> What is the expected output? What do you see instead?
+
+`git annex uninit` should abort and exit with a non-`0` return code. Instead, `git annex uninit` cleans up git-annex objects and exits with return code `0`.
+
+
+> What version of git-annex are you using? On what operating system?
+
+3.20120406 on Ubuntu 12.04.1.
+
+
+> Please provide any additional information below.
+
+git-annex should probably not be used on a file system where hard links are disabled.
+
+However, if the user is not aware that he's using git-annex on such a filesystem, he will accidently delete his annexed files by issuing a `git annex uninit` command.
+
+> git-annex needs a POSIX filesystem, which includes the ability to create
+> hard links. The `git annex add` in the example above will fail
+> trying to create a hard link with current versions.
+>
+> I've made uninit fall back to a non-hard link mode. [[done]] --[[Joey]]
diff --git a/doc/bugs/uninit_does_not_work_in_old_repos.mdwn b/doc/bugs/uninit_does_not_work_in_old_repos.mdwn
new file mode 100644
index 000000000..d3df06148
--- /dev/null
+++ b/doc/bugs/uninit_does_not_work_in_old_repos.mdwn
@@ -0,0 +1,20 @@
+As uninit does not need to actually write out any data, just remove it, it should be possible to uninit in old stores.
+
+ % git annex uninit
+ git-annex: Repository version 2 is not supported. Upgrade this repository: git-annex upgrade
+
+If the repo happens to be broken, this essentially locks in data.
+
+> No, because you can always check out the version of git-annex you need
+> for that repository.
+>
+> uninit, as implemented, runs unannex on every file and then does some
+> cleanup. The cleanup does not need to write state, but the unannex does.
+> And it depends on the object directory layout, which has changed between
+> versions. So supporting old versions in this code would complicate it
+> quite a lot. I don't want to go there. --[[Joey]]
+
+>>Requiring a version upgrade for unannex is fine. Yet, I see a problem when a git repo is broken; you are stuck without being able to uninit. In this case an uninit that does nothing but undo the symlinking would be useful. -- Richard
+
+>>> As I said, version 2 of git-annex is still there for people who need
+>>> it for whatever reason. [[done]] --[[Joey]]
diff --git a/doc/bugs/uninit_does_not_work_in_old_repos/comment_1_bc0619c6e17139df74639448aa6a0f72._comment b/doc/bugs/uninit_does_not_work_in_old_repos/comment_1_bc0619c6e17139df74639448aa6a0f72._comment
new file mode 100644
index 000000000..7a1ea582b
--- /dev/null
+++ b/doc/bugs/uninit_does_not_work_in_old_repos/comment_1_bc0619c6e17139df74639448aa6a0f72._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 1"
+ date="2011-10-29T15:30:09Z"
+ content="""
+After upgrading the repo, I still have to commit the changes, else git-annex won't let me uninit. Arguably a Good Thing, but I wanted to document it here.
+"""]]
diff --git a/doc/bugs/uninit_loses_data_if_git-annex_add_didn__39__t_complete.mdwn b/doc/bugs/uninit_loses_data_if_git-annex_add_didn__39__t_complete.mdwn
new file mode 100644
index 000000000..61cfa89a5
--- /dev/null
+++ b/doc/bugs/uninit_loses_data_if_git-annex_add_didn__39__t_complete.mdwn
@@ -0,0 +1,15 @@
+* Create a git-annex repo where a lot of files live.
+* Start an annex add.
+* Kill it.
+* git-annex uninit
+
+Now, whatever files were annexed (ie: moved to .git/annex/objects/) but not committed are lost as the .git/annex directory was deleted.
+
+I know there are two conflicting issues here:
+
+1. if there is legitimately unused data in .git/annex then that shouldn't be unannexed
+2. the above case where some files were annexed but not committed should be unannexed
+
+Maybe uninit could check to see if all symlinks currently in the repo pointing to something under .git/annex/objects are committed. If not, commit them then uninit, or just de-annex them.
+
+> Added a check for this, [[done]] --[[Joey]]
diff --git a/doc/bugs/uninit_should_not_run_when_branch_git-annex_is_checked_out.mdwn b/doc/bugs/uninit_should_not_run_when_branch_git-annex_is_checked_out.mdwn
new file mode 100644
index 000000000..e4e407ec8
--- /dev/null
+++ b/doc/bugs/uninit_should_not_run_when_branch_git-annex_is_checked_out.mdwn
@@ -0,0 +1,15 @@
+Running `git annex uninit` in a repo which has branch git-annex checked out will result in:
+
+ error: Cannot delete the branch 'git-annex' which you are currently on.
+ git-annex: git [Param "-D",Param "git-annex"] failed
+
+and trying to checkout branch master afterwards results in:
+
+ error: The following untracked working tree files would be overwritten by checkout:
+
+Both of which is logical. The best thing would be if git-annex refused to run uninit while in branch git-annex.
+
+
+Richard
+
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/unlock_fails_silently_with_directory_symlinks.mdwn b/doc/bugs/unlock_fails_silently_with_directory_symlinks.mdwn
new file mode 100644
index 000000000..9b9bb6342
--- /dev/null
+++ b/doc/bugs/unlock_fails_silently_with_directory_symlinks.mdwn
@@ -0,0 +1,53 @@
+What steps will reproduce the problem?
+
++ ```~/``` is tracked by git and git annex
++ ```~/text/books/foo``` is annexed
++ ```~/books``` is a symlink to ```text/books```
++ from ```~/``` execute: ```git annex unlock books/foo```
++ which returns immediately with zero exit code and does not unlock foo.
+
+What is the expected output? What do you see instead?
+
++ I expect ```~/text/books/foo`` to be unlocked
+
++ I think ```git annex unlock``` should resolve the symlinks and realize that this is a tracked file.
+
+What version of git-annex are you using? On what operating system?
+
++ 3.20121112 in debian unstable
+
+Please provide any additional information below.
+
++ I can unlock foo if I provide the full path, eg:
+from ```~/``` execute: ```git annex unlock text/books/foo```
+
++ Interestingly, the following _does_ successfully unlock the file: ```cd ~/books && git annex unlock foo```
+
+ So it seems that symlinks in $PWD are being resolved, but not those in file paths passed as arguments.
+
+Thank you, thank you!
+
+ - Jason
+
+jason@jasonwoof.com
+
+> I'm afraid this is not a bug. Here's why: If you run "git mv books/foo
+> books/bar", git will complain:
+>
+>> fatal: not under version control, source=books/foo, destination=books/bar
+>
+> So git-annex is just following git's lead (indeed, it's just running
+> `git ls-files` to find files to act on), and git doesn't
+> recognise this path as a file that's in git. --[[Joey]]
+
++ Also, I think ```git annex unlock``` should emit an error message if a file explicitly addressed on the commandline can not be acted upon.
+
+> I'm beginning to think perhaps it should. Users seem to find the current
+> behavior to be sometimes confusing.
+>
+> However, it's actually a very difficult change to make. Several commands
+> have multiple seek stages that act on different types of files, so
+> any warning printed by an earlier stage may be premature if a later
+> stage comes along and deals with a file. --[[Joey]]
+
+>> Figured out a non-invasive way to add that warning. [[done]] --[[Joey]]
diff --git a/doc/bugs/unlock_not_working_on_os_x_10.6_-_cp:_illegal_option_--_-_.mdwn b/doc/bugs/unlock_not_working_on_os_x_10.6_-_cp:_illegal_option_--_-_.mdwn
new file mode 100644
index 000000000..3704334f3
--- /dev/null
+++ b/doc/bugs/unlock_not_working_on_os_x_10.6_-_cp:_illegal_option_--_-_.mdwn
@@ -0,0 +1,22 @@
+What steps will reproduce the problem?
+
+ try to unlock a file in a git annex checkout
+
+What is the expected output? What do you see instead?
+
+ % git annex unlock FILENAME
+ unlock FILENAME (copying...) cp: illegal option -- -
+ usage: cp [-R [-H | -L | -P]] [-fi | -n] [-apvX] source_file target_file
+ cp [-R [-H | -L | -P]] [-fi | -n] [-apvX] source_file ... target_directory
+ git-annex: copy failed!
+
+ (should unlock the file)
+
+What version of git-annex are you using? On what operating system?
+
+ latest git annex osx build as of yesterday (12-11-03)
+
+
+> I've made the `cp` command be included in the OSX standalone build,
+> so it will use the same one it's built with. So the next time we get
+> an OSX build this will be fixed. [[done]] --[[Joey]]
diff --git a/doc/bugs/unlock_not_working_on_os_x_10.6_-_cp:_illegal_option_--_-_/comment_1_a634a9f1c023bf836183de64abab1224._comment b/doc/bugs/unlock_not_working_on_os_x_10.6_-_cp:_illegal_option_--_-_/comment_1_a634a9f1c023bf836183de64abab1224._comment
new file mode 100644
index 000000000..3e322a0b6
--- /dev/null
+++ b/doc/bugs/unlock_not_working_on_os_x_10.6_-_cp:_illegal_option_--_-_/comment_1_a634a9f1c023bf836183de64abab1224._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.194"
+ subject="comment 1"
+ date="2012-11-04T20:03:47Z"
+ content="""
+Did you build this git-annex yourself? On the same machine?
+
+What does it say if you add the `--debug` option?
+"""]]
diff --git a/doc/bugs/unlock_not_working_on_os_x_10.6_-_cp:_illegal_option_--_-_/comment_2_d9ae61a7c3f1eb243ca650945b40f21d._comment b/doc/bugs/unlock_not_working_on_os_x_10.6_-_cp:_illegal_option_--_-_/comment_2_d9ae61a7c3f1eb243ca650945b40f21d._comment
new file mode 100644
index 000000000..98d42e59d
--- /dev/null
+++ b/doc/bugs/unlock_not_working_on_os_x_10.6_-_cp:_illegal_option_--_-_/comment_2_d9ae61a7c3f1eb243ca650945b40f21d._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmmPHsszTlpa3s3x_LEzmEYkZfEmqq7IjU"
+ nickname="Jan"
+ subject="comment 2"
+ date="2012-11-05T01:23:41Z"
+ content="""
+Thanks for the quick response :)
+I think the problem is that the os x cp does not support ''--reflink\" (and gnu long options). I guess I could install gnu coreutils through homebrew, though those will be prefixed with a g in the name.
+My OS version is 10.6.8 btw.
+
+ % git annex --debug unlock FILENAME
+ [2012-11-04 20:17:47 EST] read: git [\"--git-dir=/PATH/.git\",\"--work-tree=/PATH\",\"ls-files\",\"--cached\",\"-z\",\"--\",\"FILENAME\"]
+ unlock FILENAME (copying...) [2012-11-04 20:17:47 EST] call: cp [\"--reflink=auto\",\"-a\",\"/PATH/.git/annex/objects/8P/Qp/SHA256-s7173120--33c3482bf70807bb5caede9859d10a73bda9279f08340556188c93dea7e5be05/SHA256-s7173120--33c3482bf70807bb5caede9859d10a73bda9279f08340556188c93dea7e5be05\",\"/PATH/.git/annex/tmp/SHA256-s7173120--33c3482bf70807bb5caede9859d10a73bda9279f08340556188c93dea7e5be05\"]
+ cp: illegal option -- -
+ usage: cp [-R [-H | -L | -P]] [-fi | -n] [-apvX] source_file target_file
+ cp [-R [-H | -L | -P]] [-fi | -n] [-apvX] source_file ... target_directory
+ git-annex: copy failed!
+
+"""]]
diff --git a/doc/bugs/unlock_not_working_on_os_x_10.6_-_cp:_illegal_option_--_-_/comment_3_fe229c03c14e8eb2b57389e0e193ed99._comment b/doc/bugs/unlock_not_working_on_os_x_10.6_-_cp:_illegal_option_--_-_/comment_3_fe229c03c14e8eb2b57389e0e193ed99._comment
new file mode 100644
index 000000000..576202d92
--- /dev/null
+++ b/doc/bugs/unlock_not_working_on_os_x_10.6_-_cp:_illegal_option_--_-_/comment_3_fe229c03c14e8eb2b57389e0e193ed99._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmmPHsszTlpa3s3x_LEzmEYkZfEmqq7IjU"
+ nickname="Jan"
+ subject="comment 3"
+ date="2012-11-05T01:24:32Z"
+ content="""
+Ah, forgot to mention: I am running the latest build downloaded from the website (as mentioned above), so no, I did not build it myself.
+"""]]
diff --git a/doc/bugs/unlock_not_working_on_os_x_10.6_-_cp:_illegal_option_--_-_/comment_4_fa12afe295de63c4aa7eb043b715325a._comment b/doc/bugs/unlock_not_working_on_os_x_10.6_-_cp:_illegal_option_--_-_/comment_4_fa12afe295de63c4aa7eb043b715325a._comment
new file mode 100644
index 000000000..d96a469d9
--- /dev/null
+++ b/doc/bugs/unlock_not_working_on_os_x_10.6_-_cp:_illegal_option_--_-_/comment_4_fa12afe295de63c4aa7eb043b715325a._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmmPHsszTlpa3s3x_LEzmEYkZfEmqq7IjU"
+ nickname="Jan"
+ subject="exact version"
+ date="2012-11-05T01:34:29Z"
+ content="""
+ % git annex version
+ git-annex version: 3.20121017
+ local repository version: 3
+ default repository version: 3
+ supported repository versions: 3
+ upgrade supported from repository versions: 0 1 2
+
+Also, while browsing the archive for another problem (can not add files because shasum256 is missing and I get a \"dyld: Library not loaded: /opt/local/lib/libintl.8.dylib\" for it's execution when I add the path for /Applications/git-annex.app/Contents/MacOS/bin/sha256sum) I [saw](http://git-annex.branchable.com/install/OSX/old_comments/#comment-94b0f0ba446ca2f1ebd6af44c7afd3be) that it should fall back on haskell code - which it doesn't, so maybe its an old version?
+"""]]
diff --git a/doc/bugs/unlock_then_lock_of_uncommitted_file_loses_it.mdwn b/doc/bugs/unlock_then_lock_of_uncommitted_file_loses_it.mdwn
new file mode 100644
index 000000000..9c093de38
--- /dev/null
+++ b/doc/bugs/unlock_then_lock_of_uncommitted_file_loses_it.mdwn
@@ -0,0 +1,7 @@
+Add a file (do not commit), then unlock it, and then lock it.
+There is an error and the symlink gets deleted.
+
+The file will still be staged in the index, and the file content is still
+in the annex. --[[Joey]]
+
+[[done]]
diff --git a/doc/bugs/upgrade_left_untracked_.git-annex__47____42___directories.mdwn b/doc/bugs/upgrade_left_untracked_.git-annex__47____42___directories.mdwn
new file mode 100644
index 000000000..7fdbc3ca4
--- /dev/null
+++ b/doc/bugs/upgrade_left_untracked_.git-annex__47____42___directories.mdwn
@@ -0,0 +1,16 @@
+I upgraded another one of my git-annex clones. The upgrade worked fine (i.e.
+according to the manual) on two other clones before, but this time something is
+different.
+
+After 'git pull' and 'git annex upgrade', which took a long time and seemed to
+have succeeded, there are no staged changes in git. Instead there are lots of
+untracked directories in .git-annex. Aside from that, nothing seems to be
+wrong.
+
+At the time I had git-annex version 0.20110329 and I've been using the SHA1
+backend since version 1.
+
+> Yes, I agree with Jimmy, it's the same bug. So I'll be closing this one.
+> Please keep us informed how the workaround committed to git-annex
+> yesterday for the case insensativity issue works out. [[dup|done]]
+> --[[Joey]]
diff --git a/doc/bugs/upgrade_left_untracked_.git-annex__47____42___directories/comment_1_9ca2da52f3c8add0276b72d6099516a6._comment b/doc/bugs/upgrade_left_untracked_.git-annex__47____42___directories/comment_1_9ca2da52f3c8add0276b72d6099516a6._comment
new file mode 100644
index 000000000..78309df87
--- /dev/null
+++ b/doc/bugs/upgrade_left_untracked_.git-annex__47____42___directories/comment_1_9ca2da52f3c8add0276b72d6099516a6._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-04-03T02:26:20Z"
+ content="""
+I'm not sure how this happened, as far as I can see, and based on my testing, `git annex upgrade` does stage the location log files. OTOH, I vaguely rememeber needing to stage some of them when I was doing my own upgrades, but that was a while ago, and I don't remember the details.
+
+Your upgrade seems to have gone ok from the file lists you sent, so you can just: `git add .git-annex; git commit`
+"""]]
diff --git a/doc/bugs/upgrade_left_untracked_.git-annex__47____42___directories/comment_2_e14e84b770305893f2fc6e4938359f47._comment b/doc/bugs/upgrade_left_untracked_.git-annex__47____42___directories/comment_2_e14e84b770305893f2fc6e4938359f47._comment
new file mode 100644
index 000000000..4fc9647e8
--- /dev/null
+++ b/doc/bugs/upgrade_left_untracked_.git-annex__47____42___directories/comment_2_e14e84b770305893f2fc6e4938359f47._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="gernot"
+ ip="213.168.117.192"
+ subject="comment 2"
+ date="2011-04-03T15:35:52Z"
+ content="""
+'git add .git-annex' didn't do anything. That's when I noticed that this
+repository is on a case-insensitive HFS+ file system.
+
+So, if I get this right it's not a new bug, but similar to this situation:
+[[git-annex_directory_hashing_problems_on_osx]]
+
+Assuming that it was the file system's fault, I went ahead and upgraded yet
+another clone. That one (on an ext3 file system) had neither staged changes
+nor left-over untracked files. Everything seems to just have fallen right into
+place. Is that possible or still weird?
+
+"""]]
diff --git a/doc/bugs/upgrade_left_untracked_.git-annex__47____42___directories/comment_3_ec04e306c96fd20ab912aea54a8340aa._comment b/doc/bugs/upgrade_left_untracked_.git-annex__47____42___directories/comment_3_ec04e306c96fd20ab912aea54a8340aa._comment
new file mode 100644
index 000000000..99095c156
--- /dev/null
+++ b/doc/bugs/upgrade_left_untracked_.git-annex__47____42___directories/comment_3_ec04e306c96fd20ab912aea54a8340aa._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 3"
+ date="2011-04-03T16:05:39Z"
+ content="""
+Yes you seem to have come across the same bug that I had initially reported :P
+"""]]
diff --git a/doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again.mdwn b/doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again.mdwn
new file mode 100644
index 000000000..2517fa647
--- /dev/null
+++ b/doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again.mdwn
@@ -0,0 +1,434 @@
+### Please describe the problem.
+
+recently upgraded to a git snapshot; restarted assistant and found my disk space disappearing. Checked webapp and there were a bunch of transfers queued. Restarted assistant in --debug mode to get some logs.
+
+Transfers should not have happened, because I'm on a "client" machine, they are in an archive subdirectory, and there are adequate copies elsewhere (a ssh remote and a USB drive) to satisfy "numcopies=2." (Note that the USB drive was not connected at the time, but that hasn't mattered in the past)
+
+### What steps will reproduce the problem?
+
+As noted above. I don't know that this is reproducible in a fresh repo; I was hoping that a bug report with the log would do. Can try if that would help.
+
+### What version of git-annex are you using? On what operating system?
+
+checkout hash is:
+
+70ba425 2013-04-07
+
+OS X Lion.
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/debug.log
+
+
+[13:13:55 PM]$ cat daemon.log
+[2013-04-26 12:59:09 EDT] main: starting assistant version 4.20130406
+[2013-04-26 12:59:09 EDT] TransferScanner: Syncing with toshiba, homeworld
+[2013-04-26 12:59:09 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","git-annex"]
+[2013-04-26 12:59:09 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","--hash","refs/heads/git-annex"]
+[2013-04-26 12:59:09 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..9a8e676d552905528b25e29ae9c56b5e50c35f70","--oneline","-n1"]
+[2013-04-26 12:59:09 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..c19f5f18ea26d43b735de8fbdb67d4f85987d171","--oneline","-n1"]
+[2013-04-26 12:59:09 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..7077e8c56be8c84fee214456bb2c951ef5b2202e","--oneline","-n1"]
+[2013-04-26 12:59:09 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..bfa73167b1cd90bbb2213a2c9bad64fbb1befe00","--oneline","-n1"]
+[2013-04-26 12:59:09 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..f7a2f8f189db99c7f9f4bacc2fc935d63737287e","--oneline","-n1"]
+[2013-04-26 12:59:10 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..be505749576a7064cca1eaf9fc241b450cdaadc6","--oneline","-n1"]
+[2013-04-26 12:59:10 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","ls-tree","-z","--","refs/heads/git-annex","uuid.log","remote.log","trust.log","group.log","preferred-content.log"]
+[2013-04-26 12:59:10 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","symbolic-ref","HEAD"]
+[2013-04-26 12:59:10 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","refs/heads/master"]
+[2013-04-26 12:59:10 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","git-annex"]
+[2013-04-26 12:59:10 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","--hash","refs/heads/git-annex"]
+[2013-04-26 12:59:10 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..9a8e676d552905528b25e29ae9c56b5e50c35f70","--oneline","-n1"]
+[2013-04-26 12:59:10 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..c19f5f18ea26d43b735de8fbdb67d4f85987d171","--oneline","-n1"]
+[2013-04-26 12:59:10 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..7077e8c56be8c84fee214456bb2c951ef5b2202e","--oneline","-n1"]
+[2013-04-26 12:59:10 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..bfa73167b1cd90bbb2213a2c9bad64fbb1befe00","--oneline","-n1"]
+[2013-04-26 12:59:10 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..f7a2f8f189db99c7f9f4bacc2fc935d63737287e","--oneline","-n1"]
+[2013-04-26 12:59:10 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..be505749576a7064cca1eaf9fc241b450cdaadc6","--oneline","-n1"]
+[2013-04-26 12:59:10 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","ls-tree","-z","--","refs/heads/git-annex","uuid.log","remote.log","trust.log","group.log","preferred-content.log"]
+[2013-04-26 12:59:10 EDT] call: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","fetch","toshiba"]
+[2013-04-26 12:59:10 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","symbolic-ref","HEAD"]
+[2013-04-26 12:59:10 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","refs/heads/master"]
+[2013-04-26 12:59:10 EDT] Merger: merging refs/heads/synced/master into refs/heads/master
+[2013-04-26 12:59:10 EDT] call: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","merge","--no-edit","refs/heads/synced/master"]
+fatal: '/Volumes/TOSHIBAEXT/annex' does not appear to be a git repository
+fatal: Could not read from remote repository.
+
+Please make sure you have the correct access rights
+and the repository exists.
+[2013-04-26 12:59:10 EDT] call: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","fetch","homeworld"]
+Already up-to-date.
+
+(scanning...) [2013-04-26 12:59:10 EDT] Watcher: Performing startup scan
+[2013-04-26 12:59:10 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","git-annex"]
+[2013-04-26 12:59:10 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","--hash","refs/heads/git-annex"]
+[2013-04-26 12:59:10 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..9a8e676d552905528b25e29ae9c56b5e50c35f70","--oneline","-n1"]
+[2013-04-26 12:59:10 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..c19f5f18ea26d43b735de8fbdb67d4f85987d171","--oneline","-n1"]
+[2013-04-26 12:59:10 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..7077e8c56be8c84fee214456bb2c951ef5b2202e","--oneline","-n1"]
+[2013-04-26 12:59:10 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..bfa73167b1cd90bbb2213a2c9bad64fbb1befe00","--oneline","-n1"]
+[2013-04-26 12:59:10 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..f7a2f8f189db99c7f9f4bacc2fc935d63737287e","--oneline","-n1"]
+[2013-04-26 12:59:10 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..be505749576a7064cca1eaf9fc241b450cdaadc6","--oneline","-n1"]
+[2013-04-26 12:59:10 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","git-annex"]
+[2013-04-26 12:59:10 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","--hash","refs/heads/git-annex"]
+[2013-04-26 12:59:10 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..9a8e676d552905528b25e29ae9c56b5e50c35f70","--oneline","-n1"]
+[2013-04-26 12:59:10 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..c19f5f18ea26d43b735de8fbdb67d4f85987d171","--oneline","-n1"]
+[2013-04-26 12:59:10 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..7077e8c56be8c84fee214456bb2c951ef5b2202e","--oneline","-n1"]
+[2013-04-26 12:59:10 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..bfa73167b1cd90bbb2213a2c9bad64fbb1befe00","--oneline","-n1"]
+[2013-04-26 12:59:10 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..f7a2f8f189db99c7f9f4bacc2fc935d63737287e","--oneline","-n1"]
+[2013-04-26 12:59:10 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..be505749576a7064cca1eaf9fc241b450cdaadc6","--oneline","-n1"]
+[2013-04-26 12:59:10 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","symbolic-ref","HEAD"]
+[2013-04-26 12:59:10 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","refs/heads/master"]
+[2013-04-26 12:59:10 EDT] Merger: merging refs/remotes/homeworld/synced/master into refs/heads/master
+[2013-04-26 12:59:10 EDT] call: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","merge","--no-edit","refs/remotes/homeworld/synced/master"]
+Already up-to-date.
+[2013-04-26 12:59:11 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","git-annex"]
+[2013-04-26 12:59:11 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","--hash","refs/heads/git-annex"]
+[2013-04-26 12:59:11 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..9a8e676d552905528b25e29ae9c56b5e50c35f70","--oneline","-n1"]
+[2013-04-26 12:59:11 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..c19f5f18ea26d43b735de8fbdb67d4f85987d171","--oneline","-n1"]
+[2013-04-26 12:59:11 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..7077e8c56be8c84fee214456bb2c951ef5b2202e","--oneline","-n1"]
+[2013-04-26 12:59:11 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..bfa73167b1cd90bbb2213a2c9bad64fbb1befe00","--oneline","-n1"]
+[2013-04-26 12:59:11 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..f7a2f8f189db99c7f9f4bacc2fc935d63737287e","--oneline","-n1"]
+[2013-04-26 12:59:12 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..be505749576a7064cca1eaf9fc241b450cdaadc6","--oneline","-n1"]
+[2013-04-26 12:59:12 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","git-annex"]
+[2013-04-26 12:59:12 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","--hash","refs/heads/git-annex"]
+[2013-04-26 12:59:12 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..9a8e676d552905528b25e29ae9c56b5e50c35f70","--oneline","-n1"]
+[2013-04-26 12:59:13 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..c19f5f18ea26d43b735de8fbdb67d4f85987d171","--oneline","-n1"]
+[2013-04-26 12:59:13 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..7077e8c56be8c84fee214456bb2c951ef5b2202e","--oneline","-n1"]
+[2013-04-26 12:59:13 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..bfa73167b1cd90bbb2213a2c9bad64fbb1befe00","--oneline","-n1"]
+[2013-04-26 12:59:13 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..f7a2f8f189db99c7f9f4bacc2fc935d63737287e","--oneline","-n1"]
+[2013-04-26 12:59:14 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..be505749576a7064cca1eaf9fc241b450cdaadc6","--oneline","-n1"]
+[2013-04-26 12:59:14 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","git-annex"]
+[2013-04-26 12:59:14 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","--hash","refs/heads/git-annex"]
+[2013-04-26 12:59:14 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..9a8e676d552905528b25e29ae9c56b5e50c35f70","--oneline","-n1"]
+[2013-04-26 12:59:14 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..c19f5f18ea26d43b735de8fbdb67d4f85987d171","--oneline","-n1"]
+[2013-04-26 12:59:14 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..7077e8c56be8c84fee214456bb2c951ef5b2202e","--oneline","-n1"]
+[2013-04-26 12:59:14 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..bfa73167b1cd90bbb2213a2c9bad64fbb1befe00","--oneline","-n1"]
+[2013-04-26 12:59:14 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..f7a2f8f189db99c7f9f4bacc2fc935d63737287e","--oneline","-n1"]
+[2013-04-26 12:59:14 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..be505749576a7064cca1eaf9fc241b450cdaadc6","--oneline","-n1"]
+[2013-04-26 12:59:15 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","symbolic-ref","HEAD"]
+[2013-04-26 12:59:15 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","refs/heads/master"]
+[2013-04-26 12:59:15 EDT] Merger: merging refs/remotes/toshiba/synced/master into refs/heads/master
+[2013-04-26 12:59:15 EDT] call: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","--verify","-q","refs/remotes/toshiba/master"]
+[2013-04-26 12:59:15 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/master..refs/remotes/toshiba/master","--oneline","-n1"]
+[2013-04-26 12:59:20 EDT] call: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","--verify","-q","refs/remotes/toshiba/synced/master"]
+[2013-04-26 12:59:20 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/synced/master..refs/remotes/toshiba/synced/master","--oneline","-n1"]
+[2013-04-26 12:59:20 EDT] call: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","merge","--no-edit","refs/remotes/toshiba/synced/master"]
+Already up-to-date.
+[2013-04-26 12:59:20 EDT] Merger: watching /Users/ed/annex/.git/refs
+[2013-04-26 12:59:20 EDT] call: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","--verify","-q","refs/remotes/homeworld/master"]
+[2013-04-26 12:59:20 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/master..refs/remotes/homeworld/master","--oneline","-n1"]
+[2013-04-26 12:59:20 EDT] call: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","--verify","-q","refs/remotes/homeworld/synced/master"]
+[2013-04-26 12:59:20 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/synced/master..refs/remotes/homeworld/synced/master","--oneline","-n1"]
+[2013-04-26 12:59:20 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","symbolic-ref","HEAD"]
+[2013-04-26 12:59:21 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","refs/heads/master"]
+[2013-04-26 12:59:21 EDT] TransferScanner: pushing to [Remote { name ="toshiba" },Remote { name ="homeworld" }]
+[2013-04-26 12:59:21 EDT] call: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","branch","-f","synced/master"]
+[2013-04-26 12:59:21 EDT] call: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","push","toshiba","git-annex:synced/git-annex","master:synced/master"]
+fatal: '/Volumes/TOSHIBAEXT/annex' does not appear to be a git repository
+fatal: Could not read from remote repository.
+
+Please make sure you have the correct access rights
+and the repository exists.
+[2013-04-26 12:59:21 EDT] call: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","push","homeworld","git-annex:synced/git-annex","master:synced/master"]
+[2013-04-26 12:59:21 EDT] TransferWatcher: watching for transfers
+To ssh://ed@homeworld/srv/mybook/annex
+ bfa7316..9a8e676 git-annex -> synced/git-annex
+[2013-04-26 12:59:36 EDT] TransferScanner: trying manual pull to resolve failed pushes
+[2013-04-26 12:59:36 EDT] call: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","fetch","toshiba"]
+fatal: '/Volumes/TOSHIBAEXT/annex' does not appear to be a git repository
+fatal: Could not read from remote repository.
+
+Please make sure you have the correct access rights
+and the repository exists.
+[2013-04-26 12:59:36 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","git-annex"]
+[2013-04-26 12:59:36 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","--hash","refs/heads/git-annex"]
+[2013-04-26 12:59:36 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..9a8e676d552905528b25e29ae9c56b5e50c35f70","--oneline","-n1"]
+[2013-04-26 12:59:36 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..c19f5f18ea26d43b735de8fbdb67d4f85987d171","--oneline","-n1"]
+[2013-04-26 12:59:36 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..7077e8c56be8c84fee214456bb2c951ef5b2202e","--oneline","-n1"]
+[2013-04-26 12:59:37 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..f7a2f8f189db99c7f9f4bacc2fc935d63737287e","--oneline","-n1"]
+[2013-04-26 12:59:37 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..be505749576a7064cca1eaf9fc241b450cdaadc6","--oneline","-n1"]
+[2013-04-26 12:59:37 EDT] call: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","--verify","-q","refs/remotes/toshiba/master"]
+[2013-04-26 12:59:37 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/master..refs/remotes/toshiba/master","--oneline","-n1"]
+[2013-04-26 12:59:37 EDT] call: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","--verify","-q","refs/remotes/toshiba/synced/master"]
+[2013-04-26 12:59:37 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/synced/master..refs/remotes/toshiba/synced/master","--oneline","-n1"]
+[2013-04-26 12:59:37 EDT] TransferScanner: pushing to [Remote { name ="toshiba" }]
+[2013-04-26 12:59:37 EDT] call: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","branch","-f","synced/master"]
+[2013-04-26 12:59:37 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","git-annex"]
+[2013-04-26 12:59:37 EDT] call: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","push","toshiba","git-annex:synced/git-annex","master:synced/master"]
+[2013-04-26 12:59:37 EDT] read: git ["--git-dir=/Users/ed/annex/fatal: '/Volumes/TOSHIBAEXT/annex' does not appear to be a git repository
+fatal: Could not read from remote repository.
+
+Please make sure you have the correct access rights
+and the repository exists.
+.git","--work-tree=/Users/ed/annex","show-ref","--hash","refs/heads/git-annex"]
+[2013-04-26 12:59:37 EDT] TransferScanner: fallback pushing to [Remote { name ="toshiba" }]
+[2013-04-26 12:59:37 EDT] call: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","push","toshiba","git-annex:refs/synced/fa2bd02e-3ce2-11e2-a675-47389975a32e/git-annex","refs/heads/master:refs/synced/fa2bd02e-3ce2-11e2-a675-47389975a32e/master"]
+[2013-04-26 12:59:37 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..9a8e676d552905528b25e29ae9c56b5e50c35f70","--oneline","-n1"]
+fatal: '/Volumes/TOSHIBAEXT/annex' does not appear to be a git repository
+fatal: Could not read from remote repository.
+
+Please make sure you have the correct access rights
+and the repository exists.
+[2013-04-26 12:59:37 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..c19f5f18ea26d43b735de8fbdb67d4f85987d171","--oneline","-n1"]
+[2013-04-26 12:59:37 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..7077e8c56be8c84fee214456bb2c951ef5b2202e","--oneline","-n1"]
+[2013-04-26 12:59:38 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..f7a2f8f189db99c7f9f4bacc2fc935d63737287e","--oneline","-n1"]
+[2013-04-26 12:59:38 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..be505749576a7064cca1eaf9fc241b450cdaadc6","--oneline","-n1"]
+[2013-04-26 12:59:38 EDT] 127.0.0.1 GET / Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 12:59:39 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","git-annex"]
+[2013-04-26 12:59:39 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","--hash","refs/heads/git-annex"]
+[2013-04-26 12:59:39 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..9a8e676d552905528b25e29ae9c56b5e50c35f70","--oneline","-n1"]
+[2013-04-26 12:59:39 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..c19f5f18ea26d43b735de8fbdb67d4f85987d171","--oneline","-n1"]
+[2013-04-26 12:59:39 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..7077e8c56be8c84fee214456bb2c951ef5b2202e","--oneline","-n1"]
+[2013-04-26 12:59:39 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..f7a2f8f189db99c7f9f4bacc2fc935d63737287e","--oneline","-n1"]
+[2013-04-26 12:59:39 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..be505749576a7064cca1eaf9fc241b450cdaadc6","--oneline","-n1"]
+[2013-04-26 12:59:39 EDT] chat: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","cat-file","--batch"]
+[2013-04-26 12:59:39 EDT] read: git ["config","--null","--list"]
+[2013-04-26 12:59:40 EDT] TransferScanner: starting scan of [Remote { name ="toshiba" },Remote { name ="homeworld" }]
+[2013-04-26 12:59:40 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","ls-files","--cached","-z","--"]
+[2013-04-26 12:59:40 EDT] 127.0.0.1 GET /static/css/bootstrap.css Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 12:59:40 EDT] chat: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","check-attr","-z","--stdin","annex.backend","annex.numcopies","--"]
+[2013-04-26 12:59:41 EDT] 127.0.0.1 GET /static/css/bootstrap-responsive.css Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 12:59:41 EDT] 127.0.0.1 GET /static/jquery.full.js Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 12:59:41 EDT] 127.0.0.1 GET /static/js/bootstrap-dropdown.js Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 12:59:41 EDT] 127.0.0.1 GET /static/js/bootstrap-modal.js Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 12:59:41 EDT] 127.0.0.1 GET /static/js/bootstrap-collapse.js Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 12:59:41 EDT] 127.0.0.1 GET /static/longpolling.js Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 12:59:41 EDT] 127.0.0.1 GET /static/jquery.ui.core.js Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 12:59:41 EDT] 127.0.0.1 GET /static/jquery.ui.widget.js Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 12:59:42 EDT] 127.0.0.1 GET /static/jquery.ui.mouse.js Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 12:59:42 EDT] 127.0.0.1 GET /static/jquery.ui.sortable.js Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 12:59:42 EDT] 127.0.0.1 GET /static/favicon.ico Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 12:59:42 EDT] 127.0.0.1 GET /static/img/glyphicons-halflings-white.png Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 12:59:42 EDT] 127.0.0.1 GET /static/img/glyphicons-halflings.png Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 12:59:42 EDT] 127.0.0.1 GET /notifier/sidebar Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 12:59:42 EDT] 127.0.0.1 GET /notifier/repolist/RepoSelector%20%7BonlyCloud%20=%20False,%20onlyConfigured%20=%20False,%20includeHere%20=%20True,%20nudgeAddMore%20=%20True%7D Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 12:59:42 EDT] 127.0.0.1 GET /notifier/transfers Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 12:59:42 EDT] 127.0.0.1 GET /sidebar/NotificationId%200 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 12:59:42 EDT] 127.0.0.1 GET /repolist/RepoListNotificationId%20(NotificationId%200)%20(RepoSelector%20%7BonlyCloud%20=%20False,%20onlyConfigured%20=%20False,%20includeHere%20=%20True,%20nudgeAddMore%20=%20True%7D) Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 12:59:42 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 12:59:43 EDT] 127.0.0.1 GET /sidebar/NotificationId%200 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 12:59:43 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 12:59:43 EDT] 127.0.0.1 GET /repolist/RepoListNotificationId%20(NotificationId%200)%20(RepoSelector%20%7BonlyCloud%20=%20False,%20onlyConfigured%20=%20False,%20includeHere%20=%20True,%20nudgeAddMore%20=%20True%7D) Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:10 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","ls-tree","-z","--","refs/heads/git-annex","uuid.log","remote.log","trust.log","group.log","preferred-content.log"]
+[2013-04-26 13:00:27 EDT] TransferScanner: queued Download UUID "429af61a-3cf6-11e2-af0a-170be35d46b6" Books/archive/Art books/John Gadsby Chapman - American Drawing-Book - A Manual for the Amateur.pdf.part Nothing : expensive scan found missing object
+[2013-04-26 13:00:27 EDT] TransferScanner: queued Download UUID "d16d0d1a-3cdd-11e2-9161-67c83599f720" Books/archive/Art books/John Gadsby Chapman - American Drawing-Book - A Manual for the Amateur.pdf.part Nothing : expensive scan found missing object
+[2013-04-26 13:00:27 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:27 EDT] Transferrer: Transferring: Download UUID "d16d0d1a-3cdd-11e2-9161-67c83599f720" Books/archive/Art books/John Gadsby Chapman - American Drawing-Book - A Manual for the Amateur.pdf.part Nothing
+[2013-04-26 13:00:27 EDT] call: /Users/ed/bin/git-annex ["transferkeys","--readfd","34","--writefd","31"]
+[2013-04-26 13:00:27 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:27 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:27 EDT] TransferScanner: queued Download UUID "429af61a-3cf6-11e2-af0a-170be35d46b6" Books/archive/Art books/L.A. Doust - A Manual on Drawing the Human Figure.pdf.part Nothing : expensive scan found missing object
+[2013-04-26 13:00:27 EDT] TransferScanner: queued Download UUID "d16d0d1a-3cdd-11e2-9161-67c83599f720" Books/archive/Art books/L.A. Doust - A Manual on Drawing the Human Figure.pdf.part Nothing : expensive scan found missing object
+[2013-04-26 13:00:27 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:28 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:28 EDT] TransferScanner: queued Download UUID "429af61a-3cf6-11e2-af0a-170be35d46b6" Books/archive/Art books/Michael D. Mattesi - Force. The Key to Capturing Life Through Drawing.pdf Nothing : expensive scan found missing object
+[2013-04-26 13:00:28 EDT] TransferScanner: queued Download UUID "d16d0d1a-3cdd-11e2-9161-67c83599f720" Books/archive/Art books/Michael D. Mattesi - Force. The Key to Capturing Life Through Drawing.pdf Nothing : expensive scan found missing object
+[2013-04-26 13:00:28 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:28 EDT] TransferScanner: queued Download UUID "429af61a-3cf6-11e2-af0a-170be35d46b6" Books/archive/Art books/Richard G. Hatton - Figure Drawing.pdf Nothing : expensive scan found missing object
+[2013-04-26 13:00:28 EDT] TransferScanner: queued Download UUID "d16d0d1a-3cdd-11e2-9161-67c83599f720" Books/archive/Art books/Richard G. Hatton - Figure Drawing.pdf Nothing : expensive scan found missing object
+[2013-04-26 13:00:28 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:28 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:28 EDT] TransferScanner: queued Download UUID "429af61a-3cf6-11e2-af0a-170be35d46b6" Books/archive/Art books/The Figure in Repose.pdf Nothing : expensive scan found missing object
+Control socket connect(/Users/ed/annex/.git/annex/ssh/ed@homeworld): Connection refused
+[2013-04-26 13:00:28 EDT] TransferWatcher: transfer starting: Download UUID "d16d0d1a-3cdd-11e2-9161-67c83599f720" Books/archive/Art books/John Gadsby Chapman - American Drawing-Book - A Manual for the Amateur.pdf.part Nothing
+[2013-04-26 13:00:28 EDT] TransferScanner: queued Download UUID "d16d0d1a-3cdd-11e2-9161-67c83599f720" Books/archive/Art books/The Figure in Repose.pdf Nothing : expensive scan found missing object
+[2013-04-26 13:00:28 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:28 EDT] TransferWatcher: transfer starting: Download UUID "d16d0d1a-3cdd-11e2-9161-67c83599f720" Books/archive/Art books/John Gadsby Chapman - American Drawing-Book - A Manual for the Amateur.pdf.part Nothing
+[2013-04-26 13:00:28 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:28 EDT] TransferScanner: queued Download UUID "429af61a-3cf6-11e2-af0a-170be35d46b6" Books/archive/Art books/Torrent downloaded from Demonoid.com.txt Nothing : expensive scan found missing object
+[2013-04-26 13:00:28 EDT] TransferScanner: queued Download UUID "d16d0d1a-3cdd-11e2-9161-67c83599f720" Books/archive/Art books/Torrent downloaded from Demonoid.com.txt Nothing : expensive scan found missing object
+[2013-04-26 13:00:29 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:29 EDT] TransferScanner: queued Download UUID "429af61a-3cf6-11e2-af0a-170be35d46b6" Books/archive/Art books/Victor Perard - Drawing and Anatomy.pdf Nothing : expensive scan found missing object
+[2013-04-26 13:00:29 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:29 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+ControlSocket /Users/ed/annex/.git/annex/ssh/ed@homeworld already exists, disabling multiplexing
+
+SHA256E-s568690--ec5aaaf0320739ab91e4efa9a0bfd372a92ca436e96a5182a3d072ba409691b5.pdf.part
+[2013-04-26 13:00:31 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:33 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+ 568690 100% 185.12kB/s 0:00:03 (xfer#1, to-check=0/1)
+
+sent 42 bytes received 568933 bytes 87534.62 bytes/sec
+total size is 568690 speedup is 1.00
+[2013-04-26 13:00:34 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:35 EDT] Transferrer: Downloaded John Gads...pdf.part
+[2013-04-26 13:00:35 EDT] TransferWatcher: transfer finishing: Transfer {transferDirection = Download, transferUUID = UUID "d16d0d1a-3cdd-11e2-9161-67c83599f720", transferKey = Key {keyName = "ec5aaaf0320739ab91e4efa9a0bfd372a92ca436e96a5182a3d072ba409691b5.pdf.part", keyBackendName = "SHA256E", keySize = Just 568690, keyMtime = Nothing}}
+[2013-04-26 13:00:35 EDT] Pusher: Syncing with homeworld
+[2013-04-26 13:00:35 EDT] TransferScanner: queued Download UUID "d16d0d1a-3cdd-11e2-9161-67c83599f720" Books/archive/Art books/Victor Perard - Drawing and Anatomy.pdf Nothing : expensive scan found missing object
+[2013-04-26 13:00:35 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:35 EDT] Transferrer: Transferring: Download UUID "d16d0d1a-3cdd-11e2-9161-67c83599f720" Books/archive/Art books/L.A. Doust - A Manual on Drawing the Human Figure.pdf.part Nothing
+[2013-04-26 13:00:35 EDT] chat: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","hash-object","-w","--stdin-paths"]
+[2013-04-26 13:00:35 EDT] feed: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","update-index","-z","--index-info"]
+[2013-04-26 13:00:35 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:35 EDT] 127.0.0.1 GET /sidebar/NotificationId%200 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:35 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+Control socket connect(/Users/ed/annex/.git/annex/ssh/ed@homeworld): Connection refused
+[2013-04-26 13:00:35 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","--hash","refs/heads/git-annex"]
+[2013-04-26 13:00:35 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","write-tree"]
+[2013-04-26 13:00:35 EDT] 127.0.0.1 GET /sidebar/NotificationId%200 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:36 EDT] chat: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","commit-tree","24ad0c0244cd209b4689b2b3877645971fe88084","-p","refs/heads/git-annex"]
+[2013-04-26 13:00:36 EDT] call: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","update-ref","refs/heads/git-annex","726dd240a1e79cf0ce481f9875b5358b56c250b7"]
+[2013-04-26 13:00:36 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","symbolic-ref","HEAD"]
+[2013-04-26 13:00:36 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","refs/heads/master"]
+[2013-04-26 13:00:36 EDT] Pusher: pushing to [Remote { name ="homeworld" }]
+[2013-04-26 13:00:36 EDT] TransferWatcher: transfer starting: Download UUID "d16d0d1a-3cdd-11e2-9161-67c83599f720" Books/archive/Art books/L.A. Doust - A Manual on Drawing the Human Figure.pdf.part Nothing
+[2013-04-26 13:00:36 EDT] call: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","branch","-f","synced/master"]
+[2013-04-26 13:00:36 EDT] call: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","push","homeworld","git-annex:synced/git-annex","master:synced/master"]
+[2013-04-26 13:00:36 EDT] TransferWatcher: transfer starting: Download UUID "d16d0d1a-3cdd-11e2-9161-67c83599f720" Books/archive/Art books/L.A. Doust - A Manual on Drawing the Human Figure.pdf.part Nothing
+[2013-04-26 13:00:36 EDT] TransferScanner: queued Download UUID "429af61a-3cf6-11e2-af0a-170be35d46b6" Books/archive/Art books/Willy Pogany - Art of Drawing.pdf Nothing : expensive scan found missing object
+[2013-04-26 13:00:36 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:36 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+ControlSocket /Users/ed/annex/.git/annex/ssh/ed@homeworld already exists, disabling multiplexing
+[2013-04-26 13:00:37 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","git-annex"]
+[2013-04-26 13:00:37 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","--hash","refs/heads/git-annex"]
+[2013-04-26 13:00:37 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..726dd240a1e79cf0ce481f9875b5358b56c250b7","--oneline","-n1"]
+[2013-04-26 13:00:37 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..c19f5f18ea26d43b735de8fbdb67d4f85987d171","--oneline","-n1"]
+[2013-04-26 13:00:37 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..7077e8c56be8c84fee214456bb2c951ef5b2202e","--oneline","-n1"]
+[2013-04-26 13:00:37 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..9a8e676d552905528b25e29ae9c56b5e50c35f70","--oneline","-n1"]
+[2013-04-26 13:00:37 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..f7a2f8f189db99c7f9f4bacc2fc935d63737287e","--oneline","-n1"]
+[2013-04-26 13:00:37 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..be505749576a7064cca1eaf9fc241b450cdaadc6","--oneline","-n1"]
+
+SHA256E-s3733003--1536ff33f9a59112d40ff816f731f3fd96554f0c42acc9df758e59350176d616.pdf.part
+[2013-04-26 13:00:38 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:39 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:41 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:43 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:44 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:44 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","ls-files","--deleted","-z","--","/Users/ed/annex"]
+
+
+(Recording state in git...)
+(started...) [2013-04-26 13:00:44 EDT] Watcher: watching .
+[2013-04-26 13:00:44 EDT] 127.0.0.1 GET /sidebar/NotificationId%200 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:46 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:47 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:48 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:50 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+To ssh://ed@homeworld/srv/mybook/annex09
+ 9a8e676..726dd24 git-annex -> synced/git-annex
+[2013-04-26 13:00:50 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","git-annex"]
+[2013-04-26 13:00:50 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","--hash","refs/heads/git-annex"]
+[2013-04-26 13:00:50 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..726dd240a1e79cf0ce481f9875b5358b56c250b7","--oneline","-n1"]
+[2013-04-26 13:00:50 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..c19f5f18ea26d43b735de8fbdb67d4f85987d171","--oneline","-n1"]
+[2013-04-26 13:00:50 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..7077e8c56be8c84fee214456bb2c951ef5b2202e","--oneline","-n1"]
+[2013-04-26 13:00:50 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..f7a2f8f189db99c7f9f4bacc2fc935d63737287e","--oneline","-n1"]
+[2013-04-26 13:00:51 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..be505749576a7064cca1eaf9fc241b450cdaadc6","--oneline","-n1"]
+[2013-04-26 13:00:51 EDT] 127.0.0.1 GET /sidebar/NotificationId%200 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:51 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:53 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:54 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:56 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:57 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+ 3733003 100% 175.37kB/s 0:00:20 (xfer#1, to-check=0/1)
+[2013-04-26 13:00:59 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+
+sent 42 bytes received 3733631 bytes 152394.82 bytes/sec
+total size is 3733003 speedup is 1.00
+[2013-04-26 13:00:59 EDT] Transferrer: Downloaded L.A. Dous...pdf.part
+[2013-04-26 13:00:59 EDT] Pusher: Syncing with homeworld
+[2013-04-26 13:00:59 EDT] chat: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","hash-object","-w","--stdin-paths"]
+[2013-04-26 13:00:59 EDT] feed: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","update-index","-z","--index-info"]
+[2013-04-26 13:00:59 EDT] TransferWatcher: transfer finishing: Transfer {transferDirection = Download, transferUUID = UUID "d16d0d1a-3cdd-11e2-9161-67c83599f720", transferKey = Key {keyName = "1536ff33f9a59112d40ff816f731f3fd96554f0c42acc9df758e59350176d616.pdf.part", keyBackendName = "SHA256E", keySize = Just 3733003, keyMtime = Nothing}}
+[2013-04-26 13:00:59 EDT] TransferScanner: queued Download UUID "d16d0d1a-3cdd-11e2-9161-67c83599f720" Books/archive/Art books/Willy Pogany - Art of Drawing.pdf Nothing : expensive scan found missing object
+[2013-04-26 13:00:59 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:59 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","--hash","refs/heads/git-annex"]
+[2013-04-26 13:00:59 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","write-tree"]
+[2013-04-26 13:00:59 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:59 EDT] 127.0.0.1 GET /sidebar/NotificationId%200 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:59 EDT] 127.0.0.1 GET /sidebar/NotificationId%200 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:59 EDT] chat: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","commit-tree","2b93aa36603e01e699d332fb277874488ab21c1f","-p","refs/heads/git-annex"]
+[2013-04-26 13:00:59 EDT] call: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","update-ref","refs/heads/git-annex","58f45e4a8453d7bb3c1612bd910410eee0e2c72a"]
+[2013-04-26 13:00:59 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","symbolic-ref","HEAD"]
+[2013-04-26 13:00:59 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","refs/heads/master"]
+[2013-04-26 13:00:59 EDT] Pusher: pushing to [Remote { name ="homeworld" }]
+[2013-04-26 13:00:59 EDT] call: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","branch","-f","synced/master"]
+[2013-04-26 13:00:59 EDT] call: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","push","homeworld","git-annex:synced/git-annex","master:synced/master"]
+[2013-04-26 13:00:59 EDT] Transferrer: Transferring: Download UUID "d16d0d1a-3cdd-11e2-9161-67c83599f720" Books/archive/Art books/Michael D. Mattesi - Force. The Key to Capturing Life Through Drawing.pdf Nothing
+[2013-04-26 13:00:59 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:59 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:00:59 EDT] TransferScanner: queued Download UUID "429af61a-3cf6-11e2-af0a-170be35d46b6" Books/archive/Magic in china.PDF Nothing : expensive scan found missing object
+Control socket connect(/Users/ed/annex/.git/annex/ssh/ed@homeworld): Connection refused
+[2013-04-26 13:00:59 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:01:00 EDT] TransferWatcher: transfer starting: Download UUID "d16d0d1a-3cdd-11e2-9161-67c83599f720" Books/archive/Art books/Michael D. Mattesi - Force. The Key to Capturing Life Through Drawing.pdf Nothing
+[2013-04-26 13:01:00 EDT] TransferWatcher: transfer starting: Download UUID "d16d0d1a-3cdd-11e2-9161-67c83599f720" Books/archive/Art books/Michael D. Mattesi - Force. The Key to Capturing Life Through Drawing.pdf Nothing
+[2013-04-26 13:01:00 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:01:00 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:01:00 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","git-annex"]
+[2013-04-26 13:01:00 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","--hash","refs/heads/git-annex"]
+[2013-04-26 13:01:00 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..58f45e4a8453d7bb3c1612bd910410eee0e2c72a","--oneline","-n1"]
+[2013-04-26 13:01:00 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..c19f5f18ea26d43b735de8fbdb67d4f85987d171","--oneline","-n1"]
+[2013-04-26 13:01:00 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..7077e8c56be8c84fee214456bb2c951ef5b2202e","--oneline","-n1"]
+[2013-04-26 13:01:00 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..726dd240a1e79cf0ce481f9875b5358b56c250b7","--oneline","-n1"]
+ControlSocket /Users/ed/annex/.git/annex/ssh/ed@homeworld already exists, disabling multiplexing
+[2013-04-26 13:01:00 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..f7a2f8f189db99c7f9f4bacc2fc935d63737287e","--oneline","-n1"]
+[2013-04-26 13:01:00 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..be505749576a7064cca1eaf9fc241b450cdaadc6","--oneline","-n1"]
+
+SHA256E-s41718677--71d082deb0cdac45ae5556322cc5fa9245dafe477d3f3b7186fd19876e12e335.pdf
+[2013-04-26 13:01:02 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+To ssh://ed@homeworld/srv/mybook/annex12
+ 726dd24..58f45e4 git-annex -> synced/git-annex
+[2013-04-26 13:01:03 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","git-annex"]
+[2013-04-26 13:01:03 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","show-ref","--hash","refs/heads/git-annex"]
+[2013-04-26 13:01:03 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..58f45e4a8453d7bb3c1612bd910410eee0e2c72a","--oneline","-n1"]
+[2013-04-26 13:01:03 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..c19f5f18ea26d43b735de8fbdb67d4f85987d171","--oneline","-n1"]
+[2013-04-26 13:01:03 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..7077e8c56be8c84fee214456bb2c951ef5b2202e","--oneline","-n1"]
+[2013-04-26 13:01:03 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..f7a2f8f189db99c7f9f4bacc2fc935d63737287e","--oneline","-n1"]
+[2013-04-26 13:01:04 EDT] 127.0.0.1 GET /sidebar/NotificationId%200 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:01:04 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","log","refs/heads/git-annex..be505749576a7064cca1eaf9fc241b450cdaadc6","--oneline","-n1"]
+[2013-04-26 13:01:04 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:01:05 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:01:07 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:01:08 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:01:10 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:01:10 EDT] read: git ["--git-dir=/Users/ed/annex/.git","--work-tree=/Users/ed/annex","ls-tree","-z","--","refs/heads/git-annex","uuid.log","remote.log","trust.log","group.log","preferred-content.log"]
+[2013-04-26 13:01:11 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:01:13 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:01:14 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:01:16 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:01:17 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:01:18 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:01:20 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:01:21 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:01:23 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:01:24 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:01:26 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:01:27 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:01:29 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:01:30 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:01:32 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:01:33 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:01:35 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:01:36 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:01:38 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:01:39 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:01:41 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:01:42 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:01:43 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:01:45 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:01:46 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+[2013-04-26 13:01:48 EDT] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:20.0) Gecko/20100101 Firefox/20.0
+recv: resource vanished (Connection reset by peer)
+ 41718677 100% 173.12kB/s 0:03:55 (xfer#1, to-check=0/1)
+
+sent 42 bytes received 41723941 bytes 174943.32 bytes/sec
+total size is 41718677 speedup is 1.00
+
+git-annex: <file descriptor: 31>: hFlush: resource vanished (Broken pipe)
+failed
+(Recording state in git...)
+git-annex: transferkeys: 1 failed
+~/annex/.git/annex (GIT_DIR!)
+[13:14:08 PM]$
+
+# End of transcript or log.
+"""]]
+
+Here is the typical status of a file queued for download:
+
+whereis Art books/The Figure in Repose.pdf (2 copies)
+ 429af61a-3cf6-11e2-af0a-170be35d46b6 -- toshiba (toshiba external hd)
+ d16d0d1a-3cdd-11e2-9161-67c83599f720 -- homeworld
+
+This is with "numcopies=2" homeworld is trusted, backup, standard. toshiba is semitrusted, backup, standard. here is client, semitrusted, standard.
+
+[[done]]
diff --git a/doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_10_51097a6b84edcc607abc0e6e21ca21f2._comment b/doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_10_51097a6b84edcc607abc0e6e21ca21f2._comment
new file mode 100644
index 000000000..3e4e39e24
--- /dev/null
+++ b/doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_10_51097a6b84edcc607abc0e6e21ca21f2._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="99.54.57.201"
+ subject="comment 10"
+ date="2013-04-28T18:12:30Z"
+ content="""
+oh, but to answer your earlier question, \"(archive + smallarchive >= numcopies)\" would be exactly what I needed to get the behavior I want and have the others be archive directories.
+"""]]
diff --git a/doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_1_c34a4009213c410bba3c147ae0552029._comment b/doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_1_c34a4009213c410bba3c147ae0552029._comment
new file mode 100644
index 000000000..e85829179
--- /dev/null
+++ b/doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_1_c34a4009213c410bba3c147ae0552029._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 1"
+ date="2013-04-26T17:46:50Z"
+ content="""
+Tried again with the usb drive plugged in; still kept trying to transfer archive content, which was present in 2 other places (that usb drive and the ssh remote), down from the ssh remote.
+
+Tried disabling syncing from the ssh remote in the webapp; the assistant finished the last transfer from it and queued up a bunch of transfers from the USB remote instead.
+
+Turned assistant off completely; tried a \"git annex drop --auto\". (with the USB drive still plugged in.) Nothing dropped.
+
+Tried a \"git annex drop --in=here '*/archive/*'\" -- it dropped all the content from my archive directories. whew!
+
+"""]]
diff --git a/doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_2_634542867fd28962c47b7bc3ea022175._comment b/doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_2_634542867fd28962c47b7bc3ea022175._comment
new file mode 100644
index 000000000..5f69f10d0
--- /dev/null
+++ b/doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_2_634542867fd28962c47b7bc3ea022175._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="99.54.57.201"
+ subject="comment 2"
+ date="2013-04-27T05:45:53Z"
+ content="""
+update -- compiled a fresh copy of git annex from master ( 1bdfec9 2013-04-24 ) -- same effect; archived content is pulled down to the client from one of the backups, despite numcopies being satisfied by the backups.
+"""]]
diff --git a/doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_3_301f3ff2d203ac4c58a037e553b2c14d._comment b/doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_3_301f3ff2d203ac4c58a037e553b2c14d._comment
new file mode 100644
index 000000000..f69cef333
--- /dev/null
+++ b/doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_3_301f3ff2d203ac4c58a037e553b2c14d._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-04-27T19:35:15Z"
+ content="""
+Are either the USB drive or the ssh remote configured to be in the archive or smallarchive group?
+
+If not, there was a recent change to how archive directories are handled, which would explain this behavior:
+
+<pre>
+ * Adjust preferred content expressions so that content in archive
+ directories is preferred until it has reached an archive or smallarchive
+ repository.
+</pre>
+
+The solution would be to make the USB drive be in the archive group, probably..
+"""]]
diff --git a/doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_4_82ecdc88ccc1f87386b128adc4ff9af4._comment b/doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_4_82ecdc88ccc1f87386b128adc4ff9af4._comment
new file mode 100644
index 000000000..f7c701922
--- /dev/null
+++ b/doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_4_82ecdc88ccc1f87386b128adc4ff9af4._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="99.54.57.201"
+ subject="comment 4"
+ date="2013-04-27T20:51:03Z"
+ content="""
+They are both \"backup\" not \"archive.\" I had thought that backups pretty much counted as archives, but I guess this new behavior requires actual *archive* directories to do its job.
+
+Not sure what would be the best way to achieve my goals now, which are \"the usb and ssh remote want everything, the client wants to get rid of what's in archive directories if it's backed up in two backup directories.\"
+
+I can probably write a custom preferred content expression to do the job (I could copy the existing \"client\" one and replace \"archive\" with \"backup\" for example), but if there's a good way to do it with standard expressions I'd be curious to know.
+
+Thanks for the explanation!
+"""]]
diff --git a/doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_6_158b2ba3da815910505899606177d415._comment b/doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_6_158b2ba3da815910505899606177d415._comment
new file mode 100644
index 000000000..cdd39bf3f
--- /dev/null
+++ b/doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_6_158b2ba3da815910505899606177d415._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 6"
+ date="2013-04-27T21:26:11Z"
+ content="""
+I'm glad this wasn't a nasty bug!
+
+I'm not really sold on its current behavior WRT archive directories and backups. It seemed to make sense at the time.. The differences between archives and backups are subtle enough that I'd sort of like to avoid confusing them by making backups be sorta treated like archives.
+
+Nor am I entirely thrilled with the current hardcoded \"(copies=archive:1 or copies=smallarchive:1)\" that makes any given file be stored in only 1 archive repository. What's really wanted, but cannot currently be expressed with preferred content syntax is \"(archive + smallarchive >= numcopies)\"
+
+If it did that, sounds like you could convert your usb and ssh remotes to be archives and not need anything custom?
+
+I think that, as things stand, the only way to get what you want without a custom expression is to set one of the remotes, perhaps the SSH remote, to be an archive repository. Then files will be copies to both SSH (because it's the only archive), and to the USB backup (because backups want all files). And once both have a copy, numcopies will be satisfied, and files in archive/ directories will be archived, so the client will drop them.
+"""]]
diff --git a/doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_6_b068924802f3917e3e005350cb0cc2a2._comment b/doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_6_b068924802f3917e3e005350cb0cc2a2._comment
new file mode 100644
index 000000000..c48e8c429
--- /dev/null
+++ b/doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_6_b068924802f3917e3e005350cb0cc2a2._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="99.54.57.201"
+ subject="comment 6"
+ date="2013-04-27T21:44:19Z"
+ content="""
+I *think* that'd work... the only thing would be that the SSH remote wouldn't get any files that *weren't* in archive directories, right? They'd migrate from the client to the backup to satisfy numcopies, and that would be it, two copies and we're done. Since it's not in an archive directory, the ssh remote doesn't want it.
+"""]]
diff --git a/doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_7_f4772858c927d4a62edc3caf59b5da10._comment b/doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_7_f4772858c927d4a62edc3caf59b5da10._comment
new file mode 100644
index 000000000..709305098
--- /dev/null
+++ b/doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_7_f4772858c927d4a62edc3caf59b5da10._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 7"
+ date="2013-04-27T21:56:24Z"
+ content="""
+Nope, you're thinking of smallarchive. archive wants files in any directory. Should work.
+"""]]
diff --git a/doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_8_d0923d2950357f4444c5ef94ff196ba3._comment b/doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_8_d0923d2950357f4444c5ef94ff196ba3._comment
new file mode 100644
index 000000000..b0211e106
--- /dev/null
+++ b/doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_8_d0923d2950357f4444c5ef94ff196ba3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="99.54.57.201"
+ subject="comment 8"
+ date="2013-04-28T05:59:53Z"
+ content="""
+Just set it up that way. Looking good so far! I'll check in again later when I'm sure things are better.
+"""]]
diff --git a/doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_9_7fb30cb80aecc60e48c64846aa185206._comment b/doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_9_7fb30cb80aecc60e48c64846aa185206._comment
new file mode 100644
index 000000000..26b903823
--- /dev/null
+++ b/doc/bugs/upgraded_annex__44___suddenly_trying_to_grab_archive_content_onto_client_again/comment_9_7fb30cb80aecc60e48c64846aa185206._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="99.54.57.201"
+ subject="comment 9"
+ date="2013-04-28T17:01:29Z"
+ content="""
+Yeah that did it. Thanks! I'm not sure why I wasn't using Archive all along!
+
+"""]]
diff --git a/doc/bugs/uploads_queued_to_annex-ignore_remotes.mdwn b/doc/bugs/uploads_queued_to_annex-ignore_remotes.mdwn
new file mode 100644
index 000000000..6f45cb8ff
--- /dev/null
+++ b/doc/bugs/uploads_queued_to_annex-ignore_remotes.mdwn
@@ -0,0 +1,34 @@
+## What steps will reproduce the problem?
+
+After the assistant idles for a while, it queues many transfers to remotes configured annex-ignore=true
+
+##What is the expected output? What do you see instead?
+
+No attempts to upload to repos marked 'annex-ignore=true'
+
+Instead I see many queued transfers to the remote 'origin'
+
+[Screenshot](https://www.evernote.com/shard/s1/sh/ea0de76c-4b68-4266-b9f6-8a9c343997b6/72baab4a3ce73b0915b151829bbeaf75/res/8a8ab1fb-3173-47ea-875d-b0e320cb827b/skitch.png)
+
+##What version of git-annex are you using? On what operating system?
+
+ % > git annex version
+ git-annex version: 4.20130315
+ local repository version: 3
+ default repository version: 3
+ supported repository versions: 3 4
+ upgrade supported from repository versions: 0 1 2
+ build flags: Assistant Webapp Pairing Testsuite S3 WebDAV FsEvents XMPP DNS
+
+Mac OSX 10.8.2 Build 12C3006
+
+##Please provide any additional information below.
+
+The remote in question:
+
+ [remote "origin"]
+ url = git@git.example.com:annex-home
+ fetch = +refs/heads/*:refs/remotes/origin/*
+ annex-ignore = true
+
+> belived to be [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/uploads_queued_to_annex-ignore_remotes/comment_1_fa1c98f38253db8c2be3604c72eb3726._comment b/doc/bugs/uploads_queued_to_annex-ignore_remotes/comment_1_fa1c98f38253db8c2be3604c72eb3726._comment
new file mode 100644
index 000000000..d58d5f5dd
--- /dev/null
+++ b/doc/bugs/uploads_queued_to_annex-ignore_remotes/comment_1_fa1c98f38253db8c2be3604c72eb3726._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-03-17T20:03:48Z"
+ content="""
+I was able to find two ways this could happen:
+
+* When a removable drive was attached and the annex-ignored repository was on it.
+* When the network connection went down and came back up.
+
+In either case, it would git sync with the ignored repository. And in some cases could scan it for transfers.
+
+I've pushed a fix for these two cases. If you can try the next autobuild, that would be helpful.
+
+If you continue to see this happening, you should enable debug logging, and send a log after it happens.
+"""]]
diff --git a/doc/bugs/using_old_remote_format_generates_irritating_output.mdwn b/doc/bugs/using_old_remote_format_generates_irritating_output.mdwn
new file mode 100644
index 000000000..d53410c7b
--- /dev/null
+++ b/doc/bugs/using_old_remote_format_generates_irritating_output.mdwn
@@ -0,0 +1,28 @@
+a special remote (encrypted rsync) that got copied to long ago (not sure when, there are old files that already have sizes in their unencrypted file names) seems to use the aa/bb/GPGHMACSHA1-- format instead of aaa/bbb/GPGHMACSHA1-. ``git annex fsck`` over such files produces very irritating output:
+
+<code>
+fsck L1100423.JPG (gpg) (checking …remote…...)
+rsync: change_dir "…somewhere…/0a0/8cd/GPGHMACSHA1--91234b770b34eeff811d09c97ce94bb2398b3d72" failed: No such file or directory (2)
+
+sent 8 bytes received 12 bytes 40.00 bytes/sec
+total size is 0 speedup is 0.00
+rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1536) [Receiver=3.0.9]
+
+ rsync failed -- run git annex again to resume file transfer
+
+GPGHMACSHA1--91234b770b34eeff811d09c97ce94bb2398b3d72
+ 3922730 100% 623.81kB/s 0:00:06 (xfer#1, to-check=0/1)
+
+sent 30 bytes received 3923328 bytes 523114.40 bytes/sec
+total size is 3922730 speedup is 1.00
+(checksum...) ok
+</code>
+
+(observed with debian's git-annex 3.20121017).
+
+while this does output an "ok" at th end and a zero exit status, having such messages in an fsck is highly irritating.
+
+i see two ways to enhance the situation:
+
+* silence the "not found" error when the file is found in another location
+* a way to rename the files in the remote (i guess the aaa/bbb part can be derived from the file name; in that case, that could even be done w/o network interaction).
diff --git a/doc/bugs/using_old_remote_format_generates_irritating_output/comment_1_fceba878f1097e27f056580e8d6d5b31._comment b/doc/bugs/using_old_remote_format_generates_irritating_output/comment_1_fceba878f1097e27f056580e8d6d5b31._comment
new file mode 100644
index 000000000..d2208b57b
--- /dev/null
+++ b/doc/bugs/using_old_remote_format_generates_irritating_output/comment_1_fceba878f1097e27f056580e8d6d5b31._comment
@@ -0,0 +1,26 @@
+[[!comment format=mdwn
+ username="http://christian.amsuess.com/chrysn"
+ nickname="chrysn"
+ subject="also affects `git annex get`"
+ date="2012-11-12T23:11:36Z"
+ content="""
+the same problem also shows up with `git annex get`:
+
+ get …filename… (from prometheus...)
+ rsync: change_dir \"/home/shared/photos/encrypted_storage/63e/50b/GPGHMACSHA1--b83e8aaf05918ae2fc81652368f9d4068f938625\" failed: No such file or directory (2)
+
+ sent 8 bytes received 12 bytes 8.00 bytes/sec
+ total size is 0 speedup is 0.00
+ rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1536) [Receiver=3.0.9]
+
+ rsync failed -- run git annex again to resume file transfer
+
+ GPGHMACSHA1--b83e8aaf05918ae2fc81652368f9d4068f938625
+ 513214 100% 95.68kB/s 0:00:05 (xfer#1, to-check=0/1)
+
+ sent 30 bytes received 513396 bytes 44645.74 bytes/sec
+ total size is 513214 speedup is 1.00
+ ok
+
+again, it says \"ok\", but the \"no such file or directory\" / \"rsync failed\" is visually more prominent.
+"""]]
diff --git a/doc/bugs/using_old_remote_format_generates_irritating_output/comment_2_416992874813f120721a56d88b2bef65._comment b/doc/bugs/using_old_remote_format_generates_irritating_output/comment_2_416992874813f120721a56d88b2bef65._comment
new file mode 100644
index 000000000..1dfd0bde7
--- /dev/null
+++ b/doc/bugs/using_old_remote_format_generates_irritating_output/comment_2_416992874813f120721a56d88b2bef65._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.252.11.120"
+ subject="comment 2"
+ date="2012-11-13T17:27:31Z"
+ content="""
+So, I don't know how to suppress this message without causing worse problems, like suppressing real error messages, and even password prompts.
+
+"""]]
diff --git a/doc/bugs/using_old_remote_format_generates_irritating_output/comment_3_a20f470c5226ac5693eb15146a02b3f5._comment b/doc/bugs/using_old_remote_format_generates_irritating_output/comment_3_a20f470c5226ac5693eb15146a02b3f5._comment
new file mode 100644
index 000000000..8ee00709d
--- /dev/null
+++ b/doc/bugs/using_old_remote_format_generates_irritating_output/comment_3_a20f470c5226ac5693eb15146a02b3f5._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://christian.amsuess.com/chrysn"
+ nickname="chrysn"
+ subject="comment 3"
+ date="2012-11-14T07:31:11Z"
+ content="""
+how about renaming the stored files, them? if you give me a pointer on how the directory names are generated, i can write a script that does the migration (some hash of the file name?). i suppose that's just a relic from another naming scheme, isn't it?
+"""]]
diff --git a/doc/bugs/using_old_remote_format_generates_irritating_output/comment_4_a81f06191bc03a7aad5929af99f0634e._comment b/doc/bugs/using_old_remote_format_generates_irritating_output/comment_4_a81f06191bc03a7aad5929af99f0634e._comment
new file mode 100644
index 000000000..9ea804767
--- /dev/null
+++ b/doc/bugs/using_old_remote_format_generates_irritating_output/comment_4_a81f06191bc03a7aad5929af99f0634e._comment
@@ -0,0 +1,28 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.252.11.120"
+ subject="comment 4"
+ date="2012-11-14T17:31:38Z"
+ content="""
+The new hash directory tree is generated in a simple to explain way. Take the md5sum of the key and the first 3 characters are the first directory, and the next 3 characters are the second directory.
+
+The old hash directory tree is rather harder to explain. It takes the md5sum of the key, but rather than a string, represents it as 4 32bit words. Only the first word is used. It is converted into a string by the same mechanism that would be used to encode a normal md5sum value into a string, but where that would normally encode the bits using the 16 characters 0-9a-f, this instead uses the 32 characters \"0123456789zqjxkmvwgpfZQJXKMVWGPF\". The first 2 letters of the resulting string are the first directory, and the second 2 are the second directory.
+
+There's probably a 1:1 mapping between this special md5 encoding an a regular md5 encoding. But it's certainly easier just to use the existing Haskell implementation of the hash. The following program, which needs to be built inside a git-annex source tree, reads keys on stdin, and outputs their old hash directory tree values, and their new values on stdout.
+
+<pre>
+import Locations
+import Types.Key
+import Utility.Misc
+
+main = interact $ \s -> case file2key $ firstLine s of
+ Nothing -> \"bad key\"
+ Just k -> hashDirMixed k ++ \" \" ++ hashDirLower k ++ \"\n\"
+</pre>
+
+<pre>
+joey@gnu:~/src/git-annex>ghc --make convert.hs
+joey@gnu:~/src/git-annex>echo WORM--foo | ./ convert
+jq/8w/ 2b1/ba3/
+</pre>
+"""]]
diff --git a/doc/bugs/using_old_remote_format_generates_irritating_output/comment_5_7438caecf78b4fb5d21f9f31dff95cf2._comment b/doc/bugs/using_old_remote_format_generates_irritating_output/comment_5_7438caecf78b4fb5d21f9f31dff95cf2._comment
new file mode 100644
index 000000000..707ea52cf
--- /dev/null
+++ b/doc/bugs/using_old_remote_format_generates_irritating_output/comment_5_7438caecf78b4fb5d21f9f31dff95cf2._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://christian.amsuess.com/chrysn"
+ nickname="chrysn"
+ subject="single-line migration"
+ date="2012-11-22T03:14:45Z"
+ content="""
+i've successfully applied this monster to migrate my repository (as always with such expressions, use it only if you know what it does, and have a backup):
+
+ find . -path './??/??/*' -type d \( -exec python -c 'import sys, hashlib, os; hash = hashlib.md5(sys.argv[1][8:]).hexdigest(); h1 = hash[:3]; h2 = hash[3:6]; os.mkdir(h1) if not os.path.exists(h1) else None; os.mkdir(h1+\"/\"+h2) if not os.path.exists(h1+\"/\"+h2) else None; os.rename(sys.argv[1], h1+\"/\"+h2+\"/\"+sys.argv[1][8:])' '{}' ';' -o -print \) -prune
+
+when executed in an encrypted git annex object directory, it takes all two-letter directories, executes a python expression on them (in case of failure, printing the file name it failed on), and doesn't continue searching there (-prune avoids error messages about moved-away directories).
+
+the python expression itself generates the hash described above, generates the required directories (put awkwardly in an `a if b else c` expression to avoid ifs (which wouldn't fit in a single line) and because python still doesn't have a proper mkdir-p function), and moves the found object there. (nb: using the system's `mkdir -p` would trigger [[another bug|bugs/using_old_remote_format_generates_irritating_output]]).
+"""]]
diff --git a/doc/bugs/utf8.mdwn b/doc/bugs/utf8.mdwn
new file mode 100644
index 000000000..73b9bd9a9
--- /dev/null
+++ b/doc/bugs/utf8.mdwn
@@ -0,0 +1,192 @@
+### Please describe the problem.
+
+Git Annex stumbles and does not transfer files with special characters...
+
+
+### What steps will reproduce the problem?
+
+Added the file "Freddie_Mercury/Barcelona_[+video]/B00921KHNS_(disc_1)_04_-_Ensueño_(New_Orchestrated_Version).mp3" to Git Annex on my Galaxy Nexus (Android), which was committed successfully but not gettable.
+
+
+### What version of git-annex are you using? On what operating system?
+
+Phone: 4.20130709-g339d1eo
+Transfer Server: 3.20120406 (which it did not get to)
+Desktop: 3.20120629
+
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+fozz@cobol:~/Phone $ git annex get
+get Freddie_Mercury/Barcelona_[+video]/B00921KHNS_(disc_1)_04_-_Ensueño_(New_Orchestrated_Version).mp3 (not available)
+ Try making some of these repositories available:
+ 1f368162-f02f-4794-af0c-1b5489e099b3 -- u0_a84@localhost:/sdcard/annex
+failed
+get Freddie_Mercury/Barcelona_[+video]/B00921KKSA_(disc_2)_05_-_Ensueño_(Monsterrat's_Live_Takes).mp3 (not available)
+ Try making some of these repositories available:
+ 1f368162-f02f-4794-af0c-1b5489e099b3 -- u0_a84@localhost:/sdcard/annex
+failed
+get Freddie_Mercury/Barcelona_[+video]/B00921KMYW_(disc_3)_04_-_Ensueno_(Orchestral_Version).mp3 (not available)
+ Try making some of these repositories available:
+ 1f368162-f02f-4794-af0c-1b5489e099b3 -- u0_a84@localhost:/sdcard/annex
+failed
+get Freddie_Mercury/Barcelona_[+video]/B00921KMYW_(disc_3)_04_-_Ensueño_(Orchestral_Version).mp3 (not available)
+ Try making some of these repositories available:
+ 1f368162-f02f-4794-af0c-1b5489e099b3 -- u0_a84@localhost:/sdcard/annex
+failed
+git-annex: get: 4 failed
+
+===============
+
+fozz@cobol:~/Phone $ git annex whereis Freddie_Mercury/
+whereis Freddie_Mercury/Barcelona_[+video]/B00921KGRK_(disc_1)_01_-_Barcelona_(New_Orchestrated_Version.mp3 (3 copies)
+ 1f368162-f02f-4794-af0c-1b5489e099b3 -- u0_a84@localhost:/sdcard/annex
+ 53f03d06-f1e3-11e2-8519-1b41c09abecd -- here (Cobol: Phone)
+ cb6240e0-f1df-11e2-836a-7f4323e50c49 -- origin (Markdown: Phone)
+ok
+whereis Freddie_Mercury/Barcelona_[+video]/B00921KH5G_(disc_1)_02_-_La_Japonaise_(New_Orchestrated_Vers.mp3 (3 copies)
+ 1f368162-f02f-4794-af0c-1b5489e099b3 -- u0_a84@localhost:/sdcard/annex
+ 53f03d06-f1e3-11e2-8519-1b41c09abecd -- here (Cobol: Phone)
+ cb6240e0-f1df-11e2-836a-7f4323e50c49 -- origin (Markdown: Phone)
+ok
+whereis Freddie_Mercury/Barcelona_[+video]/B00921KHD8_(disc_1)_03_-_The_Fallen_Priest_(New_Orchestrated.mp3 (3 copies)
+ 1f368162-f02f-4794-af0c-1b5489e099b3 -- u0_a84@localhost:/sdcard/annex
+ 53f03d06-f1e3-11e2-8519-1b41c09abecd -- here (Cobol: Phone)
+ cb6240e0-f1df-11e2-836a-7f4323e50c49 -- origin (Markdown: Phone)
+ok
+whereis Freddie_Mercury/Barcelona_[+video]/B00921KHNS_(disc_1)_04_-_Ensueño_(New_Orchestrated_Version).mp3 (1 copy)
+ 1f368162-f02f-4794-af0c-1b5489e099b3 -- u0_a84@localhost:/sdcard/annex
+ok
+whereis Freddie_Mercury/Barcelona_[+video]/B00921KHY2_(disc_1)_05_-_The_Golden_Boy_(New_Orchestrated_Ve.mp3 (3 copies)
+ 1f368162-f02f-4794-af0c-1b5489e099b3 -- u0_a84@localhost:/sdcard/annex
+ 53f03d06-f1e3-11e2-8519-1b41c09abecd -- here (Cobol: Phone)
+ cb6240e0-f1df-11e2-836a-7f4323e50c49 -- origin (Markdown: Phone)
+ok
+whereis Freddie_Mercury/Barcelona_[+video]/B00921KI9G_(disc_1)_06_-_Guide_Me_Home_(New_Orchestrated_Ver.mp3 (3 copies)
+ 1f368162-f02f-4794-af0c-1b5489e099b3 -- u0_a84@localhost:/sdcard/annex
+ 53f03d06-f1e3-11e2-8519-1b41c09abecd -- here (Cobol: Phone)
+ cb6240e0-f1df-11e2-836a-7f4323e50c49 -- origin (Markdown: Phone)
+ok
+whereis Freddie_Mercury/Barcelona_[+video]/B00921KIIW_(disc_1)_07_-_How_Can_I_Go_On_(New_Orchestrated_V.mp3 (3 copies)
+ 1f368162-f02f-4794-af0c-1b5489e099b3 -- u0_a84@localhost:/sdcard/annex
+ 53f03d06-f1e3-11e2-8519-1b41c09abecd -- here (Cobol: Phone)
+ cb6240e0-f1df-11e2-836a-7f4323e50c49 -- origin (Markdown: Phone)
+ok
+whereis Freddie_Mercury/Barcelona_[+video]/B00921KITG_(disc_1)_08_-_Exercises_In_Free_Love_(New_Orchest.mp3 (3 copies)
+ 1f368162-f02f-4794-af0c-1b5489e099b3 -- u0_a84@localhost:/sdcard/annex
+ 53f03d06-f1e3-11e2-8519-1b41c09abecd -- here (Cobol: Phone)
+ cb6240e0-f1df-11e2-836a-7f4323e50c49 -- origin (Markdown: Phone)
+ok
+whereis Freddie_Mercury/Barcelona_[+video]/B00921KJ22_(disc_1)_09_-_Overture_Piccante_(New_Orchestrated.mp3 (3 copies)
+ 1f368162-f02f-4794-af0c-1b5489e099b3 -- u0_a84@localhost:/sdcard/annex
+ 53f03d06-f1e3-11e2-8519-1b41c09abecd -- here (Cobol: Phone)
+ cb6240e0-f1df-11e2-836a-7f4323e50c49 -- origin (Markdown: Phone)
+ok
+whereis Freddie_Mercury/Barcelona_[+video]/B00921KJB8_(disc_1)_10_-_How_Can_I_Go_On_(New_Orchestrated_V.mp3 (3 copies)
+ 1f368162-f02f-4794-af0c-1b5489e099b3 -- u0_a84@localhost:/sdcard/annex
+ 53f03d06-f1e3-11e2-8519-1b41c09abecd -- here (Cobol: Phone)
+ cb6240e0-f1df-11e2-836a-7f4323e50c49 -- origin (Markdown: Phone)
+ok
+whereis Freddie_Mercury/Barcelona_[+video]/B00921KJMW_(disc_2)_01_-_Exercises_In_Free_Love_(1987_B-Side.mp3 (3 copies)
+ 1f368162-f02f-4794-af0c-1b5489e099b3 -- u0_a84@localhost:/sdcard/annex
+ 53f03d06-f1e3-11e2-8519-1b41c09abecd -- here (Cobol: Phone)
+ cb6240e0-f1df-11e2-836a-7f4323e50c49 -- origin (Markdown: Phone)
+ok
+whereis Freddie_Mercury/Barcelona_[+video]/B00921KJVI_(disc_2)_02_-_Barcelona_(Early_Version__Freddie's.mp3 (3 copies)
+ 1f368162-f02f-4794-af0c-1b5489e099b3 -- u0_a84@localhost:/sdcard/annex
+ 53f03d06-f1e3-11e2-8519-1b41c09abecd -- here (Cobol: Phone)
+ cb6240e0-f1df-11e2-836a-7f4323e50c49 -- origin (Markdown: Phone)
+ok
+whereis Freddie_Mercury/Barcelona_[+video]/B00921KK5I_(disc_2)_03_-_La_Japonaise_(Early_Version__Freddi.mp3 (3 copies)
+ 1f368162-f02f-4794-af0c-1b5489e099b3 -- u0_a84@localhost:/sdcard/annex
+ 53f03d06-f1e3-11e2-8519-1b41c09abecd -- here (Cobol: Phone)
+ cb6240e0-f1df-11e2-836a-7f4323e50c49 -- origin (Markdown: Phone)
+ok
+whereis Freddie_Mercury/Barcelona_[+video]/B00921KKHQ_(disc_2)_04_-_Rachmaninov's_Revenge_(The_Fallen_P.mp3 (3 copies)
+ 1f368162-f02f-4794-af0c-1b5489e099b3 -- u0_a84@localhost:/sdcard/annex
+ 53f03d06-f1e3-11e2-8519-1b41c09abecd -- here (Cobol: Phone)
+ cb6240e0-f1df-11e2-836a-7f4323e50c49 -- origin (Markdown: Phone)
+ok
+whereis Freddie_Mercury/Barcelona_[+video]/B00921KKSA_(disc_2)_05_-_Ensueño_(Monsterrat's_Live_Takes).mp3 (1 copy)
+ 1f368162-f02f-4794-af0c-1b5489e099b3 -- u0_a84@localhost:/sdcard/annex
+ok
+whereis Freddie_Mercury/Barcelona_[+video]/B00921KL2U_(disc_2)_06_-_The_Golden_Boy_(Early_Version__Fred.mp3 (3 copies)
+ 1f368162-f02f-4794-af0c-1b5489e099b3 -- u0_a84@localhost:/sdcard/annex
+ 53f03d06-f1e3-11e2-8519-1b41c09abecd -- here (Cobol: Phone)
+ cb6240e0-f1df-11e2-836a-7f4323e50c49 -- origin (Markdown: Phone)
+ok
+whereis Freddie_Mercury/Barcelona_[+video]/B00921KLBQ_(disc_2)_07_-_Guide_Me_Home_(Alternative_Version).mp3 (3 copies)
+ 1f368162-f02f-4794-af0c-1b5489e099b3 -- u0_a84@localhost:/sdcard/annex
+ 53f03d06-f1e3-11e2-8519-1b41c09abecd -- here (Cobol: Phone)
+ cb6240e0-f1df-11e2-836a-7f4323e50c49 -- origin (Markdown: Phone)
+ok
+whereis Freddie_Mercury/Barcelona_[+video]/B00921KLJI_(disc_2)_08_-_How_Can_I_Go_On_(Alternative_Versio.mp3 (3 copies)
+ 1f368162-f02f-4794-af0c-1b5489e099b3 -- u0_a84@localhost:/sdcard/annex
+ 53f03d06-f1e3-11e2-8519-1b41c09abecd -- here (Cobol: Phone)
+ cb6240e0-f1df-11e2-836a-7f4323e50c49 -- origin (Markdown: Phone)
+ok
+whereis Freddie_Mercury/Barcelona_[+video]/B00921KLUC_(disc_2)_09_-_How_Can_I_Go_On_(Alternative_Piano_.mp3 (3 copies)
+ 1f368162-f02f-4794-af0c-1b5489e099b3 -- u0_a84@localhost:/sdcard/annex
+ 53f03d06-f1e3-11e2-8519-1b41c09abecd -- here (Cobol: Phone)
+ cb6240e0-f1df-11e2-836a-7f4323e50c49 -- origin (Markdown: Phone)
+ok
+whereis Freddie_Mercury/Barcelona_[+video]/B00921KM3I_(disc_3)_01_-_Barcelona_(Orchestral_Version).mp3 (3 copies)
+ 1f368162-f02f-4794-af0c-1b5489e099b3 -- u0_a84@localhost:/sdcard/annex
+ 53f03d06-f1e3-11e2-8519-1b41c09abecd -- here (Cobol: Phone)
+ cb6240e0-f1df-11e2-836a-7f4323e50c49 -- origin (Markdown: Phone)
+ok
+whereis Freddie_Mercury/Barcelona_[+video]/B00921KMBU_(disc_3)_02_-_La_Japonaise_(Orchestral_Version).mp3 (3 copies)
+ 1f368162-f02f-4794-af0c-1b5489e099b3 -- u0_a84@localhost:/sdcard/annex
+ 53f03d06-f1e3-11e2-8519-1b41c09abecd -- here (Cobol: Phone)
+ cb6240e0-f1df-11e2-836a-7f4323e50c49 -- origin (Markdown: Phone)
+ok
+whereis Freddie_Mercury/Barcelona_[+video]/B00921KMM4_(disc_3)_03_-_The_Fallen_Priest_(Orchestral_Versi.mp3 (3 copies)
+ 1f368162-f02f-4794-af0c-1b5489e099b3 -- u0_a84@localhost:/sdcard/annex
+ 53f03d06-f1e3-11e2-8519-1b41c09abecd -- here (Cobol: Phone)
+ cb6240e0-f1df-11e2-836a-7f4323e50c49 -- origin (Markdown: Phone)
+ok
+whereis Freddie_Mercury/Barcelona_[+video]/B00921KMYW_(disc_3)_04_-_Ensueno_(Orchestral_Version).mp3 (1 copy)
+ 1f368162-f02f-4794-af0c-1b5489e099b3 -- u0_a84@localhost:/sdcard/annex
+ok
+whereis Freddie_Mercury/Barcelona_[+video]/B00921KMYW_(disc_3)_04_-_Ensueño_(Orchestral_Version).mp3 (1 copy)
+ 1f368162-f02f-4794-af0c-1b5489e099b3 -- u0_a84@localhost:/sdcard/annex
+ok
+whereis Freddie_Mercury/Barcelona_[+video]/B00921KNAK_(disc_3)_05_-_The_Golden_Boy_(Orchestral_Version).mp3 (3 copies)
+ 1f368162-f02f-4794-af0c-1b5489e099b3 -- u0_a84@localhost:/sdcard/annex
+ 53f03d06-f1e3-11e2-8519-1b41c09abecd -- here (Cobol: Phone)
+ cb6240e0-f1df-11e2-836a-7f4323e50c49 -- origin (Markdown: Phone)
+ok
+whereis Freddie_Mercury/Barcelona_[+video]/B00921KNUA_(disc_3)_06_-_Guide_Me_Home_(Orchestral_Version).mp3 (3 copies)
+ 1f368162-f02f-4794-af0c-1b5489e099b3 -- u0_a84@localhost:/sdcard/annex
+ 53f03d06-f1e3-11e2-8519-1b41c09abecd -- here (Cobol: Phone)
+ cb6240e0-f1df-11e2-836a-7f4323e50c49 -- origin (Markdown: Phone)
+ok
+whereis Freddie_Mercury/Barcelona_[+video]/B00921KOVI_(disc_3)_07_-_How_Can_I_Go_On_(Orchestral_Version.mp3 (3 copies)
+ 1f368162-f02f-4794-af0c-1b5489e099b3 -- u0_a84@localhost:/sdcard/annex
+ 53f03d06-f1e3-11e2-8519-1b41c09abecd -- here (Cobol: Phone)
+ cb6240e0-f1df-11e2-836a-7f4323e50c49 -- origin (Markdown: Phone)
+ok
+whereis Freddie_Mercury/Barcelona_[+video]/B00921KPP8_(disc_3)_08_-_Exercises_In_Free_Love_(Orchestral_.mp3 (3 copies)
+ 1f368162-f02f-4794-af0c-1b5489e099b3 -- u0_a84@localhost:/sdcard/annex
+ 53f03d06-f1e3-11e2-8519-1b41c09abecd -- here (Cobol: Phone)
+ cb6240e0-f1df-11e2-836a-7f4323e50c49 -- origin (Markdown: Phone)
+ok
+whereis Freddie_Mercury/Barcelona_[+video]/B00921KQJ8_(disc_3)_09_-_Overture_Piccante_(Orchestral_Versi.mp3 (3 copies)
+ 1f368162-f02f-4794-af0c-1b5489e099b3 -- u0_a84@localhost:/sdcard/annex
+ 53f03d06-f1e3-11e2-8519-1b41c09abecd -- here (Cobol: Phone)
+ cb6240e0-f1df-11e2-836a-7f4323e50c49 -- origin (Markdown: Phone)
+ok
+
+
+# End of transcript or log.
+"""]]
+
+> We seem to have reached a point of confusion, lack of information,
+> and/or diminishing returns with this bug report. I have fixed
+> it as best I can. If you have any problems, please file a new bug report
+> with as complete information as possible. [[done]] --[[Joey]]
diff --git a/doc/bugs/utf8/comment_10_f298b8b480d3ab2dd9c279589afcd0ea._comment b/doc/bugs/utf8/comment_10_f298b8b480d3ab2dd9c279589afcd0ea._comment
new file mode 100644
index 000000000..7a61fc0d5
--- /dev/null
+++ b/doc/bugs/utf8/comment_10_f298b8b480d3ab2dd9c279589afcd0ea._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnRai_qFYPVvEgC6i1nlM1bh-C__jbhqS0"
+ nickname="Matthew"
+ subject="Ooops"
+ date="2013-07-26T21:28:46Z"
+ content="""
+Hi Joey,
+
+I started replicating it today but managed to make annex a directory structure I did not mean to through my own silly fault and it's taking ages to unannex, I'll have another go over the weekend, this time with not so fat fingers!
+"""]]
diff --git a/doc/bugs/utf8/comment_11_a8864a46f8154680beeea27449ac6f09._comment b/doc/bugs/utf8/comment_11_a8864a46f8154680beeea27449ac6f09._comment
new file mode 100644
index 000000000..50822a094
--- /dev/null
+++ b/doc/bugs/utf8/comment_11_a8864a46f8154680beeea27449ac6f09._comment
@@ -0,0 +1,142 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnRai_qFYPVvEgC6i1nlM1bh-C__jbhqS0"
+ nickname="Matthew"
+ subject="Replicated, I think"
+ date="2013-07-27T10:02:32Z"
+ content="""
+I think I have it replicated, I did not do _exactly_ the same thing, no renaming of the tilde-n file but I still got the ControlPath error.
+
+ # On phone - Copy folder into Git Annex... wait till done
+ # On Server with new Git Annex: git annex sync
+ fozz@markdown:~/tmp/zzz$ git annex get .
+ get Freddie_Mercury/Barcelona_[+video]/B00921KGRK_(disc_1)_01_-_Barcelona_(New_Orchestrated_Version.mp3 (from origin...) ok
+ get Freddie_Mercury/Barcelona_[+video]/B00921KH5G_(disc_1)_02_-_La_Japonaise_(New_Orchestrated_Vers.mp3 (from origin...) ok
+ get Freddie_Mercury/Barcelona_[+video]/B00921KHD8_(disc_1)_03_-_The_Fallen_Priest_(New_Orchestrated.mp3 (from origin...) ok
+ get Freddie_Mercury/Barcelona_[+video]/B00921KHNS_(disc_1)_04_-_Ensueño_(New_Orchestrated_Version).mp3 (not available)
+ Try making some of these repositories available:
+ bc0525c4-cf9e-45da-a8e1-19003dee1dcb -- u0_a84@localhost:/sdcard/annex
+ failed
+ get Freddie_Mercury/Barcelona_[+video]/B00921KHY2_(disc_1)_05_-_The_Golden_Boy_(New_Orchestrated_Ve.mp3 (from origin...) ok
+ get Freddie_Mercury/Barcelona_[+video]/B00921KI9G_(disc_1)_06_-_Guide_Me_Home_(New_Orchestrated_Ver.mp3 (from origin...) ok
+ get Freddie_Mercury/Barcelona_[+video]/B00921KIIW_(disc_1)_07_-_How_Can_I_Go_On_(New_Orchestrated_V.mp3 ^[[A^[[A^[[A^[[A^[[A^[[A(from origin...) ^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[A^[[Aok
+ get Freddie_Mercury/Barcelona_[+video]/B00921KITG_(disc_1)_08_-_Exercises_In_Free_Love_(New_Orchest.mp3 ^[[A^[[A^[[A^[[A^[[A^[[A(from origin...) ^[[A^[[A^[[A^[[A^[[A^[[Aok
+ get Freddie_Mercury/Barcelona_[+video]/B00921KJ22_(disc_1)_09_-_Overture_Piccante_(New_Orchestrated.mp3 ^C
+ fozz@markdown:~/tmp/zzz$ git annex get .
+ get Freddie_Mercury/Barcelona_[+video]/B00921KHNS_(disc_1)_04_-_Ensueño_(New_Orchestrated_Version).mp3 (not available)
+ Try making some of these repositories available:
+ bc0525c4-cf9e-45da-a8e1-19003dee1dcb -- u0_a84@localhost:/sdcard/annex
+ failed
+ get Freddie_Mercury/Barcelona_[+video]/B00921KJ22_(disc_1)_09_-_Overture_Piccante_(New_Orchestrated.mp3 (from origin...) ok
+ get Freddie_Mercury/Barcelona_[+video]/B00921KJB8_(disc_1)_10_-_How_Can_I_Go_On_(New_Orchestrated_V.mp3 (from origin...) ok
+ get Freddie_Mercury/Barcelona_[+video]/B00921KJMW_(disc_2)_01_-_Exercises_In_Free_Love_(1987_B-Side.mp3 (from origin...) ok
+ get Freddie_Mercury/Barcelona_[+video]/B00921KJVI_(disc_2)_02_-_Barcelona_(Early_Version__Freddie's.mp3 (from origin...) ok
+ get Freddie_Mercury/Barcelona_[+video]/B00921KK5I_(disc_2)_03_-_La_Japonaise_(Early_Version__Freddi.mp3 (from origin...) ok
+ get Freddie_Mercury/Barcelona_[+video]/B00921KKHQ_(disc_2)_04_-_Rachmaninov's_Revenge_(The_Fallen_P.mp3 (from origin...) ok
+ get Freddie_Mercury/Barcelona_[+video]/B00921KKSA_(disc_2)_05_-_Ensueño_(Monsterrat's_Live_Takes).mp3 (not available)
+ Try making some of these repositories available:
+ bc0525c4-cf9e-45da-a8e1-19003dee1dcb -- u0_a84@localhost:/sdcard/annex
+ failed
+ get Freddie_Mercury/Barcelona_[+video]/B00921KL2U_(disc_2)_06_-_The_Golden_Boy_(Early_Version__Fred.mp3 (from origin...) ok
+ get Freddie_Mercury/Barcelona_[+video]/B00921KLBQ_(disc_2)_07_-_Guide_Me_Home_(Alternative_Version).mp3 (from origin...) ok
+ get Freddie_Mercury/Barcelona_[+video]/B00921KLJI_(disc_2)_08_-_How_Can_I_Go_On_(Alternative_Versio.mp3 (from origin...) ok
+ get Freddie_Mercury/Barcelona_[+video]/B00921KLUC_(disc_2)_09_-_How_Can_I_Go_On_(Alternative_Piano_.mp3 (from origin...) ok
+ get Freddie_Mercury/Barcelona_[+video]/B00921KM3I_(disc_3)_01_-_Barcelona_(Orchestral_Version).mp3 (from origin...) ok
+ get Freddie_Mercury/Barcelona_[+video]/B00921KMBU_(disc_3)_02_-_La_Japonaise_(Orchestral_Version).mp3 (from origin...) ok
+ get Freddie_Mercury/Barcelona_[+video]/B00921KMM4_(disc_3)_03_-_The_Fallen_Priest_(Orchestral_Versi.mp3 (from origin...) ok
+ get Freddie_Mercury/Barcelona_[+video]/B00921KMYW_(disc_3)_04_-_Ensueño_(Orchestral_Version).mp3 (not available)
+ Try making some of these repositories available:
+ bc0525c4-cf9e-45da-a8e1-19003dee1dcb -- u0_a84@localhost:/sdcard/annex
+ failed
+ get Freddie_Mercury/Barcelona_[+video]/B00921KNAK_(disc_3)_05_-_The_Golden_Boy_(Orchestral_Version).mp3 (from origin...) ok
+ get Freddie_Mercury/Barcelona_[+video]/B00921KNUA_(disc_3)_06_-_Guide_Me_Home_(Orchestral_Version).mp3 (from origin...) ok
+ get Freddie_Mercury/Barcelona_[+video]/B00921KOVI_(disc_3)_07_-_How_Can_I_Go_On_(Orchestral_Version.mp3 (from origin...) ok
+ get Freddie_Mercury/Barcelona_[+video]/B00921KPP8_(disc_3)_08_-_Exercises_In_Free_Love_(Orchestral_.mp3 (from origin...) ok
+ get Freddie_Mercury/Barcelona_[+video]/B00921KQJ8_(disc_3)_09_-_Overture_Piccante_(Orchestral_Versi.mp3 (from origin...) ok
+ (Recording state in git...)
+ git-annex: get: 3 failed
+
+ fozz@markdown:~/tmp/zzz$ git annex whereis Freddie_Mercury/Barcelona_\[+video\]/B00921KMYW_\(disc_3\)_04_-_Ensueño_\(Orchestral_Version\).mp3
+ whereis Freddie_Mercury/Barcelona_[+video]/B00921KMYW_(disc_3)_04_-_Ensueño_(Orchestral_Version).mp3 (1 copy)
+ bc0525c4-cf9e-45da-a8e1-19003dee1dcb -- u0_a84@localhost:/sdcard/annex
+ ok
+
+ # On phone
+ Falling back to hardcoded app location; cannot find expected files in /data/app-lib
+ git annex webapp
+ u0_a84@android:/sdcard/git-annex.home $ git annex webapp
+
+ Detected a crippled filesystem.
+
+ Enabling direct mode.
+ fozz@markdown.lang.speechmarks.com's password:
+ fozz@markdown.lang.speechmarks.com's password:
+ ^Z[1] + Stopped git annex webapp
+ u0_a84@android:/sdcard/git-annex.home $ bg
+ [1] git annex webapp
+ u0_a84@android:/sdcard/git-annex.home $ cd ../annex/
+ u0_a84@android:/sdcard/annex $ ls
+ Freddie_Mercury
+ u0_a84@android:/sdcard/annex $ git remote -v
+ markdown.lang.speechmarks.com_phoneannex ssh://fozz@git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex/~/phone-annex/ (fetch)
+ markdown.lang.speechmarks.com_phoneannex ssh://fozz@git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex/~/phone-annex/ (push)
+ u0_a84@android:/sdcard/annex $ git annex copy . --to markdown.lang.speechmarks.com_phoneannex
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KGRK_(disc_1)_01_-_Barcelona_(New_Orchestrated_Version.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ControlPath \"/data/data/ga.androidterm/tmp/fozz@git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex.IdWwlXHtSsjVUMcq\" too long for Unix domain socket
+ ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KH5G_(disc_1)_02_-_La_Japonaise_(New_Orchestrated_Vers.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ControlPath \"/data/data/ga.androidterm/tmp/fozz@git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex.WisPICyIHiMGEO3k\" too long for Unix domain socket
+ ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KHD8_(disc_1)_03_-_The_Fallen_Priest_(New_Orchestrated.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ControlPath \"/data/data/ga.androidterm/tmp/fozz@git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex.hYyDKddvBHgjW4AI\" too long for Unix domain socket
+ ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KHNS_(disc_1)_04_-_Ensueo_(New_Orchestrated_Version).mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ControlPath \"/data/data/ga.androidterm/tmp/fozz@git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex.PR2s7Btep0Vklpr1\" too long for Unix domain socket
+ ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KHY2_(disc_1)_05_-_The_Golden_Boy_(New_Orchestrated_Ve.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ControlPath \"/data/data/ga.androidterm/tmp/fozz@git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex.GuiE6O9sVgvAsPjv\" too long for Unix domain socket
+ ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KI9G_(disc_1)_06_-_Guide_Me_Home_(New_Orchestrated_Ver.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ControlPath \"/data/data/ga.androidterm/tmp/fozz@git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex.MNE7Nrd4rTe59BpR\" too long for Unix domain socket
+ ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KIIW_(disc_1)_07_-_How_Can_I_Go_On_(New_Orchestrated_V.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ControlPath \"/data/data/ga.androidterm/tmp/fozz@git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex.MtXCKPHds4ma0iPl\" too long for Unix domain socket
+ ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KITG_(disc_1)_08_-_Exercises_In_Free_Love_(New_Orchest.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ControlPath \"/data/data/ga.androidterm/tmp/fozz@git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex.6iovvzKR6HE4nZwz\" too long for Unix domain socket
+ ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KJ22_(disc_1)_09_-_Overture_Piccante_(New_Orchestrated.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ControlPath \"/data/data/ga.androidterm/tmp/fozz@git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex.wZy825TDcYvHhDUx\" too long for Unix domain socket
+ ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KJB8_(disc_1)_10_-_How_Can_I_Go_On_(New_Orchestrated_V.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ControlPath \"/data/data/ga.androidterm/tmp/fozz@git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex.RQLLAcX2MGpLvJC5\" too long for Unix domain socket
+ ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KJMW_(disc_2)_01_-_Exercises_In_Free_Love_(1987_B-Side.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ControlPath \"/data/data/ga.androidterm/tmp/fozz@git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex.kiQQXvKBLNSP3cRO\" too long for Unix domain socket
+ ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KJVI_(disc_2)_02_-_Barcelona_(Early_Version__Freddie's.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ControlPath \"/data/data/ga.androidterm/tmp/fozz@git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex.CIdY4uFDFCIboOpG\" too long for Unix domain socket
+ ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KK5I_(disc_2)_03_-_La_Japonaise_(Early_Version__Freddi.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ControlPath \"/data/data/ga.androidterm/tmp/fozz@git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex.sza5nEOnJ4qnh6op\" too long for Unix domain socket
+ ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KKHQ_(disc_2)_04_-_Rachmaninov's_Revenge_(The_Fallen_P.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ControlPath \"/data/data/ga.androidterm/tmp/fozz@git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex.PXT6QfTHojjPvlBM\" too long for Unix domain socket
+ ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KKSA_(disc_2)_05_-_Ensueo_(Monsterrat's_Live_Takes).mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ControlPath \"/data/data/ga.androidterm/tmp/fozz@git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex.LaHS26WonwTUqBDO\" too long for Unix domain socket
+ ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KL2U_(disc_2)_06_-_The_Golden_Boy_(Early_Version__Fred.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ControlPath \"/data/data/ga.androidterm/tmp/fozz@git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex.rw9hP3fjehIAJc1P\" too long for Unix domain socket
+ ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KLBQ_(disc_2)_07_-_Guide_Me_Home_(Alternative_Version).mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ControlPath \"/data/data/ga.androidterm/tmp/fozz@git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex.aJOWNwtRBDG6pecN\" too long for Unix domain socket
+ ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KLJI_(disc_2)_08_-_How_Can_I_Go_On_(Alternative_Versio.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ControlPath \"/data/data/ga.androidterm/tmp/fozz@git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex.fOFCaugrRAzzHAMZ\" too long for Unix domain socket
+ ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KLUC_(disc_2)_09_-_How_Can_I_Go_On_(Alternative_Piano_.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ControlPath \"/data/data/ga.androidterm/tmp/fozz@git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex.onG8CR4YP9x5c3ZK\" too long for Unix domain socket
+ ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KM3I_(disc_3)_01_-_Barcelona_(Orchestral_Version).mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ControlPath \"/data/data/ga.androidterm/tmp/fozz@git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex.KgOqB8Rg1ZZI1fzP\" too long for Unix domain socket
+ ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KMBU_(disc_3)_02_-_La_Japonaise_(Orchestral_Version).mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ControlPath \"/data/data/ga.androidterm/tmp/fozz@git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex.xN1FqoX79hSxwQS7\" too long for Unix domain socket
+ ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KMM4_(disc_3)_03_-_The_Fallen_Priest_(Orchestral_Versi.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ControlPath \"/data/data/ga.androidterm/tmp/fozz@git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex.YpZgAo1LVawkOIBd\" too long for Unix domain socket
+ ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KMYW_(disc_3)_04_-_Ensueo_(Orchestral_Version).mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ControlPath \"/data/data/ga.androidterm/tmp/fozz@git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex.TDvJl5gPqOFTbqgF\" too long for Unix domain socket
+ ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KNAK_(disc_3)_05_-_The_Golden_Boy_(Orchestral_Version).mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ControlPath \"/data/data/ga.androidterm/tmp/fozz@git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex.CYBfRJuMZTYUgTnN\" too long for Unix domain socket
+ ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KNUA_(disc_3)_06_-_Guide_Me_Home_(Orchestral_Version).mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ControlPath \"/data/data/ga.androidterm/tmp/fozz@git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex.VjyVTH1bRjeRl7fE\" too long for Unix domain socket
+ ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KOVI_(disc_3)_07_-_How_Can_I_Go_On_(Orchestral_Version.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ControlPath \"/data/data/ga.androidterm/tmp/fozz@git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex.SfA8ZMsoaea1JqZm\" too long for Unix domain socket
+ ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KPP8_(disc_3)_08_-_Exercises_In_Free_Love_(Orchestral_.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ControlPath \"/data/data/ga.androidterm/tmp/fozz@git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex.uYsVLhxvYZl1F7Dj\" too long for Unix domain socket
+ ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KQJ8_(disc_3)_09_-_Overture_Piccante_(Orchestral_Versi.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ControlPath \"/data/data/ga.androidterm/tmp/fozz@git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex.NRAFY6O124W6tAdG\" too long for Unix domain socket
+ ok
+ (Recording state in git...)
+ u0_a84@android:/sdcard/annex $
+
+"""]]
diff --git a/doc/bugs/utf8/comment_12_2202c3479d19d306f31aac5a47b55e7d._comment b/doc/bugs/utf8/comment_12_2202c3479d19d306f31aac5a47b55e7d._comment
new file mode 100644
index 000000000..50adfd847
--- /dev/null
+++ b/doc/bugs/utf8/comment_12_2202c3479d19d306f31aac5a47b55e7d._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.110"
+ subject="comment 12"
+ date="2013-07-27T17:46:11Z"
+ content="""
+Ok, I think if you upgrade to the current build for Android, you'll find that the problem goes away. I put in a fix several days ago that makes it use much shorter controlpaths.
+
+The question remains why it ever used a path of \"/data/data/ga.androidterm/tmp/fozz@git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex.IdWwlXHtSsjVUMcq\". This is 110 bytes; the code checks for a path of longer than 99 bytes. It should have disabled ssh connection caching when it was unable to construct a short enough path.
+"""]]
diff --git a/doc/bugs/utf8/comment_13_7044d2c5bb1c91ee37eb9868963a1ff2._comment b/doc/bugs/utf8/comment_13_7044d2c5bb1c91ee37eb9868963a1ff2._comment
new file mode 100644
index 000000000..651e43438
--- /dev/null
+++ b/doc/bugs/utf8/comment_13_7044d2c5bb1c91ee37eb9868963a1ff2._comment
@@ -0,0 +1,41 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.110"
+ subject="comment 13"
+ date="2013-07-27T20:46:01Z"
+ content="""
+I've verified that the (old) code correctly returned no path when it's too long:
+
+<pre>
+*Annex.Ssh System.Directory System.Posix.Directory Annex Git.Construct Git.Config System.Posix.Env Utility.Env> eval (newState r') $ changeGitConfig (\c -> c { annexCrippledFileSystem = True }) >> sshInfo (\"fozz@git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex.IdWwlXHtSsjVUMcq\", Nothing)
+(Nothing,[])
+</pre>
+
+In case the problem was somehow related to calculating the length on Android (ie, Data.Bits.Utils broken), I built a small program that calculated the length of the string the same way
+
+[[!format haskell \"\"\"
+import Utility.FileSystemEncoding
+
+main = do
+ let s = \"/data/data/ga.androidterm/tmp/fozz@git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex.IdWwlXHtSsjVUMcq\"
+ let ws = decodeW8 s
+ print (length ws)
+\"\"\"]]
+
+Outputs 110 on Android as expected.
+
+Finally, using git-annex 4.20130721-g002de3e on Android (a newer version than the bug reporter's but with no changes to Annex.Ssh), I manually set up a repository using the same hostname:
+
+<pre>
+[remote \"foo\"]
+ url = ssh://fozz@git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex.IdWwlXHtSsjVUMcq
+ fetch = +refs/heads/*:refs/remotes/foo/*
+ annex-uuid = dummy
+</pre>
+
+And still cannot replicate the bug; as expected it does not use the socket since it's too long:
+
+copy foo (checking foo...) [2013-07-27 16:40:42 EDT] call: ssh [\"-T\",\"fozz@git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex.IdWwlXHtSsjVUMcq\",\"git-annex-shell 'inannex' '' 'SHA256E-s29--093429efb0d1427753d1f038f5279ec4df66785a1b2429b3fa5e3a01bcb75bd8' --uuid 111\"]
+
+So, I don't understand how this could have happened. Although my recent changes mean it'll use a 62 byte path max on Android now, which certainly should avoid the problem, even if there's some actual bug here that I cannot reproduce.
+"""]]
diff --git a/doc/bugs/utf8/comment_14_656b3caa16ae93b092fb5804fa575a3b._comment b/doc/bugs/utf8/comment_14_656b3caa16ae93b092fb5804fa575a3b._comment
new file mode 100644
index 000000000..6c858013b
--- /dev/null
+++ b/doc/bugs/utf8/comment_14_656b3caa16ae93b092fb5804fa575a3b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnRai_qFYPVvEgC6i1nlM1bh-C__jbhqS0"
+ nickname="Matthew"
+ subject="Will give the new version a got tomorrow..."
+ date="2013-07-27T21:45:29Z"
+ content="""
+But do you have any idea why it didn't transfer the filename with the ~ above the n?
+"""]]
diff --git a/doc/bugs/utf8/comment_15_25b3d4c47c45b72129b17b171a45c5f9._comment b/doc/bugs/utf8/comment_15_25b3d4c47c45b72129b17b171a45c5f9._comment
new file mode 100644
index 000000000..8fb44eebd
--- /dev/null
+++ b/doc/bugs/utf8/comment_15_25b3d4c47c45b72129b17b171a45c5f9._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.110"
+ subject="comment 15"
+ date="2013-07-27T21:50:32Z"
+ content="""
+AFAICS it was failing to transfer every file, no matter what the name, due to the socket length too long problem.
+"""]]
diff --git a/doc/bugs/utf8/comment_16_2aaab9253bbc75012292c7b5a7d55696._comment b/doc/bugs/utf8/comment_16_2aaab9253bbc75012292c7b5a7d55696._comment
new file mode 100644
index 000000000..e10b8f85a
--- /dev/null
+++ b/doc/bugs/utf8/comment_16_2aaab9253bbc75012292c7b5a7d55696._comment
@@ -0,0 +1,173 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnRai_qFYPVvEgC6i1nlM1bh-C__jbhqS0"
+ nickname="Matthew"
+ subject="Not completely..."
+ date="2013-07-28T11:44:40Z"
+ content="""
+So done a bit of testing this morning...
+
+I upgraded the Git Annex on my phone and added a text file called \"mañnequin\" into my Git Annex. The assistant web app did not do anything and it did not appear on my desktop when I sync'd... So I went to my phone manually added it and synced. Which then did make it appear on my desktop when I did a sync.
+
+Phone Log:
+
+ Falling back to hardcoded app location; cannot find expected files in /data/app-lib
+ git annex webapp
+ u0_a84@android:/sdcard/git-annex.home $ git annex webapp
+ ^Z[1] + Stopped git annex webapp
+ u0_a84@android:/sdcard/git-annex.home $ bg
+ [1] git annex webapp
+ u0_a84@android:/sdcard/git-annex.home $ cd ../annex/
+ u0_a84@android:/sdcard/annex $ git remote -v
+ markdown.lang.speechmarks.com_phoneannex ssh://fozz@git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex/~/phone-annex/ (fetch)
+ markdown.lang.speechmarks.com_phoneannex ssh://fozz@git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex/~/phone-annex/ (push)
+ u0_a84@android:/sdcard/annex $ git-annex version
+ git-annex version: 4.20130723-ged05a63
+ build flags: Assistant Webapp Testsuite S3 WebDAV Inotify XMPP DNS
+ local repository version: 4
+ default repository version: 3
+ supported repository versions: 3 4
+ upgrade supported from repository versions: 0 1 2
+ u0_a84@android:/sdcard/annex $ git annex copy . --to markdown.lang.speechmarks.com_phoneannex
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KGRK_(disc_1)_01_-_Barcelona_(New_Orchestrated_Version.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KH5G_(disc_1)_02_-_La_Japonaise_(New_Orchestrated_Vers.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KHD8_(disc_1)_03_-_The_Fallen_Priest_(New_Orchestrated.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KHNS_(disc_1)_04_-_Ensueo_(New_Orchestrated_Version).mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KHY2_(disc_1)_05_-_The_Golden_Boy_(New_Orchestrated_Ve.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KI9G_(disc_1)_06_-_Guide_Me_Home_(New_Orchestrated_Ver.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KIIW_(disc_1)_07_-_How_Can_I_Go_On_(New_Orchestrated_V.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KITG_(disc_1)_08_-_Exercises_In_Free_Love_(New_Orchest.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KJ22_(disc_1)_09_-_Overture_Piccante_(New_Orchestrated.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KJB8_(disc_1)_10_-_How_Can_I_Go_On_(New_Orchestrated_V.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KJMW_(disc_2)_01_-_Exercises_In_Free_Love_(1987_B-Side.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KJVI_(disc_2)_02_-_Barcelona_(Early_Version__Freddie's.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KK5I_(disc_2)_03_-_La_Japonaise_(Early_Version__Freddi.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KKHQ_(disc_2)_04_-_Rachmaninov's_Revenge_(The_Fallen_P.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KKSA_(disc_2)_05_-_Ensueo_(Monsterrat's_Live_Takes).mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KL2U_(disc_2)_06_-_The_Golden_Boy_(Early_Version__Fred.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KLBQ_(disc_2)_07_-_Guide_Me_Home_(Alternative_Version).mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KLJI_(disc_2)_08_-_How_Can_I_Go_On_(Alternative_Versio.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KLUC_(disc_2)_09_-_How_Can_I_Go_On_(Alternative_Piano_.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KM3I_(disc_3)_01_-_Barcelona_(Orchestral_Version).mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KMBU_(disc_3)_02_-_La_Japonaise_(Orchestral_Version).mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KMM4_(disc_3)_03_-_The_Fallen_Priest_(Orchestral_Versi.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KMYW_(disc_3)_04_-_Ensueo_(Orchestral_Version).mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KNAK_(disc_3)_05_-_The_Golden_Boy_(Orchestral_Version).mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KNUA_(disc_3)_06_-_Guide_Me_Home_(Orchestral_Version).mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KOVI_(disc_3)_07_-_How_Can_I_Go_On_(Orchestral_Version.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KPP8_(disc_3)_08_-_Exercises_In_Free_Love_(Orchestral_.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ok
+ copy Freddie_Mercury/Barcelona_[+video]/B00921KQJ8_(disc_3)_09_-_Overture_Piccante_(Orchestral_Versi.mp3 (checking markdown.lang.speechmarks.com_phoneannex...) ok
+ u0_a84@android:/sdcard/annex $ ls
+ Freddie_Mercury
+ u0_a84@android:/sdcard/annex $ ls
+ ls lsattr lsmod lsof lspci lsusb
+ rcury/Barcelona_\[+video]/B00921K <
+ B00921KGRK_(disc_1)_01_-_Barcelona_(New_Orchestrated_Version.mp3
+ B00921KH5G_(disc_1)_02_-_La_Japonaise_(New_Orchestrated_Vers.mp3
+ B00921KHD8_(disc_1)_03_-_The_Fallen_Priest_(New_Orchestrated.mp3
+ B00921KHNS_(disc_1)_04_-_Ensueo_(New_Orchestrated_Version).mp3
+ B00921KHY2_(disc_1)_05_-_The_Golden_Boy_(New_Orchestrated_Ve.mp3
+ B00921KI9G_(disc_1)_06_-_Guide_Me_Home_(New_Orchestrated_Ver.mp3
+ B00921KIIW_(disc_1)_07_-_How_Can_I_Go_On_(New_Orchestrated_V.mp3
+ B00921KITG_(disc_1)_08_-_Exercises_In_Free_Love_(New_Orchest.mp3
+ B00921KJ22_(disc_1)_09_-_Overture_Piccante_(New_Orchestrated.mp3
+ B00921KJB8_(disc_1)_10_-_How_Can_I_Go_On_(New_Orchestrated_V.mp3
+ B00921KJMW_(disc_2)_01_-_Exercises_In_Free_Love_(1987_B-Side.mp3
+ B00921KJVI_(disc_2)_02_-_Barcelona_(Early_Version__Freddie's.mp3
+ B00921KK5I_(disc_2)_03_-_La_Japonaise_(Early_Version__Freddi.mp3
+ B00921KKHQ_(disc_2)_04_-_Rachmaninov's_Revenge_(The_Fallen_P.mp3
+ B00921KKSA_(disc_2)_05_-_Ensueo_(Monsterrat's_Live_Takes).mp3
+ B00921KL2U_(disc_2)_06_-_The_Golden_Boy_(Early_Version__Fred.mp3
+ B00921KLBQ_(disc_2)_07_-_Guide_Me_Home_(Alternative_Version).mp3
+ B00921KLJI_(disc_2)_08_-_How_Can_I_Go_On_(Alternative_Versio.mp3
+ B00921KLUC_(disc_2)_09_-_How_Can_I_Go_On_(Alternative_Piano_.mp3
+ B00921KM3I_(disc_3)_01_-_Barcelona_(Orchestral_Version).mp3
+ B00921KMBU_(disc_3)_02_-_La_Japonaise_(Orchestral_Version).mp3
+ B00921KMM4_(disc_3)_03_-_The_Fallen_Priest_(Orchestral_Versi.mp3
+ B00921KMYW_(disc_3)_04_-_Ensueo_(Orchestral_Version).mp3
+ B00921KNAK_(disc_3)_05_-_The_Golden_Boy_(Orchestral_Version).mp3
+ B00921KNUA_(disc_3)_06_-_Guide_Me_Home_(Orchestral_Version).mp3
+ B00921KOVI_(disc_3)_07_-_How_Can_I_Go_On_(Orchestral_Version.mp3
+ B00921KPP8_(disc_3)_08_-_Exercises_In_Free_Love_(Orchestral_.mp3
+ B00921KQJ8_(disc_3)_09_-_Overture_Piccante_(Orchestral_Versi.mp3
+ rcury/Barcelona_\[+video]/B00921K <
+ ls: Freddie_Mercury/Barcelona_[+video]/B00921K: No such file or directory
+ 1|u0_a84@android:/sdcard/annex $
+ 1|u0_a84@android:/sdcard/annex $
+ 1|u0_a84@android:/sdcard/annex $
+ 1|u0_a84@android:/sdcard/annex $
+ 1|u0_a84@android:/sdcard/annex $
+ 1|u0_a84@android:/sdcard/annex $ fg
+ git annex webapp
+ bg
+ ^Z[1] + Stopped git annex webapp
+ u0_a84@android:/sdcard/annex $ bg
+ [1] git annex webapp
+ u0_a84@android:/sdcard/annex $ ls
+ Freddie_Mercury ma??nequin
+ u0_a84@android:/sdcard/annex $ git annex add manequin
+ Freddie_Mercury/ manequin
+ u0_a84@android:/sdcard/annex $ git annex add manequin
+ add manequin (checksum...) ok
+ (Recording state in git...)
+ u0_a84@android:/sdcard/annex $ git annex sync
+ commit
+ ok
+ pull markdown.lang.speechmarks.com_phoneannex
+ remote: Counting objects: 12, done.
+ remote: Compressing objects: 100% (6/6), done.
+ remote: Total 8 (delta 4), reused 0 (delta 0)
+ Unpacking objects: 100% (8/8), done.
+ From ssh://git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex/~/phone-annex
+ c709e47..d2678a5 synced/git-annex -> markdown.lang.speechmarks.com_phoneannex/synced/git-annex
+ ok
+ (merging markdown.lang.speechmarks.com_phoneannex/synced/git-annex into git-annex...)
+ (Recording state in git...)
+ (Recording state in git...)
+ push markdown.lang.speechmarks.com_phoneannex
+ warning: no threads support, ignoring --threads
+ Counting objects: 15, done.
+ Compressing objects: 100% (11/11), done.
+ Writing objects: 100% (12/12), 1.19 KiB, done.
+ Total 12 (delta 4), reused 0 (delta 0)
+ To ssh://fozz@git-annex-markdown.lang.speechmarks.com-fozz_phone.2Dannex/~/phone-annex/
+ d2678a5..577fa92 git-annex -> synced/git-annex
+ c829a0a..2aa892f master -> synced/master
+ ok
+ u0_a84@android:/sdcard/annex $
+
+I have no idea in this log why it is wrote \"manequin\" not \"mañnequin\" but this is what the command completion gave me ( I don't know how to type that letter ), but as you can see later it came over correctly later.
+
+Desktop:
+
+ fozz@cobol:~/phone-annex $ git annex sync
+ commit
+ # On branch master
+ nothing to commit, working directory clean
+ ok
+ pull origin
+ remote: Counting objects: 15, done.
+ remote: Compressing objects: 100% (11/11), done.
+ remote: Total 12 (delta 4), reused 0 (delta 0)
+ Unpacking objects: 100% (12/12), done.
+ From ssh://markdown.lang.speechmarks.com/home/fozz/phone-annex
+ c829a0a..2aa892f master -> origin/master
+ d2678a5..577fa92 synced/git-annex -> origin/synced/git-annex
+ c829a0a..2aa892f synced/master -> origin/synced/master
+
+ Updating c829a0a..2aa892f
+ Fast-forward
+ \"ma\303\261nequin\" | 1 +
+ 1 file changed, 1 insertion(+)
+ create mode 120000 \"ma\303\261nequin\"
+
+ Already up-to-date.
+ ok
+ (merging origin/synced/git-annex into git-annex...)
+ push origin
+ Everything up-to-date
+ ok
+
+I have since gone through and replicated this with \"mañnequin.txt\" from scratch with a completely empty repository and it did an identical thing again. I then added a backup of my KeePass.kdb database and it went over fine. So it seems that git-annex has no problem with the \"ñ\" file now, but the assistant does not see it at all.
+
+I have left the repository on my phone / desktop / server in this state so if you want further output please let me know.
+"""]]
diff --git a/doc/bugs/utf8/comment_1_416ad6fb5f7379732129dc5283a7e550._comment b/doc/bugs/utf8/comment_1_416ad6fb5f7379732129dc5283a7e550._comment
new file mode 100644
index 000000000..0df4c2aa5
--- /dev/null
+++ b/doc/bugs/utf8/comment_1_416ad6fb5f7379732129dc5283a7e550._comment
@@ -0,0 +1,23 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnRai_qFYPVvEgC6i1nlM1bh-C__jbhqS0"
+ nickname="Matthew"
+ subject="Renaming files"
+ date="2013-07-21T10:08:16Z"
+ content="""
+Renaming the files does not fix it, Git annex on all computers knows that those files are only in my phone, but the assistant is refusing to transfer the contents, it does not seem to know that it needs to...
+
+ whereis Freddie_Mercury/Barcelona_[+video]/B00921KMM4_(disc_3)_03_-_The_Fallen_Priest_(Orchestral_Versi.mp3 (3 copies)
+ 1f368162-f02f-4794-af0c-1b5489e099b3 -- u0_a84@localhost:/sdcard/annex
+ 53f03d06-f1e3-11e2-8519-1b41c09abecd -- here (Cobol: Phone)
+ cb6240e0-f1df-11e2-836a-7f4323e50c49 -- origin (Markdown: Phone)
+ ok
+ whereis Freddie_Mercury/Barcelona_[+video]/B00921KMYW_(disc_3)_04_-_Ensueno_(Orchestral_Version).mp3 (1 copy)
+ 1f368162-f02f-4794-af0c-1b5489e099b3 -- u0_a84@localhost:/sdcard/annex
+ ok
+ whereis Freddie_Mercury/Barcelona_[+video]/B00921KNAK_(disc_3)_05_-_The_Golden_Boy_(Orchestral_Version).mp3 (3 copies)
+ 1f368162-f02f-4794-af0c-1b5489e099b3 -- u0_a84@localhost:/sdcard/annex
+ 53f03d06-f1e3-11e2-8519-1b41c09abecd -- here (Cobol: Phone)
+ cb6240e0-f1df-11e2-836a-7f4323e50c49 -- origin (Markdown: Phone)
+ ok
+
+"""]]
diff --git a/doc/bugs/utf8/comment_2_cd55f6bbeb145fd554f331dcff64f5e1._comment b/doc/bugs/utf8/comment_2_cd55f6bbeb145fd554f331dcff64f5e1._comment
new file mode 100644
index 000000000..ff2a5363d
--- /dev/null
+++ b/doc/bugs/utf8/comment_2_cd55f6bbeb145fd554f331dcff64f5e1._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnRai_qFYPVvEgC6i1nlM1bh-C__jbhqS0"
+ nickname="Matthew"
+ subject="git annex copy --to won't get them across either..."
+ date="2013-07-21T10:12:03Z"
+ content="""
+git annex copy . --to markdown.DOMAIN_phoneannex responds with
+
+ ControlPath \"/data/data/ga.androidterm/tmp/fozz@...somethingthatlookslikeahash\" too long for Unix domain socket
+"""]]
diff --git a/doc/bugs/utf8/comment_3_bb583a419d6fa4e33e5364c4468b35c6._comment b/doc/bugs/utf8/comment_3_bb583a419d6fa4e33e5364c4468b35c6._comment
new file mode 100644
index 000000000..ecdee070c
--- /dev/null
+++ b/doc/bugs/utf8/comment_3_bb583a419d6fa4e33e5364c4468b35c6._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.140"
+ subject="seems to not involve utf8 at all.."
+ date="2013-07-21T18:17:00Z"
+ content="""
+Can you please show me the actual filename, that you obfuscated as \"/data/data/ga.androidterm/tmp/fozz@...somethingthatlookslikeahash\" ?
+"""]]
diff --git a/doc/bugs/utf8/comment_4_cd8a22cfb70d9d21f0a5339ccc52ee93._comment b/doc/bugs/utf8/comment_4_cd8a22cfb70d9d21f0a5339ccc52ee93._comment
new file mode 100644
index 000000000..12bf4c5a6
--- /dev/null
+++ b/doc/bugs/utf8/comment_4_cd8a22cfb70d9d21f0a5339ccc52ee93._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="GLITTAH"
+ ip="37.130.227.133"
+ subject="comment 4"
+ date="2013-07-21T19:36:16Z"
+ content="""
+This sounds like a bug I ran into a while ago that got fixed.
+
+>What version of git-annex are you using? On what operating system?
+>
+>Phone: 4.20130709-g339d1eo Transfer Server: 3.20120406 (which it did not get to) Desktop: 3.20120629
+
+Maybe try upgrading your server and desktop versions? Those look old enough to still have the utf-8 bug.
+"""]]
diff --git a/doc/bugs/utf8/comment_5_14eefd4bee283802e9c462fa20b7835c._comment b/doc/bugs/utf8/comment_5_14eefd4bee283802e9c462fa20b7835c._comment
new file mode 100644
index 000000000..22ec33481
--- /dev/null
+++ b/doc/bugs/utf8/comment_5_14eefd4bee283802e9c462fa20b7835c._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnRai_qFYPVvEgC6i1nlM1bh-C__jbhqS0"
+ nickname="Matthew"
+ subject="Darn it..."
+ date="2013-07-21T20:29:33Z"
+ content="""
+Hi,
+
+Sorry, it was on my phone and very long and I didn't think it'd be important... Sheesh Users eh!
+
+I think the error happened for every file or at least lots, not just the one with the strange tilde above the \"n\".
+Eventually, it might have been after a phone reboot, it sorted itself and continued.
+
+I can try and recreate it if it'll help, though it won't be till Wednesday / Thursday as I'm going away for a few days and I still need to pack.
+
+Sorry for the bad bug report, I know how annoying they are.
+
+It's not so easy for me to upgrade because one's an Ubuntu LTS and one is a Mint Debian Edition, both are the repository versions.
+"""]]
diff --git a/doc/bugs/utf8/comment_6_58d8b5bdb9f11e8c344e86a675a075dd._comment b/doc/bugs/utf8/comment_6_58d8b5bdb9f11e8c344e86a675a075dd._comment
new file mode 100644
index 000000000..bb97d0fa4
--- /dev/null
+++ b/doc/bugs/utf8/comment_6_58d8b5bdb9f11e8c344e86a675a075dd._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmkBwMWvNKZZCge_YqobCSILPMeK6xbFw8"
+ nickname="develop"
+ subject="comment 6"
+ date="2013-07-21T20:31:50Z"
+ content="""
+As much i myself personally would hate it. You really should go with the standalone builds provided on this site then.
+
+Just download the zip, extract on both machines. Make sure the PATH is correct, and it should Just Work(TM)
+
+"""]]
diff --git a/doc/bugs/utf8/comment_7_00fa9672ce55b6bfa885b8a13287ac25._comment b/doc/bugs/utf8/comment_7_00fa9672ce55b6bfa885b8a13287ac25._comment
new file mode 100644
index 000000000..925067989
--- /dev/null
+++ b/doc/bugs/utf8/comment_7_00fa9672ce55b6bfa885b8a13287ac25._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.1.10"
+ subject="comment 7"
+ date="2013-07-22T18:34:55Z"
+ content="""
+The only version of git-annex that matters is the one installed on the Android device. Which is fine.
+
+I reiterate my request for the actual thing that got obfuscated as \"/data/data/ga.androidterm/tmp/fozz@...somethingthatlookslikeahash\". Once I have that peice of information I should be able to fix this bug in short order. I understand exactly what's going on, except I don't know what the actual length of the filename that is causing the problem is.
+"""]]
diff --git a/doc/bugs/utf8/comment_8_a01e26fa0fafbc291020f53dbfdf6443._comment b/doc/bugs/utf8/comment_8_a01e26fa0fafbc291020f53dbfdf6443._comment
new file mode 100644
index 000000000..dfb3570b6
--- /dev/null
+++ b/doc/bugs/utf8/comment_8_a01e26fa0fafbc291020f53dbfdf6443._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnRai_qFYPVvEgC6i1nlM1bh-C__jbhqS0"
+ nickname="Matthew"
+ subject="I will give recreating the bug a go in about 3 days time..."
+ date="2013-07-22T19:26:44Z"
+ content="""
+I will give recreating the bug a go in about 3 days time when I get back off holiday.
+
+Thanks
+"""]]
diff --git a/doc/bugs/utf8/comment_9_b7c084be01ce985be51e48503fcba468._comment b/doc/bugs/utf8/comment_9_b7c084be01ce985be51e48503fcba468._comment
new file mode 100644
index 000000000..f2c42a6bd
--- /dev/null
+++ b/doc/bugs/utf8/comment_9_b7c084be01ce985be51e48503fcba468._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.110"
+ subject="comment 9"
+ date="2013-07-26T21:09:36Z"
+ content="""
+Any luck reproducing this bug and getting the info I need to know exactly what's going on?
+"""]]
diff --git a/doc/bugs/uuid.log_trust.log_and_remote.log_merge_wackiness.mdwn b/doc/bugs/uuid.log_trust.log_and_remote.log_merge_wackiness.mdwn
new file mode 100644
index 000000000..a84d8cb56
--- /dev/null
+++ b/doc/bugs/uuid.log_trust.log_and_remote.log_merge_wackiness.mdwn
@@ -0,0 +1,36 @@
+Since uuid.log, trust.log and remote.log are union merged, it's possible
+for any given item in them to have multiple values after a merge.
+This would happen, for example, if the value was changed in different ways
+in two repos which were then merged. git-annex will use an arbitrary
+one of the multiple values.
+
+A workaround if this should happen to you is to use `git annex describe`
+or other commands to re-set the value you want. The process of setting
+the value will remove the multiple lines.
+
+To fix this the file format needs to be changed to include a timestamp
+as is done with the other log files, then git-annex can consistently
+pick the newest value -- which is as close to the "right" value as can be
+determined in this situation.
+
+----
+
+File format backwards-compatability is the issue. Ideally, old git-annex
+would keep working, ignoring the timestamp.
+
+- uuid.log: "uuid description timestamp" would work; old git-annex
+ would just treat the timestamp as part of the description which would be
+ ok
+ > update: converted! --[[Joey]]
+- trust.log: "uuid trustlevel timestamp" would work; old git-annex
+ ignores trailing words
+ > update: converted! --[[Joey]]
+- remote.log: "uuid key=value ... timestamp" is on the edge but does work
+ (old git-annex will include the timestamp in the key/value map it builds,
+ but that should not break anything really)
+ > update: converted! --[[Joey]]
+
+Appending "timestamp=xxxxx" would be good for clarity, and make
+it easier to parse the timestamp out from lines that have it.
+
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/version_doesn__39__t_show___34__Feeds__34___but_podcasting_feature_working.mdwn b/doc/bugs/version_doesn__39__t_show___34__Feeds__34___but_podcasting_feature_working.mdwn
new file mode 100644
index 000000000..64e83526f
--- /dev/null
+++ b/doc/bugs/version_doesn__39__t_show___34__Feeds__34___but_podcasting_feature_working.mdwn
@@ -0,0 +1,28 @@
+### Please describe the problem.
+on [[tips/downloading_podcasts/]] it says to look for "Feeds" in the output of version to see if you have the importfeeds support. I have importfeeds support but "Feeds" is not listed when doing version.
+
+### What steps will reproduce the problem?
+# git-annex version
+# git-annex importfeed <someurl>
+
+### What version of git-annex are you using? On what operating system?
+4.20130802 on Debian unstable
+
+### Please provide any additional information below.
+
+[[!format sh """
+greg@x200s:~/annextest$ git-annex version
+git-annex version: 4.20130802
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP
+local repository version: 3
+default repository version: 3
+supported repository versions: 3 4
+upgrade supported from repository versions: 0 1 2
+
+greg@x200s:~/annextest$ git-annex importfeed http://feeds.feedburner.com/OpenMetalcast/ogg
+(checking known urls...)
+importfeed http://feeds.feedburner.com/OpenMetalcast/ogg
+....<downloads the episodes etc>
+"""]]
+
+> Forgot I had to manually add that. [[done]] (really this time!) --[[Joey]]
diff --git a/doc/bugs/version_doesn__39__t_show___34__Feeds__34___but_podcasting_feature_working/comment_1_ce06ba4f65f322362b23797f6190c7c3._comment b/doc/bugs/version_doesn__39__t_show___34__Feeds__34___but_podcasting_feature_working/comment_1_ce06ba4f65f322362b23797f6190c7c3._comment
new file mode 100644
index 000000000..8b156f822
--- /dev/null
+++ b/doc/bugs/version_doesn__39__t_show___34__Feeds__34___but_podcasting_feature_working/comment_1_ce06ba4f65f322362b23797f6190c7c3._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="http://a-or-b.myopenid.com/"
+ ip="203.45.2.230"
+ subject="comment 1"
+ date="2013-09-04T01:36:46Z"
+ content="""
+This still is not fixed. :-(
+
+ $ git annex version
+ git-annex version: 4.20130827
+ build flags: Assistant Webapp Pairing Testsuite S3 WebDAV FsEvents XMPP DNS
+
+
+...but the ```importfeed``` functionality works.
+
+I know this isn't a particularly high priority bug...
+"""]]
diff --git a/doc/bugs/view_logs_fails:_Internal_Server_Error__internal_liftAnnex.mdwn b/doc/bugs/view_logs_fails:_Internal_Server_Error__internal_liftAnnex.mdwn
new file mode 100644
index 000000000..0b9c54039
--- /dev/null
+++ b/doc/bugs/view_logs_fails:_Internal_Server_Error__internal_liftAnnex.mdwn
@@ -0,0 +1,20 @@
+### Please describe the problem.
+I tried to setup a fresh local repository and got an error:
+> Internal Server Error
+> user error (git ["--git-dir=/home/jana/Bilder/Fotos/.git","--work-tree=/home/jana/Bilder/Fotos","commit-tree","4b825dc642cb6eb9a060e54bf8d69288fbee4904"] exited 128)
+
+When clicking on "View logs", I get the following error:
+
+> Internal Server Error
+> internal liftAnnex
+
+### What steps will reproduce the problem?
+1. Run git-annex from programs menu
+2. Click "Make repository"
+
+### What version of git-annex are you using? On what operating system?
+- git-annex 4.20130627 on Ubuntu 13.10, installed from debian unstable (sid) repository.
+- git version 1.8.1.2
+
+> I've made it detect systems that lack a FQDN and set user.email
+> automatically. [[done]] --[[Joey]]
diff --git a/doc/bugs/view_logs_fails:_Internal_Server_Error__internal_liftAnnex/comment_1_57547f9a480df2c3f7b3997b0fb7039a._comment b/doc/bugs/view_logs_fails:_Internal_Server_Error__internal_liftAnnex/comment_1_57547f9a480df2c3f7b3997b0fb7039a._comment
new file mode 100644
index 000000000..44807b62f
--- /dev/null
+++ b/doc/bugs/view_logs_fails:_Internal_Server_Error__internal_liftAnnex/comment_1_57547f9a480df2c3f7b3997b0fb7039a._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://cweiske.de/"
+ nickname="cweiske"
+ subject="comment 1"
+ date="2013-07-04T20:20:15Z"
+ content="""
+Running git-annex from the command line shows me:
+
+> fatal: unable to auto-detect email address (got 'jana@sybo.(none)')
+
+Setting user.email and user.name fixed the error.
+"""]]
diff --git a/doc/bugs/view_logs_fails:_Internal_Server_Error__internal_liftAnnex/comment_2_99f12da3ef01141dc7a9105fcf966793._comment b/doc/bugs/view_logs_fails:_Internal_Server_Error__internal_liftAnnex/comment_2_99f12da3ef01141dc7a9105fcf966793._comment
new file mode 100644
index 000000000..61a725060
--- /dev/null
+++ b/doc/bugs/view_logs_fails:_Internal_Server_Error__internal_liftAnnex/comment_2_99f12da3ef01141dc7a9105fcf966793._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.193"
+ subject="comment 2"
+ date="2013-07-05T15:30:37Z"
+ content="""
+Ok, the liftAnnex part of this is just because most of the webapp, including viewing logs, requires a repo to be set up, and it's not gotten past the early setup part where this happens before it, apparently, crashed because of the email misconfiguration problem.
+
+So, I should really detect and deal with this rather annoyingly common misconfiguration of user's computers..
+"""]]
diff --git a/doc/bugs/warning_-_WebApp_crashed:___60__file_descriptor_15__62__:_hPutStr:_illegal_operation___40__handle_is_closed__41___on_Android.mdwn b/doc/bugs/warning_-_WebApp_crashed:___60__file_descriptor_15__62__:_hPutStr:_illegal_operation___40__handle_is_closed__41___on_Android.mdwn
new file mode 100644
index 000000000..afdf6b270
--- /dev/null
+++ b/doc/bugs/warning_-_WebApp_crashed:___60__file_descriptor_15__62__:_hPutStr:_illegal_operation___40__handle_is_closed__41___on_Android.mdwn
@@ -0,0 +1,24 @@
+### Please describe the problem.
+The first time I open the webapp on Android I see the following warning :
+
+`WebApp crashed:<file descriptor 15>: hPutStr: illegal operation(handle_is_closed)`
+
+See screen capture : [http://i.imgur.com/K0wkk2n.png](http://i.imgur.com/K0wkk2n.png)
+
+### What steps will reproduce the problem?
+1. Close git-annex if running
+2. Open the WebApp
+
+### What version of git-annex are you using? On what operating system?
+It says 1.0.52 in the Android settings but I'm using the daily build that I downloaded around 2013-05-29 13:10:00 (Eastern Time)
+
+### Please provide any additional information below.
+
+Git annex still syncs with `box.com` even if the warning is showing.
+
+I'm using a Nexus 4 (4.2.2)
+
+I didn't find `daemon.log`.
+
+> [[done]]; the android app no longer uses `am`, so no longer needs to
+> display a message when `am` fails. --[[Joey]]
diff --git a/doc/bugs/warning_-_WebApp_crashed:___60__file_descriptor_15__62__:_hPutStr:_illegal_operation___40__handle_is_closed__41___on_Android/comment_1_e8866dc15f8fc049229e7451addad1d5._comment b/doc/bugs/warning_-_WebApp_crashed:___60__file_descriptor_15__62__:_hPutStr:_illegal_operation___40__handle_is_closed__41___on_Android/comment_1_e8866dc15f8fc049229e7451addad1d5._comment
new file mode 100644
index 000000000..3aaa01e06
--- /dev/null
+++ b/doc/bugs/warning_-_WebApp_crashed:___60__file_descriptor_15__62__:_hPutStr:_illegal_operation___40__handle_is_closed__41___on_Android/comment_1_e8866dc15f8fc049229e7451addad1d5._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-05-30T15:57:41Z"
+ content="""
+This is an intriguing screenshot, since it shows the webapp reporting a crash of the webapp! I think what's going on is that the web server thread run by the webapp is still running, although the webapp's own thread has crashed.
+
+The log should be in `/sdcard/DCIM/.git/annex/daemon.log`. I would be interested to see it.
+
+Does the webapp continue to update and function despite saying it crashed?
+"""]]
diff --git a/doc/bugs/warning_-_WebApp_crashed:___60__file_descriptor_15__62__:_hPutStr:_illegal_operation___40__handle_is_closed__41___on_Android/comment_2_ee616b0251ffaace9844cfd7af896c35._comment b/doc/bugs/warning_-_WebApp_crashed:___60__file_descriptor_15__62__:_hPutStr:_illegal_operation___40__handle_is_closed__41___on_Android/comment_2_ee616b0251ffaace9844cfd7af896c35._comment
new file mode 100644
index 000000000..b19fbf584
--- /dev/null
+++ b/doc/bugs/warning_-_WebApp_crashed:___60__file_descriptor_15__62__:_hPutStr:_illegal_operation___40__handle_is_closed__41___on_Android/comment_2_ee616b0251ffaace9844cfd7af896c35._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-05-30T16:07:59Z"
+ content="""
+Could you please get me a screenshot of git-annex's terminal window after this has occurred?
+
+The most likely thing seems to be that it's crashing while trying to open the web browser. How did you get the web browser open on the webapp? Using the new menu item to do it, or did it automatically open?
+"""]]
diff --git a/doc/bugs/warning_-_WebApp_crashed:___60__file_descriptor_15__62__:_hPutStr:_illegal_operation___40__handle_is_closed__41___on_Android/comment_3_6b8bd314b647ea3a485f5faf4856f9a9._comment b/doc/bugs/warning_-_WebApp_crashed:___60__file_descriptor_15__62__:_hPutStr:_illegal_operation___40__handle_is_closed__41___on_Android/comment_3_6b8bd314b647ea3a485f5faf4856f9a9._comment
new file mode 100644
index 000000000..88a99684a
--- /dev/null
+++ b/doc/bugs/warning_-_WebApp_crashed:___60__file_descriptor_15__62__:_hPutStr:_illegal_operation___40__handle_is_closed__41___on_Android/comment_3_6b8bd314b647ea3a485f5faf4856f9a9._comment
@@ -0,0 +1,35 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkGCmVc5qIJaQQgG82Hc5zzBdAVdhe2JEM"
+ nickname="Bruno"
+ subject="comment 3"
+ date="2013-05-30T16:30:31Z"
+ content="""
+Here's the screen capture : [http://i.imgur.com/owmuIKa.png](http://i.imgur.com/owmuIKa.png)
+
+I used the menu item to open the WebApp. Nothing appeared in the git-annex's terminal window when I opened the WebApp. The error message is the one that appears when I start Git Annex.
+
+The WebApp seems to be working. It synced a picture I took when the WebApp was already running. See : [http://i.imgur.com/Bcu4iAE.png](http://i.imgur.com/Bcu4iAE.png)
+
+I think I have this bug since the Android version is out. I thought maybe it was normal in the beginning.
+
+Here's the log :
+
+ [2013-05-30 12:15:36 EDT] main: starting assistant version 4.20130529-g6b9b452
+ \"_xmpp-client._tcp.gmail.com\"
+ Just [(5,0,5222,\"xmpp.l.google.com.\"),(20,0,5222,\"alt1.xmpp.l.google.com.\"),(20,0,5222,\"alt3.xmpp.l.google.com.\"),(20,0,5222,\"alt4.xmpp.l.google.com.\"),(20,0,5222,\"alt2.xmpp.l.google.com.\")]
+ (scanning...) [2013-05-30 12:15:37 EDT] Watcher: Performing startup scan
+ WebApp crashed: <file descriptor: 15>: hPutStr: illegal operation (handle is closed)
+ [2013-05-30 12:15:37 EDT] WebApp: warning WebApp crashed: <file descriptor: 15>: hPutStr: illegal operation (handle is closed)
+ (started...) [2013-05-30 12:22:02 EDT] Committer: Adding IMG_20130..22201.jpg
+
+ add Camera/IMG_20130530_122201.jpg (checksum...) [2013-05-30 12:22:02 EDT] Committer: Committing changes to git
+ [2013-05-30 12:22:13 EDT] Committer: Adding IMG_20130..22201.jpg
+ ok
+ (Recording state in git...)
+ (Recording state in git...)
+ add Camera/IMG_20130530_122201.jpg (checksum...) [2013-05-30 12:22:14 EDT] Committer: Committing changes to git
+ (gpg)
+ [...]
+
+ [2013-05-30 12:22:50 EDT] Transferrer: Uploaded IMG_20130..22201.jpg
+"""]]
diff --git a/doc/bugs/warning_-_WebApp_crashed:___60__file_descriptor_15__62__:_hPutStr:_illegal_operation___40__handle_is_closed__41___on_Android/comment_4_7009b6727ba40bc9bd1b1f939e75d093._comment b/doc/bugs/warning_-_WebApp_crashed:___60__file_descriptor_15__62__:_hPutStr:_illegal_operation___40__handle_is_closed__41___on_Android/comment_4_7009b6727ba40bc9bd1b1f939e75d093._comment
new file mode 100644
index 000000000..eba3baedc
--- /dev/null
+++ b/doc/bugs/warning_-_WebApp_crashed:___60__file_descriptor_15__62__:_hPutStr:_illegal_operation___40__handle_is_closed__41___on_Android/comment_4_7009b6727ba40bc9bd1b1f939e75d093._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 4"
+ date="2013-05-30T19:18:50Z"
+ content="""
+Seems it's crashing while trying to print out a message telling you to use the menu to open the webapp. I'm not sure why, but I have updated the android autobuild to try to work around this. If you can test and tell me if that fixes it or not, it'll help me tell what's going on.
+"""]]
diff --git a/doc/bugs/warning_-_WebApp_crashed:___60__file_descriptor_15__62__:_hPutStr:_illegal_operation___40__handle_is_closed__41___on_Android/comment_5_00ddf7ade6cca758afa838be0b9588cb._comment b/doc/bugs/warning_-_WebApp_crashed:___60__file_descriptor_15__62__:_hPutStr:_illegal_operation___40__handle_is_closed__41___on_Android/comment_5_00ddf7ade6cca758afa838be0b9588cb._comment
new file mode 100644
index 000000000..04de2d3de
--- /dev/null
+++ b/doc/bugs/warning_-_WebApp_crashed:___60__file_descriptor_15__62__:_hPutStr:_illegal_operation___40__handle_is_closed__41___on_Android/comment_5_00ddf7ade6cca758afa838be0b9588cb._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkGCmVc5qIJaQQgG82Hc5zzBdAVdhe2JEM"
+ nickname="Bruno"
+ subject="comment 5"
+ date="2013-05-30T19:38:59Z"
+ content="""
+I still have the problem :(
+
+ [2013-05-30 15:36:31 EDT] main: starting assistant version 4.20130530-g2e0f464
+ Already up-to-date.
+ WebApp crashed: <file descriptor: 14>: hPutStr: illegal operation (handle is closed)
+ [2013-05-30 15:36:32 EDT] WebApp: warning WebApp crashed: <file descriptor: 14>: hPutStr: illegal operation (handle is closed)
+
+ (scanning...) [2013-05-30 15:36:32 EDT] Watcher: Performing startup scan
+ Already up-to-date.
+ [2013-05-30 15:36:35 EDT] Committer: Committing changes to git
+
+ (Recording state in git...)
+ (started...) [2013-05-30 15:36:44 EDT] Committer: Committing changes to git
+"""]]
diff --git a/doc/bugs/warning_-_WebApp_crashed:___60__file_descriptor_15__62__:_hPutStr:_illegal_operation___40__handle_is_closed__41___on_Android/comment_6_6137ef0ad01d5600dab6fccbeed9a88b._comment b/doc/bugs/warning_-_WebApp_crashed:___60__file_descriptor_15__62__:_hPutStr:_illegal_operation___40__handle_is_closed__41___on_Android/comment_6_6137ef0ad01d5600dab6fccbeed9a88b._comment
new file mode 100644
index 000000000..79606cb09
--- /dev/null
+++ b/doc/bugs/warning_-_WebApp_crashed:___60__file_descriptor_15__62__:_hPutStr:_illegal_operation___40__handle_is_closed__41___on_Android/comment_6_6137ef0ad01d5600dab6fccbeed9a88b._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 6"
+ date="2013-05-30T19:45:30Z"
+ content="""
+Changed to fd 14 and not 15, so my change to use the dupped stdout did take effect.
+
+Interesting. Either dup() is just failing (silently!), or the `am` command is somehow closing the assistant's fds (not sure if that's possible).
+
+In either case, it's only happening on your device, not on mine.
+
+I suppose this will just need to wait until I sort out better the opening of the webapp on android. The \"crash\" does not seem like it will affect the actual functioning of the webapp.
+"""]]
diff --git a/doc/bugs/warning_-_WebApp_crashed:___60__file_descriptor_15__62__:_hPutStr:_illegal_operation___40__handle_is_closed__41___on_Android/comment_7_4b79d7ea338d9f70eb80b8cc2c5a21e4._comment b/doc/bugs/warning_-_WebApp_crashed:___60__file_descriptor_15__62__:_hPutStr:_illegal_operation___40__handle_is_closed__41___on_Android/comment_7_4b79d7ea338d9f70eb80b8cc2c5a21e4._comment
new file mode 100644
index 000000000..03fe1cf8b
--- /dev/null
+++ b/doc/bugs/warning_-_WebApp_crashed:___60__file_descriptor_15__62__:_hPutStr:_illegal_operation___40__handle_is_closed__41___on_Android/comment_7_4b79d7ea338d9f70eb80b8cc2c5a21e4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 7"
+ date="2013-05-30T19:48:14Z"
+ content="""
+Actually, the dupped stdout is open and working before `am` is run, so `am` must somehow be messing with it. Can't be a dupping problem. Need to stop using this `am` nonsense clearly.
+"""]]
diff --git a/doc/bugs/watch_command_on_OSX_--_hangs_with_a_small_repo.mdwn b/doc/bugs/watch_command_on_OSX_--_hangs_with_a_small_repo.mdwn
new file mode 100644
index 000000000..c598bb4d7
--- /dev/null
+++ b/doc/bugs/watch_command_on_OSX_--_hangs_with_a_small_repo.mdwn
@@ -0,0 +1,41 @@
+I had started a fresh repo to test out the watch command again on OSX and noticed that it's borked, I'm not sure when it was broken.
+
+The snippet of the log message and command is
+
+<pre>
+$ git annex watch --foreground -d -v
+watch . read: git ["--git-dir=/Users/jtang/sandbox/atest/.git","--work-tree=/Users/jtang/sandbox/atest","show-ref","git-annex"]
+read: git ["--git-dir=/Users/jtang/sandbox/atest/.git","--work-tree=/Users/jtang/sandbox/atest","show-ref","--hash","refs/heads/git-annex"]
+read: git ["--git-dir=/Users/jtang/sandbox/atest/.git","--work-tree=/Users/jtang/sandbox/atest","log","refs/heads/git-annex..6702e5361146450800ae5af0b63e97bd9c55d70b","--oneline","-n1"]
+chat: git ["--git-dir=/Users/jtang/sandbox/atest/.git","--work-tree=/Users/jtang/sandbox/atest","cat-file","--batch"]
+(scanning...) call: git ["--git-dir=/Users/jtan
+</pre>
+
+I had run git-annex with a new repo with just doing a git init and git annex init, I just threw in one or two small text files to see if it was working. It just hangs and does nothing. I had also tried it out on one of my bigger repos and it does the same thing it just hangs at _(scanning...)_ There isn't much to go on, I wonder if it's hitting the [[Issue on OSX with some system limits]] or if its just a thread/fork issue on OSX.
+
+It still hangs on the small repo even if I do
+
+ $ sudo sysctl -w kern.maxfilesperproc=400000
+ $ ulimit -n 2000
+
+Also, just in case if you need it still (on a clean OSX 10.7 system)
+
+<pre>
+$ ulimit -a
+core file size (blocks, -c) 0
+data seg size (kbytes, -d) unlimited
+file size (blocks, -f) unlimited
+max locked memory (kbytes, -l) unlimited
+max memory size (kbytes, -m) unlimited
+open files (-n) 256
+pipe size (512 bytes, -p) 1
+stack size (kbytes, -s) 8192
+cpu time (seconds, -t) unlimited
+max user processes (-u) 709
+virtual memory (kbytes, -v) unlimited
+</pre>
+
+Please close or merge this report if it's a duplicate.
+
+> I've fixed this, it works in my (so far limited) tests. [[done]]
+> --[[Joey]]
diff --git a/doc/bugs/watch_command_on_OSX_--_hangs_with_a_small_repo/comment_1_63f04694610839db0c2381005b15da35._comment b/doc/bugs/watch_command_on_OSX_--_hangs_with_a_small_repo/comment_1_63f04694610839db0c2381005b15da35._comment
new file mode 100644
index 000000000..1b9fe9a4a
--- /dev/null
+++ b/doc/bugs/watch_command_on_OSX_--_hangs_with_a_small_repo/comment_1_63f04694610839db0c2381005b15da35._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="98.65.205.24"
+ subject="comment 1"
+ date="2012-07-20T18:17:04Z"
+ content="""
+I see this too, on OSX, and it's another one of the hangs with the threaded runtime I've been battling recently. Removing -threaded from the Makefile or git-annex.cabal (whichever you're using) makes it work.
+
+Seems likely this one is specific to my kqueue code. Indeed, I see it entering the kqueue code and then hanging, when it should be noticing changes. Interestingly, all threads seem to get blocked, too.
+
+AHA! I had the FFI functions marked unsafe. Marking safe seems to fix that. I need to go re-read up on the FFI and when it's safe to mark functions threadsafe.
+
+Thanks as always for the OSX eyes Jimmy!
+"""]]
diff --git a/doc/bugs/watch_command_on_OSX_--_hangs_with_a_small_repo/comment_2_8afe4720e301cf7ccf11ff0a23261936._comment b/doc/bugs/watch_command_on_OSX_--_hangs_with_a_small_repo/comment_2_8afe4720e301cf7ccf11ff0a23261936._comment
new file mode 100644
index 000000000..1c97338f1
--- /dev/null
+++ b/doc/bugs/watch_command_on_OSX_--_hangs_with_a_small_repo/comment_2_8afe4720e301cf7ccf11ff0a23261936._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 2"
+ date="2012-07-20T19:31:11Z"
+ content="""
+Glad that I can help ;) Alas if it weren't for the learning curve of haskell, I'd fix it myself.
+"""]]
diff --git a/doc/bugs/watch_command_on_OSX_10.7.mdwn b/doc/bugs/watch_command_on_OSX_10.7.mdwn
new file mode 100644
index 000000000..1348c1155
--- /dev/null
+++ b/doc/bugs/watch_command_on_OSX_10.7.mdwn
@@ -0,0 +1,37 @@
+Running the tip of the watch branch on OSX in an annex'ed directory.
+
+The watch command detects the changes, does _something_, see the output below.
+
+Output from watch command
+
+<pre>
+(Recording state in git...)
+Added "./KeePass2.18.dmg"
+Added "./KeePassX-0.4.3.dmg"
+add ./KeePass2.18.dmg (checksum...) ok
+add ./KeePassX-0.4.3.dmg (checksum...) ok
+</pre>
+
+State of the annex
+
+<pre>
+laplace:annex jtang$ git status
+# On branch master
+# Untracked files:
+# (use "git add <file>..." to include in what will be committed)
+#
+# KeePass2.18.dmg
+# KeePassX-0.4.3.dmg
+nothing added to commit but untracked files present (use "git add" to track)
+</pre>
+
+It seems to not do a git add and commit after the creation of the symlinks, manually doing this makes it all happy again till more files are added.
+
+note: i had posted a comment in the blog post, but posting the issue here is probably more appropriate.
+
+> Yeah, this is the issue I was struggling with last night.
+> I think it's fixed in 57cf65eb6d811ba7fd19eb62a54e3b83a0c2dfa7,
+> but the kqueue watch still needs a lot of work. --[[Joey]]
+
+>> Confirmed this is fixed, but do note the known kqueue bugs in
+>> [[design/assistant/inotify]]! [[done]] --[[Joey]]
diff --git a/doc/bugs/watcher_commits_unlocked_files.mdwn b/doc/bugs/watcher_commits_unlocked_files.mdwn
new file mode 100644
index 000000000..37e50fca0
--- /dev/null
+++ b/doc/bugs/watcher_commits_unlocked_files.mdwn
@@ -0,0 +1,37 @@
+When having "git annex watch" running, unlocking files causes the watcher
+to immediately lock/commit them.
+
+----
+
+Possible approaches:
+
+* The watcher could detect unlocked files by checking if newly added files
+ are a typechange of a file already in git. But this would add git overhead
+ to every file add.
+* `git annex unlock` could add some type of flag file, which the assistant
+ could check. This would work fine, for users who want to use `git annex
+ unlock` with the assistant. That's probably not simple enough for most
+ users, though.
+* There could be a UI in the assistant to pick a file and unlock it.
+ The assistant would have its own list of files it knows are unlocked.
+ But I'm trying to avoid mandatory UI to use the assistant.
+* Perhaps instead, have a directory, like "edit". The assistant could notice
+ when files move into this special directory, and automatically unlock them.
+ Then when they're moved out, automatically commit them.
+* Alternatively, files that are moved out of the repository entirely could be
+ automatically unlocked, and then when they're moved back in, it would
+ automatically do the right thing. This may be worth implementing in
+ combination with the "edit" directory, as different use cases would work
+ better with one or the other. However, I don't currently get inotify
+ events when files are moved out of the repository (well, I do, but it
+ just says "file moved", with no forwarding address, so I don't know
+ how to find the file to unlock it.
+
+[[!meta title="assistant: watcher_commits_unlocked_files"]]
+
+> [[done]]; I just tested and somehow this no longer happens;
+> the watcher/assistant leaves the unlocked file alone, and then
+> as soon as it's modified re-adds it.
+>
+> Also, of course, there is direct mode, which avoids needing to unlock...
+> --[[Joey]]
diff --git a/doc/bugs/watcher_commits_unlocked_files/comment_1_f70e1912fde0eee59e208307df06b503._comment b/doc/bugs/watcher_commits_unlocked_files/comment_1_f70e1912fde0eee59e208307df06b503._comment
new file mode 100644
index 000000000..a06b8fe82
--- /dev/null
+++ b/doc/bugs/watcher_commits_unlocked_files/comment_1_f70e1912fde0eee59e208307df06b503._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 1"
+ date="2012-06-28T13:39:18Z"
+ content="""
+That is a known problem/bug which is listed at [[design/assistant/inotify]]
+"""]]
diff --git a/doc/bugs/web_app_loops_over_a_non-addable_file.mdwn b/doc/bugs/web_app_loops_over_a_non-addable_file.mdwn
new file mode 100644
index 000000000..a1f490061
--- /dev/null
+++ b/doc/bugs/web_app_loops_over_a_non-addable_file.mdwn
@@ -0,0 +1,56 @@
+### Please describe the problem.
+
+I started the webapp on a pre-existing repo today, and it started adding all sorts of files which I didn't manually add, which is a little bit surprising, but "okay".
+
+The problem is that it would loop over this one file over and over again. Adding it on the commandline yields a proper error, but this doesn't seem to properly propagate to the frontend.
+
+### What steps will reproduce the problem?
+
+Unclear.
+
+### What version of git-annex are you using? On what operating system?
+
+4.20131105-g8efdc1a
+
+### Please provide any additional information below.
+
+Here's the daemon.log:
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+add clips/A31-05-12_21.22.amr (checksum...) [2013-11-06 10:21:10 EST] Committer: Committing changes to git
+[2013-11-06 10:21:11 EST] Committer: Adding A31-05-12_21.22.amr
+(Recording state in git...)
+(Recording state in git...)
+add clips/A31-05-12_21.22.amr (checksum...) [2013-11-06 10:21:11 EST] Committer: Committing changes to git
+[2013-11-06 10:21:12 EST] Committer: Adding A31-05-12_21.22.amr
+(Recording state in git...)
+(Recording state in git...)
+add clips/A31-05-12_21.22.amr (checksum...) [2013-11-06 10:21:12 EST] Committer: Committing changes to git
+[2013-11-06 10:21:13 EST] Committer: Adding A31-05-12_21.22.amr
+(Recording state in git...)
+add clips/A31-05-12_21.22.amr (checksum...) [2013-11-06 10:21:13 EST] Committer: Committing changes to git
+[2013-11-06 10:21:14 EST] Committer: Adding A31-05-12_21.22.amr
+(Recording state in git...)
+(Recording state in git...)
+add clips/A31-05-12_21.22.amr (checksum...) [2013-11-06 10:21:14 EST] Committer: Committing changes to git
+# End of transcript or log.
+"""]]
+
+And here's the attempt on the commandline, which is way more informative:
+
+[[!format sh """
+anarcat@marcos:video$ git annex add .
+add clips/96_257.mp3 ok
+add clips/A31-05-12_21.22.amr (checksum...)
+git-annex: /srv/video/.git/annex/objects/z3/96/SHA256E-s260070--46f0d657cdd79032d431e2aebb04b63685ab26e7d00963036e0b64c9f86998f8.22.amr/SHA256E-s260070--46f0d657cdd79032d431e2aebb04b63685ab26e7d00963036e0b64c9f86998f8.22.amr: setFileMode: permission denied (Operation not permitted)
+failed
+"""]]
+
+Turns out that file is owned by root, so it's an expected failure. But the webapp should simply skip this file, not loop over it.
+
+The workaround is obviously to give this file to the proper user. --[[anarcat]]
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/webapp:_difficult_to_abort_adding_a_repository.mdwn b/doc/bugs/webapp:_difficult_to_abort_adding_a_repository.mdwn
new file mode 100644
index 000000000..41007dbb4
--- /dev/null
+++ b/doc/bugs/webapp:_difficult_to_abort_adding_a_repository.mdwn
@@ -0,0 +1,24 @@
+### Please describe the problem.
+I could not find a way to abort the addition of a new remote repository.
+
+### What steps will reproduce the problem?
+- start adding a remote repository (unencrypted, with git-annex installed);
+- forget to create the folder on the remote host;
+- navigate away from the repository page;
+- the dashboard says the repository is partially set-up, and the only thing one can do is look at the log (which says the folder is missing).
+
+I was able to solve it by creating another repository with the exact same data.
+
+### What version of git-annex are you using? On what operating system?
+
+Version: 4.20131002-gf25991c on OS X 10.8.5
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
diff --git a/doc/bugs/webapp_hang.mdwn b/doc/bugs/webapp_hang.mdwn
new file mode 100644
index 000000000..a1d296893
--- /dev/null
+++ b/doc/bugs/webapp_hang.mdwn
@@ -0,0 +1,144 @@
+Occasionally, clicking on a link in the webapp will hang. When this
+happens, which has only been seen in Chromium so far, the tab will spin
+forever, without anything loading. Other tabs can be opened with
+middle-click on links in the webapp, and work fine. Stopping and reloading
+in the tab tends to hang again, although eventually this will clear the
+hang up.
+
+-------
+
+My best procedure to replicate this, about 25% of the time:
+
+* have 2 large files and a libreoffice spreadsheet
+* start webapp, make repository
+* open file browser using button in webapp
+* move files into repository
+* make media subdir; move media into it
+* open spreadsheet, modify, save
+* click on New Repository button for the hang
+
+Running recordmydesktop at the same time may also help.. Or giving a
+presentation in Australia. :/
+
+-------
+
+Hypotheses:
+
+* Warp's slowloris protection could be triggering. Possibly by the
+ repeated hits to update the alerts? I added a settingsOnException handler
+ that logs all exceptions, and ThreadKilled is happening several times.
+ The only place in Warp that kills threads is due to a timeout installed
+ for that.
+
+ **Verified** Bug filed upstream: <https://github.com/yesodweb/wai/issues/146>
+
+ ** workaround in place **
+
+* Something deep in git-annex, such as the inotidy code, could be
+ preventing a web server thread from running. But then why do other
+ tabs and other web browsers work while it's stuck?
+ It would have to affect only 1 thread.
+
+-------
+
+I captured a clean protocol dump of this happening. It includes only the
+final, hanging http request and subsequent traffic, not the setup.
+
+We can see the web browser send a request. The server ACKs it at the TCP
+level, but never sends any reply. The web browser continues sending TCP
+keep-alive packets, which are acked by the server. This continued as long
+as the browser tab was left open.
+
+Question: Did the browser send a complete & valid request? The last part
+sent is a cookie and "\r\n\r\n".. So it seems complete. Unless warp is
+expecting a request body?
+
+<pre>
+17:22:30.533079 IP localhost.localdomain.53239 > localhost.localdomain.45836: Flags [P.], seq 4237976899:4237977772, ack 2608808926, win 2048, options [nop,nop,TS val 4895706 ecr 4885760], length 873
+ 0x0000: 4500 039d be84 4000 4006 7ad4 7f00 0001 E.....@.@.z.....
+ 0x0010: 7f00 0001 cff7 b30c fc9a 6543 9b7f 43de ..........eC..C.
+ 0x0020: 8018 0800 0192 0000 0101 080a 004a b3da .............J..
+ 0x0030: 004a 8d00 4745 5420 2f63 6f6e 6669 672f .J..GET./config/
+ 0x0040: 7265 706f 7369 746f 7279 3f61 7574 683d repository?auth=
+ 0x0050: 6437 6266 3037 3438 6663 3863 3031 3965 d7bf0748fc8c019e
+ 0x0060: 6230 3966 3530 3631 6164 6663 3861 3563 b09f5061adfc8a5c
+ 0x0070: 3430 3437 3633 6562 3736 6630 6163 3533 404763eb76f0ac53
+ 0x0080: 3663 3362 6230 3066 3835 6663 6361 3233 6c3bb00f85fcca23
+ 0x0090: 6235 3639 3764 3332 3464 3737 3930 3063 b5697d324d77900c
+ 0x00a0: 3739 3532 6430 6165 3235 3166 6331 6337 7952d0ae251fc1c7
+ 0x00b0: 3532 3632 6330 3233 6265 3936 3066 3563 5262c023be960f5c
+ 0x00c0: 3364 6135 6532 6262 6234 3639 3863 3035 3da5e2bbb4698c05
+ 0x00d0: 2048 5454 502f 312e 310d 0a48 6f73 743a .HTTP/1.1..Host:
+ 0x00e0: 2031 3237 2e30 2e30 2e31 3a34 3538 3336 .127.0.0.1:45836
+ 0x00f0: 0d0a 436f 6e6e 6563 7469 6f6e 3a20 6b65 ..Connection:.ke
+ 0x0100: 6570 2d61 6c69 7665 0d0a 4163 6365 7074 ep-alive..Accept
+ 0x0110: 3a20 7465 7874 2f68 746d 6c2c 6170 706c :.text/html,appl
+ 0x0120: 6963 6174 696f 6e2f 7868 746d 6c2b 786d ication/xhtml+xm
+ 0x0130: 6c2c 6170 706c 6963 6174 696f 6e2f 786d l,application/xm
+ 0x0140: 6c3b 713d 302e 392c 2a2f 2a3b 713d 302e l;q=0.9,*/*;q=0.
+ 0x0150: 380d 0a55 7365 722d 4167 656e 743a 204d 8..User-Agent:.M
+ 0x0160: 6f7a 696c 6c61 2f35 2e30 2028 5831 313b ozilla/5.0.(X11;
+ 0x0170: 204c 696e 7578 2069 3638 3629 2041 7070 .Linux.i686).App
+ 0x0180: 6c65 5765 624b 6974 2f35 3337 2e31 3720 leWebKit/537.17.
+ 0x0190: 284b 4854 4d4c 2c20 6c69 6b65 2047 6563 (KHTML,.like.Gec
+ 0x01a0: 6b6f 2920 4368 726f 6d65 2f32 342e 302e ko).Chrome/24.0.
+ 0x01b0: 3133 3132 2e36 3820 5361 6661 7269 2f35 1312.68.Safari/5
+ 0x01c0: 3337 2e31 370d 0a52 6566 6572 6572 3a20 37.17..Referer:.
+ 0x01d0: 6874 7470 3a2f 2f31 3237 2e30 2e30 2e31 http://127.0.0.1
+ 0x01e0: 3a34 3538 3336 2f3f 6175 7468 3d64 3762 :45836/?auth=d7b
+ 0x01f0: 6630 3734 3866 6338 6330 3139 6562 3039 f0748fc8c019eb09
+ 0x0200: 6635 3036 3161 6466 6338 6135 6334 3034 f5061adfc8a5c404
+ 0x0210: 3736 3365 6237 3666 3061 6335 3336 6333 763eb76f0ac536c3
+ 0x0220: 6262 3030 6638 3566 6363 6132 3362 3536 bb00f85fcca23b56
+ 0x0230: 3937 6433 3234 6437 3739 3030 6337 3935 97d324d77900c795
+ 0x0240: 3264 3061 6532 3531 6663 3163 3735 3236 2d0ae251fc1c7526
+ 0x0250: 3263 3032 3362 6539 3630 6635 6333 6461 2c023be960f5c3da
+ 0x0260: 3565 3262 6262 3436 3938 6330 350d 0a41 5e2bbb4698c05..A
+ 0x0270: 6363 6570 742d 456e 636f 6469 6e67 3a20 ccept-Encoding:.
+ 0x0280: 677a 6970 2c64 6566 6c61 7465 2c73 6463 gzip,deflate,sdc
+ 0x0290: 680d 0a41 6363 6570 742d 4c61 6e67 7561 h..Accept-Langua
+ 0x02a0: 6765 3a20 656e 2d55 532c 656e 3b71 3d30 ge:.en-US,en;q=0
+ 0x02b0: 2e38 0d0a 4163 6365 7074 2d43 6861 7273 .8..Accept-Chars
+ 0x02c0: 6574 3a20 4953 4f2d 3838 3539 2d31 2c75 et:.ISO-8859-1,u
+ 0x02d0: 7466 2d38 3b71 3d30 2e37 2c2a 3b71 3d30 tf-8;q=0.7,*;q=0
+ 0x02e0: 2e33 0d0a 436f 6f6b 6965 3a20 5f53 4553 .3..Cookie:._SES
+ 0x02f0: 5349 4f4e 3d45 3363 7455 496c 7341 5451 SION=E3ctUIlsATQ
+ 0x0300: 3631 694c 6d54 6954 7131 6f37 6465 7830 61iLmTiTq1o7dex0
+ 0x0310: 3361 6f57 3049 4b63 7663 467a 5838 4344 3aoW0IKcvcFzX8CD
+ 0x0320: 5432 7666 4b31 6c42 416d 6279 3166 764f T2vfK1lBAmby1fvO
+ 0x0330: 4643 7952 7863 6f5a 6277 5633 6a4b 4971 FCyRxcoZbwV3jKIq
+ 0x0340: 6b35 6958 4674 7557 5261 6b48 6944 6132 k5iXFtuWRakHiDa2
+ 0x0350: 7769 3075 2f53 6430 5a49 7a75 4464 7947 wi0u/Sd0ZIzuDdyG
+ 0x0360: 774f 6a31 7838 3130 356a 772f 5a2b 355a wOj1x8105jw/Z+5Z
+ 0x0370: 6f4b 6f48 396e 6779 6e4b 5366 5839 742f oKoH9ngynKSfX9t/
+ 0x0380: 6862 4b79 435a 6966 7739 4148 3053 6d4b hbKyCZifw9AH0SmK
+ 0x0390: 436e 4c38 5358 513d 3d0d 0a0d 0a CnL8SXQ==....
+17:22:30.571152 IP localhost.localdomain.45836 > localhost.localdomain.53239: Flags [.], ack 873, win 2048, options [nop,nop,TS val 4895716 ecr 4895706], length 0
+ 0x0000: 4500 0034 f15b 4000 4006 4b66 7f00 0001 E..4.[@.@.Kf....
+ 0x0010: 7f00 0001 b30c cff7 9b7f 43de fc9a 68ac ..........C...h.
+ 0x0020: 8010 0800 fe28 0000 0101 080a 004a b3e4 .....(.......J..
+ 0x0030: 004a b3da .J..
+17:22:35.803152 IP localhost.localdomain.53240 > localhost.localdomain.45836: Flags [.], ack 2157632553, win 2048, options [nop,nop,TS val 4897024 ecr 4885760], length 0
+ 0x0000: 4500 0034 3a63 4000 4006 025f 7f00 0001 E..4:c@.@.._....
+ 0x0010: 7f00 0001 cff8 b30c 7533 e963 809a dc29 ........u3.c...)
+ 0x0020: 8010 0800 fe28 0000 0101 080a 004a b900 .....(.......J..
+ 0x0030: 004a 8d00 .J..
+17:22:35.803213 IP localhost.localdomain.45836 > localhost.localdomain.53240: Flags [.], ack 1, win 2048, options [nop,nop,TS val 4897024 ecr 4840696], length 0
+ 0x0000: 4500 0034 10e5 4000 4006 2bdd 7f00 0001 E..4..@.@.+.....
+ 0x0010: 7f00 0001 b30c cff8 809a dc29 7533 e964 ...........)u3.d
+ 0x0020: 8010 0800 fe28 0000 0101 080a 004a b900 .....(.......J..
+ 0x0030: 0049 dcf8 .I..
+17:23:15.611193 IP localhost.localdomain.53239 > localhost.localdomain.45836: Flags [.], ack 1, win 2048, options [nop,nop,TS val 4906976 ecr 4895716], length 0
+ 0x0000: 4500 0034 be85 4000 4006 7e3c 7f00 0001 E..4..@.@.~<....
+ 0x0010: 7f00 0001 cff7 b30c fc9a 68ab 9b7f 43de ..........h...C.
+ 0x0020: 8010 0800 fe28 0000 0101 080a 004a dfe0 .....(.......J..
+ 0x0030: 004a b3e4 .J..
+17:23:15.611290 IP localhost.localdomain.45836 > localhost.localdomain.53239: Flags [.], ack 873, win 2048, options [nop,nop,TS val 4906976 ecr 4895706], length 0
+ 0x0000: 4500 0034 f15c 4000 4006 4b65 7f00 0001 E..4.\@.@.Ke....
+ 0x0010: 7f00 0001 b30c cff7 9b7f 43de fc9a 68ac ..........C...h.
+ 0x0020: 8010 0800 fe28 0000 0101 080a 004a dfe0 .....(.......J..
+ 0x0030: 004a b3da .J..
+</pre>
+
+[[!tag /design/assistant]]
+[[done]]
diff --git a/doc/bugs/webapp_hang/comment_1_08aa908a64d0fe2d50438d01545c3f01._comment b/doc/bugs/webapp_hang/comment_1_08aa908a64d0fe2d50438d01545c3f01._comment
new file mode 100644
index 000000000..66822d759
--- /dev/null
+++ b/doc/bugs/webapp_hang/comment_1_08aa908a64d0fe2d50438d01545c3f01._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://gdr.name/"
+ nickname="gdr.name"
+ subject="Not only Chrome"
+ date="2013-03-09T10:55:57Z"
+ content="""
+It happened to me numerous times with Opera. I was never able to repeat it hence no bug report.
+"""]]
diff --git a/doc/bugs/webapp_hang/comment_2_2a21ac5657128a454f9deb77c4d18057._comment b/doc/bugs/webapp_hang/comment_2_2a21ac5657128a454f9deb77c4d18057._comment
new file mode 100644
index 000000000..ece1aa358
--- /dev/null
+++ b/doc/bugs/webapp_hang/comment_2_2a21ac5657128a454f9deb77c4d18057._comment
@@ -0,0 +1,21 @@
+[[!comment format=mdwn
+ username="http://crosstwine.com/dd/"
+ ip="88.65.128.43"
+ subject="chrome://net-internals/"
+ date="2013-03-09T20:10:54Z"
+ content="""
+Hi Joey,
+
+I see that you have found the cause and a workaround for this particular
+problem, but would like to point out that `chrome://net-internals/` can be
+very useful for diagnosing such issues.
+
+(I once hit the `SOCKET_POOL_STALLED_MAX_SOCKETS_PER_GROUP` problem
+mentioned in
+<https://code.google.com/p/chromium/issues/detail?id=27324>, which can
+cause Chromium to keep spinning while not issuing any new requests to a
+specific web server.)
+
+Cheers,
+Damien Diederen
+"""]]
diff --git a/doc/bugs/webapp_raise_an_internal_server_error_upon_creating_the_initial_repo.mdwn b/doc/bugs/webapp_raise_an_internal_server_error_upon_creating_the_initial_repo.mdwn
new file mode 100644
index 000000000..b7ecdebbf
--- /dev/null
+++ b/doc/bugs/webapp_raise_an_internal_server_error_upon_creating_the_initial_repo.mdwn
@@ -0,0 +1,26 @@
+What steps will reproduce the problem?
+
+Fresh install on a 12.40 xubuntu with
+
+ cabal install git-annex --bindir=$HOME/bin
+
+What is the expected output? What do you see instead?
+
+I launched the git-annex webapp (the assistant) and the system proposed to create a git-annex repository: I choose ~/annex/ and clicked on "Make repositiry" but I got:
+
+ Internal Server Error
+
+ user error (git ["--git-dir=/home/m/annex/.git","--work-tree=/home/m/annex","commit-tree","4b825dc642cb6eb9a060e54bf8d69288fbee4904"] exited 128)
+
+ git-annex version 3.20130102
+
+What version of git-annex are you using? On what operating system?
+
+git-annex version 3.20130102 on Xubuntu 12.04, installed with cabal (got no errors).
+
+Please provide any additional information below.
+
+I do not know if there is any log, or any info about the reason of the failure. Something useful could be that ~/annex/ now contains an empty git repository, so "something" happened despite the error.
+
+> Made assistant detect misconfigured system and set enough environment
+> variables so git will work. [[done]] --[[Joey]]
diff --git a/doc/bugs/webapp_raise_an_internal_server_error_upon_creating_the_initial_repo/comment_1_1bcf0f565eacac851bd21cd428c8e0a5._comment b/doc/bugs/webapp_raise_an_internal_server_error_upon_creating_the_initial_repo/comment_1_1bcf0f565eacac851bd21cd428c8e0a5._comment
new file mode 100644
index 000000000..fbf63a97c
--- /dev/null
+++ b/doc/bugs/webapp_raise_an_internal_server_error_upon_creating_the_initial_repo/comment_1_1bcf0f565eacac851bd21cd428c8e0a5._comment
@@ -0,0 +1,33 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.211"
+ subject="comment 1"
+ date="2013-01-06T17:00:40Z"
+ content="""
+There should be an error message on either the terminal where you started git-annex, or in ~/.xsession-errors if you started it from a GUI menu.
+
+Without the error message, this seems most likely to be another case of git commit failing due to not being able to determine the user's full name. For example, if I delete my full name out of /etc/passwd,
+
+<pre>
+describe . ok
+(Recording state in git...)
+
+*** Please tell me who you are.
+
+Run
+
+ git config --global user.email \"you@example.com\"
+ git config --global user.name \"Your Name\"
+
+to set your account's default identity.
+Omit --global to set the identity only in this repository.
+
+fatal: empty ident joey@gnu.kitenet.net
+ not allowed
+
+git-annex: user error (git [\"--git-dir=/home/joey/tmp/r/.git\",\"--work-tree=/home/joey/tmp/r\",\"commit-tree\",\"5316749be9efffeee538051b576166291c516472\",\"-p\",\"refs/heads/git-annex\"] exited 128)
+failed
+</pre>
+
+I'm perfectly comfortable with command-line git-annex not working if the system is so misconfigured; after all git tells the user one way to fix it. Perhaps though it's worth the assistant holding the user's hand here and detecting this problem.
+"""]]
diff --git a/doc/bugs/webapp_raise_an_internal_server_error_upon_creating_the_initial_repo/comment_2_7dd2483b5b07df8f3b37a34651c05962._comment b/doc/bugs/webapp_raise_an_internal_server_error_upon_creating_the_initial_repo/comment_2_7dd2483b5b07df8f3b37a34651c05962._comment
new file mode 100644
index 000000000..5459af2e6
--- /dev/null
+++ b/doc/bugs/webapp_raise_an_internal_server_error_upon_creating_the_initial_repo/comment_2_7dd2483b5b07df8f3b37a34651c05962._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="m"
+ ip="79.98.40.98"
+ subject="thanks"
+ date="2013-01-11T01:23:25Z"
+ content="""
+exactly, it was an error on the git configuration
+"""]]
diff --git a/doc/bugs/webapp_requires_reload_for_notification_bubbles.mdwn b/doc/bugs/webapp_requires_reload_for_notification_bubbles.mdwn
new file mode 100644
index 000000000..f8ea8ad39
--- /dev/null
+++ b/doc/bugs/webapp_requires_reload_for_notification_bubbles.mdwn
@@ -0,0 +1,41 @@
+What steps will reproduce the problem?
+
+> Open Webapp on Mac OSX Mountain Lion
+
+What is the expected output? What do you see instead?
+
+> I expect notification bubbles and transfer progress bars to show and update on the fly, as well as notifications to disappear when I click the X.
+>
+> Instead, I have to reload the page after clicking an X or to see new bubbles and progress bar updates.
+
+What version of git-annex are you using? On what operating system?
+
+> git-annex version: 3.20130107
+> local repository version: 3
+> default repository version: 3
+> supported repository versions: 3
+> upgrade supported from repository versions: 0 1 2
+>
+> Mac OS X 10.8.2 Build 12C3006
+>
+> Chrome Version 23.0.1271.101
+
+Please provide any additional information below.
+
+Javascript console error log says "Syntax error on localhost:5" which is this line:
+
+ <link rel="stylesheet" href="/static/css/bootstrap.css"><link rel="stylesheet" href="/static/css/bootstrap-responsive.css"><style>body{padding-top:60px;padding-bottom:40px}.sidebar-nav{padding:9px 0}</style><script src="/static/jquery.full.js"></script><script src="/static/js/bootstrap-dropdown.js"></script><script src="/static/js/bootstrap-modal.js"></script><script src="/static/js/bootstrap-collapse.js"></script><script src="/static/longpolling.js"></script><script>function longpoll_"sidebar"() {
+
+> And the bug is the quoting inside the function name.
+>
+> I believe this affects all builds done using shakespeare-js 1.0.0.2.
+> It may be that some browsers manage to run the javascript despite the
+> quoting. Otherwise, I don't know why noone has reported this bug
+> before now.
+>
+> I've fixed this bug in git. Your testing with tomorrow's
+> autobuild would be appreciated. --[[Joey]]
+
+>> There was a second issue as noted. I fixed that last week,
+>> and the fix is in the autobuilds if you'd like to test before
+>> the next release. [[done]] again --[[Joey]]
diff --git a/doc/bugs/webapp_requires_reload_for_notification_bubbles/comment_1_b15480e5dec1ffbebb8cde1ca8d7c9d5._comment b/doc/bugs/webapp_requires_reload_for_notification_bubbles/comment_1_b15480e5dec1ffbebb8cde1ca8d7c9d5._comment
new file mode 100644
index 000000000..4544f1efb
--- /dev/null
+++ b/doc/bugs/webapp_requires_reload_for_notification_bubbles/comment_1_b15480e5dec1ffbebb8cde1ca8d7c9d5._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmRFKwny4rArBaz-36xTcsJYqKIgdDaw5Q"
+ nickname="Andrew"
+ subject="comment 1"
+ date="2013-01-19T06:53:19Z"
+ content="""
+Just got around to testing both the git-annex.app and the latest build from cabal 3.20130114 and still no go. Neither notification bubbles nor progress bars will update without reloading the page. However the errors have changed:
+
+ Uncaught Error: Syntax error, unrecognized expression: #\"sidebar\"
+
+"""]]
diff --git a/doc/bugs/webapp_requires_reload_for_notification_bubbles/comment_2_8dad57a852e1db804aa38f90f3bb398b._comment b/doc/bugs/webapp_requires_reload_for_notification_bubbles/comment_2_8dad57a852e1db804aa38f90f3bb398b._comment
new file mode 100644
index 000000000..de4c4842a
--- /dev/null
+++ b/doc/bugs/webapp_requires_reload_for_notification_bubbles/comment_2_8dad57a852e1db804aa38f90f3bb398b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmRFKwny4rArBaz-36xTcsJYqKIgdDaw5Q"
+ nickname="Andrew"
+ subject="comment 2"
+ date="2013-01-20T02:04:01Z"
+ content="""
+I just built git-annex fresh from the git repo and the new build seems to have fixed it. [[done]] indeed. :)
+"""]]
diff --git a/doc/bugs/webapp_shows___34__Added_x_files__34___a_bit_ugly.mdwn b/doc/bugs/webapp_shows___34__Added_x_files__34___a_bit_ugly.mdwn
new file mode 100644
index 000000000..51e157c19
--- /dev/null
+++ b/doc/bugs/webapp_shows___34__Added_x_files__34___a_bit_ugly.mdwn
@@ -0,0 +1,15 @@
+### Please describe the problem.
+When adding a folder with some 80.000 files, the sidebar with "Added x files" gets updated in batches. After some time, it shows (also see attached screenshot):
+
+> Added 6496 files 5781 files 8633 files 7363 files 6159 files
+
+This is a bit ugly. There could a newline after "files".
+
+### What steps will reproduce the problem?
+Add a folder with many files and subfolders in it.
+
+### What version of git-annex are you using? On what operating system?
+4.20130627
+
+> I have improved the display, now it will just show a single ongoing count,
+> and the most recent 10 or so files added. [[done]] --[[Joey]]
diff --git a/doc/bugs/webapp_usability:_fails_mysteriously_on_newer_repo_layouts.mdwn b/doc/bugs/webapp_usability:_fails_mysteriously_on_newer_repo_layouts.mdwn
new file mode 100644
index 000000000..73908f40b
--- /dev/null
+++ b/doc/bugs/webapp_usability:_fails_mysteriously_on_newer_repo_layouts.mdwn
@@ -0,0 +1,34 @@
+### Please describe the problem.
+
+Starting the webapp on a repository that was hastily created by copying an existing one with an older version yields an undecipherable error.
+
+Rather minor.
+
+### What steps will reproduce the problem?
+
+1. Install git-annex from git
+2. make a repo
+3. copy it over to an external hard drive
+4. connect that drive to a wheezy box running git-annex from backports
+5. add the external hard drive to the webapp as a new repo
+6. boom
+
+I expected git-annex to tell me:
+
+ git-annex: Repository version 5 is not supported. Upgrade git-annex.
+
+Instead, it popped a red box saying a scary "Internal server error". I couldn't read the daemon logs either.
+
+### What version of git-annex are you using? On what operating system?
+
+original version is:
+
+ git-annex version: 5.20131109-gf2cb5b9
+
+the failing version is running the one from wheezy backports.
+
+### Please provide any additional information below.
+
+screenshot coming up.
+
+> [[fixed|done]] --[[Joey]]
diff --git a/doc/bugs/webapp_usability:_put_the_notices_on_the_right.mdwn b/doc/bugs/webapp_usability:_put_the_notices_on_the_right.mdwn
new file mode 100644
index 000000000..54f6c3a4f
--- /dev/null
+++ b/doc/bugs/webapp_usability:_put_the_notices_on_the_right.mdwn
@@ -0,0 +1,18 @@
+### Please describe the problem.
+
+The colored notices on the left of the screen are a little off. When they disappear, it also leaves a huge gap on the left side.
+
+### What steps will reproduce the problem?
+
+Click the `X` on all the messages on the left.
+
+### What version of git-annex are you using? On what operating system?
+
+4.20130815~bpo70+1 on Debian Wheezy, with Chromium Version 29.0.1547.57 Debian 7.1 (217859)
+
+### Please provide any additional information below.
+
+This is admittedly a very mild problem, but from a usability perspective, it would be less confusing to show those on the right. When they were gone, I thought git-annex was broken somewhat... -- [[anarcat]]
+
+> [[done]], although I'm not sure I'm sold on their being on the right
+> being better. --[[Joey]]
diff --git a/doc/bugs/webapp_usability:_put_the_notices_on_the_right/comment_1_ec7a444e09a028b5225bd41fb83442e8._comment b/doc/bugs/webapp_usability:_put_the_notices_on_the_right/comment_1_ec7a444e09a028b5225bd41fb83442e8._comment
new file mode 100644
index 000000000..a494c5326
--- /dev/null
+++ b/doc/bugs/webapp_usability:_put_the_notices_on_the_right/comment_1_ec7a444e09a028b5225bd41fb83442e8._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.255.110"
+ subject="comment 1"
+ date="2013-09-09T04:36:12Z"
+ content="""
+They're on the left hand side because that's where Bootstrap puts its sidebar.
+If someone knows how to make it put its sidebar on the right I'll happily do so.
+"""]]
diff --git a/doc/bugs/weird_local_clone_confuses.mdwn b/doc/bugs/weird_local_clone_confuses.mdwn
new file mode 100644
index 000000000..aa838f167
--- /dev/null
+++ b/doc/bugs/weird_local_clone_confuses.mdwn
@@ -0,0 +1,20 @@
+See
+<http://www.git.code-experiments.com/blog/2011/01/manage-large-files-with-git-annex-by-joey-hess.html>
+
+If a local repo is cloned with "git clone orig/.git new", then git-annex in
+new cannot see origin.
+
+the .git/config has "url=/.../orig/.git". Apparently git is ok with that
+weird construction; probably it treats it as a bare git repo. But git-annex
+just sees a directory w/o a .git subdir, and gives up.
+
+---
+
+Just tested, and the new support for bare repositories didn't solve this.
+(Because config.bare is not set.)
+
+I think this is not something git-annex should go out of its way to
+support. [[done]]
+--[[Joey]]
+
+Later.. Fixed this after all. --[[Joey]]
diff --git a/doc/bugs/whereis_outputs_no_informaiton_for_unlocked_files.mdwn b/doc/bugs/whereis_outputs_no_informaiton_for_unlocked_files.mdwn
new file mode 100644
index 000000000..cb8519952
--- /dev/null
+++ b/doc/bugs/whereis_outputs_no_informaiton_for_unlocked_files.mdwn
@@ -0,0 +1,44 @@
+What steps will reproduce the problem?
+
+ ...:/tmp$ mkdir repro
+ ...:/tmp$ cd repro/
+ ...:/tmp/repro$ git init
+ Initialized empty Git repository in /tmp/repro/.git/
+ ...:/tmp/repro$ git annex init test
+ init test ok
+ ...:/tmp/repro$ echo "A" > a.txt
+ ...:/tmp/repro$ git annex add a.txt
+ add a.txt (checksum...) ok
+ (Recording state in git...)
+ ...:/tmp/repro$ git commit -m "add file"
+ [master (root-commit) bf53ce2] add file
+ 1 file changed, 1 insertion(+)
+ create mode 120000 a.txt
+ ...:/tmp/repro$ git annex whereis a.txt
+ whereis a.txt (1 copy)
+ 5c028c6a-2c5e-11e2-bb9c-17bd7ce81377 -- here (test)
+ ok
+ ...:/tmp/repro$ git annex unlock a.txt
+ unlock a.txt (copying...) ok
+ ...:/tmp/repro$ git annex whereis a.txt
+
+What is the expected output? What do you see instead?
+
+ I'd expect that whereis executed on an unlocked file would behave like whereis executed on a locked file.
+
+What version of git-annex are you using? On what operating system?
+
+ $ cat /etc/issue
+ Ubuntu 12.04.1 LTS \n \l
+
+ $ git-annex version
+ git-annex version: 3.20120406
+ local repository version: 3
+ default repository version: 3
+ supported repository versions: 3
+ upgrade supported from repository versions: 0 1 2
+
+ $ uname -a
+ Linux ... 3.2.0-31-generic #50-Ubuntu SMP Fri Sep 7 16:16:45 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
+
+Please provide any additional information below.
diff --git a/doc/bugs/windows_fails_test___34__recoverEncode__34__.mdwn b/doc/bugs/windows_fails_test___34__recoverEncode__34__.mdwn
new file mode 100644
index 000000000..0413bb55d
--- /dev/null
+++ b/doc/bugs/windows_fails_test___34__recoverEncode__34__.mdwn
@@ -0,0 +1,39 @@
+### Please describe the problem.
+
+My windows install (2013-09-09) fails "quick checks" when running "git annex test". See below the errors from two seperate runs of the test in two fresh empty directories:
+
+*** Failed! Exception: 'recoverEncode: invalid argument (invalid character)' (after 13 tests):
+Key {keyName = "\140\DEL\159/\RS'", keyBackendName = "WQACSWJDVY", keySize = Just 6, keyMtime = Just 3}
+prop_idempotent_configEscape
+
+*** Failed! Exception: 'recoverEncode: invalid argument (invalid character)' (after 4 tests):
+Key {keyName = "\130", keyBackendName = "Y", keySize = Nothing, keyMtime = Nothing}
+prop_idempotent_configEscape
+
+### What steps will reproduce the problem?
+
+create a directory
+cd to it in cmd or Git Bash
+run "git annex test"
+
+
+### What version of git-annex are you using? On what operating system?
+
+OS Name: Microsoft Windows 7 Professional (64bit)
+OS Version: 6.1.7601 Service Pack 1 Build 7601
+
+Install Git-1.8.3-preview20130601 (third option to add git and tools to path)
+Install git-annex-installer (2013-09-09)
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
+
+> I've released a fix for this problem. Thanks for reporting! [[done]]
+> --[[Joey]]
diff --git a/doc/bugs/windows_fails_test___34__recoverEncode__34__/comment_1_424b3536e21e02f192f7f2b8e833ed18._comment b/doc/bugs/windows_fails_test___34__recoverEncode__34__/comment_1_424b3536e21e02f192f7f2b8e833ed18._comment
new file mode 100644
index 000000000..e94608921
--- /dev/null
+++ b/doc/bugs/windows_fails_test___34__recoverEncode__34__/comment_1_424b3536e21e02f192f7f2b8e833ed18._comment
@@ -0,0 +1,67 @@
+[[!comment format=mdwn
+ username="gary"
+ ip="82.112.140.250"
+ subject="Thanks for the fix"
+ date="2013-09-12T07:20:12Z"
+ content="""
+Hi the fix works fine, all the tests pass now. However I am having issues when trying to sync two directories. I have had this working in direct mode in fedora but not in the previously mentioned windows install
+
+2 directories d1 and d2.
+
+SETUP:
+
+cd d1
+
+mkdir annex
+
+cd annex
+
+cp someFile . (as get branch issue if empty)
+
+git init
+
+git annex init d1
+
+cp someFile . (as get branch issue if empty)
+
+git annex add .
+
+git annex sync
+
+cd ..\..\d2
+
+git clone ..\..\d1\annex
+
+cd annex
+
+git annex init d2
+
+git remote add d1 ..\..\d1\annex
+
+cd ..\..\d1\annex
+
+git remote add d2 ..\..\d2\annex
+
+
+SYNCING
+
+cd d1\annex
+
+cp someFiles .
+
+git annex add .
+
+git annex sync
+
+cd ..\..\d2\annex
+
+git annex sync
+
+git annex mirror --from d1
+
+It looks like the files copy across but when I look at them in explorer they are still just the place holders.
+
+any ideas on what may be going on. Does the work flow look correct?
+
+(ps typo on all slashes but
+"""]]
diff --git a/doc/bugs/windows_fails_test___34__recoverEncode__34__/comment_2_78db183aa401e2023d7faec5f7a4a573._comment b/doc/bugs/windows_fails_test___34__recoverEncode__34__/comment_2_78db183aa401e2023d7faec5f7a4a573._comment
new file mode 100644
index 000000000..f186a0d81
--- /dev/null
+++ b/doc/bugs/windows_fails_test___34__recoverEncode__34__/comment_2_78db183aa401e2023d7faec5f7a4a573._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.2.134"
+ subject="comment 2"
+ date="2013-09-13T17:04:26Z"
+ content="""
+That is an unrelated bug. You got very lucky that I saw your followup comment.
+
+I was able to reproduce it, and found bug in git annex fsck that prevented it from finding and fixing this problem on Windows. Am still investigating why the problem occurs in the first place..
+"""]]
diff --git a/doc/bugs/windows_fails_test___34__recoverEncode__34__/comment_3_ed2da19eaf0bd0864f6b28816a79bc23._comment b/doc/bugs/windows_fails_test___34__recoverEncode__34__/comment_3_ed2da19eaf0bd0864f6b28816a79bc23._comment
new file mode 100644
index 000000000..a8f7c0a02
--- /dev/null
+++ b/doc/bugs/windows_fails_test___34__recoverEncode__34__/comment_3_ed2da19eaf0bd0864f6b28816a79bc23._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.2.134"
+ subject="comment 3"
+ date="2013-09-13T17:44:04Z"
+ content="""
+I have now diagnosed and fixed the underlying problem on Windows.
+"""]]
diff --git a/doc/bugs/windows_install_failure.mdwn b/doc/bugs/windows_install_failure.mdwn
new file mode 100644
index 000000000..b67adf10b
--- /dev/null
+++ b/doc/bugs/windows_install_failure.mdwn
@@ -0,0 +1,30 @@
+### Please describe the problem.
+When installing the windows aplha dated 2013-06-21 12:17 it gives an error:
+
+Error opening file for writing:
+c:\program files (x86)\Git\cmd\git-annex.exe
+Abort,retry or ignore?
+
+If you run as administrator it works.
+
+
+
+### What steps will reproduce the problem?
+
+Download the alpha installer and run as normal user.
+
+### What version of git-annex are you using? On what operating system?
+Windows 7 64 bit
+
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
+
+[[!meta title="windows installer fails unless run as admin user"]]
diff --git a/doc/bugs/windows_install_failure/comment_1_f339574c7cfa35c1f0dfd515fde457f5._comment b/doc/bugs/windows_install_failure/comment_1_f339574c7cfa35c1f0dfd515fde457f5._comment
new file mode 100644
index 000000000..a1e10da20
--- /dev/null
+++ b/doc/bugs/windows_install_failure/comment_1_f339574c7cfa35c1f0dfd515fde457f5._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnI6EUnvCSB6JG3KsjCDpBIBWYniaZkhXs"
+ nickname="Jason"
+ subject="expected behavior"
+ date="2013-06-27T02:44:37Z"
+ content="""
+I expect it should automatically ask for privileged escalation rather than fail.
+"""]]
diff --git a/doc/bugs/windows_install_failure/comment_2_1d3364d8f5c4963f3a7e473298ec6ed1._comment b/doc/bugs/windows_install_failure/comment_2_1d3364d8f5c4963f3a7e473298ec6ed1._comment
new file mode 100644
index 000000000..84966d647
--- /dev/null
+++ b/doc/bugs/windows_install_failure/comment_2_1d3364d8f5c4963f3a7e473298ec6ed1._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnrFnHRRNUQBB5RCDaIwhVmCcxQp8_yiYw"
+ nickname="Oliver"
+ subject="comment 2"
+ date="2013-06-28T08:37:39Z"
+ content="""
+Indeed, but the windows installer (whether built by hand or from the prebuilts) does not. Might have a poke at it when I'm back at my machine again - should be a fairly easy fix.
+"""]]
diff --git a/doc/bugs/windows_port_-_can__39__t_directly_access_files.mdwn b/doc/bugs/windows_port_-_can__39__t_directly_access_files.mdwn
new file mode 100644
index 000000000..cb2e650d0
--- /dev/null
+++ b/doc/bugs/windows_port_-_can__39__t_directly_access_files.mdwn
@@ -0,0 +1,250 @@
+### Please describe the problem.
+Using the windows port of git annex, I'm unable to directly access files that are retrieved from a remote ssh repository. Instead, the file contains a reference to ../.git/annex/objects....
+
+**Update** This appears to be a problem with remote bare repositories only. I was able to get from a remote regular git repository without the stand-in symlinks. The stand-in symlink file gets replaced with the real content on "get" using a non-base repository.
+
+### What steps will reproduce the problem?
+
+[[!format sh """
+** on ssh server **
+
+git init --bare annex.git
+cd annex.git
+git annex init origin
+
+** on windows laptop - add content main repository **
+git init annex
+cd annex
+git annex init laptop
+
+git remote add origin ssh://xxxxx/~/annex.git
+echo hello > foo.txt
+git annex add .
+git commit -m "done"
+git annex sync
+git annex copy --to origin
+git annex sync
+git annex whereis foo.txt
+
+** on windows laptop - backup repository **
+
+cd ..
+git init annex.backup
+cd annex.backup
+git annex init "backup"
+git remote add origin ssh://joebo@xxxxx.com/~/annex.git
+git fetch origin
+git merge origin/synced/master
+git annex sync
+git annex get .
+find . | xargs grep hello
+./.git/annex/objects/d91/b11/SHA256E-s6--5891b5b522d5df086d0ff0b110fbd9d21bb4fc7
+163af34d08286a2e846f6be03.txt/SHA256E-s6--5891b5b522d5df086d0ff0b110fbd9d21bb4fc
+7163af34d08286a2e846f6be03.txt:hello
+
+** updating the file from windows laptop **
+cd ..\annex
+echo hello2 > foo.txt
+git annex add .
+git commit -m "updated"
+git annex sync
+git annex copy --to origin
+git annex sync
+
+cd ..\annex.backup
+git fetch origin
+git merge origin/synced/master
+get annex sync
+git annex get .
+find . | xargs grep hello2
+./.git/annex/objects/7ed/895/SHA256E-s9--3f70947299d2926028fd0107c4309e65ca33a9a
+e0175fc4bc57792ca17240d18.txt/SHA256E-s9--3f70947299d2926028fd0107c4309e65ca33a9
+ae0175fc4bc57792ca17240d18.txt:hello2
+"""]]
+
+
+
+### What version of git-annex are you using? On what operating system?
+
+ git-annex version: 4.20130601-gc01f842
+ build flags: Pairing Testsuite S3 WebDAV DNS
+ local repository version: 4
+ default repository version: 3
+ supported repository versions: 3 4
+ upgrade supported from repository versions: 2
+
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+joebo@joebo:~$ sudo rm -rf annex.git
+joebo@joebo:~$ git init --bare annex.git
+Initialized empty Git repository in /home/joebo/annex.git/
+joebo@joebo:~$ cd annex.git
+joebo@joebo:~/annex.git$ git annex init origin
+init origin ok
+
+
+
+C:\Users\joebo>cd annex
+
+C:\Users\joebo\annex>git annex init laptop
+init laptop
+ Detected a crippled filesystem.
+
+ Enabling direct mode.
+
+ Detected a filesystem without fifo support.
+
+ Disabling ssh connection caching.
+ok
+(Recording state in git...)
+
+C:\Users\joebo\annex>
+C:\Users\joebo\annex>git remote add origin ssh://joebo@xxxxx.com/~
+cho hello > foo.txt
+
+C:\Users\joebo\annex>git annex add .
+add foo.txt (checksum...) ok
+(Recording state in git...)
+
+C:\Users\joebo\annex>git commit -m "done"
+[master (root-commit) 7f54efa] done
+ 1 file changed, 1 insertion(+)
+ create mode 120000 foo.txt
+
+C:\Users\joebo\annex>git annex sync
+commit
+ok
+pull origin
+warning: no common commits
+remote: Counting objects: 5, done.
+remote: Compressing objects: 100% (3/3), done.
+remote: Total 5 (delta 1), reused 0 (delta 0)
+Unpacking objects: 100% (5/5), done.
+From ssh://xxxxx.com/~/annex
+ * [new branch] git-annex -> origin/git-annex
+ok
+(merging origin/git-annex into git-annex...)
+(Recording state in git...)
+push origin
+Counting objects: 18, done.
+Delta compression using up to 4 threads.
+Compressing objects: 100% (12/12), done.
+Writing objects: 100% (16/16), 1.48 KiB, done.
+Total 16 (delta 1), reused 0 (delta 0)
+To ssh://joebo@xxxxx.com/~/annex.git
+ * [new branch] git-annex -> synced/git-annex
+ * [new branch] master -> synced/master
+ok
+
+C:\Users\joebo\annex>git annex copy --to origin
+copy foo.txt (checking origin...) (to origin...)
+foo.txt
+ 0 100% 0.00kB/s 0:00:00 (xfer#1, to-check=0/1)
+
+sent 67 bytes received 31 bytes 65.33 bytes/sec
+total size is 0 speedup is 0.00
+ok
+(Recording state in git...)
+
+C:\Users\joebo\annex>git annex sync
+commit
+ok
+pull origin
+ok
+push origin
+Counting objects: 9, done.
+Delta compression using up to 4 threads.
+Compressing objects: 100% (4/4), done.
+Writing objects: 100% (5/5), 446 bytes, done.
+Total 5 (delta 1), reused 0 (delta 0)
+To ssh://joebo@xxxxx.com/~/annex.git
+ ed1a701..c4c9cd0 git-annex -> synced/git-annex
+ok
+
+C:\Users\joebo\annex>git annex whereis foo.txt
+whereis foo.txt (2 copies)
+ 03573d86-d460-11e2-8500-ebab2910b225 -- origin
+ 3b6b60fb-0979-4869-98de-38208182ab92 -- here (laptop)
+ok
+
+
+C:\Users\joebo\annex>cd ..
+
+C:\Users\joebo>git init annex.backup
+Initialized empty Git repository in C:/Users/joebo/annex.backup/.git/
+
+C:\Users\joebo>cd annex.backup
+
+C:\Users\joebo\annex.backup>git annex init "backup"
+init backup
+ Detected a crippled filesystem.
+
+ Enabling direct mode.
+
+ Detected a filesystem without fifo support.
+
+ Disabling ssh connection caching.
+ok
+(Recording state in git...)
+
+C:\Users\joebo\annex.backup>git remote add origin ssh://joebo@xxxxx.com/~/anne
+x.git
+
+C:\Users\joebo\annex.backup>git fetch origin
+warning: no common commits
+remote: Counting objects: 25, done.
+remote: Compressing objects: 100% (19/19), done.
+remote: Total 25 (delta 4), reused 0 (delta 0)
+Unpacking objects: 100% (25/25), done.
+From ssh://xxxxx.com/~/annex
+ * [new branch] git-annex -> origin/git-annex
+ * [new branch] synced/git-annex -> origin/synced/git-annex
+ * [new branch] synced/master -> origin/synced/master
+
+C:\Users\joebo\annex.backup>git merge origin/synced/master
+
+C:\Users\joebo\annex.backup>git annex sync
+(merging origin/git-annex origin/synced/git-annex into git-annex...)
+(Recording state in git...)
+commit
+ok
+pull origin
+ok
+push origin
+Counting objects: 12, done.
+Delta compression using up to 4 threads.
+Compressing objects: 100% (6/6), done.
+Writing objects: 100% (8/8), 818 bytes, done.
+Total 8 (delta 2), reused 0 (delta 0)
+To ssh://joebo@xxxxx.com/~/annex.git
+ c4c9cd0..f403560 git-annex -> synced/git-annex
+ok
+
+C:\Users\joebo\annex.backup>git annex get .
+get foo.txt (from origin...)
+SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.txt
+
+ 0 100% 0.00kB/s 0:00:00 (xfer#1, to-check=0/1)
+
+sent 30 bytes received 145 bytes 116.67 bytes/sec
+total size is 0 speedup is 0.00
+ok
+(Recording state in git...)
+
+C:\Users\joebo\annex.backup>cat foo.txt
+.git/annex/objects/fW/Gk/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649
+b934ca495991b7852b855.txt/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e464
+9b934ca495991b7852b855.txt
+C:\Users\joebo\annex.backup>ls
+foo.txt
+
+
+# End of transcript or log.
+"""]]
+
+> [[done]]; see my comment. --[[Joey]]
diff --git a/doc/bugs/windows_port_-_can__39__t_directly_access_files/comment_1_03ef9d33839173044dcc4f2b37f575d2._comment b/doc/bugs/windows_port_-_can__39__t_directly_access_files/comment_1_03ef9d33839173044dcc4f2b37f575d2._comment
new file mode 100644
index 000000000..ad41694b0
--- /dev/null
+++ b/doc/bugs/windows_port_-_can__39__t_directly_access_files/comment_1_03ef9d33839173044dcc4f2b37f575d2._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmhfodZquCI_EEl-f3h7HkROTszlsQL6yA"
+ nickname="Joe"
+ subject="Closed - not a bug"
+ date="2013-06-14T13:23:24Z"
+ content="""
+It was a user error. I needed to have git-shell in my path. I had added it to the end of .bashrc and it needed to be before the part that returned if not interactive: http://stackoverflow.com/questions/940533/how-do-i-set-path-such-that-ssh-userhost-command-works
+"""]]
diff --git a/doc/bugs/windows_port_-_can__39__t_directly_access_files/comment_2_c65e5491c82908af46fe2c97e048d210._comment b/doc/bugs/windows_port_-_can__39__t_directly_access_files/comment_2_c65e5491c82908af46fe2c97e048d210._comment
new file mode 100644
index 000000000..3368e3a31
--- /dev/null
+++ b/doc/bugs/windows_port_-_can__39__t_directly_access_files/comment_2_c65e5491c82908af46fe2c97e048d210._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-06-14T15:40:04Z"
+ content="""
+Your transcript shows `git annex get` apparently receiving the file. I don't see how that could possibly have worked if git-annex-shell were not in the path on the server, since that is the command it runs to send the file. Also, `git annex copy` is earlier used to send the file to origin, which again should not work if git-annex-shell was not in the path. I think this whole git-annex-shell not in path thing is a red herring.
+
+What actually appears to be going on is this:
+
+1. You create a new empty repository. Since this is Windows, it's forced into direct mode.
+2. You manually merge origin/synced/master into this repository. Bypassing `git annex sync` in this way means that direct mode mappings are not updated for the files contained in that branch.
+3. You run `git annex get` on a file from that branch. The file is retrieved. Since no direct mode mapping exists for the object it just retrieved, it stashes it in .git/annex/objects and the file is left with the fake symlink git uses on windows.
+
+The manual merge in step 2 is the cause of the problem. The [[direct_mode]] documentation advises against using git commands that update the repository tree because it can lead to this kind of problem (as well as more serious data loss).
+
+Of course, you had no choice but to merge from origin/synced/master, because git annex sync didn't push to origin/master, so simply cloning the bare repository wouldn't work. However, I did fix that a few days ago.
+
+I see this as more evidence of there needing to be a [[todo/direct_mode_guard]] to block users from running unsafe git commands in direct mode repositories. This bug probably can be closed, assuming I correctly understand what happened.
+"""]]
diff --git a/doc/bugs/windows_port_-_git_annex_add_hangs_when_adding_17_files_at_once_or_more_.mdwn b/doc/bugs/windows_port_-_git_annex_add_hangs_when_adding_17_files_at_once_or_more_.mdwn
new file mode 100644
index 000000000..50f020b19
--- /dev/null
+++ b/doc/bugs/windows_port_-_git_annex_add_hangs_when_adding_17_files_at_once_or_more_.mdwn
@@ -0,0 +1,197 @@
+### Please describe the problem.
+git annex add hangs on the windows port when adding many files at once. It seems like the magic number is 17. 17 and greater hangs
+
+Running in debug, it hangs on this:
+
+ [2013-06-14 13:59:46 Eastern Daylight Time] feed: git ["--git-dir=C:\\temp\\backup\\q10\\.git","--work-tree=C:\\temp\\backup\\q10","update-index","-z","--index-info"]
+
+
+### What steps will reproduce the problem?
+
+[[!format sh """
+git init t17
+cd t17
+git annex init
+for /l %a in (1,1,17) do @echo %a > %a.txt
+
+git annex add .
+add 1.txt (checksum...) ok
+add 10.txt (checksum...) ok
+add 11.txt (checksum...) ok
+add 12.txt (checksum...) ok
+add 13.txt (checksum...) ok
+add 14.txt (checksum...) ok
+add 15.txt (checksum...) ok
+add 16.txt (checksum...) ok
+add 17.txt (checksum...) ok
+add 2.txt (checksum...) ok
+add 3.txt (checksum...) ok
+add 4.txt (checksum...) ok
+add 5.txt (checksum...) ok
+add 6.txt (checksum...) ok
+add 7.txt (checksum...) ok
+add 8.txt (checksum...) ok
+add 9.txt (checksum...) ok
+(Recording state in git...)
+
+** gets stuck here
+
+"""]]
+
+### What version of git-annex are you using? On what operating system?
+
+ git-annex version: 4.20130601-gc01f842
+ build flags: Pairing Testsuite S3 WebDAV DNS
+ local repository version: 4
+ default repository version: 3
+ supported repository versions: 3 4
+ upgrade supported from repository versions: 2
+
+
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+** 16 works fine
+git init t16
+cd t16
+for /l %a in (1,1,16) do @echo %a > %a.txt
+git annex init
+git annex add .
+
+
+** not 17
+git init t18
+cd t18
+for /l %a in (1,1,17) do @echo %a > %a.txt
+
+C:\temp\backup\t18>git annex init
+init
+ Detected a crippled filesystem.
+
+ Enabling direct mode.
+
+ Detected a filesystem without fifo support.
+
+ Disabling ssh connection caching.
+ok
+(Recording state in git...)
+
+C:\temp\backup\t18>git annex add . --debug
+[2013-06-14 14:05:28 Eastern Daylight Time] read: git ["--git-dir=C:\\temp\\back
+up\\t18\\.git","--work-tree=C:\\temp\\backup\\t18","ls-files","--others","--excl
+ude-standard","-z","--","."]
+[2013-06-14 14:05:28 Eastern Daylight Time] read: git ["--git-dir=C:\\temp\\back
+up\\t18\\.git","--work-tree=C:\\temp\\backup\\t18","ls-files","--modified","-z",
+"--","."]
+[2013-06-14 14:05:28 Eastern Daylight Time] chat: git ["--git-dir=C:\\temp\\back
+up\\t18\\.git","--work-tree=C:\\temp\\backup\\t18","cat-file","--batch"]
+add 1.txt [2013-06-14 14:05:28 Eastern Daylight Time] chat: git ["--git-dir=C:\\
+temp\\backup\\t18\\.git","--work-tree=C:\\temp\\backup\\t18","check-attr","-z","
+--stdin","annex.backend","annex.numcopies","--"]
+(checksum...) [2013-06-14 14:05:28 Eastern Daylight Time] chat: git ["--git-dir=
+C:\\temp\\backup\\t18\\.git","--work-tree=C:\\temp\\backup\\t18","cat-file","--b
+atch"]
+[2013-06-14 14:05:28 Eastern Daylight Time] chat: git ["--git-dir=C:\\temp\\back
+up\\t18\\.git","--work-tree=C:\\temp\\backup\\t18","hash-object","-t","blob","-w
+","--stdin"]
+ok
+add 10.txt (checksum...) [2013-06-14 14:05:28 Eastern Daylight Time] chat: git [
+"--git-dir=C:\\temp\\backup\\t18\\.git","--work-tree=C:\\temp\\backup\\t18","has
+h-object","-t","blob","-w","--stdin"]
+ok
+add 11.txt (checksum...) [2013-06-14 14:05:28 Eastern Daylight Time] chat: git [
+"--git-dir=C:\\temp\\backup\\t18\\.git","--work-tree=C:\\temp\\backup\\t18","has
+h-object","-t","blob","-w","--stdin"]
+ok
+add 12.txt (checksum...) [2013-06-14 14:05:28 Eastern Daylight Time] chat: git [
+"--git-dir=C:\\temp\\backup\\t18\\.git","--work-tree=C:\\temp\\backup\\t18","has
+h-object","-t","blob","-w","--stdin"]
+ok
+add 13.txt (checksum...) [2013-06-14 14:05:28 Eastern Daylight Time] chat: git [
+"--git-dir=C:\\temp\\backup\\t18\\.git","--work-tree=C:\\temp\\backup\\t18","has
+h-object","-t","blob","-w","--stdin"]
+ok
+add 14.txt (checksum...) [2013-06-14 14:05:28 Eastern Daylight Time] chat: git [
+"--git-dir=C:\\temp\\backup\\t18\\.git","--work-tree=C:\\temp\\backup\\t18","has
+h-object","-t","blob","-w","--stdin"]
+ok
+add 15.txt (checksum...) [2013-06-14 14:05:28 Eastern Daylight Time] chat: git [
+"--git-dir=C:\\temp\\backup\\t18\\.git","--work-tree=C:\\temp\\backup\\t18","has
+h-object","-t","blob","-w","--stdin"]
+ok
+add 16.txt (checksum...) [2013-06-14 14:05:28 Eastern Daylight Time] chat: git [
+"--git-dir=C:\\temp\\backup\\t18\\.git","--work-tree=C:\\temp\\backup\\t18","has
+h-object","-t","blob","-w","--stdin"]
+ok
+add 17.txt (checksum...) [2013-06-14 14:05:29 Eastern Daylight Time] chat: git [
+"--git-dir=C:\\temp\\backup\\t18\\.git","--work-tree=C:\\temp\\backup\\t18","has
+h-object","-t","blob","-w","--stdin"]
+ok
+add 2.txt (checksum...) [2013-06-14 14:05:29 Eastern Daylight Time] chat: git ["
+--git-dir=C:\\temp\\backup\\t18\\.git","--work-tree=C:\\temp\\backup\\t18","hash
+-object","-t","blob","-w","--stdin"]
+ok
+add 3.txt (checksum...) [2013-06-14 14:05:29 Eastern Daylight Time] chat: git ["
+--git-dir=C:\\temp\\backup\\t18\\.git","--work-tree=C:\\temp\\backup\\t18","hash
+-object","-t","blob","-w","--stdin"]
+ok
+add 4.txt (checksum...) [2013-06-14 14:05:29 Eastern Daylight Time] chat: git ["
+--git-dir=C:\\temp\\backup\\t18\\.git","--work-tree=C:\\temp\\backup\\t18","hash
+-object","-t","blob","-w","--stdin"]
+ok
+add 5.txt (checksum...) [2013-06-14 14:05:29 Eastern Daylight Time] chat: git ["
+--git-dir=C:\\temp\\backup\\t18\\.git","--work-tree=C:\\temp\\backup\\t18","hash
+-object","-t","blob","-w","--stdin"]
+ok
+add 6.txt (checksum...) [2013-06-14 14:05:29 Eastern Daylight Time] chat: git ["
+--git-dir=C:\\temp\\backup\\t18\\.git","--work-tree=C:\\temp\\backup\\t18","hash
+-object","-t","blob","-w","--stdin"]
+ok
+add 7.txt (checksum...) [2013-06-14 14:05:29 Eastern Daylight Time] chat: git ["
+--git-dir=C:\\temp\\backup\\t18\\.git","--work-tree=C:\\temp\\backup\\t18","hash
+-object","-t","blob","-w","--stdin"]
+ok
+add 8.txt (checksum...) [2013-06-14 14:05:29 Eastern Daylight Time] chat: git ["
+--git-dir=C:\\temp\\backup\\t18\\.git","--work-tree=C:\\temp\\backup\\t18","hash
+-object","-t","blob","-w","--stdin"]
+ok
+add 9.txt (checksum...) [2013-06-14 14:05:29 Eastern Daylight Time] chat: git ["
+--git-dir=C:\\temp\\backup\\t18\\.git","--work-tree=C:\\temp\\backup\\t18","hash
+-object","-t","blob","-w","--stdin"]
+ok
+(Recording state in git...)
+[2013-06-14 14:05:29 Eastern Daylight Time] feed: git ["--git-dir=C:\\temp\\back
+up\\t18\\.git","--work-tree=C:\\temp\\backup\\t18","update-index","-z","--index-
+info"]
+[2013-06-14 14:05:29 Eastern Daylight Time] chat: git ["--git-dir=C:\\temp\\back
+up\\t18\\.git","--work-tree=C:\\temp\\backup\\t18","hash-object","-w","--stdin-p
+aths"]
+[2013-06-14 14:05:29 Eastern Daylight Time] feed: git ["--git-dir=C:\\temp\\back
+up\\t18\\.git","--work-tree=C:\\temp\\backup\\t18","update-index","-z","--index-
+info"]
+
+
+**gets stuck here and never finishes**
+
+
+# End of transcript or log.
+"""]]
+
+> Reproduced this, and git update-index was in fact not hanging.
+> Instead, after that was done, it tried to stop the git hash-object
+> process, and this hung.
+>
+> It seems that the use of runInteractiveProcess is at fault somehow,
+> and I guess it must be due to it opening a pipe for stderr, which
+> I don't need or want. Perhaps I need to ensure I read from that pipe,
+> or windows keeps the process from terminating. (Unix would just toss the piped
+> data away.)
+>
+> That was the only place runInteractiveProcess was used, so I replaced
+> it with an alternative that lets stderr be inherited. With this change,
+> I have successfully added 1000 files to the annex in one go, with no
+> hang. Provisionally [[done]]. --[[Joey]]
diff --git a/doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_.mdwn b/doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_.mdwn
new file mode 100644
index 000000000..76c05aa72
--- /dev/null
+++ b/doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_.mdwn
@@ -0,0 +1,559 @@
+### Please describe the problem.
+
+Using a centralized remote repository, new files that are added to the repository after it's pulled cannot be directly accessed - instead are pulled as symlinks.
+
+The workaround is to create a new remote repository that clones from the source. That repo can pull all files correctly
+
+### What steps will reproduce the problem?
+
+The following script works fine when everything is run on a linux box. If the same script is run on the windows box, it will not show foo2.txt in the repository clone. foo.txt is still valid.
+
+a file, testrepo.sh is set up on the server to simplify the creation of the repo for testing
+
+**testrepo.sh**
+[[!format sh """
+
+rm -rf repo.git
+git init --bare repo.git
+cd repo.git
+git annex init origin
+git annex sync
+
+
+"""]]
+
+**test script**
+[[!format sh """
+
+ssh joebo@xxxxx sh testrepo.sh
+
+
+rm -rf repo
+git init repo
+cd repo
+
+git annex init
+git remote add origin ssh://joebo@xxxxx/~/repo.git
+echo hello > foo.txt
+git annex add .
+git commit -m "initial commit"
+git annex sync
+git annex copy --to origin
+git annex sync
+
+cd ..
+rm -rf repo-bak
+git init repo-bak
+cd repo-bak
+git remote add origin ssh://joebo@xxxxx/~/repo.git
+git fetch origin
+git merge origin/synced/master
+git annex sync
+git annex get .
+cat foo.txt #works just fine!
+
+cd ..
+cd repo
+echo foo2 > foo2.txt
+git annex add .
+git commit -m "another"
+git annex sync
+git annex copy --to origin
+git annex sync
+
+cd ..
+cd repo-bak
+git annex sync
+
+## throws a fastforward error:
+commit
+ok
+pull origin
+remote: Counting objects: 21, done.
+remote: Compressing objects: 100% (14/14), done.
+remote: Total 16 (delta 3), reused 0 (delta 0)
+Unpacking objects: 100% (16/16), done.
+From ssh://xxxx.com/~/repo
+ c5ed8e1..7ea5586 synced/git-annex -> origin/synced/git-annex
+ a8402ae..1a72b3d synced/master -> origin/synced/master
+ok
+(merging origin/synced/git-annex into git-annex...)
+(Recording state in git...)
+push origin
+Counting objects: 15, done.
+Delta compression using up to 4 threads.
+Compressing objects: 100% (7/7), done.
+Writing objects: 100% (8/8), 844 bytes, done.
+Total 8 (delta 2), reused 0 (delta 0)
+To ssh://joebo@xxxx.com/~/repo.git
+ 7ea5586..5df3c85 git-annex -> synced/git-annex
+ ! [rejected] master -> synced/master (non-fast-forward)
+error: failed to push some refs to 'ssh://joebo@xxx.com/~/repo.git'
+hint: Updates were rejected because a pushed branch tip is behind its remote
+hint: counterpart. Check out this branch and merge the remote changes
+hint: (e.g. 'git pull') before pushing again.
+hint: See the 'Note about fast-forwards' in 'git push --help' for details.
+failed
+git-annex: sync: 1 failed
+"""]]
+
+If I try to work around it by merging, then I get the symlink in the file after getting
+
+
+[[!format sh """
+
+C:\joe\backup\repo-bak>git merge origin/synced/master
+Updating f586b6a..fcae7bc
+Fast-forward
+ foo2.txt | 1 +
+ 1 file changed, 1 insertion(+)
+ create mode 120000 foo2.txt
+
+C:\joe\backup\repo-bak>git annex get foo2.txt
+get foo2.txt (from origin...)
+SHA256E-s7--eef0e29200a3194851e5fb4ff77d0d0aec5cd3f5ccd78762e80a45f0bbece05f.txt
+
+ 7 100% 6.84kB/s 0:00:00 (xfer#1, to-check=0/1)
+
+sent 30 bytes received 156 bytes 124.00 bytes/sec
+total size is 7 speedup is 0.04
+ok
+warning: LF will be replaced by CRLF in C:\joe\backup\repo-bak\.git\annex\journa
+l\fba_8bb_SHA256E-s7--eef0e29200a3194851e5fb4ff77d0d0aec5cd3f5ccd78762e80a45f0bb
+ece05f.txt.log.
+The file will have its original line endings in your working directory.
+(Recording state in git...)
+
+C:\joe\backup\repo-bak>cat foo2.txt
+.git/annex/objects/3V/kM/SHA256E-s7--eef0e29200a3194851e5fb4ff77d0d0aec5cd3f5ccd
+78762e80a45f0bbece05f.txt/SHA256E-s7--eef0e29200a3194851e5fb4ff77d0d0aec5cd3f5cc
+d78762e80a45f0bbece05f.txt
+
+"""]]
+
+removing the backup repository and starting over works:
+
+[[!format sh """
+
+C:\joe\backup>git init repo-bak
+Initialized empty Git repository in C:/joe/backup/repo-bak/.git/
+
+C:\joe\backup>cd repo-bak
+
+C:\joe\backup\repo-bak>git remote add origin ssh://joebo@xxxx.com/~/repo.git
+
+C:\joe\backup\repo-bak>git fetch origin
+remote: Counting objects: 57, done.
+remote: Compressing objects: 100% (48/48), done.
+remote: Total 57 (delta 20), reused 0 (delta 0)
+Unpacking objects: 100% (57/57), done.
+From ssh://xxxx.com/~/repo
+ * [new branch] git-annex -> origin/git-annex
+ * [new branch] synced/git-annex -> origin/synced/git-annex
+ * [new branch] synced/master -> origin/synced/master
+
+C:\joe\backup\repo-bak>git merge origin/synced/master
+
+C:\joe\backup\repo-bak>git annex sync
+
+ Detected a crippled filesystem.
+
+ Enabling direct mode.
+
+ Detected a filesystem without fifo support.
+
+ Disabling ssh connection caching.
+warning: LF will be replaced by CRLF in C:\joe\backup\repo-bak\.git\annex\journa
+l\uuid.log.
+The file will have its original line endings in your working directory.
+(merging origin/git-annex origin/synced/git-annex into git-annex...)
+(Recording state in git...)
+commit
+ok
+pull origin
+ok
+push origin
+Counting objects: 9, done.
+Delta compression using up to 4 threads.
+Compressing objects: 100% (4/4), done.
+Writing objects: 100% (5/5), 533 bytes, done.
+Total 5 (delta 3), reused 0 (delta 0)
+To ssh://joebo@xxxx.com/~/repo.git
+ 5038806..67d6383 git-annex -> synced/git-annex
+ok
+
+C:\joe\backup\repo-bak>git annex get .
+get foo.txt (from origin...)
+SHA256E-s8--f873eef4f852e335da367d76ce7f1973c15b8ffebf532b064df4bc691cd51a87.txt
+
+ 8 100% 7.81kB/s 0:00:00 (xfer#1, to-check=0/1)
+
+sent 30 bytes received 157 bytes 124.67 bytes/sec
+total size is 8 speedup is 0.04
+ok
+get foo2.txt (from origin...)
+SHA256E-s7--eef0e29200a3194851e5fb4ff77d0d0aec5cd3f5ccd78762e80a45f0bbece05f.txt
+
+ 7 100% 6.84kB/s 0:00:00 (xfer#1, to-check=0/1)
+
+sent 30 bytes received 156 bytes 124.00 bytes/sec
+total size is 7 speedup is 0.04
+ok
+warning: LF will be replaced by CRLF in C:\joe\backup\repo-bak\.git\annex\journa
+l\fba_8bb_SHA256E-s7--eef0e29200a3194851e5fb4ff77d0d0aec5cd3f5ccd78762e80a45f0bb
+ece05f.txt.log.
+The file will have its original line endings in your working directory.
+warning: LF will be replaced by CRLF in C:\joe\backup\repo-bak\.git\annex\journa
+l\ae4_1e9_SHA256E-s8--f873eef4f852e335da367d76ce7f1973c15b8ffebf532b064df4bc691c
+d51a87.txt.log.
+The file will have its original line endings in your working directory.
+(Recording state in git...)
+
+C:\joe\backup\repo-bak>cat *
+hello
+foo2
+
+C:\joe\backup\repo-bak>ls -lah
+total 5.0k
+drwxr-xr-x 1 jbogner Administ 0 Jun 15 08:44 .
+drwxr-xr-x 23 jbogner Administ 4.0k Jun 15 08:43 ..
+drwxr-xr-x 1 jbogner Administ 4.0k Jun 15 08:44 .git
+-rw-r--r-- 1 jbogner Administ 8 Jun 15 08:44 foo.txt
+-rw-r--r-- 1 jbogner Administ 7 Jun 15 08:44 foo2.txt
+
+C:\joe\backup\repo-bak>
+
+"""]]
+
+### What version of git-annex are you using? On what operating system?
+
+Windows:
+
+ C:\joe\backup\repo-bak>git annex version
+ git-annex version: 4.20130614-g3a93e24
+ build flags: Pairing Testsuite S3 WebDAV DNS
+ local repository version: 4
+ default repository version: 3
+ supported repository versions: 3 4
+ upgrade supported from repository versions: 2
+
+
+Linux:
+
+ git-annex version: 4.20130531-g5df09b5
+ build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP
+
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+C:\joe\backup>cd repo
+
+C:\joe\backup\repo>git annex init
+init
+ Detected a crippled filesystem.
+
+ Enabling direct mode.
+
+ Detected a filesystem without fifo support.
+
+ Disabling ssh connection caching.
+ok
+warning: LF will be replaced by CRLF in C:\joe\backup\repo\.git\annex\journal\uu
+id.log.
+The file will have its original line endings in your working directory.
+(Recording state in git...)
+
+C:\joe\backup\repo>git remote add origin ssh://joebo@xxxx.com/~/repo.git
+
+C:\joe\backup\repo>echo hello 1>foo.txt
+
+C:\joe\backup\repo>git annex add .
+add foo.txt (checksum...) ok
+(Recording state in git...)
+warning: LF will be replaced by CRLF in C:\joe\backup\repo\.git\annex\journal\ae
+4_1e9_SHA256E-s8--f873eef4f852e335da367d76ce7f1973c15b8ffebf532b064df4bc691cd51a
+87.txt.log.
+The file will have its original line endings in your working directory.
+
+C:\joe\backup\repo>git commit -m "initial commit"
+[master (root-commit) 47c05ea] initial commit
+ 1 file changed, 1 insertion(+)
+ create mode 120000 foo.txt
+
+C:\joe\backup\repo>git annex sync
+commit
+ok
+pull origin
+warning: no common commits
+remote: Counting objects: 5, done.
+remote: Compressing objects: 100% (3/3), done.
+remote: Total 5 (delta 1), reused 0 (delta 0)
+Unpacking objects: 100% (5/5), done.
+From ssh://xxxx.com/~/repo
+ * [new branch] git-annex -> origin/git-annex
+ok
+(merging origin/git-annex into git-annex...)
+(Recording state in git...)
+push origin
+Counting objects: 18, done.
+Delta compression using up to 4 threads.
+Compressing objects: 100% (12/12), done.
+Writing objects: 100% (16/16), 1.40 KiB, done.
+Total 16 (delta 3), reused 0 (delta 0)
+To ssh://joebo@xxxx.com/~/repo.git
+ * [new branch] git-annex -> synced/git-annex
+ * [new branch] master -> synced/master
+ok
+
+C:\joe\backup\repo>git annex copy --to origin
+copy foo.txt (checking origin...) (to origin...)
+foo.txt
+ 8 100% 0.00kB/s 0:00:00 (xfer#1, to-check=0/1)
+
+sent 79 bytes received 31 bytes 73.33 bytes/sec
+total size is 8 speedup is 0.07
+ok
+warning: LF will be replaced by CRLF in C:\joe\backup\repo\.git\annex\journal\ae
+4_1e9_SHA256E-s8--f873eef4f852e335da367d76ce7f1973c15b8ffebf532b064df4bc691cd51a
+87.txt.log.
+The file will have its original line endings in your working directory.
+(Recording state in git...)
+
+C:\joe\backup\repo>git annex sync
+commit
+ok
+pull origin
+ok
+push origin
+Counting objects: 9, done.
+Delta compression using up to 4 threads.
+Compressing objects: 100% (4/4), done.
+Writing objects: 100% (5/5), 450 bytes, done.
+Total 5 (delta 1), reused 0 (delta 0)
+To ssh://joebo@xxxx.com/~/repo.git
+ bd52e5f..02a0a4a git-annex -> synced/git-annex
+ok
+
+C:\joe\backup\repo>cd ..
+
+C:\joe\backup>rm -rf repo-bak
+
+C:\joe\backup>git init repo-bak
+Initialized empty Git repository in C:/joe/backup/repo-bak/.git/
+
+C:\joe\backup>cd repo-bak
+
+C:\joe\backup\repo-bak>git remote add origin ssh://joebo@xxxx.com/~/repo.git
+
+C:\joe\backup\repo-bak>git fetch origin
+remote: Counting objects: 25, done.
+remote: Compressing objects: 100% (19/19), done.
+remote: Total 25 (delta 6), reused 0 (delta 0)
+Unpacking objects: 100% (25/25), done.
+From ssh://xxxx.com/~/repo
+ * [new branch] git-annex -> origin/git-annex
+ * [new branch] synced/git-annex -> origin/synced/git-annex
+ * [new branch] synced/master -> origin/synced/master
+
+C:\joe\backup\repo-bak>git merge origin/synced/master
+
+C:\joe\backup\repo-bak>git annex sync
+
+ Detected a crippled filesystem.
+
+ Enabling direct mode.
+
+ Detected a filesystem without fifo support.
+
+ Disabling ssh connection caching.
+warning: LF will be replaced by CRLF in C:\joe\backup\repo-bak\.git\annex\journa
+l\uuid.log.
+The file will have its original line endings in your working directory.
+(merging origin/git-annex origin/synced/git-annex into git-annex...)
+(Recording state in git...)
+commit
+ok
+pull origin
+ok
+push origin
+Counting objects: 9, done.
+Delta compression using up to 4 threads.
+Compressing objects: 100% (4/4), done.
+Writing objects: 100% (5/5), 610 bytes, done.
+Total 5 (delta 1), reused 0 (delta 0)
+To ssh://joebo@xxxx.com/~/repo.git
+ 02a0a4a..88d19ce git-annex -> synced/git-annex
+ok
+
+C:\joe\backup\repo-bak>git annex get .
+get foo.txt (from origin...)
+SHA256E-s8--f873eef4f852e335da367d76ce7f1973c15b8ffebf532b064df4bc691cd51a87.txt
+
+ 8 100% 7.81kB/s 0:00:00 (xfer#1, to-check=0/1)
+
+sent 30 bytes received 157 bytes 124.67 bytes/sec
+total size is 8 speedup is 0.04
+ok
+warning: LF will be replaced by CRLF in C:\joe\backup\repo-bak\.git\annex\journa
+l\ae4_1e9_SHA256E-s8--f873eef4f852e335da367d76ce7f1973c15b8ffebf532b064df4bc691c
+d51a87.txt.log.
+The file will have its original line endings in your working directory.
+(Recording state in git...)
+
+C:\joe\backup\repo-bak>cat foo.txt
+hello
+
+C:\joe\backup\repo-bak>cd ..
+
+C:\joe\backup>cd repo
+
+C:\joe\backup\repo>echo foo2 1>foo2.txt
+
+C:\joe\backup\repo>git annex add .
+add foo2.txt (checksum...) ok
+(Recording state in git...)
+warning: LF will be replaced by CRLF in C:\joe\backup\repo\.git\annex\journal\fb
+a_8bb_SHA256E-s7--eef0e29200a3194851e5fb4ff77d0d0aec5cd3f5ccd78762e80a45f0bbece0
+5f.txt.log.
+The file will have its original line endings in your working directory.
+
+C:\joe\backup\repo>git commit -m "another"
+[master 76a9e44] another
+ 1 file changed, 1 insertion(+)
+ create mode 120000 foo2.txt
+
+C:\joe\backup\repo>git annex sync
+commit
+ok
+pull origin
+remote: Counting objects: 9, done.
+remote: Compressing objects: 100% (4/4), done.
+remote: Total 5 (delta 1), reused 0 (delta 0)
+Unpacking objects: 100% (5/5), done.
+From ssh://xxxx.com/~/repo
+ 02a0a4a..88d19ce synced/git-annex -> origin/synced/git-annex
+ok
+(merging origin/synced/git-annex into git-annex...)
+(Recording state in git...)
+push origin
+Counting objects: 16, done.
+Delta compression using up to 4 threads.
+Compressing objects: 100% (10/10), done.
+Writing objects: 100% (11/11), 1.11 KiB, done.
+Total 11 (delta 2), reused 0 (delta 0)
+To ssh://joebo@xxxx.com/~/repo.git
+ 88d19ce..f47091a git-annex -> synced/git-annex
+ 47c05ea..76a9e44 master -> synced/master
+ok
+
+C:\joe\backup\repo>git annex copy --to origin
+copy foo.txt (checking origin...) ok
+copy foo2.txt (checking origin...) (to origin...)
+foo2.txt
+ 7 100% 0.00kB/s 0:00:00 (xfer#1, to-check=0/1)
+
+sent 79 bytes received 31 bytes 73.33 bytes/sec
+total size is 7 speedup is 0.06
+ok
+warning: LF will be replaced by CRLF in C:\joe\backup\repo\.git\annex\journal\fb
+a_8bb_SHA256E-s7--eef0e29200a3194851e5fb4ff77d0d0aec5cd3f5ccd78762e80a45f0bbece0
+5f.txt.log.
+The file will have its original line endings in your working directory.
+(Recording state in git...)
+
+C:\joe\backup\repo>git annex sync
+commit
+ok
+pull origin
+ok
+push origin
+Counting objects: 9, done.
+Delta compression using up to 4 threads.
+Compressing objects: 100% (4/4), done.
+Writing objects: 100% (5/5), 477 bytes, done.
+Total 5 (delta 1), reused 0 (delta 0)
+To ssh://joebo@xxxx.com/~/repo.git
+ f47091a..98082cb git-annex -> synced/git-annex
+ok
+
+C:\joe\backup\repo>cd ..
+
+C:\joe\backup>cd repo-bak
+
+C:\joe\backup\repo-bak>git annex sync
+commit
+ok
+pull origin
+remote: Counting objects: 21, done.
+remote: Compressing objects: 100% (14/14), done.
+remote: Total 16 (delta 4), reused 0 (delta 0)
+Unpacking objects: 100% (16/16), done.
+From ssh://xxxx.com/~/repo
+ 88d19ce..98082cb synced/git-annex -> origin/synced/git-annex
+ 47c05ea..76a9e44 synced/master -> origin/synced/master
+ok
+(merging origin/synced/git-annex into git-annex...)
+(Recording state in git...)
+push origin
+Counting objects: 15, done.
+Delta compression using up to 4 threads.
+Compressing objects: 100% (7/7), done.
+Writing objects: 100% (8/8), 843 bytes, done.
+Total 8 (delta 2), reused 0 (delta 0)
+To ssh://joebo@xxxx.com/~/repo.git
+ 98082cb..2537203 git-annex -> synced/git-annex
+ ! [rejected] master -> synced/master (non-fast-forward)
+error: failed to push some refs to 'ssh://joebo@xxxx.com/~/repo.git'
+hint: Updates were rejected because a pushed branch tip is behind its remote
+hint: counterpart. Check out this branch and merge the remote changes
+hint: (e.g. 'git pull') before pushing again.
+hint: See the 'Note about fast-forwards' in 'git push --help' for details.
+failed
+git-annex: sync: 1 failed
+
+C:\joe\backup\repo-bak>git annex get foo2.txt
+git-annex: foo2.txt not found
+
+C:\joe\backup\repo-bak>cat foo2.txt
+cat: foo2.txt: No such file or directory
+C:\joe\backup\repo-bak>git pull origin synced/master
+From ssh://xxxx.com/~/repo
+ * branch synced/master -> FETCH_HEAD
+Updating 47c05ea..76a9e44
+Fast-forward
+ foo2.txt | 1 +
+ 1 file changed, 1 insertion(+)
+ create mode 120000 foo2.txt
+
+C:\joe\backup\repo-bak>git annex get foo2.txt
+get foo2.txt (from origin...)
+SHA256E-s7--eef0e29200a3194851e5fb4ff77d0d0aec5cd3f5ccd78762e80a45f0bbece05f.txt
+
+ 7 100% 6.84kB/s 0:00:00 (xfer#1, to-check=0/1)
+
+sent 30 bytes received 156 bytes 124.00 bytes/sec
+total size is 7 speedup is 0.04
+ok
+warning: LF will be replaced by CRLF in C:\joe\backup\repo-bak\.git\annex\journa
+l\fba_8bb_SHA256E-s7--eef0e29200a3194851e5fb4ff77d0d0aec5cd3f5ccd78762e80a45f0bb
+ece05f.txt.log.
+The file will have its original line endings in your working directory.
+(Recording state in git...)
+
+C:\joe\backup\repo-bak>cat foo2.txt
+.git/annex/objects/3V/kM/SHA256E-s7--eef0e29200a3194851e5fb4ff77d0d0aec5cd3f5ccd
+78762e80a45f0bbece05f.txt/SHA256E-s7--eef0e29200a3194851e5fb4ff77d0d0aec5cd3f5cc
+d78762e80a45f0bbece05f.txt
+C:\joe\backup\repo-bak>
+
+
+
+# End of transcript or log.
+"""]]
+
+> Apparently the last of the issues discussed here is fixed.
+> Closing this bug report before it grows a new issue. ;) [[done]] --[[Joey]]
diff --git a/doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_10_b4f5e2d6a0d690f6b0089fa80a3c920b._comment b/doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_10_b4f5e2d6a0d690f6b0089fa80a3c920b._comment
new file mode 100644
index 000000000..71cc02668
--- /dev/null
+++ b/doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_10_b4f5e2d6a0d690f6b0089fa80a3c920b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmhfodZquCI_EEl-f3h7HkROTszlsQL6yA"
+ nickname="Joe"
+ subject="comment 10"
+ date="2013-06-19T00:44:44Z"
+ content="""
+The latest build is working again. Thanks!
+"""]]
diff --git a/doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_1_c2092add1430667108a3fdc5e1c9b5f5._comment b/doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_1_c2092add1430667108a3fdc5e1c9b5f5._comment
new file mode 100644
index 000000000..52bb21ae3
--- /dev/null
+++ b/doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_1_c2092add1430667108a3fdc5e1c9b5f5._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-06-15T18:50:45Z"
+ content="""
+Joe, you need to carefully read [[direct_mode]]. When you manually run `git merge` in a direct mode repository, you defeat associated file tracking, with the resulting behavior you describe. This is why there is a [[todo/direct_mode_guard]] todo item.
+"""]]
diff --git a/doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_2_f0ea453951daf84dbddc653ac64822b6._comment b/doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_2_f0ea453951daf84dbddc653ac64822b6._comment
new file mode 100644
index 000000000..2c45f6b58
--- /dev/null
+++ b/doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_2_f0ea453951daf84dbddc653ac64822b6._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmhfodZquCI_EEl-f3h7HkROTszlsQL6yA"
+ nickname="Joe"
+ subject="comment 2"
+ date="2013-06-15T19:39:09Z"
+ content="""
+joey, Thank you for the reply. I have read that and also read about the direct mode guard. I only used git merge because I was stuck and didn't know what else to do. I assume the proper way to refresh my backup repo is to git annex sync. That's what's failing with the non-fast-forward error. I don't know what to do from there. Thank you for any help.
+"""]]
diff --git a/doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_3_35a8be5ecc9d1b72c38f8ddb47678160._comment b/doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_3_35a8be5ecc9d1b72c38f8ddb47678160._comment
new file mode 100644
index 000000000..c723d85bb
--- /dev/null
+++ b/doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_3_35a8be5ecc9d1b72c38f8ddb47678160._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmhfodZquCI_EEl-f3h7HkROTszlsQL6yA"
+ nickname="Joe"
+ subject="comment 3"
+ date="2013-06-16T13:27:36Z"
+ content="""
+Making some progress. It looks like it needs a .map file for the newly added file when I pull in the backup repo. I'm tracing the various places addAssociatedFile gets called. It looks like sync should do it. I think that's what sets up the map. If I copy the map file from another repo, I'm able to call get annex get foo2.txt. So the key is getting that map file created.
+"""]]
diff --git a/doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_4_29e72997b88f91f84639587b4cede34c._comment b/doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_4_29e72997b88f91f84639587b4cede34c._comment
new file mode 100644
index 000000000..c785ff77b
--- /dev/null
+++ b/doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_4_29e72997b88f91f84639587b4cede34c._comment
@@ -0,0 +1,76 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmhfodZquCI_EEl-f3h7HkROTszlsQL6yA"
+ nickname="Joe"
+ subject="comment 4"
+ date="2013-06-16T17:27:18Z"
+ content="""
+I have a workaround that requires a small patch. I'm not sure why it's not creating the mapping, but I noticed that git annex fsck has a verifyDirectMapping which will create the mapping if it doesn't exist.
+
+git annex fsck will throw an error on fixLinks and won't proceed to verifyDirectMapping if the map file doesn't exist. So, I needed a way to call verifyDirectMapping directly. My hack is to add an argument to git annex fsck to call verifyDirectMapping.
+
+My workflow is this:
+
+**repo1**:
+[[!format sh \"\"\"
+echo a > new.txt
+git annex add .
+git commit -m \"add a\"
+git copy --to origin
+git annex sync
+\"\"\"]]
+
+**repo2**:
+[[!format sh \"\"\"
+git annex sync
+git annex pull origin synced/master
+git annex fsck --verifyDirectMapping
+git annex get .
+\"\"\"]]
+
+The new file comes down cleanly.
+
+I'm sure there's a better way to do this to fix the core issue, but here's how I patched Fsck.hs as a minimal workaround
+
+[[!format diff \"\"\"
+
+diff --git a/Command/Fsck.hs b/Command/Fsck.hs
+old mode 100644
+new mode 100755
+index 9af6a4a..97aabb8
+--- a/Command/Fsck.hs
++++ b/Command/Fsck.hs
+@@ -59,12 +60,16 @@ incrementalScheduleOption :: Option
+ incrementalScheduleOption = Option.field [] \"incremental-schedule\" paramTime
+ \"schedule incremental fscking\"
+
++verifyDirectMappingOption :: Option
++verifyDirectMappingOption = Option.flag [] \"verifyDirectMapping\" \"verifies direct mappings are consistent\"
++
+ options :: [Option]
+ options =
+ [ fromOption
+ , startIncrementalOption
+ , moreIncrementalOption
+ , incrementalScheduleOption
++ , verifyDirectMappingOption
+ ]
+
+ seek :: [CommandSeek]
+@@ -107,18 +112,23 @@ withIncremental = withValue $ do
+ start :: Maybe Remote -> Incremental -> FilePath -> (Key, Backend) -> CommandStart
+ start from inc file (key, backend) = do
+ numcopies <- numCopies file
+- case from of
+- Nothing -> go $ perform key file backend numcopies
+- Just r -> go $ performRemote key file backend numcopies r
++ verify <- Annex.getFlag (Option.name verifyDirectMappingOption)
++ if verify
++ then go $ verifyDirectMapping key file
++ else
++ case from of
++ Nothing -> go $ perform key file backend numcopies
++ Just r -> go $ performRemote key file backend numcopies r
+
+
+\"\"\"]]
+"""]]
diff --git a/doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_5_2de7f6532de4cbc21737ce53a89d6525._comment b/doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_5_2de7f6532de4cbc21737ce53a89d6525._comment
new file mode 100644
index 000000000..a08bd2899
--- /dev/null
+++ b/doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_5_2de7f6532de4cbc21737ce53a89d6525._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 5"
+ date="2013-06-18T00:09:58Z"
+ content="""
+I have followed the transcript (on my linux system), and cannot reproduce the non-fast-forward problem.
+
+What error does fsck throw in fixLink?
+"""]]
diff --git a/doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_6_80d130b5af829763be77c61a9c5ca306._comment b/doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_6_80d130b5af829763be77c61a9c5ca306._comment
new file mode 100644
index 000000000..6c05e5665
--- /dev/null
+++ b/doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_6_80d130b5af829763be77c61a9c5ca306._comment
@@ -0,0 +1,29 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmhfodZquCI_EEl-f3h7HkROTszlsQL6yA"
+ nickname="Joe"
+ subject="comment 6"
+ date="2013-06-18T00:25:53Z"
+ content="""
+The transcript also works fine on my linux machine.
+
+This is the git annex fsck error:
+
+[[!format sh \"\"\"
+
+(fixing content location) looking for mapping\"C:\\joe\\backup\\repo-bak\\.git\\a
+nnex\\objects\\fba\\8bb\\SHA256E-s7--eef0e29200a3194851e5fb4ff77d0d0aec5cd3f5ccd
+78762e80a45f0bbece05f.txt\\SHA256E-s7--eef0e29200a3194851e5fb4ff77d0d0aec5cd3f5c
+cd78762e80a45f0bbece05f.txt.map\"
+
+git-annex: C:\joe\backup\repo-bak\.git/annex/objects/3V/kM/SHA256E-s7--eef0e2920
+0a3194851e5fb4ff77d0d0aec5cd3f5ccd78762e80a45f0bbece05f.txt/SHA256E-s7--eef0e292
+00a3194851e5fb4ff77d0d0aec5cd3f5ccd78762e80a45f0bbece05f.txt: renameFile: does n
+ot exist (No such file or directory)
+failed
+git-annex: fsck: 1 failed
+
+
+\"\"\"]]
+
+As such it can't get to verifyDirectMapping to corrrect the missing mapping
+"""]]
diff --git a/doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_7_ec199db851952b40e8b18922da574ea4._comment b/doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_7_ec199db851952b40e8b18922da574ea4._comment
new file mode 100644
index 000000000..9f5dc052d
--- /dev/null
+++ b/doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_7_ec199db851952b40e8b18922da574ea4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 7"
+ date="2013-06-18T01:38:05Z"
+ content="""
+There were at least 4 windows port bugs here. (Including `git annex sync` not committing on Windows, I think!) Should now have fixed them all. This includes fixing my earlier fix to make git annex sync push to master in a bare repository, which was not working on Windows.
+"""]]
diff --git a/doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_8_d269fcadea9d5a668e3c6d6cf019f56a._comment b/doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_8_d269fcadea9d5a668e3c6d6cf019f56a._comment
new file mode 100644
index 000000000..feda63b4a
--- /dev/null
+++ b/doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_8_d269fcadea9d5a668e3c6d6cf019f56a._comment
@@ -0,0 +1,353 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmhfodZquCI_EEl-f3h7HkROTszlsQL6yA"
+ nickname="Joe"
+ subject="comment 8"
+ date="2013-06-18T02:14:01Z"
+ content="""
+Thanks joey - I pulled the latest and built it. I don't think everything is working, or maybe my steps need to be updated. On the positive side, git annex fsck no longer errors out. However, I still get the fast-forward message and get annex get . gives me an error about repositories not being available.
+
+This is running my test script:
+
+[[!format sh \"\"\"
+
+C:\joe\backup>ssh joebo@xxxx.com sh testrepo.sh
+Initialized empty Git repository in /home/joebo/repo.git/
+init origin ok
+(Recording state in git...)
+commit
+ok
+git-annex: no branch is checked out
+
+C:\joe\backup>rm -rf repo
+
+C:\joe\backup>git init repo
+Initialized empty Git repository in C:/joe/backup/repo/.git/
+
+C:\joe\backup>cd repo
+
+C:\joe\backup\repo>git annex init
+init
+ Detected a crippled filesystem.
+
+ Enabling direct mode.
+
+ Detected a filesystem without fifo support.
+
+ Disabling ssh connection caching.
+ok
+warning: LF will be replaced by CRLF in C:\joe\backup\repo\.git\annex\journal\uu
+id.log.
+The file will have its original line endings in your working directory.
+(Recording state in git...)
+
+C:\joe\backup\repo>git remote add origin ssh://joebo@xxxx.com/~/repo.git
+
+C:\joe\backup\repo>echo hello 1>foo.txt
+
+C:\joe\backup\repo>git annex add .
+add foo.txt (checksum...) ok
+(Recording state in git...)
+warning: LF will be replaced by CRLF in C:\joe\backup\repo\.git\annex\journal\ae
+4_1e9_SHA256E-s8--f873eef4f852e335da367d76ce7f1973c15b8ffebf532b064df4bc691cd51a
+87.txt.log.
+The file will have its original line endings in your working directory.
+
+C:\joe\backup\repo>git commit -m \"initial commit\"
+[master (root-commit) 4450966] initial commit
+ 1 file changed, 1 insertion(+)
+ create mode 120000 foo.txt
+
+C:\joe\backup\repo>git annex sync
+commit
+ok
+pull origin
+warning: no common commits
+remote: Counting objects: 5, done.
+remote: Compressing objects: 100% (3/3), done.
+remote: Total 5 (delta 1), reused 0 (delta 0)
+Unpacking objects: 100% (5/5), done.
+From ssh://xxxx.com/~/repo
+ * [new branch] git-annex -> origin/git-annex
+ok
+(merging origin/git-annex into git-annex...)
+(Recording state in git...)
+push origin
+Counting objects: 18, done.
+Delta compression using up to 4 threads.
+Compressing objects: 100% (12/12), done.
+Writing objects: 100% (16/16), 1.41 KiB, done.
+Total 16 (delta 3), reused 0 (delta 0)
+To ssh://joebo@xxxx.com/~/repo.git
+ * [new branch] git-annex -> synced/git-annex
+ * [new branch] master -> synced/master
+ok
+
+C:\joe\backup\repo>git annex copy --to origin
+copy foo.txt (checking origin...) (to origin...)
+foo.txt
+ 8 100% 0.00kB/s 0:00:00 (xfer#1, to-check=0/1)
+
+sent 79 bytes received 31 bytes 31.43 bytes/sec
+total size is 8 speedup is 0.07
+ok
+warning: LF will be replaced by CRLF in C:\joe\backup\repo\.git\annex\journal\ae
+4_1e9_SHA256E-s8--f873eef4f852e335da367d76ce7f1973c15b8ffebf532b064df4bc691cd51a
+87.txt.log.
+The file will have its original line endings in your working directory.
+(Recording state in git...)
+
+C:\joe\backup\repo>git annex sync
+commit
+ok
+pull origin
+remote: Counting objects: 6, done.
+remote: Compressing objects: 100% (4/4), done.
+remote: Total 5 (delta 0), reused 0 (delta 0)
+Unpacking objects: 100% (5/5), done.
+From ssh://xxxx.com/~/repo
+ dd2afc8..fcccfa3 git-annex -> origin/git-annex
+ok
+(merging origin/git-annex into git-annex...)
+(Recording state in git...)
+push origin
+Counting objects: 21, done.
+Delta compression using up to 4 threads.
+Compressing objects: 100% (9/9), done.
+Writing objects: 100% (11/11), 896 bytes, done.
+Total 11 (delta 4), reused 0 (delta 0)
+To ssh://joebo@xxxx.com/~/repo.git
+ a093010..10a7c3a git-annex -> synced/git-annex
+ok
+
+C:\joe\backup\repo>git push origin master
+Everything up-to-date
+
+C:\joe\backup\repo>cd ..
+
+C:\joe\backup>rm -rf repo-bak
+
+C:\joe\backup>git init repo-bak
+Initialized empty Git repository in C:/joe/backup/repo-bak/.git/
+
+C:\joe\backup>cd repo-bak
+
+C:\joe\backup\repo-bak>git remote add origin ssh://joebo@xxxx.com/~/repo.git
+
+C:\joe\backup\repo-bak>git fetch origin
+remote: Counting objects: 36, done.
+remote: Compressing objects: 100% (28/28), done.
+remote: Total 36 (delta 11), reused 0 (delta 0)
+Unpacking objects: 100% (36/36), done.
+From ssh://xxxx.com/~/repo
+ * [new branch] git-annex -> origin/git-annex
+ * [new branch] master -> origin/master
+ * [new branch] synced/git-annex -> origin/synced/git-annex
+ * [new branch] synced/master -> origin/synced/master
+
+C:\joe\backup\repo-bak>git merge origin/synced/master
+
+C:\joe\backup\repo-bak>git annex sync
+
+ Detected a crippled filesystem.
+
+ Enabling direct mode.
+
+ Detected a filesystem without fifo support.
+
+ Disabling ssh connection caching.
+warning: LF will be replaced by CRLF in C:\joe\backup\repo-bak\.git\annex\journa
+l\uuid.log.
+The file will have its original line endings in your working directory.
+(merging origin/git-annex origin/synced/git-annex into git-annex...)
+(Recording state in git...)
+commit
+ok
+pull origin
+ok
+push origin
+Counting objects: 18, done.
+Delta compression using up to 4 threads.
+Compressing objects: 100% (6/6), done.
+Writing objects: 100% (8/8), 695 bytes, done.
+Total 8 (delta 4), reused 0 (delta 0)
+To ssh://joebo@xxxx.com/~/repo.git
+ 10a7c3a..dbf4a72 git-annex -> synced/git-annex
+ok
+
+C:\joe\backup\repo-bak>git annex get .
+get foo.txt (not available)
+ Try making some of these repositories available:
+ 608d7025-8d33-459e-875b-84de43946980
+ 608d7025-8d33-459e-875b-84de43946980
+ def09afe-da97-4f07-ae90-90ea116eb8c4
+failed
+git-annex: get: 1 failed
+
+C:\joe\backup\repo-bak>cat foo.txt
+.git/annex/objects/6k/Mf/SHA256E-s8--f873eef4f852e335da367d76ce7f1973c15b8ffebf5
+32b064df4bc691cd51a87.txt/SHA256E-s8--f873eef4f852e335da367d76ce7f1973c15b8ffebf
+532b064df4bc691cd51a87.txt
+C:\joe\backup\repo-bak>cd ..
+
+C:\joe\backup>cd repo
+
+C:\joe\backup\repo>echo foo2 1>foo2.txt
+
+C:\joe\backup\repo>git annex add .
+add foo2.txt (checksum...) ok
+(Recording state in git...)
+warning: LF will be replaced by CRLF in C:\joe\backup\repo\.git\annex\journal\fb
+a_8bb_SHA256E-s7--eef0e29200a3194851e5fb4ff77d0d0aec5cd3f5ccd78762e80a45f0bbece0
+5f.txt.log.
+The file will have its original line endings in your working directory.
+
+C:\joe\backup\repo>git commit -m \"another\"
+[master 438409c] another
+ 1 file changed, 1 insertion(+)
+ create mode 120000 foo2.txt
+
+C:\joe\backup\repo>git annex sync
+commit
+ok
+pull origin
+remote: Counting objects: 18, done.
+remote: Compressing objects: 100% (6/6), done.
+remote: Total 8 (delta 4), reused 0 (delta 0)
+Unpacking objects: 100% (8/8), done.
+From ssh://xxxx.com/~/repo
+ 10a7c3a..dbf4a72 synced/git-annex -> origin/synced/git-annex
+ok
+(merging origin/synced/git-annex into git-annex...)
+(Recording state in git...)
+push origin
+Counting objects: 25, done.
+Delta compression using up to 4 threads.
+Compressing objects: 100% (12/12), done.
+Writing objects: 100% (14/14), 1.32 KiB, done.
+Total 14 (delta 3), reused 0 (delta 0)
+To ssh://joebo@xxxx.com/~/repo.git
+ dbf4a72..79c01f2 git-annex -> synced/git-annex
+ 4450966..438409c master -> synced/master
+ok
+
+C:\joe\backup\repo>git annex copy --to origin
+copy foo.txt (checking origin...) ok
+copy foo2.txt (checking origin...) (to origin...)
+foo2.txt
+ 7 100% 0.00kB/s 0:00:00 (xfer#1, to-check=0/1)
+
+sent 79 bytes received 31 bytes 220.00 bytes/sec
+total size is 7 speedup is 0.06
+ok
+warning: LF will be replaced by CRLF in C:\joe\backup\repo\.git\annex\journal\fb
+a_8bb_SHA256E-s7--eef0e29200a3194851e5fb4ff77d0d0aec5cd3f5ccd78762e80a45f0bbece0
+5f.txt.log.
+The file will have its original line endings in your working directory.
+(Recording state in git...)
+
+C:\joe\backup\repo>git annex sync
+commit
+ok
+pull origin
+remote: Counting objects: 6, done.
+remote: Compressing objects: 100% (4/4), done.
+remote: Total 5 (delta 0), reused 0 (delta 0)
+Unpacking objects: 100% (5/5), done.
+From ssh://xxxx.com/~/repo
+ fcccfa3..eb065b0 git-annex -> origin/git-annex
+ok
+(merging origin/git-annex into git-annex...)
+(Recording state in git...)
+push origin
+Counting objects: 33, done.
+Delta compression using up to 4 threads.
+Compressing objects: 100% (13/13), done.
+Writing objects: 100% (17/17), 1.27 KiB, done.
+Total 17 (delta 8), reused 0 (delta 0)
+To ssh://joebo@xxxx.com/~/repo.git
+ 79c01f2..7ecf368 git-annex -> synced/git-annex
+ok
+
+C:\joe\backup\repo>cd ..
+
+C:\joe\backup>cd repo-bak
+
+C:\joe\backup\repo-bak>git annex sync
+commit
+ok
+pull origin
+remote: Counting objects: 52, done.
+remote: Compressing objects: 100% (29/29), done.
+remote: Total 36 (delta 13), reused 0 (delta 0)
+Unpacking objects: 100% (36/36), done.
+From ssh://xxxx.com/~/repo
+ fcccfa3..eb065b0 git-annex -> origin/git-annex
+ 4450966..438409c master -> origin/master
+ dbf4a72..7ecf368 synced/git-annex -> origin/synced/git-annex
+ 4450966..438409c synced/master -> origin/synced/master
+ok
+(merging origin/git-annex origin/synced/git-annex into git-annex...)
+(Recording state in git...)
+push origin
+Counting objects: 30, done.
+Delta compression using up to 4 threads.
+Compressing objects: 100% (7/7), done.
+Writing objects: 100% (9/9), 732 bytes, done.
+Total 9 (delta 5), reused 0 (delta 0)
+To ssh://joebo@xxxx.com/~/repo.git
+ 7ecf368..7895f60 git-annex -> synced/git-annex
+ ! [rejected] master -> synced/master (non-fast-forward)
+error: failed to push some refs to 'ssh://joebo@xxxx.com/~/repo.git'
+hint: Updates were rejected because a pushed branch tip is behind its remote
+hint: counterpart. Check out this branch and merge the remote changes
+hint: (e.g. 'git pull') before pushing again.
+hint: See the 'Note about fast-forwards' in 'git push --help' for details.
+failed
+git-annex: sync: 1 failed
+
+C:\joe\backup\repo-bak>git pull origin synced/master
+From ssh://xxxx.com/~/repo
+ * branch synced/master -> FETCH_HEAD
+Updating 4450966..438409c
+Fast-forward
+ foo2.txt | 1 +
+ 1 file changed, 1 insertion(+)
+ create mode 120000 foo2.txt
+
+C:\joe\backup\repo-bak>git annex sync
+commit
+ok
+pull origin
+ok
+push origin
+Everything up-to-date
+ok
+
+C:\joe\backup\repo-bak>cat foo.txt
+.git/annex/objects/6k/Mf/SHA256E-s8--f873eef4f852e335da367d76ce7f1973c15b8ffebf5
+32b064df4bc691cd51a87.txt/SHA256E-s8--f873eef4f852e335da367d76ce7f1973c15b8ffebf
+532b064df4bc691cd51a87.txt
+C:\joe\backup\repo-bak>git annex get foo.txt
+get foo.txt (not available)
+ Try making some of these repositories available:
+ 608d7025-8d33-459e-875b-84de43946980
+ 608d7025-8d33-459e-875b-84de43946980
+ 608d7025-8d33-459e-875b-84de43946980
+ 608d7025-8d33-459e-875b-84de43946980
+ def09afe-da97-4f07-ae90-90ea116eb8c4
+ def09afe-da97-4f07-ae90-90ea116eb8c4
+failed
+git-annex: get: 1 failed
+
+C:\joe\backup\repo-bak>
+C:\joe\backup\repo-bak>git annex fsck foo.txt
+fsck foo.txt ok
+
+C:\joe\backup\repo-bak>
+
+\"\"\"]]
+
+Perhaps I need to change my transcript to reflect the new fixes?
+
+Reverting back to my patched version, I can run the script and run git annex fsck --verifyDirectMapping and get the file cleanly. Do I need to update the server version? (I assume not)
+"""]]
diff --git a/doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_9_908d1b981d56107f29d8972bf11aefc8._comment b/doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_9_908d1b981d56107f29d8972bf11aefc8._comment
new file mode 100644
index 000000000..0f9eaeb6f
--- /dev/null
+++ b/doc/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/comment_9_908d1b981d56107f29d8972bf11aefc8._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmhfodZquCI_EEl-f3h7HkROTszlsQL6yA"
+ nickname="Joe"
+ subject="comment 9"
+ date="2013-06-18T09:58:41Z"
+ content="""
+The regression appears to behere: $ git diff d80a0f62a4aa5a2a3566f29dd6bda619b1a7eabd..64f8819ae47cc27b164eb69aa846dfb0f7cc6ef3 Process.hs
+
+I rewound each commit until I no longer had the regression. This commit was clean: d80a0f62a4aa5a2a3566f29dd6bda619b1a7eabd. Something with the changes to Process.hs is causing my error.
+
+I validated by building using git checkout d80a0f62a4aa5a2a3566f29dd6bda619b1a7eabd Process.hs and the error went away.
+"""]]
diff --git a/doc/bugs/wrong_program_path_in___126____47__.config__47__git-annex__47__program.mdwn b/doc/bugs/wrong_program_path_in___126____47__.config__47__git-annex__47__program.mdwn
new file mode 100644
index 000000000..d145fa6e6
--- /dev/null
+++ b/doc/bugs/wrong_program_path_in___126____47__.config__47__git-annex__47__program.mdwn
@@ -0,0 +1,20 @@
+## What steps will reproduce the problem?
+
+install the latest linux snapshot of git-annex (https://downloads.kitenet.net/git-annex/linux/3.20121127/git-annex-standalone-amd64.tar.gz)
+
+## What is the expected output? What do you see instead?
+
+I would expect `~/.config/git-annex/program` to contain `/home/thedward/tmp/git-annex.linux/runshell`
+
+Instead it contains `/home/thedward/tmp/git-annex.linuxrunshell`, which causes a problem next time I start the webapp (unless I manually fix it first).
+
+## What version of git-annex are you using? On what operating system?
+
+git-annex=3.20121127 on Ubuntu 12.04 LTS
+
+
+## Please provide any additional information below.
+
+Otherwise it is working great.
+
+> I've fixed this. [[done]] --[[Joey]]
diff --git a/doc/bugs/wrong_program_path_in___126____47__.config__47__git-annex__47__program/comment_1_44c11918d00ead38d40556aade98c0af._comment b/doc/bugs/wrong_program_path_in___126____47__.config__47__git-annex__47__program/comment_1_44c11918d00ead38d40556aade98c0af._comment
new file mode 100644
index 000000000..297eea157
--- /dev/null
+++ b/doc/bugs/wrong_program_path_in___126____47__.config__47__git-annex__47__program/comment_1_44c11918d00ead38d40556aade98c0af._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkvSZ1AFJdY_1FeutZr_KWeqtzjZta1PNE"
+ nickname="Thedward"
+ subject="comment 1"
+ date="2012-11-28T22:14:12Z"
+ content="""
+Sweet!
+
+That's the fastest I've ever had a bug I reported closed.
+
+Thanks for all your hard work on this. :-)
+"""]]
diff --git a/doc/bugs/xdg-user-dir_error.mdwn b/doc/bugs/xdg-user-dir_error.mdwn
new file mode 100644
index 000000000..5a8ed52d7
--- /dev/null
+++ b/doc/bugs/xdg-user-dir_error.mdwn
@@ -0,0 +1,8 @@
+Run *git annex webapp* in Debian Sid with KDE.
+
+It opens the web browser with this error: **Internal Server Error** *xdg-user-dir ["DESKTOP"] exited 127*.
+
+I've tried to changing the xdg-user-dir config with no success.
+
+> This is fixed in my master branch. Workaround: Install the xdg-user-dirs
+> package. [[done]] --[[Joey]]
diff --git a/doc/bugs/xmpp_needs_one_account_per_distinct_repository.mdwn b/doc/bugs/xmpp_needs_one_account_per_distinct_repository.mdwn
new file mode 100644
index 000000000..c917cc3d2
--- /dev/null
+++ b/doc/bugs/xmpp_needs_one_account_per_distinct_repository.mdwn
@@ -0,0 +1,107 @@
+The way [[XMPP pairing|design/assistant/XMPP]] currently works, each
+separate repository needs to use a different XMPP account. If two
+repositories use the same XMPP account, then they will be combined together
+when XMPP pairing takes place.
+
+There are two different UIs for XMPP pairing. While the same protocol
+is running behind the scenes, these UIs should be considered separately.
+
+## Share with your other devices
+
+Here, I think it makes sense to require the user to use the same XMPP
+account on all their devices (otherwise it's pairing with a friend), and
+automatically combine repositories of devices that use the same XMPP
+account.
+
+The UI is pretty clear about this:
+
+ If you have multiple devices, all running git-annex, and using #
+ your Jabber account #{account}, you can configure them to share #
+ your files between themselves.
+
+Doing it this way avoids needing to confirm pair requests coming from the same
+XMPP account. Which means that, for example, you can have a device at home,
+and one at work, and pair them by simply initiating a pair request from one
+to the other. You don't have to travel between home and work to confirm
+the request.
+
+(Also, when you have a lot of devices, this avoids a combinatorial explosion
+of pair request confirmations.)
+
+The only problem with this is that users who want multiple repositories
+need to find multiple XMPP accounts. However, I'm inclined to think this is
+a reasonable requirement.
+
+## Share with a friend
+
+Suppose that Alice wants to share with Bob. Bob is using the same XMPP
+account for two separate repositories (B1 and B2), that are not
+themselves paired.
+
+When Alice chooses to share with Bob, a XMPP pair request is sent.
+Both of Bob's repositories see it, and both ask him to confirm.
+Bob can choose to only confirm the request in B1, and
+not in B2. This should work ok.
+
+* The UI for this only says "Pair request received from #{name}",
+ it does not indicate which repository of Alice's is being paired
+ with. This could be improved. If Alice has two repositories as well,
+ she and Bob will want to coordinate pairing the right ones together.
+ Could be fixed by just displaying the description of Alice's repository
+ to Bob.
+
+-----
+
+Now, suppose that Alice makes a second, distinct repository (A2),
+and chooses to share it with Bob (intending to share with B2). This
+sends an XMPP pair request to both of Bob's repositories.
+
+B1 has already paired with Alice, so it assumes this
+new pair request is from a different device belonging to Alice, and it
+automatically ACKs the pair request.
+
+The result is that Alice's new A2 repository combines with B1,
+which is already combined with A1. Effectively combining all of A1, A2, B1,
+and B2, unexpectedly. **This is a bug**.
+
+Some possible fixes:
+
+1. Stop auto-accepting pair requests
+ from friends we're already paired with. Require another confirmation.
+2. Or, only auto-accept pair requests from friends we're already paired with
+ when they come from a repository whose UUID we already know. This
+ enhancment to fix #1 makes it easier to build more robust networks of
+ repositories. **done**
+
+Hmm, I don't think those fixes are sufficient. Suppose they're in place.
+Then when Alice shares A2 with Bob, both his repositories will ask him to
+confirm the pair request. He confirms in B2, and pairing proceeds.
+
+But, XMPP git push is broadcast to all clients of an XMPP account.
+So when B2 sends a push, A1 sees it, and happily merges away. The
+repositories still combine!
+
+So, we need another fix:
+
+* Send UUID in XMPP git push protocol messages. Only respond to git push
+ messages from a known UUID, and ignore all others. (XMPP pairing
+ already sends the UUID, so it will be known.) **done**
+
+----
+
+* Alternatively, we could say that the problem is that Bob has two
+ distinct repositories using the same XMPP account, and try to prevent
+ him from doing that in the first place.
+
+ One way to do this would be, when configuring the
+ XMPP account, scan for other repositories using the same account, and
+ don't let it be used unless the user confirms they want to pair them.
+ But, this doesn't seem viable because if the other repository is on
+ another device, which is turned off, this check wouldn't see it.
+
+ Or there could be a warning about account reuse. Doesn't seem likely to
+ be effective.
+
+-----
+
+> [[done]]. I've put in the fixes around pairing with friends. --[[Joey]]
diff --git a/doc/bugs/xmpp_needs_one_account_per_distinct_repository/comment_1_820732c4dcb15186b4f635c50fdb0805._comment b/doc/bugs/xmpp_needs_one_account_per_distinct_repository/comment_1_820732c4dcb15186b4f635c50fdb0805._comment
new file mode 100644
index 000000000..eec708362
--- /dev/null
+++ b/doc/bugs/xmpp_needs_one_account_per_distinct_repository/comment_1_820732c4dcb15186b4f635c50fdb0805._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="fmarier"
+ ip="121.98.93.240"
+ subject="My current XMPP setup"
+ date="2013-04-28T22:16:50Z"
+ content="""
+Here's the way I currently use XMPP (Google Talk) on my devices:
+
+* I have a separate XMPP/Google account on each device (device1@gmail.com, device2@gmail.com, etc.). I keep them separate to protect the credentials of the other devices in case I lose one of the devices.
+* I setup git-annex to sync with a \"friend\" and have device1@gmail.com and device2@gmail.com sync with each other.
+
+I have three different repositories I'd like to manage with git-annex assistant:
+
+ * R1: things I want everywhere
+ * R2: things I only want on personal laptop and desktop
+ * R3: things I only want on personal and work laptops
+
+So it would be great if there was a way to easily keep things separate.
+"""]]
diff --git a/doc/bugs/yesod-default_is_needed_as_a_dependancy.mdwn b/doc/bugs/yesod-default_is_needed_as_a_dependancy.mdwn
new file mode 100644
index 000000000..28727f97f
--- /dev/null
+++ b/doc/bugs/yesod-default_is_needed_as_a_dependancy.mdwn
@@ -0,0 +1,10 @@
+Seems like there is a needed dependancy, yesod-default is needed on OSX.
+
+<pre>
+Utility/Yesod.hs:10:8:
+ Could not find module `Yesod.Default.Util'
+ Use -v to see a list of the files searched for.
+make: *** [git-annex] Error 1
+</pre>
+
+> Only on OSX apparently. Weird. Added. [[done]] --[[Joey]]
diff --git a/doc/bugs/yesod-form_missing.mdwn b/doc/bugs/yesod-form_missing.mdwn
new file mode 100644
index 000000000..ad92bd040
--- /dev/null
+++ b/doc/bugs/yesod-form_missing.mdwn
@@ -0,0 +1,23 @@
+What steps will reproduce the problem?
+
+build using cabal from a git checkout
+
+What is the expected output? What do you see instead?
+
+successful build; error message is:
+
+Assistant/WebApp/Form.hs:15:8:
+ Could not find module `Yesod.Form.Fields'
+ It is a member of the hidden package `yesod-form-1.2.0'.
+ Perhaps you need to add `yesod-form' to the build-depends in your .cabal file.
+
+
+What version of git-annex are you using? On what operating system?
+
+git checkout commit 90b62db1defdd223294935ec0bbaac883cd20c04 on OS X Lion
+
+Please provide any additional information below.
+
+adding yesod-form to the build depends in git-annex.cabal does indeed fix the problem!
+
+> [[done]] --[[Joey]]
diff --git a/doc/bugs/youtube_support_suddenly_stopped_working.mdwn b/doc/bugs/youtube_support_suddenly_stopped_working.mdwn
new file mode 100644
index 000000000..bedda7674
--- /dev/null
+++ b/doc/bugs/youtube_support_suddenly_stopped_working.mdwn
@@ -0,0 +1,62 @@
+### Please describe the problem.
+
+[[This|design/assistant/blog/day_314__quvi/]] says that I can download youtube videos with git-annex, but I can't - it downloads the HTML of the page instead!
+
+### What steps will reproduce the problem?
+
+ git annex addurl http://www.youtube.com/watch?v=BTzNLhxPzjo
+
+Should have downloaded a Bill Hicks video, instead it downloads the HTML.
+
+### What version of git-annex are you using? On what operating system?
+
+[[!format txt """
+git-annex version: 4.20130912-ga1faca3
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP DNS Feeds Quvi
+local repository version: 3
+default repository version: 3
+supported repository versions: 3 4
+upgrade supported from repository versions: 0 1 2
+"""]]
+
+Note that quvi is still capable of fetching that video, no problem there.
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+anarcat@marcos:clips$ git annex addurl http://www.youtube.com/watch?v=BTzNLhxPzjo
+addurl www.youtube.com_watch_v=BTzNLhxPzjo ok
+anarcat@marcos:clips$ file www.youtube.com_watch_v\=BTzNLhxPzjo
+www.youtube.com_watch_v=BTzNLhxPzjo: broken symbolic link to `.git/annex/objects/qZ/q1/SHA256E-s123162--96fe8634aaf035373077473ac2b166c5ad22bfe099112c414eee9fe753f4ce2b/SHA256E-s123162--96fe8634aaf035373077473ac2b166c5ad22bfe099112c414eee9fe753f4ce2b'
+anarcat@marcos:clips$ file www.youtube.com_watch_v\=BTzNLhxPzjo ^C
+anarcat@marcos:clips$ file .git/annex/objects/qZ/q1/SHA256E-s123162--96fe8634aaf035373077473ac2b166c5ad22bfe099112c414eee9fe753f4ce2b/SHA256E-s123162--96fe8634aaf035373077473ac2b166c5ad22bfe099112c414eee9fe753f4ce2b
+.git/annex/objects/qZ/q1/SHA256E-s123162--96fe8634aaf035373077473ac2b166c5ad22bfe099112c414eee9fe753f4ce2b/SHA256E-s123162--96fe8634aaf035373077473ac2b166c5ad22bfe099112c414eee9fe753f4ce2b: ERROR: cannot open `.git/annex/objects/qZ/q1/SHA256E-s123162--96fe8634aaf035373077473ac2b166c5ad22bfe099112c414eee9fe753f4ce2b/SHA256E-s123162--96fe8634aaf035373077473ac2b166c5ad22bfe099112c414eee9fe753f4ce2b' (No such file or directory)
+anarcat@marcos:clips$ git annex get www.youtube.com_watch_v\=BTzNLhxPzjo
+get www.youtube.com_watch_v=BTzNLhxPzjo (from web...)
+--2013-09-14 17:24:23-- http://www.youtube.com/watch?v=BTzNLhxPzjo
+Résolution de www.youtube.com (www.youtube.com)... 173.194.43.96, 173.194.43.97, 173.194.43.98, ...
+Connexion vers www.youtube.com (www.youtube.com)|173.194.43.96|:80...connecté.
+requête HTTP transmise, en attente de la réponse...200 OK
+Longueur: non spécifié [text/html]
+Sauvegarde en : «/srv/video/clips/.git/annex/tmp/SHA256E-s123162--96fe8634aaf035373077473ac2b166c5ad22bfe099112c414eee9fe753f4ce2b»
+
+ [ <=> ] 123 245 346K/s ds 0,3s
+
+2013-09-14 17:24:23 (346 KB/s) - «/srv/video/clips/.git/annex/tmp/SHA256E-s123162--96fe8634aaf035373077473ac2b166c5ad22bfe099112c414eee9fe753f4ce2b» sauvegardé [123245]
+
+ok
+(Recording state in git...)
+anarcat@marcos:clips$ file www.youtube.com_watch_v\=BTzNLhxPzjo
+www.youtube.com_watch_v=BTzNLhxPzjo: symbolic link to `.git/annex/objects/qZ/q1/SHA256E-s123162--96fe8634aaf035373077473ac2b166c5ad22bfe099112c414eee9fe753f4ce2b/SHA256E-s123162--96fe8634aaf035373077473ac2b166c5ad22bfe099112c414eee9fe753f4ce2b'
+anarcat@marcos:clips$ file .git/annex/objects/qZ/q1/SHA256E-s123162--96fe8634aaf035373077473ac2b166c5ad22bfe099112c414eee9fe753f4ce2b/SHA256E-s123162--96fe8634aaf035373077473ac2b166c5ad22bfe099112c414eee9fe753f4ce2b
+.git/annex/objects/qZ/q1/SHA256E-s123162--96fe8634aaf035373077473ac2b166c5ad22bfe099112c414eee9fe753f4ce2b/SHA256E-s123162--96fe8634aaf035373077473ac2b166c5ad22bfe099112c414eee9fe753f4ce2b: HTML document, UTF-8 Unicode text, with very long lines
+# End of transcript or log.
+"""]]
+
+### Workaround
+
+Use the `quvi` prefix.
+
+> Typo introduced in last release. [[fixed|done]] --[[Joey]]
diff --git a/doc/builds.mdwn b/doc/builds.mdwn
new file mode 100644
index 000000000..49dfc8859
--- /dev/null
+++ b/doc/builds.mdwn
@@ -0,0 +1,20 @@
+[[!meta title="git-annex autobuild overview"]]
+
+<h2>Linux i386</h2>
+<iframe width=1024 scrolling=no frameborder=0 marginheight=0 marginwidth=0 src="https://downloads.kitenet.net/git-annex/autobuild/i386/">
+</iframe>
+<h2>Linux amd64</h2>
+<iframe width=1024 scrolling=no frameborder=0 marginheight=0 marginwidth=0 src="https://downloads.kitenet.net/git-annex/autobuild/amd64/">
+</iframe>
+<h2>Android</h2>
+<iframe width=1024 scrolling=no frameborder=0 marginheight=0 marginwidth=0 src="https://downloads.kitenet.net/git-annex/autobuild/android/">
+</iframe>
+<h2>OSX Mavericks</h2>
+<iframe width=1024 scrolling=no frameborder=0 marginheight=0 marginwidth=0 src="https://downloads.kitenet.net/git-annex/autobuild/x86_64-apple-mavericks/">
+</iframe>
+<h2>OSX Lion</h2>
+<iframe width=1024 scrolling=no frameborder=0 marginheight=0 marginwidth=0 src="http://www.sgenomics.org/~jtang/gitbuilder-git-annex-x00-x86_64-apple-darwin10.8.0-binary/">
+</iframe>
+<h2>Windows</h2>
+<iframe width=1024 height=1024 scrolling=no frameborder=0 marginheight=0 marginwidth=0 src="https://qa.nest-initiative.org/view/msysGit/job/msysgit-git-annex-assistant-test/">
+</iframe>
diff --git a/doc/coding_style.mdwn b/doc/coding_style.mdwn
new file mode 100644
index 000000000..101ac4f58
--- /dev/null
+++ b/doc/coding_style.mdwn
@@ -0,0 +1,92 @@
+If you do nothing else, avoid use of partial functions from the Prelude!
+`import Utility.PartialPrelude` helps avoid this by defining conflicting
+functions for all the common ones. Also avoid `!!`, it's partial too.
+
+Use tabs for indentation. The one exception to this rule are
+the Hamlet format files in `templates/*`. Hamlet, infuriatingly, refuses
+to allow tabs to be used for indentation.
+
+Code should make sense with any tab stop setting, but 8 space tabs are
+the default. With 8 space tabs, code should not exceed 80 characters
+per line. (With larger tabs, it may of course.)
+
+Use spaces for layout. For example, here spaces (indicated with `.`)
+are used after the initial tab to make the third test line up with
+the others.
+
+ when (foo_test || bar_test ||
+ ......some_other_long_test)
+ print "hi"
+
+As a special Haskell-specific rule, "where" clauses are indented with two
+spaces, rather than a tab. This makes them stand out from the main body
+of the function, and avoids excessive indentation of the where cause content.
+The definitions within the where clause should be put on separate lines,
+each indented with a tab.
+
+ main = do
+ foo
+ bar
+ foo
+ where
+ foo = ...
+ bar = ...
+
+Where clauses for instance definitions and modules tend to appear at the end
+of a line, rather than on a separate line.
+
+ module Foo (Foo, mkFoo, unFoo) where
+ instance MonadBaseControl IO Annex where
+
+When a function's type signature needs to be wrapped to another line,
+it's typical to switch to displaying one parameter per line.
+
+ foo :: Bar -> Baz -> (Bar -> Baz) -> IO Baz
+
+ foo'
+ :: Bar
+ -> Baz
+ -> (Bar -> Baz)
+ -> IO Baz
+
+Note that the "::" then starts its own line. It is not put on the same
+line as the function name because then it would not be guaranteed to line
+up with the "->" at all tab width settings. Similarly, guards are put
+on their own lines:
+
+ splat i
+ | odd i = error "splat!"
+ | otherwise = i
+
+Multiline lists and record syntax are written with leading commas,
+that line up with the open and close punctuation.
+
+ list =
+ [ item1
+ , item2
+ , item3
+ ]
+
+ foo = DataStructure
+ { name = "bar"
+ , address = "baz"
+ }
+
+Module imports are separated into two blocks, one for third-party modules,
+and one for modules that are part of git-annex. (Additional blocks can be used
+if it makes sense.)
+
+Using tabs for indentation makes use of `let .. in` particularly tricky.
+There's no really good way to bind multiple names in a let clause with
+tab indentation. Instead, a where clause is typically used. To bind a single
+name in a let clause, this is sometimes used:
+
+ foo = let x = 42
+ in x + (x-1) + x
+
+-----
+
+If you feel that this coding style leads to excessive amounts of horizontal
+or vertical whitespace around your code, making it hard to fit enough of it
+on the screen, consider finding a better abstraction, so the code that
+does fit on the screen is easily understandable. ;)
diff --git a/doc/comments.mdwn b/doc/comments.mdwn
new file mode 100644
index 000000000..e19962b92
--- /dev/null
+++ b/doc/comments.mdwn
@@ -0,0 +1,9 @@
+[[!sidebar content="""
+[[!inline pages="comment_pending(*)" feedfile=pendingmoderation
+description="comments pending moderation" show=-1]]
+Comments in the [[!commentmoderation desc="moderation queue"]]:
+[[!pagecount pages="comment_pending(*)"]]
+"""]]
+
+Recent comments posted to this site:
+[[!inline pages="comment(*)" template="comment"]]
diff --git a/doc/contact.mdwn b/doc/contact.mdwn
new file mode 100644
index 000000000..b2ccf8201
--- /dev/null
+++ b/doc/contact.mdwn
@@ -0,0 +1,11 @@
+Joey Hess <joey@kitenet.net> is the author of git-annex. If you need to
+talk about something privately, email me.
+
+The [[forum]] is the best place to discuss git-annex.
+
+For realtime chat, use the `#git-annex` channel on irc.oftc.net.
+You can also watch incoming commits there.
+
+The [VCS-home mailing list](http://lists.madduck.net/listinfo/vcs-home)
+is a good mailing list for users who want to use git-annex in the context
+of managing their large personal files.
diff --git a/doc/contact/comment_1_12d60f767d90bea94974e1ff6b206d31._comment b/doc/contact/comment_1_12d60f767d90bea94974e1ff6b206d31._comment
new file mode 100644
index 000000000..f72f3fbe5
--- /dev/null
+++ b/doc/contact/comment_1_12d60f767d90bea94974e1ff6b206d31._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlZQcpoRmyZBlsFQ7TMMYlZZdmBG1TxMzA"
+ nickname="Felipe"
+ subject="translation"
+ date="2013-09-10T20:19:53Z"
+ content="""
+I would like to translate this content of site, the tutorials, pages, etc, to portuguese. I think that can help many users in my country. How can I build a new pages here with git-annex content in portuguese?
+"""]]
diff --git a/doc/contact/comment_2_95b6d868b913418de50ba121d71d2390._comment b/doc/contact/comment_2_95b6d868b913418de50ba121d71d2390._comment
new file mode 100644
index 000000000..6f451d9ae
--- /dev/null
+++ b/doc/contact/comment_2_95b6d868b913418de50ba121d71d2390._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.51"
+ subject="comment 2"
+ date="2013-09-12T21:08:16Z"
+ content="""
+I welcome translations in theory, but I do not have any infrastructure in place to support it, so that would have to be the first step.
+
+(Also, this page is not a general-purpose discussion forum.)
+"""]]
diff --git a/doc/contact/comment_3_2cf43bd406673294e6cdbd785c4a0d0c._comment b/doc/contact/comment_3_2cf43bd406673294e6cdbd785c4a0d0c._comment
new file mode 100644
index 000000000..32fbc7f65
--- /dev/null
+++ b/doc/contact/comment_3_2cf43bd406673294e6cdbd785c4a0d0c._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlkA6XinbeOdnEDxEGQUWyjqPGh0kdMXr4"
+ nickname="Blake"
+ subject="Starting git-annex assistant"
+ date="2013-10-02T23:57:48Z"
+ content="""
+Hi Joey,
+
+I am one of your original funders for git-annex. I think you have done a great job and I am proud to say I helped fund your endeavor.
+
+How do I start the git-annex assistant webapp via command line? I installed the program on my Fedora 19 computer via YUM and it does not come packaged with a desktop icon as you show in your demonstration video. I try running `$ git annex assistant` but I cannot access `http://127.0.0.1:34795/` as you do in the video. Also, the quickstart page (http://git-annex.branchable.com/assistant/quickstart/) seems to have outdated information as it states you can start the webapp via `$ git annex webapp`, however when I try to run this I get the following error: `git-annex: unknown command webapp`.
+
+Regards,
+Blake
+
+"""]]
diff --git a/doc/contact/comment_4_586a506e27379d74fbc0f4b654e89c7d._comment b/doc/contact/comment_4_586a506e27379d74fbc0f4b654e89c7d._comment
new file mode 100644
index 000000000..1cf9c3acc
--- /dev/null
+++ b/doc/contact/comment_4_586a506e27379d74fbc0f4b654e89c7d._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="108.236.230.124"
+ subject="comment 4"
+ date="2013-10-03T00:06:11Z"
+ content="""
+Your fedora build apparently does not include the webapp, since `git annex webapp` is the right command. Install the [[install/Linux_standalone]] build instead.
+
+(Again this page is not a discussion forum. Next person to post here will waste my time since I will have to go configure the site to block comments here..)
+"""]]
diff --git a/doc/copies.mdwn b/doc/copies.mdwn
new file mode 100644
index 000000000..93cbd8ea8
--- /dev/null
+++ b/doc/copies.mdwn
@@ -0,0 +1,38 @@
+Annexed data is stored inside your git repository's `.git/annex` directory.
+Some [[special_remotes]] can store annexed data elsewhere.
+
+It's important that data not get lost by an ill-considered `git annex drop`
+command. So, git-annex can be configured to try
+to keep N copies of a file's content available across all repositories.
+(Although [[untrusted_repositories|trust]] don't count toward this total.)
+
+By default, N is 1; it is configured by annex.numcopies. This default
+can be overridden on a per-file-type basis by the annex.numcopies
+setting in `.gitattributes` files. The --numcopies switch allows
+temporarily using a different value.
+
+`git annex drop` attempts to check with other git remotes, to check that N
+copies of the file exist. If enough repositories cannot be verified to have
+it, it will retain the file content to avoid data loss. Note that
+[[trusted_repositories|trust]] are not explicitly checked.
+
+For example, consider three repositories: Server, Laptop, and USB. Both Server
+and USB have a copy of a file, and N=1. If on Laptop, you `git annex get
+$file`, this will transfer it from either Server or USB (depending on which
+is available), and there are now 3 copies of the file.
+
+Suppose you want to free up space on Laptop again, and you `git annex drop` the file
+there. If USB is connected, or Server can be contacted, git-annex can check
+that it still has a copy of the file, and the content is removed from
+Laptop. But if USB is currently disconnected, and Server also cannot be
+contacted, it can't verify that it is safe to drop the file, and will
+refuse to do so.
+
+With N=2, in order to drop the file content from Laptop, it would need access
+to both USB and Server.
+
+Note that different repositories can be configured with different values of
+N. So just because Laptop has N=2, this does not prevent the number of
+copies falling to 1, when USB and Server have N=1. To avoid this,
+configure it in `.gitattributes`, which is shared between repositories
+using git.
diff --git a/doc/copies/comment_1_af9bee33777fb8a187b714fc8c5fb11d._comment b/doc/copies/comment_1_af9bee33777fb8a187b714fc8c5fb11d._comment
new file mode 100644
index 000000000..45e572260
--- /dev/null
+++ b/doc/copies/comment_1_af9bee33777fb8a187b714fc8c5fb11d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://olivier.berger.myopenid.com/"
+ nickname="obergix"
+ subject="See also section on backups in walthroug"
+ date="2013-08-25T05:37:04Z"
+ content="""
+See also [walthrough/backups](/walkthrough/backups/) for some details about copies.
+"""]]
diff --git a/doc/design.mdwn b/doc/design.mdwn
new file mode 100644
index 000000000..9a03e7554
--- /dev/null
+++ b/doc/design.mdwn
@@ -0,0 +1,8 @@
+git-annex's high-level design is mostly inherent in the data that it
+stores in git, and alongside git. See [[internals]] for details.
+
+See [[encryption]] for design of encryption elements.
+
+See [[roadmap]] for planning and scheduling of new stuff.
+
+See [[assistant]] for the design site for the git-annex [[/assistant]].
diff --git a/doc/design/assistant.mdwn b/doc/design/assistant.mdwn
new file mode 100644
index 000000000..daf6fce0b
--- /dev/null
+++ b/doc/design/assistant.mdwn
@@ -0,0 +1,45 @@
+These are the design pages for the git-annex [[/assistant]].
+
+Parts of the design is still being fleshed out, still many ideas
+and use cases to add. Feel free to chip in with comments! --[[Joey]]
+
+See [[roadmap]] for current plans.
+
+## initial development kickstarter year overview (2012-2013)
+
+* Month 1 "like dropbox": [[!traillink inotify]] [[!traillink syncing]]
+* Month 2 "shiny webapp": [[!traillink webapp]] [[!traillink progressbars]]
+* Month 3 "easy setup": [[!traillink configurators]] [[!traillink pairing]]
+* Month 4 "cloud": [[!traillink cloud]] [[!traillink transfer_control]]
+* Month 5 "cloud continued": [[!traillink xmpp]] [[!traillink more_cloud_providers]]
+* Month 6 "9k bonus round": [[!traillink desymlink]]
+* Month 7: user-driven features and polishing;
+ [presentation at LCA2013](http://mirror.linux.org.au/linux.conf.au/2013/mp4/gitannex.mp4)
+* Month 8: [[!traillink Android]]
+* Month 9: [[screencasts|videos]] and polishing
+* Month 10: bugfixing, [[Android]] webapp
+* Month 11: [[!traillink Windows]] porting, finishing touches
+* Month 12: [presentation at SELF2013](http://www.southeastlinuxfest.org/), finishing touches
+
+## porting
+
+* [[OSX]] port is in fairly good shape, but still has some room for improvement
+* [[android]] port is zooming along
+* [[Windows]] port is barely getting started
+
+## not yet on the map:
+
+* [[rate_limiting]]
+* [[partial_content]]
+* [[deltas]]
+* [[leftovers]]
+* [[other todo items|todo]]
+
+## polls
+
+I post [[polls]] occasionally to make decisions. You can vote!
+
+## blog
+
+I'm blogging about my progress in the [[devblog]] on a semi-daily basis.
+Follow along!
diff --git a/doc/design/assistant/OSX.mdwn b/doc/design/assistant/OSX.mdwn
new file mode 100644
index 000000000..400e517bf
--- /dev/null
+++ b/doc/design/assistant/OSX.mdwn
@@ -0,0 +1,13 @@
+Misc OSX porting things:
+
+* autostart the assistant on OSX, using launchd **done**
+* icon to start webapp **done**
+* use FSEvents to detect file changes (better than kqueue) **done**
+* Use OSX's "network reachability functionality" to detect when on a network
+ <http://developer.apple.com/library/mac/#documentation/Networking/Conceptual/SystemConfigFrameworks/SC_Intro/SC_Intro.html#//apple_ref/doc/uid/TP40001065>
+* Switch from gpg to <https://gpgtools.org/>. According to a user,
+ this is better because it can show a dialog window for password prompts.
+
+Bugs:
+
+[[!inline pages="tagged(design/assistant/OSX) and !link(bugs/done)" show=0 archive=yes]]
diff --git a/doc/design/assistant/OSX/comment_1_9290f6e6f265e906b08631224392b7bf._comment b/doc/design/assistant/OSX/comment_1_9290f6e6f265e906b08631224392b7bf._comment
new file mode 100644
index 000000000..633dd01b4
--- /dev/null
+++ b/doc/design/assistant/OSX/comment_1_9290f6e6f265e906b08631224392b7bf._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlu-fdXIt_RF9ggvg4zP0yBbtjWQwHAMS4"
+ nickname="Jörn"
+ subject="Mount detection"
+ date="2012-09-21T09:23:34Z"
+ content="""
+regarding the current mount polling on OSX: why not use the NSNotificationCenter for being notified on mount events on OSX?
+
+Details see:
+
+1. <http://stackoverflow.com/questions/12409458/detect-when-a-volume-is-mounted-on-os-x>
+2. <http://stackoverflow.com/questions/6062299/how-to-add-an-observer-to-nsnotificationcenter-in-a-c-class-using-objective-c>
+3. <https://developer.apple.com/library/mac/#documentation/CoreFoundation/Reference/CFNotificationCenterRef/Reference/reference.html#//apple_ref/doc/uid/20001438>
+"""]]
diff --git a/doc/design/assistant/android.mdwn b/doc/design/assistant/android.mdwn
new file mode 100644
index 000000000..8beaffabc
--- /dev/null
+++ b/doc/design/assistant/android.mdwn
@@ -0,0 +1,42 @@
+The Android port is just about usable. Still, we have some fun todo items
+to improve it.
+
+## high-priority TODO
+
+* [[bugs/Android_app_permission_denial_on_startup]]
+* S3 doesn't work (at least to Internet Archive:
+ "connect: does not exist (connection refused)")
+* Get app into Google Play and/or FDroid
+
+## TODO
+
+* Don't make app initially open terminal + webapp, but go to a page that
+ allows opening the webapp or terminal.
+ Possibly, switch from running inside terminal app to real standalone app.
+ See <https://github.com/neurocyte/android-haskell-activity>
+ and <https://github.com/neurocyte/foreign-jni>.
+
+* I have seen an assistant thread crash with an interrupted system call
+ when the device went to sleep while it was running. Auto-detect and deal with
+ that somehow.
+* Make git stop complaining that "warning: no threads uspport, ignoring --threads"
+* git does not support http remotes. To fix, need to port libcurl and
+ allow git to link to it.
+* getEnvironment is broken on Android <https://github.com/neurocyte/ghc-android/issues/7>
+ and a few places use it. I have some horrible workarounds in place.
+* Get local pairing to work. network-multicast and network-info don't
+ currently install.
+* Get test suite to pass. `git clone` of a local repo fails on android
+ for some reason.
+* Make app autostart on boot, optionally. <http://stackoverflow.com/questions/1056570/how-to-autostart-an-android-application>
+* The app should be aware of power status, and avoid expensive background
+ jobs when low on battery or run flat out when plugged in.
+* The app should be aware of network status, and avoid expensive data
+ transfers when not on wifi. This may need to be configurable.
+* glacier and local pairing are not yet enabled for Android.
+* The "Files" link doesn't start a file browser. Should be possible to do
+ on Android via intents, I suppose?
+* Adding removable drives would work, but the android app is not in the
+ appropriate group to write to them. `WRITE_MEDIA_STORAGE` permission
+ needed. Added to AndroidManifest, but did not seem to be used.
+ Googleing for it will find a workaround that needs a rooted device.
diff --git a/doc/design/assistant/android/comment_10_316bde8d22628e5e9d4f8dabce1d2ad4._comment b/doc/design/assistant/android/comment_10_316bde8d22628e5e9d4f8dabce1d2ad4._comment
new file mode 100644
index 000000000..89f23d72c
--- /dev/null
+++ b/doc/design/assistant/android/comment_10_316bde8d22628e5e9d4f8dabce1d2ad4._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="Xyem"
+ ip="87.194.19.134"
+ subject="comment 10"
+ date="2013-05-06T12:18:39Z"
+ content="""
+One of the points is:
+
+* The app should be aware of power status, and avoid expensive background jobs when low on battery or run flat out when plugged in.
+
+This isn't good for situations where the device is plugged in and charging, but will only be so for a limited time (such as charging during a car journey) as the device would charge slower.
+
+Could this behaviour be configurable too?
+"""]]
diff --git a/doc/design/assistant/android/comment_1_8be9a74e5fc4641c2bf2e1bb7673dd59._comment b/doc/design/assistant/android/comment_1_8be9a74e5fc4641c2bf2e1bb7673dd59._comment
new file mode 100644
index 000000000..389eac026
--- /dev/null
+++ b/doc/design/assistant/android/comment_1_8be9a74e5fc4641c2bf2e1bb7673dd59._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://launchpad.net/~gdr-go2"
+ nickname="gdr-go2"
+ subject="FAT symlinks"
+ date="2012-05-28T18:12:10Z"
+ content="""
+It's a linux kernel so perhaps another option would be to create a big file and mount -o loop
+"""]]
diff --git a/doc/design/assistant/android/comment_2_3dd386ac1b757c73d14f14377b9eedd4._comment b/doc/design/assistant/android/comment_2_3dd386ac1b757c73d14f14377b9eedd4._comment
new file mode 100644
index 000000000..3ff46ca06
--- /dev/null
+++ b/doc/design/assistant/android/comment_2_3dd386ac1b757c73d14f14377b9eedd4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlhIMPGF1E0XEJKV6j6-PFzAxA1-nIlydo"
+ nickname="Bernhard"
+ subject="re @ gdr-go2 "
+ date="2012-09-10T19:34:00Z"
+ content="""
+`mount` requires root and you'll have still the 4gb limit for your image by FAT. some phones (e.g. galaxy nexus) already use `ext4` for `/sdcard` though.
+"""]]
diff --git a/doc/design/assistant/android/comment_3_5dca47a4599d6e88d19193701c5a571b._comment b/doc/design/assistant/android/comment_3_5dca47a4599d6e88d19193701c5a571b._comment
new file mode 100644
index 000000000..8f60efdb0
--- /dev/null
+++ b/doc/design/assistant/android/comment_3_5dca47a4599d6e88d19193701c5a571b._comment
@@ -0,0 +1,46 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlhIMPGF1E0XEJKV6j6-PFzAxA1-nIlydo"
+ nickname="Bernhard"
+ subject="GHC and Android"
+ date="2012-09-10T21:58:28Z"
+ content="""
+I played around a bit with GHC and Android today. It isn't really a result, but maybe useful for someone out there.
+
+I have a Debian `chroot` environment on my Android device (howto: <http://www.saurik.com/id/10/>). In the Debian box:
+
+ $ cat arm.hs
+ main = do
+ putStrLn \"Hello ARM\"
+ $ ghc -static --make arm.hs
+ Linking arm ...
+ $ ldd arm
+ libgmp.so.3 => /usr/lib/libgmp.so.3 (0x40233000)
+ libm.so.6 => /lib/libm.so.6 (0x400c8000)
+ libffi.so.5 => /usr/lib/libffi.so.5 (0x401b1000)
+ librt.so.1 => /lib/librt.so.1 (0x40171000)
+ libdl.so.2 => /lib/libdl.so.2 (0x40180000)
+ libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x4018b000)
+ libc.so.6 => /lib/libc.so.6 (0x40282000)
+ /lib/ld-linux.so.3 (0x400a2000)
+ libpthread.so.0 => /lib/libpthread.so.0 (0x4007e000)
+
+well, that isn't really static. tell the linker to build a static binary (those are arguments to `ld`):
+
+ $ ghc --make arm.hs -optl-static -optl-pthread
+ [1 of 1] Compiling Main ( arm.hs, arm.o )
+ Linking arm ...
+ $ file arm
+ arm: ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, for GNU/Linux 2.6.18, not stripped
+ $ ldd arm
+ not a dynamic executable
+ $ ./arm
+ Hello ARM
+
+now, get this (quite big) binary into the normal android environment, using `adb`, `SSHDroid` or whatever:
+
+ % cd /data/local/tmp # assuming destination of file transfer
+ % ./arm
+ arm: mkTextEncoding: invalid argument (Invalid argument)
+
+looking in the source of `System.IO` it seems like an `iconv` issue. So, there's still some dynamic dependency in there... *sigh*
+"""]]
diff --git a/doc/design/assistant/android/comment_4_054f06311e2b51d73be569f181eb004f._comment b/doc/design/assistant/android/comment_4_054f06311e2b51d73be569f181eb004f._comment
new file mode 100644
index 000000000..76c32908a
--- /dev/null
+++ b/doc/design/assistant/android/comment_4_054f06311e2b51d73be569f181eb004f._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.30"
+ subject="comment 4"
+ date="2012-09-11T02:12:45Z"
+ content="""
+Thanks Bernard, that's really massively useful. It makes sense -- statically building with libc should work, the Android kernel is still Linux after all.
+
+To get past the iconv problem, I think all you need is part of the `locales` package from your linux system installed on the Android. Probably just a few of the data files from /usr/share/i18n/charmaps/
+"""]]
diff --git a/doc/design/assistant/android/comment_5_bb3d36e9d29f2fa77bee6d47ef9917fe._comment b/doc/design/assistant/android/comment_5_bb3d36e9d29f2fa77bee6d47ef9917fe._comment
new file mode 100644
index 000000000..be1e3e9e8
--- /dev/null
+++ b/doc/design/assistant/android/comment_5_bb3d36e9d29f2fa77bee6d47ef9917fe._comment
@@ -0,0 +1,21 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlhIMPGF1E0XEJKV6j6-PFzAxA1-nIlydo"
+ nickname="Bernhard"
+ subject="comment 5"
+ date="2012-09-11T09:34:42Z"
+ content="""
+`/usr/share/i18n/` does not exists on my Debian ARM system :/
+
+however, `strace ./arm` in the debian chroot reveals that some files from `/usr/lib/gconv/` are loaded:
+
+ [...]
+ open(\"/usr/lib/gconv/UTF-32.so\", O_RDONLY) = 3
+ read(3, \"\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\4\4\0\0004\0\0\0\"..., 512) = 512
+ [...]
+
+full log: <http://wien.tomnetworks.com/strace_arm>. Unfortunately, I don't have `strace` in the android userland for comparison.
+
+Just copying the related `gconv` files didn't work. I don't have so much time at the moment, I'll investigate further in some days or so.
+
+At least, output using `error :: String -> a` does work :-)
+"""]]
diff --git a/doc/design/assistant/android/comment_6_fee32a831eeb5736fe1dce52e30320c8._comment b/doc/design/assistant/android/comment_6_fee32a831eeb5736fe1dce52e30320c8._comment
new file mode 100644
index 000000000..9dfe5670d
--- /dev/null
+++ b/doc/design/assistant/android/comment_6_fee32a831eeb5736fe1dce52e30320c8._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 6"
+ date="2012-10-30T08:44:32Z"
+ content="""
+Just so this does not get lost: For better or for worse, the vanilla Android devices stopped shipping with micro-SD support in 2011 (or 2010 if the Nexus S does not support them either; on sketchy GPRS so not googling around). Most higher-end Android devices ship with at least 8 GiB of on-board Flash storage, some even go up to 64 GiB.
+
+IMHO, this would make it viable to first get git-annex working on Android without regard for FAT.
+
+The obvious advantage is that porting should be easier and quicker.
+
+The obvious downside is that this may mean revisiting some parts of the code later.
+
+-- Richard
+"""]]
diff --git a/doc/design/assistant/android/comment_7_d8e9b0a5287fc96b19dc2cb9da3586ce._comment b/doc/design/assistant/android/comment_7_d8e9b0a5287fc96b19dc2cb9da3586ce._comment
new file mode 100644
index 000000000..0419b1d1b
--- /dev/null
+++ b/doc/design/assistant/android/comment_7_d8e9b0a5287fc96b19dc2cb9da3586ce._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 7"
+ date="2012-10-30T08:51:17Z"
+ content="""
+Actually, this is something that would be ideal for a poll:
+
+Should FAT-based Android repos be implemented:
+
+* Immediately
+* After the initial release of the Android app is working
+* Before the kickstarter ends
+* Not at all
+
+Also, as another data point, the FAT-based SD card can be mounted as USB storage by any computer an Android device is connected to whereas the EXT4-based root FS can only be accessed via MTP.
+"""]]
diff --git a/doc/design/assistant/android/comment_8_79a7b5bb5f4aaeea4a4e8ced0561701a._comment b/doc/design/assistant/android/comment_8_79a7b5bb5f4aaeea4a4e8ced0561701a._comment
new file mode 100644
index 000000000..91db74ec6
--- /dev/null
+++ b/doc/design/assistant/android/comment_8_79a7b5bb5f4aaeea4a4e8ced0561701a._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnZEanlyzay_QlEAL0CWpyZcRTyN7vay8U"
+ nickname="Carlo"
+ subject="Terminal IDE"
+ date="2012-11-21T21:46:19Z"
+ content="""
+I use Terminal IDE on android, which is 'sort of a shell environment'.
+
+It has bash, git, dropbear ssh, and vim. It is a bit limited, but it does feel like a linux shell.
+
+"""]]
diff --git a/doc/design/assistant/android/comment_9_55ea70a6929523d26248ff6409b04a6e._comment b/doc/design/assistant/android/comment_9_55ea70a6929523d26248ff6409b04a6e._comment
new file mode 100644
index 000000000..d371c5fed
--- /dev/null
+++ b/doc/design/assistant/android/comment_9_55ea70a6929523d26248ff6409b04a6e._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl7ciFZWmffuw6sLRww3CcL_F5ItsttL9w"
+ nickname="Aaron"
+ subject="Feature request: Events triggered on wifi SSID or connection state"
+ date="2013-01-08T13:04:05Z"
+ content="""
+I'd like to have my phone sync a bunch of files when I'm at home and when I get to work, have them synced to my work machine, deleted off my phone and when I get home, also deleted off my home machine.
+
+This will allow incremental backups to a local folder at home and I can then \"mule\" my files, sneaker-net style, to work with zero user intervention. It only works if events can be triggered or I can combine a triggering app with a special android intent for both ends of my trip.
+"""]]
diff --git a/doc/design/assistant/blog.mdwn b/doc/design/assistant/blog.mdwn
new file mode 100644
index 000000000..561173d27
--- /dev/null
+++ b/doc/design/assistant/blog.mdwn
@@ -0,0 +1,11 @@
+This blog was updated on a semi-daily basis by Joey during the year of work
+concentrating on the git-annex assistant that was funded by his kickstarter
+campaign.
+
+Post-kickstarter work will instead appear on the [[devblog]]. However,
+this page's RSS feed will continue to work, so you don't have to migrate
+your RSS reader.
+
+[[!inline pages="page(devblog/*)" show=-1 feedshow=7]]
+
+[[!inline pages="page(design/assistant/blog/*)" show=0 feeds=no]]
diff --git a/doc/design/assistant/blog/day_100__cursed_clouds.mdwn b/doc/design/assistant/blog/day_100__cursed_clouds.mdwn
new file mode 100644
index 000000000..7ac38f463
--- /dev/null
+++ b/doc/design/assistant/blog/day_100__cursed_clouds.mdwn
@@ -0,0 +1,19 @@
+Preferred content control is wired up to `--auto` and working for `get`,
+`copy`, and `drop`. Note that `drop --from remote --auto` drops files that
+the remote's preferred content settings indicate it doesn't want;
+likewise `copy --to remote --auto` sends content that the remote does want.
+
+Also implemented `smallerthan`, `largerthan`, and `ingroup` limits,
+which should be everything needed for the scenarios described in
+[[transfer_control]].
+
+Dying to hook this up to the assistant, but a cloudy day is forcing me to
+curtail further computer use.
+
+----
+
+Also, last night I developed a patch for the hS3 library, that should let
+git-annex upload large files to S3 without buffering their whole content in
+memory. I have a `s3-memory-leak` in git-annex that uses the new API I
+developed. Hopefully hS3's maintainer will release a new version with that
+soon.
diff --git a/doc/design/assistant/blog/day_102__very_high_level_programming.mdwn b/doc/design/assistant/blog/day_102__very_high_level_programming.mdwn
new file mode 100644
index 000000000..4e29cc65d
--- /dev/null
+++ b/doc/design/assistant/blog/day_102__very_high_level_programming.mdwn
@@ -0,0 +1,37 @@
+## today
+
+Came up with four groups of repositories that it makes sense to
+define standard preferred content expressions for.
+
+[[!format haskell """
+ preferredContent :: StandardGroup -> String
+ preferredContent ClientGroup = "exclude=*/archive/*"
+ preferredContent TransferGroup = "not inallgroup=client and " ++ preferredContent ClientGroup
+ preferredContent ArchiveGroup = "not copies=archive:1"
+ preferredContent BackupGroup = "" -- all content is preferred
+"""]]
+
+[[preferred_content]] has the details about these groups, but
+as I was writing those three preferred content expressions,
+I realized they are some of the highest level programming I've ever done,
+in a way.
+
+Anyway, these make for a very simple repository configuration UI:
+
+[[!img /assistant/repogroups.png alt="form with simple select box"]]
+
+## yesterday (forgot to post this)
+
+Got the assistant honoring preferred content settings. Although so far that
+only determines what it transfers. Additional work will be needed to make
+content be dropped when it stops being preferred.
+
+----
+
+Added a "configure" link next to each repository on the repository config
+page. This will go to a form to allow setting things like repository
+descriptions, groups, and preferred content settings.
+
+----
+
+Cut a release.
diff --git a/doc/design/assistant/blog/day_102__very_high_level_programming/comment_1_c028b403261dd66bcf83e6ffd134b80b._comment b/doc/design/assistant/blog/day_102__very_high_level_programming/comment_1_c028b403261dd66bcf83e6ffd134b80b._comment
new file mode 100644
index 000000000..d9be239bd
--- /dev/null
+++ b/doc/design/assistant/blog/day_102__very_high_level_programming/comment_1_c028b403261dd66bcf83e6ffd134b80b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlVwbp82f-7rNOyEpvqc9A8FEfn7wl2Akw"
+ nickname="Jos"
+ subject="Works for me"
+ date="2012-10-11T13:40:08Z"
+ content="""
+These categories make it much clearer to me how I will be able to use git annex assistant
+"""]]
diff --git a/doc/design/assistant/blog/day_103__bugfix_day.mdwn b/doc/design/assistant/blog/day_103__bugfix_day.mdwn
new file mode 100644
index 000000000..7c08a2065
--- /dev/null
+++ b/doc/design/assistant/blog/day_103__bugfix_day.mdwn
@@ -0,0 +1,25 @@
+Bugfixes all day.
+
+The most amusing bug, which I just stumbled over randomly on my own,
+after someone on IRC yesterday was possibly encountering the same issue,
+made `git annex webapp` go into an infinite memory-consuming loop on
+startup if the repository it had been using was no longer a valid git
+repository.
+
+Then there was the place where HOME got unset, with also sometimes amusing
+results.
+
+Also fixed several build problems, including a threaded runtime hang
+in the test suite. Hopefully the next release will build on all Debian
+architectures again.
+
+I'll be cutting that release tomorrow. I also updated the linux
+prebuilt tarballs today.
+
+----
+
+Hmm, not entirely bugfixes after all. Had time (and power) to work
+on the repository configuration form too, and added a check box to it that
+can be unchecked to disable syncing with a repository.
+Also, made that form be displayed after the webapp creates a new
+repository.
diff --git a/doc/design/assistant/blog/day_104__misc.mdwn b/doc/design/assistant/blog/day_104__misc.mdwn
new file mode 100644
index 000000000..bda802bfe
--- /dev/null
+++ b/doc/design/assistant/blog/day_104__misc.mdwn
@@ -0,0 +1,18 @@
+Switched the OSX standalone app to use `DYLD_ROOT_PATH`.
+This is the third `DYLD_*` variable I've tried; neither
+of the other two worked in all situations. This one may do better.
+If not, I may be stuck modifying the library names in each executable
+using `install_name_tool`
+([good reference for doing that](http://www.mikeash.com/pyblog/friday-qa-2009-11-06-linking-and-install-names.html)).
+As far as I know, every existing dynamic library lookup system is broken
+in some way other other; nothing I've seen about OSX's so far
+disproves that rule.
+
+Fixed a nasty utf-8 encoding crash that could occur when merging the
+git-annex branch. I hope I'm almost done with those.
+
+Made git-annex auto-detect when a git remote is on a sever like github
+that doesn't support git-annex, and automatically set annex-ignore.
+
+Finished the UI for pausing syncing of a remote. Making the syncing
+actually stop still has some glitches to resolve.
diff --git a/doc/design/assistant/blog/day_104__misc/comment_1_13d7fad2d3f8eab10314784c035e2a16._comment b/doc/design/assistant/blog/day_104__misc/comment_1_13d7fad2d3f8eab10314784c035e2a16._comment
new file mode 100644
index 000000000..67e342a4b
--- /dev/null
+++ b/doc/design/assistant/blog/day_104__misc/comment_1_13d7fad2d3f8eab10314784c035e2a16._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmubB1Sj2rwFoVdZYvGV0ACaQUJQyiJXJI"
+ nickname="Paul"
+ subject="Thank you for stickers"
+ date="2012-10-14T13:59:55Z"
+ content="""
+Mail received in Finland.
+"""]]
diff --git a/doc/design/assistant/blog/day_105__lazy_Sunday.mdwn b/doc/design/assistant/blog/day_105__lazy_Sunday.mdwn
new file mode 100644
index 000000000..eb25ddace
--- /dev/null
+++ b/doc/design/assistant/blog/day_105__lazy_Sunday.mdwn
@@ -0,0 +1,43 @@
+Did a fair amount of testing and bug fixing today.
+
+There is still some buggy behavior around pausing syncing to a remote,
+where transfers still happen to it, but I fixed the worst bug there.
+
+Noticed that if a non-bare repo is set up on a removable drive,
+its file tree will not normally be updated as syncs come in -- because the
+assistant is not running on that repo, and so incoming syncs are not
+merged into the local master branch. For now I made it always use bare
+repos on removable drives, but I may want to revisit this.
+
+The repository edit form now has a field for the name of the repo,
+so the ugly names that the assistant comes up with for ssh remotes
+can be edited as you like. `git remote rename` is a very nice thing.
+
+Changed the preferred content expression for transfer repos to this:
+"not (inallgroup=client **and copies=client:2)**". This way, when there's
+just one client, files on it will be synced to transfer repos, even
+though those repos have no other clients to transfer them to. Presumably,
+if a transfer repo is set up, more clients are coming soon, so this avoids
+a wait. Particularly useful with removable drives, as the drive will start
+being filled as soon as it's added, and can then be brought to a client
+elsewhere. The "2" does mean that, once another client is found,
+the data on the transfer repo will be dropped, and so if it's brought
+to yet another new client, it won't have data for it right away.
+I can't see way to generalize this workaround to more than 2 clients;
+the transfer repo has to start dropping apparently unwanted content at
+some point. Still, this will avoid a potentially very confusing behavior
+when getting started.
+
+----
+
+I need to get that dropping of non-preferred content to happen still.
+Yesterday, I did some analysis of all the events that can cause previously
+preferred content to no longer be preferred, so I know all the places
+I have to deal with this.
+
+The one that's giving me some trouble is checking in the transfer scan. If it
+checks for content to drop at the same time as content to transfer, it could
+end up doing a lot of transfers before dropping anything. It'd be nicer to
+first drop as much as it can, before getting more data, so that transfer
+remotes stay as small as possible. But the scan is expensive, and it'd also
+be nice not to need two passes.
diff --git a/doc/design/assistant/blog/day_106__lazy_Monday.mdwn b/doc/design/assistant/blog/day_106__lazy_Monday.mdwn
new file mode 100644
index 000000000..84b96f635
--- /dev/null
+++ b/doc/design/assistant/blog/day_106__lazy_Monday.mdwn
@@ -0,0 +1,10 @@
+I was mostly working on other things today, but I did do some bug fixing.
+The worst of these is a bug introduced in 3.20121009 that breaks
+`git-annex-shell configlist`. That's pretty bad for using git-annex
+on servers, although you mostly won't notice unless you're just getting
+started using a ssh remote, since that's when it calls configlist.
+I will be releasing a new version as soon as I have bandwidth (tomorrow).
+
+Also made the standalone Linux and OSX binaries build with ssh connection
+caching disabled, since they don't bundle their own ssh and need to work
+with whatever ssh is installed.
diff --git a/doc/design/assistant/blog/day_107__memory_leak.mdwn b/doc/design/assistant/blog/day_107__memory_leak.mdwn
new file mode 100644
index 000000000..e33008f97
--- /dev/null
+++ b/doc/design/assistant/blog/day_107__memory_leak.mdwn
@@ -0,0 +1,11 @@
+More bugfixes today. The assistant now seems to have enough users that
+they're turning up interesting bugs, which is good. But does keep me too
+busy to add many more bugs\^Wcode.
+
+The fun one today made it bloat to eat all memory when logging out of a
+Linux desktop. I tracked that back to a bug in the Haskell DBUS library
+when a session connection is open and the session goes away. Developed a
+test case, and even profiled it, and sent it all of to the library's
+author. Hopefully there will be a quick fix, in the meantime today's
+release has DBUS turned off. Which is ok, it just makes it a little bit
+slower to notice some events.
diff --git a/doc/design/assistant/blog/day_108__another_zombie_outbreak.mdwn b/doc/design/assistant/blog/day_108__another_zombie_outbreak.mdwn
new file mode 100644
index 000000000..ee46073bd
--- /dev/null
+++ b/doc/design/assistant/blog/day_108__another_zombie_outbreak.mdwn
@@ -0,0 +1,33 @@
+I released git-annex an unprecidented two times yesterday, because just
+after the first release, I learned of a another zombie problem. Turns out
+this zombie had existed for a while, but it was masked by zombie reaping
+code that I removed recently, after fixing most of the other zombie
+problems. This one, though, is not directly caused by git-annex. When rsync
+runs ssh, it seems to run two copies, and one is left unwaited on as a
+zombie. Oddly, this only happens when rsync's stdout is piped into
+git-annex, for progress bar handling. I have not source-dived rsync's code
+to get to the bottom of this, but I put in a workaround.
+
+I did get to the bottom of yesterday's runaway dbus library. Got lucky and
+found the cause of the memory leak in that library on the first try, which
+is nice since each try involved logging out of X. I've been corresponding
+with its author, and a fix will be available soon, and then git-annex will
+need some changes to handle dbus reconnection.
+
+-----
+
+For the first time, I'm starting to use the assistant on my own personal
+git-annex repo. The preferred content and group settings let me configure it
+use the complex system of partial syncing I need. For example, I have this
+configured for my sound files, keeping new podcasts on a server until they land
+somewhere near me. And keeping any sound files that I've manually put on my
+laptop, and syncing new podcasts, but not other stuff.
+
+ # (for my server)
+ preferred-content 87e06c7a-7388-11e0-ba07-03cdf300bd87 = include=podcasts/* and (not copies=nearjoey:1)
+ # (for my laptop)
+ preferred-content 0c443de8-e644-11df-acbf-f7cd7ca6210d = exclude=*/out/* and (in=here or (include=podcasts/*))
+
+Found and fixed a bug in the preferred content matching code, where
+if the assistant was run in a subdirectory of the repo, it failed to
+match files correctly.
diff --git a/doc/design/assistant/blog/day_108__another_zombie_outbreak/comment_1_194c48d65993462f809a2cfaa774a3e2._comment b/doc/design/assistant/blog/day_108__another_zombie_outbreak/comment_1_194c48d65993462f809a2cfaa774a3e2._comment
new file mode 100644
index 000000000..690d59d17
--- /dev/null
+++ b/doc/design/assistant/blog/day_108__another_zombie_outbreak/comment_1_194c48d65993462f809a2cfaa774a3e2._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://a-or-b.myopenid.com/"
+ ip="203.45.2.230"
+ subject="comment 1"
+ date="2012-10-19T01:21:42Z"
+ content="""
+Can you elaborate on the \"nearjoey\" option below?
+> (not copies=nearjoey:1)
+
+Are you able to assign a \"nearjoey\" flag to multiple annexes?
+"""]]
diff --git a/doc/design/assistant/blog/day_108__another_zombie_outbreak/comment_2_ef5ee5933fcadcb81cc81b816db14bda._comment b/doc/design/assistant/blog/day_108__another_zombie_outbreak/comment_2_ef5ee5933fcadcb81cc81b816db14bda._comment
new file mode 100644
index 000000000..0da13b735
--- /dev/null
+++ b/doc/design/assistant/blog/day_108__another_zombie_outbreak/comment_2_ef5ee5933fcadcb81cc81b816db14bda._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.23"
+ subject="comment 2"
+ date="2012-10-19T17:07:08Z"
+ content="""
+Yes, using the group command.
+"""]]
diff --git a/doc/design/assistant/blog/day_109__dropping.mdwn b/doc/design/assistant/blog/day_109__dropping.mdwn
new file mode 100644
index 000000000..210f71f55
--- /dev/null
+++ b/doc/design/assistant/blog/day_109__dropping.mdwn
@@ -0,0 +1,16 @@
+Got unwanted content to be dropped from the local repo, as well as remotes
+when doing the expensive scan. I kept the scan a single pass for now,
+need to revisit that later to drop content before transferring more.
+Also, when content is downloaded or uploaded, this can result in it
+needing to be dropped from somewhere, and the assistant handles that too.
+
+There are some edge cases with hypothetical, very weird preferred
+content expressions, where the assistant won't drop content right away.
+(But will later in the expensive scan.) Other than those, I think I have
+nearly all content dropping sorted out. The only common case I know of where
+unwanted content is not dropped by the assistant right away is when a file
+is renamed (eg, put in a "Trash" directory).
+
+In other words, repositories put into the transfer group will now work as
+described, only retaining content as long as is needed to distribute it to
+clients. Big milestone!
diff --git a/doc/design/assistant/blog/day_10__lsof.mdwn b/doc/design/assistant/blog/day_10__lsof.mdwn
new file mode 100644
index 000000000..d4217677f
--- /dev/null
+++ b/doc/design/assistant/blog/day_10__lsof.mdwn
@@ -0,0 +1,54 @@
+A rather frustrating and long day coding went like this:
+
+## 1-3 pm
+
+Wrote a single function, of which all any Haskell programmer needs to know
+is its type signature:
+
+ Lsof.queryDir :: FilePath -> IO [(FilePath, LsofOpenMode, ProcessInfo)]
+
+When I'm spending another hour or two taking a unix utility like lsof and
+parsing its output, which in this case is in a rather complicated
+machine-parsable output format, I often wish unix streams were strongly
+typed, which would avoid this bother.
+
+## 3-9 pm
+
+Six hours spent making it defer annexing files until the commit thread
+wakes up and is about to make a commit. Why did it take so horribly long?
+Well, there were a number of complications, and some really bad bugs
+involving races that were hard to reproduce reliably enough to deal with.
+
+In other words, I was lost in the weeds for a lot of those hours...
+
+At one point, something glorious happened, and it was always making exactly
+one commit for batch mode modifications of a lot of files (like untarring
+them). Unfortunately, I had to lose that gloriousness due to another
+potential race, which, while unlikely, would have made the program deadlock
+if it happened.
+
+So, it's back to making 2 or 3 commits per batch mode change. I also have a
+buglet that causes sometimes a second empty commit after a file is added.
+I know why (the inotify event for the symlink gets in late,
+after the commit); will try to improve commit frequency later.
+
+## 9-11 pm
+
+Put the capstone on the day's work, by calling lsof on a directory full
+of hardlinks to the files that are about to be annexed, to check if any
+are still open for write.
+
+This works great! Starting up `git annex watch` when processes have files
+open is no longer a problem, and even if you're evil enough to try having
+multiple processes open the same file, it will complain and not annex it
+until all the writers close it.
+
+(Well, someone really evil could turn the write bit back on after git annex
+clears it, and open the file again, but then really evil people can do
+that to files in `.git/annex/objects` too, and they'll get their just
+deserts when `git annex fsck` runs. So, that's ok..)
+
+----
+
+Anyway, will beat on it more tomorrow, and if all is well, this will finally
+go out to the beta testers.
diff --git a/doc/design/assistant/blog/day_10__lsof/comment_1_9b8c28c85c979f32e5c295b6a03c048e._comment b/doc/design/assistant/blog/day_10__lsof/comment_1_9b8c28c85c979f32e5c295b6a03c048e._comment
new file mode 100644
index 000000000..9d970da22
--- /dev/null
+++ b/doc/design/assistant/blog/day_10__lsof/comment_1_9b8c28c85c979f32e5c295b6a03c048e._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://dieter-be.myopenid.com/"
+ nickname="dieter"
+ subject="comment 1"
+ date="2012-06-16T09:14:26Z"
+ content="""
+maybe at some point, your tool could show \"warning, the following files are still open and are hence not being annexed\"
+to avoid any nasty surprises of a file not being annexed and the user not realizing it.
+"""]]
diff --git a/doc/design/assistant/blog/day_110__more_dropping.mdwn b/doc/design/assistant/blog/day_110__more_dropping.mdwn
new file mode 100644
index 000000000..afa256c77
--- /dev/null
+++ b/doc/design/assistant/blog/day_110__more_dropping.mdwn
@@ -0,0 +1,55 @@
+Got preferred content checked when files are moved around.
+So, in repositories in the default client group, if you make a
+"archive" directory and move files to it, the assistant will drop
+their content (when possible, ie when it's reached an archive or backup).
+Move a file out of an archive directory, and the assistant will get its
+content again. Magic.
+
+Found an intractable bug, obvious in retrospect, with the git-annex branch
+read cache, and had to remove that cache. I have not fully determined
+if this will slow down git-annex in some use cases; might need to add more
+higher-level caching. It was a very minimal cache anyway, just of one file.
+
+Removed support for "in=" from preferred content expressions. That was
+problimatic in two ways. First, it referred to a remote by name, but
+preferred content expressions can be evaluated elsewhere, where that remote
+doesn't exist, or a different remote has the same name. This name lookup
+code could error out at runtime. Secondly, "in=" seemed pretty useless, and
+indeed counterintuitive in preferred content expressions. "in=here" did not
+cause content to be gotten, but it did let present content be dropped.
+Other uses of "in=" are better handled by using groups.
+
+In place of "in=here", preferred content expressions can now use "present",
+which is useful if you want to disable automatic getting or dropping of
+content in some part of a repository. Had to document that "not present"
+is not a good thing to use -- it's unstable. Still, I find "present" handy
+enough to put up with that wart.
+
+Realized last night that the code I added to the TransferWatcher
+to check preferred content once a transfer is done is subject to a race;
+it will often run before the location log gets updated. Haven't found a good
+solution yet, but this is something I want working now, so I did put in a
+quick delay hack to avoid the race. Delays to avoid races are never a real
+solution, but sometimes you have to TODO it for later.
+
+----
+
+Been thinking about how to make the assistant notice changes to configuration
+in the git-annex branch that are merged in from elsewhere while it's running.
+I'd like to avoid re-reading unchanged configuration files after each merge
+of the branch.
+
+The most efficient way would be to reorganise the git-annex branch, moving
+config files into a configs directory, and logs into a logs directory. Then it
+could `git ls-tree git-annex configs` and check if the sha of the configs
+directory had changed, with git doing minimal work
+(benchmarked at 0.011 seconds).
+
+Less efficiently, keep the current git-annex branch layout, and
+use: `git ls-tree git-annex uuid.log remote.log preferred-content.log group.log trust.log`
+(benchmarked at 0.015 seconds)
+
+Leaning toward the less efficient option, with a rate limiter so it
+doesn't try more often than once every minute. Seems reasonable for it to
+take a minute for config changes take effect on remote repos, even
+if the assistant syncs file changes to them more quickly.
diff --git a/doc/design/assistant/blog/day_111__config_monitor.mdwn b/doc/design/assistant/blog/day_111__config_monitor.mdwn
new file mode 100644
index 000000000..8addf54ae
--- /dev/null
+++ b/doc/design/assistant/blog/day_111__config_monitor.mdwn
@@ -0,0 +1,18 @@
+Added yet another thread, the ConfigMonitor. Since that thread needs to run
+code to reload cached config values from the git-annex branch when files
+there change, writing it also let me review where config files are cached,
+and I found that every single config file in the git-annex branch does
+get cached, with the exception of the uuid.log. So, added a cache for that,
+and now I'm more sanguine about yesterday's removal of the lower-level
+cache, because the only thing not being cached is location log information.
+
+The ConfigMonitor thread seems to work, though I have not tested it
+extensively. The assistant should notice and apply config changes
+made locally, as well as any config changes pushed in from remotes.
+So, for example, if you add a S3 repo in the webapp, and are paired with
+another computer, that one's webapp will shortly include the new repo in
+its list. And all the preferred content, groups, etc settings will
+propigate over and be used as well.
+
+Well ... almost. Seems nothing causes git-annex branch changes to be
+pushed, until there's some file change to sync out.
diff --git a/doc/design/assistant/blog/day_112__and_now_for_something_completely_different.mdwn b/doc/design/assistant/blog/day_112__and_now_for_something_completely_different.mdwn
new file mode 100644
index 000000000..b7d72a275
--- /dev/null
+++ b/doc/design/assistant/blog/day_112__and_now_for_something_completely_different.mdwn
@@ -0,0 +1,50 @@
+Time to solve the assistant's [[cloud]] notification problem. This is
+really the last big road-bump to making it be able to sync computers
+across the big, bad internet.
+
+So, IRC still seems a possibility, but I'm going to try XMPP first. Since
+Google Talk uses XMPP, it should be easy for users to get an account, and
+it's also easy to run your own XMPP server.
+
+Played around with the Haskell XMPP library. Clint helpfully showed me an
+example of a simple client, which helped cut through that library's thicket
+of data types. In short order I had some clients that were able to see each
+other connecting to my personal XMPP server. On to some design..
+
+1. I want to avoid user-visible messages.
+ (dvcs-autosync also uses XMPP, but I checked the code and it
+ seems to send user-visible messages, so I diverge from its lead here.)
+ This seems very possible, only a matter of finding the right
+ way to use the protocol, or an appropriate and widely deployed extension.
+ The only message I need to send with XMPP, really, is "I have pushed to our
+ git repo". One bit of data would do; being able to send a UUID of the repo
+ that did the update would be nice.
+
+2. I'd also like to broadcast my notification to a user's buddies.
+ dvcs-autosync sends only self-messages, but that requires every node
+ have the same XMPP account configured. While I want to be able to run
+ in that mode, I also want to support pairs of users who have their own XMPP
+ accounts, that are buddied up in XMPP.
+
+3. To add to the fun, the assistant's use of XMPP should not make that XMPP
+ account appear active to its buddies. Users should not need a dedicated
+ XMPP account for git-annex, and always seeming to be available when
+ git-annex is running would not be nice.
+
+The first method I'm trying out is to encode the notification
+data inside a XMPP presence broadcast. This should meet all three
+requirements. The plan is two send two
+presence messages, the first marks the client as available, and the second
+as unavailable again.
+The "id" attribute will be set to some
+value generated by the assistant. That attribute is allowed on presence
+messages, and servers are [required to preserve it](http://xmpp.org/rfcs/rfc6121.html#presence-probe-inbound-id)
+while the client is connected.
+(I'd only send unavailable messages, but while
+that worked when I tested it using the prosody server, with google talk,
+repeated unavailable messages were suppressed. Also, google talk does not
+preserve the "id" attribute of unavailable presence messages.)
+
+If this presence hackery doesn't work out, I could try
+[XEP-0163: Personal Eventing Protocol](http://xmpp.org/extensions/xep-0163.html).
+But I like not relying on any extensions.
diff --git a/doc/design/assistant/blog/day_112__and_now_for_something_completely_different/comment_1_5e4fe1538d9ae1c450b0a6602fc6d29b._comment b/doc/design/assistant/blog/day_112__and_now_for_something_completely_different/comment_1_5e4fe1538d9ae1c450b0a6602fc6d29b._comment
new file mode 100644
index 000000000..26514601b
--- /dev/null
+++ b/doc/design/assistant/blog/day_112__and_now_for_something_completely_different/comment_1_5e4fe1538d9ae1c450b0a6602fc6d29b._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmQ4Oe5-qOANRuZel9kDvtBfQG1zlEcIzw"
+ nickname="Dominik"
+ subject="PEP is ok"
+ date="2012-10-24T05:15:38Z"
+ content="""
+PEP and pubsub are really widely used. You will have a hard time finding a server that doesn't support it.
+
+Also note XMPPs ability to send status to only selected buddies and even resources. You can globally appear as offline while sending availability to myownjid@example.com/thatannexthere.
+"""]]
diff --git a/doc/design/assistant/blog/day_112__and_now_for_something_completely_different/comment_2_c5a734f611ecc95729904e645583ee43._comment b/doc/design/assistant/blog/day_112__and_now_for_something_completely_different/comment_2_c5a734f611ecc95729904e645583ee43._comment
new file mode 100644
index 000000000..2b85707a9
--- /dev/null
+++ b/doc/design/assistant/blog/day_112__and_now_for_something_completely_different/comment_2_c5a734f611ecc95729904e645583ee43._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmQ4Oe5-qOANRuZel9kDvtBfQG1zlEcIzw"
+ nickname="Dominik"
+ subject="Remote control clients"
+ date="2012-10-24T05:18:02Z"
+ content="""
+Then of course there is XEP-0146, which has some advantages to it, like controlling annex from the context menu of another Jabber client.
+"""]]
diff --git a/doc/design/assistant/blog/day_112__and_now_for_something_completely_different/comment_3_46b16dcd0fce07036cd8ed6ed9d2b055._comment b/doc/design/assistant/blog/day_112__and_now_for_something_completely_different/comment_3_46b16dcd0fce07036cd8ed6ed9d2b055._comment
new file mode 100644
index 000000000..5c6c161ff
--- /dev/null
+++ b/doc/design/assistant/blog/day_112__and_now_for_something_completely_different/comment_3_46b16dcd0fce07036cd8ed6ed9d2b055._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.23"
+ subject="comment 3"
+ date="2012-10-24T22:44:41Z"
+ content="""
+Google talk does not seem to support PEP. At least, I'm sending something that prosody accepts and that looks like the example at <http://xmpp.org/extensions/xep-0163.html#howitworks>, and it replies with an IQ Error.
+"""]]
diff --git a/doc/design/assistant/blog/day_112__and_now_for_something_completely_different/comment_4_1fe036e4c65fb4211aa2c394f535344a._comment b/doc/design/assistant/blog/day_112__and_now_for_something_completely_different/comment_4_1fe036e4c65fb4211aa2c394f535344a._comment
new file mode 100644
index 000000000..d19b70189
--- /dev/null
+++ b/doc/design/assistant/blog/day_112__and_now_for_something_completely_different/comment_4_1fe036e4c65fb4211aa2c394f535344a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmaM3-vbAh5B8tY_IL3yh31ik6cAVsgoPw"
+ nickname="IC"
+ subject="Haskell XMPP"
+ date="2012-10-27T05:54:53Z"
+ content="""
+Which xmpp library you've decided to use?
+"""]]
diff --git a/doc/design/assistant/blog/day_112__and_now_for_something_completely_different/comment_5_e4ba3568c4efd98f212dd47427a1cf47._comment b/doc/design/assistant/blog/day_112__and_now_for_something_completely_different/comment_5_e4ba3568c4efd98f212dd47427a1cf47._comment
new file mode 100644
index 000000000..272970caa
--- /dev/null
+++ b/doc/design/assistant/blog/day_112__and_now_for_something_completely_different/comment_5_e4ba3568c4efd98f212dd47427a1cf47._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 5"
+ date="2012-10-27T06:08:44Z"
+ content="""
+I'm using http://hackage.haskell.org/package/network-protocol-xmpp
+
+While its author thinks \"its current design (session in an XMPP monad) is a failed mistake\", I've found it pretty good. Aside from the segfault problem, which we got fixed today.
+"""]]
diff --git a/doc/design/assistant/blog/day_113__notifier_work.mdwn b/doc/design/assistant/blog/day_113__notifier_work.mdwn
new file mode 100644
index 000000000..920b48dfe
--- /dev/null
+++ b/doc/design/assistant/blog/day_113__notifier_work.mdwn
@@ -0,0 +1,22 @@
+Built out the XMPP push notifier; around 200 lines of code.
+Haven't tested it yet, but it just might work. It's in the `xmpp` branch
+for now.
+
+I decided to send the UUID of the repo that was pushed to, otherwise
+peers would have to speculatively pull from every repo. A wrinkle in this
+is that not all git repos have a git-annex UUID. So it might notify that
+a push was sent to an unidentified repo, and then peers need to pull from
+every such repo. In the common case, there will only be one or a few such
+repos, at someplace like at github that doesn't support git-annex. I could
+send the URL, but there's no guarantee different clients have the same
+URLs for a git remote, and also sending the URL leaks rather more data than
+does a random UUID.
+
+Had a bit of a scare where it looked like I couldn't use the haskell
+`network-protocol-xmpp` package together with the `mtl` package that
+git-annex already depends on. With help from #haskell I found the way
+to get them co-existing, by using the PackageImports extension. Whew!
+
+Need to add configuration of the XMPP server to use in the webapp, and
+perhaps also a way to create `.git/annex/creds/notify-xmpp` from the
+command line.
diff --git a/doc/design/assistant/blog/day_114__xmpp.mdwn b/doc/design/assistant/blog/day_114__xmpp.mdwn
new file mode 100644
index 000000000..617824d48
--- /dev/null
+++ b/doc/design/assistant/blog/day_114__xmpp.mdwn
@@ -0,0 +1,56 @@
+Had to toss out my XMPP presence hack. Turns out that, at least in Google
+Talk, presence info is not sent to clients that have marked themselves
+unavailable, and that means the assistant would not see notifications, as it
+was nearly always marked unavailable as part of the hack.
+
+I tried writing a test program that uses XMPP personal eventing, only
+to find that Google Talk rejected my messages. I'm not 100% sure my
+messages were right, but I was directly copying the example in the RFC,
+and prosody accepted them. I could not seem to get a list of extensions out
+of Google Talk either, so I don't know if it doesn't support personal
+eventing, or perhaps only supports certian specific types of events.
+
+So, plan C... using XMPP [presence extended content](http://xmpp.org/rfcs/rfc6121.html#presence-extended).
+The assistant generates a presence message tagged "xa" (Extended Away),
+which hopefully will make it not seem present to clients.
+And to that presence message, I add my own XML element:
+
+ <git-annex xmlns='git-annex' push="uuid,uuid" />
+
+This is all entirely legal, and not at all a hack.
+(Aside from this not really being presence info.) Isn't XML fun?
+
+And plan C works, with Google Talk, and prosody. I've successfully gotten
+push notifications flowing over XMPP!
+
+----
+
+Spent some hours dealing with an unusual probolem: git-annex started
+segfaulting intermittently on startup with the new XMPP code.
+
+Haskell code is not supposed to segfault..
+
+I think this was probably due to not using a bound thread for XMPP,
+so if haskell's runtime system recheduled its green thread onto a different
+OS thread during startup, when it's setting up TLS, it'd make gnuTLS very
+unhappy.
+
+So, fixed it to use a bound thread. Will wait and see if the crash is gone.
+
+----
+
+Re-enabled DBUS support, using a new version of the library that avoids the
+memory leak. Will need further changes to the library to support
+reconnecting to dbus.
+
+----
+
+Next will be a webapp configuration UI for XMPP. Various parts of the
+webapp will direct the user to set up XMPP, when appropriate, especially
+when the user sets up a cloud remote.
+
+To make XMPP sufficiently easy to configure, I need to check SRV records to
+find the XMPP server, which is an unexpected PITA because `getaddrinfo`
+can't do that. There are several haskell DNS libraries that I could use for
+SRV, or I could use the `host` command:
+`host -t SRV _xmpp-client._tcp.gmail.com`
diff --git a/doc/design/assistant/blog/day_114__xmpp/comment_1_c2b0617a2fc3dc4f19a6be6947913842._comment b/doc/design/assistant/blog/day_114__xmpp/comment_1_c2b0617a2fc3dc4f19a6be6947913842._comment
new file mode 100644
index 000000000..a391435c4
--- /dev/null
+++ b/doc/design/assistant/blog/day_114__xmpp/comment_1_c2b0617a2fc3dc4f19a6be6947913842._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://phil.0x539.de/"
+ nickname="Philipp Kern"
+ subject="How to deal with offline messages being eaten?"
+ date="2012-11-09T14:05:30Z"
+ content="""
+How do you avoid eating up normal text messages when git-annex is the only client left? Granted, Google Talk does some additional magic so that it shows you the history when connecting with the web page client. But with other servers it would be inconvenient if new messages weren't saved as offline messages but sent to the dæmon instead.
+"""]]
diff --git a/doc/design/assistant/blog/day_114__xmpp/comment_2_d14375dfb5791615802dab3c5438f8e2._comment b/doc/design/assistant/blog/day_114__xmpp/comment_2_d14375dfb5791615802dab3c5438f8e2._comment
new file mode 100644
index 000000000..716f7d99a
--- /dev/null
+++ b/doc/design/assistant/blog/day_114__xmpp/comment_2_d14375dfb5791615802dab3c5438f8e2._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.27"
+ subject="comment 2"
+ date="2012-11-09T21:55:42Z"
+ content="""
+It does try to mark itself as extended away, but yes, I think this is a potential concern. If you find the assistant interacts badly with your other clients, you can certainly give it its own XMPP account.
+"""]]
diff --git a/doc/design/assistant/blog/day_114__xmpp/comment_3_6d72ea32c111e605be30ad2153fc71c9._comment b/doc/design/assistant/blog/day_114__xmpp/comment_3_6d72ea32c111e605be30ad2153fc71c9._comment
new file mode 100644
index 000000000..6d2147d37
--- /dev/null
+++ b/doc/design/assistant/blog/day_114__xmpp/comment_3_6d72ea32c111e605be30ad2153fc71c9._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://phil.0x539.de/"
+ nickname="Philipp Kern"
+ subject="comment 3"
+ date="2012-11-10T18:50:46Z"
+ content="""
+Sure, I could, as I'm operating my own server anyway. Others might not be willing to go to some random server and create another account, though.
+
+Reviewing RFC 6121: Did you try negative priorities for your resources already? It's possible that Gtalk does something weird but in theory they should be ignored for messages directed to non-qualified JIDs (i.e. without an explicit resource setting). Setting \"xa\" alone won't help you anything, it will only cause the others to see you as \"xa\" but that's a perfectly valid common chat status where you expect messages to be queued in the client until the user returns.
+"""]]
diff --git a/doc/design/assistant/blog/day_114__xmpp/comment_4_e51d6f854db5f9e74a1aa58bd8923795._comment b/doc/design/assistant/blog/day_114__xmpp/comment_4_e51d6f854db5f9e74a1aa58bd8923795._comment
new file mode 100644
index 000000000..7320d0365
--- /dev/null
+++ b/doc/design/assistant/blog/day_114__xmpp/comment_4_e51d6f854db5f9e74a1aa58bd8923795._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.27"
+ subject="comment 4"
+ date="2012-11-10T19:48:01Z"
+ content="""
+I hadn't tried it, but it looks like a very good idea. I will have to change my protocol a little bit as I currently sometimes send chat messages not directed to a specific client, in order to reach any clients using an account. To reach clients with a negative priority, chat messages have to be directed at the client.
+
+Ok, done; priority is set to -1 and all the XMPP messaging in git-annex still seems to work!
+
+I don't know though, that this entirely solves the problem. In particular, a regular xmpp client may decide to direct a chat message at a git-annex client, due to that being the only client connected. If this does become a problem, I suppose git-annex could buffer and re-send such messages when it sees a regular client connect. Or it could show them in the webapp, but that seems feature creep.
+"""]]
diff --git a/doc/design/assistant/blog/day_115__my_new_form.mdwn b/doc/design/assistant/blog/day_115__my_new_form.mdwn
new file mode 100644
index 000000000..d44565084
--- /dev/null
+++ b/doc/design/assistant/blog/day_115__my_new_form.mdwn
@@ -0,0 +1,17 @@
+Built a SRV lookup library that can use either `host` or ADNS.
+
+Worked on DBUS reconnection some more; found a FD leak in the dbus library,
+and wrote its long-suffering author, John Millikin (also the XMPP library
+author, so I've been bothering him a lot lately), who once again came
+through with a quick fix.
+
+Built a XMPP configuration form, that tests the connection to the server.
+Getting the wording right on this was hard, and it's probably still not
+100% right.
+
+[[!img /assistant/xmpp.png]]
+
+Pairing over XMPP is something I'm still thinking about. It's
+contingent on tunneling git over XMPP (actually not too hard),
+and getting a really secure XMPP connection (needs library improvements,
+as the library currently accepts any SSL certificate).
diff --git a/doc/design/assistant/blog/day_116__the_segfault.mdwn b/doc/design/assistant/blog/day_116__the_segfault.mdwn
new file mode 100644
index 000000000..47633454a
--- /dev/null
+++ b/doc/design/assistant/blog/day_116__the_segfault.mdwn
@@ -0,0 +1,25 @@
+Continuing to flail away at this XMPP segfault, which turned out not to be
+fixed by bound threads. I managed to make a fairly self-contained and small
+reproducible test case for it that does not depend on the network.
+Seems the bug is gonna be either in the Haskell binding for GNUTLS,
+or possibly in GNUTLS itself.
+
+Update: John was able to fix it using my testcase! It was a GNUTLS
+credentials object that went out of scope and got garbage collected.
+I think I was seeing the crash only with the threaded runtime because
+it has a separate garbage collection thread.
+
+----
+
+Arranged for the XMPP thread to restart when network connections
+change, as well as when the webapp configures it.
+
+Added an alert to nudge users to enable XMPP. It's displayed after adding a
+remote in the cloud.
+
+[[!img /assistant/xmppnudge.png]]
+
+----
+
+So, the first stage of XMPP is done. But so far all it does is push
+notification. Much more work to do here.
diff --git a/doc/design/assistant/blog/day_117__new_topologies.mdwn b/doc/design/assistant/blog/day_117__new_topologies.mdwn
new file mode 100644
index 000000000..f62da3c5b
--- /dev/null
+++ b/doc/design/assistant/blog/day_117__new_topologies.mdwn
@@ -0,0 +1,41 @@
+Back in [[day_85__more_foundation_work]], I wrote:
+
+> I suspect, but have not proven,
+> that the assistant is able to keep repos arranged in any shape of graph in
+> sync, as long as it's connected (of course) and each connection is
+> bi-directional. [And each node is running the assistant.]
+
+After today's work, many more graph topologies can be kept in sync -- the
+assistant now can keep repos in sync that are not directly connected, but
+must go through a central transfer point, which does not run the assistant
+at all. Major milestone!
+
+To get that working, as well as using XMPP push notifications, it turned
+out to need to be more agressive about pushing out changed location log
+information. And, it seems, that was the last piece that was missing.
+Although I narrowly avoided going down a blind alley involving sending
+transfer notifications over XMPP. Luckily, I came to my senses.
+
+----
+
+This month's focus was the cloud, and the month is almost done. And now
+the assistant can, indeed be used to sync over the cloud! I would have
+liked to have gotten on to implementing Amazon Glacier or Google Drive
+support, but at least the cloud fundamentals are there.
+
+Now that I have XMPP support, I'm tending toward going ahead and adding
+XMPP pairing, and git push over XMPP. This will open up lots of excellent
+use cases.
+
+So, how to tunnel git pushes over XMPP? Well, `GIT_SHELL` can be set to
+something that intercepts the output of `git-send-pack` and
+`git-receive-pack`, and that data can be tunneled through XMPP to connect
+them. Probably using XMPP ping.
+(XEP-0047: In-Band Bytestreams would be the right way ...
+but of course Google Talk doesn't support that extension.)
+
+XMPP requires ugly encoding that will bloat the data, but the data
+quantities are fairly small to sync up a few added or moved files
+(of course, we'll not be sending file contents over XMPP). Pairing with
+an large git repository over XMPP will need rather more bandwidth,
+of course.
diff --git a/doc/design/assistant/blog/day_118__monadic_discontinuity.mdwn b/doc/design/assistant/blog/day_118__monadic_discontinuity.mdwn
new file mode 100644
index 000000000..758b26974
--- /dev/null
+++ b/doc/design/assistant/blog/day_118__monadic_discontinuity.mdwn
@@ -0,0 +1,15 @@
+Spent most of the past day moving the assistant into a monad of its own
+that encapsulates all the communications channels for its threads. This
+involved modifiying nearly every line of code in the whole assistant.
+
+Typical change:
+
+[[!format haskell """
+handleConnection threadname st dstatus scanremotes pushnotifier = do
+ reconnectRemotes threadname st dstatus scanremotes (Just pushnotifier)
+ =<< networkRemotes st
+
+handleConnection = reconnectRemotes True =<< networkRemotes
+"""]]
+
+So, it's getting more readable..
diff --git a/doc/design/assistant/blog/day_119__time_for_testing.mdwn b/doc/design/assistant/blog/day_119__time_for_testing.mdwn
new file mode 100644
index 000000000..adf1d0d41
--- /dev/null
+++ b/doc/design/assistant/blog/day_119__time_for_testing.mdwn
@@ -0,0 +1,12 @@
+Finished working the new assistant monad into all the assistant's code.
+I've changed 1870 lines of code in the past two days. It feels like more.
+While the total number of lines of code has gone up by around 100, the
+actual code size has gone *down*; the monad allowed dropping 3.4 kilobytes
+of manual variable threading complications. Or around 1% of a novel edited
+away, in other words.
+
+I don't seem to have broken anything, but I'm started an extensive test
+of all the assistant and webapp. So far, the bugs I've found were not
+introduced by my monadic changes. Fixed several bugs around adding
+removable drives, and a few other minor bugs. Plan to continue testing
+tomorrow.
diff --git a/doc/design/assistant/blog/day_11__freebsd.mdwn b/doc/design/assistant/blog/day_11__freebsd.mdwn
new file mode 100644
index 000000000..92a3ef289
--- /dev/null
+++ b/doc/design/assistant/blog/day_11__freebsd.mdwn
@@ -0,0 +1,50 @@
+I've been investigating how to make `git annex watch` work on
+FreeBSD, and by extension, OSX.
+
+One option is kqueue, which works on both operating systems, and allows
+very basic monitoring of file changes. There's also an OSX specific
+hfsevents interface.
+
+Kqueue is far from optimal for `git annex watch`, because it provides even
+less information than inotify (which didn't really provide everything I
+needed, thus the lsof hack). Kqueue doesn't have events for files being
+closed, only an event when a file is created. So it will be difficult for
+`git annex watch` to know when a file is done being written to and can be
+annexed. git annex will probably need to run lsof periodically to check when
+recently added files are complete. (hsevents shares this limitation)
+
+Kqueue also doesn't provide specific events when a file or directory is
+moved. Indeed, it doesn't provide specific events about what changed at
+all. All you get with kqueue is a generic "oh hey, the directory you're
+watching changed in some way", and it's up to you to scan it to work out
+how. So git annex will probably need to run `git ls-tree --others`
+to find changes in the directory tree. This could be expensive with large
+trees. (hsevents has per-file events on current versions of OSX)
+
+Despite these warts, I want to try kqueue first, since it's more portable
+than hfsevents, and will surely be easier for me to develop support for,
+since I don't have direct access to OSX.
+
+So I went to a handy Debian kFreeBSD porter box, and tried some kqueue
+stuff to get a feel for it. I got a python program that does basic
+directory monitoring with kqueue to work, so I know it's usable there.
+
+Next step was getting kqueue working from Haskell. Should be easy, there's
+a Haskell library already. I spent a while trying to get it to work on
+Debian kFreeBSD, but ran into a
+[problem](https://github.com/hesselink/kqueue/issues/1) that could be
+caused by the Debian kFreeBSD being different, or just a bug in the Haskell
+library. I didn't want to spend too long shaving this yak; I might install
+"real" FreeBSD on a spare laptop and try to get it working there instead.
+
+But for now, I've dropped down to C instead, and have a simple C program
+that can monitor a directory with kqueue. Next I'll turn it into a simple
+library, which can easily be linked into my Haskell code. The Haskell code
+will pass it a set of open directory descriptors, and it'll return the
+one that it gets an event on. This is necessary because kqueue doesn't
+recurse into subdirectories on its own.
+
+I've generally had good luck with this approach to adding stuff in Haskell;
+rather than writing a bit-banging and structure packing low level interface
+in Haskell, write it in C, with a simpler interface between C and
+Haskell.
diff --git a/doc/design/assistant/blog/day_120__test_day.mdwn b/doc/design/assistant/blog/day_120__test_day.mdwn
new file mode 100644
index 000000000..548222989
--- /dev/null
+++ b/doc/design/assistant/blog/day_120__test_day.mdwn
@@ -0,0 +1,2 @@
+Did a lot of testing, found and fixed 4 bugs with repository setup
+configurators. None of them were caused by the recent code reworking.
diff --git a/doc/design/assistant/blog/day_121__buddy_list.mdwn b/doc/design/assistant/blog/day_121__buddy_list.mdwn
new file mode 100644
index 000000000..48ea1ffda
--- /dev/null
+++ b/doc/design/assistant/blog/day_121__buddy_list.mdwn
@@ -0,0 +1,10 @@
+Got the XMPP client maintaining a list of buddies, including tracking which
+clients are present and away, and which clients are recognised as other
+git-annex assistant clients. This was fun, it is almost all pure
+functional code, which always makes me happy.
+
+Started building UI for XMPP pairing. So far, I have it showing a list of
+buddies who are also running git-annex (or not). The list even refreshes
+in real time as new buddies come online.
+
+[[!img /assistant/buddylist.png]]
diff --git a/doc/design/assistant/blog/day_122__xmpp_pairing.mdwn b/doc/design/assistant/blog/day_122__xmpp_pairing.mdwn
new file mode 100644
index 000000000..868382725
--- /dev/null
+++ b/doc/design/assistant/blog/day_122__xmpp_pairing.mdwn
@@ -0,0 +1,29 @@
+Reworked my XMPP code, which was still specific to push notification, into
+a more generic XMPP client, that's based on a very generic NetMessager
+class, that the rest of the assistant can access without knowing anything
+about XMPP.
+
+Got pair requests flowing via XMPP ping, over Google Talk! And when the
+webapp receives a pair request, it'll pop up an alert to respond. The rest
+of XMPP pairing should be easy to fill in from here.
+
+To finish XMPP pairing, I'll need git pull over XMPP, which is nontrivial,
+but I think I know basically how to do. And I'll need some way to represent
+an XMPP buddy as a git remote, which is all that XMPP pairing will really
+set up.
+
+It could be a git remote using an `xmpp:user@host` URI for the git url, but
+that would confuse regular git to no end (it'd think it was a ssh host),
+and probably need lots of special casing in the parts of git-annex that
+handle git urls too. Or it could be a git remote without an url set, and
+use another config field to represent the XMPP data. But then git wouldn't
+think it was a remote at all, which would prevent using "git pull
+xmppremote" at all, which I'd like to be able to use when implementing git
+pull over XMPP.
+
+Aha! The trick seems to be to leave the url unset in git config,
+but temporarily set it when pulling:
+
+ GIT_SSH=git-annex git git -c remote.xmppremote.url=xmpp:client pull xmppremote
+
+Runs git-annex with "xmpp git-upload-pack 'client'".. Just what I need.
diff --git a/doc/design/assistant/blog/day_122__xmpp_pairing/comment_1_e95efb23eb2e67e3f11a5c7de56424a7._comment b/doc/design/assistant/blog/day_122__xmpp_pairing/comment_1_e95efb23eb2e67e3f11a5c7de56424a7._comment
new file mode 100644
index 000000000..990fa816e
--- /dev/null
+++ b/doc/design/assistant/blog/day_122__xmpp_pairing/comment_1_e95efb23eb2e67e3f11a5c7de56424a7._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://meep.pl/"
+ ip="193.219.28.34"
+ subject="git-remote-helpers"
+ date="2012-11-09T08:54:11Z"
+ content="""
+It seems that xmpp::user@host (with double colon) would cause git to try to use a remote-xmpp helper.
+Wouldn't it be a way to have the remote address (if not really URL) set and not be treated as ssh?
+
+"""]]
diff --git a/doc/design/assistant/blog/day_122__xmpp_pairing/comment_2_30e251e73146512bde8b2f69eddeef2e._comment b/doc/design/assistant/blog/day_122__xmpp_pairing/comment_2_30e251e73146512bde8b2f69eddeef2e._comment
new file mode 100644
index 000000000..256b91242
--- /dev/null
+++ b/doc/design/assistant/blog/day_122__xmpp_pairing/comment_2_30e251e73146512bde8b2f69eddeef2e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.27"
+ subject="comment 2"
+ date="2012-11-09T17:41:08Z"
+ content="""
+Thanks, I think that's exactly what I should do.
+"""]]
diff --git a/doc/design/assistant/blog/day_123__xmpp_insanity.mdwn b/doc/design/assistant/blog/day_123__xmpp_insanity.mdwn
new file mode 100644
index 000000000..bfbc30669
--- /dev/null
+++ b/doc/design/assistant/blog/day_123__xmpp_insanity.mdwn
@@ -0,0 +1,49 @@
+Spent about 5 hours the other night in XMPP hell. At every turn Google Talk
+exhibited behavior that may meet the letter of the XMPP spec (or not), but
+varies between highly annoying and insane.
+
+By "insane", I mean this: If a presence message is directed from one client
+to another client belonging to that same user, randomly leaking that message
+out to other users who are subscribed is just a security hole waiting to
+happen.
+
+Anyway, I came out of that with a collection of hacks that worked, but I
+didn't like. I was using directed presence for buddy-to-buddy pairing, and
+an IQ message hack for client-to-client pairing.
+
+Today I got chat messages working instead, for both sorts of pairing. These
+chat messages have an empty body, which *should* prevent clients from
+displaying them, but they're sent directed to only git-annex clients
+anyway.
+
+----
+
+And XMPP pairing 100% works now! Of course, it doesn't know how to git pull
+over XMPP yet, but everything else works.
+
+Here's a real `.git/config` generated by the assistant after XMPP pairing.
+
+ [remote "joey"]
+ url =
+ fetch = +refs/heads/*:refs/remotes/joey/*
+ annex-uuid = 14f5e93e-1ed0-11e2-aa1c-f7a45e662d39
+ annex-xmppaddress = joey@kitenet.net
+
+----
+
+Fixed a typo that led to an infinite loop when adding a ssh git repo with the
+assistant. Only occurred when an absolute directory was specified, which
+is why I didn't notice it before.
+
+----
+
+Security fix: Added a `GIT_ANNEX_SHELL_DIRECTORY` environment variable that
+locks down git-annex-shell to operating in only a single directory. The
+assistant sets that in ssh `authorized_keys` lines it creates. This
+prevents someone you pair with from being able to access any other git or
+git-annex repositories you may have.
+
+----
+
+Next up, more craziness. But tomorrow is Nov 6th, so you in the US already
+knew that..
diff --git a/doc/design/assistant/blog/day_124__git_push_over_xmpp_groundwork.mdwn b/doc/design/assistant/blog/day_124__git_push_over_xmpp_groundwork.mdwn
new file mode 100644
index 000000000..ecb6023f2
--- /dev/null
+++ b/doc/design/assistant/blog/day_124__git_push_over_xmpp_groundwork.mdwn
@@ -0,0 +1,28 @@
+Laying the groundwork for git push over XMPP. BTW, the motivation for doing
+this now is that if the assistant can push git data peer-to-peer, users
+who are entirely using the cloud don't need to set up a git repo in the
+cloud somewhere. Instead, a single special remote in the cloud will be all
+they need. So this is a keystone in the assistant's cloud support.
+
+I'm building the following pipeline:
+
+ git push <--> git-annex xmppgit <--> xmppPush <-------> xmpp
+ |
+ git receive-pack <--> xmppReceivePack <---------------> xmpp
+
+A tricky part of this is `git-annex xmppgit`, which is run by `git push`
+rather than the usual `ssh`. Rather than speak XMPP itself, that feeds the
+data through the assistant daemon, using some special FDs that are set
+up by the assistant when it runs `git push`, and communicated via
+environment variables. I hoped to set up a pipe and not need it to do any
+work on its own, but short of using the linux-specific `splice(2)`, that
+doesn't seem possible. It also will receive the exit status of
+`git receive-pack` and propigate it to `git push`.
+
+Also built the IO sides of `xmppPush` and `xmppReceivePack` although these
+are not tested. The XMPP sides of them come next.
+
+----
+
+Stuffing lots of git-annex branded USB keys into envelopes tonight, while
+watching the election coverage.
diff --git a/doc/design/assistant/blog/day_125__xmpp_push_continues.mdwn b/doc/design/assistant/blog/day_125__xmpp_push_continues.mdwn
new file mode 100644
index 000000000..010ab14da
--- /dev/null
+++ b/doc/design/assistant/blog/day_125__xmpp_push_continues.mdwn
@@ -0,0 +1,15 @@
+I've finished building the XMMP side of git push over XMPP. Now I only
+have to add code to trigger these pushes. And of course, fix all the bugs,
+since none of this has been tested at all.
+
+Had to deal with some complications, like handling multiple clients that
+all want to push at the same time. Only one push is handled at a time;
+messages for others are queued. Another complication I don't deal with yet
+is what to do if a client stops responding in the middle of a push. It
+currently will wait forever for a message from the client; instead it
+should time out.
+
+----
+
+Jimmy got the OSX builder working again, despite my best attempts to add
+dependencies and break it.
diff --git a/doc/design/assistant/blog/day_126__mr_watson_come_here.mdwn b/doc/design/assistant/blog/day_126__mr_watson_come_here.mdwn
new file mode 100644
index 000000000..78d263b6d
--- /dev/null
+++ b/doc/design/assistant/blog/day_126__mr_watson_come_here.mdwn
@@ -0,0 +1,52 @@
+I'm stunned and stoked to have gotten git push over XMPP working today.
+And am nearly out of steam, it was a wild ride..
+
+ To xmpp::joey@kitenet.net
+ * [new branch] master -> refs/xmpp/newmaster
+
+The surprising part is how close my initial implementation came to just
+working on the first try. It had around 3 bugs, which took hours of staring
+at debugging output to find:
+
+1. The git push action was run in the same thread as the XMPP
+ client, which prevented the client from continuing to run and relaying
+ messages.
+2. The git-receive-pack side waited on the wrong thread, so didn't
+ notice when the program was done.
+3. I accidentially used the wrong attribute name when sending a ReceivePackDone
+ message.
+
+But all in all, it just worked.
+
+Here's a sample of the actual data sent when one file is added to the
+repository (also includes the corresponding update to the git-annex branch):
+
+ MDA4NjhhMmNmOGZjMWE3MTlkOGVjOWVmOWZiMGZiNjVlODc2NjQ1NDAyMTAgODIwNTZjMDM4
+ ZjU2YzE1ODdjYzllOWRhNzQzMzU0YjE4NzNjZWJlOSByZWZzL3htcHAvbmV3bWFzdGVyACBy
+ ZXBvcnQtc3RhdHVzIHNpZGUtYmFuZC02NGswMDAw
+
+ UEFDSwAAAAIAAAADnAx4nJXLTQ4CIQxA4T2n4AKaAqVAYoxL4y2gU+Jo5iczdeHtnSu4eMm3
+ ebqJ2NwgSCLmNkTBlKFCYwwhoHOtQ+scqZCwWesms9pcPffc2dXkypCFi/TSG/RGUXIiwojg
+ HZj60eey2cciX3uXfbeX18Hbe1SZRc9HV+tC9FgyJW9PgACGl2kaVeXfz/wArHQ81qMGeJwz
+ NDIAAoVUI4ZZB9RW1E8NtXp5t77/fn3hw41cl2MNIbIZqTk5+Qwerw+aJX2INjsffYndtdCz
+ 5mZWLDdUQV5qeVpmDtCQnx/3/6s40+Q4P/7O+Y4ShS+1Ad83AwC6CirftAt4nK3MsRGDMAwF
+ 0IkcSVgSdpkidzRUmcDWBy4pSAEFl+mzRN4A77a9Tmr7vlz06e8lzoPmmb5Mz+k+mD/SkTkl
+ eFHPq9eqQ+nSzFsWaDFnFmCMCEOvHgLrCrQxS7AWdvUVhv9uPwHxMbfumlvWdco1RLL4wSQF
+ g0uFFOKu3Q==
+
+Git said this push took 385 bytes; after base64 encoding to transport it over
+XMPP as shown above, it needs 701 bytes, and the XMPP envelope and encryption
+adds more overhead (although the XMPP connection may also be compressed?)
+
+Not the most efficient git transport, but still a practical one!
+
+----
+
+Big thanks by the way to meep, who posted a comment reminding me about
+`git-remote-helpers`. This was the right thing to use for XMPP over git,
+it lets the git remote be configured with `url = xmpp::user@host`.
+
+----
+
+Next, I need to get the assistant to use this for syncing. Currently, it only
+pushes a test branch.
diff --git a/doc/design/assistant/blog/day_126__mr_watson_come_here/comment_1_ee1361e6b235f4e1c00596ba516b519a._comment b/doc/design/assistant/blog/day_126__mr_watson_come_here/comment_1_ee1361e6b235f4e1c00596ba516b519a._comment
new file mode 100644
index 000000000..47766dc77
--- /dev/null
+++ b/doc/design/assistant/blog/day_126__mr_watson_come_here/comment_1_ee1361e6b235f4e1c00596ba516b519a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5vDem1yeIu6uith5pxfb4mdKdIWVJpCs"
+ nickname="Louis"
+ subject="Base64 vs. yEnc"
+ date="2012-11-12T02:02:17Z"
+ content="""
+Would yEnc be a suitable alternative to base64 for encoding the binary transfers over XMPP? Or why not?
+
+Thanks!
+"""]]
diff --git a/doc/design/assistant/blog/day_126__mr_watson_come_here/comment_2_8eb366ae7efb347bd3bbd9a98e0821b3._comment b/doc/design/assistant/blog/day_126__mr_watson_come_here/comment_2_8eb366ae7efb347bd3bbd9a98e0821b3._comment
new file mode 100644
index 000000000..6f76ec4c8
--- /dev/null
+++ b/doc/design/assistant/blog/day_126__mr_watson_come_here/comment_2_8eb366ae7efb347bd3bbd9a98e0821b3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.27"
+ subject="comment 2"
+ date="2012-11-12T02:39:19Z"
+ content="""
+AFAIK, yenc can use xml characters like &lt; and &gt; in its encoding.
+"""]]
diff --git a/doc/design/assistant/blog/day_127__xmpp_syncs.mdwn b/doc/design/assistant/blog/day_127__xmpp_syncs.mdwn
new file mode 100644
index 000000000..7f95f87e3
--- /dev/null
+++ b/doc/design/assistant/blog/day_127__xmpp_syncs.mdwn
@@ -0,0 +1,35 @@
+I got full-on git-annex assistant syncing going over XMPP today!
+
+How well does it work? Well, I'm at the cabin behind a dialup modem. I have
+two repos that can only communicate over XMPP. One uses my own XMPP server,
+and the other uses a Google Talk account. I make a file in one repo, and
+switch windows to the other, and type `ls`, and the file (not its content
+tho..) has often already shown up. So, it's about as fast as syncing over
+ssh, although YMMV.
+
+----
+
+Refactored the git push over XMPP code rather severely. It's quite a
+lot cleaner now.
+
+----
+
+Set XMPP presence priority to a negative value, which will hopefully
+prevent git-annex clients that share a XMPP account with other clients from
+intercepting chat messages. Had to change my XMPP protocol some to deal
+with this.
+
+----
+
+Some webapp UI work. When showing the buddy list, indicate which buddies
+are already paired with.
+
+After XMPP pairing, it now encourages setting up a shared cloud repository.
+
+[[!img /assistant/xmpppairingend.png]]
+
+I still need to do more with the UI after XMPP pairing, to help the paired
+users configure a shared cloud transfer remote. Perhaps the thing to do is
+for the ConfigMonitor to notice when a git push adds a new remote,
+and pop up an alert suggesting the user enable it. Then one user
+can create the repository, and the other one enable it.
diff --git a/doc/design/assistant/blog/day_128__last_xmpp_day.mdwn b/doc/design/assistant/blog/day_128__last_xmpp_day.mdwn
new file mode 100644
index 000000000..2c7d70acc
--- /dev/null
+++ b/doc/design/assistant/blog/day_128__last_xmpp_day.mdwn
@@ -0,0 +1,49 @@
+I hope I'm nearly at the end of this XMPP stuff after today. Planning a new
+release tomorrow.
+
+----
+
+Split up the local pairing and XMPP pairing UIs, and wrote a
+[[/assistant/share_with_a_friend_walkthrough]].
+
+----
+
+Got the XMPP push code to time out if expected data doesn't arrive within
+2 minutes, rather than potentially blocking other XMPP push forever if
+the other end went away.
+
+I pulled in the Haskell
+[async](http://hackage.haskell.org/package/async) library for this,
+which is yes, yet another library, but one that's now in the haskell platform.
+It's worth it, because of how nicely it let me implement IO actions that
+time out.
+
+[[!format haskell """
+runTimeout :: Seconds -> IO a -> IO (Either SomeException a)
+runTimeout secs a = do
+ runner <- async a
+ controller <- async $ do
+ threadDelaySeconds secs
+ cancel runner
+ cancel controller `after` waitCatch runner
+"""]]
+
+This would have been 20-50 lines of gnarly code without async, and I'm sure
+I'll find more uses for async in the future.
+
+----
+
+Discovered that the XMPP push code could deadlock, if both clients started
+a push to the other at the same time. I decided to fix this by allowing
+each client to run both one push and one receive-pack over XMPP at the same
+time.
+
+----
+
+Prevented the transfer scanner from trying to queue transfers to XMPP remotes.
+
+----
+
+Made XMPP pair requests that come from the same account we've already
+paired with be automatically accepted. So once you pair with one device,
+you can easily add more.
diff --git a/doc/design/assistant/blog/day_128__last_xmpp_day/comment_1_fd8c1d6358cb50f4dad8ba11d33d861f._comment b/doc/design/assistant/blog/day_128__last_xmpp_day/comment_1_fd8c1d6358cb50f4dad8ba11d33d861f._comment
new file mode 100644
index 000000000..add2cf313
--- /dev/null
+++ b/doc/design/assistant/blog/day_128__last_xmpp_day/comment_1_fd8c1d6358cb50f4dad8ba11d33d861f._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmqVi9eQjkZt8EC-byTXJ8TnY7VyOHzW2s"
+ nickname="Zahary"
+ subject="Pairing on the local network"
+ date="2012-11-12T11:39:17Z"
+ content="""
+Joey, How does pairing on the local network work btw?
+Now that you have experience intercepting and relaying the git pack output maybe you can use UDP broadcast on the local network for a truly fast sync.
+With dropbox, I'm often syncing working copies of software projects between several VMs so I can test the code on all platforms before committing. I've found that to be faster (for builds) then using a VM shared folders, network shares, etc.
+"""]]
diff --git a/doc/design/assistant/blog/day_128__last_xmpp_day/comment_2_43664b73c71c41d71bc95e665f128106._comment b/doc/design/assistant/blog/day_128__last_xmpp_day/comment_2_43664b73c71c41d71bc95e665f128106._comment
new file mode 100644
index 000000000..3a8318618
--- /dev/null
+++ b/doc/design/assistant/blog/day_128__last_xmpp_day/comment_2_43664b73c71c41d71bc95e665f128106._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://phil.0x539.de/"
+ nickname="Philipp Kern"
+ subject="comment 2"
+ date="2012-11-12T11:50:42Z"
+ content="""
+Developing something new based on IPv4 UDP broadcast seems to be insane. IPv6 link-local multicast should be available virtually anywhere. XMPP relies on TCP and a central server to guarantee that a single packet is not split up, which would need quite some protocol engineering to get right over lossy UDP (e.g. segmentation, flow control, congestion avoidance). But TCP as discovered using mDNS might work… Still needs some kind of authentication / encryption, though.
+"""]]
diff --git a/doc/design/assistant/blog/day_128__last_xmpp_day/comment_3_d369b04f686009a9dbb57b999107a55e._comment b/doc/design/assistant/blog/day_128__last_xmpp_day/comment_3_d369b04f686009a9dbb57b999107a55e._comment
new file mode 100644
index 000000000..951cc7e05
--- /dev/null
+++ b/doc/design/assistant/blog/day_128__last_xmpp_day/comment_3_d369b04f686009a9dbb57b999107a55e._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmqVi9eQjkZt8EC-byTXJ8TnY7VyOHzW2s"
+ nickname="Zahary"
+ subject="Jingle"
+ date="2012-11-12T12:00:50Z"
+ content="""
+Also, you probably know about Jingle:
+http://en.wikipedia.org/wiki/Jingle_(protocol)
+
+What are you thoughts about it? I guess it would have been harder to use the Google C++ library from Haskell and full mesh peer-to-peer is certainly more complicated than using the XMPP server to effectively multicast to all paired clients.
+"""]]
diff --git a/doc/design/assistant/blog/day_128__last_xmpp_day/comment_4_095855d301e7ccd3689ffe507cfb63ee._comment b/doc/design/assistant/blog/day_128__last_xmpp_day/comment_4_095855d301e7ccd3689ffe507cfb63ee._comment
new file mode 100644
index 000000000..0e5295ad2
--- /dev/null
+++ b/doc/design/assistant/blog/day_128__last_xmpp_day/comment_4_095855d301e7ccd3689ffe507cfb63ee._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmqVi9eQjkZt8EC-byTXJ8TnY7VyOHzW2s"
+ nickname="Zahary"
+ subject="@Philipp Kern"
+ date="2012-11-12T12:13:33Z"
+ content="""
+Alright, I stand corrected, although I'm aware of some libraries that have already solved the problem so you don't really have to implement reliable UDP from scratch: http://code.google.com/p/openpgm/
+"""]]
diff --git a/doc/design/assistant/blog/day_128__last_xmpp_day/comment_5_da7b0586b0b28e1e0fe4126f6543a7bc._comment b/doc/design/assistant/blog/day_128__last_xmpp_day/comment_5_da7b0586b0b28e1e0fe4126f6543a7bc._comment
new file mode 100644
index 000000000..f10326a3c
--- /dev/null
+++ b/doc/design/assistant/blog/day_128__last_xmpp_day/comment_5_da7b0586b0b28e1e0fe4126f6543a7bc._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://phil.0x539.de/"
+ nickname="Philipp Kern"
+ subject="comment 5"
+ date="2012-11-12T12:50:26Z"
+ content="""
+To quote the website (emphasis mine):
+> PGM is appropriate for applications that require duplicate-free multicast data delivery from multiple sources to multiple receivers. *PGM does not support acknowledged delivery, nor does it guarantee ordering of packets from multiple senders.*
+"""]]
diff --git a/doc/design/assistant/blog/day_128__last_xmpp_day/comment_6_2f9ba367e19d77bf52f372b6f0f5938a._comment b/doc/design/assistant/blog/day_128__last_xmpp_day/comment_6_2f9ba367e19d77bf52f372b6f0f5938a._comment
new file mode 100644
index 000000000..e73c4c071
--- /dev/null
+++ b/doc/design/assistant/blog/day_128__last_xmpp_day/comment_6_2f9ba367e19d77bf52f372b6f0f5938a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.27"
+ subject="comment 6"
+ date="2012-11-12T14:43:32Z"
+ content="""
+For local pairing, multicast UDP is used for discovery and authentication, and then all data transfers take place over ssh.
+"""]]
diff --git a/doc/design/assistant/blog/day_129__release.mdwn b/doc/design/assistant/blog/day_129__release.mdwn
new file mode 100644
index 000000000..553b0e91f
--- /dev/null
+++ b/doc/design/assistant/blog/day_129__release.mdwn
@@ -0,0 +1,4 @@
+Cut a new release today. It's been nearly a month since the last one, and a
+large number of improvements.. Be sure to read the
+[[/assistant/release_notes]] if upgrading. All the standalone builds are
+updated already.
diff --git a/doc/design/assistant/blog/day_12__freebsd_redux.mdwn b/doc/design/assistant/blog/day_12__freebsd_redux.mdwn
new file mode 100644
index 000000000..5ec446c9d
--- /dev/null
+++ b/doc/design/assistant/blog/day_12__freebsd_redux.mdwn
@@ -0,0 +1,23 @@
+Followed my plan from yesterday, and wrote a simple C library to interface
+to `kqueue`, and Haskell code to use that library. By now I think I
+understand kqueue fairly well -- there are some very tricky parts to the
+interface.
+
+But... it still didn't work. After building all this, my code was
+failing the same way that the
+[haskell kqueue library failed](https://github.com/hesselink/kqueue/issues/1)
+yesterday. I filed a [bug report with a testcase]().
+
+Then I thought to ask on #haskell. Got sorted out in quick order! The
+problem turns out to be that haskell's runtime has a periodic SIGALARM,
+that is interrupting my kevent call. It can be worked around with `+RTS -V0`,
+but I put in a fix to retry to kevent when it's interrupted.
+
+And now `git-annex watch` can detect changes to directories on BSD and OSX!
+
+Note: I said "detect", not "do something useful in response to". Getting
+from the limited kqueue events to actually staging changes in the git repo
+is going to be another day's work. Still, brave FreeBSD or OSX users
+might want to check out the `watch` branch from git and see if
+`git annex watch` will at least *say* it sees changes you make to your
+repository.
diff --git a/doc/design/assistant/blog/day_12__freebsd_redux/comment_1_5da32cf53f1de27bfe6cec2d294db3e1._comment b/doc/design/assistant/blog/day_12__freebsd_redux/comment_1_5da32cf53f1de27bfe6cec2d294db3e1._comment
new file mode 100644
index 000000000..253af9e7c
--- /dev/null
+++ b/doc/design/assistant/blog/day_12__freebsd_redux/comment_1_5da32cf53f1de27bfe6cec2d294db3e1._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 1"
+ date="2012-06-19T06:53:26Z"
+ content="""
+heh, yea, it's detecting changes on OSX ;)
+"""]]
diff --git a/doc/design/assistant/blog/day_12__freebsd_redux/comment_2_696d6e22034acf5bb60d80124b72ef2f._comment b/doc/design/assistant/blog/day_12__freebsd_redux/comment_2_696d6e22034acf5bb60d80124b72ef2f._comment
new file mode 100644
index 000000000..9f3e34adb
--- /dev/null
+++ b/doc/design/assistant/blog/day_12__freebsd_redux/comment_2_696d6e22034acf5bb60d80124b72ef2f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 1"
+ date="2012-06-19T07:01:26Z"
+ content="""
+issues with the watch command on OSX, it seems that there is a race condition somewhere. I dumped a few iso's into an annex and it only annexed the smaller files (checksums) and the bigger ones (the iso's) just got made read only. also do you want these bugs to be logged here or in the bugs section?
+"""]]
diff --git a/doc/design/assistant/blog/day_130__what_now.mdwn b/doc/design/assistant/blog/day_130__what_now.mdwn
new file mode 100644
index 000000000..4fc3fe53c
--- /dev/null
+++ b/doc/design/assistant/blog/day_130__what_now.mdwn
@@ -0,0 +1,36 @@
+Dealt with post-release feedback deluge. There are a couple weird bugs that
+I don't understand yet. OSX app is still not working everywhere.
+
+----
+
+Got the list of repositories in the webapp to update automatically when
+repositories are added, including when syncing with a remote causes
+repositories to be discovered.
+
+----
+
+I need a plan for the rest of the month. It feels right to focus on more
+cloud storage support. Particularly because all the cloud providers
+supported so far are ones that, while often being best of breed, also cost
+money. To finish up the cloud story, need support for some free ones.
+
+Looking at the results of the [[polls/prioritizing_special_remotes]]
+poll, I suspect that free storage is a large part of why Google Drive got
+so many votes. Soo, since there is not yet a Haskell library for Google
+Drive, rather than spending a large chunk of time writing one, I hope to
+use a [Haskell WebDAV library](http://hackage.haskell.org/package/DAV)
+that my friend Clint recently wrote. A generic
+WebDAV special remote in git-annex will provide much better support for
+box.com (which has 5 to 50 gb free storage), as well as all the
+[OwnCloud providers](http://owncloud.org/providers/), at least one of which
+provides 5 gb free storage.
+
+If I have time left this month after doing that, I'd be inclined to do
+Amazon Glacier. People have already gotten that working with git-annex, but
+a proper special remote should be better/easier, and will allow integrating
+support for it into the assistant, which should help deal with its long
+retrieval delays. And since, if you have a lot of data
+archived in Glacier, you will only want to pull out a few files at a time,
+this is another place besides mobile phones where a [[partial_content]]
+retrieval UI is needed. Which is on the roadmap to be worked on next
+month-ish. Synergy, here I come. I hope.
diff --git a/doc/design/assistant/blog/day_130__what_now/comment_1_402f00cc034351d8253a797dd4de55bf._comment b/doc/design/assistant/blog/day_130__what_now/comment_1_402f00cc034351d8253a797dd4de55bf._comment
new file mode 100644
index 000000000..ec2158c22
--- /dev/null
+++ b/doc/design/assistant/blog/day_130__what_now/comment_1_402f00cc034351d8253a797dd4de55bf._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm7AuSfii_tCkLyspL6Mr0ATlO6OxLNYOo"
+ nickname="Georg"
+ subject="definitely glacier would be cool"
+ date="2012-11-14T08:51:40Z"
+ content="""
+Because having it available as an archival system to move stuff over that you don't expect to constantly need available. But what would be needed is a way to prevent the assistant to pull all the data from there back on your clients. This probably allready is doable with preferred content, but probably needs an easier way to set up - when I tried the new version it immediately started to pull all the stuff from my server repository that I moved there to get my disk space free. So my scenario would be \"move stuff to archives and when I drop it afterwards, keep it dropped locally if at least one archival server has it\".
+"""]]
diff --git a/doc/design/assistant/blog/day_131__webdav_groundwork.mdwn b/doc/design/assistant/blog/day_131__webdav_groundwork.mdwn
new file mode 100644
index 000000000..795acfea1
--- /dev/null
+++ b/doc/design/assistant/blog/day_131__webdav_groundwork.mdwn
@@ -0,0 +1,28 @@
+Read up on WebDAV, and got the haskell library working. Several hours
+were wasted by stumbling over a bug in the library, that requires a
+carefully crafted XML document to prevent. Such a pity about things
+like DAV (and XMPP) being designed back when people were gung-ho about
+XML.. but we're stuck with them now.
+
+Now I'm able to send and receive files to box.com using the library. Trying to
+use an OwnCloud server, though, I get a most strange error message, which
+looks to be coming from deep in the HTTPS library stack: "invalid IV length"
+
+The haskell DAV library didn't have a way to delete files. I've added one
+and sent off a patch.
+
+Roughed in a skeleton of a webdav special remote. Doesn't do anything yet.
+Will soon.
+
+Factored out a Creds module from parts of the S3 special remote and XMPP
+support, that all has to do with credentials storage. Using this for webdav
+creds storage too.
+
+Will also need to factor out the code that's currently in the directory
+special remote, for chunking of files.
+
+----
+
+PS: WebDAV, for all its monstrously complicated feature set, lacks one obvious
+feature: The ability to check how much free space is available to store
+files. Eyeroll.
diff --git a/doc/design/assistant/blog/day_132__webdav_continued.mdwn b/doc/design/assistant/blog/day_132__webdav_continued.mdwn
new file mode 100644
index 000000000..075a5d8c4
--- /dev/null
+++ b/doc/design/assistant/blog/day_132__webdav_continued.mdwn
@@ -0,0 +1,22 @@
+Two releases of the Haskell DAV library today. First release had my changes
+from yesterday. Then I realized I'd also need support for making WebDAV
+"collections" (subdirectories), and sent Clint a patch for that too, as
+well as a patch for querying DAV properties, and that was 0.2.
+Got it into Debian unstable as well. Should have everything I'll need now.
+
+The webdav special remote is now working! Still todo:
+Encryption support, progress bars, large file chunking, and webapp
+configurators. But already, it's a lot nicer than the old approach of using
+davfs2, which was really flakey and slow with large data volumes.
+
+I did notice, though, that uploading a 100 mb file made the process use 100
+mb of memory. This is a problem I've struggled with earlier with S3, the
+Haskell http libraries are prevented from streaming data by several parts
+of the protocol that cause the data to be accessed more than once. I guess
+this won't be a problem for DAV though, since it'll probably be chunking
+files anyway.
+
+---
+
+Mailed out all my Kickstarter USB key rewards, and ordered
+the T-shirts too.
diff --git a/doc/design/assistant/blog/day_133__webdav_working.mdwn b/doc/design/assistant/blog/day_133__webdav_working.mdwn
new file mode 100644
index 000000000..d71f25852
--- /dev/null
+++ b/doc/design/assistant/blog/day_133__webdav_working.mdwn
@@ -0,0 +1,31 @@
+Worked on webdav special remotes all day.
+
+* Got encryption working,
+ after fixing an amusing typo that made `initremote` for webdav throw away the
+ encryption configuration and store files unencrypted.
+* Factored out parts of the directory special remote that had to do with file
+ chunking, and am using that for webdav. This refactoring was painful.
+
+At this point, I feel the webdav special remote works better than the old
+davfs2 + directory special remote hack. While webdav doesn't yet have
+progress info for uploads, that info was pretty busted anyway with
+davfs2 due to how it buffers files. So ... I've merged webdav into master!
+
+-----
+
+Tomorrow, webapp configurators for Box.com and any other webdav supporting
+sites I can turn up and get to work..
+
+-----
+
+A while ago I made git-annex not store login credentials in git for special
+remotes, when it's only encrypting them with a shared cipher. The
+rationalle was that you don't want to give everyone who gets ahold of your
+git repo (which includes the encryption key) access to your passwords,
+Amazon S3 account, or whatever. I'm now considering adding a checkbox (or
+command-line flag) that allows storing the login credentials in git,
+if the user wants to. While using public key crypto is the real solution
+(and is fully supported by git-annex (but not yet configurable in the
+webapp)), this seems like a reasonable thing to do in some circumstances,
+like when you have a Box.com account you really do want to share with
+the people who use the git repo.
diff --git a/doc/design/assistant/blog/day_134__box.com_configurator.mdwn b/doc/design/assistant/blog/day_134__box.com_configurator.mdwn
new file mode 100644
index 000000000..115633640
--- /dev/null
+++ b/doc/design/assistant/blog/day_134__box.com_configurator.mdwn
@@ -0,0 +1,8 @@
+I needed an easy day, and I got one. Configurator in the webapp for Box.com
+came together really quickly and easily, and worked on the first try.
+
+Also filed a [bug](https://github.com/vincenthz/hs-cryptocipher/issues/21)
+on the Haskell library that is failing on portknox.com's SSL certificate.
+That site is the only OwnCloud provider currently offering free WebDAV
+storage. Will hold off on adding OwnCloud to the webapp's cloud provider lists
+until that's fixed.
diff --git a/doc/design/assistant/blog/day_135__progress_revisited.mdwn b/doc/design/assistant/blog/day_135__progress_revisited.mdwn
new file mode 100644
index 000000000..63e3c4bf2
--- /dev/null
+++ b/doc/design/assistant/blog/day_135__progress_revisited.mdwn
@@ -0,0 +1,37 @@
+Unexpectedly today, I got progress displays working for uploads via WebDAV.
+
+The roadblock had been that the interface of for uploading to S3 and WebDAV
+is something like `ByteString -> IO a`. Which doesn't provide any hook to
+update a progress display as the ByteString is consumed.
+
+My solution to this was to create a `hGetContentsObserved`, that's similar
+to `hGetContents`, but after reading each 64kb chunk of data from the
+Handle to populate the ByteString, it runs some observing action. So when
+the ByteString is streamed, as each chunk is consumed, the observer
+runs. I was able to get this to run in constant space, despite not having
+access to some of the ByteString internals that `hGetContents` is built
+with.
+
+So, a little scary, but nice. I am curious if there's not a better way
+to solve this problem hidden in a library somewhere. Perhaps it's another
+thing that conduit solves somehow? Because if there's not, my solution
+probably deserves to be put into a library. Any Haskell folk know?
+
+----
+
+Used above to do progress displays for uploads to S3. Also did progress
+display to console on download from S3. Now very close to being done
+with [[progressbars]]. Finally. Only bup and hook remotes need progress
+work.
+
+----
+
+Reworked the core crypto interface, to better support streaming data through
+gpg. This allowed fixing both the directory and webdav special remotes to
+not buffer whole files in memory when retrieving them as chunks from the
+remote.
+
+-----
+
+Spent some time dealing with API changes in Yesod and Conduit. Some of them
+annoyingly gratuitous.
diff --git a/doc/design/assistant/blog/day_136__misc.mdwn b/doc/design/assistant/blog/day_136__misc.mdwn
new file mode 100644
index 000000000..5a14156d5
--- /dev/null
+++ b/doc/design/assistant/blog/day_136__misc.mdwn
@@ -0,0 +1,14 @@
+Changed how the directory and webdav special remotes store content.
+The new method uses less system calls, is more robust, and leaves any
+partially transferred key content in a single tmp directory, which
+will make it easier to clean that out later.
+
+Also found & fixed a cute bug in the directory special remote when the
+chunksize is set to a smaller value than the ByteString chunk size, that
+caused it to loop forever creating empty files.
+
+----
+
+Added an embedcreds=yes option when setting up special remotes.
+Will put UI for it into the webapp later, but rather than work on that
+tomorrow, I plan to work on glacier.
diff --git a/doc/design/assistant/blog/day_137__Glacier.mdwn b/doc/design/assistant/blog/day_137__Glacier.mdwn
new file mode 100644
index 000000000..4e6787eb5
--- /dev/null
+++ b/doc/design/assistant/blog/day_137__Glacier.mdwn
@@ -0,0 +1,30 @@
+Got Amazon Glacier working as a full-fledged special remote.
+
+(Well, I think it works... Since it takes 4 hours to get data out,
+which is longer than the time it took me to sign up for Glacier and
+write the special remote ... I've yet to fully test it!)
+
+Thanks to Robie Basak for writing glacier-cli, and developing the intial
+hook remote support. Also thanks to Peter Todd for pointing out that
+Glacier cannot store empty files, which had to be worked around in the
+special remote.
+
+Of course the 4 hour delay on retreval makes Glacier interesting. For now,
+you have to run "git annex get" twice, once to queue the retrieval, and a
+second time in 4 hours to get the file(s). There is a helpful example in
+[[tips/using_Amazon_Glacier]].
+
+The real complication though, is that Glacier's inventories take a long
+time to get, and can be out of date. So glacier-cli caches inventory info.
+I didn't feel comfortable making git-annex trust that information,
+so it'll refuse to trust that Glacier has a copy of a file when dropping
+it. There's a `--trust-glacier` switch to override this default paranoid
+behavior when dropping files.
+
+----
+
+Tomorrow ... er, tomorrow is Thanksgiving trip start.
+
+Next weekend: Webapp configurator for glacier, and maybe something
+to get the assistant to detect when jobs are complete and finish
+retrievals from Glacier, automatically.
diff --git a/doc/design/assistant/blog/day_138__back.mdwn b/doc/design/assistant/blog/day_138__back.mdwn
new file mode 100644
index 000000000..7c2b4ec45
--- /dev/null
+++ b/doc/design/assistant/blog/day_138__back.mdwn
@@ -0,0 +1,25 @@
+Added a configurator for Glacier repositories to the webapp. That was the last
+cloud repository configurator that was listed in the webapp and wasn't
+done. Indeed, just two more repository configurators remain to be filled in:
+phone and NAS.
+
+By default, Glacier repositories are put in a new "small archive" group.
+This makes only files placed in "archive" directories be sent to Glacier
+(as well as being dropped from clients), unlike the full archive group
+which archives all files. Of course you can change this setting, but
+avoiding syncing all data to Glacier seemed like a good default, especially
+since some are still worried about Glacier's pricing model.
+
+Fixed several bugs in the handling of archive directories, and
+the webapp makes a toplevel archive directory when an archive remote is
+created, so the user can get on with using it.
+
+Made the assistant able to drop local files immediately after transferring
+them to glacier, despite not being able to trust glacier's inventory.
+This was accomplished by making the transferrer, after a successful upload,
+indicate that it trusts the remote it just uploaded to has the file,
+when it checks if the file should be dropped.
+
+Only thing left to do for glacier is to make the assistant retry failed
+downloads from it after 4 hours, or better, as soon as they become
+available.
diff --git a/doc/design/assistant/blog/day_138__back/comment_1_65a8499b284bed38d2bde1886a54a311._comment b/doc/design/assistant/blog/day_138__back/comment_1_65a8499b284bed38d2bde1886a54a311._comment
new file mode 100644
index 000000000..5bd94d13e
--- /dev/null
+++ b/doc/design/assistant/blog/day_138__back/comment_1_65a8499b284bed38d2bde1886a54a311._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmnG4EuvZWse5hvgrl0XAK-U61e-0iGaao"
+ nickname="David"
+ subject="NAS?"
+ date="2012-11-25T12:27:50Z"
+ content="""
+What are you planning to support with the NAS repository type? Will the assistant sync over NFS? I wanted to read more about this but I couldn't find anything on the design pages.
+"""]]
diff --git a/doc/design/assistant/blog/day_139__catch_up.mdwn b/doc/design/assistant/blog/day_139__catch_up.mdwn
new file mode 100644
index 000000000..fc1e572b0
--- /dev/null
+++ b/doc/design/assistant/blog/day_139__catch_up.mdwn
@@ -0,0 +1,11 @@
+Got progress bars working for glacier. This needed some glacier-cli
+changes, which Robie helpfully made earlier.
+
+Spent some hours getting caught up and responding to bug reports, etc.
+
+Spent a while trying to make git-annex commands that fail to find
+any matching files to act on print a useful warning message,
+rather than the current nothing. Concluded this will be surprisingly
+hard to do, due to the multiple seek passes some commands perform. Update:
+Thought of a non-invasive and not too ugly way to do this while on my
+evening walk, and this wart is gone.
diff --git a/doc/design/assistant/blog/day_13__kqueue_continued.mdwn b/doc/design/assistant/blog/day_13__kqueue_continued.mdwn
new file mode 100644
index 000000000..fd0cbb372
--- /dev/null
+++ b/doc/design/assistant/blog/day_13__kqueue_continued.mdwn
@@ -0,0 +1,34 @@
+Good news! My beta testers report that the new kqueue code works on OSX.
+At least "works" as well as it does on Debian kFreeBSD. My crazy
+development strategy of developing on Debian kFreeBSD while targeting Mac
+OSX is vindicated. ;-)
+
+So, I've been beating the kqueue code into shape for the last 12 hours,
+minus a few hours sleep.
+
+First, I noticed it was seeming to starve the other threads. I'm using
+Haskell's non-threaded runtime, which does cooperative multitasking between
+threads, and my C code was never returning to let the other threads run.
+Changed that around, so the C code runs until SIGALARMed, and then that
+thread calls `yield` before looping back into the C code. Wow, cooperative
+multitasking.. I last dealt with that when programming for Windows 3.1!
+(Should try to use Haskell's -threaded runtime sometime, but git-annex
+doesn't work under it, and I have not tried to figure out why not.)
+
+Then I made a [single commit](http://source.git-annex.branchable.com/?p=source.git;a=commitdiff;h=2bfcc0b09c5dd37c5e0ab65cb089232bfcc31934),
+with no testing, in which I made the kqueue code maintain a cache of what
+it expects in the directory tree, and use that to determine what files
+changed how when a change is detected. Serious code. It worked on the
+first go. If you were wondering why I'm writing in Haskell ... yeah,
+that's why.
+
+And I've continued to hammer on the kqueue code, making lots of little
+fixes, and at this point it seems *almost* able to handle the changes I
+throw at it. It does have one big remaining problem; kqueue doesn't tell me
+when a writer closes a file, so it will sometimes miss adding files. To fix
+this, I'm going to need to make it maintain a queue of new files, and
+periodically check them, with `lsof`, to see when they're done being
+written to, and add them to the annex. So while a file is being written
+to, `git annex watch` will have to wake up every second or so, and run
+`lsof` ... and it'll take it at least 1 second to notice a file's complete.
+Not ideal, but the best that can be managed with kqueue.
diff --git a/doc/design/assistant/blog/day_140__release_monday.mdwn b/doc/design/assistant/blog/day_140__release_monday.mdwn
new file mode 100644
index 000000000..9c9ccd166
--- /dev/null
+++ b/doc/design/assistant/blog/day_140__release_monday.mdwn
@@ -0,0 +1,25 @@
+New release today, the main improvements in this one being WebDAV,
+Box.com, and Amazon glacier support. [[/assistant/release_notes]]
+
+Collected together all the OSX problem reports into one place
+at [[/assistant/OSX]], to make it easier to get an overview of them.
+
+Did some testing of the OSX standalone app and found that it was missing
+some libraries. It seems some new libraries it's using themselves depend on
+other libraries, and `otool -L` doesn't recursively resolve this.
+
+So I converted the simplistic shell script it was using to install
+libraries into a haskell progream that recursively adds libraries until
+there are no more to add. It's pulling in quite a lot more libraries now.
+This may fix some of the problems that have been reported with the
+standalone app; I don't really know since I can only do very limited
+testing on OSX.
+
+Still working on getting the standalone builds for this release done,
+should be done by the end of today.
+
+Also found a real stinker of a bug in `dirContentsRecursive`, which was
+just completely broken, apparently since day 1. Fixing that has certainly
+fixed buggy behavior of `git annex import`. It seems that the other
+user of it, the transfer log code, luckily avoided the deep directory
+trees that triggered the bug.
diff --git a/doc/design/assistant/blog/day_141__release_tuesday.mdwn b/doc/design/assistant/blog/day_141__release_tuesday.mdwn
new file mode 100644
index 000000000..41c323f01
--- /dev/null
+++ b/doc/design/assistant/blog/day_141__release_tuesday.mdwn
@@ -0,0 +1,6 @@
+I had planned to do nothing today; I can't remember the last time I did
+that. Twas not to be; instead I had to make a new release to fix
+a utterly stupid typo in the rsync special remote. I'm also seeing
+some slightly encouraging signs of the OSX app being closer to working
+and this release has a further fix toward that end; unsetting all the
+environment variables before running the system's web browser.
diff --git a/doc/design/assistant/blog/day_141__release_tuesday/comment_1_a5adea7a726df12f9121c744a036f08d._comment b/doc/design/assistant/blog/day_141__release_tuesday/comment_1_a5adea7a726df12f9121c744a036f08d._comment
new file mode 100644
index 000000000..69fb64778
--- /dev/null
+++ b/doc/design/assistant/blog/day_141__release_tuesday/comment_1_a5adea7a726df12f9121c744a036f08d._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnbBRfl5F8gKRr1ko8Ai6FbEZStXXNF1S4"
+ nickname="Áron"
+ subject="deb package for amd64"
+ date="2012-12-04T08:51:55Z"
+ content="""
+Hey, great work!
+Will we also have 64bit binaries in debian unstable soon?
+
+"""]]
diff --git a/doc/design/assistant/blog/day_142__filling_in.mdwn b/doc/design/assistant/blog/day_142__filling_in.mdwn
new file mode 100644
index 000000000..d7f5c84bf
--- /dev/null
+++ b/doc/design/assistant/blog/day_142__filling_in.mdwn
@@ -0,0 +1,9 @@
+Just filling in a few remaining bits and pieces from this month's work.
+
+* Made the assistant periodically check glacier-cli for archives that are
+ ready, and queue downloads of them.
+* The box.com configurator defaults to embedding the account info, allowing
+ one-click enabling of the repository. There's a check box to control this.
+* Fix some bugs with how the standalone images run git-annex.
+* Included ssh in the standalone images.
+* Various other bug fies.
diff --git a/doc/design/assistant/blog/day_143__what_next.mdwn b/doc/design/assistant/blog/day_143__what_next.mdwn
new file mode 100644
index 000000000..6c277f7a2
--- /dev/null
+++ b/doc/design/assistant/blog/day_143__what_next.mdwn
@@ -0,0 +1,22 @@
+Yesterday, I woke up and realized I didn't know what I needed to work on in
+git-annex. Added a poll, [[polls/Android]] to help me decide what major
+thing to work on next.
+
+----
+
+More flailing at the OSX monster. (A species of gelatinous cube?)
+Current fun seems to involve git processes spinning if git-annex
+was started without a controlling TTY. I'm befuddled by this.
+
+----
+
+Made the S3 and Glacier configurators have a list of regions, rather than
+requiring a the region's code be entered correctly. I could not find a list of
+regions, or better, an API to get a list, so I'll have to keep updating as
+Amazon adds services in new regions.
+
+----
+
+Spent some time trying to get WebDAV to work with livedrive.com.
+It doesn't like empty PROPPATCH. I've developed a change to the haskell DAV
+library that will let me avoid this problem.
diff --git a/doc/design/assistant/blog/day_143__what_next/comment_1_40cf25a2ebdd43d8974a28e180e100e5._comment b/doc/design/assistant/blog/day_143__what_next/comment_1_40cf25a2ebdd43d8974a28e180e100e5._comment
new file mode 100644
index 000000000..28ef42975
--- /dev/null
+++ b/doc/design/assistant/blog/day_143__what_next/comment_1_40cf25a2ebdd43d8974a28e180e100e5._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://1id.com/contact/=tp"
+ nickname="Tom"
+ subject="In case it might be helpful"
+ date="2012-12-04T14:25:14Z"
+ content="""
+S3 and Glacier regions.
+<http://docs.amazonwebservices.com/general/latest/gr/rande.html#s3_region>
+<http://docs.amazonwebservices.com/general/latest/gr/rande.html#glacier_region>
+
+(EC2) Region list API - likely a superset of the other service regions, could be used for sanity checks.
+<http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeRegions.html>
+"""]]
diff --git a/doc/design/assistant/blog/day_143__what_next/comment_2_af9ccbbc5131e6333c029415141bdb51._comment b/doc/design/assistant/blog/day_143__what_next/comment_2_af9ccbbc5131e6333c029415141bdb51._comment
new file mode 100644
index 000000000..b9df466cf
--- /dev/null
+++ b/doc/design/assistant/blog/day_143__what_next/comment_2_af9ccbbc5131e6333c029415141bdb51._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5vDem1yeIu6uith5pxfb4mdKdIWVJpCs"
+ nickname="Louis"
+ subject="AWS regions in JSON"
+ date="2012-12-05T03:27:52Z"
+ content="""
+Mitch Garnaat maintains a json data file with AWS service regions & other useful data...
+
+https://github.com/garnaat/missingcloud/blob/master/aws.json
+"""]]
diff --git a/doc/design/assistant/blog/day_144__webapp_work.mdwn b/doc/design/assistant/blog/day_144__webapp_work.mdwn
new file mode 100644
index 000000000..4e0c8287f
--- /dev/null
+++ b/doc/design/assistant/blog/day_144__webapp_work.mdwn
@@ -0,0 +1,8 @@
+Made the webapp show runtime errors on a prettified page that includes version
+info, a bug reporting link, etc.
+
+Dealt with a bad interaction between required fields and the bootstrap modals
+displayed when submitting some configuration forms. This was long, complex,
+and had lots of blind alleys. In the end, I had to derive new password and
+text fields in yesod that don't set the required attribute in the generated
+html.
diff --git a/doc/design/assistant/blog/day_145__more_webapp_work.mdwn b/doc/design/assistant/blog/day_145__more_webapp_work.mdwn
new file mode 100644
index 000000000..f9649be39
--- /dev/null
+++ b/doc/design/assistant/blog/day_145__more_webapp_work.mdwn
@@ -0,0 +1,12 @@
+One problem with the current configurators for remotes is they have a lot
+of notes and text to read at the top. I've worked on cut that down somewhat,
+mostly by adding links and help buttons next to fields in the form.
+
+I also made each form have a check box controlling whether encryption is
+enabled. Mostly as a way to declutter the text at the top, which always had
+to say encryption is enabled.
+
+---
+
+I have a fairly well worked out design for [[desymlink]]. Will wait a few
+days to work on it to let it jell.
diff --git a/doc/design/assistant/blog/day_146__meanwhile.mdwn b/doc/design/assistant/blog/day_146__meanwhile.mdwn
new file mode 100644
index 000000000..8ff8b1d72
--- /dev/null
+++ b/doc/design/assistant/blog/day_146__meanwhile.mdwn
@@ -0,0 +1,22 @@
+Biding my time while [[desymlink]] gells in my head..
+
+Fixed a bug in the assistant's local pairing that rejected ssh keys with a
+period in the comment.
+
+Fixed a bug in the assistant that made it try to drop content from remotes
+that didn't have it, and avoided a drop failure crashing a whole assistant
+thread.
+
+Made --auto behave better when preferred content is set.
+
+Looked into making the transfer queue allow running multiple transfers at
+the same time, ie, one per remote. This seems to essentially mean splitting
+the queue into per remote queues. There are some complexities, and I
+decided not to dive into working through it right now, since it'd be
+a distraction from thinking about [[desymlink]]. Will revisit it later.
+
+Allow specifying a port when setting up a ssh remote.
+
+While doing that, noticed that the assistant fails to transfer files to
+sync to a ssh remote that was just added. That got broken while optimising
+reconnecting with a remote; fixed it.
diff --git a/doc/design/assistant/blog/day_147__direct_mode.mdwn b/doc/design/assistant/blog/day_147__direct_mode.mdwn
new file mode 100644
index 000000000..1a7523785
--- /dev/null
+++ b/doc/design/assistant/blog/day_147__direct_mode.mdwn
@@ -0,0 +1,36 @@
+Started laying the groundwork for [[desymlink]]'s direct mode.
+I got rather far!
+
+A git repo can be configured with `annex.direct` and all actions that
+transfer objects to it will replace the symlinks with regular files.
+Removing objects also works (and puts back a broken symlink),
+as does checking if an object is present, which even detects if a file
+has been modified.
+
+So far, this works best when such a direct mode repository is used as a git
+remote of another repository. It is also possible to run a few git-annex
+commands, like "get" in a direct mode repository, though others, like
+"drop" won't work because they rely on the symlink to map back to the key.
+
+Direct mode relies on map files existing for each key in the repository, that tell
+what file(s) use it. It also relies on cache files, that contain the last
+known mtime, size, and inode of the file. So far, I've been setting these
+files up by hand.
+
+The main thing that's missing is support for transferring objects from
+direct mode repositories. There's no single place I can modify to support
+that (like I could for the stuff mentioned above), and also it's difficult
+to do safely, since files could be modified at any time.
+
+So it'll need to quarantine files, to prevent a modified version from
+getting sent out. I could either do this by copying the file, or by
+temporarily `git annex lock`ing it. Unsure which choice would be less
+annoying..
+
+----
+
+Also did some investigation with Jimmy of the OSX app git-config hang.
+Seems to be some kind of imcompatability between the 10.7 autobuilder and
+10.8. Next step is probably to try to build on 10.8. Might also
+be worth trying <http://macdylibbundler.sourceforge.net/>, although my
+own scripts do more or less the same thing to build the app.
diff --git a/doc/design/assistant/blog/day_147__direct_mode/comment_1_0bd69532afce9dc04e3d88bfd0aed4b2._comment b/doc/design/assistant/blog/day_147__direct_mode/comment_1_0bd69532afce9dc04e3d88bfd0aed4b2._comment
new file mode 100644
index 000000000..567c094c9
--- /dev/null
+++ b/doc/design/assistant/blog/day_147__direct_mode/comment_1_0bd69532afce9dc04e3d88bfd0aed4b2._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://lj.rossia.org/users/imz/"
+ ip="79.165.59.119"
+ subject="&quot;removing&quot; vs drop"
+ date="2012-12-12T13:20:42Z"
+ content="""
+I don't understand the difference behind:
+
+> Removing objects also works (and puts back a broken symlink)
+
+and
+
+> \"drop\" won't work because they rely on the symlink to map back to the key.
+
+If a file is removed (its content, which is replaced by a symlink), then it's not present there, so effectively it should be counted as \"dropped\" at this place. So, removing a file without counting it as dropped is something inconsistent, isn't it? Do I misunderstand something?
+"""]]
diff --git a/doc/design/assistant/blog/day_147__direct_mode/comment_2_3b26f0d081c3bf1037bb872d529ce825._comment b/doc/design/assistant/blog/day_147__direct_mode/comment_2_3b26f0d081c3bf1037bb872d529ce825._comment
new file mode 100644
index 000000000..b29d45390
--- /dev/null
+++ b/doc/design/assistant/blog/day_147__direct_mode/comment_2_3b26f0d081c3bf1037bb872d529ce825._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.117"
+ subject="comment 2"
+ date="2012-12-12T23:45:42Z"
+ content="""
+`git annex drop` is a user-level operation built on top of lower-level object removal functions that are also used by other things.
+"""]]
diff --git a/doc/design/assistant/blog/day_148__direct_mode.mdwn b/doc/design/assistant/blog/day_148__direct_mode.mdwn
new file mode 100644
index 000000000..14f1f889f
--- /dev/null
+++ b/doc/design/assistant/blog/day_148__direct_mode.mdwn
@@ -0,0 +1,42 @@
+Got object sending working in direct mode. However, I don't yet have a
+reliable way to deal with files being modified while they're being
+transferred. I have code that detects it on the sending side, but the
+receiver is still free to move the wrong content into its annex, and record
+that it has the content. So that's not acceptable, and I'll need to work
+on it some more. However, at this point I can use a direct mode repository
+as a remote and transfer files from and to it.
+
+----
+
+Automated updating of the cached mtime, etc data. Next I need to automate
+generation of the key to filename mapping files. I'm thinking that I'll make
+`git annex sync` do it. Then, once I get committing and
+merging working in direct mode repositories (which is likely to be a
+good week's worth of work), the workflow for using these repositories
+will be something like this:
+
+ git config annex.direct true
+ git annex sync # pulls any changes, merges, updates maps and caches
+ git annex get
+ # modify files
+ git annex sync # commits and pushes changes
+
+And once I get direct mode repositories working to this degree at the
+command line, I can get on with adding support to the assistant.
+
+----
+
+Also did some more work today on the OSX app. Am in the middle of getting
+it to modify the binaries in the app to change the paths to the libraries they
+depend on. This will avoid the hacky environment variable it is currently
+using, and make runshell a much more usable environment. It's the right way
+to do it. (I can't believe I just said RPATH was the right way to do
+anything.)
+
+In the middle of this, I discovered
+<http://hackage.haskell.org/package/cabal-macosx>, which does the same
+type of thing.
+
+Anyway, I have to do some crazy hacks to work around short library name
+fields in executables that I don't want to have to be specially rebuilt in
+order to build the webapp. Like git.
diff --git a/doc/design/assistant/blog/day_149__rainy_day.mdwn b/doc/design/assistant/blog/day_149__rainy_day.mdwn
new file mode 100644
index 000000000..eb4210884
--- /dev/null
+++ b/doc/design/assistant/blog/day_149__rainy_day.mdwn
@@ -0,0 +1,15 @@
+Made `git annex sync` update the file mappings in direct mode.
+To do this efficiently, it uses `git diff-tree` to find files that are
+changed by the sync, and only updates those mappings. I'm rather happy
+with this, as a first step to fully supporting sync in direct mode.
+
+Finished the overhaul of the OSX app's library handling. It seems to work
+well, and will fix a whole class of ways the OSX app could break.
+
+Fixed a bug in the preferred content settings for backup repositories,
+introduced by some changes I made to preferred content handling 4 days ago.
+
+Fixed the Debian package to build with WebDAV support, which I forgot to
+turn on before.
+
+Planning a release tomorrow.
diff --git a/doc/design/assistant/blog/day_14__kqueue_kqueue_kqueue.mdwn b/doc/design/assistant/blog/day_14__kqueue_kqueue_kqueue.mdwn
new file mode 100644
index 000000000..d7dab3611
--- /dev/null
+++ b/doc/design/assistant/blog/day_14__kqueue_kqueue_kqueue.mdwn
@@ -0,0 +1,23 @@
+... I'm getting tired of kqueue.
+
+But the end of the tunnel is in sight. Today I made git-annex handle files
+that are still open for write after a kqueue creation event is received.
+Unlike with inotify, which has a new event each time a file is closed,
+kqueue only gets one event when a file is first created, and so git-annex
+needs to retry adding files until there are no writers left.
+
+Eventually I found an elegant way to do that. The committer thread already
+wakes up every second as long as there's a pending change to commit. So for
+adds that need to be retried, it can just push them back onto the change
+queue, and the committer thread will wait one second and retry the add. One
+second might be too frequent to check, but it will do for now.
+
+This means that `git annex watch` should now be usable on OSX, FreeBSD, and
+NetBSD! (It'll also work on Debian kFreeBSD once [lsof is ported to it](http://bugs.debian.org/589103).)
+I've meged kqueue support to `master`.
+
+I also think I've squashed the empty commits that were sometimes made.
+
+Incidentally, I'm 50% through my first month, and finishing [[inotify]]
+was the first half of my roadmap for this month. Seem to be right on
+schedule.. Now I need to start thinking about [[syncing]].
diff --git a/doc/design/assistant/blog/day_14__thinking_about_syncing.mdwn b/doc/design/assistant/blog/day_14__thinking_about_syncing.mdwn
new file mode 100644
index 000000000..4173fbf77
--- /dev/null
+++ b/doc/design/assistant/blog/day_14__thinking_about_syncing.mdwn
@@ -0,0 +1,44 @@
+Pondering [[syncing]] today. I will be doing syncing of the git repository
+first, and working on syncing of file data later.
+
+The former seems straightforward enough, since we just want to push all
+changes to everywhere. Indeed, git-annex already has a [[sync]] command
+that uses a smart technique to allow syncing between clones without a
+central bare repository. (Props to Joachim Breitner for that.)
+
+But it's not all easy. Syncing should happen as fast as possible, so
+changes show up without delay. Eventually it'll need to support syncing
+between nodes that cannot directly contact one-another. Syncing needs to
+deal with nodes coming and going; one example of that is a USB drive being
+plugged in, which should immediately be synced, but network can also come
+and go, so it should periodically retry nodes it failed to sync with. To
+start with, I'll be focusing on fast syncing between directly connected
+nodes, but I have to keep this wider problem space in mind.
+
+One problem with `git annex sync` is that it has to be run in both clones
+in order for changes to fully propagate. This is because git doesn't allow
+pushing changes into a non-bare repository; so instead it drops off a new
+branch in `.git/refs/remotes/$foo/synced/master`. Then when it's run locally
+it merges that new branch into `master`.
+
+So, how to trigger a clone to run `git annex sync` when syncing to it?
+Well, I just realized I have spent two weeks developing something that can
+be repurposed to do that! [[Inotify]] can watch for changes to
+`.git/refs/remotes`, and the instant a change is made, the local sync
+process can be started. This avoids needing to make another ssh connection
+to trigger the sync, so is faster and allows the data to be transferred
+over another protocol than ssh, which may come in handy later.
+
+So, in summary, here's what will happen when a new file is created:
+
+1. inotify event causes the file to be added to the annex, and
+ immediately committed.
+2. new branch is pushed to remotes (probably in parallel)
+3. remotes notice new sync branch and merge it
+4. (data sync, TBD later)
+5. file is fully synced and available
+
+Steps 1, 2, and 3 should all be able to be accomplished in under a second.
+The speed of `git push` making a ssh connection will be the main limit
+to making it fast. (Perhaps I should also reuse git-annex's existing ssh
+connection caching code?)
diff --git a/doc/design/assistant/blog/day_150__12:12.mdwn b/doc/design/assistant/blog/day_150__12:12.mdwn
new file mode 100644
index 000000000..8e1f192db
--- /dev/null
+++ b/doc/design/assistant/blog/day_150__12:12.mdwn
@@ -0,0 +1,53 @@
+Yesterday I cut another release. However, getting an OSX build took until
+12:12 pm today because of a confusion about the location of lsof on OSX. The
+OSX build is now available, and I'm looking forward to hearing if it's working!
+
+----
+
+Today I've been working on making `git annex sync` commit in direct mode.
+
+For this I needed to find all new, modified, and deleted files, and I also
+need the git SHA from the index for all non-new files. There's not really
+an ideal git command to use to query this. For now I'm using
+`git ls-files --others --stage`, which works but lists more files than I
+really need to look at. It might be worth using one of the Haskell libraries
+that can directly read git's index.. but for now I'll stick with `ls-files`.
+
+It has to check all direct mode files whose content is present, which means
+one stat per file (on top of the stat that git already does), as well as one
+retrieval of the key per file (using the single `git cat-file` process that
+git-annex talks to).
+
+This is about as efficient as I can make it, except that unmodified
+annexed files whose content is not present are listed due to --stage,
+and so it has to stat those too, and currently also feeds them into `git add`.
+
+The assistant will be able to avoid all this work, except once at startup.
+
+Anyway, direct mode committing is working!
+
+For now, `git annex sync` in direct mode also adds new files. This because
+`git annex add` doesn't work yet in direct mode.
+
+It's possible for a direct mode file to be changed during a commit,
+which would be a problem since committing involves things like calculating
+the key and caching the mtime/etc, that would be screwed up. I took
+care to handle that case; it checks the mtime/etc cache before and after
+generating a key for the file, and if it detects the file has changed,
+avoids committing anything. It could retry, but if the file is a VM disk
+image or something else that's constantly modified, commit retrying forever
+would not be good.
+
+----
+
+For `git annex sync` to be usable in direct mode, it still needs
+to handle merging. It looks like I may be able to just enhance the automatic
+conflict resolution code to know about typechanged direct mode files.
+
+The other missing piece before this can really be used is that currently
+the key to file mapping is only maintained for files added locally, or
+that come in via `git annex sync`. Something needs to set up that mapping
+for files present when the repo is initally cloned. Maybe the thing
+to do is to have a `git annex directmode` command that enables/disables
+direct mode and can setup the the mapping, as well as any necessary unlocks
+and setting the trust level to untrusted.
diff --git a/doc/design/assistant/blog/day_151__direct_mode_toggle.mdwn b/doc/design/assistant/blog/day_151__direct_mode_toggle.mdwn
new file mode 100644
index 000000000..c0b3f3245
--- /dev/null
+++ b/doc/design/assistant/blog/day_151__direct_mode_toggle.mdwn
@@ -0,0 +1,59 @@
+Built `git annex direct` and `git annex indirect` to toggle back and forth
+between direct mode. Made `git annex status` show if the repository is in
+direct mode. Now *only* merging is needed for direct mode to be basically
+usable.
+
+I can do a little demo now. Pay attention to the "@" ls shows at the end
+of symlinks.
+
+ joey@gnu:~/tmp/bench/rdirect>ls
+ myfile@ otherfile@
+ joey@gnu:~/tmp/bench/rdirect>git annex find
+ otherfile
+ # So, two files, only one present in this repo.
+
+ joey@gnu:~/tmp/bench/rdirect>git annex direct
+ commit
+ # On branch master
+ # Your branch is ahead of 'origin/master' by 7 commits.
+ #
+ nothing to commit (working directory clean)
+ ok
+ direct myfile ok
+ direct otherfile ok
+ direct ok
+
+ joey@gnu:~/tmp/bench/rdirect>ls
+ myfile@ otherfile
+ # myfile is still a broken symlink because we don't have its content
+ joey@gnu:~/tmp/bench/rdirect>git annex get myfile
+ get myfile (from origin...) ok
+ (Recording state in git...)
+ joey@gnu:~/tmp/bench/rdirect>ls
+ myfile otherfile
+
+ joey@gnu:~/tmp/bench/rdirect>echo "look mom, no symlinks" >> myfile
+ joey@gnu:~/tmp/bench/rdirect>git annex sync
+ add myfile (checksum...) ok
+ commit
+ (Recording state in git...)
+ [master 0e8de9b] git-annex automatic sync
+ ...
+ ok
+
+ joey@gnu:~/tmp/bench/rdirect>git annex indirect
+ commit ok
+ indirect myfile ok
+ indirect otherfile ok
+ indirect ok
+ joey@gnu:~/tmp/bench/rdirect>ls
+ myfile@ otherfile@
+
+I'd like `git annex direct` to set the repository to untrusted, but
+I didn't do it. Partly because having `git annex indirect` set it back to
+semitrusted seems possibly wrong -- the user might not trust a repo even in
+indirect mode. Or might fully trust it. The docs will encourage users to
+set direct mode repos to untrusted -- in direct mode you're operating
+without large swathes of git-annex's carefully constructed safety net.
+(When the assistant later uses direct mode, it'll untrust the repository
+automatically.)
diff --git a/doc/design/assistant/blog/day_152__bugfixes.mdwn b/doc/design/assistant/blog/day_152__bugfixes.mdwn
new file mode 100644
index 000000000..da70fd156
--- /dev/null
+++ b/doc/design/assistant/blog/day_152__bugfixes.mdwn
@@ -0,0 +1,18 @@
+Fixed a bug in the kqueue code that made the assistant not notice when a
+file was renamed into a subdirectory. This turned out to be because the
+symlink got broken, and it was using `stat` on the file. Switching to
+`lstat` fixed that.
+
+Improved installation of programs into standalone bundles. Now it uses
+the programs detected by configure, rather than a separate hardcoded list.
+Also improved handling of lsof, which is not always in PATH.
+
+Made a OSX 10.8.2 build of the app, which is nearly my last gasp attempt
+at finding a way around this crazy `git init` spinning problem with Jimmy's
+daily builds are used with newer OSX versions. Try it here:
+<http://downloads.kitenet.net/tmp/git-annex.dmg.bz2>
+
+----
+
+Mailed out the Kickstarter T-shirt rewards today, to people in the US.
+Have to fill out a bunch of forms before I can mail the non-US ones.
diff --git a/doc/design/assistant/blog/day_152__bugfixes/comment_1_46863a875f9daa6f2c9248b66ff91929._comment b/doc/design/assistant/blog/day_152__bugfixes/comment_1_46863a875f9daa6f2c9248b66ff91929._comment
new file mode 100644
index 000000000..9199f3768
--- /dev/null
+++ b/doc/design/assistant/blog/day_152__bugfixes/comment_1_46863a875f9daa6f2c9248b66ff91929._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmYiJgOvC4IDYkr2KIjMlfVD9r_1Sij_jY"
+ nickname="Douglas"
+ subject="OSX troubles"
+ date="2012-12-17T16:07:41Z"
+ content="""
+Have you considered making a homebrew installable version of git-annex? It may make things easier for you when it comes to build dependencies.
+
+"""]]
diff --git a/doc/design/assistant/blog/day_152__bugfixes/comment_2_a586e617bc024c8a9ff60f1b8345d74d._comment b/doc/design/assistant/blog/day_152__bugfixes/comment_2_a586e617bc024c8a9ff60f1b8345d74d._comment
new file mode 100644
index 000000000..af7a901a9
--- /dev/null
+++ b/doc/design/assistant/blog/day_152__bugfixes/comment_2_a586e617bc024c8a9ff60f1b8345d74d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.117"
+ subject="comment 2"
+ date="2012-12-17T16:16:47Z"
+ content="""
+I would *love* *love* *love* for there to be a homebrew for git-annex. But I know nothing about homebrew so am not in a very good position to do it.
+"""]]
diff --git a/doc/design/assistant/blog/day_153__hibernation.mdwn b/doc/design/assistant/blog/day_153__hibernation.mdwn
new file mode 100644
index 000000000..5406fcb86
--- /dev/null
+++ b/doc/design/assistant/blog/day_153__hibernation.mdwn
@@ -0,0 +1,26 @@
+As winter clouds set in, I have to ration my solar power and have been less
+active than usual.
+
+It seems that the OSX 10.8.2 `git init` hanging issue has indeed been
+resolved, by building the app on 10.8.2. Very good news! Autobuilder setup is
+in progress.
+
+----
+
+Finally getting stuck in to direct mode git-merge handling. It's
+not possible to run `git merge` in a direct mode tree, because it'll
+see typechanged files and refuse to do anything.
+
+So the only way to use `git merge`, rather than writing my own merge engine,
+is to use `--work-tree` to make it operate in a temporary work tree directory
+rather than the real one.
+
+When it's run this way, any new, modified, or renamed files will be added
+to the temp dir, and will need to be moved to the real work tree.
+To detect deleted files, need to use `git ls-files --others`, and
+look at the old tree to see if the listed files were in it.
+
+When a merge conflict occurs, the new version of the file will be in the temp
+directory, and the old one in the work tree. The normal automatic merge
+conflict resolution machinery should work, with just some tweaks to handle
+direct mode.
diff --git a/doc/design/assistant/blog/day_154__direct_mode_merging.mdwn b/doc/design/assistant/blog/day_154__direct_mode_merging.mdwn
new file mode 100644
index 000000000..c3233c36d
--- /dev/null
+++ b/doc/design/assistant/blog/day_154__direct_mode_merging.mdwn
@@ -0,0 +1,21 @@
+Got merging working in direct mode!
+
+Basically works as outlined yesterday, although slightly less clumsily.
+Since there was already code that ran `git diff-tree` to update the
+associated files mappings after a merge, I was able to adapt that same code
+to also update the working tree.
+
+An important invariant for direct mode merges is that they should never
+cause annexed objects to be dropped. So if a file is deleted by a merge,
+and was a direct mode file that was the only place in the working copy
+where an object was stored, the object is moved into `.git/annex/objects`.
+This avoids data loss and any need to re-transfer objects after a merge.
+It also makes renames and other move complex tree manipulations always end
+up with direct mode files, when their content was present.
+
+Automatic merge conflict resoltion doesn't quite work right yet in direct
+mode.
+
+Direct mode has landed in the `master` branch, but I still consider it
+experimental, and of course the assistant still needs to be updated to
+support it.
diff --git a/doc/design/assistant/blog/day_155__bugfixes.mdwn b/doc/design/assistant/blog/day_155__bugfixes.mdwn
new file mode 100644
index 000000000..42a95cc5a
--- /dev/null
+++ b/doc/design/assistant/blog/day_155__bugfixes.mdwn
@@ -0,0 +1,15 @@
+Finished getting automatic merge conflict resolution working in direct
+mode. Turned out I was almost there yesterday, just a bug in a filename
+comparison needed to be fixed.
+
+Fixed a bug where the assistant dropped a file after transferring it,
+despite the preferred content settings saying it should keep its copy of
+the file. This turned out to be due to it reading the transfer info
+incorrectly, and adding a "\n" to the end of the filename, which caused the
+preferred content check to think it wasn't wanted after all. (Probably
+because it thought 0 copies of the file were wanted, but I didn't look into
+this in detail.)
+
+Worked on my test suite, particularly more QuickCheck tests. I need to
+use QuickCheck more, particularly when I've pairs of functions, like encode
+and decode, that make for easy QuickCheck properties.
diff --git a/doc/design/assistant/blog/day_156_and_157__direct_mode_assistant.mdwn b/doc/design/assistant/blog/day_156_and_157__direct_mode_assistant.mdwn
new file mode 100644
index 000000000..f49d2914f
--- /dev/null
+++ b/doc/design/assistant/blog/day_156_and_157__direct_mode_assistant.mdwn
@@ -0,0 +1,45 @@
+Over Christmas, I'm working on making the assistant support direct
+mode. I like to have a fairly detailed plan before starting this kind of
+job, but in this case, I don't. (Also I have a cold so planning? Meh.)
+This is a process of seeing what's broken in direct mode and fixing it.
+I don't know if it'll be easy or hard. Let's find out..
+
+* First, got direct mode adding of new files working. This was not hard, all the
+ pieces I needed were there. For now, it uses the same method as in
+ indirect mode to make sure nothing can modify the file while it's being
+ added.
+
+* An unexpected problem is that in its startup scan, the assistant runs
+ `git add --update` to detect and stage any deletions that happened
+ while it was not running. But in direct mode that also stages the full file
+ contents, so can't be used. Had to switch to using git plumbing to only
+ stage deleted files. Happily this also led to fixing a bug; deletions
+ were not always committed at startup when using the old method; with the
+ new method it can tell when there are deletions and trigger a commit.
+
+* Next, got it to commit when direct mode files are modified. The Watcher
+ thread gets a inotify event when this happens, so that was easy. (Although
+ in doing that I had to disable a guard in direct mode that made annexed
+ files co-exist with regular in-git files, so such mixed repositories
+ probably won't work in direct mode yet.)
+
+ However, naughty kqueue is another story, there are no kqueue events for
+ file modifications. So this won't work on OSX or the BSDs yet. I tried
+ setting some more kqueue flags in hope that one would make such events
+ appear, but no luck. Seems I will need to find some other method to detect
+ file modifications, possibly an OSX-specific API.
+
+* Another unexpected problem: When an assistant receives new files from one
+ of its remotes, in direct mode it still sets up symlinks to the content.
+ This was because the Merger thread didn't use the `sync` command's direct
+ mode aware merge code.. so fixed that.
+
+* Finally there was some direct mode bookeeping the assistant has
+ to get right. For example, when a file is modified, the old object has
+ to be looked up, and be marked as not locally present any longer. That
+ lookup relies on the already running `git cat-file --batch`, so it's
+ not as fast as it could be, if I kept a local cache of the mapping
+ between files and objects. But it seems fast enough for now.
+
+At this point the assistant seems to work in direct mode on Linux!
+Needs more testing..
diff --git a/doc/design/assistant/blog/day_158__fsevents.mdwn b/doc/design/assistant/blog/day_158__fsevents.mdwn
new file mode 100644
index 000000000..472b6c2be
--- /dev/null
+++ b/doc/design/assistant/blog/day_158__fsevents.mdwn
@@ -0,0 +1,20 @@
+Investigated using the OSX fsevents API to detect when files are modified,
+so they can be committed when using direct mode. There's a
+[haskell library](http://hackage.haskell.org/package/hfsevents-0.1.3)
+and even a [sample directory watching program](http://hackage.haskell.org/package/hobbes).
+Initial tests look good...
+
+Using fsevents will avoid kqueue's problems with needing enough file
+descriptors to open every subdirectory. kqueue is a rather poor match for
+git-annex's needs, really. It does not seem to provide events for file
+modifications at all, unless every *file* is individually opened. While I
+dislike leaving the BSD's out, they need a better interface to be perfectly
+supported by git-annex, and kqueue will still work for indirect mode
+repositories.
+
+----
+
+Got the assistant to use fsevents. It seems to work well!
+
+The only problem I know of is that it doesn't yet handle whole directory
+renames. That should be easy to fix later.
diff --git a/doc/design/assistant/blog/day_158__fsevents/comment_1_b278372ac6399f64d5fa9da178278a6d._comment b/doc/design/assistant/blog/day_158__fsevents/comment_1_b278372ac6399f64d5fa9da178278a6d._comment
new file mode 100644
index 000000000..a13936ed5
--- /dev/null
+++ b/doc/design/assistant/blog/day_158__fsevents/comment_1_b278372ac6399f64d5fa9da178278a6d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkey8WuXUh_x5JC2c9_it1CYRnVTgdGu1M"
+ nickname="Dustin"
+ subject="Linux Support"
+ date="2012-12-27T21:37:45Z"
+ content="""
+Does this mean Linux will not support Direct mode?
+"""]]
diff --git a/doc/design/assistant/blog/day_158__fsevents/comment_2_2d5ce9b2807068c3517e185945662bd2._comment b/doc/design/assistant/blog/day_158__fsevents/comment_2_2d5ce9b2807068c3517e185945662bd2._comment
new file mode 100644
index 000000000..edd63b125
--- /dev/null
+++ b/doc/design/assistant/blog/day_158__fsevents/comment_2_2d5ce9b2807068c3517e185945662bd2._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.127"
+ subject="comment 2"
+ date="2012-12-28T02:46:23Z"
+ content="""
+No, linux's inotify has everything I need for direct mode.
+"""]]
diff --git a/doc/design/assistant/blog/day_159__fsevents_and_assistant.mdwn b/doc/design/assistant/blog/day_159__fsevents_and_assistant.mdwn
new file mode 100644
index 000000000..754e2c91f
--- /dev/null
+++ b/doc/design/assistant/blog/day_159__fsevents_and_assistant.mdwn
@@ -0,0 +1,16 @@
+Short day today, but I spent it all on testing the new FSEvents code,
+getting it working with the assistant in direct mode. This included fixing
+its handling of renaming, and various other bugs.
+
+The assistant in direct mode now seems to work well on OSX. So I made
+the assistant *default* to making direct mode repositories on OSX.
+
+That'll presumably flush out any bugs. :) More importantly,
+it let me close several OSX-specific bugs to do with interactions between
+git-annex's symlinks and OSX programs that were apparently written under the
+misprehension that it's a user-mode program's job to manually follow symlinks.
+
+Of course, defaulting to direct mode also means users can just modify files
+as they like and the assistant will commit and sync the changed files.
+I'm waiting to see if direct mode becomes popular enough to make it the
+default on all OS's.
diff --git a/doc/design/assistant/blog/day_159__fsevents_and_assistant/comment_1_b85f446c3fa8d703a2a8882825c6f33f._comment b/doc/design/assistant/blog/day_159__fsevents_and_assistant/comment_1_b85f446c3fa8d703a2a8882825c6f33f._comment
new file mode 100644
index 000000000..8bc089857
--- /dev/null
+++ b/doc/design/assistant/blog/day_159__fsevents_and_assistant/comment_1_b85f446c3fa8d703a2a8882825c6f33f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="comment 1"
+ date="2012-12-28T23:53:22Z"
+ content="""
+Make a release please, Im eager to try it out!:)
+"""]]
diff --git a/doc/design/assistant/blog/day_159__fsevents_and_assistant/comment_2_a150b404e0c39e0bb2f7dd00cda63cdc._comment b/doc/design/assistant/blog/day_159__fsevents_and_assistant/comment_2_a150b404e0c39e0bb2f7dd00cda63cdc._comment
new file mode 100644
index 000000000..bc9c7031b
--- /dev/null
+++ b/doc/design/assistant/blog/day_159__fsevents_and_assistant/comment_2_a150b404e0c39e0bb2f7dd00cda63cdc._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnFhHPFP7j3wGNgBxEJoA8LcBJ4Xd1tTMY"
+ nickname="Joe"
+ subject="Release + Version Number"
+ date="2012-12-29T11:16:05Z"
+ content="""
+I second Laszlo's request for a release! Also, could you include a version number of some sort on the download (and binary if there isn't one there) to make it easy to tell what is available for download vs. what is installed?
+"""]]
diff --git a/doc/design/assistant/blog/day_159__fsevents_and_assistant/comment_3_37abc41bae23a1d7de0d19d952aec492._comment b/doc/design/assistant/blog/day_159__fsevents_and_assistant/comment_3_37abc41bae23a1d7de0d19d952aec492._comment
new file mode 100644
index 000000000..b08636fd8
--- /dev/null
+++ b/doc/design/assistant/blog/day_159__fsevents_and_assistant/comment_3_37abc41bae23a1d7de0d19d952aec492._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 3"
+ date="2012-12-29T13:26:30Z"
+ content="""
+There are daily/hourly builds at the [[install/OSX]] install page, try out the new features from there
+"""]]
diff --git a/doc/design/assistant/blog/day_15__its_aliiive.mdwn b/doc/design/assistant/blog/day_15__its_aliiive.mdwn
new file mode 100644
index 000000000..10ef4ffe5
--- /dev/null
+++ b/doc/design/assistant/blog/day_15__its_aliiive.mdwn
@@ -0,0 +1,33 @@
+Syncing works! I have two clones, and any file I create in the first
+is immediately visible in the second. Delete that file from the second, and
+it's immediately removed from the first.
+
+Most of my work today felt like stitching existing limbs onto a pre-existing
+monster. Took the committer thread, that waits for changes and commits them,
+and refashioned it into a pusher thread, that waits for commits and pushes
+them. Took the watcher thread, that watches for files being made,
+and refashioned it into a merger thread, that watches for git refs being
+updated. Pulled in bits of the `git annex sync` command to reanimate this.
+
+It may be a shambling hulk, but it works.
+
+Actually, it's not much of a shambling hulk; I refactored my code after
+copying it. ;)
+
+I think I'm up to 11 threads now in the new
+`git annex assistant` command, each with its own job, and each needing
+to avoid stepping on the other's toes. I did see one MVar deadlock error
+today, which I have not managed to reproduce after some changes. I think
+the committer thread was triggering the merger thread, which probably
+then waited on the Annex state MVar the committer thread had held.
+
+Anyway, it even pushes to remotes in parallel, and keeps track of remotes
+it failed to push to, although as of yet it doesn't do any attempt at
+periodically retrying.
+
+One bug I need to deal with is that the push code assumes any change
+made to the remote has already been pushed back to it. When it hasn't,
+the push will fail due to not being a fast-forward. I need to make it
+detect this case and pull before pushing.
+
+(I've pushed this work out in a new `assistant branch`.)
diff --git a/doc/design/assistant/blog/day_160__finishing_up_direct_mode.mdwn b/doc/design/assistant/blog/day_160__finishing_up_direct_mode.mdwn
new file mode 100644
index 000000000..c789ca2f6
--- /dev/null
+++ b/doc/design/assistant/blog/day_160__finishing_up_direct_mode.mdwn
@@ -0,0 +1,10 @@
+A few final bits and pieces of direct mode. Fixed a few more bugs in the
+assistant. Made all git-annex commands that don't work at
+all, or only partially work in direct mode, refuse to run at all. Also,
+some optimisations.
+
+I'll surely need to revisit direct mode later and make more commands
+support it; `fsck` and `add` especially.
+But the only thing I'd like to deal with before I make a release with direct
+mode is the problem of files being able to be modified while they're
+being transferred, which can result in data loss.
diff --git a/doc/design/assistant/blog/day_161__release_day.mdwn b/doc/design/assistant/blog/day_161__release_day.mdwn
new file mode 100644
index 000000000..5e3a62168
--- /dev/null
+++ b/doc/design/assistant/blog/day_161__release_day.mdwn
@@ -0,0 +1,8 @@
+Released the first git-annex with direct mode today. Notably, the assistant
+enables direct mode in repositories it creates. All builds are updated to
+3.20130102 now.
+
+My plan for this month is to fix whatever things currently might be
+preventing you from using the git-annex assistant. So bugfixes and
+whatever other important gaps need to be filled, but no major new
+feature developments.
diff --git a/doc/design/assistant/blog/day_161__release_day/comment_1_e82c67f3ce216618149537bba1e0b850._comment b/doc/design/assistant/blog/day_161__release_day/comment_1_e82c67f3ce216618149537bba1e0b850._comment
new file mode 100644
index 000000000..f697d12dc
--- /dev/null
+++ b/doc/design/assistant/blog/day_161__release_day/comment_1_e82c67f3ce216618149537bba1e0b850._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="comment 1"
+ date="2013-01-02T21:26:32Z"
+ content="""
+1. Im not able to set direct mode (linux build, Version: 3.20130102 in about page).
+Is there something specific needed? I started fresh. I added a new directory (empty), once
+git annex assistant started, I copied files to that directory, and the assistant
+replaced all files with symlinks, just as before.
+What am I missing here?
+
+2. It is just minor usability remark:
+ I would like to see in the gui somewhere shown where the actual config is stored (~/.config/git-annex),
+and an option to wipe it out and start fresh. Also a restart button.
+
+Best, Laszlo
+
+"""]]
diff --git a/doc/design/assistant/blog/day_161__release_day/comment_2_b1fe96fd818935c0497b78bb8ad32ffa._comment b/doc/design/assistant/blog/day_161__release_day/comment_2_b1fe96fd818935c0497b78bb8ad32ffa._comment
new file mode 100644
index 000000000..1e44738a1
--- /dev/null
+++ b/doc/design/assistant/blog/day_161__release_day/comment_2_b1fe96fd818935c0497b78bb8ad32ffa._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.211"
+ subject="comment 2"
+ date="2013-01-03T17:59:22Z"
+ content="""
+\"I added a new directory (empty)\"
+
+Sounds like you set up the repository yourself, rather than letting the assistant do it. If so, it won't be in direct mode. You can `git annex assistant--stop`, and then `git annex direct` to enable direct mode.
+
+Restart/shutdown in the UI coming soon, I think.
+
+The entire git-annex configuration, include that of the assistant, is stored in the `.git/config` of your reposository, and on its `git-annex` branch. Deleting the repository is thus all that's needed to start over.
+"""]]
diff --git a/doc/design/assistant/blog/day_161__release_day/comment_3_40bac0e1756aa77bb966c4654857141c._comment b/doc/design/assistant/blog/day_161__release_day/comment_3_40bac0e1756aa77bb966c4654857141c._comment
new file mode 100644
index 000000000..5bb35353b
--- /dev/null
+++ b/doc/design/assistant/blog/day_161__release_day/comment_3_40bac0e1756aa77bb966c4654857141c._comment
@@ -0,0 +1,44 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="comment 3"
+ date="2013-01-03T22:23:36Z"
+ content="""
+>> I added a new directory (empty)
+
+> Sounds like you set up the repository yourself, rather than letting the assistant do it.
+> If so, it won't be in direct mode. You can git annex assistant--stop,
+> and then git annex direct to enable direct mode.
+
+I added like this:
+0. no git-annex or git-annex-assistant is running
+1. create directory (/mnt/dxd/annex)
+2. launch git-annex-assistant
+3. add repository via the webbrowser
+4. copy a file over this(/mnt/dxd/annex) directory (via command line or nautilus)
+
+The file is replaced with symlink.
+
+This fix the issue:
+0. stop git-annex-assistant
+1. Go in the shell to that directory (cd /mnt/dxd/annex)
+2. switch to direct mode (/home/looser/Desktop/download/git-annex.linux/git-annex direct)
+3. start git-annex-assistant
+4. create a new repository(/mnt/dxd/annex2) via the webbrowser (add repository in top right corner)
+5. Now:
+/mnt/dxd/annex - NOT in direct mode (symlinks created instantly)
+/mnt/dxd/annex2 - in direct mode
+
+Im really happy I have finally direct mode running.
+I will surely stress-test git-annex in the coming weeks.
+
+> Restart/shutdown in the UI coming soon, I think.
+
+Awesome.
+
+> The entire git-annex configuration, include that of the assistant,
+> is stored in the .git/config of your reposository, and on its git-annex branch.
+> Deleting the repository is thus all that's needed to start over.
+
+Thank you for the answer.
+"""]]
diff --git a/doc/design/assistant/blog/day_161__release_day/comment_4_af65656b0d1179636937595868bb97b0._comment b/doc/design/assistant/blog/day_161__release_day/comment_4_af65656b0d1179636937595868bb97b0._comment
new file mode 100644
index 000000000..178e2ead4
--- /dev/null
+++ b/doc/design/assistant/blog/day_161__release_day/comment_4_af65656b0d1179636937595868bb97b0._comment
@@ -0,0 +1,30 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="comment 4"
+ date="2013-01-03T22:33:54Z"
+ content="""
+Usecase:
+Keep two directories in sync on the same computer.
+
+\"Removable drive\" almost covers this, except you need an usb thumbdrive
+permanently plugged into the computer.
+
+Would be nice, if I could select a \"sync to this local folder\" option
+alongside the \"Select drive:\" option.
+
+So it is my choice if I want to sync to a partition or to a folder.
+
+Bug(?):
+I created two repositories:
+/mnt/dxd/annex
+/mnt/dxd/annex2
+
+And I added a \"Removable drive\" syncing option to /mnt/dxd/annex2, and I selected the \"/mnt/dxd\" drive as removable drive.
+The two repositories got mixed together
+(ie. broken symlinks pointing to nonexistent .git/annex/objects/.. file)
+
+Best,
+ Laszlo
+
+"""]]
diff --git a/doc/design/assistant/blog/day_161__release_day/comment_5_0c05caaaf9588e124585041bf5f45d75._comment b/doc/design/assistant/blog/day_161__release_day/comment_5_0c05caaaf9588e124585041bf5f45d75._comment
new file mode 100644
index 000000000..e461bfdc4
--- /dev/null
+++ b/doc/design/assistant/blog/day_161__release_day/comment_5_0c05caaaf9588e124585041bf5f45d75._comment
@@ -0,0 +1,20 @@
+[[!comment format=c
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="comment 5"
+ date="2013-01-03T22:49:41Z"
+ content="""
+Ok, I think I figured it out. I have quit from git-annex-assistant (Ctrl-C in terminal window).
+
+And launched this command:
+$ ps -e |grep git-ann
+ 1782 ? 00:01:00 git-annex
+20144 pts/0 00:00:00 git-annex-webap
+20148 pts/0 00:00:00 git-annex
+20178 pts/0 00:00:00 git-annex <defunct>
+20508 pts/0 00:00:00 git-annex <defunct>
+20528 ? 00:00:02 git-annex
+21132 ? 00:00:00 git-annex <defunct>
+
+I will be more cautious in future.
+"""]]
diff --git a/doc/design/assistant/blog/day_161__release_day/comment_6_5dfb5f428633d6062925f61af2b8829b._comment b/doc/design/assistant/blog/day_161__release_day/comment_6_5dfb5f428633d6062925f61af2b8829b._comment
new file mode 100644
index 000000000..f9683c820
--- /dev/null
+++ b/doc/design/assistant/blog/day_161__release_day/comment_6_5dfb5f428633d6062925f61af2b8829b._comment
@@ -0,0 +1,23 @@
+[[!comment format=c
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="comment 6"
+ date="2013-01-03T22:55:41Z"
+ content="""
+another problem:
+1. If you add a removable drive via the gui, you can not remove it anymore (from the gui)
+2. If you delete the directory on the removable drive, git-annex assistant silently fails
+to recreate the directory and start fresh.
+2/a. on the gui, there is no indication something is wrong with the removable drive repository
+2/b on the terminal it shows only this:
+fatal: Not a git repository: '/mnt/dxd/annex/.git'
+
+On the main page it shows the two repositories, but on the upper right corner, the dropdown menu
+contains only the original repository and not the removeable drive repository.
+
+I stop spaming now...
+
+Laszlo
+
+
+"""]]
diff --git a/doc/design/assistant/blog/day_161__release_day/comment_7_ac4effb381b08d94d4a2d2482e92c89a._comment b/doc/design/assistant/blog/day_161__release_day/comment_7_ac4effb381b08d94d4a2d2482e92c89a._comment
new file mode 100644
index 000000000..359947a5a
--- /dev/null
+++ b/doc/design/assistant/blog/day_161__release_day/comment_7_ac4effb381b08d94d4a2d2482e92c89a._comment
@@ -0,0 +1,13 @@
+[[!comment format=c
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="comment 7"
+ date="2013-01-03T23:07:27Z"
+ content="""
+Can not withstand myself.
+
+1. If you add a Removable drive repository, only the *new* files are copied over to the removable drive.
+2. Removable drive repository is not in direct mode.
+Would be nice if it could be kept the same mode as the original repository.
+It is some kind of special repsoitory, I do not see any seemlinks either.
+"""]]
diff --git a/doc/design/assistant/blog/day_161__release_day/comment_8_32600e89e3098e52a1280895e03b3f86._comment b/doc/design/assistant/blog/day_161__release_day/comment_8_32600e89e3098e52a1280895e03b3f86._comment
new file mode 100644
index 000000000..c220fc826
--- /dev/null
+++ b/doc/design/assistant/blog/day_161__release_day/comment_8_32600e89e3098e52a1280895e03b3f86._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://csights.myopenid.com/"
+ ip="70.226.161.163"
+ subject="walkthroughs?"
+ date="2013-01-04T02:39:59Z"
+ content="""
+Could you post some walk-throughs?
+Is it possible to set up a direct mode repository using git-annex webapp ?
+
+Thanks for your work! Sad to hear you had to get a generator. :)
+C.
+
+"""]]
diff --git a/doc/design/assistant/blog/day_161__release_day/comment_9_07e5d0c3cad0ce2bd4943e53b61f1767._comment b/doc/design/assistant/blog/day_161__release_day/comment_9_07e5d0c3cad0ce2bd4943e53b61f1767._comment
new file mode 100644
index 000000000..fc8c9c4b1
--- /dev/null
+++ b/doc/design/assistant/blog/day_161__release_day/comment_9_07e5d0c3cad0ce2bd4943e53b61f1767._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="spwhitton"
+ ip="163.1.166.255"
+ subject="comment 9"
+ date="2013-01-04T20:26:46Z"
+ content="""
+You noted in a recent blog post that direct mode won't work with mixed repositories, that is, those that have files checked into git alongside annexed ones. Is this still the case? Thanks.
+"""]]
diff --git a/doc/design/assistant/blog/day_162__UI.mdwn b/doc/design/assistant/blog/day_162__UI.mdwn
new file mode 100644
index 000000000..8994835c6
--- /dev/null
+++ b/doc/design/assistant/blog/day_162__UI.mdwn
@@ -0,0 +1,17 @@
+[Installed a generator](http://joeyh.name/blog/entry/overcast/),
+so I'll have more power and less hibernation.
+
+Added UI in the webapp to shut down the daemon. Would like to also have
+restart UI, but that's rather harder to do, seems it'd need to start
+another copy of the webapp (and so, of the assistant), and redirect the
+browser to its new url. ... But running two assistants in the same repo at
+the same time isn't good. Anyway, users can now use the UI to shut it down,
+and then use their native desktop UI to start it back up.
+
+[[!img /assistant/controlmenu.png]]
+
+Spiffed up the control menu. Had to stop listing other local repositories
+in the menu, because there was no way to notice when a new one was added
+(without checking a file on every page load, which is way overkill for this
+minor feature). Instead added a new page that lists local repositories it
+can switch to.
diff --git a/doc/design/assistant/blog/day_163__free_features.mdwn b/doc/design/assistant/blog/day_163__free_features.mdwn
new file mode 100644
index 000000000..444b6cc30
--- /dev/null
+++ b/doc/design/assistant/blog/day_163__free_features.mdwn
@@ -0,0 +1,32 @@
+There was a typo in cabal file that broke building the assistant on OSX.
+This didn't affect the autobuilds of the app, but several users building by
+hand reported problems. I made a new minor release fixing that typo, and
+also a resouce leak bug.
+
+Got a restart UI working after all. It's a hack though. It
+opens a new tab for the new assistant instance, and as most web browsers
+don't allow javascript to close tabs, the old tab is left open. At some
+point I need to add a proper thread manager to the assistant, which the
+restart code could use to kill the watcher and committer threads, and then
+I could do a clean restart, bringing up the new daemon and redirecting the
+browser to it.
+
+Found a bug in the assistant in direct mode -- the expensive transfer scan
+didn't queue uploads needed to sync to other repos in direct mode, although
+it did queue downloads. Fixing this laid some very useful groundwork for
+making more commands support direct mode, too. Got stuck for a long time
+dealing with some very strange `git-cat-file` behavior while making this
+work. Ended up putting in a workaround.
+
+After that, I found that these commands work in direct mode, without
+needing any futher changes!
+
+* `git annex find`
+* `git annex whereis`
+* `git annex copy`
+* `git annex move`
+* `git annex drop`
+* `git annex log`
+
+Enjoy! The only commands I'd like to add to this are `fsck`, `add`,
+and `addurl`...
diff --git a/doc/design/assistant/blog/day_164__bugfixes.mdwn b/doc/design/assistant/blog/day_164__bugfixes.mdwn
new file mode 100644
index 000000000..1edca3d19
--- /dev/null
+++ b/doc/design/assistant/blog/day_164__bugfixes.mdwn
@@ -0,0 +1,17 @@
+Several bugfixes from user feedback today.
+
+Made the assistant detect misconfigured systems where git will fail to
+commit because it cannot determine the user's name or email address, and
+dummy up enough info to get git working. It makes sense for git and
+git-annex to fail at the command line on such a misconfigured system, so
+the user can fix it, but for the assistant it makes sense to plow on and just
+work.
+
+I found a big gap in direct mode -- all the special remotes expected to find
+content in the indirect mode location when transferring to the remote. It
+was easy to fix once I noticed the problem. This is a big enough bug that
+I will be making a new release in a day or so.
+
+Also, got fsck working in direct mode. It doesn't check as many things
+as in indirect mode, because direct mode files can be modified at any time.
+Still, it's usable, and useful.
diff --git a/doc/design/assistant/blog/day_165__release_day.mdwn b/doc/design/assistant/blog/day_165__release_day.mdwn
new file mode 100644
index 000000000..f29c6e589
--- /dev/null
+++ b/doc/design/assistant/blog/day_165__release_day.mdwn
@@ -0,0 +1,16 @@
+(Posted a day late.) [[!meta date="Mon Jan 7 16:05:13 JEST 2013"]]
+
+Got `git annex add` (and `addurl`) working in direct mode. This allowed me
+to make `git annex sync` in direct mode no longer automatically add new
+files.
+
+It's also now safe to mix direct mode annexed files with regular files in
+git, in the same repository. Might have been safe all along, but I've
+tested it, and it certainly works now. You just have to be careful to not
+use `git commit -a` to commit changes to such files, since that'll also
+stage the entire content of direct mode files.
+
+Made a minor release for these recent changes and bugfixes. Recommended if
+you're using direct mode. Had to chase down a stupid typo I made yesterday
+that caused fsck to infinite loop if it found a corrupted file. Thank
+goodness for test suites.
diff --git a/doc/design/assistant/blog/day_166__a_short_long_day.mdwn b/doc/design/assistant/blog/day_166__a_short_long_day.mdwn
new file mode 100644
index 000000000..5f03fd1cf
--- /dev/null
+++ b/doc/design/assistant/blog/day_166__a_short_long_day.mdwn
@@ -0,0 +1,25 @@
+I was up at the crack of dawn wrestling 100 pound batteries around for 3
+hours and rewiring most of my battery bank, so today is a partial day...
+but a day with power, which is always nice.
+
+Did some design work on finally making transfers of files from direct mode
+repositories safe, even if a file is modified as it's being uploaded.
+This seems easily doable for special remotes; git to git repository
+transfers are harder, but I think I see how to do it without breaking
+backwards compatability.
+
+(An unresolved problem is that a temp file would be left behind when a
+transfer failed due to a file being changed. What would really be nice to
+do is to use that temp file as the rsync basis when transferring the new
+version of a file. Although this really goes beyond direct mode, and into
+[[deltas]] territory.)
+
+Made fsck work better in direct mode repositories. While it's expected for
+files to change at any time in direct mode, and so fsck cannot complain
+every time there's a checksum mismatch, it is possible for it to detect
+when a file does not *seem* to have changed, then check its checksum,
+and so detect disk corruption or other data problems.
+
+Also dealt with several bug reports. One really weird one involves `git
+cat-file` failing due to some kind of gpg signed data in the git-annex
+branch. I don't understand that at all yet.
diff --git a/doc/design/assistant/blog/day_167__safe_direct_mode_transfers.mdwn b/doc/design/assistant/blog/day_167__safe_direct_mode_transfers.mdwn
new file mode 100644
index 000000000..8aa15fb13
--- /dev/null
+++ b/doc/design/assistant/blog/day_167__safe_direct_mode_transfers.mdwn
@@ -0,0 +1,12 @@
+Well underway on making direct mode transfers roll back when the file is
+modified while it's transferred.
+
+As expected, it was easy to do for all the special remotes ... Except for
+bup, which does not allow deleting content. For bup it just removes the git
+ref for the bad content, and relies on bup's use of git delta compression
+to keep space use sane.
+
+The problem is also handled by `git-annex-shell sendkey`.
+But not yet for downloads from other git repositories. Bit stuck on that.
+
+Also: A few minor bug fixes.
diff --git a/doc/design/assistant/blog/day_167__safe_direct_mode_transfers/comment_1_f1aa64fe803d8c14b250a4e98b88142a._comment b/doc/design/assistant/blog/day_167__safe_direct_mode_transfers/comment_1_f1aa64fe803d8c14b250a4e98b88142a._comment
new file mode 100644
index 000000000..4b5092036
--- /dev/null
+++ b/doc/design/assistant/blog/day_167__safe_direct_mode_transfers/comment_1_f1aa64fe803d8c14b250a4e98b88142a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm7AuSfii_tCkLyspL6Mr0ATlO6OxLNYOo"
+ nickname="Georg"
+ subject="comment 1"
+ date="2013-01-10T08:49:20Z"
+ content="""
+hmm, wouldn't it make sense to do the downloads into the annex object space, just like with indirect annexes? Then when the download is complete, with indirect annexes you create a soft link and with direct annexes you move the file (or create a hardlink and remove the directory entry in the annex object space)? Actually when you started to talk about direct I first envisioned it to be exactly like indirect, only with hard links instead of soft links.
+"""]]
diff --git a/doc/design/assistant/blog/day_167__safe_direct_mode_transfers/comment_2_5ce1db84c9ead713f1272c4975645b93._comment b/doc/design/assistant/blog/day_167__safe_direct_mode_transfers/comment_2_5ce1db84c9ead713f1272c4975645b93._comment
new file mode 100644
index 000000000..c1b2724cb
--- /dev/null
+++ b/doc/design/assistant/blog/day_167__safe_direct_mode_transfers/comment_2_5ce1db84c9ead713f1272c4975645b93._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.238"
+ subject="comment 2"
+ date="2013-01-10T16:06:28Z"
+ content="""
+That is how direct mode works. (Although without the hard links, since maintaining them doesn't have any benefits.) And that's how downloading into a direct mode repo works. The issue I'm dealing with, though, is uploading from a direct mode repo, where the file that's being uploaded can be modified at the same time.
+"""]]
diff --git a/doc/design/assistant/blog/day_168__back_to_theme.mdwn b/doc/design/assistant/blog/day_168__back_to_theme.mdwn
new file mode 100644
index 000000000..ff230e764
--- /dev/null
+++ b/doc/design/assistant/blog/day_168__back_to_theme.mdwn
@@ -0,0 +1,18 @@
+This month's theme is supposed to be fixing up whatever might prevent users
+from using the assistant. To that end, I've posted an open-ended poll,
+[[polls/what is preventing me from using git-annex assistant]]. Please go
+fill it out so I can get an idea of how many people are using the
+assistant, and what needs to be done to get the rest of you, and your
+friends and family able to use it.
+
+In the meantime, today I fixed several bugs that were recently reported in
+the webapp and assistant. Getting it working as widely as possible, even on
+strange IPv6 only systems, and with browsers that didn't like my generated
+javascript code is important, and fits right into this month's theme. I'm
+happy to see lots of bugs being filed, since it means more users are trying
+the assistant out.
+
+Also continued work on making direct mode transfers safe. All transfers to
+local git remotes (wish I had a better phrase!) are now safe in direct mode.
+Only uploading from a direct mode repository over ssh to another git
+repository is still potentially unsafe.
diff --git a/doc/design/assistant/blog/day_168__back_to_theme/comment_1_f248780bfcbd0384d9d72c2633a4ea46._comment b/doc/design/assistant/blog/day_168__back_to_theme/comment_1_f248780bfcbd0384d9d72c2633a4ea46._comment
new file mode 100644
index 000000000..eaa098d69
--- /dev/null
+++ b/doc/design/assistant/blog/day_168__back_to_theme/comment_1_f248780bfcbd0384d9d72c2633a4ea46._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://jasonwoof.com/"
+ nickname="JasonWoof"
+ subject="phrase suggestion"
+ date="2013-01-11T00:24:39Z"
+ content="""
+I suggest using the term \"repository\" not \"remote\". Two reasons: 1: it's a noun in *English. 2: it works for both local and remote repositories.
+
+Both get +1 because they match git terminology. (I have a secret dream that the assistant might bring people to git, maybe that's silly.)
+
+\* OK, so \"remote\" is also a noun in English, but it means the widget with buttons that controls the tv/whatever.
+"""]]
diff --git a/doc/design/assistant/blog/day_168__back_to_theme/comment_2_5beba073373b8e75a32d1fcfdc1a0782._comment b/doc/design/assistant/blog/day_168__back_to_theme/comment_2_5beba073373b8e75a32d1fcfdc1a0782._comment
new file mode 100644
index 000000000..630892025
--- /dev/null
+++ b/doc/design/assistant/blog/day_168__back_to_theme/comment_2_5beba073373b8e75a32d1fcfdc1a0782._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://csights.myopenid.com/"
+ ip="70.226.161.163"
+ subject="&quot;local git remotes&quot;"
+ date="2013-01-13T02:36:48Z"
+ content="""
+I am not quite sure how git-annex works and I do not know what a \"local git remote\" functionality is.
+
+How about this: call a \"git remote\" a \"git-annex store\" or just \"store\". Then instead of a remote git remote it would be a remote git-annex store or just remote store. :)
+
+
+
+"""]]
diff --git a/doc/design/assistant/blog/day_169__direct_mode_is_safe.mdwn b/doc/design/assistant/blog/day_169__direct_mode_is_safe.mdwn
new file mode 100644
index 000000000..c3f569bd8
--- /dev/null
+++ b/doc/design/assistant/blog/day_169__direct_mode_is_safe.mdwn
@@ -0,0 +1,24 @@
+I've finished making direct mode file transfers safe. The last piece of the
+puzzle was making `git-annex-shell recv-key` check data it's received from
+direct mode repositories. This is a bit expensive, but avoids adding
+another round-trip to the protocol. I might revisit this later, this was
+just a quick fix.
+
+---
+
+The [[poll|polls/what is preventing me from using git-annex assistant]] was
+quite useful. Some interesting points:
+
+* 14% have been reading this blog, and rightly don't trust direct mode to
+ be safe. Which is why I went ahead with a quick fix to make it safe.
+* 6% want an Ubuntu PPA. I don't anticipate doing this myself, but
+ if anyone who develops for Ubuntu wants to put together a PPA with a
+ newer version, I can help you pick the newer haskell packages you'll
+ need from Debian, etc.
+* 9% just need me to update the amd64 build in Debian sid. I forgot to
+ include it in the last release, and the Debian buildds cannot currently
+ autobuild git-annex due to some breakage in the versions of haskell
+ libraries in unstable. Hopefully I'll remember to include an amd64 build
+ in my next release.
+
+And lots of other interesting stuff, I have a nice new TODO list now. :)
diff --git a/doc/design/assistant/blog/day_169__direct_mode_is_safe/comment_1_65f87656c4e6bc7cdb614f53961341c9._comment b/doc/design/assistant/blog/day_169__direct_mode_is_safe/comment_1_65f87656c4e6bc7cdb614f53961341c9._comment
new file mode 100644
index 000000000..b51153cad
--- /dev/null
+++ b/doc/design/assistant/blog/day_169__direct_mode_is_safe/comment_1_65f87656c4e6bc7cdb614f53961341c9._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="spwhitton"
+ ip="163.1.166.255"
+ subject="comment 1"
+ date="2013-01-11T20:25:48Z"
+ content="""
+If you have time, an updated sid package for armel would be much appreciated.
+"""]]
diff --git a/doc/design/assistant/blog/day_169__direct_mode_is_safe/comment_2_a116a402a126c62be54c06afd82439ab._comment b/doc/design/assistant/blog/day_169__direct_mode_is_safe/comment_2_a116a402a126c62be54c06afd82439ab._comment
new file mode 100644
index 000000000..7afd951e1
--- /dev/null
+++ b/doc/design/assistant/blog/day_169__direct_mode_is_safe/comment_2_a116a402a126c62be54c06afd82439ab._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="http://csights.myopenid.com/"
+ ip="70.226.161.163"
+ subject="use debian repos instead of Ubuntu PPA?"
+ date="2013-01-12T13:43:44Z"
+ content="""
+Maybe Ubuntu users would be satisfied with tweaks to their sources.list and preferences?
+
+/etc/apt/sources.list.d/git-annex.sources.list
+deb http://ftp.us.debian.org/debian unstable main
+
+/etc/apt/preferences.d/git-annex.preferences
+Package: *
+Pin: release a=unstable,o=Debian
+Pin-Priority: 400
+
+
+Not sure how that will work out in Ubuntu package manager. In aptitude you'll get warning about untrusted repos (maybe install Debian's gpg keys) and will probably have to manually select dependencies from Debian repos.
+"""]]
diff --git a/doc/design/assistant/blog/day_16__more_robust_syncing.mdwn b/doc/design/assistant/blog/day_16__more_robust_syncing.mdwn
new file mode 100644
index 000000000..e9343f846
--- /dev/null
+++ b/doc/design/assistant/blog/day_16__more_robust_syncing.mdwn
@@ -0,0 +1,44 @@
+I released a version of git-annex over the weekend that includes the `git
+annex watch` command. There's a minor issue installing it from cabal on
+OSX, which I've fixed in my tree. Nice timing: At least the watch command
+should be shipped in the next Debian release, which freezes at the end of
+the month.
+
+Jimmy found out how kqueue [[blows
+up|bugs/Issue_on_OSX_with_some_system_limits]] when there are too many
+directories to keep all open. I'm not surprised this happens, but it's nice
+to see exactly how. Odd that it happened to him at just 512 directories;
+I'd have guessed more. I have plans to fork watcher programs that each
+watch 512 directories (or whatever the ulimit is), to deal with this. What
+a pitiful interface is kqueue.. I have not thought yet about how the watcher
+programs would communicate back to the main program.
+
+----
+
+Back on the assistant front, I've worked today on making git syncing more
+robust. Now when a push fails, it tries a pull, and a merge, and repushes.
+That ensures that the push is, almost always, a fast-forward. Unless
+something else gets in a push first, anyway!
+
+If a push still fails, there's Yet Another Thread, added today, that will
+wake up after 30 minutes and retry the push. It currently keeps retrying
+every 30 minutes until the push finally gets though. This will deal, to
+some degree, with those situations where a remote is only sometimes
+available.
+
+I need to refine the code a bit, to avoid it keeping an ever-growing queue
+of failed pushes, if a remote is just dead. And to clear old failed pushes
+from the queue when a later push succeeds.
+
+I also need to write a git merge driver that handles conflicts in the tree.
+If two conflicting versions of a file `foo` are saved, this would merge
+them, renaming them to `foo.X` and `foo.Y`. Probably X and Y are the
+git-annex keys for the content of the files; this way all clones will
+resolve the conflict in a way that leads to the same tree. It's also
+possible to get a conflict by one repo deleting a file, and another
+modifying it. In this case, renaming the deleted file to `foo.Y` may
+be the right approach, I am not sure.
+
+I glanced through some Haskell dbus bindings today. I belive there are dbus
+events available to detect when drives are mounted, and on Linux this would
+let git-annex notice and sync to usb drives, etc.
diff --git a/doc/design/assistant/blog/day_16__more_robust_syncing/comment_1_23e7a90429e4431f90787cd016ebe188._comment b/doc/design/assistant/blog/day_16__more_robust_syncing/comment_1_23e7a90429e4431f90787cd016ebe188._comment
new file mode 100644
index 000000000..fece5c9af
--- /dev/null
+++ b/doc/design/assistant/blog/day_16__more_robust_syncing/comment_1_23e7a90429e4431f90787cd016ebe188._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="comment 1"
+ date="2012-06-27T12:46:31Z"
+ content="""
+can X and Y be the names of the git-annex remotes?
+"""]]
diff --git a/doc/design/assistant/blog/day_16__more_robust_syncing/comment_2_8e7e7cd27791bb47625e60a284e9c802._comment b/doc/design/assistant/blog/day_16__more_robust_syncing/comment_2_8e7e7cd27791bb47625e60a284e9c802._comment
new file mode 100644
index 000000000..e47b03d48
--- /dev/null
+++ b/doc/design/assistant/blog/day_16__more_robust_syncing/comment_2_8e7e7cd27791bb47625e60a284e9c802._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.2.189"
+ subject="comment 2"
+ date="2012-07-26T17:27:39Z"
+ content="""
+That's a good question. Unfortunatly they cannot; X and Y need to be stable across repositories, and git remotes can have different names in different repositories.
+
+Even using the description that git-annex stores for each repository for X and Y is problimatic, since that description can change, and so could be different in two repos that are each trying to resolve the same merge conflict.
+"""]]
diff --git a/doc/design/assistant/blog/day_170__bugfixes_and_release.mdwn b/doc/design/assistant/blog/day_170__bugfixes_and_release.mdwn
new file mode 100644
index 000000000..251ee7636
--- /dev/null
+++ b/doc/design/assistant/blog/day_170__bugfixes_and_release.mdwn
@@ -0,0 +1,8 @@
+Fixed a goodly amount of bugs today.
+
+The most interesting change was that in direct mode, files using the same
+key are no longer hardlinked, as that could cause a surprising behavior if
+modifying one, where the other would also change.
+
+Made a release, which is almost entirely bug fixes. Debian amd64 build
+included this time. :)
diff --git a/doc/design/assistant/blog/day_171__logs.mdwn b/doc/design/assistant/blog/day_171__logs.mdwn
new file mode 100644
index 000000000..7c7a4c821
--- /dev/null
+++ b/doc/design/assistant/blog/day_171__logs.mdwn
@@ -0,0 +1,23 @@
+I've noticed people have some problems getting me logs when there'a a bug,
+so I worked on improving the logging of the assistant.
+
+While the assistant logged to `.git/annex/daemon.log` when started as a
+daemon, when the webapp ran it didn't log there. It's somewhat tricky to
+make the webapp redirect messages to the log, because it may start a web
+browser that wants to write to the console. Took some file descriptor
+juggling, but I made this work. Now the log is even used when the assistant
+is started for the first time in a newly created repository. So, we have
+total log coverage.
+
+Next, I made a simple page in the webapp to display the accumulated logs.
+It does not currently refresh as new things are logged. But it's easier
+for me to tell users to click on `Current Repository -> View log` than
+ask for them to look for the daemon.log file.
+
+Finally, I made all the webapp's alerts also be written to the log.
+
+---
+
+Also did the requisite bug fixes.
+
+[[!img /assistant/logs.png alt="screenshot of logs page"]]
diff --git a/doc/design/assistant/blog/day_172__short_day.mdwn b/doc/design/assistant/blog/day_172__short_day.mdwn
new file mode 100644
index 000000000..031f90e0f
--- /dev/null
+++ b/doc/design/assistant/blog/day_172__short_day.mdwn
@@ -0,0 +1,22 @@
+Only one bug fix today, but it was a doozie. It seems that gpg2 has an
+incompatability with the gpg 1.x that git-annex was written for, that
+causes large numbers of excess passphrase prompts, when it's supposed to be
+using a remote's symmetric encryption key. Adding the --batch parameter
+fixed this.
+
+I also put together a page listing [[related_software]] to git-annex.
+
+I've also updated [[direct_mode]]'s documentation, about when it's safe to
+use direct mode. The intuition I've developed about direct mode is that if
+you don't need full versioning of files (with the ability to get back old
+versions), direct mode is fine and safe to use. If you want full
+versioning, it's best to not use direct mode. Or a reasonable compromise is
+to `git annex untrust` the direct mode repository and set up a backup remote.
+With this compromise, only if you edit a file twice in a row might the old
+version get lost before it can be backed up.
+
+Of course, it would be possible to make direct mode fully version
+preserving, but it'd have to back up every file in the repository locally
+to do so. Going back to two local copies of every file, which is part of
+git that git-annex happily avoids. Hmm, it might be possible to only back
+up a file locally until it reaches the backup remote..
diff --git a/doc/design/assistant/blog/day_172__short_day/comment_1_b75e26b77a23a45da1c4c3bca1399246._comment b/doc/design/assistant/blog/day_172__short_day/comment_1_b75e26b77a23a45da1c4c3bca1399246._comment
new file mode 100644
index 000000000..c7d4c74ca
--- /dev/null
+++ b/doc/design/assistant/blog/day_172__short_day/comment_1_b75e26b77a23a45da1c4c3bca1399246._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://launchpad.net/~rubiojr"
+ nickname="rubiojr"
+ subject="comment 1"
+ date="2013-01-18T18:42:35Z"
+ content="""
+Awesome @joey, crisp clear.
+
+I guess that most people used to the Dropbox way of doing things will not miss versioning that much, which is not very useful for medium/large binary files in most cases I'd say.
+
+Being able to choose the mode for power users is pretty cool though.
+"""]]
diff --git a/doc/design/assistant/blog/day_173__snow_day.mdwn b/doc/design/assistant/blog/day_173__snow_day.mdwn
new file mode 100644
index 000000000..9b07a8c5f
--- /dev/null
+++ b/doc/design/assistant/blog/day_173__snow_day.mdwn
@@ -0,0 +1,22 @@
+When I wasn't dealing with the snowstorm today, I was fixing more bugs.
+Rather serious bugs.
+
+One actually involved corruption to git-annex's location tracking info, due
+to a busted three-way merge. Takes an unusual set of circumstances for that
+bug to be triggered, which is why it was not noticed before now. Also,
+since git-annex is designed to not trust its location tracking info, and
+recover from it becoming inconsistent, someone could have experienced the
+bug and not really noticed it. Still it's a serious problem and I'm in debt
+to user a-or-b for developing a good test case that let me reproduce it and
+fix it. (Also added to the test suite.)
+[[This is how to make a perfect bug report|bugs/Annex_thinks_file_exists_afer_being_dropped]]
+
+Another bug made `git add; git commit` cause data loss in direct mode.
+I was able to make that not lose data, although it still does something
+that's unlikely to be desired, unless the goal is to move a file from an
+annexed direct mode file to having its entire contents stored in git.
+
+Also found a bug with sync's automatic resolution of git conflicts. It
+failed when two repositories both renamed a file to different names.
+I had neglected to explicitly `git rm` the old file name, which is
+necessary to resolve such a conflict.
diff --git a/doc/design/assistant/blog/day_174__last_weekend_before_AU.mdwn b/doc/design/assistant/blog/day_174__last_weekend_before_AU.mdwn
new file mode 100644
index 000000000..b86a39d66
--- /dev/null
+++ b/doc/design/assistant/blog/day_174__last_weekend_before_AU.mdwn
@@ -0,0 +1,25 @@
+On Friday, worked on several bugs in direct mode mapping code. Fixed it
+to not crash on invalid unicode in filenames. Dealt with some bugs when
+mappings were updated in subdirectories of the repository.
+
+Those bugs could result in inconsistent mapping files, so today I
+made `fsck` check mapping files for consistency.
+
+Leaving for Australia tomorrow, but I also hope to get another bugfix
+release out before my flight leaves. Then will be on vacation for several
+days, more or less. Then at Linux Conf Australia, where there will
+be a git-annex presentation on February 1st.
+
+----
+
+BTW, I've lined up my Android development hardware for next month. I will
+be using an [Asus Transformer](http://en.wikipedia.org/wiki/ASUS_Eee_Pad_Transformer),
+kindly lent to me by Mark H. This has the advantage
+of having a real keyboard, and running the (currently) second most widely used
+version of Android, 4.0.x. I have already experienced frustration getting photos
+off the thing and into my photo annex; the file manager is the worst I've
+seen since the 80's. I understand why so many want an Android port!
+
+Interestingly, its main user filesystem is a FUSE mount point on `/sdcard`
+backed by an ext4 filesystem on `/data` that a regular user is not allowed
+to access. Whatever craziness this entails does not support symlinks.
diff --git a/doc/design/assistant/blog/day_174__last_weekend_before_AU/comment_1_05a8fd47f54373331741cc869a53b0c3._comment b/doc/design/assistant/blog/day_174__last_weekend_before_AU/comment_1_05a8fd47f54373331741cc869a53b0c3._comment
new file mode 100644
index 000000000..f2a51310d
--- /dev/null
+++ b/doc/design/assistant/blog/day_174__last_weekend_before_AU/comment_1_05a8fd47f54373331741cc869a53b0c3._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 1"
+ date="2013-01-19T20:40:52Z"
+ content="""
+The Nexus devices all come without support for SD cards and without FAT anywhere to be seen. Indirect mode should work nicely on those.
+
+-- Richard
+"""]]
diff --git a/doc/design/assistant/blog/day_174__last_weekend_before_AU/comment_2_fc8e65eef954c4caa8321c2fe8b711b7._comment b/doc/design/assistant/blog/day_174__last_weekend_before_AU/comment_2_fc8e65eef954c4caa8321c2fe8b711b7._comment
new file mode 100644
index 000000000..b84ad4e3e
--- /dev/null
+++ b/doc/design/assistant/blog/day_174__last_weekend_before_AU/comment_2_fc8e65eef954c4caa8321c2fe8b711b7._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="EskildHustvedt"
+ ip="84.48.83.221"
+ subject="Presentation video"
+ date="2013-01-19T22:09:50Z"
+ content="""
+Any chance your presentation will be filmed and made available?
+"""]]
diff --git a/doc/design/assistant/blog/day_174__last_weekend_before_AU/comment_3_399534f540d85cac067fbb7be9d373b4._comment b/doc/design/assistant/blog/day_174__last_weekend_before_AU/comment_3_399534f540d85cac067fbb7be9d373b4._comment
new file mode 100644
index 000000000..ebce958a7
--- /dev/null
+++ b/doc/design/assistant/blog/day_174__last_weekend_before_AU/comment_3_399534f540d85cac067fbb7be9d373b4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="hamish"
+ ip="203.0.139.23"
+ subject="AU"
+ date="2013-01-24T12:50:06Z"
+ content="""
+I dont know how busy your LCA week is looking, but I'd love to shout you a beer one evening - perhaps there would also be other git-annex people hanging around the conference and interested too
+"""]]
diff --git a/doc/design/assistant/blog/day_175__pacific_features.mdwn b/doc/design/assistant/blog/day_175__pacific_features.mdwn
new file mode 100644
index 000000000..403088ec8
--- /dev/null
+++ b/doc/design/assistant/blog/day_175__pacific_features.mdwn
@@ -0,0 +1,15 @@
+15 hours in a plane with in-seat power. Ok, time for some new features!
+
+Added two new repository groups.
+
+"manual" can be used to avoid the assistant downloading any file contents
+on its own. It'll still upload and otherwise sync data. To download files,
+you can use `git annex get` while the assistant is running. You can also
+drop files using the command line.
+
+"source" is for repositories that are the source of new files, but don't
+need to retain a copy once the file has been moved to another repository.
+A camera would be a good example.
+
+Ok, those were easy features to code; I suck at being productive on planes.
+Release coming up with those, once I find enough bandwidth here in AU.
diff --git a/doc/design/assistant/blog/day_175__pacific_features/comment_1_c3ee4386f872b7c76aaecfa638b368cb._comment b/doc/design/assistant/blog/day_175__pacific_features/comment_1_c3ee4386f872b7c76aaecfa638b368cb._comment
new file mode 100644
index 000000000..0f2708005
--- /dev/null
+++ b/doc/design/assistant/blog/day_175__pacific_features/comment_1_c3ee4386f872b7c76aaecfa638b368cb._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlyFDd2xkx0uj738OArDj10CqEkVfWu_mQ"
+ nickname="Johann"
+ subject="comment 1"
+ date="2013-01-24T15:36:34Z"
+ content="""
+Regarding 'manual': Maybe it is necessary to adjust the other standard settings for preferred content then.
+For the 'transfer' for example it would still make sense to treat a manual repository as a client.
+"""]]
diff --git a/doc/design/assistant/blog/day_176__thread_management.mdwn b/doc/design/assistant/blog/day_176__thread_management.mdwn
new file mode 100644
index 000000000..38f043fcf
--- /dev/null
+++ b/doc/design/assistant/blog/day_176__thread_management.mdwn
@@ -0,0 +1,13 @@
+Got back to hacking today, and did something I've wanted to do for some
+time. Made all the assistant's threads be managed by a thread manager. This
+allows restarting threads if they crash, by clicking a button in the
+webapp. It also will allow for other features later, like stopping and
+starting the watcher thread, to pause the assistant adding local files.
+
+[[!img /assistant/crashrecovery.png]]
+
+I added the haskell async library as a dependency, which made this pretty
+easy to implement. The only hitch is that async's documentation is not
+clear about how it handles asyncronous exceptions. It took me quite a while
+to work out why the errors I'd inserted into threads to test were crashing
+the whole program rather than being caught!
diff --git a/doc/design/assistant/blog/day_178__bus_hacking.mdwn b/doc/design/assistant/blog/day_178__bus_hacking.mdwn
new file mode 100644
index 000000000..738afd2c9
--- /dev/null
+++ b/doc/design/assistant/blog/day_178__bus_hacking.mdwn
@@ -0,0 +1,10 @@
+Hacking on a bus to Canberra for [LCA2013](https://lca2013.linux.org.au/),
+I made the webapp's UI for pausing syncing to a repository also work for
+the local repository. This pauses the watcher thread. (There's also an
+annex.autocommit config setting for this.)
+
+Ironically, this didn't turn out to the use the thread manager I built
+yesterday. I am not sure that a ThreadKilled exception would never be
+masked in the watcher thread. (There is some overly broad exception
+handling in git-annex that dates to back before I quite understood haskell
+exceptions.)
diff --git a/doc/design/assistant/blog/day_179__brief_updates.mdwn b/doc/design/assistant/blog/day_179__brief_updates.mdwn
new file mode 100644
index 000000000..e755ca8ae
--- /dev/null
+++ b/doc/design/assistant/blog/day_179__brief_updates.mdwn
@@ -0,0 +1,19 @@
+Not doing significant coding here at LCA2013, but stuff is still happening:
+
+* I'll be giving a talk and demo of git-annex and the assistant tomorrow.
+ Right after a keynote by Tim Berners-Lee! There's no streaming, but
+ a recording will be available later.
+* I've met numerous git-annex users and git-annex curious folk from down
+ under.
+* I had a suggestion that direct mode rename the `.git` directory to
+ something else, to prevent foot-shooting git commands being used.
+ A wrapper around git could be used to run git commands, and limit
+ to safe ones. Under consideration.
+* I finally updated the OSX 10.8.2 build to last week's release.
+ Been having some problems with the autobuilder, but it finally spat out
+ a build. Hopefully this build is good, and it should fix the javascript
+ issues with Safari and the webapp.
+* Ulrik Sverdrup has written <https://github.com/blake2-ppc/git-remote-gcrypt>,
+ which allows using gpg encrypted ssh remotes with git. The same idea
+ could be expanded to other types of remotes, like S3. I'm excited
+ about adding encrypted git remote support to the assistant!
diff --git a/doc/design/assistant/blog/day_179__brief_updates/comment_1_920a84457d40358507a3eb817a4568d9._comment b/doc/design/assistant/blog/day_179__brief_updates/comment_1_920a84457d40358507a3eb817a4568d9._comment
new file mode 100644
index 000000000..c58529cf1
--- /dev/null
+++ b/doc/design/assistant/blog/day_179__brief_updates/comment_1_920a84457d40358507a3eb817a4568d9._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmnG4EuvZWse5hvgrl0XAK-U61e-0iGaao"
+ nickname="David"
+ subject="git commit in direct mode"
+ date="2013-01-31T08:30:19Z"
+ content="""
+How about creating a .git/hooks/pre-commit script that warns the user or checks the commit before anything goes wrong?
+"""]]
diff --git a/doc/design/assistant/blog/day_17__push_queue_prune.mdwn b/doc/design/assistant/blog/day_17__push_queue_prune.mdwn
new file mode 100644
index 000000000..54ee75fb8
--- /dev/null
+++ b/doc/design/assistant/blog/day_17__push_queue_prune.mdwn
@@ -0,0 +1,19 @@
+Not much available time today, only a few hours.
+
+Main thing I did was fixed up the failed push tracking to use a better data
+structure. No need for a queue of failed pushes, all it needs is a map of
+remotes that have an outstanding failed push, and a timestamp. Now it
+won't grow in memory use forever anymore. :)
+
+Finding the right thread mutex type for this turned out to be a bit of a
+challenge. I ended up with a STM TMVar, which is left empty when there are
+no pushes to retry, so the thread using it blocks until there are some. And,
+it can be updated transactionally, without races.
+
+I also fixed a bug outside the git-annex assistant code. It was possible to
+crash git-annex if a local git repository was configured as a remote, and
+the repository was not available on startup. git-annex now ignores such
+remotes. This does impact the assistant, since it is a long running process
+and git repositories will come and go. Now it ignores any that
+were not available when it started up. This will need to be dealt with when
+making it support removable drives.
diff --git a/doc/design/assistant/blog/day_180__back.mdwn b/doc/design/assistant/blog/day_180__back.mdwn
new file mode 100644
index 000000000..adb336244
--- /dev/null
+++ b/doc/design/assistant/blog/day_180__back.mdwn
@@ -0,0 +1,7 @@
+Back from Australia. Either later today or tomorrow I'll dig into the
+messages I was not able to get to while traveling, and then the plan is to
+get into the Android port.
+
+Video of my LCA2013 [git-annex talk](http://mirror.linux.org.au/linux.conf.au/2013/mp4/gitannex.mp4)
+is now available. I have not watched it yet, hope it turned out ok despite
+some technical difficulties!
diff --git a/doc/design/assistant/blog/day_181__triage.mdwn b/doc/design/assistant/blog/day_181__triage.mdwn
new file mode 100644
index 000000000..9c5e92280
--- /dev/null
+++ b/doc/design/assistant/blog/day_181__triage.mdwn
@@ -0,0 +1,23 @@
+Got fairly far along in my triage of my backlog, looking through everything
+that happened after January 23rd. Still 39 or so items to look at.
+
+There have been several reports of problems with ssh password prompts.
+I'm beginning to think the assistant may need to prompt for the password
+when setting up a ssh remote. This should be handled by `ssh-askpass` or
+similar, but some Linux users probably don't have it installed, and there
+seems to be no widely used OSX equivalent.
+
+---
+
+Fixed several bugs today, all involving (gasp) direct mode.
+
+The tricky one involved renaming or deleting files in direct mode.
+Currently nothing removes the old filename from the direct mode
+mapping, and this could result in the renamed or deleted file
+unexpectedly being put back into the tree when content is downloaded.
+
+To deal with this, it now assumes that direct mode mappings may be out of
+date compared to the tree, and does additional checks to catch
+inconsistencies. While that works well enough for the assistant,
+I'd also like to make the `pre-commit` hook update the mappings for files
+that are changed. That's needed to handle things like `git mv`.
diff --git a/doc/design/assistant/blog/day_182__it_begins.mdwn b/doc/design/assistant/blog/day_182__it_begins.mdwn
new file mode 100644
index 000000000..48daea78f
--- /dev/null
+++ b/doc/design/assistant/blog/day_182__it_begins.mdwn
@@ -0,0 +1,50 @@
+I need an Android development environment. I briefly looked into rooting
+the Asus Transformer so I could put a Debian chroot on it and build
+git-annex in there, but this quickly devolved to the typical maze of
+forum posts all containing poor instructions and dead links. Not worth it.
+
+Instead, I'm doing builds on my Sheevaplug, and once I have a static armel
+binary, will see what I need to do to get it running on Android.
+
+Fixed building with the webapp disabled, was broken by recent improvements.
+I'll be building without the webapp on arm initially, because ghci/template
+haskell on arm is still getting sorted out. (I tried ghc 7.6.2 and ghci is
+available, but doesn't quite work.)
+
+From there, I got a binary built pretty quickly (well, it's arm, so not *too*
+quickly). Then tried to make it static by appending
+`-optl-static -optl-pthread` to the ghc command line.
+This failed with a bunch of errors:
+
+<pre>
+/usr/lib/gcc/arm-linux-gnueabi/4.6/../../../arm-linux-gnueabi/libxml2.a(nanohttp.o): In function `xmlNanoHTTPMethodRedir': (.text+0x2128): undefined reference to `inflateInit2_'
+/usr/lib/gcc/arm-linux-gnueabi/4.6/../../../arm-linux-gnueabi/libxml2.a(xzlib.o): In function `xz_decomp': (.text+0x36c): undefined reference to `lzma_code'
+...
+</pre>
+
+Disabling DBUS and (temporarily) XMPP got around that.
+
+Result!
+
+<pre>
+joey@leech:~/git-annex>ldd tmp/git-annex
+ not a dynamic executable
+joey@leech:~/git-annex>ls -lha tmp/git-annex
+-rwxr-xr-x 1 joey joey 18M Feb 6 16:23 tmp/git-annex*
+</pre>
+
+Next: Copy binary to Android device, and watch it fail in some interesting way.
+Repeat.
+
+---
+
+Also more bug triage this morning...
+
+Got the pre-commit hook to update direct mode mappings.
+Uses `git diff-index HEAD` to find out what's changed. The only
+tricky part was detecting when `HEAD` doesn't exist yet. Git's
+plumbing is deficient in this area. Anyway, the mappings get updated
+much better now.
+
+Fixed a wacky bug where `git annex uninit` behaved badly on a filesystem
+that does not support hardlinks.
diff --git a/doc/design/assistant/blog/day_183__plan_b.mdwn b/doc/design/assistant/blog/day_183__plan_b.mdwn
new file mode 100644
index 000000000..b310d0412
--- /dev/null
+++ b/doc/design/assistant/blog/day_183__plan_b.mdwn
@@ -0,0 +1,19 @@
+Have not tried to run my static binary on Android yet, but I'm already
+working on a plan B in case that doesn't work. Yesterday I stumbled upon
+<https://github.com/neurocyte/ghc-android>, a ghc cross-compiler for
+Android that uses the Android native development kit.
+It first appeared on February 4th. Good timing!
+
+I've gotten it to build and it emits arm executables, that seem to use the
+Android linker. So that's very promising indeed.
+
+I've also gotten cabal working with it, and have it chewing through
+installing git-annex's build dependencies.
+
+----
+
+Also made a release today, this is another release that's mostly bugfixes,
+and a few minor features. Including one bug fixed at 6 am this morning, urk.
+
+I think I will probably split my days between working on Android porting
+and other git-annex development.
diff --git a/doc/design/assistant/blog/day_184__just_wanna_run_something.mdwn b/doc/design/assistant/blog/day_184__just_wanna_run_something.mdwn
new file mode 100644
index 000000000..ac34293c3
--- /dev/null
+++ b/doc/design/assistant/blog/day_184__just_wanna_run_something.mdwn
@@ -0,0 +1,46 @@
+Have been working on getting all the haskell libraries git-annex uses
+built with the android cross compiler. Difficulties so far are
+libraries that need tweaks to work with the new version of ghc, and some
+that use cabal in ways that break cross compilation. Haskell's network
+library was the last and most challenging of those.
+
+At this point, I'm able to start trying to build git-annex for android.
+Here's the first try!
+
+<pre>
+joey@gnu:~/src/git-annex>cabal install -w $HOME/.ghc-android-14-arm-linux-androideabi-4.7/bin/arm-unknown-linux-androideabi-ghc --with-ghc-pkg=$HOME/.ghc-android-14-arm-linux-androideabi-4.7/bin/arm-unknown-linux-androideabi-ghc-pkg --with-ld=$HOME/.ghc-android-14-arm-linux-androideabi-4.7/bin/arm-linux-androideabi-ld --flags="-Webapp -WebDAV -XMPP -S3 -Dbus"
+Resolving dependencies...
+Configuring git-annex-3.20130207...
+Building git-annex-3.20130207...
+Preprocessing executable 'git-annex' for git-annex-3.20130207...
+on the commandline: Warning:
+ -package-conf is deprecated: Use -package-db instead
+
+Utility/libdiskfree.c:28:26:
+ fatal error: sys/statvfs.h: No such file or directory
+compilation terminated.
+</pre>
+
+Should not be far from a first android build now..
+
+----
+
+While I already have Android "hello world" executables to try, I have not yet
+been able to run them. Can't seem to find a directory I can write to on the
+Asus Transformer, with a filesystem that supports the +x bit. Do you really
+have to root Android just to run simple binaries? I'm crying inside.
+
+It seems that the blessed Android NDK way would involve making a Java app,
+that pulls in a shared library that contains the native code. For haskell,
+the library will need to contain a C shim that, probably, calls an entry
+point to the Haskell runtime system. Once running, it can use the FFI to
+communicate back to the Java side, probably. The good news is that CJ van
+den Berg, who already saved my bacon once by developing ghc-android, tells
+me he's hard at work on that very thing.
+
+----
+
+In the meantime, downloaded the Android SDK. Have gotten it to build a
+`.apk` package from just javascript code, and managed to do it without
+using eclipse (thank god). Will need this later, but for now want to wash
+my brain out with soap after using it.
diff --git a/doc/design/assistant/blog/day_184__just_wanna_run_something/comment_1_689adac7e26cb0b0a4e7ecc787cfd716._comment b/doc/design/assistant/blog/day_184__just_wanna_run_something/comment_1_689adac7e26cb0b0a4e7ecc787cfd716._comment
new file mode 100644
index 000000000..b6ad3ac7e
--- /dev/null
+++ b/doc/design/assistant/blog/day_184__just_wanna_run_something/comment_1_689adac7e26cb0b0a4e7ecc787cfd716._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="hhm"
+ ip="108.17.80.177"
+ subject="Write and exec on unrooted Android."
+ date="2013-02-10T05:43:41Z"
+ content="""
+See <http://kevinboone.net/android_nonroot.html> for info on where in the android filesystem you have write, exec ability.
+
+Basically you have these abilities in `/data/local` from `adb shell` (and in debuggable app's folders using run-as with `adb shell`), and in `/data/data/<app_id>/` for each app (for example the terminal emulator's data dir when using the terminal emulator).
+
+It might be possible to just have temporary root using an old exploit and writing up a bit of code to just setuid on the process and exec sh (source for nachoroot exploit <https://github.com/CunningLogic/NachoRoot>).
+
+It *is* possible to install a distro without root using a chroot faker.
+
+I am working here <https://sites.google.com/site/taldewandroid/> on a way to install the OpenWrt distro on Android. This is working on my phone already for quite a while! So far only sketchy notes are up, but more to come, G-d willing.
+"""]]
diff --git a/doc/design/assistant/blog/day_185__android_liftoff.mdwn b/doc/design/assistant/blog/day_185__android_liftoff.mdwn
new file mode 100644
index 000000000..88fc5635c
--- /dev/null
+++ b/doc/design/assistant/blog/day_185__android_liftoff.mdwn
@@ -0,0 +1,20 @@
+Thanks to hhm, who pointed me at [KBOX](http://kevinboone.net/kbox.html),
+I have verified that I can build haskell programs that work on Android.
+
+After hacking on it all day, I've succeeded in making an initial build of
+git-annex for Android. It links! It runs!
+
+Which is not to say it's usable yet; for one thing I need to get a port
+of git before it can do anything useful. (Some of the other things git-annex
+needs, like ssh and sha256sum, are helpfully provided by KBOX.)
+
+Next step will be to find or built a git port for Android. I know there's
+one in the "Terminal IDE" app. Once I can use git-annex at the command line
+on Android, I'll be able to test it out some (I can also port the test
+suite program and run it on Android), and get a feeling for what is needed
+to get the port to a usable command-line state.
+
+And then on to the webapp, and an Android app, I suppose. So far, the port
+doesn't include the webapp, but does include the assistant. The webapp
+needs ghci/template haskell for arm. A few people have been reporting they
+have that working, but I don't yet.
diff --git a/doc/design/assistant/blog/day_185__android_liftoff/comment_1_b7d28010a72619a7e9a5ad4f2a0d6c07._comment b/doc/design/assistant/blog/day_185__android_liftoff/comment_1_b7d28010a72619a7e9a5ad4f2a0d6c07._comment
new file mode 100644
index 000000000..c0d336b11
--- /dev/null
+++ b/doc/design/assistant/blog/day_185__android_liftoff/comment_1_b7d28010a72619a7e9a5ad4f2a0d6c07._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://mlinden.myopenid.com/"
+ ip="2001:470:d1c3:0:5c01:5562:e242:37b9"
+ subject="&quot;Build native GNU/Linux applications: the easy way&quot;"
+ date="2013-02-10T22:02:19Z"
+ content="""
+Maybe this helps:
+[[http://forum.xda-developers.com/showthread.php?t=1444792]]
+"""]]
diff --git a/doc/design/assistant/blog/day_185__android_liftoff/comment_2_ddeb24e86fafb7dae93142cc02767aad._comment b/doc/design/assistant/blog/day_185__android_liftoff/comment_2_ddeb24e86fafb7dae93142cc02767aad._comment
new file mode 100644
index 000000000..ed0c3dc31
--- /dev/null
+++ b/doc/design/assistant/blog/day_185__android_liftoff/comment_2_ddeb24e86fafb7dae93142cc02767aad._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnbBRfl5F8gKRr1ko8Ai6FbEZStXXNF1S4"
+ nickname="Áron"
+ subject="another android git app"
+ date="2013-02-11T08:20:42Z"
+ content="""
+https://play.google.com/store/apps/details?id=com.madgag.agit&hl=en
+
+I used it and its decent and certainly runs git as a backend (although I havent seen its internals)
+"""]]
diff --git a/doc/design/assistant/blog/day_186__Android_success.mdwn b/doc/design/assistant/blog/day_186__Android_success.mdwn
new file mode 100644
index 000000000..8ede7f29a
--- /dev/null
+++ b/doc/design/assistant/blog/day_186__Android_success.mdwn
@@ -0,0 +1,33 @@
+I'm now successfully using git-annex at the command line on Android.
+`git annex watch` works too.
+
+For now, I'm using a git repository under `/data`, which is on a real,
+non-cripped filesystem, so symlinks work there.
+
+There's still the issue of running without any symlinks on `/mnt/sdcard`.
+While direct mode gets most of the way, it still uses symlinks in a few
+places, so some more work will be needed there. Also, git-annex uses hard
+links to lock down files, which won't work on cripped filesystems.
+
+Besides that, there's lots of minor porting, but no big show-stoppers
+currently.. Some of today's porting work:
+
+* Cross-compiled git for Android. While the Terminal IDE app has some git
+ stuff, it's not complete and misses a lot of plumbing commands git-annex
+ uses. My git build needs some tweaks to be relocatable without setting
+ `GIT_EXEC_PATH`, but it works.
+
+* Switched git-annex to use the Haskell glob library, rather than PCRE. This
+ avoids needing libpcre, which simplifies installation on several platforms
+ (including Android).
+
+* Made git-annex's `configure` hardcode some settings when cross-compiling
+ for Android, rather than probing the build system.
+
+* Android's built-in `lsof` doesn't support the -F option to use a
+ machine-readable output format. So wrote a separate lsof output parser for
+ the standard lsof output format. Unfortunatly, Android's lsof does not
+ provide any information about where a file is open for read or write, so
+ for safety, git-annex has to assume any file that's open might be written
+ to, and avoid annexing it. It might be better to provide my own lsof
+ eventually.
diff --git a/doc/design/assistant/blog/day_186__Android_success/comment_1_1629da240ca7db5f8a32059f561fd435._comment b/doc/design/assistant/blog/day_186__Android_success/comment_1_1629da240ca7db5f8a32059f561fd435._comment
new file mode 100644
index 000000000..07ef87bb4
--- /dev/null
+++ b/doc/design/assistant/blog/day_186__Android_success/comment_1_1629da240ca7db5f8a32059f561fd435._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 1"
+ date="2013-02-12T10:24:50Z"
+ content="""
+heh, +1 for removing the need for pcre
+"""]]
diff --git a/doc/design/assistant/blog/day_187__porting_utilities.mdwn b/doc/design/assistant/blog/day_187__porting_utilities.mdwn
new file mode 100644
index 000000000..496c74a1f
--- /dev/null
+++ b/doc/design/assistant/blog/day_187__porting_utilities.mdwn
@@ -0,0 +1,22 @@
+Ported all the utilities git-annex needs to run on Android:
+git, rsync, gnupg, dropbear (ssh client), busybox. Built a
+Makefile that can download, patch, and cross build these from source.
+
+While all the utilities work, dropbear doesn't allow git-annex to use ssh
+connection caching, which is rather annoying especially since these systems
+tend to be rather slow and take a while to start up ssh connections.
+I'd sort of like to try to get openssh's client working on Android instead.
+Don't know how realistic that is.
+
+Dealt with several parts of git-annex that assumed `/bin/sh` exists,
+so it instead uses `/system/bin/sh` on Android. Also adapted `runshell`
+for Android.
+
+Now I have a 8 mb compressed tarball for Android.
+Uncompressed it's 25 mb. This includes a lot of git and busybox
+commands that won't be used, so it could be trimmed down further.
+16 mb of it is git-annex itself.
+
+[[Instructions for using the Android tarball|install/Android]]
+This is for users who are rather brave, not afraid of command line and
+keyboard usage. Good first step.
diff --git a/doc/design/assistant/blog/day_187__porting_utilities/comment_1_0e6a3f4fe8e09f247fa04156bc60f8c7._comment b/doc/design/assistant/blog/day_187__porting_utilities/comment_1_0e6a3f4fe8e09f247fa04156bc60f8c7._comment
new file mode 100644
index 000000000..e25ff1c15
--- /dev/null
+++ b/doc/design/assistant/blog/day_187__porting_utilities/comment_1_0e6a3f4fe8e09f247fa04156bc60f8c7._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://a-or-b.myopenid.com/"
+ ip="203.45.2.230"
+ subject="comment 1"
+ date="2013-02-13T22:16:17Z"
+ content="""
+In addition to dropbear, there is ConnectBot <https://code.google.com/p/connectbot/> which might make the ssh side of the equation simpler. I prefer it because it is half the size of dropbear.
+"""]]
diff --git a/doc/design/assistant/blog/day_188__crippled_filesystem_support.mdwn b/doc/design/assistant/blog/day_188__crippled_filesystem_support.mdwn
new file mode 100644
index 000000000..48f6069d4
--- /dev/null
+++ b/doc/design/assistant/blog/day_188__crippled_filesystem_support.mdwn
@@ -0,0 +1,37 @@
+There are at least three problems with using git-annex
+on `/sdcard` on Android, or on a FAT filesystem, or on (to a first
+approximation) Windows:
+
+1. symlinks
+2. hard links
+3. unix permissions
+
+So, I've added an `annex.crippledfilesystem` setting. `git annex init` now
+probes to see if all three are supported, and if not, enables that, as well
+as direct mode.
+
+In crippled filesystem mode, all the permissions settings are skipped.
+Most of them are only used to lock down content in the annex in indirect
+mode anyway, so no great loss.
+
+There are several uses of hard links, most of which can be dealt with by
+making copies. The one use of permissions and hard links I absolutely
+needed to deal with was that they're used to lock down a file as it's being
+ingested into the annex. That can't be done on crippled filesystems, so I
+made it instead check the metadata of the file before and after to detect
+if it changed, the same way direct mode detects when files are modified.
+This is likely better than the old method anyway.
+
+The other reason files are hardlinked while they're being ingested is that
+this allows running lsof on a single directory of files that are in the
+process of being added, to detect if anything has them open for write.
+I still need to adjust the lsof check to work in crippled filesystem mode.
+It seems this won't make it much slower to run lsof on the whole repository.
+
+At this point, I can use git-annex with a repository on `/sdcard` or a FAT
+filesystem, and at least `git annex add` works.
+
+Still several things on the TODO list before crippled filesystem mode is
+complete. The only one I'm scared about is making `git merge` do something
+sane when it wants to merge two trees full of symlinks, and the filesystem
+doesn't let it create a symlink..
diff --git a/doc/design/assistant/blog/day_188__crippled_filesystem_support/comment_1_32a296fce23ae4b1e18bd5a9964bf619._comment b/doc/design/assistant/blog/day_188__crippled_filesystem_support/comment_1_32a296fce23ae4b1e18bd5a9964bf619._comment
new file mode 100644
index 000000000..2796964e0
--- /dev/null
+++ b/doc/design/assistant/blog/day_188__crippled_filesystem_support/comment_1_32a296fce23ae4b1e18bd5a9964bf619._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://nullroute.eu.org/~grawity/"
+ nickname="Mantas"
+ subject="comment 1"
+ date="2013-02-15T00:38:00Z"
+ content="""
+Windows supports hardlinks on NTFS filesystems. Not sure about the privileges needed; I think all users can create them.
+
+Recent versions also support symlinks, but that's limited to Administrators by default, so Cygwin-Git (like the rest of Cygwin) uses special files with the \"system\" flag.
+
+As far as I know, Git does not try to dereference symlinks when merging – it only tracks the paths they point to. Where symlinks are not supported (e.g. vfat filesystems in general, or msysGit on Windows) it simply creates regular files containing the target path (i.e. the raw contents of the respective blobs).
+
+Regarding the use of Unix permissions: The \"open file\" syscall on Windows has a \"share mode\" flag, which can be used to disallow other programs from opening the file for writing (and/or even reading) as long as git-annex keeps it open. (I guess this is similar to mandatory locks in Linux.)
+"""]]
diff --git a/doc/design/assistant/blog/day_189__more_crippling.mdwn b/doc/design/assistant/blog/day_189__more_crippling.mdwn
new file mode 100644
index 000000000..f3ddad266
--- /dev/null
+++ b/doc/design/assistant/blog/day_189__more_crippling.mdwn
@@ -0,0 +1,44 @@
+Finished crippled filesystem support, except for symlink handling.
+This was straightforward, just got lsof working in that mode, made
+`migrate` copy key contents, and adapted the rsync special remote to
+support it. Encrypted rsync special remotes have no more overhead on
+crippled filesystems than normally. Un-encrypted rsync special remotes
+have some added overhead, but less than encrypted remotes. Acceptable
+for now.
+
+I've now successfully run the assistant on a FAT filesystem.
+
+----
+
+Git handles symlinks on crippled filesystems by setting
+`core.symlinks=false` and checking them out as files containing the link
+text. So to finish up crippled filesystem support, git-annex needs to
+do the same whenever it creates a symlink, and needs to read file contents
+when it normally reads a symlink target.
+
+There are rather a lot of calls to `createSymbolicLink`,
+`readSymbolicLink`, `getSymbolicLinkStatus`, `isSymbolicLink`, and `isSymLink`
+in the tree; only ones that are used in direct mode
+need to be converted. This will take a while.
+
+Checking whether something is a symlink, or where it points is especially
+tricky. How to tell if a small file in a git working tree is intended to be
+a symlink or not? Well, it can look at the content and see if it makes
+sense as a link text pointing at a git-annex key. As long as the
+possibility of false positives is ok. It might be possible, in some cases,
+to query git to verify if the object stored for that file is really a
+symlink, but that won't work if the file has been renamed, for example.
+
+Converted some of the most commonly used symlink code to handle this.
+Much more to do, but it basically works; I can `git annex get` and `git
+annex drop` on FAT, and it works.
+
+-----
+
+Unfortunately, got side-tracked when I discovered that the last release
+introduced a bug in direct mode. Due to the bug, "git annex get file; git annex
+drop file; git annex get file" would end up with the file being an indirect
+mode symlink to the content, rather than a direct mode file. No data loss,
+but not right. So, spent several hours fixing that reversion, which was
+caused by me stupidly fixing another bug at 5 am in the morning last week..
+and I'll probably be pushing out another release tomorrow with the fix.
diff --git a/doc/design/assistant/blog/day_18__merging.mdwn b/doc/design/assistant/blog/day_18__merging.mdwn
new file mode 100644
index 000000000..f963cf85d
--- /dev/null
+++ b/doc/design/assistant/blog/day_18__merging.mdwn
@@ -0,0 +1,82 @@
+Worked on automatic merge conflict resolution today. I had expected to be
+able to use git's merge driver interface for this, but that interface is
+not sufficient. There are two problems with it:
+
+1. The merge program is run when git is in the middle of an operation
+ that locks the index. So it cannot delete or stage files. I need to
+ do both as part of my conflict resolution strategy.
+2. The merge program is not run at all when the merge conflict is caused
+ by one side deleting a file, and the other side modifying it. This is
+ an important case to handle.
+
+So, instead, git-annex will use a regular `git merge`, and if it fails, it
+will fix up the conflicts.
+
+That presented its own difficulty, of finding which files in the tree
+conflict. `git ls-files --unmerged` is the way to do that, but its output
+is a quite raw form:
+
+ 120000 3594e94c04db171e2767224db355f514b13715c5 1 foo
+ 120000 35ec3b9d7586b46c0fd3450ba21e30ef666cfcd6 3 foo
+ 100644 1eabec834c255a127e2e835dadc2d7733742ed9a 2 bar
+ 100644 36902d4d842a114e8b8912c02d239b2d7059c02b 3 bar
+
+I had to stare at the rather impenetrable documentation for hours and
+write a lot of parsing and processing code to get from that to these mostly
+self explanatory data types:
+
+ data Conflicting v = Conflicting
+ { valUs :: Maybe v
+ , valThem :: Maybe v
+ } deriving (Show)
+
+ data Unmerged = Unmerged
+ { unmergedFile :: FilePath
+ , unmergedBlobType :: Conflicting BlobType
+ , unmergedSha :: Conflicting Sha
+ } deriving (Show)
+
+Not the first time I've whined here about time spent parsing unix command
+output, is it? :)
+
+From there, it was relatively easy to write the actual conflict cleanup
+code, and make `git annex sync` use it. Here's how it looks:
+
+ $ ls -1
+ foo.png
+ bar.png
+ $ git annex sync
+ commit
+ # On branch master
+ nothing to commit (working directory clean)
+ ok
+ merge synced/master
+ CONFLICT (modify/delete): bar.png deleted in refs/heads/synced/master and modified in HEAD. Version HEAD of bar.png left in tree.
+ Automatic merge failed; fix conflicts and then commit the result.
+ bar.png: needs merge
+ (Recording state in git...)
+ [master 0354a67] git-annex automatic merge conflict fix
+ ok
+ $ ls -1
+ foo.png
+ bar.variant-a1fe.png
+ bar.variant-93a1.png
+
+There are very few options for ways for the conflict resolution code to
+name conflicting variants of files. The conflict resolver can only use data
+present in git to generate the names, because the same conflict needs to
+be resolved the same everywhere.
+
+So I had to choose between using the full key name in the filenames produced
+when resolving a merge, and using a shorter checksum of the key, that would be
+more user-friendly, but could theoretically collide with another key.
+I chose the checksum, and weakened it horribly by only using 32 bits of it!
+
+Surprisingly, I think this is a safe choice. The worst that can
+happens if such a collision happens is another conflict, and the conflict
+resolution code will work on conflicts produced by the conflict resolution
+code! In such a case, it does fall back to putting the whole key in
+the filename:
+"bar.variant-SHA256-s2550--2c09deac21fa93607be0844fefa870b2878a304a7714684c4cc8f800fda5e16b.png"
+
+Still need to hook this code into `git annex assistant`.
diff --git a/doc/design/assistant/blog/day_18__merging/comment_1_7a553ad559519f3b3e3cd20115b4c44e._comment b/doc/design/assistant/blog/day_18__merging/comment_1_7a553ad559519f3b3e3cd20115b4c44e._comment
new file mode 100644
index 000000000..94261f81e
--- /dev/null
+++ b/doc/design/assistant/blog/day_18__merging/comment_1_7a553ad559519f3b3e3cd20115b4c44e._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://droggl.myopenid.com/"
+ ip="2001:638:602:1181:a6ba:dbff:fedd:8041"
+ subject="comment 1"
+ date="2013-09-11T11:55:27Z"
+ content="""
+Nice!
+However I didnt find any documentation yet on how to actually resolve the situation as a user (sorry if I'm being blind).
+To be more specific: Say a conflict occurs on foo.txt and i now have two files foo.variant-dead.txt and foo.variant-beef.txt.
+Now what? Say I used my favorite merge diffmerge tool to create a merged version foo-merged.txt, should I rename that to foo.txt?
+Should I delete the variant files? Or drop them? Or would that lead to another merge for systems that still have the old foo.txt?
+(You see I'm kind of confused of what happens here ;))
+
+TIA for any helpers
+"""]]
diff --git a/doc/design/assistant/blog/day_190-191__weekend.mdwn b/doc/design/assistant/blog/day_190-191__weekend.mdwn
new file mode 100644
index 000000000..21e46529a
--- /dev/null
+++ b/doc/design/assistant/blog/day_190-191__weekend.mdwn
@@ -0,0 +1,28 @@
+Pushed out a release yesterday mostly for a bug fix. I have to build
+git-annex 5 times now when releasing. Am wondering if I could get rid of
+the Linux 64 bit standalone build. The 32 bit build should run ok on 64 bit
+Linux systems, since it has all its own 32 bit libraries. What I really
+need to do is set up autobuilders for Linux and Android, like we have for OSX.
+
+Today, dealt with all code that creates or looks at symlinks. Audited every
+bit of it, and converted all relevant parts to use a new abstraction layer
+that handles the pseudolink files git uses when core.symlinks=false.
+This is untested, but I'm quite happy with how it turned out.
+
+----
+
+Where next for Android? I want to spend a while testing command-line
+git-annex. After I'm sure it's really solid, I should try to get the webapp
+working, if possible.
+
+I've heard rumors that Ubuntu's version of ghc somehow supports template
+haskell on arm, so I need to investigate that. If I am unable to get
+template haskell on arm, I would need to either wait for further
+developments, or try to expand yesod's template haskell to regular haskell
+and then build it on arm, or I could of course switch away from hamlet
+(using blaze-html instead is appealing in some ways) and
+use yesod in non-template-haskell mode entirely. One of these will work,
+for sure, only question is how much pain.
+
+After getting the webapp working, there's still the issue of bundling it
+all up in an Android app that regular users can install.
diff --git a/doc/design/assistant/blog/day_190-191__weekend/comment_1_dbd692d12c14d08acd7d73a655b34e8b._comment b/doc/design/assistant/blog/day_190-191__weekend/comment_1_dbd692d12c14d08acd7d73a655b34e8b._comment
new file mode 100644
index 000000000..965a762e6
--- /dev/null
+++ b/doc/design/assistant/blog/day_190-191__weekend/comment_1_dbd692d12c14d08acd7d73a655b34e8b._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://jasonwoof.com/"
+ nickname="JasonWoof"
+ subject="phonegap might help"
+ date="2013-02-17T22:43:06Z"
+ content="""
+In your research to see how to bundle up a graphical android app, I suggest you read up on phonegap: http://phonegap.com/
+
+Essentially they bundle webkit so you can turn a web app into an android app. Not sure if they help you ship native/binary stuff along side the html/javascript/css, but phonegap should at least be useful as a reference for how to do some of the bundling-related stuff.
+"""]]
diff --git a/doc/design/assistant/blog/day_190-191__weekend/comment_2_c813830e53471a9732e010a748d574fc._comment b/doc/design/assistant/blog/day_190-191__weekend/comment_2_c813830e53471a9732e010a748d574fc._comment
new file mode 100644
index 000000000..bdda398b0
--- /dev/null
+++ b/doc/design/assistant/blog/day_190-191__weekend/comment_2_c813830e53471a9732e010a748d574fc._comment
@@ -0,0 +1,28 @@
+[[!comment format=c
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="Two direct mode repository on the same computer"
+ date="2013-02-19T09:24:21Z"
+ content="""
+Hi,
+
+I just tried the newest git annex webapp (20130216),
+I am still not able to configure two direct mode repositories (one normal, one backup) on the same computer.
+
+It does recognize my other partition (/mnt/the) as a removable drive, but when I add it
+it gives me internal server error:
+\"\"\"
+Internal Server Error
+
+there is no available git remote named \"the\"
+git-annex version 3.20130216
+\"\"\"
+
+Could you please (pretty please) add a possibility to specify the removable drive as a simple folder?
+So I could choose arbitrary folder(/mnt/the/annex-backup) on my computer and
+it would treat it as a direct mode repository.
+
+Best,
+ Laszlo
+
+"""]]
diff --git a/doc/design/assistant/blog/day_192_193__more_porting.mdwn b/doc/design/assistant/blog/day_192_193__more_porting.mdwn
new file mode 100644
index 000000000..59f7cf836
--- /dev/null
+++ b/doc/design/assistant/blog/day_192_193__more_porting.mdwn
@@ -0,0 +1,44 @@
+Felt spread thin yesterday, as I was working on multiple things
+concurrently & bouncing around as compiles finished. Been working to get
+openssh to build for Android, which is quite a pain, starting with getting
+openssl to build and then dealing with the Cyanogenmod patches, some of
+which are necessary to build on Android and some of which break builds
+outside Cyanogenmod. At the same time was testing git-annex on Android.
+Found and fixed several more portability bugs while doing that. And on the
+back burner I was making some changes to the webapp..
+
+(Forgot to commit my blog post yesterday too..)
+
+Today, that all came together.
+
+* When adding another local repository in the webapp,
+ it now allows you to choose whether it should be combined with
+ your current repository, or kept separate. Several people had requested
+ a way to add local clones with the webapp, for various reasons, like
+ wanting a backup repository, or wanting to make a repository on a NFS
+ server, and this allows doing that.
+
+[[!img /assistant/combinerepos.png]]
+
+* More porting fun. FAT filesystems and other things used on Android can
+ get all new inode numbers each time mounted. Made git-annex use a
+ sentinal file to detect when this has happened, since in direct mode
+ it compares inodes. (As a bonus this also makes copying direct mode
+ repositories between filesystems work.)
+
+* Got openssh building for Android. Changed it to use $HOME/.ssh rather
+ than trusting pwent.
+
+* Got git-annex's ssh connection caching working on Android. That needs
+ a place where it can create a socket. When the
+ repository is on a crippled filesystem, it instead puts the socket
+ in a temporary directory set up on the filesystem where the git-annex
+ program resides.
+
+With ssh connection caching, transferring multiple files off my Android
+tablet *screams*! I was seeing 6.5 megabytes transferred per second,
+sustained over a whole month's worth of photos.
+
+Next problem: `git annex assistant` on Android is for some reason crashing
+with a segfault on startup. Especially odd since `git annex watch` works.
+I'm so close to snap-photo-and-it-syncs-nirvana, but still so far away...
diff --git a/doc/design/assistant/blog/day_194__nice_moment.mdwn b/doc/design/assistant/blog/day_194__nice_moment.mdwn
new file mode 100644
index 000000000..1a5ee9b1e
--- /dev/null
+++ b/doc/design/assistant/blog/day_194__nice_moment.mdwn
@@ -0,0 +1,37 @@
+<video controls src="http://downloads.kitenet.net/videos/git-annex-android.ogv" width="100%"></video>
+<a href="http://downloads.kitenet.net/videos/git-annex-android.ogv">video</a>
+
+Today's work:
+
+* Fixed `git annex add` of a modified file in direct mode.
+* Fixed bugs in the inode sentinal file code added yesterday.
+* With some help from Kevin Boone, I now understand how KBOX works and
+ how to use similar techniques to build my own standalone Android app
+ that includes git-annex.
+
+ Kevin is using a cute hack; he ships a tarball and some other stuff
+ as (pseudo-)library files (`libfoo.so`), which are the only files
+ the Android package manager deigns to install. Then the app runs one
+ of these, which installs the programs.
+
+ This avoids needing to write Java code that extracts the programs from
+ one of its assets and writes it to an executable file, which is the
+ canonical way to do this sort of thing. But I noticed it has a benefit too
+ (which KBOX does not yet exploit). Since the pseudo-library file is installed
+ with the X bit set, if it's really a program, such as busybox or git-annex,
+ that program can be run without needing to copy it to an executable file.
+ This can save a lot of disk space. So, I'm planning to include all
+ the binaries needed by git-annex as these pseudo-libraries.
+* Got the Android Terminal Emulator to build. I will be basing my first
+ git-annex Android app on this, since a terminal is needed until there's
+ a webapp.
+* Wasted several hours fighting with `Android.mk` files to include
+ my pseudo shared library. This abuse of Makefiles by the NDK is what CDBS
+ wants to grow up to be.. or is it the other way around? Anyway, it
+ sucks horribly, and I finally found a way to do it without
+ modifying the file at all. Ugh.
+* At this point, I can build a `git-annex.apk` file containing a
+ `libgit-annex.so`, and a `libbusybox.so`, that can both be directly
+ run. The plan from here is to give git-annex the ability to
+ auto-install itself, and the other pseudo-libraries, when it's run as
+ `libgit-annex.so`.
diff --git a/doc/design/assistant/blog/day_195__real_android_app.mdwn b/doc/design/assistant/blog/day_195__real_android_app.mdwn
new file mode 100644
index 000000000..f6a4eeebe
--- /dev/null
+++ b/doc/design/assistant/blog/day_195__real_android_app.mdwn
@@ -0,0 +1,32 @@
+Well, it's built. [Real Android app for git-annex](http://downloads.kitenet.net/git-annex/android/current/).
+
+[[!img /android/appinstalled.png]]
+
+When installed, this will open a terminal in which you have access to
+git-annex and all the git commands and busybox commands as well. No webapp
+yet, but command line users should feel right at home.
+
+[[!img /android/terminal.png]]
+
+Please test it out, at least as far as installing it, opening the terminal,
+and checking that you can run `git annex`; I've only been able to test on
+one Android device so far. I'm especially keen to know if it works with
+newer versions of Android than 4.0.3. (I know it only supports arm based
+Android, no x86 etc.) Please comment if you tried it.
+
+----
+
+Building this went mostly as planned, although I had about 12 builds of
+the app in the middle which crashed on startup with no error message ora
+logs. Still, it took only one day to put it all together,
+ and I even had time to gimp up a quick icon. (Better icons welcome.)
+
+Kevin thinks that my space-saving hack won't work on all Androiden, and he
+may be right. If the `lib` directory is on a different filesystem on some
+devices, it will fail. But I used it for now anyhow. Thanks to the hack,
+the 7.8 mb compressed .apk file installs to use around 23 mb of disk space.
+
+----
+
+Tomorrow: Why does `git-annex assistant` on Android re-add all existing
+files on startup?
diff --git a/doc/design/assistant/blog/day_195__real_android_app/comment_10_0112007552b30cd9bfeac614a1e399c4._comment b/doc/design/assistant/blog/day_195__real_android_app/comment_10_0112007552b30cd9bfeac614a1e399c4._comment
new file mode 100644
index 000000000..cc24c08c3
--- /dev/null
+++ b/doc/design/assistant/blog/day_195__real_android_app/comment_10_0112007552b30cd9bfeac614a1e399c4._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.253.75"
+ subject="comment 10"
+ date="2013-02-22T17:30:59Z"
+ content="""
+@rillian could you try to install KBOX <http://kevinboone.net/Term-debug.apk> and see if its terminal accepts input? It's the same terminal app, so will be good to know if I broke it or this is a wider problem.
+
+Also, did you try the soft keyboard? There's a menu item to enable it.
+"""]]
diff --git a/doc/design/assistant/blog/day_195__real_android_app/comment_11_230d3c169c713f613b9d607d84ce5092._comment b/doc/design/assistant/blog/day_195__real_android_app/comment_11_230d3c169c713f613b9d607d84ce5092._comment
new file mode 100644
index 000000000..a984dd339
--- /dev/null
+++ b/doc/design/assistant/blog/day_195__real_android_app/comment_11_230d3c169c713f613b9d607d84ce5092._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="rillian"
+ ip="64.213.70.194"
+ subject="Re: no keybourd events on Galaxy Tab 10.1"
+ date="2013-02-22T18:28:11Z"
+ content="""
+KBOX has the same input problem so you didn't break anything with your changes.
+
+I was testing with the soft keyboard. Turns out the spacebar and number keys on the soft keyboard work, as well as return, just not the alphabetic keys.
+
+Trying on a hardware keyboard (Samsung docking station) is similar. Space, Enter and numbers work, but not letters. There's some additional confusion about shift state, where it gets confused and reports shifted digits from the hardware keys when the soft keyboard is in some shift states. E.g. switching the soft keyboard to numeric mode results in shift-digits (punctuation) from the hardware numeric keys.
+"""]]
diff --git a/doc/design/assistant/blog/day_195__real_android_app/comment_12_8d74ad2a61c02272758d157282ad56ec._comment b/doc/design/assistant/blog/day_195__real_android_app/comment_12_8d74ad2a61c02272758d157282ad56ec._comment
new file mode 100644
index 000000000..76aee55fd
--- /dev/null
+++ b/doc/design/assistant/blog/day_195__real_android_app/comment_12_8d74ad2a61c02272758d157282ad56ec._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.253.75"
+ subject="comment 12"
+ date="2013-02-22T18:35:35Z"
+ content="""
+@rillian the upstream for this terminal is <https://github.com/jackpal/Android-Terminal-Emulator/>
+and I found a bug that looks similar. <https://github.com/jackpal/Android-Terminal-Emulator/issues/129>
+You might add your info there, and try the workaround documented there.
+"""]]
diff --git a/doc/design/assistant/blog/day_195__real_android_app/comment_13_4f6bc0680f2debd638933968a26975e0._comment b/doc/design/assistant/blog/day_195__real_android_app/comment_13_4f6bc0680f2debd638933968a26975e0._comment
new file mode 100644
index 000000000..57a601530
--- /dev/null
+++ b/doc/design/assistant/blog/day_195__real_android_app/comment_13_4f6bc0680f2debd638933968a26975e0._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.253.75"
+ subject="comment 13"
+ date="2013-02-22T19:39:15Z"
+ content="""
+@Karsten does KBOX work on this version of Android? <http://kevinboone.net/Term-debug.apk>
+
+It may well be that this is just too old and incompatable for the terminal to work.
+"""]]
diff --git a/doc/design/assistant/blog/day_195__real_android_app/comment_14_71539c62608866464e8faa76bc522a55._comment b/doc/design/assistant/blog/day_195__real_android_app/comment_14_71539c62608866464e8faa76bc522a55._comment
new file mode 100644
index 000000000..bfb12f24a
--- /dev/null
+++ b/doc/design/assistant/blog/day_195__real_android_app/comment_14_71539c62608866464e8faa76bc522a55._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://meep.pl/"
+ ip="193.23.174.18"
+ subject="comment 14"
+ date="2013-02-22T21:45:54Z"
+ content="""
+On Android 2.3.3 (Samsung Galaxy S+) KBOX works, git-annex displays the \"Terminal session is running\" notification and dies immediately.
+
+"""]]
diff --git a/doc/design/assistant/blog/day_195__real_android_app/comment_15_e1b205289721ae79ac7fbed2f44018b2._comment b/doc/design/assistant/blog/day_195__real_android_app/comment_15_e1b205289721ae79ac7fbed2f44018b2._comment
new file mode 100644
index 000000000..e48ee7134
--- /dev/null
+++ b/doc/design/assistant/blog/day_195__real_android_app/comment_15_e1b205289721ae79ac7fbed2f44018b2._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.253.75"
+ subject="comment 15"
+ date="2013-02-22T22:26:22Z"
+ content="""
+I'm seeing a pattern with Android 2.3 failing..
+
+This failure mode suggests that the bug is in the installation script. The next build will make the terminal not exit immediately if that script fails, so you can go in to the shell and run it by hand to see what's going wrong.
+"""]]
diff --git a/doc/design/assistant/blog/day_195__real_android_app/comment_1_4bc0aeae4fa1116944644c64feaf9697._comment b/doc/design/assistant/blog/day_195__real_android_app/comment_1_4bc0aeae4fa1116944644c64feaf9697._comment
new file mode 100644
index 000000000..05e3d298b
--- /dev/null
+++ b/doc/design/assistant/blog/day_195__real_android_app/comment_1_4bc0aeae4fa1116944644c64feaf9697._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://andrew.aylett.co.uk/"
+ nickname="andrew"
+ subject="Works on Samsung Galaxy S3"
+ date="2013-02-21T23:23:08Z"
+ content="""
+Installed, executed and managed to get the help text on a Samsung Galaxy S3 running 4.1.2. Not tried anything else yet, but looks good so far, thank you very much :).
+"""]]
diff --git a/doc/design/assistant/blog/day_195__real_android_app/comment_2_17bb6e7565d4c757f6c1e3514c22f47d._comment b/doc/design/assistant/blog/day_195__real_android_app/comment_2_17bb6e7565d4c757f6c1e3514c22f47d._comment
new file mode 100644
index 000000000..138518bdb
--- /dev/null
+++ b/doc/design/assistant/blog/day_195__real_android_app/comment_2_17bb6e7565d4c757f6c1e3514c22f47d._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlmNbexnCgLywD0MKyT9mG9mWFb_qVj-8I"
+ nickname="Joshua"
+ subject="Toshiba Excite 7.7 (Android 4.1.1)"
+ date="2013-02-22T00:15:46Z"
+ content="""
+Seems to run fine. I managed to create a repository, git-annex init it (had to set email and name per repository).
+
+The first time I tried git-annex init it said \"Detected a crippled file system.\" \"Enabling direct mode.\" The final try that actually worked only mentioned the crippled filesystem and not direct mode.
+"""]]
diff --git a/doc/design/assistant/blog/day_195__real_android_app/comment_3_cd8a6bec0f7c6843dd11d3266f25f864._comment b/doc/design/assistant/blog/day_195__real_android_app/comment_3_cd8a6bec0f7c6843dd11d3266f25f864._comment
new file mode 100644
index 000000000..643605d5b
--- /dev/null
+++ b/doc/design/assistant/blog/day_195__real_android_app/comment_3_cd8a6bec0f7c6843dd11d3266f25f864._comment
@@ -0,0 +1,44 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnBJ6Dv1glxzzi4qIzGFNa6F-mfHIvv9Ck"
+ nickname="Jim"
+ subject="Installs and runs"
+ date="2013-02-22T00:17:30Z"
+ content="""
+No problem installing on a Galaxy Nexus with 4.2.2
+
+ 1|u0_a162@android:/sdcard $ git clone https://git.jim.sh/jim/annex.git
+ Cloning into 'annex'...
+ fatal: Unable to find remote helper for 'https'
+
+Too much to hope for at this stage, I suppose :)
+
+ 128|u0_a162@android:/sdcard $ git annex assistant
+ git-annex: Not in a git repository.
+ 1|u0_a162@android:/sdcard $ git init test
+ Initialized empty Git repository in /storage/emulated/legacy/test/.git/
+ u0_a162@android:/sdcard $ cd test
+ u0_a162@android:/sdcard/test $ git annex init
+ init
+ Detected a crippled filesystem.
+
+ Enabling direct mode.
+
+ *** Please tell me who you are.
+
+ Run
+
+ git config --global user.email \"you@example.com\"
+ git config --global user.name \"Your Name\"
+
+ to set your account's default identity.
+ Omit --global to set the identity only in this repository.
+
+ fatal: unable to auto-detect email address (got 'u0_a162@localhost.(none)')
+
+ git-annex: user error (git [\"--git-dir=/storage/emulated/legacy/test/.git\",\"--work-tree=/storage/emulated/legacy/test\",\"commit-tree\",\"4b825dc642cb6eb9a060e54bf8d69288fbee4904\"] exited 128)
+ failed
+ git-annex: init: 1 failed
+ 1|u0_a162@android:/sdcard/test $
+
+However, I get the same error even after setting `user.email` and `user.name` (which seems to work fine)
+"""]]
diff --git a/doc/design/assistant/blog/day_195__real_android_app/comment_4_2d2eee4bcbbd1d069a80bff5edc90c3c._comment b/doc/design/assistant/blog/day_195__real_android_app/comment_4_2d2eee4bcbbd1d069a80bff5edc90c3c._comment
new file mode 100644
index 000000000..acb022e13
--- /dev/null
+++ b/doc/design/assistant/blog/day_195__real_android_app/comment_4_2d2eee4bcbbd1d069a80bff5edc90c3c._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.253.75"
+ subject="comment 4"
+ date="2013-02-22T00:54:56Z"
+ content="""
+@jim git http support is disabled to save space
+
+What seems to work is: git config user.email \"you@example.com\"
+
+It's probably looking in the wrong place for the global .gitconfig so --global doesn't work. The assistant
+also automates dealing with this problem BTW.
+"""]]
diff --git a/doc/design/assistant/blog/day_195__real_android_app/comment_6_3d96568c469a8c53a982f304eae5e7d4._comment b/doc/design/assistant/blog/day_195__real_android_app/comment_6_3d96568c469a8c53a982f304eae5e7d4._comment
new file mode 100644
index 000000000..0fc0a5cec
--- /dev/null
+++ b/doc/design/assistant/blog/day_195__real_android_app/comment_6_3d96568c469a8c53a982f304eae5e7d4._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="rillian"
+ ip="174.6.6.167"
+ subject="no keybourd events on Galaxy Tab 10.1"
+ date="2013-02-22T06:54:54Z"
+ content="""
+Hey, thanks for working on this.
+
+I tried the Feb 21 apk on my Samsung galaxy Tab 10.1 with Android 4.0.4. It installed and launched fine, bringing up a terminal window, keyboard, etc, but only the return key works. It's not possible to type znything. The menus, new window button etc all seem to be functional.
+"""]]
diff --git a/doc/design/assistant/blog/day_195__real_android_app/comment_6_e8667c47d07fc842cf0fe2ebbfbc1c58._comment b/doc/design/assistant/blog/day_195__real_android_app/comment_6_e8667c47d07fc842cf0fe2ebbfbc1c58._comment
new file mode 100644
index 000000000..8f1c71bad
--- /dev/null
+++ b/doc/design/assistant/blog/day_195__real_android_app/comment_6_e8667c47d07fc842cf0fe2ebbfbc1c58._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn7gQ1zZDdWhXy9H51W2krZYShNmKL3qfM"
+ nickname="Karsten"
+ subject="comment 6"
+ date="2013-02-22T07:00:41Z"
+ content="""
+Installed on Cyanogenmod 7.2 (Android 2.3.7) on my HTC Desire. When starting the App \"Terminalsitzung wird ausgeführt\" (Terminalsession is started) shows in the statusline, then the app immediately closes.
+"""]]
diff --git a/doc/design/assistant/blog/day_195__real_android_app/comment_7_cf8da7720ddc20b05955ee671ca4acd5._comment b/doc/design/assistant/blog/day_195__real_android_app/comment_7_cf8da7720ddc20b05955ee671ca4acd5._comment
new file mode 100644
index 000000000..b583d675b
--- /dev/null
+++ b/doc/design/assistant/blog/day_195__real_android_app/comment_7_cf8da7720ddc20b05955ee671ca4acd5._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm7AuSfii_tCkLyspL6Mr0ATlO6OxLNYOo"
+ nickname="Georg"
+ subject="installed successfully on galaxy nexus stock 4.2.2 rom"
+ date="2013-02-22T08:28:36Z"
+ content="""
+could run git annex and get the help screen. didn't do much else after that since I am at work currently.
+"""]]
diff --git a/doc/design/assistant/blog/day_195__real_android_app/comment_8_f4709bdbc739182819b648fd6aa00531._comment b/doc/design/assistant/blog/day_195__real_android_app/comment_8_f4709bdbc739182819b648fd6aa00531._comment
new file mode 100644
index 000000000..367e791ff
--- /dev/null
+++ b/doc/design/assistant/blog/day_195__real_android_app/comment_8_f4709bdbc739182819b648fd6aa00531._comment
@@ -0,0 +1,36 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="nexus 4, android 4.2.2"
+ date="2013-02-22T11:59:13Z"
+ content="""
+Installs but can not detect email even when set:
+
+ --global user.name \"Your Name\" <
+ --global user.email \"you@example.com\" <
+ u0_a135@android:/sdcard/git-annex.home $ git annex init
+ init
+ Detected a crippled filesystem.
+
+ *** Please tell me who you are.
+
+ Run
+
+ git config --global user.email \"you@example.com\"
+ git config --global user.name \"Your Name\"
+
+ to set your account's default identity.
+ Omit --global to set the identity only in this repository.
+
+ fatal: unable to auto-detect email address (got 'u0_a135@localhost.(none)')
+
+ git-annex: user error (git [\"--git- dir=/storage/emulated/legacy/git-annex.home/.git\",\"--work-tree=/storage/emulated/legacy/git-annex.home\",\"commit-tree\",\"4b825dc642cb6eb9a060e54bf8d69288fbee4904\"] exited 128)
+failed
+ git-annex: init: 1 failed
+ 1|u0_a135@android:/sdcard/git-annex.home $
+
+
+Sorry for bad copy paste... On tour bus in Stockholm and only have phone, no laptop...
+
+RichiH
+"""]]
diff --git a/doc/design/assistant/blog/day_195__real_android_app/comment_9_e66af12c7eca0d457b8406e9fb4b69be._comment b/doc/design/assistant/blog/day_195__real_android_app/comment_9_e66af12c7eca0d457b8406e9fb4b69be._comment
new file mode 100644
index 000000000..46a9eff3d
--- /dev/null
+++ b/doc/design/assistant/blog/day_195__real_android_app/comment_9_e66af12c7eca0d457b8406e9fb4b69be._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://ertai.myopenid.com/"
+ nickname="npouillard"
+ subject="comment 9"
+ date="2013-02-22T15:19:25Z"
+ content="""
+Same trouble with --global config, however local config works.
+"""]]
diff --git a/doc/design/assistant/blog/day_196__android_bugfixes.mdwn b/doc/design/assistant/blog/day_196__android_bugfixes.mdwn
new file mode 100644
index 000000000..a78853f93
--- /dev/null
+++ b/doc/design/assistant/blog/day_196__android_bugfixes.mdwn
@@ -0,0 +1,26 @@
+So it seems the Android app works pretty well on a variety of systems.
+Only report of 100% failure so far is on Cyanogenmod 7.2 (Android 2.3.7).
+
+Worked today on some of the obvious bugs.
+
+* Turns out that getEnvironment is broken on Android, returning no
+ environment, which explains the weird git behavior where it complains
+ that it cannot determine the username and email (because it sees no USER
+ or HOST), and suggests setting them in the global git config (which it
+ ignores, because it sees no HOME). Put in a work around for this
+ that makes `git annex init` more pleasant, and opened a bug report on
+ ghc-android.
+* Made the Android app detect when it's been upgraded, and re-link all
+ the commands, etc.
+* Fixed the bug that made `git-annex assistant` on Android re-add all
+ existing files on startup.
+* Enabled a few useful things in busybox. Including vi.
+* Replaced the service notification icon with one with the git-annex logo.
+* Made the terminal not close immediately when the shell exits, which
+ should aid in debugging of certain types of crashes.
+
+I want to set up an autobuilder for Android, but to do that I need to
+install all the haskell libraries on my server. Since getting them built
+for Android involved several days of hacking the first time, this will
+be an opportunity to make sure I can replicate that. Hopefully in less time.
+;)
diff --git a/doc/design/assistant/blog/day_197__template_haskell.mdwn b/doc/design/assistant/blog/day_197__template_haskell.mdwn
new file mode 100644
index 000000000..cb42b0803
--- /dev/null
+++ b/doc/design/assistant/blog/day_197__template_haskell.mdwn
@@ -0,0 +1,36 @@
+Set up an autobuilder for the linux standalone binaries.
+Did not get an Android autobuilder set up yet, but I did update
+the Android app with recent improvements, so [[upgrade|install/Android]].
+
+----
+
+Investigated further down paths to getting the webapp built for Android.
+
+* Since recent ghc versions support ghci and thus template haskell on arm,
+ at least some of the time, I wonder what's keeping the ghc-android build
+ from doing so? It might be due to it being a cross compiler. I tried
+ recompiling it with the stage 2, native compiler enabled. While I was
+ able to use that ghc binary on Android, it refused to run --interactive,
+ claiming it was not built with that enabled. Don't really understand
+ the ghc build system, so might have missed something.
+
+ Maybe I need to recompile ghc using the native ghc running on Android.
+ But that would involve porting gcc and a lot of libraries and toolchain
+ stuff to Android.
+
+* [yesod-pure](http://hackage.haskell.org/package/yesod-pure) is an option,
+ and I would not mind making all the code changes to use it, getting
+ rid of template haskell entirely. (Probably around 1 thousand lines of
+ code would need to be written, but most of it would be trivial
+ conversion of hamlet templates.)
+
+ Question is, will yesod install at all without template haskell? Not
+ easily. `vector`, `monad-logger`, `aeson`, `shakespeare`,
+ `shakespeare-css`, `shakespeare-js`, `shakespeare-i18n`, `hamlet`
+ all use TH at build time. Hacked them all to just remove the TH parts.
+
+ The hack job on `yesod-core` was especially rough, involving things like
+ 404 handlers. Did get it to build tho!
+
+ Still a dozen packages before I can build yesod, and then will try
+ building [this yesod-pure demo](https://gist.github.com/snoyberg/3870834/raw/212f0164de36524291df3ab35788e2b72d8d1e75/fib.hs).
diff --git a/doc/design/assistant/blog/day_197__template_haskell/comment_1_82d9f9508929d84abf7b718c59436ae8._comment b/doc/design/assistant/blog/day_197__template_haskell/comment_1_82d9f9508929d84abf7b718c59436ae8._comment
new file mode 100644
index 000000000..95fcde0d6
--- /dev/null
+++ b/doc/design/assistant/blog/day_197__template_haskell/comment_1_82d9f9508929d84abf7b718c59436ae8._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="http://meep.pl/"
+ ip="193.23.174.18"
+ subject="Android 2.3"
+ date="2013-02-24T15:16:51Z"
+ content="""
+The updated version lets me see the failure(s), and it looks like this:
+
+ cd: can't cd to /data/data/ga.androidterm/lib/lib.runshell.so/../..
+ [: not found
+ [: not found
+ could not open //installed-version, No such file or directory
+ /data/data/ga.androidterm/lib/lib.runshell.so: cannot create
+ /sdcard/git-annex.home/git-annex-install.log: directory nonexistent
+
+ [Terminal session finished]
+
+"""]]
diff --git a/doc/design/assistant/blog/day_198__bugfixes.mdwn b/doc/design/assistant/blog/day_198__bugfixes.mdwn
new file mode 100644
index 000000000..ec8535ad1
--- /dev/null
+++ b/doc/design/assistant/blog/day_198__bugfixes.mdwn
@@ -0,0 +1,11 @@
+Wrote a C shim to get the Android app started. This avoids it relying on
+the Android /system/bin/sh to run its shell script, or indeed relying on
+any unix utilities from Android at all, which may help on some
+systems. Pushed a new build of the Android app.
+
+Tracked down a failure a lot of people are reporting with WebDAV support
+to a backported security fix in the TLS library, and filed an upstream bug
+about it.
+
+Various other misc fixing and stuff.
+My queue of bug reports and stuff only has 47 items in it now. Urk..
diff --git a/doc/design/assistant/blog/day_198__bugfixes/comment_1_5a15b5bad0f9ba2423d2aebe440ac0ea._comment b/doc/design/assistant/blog/day_198__bugfixes/comment_1_5a15b5bad0f9ba2423d2aebe440ac0ea._comment
new file mode 100644
index 000000000..279a53f04
--- /dev/null
+++ b/doc/design/assistant/blog/day_198__bugfixes/comment_1_5a15b5bad0f9ba2423d2aebe440ac0ea._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="http://meep.pl/"
+ ip="193.23.174.18"
+ subject="Android 2.3 again"
+ date="2013-02-24T23:07:28Z"
+ content="""
+I got _a lot_ further with the latest upgrade.
+
+* installation worked
+* `git init` worked
+* first `git annex init` asked to set user.{email,name}
+* `git config --global ...` worked
+* second `git annex init` segfaulted, but not immediately:
+
+ init
+ Detected a crippled filesystem.
+ error: git-annex died of signal 11
+
+"""]]
diff --git a/doc/design/assistant/blog/day_198__bugfixes/comment_2_36d94b838e5e65c85e7afaabe8a578f1._comment b/doc/design/assistant/blog/day_198__bugfixes/comment_2_36d94b838e5e65c85e7afaabe8a578f1._comment
new file mode 100644
index 000000000..0a3414864
--- /dev/null
+++ b/doc/design/assistant/blog/day_198__bugfixes/comment_2_36d94b838e5e65c85e7afaabe8a578f1._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="comment 2"
+ date="2013-02-25T11:22:53Z"
+ content="""
+Is the autiobuilder for linux available already?
+I can't find it, and I'm eager to try the thumbdrive related fixes (where I can specify a simple folder).
+
+Best,
+ Laszlo
+"""]]
diff --git a/doc/design/assistant/blog/day_198__bugfixes/comment_3_ae9b74341a3bc6e1e84d2c0ca4c5f612._comment b/doc/design/assistant/blog/day_198__bugfixes/comment_3_ae9b74341a3bc6e1e84d2c0ca4c5f612._comment
new file mode 100644
index 000000000..39e017ceb
--- /dev/null
+++ b/doc/design/assistant/blog/day_198__bugfixes/comment_3_ae9b74341a3bc6e1e84d2c0ca4c5f612._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.210"
+ subject="comment 3"
+ date="2013-02-25T15:53:30Z"
+ content="""
+@meep try running it with --debug for some more hint of where it's crashing
+
+@Laszlo see [[install/Linux_standalone]]
+"""]]
diff --git a/doc/design/assistant/blog/day_198__bugfixes/comment_4_5a4827227c03bcff3b1e4c44b531f816._comment b/doc/design/assistant/blog/day_198__bugfixes/comment_4_5a4827227c03bcff3b1e4c44b531f816._comment
new file mode 100644
index 000000000..fafb8fd27
--- /dev/null
+++ b/doc/design/assistant/blog/day_198__bugfixes/comment_4_5a4827227c03bcff3b1e4c44b531f816._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="comment 4"
+ date="2013-02-25T18:28:09Z"
+ content="""
+joeyh: Is the 20130216 is the newest? Because you just wrote about two days ago of direct mode fixes, I'm interested in.
+I tried 20130216 already.
+
+Laszlo
+
+"""]]
diff --git a/doc/design/assistant/blog/day_198__bugfixes/comment_5_9c5f4c85217e898be4c57c615e53c36f._comment b/doc/design/assistant/blog/day_198__bugfixes/comment_5_9c5f4c85217e898be4c57c615e53c36f._comment
new file mode 100644
index 000000000..221e28d25
--- /dev/null
+++ b/doc/design/assistant/blog/day_198__bugfixes/comment_5_9c5f4c85217e898be4c57c615e53c36f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.210"
+ subject="comment 5"
+ date="2013-02-26T16:33:11Z"
+ content="""
+I have not made a release with those fixes yet, but they are available in the autobuilds.
+"""]]
diff --git a/doc/design/assistant/blog/day_198__bugfixes/comment_6_bccf1abfb7f56d97673158f3ccfce511._comment b/doc/design/assistant/blog/day_198__bugfixes/comment_6_bccf1abfb7f56d97673158f3ccfce511._comment
new file mode 100644
index 000000000..22012c0cd
--- /dev/null
+++ b/doc/design/assistant/blog/day_198__bugfixes/comment_6_bccf1abfb7f56d97673158f3ccfce511._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://meep.pl/"
+ ip="193.23.174.18"
+ subject="git annex init --debug"
+ date="2013-02-27T06:39:19Z"
+ content="""
+The last thing before the signal 11 error that I can see with `--debug` is `read: uname [\"-n\"]` after reports of running 5 git commands.
+
+"""]]
diff --git a/doc/design/assistant/blog/day_198__bugfixes/comment_7_6f1b51b002cc5d2b505d80e3e04bf6f3._comment b/doc/design/assistant/blog/day_198__bugfixes/comment_7_6f1b51b002cc5d2b505d80e3e04bf6f3._comment
new file mode 100644
index 000000000..8adcd394d
--- /dev/null
+++ b/doc/design/assistant/blog/day_198__bugfixes/comment_7_6f1b51b002cc5d2b505d80e3e04bf6f3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://meep.pl/"
+ ip="193.23.174.18"
+ subject="comment 7"
+ date="2013-02-27T06:53:15Z"
+ content="""
+But the error does not happen immediately after that. All the 6 log messages have the same timestamp and `git annex init --debug; date` prints a timestamp that is 3-4 seconds later.
+"""]]
diff --git a/doc/design/assistant/blog/day_198__bugfixes/comment_8_8a3542437663028b17442818eba3f7c5._comment b/doc/design/assistant/blog/day_198__bugfixes/comment_8_8a3542437663028b17442818eba3f7c5._comment
new file mode 100644
index 000000000..f9a50b94e
--- /dev/null
+++ b/doc/design/assistant/blog/day_198__bugfixes/comment_8_8a3542437663028b17442818eba3f7c5._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://meep.pl/"
+ ip="193.23.174.18"
+ subject="comment 8"
+ date="2013-02-27T06:55:24Z"
+ content="""
+Also, this was after a reinstall. The next time I start the app the terminal opens but prompt does not appear (at least not for a very long time). Then after uninstall and reinstall I get to the prompt again.
+
+"""]]
diff --git a/doc/design/assistant/blog/day_199__wrapping_up_Android_for_now.mdwn b/doc/design/assistant/blog/day_199__wrapping_up_Android_for_now.mdwn
new file mode 100644
index 000000000..0cd92137b
--- /dev/null
+++ b/doc/design/assistant/blog/day_199__wrapping_up_Android_for_now.mdwn
@@ -0,0 +1,26 @@
+An Android autobuilder is now set up to run nightly. At this point
+I don't see an immediate way to getting the webapp working on Android, so
+it's best to wait a month or two and see how things develop in Haskell land.
+So I'm moving on to other things.
+
+Today:
+
+* Fixed a nasty regression that made `*` not match files in subdirectories.
+ That broke the preferred content handling, amoung other things. I will
+ be pushing out a new release soon.
+* As a last Android thing (for now), made the Android app automatically
+ run `git annex assistant --autostart` , so you can manually set up
+ an assistant-driven repository on Android, listing the repository in
+ `.config/git-annex/autostart`
+* Made the webapp display any error message from `git init` if it fails.
+ This was the one remaining gap in the logging.
+ One reason it could fail is if the system has a newer git in use, and
+ `~/.gitconfig` is configured with some options the older git bundled
+ with git-annex doesn't like.
+* Bumped the major version to 4, and annex.version will be set to 4 in
+ new direct mode repositories. (But version 3 is otherwise still used, to
+ avoid any upgrade pain.) This is to prevent old versions that don't
+ understand direct mode from getting confused. I hope direct mode is
+ finally complete, too, after the work to make it work on crippled
+ filesystems this month.
+* Misc other bugfixes etc. Backlog down to 43.
diff --git a/doc/design/assistant/blog/day_199__wrapping_up_Android_for_now/comment_1_ec57358afc7e78d2860aa4237793832d._comment b/doc/design/assistant/blog/day_199__wrapping_up_Android_for_now/comment_1_ec57358afc7e78d2860aa4237793832d._comment
new file mode 100644
index 000000000..1d7923739
--- /dev/null
+++ b/doc/design/assistant/blog/day_199__wrapping_up_Android_for_now/comment_1_ec57358afc7e78d2860aa4237793832d._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="Automagic photo backups"
+ date="2013-02-26T21:56:44Z"
+ content="""
+Did you investigate how hard it would be to only commit & upload once the phone is being charged _and_ on WiFi? That does not rely on the webapp, but it would make using git-annex on Android a lot more useful until you restart your work on this.
+
+
+RichiH
+"""]]
diff --git a/doc/design/assistant/blog/day_19__random_improvements.mdwn b/doc/design/assistant/blog/day_19__random_improvements.mdwn
new file mode 100644
index 000000000..acb30bf93
--- /dev/null
+++ b/doc/design/assistant/blog/day_19__random_improvements.mdwn
@@ -0,0 +1,50 @@
+Random improvements day..
+
+Got the merge conflict resolution code working in `git annex assistant`.
+
+Did some more fixes to the pushing and pulling code, covering some cases
+I missed earlier.
+
+Git syncing seems to work well for me now; I've seen it recover
+from a variety of error conditions, including merge conflicts and repos
+that were temporarily unavailable.
+
+----
+
+There is definitely a MVar deadlock if the merger thread's inotify event
+handler tries to run code in the Annex monad. Luckily, it doesn't
+currently seem to need to do that, so I have put off debugging what's going
+on there.
+
+Reworked how the inotify thread runs, to avoid the two inotify threads
+in the assistant now from both needing to wait for program termination,
+in a possibly conflicting manner.
+
+Hmm, that *seems* to have fixed the MVar deadlock problem.
+
+----
+
+Been thinking about how to fix [[bugs/watcher_commits_unlocked_files]].
+Posted some thoughts there.
+
+It's about time to move on to data [[syncing]]. While eventually that will
+need to build a map of the repo network to efficiently sync data over the
+fastest paths, I'm thinking that I'll first write a dumb version. So, two
+more threads:
+
+1. Uploads new data to every configured remote. Triggered by the watcher
+ thread when it adds content. Easy; just use a `TSet` of Keys to send.
+
+2. Downloads new data from the cheapest remote that has it. Could be
+ triggered by the
+ merger thread, after it merges in a git sync. Rather hard; how does it
+ work out what new keys are in the tree without scanning it all? Scan
+ through the git history to find newly created files? Maybe the watcher
+ triggers this thread instead, when it sees a new symlink, without data,
+ appear.
+
+Both threads will need to be able to be stopped, and restarted, as needed
+to control the data transfer. And a lot of other control smarts will
+eventually be needed, but my first pass will be to do a straightforward
+implementation. Once it's done, the git annex assistant will be basically
+usable.
diff --git a/doc/design/assistant/blog/day_1__inotify.mdwn b/doc/design/assistant/blog/day_1__inotify.mdwn
new file mode 100644
index 000000000..ca27a4586
--- /dev/null
+++ b/doc/design/assistant/blog/day_1__inotify.mdwn
@@ -0,0 +1,57 @@
+First day of [Kickstarter funded work](http://www.kickstarter.com/projects/joeyh/git-annex-assistant-like-dropbox-but-with-your-own/)!
+
+Worked on [[inotify]] today. The `watch` branch in git now does a pretty
+good job of following changes made to the directory, annexing files
+as they're added and staging other changes into git. Here's a quick
+transcript of it in action:
+
+ joey@gnu:~/tmp>mkdir demo
+ joey@gnu:~/tmp>cd demo
+ joey@gnu:~/tmp/demo>git init
+ Initialized empty Git repository in /home/joey/tmp/demo/.git/
+ joey@gnu:~/tmp/demo>git annex init demo
+ init demo ok
+ (Recording state in git...)
+ joey@gnu:~/tmp/demo>git annex watch &
+ [1] 3284
+ watch . (scanning...) (started)
+ joey@gnu:~/tmp/demo>dd if=/dev/urandom of=bigfile bs=1M count=2
+ add ./bigfile 2+0 records in
+ 2+0 records out
+ 2097152 bytes (2.1 MB) copied, 0.835976 s, 2.5 MB/s
+ (checksum...) ok
+ (Recording state in git...)
+ joey@gnu:~/tmp/demo>ls -la bigfile
+ lrwxrwxrwx 1 joey joey 188 Jun 4 15:36 bigfile -> .git/annex/objects/Wx/KQ/SHA256-s2097152--e5ced5836a3f9be782e6da14446794a1d22d9694f5c85f3ad7220b035a4b82ee/SHA256-s2097152--e5ced5836a3f9be782e6da14446794a1d22d9694f5c85f3ad7220b035a4b82ee
+ joey@gnu:~/tmp/demo>git status -s
+ A bigfile
+ joey@gnu:~/tmp/demo>mkdir foo
+ joey@gnu:~/tmp/demo>mv bigfile foo
+ "del ./bigfile"
+ joey@gnu:~/tmp/demo>git status -s
+ AD bigfile
+ A foo/bigfile
+
+Due to Linux's inotify interface, this is surely some of the most subtle,
+race-heavy code that I'll need to deal with while developing the git annex
+assistant. But I can't start wading, need to jump off the deep end to make
+progress!
+
+The hardest problem today involved the case where a directory is moved
+outside of the tree that's being watched. Inotify will still send events
+for such directories, but it doesn't make sense to continue to handle them.
+
+Ideally I'd stop inotify watching such directories, but a lot of state
+would need to be maintained to know which inotify handle to stop watching.
+(Seems like Haskell's inotify API makes this harder than it needs to be...)
+
+Instead, I put in a hack that will make it detect inotify events from
+directories moved away, and ignore them. This is probably acceptable,
+since this is an unusual edge case.
+
+----
+
+The notable omission in the inotify code, which I'll work on next, is
+staging deleting of files. This is tricky because adding a file to the
+annex happens to cause a deletion event. I need to make sure there are no
+races where that deletion event causes data loss.
diff --git a/doc/design/assistant/blog/day_200__release_day.mdwn b/doc/design/assistant/blog/day_200__release_day.mdwn
new file mode 100644
index 000000000..99aebcf70
--- /dev/null
+++ b/doc/design/assistant/blog/day_200__release_day.mdwn
@@ -0,0 +1,19 @@
+As well as making a new release, I rewrote most of the Makefile, so that it
+uses cabal to build git-annex. This avoids some duplication, and most
+importantly, means that the Makefile can auto-detect available libraries
+rather than needing to juggle build flags manually. Which was becoming a
+real pain.
+
+I had avoided doing this before because cabal is slow for me on my little
+netbook. Adding ten seconds to every rebuild really does matter! But I came
+up with a hack to let me do incremental development builds without the
+cabal overhead, by intercepting and reusing the ghc command that cabal
+runs.
+
+There was also cabal "fun" to get the Android build working with cabal.
+And more fun involving building the test suite. For various reasons, I
+decided to move the test suite into the git-annex binary. So you can run
+`git annex test` at any time, any place, and it self-tests. That's a neat
+trick I've seen one or two other programs do, and probably the nicest thing
+to come out of what was otherwise a pretty yak shaving change that involved
+babysitting builds all day.
diff --git a/doc/design/assistant/blog/day_200__release_day/comment_10_40cfe9bfd9e611fd734dbb5aad348aa3._comment b/doc/design/assistant/blog/day_200__release_day/comment_10_40cfe9bfd9e611fd734dbb5aad348aa3._comment
new file mode 100644
index 000000000..dfd4f32fe
--- /dev/null
+++ b/doc/design/assistant/blog/day_200__release_day/comment_10_40cfe9bfd9e611fd734dbb5aad348aa3._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 10"
+ date="2013-03-01T04:23:48Z"
+ content="""
+@Brian, I follow your logic, it does seem that start.c is not finding itself. But, you checked the pid of the terminal, while start.c is the program it (usually) starts.
+
+Anyway, I have tried making start.c fall back to a hard coded path if it cannot find busybox. It'll also say what path it detected, which may help debug the underlying problem. You can pick up an app with this change from the autobuilder.
+"""]]
diff --git a/doc/design/assistant/blog/day_200__release_day/comment_11_b26890fdae575d42170988073fb2e45d._comment b/doc/design/assistant/blog/day_200__release_day/comment_11_b26890fdae575d42170988073fb2e45d._comment
new file mode 100644
index 000000000..164dce53f
--- /dev/null
+++ b/doc/design/assistant/blog/day_200__release_day/comment_11_b26890fdae575d42170988073fb2e45d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmmLfBDEDFfEOba8Ra46nsnTmoNHFsLObo"
+ nickname="Brian"
+ subject="comment 11"
+ date="2013-03-01T12:02:09Z"
+ content="""
+Good point--it didn't occur to me start.c runs as a child process. Makes sense. How do I download the output of the autobuild? Size-wise and behavior-wise, http://downloads.kitenet.net/git-annex/android/current/git-annex.apk looks like the same file I already had.
+"""]]
diff --git a/doc/design/assistant/blog/day_200__release_day/comment_13_710a30c5d31bf549833ecfe9a0997c94._comment b/doc/design/assistant/blog/day_200__release_day/comment_13_710a30c5d31bf549833ecfe9a0997c94._comment
new file mode 100644
index 000000000..50b99a965
--- /dev/null
+++ b/doc/design/assistant/blog/day_200__release_day/comment_13_710a30c5d31bf549833ecfe9a0997c94._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 13"
+ date="2013-03-01T16:36:58Z"
+ content="""
+@Brian the autobuild is linked to on [[install/Android]]
+"""]]
diff --git a/doc/design/assistant/blog/day_200__release_day/comment_13_b6f62ab7e810ba6d3a43f0ead370c79a._comment b/doc/design/assistant/blog/day_200__release_day/comment_13_b6f62ab7e810ba6d3a43f0ead370c79a._comment
new file mode 100644
index 000000000..efd38879f
--- /dev/null
+++ b/doc/design/assistant/blog/day_200__release_day/comment_13_b6f62ab7e810ba6d3a43f0ead370c79a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmmLfBDEDFfEOba8Ra46nsnTmoNHFsLObo"
+ nickname="Brian"
+ subject="comment 13"
+ date="2013-03-01T23:52:53Z"
+ content="""
+I got the latest autobuild version installed and the fallback works for me--thanks. FYI, the fallback error message says: \"cannot find expected files in /data/app-lib\"
+"""]]
diff --git a/doc/design/assistant/blog/day_200__release_day/comment_1_a68e1ed7829b49086c567d97ddc09912._comment b/doc/design/assistant/blog/day_200__release_day/comment_1_a68e1ed7829b49086c567d97ddc09912._comment
new file mode 100644
index 000000000..51247f6b7
--- /dev/null
+++ b/doc/design/assistant/blog/day_200__release_day/comment_1_a68e1ed7829b49086c567d97ddc09912._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnxp2XU8gIribhhGhGuYtU6eMMwHv5gUGI"
+ nickname="Amitai"
+ subject="comment 1"
+ date="2013-02-28T02:53:53Z"
+ content="""
+That _is_ a neat trick, especially since you're deploying to odd platforms where you'll probably be even gladder of the in-app tests far in the future than you are now!
+"""]]
diff --git a/doc/design/assistant/blog/day_200__release_day/comment_2_39d3ad0a029fe56e96f97d28d17fbbd2._comment b/doc/design/assistant/blog/day_200__release_day/comment_2_39d3ad0a029fe56e96f97d28d17fbbd2._comment
new file mode 100644
index 000000000..f6aeb306d
--- /dev/null
+++ b/doc/design/assistant/blog/day_200__release_day/comment_2_39d3ad0a029fe56e96f97d28d17fbbd2._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://meep.pl/"
+ ip="193.23.174.18"
+ subject="comment 2"
+ date="2013-02-28T06:13:21Z"
+ content="""
+Maybe it's the build changes? Android apk disappeared from <http://downloads.kitenet.net/git-annex/android/current/>
+"""]]
diff --git a/doc/design/assistant/blog/day_200__release_day/comment_3_5b752d6a8d74e61190f09384b6108206._comment b/doc/design/assistant/blog/day_200__release_day/comment_3_5b752d6a8d74e61190f09384b6108206._comment
new file mode 100644
index 000000000..066abd19a
--- /dev/null
+++ b/doc/design/assistant/blog/day_200__release_day/comment_3_5b752d6a8d74e61190f09384b6108206._comment
@@ -0,0 +1,31 @@
+[[!comment format=c
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="comment 3"
+ date="2013-02-28T08:40:46Z"
+ content="""
+Two suggestion:
+1. Possibility to restrict CPU usage (a 10-20% would be nice, or a slider)
+2. Pager on Dashboard
+
+I have a directory, it is 741MB, and contains 23381 files.
+This directory is pretty much everything needed for my daily job.
+
+I added a copy of this directory to annex, then I created a backup dir of annex,
+and my laptop is using almost 100%CPU al the time, it is running since 1 hour already, and
+only 140MB was copied over to the backup directory.
+
+Don't get me wrong, this application just blows my mind, and it seems to *work* for the first time for real.
+
+The suggestion is simply a slider in resource manager (preferably inside dashboard):
+Restrict CPU usage [0---X---100]34%
+Restrict upload bandwith [0-X----800]9kB/s
+Restrict download bandwith [0-X----800]80kB/s
+
+Also the pager is musthave in dashboard, because it renders firefox unusable with that many entries (21000).
+
+Nice work, thank you for the release!
+
+Laszlo
+
+"""]]
diff --git a/doc/design/assistant/blog/day_200__release_day/comment_4_881274ae0d6230bb4cafa4151ad72b49._comment b/doc/design/assistant/blog/day_200__release_day/comment_4_881274ae0d6230bb4cafa4151ad72b49._comment
new file mode 100644
index 000000000..75d54e04e
--- /dev/null
+++ b/doc/design/assistant/blog/day_200__release_day/comment_4_881274ae0d6230bb4cafa4151ad72b49._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="lot of stuck git processes"
+ date="2013-02-28T09:01:25Z"
+ content="""
+Oh, and here is how it looks
+ps -e |grep git
+command after git-annex has been stopped (from the gui):
+(54 process, from which 50 process <defunct>)
+http://pastebin.com/5u74qTNU
+"""]]
diff --git a/doc/design/assistant/blog/day_200__release_day/comment_5_e220059be77cf0ef396f37a4f9ccf9b5._comment b/doc/design/assistant/blog/day_200__release_day/comment_5_e220059be77cf0ef396f37a4f9ccf9b5._comment
new file mode 100644
index 000000000..bd518cc0a
--- /dev/null
+++ b/doc/design/assistant/blog/day_200__release_day/comment_5_e220059be77cf0ef396f37a4f9ccf9b5._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 5"
+ date="2013-02-28T19:42:09Z"
+ content="""
+@meep That's not the autobuild. I put the wrong file there! Fixed.
+"""]]
diff --git a/doc/design/assistant/blog/day_200__release_day/comment_6_ec2152151188dd252cdb61c68cfc12e4._comment b/doc/design/assistant/blog/day_200__release_day/comment_6_ec2152151188dd252cdb61c68cfc12e4._comment
new file mode 100644
index 000000000..43e676f60
--- /dev/null
+++ b/doc/design/assistant/blog/day_200__release_day/comment_6_ec2152151188dd252cdb61c68cfc12e4._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 6"
+ date="2013-02-28T19:52:59Z"
+ content="""
+Lazlo, could you please file a proper [[bug|bugs]] report and include details like what version of git-annex you're using there when you get the zombies.
+
+I have modified the webapp to only ever show 10 queued transfers on the dashboard.
+"""]]
diff --git a/doc/design/assistant/blog/day_200__release_day/comment_7_42572411617c287368482bb9dcf94324._comment b/doc/design/assistant/blog/day_200__release_day/comment_7_42572411617c287368482bb9dcf94324._comment
new file mode 100644
index 000000000..409ade91d
--- /dev/null
+++ b/doc/design/assistant/blog/day_200__release_day/comment_7_42572411617c287368482bb9dcf94324._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmmLfBDEDFfEOba8Ra46nsnTmoNHFsLObo"
+ nickname="Brian"
+ subject="link busybox: No such file or directory"
+ date="2013-03-01T02:32:32Z"
+ content="""
+When I run the 28-Feb-2013 android version of git annex, I'm getting the error:
+
+ link busybox: No such file or directory
+
+Maybe this code is not finding the busybox.so file:
+
+ link(\"lib/lib.busybox.so\", \"busybox\")
+
+Any ideas how I can troubleshoot?
+
+I'm running Android 4.2.2.
+"""]]
diff --git a/doc/design/assistant/blog/day_200__release_day/comment_8_6b69aa81a9ba4e07e547ed1869946d51._comment b/doc/design/assistant/blog/day_200__release_day/comment_8_6b69aa81a9ba4e07e547ed1869946d51._comment
new file mode 100644
index 000000000..c375f3b84
--- /dev/null
+++ b/doc/design/assistant/blog/day_200__release_day/comment_8_6b69aa81a9ba4e07e547ed1869946d51._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 8"
+ date="2013-03-01T03:10:35Z"
+ content="""
+@Brian what you can do is go to the terminal's preferences menu and change the shell it runs to `/system/bin/sh` . This should let you open a new tab with a shell prompt. Then you can try to cd to `/data/data/ga.androidterm`, and see if both `lib/lib.start.so` and `lib/lib.busybox.so` exist.
+
+You could then try to do the same thing it does to set up the system:
+
+<pre>
+ln lib/lib.busybox.so busybox
+./busybox sh lib/lib.runshell.so
+</pre>
+"""]]
diff --git a/doc/design/assistant/blog/day_200__release_day/comment_9_b070a2e4151d9fbf43d7906efa78515f._comment b/doc/design/assistant/blog/day_200__release_day/comment_9_b070a2e4151d9fbf43d7906efa78515f._comment
new file mode 100644
index 000000000..4acf003c8
--- /dev/null
+++ b/doc/design/assistant/blog/day_200__release_day/comment_9_b070a2e4151d9fbf43d7906efa78515f._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmmLfBDEDFfEOba8Ra46nsnTmoNHFsLObo"
+ nickname="Brian"
+ subject="comment 9"
+ date="2013-03-01T03:55:46Z"
+ content="""
+@joey Both .so files were present and I was able to run the ln and busybox commands. And after that 'git annex' displayed the help screen. Thanks!
+
+Then I ran 'ps | grep ga.androidterm' to find the pid and then 'ls -l /proc/&lt;pid&gt;/exe' and it showed the symlink points at '/system/bin/app_process'.
+
+So the 'int n=readlink(\"/proc/self/exe\", buf, 1023);' in start.c isn't very useful in this case.
+"""]]
diff --git a/doc/design/assistant/blog/day_201__real_Android_wrapup.mdwn b/doc/design/assistant/blog/day_201__real_Android_wrapup.mdwn
new file mode 100644
index 000000000..8ff743f68
--- /dev/null
+++ b/doc/design/assistant/blog/day_201__real_Android_wrapup.mdwn
@@ -0,0 +1,38 @@
+[[!meta title="day 201 real Android wrapup"]]
+
+I got yesod-pure fully working on Android...
+
+[[!img fib.png size=400x]]
+
+As expected, this involved manually splicing some template haskell. I'm now
+confident I can port the git-annex webapp to Android this way, and that it
+will take about a week. Probably will start on that in a month or so. If
+anyone has some spare Android hardware they'd like to loan me, possibly
+sooner. (Returning loaner Asus Transformer tomorrow; thanks Mark.) Although
+I'm inclined to let the situation develop; we may just get a ghc-android
+that supports TH..
+
+Also:
+
+* Fixed several bugs in the Android installation process.
+* Committed patches for all Haskell libraries I've modified to
+ the git-annex git repo.
+* Ran the test suite on Android. It found a problem; seems `git clone`
+ of a local repository is broken in the Android environment.
+
+Non-Android:
+
+* Made the assistant check every hour if logs have grown larger than a
+ megabyte, and rotate them to avoid using too much disk space.
+* Avoided noise in log about typechanged objects when running
+ git commit in direct mode repositories. Seems `git commit`
+ has no way to shut that up, so I had to /dev/null it.
+* When run with `--debug`, the assistant now logs more information
+ about why it transfers or drops objects.
+* Found and fixed a case where moving a file to an archive directory would
+ not cause its content to be dropped.
+* Working on a bug with the assistant where moving a file out of an
+ archive directory in direct mode sometimes ends up with a symlink
+ rather than a proper direct mode file. Have not gotten to the bottom
+ of it entirely, but it's a race, and I think the race is between
+ the direct mode mapping being updated, and the file being transferred.
diff --git a/doc/design/assistant/blog/day_201__real_Android_wrapup/comment_1_88b9950c51324f0bb89c5646b3170952._comment b/doc/design/assistant/blog/day_201__real_Android_wrapup/comment_1_88b9950c51324f0bb89c5646b3170952._comment
new file mode 100644
index 000000000..b9edfc4b6
--- /dev/null
+++ b/doc/design/assistant/blog/day_201__real_Android_wrapup/comment_1_88b9950c51324f0bb89c5646b3170952._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="http://ao2.it/"
+ nickname="ao2"
+ subject="Using the Emulator?"
+ date="2013-03-04T13:58:18Z"
+ content="""
+Hi Joey,
+
+while you wait for some actual Android device have you tried the emulator?
+
+I've recently started playing with Android without any physical device, and the emulator is pretty responsive with hardware acceleration on (you need to run an x86 AVD).
+
+Here are some instructions: http://git.ao2.it/android/android-app-development-getting-started.git/blob/HEAD:/android-app-development-getting-started.sh
+
+Also, are you going to use a WebView connecting to the haskell web server for the WebApp?
+
+Ciao,
+ Antonio
+"""]]
diff --git a/doc/design/assistant/blog/day_201__real_Android_wrapup/fib.png b/doc/design/assistant/blog/day_201__real_Android_wrapup/fib.png
new file mode 100644
index 000000000..f9b8c27fd
--- /dev/null
+++ b/doc/design/assistant/blog/day_201__real_Android_wrapup/fib.png
Binary files differ
diff --git a/doc/design/assistant/blog/day_201__working_web_server.mdwn b/doc/design/assistant/blog/day_201__working_web_server.mdwn
new file mode 100644
index 000000000..c9e959a33
--- /dev/null
+++ b/doc/design/assistant/blog/day_201__working_web_server.mdwn
@@ -0,0 +1,31 @@
+Seems I am not done with the Android porting just yet after all. One more
+porting day..
+
+Last night I managed to get all of Yesod to build for Android.
+I even successfully expanded some Template Haskell used in yesod-form. And
+am fairly confident I could manually expand all the TH in there, so it's
+actually useable without TH. Most of the TH is just commented out for now.
+
+However, programs using Yesod didn't link; lots of missing symbols. I have
+been fighting to fix those all day today.
+
+Finally, I managed to build [the yesod-pure demo server](https://gist.github.com/snoyberg/3870834/raw/212f0164de36524291df3ab35788e2b72d8d1e75/fib.hs),
+and I have a working web server on Android! It listens for requests, it logs
+them correctly, and it replies to requests. I did cripple yesod's routing
+code in my hack-n-slash port of it, so it fails to *display* any pages,
+but never has "Internal Server Error" in a web browser been such a sweet
+sight. ;-)
+
+At this point, I estimate about 1 or 2 weeks work to get to an Android
+webapp. I'd need to:
+
+1. More carefully port Yesod, manually expanding all Template Haskell
+ as I went, rather than commenting it all out like I did this time.
+2. Either develop a tool to automatically expand Hamlet TH splices
+ (preferred; seems doable), or convert all the webapp's templates
+ to not use Hamlet.
+
+-----
+
+I've modified 38 Haskell libraries so far to port them to Android. Mostly
+small hacks, but eep this is a lot of stuff to keep straight.
diff --git a/doc/design/assistant/blog/day_203__procrastination.mdwn b/doc/design/assistant/blog/day_203__procrastination.mdwn
new file mode 100644
index 000000000..b6eb262e9
--- /dev/null
+++ b/doc/design/assistant/blog/day_203__procrastination.mdwn
@@ -0,0 +1,25 @@
+Stuck on a bug or two, I instead built a new Preferences page:
+
+[[!img /assistant/preferences.png]]
+
+The main reason I wanted that was to allow enabling debug logging at
+runtime. But I've also wanted to expose annex.diskreserve and
+annex.numcopies settings to the webapp user. Might as well let them control
+whether it auto-starts too.
+
+Had some difficulty deciding where to put this. It could be considered
+additional configuration for the local repository, and so go in the
+local repository edit form. However, this stuff can only be configured for
+local repositories, and not remotes, and that same form is used to edit
+remotes, which would lead to inconsistent UI and complicate the code.
+Also, it might grow to include things not tied to any repository,
+like choice of key/value backends. So, I put the preferences on their own
+page.
+
+---
+
+Also, based on some useful feedback from testing the assistant with a large
+number of files, I made the assistant disable git-gc auto packing in
+repositories it sets up. (Like fsck, git-gc always seems to run exactly
+when you are in a hurry.) Instead, it'll pack at most once a day, and with
+a rather higher threshold for the number of loose objects.
diff --git a/doc/design/assistant/blog/day_204__deprocrastination.mdwn b/doc/design/assistant/blog/day_204__deprocrastination.mdwn
new file mode 100644
index 000000000..6299140e3
--- /dev/null
+++ b/doc/design/assistant/blog/day_204__deprocrastination.mdwn
@@ -0,0 +1,62 @@
+Tracked down the bug that's been eluding me for days. It was indeed a race, and
+could result in a file being transferred into a direct mode repository and
+ending up in indirect mode. Was easy to fix once understood, just needed to
+update the direct mode mapping before starting the transfer.
+
+While I was in there, I noticed another potential race, also in direct
+mode, where the watcher could decide to rewrite a symlink to fix its
+target, and at just the wrong time direct mode content could arrive in its
+place, and so get deleted. Fixed that too.
+
+Seems likely there are some other direct mode races. I spent quite a while
+hammering on dealing with the indirect mode races with the assistant
+originally.
+
+-----
+
+Next on my list is revisiting XMPP.
+
+Verified that git push over XMPP works between multiple repositories that
+are sharing the same XMPP account. It does.
+
+Seeing the XMPP setup process with fresh eyes, I found several places
+wording could be improved. Also, when the user goes in and configures
+(or reconfigures) an XMPP account, the next step is to do pairing,
+so it now redirects directly to there.
+
+Next I need to make XMPP get back into sync after a network disconnection
+or when the assistant is restarted. This currently doesn't happen until
+a XMPP push is received due to a new change being made.
+
+### back burner: yesod-pure
+
+Last night I made a yesod-pure branch, and did some exploratory conversion
+away from using Hamlet, of the Preferences page I built yesterday.
+
+I was actually finding writing pure Blaze worked *better* than Hamlet,
+at first. Was able to refactor several things into functions that in Hamlet
+are duplicated over and over in my templates, and built some stuff that makes
+rendering type safe urls in pure Blaze not particularly ungainly. For example,
+this makes a submit button and a cancel button that redirects to another page:
+
+[[!format haskell """
+ buttons = toWidget $ \redir ->
+ "Save Preferences" <>|<> redir ConfigurationR []
+"""]]
+
+The catch is how to deal with widgets that need to be nested inside other
+html. It's not possible to do this both cleanly and maximally
+efficiently, with Blaze. For max efficiency, all the html before the widget
+should be emitted, and then the widget run, and then all html after it be
+emitted. To use Blaze, it would have to instead generate the full html,
+then split it around the widget, and then emit the parts, which is less
+efficient, doesn't stream, etc.
+
+I guess that's the core of what Hamlet does; it allows a clean
+representation and due to running TH at build time, can convert this into
+an efficient (but ugly) html emitter.
+
+So, I may give up on this experiment. Or I may make the webapp less than
+maximally fast at generating html and go on with it. After all, these
+sorts of optimisations are mostly aimed at high-volume websites, not local
+webapps.
diff --git a/doc/design/assistant/blog/day_205_206__rainy_day__snow_day.mdwn b/doc/design/assistant/blog/day_205_206__rainy_day__snow_day.mdwn
new file mode 100644
index 000000000..e1d07c8e4
--- /dev/null
+++ b/doc/design/assistant/blog/day_205_206__rainy_day__snow_day.mdwn
@@ -0,0 +1,12 @@
+Yesterday was all bug fixes, nothing to write about really.
+
+Today I've been working on getting XMPP remotes to sync more reliably.
+I left some big holes when I stopped work on it in November:
+
+1. The assistant did not sync with XMPP remotes when it started up.
+2. .. Or when it detected a network reconnection.
+3. There was no way to trigger a full scan for transfers
+ after receiving a push from an XMPP remote.
+
+The asynchronous nature of git push over XMPP complicated doing this, but
+I've solved all 3 issues today.
diff --git a/doc/design/assistant/blog/day_207__XMPP.mdwn b/doc/design/assistant/blog/day_207__XMPP.mdwn
new file mode 100644
index 000000000..8419905f1
--- /dev/null
+++ b/doc/design/assistant/blog/day_207__XMPP.mdwn
@@ -0,0 +1,7 @@
+More XMPP fixes. The most important change is that it now stores important
+messages, like push requests, and (re)sends them when a buddy's client
+sends XMPP presence. This makes XMPP syncing much more robust, all the
+clients do not need to already be connected when messages are initially
+sent, but can come and go. Also fixed a bug preventing syncing from working
+immediately after XMPP pairing. XMPP seems to be working well now; I only
+know of one minor bug.
diff --git a/doc/design/assistant/blog/day_208__bugfixes.mdwn b/doc/design/assistant/blog/day_208__bugfixes.mdwn
new file mode 100644
index 000000000..41874b918
--- /dev/null
+++ b/doc/design/assistant/blog/day_208__bugfixes.mdwn
@@ -0,0 +1,17 @@
+Fixed the last XMPP bug I know of. Turns out it was not specific to XMPP at
+all; the assistant could forget to sync with any repository on startup
+under certain conditions.
+
+Also fixed bugs in `git annex add` and in the glob matching, and some more.
+
+I've been working on some screencasts. More on them later.. But while doing
+them I found a perfect way to reliably reproduce the webapp hang that
+I've been chasing for half a year, and last saw at my presentation in
+Australia. Seems the old joke about bugs only reproducible during
+presentations is literally true here!
+
+I have given this bug its [[own page|bugs/webapp_hang]] at last, and have a
+tcpdump of it happening and everything. Am working on an hypotheses that it
+might be caused by Warp's [slowloris](http://ha.ckers.org/slowloris/)
+attack prevention code being falsely triggered by the repeated hits the web
+browser makes as the webapp's display is updated.
diff --git a/doc/design/assistant/blog/day_209__The_Bug.mdwn b/doc/design/assistant/blog/day_209__The_Bug.mdwn
new file mode 100644
index 000000000..b2e87fd8f
--- /dev/null
+++ b/doc/design/assistant/blog/day_209__The_Bug.mdwn
@@ -0,0 +1,23 @@
+> And so we waited. Tick-tock, blink-blink, thirty seconds stretched
+> themselves out one by one, a hole in human experience. -- The Bug
+
+I *think* I've managed to fully track down the [[webapp_hang]]. It is,
+apparently, a bug in the Warp web server's code intended to protect against
+the [Slowloris](http://ha.ckers.org/slowloris/) attack. It assumes,
+incorrectly, that a web browser won't reuse a connection it's left idle for
+30 seconds. Some bad error handling keeps a connection open with no thread
+to service it, leading to the hang.
+<https://github.com/yesodweb/wai/issues/146>
+
+Have put a 30 minute timeout into place as a workaround, and, unless
+a web browser sits on an idle connection for a full 30 minutes and then
+tries to reuse it, this should be sufficient.
+
+I was chasing that bug, quietly, for 6 months. Would see it now and
+then, but not be able to reproduce it or get anywhere with analysis.
+I had nearly given up. If you enjoy stories like that, read Ellen
+Ullman's excellent book The Bug.
+
+> To discover that between the blinks of the machine’s shuttered eye—going
+> on without pause or cease; simulated, imagined, but still not caught—was
+> life.
diff --git a/doc/design/assistant/blog/day_20__data_transfer_design.mdwn b/doc/design/assistant/blog/day_20__data_transfer_design.mdwn
new file mode 100644
index 000000000..4f47ae63c
--- /dev/null
+++ b/doc/design/assistant/blog/day_20__data_transfer_design.mdwn
@@ -0,0 +1,22 @@
+Today is a planning day. I have only a few days left before I'm off to
+Nicaragua for [DebConf](http://debconf12.debconf.org/), where I'll only
+have smaller chunks of time without interruptions. So it's important to get
+some well-defined smallish chunks designed that I can work on later. See
+bulleted action items below (now moved to [[syncing]]. Each
+should be around 1-2 hours unless it turns out to be 8 hours... :)
+
+First, worked on writing down a design, and some data types, for data transfer
+tracking (see [[syncing]] page). Found that writing down these simple data
+types before I started slinging code has clarified things a lot for me.
+
+Most importantly, I realized that I will need to modify `git-annex-shell`
+to record on disk what transfers it's doing, so the assistant can get that
+information and use it to both avoid redundant transfers (potentially a big
+problem!), and later to allow the user to control them using the web app.
+
+While eventually the user will be able to use the web app to prioritize
+transfers, stop and start, throttle, etc, it's important to get the default
+behavior right. So I'm thinking about things like how to prioritize uploads
+vs downloads, when it's appropriate to have multiple downloads running at
+once, etc.
+
diff --git a/doc/design/assistant/blog/day_210__spring.mdwn b/doc/design/assistant/blog/day_210__spring.mdwn
new file mode 100644
index 000000000..ff34cfbfe
--- /dev/null
+++ b/doc/design/assistant/blog/day_210__spring.mdwn
@@ -0,0 +1,29 @@
+Trying to record screencasts demoing the assistant is really helping me
+see things that need to be fixed.
+
+Got the version of the haskell TLS library in Debian fixed, backporting
+some changes to fix a botched security fix that made it reject all
+certificates. So WebDAV special remotes will work again on the next release.
+
+Fixed some more problems around content being dropped when files are
+moved to archive directories, and gotten again when files are
+moved out.
+
+Fixed some problems around USB drives. One was a real jaw-dropping
+bug: "git annex drop --from usbdrive" when the drive was not
+connected still updated the location log to indicate it did not have
+the file anymore! (Thank goodness for fsck..)
+
+I've noticed that moving around files in direct mode repos is inneficient,
+because the assistant re-checksums the "new" file. One way to avoid
+that would be to have a lookup table from (inode, size, mtime) to
+key, but I don't have one, and would like to avoid adding one.
+
+Instead, I have a cunning plan to deal with this heuristically. If the
+assistant can notice a file was removed and another file added at the same
+time, it can compare the (inode, size, mtime) to see if it's a rename, and
+avoid the checksum overhead.
+
+The first step to getting there was to make the assistant better at
+batching together delete+add events into a single rename commit. I'm happy
+to say I've accomplished that, with no perceptable delay to commits.
diff --git a/doc/design/assistant/blog/day_211__zooming_along.mdwn b/doc/design/assistant/blog/day_211__zooming_along.mdwn
new file mode 100644
index 000000000..fb87077be
--- /dev/null
+++ b/doc/design/assistant/blog/day_211__zooming_along.mdwn
@@ -0,0 +1,24 @@
+Got renaming fully optimised in the assistent in direct mode. I even got it
+to work for whole directory renames. I can drag files around all day in the
+file manager and the assistant often finishes committing the rename before
+the file manager updates. So much better than checksumming every single
+renamed file! Also, this means the assistant makes just 1 commit when a
+whole directory is renamed.
+
+Last night I added a feature to `git annex status`. It can now be asked to
+only show the status of a single directory, rather than the whole annex.
+All the regular file filtering switches work, so some neat commands
+are possible. I like `git annex status . --in foo --not --in bar` to see
+how much data is in one remote but not another.
+
+This morning, an important thought about [[bugs/smarter_flood_filling]],
+that will avoid unnecessary uploads to transfer remotes when all that's
+needed to get the file to its destination is a transfer over the LAN.
+I found an easy way to make that work, at least in simple cases.
+Hoping to implement it soon.
+
+Less fun, direct mode turns out to be somewhat buggy when files with
+duplicate content are in the repository. Nothing fails, but `git annex
+sync` will re-checksum files each time it's run in this situation, and the
+assistant will re-checksum files in certian cases. Need to work on this
+soon too.
diff --git a/doc/design/assistant/blog/day_212__accidental_all_nighter.mdwn b/doc/design/assistant/blog/day_212__accidental_all_nighter.mdwn
new file mode 100644
index 000000000..600522d14
--- /dev/null
+++ b/doc/design/assistant/blog/day_212__accidental_all_nighter.mdwn
@@ -0,0 +1,24 @@
+Last night, revamped the web site, including making a [[/videos]]
+page, which includes a new screencast introducing the git-annex assistant.
+
+Worked on improving my Haskell development environment in vim.
+hdevtools is an excellent but tricky thing to get working. Where before
+it took around 30 seconds per compile for me to see type errors,
+I now see them in under a second each time I save, and can also look up
+types of any expression in the file. Since programming in Haskell is
+mostly driven by reacting to type errors ;) this should speed me up a lot,
+although it's not perfect. Unfortunatly, I got really caught up in tuning
+my setup, and only finished doing that at 5:48 am.
+
+Disasterously late this morning, fixed the assistant's
+`~/.ssh/git-annex-shell` wrapper so it will work when the ssh key does
+not force a command to be run. Also made the webapp behave better
+when it's told to create a git repository that already exists.
+
+After entirely too little sleep, I found a puzzling bug where copying files
+to a local repo fails once the inode cache has been invalidated. This
+turned out to involve running a check in the state monad of the wrong
+repository. A failure mode I'd never encountered before.
+
+Only thing I had brains left to do today was to record another screencast,
+which is rendering now...
diff --git a/doc/design/assistant/blog/day_212__accidental_all_nighter/comment_1_6ee1f8056eedb6eb18013faf8f5ec212._comment b/doc/design/assistant/blog/day_212__accidental_all_nighter/comment_1_6ee1f8056eedb6eb18013faf8f5ec212._comment
new file mode 100644
index 000000000..6ad0ab235
--- /dev/null
+++ b/doc/design/assistant/blog/day_212__accidental_all_nighter/comment_1_6ee1f8056eedb6eb18013faf8f5ec212._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl1D_4vD5ueaDw8gRsIYPO3UHRKEpFfg9I"
+ nickname="Дмитрий"
+ subject="About development in Vim"
+ date="2013-03-13T02:18:20Z"
+ content="""
+Could you describe your vim configuration for haskell development, what plugins do you use, what is in you .vimrc file and maybe even record a screencast of typical \"session\" of work?
+"""]]
diff --git a/doc/design/assistant/blog/day_212__accidental_all_nighter/comment_2_07c83d75bb105bb77ada07359ed0ea7a._comment b/doc/design/assistant/blog/day_212__accidental_all_nighter/comment_2_07c83d75bb105bb77ada07359ed0ea7a._comment
new file mode 100644
index 000000000..06aae6e1b
--- /dev/null
+++ b/doc/design/assistant/blog/day_212__accidental_all_nighter/comment_2_07c83d75bb105bb77ada07359ed0ea7a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmU_2tE75oyG0h2ZPN4lcroIKEMC8G-otE"
+ nickname="Michael"
+ subject="Global preferences?"
+ date="2013-03-13T08:00:55Z"
+ content="""
+I just did a \"cabal install git-annex --bindir=$HOME/bin\" on Ubuntu 12.10 and I don't see the global preferences (where you configure the autostart etc.) from the screencast. How can I enable this?
+"""]]
diff --git a/doc/design/assistant/blog/day_212__accidental_all_nighter/comment_3_2c904d33f4f14807fbe718a01e98800a._comment b/doc/design/assistant/blog/day_212__accidental_all_nighter/comment_3_2c904d33f4f14807fbe718a01e98800a._comment
new file mode 100644
index 000000000..943bd5277
--- /dev/null
+++ b/doc/design/assistant/blog/day_212__accidental_all_nighter/comment_3_2c904d33f4f14807fbe718a01e98800a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-03-13T16:08:35Z"
+ content="""
+The global preferences page is a new feature that will be in the next release. You can use a daily build or build from source to try it now.
+"""]]
diff --git a/doc/design/assistant/blog/day_212__accidental_all_nighter/comment_4_59ec5c1cab75df87293800a7a03fe9c6._comment b/doc/design/assistant/blog/day_212__accidental_all_nighter/comment_4_59ec5c1cab75df87293800a7a03fe9c6._comment
new file mode 100644
index 000000000..c3e8f8351
--- /dev/null
+++ b/doc/design/assistant/blog/day_212__accidental_all_nighter/comment_4_59ec5c1cab75df87293800a7a03fe9c6._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmU_2tE75oyG0h2ZPN4lcroIKEMC8G-otE"
+ nickname="Michael"
+ subject="comment 4"
+ date="2013-03-13T16:34:46Z"
+ content="""
+Build from source is too hard for a non-haskell developer, I run into various errors I can not resolve. The daily build gives me \"git-annex: error while loading shared libraries: libyaml-0.so.2: cannot open shared object file: No such file or directory\". For Ubuntu a PPA with daily build would be handy.
+"""]]
diff --git a/doc/design/assistant/blog/day_212__accidental_all_nighter/comment_5_13893f106e835dcc52e03c7c6740c35b._comment b/doc/design/assistant/blog/day_212__accidental_all_nighter/comment_5_13893f106e835dcc52e03c7c6740c35b._comment
new file mode 100644
index 000000000..8c6419b1c
--- /dev/null
+++ b/doc/design/assistant/blog/day_212__accidental_all_nighter/comment_5_13893f106e835dcc52e03c7c6740c35b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 5"
+ date="2013-03-13T16:58:04Z"
+ content="""
+In the standalone linux daily build, you need to use the \"runshell\" script to start a shell environment in which you can run git-annex.
+"""]]
diff --git a/doc/design/assistant/blog/day_213__costs.mdwn b/doc/design/assistant/blog/day_213__costs.mdwn
new file mode 100644
index 000000000..41517a7ab
--- /dev/null
+++ b/doc/design/assistant/blog/day_213__costs.mdwn
@@ -0,0 +1,34 @@
+Got the assistant to check again, just before starting a transfer, if
+the remote still wants the object. This should be all that's needed to
+handle the case where there is a transfer remote on the internet somewhere,
+and a locally paired client on the LAN. As long as the paired repository
+has a lower cost value, it will be sent any new file first, and if that
+is the only client, the file will not be sent to the transfer remote at
+all.
+
+But.. locally paired repos did not have a lower cost set, at all.
+So I made their cost be set to 175 when they're created. Anyone
+who already did local pairing should make sure the Repositories
+list shows locally paired repositories above transfer remotes.
+
+Which brought me to needing an easy way to reorder that list of remotes,
+which I plan to do by letting the user drag and drop remotes around,
+which will change their cost accordingly. Implementing that has two
+pain points:
+
+1. Often a lot of remotes will have the same default cost value.
+ So how to insert a remote in between two that have cost 100?
+ This would be easy if git-annex didn't have these cost numbers,
+ and instead just had an ordered list of remotes.. but it doesn't.
+ Instead, dragging remotes in the list will sometimes need to change
+ the costs of others, to make room to insert them in. It's BASIC
+ renumbering all over again. So I wrote some code to do this with as
+ little bother as possible.
+
+2. Drag and drop means javascript. I got the basics going quickly with
+ jquery-ui, only to get stuck for over an hour on some CSS issue
+ that made lines from the list display all weird while being dragged.
+ It is always something like this with javascript..
+
+So I've got these 2 peices working, and even have the AJAX call
+firing, but it's not quite wired up just yet. Tomorrow.
diff --git a/doc/design/assistant/blog/day_214__release_day.mdwn b/doc/design/assistant/blog/day_214__release_day.mdwn
new file mode 100644
index 000000000..2ada21308
--- /dev/null
+++ b/doc/design/assistant/blog/day_214__release_day.mdwn
@@ -0,0 +1,5 @@
+Fighting with javascript all day and racing to get a release out. Unstuck
+the OSX and Android autobuilders. Got drag and drop repository list
+reordering working great. Tons of changes in this release!
+
+Also put up a new podcast.
diff --git a/doc/design/assistant/blog/day_215__dashboard_UI_refresh.mdwn b/doc/design/assistant/blog/day_215__dashboard_UI_refresh.mdwn
new file mode 100644
index 000000000..9381ebee2
--- /dev/null
+++ b/doc/design/assistant/blog/day_215__dashboard_UI_refresh.mdwn
@@ -0,0 +1,25 @@
+I've reworked the UI of the webapp's dashboard. Now the repository list is
+included, above the transfers. I found I was spending a lot of time
+switching between the dashboard and repository list, so might as well
+combine them into a single screen. Yesod's type safe urls and widgets
+made this quite easy to do, despite it being a thousand line commit.
+Liking the result ... Even though it does make all my screencasts dated.
+
+[[!img /assistant/dashboard.png]]
+
+----
+
+Rest of my time was spent on XMPP pairing UI. Using the same pages for both
+pairing with a friend and for self-pairing was confusing, so now the two
+options are split.
+
+Now every time an XMPP git push is received or sent, it checks if there's
+a cloud repository configured, which is needed to send the contents of
+files. If not, it'll display this alert. Hopefully this
+will be enough to get users fully set up.
+
+[[!img /assistant/cloudnudge.png]]
+
+At this point I'm finally happy enough with the XMPP pairing + cloud
+repository setup process to film a screencast of it. As soon as I have
+some time & bandwidth someplace quiet. Expect one by the end of the month.
diff --git a/doc/design/assistant/blog/day_216__more_bugfixes.mdwn b/doc/design/assistant/blog/day_216__more_bugfixes.mdwn
new file mode 100644
index 000000000..a988643ff
--- /dev/null
+++ b/doc/design/assistant/blog/day_216__more_bugfixes.mdwn
@@ -0,0 +1,42 @@
+A long time ago I made Remote be an instance of the Ord typeclass, with an
+implementation that compared the costs of Remotes. That seemed like a good
+idea at the time, as it saved typing.. But at the time I was still making
+custom Read and Show instances too. I've since learned that this is *not* a
+good idea, and neither is making custom Ord instances, without deep thought
+about the possible sets of values in a type.
+
+This Ord instance came around and bit me when I put Remotes into a Set,
+because now remotes with the same cost appeared to be in the Set even if
+they were not. Also affected putting Remotes into a Map. I noticed this
+when the webapp got confused about which Remotes were paused.
+
+Rarely does a bug go this deep. I've fixed it comprehensively, first
+removing the Ord instance entirely, and fixing the places that wanted to
+order remotes by cost to do it explicitly. Then adding back an Ord instance
+that is much more sane. Also by checking the rest of the Ord (and Eq)
+instances in the code base (which were all ok).
+
+While doing that, I found lots of places that kept remotes in Maps and
+Sets. All of it was probably subtly broken in one way or another before
+this fix, but it would be hard to say exactly how the bugs would
+manifest.
+
+-----
+
+Also fought some with Google Talk today. Seem to be missing presence
+messages sometimes. Ugh. May have fixed it, but I've thought that before..
+
+Made --debug include a sanitized dump of the XMPP protocol.
+
+Made UI changes to encourage user to install git-annex on the server when
+adding a ssh server, rather than just funneling them through to rsync.
+
+Fixed UI glitches in XMPP username/password prompt.
+
+Switched all forms in the webapp to use POST, to avoid sensitive
+information leaking on the url bar.
+
+----
+
+Added an incremental backup group. Repositories in this group only want
+files that have not been backed up somewhere else yet.
diff --git a/doc/design/assistant/blog/day_216__more_bugfixes/comment_1_299462bcdd0e4f6cd7895b5f40ca00ad._comment b/doc/design/assistant/blog/day_216__more_bugfixes/comment_1_299462bcdd0e4f6cd7895b5f40ca00ad._comment
new file mode 100644
index 000000000..7d28cfdbf
--- /dev/null
+++ b/doc/design/assistant/blog/day_216__more_bugfixes/comment_1_299462bcdd0e4f6cd7895b5f40ca00ad._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnR7hb8IaKB3IKZptRukje0yahmhfLOO98"
+ nickname="Adam"
+ subject="comment 1"
+ date="2013-03-17T00:30:26Z"
+ content="""
+> Made UI changes to encourage user to install git-annex on the server when adding a ssh server, rather than just funneling them through to rsync.
+
+What's the difference between having git-annex available versus not?
+"""]]
diff --git a/doc/design/assistant/blog/day_216__more_bugfixes/comment_2_1913d65dfe4ba08379d82a4a2ca91c40._comment b/doc/design/assistant/blog/day_216__more_bugfixes/comment_2_1913d65dfe4ba08379d82a4a2ca91c40._comment
new file mode 100644
index 000000000..200846545
--- /dev/null
+++ b/doc/design/assistant/blog/day_216__more_bugfixes/comment_2_1913d65dfe4ba08379d82a4a2ca91c40._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnxp2XU8gIribhhGhGuYtU6eMMwHv5gUGI"
+ nickname="Amitai"
+ subject="Google Talk silently drops non-Google invites (at least)"
+ date="2013-03-17T13:44:18Z"
+ content="""
+Have you seen <http://www.fsf.org/blogs/sysadmin/google-backslides-on-federated-instant-messaging-on-purpose>? Maybe they're also doing other funny stuff that gets in your way.
+"""]]
diff --git a/doc/design/assistant/blog/day_216__more_bugfixes/comment_3_92c774599a78540ad398afcd1d05f7ce._comment b/doc/design/assistant/blog/day_216__more_bugfixes/comment_3_92c774599a78540ad398afcd1d05f7ce._comment
new file mode 100644
index 000000000..05847a73b
--- /dev/null
+++ b/doc/design/assistant/blog/day_216__more_bugfixes/comment_3_92c774599a78540ad398afcd1d05f7ce._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnR7hb8IaKB3IKZptRukje0yahmhfLOO98"
+ nickname="Adam"
+ subject="comment 3"
+ date="2013-03-25T01:58:23Z"
+ content="""
+About the UI prompt for the webapp:
+
+> What's the difference between having git-annex available versus not?
+
+I can see from the UI that if you make it be a git repository, you get this:
+
+> All your data will be uploaded to the server, including the full git repository. This is a great choice if you want to set up other devices to use the same server, or share the repository with others.
+
+Versus an rsync repo:
+
+> The contents of your files will be stored, fully encrypted, on the server. The server will not store other information about your git repository. This is the best choice if you don't run the server yourself, or have sensitive data.
+
+Unfortunately I'm looking for a shared server (as per the git repo description), but **also fully encrypted** because I'll be storing sensitive data.
+"""]]
diff --git a/doc/design/assistant/blog/day_217__nothing.mdwn b/doc/design/assistant/blog/day_217__nothing.mdwn
new file mode 100644
index 000000000..95deabd23
--- /dev/null
+++ b/doc/design/assistant/blog/day_217__nothing.mdwn
@@ -0,0 +1,2 @@
+Is what I planned to do on git-annex today. Instead I fixed several bugs,
+but I'm drawing the line at blogging. Oops.
diff --git a/doc/design/assistant/blog/day_219__bug_triage.mdwn b/doc/design/assistant/blog/day_219__bug_triage.mdwn
new file mode 100644
index 000000000..82494ceca
--- /dev/null
+++ b/doc/design/assistant/blog/day_219__bug_triage.mdwn
@@ -0,0 +1,14 @@
+Triaged some of the older bugs and was able to close a lot of them.
+
+-----
+
+Should mention that I will be in Boston this weekend, attending
+[LibrePlanet 2013](http://libreplanet.org/wiki/LibrePlanet:Conference/2013).
+Drop by and find me, I'll have git-annex stickers! ;)
+
+-----
+
+Did some UI work on the webapp. Minor stuff, but stuff that needed to be
+fixed up. Like inserting zero-width spaces into filenames displayed in it
+so very long filenames always get reasonably wrapped by the browser.
+(Perhaps there's a better way to do that with CSS?)
diff --git a/doc/design/assistant/blog/day_219__bug_triage/comment_1_c6b977a969cacdce62987a439b7686f5._comment b/doc/design/assistant/blog/day_219__bug_triage/comment_1_c6b977a969cacdce62987a439b7686f5._comment
new file mode 100644
index 000000000..5722f7e19
--- /dev/null
+++ b/doc/design/assistant/blog/day_219__bug_triage/comment_1_c6b977a969cacdce62987a439b7686f5._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://jasonwoof.com/"
+ nickname="JasonWoof"
+ subject="wrapping css"
+ date="2013-03-20T20:28:04Z"
+ content="""
+You can do this in css:
+
+ word-wrap: break-word;
+
+That should make the text not leave the box. Not sure if this makes it break \"reasonably\" though, eg a two letter word followed by an 200 letter \"word\" would probably leave the two letter word on a line by itself.
+
+Worth a try though.
+
+Seems to be well supported on browsers: [http://caniuse.com/#search=wrap](http://caniuse.com/#search=wrap)
+"""]]
diff --git a/doc/design/assistant/blog/day_21__transfer_tracking.mdwn b/doc/design/assistant/blog/day_21__transfer_tracking.mdwn
new file mode 100644
index 000000000..79c0b6438
--- /dev/null
+++ b/doc/design/assistant/blog/day_21__transfer_tracking.mdwn
@@ -0,0 +1,28 @@
+Worked today on two action items from my last blog post:
+
+* on-disk transfers in progress information files (read/write/enumerate)
+* locking for the files, so redundant transfer races can be detected,
+ and failed transfers noticed
+
+That's all done, and used by the `get`, `copy`, and `move` subcommands.
+
+Also, I made `git-annex status` use that information to display any
+file transfers that are currently in progress:
+
+ joey@gnu:~/lib/sound/misc>git annex status
+ [...]
+ transfers in progress:
+ downloading Vic-303.mp3 from leech
+
+(Webapp, here we come!)
+
+However... Files being sent or received by `git-annex-shell` don't yet
+have this transfer info recorded. The problem is that to do so,
+`git-annex-shell` will need to be run with a `--remote=` parameter. But
+old versions will of course fail when run with such an unknown parameter.
+
+This is a problem I last faced in December 2011 when adding the `--uuid=`
+parameter. That time I punted and required the remote `git-annex-shell` be
+updated to a new enough version to accept it. But as git-annex gets more widely
+used and packaged, that's becoming less an option. I need to find a real
+solution to this problem.
diff --git a/doc/design/assistant/blog/day_220__performance.mdwn b/doc/design/assistant/blog/day_220__performance.mdwn
new file mode 100644
index 000000000..a1b7b329a
--- /dev/null
+++ b/doc/design/assistant/blog/day_220__performance.mdwn
@@ -0,0 +1,40 @@
+I've been running some large transfers with the assistant, and looking at
+ways to improve performance. (I also found and fixed a zombie process
+leak.)
+
+----
+
+One thing I noticed is that the assistant pushes changes to the git-annex
+location log quite frequently during a batch transfer. If the files being
+transferred are reasonably sized, it'll be pushing once per file transfer.
+It would be good to reduce the number of pushes, but the pushes are
+important in some network topologies to inform other nodes
+when a file gets near to them, so they can get the file too.
+
+Need to see if I can find a smart way to avoid some of the pushes.
+For example, if we've just downloaded a file, and are queuing uploads
+of the file to a remote, we probably don't need to push the git-annex
+branch to the remote.
+
+----
+
+Another performance problem is that having the webapp open while transfers
+are running uses significant CPU just for the browser to update the progress
+bar. Unsurprising, since the webapp is sending the browser a new `<div>`
+each time. Updating the DOM instead from javascript would avoid that;
+the webapp just needs to send the javascript either a full `<div>` or a
+changed percentage and quantity complete to update a single progress bar.
+
+I'd prefer to wait on doing that until I'm able to use Fay to generate
+Javascript from Haskell, because it would be much more pleasant.. will see.
+
+----
+
+Also a performance problem when performing lots of transfers, particularly
+of small files, is that the assistant forks off a `git annex transferkey`
+for each transfer, and that has to in turn start up several git commands.
+
+Today I have been working to change that, so the assistant maintains a
+pool of transfer processes, and dispatches each transfer it wants to make
+to a process from the pool. I just got all that to build, although untested
+so far, in the `transferpools` branch.
diff --git a/doc/design/assistant/blog/day_221__this_and_that.mdwn b/doc/design/assistant/blog/day_221__this_and_that.mdwn
new file mode 100644
index 000000000..87406547e
--- /dev/null
+++ b/doc/design/assistant/blog/day_221__this_and_that.mdwn
@@ -0,0 +1,28 @@
+Was unsure yesterday if my transferrer pools code would just work, or
+would be horribly broken and need a lot of work to get going. It was a
+complex change involving both high-level STM code and low-level pipes and
+fds. Well, it almost worked 100% first time, I just had a minor issue in
+my fd setup to fix. Everything else seems to work perfectly.
+Very happy how that went!
+
+----
+
+Improved support and documentation for using the OSX app and Linux
+standalone tarball at the command line. Now it's sufficient to just put
+their directory into `PATH`, rather than using `runshell`.
+
+----
+
+The webapp's form for adding a removable drive now allows specifying the
+directory to use within the drive (default "annex").
+
+When the drive's repository already exists, and it's not a repository
+that git-annex knows about, it confirms that the user wants
+to combine its contents into their repository.
+
+
+(Should probably implement this same check when adding a ssh remote.)
+
+----
+
+Off to Boston!
diff --git a/doc/design/assistant/blog/day_222__back.mdwn b/doc/design/assistant/blog/day_222__back.mdwn
new file mode 100644
index 000000000..9c3c17094
--- /dev/null
+++ b/doc/design/assistant/blog/day_222__back.mdwn
@@ -0,0 +1,16 @@
+Back from my trip. Spent today getting caught up.
+
+Didn't do much while I was away. Pushed out a new release on Saturday.
+Made `git annex` usage display nicer.
+
+Fixed some minor webapp bugs today. The interesting bug was a
+race that sometimes caused alerts or other notifications to be
+missed and not be immediately displayed if they occurred while
+a page was loading. You sometimes had to hit reload to see them,
+but not anymore!
+
+Checked if the `push.default=simple` change in upcoming git release will
+affect git-annex. It shouldn't affect the assistant, or `git annex sync`,
+since they always list all branches to push explicitly. But if you `git push`
+manually, when the default changes that won't include the git-annex branch
+in the push any longer.
diff --git a/doc/design/assistant/blog/day_222__back/comment_1_f05b48231a1ee0cffba7d66e112e5551._comment b/doc/design/assistant/blog/day_222__back/comment_1_f05b48231a1ee0cffba7d66e112e5551._comment
new file mode 100644
index 000000000..f788cc283
--- /dev/null
+++ b/doc/design/assistant/blog/day_222__back/comment_1_f05b48231a1ee0cffba7d66e112e5551._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm7AuSfii_tCkLyspL6Mr0ATlO6OxLNYOo"
+ nickname="Georg"
+ subject="something for the wishlist maybe?"
+ date="2013-03-28T08:30:00Z"
+ content="""
+Something I was wondering with the assistant now getting really smart: would it be possible to have a cli-mode for the assistant that runs in the forground and only until there is nothing to do anymore? Something like a single-run-assistant`? Reason being that in my usecases most often I know exactly when the right moment for a run is - for example after processing a bunch of photographs - and I most definitely don't want a background process to work on those photographs while I do work on them. Or with archival media, I know when I will hook up the archive drives. In allmost all of my scenarios it would be much easier to not run the assistant in the background, but to fire it from the cli at the right moments, letting it work over night and have it shut down automatically when all is synced.
+"""]]
diff --git a/doc/design/assistant/blog/day_222__back/comment_2_4d5f003ccd81580017ebf0dc31bc9cda._comment b/doc/design/assistant/blog/day_222__back/comment_2_4d5f003ccd81580017ebf0dc31bc9cda._comment
new file mode 100644
index 000000000..cc28d5608
--- /dev/null
+++ b/doc/design/assistant/blog/day_222__back/comment_2_4d5f003ccd81580017ebf0dc31bc9cda._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-03-28T15:50:47Z"
+ content="""
+That's an interesting thought. I think it would be hard to find a clear condition when it was done and could shut down. While there is easy visibility into the transfer queue to tell when file transfers are done, it's harder to tell when it's actively syncing git repositories or scanning for transfers to do, or finding new files to commit. Each thread knows what it's doing, but none of the other threads do. Maybe active threads could hold a lock to indicate they're busy, and this combined with visibility into the various work queues could do the job.
+"""]]
diff --git a/doc/design/assistant/blog/day_223__progress_revisited.mdwn b/doc/design/assistant/blog/day_223__progress_revisited.mdwn
new file mode 100644
index 000000000..9f899899d
--- /dev/null
+++ b/doc/design/assistant/blog/day_223__progress_revisited.mdwn
@@ -0,0 +1,24 @@
+Went out and tried for the second time to record a screencast demoing
+setting up syncing between two computers using just Jabber and a cloud
+remote. I can't record this one at home, or viewers would think git-annex
+was crazy slow, when it's just my dialup. ;) But once again I encountered
+bugs, and so I found myself working on progress bars today, unexpectedly.
+
+Seems there was confusion in different parts of the progress bar code
+about whether an update contained the total number of bytes transferred, or
+the delta of bytes transferred since the last update. One way this bug
+showed up was progress bars that seemed to stick at 0% for a long time.
+Happened for most special remotes, although not for rsync or git remotes.
+In order to fix it comprehensively, I added a new BytesProcessed data type,
+that is explicitly a total quantity of bytes, not a delta. And checked and
+fixed all the places that used a delta as that type was knitted into
+the code.
+
+(Note that this doesn't necessarily fix every problem with progress bars.
+Particularly, buffering can now cause progress bars to seem to run ahead
+of transfers, reaching 100% when data is still being uploaded. Still,
+they should be a lot better than before.)
+
+I've just successfully run through the Jabber + Cloud remote setup process
+again, and it seems to be working great now. Maybe I'll still get the
+screencast recorded by the end of March.
diff --git a/doc/design/assistant/blog/day_224__annex.largefiles.mdwn b/doc/design/assistant/blog/day_224__annex.largefiles.mdwn
new file mode 100644
index 000000000..4fab93fb6
--- /dev/null
+++ b/doc/design/assistant/blog/day_224__annex.largefiles.mdwn
@@ -0,0 +1,23 @@
+Built a feature for power users today. `annex.largefiles` can be
+configured to specify what files `git annex add` and the assistant should
+put into the annex. It uses the same syntax as [[/preferred_content]],
+so arbitrarily complex expressions can be built.
+
+For example, a game written in C with some large data files could
+include only 100kb or larger files, that are not C code:
+
+ annex.largefiles = largerthan=100kb and not (include=*.c or include=*.h)
+
+The assistant will commit small files to git directly!
+`git annex add`, being a lower level tool, skips small files
+and leaves it up to you to `git add` them as desired.
+
+It's even possible to tell the assistant that no file is too large to be
+committed directly to git. `git config annex.largefiles 'exclude=*'`
+The result should be much like using SparkleShare or dvcs-autosync.
+
+-----
+
+Also today, made the remote ssh server checking code in the webapp
+deal with servers where the default shell is csh or some other non-POSIX
+shell.
diff --git a/doc/design/assistant/blog/day_224__annex.largefiles/comment_1_408e4021b18f7ff5548d2d19ab558922._comment b/doc/design/assistant/blog/day_224__annex.largefiles/comment_1_408e4021b18f7ff5548d2d19ab558922._comment
new file mode 100644
index 000000000..370f599c2
--- /dev/null
+++ b/doc/design/assistant/blog/day_224__annex.largefiles/comment_1_408e4021b18f7ff5548d2d19ab558922._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm7AuSfii_tCkLyspL6Mr0ATlO6OxLNYOo"
+ nickname="Georg"
+ subject="Great idea! "
+ date="2013-03-30T08:00:16Z"
+ content="""
+This will be perfect for my raw image pool! I use Lightroom, so my photos are only imported once and only in case of DNG are they actually changed, in all other formats LR creates little sidecar XML files with processing instructions. So with this change the side car files can actually be fully Versionen and lage files are kept out of the repo and handled by archiving with annex. Cool!
+"""]]
diff --git a/doc/design/assistant/blog/day_224__annex.largefiles/comment_2_b24d1da2bc4307ded0216daffb8f9336._comment b/doc/design/assistant/blog/day_224__annex.largefiles/comment_2_b24d1da2bc4307ded0216daffb8f9336._comment
new file mode 100644
index 000000000..14fdfed5c
--- /dev/null
+++ b/doc/design/assistant/blog/day_224__annex.largefiles/comment_2_b24d1da2bc4307ded0216daffb8f9336._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmWBvsZvSsAL8P2ye3F0OBStjFCVnOImzM"
+ nickname="Jarno"
+ subject="Making &quot;git-annex add&quot; commit largefiles, too?"
+ date="2013-10-31T00:26:21Z"
+ content="""
+Is it possible to make `git annex add` also *not* skip largefiles but do an automatic `git add` instead? I'd like to keep .txt, .sh and the like in git directly (for easier diffing) but having to add them separately sounds like trouble.
+"""]]
diff --git a/doc/design/assistant/blog/day_225__back_from_the_dead.mdwn b/doc/design/assistant/blog/day_225__back_from_the_dead.mdwn
new file mode 100644
index 000000000..e550c6b8b
--- /dev/null
+++ b/doc/design/assistant/blog/day_225__back_from_the_dead.mdwn
@@ -0,0 +1,47 @@
+I've posted a poll: [[polls/goals_for_April]]
+
+----
+
+Today added UI to the webapp to delete repositories, which many
+users have requested. It can delete the local repository,
+with appropriate cautions and sanity checks:
+
+[[!img /assistant/deleterepository.png]]
+
+More likely, you'll use it to remove a remote, which is done with no muss
+and no fuss, since that doesn't delete any data and the remote can always
+be added back if you change your mind.
+
+It also has an option to fully delete the data on a remote. This doesn't
+actually delete the remote right away. All it does is marks the remote
+as untrusted[1], and configures it to not want any content.
+This causes all the content on it to be sucked off to whatever
+other repositories can hold it.
+
+I had to adjust the preferred content expressions to make that work. For
+example, when deleting an archive drive, your local (client) repository
+does not normally want to hold all the data it has in "archive"
+directories. With the adjusted preferred content expressions, any data on
+an untrusted or dead repository is wanted. An interesting result is that
+once a client repository has moved content from an untrusted remote, it
+will decide it doesn't want it anymore, and shove it out to any other
+remote that will accept it. Which is just the behavior we want. All it took
+to get all this behavior is adding "or (not copies=semitrusted:1)" to the
+preferred content expressions!
+
+For most special remotes, just sucking the data from them is sufficient to
+pretty well delete them. You'd want to delete an Amazon bucket or glacier
+once it's empty, and git repositories need to be fully deleted. Since this
+would need unique code for each type of special remote, and it would be
+code that a) deletes possibly large quantities of data with no real way to
+sanity check it and b) doesn't get run and tested very often; it's not
+something I'm thrilled about fully automating. However, I would like to
+make the assistant detect when all the content has been sucked out of a
+remote, and pop up at least a message prompting to finish the deletion.
+Future work.
+
+-----
+
+[1] I really, really wanted to mark it dead, but letting puns drive code
+is probably a bad idea. I had no idea I'd get here when I started
+developing this feature this morning.. Honest!
diff --git a/doc/design/assistant/blog/day_225__back_from_the_dead/comment_1_9ac37c3b5c4c72ec8a39dce00bcbe420._comment b/doc/design/assistant/blog/day_225__back_from_the_dead/comment_1_9ac37c3b5c4c72ec8a39dce00bcbe420._comment
new file mode 100644
index 000000000..325eff30c
--- /dev/null
+++ b/doc/design/assistant/blog/day_225__back_from_the_dead/comment_1_9ac37c3b5c4c72ec8a39dce00bcbe420._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="andy"
+ ip="99.65.214.16"
+ subject="Just wondering what I'm missing..."
+ date="2013-04-02T21:43:33Z"
+ content="""
+I haven't played around with the preferred content expressions, but what is is that keeps \"or (not copies=semitrusted:1)\" from grabbing all the content from trusted repositories, as well as untrusted or dead ones?
+"""]]
diff --git a/doc/design/assistant/blog/day_225__back_from_the_dead/comment_2_26125dd9ef2bd10b597d14b2c6180952._comment b/doc/design/assistant/blog/day_225__back_from_the_dead/comment_2_26125dd9ef2bd10b597d14b2c6180952._comment
new file mode 100644
index 000000000..384d20f31
--- /dev/null
+++ b/doc/design/assistant/blog/day_225__back_from_the_dead/comment_2_26125dd9ef2bd10b597d14b2c6180952._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-04-03T03:42:40Z"
+ content="""
+That's some seriously sharp eyes, Andy. Nothing. I forgot it didn't work that way. Now it uses semitrusted+:1 which works the right way.
+"""]]
diff --git a/doc/design/assistant/blog/day_226__poll_results.mdwn b/doc/design/assistant/blog/day_226__poll_results.mdwn
new file mode 100644
index 000000000..e79ff2585
--- /dev/null
+++ b/doc/design/assistant/blog/day_226__poll_results.mdwn
@@ -0,0 +1,28 @@
+Both the assistant and `git annex drop --auto` refused to drop files from
+untrusted repositories. Got that fixed.
+
+Finally recorded the xmpp pairing screencast. In one perfect take, which
+somehow `recordmydesktop` lost the last 3 minutes of.
+Argh! Anyway I'm editing it now, so, look for that screencast soon.
+
+The [[polls/goals_for_April]] poll results are in.
+
+* There have been no votes at all for working on
+ cloud remotes. Seems that git-annex supports enough cloud remotes already.
+* A lot of people want the Android webapp port to be done, so I will
+ probably spend some time on that this month.
+* Interest in other various features is split. I am surprised how many
+ want git-remote-gcrypt, compared to the features that would make
+ syncing use less bandwidth. Doesn't git push over xmpp cover most
+ of the use cases where git-remote-gcrypt would need to be used with the
+ assistant?
+* Nearly as many people as want features, want me to work on bug
+ fixing and polishing what's already there.
+ So I should probably continue to make screencasts, since they often force
+ me to look at things with fresh eyes and see and fix problems. And of course,
+ continue working on bugs as they're reported.
+* I'm not sure what to make of the 10% who want me to add direct mode support.
+ Since direct mode is already used by default, perhaps they want
+ me to take time off? :) (I certainly need to fix the
+ [[bugs/Direct_mode_keeps_re-checksuming_duplicated_files]] bug, and one other
+ direct mode bug I discovered yesterday.)
diff --git a/doc/design/assistant/blog/day_226__poll_results/comment_1_1ed980472214be6d0a8cf55f37797fda._comment b/doc/design/assistant/blog/day_226__poll_results/comment_1_1ed980472214be6d0a8cf55f37797fda._comment
new file mode 100644
index 000000000..f936e68ed
--- /dev/null
+++ b/doc/design/assistant/blog/day_226__poll_results/comment_1_1ed980472214be6d0a8cf55f37797fda._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://dzsino.myopenid.com/"
+ nickname="dzsino"
+ subject="I've voted for git-remote-gcrypt because.."
+ date="2013-04-02T09:07:23Z"
+ content="""
+... as important a Windows port seems for git-annex to really take off (IMO), I would welcome encrypted repos for storing stuff on external drives: directory special remotes feel kinda cumbersome for me, I would rather use full blown repos.
+"""]]
diff --git a/doc/design/assistant/blog/day_226__poll_results/comment_2_6823b0a9a8037f1a5214db4db98fb16e._comment b/doc/design/assistant/blog/day_226__poll_results/comment_2_6823b0a9a8037f1a5214db4db98fb16e._comment
new file mode 100644
index 000000000..c6e65adf2
--- /dev/null
+++ b/doc/design/assistant/blog/day_226__poll_results/comment_2_6823b0a9a8037f1a5214db4db98fb16e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-04-02T21:36:50Z"
+ content="""
+Thanks for reminding me about that use case. I have created a page [[encrypted_git_remotes]] for this.
+"""]]
diff --git a/doc/design/assistant/blog/day_227__bigfixing_all_day_today.mdwn b/doc/design/assistant/blog/day_227__bigfixing_all_day_today.mdwn
new file mode 100644
index 000000000..74e9fd82f
--- /dev/null
+++ b/doc/design/assistant/blog/day_227__bigfixing_all_day_today.mdwn
@@ -0,0 +1,21 @@
+The [[xmpp screencast|videos/git-annex_assistant_remote_sharing]]
+is at long last done!
+
+----
+
+Fixed a bug that could cause the assistant to unstage files
+from git sometimes. This happened because of a bad optimisation; adding a
+file when it's already present and unchanged was optimised to do nothing.
+But if the file had just been removed, and was put back, this resulted
+in the removal being staged, and the add not being staged. Ugly bug,
+although the assistant's daily sanity check automatically restaged the
+files.
+
+Underlying that bug was a more important problem: git-annex does not always
+update working tree files atomically. So a crash at just the wrong instant
+could cause a file to be deleted from the working tree. I fixed that too;
+all changes to files in the working tree should now be staged in a temp
+file, which is renamed into place atomically.
+
+Also made a bunch of improvements to the dashboard's transfer display, and
+to the handling of the underlying transfer queue.
diff --git a/doc/design/assistant/blog/day_228__more_work_on_repository_removals.mdwn b/doc/design/assistant/blog/day_228__more_work_on_repository_removals.mdwn
new file mode 100644
index 000000000..f8b450216
--- /dev/null
+++ b/doc/design/assistant/blog/day_228__more_work_on_repository_removals.mdwn
@@ -0,0 +1,27 @@
+Getting back to the repository removal handling from Sunday, I made the
+assistant detect when a repository that has been marked as unwanted becomes
+empty, and finish the removal process.
+
+I was able to add this to the expensive transfer scan without making it any
+more expensive than it already was, since that scan already looks at the
+location of all keys. Although when a remote is detected as empty, it then
+does one more check, equivilant to `git annex unused`, to find any
+remaining objects on the remote, and force them off.
+
+I think this should work pretty well, but it needs some testing and
+probably some UI work.
+
+----
+
+Andy spotted a bug in the preferred content expressions I was using to
+handle untrusted remotes. So he saved me several hours dealing with an ugly
+bug at some point down the line. I had misread my own preferred content
+expression documentation, and `copies=semitrusted:1` was not doing what I
+thought it was. Added a new syntax that does what I need,
+`copies=semitrusted+:1`
+
+----
+
+The 64 bit linux standalone builds are back. Apparently the 32 bit builds
+have stopped working on recent Fedora, for reasons that are unclear. I set
+up an autobuilder to produce the 64 bit builds.
diff --git a/doc/design/assistant/blog/day_229__rainy_day_bugfixes.mdwn b/doc/design/assistant/blog/day_229__rainy_day_bugfixes.mdwn
new file mode 100644
index 000000000..87611a97d
--- /dev/null
+++ b/doc/design/assistant/blog/day_229__rainy_day_bugfixes.mdwn
@@ -0,0 +1,17 @@
+Got caught up on bug reports and made some bug fixes.
+
+The one bug I was really worried about, a strange file corruption problem
+on Android, turned out not to be a bug in git-annex. (Nor is it a bug that
+will affect regular users.)
+
+The only interesting bug fixed was a mixed case hash directory name
+collision when a repository is put on a VFAT filesystem (or other
+filesystem with similar semantics). I was able to fix that nicely; since
+such a repository will be in crippled filesystem mode due to other
+limitations of the filesystem, and so won't be using symlinks,
+it doesn't need to use the mixed case hash directory names.
+
+Last night, finished up the repository removal code, and associated UI
+tweaks. It works very well.
+
+Will probably make a release tomorrow.
diff --git a/doc/design/assistant/blog/day_22__horrible_option_parsing_hack.mdwn b/doc/design/assistant/blog/day_22__horrible_option_parsing_hack.mdwn
new file mode 100644
index 000000000..8f6708e59
--- /dev/null
+++ b/doc/design/assistant/blog/day_22__horrible_option_parsing_hack.mdwn
@@ -0,0 +1,34 @@
+Well, sometimes you just have to go for the hack. Trying to find a way
+to add additional options to git-annex-shell without breaking backwards
+compatibility, I noticed that it ignores all options after `--`, because
+those tend to be random rsync options due to the way rsync runs it.
+
+So, I've added a new class of options, that come in between, like
+`-- opt=val opt=val ... --`
+
+The parser for these will not choke on unknown options, unlike normal
+getopt. So this let me add the additional info I needed to
+pass to git-annex-shell to make it record transfer information. And
+if I need to pass more info in the future, that's covered too.
+
+It's ugly, but since only git-annex runs git-annex-shell, this is an
+ugliness only I (and now you, dear reader) have to put up with.
+
+Note to self: Command-line programs are sometimes an API, particularly
+if designed to be called remotely, and so it makes sense consider
+whether they are, and design expandability into them from day 1.
+
+---
+
+Anyway, we now have full transfer tracking in git-annex! Both sides of
+a transfer know what's being transferred, and from where, and have
+the info necessary to interrupt the transfer.
+
+---
+
+Also did some basic groundwork, adding a queue of transfers to perform,
+and adding to the daemon's status information a map of currently running
+transfers.
+
+Next up: The daemon will use inotify to notice new and deleted transfer
+info files, and update its status info.
diff --git a/doc/design/assistant/blog/day_230__Mom.mdwn b/doc/design/assistant/blog/day_230__Mom.mdwn
new file mode 100644
index 000000000..66a0c864d
--- /dev/null
+++ b/doc/design/assistant/blog/day_230__Mom.mdwn
@@ -0,0 +1,35 @@
+Made a release today. Releasing has sure gotten easier with all the
+autobuilds to use!
+
+I am now using git-annex to share files with my mom. Here's how the webapp
+looks for our family's repository. Soon several of us will be using this
+repository.
+
+[[!img assistant/example.png]]
+
+We're using XMPP and rsync.net, so pretty standard setup much like
+shown in my last screencast.
+
+Real-world deployments help find bugs, and I found a few:
+
+* If you're running the webapp in `w3m` on a remote computer to set it up,
+ some forms are lacking submit buttons. This must be a issue with
+ Bootstrap, or HTML5, I guess. I switched to `lynx` and it offers a
+ way to submit forms that lack an explicit button.
+
+* Progress bars for downloads from encrypted rsync repos don't update
+ during the actual download, but only when gpg is decrypting the
+ downloaded file.
+
+* XMPP pushes sometimes fail still. Especially when your mom's computer
+ is saturating its limited outgoing network connection uploading hundreds of
+ photos. I have not yet determined if this is a packet loss/corruption issue,
+ or if the XMPP messages are getting out of order. My gut feeling is it's
+ the latter, in which can I can fix this pretty easily by adding sequence
+ numbers and some buffering for out of order packets. Or perhaps just
+ make it retry failed pushes when this happens.
+
+ Anyway, I found it was useful to set up a regular git repository on a
+ server to suppliment the git pushes over XMPP. It's helpful to have
+ such a git repository anyway, so that clients can push to there when the
+ other client(s) are not online to be pushed to directly over XMPP.
diff --git a/doc/design/assistant/blog/day_230__Mom/comment_1_696bba2246c8a9e6ce4aed3071bcc96c._comment b/doc/design/assistant/blog/day_230__Mom/comment_1_696bba2246c8a9e6ce4aed3071bcc96c._comment
new file mode 100644
index 000000000..5b8b8187f
--- /dev/null
+++ b/doc/design/assistant/blog/day_230__Mom/comment_1_696bba2246c8a9e6ce4aed3071bcc96c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="68.35.120.66"
+ subject="comment 1"
+ date="2013-04-05T23:50:14Z"
+ content="""
+This is probably a Dumb Git Question, but is there a tag in the repo for the new release? I go into my clone and type \"git tag\" and the latest one I see is 4.20130323.
+"""]]
diff --git a/doc/design/assistant/blog/day_230__Mom/comment_2_2fa295ab6db0828cb725cfcfb6777822._comment b/doc/design/assistant/blog/day_230__Mom/comment_2_2fa295ab6db0828cb725cfcfb6777822._comment
new file mode 100644
index 000000000..3f1666d89
--- /dev/null
+++ b/doc/design/assistant/blog/day_230__Mom/comment_2_2fa295ab6db0828cb725cfcfb6777822._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawln3ckqKx0x_xDZMYwa9Q1bn4I06oWjkog"
+ nickname="Michael"
+ subject="deletions by mistake?"
+ date="2013-04-06T04:58:09Z"
+ content="""
+Let's say a family member deletes a file by mistake in a synced diretory? Looks like this kind of error is easy to go unnoticed. What would be a good way to handle this?
+"""]]
diff --git a/doc/design/assistant/blog/day_230__Mom/comment_3_fafd7abec629290418334ddb015bf62c._comment b/doc/design/assistant/blog/day_230__Mom/comment_3_fafd7abec629290418334ddb015bf62c._comment
new file mode 100644
index 000000000..9cfa45aca
--- /dev/null
+++ b/doc/design/assistant/blog/day_230__Mom/comment_3_fafd7abec629290418334ddb015bf62c._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-04-06T16:26:57Z"
+ content="""
+Weird, I don't know where the tag went. I've pushed a new one.
+
+If a file is deleted, it's still there in git, and git-annex hangs onto its contents. You need a git history browser to get it back of course.
+"""]]
diff --git a/doc/design/assistant/blog/day_230__Mom/comment_4_450cac0f2e82c94fd34b527ae05ef1b8._comment b/doc/design/assistant/blog/day_230__Mom/comment_4_450cac0f2e82c94fd34b527ae05ef1b8._comment
new file mode 100644
index 000000000..56c8d3204
--- /dev/null
+++ b/doc/design/assistant/blog/day_230__Mom/comment_4_450cac0f2e82c94fd34b527ae05ef1b8._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlUbH3eytydcwlWqv8oauE2Jg4NwcV9uA0"
+ nickname="Anna"
+ subject="me!"
+ date="2013-04-06T18:22:30Z"
+ content="""
+I want in on the family repository! :-)
+"""]]
diff --git a/doc/design/assistant/blog/day_231__insert_title.mdwn b/doc/design/assistant/blog/day_231__insert_title.mdwn
new file mode 100644
index 000000000..6f91b2d36
--- /dev/null
+++ b/doc/design/assistant/blog/day_231__insert_title.mdwn
@@ -0,0 +1,26 @@
+Finally fixed the bug causing repeated checksumming when a direct mode file
+contains duplicate files. I may need to add some cleaning of stale inode
+caches eventually.
+
+Meanwhile, Guilhem made `git annex initremote` use higher quality entropy,
+with `--fast` getting back to the old behavior of urandom quality entropy.
+The assistant doesn't use high quality entropy since I have no way to
+prompt when the user would need to generate more. I did have a fun idea to
+deal with this: Make a javascript game, that the user can play while
+waiting, which would generate enropy nicely. Maybe one day.. ;)
+
+Also made a small but significant change to [[archive directory handling|todo/assistant_smarter_archive_directory_handling]].
+Now the assistant syncs files that are in `archive` directories like any
+other file, until they reach an archive repository. Then they get dropped
+from all the clients. This way, users who don't set up archive repositories
+don't need to know about this special case, and users who do want to use
+them can, with no extra configuration.
+
+After recent changes, the preferred content expression for transfer
+repositories is becoming a bit unweidly, at 212 characters. Probably
+time to add support for macros..
+
+`(not (inallgroup=client and copies=client:2) and (((exclude=*/archive/* and exclude=archive/*) or (not (copies=archive:1 or copies=smallarchive:1))) or (not copies=semitrusted+:1))) or (not copies=semitrusted+:1)`
+
+Still, it's pretty great how much this little language lets me express, so
+easily.
diff --git a/doc/design/assistant/blog/day_232__headless_webapp.mdwn b/doc/design/assistant/blog/day_232__headless_webapp.mdwn
new file mode 100644
index 000000000..a60ab383d
--- /dev/null
+++ b/doc/design/assistant/blog/day_232__headless_webapp.mdwn
@@ -0,0 +1,22 @@
+Developed a way to run the webapp on a remote or headless computer.
+
+The webapp can now be started on a remote or headless computer, just
+specify `--listen=address` to make it listen on an address other than
+localhost. It'll print out the URL to open to access it.
+
+This doesn't use HTTPS yet, because it'd need to generate a
+certificate, and even if it generated a self-signed SSL certificate,
+there'd be no easy way for the browser to verify it and avoid a MITM.
+
+So `--listen` is a less secure but easier option; using ssh to forward
+the webapp's port to the remote computer is more secure.
+
+(I do have an idea for a way to do this entirely securely, making
+the webapp set up the ssh port forwarding, which I have written down
+in [[webapp]].. but it would be rather complicated to implement.)
+
+----
+
+Made the webapp rescan for transfers after it's been used to change a
+repository's group. Would have been easy, but I had to chase down a
+cache invalidation bug.
diff --git a/doc/design/assistant/blog/day_232__headless_webapp/comment_1_0fdd77d143ecba6fdb9f75cb6fc37bfb._comment b/doc/design/assistant/blog/day_232__headless_webapp/comment_1_0fdd77d143ecba6fdb9f75cb6fc37bfb._comment
new file mode 100644
index 000000000..1b36a9ad8
--- /dev/null
+++ b/doc/design/assistant/blog/day_232__headless_webapp/comment_1_0fdd77d143ecba6fdb9f75cb6fc37bfb._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="Certificate storage"
+ date="2013-04-09T00:43:12Z"
+ content="""
+Why not store the certificate within the repository? Either a common one in, e.g.
+
+ .git-annex.key-cert.pem
+
+or host-specific as per
+
+ .git-annex.key-cert.pem.$HOST
+
+-- Richard
+"""]]
diff --git a/doc/design/assistant/blog/day_232__headless_webapp/comment_2_0784a2a73c3e2945f3d3f2577b3b9c9c._comment b/doc/design/assistant/blog/day_232__headless_webapp/comment_2_0784a2a73c3e2945f3d3f2577b3b9c9c._comment
new file mode 100644
index 000000000..67e797243
--- /dev/null
+++ b/doc/design/assistant/blog/day_232__headless_webapp/comment_2_0784a2a73c3e2945f3d3f2577b3b9c9c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmU_2tE75oyG0h2ZPN4lcroIKEMC8G-otE"
+ nickname="Michael"
+ subject="comment 2"
+ date="2013-04-09T07:27:53Z"
+ content="""
+Can you also set the port via listen= ?
+"""]]
diff --git a/doc/design/assistant/blog/day_232__headless_webapp/comment_3_ccb9fa22422fb913b6a496ebe65c49fb._comment b/doc/design/assistant/blog/day_232__headless_webapp/comment_3_ccb9fa22422fb913b6a496ebe65c49fb._comment
new file mode 100644
index 000000000..e2c00c59e
--- /dev/null
+++ b/doc/design/assistant/blog/day_232__headless_webapp/comment_3_ccb9fa22422fb913b6a496ebe65c49fb._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-04-09T18:58:40Z"
+ content="""
+@Richard besides the issues with where to store the private key part, that doesn't help with probably the most common use case for a headless webapp: Setting up a new repository on the remote system, which then might get joined into an existing repository network.
+"""]]
diff --git a/doc/design/assistant/blog/day_232__headless_webapp/comment_4_ceba4468760a2525960327698431cee2._comment b/doc/design/assistant/blog/day_232__headless_webapp/comment_4_ceba4468760a2525960327698431cee2._comment
new file mode 100644
index 000000000..e953233eb
--- /dev/null
+++ b/doc/design/assistant/blog/day_232__headless_webapp/comment_4_ceba4468760a2525960327698431cee2._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 4"
+ date="2013-04-09T19:18:24Z"
+ content="""
+@Michael you can now! --listen=address:port
+"""]]
diff --git a/doc/design/assistant/blog/day_233__taxes.mdwn b/doc/design/assistant/blog/day_233__taxes.mdwn
new file mode 100644
index 000000000..55273dd4b
--- /dev/null
+++ b/doc/design/assistant/blog/day_233__taxes.mdwn
@@ -0,0 +1,11 @@
+Did my taxes today. Not very pretty. Planning to run them by a professional.
+
+Reproduced a bug that prevents git-annex from authenticating to the ejabberd
+server, and passed the buck upstream with a test case to the author of the
+haskell XMPP library.
+
+Added some animations to the webapp to show when it's busy doing things.
+
+Made `git annex webapp --listen=address:port` work.
+
+Added a `annex.web-download-command` setting.
diff --git a/doc/design/assistant/blog/day_233__taxes/comment_1_9473ffdc42595af9c293fbcd5a1cdb54._comment b/doc/design/assistant/blog/day_233__taxes/comment_1_9473ffdc42595af9c293fbcd5a1cdb54._comment
new file mode 100644
index 000000000..a35e738c1
--- /dev/null
+++ b/doc/design/assistant/blog/day_233__taxes/comment_1_9473ffdc42595af9c293fbcd5a1cdb54._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="comment 1"
+ date="2013-04-10T13:35:30Z"
+ content="""
+I don't really want to nagging you, but I'm impatiently waiting
+for a new build (for linux) to be able to try out your duplicated file fix.
+
+Please don't delay your next release too much:)
+
+Laszlo
+
+"""]]
diff --git a/doc/design/assistant/blog/day_233__taxes/comment_2_5feed8d7053ba03812ccda8c61fd9775._comment b/doc/design/assistant/blog/day_233__taxes/comment_2_5feed8d7053ba03812ccda8c61fd9775._comment
new file mode 100644
index 000000000..32e4f077f
--- /dev/null
+++ b/doc/design/assistant/blog/day_233__taxes/comment_2_5feed8d7053ba03812ccda8c61fd9775._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-04-11T14:57:24Z"
+ content="""
+You can already try that fix out using the [[install/Linux_standalone]] autobuild.
+"""]]
diff --git a/doc/design/assistant/blog/day_234__clean_shutdown.mdwn b/doc/design/assistant/blog/day_234__clean_shutdown.mdwn
new file mode 100644
index 000000000..61b765b59
--- /dev/null
+++ b/doc/design/assistant/blog/day_234__clean_shutdown.mdwn
@@ -0,0 +1,29 @@
+Short day because I spent 3 hours this morning explaining free software
+and kickstarter to an accountant. And was away until 3 pm, so how did I get
+all this done‽
+
+Eliot pointed out that shutting down the assistant could leave transfers
+running. This happened because `git annex transferkeys` is a separate
+process, and so it was left to finish up any transfer that was in
+process. I've made shutdown stop all transfers that the
+assistant started. (Other paired computers could still be connecting to
+make transfers even when the assistant is not running, and those are not
+affected.)
+
+Added sequence numbers to the XMPP messages used for git pushes. While
+these numbers are not used yet, they're available for debugging, and will
+help me determine if packets are lost or come out of order. So if you have
+experienced problems with XMPP syncing sometimes failing, run tonight's
+build of the assistant with `--debug` (or turn on debugging in the webapp
+configuration screen), and send me a log by email to
+<debuglogs201204@joeyh.name>
+
+Changed the way that autobuilds and manual builds report their version
+number. It now includes the date of the last commit, and the abbreviated
+commit ID, rather than being some random date after the last release.
+
+Frederik found a bug using the assistant on a FAT filesystem. It didn't
+properly handle the files that git uses to stand-in for symlinks in that
+situation, and annexed those files. I've fixed this, and even moving
+around symlink stand-in files on a FAT filesystem now results in correct
+changes to symlinks being committed.
diff --git a/doc/design/assistant/blog/day_235__birthday.mdwn b/doc/design/assistant/blog/day_235__birthday.mdwn
new file mode 100644
index 000000000..2bd2b0d22
--- /dev/null
+++ b/doc/design/assistant/blog/day_235__birthday.mdwn
@@ -0,0 +1,31 @@
+Felt like spending my birthday working on git-annex. Thanks again to
+everyone who makes it possible for me to work on something I care about
+every day.
+
+----
+
+Did some work on `git annex addurl` today. It had gotten broken in direct
+mode (I think by an otherwise good and important bugfix). After fixing
+that, I made it interoperate with the webapp. So if you have the webapp
+open, it will display progress bars for downloads being run by `git annex
+addurl`.
+
+This enhancement meshes nicely with a FlashGot script Andy
+contributed, which lets you queue up downloads into your annex from a web
+browser. Andy described how to set it up in
+[[this_tip|tips/Using_Git-annex_as_a_web_browsing_assistant]].
+
+(I also looked briefly into ways to intercept a drag and drop of a link
+into the webapp and make it lauch a download for you. It doesn't seem that
+browsers allow javascript to override their standard behavior of loading
+links that are dropped into them. Probably good to prevent misuse, but it
+would be nice here...)
+
+----
+
+Also, I think I have fixed the progress bars displayed when downloading
+a file from an encrypted remote. I did this by hooking up existing
+download progress metering (that was only being used to display
+a download percentage in the console) into the location log, so the
+webapp can use it. So that was a *lot* easier than it could have been,
+but still a pretty large patch (500+ lines). Haven't tested this; should work.
diff --git a/doc/design/assistant/blog/day_235__birthday/comment_1_db558b071067c1e63cde05cca0551094._comment b/doc/design/assistant/blog/day_235__birthday/comment_1_db558b071067c1e63cde05cca0551094._comment
new file mode 100644
index 000000000..32c2c5d50
--- /dev/null
+++ b/doc/design/assistant/blog/day_235__birthday/comment_1_db558b071067c1e63cde05cca0551094._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawksoT5jmbiZ9UghROilchqy3kNJ1XGqCAo"
+ nickname="Rob"
+ subject="Drag and Drop"
+ date="2013-04-12T03:37:53Z"
+ content="""
+Is this along the lines of what you are looking for? http://www.dropzonejs.com/
+"""]]
diff --git a/doc/design/assistant/blog/day_235__birthday/comment_2_d1a2c1124781118267599457ae9e0512._comment b/doc/design/assistant/blog/day_235__birthday/comment_2_d1a2c1124781118267599457ae9e0512._comment
new file mode 100644
index 000000000..e41c083ce
--- /dev/null
+++ b/doc/design/assistant/blog/day_235__birthday/comment_2_d1a2c1124781118267599457ae9e0512._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="marvin"
+ ip="91.152.75.65"
+ subject="Happy Birthday"
+ date="2013-04-12T17:52:43Z"
+ content="""
+Great work!
+"""]]
diff --git a/doc/design/assistant/blog/day_235__birthday/comment_3_b853508d1d15234958b9f4a39277e45c._comment b/doc/design/assistant/blog/day_235__birthday/comment_3_b853508d1d15234958b9f4a39277e45c._comment
new file mode 100644
index 000000000..350ac2bc2
--- /dev/null
+++ b/doc/design/assistant/blog/day_235__birthday/comment_3_b853508d1d15234958b9f4a39277e45c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="robconnolly"
+ ip="118.90.78.117"
+ subject="comment 3"
+ date="2013-04-13T03:12:14Z"
+ content="""
+Thanks for fixing the addurl bug and Happy Birthday!
+"""]]
diff --git a/doc/design/assistant/blog/day_235__birthday/comment_5_73aad3398a43bc4d28bca9bf635fa757._comment b/doc/design/assistant/blog/day_235__birthday/comment_5_73aad3398a43bc4d28bca9bf635fa757._comment
new file mode 100644
index 000000000..969253971
--- /dev/null
+++ b/doc/design/assistant/blog/day_235__birthday/comment_5_73aad3398a43bc4d28bca9bf635fa757._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="andy"
+ ip="99.48.75.171"
+ subject="Just in case it might be helpful..."
+ date="2013-04-14T05:56:47Z"
+ content="""
+For whatever reason, dragging links onto the page text in the \"Using drag and drop for selecting\" section of <http://www.html5rocks.com/en/tutorials/file/dndfiles/#toc-selecting-files-dnd> does not trigger the usual page change. I don't really know why--I couldn't get it to work on my own with Firebug. And thanks for git-annex--love it!
+"""]]
diff --git a/doc/design/assistant/blog/day_236__evil_splicer.mdwn b/doc/design/assistant/blog/day_236__evil_splicer.mdwn
new file mode 100644
index 000000000..72c8f51a9
--- /dev/null
+++ b/doc/design/assistant/blog/day_236__evil_splicer.mdwn
@@ -0,0 +1,29 @@
+Spent today bulding the Evil Splicer, a program that parses `ghc -ddump-splices`
+output, and uses it to expand Template Haskell splices in source code.
+I hope to use this crazy hack to get the webapp working on Android.
+
+This was a good opportunity to use the
+[Parsec](http://hackage.haskell.org/package/parsec) library for parsing the
+ghc output. I've never really used it before, but found it quite nice to
+work with. The learning curve, if you already know monads and applicatives,
+is about 5 minutes. And instead of ugly regular expressions, you can work
+with nice code that's easily composable and refactorable. Even the ugly
+bits come out well:
+
+[[!format haskell """
+ {- All lines of the splice result will start with the same
+ - indent, which is stripped. Any other indentation is preserved. -}
+ i <- lookAhead indent
+ result <- unlines <$> many1 (string i >> restOfLine)
+"""]]
+
+Anyway, it works.. sorta. The parser works great! The splices that ghc
+outputs are put into the right places in the source files, and formatted in
+a way that ghc is able to build. Often though, they contain code that
+doesn't actually build as-is. I'm working to fix up the code to get closer
+to buildable.
+
+----
+
+Meanwhile, guilhem has made ssh connection caching work for rsync special
+remotes! It's very nice to have another developer working on git-annex. :)
diff --git a/doc/design/assistant/blog/day_237__gnome-keyring_craziness.mdwn b/doc/design/assistant/blog/day_237__gnome-keyring_craziness.mdwn
new file mode 100644
index 000000000..01b8195b6
--- /dev/null
+++ b/doc/design/assistant/blog/day_237__gnome-keyring_craziness.mdwn
@@ -0,0 +1,29 @@
+Fixed a bug where the locked down ssh key that the assistant sets up to
+access the annex on a remote server was being used by ssh *by default* for
+all logins to that server.
+
+That should not have happened. The locked down key is written to a filename
+that ssh won't use at all, by default. But, I found code in gnome-keyring
+that watches for `~/.ssh/*.pub` to appear, and automatically adds all such
+keys to the keyring. In at least some cases, probably when it has no other
+key, it then tells ssh to go ahead and use that key. Astounding.
+
+To avoid this, the assistant will store its keys in <s>`~/.ssh/annex/`</s>
+`~/.ssh/git-annex/` instead. gnome-keyring does not look there (verified in
+the source). If you use gnome-keyring and have set up a repository on a
+remote server with the assistant, I'd recommend moving the keys it set up
+and editing `~/.ssh/config` to point to their new location.
+
+gnome-keyring is not the only piece of software that has a bad
+interaction with git-annex. I've been working on a bug that makes git-annex
+fail to authenticate to ejabberd. ejabberd 2.1.10 got support for
+SCRAM-SHA-1, but its code violates the RFC, and chokes on an address
+attribute that the haskell XMPP library provides. I hope to get this fixed
+in ejabberd.
+
+
+Also did some more work on the Evil Splicer today, integrating it into the
+build of the Android app, and making it support incremental building.
+Improved its code generation, and am at the milestone where it creates
+valid haskell code for the entire `Assistant/WebApp/Types.hs` file,
+where Template Haskell expands 2 lines into 2300 lines of code!
diff --git a/doc/design/assistant/blog/day_237__gnome-keyring_craziness/comment_1_0cb088b732881d1fa92493aa1fd93d43._comment b/doc/design/assistant/blog/day_237__gnome-keyring_craziness/comment_1_0cb088b732881d1fa92493aa1fd93d43._comment
new file mode 100644
index 000000000..e8cc45782
--- /dev/null
+++ b/doc/design/assistant/blog/day_237__gnome-keyring_craziness/comment_1_0cb088b732881d1fa92493aa1fd93d43._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="Confusing name for storage directory"
+ date="2013-04-14T23:55:03Z"
+ content="""
+`~/.ssh/annex/` would make sense for ssh-annex. I would suggest using `~/.ssh/git-annex/` or similar, instead.
+"""]]
diff --git a/doc/design/assistant/blog/day_237__gnome-keyring_craziness/comment_2_b855fd710954beebaafe6d2bd03eb368._comment b/doc/design/assistant/blog/day_237__gnome-keyring_craziness/comment_2_b855fd710954beebaafe6d2bd03eb368._comment
new file mode 100644
index 000000000..cf3e8fbbf
--- /dev/null
+++ b/doc/design/assistant/blog/day_237__gnome-keyring_craziness/comment_2_b855fd710954beebaafe6d2bd03eb368._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-04-14T23:59:44Z"
+ content="""
+I agree, change made
+"""]]
diff --git a/doc/design/assistant/blog/day_238__back_to_Android.mdwn b/doc/design/assistant/blog/day_238__back_to_Android.mdwn
new file mode 100644
index 000000000..b07d784fa
--- /dev/null
+++ b/doc/design/assistant/blog/day_238__back_to_Android.mdwn
@@ -0,0 +1,11 @@
+Back to really working toward an Android webapp now. I have been improving
+the EvilSplicer, and the build machinery, and build environment all day.
+Slow but steady progress.
+
+First milestone of the day was when I got `yesod-form` to build with all
+Template Haskell automatically expanded by the EvilSplicer. (With a few
+manual fixups where it's buggy.)
+
+At this point the Android build with the webapp enabled successfully
+builds several files containing Yesod code.. And I suspect I am very close
+to getting a first webapp build for Android.
diff --git a/doc/design/assistant/blog/day_239__bugfixes_and_frustration.mdwn b/doc/design/assistant/blog/day_239__bugfixes_and_frustration.mdwn
new file mode 100644
index 000000000..2ca62cfe6
--- /dev/null
+++ b/doc/design/assistant/blog/day_239__bugfixes_and_frustration.mdwn
@@ -0,0 +1,28 @@
+Several bug fixes today, and got mostly caught up on recent messages.
+Still have a backlog of two known bugs that I cannot reproduce well enough
+to have worked on, but I am thinking I will make a release tomorrow. There
+have been a lot of changes in the 10 days since the last release.
+
+----
+
+I am, frustratingly, stuck building the webapp on Android with no forward
+progress today (and last night) after such a productive day yesterday.
+
+The expanded Template Haskell code of the webapp fails to compile,
+whereever type safe urls are used.
+
+<pre>
+Assistant/WebApp/Types.hs:95:63:
+ Couldn't match expected type `Route WebApp -> t2'
+ with actual type `Text'
+ The function `urender_a1qcK' is applied to three arguments,
+ but its type `Route WebApp -> [(Text, Text)] -> Text' has only two
+ In the expression: urender_a1qcK u_a1qcL [] LogR
+ In the first argument of `toHtml', namely
+ `(\ u_a1qcL -> urender_a1qcK u_a1qcL [] LogR)'
+</pre>
+
+My best guess is this is a mismatch between the versions of yesod (or other
+libraries) used for the native and cross compiled ghc's. So I've been
+slowly trying to get a fully matched set of versions in between working on
+bugs.
diff --git a/doc/design/assistant/blog/day_23__transfer_watching.mdwn b/doc/design/assistant/blog/day_23__transfer_watching.mdwn
new file mode 100644
index 000000000..3e4e27d47
--- /dev/null
+++ b/doc/design/assistant/blog/day_23__transfer_watching.mdwn
@@ -0,0 +1,25 @@
+Starting to travel, so limited time today.
+
+Yet Another Thread added to the assistant, all it does is watch for changes
+to transfer information files, and update the assistant's map of transfers
+currently in progress. Now the assistant will know if some other repository
+has connected to the local repo and is sending or receiving a file's
+content.
+
+This seemed really simple to write, it's just 78 lines of code. It worked
+100% correctly the first time. :) But it's only so easy because I've got
+this shiny new inotify hammer that I keep finding places to use in the
+assistant.
+
+Also, the new thread does some things that caused a similar thread (the
+merger thread) to go into a MVar deadlock. Luckily, I spent much of
+[day 19](day_19__random_improvements) investigating and fixing that
+deadlock, even though it was not a problem at the time.
+
+So, good.. I'm doing things right and getting to a place where rather
+nontrivial features can be added easily.
+
+--
+
+Next up: Enough nonsense with tracking transfers... Time to start actually
+transferring content around!
diff --git a/doc/design/assistant/blog/day_240__it_builds.mdwn b/doc/design/assistant/blog/day_240__it_builds.mdwn
new file mode 100644
index 000000000..dc975af81
--- /dev/null
+++ b/doc/design/assistant/blog/day_240__it_builds.mdwn
@@ -0,0 +1,37 @@
+Late last night, I successfully built the full webapp for Android!
+
+That was with several manual modifications to the generated code, which I
+still need to automate. And I need to set up the autobuilder properly
+still. And I need to find a way to make the webapp open Android's web browser
+to URL. So it'll be a while yet until a package is available
+to try. But what a milestone!
+
+The point I was stuck on all day yesterday was generated code that
+looked like this:
+
+[[!format haskell """
+(toHtml
+ (\ u_a2ehE -> urender_a2ehD u_a2ehE []
+ (CloseAlert aid)))));
+"""]]
+
+That just couldn't type check at all. Most puzzling. My best guess is that
+`u_a2ehE` is the dictionary GHC passes internally to make a typeclass work,
+which somehow leaked out and became visible. Although
+I can't rule out that I may have messed something up in my build environment.
+The EvilSplicer has a hack in it that finds such code and converts it to
+something like this:
+
+[[!format haskell """
+(toHtml
+ (flip urender_a2ehD []
+ (CloseAlert aid)))));
+"""]]
+
+I wrote some more about the process of the Android port in my personal blog:
+[Template Haskell on impossible architectures](http://joeyh.name/blog/entry/Template_Haskell_on_impossible_architectures/)
+
+----
+
+Release day today. The OSX builds are both not available yet for this
+release, hopefully will come out soon.
diff --git a/doc/design/assistant/blog/day_240__it_builds/comment_1_151840ae0020ea63b2f041488c905386._comment b/doc/design/assistant/blog/day_240__it_builds/comment_1_151840ae0020ea63b2f041488c905386._comment
new file mode 100644
index 000000000..a8e489582
--- /dev/null
+++ b/doc/design/assistant/blog/day_240__it_builds/comment_1_151840ae0020ea63b2f041488c905386._comment
@@ -0,0 +1,25 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="Duplicated files resolved"
+ date="2013-04-18T05:52:35Z"
+ content="""
+Hi,
+
+Seems like the duplicated file issue finally resolved in this release,
+also the logging is not so detailed, so it does not explode the disk space either.
+
+I think a new bug introduced in this release,
+namely if you create a repository and a backup repository of it (pendrive), then this repository is not in direct mode by default.
+(and there is a missing direct = True variable in that repository (/mnt/dat/annex_backup/.git/annex/config)).
+
+Also I run into resource exhausted bug, and every thread is crashed.
+Can git-annex only watch a directory, and not every file in it?
+
+I will create a bugreport for resource exhausted.
+
+Best,
+ Laszlo
+
+
+"""]]
diff --git a/doc/design/assistant/blog/day_241__cleanup.mdwn b/doc/design/assistant/blog/day_241__cleanup.mdwn
new file mode 100644
index 000000000..077922695
--- /dev/null
+++ b/doc/design/assistant/blog/day_241__cleanup.mdwn
@@ -0,0 +1,14 @@
+Finished the last EvilSplicer tweak and other fixes to make the
+Android webapp build without any hand-holding.
+
+Currently setting up the Android autobuilder to include the webapp in its
+builds. To make this work I had to set up a new chroot with all the right
+stuff installed.
+
+Investigated how to make the Android webapp open a web browser when run.
+As far as I can tell (without access to an Android device right now),
+`am start -a android.intent.action.VIEW -d http://localhost/etc` should do
+it.
+
+Seems that git 1.8.2 broke the assistant. I've put in a fix but have not
+yet tested it.
diff --git a/doc/design/assistant/blog/day_241__cleanup/comment_1_0e283cdf66a25b3cc9423fe651084cb9._comment b/doc/design/assistant/blog/day_241__cleanup/comment_1_0e283cdf66a25b3cc9423fe651084cb9._comment
new file mode 100644
index 000000000..d9e468f32
--- /dev/null
+++ b/doc/design/assistant/blog/day_241__cleanup/comment_1_0e283cdf66a25b3cc9423fe651084cb9._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlJ2utMQgMEYAOs3Dfc6eZRyUzt4acNXUU"
+ nickname="David"
+ subject="am start -a android.intent.action.VIEW -d http://localhost/etc"
+ date="2013-04-18T22:39:50Z"
+ content="""
+Just tested the command on an Android device, it works well.
+"""]]
diff --git a/doc/design/assistant/blog/day_242__more_porting.mdwn b/doc/design/assistant/blog/day_242__more_porting.mdwn
new file mode 100644
index 000000000..89fbfea0f
--- /dev/null
+++ b/doc/design/assistant/blog/day_242__more_porting.mdwn
@@ -0,0 +1,4 @@
+Got WebDAV enabled in the Android build. Had to deal with some system calls
+not available in Android's libc.
+
+New poll: [[polls/Android_default_directory]]
diff --git a/doc/design/assistant/blog/day_243__in_the_field.mdwn b/doc/design/assistant/blog/day_243__in_the_field.mdwn
new file mode 100644
index 000000000..b05ccac9e
--- /dev/null
+++ b/doc/design/assistant/blog/day_243__in_the_field.mdwn
@@ -0,0 +1,21 @@
+Today was not a work day for me, but I did get a chance to install
+git-annex in real life while visiting. Was happy to download the standalone
+Linux tarball and see that it could be unpacked, and git-annex webapp
+started just by clicking around in the GUI. And in very short order got it
+set up.
+
+I was especially pleased to see my laptop noticed this new repository
+had appeared on the network via XMPP push, and started immediately
+uploading files to my rsync.net transfer repository so the new
+repository could get them.
+
+Did notice that the standalone tarball neglected to install a
+FDO menu file. Fixed that, and some other minor issues I noticed.
+
+
+I also got a brief chance to try the Android webapp. It fails to start;
+apparently `getaddrinfo` doesn't like the flags passed to it and is
+failing. As failure modes go, this isn't at all bad. I can certainly work
+around it with some hardcoded port numbers, but I want to fix it the right
+way. Have ordered a replacement battery for my dead phone so I can use it
+for Android testing.
diff --git a/doc/design/assistant/blog/day_244__android_porting.mdwn b/doc/design/assistant/blog/day_244__android_porting.mdwn
new file mode 100644
index 000000000..e535c1054
--- /dev/null
+++ b/doc/design/assistant/blog/day_244__android_porting.mdwn
@@ -0,0 +1,6 @@
+Ported all the C libraries needed for XMPP to Android. (gnutls,
+libgcrypt, libgpg-error, nettle, xml2, gsasl, etc). Finally
+got it all to link. What a pain.
+
+Bonus: Local pairing support builds for Android now, seems recent changes to
+the network library for WebDAV also fixed it.
diff --git a/doc/design/assistant/blog/day_245__misc.mdwn b/doc/design/assistant/blog/day_245__misc.mdwn
new file mode 100644
index 000000000..8559ac4f1
--- /dev/null
+++ b/doc/design/assistant/blog/day_245__misc.mdwn
@@ -0,0 +1,15 @@
+Got the OSX autobuilder back running, and finally got a OSX build up for
+the 4.20130417 release. Also fixed the OSX app build machinery to handle
+rpath.
+
+Made the assistant (and `git annex sync`) sync with git remotes that have
+`annex-ignore` set. So, `annex-ignore` is only used to prevent using
+the annex of a remote, not syncing with it. The benefit of this change
+is that it'll make the assistant sync the local git repository with
+a git remote that is on a server that does not have git-annex installed.
+It can even sync to github.
+
+Worked around more breakage on misconfigured systems that don't have GECOS
+information.
+
+... And other bug fixes and bug triage.
diff --git a/doc/design/assistant/blog/day_245__misc/comment_1_3a2976617bb0cdc206fb1397a2ef1177._comment b/doc/design/assistant/blog/day_245__misc/comment_1_3a2976617bb0cdc206fb1397a2ef1177._comment
new file mode 100644
index 000000000..4ee7612f1
--- /dev/null
+++ b/doc/design/assistant/blog/day_245__misc/comment_1_3a2976617bb0cdc206fb1397a2ef1177._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="spwhitton"
+ ip="192.76.7.217"
+ subject="comment 1"
+ date="2013-04-23T17:11:46Z"
+ content="""
+If I set my annex-ignore'd respository to `annex-sync = false` will this override the new behaviour? My remote requires mounting a fuse mount, so this change will just result in my seeing lots of sync failure messages in the webapp.
+"""]]
diff --git a/doc/design/assistant/blog/day_245__misc/comment_2_e0f9704e91fedca8ff26356f354cc1c3._comment b/doc/design/assistant/blog/day_245__misc/comment_2_e0f9704e91fedca8ff26356f354cc1c3._comment
new file mode 100644
index 000000000..545da72cd
--- /dev/null
+++ b/doc/design/assistant/blog/day_245__misc/comment_2_e0f9704e91fedca8ff26356f354cc1c3._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-04-23T20:16:26Z"
+ content="""
+Yes, setting that, or just clicking to pause syncing to a remote in the webapp will still work.
+
+Although I don't think you need to.. If the remote is on a filesystem mount point, the assistant will just ignore it when it's not mounted. And will automatically detect when it gets mounted and sync with it, too. Same as USB drives are handled.
+"""]]
diff --git a/doc/design/assistant/blog/day_245__misc/comment_3_93003a0d0983efbdc046d7459be194b0._comment b/doc/design/assistant/blog/day_245__misc/comment_3_93003a0d0983efbdc046d7459be194b0._comment
new file mode 100644
index 000000000..45a3b6adc
--- /dev/null
+++ b/doc/design/assistant/blog/day_245__misc/comment_3_93003a0d0983efbdc046d7459be194b0._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="spwhitton"
+ ip="163.1.167.50"
+ subject="comment 3"
+ date="2013-04-24T17:09:50Z"
+ content="""
+It's a userspace fuse mount so the assistant won't know it's a mountpoint unless mounted. Also I don't want the automatic sync since I like to keep this respository manual as a kind of backup. Thanks for the info.
+"""]]
diff --git a/doc/design/assistant/blog/day_246__bug_treadmill.mdwn b/doc/design/assistant/blog/day_246__bug_treadmill.mdwn
new file mode 100644
index 000000000..36ee0c617
--- /dev/null
+++ b/doc/design/assistant/blog/day_246__bug_treadmill.mdwn
@@ -0,0 +1,18 @@
+There seem to be a steady state of enough bug reports coming in that I can
+work on them whenever I'm not working on anything else. As I did all day
+today.
+
+This doesn't bother me if the bug reports are of real bugs that I can
+reproduce and fix, but I'm spending a lot of time currently following up to
+messages and asking simple questions like "what version number" and "can I
+please see the whole log file". And just trying to guess what a vague
+problem report means and read people's minds to get to a definite bug
+with a test case that I can then fix.
+
+I've noticed the overall quality of bug reports nosedive over the past
+several months. My guess is this means that git-annex has found a less
+technical audience. I need to find something to do about this.
+
+With that whining out of the way ...
+I fixed a pretty ugly bug on FAT/Android today, and
+I am 100% caught up on messages right now!
diff --git a/doc/design/assistant/blog/day_246__bug_treadmill/comment_1_f76f653364fe2b97e85e8356c93b0fce._comment b/doc/design/assistant/blog/day_246__bug_treadmill/comment_1_f76f653364fe2b97e85e8356c93b0fce._comment
new file mode 100644
index 000000000..33746ed4a
--- /dev/null
+++ b/doc/design/assistant/blog/day_246__bug_treadmill/comment_1_f76f653364fe2b97e85e8356c93b0fce._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkQafKy7hNSEolLs6TvbgUnkklTctUY9LI"
+ nickname="Zellyn"
+ subject="Bugs..."
+ date="2013-04-23T23:30:47Z"
+ content="""
+Perhaps if you made a bug report form that asked for the version number (with helpful command to get it printed below), and had a checkbox for \"full log attached\", etc. you might be able to weed out low-value bugs... Not that adding UI to force good bugs really works, but there might be a couple of low-hanging fruit before the diminishing returns kick in.
+"""]]
diff --git a/doc/design/assistant/blog/day_247__performance_tuning.mdwn b/doc/design/assistant/blog/day_247__performance_tuning.mdwn
new file mode 100644
index 000000000..964710b8e
--- /dev/null
+++ b/doc/design/assistant/blog/day_247__performance_tuning.mdwn
@@ -0,0 +1,16 @@
+Working on assistant's performance when it has to add a whole lot of files
+(10k to 100k).
+
+Improved behavior in several ways, including fixing display
+of the alert in the webapp when the default inotify limit of 8192
+directories is exceeded.
+
+Created a new TList data type, a transactional DList. Much nicer
+implementation than the TChan based thing it was using to keep track of the
+changes, although it only improved runtime and memory usage a little bit.
+The way that this is internally storing a function in STM and modifying
+that function to add items to the list is way cool.
+
+Other tuning seems to have decreased the time it would take to import 100k
+files from somewhere in the range of a full day (too long to wait to see),
+to around 3.5 hours. I don't know if that's good, but it's certainly better.
diff --git a/doc/design/assistant/blog/day_248__Internet_Archive.mdwn b/doc/design/assistant/blog/day_248__Internet_Archive.mdwn
new file mode 100644
index 000000000..f002939f1
--- /dev/null
+++ b/doc/design/assistant/blog/day_248__Internet_Archive.mdwn
@@ -0,0 +1,28 @@
+Very productive & long day today, spent adding a new feature to the
+webapp: Internet Archive support!
+
+[[!img /assistant/iaitem.png]]
+
+git-annex already supported using archive.org via its S3 special remotes,
+so this is just a nice UI around that.
+
+How does it decide which files to publish on archive.org? Well,
+the item has a unique name, which is based on the description
+field. Any files located in a directory with that name will be uploaded
+to that item. (This is done via a new preferred content expression I added.)
+
+So, you can have one repository with multiple IA items attached, and
+sort files between them however you like.
+I plan to make a screencast eventually demoing that.
+
+Another interesting use case, once the Android webapp is done, would be add
+a repository on the DCIM directory, set the archive.org repository to
+prefer all content, and *bam*, you have a phone or tablet that
+auto-publishes and archives every picture it takes.
+
+Another nice little feature added today is that whenever a file is uploaded
+to the Internet Archive, its public url is automatically recorded, same
+as if you'd ran `git annex addurl`. So any users who can clone your
+repository can download the files from archive.org, without needing any
+login or password info. This makes the Internet Archive a nice way to
+publish the large files associated with a public git repository.
diff --git a/doc/design/assistant/blog/day_249__quiet_day.mdwn b/doc/design/assistant/blog/day_249__quiet_day.mdwn
new file mode 100644
index 000000000..28c1e6f3d
--- /dev/null
+++ b/doc/design/assistant/blog/day_249__quiet_day.mdwn
@@ -0,0 +1,7 @@
+Quiet day. Only did minor things, like adding webapp UI for changing the
+directory used by Internet Archive remotes, and splitting out an
+`enableremote` command from `initremote`.
+
+My Android development environment is set up and ready to go on my Motorola
+Droid. The current Android build of git-annex fails to link at run time, so
+my work is cut out for me. Probably broke something while enabling XMPP?
diff --git a/doc/design/assistant/blog/day_24__airport_digressions.mdwn b/doc/design/assistant/blog/day_24__airport_digressions.mdwn
new file mode 100644
index 000000000..695296974
--- /dev/null
+++ b/doc/design/assistant/blog/day_24__airport_digressions.mdwn
@@ -0,0 +1,99 @@
+In a series of airport layovers all day. Since I woke up at 3:45 am,
+didn't feel up to doing serious new work, so instead I worked through some
+OSX support backlog.
+
+git-annex will now use Haskell's SHA library if the `sha256sum`
+command is not available. That library is slow, but it's guaranteed to be
+available; git-annex already depended on it to calculate HMACs.
+
+Then I decided to see if it makes sense to use the SHA library
+when adding smaller files. At some point, its slower implementation should
+win over needing to fork and parse the output of `sha256sum`. This was
+the first time I tried out Haskell's
+[Criterion](http://hackage.haskell.org/package/criterion) benchmarker,
+and I built this simple benchmark in short order.
+
+[[!format haskell """
+import Data.Digest.Pure.SHA
+import Data.ByteString.Lazy as L
+import Criterion.Main
+import Common
+
+testfile :: FilePath
+testfile = "/tmp/bar" -- on ram disk
+
+main = defaultMain
+ [ bgroup "sha256"
+ [ bench "internal" $ whnfIO internal
+ , bench "external" $ whnfIO external
+ ]
+ ]
+
+internal :: IO String
+internal = showDigest . sha256 <$> L.readFile testfile
+
+external :: IO String
+external = pOpen ReadFromPipe "sha256sum" [testfile] $ \h ->
+ fst . separate (== ' ') <$> hGetLine h
+"""]]
+
+The nice thing about benchmarking in Airports is when you're running a
+benchmark locally, you don't want to do anything else with the computer,
+so can alternate people watching, spacing out, and analizing results.
+
+100 kb file:
+
+ benchmarking sha256/internal
+ mean: 15.64729 ms, lb 15.29590 ms, ub 16.10119 ms, ci 0.950
+ std dev: 2.032476 ms, lb 1.638016 ms, ub 2.527089 ms, ci 0.950
+
+ benchmarking sha256/external
+ mean: 8.217700 ms, lb 7.931324 ms, ub 8.568805 ms, ci 0.950
+ std dev: 1.614786 ms, lb 1.357791 ms, ub 2.009682 ms, ci 0.950
+
+75 kb file:
+
+ benchmarking sha256/internal
+ mean: 12.16099 ms, lb 11.89566 ms, ub 12.50317 ms, ci 0.950
+ std dev: 1.531108 ms, lb 1.232353 ms, ub 1.929141 ms, ci 0.950
+
+ benchmarking sha256/external
+ mean: 8.818731 ms, lb 8.425744 ms, ub 9.269550 ms, ci 0.950
+ std dev: 2.158530 ms, lb 1.916067 ms, ub 2.487242 ms, ci 0.950
+
+50 kb file:
+
+ benchmarking sha256/internal
+ mean: 7.699274 ms, lb 7.560254 ms, ub 7.876605 ms, ci 0.950
+ std dev: 801.5292 us, lb 655.3344 us, ub 990.4117 us, ci 0.950
+
+ benchmarking sha256/external
+ mean: 8.715779 ms, lb 8.330540 ms, ub 9.102232 ms, ci 0.950
+ std dev: 1.988089 ms, lb 1.821582 ms, ub 2.181676 ms, ci 0.950
+
+10 kb file:
+
+ benchmarking sha256/internal
+ mean: 1.586105 ms, lb 1.574512 ms, ub 1.604922 ms, ci 0.950
+ std dev: 74.07235 us, lb 51.71688 us, ub 108.1348 us, ci 0.950
+
+ benchmarking sha256/external
+ mean: 6.873742 ms, lb 6.582765 ms, ub 7.252911 ms, ci 0.950
+ std dev: 1.689662 ms, lb 1.346310 ms, ub 2.640399 ms, ci 0.950
+
+It's possible to get nice graphical reports out of Criterion, but
+this is clear enough, so I stopped here. 50 kb seems a reasonable
+cutoff point.
+
+I also used this to benchmark the SHA256 in Haskell's Crypto package.
+Surprisingly, it's a *lot* slower than even the Pure.SHA code.
+On a 50 kb file:
+
+ benchmarking sha256/Crypto
+ collecting 100 samples, 1 iterations each, in estimated 6.073809 s
+ mean: 69.89037 ms, lb 69.15831 ms, ub 70.71845 ms, ci 0.950
+ std dev: 3.995397 ms, lb 3.435775 ms, ub 4.721952 ms, ci 0.950
+
+
+There's another Haskell library, [SHA2](http://hackage.haskell.org/package/SHA2),
+which I should try some time.
diff --git a/doc/design/assistant/blog/day_250__stymied.mdwn b/doc/design/assistant/blog/day_250__stymied.mdwn
new file mode 100644
index 000000000..f9d50b48c
--- /dev/null
+++ b/doc/design/assistant/blog/day_250__stymied.mdwn
@@ -0,0 +1,23 @@
+Turns out my old Droid has such an old version of Android (2.2) that
+it doesn't work with any binaries produced by my haskell cross-compiler. I
+think it's using a symbol not in its version of libc. Since upgrading this
+particular phone is a ugly process and the hardware is dying anyway (bad
+USB power connecter), I have given up on using it, and ordered an Android
+tablet instead to use for testing. Until that arrives, no Android. Bah.
+Wanted to get the Android app working in April.
+
+Instead, today I worked on making the webapp require less redundant
+password entry when adding multiple repositories using the same cloud
+provider. This is especially needed for the Internet Archive, since users
+will often want to have quite a few repositories, for different IA items.
+Implemented it for box.com, and Amazon too.
+
+Francois Marier has built an Ubuntu PPA for git-annex, containing the
+current version, with the assistant and webapp. It's targeted at Precise,
+but I think will probably also work with newer releases.
+<https://launchpad.net/~fmarier/+archive/ppa>
+
+Probably while I'm waiting to work on Android again, I will try to
+improve the situation with using a single XMPP account for multiple
+repositories. Spent a while today thinking through ways to improve the
+design, and have some ideas.
diff --git a/doc/design/assistant/blog/day_250__stymied/comment_1_330a10d447ccc3db03fcbfe571dbb404._comment b/doc/design/assistant/blog/day_250__stymied/comment_1_330a10d447ccc3db03fcbfe571dbb404._comment
new file mode 100644
index 000000000..26c7d7c7f
--- /dev/null
+++ b/doc/design/assistant/blog/day_250__stymied/comment_1_330a10d447ccc3db03fcbfe571dbb404._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnLgNOfkl8c6oQu9b42U0Pm_uC4n3Gkgiw"
+ nickname="Mark"
+ subject="Thanks!"
+ date="2013-04-29T01:24:55Z"
+ content="""
+I was not looking forward to figuring out how to come up with all of those haskell build deps on Precise, so thanks to François Marier for putting this together. (Does Ubuntu/launchpad autobuild all of the architectures, or do they need to be contributed? I see that `armhf` isn't there at the moment...)
+"""]]
diff --git a/doc/design/assistant/blog/day_251__xmpp_improvements.mdwn b/doc/design/assistant/blog/day_251__xmpp_improvements.mdwn
new file mode 100644
index 000000000..7007d7c0d
--- /dev/null
+++ b/doc/design/assistant/blog/day_251__xmpp_improvements.mdwn
@@ -0,0 +1,34 @@
+Took 2 days in a row off, because I noticed I have forgotten to do that
+since February, or possibly earlier, not counting trips. Whoops!
+
+Also, I was feeling overwhelmed with the complexity of fixing XMPP to not
+be buggy when there are multiple separate repos using the same XMPP
+account. Let my subconscious work on that, and last night it served up the
+solution, in detail. Built it today.
+
+It's only a partial solution, really. If you want to use the same XMPP
+account for multiple separate repositories, you cannot use the "Share with
+your other devices" option to pair your devices. That's because XMPP
+pairing assumes all your devices are using the same XMPP account, in order
+to avoid needing to confirm on every device each time you add a new device.
+The UI is clear about that, and it avoids complexity, so I'm ok with that.
+
+But, if you want to instead use "Share with a friend", you now can use the
+same XMPP account for as many separate repositories as you like. The
+assistant now ignores pushes from repositories it doesn't know about.
+Before, it would merge them all together without warning.
+
+----
+
+While I was testing that, I think I found out the real reason why XMPP
+pushes have seemed a little unreliable. It turns out to not be an XMPP
+issue at all! Instead, the merger was simply not always
+noticing when `git receive-pack` updated a ref, and not merging it into
+master. That was easily fixed.
+
+----
+
+Adam Spiers has been getting a `.gitignore` query interface suitable for
+the assistant to use into `git`, and he tells me it's landed in `next`.
+I should soon check that out and get the assistant using it. But first,
+Android app!
diff --git a/doc/design/assistant/blog/day_252__release_day.mdwn b/doc/design/assistant/blog/day_252__release_day.mdwn
new file mode 100644
index 000000000..70c99760a
--- /dev/null
+++ b/doc/design/assistant/blog/day_252__release_day.mdwn
@@ -0,0 +1,6 @@
+Pushed out a release today. Looking back over April, I'm happy with it as a
+bug fix and stabilization month. Wish I'd finished the Android app in April,
+but let's see what happens tomorrow.
+
+Recorded part of a screencast on using Archive.org, but `recordmydesktop`
+lost the second part. Grr. Will work on that later.
diff --git a/doc/design/assistant/blog/day_253__OMG.mdwn b/doc/design/assistant/blog/day_253__OMG.mdwn
new file mode 100644
index 000000000..b1cc89fff
--- /dev/null
+++ b/doc/design/assistant/blog/day_253__OMG.mdwn
@@ -0,0 +1,22 @@
+[[!img /android/webapp.png alt="git-annex webapp on Android"]]
+
+I fixed what I thought was keeping the webapp from working on Android, but
+then it started segfaulting every time it was started. Eventually I
+determined this segfault happened whenever haskell code called
+`getaddrinfo`. I don't know why. This is particularly weird since I had
+a demo web server that used `getaddrinfo` working way back in
+[[day_201__real_Android_wrapup]]. Anyway, I worked around it by not using
+`getaddrinfo` on Android.
+
+Then I spent 3 hours stuck, because the webapp seemed to run, but
+nothing could connect to the port it was on. Was it a firewall? Was
+the Haskell threaded runtime's use of `accept()` broken? I went all the way
+down to the raw system calls, and back, only to finally notice I had `netstat`
+available on my Android. Which showed it was not listening to the port I
+thought it was!
+
+Seems that `ntohs` and `htons` are broken somehow. To get the
+screenshot, I fixed up the port manually. Have a build running that
+should work around the issue.
+
+Anyway, the webapp works on Android!
diff --git a/doc/design/assistant/blog/day_253__OMG/comment_1_bbdc61092771163e65a90a4755a807d8._comment b/doc/design/assistant/blog/day_253__OMG/comment_1_bbdc61092771163e65a90a4755a807d8._comment
new file mode 100644
index 000000000..0fa06b32f
--- /dev/null
+++ b/doc/design/assistant/blog/day_253__OMG/comment_1_bbdc61092771163e65a90a4755a807d8._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnxp2XU8gIribhhGhGuYtU6eMMwHv5gUGI"
+ nickname="Amitai"
+ subject="Woohoo!"
+ date="2013-05-03T03:13:25Z"
+ content="""
+(See above)
+"""]]
diff --git a/doc/design/assistant/blog/day_254__Android_app_polishing.mdwn b/doc/design/assistant/blog/day_254__Android_app_polishing.mdwn
new file mode 100644
index 000000000..cbb6f7f15
--- /dev/null
+++ b/doc/design/assistant/blog/day_254__Android_app_polishing.mdwn
@@ -0,0 +1,35 @@
+There's a new page [[/Android]] that documents using git-annex on Android
+in detail.
+
+The Android app now opens the webapp when a terminal window is opened.
+This is good enough for trying it out easily, but far from ideal.
+
+Fixed an EvilSplicer bug that corrupted newlines in
+the static files served by the webapp. Now the icons in the webapp
+display properly, and the javascript works.
+
+Made the startup screen default to `/sdcard/annex` for the repository
+location, and also have a button to set up a camera repository. The camera
+repository is put in the "source" preferred content group, so it will only
+hang onto photos and videos until they're uploaded off the Android device.
+
+Quite a lot of other small fixes on Android. At this point I've tested the
+following works:
+
+* Starting webapp.
+* Making a repository, adding files.
+* All the basic webapp UI.
+
+However, I was not able to add any remote repository using only the webapp,
+due to some more problems with the network stack.
+
+* Jabber and Webdav don't quite work ("getProtocolByname: does not exist (no
+ such protocol name: tcp)").
+* SSH server fails.
+ ("Network/Socket/Types.hsc:(881,3)-(897,61): Non-exhaustive patterns in case")
+ I suspect it will work if I disable the DNS expansion code.
+
+So, that's the next thing that needs to be tackled.
+
+If you'd like to play with it in its current state, I've updated the
+Android builds to incorporate all my work so far.
diff --git a/doc/design/assistant/blog/day_254__Android_app_polishing/comment_1_37f4ff5227566ce4b3fa69fc32568841._comment b/doc/design/assistant/blog/day_254__Android_app_polishing/comment_1_37f4ff5227566ce4b3fa69fc32568841._comment
new file mode 100644
index 000000000..7ba9f9420
--- /dev/null
+++ b/doc/design/assistant/blog/day_254__Android_app_polishing/comment_1_37f4ff5227566ce4b3fa69fc32568841._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkGCmVc5qIJaQQgG82Hc5zzBdAVdhe2JEM"
+ nickname="Bruno"
+ subject="comment 1"
+ date="2013-05-04T05:30:26Z"
+ content="""
+> The camera repository is put in the \"source\" preferred content group, so it will only hang onto photos and videos until they're uploaded off the Android device.
+
+This is very nice but I'm wondering if I take a picture that I want to share using an Android app like Facebook, would the picture get deleted before I could share it?
+
+Would there be a way to access old pictures? For example, to show them to people you meet.
+
+
+"""]]
diff --git a/doc/design/assistant/blog/day_254__Android_app_polishing/comment_2_58bbb105bdbb72bba85c3622195f43b9._comment b/doc/design/assistant/blog/day_254__Android_app_polishing/comment_2_58bbb105bdbb72bba85c3622195f43b9._comment
new file mode 100644
index 000000000..7311b72e0
--- /dev/null
+++ b/doc/design/assistant/blog/day_254__Android_app_polishing/comment_2_58bbb105bdbb72bba85c3622195f43b9._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-05-06T15:08:19Z"
+ content="""
+As it stands, using the \"source\" repository type will tend to remove the picture from that repository pretty quickly, assuming a fast network connection. I think if you want to do things on your phone with pictures you take, it's best to use \"client\" instead. Perhaps with an archive repository set up, so you can move stuff to an \"archive\" folder when done with it to get it removed from the phone.
+
+Whether \"source\" is a good default in this case remains to be seen...
+
+It might also be possible to change \"source\" in some way to make it more useful. For example, if it held onto new files for a day after they were created, you'd have plenty of time to use them before they expire off your phone. I have posted some thoughts about this to [[partial_content]].
+"""]]
diff --git a/doc/design/assistant/blog/day_255__Debian_release_day.mdwn b/doc/design/assistant/blog/day_255__Debian_release_day.mdwn
new file mode 100644
index 000000000..9c41ab2b2
--- /dev/null
+++ b/doc/design/assistant/blog/day_255__Debian_release_day.mdwn
@@ -0,0 +1,26 @@
+Created a backport of the latest git-annex release for Debian 7.0 wheezy.
+Needed to backport a dozen haskell dependencies, but not too bad.
+This will be available in the backports repository once Debian
+starts accepting new packages again. I plan to keep the backport up-to-date
+as I make new releases.
+
+The cheap Android tablet I bought to do this last Android push with came
+pre-rooted from the factory. This may be why I have not seen this bug:
+[[bugs/Android_app_permission_denial_on_startup]]. If you have Android
+4.2.2 or a similar version, your testing would be helpful for me to know if
+this is a widespread problem. I have an idea about a way to work around the
+problem, but it involves writing Java code, and probably polling a file,
+ugh.
+
+Got S3 support to build for Android. Probably fails to work
+due to the same network stack problems affecting WebDAV and Jabber.
+
+Got removable media mount detection working on Android. Bionic has an
+amusing stub for `getmntent` that prints out "FIX ME! implement
+getmntent()". But, `/proc/mounts` is there, so I just parse it.
+Also enabled the app's `WRITE_MEDIA_STORAGE` permission to allow
+access to removable media. However, this didn't seem to do anything. :(
+
+Several fixes to make the Android webapp be able to set up repositories on
+remote ssh servers. However, it fails at the last hurdle with what
+looks like a `git-annex-shell` communication problem. Almost there..
diff --git a/doc/design/assistant/blog/day_256__8bit.mdwn b/doc/design/assistant/blog/day_256__8bit.mdwn
new file mode 100644
index 000000000..1155fd2f8
--- /dev/null
+++ b/doc/design/assistant/blog/day_256__8bit.mdwn
@@ -0,0 +1,27 @@
+This seems a very auspicious day to have finally gotten the Android app
+doing something useful! I've fixed the last bugs with using it to set up a
+remote ssh server, which is all I need to make my Android tablet
+sync photos I take with a repository on my laptop.
+
+[[!img /android/DCIM.png alt="git-annex webapp running on Android"]]
+
+I set this up entirely in the GUI, except for needing to switch to the
+terminal twice to enter my laptop's password.
+
+How fast is it? Even several minute long videos transfer before I can
+switch from the camera app to the webapp. To get this screenshot with it in
+the process of syncing, I had to take a dozen pictures in a minute. Nice
+problem to have. ;)
+
+Have fun trying this out for yourself after tonight's autobuilds. But a
+warning: One of the bugs I fixed today had to be fixed in `git-annex-shell`,
+as run on the ssh server that the Android connects to. So the Android app
+will only work with ssh servers running a new enough version of git-annex.
+
+----
+
+Worked on geting git-annex into Debian testing, which is needed before
+the wheezy backport can go in. Think I've worked around most of the issues
+that were keeping it from building on various architectures.
+
+Caught up on some bug reports and fixed some of them.
diff --git a/doc/design/assistant/blog/day_256__8bit/comment_1_f9b50263e3997d4c5b9836a2e0a346d7._comment b/doc/design/assistant/blog/day_256__8bit/comment_1_f9b50263e3997d4c5b9836a2e0a346d7._comment
new file mode 100644
index 000000000..b7c54ed58
--- /dev/null
+++ b/doc/design/assistant/blog/day_256__8bit/comment_1_f9b50263e3997d4c5b9836a2e0a346d7._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm8wY171R5c4u_jPmB6LU6n6Px2xePM4sE"
+ nickname="Efraim"
+ subject="comment 1"
+ date="2013-05-07T06:20:35Z"
+ content="""
+that's amazing. I saw in one of the conference videos that you said you didn't use dropbox, and I wanted to let you know (in case you were curious) that this is one of the features that they have on their android app, that pictures and videos are uploaded to one's dropbox. Two questions, is there a toggle or option somewhere to upload over wifi only? and did you set up the tablet's camera folder as a source directory?
+"""]]
diff --git a/doc/design/assistant/blog/day_257__rainy_day.mdwn b/doc/design/assistant/blog/day_257__rainy_day.mdwn
new file mode 100644
index 000000000..871e5b8b5
--- /dev/null
+++ b/doc/design/assistant/blog/day_257__rainy_day.mdwn
@@ -0,0 +1,6 @@
+Put in a fix for `getprotobyname` apparently not returning anything for
+"tcp" on Android. This might fix all the special remotes there, but I don't
+know yet, because I have to rebuild a lot of Haskell libraries to try it.
+
+So, I spent most of today writing a script to build all the Haskell
+libraries for Android from scratch, with all my patches.
diff --git a/doc/design/assistant/blog/day_258__beginning_of_the_end.mdwn b/doc/design/assistant/blog/day_258__beginning_of_the_end.mdwn
new file mode 100644
index 000000000..e2e544399
--- /dev/null
+++ b/doc/design/assistant/blog/day_258__beginning_of_the_end.mdwn
@@ -0,0 +1,24 @@
+Fixed a nasty bug that affects at least some FreeBSD systems. It misparsed
+the output of `sha256`, and thought every file had a SHA256 of "SHA256".
+Added multiple layers of protection against checksum programs not having
+the expected output format.
+
+Lots more building and rebuilding today of Android libs than I wanted to do.
+Finally have a completly clean build, which might be able to open TCP
+connections. Will test tomorrow.
+
+In the meantime, I fired up the evil twin of my development laptop.
+It's identical, except it runs Windows.
+
+I installed the Haskell Platform for Windows on it, and removed
+some of the bloatware to free up disk space and memory for development.
+While a rather disgusting experience, I certainly have a usable Haskell
+development environment on this OS a lot faster than I did on Android!
+Cabal is happily installing some stuff, and other stuff wants me to install
+Cygwin.
+
+So, the clock on my month of working on a Windows port starts now. Since
+I've already done rather a lot of ground work that was necessary for a
+Windows port (direct mode, crippled filesystem support), and for general
+sanity and to keep everything else from screeching to a halt, I plan to
+only spend half my time messing with Windows over the next 30 days.
diff --git a/doc/design/assistant/blog/day_259__Android_dominos_toppling.mdwn b/doc/design/assistant/blog/day_259__Android_dominos_toppling.mdwn
new file mode 100644
index 000000000..3f96b1fb0
--- /dev/null
+++ b/doc/design/assistant/blog/day_259__Android_dominos_toppling.mdwn
@@ -0,0 +1,15 @@
+It all came together for Android today. Went from a sort of working app
+to a fully working app!
+
+* rsync.net works.
+* Box.com appears to work -- at least it's failing with the same
+ timeout I get on my linux box here behind the firewall of dialup doom.
+* XMPP is working too!
+
+These all needed various little fixes. Like loading TLS certificates from
+where they're stored on Android, and ensuring that totally crazy file
+permissions from Android (----rwxr-x for files?!) don't leak out into rsync
+repositories. Mostly though, it all just fell into place today.
+Wonderful..
+
+The Android autobuild is updated with all of today's work, so try it out.
diff --git a/doc/design/assistant/blog/day_259__Android_dominos_toppling/comment_1_0b4a6e4893b0157e4768b46468dbbb87._comment b/doc/design/assistant/blog/day_259__Android_dominos_toppling/comment_1_0b4a6e4893b0157e4768b46468dbbb87._comment
new file mode 100644
index 000000000..9e1f666aa
--- /dev/null
+++ b/doc/design/assistant/blog/day_259__Android_dominos_toppling/comment_1_0b4a6e4893b0157e4768b46468dbbb87._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkGCmVc5qIJaQQgG82Hc5zzBdAVdhe2JEM"
+ nickname="Bruno"
+ subject="comment 1"
+ date="2013-05-10T23:52:43Z"
+ content="""
+I have a 'Connection timed out' when I try to set-up my Gtalk account on my Nexus 4 (4.2.2). I tested it at home without a web proxy.
+
+Here's a screen capture: [http://i.imgur.com/RBcNjSv.png](http://i.imgur.com/RBcNjSv.png).
+"""]]
diff --git a/doc/design/assistant/blog/day_259__Android_dominos_toppling/comment_2_1ebc5aff5d217e1392cb7c8bb6c5156b._comment b/doc/design/assistant/blog/day_259__Android_dominos_toppling/comment_2_1ebc5aff5d217e1392cb7c8bb6c5156b._comment
new file mode 100644
index 000000000..cfe1347bd
--- /dev/null
+++ b/doc/design/assistant/blog/day_259__Android_dominos_toppling/comment_2_1ebc5aff5d217e1392cb7c8bb6c5156b._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmmLfBDEDFfEOba8Ra46nsnTmoNHFsLObo"
+ nickname="Brian"
+ subject="I also see the connection timed out"
+ date="2013-05-15T00:19:34Z"
+ content="""
+Same Android device and same behavior as the above comment. While the connection attempt was being made, I switched to the terminal window and saw a connection to 173.194.46.86:5222 in the SYN_SENT state (and that connection wasn't there prior to the jabber configuration attempt).
+
+Even from my desktop, manual connection attempts to 173.194.46.86:5222 timed out.
+
+Then I ran the same jabber configuration from my desktop and it worked fin. Using netstat, I could see it connected to 74.125.133.125:5222.
+
+So is the Android version using the wrong address?
+"""]]
diff --git a/doc/design/assistant/blog/day_259__Android_dominos_toppling/comment_3_eed7792f6142f3fc74d3c384bb16559b._comment b/doc/design/assistant/blog/day_259__Android_dominos_toppling/comment_3_eed7792f6142f3fc74d3c384bb16559b._comment
new file mode 100644
index 000000000..245ae7a06
--- /dev/null
+++ b/doc/design/assistant/blog/day_259__Android_dominos_toppling/comment_3_eed7792f6142f3fc74d3c384bb16559b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-05-19T20:56:25Z"
+ content="""
+For the record, there was a bug with XMPP and SRV records. This got fixed in time for the last release.
+"""]]
diff --git a/doc/design/assistant/blog/day_25__transfer_queueing.mdwn b/doc/design/assistant/blog/day_25__transfer_queueing.mdwn
new file mode 100644
index 000000000..b07e4592e
--- /dev/null
+++ b/doc/design/assistant/blog/day_25__transfer_queueing.mdwn
@@ -0,0 +1,41 @@
+So as not to bury the lead, I've been hard at work on my first day in
+Nicaragua, and ** the git-annex assistant fully syncs files (including
+their contents) between remotes now !! **
+
+Details follow..
+
+Made the committer thread queue Upload Transfers when new files
+are added to the annex. Currently it tries to transfer the new content
+to *every* remote; this inefficiency needs to be addressed later.
+
+Made the watcher thread queue Download Transfers when new symlinks
+appear that point to content we don't have. Typically, that will happen
+after an automatic merge from a remote. This needs to be improved as it
+currently adds Transfers from every remote, not just those that have the
+content.
+
+This was the second place that needed an ordered list of remotes
+to talk to. So I cached such a list in the DaemonStatus state info.
+This will also be handy later on, when the webapp is used to add new
+remotes, so the assistant can know about them immediately.
+
+Added YAT (Yet Another Thread), number 15 or so, the transferrer thread
+that waits for transfers to be queued and runs them. Currently a naive
+implementation, it runs one transfer at a time, and does not do anything
+to recover when a transfer fails.
+
+Actually transferring content requires YAT, so that the transfer
+action can run in a copy of the Annex monad, without blocking
+all the assistant's other threads from entering that monad while a transfer
+is running. This is also necessary to allow multiple concurrent transfers
+to run in the future.
+
+This is a very tricky piece of code, because that thread will modify the
+git-annex branch, and its parent thread has to invalidate its cache in
+order to see any changes the child thread made. Hopefully that's the extent
+of the complication of doing this. The only reason this was possible at all
+is that git-annex already support multiple concurrent processes running
+and all making independent changes to the git-annex branch, etc.
+
+After all my groundwork this week, file content transferring is now
+fully working!
diff --git a/doc/design/assistant/blog/day_25__transfer_queueing/comment_1_59fd4f1ffe96c412f613dc86276e7dbd._comment b/doc/design/assistant/blog/day_25__transfer_queueing/comment_1_59fd4f1ffe96c412f613dc86276e7dbd._comment
new file mode 100644
index 000000000..0a5b6c099
--- /dev/null
+++ b/doc/design/assistant/blog/day_25__transfer_queueing/comment_1_59fd4f1ffe96c412f613dc86276e7dbd._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawldKnauegZulM7X6JoHJs7Gd5PnDjcgx-E"
+ nickname="Matt"
+ subject="Source code"
+ date="2012-07-06T00:12:15Z"
+ content="""
+Hi Joey,
+
+Is the source code for git-annex assistant available somewhere?
+"""]]
diff --git a/doc/design/assistant/blog/day_25__transfer_queueing/comment_2_93bf768a67117e873af5732ecf08dc78._comment b/doc/design/assistant/blog/day_25__transfer_queueing/comment_2_93bf768a67117e873af5732ecf08dc78._comment
new file mode 100644
index 000000000..6c0ca0781
--- /dev/null
+++ b/doc/design/assistant/blog/day_25__transfer_queueing/comment_2_93bf768a67117e873af5732ecf08dc78._comment
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ subject="comment 2"
+ date="2012-07-06T00:21:43Z"
+ content="""
+It's in the `assistant` branch of git://git-annex.branchable.com/
+"""]]
diff --git a/doc/design/assistant/blog/day_260__Windows_dev_environment.mdwn b/doc/design/assistant/blog/day_260__Windows_dev_environment.mdwn
new file mode 100644
index 000000000..4fa2ccf5a
--- /dev/null
+++ b/doc/design/assistant/blog/day_260__Windows_dev_environment.mdwn
@@ -0,0 +1,46 @@
+Set up my Windows development environment. For future reference, I've
+installed:
+
+* haskell platform for windows
+* cygwin
+* gcc and a full C toolchain in cygwin
+* git from upstream (probably git-annex will use this)
+* git in cygwin (the other git was not visible inside cygwin)
+* vim in cygwin
+* vim from upstream, as the cygwin vim is not very pleasant to use
+* openssh in cygwin (seems to be missing a ssh server)
+* rsync in cygwin
+* Everything that `cabal install git-annex` is able to install successfully.
+ This includes all the libraries needed to build regular git-annex,
+ but not the webapp. Good start though.
+
+Result basically feels like a linux system that can't decide which way
+slashes in paths go. :P I've never used Cygwin before (I last used a
+Windows machine in 2003 for that matter), and it's a fairly impressive hack.
+
+----
+
+Fixed up git-annex's configure program to run on Windows (or, at least, in
+Cygwin), and have started getting git-annex to build.
+
+For now, I'm mostly stubbing out functions that use unix stuff. Gotten the
+first 44 of 300 source files to build this way.
+
+Once I get it to build, if only with stubs, I'll have a good
+idea about all the things I need to find Windows equivilants of.
+Hopefully most of it will be provided by
+<http://hackage.haskell.org/package/unix-compat-0.3.0.1>.
+
+----
+
+So that's the plan. There is a possible shortcut, rather than doing a full
+port. It seems like it would probably not be too hard to rebuild ghc inside
+Cygwin, and the resulting ghc would probably have a full POSIX emulation
+layer going through cygwin. From ghc's documentation, it looks like that's
+how ghc used to be built at some point in the past, so it would probably
+not be too hard to build it that way. With such a cygwin ghc, git-annex
+would probably build with little or no changes. However, it would be a
+git-annex targeting Cygwin, and not really a native Windows port. So
+it'd see Cygwin's emulated POSIX filesystem paths, etc. That
+seems probably not ideal for most windows users.. but if I get really stuck
+I may go back and try this method.
diff --git a/doc/design/assistant/blog/day_261__Windows_first_stage_complete.mdwn b/doc/design/assistant/blog/day_261__Windows_first_stage_complete.mdwn
new file mode 100644
index 000000000..8107336f0
--- /dev/null
+++ b/doc/design/assistant/blog/day_261__Windows_first_stage_complete.mdwn
@@ -0,0 +1,29 @@
+After working on it all day, git-annex now builds on Windows!
+
+Even better, `git annex init` works. So does `git annex status`, and
+probably more. Not `git annex add` yet, so I wasn't able to try much more.
+
+I didn't have to add many stubs today, either. Many of the missing Windows
+features were only used in code paths that made git-annex faster, but I
+could fall back to a slower code path on Windows.
+
+The things that are most problimatic so far:
+
+* POSIX file locking. This is used in git-annex in several places to
+ make it safe when multiple git-annex processes are running. I put in
+ really horrible dotfile type locking in the Windows code paths, but I
+ don't trust it at all of course.
+* There is, apparently, no way to set an environment variable in Windows
+ from Haskell. It is only possible to set up a new process' environment
+ before starting it. Luckily most of the really crucial environment
+ variable stuff in git-annex is of this latter sort, but there were
+ a few places I had to stub out code that tries to manipulate git-annex's
+ own environment.
+
+The `windows` branch has a diff of 2089 lines. It add 88 ifdefs to the code
+base. Only 12 functions are stubbed out on Windows. This could be so much
+worse.
+
+Next step: Get the test suite to build. Currently ifdefed out because it
+uses some stuff like `setEnv` and `changeWorkingDirectory` that I don't know
+how to do in Windows yet.
diff --git a/doc/design/assistant/blog/day_262__DOS_path_separators.mdwn b/doc/design/assistant/blog/day_262__DOS_path_separators.mdwn
new file mode 100644
index 000000000..a7f6c07cc
--- /dev/null
+++ b/doc/design/assistant/blog/day_262__DOS_path_separators.mdwn
@@ -0,0 +1,14 @@
+It's remarkable that a bad decision made in 1982 can cause me to waste an
+entire day in 2013. Yes, `/` vs `\` fun time. Even though I long ago
+converted git-annex to use the haskell `</>` operator wherever it builds
+up paths (which transparently handles either type of separator), I still
+spent most of today dealing with it. Including some libraries I use that
+get it wrong. Adding to the fun is that git uses `/` internally, even on
+Windows, so Windows separated paths have to be converted when being fed
+into git.
+
+Anyway, `git annex add` now works on Windows. So does `git annex find`,
+and `git annex whereis`, and probably most query stuff.
+
+Today was very un-fun and left me with a splitting headache, so I will
+certainly *not* be working on the Windows port tomorrow.
diff --git a/doc/design/assistant/blog/day_262__DOS_path_separators/comment_1_45ecae90b22e31202c21083980d6b567._comment b/doc/design/assistant/blog/day_262__DOS_path_separators/comment_1_45ecae90b22e31202c21083980d6b567._comment
new file mode 100644
index 000000000..a024103a7
--- /dev/null
+++ b/doc/design/assistant/blog/day_262__DOS_path_separators/comment_1_45ecae90b22e31202c21083980d6b567._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://jamesjustjames.wordpress.com/"
+ nickname="purpleidea"
+ subject="Isn't windows deprecated?"
+ date="2013-05-13T05:51:20Z"
+ content="""
+I feel bad for you, however I respect you for keeping your promise to try and hack on Windows. I had to port over some code than ran beautifully on GNU/Linux and it was more trouble than it was worth. In the end it was never used :P
+
+Cheers!
+"""]]
diff --git a/doc/design/assistant/blog/day_263_catching_up.mdwn b/doc/design/assistant/blog/day_263_catching_up.mdwn
new file mode 100644
index 000000000..b8eadbc96
--- /dev/null
+++ b/doc/design/assistant/blog/day_263_catching_up.mdwn
@@ -0,0 +1,11 @@
+Spent some time today to get caught up on bug reports and website traffic.
+Fixed a few things.
+
+Did end up working on Windows for a while too. I got `git annex drop`
+working. But nothing that moves content quite works yet..
+
+I've run into a stumbling block with `rsync`. It thinks that
+`C:\repo` is a path on a ssh server named "C". Seems I will need to translate
+native windows paths to unix-style paths when running rsync.
+
+[[!meta date="13 May 2013"]]
diff --git a/doc/design/assistant/blog/day_263_catching_up/comment_1_9023da0573dfc81644d68128adb331a7._comment b/doc/design/assistant/blog/day_263_catching_up/comment_1_9023da0573dfc81644d68128adb331a7._comment
new file mode 100644
index 000000000..83e7523ff
--- /dev/null
+++ b/doc/design/assistant/blog/day_263_catching_up/comment_1_9023da0573dfc81644d68128adb331a7._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkHscTHMCNvjJ6nLI1VpsBrJFI5FTwhUT4"
+ nickname="David"
+ subject="Just use Unix Paths like git does?"
+ date="2013-05-15T20:43:34Z"
+ content="""
+Can't you just use unix-style paths for your internal data structures, and wrap/patch the filesystem I/O code to convert between the two?
+"""]]
diff --git a/doc/design/assistant/blog/day_264__Windows_second_stage_complete.mdwn b/doc/design/assistant/blog/day_264__Windows_second_stage_complete.mdwn
new file mode 100644
index 000000000..f34e8b15e
--- /dev/null
+++ b/doc/design/assistant/blog/day_264__Windows_second_stage_complete.mdwn
@@ -0,0 +1,21 @@
+The Windows port can now do everything in the [[walkthrough]]. It can use
+both local and remote git repositories. Some special remotes work
+(directory at least; probably rsync; likely any other special remote that
+can have its dependencies built). Missing features include most special
+remotes, gpg encryption, and of course, the assistant.
+
+Also built a NullSoft installer for git-annex today. This was made very
+easy when I found the Haskell ncis library, which provides a DSL embedding
+the language used to write NullSoft installers into Haskell. So I didn't
+need to learn a new language, yay! And could pull in all my helpful
+Haskell utility libraries in the program that builds the installer.
+
+The only tricky part was: How to get git-annex onto PATH? The standard way
+to do this seems to be to use a multiple-hundred line include file. Of
+course, that file does not have any declared license.. Instead of that,
+I used a hack. The git installer for Windows adds itself to PATH, and is
+a pre-requisite for git-annex. So the git-annex installer just installs
+it into the same directory as git.
+
+So.. I'll be including this first stage Windows port, with installer in
+the next release. Anyone want to run a Windows autobuilder?
diff --git a/doc/design/assistant/blog/day_264__Windows_second_stage_complete/comment_1_42a7502d6ece75520eb59a76fdb1e2f0._comment b/doc/design/assistant/blog/day_264__Windows_second_stage_complete/comment_1_42a7502d6ece75520eb59a76fdb1e2f0._comment
new file mode 100644
index 000000000..e7846d5fb
--- /dev/null
+++ b/doc/design/assistant/blog/day_264__Windows_second_stage_complete/comment_1_42a7502d6ece75520eb59a76fdb1e2f0._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlJ2utMQgMEYAOs3Dfc6eZRyUzt4acNXUU"
+ nickname="David"
+ subject="git on windows"
+ date="2013-05-15T04:26:48Z"
+ content="""
+Adding git to the PATH variable is an optional step in the msysgit installer, fyi.
+
+"""]]
diff --git a/doc/design/assistant/blog/day_264__Windows_second_stage_complete/comment_2_f2b11322ac87e2a36cddc035b2c3c1ea._comment b/doc/design/assistant/blog/day_264__Windows_second_stage_complete/comment_2_f2b11322ac87e2a36cddc035b2c3c1ea._comment
new file mode 100644
index 000000000..1ff6bd542
--- /dev/null
+++ b/doc/design/assistant/blog/day_264__Windows_second_stage_complete/comment_2_f2b11322ac87e2a36cddc035b2c3c1ea._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 2"
+ date="2013-05-15T22:30:05Z"
+ content="""
+I was thinking maybe migrating away from gitbuilder to using something like buildbot as it seems to be a better fit for this project than gitbuilder.
+"""]]
diff --git a/doc/design/assistant/blog/day_264__Windows_second_stage_complete/comment_3_ea6ee05acb946fc7e8d95e62647cfa2a._comment b/doc/design/assistant/blog/day_264__Windows_second_stage_complete/comment_3_ea6ee05acb946fc7e8d95e62647cfa2a._comment
new file mode 100644
index 000000000..39d2a837d
--- /dev/null
+++ b/doc/design/assistant/blog/day_264__Windows_second_stage_complete/comment_3_ea6ee05acb946fc7e8d95e62647cfa2a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-05-15T22:56:27Z"
+ content="""
+@Jimmy, would be fine with me if it works better
+"""]]
diff --git a/doc/design/assistant/blog/day_264__Windows_second_stage_complete/comment_4_9ce106baf28b7f75f7f6febd7bfcea70._comment b/doc/design/assistant/blog/day_264__Windows_second_stage_complete/comment_4_9ce106baf28b7f75f7f6febd7bfcea70._comment
new file mode 100644
index 000000000..d3ac0df12
--- /dev/null
+++ b/doc/design/assistant/blog/day_264__Windows_second_stage_complete/comment_4_9ce106baf28b7f75f7f6febd7bfcea70._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 4"
+ date="2013-05-16T17:31:40Z"
+ content="""
+joey, I'll poke at it on the weekend, been meaning to look for an excuse to learn a bit more about buildbot.
+"""]]
diff --git a/doc/design/assistant/blog/day_265__correctness.mdwn b/doc/design/assistant/blog/day_265__correctness.mdwn
new file mode 100644
index 000000000..a4415b444
--- /dev/null
+++ b/doc/design/assistant/blog/day_265__correctness.mdwn
@@ -0,0 +1,23 @@
+Laid some groundwork for porting the test suite to Windows, and getting it
+working in direct mode. That's not complete, but even starting to run the
+test suite in direct mode and looking at all the failures (many of them
+benign, like files not being symlinks) highlighted something
+I have been meaning to look into for quite a while: Why, in direct mode,
+`git-annex` doesn't operate on data staged in the index, but requires you
+commit changes to files before it'll see them. That's an annoying
+difference between direct and indirect modes.
+
+It turned out that I introduced this behavior back on
+[[January 5th|day_163__free_features]], working around a nasty
+bug I didn't understand. Bad Joey, should have root caused the bug at the
+time! But the commit says I was stuck on it for hours, and it was
+presenting as if it was a bug in `git cat-file` itself, so ok. Anyway,
+I quickly got to the bottom of it today, fixed the underlying bug (which
+was in git-annex, not git itself), and got rid of the workaround and its
+undesired consequences. Much better.
+
+The test suite is turning up some other minor problems with direct mode.
+Should have found time to port it earlier.
+
+Also, may have fixed the issue that was preventing GTalk from working on
+Android. (Missing DNS library so it didn't do SRV lookups right.)
diff --git a/doc/design/assistant/blog/day_265__correctness/comment_1_e8959a6df87eb92310947e66c7471e97._comment b/doc/design/assistant/blog/day_265__correctness/comment_1_e8959a6df87eb92310947e66c7471e97._comment
new file mode 100644
index 000000000..96731a43e
--- /dev/null
+++ b/doc/design/assistant/blog/day_265__correctness/comment_1_e8959a6df87eb92310947e66c7471e97._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkF8_uQjLYm5Mf5F_JuVW-BxlvzpWjvR_o"
+ nickname="Andrew"
+ subject="Android success"
+ date="2013-05-16T04:14:09Z"
+ content="""
+I now have my android phone and laptop talking with GTalk and used a remote ssh server to synchronise files.
+
+Photos are flowing from my phone to my laptop quite happily. Magic.
+
+Would help to exclude .thumbnails from the DCIM directory on the phone though...
+"""]]
diff --git a/doc/design/assistant/blog/day_265__correctness/comment_2_0cb953fcc085eedb34e65c227309ede7._comment b/doc/design/assistant/blog/day_265__correctness/comment_2_0cb953fcc085eedb34e65c227309ede7._comment
new file mode 100644
index 000000000..cf936cf2a
--- /dev/null
+++ b/doc/design/assistant/blog/day_265__correctness/comment_2_0cb953fcc085eedb34e65c227309ede7._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmubB1Sj2rwFoVdZYvGV0ACaQUJQyiJXJI"
+ nickname="Paul"
+ subject="GTalk/XMPP"
+ date="2013-05-19T09:58:51Z"
+ content="""
+Google seems to be deprecating XMPP and GTalk. Can git-annex assistant use other XMPP services? And does it handle federation correctly?
+"""]]
diff --git a/doc/design/assistant/blog/day_265__correctness/comment_3_df57628a8969af2995732e7ea2a0fae3._comment b/doc/design/assistant/blog/day_265__correctness/comment_3_df57628a8969af2995732e7ea2a0fae3._comment
new file mode 100644
index 000000000..27bee6171
--- /dev/null
+++ b/doc/design/assistant/blog/day_265__correctness/comment_3_df57628a8969af2995732e7ea2a0fae3._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-05-19T19:12:59Z"
+ content="""
+git-annex can use any xmpp server. The only thing that would need to be changed if google talk went away tomorrow is changing some text that suggests entering one's gmail address, to some other text that suggests some other xmpp server to use.
+
+However, I am skeptical about echo chamber conclusions (and/or tech press) about what google is, or is not doing, or is or is not planning to do.
+"""]]
diff --git a/doc/design/assistant/blog/day_266__release_day.mdwn b/doc/design/assistant/blog/day_266__release_day.mdwn
new file mode 100644
index 000000000..8e373c94c
--- /dev/null
+++ b/doc/design/assistant/blog/day_266__release_day.mdwn
@@ -0,0 +1,6 @@
+Made a release.
+
+I am firming up some ideas for post-kickstarter. More on that later.
+
+In the process of setting up a Windows autobuilder, using the same
+jenkins installation that is used to autobuild msysgit.
diff --git a/doc/design/assistant/blog/day_266__release_day/comment_1_92c8d1d9216b46b07dfe69bbc77a923e._comment b/doc/design/assistant/blog/day_266__release_day/comment_1_92c8d1d9216b46b07dfe69bbc77a923e._comment
new file mode 100644
index 000000000..39ff88541
--- /dev/null
+++ b/doc/design/assistant/blog/day_266__release_day/comment_1_92c8d1d9216b46b07dfe69bbc77a923e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmubB1Sj2rwFoVdZYvGV0ACaQUJQyiJXJI"
+ nickname="Paul"
+ subject="Continued work"
+ date="2013-05-17T07:44:38Z"
+ content="""
+Can we continue to fund your work in some way?
+"""]]
diff --git a/doc/design/assistant/blog/day_267__windows_autobuilder.mdwn b/doc/design/assistant/blog/day_267__windows_autobuilder.mdwn
new file mode 100644
index 000000000..b9e28438d
--- /dev/null
+++ b/doc/design/assistant/blog/day_267__windows_autobuilder.mdwn
@@ -0,0 +1,9 @@
+git-annex is now autobuilt for Windows on the same Jenkins farm that
+builds msysgit. Thanks for Yury V. Zaytsev for providing that! Spent about
+half of today setting up the build.
+
+Got the test suite to pass in direct mode, and indeed in direct mode
+on a FAT file system. Had to fix one corner case in direct mode `git annex
+add`. Unfortunately it still doesn't work on Android; somehow `git clone`
+of a local repository is broken there. Also got the test suite to build,
+and run on Windows, though it fails pretty miserably.
diff --git a/doc/design/assistant/blog/day_267__windows_autobuilder/comment_1_978b584d86395f2f621b0e1f7c5e70d7._comment b/doc/design/assistant/blog/day_267__windows_autobuilder/comment_1_978b584d86395f2f621b0e1f7c5e70d7._comment
new file mode 100644
index 000000000..ccda628ae
--- /dev/null
+++ b/doc/design/assistant/blog/day_267__windows_autobuilder/comment_1_978b584d86395f2f621b0e1f7c5e70d7._comment
@@ -0,0 +1,21 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkDb5BRI8VzliQuKRVM7NwMdudvxiUNPHI"
+ nickname="Richard"
+ subject="git annex add on Win7 NTFS"
+ date="2013-06-14T09:26:24Z"
+ content="""
+Hello I took latest build from download #243.
+
+running in CMD or in GIT bash as admin user.
+
+git annex add, fails on all files.
+
+Example:
+add IS Breast/Changing IP Address of The Server/flowplayer-3.2.4.min.js (checksum...)
+git-annex: C:\development storage\.git\annex\objects\e4b\168\SHA256E-s15723--f6950
+bd995674741c600d0465a333f5491d5713e8ac2e3fc57d61cccadba522d.min.js\SHA256E-s15723--f6950bd995674741c600d0465a333f5491d57
+13e8ac2e3fc57d61cccadba522d.min.js.cache: openFile: does not exist (No such file or directory)
+
+Am I doing something wrong? I somehow understood that this should be ok now.
+Thanks for your kind answer
+"""]]
diff --git a/doc/design/assistant/blog/day_267__windows_autobuilder/comment_2_8f978d2811c8fbf11e3d12f245bdb52b._comment b/doc/design/assistant/blog/day_267__windows_autobuilder/comment_2_8f978d2811c8fbf11e3d12f245bdb52b._comment
new file mode 100644
index 000000000..796dea21e
--- /dev/null
+++ b/doc/design/assistant/blog/day_267__windows_autobuilder/comment_2_8f978d2811c8fbf11e3d12f245bdb52b._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.193"
+ subject="comment 2"
+ date="2013-06-25T17:12:17Z"
+ content="""
+That is the same problem that is currently making the test suite fail on the windows autobuilder.
+
+I don't know what is causing this problem, and have not been able to reproduce it locally in order to debug it.
+"""]]
diff --git a/doc/design/assistant/blog/day_268__core_monad_change.mdwn b/doc/design/assistant/blog/day_268__core_monad_change.mdwn
new file mode 100644
index 000000000..2704bb090
--- /dev/null
+++ b/doc/design/assistant/blog/day_268__core_monad_change.mdwn
@@ -0,0 +1,9 @@
+Today I had to change the implementation of the Annex monad. The old one
+turned out to be buggy around exception handling -- changes to state
+recorded by code that ran in an exception handler were discarded when it
+threw an exception. Changed from a StateT monad to a ReaderT with
+a MVar. Really deep-level change, but it went off without a
+hitch!
+
+Other than that it was a bug catch up day. Almost entirely caught up once
+more.
diff --git a/doc/design/assistant/blog/day_269__bugfixes.mdwn b/doc/design/assistant/blog/day_269__bugfixes.mdwn
new file mode 100644
index 000000000..7cbdb5863
--- /dev/null
+++ b/doc/design/assistant/blog/day_269__bugfixes.mdwn
@@ -0,0 +1,14 @@
+Worked on several important bug fixes today. One affects automatic merge
+confict resolution, and can case data loss in direct mode, so I will be
+making a release with the fix tomorrow.
+
+Practiced TDD today, and good thing too. The new improved test suite
+turned up a really subtle bug involving the git-annex branch vector
+clocks-ish code, which I also fixed.
+
+Also, fixes to the OSX autobuilds. One of them had a broken gpg, which is
+now fixed. The other one is successfully building again. And, I'm switching
+the Linux autobuilds to build against Debian stable, since testing has a
+new version of libc now, which would make the autobuilds not work on older
+systems. Getting an amd64 chroot into shape is needing rather a lot
+of backporting of build dependencies, which I already did for i386.
diff --git a/doc/design/assistant/blog/day_26__dying_drives.mdwn b/doc/design/assistant/blog/day_26__dying_drives.mdwn
new file mode 100644
index 000000000..109ceb19e
--- /dev/null
+++ b/doc/design/assistant/blog/day_26__dying_drives.mdwn
@@ -0,0 +1,28 @@
+My laptop's SSD died this morning. I had some work from yesterday
+committed to the git repo on it, but not pushed as it didn't build.
+Luckily I was able to get that off the SSD, which is now a read-only
+drive -- even mounting it fails with fsck write errors.
+
+Wish I'd realized the SSD was dying before the day before my trip to
+Nicaragua..
+Getting back to a useful laptop used most of my time and energy today.
+
+I did manage to fix transfers to not block the rest of the assistant's
+threads. Problem was that, without Haskell's threaded runtime, waiting
+on something like a rsync command blocks all threads. To fix this,
+transfers now are run in separate processes.
+
+Also added code to allow multiple transfers to run at once. Each transfer
+takes up a slot, with the number of free slots tracked by a `QSemN`.
+This allows the transfer starting thread to block until a slot frees up,
+and then run the transfer.
+
+This needs to be extended to be aware of transfers initiated by remotes.
+The transfer watcher thread should detect those starting and stopping
+and update the `QSemN` accordingly. It would also be nice if transfers
+initiated by remotes would be delayed when there are no free slots for them
+... but I have not thought of a good way to do that.
+
+There's a bug somewhere in the new transfer code, when two transfers are
+queued close together, the second one is lost and doesn't happen.
+Would debug this, but I'm spent for the day.
diff --git a/doc/design/assistant/blog/day_270__release_and_xmpp.mdwn b/doc/design/assistant/blog/day_270__release_and_xmpp.mdwn
new file mode 100644
index 000000000..eb28f97bd
--- /dev/null
+++ b/doc/design/assistant/blog/day_270__release_and_xmpp.mdwn
@@ -0,0 +1,39 @@
+Got the bugfix release out.
+
+Tobias contributed [[tips/megaannex]], which allows using mega.co.nz as a
+special remote. Someone should do this with Flickr, using
+[filr](https://github.com/ricardobeat/filr). I have improved the
+[[special_remotes/hook]] special remote to make it easier to create
+and use reusable programs like megaannex.
+
+But, I am too busy rewriting lots of the XMPP code to join in the
+special remote fun. Spent all last night staring at protocol traces and
+tests, and came to the conclusion that it's working well at the basic
+communication level, but there are a lot of bugs above that level. This
+mostly shows up as one side refusing to push changes made to its tree,
+although it will happily merge in changes sent from the other side.
+
+The NetMessanger code, which handles routing messages to git commands and
+queuing other messages, seems to be just wrong. This is code I wrote in the
+fall, and have basically not touched since. And it shows. Spent 4 hours
+this morning rewriting it. Went all Erlang and implemented message inboxes
+using STM. I'm much more confident it won't drop messages on the
+floor, which the old code certainly did do sometimes.
+
+Added a check to avoid unnecessary pushes over XMPP. Unfortunately, this
+required changing the protocol in a way that will make previous versions of
+git-annex refuse to accept any pushes advertised by this version. Could not
+find a way around that, but there were so many unnecessary pushes happening
+(and possibly contributing to other problems) that it seemed worth the
+upgrade pain.
+
+Will be beating on XMPP a bit more. There is one problem I was seeing
+last night that I cannot reproduce now. It may have been masked or even
+fixed by these changes, but I need to verify that, or put in a workaround.
+It seemed that sometimes this code in `runPush` would run the setup
+and the action, but either the action blocked forever, or an exception
+got through and caused the cleanup not to be run.
+
+[[!format haskell """
+ r <- E.bracket_ setup cleanup <~> a
+"""]]
diff --git a/doc/design/assistant/blog/day_271__more_xmpp.mdwn b/doc/design/assistant/blog/day_271__more_xmpp.mdwn
new file mode 100644
index 000000000..14e734a2d
--- /dev/null
+++ b/doc/design/assistant/blog/day_271__more_xmpp.mdwn
@@ -0,0 +1,31 @@
+Tobias has been busy again today, creating a [[/tips/flickrannex]]
+special remote! Meanwhile, I'm thinking about providing a
+[[more complete interface|/todo/support_for_writing_external_special_remotes]]
+so that special remote programs not written in Haskell can do some of the
+things the hook special remote's simplicity doesn't allow.
+
+Finally realized last night that the main problem with the XMPP push code
+was an inversion of control. Reworked it so now there are two new threads,
+XMPPSendpack and XMPPReceivePack, each with their own queue of push
+initiation requests, that run the pushes. This is a lot easier to
+understand, probably less buggy, and lets it apply some smarts to squash
+duplicate actions and pick the best request to handle next.
+
+Also made the XMPP client send pings to detect when it has been disconnected
+from the server. Currently every 120 seconds, though that may change. Testing
+showed that without this, it did not notice (for at least 20 minutes) when
+it lost routing to the server. Not sure why -- I'd think the TCP connections
+should break and this throw an error -- but this will also handle any idle
+disconnection problems that some XMPP servers might have.
+
+While writing that, I found myself writing this jem using
+[async](http://hackage.haskell.org/package/async), which has a comment
+much longer than the code, but basically we get 4 threads that are all
+linked, so when any dies, all do.
+
+[[!format haskell """
+pinger `concurrently` sender `concurrently` receiver
+"""]]
+
+Anyway, I need to run some long-running XMPP push tests to see if I've
+really ironed out all the bugs.
diff --git a/doc/design/assistant/blog/day_272__fuzz_tester.mdwn b/doc/design/assistant/blog/day_272__fuzz_tester.mdwn
new file mode 100644
index 000000000..9d352f70a
--- /dev/null
+++ b/doc/design/assistant/blog/day_272__fuzz_tester.mdwn
@@ -0,0 +1,37 @@
+The Android app should work on some more devices now, where hard linking to
+busybox didn't work. Now it installs itself using symlinks.
+
+Pushed a point release so `cabal install git-annex` works again. And,
+I'm really happy to see that the 4.20130521 release has autobuilt on all
+Debian architectures, and will soon be replacing the old 3.20120629 version
+in testing. (Well, once a libffi transition completes..)
+
+TobiasTheMachine has done it again: [[tips/googledriveannex]]
+
+-----
+
+I spent most of today building a fuzz tester for the assistant. `git annex
+fuzztest` will (once you find the special runes to allow it to run) create
+random files in the repository, move them around, delete them, move
+directory trees around, etc. The plan is to use this to run some long
+duration tests with eg, XMPP, to make sure the assistant keeps things
+in shape after a lot of activity. It logs in machine-readable format,
+so if it turns up a bug I may even be able to use it to reproduce the same
+bug (fingers crossed).
+
+I was able to use QuickCheck to generate random data for some parts of the fuzz
+tester. (Though the actual file names it uses are not generated using
+QuickCheck.) Liked this part:
+
+[[!format haskell """
+instance Arbitrary FuzzAction where
+ arbitrary = frequency
+ [ (100, FuzzAdd <$> arbitrary)
+ , (10, FuzzDelete <$> arbitrary)
+ , (10, FuzzMove <$> arbitrary <*> arbitrary)
+ , (10, FuzzModify <$> arbitrary)
+ , (10, FuzzDeleteDir <$> arbitrary)
+ , (10, FuzzMoveDir <$> arbitrary <*> arbitrary)
+ , (10, FuzzPause <$> arbitrary)
+ ]
+"""]]
diff --git a/doc/design/assistant/blog/day_273-274__fun.mdwn b/doc/design/assistant/blog/day_273-274__fun.mdwn
new file mode 100644
index 000000000..2fa12003a
--- /dev/null
+++ b/doc/design/assistant/blog/day_273-274__fun.mdwn
@@ -0,0 +1,19 @@
+Got caught up on some bug reports yesterday. The main one was odd behavior
+of the assistant when the repository was in manual mode. A recent change to
+the preferred content expression caused it. But the expression was not
+broken. The problem was in the parser, which got the parentheses wrong
+in this case. I had to mostly rewrite the parser, unfortunately. I've tested
+the new one fairly extensively -- on the other hand this bug lurked in the
+old parser for several years (this same code is used for matching files
+with command-line parameters).
+
+Just as I finished with that, I noticed another bug. Turns out git-cat-file
+doesn't reload the index after it's started. So last week's changes to make
+git-annex check the state of files in the index won't work when using the
+assistant. Luckily there was an easy workaround for this.
+
+Today I finished up some robustness fixes, and added to the test suite
+checks for preferred content expressions, manual mode, etc.
+
+I've started a stress test, syncing 2 repositories over XMPP, with the fuzz
+tester running in each to create lots of changes to keep in sync.
diff --git a/doc/design/assistant/blog/day_275__working_hard_or.mdwn b/doc/design/assistant/blog/day_275__working_hard_or.mdwn
new file mode 100644
index 000000000..b667ba08a
--- /dev/null
+++ b/doc/design/assistant/blog/day_275__working_hard_or.mdwn
@@ -0,0 +1,12 @@
+Fuzz tester has found several interesting bugs that I've now fixed. It's
+even found a bug in my fixes. Most of the problems the fuzz testing has
+found have had to do with direct mode merges, and automatic merge conflict
+resoltion. Turns out the second level of automatic merge conflict
+resolution (where the changes made to resolve a merge conflict themselves
+turn out conflict in a later merge) was buggy, for example.
+
+So, didn't really work a lot today -- was not intending to work at all
+actually -- but have still accomplished a lot.
+
+(Also, Tobias contributed [[tips/dropboxannex]] .. I'll be curious to see
+what the use case for that is, if any!)
diff --git a/doc/design/assistant/blog/day_276__fuzzing_continues.mdwn b/doc/design/assistant/blog/day_276__fuzzing_continues.mdwn
new file mode 100644
index 000000000..d6fc88b05
--- /dev/null
+++ b/doc/design/assistant/blog/day_276__fuzzing_continues.mdwn
@@ -0,0 +1,12 @@
+The fuzz testing found a file descriptor leak in the XMPP git push code.
+The assistant seems to hold up under fuzzing for quite a while now.
+
+Have started trying to work around some versions of Android not letting
+the `am` command be used by regular users to open a web browser on an URL.
+Here is my current crazy plan: Hack the terminal emulator's title setting
+code, to get a new escape sequence that requests an URL be opened. This
+assumes I can just use `startActivity()` from inside the app and it will
+work. This may sound a little weird, but it avoids me needing to set up a
+new communications channel from the assistant to the Java app. Best of all,
+I have to write very little Java code. I last wrote Java code in 1995, so
+writing much more is probably a good thing to avoid.
diff --git a/doc/design/assistant/blog/day_276__fuzzing_continues/comment_1_f5dd0658511a1063c2eb025b0fe98426._comment b/doc/design/assistant/blog/day_276__fuzzing_continues/comment_1_f5dd0658511a1063c2eb025b0fe98426._comment
new file mode 100644
index 000000000..4a54fa188
--- /dev/null
+++ b/doc/design/assistant/blog/day_276__fuzzing_continues/comment_1_f5dd0658511a1063c2eb025b0fe98426._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkGCmVc5qIJaQQgG82Hc5zzBdAVdhe2JEM"
+ nickname="Bruno"
+ subject="comment 1"
+ date="2013-05-28T03:23:50Z"
+ content="""
+Does the Android application use a [WakeLock](https://developer.android.com/reference/android/os/PowerManager.WakeLock.html) to ensure syncing happens even if the device screen goes off?
+
+I'm under the impression that it doesn't since it took a very long time to sync the first time (before I used the terminal's options to prevent the phone from sleeping).
+
+I think that option shouldn't be left on since it would waste the battery and I think the application should block sleep mode only when syncing.
+
+I might be wrong. I never had to use a WakeLock on Android yet.
+"""]]
diff --git a/doc/design/assistant/blog/day_276__fuzzing_continues/comment_2_a56c4c26a9e7bb8cfe3f598dbeed0813._comment b/doc/design/assistant/blog/day_276__fuzzing_continues/comment_2_a56c4c26a9e7bb8cfe3f598dbeed0813._comment
new file mode 100644
index 000000000..3a98c8a09
--- /dev/null
+++ b/doc/design/assistant/blog/day_276__fuzzing_continues/comment_2_a56c4c26a9e7bb8cfe3f598dbeed0813._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-05-29T16:30:20Z"
+ content="""
+The terminal has options to take the wake lock, and also the wifi lock, in its menu.
+
+Currently this has to be managed manually. The assistant does not try to deal with this.
+"""]]
diff --git a/doc/design/assistant/blog/day_277__private_static_protected_void.mdwn b/doc/design/assistant/blog/day_277__private_static_protected_void.mdwn
new file mode 100644
index 000000000..dbe2244a0
--- /dev/null
+++ b/doc/design/assistant/blog/day_277__private_static_protected_void.mdwn
@@ -0,0 +1,19 @@
+Yeah, Java hacking today. I have something that I think should deal with
+the [[bugs/Android_app_permission_denial_on_startup]] problem. Added a "Open
+WebApp" item to the terminal's menu, which should behave as advertised.
+This is available in the Android daily build now, if your device has that
+problem.
+
+I was not able to get the escape sequence hack to work. I had no difficulty
+modifying the terminal to send an intent to open an url when it received a
+custom escape sequence. But sending the intent just seemed to lock up the
+terminal for a minute without doing anything. No idea why. I had to propigate a
+context object in to the terminal emulator through several layers of objects.
+Perhaps that doesn't really work despite what I [read on stackoverflow](http://stackoverflow.com/questions/9051849/opening-a-link-in-the-browser/9052208#9052208).
+
+Anyway, that's all I have time to do. It would be nice if I, or some other
+interested developer who is more comfortable with Java, could write a custom
+Android frontend app, that embedded a web browser widget for the webapp,
+rather than abusing the terminal this way. OTOH, this way does provide the
+bonus of a pretty good terminal and git shell environment for Android to go
+with git-annex.
diff --git a/doc/design/assistant/blog/day_278__winding_down.mdwn b/doc/design/assistant/blog/day_278__winding_down.mdwn
new file mode 100644
index 000000000..824feceaf
--- /dev/null
+++ b/doc/design/assistant/blog/day_278__winding_down.mdwn
@@ -0,0 +1,11 @@
+Winding down work for now, as I prepare for a week at the beach starting in
+2 days. That will be followed by a talk about git-annex at
+[SELF2013](http://www.southeastlinuxfest.org/) in Charlotte NC on June 9th.
+
+Bits & pieces today.
+
+Want to get a release out RSN, but I'm waiting for the previous release
+to finally reach Debian testing, which should happen on Saturday. Luckily I
+hear the beach house has wifi, so I will probably end up cutting the
+release from there. Only other thing I might work on next week is updating
+to yesod 1.2.
diff --git a/doc/design/assistant/blog/day_279__final_release_prep.mdwn b/doc/design/assistant/blog/day_279__final_release_prep.mdwn
new file mode 100644
index 000000000..f209c1ccb
--- /dev/null
+++ b/doc/design/assistant/blog/day_279__final_release_prep.mdwn
@@ -0,0 +1,14 @@
+Landed two final changes before the release..
+
+First, made git-annex detect if any of the several long-running git process
+it talks to have died, and, if yes, restart them. My stress test is reliably
+able to get at least `git cat-file` to crash, and while I don't know why (and
+obviously should follow up by getting a core dump and stack trace of it),
+the assistant needs to deal with this to be robust.
+
+Secondly, wrote rather a lot of Java code to better open the web browser
+when the Android app is started. A thread listens for URLs to be written to
+a FIFO. Creating a FIFO from fortran&#94;Wjava code is .. interesting. Glad to
+see the back of the `am` command; it did me no favors.
+
+AFK
diff --git a/doc/design/assistant/blog/day_27__robust_transfers.mdwn b/doc/design/assistant/blog/day_27__robust_transfers.mdwn
new file mode 100644
index 000000000..49ace417b
--- /dev/null
+++ b/doc/design/assistant/blog/day_27__robust_transfers.mdwn
@@ -0,0 +1,31 @@
+Spent most of the day making file content transfers robust. There were lots
+of bugs, hopefully I've fixed most of them. It seems to work well now,
+even when I throw a lot of files at it.
+
+One of the changes also sped up transfers; it no longer roundtrips to the
+remote to verify it has a file. The idea here is that when the assistant is
+running, repos should typically be fairly tightly synced to their remotes
+by it, so some of the extra checks that the `move` command does are
+unnecessary.
+
+Also spent some time trying to use ghc's threaded runtime, but continue to
+be baffled by the random hangs when using it. This needs fixing eventually;
+all the assistant's threads can potentially be blocked when it's waiting on
+an external command it has run.
+
+Also changed how transfer info files are locked. The lock file is now
+separate from the info file, which allows the TransferWatcher thread to
+notice when an info file is created, and thus actually track transfers
+initiated by remotes.
+
+---
+
+I'm fairly close now to merging the `assistant` branch into `master`.
+The data syncing code is very brute-force, but it will work well enough
+for a first cut.
+
+Next I can either add some repository network mapping, and use graph
+analysis to reduce the number of data transfers, or I can move on to the
+[[webapp]]. Not sure yet which I'll do. It's likely that since DebConf
+begins tomorrow I'll put off either of those big things until after the
+conference.
diff --git a/doc/design/assistant/blog/day_28-35__threaded_runtime_tarpit.mdwn b/doc/design/assistant/blog/day_28-35__threaded_runtime_tarpit.mdwn
new file mode 100644
index 000000000..612dfc514
--- /dev/null
+++ b/doc/design/assistant/blog/day_28-35__threaded_runtime_tarpit.mdwn
@@ -0,0 +1,17 @@
+I didn't plan to work on git-annex much while at DebConf, because the conference
+always prevents the kind of concentration I need. But I unexpectedly also had to deal
+with [three dead drives](http://joeyh.name/blog/entry/I_am_become_Joey_destroyer_of_drives/)
+and illness this week.
+
+That said, I have been trying to debug a problem with git-annex and Haskell's threaded
+runtime all week. It just hangs, randomly. No luck so far isolating why, although I now
+have a branch that hangs fairly reliably, and in which I am trying to whittle the entire
+git-annex code base (all 18 thousand lines!) into a nice test case.
+
+This threaded runtime problem doesn't affect the assistant yet, but if I want to use
+Yesod in developing the webapp, I'll need the threaded runtime, and using the threaded
+runtime in the assistant generally would make it more responsive and less hacky.
+
+Since this is a task I can work on without much concentration, I'll probably keep beating
+on it until I return home. Then I need to spend some quality thinking time on where
+to go next in the assistant.
diff --git a/doc/design/assistant/blog/day_280__yesod.mdwn b/doc/design/assistant/blog/day_280__yesod.mdwn
new file mode 100644
index 000000000..ff02fd02b
--- /dev/null
+++ b/doc/design/assistant/blog/day_280__yesod.mdwn
@@ -0,0 +1,7 @@
+Today marks 1 year since I started working on the git-annex assistant. 280
+solid days of work!
+
+As a background task here at the beach I've been porting git-annex to yesod
+1.2. Finished it today, earlier than expected, and also managed to keep it
+building with older versions. Some tricks kept the number of
+ifdefs reasonably low.
diff --git a/doc/design/assistant/blog/day_280__yesod/comment_1_a42213a8cef71f2b54db18606028136d._comment b/doc/design/assistant/blog/day_280__yesod/comment_1_a42213a8cef71f2b54db18606028136d._comment
new file mode 100644
index 000000000..3a99c2210
--- /dev/null
+++ b/doc/design/assistant/blog/day_280__yesod/comment_1_a42213a8cef71f2b54db18606028136d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkGCmVc5qIJaQQgG82Hc5zzBdAVdhe2JEM"
+ nickname="Bruno"
+ subject="comment 1"
+ date="2013-06-04T12:51:20Z"
+ content="""
+Congrats on the first year Joey!
+"""]]
diff --git a/doc/design/assistant/blog/day_281__back.mdwn b/doc/design/assistant/blog/day_281__back.mdwn
new file mode 100644
index 000000000..03e42c0a5
--- /dev/null
+++ b/doc/design/assistant/blog/day_281__back.mdwn
@@ -0,0 +1,37 @@
+Slowly getting through the bugs that were opened while I was on vacation and
+then I'll try to get to all the comments. 60+ messages to go.
+
+Got git-annex working better on encfs, which does not support hard links in
+paranoid mode. Now git-annex can be used in indirect mode, it doesn't force
+direct mode when hard links are not supported.
+
+Made the Android repository setup special case generate a .gitignore file
+to ignore thumbnails. Which will only start working once the assistant
+gets .gitignore support.
+
+-----
+
+Been thinking today about encrypting XMPP traffic, particularly git push
+data. Of course, XMPP is already encrypted, but that doesn't hide it from
+those entities who have access to the XMPP server or its encryption key.
+So adding client-to-client encryption has been on the TODO list all along.
+
+OTR would be a great way to do it. But I worry that the confirmation steps
+OTR uses to authenticate the recipient would make the XMPP pairing UI harder
+to get through.
+
+Particularly when pairing your own devices over XMPP, with several devices
+involved, you'd need to do a lot of cross-confirmations. It would be better
+there, I think, to just use a shared secret for authentication. (The need
+to enter such a secret on each of your devices before pairing them would
+also provide a way to use different repositories with the same XMPP
+account, so 2birds1stone.)
+
+Maybe OTR confirmations would be ok when setting up sharing with a friend.
+If OTR was not used there, and it just did a Diffie-Hellman key exchange
+during the pairing process, it could be attacked by an active MITM spoofing
+attack. The attacker would then know the keys, and could decrypt future
+pushes. How likely is such an attack? This goes far beyond what we're
+hearing about. Might be best to put in some basic encryption now, so
+we don't have to worry about pushes being passively recorded on the
+server. Comments appreciated.
diff --git a/doc/design/assistant/blog/day_281__back/comment_1_128809c5a2a9f5cc345a10fdbf55be01._comment b/doc/design/assistant/blog/day_281__back/comment_1_128809c5a2a9f5cc345a10fdbf55be01._comment
new file mode 100644
index 000000000..a120cc2d3
--- /dev/null
+++ b/doc/design/assistant/blog/day_281__back/comment_1_128809c5a2a9f5cc345a10fdbf55be01._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlJ2utMQgMEYAOs3Dfc6eZRyUzt4acNXUU"
+ nickname="David"
+ subject="comment 1"
+ date="2013-06-10T23:42:20Z"
+ content="""
+If you do a D-H key exchange and display the key fingerprint on both devices, that would be a pretty strong disincentive against XMPP servers doing a MitM. You only need one victim to casually notice a discrepancy, and it leaves behind a strong proof of tampering.
+"""]]
diff --git a/doc/design/assistant/blog/day_281__back/comment_2_6d0bbdf6ebaff9da399804570f0e606d._comment b/doc/design/assistant/blog/day_281__back/comment_2_6d0bbdf6ebaff9da399804570f0e606d._comment
new file mode 100644
index 000000000..884b2484e
--- /dev/null
+++ b/doc/design/assistant/blog/day_281__back/comment_2_6d0bbdf6ebaff9da399804570f0e606d._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-06-10T23:50:27Z"
+ content="""
+David, along those lines, if a value derived from the D-H key were committed to the git repo, then the MITM would need to maintain two distinct git trees, and translate between them on an ongoing basis. Which is harder. And then if both clients at any point communicated via another channel (ie, local pairing), the forgery would be very noticeable.
+
+Which is not to say that this is necessarily good enough..
+"""]]
diff --git a/doc/design/assistant/blog/day_282-283__caught_up.mdwn b/doc/design/assistant/blog/day_282-283__caught_up.mdwn
new file mode 100644
index 000000000..b097e8d24
--- /dev/null
+++ b/doc/design/assistant/blog/day_282-283__caught_up.mdwn
@@ -0,0 +1,18 @@
+Got caught up on my backlog yesterday.
+
+Part of adding files in direct mode involved removing write permission from
+them temporarily. That turned out to cause problems with some programs that
+open a file repeatedly, and was generally against the principle that direct
+mode files are always directly available. Happily, I was able to get rid of
+that without sacrificing any safety.
+
+Improved syncing to bare repositories. Normally syncing pushes to a
+synced/master branch, which is good for non-bare repositories since git
+does not allow pushing to the currently checked out branch. But for bare
+repositories, this could leave them without a master branch, so cloning
+from them wouldn't work. A funny thing is that git does not really have any
+way to tell if a remote repository is bare or not. Anyway, I did put in a
+fix, at the expense of pushing twice (but the git data should only be
+transferred once anyway).
+
+
diff --git a/doc/design/assistant/blog/day_284__porting.mdwn b/doc/design/assistant/blog/day_284__porting.mdwn
new file mode 100644
index 000000000..f0648b0e1
--- /dev/null
+++ b/doc/design/assistant/blog/day_284__porting.mdwn
@@ -0,0 +1,13 @@
+Today I got to deal with bugs on Android (busted use of `cp` among other
+problems), Windows (fixed a strange hang when adding several files), and
+Linux (`.desktop` files suck and Wine ships a particularly nasty one).
+Pretty diverse!
+
+Did quite a lot of research and thinking on XMPP encryption yesterday, but
+have not run any code yet (except for trying out a D-H exchange in `ghci`).
+I have listed several options on the [[XMPP]] page.
+
+Planning to take a look at
+[[bugs/Handling_of_files_inside_and_outside_archive_directory_at_the_same_time]]
+tomorrow; maybe I can come up with a workaround to avoid it behaving so
+badly in that case.
diff --git a/doc/design/assistant/blog/day_285__fixed_the_archive_directory_loop.mdwn b/doc/design/assistant/blog/day_285__fixed_the_archive_directory_loop.mdwn
new file mode 100644
index 000000000..252dc367f
--- /dev/null
+++ b/doc/design/assistant/blog/day_285__fixed_the_archive_directory_loop.mdwn
@@ -0,0 +1,23 @@
+Yay, I fixed the
+[[bugs/Handling_of_files_inside_and_outside_archive_directory_at_the_same_time]]
+bug!
+At least in direct mode, which thanks to its associated files tracking
+knows when a given file has another file in the repository with the same
+content. Had not realized the behavior in direct mode was so bad, or the
+fix so relatively easy. Pity I can't do the same for indirect mode, but
+the problem is much less serious there.
+
+That was this weekend. Today, I nearly put out a new release (been 2 weeks
+since the last one..), but ran out of time in the end, and need to get the
+OSX autobuilder fixed first, so have deferred it until Friday.
+
+However, I did make some improvements today.
+Added an `annex.debug` git config setting, so debugging can
+be turned on persistently. People seem to expect that to happen when
+checking the checkbox in the webapp, so now it does.
+
+Fixed 3 or 4 bugs in the Windows port. Which actually, has users now, or
+at least one user. It's very handy to actually get real world testing of
+that port.
+
+[[!meta date="Mon, 17 Jun 2013 17:14:04 -0400"]]
diff --git a/doc/design/assistant/blog/day_285__fixed_the_archive_directory_loop/comment_1_1065e756dc6d66aefd214eb8ac5ebe1d._comment b/doc/design/assistant/blog/day_285__fixed_the_archive_directory_loop/comment_1_1065e756dc6d66aefd214eb8ac5ebe1d._comment
new file mode 100644
index 000000000..41494c02f
--- /dev/null
+++ b/doc/design/assistant/blog/day_285__fixed_the_archive_directory_loop/comment_1_1065e756dc6d66aefd214eb8ac5ebe1d._comment
@@ -0,0 +1,25 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 1"
+ date="2013-06-26T08:36:33Z"
+ content="""
+Been pretty bad with keeping the osx builder going, but this should fix it...
+
+
+<pre>
+[jtang@x00 build ((cfb577d...))]$ git diff
+diff --git a/.gitignore b/.gitignore
+index 93bd49e..717b58a 100644
+--- a/.gitignore
++++ b/.gitignore
+@@ -24,3 +24,5 @@ cabal-dev
+ .virthualenv
+ tags
+ Setup
++*.hi
++*.o
+</pre>
+
+The build on OSX leaves some stray files and it complains about it.
+"""]]
diff --git a/doc/design/assistant/blog/day_286__Windows_test_suite.mdwn b/doc/design/assistant/blog/day_286__Windows_test_suite.mdwn
new file mode 100644
index 000000000..f62aa8eb2
--- /dev/null
+++ b/doc/design/assistant/blog/day_286__Windows_test_suite.mdwn
@@ -0,0 +1,19 @@
+One of my Windows fixes yesterday got the test suite close to sort of
+working on Windows, and I spent all day today pounding on it. Fixed
+numerous bugs, and worked around some weird Windows behaviors -- like
+recursively deleting a directory sometimes fails with a permission denied
+error about a file in it, and leaves behind an empty directory. (What!?)
+The most important bug I fixed caused CR to leak into files in the
+git-annex branch from Windows, during a union merge, which was not a good
+thing at all.
+
+At the end of the day, I only have 6 remaining failing test cases on
+Windows. Half of them are some problem where running `git annex sync`
+from the test suite stomps on PATH somehow and prevents xargs from working.
+The rest are probably real bugs in the directory (again something to do
+with recursive directory deletion, hmmm..), hook, and rsync
+special remotes on Windows. I'm punting on those 6 for now, they'll be
+skipped on Windows.
+
+Should be worth today's pain to know in the future when I break
+something that I've oh-so-painfully gotten working on Windows.
diff --git a/doc/design/assistant/blog/day_287__niceness.mdwn b/doc/design/assistant/blog/day_287__niceness.mdwn
new file mode 100644
index 000000000..5fc193353
--- /dev/null
+++ b/doc/design/assistant/blog/day_287__niceness.mdwn
@@ -0,0 +1,13 @@
+Pushed out a release today. While I've somewhat ramped down activity this
+month with the Kickstarter period over and summer trips and events ongoing,
+looking over the changelog I still see a ton of improvements in the 20 days
+since the last release.
+
+Been doing some work to make the assistant daemon be more `nice`. I don't
+want to nice the whole program, because that could make the web interface
+unresponsive. What I am able to do, thanks to Linux violating POSIX, is to
+`nice` certain expensive operations, including the startup scan and the daily
+sanity check. Also, I put in a call to `ionice` (when it's available)
+when `git annex assistant --autostart` is run, so the daemon's
+disk IO will be prioritized below other IO. Hope this keeps it out of your
+way while it does its job.
diff --git a/doc/design/assistant/blog/day_288__success_stories.mdwn b/doc/design/assistant/blog/day_288__success_stories.mdwn
new file mode 100644
index 000000000..c19f64e1f
--- /dev/null
+++ b/doc/design/assistant/blog/day_288__success_stories.mdwn
@@ -0,0 +1,32 @@
+Got caught up on a big queue of messages today. Mostly I hear from people
+when git-annex is not working for them, or they have a question about using
+it. From time to time someone does mention that it's working for them.
+
+> We have 4 or so machines all synching with each other via the local
+> network thing. I'm always amazed when it doesn't just explode :)
+
+Due to the nature of git-annex, a lot of people can be using it without
+anyone knowing about it. Which is great. But these little success stories
+can make all the difference. It motivates me to keep pounding out the
+development hours, it encourages other people to try it, and it'd be a good
+thing to be able to point at if I tried to raise more funding now that I'm
+out of Kickstarter money.
+
+I'm posting my own success story to my main blog:
+[git annex and my mom](http://joeyh.name/blog/entry/git_annex_and_my_mom)
+
+If you have a success story to share, why not blog about it, microblog it,
+or just post a comment here, or even send me a private message. Just a
+quick note is fine. Thanks!
+
+----
+
+Going through the bug reports and questions today, I ended up fixing
+three separate bugs that could break setting up a repo on a remote ssh
+server from the webapp.
+
+Also developed a minimal test case for some gnucash behavior that prevents
+the watcher from seeing files it writes out. I understand the problem,
+but don't have a fix for that yet. Will have to think about it. (A year ago
+today, my blog featured the
+[[first_release_of_the_watcher|day_16__more_robust_syncing]].)
diff --git a/doc/design/assistant/blog/day_288__success_stories/comment_10_9ddf57b8ae0241268bb33bec1b169e4c._comment b/doc/design/assistant/blog/day_288__success_stories/comment_10_9ddf57b8ae0241268bb33bec1b169e4c._comment
new file mode 100644
index 000000000..f53f4b654
--- /dev/null
+++ b/doc/design/assistant/blog/day_288__success_stories/comment_10_9ddf57b8ae0241268bb33bec1b169e4c._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmnG4EuvZWse5hvgrl0XAK-U61e-0iGaao"
+ nickname="David"
+ subject="Nothing fancy but..."
+ date="2013-06-27T16:52:12Z"
+ content="""
+Hi Joey,
+
+First, thanks very much for your effort put into git-annex. I store my photos in git-annex and I like it because:
+
+* I want to store multiple copies of the pictures and I can see where they are,
+* I can have a global view of the collection on my laptop without carrying all the files.
+* the indirect mode makes it difficult to me to do stupid things.
+
+So there's nothing fancy, but it works for me very well. From time to time I try the assistant's new features and I'm planning to replace Dropbox eventually.
+
+Secondly, thanks very much for the dev blog! I was looking forward every morning to see what's coming next, what problems you are facing and how you're planning to solve them. It is simply amazing what you've achieved in the last year and your posts gave me a lot of motivation too (in finishing my thesis :-))!
+
+Thanks!
+"""]]
diff --git a/doc/design/assistant/blog/day_288__success_stories/comment_11_50b8a597bd8677608f2ef176443f23f3._comment b/doc/design/assistant/blog/day_288__success_stories/comment_11_50b8a597bd8677608f2ef176443f23f3._comment
new file mode 100644
index 000000000..219e1e651
--- /dev/null
+++ b/doc/design/assistant/blog/day_288__success_stories/comment_11_50b8a597bd8677608f2ef176443f23f3._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.193"
+ subject="comment 11"
+ date="2013-06-27T18:11:03Z"
+ content="""
+Excerpt from a [longer comment](http://git-annex.branchable.com/bugs/Problems_with_syncing_gnucash/#comment-7d70d822a0fdf672ba09535f943af7c9) by Florian:
+
+I know that my expectations in this project are a little bit high and I see how much work it was to get where we are now. Once again thank you for the excellent work done so far. I don't fear to synchronize important data with git-annex. I even use git-annex to backup and synchronize the member database for our club (wannabe hackerspace).
+"""]]
diff --git a/doc/design/assistant/blog/day_288__success_stories/comment_12_f2df427cf3608377e9a52d8bdeadb26f._comment b/doc/design/assistant/blog/day_288__success_stories/comment_12_f2df427cf3608377e9a52d8bdeadb26f._comment
new file mode 100644
index 000000000..10699c959
--- /dev/null
+++ b/doc/design/assistant/blog/day_288__success_stories/comment_12_f2df427cf3608377e9a52d8bdeadb26f._comment
@@ -0,0 +1,21 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.193"
+ subject="comment 12"
+ date="2013-06-27T18:11:45Z"
+ content="""
+From a mail I received: --[[Joey]]
+
+Git-annex makes it possible for me to have lots of data. Before I
+started using it I had a music library and a few massive tar files,
+none of it properly backed up, and occasionally there would be random
+corruption (I still have broken mp3s which jump and stutter in places)
+because I would carelessly cp them from HDD to HDD. So I'd avoid
+actually letting data accumulate; this was inconvenient in itself.
+Now git-annex does everything for me.
+
+Following your development blog, as a novice programmer, has been
+really enjoyable and interesting. My only experience of professional
+IT has put me of but it's good to see you working through things
+methodically and properly.
+"""]]
diff --git a/doc/design/assistant/blog/day_288__success_stories/comment_13_8762efed97f21eeba8f0a7be45bd924a._comment b/doc/design/assistant/blog/day_288__success_stories/comment_13_8762efed97f21eeba8f0a7be45bd924a._comment
new file mode 100644
index 000000000..3b18645e4
--- /dev/null
+++ b/doc/design/assistant/blog/day_288__success_stories/comment_13_8762efed97f21eeba8f0a7be45bd924a._comment
@@ -0,0 +1,35 @@
+[[!comment format=mdwn
+ username="http://julien.lefrique.name/"
+ nickname="jlefrique"
+ subject="Many thanks!"
+ date="2013-06-27T19:59:47Z"
+ content="""
+Hi Joey,
+
+More than ten years ago, I was looking for a software to index the content of all my
+CD-ROMs in order to create a kind of \"table of content\". Today there is
+git-annex!
+
+I discovered git-annex few months ago and it really helps me to keep my file
+well organized. I missed the first crowd funding campaign but would be happy
+to contribute to the next one :D
+
+I mainly use four different annexes for:
+
+* my private photos and videos,
+* my music collection,
+* my other multimedia files (movies...),
+* my other files that are too large to be commited into git directly (pdf, binaries...).
+
+I use git-annex manually via the command line. I started to play with the
+assistant on my Android tablet and I plan to install it on my wife's
+Macbook to synchronize her data with the NAS.
+
+A standalone build for arm to run git-annex on my NAS (QNAP 219 PII) would be perfect :-P
+
+Thank you very much for all your great softwares (yes I also use etckeeper,
+some moreutils tools and more recently ikiwiki).
+
+-Julien
+
+"""]]
diff --git a/doc/design/assistant/blog/day_288__success_stories/comment_14_55e1bb15c3a93d582d110f8173ceefc2._comment b/doc/design/assistant/blog/day_288__success_stories/comment_14_55e1bb15c3a93d582d110f8173ceefc2._comment
new file mode 100644
index 000000000..f63dc7b9e
--- /dev/null
+++ b/doc/design/assistant/blog/day_288__success_stories/comment_14_55e1bb15c3a93d582d110f8173ceefc2._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="EvanDeaubl"
+ ip="67.128.198.190"
+ subject="comment 14"
+ date="2013-06-28T18:35:55Z"
+ content="""
+git-annex has been working brilliantly for me. I have been slowly moving content out of the various places I've had it stored (file servers, folders hidden away on all my machines, Dropbox, Google Drive, etc.) into a single git-annex repo. The idea has been to mimic Dropbox's single folder, but with much more flexibility: I sync my working machines, my home fileserver, my VPS (for file access on the go), Android devices, and even a couple of dumb MP3 players from git-annex. Best of all, I have one place to go for all of my files, and if they're not on the device at the moment I need them, they're a download away. I didn't find git-annex until after the first crowdfunding campaign had completed, but if there's another, I would be a happy supporter.
+
+"""]]
diff --git a/doc/design/assistant/blog/day_288__success_stories/comment_15_5749aef8b585b293385b20b75c40f9d8._comment b/doc/design/assistant/blog/day_288__success_stories/comment_15_5749aef8b585b293385b20b75c40f9d8._comment
new file mode 100644
index 000000000..d8c99640b
--- /dev/null
+++ b/doc/design/assistant/blog/day_288__success_stories/comment_15_5749aef8b585b293385b20b75c40f9d8._comment
@@ -0,0 +1,31 @@
+[[!comment format=txt
+ username="http://jasonwoof.com/"
+ nickname="JasonWoof"
+ subject="It's been great!"
+ date="2013-06-29T03:48:08Z"
+ content="""
+Looks like I started using git-annex in November 2010.
+
+I'd already been tracking lots of small files in my home directory (settings, scripts, notes, todo list, timesheets, invoices, etc) with git.
+
+So awesome to get backups, syncing and manual merge conflict resolution.
+
+git-annex extended that to handle my larger files. git-annex's ability to be selective about what is stored where, allowed my to still be able to git clone my home directory onto small devices (I've got a debian chroot with only 6GB or so, and I installed debian on my new chromebook, that's only got 16GB of disk space (for the whole system.))
+
+I love having the full catalog visible on my filesystem with symlinks, and I can just request a file, and git-annex will figure out where to get it from, even if I'm away from home on my laptop.
+
+I just got a 2nd external hard drive, and I'm delighted with how easy it was to get a backup of everything on there.
+
+I was able to quickly and safely clear up space on my desktop computer! I'm confident that my data is safe because I've got git-annex configured to make sure there's at least two copies of my videos, and 3 copies of everything else.
+
+I've finally gone from either keeping hard drives from my past computers or keeping a full copy of the data, to having a proper archiving and backup system for all files I care about.
+
+I've got over 12,000 files stored on my main annex, and it's perfectly responsive.
+
+Joey does a great job, and has been very responsive on the rare occasions where I needed help.
+
+Three cheers!
+
+--
+Jason
+"""]]
diff --git a/doc/design/assistant/blog/day_288__success_stories/comment_16_911c6d2764906cad7d6324835441ed34._comment b/doc/design/assistant/blog/day_288__success_stories/comment_16_911c6d2764906cad7d6324835441ed34._comment
new file mode 100644
index 000000000..64d17f872
--- /dev/null
+++ b/doc/design/assistant/blog/day_288__success_stories/comment_16_911c6d2764906cad7d6324835441ed34._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://dzsino.myopenid.com/"
+ nickname="dzsino"
+ subject="thanks!"
+ date="2013-06-30T13:10:35Z"
+ content="""
+I'm using git-annex to consolidate all the stuff that accumulated for years on various drives I have. Music I downloaded and bought (don't wanna loose those), photos from 2003 and on, archives of school and work stuff etc. Using it for 6-7 months now, I came to trust git-annex, I very much like the command line robustness it has and I really like that all my files are accessible in a single tree. It would be cool to have some metadata storage (for file dates, tags and such) and maybe spotlight-like search (elastic-search comes to mind)..
+Still, without these, it has a great problem-solution fit for me!
+
+Thanks Joey for all the great work, I really hope you can continue improving it, I would gladly join to a second kickstarter funding!
+
+"""]]
diff --git a/doc/design/assistant/blog/day_288__success_stories/comment_17_eb6aa8af5aa70877255a11d132d51aba._comment b/doc/design/assistant/blog/day_288__success_stories/comment_17_eb6aa8af5aa70877255a11d132d51aba._comment
new file mode 100644
index 000000000..0586afab5
--- /dev/null
+++ b/doc/design/assistant/blog/day_288__success_stories/comment_17_eb6aa8af5aa70877255a11d132d51aba._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="GLITTAH"
+ ip="50.23.191.90"
+ subject="Several annexes managing >3TB. No problems!"
+ date="2013-07-02T00:12:27Z"
+ content="""
+I've got an annex with all my DVD ISOs that's nearly 3TB alone, uses the SHA512 hash and gets split over three computers, 6 external SATA drives and 3 USB drives. No errors so far, and the issues with git-annex I've had have all been addressed very quickly (thanks Joey!) and in a non-destructive manner so I don't have to re-init a repo. I also use it to manage my music library, which allows to me to sleep at night without worrying about a corrupted file spreading through all my backups over time since git-annex has a fsck and hashing utility. I can't imagine using anything else for managing collections of files: it offloads the task of keeping track of, getting, verifying, and general management of files so I don't even need to worry about the boring stuff, I just get around to watching/listening to my media collection.
+
+Thanks for all the work, it's changed my workflow and file management (I get more sleep too)!
+"""]]
diff --git a/doc/design/assistant/blog/day_288__success_stories/comment_18_9a57de4cea407a73b2d023d85afdccc6._comment b/doc/design/assistant/blog/day_288__success_stories/comment_18_9a57de4cea407a73b2d023d85afdccc6._comment
new file mode 100644
index 000000000..1e4277277
--- /dev/null
+++ b/doc/design/assistant/blog/day_288__success_stories/comment_18_9a57de4cea407a73b2d023d85afdccc6._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.193"
+ subject="comment 18"
+ date="2013-07-03T15:51:48Z"
+ content="""
+Another good tweet: --[[Joey]]
+
+My google Reader replacement: newsbeuter with the data directory stored in an autosynced git-annex repo.
+
+<https://twitter.com/JustinAzoff/status/352256199070199809>
+"""]]
diff --git a/doc/design/assistant/blog/day_288__success_stories/comment_19_1767c86067bee35941004282b96b8e95._comment b/doc/design/assistant/blog/day_288__success_stories/comment_19_1767c86067bee35941004282b96b8e95._comment
new file mode 100644
index 000000000..93bfb03e6
--- /dev/null
+++ b/doc/design/assistant/blog/day_288__success_stories/comment_19_1767c86067bee35941004282b96b8e95._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="GLITTAH"
+ ip="176.31.181.25"
+ subject="Forgot to add..."
+ date="2013-07-03T19:28:42Z"
+ content="""
+Forgot to add: I'm horrible at keeping things organized. Git-annex is a huge help with that -- it keeps track of files and the number of their copies. When I first started using it, I had old songs duplicated across 4 drives, while 2 of those drives had old tags and were obsolete, and one drive had the correct tags, but not the correct filenames. Every few years I'd have to go through several TB of media files, hand checking each of them to see what was old, what was unwanted, etc. Once my media libraries got larger than consumer-grade HDD's, I had to find a better solution. Git-annex removes that burden, and keeps things organized for me. Once I get an album or movie I tag/rename it the way I want, throw it in the annex and let my computer do the boring and tedious parts like automatically verifying and making sure there's enough copies. If I change a file, that change propagates through all my repo clones. It wasn't until after I started using git-annex that I realized how stressed out I was getting over simply maintaining a media library.
+
+If you do another fundraiser you've got my support!
+"""]]
diff --git a/doc/design/assistant/blog/day_288__success_stories/comment_1_22b28ca3d4d3283ad8c21ae052fb9752._comment b/doc/design/assistant/blog/day_288__success_stories/comment_1_22b28ca3d4d3283ad8c21ae052fb9752._comment
new file mode 100644
index 000000000..494cb798a
--- /dev/null
+++ b/doc/design/assistant/blog/day_288__success_stories/comment_1_22b28ca3d4d3283ad8c21ae052fb9752._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="99.54.57.201"
+ subject="comment 1"
+ date="2013-06-25T22:26:27Z"
+ content="""
+I've been real quiet cause everything's been working great. :)
+
+One thing I have not messed with yet is the whole XMPP thing. I mostly don't share between two machines that are online at the same time, I just use git annex for backups and to have content \"optionally\" available. I should give XMPP a try sometime.
+
+"""]]
diff --git a/doc/design/assistant/blog/day_288__success_stories/comment_20_1d47f3e1b9f0081649cedae4288bac83._comment b/doc/design/assistant/blog/day_288__success_stories/comment_20_1d47f3e1b9f0081649cedae4288bac83._comment
new file mode 100644
index 000000000..501cf561f
--- /dev/null
+++ b/doc/design/assistant/blog/day_288__success_stories/comment_20_1d47f3e1b9f0081649cedae4288bac83._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmhfodZquCI_EEl-f3h7HkROTszlsQL6yA"
+ nickname="Joe"
+ subject="comment 20"
+ date="2013-07-04T12:41:35Z"
+ content="""
+I'm using git-annex to make videos, pictures and music available on all my devices (windows, android, linux). It has saved me on trips with my 2yr daughter when she's had meltdowns; I have her favorite movie ready. I quickly exceeded the free dropbox quota and git-annex has replaced the need and gives me greater confidence and control over my data. Thank you!
+"""]]
diff --git a/doc/design/assistant/blog/day_288__success_stories/comment_21_31d3f58cad83cb1ecc4821a15ca258d8._comment b/doc/design/assistant/blog/day_288__success_stories/comment_21_31d3f58cad83cb1ecc4821a15ca258d8._comment
new file mode 100644
index 000000000..99c6c14af
--- /dev/null
+++ b/doc/design/assistant/blog/day_288__success_stories/comment_21_31d3f58cad83cb1ecc4821a15ca258d8._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm0sGxsiJ7yj5iQsF-A5tEl6XKOGQieqEo"
+ nickname="Matthew"
+ subject="Writing papers"
+ date="2013-07-04T15:32:24Z"
+ content="""
+I'm a graduate student, so I write a lot. I started using git to manage my latex sources a while ago, but I didn't like gumming up my repository with a bunch of figures (large binaries). I was constantly forgetting to scp the latest versions of my figures from here to there (as I do my work on a number of different computers.) Git annex gives me a good way to version the figures and manage them with the same tool I'm using for the text.
+
+My use case seems pretty far from typical, judging from the other comments here, so I thought I should add my two cents! I'm constantly trying to sell this approach to my fellow students.
+
+Also, I'm going to slip in a plug for another great Haskell project here -- Pandoc. I work with people who suggest changes to my drafts, but only using Word's \"Track Changes\". So now I'm generating Word docs from Pandoc markdown for my collaborators to edit. When it comes time to publish, I can convert my markdown to latex and clean up the formatting.
+
+Why are all the really cool projects written in Haskell? :)
+"""]]
diff --git a/doc/design/assistant/blog/day_288__success_stories/comment_22_b512bd2bf29dfaab6b36bf204518fdb6._comment b/doc/design/assistant/blog/day_288__success_stories/comment_22_b512bd2bf29dfaab6b36bf204518fdb6._comment
new file mode 100644
index 000000000..e7a62fd01
--- /dev/null
+++ b/doc/design/assistant/blog/day_288__success_stories/comment_22_b512bd2bf29dfaab6b36bf204518fdb6._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://sunny256.sunbase.org/"
+ nickname="sunny256"
+ subject="git-annex is teh awesome"
+ date="2013-07-15T12:37:54Z"
+ content="""
+Just like Git, git-annex is teh awesome. I've used it for almost a year now, and I've never had more control of all my stuff. I store all my valuable (and also not so valuable) files in it, more than a terabyte, and it's rapidly growing. Movies, pictures, recordings, software, podcasts, DVDs and CDs, you name it. It's rock solid with a really good design. Joey says it isn't a backup solution, but I strongly disagree. My data have never been safer. git-annex ensures that I have several copies in different locations, I always know where all the copies are, and the disk space is used way more efficiently now that I don't have unnecessary duplicates everywhere anymore.
+"""]]
diff --git a/doc/design/assistant/blog/day_288__success_stories/comment_2_343333356de20e170edb8020faa7400d._comment b/doc/design/assistant/blog/day_288__success_stories/comment_2_343333356de20e170edb8020faa7400d._comment
new file mode 100644
index 000000000..768469e3e
--- /dev/null
+++ b/doc/design/assistant/blog/day_288__success_stories/comment_2_343333356de20e170edb8020faa7400d._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://launchpad.net/~subito"
+ nickname="subito"
+ subject="Big success!"
+ date="2013-06-26T07:00:15Z"
+ content="""
+Annex is working great for me since 8/2012 or something... Using it a lot and the Assistant is awesome!
+
+If you would raise some more funding, I'd be more than happy to support you once more - really great software!
+"""]]
diff --git a/doc/design/assistant/blog/day_288__success_stories/comment_3_4e4034bec789543b562ac263df3e21dd._comment b/doc/design/assistant/blog/day_288__success_stories/comment_3_4e4034bec789543b562ac263df3e21dd._comment
new file mode 100644
index 000000000..c8ae3d785
--- /dev/null
+++ b/doc/design/assistant/blog/day_288__success_stories/comment_3_4e4034bec789543b562ac263df3e21dd._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl3A5oeZFLreGhDTFVMOJYIy1auKiTL_ZY"
+ nickname="Maggie"
+ subject=":)"
+ date="2013-06-26T15:04:45Z"
+ content="""
+Poets aren't humble people.
+We revel in our own narcissism.
+So being mentioned in my brother's blog
+was great for me.
+
+I am proud of the success of Git Annex.
+
+(My poems tend to be _much_ better than this.)
+"""]]
diff --git a/doc/design/assistant/blog/day_288__success_stories/comment_4_0c52794c77a9b7afc5112f5edf9cb793._comment b/doc/design/assistant/blog/day_288__success_stories/comment_4_0c52794c77a9b7afc5112f5edf9cb793._comment
new file mode 100644
index 000000000..f285863f5
--- /dev/null
+++ b/doc/design/assistant/blog/day_288__success_stories/comment_4_0c52794c77a9b7afc5112f5edf9cb793._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://nicolas-schodet.myopenid.com/"
+ ip="2a01:e35:8ae6:f130:1e4b:d6ff:fe78:1ddb"
+ subject="Thank you for this great tool!"
+ date="2013-06-26T18:10:05Z"
+ content="""
+I use git-annex for my picture collection. I can add pictures from my computers, or my FTP server when someone wants to send me their pictures. Then I push them to my online gallery. Git annex is great to keep all my repository synchronized while not requesting that all my pictures are present on my laptop. Thank you!
+"""]]
diff --git a/doc/design/assistant/blog/day_288__success_stories/comment_5_7ca419aa3a187857b19268572d5df297._comment b/doc/design/assistant/blog/day_288__success_stories/comment_5_7ca419aa3a187857b19268572d5df297._comment
new file mode 100644
index 000000000..1dd6fa4a9
--- /dev/null
+++ b/doc/design/assistant/blog/day_288__success_stories/comment_5_7ca419aa3a187857b19268572d5df297._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.193"
+ subject="comment 5"
+ date="2013-06-26T19:39:15Z"
+ content="""
+Excerpt from an email I received: --[[Joey]]
+
+Another story, but without the assistant this time: I've \"designed\" a
+small f2f file sharing network with it, I'm using it with a friend to
+share accross several computer. This is basically a workflow
+with git annex and gitoline, the flexibility of git and the capacities
+of git annex just gave us this out of the box. Some specs are here if
+you are curious
+http://worlddomination.be/ideas/2012/idea-n-21-build-a-f2f-sharing-network-using
+-git-annex.html
+
+"""]]
diff --git a/doc/design/assistant/blog/day_288__success_stories/comment_6_3edd56b3b04f19faba8d75cca285a662._comment b/doc/design/assistant/blog/day_288__success_stories/comment_6_3edd56b3b04f19faba8d75cca285a662._comment
new file mode 100644
index 000000000..f08fce4b3
--- /dev/null
+++ b/doc/design/assistant/blog/day_288__success_stories/comment_6_3edd56b3b04f19faba8d75cca285a662._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="andy"
+ ip="99.127.140.99"
+ subject="Another success story"
+ date="2013-06-27T02:03:00Z"
+ content="""
+I'm using Ubuntu, and I do a clean install about every 6 months when the new versions come out. I also have 2-3 systems I need to keep in sync. I use git annex to store files I want to keep between OS reinstalls, and to sync the various systems I need data on. I also use it to backup data to the cloud and to bup. I have 6+ repos, 235 GB of data, and 31,029 known annex keys (thanks `git annex map` and `git annex status`!); nevertheless git annex is generally pretty cooperative. I'm not using the assistant yet, but I'd like to eventually. I almost don't have to think about the stuff annex handles. It's really fun to install a fresh OS, clone the git annex repo, and have my entire annex directory tree available immediately.
+
+Thanks Joey! You've done a great job!
+"""]]
diff --git a/doc/design/assistant/blog/day_288__success_stories/comment_7_146331ae2de25a6dc3595dffab9514de._comment b/doc/design/assistant/blog/day_288__success_stories/comment_7_146331ae2de25a6dc3595dffab9514de._comment
new file mode 100644
index 000000000..61d581380
--- /dev/null
+++ b/doc/design/assistant/blog/day_288__success_stories/comment_7_146331ae2de25a6dc3595dffab9514de._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.193"
+ subject="comment 7"
+ date="2013-06-27T06:31:29Z"
+ content="""
+Amazing tweet I found! --[[Joey]]
+
+Git-annex now auto-syncing photos from my android phone to a Tor hidden SSH service I control (via @guardianproject's Orbot) #prismbreak
+
+<https://twitter.com/graphiclunarkid/status/347658443479449601>
+"""]]
diff --git a/doc/design/assistant/blog/day_288__success_stories/comment_8_72be9307e75eb120451f3d6ab7c8165e._comment b/doc/design/assistant/blog/day_288__success_stories/comment_8_72be9307e75eb120451f3d6ab7c8165e._comment
new file mode 100644
index 000000000..ab482d179
--- /dev/null
+++ b/doc/design/assistant/blog/day_288__success_stories/comment_8_72be9307e75eb120451f3d6ab7c8165e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnAvbXOnK57sqgvZvxkbG74NUKBDwKDcuk"
+ nickname="Tim"
+ subject="Backups"
+ date="2013-06-27T13:14:43Z"
+ content="""
+We use rsync and tar to backup to a server on the local network, and since we discoverd git-annex, we use this mechanism to automatically put all this data in both a local bup repo and a remote one. This gives us a daily full backup, with history available, both locally and off-site. Thanks to bup our 4T of data gets deduplicated to about 270G, only a couple of megs get transferred every night, and thanks to git-annex everything just works, like it should!
+"""]]
diff --git a/doc/design/assistant/blog/day_288__success_stories/comment_9_c27eb0a4181e85a3eed41130402350bf._comment b/doc/design/assistant/blog/day_288__success_stories/comment_9_c27eb0a4181e85a3eed41130402350bf._comment
new file mode 100644
index 000000000..cf77845b5
--- /dev/null
+++ b/doc/design/assistant/blog/day_288__success_stories/comment_9_c27eb0a4181e85a3eed41130402350bf._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlOc-EOD5ZyggsAp6lOnU7x5MxizwLtUXA"
+ nickname="Hendrik"
+ subject="more success"
+ date="2013-06-27T14:09:47Z"
+ content="""
+Hi,
+
+I have moved all my photographs to an annex running on a Ubuntu file server while doing photo editing, presenting etc. on my MacBook. The annex is great in selectively moving files between these machines for editing and presentation purposes. I started using it around christmas season last year and added a glacier \"backup\" recently. My statistics: 6 repositories in total, more than 300GB (dedup'd from 380GB), 60.000 local keys.
+
+What is missing from my point of view (and I would happily join crowd funding): stable windows and android versions, managing selective transfers from the assistant (select folders to be transferred from/to a specific repository), options for running the annex as a server daemon with web GUI (authentication to GUI + fixed URLs, status reports on GUI, etc.). All these would dramatically increase the WAF.
+"""]]
diff --git a/doc/design/assistant/blog/day_289__back_in_the_swing.mdwn b/doc/design/assistant/blog/day_289__back_in_the_swing.mdwn
new file mode 100644
index 000000000..75923f897
--- /dev/null
+++ b/doc/design/assistant/blog/day_289__back_in_the_swing.mdwn
@@ -0,0 +1,16 @@
+Came up with a fix for the gnucash hard linked file problem that makes the
+assistant notice the files gnucash writes. This is not full hard link support;
+hard linked files still don't cleanly sync around. But new hard links to
+files are noticed and added, which is enough to support gnucash.
+
+Spent around 4 hours on reproducing and trying to debug
+[[bugs/Hanging_on_install_on_Mountain_lion]]. It seems that recent upgrades
+of the OSX build machine led to this problem. And indeed, building with an
+older version of Yesod and Warp seems to have worked around the problem. So
+I updated the OSX build for the last release. I will have to re-install the
+new Yesod on my laptop and investigate further -- is this an OSX specific
+problem, or does it affect Linux? Urgh, this is the second hang I've
+encountered involving Warp..
+
+Got several nice [[success stories|day_288__success_stories]], but I don't
+think I've seen *yours* yet. ;) Please post!
diff --git a/doc/design/assistant/blog/day_290__https_release.mdwn b/doc/design/assistant/blog/day_290__https_release.mdwn
new file mode 100644
index 000000000..ea017d217
--- /dev/null
+++ b/doc/design/assistant/blog/day_290__https_release.mdwn
@@ -0,0 +1,17 @@
+Spent too many hours last night tracking down a bug that caused the webapp
+to hang when it got built with the new yesod 1.2 release. Much of that time
+was spent figuring out that yesod 1.2 was causing the problem. It turned out to
+be a stupid typo in my yesod compatability layer. `liftH = liftH` in
+Haskell is an infinite loop, not the stack overflow you get in most
+languages. ;)
+
+Even though it's only been a week since the last release,
+that was worth pushing a release out for, which I've just done.
+This release is essentially all bug fixes (aside from the automatic
+ionice and nicing of the daemon).
+
+This website is now available over https. Perhaps more importantly, all the
+links to download git-annex builds are https by default.
+
+The [[success_stories|day_288__success_stories]] list is getting really
+nice. Only way it could possibly be nicer is if you added your story! Hint. ;)
diff --git a/doc/design/assistant/blog/day_291__--all.mdwn b/doc/design/assistant/blog/day_291__--all.mdwn
new file mode 100644
index 000000000..0a5584182
--- /dev/null
+++ b/doc/design/assistant/blog/day_291__--all.mdwn
@@ -0,0 +1,32 @@
+I've felt for a while that git-annex needed better support for managing
+the contents of past versions of files that are stored in the annex. I know
+some people get confused about whether git-annex even supports old versions
+of files (it does, but you should use indirect mode; direct mode doesn't
+guarantee old versions of files will be preserved).
+
+So today I've worked on adding command-line power for managing past
+versions: a new `--all` option.
+
+So, if you want to copy every version of every file in your repository to
+an archive, you can run `git annex copy --all --to archive`.
+Or if you've got a repository on a drive that's dying, you can run
+`git annex copy --all --to newdrive`, and then on the new drive, run `git
+annex fsck --all` to check all the data.
+
+In a bare repository, `--all` is default, so you can run `git annex get`
+inside a bare repository and it will try to get every version of every file
+that it can from the remotes.
+
+The tricky thing about `--all` is that since it's operating on objects and
+not files, it can't check `.gitattributes` settings, which are tied to the
+file name. I worried for a long time that adding `--all` would make
+annex.numcopies settings in those files not be honored, and that this would
+be a Bad Thing. The solution turns out to be simple: I just didn't
+implement `git annex drop --all`! Dropping is the only action that needs to
+check numcopies (move can also reduce the number of copies, but explicitly
+bypasses numcopies settings).
+
+I also added an `--unused` option. So if you have a repository that has
+been accumulating history, and you'd like to move all file contents not
+currently in use to a central server, you can run `git annex unused; git
+annex move --unused --to origin`
diff --git a/doc/design/assistant/blog/day_291__--all/comment_1_eaa9fef19a035bef9c439e87d47c834b._comment b/doc/design/assistant/blog/day_291__--all/comment_1_eaa9fef19a035bef9c439e87d47c834b._comment
new file mode 100644
index 000000000..60cb4abb0
--- /dev/null
+++ b/doc/design/assistant/blog/day_291__--all/comment_1_eaa9fef19a035bef9c439e87d47c834b._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/2grhJvAC049fJnvALDXek.6MRZMTlg--#eec89"
+ nickname="John"
+ subject="comment 1"
+ date="2013-07-03T22:16:32Z"
+ content="""
+Excellent stuff! Another thing I'd like to see is that I find myself doing the following all the time:
+
+ git annex copy --to titan --not --in titan
+
+Meaning: copy everything to titan that it doesn't already have. This operation is very quick. But I write just:
+
+ git annex copy --to titan
+
+This operation is extremely slow, since it appears to scan through every file in the repository. Is there a way to have the latter imply the former? I wouldn't ever want to copy a file that it already has anyway...
+
+"""]]
diff --git a/doc/design/assistant/blog/day_291__--all/comment_2_90bbc26bf92048de7cbaf5fb719c9593._comment b/doc/design/assistant/blog/day_291__--all/comment_2_90bbc26bf92048de7cbaf5fb719c9593._comment
new file mode 100644
index 000000000..6838ac070
--- /dev/null
+++ b/doc/design/assistant/blog/day_291__--all/comment_2_90bbc26bf92048de7cbaf5fb719c9593._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="sfs"
+ ip="65.204.1.102"
+ subject="See history of a file"
+ date="2013-07-07T00:49:35Z"
+ content="""
+It's great that you are addressing the management of older versions. I am new to git-annex but couldn't find much information about this topic. Is it also possible to make git-annex show you the history of files (with date, size, ...) and where (which repositories) they are stored? Or to retrieve a specific version from a remote repository?
+
+Thanks for this amazing peace of software!
+Stephan
+"""]]
diff --git a/doc/design/assistant/blog/day_291__--all/comment_3_75006e9909425dcbf86415a9f7c90372._comment b/doc/design/assistant/blog/day_291__--all/comment_3_75006e9909425dcbf86415a9f7c90372._comment
new file mode 100644
index 000000000..748db49f3
--- /dev/null
+++ b/doc/design/assistant/blog/day_291__--all/comment_3_75006e9909425dcbf86415a9f7c90372._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.254.222"
+ subject="comment 3"
+ date="2013-07-07T17:20:05Z"
+ content="""
+@john I have considered making copy trust the location log for the remote (which is what your --not --in titan does), but this does change its behavior in a subtly way, and IIRC there were scenarios where this is not desirable.
+
+@sfs the best way to look at older versions of files is to use `git checkout` to check out an older version of the repository. You can then use `git annex get`, `git annex whereis`, etc like you usually would, on the old version of files.
+"""]]
diff --git a/doc/design/assistant/blog/day_291__--all/comment_4_5440449bbc5a353f7430f72e19c35e92._comment b/doc/design/assistant/blog/day_291__--all/comment_4_5440449bbc5a353f7430f72e19c35e92._comment
new file mode 100644
index 000000000..a4739c5e7
--- /dev/null
+++ b/doc/design/assistant/blog/day_291__--all/comment_4_5440449bbc5a353f7430f72e19c35e92._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 4"
+ date="2013-07-14T16:03:39Z"
+ content="""
+@john, @joeyh: I like the fact that normal copy takes some time, but that it _verifies_. Default to save, optimize to quick, imo.
+"""]]
diff --git a/doc/design/assistant/blog/day_292__bugfixes.mdwn b/doc/design/assistant/blog/day_292__bugfixes.mdwn
new file mode 100644
index 000000000..a514afd0e
--- /dev/null
+++ b/doc/design/assistant/blog/day_292__bugfixes.mdwn
@@ -0,0 +1,24 @@
+Actually spread out over several days..
+
+I think I have finally comprehensively dealt with all the wacky system
+misconfigurations that can make `git commit` complain and refuse to commit.
+The last of these is [a system with a FQDN that doesn't have a dot in it](http://git-annex.branchable.com/bugs/view_logs_fails:_Internal_Server_Error__internal_liftAnnex/).
+I personally think git should just use the hostname as-is in the email
+address for commits here -- it's better to be robust. Indeed, I think it
+would make more sense if `git commit` never failed, unless it ran out of
+disk or the repo is corrupt. But anyway, `git-annex
+init` will now detect when the commit fails because of this and put a
+workaround in place.
+
+Fixed a bug in `git annex addurl --pathdepth` when the url's path was
+shorter than the amount requested to remove from it.
+
+Tracked down a bug that prevents git-annex from working on a system with an
+old linux kernel. Probably the root cause is that the kernel was built
+without EVENTFD support. Found a workaround to get a usable git-annex on
+such a system is to build it without the webapp, since that disables the
+threaded runtime which triggered the problem.
+
+Dealt with a lot of Windows bugs. Very happy that it's working well enough
+that some users are reporting bugs on it in Windows, and with enough detail
+that I have not needed to boot Windows to fix them so far. ;)
diff --git a/doc/design/assistant/blog/day_292__bugfixes/comment_1_bbac3878d80f7540d229183c56664784._comment b/doc/design/assistant/blog/day_292__bugfixes/comment_1_bbac3878d80f7540d229183c56664784._comment
new file mode 100644
index 000000000..5aafab12d
--- /dev/null
+++ b/doc/design/assistant/blog/day_292__bugfixes/comment_1_bbac3878d80f7540d229183c56664784._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://cweiske.de/"
+ nickname="cweiske"
+ subject="comment 1"
+ date="2013-07-09T06:52:11Z"
+ content="""
+Thanks for the quick bugfix!
+"""]]
diff --git a/doc/design/assistant/blog/day_292__bugfixes/comment_2_8c9e5291ceb257f3a938af0ad967c5d7._comment b/doc/design/assistant/blog/day_292__bugfixes/comment_2_8c9e5291ceb257f3a938af0ad967c5d7._comment
new file mode 100644
index 000000000..adb161fd0
--- /dev/null
+++ b/doc/design/assistant/blog/day_292__bugfixes/comment_2_8c9e5291ceb257f3a938af0ad967c5d7._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://nullroute.eu.org/~grawity/"
+ nickname="Mantas"
+ subject="comment 2"
+ date="2013-07-09T13:47:20Z"
+ content="""
+git **used to** use the hostname as-is, but that didn't work out well – many people just kept on committing as `joeyh@kremvax.(none)`, which doesn't make for a good email address or a globally-unique identifier (sometimes by being lazy; sometimes by forgetting to carry their Git config over to a new machine).
+
+The stricter check was implemented in [8c5b1ae1](https://github.com/gitster/git/commit/8c5b1ae1b26a7512eb29e75391b8b24c0d0439e7) for git v1.8.3. Setting `$EMAIL` or running `git -c user.email=foo@bar` should override it.
+"""]]
diff --git a/doc/design/assistant/blog/day_292__bugfixes/comment_3_02f875e8edd30f47939249f16d92712b._comment b/doc/design/assistant/blog/day_292__bugfixes/comment_3_02f875e8edd30f47939249f16d92712b._comment
new file mode 100644
index 000000000..3d02b447b
--- /dev/null
+++ b/doc/design/assistant/blog/day_292__bugfixes/comment_3_02f875e8edd30f47939249f16d92712b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://nullroute.eu.org/~grawity/"
+ nickname="Mantas"
+ subject="comment 3"
+ date="2013-07-09T13:48:49Z"
+ content="""
+(I was wrong about the version; it appears to be v1.7.11.)
+"""]]
diff --git a/doc/design/assistant/blog/day_293__gpg_builds.mdwn b/doc/design/assistant/blog/day_293__gpg_builds.mdwn
new file mode 100644
index 000000000..eb3ccbd25
--- /dev/null
+++ b/doc/design/assistant/blog/day_293__gpg_builds.mdwn
@@ -0,0 +1,32 @@
+Two gpg fixes today. The OSX Mtn Lion builds were pulling in a build of gpg
+that wanted a gpg-agent to be installed in /usr/local or it wouldn't work.
+I had to build my own gpg on OSX to work around this. I am pondering making
+the OSX dmg builds pull down the gpg source and build their own binary,
+so issues on the build system can't affect it. But would really rather not,
+since maintaining your own version of every dependency on every
+OS is hard (pity about there still being so many OS's without sane package
+management).
+
+On Android, which I have not needed to touch for a month, gpg was built
+with --enable-minimal, which turned out to not be necessary and was
+limiting the encryption algorythms included, and led to
+interoperability problems for some. Fixed that gpg build too.
+
+Also fixed an ugly bug in the webapp when setting up a rsync repository.
+It would configure `~/.ssh/authorized_keys` on the server to force
+git-annex-shell to be run. Which doesn't work for rsync. I didn't notice
+this before because it doesn't affect ssh servers that already have a ssh
+setup that allows accessing them w/o a password.
+
+Spent a while working on a bug that can occur in a non-utf8 locale
+when using special characters in the directory name of a ssh remote.
+I was able to reproduce it, but have not worked out how to fix it; encoding
+issues like this are always tricky.
+
+Added something to the walkthrough to help convince people that yes, you
+can use tags and branches with git-annex just like with regular git. One of
+those things that is so obvious to the developer writing the docs
+that it's hard to realize it will be a point of concern.
+
+Seems like there is a release worth of changes already, so I plan to push
+it out tomorrow.
diff --git a/doc/design/assistant/blog/day_293__gpg_builds/comment_1_4f152de8ea5aca4ec381d439e2a821f7._comment b/doc/design/assistant/blog/day_293__gpg_builds/comment_1_4f152de8ea5aca4ec381d439e2a821f7._comment
new file mode 100644
index 000000000..82563a41d
--- /dev/null
+++ b/doc/design/assistant/blog/day_293__gpg_builds/comment_1_4f152de8ea5aca4ec381d439e2a821f7._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnXybLxkPMYpP3yw4b_I6IdC3cKTD-xEdU"
+ nickname="Matt"
+ subject="comment 1"
+ date="2013-07-09T07:18:09Z"
+ content="""
+Hi, glad you added the git history and branch info to the walk through. With a 40,000 foot view some of the wording in the docs (whilst correct) may lead to the wrong impression. For example, in the unused data section, there is a sense that it seems bad that data can accumulate and doing a \"git rm\" rather than doing a \"git annex drop\" is a naughty thing to do (I know you don't actually say this).
+
+I think it needs to made clear that \"removing\" files is more subtle than in a traditional file-system: that there is a choice of deleting from the working tree so that contents remain and can be recovered or removing the file and contents labeled together (a.k.a \"dropping\"). With dropping so pervasive in the docs its easy to think this \"right\" (and only) way.
+
+I wonder if a \"git annex rm\" which is simply an alias for \"git rm\" might be a good idea for a UI perspective...
+"""]]
diff --git a/doc/design/assistant/blog/day_293__gpg_builds/comment_2_42f625638638bc875379f6c604d6f673._comment b/doc/design/assistant/blog/day_293__gpg_builds/comment_2_42f625638638bc875379f6c604d6f673._comment
new file mode 100644
index 000000000..6f00552e2
--- /dev/null
+++ b/doc/design/assistant/blog/day_293__gpg_builds/comment_2_42f625638638bc875379f6c604d6f673._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="LP"
+ ip="72.227.131.46"
+ subject="Just to say.."
+ date="2013-07-10T23:01:56Z"
+ content="""
+These updates are fantastic. They're great demonstrations of transparency in work, fun to read as a kstarter contributor, and interesting as a copypasta coder. Bravo.
+"""]]
diff --git a/doc/design/assistant/blog/day_294__release_day.mdwn b/doc/design/assistant/blog/day_294__release_day.mdwn
new file mode 100644
index 000000000..b64b91ae5
--- /dev/null
+++ b/doc/design/assistant/blog/day_294__release_day.mdwn
@@ -0,0 +1,7 @@
+Got the release out, after fixing test suite and windows build breakage.
+This release has all the features on the command line side (--all,
+--unused, etc), but several bugfixes on the assistant side, and a lot
+of Windows bug fixes.
+
+I've spent this evening adding icons to git-annex on Linux.
+Even got the Linux standalone tarball to automatically install icons.
diff --git a/doc/design/assistant/blog/day_295__balls_in_the_air.mdwn b/doc/design/assistant/blog/day_295__balls_in_the_air.mdwn
new file mode 100644
index 000000000..ebbad2973
--- /dev/null
+++ b/doc/design/assistant/blog/day_295__balls_in_the_air.mdwn
@@ -0,0 +1,13 @@
+Been keeping several non-coding balls in the air recently, two of which
+landed today.
+
+First, Rsync.net is [offering a discount to all git-annex users](http://www.rsync.net/products/git-annex-pricing.html),
+at one third their normal price.
+"People using git-annex are clueful and won't be a big support burden for us,
+so it's a win-win."
+The web app will be updated offer the discount when setting up a rsync.net
+repository.
+
+Secondly, I've recorded an interview today for the Git Minutes podcast,
+about git-annex. Went well, looking forward to it going up, probably on
+Monday.
diff --git a/doc/design/assistant/blog/day_296__new_crowdfunding_campaign.mdwn b/doc/design/assistant/blog/day_296__new_crowdfunding_campaign.mdwn
new file mode 100644
index 000000000..759bde12f
--- /dev/null
+++ b/doc/design/assistant/blog/day_296__new_crowdfunding_campaign.mdwn
@@ -0,0 +1,41 @@
+Surprise! I'm running a new crowdfunding campaign, which I hope will fund
+several more months of git-annex development.
+
+<https://campaign.joeyh.name/>
+
+Please don't feel you have to give, but if you do decide to, give
+generously. ;) I'm accepting both Paypal and Bitcoin (via CoinBase.com),
+and have some rewards that you might enjoy.
+
+----
+
+I came up with two lists of things I hope this campaign will fund.
+These are by no means complete lists. First, some general features and
+development things:
+
+* Integrate better with Android.
+* Get the assistant and webapp ported to Windows.
+* Refine the automated stress testing tools to find and fix more problems
+ before users ever see them.
+* Automatic recovery. Cosmic ray flipped a bit in a file?
+ USB drive corrupted itself? The assistant should notice these problems,
+ and fix them.
+* Encourage more contributions from others. For example, improve the
+ special remote plugin interface so it can do everything the native Haskell
+ interface can do. Eight new cloud storage services were added this year
+ as plugins, but we can do better!
+* Use deltas to reduce bandwidth needed to transfer modified versions of files.
+
+Secondly, some things to improve security:
+
+* Add easy support for encrypted git repositories
+ using [git-remote-gcrypt](https://github.com/blake2-ppc/git-remote-gcrypt),
+ so you can safely push to a repository on a server you don't control.
+* Add support for setting up and using GPG keys in the webapp.
+* Add protection to the XMPP protocol to guard against man in the middle
+ attacks if the XMPP server is compromised. Ie, Google should not be able to
+ learn about your git-annex repository even if you're using their servers.
+* To avoid leaking even the size of your encrypted files to
+ cloud storage providers, add a mode that stores fixed size chunks.
+
+It will also, of course, fund ongoing bugfixing, support, etc.
diff --git a/doc/design/assistant/blog/day_296__new_crowdfunding_campaign/comment_1_cccad1a5103c504d21d0f8e69bb39e1b._comment b/doc/design/assistant/blog/day_296__new_crowdfunding_campaign/comment_1_cccad1a5103c504d21d0f8e69bb39e1b._comment
new file mode 100644
index 000000000..71cfd60c4
--- /dev/null
+++ b/doc/design/assistant/blog/day_296__new_crowdfunding_campaign/comment_1_cccad1a5103c504d21d0f8e69bb39e1b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="EskildHustvedt"
+ ip="80.202.103.73"
+ subject="Shipping costs"
+ date="2013-07-15T05:07:07Z"
+ content="""
+Hi, it doesn't mention anything about offsetting shipping costs for people located outside of the US (like I am). Any chance you could add that?
+"""]]
diff --git a/doc/design/assistant/blog/day_296__new_crowdfunding_campaign/comment_2_4fef7bd9c8e15cd57df365fadb95717f._comment b/doc/design/assistant/blog/day_296__new_crowdfunding_campaign/comment_2_4fef7bd9c8e15cd57df365fadb95717f._comment
new file mode 100644
index 000000000..57df8f995
--- /dev/null
+++ b/doc/design/assistant/blog/day_296__new_crowdfunding_campaign/comment_2_4fef7bd9c8e15cd57df365fadb95717f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.187"
+ subject="comment 2"
+ date="2013-07-15T05:26:54Z"
+ content="""
+Shipping is minimal, either $1 or $1.50 outside the US. It's factored into the reward levels, basically.
+"""]]
diff --git a/doc/design/assistant/blog/day_296__new_crowdfunding_campaign/comment_3_0b9258a1f5079e53c60138f06d0c63b1._comment b/doc/design/assistant/blog/day_296__new_crowdfunding_campaign/comment_3_0b9258a1f5079e53c60138f06d0c63b1._comment
new file mode 100644
index 000000000..fc8754502
--- /dev/null
+++ b/doc/design/assistant/blog/day_296__new_crowdfunding_campaign/comment_3_0b9258a1f5079e53c60138f06d0c63b1._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm3RqHNOKdnMCRF5V4306ON55XyJtQNlpY"
+ nickname="Marco"
+ subject="BitSync"
+ date="2013-07-15T13:11:03Z"
+ content="""
+How about using torrent to retrive files from a annex, something like BitSync would be great. Nice job Joey! Thank you.
+"""]]
diff --git a/doc/design/assistant/blog/day_296__new_crowdfunding_campaign/comment_4_46183b97ca904bc06e46569c30db2edc._comment b/doc/design/assistant/blog/day_296__new_crowdfunding_campaign/comment_4_46183b97ca904bc06e46569c30db2edc._comment
new file mode 100644
index 000000000..3febd091e
--- /dev/null
+++ b/doc/design/assistant/blog/day_296__new_crowdfunding_campaign/comment_4_46183b97ca904bc06e46569c30db2edc._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://dzsino.myopenid.com/"
+ nickname="dzsino"
+ subject="mo' stickers, less problems :)"
+ date="2013-07-16T09:56:03Z"
+ content="""
+Hi Joey, since shipping would burn 10-15% of my funding, I added another $10, so you can just batch the stickers together. I hope it's cheaper this way.. Thanks!
+"""]]
diff --git a/doc/design/assistant/blog/day_297__back_to_work.mdwn b/doc/design/assistant/blog/day_297__back_to_work.mdwn
new file mode 100644
index 000000000..c8dbedc45
--- /dev/null
+++ b/doc/design/assistant/blog/day_297__back_to_work.mdwn
@@ -0,0 +1,16 @@
+It looks like I'm funded for at least the next 9 months! It would still be
+nice to get to a year. ;) <https://campaign.joeyh.name/>
+
+Working to get caught up on recent bug reports..
+
+Made `git annex uninit` not nuke anything that's left over in
+`.git/annex/objects` after unannexing all the files. After all, that could
+be important old versions of files or deleted file, and just because the
+user wants to stop using git-annex, doesn't mean git-annex shouldn't try to
+protect that data with its dying breath. So it prints out some suggestions
+in this case, and leaves it up to the user to decide what to do with the
+data.
+
+Fixed the Android autobuilder, which had stopped including the webapp.
+
+Looks like another autobuilder will be needed for OSX 10.9.
diff --git a/doc/design/assistant/blog/day_297__back_to_work/comment_1_e300feb821bfe7b76b2cec4376d16ffa._comment b/doc/design/assistant/blog/day_297__back_to_work/comment_1_e300feb821bfe7b76b2cec4376d16ffa._comment
new file mode 100644
index 000000000..4e0042ed5
--- /dev/null
+++ b/doc/design/assistant/blog/day_297__back_to_work/comment_1_e300feb821bfe7b76b2cec4376d16ffa._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://grossmeier.net/"
+ nickname="greg"
+ subject="uninit"
+ date="2013-07-16T23:43:38Z"
+ content="""
+Hah, that bit me in the butt when I first started experimenting with git-annex. I didn't lose anything, but it taught me a very important lesson (that I've had to learn many a time).
+"""]]
diff --git a/doc/design/assistant/blog/day_298__exceptional.mdwn b/doc/design/assistant/blog/day_298__exceptional.mdwn
new file mode 100644
index 000000000..6be34821e
--- /dev/null
+++ b/doc/design/assistant/blog/day_298__exceptional.mdwn
@@ -0,0 +1,21 @@
+Theme today seems to be fun with exceptions.
+
+Fixed an uncaught exception that could crash the assistant's Watcher thread
+if just the right race occurred.
+
+Also fixed it to not throw an exception if another process is
+already transferring a file. What this means is that if you run multiple
+`git annex get` processes on the same files, they'll cooperate in each
+picking their own files to get and download in parallel. (Also works for
+copy, etc.) Especially useful when downloading from an encrypted remote,
+since often one process will be decrypting a file while the other is
+downloading the next file. There is still room for improvement here;
+a -jN option could better handle ensuring N downloads ran concurrently, and
+decouple decryption from downloading. But it would need the output layer to
+be redone to avoid scrambled output. (All the other stuff to make parallel
+git-annex transfers etc work was already in place for a long time.)
+
+----
+
+Campaign update: Now funded for nearly 10 months, and aiming for a year.
+<https://campaign.joeyh.name/>
diff --git a/doc/design/assistant/blog/day_299__bugfixing.mdwn b/doc/design/assistant/blog/day_299__bugfixing.mdwn
new file mode 100644
index 000000000..274615191
--- /dev/null
+++ b/doc/design/assistant/blog/day_299__bugfixing.mdwn
@@ -0,0 +1,8 @@
+Succeeded fixing a few bugs today, and followed up on a lot of other ones..
+
+Fixed checking when content is present in a non-bare repository accessed via
+http.
+
+My changes a few days ago turned out to make uninit leave hard links behind
+in .git/annex. Luckily the test suite caught this bug, and it was easily
+fixed by making uninit delete objects with 2 or more hard links at the end.
diff --git a/doc/design/assistant/blog/day_2__races.mdwn b/doc/design/assistant/blog/day_2__races.mdwn
new file mode 100644
index 000000000..19f868a71
--- /dev/null
+++ b/doc/design/assistant/blog/day_2__races.mdwn
@@ -0,0 +1,45 @@
+Last night I got `git annex watch` to also handle deletion of files.
+This was not as tricky as feared; the key is using `git rm --ignore-unmatch`,
+which avoids most problematic situations (such as a just deleted file
+being added back before git is run).
+
+Also fixed some races when `git annex watch` is doing its startup scan of
+the tree, which might be changed as it's being traversed. Now only one
+thread performs actions at a time, so inotify events are queued up during
+the scan, and dealt with once it completes. It's worth noting that inotify
+can only buffer so many events .. Which might have been a problem except
+for a very nice feature of Haskell's inotify interface: It has a thread
+that drains the limited inotify buffer and does its own buffering.
+
+----
+
+Right now, `git annex watch` is not as fast as it could be when doing
+something like adding a lot of files, or deleting a lot of files.
+For each file, it currently runs a git command that updates the index.
+I did some work toward coalescing these into one command (which `git annex`
+already does normally). It's not quite ready to be turned on yet,
+because of some races involving `git add` that become much worse
+if it's delayed by event coalescing.
+
+----
+
+And races were the theme of today. Spent most of the day really
+getting to grips with all the fun races that can occur between
+modification happening to files, and `git annex watch`. The [[inotify]]
+page now has a long list of known races, some benign, and several,
+all involving adding files, that are quite nasty.
+
+I fixed one of those races this evening. The rest will probably involve
+moving away from using `git add`, which necessarily examines the file
+on disk, to directly shoving the symlink into git's index.
+
+BTW, it turns out that `dvcs-autosync` has grappled with some of these same
+races: <http://comments.gmane.org/gmane.comp.version-control.home-dir/665>
+I hope that `git annex watch` will be in a better place to deal with them,
+since it's only dealing with git, and with a restricted portion of it
+relevant to git-annex.
+
+It's important that `git annex watch` be rock solid. It's the foundation
+of the git annex assistant. Users should not need to worry about races
+when using it. Most users won't know what race conditions are. If only I
+could be so lucky!
diff --git a/doc/design/assistant/blog/day_300__new_logo.mdwn b/doc/design/assistant/blog/day_300__new_logo.mdwn
new file mode 100644
index 000000000..9e13c4b13
--- /dev/null
+++ b/doc/design/assistant/blog/day_300__new_logo.mdwn
@@ -0,0 +1,36 @@
+git-annex has a new nicer versions of its [[logo]], thanks to John Lawrence.
+
+Finally tracked down a week-old bug about the watcher crashing. It turned
+out to crash when it encountered a directory containing a character that's
+invalid in the current locale. I've noticed that 'ü' is often the character I
+get bug reports about. After reproducing the bug I quickly tracked it down
+to code in the haskell hinotify library, and sent in a patch.
+
+Also uploaded a fixed hinotify to Debian, and deployed it to all 3 of the
+autobuilder chroots. That took much more time than actually fixing the bug.
+Quite a lot of yak shaving went on actually. Oh well. The Linux
+autobuilders are updated to use Debian unstable again, which is nice.
+
+Fixed a bug that prevented annex.diskreserve to be honored when storing
+files encrypted in a directory special remote.
+
+Taught the webapp the difference between initializing a new special remote
+and enabling an existing special remote, which fixed some bad behavior when
+it got confused.
+
+----
+
+And then for the really fun bug of the day! A user sent me a large file
+which badly breaks git annex add. Adding the file causes a symlink to be
+set up, but the file's content is not stored in the annex. Indeed, it's
+deleted. This is the first data loss bug since January 2012.
+
+Turns out it was caused by the code that handles the dummy files git uses
+in place of symlinks on FAT etc filesystems. Code that had no business
+running when `core.symlinks=true`. Code that was prone to false positives
+when looking at a tarball of a git-annex repository. So I put in multiple
+fixes for this bug. I'll be making a release on Monday.
+
+----
+
+Today's work was sponsored by Mikhail Barabanov. Thanks, Mikhail!
diff --git a/doc/design/assistant/blog/day_300__new_logo/comment_1_9fc64e33863b9fce00f6a03417a91e36._comment b/doc/design/assistant/blog/day_300__new_logo/comment_1_9fc64e33863b9fce00f6a03417a91e36._comment
new file mode 100644
index 000000000..714fbc825
--- /dev/null
+++ b/doc/design/assistant/blog/day_300__new_logo/comment_1_9fc64e33863b9fce00f6a03417a91e36._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://launchpad.net/~mikapflueger"
+ nickname="mikapflueger"
+ subject="The dreaded &quot;ü&quot;"
+ date="2013-07-21T20:56:30Z"
+ content="""
+Yeah, with the last name of \"Pflüger\" I also usually find bugs having to do with the letter \"ü\". (-;
+I guess it is simply one of the more frequent german umlauts, especially in names (the classic \"Müller\", which is one of the most common last names in Germany). And apparently the German cabal strikes here again.
+"""]]
diff --git a/doc/design/assistant/blog/day_300__new_logo/comment_2_e8aac0298f90004e81492d2c7f85eda0._comment b/doc/design/assistant/blog/day_300__new_logo/comment_2_e8aac0298f90004e81492d2c7f85eda0._comment
new file mode 100644
index 000000000..b4bd78e3c
--- /dev/null
+++ b/doc/design/assistant/blog/day_300__new_logo/comment_2_e8aac0298f90004e81492d2c7f85eda0._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmNu4V5fvpLlBhaCUfXXOB0MI5NXwh8SkU"
+ nickname="Adam"
+ subject="Horns?"
+ date="2013-07-31T19:53:51Z"
+ content="""
+I don't necessarily mean this as a criticism, just an observation. I wasn't a big fan of the old logo, but this new one looks like it has horns. Or a bit like a pitchfork.
+"""]]
diff --git a/doc/design/assistant/blog/day_300__new_logo/comment_3_6308c767f6e4bf090102191c91520d04._comment b/doc/design/assistant/blog/day_300__new_logo/comment_3_6308c767f6e4bf090102191c91520d04._comment
new file mode 100644
index 000000000..beb5e281e
--- /dev/null
+++ b/doc/design/assistant/blog/day_300__new_logo/comment_3_6308c767f6e4bf090102191c91520d04._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.21"
+ subject="comment 3"
+ date="2013-07-31T20:03:13Z"
+ content="""
+I think the arrows are a bit too pointy. If someone wants to adjust the svg to make the arrows have a bit more of a rounded feel like in the old logo, that'd be fine by me.
+"""]]
diff --git a/doc/design/assistant/blog/day_301__direct_unannex.mdwn b/doc/design/assistant/blog/day_301__direct_unannex.mdwn
new file mode 100644
index 000000000..c227607d6
--- /dev/null
+++ b/doc/design/assistant/blog/day_301__direct_unannex.mdwn
@@ -0,0 +1,21 @@
+No release today after all. Unexpected bandwidth failure. Maybe in a few
+days..
+
+Got unannex and uninit working in direct mode. This is one of the more
+subtle parts of git-annex, and took some doing to get it right.
+Surprisingly, unannex in direct mode actually turns out to be faster than
+in indirect mode. In direct mode it doesn't have to immediately commit the
+unannexing, it can just stage it to be committed later.
+
+Also worked on the ssh connection caching code. The perrennial problem with
+that code is that the fifo used to communicate with ssh has a small limit
+on its path, somewhere around 100 characters. This had caused problems when
+the hostname was rather long. I found a way to avoid needing to be able to
+reverse back from the fifo name to the hostname, and this let me take the
+md5sum of long hostnames, and use that shorter string for the fifo.
+
+Also various other bug followups.
+
+----
+
+[Campaign](https://campaign.joeyh.name/) is almost to 1 year!
diff --git a/doc/design/assistant/blog/day_302_release_day.mdwn b/doc/design/assistant/blog/day_302_release_day.mdwn
new file mode 100644
index 000000000..d9dd9ec55
--- /dev/null
+++ b/doc/design/assistant/blog/day_302_release_day.mdwn
@@ -0,0 +1,6 @@
+Got the release out.
+
+I've been working on fleshing out
+the [[timeline|/design/assistant]] for the next year.
+Including a fairly detailed set of things I want to do around
+[[/design/assistant/disaster_recovery]] in the assistant.
diff --git a/doc/design/assistant/blog/day_302_release_day/comment_1_fe6e572ba706e95188463d9f3e004d03._comment b/doc/design/assistant/blog/day_302_release_day/comment_1_fe6e572ba706e95188463d9f3e004d03._comment
new file mode 100644
index 000000000..86984c478
--- /dev/null
+++ b/doc/design/assistant/blog/day_302_release_day/comment_1_fe6e572ba706e95188463d9f3e004d03._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmnG4EuvZWse5hvgrl0XAK-U61e-0iGaao"
+ nickname="David"
+ subject="Broken dependencies on Debian wheezy "
+ date="2013-07-24T07:21:18Z"
+ content="""
+Hi Joey,
+Having installed this release (x86_64) on Debian wheezy I get the following error when I try to run git-annex:
+
+ git-annex: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.14' not found (required by git-annex)
+ git-annex: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.14' not found (required by $HOME/.local/share/git-annex//usr/lib/x86_64-linux-gnu/libidn.so.11)
+
+etc. for at least a dozen libraries. Different libs try to find different glibc version (2.14, 2.15, 2.16, 2.17). Previous releases were linked with GLIBC_2.13.
+
+
+
+"""]]
diff --git a/doc/design/assistant/blog/day_303__oops.mdwn b/doc/design/assistant/blog/day_303__oops.mdwn
new file mode 100644
index 000000000..639e96de8
--- /dev/null
+++ b/doc/design/assistant/blog/day_303__oops.mdwn
@@ -0,0 +1,8 @@
+Seems I forgot why I was using debian stable chroots to make the
+autobuilds: Lots of people still using old glibc version. Had to rebuild
+the stable chroots that I had upgraded to unstable. Wasted several hours..
+I was able to catch up on recent traffic in between.
+
+Was able to reproduce a bug where `git annex initremote` hung with some
+encrypted special remotes. Turns out to be a deadlock when it's not built
+with the threaded GHC runtime. So I've forced that runtime to be used.
diff --git a/doc/design/assistant/blog/day_304__dropunused_safety.mdwn b/doc/design/assistant/blog/day_304__dropunused_safety.mdwn
new file mode 100644
index 000000000..28f5dc13c
--- /dev/null
+++ b/doc/design/assistant/blog/day_304__dropunused_safety.mdwn
@@ -0,0 +1,28 @@
+The big news: Important behavior change in `git annex dropunused`. Now it
+checks, just like `git annex drop`, that it's not dropping the last copy of
+the file. So to lose data, you have to use `--force`. This continues the
+recent theme of making git-annex hold on more tenaciously to old data, and
+AFAIK it was the last place data could be removed without `--force`.
+
+Also a nice little fix to `git annex unused` so it doesn't identify
+temporary files as unused if they're being used to download a file.
+Fixing it was easy thanks to all the transfer logs and locking
+infrastucture built for the assistant.
+
+Fixed a bug in the assistant where even though syncing to a network
+remote was disabled, it would still sync with it every hour, or whenever
+a network connection was detected.
+
+Working on some direct mode scalability problems when thousands of the
+identical files are added. Fixing this may involvie replacing the current
+simple map files with something more scalable like a sqllite database.
+
+While tracking that down, I also found a bug with adding a ton of files
+in indirect mode, that could make the assistant stall.
+Turned out to be a laziness problem. (Worst kind of Haskell bug.) Fixed.
+
+----
+
+Today's sponsor is my sister, Anna Hess, who incidentially just put
+the manuscript of her latest ebook in the family's annex prior to its
+publication on Amazon this weekend.
diff --git a/doc/design/assistant/blog/day_304__dropunused_safety/comment_1_1bbcf6c74b6437c44ff8604401fb1432._comment b/doc/design/assistant/blog/day_304__dropunused_safety/comment_1_1bbcf6c74b6437c44ff8604401fb1432._comment
new file mode 100644
index 000000000..d69777090
--- /dev/null
+++ b/doc/design/assistant/blog/day_304__dropunused_safety/comment_1_1bbcf6c74b6437c44ff8604401fb1432._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlUbH3eytydcwlWqv8oauE2Jg4NwcV9uA0"
+ nickname="Anna"
+ subject="A good day to be the sponsor!"
+ date="2013-07-27T12:31:27Z"
+ content="""
+Thanks for mentioning me! I like being responsible for not allowing things to be deleted accidentally --- just my kind of feature. :-)
+
+As a shameless plug, here's the ebook mentioned above for those of you not privy to the family annex: http://www.amazon.com/Root-Cellar-Vegetables-Simplicity-ebook/dp/B00E6EGS0M/
+"""]]
diff --git a/doc/design/assistant/blog/day_305__interesting_bugs.mdwn b/doc/design/assistant/blog/day_305__interesting_bugs.mdwn
new file mode 100644
index 000000000..8b76c929d
--- /dev/null
+++ b/doc/design/assistant/blog/day_305__interesting_bugs.mdwn
@@ -0,0 +1,21 @@
+Worked on 3 interesting bugs today. One I noticed myself while doing tests
+with adding many thousands of files yesterday. Assistant was delaying
+making a last commit of the batch of files, and would only wake up and
+commit them after a further change was made. Turns out this bug was
+introduced in April while improving commit batching when making very large
+commits. I seem to remember someone mentioning this problem at some point,
+but I have not been able to find a bug report to close.
+
+Also tried to reproduce [[this_bug|bugs/utf8]]. Frustrating, because I'm
+quite sure I have made changes that will avoid it happening again,
+but since I still don't know what the root cause was, I can't let it go.
+
+The last bug is
+[[non-repos_in_repositories_list___40__+_other_weird_output__41___from_git_annex_status]]
+and is a most strange thing. Still trying to get a handle on multiple
+aspects of it.
+
+Also various other bug triage. Down to only 10 messages in my git-annex
+folder. That included merging about a dozen bugs about
+local pairing, that all seem to involve git-annex-shell not being found in
+path. Something is up with that..
diff --git a/doc/design/assistant/blog/day_306__offtopic.mdwn b/doc/design/assistant/blog/day_306__offtopic.mdwn
new file mode 100644
index 000000000..cf96401d5
--- /dev/null
+++ b/doc/design/assistant/blog/day_306__offtopic.mdwn
@@ -0,0 +1,2 @@
+Technically offtopic, but did a fun side project today:
+<http://joeyh.name/blog/entry/git-annex_as_a_podcatcher/>
diff --git a/doc/design/assistant/blog/day_307__buuuugs.mdwn b/doc/design/assistant/blog/day_307__buuuugs.mdwn
new file mode 100644
index 000000000..9cc4cae58
--- /dev/null
+++ b/doc/design/assistant/blog/day_307__buuuugs.mdwn
@@ -0,0 +1,31 @@
+Back to bug squashing. Fixed several, including a long-standing problem on
+OSX that made the app icon seem to "bounce" or not work. Followed up on a
+bunch more.
+
+The 4.20130723 git-annex release turns out to have broken support for
+running on crippled filesystems (Android, Windows). `git annex sync` will
+add dummy symlinks to the annex as if they were regular files, which is
+not good!
+[Recovery instructions](http://git-annex.branchable.com/bugs/regression_in_direct_mode_on_windows_:_weird___96__git_annex_sync__96___behavior/#comment-5d80649f9da85ac2fb505445a41207f5)
+I've updated the Android and Windows builds and recommend an immediate upgrade.
+Will make a formal release on Friday.
+
+Spent some time improving the test suite on Windows, to catch this bug,
+and fix a bug that was preventing it from testing `git annex sync` on
+Windows.
+
+----
+
+I am getting very frustrated with this "unknown UUID" problem that a dozen
+people have reported. So far nobody has given me enough information to
+reproduce the problem. It seems to have something to do with
+`git-annex-shell` not being found on the remote system that has been either
+local paired with or is being used as a ssh server, but I don't yet
+understand what. I have spent hours today trying various scenarios to break
+git-annex and get this problem to happen.
+
+I certainly can improve the webapp's behavior when a repository's UUID is
+not known. The easiest fix would be to simply not display such
+repositories. Or there could be a UI to try to get the UUID.
+But I'm more interested in fixing the core problem than putting
+in a UI bandaid.
diff --git a/doc/design/assistant/blog/day_308__ssh-agent.mdwn b/doc/design/assistant/blog/day_308__ssh-agent.mdwn
new file mode 100644
index 000000000..e18ff2ec1
--- /dev/null
+++ b/doc/design/assistant/blog/day_308__ssh-agent.mdwn
@@ -0,0 +1,16 @@
+Turns out ssh-agent is the cause of the unknown UUID bug! I got a tip
+about this from a user, and was quickly able to reproduce the bug that had
+eluded me so long. Anyone who has run `ssh-add` and is using ssh-agent
+would see the bug.
+
+It was easy enough to fix as it turns out. Just need to set IdentitiesOnly
+in .ssh/config where git-annex has set up its own IdentityFile to ensure
+that its special purpose ssh key is used rather than whatever key the
+ssh-agent has loaded into it. I do wonder why ssh behaves this way -- why
+would I set an IdentityFile for a host if I didn't want ssh to use it?
+
+Spent the rest of the day cleaning up after the bug. Since this affects so
+many people, I automated the clean up process. The webapp will
+detect repositories with this problem, and the user just has to click to
+clean up. It'll then correct their .ssh/config and re-enable the
+repository.
diff --git a/doc/design/assistant/blog/day_308__ssh-agent/comment_1_5f0fc810cf1e1cd9b3ddba3cd19bb19d._comment b/doc/design/assistant/blog/day_308__ssh-agent/comment_1_5f0fc810cf1e1cd9b3ddba3cd19bb19d._comment
new file mode 100644
index 000000000..a40921ef6
--- /dev/null
+++ b/doc/design/assistant/blog/day_308__ssh-agent/comment_1_5f0fc810cf1e1cd9b3ddba3cd19bb19d._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://launchpad.net/~mikapflueger"
+ nickname="mikapflueger"
+ subject="Thank you so much!"
+ date="2013-08-01T01:13:51Z"
+ content="""
+This behaviour of ssh has bugged me for years now (I even think it is an information leak – ssh offers basically all my public ssh keys to every server I try to connect to, even though that public key might be confidential). Although it had nothing to do with git-annex, you helped me a _lot_ by pointing me towards IdentitiesOnly. Really a nice setting!
+
+Cheers,
+
+Mika
+"""]]
diff --git a/doc/design/assistant/blog/day_309__filenames.mdwn b/doc/design/assistant/blog/day_309__filenames.mdwn
new file mode 100644
index 000000000..30c9b516c
--- /dev/null
+++ b/doc/design/assistant/blog/day_309__filenames.mdwn
@@ -0,0 +1,17 @@
+Today was a nice reminder that there are no end of bugs lurking in filename
+handling code.
+
+First, fixed a bug that prevented git-annex from adding
+filenames starting with ":", because that is a special character to git.
+
+Second, discovered that git 1.8.4 rc0 has changed `git-cat-file --batch` in
+a way that makes it impossible to operate on filenames containing spaces.
+This is, IMHO, a reversion, so hopefully my
+[bug report](http://bugs.debian.org/718517) will get it fixed.
+
+Put in a workaround for that, although using the broken version of git
+with a direct mode repository with lots of spaces in file or directory
+names is going to really slow down git-annex, since it often has to fork a
+new git cat-file process for each file.
+
+Release day tomorrow..
diff --git a/doc/design/assistant/blog/day_310__release_day.mdwn b/doc/design/assistant/blog/day_310__release_day.mdwn
new file mode 100644
index 000000000..1a8a84a66
--- /dev/null
+++ b/doc/design/assistant/blog/day_310__release_day.mdwn
@@ -0,0 +1,18 @@
+Got the release out, with rather a lot of fiddling to fix broken builds on
+various platforms.
+
+Also released a backport to Debian stable. This backport has the assistant,
+although without WebDAV support. Unfortunately it's an old version from
+May, since ghc transitions and issues have kept newer versions out of
+testing so far. Hope that will clear up soon (probably by dropping haskell
+support for s390x), and I can update it to a newer version.
+If nothing else it allows using direct mode with Debian stable.
+
+Pleased that the git-cat-files bug was quickly fixed by Peff and has
+already been pulled into Junio's release tree!
+
+----
+
+This evening, I've added an interface around the new improved
+`git check-ignore` in git 1.8.4. The assistant can finally honor `.gitignore`
+files!
diff --git a/doc/design/assistant/blog/day_310__release_day/comment_1_1e008583cebd8e373e83729529914db7._comment b/doc/design/assistant/blog/day_310__release_day/comment_1_1e008583cebd8e373e83729529914db7._comment
new file mode 100644
index 000000000..749f77d9d
--- /dev/null
+++ b/doc/design/assistant/blog/day_310__release_day/comment_1_1e008583cebd8e373e83729529914db7._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://adamspiers.myopenid.com/"
+ nickname="Adam"
+ subject="This makes me happy :-)"
+ date="2013-08-04T00:46:25Z"
+ content="""
+Glad my work was worth the effort. Thanks for that.
+"""]]
diff --git a/doc/design/assistant/blog/day_311__Windows_porting.mdwn b/doc/design/assistant/blog/day_311__Windows_porting.mdwn
new file mode 100644
index 000000000..fe14a6e4b
--- /dev/null
+++ b/doc/design/assistant/blog/day_311__Windows_porting.mdwn
@@ -0,0 +1,10 @@
+Made two big improvements to the Windows port, in just a few hours.
+First, got gpg working, and encrypted special remotes work on Windows.
+Next, fixed a permissions problem that was breaking removing files
+from directory special remotes on Windows.
+(Also cleaned up a lot of compiler warnings on Windows.)
+
+I think I'm almost ready to move the Windows port from alpha to beta
+status. The only really bad problem that I know of with using it is that
+due to a lack of locking, it's not safe to run multiple git-annex
+commands at the same time in Windows.
diff --git a/doc/design/assistant/blog/day_311__Windows_porting/comment_1_8e738f54a72557bee1e19970472b925c._comment b/doc/design/assistant/blog/day_311__Windows_porting/comment_1_8e738f54a72557bee1e19970472b925c._comment
new file mode 100644
index 000000000..9f4bf2284
--- /dev/null
+++ b/doc/design/assistant/blog/day_311__Windows_porting/comment_1_8e738f54a72557bee1e19970472b925c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlpSOjMH7Iaz56v6Pr9KCFSpbvMXvg-y9o"
+ nickname="Dominik"
+ subject="That's amazing..."
+ date="2013-08-17T11:18:05Z"
+ content="""
+...so pretty soon my bi-directional Mac <-> Win Git-Annex-Assitant sync via rsync.net will work without a VM on Windows :-)
+"""]]
diff --git a/doc/design/assistant/blog/day_312__DebConf_midpoint.mdwn b/doc/design/assistant/blog/day_312__DebConf_midpoint.mdwn
new file mode 100644
index 000000000..8e0758432
--- /dev/null
+++ b/doc/design/assistant/blog/day_312__DebConf_midpoint.mdwn
@@ -0,0 +1,30 @@
+Wow, 11 days off! I was busy with first dentistry and then DebConf.
+
+Yesterday I [visited CERN](http://joeyh.name/blog/entry/words_fail_me/) and
+got to talk with some of their IT guys about how they manage their tens of
+petabytes of data. Interested to hear they also have the equivilant of a
+per-subdirectory annex.numcopies setting. OTOH, they have half a billion
+more files than git's index file is likely to be able to scale to support. ;)
+
+Pushed a release out today despite not having many queued changes.
+Also, I got git-annex migrated to Debian testing, and so was also
+able to update the wheezy backport to a just 2 week old version.
+
+Today is also the last day of the [campaign](https://campaign.joeyh.name/)!
+
+----
+
+There has been a ton of discussion about git-annex here at DebConf,
+including 3 BoF sessions that mostly focused on it, amoung other git stuff.
+Also, RichiH will be presenting his
+"[Gitify Your Life](http://penta.debconf.org/dc13_schedule/events/1025.en.html)"
+talk on Friday; you can catch it on the [live stream](http://blog.debconf.org/blog/2013/08/14#hl_dc13_recordings).
+
+I've also had a continual stream of in-person bug and feature requests.
+(Mostly features.)
+These have been added to the wiki and I look forward to working on that
+backlog when I get home.
+
+As for coding, I am doing little here, but I do have a branch cooking that
+adds some options to `git annex import` to control handling of duplicate
+files.
diff --git a/doc/design/assistant/blog/day_313__back.mdwn b/doc/design/assistant/blog/day_313__back.mdwn
new file mode 100644
index 000000000..28c7f971d
--- /dev/null
+++ b/doc/design/assistant/blog/day_313__back.mdwn
@@ -0,0 +1,34 @@
+Back home. I have some 170 messages of backlog to attend to. Rather than
+digging into that on my first day back, I spent some time implementing some
+new features.
+
+`git annex import` has grown three options that help managing importing of
+duplicate files in different ways. I started work on that last week, but
+didn't have time to find a way to avoid the `--deduplicate` option
+checksumming each imported file twice. Unfortunately, I have still not
+found a way I'm happy with, so it works but is not as efficient as it could
+be.
+
+`git annex mirror` is a new command suggested to me by someone at DebConf
+(they don't seem to have filed the requested todo). It arranges for two
+repositories to contain the same set of files, as much as possible (when
+numcopies allows). So for example, `git annex mirror --to otherdrive`
+will make the otherdrive remote have the same files present and not present
+as the local repository.
+
+I am thinking about expanding `git annex sync` with an option to also sync
+data. I know some find it confusing that it only syncs the git metadata
+and not the file contents. That still seems to me to be the best and most
+flexible behavior, and not one I want to change in any case since
+it would be most unexpected if `git annex sync` downloaded a lot of stuff
+you don't want. But I can see making `git annex sync --data` download
+all the file contents it can, as well as uploading all available file
+contents to each remote it syncs with. And `git annex sync --data --auto`
+limit that to only the preferred content. Although perhaps
+these command lines are too long to be usable?
+
+----
+
+With the campaign more or less over, I only have a little over a week
+before it's time to dive into the first big item on the roadmap. Hope
+to be through the backlog by then.
diff --git a/doc/design/assistant/blog/day_313__back/comment_1_fbf3fdf9688c18156753d446facd942d._comment b/doc/design/assistant/blog/day_313__back/comment_1_fbf3fdf9688c18156753d446facd942d._comment
new file mode 100644
index 000000000..7230a1568
--- /dev/null
+++ b/doc/design/assistant/blog/day_313__back/comment_1_fbf3fdf9688c18156753d446facd942d._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="GLITTAH"
+ ip="77.247.181.162"
+ subject="comment 1"
+ date="2013-08-20T22:42:46Z"
+ content="""
+I wouldn't worry about the commands being too long. If they're used often enough, they'll get aliased.
+
+alias GASDA='git annex sync --data --auto'
+"""]]
diff --git a/doc/design/assistant/blog/day_314__quvi.mdwn b/doc/design/assistant/blog/day_314__quvi.mdwn
new file mode 100644
index 000000000..3c38e427d
--- /dev/null
+++ b/doc/design/assistant/blog/day_314__quvi.mdwn
@@ -0,0 +1,27 @@
+Made some good progress on the backlog today. Fixed some bugs, applied some
+patches. Noticing that without me around, things still get followed up
+on, to a point, for example incomplete test cases for bugs get corrected so
+they work. This is a very good thing. Community!
+
+I had to stop going through the backlog when I got to one message from
+Anarcat mentioning [quvi](http://quvi.sourceforge.net/). That turns
+out to be just what is needed to implement the often-requested feature
+of `git-annex addurl` supporting YouTube and other similar sites. So I
+spent the rest of the day making that work. For example:
+
+<pre>
+% git annex addurl --fast 'http://www.youtube.com/watch?v=1mxPFHBCfuU&list=PL4F80C7D2DC8D9B6C&index=1'
+addurl Star_Wars_X_Wing__Seth_Green__Clare_Grant__and_Mike_Lamond_Join_Wil_on_TableTop_SE2E09.webm ok
+</pre>
+
+Yes, that got the video title and used it as the filename, and yes,
+I can commit this file and run `git annex get` later, and it will be
+able to go download the video! I can even use `git annex fsck --fast`
+to make sure YouTube still has my videos. Awesome.
+
+The great thing about quvi is it takes the url to a video webpage, and
+returns an url that can be used to download the actual video file. So it
+simplifies ugly flash videos as far out of existence as is possible.
+However, since the direct url to the video file may not keep working for long.
+addurl actually records the page's url, with an added indication that quvi
+should be used to get it.
diff --git a/doc/design/assistant/blog/day_314__quvi/comment_1_3fdfb0742cb5422530ddd97b904f2a42._comment b/doc/design/assistant/blog/day_314__quvi/comment_1_3fdfb0742cb5422530ddd97b904f2a42._comment
new file mode 100644
index 000000000..797d25101
--- /dev/null
+++ b/doc/design/assistant/blog/day_314__quvi/comment_1_3fdfb0742cb5422530ddd97b904f2a42._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmNu4V5fvpLlBhaCUfXXOB0MI5NXwh8SkU"
+ nickname="Adam"
+ subject="New YouTube problems"
+ date="2013-09-05T03:45:16Z"
+ content="""
+Joey, you may notice eventually that YouTube is moving some videos, especially long ones, to a new format called DASH, which splits them up into smaller parts; unfortunately, it also delivers the audio as a separate file, requiring something like ffmpeg to merge it with the video. I don't know anything about quvi, but youtube-dl recently added support for DASH. It's a Python program that's packaged in Debian, but it can also update itself if you install it locally, which is helpful if Debian is frozen... Anyway, if you need it in the future, youtube-dl might be helpful.
+"""]]
diff --git a/doc/design/assistant/blog/day_315__backlog.mdwn b/doc/design/assistant/blog/day_315__backlog.mdwn
new file mode 100644
index 000000000..ec0ee33be
--- /dev/null
+++ b/doc/design/assistant/blog/day_315__backlog.mdwn
@@ -0,0 +1,12 @@
+After a couple days plowing through it, my backlog is down to 30 messages
+from 150. And most of what's left is legitimate bugs and todo items.
+
+Spent a while today on an ugly file descriptor leak in the assistant's
+local pairing listener. This was an upstream bug in the network-multicast
+library, so while I've written a patch to fix it, the fix isn't quite
+deployed yet. The file descriptor leak happens when the assistant is
+running and there is no network interface that supports multicast.
+I was able to reproduce it by just disconnecting from wifi.
+
+Meanwhile, guilhem has been working on patches that promise to massively
+speed up `git annex unused`! I will be reviewing them tonight.
diff --git a/doc/design/assistant/blog/day_316__day_off.mdwn b/doc/design/assistant/blog/day_316__day_off.mdwn
new file mode 100644
index 000000000..b26118b17
--- /dev/null
+++ b/doc/design/assistant/blog/day_316__day_off.mdwn
@@ -0,0 +1,6 @@
+Today was a day off, really. However, I have a job running to try to
+build get a version of ghc-android that works on newer Android releases.
+
+Also, guilhem's `git annex unused` speedup patch landed. The results are
+extrordinary -- speedups on the order of 50 to 100 times faster should
+not be uncommon. Best of all (for me), it still runs in constant memory!
diff --git a/doc/design/assistant/blog/day_317__misc.mdwn b/doc/design/assistant/blog/day_317__misc.mdwn
new file mode 100644
index 000000000..e2acf2168
--- /dev/null
+++ b/doc/design/assistant/blog/day_317__misc.mdwn
@@ -0,0 +1,17 @@
+Spent a while tracking down a bug that causes a crash on OSX when setting
+up an XMPP account. I managed to find a small test case that reliably
+crashes, and sent it off to the author of the haskell-gnutls bindings,
+which had one similar segfault bug fixed before with a similar test case.
+Fingers crossed..
+
+Just finished tracking down a bug in the Android app that caused its
+terminal to spin and consume most CPU (and presumably a lot of battery).
+I introduced this bug when adding the code to open urls written to a fifo,
+due to misunderstanding how java objects are created, basically. This bug
+is bad enough to do a semi-immediate release for; luckily it's just about
+time for a release anyway with other improvements, so in the next few
+days..
+
+Have not managed to get a recent ghc-android to build so far.
+
+Guilhem fixed some bugs in `git annex unused`.
diff --git a/doc/design/assistant/blog/day_36__minimal_test_case.mdwn b/doc/design/assistant/blog/day_36__minimal_test_case.mdwn
new file mode 100644
index 000000000..b77da14dd
--- /dev/null
+++ b/doc/design/assistant/blog/day_36__minimal_test_case.mdwn
@@ -0,0 +1,9 @@
+Managed to find a minimal, 20 line test case for at least one of the ways
+git-annex was hanging with GHC's threaded runtime. Sent it off to
+haskell-cafe for analysis.
+[thread](http://thread.gmane.org/gmane.comp.lang.haskell.cafe/99334)
+
+Further managed to narrow the bug down to MissingH's use of logging code,
+that git-annex doesn't use. [bug report](http://bugs.debian.org/681621).
+So, I can at least get around this problem with a modified version of
+MissingH. Hopefully that was the only thing causing the hangs I was seeing!
diff --git a/doc/design/assistant/blog/day_37__back.mdwn b/doc/design/assistant/blog/day_37__back.mdwn
new file mode 100644
index 000000000..7aef0b681
--- /dev/null
+++ b/doc/design/assistant/blog/day_37__back.mdwn
@@ -0,0 +1,64 @@
+Back home and laptop is fixed.. back to work.
+
+Warmup exercises:
+
+* Went in to make it queue transfers when a broken symlink is received,
+ only to find I'd already written code to do that, and forgotten about it.
+ Heh. Did check that the git-annex branch is always sent first,
+ which will ensure that code always knows where to transfer a key from.
+ I had probably not considered this wrinkle when first writing the code;
+ it worked by accident.
+
+* Made the assistant check that a remote is known to have a key before
+ queueing a download from it.
+
+* Fixed a bad interaction between the `git annex map` command and the
+ assistant.
+
+----
+
+Tried using a modified version of `MissingH` that doesn't use `HSLogger`
+to make git-annex work with the threaded GHC runtime. Unfortunatly,
+I am still seeing hangs in at least 3 separate code paths when
+running the test suite. I may have managed to fix one of the hangs,
+but have not grokked what's causing the others.
+
+----
+
+I now have access to a Mac OSX system, thanks to Kevin M. I've fixed
+some portability problems in git-annex with it before, but today I tested
+the assistant on it:
+
+* Found a problem with the kqueue code that prevents incoming pushes from
+ being noticed.
+
+ The problem was that the newly added git ref file does not trigger an add
+ event. The kqueue code saw a generic change event for the refs directory,
+ but since the old file was being deleted and replaced by the new file,
+ the kqueue code, which already had the old file in its cache, did not notice
+ the file had been replaced.
+
+ I fixed that by making the kqueue code also track the inode of each file.
+ Currently that adds the overhead of a stat of each file, which could be
+ avoided if haskell exposed the inode returned by `readdir`. Room to
+ optimise this later...
+
+* Also noticed that the kqueue code was not separating out file deletions
+ from directory deletions. IIRC Jimmy had once mentioned a problem with file
+ deletions not being noticed by the assistant, and this could be responsible
+ for that, although the directory deletion code seems to handle them ok
+ normally. It was making the transfer watching thread not notice when
+ any transfers finished, for sure. I fixed this oversight, looking in the
+ cache to see if there used to be a file or a directory, and running the
+ appropriate hook.
+
+Even with these fixes, the assistant does not yet reliably transfer file
+contents on OSX. I think the problem is that with kqueue we're not
+guaranteed to get an add event, and a deletion event for a transfer
+info file -- if it's created and quickly deleted, the code that
+synthensizes those events doesn't run in time to know it existed.
+Since the transfer code relies on deletion events to tell when transfers
+are complete, it stops sending files after the first transfer, if the
+transfer ran so quickly it doesn't get the expected events.
+
+So, will need to work on OSX support some more...
diff --git a/doc/design/assistant/blog/day_39__twice_is_enemy_action.mdwn b/doc/design/assistant/blog/day_39__twice_is_enemy_action.mdwn
new file mode 100644
index 000000000..14896fcb1
--- /dev/null
+++ b/doc/design/assistant/blog/day_39__twice_is_enemy_action.mdwn
@@ -0,0 +1,66 @@
+Beating my head against the threaded runtime some more. I can reproduce
+one of the hangs consistently by running 1000 git annex add commands
+in a loop. It hangs around 1% of the time, reading from `git cat-file`.
+
+Interestingly, `git cat-file` is not yet running at this point --
+git-annex has forked a child process, but the child has not yet exec'd it.
+Stracing the child git-annex, I see it stuck in a futex. Adding tracing,
+I see the child never manages to run any code at all.
+
+This really looks like the problem is once again in MissingH, which uses
+`forkProcess`. Which happens to come with a big warning about being very
+unsafe, in very subtle ways. Looking at the C code that the newer `process`
+library uses when sparning a pipe to a process, it messes around with lots of
+things; blocking signals, stopping a timer, etc. Hundreds of lines of C
+code to safely start a child process, all doing things that MissingH omits.
+
+That's the second time I've seemingly isolated a hang in the GHC threaded
+runtime to MissingH.
+
+And so I've started converting git-annex to use the new `process` library,
+for running all its external commands. John Goerzen had mentioned `process`
+to me once before when I found a nasty bug in MissingH, as the cool new
+thing that would probably eliminate the `System.Cmd.Utils` part of MissingH,
+but I'd not otherwise heard much about it. (It also seems to have the
+benefit of supporting Windows.)
+
+This is a big change and it's early days, but each time I see a hang, I'm
+converting the code to use `process`, and so far the hangs have just gone
+away when I do that.
+
+---
+
+Hours later... I've converted *all* of git-annex to use `process`.
+
+In the er, process, the `--debug` switch stopped printing all the commands
+it runs. I may try to restore that later.
+
+I've not tested everything, but the test suite passes, even when
+using the threaded runtime. **MILESTONE**
+
+Looking forward to getting out of these weeds and back to useful work..
+
+---
+
+Hours later yet.... The `assistant` branch in git now uses the threaded
+runtime. It works beautifully, using proper threads to run file transfers
+in.
+
+That should fix the problem I was seeing on OSX yesterday. Too tired to
+test it now.
+
+--
+
+Amazingly, all the assistant's own dozen or so threads and thread
+synch variables etc all work great under the threaded runtime. I had
+assumed I'd see yet more concurrency problems there when switching to it,
+but it all looks good. (Or whatever problems there are are subtle ones?)
+
+I'm very relieved. The threaded logjam is broken! I had been getting
+increasingly worried that not having the threaded runtime available would
+make it very difficult to make the assistant perform really well, and cause
+problems with the webapp, perhaps preventing me from using Yesod.
+
+Now it looks like smooth sailing ahead. Still some hard problems, but
+it feels like with inotify and kqueue and the threaded runtime all
+dealt with, the really hard infrastructure-level problems are behind me.
diff --git a/doc/design/assistant/blog/day_3__more_races.mdwn b/doc/design/assistant/blog/day_3__more_races.mdwn
new file mode 100644
index 000000000..9c1182842
--- /dev/null
+++ b/doc/design/assistant/blog/day_3__more_races.mdwn
@@ -0,0 +1,26 @@
+Today I worked on the race conditions, and fixed two of them. Both
+were fixed by avoiding using `git add`, which looks at the files currently
+on disk. Instead, `git annex watch` injects symlinks directly into git's
+index, using `git update-index`.
+
+There is one bad race condition remaining. If multiple processes have a
+file open for write, one can close it, and it will be added to the annex.
+But then the other can still write to it.
+
+----
+
+Getting away from race conditions for a while, I made `git annex watch`
+not annex `.gitignore` and `.gitattributes` files.
+
+And, I made it handle running out of inotify descriptors. By default,
+`/proc/sys/fs/inotify/max_user_watches` is 8192, and that's how many
+directories inotify can watch. Now when it needs more, it will print
+a nice message showing how to increase it with `sysctl`.
+
+FWIW, DropBox also uses inotify and has the same limit. It seems to not
+tell the user how to fix it when it goes over. Here's what `git annex
+watch` will say:
+
+ Too many directories to watch! (Not watching ./dir4299)
+ Increase the limit by running:
+ echo fs.inotify.max_user_watches=81920 | sudo tee -a /etc/sysctl.conf; sudo sysctl -p
diff --git a/doc/design/assistant/blog/day_3__more_races/comment_1_d6015338f602b574a3805de5481fc45e._comment b/doc/design/assistant/blog/day_3__more_races/comment_1_d6015338f602b574a3805de5481fc45e._comment
new file mode 100644
index 000000000..2d330f332
--- /dev/null
+++ b/doc/design/assistant/blog/day_3__more_races/comment_1_d6015338f602b574a3805de5481fc45e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkmtR6oVColYKoU0SjBORLDGrwR10G-mKo"
+ nickname="Jo-Herman"
+ subject="Dropbox Inotify"
+ date="2012-06-06T22:03:29Z"
+ content="""
+Actually, Dropbox giver you a warning via libnotify inotify. It tends to go away too quickly to properly read though, much less actually copy down the command...
+"""]]
diff --git a/doc/design/assistant/blog/day_3__more_races/comment_2_4d6b23fc6442e0ee0303523cb69d0fba._comment b/doc/design/assistant/blog/day_3__more_races/comment_2_4d6b23fc6442e0ee0303523cb69d0fba._comment
new file mode 100644
index 000000000..523e6d85f
--- /dev/null
+++ b/doc/design/assistant/blog/day_3__more_races/comment_2_4d6b23fc6442e0ee0303523cb69d0fba._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.252.8.36"
+ subject="comment 2"
+ date="2012-06-06T23:25:57Z"
+ content="""
+When I work on the [[webapp]], I'm planning to make it display this warning, and any other similar warning messages that might come up.
+"""]]
diff --git a/doc/design/assistant/blog/day_3__more_races/comment_3_03f5b2344c2a47dea60086f217d60f9b._comment b/doc/design/assistant/blog/day_3__more_races/comment_3_03f5b2344c2a47dea60086f217d60f9b._comment
new file mode 100644
index 000000000..92f5dcbd6
--- /dev/null
+++ b/doc/design/assistant/blog/day_3__more_races/comment_3_03f5b2344c2a47dea60086f217d60f9b._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnBJ6Dv1glxzzi4qIzGFNa6F-mfHIvv9Ck"
+ nickname="Jim"
+ subject="Wording"
+ date="2012-06-07T03:43:19Z"
+ content="""
+For the unfamiliar, it's hard to tell if a command like that would persist. I'd suggest being as clear as possible, e.g.:
+
+ Increase the limit for now by running:
+ sudo sysctl fs.inotify.max_user_watches=81920
+ Increase the limit now and automatically at every boot by running:
+ echo fs.inotify.max_user_watches=81920 | sudo tee -a /etc/sysctl.conf; sudo sysctl -p
+
+"""]]
diff --git a/doc/design/assistant/blog/day_3__more_races/comment_4_860e90e989ec022100001c65e353a91e._comment b/doc/design/assistant/blog/day_3__more_races/comment_4_860e90e989ec022100001c65e353a91e._comment
new file mode 100644
index 000000000..05b601eaf
--- /dev/null
+++ b/doc/design/assistant/blog/day_3__more_races/comment_4_860e90e989ec022100001c65e353a91e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.252.8.36"
+ subject="comment 4"
+ date="2012-06-07T04:48:15Z"
+ content="""
+Good thought Jim. I've done something like that.
+"""]]
diff --git a/doc/design/assistant/blog/day_40__dbus.mdwn b/doc/design/assistant/blog/day_40__dbus.mdwn
new file mode 100644
index 000000000..049c3ffe0
--- /dev/null
+++ b/doc/design/assistant/blog/day_40__dbus.mdwn
@@ -0,0 +1,100 @@
+Really productive day today, now that I'm out of the threaded runtime
+tarpit!
+
+First, brought back `--debug` logging, better than before! As part of that, I
+wrote some 250 lines of code to provide a IMHO more pleasant interface to
+`System.Process` (itself only 650 lines of code) that avoids all the
+low-level setup, cleanup, and tuple unpacking. Now I can do things like
+write to a pipe to a process, and ensure it exits nonzero, this easily:
+
+ withHandle StdinHandle createProcessSuccess (proc "git" ["hash-object", "--stdin"]) $ \h ->
+ hHutStr h objectdata
+
+My interface also makes it easy to run nasty background processes,
+reading their output lazily.
+
+ lazystring <- withHandle StdoutHandle createBackgroundProcess (proc "find" ["/"]) hGetContents
+
+Any true Haskellers are shuddering here, I really should be using
+conduits or pipes, or something. One day..
+
+----
+
+The assistant needs to detect when removable drives are attached, and
+sync with them. This is a reasonable thing to be working on at this point,
+because it'll make the currently incomplete data transfer code fully usable
+for the sneakernet use case, and firming that up will probably be a good
+step toward handing other use cases involving data transfer over the
+network, including cases where network remotes are transientely available.
+
+So I've been playing with using dbus to detect mount events.
+There's a very nice Haskell library to use dbus.
+
+This simple program will detect removable drives being mounted, and
+works on Xfce (as long as you have automounting enabled in its
+configuration), and should also work on Gnome, and, probably, KDE:
+
+[[!format haskell """
+{-# LANGUAGE OverloadedStrings #-}
+
+import Data.List (sort)
+import DBus
+import DBus.Client
+import Control.Monad
+
+main = do
+ client <- connectSession
+
+ listen client mountadded $ \s ->
+ putStrLn (show s)
+
+ forever $ getLine -- let listener thread run forever
+
+ where
+ mountadded = matchAny
+ { matchInterface = Just "org.gtk.Private.RemoteVolumeMonitor"
+ , matchMember = Just "MountAdded"
+ }
+"""]]
+
+(Yeah... "org.gtk.Private.RemoteVolumeMonitor". There are so
+many things wrong with that string. What does gtk have to do with
+mounting a drive? Why is it Private? Bleagh. Should I only match
+the "MountAdded" member and not the interface? Seems everyone who does
+this relies on google to find other people who have cargo-culted it,
+or just runs `dbus-monitor` and picks out things.
+There seems to be no canonical list of events. Bleagh.)
+
+----
+
+Spent a while shaving a yak of needing a `getmntent` interface in Haskell.
+Found one in a hsshellscript library; since that library is not packaged
+in Debian, and I don't really want to depend on it, I extracted just
+the mtab and fstab parts of it into a little library in git-annex.
+
+----
+
+I've started putting together a MountWatcher thread. On systems without
+dbus (do OSX or the BSDs have dbus?), or if dbus is not running, it polls
+`/etc/mtab` every 10 seconds for new mounts. When dbus is available,
+it doesn't need the polling, and should notice mounts more quickly.
+
+Open question: Should it still poll even when dbus is available? Some of us
+like to mount our own drives, by hand and may have automounting disabled. It'd
+be good if the assistant supported that. This might need a
+`annex.no-dbus` setting, but I'd rather avoid needing such manual
+configuration.
+
+One idea is to do polling in addition to dbus, if `/etc/fstab` contains
+mount points that seem to be removable drives, on which git remotes lives.
+Or it could always do polling in addition to dbus, which is just some extra
+work. Or, it could try to introspect dbus to see if mount events will
+be generated.
+
+The MountWatcher so far only detects new mounts and prints out what
+happened. Next up: Do something in response to them.
+
+This will involve manipulating the Annex state to belatedly add the Remote
+on the mount point.. tricky. And then, for Git Remotes, it should pull/push
+the Remote to sync git data. Finally, for all remotes, it will need to
+queue Transfers of file contents from/to the newly available Remote.
diff --git a/doc/design/assistant/blog/day_40__dbus/comment_1_43ed2a79629868b018ec9f54a32bcacc._comment b/doc/design/assistant/blog/day_40__dbus/comment_1_43ed2a79629868b018ec9f54a32bcacc._comment
new file mode 100644
index 000000000..3670e7dd5
--- /dev/null
+++ b/doc/design/assistant/blog/day_40__dbus/comment_1_43ed2a79629868b018ec9f54a32bcacc._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="dbus vs polling"
+ date="2012-07-19T17:38:40Z"
+ content="""
+I am running KDE, dbus, and I like to mount drives by hand; all that without bothering to set up /etc/fstab... Often from CLI so I don't even see the notifications for new drives.
+
+Especially while on the road, I will use no KDE, but just a tty or three. Still, dbus will be running.
+
+Long story short, I would need polling for the assistant to work flawlessly in all use cases.
+"""]]
diff --git a/doc/design/assistant/blog/day_40__dbus/comment_2_6799f2baf6a6ce14b1fa76a8402840c0._comment b/doc/design/assistant/blog/day_40__dbus/comment_2_6799f2baf6a6ce14b1fa76a8402840c0._comment
new file mode 100644
index 000000000..832be854a
--- /dev/null
+++ b/doc/design/assistant/blog/day_40__dbus/comment_2_6799f2baf6a6ce14b1fa76a8402840c0._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="hamish"
+ ip="203.0.139.24"
+ subject="dbus vs polling "
+ date="2012-07-22T07:13:37Z"
+ content="""
+I, too, am running a dbus but like to hand mount my filesystems. However, I'd imagine that I am both a minority and that my minority could like the extra control, so perhaps even a \"re-read the mtab /now/\" command that can be manually run after something is manually mounted would suffice
+
+Is it not possible to use inotify on the mtab?
+"""]]
diff --git a/doc/design/assistant/blog/day_40__dbus/comment_3_fa1d7444bdafcb990cacf2ace7ee6ef1._comment b/doc/design/assistant/blog/day_40__dbus/comment_3_fa1d7444bdafcb990cacf2ace7ee6ef1._comment
new file mode 100644
index 000000000..a372670b8
--- /dev/null
+++ b/doc/design/assistant/blog/day_40__dbus/comment_3_fa1d7444bdafcb990cacf2ace7ee6ef1._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.169"
+ subject="comment 3"
+ date="2012-07-22T16:03:52Z"
+ content="""
+How did I not think about using my favorite hammer on this problem too? But, no, /proc/mounts cannot be watched with inotify it seems, and of course the BSDs don't seem to have a file at all.
+
+I think the dbus stuff is sorted out for manual users, see later blog entries.
+"""]]
diff --git a/doc/design/assistant/blog/day_40__dbus/comment_4_3399ddad951c1a950281bb6941fc3f6f._comment b/doc/design/assistant/blog/day_40__dbus/comment_4_3399ddad951c1a950281bb6941fc3f6f._comment
new file mode 100644
index 000000000..9007850e4
--- /dev/null
+++ b/doc/design/assistant/blog/day_40__dbus/comment_4_3399ddad951c1a950281bb6941fc3f6f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 2"
+ date="2012-07-19T18:43:30Z"
+ content="""
+Joey, yes dbus is available from macports and homebrew, it's not installed by default (or as a dependancy) for most packages in macports.
+"""]]
diff --git a/doc/design/assistant/blog/day_40__dbus/comment_5_40b6b9d741d3081203f0cc94eb8dc3ea._comment b/doc/design/assistant/blog/day_40__dbus/comment_5_40b6b9d741d3081203f0cc94eb8dc3ea._comment
new file mode 100644
index 000000000..38916dd8c
--- /dev/null
+++ b/doc/design/assistant/blog/day_40__dbus/comment_5_40b6b9d741d3081203f0cc94eb8dc3ea._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://smcv.pseudorandom.co.uk/"
+ nickname="smcv"
+ subject="comment 5"
+ date="2012-07-31T09:58:13Z"
+ content="""
+It's `org.gtk` because gvfs, GLib and Gtk are all products of gtk.org (there is no separate glib.org).
+
+It's `Private` because the gvfs developers don't consider its D-Bus interface to be stable API, I believe. The official API for it is the C API in GIO, part of GLib.
+
+To poll for changes to /proc/mounts on Linux, you open it for reading and poll() for POLLERR (not sure why it gets to be different, but it is). See gio/gunixmounts.c in recent GLib.
+"""]]
diff --git a/doc/design/assistant/blog/day_41__foo.mdwn b/doc/design/assistant/blog/day_41__foo.mdwn
new file mode 100644
index 000000000..99a977f60
--- /dev/null
+++ b/doc/design/assistant/blog/day_41__foo.mdwn
@@ -0,0 +1,46 @@
+I made the MountWatcher only use dbus if it sees a client connected to dbus
+that it knows will send mount events, or if it can start up such a client
+via dbus. (Fancy!) Otherwise it falls back to polling. This should be enough
+to support users who manually mount things -- if they have gvfs
+installed, it'll be used to detect their manual mounts, even when a desktop
+is not running, and if they don't have gvfs, they get polling.
+
+Also, I got the MountWatcher to work with KDE. Found a dbus event that's
+emitted when KDE mounts a drive, and this is also used. If anyone with
+some other desktop environment wants me to add support for it, and it uses
+dbus, it should be easy: Run `dbus-monitor`, plug in a drive, get
+it mounted, and send me a transcript.
+
+Of course, it'd also be nice to support anything similar on OSX that can
+provide mount event notifications. Not a priority though, since the polling
+code will work.
+
+---
+
+Some OS X fixes today..
+
+* Jimmy pointed out that my `getmntent` code broke the build on OSX again.
+ Sorry about that.. I keep thinking Unix portability nightmares are a 80's
+ thing, not a 2010's thing. Anyway, adapted a lot of hackish C code
+ to emulate `getmntent` on BSD systems, and it seems to work. (I actually
+ think the BSD interface to this is saner than Linux's, but I'd rather have
+ either one than both, sigh..)
+* Kqueue was blocking all the threads on OSX. This is fixed, and the
+ assistant seems to be working on OSX again.
+
+----
+
+I put together a preliminary page thanking everyone who contributed to the
+git-annex Kickstarter. [[/assistant/thanks]] The wall-o-names is scary crazy humbling.
+
+----
+
+Improved `--debug` mode for the assistant, now every thread says whenever
+it's doing anything interesting, and also there are timestamps.
+
+----
+
+Had been meaning to get on with syncing to drives when they're mounted, but
+got sidetracked with the above. Maybe tomorrow. I did think through it
+in some detail as I was waking up this morning, and think I have a pretty
+good handle on it.
diff --git a/doc/design/assistant/blog/day_41__foo/comment_1_ace21fa257a4c2fd412b6ff2944a23e8._comment b/doc/design/assistant/blog/day_41__foo/comment_1_ace21fa257a4c2fd412b6ff2944a23e8._comment
new file mode 100644
index 000000000..e27f7904e
--- /dev/null
+++ b/doc/design/assistant/blog/day_41__foo/comment_1_ace21fa257a4c2fd412b6ff2944a23e8._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnYD2ZzaOz-0anQDrN-Hg8Tvh5_C7wtStk"
+ nickname="roucaries"
+ subject="Portability"
+ date="2012-07-21T20:31:32Z"
+ content="""
+For portability why not using gnulib ? It will ease porting to windows BTW.
+
+Bastien
+"""]]
diff --git a/doc/design/assistant/blog/day_42__the_answer.mdwn b/doc/design/assistant/blog/day_42__the_answer.mdwn
new file mode 100644
index 000000000..fd7c4ebb5
--- /dev/null
+++ b/doc/design/assistant/blog/day_42__the_answer.mdwn
@@ -0,0 +1,27 @@
+Made the MountWatcher update state for remotes located in a drive that
+gets mounted. This was tricky code. First I had to make remotes declare
+when they're located in a local directory. Then it has to rescan git
+configs of git remotes (because the git repo mounted at a mount point may
+change), and update all the state that a newly available remote can affect.
+
+And it works: I plug in a drive containing one of my git remotes, and the
+assistant automatically notices it and syncs the git repositories.
+
+---
+
+But, data isn't transferred yet. When a disconnected remote becomes
+connected, keys should be transferred in both directions to get back into
+sync.
+
+To that end, added Yet Another Thread; the TransferScanner thread
+will scan newly available remotes to find keys, and queue low priority
+transfers to get them fully in sync.
+
+(Later, this will probably also be used for network remotes that become
+available when moving between networks. I think network-manager sends
+dbus events it could use..)
+
+This new thread is missing a crucial peice, it doesn't yet have a way to
+find the keys that need to be transferred. Doing that efficiently (without
+scanning the whole git working copy) is Hard. I'm considering design
+possibilities..
diff --git a/doc/design/assistant/blog/day_43__simple_scanner.mdwn b/doc/design/assistant/blog/day_43__simple_scanner.mdwn
new file mode 100644
index 000000000..11ee3cca4
--- /dev/null
+++ b/doc/design/assistant/blog/day_43__simple_scanner.mdwn
@@ -0,0 +1,37 @@
+Milestone: I can run `git annex assistant`, plug in a USB drive, and it
+automatically transfers files to get the USB drive and current repo back in
+sync.
+
+I decided to implement the naive scan, to find files needing to be
+transferred. So it walks through `git ls-files` and checks each file
+in turn. I've deferred less expensive, more sophisticated approaches to later.
+
+I did some work on the TransferQueue, which now keeps track of the length
+of the queue, and can block attempts to add Transfers to it if it gets too
+long. This was a nice use of STM, which let me implement that without using
+any locking.
+
+[[!format haskell """
+atomically $ do
+ sz <- readTVar (queuesize q)
+ if sz <= wantsz
+ then enqueue schedule q t (stubInfo f remote)
+ else retry -- blocks until queuesize changes
+"""]]
+
+Anyway, the point was that, as the scan finds Transfers to do,
+it doesn't build up a really long TransferQueue, but instead is blocked
+from running further until some of the files get transferred. The resulting
+interleaving of the scan thread with transfer threads means that transfers
+start fairly quickly upon a USB drive being plugged in, and kind of hides
+the innefficiencies of the scanner, which will most of the time be
+swamped out by the IO bound large data transfers.
+
+---
+
+At this point, the assistant should do a good job of keeping repositories
+in sync, as long as they're all interconnected, or on removable media
+like USB drives. There's lots more work to be done to handle use cases
+where repositories are not well-connected, but since the assistant's
+[[syncing]] now covers at least a couple of use cases, I'm ready to move
+on to the next phase. [[Webapp]], here we come!
diff --git a/doc/design/assistant/blog/day_44__webapp_basics.mdwn b/doc/design/assistant/blog/day_44__webapp_basics.mdwn
new file mode 100644
index 000000000..a8fdb131a
--- /dev/null
+++ b/doc/design/assistant/blog/day_44__webapp_basics.mdwn
@@ -0,0 +1,83 @@
+After an all-nighter, I have `git annex webapp` launching a WebApp!
+
+It doesn't do anything useful yet, just uses Yesod to display a couple of
+hyperlinked pages and a favicon, securely.
+
+The binary size grew rather alarmingly, BTW. :) Indeed, it's been growing
+for months..
+
+ -rwxr-xr-x 1 root root 9.4M Jul 21 16:59 git-annex-no-assistant-stripped
+ -rwxr-xr-x 1 joey joey 12M Jul 25 20:54 git-annex-no-webapp-stripped
+ -rwxr-xr-x 1 joey joey 17M Jul 25 20:52 git-annex-with-webapp-stripped
+
+----
+
+Along the way, some Not Invented Here occurred:
+
+I didn't use the yesod scaffolded site, because it's a lot of what
+seems mostly to be cruft in this use case. And because I don't like
+code generated from templates that people are then expected to edit. Ugh.
+That's my least favorite part of Yesod. This added some pain, since
+I had to do everything the hard way.
+
+I didn't use [wai-handler-launch](http://hackage.haskell.org/package/wai-handler-launch)
+because:
+
+ * It seems broken on IPv6 capable machines (it always opens
+ `http://127.0.0.1:port/` even though it apparently doesn't always
+ listen there.. I think it was listening on my machine's ipv6 address
+ instead. I know, I know; I should file a bug about this..)
+ * It always uses port 4587, which is **insane**. What if you have two
+ webapps?
+ * It requires javascript in the web browser, which
+ is used to ping the server, and shut it down when the web browser closes
+ (which behavior is wrong for git-annex anyway, since the daemon should
+ stay running across browser closes).
+ * It opens the webapp on web server startup, which is wrong for git-annex;
+ instead the command `git annex webapp` will open the webapp,
+ after `git annex assistant` started the web server.
+
+Instead, I rolled my own WAI webapp laucher, that binds to any free port
+on localhost, It does use `xdg-open` to launch the web browser,
+like wai-handler-launch (or just `open` on OS X).
+
+Also, I wrote my own WAI logger, which logs using System.Log.Logger,
+instead of to stdout, like `runDebug` does.
+
+----
+
+The webapp only listens for connections from localhost, but that's
+not sufficient "security". Instead, I added a secret token to
+every url in the webapp, that only `git annex webapp` knows about.
+
+But, if that token is passed to `xdg-open` on its command line,
+it will be briefly visible to local attackers in the parameters of
+`xdg-open`.. And if the web browser's not already running, it'll run
+with it as a parameter, and be *very* visible.
+
+So instead, I used a nasty hack. On startup, the assistant
+will create a html file, readably only by the user, that redirects
+the user to the real site url. Then `git annex webapp` will run
+xdg-open on that file.
+
+----
+
+Making Yesod check the `auth=` parameter (to verify that the secret token
+is right) is when using Yesod started to pay off. Yesod has a simple
+`isAuthorized` method that can be overridden to do your own authentication
+like this.
+
+But Yesod really started to shine when I went to add the `auth=` parameter
+to every url in the webapp. There's a `joinPath` method can can be used
+to override the default url builder. And every type-safe url in the
+application goes through there, so it's perfect for this.
+
+I just had to be careful to make it not add `auth=` to the url for the
+favicon, which is included in the "Permission Denied" error page. That'd be
+an amusing security hole..
+
+----
+
+Next up: Doing some AJAX to get a dynamic view of the state of the daemon,
+including currently running transfers, in the webapp. AKA stuff I've never
+done before, and that, unlike all this heavy Haskell Yesod, scares me. :)
diff --git a/doc/design/assistant/blog/day_44__webapp_basics/comment_1_d5fb67f373038e9f583cb2e1992bef67._comment b/doc/design/assistant/blog/day_44__webapp_basics/comment_1_d5fb67f373038e9f583cb2e1992bef67._comment
new file mode 100644
index 000000000..bc1f259e8
--- /dev/null
+++ b/doc/design/assistant/blog/day_44__webapp_basics/comment_1_d5fb67f373038e9f583cb2e1992bef67._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="http://jasonwoof.com/"
+ nickname="JasonWoof"
+ subject="Your security solution is fine"
+ date="2012-07-27T06:37:03Z"
+ content="""
+I think making the html file redirect is just fine. desktopcouch does something like this. They talk about it being there to help you find the port number, but it contains the security token too.
+
+They also have some javascript to delay the redirect for a while so you can bookmark the redirect file. You can click to set a cookie to skip the delay in future.
+
+It's been a while since I used desktopcouch, but I found an old redirect file laying around. Here it is:
+
+http://jasonwoof.com/downloads/desktopcouch-redirect.txt
+
+The code is pretty short, you might find something useful there.
+
+ - Jason
+"""]]
diff --git a/doc/design/assistant/blog/day_45__long_polling.mdwn b/doc/design/assistant/blog/day_45__long_polling.mdwn
new file mode 100644
index 000000000..380c55c12
--- /dev/null
+++ b/doc/design/assistant/blog/day_45__long_polling.mdwn
@@ -0,0 +1,66 @@
+The webapp now displays actual progress bars, for the actual transfers
+that the assistant is making! And it's seriously shiny.
+
+[[!img full.png]]
+
+Yes, I used Bootstrap. I can see why so many people are using it,
+that the common complaint is everything looks the same. I spent a few hours
+mocking up the transfer display part of the WebApp using Bootstrap, and
+arrived at something that doesn't entirely suck remarkably quickly.
+
+The really sweet thing about Bootstrap is that when I resized my browser to
+the shape of a cell phone, it magically redrew the WebApp like so:
+
+[[!img phone.png]]
+
+---
+
+To update the display, the WebApp uses two techniques. On noscript
+browsers, it just uses a meta refresh, which is about the best I can do. I
+welcome feedback; it might be better to just have an "Update" button in
+this case.
+
+With javascript enabled, it uses long polling, done over AJAX. There are
+some other options I considered, including websockets, and server-sent
+events. Websockets seem too new, and while there's a WAI module supporting
+server-sent events, and even an example of them in the Yesod book, the
+module is not packaged for Debian yet. Anyway, long polling is the most
+widely supported, so a good starting place. It seems to work fine too, I
+don't really anticipate needing the more sophisticated methods.
+
+(Incidentially, this's the first time I've ever written code that uses AJAX.)
+
+Currently the status display is rendered in html by the web server, and
+just updated into place by javascript. I like this approach since it
+keeps the javascript code to a minimum and the pure haskell code to a
+maximum. But who knows, I may have to switch to JSON that gets rendered by
+javascript, for some reason, later on.
+
+---
+
+I was very happy with Yesod when I managed to factor out a
+general purpose widget that adds long-polling and meta-refresh to any
+other widget. I was less happy with Yesod when I tried to include
+jquery on my static site and it kept serving up a truncated version of it.
+Eventually worked around what's seemingly a bug in the default WAI
+middleware, by disabling that middleware.
+
+----
+
+Also yesterday I realized there were about 30 comments stuck in moderation on
+this website. I thought I had a feed of those, but obviously I didn't. I've
+posted them all, and also read them all.
+
+----
+
+Next up is probably some cleanup of bugs and minor todos. Including
+figuring out why `watch` has started to segfault on OSX when it was
+working fine before.
+
+After that, I need to build a way to block the long polling request
+until the DaemonStatus and/or TransferQueue change from the version
+previously displayed by the WebApp. An interesting concurrency problem..
+
+Once I have that working, I can reduce the current 3 second delay between
+refreshes to a very short delay, and the WebApp will update in
+near-realtime as changes come in.
diff --git a/doc/design/assistant/blog/day_45__long_polling/comment_1_994bec0978324e268666073e8ff4f6ae._comment b/doc/design/assistant/blog/day_45__long_polling/comment_1_994bec0978324e268666073e8ff4f6ae._comment
new file mode 100644
index 000000000..20d3a64e6
--- /dev/null
+++ b/doc/design/assistant/blog/day_45__long_polling/comment_1_994bec0978324e268666073e8ff4f6ae._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://jasonwoof.com/"
+ nickname="JasonWoof"
+ subject="auth token length"
+ date="2012-07-27T18:52:19Z"
+ content="""
+Your auth token looks a little short. Aren't you worried about people brute-forcing it? ;)
+"""]]
diff --git a/doc/design/assistant/blog/day_45__long_polling/comment_2_dfa164c86290899139491acccddd8b2b._comment b/doc/design/assistant/blog/day_45__long_polling/comment_2_dfa164c86290899139491acccddd8b2b._comment
new file mode 100644
index 000000000..836fe89e9
--- /dev/null
+++ b/doc/design/assistant/blog/day_45__long_polling/comment_2_dfa164c86290899139491acccddd8b2b._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.2.20"
+ subject="comment 2"
+ date="2012-07-27T18:55:51Z"
+ content="""
+Heh, I consider it overflowing most address fields a bonus, as you don't have to worry when making screenshots. :)
+
+Of course, it changes each app run too..
+"""]]
diff --git a/doc/design/assistant/blog/day_45__long_polling/full.png b/doc/design/assistant/blog/day_45__long_polling/full.png
new file mode 100644
index 000000000..3963ae1dc
--- /dev/null
+++ b/doc/design/assistant/blog/day_45__long_polling/full.png
Binary files differ
diff --git a/doc/design/assistant/blog/day_45__long_polling/phone.png b/doc/design/assistant/blog/day_45__long_polling/phone.png
new file mode 100644
index 000000000..389334d95
--- /dev/null
+++ b/doc/design/assistant/blog/day_45__long_polling/phone.png
Binary files differ
diff --git a/doc/design/assistant/blog/day_46__notification_pools.mdwn b/doc/design/assistant/blog/day_46__notification_pools.mdwn
new file mode 100644
index 000000000..483ad95b1
--- /dev/null
+++ b/doc/design/assistant/blog/day_46__notification_pools.mdwn
@@ -0,0 +1,68 @@
+Focus today was writing a notification broadcaster library. This is a way to
+send a notification to a set of clients, any of which can be blocked
+waiting for a new notification to arrive. A complication is that any number
+of clients may be be dead, and we don't want stale notifications for those
+clients to pile up and leak memory.
+
+It took me 3 tries to find the solution, which turns out to be head-smackingly
+simple: An array of SampleVars, one per client.
+
+Using SampleVars means that clients only see the most recent notification,
+but when the notification is just "the assistant's state changed somehow;
+display a refreshed rendering of it", that's sufficient.
+
+----
+
+First use of that was to make the thread that woke up every 10 minutes
+and checkpointed the daemon status to disk also wait for a notification
+that it changed. So that'll be more current, and use less IO.
+
+----
+
+Second use, of course, was to make the WebApp block long polling clients
+until there is really a change since the last time the client polled.
+
+To do that, I made one change to my Yesod routes:
+
+[[!format diff """
+ -/status StatusR GET
+ +/status/#NotificationId StatusR GET
+"""]]
+
+Now I find another reason to love Yesod, because after doing that,
+I hit "make".. and fixed the type error. And hit make.. and fixed
+the type error. And then it just freaking worked! Html was generated with
+all urls to /status including a `NotificationId`, and the handler for
+that route got it and was able to use it:
+
+[[!format haskell """
+ {- Block until there is an updated status to display. -}
+ b <- liftIO $ getNotificationBroadcaster webapp
+ liftIO $ waitNotification $ notificationHandleFromId b nid
+"""]]
+
+And now the WebApp is able to display transfers in realtime!
+When I have both the WebApp and `git annex get` running on the same screen,
+the WebApp displays files that git-annex is transferring about as fast
+as the terminal updates.
+
+The [[progressbars]] still need to be sorted out, but otherwise
+the WebApp is a nice live view of file transfers.
+
+---
+
+I also had some fun with Software Transactional Memory. Now when the
+assistant moves a transfer from its queue of transfers to do, to its map of
+transfers that are currently running, it does so in an atomic transaction.
+This will avoid the transfer seeming to go missing (or be listed twice) if
+the webapp refreshes at just the wrong point in time. I'm really starting
+to get into STM.
+
+----
+
+Next up, I will be making the WebApp maintain a list of notices, displayed
+on its sidebar, scrolling new notices into view, and removing ones the user
+closes, and ones that expire. This will be used for displaying errors, as
+well as other communication with the user (such as displaying a notice
+while a git sync is in progress with a remote, etc). Seems worth doing now,
+so the basic UI of the WebApp is complete with no placeholders.
diff --git a/doc/design/assistant/blog/day_47__alert_messages.mdwn b/doc/design/assistant/blog/day_47__alert_messages.mdwn
new file mode 100644
index 000000000..81551fa95
--- /dev/null
+++ b/doc/design/assistant/blog/day_47__alert_messages.mdwn
@@ -0,0 +1,14 @@
+Some days I spend 2 hours chasing red herrings (like "perhaps my JSON ajax
+calls arn't running asynchronoously?") that turn out to be a simple
+one-word typo. This was one of them.
+
+However, I did get the sidebar displaying alert messages, which can be
+easily sent to the user from any part of the assistant. This includes
+transient alerts of things it's doing, which disappear once the action
+finishes, and long-term alerts that are displayed until the user closes
+them. It even supports rendering arbitrary Yesod widgets as alerts, so
+they can also be used for asking questions, etc.
+
+Time for a screencast!
+
+<video controls src="http://joeyh.name/screencasts/git-annex-webapp.ogg"></video>
diff --git a/doc/design/assistant/blog/day_48__intro.mdwn b/doc/design/assistant/blog/day_48__intro.mdwn
new file mode 100644
index 000000000..2cac85d4d
--- /dev/null
+++ b/doc/design/assistant/blog/day_48__intro.mdwn
@@ -0,0 +1,8 @@
+Lots of WebApp UI improvements, mostly around the behavior when
+displaying alert messages. Trying to make the alerts informative
+without being intrusively annoying, think I've mostly succeeded now.
+
+Also, added an intro display. Shown is the display with only one repo;
+if there are more repos it also lists them all.
+
+[[!img screenshot/intro.png]]
diff --git a/doc/design/assistant/blog/day_49__first_run_experience.mdwn b/doc/design/assistant/blog/day_49__first_run_experience.mdwn
new file mode 100644
index 000000000..437046d34
--- /dev/null
+++ b/doc/design/assistant/blog/day_49__first_run_experience.mdwn
@@ -0,0 +1,39 @@
+Started work on the interface displayed when the webapp is started
+with no existing git-annex repository. All this needs to do is walk the user
+through setting up a repository, as simply as possible.
+
+A tricky part of this is that most of git-annex runs in the Annex monad,
+which requires a git-annex repository. Luckily, much of the webapp
+does not run in Annex, and it was pretty easy to work around the parts that
+do. Dodged a bullet there.
+
+There will, however, be a tricky transition from this first run webapp,
+to a normally fully running git-annex assistant and webapp. I think the
+first webapp will have to start up all the normal threads once it makes the
+repository, and then redirect the user's web browser to the full webapp.
+
+Anyway, the UI I've made is very simple: A single prompt, for the
+directory where the repository should go. With, eventually, tab completion,
+sanity checking (putting the repository in "/" is not good, and making it
+all of "$HOME" is probably unwise).
+
+[[!img screenshot/firstrun.png]]
+
+Ideally most users will accept the default, which will be something
+like `/home/username/Desktop/Annex`, and be through this step in seconds.
+
+Suggestions for a good default directory name appreciated.. Putting it on a
+folder that will appear on the desktop seems like a good idea, when there's
+a Desktop directory. I'm unsure if I should name it something specific like
+"GitAnnex", or something generic like "Synced".
+
+Time for the first of probably many polls!
+
+What should the default directory name used by the git-annex assistant be?
+
+[[!poll open=no 19 "Annex" 7 "GitAnnex" 1 "~/git-annex/" 10 "Synced" 0 "AutoSynced" 1 "Shared" 10 "something lowercase!" 1 "CowboyNeal" 1 "Annexbox"]]
+
+(Note: This is a wiki. You can edit this page to add your own
+[[ikiwiki/directive/poll]] options!)
+
+[[!tag polls]]
diff --git a/doc/design/assistant/blog/day_49__first_run_experience/comment_1_e146cf06c8dd6303dd6a991f152a73fe._comment b/doc/design/assistant/blog/day_49__first_run_experience/comment_1_e146cf06c8dd6303dd6a991f152a73fe._comment
new file mode 100644
index 000000000..9f1d74e67
--- /dev/null
+++ b/doc/design/assistant/blog/day_49__first_run_experience/comment_1_e146cf06c8dd6303dd6a991f152a73fe._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://nico.kaiser.me/"
+ nickname="Nico Kaiser"
+ subject="Directory location"
+ date="2012-08-01T07:51:36Z"
+ content="""
+I don't think the Annex directory (or whatever it will be called – \"Annex\" seems like a good choice in my opinion) should be inside the \"Desktop\" folder by default. All other xdg-user-dirs (Documents, Downloads, etc.) are in $HOME, and i think Desktop should not be cluttered with folders.
+"""]]
diff --git a/doc/design/assistant/blog/day_49__first_run_experience/comment_2_5d6adcf6782c02283bef6189582ee467._comment b/doc/design/assistant/blog/day_49__first_run_experience/comment_2_5d6adcf6782c02283bef6189582ee467._comment
new file mode 100644
index 000000000..40f75ca0b
--- /dev/null
+++ b/doc/design/assistant/blog/day_49__first_run_experience/comment_2_5d6adcf6782c02283bef6189582ee467._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.3.236"
+ subject="comment 2"
+ date="2012-08-01T14:04:08Z"
+ content="""
+Hmm, my thought on putting it under Desktop is that'll let me install git-annex and tell my mom (really!) that files dragged to there are shared. Don't the other xdg directories get used as default save/open locations for things like word processors, so not need to be on the desktop?
+
+Although that may not be necessary. I've realized I can, at least on linux, easily make a button on the webapp that pops open the directory in the desktop's file manager.
+
+I guess another way of looking at the question is: Where does dropbox put its folder?
+"""]]
diff --git a/doc/design/assistant/blog/day_49__first_run_experience/comment_3_7ac2e34c2a7bc9b57488ca0c91307d32._comment b/doc/design/assistant/blog/day_49__first_run_experience/comment_3_7ac2e34c2a7bc9b57488ca0c91307d32._comment
new file mode 100644
index 000000000..22eff96b6
--- /dev/null
+++ b/doc/design/assistant/blog/day_49__first_run_experience/comment_3_7ac2e34c2a7bc9b57488ca0c91307d32._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawllHWUwOT-UVe5bGkk8G87bpeRAzy-5T7w"
+ nickname="Rick"
+ subject="Folder location"
+ date="2012-08-01T14:18:21Z"
+ content="""
+I'm of two minds about where the Annex folder should be.
+
+For beginners, the desktop is ideal. No doubt about it. And more experienced users can override the default path during the install.
+
+On the other hand, many of the other 'synced folder' services place their folder in the user's home. Both Dropbox and Skydrive do this. It's where I'd put it for consistency, and to keep my desktop free of clutter.
+
+It's a close call, but if push came to shove, I'd probably go with the user home folder.
+"""]]
diff --git a/doc/design/assistant/blog/day_49__first_run_experience/comment_4_549b07bb02c07a5b1b95445b01758db2._comment b/doc/design/assistant/blog/day_49__first_run_experience/comment_4_549b07bb02c07a5b1b95445b01758db2._comment
new file mode 100644
index 000000000..f261d1c23
--- /dev/null
+++ b/doc/design/assistant/blog/day_49__first_run_experience/comment_4_549b07bb02c07a5b1b95445b01758db2._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="dhess"
+ ip="173.247.200.7"
+ subject="Choose a friendly/unintimidating name"
+ date="2012-09-13T00:32:15Z"
+ content="""
+You've already decided to accommodate mom by choosing ~/Desktop as the default location, so you should be consistent: choose a name that means something to people. \"Annex\" and \"GitAnnex\" are good branding, but not very user-friendly. (Contrast with \"Dropbox\", the default folder name for Dropbox -- good branding *and* reasonably meaningful.)
+
+\"Shared\" is friendly, but implies that you're sharing with other people, which isn't necessarily the case. (You should reserve the name \"Shared\" for a sub-directory of the default directory, anyway, if/when the time comes to implement sharing URLs to your g-a-a objects with other users.)
+
+I think that \"Synced\" is fine. Most English-speakers will know what it means, and it's a good description of what g-a-a does.
+
+Don't worry whether we like it or not. Nobody who comments here, nor, likely, anyone who votes, will use the default name anyway ;)
+"""]]
diff --git a/doc/design/assistant/blog/day_4__speed.mdwn b/doc/design/assistant/blog/day_4__speed.mdwn
new file mode 100644
index 000000000..085d9547b
--- /dev/null
+++ b/doc/design/assistant/blog/day_4__speed.mdwn
@@ -0,0 +1,47 @@
+Only had a few hours to work today, but my current focus is speed, and I
+have indeed sped up parts of `git annex watch`.
+
+One thing folks don't realize about git is that despite a rep for being
+fast, it can be rather slow in one area: Writing the index. You don't
+notice it until you have a lot of files, and the index gets big. So I've
+put a lot of effort into git-annex in the past to avoid writing the index
+repeatedly, and queue up big index changes that can happen all at once. The
+new `git annex watch` was not able to use that queue. Today I reworked the
+queue machinery to support the types of direct index writes it needs, and
+now repeated index writes are eliminated.
+
+... Eliminated too far, it turns out, since it doesn't yet *ever* flush
+that queue until shutdown! So the next step here will be to have a worker
+thread that wakes up periodically, flushes the queue, and autocommits.
+(This will, in fact, be the start of the [[syncing]] phase of my roadmap!)
+There's lots of room here for smart behavior. Like, if a lot of changes are
+being made close together, wait for them to die down before committing. Or,
+if it's been idle and a single file appears, commit it immediately, since
+this is probably something the user wants synced out right away. I'll start
+with something stupid and then add the smarts.
+
+(BTW, in all my years of programming, I have avoided threads like the nasty
+bug-prone plague they are. Here I already have three threads, and am going to
+add probably 4 or 5 more before I'm done with the git annex assistant. So
+far, it's working well -- I give credit to Haskell for making it easy to
+manage state in ways that make it possible to reason about how the threads
+will interact.)
+
+What about the races I've been stressing over? Well, I have an ulterior
+motive in speeding up `git annex watch`, and that's to also be able to
+**slow it down**. Running in slow-mo makes it easy to try things that might
+cause a race and watch how it reacts. I'll be using this technique when
+I circle back around to dealing with the races.
+
+Another tricky speed problem came up today that I also need to fix. On
+startup, `git annex watch` scans the whole tree to find files that have
+been added or moved etc while it was not running, and take care of them.
+Currently, this scan involves re-staging every symlink in the tree. That's
+slow! I need to find a way to avoid re-staging symlinks; I may use `git
+cat-file` to check if the currently staged symlink is correct, or I may
+come up with some better and faster solution. Sleeping on this problem.
+
+----
+
+Oh yeah, I also found one more race bug today. It only happens at startup
+and could only make it miss staging file deletions.
diff --git a/doc/design/assistant/blog/day_4__speed/comment_1_bf3c9c33cc0dea5eaeb6f2af110b924b._comment b/doc/design/assistant/blog/day_4__speed/comment_1_bf3c9c33cc0dea5eaeb6f2af110b924b._comment
new file mode 100644
index 000000000..fb5b95490
--- /dev/null
+++ b/doc/design/assistant/blog/day_4__speed/comment_1_bf3c9c33cc0dea5eaeb6f2af110b924b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawldKnauegZulM7X6JoHJs7Gd5PnDjcgx-E"
+ nickname="Matt"
+ subject="open source?"
+ date="2012-06-09T22:34:30Z"
+ content="""
+Are you publishing the source code for git-annex assistant somewhere?
+"""]]
diff --git a/doc/design/assistant/blog/day_4__speed/comment_2_33aba4c9abaa3e6a05a2c87ab7df9d0e._comment b/doc/design/assistant/blog/day_4__speed/comment_2_33aba4c9abaa3e6a05a2c87ab7df9d0e._comment
new file mode 100644
index 000000000..1fcc197ab
--- /dev/null
+++ b/doc/design/assistant/blog/day_4__speed/comment_2_33aba4c9abaa3e6a05a2c87ab7df9d0e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.126"
+ subject="comment 2"
+ date="2012-06-09T23:01:29Z"
+ content="""
+Yes, it's in [[git|download]] with the rest of git-annex. Currently in the `watch` branch.
+"""]]
diff --git a/doc/design/assistant/blog/day_50__directory_name.mdwn b/doc/design/assistant/blog/day_50__directory_name.mdwn
new file mode 100644
index 000000000..a0e57cae6
--- /dev/null
+++ b/doc/design/assistant/blog/day_50__directory_name.mdwn
@@ -0,0 +1,20 @@
+Based on the results of yesterday's poll, the WebApp defaults to
+`~/Desktop/annex` when run in the home directory. If there's no `Desktop`
+directory, it uses just `~/annex`. And if run from some other place than
+the home directory, it assumes you want to use cwd. Of course, you can
+change this default, but I think it's a good one for most use cases.
+
+----
+
+My work today has all been on making **one second** of the total lifetime
+of the WebApp work. It's the very tricky second in between clicking on
+"Make repository" and being redirected to a WebApp running in your new
+repository. The trickiness involves threads, and MVars, and
+multiple web servers, and I don't want to go into details here.
+I'd rather forget. ;-)
+
+Anyway, it works; you can run "git annex webapp" and be walked right
+through to having a usable repository! Now I need to see about adding
+that to the desktop menus, and making "git annex webapp", when run a second
+time, remembering where your repository is. I'll use
+`~/.config/git-annex/repository` for storing that.
diff --git a/doc/design/assistant/blog/day_50__directory_name/comment_1_782cec95a8558a05b2b38a2d2302214d._comment b/doc/design/assistant/blog/day_50__directory_name/comment_1_782cec95a8558a05b2b38a2d2302214d._comment
new file mode 100644
index 000000000..be55932f1
--- /dev/null
+++ b/doc/design/assistant/blog/day_50__directory_name/comment_1_782cec95a8558a05b2b38a2d2302214d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 1"
+ date="2012-08-01T21:19:03Z"
+ content="""
+Please use `$XDG_CONFIG_HOME` and fall back to `~/.config` if that's not defined.
+"""]]
diff --git a/doc/design/assistant/blog/day_50__directory_name/comment_2_2b8ceb0a26f25e8ed2711bcbe7225a58._comment b/doc/design/assistant/blog/day_50__directory_name/comment_2_2b8ceb0a26f25e8ed2711bcbe7225a58._comment
new file mode 100644
index 000000000..a09b721be
--- /dev/null
+++ b/doc/design/assistant/blog/day_50__directory_name/comment_2_2b8ceb0a26f25e8ed2711bcbe7225a58._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://piotr.ozarowski.pl/"
+ nickname="POX"
+ subject="XDG"
+ date="2012-08-02T10:30:55Z"
+ content="""
+same for XDG_DESKTOP_DIR (for pl_PL ~/.config/user-dirs.dirs file contains XDG_DESKTOP_DIR=\"$HOME/Pulpit\" instead of Desktop)
+"""]]
diff --git a/doc/design/assistant/blog/day_51__desktop.mdwn b/doc/design/assistant/blog/day_51__desktop.mdwn
new file mode 100644
index 000000000..c079a9a91
--- /dev/null
+++ b/doc/design/assistant/blog/day_51__desktop.mdwn
@@ -0,0 +1,34 @@
+Now installing git-annex automatically generates a freedesktop.org .desktop
+file, and installs it, either system-wide (root) or locally (user). So
+`Menu -> Internet -> Git Annex` will start up the web app.
+
+(I don't entirely like putting it on the Internet menu, but the
+Accessories menu is not any better (and much more crowded here),
+and there's really no menu where it entirely fits.)
+
+I generated that file by writing a generic library to deal with
+freedesktop.org desktop files and locations. Which seemed like overkill at
+the time, but then I found myself continuing to use that library. Funny how
+that happens.
+
+So, there's also another .desktop file that's used to autostart the
+`git-annex assistant` daemon when the user logs into the desktop.
+
+This even works when git-annex is installed to the ugly non-PATH location
+`.cabal/bin/git-annex` by Cabal! To make that work, it records the path
+the binary is at to a freedesktop.org data file, at install time.
+
+---
+
+That should all work in Gnome, KDE, XFCE, etc. Not Mac OSX I'm guessing...
+
+---
+
+Also today, I added a sidebar notification when the assistant notices new
+files. To make that work well, I implemented merging of related sidebar
+action notifications, so the effect is that there's one notification that
+collectes a list of recently added files, and transient notifications that
+show up if a really big file is taking a while to checksum.
+
+I'm pleased that the notification interface is at a point where I was able
+to implement all that, entirely in pure functional code.
diff --git a/doc/design/assistant/blog/day_52__file_browser.mdwn b/doc/design/assistant/blog/day_52__file_browser.mdwn
new file mode 100644
index 000000000..a9762cc09
--- /dev/null
+++ b/doc/design/assistant/blog/day_52__file_browser.mdwn
@@ -0,0 +1,21 @@
+Today I added a "Files" link in the navbar of the WebApp. It looks like a
+regular hyperlink, but clicking on it opens up your desktop's native file
+manager, to manage the files in the repository!
+
+Quite fun to be able to do this kind of thing from a web page. :)
+
+---
+
+Made `git annex init` (and the WebApp) automatically generate a description
+of the repo when none is provided.
+
+---
+
+Also worked on the configuration pages some. I don't want to get ahead
+of myself by diving into the full configuration stage yet, but I am at
+least going to add a configuration screen to clone the repo to a removable
+drive.
+
+After that, the list of transfers on the dashboard needs some love.
+I'll probably start by adding UI to cancel running transfers, and then
+try to get drag and drop reordering of transfers working.
diff --git a/doc/design/assistant/blog/day_52__file_browser/comment_1_cd000c2d56b60cc1f17b221322a32aa7._comment b/doc/design/assistant/blog/day_52__file_browser/comment_1_cd000c2d56b60cc1f17b221322a32aa7._comment
new file mode 100644
index 000000000..206b0c70e
--- /dev/null
+++ b/doc/design/assistant/blog/day_52__file_browser/comment_1_cd000c2d56b60cc1f17b221322a32aa7._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://cweiske.de/"
+ nickname="cweiske"
+ subject="comment 1"
+ date="2012-08-15T22:02:14Z"
+ content="""
+I thought that most (if not all) browsers prevent opening local files/directories via web pages. How did you solve that problem?
+"""]]
diff --git a/doc/design/assistant/blog/day_52__file_browser/comment_2_21d1da67cf9105a545583ba2302c10fb._comment b/doc/design/assistant/blog/day_52__file_browser/comment_2_21d1da67cf9105a545583ba2302c10fb._comment
new file mode 100644
index 000000000..9ba5104e2
--- /dev/null
+++ b/doc/design/assistant/blog/day_52__file_browser/comment_2_21d1da67cf9105a545583ba2302c10fb._comment
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ subject="comment 2"
+ date="2012-08-16T23:34:12Z"
+ content="""
+Yes, it's surprising to me when I see it work, and I wrote it. :) Since git-annex is running locally on the same system as the browser, it can open the file manager when the user clicks on a link in the web browser. To the web browser, this is just an AJAX request.
+"""]]
diff --git a/doc/design/assistant/blog/day_54__adding_removable_drives.mdwn b/doc/design/assistant/blog/day_54__adding_removable_drives.mdwn
new file mode 100644
index 000000000..8d57518bb
--- /dev/null
+++ b/doc/design/assistant/blog/day_54__adding_removable_drives.mdwn
@@ -0,0 +1,99 @@
+Spent yesterday and today making the WebApp handle adding removable drives.
+
+While it needs more testing, I think that it's now possible to use the WebApp
+for a complete sneakernet usage scenario.
+
+* Start up the webapp, let it make a local repo.
+* Add some files, by clicking to open the file manager, and dragging them in.
+* Plug in a drive, and tell the webapp to add it.
+* Wait while files sync..
+* Take the drive to another computer, and repeat the process there.
+
+No command-line needed, and files will automatically be synced between
+two or more computers using the drive.
+
+Sneakernet is only one usage scenario for the git-annex assistant, but I'm
+really happy to have one scenario 100% working!
+
+Indeed, since the assistant and webapp can now actually do something
+useful, I'll probably be merging them into `master` soon.
+
+Details follow..
+
+---
+
+So, yesterday's part of this was building the configuration page to add
+a removable drive. That needs to be as simple as possible, and it currently
+consists of a list of things git-annex thinks might be mount points of
+removable drives, along with how much free space they have. Pick a drive,
+click the pretty button, and away it goes..
+
+(I decided to make the page so simple it doesn't even ask where you want
+to put the directory on the removable drive. It always puts it in
+a "annex" directory. I might add an expert screen later, but experts can
+always set this up themselves at the command line too.)
+
+I also fought with Yesod and Bootstrap rather a lot to make the form look good.
+Didn't entirely succeed, and had to file a bug on Yesod about its handling of
+check boxes. (Bootstrap also has a bug, IMHO; its drop down lists are not
+always sized wide enough for their contents.)
+
+Ideally this configuration page would listen for mount events, and refresh
+its list. I may add that eventually; I didn't have a handy channel it
+could use to do that, so defferred it. Another idea is to have the mount
+event listener detect removable drives that don't have an annex on them yet,
+and pop up an alert with a link to this configuration page.
+
+----
+
+Making the form led to a somewhat interesting problem: How to tell if a mounted
+filesystem is a removable drive, or some random thing like `/proc` or
+a fuse filesystem. My answer, besides checking that the user can
+write to it, was various heuristics, which seem to work ok, at least here..
+
+[[!format haskell """
+ sane Mntent { mnt_dir = dir, mnt_fsname = dev }
+ {- We want real disks like /dev/foo, not
+ - dummy mount points like proc or tmpfs or
+ - gvfs-fuse-daemon. -}
+ | not ('/' `elem` dev) = False
+ {- Just in case: These mount points are surely not
+ - removable disks. -}
+ | dir == "/" = False
+ | dir == "/tmp" = False
+ | dir == "/run/shm" = False
+ | dir == "/run/lock" = False
+"""]]
+
+----
+
+Today I did all the gritty coding to make it create a git repository on the
+removable drive, and tell the Annex monad about it, and ensure it gets synced.
+
+As part of that, it detects when the removable drive's filesystem doesn't
+support symlinks, and makes a bare repository in that case. Another expert
+level config option that's left out for now is to always make a bare
+repository, or even to make a directory special remote rather than a git
+repository at all. (But directory special remotes cannot support the
+sneakernet use case by themselves...)
+
+----
+
+Another somewhat interesting problem was what to call the git remotes
+that it sets up on the removable drive and the local repository.
+Again this could have an expert-level configuration, but the defaults
+I chose are to use the hostname as the remote name on the removable drive,
+and to use the basename of the mount point of the removable drive as the
+remote name in the local annex.
+
+----
+
+Originally, I had thought of this as cloning the repository to the drive.
+But, partly due to luck, I started out just doing a `git init` to make
+the repository (I had a function lying around to do that..).
+
+And as I worked on it some more, I realized this is not as simple as a
+clone. It's a bi-directional sync/merge, and indeed the removable drive may
+have all the data already in it, and the local repository have just been
+created. Handling all the edge cases of that (like, the local repository
+may not have a "master" branch yet..) was fun!
diff --git a/doc/design/assistant/blog/day_54__adding_removable_drives/comment_1_5de4f220a3534f55b1f2208d1d812d63._comment b/doc/design/assistant/blog/day_54__adding_removable_drives/comment_1_5de4f220a3534f55b1f2208d1d812d63._comment
new file mode 100644
index 000000000..56f513a38
--- /dev/null
+++ b/doc/design/assistant/blog/day_54__adding_removable_drives/comment_1_5de4f220a3534f55b1f2208d1d812d63._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 1"
+ date="2012-08-05T23:50:57Z"
+ content="""
+Using `annex` as default is fine, but even non-technical users will need a way to create different annexes for different usage. Or if two users share one thumb drive and each has their own annex. Long story short, I don't think this is an expert option, but something every user should be able to change immediately.
+
+A pre-populated text area makes most sense, imo.
+"""]]
diff --git a/doc/design/assistant/blog/day_54__adding_removable_drives/comment_2_8dae1ed0a70acf9628b88692dc32ac5f._comment b/doc/design/assistant/blog/day_54__adding_removable_drives/comment_2_8dae1ed0a70acf9628b88692dc32ac5f._comment
new file mode 100644
index 000000000..b26d9b85f
--- /dev/null
+++ b/doc/design/assistant/blog/day_54__adding_removable_drives/comment_2_8dae1ed0a70acf9628b88692dc32ac5f._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://dieter-be.myopenid.com/"
+ nickname="dieter"
+ subject="comment 2"
+ date="2012-08-06T08:30:47Z"
+ content="""
++1 on what Richard said
+about the correctly figuring out what are valid mountpoints / devices that can be used, your current code doesn't seem very robust.
+check this out https://github.com/Dieterbe/aif/blob/develop/src/core/libs/lib-blockdevices-filesystems.sh#L213
+"""]]
diff --git a/doc/design/assistant/blog/day_55__alerts.mdwn b/doc/design/assistant/blog/day_55__alerts.mdwn
new file mode 100644
index 000000000..95e52e8ad
--- /dev/null
+++ b/doc/design/assistant/blog/day_55__alerts.mdwn
@@ -0,0 +1,10 @@
+Nothing flashy today; I was up all night trying to download photos taken
+by a robot lowered onto Mars by a skycrane.
+
+Some work on alerts. Added an alert when a file transfer succeeds or fails.
+Improved the alert combining code so it handles those alerts, and
+simplified it a lot, and made it more efficient.
+
+Also made the text of action alerts change from present to past tense when
+the action finishes. To support that I wrote a fun data type, a `TenseString`
+that can be rendered in either tense.
diff --git a/doc/design/assistant/blog/day_55__alerts/comment_1_6319045500a8a5e049304fdec5ff4cf4._comment b/doc/design/assistant/blog/day_55__alerts/comment_1_6319045500a8a5e049304fdec5ff4cf4._comment
new file mode 100644
index 000000000..67259bf1e
--- /dev/null
+++ b/doc/design/assistant/blog/day_55__alerts/comment_1_6319045500a8a5e049304fdec5ff4cf4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlJ2utMQgMEYAOs3Dfc6eZRyUzt4acNXUU"
+ nickname="David"
+ subject="comment 1"
+ date="2012-08-06T23:48:28Z"
+ content="""
+I see you are a regular XKCD reader
+"""]]
diff --git a/doc/design/assistant/blog/day_56__transfer_control.mdwn b/doc/design/assistant/blog/day_56__transfer_control.mdwn
new file mode 100644
index 000000000..1ce926897
--- /dev/null
+++ b/doc/design/assistant/blog/day_56__transfer_control.mdwn
@@ -0,0 +1,8 @@
+A bit under the weather, but got into building buttons to control running
+and queued transfers today. The html and javascript side is done, with
+each transfer now having a cancel button, as well as a pause/start button.
+
+Canceling queued transfers works. Canceling running transfers will
+need some more work, because killing a thread doesn't kill the processes
+being run by that thread. So I'll have to make the assistant run separate
+git-annex processes for transfers, that can be individually sent signals.
diff --git a/doc/design/assistant/blog/day_57__afk.mdwn b/doc/design/assistant/blog/day_57__afk.mdwn
new file mode 100644
index 000000000..c72849ce7
--- /dev/null
+++ b/doc/design/assistant/blog/day_57__afk.mdwn
@@ -0,0 +1,40 @@
+Probably won't be doing any big coding on the git-annex assistant in the
+upcoming week, as I'll be traveling and/or slightly ill enough that I can't
+fully get into <a href="http://en.wikipedia.org/wiki/Flow_(psychology)">flow</a>.
+
+---
+
+There was a new Yesod release this week, which required minor changes to
+make the webapp build with it. I managed to keep the old version of Yesod
+also supported, and plan to keep that working so it can be built with the
+version of Yesod available in, eg, Linux distributions. TBD how much pain
+that will involve going forward.
+
+---
+
+I'm mulling over how to support stopping/pausing transfers. The problem
+is that if the assistant is running a transfer in one thread, and the
+webapp is used to cancel it, killing that thread won't necessarily stop the
+transfer, because, at least in Haskell's thread model, killing a thread
+does not kill processes started by the thread (like rsync).
+
+So one option is to have the transfer thread run a separate git-annex
+process, which will run the actual transfer. And killing that process will
+stop the transfer nicely. However, using a separate git-annex process means
+a little startup overhead for each file transferred (I don't know if it'd
+be enough to matter). Also, there's the problem that git-annex is sometimes
+not installed in PATH (wish I understood why cabal does that), which
+makes it kind of hard for it to run itself. (It can't simply fork, sadly.
+See past horrible pain with forking and threads.)
+
+The other option is to change the API for git-annex remotes, so that
+their `storeKey` and `retrieveKeyFile` methods return a pid of the program
+that they run. When they *do* run a program.. not all remotes do. This
+seems like it'd make the code in the remotes hairier, and it is also asking
+for bugs, when a remote's implementation changes. Or I could go
+lower-level, and make every place in the utility libraries that forks a
+process record its pid in a per-thread MVar. Still seems to be asking for
+bugs.
+
+Oh well, at least git-annex is already crash-safe, so once I figure out
+how to kill a transfer process, I can kill it safely. :)
diff --git a/doc/design/assistant/blog/day_57__afk/comment_1_70e1c9f925f040c1700d3e26bab373d5._comment b/doc/design/assistant/blog/day_57__afk/comment_1_70e1c9f925f040c1700d3e26bab373d5._comment
new file mode 100644
index 000000000..c83403620
--- /dev/null
+++ b/doc/design/assistant/blog/day_57__afk/comment_1_70e1c9f925f040c1700d3e26bab373d5._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://claimid.com/strager"
+ nickname="strager"
+ subject="comment 1"
+ date="2012-08-11T04:50:52Z"
+ content="""
+What if `storeKey`, `retrieveKeyFile`, etc. return an `IO ()` which cancels the operation, if possible? The implementation can be canceled regardless if it uses separate processes or Haskell threads.
+
+"""]]
diff --git a/doc/design/assistant/blog/day_57__afk/comment_2_c70d3faccfcebf47deb25e270498cb56._comment b/doc/design/assistant/blog/day_57__afk/comment_2_c70d3faccfcebf47deb25e270498cb56._comment
new file mode 100644
index 000000000..7539ea2de
--- /dev/null
+++ b/doc/design/assistant/blog/day_57__afk/comment_2_c70d3faccfcebf47deb25e270498cb56._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="http://claimid.com/strager"
+ nickname="strager"
+ subject="comment 2"
+ date="2012-08-11T04:55:13Z"
+ content="""
+In fact, making a dedicated data type or some typeclasses may be more appropriate:
+
+ class Cancelable a where cancel :: a -> IO ()
+ class Pauseable a where pause :: a -> IO ()
+
+ -- Alternatively:
+
+ data Transfer = Transfer { cancel :: IO (), pause :: IO () }
+
+ -- Or both!
+
+"""]]
diff --git a/doc/design/assistant/blog/day_57__afk/comment_3_89020ebc6d31485339bdea41a872df3c._comment b/doc/design/assistant/blog/day_57__afk/comment_3_89020ebc6d31485339bdea41a872df3c._comment
new file mode 100644
index 000000000..ed02b9dce
--- /dev/null
+++ b/doc/design/assistant/blog/day_57__afk/comment_3_89020ebc6d31485339bdea41a872df3c._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ subject="comment 3"
+ date="2012-08-11T14:41:51Z"
+ content="""
+That's the lines I was thinking along, and I even made a throwaway branch with some types. But the problem is reworking all the code to do that. Particularly since lots of the code uses generic utility functions that are reused in other, unrelated places and would have to be modified to pass back cancel actions.
+
+The first case the type checker landed me on when I changed the types was code that downloads an url from the web. Naturally that uses a Utility.Url.download. How to cancel `download`? Depends on its implementation -- it happens to currently shell out to curl, so you have to kill curl, but it could just as easily have used libcurl (other parts of my Utility.Url library do), and then it would need to fork its own thread. So it's an abstraction layer violation problem.
+
+If I had a month to devote to this one problem, I might manage to come up with some clean solution involving monads, or maybe convert all my code to use conduit or something that might allow managing these effects better. Just a guess..
+"""]]
diff --git a/doc/design/assistant/blog/day_57__afk/comment_4_8b1f65f141ffd9813e7f5a3380f7f520._comment b/doc/design/assistant/blog/day_57__afk/comment_4_8b1f65f141ffd9813e7f5a3380f7f520._comment
new file mode 100644
index 000000000..c87e447d1
--- /dev/null
+++ b/doc/design/assistant/blog/day_57__afk/comment_4_8b1f65f141ffd9813e7f5a3380f7f520._comment
@@ -0,0 +1,27 @@
+[[!comment format=mdwn
+ username="http://claimid.com/strager"
+ ip="173.228.13.253"
+ subject="comment 4"
+ date="2012-08-11T16:08:47Z"
+ content="""
+> How to cancel download? Depends on its implementation .... So it's an abstraction layer violation problem.
+
+Precisely why I suggested returning something as generic as `IO ()`:
+
+ -- Current
+ download :: URLString -> Headers -> [CommandParam] -> FilePath -> IO Bool
+
+ -- Suggestion
+ data Transfer a = Transfer { run :: IO a, cancel :: IO () }
+ download :: URLString -> Headers -> [CommandParam] -> FilePath -> Transfer
+
+ transfer <- download ...
+ -- You can pass `cancel transfer` to another thread
+ -- which you want to be able to cancel the transfer.
+ run transfer -- blocking
+
+I realized while writing this that you may not get any result from e.g. a download while it is occurring (because the function is blocking). Maybe that's where a misunderstanding occurred. I separated the concepts of creating a transfer and starting/canceling it.
+
+(My idea is starting to feel a bit object-oriented... ;P)
+
+"""]]
diff --git a/doc/design/assistant/blog/day_58__more_transfer_control.mdwn b/doc/design/assistant/blog/day_58__more_transfer_control.mdwn
new file mode 100644
index 000000000..08b69a75d
--- /dev/null
+++ b/doc/design/assistant/blog/day_58__more_transfer_control.mdwn
@@ -0,0 +1,26 @@
+Unexpectedly managed a mostly productive day today.
+
+Went ahead with making the assistant run separate `git-annex` processes for
+transfers. This will currently fail if git-annex is not installed in PATH.
+(Deferred dealing with that.)
+
+To stop a transfer, the webapp needs to signal not just the git-annex
+process, but all its children. I'm using process groups for this, which is
+working, but I'm not extremely happy with.
+
+Anyway, the webapp's UI can now be used for stopping transfers, and it
+wasn't far from there to also implementing pausing of transfers.
+
+Pausing a transfer is actually the same as stopping it, except a special
+signal is sent to the transfer control thread, which keeps running, despite
+the git-annex process having been killed, waits for a special resume
+signal, and restarts the transfer. This way a paused transfer continues to
+occupy a transfer slot, which prevents other queued transfers from running.
+This seems to be the behavior that makes sense.
+
+Still need to wire up the webapp's button for starting a transfer. For a
+paused transfer, that will just need to resume it. I have not decided what
+the button should do when used on a transfer that is queued but not running
+yet. Maybe it forces it to run even if all transfer slots are already in
+use? Maybe it stops one of the currently running transfers to free up a
+slot?
diff --git a/doc/design/assistant/blog/day_59__dinner.mdwn b/doc/design/assistant/blog/day_59__dinner.mdwn
new file mode 100644
index 000000000..545125ac6
--- /dev/null
+++ b/doc/design/assistant/blog/day_59__dinner.mdwn
@@ -0,0 +1,10 @@
+Actually did do some work on the webapp today, just fixing a bug I noticed
+in a spare moment. Also managed a bit in the plane earlier this week,
+implementing resuming of paused transfers. (Still need to test that.)
+
+But the big thing today was dinner with one of my major Kickstarter
+backers, and as it turned out, "half the Haskell community of San
+Francisco" (3 people). Enjoyed talking about git-annex and haskell with
+them.
+
+I'm looking forward to getting back home and back to work on Monday..
diff --git a/doc/design/assistant/blog/day_59__dinner/comment_1_0c1e2d69496473e7e4a2956a2814f5dd._comment b/doc/design/assistant/blog/day_59__dinner/comment_1_0c1e2d69496473e7e4a2956a2814f5dd._comment
new file mode 100644
index 000000000..1e10549d3
--- /dev/null
+++ b/doc/design/assistant/blog/day_59__dinner/comment_1_0c1e2d69496473e7e4a2956a2814f5dd._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://claimid.com/strager"
+ ip="173.228.13.253"
+ subject="comment 1"
+ date="2012-08-17T15:59:49Z"
+ content="""
+It was fun to have you here! =]
+
+"""]]
diff --git a/doc/design/assistant/blog/day_5__committing.mdwn b/doc/design/assistant/blog/day_5__committing.mdwn
new file mode 100644
index 000000000..562387380
--- /dev/null
+++ b/doc/design/assistant/blog/day_5__committing.mdwn
@@ -0,0 +1,57 @@
+After a few days otherwise engaged, back to work today.
+
+My focus was on adding the committing thread mentioned in [[day_4__speed]].
+I got rather further than expected!
+
+First, I implemented a really dumb thread, that woke up once per second,
+checked if any changes had been made, and committed them. Of course, this
+rather sucked. In the middle of a large operation like untarring a tarball,
+or `rm -r` of a large directory tree, it made lots of commits and made
+things slow and ugly. This was not unexpected.
+
+So next, I added some smarts to it. First, I wanted to stop it waking up
+every second when there was nothing to do, and instead blocking wait on a
+change occurring. Secondly, I wanted it to know when past changes happened,
+so it could detect batch mode scenarios, and avoid committing too
+frequently.
+
+I played around with combinations of various Haskell thread communications
+tools to get that information to the committer thread: `MVar`, `Chan`,
+`QSem`, `QSemN`. Eventually, I realized all I needed was a simple channel
+through which the timestamps of changes could be sent. However, `Chan`
+wasn't quite suitable, and I had to add a dependency on
+[Software Transactional Memory](http://en.wikipedia.org/wiki/Software_Transactional_Memory),
+and use a `TChan`. Now I'm cooking with gas!
+
+With that data channel available to the committer thread, it quickly got
+some very nice smart behavior. Playing around with it, I find it commits
+*instantly* when I'm making some random change that I'd want the
+git-annex assistant to sync out instantly; and that its batch job detection
+works pretty well too.
+
+There's surely room for improvement, and I made this part of the code
+be an entirely pure function, so it's really easy to change the strategy.
+This part of the committer thread is so nice and clean, that here's the
+current code, for your viewing pleasure:
+
+[[!format haskell """
+{- Decide if now is a good time to make a commit.
+ - Note that the list of change times has an undefined order.
+ -
+ - Current strategy: If there have been 10 commits within the past second,
+ - a batch activity is taking place, so wait for later.
+ -}
+shouldCommit :: UTCTime -> [UTCTime] -> Bool
+shouldCommit now changetimes
+ | len == 0 = False
+ | len > 4096 = True -- avoid bloating queue too much
+ | length (filter thisSecond changetimes) < 10 = True
+ | otherwise = False -- batch activity
+ where
+ len = length changetimes
+ thisSecond t = now `diffUTCTime` t <= 1
+"""]]
+
+Still some polishing to do to eliminate minor inefficiencies and deal
+with more races, but this part of the git-annex assistant is now very usable,
+and will be going out to my beta testers soon!
diff --git a/doc/design/assistant/blog/day_60__taking_stock.mdwn b/doc/design/assistant/blog/day_60__taking_stock.mdwn
new file mode 100644
index 000000000..040d0cd7c
--- /dev/null
+++ b/doc/design/assistant/blog/day_60__taking_stock.mdwn
@@ -0,0 +1,40 @@
+As I prepare to dive back into development, now is a good time to review
+what I've built so far, and how well I'm keeping up with my planned
+[[roadmap|assistant]].
+
+I started working two and a half months ago, so am nearing the end of
+the three months I originally asked to be funded for on Kickstarter.
+
+I've built much of what I planned to build in the first three months --
+[[inotify]] is done (and kqueue is basically working, but needs scalability
+work), local [[syncing]] is done, the [[webapp]] works, and I've built some
+of the first [[configurators]]. It's all functional in a narrow use case
+involving syncing to removable drives.
+
+[[progressbars]] still need to be dealt with, and network syncing needs to
+be revisited soon, so that I can start building easy configurators for
+further use cases, like using the cloud, or another machine on the local
+network.
+
+I think I'm a little behind my original schedule, but not too bad,
+and at the same time, I think I've built things rather more solidly than I
+expected them to be at this point. I'm particularly happy with how well
+the inotify code works, no matter what is thrown at it, and how nice
+the UI in the webapp is shaping up to be.
+
+----
+
+I also need to get started on fulfilling my Kickstarter rewards, and
+I was happy to spend some time in the airport working on the main
+blocker toward that, a lack of a scalable git-annex logo, which is needed
+for printing on swag.
+
+Turns out that inkscape has some amazing bitmap tracing capabilities.
+I was able to come up with this scalable logo in short order, it
+actually took longer to add back the colors, as the tracer generated a
+black and white version.
+
+With that roadblock out of the way, I am moving toward ordering large
+quantities of usb drives, etc.
+
+[[logo.svg]]
diff --git a/doc/design/assistant/blog/day_60__taking_stock/comment_1_6722f81ee084f1ea9e8fe47f34576397._comment b/doc/design/assistant/blog/day_60__taking_stock/comment_1_6722f81ee084f1ea9e8fe47f34576397._comment
new file mode 100644
index 000000000..cfe4fa300
--- /dev/null
+++ b/doc/design/assistant/blog/day_60__taking_stock/comment_1_6722f81ee084f1ea9e8fe47f34576397._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://dieter-be.myopenid.com/"
+ nickname="dieter"
+ subject="better logo?"
+ date="2012-08-20T21:22:25Z"
+ content="""
+Maybe you should contact designers and see what kind of logo they can come up with. Probably something better.
+"""]]
diff --git a/doc/design/assistant/blog/day_61__network_connection_detection.mdwn b/doc/design/assistant/blog/day_61__network_connection_detection.mdwn
new file mode 100644
index 000000000..8ab40f516
--- /dev/null
+++ b/doc/design/assistant/blog/day_61__network_connection_detection.mdwn
@@ -0,0 +1,36 @@
+Today, added a thread that deals with recovering when there's been a loss
+of network connectivity. When the network's down, the normal immediate
+syncing of changes of course doesn't work. So this thread detects when the
+network comes back up, and does a pull+push to network remotes, and
+triggers scanning for file content that needs to be transferred.
+
+I used dbus again, to detect events generated by both network-manager and
+wicd when they've sucessfully brought an interface up. Or, if they're not
+available, it polls every 30 minutes.
+
+When the network comes up, in addition to the git pull+push, it also
+currently does a full scan of the repo to find files whose contents
+need to be transferred to get fully back into sync.
+
+I think it'll be ok for some git pulls and pushes to happen when
+moving to a new network, or resuming a laptop (or every 30 minutes when
+resorting to polling). But the transfer scan is currently really too heavy
+to be appropriate to do every time in those situations. I have an idea for
+avoiding that scan when the remote's git-annex branch has not changed. But
+I need to refine it, to handle cases like this:
+
+1. a new remote is added
+2. file contents start being transferred to (or from it)
+3. the network is taken down
+4. all the queued transfers fail
+5. the network comes back up
+6. the transfer scan needs to know the remote was not all in sync
+ before #3, and so should do a full scan despite the git-annex branch
+ not having changed
+
+---
+
+Doubled the ram in my netbook, which I use for all development. Yesod needs
+rather a lot of ram to compile and link, and this should make me quite a
+lot more productive. I was struggling with OOM killing bits of chromium
+during my last week of development.
diff --git a/doc/design/assistant/blog/day_61__network_connection_detection/comment_1_09b58f41a8d48f218619711ee19511ac._comment b/doc/design/assistant/blog/day_61__network_connection_detection/comment_1_09b58f41a8d48f218619711ee19511ac._comment
new file mode 100644
index 000000000..029aec783
--- /dev/null
+++ b/doc/design/assistant/blog/day_61__network_connection_detection/comment_1_09b58f41a8d48f218619711ee19511ac._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmubB1Sj2rwFoVdZYvGV0ACaQUJQyiJXJI"
+ nickname="Paul"
+ subject="Amazon Glacier"
+ date="2012-08-23T06:32:24Z"
+ content="""
+Do you think git-annex could support [Amazon Glacier](http://aws.amazon.com/glacier/) as a backend?
+"""]]
diff --git a/doc/design/assistant/blog/day_62__smarter_syncing.mdwn b/doc/design/assistant/blog/day_62__smarter_syncing.mdwn
new file mode 100644
index 000000000..28fa892d3
--- /dev/null
+++ b/doc/design/assistant/blog/day_62__smarter_syncing.mdwn
@@ -0,0 +1,21 @@
+Woke up this morning with most of the design for a smarter approach to
+[[syncing]] in my head. (This is why I sometimes slip up and tell people I
+work on this project 12 hours a day..)
+
+To keep the current `assistant` branch working while I make changes
+that break use cases that are working, I've started
+developing in a new branch, `assistant-wip`.
+
+In it, I've started getting rid of unnecessary expensive transfer scans.
+
+First optimisation I've done is to detect when a remote that was
+disconnected has diverged its `git-annex` branch from the local branch.
+Only when that's the case does a new transfer scan need to be done, to find
+out what new stuff might be available on that remote, to have caused the
+change to its branch, while it was disconnected.
+
+That broke a lot of stuff. I have a plan to fix it written down in
+[[syncing]]. It'll involve keeping track of whether a transfer scan has
+ever been done (if not, one should be run), and recording logs when
+transfers failed, so those failed transfers can be retried when the
+remote gets reconnected.
diff --git a/doc/design/assistant/blog/day_63__transfer_retries.mdwn b/doc/design/assistant/blog/day_63__transfer_retries.mdwn
new file mode 100644
index 000000000..d668f507b
--- /dev/null
+++ b/doc/design/assistant/blog/day_63__transfer_retries.mdwn
@@ -0,0 +1,26 @@
+Implemented everything I planned out yesterday: Expensive scans are only
+done once per remote (unless the remote changed while it was disconnected),
+and failed transfers are logged so they can be retried later.
+
+Changed the TransferScanner to prefer to scan low cost remotes first,
+as a crude form of scheduling lower-cost transfers first.
+
+A whole bunch of interesting syncing scenarios should work now. I have not
+tested them all in detail, but to the best of my knowledge, all these
+should work:
+
+* Connect to the network. It starts syncing with a networked remote.
+ Disconnect the network. Reconnect, and it resumes where it left off.
+* Migrate between networks (ie, home to cafe to work). Any transfers
+ that can only happen on one LAN are retried on each new network you
+ visit, until they succeed.
+
+One that is not working, but is soooo close:
+
+* Plug in a removable drive. Some transfers start. Yank the plug.
+ Plug it back in. All necessary transfers resume, and it ends up
+ fully in sync, no matter how many times you yank that cable.
+
+That's not working because of an infelicity in the MountWatcher.
+It doesn't notice when the drive gets unmounted, so it ignores
+the new mount event.
diff --git a/doc/design/assistant/blog/day_63__transfer_retries/comment_1_990d4eb6066c4e2b9ddb3cabef32e4b9._comment b/doc/design/assistant/blog/day_63__transfer_retries/comment_1_990d4eb6066c4e2b9ddb3cabef32e4b9._comment
new file mode 100644
index 000000000..119aee2c9
--- /dev/null
+++ b/doc/design/assistant/blog/day_63__transfer_retries/comment_1_990d4eb6066c4e2b9ddb3cabef32e4b9._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="comment 1"
+ date="2012-08-23T21:25:48Z"
+ content="""
+Do encrypted rsync remotes resume quickly as well?
+
+One thing I noticed was that if a copy --to an encrypted rsync remote gets interrupted it will remove the tmp file and re-encrypt the whole file before resuming rsync.
+"""]]
diff --git a/doc/design/assistant/blog/day_64__syncing_robustly.mdwn b/doc/design/assistant/blog/day_64__syncing_robustly.mdwn
new file mode 100644
index 000000000..ab0090b92
--- /dev/null
+++ b/doc/design/assistant/blog/day_64__syncing_robustly.mdwn
@@ -0,0 +1,33 @@
+Working toward getting the data syncing to happen robustly,
+so a bunch of improvements.
+
+* Got unmount events to be noticed, so unplugging and replugging
+ a removable drive will resume the syncing to it. There's really no
+ good unmount event available on dbus in kde, so it uses a heuristic
+ there.
+* Avoid requeuing a download from a remote that no longer has a key.
+* Run a full scan on startup, for multiple reasons, including dealing with
+ crashes.
+
+Ran into a strange issue: Occasionally the assistant will run `git-annex
+copy` and it will not transfer the requested file. It seems that
+when the copy command runs `git ls-files`, it does not see the file
+it's supposed to act on in its output.
+
+Eventually I figured out what's going on: When updating the git-annex
+branch, it sets `GIT_INDEX_FILE`, and of course environment settings are
+not thread-safe! So there's a race between threads that access
+the git-annex branch, and the Transferrer thread, or any other thread
+that might expect to look at the normal git index.
+
+Unfortunatly, I don't have a fix for this yet.. Git's only interface for
+using a different index file is `GIT_INDEX_FILE`. It seems I have a lot of
+code to tear apart, to push back the setenv until after forking every git
+command. :(
+
+Before I figured out the root problem, I developed a workaround for the
+symptom I was seeing. I added a `git-annex transferkey`, which is
+optimised to be run by the assistant, and avoids running `git ls-files`, so
+avoids the problem. While I plan to fix this environment variable problem
+properly, `transferkey` turns out to be so much faster than how it was
+using `copy` that I'm going to keep it.
diff --git a/doc/design/assistant/blog/day_65__transfer_polish.mdwn b/doc/design/assistant/blog/day_65__transfer_polish.mdwn
new file mode 100644
index 000000000..af1c69162
--- /dev/null
+++ b/doc/design/assistant/blog/day_65__transfer_polish.mdwn
@@ -0,0 +1,33 @@
+Almost done with the data transfer code.. Today I filled in some bits and
+peices.
+
+Made the expensive transfer scan handle multiple remotes in one pass.
+So on startup, it only runs once, not N times. And when reconnecting to the
+network, when a remote has changed, it scans all network remotes in one
+pass, rather than making M redundant passes.
+
+Got syncing with special remotes all working. Pretty easy actually. Just
+had to avoid doing any git repo push/pull with them, while still queueing
+data transfers.
+
+It'll even download anything it can from the web special remote. To support
+that, I added generic support for readonly remotes; it'll only download from
+those and not try to upload to them.
+
+(Oh, and I properly fixed the nasty `GIT_INDEX_FILE` environment variable
+problem I had the other day.)
+
+I feel I'm very close to being able to merge the assistant branch into
+master now. I'm reasonably confident the data transfer code will work
+well now, and manage to get things in sync eventually in all circumstances.
+(Unless there are bugs.) All the other core functionality of the assistant
+and webapp is working. The only think I might delay because of is the
+missing [[progressbars]] in the webapp .. but that's a silly thing to
+block the merge on.
+
+Still, I might spend a day and get a dumb implementation of progress bars
+for downloads working first (progress bars for uploads are probably rather
+harder). I'd spend longer on progress bars, but there are so many more
+exciting things I'm now ready to develop, like automatic configurators
+for using your git annex with Amazon S3, rsync.net, and the computer across
+the room..!
diff --git a/doc/design/assistant/blog/day_66__the_merge.mdwn b/doc/design/assistant/blog/day_66__the_merge.mdwn
new file mode 100644
index 000000000..0442865ba
--- /dev/null
+++ b/doc/design/assistant/blog/day_66__the_merge.mdwn
@@ -0,0 +1,19 @@
+It's done! The assistant branch is merged into master.
+
+Updated the [[assistant]] page with some screenshots and instructions for
+using it.
+
+Made some cosmetic fixes to the webapp.
+
+Fixed the transferrer to use `~/.config/git-annex/program`
+to find the path to git-annex when running it. (There are ways to find the
+path of the currently running program in unux, but they all suck, so I'm
+avoiding them this way.)
+
+Read some OSX launchd documentation, and it seems it'd be pretty easy to
+get the assistant to autostart on login on OSX. If someone would like to
+test launchd files for me, get in touch.
+
+-----
+
+AKA: Procrastinating really hard on those progress bars. ;)
diff --git a/doc/design/assistant/blog/day_66__the_merge/comment_10_eeccf4e73cc321542a1fe4780805a81e._comment b/doc/design/assistant/blog/day_66__the_merge/comment_10_eeccf4e73cc321542a1fe4780805a81e._comment
new file mode 100644
index 000000000..2e787076d
--- /dev/null
+++ b/doc/design/assistant/blog/day_66__the_merge/comment_10_eeccf4e73cc321542a1fe4780805a81e._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://kevwalke.myopenid.com/"
+ ip="94.175.38.180"
+ subject="confirmed!"
+ date="2012-09-02T07:17:43Z"
+ content="""
+Got it built and running. Thanks for this.
+I can see already that this is going to be a fantastic application.
+
+Good Work!
+-Kev
+"""]]
diff --git a/doc/design/assistant/blog/day_66__the_merge/comment_1_a34e89316d1662826848f31061c4e46b._comment b/doc/design/assistant/blog/day_66__the_merge/comment_1_a34e89316d1662826848f31061c4e46b._comment
new file mode 100644
index 000000000..be612801e
--- /dev/null
+++ b/doc/design/assistant/blog/day_66__the_merge/comment_1_a34e89316d1662826848f31061c4e46b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://kevwalke.myopenid.com/"
+ ip="94.175.38.180"
+ subject="well done!"
+ date="2012-08-27T22:08:23Z"
+ content="""
+absolutely fantastic news! I am itching to try this out now. Thank you!
+"""]]
diff --git a/doc/design/assistant/blog/day_66__the_merge/comment_2_09e244d23d05052fa2b11a7181888366._comment b/doc/design/assistant/blog/day_66__the_merge/comment_2_09e244d23d05052fa2b11a7181888366._comment
new file mode 100644
index 000000000..874aa5ea6
--- /dev/null
+++ b/doc/design/assistant/blog/day_66__the_merge/comment_2_09e244d23d05052fa2b11a7181888366._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://claimid.com/strager"
+ ip="173.228.13.253"
+ subject="comment 2"
+ date="2012-08-28T16:29:56Z"
+ content="""
+I have a few OS X machines I can test on. Send me details at: strager.nds@gmail.com
+"""]]
diff --git a/doc/design/assistant/blog/day_66__the_merge/comment_3_3961a03e167903959b96b054835613f6._comment b/doc/design/assistant/blog/day_66__the_merge/comment_3_3961a03e167903959b96b054835613f6._comment
new file mode 100644
index 000000000..4a4d0df40
--- /dev/null
+++ b/doc/design/assistant/blog/day_66__the_merge/comment_3_3961a03e167903959b96b054835613f6._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 3"
+ date="2012-08-28T18:44:28Z"
+ content="""
+As per usual I'd volunteer to test on OSX as well.
+"""]]
diff --git a/doc/design/assistant/blog/day_66__the_merge/comment_4_12a57af9f580918818b4a9f68396d5c4._comment b/doc/design/assistant/blog/day_66__the_merge/comment_4_12a57af9f580918818b4a9f68396d5c4._comment
new file mode 100644
index 000000000..6852a805a
--- /dev/null
+++ b/doc/design/assistant/blog/day_66__the_merge/comment_4_12a57af9f580918818b4a9f68396d5c4._comment
@@ -0,0 +1,23 @@
+[[!comment format=mdwn
+ username="http://kevwalke.myopenid.com/"
+ ip="77.86.30.139"
+ subject="building and installing with cabal"
+ date="2012-08-29T18:15:07Z"
+ content="""
+So I got round to trying it out. I cloned the latest from the repository@ git://git-annex.branchable.com/ and then followed the instructions on the install page: http://git-annex.branchable.com/install/cabal/
+However I get a dependency problem:
+
+cabal install --only-dependencies
+Resolving dependencies...
+cabal: Could not resolve dependencies:
+trying: git-annex-3.20120825 (user goal)
+trying: git-annex-3.20120825:+oldyesod
+trying: git-annex-3.20120825:+currentyesod
+next goal: yesod-default (dependency of git-annex-3.20120825:+oldyesod)
+rejecting: yesod-default-1.1.0 (conflict: git-annex-3.20120825:oldyesod =>
+yesod-default(<=1.0.1.1))
+rejecting: yesod-default-1.0.1.1, 1.0.1, 1.0.0, 0.6.1, 0.5.0, 0.4.1, 0.4.0,
+0.3.1 (conflict: git-annex-3.20120825:currentyesod => yesod-default(>=1.1.0))
+
+I'm not sure how to proceed from here and would be grateful of any pointers to help get this built
+"""]]
diff --git a/doc/design/assistant/blog/day_66__the_merge/comment_5_8ce638960012367c888e018a5f05db19._comment b/doc/design/assistant/blog/day_66__the_merge/comment_5_8ce638960012367c888e018a5f05db19._comment
new file mode 100644
index 000000000..f51f5ef52
--- /dev/null
+++ b/doc/design/assistant/blog/day_66__the_merge/comment_5_8ce638960012367c888e018a5f05db19._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.16"
+ subject="comment 5"
+ date="2012-08-29T22:17:01Z"
+ content="""
+@kevwalke: I fixed that problem today.
+"""]]
diff --git a/doc/design/assistant/blog/day_66__the_merge/comment_6_f461b856b940e6914bcd2b681cf9505f._comment b/doc/design/assistant/blog/day_66__the_merge/comment_6_f461b856b940e6914bcd2b681cf9505f._comment
new file mode 100644
index 000000000..2232c426b
--- /dev/null
+++ b/doc/design/assistant/blog/day_66__the_merge/comment_6_f461b856b940e6914bcd2b681cf9505f._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://kevwalke.myopenid.com/"
+ ip="77.86.30.139"
+ subject="getting new error now."
+ date="2012-08-30T11:55:49Z"
+ content="""
+Seems there is still an issue here on fresh install...
+
+cabal: Error: some packages failed to install:
+dbus-0.10 depends on libxml-sax-0.7.2 which failed to install.
+libxml-sax-0.7.2 failed during the configure step. The exception was:
+ExitFailure
+"""]]
diff --git a/doc/design/assistant/blog/day_66__the_merge/comment_7_6e73aca1fc1747d0e742e054b88b5d78._comment b/doc/design/assistant/blog/day_66__the_merge/comment_7_6e73aca1fc1747d0e742e054b88b5d78._comment
new file mode 100644
index 000000000..0cb970a4c
--- /dev/null
+++ b/doc/design/assistant/blog/day_66__the_merge/comment_7_6e73aca1fc1747d0e742e054b88b5d78._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.16"
+ subject="comment 7"
+ date="2012-08-30T17:15:58Z"
+ content="""
+It's hard to tell from that error message what's going on. I'd hope that there was actually a real error message printed earlier than that that.
+
+For now, I can only guess.. In order to install the haskell libxml-sax library, you need to have the GNOME XML2 library installed, including development headers. On Debian and derivatives, that is `apt-get install libxml2-dev`.
+
+Alternatively, you can disable use of dbus by passing this to your cabal install: `--flags=-Dbus`
+"""]]
diff --git a/doc/design/assistant/blog/day_66__the_merge/comment_8_d85f1ce23ae16d5a8eb88d2c3999acb7._comment b/doc/design/assistant/blog/day_66__the_merge/comment_8_d85f1ce23ae16d5a8eb88d2c3999acb7._comment
new file mode 100644
index 000000000..f2068146d
--- /dev/null
+++ b/doc/design/assistant/blog/day_66__the_merge/comment_8_d85f1ce23ae16d5a8eb88d2c3999acb7._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="http://kevwalke.myopenid.com/"
+ ip="94.175.38.180"
+ subject="thanks"
+ date="2012-09-01T14:44:58Z"
+ content="""
+That got rid of that error. However now I get the following at the last step:
+
+Linking dist/build/git-annex/git-annex ...
+Installing executable(s) in /home/kev/bin
+setup: git-annex.1: does not exist
+cabal: Error: some packages failed to install:
+git-annex-3.20120826 failed during the final install step. The exception was:
+ExitFailure 1
+
+There doesn't seem to be any failures further up the output just some warnings. All the other steps complete fine
+Thanks for any advice/pointers here
+-Kevin
+"""]]
diff --git a/doc/design/assistant/blog/day_66__the_merge/comment_9_c06dab4d78122c85beeaf300ffc3e376._comment b/doc/design/assistant/blog/day_66__the_merge/comment_9_c06dab4d78122c85beeaf300ffc3e376._comment
new file mode 100644
index 000000000..5a2b3c8d1
--- /dev/null
+++ b/doc/design/assistant/blog/day_66__the_merge/comment_9_c06dab4d78122c85beeaf300ffc3e376._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.16"
+ subject="comment 9"
+ date="2012-09-01T19:32:02Z"
+ content="""
+I think I've fixed that.
+"""]]
diff --git a/doc/design/assistant/blog/day_67__progress_bars.mdwn b/doc/design/assistant/blog/day_67__progress_bars.mdwn
new file mode 100644
index 000000000..1110a3c3f
--- /dev/null
+++ b/doc/design/assistant/blog/day_67__progress_bars.mdwn
@@ -0,0 +1,10 @@
+Got the webapp's progress bars updating for downloads. Updated
+[[progressbars]] with all the options for ways to get progress info. For
+downloads, it currently uses the easy, and not very expensive, approach of
+periodically polling the sizes of files that are being downloaded.
+
+For uploads, something more sophisticated will be called for..
+
+---
+
+The webapp really feels alive now that it has progress bars!
diff --git a/doc/design/assistant/blog/day_68__transfers.mdwn b/doc/design/assistant/blog/day_68__transfers.mdwn
new file mode 100644
index 000000000..498f0eae4
--- /dev/null
+++ b/doc/design/assistant/blog/day_68__transfers.mdwn
@@ -0,0 +1,15 @@
+More work on the display and control of transfers.
+
+* Hide redundant downloads from the transfer display. It seemed simplest
+ to keep the behavior of queuing downloads from every remote that has a
+ file, rather than going to some other data structure, but it's clutter
+ to display those to the user, especially when you often have 7 copies
+ of each file, like I do.
+* When canceling a download, cancel all other queued downloads of that
+ key too.
+* Fixed unsettting of the paused flag when resuming a paused transfer.
+* Implemented starting queued transfers by clicking on the start button.
+* Spent a long time debugging why pausing, then resuming, and then pausing
+ a transfer doesn't successfully pause it the second time. I see where
+ the code is seemingly locking up in a `throwTo`, but I don't understand
+ why that blocks forever. Urgh..
diff --git a/doc/design/assistant/blog/day_68__transfers/comment_1_5282960c0b553fbc0f411345b9745324._comment b/doc/design/assistant/blog/day_68__transfers/comment_1_5282960c0b553fbc0f411345b9745324._comment
new file mode 100644
index 000000000..0921ae855
--- /dev/null
+++ b/doc/design/assistant/blog/day_68__transfers/comment_1_5282960c0b553fbc0f411345b9745324._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 1"
+ date="2012-08-29T21:24:37Z"
+ content="""
+It seems to be a bad idea to cancel everything when I cancel a single transfer.
+
+I may not want to transmit videos and RAW files at the moment, but would still like to know my JPGs are stored in a second location.
+
+Two obvious approaches, ideally both offered at the same time would be to allow the user to cancel, cancel all to this remote, and cancel all plus allowing them to send transfers to the end of the queue.
+
+If this is implemented already then sorry; I did _not_ test if this is available before writing this comment.
+"""]]
diff --git a/doc/design/assistant/blog/day_69__build_fixes.mdwn b/doc/design/assistant/blog/day_69__build_fixes.mdwn
new file mode 100644
index 000000000..c3ee34e27
--- /dev/null
+++ b/doc/design/assistant/blog/day_69__build_fixes.mdwn
@@ -0,0 +1,7 @@
+Short day today.
+
+* Worked on fixing a number of build failures people reported.
+* Solved the problem that was making transfer pause/resume not always work.
+ Although there is another bug where pausing a transfer sometimes lets
+ another queued transfer start running.
+* Worked on getting the assistant to start on login on OSX.
diff --git a/doc/design/assistant/blog/day_6__polish.mdwn b/doc/design/assistant/blog/day_6__polish.mdwn
new file mode 100644
index 000000000..ebe8068c3
--- /dev/null
+++ b/doc/design/assistant/blog/day_6__polish.mdwn
@@ -0,0 +1,50 @@
+Since my last blog, I've been polishing the `git annex watch` command.
+
+First, I fixed the double commits problem. There's still some extra
+committing going on in the `git-annex` branch that I don't understand. It
+seems like a shutdown event is somehow being triggered whenever
+a git command is run by the commit thread.
+
+I also made `git annex watch` run as a proper daemon, with locking to
+prevent multiple copies running, and a pid file, and everything.
+I made `git annex watch --stop` stop it.
+
+---
+
+Then I managed to greatly increase its startup speed. At startup, it
+generates "add" events for every symlink in the tree. This is necessary
+because it doesn't really know if a symlink is already added, or was
+manually added before it starter, or indeed was added while it started up.
+Problem was that these events were causing a lot of work staging the
+symlinks -- most of which were already correctly staged.
+
+You'd think it could just check if the same symlink was in the index.
+But it can't, because the index is in a constant state of flux. The
+symlinks might have just been deleted and re-added, or changed, and
+the index still have the old value.
+
+Instead, I got creative. :) We can't trust what the index says about the
+symlink, but if the index happens to contain a symlink that looks right,
+we can trust that the SHA1 of its blob is the right SHA1, and reuse it
+when re-staging the symlink. Wham! Massive speedup!
+
+---
+
+Then I started running `git annex watch` on my own real git annex repos,
+and noticed some problems.. Like it turns normal files already checked into
+git into symlinks. And it leaks memory scanning a big tree. Oops..
+
+---
+
+I put together a quick screencast demoing `git annex watch`.
+
+<video controls src="http://joeyh.name/screencasts/git-annex-watch.ogg"></video>
+
+While making the screencast, I noticed that `git-annex watch` was spinning
+in strace, which is bad news for powertop and battery usage. This seems to
+be a [GHC bug](http://bugs.debian.org/677096) also affecting Xmonad. I
+tried switching to GHC's threaded runtime, which solves that problem, but
+causes git-annex to hang under heavy load. Tried to debug that for quite a
+while, but didn't get far. Will need to investigate this further..
+Am seeing indications that this problem only affects ghc 7.4.1; in
+particular 7.4.2 does not seem to have the problem.
diff --git a/doc/design/assistant/blog/day_70__adding_ssh_remotes.mdwn b/doc/design/assistant/blog/day_70__adding_ssh_remotes.mdwn
new file mode 100644
index 000000000..be83daa31
--- /dev/null
+++ b/doc/design/assistant/blog/day_70__adding_ssh_remotes.mdwn
@@ -0,0 +1,66 @@
+Today I built the UI in the webapp to set up a ssh or rsync remote.
+
+This is the most generic type of remote, and so it's surely got the most
+complex description. I've tried to word it as clearly as I can; suggestions
+most appreciated. Perhaps I should put in a diagram?
+
+[[!img /assistant/addsshserver.png]]
+
+The idea is that this will probe the server, using ssh. If `git-annex-shell`
+is available there, it'll go on to set up a full git remote. If not, it'll
+fall back to setting up a rsync special remote. It'll even fall all the way
+back to using `rsync://` protocol if it can't connect by ssh. So the user
+can just point it at a server and let it take care of the details,
+generally.
+
+The trickiest part of this will be authentication, of course. I'm relying
+on ssh using `ssh-askpass` to prompt for any passwords, etc, when there's
+no controlling terminal. But beyond passwords, this has to deal with ssh
+keys.
+
+I'm planning to make it check if you have a ssh key configured already. If
+you do, it doesn't touch your ssh configuration. I don't want to get in the
+way of people who have a manual configuration or are using MonkeySphere.
+
+But for a user who has never set up a ssh key, it will prompt asking if
+they'd like a key to be set up. If so, it'll generate a key and configure
+ssh to only use it with the server.. and as part of its ssh probe, that key
+will be added to `authorized_keys`.
+
+(Obviously, advanced users can skip this entirely; `git remote add
+ssh://...` still works..)
+
+----
+
+Also today, fixed more UI glitches in the transfer display. I think
+I have them all fixed now, except for the one that needs lots of javascript
+to be written to fix it.
+
+Amusingly, while I was working on UI glitches, it turned out that all the
+fixes involved 100% pure code that has nothing to do with UI. The UI was
+actually just exposing bugs.
+
+For example, closing a running transfer
+had a bug that weirdly reordered the queue. This turned out to be
+due to the transfer queue actually maintaining two versions of the queue,
+one in a TChan and one a list. Some unknown bugs caused these to get out of
+sync. That was fixed very handily by deleting the TChan, so there's only
+one copy of the data.
+
+I had only been using that TChan because I wanted a way to block while the
+queue was empty. But now that I'm more comfortable with STM, I know how
+to do that easily using a list:
+
+[[!format haskell """
+ getQueuedTransfer q = atomically $ do
+ sz <- readTVar (queuesize q)
+ if sz < 1
+ then retry -- blocks until size changes
+ else ...
+"""]]
+
+Ah, the times before [STM](http://en.wikipedia.org/wiki/Software_transactional_memory)
+were dark times indeed. I'm writing more and more STM code lately, building
+up more and more complicated and useful transactions. If you use threads and
+don't know about STM, it's a great thing to learn, to get out of the dark ages
+of dealing with priority inversions, deadlocks, and races.
diff --git a/doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_10_2fac85357ac8feccff82beabd3791439._comment b/doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_10_2fac85357ac8feccff82beabd3791439._comment
new file mode 100644
index 000000000..1b4833b12
--- /dev/null
+++ b/doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_10_2fac85357ac8feccff82beabd3791439._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmLB39PC89rfGaA8SwrsnB6tbumezj-aC0"
+ nickname="Tobias"
+ subject="comment 10"
+ date="2012-09-09T16:58:55Z"
+ content="""
+That's great news.
+
+I suggest we disregard this comment thread, i'll just follow the proper bug report(which i guess i should have made to begin with).
+
+Thanks for your good work.
+
+"""]]
diff --git a/doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_11_e9e496005fd1bf5a10c9e286b83e51fa._comment b/doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_11_e9e496005fd1bf5a10c9e286b83e51fa._comment
new file mode 100644
index 000000000..1477a71db
--- /dev/null
+++ b/doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_11_e9e496005fd1bf5a10c9e286b83e51fa._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.30"
+ subject="comment 11"
+ date="2012-09-09T17:12:55Z"
+ content="""
+That bug should be fixed now.
+"""]]
diff --git a/doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_1_913e6ae7c8f7db90b9767ec35fc84205._comment b/doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_1_913e6ae7c8f7db90b9767ec35fc84205._comment
new file mode 100644
index 000000000..f797a0249
--- /dev/null
+++ b/doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_1_913e6ae7c8f7db90b9767ec35fc84205._comment
@@ -0,0 +1,23 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmLB39PC89rfGaA8SwrsnB6tbumezj-aC0"
+ nickname="Tobias"
+ subject="gpg encryption on ssh remotes"
+ date="2012-09-01T08:25:17Z"
+ content="""
+I've been playing around with the Assistant in the last few days.
+
+And besides for gpg encryption it works great.
+
+But whenever i set up a special remote(done it manually since you hadn't made this yet) it will break, bad.
+
+Some files will transfer fine, but at some point it will still(the stdout from git-annex webapp shows gpg being stupid).
+
+I get a huge amount of [git] <defunct> in my ps auxw. And two git-annex transferkey <key> --to host --file <some file>
+
+It seems to consistently fall on a 9mb file i have. I have found no way to recover from this(killing and restarting git-annex will say 'transfer already in progress'. Deleting the file was to no avail, it still tries to transfer).
+
+I have done a lot of testing and i've only seen this on special remotes when gpg encryption is enabled(i haven't tried encryption=shared)
+
+Besides for this issue, the Assistant is looking great.
+
+"""]]
diff --git a/doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_2_634ca3c236e2062289e7df5f0d77a3c5._comment b/doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_2_634ca3c236e2062289e7df5f0d77a3c5._comment
new file mode 100644
index 000000000..84e780b4b
--- /dev/null
+++ b/doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_2_634ca3c236e2062289e7df5f0d77a3c5._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.236"
+ subject="comment 2"
+ date="2012-09-02T21:40:17Z"
+ content="""
+@tobias, when you say \"gpg being stupid\", what exactly do you see at that point? Please paste it.
+"""]]
diff --git a/doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_3_e365bbcbb7f66ce2b35fcd5b969ab315._comment b/doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_3_e365bbcbb7f66ce2b35fcd5b969ab315._comment
new file mode 100644
index 000000000..741cdfc63
--- /dev/null
+++ b/doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_3_e365bbcbb7f66ce2b35fcd5b969ab315._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmLB39PC89rfGaA8SwrsnB6tbumezj-aC0"
+ nickname="Tobias"
+ subject="comment 3"
+ date="2012-09-02T23:49:17Z"
+ content="""
+Updated to the latest trunk, and did some more testing.
+
+I'll retract the \"gpg being stupid\" comment. it just gives the normal \"(gpg)\".
+
+There really isn't anything interesting in the stdout(but a lot of defunct git's in ps auxw), but i still can't get any files larger than ~710kbyte to transfer. They just stall.
+
+http://pastebin.com/ZA8dzxZD <- stdout/stderr
+http://pastebin.com/f1J1T79E <- ps auxw | grep git
+
+"""]]
diff --git a/doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_4_b15499722a655489f9ea60ff9d4c47c6._comment b/doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_4_b15499722a655489f9ea60ff9d4c47c6._comment
new file mode 100644
index 000000000..d78f3d268
--- /dev/null
+++ b/doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_4_b15499722a655489f9ea60ff9d4c47c6._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmLB39PC89rfGaA8SwrsnB6tbumezj-aC0"
+ nickname="Tobias"
+ subject="comment 4"
+ date="2012-09-03T08:12:39Z"
+ content="""
+So, i've let the assistant run since i posted my last message, while i slept.
+
+But 8 hours later, it still hasn't made any progress. :(
+
+Again, only see this with gpg encryption enabled, and on files >700kbyte.
+"""]]
diff --git a/doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_5_8ea48276f060e75d9f40617d2a1ccd08._comment b/doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_5_8ea48276f060e75d9f40617d2a1ccd08._comment
new file mode 100644
index 000000000..0cbf81e41
--- /dev/null
+++ b/doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_5_8ea48276f060e75d9f40617d2a1ccd08._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.236"
+ subject="comment 5"
+ date="2012-09-04T20:06:17Z"
+ content="""
+Can you try running the transfer command by hand? The command line is:
+
+`/home/alansmithee/bin/git-annex transferkey SHA256-s806100--ad2c33a88a665c56d97393fad99b37529afc5947694eab7d9c27f4d178d182f4 --to host1free --file 787kbyte.txt`
+
+Paste me the full output until it seems to hang (if it hangs this way), and if it does hang you may also need to strace it and send me that..
+"""]]
diff --git a/doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_6_9b8bf7e9fa715977fbeb98087deefd1a._comment b/doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_6_9b8bf7e9fa715977fbeb98087deefd1a._comment
new file mode 100644
index 000000000..c5c2aaa8a
--- /dev/null
+++ b/doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_6_9b8bf7e9fa715977fbeb98087deefd1a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmLB39PC89rfGaA8SwrsnB6tbumezj-aC0"
+ nickname="Tobias"
+ subject="comment 6"
+ date="2012-09-04T21:57:05Z"
+ content="""
+No joy.
+
+strace: http://pastebin.com/UYSrZZAg
+"""]]
diff --git a/doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_7_42e09eacdc10c7cf579bfc6470b5117c._comment b/doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_7_42e09eacdc10c7cf579bfc6470b5117c._comment
new file mode 100644
index 000000000..5a8e2f9f8
--- /dev/null
+++ b/doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_7_42e09eacdc10c7cf579bfc6470b5117c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.236"
+ subject="comment 7"
+ date="2012-09-06T16:20:49Z"
+ content="""
+From the strace, I can see it reading the file and feeding it to gpg. Either gpg is stalling after a while, or perhaps it is not reading the output back from gpg. What type of special remote is this (rsync/directory/S3)? Can you provide `strace -f` output for the same command you straced before?
+"""]]
diff --git a/doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_8_6c02f31063b3d399d1b4f823bd6543ce._comment b/doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_8_6c02f31063b3d399d1b4f823bd6543ce._comment
new file mode 100644
index 000000000..391ec4437
--- /dev/null
+++ b/doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_8_6c02f31063b3d399d1b4f823bd6543ce._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmLB39PC89rfGaA8SwrsnB6tbumezj-aC0"
+ nickname="Tobias"
+ subject="comment 8"
+ date="2012-09-06T18:41:47Z"
+ content="""
+I've tried with rsync and directory(real, mountpoint, and fuse mount), no S3. Same result on all of them.
+
+Here is an strace -f http://pastebin.com/YqCbi7Ue
+
+Funny thing is that now i hitting the failure on smaller files(<500kbyte).
+
+I even did a restart because of that. To see if a clean boot would increate it back to the ~700kbyte, but it made no difference.
+
+The annex hasn't been idle since last time, but i haven't done anything major in it. In total the annex is 204mb(up from 185mb at the time of my first post about this)
+"""]]
diff --git a/doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_9_dd0447cb3b39d3a8c1a7cc00f17d8bc2._comment b/doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_9_dd0447cb3b39d3a8c1a7cc00f17d8bc2._comment
new file mode 100644
index 000000000..cd879bcfd
--- /dev/null
+++ b/doc/design/assistant/blog/day_70__adding_ssh_remotes/comment_9_dd0447cb3b39d3a8c1a7cc00f17d8bc2._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.30"
+ subject="comment 9"
+ date="2012-09-09T16:52:33Z"
+ content="""
+Someone else reported what looks like the same problem, here: [[bugs/transferkey_fails_due_to_gpg]]
+
+I'mm be following up to that bug report. In fact, I think I just managed to replicate the bug!
+"""]]
diff --git a/doc/design/assistant/blog/day_71__ssh_probing.mdwn b/doc/design/assistant/blog/day_71__ssh_probing.mdwn
new file mode 100644
index 000000000..ac5a47380
--- /dev/null
+++ b/doc/design/assistant/blog/day_71__ssh_probing.mdwn
@@ -0,0 +1,26 @@
+Got ssh probing implemented. It checks if it can connect to the server, and
+probes the server to see how it should be used.
+
+Turned out to need two ssh probes. The first uses the system's existing ssh
+configuration, but disables password prompts. If that's able to get in
+without prompting for a password, then the user must have set that up,
+and doesn't want to be bothered with password prompts, and it'll respect
+that configuration.
+
+Otherwise, it sets up a per-host ssh key, and configures a hostname alias
+in `~/.ssh/config` to use that key, and probes using that.
+Configuring ssh this way is nice because it avoids changing ssh's
+behavior except when git-annex uses it, and it does not open up the server
+to arbitrary commands being run without password.
+
+--
+
+Next up will be creating the repositories. When there's a per-host key,
+this will also involve setting up `authorized_keys`, locking down the ssh
+key to only allow running git-annex-shell or rsync.
+
+I decided to keep that separate from the ssh probing, even though it means
+the user will be prompted twice for their ssh password. It's cleaner and
+allows the probing to do other checks -- maybe it'll later check the amount
+of free disk space -- and the user should be able to decide after the probe
+whether or not to proceed with making the repository.
diff --git a/doc/design/assistant/blog/day_71__ssh_probing/comment_1_56a0c29f7454cfca5cc30b2849e6e942._comment b/doc/design/assistant/blog/day_71__ssh_probing/comment_1_56a0c29f7454cfca5cc30b2849e6e942._comment
new file mode 100644
index 000000000..606037372
--- /dev/null
+++ b/doc/design/assistant/blog/day_71__ssh_probing/comment_1_56a0c29f7454cfca5cc30b2849e6e942._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmRFKwny4rArBaz-36xTcsJYqKIgdDaw5Q"
+ nickname="Andrew"
+ subject="comment 1"
+ date="2013-01-19T07:23:38Z"
+ content="""
+I'm finding a few circumstances where the per-host key never gets setup. Is there a way to force this probing or key setup to happen?
+"""]]
diff --git a/doc/design/assistant/blog/day_71__ssh_probing/comment_2_f3bd3e366c92c833c7e217da125481b8._comment b/doc/design/assistant/blog/day_71__ssh_probing/comment_2_f3bd3e366c92c833c7e217da125481b8._comment
new file mode 100644
index 000000000..3ce31969d
--- /dev/null
+++ b/doc/design/assistant/blog/day_71__ssh_probing/comment_2_f3bd3e366c92c833c7e217da125481b8._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.3.194"
+ subject="comment 2"
+ date="2013-01-19T16:09:15Z"
+ content="""
+It'd be best to file a bug report with details.
+"""]]
diff --git a/doc/design/assistant/blog/day_72__remote_ssh_server_configurator_finished.mdwn b/doc/design/assistant/blog/day_72__remote_ssh_server_configurator_finished.mdwn
new file mode 100644
index 000000000..4dfc297b2
--- /dev/null
+++ b/doc/design/assistant/blog/day_72__remote_ssh_server_configurator_finished.mdwn
@@ -0,0 +1,34 @@
+Decided to only make bare git repos on remote ssh servers. This
+configurator is aimed at using a server somewhere, which is probably not
+going to be running the assistant. So it doesn't need a non-bare repo, and
+there's nothing to keep the checked out branch in a non-bare repo
+up-to-date on such a server, anyway. For non-bare repos on locally
+accessible boxes, the [[pairing]] configurator will be the thing
+to use, instead of this one.
+
+Note: While the remote ssh configurator works great, and you could even have the
+assistant running on multiple computers and use it to point them all at the
+same repo on a server, the assistant does not yet support keeping such a
+network topology in sync. That needs some of the ideas in [[cloud]] to
+happen, so clients can somehow inform each other when there are changes.
+Until that happens, the assistant polls only every 30 minutes, so it'll
+keep in sync with a 30 minute delay.
+
+---
+
+This configurator can also set up encryped rsync special remotes. Currently
+it always encrypts them, using the shared cipher mode of git-annex's
+encryption. That avoids issues with gpg key generation and distribution,
+and was easy to get working.
+
+---
+
+I feel I'm in a good place now WRT adding repository configurator wizards
+to the webapp. This one took about 2.5 days, and involved laying some
+groundwork that will be useful for other repository configurators. And it
+was probably one of the more complex ones.
+
+Now I should be able to crank out configurators for things like Amazon S3,
+Bup, Rsync.net, etc fairly quickly. First, I need to do a beta release of
+the assistant, and start getting feedback from my backers to prioritize
+what to work on.
diff --git a/doc/design/assistant/blog/day_73__rsync.net_configurator.mdwn b/doc/design/assistant/blog/day_73__rsync.net_configurator.mdwn
new file mode 100644
index 000000000..9000636a7
--- /dev/null
+++ b/doc/design/assistant/blog/day_73__rsync.net_configurator.mdwn
@@ -0,0 +1,17 @@
+Now finished building a special configurator for rsync.net. While
+this is just a rsync remote to git-annex, there are some tricky bits to
+setting up the ssh key using rsync.net's restricted shell. The configurator
+automates that nicely. It took about 3 hours of work, and 49 lines of
+rsync.net specific code to build this.
+
+[[!img /assistant/rsync.net.png]]
+
+Thanks to rsync.net who heard of my Kickstarter and gave me a really
+nice free lifetime account. BTW guys, I wish your restricted shell
+supported '&&' in between commands, and returned a nonzero exit status when
+the command fails. This would make my error handling work better.
+
+I've also reworked the repository management page. Nice to see those
+configurators start to fill in!
+
+[[!img /assistant/repositories.png]]
diff --git a/doc/design/assistant/blog/day_74__bits_and_peices.mdwn b/doc/design/assistant/blog/day_74__bits_and_peices.mdwn
new file mode 100644
index 000000000..c3a71d796
--- /dev/null
+++ b/doc/design/assistant/blog/day_74__bits_and_peices.mdwn
@@ -0,0 +1,7 @@
+* On OSX, install a launcher plist file, to run the assistant on login,
+ and a `git-annex-webapp.command` file in the desktop. This is not tested
+ yet.
+* Made the webapp display alerts when the inotify/kqueue layer has a
+ warning message.
+* Handle any crashes of each of the 15 or so named threads by displaying
+ an alert. (Of course, this should never happen.)
diff --git a/doc/design/assistant/blog/day_75__zeromq_and_pairing.mdwn b/doc/design/assistant/blog/day_75__zeromq_and_pairing.mdwn
new file mode 100644
index 000000000..9f2ba4816
--- /dev/null
+++ b/doc/design/assistant/blog/day_75__zeromq_and_pairing.mdwn
@@ -0,0 +1,50 @@
+Started reading about ZeroMQ with the hope that it could do some firewall
+traversal thing, to connect mutually-unroutable nodes. Well, it could, but
+it'd need a proxy to run on a server both can contact, and lots of
+users won't have a server to run that on. The XMPP approach used by
+dvcs-autosync is looking like the likeliest way for git-annex to handle
+that use case.
+
+However, ZeroMQ did point in promising directions to handle another use
+case I need to support: Local [[pairing]]. In fairly short order, I got
+ZeroMQ working over IP Multicast (PGM), with multiple publishers sending
+messages that were all seen by multiple clients on the LAN (actually the
+WAN; works over OpenVPN too). I had been thinking about using
+Avahi/ZeroConf for discovery of systems to pair with, but ZeroMQ is rather
+more portable and easy to work with.
+
+Unfortunatly, I wasn't able to get ZeroMQ to behave reliably enough.
+It seems to have some timeout issues the way I'm trying to use it,
+or perhaps its haskell bindings are buggy? Anyway, it's really overkill
+to use PGM when all I need for git-annex pairing discovery is lossy
+UDP Multicast. Haskell has a simple `network-multicast` library for that,
+and it works great.
+
+With discovery out of the way (theoretically), the hard part about
+[[pairing]] is going to be verifying that the desired repository is being
+paired with, and not some imposter. My plan to deal with this involves a
+shared secret, that can be communicated out of band, and HMAC. The webapp
+will prompt both parties to enter the same agreed upon secret (which could
+be any phrase, ideally with 64 bytes of entropy), and will then use it as
+the key for HMAC on the ssh public key. The digest will be sent over the
+wire, along with the ssh public key, and the other side can use the shared
+secret to verifiy the key is correct.
+
+The other hard part about [[pairing]] will be finding the best address to
+use for git, etc to connect to the other host. If MDNS is available, it's
+ideal, but if not the pair may have to rely on local DNS, or even
+hard-coded IPs, which will be much less robust. Or, the assistant could
+broadcast queries for a peer's current IP address itself, as a poor man's
+MDNS.
+
+All right then! That looks like a good week's worth of work to embark on.
+
+---
+
+Slight detour to package the haskell network-multicast library and upload
+to Debian unstable.
+
+Roughed out a data type that models the whole pairing conversation,
+and can be serialized to implement it. And a state machine to run
+that conversation. Not yet hooked up to any transport such as multicast
+UDP.
diff --git a/doc/design/assistant/blog/day_76__pairing.mdwn b/doc/design/assistant/blog/day_76__pairing.mdwn
new file mode 100644
index 000000000..0ebf55090
--- /dev/null
+++ b/doc/design/assistant/blog/day_76__pairing.mdwn
@@ -0,0 +1,16 @@
+About half way done with implementing [[pairing]]. The webapp's interface
+to prompt for a secret and start pairing is done; the protocol is
+implemented; broadcasting of pairing requests is working; added Yet Another
+Thread to listen for incoming pairing traffic.
+
+Very happy with how this came together; starting with defining the protocol
+with data types let me rapidly iterate until I had designed a simple, clean,
+robust protocol. The implementation works well too; it's even possible to
+start pairing, and only then bring up the network interface to the machine
+you intended to pair with, and it'll detect the new interface and start
+sending requests to it.
+
+Next, I need to make alerts have a button that performs a stored
+IO action. So that the incoming pair request alert can have a button to
+respond to the pair request. And then I need to write the code to actually
+perform the pairing, including ssh key setup.
diff --git a/doc/design/assistant/blog/day_76__pairing/comment_1_09665f269343422cd18051fad1a8c19e._comment b/doc/design/assistant/blog/day_76__pairing/comment_1_09665f269343422cd18051fad1a8c19e._comment
new file mode 100644
index 000000000..16956ead2
--- /dev/null
+++ b/doc/design/assistant/blog/day_76__pairing/comment_1_09665f269343422cd18051fad1a8c19e._comment
@@ -0,0 +1,24 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmubB1Sj2rwFoVdZYvGV0ACaQUJQyiJXJI"
+ nickname="Paul"
+ subject="Hogging memory"
+ date="2012-09-09T15:51:40Z"
+ content="""
+How do you prefer bugs to be reported?
+
+I'm having a problem where git-annex (from git, 1e41c0d85ecc24e8656bff79b2fba46c3663a054) is taking over 20GB of RAM after adding a single file.
+
+To reproduce:
+
+1. Create a new annex (I used the web app, created an annex at ~/annex)
+2. Add box.com as a remote, using encryption (followed <http://git-annex.branchable.com/tips/using_box.com_as_a_special_remote/>, basically `cd ~/annex; git annex initremote box.com type=directory directory=/media/box.com encryption=$GPGID`)
+3. copied a file into the annex (ok, I admit, the file was a bit large, 350MB, but still)
+4. refreshed the web app, nothing happened
+5. closed the web app
+6. started git annex assistant inside ~/annex
+7. git annex webapp
+8. noted that git annex noticed the file, and started transferring
+9. wait
+10. memory usage for the git-annex process goes beyond 21GB RAM
+11. oomkiller kills git-annex
+"""]]
diff --git a/doc/design/assistant/blog/day_76__pairing/comment_2_8e1b2233579bc26bfd758bbf6b3bdc07._comment b/doc/design/assistant/blog/day_76__pairing/comment_2_8e1b2233579bc26bfd758bbf6b3bdc07._comment
new file mode 100644
index 000000000..a2e64671f
--- /dev/null
+++ b/doc/design/assistant/blog/day_76__pairing/comment_2_8e1b2233579bc26bfd758bbf6b3bdc07._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.30"
+ subject="comment 2"
+ date="2012-09-09T16:25:52Z"
+ content="""
+The [[bugs]] page is the place to put bug reports like this so I won't forget them.
+
+This should certainly not be happening. There are actually two git-annex processes running in the situation you describe; I'd be most curious to know whether the `git annex transfer` process was the one that blew up, or if the `git annex assistant` blew up. Also, it's not clear to me if you enabled the chunksize parameter when setting up the special remote, which could well be a significant detail.
+"""]]
diff --git a/doc/design/assistant/blog/day_76__pairing/comment_3_a8b6a8432da20c468c633da8e7cbc2f3._comment b/doc/design/assistant/blog/day_76__pairing/comment_3_a8b6a8432da20c468c633da8e7cbc2f3._comment
new file mode 100644
index 000000000..28439b34f
--- /dev/null
+++ b/doc/design/assistant/blog/day_76__pairing/comment_3_a8b6a8432da20c468c633da8e7cbc2f3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmubB1Sj2rwFoVdZYvGV0ACaQUJQyiJXJI"
+ nickname="Paul"
+ subject="comment 3"
+ date="2012-09-09T17:34:07Z"
+ content="""
+I'm almost certain that I specified chunksize like in the tip. How do I check?
+"""]]
diff --git a/doc/design/assistant/blog/day_76__pairing/comment_4_36a428a2e1803f4391b821d1892f0cd7._comment b/doc/design/assistant/blog/day_76__pairing/comment_4_36a428a2e1803f4391b821d1892f0cd7._comment
new file mode 100644
index 000000000..e46240265
--- /dev/null
+++ b/doc/design/assistant/blog/day_76__pairing/comment_4_36a428a2e1803f4391b821d1892f0cd7._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.30"
+ subject="comment 4"
+ date="2012-09-09T18:00:48Z"
+ content="""
+You can see the full configuration with: git show git-annex:remote.log
+
+(You probably do not want to paste the cipher= part of that here, although it *is* encrypted with your gpg key, unless you are using the shared encryption mode.)
+"""]]
diff --git a/doc/design/assistant/blog/day_76__pairing/comment_5_11f332fe2050d8c1416e71f9e85ba280._comment b/doc/design/assistant/blog/day_76__pairing/comment_5_11f332fe2050d8c1416e71f9e85ba280._comment
new file mode 100644
index 000000000..5c93d3d3e
--- /dev/null
+++ b/doc/design/assistant/blog/day_76__pairing/comment_5_11f332fe2050d8c1416e71f9e85ba280._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmubB1Sj2rwFoVdZYvGV0ACaQUJQyiJXJI"
+ nickname="Paul"
+ subject="comment 5"
+ date="2012-09-10T14:54:17Z"
+ content="""
+chunksize=2m was defined. I tried again, and the transfers again didn't seem to start. Then I did `killall git-annex`, cleaned the files from the box.com account, and tried again. This time it seems to be working, but the webapp isn't showing progress. Memory usage also stays reasonable, and doesn't seem to grow. Maybe it was just bad handling of unexpected repository state?
+"""]]
diff --git a/doc/design/assistant/blog/day_76__pairing/comment_6_973aeb656b78eca97474ea1a3f5b57b7._comment b/doc/design/assistant/blog/day_76__pairing/comment_6_973aeb656b78eca97474ea1a3f5b57b7._comment
new file mode 100644
index 000000000..120a87845
--- /dev/null
+++ b/doc/design/assistant/blog/day_76__pairing/comment_6_973aeb656b78eca97474ea1a3f5b57b7._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.30"
+ subject="comment 6"
+ date="2012-09-10T17:31:20Z"
+ content="""
+Re transfer progress not being shown, that's expected as upload progress displays are not yet implemented in the webapp.
+
+I can't think of a way git-annex would care what was in your box.com repo. It just makes directories as needed, and will overwrite existing files in the rare case they already exist. And ignore any non-git-annex files.
+
+Are you sure it was git-annex's memory use blowing up, and not the memory use of the davfs2 daemon?
+"""]]
diff --git a/doc/design/assistant/blog/day_76__pairing/comment_7_03d2b3343f34377a4d6171e06b7609f6._comment b/doc/design/assistant/blog/day_76__pairing/comment_7_03d2b3343f34377a4d6171e06b7609f6._comment
new file mode 100644
index 000000000..5aea18576
--- /dev/null
+++ b/doc/design/assistant/blog/day_76__pairing/comment_7_03d2b3343f34377a4d6171e06b7609f6._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmubB1Sj2rwFoVdZYvGV0ACaQUJQyiJXJI"
+ nickname="Paul"
+ subject="comment 7"
+ date="2012-09-10T17:35:48Z"
+ content="""
+Positive. I was grepping for git-annex from ps for the mem usage.
+"""]]
diff --git a/doc/design/assistant/blog/day_77_alert_buttons.mdwn b/doc/design/assistant/blog/day_77_alert_buttons.mdwn
new file mode 100644
index 000000000..2c05b495b
--- /dev/null
+++ b/doc/design/assistant/blog/day_77_alert_buttons.mdwn
@@ -0,0 +1,21 @@
+Alerts can now have buttons, that go to some url when clicked. Yay.
+
+Implementing that was a PITA, because Yesod really only wants its type-safe
+urls to be rendered from within its Handler monad. Which most things that
+create alerts are not. I managed to work around Yesod's insistence on this
+only by using a MVar to store the pure function that Yesod uses internally.
+That function can only be obtained once the webapp is running.
+
+----
+
+Fixed a nasty bug where using gpg would cause hangs. I introduced this back
+when I was reworking all the code in git-annex that runs processes, so it
+would work with threading. In the process a place that had forked a process
+to feed input to gpg was lost. Fixed it by spawning a thread to feed gpg.
+Luckily I have never released a version of git-annex with that bug, but
+the many users who are building from the master branch should update.
+
+----
+
+Made alerts be displayed while pairing is going on, with buttons to cancel
+pairing or respond to a pairing request.
diff --git a/doc/design/assistant/blog/day_78__pairing_continued.mdwn b/doc/design/assistant/blog/day_78__pairing_continued.mdwn
new file mode 100644
index 000000000..74f510715
--- /dev/null
+++ b/doc/design/assistant/blog/day_78__pairing_continued.mdwn
@@ -0,0 +1,8 @@
+Worked on [[pairing]] all day. It's complicated and I was close to being in
+the weeds at times. I think it probably works now, but I have not tested it
+at all. Tomorrow, testing, and cleaning up known problems.
+
+----
+
+Also ordered 1.5 terabytes of USB keys and a thousand git-annex stickers
+today.
diff --git a/doc/design/assistant/blog/day_79__pairing_finished.mdwn b/doc/design/assistant/blog/day_79__pairing_finished.mdwn
new file mode 100644
index 000000000..ca4bbc125
--- /dev/null
+++ b/doc/design/assistant/blog/day_79__pairing_finished.mdwn
@@ -0,0 +1,33 @@
+Tons of pairing work, which culminated today in pairing fully working for
+the very first time. And it works great! Type something like "my
+hovercraft is full of eels" into two git annex webapps on the same LAN
+and the two will find each other, automatically set up ssh keys, and sync
+up, like magic. Magic based on math.
+
+* Revert changes made to `authorized_keys` when the user cancels
+ a pairing response. Which could happen if the machine that sent the
+ pairing request originally is no longer on the network.
+* Some fixes to handle lossy UDP better. Particularly tricky at the end
+ of the conversation -- how do both sides reliably know when a
+ conversation is over when it's over a lossy wire? My solution is just
+ to remember some conversatons we think are over, and keep saying
+ "this conversation is over" if we see messages in that conversation.
+ Works.
+* Added a UUID that must be the same in related pairing messages.
+ This has a nice security feature: It allows detection of brute-force
+ attacks to guess the shared secret, after the first wrong guess!
+ In which case the pairing is canceled and a warning printed.
+* That led to a thorough security overview, which I've added to
+ the [[pairing]] page. Added some guards against unusual attacks,
+ like console poisioning attacks. I feel happy with the security
+ of pairing now, with the caveats that only I have reviewed it (and
+ reviewing your own security designs is never ideal), and that the
+ out-of-band shared secret communication between users is only as good
+ as they make it.
+* Found [a bug](https://github.com/yesodweb/yesod/issues/421)
+ in Yesod's type safe urls. At least, I think it's a bug. Worked around it.
+* Got very stuck trying to close the sockets that are opened to send
+ multicast pairing messages. Nothing works, down to and including calling
+ C `close()`. At the moment I have a socket leak. :(
+ I need to understand the details of multicast sockets better to fix this.
+ Emailed the author of the library I'm using for help.
diff --git a/doc/design/assistant/blog/day_7__bugfixes.mdwn b/doc/design/assistant/blog/day_7__bugfixes.mdwn
new file mode 100644
index 000000000..79f36fe98
--- /dev/null
+++ b/doc/design/assistant/blog/day_7__bugfixes.mdwn
@@ -0,0 +1,45 @@
+Kickstarter is over. Yay!
+
+Today I worked on the bug where `git annex watch` turned regular files
+that were already checked into git into symlinks. So I made it check
+if a file is already in git before trying to add it to the annex.
+
+The tricky part was doing this check quickly. Unless I want to write my
+own git index parser (or use one from Hackage), this check requires running
+`git ls-files`, once per file to be added. That won't fly if a huge
+tree of files is being moved or unpacked into the watched directory.
+
+Instead, I made it only do the check during `git annex watch`'s initial
+scan of the tree. This should be OK, because once it's running, you
+won't be adding new files to git anyway, since it'll automatically annex
+new files. This is good enough for now, but there are at least two problems
+with it:
+
+* Someone might `git merge` in a branch that has some regular files,
+ and it would add the merged in files to the annex.
+* Once `git annex watch` is running, if you modify a file that was
+ checked into git as a regular file, the new version will be added
+ to the annex.
+
+I'll probably come back to this issue, and may well find myself directly
+querying git's index.
+
+---
+
+I've started work to fix the memory leak I see when running `git annex
+watch` in a large repository (40 thousand files). As always with a Haskell
+memory leak, I crack open [Real World Haskell's chapter on profiling](http://book.realworldhaskell.org/read/profiling-and-optimization.html).
+
+Eventually this yields a nice graph of the problem:
+
+[[!img profile.png alt="memory profile"]]
+
+So, looks like a few minor memory leaks, and one huge leak. Stared
+at this for a while and trying a few things, and got a much better result:
+
+[[!img profile2.png alt="memory profile"]]
+
+I may come back later and try to improve this further, but it's not bad memory
+usage. But, it's still rather slow to start up in such a large repository,
+and its initial scan is still doing too much work. I need to optimize
+more..
diff --git a/doc/design/assistant/blog/day_7__bugfixes/profile.png b/doc/design/assistant/blog/day_7__bugfixes/profile.png
new file mode 100644
index 000000000..702af1ca0
--- /dev/null
+++ b/doc/design/assistant/blog/day_7__bugfixes/profile.png
Binary files differ
diff --git a/doc/design/assistant/blog/day_7__bugfixes/profile2.png b/doc/design/assistant/blog/day_7__bugfixes/profile2.png
new file mode 100644
index 000000000..4d487d02a
--- /dev/null
+++ b/doc/design/assistant/blog/day_7__bugfixes/profile2.png
Binary files differ
diff --git a/doc/design/assistant/blog/day_80__default_backend.mdwn b/doc/design/assistant/blog/day_80__default_backend.mdwn
new file mode 100644
index 000000000..5b6aa7f98
--- /dev/null
+++ b/doc/design/assistant/blog/day_80__default_backend.mdwn
@@ -0,0 +1,14 @@
+I've changed the default backend used by git-annex from SHA256 to SHA256E.
+Including the filename extension in the key is known to make repositories
+more usable on things like MP3 players, and I've recently learned it also
+avoids [[forum/Weird_behavior_with_OS_X_Finder_and_Preview.app]].
+
+I thought about only changing the default in repositories set up by the
+assistant, but it seemed simpler to change the main default. The old
+backend is really only better if you might have multiple copies of files
+with the same content that have different extensions.
+
+Fixed the socket leak in pairing that eluded me earlier.
+
+I've made a new [[polls]] page, and posted a poll:
+[[polls/prioritizing_special_remotes]]
diff --git a/doc/design/assistant/blog/day_81__enabling_pre-existing_special_remotes.mdwn b/doc/design/assistant/blog/day_81__enabling_pre-existing_special_remotes.mdwn
new file mode 100644
index 000000000..45a7e9f20
--- /dev/null
+++ b/doc/design/assistant/blog/day_81__enabling_pre-existing_special_remotes.mdwn
@@ -0,0 +1,34 @@
+It's possible for one git annex repository to configure a special remote
+that it makes sense for other repositories to also be able to use. Today I
+added the UI to support that; in the list of repositories, such
+repositories have a "enable" link.
+
+To enable pre-existing rsync special remotes, the webapp has to do the same
+probing and ssh key setup that it does when initially creating them.
+Rsync.net is also handled as a special case in that code. There was one
+ugly part to this.. When a rsync remote is configured in the webapp,
+it uses a mangled hostname like "git-annex-example.com-user", to
+make ssh use the key it sets up. That gets stored in the `remote.log`, and so
+the enabling code has to unmangle it to get back to the real hostname.
+
+---
+
+Based on the still-running [[prioritizing_special_remotes]] poll, a lot
+of people want special remote support for their phone or mp3 player.
+(As opposed to running git-annex on an Android phone, which comes later..)
+It'd be easy enough to make the webapp set up a directory special remote
+on such a device, but that makes consuming some types of content on the
+phone difficult (mp3 players seem to handle them ok based on what people tell
+me). I need to think more about some of the ideas mentioned in [[android]]
+for more suitable ways of storing files.
+
+One thing's for sure: You won't want the assistant to sync all your files
+to your phone! So I also need to start coming up with partial syncing
+controls. One idea is for each remote to have a configurable matcher for files
+it likes to receive. That could be only mp3 files, or all files inside a
+given subdirectory, or all files *not* in a given subdirectory. That means
+that when the assistant detects a file has been moved, it'll need to add
+(or remove) a queued transfer. Lots of other things could be matched on,
+like file size, number of copies, etc. Oh look, I have a
+[beautiful library I wrote earlier](http://joeyh.name/blog/entry/happy_haskell_hacker)
+that I can reuse!
diff --git a/doc/design/assistant/blog/day_82__git-annex_branch_work.mdwn b/doc/design/assistant/blog/day_82__git-annex_branch_work.mdwn
new file mode 100644
index 000000000..ed2e4e602
--- /dev/null
+++ b/doc/design/assistant/blog/day_82__git-annex_branch_work.mdwn
@@ -0,0 +1,26 @@
+Started today doing testing of [[syncing]], and found some bugs and things
+it needs to do better. But was quickly sidetracked when I noticed that
+`transferkey` was making a commit to the git-annex branch for every file it
+transferred, which is too slow and bloats history too much.
+
+To fix that actually involved fixing a long-standing annoyance; that
+read-only git-annex commands like `whereis` sometimes start off with
+"(Recording state in git)", when the journal contains some not yet
+committed changes to the git-annex branch. I had to carefully think
+through the cases to avoid those commits.
+
+As I was working on that, I found a real nasty lurking bug in the git-annex
+branch handling. It's unlikely to happen unless `annex.autocommit=false` is
+set, but it could occur when two git-annex processes race one another just
+right too. The root of the bug is that `git cat-file --batch` does not
+always show changes made to the index after it started. I think it does
+in enough cases to have tricked me before, but in general it can't be
+trusted to report the current state of the index, but only some past state.
+
+I was able to fix the bug, by ensuring that changes being made to the
+branch are always visible in either the journal or the branch -- never in
+the index alone.
+
+----
+
+Hopefully something less low-level tomorrow..!
diff --git a/doc/design/assistant/blog/day_83__3-way.mdwn b/doc/design/assistant/blog/day_83__3-way.mdwn
new file mode 100644
index 000000000..9411c4c1c
--- /dev/null
+++ b/doc/design/assistant/blog/day_83__3-way.mdwn
@@ -0,0 +1,73 @@
+Syncing works well when the graph of repositories is strongly connected.
+Now I'm working on making it work reliably with less connected graphs.
+
+I've been focusing on and testing a doubly-connected list of repositories,
+such as: `A <-> B <-> C`
+
+----
+
+I was seeing a lot of git-annex branch push failures occuring in
+this line of repositories topology. Sometimes was is able to recover from
+these, but when two repositories were trying to push to one-another at the
+same time, and both failed, both would pull and merge, which actually keeps
+the git-annex branch still diverged. (The two merge commits differ.)
+
+A large part of the problem was that it pushed directly into the git-annex
+branch on the remote; the same branch the remote modifies. I changed it to
+push to `synced/git-annex` on the remote, which avoids most push failures.
+Only when A and C are both trying to push into `B/synced/git-annex` at the
+same time would one fail, and need to pull, merge, and retry.
+
+-----
+
+With that change, git syncing always succeeded in my tests, and without
+needing any retries. But with more complex sets of repositories, or more
+traffic, it could still fail.
+
+I want to avoid repeated retries, exponential backoffs, and that kind of
+thing. It'd probably be good enough, but I'm not happy with it because
+it could take arbitrarily long to get git in sync.
+
+I've settled on letting it retry once to push to the synced/git-annex
+and synced/master branches. If the retry fails, it enters a fallback mode,
+which is guaranteed to succeed, as long as the remote is accessible.
+
+The problem with the fallback mode is it uses really ugly branch names.
+Which is why Joachim Breitner and I originally decided on making `git annex
+sync` use the single `synced/master` branch, despite the potential for
+failed syncs. But in the assistant, the requirements are different,
+and I'm ok with the uglier names.
+
+It does seem to make sense to only use the uglier names as a fallback,
+rather than by default. This preserves compatability with `git annex sync`,
+and it allows the assistant to delete fallback sync branches after it's
+merged them, so the ugliness is temporary.
+
+---
+
+Also worked some today on a bug that prevents C from receiving files
+added to A.
+
+The problem is that file contents and git metadata sync independantly. So C
+will probably receive the git metadata from B before B has finished
+downloading the file from A. C would normally queue a download of the
+content when it sees the file appear, but at this point it has nowhere to
+get it from.
+
+My first stab at this was a failure. I made each download of a file result
+in uploads of the file being queued to every remote that doesn't have it
+yet. So rather than C downloading from B, B uploads to C. Which works fine,
+but then C sees this download from B has finished, and proceeds to try to
+re-upload to B. Which rejects it, but notices that this download has
+finished, so re-uploads it to C...
+
+The problem with that approach is that I don't have an event when a download
+succeeds, just an event when a download ends. Of course, C could skip
+uploading back to the same place it just downloaded from, but loops are
+still possible with other network topologies (ie, if D is connected to both
+B and C, there would be an upload loop 'B -> C -> D -> B`). So unless I can
+find a better event to hook into, this idea is doomed.
+
+I do have another idea to fix the same problem. C could certainly remember
+that it saw a file and didn't know where to get the content from, and then
+when it receives a git push of a git-annex branch, try again.
diff --git a/doc/design/assistant/blog/day_84__deferred_downloads.mdwn b/doc/design/assistant/blog/day_84__deferred_downloads.mdwn
new file mode 100644
index 000000000..0ae684e47
--- /dev/null
+++ b/doc/design/assistant/blog/day_84__deferred_downloads.mdwn
@@ -0,0 +1,33 @@
+Implemented deferred downloads. So my example from yesterday of three
+repositories in a line keep fully in sync now!
+
+I punted on one problem while doing it. It might be possible to get a really
+big list of deferred downloads in some situation. That all lives in memory.
+I aim for git-annex to always have a constant upper bound on memory use,
+so that's not really acceptable. I have TODOed a reminder to do something
+about limiting the size of this list.
+
+----
+
+I also ran into a nasty crash while implementing this, where two threads
+were trying to do things to git HEAD at the same time, and so one crashed,
+and in a way I don't entirely understand, that crash took down another
+thread with a BlockedIndefinitelyOnSTM exception. I think I've fixed
+this, but it's bothersome that this is the second time that modifications
+to the Merger thread have led to a concurrency related crash that I
+have not fully understood.
+
+My guess is that STM can get confused when it's
+retrying, and the thread that was preventing it from completing a
+transaction crashes, because it suddenly does not see any other
+references to the TVar(s) involved in the transaction. Any GHC STM gurus
+out there?
+
+---
+
+Still work to be done on making data transfers to keep fully in sync in all
+circumstances. One case I've realized needs work occurs when a USB drive is
+plugged in. Files are downloaded from it to keep the repo in sync, but the
+repo neglects to queue uploads of those files it just got out to other
+repositories it's in contact with. Seems I still need to do something to
+detecting when a successful download is done, and queue uploads.
diff --git a/doc/design/assistant/blog/day_85__more_foundation_work.mdwn b/doc/design/assistant/blog/day_85__more_foundation_work.mdwn
new file mode 100644
index 000000000..25bad3748
--- /dev/null
+++ b/doc/design/assistant/blog/day_85__more_foundation_work.mdwn
@@ -0,0 +1,17 @@
+Turns out I was able to easily avoid the potential upload loops that would
+occur if each time a repo receives a download, it queues uploads to the
+repos it's connected to. With that done. I suspect, but have not proven,
+that the assistant is able to keep repos arranged in any shape of graph in
+sync, as long as it's connected (of course) and each connection is
+bi-directional. That's a good start .. or at least a nice improvement from
+only strongly connected graphs being kept in sync.
+
+Eliminated some empty commits that would be made sometimes, which is a nice
+optimisation.
+
+------
+
+I wanted to get back to some UI work after this week's deep dive into the
+internals. So I filled in a missing piece, the repository switcher in the
+upper right corner. Now the webapp's UI allows setting up different
+repositories for different purposes, and switching between them.
diff --git a/doc/design/assistant/blog/day_86__towards_the_beta.mdwn b/doc/design/assistant/blog/day_86__towards_the_beta.mdwn
new file mode 100644
index 000000000..b11dd9bf9
--- /dev/null
+++ b/doc/design/assistant/blog/day_86__towards_the_beta.mdwn
@@ -0,0 +1,33 @@
+Putting together a shortlist of things I want to sort out before the beta.
+
+* [[Progress bars|progressbars]] for file uploads.
+* No mocked up parts in the webapp's UI. Think I implemented the last of
+ those yesterday, although there are some unlinked repository configuration
+ options.
+* The basic watching functionality, should work reliably.
+ There are some known scalability issues with eg,
+ [[kqueue on OSX|bugs/Issue_on_OSX_with_some_system_limits]] that
+ need to be dealt with, but needn't block a beta.
+* Should keep any configuration of repositories that can be set up using
+ the webapp in sync whenever it's possible to do so. I think that'll work
+ after the past few days work.
+* Should be easy to install and get running. Of course part of the point
+ of the beta release is to get it out there, on Hackage, in Debian
+ unstable, and in the other places that git-annex packagers put it.
+ As to getting it running, the autostart files and menu items look good
+ on Linux. The OSX equivilants still need work and testing.
+* No howlingly bad bugs. [[This bug|bugs/pasting_into_annex_on_OSX]] is
+ the one I'm most concerned with currently. OTOH,
+ [[bugs/watcher_commits_unlocked_files]] can be listed in the errata.
+
+----
+
+So I worked on progress bars for uploads today. Wrote a nice little
+parser for rsync's progress output, that parses arbitrary size chunks,
+returning any unparsable part. Added a ProgressCallback parameter to
+all the backends' upload methods. Wrote a nasty thing that intercepts
+rsync's output, currently a character at a time (horrible, but rsync
+doesn't output that much, so surprisingly acceptable), and outputs it and
+parses it. Hooked all this up, and got it working for uploads to
+git remotes. That's 1/10th of the total ways uploads can happen that
+have working progress bars. It'll take a while to fill in the rest..
diff --git a/doc/design/assistant/blog/day_87__more_progress_progress.mdwn b/doc/design/assistant/blog/day_87__more_progress_progress.mdwn
new file mode 100644
index 000000000..c2b266d6d
--- /dev/null
+++ b/doc/design/assistant/blog/day_87__more_progress_progress.mdwn
@@ -0,0 +1,28 @@
+Worked more on upload progress tracking. I'm fairly happy with its state
+now:
+
+* It's fully implemented for rsync special remotes.
+
+* Git remotes also fully support it, with the
+ notable exception of file uploads run by `git-annex-shell recvkey`. That
+ runs `rsync --server --sender`, and in that mode, rsync refuses to output
+ progress info. Not sure what to do about this case. Maybe I should
+ write a parser for the rsync wire protocol that can tell what chunk of the
+ file is being sent, and shim it in front of the rsync server? That's
+ rather hardcore, but it seems the best of a bad grab bag of options that
+ include things like `LD_PRELOAD` hacks.
+
+* Also optimised the rsync progress bar reader to read whole
+ chunks of data rather than one byte at a time.
+
+* Also got progress bars to actually update in the webapp for uploads.
+
+ This turned out to be tricky because kqueue cannot be used to detect when
+ existing files have been modified. (One of kqueue's worst shortcomings vs
+ inotify.) Currently on kqueue systems it has to poll.
+
+I will probably upload add progress tracking to the directory special remote,
+which should be very easy (it already implements its own progress bars),
+and leave the other special remotes for later. I can add upload progress
+tracking to each special remote when I add support for configuring it in
+the webapp.
diff --git a/doc/design/assistant/blog/day_88__progressbars_still_progressing.mdwn b/doc/design/assistant/blog/day_88__progressbars_still_progressing.mdwn
new file mode 100644
index 000000000..cd3c493c1
--- /dev/null
+++ b/doc/design/assistant/blog/day_88__progressbars_still_progressing.mdwn
@@ -0,0 +1,18 @@
+Short day today, but I again worked only on progress bars.
+
+* Added upload progress tracking for the directory special remote.
+* Some optimisations.
+* Added a `git annex-shell transferkey` command. This isn't used yet,
+ but the plan is to use it to feed back information about how much
+ of a file has been sent when downloading it. So that the uploader
+ can display a progress bar. This method avoids needing to parse the rsync
+ protocol, which is approximately impossible without copying half of rsync.
+ Happily, git-annex's automatic ssh connection caching will make the small
+ amount of data this needs to send be efficiently pipelined over the same
+ ssh connection that rsync is using.
+
+I probably have less than 10 lines of code to write to finish up
+[[progressbars]] for now. Looking forward to getting that behind me, and on
+to something more interesting. Even doing mail merge to print labels to
+mail out Kickstarter rewards is more interesting than progress bars at this
+point. :)
diff --git a/doc/design/assistant/blog/day_89__final_polish.mdwn b/doc/design/assistant/blog/day_89__final_polish.mdwn
new file mode 100644
index 000000000..4a72a7ff2
--- /dev/null
+++ b/doc/design/assistant/blog/day_89__final_polish.mdwn
@@ -0,0 +1,24 @@
+Finally wrapped up progress bars; upload progress is now reported in all
+situations.
+
+After all that, I was pleased to find a use for the progress info, beyond
+displaying it to the user. Now the assistant uses it to decide whether it
+makes sense to immediately retry a failed transfer. This should make it
+work nicely, or at least better, with flaky network or drives.
+
+The webapp crashed on startup when there was no `~/.gitconfig`.
+Guess all of us who have tried it so far are actual git users,
+but I'm glad I caught this before releasing the beta.
+
+Jimmy Tang kindly took on making a OS X .app directory for git-annex.
+So it now has an icon that will launch the webapp.
+[[!img /assistant/osx-app.png]]
+
+I'm getting lots of contributors to git-annex all of a sudden. I've had 3
+patches this weekend, and 2 of them have been to Haskell code.
+Justin Azoff is working on [[todo/incremental_fsck]], and Robie Basak
+has [gotten Amazon Glacier working](https://github.com/basak/glacier-cli)
+using the hook special remote.
+
+Started doing some design for [[transfer_control]]. I will start
+work on this after releasing the first beta.
diff --git a/doc/design/assistant/blog/day_8__speed.mdwn b/doc/design/assistant/blog/day_8__speed.mdwn
new file mode 100644
index 000000000..d99add97a
--- /dev/null
+++ b/doc/design/assistant/blog/day_8__speed.mdwn
@@ -0,0 +1,67 @@
+Since last post, I've worked on speeding up `git annex watch`'s startup time
+in a large repository.
+
+The problem was that its initial scan was naively staging every symlink in
+the repository, even though most of them are, presumably, staged correctly
+already. This was done in case the user copied or moved some symlinks
+around while `git annex watch` was not running -- we want to notice and
+commit such changes at startup.
+
+Since I already had the `stat` info for the symlink, it can look at the
+`ctime` to see if the symlink was made recently, and only stage it if so.
+This sped up startup in my big repo from longer than I cared to wait (10+
+minutes, or half an hour while profiling) to a minute or so. Of course,
+inotify events are already serviced during startup, so making it scan
+quickly is really only important so people don't think it's a resource hog.
+First impressions are important. :)
+
+But what does "made recently" mean exactly? Well, my answer is possibly
+over engineered, but most of it is really groundwork for things I'll need
+later anyway. I added a new data structure for tracking the status of the
+daemon, which is periodically written to disk by another thread (thread #6!)
+to `.git/annex/daemon.status` Currently it looks like this; I anticipate
+adding lots more info as I move into the [[syncing]] stage:
+
+ lastRunning:1339610482.47928s
+ scanComplete:True
+
+So, only symlinks made after the daemon was last running need to be
+expensively staged on startup. Although, as RichiH pointed out,
+this fails if the clock is changed. But I have been planning to have a
+cleanup thread anyway, that will handle this, and other
+potential problems, so I think that's ok.
+
+Stracing its startup scan, it's fairly tight now. There are some repeated
+`getcwd` syscalls that could be optimised out for a minor speedup.
+
+----
+
+Added the sanity check thread. Thread #7! It currently only does one sanity
+check per day, but the sanity check is a fairly lightweight job,
+so I may make it run more frequently. OTOH, it may never ever find a
+problem, so once per day seems a good compromise.
+
+Currently it's only checking that all files in the tree are properly staged
+in git. I might make it `git annex fsck` later, but fscking the whole tree
+once per day is a bit much. Perhaps it should only fsck a few files per
+day? TBD
+
+Currently any problems found in the sanity check are just fixed and logged.
+It would be good to do something about getting problems that might indicate
+bugs fed back to me, in a privacy-respecting way. TBD
+
+----
+
+I also refactored the code, which was getting far too large to all be in
+one module.
+
+I have been thinking about renaming `git annex watch` to `git annex assistant`,
+but I think I'll leave the command name as-is. Some users might
+want a simple watcher and stager, without the assistant's other features
+like syncing and the webapp. So the next stage of the
+[[roadmap|design/assistant]] will be a different command that also runs
+`watch`.
+
+At this point, I feel I'm done with the first phase of [[inotify]].
+It has a couple known bugs, but it's ready for brave beta testers to try.
+I trust it enough to be running it on my live data.
diff --git a/doc/design/assistant/blog/day_8__speed/comment_1_a3dba537b276d5737abc8cb93f1965f4._comment b/doc/design/assistant/blog/day_8__speed/comment_1_a3dba537b276d5737abc8cb93f1965f4._comment
new file mode 100644
index 000000000..d0a207c82
--- /dev/null
+++ b/doc/design/assistant/blog/day_8__speed/comment_1_a3dba537b276d5737abc8cb93f1965f4._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="Battery usage"
+ date="2012-06-15T09:57:33Z"
+ content="""
+Complete fsck is good, but once a week probably enough.
+
+But please see if you can make fsck optional depending on if the machine is running on battery.
+"""]]
diff --git a/doc/design/assistant/blog/day_90__beta.mdwn b/doc/design/assistant/blog/day_90__beta.mdwn
new file mode 100644
index 000000000..fc9bf4a41
--- /dev/null
+++ b/doc/design/assistant/blog/day_90__beta.mdwn
@@ -0,0 +1,16 @@
+Just released git-annex 3.20120924, which includes beta versions of
+the assistant and webapp. Read the [[/assistant/errata]], then give it a
+try!
+
+I've uploaded it to Haskell's cabal, and to Debian unstable, and hope my
+helpers for other distributions will update them soon. (Although the
+additional dependencies to build the webapp may take a while on some.)
+I also hope something can be done to make a prebuilt version available on
+OSX soonish.
+
+I've decided to license the webapp under the
+[AGPL](http://www.gnu.org/licenses/agpl-3.0.html). This should not impact
+normal users of it, and git-annex can be built without the webapp as a pure
+GPL licensed program. This is just insurance to prevent someone turning the
+webapp into a propritary web-only service, by requiring that anyone who
+does so provide the source of the webapp.
diff --git a/doc/design/assistant/blog/day_90__beta/comment_1_5f2a3b18ad7558abe04f51534a29ff13._comment b/doc/design/assistant/blog/day_90__beta/comment_1_5f2a3b18ad7558abe04f51534a29ff13._comment
new file mode 100644
index 000000000..6b95e317d
--- /dev/null
+++ b/doc/design/assistant/blog/day_90__beta/comment_1_5f2a3b18ad7558abe04f51534a29ff13._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlJEI45rGczFAnuM7gRSj4C6s9AS9yPZDc"
+ nickname="Kevin"
+ subject="Haskell on MacPorts"
+ date="2012-09-24T21:09:39Z"
+ content="""
+FYI, I just came across a [MacPorts ticket](https://trac.macports.org/ticket/35813) to update Haskell to 2012.2.0.0. It would be nice to install git-annex from MacPorts.
+
+"""]]
diff --git a/doc/design/assistant/blog/day_90__beta/comment_2_961c4eba97f4eac75174244d6b2b00c0._comment b/doc/design/assistant/blog/day_90__beta/comment_2_961c4eba97f4eac75174244d6b2b00c0._comment
new file mode 100644
index 000000000..ed6c8e2ae
--- /dev/null
+++ b/doc/design/assistant/blog/day_90__beta/comment_2_961c4eba97f4eac75174244d6b2b00c0._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 2"
+ date="2012-09-24T21:21:57Z"
+ content="""
+cool, I haven't been on top of things recently. If haskell-platform gets updated in macports and assuming its easy to package up any dependancies (if any) as macport packages, git-annex should be relatively straightforward to package up
+"""]]
diff --git a/doc/design/assistant/blog/day_90__beta/comment_3_c76675a4633cbbe347ed42c222918d38._comment b/doc/design/assistant/blog/day_90__beta/comment_3_c76675a4633cbbe347ed42c222918d38._comment
new file mode 100644
index 000000000..151a9c257
--- /dev/null
+++ b/doc/design/assistant/blog/day_90__beta/comment_3_c76675a4633cbbe347ed42c222918d38._comment
@@ -0,0 +1,24 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkurjhi0CRJvgm7QNaZDWS9hitBtavqIpc"
+ nickname="Bret"
+ subject="A few OS X bugs"
+ date="2012-09-25T00:50:56Z"
+ content="""
+Cabal update
+
+Cabal install git-annex
+Seemed to install correctly on OS X 10.7
+
+After the installation, an application for git-annex showed up on my desktop. This is the wrong place to put applications in OS X. It should belong in the /Applications Folder.
+Launching the git-annex app, the web-browser is opened, and it tells me to make a repository. I entered /Users/[my home folder]/Annex and continued. I then got an internal server error and nothing else happened. The Error:
+
+uuid [\"-m\"] exited 127
+
+Annex was created, and there is a .git folder in it.
+
+Checking the annex status:
+Bret-Air:Annex bret$ git annex status
+git-annex: First run: git-annex init
+
+I'll try it on 10.6 here in just a moment. Let me know if I can provide any more useful information.
+"""]]
diff --git a/doc/design/assistant/blog/day_90__beta/comment_4_f0b8f77cb691e747fe35bcf2f51b5baa._comment b/doc/design/assistant/blog/day_90__beta/comment_4_f0b8f77cb691e747fe35bcf2f51b5baa._comment
new file mode 100644
index 000000000..f6889fe04
--- /dev/null
+++ b/doc/design/assistant/blog/day_90__beta/comment_4_f0b8f77cb691e747fe35bcf2f51b5baa._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkurjhi0CRJvgm7QNaZDWS9hitBtavqIpc"
+ nickname="Bret"
+ subject="comment 4"
+ date="2012-09-25T00:59:51Z"
+ content="""
+OS X 10.6 is doing the same thing as on 10.7.
+"""]]
diff --git a/doc/design/assistant/blog/day_90__beta/comment_5_99fbc9feac62e66a12b0d357cf86ccc1._comment b/doc/design/assistant/blog/day_90__beta/comment_5_99fbc9feac62e66a12b0d357cf86ccc1._comment
new file mode 100644
index 000000000..d886d56bb
--- /dev/null
+++ b/doc/design/assistant/blog/day_90__beta/comment_5_99fbc9feac62e66a12b0d357cf86ccc1._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.14.141"
+ subject="comment 5"
+ date="2012-09-25T14:49:31Z"
+ content="""
+@Bret my best guess (without any error message from the uuid command) is that your uuid doesn't support the -m parameter. I've made the configure step check for this and it'll fall back to uuid without the parameter.
+"""]]
diff --git a/doc/design/assistant/blog/day_91__break.mdwn b/doc/design/assistant/blog/day_91__break.mdwn
new file mode 100644
index 000000000..f2102746d
--- /dev/null
+++ b/doc/design/assistant/blog/day_91__break.mdwn
@@ -0,0 +1,7 @@
+Mostly took a break from working on the assistant today. Instead worked
+on adding incremental fsck to git-annex. Well, that will be something
+that assistant will use, eventually, probably.
+
+Jimmy and I have been working on a self-contained OSX app for using the
+assistant, that doesn't depend on installing git, etc. More on that
+once we have something that works.
diff --git a/doc/design/assistant/blog/day_92__S3.mdwn b/doc/design/assistant/blog/day_92__S3.mdwn
new file mode 100644
index 000000000..c3f275a86
--- /dev/null
+++ b/doc/design/assistant/blog/day_92__S3.mdwn
@@ -0,0 +1,23 @@
+Amazon S3 was the second most popular choice in the
+[[polls/prioritizing_special_remotes]] poll, and since I'm not sure how
+I want to support phone/mp3 players, I did it first.
+
+So I added a configurator today to easily set up an Amazon S3 repository.
+That was straightforward and didn't take long since git-annex already
+supported S3.
+
+The hard part, of course, is key distribution. Since the webapp so far
+can only configure the shared encryption method, and not fullblown gpg keys,
+I didn't feel it would be secure to store the S3 keys in the git repository.
+Anyone with access to that git repo would have full access to S3 ... just not
+acceptable. Instead, the webapp stores the keys in a 600 mode file locally,
+and they're not distributed at all.
+
+When the same S3 repository is enabled on another computer, it prompts for
+keys then too. I did add a hint about using the IAM Management Console in
+this case -- it should be possible to set up users in IAM who can only
+access a single bucket, although I have not tried to set that up.
+
+---
+
+Also, more work on the standalone OSX app.
diff --git a/doc/design/assistant/blog/day_92__S3/comment_1_eda656247d11cea7fbed2e33137a39e5._comment b/doc/design/assistant/blog/day_92__S3/comment_1_eda656247d11cea7fbed2e33137a39e5._comment
new file mode 100644
index 000000000..af610bdb7
--- /dev/null
+++ b/doc/design/assistant/blog/day_92__S3/comment_1_eda656247d11cea7fbed2e33137a39e5._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 1"
+ date="2012-09-26T23:52:50Z"
+ content="""
+I think a lot of people misinterpreted \"phone/mp3 player\" as \"Android\"; I know I did.
+
+As you already support directories, MTP would be needed to support the other half of pretty much all phones and media players (other than those made by Apple). MTP is a valley of pain, though.
+"""]]
diff --git a/doc/design/assistant/blog/day_92__S3/comment_2_8249d2d9521e44c674da3fda74be077a._comment b/doc/design/assistant/blog/day_92__S3/comment_2_8249d2d9521e44c674da3fda74be077a._comment
new file mode 100644
index 000000000..fb83b23e4
--- /dev/null
+++ b/doc/design/assistant/blog/day_92__S3/comment_2_8249d2d9521e44c674da3fda74be077a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlFd2EbAmGD0FjHmuoerXfT0GO_jPcgvQA"
+ nickname="Gert"
+ subject="Single bucket for S3"
+ date="2012-09-27T09:17:24Z"
+ content="""
+You can easily do that with IAM, checkout <http://andrewhitchcock.org/?post=325>.
+
+It boils down to creating a policy for each user/bucket. But allow read access to the full bucket list (otherwise the AWS Console won't work).
+"""]]
diff --git a/doc/design/assistant/blog/day_93__OSX_standalone_app.mdwn b/doc/design/assistant/blog/day_93__OSX_standalone_app.mdwn
new file mode 100644
index 000000000..711710fc7
--- /dev/null
+++ b/doc/design/assistant/blog/day_93__OSX_standalone_app.mdwn
@@ -0,0 +1,23 @@
+Various bug fixes, and work on the OSX app today:
+
+* Avoid crashing when ssh-keygen fails due to not being able to parse
+ `authorized_keys`.. seems a lot of people have crufty unparsable
+ `authorized_keys` files.
+* On OSX, for some reason the webapp was failing to start sometimes due
+ to bind failing with EINVAL. I don't understand why, as that should
+ only happen if the socket is already bound, which it should not as
+ it's just been created. I was able to work around this by retrying
+ with a new socket when bind fails.
+* When setting up `authorized_keys` to let `git-annex-shell` be run,
+ it had been inserting a perl oneliner into it. I changed that
+ to instead call a `~/.ssh/git-annex-shell` wrapper script that it sets
+ up. The benefits are it no longer needs perl, and it's less ugly,
+ and the standalone OSX app can modify the wrapper script to point to
+ wherever it's installed today (people like to move these things around I
+ guess).
+* Made the standalone OSX app set up autostarting when it's first run.
+* Spent rather a long time collecting the licenses of all the software that
+ will be bundled with the standalone OSX app. Ended up with a file
+ containing 3954 lines of legalese. Happily, all the software appears
+ redistributable, and free software; even the couple of OSX system libraries
+ we're bundling are licensed under the APSL.
diff --git a/doc/design/assistant/blog/day_93__easy_install.mdwn b/doc/design/assistant/blog/day_93__easy_install.mdwn
new file mode 100644
index 000000000..013b872e1
--- /dev/null
+++ b/doc/design/assistant/blog/day_93__easy_install.mdwn
@@ -0,0 +1,34 @@
+I hear that people want the git-annex assistant to be easy to install
+without messing about building it from source..
+
+## on OSX
+
+So Jimmy and I have been working all week on making an easily installed OSX
+app of the assistant. This is a .dmz file that bundles all the dependencies
+(git, etc) in, so it can be installed with one click.
+
+It seems to basically work. You can get it [[here|install/OSX]].
+
+Unfortunatly, the [[bugs/pasting_into_annex_on_OSX]] bug resurfaced while
+testing this.. So I can't really recommend using it on real data yet.
+
+Still, any testing you can do is gonna be really helpful. I'm squashing OSX
+bugs right and left.
+
+## on Linux
+
+First of all, the git-annex assistant is now available in Debian unstable,
+and in Arch Linux's AUR. Proper packages.
+
+For all the other Linux distributions, I have a workaround. It's
+a big hack, but it seems to work.. at least on Debian stable.
+
+I've just put up a [[install/linux_standalone]] tarball, which has **no
+library dependencies** apart from glibc, and doesn't even need git to be
+installed on your system.
+
+## on FreeBSD
+
+The FreeBSD port has been updated to include the git-annex assistant too..
+
+[[!meta title="day 94 easy install"]]
diff --git a/doc/design/assistant/blog/day_93__easy_install/comment_1_d4f7de723c98577ef28d89ee6b87fd13._comment b/doc/design/assistant/blog/day_93__easy_install/comment_1_d4f7de723c98577ef28d89ee6b87fd13._comment
new file mode 100644
index 000000000..57a0c78d7
--- /dev/null
+++ b/doc/design/assistant/blog/day_93__easy_install/comment_1_d4f7de723c98577ef28d89ee6b87fd13._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://rjc.pip.verisignlabs.com/"
+ ip="86.22.66.200"
+ subject="assistant in Debian"
+ date="2012-09-30T09:10:17Z"
+ content="""
+The same version of ghc in Debian repository on i386 and amd64 privides ghc-ghci virtual package while on all the other architectures it doesn't. Is that normal or shall I file a bug?
+
+What it basically means is that the packages, both git-annex (with assistant) and its build dependencies, for all the other archs cannot be build on Debian porting machines until that is fixed. It already is in the experimental version but until that one gets to unstable there won't be any official debs for all non-Intel architecures.
+"""]]
diff --git a/doc/design/assistant/blog/day_93__easy_install/comment_2_6337b341c1cfb2132b59704394e57b36._comment b/doc/design/assistant/blog/day_93__easy_install/comment_2_6337b341c1cfb2132b59704394e57b36._comment
new file mode 100644
index 000000000..ba027e921
--- /dev/null
+++ b/doc/design/assistant/blog/day_93__easy_install/comment_2_6337b341c1cfb2132b59704394e57b36._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.149"
+ subject="comment 2"
+ date="2012-09-30T17:11:13Z"
+ content="""
+The next upload to debian will enable building the assistant on architectures that don't have template haskell and so cannot build the webapp.
+"""]]
diff --git a/doc/design/assistant/blog/day_95__repository_groups.mdwn b/doc/design/assistant/blog/day_95__repository_groups.mdwn
new file mode 100644
index 000000000..5e4bc6d20
--- /dev/null
+++ b/doc/design/assistant/blog/day_95__repository_groups.mdwn
@@ -0,0 +1,21 @@
+Spent a lot of time this weekend thinking about/stuck on the [[cloud]]
+notification problem. Currently IRC is looking like the best way for
+repositories to notify one-another when changes are made, but I'm not sure
+about using that, and not ready to start on it.
+
+Instead, laid some groundwork for [[transfer_control]] today. Added
+some simple commands to manage groups of repositories, and find files
+that are present in repositories in a group. I'm not completely happy
+with the syntax for that, and need to think up some good syntax to specify
+files that are present in *all* repositories in a group.
+
+The plan is to have the assistant automatically guess at groups to put new
+repositories it makes in (it should be able to make good guesses),
+as well as have an interface to change them, and an interface to configure
+transfer control using these groups (and other ways of matching files).
+And, probably, some canned transfer control recipes for common setups.
+
+---
+
+Collected up the past week's work and made a release today. I'm probably
+back to making regular releases every week or two.
diff --git a/doc/design/assistant/blog/day_96__revisiting_file_adds.mdwn b/doc/design/assistant/blog/day_96__revisiting_file_adds.mdwn
new file mode 100644
index 000000000..a9607bb80
--- /dev/null
+++ b/doc/design/assistant/blog/day_96__revisiting_file_adds.mdwn
@@ -0,0 +1,24 @@
+Today I revisited something from way back in [[day_7__bugfixes]].
+Back then, it wasn't practical to run `git ls-files` on every
+file the watcher noticed, to check if it was already in git. Revisiting
+this, I found I could efficiently do that check at the same point it checks
+`lsof`. When there's a lot of files being added, they're batched up at that
+point, so it won't be calling `git ls-files` repeatedly.
+
+Result: It's safe to mix use of the assistant with files stored in git
+in the normal way. And it's safe to mix use of `git annex unlock` with
+the assistant; it won't immediately re-lock files. Yay!
+
+----
+
+Also fixed a crash in the committer, and made `git annex status` display
+repository groups.
+
+----
+
+Been thinking through where to store the [[transfer_control]] expressions.
+Since repositories need to know about the transfer controls of other
+remotes, storing them in `.git/config` isn't right. I thought it might be
+nice to configure the expressions in `.gitattributes`, but it seems the
+file format doesn't allow complicated multi-word attributes. Instead,
+they'll be stored in the git-annex branch.
diff --git a/doc/design/assistant/blog/day_96__revisiting_file_adds/comment_1_da3ca47041168b6c82aeb2c18acc5017._comment b/doc/design/assistant/blog/day_96__revisiting_file_adds/comment_1_da3ca47041168b6c82aeb2c18acc5017._comment
new file mode 100644
index 000000000..298a95371
--- /dev/null
+++ b/doc/design/assistant/blog/day_96__revisiting_file_adds/comment_1_da3ca47041168b6c82aeb2c18acc5017._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://wiggy.net/"
+ nickname="Wichert"
+ subject="symlinks?"
+ date="2012-10-03T07:15:21Z"
+ content="""
+Does that mean that git-annex will no longer need to turn everything into symlinks? I suspect that that will improve behaviour on at least OSX quite a bit.
+"""]]
diff --git a/doc/design/assistant/blog/day_97__stuffing.mdwn b/doc/design/assistant/blog/day_97__stuffing.mdwn
new file mode 100644
index 000000000..595aca1e0
--- /dev/null
+++ b/doc/design/assistant/blog/day_97__stuffing.mdwn
@@ -0,0 +1,14 @@
+Not a lot of programming today; I spent most of the day stuffing hundreds
+of envelopes for this Kickstarter thing you may have heard of. Some post
+office is going to be very surprised with all the international mail soon.
+
+----
+
+That said, I did write 184 lines of code. (Actually rather a lot, but it
+was mostly pure functional code, so easy to write.) That
+pops up your text editor on a file with the the trust and group
+configurations of repositories, that's stored in the git-annex branch.
+Handy for both viewing that stuff all in one place, and changing it.
+
+The real reason for doing that is to provide a nice interface for editing
+transfer control expressions, which I'll be adding next.
diff --git a/doc/design/assistant/blog/day_98__preferred_content.mdwn b/doc/design/assistant/blog/day_98__preferred_content.mdwn
new file mode 100644
index 000000000..d1324f69e
--- /dev/null
+++ b/doc/design/assistant/blog/day_98__preferred_content.mdwn
@@ -0,0 +1,44 @@
+Started implementing [[transfer_control]]. Although I'm currently calling
+the configuration for it "preferred content expressions". (What a mouthful!)
+
+I was mostly able to reuse the Limit code (used to handle parameters like
+--not --in otherrepo), so it can already build Matchers for preferred content
+expressions in my little Domain Specific Language.
+
+Preferred content expressions can be edited with `git annex vicfg`, which
+checks that they parse properly.
+
+The plan is that the first place to use them is not going to be inside the
+assistant, but in commands that use the `--auto` parameter, which will use
+them as an additional constraint, in addition to the numcopies setting
+already used. Once I get it working there, I'll add it to the assistant.
+
+Let's say a repo has a preferred content setting of
+"(not copies=trusted:2) and (not in=usbdrive)"
+
+* `git annex get --auto` will get files that have less than 2 trusted
+ copies, and are not in the usb drive.
+* `git annex drop --auto` will drop files that have 2 or more trusted
+ copies, and are not in the usb drive (assuming numcopies allows dropping
+ them of course).
+* `git annex copy --auto --to thatrepo` run from another repo
+ will only copy files that have less than 2 trusted copies. (And if that
+ was run on the usb drive, it'd never copy anything!)
+
+There is a complication here.. What if the repo with that preferred content
+setting is itself trusted? Then when it gets a file, its number of
+trusted copies increases, which will make it be dropped again. :-/
+
+This is a nuance that the numcopies code already deals with, but it's
+much harder to deal with it in these complicated expressions. I need to think
+about this; the three ideas I'm working on are:
+
+1. Leave it to whoever/whatever writes these expressions to write ones
+ that avoid such problems. Which is ok if I'm the only one writing
+ pre-canned ones, in practice..
+2. Transform expressions into ones that avoid such problems. (For example,
+ replace "not copies=trusted:2" with "not (copies=trusted:2 or (in=here and
+ trusted=here and copies=trusted:3))"
+3. Have some of the commands (mostly drop I think) pretend the drop
+ has already happened, and check if it'd then want to get the file back
+ again.
diff --git a/doc/design/assistant/blog/day_98__preferred_content/comment_1_2136618e3515d0ac6369a41f1934ec2a._comment b/doc/design/assistant/blog/day_98__preferred_content/comment_1_2136618e3515d0ac6369a41f1934ec2a._comment
new file mode 100644
index 000000000..b0fcd8c79
--- /dev/null
+++ b/doc/design/assistant/blog/day_98__preferred_content/comment_1_2136618e3515d0ac6369a41f1934ec2a._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="http://meep.pl/"
+ ip="193.23.174.18"
+ subject="Ah, the barber paradox"
+ date="2012-10-05T06:51:11Z"
+ content="""
+Nice. Would (not in=here) be the simplest paradoxical expression?
+
+Is just disregarding the target repo completely during checks a possibility? This would interpret (not copies=trusted:X) as \"not in X *other* trusted repositories, no matter whether we are trusted or not\", and (not in=here) just as \"true\". I think this should generally arrive at the same results as the option 2., but by definition of the expression meaing, not by rewriting.
+
+Alternative 3 (or is my wording different enough to be 3a?) - check that the invariant \"we have all the known files matching our PCE and only these files\" would hold after an operation before actually performing it - could be bistable if done both for gets and drops:
+
+* (not in=here) and we do not have the file -> get thinks \"if we get it, we have a file not matching the PCE\" -> get does not get it;
+* (not in=here) and we do have the file -> drop thinks \"if we drop it, there exists a file matching the PCE which we miss\" -> drop does not drop it.
+
+This is not necessarily bad. Checking just for drops should be monostable, I guess, but doesn't it look a bit arbitrary? (Though it would be again equivalent to option 2, wouldn't it? So maybe not that arbitrary.)
+"""]]
diff --git a/doc/design/assistant/blog/day_98__preferred_content/comment_2_5f6db00e69628bf2f72b0e6f2981a49b._comment b/doc/design/assistant/blog/day_98__preferred_content/comment_2_5f6db00e69628bf2f72b0e6f2981a49b._comment
new file mode 100644
index 000000000..fa1ce32b8
--- /dev/null
+++ b/doc/design/assistant/blog/day_98__preferred_content/comment_2_5f6db00e69628bf2f72b0e6f2981a49b._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.149"
+ subject="comment 2"
+ date="2012-10-05T15:08:26Z"
+ content="""
+Yes, I think checking the future only for drops is both stable and equivilant to the other choices.
+
+Disregarding the target solves the problem for the current set of expressions. There may be future expressions or operations where that does not hold. For example, if move supported --auto (which it does not), you'd need to disregard both sides.
+
+That method would make it impossible to do some possibly useful things. \"in=here or (not copies=3)\"
+
+The real problem with it is that existing options like --copies and --in already take all repos into account, so this would potentally lead to two divergent DSLs being used by git-annex, which would probably be confusing.
+"""]]
diff --git a/doc/design/assistant/blog/day_99_shotgun.mdwn b/doc/design/assistant/blog/day_99_shotgun.mdwn
new file mode 100644
index 000000000..77a08f3cb
--- /dev/null
+++ b/doc/design/assistant/blog/day_99_shotgun.mdwn
@@ -0,0 +1,70 @@
+Fixed the assistant to wait on all the zombie processes that would sometimes
+pile up. I didn't realize this was as bad as it was.
+
+Zombies and git-annex have been a problem since I started developing it,
+because back then I made some rather poor choices, due to barely knowing
+how to write Haskell. So parts of the code that stream input from git commands
+don't clean up after them properly. Not normally a problem, because
+git-annex reaps the zombies after each file it processes. But this reaping
+is not thread-safe; it cannot be used in the assistant.
+
+If I were starting git-annex today, I'd use one of the new Haskell things like
+Conduits, that allow for very clean control over finalization of resources.
+But switching it to Conduits now would probably take weeks of work; I've not
+yet felt it was worthwhile. (Also it's not clear Conduits are the last,
+best thing.)
+
+For now, it keeps track of the pids it needs to wait on, and all the code
+run by the assistant is zombie-free. However, some code for fsck and unused
+that I anticipate the assistant using eventually still has some lurking
+zombies.
+
+----
+
+Solved the issue with preferred content expressions and dropping that
+I mentioned yesterday. My solution was to add a parameter to specify a set
+of repositories where content should be assumed not to be present. When
+deciding whether to drop, it can put the current repository in, and then
+if the expression fails to match, the content can be dropped.
+
+Using yesterday's example "(not copies=trusted:2) and (not in=usbdrive)",
+when the local repo is one of the 2 trusted copies, the drop check will
+see only 1 trusted copy, so the expression matches, and so the content will
+not be dropped.
+
+I've not tested my solution, but it type checks. :P I'll wire it up to
+`get/drop/move --auto` tomorrow and see how it performs.
+
+----
+
+Would preferred content expressions be more readble if they were inverted
+(becoming content filtering expressions)?
+
+1. "(not copies=trusted:2) and (not in=usbdrive)" becomes
+ "copies=trusted:2 or in=usbdrive"
+2. "smallerthan=10mb and include=*.mp3 and exclude=junk/*" becomes
+ "largerthan=10mb or exclude=*.mp3" or include=junk/*"
+3. "(not group=archival) and (not copies=archival:1)" becomes
+ "group=archival or copies=archival:1"
+
+1 and 3 are improved, but 2, less so. It's a trifle weird for "include"
+to mean "include in excluded content".
+
+The other reason not to do this is that currently the expressions
+can be fed into `git annex find` on the command line, and it'll come
+back with the files that would be kept.
+
+Perhaps a middle groud is to make "dontwant" be an alias for "not".
+Then we can write "dontwant (copies=trusted:2 or in=usbdrive)"
+
+----
+
+A user told me this:
+
+> I can confirm that the assistant does what it is supposed to do really well. I
+> just hooked up my notebook to the network and it starts syncing from notebook to
+> fileserver and the assistant on the fileserver also immediately starts syncing
+> to the [..] backup
+
+That makes me happy, it's the first quite so real-world success report I've
+heard.
diff --git a/doc/design/assistant/blog/day_99_shotgun/comment_1_12bb8f54bb13ea20ac4187a2301d77ca._comment b/doc/design/assistant/blog/day_99_shotgun/comment_1_12bb8f54bb13ea20ac4187a2301d77ca._comment
new file mode 100644
index 000000000..eeaefef42
--- /dev/null
+++ b/doc/design/assistant/blog/day_99_shotgun/comment_1_12bb8f54bb13ea20ac4187a2301d77ca._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://meep.pl/"
+ ip="193.23.174.18"
+ subject="Include/exclude"
+ date="2012-10-06T08:40:23Z"
+ content="""
+It seems that example 2 reads weird for filtering because exclude/include say *what to do* while copies/in say *what to test*. An alias (maybe \"glob\") for include should be acceptable both ways (largerthan=10mb or glob=junk/\* or not glob=\*.mp3).
+
+That said, I would vote for keeping PCEs. And actually the simple \"not (copies=trusted:2 or in=usbdrive)\" does not read significantly worse than with \"dontwant\". (In *my bikeshed* we would have \"all\" == \"glob=\*\" and \"except\" == \"and not\").
+"""]]
diff --git a/doc/design/assistant/blog/day_9__correctness.mdwn b/doc/design/assistant/blog/day_9__correctness.mdwn
new file mode 100644
index 000000000..1fa4c09d0
--- /dev/null
+++ b/doc/design/assistant/blog/day_9__correctness.mdwn
@@ -0,0 +1,30 @@
+ git merge watch_
+
+My cursor has been mentally poised here all day, but I've been reluctant to
+merge watch into master. It seems solid, but is it correct? I was able to
+think up a lot of races it'd be subject to, and deal with them, but did I
+find them all?
+
+Perhaps I need to do some automated fuzz testing to reassure myself.
+I looked into using [genbackupdata](http://liw.fi/genbackupdata/) to that
+end. It's not quite what I need, but could be
+[moved in that direction](http://bugs.debian.org/677542). Or I could write
+my own fuzz tester, but it seems better to use someone else's, because
+a) laziness and b) they're less likely to have the same blind spots I do.
+
+My reluctance to merge isn't helped by the known bugs with files that are
+either already open before `git annex watch` starts, or are opened by two
+processes at once, and confuse it into annexing the still-open file when one
+process closes it.
+
+I've been thinking about just running `lsof` on every file as it's being
+annexed to check for that, but in the end, `lsof` is too slow. Since its
+check involves trawling through all of /proc, it takes it a good half a
+second to check a file, and adding 25 seconds to the time it takes to
+process 100 files is just not acceptable.
+
+But an option that could work is to run `lsof` after a bunch of new files
+have been annexed. It can check a lot of files nearly as fast as a single
+one. In the rare case that an annexed file is indeed still open, it could
+be moved back out of the annex. Then when its remaining writer finally
+closes it, another inotify event would re-annex it.
diff --git a/doc/design/assistant/blog/day_9__correctness/comment_1_564a39cb976767e2c0a9c74fabe10be4._comment b/doc/design/assistant/blog/day_9__correctness/comment_1_564a39cb976767e2c0a9c74fabe10be4._comment
new file mode 100644
index 000000000..8236002cc
--- /dev/null
+++ b/doc/design/assistant/blog/day_9__correctness/comment_1_564a39cb976767e2c0a9c74fabe10be4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://wiggy.net/"
+ nickname="Wichert"
+ subject="os compatibility"
+ date="2012-06-15T07:19:23Z"
+ content="""
+A downside of relying on lsof is that you might be painting yourself into a linux corner: other operating systems might not have a lsof or alternative you can rely on. Especially for Windows this might be a worry.
+"""]]
diff --git a/doc/design/assistant/blog/day_9__correctness/comment_2_77924e9d50b40f05e792e427a25849a6._comment b/doc/design/assistant/blog/day_9__correctness/comment_2_77924e9d50b40f05e792e427a25849a6._comment
new file mode 100644
index 000000000..8744882c9
--- /dev/null
+++ b/doc/design/assistant/blog/day_9__correctness/comment_2_77924e9d50b40f05e792e427a25849a6._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://dieter-be.myopenid.com/"
+ nickname="dieter"
+ subject="filesystem number of open file handles on a file"
+ date="2012-06-15T08:21:37Z"
+ content="""
+wasn't there some filesystem functionality that could tell you the amount of open file handles on a certain file? I thought this was tracked per-file too.
+Or maybe i'm just confusing it with the number of hard links (which stat can tell you), anyway something to look into.
+"""]]
diff --git a/doc/design/assistant/blog/day_9__correctness/comment_3_92bd86cd06d579e23800af2e5c66a291._comment b/doc/design/assistant/blog/day_9__correctness/comment_3_92bd86cd06d579e23800af2e5c66a291._comment
new file mode 100644
index 000000000..680f16ecc
--- /dev/null
+++ b/doc/design/assistant/blog/day_9__correctness/comment_3_92bd86cd06d579e23800af2e5c66a291._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 3"
+ date="2012-06-15T08:58:17Z"
+ content="""
+I would also be reluctant to use lsof for the sake of non-linux systems or systems that don't have lsof. I've only been playing around with the watch branch of my \"other\" laptop under archlinux. It looks usable, however I would prefer support for OSX before the watch branch gets merged to master ;)
+"""]]
diff --git a/doc/design/assistant/blog/day_9__correctness/comment_4_0d12b51ccdfc2a94d3e59a5628521e0a._comment b/doc/design/assistant/blog/day_9__correctness/comment_4_0d12b51ccdfc2a94d3e59a5628521e0a._comment
new file mode 100644
index 000000000..721875491
--- /dev/null
+++ b/doc/design/assistant/blog/day_9__correctness/comment_4_0d12b51ccdfc2a94d3e59a5628521e0a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 4"
+ date="2012-06-15T10:21:17Z"
+ content="""
+Corner case, but if the other program finishes writing while you are annexing and your check shows no open files, you are left with bad checksum on a correct file. This \"broken\" file with propagate and the next round of fsck will show that all copies are \"bad\".
+
+Without verifying if this is viable, could you set the file RO and thus block future writes before starting to annex?
+"""]]
diff --git a/doc/design/assistant/blog/day_9__correctness/comment_5_208f9dd3e1d92555b05c29159538a901._comment b/doc/design/assistant/blog/day_9__correctness/comment_5_208f9dd3e1d92555b05c29159538a901._comment
new file mode 100644
index 000000000..b7fbecc39
--- /dev/null
+++ b/doc/design/assistant/blog/day_9__correctness/comment_5_208f9dd3e1d92555b05c29159538a901._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.135"
+ subject="comment 5"
+ date="2012-06-15T15:14:52Z"
+ content="""
+@wichert All this inotify stuff is entirely linux specific AFAIK anyway, so it's find for workarounds to limitations in inotify functionality to also be linux specific.
+
+@dieter I think you're thinking of hard links, filesystems don't track number of open file handles afaik.
+
+@Jimmy, I'm planning to get watch going on freebsd (and hopefully that will also cover OSX), after merging it :)
+
+@Richard, the file is set RO while it's being annexed, so any lsof would come after that point.
+"""]]
diff --git a/doc/design/assistant/blog/day_9__correctness/comment_6_90cc6b60718896fb175919417600fdf9._comment b/doc/design/assistant/blog/day_9__correctness/comment_6_90cc6b60718896fb175919417600fdf9._comment
new file mode 100644
index 000000000..622b141fd
--- /dev/null
+++ b/doc/design/assistant/blog/day_9__correctness/comment_6_90cc6b60718896fb175919417600fdf9._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.135"
+ subject="comment 6"
+ date="2012-06-15T15:23:21Z"
+ content="""
+But Rich is right, and I was thinking the same thing earlier this morning, that delaying the lsof allows the writer to change the file and exit, and only fsck can detect the problem then. Setting file permissions doesn't help once a process already has it open for write. Which has put me off the delayed lsof idea unfortunately. lsof *could* be run safely during the intial annexing.
+"""]]
diff --git a/doc/design/assistant/chunks.mdwn b/doc/design/assistant/chunks.mdwn
new file mode 100644
index 000000000..6a92731ee
--- /dev/null
+++ b/doc/design/assistant/chunks.mdwn
@@ -0,0 +1,7 @@
+To avoid leaking even the size of your encrypted files to cloud storage
+providers, add a mode that stores fixed size chunks.
+
+May be a useful starting point for [[deltas]].
+
+May also allow for downloading different chunks of a file concurrently from
+multiple remotes.
diff --git a/doc/design/assistant/cloud.mdwn b/doc/design/assistant/cloud.mdwn
new file mode 100644
index 000000000..aa0eba382
--- /dev/null
+++ b/doc/design/assistant/cloud.mdwn
@@ -0,0 +1,45 @@
+The [[syncing]] design assumes the network is connected. But it's often
+not in these pre-IPV6 days, so the cloud needs to be used to bridge between
+LANS.
+
+## The cloud notification problem (**done**)
+
+Alice and Bob have repos, and there is a cloud remote they both share.
+Alice adds a file; the assistant transfers it to the cloud remote.
+How does Bob find out about it?
+
+There are two parts to this problem. Bob needs to find out that there's
+been a change to Alice's git repo. Then he needs to pull from Alice's git repo,
+or some other repo in the cloud she pushed to. Once both steps are done,
+the assistant will transfer the file from the cloud to Bob.
+
+* dvcs-autosync uses xmppp; all repos need to have the same xmpp account
+ configured, and send self-messages. An alternative would be to have
+ different accounts that join a channel or message each other. Still needs
+ account configuration.
+* irc could be used. With a default irc network, and an agreed-upon channel,
+ no configuration should be needed. IRC might be harder to get through
+ some firewalls, and is prone to netsplits, etc. IRC networks have reasons
+ to be wary of bots using them. Only basic notifications could be done over
+ irc, as it has little security.
+* When there's a ssh server involved, code could be run on it to notify
+ logged-in clients. But this is not a general solution to this problem.
+* pubsubhubbub does not seem like an option; its hubs want to pull down
+ a feed over http.
+
+See [[xmpp]] for design of git-annex's use of xmpp for push notifications.
+
+## storing git repos in the cloud **done for XMPP**
+
+Of course, one option is to just use github etc to store the git repo.
+
+Two things can store git repos in Amazon S3:
+* <http://gabrito.com/post/storing-git-repositories-in-amazon-s3-for-high-availability>
+* <http://wiki.cs.pdx.edu/oss2009/index/projects/gits3.html>
+
+Another option is to not store the git repo in the cloud, but push/pull
+peer-to-peer. When peers cannot directly talk to one-another, this could be
+bounced through something like XMPP. This is **done** for [[xmpp]]!
+
+Another option: Use <https://github.com/blake2-ppc/git-remote-gcrypt> to store
+git repo encrypted on cloud storage.
diff --git a/doc/design/assistant/cloud/comment_1_4997778abc171999499487b71b31c9ba._comment b/doc/design/assistant/cloud/comment_1_4997778abc171999499487b71b31c9ba._comment
new file mode 100644
index 000000000..1a01afaa3
--- /dev/null
+++ b/doc/design/assistant/cloud/comment_1_4997778abc171999499487b71b31c9ba._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkq0-zRhubO6kR9f85-5kALszIzxIokTUw"
+ nickname="James"
+ subject="Cloud Service Limitations"
+ date="2012-06-11T02:15:04Z"
+ content="""
+Hey Joey!
+
+I'm not very tech savvy, but here is my question.
+I think for all cloud service providers, there is an upload limitation on how big one file may be.
+For example, I can't upload a file bigger than 100 MB on box.net.
+Does this affect git-annex at all? Will git-annex automatically split the file depending on the cloud provider or will I have to create small RAR archives of one large file to upload them?
+
+Thanks!
+James
+"""]]
diff --git a/doc/design/assistant/cloud/comment_2_08da8bc74a4845e354dca99184cffd70._comment b/doc/design/assistant/cloud/comment_2_08da8bc74a4845e354dca99184cffd70._comment
new file mode 100644
index 000000000..a9b377ea5
--- /dev/null
+++ b/doc/design/assistant/cloud/comment_2_08da8bc74a4845e354dca99184cffd70._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.126"
+ subject="re: cloud"
+ date="2012-06-11T04:48:08Z"
+ content="""
+Yes, git-annex has to split files for certian providers. I already added support for this as part of my first pass at supporting box.com, see [[tips/using_box.com_as_a_special_remote]].
+"""]]
diff --git a/doc/design/assistant/cloud/comment_3_faafd1266301997b1822d215ec8e8d8c._comment b/doc/design/assistant/cloud/comment_3_faafd1266301997b1822d215ec8e8d8c._comment
new file mode 100644
index 000000000..074a3a82c
--- /dev/null
+++ b/doc/design/assistant/cloud/comment_3_faafd1266301997b1822d215ec8e8d8c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn7Oyqusvn0oONFtVhCx5gRAcvPjyRMcBI"
+ nickname="Michaël"
+ subject="is ftp an option?"
+ date="2012-05-30T10:44:12Z"
+ content="""
+for people only having ftp-access to there storage.
+"""]]
diff --git a/doc/design/assistant/cloud/comment_4_3eb557d5439831f6e0032944d12c02cf._comment b/doc/design/assistant/cloud/comment_4_3eb557d5439831f6e0032944d12c02cf._comment
new file mode 100644
index 000000000..e3879a114
--- /dev/null
+++ b/doc/design/assistant/cloud/comment_4_3eb557d5439831f6e0032944d12c02cf._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawk9XEh8pxrJxZxIkyK7lWaA7QG1UWt9lgU"
+ nickname="Gugelplus"
+ subject="OwnCloud"
+ date="2012-08-27T20:43:19Z"
+ content="""
+“Google drive (attractive because it's free, only 5 gb tho)”
+
+Just in case somebody also wants their 5GB of disk space in the cloud, consider using some of the [owncloud providers](http://owncloud.org/providers/). They also offer that amount, but they use free software for everything, using standard protocols (WebDav mostly, because is well supported in all OS).
+
+Git Annex works with them through davfs2, but it would be great if it could support this other program/protocol (OwnCloud/WebDAV) in a more integrated way.
+"""]]
diff --git a/doc/design/assistant/comment_10_f2233fad55c20686cf299bf6788f1f23._comment b/doc/design/assistant/comment_10_f2233fad55c20686cf299bf6788f1f23._comment
new file mode 100644
index 000000000..f24357fb6
--- /dev/null
+++ b/doc/design/assistant/comment_10_f2233fad55c20686cf299bf6788f1f23._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://www.klomp.eu/"
+ ip="95.91.241.82"
+ subject="Watch also possible with git?"
+ date="2012-06-15T17:25:30Z"
+ content="""
+Hi,
+
+it seems that you put a lot of efforts in handling race conditions. Thats great. I wonder if the watch can also be used with git (i.e. changes are commited into git and not as annex)? I know that other projects follow this idea but why using different tools if the git-annex assistant could handle both...
+"""]]
diff --git a/doc/design/assistant/comment_11_a38f0f21c2346e65b786d791b6829f9b._comment b/doc/design/assistant/comment_11_a38f0f21c2346e65b786d791b6829f9b._comment
new file mode 100644
index 000000000..71a9f155d
--- /dev/null
+++ b/doc/design/assistant/comment_11_a38f0f21c2346e65b786d791b6829f9b._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawneJXwhacIb0YvvdYFxhlNVpz6Wpg6V7AA"
+ nickname="Shayne"
+ subject="comment 11"
+ date="2012-08-13T00:37:35Z"
+ content="""
+Yeah definately go with homebrew rather than macports if possible. macports and fink, whilst great systems, have a tendency to sort of create their own alternative-dimension of files within the system that just dont always feel particularly well integrated. As a result \"brew\" has become increasingly more popular to the point its almost ubuquitous now.
+
+Plus its brew-doctor thing is awesome.
+
+The best approach though thats agnostic to distro systems is to simply go for a generic installer.
+"""]]
diff --git a/doc/design/assistant/comment_12_5e991177d6577384f39a36ae02f5f574._comment b/doc/design/assistant/comment_12_5e991177d6577384f39a36ae02f5f574._comment
new file mode 100644
index 000000000..b2de673e3
--- /dev/null
+++ b/doc/design/assistant/comment_12_5e991177d6577384f39a36ae02f5f574._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlu-fdXIt_RF9ggvg4zP0yBbtjWQwHAMS4"
+ nickname="Jörn"
+ subject="Multiple annexes?"
+ date="2012-09-20T16:10:29Z"
+ content="""
+Thank you for this great piece of software which is now becoming even better with the assistant.
+
+Just one question: will one instance of the assistant be able to track multiple git annex repositories each building up their own network of annexes OR would I need to run multiple instances of the assistant?
+
+Thanks,
+Jörn
+"""]]
diff --git a/doc/design/assistant/comment_13_f8625c6f43b58847840df338a73b7972._comment b/doc/design/assistant/comment_13_f8625c6f43b58847840df338a73b7972._comment
new file mode 100644
index 000000000..c121eaf7f
--- /dev/null
+++ b/doc/design/assistant/comment_13_f8625c6f43b58847840df338a73b7972._comment
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ subject="comment 13"
+ date="2012-09-20T16:21:11Z"
+ content="""
+@Jörn, two days ago I added support in the webapp for multiple independent repositories. So you can create independent repos using it, and switch between them from a menu. Under the hood there are multiple git-annex assistant daemons running, but this is an implementation detail; it's not like these use any more memory or other resources than would a single daemon that managed multiple repositories.
+"""]]
diff --git a/doc/design/assistant/comment_14_c37ef5931b0f5c1f808083e0d636a208._comment b/doc/design/assistant/comment_14_c37ef5931b0f5c1f808083e0d636a208._comment
new file mode 100644
index 000000000..b43741feb
--- /dev/null
+++ b/doc/design/assistant/comment_14_c37ef5931b0f5c1f808083e0d636a208._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://id.koumbit.net/anarcat"
+ subject="you rock! & roadmap update?"
+ date="2012-09-21T04:25:58Z"
+ content="""
+joey, you rock. I just want to push on that point - it doesn't seem like there's that many tools that do what git-annex is trying to do out there, and you seem to be doing an incredible job at doing it, so this is great, keep going!
+
+i was wondering - i am glad to see the progress, but it is unclear to me where you actually are in the roadmap. are things going according to plan? are we at month 3? 4? or 1-4? :) just little updates on that roadmap section above would be quite useful!
+
+thanks again!
+"""]]
diff --git a/doc/design/assistant/comment_15_68c98a27083567f20c2e6bc2a760991b._comment b/doc/design/assistant/comment_15_68c98a27083567f20c2e6bc2a760991b._comment
new file mode 100644
index 000000000..10b55bbe3
--- /dev/null
+++ b/doc/design/assistant/comment_15_68c98a27083567f20c2e6bc2a760991b._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ subject="comment 15"
+ date="2012-09-21T05:25:53Z"
+ content="""
+We're on month 4 of work, and most of months 1-3 is done well enough for a first pass. Very little of what's listed in month 4 has happened yet, due to my being maybe 2 weeks behind schedule, but bits of [[cloud]] are being planned.
+
+I've made a small adjustment, I think it'll make sense to spend a month on user-driven features before getting into Android.
+"""]]
diff --git a/doc/design/assistant/comment_16_8e6788c817c60371d2a2f158e1a65f87._comment b/doc/design/assistant/comment_16_8e6788c817c60371d2a2f158e1a65f87._comment
new file mode 100644
index 000000000..de5e5b078
--- /dev/null
+++ b/doc/design/assistant/comment_16_8e6788c817c60371d2a2f158e1a65f87._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://launchpad.net/~gdr-go2"
+ nickname="gdr-go2"
+ subject="Maybe a DEB?2"
+ date="2012-09-27T09:44:14Z"
+ content="""
+Month 3 was all about easy setup, so I kind of expected to download a deb package and just install it, not to download a whole bunch of haskell libraries. Is there a chance that you will release some packages?
+"""]]
diff --git a/doc/design/assistant/comment_17_97bdfacac5ac492281c9454ee4c0228e._comment b/doc/design/assistant/comment_17_97bdfacac5ac492281c9454ee4c0228e._comment
new file mode 100644
index 000000000..ea3f50e61
--- /dev/null
+++ b/doc/design/assistant/comment_17_97bdfacac5ac492281c9454ee4c0228e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.14.141"
+ subject="comment 17"
+ date="2012-09-27T18:44:11Z"
+ content="""
+@gdr A package with the assistant is available in Debian unstable.
+"""]]
diff --git a/doc/design/assistant/comment_18_53137b2df4913496c0afb2d895aa4ee2._comment b/doc/design/assistant/comment_18_53137b2df4913496c0afb2d895aa4ee2._comment
new file mode 100644
index 000000000..672c2a9d7
--- /dev/null
+++ b/doc/design/assistant/comment_18_53137b2df4913496c0afb2d895aa4ee2._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm7AuSfii_tCkLyspL6Mr0ATlO6OxLNYOo"
+ nickname="Georg"
+ subject="for OSX, package managers (homebrew and macports) are really second-class"
+ date="2013-07-24T07:24:49Z"
+ content="""
+at least with regards to wide spread use. I agree with Wichert, the average OSX user won't use them. I myself would go with homebrew (because it is far less of a pain than macports), but actually static built binaries that are just dragged from a DMG to your programs folder is the way to go if you can't go osx app store. It's just how most Apple users are wired. PKG would be fine, too, since most will know them, but those are really only needed if you need to place stuff in /Library/Frameworks or things like that. If it can be done as a all-inclusive OSX .app, do it that way and just pack it up in a .DMG.
+"""]]
diff --git a/doc/design/assistant/comment_19_ff1b0ba57e22ed757ec3fc5400b5e43e._comment b/doc/design/assistant/comment_19_ff1b0ba57e22ed757ec3fc5400b5e43e._comment
new file mode 100644
index 000000000..1ef6136b9
--- /dev/null
+++ b/doc/design/assistant/comment_19_ff1b0ba57e22ed757ec3fc5400b5e43e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlnoH5btjn_BLib3_IhES5uMhrzuOiwCYo"
+ nickname="András"
+ subject="windows port"
+ date="2013-07-25T07:50:19Z"
+ content="""
+I'd love to use the Windows port of the assistant by Christmas. Keep up the good work! :)
+"""]]
diff --git a/doc/design/assistant/comment_1_a48fcfbf97f0a373ea375cd8f07f0fc8._comment b/doc/design/assistant/comment_1_a48fcfbf97f0a373ea375cd8f07f0fc8._comment
new file mode 100644
index 000000000..646a03398
--- /dev/null
+++ b/doc/design/assistant/comment_1_a48fcfbf97f0a373ea375cd8f07f0fc8._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 1"
+ date="2012-06-02T12:06:37Z"
+ content="""
+Will statically linked binaries be provided for say Linux, OSX and *BSD? I think having some statically linked binaries will certainly help and appeal to a lot of users.
+"""]]
diff --git a/doc/design/assistant/comment_20_099da245e3276fa84f5e14312d186621._comment b/doc/design/assistant/comment_20_099da245e3276fa84f5e14312d186621._comment
new file mode 100644
index 000000000..f423c3e10
--- /dev/null
+++ b/doc/design/assistant/comment_20_099da245e3276fa84f5e14312d186621._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 20"
+ date="2013-07-25T18:22:51Z"
+ content="""
+@Georg, DMG have been built for OSX for a long time. See [[install/OSX]]
+"""]]
diff --git a/doc/design/assistant/comment_2_6d3552414fdcc2ed3244567e6c67989d._comment b/doc/design/assistant/comment_2_6d3552414fdcc2ed3244567e6c67989d._comment
new file mode 100644
index 000000000..8056eec16
--- /dev/null
+++ b/doc/design/assistant/comment_2_6d3552414fdcc2ed3244567e6c67989d._comment
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ subject="comment 2"
+ date="2012-06-04T19:45:00Z"
+ content="""
+Jimmy, I hope to make it as easy as possible to install. I've been focusing on getting it directly into popular Linux distributions, rather than shipping my own binary. The OSX binary is static, and while I lack a OSX machine, I would like to get it easier to distribute to OSX users.
+"""]]
diff --git a/doc/design/assistant/comment_3_05223be50c889b2ed6bc4abf74116450._comment b/doc/design/assistant/comment_3_05223be50c889b2ed6bc4abf74116450._comment
new file mode 100644
index 000000000..a78fa3343
--- /dev/null
+++ b/doc/design/assistant/comment_3_05223be50c889b2ed6bc4abf74116450._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 3"
+ date="2012-06-07T20:22:55Z"
+ content="""
+I'd agree getting it into the main distros is the way to go, if you need OSX binaries, I could volunteer to setup an autobuilder to generate binaries for OSX users, however it would rely on users to have macports with the correct ports installed to use it (things like coreutils etc...)
+
+"""]]
diff --git a/doc/design/assistant/comment_4_fbbd93b55803ae21e6ba4b6568c2fafd._comment b/doc/design/assistant/comment_4_fbbd93b55803ae21e6ba4b6568c2fafd._comment
new file mode 100644
index 000000000..cd3b5aaef
--- /dev/null
+++ b/doc/design/assistant/comment_4_fbbd93b55803ae21e6ba4b6568c2fafd._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ subject="comment 4"
+ date="2012-06-08T01:56:52Z"
+ content="""
+I always appreciate your OSX work Jimmy...
+
+Could it be put into macports?
+"""]]
diff --git a/doc/design/assistant/comment_5_f4e9af3fed6c27e8ff39badb9794064d._comment b/doc/design/assistant/comment_5_f4e9af3fed6c27e8ff39badb9794064d._comment
new file mode 100644
index 000000000..bf8d9709e
--- /dev/null
+++ b/doc/design/assistant/comment_5_f4e9af3fed6c27e8ff39badb9794064d._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 5"
+ date="2012-06-08T07:22:34Z"
+ content="""
+In relation to macports, I often found that haskell in macports are often behind other distros, and I'm not willing to put much effort into maintaining or updating those ports. I found that to build git-annex, installing macports manually and then installing haskell-platform from the upstream to be the best way to get the most up to date dependancies for git-annex.
+
+fyi in macports ghc is at version 6.10.4 and haskell platform is at version 2009.2, so there are a significant number of ports to update.
+
+I was thinking about this a bit more and I reckon it might be easier to try and build a self contained .pkg package and have all the needed binaries in a .app styled package, that would work well when the webapp comes along. I will take a look at it in a week or two (currently moving house so I dont have much time)
+"""]]
diff --git a/doc/design/assistant/comment_6_c7ad07cade1f44f9a8b61f92225bb9c5._comment b/doc/design/assistant/comment_6_c7ad07cade1f44f9a8b61f92225bb9c5._comment
new file mode 100644
index 000000000..9fa66d6d3
--- /dev/null
+++ b/doc/design/assistant/comment_6_c7ad07cade1f44f9a8b61f92225bb9c5._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 6"
+ date="2012-06-08T15:21:18Z"
+ content="""
+It's not much for now... but see <http://www.sgenomics.org/~jtang/gitbuilder-git-annex-x00-x86_64-apple-darwin10.8.0/> I'm ignoring the debian-stable and pristine-tar branches for now, as I am just building and testing on osx 10.7.
+
+Hope the autobuilder will help you develop the OSX side of things without having direct access to an osx machine! I will try and get gitbuilder to spit out appropriately named tarballs of the compiled binaries in a few days when I have more time.
+"""]]
diff --git a/doc/design/assistant/comment_7_609d38e993267195a80fecd84c93d1e2._comment b/doc/design/assistant/comment_7_609d38e993267195a80fecd84c93d1e2._comment
new file mode 100644
index 000000000..6685c6548
--- /dev/null
+++ b/doc/design/assistant/comment_7_609d38e993267195a80fecd84c93d1e2._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.126"
+ subject="comment 7"
+ date="2012-06-09T18:07:51Z"
+ content="""
+Thanks, that's already been useful to me. You might as well skip the debian-specific \"bpo\" tags too.
+"""]]
diff --git a/doc/design/assistant/comment_8_22b818e1a2a825efb78139271a14f944._comment b/doc/design/assistant/comment_8_22b818e1a2a825efb78139271a14f944._comment
new file mode 100644
index 000000000..57f354e49
--- /dev/null
+++ b/doc/design/assistant/comment_8_22b818e1a2a825efb78139271a14f944._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawldKnauegZulM7X6JoHJs7Gd5PnDjcgx-E"
+ nickname="Matt"
+ subject="Homebrew instead of MacPorts"
+ date="2012-06-22T04:26:02Z"
+ content="""
+[Homebrew] is a much better package manager than MacPorts IMO.
+
+[Homebrew]: http://mxcl.github.com/homebrew/
+"""]]
diff --git a/doc/design/assistant/comment_9_d052e2142da8b4838fb1edf791ea23ae._comment b/doc/design/assistant/comment_9_d052e2142da8b4838fb1edf791ea23ae._comment
new file mode 100644
index 000000000..5e955c2b6
--- /dev/null
+++ b/doc/design/assistant/comment_9_d052e2142da8b4838fb1edf791ea23ae._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://wiggy.net/"
+ nickname="Wichert"
+ subject="macports"
+ date="2012-06-12T13:00:34Z"
+ content="""
+The average OSX user has a) no idea what macports is, and b) will not be able to install it. Anything that requires a user to do anything with a commandline (or really anything other than using a GUI installer) is effectively a dealbreaker. For our use cases OSX is definitely a requirement, but it must only use standard OSX installation methods in order to be usable. Being in the appstore would be ideal, but standard dmg/pkg installers are still common enough that they are also acceptable.
+
+FWIW this is the same reason many git GUIs were not usable for our OSX users: they required separate installation of the git commandline tools.
+"""]]
diff --git a/doc/design/assistant/configurators.mdwn b/doc/design/assistant/configurators.mdwn
new file mode 100644
index 000000000..4d08ac54a
--- /dev/null
+++ b/doc/design/assistant/configurators.mdwn
@@ -0,0 +1,20 @@
+Add to the [[webapp]] some configuration of git-annex.
+
+There are some basic settings that pass through to `git config`, things
+like how much disk space to leave free, how many copies to ensure are kept
+of files, etc.
+
+The meat of the configuration will be in configuration assistants that walk
+through setting up common use cases.
+
+* Create a repository (run when the web app is started without a configured
+ repository too). **done**
+* Clone this repo to a USB drive or other removable drive. **done**
+* Make a bare repo on a remote ssh server **done**
+* Clone this repo to another host. (Needs [[pairing]]) **done**
+* Set up Amazon S3. **done**
+* Set up encrypted rsync remote. **done**
+* Rsync.net special case **done**
+* Set up gpg encryption key; gpg key distribution.
+* I lost my USB drive!
+* etc -- many more possibilities
diff --git a/doc/design/assistant/deltas.mdwn b/doc/design/assistant/deltas.mdwn
new file mode 100644
index 000000000..ff4185a18
--- /dev/null
+++ b/doc/design/assistant/deltas.mdwn
@@ -0,0 +1,9 @@
+Speed up syncing of modified versions of existing files.
+
+One simple way is to find the key of the old version of a file that's
+being transferred, so it can be used as the basis for rsync, or any
+other similar transfer protocol.
+
+For remotes that don't use rsync, a poor man's version could be had by
+chunking each object into multiple parts. Only modified parts need be
+transferred. Sort of sub-keys to the main key being stored.
diff --git a/doc/design/assistant/deltas/comment_1_bdb477af913c9782c0e8509e6b294b6e._comment b/doc/design/assistant/deltas/comment_1_bdb477af913c9782c0e8509e6b294b6e._comment
new file mode 100644
index 000000000..3361de4bf
--- /dev/null
+++ b/doc/design/assistant/deltas/comment_1_bdb477af913c9782c0e8509e6b294b6e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkfHTPsiAcHEEN7Xl7WxiZmYq-vX7azxFY"
+ nickname="Vincent"
+ subject="zsync?"
+ date="2012-09-10T12:35:45Z"
+ content="""
+zsync.moria.org.uk may have broken some of the ground here.
+"""]]
diff --git a/doc/design/assistant/deltas/comment_2_71889d15ba20ebb0fe13080c68162a5b._comment b/doc/design/assistant/deltas/comment_2_71889d15ba20ebb0fe13080c68162a5b._comment
new file mode 100644
index 000000000..3ef911b77
--- /dev/null
+++ b/doc/design/assistant/deltas/comment_2_71889d15ba20ebb0fe13080c68162a5b._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm72W-CH7bzZ8uHvaw1KJGrToPSQDNBnIA"
+ nickname="Beni"
+ subject="bup splitting"
+ date="2013-08-05T17:13:14Z"
+ content="""
+bup splits files into chunks based on rolling sums.
+https://github.com/apenwarr/bup/blob/master/DESIGN
+For small changes to big files, this would improve not only transfer speed but also repository size.
+And git-annex already supports bup remotes. What's missing?
+"""]]
diff --git a/doc/design/assistant/desymlink.mdwn b/doc/design/assistant/desymlink.mdwn
new file mode 100644
index 000000000..ffa37399d
--- /dev/null
+++ b/doc/design/assistant/desymlink.mdwn
@@ -0,0 +1,145 @@
+While dropbox allows modifying files in the folder, git-annex freezes
+them upon creation, using symlinks.
+
+This is a core design simplification of git-annex.
+But it is problematic too:
+
+* To allow directly editing files in its folder, something like [[todo/smudge]] is
+ needed, to get rid of the symlinks that stand in for the files.
+* OSX seems to have a [[lot_of_problems|bugs/OSX_alias_permissions_and_versions_problem]]
+ with stupid programs that follow symlinks and present the git-annex
+ hash filename to the user.
+* FAT sucks and doesn't support symlinks at all, so [[Android]] can't
+ have regular repos on it.
+
+One approach for this would be to hide the git repo away somewhere,
+and have the git-annex assistant watch a regular directory, with
+regular files.
+
+There would have to be a mapping from files to git-annex objects.
+And some intelligent way to determine when a file has been changed
+and no longer corresponds to its object. (Not expensive hashing every time,
+plz.)
+
+Since this leaves every file open to modification, any such repository
+probably needs to be considered untrusted by git-annex. So it doesn't
+leave its only copy of a file in such a repository, but instead
+syncs it to a proper git-annex repository.
+
+The assistant would make git commits still, of symlinks. It can already do
+that with without actual symlinks existing on disk. More difficult is
+handling merging; git merge wants a real repository with files it can
+really operate on. The assistant would need to calculate merges on its own,
+and update the regular directory to reflect changes made in the merge.
+
+Another massive problem with this idea is that it doesn't allow for
+[[partial_content]]. The symlinks that everyone loves to hate on are what
+make it possible for the contents of some files to not be present on
+disk, while the files are still in git and can be retreived as desired.
+With real files, some other standin for a missing file would be needed.
+Perhaps a 0 length, unreadable, unwritable file? On systems that
+support symlinks it could be a broken symlink like is used now, that
+is converted to a real file when it becomes present.
+
+## concrete design
+
+* Enable with annex.direct
+* Use .git/ for the git repo, but `.git/annex/objects` won't be used
+ for object storage.
+* `git status` and similar will show all files as type changed, and
+ `git commit` would be a very bad idea. Just don't support users running
+ git commands that affect the repository in this mode. Probably.
+* However, `git status` and similar also will show deleted and new files,
+ which will be helpful for the assistant to use when starting up.
+* Cache the mtime, size etc of files, and use this to detect when they've been
+ modified when the assistant was not running. This would only need to be
+ checked at startup, probably.
+* Use dangling symlinks for standins for missing content, as now.
+ This allows just cloning one of these repositories normally, and then
+ as the files are synced in, they become real files.
+* Maintain a local mapping from keys to files in the tree. This is needed
+ when sending/receiving/dropping keys to know what file to access.
+ Note that a key can map to multiple files. And that when a file is
+ deleted or moved, the mapping needs to be updated.
+* May need a reverse mapping, from files in the tree to keys? TBD
+ (Currently, getting by looking up symlinks using `git cat-file`)
+ (Needed to make things like `git annex drop` that want to map from the
+ file back to the key work.)
+* The existing watch code detects when a file gets closed, and in this
+ mode, it could be a new file, or a modified file, or an unchanged file.
+ For a modified file, can compare mtime, size, etc, to see if it needs
+ to be re-added.
+* The inotify/kqueue interface does not tell us when a file is renamed.
+ So a rename has to be treated as a delete and an add, so can have a lot
+ of overhead, to re-hash the file.
+* Note that this could be used without the assistant, as a git remote
+ that content is transferred to and from. Without the assistant, changes
+ to files in this remote would not be noticed and committed, unless
+ a git-annex command were added to do so.
+ Getting it basically working as a remote would be a good 1st step.
+* It could also be used without the assistant as a repository that
+ the user uses directly. Would need some git-annex commands
+ to merge changes into the repo, update caches, and commit changes.
+ This could all be done by "git annex sync".
+
+## TODO
+
+* kqueue does not deliver an event when an existing file is modified.
+ This doesn't affect OSX, which uses FSEvents now, but it makes direct
+ mode assistant not 100% on other BSD's.
+
+## done
+
+* `git annex sync` updates the key to files mappings for files changed,
+ but needs much other work to handle direct mode:
+ * Generate git commit, without running `git commit`, because it will
+ want to stage the full files. **done**
+ * Update location logs for any files deleted by a commit. **done**
+ * Generate a git merge, without running `git merge` (or possibly running
+ it in a scratch repo?), because it will stumble over the direct files.
+ **done**
+ * Drop contents of files deleted by a merge (including updating the
+ location log), or if we cannot drop,
+ move their contents to `.git/annex/objects/`. **no** .. instead,
+ avoid ever losing file contents in a direct mode merge. If the file is
+ deleted, its content is moved back to .git/annex/objects, if necessary.
+ * When a merge adds a symlink pointing at a key that is present in the
+ repo, replace the symlink with the direct file (either moving out
+ of `.git/annex/objects/` or hard-linking if the same key is present
+ elsewhere in the tree. **done**
+ * handle merge conflicts on direct mode files **done**
+* support direct mode in the assistant (many little fixes)
+
+* Deal with files changing as they're being transferred from a direct mode
+ repository to another git repository. The remote repo currently will
+ accept the bad data and update the location log to say it has the key.
+
+ This affects both special remotes and git remotes.
+
+ For special remotes,
+ it seems the best that could be done is to have an error unwind action
+ passed to `sendAnnex` that is called if the file is modified as it's
+ transferred. That would then remove the probably corrupted file from the
+ remote. (The full transfer would still run, unless there was also a way
+ to cancel an in progress transfer.) **done**
+
+ (With the above, there is some potential for the bad content being
+ downloaded from the special remote into another repo. This would only
+ happen if the other repo for some reason thinks the special remote
+ has the content. Since the location log would not be updated until the
+ transfer is successful, this should not happen.)
+
+ For local git remotes, need to check the direct mode file after it's
+ copied and before it's put into place as a key's content. **done**
+ (untested)
+
+ `git-annex-shell sendkey` needs to do something if it sent bad
+ data. This seems to not need protocol changes; it can just detect
+ the problem and exit nonzero. Would need to do something to clean up
+ the temp file, which is probably corrupt. (Could in future use it as a
+ basis for transferring the new key..) **done**
+
+ For git remotes, added a flag to `git-annex-shell recvkey` (using a field
+ after the "--" to remain back-compat). With this flag, after receiving
+ the data, the remote fscks the data. This is not optimal, but avoids
+ needing another round-trip, or a protocol change.
diff --git a/doc/design/assistant/desymlink/comment_1_f1bfe250b7f872359f7075998b6e42e3._comment b/doc/design/assistant/desymlink/comment_1_f1bfe250b7f872359f7075998b6e42e3._comment
new file mode 100644
index 000000000..5e60ff29e
--- /dev/null
+++ b/doc/design/assistant/desymlink/comment_1_f1bfe250b7f872359f7075998b6e42e3._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn-KDr_Z4CMkjS0v_TxQ08SzAB5ecHG3K0"
+ nickname="Glen"
+ subject="Modifying files in a folder watched by assistant"
+ date="2012-09-19T14:18:54Z"
+ content="""
+I think this feature is really important. For my use cases, if I can't modify files that are in the folder that is kept in sync, then I would just use rsync or manually keep copies on multiple systems..
+
+I might be missing something, but tried a git annex unlock on the file, but if the assistant is running, it seems to revert this back.
+
+"""]]
diff --git a/doc/design/assistant/desymlink/comment_2_5e876edfe9853645f761b5ed9b5021aa._comment b/doc/design/assistant/desymlink/comment_2_5e876edfe9853645f761b5ed9b5021aa._comment
new file mode 100644
index 000000000..b79ae4781
--- /dev/null
+++ b/doc/design/assistant/desymlink/comment_2_5e876edfe9853645f761b5ed9b5021aa._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawknpbpx4uDElXRzJ4kPXuJU1KdcslOI6go"
+ nickname="Rodrigo"
+ subject="I strongly agree with Glen"
+ date="2012-10-03T14:07:40Z"
+ content="""
+And if your goal is to build an app \"like dropbox\" it is a must have feature.
+Thanks for your work. You are doing great!
+"""]]
diff --git a/doc/design/assistant/desymlink/comment_3_538561d74371e53c2f8df7f5ebdf58a8._comment b/doc/design/assistant/desymlink/comment_3_538561d74371e53c2f8df7f5ebdf58a8._comment
new file mode 100644
index 000000000..40067b25b
--- /dev/null
+++ b/doc/design/assistant/desymlink/comment_3_538561d74371e53c2f8df7f5ebdf58a8._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.149"
+ subject="comment 3"
+ date="2012-10-05T00:43:11Z"
+ content="""
+@Glen, for what it's worth, you can now manually \"git annex unlock\" a file and it'll stay unlocked until you manually \"git annex add\" the new version.
+"""]]
diff --git a/doc/design/assistant/desymlink/comment_4_586ecaa800e6c162377c937da5e65440._comment b/doc/design/assistant/desymlink/comment_4_586ecaa800e6c162377c937da5e65440._comment
new file mode 100644
index 000000000..aeb1587ed
--- /dev/null
+++ b/doc/design/assistant/desymlink/comment_4_586ecaa800e6c162377c937da5e65440._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlJEI45rGczFAnuM7gRSj4C6s9AS9yPZDc"
+ nickname="Kevin"
+ subject="unlock not behaving as you describe"
+ date="2012-11-05T22:35:35Z"
+ content="""
+@joeyh,
+
+I'm not seeing the behavior you describe re \"git annex unlock\" when using the assistant. After unlocking and writing the file, git annex assistant commits the changes and recreates the symlink from under me which is annoying.
+
+I'm running OS X 10.7.5 using the bundled git-annex.app version 3.20121017.
+"""]]
diff --git a/doc/design/assistant/desymlink/comment_5_8fc703de67814cf2aec2a908852298a4._comment b/doc/design/assistant/desymlink/comment_5_8fc703de67814cf2aec2a908852298a4._comment
new file mode 100644
index 000000000..ca4361532
--- /dev/null
+++ b/doc/design/assistant/desymlink/comment_5_8fc703de67814cf2aec2a908852298a4._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.27"
+ subject="comment 5"
+ date="2012-11-05T23:40:50Z"
+ content="""
+Well, you're able to unlock and modify the file -- that's what I fixed.
+
+Committing changes to files is what the assistant does..
+"""]]
diff --git a/doc/design/assistant/desymlink/comment_6_1b473ad89494afb82250af4b6df5f5c9._comment b/doc/design/assistant/desymlink/comment_6_1b473ad89494afb82250af4b6df5f5c9._comment
new file mode 100644
index 000000000..fad9cbe98
--- /dev/null
+++ b/doc/design/assistant/desymlink/comment_6_1b473ad89494afb82250af4b6df5f5c9._comment
@@ -0,0 +1,22 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="comment 6"
+ date="2012-12-03T05:33:44Z"
+ content="""
+> One approach for this would be to hide the git repo away somewhere, and have the git-annex assistant watch a regular directory, with regular files.
+
+I think this would be the single most important feature added to git-annex.
+1. It could be used to backup regularly a smb share over the network.
+2. For those who dont trust a program who modifies their files directly.
+(I had a 3GB permanent data loss, when trying to push a 10GB directory into git annex.)
+3. Android
+
+I do hope the above method will be implemented for Android too, so its like two birds with one stone.
+(Im really for option 2 here. I dont like the very idea of modifying my files directly.
+Git does not do it either, I have disk space (if not I buy more disks), rather then risquing losing important datas)
+
+Best,
+ Laszlo
+
+"""]]
diff --git a/doc/design/assistant/disaster_recovery.mdwn b/doc/design/assistant/disaster_recovery.mdwn
new file mode 100644
index 000000000..6fcf95519
--- /dev/null
+++ b/doc/design/assistant/disaster_recovery.mdwn
@@ -0,0 +1,185 @@
+The assistant should help the user recover their repository when things go
+wrong.
+
+[[!toc ]]
+
+## dangling lock files
+
+There are a few ways a git repository can get broken that are easily fixed.
+One is left over index.lck files. When a commit to a repository fails,
+check that nothing else is using it, fix the problem, and redo the commit.
+
+* **done** for .git/annex/index.lock, can be handled safely and automatically.
+* **done** for .git/index.lock, only when the assistant is starting up.
+* What about local remotes, eg removable drives? git-annex does attempt
+ to commit to the git-annex branch of those. It will use the automatic
+ fix if any are dangling. It does not commit to the master branch; indeed
+ a removable drive typically has a bare repository.
+ However, it does a scan for broken locks anyway if there's a problem
+ syncing. **done**
+* What about git-annex-shell? If the ssh remote has the assistant running,
+ it can take care of it, and if not, it's a server, and perhaps the user
+ should be required to fix up if it crashes during a commit. This should
+ not affect the assistant anyway.
+* **done** Seems that refs can also have stale lock files, for example
+ '/storage/emulated/legacy/DCIM/.git/refs/remotes/flick_phonecamera/synced/git-annex.lock'
+ All git lock files are now handled (except gc lock files).
+
+## incremental fsck
+
+Add webapp UI to enable incremental fsck **done**
+
+Of course, incremental fsck will run as an niced (and ioniced) background
+job. There will need to be a button in the webapp to stop it, in case it's
+annoying. **done**
+
+When fsck finds a damanged file, queue a download of the file from a
+remote. **done**
+
+Detect when a removable drive is connected in the Cronner, and check
+and try to run its remote fsck jobs. **done** (Same mechanism will work for
+network remotes becoming connected.)
+
+TODO: If no accessible remote has a file that fsck reported missing,
+prompt the user to eg, connect a drive containing it. Or perhaps this is a
+special case of a general problem, and the webapp should prompt the user
+when any desired file is available on a remote that's not mounted?
+
+## git-annex-shell remote fsck
+
+TODO: git-annex-shell fsck support, which would allow cheap fast fscks
+of ssh remotes.
+
+Would be nice; otherwise remote fsck is too expensive (downloads
+everything) to have the assistant do.
+
+Note that Remote.Git already tries to use this, but the assistant does not
+call it for non-local remotes.
+
+## git fsck and repair
+
+Add git fsck to scheduled self fsck **done**
+
+TODO: git fsck on ssh remotes? Probably not worth the complexity..
+
+TODO: If committing to the repository fails, after resolving any dangling
+lock files (see above), it should git fsck. This is difficult, because
+git commit will also fail if the commit turns out to be empty, or due to
+other transient problems.. So commit failures are currently ignored by the
+assistant.
+
+If git fsck finds problems, launch git repository repair. **done**
+
+git annex fsck --fast at end of repository repair to ensure
+git-annex branch is accurate. **done**
+
+If syncing with a local repository fails, try to repair it. **done**
+
+TODO: "Repair" gcrypt remotes, by removing all refs and objects,
+and re-pushing. (Since the objects are encrypted data, there is no way
+to pull missing ones from anywhere..)
+Need to preserve gcrypt-id while doing this!
+
+TODO: along with displaying alert when there is a problem detected
+by consistency check, send an email alert. (Using system MTA?)
+
+## nudge user to schedule fscks
+
+Make the webapp encourage users to schedule fscks of their
+local repositories. The goal here was that it should not be obnoxious about
+repeatedly pestering the user to set that up, but should still encourage
+anyone who cares to set it up.
+
+Maybe: Display a message only once per week, and only after the repository
+has existed for at least one full day. But, this will require storing
+quite a lot of state.
+
+Or: Display a message whenever a removable drive is detected to have been
+connected. I like this, but what about nudging the main repo? Could do it
+every webapp startup, perhaps? **done**
+
+There should be a "No thanks" button that prevents it nudging again for a
+repo. **done**
+
+## git repository repair
+
+There are several ways git repositories can get damanged.
+
+The most common is empty files in .git/annex/objects and commits that refer
+to those objects. When the objects have not yet been pushed anywhere.
+I've several times recovered from this manually by
+removing the bad files and resetting to before the commits that referred to
+them. Then re-staging any divergence in the working tree. This could
+perhaps be automated.
+
+As long as the git repository has at least one remote, another method is to
+clone the remote, sync from all other remotes, move over .git/config and
+.git/annex/objects, and tar up the old broken git repo and `git annex add`
+it. This should be automatable and get the user back on their feet. User
+could just click a button and have this be done.
+
+This is useful outside git-annex as well, so make it a
+git-recover-repository command.
+
+### detailed design
+
+Run `git fsck` and parse output to find bad objects. **done** Note that
+fsck may fall over and fail to print out all bad objects, when
+files are corrupt. So if the fsck exits nonzero, need to collect all
+bad objects it did find, and:
+
+1. If the local repository contains packs, the packs may be corrupt.
+ So, start by using `git unpack-objects` to unpack all
+ packs it can handle (which may include parts of corrupt packs)
+ back to loose objects. And delete all packs. **done**
+2. Delete all loose corrupt objects. **done**
+
+Repeat until fsck finds no new problems. **done**
+
+Check if there's a remote. If so, and if the bad objects are all
+present on it, can simply get all bad objects from the remote,
+and inject them back into .git/objects to recover:
+
+3. Make a new (bare) clone from the remote.
+ (Note: git does not seem to provide a way to fetch specific missing
+ objects from the remote. Also, cannot use `--reference` against
+ a repository with missing refs. So this seems unavoidably
+ network-expensive.) **done**
+5. Rsync objects over. (Turned out to work better than git-cat-file,
+ because we don't have to walk the graph to add missing objects.)
+ **done**
+6. If each bad object was able to be repaired this way, we're done!
+ (If not, can reuse the clone for getting objects from the next remote.)
+ **done**
+
+If some missing objects cannot be recovered from remotes, find commits in each
+local branch that are broken by all remaining missing objects. Some of this can
+be parsed from git fsck output, but for eg blobs, the commits need to
+be walked to walk the trees, to find trees that refer to the blobs. **done**
+
+For each branch that is affected, look in the reflog and/or `git log
+$branch` to find the last good commit that predates all broken commits. (If
+the head commit of a branch is broken, git log is not going to show
+anything useful, but the reflog can be used to find past refs for the
+branch -- have to first delete the .git/HEAD file if it points to the
+broken ref.) **done**
+
+The basic idea then is to reset the branch to the last good commit
+that was found for it.
+
+* For the HEAD branch, can just reset it. (If no last good commit was found
+ for the HEAD branch, reset it to a dummy empty commit.) This will
+ leave git showing any changes made since then as staged in the index and
+ uncommitted. Or if the index is missing/corrupt, any files in the tree will
+ show as modified and uncommitted. User (or git-annex assistant) can then
+ commit as appropriate. Print appropriate warning message. **done**
+* Special handling for git-annex branch and index. **done**
+* Remote tracking branches can just be removed, and then `git fetch`
+ from the remote, which will re-download missing objects from it and
+ reinstate the tracking branch. **done**
+* For other branches, reset them to last good commit, or delete
+ if none was found. **done**
+* (Decided not to touch tags.)
+
+The index file can still refer to objects that were missing.
+Rewrite to remove them. **done**
diff --git a/doc/design/assistant/disaster_recovery/comment_1_955dc807196863da23aa8dbd15e04364._comment b/doc/design/assistant/disaster_recovery/comment_1_955dc807196863da23aa8dbd15e04364._comment
new file mode 100644
index 000000000..63c7e942d
--- /dev/null
+++ b/doc/design/assistant/disaster_recovery/comment_1_955dc807196863da23aa8dbd15e04364._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://nullroute.eu.org/~grawity/"
+ nickname="Mantas"
+ subject="comment 1"
+ date="2013-10-19T15:50:47Z"
+ content="""
+The restriction on fetching over the Git protocol is, partly, for security reasons – e.g. if one accidentally pushes a commit with private data, and then `push --force`'s a cleaned-up version, Git needs to prevent anyone from downloading the old commit by just giving its SHA1 (e.g. obtained from an IRC/email push notification). So it restricts fetching to the tips of any ref. (I've been told that it could check if the given object is merely *reachable* from any ref, but it doesn't do so for performance reasons.)
+
+git 1.8 has a minor way to relax this requirement – it allows giving a SHA1 to `git fetch` (although I think the protocol already worked this way), and it allows refs to be hidden server-side but still remain fetchable, so in theory there could be a (hidden) ref for every object, for easy fetching...
+"""]]
diff --git a/doc/design/assistant/encrypted_git_remotes.mdwn b/doc/design/assistant/encrypted_git_remotes.mdwn
new file mode 100644
index 000000000..7d210a292
--- /dev/null
+++ b/doc/design/assistant/encrypted_git_remotes.mdwn
@@ -0,0 +1,22 @@
+Encrypted git remotes are now possible
+using [git-remote-gcrypt](https://github.com/joeyh/git-remote-gcrypt).
+
+There are at least two use cases for this in the assistant:
+
+* Storing an encrypted git repository on a local drive. **done**
+* Or on a remote server. This could even allow using github. But more
+ likely would be a shell server that has git-annex-shell on it so can
+ also store file contents, and which is not trusted with unencrypted data.
+ **done**
+
+git-remote-gcrypt is already usable with git-annex. What's needed is
+to make sure it's installed (ie, get it packaged into distros or embedded
+into git-annex), and make it easy to set up from the webapp. **done**
+
+Hmm, this will need gpg key creation, so would also be a good opportunity
+to make the webapp allow using that for special remotes too.
+
+One change is needed in git-annex core.. It currently does not support
+storing encrypted files on git remotes, only on special remotes. Perhaps
+the way to deal with this is to make it consider git-remote-grypt remotes
+to be a special remote type? **done**
diff --git a/doc/design/assistant/gpgkeys.mdwn b/doc/design/assistant/gpgkeys.mdwn
new file mode 100644
index 000000000..647d65083
--- /dev/null
+++ b/doc/design/assistant/gpgkeys.mdwn
@@ -0,0 +1,37 @@
+Currently the assistant sets up a shared encryption key, which is checked
+into git, so anyone who gets the repository can decrypt files that are
+stored encrypted on special remotes.
+
+To support using gpg keys in the assistant, we need some things:
+
+1. Help user set up a gpg key if they don't have one. This could be a
+ special-purpose key dedicated to being used by git-annex. It might be
+ nice to leave the user with a securely set up general purpose key,
+ but that would certainly preclude prompting for its password in the
+ webapp. Indeed, the password prompt is the main problem here.
+ Best solution would be to get gpg agent working on all supported
+ platforms.
+
+ Update: For now, git-annex only assists in generating gpg keys that are
+ intended to only be used to encrypt a repo.
+
+2. After generating a gpg key, back it up. It might be the only way
+ some data is accessible.
+
+ One way I'm considering is generating a QR code
+ of the key, which could be printed to paper. Preliminary results
+ are good; a 4096 bit secret key fits in a QR code (a secret key
+ with many subkeys may not). Debian has command-line utilities that
+ can generate and read such a QR code.
+
+3. Help user learn the gpg keys of people they want to share their repo
+ with, and give them access. If the public key was recorded in the git-annex
+ branch, this could be easily determined when sharing repositories with
+ friends. Or, use MonkeySphere, or Monkeysign..
+
+-----
+
+Another gpg key security thing is that currently git-annex stores
+crypto creds in memory while it's running. Should use locked memory. See
+<https://github.com/vincenthz/hs-securemem> and
+<https://github.com/vincenthz/hs-securemem/issues/1>
diff --git a/doc/design/assistant/inotify.mdwn b/doc/design/assistant/inotify.mdwn
new file mode 100644
index 000000000..d1afe63c5
--- /dev/null
+++ b/doc/design/assistant/inotify.mdwn
@@ -0,0 +1,196 @@
+"git annex watch" command, which runs, in the background, watching via
+inotify for changes, and automatically annexing new files, etc. Now
+available!
+
+[[!toc]]
+
+## known bugs
+
+* Kqueue has to open every directory it watches, so too many directories
+ will run it out of the max number of open files (typically 1024), and fail.
+ I may need to fork off multiple watcher processes to handle this.
+ See [[bug|bugs/Issue_on_OSX_with_some_system_limits]]. (Does not affect
+ OSX any longer, only other BSDs).
+
+## todo
+
+* There needs to be a way for a new version of git-annex, when installed,
+ to restart any running watch or assistant daemons. Or for the daemons
+ to somehow detect it's been upgraded and restart themselves. Needed
+ to allow for incompatable changes and, I suppose, for security upgrades..
+
+## beyond Linux
+
+I'd also like to support OSX and if possible the BSDs.
+
+* kqueue ([haskell bindings](http://hackage.haskell.org/package/kqueue))
+ is supported by FreeBSD, OSX, and other BSDs.
+
+ In kqueue, to watch for changes to a file, you have to have an open file
+ descriptor to the file. This wouldn't scale.
+
+ Apparently, a directory can be watched, and events are generated when
+ files are added/removed from it. You then have to scan to find which
+ files changed. [example](https://developer.apple.com/library/mac/#samplecode/FileNotification/Listings/Main_c.html#//apple_ref/doc/uid/DTS10003143-Main_c-DontLinkElementID_3)
+
+ Gamin does the best it can with just kqueue, supplimented by polling.
+ The source file `server/gam_kqueue.c` makes for interesting reading.
+ Using gamin to do the heavy lifting is one option.
+ ([haskell bindings](http://hackage.haskell.org/package/hlibfam) for FAM;
+ gamin shares the API)
+
+ kqueue does not seem to provide a way to tell when a file gets closed,
+ only when it's initially created. Poses problems..
+
+ * [man page](http://www.freebsd.org/cgi/man.cgi?query=kqueue&apropos=0&sektion=0&format=html)
+ * <https://github.com/gorakhargosh/watchdog/blob/master/src/watchdog/observers/kqueue.py> (good example program)
+
+ *kqueue is now supported*
+
+* hfsevents ([haskell bindings](http://hackage.haskell.org/package/hfsevents))
+ is OSX specific.
+
+ Originally it was only directory level, and you were only told a
+ directory had changed and not which file. Based on the haskell
+ binding's code, from OSX 10.7.0, file level events were added.
+
+ This will be harder for me to develop for, since I don't have access to
+ OSX machines..
+
+ hfsevents does not seem to provide a way to tell when a file gets closed,
+ only when it's initially created. Poses problems..
+
+ * <https://developer.apple.com/library/mac/#documentation/Darwin/Conceptual/FSEvents_ProgGuide/Introduction/Introduction.html>
+ * <http://pypi.python.org/pypi/MacFSEvents/0.2.8> (good example program)
+ * <https://github.com/gorakhargosh/watchdog/blob/master/src/watchdog/observers/fsevents.py> (good example program)
+
+* Windows has a Win32 ReadDirectoryChangesW, and perhaps other things.
+
+## the races
+
+Many races need to be dealt with by this code. Here are some of them.
+
+* File is added and then removed before the add event starts.
+
+ Not a problem; The add event does nothing since the file is not present.
+
+* File is added and then removed before the add event has finished
+ processing it.
+
+ **Minor problem**; When the add's processing of the file (checksum and so
+ on) fails due to it going away, there is an ugly error message, but
+ things are otherwise ok.
+
+* File is added and then replaced with another file before the annex add
+ moves its content into the annex.
+
+ Fixed this problem; Now it hard links the file to a temp directory and
+ operates on the hard link, which is also made unwritable.
+
+* File is added and then replaced with another file before the annex add
+ makes its symlink.
+
+ **Minor problem**; The annex add will fail creating its symlink since
+ the file exists. There is an ugly error message, but the second add
+ event will add the new file.
+
+* File is added and then replaced with another file before the annex add
+ stages the symlink in git.
+
+ Now fixed; `git annex watch` avoids running `git add` because of this
+ race. Instead, it stages symlinks directly into the index, without
+ looking at what's currently on disk.
+
+* Link is moved, fixed link is written by fix event, but then that is
+ removed by the user and replaced with a file before the event finishes.
+
+ Now fixed; same fix as previous race above.
+
+* File is removed and then re-added before the removal event starts.
+
+ Not a problem; The removal event does nothing since the file exists,
+ and the add event replaces it in git with the new one.
+
+* File is removed and then re-added before the removal event finishes.
+
+ Not a problem; The removal event removes the old file from the index, and
+ the add event adds the new one.
+
+* Symlink appears, but is then deleted before it can be processed.
+
+ Leads to an ugly message, otherwise no problem:
+
+ ./me: readSymbolicLink: does not exist (No such file or directory)
+
+ Here `me` is a file that was in a conflicted merge, which got
+ removed as part of the resolution. This is probably coming from the watcher
+ thread, which sees the newly added symlink (created by the git merge),
+ but finds it deleted (by the conflict resolver) by the time it processes it.
+
+## done
+
+- on startup, add any files that have appeared since last run **done**
+- on startup, fix the symlinks for any renamed links **done**
+- on startup, stage any files that have been deleted since last run
+ (seems to require a `git commit -a` on startup, or at least a
+ `git add --update`, which will notice deleted files) **done**
+- notice new files, and git annex add **done**
+- notice renamed files, auto-fix the symlink, and stage the new file location
+ **done**
+- handle cases where directories are moved outside the repo, and stop
+ watching them **done**
+- when a whole directory is deleted or moved, stage removal of its
+ contents from the index **done**
+- notice deleted files and stage the deletion
+ (tricky; there's a race with add since it replaces the file with a symlink..)
+ **done**
+- Gracefully handle when the default limit of 8192 inotified directories
+ is exceeded. This can be tuned by root, so help the user fix it.
+ **done**
+- periodically auto-commit staged changes (avoid autocommitting when
+ lots of changes are coming in) **done**
+- coleasce related add/rm events for speed and less disk IO **done**
+- don't annex `.gitignore` and `.gitattributes` files **done**
+- run as a daemon **done**
+- A process has a file open for write, another one closes it,
+ and so it's added. Then the first process modifies it.
+
+ Or, a process has a file open for write when `git annex watch` starts
+ up, it will be added to the annex. If the process later continues
+ writing, it will change content in the annex.
+
+ This changes content in the annex, and fsck will later catch
+ the inconsistency.
+
+ Possible fixes:
+
+ * Somehow track or detect if a file is open for write by any processes.
+ `lsof` could be used, although it would be a little slow.
+
+ Here's one way to avoid the slowdown: When a file is being added,
+ set it read-only, and hard-link it into a quarantine directory,
+ remembering both filenames.
+ Then use the batch change mode code to detect batch adds and bundle
+ them together.
+ Just before committing, lsof the quarantine directory. Any files in
+ it that are still open for write can just have their write bit turned
+ back on and be deleted from quarantine, to be handled when their writer
+ closes. Files that pass quarantine get added as usual. This avoids
+ repeated lsof calls slowing down adds, but does add a constant factor
+ overhead (0.25 seconds lsof call) before any add gets committed. **done**
+
+ * Or, when possible, making a copy on write copy before adding the file
+ would avoid this.
+ * Or, as a last resort, make an expensive copy of the file and add that.
+ * Tracking file opens and closes with inotify could tell if any other
+ processes have the file open. But there are problems.. It doesn't
+ seem to differentiate between files opened for read and for write.
+ And there would still be a race after the last close and before it's
+ injected into the annex, where it could be opened for write again.
+ Would need to detect that and undo the annex injection or something.
+
+- If a file is checked into git as a normal file and gets modified
+ (or merged, etc), it will be converted into an annexed file.
+ See [[blog/day_7__bugfixes]]. **done**; we always check ls-files now
+- When you `git annex unlock` a file, it will immediately be re-locked.
+ See [[bugs/watcher_commits_unlocked_files]]. Seems fixed now?
diff --git a/doc/design/assistant/inotify/comment_1_3d3ff74447452d65c10ccc3dbfc323cd._comment b/doc/design/assistant/inotify/comment_1_3d3ff74447452d65c10ccc3dbfc323cd._comment
new file mode 100644
index 000000000..d042806a1
--- /dev/null
+++ b/doc/design/assistant/inotify/comment_1_3d3ff74447452d65c10ccc3dbfc323cd._comment
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="http://ciffer.net/~svend/"
+ subject="comment 1"
+ date="2012-06-04T19:42:07Z"
+ content="""
+I would find it useful if the watch command could 'git add' new files (instead of 'git annex add') for certain repositories.
+"""]]
diff --git a/doc/design/assistant/inotify/comment_2_a3c0fa6d97397c508b4b8aafdcee8f6f._comment b/doc/design/assistant/inotify/comment_2_a3c0fa6d97397c508b4b8aafdcee8f6f._comment
new file mode 100644
index 000000000..13ee1523c
--- /dev/null
+++ b/doc/design/assistant/inotify/comment_2_a3c0fa6d97397c508b4b8aafdcee8f6f._comment
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ subject="comment 2"
+ date="2012-06-04T19:46:03Z"
+ content="""
+I think it's already on the list: \"configurable option to only annex files meeting certian size or filename criteria\" -- files not meeting those criteria would just be git added.
+"""]]
diff --git a/doc/design/assistant/inotify/comment_3_b346e870c1cd80e4b0a313c3a9fed6b3._comment b/doc/design/assistant/inotify/comment_3_b346e870c1cd80e4b0a313c3a9fed6b3._comment
new file mode 100644
index 000000000..c1f22c4b8
--- /dev/null
+++ b/doc/design/assistant/inotify/comment_3_b346e870c1cd80e4b0a313c3a9fed6b3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 3"
+ date="2012-06-17T08:52:32Z"
+ content="""
+In relation to OSX support, hfsevents (or supporting hfs is probably a bad idea), its very osx specific and users who are moving usb keys and disks between systems will probably end up using fat32/exfat/vfat disks around. Also if you want I can lower the turn around time for the OSX auto-builder that I have setup to every 1 or 2mins? would that help?
+"""]]
diff --git a/doc/design/assistant/inotify/comment_4_32be58b4c3b17a4ea539690d2fb45159._comment b/doc/design/assistant/inotify/comment_4_32be58b4c3b17a4ea539690d2fb45159._comment
new file mode 100644
index 000000000..d854d91c2
--- /dev/null
+++ b/doc/design/assistant/inotify/comment_4_32be58b4c3b17a4ea539690d2fb45159._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.2.147"
+ subject="comment 4"
+ date="2012-06-17T16:39:43Z"
+ content="""
+hfsevents seems usable, git-annex does not need to watch for file changes on remotes on other media.
+
+But, trying kqueue first.
+
+You could perhaps run the autobuilder on a per-commit basis..
+"""]]
diff --git a/doc/design/assistant/inotify/comment_5_0cdd3046d90ad2012025d846ece0731e._comment b/doc/design/assistant/inotify/comment_5_0cdd3046d90ad2012025d846ece0731e._comment
new file mode 100644
index 000000000..8b075c36f
--- /dev/null
+++ b/doc/design/assistant/inotify/comment_5_0cdd3046d90ad2012025d846ece0731e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 5"
+ date="2012-06-17T21:42:59Z"
+ content="""
+okay, I've gotten gitbuilder to poll the git repo every minute for changes, gitbuilder doesn't build every commit. It doesn't work like that, it checks out the master and builds that. If there is a failure it automatically bisects to find out where the problem first got introduced. Hope the change to the builder helps!
+"""]]
diff --git a/doc/design/assistant/inotify/comment_6_e197d5d0d853572ec1f2e5985762e60d._comment b/doc/design/assistant/inotify/comment_6_e197d5d0d853572ec1f2e5985762e60d._comment
new file mode 100644
index 000000000..76716ddda
--- /dev/null
+++ b/doc/design/assistant/inotify/comment_6_e197d5d0d853572ec1f2e5985762e60d._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnV2c63kDc6X21a1H81me1mIenUCScd2Gs"
+ nickname="Emanuele"
+ subject="watch branch?"
+ date="2012-06-01T19:19:17Z"
+ content="""
+Hello there? Where can I find more info about this git watch branch?
+Keep up the good work!
+"""]]
diff --git a/doc/design/assistant/leftovers.mdwn b/doc/design/assistant/leftovers.mdwn
new file mode 100644
index 000000000..b8c0f456b
--- /dev/null
+++ b/doc/design/assistant/leftovers.mdwn
@@ -0,0 +1,17 @@
+Things that don't fit anywhere else:
+
+* Automatically start daemon on boot or when user logs in, using
+ freedesktop autostart file. **done**
+* Somehow get content that is unavailable. This is problematic with inotify,
+ since we only get an event once the user has tried (and failed) to read
+ from the file. This is only needed if all the files in the directory
+ are not kept synced, but in some situations (ie, low disk space phones),
+ that is likely.
+* Drop files that have not been used lately, or meet some other criteria
+ (as long as there's a copy elsewhere). **done** (via preferred content;
+ eg archive directories)
+* Perhaps automatically dropunused files that have been deleted,
+ although I cannot see a way to do that, since by the time the inotify
+ deletion event arrives, the file is deleted, and we cannot see what
+ its symlink pointed to! Alternatively, perhaps automatically
+ do an expensive unused/dropunused cleanup process.
diff --git a/doc/design/assistant/leftovers/comment_1_b20c88bb3c583a32023c1f6b6dc9486d._comment b/doc/design/assistant/leftovers/comment_1_b20c88bb3c583a32023c1f6b6dc9486d._comment
new file mode 100644
index 000000000..3c7e1820d
--- /dev/null
+++ b/doc/design/assistant/leftovers/comment_1_b20c88bb3c583a32023c1f6b6dc9486d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 1"
+ date="2012-10-30T09:07:37Z"
+ content="""
+I think the automatic dropunused part is handled by the assistant already anyway, but in case it's not: The git repo still knows where the symlink pointed to so it should not be a problem to get that info from the last commit that was 'actively' locally and which contained said symlink.
+"""]]
diff --git a/doc/design/assistant/more_cloud_providers.mdwn b/doc/design/assistant/more_cloud_providers.mdwn
new file mode 100644
index 000000000..16e727657
--- /dev/null
+++ b/doc/design/assistant/more_cloud_providers.mdwn
@@ -0,0 +1,24 @@
+Git-annex already supports storing large files in
+several cloud providers via [[special_remotes]].
+More should be added, such as:
+
+* Google drive (attractive because it's free, only 5 gb tho)
+* Owncloud (has several [providers](http://owncloud.org/providers/);
+ at least one provides 5 gb free; open DAV based API)
+* OpenStack Swift (teh future)
+* Box.com (it's free, and current method is hard to set up and a sorta
+ shakey; a better method would be to use its API) **done**
+* Dropbox? That would be ironic.. Via its API, presumably.
+* [[Amazon Glacier|todo/special_remote_for_amazon_glacier]] **done**
+* Internet Archive **done**
+* [nimbus.io](https://nimbus.io/) Fairly low prices ($0.06/GB);
+ REST API; free software
+* Mediafire provides 50gb free and has a REST API.
+* Flickr provides 1 tb (!!!!) to free accounts, and can store at least
+ photos and videos. <https://github.com/ricardobeat/filr> is a hack
+ to allow storing any type of file on Flickr.
+* mega.co.nz. Already supported via [[tips/megaannex]], would just need
+ webapp modifications to configure it. May want to use megaannex as-is to
+ build a non-hook special remote in haskell.
+
+See poll at [[polls/prioritizing_special_remotes]].
diff --git a/doc/design/assistant/pairing.mdwn b/doc/design/assistant/pairing.mdwn
new file mode 100644
index 000000000..d09c644ee
--- /dev/null
+++ b/doc/design/assistant/pairing.mdwn
@@ -0,0 +1,83 @@
+For git-annex to be able to clone its repo to another host, it'd be good to
+have some way of pairing devices.
+
+## security
+
+Pairing uses its own network protocol, built on top of multicast UDP.
+
+It's important that pairing securely verifies that the right host is being
+paired with. This is accomplied by having a shared secret be entered on
+both the hosts that will be paired. Hopefully that secret is communicated
+securely out of band.
+
+(In practice, the security of that communication will vary. To guard against
+interception, each pairing session pairs exactly two hosts and then forgets
+the shared secret. So an attacker who tries to reuse an intercepted secret
+will not succeed in pairing. This does not guard against an intercepted
+secret that is used before the legitimate parties finish pairing.)
+
+Each host can construct messages that the other host can verify using the
+shared secret, and so know that, for example, the ssh public key it
+received belongs to the right host and has not been altered by a man in the
+middle.
+
+The verification works like this: Take a HMAC SHA1 checksum of the message,
+using the shared secret as the HMAC key. Include this checksum after the
+message. The other host can then do the same calculation and verify the
+checksum.
+
+Additionally, a UUID is included in the message. Messages that are part of
+the same pairing session all share a UUID. And all such messages should
+be verifiable as described above. If a message has the same UUID but is
+not verifiable, then someone on the network is up to no good. Perhaps
+they are trying to brute-force the shared secret. When this is detected,
+the pairing session is shut down. (Which would still let an attacker
+DOS pairing, but that's not a very interesting attack.)
+
+The protocol used for pairing consists of 3 messages, a PairReq, and
+PairAck, and a PairDone. Let's consider what an attacker could accomplish
+by replaying these:
+
+* PairReq: This would make the webapp pop up an alert about an incoming
+ pair request. If the user thought it was real and for some reason
+ entered the right shared secret used in the real one earlier, the
+ ssh key inside the PairReq would be added to `authorized_keys`. Which
+ allows the host that originally sent the PairReq to access its git
+ repository, but doesn't seem to do the attacker any good.
+* PairAck: If the host that originally sent
+ the PairReq is still pairing, it'll add the ssh key from the PairAck,
+ and start syncing, which again does the attacker no good.
+* PairDone: If the host that sent the PairAck is still syncing, it'll
+ add the ssh key from the PairDone, and start syncing, and stop
+ sending PairAcks. But probably, it's not syncing, because it would have
+ seen the original PairDone.. and anyway, this seems to do the attacker no
+ good.
+
+So replay attacks don't seem to be a problem.
+
+So far I've considered security from a third-party attacker, but either the
+first or second parties in pairing could also be attackers. Presumably they
+trust each other with access to their files as mediated by
+[[git-annex-shell]]. However, one could try to get shell access to the
+other's computer by sending malicious data in a pairing message. So the
+pairing code always checks every data field's content, for example the ssh
+public key is rejected if it looks at all unusual. Any control characters
+in the pairing message cause it to be rejected, to guard against console
+poisoning attacks. Furthermore, git-annex is careful not to expose data to
+the shell, and the webapp uses Yesod's type safety to ensure all user input
+is escaped before going to the browser.
+
+## TODO
+
+* pairing over IPV6 only networks does not work. Haskell's
+ `network-multicast` library complains "inet_addr: Malformed address: ff02::1"
+ .. seems it just doesn't support IPv6. The pairing code in git-annex
+ does support ipv6, apart from this, it's just broadcasting the messages
+ that fails. (Pairing over mixed networks is fine.)
+* If there are three assistants on the network, and 2 pair, the third is
+ left displaying a "Pair request from foo" alert, until it's close.
+ Or, if the user clicks the button to pair, it'll get to the
+ "Pairing in progress" alert, which will show forever (until canceled).
+
+ It should be possible for third parties to tell when pairing is done,
+ but it's actually rather hard since they don't necessarily share the secret.
diff --git a/doc/design/assistant/partial_content.mdwn b/doc/design/assistant/partial_content.mdwn
new file mode 100644
index 000000000..cbfbfcea8
--- /dev/null
+++ b/doc/design/assistant/partial_content.mdwn
@@ -0,0 +1,36 @@
+On a regular system, a reasonable simplifying assumption is that all the
+files in the folder will be synced to the system. A user might want to
+disable syncing of some subdirectories, for eg, archived files. But in
+general, things are simpler to understand and implement if all files sync.
+
+But, an Android gadget probably cannot hold all a user's files. Indeed,
+it's likely that old files will be aggressively dropped from the Android
+after syncing to elsewhere, in order to keep enough free space on it for
+new files.
+
+There needs to be a way for the user to browse files not on the gadget and
+request they be transferred to it. This could be done as a browser in the
+web app, or using a subdirectory full of placeholder files (not symlinks;
+see [[Android]]) that start transfer of the real file when accessed.
+
+----
+
+Currently, Android uses the "source" repository type in some
+configurations. This makes files be removed as soon as they are sent
+somewhere else.
+
+A compromise that avoids needing UI might be to change "source" so it
+retained files for a while after they were created, even after they were
+uploaded elsewhere. For example, it could hold onto them for a day. This
+would allow the user time to do things with new files before they are
+removed from the android device.
+
+One way to implement that would be a new preferred content expression like
+"age(1 day)". But this would need at least a daily full transfer scan to be
+run.
+
+Another way would be to have a way to make drops of files be deferred
+for a period of time. This approach would not need to be specific to the
+"source" repository type. And seems easy enough to do, just have a
+configuration setting for the time interval, and an ordered drop queue
+and a thread that waits as needed before dropping.
diff --git a/doc/design/assistant/partial_content/comment_1_58c4faa321a5bb71adf9fdee079849f4._comment b/doc/design/assistant/partial_content/comment_1_58c4faa321a5bb71adf9fdee079849f4._comment
new file mode 100644
index 000000000..aa65cd6b9
--- /dev/null
+++ b/doc/design/assistant/partial_content/comment_1_58c4faa321a5bb71adf9fdee079849f4._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkpEY8WTFDhjIVTWG38Ph7ppmuXUTJAHAg"
+ nickname="Justin"
+ subject="selective sync"
+ date="2012-07-28T04:08:00Z"
+ content="""
+hey joey
+
+great work!!
+
+will partial content work like selective sync in dropbox
+
+use case: on desktop i have photos/mp3s/docs, but would only want to sync the docs to my netbook
+
+cheers
+
+justin
+"""]]
diff --git a/doc/design/assistant/polls.mdwn b/doc/design/assistant/polls.mdwn
new file mode 100644
index 000000000..3457fd245
--- /dev/null
+++ b/doc/design/assistant/polls.mdwn
@@ -0,0 +1 @@
+[[!inline pages="(page(design/assistant/blog/*) and tagged(design/assistant/polls)) or page(design/assistant/polls/*)" show=0]]
diff --git a/doc/design/assistant/polls/2013_user_survey.mdwn b/doc/design/assistant/polls/2013_user_survey.mdwn
new file mode 100644
index 000000000..d1bac0ef8
--- /dev/null
+++ b/doc/design/assistant/polls/2013_user_survey.mdwn
@@ -0,0 +1 @@
+The 2013 git-annex user survey is in progress [[here|/polls/2013]].
diff --git a/doc/design/assistant/polls/Android.mdwn b/doc/design/assistant/polls/Android.mdwn
new file mode 100644
index 000000000..78806eac2
--- /dev/null
+++ b/doc/design/assistant/polls/Android.mdwn
@@ -0,0 +1,18 @@
+Help me choose a goal for the month of December. The last poll showed
+a lot of interest in using the git-annex assistant with phones, etc.
+
+Background: git-annex uses symbolic links in its repositories. This makes it
+hard to use with filesystems, such as FAT, that do not support symbolic links.
+FAT filesystems are the main storage available on some Android devices that
+have a micro-SD card. Other, newer Android devices don't have a SD card and so
+avoid this problem.
+
+I can either work on the idea described in
+[[design/assistant/desymlink]], which could solve the symlink problem and
+also could lead to a nicer workflow to editing files that are stored in
+git-annex.
+
+Or, I can work on [[Android_porting|design/assistant/android]], and try to
+get the assistant working on Android's built-in storage.
+
+[[!poll open=no 81 "solve the symlink problem first" 17 "port to Android first" 1 "other"]]
diff --git a/doc/design/assistant/polls/Android/comment_1_fa6c409833f28c67da105d25f4a440e0._comment b/doc/design/assistant/polls/Android/comment_1_fa6c409833f28c67da105d25f4a440e0._comment
new file mode 100644
index 000000000..49b779607
--- /dev/null
+++ b/doc/design/assistant/polls/Android/comment_1_fa6c409833f28c67da105d25f4a440e0._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn4yApngiiAJE5iX1MQ0VO_LXjLt4LgdHE"
+ nickname="Jim"
+ subject="No mass storage"
+ date="2012-12-02T03:33:06Z"
+ content="""
+I would have asked for better FAT support, but my Galaxy Nexus doesn't support mass storage mode, and MTP is not as easy to use nor reliably supported everywhere. So I'd lean towards functionality that stays on the phone as much as possible.
+"""]]
diff --git a/doc/design/assistant/polls/Android_default_directory.mdwn b/doc/design/assistant/polls/Android_default_directory.mdwn
new file mode 100644
index 000000000..5b18e36df
--- /dev/null
+++ b/doc/design/assistant/polls/Android_default_directory.mdwn
@@ -0,0 +1,7 @@
+What directory should the Android webapp default to creating an annex in?
+
+Same as the desktop webapp, users will be able to enter a directory they
+want the first time they run it, but to save typing on android, anything
+that gets enough votes will be included in a list of choices as well.
+
+[[!poll open=yes expandable=yes 62 "/sdcard/annex" 6 "Whole /sdcard" 5 "DCIM directory (photos and videos only)" 1 "Same as for regular git-annex. ~/annex/"]]
diff --git a/doc/design/assistant/polls/Android_default_directory/comment_1_d39655091ac3ed51a9d4325d86b23ad7._comment b/doc/design/assistant/polls/Android_default_directory/comment_1_d39655091ac3ed51a9d4325d86b23ad7._comment
new file mode 100644
index 000000000..30b73d184
--- /dev/null
+++ b/doc/design/assistant/polls/Android_default_directory/comment_1_d39655091ac3ed51a9d4325d86b23ad7._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 1"
+ date="2013-04-19T06:29:14Z"
+ content="""
+While my main use case is a photo repo, I don't think it's wise to default to there.
+
+Similarly, spamming what amounts to the root dir of \"external\" storage with repos seems like a bad idea.
+"""]]
diff --git a/doc/design/assistant/polls/Android_default_directory/comment_2_2f1eaae95075db26488517720afd1c63._comment b/doc/design/assistant/polls/Android_default_directory/comment_2_2f1eaae95075db26488517720afd1c63._comment
new file mode 100644
index 000000000..b2df3b0a2
--- /dev/null
+++ b/doc/design/assistant/polls/Android_default_directory/comment_2_2f1eaae95075db26488517720afd1c63._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnE6kFAbud1LWrQuyX76yMYnUjHt9tR-A8"
+ nickname="Leonardo"
+ subject="Direct mode"
+ date="2013-04-20T20:55:09Z"
+ content="""
+I think direct mode should be the default on Android
+"""]]
diff --git a/doc/design/assistant/polls/Android_default_directory/comment_3_b484012f60789be73d7d5b338cff6203._comment b/doc/design/assistant/polls/Android_default_directory/comment_3_b484012f60789be73d7d5b338cff6203._comment
new file mode 100644
index 000000000..7474d774d
--- /dev/null
+++ b/doc/design/assistant/polls/Android_default_directory/comment_3_b484012f60789be73d7d5b338cff6203._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-04-20T23:38:47Z"
+ content="""
+@Richard, including all of /sdcard seems a reasonable thing to do if you want to back it all up. I don't know how likely anyone would be to want to sync the whole contents though.
+
+@Leonardo direct mode is the default for all respositories created by the webapp, as well as all repositories on crippled filesystems that cannot support indirect mode. Android webapp thus defaults to direct mode twice over!
+"""]]
diff --git a/doc/design/assistant/polls/goals_for_April.mdwn b/doc/design/assistant/polls/goals_for_April.mdwn
new file mode 100644
index 000000000..53132dd44
--- /dev/null
+++ b/doc/design/assistant/polls/goals_for_April.mdwn
@@ -0,0 +1,17 @@
+What should I work on in April? I expect I could get perhaps two of these
+features done in a month if I'm lucky. I have only 3 more funded months,
+and parts of one will be spent working on porting to Windows, so choose wisely!
+--[[Joey]]
+
+[[!poll open=yes expandable=yes 4 "upload and download rate limiting" 15 "get webapp working on Android" 5 "deltas: speed up syncing modified versions of existing files" 8 "encrypted git remotes using git-remote-gcrypt" 0 "add support for more cloud storage remotes" 19 "don't work on features, work on making it easier to install and use" 2 "Handle duplicate files" 6 "direct mode (aka real files instead of symlinks) [already done --joey]" 3 "start windows port now"]]
+
+References:
+
+* [[rate_limiting]]
+* [[Android]]
+* [[deltas]] to speed up syncing modified files (at least for remotes using rsync)
+* [[encrypted_git_remotes]]
+* [[more_cloud_providers]] (OpenStack Swift, Owncloud, Google drive,
+ Dropbox, Mediafire, nimbus.io, Mega, etc.)
+* [[old poll on "what is preventing me from using git-annex assistant"|what_is_preventing_me_from_using_git-annex_assistant]]
+ (many of the items on it should be fixed now, but I have plenty of bug reports to chew on still)
diff --git a/doc/design/assistant/polls/goals_for_April/comment_1_9f81fa96db5970a4be0828c74a6d2d55._comment b/doc/design/assistant/polls/goals_for_April/comment_1_9f81fa96db5970a4be0828c74a6d2d55._comment
new file mode 100644
index 000000000..f63460543
--- /dev/null
+++ b/doc/design/assistant/polls/goals_for_April/comment_1_9f81fa96db5970a4be0828c74a6d2d55._comment
@@ -0,0 +1,22 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="Duplicate files"
+ date="2013-04-01T07:58:51Z"
+ content="""
+Having duplicate files is fairly easy.
+a) Just a backup of your files, to not have accidental deleting.
+
+b) Some programs implements UNDO command (Ctrl-Z) as simply copying over the working text file
+to a backup directory.
+
+c) If you tests precompiled programs, like git annex itself, it has identical files across releases.
+
+
+For more info about duplicate files, read hear these two bugreports:
+
+http://git-annex.branchable.com/bugs/When_syncing_two_repositories__44___git_annex_uses_9x_times_diskspace/
+(last comment)
+
+http://git-annex.branchable.com/bugs/Direct_mode_keeps_re-checksuming_duplicated_files/
+"""]]
diff --git a/doc/design/assistant/polls/goals_for_April/comment_2_d8956d220ccacff3d2f6cbeb15718459._comment b/doc/design/assistant/polls/goals_for_April/comment_2_d8956d220ccacff3d2f6cbeb15718459._comment
new file mode 100644
index 000000000..8fed65fb0
--- /dev/null
+++ b/doc/design/assistant/polls/goals_for_April/comment_2_d8956d220ccacff3d2f6cbeb15718459._comment
@@ -0,0 +1,28 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkWG4T4SGZxY-q4Wo8Jbxwb67g4J-WYmQM"
+ nickname="Mark"
+ subject="don't work on features option"
+ date="2013-04-01T14:03:35Z"
+ content="""
+The \"don't work on features...\" poll entry is a bit vague, so I figured stating my interpretation of it and why I choose it might be a good idea.
+I've had git-annex installed for the last few months during which it has been steadily improving, but IMO it still lacks polish.
+From time to time I see transient issues: (even on the current version)
+
+- random download stalling when I know the remote is accessible
+- files disappearing then reappearing without an obvious cause
+- xmmp hanging
+
+I do not have any means of replicating these issues (though IIRC some of the recently worked on bugs related to these issues).
+In my past experience this indicates that there are all sorts of 'fun' bugs hiding in the source which you seem to be chasing down.
+Heck, I could have a simple configuration error from when I set things up on my remote server.
+There was little documentation available when I setup my remote server for this and unless I have missed something in the RecentChanges feed, there still is relatively little.
+So, some issues with my xmmp daemon, local ssh keys via ssh-agent, or bad $PATH stuff could be causing things to subtlety malfunction at no fault of git-annex.
+
+Falling back to the command line only tends to be a good response, but outside of the assistant there does not seem to be any manual way to handle the special remotes.
+Fair enough, but it would seem logical for error handling to recognize that these are assistant only urls rather than some generic \"bad url\".
+Just getting the right error messages while a small touch would be a sign of some polish even though it is a nitpick.
+
+Perhaps some simple test code run repeatedly to form a stress test could reveal some odd behavior, but I'm not sure myself.
+
+With all of that said, I like what has been done so far and I'm hoping to see all the nooks of git-annex get the polishing that they deserve.
+"""]]
diff --git a/doc/design/assistant/polls/goals_for_April/comment_3_aadad6dfd56d068d2e377606910c006f._comment b/doc/design/assistant/polls/goals_for_April/comment_3_aadad6dfd56d068d2e377606910c006f._comment
new file mode 100644
index 000000000..f3cea47c8
--- /dev/null
+++ b/doc/design/assistant/polls/goals_for_April/comment_3_aadad6dfd56d068d2e377606910c006f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://adamspiers.myopenid.com/"
+ nickname="Adam"
+ subject="Ask for more money :-)"
+ date="2013-04-01T19:01:49Z"
+ content="""
+This is slightly off topic, but from my perspective this Kickstarter project has been a riotous success, and due to the credibility you have built up from 9 months of consistently high quality work produced in a very transparent and community-oriented fashion, I'd be surprised if you weren't able to raise more money to continue development after the 12 months is up. Assuming you want to of course :) Maybe you need a break or change of scene. But if not, it would be a shame not to continue if the userbase wants it.
+"""]]
diff --git a/doc/design/assistant/polls/prioritizing_special_remotes.mdwn b/doc/design/assistant/polls/prioritizing_special_remotes.mdwn
new file mode 100644
index 000000000..505c6e3a0
--- /dev/null
+++ b/doc/design/assistant/polls/prioritizing_special_remotes.mdwn
@@ -0,0 +1,16 @@
+Background: git-annex supports storing data in various [[special remotes]].
+The git-annex assistant will make it easy to configure these, and easy
+configurators have already been built for a few: removable drives, rsync.net,
+locally paired systems, and remote servers with rsync.
+
+Help me prioritize my work: What special remote would you most like
+to use with the git-annex assistant?
+
+[[!poll open=yes 16 "Amazon S3 (done)" 12 "Amazon Glacier (done)" 9 "Box.com (done)" 71 "My phone (or MP3 player)" 23 "Tahoe-LAFS" 10 "OpenStack SWIFT" 31 "Google Drive"]]
+
+This poll is ordered with the options I consider easiest to build
+listed first. Mostly because git-annex already supports them and they
+only need an easy configurator. The ones at the bottom are likely to need
+significant work. See [[cloud]] for detailed discussion.
+
+Have another idea? Absolutely need two or more? Post comments..
diff --git a/doc/design/assistant/polls/prioritizing_special_remotes/comment_1_dd9280df27848a7ff132f5809dab0a79._comment b/doc/design/assistant/polls/prioritizing_special_remotes/comment_1_dd9280df27848a7ff132f5809dab0a79._comment
new file mode 100644
index 000000000..0214d4a12
--- /dev/null
+++ b/doc/design/assistant/polls/prioritizing_special_remotes/comment_1_dd9280df27848a7ff132f5809dab0a79._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 1"
+ date="2012-09-13T08:39:59Z"
+ content="""
+I've been looking at ceph for various reasons in work, it supports a swift interface as well as it's own restful api. so +1 for swift (and any s3 compatible api).
+"""]]
diff --git a/doc/design/assistant/polls/prioritizing_special_remotes/comment_2_370e0b9c43486ee96c825f9155eebde4._comment b/doc/design/assistant/polls/prioritizing_special_remotes/comment_2_370e0b9c43486ee96c825f9155eebde4._comment
new file mode 100644
index 000000000..4d00922a4
--- /dev/null
+++ b/doc/design/assistant/polls/prioritizing_special_remotes/comment_2_370e0b9c43486ee96c825f9155eebde4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 2"
+ date="2012-09-13T09:07:02Z"
+ content="""
+Swift has its own API but offers a S3 compatibility layer. Last I tried that layer, it did not work.
+"""]]
diff --git a/doc/design/assistant/polls/prioritizing_special_remotes/comment_3_883a003b9c552b89f191135c582f99aa._comment b/doc/design/assistant/polls/prioritizing_special_remotes/comment_3_883a003b9c552b89f191135c582f99aa._comment
new file mode 100644
index 000000000..83844cd35
--- /dev/null
+++ b/doc/design/assistant/polls/prioritizing_special_remotes/comment_3_883a003b9c552b89f191135c582f99aa._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmsz4weoPXV2oEtv3zpo9dOxn_SEPz-7Iw"
+ nickname="Zooko"
+ subject="reasons to like Tahoe-LAFS as a special remote"
+ date="2012-10-12T18:17:42Z"
+ content="""
+Here are a couple of things which are (I think) unique about the Tahoe-LAFS special remote:
+
+1. encryption ; All of the data is encrypted before leaving your local system and heading for the server (or for the clouds). This is true even though you don't (I think) have to enter an encryption key into git-annex to access your data.
+
+(Note: the above implies that you're in danger of permanently losing access to your data, by losing the last copy of the encryption key, if your local git-annex state is lost. This deserves careful consideration.)
+
+2. erasure-coding ; You can configure Tahoe-LAFS to spread the data out in a RAID-like way across multiple remote storage servers, where each server holds only, say, 1/3 of the data, but there are, say, 10 different servers, where any 3 of them are sufficient to give you full access to your data. Does that make sense it uses less bandwidth and storage space than replication (i.e. putting a complete replica of your data on each of 4 or 5 or 10 different storage servers), but it is more robust than sharding (i.e. putting 1/3 of your data on each of three different servers so that if any one of them goes down you lose 1/3 of your data).
+"""]]
diff --git a/doc/design/assistant/polls/prioritizing_special_remotes/comment_4_746006c3fffc7f917c4526fd688051f7._comment b/doc/design/assistant/polls/prioritizing_special_remotes/comment_4_746006c3fffc7f917c4526fd688051f7._comment
new file mode 100644
index 000000000..713d1d7b5
--- /dev/null
+++ b/doc/design/assistant/polls/prioritizing_special_remotes/comment_4_746006c3fffc7f917c4526fd688051f7._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnjrMQEhzd8xI81V9BL2jsKlNgVJLD7PKs"
+ nickname="Pankaj"
+ subject="Google Music as remote?"
+ date="2012-10-31T06:07:32Z"
+ content="""
+A dropbox like folder which syncs with Google Music. Google Music allows uploading upto 20K songs. Also using git-annex , I can ensure that I dont need to store all the duplicate mp3 on my local drive. Only one copy of \"older music\" is \"arvhived\" on GMusic, whereas more recent songs are on my local drive.
+"""]]
diff --git a/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant.mdwn b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant.mdwn
new file mode 100644
index 000000000..4b4778c1f
--- /dev/null
+++ b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant.mdwn
@@ -0,0 +1,16 @@
+My goal for this month is to get more people using the git-annex assistant,
+and fix issues that might be blocking you from using it. To do this,
+I'd like to get an idea about whether you're already using it,
+or what's keeping you from using it.
+
+If you use `git-annex` at the command line and have no reason to use the
+assistant, please instead fill in this poll on behalf of less technically
+adept friends or family -- what's preventing you from introducing them to
+the assistant?
+
+[[!poll open=no expandable=yes 8 "I'm using the assistant!" 28 "I need a Windows port" 30 "I need an Android port" 3 "I need an IPhone port (not holding my breath)" 2 "Well, it's still in beta..." 11 "I want to, but have not had the time to try it" 5 "Just inertia. I've got this dropbox/whatever that already works.." 3 "It's too hard to install (please say why in comments)" 2 "Perceived recent increase of bug reports and thus sitting it out." 25 "Initially the lack of direct-mode. Now concerns about the safety of direct mode. Perhaps after the next release." 10 "I haven't always well understood the differences between commandline operation & the assistant, so the differences would confuse me, and I found the command line more understandable & less scary. Now trying to learn to like & trust the assistant. :)" 21 "An Ubuntu PPA would be supercool! Thanks for your great work!!" 18 "Not yet in Debian sid amd64" 6 "Waiting for Fedora/CentOS rpm repository." 2 "throttling transfers, it upsets people when I saturate the connection" 2 "partial content" 1 "Not yet available in macports" 4 "No build yet for Nokia N9" 3 "Using only git-annex webapp to config does not seem to work: Create walkthough?" 5 "No build for OSX 10.6" 5 "Needs more focus on the UI." 1 "Just inertia. I don't have a Dropbox/whatever." 4 "Replaces files with a symlink mess." 2 "configurable option to only annex files meeting certian size or filename criteria" 4 "I'm really confused about how to make it sync with a remote NON-bare repository. I'm even afraid to try `git remote add`, since there is no clear method to completely forget a git-annex remote..." 5 "A build for te raspberry pi would be supercol!" 1 "Would be nice to exclude subfolders from the gui or through a config file" 1 "I wish I had transparently encrypted git repos in the cloud available, like jgit." 1 "too many inodes used in direct mode. maybe it's possible to keep more info as git objects instead?" 2 "I need to be able to restrict in which repo dirs changes get auto-committed" 1 "Provide .deb package" 1 "Better documentation/walkthroughs on using git-annex within an existing git repo. AKA mixed use" 1 "Union mounts to have a single view of file collection on the network" 1 "Ubuntu PPA does not build with webapp" 1 "I set it up, but am confused about what I set up! It would be great to be able to start from scratch." 1 "I need to be able to restrict in which repo dirs changes get auto-committed using a syntax similar to gitignore"]]
+
+Feel free to write in your own reasons, or add a comment to give me more info.
+
+Note: Poll is now closed. Nearly all these issues have been dealt with.
+Please file bug reports if any of these issues still affect you.
diff --git a/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_10_10a4839a05be39ced54ffbe880a588bb._comment b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_10_10a4839a05be39ced54ffbe880a588bb._comment
new file mode 100644
index 000000000..b501be3b8
--- /dev/null
+++ b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_10_10a4839a05be39ced54ffbe880a588bb._comment
@@ -0,0 +1,25 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="comment 10"
+ date="2013-01-11T21:57:29Z"
+ content="""
+@joey: My usecase is fairly simple.
+I have a working directory where I do work
+(not programing, but text editing with homecooked spreadsheet/texteditor).
+
+I work/type on spot/on site. So I'm walking while typing.
+
+Its easy to do stupid things while you work,
+so would be really handy to have a backup automagically on the same computer to prevent mistakes, user errors.
+(The last mistake, I did is I copied all my daily files into a \"tmp\" directory,
+then I launched my homebrew program which also created a tmp dir then deleted the whole content of it.
+I fixed it, but my datas was lost. It is a simple user mistake which could be prevented if I would have a
+live backup all the time. Creating a git repo for daily typing is just too much overhead.
+It is like you create a git repo for your text messages...)
+
+So my usecase is a live backup. Or the broken file deleting thing on unix/linux since forever.
+
+Laszlo
+
+"""]]
diff --git a/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_11_ac91d866f11c66dd8c86e2cd1a368c85._comment b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_11_ac91d866f11c66dd8c86e2cd1a368c85._comment
new file mode 100644
index 000000000..1657d11ad
--- /dev/null
+++ b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_11_ac91d866f11c66dd8c86e2cd1a368c85._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 11"
+ date="2013-01-11T22:17:07Z"
+ content="""
+@dzsino: You may want to have a look at [metamonger](https://github.com/RichiH/metamonger) which tries to solve exactly this problem. It's not finished yet, though.
+
+-- Richard
+"""]]
diff --git a/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_12_e244c1bf334b1cc9ad0cc760bf8fe5de._comment b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_12_e244c1bf334b1cc9ad0cc760bf8fe5de._comment
new file mode 100644
index 000000000..fc2b03bac
--- /dev/null
+++ b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_12_e244c1bf334b1cc9ad0cc760bf8fe5de._comment
@@ -0,0 +1,29 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkx5V3MTbzCXS3J7Mn9FEq8M9bPPYMkAHY"
+ nickname="Pedro"
+ subject="It fails silently and leaves symlinks behind"
+ date="2013-01-11T23:49:51Z"
+ content="""
+I dedicated a day to looking into using the assistant and although it's clearly an exciting piece of software it's still pretty hard to get working. To get two machines to sync with one another the options seem to be:
+
+1. Connect both of them to a XMPP server: That makes metadata sync flawlessly and yet leaves a symlink mess behind. As it turns out that's because XMPP syncs only metadata but nowhere was that stated on the webapp (that I could find) and no error message given
+2. So then I tried the sync method with SSH.
+
+For that you'll need to:
+
+* Have SSH servers installed on both endpoints (for me that was easy to do but I'm sure most users will have a harder time)
+* Make sure both computers are actually on the same broadcast network otherwise they won't see each other (I was testing with a VM behind virtualbox's NAT so initially it didn't work)
+* Install the assistant on both sides and make sure both the base program and the shell wrapper are in the PATH. (this was harder to do than needed as in the standalone bundle they're not on the same folder and the shell wrapper needs to be run by the runshell script, so even if you get it in the path it will still fail with missing libraries. An Ubuntu PPA would have solved this I'm sure.
+
+For some reason I couldn't figure out they still couldn't sync and symlink mess ensued.
+
+I think there are a few usability issues here:
+
+1. Direct mode should never overwrite files in a way you can no longer use them just because metadata updates came before content updates. I'd rather have an older version of the file than lose access to it.
+2. Error reporting needs to be a lot more explicit to be able to debug these issues
+3. At the best of times SSH sync is going to be a problem. In my opinion to be really dropbox-like the sync method for normal users should be to connect all devices to the same XMPP account (this works great now) and then have those assistants automatically reach each other by a direct connection when possible and by something like STUN if NAT punching is needed. The SSH/bup/etc remotes all have their place for advanced setups but being able to tell the user to just connect to XMPP and be done would turn this from \"something I'll spend an afternoon writing puppet manifests to deploy in my personal servers/computers\" to \"something I can explain to a non-technical friend how to use over a phone call and then share files with him\".
+
+On the XMPP side though, it would work best if you could authenticate a Google XMPP acount through an OAuth workflow instead of asking for the password. I wouldn't give any program my gmail password but I'd easily give it permission to use gtalk on my behalf.
+
+As I started by saying the assistant (and git-annex in general) is an extremely impressive piece of software that I'm very excited about. I hope it keeps improving at the current pace as there are still a few features I'd love to have (partial content particularly) but by far the thing that's keeping me most from using it is the ability to easily get a reliable sync going that won't leave me with a folder full of symlinks that I don't know what to do about. One of the great things about dropbox is that whenever it isn't running or can't sync for any reason your folder degenerates into a folder like any other on your disk. The right way of thinking about direct mode should be that one, \"a folder like any other that we stream changes from and to on multiple machines\". Right now, with the symlink replacement when sync isn't possible and to a lesser extent the adding of .git folders it doesn't live up to that guarantee.
+"""]]
diff --git a/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_13_1a0faf4bdc78741937e8a2f5cb5bbec6._comment b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_13_1a0faf4bdc78741937e8a2f5cb5bbec6._comment
new file mode 100644
index 000000000..066859b32
--- /dev/null
+++ b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_13_1a0faf4bdc78741937e8a2f5cb5bbec6._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="comment 13"
+ date="2013-01-12T08:16:48Z"
+ content="""
+@Pedro: That is an excellent test, and usecase!
+
+Indeed, the gui needs a lot more info on it.
+Also file integratity is a real fear with this kind of application.
+
+"""]]
diff --git a/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_14_8d8a11dbfae7a7bc574bdf37f87e0684._comment b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_14_8d8a11dbfae7a7bc574bdf37f87e0684._comment
new file mode 100644
index 000000000..1ecaff59f
--- /dev/null
+++ b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_14_8d8a11dbfae7a7bc574bdf37f87e0684._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://launchpad.net/~rubiojr"
+ nickname="rubiojr"
+ subject="git-annex PPA"
+ date="2013-01-15T14:16:35Z"
+ content="""
+Hey Joey,
+
+I do maintain a PPA with a more up2date version in fact:
+
+https://launchpad.net/~rubiojr/+archive/git-annex
+
+Now that the direct mode is in place, I guess it's probably a good time to backport again.
+
+Thanks for such a great piece of software.
+"""]]
diff --git a/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_15_c437adeaccf0b3d134e0f81c64e25b9f._comment b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_15_c437adeaccf0b3d134e0f81c64e25b9f._comment
new file mode 100644
index 000000000..e6e4af37e
--- /dev/null
+++ b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_15_c437adeaccf0b3d134e0f81c64e25b9f._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://launchpad.net/~rubiojr"
+ nickname="rubiojr"
+ subject="direct mode still 'untrusted'?"
+ date="2013-01-15T14:23:22Z"
+ content="""
+BTW,
+
+Does this still apply?
+
+\"I'd like git annex direct to set the repository to untrusted, but I didn't do it. Partly because having git annex indirect set it back to semitrusted seems possibly wrong -- the user might not trust a repo even in indirect mode. Or might fully trust it. The docs will encourage users to set direct mode repos to untrusted -- in direct mode you're operating without large swathes of git-annex's carefully constructed safety net. (When the assistant later uses direct mode, it'll untrust the repository automatically.)\"
+
+http://git-annex.branchable.com/design/assistant/blog/day_151__direct_mode_toggle/
+"""]]
diff --git a/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_16_6e3fce3a32ab346dc3d0fd4b69967536._comment b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_16_6e3fce3a32ab346dc3d0fd4b69967536._comment
new file mode 100644
index 000000000..afda489a1
--- /dev/null
+++ b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_16_6e3fce3a32ab346dc3d0fd4b69967536._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://adamspiers.myopenid.com/"
+ nickname="Adam"
+ subject="just one thing"
+ date="2013-01-16T01:45:54Z"
+ content="""
+http://git-annex.branchable.com/todo/wishlist:_disable_automatic_commits/ is the only thing I'm waiting for. Will become a very keen beta-tester (maybe even coder) when that happens.
+"""]]
diff --git a/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_17_1b7233d88593d0d99b26ea3e7af20d9c._comment b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_17_1b7233d88593d0d99b26ea3e7af20d9c._comment
new file mode 100644
index 000000000..278181ad5
--- /dev/null
+++ b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_17_1b7233d88593d0d99b26ea3e7af20d9c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.238"
+ subject="comment 17"
+ date="2013-01-16T19:38:36Z"
+ content="""
+@rubiojr I recommend configuring direct mode repos as untrusted if you care about accessing old versions of your files as stored in git. If that is not a concern, direct mode is safe, it's just that it allows editing/deleting any file at any time, even if that's the only copy of the file.
+"""]]
diff --git a/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_18_a23d5a0e2718b8e486f036fe8a413b36._comment b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_18_a23d5a0e2718b8e486f036fe8a413b36._comment
new file mode 100644
index 000000000..5f82d7ebb
--- /dev/null
+++ b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_18_a23d5a0e2718b8e486f036fe8a413b36._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://christian.amsuess.com/chrysn"
+ nickname="chrysn"
+ subject="comment 18"
+ date="2013-01-17T12:04:34Z"
+ content="""
+the \"I haven't always well understood the differences between commandline operation & the assistant, so the differences would confuse me, and I found the command line more understandable & less scary. Now trying to learn to like & trust the assistant.\" fits pretty well for me -- i'd like to use the webapp at least for viewing, but i'm worried that some auto-magic would kick in, and i regularly have uncommitted stuff in at least one git-annex repo.
+
+a --dry-run flag or similar on the `git annex webapp` would be nice, or a description of what would happen or how to turn that off / make it create other branches / even commit or push something.
+"""]]
diff --git a/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_19_f4c84a9d701d52cf2f2e45f3d764a90c._comment b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_19_f4c84a9d701d52cf2f2e45f3d764a90c._comment
new file mode 100644
index 000000000..35def9374
--- /dev/null
+++ b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_19_f4c84a9d701d52cf2f2e45f3d764a90c._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnmvVKc1ECzZx7EhtLHBP6RWPZewq4x_9I"
+ nickname="Daniele"
+ subject="Windows + git ignore like syntax for files to sync"
+ date="2013-04-19T10:47:36Z"
+ content="""
+Hi,
+
+my company would need this for some project.
+
+But to adopt it I would need:
+* windows support (I don't care if now symlink support for now)
+* being able to define which files are automatically synced using a syntax similar to the gitignore one
+* being able to disable auto-commit (just synching, user should be able to commit on their own)
+
+thanks
+
+"""]]
diff --git a/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_1_00a0de8190d946caaeeca3b44646146f._comment b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_1_00a0de8190d946caaeeca3b44646146f._comment
new file mode 100644
index 000000000..4bebe748d
--- /dev/null
+++ b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_1_00a0de8190d946caaeeca3b44646146f._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="Two reasons"
+ date="2013-01-10T18:00:05Z"
+ content="""
+As of right now, the assistant has only secondary benefit over plain git-annex inasmuch there's a lot more code activity.
+
+As soon as the assistant supports Android, I will use for syncing photos off of my phone and may start to use the assistant on my usual repos as a natural consequence.
+
+Additionally, there's a subjective feeling of more bugs being reported. That may or may not be true, but as long as there's no Android port, I don't have an actual reason to \"risk\" it.
+
+-- Richard
+
+PS: This seems to be the first poll where you can place only one vote while it's the first where I really wanted to vote on two separate items.
+"""]]
diff --git a/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_20_199c9807499470771af6cbca6d034cfa._comment b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_20_199c9807499470771af6cbca6d034cfa._comment
new file mode 100644
index 000000000..51e1bc4ea
--- /dev/null
+++ b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_20_199c9807499470771af6cbca6d034cfa._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 20"
+ date="2013-04-19T18:01:44Z"
+ content="""
+You can turn off automatic commits in the webapp by pausing syncing for the local repository.
+"""]]
diff --git a/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_2_35f6f121e54260cb960211a6e2e51e8e._comment b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_2_35f6f121e54260cb960211a6e2e51e8e._comment
new file mode 100644
index 000000000..bf52b9c1c
--- /dev/null
+++ b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_2_35f6f121e54260cb960211a6e2e51e8e._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawniCRkhl_W87gOK5eElfsef3FoUsUFpAr4"
+ nickname="Alexandre"
+ subject="Two assistants with shared transfer repository"
+ date="2013-01-11T07:17:12Z"
+ content="""
+I voted for the Windows port, which unfortunately I must use at work.
+
+But another thing that Dropbox gets right is that you can [sync two clients with one shared repository](http://git-annex.branchable.com/forum/How_to_set_up_two_assistants_with_one_shared_transfer_repository__63__) that works without any configuration whether you are home or somewhere else. This use case is covered by sync over XMPP, but there are two small issues with this :
+- if I use Google XMPP servers to sync two assistants in the same network, everything goes through the slower Internet link
+- if I setup my own XMPP server, well, this is more setup, more open ports, etc.
+
+It would be nice to have repository pushs on a shared repository notified to the connected clients in the SSH connection.
+"""]]
diff --git a/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_3_acbe4f63b5d552ac5ae5a12c6f42dc18._comment b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_3_acbe4f63b5d552ac5ae5a12c6f42dc18._comment
new file mode 100644
index 000000000..0d971c29c
--- /dev/null
+++ b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_3_acbe4f63b5d552ac5ae5a12c6f42dc18._comment
@@ -0,0 +1,25 @@
+[[!comment format=mdwn
+ username="http://a-or-b.myopenid.com/"
+ ip="220.244.41.108"
+ subject="comment 3"
+ date="2013-01-11T09:32:33Z"
+ content="""
+I've got a few wishes for git-annex… Referring to the poll options:
+
+- I need an Android port
+
+I think this is the biggest issue for getting a high WAF. (I want to put our photos in an annex, and getting them auto-magically off her phone would get me massive brownie points.)
+
+- Initially the lack of direct-mode. Now concerns about the safety of direct mode. Perhaps after the next release.
+
+The \"potentially unsafe\" sort of comments in the blog make me worry about trusting my data to the direct mode. Saying that I *really* appreciate the honesty of the comments. That is why I want to keep using, and recommend to others, git-annex.
+
+- I haven't always well understood the differences between commandline operation & the assistant, so the differences would confuse me, and I found the command line more understandable & less scary. Now trying to learn to like & trust the assistant.
+
+I also have worried about the automatic adding by the assistant - prior to direct mode.
+
+- throttling transfers, it upsets people when I saturate the connection
+
+I think a bittorrent option would be ideal. Not public torrents, but torrents between my annexes.
+
+"""]]
diff --git a/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_4_0d988280865caae498a3b693b6342e37._comment b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_4_0d988280865caae498a3b693b6342e37._comment
new file mode 100644
index 000000000..b66cd12f7
--- /dev/null
+++ b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_4_0d988280865caae498a3b693b6342e37._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="Two local repositories"
+ date="2013-01-11T10:31:54Z"
+ content="""
+Here is my usecase:
+I want two local (direct mode) repositories. So basically a working directory and a backup directory to the working one.
+
+The removable media repository *almost* fulfill this usecase, except you can only select drive and not a directory.
+I think it would be relatively simple to implement. (A drive is a directory under linux after all).
+
+Best,
+ Laszlo
+
+"""]]
diff --git a/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_5_ac8fe3768c30dd7999c183500f8567bb._comment b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_5_ac8fe3768c30dd7999c183500f8567bb._comment
new file mode 100644
index 000000000..713e8ef7d
--- /dev/null
+++ b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_5_ac8fe3768c30dd7999c183500f8567bb._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="marvin"
+ ip="91.154.225.32"
+ subject="SSH keys"
+ date="2013-01-11T12:02:50Z"
+ content="""
+Really looking forward to seeing this project go forward and impressed by what you have accomplished.
+
+I have my own server which I want to use as a repository, so I'll choose \"Remote server\". I want to use direct mode.
+Now I can only create an encrypted remote which is fine for me, but I don't know how to sync that with another client using this remote.
+
+Also with the generated ssh keys I no longer can log into my server normally as it tries to use the generated keys.
+The generated keys should also be restricted to only be able to change the repository and nothing else.
+
+Maybe webdav could be used to create something with better access control and repositories for groups etc.
+Also with a simple web upload/download page, similar to dropbox.
+
+Sorry if my post is long and idiotic, just simple (hopefully constructive) feedback from a simple user :)
+"""]]
diff --git a/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_6_36832de705a2bebf8dc6e65dcd661731._comment b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_6_36832de705a2bebf8dc6e65dcd661731._comment
new file mode 100644
index 000000000..525a325f0
--- /dev/null
+++ b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_6_36832de705a2bebf8dc6e65dcd661731._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 6"
+ date="2013-01-11T15:06:47Z"
+ content="""
+Laszlo's concern about \"you can only select a drive and not a directory\" relates to a problem I had.
+
+I have two local directories, ~/annex indirect my main annex, and ~/directannex for playing with direct mode.
+
+I had hoped to back each up to the same shared drive, but didn't realize there was no option to select a directory within a shared drive, so when I tried to do that through the assistant I inadvertently connected the two by backing them up to the same directory on the shared drive!
+
+This is probably a \"power user problem\" which has a \"power user solution\" of setting up the separate repository manually. But it did take me by surprise.
+
+"""]]
diff --git a/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_7_3618067e473577a112e36970ca71e0ab._comment b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_7_3618067e473577a112e36970ca71e0ab._comment
new file mode 100644
index 000000000..bfb1b949c
--- /dev/null
+++ b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_7_3618067e473577a112e36970ca71e0ab._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://dzsino.myopenid.com/"
+ nickname="dzsino"
+ subject="Recording file creation dates?"
+ date="2013-01-11T16:35:27Z"
+ content="""
+I've just started using git annex, command line feels safer for the time being. One issue I've got with assistant that I had to kill it couple of times when it got confused over something (could be that I used command line git annex at the same time?), shutdown from the UI is welcome.
+
+More of a git annex issue for me that I lost file creation dates for annexed files, which i don't really mind for most of my content, except really old photos without proper EXIF tags.
+I think of git annex as more of a DVR for my digital life, rather than a mere sync tool, so I would welcome some basic metadata facility. Would you consider adding this?
+(Really getting carried away, I would want to full text search on file names, ID3 tags, document metadata and text etc. and requesting files based on search hits, spotlight style..)
+"""]]
diff --git a/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_8_07a13b6f000ddc0ac4472b863d8b50bd._comment b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_8_07a13b6f000ddc0ac4472b863d8b50bd._comment
new file mode 100644
index 000000000..8bbd57b5d
--- /dev/null
+++ b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_8_07a13b6f000ddc0ac4472b863d8b50bd._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.238"
+ subject="comment 8"
+ date="2013-01-11T20:02:39Z"
+ content="""
+@Alexandre, what you want can be achieved by setting up XMPP pairing, and also [[local pairing|assistant/local_pairing_walkthrough]]. Then when computers are on the same network, transfers are done via the LAN.
+
+@Laszlo, this can be set up without using the webapp. Just make the two repositories, using the webapp. Then go into each and run \"git remote add myotherrepo $path_to_other_repo\". Then assistant will automatically sync them. I *have* thought about adding a configurator for this to the webapp. It would help to know what use cases you're getting at with this.
+
+@marvin The generated ssh keys are configured to only allow running `git-annex-shell`, which limits it to only acting on the repository. The keys are also configured, in `.ssh/config` to only be used when a particular host alias is used. They should not be used when you just ssh normally to the host. If this is happening to you, please file a bug report with details.
+
+@dzsino you can get file creation dates out of git using git log :)
+"""]]
diff --git a/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_9_e15eb407d988fda363296c8b566cc8fb._comment b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_9_e15eb407d988fda363296c8b566cc8fb._comment
new file mode 100644
index 000000000..f7dd3eb88
--- /dev/null
+++ b/doc/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/comment_9_e15eb407d988fda363296c8b566cc8fb._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkQafKy7hNSEolLs6TvbgUnkklTctUY9LI"
+ nickname="Zellyn"
+ subject="Question about git-annex"
+ date="2013-01-11T21:05:55Z"
+ content="""
+Not sure where the correct place to ask this is...
+
+My use case for git-annex is to back up important files (pictures, videos, etc.) on a hard disk at work and one at home. Is there an easy way to do that? I'd like to be able to get git-annex to fill up my phone/laptop with files that it thinks are backed up in <2 of the locations, and ferry them back and forth. They can be deleted to free up space after that, if necessary.
+
+Thanks for all your work, by the way. I missed the kickstarter, but if there's a simple and direct way to donate (dwolla?, gittip?), I'd love to chip in.
+"""]]
diff --git a/doc/design/assistant/progressbars.mdwn b/doc/design/assistant/progressbars.mdwn
new file mode 100644
index 000000000..50f424508
--- /dev/null
+++ b/doc/design/assistant/progressbars.mdwn
@@ -0,0 +1,43 @@
+Currently, git-annex takes a very lazy approch to displaying
+progress into. It just lets rsync or whatever display the progress
+for it, in the terminal.
+
+Something better is needed for the [[webapp]]. There needs to be a
+way for the web app to know what the current progress is of all transfers.
+
+This is one of those potentially hidden but time consuming problems.
+
+## downloads
+
+* Watch temp file as it's coming in and use its size.
+ Can either poll every .5 seconds or so to check file size, or
+ could use inotify. **done**
+* When easily available, remotes call the MeterUpdate callback as downloads
+ progress. **done**
+* S3 TODO
+ While it has a download progress bar, `getObject` probably buffers the whole
+ download in memory before returning. Leaving the progress bar to only
+ display progress for writing the file out of memory. Fixing this would
+ involve making hS3 stream better (also avoids it wasting memory).
+
+## uploads
+
+Each individual remote type needs to implement its own support for calling
+the MeterUpdate callback as the upload progresses.
+
+* git: **done**
+* rsync: **done**
+* directory: **done**
+* web: Not applicable; does not upload
+* webdav: **done**
+* S3: **done**
+* glacier: **done**
+* bup: TODO
+* hook: Would require the hook interface to somehow do this, which seems
+ too complicated. So skipping.
+
+## communication
+
+It may be worth using a better communication channel than files on disk for
+the transfer progress. Shared memory could be used, or http posts to the
+webapp.
diff --git a/doc/design/assistant/progressbars/comment_1_3ea263b1f334e8e38e14f00a96202988._comment b/doc/design/assistant/progressbars/comment_1_3ea263b1f334e8e38e14f00a96202988._comment
new file mode 100644
index 000000000..4a011f61b
--- /dev/null
+++ b/doc/design/assistant/progressbars/comment_1_3ea263b1f334e8e38e14f00a96202988._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://abhidg.myopenid.com/"
+ ip="129.67.132.87"
+ subject="librsync"
+ date="2012-06-13T02:14:29Z"
+ content="""
+There's librsync which might support reporting the progress through its API, but it seems to be in beta.
+"""]]
diff --git a/doc/design/assistant/rate_limiting.mdwn b/doc/design/assistant/rate_limiting.mdwn
new file mode 100644
index 000000000..3ab804329
--- /dev/null
+++ b/doc/design/assistant/rate_limiting.mdwn
@@ -0,0 +1,57 @@
+Webapp needs a simple speed control knob, especially to avoid saturating
+bandwidth on uploads.
+
+We have basic throttling support in git-annex for rsync,
+but none for any special remotes. A good first step would be to expose
+this in the webapp, and ensure that `git-annex-shell` also honors it when
+sending/receiving data.
+
+We actually need two speed controls, one for upload and one for download.
+
+It is probably not necessary to throttle git push/pull operations, as the
+data transfers tend to be small. Only throttling file transfers is
+essential.
+
+## possibility: trickle
+
+Since `git-annex transferkeys` is a separate process, one easy option would
+be to run it inside `trickle`. If the user changes the bandwidth limits,
+it could kill the transfer and restart it with different trickle options.
+
+Problem: Not all special remotes support resuming transfers, so this is
+suboptimal. (So too are the pause/resume buttons, when using those
+remotes!)
+
+`trickle` is available for OSX as well as Linux and BSDs.
+<http://hints.macworld.com/comment.php?mode=view&cid=65362>
+<http://mac.softpedia.com/get/Network-Admin/Trickle.shtml>
+It is probably not easily available for Android, as it uses `LD_PRELOAD`.
+
+## possibility: built in IO limiting
+
+A cleaner method would be to do the limiting inside git-annex. We already
+have metered file IO. It should be possible to make the meter not only report
+on the transfer speed, but detect when it's going too fast, and delay. This
+will delay the file streaming through the special remote's transfer code,
+so should work for a variety of special remotes. (Not for rsync or bup
+or git-annex-shell though, so those need to be handled separately.)
+
+Should work well for uploads at least. I don't know how well it would work
+for throttling downloads; the sender may just keep sending data and the
+data buffer before it gets to the IO meter. Maybe once the buffers fill the
+OS would have the TCP throttled down. Needs investigation; trickle claims
+to throttle downloads.
+
+## communications channels
+
+There would need to be a communication channel for the assistant to tell
+`git annex transferkeys` when the rate limit has changed. It could for
+example send it a SIGUSR1, and then leave it up to the process to reload
+the git config. Inside the IO meter, we could have an MVar that contains
+the current throttle value, so the IO meter could check it each time it's
+called and adjust its throttling appropriately.
+
+Ideally, the assistant could also communicate in the same way with
+`git-annex-shell` to tell it when the limit has changed. Since
+`git-annex-shell` uses rsync, it would need to abort the transfer, and rely
+on the other side retrying to start it up with the new limit.
diff --git a/doc/design/assistant/screenshot/firstrun.png b/doc/design/assistant/screenshot/firstrun.png
new file mode 100644
index 000000000..7e9d505b4
--- /dev/null
+++ b/doc/design/assistant/screenshot/firstrun.png
Binary files differ
diff --git a/doc/design/assistant/screenshot/intro.png b/doc/design/assistant/screenshot/intro.png
new file mode 100644
index 000000000..23ed49d67
--- /dev/null
+++ b/doc/design/assistant/screenshot/intro.png
Binary files differ
diff --git a/doc/design/assistant/sshpassword.mdwn b/doc/design/assistant/sshpassword.mdwn
new file mode 100644
index 000000000..e38769867
--- /dev/null
+++ b/doc/design/assistant/sshpassword.mdwn
@@ -0,0 +1,12 @@
+Currently the assistant sets up dedicated ssh keys, that can just use
+git-annex. This is ok. The problem is that the initial 2 connections to the
+ssh server when setting up these keys involve a password prompt, which is
+done at the console unless the system happens to have a working ssh agent
+that can pop up a dialog. That can be confusing.
+
+It would be nice to have the webapp prompt for the password. Can it be done
+securely?
+
+This might come down to a simple change to the webapp to prompt for the
+password, and then rather a lot of pain to make the webapp use HTTPS so we
+can be pretty sure noone is sniffing the (localhost) connection.
diff --git a/doc/design/assistant/syncing.mdwn b/doc/design/assistant/syncing.mdwn
new file mode 100644
index 000000000..5b2a11aa6
--- /dev/null
+++ b/doc/design/assistant/syncing.mdwn
@@ -0,0 +1,260 @@
+Once files are added (or removed or moved), need to send those changes to
+all the other git clones, at both the git level and the key/value level.
+
+## efficiency
+
+Currently after each file transfer (upload or download), a git sync is done
+to all remotes. This is rather a lot of work, also it prevents collecting
+presence changes to the git-annex branch into larger commits, which would
+save disk space over time.
+
+In many cases, this sync is necessary. For example, when a file is uploaded
+to a transfer remote, the location change needs to be synced out so that
+other clients know to grab it.
+
+Or, when downloading a file from a drive, the sync lets other locally
+paired repositories know we got it, so they can download it from us.
+OTOH, this is also a case where a sync is sometimes unnecessary, since
+if we're going to upload the file to them after getting it, the sync
+only perhaps lets them start downloading it before our transfer queue
+reaches a point where we'd upload it.
+
+Do we need all the mapping stuff discussed below to know when we can avoid
+syncs?
+
+## TODO
+
+* Test MountWatcher on LXDE.
+* Add a hook, so when there's a change to sync, a program can be run
+ and do its own signaling.
+* --debug will show often unnecessary work being done. Optimise.
+* Configurablity, including only enabling git syncing but not data transfer;
+ only uploading new files but not downloading, and only downloading
+ files in some directories and not others. See for use cases:
+ [[forum/Wishlist:_options_for_syncing_meta-data_and_data]]
+* speed up git syncing by using the cached ssh connection for it too
+ Will need to use `GIT_SSH`, which needs to point to a command to run,
+ not a shell command line. Beware that the network connection may have
+ bounced and the cached ssh connection not be usable.
+* Map the network of git repos, and use that map to calculate
+ optimal transfers to keep the data in sync. Currently a naive flood fill
+ is done instead. Maybe use XMPP as a side channel to learn about the
+ network topology?
+* Find a more efficient way for the TransferScanner to find the transfers
+ that need to be done to sync with a remote. Currently it walks the git
+ working copy and checks each file. That probably needs to be done once,
+ but further calls to the TransferScanner could eg, look at the delta
+ between the last scan and the current one in the git-annex branch.
+* [[use multiple transfer slots|todo/Slow_transfer_for_a_lot_of_small_files.]]
+* The TransferQueue's list of deferred downloads could theoretically
+ grow without bounds in memory. Limit it to a given number of entries,
+ and fall back to some other method -- either storing deferred downloads
+ on disk, or perhaps scheduling a TransferScanner run to get back into sync.
+
+## data syncing
+
+There are two parts to data syncing. First, map the network and second,
+decide what to sync when.
+
+Mapping the network can reuse code in `git annex map`. Once the map is
+built, we want to find paths through the network that reach all nodes
+eventually, with the least cost. This is a minimum spanning tree problem,
+except with a directed graph, so really a Arborescence problem.
+
+With the map, we can determine which nodes to push new content to. Then we
+need to control those data transfers, sending to the cheapest nodes first,
+and with appropriate rate limiting and control facilities.
+
+This probably will need lots of refinements to get working well.
+
+### first pass: flood syncing
+
+Before mapping the network, the best we can do is flood all files out to every
+reachable remote. This is worth doing first, since it's the simplest way to
+get the basic functionality of the assistant to work. And we'll need this
+anyway.
+
+## TransferScanner
+
+The TransferScanner thread needs to find keys that need to be Uploaded
+to a remote, or Downloaded from it.
+
+How to find the keys to transfer? I'd like to avoid potentially
+expensive traversals of the whole git working copy if I can.
+(Currently, the TransferScanner does do the naive and possibly expensive
+scan of the git working copy.)
+
+One way would be to do a git diff between the (unmerged) git-annex branches
+of the git repo, and its remote. Parse that for lines that add a key to
+either, and queue transfers. That should work fairly efficiently when the
+remote is a git repository. Indeed, git-annex already does such a diff
+when it's doing a union merge of data into the git-annex branch. It
+might even be possible to have the union merge and scan use the same
+git diff data.
+
+But that approach has several problems:
+
+1. The list of keys it would generate wouldn't have associated git
+ filenames, so the UI couldn't show the user what files were being
+ transferred.
+2. Worse, without filenames, any later features to exclude
+ files/directories from being transferred wouldn't work.
+3. Looking at a git diff of the git-annex branches would find keys
+ that were added to either side while the two repos were disconnected.
+ But if the two repos' keys were not fully in sync before they
+ disconnected (which is quite possible; transfers could be incomplete),
+ the diff would not show those older out of sync keys.
+
+The remote could also be a special remote. In this case, I have to either
+traverse the git working copy, or perhaps traverse the whole git-annex
+branch (which would have the same problems with filesnames not being
+available).
+
+If a traversal is done, should check all remotes, not just
+one. Probably worth handling the case where a remote is connected
+while in the middle of such a scan, so part of the scan needs to be
+redone to check it.
+
+## done
+
+1. Can use `git annex sync`, which already handles bidirectional syncing.
+ When a change is committed, launch the part of `git annex sync` that pushes
+ out changes. **done**; changes are pushed out to all remotes in parallel
+1. Watch `.git/refs/remotes/` for changes (which would be pushed in from
+ another node via `git annex sync`), and run the part of `git annex sync`
+ that merges in received changes, and follow it by the part that pushes out
+ changes (sending them to any other remotes).
+ [The watching can be done with the existing inotify code! This avoids needing
+ any special mechanism to notify a remote that it's been synced to.]
+ **done**
+1. Periodically retry pushes that failed. **done** (every half an hour)
+1. Also, detect if a push failed due to not being up-to-date, pull,
+ and repush. **done**
+2. Use a git merge driver that adds both conflicting files,
+ so conflicts never break a sync. **done**
+
+* on-disk transfers in progress information files (read/write/enumerate)
+ **done**
+* locking for the files, so redundant transfer races can be detected,
+ and failed transfers noticed **done**
+* transfer info for git-annex-shell **done**
+* update files as transfers proceed. See [[progressbars]]
+ (updating for downloads is easy; for uploads is hard)
+* add Transfer queue TChan **done**
+* add TransferInfo Map to DaemonStatus for tracking transfers in progress.
+ **done**
+* Poll transfer in progress info files for changes (use inotify again!
+ wow! hammer, meet nail..), and update the TransferInfo Map **done**
+* enqueue Transfers (Uploads) as new files are added to the annex by
+ Watcher. **done**
+* enqueue Tranferrs (Downloads) as new dangling symlinks are noticed by
+ Watcher. **done**
+ (Note: Needs git-annex branch to be merged before the tree is merged,
+ so it knows where to download from. Checked and this is the case.)
+* Write basic Transfer handling thread. Multiple such threads need to be
+ able to be run at once. Each will need its own independant copy of the
+ Annex state monad. **done**
+* Write transfer control thread, which decides when to launch transfers.
+ **done**
+* Transfer watching has a race on kqueue systems, which makes finished
+ fast transfers not be noticed by the TransferWatcher. Which in turn
+ prevents the transfer slot being freed and any further transfers
+ from happening. So, this approach is too fragile to rely on for
+ maintaining the TransferSlots. Instead, need [[todo/assistant_threaded_runtime]],
+ which would allow running something for sure when a transfer thread
+ finishes. **done**
+* Test MountWatcher on KDE, and add whatever dbus events KDE emits when
+ drives are mounted. **done**
+* It would be nice if, when a USB drive is connected,
+ syncing starts automatically. Use dbus on Linux? **done**
+* Optimisations in 5c3e14649ee7c404f86a1b82b648d896762cbbc2 temporarily
+ broke content syncing in some situations, which need to be added back.
+ **done**
+
+ Now syncing a disconnected remote only starts a transfer scan if the
+ remote's git-annex branch has diverged, which indicates it probably has
+ new files. But that leaves open the cases where the local repo has
+ new files; and where the two repos git branches are in sync, but the
+ content transfers are lagging behind; and where the transfer scan has
+ never been run.
+
+ Need to track locally whether we're believed to be in sync with a remote.
+ This includes:
+ * All local content has been transferred to it successfully.
+ * The remote has been scanned once for data to transfer from it, and all
+ transfers initiated by that scan succeeded.
+
+ Note the complication that, if it's initiated a transfer, our queued
+ transfer will be thrown out as unnecessary. But if its transfer then
+ fails, that needs to be noticed.
+
+ If we're going to track failed transfers, we could just set a flag,
+ and use that flag later to initiate a new transfer scan. We need a flag
+ in any case, to ensure that a transfer scan is run for each new remote.
+ The flag could be `.git/annex/transfer/scanned/uuid`.
+
+ But, if failed transfers are tracked, we could also record them, in
+ order to retry them later, without the scan. I'm thinking about a
+ directory like `.git/annex/transfer/failed/{upload,download}/uuid/`,
+ which failed transfer log files could be moved to.
+* A remote may lose content it had before, so when requeuing
+ a failed download, check the location log to see if the remote still has
+ the content, and if not, queue a download from elsewhere. (And, a remote
+ may get content we were uploading from elsewhere, so check the location
+ log when queuing a failed Upload too.) **done**
+* Fix MountWatcher to notice umounts and remounts of drives. **done**
+* Run transfer scan on startup. **done**
+* Often several remotes will be queued for full TransferScanner scans,
+ and the scan does the same thing for each .. so it would be better to
+ combine them into one scan in such a case. **done**
+* The syncing code currently doesn't run for special remotes. While
+ transfering the git info about special remotes could be a complication,
+ if we assume that's synced between existing git remotes, it should be
+ possible for them to do file transfers to/from special remotes.
+ **done**
+
+* The transfer code doesn't always manage to transfer file contents.
+
+ Besides reconnection events, there are two places where transfers get queued:
+
+ 1. When the committer commits a file, it queues uploads.
+ 2. When the watcher sees a broken symlink be created, it queues downloads.
+
+ Consider a doubly-linked chain of three repositories, A B and C.
+ (C and A do not directly communicate.)
+
+ * File is added to A.
+ * A uploads its content to B.
+ * At the same time, A git syncs to B.
+ * Once B gets the git sync, it git syncs to C.
+ * When C's watcher sees the file appear, it tries to download it. But if
+ B had not finished receiving the file from A, C doesn't know B has it,
+ and cannot download it from anywhere.
+
+ Possible solution: After B receives content, it could queue uploads of it
+ to all remotes that it doesn't know have it yet, which would include C.
+ **done**
+
+ In practice, this had the problem that when C receives the content,
+ it will queue uploads of it, which can send back to B (or to some other repo
+ that already has the content) and loop, until the git-annex branches catch
+ up and break the cycle.
+
+ To avoid that problem, incoming uploads should not result in a transfer
+ info file being written when the key is already present. **done**
+
+ Possible solution: C could record a deferred download. (Similar to a failed
+ download, but with an unknown source.) When C next receives a git-annex
+ branch push, it could try to queue deferred downloads. **done**
+
+ Note that this solution won't cover use cases the other does. For example,
+ connect a USB drive A; B syncs files from it, and then should pass them to C.
+ If the files are not new, C won't immediatly request them from B.
+
+* Running the assistant in a fresh clone of a repository, it sometimes
+ skips downloading a file, while successfully downloading all the rest.
+ There does not seem to be an error message. This will sometimes reproduce
+ (in a fresh clone each time) several times in a row, but then stops happening,
+ which has prevented me from debugging it.
+ This could possibly have been caused by the bug fixed in 750c4ac6c282d14d19f79e0711f858367da145e4.
+ Provisionally closed.
diff --git a/doc/design/assistant/syncing/comment_1_c70156174ff19b503978d623bd2df36f._comment b/doc/design/assistant/syncing/comment_1_c70156174ff19b503978d623bd2df36f._comment
new file mode 100644
index 000000000..019490e61
--- /dev/null
+++ b/doc/design/assistant/syncing/comment_1_c70156174ff19b503978d623bd2df36f._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawk4YX0PWICfWGRLuncCPufMPDctT7KAYJA"
+ nickname="betabrain"
+ subject="selective data syncing"
+ date="2012-07-24T15:27:08Z"
+ content="""
+How will the assistant know which files' data to distribute between the repos?
+
+I'm using git-annex and it's numcopies attribute to maintain a redundant archive spread over different computers and usb drives. Not all drives should get a copy of everything, e.g. the usb drive I take to work should not automatically get a copy of family pictures.
+
+How about .gitattributes?
+
+* \* annex.auto-sync-data = false # don't automatically sync the data
+* archive/ annex.auto-push-repos = NAS # everything added to archive/ in any repo goes automatically to the NAS remote.
+* work/ annex.auto-synced-repos = LAPTOP WORKUSB # everything added to work/ in LAPTOP or WORKUSB gets synced to WORKUSB and LAPTOP
+* work/ annex.auto-push-repos = LAPTOP WORKUSB # stuff added to work/ anywhere gets synced to LAPTOP and WORKUSB
+* important/ annex.auto-sync-data = true # push data to all repos
+* webserver_logs/ annex.remote.WEBSERVER.auto-push-repos = S3 # only the assistant running in WEBSERVER pushes webserver_logs/ to S3 remote
+"""]]
diff --git a/doc/design/assistant/syncing/comment_2_eb992b5b2c7a5ce23443e2a6007e5ff9._comment b/doc/design/assistant/syncing/comment_2_eb992b5b2c7a5ce23443e2a6007e5ff9._comment
new file mode 100644
index 000000000..a4609d7e1
--- /dev/null
+++ b/doc/design/assistant/syncing/comment_2_eb992b5b2c7a5ce23443e2a6007e5ff9._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnBl7cA6wLDxVNUyLIHvAyCkf8ir3alYpk"
+ nickname="Tyson"
+ subject="Bridging LANs"
+ date="2012-07-10T10:20:59Z"
+ content="""
+Why rely on the cloud when you can instead use XMPP and jingle to perform NAT traversal for you? AFAIKT, it also means that traffic won't leave your router if the two endpoints are behind the same router.
+"""]]
diff --git a/doc/design/assistant/syncing/comment_3_e1b5e8a24556de16d1cacd27ee0c1bd1._comment b/doc/design/assistant/syncing/comment_3_e1b5e8a24556de16d1cacd27ee0c1bd1._comment
new file mode 100644
index 000000000..c9118595c
--- /dev/null
+++ b/doc/design/assistant/syncing/comment_3_e1b5e8a24556de16d1cacd27ee0c1bd1._comment
@@ -0,0 +1,80 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 1"
+ date="2012-07-03T08:26:43Z"
+ content="""
+On \"git syncing\" point number 9, on OSX you could potentially do this on a semi-regular basis
+
+<pre>
+system_profiler SPNetworkVolumeDataType
+Volumes:
+
+ net:
+
+ Type: autofs
+ Mount Point: /net
+ Mounted From: map -hosts
+ Automounted: Yes
+
+ home:
+
+ Type: autofs
+ Mount Point: /home
+ Mounted From: map auto_home
+ Automounted: Yes
+</pre>
+
+and
+
+<pre>
+x00:~ jtang$ system_profiler SPUSBDataType
+USB:
+
+ USB High-Speed Bus:
+
+ Host Controller Location: Built-in USB
+ Host Controller Driver: AppleUSBEHCI
+ PCI Device ID: 0x0aa9
+ PCI Revision ID: 0x00b1
+ PCI Vendor ID: 0x10de
+ Bus Number: 0x26
+
+ Hub:
+
+ Product ID: 0x2504
+ Vendor ID: 0x0424 (SMSC)
+ Version: 0.01
+ Speed: Up to 480 Mb/sec
+ Location ID: 0x26200000 / 3
+ Current Available (mA): 500
+ Current Required (mA): 2
+
+ USB to ATA/ATAPI Bridge:
+
+ Capacity: 750.16 GB (750,156,374,016 bytes)
+ Removable Media: Yes
+ Detachable Drive: Yes
+ BSD Name: disk1
+ Product ID: 0x2338
+ Vendor ID: 0x152d (JMicron Technology Corp.)
+ Version: 1.00
+ Serial Number: 313541813001
+ Speed: Up to 480 Mb/sec
+ Manufacturer: JMicron
+ Location ID: 0x26240000 / 5
+ Current Available (mA): 500
+ Current Required (mA): 2
+ Partition Map Type: MBR (Master Boot Record)
+ S.M.A.R.T. status: Not Supported
+ Volumes:
+ Porta-Disk:
+ Capacity: 750.16 GB (750,156,341,760 bytes)
+ Available: 668.42 GB (668,424,208,384 bytes)
+ Writable: Yes
+ File System: ExFAT
+....
+</pre>
+
+I think its possible to programatically get this information either from the CLI (it dumps out XML output if required) or some development library. There is also DBUS in macports, but I have never had much interaction with it, so I don't know if its good or bad on OSX.
+"""]]
diff --git a/doc/design/assistant/thanks/comment_1_8b08b5c30e5aea3fc4599f856fd25df5._comment b/doc/design/assistant/thanks/comment_1_8b08b5c30e5aea3fc4599f856fd25df5._comment
new file mode 100644
index 000000000..77a0873ee
--- /dev/null
+++ b/doc/design/assistant/thanks/comment_1_8b08b5c30e5aea3fc4599f856fd25df5._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlUbH3eytydcwlWqv8oauE2Jg4NwcV9uA0"
+ nickname="Anna"
+ subject="Special"
+ date="2012-07-20T23:45:15Z"
+ content="""
+I feel pretty special getting an individualized thank you! Btw, the good news is that your video finally explained what you were working on so that I understood it. :-)
+"""]]
diff --git a/doc/design/assistant/todo.mdwn b/doc/design/assistant/todo.mdwn
new file mode 100644
index 000000000..2b369a2e2
--- /dev/null
+++ b/doc/design/assistant/todo.mdwn
@@ -0,0 +1,4 @@
+This is a subset of [[/todo]] and [[/bugs]]
+for items tagged for the assistant.
+
+[[!inline pages="tagged(design/assistant) and !link(bugs/done) and !link(bugs/moreinfo)" show=0 archive=yes]]
diff --git a/doc/design/assistant/transfer_control.mdwn b/doc/design/assistant/transfer_control.mdwn
new file mode 100644
index 000000000..b0a14ed2b
--- /dev/null
+++ b/doc/design/assistant/transfer_control.mdwn
@@ -0,0 +1,123 @@
+Some remotes are too small to sync everything to them.
+
+The case of a small remote on a gadget that the user interacts with,
+such as a phone, where they may want to request it get content
+it doesn't currently have, is covered by the [[partial_content]] page.
+
+But often the remote is just a removable drive or a cloud remote,
+that has a limited size. This page is about making the assistant do
+something smart with such remotes.
+
+## TODO
+
+* The expensive scan currently makes one pass, dropping content at the same
+ time more uploads and downloads are queued. It would be better to drop as
+ much content as possible upfront, to keep the total annex size as small
+ as possible. How to do that without making two expensive scans?
+* The TransferWatcher's finishedTransfer function relies on the location
+ log having been updated after a transfer. But there's a race; if the
+ log is not updated in time, it will fail to drop unwanted content.
+ (There's a 10 second sleep there now to avoid the race, but that's hardly
+ a fix.)
+
+### dropping no longer preferred content
+
+When a file is renamed, it might stop being preferred, so
+could be checked and dropped. (If there's multiple links to
+the same content, this gets tricky. Let's assume there are not.)
+
+### analysis of changes that can result in content no longer being preferred
+
+1. The preferred content expression can change, or a new repo is added, or
+ groups change. Generally, some change to global annex state. Only way to deal
+ with this is an expensive scan. (The rest of the items below come from
+ analizing the terminals used in preferred content expressions.) **done**
+2. renaming of a file (ie, moved to `archive/`) **done**
+ (note also that renaming a file can also make it become preferred content
+ again, and should cause it to be transferred in that case) **done**
+3. we get a file (`in`, `copies`) **done**
+4. we sent a file (`in`, `copies`) **done**
+5. some other repository drops the file (`in`, `copies` .. However, it's
+ unlikely that an expression would prefer content when *more* copies
+ exisited, and want to drop it when less do. That's nearly a pathological
+ case.)
+6. `migrate` is used to change a backend (`inbackend`; unlikely)
+
+That's all! Of these, 1-4 are by far the most important.
+
+## specifying what data a remote prefers to contain (**done**)
+
+Imagine a per-remote preferred content setting, that matches things that
+should be stored on the remote.
+
+For example, a MP3 player might use:
+`smallerthan(10mb) and filename(*.mp3) and (not filename(junk/*))`
+
+Adding that as a filter to files sent to a remote should be
+straightforward.
+
+A USB drive that is carried between three laptops and used to sync data
+between them might use: `not (in=laptop1 and in=laptop2 and in=laptop3)`
+
+In this case, transferring data from the usb repo should
+check if preferred content settings rejects the data, and if so, drop it
+from the repo. So once all three laptops have the data, it is
+pruned from the transfer drive.
+
+## repo groups (**done**)
+
+Seems like git-annex needs a way to know the groups of repos. Some
+groups:
+
+* enduser: The user interacts with this repo directly.
+* archival: This repo accumulates stuff, and once it's in enough archives,
+ it tends to get removed from other places.
+* transfer: This repo is used to transfer data between enduser repos,
+ it does not hold data for long periods of time, and tends to have a
+ limited size.
+
+Add a group.log that can assign repos to these or other groups. (**done**)
+
+Some examples of using groups:
+
+* Want to remove content from a repo, if it's not an archival repo,
+ and the content has reached at least one archival repo:
+
+ `(not group=archival) and (not copies=archival:1)`
+
+ That would make send to configure on all repos, or even set
+ a global `annex.accept` to it. **done**
+
+* Make a cloud repo only hold data until all known clients have a copy:
+
+ `not ingroup(enduser)`
+
+## configuration
+
+The above is all well and good for those who enjoy boolean algebra, but
+how to configure these sorts of expressions in the webapp?
+
+Currently, we have a simple drop down list to select between a few
+predefined groups with pre-defined preferred content recipes. Is this good
+enough?
+
+I think so; useful recipes can be developed on the wiki and included in
+git-annex.
+
+## the state change problem (**done**)
+
+Imagine that a trusted repo has setting like `not copies=trusted:2`
+This means that `git annex get --auto` should get files not in 2 trusted
+repos. But once it has, the file is in 3 trusted repos, and so `git annex
+drop --auto` should drop it again!
+
+How to fix? Can it even be fixed? Maybe care has to be taken when
+writing expressions, to avoid this problem. One that avoids it:
+`not (copies=trusted:2 or (in=here and trusted=here and copies=trusted:3))`
+
+Or, expressions could be automatically rewritten to avoid the problem.
+
+Or, perhaps simulation could be used to detect the problem. Before
+dropping, check the expression. Then simulate that the drop has happened.
+Does the expression now make it want to add it? Then don't drop it!
+**done**.. effectively using this approach.
diff --git a/doc/design/assistant/transfer_control/comment_1_d5adaef4712913dc0263d4ebafb79320._comment b/doc/design/assistant/transfer_control/comment_1_d5adaef4712913dc0263d4ebafb79320._comment
new file mode 100644
index 000000000..54e6a59cc
--- /dev/null
+++ b/doc/design/assistant/transfer_control/comment_1_d5adaef4712913dc0263d4ebafb79320._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 1"
+ date="2012-09-23T21:58:08Z"
+ content="""
+You could try to do it similar to [RT](http://bestpractical.com/rt/):
+
+* Implement saved statements, i.e. offer common use cases
+* Allow those statements (or aliases? stanzas?) to be loaded in a relatively simple editor with a basic wizard to support the building of new rules
+* Offer a free-text input for advanced users. It should be able to parse that and load it into the simple editor.
+* Users should be able to save, export, and import those statements.
+* Optionally, allow users to dry run the rules by showing them what git-annex needs to do to fulfill the requirements set by the statements.
+
+"""]]
diff --git a/doc/design/assistant/upgrading.mdwn b/doc/design/assistant/upgrading.mdwn
new file mode 100644
index 000000000..b1d658c8b
--- /dev/null
+++ b/doc/design/assistant/upgrading.mdwn
@@ -0,0 +1,52 @@
+The assistant should support upgrading itself.
+
+## non-distro upgrades
+
+When git-annex was installed from this website, the assistant should poll
+periodically (once a day or so) to see if there is a new version.
+It downloads, over https, a .info file, which contains a serialized data
+type containing upgrade information. The url it's downloaded from is
+configured by setting `UPGRADE_LOCATION` when building git-annex on the
+autobuilders.
+
+When a new version is found, the webapp prompts the user to start the
+upgrade. (annex.autoupgrade can be set to true to upgrade w/o prompting.)
+
+The upgrade process is automatic, and rather tricky. The file is downloaded
+using git-annex (as a regular key!), and is then unpacked into a new
+directory, and the programfile updated to point to it. Then git-annex
+restarts itself.
+
+### manifest files
+
+To clean up the old installation, a git-annex.MANIFEST file is looked for
+in it, and the files listed, as well as empty directories, are deleted.
+I don't want to accidentially delete something I didn't ship!
+
+## restart on upgrade
+
+When git-annex is installed from a proper distribution package, there is no
+need for the above. But, the assistant still needs to notice when git-annex
+get upgraded, and offer to restart (or automatically restart when
+annex.autoupgrade is set).
+
+This is done using the DirWatcher, watching the directory containing the
+git-annex binary. Or, in the case of a non-distro install, watching the
+directory where eg git-annex.linux/ was unpacked.
+
+When an change is detected, restart.
+
+## multi-daemon upgrades
+
+A single system may have multiple assistant daemons running in different
+repositories.
+
+In this case, one daemon should do the non-distro upgrade, and the rest
+should notice the upgrade and restart.
+
+I don't want every daemon trying to download the file at once..
+
+Approach: The first new version is installed into a stable directory, based
+on its version. So, start the upgrade by making this directory. If upgrade
+is already in progress, the directory will already exist. (Remove directory
+if upgrade fails.)
diff --git a/doc/design/assistant/webapp.mdwn b/doc/design/assistant/webapp.mdwn
new file mode 100644
index 000000000..797c9ad30
--- /dev/null
+++ b/doc/design/assistant/webapp.mdwn
@@ -0,0 +1,65 @@
+The webapp is a web server that displays a shiny interface.
+
+## performance
+
+Having the webapp open while transfers are
+running uses significant CPU just for the browser to update the progress
+bar. Unsurprising, since the webapp is sending the browser a new `<div>`
+each time. Updating the DOM instead from javascript would avoid that;
+the webapp just needs to send the javascript either a full `<div>` or a
+changed percentage and quantity complete to update a single progress bar.
+
+(Another reason to do this is it'll cut down on the refreshes, which
+sometimes make browsers ignore clicks on UI elements like the pause button,
+if the transfer display refreshes just as the click is made.)
+
+## other features
+
+* there could be a UI to export a file, which would make it be served up
+ over http by the web app
+* there could be a UI (some javascript thing) in the web browser to
+ submit urls to the web app to be added to the annex and downloaded.
+ See: [[todo/wishlist:_an_"assistant"_for_web-browsing_--_tracking_the_sources_of_the_downloads]]
+* Display the `inotify max_user_watches` exceeded message. **done**
+* Display something sane when kqueue runs out of file descriptors.
+* allow removing git remotes **done**
+* allow disabling syncing to here, which should temporarily disable all
+ local syncing. **done**
+
+## better headless support
+
+`--listen` is insecure, and using HTTPS would still not make it 100% secure
+as there would be no way for the browser to verify its certificate.
+
+I do have a better idea, but it'd be hard to implement.
+`git annex webapp --remote user@host:dir` could ssh to the remote host,
+run the webapp there, listening only on localhost, and then send the
+port the webapp chose back over the ssh connection. Then the same
+ssh connection could be reused (using ssh connection caching) to set up
+port forwarding from a port on the local host to the remote webapp.
+
+This would need to handle the first run case too, which would require
+forwarding a second port once the webapp made the repository and
+the second webapp started up.
+
+## first start **done**
+
+* make git repo **done**
+* generate a nice description like "joey@hostname Desktop/annex" **done**
+* record repository that was made, and use it next time run **done**
+* write a pid file, to prevent more than one first-start process running
+ at once **done**
+
+## security **acceptable/done**
+
+* Listen only to localhost. **done**
+* Instruct the user's web browser to open an url that contains a secret
+ token. This guards against other users on the same system. **done**
+ (I would like to avoid passwords or other authentication methods,
+ it's your local system.)
+* Don't pass the url with secret token directly to the web browser,
+ as that exposes it to `ps`. Instead, write a html file only the user can read,
+ that redirects to the webapp. **done**
+* Alternative for Linux at least would be to write a small program using
+ GTK+ Webkit, that runs the webapp, and can know what user ran it, avoiding
+ needing authentication.
diff --git a/doc/design/assistant/webapp/comment_1_bab6f6fa720273c0f9700a3765150189._comment b/doc/design/assistant/webapp/comment_1_bab6f6fa720273c0f9700a3765150189._comment
new file mode 100644
index 000000000..3e1330f96
--- /dev/null
+++ b/doc/design/assistant/webapp/comment_1_bab6f6fa720273c0f9700a3765150189._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlup4hyZo4eCjF8T85vfRXMKBxGj9bMdl0"
+ nickname="Ben"
+ subject="ARM support"
+ date="2012-07-13T16:51:15Z"
+ content="""
+The closure of [this](http://hackage.haskell.org/trac/ghc/ticket/5839) ticket hopefully marks the end of TH issues on ARM. As of 7.4.2, GHC's linker has enough ARM support to allow a selection of common packages compile on my PandaBoard. That being said, it hasn't had a whole lot of testing so it's possible I still need to implement a few relocation types.
+"""]]
diff --git a/doc/design/assistant/webapp/comment_2_3cf0cf460c7869d0cc22940fcc84aec4._comment b/doc/design/assistant/webapp/comment_2_3cf0cf460c7869d0cc22940fcc84aec4._comment
new file mode 100644
index 000000000..60d678aba
--- /dev/null
+++ b/doc/design/assistant/webapp/comment_2_3cf0cf460c7869d0cc22940fcc84aec4._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="yatesa"
+ ip="171.25.193.21"
+ subject="Secret URL token"
+ date="2012-06-19T03:41:16Z"
+ content="""
+> Instruct the user's web browser to open an url that contains a secret token. This guards against other users on the same system.
+
+How will you implement that? Running \"sensible-browser URL\" would be the obvious way, but the secret URL would show up in a well timed ps listing. (And depending on the browser, ps may show the URL the entire time it's running.)
+"""]]
diff --git a/doc/design/assistant/webapp/comment_3_428e153135f7a64215730719207d82c4._comment b/doc/design/assistant/webapp/comment_3_428e153135f7a64215730719207d82c4._comment
new file mode 100644
index 000000000..7a73799aa
--- /dev/null
+++ b/doc/design/assistant/webapp/comment_3_428e153135f7a64215730719207d82c4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="jtang"
+ ip="79.97.135.214"
+ subject="comment 3"
+ date="2012-07-26T17:35:18Z"
+ content="""
+Using twitter-bootstrap for the webapp - this might be a wishlist item, but would it be possible to ensure that the webapp's css uses twitter-bootstrap classes. It would make theming much easier in the long run and it would give you a nice modern look with a low amount of effort.
+"""]]
diff --git a/doc/design/assistant/webapp/comment_4_f4068a7abbb77ba6a3297cbcf1e503e9._comment b/doc/design/assistant/webapp/comment_4_f4068a7abbb77ba6a3297cbcf1e503e9._comment
new file mode 100644
index 000000000..d713e3e8f
--- /dev/null
+++ b/doc/design/assistant/webapp/comment_4_f4068a7abbb77ba6a3297cbcf1e503e9._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.2.189"
+ subject="comment 4"
+ date="2012-07-26T17:45:28Z"
+ content="""
+So, Yesod's scaffolded site actually does use bootstrap, but I didn't use the scaffolded site so don't have it. I am not quite to the point of doing any theming of the webapp, but I do have this nice example of how to put in bootstrap right here..
+
+By the way, if anyone would like to play with the html templates for the webapp, the main html template is `templates/default-layout.hamlet`. Uses a slightly weird template markup, but plain html will also work. And there's also the `static/` directory; every file in there will be compiled directly into the git-annex binary, and is available at `http://localhost:port/static/$file` in the webapp. See the favicon link in `default-layout.hamlet` of how to construct a type-safe link to a static file: `href=@{StaticR favicon_ico}`. That's all you really need to theme the webapp, without doing any real programming!
+"""]]
diff --git a/doc/design/assistant/windows.mdwn b/doc/design/assistant/windows.mdwn
new file mode 100644
index 000000000..78ab69feb
--- /dev/null
+++ b/doc/design/assistant/windows.mdwn
@@ -0,0 +1,33 @@
+See [[todo/windows_support]]..
+
+## symlinks
+
+Apparently new versions of Windows have something very like symlinks.
+(Or really, 3 or so things not entirely unlike symlinks and all different.)
+Stackoverflow has some details.
+
+NTFS supports symbolic links two different ways: an [[!wikipedia NTFS symbolic link]] and an [[!wikipedia NTFS_junction_point]]. The former seems like the closest analogue to POSIX symlinks.
+
+The windows port will not use symlinks. It will only support direct mode.
+
+## POSIX
+
+Lots of ifdefs and pain to deal with POSIX calls in the code base.
+
+Or I could try to use Cygwin.
+
+## Deeper system integration
+
+[NTFS Reparse Points](http://msdn.microsoft.com/en-us/library/aa365503%28v=VS.85%29.aspx) allow a program to define how the OS will interpret a file or directory in arbitrary ways. This requires writing a file system filter.
+
+## Developement environment
+
+Someone wrote in to say:
+
+> For Windows Development you can easily qualify
+> for Bizspark - http://www.microsoft.com/bizspark/
+>
+> This will get you 100% free Windows OS licenses and
+> Dev tools, plus a free Azure account for cloud testing.
+> (You can also now deploy Linux VMs to Azure as well)
+> No money required at all.
diff --git a/doc/design/assistant/windows/comment_1_f4b829318b182e1cec29f13babb6498e._comment b/doc/design/assistant/windows/comment_1_f4b829318b182e1cec29f13babb6498e._comment
new file mode 100644
index 000000000..0bccc3a35
--- /dev/null
+++ b/doc/design/assistant/windows/comment_1_f4b829318b182e1cec29f13babb6498e._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlCGROoy62svBUy6P24x1KoGoDWrBq2ErA"
+ nickname="Steve"
+ subject="comment 1"
+ date="2012-08-07T04:15:43Z"
+ content="""
+NTFS symbolic links should do exactly what you would expect them to do. They can point to files or directories. Junction points are legacy NTFS functionality and reparse points are more like the POSIX mount functionality.
+
+NTFS symbolic links should work for you, junction point should be avoided, and reparse points would be like using a nuke to kill a fly. The only hang up you might have is that I think all three features require elevated privileges to manage.
+"""]]
diff --git a/doc/design/assistant/xmpp.mdwn b/doc/design/assistant/xmpp.mdwn
new file mode 100644
index 000000000..4bdc58874
--- /dev/null
+++ b/doc/design/assistant/xmpp.mdwn
@@ -0,0 +1,136 @@
+The git-annex assistant uses XMPP to communicate between peers that
+cannot directly talk to one-another. A typical scenario is two users
+who share a repository, that is stored in the [[cloud]].
+
+### TODO
+
+* Do git-annex clients sharing an account with regular clients cause confusing
+ things to happen?
+ See <http://git-annex.branchable.com/design/assistant/blog/day_114__xmpp/#comment-aaba579f92cb452caf26ac53071a6788>
+* Support registering with XMPP provider from within the webapp,
+ as clients like pidgin are able to do.
+* At least some XMPP servers are lossy (does XMPP guarantee delivery)?
+ I have seen a log where a push's packet 1 and 3 arrived, but 2 did not.
+ To deal with this, need at least a 1 packet buffer and ACK or resend
+ request implemented over top of XMPP. Essentially, TCP over XMPP. :(
+
+## design goals
+
+1. Avoid user-visible messages. dvcs-autosync uses XMPP similarly, but
+ sends user-visible messages. Avoiding user-visible messages lets
+ the user configure git-annex to use his existing XMPP account
+ (eg, Google Talk).
+
+2. Send notifications to buddies. dvcs-autosync sends only self-messages,
+ but that requires every node have the same XMPP account configured.
+ git-annex should support that mode, but it should also send notifications
+ to a user's buddies. (This will also allow for using XMPP for pairing
+ in the future.)
+
+3. Don't make account appear active. Just because git-annex is being an XMPP
+ client, it doesn't mean that it wants to get chat messages, or make the
+ user appear active when he's not using his chat program.
+
+## protocol
+
+To avoid relying on XMPP extensions, git-annex communicates
+using presence messages, and chat messages (with empty body tags,
+so clients don't display them).
+
+git-annex sets a negative presence priority, to avoid any regular messages
+getting eaten by its clients. It also sets itself extended away.
+Note that this means that chat messages always have to be directed at
+specific git-annex clients.
+
+To the presence and chat messages, it adds its own tag as
+[extended content](http://xmpp.org/rfcs/rfc6121.html#presence-extended).
+The xml namespace is "git-annex" (not an URL because I hate wasting bandwidth).
+
+To indicate it's pushed changes to a git repo with a given UUID, a message
+that is sent to all buddies and other clients using the account (no
+explicit pairing needed), it uses a broadcast presence message containing:
+
+ <git-annex xmlns='git-annex' push="uuid[,uuid...]" />
+
+Multiple UUIDs can be listed when multiple clients were pushed. If the
+git repo does not have a git-annex UUID, an empty string is used.
+
+To query if other git-annex clients are around, a presence message is used,
+containing:
+
+ <git-annex xmlns='git-annex' query="" />
+
+For pairing, a chat message is sent to every known git-annex client,
+containing:
+
+ <git-annex xmlns='git-annex' pairing="PairReq|PairAck|PairDone myuuid" />
+
+### git push over XMPP
+
+To indicate that we could push over XMPP, a chat message is sent,
+to each known client of each XMPP remote.
+
+ <git-annex xmlns='git-annex' canpush="myuuid" shas="sha1 sha1" />
+
+The shas are omitted by old clients. If present, they are the git shas of
+the head and git-annex branches that are available to be pushed. This lets
+the receiver check if it's already got them.
+
+To request that a remote push to us, a chat message can be sent.
+
+ <git-annex xmlns='git-annex' pushrequest="myuuid" />
+
+When replying to an canpush message, this is directed at the specific
+client that indicated it could push. To solicit pushes from all clients,
+the message has to be sent directed individually to each client.
+
+When a peer is ready to send a git push, it sends:
+
+ <git-annex xmlns='git-annex' startingpush="myuuid" />
+
+The receiver runs `git receive-pack`, and sends back its output in
+one or more chat messages, directed to the client that is pushing:
+
+ <git-annex xmlns='git-annex' rp="N">
+ 007b27ca394d26a05d9b6beefa1b07da456caa2157d7 refs/heads/git-annex report-status delete-refs side-band-64k quiet ofs-delta
+ </git-annex>
+
+The sender replies with the data from `git push`, in
+one or more chat messages, directed to the receiver:
+
+ <git-annex xmlns='git-annex' sp="N">
+ data
+ </git-annex>
+
+The value of rp and sp used to be empty, but now it's a sequence number.
+This indicates the sequence of this packet, counting from 1. The receiver
+and sender each have their own sequence numbers.
+
+When `git receive-pack` exits, the receiver indicates its exit
+status with a chat message, directed at the sender:
+
+ <git-annex xmlns='git-annex' rpdone="0" />
+
+### security
+
+Data git-annex sends over XMPP will be visible to the XMPP account's
+buddies, and to the XMPP server (and any attacker who has access to the
+XMPP server). So it's important to consider the security exposure of using
+it.
+
+Even if git-annex sends only a single bit notification, this lets attackers
+know when the user is active and changing files. Although the assistant's other
+syncing activities can somewhat mask this.
+
+As soon as git-annex does anything unlike any other client, an attacker can
+see how many clients are connected for a user, and fingerprint the ones
+running git-annex, and determine how many clients are running git-annex.
+
+An attacker can observe the UUIDs used for pushes and pairing, and determine
+how many different remotes are being used.
+
+An attacker could replay push notification messages, reusing UUIDs it's
+observed. This would make clients pull repeatedly, perhaps as a DOS.
+
+The XMPP server, or an attacker with access to it can reconstruct the git
+repository from data sent in pushes, in part or in whole.
diff --git a/doc/design/assistant/xmpp/comment_1_f20650f93d7f0ca39b9ba3ce0380193f._comment b/doc/design/assistant/xmpp/comment_1_f20650f93d7f0ca39b9ba3ce0380193f._comment
new file mode 100644
index 000000000..7ee62eea7
--- /dev/null
+++ b/doc/design/assistant/xmpp/comment_1_f20650f93d7f0ca39b9ba3ce0380193f._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://meep.pl/"
+ ip="193.23.174.18"
+ subject="xmlns"
+ date="2012-11-11T09:00:01Z"
+ content="""
+A minor point, but is saving a couple of bytes per message worth using a [deprecated feature](http://www.w3.org/TR/REC-xml-names/#iri-use) of the namespaces specification? This is not technically *breaking* the current specification, since \"git-annex\" is of course still a (relative) URI reference; and anyway chances of problems are, I guess, slim. But is it the lesser of two bugs?
+
+The shortest moderately sane absolute URI containing \"git-annex\" would probably be \"data:,git-annex\".
+"""]]
diff --git a/doc/design/assistant/xmpp/comment_2_8c22839a8f5912b4a817415c4a359697._comment b/doc/design/assistant/xmpp/comment_2_8c22839a8f5912b4a817415c4a359697._comment
new file mode 100644
index 000000000..5b6ea3946
--- /dev/null
+++ b/doc/design/assistant/xmpp/comment_2_8c22839a8f5912b4a817415c4a359697._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkurjhi0CRJvgm7QNaZDWS9hitBtavqIpc"
+ nickname="Bret"
+ subject="Plans for two factor authentication or oath?"
+ date="2013-04-15T00:58:04Z"
+ content="""
+Are there plans to support google's two factor authentication? Right now I have to use an application specific password.
+"""]]
diff --git a/doc/design/assistant/xmpp/comment_4_773102522f21844cffc841e6cde9229e._comment b/doc/design/assistant/xmpp/comment_4_773102522f21844cffc841e6cde9229e._comment
new file mode 100644
index 000000000..f8ddf0a3b
--- /dev/null
+++ b/doc/design/assistant/xmpp/comment_4_773102522f21844cffc841e6cde9229e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="hhm"
+ ip="108.17.80.177"
+ subject="file transfer?"
+ date="2013-04-23T10:22:51Z"
+ content="""
+Would it be possible to add optional support for transferring files over XMPP (possibly being disabled out-of-the-box so as not to suck up third-party bandwidth)?
+"""]]
diff --git a/doc/design/assistant/xmpp_security.mdwn b/doc/design/assistant/xmpp_security.mdwn
new file mode 100644
index 000000000..6b2b728f2
--- /dev/null
+++ b/doc/design/assistant/xmpp_security.mdwn
@@ -0,0 +1,26 @@
+Currently [[xmpp]] relies on the SSL connection to the server for security.
+The server can see git repository data pushed through it. (Also, the SSL
+connection is not pinned or really checked well at all.)
+
+Add an encryption layer that does not rely on trusting the XMPP server's
+security. There are a few options for how to generate the key for eg,
+AES encryption:
+
+ * Do a simple Diffie-Hellman shared key generation when starting each XMPP
+ push session. Would not protect the users from active MITM by the
+ XMPP server, but would prevent passive data gathering attacks from
+ getting useful data. Since the key is ephemeral, would provide
+ Forward Security.
+ * Do D-H key generation, but at pairing, not push time. Allows for an
+ optional confirmation step, using eg, BubbleBabble to compare the
+ keys out of band. ("I see xebeb-dibyb-gycub-kacyb-modib-pudub-sefab-vifuc-bygoc-daguc-gohec-kuxax .. do you too?")
+ * Prompt both users for a passphrase when XMPP pairing, and
+ use SPEKE (or similar methods like J-PAKE) to generate a shared key.
+ Avoids active MITM attacks. Makes pairing harder, especially pairing
+ between one's own devices, since the passphrase has to be entered on
+ all devices. Also problimatic when pairing more than 2 devices,
+ especially when adding a device to the set later, since there
+ would then be multiple different keys in use.
+ * Rely on the user's gpg key, and do gpg key verification during XMPP
+ pairing. Problimatic because who wants to put their gpg key on their
+ phone? Also, require the users be in the WOT and be gpg literate.
diff --git a/doc/design/assistant/xmpp_security/comment_1_c714e86553c02600249795efb224be8a._comment b/doc/design/assistant/xmpp_security/comment_1_c714e86553c02600249795efb224be8a._comment
new file mode 100644
index 000000000..92cff201d
--- /dev/null
+++ b/doc/design/assistant/xmpp_security/comment_1_c714e86553c02600249795efb224be8a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="Sagi"
+ ip="2001:610:1908:8001:25ce:8a0b:53cc:c010"
+ subject="Why not use OTR?"
+ date="2013-07-23T23:53:12Z"
+ content="""
+[OTR](http://www.cypherpunks.ca/otr/) seems a natural fit for end-to-end encryption over xmpp. I can't find Haskell bindings for libotr at this moment, but creating those instead of inventing new protocols might be worth considering. There are also several [native implementations](http://www.cypherpunks.ca/otr/software.php) (Python, Go, Scheme), but I'm not sure if that's worth the effort.
+
+
+"""]]
diff --git a/doc/design/encryption.mdwn b/doc/design/encryption.mdwn
new file mode 100644
index 000000000..cc0dd1684
--- /dev/null
+++ b/doc/design/encryption.mdwn
@@ -0,0 +1,126 @@
+This was the design doc for [[/encryption]] and is preserved for
+the curious. For an example of using git-annex with an encrypted S3 remote,
+see [[tips/using_Amazon_S3]].
+
+[[!toc]]
+
+## encryption backends
+
+It makes sense to support multiple encryption backends. So, there
+should be a way to tell what backend is responsible for a given filename
+in an encrypted remote. (And since special remotes can also store files
+unencrypted, differentiate from those as well.)
+
+The rest of this page will describe a single encryption backend using GPG.
+Probably only one will be needed, but who knows? Maybe that backend will
+turn out badly designed, or some other encryptor needed. Designing
+with more than one encryption backend in mind helps future-proofing.
+
+## encryption key management
+
+[[!template id=note text="""
+The basis of this scheme was originally developed by Lars Wirzenius et al
+[for Obnam](http://liw.fi/obnam/encryption/).
+"""]]
+
+Data is encrypted by GnuPG, using a symmetric cipher. The cipher is
+generated by GnuPG when the special remote is created. By default the
+best entropy pool is used, hence the generation may take a while; One
+can use `initremote` with `highRandomQuality=false` or `--fast` options
+to speed up things, but at the expense of using random numbers of a
+lower quality. The generated cipher is then checked into your git
+repository, encrypted using one or more OpenPGP public keys. This scheme
+allows new OpenPGP private keys to be given access to content that has
+already been stored in the remote.
+
+Different encrypted remotes need to be able to each use different ciphers.
+Allowing multiple ciphers to be used within a single remote would add a lot
+of complexity, so is not planned to be supported.
+Instead, if you want a new cipher, create a new S3 bucket, or whatever.
+There does not seem to be much benefit to using the same cipher for
+two different encrypted remotes.
+
+So, the encrypted cipher could just be stored with the rest of a remote's
+configuration in `remotes.log` (see [[internals]]). When `git
+annex intiremote` makes a remote, it can generate a random symmetric
+cipher, and encrypt it with the specified gpg key. To allow another gpg
+public key access, update the encrypted cipher to be encrypted to both gpg
+keys.
+
+## filename enumeration
+
+If the names of files are encrypted or securely hashed, or whatever is
+chosen, this makes it harder for git-annex (let alone untrusted third parties!)
+to get a list of the files that are stored on a given enrypted remote.
+But, does git-annex really ever need to do such an enumeration?
+
+Apparently not. `git annex unused --from remote` can now check for
+unused data that is stored on a remote, and it does so based only on
+location log data for the remote. This assumes that the location log is
+kept accurately.
+
+What about `git annex fsck --from remote`? Such a command should be able to,
+for each file in the repository, contact the encrypted remote to check
+if it has the file. This can be done without enumeration, although it will
+mean running gpg once per file fscked, to get the encrypted filename.
+
+So, the files stored in the remote should be encrypted. But, it needs to
+be a repeatable encryption, so they cannot just be gpg encrypted, that
+would yeild a new name each time. Instead, HMAC is used. Any hash could
+be used with HMAC. SHA-1 is the default, but [[other_hashes|/encryption]]
+can be chosen for new remotes.
+
+It was suggested that it might not be wise to use the same cipher for both
+gpg and HMAC. Being paranoid, it's best not to tie the security of one
+to the security of the other. So, the encrypted cipher described above is
+actually split in two; half is used for HMAC, and half for gpg.
+
+----
+
+Does the HMAC cipher need to be gpg encrypted? Imagine if it were
+stored in plainext in the git repository. Anyone who can access
+the git repository already knows the actual filenames, and typically also
+the content hashes of annexed content. Having access to the HMAC cipher
+could perhaps be said to only let them verify that data they already
+know.
+
+While this seems a pretty persuasive argument, I'm not 100% convinced, and
+anyway, most times that the HMAC cipher is needed, the gpg cipher is also
+needed. Keeping the HMAC cipher encrypted does slow down two things:
+dropping content from encrypted remotes, and checking if encrypted remotes
+really have content. If it's later determined to be safe to not encrypt the
+HMAC cipher, the current design allows changing that, even for existing
+remotes.
+
+## other use of the symmetric cipher
+
+The symmetric cipher can be used to encrypt other content than the content
+sent to the remote. In particular, it may make sense to encrypt whatever
+access keys are used by the special remote with the cipher, and store that
+in remotes.log. This way anyone whose gpg key has been given access to
+the cipher can get access to whatever other credentials are needed to
+use the special remote.
+
+## risks
+
+A risk of this scheme is that, once the symmetric cipher has been
+obtained, it allows full access to all the encrypted content. Indeed
+anyone owning a key that used to be granted access could already have
+decrypted the cipher and stored a copy. While it is in possible to
+remove a key with `keyid-=`, it is designed for a
+[[completely_different_purpose|/encryption]] and does not actually revoke
+access.
+
+If git-annex stores the decrypted symmetric cipher in memory, then there
+is a risk that it could be intercepted from there by an attacker. Gpg
+ameliorates these type of risks by using locked memory. For git-annex, note
+that an attacker with local machine access can tell at least all the
+filenames and metadata of files stored in the encrypted remote anyway,
+and can access whatever content is stored locally.
+
+This design does not support obfuscating the size of files by chunking
+them, as that would have added a lot of complexity, for dubious benefits.
+If the untrusted party running the encrypted remote wants to know file sizes,
+they could correlate chunks that are accessed together. Encrypting data
+changes the original file size enough to avoid it being used as a direct
+fingerprint at least.
diff --git a/doc/design/encryption/comment_1_4715ffafb3c4a9915bc33f2b26aaa9c1._comment b/doc/design/encryption/comment_1_4715ffafb3c4a9915bc33f2b26aaa9c1._comment
new file mode 100644
index 000000000..f2ecc46d0
--- /dev/null
+++ b/doc/design/encryption/comment_1_4715ffafb3c4a9915bc33f2b26aaa9c1._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 1"
+ date="2011-04-03T20:03:14Z"
+ content="""
+New encryption keys could be used for different directories/files/patterns/times/whatever. One could then encrypt this new key for the public keys of other people/machines and push them out along with the actual data. This would allow some level of access restriction or future revocation. git-annex would need to keep track of which files can be decrypted with which keys. I am undecided if that information needs to be encrypted or not.
+
+Encrypted object files should be checksummed in encrypted form so that it's possible to verify integrity without knowing any keys. Same goes for encrypted keys, etc.
+
+Chunking files in this context seems like needless overkill. This might make sense to store a DVD image on CDs or similar, at some point. But not for encryption, imo. Coming up with sane chunk sizes for all use cases is literally impossible and as you pointed out, correlation by the remote admin is trivial.
+"""]]
diff --git a/doc/design/encryption/comment_2_a610b3d056a059899178859a3a821ea5._comment b/doc/design/encryption/comment_2_a610b3d056a059899178859a3a821ea5._comment
new file mode 100644
index 000000000..d5461e23c
--- /dev/null
+++ b/doc/design/encryption/comment_2_a610b3d056a059899178859a3a821ea5._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 2"
+ date="2011-04-05T18:41:49Z"
+ content="""
+I see no use case for verifying encrypted object files w/o access to the encryption key. And possible use cases for not allowing anyone to verify your data.
+
+If there are to be multiple encryption keys usable within a single encrypted remote, than they would need to be given some kind of name (a since symmetric key is used, there is no pubkey to provide a name), and the name encoded in the files stored in the remote. While certainly doable I'm not sold that adding a layer of indirection is worthwhile. It only seems it would be worthwhile if setting up a new encrypted remote was expensive to do. Perhaps that could be the case for some type of remote other than S3 buckets.
+"""]]
diff --git a/doc/design/encryption/comment_3_cca186a9536cd3f6e86994631b14231c._comment b/doc/design/encryption/comment_3_cca186a9536cd3f6e86994631b14231c._comment
new file mode 100644
index 000000000..d3c483fdf
--- /dev/null
+++ b/doc/design/encryption/comment_3_cca186a9536cd3f6e86994631b14231c._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 3"
+ date="2011-04-05T23:24:17Z"
+ content="""
+Assuming you're storing your encrypted annex with me and I with you, our regular cron jobs to verify all data will catch corruption in each other's annexes.
+
+Checksums of the encrypted objects could be optional, mitigating any potential attack scenarios.
+
+It's not only about the cost of setting up new remotes. It would also be a way to keep data in one annex while making it accessible only in a subset of them. For example, I might need some private letters at work, but I don't want my work machine to be able to access them all.
+"""]]
diff --git a/doc/design/encryption/comment_4_8f3ba3e504b058791fc6e6f9c38154cf._comment b/doc/design/encryption/comment_4_8f3ba3e504b058791fc6e6f9c38154cf._comment
new file mode 100644
index 000000000..14eb1acac
--- /dev/null
+++ b/doc/design/encryption/comment_4_8f3ba3e504b058791fc6e6f9c38154cf._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 4"
+ date="2011-04-07T19:59:30Z"
+ content="""
+@Richard the easy way to deal with that scenario is to set up a remote that work can access, and only put in it files work should be able to see. Needing to specify which key a file should be encrypted to when putting it in a remote that supported multiple keys would add another level of complexity which that avoids.
+
+Of course, the right approach is probably to have a separate repository for work. If you don't trust it with seeing file contents, you probably also don't trust it with the contents of your git repository.
+"""]]
diff --git a/doc/design/encryption/comment_5_520e60aa53217b5ba428d4c05d897dee._comment b/doc/design/encryption/comment_5_520e60aa53217b5ba428d4c05d897dee._comment
new file mode 100644
index 000000000..ff579f49b
--- /dev/null
+++ b/doc/design/encryption/comment_5_520e60aa53217b5ba428d4c05d897dee._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkS6aFVrEwOrDuQBTMXxtGHtueA69NS_jo"
+ nickname="Hans"
+ subject="using sshfs + cryptmount is more secure"
+ date="2012-08-14T13:41:47Z"
+ content="""
+\"For git-annex, note that an attacker with local machine access can tell at least all the filenames and metadata of files stored in the encrypted remote anyway, and can access whatever content is stored locally.\"
+
+Better security is given by sshfs + cryptmount, which I used when I recently setup a git-annex repository on a free shell account from a provider I do not trust.
+
+See http://code.cjb.net/free-secure-online-backup.html for what I did to get a really secure solution.
+
+Kind regards,
+
+Hans Ekbrand
+"""]]
diff --git a/doc/design/encryption/comment_6_d677fead0fe0c543f48f07d85f83f592._comment b/doc/design/encryption/comment_6_d677fead0fe0c543f48f07d85f83f592._comment
new file mode 100644
index 000000000..a2c7013fb
--- /dev/null
+++ b/doc/design/encryption/comment_6_d677fead0fe0c543f48f07d85f83f592._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="comment 6"
+ date="2012-08-14T14:10:40Z"
+ content="""
+Hans,
+
+You are misunderstanding how git-annex encryption works. The \"untrusted host\" and the \"local machine\" are not the same machine. git-annex only transfers pre-encrypted files to the \"untrusted host\".
+
+You should setup a git-annex encrypted remote and watch how it works so you can see for yourself that it is not insecure.
+
+Your solution does not provide better security, it accomplishes the same thing as git-annex in a more complicated way. In addition, since you are mounting the image from the client your solution will not work with multiple clients.
+"""]]
diff --git a/doc/design/encryption/comment_7_c1c38a09b1276e29adc3ba564dc0fe4e._comment b/doc/design/encryption/comment_7_c1c38a09b1276e29adc3ba564dc0fe4e._comment
new file mode 100644
index 000000000..259214495
--- /dev/null
+++ b/doc/design/encryption/comment_7_c1c38a09b1276e29adc3ba564dc0fe4e._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkS6aFVrEwOrDuQBTMXxtGHtueA69NS_jo"
+ nickname="Hans"
+ subject="comment 7"
+ date="2012-08-15T19:16:10Z"
+ content="""
+Justin,
+
+thanks for clearing that up. It's great that git-annex has implemented mechanisms to work securely on untrusted hosts. My solution is thus only interesting for files that are impractical to manage with git-annex (e.g. data for/from applications that need rw-access to a large number of files). And, possibly, for providers that do not provide rsync.
+
+Your remark that my solution does not work with more than one client, is not entirely accurate. No more than one client can access the repository at any given time, but as long as access is not simultaneous, any number of clients can access the repository. Still, your point is taken, it's a limitation I should mention.
+
+It would be interesting to compare the performance of individually encrypted files to encrypted image-file. My intuition says that encrypted image-file should be faster, but that's just a guess.
+"""]]
diff --git a/doc/design/gcrypt.mdwn b/doc/design/gcrypt.mdwn
new file mode 100644
index 000000000..d5b9c064b
--- /dev/null
+++ b/doc/design/gcrypt.mdwn
@@ -0,0 +1,8 @@
+To integrate with git-remote-gcrypt, a key thing is to have a way to map
+from the gcrypt-id of an encrypted repository to a git-annex repository
+uuid.
+
+To do this, we'll make a v5 UUID, feeding in the gcrypt-id.
+The namespace used is itself a v5 UUID, generated using the URL
+namespace and the URL of this page at the time this scheme was
+developed: "http://git-annex.branchable.com/design/gcrypt/"
diff --git a/doc/design/roadmap.mdwn b/doc/design/roadmap.mdwn
new file mode 100644
index 000000000..34ddf0ed5
--- /dev/null
+++ b/doc/design/roadmap.mdwn
@@ -0,0 +1,18 @@
+## roadmap
+
+Now in the
+[sustaining git-annex development](https://campaign.joeyh.name/) year
+(starting September 2013).
+
+* Month 1 [[!traillink assistant/encrypted_git_remotes]]
+* Month 2 [[!traillink assistant/disaster_recovery]]
+* **Month 3 user-driven features and polishing** [[todo/direct_mode_guard]] [[assistant/upgrading]]
+* Month 4 improve special remote interface & git-annex enhancement contest
+* Month 5 [[!traillink assistant/xmpp_security]]
+* Month 6 Windows assistant and webapp
+* Month 7 user-driven features and polishing
+* Month 8 [[!traillink assistant/gpgkeys]] [[!traillink assistant/sshpassword]]
+* Month 9 get [[assistant/Android]] out of beta
+* Month 10 user-driven features and polishing
+* Month 11 [[!traillink assistant/chunks]] [[!traillink assistant/deltas]]
+* Month 12 user-driven features and polishing
diff --git a/doc/devblog.mdwn b/doc/devblog.mdwn
new file mode 100644
index 000000000..aa66b0100
--- /dev/null
+++ b/doc/devblog.mdwn
@@ -0,0 +1,10 @@
+Work on git-annex is [crowdfunded](https://campaign.joeyh.name/).
+Joey blogs about his progress here on a semi-daily basis.
+
+[[!sidebar content="""
+[[!calendar type="month" pages="page(devblog/*)"]]
+[[!calendar type="month" month="-1" pages="page(devblog/*)"]]
+[[!calendar type="month" month="-2" pages="page(devblog/*)"]]
+"""]]
+
+[[!inline pages="page(devblog/*)" show=0]]
diff --git a/doc/devblog/day_-1__drop_dead.mdwn b/doc/devblog/day_-1__drop_dead.mdwn
new file mode 100644
index 000000000..97f7cf1d2
--- /dev/null
+++ b/doc/devblog/day_-1__drop_dead.mdwn
@@ -0,0 +1,5 @@
+Implemented `git annex forget --drop-dead`, which is finally a way to
+remove all references to old repositories that you've marked as dead.
+
+I've still not merged in the `forget` branch, because I developed this
+while slightly ill, and have not tested it very well yet.
diff --git a/doc/devblog/day_-3__.mdwn b/doc/devblog/day_-3__.mdwn
new file mode 100644
index 000000000..fa1473e06
--- /dev/null
+++ b/doc/devblog/day_-3__.mdwn
@@ -0,0 +1,29 @@
+John Millikin came through and fixed that haskell-gnutls segfault
+on OSX that I developed a reproducible test case for the other day.
+It's a bit hard to test, since the bug doesn't always happen, but the
+fix is already deployed for Mountain Lion autobuilder.
+
+However, I then found another way to make haskell-gnutls segfault, more
+reliably on OSX, and even sometimes on Linux. Just entering the wrong XMPP
+password in the assistant can trigger this crash. Hopefully John will work
+his magic again.
+
+---
+
+Meanwhile, I fixed the sync-after-forget problem. Now sync always forces
+its push of the git-annex branch (as does the assistant). I considered but
+rejected having sync do the kind of uuid-tagged branch push that the
+assistant sometimes falls back to if it's failing to do a normal sync. It's
+ugly, but worse, it wouldn't work in the workflow where multiple clients
+are syncing to a central bare repository, because they'd not pull down the
+hidden uuid-tagged branches, and without the assistant running on the
+repository, nothing would ever merge their data into the git-annex branch.
+Forcing the push of synced/git-annex was easy, once I satisfied myself
+that it was always ok to do so.
+
+Also factored out a module that knows about all the different log files
+stored on the git-annex branch, which is all the support infrastructure
+that will be needed to make `git annex forget --drop-dead` work. Since this
+is basically a routing module, perhaps I'll get around to making it use
+a nice bidirectional routing library like
+[Zwaluw](http://hackage.haskell.org/package/Zwaluw) one day.
diff --git a/doc/devblog/day_-4__forgetting.mdwn b/doc/devblog/day_-4__forgetting.mdwn
new file mode 100644
index 000000000..a37b32e33
--- /dev/null
+++ b/doc/devblog/day_-4__forgetting.mdwn
@@ -0,0 +1,80 @@
+Yesterday I spent making a release, and shopping for a new laptop, since
+this one is dying. (Soon I'll be able to compile git-annex fast-ish! Yay!)
+And thinking about [[todo/wishlist:_dropping_git-annex_history]].
+
+Today, I added the `git annex forget` command. It's currently been lightly
+tested, seems to work, and is living in the `forget` branch until I gain
+confidence with it. It should be perfectly safe to use, even if it's buggy,
+because you can use `git reflog git-annex` to pull out and revert to an old
+version of your git-annex branch. So if you're been wanting this feature,
+please beta test!
+
+----
+
+I actually implemented something more generic than just forgetting git
+history. There's now a whole mechanism for git-annex doing distributed
+transitions of whatever sort is needed.
+
+There were several subtleties involved in distributed transitions:
+
+First is how to tell when a given transition has already been done on a
+branch. At first I was thinking that the transition log should include the
+sha of the first commit on the old branch that got rewritten. However, that
+would mean that after a single transition had been done, every git-annex
+branch merge would need to look up the first commit of the current branch,
+to see if it's done the transition yet. That's slow! Instead, transitions
+are logged with a timestamp, and as long as a branch contains a transition
+with the same timestamp, it's been done.
+
+A really tricky problem is what to do if the local repository has
+transitioned, but a remote has not, and changes keep being made to the
+remote. What it does so far is incorporate the changes from the remote into
+the index, and re-run the transition code over the whole thing to yeild a
+single new commit. This might not be very efficient (once I write the more
+full-featured transition code), but it lets the local repo keep up with
+what's going on in the remote, without directly merging with it (which
+would revert the transition). And once the remote repository has its
+git-annex upgraded to one that knows about transitions, it will finish up
+the transition on its side automatically, and the two branches will once
+again merge.
+
+Related to the previous problem, we don't want to keep trying to merge
+from a remote branch when it's not yet transitioned. So a blacklist is
+used, of untransitioned commits that have already been integrated.
+
+One really subtle thing is that when the user does a transition more
+complicated than `git annex forget`, like the `git annex forget --dead`
+that I need to implement to forget dead remotes, they're not just telling
+git-annex to forget whatever dead remotes it knows right now. They're
+actually telling git-annex to perform the transition one time on every
+existing clone of the repository, at some point in the future. Repositories
+with unfinished transitions could hang around for years, and at some future
+point when git-annex runs in the repository again, it would merge in the
+current state of the world, and re-do the transition. So you might tell it
+to forget dead remotes today, and then the very repository you ran that in
+later becomes dead, and a long-slumbering repo wakes up and forgets about
+the repo that started the whole process! I hope users don't find this
+massively confusing, but that's how the implementation works right now.
+
+----
+
+I think I have at least two more days of work to do to finish up this
+feature.
+
+* I still need to add some extra features like forgetting about dead remotes,
+ and forgetting about keys that are no longer present on any remote.
+
+* After `git annex forget`, `git annex sync`
+ will fail to push the synced/annex branch to remotes, since the branch
+ is no longer a fast-forward of the old one. I will probably fix this by
+ making `git annex sync` do a fallback push of a unique branch in this case,
+ like the assistant already does. Although I may need to adjust that code
+ to handle this case, too..
+
+* For some reason the automatic transitioning code triggers
+ a "(recovery from race)" commit. This is certainly a bug somewhere,
+ because you can't have a race with only 1 participant.
+
+----
+
+Today's work was sponsored by Richard Hartmann.
diff --git a/doc/devblog/day_-4__forgetting/comment_1_f3cc7a25af4c59fda3924c737a789419._comment b/doc/devblog/day_-4__forgetting/comment_1_f3cc7a25af4c59fda3924c737a789419._comment
new file mode 100644
index 000000000..4c926c1af
--- /dev/null
+++ b/doc/devblog/day_-4__forgetting/comment_1_f3cc7a25af4c59fda3924c737a789419._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="Sandra.Devil"
+ ip="77.172.73.184"
+ subject="New laptop"
+ date="2013-09-01T09:38:32Z"
+ content="""
+What is the new laptop you are going to use? Specs please :)
+"""]]
diff --git a/doc/devblog/day_10__lazy_Sunday.mdwn b/doc/devblog/day_10__lazy_Sunday.mdwn
new file mode 100644
index 000000000..aa6a70918
--- /dev/null
+++ b/doc/devblog/day_10__lazy_Sunday.mdwn
@@ -0,0 +1,23 @@
+Fixed a typo that broke automatic youtube video support in `addurl`.
+
+----
+
+Now there's an easy way to get an overview of how close your repository
+is to meeting the configured numcopies settings (or when it exceeds them).
+
+<pre>
+# time git annex status .
+[...]
+numcopies stats:
+ numcopies +0: 6686
+ numcopies +1: 3793
+ numcopies +3: 3156
+ numcopies +2: 2743
+ numcopies -1: 1242
+ numcopies -4: 1098
+ numcopies -3: 1009
+ numcopies +4: 372
+</pre>
+
+This does make `git annex status` slow when run on a large directory tree,
+so --fast disables that.
diff --git a/doc/devblog/day_11__webapp_encrypted_drives.mdwn b/doc/devblog/day_11__webapp_encrypted_drives.mdwn
new file mode 100644
index 000000000..677c02491
--- /dev/null
+++ b/doc/devblog/day_11__webapp_encrypted_drives.mdwn
@@ -0,0 +1,12 @@
+Now the webapp can set up encrypted repositories on removable drives.
+
+[[assistant/encryptdrive.png]]
+
+This UI needs some work, and the button to create a new key is not wired
+up. Also if you have no gpg agent installed, there will be lots of password
+prompts at the console.
+
+Forked git-remote-gcrypt to fix a bug. Hopefully my patch will be merged;
+for now I recommend installing my worked version.
+
+Today's work was sponsored by Romain Lenglet.
diff --git a/doc/devblog/day_12__gpg_key_generation.mdwn b/doc/devblog/day_12__gpg_key_generation.mdwn
new file mode 100644
index 000000000..c79c49f85
--- /dev/null
+++ b/doc/devblog/day_12__gpg_key_generation.mdwn
@@ -0,0 +1,35 @@
+I decided to keep gpg key generation very simple for now. So it generates a
+special-purpose key that is only intended to be used by git-annex. It
+hardcodes some key parameters, like RSA and 4096 bits (maximum recommended
+by gpg at this time). And there is no password on the key, although you can
+of course edit it and set one. This is because anyone who can access the
+computer to get the key can also look at the files in your git-annex
+repository. Also because I can't rely on gpg-agent being installed
+everywhere. All these simplifying assumptions may be revisited later, but
+are enough for now for someone who doesn't know about gpg (so doesn't
+have a key already) and just wants an encrypted repo on a
+removable drive.
+
+Put together a simple UI to deal with gpg taking quite a while to
+generate a key ...
+
+[[assistant/genkey.png]]
+
+[[assistant/repoinfo.png]]
+
+Then I had to patch git-remote-gcrypt again, to have a per-remote
+signingkey setting, so that these special-purpose keys get used for signing
+their repo.
+
+Next, need to add support for adding an existing gcrypt repo as a remote
+(assuming it's encrypted to an available key). Then, gcrypt repos on ssh
+servers..
+
+----
+
+Also dealt with build breakage caused by a new version of the Haskell DNS
+library.
+
+----
+
+Today's work was sponsored by Joseph Liu.
diff --git a/doc/devblog/day_12__gpg_key_generation/comment_1_48cdfe3bd71fb348ae05fd90e8cf1dab._comment b/doc/devblog/day_12__gpg_key_generation/comment_1_48cdfe3bd71fb348ae05fd90e8cf1dab._comment
new file mode 100644
index 000000000..d7a6a8631
--- /dev/null
+++ b/doc/devblog/day_12__gpg_key_generation/comment_1_48cdfe3bd71fb348ae05fd90e8cf1dab._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://nullroute.eu.org/~grawity/"
+ nickname="Mantas"
+ subject="comment 1"
+ date="2013-09-18T05:00:12Z"
+ content="""
+Should be \"PGP\" or *at least* \"GnuPG\".
+"""]]
diff --git a/doc/devblog/day_13__encrypted_sneakernet_working.mdwn b/doc/devblog/day_13__encrypted_sneakernet_working.mdwn
new file mode 100644
index 000000000..777da255a
--- /dev/null
+++ b/doc/devblog/day_13__encrypted_sneakernet_working.mdwn
@@ -0,0 +1,13 @@
+Spent basically all of today getting the assistant to be able to handle
+gcrypt special remotes that already exist when it's told to add a USB
+drive. This was quite tricky! And I did have to skip handling gcrypt repos
+that are not git-annex special remotes.
+
+Anyway, it's now almost easy to set up an encrypted sneakernet
+using a USB drive and some computers running the webapp. The only part
+that the assistant doesn't help with is gpg key management.
+
+Plan is to make a release on Friday, and then try to also add support for
+encrypted git repositories on remote servers. Tomorrow I will try to get
+through some of the communications backlog that has been piling up while I
+was head down working on gcrypt.
diff --git a/doc/devblog/day_14__gcrypt_refinements_and_OOM_fixes.mdwn b/doc/devblog/day_14__gcrypt_refinements_and_OOM_fixes.mdwn
new file mode 100644
index 000000000..2ff1d16dd
--- /dev/null
+++ b/doc/devblog/day_14__gcrypt_refinements_and_OOM_fixes.mdwn
@@ -0,0 +1,26 @@
+Spent a few hours improving gcrypt in some minor ways, including adding a
+--check option that the assistant can use to find out if a given repo is
+encrypted with dgit, and also tell if the necessary gpg key is available to
+decrypt it. Also merged in a fix to support subkeys, developed by a
+git-annex user who is the first person I've heard from who is using gcrypt.
+I don't want to maintain gcrypt, so I am glad its author has shown up
+again today.
+
+Got mostly caught up on backlog. The main bug I was able to track down
+today is git-annex using a lot of memory in certian repositories. This
+turns out to have happened when a really large file was committed right
+intoo to the git repository (by mistake or on purpose). Some parts of
+git-annex buffer file contents in memory while trying to work out if
+they're git-annex keys. Fixed by making it first check if a file in git is
+marked as a symlink. Which was really hard to do!
+
+At least 4 people ran into this bug, which makes me suspect that lots of
+people are messing up when using direct mode (probably due to not reading
+the documentation, or having `git commit -a` hardwired into their fingers,
+and forcing git to commit large files into their repos, rather than having
+git-annex manage them. Implementing [[todo/direct_mode_guard]] seems more
+urgent now.
+
+----
+
+Today's work was sponsored by Amitai Schlair.
diff --git a/doc/devblog/day_15-17__Android_rebuild.mdwn b/doc/devblog/day_15-17__Android_rebuild.mdwn
new file mode 100644
index 000000000..758e2d097
--- /dev/null
+++ b/doc/devblog/day_15-17__Android_rebuild.mdwn
@@ -0,0 +1,67 @@
+Made a release on Friday. But I had to rebuild the OSX and Linux standalone
+builds today to fix a bug in them.
+
+Spent the past **three days** redoing the whole Android build environment.
+I've been progressively moving from my first hacked up Android build env to
+something more reproducible and sane. Finally I am at the point where I can
+run a shell script (well, actually, 3 shell scripts) and get an Android
+build chroot. It's still not immune to breaking when new versions of
+haskell libs are uploaded, but this is much better, and should be
+maintainable going forward.
+
+This is a good starting point for getting git-annex into the F-Droid app
+store, or for trying to build with a newer version of the Android SDK and
+NDK, to perhaps get it working on Android 4.3. (Eventually. I am so sick
+of building Android stuff right now..)
+
+Friday was all spent struggling to get ghc-android to build. I had not built
+it successfully since February. I finally did,
+on Saturday, and I have made my own fork of it which builds using a
+known-good snapshot of the current development version of ghc. Building
+this in a Debian stable chroot means that there should be no possibility
+that upstream changes will break the build again.
+
+With ghc built, I moved on to building all the haskell libs git-annex
+needs. Unfortunately my build script for these also has stopped working
+since I made it in April. I failed to pin every package at a defined
+version, and things broke.
+
+So, I redid the build script, and updated all the haskell libs to the
+newest versions while I was at it. I have decided not to pin the library
+versions (at least until I find a foolproof way to do it), so this new
+script will break in the future, but it should break in a way I can fix up
+easily by just refreshing a patch.
+
+The new ghc-android build has a nice feature of at least being able to
+compile Template Haskell code (though still not run it at compile time.
+This made the patching needed in the Haskell libs quite a lot less. Offset
+somewhat by me needing to make general fixes to lots of libs to build with
+ghc head. Including some fun with `==#` changing its type from `Bool` to
+`Int#`. In all, I think I removed around 2.5 thousand lines of patches!
+(Only 6 thousand lines to go...)
+
+Today I improved ghc-android some more so it cross builds several C libraries
+that are needed to build several haskell libraries needed for XMPP.
+I had only ever built those once, and done it by hand, and very hackishly.
+Now they all build automatically too.
+
+And, I put together a script that builds the debian stable chroot and
+installs ghc-android.
+
+And, I hacked on the EvilSplicer (which is sadly still needed) to
+work with the new ghc/yesod/etc.
+
+At this point, I have git-annex successfully building, including the APK!
+
+----
+
+In a bored hour waiting for a compile, I also sped up `git annex add`
+on OSX by I think a factor of 10. Using cryptohash for hash calculation
+now, when external hash programs are not available. It's still a few
+percentage points slower than external hash programs, or I'd use it by
+default.
+
+----
+
+This period of important drudgery was sponsored by an unknown bitcoin
+user, and by Bradley Unterrheiner and Andreas Olsson.
diff --git a/doc/devblog/day_19__moving_on.mdwn b/doc/devblog/day_19__moving_on.mdwn
new file mode 100644
index 000000000..7f4cd8244
--- /dev/null
+++ b/doc/devblog/day_19__moving_on.mdwn
@@ -0,0 +1,37 @@
+Finished moving the Android autobuilder over to the new clean build
+environment. Tested the Android app, and it still works. Whew!
+
+There's a small chance that the issue with the Android app not working on
+Android 4.3 has been fixed by this rebuild. I doubt it, but perhaps someone
+can download the daily build and give it another try..
+
+----
+
+I have 7 days left in which I'd like to get remote gcrypt repositories
+working in the assistant. I think that should be fairly easy, but a
+prerequisite for it is making git-annex-shell support being run on a gcrypt
+repository. That's needed so that the assistant's normal locked down ssh
+key setup can also be used for gcrypt repositories.
+
+At the same time, not all gcrypt endpoints will have git-annex-shell
+installed, and it *seems* to make sense to leave in the existing support
+for running raw rsync and git push commands against such a repository. So
+that's going to add some complication.
+
+It will also complicate git-annex-shell to support gcrypt repos. Basically,
+everything it does in git-annex repos will need to be reimplemented in
+gcrypt repositories. Generally in a more simple form; for example it
+doesn't need to (and can't) update location logs in a gcrypt repo.
+
+----
+
+I also need to find a good UI to present the three available choices
+(unencrypted git, encrypted git, encrypted rsync) when setting up a repo
+on a ssh server. I don't want to just remove the encrypted rsync option,
+because it's useful when using xmpp to sync the git repo, and is simpler to
+set up since it uses shared encryption rather than gpg public keys.
+
+My current thought is to offer just 2 choices, encrypted and non-encrypted.
+If they choose encrypted, offer a choice of shared encryption or encrypting
+to a specific key. I think I can word this so it's pretty clear what the
+tradeoffs are.
diff --git a/doc/devblog/day_19__moving_on/comment_1_870106f671f9a055b81e6fc83e0850b5._comment b/doc/devblog/day_19__moving_on/comment_1_870106f671f9a055b81e6fc83e0850b5._comment
new file mode 100644
index 000000000..b0ed97bcf
--- /dev/null
+++ b/doc/devblog/day_19__moving_on/comment_1_870106f671f9a055b81e6fc83e0850b5._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmW0kg4uiMIhSHeVuvJFyo2VYMl7Qoej0s"
+ nickname="Chris"
+ subject="comment 1"
+ date="2013-09-23T20:58:45Z"
+ content="""
+The new version of the Android apk doesn't work for me on my Nexus 4.
+"""]]
diff --git a/doc/devblog/day_19__moving_on/comment_2_fad055c8860385ac6c012f897c96408f._comment b/doc/devblog/day_19__moving_on/comment_2_fad055c8860385ac6c012f897c96408f._comment
new file mode 100644
index 000000000..f2e754b3a
--- /dev/null
+++ b/doc/devblog/day_19__moving_on/comment_2_fad055c8860385ac6c012f897c96408f._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmkBwMWvNKZZCge_YqobCSILPMeK6xbFw8"
+ nickname="develop"
+ subject="comment 2"
+ date="2013-09-24T07:11:31Z"
+ content="""
+Yeah, no joy on Cyanogenmod 10.2(Android 4.3).
+
+Would be pretty surprising if it had worked.
+"""]]
diff --git a/doc/devblog/day_19__moving_on/comment_3_69e47d612159587f080ab761566d1830._comment b/doc/devblog/day_19__moving_on/comment_3_69e47d612159587f080ab761566d1830._comment
new file mode 100644
index 000000000..206fdd852
--- /dev/null
+++ b/doc/devblog/day_19__moving_on/comment_3_69e47d612159587f080ab761566d1830._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnR6E5iUghMWdUGlbA9CCs8DKaoigMjJXw"
+ nickname="Efraim"
+ subject="not working on my nexus 4 either"
+ date="2013-09-24T07:37:28Z"
+ content="""
+terminal output reads:
+
+Falling back to hardcoded app location; cannot find expected files in /data/app-lib
+
+git annex webapp
+
+u0_a124@mako:/sdcard/git-annex.home $ git annex webpp
+
+CANNOT LINK EXECUTABLE: git-annex invalid R_ARM_COPY relocation against DT_SYMBOLIC shared library libc.so (built with -Bsymbolic?)
+
+1|u0_a124@mako:/sdcard/git-annex.home $
+"""]]
diff --git a/doc/devblog/day_1__inauspicious_beginning.mdwn b/doc/devblog/day_1__inauspicious_beginning.mdwn
new file mode 100644
index 000000000..b14f763bb
--- /dev/null
+++ b/doc/devblog/day_1__inauspicious_beginning.mdwn
@@ -0,0 +1,11 @@
+I try hard to keep this devblog about git-annex development and not me.
+However, it is a shame that what I wanted to be the beginning of my first
+real month of work funded by the new campaign has been marred by my home's
+internet connection being taken out by a lightning strike, and by illness.
+Nearly back on my feet after that, and waiting for my new laptop to
+finally get here.
+
+Today's work: Finished up the `git annex forget` feature and merged it in.
+Fixed the bug that was causing the commit race detection code to
+incorrectly fire on the commit made by the transition code. Few other bits
+and pieces.
diff --git a/doc/devblog/day_1__inauspicious_beginning/comment_1_cc4dea43caf3126c6f814b589b701d70._comment b/doc/devblog/day_1__inauspicious_beginning/comment_1_cc4dea43caf3126c6f814b589b701d70._comment
new file mode 100644
index 000000000..03e3fec6d
--- /dev/null
+++ b/doc/devblog/day_1__inauspicious_beginning/comment_1_cc4dea43caf3126c6f814b589b701d70._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="rjc"
+ ip="86.22.66.200"
+ subject="laptop"
+ date="2013-09-04T21:42:52Z"
+ content="""
+Are you retiring your Dell mini?
+
+What kind of laptop are you getting?
+"""]]
diff --git a/doc/devblog/day_20__gcrypt_and_git-annex-shell.mdwn b/doc/devblog/day_20__gcrypt_and_git-annex-shell.mdwn
new file mode 100644
index 000000000..0e4142b7c
--- /dev/null
+++ b/doc/devblog/day_20__gcrypt_and_git-annex-shell.mdwn
@@ -0,0 +1,14 @@
+Added support for gcrypt remotes to git-annex-shell. Now gcrypt special
+remotes probe when they are set up to see if the remote system has a
+suitable git-annex-shell, and if so all commands are sent to it. Kept the
+direct rsync mode working as a fallback.
+
+It turns out I made a bad decision when first adding gcrypt support to
+git-annex. To make implementation marginally easier, I decided to not
+put objects inside the usual `annex/objects` directory in a gcrypt remote.
+But that lack of consistency would have made adding support to
+git-annex-shell a lot harder. So, I decided to change this. Which
+means that anyone already using gcrypt with git-annex will need to
+[[manually_move_files_around|upgrades/gcrypt]].
+
+Today's work was sponsored by Tobias Nix.
diff --git a/doc/devblog/day_21__bugfix_day.mdwn b/doc/devblog/day_21__bugfix_day.mdwn
new file mode 100644
index 000000000..a913fce56
--- /dev/null
+++ b/doc/devblog/day_21__bugfix_day.mdwn
@@ -0,0 +1,5 @@
+Did various bug fixes and followup today. Amazing how a day can vanish that
+way. Made 4 actual improvements.
+
+I still have 46 messages in unanswered backlog. Although only 8 of
+the are from this month.
diff --git a/doc/devblog/day_22__gcrypt_on_rsync.net.mdwn b/doc/devblog/day_22__gcrypt_on_rsync.net.mdwn
new file mode 100644
index 000000000..2c5951795
--- /dev/null
+++ b/doc/devblog/day_22__gcrypt_on_rsync.net.mdwn
@@ -0,0 +1,20 @@
+Being still a little unsure of the UI and complexity
+for configuring gcrypt on ssh servers, I thought I'd start today with the
+special case of gcrypt on rsync.net. Since rsync.net allows running some git
+commands, gcrypt can be used to make encrypted git repositories on it.
+
+Here's the UI I came up with. It's complicated a bit by needing to explain
+the tradeoffs between the rsync and gcrypt special remotes.
+
+[[!img /assistant/rsync.net.encryption.png]]
+
+This works fine, but I did not get a chance to add support for enabling
+existing gcrypt repos on rsync.net. Anyway, most of the changes to make
+this work will also make it easier to add general support for gcrypt on ssh
+servers.
+
+Also spent a while fixing a bug in git-remote-gcrypt. Oddly
+`gpg --list-keys --fast-list --fingerprint` does not show the fingerprints
+of some keys.
+
+Today's work was sponsored by Cloudier - Thomas Djärv.
diff --git a/doc/devblog/day_23__GNU_day.mdwn b/doc/devblog/day_23__GNU_day.mdwn
new file mode 100644
index 000000000..4f5b25ca7
--- /dev/null
+++ b/doc/devblog/day_23__GNU_day.mdwn
@@ -0,0 +1,23 @@
+Worked on making the assistant able to merge in existing encrypted
+git repositories from rsync.net.
+
+This had two parts. First, making the webapp UI where you click to enable a
+known special remote work with these encrypted repos. Secondly, handling
+the case where a user knows they have an encrypted repository on rsync.net,
+so enters in its hostname and path, but git-annex doesn't know about that
+special remote. The second case is important, for example, when the
+encrypted repository is a backup and you're restoring from it. It wouldn't
+do for the assistant, in that case, to make a *new* encrypted repo and
+push it over top of your backup!
+
+Handling that was a neat trick. It has to do quite a lot of probing, including
+downloading the whole encrypted git repo so it can decrypt it and merge it,
+to find out about the special remote configuration used for it. This all
+works with just 2 ssh connections, and only 1 ssh password prompt max.
+
+Next, on to generalizing this rsync.net specific code to work with
+arbitrary ssh servers!
+
+----
+
+Today's work was made possible by [RMS's vision 30 years ago](http://article.olduse.net/771@mit-eddie.UUCP).
diff --git a/doc/devblog/day_24__nearly_done_with_gcrypt.mdwn b/doc/devblog/day_24__nearly_done_with_gcrypt.mdwn
new file mode 100644
index 000000000..22d3fa70b
--- /dev/null
+++ b/doc/devblog/day_24__nearly_done_with_gcrypt.mdwn
@@ -0,0 +1,23 @@
+So close to being done with gcrypt support.. But still not quite there.
+
+Today I made the UI changes to support gcrypt when setting up a repository
+on a ssh server, and improved the probing and data types so it can tell
+which options the server supports. Fairly happy with how that is turning
+out.
+
+Have not yet hooked up the new buttons to make gcrypt repos. While I was
+testing that my changes didn't break other stuff, I found a bug in the
+webapp that caused it to sometimes fail to transfer one file to/from a
+remote that was just added, because the transferrer process didn't know
+about the new remote yet, and crashed (and was restarted knowing about it,
+so successfully sent any other files). So got sidetracked on fixing that.
+
+Also did some work to make the gpg bundled with git-annex on OSX be
+compatable with the config files written by MacGPG. At first I was going to
+hack it to not crash on the options it didn't support, but it turned out
+that upgrading to version 1.4.14 actually fixed the problem that was making
+it build without support for DNS.
+
+----
+
+Today's work was sponsored by Thomas Hochstein.
diff --git a/doc/devblog/day_25__finishing_up_gcrypt.mdwn b/doc/devblog/day_25__finishing_up_gcrypt.mdwn
new file mode 100644
index 000000000..9666282d0
--- /dev/null
+++ b/doc/devblog/day_25__finishing_up_gcrypt.mdwn
@@ -0,0 +1,25 @@
+Long day, but I did finally finish up with gcrypt support. More or less.
+
+Got both creating and enabling existing gcrypt repositories on ssh servers
+working in the webapp. (But I ran out of time to make it detect when the
+user is manually entering a gcrypt repo that already exists. Should be easy
+so maybe tomorrow.)
+
+Fixed several bugs in git-annex's gcrypt support that turned up in testing.
+Made git-annex ensure that a gcrypt repository does not have
+receive.denyNonFastForwards set, because gcrypt relies on always forcing
+the push of the branch it stores its manifest on. Fixed a bug in
+`git-annex-shell recvkey` when it was receiving a file from an annex in
+direct mode.
+
+Also had to add a new `git annex shell gcryptsetup` command, which is
+needed to make setting up a gcrypt repository work when the assistant
+has set up a locked-down ssh key that can only run git-annex-shell. Painted
+myself into a bit of a corner there.
+
+And tested, tested, tested. So many possibilities and edge cases in this
+part of the code..
+
+----
+
+Today's work was sponsored by Hendrik Müller Hofstede.
diff --git a/doc/devblog/day_26__gcrypt_really_done_this_time.mdwn b/doc/devblog/day_26__gcrypt_really_done_this_time.mdwn
new file mode 100644
index 000000000..347e4be5f
--- /dev/null
+++ b/doc/devblog/day_26__gcrypt_really_done_this_time.mdwn
@@ -0,0 +1,17 @@
+Did I say it would be easy to make the webapp detect when a gcrypt repository
+already existed and enable it? Well, it wasn't exactly hard, but it took
+over 300 lines of code and 3 hours..
+
+So, gcrypt support is done for now. The glaring omission is gpg key
+management for sharing gcrypt repositories between machines and/or people.
+But despite that, I think it's solid, and easy to use, and covers some
+great use cases.
+
+Pushed out a release.
+
+Now I really need to start thinking about
+[[design/assistant/disaster_recovery]].
+
+----
+
+Today's work was sponsored by Dominik Wagenknecht.
diff --git a/doc/devblog/day_27__locking_fun.mdwn b/doc/devblog/day_27__locking_fun.mdwn
new file mode 100644
index 000000000..ef0c4131f
--- /dev/null
+++ b/doc/devblog/day_27__locking_fun.mdwn
@@ -0,0 +1,49 @@
+Started the day by getting the builds updated for yesterday's release. This
+included making it possible to build git-annex with Debian stable's version
+of cryptohash. Also updated the Debian stable backport to the previous
+release.
+
+----
+
+The [[design/roadmap]] has this month devoted to improving git-annex's
+support for recovering from disasters, broken repos, and so on. Today I've
+been working on the first thing on [[the_list|design/assistant/disaster_recovery]],
+stale git index lock files.
+
+It's unfortunate that git uses simple files for locking, and does not use
+fcntl or flock to prevent the stale lock file problem. Perhaps they want
+it to work on broken NFS systems? The problem with that line of thinking is
+is means all non-broken systems end up broken by stale lock files. Not a
+good tradeoff IMHO.
+
+There are actually two lock files that can end up stale when using
+git-annex; both `.git/index.lock` and `.git/annex/index.lock`. Today I
+concentrated on the latter, because I saw a way to prevent it from ever
+being a problem. All updates to that index file are done by git-annex when
+committing to the git-annex branch. git-annex already uses fcntl locking
+when manipulating its journal. So, that can be extended to also cover
+committing to the git-annex branch, and then the git `index.lock` file
+is irrelevant, and can just be removed if it exists when a commit is
+started.
+
+To ensure this makes sense, I used the type system to prove that the journal
+locking was in effect everywhere I need it to be. Very happy I was able to
+do that, although I am very much a novice at using the type system for
+interesting proofs. But doing so made it very easily to build up to a point
+where I could unlink the `.git/annex/index.lock` and be sure it was safe to do
+that.
+
+----
+
+What about stale `.git/index.lock` files? I don't think it's appropriate
+for git-annex to generally recover from those, because it would change
+regular git command line behavior, and risks breaking something. However, I
+do want the assistant to be able to recover if such a file exists when it
+is starting up, since that would prevent it from running. Implemented that
+also today, although I am less happy with the way the assistant detects
+when this lock file is stale, which is somewhat heuristic (but should work
+even on networked filesystems with multiple writing machines).
+
+----
+
+Today's work was sponsored by Torbjørn Thorsen.
diff --git a/doc/devblog/day_27__locking_fun/comment_1_0eb247235fbf8f563934f3548e1d2e10._comment b/doc/devblog/day_27__locking_fun/comment_1_0eb247235fbf8f563934f3548e1d2e10._comment
new file mode 100644
index 000000000..261fa005c
--- /dev/null
+++ b/doc/devblog/day_27__locking_fun/comment_1_0eb247235fbf8f563934f3548e1d2e10._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://cstork.org/"
+ nickname="Chris Stork"
+ subject="News page not updated"
+ date="2013-10-04T09:38:21Z"
+ content="""
+Already for the last three or so releases the News page wasn't updated. :-( I think many people (including me) used this page to check if their version is uptodate. Posting the newest version there motivates people to try the very latest which seems very desirable for the git-annex development.
+"""]]
diff --git a/doc/devblog/day_27__locking_fun/comment_2_e8b1dfe1b0641e031d05733448b7bc8b._comment b/doc/devblog/day_27__locking_fun/comment_2_e8b1dfe1b0641e031d05733448b7bc8b._comment
new file mode 100644
index 000000000..c073f735a
--- /dev/null
+++ b/doc/devblog/day_27__locking_fun/comment_2_e8b1dfe1b0641e031d05733448b7bc8b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.243"
+ subject="comment 2"
+ date="2013-10-04T20:13:37Z"
+ content="""
+Sorry about that. It turns out my release script was broken.
+"""]]
diff --git a/doc/devblog/day_27__locking_fun/comment_3_b67f8ef4ed42b49c8c2e6c4e53163b16._comment b/doc/devblog/day_27__locking_fun/comment_3_b67f8ef4ed42b49c8c2e6c4e53163b16._comment
new file mode 100644
index 000000000..39c840e84
--- /dev/null
+++ b/doc/devblog/day_27__locking_fun/comment_3_b67f8ef4ed42b49c8c2e6c4e53163b16._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="comment 3"
+ date="2013-10-07T09:17:30Z"
+ content="""
+Hi,
+
+Can you please enlighten us mere mortals, when this stale file locking problem occcurs?
+The typical situation. I tried to google up, and read locking files on wikipedia, but
+still have no exact knowledge when the \"stale\" part happens.
+
+How it gets outdated without noticing?
+
+Best,
+ Laszlo
+
+"""]]
diff --git a/doc/devblog/day_27__locking_fun/comment_4_0759644baf26b75f4e48dbb387d725a5._comment b/doc/devblog/day_27__locking_fun/comment_4_0759644baf26b75f4e48dbb387d725a5._comment
new file mode 100644
index 000000000..cbeae8b78
--- /dev/null
+++ b/doc/devblog/day_27__locking_fun/comment_4_0759644baf26b75f4e48dbb387d725a5._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.22"
+ subject="comment 4"
+ date="2013-10-12T23:31:16Z"
+ content="""
+Git simply creates a file as a lock file, and does not use any form of locking on it, so if the git process dies for any reason before it gets a chance to remove the lock file, a stale lock file remains, and future git commands will fall over it.
+
+It's really surprisingly bad..
+"""]]
diff --git a/doc/devblog/day_28__lazy_saturday.mdwn b/doc/devblog/day_28__lazy_saturday.mdwn
new file mode 100644
index 000000000..c2237b28b
--- /dev/null
+++ b/doc/devblog/day_28__lazy_saturday.mdwn
@@ -0,0 +1,17 @@
+Finished up the automatic recovery from stale lock files. Turns out git
+has quite a few lock files; the assistant handles them all.
+
+Improved URL and WORM keys so the filenames used for them
+will always work on FAT (which has a crazy assortmeny of illegal
+characters). This is a tricky thing to deal with without breaking backwards
+compatability, so it's only dealt with when creating new URL or WORM keys.
+
+-----
+
+I think my next step in this disaster recovery themed month will be adding
+periodic incremental fsck to the assistant. `git annex fsck` can already
+do an incremental fsck, so this should mostly involve adding a user
+interface to the webapp to configure when it should fsck. For example, you
+might choose to run it for up 1 hour every night, with a goal of checking
+all your files once per month. Also will need to make the assistant do
+something useful when fsck finds a bad file (ie, queue a re-download).
diff --git a/doc/devblog/day_29__scheduling.mdwn b/doc/devblog/day_29__scheduling.mdwn
new file mode 100644
index 000000000..98c928bf8
--- /dev/null
+++ b/doc/devblog/day_29__scheduling.mdwn
@@ -0,0 +1,10 @@
+Spent most of the day building some generic types for scheduling recurring
+events. Not sure if rolling my own was a good idea, but that's what I did.
+
+In the incrementalfsck branch, I have hooked this up in `git-annex vicfg`,
+which now accepts and parses scheduled events like
+"fsck self every day at any time for 60 minutes" and
+"fsck self on day 1 of weeks divisible by 2 at 3:45 for 120 minutes", and
+stores them in the git-annex branch. The exact syntax is of course subject
+to change, but also doesn't matter a whole lot since the webapp will have
+a better interface.
diff --git a/doc/devblog/day_2__new_laptop.mdwn b/doc/devblog/day_2__new_laptop.mdwn
new file mode 100644
index 000000000..000800742
--- /dev/null
+++ b/doc/devblog/day_2__new_laptop.mdwn
@@ -0,0 +1,8 @@
+Now I can build git-annex twice as fast! And a typical incremental build is
+down to 10 seconds, from 51 seconds.
+
+Spent a productive evening working with Guilhem to get his encryption
+patches reviewed and merged. Now there is a way to remove revoked gpg keys,
+and there is a new encryption scheme available that uses public key
+encryption by default rather than git-annex's usual approach. That's not
+for everyone, but it is a good option to have available.
diff --git a/doc/devblog/day_2__new_laptop/comment_1_93447dbd4eb09b4db96770644ea663cb._comment b/doc/devblog/day_2__new_laptop/comment_1_93447dbd4eb09b4db96770644ea663cb._comment
new file mode 100644
index 000000000..15d19b0c9
--- /dev/null
+++ b/doc/devblog/day_2__new_laptop/comment_1_93447dbd4eb09b4db96770644ea663cb._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="comment 1"
+ date="2013-09-05T15:07:44Z"
+ content="""
+out of curiosity, what laptop model have you choosen finally?
+
+Laszlo
+"""]]
diff --git a/doc/devblog/day_2__new_laptop/comment_2_e1d022b25f2c16dbe72db07ad4b10a2d._comment b/doc/devblog/day_2__new_laptop/comment_2_e1d022b25f2c16dbe72db07ad4b10a2d._comment
new file mode 100644
index 000000000..052597521
--- /dev/null
+++ b/doc/devblog/day_2__new_laptop/comment_2_e1d022b25f2c16dbe72db07ad4b10a2d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="24.159.78.54"
+ subject="comment 2"
+ date="2013-09-06T18:02:08Z"
+ content="""
+Lenovo Yoga 11s
+"""]]
diff --git a/doc/devblog/day_30__cronner.mdwn b/doc/devblog/day_30__cronner.mdwn
new file mode 100644
index 000000000..f368407ca
--- /dev/null
+++ b/doc/devblog/day_30__cronner.mdwn
@@ -0,0 +1,17 @@
+Lots of progress from yesterday's modest start of building data types for
+scheduling. Last night I wrote the hairy calendar code to calculate when
+next to run a scheduled event. (This is actually quite superior to `cron`,
+which checks every second to see if it should run each event!) Today I
+built a "Cronner" thread that handles spawning threads to handle each
+scheduled event. It even notices when changes have been made to the its
+schedule and stops/starts event threads appropriately.
+
+Everything is hooked up, building, and there's a good chance it works
+without too many bugs, but while I've tested all the pure code (mostly
+automatically with quickcheck properties), I have not run the Cronner
+thread at all. And there is some tricky stuff in there, like noticing
+that the machine was asleep past when it expected to wake up, and deciding
+if it should still run a scheduled event, or should wait until next time.
+So tomorrow we'll see..
+
+Today's work was sponsored by Ethan Aubin.
diff --git a/doc/devblog/day_30__cronner/comment_1_53dfd9310e92f5225db52a13e20a46d4._comment b/doc/devblog/day_30__cronner/comment_1_53dfd9310e92f5225db52a13e20a46d4._comment
new file mode 100644
index 000000000..dc0c7dfe1
--- /dev/null
+++ b/doc/devblog/day_30__cronner/comment_1_53dfd9310e92f5225db52a13e20a46d4._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://nullroute.eu.org/~grawity/"
+ nickname="Mantas"
+ subject="comment 1"
+ date="2013-10-09T06:04:15Z"
+ content="""
+The SysV Unix *cron* learned this same thing [in 1979][1].
+
+[1]: http://en.wikipedia.org/wiki/Cron#Multi-user_capability
+"""]]
diff --git a/doc/devblog/day_30__cronner/comment_2_f98357c6f7a6da23873ac27c2e1e9638._comment b/doc/devblog/day_30__cronner/comment_2_f98357c6f7a6da23873ac27c2e1e9638._comment
new file mode 100644
index 000000000..0fc310a78
--- /dev/null
+++ b/doc/devblog/day_30__cronner/comment_2_f98357c6f7a6da23873ac27c2e1e9638._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.22"
+ subject="comment 2"
+ date="2013-10-11T17:07:24Z"
+ content="""
+However, if you strace a traditional cron, you will be sad at how it's implemented. So much statting of files, and checking of entries every second..
+
+0 polling or redundant calulcation in my code!
+"""]]
diff --git a/doc/devblog/day_31__blah.mdwn b/doc/devblog/day_31__blah.mdwn
new file mode 100644
index 000000000..672adbfd3
--- /dev/null
+++ b/doc/devblog/day_31__blah.mdwn
@@ -0,0 +1,17 @@
+Some neat stuff is coming up, but today was a pretty blah day for me.
+I did get the Cronner tested and working (only had a few little bugs). But
+I got stuck for quite a while making the Cronner stop `git-annex fsck`
+processes it was running when their jobs get removed. I had some code to do
+this that worked when run standalone, but not when run from git-annex.
+
+After considerable head-scratching, I found out this was due to
+`forkProcess` masking aync exceptions, which seems to be probably
+[a bug](http://ghc.haskell.org/trac/ghc/ticket/8433). Luckily was able to
+work around it. Async exceptions continue to strike me as the worst part of
+the worst part of Haskell (the worst part being exceptions in general).
+
+Was more productive after that.. Got the assistant to automatically queue
+re-downloads of any files that fsck throws out due to having bad contents,
+and made the webapp display an alert while fscking is running, which will
+go to the page to configure fsck schedules. Now all I need to do is
+build the UI of that page.
diff --git a/doc/devblog/day_32__fsck_config_UI.mdwn b/doc/devblog/day_32__fsck_config_UI.mdwn
new file mode 100644
index 000000000..66f4cfd54
--- /dev/null
+++ b/doc/devblog/day_32__fsck_config_UI.mdwn
@@ -0,0 +1,20 @@
+Last night, built this nice user interface for configuring periodic fscks:
+
+[[!img assistant/fsckconfig.png]]
+
+Rather happy that that whole UI needed only 140 lines of code to build.
+Though rather more work behind it, as seen in this blog..
+
+Today I added some support to git-annex for smart fscking of remotes.
+So far only git repos on local drives, but this should get extended to
+git-annex-shell for ssh remotes. The assistant can also run periodic fscks
+of these.
+
+Still need to test that, and find a way to make a removable drive's fsck
+job run when the drive gets plugged in. That's where picking "any time"
+will be useful; it'll let you configure fscking of removable drives when
+they're available, as long as they have not been fscked too recently.
+
+----
+
+Today's work was sponsored by Georg Bauer.
diff --git a/doc/devblog/day_33__fsck_on_connect.mdwn b/doc/devblog/day_33__fsck_on_connect.mdwn
new file mode 100644
index 000000000..36c226008
--- /dev/null
+++ b/doc/devblog/day_33__fsck_on_connect.mdwn
@@ -0,0 +1,9 @@
+Built everything needed to run a fsck when a remote gets connected. Have
+not tested it; only testing is blocking merging the incrementalfsck branch
+now.
+
+Also updated the OSX and Android builds to use a new gpg release (denial of
+service security fix), and updated the Debian backport, and did a small
+amount of bug fixing. I need to do several more days of bug fixing once
+I get this incremental fsck feature wrapped up before moving on to recovery
+of corrupt git repositories.
diff --git a/doc/devblog/day_34__wrapping_up_fsck.mdwn b/doc/devblog/day_34__wrapping_up_fsck.mdwn
new file mode 100644
index 000000000..b66708605
--- /dev/null
+++ b/doc/devblog/day_34__wrapping_up_fsck.mdwn
@@ -0,0 +1,7 @@
+Fixed a lot of bugs in the assistant's fsck handling today, and merged
+it into master. There are some enhancments that could be added to it,
+including fscking ssh remotes via git-annex-shell and adding the ability to
+schedule events to run every 30 days instead of on a specific day of the
+month. But enough on this feature for now.
+
+Today's work was sponsored by Daniel Brockman.
diff --git a/doc/devblog/day_35__anacron_and_bugfixing.mdwn b/doc/devblog/day_35__anacron_and_bugfixing.mdwn
new file mode 100644
index 000000000..af021d576
--- /dev/null
+++ b/doc/devblog/day_35__anacron_and_bugfixing.mdwn
@@ -0,0 +1,15 @@
+While I said I was done with fsck scheduling yesterday, I ended up adding
+one more feature to it today: Full anacron style scheduling. So a fsck can
+be scheduled to run once per week, or month, or year, and it'll run the
+fsck the next time it's available after that much time has passed. The nice
+thing about this is I didn't have to change Cronner *at all* to add this,
+just improved the Recurrance data type and the code that calculates when
+to run events.
+
+Rest of the day I've been catching up on some bug reports. The main bug I
+fixed caused git-annex on Android to hang when adding files. This turns out
+to be because it's using a new (unreleased) version of git, and
+`git check-attr -z` output format has changed in an incompatable way.
+
+I am currently 70 messages behind, which includes some ugly looking bug
+reports, so I will probably continue with this over the next couple days.
diff --git a/doc/devblog/day_36__bugfixing.mdwn b/doc/devblog/day_36__bugfixing.mdwn
new file mode 100644
index 000000000..0e31d54bf
--- /dev/null
+++ b/doc/devblog/day_36__bugfixing.mdwn
@@ -0,0 +1 @@
+Productive day, but I'm wiped out. Backlog down to 51.
diff --git a/doc/devblog/day_37__long_day.mdwn b/doc/devblog/day_37__long_day.mdwn
new file mode 100644
index 000000000..7882a746d
--- /dev/null
+++ b/doc/devblog/day_37__long_day.mdwn
@@ -0,0 +1,6 @@
+A long day of bugfixing. Split into two major parts. First I got back to a
+bug I filed in August to do with the assistant misbehaving when run in a
+subdirectory of a git repository, and did a nice type-driven fix of the
+underlying problem (that also found and fixed some other related bugs that
+would not normally occur). Then, spent 4 hours in Windows purgatory working
+around crazy path separator issues.
diff --git a/doc/devblog/day_38__starting_git_repo_repair.mdwn b/doc/devblog/day_38__starting_git_repo_repair.mdwn
new file mode 100644
index 000000000..3808abe38
--- /dev/null
+++ b/doc/devblog/day_38__starting_git_repo_repair.mdwn
@@ -0,0 +1,11 @@
+Goal for the rest of the month is to build automatic recovery git
+repository corruption. Spent today investigating how to do it and came up
+with a fairly [[detailed_design|design/assistant/disaster_recovery]]. It
+will have two parts, first to handle repository problems that can be fixed
+by fetching objects from remotes, and secondly to recover from problems
+where data never got sent to a remote, and has been lost.
+
+In either case, the assistant should be able to detect the problem and
+automatically recover well enough to keep running. Since this also affects
+non-git-annex repositories, it will also be available in a standalone
+`git-recover-repository` command.
diff --git a/doc/devblog/day_38__starting_git_repo_repair/comment_1_321468d9686db5dde072500bdaeb7d29._comment b/doc/devblog/day_38__starting_git_repo_repair/comment_1_321468d9686db5dde072500bdaeb7d29._comment
new file mode 100644
index 000000000..3a1ce7851
--- /dev/null
+++ b/doc/devblog/day_38__starting_git_repo_repair/comment_1_321468d9686db5dde072500bdaeb7d29._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://cstork.org/"
+ nickname="Chris Stork"
+ subject="Idea: checksum left-over files in .git/annex/tmp for potential recovery"
+ date="2013-10-19T12:30:58Z"
+ content="""
+This just came to mind when I thought about the second case. I noticed quite often that files were left in .git/annex/tmp (seen on OS X) and sometimes these are the only instances of files on this particular computer.
+
+(It's on my todo list to file several bug reports about this and other issues on OS X...)
+"""]]
diff --git a/doc/devblog/day_39__git-recover-repository.mdwn b/doc/devblog/day_39__git-recover-repository.mdwn
new file mode 100644
index 000000000..f2c552eef
--- /dev/null
+++ b/doc/devblog/day_39__git-recover-repository.mdwn
@@ -0,0 +1,54 @@
+Built a `git-recover-repository` command today. So far it only does the
+detection and deletion of corrupt objects, and retrieves them from remotes
+when possible. No handling yet of missing objects that cannot be recovered
+from remotes.
+
+Here's a couple of sample runs where I do bad things to the git
+repository and it fixes them:
+
+<pre>
+joey@darkstar:~/tmp/git-annex>chmod 644 .git/objects/pack/*
+joey@darkstar:~/tmp/git-annex>echo > .git/objects/pack/pack-a1a770c1569ac6e2746f85573adc59477b96ebc5.pack
+joey@darkstar:~/tmp/git-annex>~/src/git-annex/git-recover-repository
+Running git fsck ...
+git fsck found a problem but no specific broken objects. Perhaps a corrupt pack file? Unpacking all pack files.
+fatal: early EOF
+Unpacking objects: 100% (148/148), done.
+Unpacking objects: 100% (354/354), done.
+Re-running git fsck to see if it finds more problems.
+Re-running git fsck to see if it finds more problems.
+Initialized empty Git repository in /home/joey/tmp/tmprepo.0/.git/
+Trying to recover missing objects from remote origin
+Successfully recovered repository!
+You should run "git fsck" to make sure, but it looks like
+everything was recovered ok.
+</pre>
+
+----
+
+<pre>
+joey@darkstar:~/tmp/git-annex>chmod 644 .git/objects/00/0800742987b9f9c34caea512b413e627dd718e
+joey@darkstar:~/tmp/git-annex>echo > .git/objects/00/0800742987b9f9c34caea512b413e627dd718e
+joey@darkstar:~/tmp/git-annex>~/src/git-annex/git-recover-repository
+Running git fsck ...
+error: unable to unpack 000800742987b9f9c34caea512b413e627dd718e header
+error: inflateEnd: stream consistency error (no message)
+error: unable to unpack 000800742987b9f9c34caea512b413e627dd718e header
+error: inflateEnd: stream consistency error (no message)
+git fsck found 1 broken objects. Unpacking all pack files.
+removing 1 corrupt loose objects
+Re-running git fsck to see if it finds more problems.
+Re-running git fsck to see if it finds more problems.
+Initialized empty Git repository in /home/joey/tmp/tmprepo.0/.git/
+Trying to recover missing objects from remote origin
+Successfully recovered repository!
+You should run "git fsck" to make sure, but it looks like
+everything was recovered ok.
+</pre>
+
+Works great! I need to move this and `git-union-merge` out of the git-annex
+source tree sometime.
+
+----
+
+Today's work was sponsored by Francois Marier.
diff --git a/doc/devblog/day_3__gcrypt_uuids.mdwn b/doc/devblog/day_3__gcrypt_uuids.mdwn
new file mode 100644
index 000000000..3182aca63
--- /dev/null
+++ b/doc/devblog/day_3__gcrypt_uuids.mdwn
@@ -0,0 +1,63 @@
+Started work on [gcrypt](https://github.com/blake2-ppc/git-remote-gcrypt)
+support.
+
+The first question is, should git-annex leave it up to gcrypt to transport
+the data to the encrypted repository on a push/pull? gcrypt hooks into git
+nicely to make that just work. However, if I go this route, it limits
+the places the encrypted git repositores can be stored to regular git
+remotes (and rsync). The alternative is to somehow use gcrypt to
+generate/consume the data, but use the git-annex special remotes to store
+individual files. Which would allow for a git repo stored on S3, etc.
+For now, I am going with the simple option, but I have not ruled out
+trying to make the latter work. It seems it would need changes to gcrypt
+though.
+
+Next question: Given a remote that uses gcrypt, how do I determine the
+annex.uuid of that repository. I found a nice solutuon to this. gcrypt has
+its own gcrypt-id, and I convert it to a UUID in a
+[[reproducible, and even standards-compliant way|design/gcrypt]]. So
+the same encrypted remote will automatically get the same annex.uuid
+wherever it's used. Nice. Does mean that git-annex cannot find a uuid
+until `git pull` or `git push` has been used, to let gcrypt get the
+gcrypt-id. Implemented that.
+
+The next step is actually making git-annex store data on gcrypt remotes.
+And it needs to store it encrypted of course. It seems best to avoid
+needing a `git annex initremote` for these gcrypt remotes, and just have
+git-annex automatically encrypt data stored on them. But I don't
+know. Without initializing them like a special remote is, I'm limited to
+using the gpg keys that gcrypt is configured to encrypt to, and cannot use
+the regular git-annex hybrid encryption scheme. Also, I need to generate
+and store a nonce anyway to HMAC ecrypt keys. (Or modify gcrypt
+to put enough entropy in gcrypt-id that I can use it?)
+
+Another concern I have is that gcrypt's own encryption scheme is simply
+to use a list of public keys to encrypt to. It would be nicer if the
+full set of git-annex encryption schemes could be used. Then the webapp
+could use shared encryption to avoid needing to make the user set up a gpg
+key, or hybrid encryption could be used to add keys later, etc.
+
+But I see why gcrypt works the way it does. Otherwise, you can't make an
+encrypted repo with a friend set as one of the particpants and have them be
+able to git clone it. Both hybrid and shared encryption store a secret
+inside the repo, which is not accessible if it's encrypted using that
+secret. There are use cases where not being able to blindly clone a gcrypt
+repo would be ok. For example, you use the assistant to pair with a friend
+and then set up an encrypted repo in the cloud for both of you to use.
+
+Anyway, for now, I will need to deal with
+setting up gpg keys etc in the assistant. I don't want to tackle
+full [[design/assistant/gpgkeys]] yet. Instead, I think I will start by
+adding some simple stuff to the assistant:
+
+* When adding a USB drive, offer to encrypt the repository on the drive
+ so that only you can see it.
+* When adding a ssh remote make a similar offer.
+* Add a UI to add an arbitrary git remote with encryption.
+ Let the user paste in the url to an empty remote they have,
+ which could be to eg github. (In most cases this won't be used for
+ annexed content..)
+* When the user has no gpg key, prompt to set one up. (Securely!)
+* Maybe have an interface to add another gpg key that can access the gcrypt
+ repo. Note that this will need to re-encrypt and re-push the whole
+ git history.
diff --git a/doc/devblog/day_40__another_fine_mess.mdwn b/doc/devblog/day_40__another_fine_mess.mdwn
new file mode 100644
index 000000000..dfe5bc564
--- /dev/null
+++ b/doc/devblog/day_40__another_fine_mess.mdwn
@@ -0,0 +1,15 @@
+Solid day of working on repository recovery. Got `git recover-repository
+--force` working, which involves fixing up branches that refer to missing
+objects. Mostly straightforward traversal of git commits, trees, blobs, to
+find when a branch has a problem, and identify an old version of it that
+predates the missing object. (Can also find them in the reflog.)
+
+The main complication turned out to be that `git branch -D` and `git
+show-ref` don't behave very well when the commit objects pointed to by refs
+are themselves missing. And git has no low-level plumbing that avoids
+falling over these problems, so I had to write it myself.
+
+Testing has turned up one unexpected problem: Git's index can itself refer
+to missing objects, and that will break future commits, etc. So I need to
+find a way to validate the index, and when it's got problems,
+either throw it out, or possibly recover some of the staged data from it.
diff --git a/doc/devblog/day_41__onward.mdwn b/doc/devblog/day_41__onward.mdwn
new file mode 100644
index 000000000..fd393b734
--- /dev/null
+++ b/doc/devblog/day_41__onward.mdwn
@@ -0,0 +1,17 @@
+I think that git-recover-repository is ready now. Made it deal with the
+index file referencing corrupt objects. The best approach I could think of
+for that is to just remove those objects from the index, so the user can
+re-add files from their work tree after recovery.
+
+Now to integrate this git repository repair capability into the git-annex
+assistant. I decided to run `git fsck` as part of a scheduled
+repository consistency check. It may also make sense for the assistant to
+notice when things are going wrong, and suggest an immediate check. I've
+started on the webapp UI to run a repository repair when fsck detects
+problems.
+
+[[!img /assistant/brokenrepositoryalert.png]]
+
+[[!img /assistant/repairrepository.png]]
+
+[[!meta title="the user interface I hope noone ever sees"]]
diff --git a/doc/devblog/day_41__onward/comment_1_a716c7b5a9ea3c949ff047cfb4e9a0a4._comment b/doc/devblog/day_41__onward/comment_1_a716c7b5a9ea3c949ff047cfb4e9a0a4._comment
new file mode 100644
index 000000000..0457a4bf0
--- /dev/null
+++ b/doc/devblog/day_41__onward/comment_1_a716c7b5a9ea3c949ff047cfb4e9a0a4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="aarone"
+ ip="2607:f470:8:d008:290:f5ff:fec3:a9e6"
+ subject="Email alert"
+ date="2013-10-22T21:23:24Z"
+ content="""
+I have at least one git-annex repository where I seldom open the web UI, but rather have the assistant humming along in the background. I think for my use case it would be best to receive an email notification that the assistant had detected a problem, which would prompt me to open the web UI and perform the recovery.
+"""]]
diff --git a/doc/devblog/day_41__onward/comment_2_33149e424cd5f03fac376288bcc4dfdc._comment b/doc/devblog/day_41__onward/comment_2_33149e424cd5f03fac376288bcc4dfdc._comment
new file mode 100644
index 000000000..fd26f9290
--- /dev/null
+++ b/doc/devblog/day_41__onward/comment_2_33149e424cd5f03fac376288bcc4dfdc._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="64.134.31.139"
+ subject="excellent idea"
+ date="2013-10-22T22:13:58Z"
+ content="""
+Added to my todo. I think it would require the system have an MTA though, I really don't want git-annex to grow to the point it can send email. ;)
+"""]]
diff --git a/doc/devblog/day_41__onward/comment_3_3b07503bd79089ad3ce3ddd7535ed116._comment b/doc/devblog/day_41__onward/comment_3_3b07503bd79089ad3ce3ddd7535ed116._comment
new file mode 100644
index 000000000..1116b4d1b
--- /dev/null
+++ b/doc/devblog/day_41__onward/comment_3_3b07503bd79089ad3ce3ddd7535ed116._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://jasonwoof.com/"
+ nickname="JasonWoof"
+ subject="Please check if it needs help from the user first"
+ date="2013-10-23T23:30:10Z"
+ content="""
+Awesome that you're working on recovery, and recovery automation!
+
+Please only bother the user if there is a serious problem _and_ it can't be fixed without their help. Otherwise I fear people will learn to ignore your dialog boxes, like they do most dialog boxes. If you want to notify your user that some hard drive corruption happened (and it's been fixed already) then put a little yellow/orange line across somewhere with a warning message.
+
+When I read to the part about how it can (probably) be fixed automatically, I got a flash of annoyance and thought \"well, then fix it automatically, why are you bothering me?\"
+
+Please (if you aren't already) check if it can be automatically fixed without help from the user before telling the user about it. Then you can say \"The data to fix this could not be reached, please plug in another repo or something.\"
+"""]]
diff --git a/doc/devblog/day_42__repair_milestone.mdwn b/doc/devblog/day_42__repair_milestone.mdwn
new file mode 100644
index 000000000..61a1bea27
--- /dev/null
+++ b/doc/devblog/day_42__repair_milestone.mdwn
@@ -0,0 +1,35 @@
+The webapp now fully handles repairing damage to the repository.
+
+Along with all the git repository repair stuff already built, I added
+additional repairs of the git-annex branch and git-annex's index file.
+That was pretty easy actually, since git-annex already handles merging
+git-annex branches that can sometimes be quite out of date. So when git repo
+repair has to throw away recent changes to the git-annex branch, it just
+effectively becomes out of date. Added a `git annex fsck --fast` run to
+ensure that the git-annex branch reflects the current state of the
+repository.
+
+When the webapp runs a repair, it first stops the assistant from committing
+new files. Once the repair is done, that's started back up, and it runs a
+startup scan, which is just what is needed in this sitation; it will add
+any new files, as well as any old files that the git repository damange
+caused to be removed from the index.
+
+Also made `git annex repair` run the git repository repair code,
+for those with a more command-line bent. It can be used in non-git-annex
+repos too!
+
+----
+
+So, I'm nearly ready to wrap up working on disaster recovery. Lots has been
+accomplished this month. And I have put off making a release for entirely
+too long!
+
+The big missing piece is repair of git remotes located on removable drive.
+I may make a release before adding that, but removable drives are probably
+where git repository corruption is most likely to occur, so I certainly
+need to add that.
+
+----
+
+Today's work was sponsored by Scott Robinson.
diff --git a/doc/devblog/day_43__bugfix_day.mdwn b/doc/devblog/day_43__bugfix_day.mdwn
new file mode 100644
index 000000000..ad150f512
--- /dev/null
+++ b/doc/devblog/day_43__bugfix_day.mdwn
@@ -0,0 +1,26 @@
+Got well caught up on bug fixes and traffic. Backlog is down to 40.
+
+Made the assistant wait for a few seconds before doing the startup
+scan when it's autostarted, since the desktop is often busy starting
+up at that same time.
+
+Fixed an ugly bug with chunked webdav and directory special remotes
+that caused it to not write a "chunkcount" file when storing data,
+so it didn't think the data was present later. I was able to make it
+recover nicely from that mistake, by probing for what chunks are actually
+present.
+
+Several people turn out to have had problems with `git annex sync` not
+working because receive.denyNonFastForwards is enabled. I made the webapp
+not enable it when setting up a ssh repository, and I made `git annex sync`
+print out a hint about this when it's failed to push. (I don't think this
+problem affects the assistant's own syncing.)
+
+Made the assistant try to repair a damaged git repository without
+prompting. It will only prompt when it fails to fetch all the lost
+objects from remotes.
+
+Glad to see that others have managed to
+[get git-annex to build on Max OS X 10.9](http://git-annex.branchable.com/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/#comment-8e8ee5e50506a6fde029d236f4809df8).
+Now I just need someone to offer up a ssh account on that OS, and I could
+set up an autobuilder for it.
diff --git a/doc/devblog/day_44__automatic_removable_drive_repair.mdwn b/doc/devblog/day_44__automatic_removable_drive_repair.mdwn
new file mode 100644
index 000000000..444cf5f2e
--- /dev/null
+++ b/doc/devblog/day_44__automatic_removable_drive_repair.mdwn
@@ -0,0 +1,16 @@
+Finally got the assistant to repair git repositories on removable drives,
+or other local repos. Mostly this happens entirely automatically, whatever
+data in the git repo on the drive has been corrupted can just be copied
+to it from `~/annex/.git`.
+
+And, the assistant will launch a git fsck of such a repo whenever it fails
+to sync with it, so the user does not even need to schedule periodic fscks.
+Although it's still a good idea, since some git repository problems don't
+prevent syncing from happening.
+
+Watching git annex heal problems like this is quite cool!
+
+One thing I had to defer till later is repairing corrupted gcrypt
+repositories. I don't see a way to do it without deleting all the objects
+in the gcrypt repository, and re-pushing everything. And even doing that
+is tricky, since the `gcrypt-id` needs to stay the same.
diff --git a/doc/devblog/day_45__command_line.mdwn b/doc/devblog/day_45__command_line.mdwn
new file mode 100644
index 000000000..fa6a7ffc7
--- /dev/null
+++ b/doc/devblog/day_45__command_line.mdwn
@@ -0,0 +1,9 @@
+All command line stuff today..
+
+Added --want-get and --want-drop, which can be used to test preferred content settings
+of a repository. For example `git annex find --in . --want-drop` will list the same
+files that `git annex drop --auto` would try to drop. (Also renamed `git annex content`
+to `git annex wanted`.)
+
+Finally laid to rest problems with `git annex unannex` when multiple files point to the
+same key. It's a lot slower, but I'll stop getting bug reports about that.
diff --git a/doc/devblog/day_46__wrapping_up_the_month.mdwn b/doc/devblog/day_46__wrapping_up_the_month.mdwn
new file mode 100644
index 000000000..c6045178c
--- /dev/null
+++ b/doc/devblog/day_46__wrapping_up_the_month.mdwn
@@ -0,0 +1,18 @@
+Spent today reviewing my [[plans_for_the_month|assistant/disaster_recovery]]
+and filling in a couple of missing peices.
+
+Noticed that I had forgotten to make repository repair clean up any stale
+git locks, despite writing that code at the beginning of the month, and
+added that in.
+
+Made the webapp notice when a repository that is being used does not have
+any consistency checks configured, and encourage the user to set up checks.
+This happens when the assistant is started (for the local repository),
+and when removable drives containing repositories are plugged in. If the
+reminders are annoying, they can be disabled with a couple clicks.
+
+And I think that just about wraps up the month. (If I get a chance, I would
+still like to add recovery of git-remote-gcrypt encrypted git repositories.)
+
+My [[design/roadmap]] has next month dedicated to user-driven features
+and polishing and bugfixing.
diff --git a/doc/devblog/day_47__fell_off_the_blogging_wagon.mdwn b/doc/devblog/day_47__fell_off_the_blogging_wagon.mdwn
new file mode 100644
index 000000000..fd312a0d8
--- /dev/null
+++ b/doc/devblog/day_47__fell_off_the_blogging_wagon.mdwn
@@ -0,0 +1,3 @@
+Low activity the past couple of days. Released a new version of git-annex
+yesterday. Today fixed three bugs (including a local pairing one that was
+pretty compicated) and worked on getting caught up with traffic.
diff --git a/doc/devblog/day_48__direct_mode_guard_design.mdwn b/doc/devblog/day_48__direct_mode_guard_design.mdwn
new file mode 100644
index 000000000..c047e7f75
--- /dev/null
+++ b/doc/devblog/day_48__direct_mode_guard_design.mdwn
@@ -0,0 +1,29 @@
+I've been investigating ways to implement a [[/todo/direct_mode_guard]].
+Preventing a stray `git commit -a` or `git add` doing bad things in a
+direct mode repository seems increasingly important.
+
+First, considered moving `.git`, so git won't know it's a git repository.
+This doesn't seem *too* hard to do, but there will certainly be unexpected
+places that assume `.git` is the directory name.
+
+I dislike it more and more as I think about it though, because it moves
+direct mode git-annex toward being entirely separate from git, and I don't
+want to write my own version control system. Nor do I want to complicate
+the git ecosystem with tools needing to know about git-annex to work in
+such a repository.
+
+So, I'm happy that one of the other ideas I tried today seems quite
+promising. Just set core.bare=true in a direct mode repository. This nicely
+blocks all git commands that operate on the working tree from doing
+anything, which is just what's needed in direct mode, since they don't know
+how to handle the direct mode files. But it lets all git commands and other
+tools that don't touch the working tree continue to be used. You can even
+run `git log file` in such a repository (surprisingly!)
+
+It also gives an easy out for anyone who really wants to use git commands
+that operate on the work tree of their direct mode repository, by just
+passing `-c core.bare=false`. And it's really easy to implement in
+git-annex too -- it can just notice if a repo has core.bare and
+annex.direct both set, and pass that parameter to every git command it
+runs. I should be able to get by with only modifying 2 functions to
+implement this.
diff --git a/doc/devblog/day_48__direct_mode_guard_design/comment_1_ec0147ccc55bad3a38652383f4098a65._comment b/doc/devblog/day_48__direct_mode_guard_design/comment_1_ec0147ccc55bad3a38652383f4098a65._comment
new file mode 100644
index 000000000..3f297d505
--- /dev/null
+++ b/doc/devblog/day_48__direct_mode_guard_design/comment_1_ec0147ccc55bad3a38652383f4098a65._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://id.koumbit.net/anarcat"
+ ip="70.82.37.38"
+ subject="awesome!"
+ date="2013-11-05T15:50:15Z"
+ content="""
+`core.bare=true` seems like an awesome idea!!! it probably means this can be factored into current installs without any change too right?
+"""]]
diff --git a/doc/devblog/day_49__direct_mode_guard_implementation.mdwn b/doc/devblog/day_49__direct_mode_guard_implementation.mdwn
new file mode 100644
index 000000000..ebc0dd494
--- /dev/null
+++ b/doc/devblog/day_49__direct_mode_guard_implementation.mdwn
@@ -0,0 +1,14 @@
+Long, long day coding up the direct mode guard today. About 90% of the fun
+is dealing with `receive.denyCurrentBranch` not preventing pushes that
+change the current branch, now that core.bare is set in direct mode.
+My current solution to this involves using a special branch when using
+direct mode, which nothing will ever push to (hopefully). A much nicer
+solution would be to use a `update` hook to deny pushes of the current
+branch -- but there are filesystems where repos cannot have git hooks.
+
+The test suite is falling over, but the `directguard` branch otherwise
+seems usable.
+
+----
+
+Today's work was sponsored by Carlo Matteo Capocasa.
diff --git a/doc/devblog/day_49__direct_mode_guard_implementation/comment_1_3ebe5c3f708070f164ecaf36b79f7bfc._comment b/doc/devblog/day_49__direct_mode_guard_implementation/comment_1_3ebe5c3f708070f164ecaf36b79f7bfc._comment
new file mode 100644
index 000000000..2a77d6d81
--- /dev/null
+++ b/doc/devblog/day_49__direct_mode_guard_implementation/comment_1_3ebe5c3f708070f164ecaf36b79f7bfc._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnZEanlyzay_QlEAL0CWpyZcRTyN7vay8U"
+ nickname="Carlo"
+ subject="comment 1"
+ date="2013-11-06T11:50:00Z"
+ content="""
+Thanks, Joey! I am very proud!
+"""]]
diff --git a/doc/devblog/day_4__unexpected_windows_day.mdwn b/doc/devblog/day_4__unexpected_windows_day.mdwn
new file mode 100644
index 000000000..6a448c3fc
--- /dev/null
+++ b/doc/devblog/day_4__unexpected_windows_day.mdwn
@@ -0,0 +1,10 @@
+Woke up with a pretty solid plan for gcrypt. It will be structured as a
+separate special remote, so `initremote` will be needed, with a gitrepo=
+parameter (unless the remote already exists). git-annex will then set up
+the git remote, including pushing to it (needed to get a gcrypt-id).
+
+Didn't feel up to implementing that today. Instead I expectedly spent
+the day doing mostly Windows work, including setting up a VM on my new
+laptop for development. Including a ssh server in Windows, so I can
+script local builds and tests on Windows without ever having to
+touch the desktop. Much better!
diff --git a/doc/devblog/day_50__grab_bag.mdwn b/doc/devblog/day_50__grab_bag.mdwn
new file mode 100644
index 000000000..e38ec065c
--- /dev/null
+++ b/doc/devblog/day_50__grab_bag.mdwn
@@ -0,0 +1,34 @@
+Started by tracking down a strange bug that was apparently
+ubuntu-specific and caused git-annex branch changes to get committed to
+master. Root cause turned out to failing to recover from an
+exception. I'm kicking myself about that, because I remember looking at the
+code where the bug was at least twice before and thinking "hmm, should add
+exception handling here? nah..". Exceptions are horrible.
+
+Made a release with a fix for that and a few minor other accumulated
+changes since last Friday's release. The pain point of this release is to
+fix building without the webapp (so it will propigate to Debian testing,
+etc). This release does not include the direct mode guard, so I'll have a
+few weeks until the next release to get that tested.
+
+Fixed the test suite in `directguard`. This branch is now nearly ready to
+merge to master, but one command that is badly needed in guarded direct
+mode is "git status". So I am planning to rename "git annex status" to
+"git annex info", and make "git annex status" display something similar
+to "git status".
+
+Also took half an hour and added optional [[EKG]] support to git-annex.
+This is a Haskell library that can add a terrific monitoring console web
+UI to any program in 2 lines of code. Here we can see the git-annex
+webapp using resources at startup, followed in a few seconds by the
+assistant's startup scan of the repository.
+
+[[!img ekg/ekg.png]]
+
+BTW, Kevin tells me that the machine used to build git-annex for OSX is
+going to be upgraded to 10.9 soon. So, hopefully I'll be making autobuilds
+of that. I may have to stop the 10.8.2 autobuilds though.
+
+----
+
+Today's work was sponsored by [Protonet](http://protonet.info/).
diff --git a/doc/devblog/day_50__grab_bag/comment_1_01846f6494fe843889391fd09fd127a0._comment b/doc/devblog/day_50__grab_bag/comment_1_01846f6494fe843889391fd09fd127a0._comment
new file mode 100644
index 000000000..1c1717180
--- /dev/null
+++ b/doc/devblog/day_50__grab_bag/comment_1_01846f6494fe843889391fd09fd127a0._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/2grhJvAC049fJnvALDXek.6MRZMTlg--#eec89"
+ nickname="John"
+ subject="OS X builds"
+ date="2013-11-07T05:12:13Z"
+ content="""
+Joey, were you not interested in my offer of an OS X build server that I've posted elsewhere on this list, and also in e-mail to you?
+"""]]
diff --git a/doc/devblog/day_50__grab_bag/comment_2_12736014aa2c1af81e4b83072505e7d5._comment b/doc/devblog/day_50__grab_bag/comment_2_12736014aa2c1af81e4b83072505e7d5._comment
new file mode 100644
index 000000000..70d7b7cd1
--- /dev/null
+++ b/doc/devblog/day_50__grab_bag/comment_2_12736014aa2c1af81e4b83072505e7d5._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 2"
+ date="2013-11-07T16:01:00Z"
+ content="""
+John, must have missed that; can't see to find it anywhere..
+"""]]
diff --git a/doc/devblog/day_51__direct_mode_guard_finished.mdwn b/doc/devblog/day_51__direct_mode_guard_finished.mdwn
new file mode 100644
index 000000000..9c637aa94
--- /dev/null
+++ b/doc/devblog/day_51__direct_mode_guard_finished.mdwn
@@ -0,0 +1,6 @@
+Finished the direct mode guard, including the new `git annex status`
+command.
+
+Spent the rest of the day working on various bug fixes. One of them turned
+into rather a lot of work to make the webapp's UI better for git
+remotes that do not have an annex.uuid.
diff --git a/doc/devblog/day_52__slowly_but_surely.mdwn b/doc/devblog/day_52__slowly_but_surely.mdwn
new file mode 100644
index 000000000..01019355b
--- /dev/null
+++ b/doc/devblog/day_52__slowly_but_surely.mdwn
@@ -0,0 +1,5 @@
+Been chipping away at my backlog of messages, and it's down to 23 items.
+
+Finally managed to get ghc to build with a newer version of the NDK.
+This *might* mean a solution to git-annex on Android 4.2. I
+[need help with testing](http://git-annex.branchable.com/bugs/git-annex_broken_on_Android_4.3/#comment-90b82735cd6090a7765f423b743fffd3).
diff --git a/doc/devblog/day_54__android_bisection_minions.mdwn b/doc/devblog/day_54__android_bisection_minions.mdwn
new file mode 100644
index 000000000..ed86c68d0
--- /dev/null
+++ b/doc/devblog/day_54__android_bisection_minions.mdwn
@@ -0,0 +1,9 @@
+Finally found the [root cause](http://git-annex.branchable.com/bugs/git-annex_broken_on_Android_4.3/#comment-452bee7d0a816300ccb4a34f9758134e)
+of the Android 4.3/4.4 trouble, and a fix is now in place!
+
+As a bonus, it looks like I've fixed a problem accessing the
+environment on Android that had been worked around in an ugly way before.
+
+Big thanks to my remote hands Michael Alan, Sören, and subito. All
+told they ran 19 separate tests to help me narrow down this tricky
+problem, often repeating long command lines on software keyboards.
diff --git a/doc/devblog/day_54__android_bisection_minions/comment_1_bea8fbe2b87d4a4865b92fa796298fa0._comment b/doc/devblog/day_54__android_bisection_minions/comment_1_bea8fbe2b87d4a4865b92fa796298fa0._comment
new file mode 100644
index 000000000..0f8e58827
--- /dev/null
+++ b/doc/devblog/day_54__android_bisection_minions/comment_1_bea8fbe2b87d4a4865b92fa796298fa0._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmW0kg4uiMIhSHeVuvJFyo2VYMl7Qoej0s"
+ nickname="Chris"
+ subject="Woot!"
+ date="2013-11-12T15:52:48Z"
+ content="""
+Thanks for getting this fixed. I'm about to go on a long plane ride, and this will make it a lot easier for me to put movies on my tablet.
+"""]]
diff --git a/doc/devblog/day_55__fireside_porting.mdwn b/doc/devblog/day_55__fireside_porting.mdwn
new file mode 100644
index 000000000..c7469d953
--- /dev/null
+++ b/doc/devblog/day_55__fireside_porting.mdwn
@@ -0,0 +1,22 @@
+Annoyingly, the Android 4.3 fix breaks git-annex on Android 4.0 (probably
+through 4.2), so I now have two separate builds of the Android app.
+
+---
+
+Worked on Windows porting today. I've managed to get the assistant
+and watcher (but not yet webapp) to build on Windows.
+The `git annex transferrer` interface needs POSIX stuff, and seems to be
+the main thing that will need porting for Windows for the assistant to
+work, besides of course file change detection. For that, I've hooked up
+[Win32-notify](http://hackage.haskell.org/package/Win32-notify).
+
+So the watcher might work on Windows.
+At least in theory. Problem is, while all the code builds ok,
+it fails to link:
+
+ ghc.exe: could not execute: C:\Program Files (x86)\Haskell Platform\2012.4.0.0\lib/../mingw/bin/gcc.exe
+
+I wonder if this is case of too many parameters being passed?
+
+This happens both on the autobuilder and on my laptop, so I'm stuck here.
+Oh well, I was not planning to work on this anyway until February...
diff --git a/doc/devblog/day_55__fireside_porting/comment_1_d690a52db82f9594d99ae65fe51e1f1a._comment b/doc/devblog/day_55__fireside_porting/comment_1_d690a52db82f9594d99ae65fe51e1f1a._comment
new file mode 100644
index 000000000..74acc8322
--- /dev/null
+++ b/doc/devblog/day_55__fireside_porting/comment_1_d690a52db82f9594d99ae65fe51e1f1a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://nullroute.eu.org/~grawity/"
+ nickname="Mantas"
+ subject="comment 1"
+ date="2013-11-13T06:22:49Z"
+ content="""
+[ProcExp](http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx) may be useful -- it can show process-related syscalls and their return codes _(among other things like file or registry access)_ so it should tell exactly why the exec failed.
+"""]]
diff --git a/doc/devblog/day_56__git-annex_user_survey.mdwn b/doc/devblog/day_56__git-annex_user_survey.mdwn
new file mode 100644
index 000000000..8c1c67994
--- /dev/null
+++ b/doc/devblog/day_56__git-annex_user_survey.mdwn
@@ -0,0 +1,20 @@
+One of my goals for this month is to get a better sense of how git-annex is
+being used, how it's working out for people, and what areas need to be
+concentrated on. To start on that, I am doing the
+[2013 git-annex user survey](http://git-annex-survey.branchable.com/polls/2013/), similar to the git user
+surveys. I will be adding some less general polls later (suggestions for
+topics appreciated!), but you can go vote in any or all of 10 polls now.
+
+----
+
+Found a workaround for yesterday's Windows build problem. Seems that only
+cabal runs gcc in a way that fails, so `ghc --make` builds is successfully.
+However, the watcher doesn't quite work on Windows. It does get events when
+files are created, but it seems to then hang before it can add the file to
+git, or indeed finish printing out a debug log message about the event.
+This looks like it could be a problem with the threaded ghc runtime on
+Windows, or something like that.
+
+Main work today was improving the git repository repair to handle corrupt
+index files. The assistant can now start up, detect that the index file is
+corrupt, and regenerate it all automatically.
diff --git a/doc/devblog/day_57__mavericks.mdwn b/doc/devblog/day_57__mavericks.mdwn
new file mode 100644
index 000000000..1031895be
--- /dev/null
+++ b/doc/devblog/day_57__mavericks.mdwn
@@ -0,0 +1,14 @@
+The user survey is producing some interesting and useful results!
+Added two more polls: [using with](http://git-annex-survey.branchable.com/polls/2013/using_with/) and [blocking problems](http://git-annex-survey.branchable.com/polls/2013/blocking_problems/)
+(There were some load issues so if you were unable to vote yesterday, try
+again..)
+
+Worked on getting the autobuilder for OS X Mavericks set up. Eventually
+succeeded, after patching a few packages to work around a cpp that thinks
+it should parse haskell files as if they're C code.
+Also, Jimmy has resuscitated the OS X Lion autobuilder.
+
+A not too bad bug in automatic merge conflict resolution has been reported,
+so I will need to dig into that tomorrow. Didn't feel up to it today, so
+instead have been spending the remaining time finishing up a branch that
+switches the test suite to use the tasty test framework.
diff --git a/doc/devblog/day_58__urgle.mdwn b/doc/devblog/day_58__urgle.mdwn
new file mode 100644
index 000000000..f6d930d80
--- /dev/null
+++ b/doc/devblog/day_58__urgle.mdwn
@@ -0,0 +1,16 @@
+Fixed two difficult bugs with direct mode. One happened (sometimes) when a
+file was deleted and replaced with a directory by the same name and then
+those changes were merged into a direct mode repository.
+
+The other problem was that direct mode did not prevent writes to
+.git/annex/objects the way that indirect mode does, so when a file in the
+repository was not currently present, writing to the dangling symlink would
+follow it and write into the object directory.
+
+Hmm, I was going to say that it's a pity that direct mode still has so many
+bugs being found and fixed, but the last real bug fix to direct mode was
+made last May! Instead, I probably have to thank Tim for being a very
+thorough tester.
+
+Finished switching the test suite to use the tasty framework, and prepared
+tasty packages for Debian.
diff --git a/doc/devblog/day_58__urgle/comment_1_bd279f58f614b103a53215dfb0211007._comment b/doc/devblog/day_58__urgle/comment_1_bd279f58f614b103a53215dfb0211007._comment
new file mode 100644
index 000000000..0fec5fa8c
--- /dev/null
+++ b/doc/devblog/day_58__urgle/comment_1_bd279f58f614b103a53215dfb0211007._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkx5V3MTbzCXS3J7Mn9FEq8M9bPPYMkAHY"
+ nickname="Pedro"
+ subject="Is direct mode still using symlinks then?"
+ date="2013-11-16T16:28:39Z"
+ content="""
+Is direct mode still using symlinks? I see the bug I opened is still unclosed:
+
+http://git-annex.branchable.com/bugs/Direct_mode_repositories_still_use_symlinks_sometimes/
+
+Any opinion on this? This is still my main problem with replacing dropbox with git-annex.
+"""]]
diff --git a/doc/devblog/day_59__release_day.mdwn b/doc/devblog/day_59__release_day.mdwn
new file mode 100644
index 000000000..469ccec44
--- /dev/null
+++ b/doc/devblog/day_59__release_day.mdwn
@@ -0,0 +1,11 @@
+Release today, right on bi-weekly schedule. Rather startled
+at the size of the changelog for this one; along with the direct mode
+guard, it adds support for OS X Mavericks, Android 4.3/4.4, and fixes
+numerous bugs.
+
+Posted another question in the survey,
+<http://git-annex-survey.branchable.com/polls/2013/roadmap/>.
+
+Spun off git-repair as an independant package from git-annex. Of course,
+most of the source code is shared with git-annex. I need to do something
+with libraries eventually..
diff --git a/doc/devblog/day_5__gcrypt_special_remote_part_1.mdwn b/doc/devblog/day_5__gcrypt_special_remote_part_1.mdwn
new file mode 100644
index 000000000..626b5edaf
--- /dev/null
+++ b/doc/devblog/day_5__gcrypt_special_remote_part_1.mdwn
@@ -0,0 +1,7 @@
+About half way done with a gcrypt special remote. I can initremote it (the
+hard part to get working), and can send files to it. Can't yet get files
+back, or remove files, and only local repositories work so far, but this is
+enough to know it's going to be pretty nice!
+
+Did find one issue in gcrypt that I may need to develop a patch for:
+<https://github.com/blake2-ppc/git-remote-gcrypt/issues/3>
diff --git a/doc/devblog/day_60__damage_driven_development.mdwn b/doc/devblog/day_60__damage_driven_development.mdwn
new file mode 100644
index 000000000..64460e86a
--- /dev/null
+++ b/doc/devblog/day_60__damage_driven_development.mdwn
@@ -0,0 +1,36 @@
+Wrote some evil code you don't want to run today. Git.Destroyer randomly
+generates Damage, and applies it to a git repository, in a way that is
+reproducible -- applying the same Damage to clones of the same git repo
+will always yeild the same result.
+
+This let me build a test harness for git-repair, which repeatedly clones,
+damages, and repairs a repository. And when it fails, I can just ask it to
+retry after fixing the bug and it'll re-run every attempt it's logged.
+
+This is already yeilding improvements to the git-repair code.
+The first randomly constructed Damage that it failed to recover
+turned out to be a truncated index file that hid some other
+corrupted object files from being repaired.
+
+ [Damage Empty (FileSelector 1),
+ Damage Empty (FileSelector 2),
+ Damage Empty (FileSelector 3),
+ Damage Reverse (FileSelector 3),
+ Damage (ScrambleFileMode 3) (FileSelector 5),
+ Damage Delete (FileSelector 9),
+ Damage (PrependGarbage "¥SOH¥STX¥ENQ¥f¥a¥ACK¥b¥DLE¥n") (FileSelector 9),
+ Damage Empty (FileSelector 12),
+ Damage (CorruptByte 11 25) (FileSelector 6),
+ Damage Empty (FileSelector 5),
+ Damage (ScrambleFileMode 4294967281) (FileSelector 14)
+ ]
+
+I need to improve the ranges of files that it damages -- currently QuickCheck
+seems to only be selecting one of the first 20 or so files. Also, it's quite
+common that it will damage `.git/config` so badly that git thinks it's not
+a git repository anymore. I am not sure if that is something `git-repair`
+should try to deal with.
+
+---
+
+Today's work was sponsored by the WikiMedia Foundation.
diff --git a/doc/devblog/day_61__damage_driven_development__II.mdwn b/doc/devblog/day_61__damage_driven_development__II.mdwn
new file mode 100644
index 000000000..605a3878d
--- /dev/null
+++ b/doc/devblog/day_61__damage_driven_development__II.mdwn
@@ -0,0 +1,15 @@
+Pushed out a minor release of git-annex today, mostly to fix build problems
+on Debian. No strong reason to upgrade to it otherwise.
+
+Continued where I left off with the Git.Destroyer. Fixed quite a lot of
+edge cases where git repair failed due to things like a corrupted .git/HEAD
+file (this makes git think it's not in a git repository), corrupt
+git objects that have an unknown object type and so crash git hard, and
+an interesting failure mode where git fsck wants to allocate 116 GB of
+memory due to a corrupted object size header. Reported that last to the git
+list, as well as working around it.
+
+At the end of the day, I ran a test creating 10000 corrupt git
+repositories, and **all** of them were recovered! Any improvements will
+probably involve finding new ways to corrupt git repositories that my code
+can't think of. ;)
diff --git a/doc/devblog/day_62__upgrade_alerts.mdwn b/doc/devblog/day_62__upgrade_alerts.mdwn
new file mode 100644
index 000000000..0b3078563
--- /dev/null
+++ b/doc/devblog/day_62__upgrade_alerts.mdwn
@@ -0,0 +1,22 @@
+Still working on the git repair code. Improved the test suite, which found
+some more bugs, and so I've been running tests all day and occasionally
+going and fixing a bug in the repair code. The hardest part of repairing a
+git repo has turned out to be reliably determining which objects in it are
+broken. Bugs in git don't help (but the git devs are going to fix the one I
+reported).
+
+But the interesting new thing today is that I added some upgrade alert code
+to the webapp. Ideally everyone would get git-annex and other software as
+part of an OS distribution, which would include its own upgrade system --
+But the [survey](http://git-annex-survey.branchable.com/polls/2013/how_installed/)
+tells me that a quarter of installs are from the prebuilt binaries I
+distribute.
+
+So, those builds are going to be built with knowledge of an upgrade url,
+and will periodically download a small info file (over https) to see if a
+newer version is available, and show an alert.
+
+I think all that's working, though I have not yet put the info files in
+place and tested it. The actual upgrade process will be a manual
+download and reinstall, to start with, and then perhaps I'll automate it
+further, depending on how hard that is on the different platforms.
diff --git a/doc/devblog/day_62__upgrade_alerts/comment_1_cdb44aaa1d2a784a72613cbf16038f89._comment b/doc/devblog/day_62__upgrade_alerts/comment_1_cdb44aaa1d2a784a72613cbf16038f89._comment
new file mode 100644
index 000000000..cb0bfc08b
--- /dev/null
+++ b/doc/devblog/day_62__upgrade_alerts/comment_1_cdb44aaa1d2a784a72613cbf16038f89._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawniayrgSdVLUc3c6bf93VbO-_HT4hzxmyo"
+ nickname="Tobias"
+ subject="gitannex-install"
+ date="2013-11-22T07:13:02Z"
+ content="""
+To install and upgrade the prebuilt binary on Linux I use the fantastic [gitannex-install](https://github.com/zerodogg/scriptbucket/blob/master/gitannex-install) script, together with the upgrade alert this is just great.
+"""]]
diff --git a/doc/devblog/day_62__upgrade_alerts/comment_2_b08bb946e4760d7f03b45c852c745b2e._comment b/doc/devblog/day_62__upgrade_alerts/comment_2_b08bb946e4760d7f03b45c852c745b2e._comment
new file mode 100644
index 000000000..3a5ec5b7d
--- /dev/null
+++ b/doc/devblog/day_62__upgrade_alerts/comment_2_b08bb946e4760d7f03b45c852c745b2e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://id.clacke.se/"
+ nickname="clacke"
+ subject="git-annex release annex"
+ date="2013-11-25T06:15:23Z"
+ content="""
+Immediate thought: instead of an info file, why not sync a public git repo with releases annexed with URLs?
+"""]]
diff --git a/doc/devblog/day_63__leverage.mdwn b/doc/devblog/day_63__leverage.mdwn
new file mode 100644
index 000000000..6cf8acfa2
--- /dev/null
+++ b/doc/devblog/day_63__leverage.mdwn
@@ -0,0 +1,24 @@
+The difference picking the right type can make! Last night, I realized that
+the where I had a `distributionSha256sum :: String`, I should instead use
+`distributionKey :: Key`. This means that when git-annex is eventually
+downloading an upgrade, it can treat it as just another Key being
+downloaded from the web. So the webapp will show that transfer along with
+all the rest, and I can leverage tons of code for a new purpose. For
+example, it can simply fsck the key once it's downloaded to verify its
+checksum.
+
+Also, built a DistriutionUpdate program, which I'll run to generate the
+info files for a new version. And since I keep git-annex releases in a
+git-annex repo, this too leverages a lot of git-annex modules, and ended up
+being just 60 easy lines of code. The upgrade notification code is tested
+and working now.
+
+And, I made the assistant detect when the git-annex program binary is
+replaced or modified. Used my existing DirWatcher code for that. The plan
+is to restart the assistant on upgrade, although I need to add some sanity
+checks (eg, reuse the lsof code) first. And yes, this will work even for
+`apt-get upgrade`!
+
+----
+
+Today's work was sponsored by Paul Tötterman
diff --git a/doc/devblog/day_64__overkill.mdwn b/doc/devblog/day_64__overkill.mdwn
new file mode 100644
index 000000000..fd5d66f4e
--- /dev/null
+++ b/doc/devblog/day_64__overkill.mdwn
@@ -0,0 +1,31 @@
+Completely finished up with making the assistant detect when git-annex's
+binary has changed and handling the restart.
+
+It's a bit tricky because during an upgrade there can be two assistant
+daemons running at the same time, in the same repository. Although I
+disable the watcher of the old one first. Luckily, git-annex has long
+supported running multiple concurrent git-annex processes in the same
+repository.
+
+The surprisingly annoying part turned out to be how to make the webapp
+redirect the browser to the new url when it's upgraded. Particularly needed
+when automatic upgrades are enabled, since the user will not then be taking
+any action in the webapp that could result in a redirect. My solution to this
+feels like overkill; the webapp does ajax long polling until it gets an
+url, and then redirects to it. Had to write javascript code and ugh.
+
+But, that turned out to also be useful when manually restarting the webapp
+(removed some horrible old code that ran a shell script to do it before),
+and also when shutting the webapp down.
+
+[[!img assistant/downloadupgrade.png alt="assistant downloading an upgrade to itself"]]
+
+Getting back to upgrades, I have the assistant downloading the upgrade, and
+running a hook action once the key is transferred. Now all I need is some
+platform-specific code to install it. Will probably be hairy, especially on
+OSX where I need to somehow unmount the old git-annex dmg and mount the new
+one, from within a program running on the old dmg.
+
+----
+
+Today's work was sponsored by Evan Deaubl.
diff --git a/doc/devblog/day_64__overkill/comment_1_e1db7678aae37af281d31ae211677786._comment b/doc/devblog/day_64__overkill/comment_1_e1db7678aae37af281d31ae211677786._comment
new file mode 100644
index 000000000..b04af39ff
--- /dev/null
+++ b/doc/devblog/day_64__overkill/comment_1_e1db7678aae37af281d31ae211677786._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="abg"
+ ip="184.75.210.234"
+ subject="Upgrade installation in OSX"
+ date="2013-11-24T00:28:03Z"
+ content="""
+Hey,
+
+You don't have to implement any whacky DMG replacement logic for OSX upgrades. No sane user will be using the application from the DMG. They will drag the .app directory to /Applications or some non-standard location and unmount the DMG. So your upgrade logic for OSX should end up looking very similar to the upgrade logic for Linux.
+"""]]
diff --git a/doc/devblog/day_64__overkill/comment_3_f7a96f0b6d942d0b59d9d0ec1b21c4bf._comment b/doc/devblog/day_64__overkill/comment_3_f7a96f0b6d942d0b59d9d0ec1b21c4bf._comment
new file mode 100644
index 000000000..c9e76b577
--- /dev/null
+++ b/doc/devblog/day_64__overkill/comment_3_f7a96f0b6d942d0b59d9d0ec1b21c4bf._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmuh_0-Mjz7QkVz7gT_7PRpCgmMcBFkj14"
+ nickname="Wichert"
+ subject="Running from DMG is not a sane use-case"
+ date="2013-11-25T08:23:38Z"
+ content="""
+I don't think you should bother trying to support upgrades when people are running from a dmg. A DMG is just a disk image, and a format commonly used to distribute software. Running software from a DMG is not something anyone does beyond a quick first test of an application. A more reasonable thing to do, which many applications do now, is to offer to move the application from the DMG to /Applications if you detect someone is running it from a DMG.
+"""]]
diff --git a/doc/devblog/day_65__wrapping_up_upgrades.mdwn b/doc/devblog/day_65__wrapping_up_upgrades.mdwn
new file mode 100644
index 000000000..9faa31a63
--- /dev/null
+++ b/doc/devblog/day_65__wrapping_up_upgrades.mdwn
@@ -0,0 +1,5 @@
+[[!img assistant/upgradecomplete.png]]
+
+Upgrades are fully working on Linux. OSX code is written but intested and I
+thought of one bug it certainly has on my evening walk. Probably another
+hour's work left later this evening to finish it off.
diff --git a/doc/devblog/day_66__upgrade_testing.mdwn b/doc/devblog/day_66__upgrade_testing.mdwn
new file mode 100644
index 000000000..741ec494e
--- /dev/null
+++ b/doc/devblog/day_66__upgrade_testing.mdwn
@@ -0,0 +1,17 @@
+Upgrades should be working on OSX Mavericks, Linux, and sort of on Android.
+This needs more testing, so I have temporarily made the daily builds think
+they are an older version than the last git-annex release. So when you
+install a daily build, and start the webapp, it should try to upgrade
+(really downgrade) to the last release. Tests appreciated.
+
+Looking over the whole upgrade code base, it took 700 lines of code
+to build the whole thing, of which 75 are platform specific (and mostly
+come down to just 3 or 4 shell commands). Not bad..
+
+----
+
+Last night, added support for quvi 0.9, which has a completely changed
+command line interface from the 0.4 version.
+
+Plan to spend tomorrow catching up on bug reports etc and then low activity
+for rest of the week.
diff --git a/doc/devblog/day_67_thanksgiving_rush.mdwn b/doc/devblog/day_67_thanksgiving_rush.mdwn
new file mode 100644
index 000000000..7ac6ba523
--- /dev/null
+++ b/doc/devblog/day_67_thanksgiving_rush.mdwn
@@ -0,0 +1,19 @@
+My last day before thanksgiving, getting caught up with some recent bug
+reports and, quite a rush to get a lot of fixes in. Adding to the fun,
+wintery weather means very limited power today.
+
+It was a very productive day, especially for Android, which hopefully has
+XMPP working again (at least it builds..), halved the size of the package,
+etc.
+
+Fixed a stupid bug in the automatic v5 upgrade code; annex.version was not
+being set to 5, and so every git annex command was
+actually re-running the upgrade.
+
+Fixed another bug I introduced last Friday, which the test suite luckily
+caught, that broke using some local remotes in direct mode.
+
+Tracked down a behavior that makes `git annex sync` quite slow on
+filesystems that don't support symlinks. I need to switch direct mode to
+not using `git commit` at all, and use plumbing to make commits there.
+Will probably work on this over the holiday.
diff --git a/doc/devblog/day_6__gcrypt_fully_working.mdwn b/doc/devblog/day_6__gcrypt_fully_working.mdwn
new file mode 100644
index 000000000..58abdbb60
--- /dev/null
+++ b/doc/devblog/day_6__gcrypt_fully_working.mdwn
@@ -0,0 +1,8 @@
+gcrpyt is fully working now. *Most* of the examples in
+[[tips/fully_encrypted_git_repositories_with_gcrypt]] should work.
+
+A few known problems:
+
+* `git annex sync` refuses to sync with gcrypt remotes. some url parsing issue.
+* Swapping two drives with gcrypt repositories on the same mount point doesn't work yet.
+* http urls are not supported
diff --git a/doc/devblog/day_6__gcrypt_fully_working/comment_1_136bb7537a9ba93d400ce6f6ea1932ac._comment b/doc/devblog/day_6__gcrypt_fully_working/comment_1_136bb7537a9ba93d400ce6f6ea1932ac._comment
new file mode 100644
index 000000000..adb298fd3
--- /dev/null
+++ b/doc/devblog/day_6__gcrypt_fully_working/comment_1_136bb7537a9ba93d400ce6f6ea1932ac._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="spwhitton"
+ ip="82.36.235.9"
+ subject="Converting an rsync special remote to a gcrypt special remote"
+ date="2013-09-11T17:36:09Z"
+ content="""
+I'm guessing there is no way to convert an rsync special remote to a gcrypt special remote? It would be cool not to have to upload 100GB across the Atlantic again!
+"""]]
diff --git a/doc/devblog/day_6__gcrypt_fully_working/comment_2_1f8faa65bbd56a12588b43a5bc822d96._comment b/doc/devblog/day_6__gcrypt_fully_working/comment_2_1f8faa65bbd56a12588b43a5bc822d96._comment
new file mode 100644
index 000000000..a6859cf2f
--- /dev/null
+++ b/doc/devblog/day_6__gcrypt_fully_working/comment_2_1f8faa65bbd56a12588b43a5bc822d96._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.51"
+ subject="comment 2"
+ date="2013-09-12T16:53:02Z"
+ content="""
+Well, rsync and gcrypt use the same locations for annexed content, so it's theoretically possible.
+
+However, it seems a lot easier to just add a gcrypt remote and let git-annex use the existing rsync remote for the content that is already stored in it.
+"""]]
diff --git a/doc/devblog/day_7__release_day.mdwn b/doc/devblog/day_7__release_day.mdwn
new file mode 100644
index 000000000..f377bb4be
--- /dev/null
+++ b/doc/devblog/day_7__release_day.mdwn
@@ -0,0 +1,10 @@
+Got git annex sync working with gcrypt. So went ahead and made a release
+today. Lots of nice new features!
+
+Unfortunately the linux 64 bit daily build is failing, because my build
+host only has 2 gb of memory and it is no longer enough. I am looking for a
+new build host, ideally one that doesn't cost me $40/month for 3 gb of ram
+and 15 gb of disk. (Extra special ideally one that I can run multiple builds
+per day on, rather than the current situation of only building overnight to
+avoid loading the machine during the day.) Until this is sorted out, no
+new 64 bit linux builds..
diff --git a/doc/devblog/day_7__release_day/comment_1_12bb94d903868ecddb3e348c9c4afeaf._comment b/doc/devblog/day_7__release_day/comment_1_12bb94d903868ecddb3e348c9c4afeaf._comment
new file mode 100644
index 000000000..266e843fd
--- /dev/null
+++ b/doc/devblog/day_7__release_day/comment_1_12bb94d903868ecddb3e348c9c4afeaf._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/2grhJvAC049fJnvALDXek.6MRZMTlg--#eec89"
+ nickname="John"
+ subject="comment 1"
+ date="2013-09-09T21:51:47Z"
+ content="""
+Joey, I'd be happy to host 64-bit builds on both Mac and Linux using my personal Jenkins server (both machines are local and have 16+ GB of RAM). I might even be able to get you SSH jail access to the build tree for the 64-bit Linux build. Just let me know at johnw@fpcomplete.com.
+"""]]
diff --git a/doc/devblog/day_7__release_day/comment_2_d3e38d6f6bba179dab40d4d75ff061de._comment b/doc/devblog/day_7__release_day/comment_2_d3e38d6f6bba179dab40d4d75ff061de._comment
new file mode 100644
index 000000000..96fb5dce3
--- /dev/null
+++ b/doc/devblog/day_7__release_day/comment_2_d3e38d6f6bba179dab40d4d75ff061de._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/2grhJvAC049fJnvALDXek.6MRZMTlg--#eec89"
+ nickname="John"
+ subject="comment 2"
+ date="2013-09-10T23:11:27Z"
+ content="""
+Everything is all setup now to build git-annex on both systems, at most once per hour (if there have been new Git commits), and only between 2am and 4pm. Just contact me on IRC or e-mail and I'll setup you up with credentials so that you can manipulate the jobs and access the build artifacts.
+"""]]
diff --git a/doc/devblog/day_8__ill.mdwn b/doc/devblog/day_8__ill.mdwn
new file mode 100644
index 000000000..c086a9dc1
--- /dev/null
+++ b/doc/devblog/day_8__ill.mdwn
@@ -0,0 +1,20 @@
+I've been out sick. However, some things kept happening. Mesar contributed
+a build host, and the linux and android builds are now happening, hourly,
+there. (Thanks as well to the two other people who also offered hostng.)
+And I made a minor release to fix a bug in the test suite that I was pleased
+three different people reported.
+
+Today, my main work was getting git-annex to notice when a gcrypt remote
+located on some removable drive mount point is not the same gcrypt remote
+that was mounted there before. I was able to finesse this so it
+re-configures things to use the new gcrypt remote, as long as it's a
+special remote it knows about. (Otherwise it has to ignore the remote.)
+So, encrypted repos on removable drives will work just as well as
+non-encrypted repos!
+
+Also spent a while with rsync.net tech support trying to work out why
+someone's git-annex apparently opened a lot of concurrent ssh connections
+to rsync.net. Have not been able to reproduce the problem though.
+
+Also, a lot of catch-up to traffic. Still 63 messages backlogged however,
+and still not entirely well..
diff --git a/doc/devblog/day_9__Friday_the_13th.mdwn b/doc/devblog/day_9__Friday_the_13th.mdwn
new file mode 100644
index 000000000..77d9039eb
--- /dev/null
+++ b/doc/devblog/day_9__Friday_the_13th.mdwn
@@ -0,0 +1,21 @@
+Worked to get git-remote-gcrypt included in every git-annex autobuild
+bundle.
+(Except Windows; running a shell script there may need some work later..)
+
+Next I want to work on making the assistant easily able to create encrypted
+git repositories on removable drives. Which will involve a UI to select
+which gpg key to use, or creating (and backing up!) a gpg key.
+
+But, I got distracted chasing down some bugs on Windows. These were
+quite ugly; more direct mode mapping breakage which resulted in
+files not being accessible. Also fsck on Windows failed to detect and fix
+the problem. All fixed now. (If you use git-annex on Windows, you should
+certainly upgrade and run `git annex fsck`.)
+
+As with most bugs in the Windows port, the underlying cause turned out to
+be stupid: `isSymlink` always returned False on Windows. Which makes sense
+from the perspective of Windows not quite having anything entirely like
+symlinks. But failed when that was being used to detect when files in the
+git tree being merged into the repository had the symlink bit set..
+
+Did bug triage. Backlog down to 32 (mostly messages from August).
diff --git a/doc/devblog/day_9__Friday_the_13th/comment_1_07195b4ec399ba1be6c8bdb3ae0fa50b._comment b/doc/devblog/day_9__Friday_the_13th/comment_1_07195b4ec399ba1be6c8bdb3ae0fa50b._comment
new file mode 100644
index 000000000..aff4dc264
--- /dev/null
+++ b/doc/devblog/day_9__Friday_the_13th/comment_1_07195b4ec399ba1be6c8bdb3ae0fa50b._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://nullroute.eu.org/~grawity/"
+ nickname="Mantas"
+ subject="comment 1"
+ date="2013-09-13T22:05:37Z"
+ content="""
+Windows *does* have something very much like symlinks – they're called *symlinks* (\"symbolic links\") and they are meant to [\"function just like UNIX links\"][1] as the official docs say.
+
+But on the other hand, yes – `isSymlink` makes less sense on Windows, because symlinks are just a type of reparse points, and there may be several other types (e.g. directory junctions should also be treated like symlinks, but mount points shouldn't...)
+
+[1]: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365680(v=vs.85).aspx
+"""]]
diff --git a/doc/devblog/moving_blogs.mdwn b/doc/devblog/moving_blogs.mdwn
new file mode 100644
index 000000000..f6dac56c9
--- /dev/null
+++ b/doc/devblog/moving_blogs.mdwn
@@ -0,0 +1,5 @@
+I've started a new page for my devblog, since I'm not focusing extensively
+on the assistant and so keeping the blog [[here|design/assistant/blog]]
+increasingly felt wrong. Also, my new year of
+[crowdfunded development](https://campaign.joeyh.name)
+formally starts in September, so a new blog seemed good.
diff --git a/doc/devblog/moving_blogs/comment_1_6caa7e67461a6ea5de8155ae9cf75fab._comment b/doc/devblog/moving_blogs/comment_1_6caa7e67461a6ea5de8155ae9cf75fab._comment
new file mode 100644
index 000000000..46df4a7f6
--- /dev/null
+++ b/doc/devblog/moving_blogs/comment_1_6caa7e67461a6ea5de8155ae9cf75fab._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://pnijjar.livejournal.com/"
+ ip="99.236.22.229"
+ subject="comment 1"
+ date="2013-08-31T00:05:16Z"
+ content="""
+Do we need to update our RSS feeds? I appear to be getting your devblog posts in my old feed, but I do not know whether that will continue working.
+"""]]
diff --git a/doc/devblog/moving_blogs/comment_2_e3e2048fc2397b87a2f29c9fe49394cb._comment b/doc/devblog/moving_blogs/comment_2_e3e2048fc2397b87a2f29c9fe49394cb._comment
new file mode 100644
index 000000000..19b5ae1c6
--- /dev/null
+++ b/doc/devblog/moving_blogs/comment_2_e3e2048fc2397b87a2f29c9fe49394cb._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmkBwMWvNKZZCge_YqobCSILPMeK6xbFw8"
+ nickname="develop"
+ subject="comment 2"
+ date="2013-08-31T10:03:04Z"
+ content="""
+The old RSS feed will continue working.
+
+So sit back, relax, and enjoy the show.
+"""]]
diff --git a/doc/direct_mode.mdwn b/doc/direct_mode.mdwn
new file mode 100644
index 000000000..749d3a6e2
--- /dev/null
+++ b/doc/direct_mode.mdwn
@@ -0,0 +1,93 @@
+Normally, git-annex repositories consist of symlinks that are checked into
+git, and in turn point at the content of large files that is stored in
+`.git/annex/objects/`. Direct mode gets rid of the symlinks.
+
+The advantage of direct mode is that you can access files directly,
+including modifying them. The disadvantage is that most regular git
+commands cannot be used in a direct mode repository.
+
+Normally, git-annex repositories start off in indirect mode. With some
+exceptions:
+
+* Repositories created by the [[assistant]] use direct mode by default.
+* Repositories on FAT and other less than stellar filesystems
+ that don't support things like symlinks will be automatically put
+ into direct mode.
+* Windows always uses direct mode.
+
+## enabling (and disabling) direct mode
+
+Any repository can be converted to use direct mode at any time, and if you
+decide not to use it, you can convert back to indirect mode just as easily.
+Also, you can have one clone of a repository using direct mode, and another
+using indirect mode.
+
+To start using direct mode:
+
+ git annex direct
+
+To stop using direct mode:
+
+ git annex indirect
+
+## safety of using direct mode
+
+With direct mode, you're operating without large swathes of git-annex's
+carefully constructed safety net, which ensures that past versions of
+files are preserved and can be accessed.
+With direct mode, any file can be edited directly, or deleted at any time,
+and there's no guarantee that the old version is backed up somewhere else.
+
+So if you care about preserving the history of files, you're strongly
+encouraged to tell git-annex that your direct mode repository cannot be
+trusted to retain the content of a file. To do so:
+
+ git annex untrust .
+
+On the other hand, if you only care about the current versions of files,
+and are using git-annex with direct mode to keep files synchronised between
+computers, and manage your files, this should not be a concern for you.
+
+## use a direct mode repository
+
+You can use most git-annex commands as usual in a direct mode repository.
+
+Direct mode also works well with the git-annex assistant.
+
+The most important command to use in a direct mode repository is `git annex
+sync`. This will commit any files you have run `git annex add` on, as well
+as files that were added earlier and have been modified. It will push
+the changes to other repositories for `git annex sync` there to pick up,
+and will pull and merge any changes made on other repositories into the
+local repository.
+
+## what doesn't work in direct mode
+
+A very few git-annex commands don't work in direct mode, and will refuse
+to do anything. For example, `git annex unlock` doesn't make sense in
+direct mode.
+
+As for git commands, direct mode prevents using any git command that would
+modify or access the work tree. So you cannot `git commit` or `git pull`
+(use `git annex sync` for both instead), or run `git status` (use `git
+annex status` instead). These git commands will complain "fatal: This
+operation must be run in a work tree".
+
+The reason for this is that git doesn't understand how git-annex uses the
+work tree in direct mode. Where git expects the symlinks that get checked
+into git to be checked out in the work tree, direct mode instead replaces
+them with the actual content of files, as managed by git-annex.
+
+There are still lots of git commands you can use in direct mode. For
+example, you can run `git log` on files, run `git push`, `git fetch`,
+`git config`, `git remote add` etc.
+
+## forcing git to use the work tree in direct mode
+
+This is for experts only. You can lose data doing this, or check enormous
+files directly into your git repository, and it's your fault if you do!
+Also, there should be no good reason to need to do this, ever.
+
+Ok, with the warnings out of the way, all you need to do to make any
+git command access the work tree in direct mode is pass it
+`-c core.bare=false`
diff --git a/doc/direct_mode/comment_11_1c79c93f4b17cfc354ab920e3775cc60._comment b/doc/direct_mode/comment_11_1c79c93f4b17cfc354ab920e3775cc60._comment
new file mode 100644
index 000000000..ad1b66bc0
--- /dev/null
+++ b/doc/direct_mode/comment_11_1c79c93f4b17cfc354ab920e3775cc60._comment
@@ -0,0 +1,26 @@
+[[!comment format=mdwn
+ username="http://www.gl-como.it/author/valhalla/"
+ nickname="valhalla"
+ subject="Direct mode clone of an indirect repo"
+ date="2013-08-18T08:47:35Z"
+ content="""
+I too have issues with mixing direct and indirect mode repositories.
+
+ I have a regular, existing repository with ebooks, shared between various clones on proper :) filesystems; now I would need a copy of some of them on an ereader which only offers a FAT filesystem, so it has to be direct mode.
+
+ mount $READER
+ cd $reader
+ git clone $REPO
+
+I get a directory full of small files, the way git manages links on FAT.
+
+ git annex init \"ebook reader\"
+
+This detects the fact that it is working on a crippled filesystem, enables direct mode and disables ssh connection caching; up to now everything seems to be fine, but then
+
+ git annex get $SOME_BOOK
+
+seems to work, downloads the file somewhere, but when I try to open $SOME_BOOK it is still the fake link, and the file has been downloaded in its destination, as if the repo wasn't in direct mode.
+
+I use version 4.20130723 on debian jessie
+"""]]
diff --git a/doc/direct_mode/comment_12_1b5218fdb6ee362d6df68ff1229590d4._comment b/doc/direct_mode/comment_12_1b5218fdb6ee362d6df68ff1229590d4._comment
new file mode 100644
index 000000000..1743d5df9
--- /dev/null
+++ b/doc/direct_mode/comment_12_1b5218fdb6ee362d6df68ff1229590d4._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 12"
+ date="2013-08-23T17:48:54Z"
+ content="""
+There should be no obstacles to using direct mode on one clone of a git repository, and indirect mode on another clone. The data stored in git for either mode is identical, and I do this myself for some repositories.
+
+@valhalla, you probably need to run `git annex fsck`, and if that does not solve your problem, you need to file a bug report.
+"""]]
diff --git a/doc/direct_mode/comment_13_55108ac736ea450df89332ba5de4a208._comment b/doc/direct_mode/comment_13_55108ac736ea450df89332ba5de4a208._comment
new file mode 100644
index 000000000..b8d80cd7e
--- /dev/null
+++ b/doc/direct_mode/comment_13_55108ac736ea450df89332ba5de4a208._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 13"
+ date="2013-08-23T17:50:15Z"
+ content="""
+@obergix asked:
+
+> But then, how can a direct repo sync with changes made in other remotes, if there no pull/fetch available.
+
+The answer is simple: By running `git annex sync`, which handles all that.
+"""]]
diff --git a/doc/direct_mode/comment_14_ff4ffc2aabc5fd174d7386ef13860f78._comment b/doc/direct_mode/comment_14_ff4ffc2aabc5fd174d7386ef13860f78._comment
new file mode 100644
index 000000000..3a538e00b
--- /dev/null
+++ b/doc/direct_mode/comment_14_ff4ffc2aabc5fd174d7386ef13860f78._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://olivier.berger.myopenid.com/"
+ nickname="obergix"
+ subject="Git annex copy needed before git annex sync"
+ date="2013-08-23T19:59:35Z"
+ content="""
+Thanks for these details @joeyh. But AFAIU, one needs to proceed to the git annex copy before doing the git annex sync, otherwise, symlinks (or files containing the symlink path on SMB) will be created, instead of the plain \"direct\" files that are expected.
+
+I'm still not sure whether the git annex sync needs to be issued on either of the indirect or direct remotes first, or both, then in which sequence. I think a \"walkthrough\" script would help.
+"""]]
diff --git a/doc/direct_mode/comment_15_1cd32456630b25d5aaa6d2763e6eb384._comment b/doc/direct_mode/comment_15_1cd32456630b25d5aaa6d2763e6eb384._comment
new file mode 100644
index 000000000..d265118a0
--- /dev/null
+++ b/doc/direct_mode/comment_15_1cd32456630b25d5aaa6d2763e6eb384._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 15"
+ date="2013-08-24T15:56:47Z"
+ content="""
+No, you can sync before you copy, get, or whatever. git-annex will replace the symlinks with the actual files when they arrive at the repository.
+"""]]
diff --git a/doc/direct_mode/comment_3_8020d74bddf0e38b0a297e5dae7c217b._comment b/doc/direct_mode/comment_3_8020d74bddf0e38b0a297e5dae7c217b._comment
new file mode 100644
index 000000000..f89cafe53
--- /dev/null
+++ b/doc/direct_mode/comment_3_8020d74bddf0e38b0a297e5dae7c217b._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl2Jj8q2upJL4ZQAc2lp7ugTxJiGtcICv8"
+ nickname="Michael"
+ subject="comment 3"
+ date="2013-02-19T03:03:14Z"
+ content="""
+So, if I edit a \"content file\" (change a music file's metadata, say), what's the workflow to record that fact and then synchronise it to other repositories?
+
+I can't do a `git add`, so I don't understand what has to happen as a first step. (Thanks for your quick reply above, BTW.)
+
+
+"""]]
diff --git a/doc/direct_mode/comment_4_97c26bd82f623a3b2d56bab4afff0126._comment b/doc/direct_mode/comment_4_97c26bd82f623a3b2d56bab4afff0126._comment
new file mode 100644
index 000000000..cf5ae2fb6
--- /dev/null
+++ b/doc/direct_mode/comment_4_97c26bd82f623a3b2d56bab4afff0126._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.183"
+ subject="comment 4"
+ date="2013-02-19T03:05:35Z"
+ content="""
+<pre>
+git annex add $file
+git annex sync
+git annex copy $file --to otherrepo
+</pre>
+"""]]
diff --git a/doc/direct_mode/comment_5_42363bf0367f935b3eee8ad3d2eaf5cf._comment b/doc/direct_mode/comment_5_42363bf0367f935b3eee8ad3d2eaf5cf._comment
new file mode 100644
index 000000000..d4e2962a6
--- /dev/null
+++ b/doc/direct_mode/comment_5_42363bf0367f935b3eee8ad3d2eaf5cf._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="mildred"
+ ip="2a01:e35:2f7b:8350:225:22ff:fe40:fdfc"
+ subject="What happens to object database in direct mode?"
+ date="2013-07-08T13:27:21Z"
+ content="""
+What happens to the object database (`.git/annex/objects`) when going to direct mode? Are the objects deleted, moved to another location, kept?
+
+If the objects are kept, does it means that the file on the repository in direct mode is duplicated in the object database? If so, would it be relevant to use `cp --reflink=auto` to populate the working directory to enable copy on write on filesystems that supports it?
+"""]]
diff --git a/doc/direct_mode/comment_6_5f03b1686c1fb3f7606a5bc724ac3812._comment b/doc/direct_mode/comment_6_5f03b1686c1fb3f7606a5bc724ac3812._comment
new file mode 100644
index 000000000..1cdb9a79c
--- /dev/null
+++ b/doc/direct_mode/comment_6_5f03b1686c1fb3f7606a5bc724ac3812._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.254.222"
+ subject="comment 6"
+ date="2013-07-08T16:11:32Z"
+ content="""
+`.git/annex/objects` does not typically contain any file contents in direct mode. The file contents are stored directly in the working tree.
+"""]]
diff --git a/doc/direct_mode/comment_7_5355ac418bfb26e990762b80f4c36b77._comment b/doc/direct_mode/comment_7_5355ac418bfb26e990762b80f4c36b77._comment
new file mode 100644
index 000000000..d416a01f6
--- /dev/null
+++ b/doc/direct_mode/comment_7_5355ac418bfb26e990762b80f4c36b77._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://caust1c.myopenid.com/"
+ nickname="asbraithwaite"
+ subject="comment 7"
+ date="2013-08-12T18:06:21Z"
+ content="""
+Would it be safe to add largefiles to gitignore in direct mode?
+
+Can git-annex still track large files ignored by git?
+
+Thanks. :-)
+"""]]
diff --git a/doc/direct_mode/comment_8_6cd15e2c5fd0bef48f60c6993322c2fc._comment b/doc/direct_mode/comment_8_6cd15e2c5fd0bef48f60c6993322c2fc._comment
new file mode 100644
index 000000000..72ba16baf
--- /dev/null
+++ b/doc/direct_mode/comment_8_6cd15e2c5fd0bef48f60c6993322c2fc._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="arand"
+ ip="130.243.226.21"
+ subject="comment 8"
+ date="2013-08-12T18:12:32Z"
+ content="""
+asbraithwaite:
+No, as far as I know it can not.
+"""]]
diff --git a/doc/distributed_version_control.mdwn b/doc/distributed_version_control.mdwn
new file mode 100644
index 000000000..ccf82b91c
--- /dev/null
+++ b/doc/distributed_version_control.mdwn
@@ -0,0 +1,21 @@
+In git, there can be multiple clones of a repository, each clone can
+be independently modified, and clones can push or pull changes to
+one-another to get back in sync.
+
+git-annex preserves that fundamental distributed nature of git, while
+dropping the requirement that, once in sync, each clone contains all the data
+that was committed to each other clone. Instead of storing the content
+of a file in the repository, git-annex stores a pointer to the content.
+
+Each git-annex repository is responsible for storing some of the content,
+and can copy it to or from other repositories. [[Location_tracking]]
+information is committed to git, to let repositories inform other
+repositories what file contents they have available.
+
+---
+
+The [[walkthrough]] shows how to create a distributed set of git-annex
+repositories with no central repository.
+
+Prefer a central repository like GitHub? See the
+[[tips/centralized_git_repository_tutorial]].
diff --git a/doc/download.mdwn b/doc/download.mdwn
new file mode 100644
index 000000000..8c6f5b514
--- /dev/null
+++ b/doc/download.mdwn
@@ -0,0 +1,40 @@
+The main git repository for git-annex is `git://git-annex.branchable.com/`
+
+(You can push changes to this wiki from that anonymous git checkout.)
+
+Other mirrors of the git repository:
+
+* `git://git.kitenet.net/git-annex` [[gitweb](http://git.kitenet.net/?p=git-annex.git;a=summary)]
+* [at github](https://github.com/joeyh/git-annex)
+
+Releases of git-annex are uploaded
+[to hackage](http://hackage.haskell.org/package/git-annex). Get your
+tarballs there, if you need them.
+
+Some operating systems include git-annex in easily prepackaged form and
+others need some manual work. See [[install]] for details.
+
+## git branches
+
+The git repository has some branches:
+
+* `ghc7.0` supports versions of ghc older than 7.4, which
+ had a major change to filename encoding.
+* `old-monad-control` is for systems that don't have a newer monad-control
+ library.
+* `no-ifelse` avoids using the IFelse library
+ (merge it into master if you need it)
+* `no-bloom` avoids using bloom filters. (merge it into master if you need it)
+* `no-s3` avoids using the S3 library (merge it into master if you need it)
+* `debian-stable` contains the latest backport of git-annex to Debian
+ stable.
+* `tweak-fetch` adds support for the git tweak-fetch hook, which has
+ been proposed and implemented but not yet accepted into git.
+* `setup` contains configuration for this website
+* `pristine-tar` contains [pristine-tar](http://kitenet.net/~joey/code/pristine-tar)
+ data to create tarballs of any past git-annex release.
+
+----
+
+Developing git-annex? Patches are very welcome.
+You should read [[coding_style]].
diff --git a/doc/download/comment_1_ec2578241a966cfcdd43f2a26a5c8709._comment b/doc/download/comment_1_ec2578241a966cfcdd43f2a26a5c8709._comment
new file mode 100644
index 000000000..e242230a0
--- /dev/null
+++ b/doc/download/comment_1_ec2578241a966cfcdd43f2a26a5c8709._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm3uJkdiJJejvqix9dULvw_Ma7DCtB-6zA"
+ nickname="Ian"
+ subject="git clone git://git-annex.branchable.com/ gives an error"
+ date="2012-08-13T20:57:34Z"
+ content="""
+Thought you would want to know
+
+error: unable to create file doc/forum/__91__Installation__93___base-3.0.3.2_requires_syb___61____61__0.1.0.2_however_syb-0.1.0.2_was_excluded_because_json-0.5_requires_syb___62____61__0.3.3.mdwn (File name too long)
+fatal: cannot create directory at 'doc/forum/__91__Installation__93___base-3.0.3.2_requires_syb___61____61__0.1.0.2_however_syb-0.1.0.2_was_excluded_because_json-0.5_requires_syb___62____61__0.3.3': File name too long
+
+
+"""]]
diff --git a/doc/download/comment_2_ee0d158ac59903737dbc4ef632f11fe3._comment b/doc/download/comment_2_ee0d158ac59903737dbc4ef632f11fe3._comment
new file mode 100644
index 000000000..d3024217a
--- /dev/null
+++ b/doc/download/comment_2_ee0d158ac59903737dbc4ef632f11fe3._comment
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ subject="comment 2"
+ date="2012-08-16T23:28:30Z"
+ content="""
+Ok, I've renamed that long-ish filename.
+"""]]
diff --git a/doc/ekg.mdwn b/doc/ekg.mdwn
new file mode 100644
index 000000000..3bbea8614
--- /dev/null
+++ b/doc/ekg.mdwn
@@ -0,0 +1,14 @@
+You can `cabal configure -fEKG` to build a git-annex that includes
+the EKG remote monitoring interface.
+
+To access the EKG control panel, go to
+<http://localhost:4242/> while a git-annex command is running.
+
+This EKG build is mostly useful for debugging resource usage problems.
+
+[[!img ekg.png caption="git-annex webapp startup, and assistant startup scan"]]
+
+Note that since only one process can open port 4242 at a time, running
+more than one git-annex process with EKG support at the same time can
+result in some "resource busy (Address already in use)" messages -- but
+git-annex will continue to work.
diff --git a/doc/ekg/ekg.png b/doc/ekg/ekg.png
new file mode 100644
index 000000000..a8d16a2d8
--- /dev/null
+++ b/doc/ekg/ekg.png
Binary files differ
diff --git a/doc/encryption.mdwn b/doc/encryption.mdwn
new file mode 100644
index 000000000..1eba19a68
--- /dev/null
+++ b/doc/encryption.mdwn
@@ -0,0 +1,101 @@
+[[!toc]]
+
+git-annex mostly does not use encryption. Anyone with access to a git
+repository can see all the filenames in it, its history, and can access
+any annexed file contents.
+
+Encryption is needed when using [[special_remotes]] like Amazon S3, where
+file content is sent to an untrusted party who does not have access to the
+git repository.
+
+Such an encrypted remote uses strong ([[symmetric|design/encryption]] or
+asymmetric) encryption on the contents of files, as well as HMAC hashing
+of the filenames. The size of the encrypted files, and access patterns
+of the data, should be the only clues to what is stored in such a
+remote.
+
+You should decide whether to use encryption with a special remote before
+any data is stored in it. So, `git annex initremote` requires you
+to specify "encryption=none" when first setting up a remote in order
+to disable encryption. To use encryption, you run
+run `git-annex initremote` in one of these ways:
+
+* `git annex initremote newremote type=... encryption=hybrid keyid=KEYID ...`
+* `git annex initremote newremote type=... encryption=shared`
+* `git annex initremote newremote type=... encryption=pubkey keyid=KEYID ...`
+
+## hybrid encryption keys
+
+The [[hybrid_key_design|design/encryption]] allows additional
+encryption keys to be added on to a special remote later. Due to this
+flexability, it is the default and recommended encryption scheme.
+
+ git annex initremote newremote type=... [encryption=hybrid] keyid=KEYID ...
+
+Here the KEYID(s) are passed to `gpg` to find encryption keys.
+Typically, you will say "keyid=2512E3C7" to use a specific gpg key.
+Or, you might say "keyid=joey@kitenet.net" to search for matching keys.
+
+To add a new key and allow it to access all the content that is stored
+in the encrypted special remote, just run `git annex
+enableremote` specifying the new encryption key:
+
+ git annex enableremote myremote keyid+=788A3F4C
+
+While a key can later be removed from the list, note that
+that will **not** necessarily prevent the owner of the key
+from accessing data on the remote (which is by design impossible to prevent,
+short of deleting the remote). In fact the only sound use of `keyid-=` is
+probably to replace a revoked key:
+
+ git annex enableremote myremote keyid-=2512E3C7 keyid+=788A3F4C
+
+See also [[encryption_design|design/encryption]] for other security
+risks associated with encryption.
+
+## shared encryption key
+
+Alternatively, you can configure git-annex to use a shared cipher to
+encrypt data stored in a remote. This shared cipher is stored,
+**unencrypted** in the git repository. So it's shared among every
+clone of the git repository.
+
+ git annex initremote newremote type=... encryption=shared
+
+The advantage is you don't need to set up gpg keys. The disadvantage is
+that this is **insecure** unless you trust every clone of the git
+repository with access to the encrypted data stored in the special remote.
+
+## regular public key encryption
+
+This alternative simply encrypts the files in the special remotes to one or
+more public keys. It might be considered more secure due to its simplicity
+and since it's exactly the way everyone else uses gpg.
+
+ git annex initremote newremote type=.... encryption=pubkey keyid=KEYID ...
+
+A disavantage is that is not easy to later add additional public keys
+to the special remote. While the `enableremote` parameters `keyid+=` and
+`keyid-=` can be used, they have **no effect** on files that are already
+present on the remote. Probably the only use for these parameters is
+to replace a revoked key:
+
+ git annex enableremote myremote keyid-=2512E3C7 keyid+=788A3F4C
+
+But even in this case, since the files are not re-encrypted, the revoked
+key has to be kept around to be able to decrypt those files.
+(Of course, if the reason for revocation is
+that the key has been compromised, it is **insecure** to leave files
+encrypted using that old key, and the user should re-encrypt everything.)
+
+(Because filenames are MAC'ed, a cipher still needs to be
+generated (and encrypted to the given key IDs).)
+
+## MAC algorithm
+
+The default MAC algorithm to be applied on the filenames is HMACSHA1. A
+stronger one, for instance HMACSHA512, one can be chosen upon creation
+of the special remote with the option `mac=HMACSHA512`. The available
+MAC algorithms are HMACSHA1, HMACSHA224, HMACSHA256, HMACSHA384, and
+HMACSHA512. Note that it is not possible to change algorithm for a
+non-empty remote.
diff --git a/doc/encryption/comment_1_1afca8d7182075d46db41f6ad3dd5911._comment b/doc/encryption/comment_1_1afca8d7182075d46db41f6ad3dd5911._comment
new file mode 100644
index 000000000..db93bf63f
--- /dev/null
+++ b/doc/encryption/comment_1_1afca8d7182075d46db41f6ad3dd5911._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="zooko"
+ ip="75.220.153.232"
+ subject="Tahoe-LAFS comes with encryption"
+ date="2011-05-18T04:32:14Z"
+ content="""
+The Tahoe-LAFS special remote automatically encrypts and adds cryptography integrity checks/digital signatures. For that special remote you should not use the git-annex encryption scheme.
+
+Tahoe-LAFS encryption generates a new independent key for each file. This means that you can share access to one of the files without thereby sharing access to all of them, and it means that individual files can be deduplicated among multiple users.
+"""]]
diff --git a/doc/favicon.ico b/doc/favicon.ico
new file mode 100644
index 000000000..5bb405931
--- /dev/null
+++ b/doc/favicon.ico
Binary files differ
diff --git a/doc/favicon.png b/doc/favicon.png
new file mode 100644
index 000000000..1efbebdd7
--- /dev/null
+++ b/doc/favicon.png
Binary files differ
diff --git a/doc/feeds.mdwn b/doc/feeds.mdwn
new file mode 100644
index 000000000..cc63be876
--- /dev/null
+++ b/doc/feeds.mdwn
@@ -0,0 +1,4 @@
+Aggregating git-annex mentions from elsewhere on the net..
+
+* [[!aggregate expirecount=25 name="twitter" feedurl="http://tmp.kitenet.net/git-annex-twitter.rss" url="http://search.twitter.com/search.atom?q=git-annex"]]
+
diff --git a/doc/footer/column_a.mdwn b/doc/footer/column_a.mdwn
new file mode 100644
index 000000000..92c77d840
--- /dev/null
+++ b/doc/footer/column_a.mdwn
@@ -0,0 +1,7 @@
+### Recent [[news]]
+
+[[!inline pages="news/* and !*/Discussion" archive=yes show=2 feeds=no]]
+
+### [[devblog|devblog]]
+
+[[!inline pages="devblog/* and !*/Discussion" archive=yes show=5 feeds=no]]
diff --git a/doc/footer/column_b.mdwn b/doc/footer/column_b.mdwn
new file mode 100644
index 000000000..4d2d3dd98
--- /dev/null
+++ b/doc/footer/column_b.mdwn
@@ -0,0 +1,7 @@
+### Recent [[videos]]
+
+[[!inline pages="videos/* and !*/Discussion" archive=yes show=2 feeds=no]]
+
+### Recent [[forum posts|forum]]
+
+[[!inline pages="forum/* and !*/Discussion" archive=yes show=5 feeds=no]]
diff --git a/doc/forum.mdwn b/doc/forum.mdwn
new file mode 100644
index 000000000..e8a208ddf
--- /dev/null
+++ b/doc/forum.mdwn
@@ -0,0 +1,8 @@
+This is a place to discuss using git-annex.
+If you need help, advice, or anything, post about it here.
+
+But, please don't post bug reports here. Put them in [[bugs]].
+And please don't make wishlist requests here. Put them in [[todo]].
+(If you post bugs/todo here, it'll just get moved.)
+
+[[!inline pages="forum/* and !*/Discussion" archive=yes rootpage=forum postformtext="Add a new thread titled:"]]
diff --git a/doc/forum/A_question_an_the_nomad_use_cases:_files_to_fetch__44___files_to_delete__44___files_to_keep__63__.mdwn b/doc/forum/A_question_an_the_nomad_use_cases:_files_to_fetch__44___files_to_delete__44___files_to_keep__63__.mdwn
new file mode 100644
index 000000000..c6c67a291
--- /dev/null
+++ b/doc/forum/A_question_an_the_nomad_use_cases:_files_to_fetch__44___files_to_delete__44___files_to_keep__63__.mdwn
@@ -0,0 +1,12 @@
+Hello,
+
+I went through several of the questions on the forum but could not find the answer to this. I have the following scenario, which seems very similar to the nomad case.
+
+I have a server at home with many big media files. I want to keep a subset of these files on my laptop, to watch when I travel. When I'm done watching the files, I want to either delete them (i.e, they should no longer be on any machine) or archive them (i.e., they should remain on the server, but no longer be on the laptop). I think I know how to do this from the command line, but I still have a few questions.
+
+- How do I drop a file from _every_ repository? If I understood correctly, `git annex drop foo` will only drop foo locally.
+- Is it possible to follow this use case using the assistant, or should I use the command line instead (which would be very fine with me)? In particular, how do I choose the file I want to put on the laptop? (It seems `git annex get` is the command line way, is there an assistant equivalent?)
+- Can I use both the assistant and the command line at the same time? Is there a description of the command-line version of what the assistant is doing behind the scenes?
+- Can the server repository be both a "transfer" repository (to hold the files I haven't watch) and an "archive" repository (to keep the files I've watched and decided to keep), or do I need two repositories (on the server) for that?
+
+Thanks a lot for any suggestion.
diff --git a/doc/forum/A_question_an_the_nomad_use_cases:_files_to_fetch__44___files_to_delete__44___files_to_keep__63__/comment_1_fe291cd6cd8e2d5b8e23f8e3689d824b._comment b/doc/forum/A_question_an_the_nomad_use_cases:_files_to_fetch__44___files_to_delete__44___files_to_keep__63__/comment_1_fe291cd6cd8e2d5b8e23f8e3689d824b._comment
new file mode 100644
index 000000000..e29f57657
--- /dev/null
+++ b/doc/forum/A_question_an_the_nomad_use_cases:_files_to_fetch__44___files_to_delete__44___files_to_keep__63__/comment_1_fe291cd6cd8e2d5b8e23f8e3689d824b._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="64.134.31.139"
+ subject="comment 1"
+ date="2013-10-21T22:41:44Z"
+ content="""
+You can use `git annex drop foo --from remote` to drop the file from the remote. Of course, the remote has to be accessible. You can't drop files from an offline drive that's stored in a safe..
+
+What you might be looking for is `git annex drop foo; rm foo`, followed by a git commit, and then later you can run `git annex unused` on a remote and it will let you then easily drop the files you've removed from the repository. This approach of just deleting files when you're done with them also works when using the assistant.
+
+The assistant isn't really about only keeping a subset of files on your laptop. It would like to get them all, except for ones in \"archive\" directories.
+You can configure the assistant to use manual mode, and then it doesn't download any files on its own (so you have to manually `git annex get` them), but it will still handle all the other stuff the assistant does, like automatically committing and syncing changes.
+
+An archive repository wants one copy of every file that is not already stored in some other archive repository. So an archive repository could certainly be used instead of a transfer repository. (But not a small archive repository; those only want files that are moved to \"archive\" directories.) A better choice might be to make that server be a backup repository. That makes it want *every* file, no matter what, and it follows that it would archive everything, and have everything the client wants available for transferring to it.
+"""]]
diff --git a/doc/forum/A_question_an_the_nomad_use_cases:_files_to_fetch__44___files_to_delete__44___files_to_keep__63__/comment_2_f0dbc3c723999bf0f22502e3a89d1d4a._comment b/doc/forum/A_question_an_the_nomad_use_cases:_files_to_fetch__44___files_to_delete__44___files_to_keep__63__/comment_2_f0dbc3c723999bf0f22502e3a89d1d4a._comment
new file mode 100644
index 000000000..3ae6b94c5
--- /dev/null
+++ b/doc/forum/A_question_an_the_nomad_use_cases:_files_to_fetch__44___files_to_delete__44___files_to_keep__63__/comment_2_f0dbc3c723999bf0f22502e3a89d1d4a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://alan.petitepomme.net/"
+ nickname="Alan Schmitt"
+ subject="comment 2"
+ date="2013-10-23T10:06:53Z"
+ content="""
+Thank you for the suggestions and explanations. I'm using a manual repo and I find that it works quite well.
+"""]]
diff --git a/doc/forum/A_really_stupid_question.mdwn b/doc/forum/A_really_stupid_question.mdwn
new file mode 100644
index 000000000..38c7bcb56
--- /dev/null
+++ b/doc/forum/A_really_stupid_question.mdwn
@@ -0,0 +1,3 @@
+Sorry, but all this wiki and the manpage seem to gloss over the most obvious question:
+
+What happens when you commit conflicting edits in different repositories?
diff --git a/doc/forum/A_really_stupid_question/comment_1_40e02556de0b00b94f245a0196b5a89f._comment b/doc/forum/A_really_stupid_question/comment_1_40e02556de0b00b94f245a0196b5a89f._comment
new file mode 100644
index 000000000..2a400db3b
--- /dev/null
+++ b/doc/forum/A_really_stupid_question/comment_1_40e02556de0b00b94f245a0196b5a89f._comment
@@ -0,0 +1,31 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="Good question!"
+ date="2011-12-20T23:07:25Z"
+ content="""
+You get a regular git merge conflict, which can be resolved in any of the regular ways, except that conflicting files are just symlinks.
+
+Example:
+
+<pre>
+$ git pull
+...
+Auto-merging myfile
+CONFLICT (add/add): Merge conflict in myfile
+Automatic merge failed; fix conflicts and then commit the result.
+$ git status
+# On branch master
+# Your branch and 'origin/master' have diverged,
+# and have 1 and 1 different commit(s) each, respectively.
+#
+# Unmerged paths:
+# (use \"git add/rm <file>...\" as appropriate to mark resolution)
+#
+# both added: myfile
+#
+no changes added to commit (use \"git add\" and/or \"git commit -a\")
+$ git add myfile
+$ git commit -m \"took local version of the conflicting file\"
+</pre>
+"""]]
diff --git a/doc/forum/Accessing_files_directly_on__a_USB_device.mdwn b/doc/forum/Accessing_files_directly_on__a_USB_device.mdwn
new file mode 100644
index 000000000..7b16f6523
--- /dev/null
+++ b/doc/forum/Accessing_files_directly_on__a_USB_device.mdwn
@@ -0,0 +1,11 @@
+Using the assistant, I have created a repository on my laptop plus a synced repository on a USB disk. Looking into the first repository, I see my files accompanied by a .git directory. However, looking on the USB disk (e.g. /media/usb/annex), all I see is what looks like the content of a .git directory.
+
+This means that it is difficult to retrieve any file directly from this disk -- it has to be synced to another local repository first.
+
+Is there any way to change this ? E.g. to have a copy of the working tree, plus a .git directory, on the disk ?
+
+My use case: I have added plenty of media files to my repository. In addition to using the USB disk as a backup/medium for transfering these files to another computer, I'd like to be able to plug the disk to e.g. a media player and read the files directly from the tree, but it does not work at the moment.
+
+Is there anything I am missing ?
+
+Edited: yes, there is something I was missing: the forum entry at [[forum/USB_backup_with_files_visible/]]
diff --git a/doc/forum/Accessing_files_in_bare_repository.mdwn b/doc/forum/Accessing_files_in_bare_repository.mdwn
new file mode 100644
index 000000000..2ea6ba9d3
--- /dev/null
+++ b/doc/forum/Accessing_files_in_bare_repository.mdwn
@@ -0,0 +1,5 @@
+I have set up a remote server repository using the git-annex web assistant, accessed via ssh. The repository is a bare one according to the config file in the annex directory on the server.
+
+I am wondering how I could access any of the files in the repository while logged in to the server - they don't have their usual file names to look for clearly. Is there a way to get a list of the files for starters? I tried using git annex find, but it never returns any files. git annex get followed by a filename of a document in the repository also doesn't work.
+
+Thanks to help me understand better how to approach this.
diff --git a/doc/forum/Accessing_files_in_bare_repository/comment_10_7eb66e3806f9524e043fae2da9d57d64._comment b/doc/forum/Accessing_files_in_bare_repository/comment_10_7eb66e3806f9524e043fae2da9d57d64._comment
new file mode 100644
index 000000000..2b9bb8631
--- /dev/null
+++ b/doc/forum/Accessing_files_in_bare_repository/comment_10_7eb66e3806f9524e043fae2da9d57d64._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 10"
+ date="2013-05-13T04:08:14Z"
+ content="""
+I'm not sure what's up. I hope Joey can weigh in.
+
+\"git annex sync\" ought to go get the symlinks from your remote, and merge them into your master branch, which is currently checked out, so you should see them. :(
+"""]]
diff --git a/doc/forum/Accessing_files_in_bare_repository/comment_11_f0165d66865ad14f7eb5d50e900c1df4._comment b/doc/forum/Accessing_files_in_bare_repository/comment_11_f0165d66865ad14f7eb5d50e900c1df4._comment
new file mode 100644
index 000000000..abacbc30e
--- /dev/null
+++ b/doc/forum/Accessing_files_in_bare_repository/comment_11_f0165d66865ad14f7eb5d50e900c1df4._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 11"
+ date="2013-05-13T17:33:26Z"
+ content="""
+When the assistant (or git annex sync) pushes to a repository, it creates a `synced/master` branch. So your bare repository has no regular `master` branch. So when you clone it, you get a repository with no branch checked out, which is what git-annex sync complains about.
+
+There are several solutions. The easiest is to run `git merge origin/synced/master`; then your checkout will have a master branch and you can use `git annex sync` from then on.
+"""]]
diff --git a/doc/forum/Accessing_files_in_bare_repository/comment_12_0e7ea5161b6da6e9bb9425bdb953de33._comment b/doc/forum/Accessing_files_in_bare_repository/comment_12_0e7ea5161b6da6e9bb9425bdb953de33._comment
new file mode 100644
index 000000000..8d083d32d
--- /dev/null
+++ b/doc/forum/Accessing_files_in_bare_repository/comment_12_0e7ea5161b6da6e9bb9425bdb953de33._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/bBy7WkgQicYHIiiyj.Vm0TcMbxi2quzbPFef#6f9f7"
+ nickname="Frederik Vanrenterghem"
+ subject="comment 12"
+ date="2013-05-14T04:07:37Z"
+ content="""
+Thanks Joey, this worked. The symlinks are in the directory and I can get the actual file contents (except for one attempt that failed - I'll need to check why that didn't seem to have propagated to the bare repository.)
+"""]]
diff --git a/doc/forum/Accessing_files_in_bare_repository/comment_13_f804b9bf71f7d04bd23ce32d813dc340._comment b/doc/forum/Accessing_files_in_bare_repository/comment_13_f804b9bf71f7d04bd23ce32d813dc340._comment
new file mode 100644
index 000000000..470541f1d
--- /dev/null
+++ b/doc/forum/Accessing_files_in_bare_repository/comment_13_f804b9bf71f7d04bd23ce32d813dc340._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 13"
+ date="2013-06-12T18:56:39Z"
+ content="""
+Regarding my comment above, I've changed things so now `git annex sync` to a bare repository *does* push to the regular branch. So `git clone` will work without this bother.
+"""]]
diff --git a/doc/forum/Accessing_files_in_bare_repository/comment_1_6de649d38febd2240eb5b703da77c2d6._comment b/doc/forum/Accessing_files_in_bare_repository/comment_1_6de649d38febd2240eb5b703da77c2d6._comment
new file mode 100644
index 000000000..ec14394b8
--- /dev/null
+++ b/doc/forum/Accessing_files_in_bare_repository/comment_1_6de649d38febd2240eb5b703da77c2d6._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 1"
+ date="2013-05-08T13:40:16Z"
+ content="""
+Do you have git-annex available on the server from the command line?
+
+If so, the easiest way would probably be to clone the repo in git, and do a \"git annex init\" in it. This would give you a copy of the repo with none of the files in it. It would be tiny, just full of symlinks, no content. Then pull down copies of *only* the individual files you need using \"git annex get.\"
+
+Maybe set that repo to \"untrusted\" to make sure other repos don't start depending on it to store copies of files to fulfill numcopies.
+
+When you're done with a copy of a file, just \"git annex drop\" it again so it disappears from this skeletal repo.
+
+"""]]
diff --git a/doc/forum/Accessing_files_in_bare_repository/comment_2_7e8dd09915ddc3267377e900891cb02c._comment b/doc/forum/Accessing_files_in_bare_repository/comment_2_7e8dd09915ddc3267377e900891cb02c._comment
new file mode 100644
index 000000000..9c4df2f05
--- /dev/null
+++ b/doc/forum/Accessing_files_in_bare_repository/comment_2_7e8dd09915ddc3267377e900891cb02c._comment
@@ -0,0 +1,24 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/bBy7WkgQicYHIiiyj.Vm0TcMbxi2quzbPFef#6f9f7"
+ nickname="Frederik Vanrenterghem"
+ subject="comment 2"
+ date="2013-05-10T03:21:57Z"
+ content="""
+I have git-annex on the VPS. The bare repository is in the directory \"annex\"
+
+From the user's root directory, I execute:
+
+git clone annex/ Documents
+Cloning into 'Documents'...
+done.
+warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+cd Documents/
+~/Documents$ git annex init 'Documents on VPS'
+init Documents on VPS ok
+(Recording state in git...)
+
+Still, when I try to get a file now, or do a git annex find, nothing shows up.
+
+
+"""]]
diff --git a/doc/forum/Accessing_files_in_bare_repository/comment_3_80eae4a73f38d1a7e35f97c33b6401f8._comment b/doc/forum/Accessing_files_in_bare_repository/comment_3_80eae4a73f38d1a7e35f97c33b6401f8._comment
new file mode 100644
index 000000000..31aa5b1a3
--- /dev/null
+++ b/doc/forum/Accessing_files_in_bare_repository/comment_3_80eae4a73f38d1a7e35f97c33b6401f8._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="99.54.57.201"
+ subject="comment 3"
+ date="2013-05-10T04:11:22Z"
+ content="""
+OK, I'm not sure what is up, but perhaps try \"git annex sync\" and see if that gives you the treeful of symlinks that you want.
+"""]]
diff --git a/doc/forum/Accessing_files_in_bare_repository/comment_4_5ec13e98d3ecb69426e974d34f712f9b._comment b/doc/forum/Accessing_files_in_bare_repository/comment_4_5ec13e98d3ecb69426e974d34f712f9b._comment
new file mode 100644
index 000000000..720d78766
--- /dev/null
+++ b/doc/forum/Accessing_files_in_bare_repository/comment_4_5ec13e98d3ecb69426e974d34f712f9b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="99.54.57.201"
+ subject="comment 4"
+ date="2013-05-10T04:11:53Z"
+ content="""
+that is, do \"git annex sync\" from within your new clone.
+"""]]
diff --git a/doc/forum/Accessing_files_in_bare_repository/comment_5_dccbf5793998c6381e23eb8ff6497ebf._comment b/doc/forum/Accessing_files_in_bare_repository/comment_5_dccbf5793998c6381e23eb8ff6497ebf._comment
new file mode 100644
index 000000000..d89ab793e
--- /dev/null
+++ b/doc/forum/Accessing_files_in_bare_repository/comment_5_dccbf5793998c6381e23eb8ff6497ebf._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/bBy7WkgQicYHIiiyj.Vm0TcMbxi2quzbPFef#6f9f7"
+ nickname="Frederik Vanrenterghem"
+ subject="comment 5"
+ date="2013-05-10T04:23:28Z"
+ content="""
+Thanks for your help. Unfortunately that doesn't do the trick either:
+
+git annex sync
+(merging origin/git-annex into git-annex...)
+(Recording state in git...)
+commit
+ok
+git-annex: no branch is checked out
+
+After this, git annex find still yields no results.
+"""]]
diff --git a/doc/forum/Accessing_files_in_bare_repository/comment_6_42d923916232c81f3b8bdbefa34a89d3._comment b/doc/forum/Accessing_files_in_bare_repository/comment_6_42d923916232c81f3b8bdbefa34a89d3._comment
new file mode 100644
index 000000000..f33b52146
--- /dev/null
+++ b/doc/forum/Accessing_files_in_bare_repository/comment_6_42d923916232c81f3b8bdbefa34a89d3._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 6"
+ date="2013-05-10T12:52:48Z"
+ content="""
+OK, I'm going to guess the problem is there is no \"master\" branch in your cloned repository, because there is no \"master\" branch in a bare remote. (Not sure about this, just guessing.) Try \"git branch\" in your clone. If there is no \"master\" branch, that's the problem.
+
+If that's true, the right thing to do would probably have been not to clone from it, but to create a fresh git repo and then set your bare repo as a remote.
+
+You could try doing that -- create a fresh git repo, git annex init it, and then try something like \"git remote add barerepo /path/to/bare/repo\" and then \"git annex sync\" which should pull changes from the bare repo's 'synced/master' branch into your 'synced/master' branch and from there into your master branch, giving you all your symlinks.
+
+If that works you could declare your previous attempt \"dead\" and you'll be good.
+
+It *may* also be possible to just fix the clone you've got by creating a master branch, maybe by branching off of synced/master. Do a \"git branch\" and see whether synced/master exists, and just try \"git branch master synced/master\" and then \"git checkout master\" and that might do the job!
+
+But I'm just throwing ideas around here, so I hope somebody who actually knows what's going on (joey? are you there?) will pipe up.
+"""]]
diff --git a/doc/forum/Accessing_files_in_bare_repository/comment_7_43a0a7d222faee582aeb3150a59cef87._comment b/doc/forum/Accessing_files_in_bare_repository/comment_7_43a0a7d222faee582aeb3150a59cef87._comment
new file mode 100644
index 000000000..7684b0c46
--- /dev/null
+++ b/doc/forum/Accessing_files_in_bare_repository/comment_7_43a0a7d222faee582aeb3150a59cef87._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/bBy7WkgQicYHIiiyj.Vm0TcMbxi2quzbPFef#6f9f7"
+ nickname="Frederik Vanrenterghem"
+ subject="comment 7"
+ date="2013-05-12T14:04:29Z"
+ content="""
+That all sounded very plausible, but for some reason it failed to work for me. I went back to basics and tried getting there by replicating steps 1 to 3 of the walkthrough, but also to no aval. I'll still try one more thing - setting up a local repository on the VPS and syncing it to my main one over XMPP. That seems rather convoluted given the bare repository is on the same server, but who knows...
+"""]]
diff --git a/doc/forum/Accessing_files_in_bare_repository/comment_8_ec1024235c1c74c113483a833df84654._comment b/doc/forum/Accessing_files_in_bare_repository/comment_8_ec1024235c1c74c113483a833df84654._comment
new file mode 100644
index 000000000..e609a4c90
--- /dev/null
+++ b/doc/forum/Accessing_files_in_bare_repository/comment_8_ec1024235c1c74c113483a833df84654._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 8"
+ date="2013-05-12T19:06:14Z"
+ content="""
+So what *does* show up? Is your repo an empty directory? Or are the symlinks that should point to content there?
+
+as far as git goes, are you on the master branch? *is* there a master branch? If you do \"git status\" what do you see?
+
+There's no reason this shouldn't work for you....
+"""]]
diff --git a/doc/forum/Accessing_files_in_bare_repository/comment_9_c156b8c1ae0f2905566bbdb13b84e577._comment b/doc/forum/Accessing_files_in_bare_repository/comment_9_c156b8c1ae0f2905566bbdb13b84e577._comment
new file mode 100644
index 000000000..43b93b271
--- /dev/null
+++ b/doc/forum/Accessing_files_in_bare_repository/comment_9_c156b8c1ae0f2905566bbdb13b84e577._comment
@@ -0,0 +1,37 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/bBy7WkgQicYHIiiyj.Vm0TcMbxi2quzbPFef#6f9f7"
+ nickname="Frederik Vanrenterghem"
+ subject="comment 9"
+ date="2013-05-12T23:51:16Z"
+ content="""
+I get the following:
+
+frederik@niihau:~/Documents$ git status
+# On branch master
+#
+# Initial commit
+#
+nothing to commit (create/copy files and use \"git add\" to track)
+
+And this is the config:
+
+frederik@niihau:~/Documents$ cat .git/config
+[core]
+ repositoryformatversion = 0
+ filemode = true
+ bare = false
+ logallrefupdates = true
+[remote \"origin\"]
+ fetch = +refs/heads/*:refs/remotes/origin/*
+ url = /home/frederik/annex
+ annex-uuid = 1648a298-27aa-4cb1-xx-xxx
+[annex]
+ uuid = 4406bd35-9ff7-4008-yy-yyy
+ version = 3
+[remote \"niihau\"]
+ url = /home/frederik/annex
+ fetch = +refs/heads/*:refs/remotes/niihau/*
+ annex-uuid = 1648a298-27aa-4cb1-xx-xxx
+
+Not having worked with git before, all this is still very new for me. I have 33M of data in the .git directory, mostly in objects, so it does seem to have synced something already.
+"""]]
diff --git a/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository.mdwn b/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository.mdwn
new file mode 100644
index 000000000..f09b2ea3d
--- /dev/null
+++ b/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository.mdwn
@@ -0,0 +1,28 @@
+Hi!
+
+One of my annex repository has a very strange behavior. Every `git annex` command is very slow.
+
+I'm using MacOSX Mavericks, and this repository is a network drive, mounted with Samba. It's using direct mode, and the filesystem is crippled. I use *annex* for storing huge files, for example movies. I moved some files in this directory, and used `git annex add`. It was long (as checksum was performed) and I thought that everything was OK. I tried `git log -p`, it was OK too:
+
+ new file mode 120000
+ index 0000000..e58c65a
+ --- /dev/null
+ +++ b/Movies/movie.mp4
+ @@ -0,0 +1 @@
+ +../.git/annex/objects/FK/60/SHA256E-s346858581--053dca6a842376ab8022722df306ad5
+ \ No newline at end of file
+
+However it was not. I tried to launch `git annex sync another_repo` (with *another_repo* indirect and on a local disk) and it took ages. Even `git annex list` takes ages, **on every repository linked to this one**. With `ps -A`, I found out that the issue was created by `git --git-dir=/Volumes/SAMBA_REMOTE/.git --work-tree=/Volumes/SAMBA_REMOTE -c core.bare=false checkout -q -B annex/direct/master`.
+
+**Have you ever noticed this behavior? Have I done something wrong?**
+
+Here is the output of `git annex version`:
+
+ git-annex version: 5.20131117-gbd514dc
+ build flags: Assistant Webapp Pairing Testsuite S3 WebDAV FsEvents XMPP DNS Feeds Quvi TDFA CryptoHash
+ key/value backends: SHA256E SHA1E SHA512E SHA224E SHA384E SKEIN256E SKEIN512E SHA256 SHA1 SHA512 SHA224 SHA384 SKEIN256 SKEIN512 WORM URL
+ remote types: git gcrypt S3 bup directory rsync web webdav glacier hook
+ local repository version: 4
+ default repository version: 3
+ supported repository versions: 3 5
+ upgrade supported from repository versions: 0 1 2 4
diff --git a/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/bugs/direct_mode_sync_should_avoid_git_commit.mdwn b/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/bugs/direct_mode_sync_should_avoid_git_commit.mdwn
new file mode 100644
index 000000000..ec7ce2cce
--- /dev/null
+++ b/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/bugs/direct_mode_sync_should_avoid_git_commit.mdwn
@@ -0,0 +1 @@
+See [[/bugs/direct_mode_sync_should_avoid_git_commit/]] instead.
diff --git a/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_10_06dae5709750ea1da4f7fdbee4e84efc._comment b/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_10_06dae5709750ea1da4f7fdbee4e84efc._comment
new file mode 100644
index 000000000..c8feb05b9
--- /dev/null
+++ b/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_10_06dae5709750ea1da4f7fdbee4e84efc._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.64"
+ subject="comment 10"
+ date="2013-11-26T21:48:11Z"
+ content="""
+Hmm. Seems to me that `git commit` is trying to download the whole big file from the SMB share. Perhaps just to compare it with the symlink it expects to be there?
+
+When I try this, in a large direct mode repository with some video from *my* family, `git commit` does not open the file (verified with strace), let alone read it, and so finishes in well under 1 second.
+
+Aha, I was able to reproduce `git commit` doing that with a repo on a FAT filesystem. git opens the file, and mmaps it, and I guess it proceeds to try to diff it against the symlink standin file it expected to be there.
+
+This is particularly unfortunate, since `git commit` is only, I think, doing this so that it can print out a \"Changes not staged for commit\" message. Which git-annex sync throws away. There seems to be no git commit option that disables this behavior.
+
+I think that this calls for making `git annex sync` not use `git commit` any longer, and instead manually build the commit using `git-write-tree` and `git-commit-tree`. Since I don't know if I will get to this before the thanksgiving holiday, I am creating a bug: [[bugs/direct_mode_sync_should_avoid_git_commit]]
+"""]]
diff --git a/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_11_2069c5c41882ae0a1973fb7da583b60e._comment b/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_11_2069c5c41882ae0a1973fb7da583b60e._comment
new file mode 100644
index 000000000..76ecd13c2
--- /dev/null
+++ b/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_11_2069c5c41882ae0a1973fb7da583b60e._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="TroisSinges"
+ ip="82.227.207.5"
+ subject="comment 11"
+ date="2013-11-26T21:57:52Z"
+ content="""
+Awesome! Thanks for your very efficient investigations. I'll stay tuned to the bug report.
+
+Happy Thanksgiving!
+"""]]
diff --git a/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_12_b35e3a87c30974eedd71ebe52ecbed96._comment b/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_12_b35e3a87c30974eedd71ebe52ecbed96._comment
new file mode 100644
index 000000000..282f1fb4c
--- /dev/null
+++ b/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_12_b35e3a87c30974eedd71ebe52ecbed96._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="TroisSinges"
+ ip="82.227.207.5"
+ subject="comment 12"
+ date="2013-11-27T12:08:29Z"
+ content="""
+I corrected the bug address: See [[/bugs/direct_mode_sync_should_avoid_git_commit/]]
+"""]]
diff --git a/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_13_84e026f9bda87bfd12a3769dcef77f8b._comment b/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_13_84e026f9bda87bfd12a3769dcef77f8b._comment
new file mode 100644
index 000000000..dfc0db3d2
--- /dev/null
+++ b/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_13_84e026f9bda87bfd12a3769dcef77f8b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.64"
+ subject="comment 13"
+ date="2013-11-27T12:13:04Z"
+ content="""
+thanks!
+"""]]
diff --git a/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_1_ed3534196164c6736a8dbf21c65c119d._comment b/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_1_ed3534196164c6736a8dbf21c65c119d._comment
new file mode 100644
index 000000000..ed104f488
--- /dev/null
+++ b/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_1_ed3534196164c6736a8dbf21c65c119d._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.64"
+ subject="comment 1"
+ date="2013-11-26T17:26:12Z"
+ content="""
+If you run git-annex with --debug, it will print out every command it is running. This is useful because A) I can see the commands in context and B) it includes timestamps, which is a little bit more informative than \"it took ages\". (Which can mean anything.)
+
+Anyway, I figured out the problem. Upgrade from v4 to v5 does what should be a one-time git checkout, but it seems that the auto upgrade code neglected to update annex.version, so it started doing it on every command run in a v4 repo. Fixed in git. You can work around the bug by running \"git config annex.version 5\".
+"""]]
diff --git a/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_2_1e29bcf568f02765c48f0eac6c640673._comment b/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_2_1e29bcf568f02765c48f0eac6c640673._comment
new file mode 100644
index 000000000..ab0cd9c9d
--- /dev/null
+++ b/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_2_1e29bcf568f02765c48f0eac6c640673._comment
@@ -0,0 +1,45 @@
+[[!comment format=mdwn
+ username="TroisSinges"
+ ip="82.227.207.5"
+ subject="comment 2"
+ date="2013-11-26T20:42:03Z"
+ content="""
+My problem isn't solved. I cloned the repository from my netbook to the SMD drive, and added a file in this new direct annex repository :
+
+ [3singes:/Volumes/Video/Videos/Films] $ git annex add MyFamily.mkv --debug
+ [2013-11-26 19:52:59 CET] read: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"ls-files\",\"--others\",\"--exclude-standard\",\"-z\",\"--\",\"MyFamily.mkv\"]
+ [2013-11-26 19:52:59 CET] read: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"ls-files\",\"--modified\",\"-z\",\"--\",\"MyFamily.mkv\"]
+ [2013-11-26 19:52:59 CET] chat: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"cat-file\",\"--batch\"]
+ add MyFamily.mkv [2013-11-26 19:52:59 CET] chat: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"check-attr\",\"-z\",\"--stdin\",\"annex.backend\",\"annex.numcopies\",\"--\"]
+ (checksum...) [2013-11-26 19:52:59 CET] read: gsha256sum [\"MyFamily.mkv\"]
+ [2013-11-26 20:55:35 CET] chat: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"cat-file\",\"--batch\"]
+ [2013-11-26 20:55:35 CET] chat: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"hash-object\",\"-t\",\"blob\",\"-w\",\"--stdin\",\"--no-filters\"]
+ ok
+ (Recording state in git...)
+ [2013-11-26 20:55:35 CET] feed: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"update-index\",\"-z\",\"--index-info\"]
+ [2013-11-26 20:55:35 CET] chat: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"hash-object\",\"-w\",\"--stdin-paths\",\"--no-filters\"]
+ [2013-11-26 20:55:35 CET] feed: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"update-index\",\"-z\",\"--index-info\"]
+ [2013-11-26 20:55:35 CET] read: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+ [2013-11-26 20:55:36 CET] read: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"write-tree\"]
+ [2013-11-26 20:55:36 CET] chat: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"commit-tree\",\"9bdb7b18b44020441ec8dc179e676120e769ff32\",\"-p\",\"refs/heads/git-annex\"]
+ [2013-11-26 20:55:37 CET] call: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"update-ref\",\"refs/heads/git-annex\",\"293332232ca4e7428090171b52dcc5b3b80d1df6\"]
+
+Let's try to sync to my macbookpro annex repository:
+
+ [3singes:/Volumes/Video/Videos/Films] $ git annex sync macbookpro --debug
+ [2013-11-26 20:57:48 CET] read: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"show-ref\",\"git-annex\"]
+ [2013-11-26 20:57:48 CET] read: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+ [2013-11-26 20:57:49 CET] read: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"log\",\"refs/heads/git-annex..293332232ca4e7428090171b52dcc5b3b80d1df6\",\"--oneline\",\"-n1\"]
+ [2013-11-26 20:57:49 CET] read: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"log\",\"refs/heads/git-annex..b2146cf0abc7d6a7e5c79d3b133181b56cd77461\",\"--oneline\",\"-n1\"]
+ [2013-11-26 20:57:49 CET] read: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"log\",\"refs/heads/git-annex..c2cf7488b4745d4168491d8e62f5bdc354869133\",\"--oneline\",\"-n1\"]
+ [2013-11-26 20:57:49 CET] chat: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"cat-file\",\"--batch\"]
+ [2013-11-26 20:57:49 CET] read: git [\"config\",\"--null\",\"--list\"]
+ [2013-11-26 20:57:49 CET] read: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"ls-files\",\"--stage\",\"-z\",\"--others\",\"--exclude-standard\",\"--\",\"/Volumes/Video/Videos\"]
+ [2013-11-26 20:57:50 CET] chat: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"cat-file\",\"--batch\"]
+ (Recording state in git...)
+ [2013-11-26 20:57:55 CET] feed: xargs [\"-0\",\"git\",\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"add\",\"-f\"]
+ commit
+ [2013-11-26 20:57:55 CET] read: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"commit\",\"-m\",\"git-annex automatic sync\"]
+
+Now it's 21:41 CET, and it's been stuck for circa 1 hour.
+"""]]
diff --git a/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_3_9ea6803a94b1de15079a3fa20d59c9af._comment b/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_3_9ea6803a94b1de15079a3fa20d59c9af._comment
new file mode 100644
index 000000000..f2c4fd77e
--- /dev/null
+++ b/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_3_9ea6803a94b1de15079a3fa20d59c9af._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.64"
+ subject="comment 3"
+ date="2013-11-26T20:51:59Z"
+ content="""
+The problem you reported *is* solved. You were not talking about syncing before.
+
+If your setup is such that `git commit` takes a long time to run, then `git annex sync` is also necessarily going to take a long time to run.
+"""]]
diff --git a/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_4_3fae5a7fa5d99d0eb4473adb43e7f6f5._comment b/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_4_3fae5a7fa5d99d0eb4473adb43e7f6f5._comment
new file mode 100644
index 000000000..e9b7655cf
--- /dev/null
+++ b/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_4_3fae5a7fa5d99d0eb4473adb43e7f6f5._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="TroisSinges"
+ ip="82.227.207.5"
+ subject="comment 4"
+ date="2013-11-26T20:55:39Z"
+ content="""
+Thanks for your answer. On the second part of my problem, *why* should `git commit` be slow? It's only committing a file with a line (../.git/annex/...), isn't it?
+"""]]
diff --git a/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_5_57a5b73cff480266355e75c7bdc762c2._comment b/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_5_57a5b73cff480266355e75c7bdc762c2._comment
new file mode 100644
index 000000000..51e31d9b4
--- /dev/null
+++ b/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_5_57a5b73cff480266355e75c7bdc762c2._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="TroisSinges"
+ ip="82.227.207.5"
+ subject="comment 5"
+ date="2013-11-26T21:02:17Z"
+ content="""
+Err, I read my post again, and I definitely *was* talking about syncing ;-)
+"""]]
diff --git a/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_6_bbcf5e863c8f152e1079536e9011a404._comment b/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_6_bbcf5e863c8f152e1079536e9011a404._comment
new file mode 100644
index 000000000..4640a91bf
--- /dev/null
+++ b/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_6_bbcf5e863c8f152e1079536e9011a404._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.64"
+ subject="comment 6"
+ date="2013-11-26T21:04:44Z"
+ content="""
+I think the most likely reason for git commit to be slow on your setup is that it probably rewrites .git/index. If you have a lot of files in your repository, the index file will be large and rewriting the index file will involve re-transferring it all over the network to the SMB share.
+
+It's also possible that git commit scans the whole work tree, although I don't think it should -- it's not been told to with -a.
+
+You may be able to find what's taking a long time by
+
+ strace git --git-dir=/Volumes/Video/Videos/.git --work-tree=/Volumes/Video/Videos -c core.bare=false commit -m \"git-annex automatic sync\"
+
+(or ltrace)
+"""]]
diff --git a/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_7_fdcd144c22601bdf98ff844254b0120d._comment b/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_7_fdcd144c22601bdf98ff844254b0120d._comment
new file mode 100644
index 000000000..033a1af45
--- /dev/null
+++ b/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_7_fdcd144c22601bdf98ff844254b0120d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.64"
+ subject="comment 7"
+ date="2013-11-26T21:07:12Z"
+ content="""
+If you kept your git repository on your local disk, and used a [[directory special remote|special_remotes/directory]] on the SMB share, you could then `git annex copy --to smbshare` and `git annex get --from smbshare` as desired, which would probably be much more efficient.
+"""]]
diff --git a/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_8_b77243e765b2af7ba71e963fcb5cbbb1._comment b/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_8_b77243e765b2af7ba71e963fcb5cbbb1._comment
new file mode 100644
index 000000000..273b9d8e9
--- /dev/null
+++ b/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_8_b77243e765b2af7ba71e963fcb5cbbb1._comment
@@ -0,0 +1,71 @@
+[[!comment format=mdwn
+ username="TroisSinges"
+ ip="82.227.207.5"
+ subject="comment 8"
+ date="2013-11-26T21:17:38Z"
+ content="""
+Thanks again for your answers.
+
+`.git/index` is only 30Ko big. It shouldn't be an issue, even through the network.
+
+However, I ran `lsof`, and strangely it lock the big file I added before (`/Volumes/Video/Videos/Films/MyFamily.mkv`)
+
+ COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
+ git 68047 3singes cwd DIR 46,7 16384 5152641528667254045 /Volumes/Video/Videos
+ git 68047 3singes txt REG 1,4 3035984 77501447 /Applications/git-annex.app/Contents/MacOS/bundle/git
+ git 68047 3singes txt REG 46,7 8632 9219631544499731818 /Volumes/Video/Videos/.git/objects/pack/pack-99901c82bacfa26c04f505ceb27c4af9ccda414f.idx
+ git 68047 3singes txt REG 1,4 403392 77501680 /Applications/git-annex.app/Contents/MacOS/bundle/usr/lib/libpcre.0.dylib
+ git 68047 3singes txt REG 46,7 4012 8204150806531008435 /Volumes/Video/Videos/.git/objects/pack/pack-bb60a2315b13bda720682a4213507e5ee9ba029f.idx
+ git 68047 3singes txt REG 46,7 15969 12003107822997399035 /Volumes/Video/Videos/.git/objects/pack/pack-bb60a2315b13bda720682a4213507e5ee9ba029f.pack
+ git 68047 3singes txt REG 1,4 169392 77501683 /Applications/git-annex.app/Contents/MacOS/bundle/usr/lib/libz.1.dylib
+ git 68047 3singes txt REG 1,4 2088992 77501673 /Applications/git-annex.app/Contents/MacOS/bundle/usr/lib/libiconv.2.dylib
+ git 68047 3singes txt REG 1,4 600832 72809225 /usr/lib/dyld
+ git 68047 3singes txt REG 1,4 342937194 75930310 /private/var/db/dyld/dyld_shared_cache_x86_64
+ git 68047 3singes 0u CHR 16,10 0t718314 2413 /dev/ttys010
+ git 68047 3singes 1w CHR 3,2 0t0 308 /dev/null
+ git 68047 3singes 2w CHR 3,2 0t0 308 /dev/null
+ git 68047 3singes 3u REG 46,7 0 17793593705208135594 /Volumes/Video/Videos/.git/index.lock
+ git 68047 3singes 4r REG 46,7 15581987050 12221620371912261305 /Volumes/Video/Videos/Films/MyFamily.mkv
+ git 68047 3singes 8w CHR 3,2 0t0 308 /dev/null
+
+I'm using MacOSX, so I can only use `dtrace`, which I don't know so much.
+
+**The process is over, after 1H30:**
+
+ ok
+ [2013-11-26 22:13:48 CET] read: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"symbolic-ref\",\"HEAD\"]
+ [2013-11-26 22:13:48 CET] read: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"show-ref\",\"refs/heads/annex/direct/master\"]
+ [2013-11-26 22:13:48 CET] call: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"show-ref\",\"--verify\",\"-q\",\"refs/heads/synced/master\"]
+ [2013-11-26 22:13:49 CET] read: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"log\",\"refs/heads/annex/direct/master..refs/heads/synced/master\",\"--oneline\",\"-n1\"]
+ pull macbookpro
+ [2013-11-26 22:13:49 CET] call: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"fetch\",\"macbookpro\"]
+ From /Users/3singes/Movies/NE PAS SAUVEGARDER/Videos
+ b2146cf..c2cf748 git-annex -> macbookpro/git-annex
+ [2013-11-26 22:13:50 CET] call: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"show-ref\",\"--verify\",\"-q\",\"refs/remotes/macbookpro/annex/direct/master\"]
+ [2013-11-26 22:13:50 CET] call: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"show-ref\",\"--verify\",\"-q\",\"refs/remotes/macbookpro/synced/master\"]
+ [2013-11-26 22:13:50 CET] read: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"log\",\"refs/heads/synced/master..refs/remotes/macbookpro/synced/master\",\"--oneline\",\"-n1\"]
+ ok
+ [2013-11-26 22:13:50 CET] read: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"show-ref\",\"git-annex\"]
+ [2013-11-26 22:13:50 CET] read: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+ [2013-11-26 22:13:50 CET] read: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"log\",\"refs/heads/git-annex..293332232ca4e7428090171b52dcc5b3b80d1df6\",\"--oneline\",\"-n1\"]
+ [2013-11-26 22:13:51 CET] read: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"log\",\"refs/heads/git-annex..b2146cf0abc7d6a7e5c79d3b133181b56cd77461\",\"--oneline\",\"-n1\"]
+ [2013-11-26 22:13:51 CET] read: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"log\",\"refs/heads/git-annex..c2cf7488b4745d4168491d8e62f5bdc354869133\",\"--oneline\",\"-n1\"]
+ [2013-11-26 22:13:51 CET] call: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"branch\",\"-f\",\"synced/master\"]
+ [2013-11-26 22:13:51 CET] call: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"branch\",\"-f\",\"master\"]
+ [2013-11-26 22:13:51 CET] call: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"show-ref\",\"--verify\",\"-q\",\"refs/remotes/macbookpro/synced/master\"]
+ [2013-11-26 22:13:51 CET] read: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"log\",\"refs/remotes/macbookpro/synced/master..refs/heads/synced/master\",\"--oneline\",\"-n1\"]
+ [2013-11-26 22:13:51 CET] call: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"show-ref\",\"--verify\",\"-q\",\"refs/remotes/macbookpro/git-annex\"]
+ [2013-11-26 22:13:51 CET] read: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"log\",\"refs/remotes/macbookpro/git-annex..git-annex\",\"--oneline\",\"-n1\"]
+ push macbookpro
+ [2013-11-26 22:13:52 CET] call: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"push\",\"macbookpro\",\"+git-annex:synced/git-annex\",\"annex/direct/master:synced/master\"]
+ Counting objects: 9, done.
+ Delta compression using up to 8 threads.
+ Compressing objects: 100% (4/4), done.
+ Writing objects: 100% (5/5), 440 bytes | 0 bytes/s, done.
+ Total 5 (delta 3), reused 0 (delta 0)
+ To /Users/3singes/Movies/NE PAS SAUVEGARDER/Videos
+ c2cf748..2933322 git-annex -> synced/git-annex
+ [2013-11-26 22:13:57 CET] read: git [\"--git-dir=/Volumes/Video/Videos/.git\",\"--work-tree=/Volumes/Video/Videos\",\"-c\",\"core.bare=false\",\"push\",\"macbookpro\",\"master\"]
+ ok
+
+"""]]
diff --git a/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_9_cb0815e96ee211d4778f2e7a4274e855._comment b/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_9_cb0815e96ee211d4778f2e7a4274e855._comment
new file mode 100644
index 000000000..041f3c547
--- /dev/null
+++ b/doc/forum/Actions_very_slow_on_a_direct___40__and_crippled__41___annex_repository/comment_9_cb0815e96ee211d4778f2e7a4274e855._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="TroisSinges"
+ ip="82.227.207.5"
+ subject="comment 9"
+ date="2013-11-26T21:19:42Z"
+ content="""
+I thought to a directory special remote, but it doesn't meet my needs: the SMB drive is used by a MediaCenter, so I need the working tree.
+"""]]
diff --git a/doc/forum/Add_a___34__local__34___remote.txt b/doc/forum/Add_a___34__local__34___remote.txt
new file mode 100644
index 000000000..c35a637a8
--- /dev/null
+++ b/doc/forum/Add_a___34__local__34___remote.txt
@@ -0,0 +1,13 @@
+I have been playing around with annex assistent today (way late as I am one of the Kickstarter backers) and found the following puzzling.
+
+I am running a fairly new version, my package manager calls it 4.20130323 (git-annex does not seem to have a --version switch).
+
+I have been playing around with the annex assistent webapp today and have the following questions/observations:
+
+1) The "remote" server creates a bare git repository as far as I can tell, the "local computer" probably does the right thing (but I cannot run it as the "other box" has no X or browser). Is there any way to remotely create a "local" copy (i.e. non-bare git repository, which can later be managed by the cli?)
+2) It seems like git-annex-assistent (webapp) binds to localhost, is it possible to let it bind to either a specific ip-address (or all)? (Yes, I understand the security implications, but the use-case is the box from question 2 - i.e. on local network but no X and no browser).
+3) what is being launched when I hit "files", on the video it starts a file-manager on my box nothing happens (and no errors as far as I can tell).
+
+Thank you in advance
+
+Svenne
diff --git a/doc/forum/Add_a___34__local__34___remote/comment_1_c68ad724b465c4be5243be687168c0b3._comment b/doc/forum/Add_a___34__local__34___remote/comment_1_c68ad724b465c4be5243be687168c0b3._comment
new file mode 100644
index 000000000..251e89e03
--- /dev/null
+++ b/doc/forum/Add_a___34__local__34___remote/comment_1_c68ad724b465c4be5243be687168c0b3._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-04-08T19:11:33Z"
+ content="""
+1. If you want to use the cli for managing the repository, why not `git clone` it using the cli as well? Set up a remote in your existing repository pointing at the repository you cloned, and the assistant will push changes to it. This is all that the webapp would do when creating the repository. The webapp does not set up remote non-bare repositories because unless the user is comfortable with the cli, nothing is going to keep them up-to-date.
+
+2. Setting up the assistant on a headless box is something I need to support better, indeed. I've just now made `git annex webapp --listen=IP` listen on the specified IP address, and output the URL you can connect to from the remote side. Note that this does not yet use HTTPS, so use with caution.
+
+3. It uses the `xdg-open` program to open a file manager. If `xdg-open` was not in your PATH, it would instead point the web browser at a file:/// URI as a fallback. If it seems to do nothing, this probably means `xdg-open` is in PATH but not working for some reason. Try running `xdg-open /path/to/your/repository`
+"""]]
diff --git a/doc/forum/Adding_existing_S3_bucket_to_sync_with.mdwn b/doc/forum/Adding_existing_S3_bucket_to_sync_with.mdwn
new file mode 100644
index 000000000..af138c101
--- /dev/null
+++ b/doc/forum/Adding_existing_S3_bucket_to_sync_with.mdwn
@@ -0,0 +1,16 @@
+Hello,
+
+I am just starting to learn git-annex so forgive me if this is a naive question.
+
+I have the following repositories:
+
+1. Home (laptop)
+2. Work (mac mini)
+3. S3 bucket
+4. USB drive, full backup, attached to Home laptop.
+
+I want to sync files between Home and Work via the S3 bucket. It is not clear to me how to accomplish this through the git-annex assistant. Is this possible? Are there instructions online?
+
+Thanks in advance!
+
+Scott
diff --git a/doc/forum/Adding_existing_S3_bucket_to_sync_with/comment_1_30b9a70d367dd5b8781e9a86e42d4c3e._comment b/doc/forum/Adding_existing_S3_bucket_to_sync_with/comment_1_30b9a70d367dd5b8781e9a86e42d4c3e._comment
new file mode 100644
index 000000000..d68af19f9
--- /dev/null
+++ b/doc/forum/Adding_existing_S3_bucket_to_sync_with/comment_1_30b9a70d367dd5b8781e9a86e42d4c3e._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://marco.paga.myopenid.com/"
+ ip="2001:4dd0:ff00:917b:d575:780:2c27:d982"
+ subject="Yes, it is possible"
+ date="2013-08-19T17:59:56Z"
+ content="""
+You can sync both repos. The simplest way is to have both clients signed on to jabber. This way the clients exchange information when the two are online.
+
+Additionally you need to have a cloud special remote available on both ends. The cloud repository is needed to push and retrieve data for the clients. You need to configure the cloud as a transfer reposity. The clients as - what else - client. The USB Drive can be used as a backup repository on one or both ends and perhaps even for syncing very large files around.
+"""]]
diff --git a/doc/forum/Adding_existing_S3_bucket_to_sync_with/comment_2_a8525c1a7e5f89c30c9503fe8bfed02e._comment b/doc/forum/Adding_existing_S3_bucket_to_sync_with/comment_2_a8525c1a7e5f89c30c9503fe8bfed02e._comment
new file mode 100644
index 000000000..9e1d27af4
--- /dev/null
+++ b/doc/forum/Adding_existing_S3_bucket_to_sync_with/comment_2_a8525c1a7e5f89c30c9503fe8bfed02e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://marco.paga.myopenid.com/"
+ ip="2001:4dd0:ff00:917b:d575:780:2c27:d982"
+ subject="I forgot to mention"
+ date="2013-08-19T18:01:47Z"
+ content="""
+You might want to have a look at this: https://git-annex.branchable.com/assistant/remote_sharing_walkthrough/
+"""]]
diff --git a/doc/forum/Adding_existing_S3_bucket_to_sync_with/comment_3_c3878989f74e740c0ed42f440750f3a4._comment b/doc/forum/Adding_existing_S3_bucket_to_sync_with/comment_3_c3878989f74e740c0ed42f440750f3a4._comment
new file mode 100644
index 000000000..9925f8274
--- /dev/null
+++ b/doc/forum/Adding_existing_S3_bucket_to_sync_with/comment_3_c3878989f74e740c0ed42f440750f3a4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkjQhXk8KAh9yD0p1R6QzT-Sw7FtHE3d54"
+ nickname="Scott"
+ subject="comment 3"
+ date="2013-08-19T18:03:41Z"
+ content="""
+Great thanks! I'll try it out tonight and report back.
+"""]]
diff --git a/doc/forum/Adding_existing_S3_bucket_to_sync_with/comment_4_c06cc86496f9d4c0c42a8c89aa5a7b35._comment b/doc/forum/Adding_existing_S3_bucket_to_sync_with/comment_4_c06cc86496f9d4c0c42a8c89aa5a7b35._comment
new file mode 100644
index 000000000..5e1a39713
--- /dev/null
+++ b/doc/forum/Adding_existing_S3_bucket_to_sync_with/comment_4_c06cc86496f9d4c0c42a8c89aa5a7b35._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkjQhXk8KAh9yD0p1R6QzT-Sw7FtHE3d54"
+ nickname="Scott"
+ subject="comment 4"
+ date="2013-08-20T16:18:24Z"
+ content="""
+When I try to setup my Jabber client, using my gmail address, the assistant crashes. I thought this might be due to having two-factor authentication enabled so I generated an application specific password and tried that. The assistant still crashes. The log is huge, I am not sure what would be relevant to show here.
+"""]]
diff --git a/doc/forum/Adding_existing_S3_bucket_to_sync_with/comment_5_0a1c2dd0929511ff824be8de2c8d85eb._comment b/doc/forum/Adding_existing_S3_bucket_to_sync_with/comment_5_0a1c2dd0929511ff824be8de2c8d85eb._comment
new file mode 100644
index 000000000..2c4927b19
--- /dev/null
+++ b/doc/forum/Adding_existing_S3_bucket_to_sync_with/comment_5_0a1c2dd0929511ff824be8de2c8d85eb._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://marco.paga.myopenid.com/"
+ ip="2001:4dd0:ff00:917b:f87b:5579:3820:5db"
+ subject="Please post the log"
+ date="2013-08-21T15:49:00Z"
+ content="""
+I don't know what is going wrong. It is not a bad idea to post the log information.
+
+"""]]
diff --git a/doc/forum/Adding_existing_S3_bucket_to_sync_with/comment_6_1444c2f89885f028f20a4d3ce225a403._comment b/doc/forum/Adding_existing_S3_bucket_to_sync_with/comment_6_1444c2f89885f028f20a4d3ce225a403._comment
new file mode 100644
index 000000000..21c3d80e3
--- /dev/null
+++ b/doc/forum/Adding_existing_S3_bucket_to_sync_with/comment_6_1444c2f89885f028f20a4d3ce225a403._comment
@@ -0,0 +1,23 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkjQhXk8KAh9yD0p1R6QzT-Sw7FtHE3d54"
+ nickname="Scott"
+ subject="comment 6"
+ date="2013-08-21T20:05:31Z"
+ content="""
+I tried a different approach and attempted to setup s3 at the command line. This is what I did:
+
+zombie:annex scott$ export AWS_ACCESS_KEY_ID=\"my key\"
+zombie:annex scott$ export AWS_SECRET_ACCESS_KEY=\"my secret key\"
+zombie:annex scott$ git annex initremote S3 type=S3 encryption=shared
+[2013-08-21 13:03:42 PDT] read: git [\"--git-dir=/Network/Servers/filer004/vol/office_homes/scott/annex/.git\",\"--work-tree=/Network/Servers/filer004/vol/office_homes/scott/annex\",\"show-ref\",\"git-annex\"]
+[2013-08-21 13:03:42 PDT] read: git [\"--git-dir=/Network/Servers/filer004/vol/office_homes/scott/annex/.git\",\"--work-tree=/Network/Servers/filer004/vol/office_homes/scott/annex\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+[2013-08-21 13:03:42 PDT] read: git [\"--git-dir=/Network/Servers/filer004/vol/office_homes/scott/annex/.git\",\"--work-tree=/Network/Servers/filer004/vol/office_homes/scott/annex\",\"log\",\"refs/heads/git-annex..da801570f9ed8d28e5a0cea6cc51f1a2003317d6\",\"--oneline\",\"-n1\"]
+[2013-08-21 13:03:42 PDT] read: git [\"--git-dir=/Network/Servers/filer004/vol/office_homes/scott/annex/.git\",\"--work-tree=/Network/Servers/filer004/vol/office_homes/scott/annex\",\"log\",\"refs/heads/git-annex..8015f3fed32792b558d16008d20816fab0fc50c2\",\"--oneline\",\"-n1\"]
+[2013-08-21 13:03:42 PDT] chat: git [\"--git-dir=/Network/Servers/filer004/vol/office_homes/scott/annex/.git\",\"--work-tree=/Network/Servers/filer004/vol/office_homes/scott/annex\",\"cat-file\",\"--batch\"]
+[2013-08-21 13:03:42 PDT] read: git [\"config\",\"--null\",\"--list\"]
+initremote S3 (encryption setup) [2013-08-21 13:03:42 PDT] read: gpg [\"--quiet\",\"--trust-model\",\"always\",\"--gen-random\",\"--armor\",\"2\",\"512\"]
+(shared cipher) (checking bucket...)
+git-annex: connect: does not exist (Connection refused)
+failed
+git-annex: initremote: 1 failed
+"""]]
diff --git a/doc/forum/Adding_existing_S3_bucket_to_sync_with/comment_7_1c30944010d541096baff18198a5560d._comment b/doc/forum/Adding_existing_S3_bucket_to_sync_with/comment_7_1c30944010d541096baff18198a5560d._comment
new file mode 100644
index 000000000..7e05bf59a
--- /dev/null
+++ b/doc/forum/Adding_existing_S3_bucket_to_sync_with/comment_7_1c30944010d541096baff18198a5560d._comment
@@ -0,0 +1,23 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkjQhXk8KAh9yD0p1R6QzT-Sw7FtHE3d54"
+ nickname="Scott"
+ subject="comment 7"
+ date="2013-08-21T20:07:58Z"
+ content="""
+Sorry that didnt format properly
+
+ zombie:annex scott$ export AWS_ACCESS_KEY_ID=\"key\"
+ zombie:annex scott$ export AWS_SECRET_ACCESS_KEY=\"secret\"
+ zombie:annex scott$ git annex initremote S3 type=S3 encryption=shared
+ [2013-08-21 13:03:42 PDT] read: git [\"--git-dir=/Network/Servers/filer004/vol/office_homes/scott/annex/.git\",\"--work-tree=/Network/Servers/filer004/vol/office_homes/scott/annex\",\"show-ref\",\"git-annex\"]
+ [2013-08-21 13:03:42 PDT] read: git [\"--git-dir=/Network/Servers/filer004/vol/office_homes/scott/annex/.git\",\"--work-tree=/Network/Servers/filer004/vol/office_homes/scott/annex\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+ [2013-08-21 13:03:42 PDT] read: git [\"--git-dir=/Network/Servers/filer004/vol/office_homes/scott/annex/.git\",\"--work-tree=/Network/Servers/filer004/vol/office_homes/scott/annex\",\"log\",\"refs/heads/git-annex..da801570f9ed8d28e5a0cea6cc51f1a2003317d6\",\"--oneline\",\"-n1\"]
+ [2013-08-21 13:03:42 PDT] read: git [\"--git-dir=/Network/Servers/filer004/vol/office_homes/scott/annex/.git\",\"--work-tree=/Network/Servers/filer004/vol/office_homes/scott/annex\",\"log\",\"refs/heads/git-annex..8015f3fed32792b558d16008d20816fab0fc50c2\",\"--oneline\",\"-n1\" ]
+ [2013-08-21 13:03:42 PDT] chat: git [\"--git-dir=/Network/Servers/filer004/vol/office_homes/scott/annex/.git\",\"--work-tree=/Network/Servers/filer004/vol/office_homes/scott/annex\",\"cat-file\",\"--batch\"]
+ [2013-08-21 13:03:42 PDT] read: git [\"config\",\"--null\",\"--list\"]
+ initremote S3 (encryption setup) [2013-08-21 13:03:42 PDT] read: gpg [\"--quiet\",\"--trust-model\",\"always\",\"--gen-random\",\"--armor\",\"2\",\"512\"]
+ (shared cipher) (checking bucket...)
+ git-annex: connect: does not exist (Connection refused)
+ failed
+ git-annex: initremote: 1 failed
+"""]]
diff --git a/doc/forum/Android:_is_constant_high_cpu_usage_to_be_expected__63__.mdwn b/doc/forum/Android:_is_constant_high_cpu_usage_to_be_expected__63__.mdwn
new file mode 100644
index 000000000..0392dbb38
--- /dev/null
+++ b/doc/forum/Android:_is_constant_high_cpu_usage_to_be_expected__63__.mdwn
@@ -0,0 +1,3 @@
+While running the Git Annex App on Android, the app causes a constant cpu usage of about 50% when idling. I've seen this behavior on two devices (phone and tablet) with a CM 10.1 nightly build. The app causes this high cpu usage even when it is in the background, not performing any synchronization and managing only one repository containing just one file. Unfortunately I couldn't figure out what causes the cpu usage. The daemon.log file remains unchanged and I couldn't find any other log files.
+
+Is this expected behavior or unusual high cpu usage?
diff --git a/doc/forum/Android:_is_constant_high_cpu_usage_to_be_expected__63__/comment_1_7880fc38792a1fcbf3e5c47e8bcaabce._comment b/doc/forum/Android:_is_constant_high_cpu_usage_to_be_expected__63__/comment_1_7880fc38792a1fcbf3e5c47e8bcaabce._comment
new file mode 100644
index 000000000..28f3dfb92
--- /dev/null
+++ b/doc/forum/Android:_is_constant_high_cpu_usage_to_be_expected__63__/comment_1_7880fc38792a1fcbf3e5c47e8bcaabce._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmKKg3Vmzk7KwRGRKjHVdtyoj1JfxLX6NM"
+ nickname="Tom"
+ subject="comment 1"
+ date="2013-10-01T17:38:03Z"
+ content="""
+I've had this issue as well. Saw a comment on Joey's blog that implies he knows about it and that a fix will be released soon.
+"""]]
diff --git a/doc/forum/Android:_is_constant_high_cpu_usage_to_be_expected__63__/comment_2_840fbce18b4fdec21ee557fdf52c366e._comment b/doc/forum/Android:_is_constant_high_cpu_usage_to_be_expected__63__/comment_2_840fbce18b4fdec21ee557fdf52c366e._comment
new file mode 100644
index 000000000..eaf42c9e2
--- /dev/null
+++ b/doc/forum/Android:_is_constant_high_cpu_usage_to_be_expected__63__/comment_2_840fbce18b4fdec21ee557fdf52c366e._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="64.134.31.139"
+ subject="comment 2"
+ date="2013-10-16T16:57:02Z"
+ content="""
+This was fixed.
+
+(Please file bug reports for bugs in the future, so they don't clutter up this forum once fixed.)
+"""]]
diff --git a/doc/forum/Annex_contents_just_disappeared__63__.mdwn b/doc/forum/Annex_contents_just_disappeared__63__.mdwn
new file mode 100644
index 000000000..d18e2bf91
--- /dev/null
+++ b/doc/forum/Annex_contents_just_disappeared__63__.mdwn
@@ -0,0 +1,12 @@
+Joey,
+
+I have git-annex now to manage many of the repositories on my system. I have them both on my local machine, and on a very large file server, and a backup system on the Internet.
+
+Today I went to look at a file in one of my annexes and it wasn't there. This really surprised me. But what surprised me most is that around 90% of the files in *all* of my annexes on both my local system and my file server are completely missing. Only the Internet backup system has them.
+
+How could something like this happen, when I haven't been interacting with these annexes at all during this time? Can you think of any scenario that might lead to this? This is pretty much the absolute worst case scenario for an archival data system.
+
+I am running on Mac OS X 10.8, using GHC 7.6.3 to build git-annex, and I keep my git-annex binary updated often.
+
+Thanks,
+ John
diff --git a/doc/forum/Annex_contents_just_disappeared__63__/comment_1_4ab5ca00f912c0c95fabc10f2d9600d3._comment b/doc/forum/Annex_contents_just_disappeared__63__/comment_1_4ab5ca00f912c0c95fabc10f2d9600d3._comment
new file mode 100644
index 000000000..fe4edbc27
--- /dev/null
+++ b/doc/forum/Annex_contents_just_disappeared__63__/comment_1_4ab5ca00f912c0c95fabc10f2d9600d3._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/2grhJvAC049fJnvALDXek.6MRZMTlg--#eec89"
+ nickname="John"
+ subject="comment 1"
+ date="2013-08-23T03:06:00Z"
+ content="""
+Wait, I think this comes from a backend switch. I changed my .gitattributes file at one point to read:
+
+* annex.backend=SHA512E annex.numcopies=2
+
+I thought this would just affect new files, not existing annexed content. Could this do it?
+"""]]
diff --git a/doc/forum/Annex_contents_just_disappeared__63__/comment_2_657f737c5d64d440aa133ddb41408fbc._comment b/doc/forum/Annex_contents_just_disappeared__63__/comment_2_657f737c5d64d440aa133ddb41408fbc._comment
new file mode 100644
index 000000000..e30ff02ca
--- /dev/null
+++ b/doc/forum/Annex_contents_just_disappeared__63__/comment_2_657f737c5d64d440aa133ddb41408fbc._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/2grhJvAC049fJnvALDXek.6MRZMTlg--#eec89"
+ nickname="John"
+ subject="comment 2"
+ date="2013-08-23T03:14:15Z"
+ content="""
+Yes, that was the problem, sorry to bother you. None of my data is gone, it's just sitting there under unknown names. I can roll back to when it knew the names, and migrate them forward.
+"""]]
diff --git a/doc/forum/Annex_contents_just_disappeared__63__/comment_3_9b4c35feb14b37d43d053d7430da9abf._comment b/doc/forum/Annex_contents_just_disappeared__63__/comment_3_9b4c35feb14b37d43d053d7430da9abf._comment
new file mode 100644
index 000000000..6c40a1cac
--- /dev/null
+++ b/doc/forum/Annex_contents_just_disappeared__63__/comment_3_9b4c35feb14b37d43d053d7430da9abf._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 3"
+ date="2013-08-23T04:28:45Z"
+ content="""
+If you change the backend, and then in one repository you run `git annex migrate`, other repositories that have the old keys will not know about the new names. For this reason, then multiple repositories have the files, it's best to run it redundantly in each repository.
+
+TBH, migration is a bit of a PITA because of this. Best to aovid it in most cases.
+
+Git-annex will never perform a migration begind your back. You must have run `git annex migrate` at some point. You can check the git history for details.
+"""]]
diff --git a/doc/forum/Annex_contents_just_disappeared__63__/comment_4_c3625409652bff5f2165260803269a8a._comment b/doc/forum/Annex_contents_just_disappeared__63__/comment_4_c3625409652bff5f2165260803269a8a._comment
new file mode 100644
index 000000000..236f8cfde
--- /dev/null
+++ b/doc/forum/Annex_contents_just_disappeared__63__/comment_4_c3625409652bff5f2165260803269a8a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/2grhJvAC049fJnvALDXek.6MRZMTlg--#eec89"
+ nickname="John"
+ subject="comment 4"
+ date="2013-08-30T06:06:16Z"
+ content="""
+Just to confirm, this wasn't a git-annex problem at all, but just a misstep during migration as you suggested.
+
+I think what I'm going to do now is to just wipe the slate clean and start over again, by using `unannex -fast` on all the files, wiping `.git`, and then adding everything back in using my new default backend of SHA512E. The bigger pain is doing the same thing on all the servers where I have this data (to avoid having to upload it again), but in such a way that I'm not replicating file history. I think I should be able to just clone, `mv $OLDREPO/.git/annex/objects objects`, `git annex add objects`, `git rm -r --cached objects`, and then everything should be good without even needing a new commit on the remote machine, just a git-annex sync.
+"""]]
diff --git a/doc/forum/Annex_dropping_files.mdwn b/doc/forum/Annex_dropping_files.mdwn
new file mode 100644
index 000000000..7ec19caa1
--- /dev/null
+++ b/doc/forum/Annex_dropping_files.mdwn
@@ -0,0 +1,12 @@
+It seems like one of my repos dropped files by itself, my setup involved 3 distributed repos (non bare repos, not using assistant), A/B/C then one client died I've created another one in its place called D cloned from B and marked C as dead. I have now A/B/D. I have updated files in A synced it to D (central) I then tried dropping unused, it listed none (I've dropped the files from A which has full copy) at this point I thought B did not sync to it maybe thats why it did not drop them. I went home sync my laptop B (B dropped its share of unused files) but cental D still show no unused.
+
+A-D has full copies of the repo
+B has partial.
+
+At this point I checked out a old commit from a week ago, checked where the links for the files are pointing to, they point to no where files are not there. Repo sized reported with du -hcs show both repos are the same size (132GB) looks like D managed to drop unused files by itself. I am wondering what caused this?
+
+My annex version is,
+
+git-annex version: 4.20130902-g307537a
+
+on all clients.
diff --git a/doc/forum/Annex_dropping_files/comment_1_62fbea95248fda2ff075b5a8952a728f._comment b/doc/forum/Annex_dropping_files/comment_1_62fbea95248fda2ff075b5a8952a728f._comment
new file mode 100644
index 000000000..3844d3f0d
--- /dev/null
+++ b/doc/forum/Annex_dropping_files/comment_1_62fbea95248fda2ff075b5a8952a728f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.51"
+ subject="comment 1"
+ date="2013-09-12T21:01:03Z"
+ content="""
+If you have just created repository D and have just copied some files to it, then it will only contain those files, and not old deleted files or old versions of files. You can run `git annex copy --all --to D` to copy all those files to D, although if you're only wanting to dropunused them, there is not much point in that..
+"""]]
diff --git a/doc/forum/Assistant:_configure_auto-sync.mdwn b/doc/forum/Assistant:_configure_auto-sync.mdwn
new file mode 100644
index 000000000..48c4dc455
--- /dev/null
+++ b/doc/forum/Assistant:_configure_auto-sync.mdwn
@@ -0,0 +1,11 @@
+I have large central repositories of data. Therefore, on each client I want to save part data(to save space of disk). In command line I do
+
+ [...]
+ git-annex webapp
+ git-annex drop [DeleteContentDirectory]
+ [...]
+
+After this command Assistant performs automatic synchronization getting content of files from this directory(DeleteContentDirectory), but I don't want. I want it's was only symlink of file in this directory.
+
+How can I configure Assistant which files have to get content on the client? It's possible?
+
diff --git a/doc/forum/Assistant:_configure_auto-sync/comment_1_c8cabd38114582bbdbad49f2d81959d7._comment b/doc/forum/Assistant:_configure_auto-sync/comment_1_c8cabd38114582bbdbad49f2d81959d7._comment
new file mode 100644
index 000000000..34fffb846
--- /dev/null
+++ b/doc/forum/Assistant:_configure_auto-sync/comment_1_c8cabd38114582bbdbad49f2d81959d7._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmWg4VvDTer9f49Y3z-R0AH16P4d1ygotA"
+ nickname="Tobias"
+ subject="comment 1"
+ date="2013-08-26T07:44:22Z"
+ content="""
+You should set your repository to \"manual\" mode instead of \"client\" mode.
+
+But then no data will be synced at all by the assistant, only metadata. You would have to do \"get/drop\" manually for commandline for all files.
+
+Alternatively you could use the special \"archive\" folders that are supported by the assistant.
+
+"""]]
diff --git a/doc/forum/Assistant_not_syncing_to_Rsync.mdwn b/doc/forum/Assistant_not_syncing_to_Rsync.mdwn
new file mode 100644
index 000000000..18adc733d
--- /dev/null
+++ b/doc/forum/Assistant_not_syncing_to_Rsync.mdwn
@@ -0,0 +1,15 @@
+I have 3 remotes for an annex - one on my laptop, one on a USB drive that's plugged in 50% of the time, and an rsync special remote on a friend's machine that I can access using SSH.
+
+I have tried various things (annex copy, numcopies=3) to make it move data to the rsync remote, but it doesn't seem to want to work. I have tried git annex sync. I added the remote repo using the webapp, and it looked as if it was copying my files for a bit then stopped. I have the remote repo setup as a backup in the webapp.
+
+The sizes of the directorys:
+ ~ $ du -sh Documents
+ 126M Documents
+ ~ $ du -sh /Volumes/Backup/Documents
+ 227M /Volumes/Backup/Documents
+
+and the remote
+ [c0g@womb Tom]$ du -sh MacDocuments/
+ 21M MacDocuments/
+
+I'm also curious as to why the usb drive repo is so much bigger than the thing I'm copying, but I'll worry about that later.
diff --git a/doc/forum/Assistant_not_syncing_to_Rsync/comment_1_2178a7fc0d66643e84597b0938ef65f2._comment b/doc/forum/Assistant_not_syncing_to_Rsync/comment_1_2178a7fc0d66643e84597b0938ef65f2._comment
new file mode 100644
index 000000000..e701b7cd8
--- /dev/null
+++ b/doc/forum/Assistant_not_syncing_to_Rsync/comment_1_2178a7fc0d66643e84597b0938ef65f2._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.238"
+ subject="comment 1"
+ date="2013-01-10T18:36:04Z"
+ content="""
+What does it say when you run:
+
+ git annex copy --to $rsyncremote
+"""]]
diff --git a/doc/forum/Assistant_not_syncing_to_Rsync/comment_2_650651398443e128c2adc6a2a2d320d0._comment b/doc/forum/Assistant_not_syncing_to_Rsync/comment_2_650651398443e128c2adc6a2a2d320d0._comment
new file mode 100644
index 000000000..28d043c6d
--- /dev/null
+++ b/doc/forum/Assistant_not_syncing_to_Rsync/comment_2_650651398443e128c2adc6a2a2d320d0._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkjWgG_L90szs6o4E8cBusol57zkcDhg7c"
+ nickname="Tom"
+ subject="comment 2"
+ date="2013-01-10T18:40:13Z"
+ content="""
+....
+copy FrenchBasicCourserevised-Volume1-StudentText.pdf (checking Womb_MacDocuments...) ok
+....
+
+for each file in the directory.
+"""]]
diff --git a/doc/forum/Assistant_not_syncing_to_Rsync/comment_3_e6d0c9620b148acc72342862a8b4cfef._comment b/doc/forum/Assistant_not_syncing_to_Rsync/comment_3_e6d0c9620b148acc72342862a8b4cfef._comment
new file mode 100644
index 000000000..99b78a73c
--- /dev/null
+++ b/doc/forum/Assistant_not_syncing_to_Rsync/comment_3_e6d0c9620b148acc72342862a8b4cfef._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.238"
+ subject="comment 3"
+ date="2013-01-10T18:44:00Z"
+ content="""
+Sounds like copy works then?
+
+What version of git-annex do you have installed? A bug was fixed on December 11th, before that the assistant never stored things in repositories configured as backups.
+"""]]
diff --git a/doc/forum/Assistant_not_syncing_to_Rsync/comment_4_b91f9febdb8b69d8b487ba4ea08c119a._comment b/doc/forum/Assistant_not_syncing_to_Rsync/comment_4_b91f9febdb8b69d8b487ba4ea08c119a._comment
new file mode 100644
index 000000000..8303babe3
--- /dev/null
+++ b/doc/forum/Assistant_not_syncing_to_Rsync/comment_4_b91f9febdb8b69d8b487ba4ea08c119a._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkjWgG_L90szs6o4E8cBusol57zkcDhg7c"
+ nickname="Tom"
+ subject="comment 4"
+ date="2013-01-10T18:48:16Z"
+ content="""
+Sorry for lack of extra information: The sizes of the remote folder is still at 21MB, well below even the size of the PDF I posted about (that's about 75MB). Copy claims to work, but I see no network use and the remote repo doesn't grow. I install using cabal on my max yesterday, git-annex version: 3.20130107
+
+
+
+"""]]
diff --git a/doc/forum/Assistant_not_syncing_to_Rsync/comment_5_c5ad7c1546a17d8459c995c9c8c26414._comment b/doc/forum/Assistant_not_syncing_to_Rsync/comment_5_c5ad7c1546a17d8459c995c9c8c26414._comment
new file mode 100644
index 000000000..653b7cc51
--- /dev/null
+++ b/doc/forum/Assistant_not_syncing_to_Rsync/comment_5_c5ad7c1546a17d8459c995c9c8c26414._comment
@@ -0,0 +1,31 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.238"
+ subject="comment 5"
+ date="2013-01-10T18:58:49Z"
+ content="""
+Ok, so copy is checking if the file is present, and it seems to think it is, so doesn't try again to send it.
+
+Here's what you need to do: Run `git annex copy FrenchBasicCourserevised-Volume1-StudentText.pdf --to Womb_MacDocuments --debug`
+
+It'll output something like this:
+
+ copy new (checking rsync...) [2013-01-10 14:51:43 JEST] read: rsync [\"localhost:/tmp/r/f87/4d5/'SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'\"]
+
+Now try running that command at the shell, and check its exit status. For the above, I ran:
+
+ rsync \"localhost:/tmp/r/f87/4d5/'SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855/SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'\"; echo $?
+
+It output:
+
+ -rw-r--r-- 0 2013/01/10 14:51:40 SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+ 0
+
+Compare with the same command but with the filename mangled.
+
+ rsync: link_stat \"/tmp/r/f87/4d5/'SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855/mangled'\" failed: No such file or directory (2)
+ rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1536) [Receiver=3.0.9]
+ 27
+
+It seems that rsync might be exiting 0 for content that's not there, in your case. This test will confirm or disprove that hypothesis and might provide some useful debug info.
+"""]]
diff --git a/doc/forum/Assistant_not_syncing_to_Rsync/comment_6_4c12587f972eced91c5128d4885800b5._comment b/doc/forum/Assistant_not_syncing_to_Rsync/comment_6_4c12587f972eced91c5128d4885800b5._comment
new file mode 100644
index 000000000..3746fa2e3
--- /dev/null
+++ b/doc/forum/Assistant_not_syncing_to_Rsync/comment_6_4c12587f972eced91c5128d4885800b5._comment
@@ -0,0 +1,30 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkjWgG_L90szs6o4E8cBusol57zkcDhg7c"
+ nickname="Tom"
+ subject="comment 6"
+ date="2013-01-11T07:44:11Z"
+ content="""
+I did what you said for a file, and checked the remote size as well. Local size of this file was 11.4 meg, remote was 1.3 megabytes.
+
+ copy Paradox Interactive/Crusader Kings II/save games/Yngling/1066_09_15_2.ck2 (checking Womb_MacDocuments...) [2013-01-11 07:30:26 GMT] read: rsync [\"c0g@git- annex-c0g:/raid/Tom/MacDocuments/87f/7f7/'GPGHMACSHA1--0148d706315885fac29c3a1dc0ec37b2835739a7/GPGHMACSHA1--0148d706315885fac29c3a1dc0ec37b2835739a7'\"]
+ ok
+
+ rsync c0g@git-annex-c0g:/raid/Tom/MacDocuments/87f/7f7/'GPGHMACSHA1--0148d706315885fac29c3a1dc0ec37b2835739a7/GPGHMACSHA1--0148d706315885fac29c3a1dc0ec37b2835739a7'
+ -rw-r--r-- 1290004 2013/01/10 17:37:14 GPGHMACSHA1--0148d706315885fac29c3a1dc0ec37b2835739a7
+ 0
+
+ ~/Documents ± la Paradox\ Interactive/Crusader\ Kings\ II/save\ games/Yngling
+ total 44728
+ drwx------ 4 c0g staff 136 10 Jan 17:52 .
+ drwx------ 3 c0g staff 102 10 Nov 20:53 ..
+ -rw-r--r-- 1 c0g staff 11413707 10 Jan 17:52 1066_09_15.ck2
+ -rw-r--r-- 1 c0g staff 11484448 10 Jan 17:52 1066_09_15_2.ck2
+
+ [c0g@womb GPGHMACSHA1--0148d706315885fac29c3a1dc0ec37b2835739a7]$ ls -la
+ total 1268
+ drwxr-xr-x 2 c0g users 4096 Jan 10 12:37 .
+ drwxr-xr-x 3 c0g users 4096 Jan 10 12:37 ..
+ -rw-r--r-- 1 c0g users 1290004 Jan 10 12:37 GPGHMACSHA1--0148d706315885fac29c3a1dc0ec37b2835739a7
+
+
+"""]]
diff --git a/doc/forum/Assistant_not_syncing_to_Rsync/comment_7_6ecaaee9316bcf0c65688676d60fc055._comment b/doc/forum/Assistant_not_syncing_to_Rsync/comment_7_6ecaaee9316bcf0c65688676d60fc055._comment
new file mode 100644
index 000000000..38f755c86
--- /dev/null
+++ b/doc/forum/Assistant_not_syncing_to_Rsync/comment_7_6ecaaee9316bcf0c65688676d60fc055._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkjWgG_L90szs6o4E8cBusol57zkcDhg7c"
+ nickname="Tom"
+ subject="comment 7"
+ date="2013-01-11T07:52:17Z"
+ content="""
+I just compressed the documents folder, and it compresses down to 20 MB... I'm going to guess it stores as a compressed encrypted archive? How embarrasing for me!
+"""]]
diff --git a/doc/forum/Assistant_not_syncing_to_Rsync/comment_8_daa9a9a6188afa0394833e1b682f7cd4._comment b/doc/forum/Assistant_not_syncing_to_Rsync/comment_8_daa9a9a6188afa0394833e1b682f7cd4._comment
new file mode 100644
index 000000000..f0a1c88fc
--- /dev/null
+++ b/doc/forum/Assistant_not_syncing_to_Rsync/comment_8_daa9a9a6188afa0394833e1b682f7cd4._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.238"
+ subject="comment 8"
+ date="2013-01-11T17:20:19Z"
+ content="""
+Aha! Yes, encryption includes compression.
+
+So, only remaining question is why your USB drive seems to be using 2x the uncompressed file size. One possibility would be it could have old versions of files, or deleted files still stored in it. You could try running \"git annex unused\" in its repository to find them. Other than that, I'm not sure what it could be. You can look around in its .git/annex directory, and compare to your laptop's repository, and perhaps see what's using the space.
+"""]]
diff --git a/doc/forum/Auto_archiving.mdwn b/doc/forum/Auto_archiving.mdwn
new file mode 100644
index 000000000..f32a648c2
--- /dev/null
+++ b/doc/forum/Auto_archiving.mdwn
@@ -0,0 +1,17 @@
+I've been toying with the idea of auto archiving files (that is - removing them from .) based on a set of rules.
+
+Git already provides attribute management for files and I put together a simple script that tries to achieve the following:
+
+* Look for files with X copies (including a local one)
+* Verify that the file is not recent (defined as not having been dropped or getted within X days )
+* Verify that the file has an annex.archive attribute
+* Archive if the above is met
+
+Here is the script:
+http://pastebin.com/53iLqyPd
+
+You just add the annex.archive attribute to files via .gitattributes to use
+
+The script runs in preview mode... exec with autoArchive.sh commit to drop the files.
+
+Open to thoughts / suggestions
diff --git a/doc/forum/Automatic___96__git_annex_get__96___after_invalidation_of_local_files_due_to_external_modification__63__.mdwn b/doc/forum/Automatic___96__git_annex_get__96___after_invalidation_of_local_files_due_to_external_modification__63__.mdwn
new file mode 100644
index 000000000..50518e33a
--- /dev/null
+++ b/doc/forum/Automatic___96__git_annex_get__96___after_invalidation_of_local_files_due_to_external_modification__63__.mdwn
@@ -0,0 +1,46 @@
+## Use case
+
+A laptop with a relatively small hard drive has copies of a subset of
+all annexed files. When annexed files are changed externally and `git
+annex sync` is run on the laptop, the stale local copies are
+invalidated and their symlinks break. How can I automatically fetch
+the updated versions of these previously locally-cached files?
+
+Because I only want a subset of files, I can't do
+
+ git annex add --not --in here --and --in superset.
+
+Because files may be renamed, the
+[[tips/automatically_getting_files_on_checkout/]] solution, by making
+`dir` specify the subset, will require manually and redundantly
+tracking renames.
+
+## Simple ( (?) ) feature addition to git-annex to support this
+
+When locally-cached files are invalidated by `git-annex sync`,
+git-annex could notify the user, and give them the option to
+`git-annex get` the invalidated files. Bonus points if the mechanism
+allows this to be done at any point in the future, not just when
+running `git-annex sync`. The idea is that git-annex could track
+which files, previously cached locally, have been invalidated
+*unintentionally* by syncs, and treat them differently from files,
+previously cached locally, that have been *intentionally* dropped
+using `git-annex drop` or `git-annex move`.
+
+## More generally
+
+The ability to specify a collection of files to always cache locally
+(something like a numcopies.here=1), which is robust to renames, would
+work. The "robust to renames" part seems tricky in git: whereas svn
+attaches properties to files, and so properties are propagated by `svn
+mv`, I believe git attributes are only specified by patterns in
+.gitattributes files.
+
+## Related questions / possible approaches
+
+Other forum posts mention [[`git
+subtree`|forum/git-subtree_support__63__/]] and [[sparse git
+checkouts|forum/sparse_git_checkouts_with_annex/]], but I'm not
+familiar with these features and from reading those questions it's
+unclear if those approaches will work for me. Does anyone more
+familiar see how to adapt one of those features to my use case?
diff --git a/doc/forum/Automatic___96__git_annex_get__96___after_invalidation_of_local_files_due_to_external_modification__63__/comment_1_dab1099ee56541c194de319c593f1268._comment b/doc/forum/Automatic___96__git_annex_get__96___after_invalidation_of_local_files_due_to_external_modification__63__/comment_1_dab1099ee56541c194de319c593f1268._comment
new file mode 100644
index 000000000..fa561ef04
--- /dev/null
+++ b/doc/forum/Automatic___96__git_annex_get__96___after_invalidation_of_local_files_due_to_external_modification__63__/comment_1_dab1099ee56541c194de319c593f1268._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ subject="comment 1"
+ date="2012-06-04T19:56:05Z"
+ content="""
+Personally, I deal with this problem by having a directory, or directories where I put files that I want to have on my partial checkout laptop, and run `git annex get` in that directory.
+
+It's not a perfect solution, but I don't know that a perfect solution exists.
+"""]]
diff --git a/doc/forum/Automatic___96__git_annex_get__96___after_invalidation_of_local_files_due_to_external_modification__63__/comment_2_b5faccf132fb47e3cda778a6600fd9ef._comment b/doc/forum/Automatic___96__git_annex_get__96___after_invalidation_of_local_files_due_to_external_modification__63__/comment_2_b5faccf132fb47e3cda778a6600fd9ef._comment
new file mode 100644
index 000000000..2cd1001ef
--- /dev/null
+++ b/doc/forum/Automatic___96__git_annex_get__96___after_invalidation_of_local_files_due_to_external_modification__63__/comment_2_b5faccf132fb47e3cda778a6600fd9ef._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlu7K3h7Ry1uDAU_ERYGuqt0LoGNJqGuRo"
+ nickname="Nathan"
+ subject="comment 2"
+ date="2012-06-04T21:01:52Z"
+ content="""
+Joey, that sounds reasonable; I'll try it. Thanks!
+"""]]
diff --git a/doc/forum/Automatic_commit_messages_for_git_annex_sync.mdwn b/doc/forum/Automatic_commit_messages_for_git_annex_sync.mdwn
new file mode 100644
index 000000000..60b8e034d
--- /dev/null
+++ b/doc/forum/Automatic_commit_messages_for_git_annex_sync.mdwn
@@ -0,0 +1 @@
+Not really important (who reads git annex commit messages anyways ;-)), but nice to have and maybe a nice task for someone who wants to play around with Haskell and git annex: It would be shiny if the auto-commit done by git annex sync would automatically create a sensible commmit message and description. E.g. if just one file is added, it could say „Added blubb“. If a few files are added, it could say „Added blubb, bla and n other files“, based on the file name length, and list the files in the long description. Lots of room for playing around :-)
diff --git a/doc/forum/Automatic_commit_messages_for_git_annex_sync/comment_1_ea2ec57bc695da4df8a30a35d433959d._comment b/doc/forum/Automatic_commit_messages_for_git_annex_sync/comment_1_ea2ec57bc695da4df8a30a35d433959d._comment
new file mode 100644
index 000000000..c07dd4999
--- /dev/null
+++ b/doc/forum/Automatic_commit_messages_for_git_annex_sync/comment_1_ea2ec57bc695da4df8a30a35d433959d._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2012-02-24T20:52:51Z"
+ content="""
+Took me a minute to see this is not about [[bugs/wishlist:_more_descriptive_commit_messages_in_git-annex_branch]], but about the \"git-annex automatic sync\" message that is used when committing any changes currently on the master branch before doing the rest of the sync.
+
+So.. It would be pretty easy to `ls-files` the relevant files before the commit and make a message. Although this would roughly double the commit time in a large tree, since that would walk the whole tree again (git commit -a already does it once). Smarter approaches could be faster.. perhaps it could find unstaged files, stage them, generate the message, and then `git commit` the staged changes.
+
+But, would this really be useful? It's already easy to get `git log` to show a summary of the changes made in such a commit. So it's often seen as bad form to unnecessarily mention which files a commit changes in the commit message.
+
+Perhaps more useful would be to expand the current message with details like where the sync is being committed, or what
+remotes it's going to sync from, or something like that.
+"""]]
diff --git a/doc/forum/Automatic_commit_messages_for_git_annex_sync/comment_2_af71f53dbbca35d5a5c66ff131887ada._comment b/doc/forum/Automatic_commit_messages_for_git_annex_sync/comment_2_af71f53dbbca35d5a5c66ff131887ada._comment
new file mode 100644
index 000000000..a71f72b9e
--- /dev/null
+++ b/doc/forum/Automatic_commit_messages_for_git_annex_sync/comment_2_af71f53dbbca35d5a5c66ff131887ada._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://www.joachim-breitner.de/"
+ nickname="nomeata"
+ subject="comment 2"
+ date="2012-02-24T23:09:03Z"
+ content="""
+Yes, it is really a minor point. And indeed, \"git log --summary\" is pretty good already. But I’d still think that at least the title could deserves some love. Including the Hostname or the name of the repository there is a good idea as well.
+"""]]
diff --git a/doc/forum/Automatically_syncronise_centralised_repository.mdwn b/doc/forum/Automatically_syncronise_centralised_repository.mdwn
new file mode 100644
index 000000000..fe93a814d
--- /dev/null
+++ b/doc/forum/Automatically_syncronise_centralised_repository.mdwn
@@ -0,0 +1,14 @@
+I would like to use git annex between two locations (work and home) where essentially the two computers are never on at the same time.
+
+I have set up a special remote (S3) to cater for file transfer between the sites, but still need some way of syncronising the git repositories between them.
+I have access to a git server, but which doesn't have git-annex on it. So, I think that is all the components I need to get this working.
+
+However, I don't want to have to manually sync my computers with the central server, so I would like the assistant to do it for me, in what is essentially the complement of the special remote.
+
+What is the best way to accomplish this? I guess that this is a general git question, not specific to git annex.
+I see some solutions [[http://stackoverflow.com/questions/3583061/automatically-mirror-a-git-repository]], but my git isn't really up to evaluating the options properly.
+
+So, what do other people do in this situation?
+
+
+--Walter
diff --git a/doc/forum/Automatically_syncronise_centralised_repository/comment_1_6a2047daa9faf4309d2ed27d5cc48b76._comment b/doc/forum/Automatically_syncronise_centralised_repository/comment_1_6a2047daa9faf4309d2ed27d5cc48b76._comment
new file mode 100644
index 000000000..cbf8f0d04
--- /dev/null
+++ b/doc/forum/Automatically_syncronise_centralised_repository/comment_1_6a2047daa9faf4309d2ed27d5cc48b76._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-04-22T18:58:08Z"
+ content="""
+The assistant can handle this syncing via a central bare remote. The only problem is that, since your server does not have git-annex installed, that remote will have annex-ignore set on it. That made the assistant not use it for syncing at all.
+
+I've just committed a change to git that makes the assistant still use such a git remote for syncing the git repository, even though it cannot store file contents there.
+"""]]
diff --git a/doc/forum/Automatically_syncronise_centralised_repository/comment_2_3be7b45bc2284019f17a81375637a576._comment b/doc/forum/Automatically_syncronise_centralised_repository/comment_2_3be7b45bc2284019f17a81375637a576._comment
new file mode 100644
index 000000000..956e6b00a
--- /dev/null
+++ b/doc/forum/Automatically_syncronise_centralised_repository/comment_2_3be7b45bc2284019f17a81375637a576._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnSenxKyE_2Z6Wb-EBMO8FciyRywjx1ZiQ"
+ nickname="Walter"
+ subject="comment 2"
+ date="2013-04-22T20:37:59Z"
+ content="""
+That looks like exactly what I'm after!
+
+I'm very impressed by the quick response. Keep up the great work!
+"""]]
diff --git a/doc/forum/Behaviour_of_fsck.mdwn b/doc/forum/Behaviour_of_fsck.mdwn
new file mode 100644
index 000000000..cd27d49f7
--- /dev/null
+++ b/doc/forum/Behaviour_of_fsck.mdwn
@@ -0,0 +1,13 @@
+The current behaviour of 'fsck' is a bit verbose. I have an annex'd directory of tarballs for my own build system for "science" applications, there's about ~600 or so blobs in my repo, I do occassionally like to run fsck across all my data to see what files don't meet the min num copies requirement that I have set.
+
+Would it be better for the default behaviour of fsck when it has not been given a path to only output errors and not bother to show that a file is ok for every single file in a repo. i.e.
+
+ git annex fsck
+
+should show only 'errors' and maybe a simple indicator showing the status (show a spinner or dots?) and when
+
+ git annex fsck PATH/FILE
+
+it should have the current behaviour?
+
+Right now the current fsck behaviour might get annoying for anyone who would want to run fsck with repos with lots of big files.
diff --git a/doc/forum/Behaviour_of_fsck/comment_1_0e40f158b3f4ccdcaab1408d858b68b8._comment b/doc/forum/Behaviour_of_fsck/comment_1_0e40f158b3f4ccdcaab1408d858b68b8._comment
new file mode 100644
index 000000000..dc48e2f94
--- /dev/null
+++ b/doc/forum/Behaviour_of_fsck/comment_1_0e40f158b3f4ccdcaab1408d858b68b8._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-03-24T17:45:08Z"
+ content="""
+I tend to agree that the default output of fsck is not quite right. I often use git annex fsck -q. A progress spinner display is a good idea.
+"""]]
diff --git a/doc/forum/Behaviour_of_fsck/comment_2_ead36a23c3e6efa1c41e4555f93e014e._comment b/doc/forum/Behaviour_of_fsck/comment_2_ead36a23c3e6efa1c41e4555f93e014e._comment
new file mode 100644
index 000000000..357b48a23
--- /dev/null
+++ b/doc/forum/Behaviour_of_fsck/comment_2_ead36a23c3e6efa1c41e4555f93e014e._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 2"
+ date="2011-03-26T10:57:41Z"
+ content="""
+After some thought, perhaps the default fsck output should be at least machine readable and copy and pasteable i.e.
+
+<pre>
+$ git annex fsck
+Files with errors
+
+ file1
+ file2
+
+</pre>
+
+so I can then copy the list of borked files and then just paste it into a for loop in my shell to recover the files. it's just an idea.
+"""]]
diff --git a/doc/forum/Behaviour_of_fsck/comment_3_97848f9a3db89c0427cfb671ba13300e._comment b/doc/forum/Behaviour_of_fsck/comment_3_97848f9a3db89c0427cfb671ba13300e._comment
new file mode 100644
index 000000000..be34473c0
--- /dev/null
+++ b/doc/forum/Behaviour_of_fsck/comment_3_97848f9a3db89c0427cfb671ba13300e._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 3"
+ date="2011-03-28T01:16:21Z"
+ content="""
+Another nice thing would be a summary of _what_ is wrong. I.e.
+
+ % git fsck
+ [...]
+ git-annex: 100 total failed
+ 50 checksum failed
+ 50 not enough copies exit
+
+And the same/similar for all other failure modes.
+
+
+-- RichiH
+"""]]
diff --git a/doc/forum/Behaviour_of_fsck/comment_4_e4911dc6793f98fb81151daacbe49968._comment b/doc/forum/Behaviour_of_fsck/comment_4_e4911dc6793f98fb81151daacbe49968._comment
new file mode 100644
index 000000000..e8c983746
--- /dev/null
+++ b/doc/forum/Behaviour_of_fsck/comment_4_e4911dc6793f98fb81151daacbe49968._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 2"
+ date="2011-03-25T11:23:04Z"
+ content="""
+FWIW, I wanted to suggest exactly the same thing.
+"""]]
diff --git a/doc/forum/Best_way_to_manage_files_on_removable_media__63__.mdwn b/doc/forum/Best_way_to_manage_files_on_removable_media__63__.mdwn
new file mode 100644
index 000000000..d6d1206ae
--- /dev/null
+++ b/doc/forum/Best_way_to_manage_files_on_removable_media__63__.mdwn
@@ -0,0 +1,18 @@
+I have a bunch of removable storage devices and was planning on storing my data across
+all of them. I've run into an annoyance, and would like to see if anybody has any
+ideas.
+
+My goal was to have the full file tree on all the devices, but only a subset of the
+annexed data. Where I have run into trouble is removing data from the system. It
+seems that the "git annex unused" command checks remote branches as well as local ones
+when determining whether an object is referred to.
+
+This means that if I remove a file that is stored locally, "git annex unused" doesn't
+report the corresponding object as unused until I either connect and update all
+removable storage *or* remove the remote corresponding to the removable storage. I
+posted a bug about this inconsistency named
+[[bugs/git annex unused considers remote branches which makes it inconsistent]].
+
+If I used the removable storage as a special remote, then I wouldn't have this issue,
+but I also wouldn't be able to conveniently use the files on it and manage the repo
+from it either.
diff --git a/doc/forum/Best_way_to_re-add_a_file_in_a_direct_and_crippled_annex_repository.mdwn b/doc/forum/Best_way_to_re-add_a_file_in_a_direct_and_crippled_annex_repository.mdwn
new file mode 100644
index 000000000..c126f8373
--- /dev/null
+++ b/doc/forum/Best_way_to_re-add_a_file_in_a_direct_and_crippled_annex_repository.mdwn
@@ -0,0 +1,17 @@
+Hi!
+
+What is the best way to add again the content of file in an direct and crippled annex repository? I'm using such a repository on a SMB drive, with no symbolic links, that's why the repository is in direct mode.
+
+For example:
+
+`/disk/annex-rep/a.bin` contains the text `../.git/annex/objects/W3/M8/SHA256E-s4701522386--e486cce01b1870cee394a376a3acc64a608e84e38b85e6c21c29721cf14328e6.bin/SHA256E-s4701522386--e486cce01b1870cee394a376a3acc64a608e84e38b85e6c21c29721cf14328e6.bin`
+
+and I've got the real content in another directory, outside annex: /disk/a.bin (contains the binary data)
+
+I imagined this process:
+* replace `/disk/annex-rep/a.bin` with `/disk/a.bin``
+* update `git-annex:122/4b8/SHA256E-s4701522386--e486cce01b1870cee394a376a3acc64a608e84e38b85e6c21c29721cf14328e6.bin.log` by adding this repository uuid
+
+I tried `git annex reinject` but it didn't work.
+
+Is there another way?
diff --git a/doc/forum/Best_way_to_re-add_a_file_in_a_direct_and_crippled_annex_repository/comment_1_552e74f9573a34ec178f396b83252c3e._comment b/doc/forum/Best_way_to_re-add_a_file_in_a_direct_and_crippled_annex_repository/comment_1_552e74f9573a34ec178f396b83252c3e._comment
new file mode 100644
index 000000000..439c985dc
--- /dev/null
+++ b/doc/forum/Best_way_to_re-add_a_file_in_a_direct_and_crippled_annex_repository/comment_1_552e74f9573a34ec178f396b83252c3e._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.64"
+ subject="comment 1"
+ date="2013-11-26T19:54:21Z"
+ content="""
+There's a bug report asking that reinject work in direct mode. I just have not gotten around to it.
+
+Another way to do it would be to make a temp directory in your annex repository, move or copy the file to there, and `git annex add`. As long as you're not using the WORM backend, the checksum will be used, and so it'll see it's added the content of the file, and make the a.bin file have that content too.
+
+Off to see if I can easily add direct mode reinject now..
+"""]]
diff --git a/doc/forum/Best_way_to_re-add_a_file_in_a_direct_and_crippled_annex_repository/comment_2_33c57922714f204fc63c260b838f3712._comment b/doc/forum/Best_way_to_re-add_a_file_in_a_direct_and_crippled_annex_repository/comment_2_33c57922714f204fc63c260b838f3712._comment
new file mode 100644
index 000000000..afc449ac2
--- /dev/null
+++ b/doc/forum/Best_way_to_re-add_a_file_in_a_direct_and_crippled_annex_repository/comment_2_33c57922714f204fc63c260b838f3712._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.64"
+ subject="comment 2"
+ date="2013-11-26T20:18:56Z"
+ content="""
+Turned out to be trivial, so it's supported now.
+"""]]
diff --git a/doc/forum/Box.com_hasn__39__t_been_working_for_a_few_days.mdwn b/doc/forum/Box.com_hasn__39__t_been_working_for_a_few_days.mdwn
new file mode 100644
index 000000000..77b092891
--- /dev/null
+++ b/doc/forum/Box.com_hasn__39__t_been_working_for_a_few_days.mdwn
@@ -0,0 +1,72 @@
+I've been experiencing problems with Box.com for a few days now and I don't know what's causing them. Is anyone else experiencing anything similar?
+
+I paste the log.
+
+ [2013-09-02 12:27:26 CEST] TransferWatcher: transfer finishing: Transfer {transferDirection = Upload, transferUUID = UUID "72111b4c-28fe-42fd-a77b-e4cb9240a1c9", transferKey = Key {keyName = "c9e1d5421e78924c21e3d68e84f80a8d1f64f9488020107ca0eeee0c4f10e763.py", keyBackendName = "SHA256E", keySize = Just 1891, keyMtime = Nothing}}
+ [2013-09-02 12:27:26 CEST] TransferScanner: queued Upload UUID "72111b4c-28fe-42fd-a77b-e4cb9240a1c9" Documentos/diveintopython-5.4/py/kgp/kant.xml Nothing : expensive scan found missing object
+ [2013-09-02 12:27:26 CEST] Transferrer: Transferring: Upload UUID "72111b4c-28fe-42fd-a77b-e4cb9240a1c9" Documentos/diveintopython-5.4/py/argecho.py Nothing
+ [2013-09-02 12:27:26 CEST] TransferWatcher: transfer starting: Upload UUID "72111b4c-28fe-42fd-a77b-e4cb9240a1c9" Documentos/diveintopython-5.4/py/argecho.py Nothing
+ [2013-09-02 12:27:26 CEST] TransferWatcher: transfer starting: Upload UUID "72111b4c-28fe-42fd-a77b-e4cb9240a1c9" Documentos/diveintopython-5.4/py/argecho.py Nothing
+
+
+ 100% 0.0 B/s 0s[2013-09-02 12:27:26 CEST] TransferWatcher: transfer starting: Upload UUID "72111b4c-28fe-42fd-a77b-e4cb9240a1c9" Documentos/diveintopython-5.4/py/argecho.py Just 437
+ ResponseTimeout
+ ResponseTimeout
+
+
+ [2013-09-02 12:27:44 CEST] TransferWatcher: transfer finishing: Transfer {transferDirection = Upload, transferUUID = UUID "72111b4c-28fe-42fd-a77b-e4cb9240a1c9", transferKey = Key {keyName = "dd3cc45d91430c6f7d68eb807f4ac1561cd0297b11a2de77b5fe66017d125798.py", keyBackendName = "SHA256E", keySize = Just 437, keyMtime = Nothing}}
+ [2013-09-02 12:27:44 CEST] TransferScanner: queued Upload UUID "72111b4c-28fe-42fd-a77b-e4cb9240a1c9" Documentos/diveintopython-5.4/py/kgp/kgp.dtd Nothing : expensive scan found missing object
+ [2013-09-02 12:27:44 CEST] Transferrer: Transferring: Upload UUID "72111b4c-28fe-42fd-a77b-e4cb9240a1c9" Documentos/diveintopython-5.4/py/autosize.py Nothing
+ [2013-09-02 12:27:44 CEST] TransferWatcher: transfer starting: Upload UUID "72111b4c-28fe-42fd-a77b-e4cb9240a1c9" Documentos/diveintopython-5.4/py/autosize.py Nothing
+ [2013-09-02 12:27:44 CEST] TransferWatcher: transfer starting: Upload UUID "72111b4c-28fe-42fd-a77b-e4cb9240a1c9" Documentos/diveintopython-5.4/py/autosize.py Nothing
+
+
+ 100% 0.0 B/s 0s[2013-09-02 12:27:44 CEST] TransferWatcher: transfer starting: Upload UUID "72111b4c-28fe-42fd-a77b-e4cb9240a1c9" Documentos/diveintopython-5.4/py/autosize.py Just 2861
+ ResponseTimeout
+ ResponseTimeout
+
+
+ [2013-09-02 12:28:02 CEST] TransferWatcher: transfer finishing: Transfer {transferDirection = Upload, transferUUID = UUID "72111b4c-28fe-42fd-a77b-e4cb9240a1c9", transferKey = Key {keyName = "d6b7940ac68768a8e37e72f248e2d94f19fb0d47062084d9baf0ec08cebbf692.py", keyBackendName = "SHA256E", keySize = Just 2861, keyMtime = Nothing}}
+ [2013-09-02 12:28:02 CEST] TransferScanner: queued Upload UUID "72111b4c-28fe-42fd-a77b-e4cb9240a1c9" Documentos/diveintopython-5.4/py/kgp/kgp.py Nothing : expensive scan found missing object
+ [2013-09-02 12:28:02 CEST] Transferrer: Transferring: Upload UUID "72111b4c-28fe-42fd-a77b-e4cb9240a1c9" Documentos/diveintopython-5.4/py/builddialectexamples.py Nothing
+ [2013-09-02 12:28:03 CEST] TransferWatcher: transfer starting: Upload UUID "72111b4c-28fe-42fd-a77b-e4cb9240a1c9" Documentos/diveintopython-5.4/py/builddialectexamples.py Nothing
+ [2013-09-02 12:28:03 CEST] TransferWatcher: transfer starting: Upload UUID "72111b4c-28fe-42fd-a77b-e4cb9240a1c9" Documentos/diveintopython-5.4/py/builddialectexamples.py Nothing
+
+
+ 100% 0.0 B/s 0s[2013-09-02 12:28:03 CEST] TransferWatcher: transfer starting: Upload UUID "72111b4c-28fe-42fd-a77b-e4cb9240a1c9" Documentos/diveintopython-5.4/py/builddialectexamples.py Just 1090
+ ResponseTimeout
+ ResponseTimeout
+
+
+ [2013-09-02 12:28:21 CEST] TransferWatcher: transfer finishing: Transfer {transferDirection = Upload, transferUUID = UUID "72111b4c-28fe-42fd-a77b-e4cb9240a1c9", transferKey = Key {keyName = "f1492b80d05b96cc7cf2904d461c99d430fa86a4eb1d99f1b155c9147ff4420f.py", keyBackendName = "SHA256E", keySize = Just 1090, keyMtime = Nothing}}
+ [2013-09-02 12:28:21 CEST] TransferScanner: queued Upload UUID "72111b4c-28fe-42fd-a77b-e4cb9240a1c9" Documentos/diveintopython-5.4/py/kgp/russiansample.xml Nothing : expensive scan found missing object
+ [2013-09-02 12:28:21 CEST] Transferrer: Transferring: Upload UUID "72111b4c-28fe-42fd-a77b-e4cb9240a1c9" Documentos/diveintopython-5.4/py/colorize.py Nothing
+ [2013-09-02 12:28:21 CEST] TransferWatcher: transfer starting: Upload UUID "72111b4c-28fe-42fd-a77b-e4cb9240a1c9" Documentos/diveintopython-5.4/py/colorize.py Nothing
+ [2013-09-02 12:28:21 CEST] TransferWatcher: transfer starting: Upload UUID "72111b4c-28fe-42fd-a77b-e4cb9240a1c9" Documentos/diveintopython-5.4/py/colorize.py Nothing
+
+
+ 100% 0.0 B/s 0s[2013-09-02 12:28:21 CEST] TransferWatcher: transfer starting: Upload UUID "72111b4c-28fe-42fd-a77b-e4cb9240a1c9" Documentos/diveintopython-5.4/py/colorize.py Just 4864
+ ResponseTimeout
+ ResponseTimeout
+
+
+ [2013-09-02 12:28:40 CEST] TransferWatcher: transfer finishing: Transfer {transferDirection = Upload, transferUUID = UUID "72111b4c-28fe-42fd-a77b-e4cb9240a1c9", transferKey = Key {keyName = "b577eaf8b6ddbf9fef866c455cae248aec3b22e3f2e91aa2b75ece90f1801689.py", keyBackendName = "SHA256E", keySize = Just 4864, keyMtime = Nothing}}
+ [2013-09-02 12:28:40 CEST] TransferScanner: queued Upload UUID "72111b4c-28fe-42fd-a77b-e4cb9240a1c9" Documentos/diveintopython-5.4/py/kgp/stderr.py Nothing : expensive scan found missing object
+ [2013-09-02 12:28:40 CEST] Transferrer: Transferring: Upload UUID "72111b4c-28fe-42fd-a77b-e4cb9240a1c9" Documentos/diveintopython-5.4/py/dialect.py Nothing
+ [2013-09-02 12:28:40 CEST] TransferWatcher: transfer starting: Upload UUID "72111b4c-28fe-42fd-a77b-e4cb9240a1c9" Documentos/diveintopython-5.4/py/dialect.py Nothing
+ [2013-09-02 12:28:40 CEST] TransferWatcher: transfer starting: Upload UUID "72111b4c-28fe-42fd-a77b-e4cb9240a1c9" Documentos/diveintopython-5.4/py/dialect.py Nothing
+
+
+ 100% 0.0 B/s 0s[2013-09-02 12:28:40 CEST] TransferWatcher: transfer starting: Upload UUID "72111b4c-28fe-42fd-a77b-e4cb9240a1c9" Documentos/diveintopython-5.4/py/dialect.py Just 4449
+ ResponseTimeout
+ ResponseTimeout
+
+
+ [2013-09-02 12:28:58 CEST] TransferWatcher: transfer finishing: Transfer {transferDirection = Upload, transferUUID = UUID "72111b4c-28fe-42fd-a77b-e4cb9240a1c9", transferKey = Key {keyName = "c5e5d9b1bee2710c7ed05270a363d3e93270b0fb6779c4c8d59ace06c11db684.py", keyBackendName = "SHA256E", keySize = Just 4449, keyMtime = Nothing}}
+ [2013-09-02 12:28:58 CEST] TransferScanner: queued Upload UUID "72111b4c-28fe-42fd-a77b-e4cb9240a1c9" Documentos/diveintopython-5.4/py/kgp/stdout.py Nothing : expensive scan found missing object
+ [2013-09-02 12:28:58 CEST] Transferrer: Transferring: Upload UUID "72111b4c-28fe-42fd-a77b-e4cb9240a1c9" Documentos/diveintopython-5.4/py/fibonacci.py Nothing
+ [2013-09-02 12:28:58 CEST] TransferWatcher: transfer starting: Upload UUID "72111b4c-28fe-42fd-a77b-e4cb9240a1c9" Documentos/diveintopython-5.4/py/fibonacci.py Nothing
+ [2013-09-02 12:28:58 CEST] TransferWatcher: transfer starting: Upload UUID "72111b4c-28fe-42fd-a77b-e4cb9240a1c9" Documentos/diveintopython-5.4/py/fibonacci.py Nothing
+
+
+ 100% 0.0 B/s 0s[2013-09-02 12:28:58 CEST] TransferWatcher: transfer starting: Upload UUID "72111b4c-28fe-42fd-a77b-e4cb9240a1c9" Documentos/diveintopython-5.4/py/fibonacci.py Just 532
diff --git a/doc/forum/Box.com_hasn__39__t_been_working_for_a_few_days/comment_1_6ca872c241399b9129cf9a18f42ebd43._comment b/doc/forum/Box.com_hasn__39__t_been_working_for_a_few_days/comment_1_6ca872c241399b9129cf9a18f42ebd43._comment
new file mode 100644
index 000000000..2c7d98b49
--- /dev/null
+++ b/doc/forum/Box.com_hasn__39__t_been_working_for_a_few_days/comment_1_6ca872c241399b9129cf9a18f42ebd43._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://sunny256.sunbase.org/"
+ nickname="sunny256"
+ subject="It works here"
+ date="2013-09-02T11:47:00Z"
+ content="""
+I set up a box.com remote a couple of months ago or so just for testing. Haven't used it that much, but I tested it now to see if it still works. No errors or problems. I have pasted the output from a session where I copied a file to box.com, dropped it locally, then got it back from box.com here: <https://gist.github.com/sunny256/6411972>. The computer I ran the test on is using the newest git-annex binary (v4.20130827), Ubuntu 10.04.4 LTS. Pretty old distro, but it still works.
+"""]]
diff --git a/doc/forum/Building_a_Debian_package_of_git-annex.mdwn b/doc/forum/Building_a_Debian_package_of_git-annex.mdwn
new file mode 100644
index 000000000..ee222df29
--- /dev/null
+++ b/doc/forum/Building_a_Debian_package_of_git-annex.mdwn
@@ -0,0 +1,27 @@
+I'd like to have a Debian/Ubuntu package of the latest git-annex (f.e. to have it installed systemwide). In the source I can find the debian/ folder with all needed information to build the package. But it looks like I don't have all needed dependencies on my Ubuntu 12.10:
+
+ user@laptop(pc) ~/src/git/git-annex (git)-[master] % debuild -us -uc
+ dpkg-buildpackage -rfakeroot -D -us -uc
+ dpkg-buildpackage: source package git-annex
+ dpkg-buildpackage: source version 3.20130115
+ dpkg-buildpackage: source changed by Joey Hess <joeyh@debian.org>
+ dpkg-source --before-build git-annex
+ dpkg-buildpackage: host architecture amd64
+ dpkg-checkbuilddeps: Unmet build dependencies: libghc-dav-dev (>= 0.3) libghc-dbus-dev (>= 0.10.3) libghc-yesod-dev libghc-yesod-static-dev libghc-yesod-default-dev libghc-hamlet-dev libghc-clientsession-dev libghc-warp-dev libghc-wai-dev libghc-wai-logger-dev libghc-case-insensitive-dev libghc-http-types-dev libghc-blaze-builder-dev libghc-crypto-api-dev libghc-network-multicast-dev libghc-network-info-dev libghc-safesemaphore-dev libghc-network-protocol-xmpp-dev (>= 0.4.3-1+b1) libghc-gnutls-dev (>= 0.1.4) libghc-xml-types-dev
+ dpkg-buildpackage: warning: build dependencies/conflicts unsatisfied; aborting
+ dpkg-buildpackage: warning: (Use -d flag to override.)
+ debuild: fatal error at line 1357:
+ dpkg-buildpackage -rfakeroot -D -us -uc failed
+ user@laptop(pc) ~/src/git/git-annex (git)-[master] % apt-get install libghc-dav-dev libghc-dbus-dev libghc-yesod-dev libghc-yesod-static-dev libghc-yesod- default-dev libghc-hamlet-dev libghc-clientsession-dev libghc-warp-dev libghc-wai-dev libghc-wai-logger-dev libghc-case-insensitive-dev libghc-http-types-dev libghc-blaze-builder-dev libghc-crypto-api-dev libghc-network-multicast-dev libghc-network-info-dev libghc-safesemaphore-dev libghc-network-protocol-xmpp-dev libghc-gnutls-dev libghc-xml-types-dev
+ Reading package lists... Done
+ Building dependency tree
+ Reading state information... Done
+ E: Unable to locate package libghc-dav-dev
+ E: Unable to locate package libghc-network-multicast-dev
+ E: Unable to locate package libghc-network-info-dev
+ E: Unable to locate package libghc-safesemaphore-dev
+
+How can I build the package? Or would it be possible for you to build the package and add it to the "Install" page (like the prebuilt linux tarball)? That would be great!
+
+Cheers and thanks for the hard work,
+Tobias
diff --git a/doc/forum/Building_a_Debian_package_of_git-annex/comment_1_0848513c46f3efa21bc34784554ae88a._comment b/doc/forum/Building_a_Debian_package_of_git-annex/comment_1_0848513c46f3efa21bc34784554ae88a._comment
new file mode 100644
index 000000000..39790c5ff
--- /dev/null
+++ b/doc/forum/Building_a_Debian_package_of_git-annex/comment_1_0848513c46f3efa21bc34784554ae88a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.238"
+ subject="comment 1"
+ date="2013-01-16T23:05:13Z"
+ content="""
+There is a package available already: <http://packages.debian.org/unstable/git-annex>
+
+This will install even on Debian stable, I think.
+"""]]
diff --git a/doc/forum/Building_git-annex-3.20121112-19309.mdwn b/doc/forum/Building_git-annex-3.20121112-19309.mdwn
new file mode 100644
index 000000000..68d5e3205
--- /dev/null
+++ b/doc/forum/Building_git-annex-3.20121112-19309.mdwn
@@ -0,0 +1,78 @@
+Hi,
+
+I have Problems building git-annex-3.20121112-19309, I rceive the following error:
+
+...
+ Loading object (static) dist/build/git-annex/git-annex-tmp/Utility/libmounts.o ... done
+ final link ... done
+
+ Assistant/Alert.hs:66:30:
+ Warning: default newline style has changed, using an explicit $newline is recommended
+
+ Assistant/Alert.hs:69:31:
+ Warning: default newline style has changed, using an explicit $newline is recommended
+ [157 of 279] Compiling Assistant.Types.DaemonStatus ( Assistant/Types/DaemonStatus.hs, dist/build/git-annex/git-annex-tmp/Assistant/Types/DaemonStatus.o )
+ [158 of 279] Compiling Assistant.Monad ( Assistant/Monad.hs, dist/build/git-annex/git-annex-tmp/Assistant/Monad.o )
+
+ Assistant/Monad.hs:86:16:
+ Couldn't match expected type `Assistant a'
+ with actual type `Reader AssistantData a'
+ Expected type: (AssistantData -> a) -> Assistant a
+ Actual type: (AssistantData -> a) -> Reader AssistantData a
+ In the expression: reader
+ In an equation for `getAssistant': getAssistant = reader
+
+ Assistant/Monad.hs:93:15:
+ Couldn't match expected type `Assistant t0'
+ with actual type `Reader r0 a0'
+ In the return type of a call of `reader'
+ In a stmt of a 'do' block: st <- reader threadState
+ In the expression:
+ do { st <- reader threadState;
+ liftIO $ runThreadState st a }
+
+ Assistant/Monad.hs:99:14:
+ Couldn't match expected type `Assistant t0'
+ with actual type `Reader r0 a0'
+ In the return type of a call of `reader'
+ In a stmt of a 'do' block: d <- reader id
+ In the expression:
+ do { d <- reader id;
+ liftIO $ io $ runAssistant d a }
+
+ Assistant/Monad.hs:105:14:
+ Couldn't match expected type `Assistant t0'
+ with actual type `Reader r0 a0'
+ In the return type of a call of `reader'
+ In a stmt of a 'do' block: d <- reader id
+ In the expression:
+ do { d <- reader id;
+ return $ runAssistant d a }
+
+ Assistant/Monad.hs:110:14:
+ Couldn't match expected type `Assistant t0'
+ with actual type `Reader r0 a0'
+ In the return type of a call of `reader'
+ In a stmt of a 'do' block: d <- reader id
+ In the expression:
+ do { d <- reader id;
+ return $ \ v -> runAssistant d $ a v }
+
+ Assistant/Monad.hs:115:14:
+ Couldn't match expected type `Assistant t0'
+ with actual type `Reader r0 a0'
+ In the return type of a call of `reader'
+ In a stmt of a 'do' block: d <- reader id
+ In the expression:
+ do { d <- reader id;
+ return $ \ v1 v2 -> runAssistant d (a v1 v2) }
+
+ Assistant/Monad.hs:120:12:
+ Couldn't match expected type `Assistant a0'
+ with actual type `Reader r0 a1'
+ In the return type of a call of `reader'
+ In the first argument of `(>>=)', namely `reader v'
+ In the expression: reader v >>= liftIO . io
+ cabal: Error: some packages failed to install:
+ git-annex-3.20121112 failed during the building phase. The exception was:
+ ExitFailure 1
diff --git a/doc/forum/Building_git-annex-3.20121112-19309/comment_1_b115e28c77fe748ee6643c41f766beb4._comment b/doc/forum/Building_git-annex-3.20121112-19309/comment_1_b115e28c77fe748ee6643c41f766beb4._comment
new file mode 100644
index 000000000..3b75dfeb6
--- /dev/null
+++ b/doc/forum/Building_git-annex-3.20121112-19309/comment_1_b115e28c77fe748ee6643c41f766beb4._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.252.11.120"
+ subject="comment 1"
+ date="2012-11-18T17:49:57Z"
+ content="""
+What platform are you building on?
+
+What version of ghc is installed?
+
+What version of the haskell mtl library is installed? (`cabal list --installed --simple-output mtl`)
+"""]]
diff --git a/doc/forum/Building_git-annex-3.20121112-19309/comment_2_8c6ae1fd74f14da12ccfa77dbd27fc65._comment b/doc/forum/Building_git-annex-3.20121112-19309/comment_2_8c6ae1fd74f14da12ccfa77dbd27fc65._comment
new file mode 100644
index 000000000..195f63991
--- /dev/null
+++ b/doc/forum/Building_git-annex-3.20121112-19309/comment_2_8c6ae1fd74f14da12ccfa77dbd27fc65._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmU_2tE75oyG0h2ZPN4lcroIKEMC8G-otE"
+ nickname="Michael"
+ subject="comment 2"
+ date="2012-11-19T06:57:54Z"
+ content="""
+This is an Ubuntu 12.04 system (3.2.0-29-generic-pae #46-Ubuntu SMP Fri Jul 27 17:25:43 UTC 2012 i686 i686 i386 GNU/Linux)
+
+ghc is 7.4.1
+
+mtl info is:
+
+MonadCatchIO-mtl 0.3.0.5
+mtl 2.0.1.0
+
+"""]]
diff --git a/doc/forum/Building_git-annex-3.20121112-19309/comment_3_2f30b301c14f3a7fa0f52715d6140353._comment b/doc/forum/Building_git-annex-3.20121112-19309/comment_3_2f30b301c14f3a7fa0f52715d6140353._comment
new file mode 100644
index 000000000..d4f48434c
--- /dev/null
+++ b/doc/forum/Building_git-annex-3.20121112-19309/comment_3_2f30b301c14f3a7fa0f52715d6140353._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.49"
+ subject="comment 3"
+ date="2012-11-25T18:56:01Z"
+ content="""
+On my Debian system, where it builds ok, I have the same ghc version, but version 2.1.1 of mtl. I suspect your old version of that is the problem. You can try using cabal to install a newer mtl:
+
+<pre>
+ cabal update
+ cabal install mtl
+</pre>
+"""]]
diff --git a/doc/forum/Building_git-annex-3.20121112-19309/comment_4_1e3c3903a71a2ff7109372aa4dd5742a._comment b/doc/forum/Building_git-annex-3.20121112-19309/comment_4_1e3c3903a71a2ff7109372aa4dd5742a._comment
new file mode 100644
index 000000000..1b59c3d2d
--- /dev/null
+++ b/doc/forum/Building_git-annex-3.20121112-19309/comment_4_1e3c3903a71a2ff7109372aa4dd5742a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.49"
+ subject="comment 4"
+ date="2012-11-25T20:26:33Z"
+ content="""
+I was able to reproduce this build failure with the same old version of mtl you have. I've adjusted the cabal build dependencies to require a newer version.
+"""]]
diff --git a/doc/forum/Cabal:_Could_not_resolve_dependencies___40__yesod__41__.mdwn b/doc/forum/Cabal:_Could_not_resolve_dependencies___40__yesod__41__.mdwn
new file mode 100644
index 000000000..f4878da20
--- /dev/null
+++ b/doc/forum/Cabal:_Could_not_resolve_dependencies___40__yesod__41__.mdwn
@@ -0,0 +1,19 @@
+Hi,
+
+I try to install git-annex master with cabal, so I cloned the git repo and run "cabal install --only-dependencies". This gives me the following error:
+
+ Resolving dependencies...
+ cabal: Could not resolve dependencies:
+ trying: git-annex-3.20120826 (user goal)
+ trying: git-annex-3.20120826:+oldyesod
+ trying: git-annex-3.20120826:+currentyesod
+ next goal: yesod-default (dependency of git-annex-3.20120826:+oldyesod)
+ rejecting: yesod-default-1.1.0 (conflict: git-annex-3.20120826:oldyesod =>
+ yesod-default(<=1.0.1.1))
+ rejecting: yesod-default-1.0.1.1, 1.0.1, 1.0.0, 0.6.1, 0.5.0, 0.4.1, 0.4.0,
+ 0.3.1 (conflict: git-annex-3.20120826:currentyesod => yesod-default(>=1.1.0))
+
+Any idea how to fix this? (PS: I'm running Kubuntu 12.04)
+
+Cheers,
+Tobias
diff --git a/doc/forum/Cabal:_Could_not_resolve_dependencies___40__yesod__41__/comment_1_2eb4f410b54a25fcc895893a3c631c43._comment b/doc/forum/Cabal:_Could_not_resolve_dependencies___40__yesod__41__/comment_1_2eb4f410b54a25fcc895893a3c631c43._comment
new file mode 100644
index 000000000..b18e74f7a
--- /dev/null
+++ b/doc/forum/Cabal:_Could_not_resolve_dependencies___40__yesod__41__/comment_1_2eb4f410b54a25fcc895893a3c631c43._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.16"
+ subject="comment 1"
+ date="2012-08-29T16:01:00Z"
+ content="""
+Hmm, cabal is not as smart as I'd hoped it could be. I've removed the support for old version of yesod.
+"""]]
diff --git a/doc/forum/Cabal:_Could_not_resolve_dependencies___40__yesod__41__/comment_2_44cd6f6dd674df105d6f0b3f320f3236._comment b/doc/forum/Cabal:_Could_not_resolve_dependencies___40__yesod__41__/comment_2_44cd6f6dd674df105d6f0b3f320f3236._comment
new file mode 100644
index 000000000..4d8b0a8aa
--- /dev/null
+++ b/doc/forum/Cabal:_Could_not_resolve_dependencies___40__yesod__41__/comment_2_44cd6f6dd674df105d6f0b3f320f3236._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawniayrgSdVLUc3c6bf93VbO-_HT4hzxmyo"
+ nickname="Tobias"
+ subject="comment 2"
+ date="2012-08-30T10:01:24Z"
+ content="""
+thanks, that resolved the dependency trouble.
+But now:
+
+ Building git-annex-3.20120826...
+ Preprocessing executable 'git-annex' for git-annex-3.20120826...
+
+ Utility/Yesod.hs:15:8:
+ Could not find module `Data.Default'
+ It is a member of the hidden package `data-default-0.5.0'.
+ Perhaps you need to add `data-default' to the build-depends in your .cabal file.
+ Use -v to see a list of the files searched for.
+
+"""]]
diff --git a/doc/forum/Cabal:_Could_not_resolve_dependencies___40__yesod__41__/comment_3_992af6855901df79a2018a07941cb8b6._comment b/doc/forum/Cabal:_Could_not_resolve_dependencies___40__yesod__41__/comment_3_992af6855901df79a2018a07941cb8b6._comment
new file mode 100644
index 000000000..09d0dbd9a
--- /dev/null
+++ b/doc/forum/Cabal:_Could_not_resolve_dependencies___40__yesod__41__/comment_3_992af6855901df79a2018a07941cb8b6._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.16"
+ subject="comment 3"
+ date="2012-08-30T16:59:07Z"
+ content="""
+The Data.Default problem is fixed now.
+"""]]
diff --git a/doc/forum/Calculating_Annex_Cost_by_Ping_Times.mdwn b/doc/forum/Calculating_Annex_Cost_by_Ping_Times.mdwn
new file mode 100644
index 000000000..996e864c3
--- /dev/null
+++ b/doc/forum/Calculating_Annex_Cost_by_Ping_Times.mdwn
@@ -0,0 +1 @@
+I threw together a pair of shell scripts for calculating the cost of a remote using ping times. I don't know how useful this is in practice, but the theory seemed sound to me. If I'm in a hotel room with my two laptops, I'd rather annex try to get a file from the other laptop than from my NAS all the way back home. I'd love to figure out how to also detect if I'm on my VerizonWireless connection at the time and multiply the cost of all connections over the Internet accordingly, but that's down the road. Latest versions of the pair of scripts will be at <https://gist.github.com/4410357>. I'm interested in feedback, so please fork the git repo on gist and send me changes/updates. Also of note is that these were written for MacOSX. If you're interested in using them on a different linux, pay attention to the format of the summary line of your ping command.
diff --git a/doc/forum/Calculating_Annex_Cost_by_Ping_Times/comment_1_9b4a6bc8d52ecbbdd537e8cf76757a80._comment b/doc/forum/Calculating_Annex_Cost_by_Ping_Times/comment_1_9b4a6bc8d52ecbbdd537e8cf76757a80._comment
new file mode 100644
index 000000000..2a2554f8d
--- /dev/null
+++ b/doc/forum/Calculating_Annex_Cost_by_Ping_Times/comment_1_9b4a6bc8d52ecbbdd537e8cf76757a80._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 1"
+ date="2012-12-30T23:01:39Z"
+ content="""
+You may want to use hop count, not ping times, for a rough guesstimate of distance.
+
+Generally speaking, this is a highly non-trivial problem that's subject to university research projects so unless you find a well-maintained third party tool to solve this problem, it's unlikely that you will find a truly general solution.
+
+Anyway, look into mtr for your distance measurements.
+
+
+Richard
+"""]]
diff --git a/doc/forum/Calculating_Annex_Cost_by_Ping_Times/comment_2_7e04f85c6ba74c18c8dde148aef9bf80._comment b/doc/forum/Calculating_Annex_Cost_by_Ping_Times/comment_2_7e04f85c6ba74c18c8dde148aef9bf80._comment
new file mode 100644
index 000000000..7dc4072eb
--- /dev/null
+++ b/doc/forum/Calculating_Annex_Cost_by_Ping_Times/comment_2_7e04f85c6ba74c18c8dde148aef9bf80._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmRFKwny4rArBaz-36xTcsJYqKIgdDaw5Q"
+ nickname="Andrew"
+ subject="comment 2"
+ date="2013-01-06T11:08:42Z"
+ content="""
+Yeah, I was debating between ping times (max or avg) and hop count and ultimately went with ping time because of this situation: From my office to my house is ~12 hops but because we peer with the cable modem provider the ping time is still ~5ms. But from my cell modem, it's ~8 hops but ping times of ~200ms.
+"""]]
diff --git a/doc/forum/Can_I_store_normal_files_in_the_git-annex_git_repository__63__.mdwn b/doc/forum/Can_I_store_normal_files_in_the_git-annex_git_repository__63__.mdwn
new file mode 100644
index 000000000..6d1083dd5
--- /dev/null
+++ b/doc/forum/Can_I_store_normal_files_in_the_git-annex_git_repository__63__.mdwn
@@ -0,0 +1,6 @@
+Is it possible to story ordinary files in the git repository, or is this going to confuse git-annex? In other words, can I safely run
+
+ git add .gitattributes
+ git commit -m 'remember attributes' .gitattributes
+
+..., or do I have to use `git-annex add` all time?
diff --git a/doc/forum/Can_I_store_normal_files_in_the_git-annex_git_repository__63__/comment_1_c8f9923d8dc76b8bed25dce5ae09b520._comment b/doc/forum/Can_I_store_normal_files_in_the_git-annex_git_repository__63__/comment_1_c8f9923d8dc76b8bed25dce5ae09b520._comment
new file mode 100644
index 000000000..8873edcde
--- /dev/null
+++ b/doc/forum/Can_I_store_normal_files_in_the_git-annex_git_repository__63__/comment_1_c8f9923d8dc76b8bed25dce5ae09b520._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://peter-simons.myopenid.com/"
+ ip="77.12.196.1"
+ subject="Solved"
+ date="2011-07-13T16:21:25Z"
+ content="""
+I got my answer on #vcs-home: Yes, git-annex and git get along fine.
+"""]]
diff --git a/doc/forum/Can__39__t_get_git-annex_merge_to_work_from_git_hook.mdwn b/doc/forum/Can__39__t_get_git-annex_merge_to_work_from_git_hook.mdwn
new file mode 100644
index 000000000..9c0f5c7d7
--- /dev/null
+++ b/doc/forum/Can__39__t_get_git-annex_merge_to_work_from_git_hook.mdwn
@@ -0,0 +1,41 @@
+I'm trying to automate syncing of two repos A and B. My goal is to run `git annex sync` from A and have the working copy of B updated automatically. According to the manual page, `git annex merge` should to the trick. It works just fine when I run it manually in B, but not when I run it from the post-receive hook, as suggested in the manual page.
+
+Here is a test script that illustrates the issue: <https://gist.github.com/anonymous/6197019>
+
+The output I get:
+
+ [...]
+ file1 exists after manual git annex merge
+ [...]
+ file2 does not exist after git annex merge in post-receive
+
+From the output I can see that `git annex merge` is run on the remote end, and seems to do it's thing (`file2` is added):
+
+ remote: merge git-annex (merging synced/git-annex into git-annex...)
+ remote: ok
+ remote: merge synced/master Updating 6e5bfba..0dcbcfd
+ remote: Fast-forward
+ remote: file2 | 1 +
+ remote: 1 file changed, 1 insertion(+)
+ remote: create mode 120000 file2
+ remote:
+ remote: ok
+
+However, the working copy in B does not have the file `file2`. Even worse, `git status` in B shows the file as deleted:
+
+ # On branch master
+ # Your branch is ahead of 'origin/master' by 2 commits.
+ #
+ # Changes not staged for commit:
+ # (use "git add/rm <file>..." to update what will be committed)
+ # (use "git checkout -- <file>..." to discard changes in working directory)
+ #
+ # deleted: file2
+ #
+ no changes added to commit (use "git add" and/or "git commit -a")
+
+So when running `git annex sync` from B now, the file will be deleted from A as well, which is not what I expected.
+
+This is on Ubuntu 12.04, using the precompiled git-annex tarball (amd64).
+
+What am I doing wrong?
diff --git a/doc/forum/Can__39__t_get_git-annex_merge_to_work_from_git_hook/comment_1_8b71cb6772b219c27c17392d5099907a._comment b/doc/forum/Can__39__t_get_git-annex_merge_to_work_from_git_hook/comment_1_8b71cb6772b219c27c17392d5099907a._comment
new file mode 100644
index 000000000..cfaff89b1
--- /dev/null
+++ b/doc/forum/Can__39__t_get_git-annex_merge_to_work_from_git_hook/comment_1_8b71cb6772b219c27c17392d5099907a._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://kallesoderman.myopenid.com/"
+ ip="85.224.35.48"
+ subject="Same problem here"
+ date="2013-08-14T20:20:42Z"
+ content="""
+I'm trying to achieve [[USB_backup_with_files_visible/]] but can't make the post-recieve or post-update hooks have any effect. The filesystem is vfat so there are some issues with mounting defaults and executables (do the hooks have to be executable?) but regardless of mount options no dice.
+
+ ``git-annex merge`` at the cli works perfectly. I havent been bitten by files being deleted and propagated though.
+
+Manually merging ruins my \"late for work need to bring data but to tired to think properly\" use case.
+"""]]
diff --git a/doc/forum/Can__39__t_get_git-annex_merge_to_work_from_git_hook/comment_2_af2a2634d8d128868022d033d6adb549._comment b/doc/forum/Can__39__t_get_git-annex_merge_to_work_from_git_hook/comment_2_af2a2634d8d128868022d033d6adb549._comment
new file mode 100644
index 000000000..0623ed1db
--- /dev/null
+++ b/doc/forum/Can__39__t_get_git-annex_merge_to_work_from_git_hook/comment_2_af2a2634d8d128868022d033d6adb549._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 2"
+ date="2013-08-23T18:35:01Z"
+ content="""
+Having just set up <http://annex.debconf.org> which uses a git hook to run `git annex merge`, I can say that the main problems you are likely to run into are:
+
+1. The hook might be run with the cwd not set to the top of the git repository. cd to the git repository in the hook to fix.
+2. The hook might be run with `GIT_DIR` set to a strange value (in my case, it was set to \".\"), which is not the actual .git directory location. Unsetting it fixes that.
+
+I don't know about how to get git hooks to work on FAT filesystems though. Hooks have to be executable, and most systems probably don't mount such filesystems with executability allowed.
+"""]]
diff --git a/doc/forum/Can__39__t_get_git-annex_merge_to_work_from_git_hook/comment_3_31ec762a0684d2ce87d229ed2924db93._comment b/doc/forum/Can__39__t_get_git-annex_merge_to_work_from_git_hook/comment_3_31ec762a0684d2ce87d229ed2924db93._comment
new file mode 100644
index 000000000..2a56b57e9
--- /dev/null
+++ b/doc/forum/Can__39__t_get_git-annex_merge_to_work_from_git_hook/comment_3_31ec762a0684d2ce87d229ed2924db93._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlq495p0WtZDUpxzYN9YnToZGODfCGnqOw"
+ nickname="Stanis"
+ subject="comment 3"
+ date="2013-08-24T13:30:52Z"
+ content="""
+Thanks joey, that's exactly what was happening.
+
+Just to repeat it here, if anyone else runs into the same problem, your post-receive hook has to look like this:
+
+ #!/bin/sh
+ unset GIT_DIR
+ cd ..
+ git annex merge
+
+"""]]
diff --git a/doc/forum/Can__39__t_get_pairing_to_work.mdwn b/doc/forum/Can__39__t_get_pairing_to_work.mdwn
new file mode 100644
index 000000000..fc45bffcb
--- /dev/null
+++ b/doc/forum/Can__39__t_get_pairing_to_work.mdwn
@@ -0,0 +1,5 @@
+I'm trying to pair my ~/music repositories on my two laptops (Ubuntu 10.04 and 12.04) using the Linux standalone tarball on my home WiFi network. After entering the same passphrase on both machines, nothing happens, both remain in "Pairing in progress" state.
+
+The router I'm using is, I think, fairly standard, it's a ZyXEL P-2812HNU-F1 with factory settings.
+
+Are others having the problem too? Any advice where I should start looking for what goes wrong?
diff --git a/doc/forum/Can__39__t_get_pairing_to_work/comment_1_b981977b4fb942fd109c37fcf40f35d7._comment b/doc/forum/Can__39__t_get_pairing_to_work/comment_1_b981977b4fb942fd109c37fcf40f35d7._comment
new file mode 100644
index 000000000..5e6690354
--- /dev/null
+++ b/doc/forum/Can__39__t_get_pairing_to_work/comment_1_b981977b4fb942fd109c37fcf40f35d7._comment
@@ -0,0 +1,22 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.8"
+ subject="comment 1"
+ date="2012-10-11T23:48:37Z"
+ content="""
+It's not clear from your description whether you
+
+a) Started the pairing process independently on both machines... which probably doesn't work.
+
+b) Started pairing on one machine, and the other one noticed and popped up a pair request alert where
+you re-entered the password.
+
+If b) didn't happen, then the the pairing broadcast is not being seen by the second machine.
+You can try using tcpdump or wireshark to see the traffic. The traffic will look like this:
+
+<pre>
+19:45:11.125893 IP 10.1.1.2.43376 > 224.0.0.1.55556: UDP, length 692
+</pre>
+
+If all is going well, you should be able to see that on both the machine that's initiating the pairing and the other machine. And every other machine on the network for that matter.
+"""]]
diff --git a/doc/forum/Can__39__t_get_pairing_to_work/comment_2_341e2ff6c88ace1b1422e16781edf580._comment b/doc/forum/Can__39__t_get_pairing_to_work/comment_2_341e2ff6c88ace1b1422e16781edf580._comment
new file mode 100644
index 000000000..541b0e581
--- /dev/null
+++ b/doc/forum/Can__39__t_get_pairing_to_work/comment_2_341e2ff6c88ace1b1422e16781edf580._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlZvtBCVyJw4O71OPsdwGpVh6iJ1W-xaPc"
+ nickname="Kilian"
+ subject="comment 2"
+ date="2012-10-17T14:39:58Z"
+ content="""
+Thanks - it seems to be a problem with my router's firmware.
+"""]]
diff --git a/doc/forum/Can__39__t_get_pairing_to_work/comment_3_0c8cce48f179f2564ff0844bb7ef6bd1._comment b/doc/forum/Can__39__t_get_pairing_to_work/comment_3_0c8cce48f179f2564ff0844bb7ef6bd1._comment
new file mode 100644
index 000000000..f1ade11f9
--- /dev/null
+++ b/doc/forum/Can__39__t_get_pairing_to_work/comment_3_0c8cce48f179f2564ff0844bb7ef6bd1._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 3"
+ date="2012-10-17T17:35:11Z"
+ content="""
+Well, that's interesting. I wonder if other broadcast network services work over your router? The most common one is probably the avahi/zeroconf services.
+"""]]
diff --git a/doc/forum/Can__39__t_get_pairing_to_work/comment_4_169d77b30cea05125068ee1eeb2ef328._comment b/doc/forum/Can__39__t_get_pairing_to_work/comment_4_169d77b30cea05125068ee1eeb2ef328._comment
new file mode 100644
index 000000000..7725a3a62
--- /dev/null
+++ b/doc/forum/Can__39__t_get_pairing_to_work/comment_4_169d77b30cea05125068ee1eeb2ef328._comment
@@ -0,0 +1,25 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlZvtBCVyJw4O71OPsdwGpVh6iJ1W-xaPc"
+ nickname="Kilian"
+ subject="comment 4"
+ date="2012-10-18T22:44:40Z"
+ content="""
+Hmm... using avahi-discover the two machines can indeed see some services offered by each other. A git-annex-assistant specific problem after all?
+
+So when I initiate a pairing on 192.168.1.63, and run tcpdump on the same machine, it looks like this:
+
+ke@thot:~/opt/git-annex.linux$ sudo tcpdump -i eth1 host 224.0.0.1 -n
+tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
+listening on eth1, link-type EN10MB (Ethernet), capture size 65535 bytes
+00:33:47.723989 IP 192.168.1.63.56243 > 224.0.0.1.55556: UDP, length 691
+00:33:49.729242 IP 192.168.1.63.55072 > 224.0.0.1.55556: UDP, length 691
+00:33:51.733358 IP 192.168.1.63.55115 > 224.0.0.1.55556: UDP, length 691
+00:33:53.736730 IP 192.168.1.63.60249 > 224.0.0.1.55556: UDP, length 691
+00:33:55.741641 IP 192.168.1.63.59753 > 224.0.0.1.55556: UDP, length 691
+
+The same command (modulo different interface name) on the other machine (192.168.1.59) turns up nothing:
+
+ke@apis:~/opt/git-annex.linux$ sudo tcpdump -i wlan0 host 224.0.0.1 -n
+tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
+listening on wlan0, link-type EN10MB (Ethernet), capture size 96 bytes
+"""]]
diff --git a/doc/forum/Can__39__t_get_pairing_to_work/comment_5_70e6c4f4f01277be1767b38ca8374793._comment b/doc/forum/Can__39__t_get_pairing_to_work/comment_5_70e6c4f4f01277be1767b38ca8374793._comment
new file mode 100644
index 000000000..2b249ab57
--- /dev/null
+++ b/doc/forum/Can__39__t_get_pairing_to_work/comment_5_70e6c4f4f01277be1767b38ca8374793._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.23"
+ subject="comment 5"
+ date="2012-10-22T16:18:56Z"
+ content="""
+So, the only difference I can think of is that avahi uses a different multicast address than the one I picked for git-annex. It may be that your router is only letting that one address through even though it's supposed to let a whole range through.
+
+I've prepared a test build of git-annex that uses the same 224.0.0.251 address avahi does. http://downloads.kitenet.net/tmp/git-annex-standalone-i386.tar.gz (i386 build)
+If you can try that and see how it behaves, I'll see if I need to change the address.
+"""]]
diff --git a/doc/forum/Can__39__t_get_pairing_to_work/comment_6_2cd014a76fac6e08269dfd8146957418._comment b/doc/forum/Can__39__t_get_pairing_to_work/comment_6_2cd014a76fac6e08269dfd8146957418._comment
new file mode 100644
index 000000000..49a5a9ac9
--- /dev/null
+++ b/doc/forum/Can__39__t_get_pairing_to_work/comment_6_2cd014a76fac6e08269dfd8146957418._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlZvtBCVyJw4O71OPsdwGpVh6iJ1W-xaPc"
+ nickname="Kilian"
+ subject="comment 6"
+ date="2012-10-22T19:44:45Z"
+ content="""
+Yep, with the test build I see the pair request and can respond to it!
+
+Pairing doesn't seem to succeed, but that looks like a different issue. I'll try around some more and report back, probably in a new thread.
+"""]]
diff --git a/doc/forum/Can__39__t_get_pairing_to_work/comment_7_b9b715084d5a5562998b1724699d49e5._comment b/doc/forum/Can__39__t_get_pairing_to_work/comment_7_b9b715084d5a5562998b1724699d49e5._comment
new file mode 100644
index 000000000..69d6e12e0
--- /dev/null
+++ b/doc/forum/Can__39__t_get_pairing_to_work/comment_7_b9b715084d5a5562998b1724699d49e5._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.23"
+ subject="comment 7"
+ date="2012-10-22T19:49:44Z"
+ content="""
+All right, I'll change the address.
+"""]]
diff --git a/doc/forum/Can__39__t_init_git_annex.mdwn b/doc/forum/Can__39__t_init_git_annex.mdwn
new file mode 100644
index 000000000..85be0e107
--- /dev/null
+++ b/doc/forum/Can__39__t_init_git_annex.mdwn
@@ -0,0 +1,15 @@
+It seems I can't initialize git annex:
+
+ $ git annex init "files2"
+ init files2
+ pre-commit hook (/Volumes/project/annex/.git/hooks/pre-commit) already exists, not configuring
+
+ git-annex: waitToSetLock: failed (Operation not supported)
+ failed
+ git-annex: init: 1 failed
+ $
+
+
+ `project` is a remote file server connected via `smb://`.
+
+ Any ideas why and how to fix?
diff --git a/doc/forum/Can__39__t_init_git_annex/comment_10_c4d2ab1ecf69718a2211c3ea7b27092b._comment b/doc/forum/Can__39__t_init_git_annex/comment_10_c4d2ab1ecf69718a2211c3ea7b27092b._comment
new file mode 100644
index 000000000..273d0c135
--- /dev/null
+++ b/doc/forum/Can__39__t_init_git_annex/comment_10_c4d2ab1ecf69718a2211c3ea7b27092b._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.8"
+ subject="comment 10"
+ date="2012-10-16T05:52:08Z"
+ content="""
+If you need a git repository with your regular file names on the smb share, none of the special remotes will meet your needs. You'd need to find a way to make it support POSIX locking to use git-annex on it in a full git repository.
+
+But I think that in most cases a directory special remote on such a share, with the git repository kept locally and git-annex used to pull files down to it as needed, would work ok.
+"""]]
diff --git a/doc/forum/Can__39__t_init_git_annex/comment_12_fca9ed3707e097bee2cd642424681005._comment b/doc/forum/Can__39__t_init_git_annex/comment_12_fca9ed3707e097bee2cd642424681005._comment
new file mode 100644
index 000000000..adc9fba3b
--- /dev/null
+++ b/doc/forum/Can__39__t_init_git_annex/comment_12_fca9ed3707e097bee2cd642424681005._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnZ0g2UAijV7RGrKtWPljCCAYHBJ3pwPvM"
+ nickname="Meng"
+ subject="comment 12"
+ date="2012-10-16T06:01:44Z"
+ content="""
+OK; The purpose of putting files on the remote `smb://` partition is to publish these big data files, so other (potentially non-technical) people can download and use them. They'll not be willing to learn how to use git, let alone git-annex. And i have multiple development machines that can generate revisions/updates to these big files. I previously just rsync from/to various development machines to/from this smb partition, but i find sometimes I don't always srync in correct direction. The hope is i can have annex on these development machines, and set the smb:// partition as the remote for these git annex. But it sounds like none of the special remote will have the original form, and a normal remote is not possible on smb:// partition.
+"""]]
diff --git a/doc/forum/Can__39__t_init_git_annex/comment_1_a294b5e7e52aa9f66a708866be16f137._comment b/doc/forum/Can__39__t_init_git_annex/comment_1_a294b5e7e52aa9f66a708866be16f137._comment
new file mode 100644
index 000000000..2dd0575ec
--- /dev/null
+++ b/doc/forum/Can__39__t_init_git_annex/comment_1_a294b5e7e52aa9f66a708866be16f137._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.8"
+ subject="comment 1"
+ date="2012-10-16T02:52:26Z"
+ content="""
+The smb:// is a red flag to me. git-annex relies on POSIX file locking, and I'll bet smb does not provide that, or, perhaps, your samba server needs a configuration change to support it.
+
+You might consider putting your git annex repository on the local filesystem, and setting up a [[special_remote|special_remotes]] on smb. The [[special_remotes/directory]] special remote is a likely choice.
+"""]]
diff --git a/doc/forum/Can__39__t_init_git_annex/comment_2_fcf678d5188821d63b4c9ea5b59474a8._comment b/doc/forum/Can__39__t_init_git_annex/comment_2_fcf678d5188821d63b4c9ea5b59474a8._comment
new file mode 100644
index 000000000..c3596a518
--- /dev/null
+++ b/doc/forum/Can__39__t_init_git_annex/comment_2_fcf678d5188821d63b4c9ea5b59474a8._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnZ0g2UAijV7RGrKtWPljCCAYHBJ3pwPvM"
+ nickname="Meng"
+ subject="comment 2"
+ date="2012-10-16T03:19:43Z"
+ content="""
+Thanks for getting back so quick; So, after doing
+
+ git annex initremote smb type=directory directory=/Volumes/subproject/ encryption=none
+ git annex describe smb \"smb://XXXhost.com/subproject\"
+
+What else do i need to do? Do i need to `git init` and/or `git annex init` in `/Volumes/subproject/`?
+"""]]
diff --git a/doc/forum/Can__39__t_init_git_annex/comment_3_c83f7dea7d5304e226e52eb3c43ef14a._comment b/doc/forum/Can__39__t_init_git_annex/comment_3_c83f7dea7d5304e226e52eb3c43ef14a._comment
new file mode 100644
index 000000000..c7680bc93
--- /dev/null
+++ b/doc/forum/Can__39__t_init_git_annex/comment_3_c83f7dea7d5304e226e52eb3c43ef14a._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.8"
+ subject="comment 3"
+ date="2012-10-16T04:12:55Z"
+ content="""
+Nope, you're set with just those two commands. You can now do things like \"git annex copy --to smb\"
+to put files there, and \"git annex get\" will get files from there as necessary.
+"""]]
diff --git a/doc/forum/Can__39__t_init_git_annex/comment_4_06a01dd51ffbfd006c0afb8eab40b530._comment b/doc/forum/Can__39__t_init_git_annex/comment_4_06a01dd51ffbfd006c0afb8eab40b530._comment
new file mode 100644
index 000000000..421f98e62
--- /dev/null
+++ b/doc/forum/Can__39__t_init_git_annex/comment_4_06a01dd51ffbfd006c0afb8eab40b530._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnZ0g2UAijV7RGrKtWPljCCAYHBJ3pwPvM"
+ nickname="Meng"
+ subject="comment 4"
+ date="2012-10-16T04:17:11Z"
+ content="""
+Could i use (some variant of) `git annex sync` to do two-way sync between local and `smb`?
+"""]]
diff --git a/doc/forum/Can__39__t_init_git_annex/comment_5_53c33484bded57abc60f0449331c7b05._comment b/doc/forum/Can__39__t_init_git_annex/comment_5_53c33484bded57abc60f0449331c7b05._comment
new file mode 100644
index 000000000..5bbbb7360
--- /dev/null
+++ b/doc/forum/Can__39__t_init_git_annex/comment_5_53c33484bded57abc60f0449331c7b05._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.8"
+ subject="comment 5"
+ date="2012-10-16T04:23:59Z"
+ content="""
+`git annex sync` only syncs the git repository, not file contents, and the special remote has no git repo, only file contents. `git annex copy` will avoid transferring things that are already there, so it's the way to go.
+
+If you want automatic syncing of file contents and lots of other magic including automatic commit of new files, you could try the [[assistant]].
+
+"""]]
diff --git a/doc/forum/Can__39__t_init_git_annex/comment_6_9e0ff44f6e62581bfc83f9f1da3e0100._comment b/doc/forum/Can__39__t_init_git_annex/comment_6_9e0ff44f6e62581bfc83f9f1da3e0100._comment
new file mode 100644
index 000000000..36c0bb5d5
--- /dev/null
+++ b/doc/forum/Can__39__t_init_git_annex/comment_6_9e0ff44f6e62581bfc83f9f1da3e0100._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnZ0g2UAijV7RGrKtWPljCCAYHBJ3pwPvM"
+ nickname="Meng"
+ subject="comment 6"
+ date="2012-10-16T04:38:40Z"
+ content="""
+OK; The reason i ask about `git annex sync` is because I had previously copied the large files onto `smb://` before setting up the `annex` and don't want to unnecessarily transfer large data over Internet again. But now if i do `git annex copy --to smb`, and check what's added/changed in `smb` end, i found
+
+ $ cd /Volumes/subproject
+ $ ls
+ 091 383 bigdir1 bigfile1 ...
+
+The files with numbers in names such as`091`, `383` are being added, the `bigfile1` and `bigdir1` are the ones previously copied there. What are those `091`, `383` etc.
+"""]]
diff --git a/doc/forum/Can__39__t_init_git_annex/comment_7_7f96b5ef05e2faf4a3dbe8bfc39b810e._comment b/doc/forum/Can__39__t_init_git_annex/comment_7_7f96b5ef05e2faf4a3dbe8bfc39b810e._comment
new file mode 100644
index 000000000..9c29567f6
--- /dev/null
+++ b/doc/forum/Can__39__t_init_git_annex/comment_7_7f96b5ef05e2faf4a3dbe8bfc39b810e._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.8"
+ subject="comment 7"
+ date="2012-10-16T04:52:12Z"
+ content="""
+That's where it stores files in the directory special remote. You can move the similar contents of /Volumes/subproject/.git/annex/objects/ to the same place as those and then run `git annex fsck --from smb --fast` and it'll learn about those files you already transferred.
+
+You probably also want to delete /Volumes/subproject/.git afterwards, and any git working tree that was checked out there before; the directory special remote does not use the git repository that you had there before.
+"""]]
diff --git a/doc/forum/Can__39__t_init_git_annex/comment_8_65ab8463716f4ddd7721a5bcfcd18fa0._comment b/doc/forum/Can__39__t_init_git_annex/comment_8_65ab8463716f4ddd7721a5bcfcd18fa0._comment
new file mode 100644
index 000000000..8f37408f7
--- /dev/null
+++ b/doc/forum/Can__39__t_init_git_annex/comment_8_65ab8463716f4ddd7721a5bcfcd18fa0._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnZ0g2UAijV7RGrKtWPljCCAYHBJ3pwPvM"
+ nickname="Meng"
+ subject="comment 8"
+ date="2012-10-16T05:22:54Z"
+ content="""
+Oh, I see. But what I need on the remote partition `/Volumes/subproject` connected via `smb://` is the actual `bigdir1` and `bigfile`, not the encoded objects. Maybe I should use some other types of special remote?
+"""]]
diff --git a/doc/forum/Can__39__t_init_git_annex/comment_9_31a45f6a72266190b3ed7a7b02e03d5b._comment b/doc/forum/Can__39__t_init_git_annex/comment_9_31a45f6a72266190b3ed7a7b02e03d5b._comment
new file mode 100644
index 000000000..94db3f2fe
--- /dev/null
+++ b/doc/forum/Can__39__t_init_git_annex/comment_9_31a45f6a72266190b3ed7a7b02e03d5b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnZ0g2UAijV7RGrKtWPljCCAYHBJ3pwPvM"
+ nickname="Meng"
+ subject="comment 9"
+ date="2012-10-16T05:33:06Z"
+ content="""
+Maybe i didn't explain clearly at the beginning: `/Volumes/subproject` is a remote partition connected via smb://. It doesn't have a `.git`. The content I mentioned previously \"copied\" there was copied via `cp -R`. And my local annex is `~/project/subproject` and it does have `.git` and `.git/annex` in it.
+"""]]
diff --git a/doc/forum/Can__39__t_install:_Mac_OS_10.8.2.mdwn b/doc/forum/Can__39__t_install:_Mac_OS_10.8.2.mdwn
new file mode 100644
index 000000000..d63acdcb8
--- /dev/null
+++ b/doc/forum/Can__39__t_install:_Mac_OS_10.8.2.mdwn
@@ -0,0 +1,36 @@
+###Tried to install git-annex.app
+
+- App hangs up
+- Cpu "git" load is 100
+- Had to force quite git-annex
+
+###Install thru command line: using Brew
+
+- Installed haskell
+- updated cabal
+- But when I do:
+
+`
+cabal install git-annex --bindir=$HOME/bin
+`
+
+**I get this**
+
+ Resolving dependencies...
+ Configuring gnuidn-0.2...
+ cabal: The program c2hs is required but it could not be found.
+ Configuring libxml-sax-0.7.3...
+ cabal: The pkg-config package libxml-2.0 is required but it could not be found.
+ cabal: Error: some packages failed to install:
+ git-annex-3.20121127.1 depends on libxml-sax-0.7.3 which failed to install.
+ gnuidn-0.2 failed during the configure step. The exception was:
+ ExitFailure 1
+ libxml-sax-0.7.3 failed during the configure step. The exception was:
+ ExitFailure 1
+ network-protocol-xmpp-0.4.4 depends on libxml-sax-0.7.3 which failed to install.
+
+Any help would be greatly appreciated.
+
+Thanks,
+
+Carlito
diff --git a/doc/forum/Can__39__t_install:_Mac_OS_10.8.2/comment_1_c44023d81e9e4f7c9341af0e4271a1e4._comment b/doc/forum/Can__39__t_install:_Mac_OS_10.8.2/comment_1_c44023d81e9e4f7c9341af0e4271a1e4._comment
new file mode 100644
index 000000000..43f86c8b0
--- /dev/null
+++ b/doc/forum/Can__39__t_install:_Mac_OS_10.8.2/comment_1_c44023d81e9e4f7c9341af0e4271a1e4._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.253.113"
+ subject="comment 1"
+ date="2012-12-06T18:09:13Z"
+ content="""
+The lack of c2hs can be dealt with by `cabal install c2hs` (which the install instructions already say to do).
+
+Nobody currently understands why git commands are spinning and using all CPU when run by the app. This is being tracked at [[bugs/OSX_app_issues]].
+"""]]
diff --git a/doc/forum/Can__39__t_install:_Mac_OS_10.8.2/comment_2_dfbcd39eedff28dc9ed866a8f1411ef3._comment b/doc/forum/Can__39__t_install:_Mac_OS_10.8.2/comment_2_dfbcd39eedff28dc9ed866a8f1411ef3._comment
new file mode 100644
index 000000000..904fbb15c
--- /dev/null
+++ b/doc/forum/Can__39__t_install:_Mac_OS_10.8.2/comment_2_dfbcd39eedff28dc9ed866a8f1411ef3._comment
@@ -0,0 +1,30 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlxKQEwwP6J58W0Dmfq0-v0j3LXtT5gNAA"
+ nickname="Carlito"
+ subject="Thanks"
+ date="2012-12-06T19:23:48Z"
+ content="""
+Thanks joey!
+
+Sorry missed `cabal install c2hs` in the instruction. But got passed that and still can't install.
+
+ Resolving dependencies...
+ Configuring libxml-sax-0.7.3...
+ cabal: The pkg-config package libxml-2.0 is required but it could not be found.
+ cabal: Error: some packages failed to install:
+ git-annex-3.20121127.1 depends on libxml-sax-0.7.3 which failed to install.
+ libxml-sax-0.7.3 failed during the configure step. The exception was:
+ ExitFailure 1
+ network-protocol-xmpp-0.4.4 depends on libxml-sax-0.7.3 which failed to install.
+
+I tried
+
+ brew install libxml2
+ cabal install libxml
+
+Also I added $HOME/.cabal/bin to my path
+
+Thanks,
+
+Carlito
+"""]]
diff --git a/doc/forum/Can__39__t_install:_Mac_OS_10.8.2/comment_3_b37b2a9906ffb956cca91adb4bb4e521._comment b/doc/forum/Can__39__t_install:_Mac_OS_10.8.2/comment_3_b37b2a9906ffb956cca91adb4bb4e521._comment
new file mode 100644
index 000000000..dbfff2a84
--- /dev/null
+++ b/doc/forum/Can__39__t_install:_Mac_OS_10.8.2/comment_3_b37b2a9906ffb956cca91adb4bb4e521._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.14.162"
+ subject="comment 3"
+ date="2012-12-06T21:20:19Z"
+ content="""
+I can't help with installing libraries on OSX, but you can disable XMPP support in git-annex like this: \"cabal install git-annex -f-XMPP\"
+"""]]
diff --git a/doc/forum/Can__39__t_install:_Mac_OS_10.8.2/comment_4_afddf16f8faedc78d458835480f10dc3._comment b/doc/forum/Can__39__t_install:_Mac_OS_10.8.2/comment_4_afddf16f8faedc78d458835480f10dc3._comment
new file mode 100644
index 000000000..c221455fc
--- /dev/null
+++ b/doc/forum/Can__39__t_install:_Mac_OS_10.8.2/comment_4_afddf16f8faedc78d458835480f10dc3._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlxKQEwwP6J58W0Dmfq0-v0j3LXtT5gNAA"
+ nickname="Carlito"
+ subject="Got it to work!"
+ date="2012-12-06T22:17:55Z"
+ content="""
+Had to link it:
+
+ brew install libxml2
+ brew link libxml2
+
+Thanks for your help.
+
+Will test out annex and leave any bug reports.
+"""]]
diff --git a/doc/forum/Can_we_have_remotes_that_aren__39__t_tracked__63___.mdwn b/doc/forum/Can_we_have_remotes_that_aren__39__t_tracked__63___.mdwn
new file mode 100644
index 000000000..684893e84
--- /dev/null
+++ b/doc/forum/Can_we_have_remotes_that_aren__39__t_tracked__63___.mdwn
@@ -0,0 +1,13 @@
+I'm wondering if it is possible to have remotes that don't have the *content* of git-annex tracked.
+
+# My use case:
+
+I have a number of projects that I am working on at any one time. They all are tracking independently by `git` and more recently I am using `git annex` to manage the large files.
+
+However because I have so many projects I work on one (called `AAA`), move to another, delete `AAA` to save disk space, ...time passes... return to `AAA`.
+
+Now, prior to `git-annex` I could just clone `AAA` from my central repository folder do work, commit, push, repeat and then delete and there is no indication that I had one, or many copies of `AAA` floating around. Now with `git-annex` there is some trail of me cloning, running `git annex get`, etc.
+
+Is there some way to set a remote as `untracked`? By that I mean it is classed as `untrusted` - so I can move files around, add them, copy to trusted remotes and delete the whole repository without worrying about losing data - but it also doesn't push any of the git-annex tracking info of where a copy of a file actually is. I don't want to know if any or all of my other `untracked` repositories have a copy of a file or not.
+
+I don't want my `git annex whereis` polluted with many references to repositories that just don't exist any more. I guess I could set them to dead but that still keeps all of the tracking info around in all the repos, which seems unnecessary...
diff --git a/doc/forum/Can_we_have_remotes_that_aren__39__t_tracked__63___/comment_1_35e5a963b9e58ed7773dfcb884f8ecbd._comment b/doc/forum/Can_we_have_remotes_that_aren__39__t_tracked__63___/comment_1_35e5a963b9e58ed7773dfcb884f8ecbd._comment
new file mode 100644
index 000000000..955c256ca
--- /dev/null
+++ b/doc/forum/Can_we_have_remotes_that_aren__39__t_tracked__63___/comment_1_35e5a963b9e58ed7773dfcb884f8ecbd._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 1"
+ date="2013-08-07T16:27:21Z"
+ content="""
+This seems like a reasonable request, so I've opened [[todo/untracked_remotes]]
+
+I will note that if you know the annex.uuid of the previous AAA repository, you can make the new one use that same uuid, just `git config annex.uuid $UUID`. (`git annex fsck --fast` would be a good idea after doing that.)
+"""]]
diff --git a/doc/forum/Cannot_find_git-annex_in_server.mdwn b/doc/forum/Cannot_find_git-annex_in_server.mdwn
new file mode 100644
index 000000000..6208c288e
--- /dev/null
+++ b/doc/forum/Cannot_find_git-annex_in_server.mdwn
@@ -0,0 +1,10 @@
+My server is running the precompiled tarball https://downloads.kitenet.net/git-annex/linux/current/
+
+git-annex version: 4.20130531-g5df09b5
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP
+
+The tarball is untared in "/opt/git-annex.linux" and this location is added to the users path in ".profile", who can launch the webapp as usual and so on.
+
+But when a git-annex client from another computer tries to stablish a remote server repository with the server via ssh, it will complain "/usr/bin/git-annex", "runshell" and so on are missing. And if the binaries in "/opt/git-annex.linux" are symlinked in "/usr/bin" they will start to miss the other bin and libs in the "/opt/git-annex.linux" source tree.
+
+As you can understand, I can't put the whole "/opt/git-annex.linux" folder tree in "/usr/bin". Is there any solution to make the precompiled tarball work properly as a git-annex server?
diff --git a/doc/forum/Cannot_find_git-annex_in_server/comment_1_bf7e98e6130698ad0dc92e3a6a63ade3._comment b/doc/forum/Cannot_find_git-annex_in_server/comment_1_bf7e98e6130698ad0dc92e3a6a63ade3._comment
new file mode 100644
index 000000000..b5685c901
--- /dev/null
+++ b/doc/forum/Cannot_find_git-annex_in_server/comment_1_bf7e98e6130698ad0dc92e3a6a63ade3._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-06-20T15:23:32Z"
+ content="""
+The standalone tarball does not need to be installed in /usr/bin or any other particular location. I *never* hardcode /usr/bin in anything.
+
+It seems likely to me that you have not correctly added /opt/git-annex.linux to PATH. You mention `.profile` -- but this is only used
+by bash when starting a login shell. So any non-login shells won't have it in path. You need to put something in .bashrc for that.
+
+Also, to use git-annex on a server, there is no reason at all to install the latest and greatest version. Any version 3 or greater build of git-annex will work fine on a server with newer git-annex versions on clients. So `apt-get install git-annex` is a much easier and nicer way to install it on a server. Most linux distributions have a package of git-annex and an easy way to install it.
+
+(It would also help if you pasted actual error messages, rather than a summary of an error message.)
+"""]]
diff --git a/doc/forum/Cannot_find_git-annex_in_server/comment_2_168dda4aed09f90a510bc453e8a7cda7._comment b/doc/forum/Cannot_find_git-annex_in_server/comment_2_168dda4aed09f90a510bc453e8a7cda7._comment
new file mode 100644
index 000000000..48c0a65af
--- /dev/null
+++ b/doc/forum/Cannot_find_git-annex_in_server/comment_2_168dda4aed09f90a510bc453e8a7cda7._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmCEE7m7pm6lqvYmgRSESRP9xqmmMm9ox8"
+ nickname="Daniel"
+ subject="comment 2"
+ date="2013-06-20T20:14:25Z"
+ content="""
+I'd rather use the package from the repositories. But this server is running an openSUSE install and the package manager could not resolve the Haskell dependencies of the unofficial git-annex rpm package.
+
+Indeed, performing the PATH extension in \".bashrc\", not in \".profile\", solved the issue. I feel like a newbie. Thanks for the express answer!
+"""]]
diff --git a/doc/forum/Cannot_launch_webapp_on_ubuntu_12.04_using_ppa.mdwn b/doc/forum/Cannot_launch_webapp_on_ubuntu_12.04_using_ppa.mdwn
new file mode 100644
index 000000000..351c6f92d
--- /dev/null
+++ b/doc/forum/Cannot_launch_webapp_on_ubuntu_12.04_using_ppa.mdwn
@@ -0,0 +1,6 @@
+Hi, I have installed latest version from https://launchpad.net/~rubiojr/+archive/git-annex, that is git-annex version: 3.20121017-ubuntu1ppa1~precise
+When running git annex webapp I get
+
+git-annex: unknown command webapp
+
+I only installed git-annex. Are there more packages to be installed to make it work?
diff --git a/doc/forum/Cannot_launch_webapp_on_ubuntu_12.04_using_ppa/comment_1_9345551f5772c3a6f1490b00e1edbf69._comment b/doc/forum/Cannot_launch_webapp_on_ubuntu_12.04_using_ppa/comment_1_9345551f5772c3a6f1490b00e1edbf69._comment
new file mode 100644
index 000000000..aae67b95e
--- /dev/null
+++ b/doc/forum/Cannot_launch_webapp_on_ubuntu_12.04_using_ppa/comment_1_9345551f5772c3a6f1490b00e1edbf69._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawniayrgSdVLUc3c6bf93VbO-_HT4hzxmyo"
+ nickname="Tobias"
+ subject="comment 1"
+ date="2013-04-23T08:39:50Z"
+ content="""
+This version does not have the webapp. Use a newer one (maybe you need the standalone build)
+"""]]
diff --git a/doc/forum/Cannot_launch_webapp_on_ubuntu_12.04_using_ppa/comment_2_0b688a442b6a911a0353e73097a24cb6._comment b/doc/forum/Cannot_launch_webapp_on_ubuntu_12.04_using_ppa/comment_2_0b688a442b6a911a0353e73097a24cb6._comment
new file mode 100644
index 000000000..b83eb40ec
--- /dev/null
+++ b/doc/forum/Cannot_launch_webapp_on_ubuntu_12.04_using_ppa/comment_2_0b688a442b6a911a0353e73097a24cb6._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="tomas"
+ ip="64.103.25.104"
+ subject="comment 2"
+ date="2013-04-23T11:50:21Z"
+ content="""
+According to documentation:
+http://git-annex.branchable.com/assistant/
+The git-annex assistant comes as part of git-annex, starting with version 3.20120924.
+
+So it should be there in 3.20121017, no?
+"""]]
diff --git a/doc/forum/Cannot_launch_webapp_on_ubuntu_12.04_using_ppa/comment_3_7e246caa00005560bb489c927c663046._comment b/doc/forum/Cannot_launch_webapp_on_ubuntu_12.04_using_ppa/comment_3_7e246caa00005560bb489c927c663046._comment
new file mode 100644
index 000000000..e2463ba23
--- /dev/null
+++ b/doc/forum/Cannot_launch_webapp_on_ubuntu_12.04_using_ppa/comment_3_7e246caa00005560bb489c927c663046._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-04-23T16:05:31Z"
+ content="""
+git-annex can be built without the webapp, and if some of the necessary dependencies for the webapp are not available, it will build without it by default. More recent versions than that one let you run `git annex version` and see the build flags, which can all be disabled due to missing dependencies. For example:
+
+ build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP
+
+Sergio does seem to be trying to backport all the dependencies of the webapp, but it looks to me like some of them, particularly haskell-xml-hamlet, have not successfully built yet.
+"""]]
diff --git a/doc/forum/Cannot_launch_webapp_on_ubuntu_12.04_using_ppa/comment_4_1d8025aabe8bc72711a77f691f67da5f._comment b/doc/forum/Cannot_launch_webapp_on_ubuntu_12.04_using_ppa/comment_4_1d8025aabe8bc72711a77f691f67da5f._comment
new file mode 100644
index 000000000..4c050f052
--- /dev/null
+++ b/doc/forum/Cannot_launch_webapp_on_ubuntu_12.04_using_ppa/comment_4_1d8025aabe8bc72711a77f691f67da5f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="fmarier"
+ ip="121.98.93.240"
+ subject="My PPA (Ubuntu Precise) has git-annex 4.20130417"
+ date="2013-04-27T23:31:54Z"
+ content="""
+It has the 90+ Haskell packages that are required to build git annex with every backend: https://launchpad.net/~fmarier/+archive/ppa
+"""]]
diff --git a/doc/forum/Cannot_launch_webapp_on_ubuntu_12.04_using_ppa/comment_5_7c2f95da65190016192424e7c622122f._comment b/doc/forum/Cannot_launch_webapp_on_ubuntu_12.04_using_ppa/comment_5_7c2f95da65190016192424e7c622122f._comment
new file mode 100644
index 000000000..6821da22d
--- /dev/null
+++ b/doc/forum/Cannot_launch_webapp_on_ubuntu_12.04_using_ppa/comment_5_7c2f95da65190016192424e7c622122f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawk3HGoDpnOPob5jOjvIootmkve1-nCpRiI"
+ nickname="Kalle"
+ subject="Debian Sid PowerPC is also without webapp"
+ date="2013-05-07T09:44:31Z"
+ content="""
+Took me a couple of minutes to figure out why git-annex on my old Apple G4 wouldn't recognise the webapp command. Comparing the version command output on AMD64 and PowerPC made it obvious.
+"""]]
diff --git a/doc/forum/Cannot_launch_webapp_on_ubuntu_12.04_using_ppa/comment_6_9b8465cefe609e7a696e7573b8892e38._comment b/doc/forum/Cannot_launch_webapp_on_ubuntu_12.04_using_ppa/comment_6_9b8465cefe609e7a696e7573b8892e38._comment
new file mode 100644
index 000000000..b2a6e55bb
--- /dev/null
+++ b/doc/forum/Cannot_launch_webapp_on_ubuntu_12.04_using_ppa/comment_6_9b8465cefe609e7a696e7573b8892e38._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="tomas"
+ ip="188.167.111.235"
+ subject="thanks for the ppa"
+ date="2013-05-08T10:04:25Z"
+ content="""
+Thanks François for your work
+"""]]
diff --git a/doc/forum/Cannot_launch_webapp_on_ubuntu_12.04_using_ppa/comment_7_af6472762a598a454ba52ac0caa059aa._comment b/doc/forum/Cannot_launch_webapp_on_ubuntu_12.04_using_ppa/comment_7_af6472762a598a454ba52ac0caa059aa._comment
new file mode 100644
index 000000000..d205e653d
--- /dev/null
+++ b/doc/forum/Cannot_launch_webapp_on_ubuntu_12.04_using_ppa/comment_7_af6472762a598a454ba52ac0caa059aa._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://openid.fmarier.org/"
+ nickname="fmarier"
+ subject="New location for my PPA"
+ date="2013-06-15T07:41:03Z"
+ content="""
+My Ubuntu Precise PPA has moved here: https://launchpad.net/~fmarier/+archive/git-annex
+
+It contains version 20130601 of git-annex.
+"""]]
diff --git a/doc/forum/Centralized_repository_with_webapp.mdwn b/doc/forum/Centralized_repository_with_webapp.mdwn
new file mode 100644
index 000000000..6a9fb285d
--- /dev/null
+++ b/doc/forum/Centralized_repository_with_webapp.mdwn
@@ -0,0 +1,13 @@
+Hi,
+
+I'm kind of new to git-annex, I've been following it for a while and tried small task, but never used it in a real situation.
+I'm now trying to sync various computers through a central server and I'm having some problems, so I think I might be doing something wrong.
+
+I have a remote server that I want to use as central server. I use the webapp to configure client 1 to use that server as remote server and using git (so I assume it stores the files and the tree). I then create the client 2 in another computer and doing the exact same steps.
+Initially everything seams to work, but after a few modifications in the clients weird things start to happen, files only in one client, some files don't get updated, etc.
+
+I guess I'm doing something wrong (maybe I need to clone the repo in client 2 instead of creating a new one?) but I can't figure out how to solve it.
+
+Any tip that could help me?
+
+Thanks!
diff --git a/doc/forum/Centralized_repository_with_webapp/comment_1_dcb9b07fd154f4d4fdef4809cc37ce77._comment b/doc/forum/Centralized_repository_with_webapp/comment_1_dcb9b07fd154f4d4fdef4809cc37ce77._comment
new file mode 100644
index 000000000..78866072e
--- /dev/null
+++ b/doc/forum/Centralized_repository_with_webapp/comment_1_dcb9b07fd154f4d4fdef4809cc37ce77._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-03-11T15:13:32Z"
+ content="""
+Your setup is fine as far as it goes. The problem is that a client has no way to know when another client has pushed a change to the centralized repository. It might take quite a while before it decides on its own to go pull changes from there (most often because *it* has now changed a file, and realizes it needs to sync), and so it won't see files the other client has added right away.
+
+The solution to this is to go to Configuration -> Jabber account, and set both clients up using the same Jabber account. (Or, if these two machines belong to different people, you can pick \"pair with a friend\" to link one with the other over Jabber.)
+
+Now when one client pushes to the centralized repository, it will immediately send the other a message letting it know something has changed.
+
+The webapp actually pops up an alert when you add that centralized ssh repository, to nudge you to do this:
+
+[[/assistant/xmppnudge.png]]
+
+I'm trying to find ways to make the need to do this more clear...
+"""]]
diff --git a/doc/forum/Centralized_repository_with_webapp/comment_2_08c84f2703f89dc12982eba9dd2a06d1._comment b/doc/forum/Centralized_repository_with_webapp/comment_2_08c84f2703f89dc12982eba9dd2a06d1._comment
new file mode 100644
index 000000000..a6686f6a3
--- /dev/null
+++ b/doc/forum/Centralized_repository_with_webapp/comment_2_08c84f2703f89dc12982eba9dd2a06d1._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawk9nck8WX8-ADF3Fdh5vFo4Qrw1I_bJcR8"
+ nickname="Jon Ander"
+ subject="comment 2"
+ date="2013-03-13T23:52:32Z"
+ content="""
+Hi Joey,
+
+My problem isn't that the repositories don't sync immediately, they are never up at the same time and I understand that the assistant is not constantly checking for changes, so that's not an issue.
+The problem is that with this setup I'm experiencing data loss (files being completely removed from both repos), it has happened a few times, but I cant seam to reproduce it reliably. I'll keep investigating and get back to you if I have a proper bug.
+"""]]
diff --git a/doc/forum/Change_remote_server_address.mdwn b/doc/forum/Change_remote_server_address.mdwn
new file mode 100644
index 000000000..722b4ada4
--- /dev/null
+++ b/doc/forum/Change_remote_server_address.mdwn
@@ -0,0 +1,6 @@
+Hi again,
+
+I have a SSH remote server that I registered to my git-annex repository via git-annex assistant. When I go to edit the settings for the repository from within git-annex assistant I noticed I can't edit the server address. If the server IP changes, how should I go about letting git-annex know of this? Can I just (1) shutdown git-annex assistant, (2) edit the 'url' line of the remote entry inside the repository's ``.git/config`` file, and then (3) start up git-annex assistant again? Is this a safe method for doing this?
+
+Regards,
+Blake
diff --git a/doc/forum/Change_remote_server_address/comment_1_401c3d2530ac7ba41dd3857ab4737ed5._comment b/doc/forum/Change_remote_server_address/comment_1_401c3d2530ac7ba41dd3857ab4737ed5._comment
new file mode 100644
index 000000000..d4e406829
--- /dev/null
+++ b/doc/forum/Change_remote_server_address/comment_1_401c3d2530ac7ba41dd3857ab4737ed5._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 1"
+ date="2013-11-01T16:35:47Z"
+ content="""
+Yes, you can certainly edit .git/config in any way you like and the assistant will use the new values when started back up.
+
+It shouldn't be using a hardcoded IP address normally, unless you manually entered an IP address when setting up that ssh remote. Using DNS is better..
+"""]]
diff --git a/doc/forum/Check_if_remote_is_using_GPG__63__.mdwn b/doc/forum/Check_if_remote_is_using_GPG__63__.mdwn
new file mode 100644
index 000000000..d719b2feb
--- /dev/null
+++ b/doc/forum/Check_if_remote_is_using_GPG__63__.mdwn
@@ -0,0 +1 @@
+Is there a way to check if a special remote is setup to use GPG? And, if so, see the ID of keys that it is encrypting to?
diff --git a/doc/forum/Check_if_remote_is_using_GPG__63__/comment_1_db8ce8ef50fc33a28860ee475988450f._comment b/doc/forum/Check_if_remote_is_using_GPG__63__/comment_1_db8ce8ef50fc33a28860ee475988450f._comment
new file mode 100644
index 000000000..ff073cd9a
--- /dev/null
+++ b/doc/forum/Check_if_remote_is_using_GPG__63__/comment_1_db8ce8ef50fc33a28860ee475988450f._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-03-17T18:59:40Z"
+ content="""
+You can tell this by looking at remote.log:
+
+git show git-annex:remote.log
+
+Remotes that are encrypted will have a big \"cipher=\" block in there, and ones that are encrypted to gpg public keys will have a list of the keys following \"cipherkeys=\"
+
+
+"""]]
diff --git a/doc/forum/Check_if_remote_is_using_GPG__63__/comment_2_11c7033904c9c7a1df766e915632c386._comment b/doc/forum/Check_if_remote_is_using_GPG__63__/comment_2_11c7033904c9c7a1df766e915632c386._comment
new file mode 100644
index 000000000..a88021352
--- /dev/null
+++ b/doc/forum/Check_if_remote_is_using_GPG__63__/comment_2_11c7033904c9c7a1df766e915632c386._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="annexuser"
+ ip="77.247.182.246"
+ subject="comment 2"
+ date="2013-03-17T22:25:58Z"
+ content="""
+If a special remote was setup using shared encryption, can I change it to using keys by simply doing `initremote myremote encryption=keyid`? Or should I remove the remote and start over?
+"""]]
diff --git a/doc/forum/Check_if_remote_is_using_GPG__63__/comment_3_a7ab70ad87a334c36761ddb3d830d99b._comment b/doc/forum/Check_if_remote_is_using_GPG__63__/comment_3_a7ab70ad87a334c36761ddb3d830d99b._comment
new file mode 100644
index 000000000..f467495b8
--- /dev/null
+++ b/doc/forum/Check_if_remote_is_using_GPG__63__/comment_3_a7ab70ad87a334c36761ddb3d830d99b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-03-18T15:09:53Z"
+ content="""
+git-annex won't let you change a remote's encryption scheme, as this would make any data stored in the remote using the old scheme be no longer accessible. You need to make a new remote. It should be fine to point the new remote at the same location as the old one, though.
+"""]]
diff --git a/doc/forum/Check_when_your_last_fsck_was__63__.mdwn b/doc/forum/Check_when_your_last_fsck_was__63__.mdwn
new file mode 100644
index 000000000..4a655cc1d
--- /dev/null
+++ b/doc/forum/Check_when_your_last_fsck_was__63__.mdwn
@@ -0,0 +1,4 @@
+Hey Joey,
+ Is there a way to see when the last fsck was? I know about --incremental and the related options, but sometimes I'd like to know when the last time I fsck'd a file (or even the whole repo) was. There doesn't seem to be a command line option for it, but I know that info is saved somewhere...maybe this could be part of 'git annex status'?
+
+$(words of gratitude and encouragement)
diff --git a/doc/forum/Check_when_your_last_fsck_was__63__/comment_1_ee98a1fcd796fe4fd7af6f77d0c1837d._comment b/doc/forum/Check_when_your_last_fsck_was__63__/comment_1_ee98a1fcd796fe4fd7af6f77d0c1837d._comment
new file mode 100644
index 000000000..ae8ffe42f
--- /dev/null
+++ b/doc/forum/Check_when_your_last_fsck_was__63__/comment_1_ee98a1fcd796fe4fd7af6f77d0c1837d._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-05-19T18:50:06Z"
+ content="""
+You're quite right. that info is stored in `.git/annex/fsckstate`. The timestamp of the file is when the last incremental fsck was started. The contents of the file is the same date, represented as seconds from epoch.
+
+That is only written to when doing an incremental fsck though. A non-incremental fsck does not touch the file.
+"""]]
diff --git a/doc/forum/Cleaning_up_after_aborted_sync_in_direct_mode.mdwn b/doc/forum/Cleaning_up_after_aborted_sync_in_direct_mode.mdwn
new file mode 100644
index 000000000..f0912fd74
--- /dev/null
+++ b/doc/forum/Cleaning_up_after_aborted_sync_in_direct_mode.mdwn
@@ -0,0 +1,19 @@
+I recently began experimenting with direct mode on a repository where only a very limited number of commands (`git annex sync`, `git annex add .`, etc.) are being used (through desktop buttons).
+
+Things were working well, and then on another repository in indirect mode I moved a large folder and synced that data with a bare repo, and synced the repo in direct mode with the same bare repo (to get everything in sync).
+
+At that point, git annex seemed to hang, taking forever to complete, and from looking a processes and files it seemed like it was going nowhere, so I killed it. I wish I had done a bit more diagnostics before that, but unfortunately I didn't.
+
+At that point, I noticed that the old directory was still there and that there were still many files in it, but the new folder had also been created and there were files there, too. So I thought the transfer was done, and for whatever reason `git annex sync` had just not cleaned up properly.
+
+In fact, the sync was only half done and the remaining files in the old directory were the only (local) copies (on the direct mode repo). I removed them and then synced again, which actually told git to delete those symlinks.
+
+When I updated another (indirect mode) repository I noticed this, so I reverted the commit in question and got the symlinks back, no data lost. Then I went back to the direct mode repo, switched to indirect mode because I was worried about direct mode, `git annex sync`ed, then `git annex get` to get the files again from a usb and everything was back to normal.
+
+Except that when I tried to go back to direct mode in that original repo, I got an error saying that git could not stat a file which is in the old (deleted) folder. Searching around, I noticed that in the `.git/annex/objects` directory, there are many remaining `.map` files with lines referring to the old (deleted) directory.
+
+Is there any way to "reset" this somehow? I would like to switch back to direct mode, and I'd prefer not to recreate the repo.
+
+Oh and I'm using version: 4.20130501-g4a5bfb3.
+
+Thanks!
diff --git a/doc/forum/Cleaning_up_after_aborted_sync_in_direct_mode/comment_1_3440b2e1662d3b113c18283afcbf4520._comment b/doc/forum/Cleaning_up_after_aborted_sync_in_direct_mode/comment_1_3440b2e1662d3b113c18283afcbf4520._comment
new file mode 100644
index 000000000..77c0ebbba
--- /dev/null
+++ b/doc/forum/Cleaning_up_after_aborted_sync_in_direct_mode/comment_1_3440b2e1662d3b113c18283afcbf4520._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnkBYpLu_NOj7Uq0-acvLgWhxF8AUEIJbo"
+ nickname="Chris"
+ subject="comment 1"
+ date="2013-05-10T03:50:26Z"
+ content="""
+Maybe a simpler question: if I delete all the `.map` and `.cache` files that are leftover in the `.git/annex/objects` directory, will that effectively \"reset\" the status so that I can then switch to direct mode?
+"""]]
diff --git a/doc/forum/Cleaning_up_after_aborted_sync_in_direct_mode/comment_2_9a61ba8ac4a375f1d69cd09b5a6f8091._comment b/doc/forum/Cleaning_up_after_aborted_sync_in_direct_mode/comment_2_9a61ba8ac4a375f1d69cd09b5a6f8091._comment
new file mode 100644
index 000000000..e471f113e
--- /dev/null
+++ b/doc/forum/Cleaning_up_after_aborted_sync_in_direct_mode/comment_2_9a61ba8ac4a375f1d69cd09b5a6f8091._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnkBYpLu_NOj7Uq0-acvLgWhxF8AUEIJbo"
+ nickname="Chris"
+ subject="comment 2"
+ date="2013-05-10T04:01:38Z"
+ content="""
+After reading [this](http://git-annex.branchable.com/internals/):
+
+> Also in direct mode, some additional data is stored in these directories. .cache files contain cached file stats used in detecting when a file has changed, and .map files contain a list of file(s) in the work directory that contain the key.
+
+I decided that indeed, deleting the `.map` and `.cache` files should do the trick, so I deleted them and direct mode works again.
+
+Still not sure what went wrong with the original sync, but at least I got things back on track.
+"""]]
diff --git a/doc/forum/Cleaning_up_after_aborted_sync_in_direct_mode/comment_3_6b9d8c48547f3d0a911310622ba91df7._comment b/doc/forum/Cleaning_up_after_aborted_sync_in_direct_mode/comment_3_6b9d8c48547f3d0a911310622ba91df7._comment
new file mode 100644
index 000000000..b7d495dea
--- /dev/null
+++ b/doc/forum/Cleaning_up_after_aborted_sync_in_direct_mode/comment_3_6b9d8c48547f3d0a911310622ba91df7._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-05-13T18:00:42Z"
+ content="""
+This sounds like one or more bugs that I should address, but I'm having trouble understanding exactly what you did, from your description, at the level of detail I need to replicate a problem.
+
+Do you still have a copy of the corrupted repository? Or any error messages to show me?
+
+It sounds like at least one problem might have been this bug: [[bugs/Unable_to_switch_back_to_direct_mode]]
+At least that is fixed in current git.
+"""]]
diff --git a/doc/forum/Coming_from_git_world.mdwn b/doc/forum/Coming_from_git_world.mdwn
new file mode 100644
index 000000000..ee8b844e8
--- /dev/null
+++ b/doc/forum/Coming_from_git_world.mdwn
@@ -0,0 +1,9 @@
+So i am coming from git world, All documentation and posts seemed to be for media etc. I have a simple question.
+
+Can i use git annex to manage large files , Which i think i can. But will it work with branching/tagging etc.
+
+e.g. We currently use git have some large files in git repo.... I am planning to move the large files to use annex. But would like to maintain branches, i.e. each branch might have different version of files and maybe tagged, So i can get back some old version from a branch.
+
+Is this possible ? I did not get any explicit answer or examples on how this works or even if its supported.
+
+Also can i use same folder for git and git-annex ?
diff --git a/doc/forum/Coming_from_git_world/comment_10_098bef38c2688607e869425a557cc482._comment b/doc/forum/Coming_from_git_world/comment_10_098bef38c2688607e869425a557cc482._comment
new file mode 100644
index 000000000..85ba7fe7f
--- /dev/null
+++ b/doc/forum/Coming_from_git_world/comment_10_098bef38c2688607e869425a557cc482._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.235"
+ subject="comment 10"
+ date="2013-07-10T17:05:49Z"
+ content="""
+It has its own ssh server written in java too, which hardcodes the set of commands it supports. AFAICS it would require some java coding to add a command to this, it does not seem to be designed for easy extensability.
+"""]]
diff --git a/doc/forum/Coming_from_git_world/comment_11_98d75a1415e0c3689ab4231855e61233._comment b/doc/forum/Coming_from_git_world/comment_11_98d75a1415e0c3689ab4231855e61233._comment
new file mode 100644
index 000000000..3dba0760b
--- /dev/null
+++ b/doc/forum/Coming_from_git_world/comment_11_98d75a1415e0c3689ab4231855e61233._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn5RcmefXjrl1vmbHIiOWQyXGXVKxlm3rg"
+ nickname="Kavin"
+ subject="comment 11"
+ date="2013-07-10T20:14:52Z"
+ content="""
+:( Ahh... So i guess this might not be possible in near future.
+
+Ill go to plan B, Setup another server which users will connect to for large files which will have git-annex installed. (So a central Repository for git annex). They will need to add another remote in git config.
+
+Does git annex have a way to manage ssh keys ? (Please can you point me to the location where i can read how git-annex-shell ? )
+"""]]
diff --git a/doc/forum/Coming_from_git_world/comment_12_5e7079e9bf3e4d97191333c66ac00e52._comment b/doc/forum/Coming_from_git_world/comment_12_5e7079e9bf3e4d97191333c66ac00e52._comment
new file mode 100644
index 000000000..2d7668737
--- /dev/null
+++ b/doc/forum/Coming_from_git_world/comment_12_5e7079e9bf3e4d97191333c66ac00e52._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.235"
+ subject="comment 12"
+ date="2013-07-10T21:10:03Z"
+ content="""
+Yes, a separate repository is one way to go, although I do not think it would be very hard to get gerrit's internal ssh to run git-annex-shell.
+
+[[git-annex-shell]] is a low-level restricted shell like git-shell, not a login manager, so it has nothing at all to do with ssh keys. Things like gitosis and gitolite can be built on top of git-shell and git-annex-shell and handle ssh key management.
+"""]]
diff --git a/doc/forum/Coming_from_git_world/comment_1_357443dc601ae38784c01cf18552f4d5._comment b/doc/forum/Coming_from_git_world/comment_1_357443dc601ae38784c01cf18552f4d5._comment
new file mode 100644
index 000000000..adc65d50f
--- /dev/null
+++ b/doc/forum/Coming_from_git_world/comment_1_357443dc601ae38784c01cf18552f4d5._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.235"
+ subject="comment 1"
+ date="2013-07-08T20:09:54Z"
+ content="""
+Yes, git-annex would not do very well at adding large file support to git if it did not handle tagging, branches, etc! So of course it does. It's in a sense too obvious a thing to get much mention. And so people sometimes get confused about it.
+
+The only thing to need to be aware of coming from git is that not every repository will have every version of every file locally available. When you check out a branch, you may need to run `git annex get` to retrieve those versions from origin or elsewhere.
+
+And, `git annex unused` can be used to find versions of files that no existing tag or branch refers to, and `git annex dropunused` can then delete those versions. If you want to ensure every revision in your git repo is accessible, you should avoid using those two commands; otherwise git-annex will never delete old versions of files.
+
+The unreleased git master adds a new feature, a --all switch that makes git annex commands operate on all versions of files. While normally `git annex get` will only do what it needs to to get all files in the currently checked out branch, `git annex get --all` will pull down every version of every file in the whole history. Similarly, `git annex copy --all --to origin` will ensure that every locally available version of every file is sent to origin.
+"""]]
diff --git a/doc/forum/Coming_from_git_world/comment_2_ed1847dd3f47a9d013b8dd0455fb80ff._comment b/doc/forum/Coming_from_git_world/comment_2_ed1847dd3f47a9d013b8dd0455fb80ff._comment
new file mode 100644
index 000000000..33d7d44d3
--- /dev/null
+++ b/doc/forum/Coming_from_git_world/comment_2_ed1847dd3f47a9d013b8dd0455fb80ff._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.235"
+ subject="comment 2"
+ date="2013-07-08T20:18:27Z"
+ content="""
+And yes, you can use the same git repository for files added to git `git add file` and added to git annex `git annex add file`
+"""]]
diff --git a/doc/forum/Coming_from_git_world/comment_3_09c6bb83a73d34dff2b8bc185a14a1db._comment b/doc/forum/Coming_from_git_world/comment_3_09c6bb83a73d34dff2b8bc185a14a1db._comment
new file mode 100644
index 000000000..07023ffe3
--- /dev/null
+++ b/doc/forum/Coming_from_git_world/comment_3_09c6bb83a73d34dff2b8bc185a14a1db._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn5RcmefXjrl1vmbHIiOWQyXGXVKxlm3rg"
+ nickname="Kavin"
+ subject="comment 3"
+ date="2013-07-08T23:27:45Z"
+ content="""
+Awesome!! thanks, As i am kicking the tires, Based on my current scenario, How can i deploy this in my company , So each developer to do the bare minimum, Like just install git annex and it should work.
+
+i.e. is it possible to avoid the step git remote add backup ? Then they can just do
+
+$ yum install git-annex
+$ cd repo
+$ git checkout staging
+$ git pull
+$ git annex get large_file
+
+And it then just works.
+"""]]
diff --git a/doc/forum/Coming_from_git_world/comment_4_6c731bb9a8d21dd9ab8c09612b23f908._comment b/doc/forum/Coming_from_git_world/comment_4_6c731bb9a8d21dd9ab8c09612b23f908._comment
new file mode 100644
index 000000000..f09281bc4
--- /dev/null
+++ b/doc/forum/Coming_from_git_world/comment_4_6c731bb9a8d21dd9ab8c09612b23f908._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.235"
+ subject="comment 4"
+ date="2013-07-09T18:14:07Z"
+ content="""
+I don't know where you got the \"git remote add backup\" step from. Obviously this is not necessary unless you want to add a remote named \"backup\".
+
+To use git-annex in a centralized git environment, which it sounds like you have here, you just need to install git-annex on the central git server, and arrange for all the developers to have ssh access to it. Then any git repository that is cloned from that server using ssh as the transport can support git-annex without the user needing to do anything special to set it up.
+
+This assumes that users have shell accounts on the server. git-annex includes the git-annex-shell program, which is similar to the git-shell in git. User accounts can be locked down to use this restricted shell if giving them full shell access to the server is not desired.
+
+If the server is using a git repository manager like gitolite or gitosis, those can also be adapted to use git-annex-shell. I got gitolite patched to support it earlier, see [[tips/using_gitolite_with_git-annex]].
+
+PS: I'm available for consulting on deploying git-annex in production environments. ;)
+"""]]
diff --git a/doc/forum/Coming_from_git_world/comment_5_e719d99af5afd90da3d3db692eff28dc._comment b/doc/forum/Coming_from_git_world/comment_5_e719d99af5afd90da3d3db692eff28dc._comment
new file mode 100644
index 000000000..ffeaaa6e0
--- /dev/null
+++ b/doc/forum/Coming_from_git_world/comment_5_e719d99af5afd90da3d3db692eff28dc._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn5RcmefXjrl1vmbHIiOWQyXGXVKxlm3rg"
+ nickname="Kavin"
+ subject="comment 5"
+ date="2013-07-09T20:32:51Z"
+ content="""
+Thank you very much!!!!! Yes, Planning to use Centralized repo. Basically what i understood was there will be a git server and separate server for hosting the large files. Its great to know i can use the same server and do not need to explicitly point to the server.
+
+As we are using Gerrit, What is the general best practice for it. (After i am done with it, I will write a blog post, As i am sure many people with centralized repo's might need this)
+Thanks!
+"""]]
diff --git a/doc/forum/Coming_from_git_world/comment_6_85a42106944dba9995fb3f4bfee3443a._comment b/doc/forum/Coming_from_git_world/comment_6_85a42106944dba9995fb3f4bfee3443a._comment
new file mode 100644
index 000000000..840553025
--- /dev/null
+++ b/doc/forum/Coming_from_git_world/comment_6_85a42106944dba9995fb3f4bfee3443a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.235"
+ subject="comment 6"
+ date="2013-07-09T20:39:25Z"
+ content="""
+Yes, the default for a repository accessed using ssh is to also store the large files in that repository. Of course you can set up a second remote to hold the large files if that works better.
+
+I don't have any personal experience with Gerrit. All I can say is that files managed by git-annex will appear as symlinks.
+"""]]
diff --git a/doc/forum/Coming_from_git_world/comment_7_90623294b910ceca3dc8ebd41b50fc9b._comment b/doc/forum/Coming_from_git_world/comment_7_90623294b910ceca3dc8ebd41b50fc9b._comment
new file mode 100644
index 000000000..50b34fb86
--- /dev/null
+++ b/doc/forum/Coming_from_git_world/comment_7_90623294b910ceca3dc8ebd41b50fc9b._comment
@@ -0,0 +1,38 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn5RcmefXjrl1vmbHIiOWQyXGXVKxlm3rg"
+ nickname="Kavin"
+ subject="comment 7"
+ date="2013-07-09T23:48:17Z"
+ content="""
+Thanks, So i made some progress, In the gerrit repo server, (which has git-annex installed)
+
+I ran:
+ git annex init origin,
+
+Did a clone of the repo, it had the branch git-annex, So i assumed all is working.
+
+I did a
+ git annex add
+and
+ git push
+
+Then when i try to
+ git annex copy --to origin
+
+I get error , But git-annex-shell is installed on the machine:
+
+ $ echo $PATH
+ /usr/lib64/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/gerrit2/bin
+ $ which git-annex-shell
+ /usr/bin/git-annex-shell
+
+
+
+ Gerrit Code Review: git-annex-shell: not found
+ rsync: connection unexpectedly closed (0 bytes received so far) [sender]
+ rsync error: error in rsync protocol data stream (code 12) at io.c(600) [sender=3.0.6]
+
+ rsync failed -- run git annex again to resume file transfer failed
+
+Any idea what i need to do to make it work ?
+"""]]
diff --git a/doc/forum/Coming_from_git_world/comment_8_28dbee30eb54877418f72eb8935302d8._comment b/doc/forum/Coming_from_git_world/comment_8_28dbee30eb54877418f72eb8935302d8._comment
new file mode 100644
index 000000000..668cfbd95
--- /dev/null
+++ b/doc/forum/Coming_from_git_world/comment_8_28dbee30eb54877418f72eb8935302d8._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.235"
+ subject="comment 8"
+ date="2013-07-10T16:42:18Z"
+ content="""
+If gerrit is handling incoming ssh connections, it's probable running its own restricted shell. That shell would need to be configured to spawn git-annex-shell when asked to do so in order for git-annex to transfer files to that repository.
+"""]]
diff --git a/doc/forum/Coming_from_git_world/comment_9_6edb36ea9535030fa3766937398e5bc7._comment b/doc/forum/Coming_from_git_world/comment_9_6edb36ea9535030fa3766937398e5bc7._comment
new file mode 100644
index 000000000..2f1034d17
--- /dev/null
+++ b/doc/forum/Coming_from_git_world/comment_9_6edb36ea9535030fa3766937398e5bc7._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawln3ckqKx0x_xDZMYwa9Q1bn4I06oWjkog"
+ nickname="Michael"
+ subject="comment 9"
+ date="2013-07-10T16:57:29Z"
+ content="""
+AFAIK Gerrit relies on jgit implementation of git in java; allowing it to execute helper programs like git-annex-shell may be tricky.
+"""]]
diff --git a/doc/forum/Compression_in_special_remotes___40__specifically_S3__41____63__.mdwn b/doc/forum/Compression_in_special_remotes___40__specifically_S3__41____63__.mdwn
new file mode 100644
index 000000000..49f3d75ef
--- /dev/null
+++ b/doc/forum/Compression_in_special_remotes___40__specifically_S3__41____63__.mdwn
@@ -0,0 +1 @@
+I use git-annex mostly to archive my photos. They're generally large raw files and I am encrypting them going to the S3 special remote. Are there any plans to compress objects before encrypting them? It would save on S3 costs, only add some overhead on get and copy, and I don't think there would be any problems looking up data later.
diff --git a/doc/forum/Compression_in_special_remotes___40__specifically_S3__41____63__/comment_1_9c6c4ca0c9dc6976ba7cf27e84683bf0._comment b/doc/forum/Compression_in_special_remotes___40__specifically_S3__41____63__/comment_1_9c6c4ca0c9dc6976ba7cf27e84683bf0._comment
new file mode 100644
index 000000000..7c5f1ecc1
--- /dev/null
+++ b/doc/forum/Compression_in_special_remotes___40__specifically_S3__41____63__/comment_1_9c6c4ca0c9dc6976ba7cf27e84683bf0._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.117"
+ subject="comment 1"
+ date="2012-12-14T18:53:04Z"
+ content="""
+gpg compresses encrypted content by default, so all encrypted special remotes get compression for free
+"""]]
diff --git a/doc/forum/DBus_on_Ubuntu_12.04__63__.mdwn b/doc/forum/DBus_on_Ubuntu_12.04__63__.mdwn
new file mode 100644
index 000000000..b4271d172
--- /dev/null
+++ b/doc/forum/DBus_on_Ubuntu_12.04__63__.mdwn
@@ -0,0 +1,3 @@
+I tried to compile the assitant branch on Ubuntu 12.04. But i depends on the DBus libraryw hich does not compile with some glibberish errors. Is there a way to solve this?
+
+
diff --git a/doc/forum/DBus_on_Ubuntu_12.04__63__/comment_1_dc14a40b64b7eda94d1a3fd766cd39cc._comment b/doc/forum/DBus_on_Ubuntu_12.04__63__/comment_1_dc14a40b64b7eda94d1a3fd766cd39cc._comment
new file mode 100644
index 000000000..0ef2469d3
--- /dev/null
+++ b/doc/forum/DBus_on_Ubuntu_12.04__63__/comment_1_dc14a40b64b7eda94d1a3fd766cd39cc._comment
@@ -0,0 +1,28 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.119"
+ subject="comment 1"
+ date="2012-08-25T13:06:31Z"
+ content="""
+Hmm, let's see...
+
+If the gibberish error is ouyay orgotfay otay otay elltay emay utwhay ethay
+roreay asway, then we can figure it out, surely..
+
+If the gibberish error looks something like Ḩ̶̞̗̓ͯ̅͒ͪͫe̢ͦ̊ͭͭͤͣ̂͏̢̳̦͔̬ͅ ̣̘̹̄̕͢Ç̛͈͔̹̮̗͈͓̞ͨ͂͑ͅo̿ͥͮ̿͢͏̧̹̗̪͇̫m̷̢̞̙͑̊̔ͧ̍ͩ̇̚ę̜͑̀͝s̖̱̝̩̞̻͐͂̐́̂̇̆͂
+
+.. your use of cabal
+has accidentually summoned Cthulu! Back slowly away from the monitor!
+
+Otherwise, you might try installing the `libdbus-1-dev` package with apt,
+which might make cabal install the haskell dbus bindings successfully. Or
+you could just install the `libghc-dbus-dev` package, which contains the
+necessary haskell library pre-built. But I don't know if it's in Ubuntu
+12.04; it only seems to be available in quantal
+<http://packages.ubuntu.com/search?keywords=libghc-dbus-dev>
+
+Or you could even build it with the Makefile, rather than using cabal.
+The Makefile has a `-DWITH_DBUS` setting in it that can be removed to build
+the fallback mode that doesn't use dbus.
+
+"""]]
diff --git a/doc/forum/DBus_on_Ubuntu_12.04__63__/comment_2_608a30e274e6a691a39f69503720e320._comment b/doc/forum/DBus_on_Ubuntu_12.04__63__/comment_2_608a30e274e6a691a39f69503720e320._comment
new file mode 100644
index 000000000..02bda9eaa
--- /dev/null
+++ b/doc/forum/DBus_on_Ubuntu_12.04__63__/comment_2_608a30e274e6a691a39f69503720e320._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.119"
+ subject="comment 2"
+ date="2012-08-25T13:11:37Z"
+ content="""
+I fnordgot to mention, cabal can be configured to not build with dbus too. The relevant incantation is:
+
+cabal install git-annex --flags=\"-Dbus\"
+"""]]
diff --git a/doc/forum/DBus_on_Ubuntu_12.04__63__/comment_3_791b9978b410c1aff7fd8ef05c38f5f9._comment b/doc/forum/DBus_on_Ubuntu_12.04__63__/comment_3_791b9978b410c1aff7fd8ef05c38f5f9._comment
new file mode 100644
index 000000000..4097070fd
--- /dev/null
+++ b/doc/forum/DBus_on_Ubuntu_12.04__63__/comment_3_791b9978b410c1aff7fd8ef05c38f5f9._comment
@@ -0,0 +1,40 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmU_2tE75oyG0h2ZPN4lcroIKEMC8G-otE"
+ nickname="Michael"
+ subject="Shame on me..."
+ date="2012-08-25T15:43:19Z"
+ content="""
+The build error is:
+
+$ cabal install DBus
+Resolving dependencies...
+Configuring DBus-0.4...
+checking for pkg-config... /usr/bin/pkg-config
+checking pkg-config is at least version 0.9.0... yes
+checking for DBUS... yes
+configure: creating ./config.status
+config.status: creating DBus.buildinfo
+Building DBus-0.4...
+Preprocessing library DBus-0.4...
+
+DBus/Message.hsc:1:14:
+ Warning: -XPatternSignatures is deprecated: use -XScopedTypeVariables or pragma {-# LANGUAGE ScopedTypeVariables #-} instead
+
+DBus/Message.hsc:2:12:
+ Warning: -fglasgow-exts is deprecated: Use individual extensions instead
+[1 of 5] Compiling DBus.Shared ( dist/build/DBus/Shared.hs, dist/build/DBus/Shared.o )
+[2 of 5] Compiling DBus ( dist/build/DBus.hs, dist/build/DBus.o )
+
+DBus.hsc:26:49:
+ Warning: In the use of `mkTyCon'
+ (imported from Data.Typeable):
+ Deprecated: \"either derive Typeable, or use mkTyCon3 instead\"
+[3 of 5] Compiling DBus.Internal ( dist/build/DBus/Internal.hs, dist/build/DBus/Internal.o )
+
+DBus/Internal.hsc:12:27:
+ Module `Control.Exception' does not export `throwDyn'
+cabal: Error: some packages failed to install:
+DBus-0.4 failed during the building phase. The exception was:
+ExitFailure 1
+
+"""]]
diff --git a/doc/forum/DBus_on_Ubuntu_12.04__63__/comment_4_8665c95299916138c4af375626d9ec7d._comment b/doc/forum/DBus_on_Ubuntu_12.04__63__/comment_4_8665c95299916138c4af375626d9ec7d._comment
new file mode 100644
index 000000000..abd154a6b
--- /dev/null
+++ b/doc/forum/DBus_on_Ubuntu_12.04__63__/comment_4_8665c95299916138c4af375626d9ec7d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.119"
+ subject="in the language of the ancients, small details matter"
+ date="2012-08-25T15:50:47Z"
+ content="""
+It seems that to cabal, \"DBus\" and \"dbus\" are different packages, and it seems you should install the latter, which has a current version of 0.10 which works and not some old 0.4 version.
+"""]]
diff --git a/doc/forum/DS__95__Store_files_are_not_added.mdwn b/doc/forum/DS__95__Store_files_are_not_added.mdwn
new file mode 100644
index 000000000..f0ccf2023
--- /dev/null
+++ b/doc/forum/DS__95__Store_files_are_not_added.mdwn
@@ -0,0 +1,3 @@
+The "git annex add" command adds new file to the annex. However ".DS_Store" files are ignored by git-annex. Is there a list of files that are being ignored?
+
+Maybe sometimes it's useful to add .DS_Store extended attribute data to the annex to ensure a complete sync of Mac files...
diff --git a/doc/forum/DS__95__Store_files_are_not_added/comment_1_30687306da9bd35ec02a806193c5e240._comment b/doc/forum/DS__95__Store_files_are_not_added/comment_1_30687306da9bd35ec02a806193c5e240._comment
new file mode 100644
index 000000000..3402b84c6
--- /dev/null
+++ b/doc/forum/DS__95__Store_files_are_not_added/comment_1_30687306da9bd35ec02a806193c5e240._comment
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ subject="comment 1"
+ date="2012-08-02T23:29:38Z"
+ content="""
+git-annex ignores whatever git does. See `git-ls-files` and the gitignore configuration.
+"""]]
diff --git a/doc/forum/Debugging_Git_Annex.mdwn b/doc/forum/Debugging_Git_Annex.mdwn
new file mode 100644
index 000000000..fc4d829a2
--- /dev/null
+++ b/doc/forum/Debugging_Git_Annex.mdwn
@@ -0,0 +1,4 @@
+Hi,
+May I know, how can I debug git-annex code.
+I am new to Haskell Platform, I would like to know which IDE can be used to debug haskell code.
+Thank You.
diff --git a/doc/forum/Debugging_Git_Annex/comment_1_ce63b2ee641a2338f1ad5ded9e6f09a8._comment b/doc/forum/Debugging_Git_Annex/comment_1_ce63b2ee641a2338f1ad5ded9e6f09a8._comment
new file mode 100644
index 000000000..84781a00a
--- /dev/null
+++ b/doc/forum/Debugging_Git_Annex/comment_1_ce63b2ee641a2338f1ad5ded9e6f09a8._comment
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ subject="This is not an easy question to answer..."
+ date="2012-06-04T19:49:46Z"
+ content="""
+Do you have a bug in git-annex that you need fixed, or are you just curious?
+"""]]
diff --git a/doc/forum/Debugging_Git_Annex/comment_2_1d70ff052d00f33c34fd45730ea13040._comment b/doc/forum/Debugging_Git_Annex/comment_2_1d70ff052d00f33c34fd45730ea13040._comment
new file mode 100644
index 000000000..017b34b0d
--- /dev/null
+++ b/doc/forum/Debugging_Git_Annex/comment_2_1d70ff052d00f33c34fd45730ea13040._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlYu7QmD7wrbHWkoxuriaA9XcijM-g5vrQ"
+ nickname="Royal"
+ subject="comment 2"
+ date="2012-06-05T17:19:16Z"
+ content="""
+Hi,
+
+I want to replace rsync with aspera-rsync. Whenever there is file transfer between 2 repositories which are in two different hosts, git-annex will use rsync protocol. I am trying to replace that rsync call with aspera-rsync so that transfer can be more faster. Since I am new to Haskell I am finding difficulties to understand the flow of execution. Is there any way I can debug so that I can get the flow?
+
+Thanks
+"""]]
diff --git a/doc/forum/Default_text__47__html_handler.mdwn b/doc/forum/Default_text__47__html_handler.mdwn
new file mode 100644
index 000000000..a6bf4aaab
--- /dev/null
+++ b/doc/forum/Default_text__47__html_handler.mdwn
@@ -0,0 +1,2 @@
+I've had to change my default `text/html .html` handler from a text editor to a browser to support the opening sequence of `git annex webapp`. any other way around this? perhaps to have it open the page in the default browser rather than the default text/html handler?
+
diff --git a/doc/forum/Default_text__47__html_handler/comment_1_4730061916c7e12b7a41906152f847ee._comment b/doc/forum/Default_text__47__html_handler/comment_1_4730061916c7e12b7a41906152f847ee._comment
new file mode 100644
index 000000000..e2424f1cc
--- /dev/null
+++ b/doc/forum/Default_text__47__html_handler/comment_1_4730061916c7e12b7a41906152f847ee._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.252.11.120"
+ subject="comment 1"
+ date="2012-11-13T17:25:07Z"
+ content="""
+Not without exposing the secret token to other users in the system by passing it as a parameter to the browser command. Which is why it uses the method it does.
+
+But, you can configure it to use a specific browser in the standard git way:
+
+git config web.browser chromium
+"""]]
diff --git a/doc/forum/Delete_unused_files__47__metadata.mdwn b/doc/forum/Delete_unused_files__47__metadata.mdwn
new file mode 100644
index 000000000..5c6b41399
--- /dev/null
+++ b/doc/forum/Delete_unused_files__47__metadata.mdwn
@@ -0,0 +1,7 @@
+After moving some files (about 1G, some big and some small files) in and out the annex, I noticed that the size of the repository has grown quite a bit. My empty repository now is over 100 MB (even after "git annex dropunused ..." and "git gc").
+
+Most of this size is not Git metadata but many small files in the git-annex branch that seem to hold information about files I deleted (even in the other known repositories).
+
+So is there a way to get rid of these useless but space consuming information?
+
+(Maybe there is no (elegant) way to remove the symlink versions from the Git history (is there?), but it would already be nice if those small git-annex metadata files could be removed)
diff --git a/doc/forum/Delete_unused_files__47__metadata/comment_1_3efc19895c8dec89b71ae3778b583fea._comment b/doc/forum/Delete_unused_files__47__metadata/comment_1_3efc19895c8dec89b71ae3778b583fea._comment
new file mode 100644
index 000000000..c0d779abd
--- /dev/null
+++ b/doc/forum/Delete_unused_files__47__metadata/comment_1_3efc19895c8dec89b71ae3778b583fea._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ subject="comment 1"
+ date="2012-08-07T20:06:26Z"
+ content="""
+You must have quite a number of files and/or location tracking churn to get the branch that large.
+
+Removing location tracking files for vanished files from the git-annex branch would not save much space.. Only a very little bit of tree object size going forward. The way the git-annex branch is merged does not really allow deleting files from it. And of course git uses space for even deleted files.
+
+It'd be possible to delete the git-annex branch entirely, first backing up git-annex:uuid.log git-annex:remote.log and git-annex:trust.log and then making a new, clean branch that those files are added back to. Then run git annex fsck on every clone to repopulate the location tracking info for files that still exit. (Note that this would also lose urls stored by `git-annex addurl`.)
+"""]]
diff --git a/doc/forum/Delete_unused_files__47__metadata/comment_2_23597d9468347b3d94257f3c02afe1b8._comment b/doc/forum/Delete_unused_files__47__metadata/comment_2_23597d9468347b3d94257f3c02afe1b8._comment
new file mode 100644
index 000000000..340debc11
--- /dev/null
+++ b/doc/forum/Delete_unused_files__47__metadata/comment_2_23597d9468347b3d94257f3c02afe1b8._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 2"
+ date="2012-08-08T14:54:42Z"
+ content="""
+I'm sort of getting into the same issue as I run 'git-annex get .' and 'git annex sync' with one of the annexes that I have on a nightly basis to collect data for back up reasons. But it's good to know there is a work around for it.
+"""]]
diff --git a/doc/forum/Detached_git_work_tree__63__.mdwn b/doc/forum/Detached_git_work_tree__63__.mdwn
new file mode 100644
index 000000000..3c1f6ae24
--- /dev/null
+++ b/doc/forum/Detached_git_work_tree__63__.mdwn
@@ -0,0 +1,11 @@
+Does git-annex (safely) handle detached work trees?
+
+That is, in git I can set `GIT_WORK_TREE=/dir/A` and `GIT_DIR=/dir/B` in the environment and have all my .git stuff in /dir/B and all my files in /dir/A.
+
+I can see this coming in useful for a few situations, but in particular for difficult file systems - like SMB or old implementations of NFS.
+
+In my particular case I have a Drobo (something like a proprietary NAS). The Drobo is linux based, but by default mounts as a samba share or if you install `unfsd` it can be mounted via NFS. Unfortunately, the nfs is v3 and doesn't allow locks, so git-annex barfs. :-(
+
+What I'd like to be able to do is have a direct mode annex on the drobo, with the git directory sitting on one of my linux machines. That machine would be the only one that would directly access the drobo data as an annex but other systems that look at the drobo would see what looks like a normal directory structure; for example my media centre - `mythtv` naturally! - would see "normal" names for my music collection, not SHA256 hashes...
+
+I guess there would be an issue if there were different `GIT_DIR`s pointing to the one `GIT_WORK_TREE`, but that is a caveat emptor IMHO.
diff --git a/doc/forum/Detached_git_work_tree__63__/comment_10_656c737772bf92be2c7a2f33bd2bb0f0._comment b/doc/forum/Detached_git_work_tree__63__/comment_10_656c737772bf92be2c7a2f33bd2bb0f0._comment
new file mode 100644
index 000000000..0bf9c12f4
--- /dev/null
+++ b/doc/forum/Detached_git_work_tree__63__/comment_10_656c737772bf92be2c7a2f33bd2bb0f0._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlRThEwuPnr8_bcuuCTQ0rQd3w6AfeMiLY"
+ nickname="Alex"
+ subject="comment 10"
+ date="2013-02-24T12:04:21Z"
+ content="""
+Been using it a few hours now and it works like a charm - first thing I did was get a sitemap of the LCA and FOSDEM talks and use addurl --fast on them, since I've been wanting to do that since I saw the lightning talk last year at FOSDEM.
+
+Thanks again for making this awesome utility!
+"""]]
diff --git a/doc/forum/Detached_git_work_tree__63__/comment_1_28ac35a325fba250721d9f1b7c994960._comment b/doc/forum/Detached_git_work_tree__63__/comment_1_28ac35a325fba250721d9f1b7c994960._comment
new file mode 100644
index 000000000..83721eac3
--- /dev/null
+++ b/doc/forum/Detached_git_work_tree__63__/comment_1_28ac35a325fba250721d9f1b7c994960._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.238"
+ subject="comment 1"
+ date="2013-01-14T16:32:51Z"
+ content="""
+Recent versions of git-annex support these variables. I haven't tested it extensively, but AFAIK it works.
+"""]]
diff --git a/doc/forum/Detached_git_work_tree__63__/comment_2_7128c26bbc8efea04a5a317edf0ca9f2._comment b/doc/forum/Detached_git_work_tree__63__/comment_2_7128c26bbc8efea04a5a317edf0ca9f2._comment
new file mode 100644
index 000000000..e9154c693
--- /dev/null
+++ b/doc/forum/Detached_git_work_tree__63__/comment_2_7128c26bbc8efea04a5a317edf0ca9f2._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlRThEwuPnr8_bcuuCTQ0rQd3w6AfeMiLY"
+ nickname="Alex"
+ subject="Having issues here"
+ date="2013-02-23T14:44:15Z"
+ content="""
+I'm trying to use git-annex with vcsh, and it doesn't seem to be respecting the GIT_WORK_TREE and GIT_DIR variables vcsh sets. If I try it manually, the same happens.
+
+Any time I try to invoke a git-annex subcommand (init, add) via vcsh (vcsh $repo annex init/add/etc) it spits out an error that \"git-annex: Not in a git repository.\"
+
+I'd really like this to work, so that I can manage the bigger files in my home with topic-based annexes alongside plain-git repos for dotfiles.
+
+"""]]
diff --git a/doc/forum/Detached_git_work_tree__63__/comment_3_a3c22f905748ff2c803e8621c74a87a0._comment b/doc/forum/Detached_git_work_tree__63__/comment_3_a3c22f905748ff2c803e8621c74a87a0._comment
new file mode 100644
index 000000000..0e59edd76
--- /dev/null
+++ b/doc/forum/Detached_git_work_tree__63__/comment_3_a3c22f905748ff2c803e8621c74a87a0._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.253.75"
+ subject="comment 3"
+ date="2013-02-23T15:01:57Z"
+ content="""
+@Alex, you forgot to say what version of git-annex you are having trouble with.
+"""]]
diff --git a/doc/forum/Detached_git_work_tree__63__/comment_4_8063921241760458349e7cb0cadf3d4e._comment b/doc/forum/Detached_git_work_tree__63__/comment_4_8063921241760458349e7cb0cadf3d4e._comment
new file mode 100644
index 000000000..b0d8fcd41
--- /dev/null
+++ b/doc/forum/Detached_git_work_tree__63__/comment_4_8063921241760458349e7cb0cadf3d4e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlRThEwuPnr8_bcuuCTQ0rQd3w6AfeMiLY"
+ nickname="Alex"
+ subject="comment 4"
+ date="2013-02-23T15:07:52Z"
+ content="""
+3.20130216.1 from Hackage - I packaged it for Exherbo specifically to try this, and installed it about two hours ago.
+"""]]
diff --git a/doc/forum/Detached_git_work_tree__63__/comment_5_4510a787255cb03e7d0c3e7b830b7d52._comment b/doc/forum/Detached_git_work_tree__63__/comment_5_4510a787255cb03e7d0c3e7b830b7d52._comment
new file mode 100644
index 000000000..693e8ef4d
--- /dev/null
+++ b/doc/forum/Detached_git_work_tree__63__/comment_5_4510a787255cb03e7d0c3e7b830b7d52._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.253.75"
+ subject="comment 5"
+ date="2013-02-23T16:44:48Z"
+ content="""
+So, I found and fixed that bug. It really seems to be working now. Although I've thought that at least twice before!
+
+There is an important caveat though, with using `GIT_DIR` and/or `GIT_WORK_TREE`.
+
+git-annex needs to check in symlinks that point at the git repository. If using `GIT_DIR`, those symlinks do not look like \"-> .git/annex/objects/\"; they instead point off to some git repository elsewhere, as a relative path. For example they could look like \"-> ../gitrepo/annex/objects/\". Similar when using `GIT_WORK_TREE`.
+
+But this is a problem if you want to use the same git repo elsewhere, with a git work tree and repo that are not set up the same relative to one-another, because the links will all be wrong. So, if you decide to use `GIT_DIR` or `GIT_WORK_TREE` with git-annex, any clone of the repository will need to place the git directory in the same place relative to the working tree.
+
+If you later want to change the relative paths between git directory and work tree, it would need to be changed in all clones of the repository, and then you could use `git annex fix` to update the symlinks.
+"""]]
diff --git a/doc/forum/Detached_git_work_tree__63__/comment_6_ffd9c67ecc5b46ae98996018573f5591._comment b/doc/forum/Detached_git_work_tree__63__/comment_6_ffd9c67ecc5b46ae98996018573f5591._comment
new file mode 100644
index 000000000..faecbf2f5
--- /dev/null
+++ b/doc/forum/Detached_git_work_tree__63__/comment_6_ffd9c67ecc5b46ae98996018573f5591._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlRThEwuPnr8_bcuuCTQ0rQd3w6AfeMiLY"
+ nickname="Alex"
+ subject="comment 6"
+ date="2013-02-23T21:23:18Z"
+ content="""
+Cool, thanks! The caveat shouldn't be much of a problem for my use case - with vcsh, the workdir is always $HOME, and I'm using the recommended mr-based workflow so the gitdir will always be ~/.config/vcsh/repo.d/$name.git in each clone.
+
+EDIT: fix erroneous path
+"""]]
diff --git a/doc/forum/Detached_git_work_tree__63__/comment_7_36ca007643c983604fc4aed6ec8cb3d2._comment b/doc/forum/Detached_git_work_tree__63__/comment_7_36ca007643c983604fc4aed6ec8cb3d2._comment
new file mode 100644
index 000000000..9e5d241a2
--- /dev/null
+++ b/doc/forum/Detached_git_work_tree__63__/comment_7_36ca007643c983604fc4aed6ec8cb3d2._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlRThEwuPnr8_bcuuCTQ0rQd3w6AfeMiLY"
+ nickname="Alex"
+ subject="Further possible issues"
+ date="2013-02-23T23:17:43Z"
+ content="""
+Mm, looking at the actual code changes it may still not work with vcsh - since multiple GIT_DIRS share one GIT_WORKTREE, some symlinks will point to ~/.config/vcsh/repo.d/foo.git and some will point to ~/.config/vcsh/repo.d/bar.git. When git annex is invoked with GIT_DIR='~/.config/vcsh/repo.d/bar.git', with the changes you made files annexed by ~/.config/vcsh/repo.d/foo.git will still match isLinkToAnnex.
+"""]]
diff --git a/doc/forum/Detached_git_work_tree__63__/comment_8_b7a2da4fbace7156e11c48a496a19dc9._comment b/doc/forum/Detached_git_work_tree__63__/comment_8_b7a2da4fbace7156e11c48a496a19dc9._comment
new file mode 100644
index 000000000..7d9d13a7a
--- /dev/null
+++ b/doc/forum/Detached_git_work_tree__63__/comment_8_b7a2da4fbace7156e11c48a496a19dc9._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.210"
+ subject="comment 8"
+ date="2013-02-23T23:23:01Z"
+ content="""
+That should not be a problem, because git-annex only acts on files that `git ls-files` lists.
+"""]]
diff --git a/doc/forum/Detached_git_work_tree__63__/comment_9_f9fa237a693d28178f0451799209f7e2._comment b/doc/forum/Detached_git_work_tree__63__/comment_9_f9fa237a693d28178f0451799209f7e2._comment
new file mode 100644
index 000000000..16702141c
--- /dev/null
+++ b/doc/forum/Detached_git_work_tree__63__/comment_9_f9fa237a693d28178f0451799209f7e2._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlRThEwuPnr8_bcuuCTQ0rQd3w6AfeMiLY"
+ nickname="Alex"
+ subject="comment 9"
+ date="2013-02-24T00:52:52Z"
+ content="""
+Alright then, sounds like it should be perfect! Thanks for the quick response!
+"""]]
diff --git a/doc/forum/Difference_between_copy__44___move_and_get__63__.mdwn b/doc/forum/Difference_between_copy__44___move_and_get__63__.mdwn
new file mode 100644
index 000000000..a94281a1f
--- /dev/null
+++ b/doc/forum/Difference_between_copy__44___move_and_get__63__.mdwn
@@ -0,0 +1,24 @@
+I'm starting to experiment with git annex. I'd like to use it for a centralized git repo that will be checked out often, but the clones will rarely need some large binary files (used for testing). Therefore, I've set up a centralized/bare git repo and a clone of that repo using the instructions at [centralized_git_repository_tutorial](http://git-annex.branchable.com/tips/centralized_git_repository_tutorial/) and [bare_repositories](http://git-annex.branchable.com/bare_repositories/). I've added some files to the annex in the clone.
+
+I'm struggling to understand the difference between copy, move, and get. Here's a sequence of commands:
+
+ >> git annex add shared/1bel.maegz
+ >> git commit -m "added first file"
+ >> git push
+ >> git annex move shared/1bel.maegz --to origin
+ ## Now it no longer exists in my local repo
+ >> git annex get shared/1bel.maegz
+ fails.
+ >> git annex get shared/1bel.maegz --from origin
+ fails.
+ >> git annex copy shared/1bel.maegz --from origin
+ fails.
+ >> git annex move shared/1bel.maegz --from origin
+ succeeds! Now I have the file in my clone.
+
+Each failure message is:
+
+ fatal: Could not switch to '../.git/annex/objects/W8/gZ/SHA256-s99196--62874e9b58e652c9c01e796c2bf38b2234a80e0cef95c185bb7f0857d9765df2': No such file or directory
+ git-annex: <file descriptor: 6>: hGetLine: end of file
+
+How are copy, move, and get different? Which one *should* I be using to move my large data into the central (bare) repo? Will it then be available to other clones?
diff --git a/doc/forum/Difference_between_copy__44___move_and_get__63__/comment_1_26ee8192af3a62178c1ccf17c6da5ca5._comment b/doc/forum/Difference_between_copy__44___move_and_get__63__/comment_1_26ee8192af3a62178c1ccf17c6da5ca5._comment
new file mode 100644
index 000000000..fb1aed5da
--- /dev/null
+++ b/doc/forum/Difference_between_copy__44___move_and_get__63__/comment_1_26ee8192af3a62178c1ccf17c6da5ca5._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-03-09T02:00:11Z"
+ content="""
+There is no particular reason to use any of copy, move, or get. Use which ever command makes sense at the time.
+
+The problem you're encoutering is that you have an old, and broken version of git-annex installed. Upgrade and the error message will go away and both get and copy, in your example, will work.
+"""]]
diff --git a/doc/forum/Different_annexes_pointing_to_same_special_remote__63__.mdwn b/doc/forum/Different_annexes_pointing_to_same_special_remote__63__.mdwn
new file mode 100644
index 000000000..8413a6e08
--- /dev/null
+++ b/doc/forum/Different_annexes_pointing_to_same_special_remote__63__.mdwn
@@ -0,0 +1,6 @@
+Is there likely to be any problem in pointing different annexes to the same special remote (i.e. rsync/box.com/etc.) ?
+
+As the objects are stored based on their SHA256 key the expectation is that the chance of collision is is small.
+
+The only problem I can foresee is where the same content is stored in more than one annex and it is deleted in the remote in one annex, but not the other - there won't be any protection against that, but for non-overlapping content this risk should be negligible.
+
diff --git a/doc/forum/Different_annexes_pointing_to_same_special_remote__63__/comment_1_359f46805e6508d03aadd90429937546._comment b/doc/forum/Different_annexes_pointing_to_same_special_remote__63__/comment_1_359f46805e6508d03aadd90429937546._comment
new file mode 100644
index 000000000..282ed82c8
--- /dev/null
+++ b/doc/forum/Different_annexes_pointing_to_same_special_remote__63__/comment_1_359f46805e6508d03aadd90429937546._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.210"
+ subject="comment 1"
+ date="2013-02-24T21:51:19Z"
+ content="""
+You're basically right. Additionally, if you use encryption, the keys used on the remote are themselves encrypted and so even the same content will result in different keys.
+
+With this said, it's easy to use a subdirectory of a rsync or box.com remote, and I'd rather recommend doing that, rather than jumbling multiple repositories data into a single directory.
+"""]]
diff --git a/doc/forum/Direct_special_remotes.mdwn b/doc/forum/Direct_special_remotes.mdwn
new file mode 100644
index 000000000..bf80d57f8
--- /dev/null
+++ b/doc/forum/Direct_special_remotes.mdwn
@@ -0,0 +1,26 @@
+I have a NAS at home which I access both as AFP/SMB shares and thru ssh/rsync. Now, I'd like to keep on using the shares as before, i.e., browsable via AFP/SMB with conventional file names. Ideally, I'd also like to git-annex some NAS shares, preferably, in direct mode. However, it seems out of the question to install git-annex on the NAS (hopefully, I'm wrong about this in the long run).
+
+Two **non-special remote setups** would be:
+
+1. Mount the share and turn it into a direct mode git annex repo. Does anybody have experience with this? I'd suspect this to be very inefficient due to the use of all the files in .git over AFP/SMB. Configuration as a WORM backend seems to be advised? (Edit: Well, I just tried this and 'git annex init' failed as described in this [forum post](http://git-annex.branchable.com/forum/Can__39__t_init_git_annex/). So AFP/SMB seem to be non-starters. :-( Furthermore, AFP/SMB are immediately detected as crippled and set to direct mode automatically.)
+2. Same as 1. but with a local GIT_DIR. This should work by having .git on the NAS link to the local GIT_DIR.
+
+Alternatively, I could treat my NAS as a [**web special remote**](http://git-annex.branchable.com/tips/using_the_web_as_a_special_remote/). Some URL schemes come to mind:
+
+* **file:** This would benefit from some wish list items ([recursive directory remote setup/addurl](http://git-annex.branchable.com/todo/wishlist:_recursive_directory_remote_setup__47__addurl/)).
+* **rsync:** AFAIK not implemented (yet?) as an option for web special remotes.
+* **sftp:** (Might also include ssh access.)
+
+The problem is that the "web semantics" don't really work in my use case:
+
+* Files might change/move on the NAS.
+* I'd like changes (e.g., renamed files) in my local repo to propagate to the NAS. Currently, git-annex would use git push for this purpose IIUC, however that's not available on the NAS...
+* the web semantics seem to imply that there is exactly one "web" repository (and the URL is fixed)
+
+All of these indicate a mismatch between my use case and web special remotes.
+
+Hence my question: **Would something like a "direct special remote" make sense?**
+
+As a starting point I'd look at a setup similar to 2. above, i.e., a remote "working copy" with local GIT_DIR. Except that instead of a whole local .git directory a branch in an existing .git dir might be more appropriate...
+
+--Chris
diff --git a/doc/forum/Direct_special_remotes/comment_1_50357130a1c57ad2fab70f71925faf02._comment b/doc/forum/Direct_special_remotes/comment_1_50357130a1c57ad2fab70f71925faf02._comment
new file mode 100644
index 000000000..09e977128
--- /dev/null
+++ b/doc/forum/Direct_special_remotes/comment_1_50357130a1c57ad2fab70f71925faf02._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmVICFY2CDP08xdsPr3cgmScomy9HA-1sk"
+ nickname="Andrew"
+ subject="comment 1"
+ date="2013-04-04T00:33:15Z"
+ content="""
+\"Dumb NAS in direct mode, without git-annex installed\" would greatly expand the possible use cases IMO - it would transform git-annex from a distributed filesystem to a general sync tool. Or maybe I'm dreaming.
+"""]]
diff --git a/doc/forum/Direct_special_remotes/comment_2_e94a722ca056a068bcc16eb822008602._comment b/doc/forum/Direct_special_remotes/comment_2_e94a722ca056a068bcc16eb822008602._comment
new file mode 100644
index 000000000..4b4d8632c
--- /dev/null
+++ b/doc/forum/Direct_special_remotes/comment_2_e94a722ca056a068bcc16eb822008602._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="https://pradermecker.myopenid.com/"
+ ip="81.244.179.73"
+ subject="Local rsync ssh remote (I am confused)"
+ date="2013-04-13T17:54:06Z"
+ content="""
+If I understand this right, it is not possible to use git-annex as a simple wrapper around rsync.
+
+My use case is this: I have a music folder on a plug computer running debian squeeze. The plug computer acts as a streaming music server. My wish is to create a local ssh remote to have my laptop git-annex music repo in sync with the plug computer. So ideally I don't want to install git-annex on the plug computer (but git is there so a git bare repo can be used).
+
+According to the UI, if I use \"Pairing with a local computer\", both computers needs to have git-annex installed. If I try \"Remote server\" either I need both machines git-annex aware or I need the content of the plug computer to be encrypted (which is obviously not what I want in this case).
+
+Is the use case supported by the UI ? Should I try with the CLI ?
+
+Thanks for your help
+
+
+"""]]
diff --git a/doc/forum/Direct_special_remotes/comment_4_187036bbfee0508e2914afb51ead3c71._comment b/doc/forum/Direct_special_remotes/comment_4_187036bbfee0508e2914afb51ead3c71._comment
new file mode 100644
index 000000000..1f6287111
--- /dev/null
+++ b/doc/forum/Direct_special_remotes/comment_4_187036bbfee0508e2914afb51ead3c71._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://pradermecker.myopenid.com/"
+ ip="81.244.190.181"
+ subject="comment 4"
+ date="2013-04-14T09:01:27Z"
+ content="""
+Thanks !
+
+Before trying the CLI, I will install have a go with installing git-annex on the plug computer.
+
+Do you know by any chance if version 3.20120629~bpo60+2 (the available version on squeeze-backport) will be compatible with the current latest release (4.20130405) ?
+
+I guess I am asking if version 3 is compatible with version 4.
+
+
+"""]]
diff --git a/doc/forum/Direct_special_remotes/comment_4_6bfbf60f2061d49b7d34c844e7e1dea2._comment b/doc/forum/Direct_special_remotes/comment_4_6bfbf60f2061d49b7d34c844e7e1dea2._comment
new file mode 100644
index 000000000..86621a00e
--- /dev/null
+++ b/doc/forum/Direct_special_remotes/comment_4_6bfbf60f2061d49b7d34c844e7e1dea2._comment
@@ -0,0 +1,66 @@
+[[!comment format=mdwn
+ username="andy"
+ ip="99.48.75.171"
+ subject="comment 4"
+ date="2013-04-14T01:07:19Z"
+ content="""
+@pradermecker: I think that the CLI would be able to do what you're describing (to some extent), but the issue is that the filenames it creates will be hashes, and not in the folder pattern that is on your laptop. Of course, if the plug computer uses file metadata to determine file info, and will search a directory tree, then it probably won't care that the files are named strange things.
+
+As a quick example:
+
+I have a repo with three files in it:
+
+ $ ls -R
+ .:
+ File 1 File 2 File 3
+
+I copy those files to a directory remote:
+
+ $ git annex copy --to=test-dir *
+ copy File 1 (to test-dir...)
+ ok
+ copy File 2 (to test-dir...)
+ ok
+ copy File 3 (to test-dir...)
+ ok
+ (Recording state in git...)
+
+Then I look at what's in my directory remote:
+
+ $ cd ../remote
+ $ ls -R
+ .:
+ 0d4 d35 f15
+
+ ./0d4:
+ d37
+
+ ./0d4/d37:
+ SHA256-s7--a940d8aadc02f798331b2d46f1a8ad2c9821783060f4a0810da42bf785855c1c
+
+ ./0d4/d37/SHA256-s7--a940d8aadc02f798331b2d46f1a8ad2c9821783060f4a0810da42bf785855c1c:
+ SHA256-s7--a940d8aadc02f798331b2d46f1a8ad2c9821783060f4a0810da42bf785855c1c
+
+ ./d35:
+ 55c
+
+ ./d35/55c:
+ SHA256-s7--ab1ad6a49c022416008887464b8dc03b523b9e81530cf47d1f6f7712c1b30955
+
+ ./d35/55c/SHA256-s7--ab1ad6a49c022416008887464b8dc03b523b9e81530cf47d1f6f7712c1b30955:
+ SHA256-s7--ab1ad6a49c022416008887464b8dc03b523b9e81530cf47d1f6f7712c1b30955
+
+ ./f15:
+ 3f2
+
+ ./f15/3f2:
+ SHA256-s7--d1993f1115215aa6389e33fa9979fb39bb29e5bed14661baf1cf6af3182f0164
+
+ ./f15/3f2/SHA256-s7--d1993f1115215aa6389e33fa9979fb39bb29e5bed14661baf1cf6af3182f0164:
+ SHA256-s7--d1993f1115215aa6389e33fa9979fb39bb29e5bed14661baf1cf6af3182f0164
+
+I haven't checked, but I think that the assistant will be able to use a special remote that you create from the CLI once you create it.
+
+To create a remote without encryption using the CLI, try a command of the form `git annex initremote remote-name blah blah blah encryption=none`
+Also see the information at [[special_remotes/directory]], [[special_remotes/rsync]], and [[Repo accessible from \"dumb\" client without git-annex]].
+"""]]
diff --git a/doc/forum/Direct_special_remotes/comment_5_69c34c655e4b153dfc0d1b8580091124._comment b/doc/forum/Direct_special_remotes/comment_5_69c34c655e4b153dfc0d1b8580091124._comment
new file mode 100644
index 000000000..bad1f635c
--- /dev/null
+++ b/doc/forum/Direct_special_remotes/comment_5_69c34c655e4b153dfc0d1b8580091124._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="andy"
+ ip="99.48.75.171"
+ subject="comment 4"
+ date="2013-04-16T07:57:05Z"
+ content="""
+Not I. Sorry. You might want to make a forum post about this, if you haven't already: [[forum]]
+"""]]
diff --git a/doc/forum/Direct_special_remotes/comment_6_b054cfc3d3f81873f3faae7eb4f5337c._comment b/doc/forum/Direct_special_remotes/comment_6_b054cfc3d3f81873f3faae7eb4f5337c._comment
new file mode 100644
index 000000000..5ade3f1d0
--- /dev/null
+++ b/doc/forum/Direct_special_remotes/comment_6_b054cfc3d3f81873f3faae7eb4f5337c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 6"
+ date="2013-04-16T17:03:36Z"
+ content="""
+Version 3.2012* is compatible with the current version. You can install that version anywhere you don't need the full assistant.
+"""]]
diff --git a/doc/forum/Does_Jabber_syncing_work_when_the_buddy_is_offline__63__.mdwn b/doc/forum/Does_Jabber_syncing_work_when_the_buddy_is_offline__63__.mdwn
new file mode 100644
index 000000000..d5a3d3a92
--- /dev/null
+++ b/doc/forum/Does_Jabber_syncing_work_when_the_buddy_is_offline__63__.mdwn
@@ -0,0 +1 @@
+Do both friends need to be online in order for Jabber syncing to work? Or will the pushed changes be stored on the Jabber server, so that when the remote machine does come online it can pull them even if the original machine is now offline?
diff --git a/doc/forum/Does_Jabber_syncing_work_when_the_buddy_is_offline__63__/comment_1_f290dd8547176793934f8077374e1c0a._comment b/doc/forum/Does_Jabber_syncing_work_when_the_buddy_is_offline__63__/comment_1_f290dd8547176793934f8077374e1c0a._comment
new file mode 100644
index 000000000..8df82612a
--- /dev/null
+++ b/doc/forum/Does_Jabber_syncing_work_when_the_buddy_is_offline__63__/comment_1_f290dd8547176793934f8077374e1c0a._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-02-27T17:54:47Z"
+ content="""
+Both friends need to be online at the same time to sync with Jabber.
+
+There are some extensions that store and forward jabber messages, but:
+
+* They are probably not widely available.
+* AFAIK they only forward chat messages. But we try not to use visible messages, because that would prevent
+ reusing your jabber account with git-annex.
+* Most importantly, the git protocol lets the sender and receiver communicate with each other to work out what data to transfer. If one if offline, the best that could be done is to upload the whole git repository!
+
+If you want the ability for off-line clients to sync up, you should add a shared bare git repository.
+"""]]
diff --git a/doc/forum/Does_Jabber_syncing_work_when_the_buddy_is_offline__63__/comment_2_c358eb51047f333e582bd824be5e0e65._comment b/doc/forum/Does_Jabber_syncing_work_when_the_buddy_is_offline__63__/comment_2_c358eb51047f333e582bd824be5e0e65._comment
new file mode 100644
index 000000000..b3efced0b
--- /dev/null
+++ b/doc/forum/Does_Jabber_syncing_work_when_the_buddy_is_offline__63__/comment_2_c358eb51047f333e582bd824be5e0e65._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="annexuser"
+ ip="24.16.193.140"
+ subject="comment 2"
+ date="2013-03-11T19:40:30Z"
+ content="""
+How would I add a shared bare git repository in the web app?
+"""]]
diff --git a/doc/forum/Does_Jabber_syncing_work_when_the_buddy_is_offline__63__/comment_3_a2332c0e7b29110b9aed2ab69ce9d8c4._comment b/doc/forum/Does_Jabber_syncing_work_when_the_buddy_is_offline__63__/comment_3_a2332c0e7b29110b9aed2ab69ce9d8c4._comment
new file mode 100644
index 000000000..c9a877980
--- /dev/null
+++ b/doc/forum/Does_Jabber_syncing_work_when_the_buddy_is_offline__63__/comment_3_a2332c0e7b29110b9aed2ab69ce9d8c4._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-03-11T19:45:34Z"
+ content="""
+That's done by the \"Remote server\" option on the Repositories page.
+
+You need to have git-annex (any old version will do) installed on the server for this to work.
+
+Of course, a regular git remote will do as well, although the assistant does not set this up. You could even use github for that remote, or a similar service; any remote added with `git remote add` will be used by the assistant.
+"""]]
diff --git a/doc/forum/Does_git-annex_version_big_files__63__.mdwn b/doc/forum/Does_git-annex_version_big_files__63__.mdwn
new file mode 100644
index 000000000..5cbe7d50a
--- /dev/null
+++ b/doc/forum/Does_git-annex_version_big_files__63__.mdwn
@@ -0,0 +1,5 @@
+Hi
+
+I am trying to understand how git-annex works. Does it version big files at all?
+
+thanks
diff --git a/doc/forum/Does_git-annex_version_big_files__63__/comment_1_0b44003c1dc53adb807298ae452f8004._comment b/doc/forum/Does_git-annex_version_big_files__63__/comment_1_0b44003c1dc53adb807298ae452f8004._comment
new file mode 100644
index 000000000..7f403f0cd
--- /dev/null
+++ b/doc/forum/Does_git-annex_version_big_files__63__/comment_1_0b44003c1dc53adb807298ae452f8004._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.27"
+ subject="comment 1"
+ date="2012-11-09T18:56:59Z"
+ content="""
+Yes. Have you read [[How_It_Works]]?
+"""]]
diff --git a/doc/forum/Does_git-annex_version_big_files__63__/comment_2_ca40b67abd7bd36155d16d0396d7472c._comment b/doc/forum/Does_git-annex_version_big_files__63__/comment_2_ca40b67abd7bd36155d16d0396d7472c._comment
new file mode 100644
index 000000000..a753d7e82
--- /dev/null
+++ b/doc/forum/Does_git-annex_version_big_files__63__/comment_2_ca40b67abd7bd36155d16d0396d7472c._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="karhun"
+ ip="99.20.248.32"
+ subject="comment 2"
+ date="2012-11-09T21:37:19Z"
+ content="""
+Hi
+
+Thanks for the pointer.
+
+The reason I asked about is that it says that \"git-annex allows managing files with git, without checking the file contents into git. \". So I was just trying to understand the mechanic behind the description. If it is not check into the git then probably it is not versioning the files. I assumed that it must be merely a sync tool.
+
+
+"""]]
diff --git a/doc/forum/Does_git-annex_version_big_files__63__/comment_3_32de3501feedce51b43ed9dcc399c7a9._comment b/doc/forum/Does_git-annex_version_big_files__63__/comment_3_32de3501feedce51b43ed9dcc399c7a9._comment
new file mode 100644
index 000000000..33c4ef7ba
--- /dev/null
+++ b/doc/forum/Does_git-annex_version_big_files__63__/comment_3_32de3501feedce51b43ed9dcc399c7a9._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="karhun"
+ ip="99.20.248.32"
+ subject="comment 3"
+ date="2012-11-12T05:58:16Z"
+ content="""
+Hi
+
+I have one more follow up question.
+
+So git-annex versions files as I understand. Is it possible to use it without file versioning and just use it as a sync tool. I realize that there are example scenarios to demonstrate it however I would like to disable versioning if possible because I am intending to use it on large folders with big binary type files.
+
+thanks
+
+"""]]
diff --git a/doc/forum/Does_git-annex_version_big_files__63__/comment_4_8c65a7f8bda3c876971c2801fb6a76a1._comment b/doc/forum/Does_git-annex_version_big_files__63__/comment_4_8c65a7f8bda3c876971c2801fb6a76a1._comment
new file mode 100644
index 000000000..f7f2e85dc
--- /dev/null
+++ b/doc/forum/Does_git-annex_version_big_files__63__/comment_4_8c65a7f8bda3c876971c2801fb6a76a1._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.27"
+ subject="comment 4"
+ date="2012-11-12T15:17:53Z"
+ content="""
+Let's suppose you delete a file from git, and sync the deletion. Later, you can run `git annex unused` and it will find content not needed by any branch of the git repository. And if you choose, you can use `git annex dropunused` to delete that content.
+"""]]
diff --git a/doc/forum/Does_migrate_ensure_data_integrity__63__.mdwn b/doc/forum/Does_migrate_ensure_data_integrity__63__.mdwn
new file mode 100644
index 000000000..872e7d53d
--- /dev/null
+++ b/doc/forum/Does_migrate_ensure_data_integrity__63__.mdwn
@@ -0,0 +1,7 @@
+Out of simple curiosity, how does 'git annex migrate' work? I'm mostly wondering how file integrity is ensured.
+
+Let's say you want to migrate foo.txt from (say) md5 to sha256. Does git annex simply sha256sum foo.txt and rename it in the .git/objects folder to the new sum? Or does it md5sum foo.txt, verify that it's the not corrupt, then sha256sum it and rename to the new sum?
+
+You could run into problems if you migrate without first verifying; if the file is corrupt and you simply sha256sum and rename it, then the file wouldn't seem corrupt at your next fsck.
+
+I'm sure you've considered this during the basic design phase of git-annex, but I'd just like to be sure. I'm kind of paranoid when it comes to data integrity. =P
diff --git a/doc/forum/Does_migrate_ensure_data_integrity__63__/comment_1_cef50b32c46f4406c6f918c5866ddc15._comment b/doc/forum/Does_migrate_ensure_data_integrity__63__/comment_1_cef50b32c46f4406c6f918c5866ddc15._comment
new file mode 100644
index 000000000..7c819a8ca
--- /dev/null
+++ b/doc/forum/Does_migrate_ensure_data_integrity__63__/comment_1_cef50b32c46f4406c6f918c5866ddc15._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-05-13T18:28:01Z"
+ content="""
+I actually didn't originally consider this, but it turns out I have wonderful users, and you're at least the second to consider this case.
+
+So the released git-annex version does already verify the checksum when doing a migration. However, as I was checking this, I noticed
+I had left a window between the verification and the generation of the new key for the migration. It's pretty unlikely a file would get corrupted just as it was being migrated, but that's no excuse. I've committed a change that reverses the order; so it generates a new key and then verifies the old one.
+"""]]
diff --git a/doc/forum/Does_migrate_ensure_data_integrity__63__/comment_2_f389b924c8531b35fdf5dedd10fc8000._comment b/doc/forum/Does_migrate_ensure_data_integrity__63__/comment_2_f389b924c8531b35fdf5dedd10fc8000._comment
new file mode 100644
index 000000000..c377d814c
--- /dev/null
+++ b/doc/forum/Does_migrate_ensure_data_integrity__63__/comment_2_f389b924c8531b35fdf5dedd10fc8000._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="GLITTAH"
+ ip="154.51.136.37"
+ subject="comment 2"
+ date="2013-05-14T15:54:08Z"
+ content="""
+An even better solution. Thanks for your time and effort joey!
+"""]]
diff --git a/doc/forum/Don__39__t_understand_how_to_delete__47__recover_files.mdwn b/doc/forum/Don__39__t_understand_how_to_delete__47__recover_files.mdwn
new file mode 100644
index 000000000..aae2bf276
--- /dev/null
+++ b/doc/forum/Don__39__t_understand_how_to_delete__47__recover_files.mdwn
@@ -0,0 +1,25 @@
+My Use Case:
+
+I try basicly to use annex as a raid-like tool (at least thats the first step)
+
+so I added some big files to it, and then I synced it to a usb-remote. So far all did go well...
+
+No I startet annex watch daemon... because I thought it would then watch the files and checkin and out at least for the "origin" copy of the files.
+
+Then I thought lets delete some files I dont need anymore... so... rm.... ^^
+
+Maybe I just wanted to see what happens or if that would magicly do what I wanted him to do... ok I knew that it would not delete the file on the usb-drive (backup...) ok... but maybe at least localy...
+
+
+Now what did happen instead of that... the links are gone yes... the files it self are in the .git objects tree, so they did not get deleted, so ok not the way I wanted... have to unlock it first, would make maybe sense...
+
+So I tried first to get the links back... tried fix, tried unused, tried get... but the links doesnt show up again...
+
+is there a way to first bring back the links?
+is it save or the right way to just git rebase HEAD~3 to bring the links back?
+
+and then when I want to delete files from all places whats the way to do that... annex unlock -> then delete? or git drop filex --copies=0 or something?
+
+like I said I try to use is like a more flexible raid thing, this files are to big to really back em up with history... I watch them... and then soon I will often delete them (from everywhere). but other parts stay... I dont delete them then... ^^
+
+So maybe I missuse annex for that usecase... try to find that out ;)
diff --git a/doc/forum/Don__39__t_understand_how_to_delete__47__recover_files/comment_1_b307bfb0b70d649897f411eb753bd50a._comment b/doc/forum/Don__39__t_understand_how_to_delete__47__recover_files/comment_1_b307bfb0b70d649897f411eb753bd50a._comment
new file mode 100644
index 000000000..739319b71
--- /dev/null
+++ b/doc/forum/Don__39__t_understand_how_to_delete__47__recover_files/comment_1_b307bfb0b70d649897f411eb753bd50a._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.60"
+ subject="comment 1"
+ date="2012-09-16T00:14:49Z"
+ content="""
+You can use any git command you like like `git rebase` or `git revert` to operate on the links.
+
+git-annex, like git, keeps data for files that have been deleted.
+
+The `git annex unused` command will find that data and let you remove it. See [[walkthrough/unused_data]].
+
+
+"""]]
diff --git a/doc/forum/Don__39__t_understand_how_to_delete__47__recover_files/comment_2_58a6a1476274b8c4feb3d43ecd998759._comment b/doc/forum/Don__39__t_understand_how_to_delete__47__recover_files/comment_2_58a6a1476274b8c4feb3d43ecd998759._comment
new file mode 100644
index 000000000..01ad2901d
--- /dev/null
+++ b/doc/forum/Don__39__t_understand_how_to_delete__47__recover_files/comment_2_58a6a1476274b8c4feb3d43ecd998759._comment
@@ -0,0 +1,41 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn4bbuawnh-nSo9pAh8irYAcV4MQCcfdHo"
+ nickname="Stefan"
+ subject="thanx for fast help ;)"
+ date="2012-09-16T16:09:29Z"
+ content="""
+git-annex version: 3.20120629
+
+git annex unused did not show me anything... dont know why... I did only \"rm Directory\" not git rm... but \"git annex watch\" did check it in... I sadly have reverted and droped the file now... but if you want I can try to delete other files the same way to see if annex unused shows them... then I post the hole commands... k I try it now:
+
+oh I see the directory I wanted to drop did not get dropped because I set numcopies to 2 ;) so I try it again with that file:
+
+1. rm -r directory
+2. ls it is gone (should be ;) )
+
+user@host:~/annex/SOFTWARE$ git annex unused
+unused . (checking for unused data...) (checking master...) (checking synced/master...) (checking usbdrive/master...) ok
+user@host:~/annex/SOFTWARE$
+
+Is that like it should be? If so, should unused only show stuff that I delete with git rm?
+
+
+-----------------------------------
+
+Ok I did read the unused doku you pointed me. So I thought I got it, but I did not:
+
+If I
+
+1. rm File
+2. in the usb-repos, git pull
+both repositories dont have a link to the file.
+3. git unused shows nothing
+4. it seemed that the link AND the File it links to got deleted:
+
+-../.git/annex/objects/pM/vq/SHA256-s1066518528--00c5e1b1610c0c2dfab05c7a55aaad
+
+but the file size is 1gb, both directories dont get smaller... also if I use git gc after that it does not get smaller too.
+
+Is there a way to really delete files from both repositories.
+
+"""]]
diff --git a/doc/forum/Don__39__t_understand_how_to_delete__47__recover_files/comment_3_4b857f481db7b2437ac9f8137a8510e2._comment b/doc/forum/Don__39__t_understand_how_to_delete__47__recover_files/comment_3_4b857f481db7b2437ac9f8137a8510e2._comment
new file mode 100644
index 000000000..a1e003ee7
--- /dev/null
+++ b/doc/forum/Don__39__t_understand_how_to_delete__47__recover_files/comment_3_4b857f481db7b2437ac9f8137a8510e2._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.60"
+ subject="comment 3"
+ date="2012-09-16T17:08:49Z"
+ content="""
+> unused . (checking for unused data...) (checking master...) (checking synced
+/master...) (checking usbdrive/master...) ok
+
+It still considers a file's content used while some branch contains the file. So one of the branches it's checking there still has your file in it. Once you get all the branches synced up, the file will become unused.
+"""]]
diff --git a/doc/forum/Don__39__t_understand_how_to_delete__47__recover_files/comment_4_828db3bf2863d98c0b0fb4074aa7f066._comment b/doc/forum/Don__39__t_understand_how_to_delete__47__recover_files/comment_4_828db3bf2863d98c0b0fb4074aa7f066._comment
new file mode 100644
index 000000000..20e180107
--- /dev/null
+++ b/doc/forum/Don__39__t_understand_how_to_delete__47__recover_files/comment_4_828db3bf2863d98c0b0fb4074aa7f066._comment
@@ -0,0 +1,33 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn4bbuawnh-nSo9pAh8irYAcV4MQCcfdHo"
+ nickname="Stefan"
+ subject="comment 4"
+ date="2012-09-16T22:51:00Z"
+ content="""
+hmm Ok I tried now something that seems to did it... after I did checkin and pull the deletion of the soft-link of the file... I addionaly used git annex sync, and then again pushed it from the usb drive... now the unused command finds stuff...
+
+So am I right now to make that happen:
+
+1. delete the file in the \"main\" repos
+2. git pull from the other repository(s)
+3. git annex sync
+
+4. git annex unused (now it founds something to delete)
+
+5. git annex dropunused 1-1000 (or some other range) do that in both repositories to delete in on both... and do that maybe as cronjob (from point 2 to 5) or do the last last step only if a drive is nearly full (automaticly or manually...)
+
+ok so maybe I could use that.
+
+the advantages over something like rsync are...
+
+1. I have a history and can reverse some operations (till I do step 5 ^^)
+2. I am more flexible in repo/remote types
+3. checksums get saved
+4. I can have repo with all links but 0 data on a 3rd pc and can \"get\" stuff dynamicly (what is the cheapest transfeir) ot them... aka partial checkouts
+
+ok I think the 4. advantage buys me ;)
+
+hope I got it now right with the 5 step instruction.
+
+keep up your great work, would have tried kickstarter here maybe too for other stuff... but I am no american ;) and eu-guys are not allowed, and I also have no relative in usa ;) but that only as a site note ;)
+"""]]
diff --git a/doc/forum/Don__39__t_understand_how_to_delete__47__recover_files/comment_5_cb2063d6a4e08a5c12bf3723d0fa74e0._comment b/doc/forum/Don__39__t_understand_how_to_delete__47__recover_files/comment_5_cb2063d6a4e08a5c12bf3723d0fa74e0._comment
new file mode 100644
index 000000000..14e5b3da3
--- /dev/null
+++ b/doc/forum/Don__39__t_understand_how_to_delete__47__recover_files/comment_5_cb2063d6a4e08a5c12bf3723d0fa74e0._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="comment 5"
+ date="2012-09-17T14:12:13Z"
+ content="""
+That looks right except you shouldn't have to `git pull from the other repository(s)`. The first thing `git annex sync` does is a `git pull`.
+"""]]
diff --git a/doc/forum/Don__39__t_understand_how_to_delete__47__recover_files/comment_6_1759bcd5708f591f91b9c410f6dc5c54._comment b/doc/forum/Don__39__t_understand_how_to_delete__47__recover_files/comment_6_1759bcd5708f591f91b9c410f6dc5c54._comment
new file mode 100644
index 000000000..379d728ee
--- /dev/null
+++ b/doc/forum/Don__39__t_understand_how_to_delete__47__recover_files/comment_6_1759bcd5708f591f91b9c410f6dc5c54._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn4bbuawnh-nSo9pAh8irYAcV4MQCcfdHo"
+ nickname="Stefan"
+ subject="comment 6"
+ date="2012-09-17T23:00:09Z"
+ content="""
+ok I now at least got it that it is nice to run watch on both repositories...
+
+but what I dont get is, is the git annex watch commando not a automatic way so that this deamon makes sync command whenever needed? so I have to use git annex sync first on the repos where I delete the file and then again on the repos I want to receive that change... that seemed to work, but why did watch not do that for me???
+
+
+
+
+"""]]
diff --git a/doc/forum/Don__39__t_understand_how_to_delete__47__recover_files/comment_7_2a389f01eb5131042ea1e71a73c9787a._comment b/doc/forum/Don__39__t_understand_how_to_delete__47__recover_files/comment_7_2a389f01eb5131042ea1e71a73c9787a._comment
new file mode 100644
index 000000000..ecc159641
--- /dev/null
+++ b/doc/forum/Don__39__t_understand_how_to_delete__47__recover_files/comment_7_2a389f01eb5131042ea1e71a73c9787a._comment
@@ -0,0 +1,21 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn4bbuawnh-nSo9pAh8irYAcV4MQCcfdHo"
+ nickname="Stefan"
+ subject="comment 7"
+ date="2012-09-18T00:11:50Z"
+ content="""
+cd /mnt/data/annex/ &&
+/usr/bin/git annex sync &&
+/usr/bin/git annex copy --auto --to usbdrive &&
+cd /mnt/usb1/annex/ &&
+/usr/bin/git annex sync &&
+echo \"synced\" ||
+echo \"backup of annex failed\" | sendxmpp -t name@server.country
+
+
+ok suprisingly that did not only sync the files but also did remove the file, so you dont need a pull... dont know what I did wrong the other times I tried, does maybe the copy command also \"copies\" the delete commit?
+
+but annyway that works for me... (for now I do the dropunused command manuelly...)
+
+that should work as cronjob...
+"""]]
diff --git a/doc/forum/Don__39__t_understand_local_vs._known_keys.mdwn b/doc/forum/Don__39__t_understand_local_vs._known_keys.mdwn
new file mode 100644
index 000000000..39f8c1041
--- /dev/null
+++ b/doc/forum/Don__39__t_understand_local_vs._known_keys.mdwn
@@ -0,0 +1,19 @@
+I just created a new Annex by doing the following:
+
+ 1. git init
+ 2. git annex init
+ 3. git annex add .
+ 4. git commit -m "Added files"
+ 5. git annex status
+
+I see the following:
+
+ local annex keys: 224
+ local annex size: 41 gigabytes
+ known annex keys: 235
+ known annex size: 49 gigabytes
+ bloom filter size: 16 mebibytes (0% full)
+ backend usage:
+ SHA256: 459
+
+Why is there an 8 gigabyte difference here? What/where are those files? What is a bloom filter?
diff --git a/doc/forum/Don__39__t_understand_local_vs._known_keys/comment_1_10749c0d76e824217dd1ff8c8a6e42a5._comment b/doc/forum/Don__39__t_understand_local_vs._known_keys/comment_1_10749c0d76e824217dd1ff8c8a6e42a5._comment
new file mode 100644
index 000000000..5ab1d55cc
--- /dev/null
+++ b/doc/forum/Don__39__t_understand_local_vs._known_keys/comment_1_10749c0d76e824217dd1ff8c8a6e42a5._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="comment 1"
+ date="2012-10-17T12:54:42Z"
+ content="""
+Those are duplicate files.
+
+see http://git-annex.branchable.com/tips/finding_duplicate_files/ for how to easily display them.
+"""]]
diff --git a/doc/forum/Don__39__t_understand_local_vs._known_keys/comment_2_db9f1b6d9638c2b0a7e241c2727e8cfb._comment b/doc/forum/Don__39__t_understand_local_vs._known_keys/comment_2_db9f1b6d9638c2b0a7e241c2727e8cfb._comment
new file mode 100644
index 000000000..c1ca018f5
--- /dev/null
+++ b/doc/forum/Don__39__t_understand_local_vs._known_keys/comment_2_db9f1b6d9638c2b0a7e241c2727e8cfb._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 2"
+ date="2012-10-17T17:32:52Z"
+ content="""
+The local keys are files whose content is locally present.
+The known keys are annexed files in the current branch, whose content may or may not be present.
+
+Justin is correct -- if you have the same file in the tree twice, it will be counted twice as known keys. Since git-annex deuplicates, only one local key is needed to store it.
+
+The bloom filter is a technical implementation detail that allows the potentially expensive status scan to run in constant space. You can read about it on Wikipedia if interested. :)
+"""]]
diff --git a/doc/forum/Drop_with_assistant.mdwn b/doc/forum/Drop_with_assistant.mdwn
new file mode 100644
index 000000000..f8847ab18
--- /dev/null
+++ b/doc/forum/Drop_with_assistant.mdwn
@@ -0,0 +1,5 @@
+Hi,
+
+how can I handle *drop* with the assistant? There are some files in my annex that I don't need on my laptop. so i just *drop* them on the command line bevcause I have copies on my server and an external usb drive. But after a while the assistant pulls all the files back in. Can I avoid this and make the *drop* somehow "sticky" until i *get* them over cli?
+
+Best, Michael
diff --git a/doc/forum/Drop_with_assistant/comment_1_048f5a31c549afb19b76a65bddd0cd24._comment b/doc/forum/Drop_with_assistant/comment_1_048f5a31c549afb19b76a65bddd0cd24._comment
new file mode 100644
index 000000000..e59c285c2
--- /dev/null
+++ b/doc/forum/Drop_with_assistant/comment_1_048f5a31c549afb19b76a65bddd0cd24._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn7gQ1zZDdWhXy9H51W2krZYShNmKL3qfM"
+ nickname="Karsten"
+ subject="comment 1"
+ date="2013-04-11T07:32:50Z"
+ content="""
+Hi,
+
+you can set your repository type to 'manual'.
+
+Best
+Karsten
+"""]]
diff --git a/doc/forum/Drop_with_assistant/comment_2_527d7b6a8efa85b904111f179912d926._comment b/doc/forum/Drop_with_assistant/comment_2_527d7b6a8efa85b904111f179912d926._comment
new file mode 100644
index 000000000..d3ffed3f7
--- /dev/null
+++ b/doc/forum/Drop_with_assistant/comment_2_527d7b6a8efa85b904111f179912d926._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmU_2tE75oyG0h2ZPN4lcroIKEMC8G-otE"
+ nickname="Michael"
+ subject="comment 2"
+ date="2013-04-11T08:26:01Z"
+ content="""
+@Karsten But then I would loose all replication features? Or can I mark subfolders as manual? Or would I mix different annexes?
+"""]]
diff --git a/doc/forum/Drop_with_assistant/comment_3_c50857506869bb1cd306b66acf37fba8._comment b/doc/forum/Drop_with_assistant/comment_3_c50857506869bb1cd306b66acf37fba8._comment
new file mode 100644
index 000000000..cd45baeaf
--- /dev/null
+++ b/doc/forum/Drop_with_assistant/comment_3_c50857506869bb1cd306b66acf37fba8._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 3"
+ date="2013-04-11T13:18:04Z"
+ content="""
+The trivial way to do this is to set your repository to \"client\" and then when you want to drop a file, create a folder called \"archive\" and drag the file into that folder. The assistant will drop it (if numcopies is satisfied that there are enough copies elsewhere). If you want it back, drag it out of the archive and the assistant will re-fetch it.
+
+This is how I use git-annex: I have an ssh remote and a usb drive which are both \"backup\" and my laptop is \"client\", and my numcopies is sent to 2.
+
+Files are always copied to the ssh remote and the usb drive because they're \"backup.\" That fulfills my numcopies=2. At that point, anything in an \"archive\" folder on my laptop will be dropped automatically.
+
+It means my annex is littered with \"archive\" folders, but it achieves the desired effect.
+"""]]
diff --git a/doc/forum/Drop_with_assistant/comment_4_1ea37445d5eb96c3efa182e88e07b867._comment b/doc/forum/Drop_with_assistant/comment_4_1ea37445d5eb96c3efa182e88e07b867._comment
new file mode 100644
index 000000000..56fcfa254
--- /dev/null
+++ b/doc/forum/Drop_with_assistant/comment_4_1ea37445d5eb96c3efa182e88e07b867._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmU_2tE75oyG0h2ZPN4lcroIKEMC8G-otE"
+ nickname="Michael"
+ subject="comment 4"
+ date="2013-04-11T13:39:13Z"
+ content="""
+A nice feature would be, to be able to put a .annex-manual file into a subfolder and from that point the files would require manual git-annex management.
+"""]]
diff --git a/doc/forum/Drop_with_assistant/comment_5_c08908ea5232cbe067c73ecd12d0e218._comment b/doc/forum/Drop_with_assistant/comment_5_c08908ea5232cbe067c73ecd12d0e218._comment
new file mode 100644
index 000000000..b13392a9c
--- /dev/null
+++ b/doc/forum/Drop_with_assistant/comment_5_c08908ea5232cbe067c73ecd12d0e218._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 5"
+ date="2013-04-11T15:00:10Z"
+ content="""
+Setting your repository to manual doesn't prevent it syncing changes out to other repositories, it just prevents it from downloading the contents of files it doesn't already have.
+
+
+"""]]
diff --git a/doc/forum/Drop_with_assistant/comment_6_015134228cb865f97326fbb7193636ea._comment b/doc/forum/Drop_with_assistant/comment_6_015134228cb865f97326fbb7193636ea._comment
new file mode 100644
index 000000000..b57bfdda9
--- /dev/null
+++ b/doc/forum/Drop_with_assistant/comment_6_015134228cb865f97326fbb7193636ea._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmU_2tE75oyG0h2ZPN4lcroIKEMC8G-otE"
+ nickname="Michael"
+ subject="comment 6"
+ date="2013-04-12T06:31:17Z"
+ content="""
+@joey But a *manual* node will still be the middleman between say a remote host and a local usb connected to the node?
+"""]]
diff --git a/doc/forum/Drop_with_assistant/comment_7_950759930667588f21659cd6d7065fbb._comment b/doc/forum/Drop_with_assistant/comment_7_950759930667588f21659cd6d7065fbb._comment
new file mode 100644
index 000000000..c4bd03a9c
--- /dev/null
+++ b/doc/forum/Drop_with_assistant/comment_7_950759930667588f21659cd6d7065fbb._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 7"
+ date="2013-04-12T13:30:24Z"
+ content="""
+As I understand it, nothing will \"be the middleman\" in the sense of, if annex A has remotes B and C, grabbing content from B in order to give it to C without regards for whether or not A wants it. Annex A doesn't think in terms of moving content from one remote to another remote, only in terms of pulling and pushing to remotes individually.
+
+I get the \"move content from remote B to C\" effect by setting numcopies=2 and making both remotes \"backup.\" If content is only on remote B, it will migrate to A in order to fulfill numcopies. Then it will migrate to C because of C's preferred content settings.
+
+(Respecting minimum numcopies is higher priority than respecting preferred content settings, so even if A wouldn't normally \"want\" the content, it will receive it if it needs to in order to fulfill numcopies.)
+
+I've got A set to \"client\" so content in archive directories disappears once the content is on B and C (because numcopies is fulfilled, and so A's preferred content can take effect.)
+
+If you had A set to \"manual,\" then it wouldn't automatically drop content once it moved from B to A to C, though. Because it would only drop things manually.
+
+"""]]
diff --git a/doc/forum/Drop_with_assistant/comment_8_773e540e46adc43487323e8d38ceb2d9._comment b/doc/forum/Drop_with_assistant/comment_8_773e540e46adc43487323e8d38ceb2d9._comment
new file mode 100644
index 000000000..9f9e0855c
--- /dev/null
+++ b/doc/forum/Drop_with_assistant/comment_8_773e540e46adc43487323e8d38ceb2d9._comment
@@ -0,0 +1,23 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 8"
+ date="2013-04-16T20:46:09Z"
+ content="""
+@edheil, you used to be right about the middleman. But I'm continually improving things. :)
+
+So, consider this situation:
+
+> A (client) --- B (client) ---- C (archive)
+
+If a file is created on A, inside an `archive` directory, B wants a copy, since it's not archived yet. Once B gets the copy, it sends it on the C. At that point, B notices that hey, this file was archived and is in an archive directory, and so it no longer wants its copy and drops it.
+
+(At this point A will also want to drop the file. However, it cannot! This is because git-annex requires positive, direct verification that some other repository has a file before dropping it, and A cannot talk to C to check.
+However, if you set C to be trusted, this verification is bypassed, and then A will be able to drop the file as well.)
+
+This support for middlemen is a new feature, which will be in the next release. You can get it in any recent nightly build.
+
+Amusingly this feature was built without writing any haskell code.. just fine-tuning the preferred content expressions!
+
+We can also consider what happens if B is set to manual. In this case, it won't automatically get the file from A. But if you manually get it, then B will send it on to C. And A will drop the file once it hears that C has it. Due to the manual mode, you'll have to manually drop it from B of course.
+"""]]
diff --git a/doc/forum/Drop_with_assistant/comment_9_d85d120d7219ea6c179c2619a17bdae9._comment b/doc/forum/Drop_with_assistant/comment_9_d85d120d7219ea6c179c2619a17bdae9._comment
new file mode 100644
index 000000000..9c9aa439c
--- /dev/null
+++ b/doc/forum/Drop_with_assistant/comment_9_d85d120d7219ea6c179c2619a17bdae9._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="99.54.57.201"
+ subject="comment 9"
+ date="2013-04-17T03:37:48Z"
+ content="""
+Nice! It sounds like there would be another way to accomplish what I'm currently accomplishing by using numcopies=2 and standard client/backup directories. (backup <--> client <--> backup)
+
+In order to get double backups, I *could* tweak the content settings for my laptop's annex, which is currently set to standard \"client\" mode, so that it's exactly like \"client\" mode except that \"archive\" directories want to drop content which is archived *twice*. (backup <--> tweaked-client <--> backup)
+
+Then I'd get content automatically copying itself out to two archives, and dropping it when it has done so, without touching numcopies.
+
+No reason not to keep doing it the way I'm doing it, since it's simpler, but it's cool to see the assistant getting smarter. :)
+
+"""]]
diff --git a/doc/forum/Effectively_replicating_backup_files.mdwn b/doc/forum/Effectively_replicating_backup_files.mdwn
new file mode 100644
index 000000000..85d8f4b52
--- /dev/null
+++ b/doc/forum/Effectively_replicating_backup_files.mdwn
@@ -0,0 +1,25 @@
+I currently use duply/duplicity to back up my networked computers to my home server. I have two external HDDs and, every week or so, I bring one of these home and copy the backup files to the hard drive (I leave them on the server to easily restore files and because I have a large hard drive in that). I use some hand-written scripts to keep a copy these backup files in the cloud (Ubuntu One) until they have been copied to both hard drives, ensuring that there are always two copies of the files somewhere offsite. Out of paranoia, I also have some "standalone backups" that are just huge encrypted archives of important folders (say, my entire Photos directory) as at a certain date - in case for some reason duplicity ever stops working or I need to roll something back to a version years earlier. I am less worried about these standalone backups and manually keep one copy of each somewhere.
+
+It sounds like Git-Annex could automate things quite nicely (and give me some neat extras, like knowing where they were). This is how I understand I should do it, but please let me know if it is the right approach or if you have any suggestions:
+
+1. Create a folder on my server called "annex" and make a Git-Annex "large backup" repository in there.
+2. Create a folder within that called "archive" and put a "backup" folder within that. I understand that having the backups within an archive folder will mean that they aren't automatically copied to my desktop machines etc.
+3. Within that "backup" folder, create two folders, one called "duplicity" and one called "standalone". Put the backups in the respective folders.
+4. Set up gcrypt Git-Annex repositories on my two external HDDs as "small backups". This seems to just start copying files across. That surprised me, as the files are in the archive folder and I thought the default was numcopies=1. Is there some autosync option that I need to turn off? Ideally, I would like it to encrypt/decrypt primarily with my server GPG key (which I'm not worried about copying around my computers), but also encrypt to my personal GPG key (where I'd only put my public key on the server, but I know I will not lose the secret key for that). Am I right that to do that I would need to set the repos up manually with:
+
+ git init --bare /mnt/externalHDD1
+
+ git annex initremote externalHDD1 type=gcrypt gitrepo=/mnt/externalHDD1 keyid=$serverkey keyid=$personalkey
+
+ git annex sync externalHDD1
+
+ Or should the gitrepo be the location of my main Git-Annex repository? How do I make it sync up with my other repos?
+
+5. I understand that I would then need to set numcopies=3 in a .gitattributes file in the "archive/backup/duplicity" directory and, say, a numcopies=2 in the "archive/backup/standalone".
+6. I could then add a cloud repository as a "transfer" repository and Git-Annex should only keep files on that that are not already in the right number of places (similar to what my scripts are doing now).
+7. I have recently upgraded my hard drive, so I have my old 1TB internal hard drive that I will be putting in a cupboard somewhere. I was thinking that I could make this an archive drive for things like one copy of my duplicity/standalone backups. I wouldn't want it to be the only copy of anything. If I just set it as an archive drive, would this work?
+8. Are there more clever ways of doing this? I consider my external HDDs and the cloud repo as "offsite" repositories and ideally there would always be one copy of my backups offsite (in addition to at least three overall). There would also ideally be one of each of my files "live" (in most cases my server) that could instantly push files into a cloud repo and then to wherever I am. Is there any ability to put repositories in groups and write rules like that?
+
+Any thoughts greatly appreciated!
+
+Aaron
diff --git a/doc/forum/Effectively_replicating_backup_files/comment_1_b1ab0da82db076c5244b0dcc95282ddd._comment b/doc/forum/Effectively_replicating_backup_files/comment_1_b1ab0da82db076c5244b0dcc95282ddd._comment
new file mode 100644
index 000000000..54f7f782a
--- /dev/null
+++ b/doc/forum/Effectively_replicating_backup_files/comment_1_b1ab0da82db076c5244b0dcc95282ddd._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 1"
+ date="2013-11-07T16:42:14Z"
+ content="""
+This all sounds reasonable to me.
+
+gitrepo= is the location of the repository you are setting up with gcrypt, not your existing git-annex repository.
+
+numcopies configures the lower bound of the number of copies, not the upper bound. There's no \"small backup\" type, you must mean either small archive, or incremental backup. Either type of repository is going to want to have files that have not previously been archived, or backed up.
+
+You might eventually want to write your own [[preferred_content]] expressions to handle offsite repositories. I'd recommend starting simple and building up.
+"""]]
diff --git a/doc/forum/Effectively_replicating_backup_files/comment_2_472ab9c973b475f7f3ce7e3934f94281._comment b/doc/forum/Effectively_replicating_backup_files/comment_2_472ab9c973b475f7f3ce7e3934f94281._comment
new file mode 100644
index 000000000..668416c04
--- /dev/null
+++ b/doc/forum/Effectively_replicating_backup_files/comment_2_472ab9c973b475f7f3ce7e3934f94281._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnFjuvfPpi1kf6l54bxfFUm0Aw_Gf_IO0o"
+ nickname="Aaron"
+ subject="comment 2"
+ date="2013-11-07T19:46:32Z"
+ content="""
+Thanks Joey!
+
+> gitrepo= is the location of the repository you are setting up with gcrypt, not your existing git-annex repository.
+
+Great, thanks. If I set these up outside of the WebApp, what is the best way to link them up to my main repositories?
+
+> numcopies configures the lower bound of the number of copies, not the upper bound. There's no \"small backup\" type,
+> you must mean either small archive, or incremental backup. Either type of repository is going to want to have files
+> that have not previously been archived, or backed up.
+
+Yes, I meant incremental backup. Thanks, understood. The page on preferred content ( http://git-annex.branchable.com/preferred_content/ ) made things a bit clearer. I didn't realise that the incremental backups etc want a copy even if it isn't necessary to satisfy numcopies. Does that mean that once it is on one backup drive, it will not be sent to the other unless I increase numcopies?
+
+"""]]
diff --git a/doc/forum/Effectively_replicating_backup_files/comment_3_826493bd59b81786c1f6a56f1c438004._comment b/doc/forum/Effectively_replicating_backup_files/comment_3_826493bd59b81786c1f6a56f1c438004._comment
new file mode 100644
index 000000000..9088de9e7
--- /dev/null
+++ b/doc/forum/Effectively_replicating_backup_files/comment_3_826493bd59b81786c1f6a56f1c438004._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="108.236.230.124"
+ subject="comment 3"
+ date="2013-11-08T17:06:02Z"
+ content="""
+The webapp can use remotes that you have configured at the command line just as well as it can use remotes you configure using the webapp.
+
+Each file only gets backed up to one incremental backup repository. If you have a full backup repository it will (try to) get another copy of every single file.
+"""]]
diff --git a/doc/forum/Encrypted_ssh_remote__44___synced_folders.mdwn b/doc/forum/Encrypted_ssh_remote__44___synced_folders.mdwn
new file mode 100644
index 000000000..ea54026f8
--- /dev/null
+++ b/doc/forum/Encrypted_ssh_remote__44___synced_folders.mdwn
@@ -0,0 +1,87 @@
+Hello,
+
+I hope my understanding of the git-annex webapp is correct, and if not, please correct my wrong thought-pattern.
+
+I have 2 VPS servers and 5 computers. On the 5 computers, I want to sync one folder (with subfolders and files). All the computers are full-disk encrypted, and it is important for me that when the data leaves my computer, it stays encrypted in one way or another. I want to use the two VPS's as an encrypted ssh full backup repository.
+
+The computers are rarely on at the same time, some are off for two weeks, others are on more frequent. However, the VPS's are always on.
+
+Now, is it possible to set up git-annex to support this behaviour? Using an encrypted ssh remote to make sure the folder is in sync on all computers?
+
+I've set git-annex up on one box, with the two servers as encrypted full backup remotes (without git-annex installed there), and configured my jabber account. That all works, and the files get synced.
+
+Then I've set up a second computer, while the first one is still on. There I've added my jabber account, and created a local repository. Then I selected "Share with your other devices". It now shows my jabber account on both machines, and I saw a few syncing messages, but then there came errors, "Unable to download files from your other devices". I've attached the log at the bottom of this page.
+
+It gives me the option to add a Cloud Repository. If I add the encrypted rsync full backup remote VPS there, will it work and keep my files in sync? is there something I'm doing wrong?
+
+Note that the computers I've set up now are two OS X machines running Mountain Lion, and the servers are CentOS 6.
+
+Log:
+
+
+ [2013-07-15 07:44:17 CEST] main: starting assistant version 4.20130709-g18e5f43
+
+ (scanning...) [2013-07-15 07:44:17 CEST] Watcher: Performing startup scan
+ (started...) [2013-07-15 07:45:08 CEST] main: starting assistant version 4.20130709-g18e5f43
+
+ (scanning...) [2013-07-15 07:45:08 CEST] Watcher: Performing startup scan
+ (started...) [2013-07-15 07:54:31 CEST] XMPPClient: Pairing with stnl in progress
+ rercrrrreveeeec:ccccv vvvv:r:::: e rsrrrreoeeeesussssorooooucuuuurerrrrc cccceveeee a vnvvvvaiaaaansnnnnihiiiisesssshdhhhhe eeeed(dddd C (o((((CnCCCConoooonennnnncnnnneteeeecicccctottttiniiiio oooonrnnnn e rsrrrreeeeeestsssse eeeetbtttt y b bbbbypyyyy e peppppereeeee)eeeer
+ rrrr)))))
+
+
+
+
+ recv: resource vanished (Connection reset by peer)
+ recv:r errceevcs:vo :ur rercseeos uovruacrneci esv havenadin si(hsCehoden dn( eC(coCtnoinnoennce tcriteoisnoe ntr erbseyes tep teb eybr y)p
+ epeere)r
+ )
+ [2013-07-15 07:55:00 CEST] XMPPSendPack: Syncing with janwxmpp
+ Already up-to-date.
+ recv: resource vanished (Connection reset by peer)
+ [2013-07-15 07:55:04 CEST] XMPPReceivePack: Syncing with janwxmpp
+ To xmpp::janwxmpp@gmail.com
+ * [new branch] git-annex -> refs/synced/0a41c397-09e8-4957-a6f4-2a6846a4f9d8/cmVsc3RubEBnbWFpbC5jb20=/git-annex
+ * [new branch] master -> refs/synced/0a41c397-09e8-4957-a6f4-2a6846a4f9d8/cmVsc3RubEBnbWFpbC5jb20=/master
+ [2013-07-15 07:55:25 CEST] XMPPSendPack: Unable to download files from your other devices.
+ [2013-07-15 07:55:25 CEST] XMPPSendPack: Syncing with janwxmpp
+ recv: resource vanished (Connection reset by peer)
+ fatal: Could not read from remote repository.
+
+ Please make sure you have the correct access rights
+ and the repository exists.
+ [2013-07-15 07:57:25 CEST] XMPPSendPack: Unable to download files from your other devices.
+ recv: resource vanished (Connection reset by peer)
+ recv: resource vanished (Connection reset by peer)
+ recv: resource vanished (Connection reset by peer)
+ recv: resource vanished (Connection reset by peer)
+ recv: resource vanished (Connection reset by peer)
+
+ (Recording state in git...)
+
+ (scanning...) [2013-07-15 08:01:36 CEST] Watcher: Performing startup scan
+ (started...) recvr:rrrrrrre eeeeeeecrcccccccvevvvvvvv:s::::::: o rurrrrrrrereeeeeeescsssssssoeooooooou uuuuuuurvrrrrrrrcaccccccceneeeeeee i vsvvvvvvvahaaaaaaanennnnnnnidiiiiiiis sssssssh(hhhhhhheCeeeeeeedoddddddd n (n(((((((CeCCCCCCCocooooooontnnnnnnnninnnnnnneoeeeeeeecnccccccct tttttttiriiiiiiioeooooooonsnnnnnnn e rtrrrrrrre eeeeeeesbssssssseyeeeeeeet ttttttt p bebbbbbbbyeyyyyyyy r p)pppppppe
+ eeeeeeeeeeeeeeerrrrrrrr))))))))
+
+
+
+
+
+
+
+ [2013-07-15 08:44:42 CEST] XMPPSendPack: Syncing with janwxmpp
+ recv: resource vanished (Connection reset by peer)
+ recrvre:ec cvrv:e: s roreuesrsocoueur rcvceae n vivasanhnieisdsh he(edCd o (n(CnCoeoncnntneiecoctnti ioronen s reretes sebetyt bpbyey e prpe)ee
+ err))
+
+ fatal: Could not read from remote repository.
+
+ Please make sure you have the correct access rights
+ and the repository exists.
+ [2013-07-15 08:46:42 CEST] XMPPSendPack: Unable to download files from your other devices.
+ [2013-07-15 08:46:42 CEST] XMPPSendPack: Syncing with janwxmpp
+ fatal: Could not read from remote repository.
+
+ Please make sure you have the correct access rights
+ and the repository exists.
+ [2013-07-15 08:48:42 CEST] XMPPSendPack: Unable to download files from your other devices.
diff --git a/doc/forum/Encrypted_ssh_remote__44___synced_folders/comment_1_7b9b4ef614c90e0b222d24678d1b9026._comment b/doc/forum/Encrypted_ssh_remote__44___synced_folders/comment_1_7b9b4ef614c90e0b222d24678d1b9026._comment
new file mode 100644
index 000000000..9ebee5f70
--- /dev/null
+++ b/doc/forum/Encrypted_ssh_remote__44___synced_folders/comment_1_7b9b4ef614c90e0b222d24678d1b9026._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.90"
+ subject="comment 1"
+ date="2013-07-16T19:40:20Z"
+ content="""
+Yes, you need to add the rsync remote to the second computer. Once it's set up, they will be able to exchange file contents using it, and using XMPP as a control channel.
+
+If the first computer already has that rsync remote configured, it should push some notes about the existance of that remote to the second one, over XMPP. Then in the webapp, you should just need to click on \"enable\" next to the rsync remote, and it'll prompt for the necessary info to set it up.
+"""]]
diff --git a/doc/forum/Error_adding_ssh_remote_in_assistant.mdwn b/doc/forum/Error_adding_ssh_remote_in_assistant.mdwn
new file mode 100644
index 000000000..e2ef42a19
--- /dev/null
+++ b/doc/forum/Error_adding_ssh_remote_in_assistant.mdwn
@@ -0,0 +1,15 @@
+I'm trying to add a ssh remote in the web app, but I receive the following error:
+
+ Internal Server Error
+
+ ssh-keygen ["-F","router.eisenacher81.org"] exited 1
+
+The console complains about the known_hosts file:
+
+ /home/michael/.ssh/known_hosts is not a valid known_hosts file.
+ line 44 missing key: AAAAB3NzaC1yc2EAAAABIwAAAIEAtnX75Qa8YVR...
+ key_read: uudecode AAAAB3NzaC1|1|veTakKhYY3OSqCepiq7WAUK8cxQ=|suoi0YU/lgg781Vz9O7yTao5exY= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEA4bTnEFFiKz4+i3S9DWHJVoV8CD1DsVRJRodWdTA86+x58S0l0rUyJgXbGwScMI+xFCrqzpd4Hgoc4ElRykj5SL+7IuB5ZAe+4ILQPeiL9ck/1Q7uoh7vWiURXr92Hz5tjuEe3QI9H iKauXj5yj5mGq1VVXLN1CdfQ99G4zSxK7c= failed
+ line 73 invalid key: |1|k9vzo7Ftuxf235It5LbrX36p2f0=|rNHdygip...
+ line 93: invalid hashed name: |1||1|aptgcuUg4ITWhZQLxzRHH8gUIOQ=|Qe2JAlAw++SZosE9ZhQW+fA3twE=...
+ line 120 missing key: AAAAB3NzaC1yc2EAAAABIwAAAQEAsHa75NfjyB1...
+ /home/michael/.ssh/known_hosts is not a valid known_hosts file.
diff --git a/doc/forum/Error_adding_ssh_remote_in_assistant/comment_1_eecc0660db4083cc91c5330587f74610._comment b/doc/forum/Error_adding_ssh_remote_in_assistant/comment_1_eecc0660db4083cc91c5330587f74610._comment
new file mode 100644
index 000000000..c5ca91231
--- /dev/null
+++ b/doc/forum/Error_adding_ssh_remote_in_assistant/comment_1_eecc0660db4083cc91c5330587f74610._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.14.141"
+ subject="comment 1"
+ date="2012-09-22T12:40:55Z"
+ content="""
+Looks like you have a corrupt known_hosts file, but I'm pretty sure git-annex did not do it, as it only lets ssh update that as normal. If you delete the problem lines it'll probably work, though you might want to save a copy to investigate what happened.
+"""]]
diff --git a/doc/forum/Error_adding_ssh_remote_in_assistant/comment_2_3e6aad22e8020b12ff7ef914b75281d1._comment b/doc/forum/Error_adding_ssh_remote_in_assistant/comment_2_3e6aad22e8020b12ff7ef914b75281d1._comment
new file mode 100644
index 000000000..85acfcc1e
--- /dev/null
+++ b/doc/forum/Error_adding_ssh_remote_in_assistant/comment_2_3e6aad22e8020b12ff7ef914b75281d1._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.14.141"
+ subject="comment 2"
+ date="2012-09-27T15:29:56Z"
+ content="""
+I've made the assistant ignore ssh-keygen -F failing.
+"""]]
diff --git a/doc/forum/Error_adding_ssh_remote_in_assistant/comment_3_3ea529e16502071fc0980c6d5c60a036._comment b/doc/forum/Error_adding_ssh_remote_in_assistant/comment_3_3ea529e16502071fc0980c6d5c60a036._comment
new file mode 100644
index 000000000..799050de0
--- /dev/null
+++ b/doc/forum/Error_adding_ssh_remote_in_assistant/comment_3_3ea529e16502071fc0980c6d5c60a036._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmU_2tE75oyG0h2ZPN4lcroIKEMC8G-otE"
+ nickname="Michael"
+ subject="comment 3"
+ date="2012-09-27T15:42:19Z"
+ content="""
+Okay, cleaning up the file worked for me, but I suspect that these invalid entries were created by a valid program. So ignoring errors in the file is \"good enough\".
+"""]]
diff --git a/doc/forum/External_drive_syncs_git-annex_branch_but_not_master_branch.mdwn b/doc/forum/External_drive_syncs_git-annex_branch_but_not_master_branch.mdwn
new file mode 100644
index 000000000..76294b6a6
--- /dev/null
+++ b/doc/forum/External_drive_syncs_git-annex_branch_but_not_master_branch.mdwn
@@ -0,0 +1 @@
+I have an external HDD which I setup as a remote manually before I started using the assistant. When I plug it in files sync fine and the git-annex branch gets synced, but the master branch doesn't; git annex sync doesn't do the job and I have to run git pull. This is annoying because it means that portable drive is useless as a backup, since it doesn't have the required metadata; I have to manually git pull to make it a useful backup. How can I make the assistant sync the metadata in--if not the master branch, at least origin/master so I could merge later without the remote available. Thanks.
diff --git a/doc/forum/External_drive_syncs_git-annex_branch_but_not_master_branch/comment_1_9a909e3d89061adacbd8ed370520250c._comment b/doc/forum/External_drive_syncs_git-annex_branch_but_not_master_branch/comment_1_9a909e3d89061adacbd8ed370520250c._comment
new file mode 100644
index 000000000..43fe578e1
--- /dev/null
+++ b/doc/forum/External_drive_syncs_git-annex_branch_but_not_master_branch/comment_1_9a909e3d89061adacbd8ed370520250c._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 1"
+ date="2012-12-08T21:25:49Z"
+ content="""
+apologies if I misunderstand your question, but I believe that git-annex puts the metadata in the repository's sync/master branch, which you can merge into the repository's local master either manually or by running \"git annex sync\" in the repository.
+
+"""]]
diff --git a/doc/forum/External_drive_syncs_git-annex_branch_but_not_master_branch/comment_2_0dd489b264374b7b1065b89e1ff7561b._comment b/doc/forum/External_drive_syncs_git-annex_branch_but_not_master_branch/comment_2_0dd489b264374b7b1065b89e1ff7561b._comment
new file mode 100644
index 000000000..d26707c22
--- /dev/null
+++ b/doc/forum/External_drive_syncs_git-annex_branch_but_not_master_branch/comment_2_0dd489b264374b7b1065b89e1ff7561b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="spwhitton"
+ ip="163.1.166.255"
+ subject="comment 2"
+ date="2012-12-08T21:57:37Z"
+ content="""
+It does, which is what one would have expected I guess, but I didn't look. Thanks so much.
+"""]]
diff --git a/doc/forum/Feature_Request:_add_filename_to_hash_objects.mdwn b/doc/forum/Feature_Request:_add_filename_to_hash_objects.mdwn
new file mode 100644
index 000000000..173cd2d94
--- /dev/null
+++ b/doc/forum/Feature_Request:_add_filename_to_hash_objects.mdwn
@@ -0,0 +1,6 @@
+hi,
+i just did git annex unused in 2 repos, one with WORM and one with SHA1.
+with WORM i instantly could see which file it was, with SHA1 not.
+
+so would it be possible to just add the first seen filename to the hashes identifier? the name could just be ignored but it would help with unused to see which file i am searching for.
+thanks!
diff --git a/doc/forum/Feature_Request:_add_filename_to_hash_objects/comment_1_73dc0a9cad486cf2d34faf064c6193b1._comment b/doc/forum/Feature_Request:_add_filename_to_hash_objects/comment_1_73dc0a9cad486cf2d34faf064c6193b1._comment
new file mode 100644
index 000000000..8a2f9fb00
--- /dev/null
+++ b/doc/forum/Feature_Request:_add_filename_to_hash_objects/comment_1_73dc0a9cad486cf2d34faf064c6193b1._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="64.134.31.139"
+ subject="comment 1"
+ date="2013-10-16T15:19:25Z"
+ content="""
+Adding a filename would defeat deduplication. You suggest adding the \"first seen\" filename, but then git-annex would need to maintain a lookup between hashes and hashes with the first seen filename to use when adding new files.
+
+There is already [[todo/wishlist: option to print more info with 'unused']].
+"""]]
diff --git a/doc/forum/Feature_Request:_add_filename_to_hash_objects/comment_2_f818b3ecfeb1d1dd83df4668c061718a._comment b/doc/forum/Feature_Request:_add_filename_to_hash_objects/comment_2_f818b3ecfeb1d1dd83df4668c061718a._comment
new file mode 100644
index 000000000..638492822
--- /dev/null
+++ b/doc/forum/Feature_Request:_add_filename_to_hash_objects/comment_2_f818b3ecfeb1d1dd83df4668c061718a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="orb"
+ ip="178.11.228.69"
+ subject="comment 2"
+ date="2013-10-17T21:12:09Z"
+ content="""
+thanks! (i hope a thanks is wanted, i know people who are just distracted and consider \"thanks\" posts unnecessary)
+"""]]
diff --git a/doc/forum/Feature_request:_Multiple_concurrent_transfers.mdwn b/doc/forum/Feature_request:_Multiple_concurrent_transfers.mdwn
new file mode 100644
index 000000000..a287e5ddf
--- /dev/null
+++ b/doc/forum/Feature_request:_Multiple_concurrent_transfers.mdwn
@@ -0,0 +1,19 @@
+I'm sitting on a pretty fast connection, and often git-annex isn't using my entire upstream to fill the remotes.
+
+Lets say i have an annex with 10 x 100mb files. and my git-annex has 5 special remotes that needs to be filled.
+
+I would like to have git-annex do 5 concurrent uploads(one to each remote). Currently git-annex only uploads to one special-remote at a time (meaning the 4 remaining servers are just waiting).
+
+It would also be nice to have a per remote number of threads. Especially if adding a directory with 1000 small files in it(say 100bytes each), having 5 transfer threads to each remote would make the sync complete much faster.
+
+
+For now i've made a shell script that i call:
+
+# for j in `seq -w 0 10`; do echo DOING $j; for i in `curl "http://127.0.0.1:$1/?auth=$2" | grep "continue" | gawk -F\" ' { print $8 } '`; do curl "http://127.0.0.1:$1$i"; sleep 0; done; done
+
+But it is very rough, and basically just starts all transfers on the page. Which means i currently have 315 active transfers running. whoops.
+
+I could improve the shell script. But it really would be quite a bit niftier to have it as settings in git-annex.
+
+Sincerely
+Tobias
diff --git a/doc/forum/Feature_request:_git_annex_copy_--auto_does_the_right_thing.mdwn b/doc/forum/Feature_request:_git_annex_copy_--auto_does_the_right_thing.mdwn
new file mode 100644
index 000000000..0a069340c
--- /dev/null
+++ b/doc/forum/Feature_request:_git_annex_copy_--auto_does_the_right_thing.mdwn
@@ -0,0 +1,5 @@
+I'm not sure of the right place for feature requests; sorry if this is incorrect.
+
+It occurred to me that it would be neat if running git annex copy --auto copied enough copies of the file to connected remotes that don't have it to fulfil numcopies (if possible). Further coolness could come from choosing the remotes smartly (based, for example, on availability, access cost, remote disk space, trust level... you get the idea)
+
+Having an option like this would allow the user to use numcopies to backup files to wherever possible, if they don't really care about where those copies go.
diff --git a/doc/forum/Feature_request:_git_annex_copy_--auto_does_the_right_thing/comment_1_bbac7d0810a79eb1f42a01e1b31d5c4c._comment b/doc/forum/Feature_request:_git_annex_copy_--auto_does_the_right_thing/comment_1_bbac7d0810a79eb1f42a01e1b31d5c4c._comment
new file mode 100644
index 000000000..cd834e08d
--- /dev/null
+++ b/doc/forum/Feature_request:_git_annex_copy_--auto_does_the_right_thing/comment_1_bbac7d0810a79eb1f42a01e1b31d5c4c._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.183"
+ subject="comment 1"
+ date="2013-02-09T02:32:23Z"
+ content="""
+You can kind of do this now by:
+
+for remote in $(git remote); do git annex copy --auto --to $remote; done
+
+Although without some of the potential smarts of course.
+"""]]
diff --git a/doc/forum/Feature_request:_webapp_support_for_centralized_bare_repos.mdwn b/doc/forum/Feature_request:_webapp_support_for_centralized_bare_repos.mdwn
new file mode 100644
index 000000000..2fdab28a7
--- /dev/null
+++ b/doc/forum/Feature_request:_webapp_support_for_centralized_bare_repos.mdwn
@@ -0,0 +1 @@
+I would like it if the webapp could support setting up [bare remotes](http://git-annex.branchable.com/tips/centralized_git_repository_tutorial/) to assist with syncing between two machines that are never online at the same time.
diff --git a/doc/forum/First_attempt_at_an_OSX_launcher___40__.app__41__.mdwn b/doc/forum/First_attempt_at_an_OSX_launcher___40__.app__41__.mdwn
new file mode 100644
index 000000000..ded094ec1
--- /dev/null
+++ b/doc/forum/First_attempt_at_an_OSX_launcher___40__.app__41__.mdwn
@@ -0,0 +1,3 @@
+I've made a first attempt at a .app launcher for git-annex webapp for OSX, please see <https://github.com/jcftang/git-annex/commits/master> the icon needs to be resized and made to look nicer at somepoint, the launcher assumes that git-annex is in the run time path.
+
+I would imagine it might be possible to fiddle with the paths and get all the needed components into the .app file for OSX users.
diff --git a/doc/forum/First_attempt_at_an_OSX_launcher___40__.app__41__/comment_1_97c261b9080c5ecc5424683066bbe05b._comment b/doc/forum/First_attempt_at_an_OSX_launcher___40__.app__41__/comment_1_97c261b9080c5ecc5424683066bbe05b._comment
new file mode 100644
index 000000000..aa2757054
--- /dev/null
+++ b/doc/forum/First_attempt_at_an_OSX_launcher___40__.app__41__/comment_1_97c261b9080c5ecc5424683066bbe05b._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.14.141"
+ subject="comment 1"
+ date="2012-09-23T15:14:20Z"
+ content="""
+Aha! I had been fumbling trying to find the right way to do this. Looks very promising. Found the documentation for the file format: <http://developer.apple.com/library/ios/#documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html>
+
+Where do I install this thing? If I put the git-annex.app directory inside ~/Desktop/, will that put it on the user's desktop?
+
+Could you make a screenshot?
+
+I'm guessing that the NSAppleScriptEnabled is not needed, and perhaps the LSMinimumSystemVersionByArchitecture block could also be removed.
+"""]]
diff --git a/doc/forum/First_attempt_at_an_OSX_launcher___40__.app__41__/comment_2_ae45f9703b635c235409682cf252d36c._comment b/doc/forum/First_attempt_at_an_OSX_launcher___40__.app__41__/comment_2_ae45f9703b635c235409682cf252d36c._comment
new file mode 100644
index 000000000..edb8e50c7
--- /dev/null
+++ b/doc/forum/First_attempt_at_an_OSX_launcher___40__.app__41__/comment_2_ae45f9703b635c235409682cf252d36c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.14.141"
+ subject="comment 2"
+ date="2012-09-23T15:17:42Z"
+ content="""
+Also, is there any global location I can install it when installing as root?
+"""]]
diff --git a/doc/forum/First_attempt_at_an_OSX_launcher___40__.app__41__/comment_3_066ca31a2e5dfe55a58092ba85231c7c._comment b/doc/forum/First_attempt_at_an_OSX_launcher___40__.app__41__/comment_3_066ca31a2e5dfe55a58092ba85231c7c._comment
new file mode 100644
index 000000000..4a48117ee
--- /dev/null
+++ b/doc/forum/First_attempt_at_an_OSX_launcher___40__.app__41__/comment_3_066ca31a2e5dfe55a58092ba85231c7c._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 3"
+ date="2012-09-23T15:52:31Z"
+ content="""
+The .app file can be placed anywhere, typically you would want to bundle it in a .dmg file for the user and the user just \"drags\" it to the /Applications folder. It should be possible to bundle statically linked binaries inside the .app bundle, you might end up having to ship parts of coreutils and a few other applications to make it self contained.
+
+Anyhow, here is a quick screencast <http://screencast.com/t/pnk8bk3hyUJM> and a screengrab of the app <http://screencast.com/t/4jjeRFx4g>
+"""]]
diff --git a/doc/forum/First_attempt_at_an_OSX_launcher___40__.app__41__/comment_4_a0a9f7f44cadb8036fcddfc21bb0781f._comment b/doc/forum/First_attempt_at_an_OSX_launcher___40__.app__41__/comment_4_a0a9f7f44cadb8036fcddfc21bb0781f._comment
new file mode 100644
index 000000000..a18b341f7
--- /dev/null
+++ b/doc/forum/First_attempt_at_an_OSX_launcher___40__.app__41__/comment_4_a0a9f7f44cadb8036fcddfc21bb0781f._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 4"
+ date="2012-09-23T16:00:35Z"
+ content="""
+Thinking this out a little, I reckon the script _MacOS/git-annex_ could be a bit more clever and get the basedir/basename of where it app is and execute git-annex from the .app bundle, then you wouldn't need to install it as root at all. It would require a bit of work to collect the executables needed.
+
+Also, I just quickly checked my Lion install, it seems to come with git and uuidgen once xcode and the command line tools are installed.
+"""]]
diff --git a/doc/forum/First_attempt_at_an_OSX_launcher___40__.app__41__/comment_5_92240b3f8629f1f2bbe1829700082a79._comment b/doc/forum/First_attempt_at_an_OSX_launcher___40__.app__41__/comment_5_92240b3f8629f1f2bbe1829700082a79._comment
new file mode 100644
index 000000000..e8a6d550f
--- /dev/null
+++ b/doc/forum/First_attempt_at_an_OSX_launcher___40__.app__41__/comment_5_92240b3f8629f1f2bbe1829700082a79._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.14.141"
+ subject="comment 5"
+ date="2012-09-23T16:29:19Z"
+ content="""
+For now I have it generating the shell script, so it contains the path to whereever git-annex's binary is actually installed.
+
+For root, the app is installed in /Applications/ , for non-root installs I put it in ~/Desktop/
+"""]]
diff --git a/doc/forum/Fixing_up_corrupt_annexes.mdwn b/doc/forum/Fixing_up_corrupt_annexes.mdwn
new file mode 100644
index 000000000..be6beeca8
--- /dev/null
+++ b/doc/forum/Fixing_up_corrupt_annexes.mdwn
@@ -0,0 +1,10 @@
+I was wondering how does one recover from...
+
+<pre>
+(Recording state in git...)
+error: invalid object 100644 8f154c946adc039af5240cc650a0a95c840e6fa6 for '041/5a4/SHA256-s6148--7ddcf853e4b16e77ab8c3c855c46867e6ed61c7089c334edf98bbdd3fb3a89ba.log'
+fatal: git-write-tree: error building trees
+git-annex: failed to read sha from git write-tree
+</pre>
+
+The above was caught when i ran a "git annex fsck --fast" to check stash of files"
diff --git a/doc/forum/Fixing_up_corrupt_annexes/comment_1_cea21f96bcfb56aaab7ea03c1c804d2d._comment b/doc/forum/Fixing_up_corrupt_annexes/comment_1_cea21f96bcfb56aaab7ea03c1c804d2d._comment
new file mode 100644
index 000000000..335cbb51d
--- /dev/null
+++ b/doc/forum/Fixing_up_corrupt_annexes/comment_1_cea21f96bcfb56aaab7ea03c1c804d2d._comment
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ subject="comment 1"
+ date="2012-07-24T22:00:35Z"
+ content="""
+This is a corrupt git repository. See [[tips/what_to_do_when_a_repository_is_corrupted]]
+"""]]
diff --git a/doc/forum/Fixing_up_corrupt_annexes/comment_2_5cdd2fcfa61b3f6255e5ad63a3ab00ce._comment b/doc/forum/Fixing_up_corrupt_annexes/comment_2_5cdd2fcfa61b3f6255e5ad63a3ab00ce._comment
new file mode 100644
index 000000000..4692338af
--- /dev/null
+++ b/doc/forum/Fixing_up_corrupt_annexes/comment_2_5cdd2fcfa61b3f6255e5ad63a3ab00ce._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 2"
+ date="2012-07-25T06:52:32Z"
+ content="""
+Ah I was looking at the walkthrough on how to fix the issue, I had not thought about looking at the tips section. That tip fixed the issue for me, thanks.
+"""]]
diff --git a/doc/forum/Forcing_one_repo_to_contain_a_copy_of_all_files.mdwn b/doc/forum/Forcing_one_repo_to_contain_a_copy_of_all_files.mdwn
new file mode 100644
index 000000000..827383f9f
--- /dev/null
+++ b/doc/forum/Forcing_one_repo_to_contain_a_copy_of_all_files.mdwn
@@ -0,0 +1 @@
+With numcopies it is possible to control how many copies there should be of a file overall in all of the remotes. Is it also possible, using .gitattributes or something else, to force one of the repos (e.g. a server) to contain a copy of all files, or does this have to be done manually?
diff --git a/doc/forum/Forcing_one_repo_to_contain_a_copy_of_all_files/comment_1_702b1b94c735f1b9cde16daa77a80c12._comment b/doc/forum/Forcing_one_repo_to_contain_a_copy_of_all_files/comment_1_702b1b94c735f1b9cde16daa77a80c12._comment
new file mode 100644
index 000000000..d964a253b
--- /dev/null
+++ b/doc/forum/Forcing_one_repo_to_contain_a_copy_of_all_files/comment_1_702b1b94c735f1b9cde16daa77a80c12._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="99.54.57.201"
+ subject="comment 1"
+ date="2013-09-14T20:36:53Z"
+ content="""
+That is what the \"backup\" preferred content group is for. Depending on how your repos connect to each other it might take some more trickery to make all content migrate to it, but that will make it \"want\" all the files if it can get them.
+"""]]
diff --git a/doc/forum/Forcing_one_repo_to_contain_a_copy_of_all_files/comment_2_3df7fcbcd482bb9377ead238b314995b._comment b/doc/forum/Forcing_one_repo_to_contain_a_copy_of_all_files/comment_2_3df7fcbcd482bb9377ead238b314995b._comment
new file mode 100644
index 000000000..e59af71fb
--- /dev/null
+++ b/doc/forum/Forcing_one_repo_to_contain_a_copy_of_all_files/comment_2_3df7fcbcd482bb9377ead238b314995b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.14.105"
+ subject="Ed's right"
+ date="2013-09-19T18:56:39Z"
+ content="""
+What we don't have is something to enforce a particular preferred content setting. Ie, refuse to allow dropping a file from a repo if it's preferred content there. Currently you have to remember to use `git annex drop --auto` to cause the preferred content to be honored.
+"""]]
diff --git a/doc/forum/GPG_passphrase_handling.txt b/doc/forum/GPG_passphrase_handling.txt
new file mode 100644
index 000000000..b0f82cb89
--- /dev/null
+++ b/doc/forum/GPG_passphrase_handling.txt
@@ -0,0 +1,76 @@
+[[!meta title="GPG passphrase handling on OSX"]]
+
+Hello!
+I'm using OSX 10.9 and have installed gpg (and gpg2, if it matters) through
+homebrew and git-annex through cabal. I also installed
+https://github.com/joeyh/git-remote-gcrypt like the UI told me.
+
+Whenever I'm trying to add an encrypted remote through the web UI I get a
+lot of "You need a passphrase to unlock the secret key for user:" on stdout
+and, obviously, I can't enter my passphrase (If I could I wouldn't make this
+post to begin with :))
+Is this behavior normal? What should I do to work around it?
+I did also try to not use the web UI by using this command:
+git annex initremote rsync.net type=gcrypt gitrepo=user@host:directory encryption=pubkey keyid=X
+
+Because of this I can't copy files to my remotes. All I get is:
+-----
+$ git annex copy --to rsync.net
+copy MySecretFile (gpg)
+You need a passphrase to unlock the secret key for
+user: "user"
+4096-bit RSA key, ID X, created 2013-10-01 (main key ID Y)
+
+(checking rsync.net...) (to rsync.net...) gpg: no valid addressees
+gpg: [stdin]: encryption failed: No user ID
+failed
+-----
+
+Yes, I am using gpg-agent. When other applications ask for my passphrase I get
+the pinentry dialog from GPGTools, just like I've configured it in
+~/.gnupg/gpg-agent.conf, but this isn't the case with git-annex.
+
+If I remove GPGTools from /usr/local/bin with: ``brew link --overwrite gnupg &&
+brew link --overwrite gnupg2'' it works *slightly* better.
+I get that pinentry dialog I want but when I do a copy I get:
+-----
+$ git annex copy --to rsync.net
+copy MySecretFile (gpg) (checking rsync.net...) (to rsync.net...) gpg: no valid addressees
+gpg: [stdin]: encryption failed: no such user id
+failed
+-----
+
+--debug shows me it is executing gpg llke so:
+-----
+gpg ["--batch","--no-tty","--use-agent","--quiet","--trust-model","always","--batch","--encrypt","--no-encrypt-to","--no-default-recipient","--force-mdc","--no-textmode"]
+-----
+
+$ git annex version
+git-annex version: 4.20131024
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV FsEvents XMPP DNS Feeds Quvi TDFA CryptoHash
+key/value backends: SHA256E SHA1E SHA512E SHA224E SHA384E SKEIN256E SKEIN512E SHA256 SHA1 SHA512 SHA224 SHA384 SKEIN256 SKEIN512 WORM URL
+remote types: git gcrypt S3 bup directory rsync web webdav glacier hook
+
+$ gpg --version
+gpg (GnuPG) 2.0.22
+libgcrypt 1.5.3
+Copyright (C) 2013 Free Software Foundation, Inc.
+License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
+This is free software: you are free to change and redistribute it.
+There is NO WARRANTY, to the extent permitted by law.
+
+Home: ~/.gnupg
+Supported algorithms:
+Pubkey: RSA, ELG, DSA, ?, ?
+Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
+ CAMELLIA128, CAMELLIA192, CAMELLIA256
+Hash: MD5, SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
+Compression: Uncompressed, ZIP, ZLIB, BZIP2
+
+ $ gpg-agent --version
+gpg-agent (GnuPG/MacGPG2) 2.0.22
+libgcrypt 1.5.3
+Copyright (C) 2013 Free Software Foundation, Inc.
+License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
+This is free software: you are free to change and redistribute it.
+There is NO WARRANTY, to the extent permitted by law.
diff --git a/doc/forum/GPG_passphrase_handling/comment_1_11ba130e8bea6698858d0a1a5b01830f._comment b/doc/forum/GPG_passphrase_handling/comment_1_11ba130e8bea6698858d0a1a5b01830f._comment
new file mode 100644
index 000000000..f2709f18c
--- /dev/null
+++ b/doc/forum/GPG_passphrase_handling/comment_1_11ba130e8bea6698858d0a1a5b01830f._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkzwmw_zyMpZC9_J7ey--woeYPoZkAOgGw"
+ nickname="dxtrish"
+ subject="comment 1"
+ date="2013-10-31T00:06:22Z"
+ content="""
+In fact I just tried this with a key without a passphrase and I STILL get:
+
+[2013-10-31 01:00:50 CET] Pusher: Syncing with rsync.net
+gpg: no valid addressees
+gpg: [stdin]: encryption failed: no such user id
+
+In addition I also noticed a lot of:
+git-annex: fd:28: hPutBuf: resource vanished (Broken pipe)
+"""]]
diff --git a/doc/forum/GPG_passphrase_handling/comment_2_ef9d58d15b7bbe0b3c7140bb01d73a31._comment b/doc/forum/GPG_passphrase_handling/comment_2_ef9d58d15b7bbe0b3c7140bb01d73a31._comment
new file mode 100644
index 000000000..d15248ab7
--- /dev/null
+++ b/doc/forum/GPG_passphrase_handling/comment_2_ef9d58d15b7bbe0b3c7140bb01d73a31._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkzwmw_zyMpZC9_J7ey--woeYPoZkAOgGw"
+ nickname="dxtrish"
+ subject="comment 2"
+ date="2013-10-31T02:42:47Z"
+ content="""
+I think I have found two ways I can make this happen.
+
+1) If a filename contains UTF-8 it seems to happen (At least with this specific filename I have right here)
+
+2) Finder.app does not seem to play nice with git-annex (I got the same error when I tried using Finder to copy files to my git-annex thing)
+
+
+
+"""]]
diff --git a/doc/forum/GPG_passphrase_handling/comment_3_84eb129c8483b87b3ae6ecaf8b4a8309._comment b/doc/forum/GPG_passphrase_handling/comment_3_84eb129c8483b87b3ae6ecaf8b4a8309._comment
new file mode 100644
index 000000000..298e2f13d
--- /dev/null
+++ b/doc/forum/GPG_passphrase_handling/comment_3_84eb129c8483b87b3ae6ecaf8b4a8309._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 3"
+ date="2013-11-02T20:39:36Z"
+ content="""
+There seem to be a lot of different ways to install gpg on OSX, with different results in what works and not. I don't know what's going on with that. Advice from those who understand Mac OS would be appreciated.
+
+As far as the \"gpg: no valid addressees\" bug goes, I can reproduce it on Linux, and have fixed it. Only affected using gcrypt with encryption=pubkey.
+
+(Please file bug reports in [[bugs]] in the future, not in the forum!)
+"""]]
diff --git a/doc/forum/GPG_passphrase_handling/comment_4_8724297f6d7ac140ab395a940bab0d7d._comment b/doc/forum/GPG_passphrase_handling/comment_4_8724297f6d7ac140ab395a940bab0d7d._comment
new file mode 100644
index 000000000..983c35c3a
--- /dev/null
+++ b/doc/forum/GPG_passphrase_handling/comment_4_8724297f6d7ac140ab395a940bab0d7d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkzwmw_zyMpZC9_J7ey--woeYPoZkAOgGw"
+ nickname="dxtrish"
+ subject="comment 4"
+ date="2013-11-03T13:10:11Z"
+ content="""
+I would have filed it in the bug section if I knew it was a bug. I just thought I had done something wrong :)
+"""]]
diff --git a/doc/forum/Getting_started_with_Amazon_S3.mdwn b/doc/forum/Getting_started_with_Amazon_S3.mdwn
new file mode 100644
index 000000000..1ee86b57f
--- /dev/null
+++ b/doc/forum/Getting_started_with_Amazon_S3.mdwn
@@ -0,0 +1,28 @@
+I'm just getting started with git-annex and trying to wrap my head around using it with Amazon S3. I am familiar with using git, but things are a bit different as we can't init a repo at S3 directly.
+
+I've followed http://git-annex.branchable.com/tips/using_Amazon_S3/, and performed:
+
+`git init`<br/>
+Initialized empty Git repository in /home/<br/>
+`git annex init`<br/>
+init ok<br/>
+`git annex initremote s3 type=S3 encryption=FOOBAR bucket=foo`<br/>
+initremote s3 (encryption setup with gpg key YGTVT51715TFR) (checking bucket...) (gpg) ok<br/>
+`git annex describe s3 "Amazon S3"`<br/>
+describe s3 ok<br/>
+`git annexx add foo/`<br/>
+add foo/bar.txt<br/>
+add foo/bar.png<br/>
+...etc<br/>
+`git annex sync`<br/>
+51 files changed, 51 insertions(+)<br/>
+create mode 120000 foo/bar.txt<br/>
+create mode 120000 foo/bar.png<br/>
+...etc<br/>
+
+
+Looking at http://git-annex.branchable.com/git-annex/, I thought the files added would then be pushed to S3 by git annex sync, but that doesn't seem to be the case. I've also tried variations of got annex copy, like `git annex copy . --to s3`, without any luck.
+
+Is there a way to push to s3?
+
+Any help is appreciated!
diff --git a/doc/forum/Getting_started_with_Amazon_S3/comment_1_f50883133d5d4903cc95c0dcaa52d052._comment b/doc/forum/Getting_started_with_Amazon_S3/comment_1_f50883133d5d4903cc95c0dcaa52d052._comment
new file mode 100644
index 000000000..b2211fa6c
--- /dev/null
+++ b/doc/forum/Getting_started_with_Amazon_S3/comment_1_f50883133d5d4903cc95c0dcaa52d052._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.81.112"
+ subject="comment 1"
+ date="2012-05-29T19:09:50Z"
+ content="""
+`git annex sync` only syncs git metadata, not file contents, and metadata is not stored on S3, so it does notthing (much).
+
+`git annex move . --to s3` or `git annex copy . --to s3` is the right way to send the files to S3. I'm not sure why you say it's not working. I'd try it but Amazon is not letting me sign up for S3 again right now. Can you show what goes wrong with copy?
+"""]]
diff --git a/doc/forum/Getting_started_with_Amazon_S3/comment_2_e90aa3259d9a12cd67daa27d42d69ab5._comment b/doc/forum/Getting_started_with_Amazon_S3/comment_2_e90aa3259d9a12cd67daa27d42d69ab5._comment
new file mode 100644
index 000000000..742e8d446
--- /dev/null
+++ b/doc/forum/Getting_started_with_Amazon_S3/comment_2_e90aa3259d9a12cd67daa27d42d69ab5._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnoUOqs_lbuWyZBqyU6unHgUduJwDDgiKY"
+ nickname="Matt"
+ subject="comment 2"
+ date="2012-05-30T00:40:45Z"
+ content="""
+It's strange. I've done some testing on another machine, and this one, and the issue seems to be with adding only certain sub-directories of the git-annex directory. Would it cause an issue with git-annex if a sub-directory was a git repo?
+"""]]
diff --git a/doc/forum/Getting_started_with_Amazon_S3/comment_3_c3adce7c0f29e71ed9dd07103ede2c1a._comment b/doc/forum/Getting_started_with_Amazon_S3/comment_3_c3adce7c0f29e71ed9dd07103ede2c1a._comment
new file mode 100644
index 000000000..450a1513c
--- /dev/null
+++ b/doc/forum/Getting_started_with_Amazon_S3/comment_3_c3adce7c0f29e71ed9dd07103ede2c1a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.81.112"
+ subject="comment 3"
+ date="2012-05-30T00:54:38Z"
+ content="""
+If the subdirectory has a .git, then it's a separate git repo, and inside the directory, all git (and git-annex) commands in it will operate on that nested repo and ignore the outside one.
+"""]]
diff --git a/doc/forum/Git_Annex_Assistant:_How_to_add_a_remote__63__.mdwn b/doc/forum/Git_Annex_Assistant:_How_to_add_a_remote__63__.mdwn
new file mode 100644
index 000000000..0a3aac911
--- /dev/null
+++ b/doc/forum/Git_Annex_Assistant:_How_to_add_a_remote__63__.mdwn
@@ -0,0 +1,11 @@
+Hi,
+
+I am trying to use Git Annex Assistant on my Fedora Linux computer. I currently have a local repository that assistant monitors, but now I want to use my personal server as a git remote for the repository. I click on Configuration > Remote server and it prompts me for my server login credentials and then click the "Check this server" button. After this I am shown a screen that assistant is "Ready to add remote server" and then states:
+> The server <MY IP ADDRESS HERE> can be used as is, but installing git-annex on it would make it work better, and provide more options below.
+>
+> If you're able to install software on the server, do so and click Retry
+
+The information shown below this message is regarding encrypting the data (if I have git-annex installed on the server, which I don't). So my question is, what do I do now? There is no button to just add the remote from within git annex assistant? I created a bare repository on my server and added a remote manually inside the repository on my local machine, but git annex assistant doesn't notice it. I'm clueless on what git annex assistant is expecting from me at this point. I would think what I'm trying to do is one of the most common use cases for git annex, but I can't find any documentation or materials on the correct procedure for this. Any help is appreciated.
+
+Regards,
+Blake
diff --git a/doc/forum/Git_Annex_Assistant:_How_to_add_a_remote__63__/comment_1_d0a3d0090928790d5a05e9f8e5f05320._comment b/doc/forum/Git_Annex_Assistant:_How_to_add_a_remote__63__/comment_1_d0a3d0090928790d5a05e9f8e5f05320._comment
new file mode 100644
index 000000000..5c3a596a5
--- /dev/null
+++ b/doc/forum/Git_Annex_Assistant:_How_to_add_a_remote__63__/comment_1_d0a3d0090928790d5a05e9f8e5f05320._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="64.134.31.139"
+ subject="comment 1"
+ date="2013-10-21T22:20:53Z"
+ content="""
+You have two choices:
+
+1. Install git-annex on your server. You can then use the webapp to set up a git repository, or use the git repository you've already set up.
+
+2. Don't install git-annex on your server. Select the option in the webapp to use an encrypred rsync repository on your server. (The screen you described the webapp showing had a button to use this option, but you seem to have misread it.)
+"""]]
diff --git a/doc/forum/Git_Annex_Transfer_Protocols.mdwn b/doc/forum/Git_Annex_Transfer_Protocols.mdwn
new file mode 100644
index 000000000..d6a660a2d
--- /dev/null
+++ b/doc/forum/Git_Annex_Transfer_Protocols.mdwn
@@ -0,0 +1,9 @@
+Hi,
+
+May I know, which processes git-annex is using to move/copy/get file content between repositories?
+Is it using same processes which git uses, Like send-pack, receive-pack.
+I want to use Aspera to move file contents between repositories.
+Is it enough if I customize send-pack, receive-pack of git code to do Aspera file transfer or git-annex uses any other transfer mechanism.
+
+Many Thanks,
+Royal Pinto
diff --git a/doc/forum/Git_Annex_Transfer_Protocols/comment_1_a870ec991078c95a6bb683d6962ab56e._comment b/doc/forum/Git_Annex_Transfer_Protocols/comment_1_a870ec991078c95a6bb683d6962ab56e._comment
new file mode 100644
index 000000000..31c463470
--- /dev/null
+++ b/doc/forum/Git_Annex_Transfer_Protocols/comment_1_a870ec991078c95a6bb683d6962ab56e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.2.186"
+ subject="rsync over ssh"
+ date="2012-05-10T18:18:01Z"
+ content="""
+Some other protocols such as S3 for special remotes.
+"""]]
diff --git a/doc/forum/Git_Annex_Transfer_Protocols/comment_2_71419376ef50a679ea8f0f9e16991c17._comment b/doc/forum/Git_Annex_Transfer_Protocols/comment_2_71419376ef50a679ea8f0f9e16991c17._comment
new file mode 100644
index 000000000..2e07aef08
--- /dev/null
+++ b/doc/forum/Git_Annex_Transfer_Protocols/comment_2_71419376ef50a679ea8f0f9e16991c17._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlYu7QmD7wrbHWkoxuriaA9XcijM-g5vrQ"
+ nickname="Royal"
+ subject="Protocols to transfer file content"
+ date="2012-05-10T18:48:40Z"
+ content="""
+Thanks, Is git annex is using same protocols as normal git to transfer content between normal git repositories?
+"""]]
diff --git a/doc/forum/Git_Annex_Transfer_Protocols/comment_3_fea43664a500111ca99f4043e0dadb14._comment b/doc/forum/Git_Annex_Transfer_Protocols/comment_3_fea43664a500111ca99f4043e0dadb14._comment
new file mode 100644
index 000000000..6e7b36e31
--- /dev/null
+++ b/doc/forum/Git_Annex_Transfer_Protocols/comment_3_fea43664a500111ca99f4043e0dadb14._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.2.186"
+ subject="comment 3"
+ date="2012-05-10T18:51:56Z"
+ content="""
+git-annex doesn't transfer git content between git repositories. You use git for that. Well, git-annex sync can run a few git commands for you to do it.
+"""]]
diff --git a/doc/forum/Git_Annex_Transfer_Protocols/comment_4_56fb2dab1d4030c9820be32b495afdf0._comment b/doc/forum/Git_Annex_Transfer_Protocols/comment_4_56fb2dab1d4030c9820be32b495afdf0._comment
new file mode 100644
index 000000000..fef10cd81
--- /dev/null
+++ b/doc/forum/Git_Annex_Transfer_Protocols/comment_4_56fb2dab1d4030c9820be32b495afdf0._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlYu7QmD7wrbHWkoxuriaA9XcijM-g5vrQ"
+ nickname="Royal"
+ subject="Git annex content transfer protocols"
+ date="2012-05-10T19:13:48Z"
+ content="""
+Sorry if I am not clear. Actually i meant to ask, if i have 2 git repositories which are not special remotes and I am transferring annexed file content between these repositories using git annex command (move or copy) then, which protocol it uses to transfer content? Is it uses git-send-pack git-recieve-pack or some other protocols.
+"""]]
diff --git a/doc/forum/Git_Annex_Transfer_Protocols/comment_5_a6ec9c5a4a3c0bac1df87f1df9be140b._comment b/doc/forum/Git_Annex_Transfer_Protocols/comment_5_a6ec9c5a4a3c0bac1df87f1df9be140b._comment
new file mode 100644
index 000000000..be25737c1
--- /dev/null
+++ b/doc/forum/Git_Annex_Transfer_Protocols/comment_5_a6ec9c5a4a3c0bac1df87f1df9be140b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.2.186"
+ subject="comment 5"
+ date="2012-05-10T19:17:22Z"
+ content="""
+rsync over ssh is used to transfer file contents between repositories. (You can use the -d option to see the commands git-annex runs.)
+"""]]
diff --git a/doc/forum/Git_Annex_Transfer_Protocols/comment_6_1678452fb7114aeabcf0cc3d5f6c69b0._comment b/doc/forum/Git_Annex_Transfer_Protocols/comment_6_1678452fb7114aeabcf0cc3d5f6c69b0._comment
new file mode 100644
index 000000000..b7ef8f33c
--- /dev/null
+++ b/doc/forum/Git_Annex_Transfer_Protocols/comment_6_1678452fb7114aeabcf0cc3d5f6c69b0._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlYu7QmD7wrbHWkoxuriaA9XcijM-g5vrQ"
+ nickname="Royal"
+ subject="comment 6"
+ date="2012-05-10T19:21:08Z"
+ content="""
+Ok. This helped me a lot. Thank you
+"""]]
diff --git a/doc/forum/Git_annex___39__corrupting__39___itself.mdwn b/doc/forum/Git_annex___39__corrupting__39___itself.mdwn
new file mode 100644
index 000000000..fe1edc17d
--- /dev/null
+++ b/doc/forum/Git_annex___39__corrupting__39___itself.mdwn
@@ -0,0 +1,34 @@
+Hi,
+
+Since the I updated to `2013-10-24` `git annex` has corrupted itself twice on my setup. I'm not claiming causality here and thus I haven't filled it as a bug (probably the mistake is mine).
+
+I use three laptops and one remote ssh server. The motherboard on laptop *T* seems to have broken and I haven't fixed it yet. I have disabled sync to *T* on the webapp dashboard.
+
+First, one computer, called *W*, broke on Friday. I got the dreaded [serious problem](http://git-annex.branchable.com/devblog/day_41__onward/) screen. `git fsck` reported lots of missing blobs and tree problem, though my data seemed OK. I git cloned the repo from computer *X*. Now, last night both X and W reported the same problem (log below). *W* recovered itself somehow, but *X* is now in a cycle of re-adding all files in the repo and the posting the below error that has to do with computer *T* (IP ending with 107).
+
+I would appreciate hints on why this suddenly started happen. Computer T has been out of sync for almost 14 days (since the 24th of October I think).
+
+ error: refs/remotes/192.168.1.107_annex/git-annex does not point to a valid object!
+ error: refs/remotes/192.168.1.107_annex/master does not point to a valid object!
+ error: refs/remotes/192.168.1.107_annex/synced/git-annex does not point to a valid object!
+ error: refs/remotes/192.168.1.107_annex/synced/master does not point to a valid object!
+ error: refs/synced/2ed58ecf-8e8c-44b8-ad34-d42ddfb35315/cmFzbXVzQGNvZGVyb2xsZXJzLmNvbQ==/git-annex does not point to a valid object!
+ error: refs/synced/2ed58ecf-8e8c-44b8-ad34-d42ddfb35315/cmFzbXVzQGNvZGVyb2xsZXJzLmNvbQ==/master does not point to a valid object!
+ error: refs/synced/f54b8200-8ec1-43d2-8710-b73ec118addc/cmFzbXVzQGNvZGVyb2xsZXJzLmNvbQ==/git-annex does not point to a valid object!
+ error: refs/synced/f54b8200-8ec1-43d2-8710-b73ec118addc/cmFzbXVzQGNvZGVyb2xsZXJzLmNvbQ==/master does not point to a valid object!
+ error: refs/synced/f54b8200-8ec1-43d2-8710-b73ec118addc/git-annex does not point to a valid object!
+ error: refs/synced/f54b8200-8ec1-43d2-8710-b73ec118addc/master does not point to a valid object!
+ error: refs/remotes/192.168.1.107_annex/git-annex does not point to a valid object!
+ error: refs/remotes/192.168.1.107_annex/master does not point to a valid object!
+ error: refs/remotes/192.168.1.107_annex/synced/git-annex does not point to a valid object!
+ error: refs/remotes/192.168.1.107_annex/synced/master does not point to a valid object!
+ error: refs/synced/2ed58ecf-8e8c-44b8-ad34-d42ddfb35315/cmFzbXVzQGNvZGVyb2xsZXJzLmNvbQ==/git-annex does not point to a valid object!
+ error: refs/synced/2ed58ecf-8e8c-44b8-ad34-d42ddfb35315/cmFzbXVzQGNvZGVyb2xsZXJzLmNvbQ==/master does not point to a valid object!
+ error: refs/synced/f54b8200-8ec1-43d2-8710-b73ec118addc/cmFzbXVzQGNvZGVyb2xsZXJzLmNvbQ==/git-annex does not point to a valid object!
+ error: refs/synced/f54b8200-8ec1-43d2-8710-b73ec118addc/cmFzbXVzQGNvZGVyb2xsZXJzLmNvbQ==/master does not point to a valid object!
+ error: refs/synced/f54b8200-8ec1-43d2-8710-b73ec118addc/git-annex does not point to a valid object!
+ error: refs/synced/f54b8200-8ec1-43d2-8710-b73ec118addc/master does not point to a valid object!
+ error: invalid object 100644 1ca66de3cdd9c79cde26a7555cf3b8d26d0e371d for '000/147/SHA256E-s347--1ab8084bf9ae06407ce0a7260a83638ea6e9a028dc59b4815fd60aec61dbd747.txt.log.log'
+ fatal: git-write-tree: error building trees
+ TransferScanner crashed: failed to read sha from git write-tree
+ [2013-11-04 09:45:41 CET] TransferScanner: warning TransferScanner crashed: failed to read sha from git write-tree
diff --git a/doc/forum/Git_annex___39__corrupting__39___itself/comment_1_bcf50a215e2f8771e098aadfff4c300c._comment b/doc/forum/Git_annex___39__corrupting__39___itself/comment_1_bcf50a215e2f8771e098aadfff4c300c._comment
new file mode 100644
index 000000000..2fe95ab33
--- /dev/null
+++ b/doc/forum/Git_annex___39__corrupting__39___itself/comment_1_bcf50a215e2f8771e098aadfff4c300c._comment
@@ -0,0 +1,43 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlEXAlu8qKv_FHYOv-uEohdGgMY_Lw-Ges"
+ nickname="Jonas"
+ subject="Just happened for me as well."
+ date="2013-11-12T08:10:56Z"
+ content="""
+This was the first search result when I googled the error message, I'm not sure what has happened (or if it is a problem since I don't change my files that often).
+
+git-annex version: 4.20131101
+
+Also running git annex with one ssh remote ( laptop1 & laptop2 synching through a ssh remote server ).
+
+Got a bunch of
+ error: refs/synced/dbb70cea-4b83-416f-93af-e59082c4d633/git-annex does not point to a valid object!
+ error: refs/synced/dbb70cea-4b83-416f-93af-e59082c4d633/master does not point to a valid object!
+ error: refs/synced/dbb70cea-4b83-416f-93af-e59082c4d633/git-annex does not point to a valid object!
+ error: refs/synced/dbb70cea-4b83-416f-93af-e59082c4d633/master does not point to a valid object!
+when I tried a manual git annex sync, and noticed that I had a bunch of those in the log in the webapp as well...
+
+The gui doesn't show that anything is wrong, and looking at the log it seems that things are atleast uploading
+
+ [2013-11-12 09:05:46 CET] Committer: Committing changes to git
+ [2013-11-12 09:05:46 CET] Pusher: Syncing with born
+ error: refs/synced/dbb70cea-4b83-416f-93af-e59082c4d633/git-annex does not point to a valid object!
+ error: refs/synced/dbb70cea-4b83-416f-93af-e59082c4d633/master does not point to a valid object!
+ Everything up-to-date
+
+ FILE
+
+ 32768 42% 0.00kB/s 0:00:00
+ 76972 100% 42.16MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 77056 bytes received 31 bytes 51391.33 bytes/sec
+ total size is 76972 speedup is 1.00
+ [2013-11-12 09:05:48 CET] Transferrer: Uploaded FILE
+ [2013-11-12 09:05:48 CET] Pusher: Syncing with born
+ error: refs/synced/dbb70cea-4b83-416f-93af-e59082c4d633/git-annex does not point to a valid object!
+ error: refs/synced/dbb70cea-4b83-416f-93af-e59082c4d633/master does not point to a valid object!
+ error: refs/synced/dbb70cea-4b83-416f-93af-e59082c4d633/git-annex does not point to a valid object!
+ error: refs/synced/dbb70cea-4b83-416f-93af-e59082c4d633/master does not point to a valid object!
+ To ssh://me@born/annex
+ 54e04cf..333cf10 git-annex -> synced/git-annex
+"""]]
diff --git a/doc/forum/Git_annex___39__corrupting__39___itself/comment_3_75f957e7be6c1ad8936c0a2a5374db3e._comment b/doc/forum/Git_annex___39__corrupting__39___itself/comment_3_75f957e7be6c1ad8936c0a2a5374db3e._comment
new file mode 100644
index 000000000..80f778bb1
--- /dev/null
+++ b/doc/forum/Git_annex___39__corrupting__39___itself/comment_3_75f957e7be6c1ad8936c0a2a5374db3e._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlEXAlu8qKv_FHYOv-uEohdGgMY_Lw-Ges"
+ nickname="Jonas"
+ subject="comment 3"
+ date="2013-11-13T09:03:24Z"
+ content="""
+I did a change of one of the files and that totally broke all other repositories, git fsck reports a lot of missing trees (I'm not sure if it is normal), and git annex fsck started reporting invalid object for another file for some reason, also got a (git annex repair still reports everything is fine though.)
+
+ fatal: git-write-tree: error building trees
+ git-annex: failed to read sha from git write-tree
+
+
+
+I tried following those instructions but I don't think I had a good repository, git annex repair reported everything was ok but git fsck said a lot of trees where missing and it stopped updating.
+I noticed I was running different git version (git version 1.7.9.5 on the server and git version 1.8.4.2 on one of the clients), so maybe that was part of the reason.
+
+I couldn't find out what remote dbb70cea-4b83-416f-93af-e59082c4d633 was supposed to be either, it wasn't any of the active ones and it didn't show up with git annex status either (I've lost a few repositories when I reinstalled my computer).
+
+I ended up recreating the repository (by copying the raw files) from what I think is the most recent version from one of my computers and hope that it was a error that happened due to upgrades.
+"""]]
diff --git a/doc/forum/Git_annex___39__corrupting__39___itself/comment_3_ab062b1df3b55fd49852a6220c98249e._comment b/doc/forum/Git_annex___39__corrupting__39___itself/comment_3_ab062b1df3b55fd49852a6220c98249e._comment
new file mode 100644
index 000000000..76e9d00de
--- /dev/null
+++ b/doc/forum/Git_annex___39__corrupting__39___itself/comment_3_ab062b1df3b55fd49852a6220c98249e._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://id.clacke.se/"
+ nickname="clacke"
+ subject="comment 3"
+ date="2013-11-12T17:19:32Z"
+ content="""
+I have been getting this too. Here is what I have done to fix it:
+
+[[tips/recovering_from_a_corrupt_git_repository]]
+"""]]
diff --git a/doc/forum/Git_annex_assistant_in_command_line.mdwn b/doc/forum/Git_annex_assistant_in_command_line.mdwn
new file mode 100644
index 000000000..9323d2137
--- /dev/null
+++ b/doc/forum/Git_annex_assistant_in_command_line.mdwn
@@ -0,0 +1,2 @@
+How can I clone a git annex remote (bare repository) created with the webapp in command line ? My goal is to be able to access the files using an ssh connection.
+
diff --git a/doc/forum/Git_annex_assistant_in_command_line/comment_1_ce05226307ade8db90ada2dbf290bd58._comment b/doc/forum/Git_annex_assistant_in_command_line/comment_1_ce05226307ade8db90ada2dbf290bd58._comment
new file mode 100644
index 000000000..e02a4298c
--- /dev/null
+++ b/doc/forum/Git_annex_assistant_in_command_line/comment_1_ce05226307ade8db90ada2dbf290bd58._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.254.222"
+ subject="comment 1"
+ date="2013-07-07T17:16:27Z"
+ content="""
+There is no difference between a repository created using the assistant and one created by hand. So you can just `git clone ssh://server/path` or `git remote add foo ssh://server/path` and use it at the command line like any other repository.
+
+The assistant interoperates perfectly with the command line; you can switch between them at will at any time.
+"""]]
diff --git a/doc/forum/Git_annex_assistant_on_EC2.mdwn b/doc/forum/Git_annex_assistant_on_EC2.mdwn
new file mode 100644
index 000000000..27f20ae46
--- /dev/null
+++ b/doc/forum/Git_annex_assistant_on_EC2.mdwn
@@ -0,0 +1,5 @@
+With Amazon EC2, it is possible to take a snapshot of the virtual machine and then bring up multiple instances based on the snapshot.
+
+If I configure git annex assistant to sync a folder to S3, will it work correctly if I spin up multiple instances, all identical git annex assistant configurations?
+
+My use case is to allow users of my forums to upload attachments with their posts. The attachments are stored locally on disk, but I'm hoping that git annex assistant can help synchroise the attachments across all forum instances (I usually run only 1 instance, but their could be as many as 3 under heavy load).
diff --git a/doc/forum/Git_annex_assistant_on_EC2/comment_1_bbdb4611373117a2176c225378110a05._comment b/doc/forum/Git_annex_assistant_on_EC2/comment_1_bbdb4611373117a2176c225378110a05._comment
new file mode 100644
index 000000000..cab80f976
--- /dev/null
+++ b/doc/forum/Git_annex_assistant_on_EC2/comment_1_bbdb4611373117a2176c225378110a05._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="comment 1"
+ date="2013-09-06T22:57:05Z"
+ content="""
+If you are using ec2 and s3 why don't you just serve the attachments directly from s3? Not sure how git-annex adds anything here.
+"""]]
diff --git a/doc/forum/Git_annex_assistant_on_EC2/comment_2_614ed11f7134137d6376d36a61c293f5._comment b/doc/forum/Git_annex_assistant_on_EC2/comment_2_614ed11f7134137d6376d36a61c293f5._comment
new file mode 100644
index 000000000..dfb629d62
--- /dev/null
+++ b/doc/forum/Git_annex_assistant_on_EC2/comment_2_614ed11f7134137d6376d36a61c293f5._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.251.174"
+ subject="comment 2"
+ date="2013-09-07T17:08:27Z"
+ content="""
+You are going to need to make each repository have a distinct UUID. Otherwise, the assistant will get confused.
+"""]]
diff --git a/doc/forum/Git_annex_on_Windows.mdwn b/doc/forum/Git_annex_on_Windows.mdwn
new file mode 100644
index 000000000..b5ca80bee
--- /dev/null
+++ b/doc/forum/Git_annex_on_Windows.mdwn
@@ -0,0 +1,11 @@
+Hi,
+I want to download some files in git and git annex in Windows OS.
+I have installed msysgit for git-scm in D:\Git directory,
+Now I download git-annex assistant for Windows, and install it
+in D:\Git\cmd directory.
+But when I run the command "git annex" in git-bash, it says it can not
+found the "git annex" command.
+My question is that, how should I use git annex in Windows to download files?
+For example, git annex get <filename>.
+Doea anyone has any idear to help me figure it out?
+Thanks in advance!
diff --git a/doc/forum/Git_annex_on_Windows/comment_1_da24ba0219a164f9ab93fe75dd85127e._comment b/doc/forum/Git_annex_on_Windows/comment_1_da24ba0219a164f9ab93fe75dd85127e._comment
new file mode 100644
index 000000000..be50ece07
--- /dev/null
+++ b/doc/forum/Git_annex_on_Windows/comment_1_da24ba0219a164f9ab93fe75dd85127e._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.251.174"
+ subject="comment 1"
+ date="2013-09-07T17:00:03Z"
+ content="""
+Are you able to run git commands? IIRC msysgit prompts when it's installed about whether you want to put it in the path or not. git-annex just piggybacks on this path setting. It is installed in the same folder as the git.exe and should work as long as that is in path.
+Otherwise, consult windows documentation to add git-annex to the path, or you can copy the git-annex.exe to somewhere else I suppose.
+
+I built a clean Windows system yesterday and have just re-tested it and it does work.
+"""]]
diff --git a/doc/forum/Git_annex_on_Windows/comment_2_c0880ce3ee13d388ab5b46a740170845._comment b/doc/forum/Git_annex_on_Windows/comment_2_c0880ce3ee13d388ab5b46a740170845._comment
new file mode 100644
index 000000000..bdf30b3b7
--- /dev/null
+++ b/doc/forum/Git_annex_on_Windows/comment_2_c0880ce3ee13d388ab5b46a740170845._comment
@@ -0,0 +1,50 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkQrsXK-icnYXg6kJNd-jDjMgOixnhwE34"
+ nickname="x"
+ subject="reply to Comment 1"
+ date="2013-09-10T13:46:45Z"
+ content="""
+Thanks for your helpful comment.I add the path to windows, and the
+problem disappears now.
+But I meet another problem when I download the data using git annex.
+I use the command \"git annex get foo.nc\" to download data. The foo.nc
+is actually symlink. For example:
+foo.nc -> ../../.git/annex/objects/jK/v7/WORM-s16009120-m1337754158--
+foo.nc/WORM-s16009120-m1337754158--foo.nc
+Could you help me to figure it out?
+Thank you.
+
+The erro information when using git annex in Windows, is as below:
+
+$ git annex get tau.nc
+
+ Detected a crippled filesystem.
+
+ Enabling direct mode.
+
+ Detected a filesystem without fifo support.
+
+ Disabling ssh connection caching.
+
+*** Please tell me who you are.
+
+
+
+Run
+
+ git config --global user.email \"you@example.com\"
+
+ git config --user.name \"Your Name\"
+
+to set your account's default identity.
+
+Omit --global to set the identity only in this repository.
+
+
+
+fatal: unable to auto-detect email address (got 'xshao@DELL-PC.(none')
+
+git-annex :tau.nc not found
+
+(Recording state in git ...)
+"""]]
diff --git a/doc/forum/Git_annex_on_Windows/comment_3_70c22716fde60d14fd0c7e74acf4a224._comment b/doc/forum/Git_annex_on_Windows/comment_3_70c22716fde60d14fd0c7e74acf4a224._comment
new file mode 100644
index 000000000..772d9348a
--- /dev/null
+++ b/doc/forum/Git_annex_on_Windows/comment_3_70c22716fde60d14fd0c7e74acf4a224._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkQrsXK-icnYXg6kJNd-jDjMgOixnhwE34"
+ nickname="x"
+ subject="Comment3"
+ date="2013-09-10T15:36:57Z"
+ content="""
+In addition, because the file is actually symlink direct to the data stored in Amazon S3
+How could I get the URL, given the symlink for git annex. For example:
+foo.nc -> ../../.git/annex/objects/jK/v7/WORM-s16009120-m1337754158--foo.nc/WORM-s16009120-m1337754158--foo.nc
+Thank you.
+"""]]
diff --git a/doc/forum/Git_annex_on_Windows/comment_4_b9232deab6bc5036d7339aa202013218._comment b/doc/forum/Git_annex_on_Windows/comment_4_b9232deab6bc5036d7339aa202013218._comment
new file mode 100644
index 000000000..6fd2f8c3d
--- /dev/null
+++ b/doc/forum/Git_annex_on_Windows/comment_4_b9232deab6bc5036d7339aa202013218._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.51"
+ subject="comment 4"
+ date="2013-09-12T20:58:30Z"
+ content="""
+Once `git annex get` has downloaded the file, it will replace the symlink with the contents of the file.
+
+If that is not happening, you might try running `git annex fsck`
+
+
+"""]]
diff --git a/doc/forum/Git_annex_on_Windows/comment_5_27af3c431b50b540d2bd1d3af3f21080._comment b/doc/forum/Git_annex_on_Windows/comment_5_27af3c431b50b540d2bd1d3af3f21080._comment
new file mode 100644
index 000000000..5db96f08e
--- /dev/null
+++ b/doc/forum/Git_annex_on_Windows/comment_5_27af3c431b50b540d2bd1d3af3f21080._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.2.134"
+ subject="comment 5"
+ date="2013-09-13T18:03:17Z"
+ content="""
+Turns out that there was a bug in the Windows port that could lead to the behavior described, and another bug that prevented `git annex fsck` from fixing it. I have fixed both bugs, so you should upgrade and then run `git annex fsck`.
+"""]]
diff --git a/doc/forum/Git_annex_syncing_speed__44___possible__63__.mdwn b/doc/forum/Git_annex_syncing_speed__44___possible__63__.mdwn
new file mode 100644
index 000000000..d1fcc74aa
--- /dev/null
+++ b/doc/forum/Git_annex_syncing_speed__44___possible__63__.mdwn
@@ -0,0 +1,21 @@
+Hello
+
+I'm trying Git annex latest builds available in Linux & Android
+Here is the scenario :-
+
+Syncing 2 peer devices running Linux & Android
+Devices can access each other directly over Cisco VPN encrypted link
+
+Currently, syncing files via rsync over webdav (over Cisco VPN)
+Everything is working, manual file tracking is an issue.
+
+Here's where Git annex steps in,
+I've configures external jabber account so they can talk to each other.
+
+But the transfers are super-slow over internet,
+I'm guessing Cisco VPN adding 15-20% overhead + SSH adding another 20-30% overhead.
+
+Since the network link is trusted, is there any way to speed things up assuming Cisco solution
+remains in place?
+
+looking to solve this issue
diff --git a/doc/forum/Git_annex_syncing_speed__44___possible__63__/comment_1_8aa224b3016dc38e4cea8ee1865a3ab6._comment b/doc/forum/Git_annex_syncing_speed__44___possible__63__/comment_1_8aa224b3016dc38e4cea8ee1865a3ab6._comment
new file mode 100644
index 000000000..eb0e65f80
--- /dev/null
+++ b/doc/forum/Git_annex_syncing_speed__44___possible__63__/comment_1_8aa224b3016dc38e4cea8ee1865a3ab6._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="comment 1"
+ date="2013-07-12T20:09:32Z"
+ content="""
+Not sure if it applies to your devices, but I considerably speed up SSH transfers on my raspberry pi by using
+
+ Ciphers arcfour
+
+in the ssh configuration.
+"""]]
diff --git a/doc/forum/Git_repos_in_git_annex__63__.mdwn b/doc/forum/Git_repos_in_git_annex__63__.mdwn
new file mode 100644
index 000000000..2d16a6659
--- /dev/null
+++ b/doc/forum/Git_repos_in_git_annex__63__.mdwn
@@ -0,0 +1,7 @@
+Hello,
+
+A mode of operation that I find comfortable, and from various online posts it seems that so do some others, is putting whole git repositories in dropbox.
+
+It seems that currently this mode of operations if not supported in a simple manner. (i.e. just add and let assistant do the work). Is there any workaround or possibility to do this?
+
+Thanks!
diff --git a/doc/forum/Git_repos_in_git_annex__63__/comment_1_8aaa0d83e8fcd5997f6b0097f3b21622._comment b/doc/forum/Git_repos_in_git_annex__63__/comment_1_8aaa0d83e8fcd5997f6b0097f3b21622._comment
new file mode 100644
index 000000000..fac5ad5b1
--- /dev/null
+++ b/doc/forum/Git_repos_in_git_annex__63__/comment_1_8aaa0d83e8fcd5997f6b0097f3b21622._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="EvanDeaubl"
+ ip="68.230.56.163"
+ subject="comment 1"
+ date="2013-07-28T02:40:24Z"
+ content="""
+I'll give this warning upfront: this works for me, but it requires manual intervention, and I wouldn't be surprised if this spectacularly broke with the assistant running in full auto mode.
+
+I'm currently storing git repos inside of my annex by using a separated git dir, so that git doesn't detect the nested repository and balk at adding it. Doing a git clone or git init with a --separate-git-dir=<git dir> argument puts what would normally be in .git in that directory, and creates a simple .git file in its place which references the separated git dir.
+
+When I'm not using the repo, I move the .git file out of the directory, and everything looks like regular files to git-annex. When I want to use it, I move it back in place, and any git operations inside the repo directory use the inner git repo itself.
+
+Another option I used for a while was to store bare repos in the annex, and doing checkouts from those repos.
+"""]]
diff --git a/doc/forum/Git_repositories_in_the_annex__63__.mdwn b/doc/forum/Git_repositories_in_the_annex__63__.mdwn
new file mode 100644
index 000000000..a18af8c2c
--- /dev/null
+++ b/doc/forum/Git_repositories_in_the_annex__63__.mdwn
@@ -0,0 +1,5 @@
+First of all thanks for the great work. git-annex looks very nice already!
+
+I wonder if it's possible to add Git repositories to the annex. In my current Dropbox setup I drop some small Git repositories into the Dropbox to keep them in sync on two computers.
+
+This is obviously not possible with git-annex, as the annex itself is a Git repository and sub-repositories (directories with .git folders) are ignored. But in some cases people might want to be able to drop "anything" into the annex, maybe even Git repositories (e.g. the "nomad" usecase)...
diff --git a/doc/forum/Handling_web_special_remote_when_content_changes__63__.mdwn b/doc/forum/Handling_web_special_remote_when_content_changes__63__.mdwn
new file mode 100644
index 000000000..5b7be7157
--- /dev/null
+++ b/doc/forum/Handling_web_special_remote_when_content_changes__63__.mdwn
@@ -0,0 +1,19 @@
+I am in the process of organising all of my documents (pdf/ps/etc.) and putting them into an annex. It seems like the easiest (and smartest?) way for me to manage my 15,000+ document library... (Yeah, I've not read them all!)
+
+However, one of the issues I have run into is when I want to include something like a software manual...
+
+I'm not even sure if git-annex is the correct way to handle these sort of document, but...
+
+What would you do if the URL stays the same, but the file content changes over time?
+
+For example, the administration manual for R gets updated and re-released for each release of R, but the URL stays the same.
+
+ http://cran.r-project.org/doc/manuals/R-admin.pdf
+
+I'm not particularly worried about whether my annex version is the most recent, just that if I want to 'annex get' it, it will pull *a* version from somewhere.
+
+Any thoughts?
+
+I'd bet that the SHA-hash would change between releases(!) so would a WORM backend be the best approach? It would mess up my one-file-in-multiple-directories (i.e. multiple simlinks to the one SHA-...-.....) approach.
+
+
diff --git a/doc/forum/Handling_web_special_remote_when_content_changes__63__/comment_1_05ee6a1b1943ef3c90634e52233bde1c._comment b/doc/forum/Handling_web_special_remote_when_content_changes__63__/comment_1_05ee6a1b1943ef3c90634e52233bde1c._comment
new file mode 100644
index 000000000..0f0bf2f32
--- /dev/null
+++ b/doc/forum/Handling_web_special_remote_when_content_changes__63__/comment_1_05ee6a1b1943ef3c90634e52233bde1c._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2012-01-03T00:57:55Z"
+ content="""
+The web special remote will happily download files when you `git annex get` even if they don't have the same content that they did before.
+
+`git annex fsck` will detect such mismatched content to the best ability of the backend (so checking the SHA1, or verifying the file size at least matches if you use WORM), and complain and move such mismatched content aside. `git annex addurl --fast` deserves a special mention; it uses a backend that only records the URL, and so if it's used, fsck cannot later detect such changes. Which might be what you want..
+
+For most users, this is one of the reasons `git annex untrust web` is a recommended configuration. Once you untrust the web, any content you download from the web will be kept around in one of your own git-annex repositories, rather than the untrustworthy web being the old copy.
+"""]]
diff --git a/doc/forum/Handling_web_special_remote_when_content_changes__63__/comment_2_48d82e391812d8ec0d4e6562d0607fe7._comment b/doc/forum/Handling_web_special_remote_when_content_changes__63__/comment_2_48d82e391812d8ec0d4e6562d0607fe7._comment
new file mode 100644
index 000000000..93c43137d
--- /dev/null
+++ b/doc/forum/Handling_web_special_remote_when_content_changes__63__/comment_2_48d82e391812d8ec0d4e6562d0607fe7._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://a-or-b.myopenid.com/"
+ ip="203.45.2.230"
+ subject="comment 2"
+ date="2012-01-03T02:49:18Z"
+ content="""
+Thanks! `git annex addurl --fast` does exactly what I want it to do.
+
+Wow. Yet another special backend for me to play with. :-)
+"""]]
diff --git a/doc/forum/Help_Windows_walkthrough.mdwn b/doc/forum/Help_Windows_walkthrough.mdwn
new file mode 100644
index 000000000..dbe61b556
--- /dev/null
+++ b/doc/forum/Help_Windows_walkthrough.mdwn
@@ -0,0 +1,177 @@
+Hello,
+
+i am trying to run the walkthrough on Windows 7. When i try to get the contents of a file, i only get a some git annex text string and not the real file. Both repositories are on the same ntfs filesystem.
+
+C:\tmp>git annex version
+git-annex version: 4.20130827-g4f18612
+build flags: Pairing Testsuite S3 WebDAV DNS
+local repository version: 4
+default repository version: 3
+supported repository versions: 3 4
+upgrade supported from repository versions: 2
+
+C:\tmp\server>git --version
+git version 1.8.3.msysgit.0
+
+
+# walkthrough.bat
+
+ doskey /history > commands.log
+ mkdir laptop
+ cd laptop
+ git init
+ git annex init laptop
+ cd ..
+
+ git clone laptop server
+ cd server
+ git annex init server
+ git remote add laptop c:\tmp\laptop
+
+ cd ..\laptop
+ git remote add server c:\tmp\server
+ copy ..\1.pdf .
+ git annex add 1.pdf
+ git commit -m add
+ dir
+
+ cd ..\server
+ dir
+ git fetch laptop
+ git merge laptop/master
+ git annex get 1.pdf
+ dir
+ type 1.pdf
+
+
+# walkthrough.log
+
+ C:\tmp>walkthrough.bat
+
+ C:\tmp>doskey /history 1>commands.log
+
+ C:\tmp>mkdir laptop
+
+ C:\tmp>cd laptop
+
+ C:\tmp\laptop>git init
+ Initialized empty Git repository in C:/tmp/laptop/.git/
+
+ C:\tmp\laptop>git annex init laptop
+ init laptop
+ Detected a crippled filesystem.
+
+ Enabling direct mode.
+
+ Detected a filesystem without fifo support.
+
+ Disabling ssh connection caching.
+ ok
+ (Recording state in git...)
+
+ C:\tmp\laptop>cd ..
+
+ C:\tmp>git clone laptop server
+ Cloning into 'server'...
+ done.
+ warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+
+ C:\tmp>cd server
+
+ C:\tmp\server>git annex init server
+ init server
+ Detected a crippled filesystem.
+
+ Enabling direct mode.
+
+ Detected a filesystem without fifo support.
+
+ Disabling ssh connection caching.
+ ok
+ (Recording state in git...)
+
+ C:\tmp\server>git remote add laptop c:\tmp\laptop
+
+ C:\tmp\server>cd ..\laptop
+
+ C:\tmp\laptop>git remote add server c:\tmp\server
+
+ C:\tmp\laptop>copy ..\1.pdf .
+ 1 file(s) copied.
+
+ C:\tmp\laptop>git annex add 1.pdf
+ add 1.pdf (checksum...) ok
+ (Recording state in git...)
+
+ C:\tmp\laptop>git commit -m add
+ [master (root-commit) 7ad1514] add
+ 1 file changed, 1 insertion(+)
+ create mode 120000 1.pdf
+
+ C:\tmp\laptop>dir
+ Volume in drive C has no label.
+ Volume Serial Number is x
+
+ Directory of C:\tmp\laptop
+
+ 09/01/2013 11:03 AM <DIR> .
+ 09/01/2013 11:03 AM <DIR> ..
+ 08/30/2013 12:43 PM 37,500 1.pdf
+ 1 File(s) 37,500 bytes
+ 2 Dir(s) 7,698,817,024 bytes free
+
+ C:\tmp\laptop>cd ..\server
+
+ C:\tmp\server>dir
+ Volume in drive C has no label.
+ Volume Serial Number is x
+
+ Directory of C:\tmp\server
+
+ 09/01/2013 11:03 AM <DIR> .
+ 09/01/2013 11:03 AM <DIR> ..
+ 0 File(s) 0 bytes
+ 2 Dir(s) 7,698,817,024 bytes free
+
+ C:\tmp\server>git fetch laptop
+ remote: Counting objects: 9, done.
+ remote: Compressing objects: 100% (6/6), done.
+ remote: Total 8 (delta 1), reused 0 (delta 0)
+ Unpacking objects: 100% (8/8), done.
+ From c:\tmp\laptop
+ * [new branch] git-annex -> laptop/git-annex
+ * [new branch] master -> laptop/master
+
+ C:\tmp\server>git merge laptop/master
+
+ C:\tmp\server>git annex get 1.pdf
+ get 1.pdf (merging laptop/git-annex origin/git-annex into git-annex...)
+ (Recording state in git...)
+ (from laptop...)
+ 1.pdf
+ 37500 100% 4.51MB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 37573 bytes received 31 bytes 75208.00 bytes/sec
+ total size is 37500 speedup is 1.00
+ ok
+ (Recording state in git...)
+
+ C:\tmp\server>dir
+ Volume in drive C has no label.
+ Volume Serial Number is x
+
+ Directory of C:\tmp\server
+
+ 09/01/2013 11:03 AM <DIR> .
+ 09/01/2013 11:03 AM <DIR> ..
+ 09/01/2013 11:03 AM 194 1.pdf
+ 1 File(s) 194 bytes
+ 2 Dir(s) 7,698,767,872 bytes free
+
+ C:\tmp\server>type 1.pdf
+ .git/annex/objects/kM/0q/SHA256E-s37500--32d8190c7e189d45f48245a100e4cc981ea1bbc
+ 02ac8bfa6188db73e41ce06f3.pdf/SHA256E-s37500--32d8190c7e189d45f48245a100e4cc981e
+ a1bbc02ac8bfa6188db73e41ce06f3.pdfC:\tmp\server>
+ C:\tmp\server>
+
diff --git a/doc/forum/Help_Windows_walkthrough/comment_1_5fc22393a1b28235eabb2871ad83d0a7._comment b/doc/forum/Help_Windows_walkthrough/comment_1_5fc22393a1b28235eabb2871ad83d0a7._comment
new file mode 100644
index 000000000..95623a645
--- /dev/null
+++ b/doc/forum/Help_Windows_walkthrough/comment_1_5fc22393a1b28235eabb2871ad83d0a7._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.7"
+ subject="comment 1"
+ date="2013-09-03T17:59:03Z"
+ content="""
+The walkthrough assumes a system that uses indirect mode by default, so it won't work quite right on Windows, which is forced to use direct mode.
+
+Running `git annex fsck` in the server repository will fix up this situation, but the right thing on Windows is to use `git annex sync` rather than the manual `git fetch + git merge` the walkthrough shows.
+
+Guess I'll make the walkthrough use sync, although it may make it harder for people to understand what's going on internally.
+"""]]
diff --git a/doc/forum/Help_on_my_usecase.mdwn b/doc/forum/Help_on_my_usecase.mdwn
new file mode 100644
index 000000000..ef670aa25
--- /dev/null
+++ b/doc/forum/Help_on_my_usecase.mdwn
@@ -0,0 +1,22 @@
+I am using git-annex assistant for a few months now and still don't think I have it all setup correctly. My setup is:
+
+* Laptop Computer with low storage. Content creator, assistant: file source
+* Desktop Computer with medium storage capacity. Consumer, assistant: manual Mode
+* 2TB USB HD (EXT4) Backup, assistant: full backup
+* 2.5" portable 500GB drive NTFS formatted. transfer to backup: assistant: tried transfer and partial backup
+* Root Server on the web, not yet in the mix. Planned: Index only / content creator
+
+My primary goal is getting the stuff from the Laptop to the 2TB USB drive, syncing the annex with the desktop so I can get files on the desktop from the backup.
+What works:
+
+* Checking stuff into the annex on the Laptop
+* When the 2TB drive is connected to the Laptop, stuff is automatically moved there too
+* Bare Repo on the 2.5" configured as partial backup automatically backups the data
+
+What doesn't work:
+
+* Connecting the 2.5" bare repo to the Desktop to move stuff to the backup drive automatically
+* Having a human readable folder Structure on the 2.5" NTFS drive. I'd be ok to have a bare repo plus a special remote on the drive, but I don't know how to configure it
+* How do I drop stuff from the bare repo on the 2.5" drive? I think a partial backup should drop content that is in a full backup, but it doesn't
+
+Thanks for reading this long post. If anyone has any tips on how to configure the assistant, thats much appreciated.
diff --git a/doc/forum/Help_on_my_usecase/comment_1_a35b35c7927640f21d47c3df4f91dabb._comment b/doc/forum/Help_on_my_usecase/comment_1_a35b35c7927640f21d47c3df4f91dabb._comment
new file mode 100644
index 000000000..25116a7c4
--- /dev/null
+++ b/doc/forum/Help_on_my_usecase/comment_1_a35b35c7927640f21d47c3df4f91dabb._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.246"
+ subject="comment 1"
+ date="2013-11-09T18:18:49Z"
+ content="""
+An incremental backup is supposed to drop content once it reaches a full backup. But, the assistant can only do that if it's able to verify that the full backup drive (or some other repository it can access) has a file, at the same time it's dropping it from the incremental backup drive. If you don't have both the incremental and full backup drives plugged in at the same time, you could consider making git-annex [[trust]] the full backup drive, which would avoid this explicit check.
+
+It sounds like you want a non-bare git repository on the 2.5\" drive. The assistant does not currently support setting that up, but you can do it by just using `git clone` as shown in the [[walkthrough]].
+
+I'm not clear on what doesn't work when you connect the 2.5\" drive to your desktop.
+"""]]
diff --git a/doc/forum/Help_with_syncing_file_contents.mdwn b/doc/forum/Help_with_syncing_file_contents.mdwn
new file mode 100644
index 000000000..28ac22b2e
--- /dev/null
+++ b/doc/forum/Help_with_syncing_file_contents.mdwn
@@ -0,0 +1,68 @@
+Hi everyone,
+
+everyday I understand more and more how git and git-annex work but I need help with this one.
+I guess I have two questions but let me describe the scenario first:
+
+I have one local repository of mp3s (assume just one file: file1.mp3).
+I clone that repository into a remote git-annex repository over ssh and "git annex get" the file contents for file1.mp3.
+
+I unlock some mp3's locally and modify some mp3 tags.
+Then I notify git-annex of these changes
+with "git annex add *"
+and commit them with "git commit -m 'mp3 tags changed'".
+[git annex locks them again and changes the symlinks to point to the changed file in the annex, git commits the changed symlink]
+
+At this point in time there are two objects in my git annex repository:
+hash(file1.mp3)
+hash(file1.mp3|with modified tags)
+The symlink points now to hash(file1.mp3|with modified tags)
+
+At this point the remote still does not now of this commit and of the new file contents.
+Thus I do "git push" to send the changes to the remote.
+The remote now has a BROKEN symlink because it already points to hash(file1.mp3|with modified tags)
+but the remote annex's object directory only contains hash(file1.mp3).
+
+Then I want my remote repository to also have the updated mp3 tags.
+The only way I see (without scripting) to have the updated mp3 tags in the remote repository is to do an "git annex get file1.mp3" on the remote repository or an "git annex copy --to remote file1.mp3" at my local repository. However, although the binary differences between both files
+file1.mp3 and file1.mp3|with modified tags are small the latter is transferred completely from the local repository to the remote repository.
+
+This is not a problem when just changing one file, but a problem when I have 10GB's of files and when it takes 2days to upload them to the remote because of a low bandwidth.
+
+First question: Did I miss something? Does git-annex already provide means to only transmit the diff between the two objects?
+
+Second question regarding disk space.
+I now have a complete history of all changes to file1.mp3 in my git-annex repository. I have the objects that represent every state of file1.mp3 and I can go back to these states when I checkout the respective commits and thereby the symlinks that link to these "old" objects. This history can take up a lot of space. What is the clean way to forget the past? AFAIK "git drop unused" only drops file contents that are not referenced in any commit?
+
+If one wanted to preserve the entire history but save disk space one could also only store the current content and the patches that allow to reconstruct older versions from the current one. I understand that applying several patches consecutively takes more cpu time but for me going back to an older commit with my binary files only happens rarely.
+
+This is the algorithm I have in mind for an optimized "git annex get file1":
+
+On that repository where the file is missing:
+
+1. Find the newest object that represented the contents of file1 in file1's commit history.
+
+2. Transmit this object identification hash(object) to the remote that has the current version (the one I am getting from).
+
+At that remote:
+
+If the history contains full versions of file contents:
+
+Create a binary diff between the object identified by hash(object) and the current content of file1.
+
+If the history contains only the current version and patches to older versions:
+Collect all patches that represent the change from hash(object) to the current content of file1.
+
+If the list of patches is bigger than the current content of file 1 transmit the current content of file1. Otherwise transmit the patch(es)
+
+On that repository where the file is missing:
+
+Apply the patch(es) to the latest object to obtain the current object.
+
+What's your opinion on this?
+
+Marek
+
+
+
+
+
diff --git a/doc/forum/Help_with_syncing_file_contents/comment_1_7ec34de3140983739080115c82966bf5._comment b/doc/forum/Help_with_syncing_file_contents/comment_1_7ec34de3140983739080115c82966bf5._comment
new file mode 100644
index 000000000..87ef6d130
--- /dev/null
+++ b/doc/forum/Help_with_syncing_file_contents/comment_1_7ec34de3140983739080115c82966bf5._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmp1ThsNNAbSn46ju-gwFELfStlhl8usJo"
+ nickname="donkeyicydragon"
+ subject="Possible quick solution with rsync"
+ date="2013-05-28T10:52:30Z"
+ content="""
+One could achieve the effect of only transmitting the changes of file contents using rsync.
+
+On the repository that lacks the current version:
+
+cp latestversionavailable currentversion
+rsync remoterepository/currentversion ./currentversion
+
+
+
+
+
+"""]]
diff --git a/doc/forum/Help_with_syncing_file_contents/comment_2_7dba58d3c62d6f64a270298e4e4329a4._comment b/doc/forum/Help_with_syncing_file_contents/comment_2_7dba58d3c62d6f64a270298e4e4329a4._comment
new file mode 100644
index 000000000..2d427cccb
--- /dev/null
+++ b/doc/forum/Help_with_syncing_file_contents/comment_2_7dba58d3c62d6f64a270298e4e4329a4._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmp1ThsNNAbSn46ju-gwFELfStlhl8usJo"
+ nickname="donkeyicydragon"
+ subject="I should have read git annex unused first"
+ date="2013-05-28T22:14:46Z"
+ content="""
+Apparently \"git annex unused\" finds previous versions of the object that are not symlinked anymore. However, if a file is renamed then the oldest version before the rename is not marked as unused.
+
+
+"""]]
diff --git a/doc/forum/Help_with_syncing_file_contents/comment_3_b26cfa20dc81517d93e760f4809bdc24._comment b/doc/forum/Help_with_syncing_file_contents/comment_3_b26cfa20dc81517d93e760f4809bdc24._comment
new file mode 100644
index 000000000..ff9902e8d
--- /dev/null
+++ b/doc/forum/Help_with_syncing_file_contents/comment_3_b26cfa20dc81517d93e760f4809bdc24._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-05-29T16:50:35Z"
+ content="""
+Treating each version of a file as a separate object that is stored and transmitted separately is one of the core simplifying assumptions of git-annex. Amoung other things it makes it easy to have dumb special remotes that are mere key/value stores. And it keeps it easy to understand.
+
+I don't consider this a problem as far as storage goes. Disk space is cheap; git-annex allows dropping unused versions of files from repositories that are not on large cheap storage.
+
+For file transfer, it would be nice to find optimisations that don't require changing this simplifying assumption. This can be done at least for rsync I think. The [[design/assistant/deltas]] page is where the design of this is or will be worked on.
+"""]]
diff --git a/doc/forum/How_do_I_cleanly_remove_an_Android_git-annex_installation__63__.mdwn b/doc/forum/How_do_I_cleanly_remove_an_Android_git-annex_installation__63__.mdwn
new file mode 100644
index 000000000..a4bcc4843
--- /dev/null
+++ b/doc/forum/How_do_I_cleanly_remove_an_Android_git-annex_installation__63__.mdwn
@@ -0,0 +1 @@
+I had accidentally chosen the wrong directory for the repository. What should I do to clean all of git-annex?
diff --git a/doc/forum/How_do_I_cleanly_remove_an_Android_git-annex_installation__63__/comment_1_e14757c2c106770c2d7069ace4987b3b._comment b/doc/forum/How_do_I_cleanly_remove_an_Android_git-annex_installation__63__/comment_1_e14757c2c106770c2d7069ace4987b3b._comment
new file mode 100644
index 000000000..b051aa704
--- /dev/null
+++ b/doc/forum/How_do_I_cleanly_remove_an_Android_git-annex_installation__63__/comment_1_e14757c2c106770c2d7069ace4987b3b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 1"
+ date="2013-08-24T18:43:08Z"
+ content="""
+It should be sufficient to delete `/sdcard/git-annex.home` and delete the .git directory inside whatever directory you set up as the repository.
+"""]]
diff --git a/doc/forum/How_do_I_dropunused_with_an_rsync_remote__63__.mdwn b/doc/forum/How_do_I_dropunused_with_an_rsync_remote__63__.mdwn
new file mode 100644
index 000000000..c9a5a6c0a
--- /dev/null
+++ b/doc/forum/How_do_I_dropunused_with_an_rsync_remote__63__.mdwn
@@ -0,0 +1,3 @@
+`git annex dropunused` is simple enough.
+
+But how do I perform the equivalent procedure on an rsync remote? I'd presume that `git annex copy --to remote` is not sufficient.
diff --git a/doc/forum/How_do_I_dropunused_with_an_rsync_remote__63__/comment_1_8db3cb5348b845eb99c2c829957db9ea._comment b/doc/forum/How_do_I_dropunused_with_an_rsync_remote__63__/comment_1_8db3cb5348b845eb99c2c829957db9ea._comment
new file mode 100644
index 000000000..026d393bb
--- /dev/null
+++ b/doc/forum/How_do_I_dropunused_with_an_rsync_remote__63__/comment_1_8db3cb5348b845eb99c2c829957db9ea._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmUJBh1lYmvfCCiGr3yrdx-QhuLCSRnU5c"
+ nickname="Justin"
+ subject="comment 1"
+ date="2013-05-12T23:06:34Z"
+ content="""
+Oh, sheesh, it's right there at the bottom of http://git-annex.branchable.com/special_remotes/. Oops.
+"""]]
diff --git a/doc/forum/How_do_I_dropunused_with_an_rsync_remote__63__/comment_2_6cc909d9d74bc1ccb8a7b0d7d234c7cd._comment b/doc/forum/How_do_I_dropunused_with_an_rsync_remote__63__/comment_2_6cc909d9d74bc1ccb8a7b0d7d234c7cd._comment
new file mode 100644
index 000000000..2df92a8a3
--- /dev/null
+++ b/doc/forum/How_do_I_dropunused_with_an_rsync_remote__63__/comment_2_6cc909d9d74bc1ccb8a7b0d7d234c7cd._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-05-13T18:03:23Z"
+ content="""
+Well, in your defense it's documented there because I can't think of a better place to put it. Maybe you looked in some other places first before finding it there, and I should add a pointer to those places?
+
+(For the curious, the magic run is just: git annex unused --from remote)
+"""]]
diff --git a/doc/forum/How_do_I_dropunused_with_an_rsync_remote__63__/comment_3_f24d678e4192a70322aa164ed9b71fc8._comment b/doc/forum/How_do_I_dropunused_with_an_rsync_remote__63__/comment_3_f24d678e4192a70322aa164ed9b71fc8._comment
new file mode 100644
index 000000000..2b53984c3
--- /dev/null
+++ b/doc/forum/How_do_I_dropunused_with_an_rsync_remote__63__/comment_3_f24d678e4192a70322aa164ed9b71fc8._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmUJBh1lYmvfCCiGr3yrdx-QhuLCSRnU5c"
+ nickname="Justin"
+ subject="comment 3"
+ date="2013-05-13T18:56:32Z"
+ content="""
+I think in general the `git annex command --help` bits could be more thorough. If `git annex dropunused --help` indicated that it took `--from`, that would probably have helped me.
+"""]]
diff --git a/doc/forum/How_do_I_dropunused_with_an_rsync_remote__63__/comment_4_9233decd0aaf9211447f36e0d9346445._comment b/doc/forum/How_do_I_dropunused_with_an_rsync_remote__63__/comment_4_9233decd0aaf9211447f36e0d9346445._comment
new file mode 100644
index 000000000..f326cd340
--- /dev/null
+++ b/doc/forum/How_do_I_dropunused_with_an_rsync_remote__63__/comment_4_9233decd0aaf9211447f36e0d9346445._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 4"
+ date="2013-05-13T18:59:08Z"
+ content="""
+You might be using an older version. Here's the output of that command in the current version:
+
+<pre>
+Usage: git-annex dropunused NUM|RANGE ... [option ...]
+ -f REMOTE --from=REMOTE drop content from a remote
+
+To see additional options common to all commands, run: git annex help options
+</pre>
+"""]]
diff --git a/doc/forum/How_do_I_dropunused_with_an_rsync_remote__63__/comment_5_e1deb110f752e5495d5c77ec444abac5._comment b/doc/forum/How_do_I_dropunused_with_an_rsync_remote__63__/comment_5_e1deb110f752e5495d5c77ec444abac5._comment
new file mode 100644
index 000000000..e9ca6bc13
--- /dev/null
+++ b/doc/forum/How_do_I_dropunused_with_an_rsync_remote__63__/comment_5_e1deb110f752e5495d5c77ec444abac5._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmUJBh1lYmvfCCiGr3yrdx-QhuLCSRnU5c"
+ nickname="Justin"
+ subject="comment 5"
+ date="2013-05-13T19:07:11Z"
+ content="""
+Ah, rebuilding got me that. That's pretty good!
+"""]]
diff --git a/doc/forum/How_do_you_know_when_something_fails_a_fsck__63__.mdwn b/doc/forum/How_do_you_know_when_something_fails_a_fsck__63__.mdwn
new file mode 100644
index 000000000..d574956bf
--- /dev/null
+++ b/doc/forum/How_do_you_know_when_something_fails_a_fsck__63__.mdwn
@@ -0,0 +1,4 @@
+Hi Joey,
+ I was wondering how you know when a file in your repo fails a fsck. I'm having trouble finding out since I can't change any of the objects (which is great!). I'd just like to know since I have thousands of files in one of my annexes, and scrolling through my term buffer is unwieldy. I'd assume it would show up when the fsck was done, or in 'git annex status'...
+
+Thanks!
diff --git a/doc/forum/How_do_you_know_when_something_fails_a_fsck__63__/comment_1_1c14981916dd55376d5e9f95023556cb._comment b/doc/forum/How_do_you_know_when_something_fails_a_fsck__63__/comment_1_1c14981916dd55376d5e9f95023556cb._comment
new file mode 100644
index 000000000..042a1c46a
--- /dev/null
+++ b/doc/forum/How_do_you_know_when_something_fails_a_fsck__63__/comment_1_1c14981916dd55376d5e9f95023556cb._comment
@@ -0,0 +1,32 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="comment 1"
+ date="2013-06-10T14:23:25Z"
+ content="""
+ justin@box:/tmp/f$ git init
+ Initialized empty Git repository in /tmp/f/.git/
+ justin@box:/tmp/f$ git-annex init
+ init ok
+ (Recording state in git...)
+ justin@box:/tmp/f$ cp /etc/motd .
+ justin@box:/tmp/f$ git-annex add .
+ add motd (checksum...) ok
+ (Recording state in git...)
+ justin@box:/tmp/f$ git-annex fsck
+ fsck motd (checksum...) ok
+ justin@box:/tmp/f$ chmod +w motd
+ justin@box:/tmp/f$ echo hi >> motd
+ justin@box:/tmp/f$ git-annex fsck
+ fsck motd
+ Bad file size (3 B larger); moved to /tmp/f/.git/annex/bad/SHA256-s354--2e724dde1a5dc33bc15580b2aef1ee541ca8047d746fff9bb7917062b871c0bf
+
+ ** No known copies exist of motd
+ failed
+ (Recording state in git...)
+ git-annex: fsck: 1 failed
+
+
+You can also use fsck -q which will only show errors.
+
+"""]]
diff --git a/doc/forum/How_does_one_change_git-annex_assistant__39__s_web_browser__63__.mdwn b/doc/forum/How_does_one_change_git-annex_assistant__39__s_web_browser__63__.mdwn
new file mode 100644
index 000000000..a2ac090ad
--- /dev/null
+++ b/doc/forum/How_does_one_change_git-annex_assistant__39__s_web_browser__63__.mdwn
@@ -0,0 +1,7 @@
+When starting git-annex assistant with:
+
+ git-annex webapp
+
+an unwanted web browser is opened.
+
+How does one change the web browser with which the web interface is displayed?
diff --git a/doc/forum/How_does_one_change_git-annex_assistant__39__s_web_browser__63__/comment_1_f4402eabda2327da3a0bbc64ed3baf9a._comment b/doc/forum/How_does_one_change_git-annex_assistant__39__s_web_browser__63__/comment_1_f4402eabda2327da3a0bbc64ed3baf9a._comment
new file mode 100644
index 000000000..6369dbd0b
--- /dev/null
+++ b/doc/forum/How_does_one_change_git-annex_assistant__39__s_web_browser__63__/comment_1_f4402eabda2327da3a0bbc64ed3baf9a._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.60"
+ subject="comment 1"
+ date="2012-09-17T15:32:07Z"
+ content="""
+The web browser is started by running the `xdg-open` program (or just `open` on Mac OS X).
+
+xdg-open, in turn, runs the desktop environment's kde-open, gvfs-open, exo-open. Which browser these run is configured in the desktop environment's settings. Which is my goal for the web app; it should open the same browser that other applications in the desktop use.
+
+When there's no desktop environment in use, xdg-open falls back to some default browser, or to what's configured by the BROWSER environment variable.
+"""]]
diff --git a/doc/forum/How_does_one_change_git-annex_assistant__39__s_web_browser__63__/comment_2_cdb41f2c7b6bc5bf40d88582dcbf45aa._comment b/doc/forum/How_does_one_change_git-annex_assistant__39__s_web_browser__63__/comment_2_cdb41f2c7b6bc5bf40d88582dcbf45aa._comment
new file mode 100644
index 000000000..ce626fa9f
--- /dev/null
+++ b/doc/forum/How_does_one_change_git-annex_assistant__39__s_web_browser__63__/comment_2_cdb41f2c7b6bc5bf40d88582dcbf45aa._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlZvtBCVyJw4O71OPsdwGpVh6iJ1W-xaPc"
+ nickname="Kilian"
+ subject="comment 2"
+ date="2012-10-11T21:56:26Z"
+ content="""
+On my Ubuntu 10.04 machine, ./git-annex-webapp starts Firefox whereas xdg-open starts my configured standard browser, Chrome.
+
+-ke
+"""]]
diff --git a/doc/forum/How_does_one_change_git-annex_assistant__39__s_web_browser__63__/comment_3_ca75e928c245eb23a02b5f40ec69cbb1._comment b/doc/forum/How_does_one_change_git-annex_assistant__39__s_web_browser__63__/comment_3_ca75e928c245eb23a02b5f40ec69cbb1._comment
new file mode 100644
index 000000000..b2b605492
--- /dev/null
+++ b/doc/forum/How_does_one_change_git-annex_assistant__39__s_web_browser__63__/comment_3_ca75e928c245eb23a02b5f40ec69cbb1._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.8"
+ subject="comment 3"
+ date="2012-10-11T23:41:36Z"
+ content="""
+Recently the webapp has started honoring git's web.browser setting, so if that's set in ~/.gitconfig, it'll use a different browser than xdg-open does.
+"""]]
diff --git a/doc/forum/How_does_one_change_git-annex_assistant__39__s_web_browser__63__/comment_4_1635f136909711295b9b70d1255e0378._comment b/doc/forum/How_does_one_change_git-annex_assistant__39__s_web_browser__63__/comment_4_1635f136909711295b9b70d1255e0378._comment
new file mode 100644
index 000000000..e6d12ca5d
--- /dev/null
+++ b/doc/forum/How_does_one_change_git-annex_assistant__39__s_web_browser__63__/comment_4_1635f136909711295b9b70d1255e0378._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnBJ6Dv1glxzzi4qIzGFNa6F-mfHIvv9Ck"
+ nickname="Jim"
+ subject="Doesn't use the configured web browser app..."
+ date="2012-12-04T23:10:43Z"
+ content="""
+On my system, `xdg-open http://google.com/` opens firefox as desired, but `xdg-open file:///tmp/foo.html` tries to load **wine**!
+I'm using xfce, and it seems like exo-open is noticing the `file://` URL, finding the mime type, and looking it up in `~/.local/share/applications/wine-extension-html.desktop`, which was (annoyingly) created by wine. Deleting those files fixes it.
+
+Not sure how you'd make this better. Maybe give xdg-open a URL like `http://localhost:54896/?authfile=...` that redirects to `file:///tmp/webapp12345.html` that redirects to `http://localhost:54896/?auth=...` ?
+"""]]
diff --git a/doc/forum/How_does_one_change_git-annex_assistant__39__s_web_browser__63__/comment_5_ee0cbe9498c518de98480a2ad229f685._comment b/doc/forum/How_does_one_change_git-annex_assistant__39__s_web_browser__63__/comment_5_ee0cbe9498c518de98480a2ad229f685._comment
new file mode 100644
index 000000000..8dc9d74ec
--- /dev/null
+++ b/doc/forum/How_does_one_change_git-annex_assistant__39__s_web_browser__63__/comment_5_ee0cbe9498c518de98480a2ad229f685._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.72"
+ subject="comment 5"
+ date="2012-12-05T01:21:03Z"
+ content="""
+@Jim, that would be a good technique.. except many browsers prohibit redirecting to file:// urls.
+
+
+"""]]
diff --git a/doc/forum/How_does_one_change_git-annex_assistant__39__s_web_browser__63__/comment_6_799b9d9d3ffbc2c14eca8d442e2aff8c._comment b/doc/forum/How_does_one_change_git-annex_assistant__39__s_web_browser__63__/comment_6_799b9d9d3ffbc2c14eca8d442e2aff8c._comment
new file mode 100644
index 000000000..767426fef
--- /dev/null
+++ b/doc/forum/How_does_one_change_git-annex_assistant__39__s_web_browser__63__/comment_6_799b9d9d3ffbc2c14eca8d442e2aff8c._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnZEanlyzay_QlEAL0CWpyZcRTyN7vay8U"
+ nickname="Carlo"
+ subject="comment 6"
+ date="2013-11-15T13:43:06Z"
+ content="""
+Since git web--browse defaults to firefox on my system (Ubuntu/XMonad), I did this on Ubuntu to get the system default browser.
+
+ git config --global web.browser xdg-open
+
+"""]]
diff --git a/doc/forum/How_to_cancel_an_add__63__.mdwn b/doc/forum/How_to_cancel_an_add__63__.mdwn
new file mode 100644
index 000000000..e0b0f1c8f
--- /dev/null
+++ b/doc/forum/How_to_cancel_an_add__63__.mdwn
@@ -0,0 +1,5 @@
+What is the safest way to cancel a `git annex add` before the first commit?
+
+Say I first added a directory with a lot of small files to the annex and then (while watching the endless list of checksum operations) decide I should actually put them in a tar file and annex that instead.
+
+The problem seems to be that `git annex add` immediately replaces the files with symlinks instead of waiting for a commit, so I can't just `git reset largedir/; tar cvfz largedir.tgz largedir/; git annex add largedir.tgz`.
diff --git a/doc/forum/How_to_cancel_an_add__63__/comment_1_f768ce5dc7c76f96ee6eb352f167be44._comment b/doc/forum/How_to_cancel_an_add__63__/comment_1_f768ce5dc7c76f96ee6eb352f167be44._comment
new file mode 100644
index 000000000..cef938469
--- /dev/null
+++ b/doc/forum/How_to_cancel_an_add__63__/comment_1_f768ce5dc7c76f96ee6eb352f167be44._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 1"
+ date="2013-11-03T00:50:48Z"
+ content="""
+Run `git annex unannex` on the files.
+"""]]
diff --git a/doc/forum/How_to_copy__47__duplicate_all_data_from_rsync__47__ssh_backend_to_other_backend__63__.mdwn b/doc/forum/How_to_copy__47__duplicate_all_data_from_rsync__47__ssh_backend_to_other_backend__63__.mdwn
new file mode 100644
index 000000000..0e72582d3
--- /dev/null
+++ b/doc/forum/How_to_copy__47__duplicate_all_data_from_rsync__47__ssh_backend_to_other_backend__63__.mdwn
@@ -0,0 +1,14 @@
+Hello,
+
+I want to be safe and have two copies of my files on two different backend. Currently I only have a SSH backend, that stores all my data. I have full(root) access to that machine/backend. On my laptop I have only a few bytes of data, because all is moved/copied to that SSH backend. Now, I want to duplicate the data on the SSH backend to a Google Drive account (or any other). How could I do that (without downloading all data from the SSH backend)??? Encryption is not a must.
+
+I looked into the annex/objects folder on the SSH backend, but there are 3 char length directories compared to what I see on a test Google Drive backend, where only 2 char length directory names are.
+
+Example SSH backend: [git-annex root]/annex/objects/c10/90a/SHA256E-s445227--14c3f85d6dd3464f116f6a5bbd411012781d36794549d136b18d1914c4158820.jpg/SHA256E-s445227--14c3f85d6dd3464f116f6a5bbd411012781d36794549d136b18d1914c4158820.jpg
+
+Example Google Drive: [Google Drive root]/annex/W7/xQ/SHA256E-s913904--29f9800b0dd34d4200c4e9ee152b79c3556a9a473848720be7cf83d20eff65a4.JPG
+
+Is there a way to convert these directory names and do a simpe copy???
+
+Thank you,
+Bence
diff --git a/doc/forum/How_to_copy__47__duplicate_all_data_from_rsync__47__ssh_backend_to_other_backend__63__/comment_1_7973928b1aa9e0fcfeb6bf80885441f5._comment b/doc/forum/How_to_copy__47__duplicate_all_data_from_rsync__47__ssh_backend_to_other_backend__63__/comment_1_7973928b1aa9e0fcfeb6bf80885441f5._comment
new file mode 100644
index 000000000..3c7d07258
--- /dev/null
+++ b/doc/forum/How_to_copy__47__duplicate_all_data_from_rsync__47__ssh_backend_to_other_backend__63__/comment_1_7973928b1aa9e0fcfeb6bf80885441f5._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.251.174"
+ subject="comment 1"
+ date="2013-09-07T17:11:03Z"
+ content="""
+Just run `git annex copy --all --to remote`
+
+(Needs git-annex 4.20130709 or newer.)
+"""]]
diff --git a/doc/forum/How_to_deal_with_renamed_files_in_direct_mode__63__.mdwn b/doc/forum/How_to_deal_with_renamed_files_in_direct_mode__63__.mdwn
new file mode 100644
index 000000000..576d598dd
--- /dev/null
+++ b/doc/forum/How_to_deal_with_renamed_files_in_direct_mode__63__.mdwn
@@ -0,0 +1,3 @@
+I use git annex in direct mode and I have renamed a file. What should I do to make git annex understand that the file has just been renamed and not deleted/added?
+
+The file I renamed is quite big and I would like to avoid having to copy it again to the remotes and I would also like to avoid having to redownload it again in all the repositories.
diff --git a/doc/forum/How_to_deal_with_renamed_files_in_direct_mode__63__/comment_1_fe38fedbbc9e4a9e13bf19950e63c7ac._comment b/doc/forum/How_to_deal_with_renamed_files_in_direct_mode__63__/comment_1_fe38fedbbc9e4a9e13bf19950e63c7ac._comment
new file mode 100644
index 000000000..6f452acb8
--- /dev/null
+++ b/doc/forum/How_to_deal_with_renamed_files_in_direct_mode__63__/comment_1_fe38fedbbc9e4a9e13bf19950e63c7ac._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.254.222"
+ subject="comment 1"
+ date="2013-07-07T17:14:18Z"
+ content="""
+You don't have to do anything special, git-annex automatically detects when a file has been renamed.
+
+Just `git annex` add the new file, and commit and sync like usual.
+"""]]
diff --git a/doc/forum/How_to_define_an_alternative_remote_url_for_a_git_remote_repository__63__.mdwn b/doc/forum/How_to_define_an_alternative_remote_url_for_a_git_remote_repository__63__.mdwn
new file mode 100644
index 000000000..7b8e1a0ba
--- /dev/null
+++ b/doc/forum/How_to_define_an_alternative_remote_url_for_a_git_remote_repository__63__.mdwn
@@ -0,0 +1,7 @@
+I'm using git-annex to manage my files. Some of my remotes are available using 2 or 3 methods, for example ssh and nfs, but the nfs access is only possible on my local network, of course. Then, git-annex chooses the fastest method to sync or get the files (nfs, if available, ssh instead, using scores to choose). For now, I define a remote per repository and per access method (example: server-by-ssh, server-by-nfs), but that's not a really git-annex way to do the job, as it is not compliant with the numcopies option, which ckecks that the files in the annex are kept with enough replications (with my current method, many remotes are in fact the same folders on a hard drive).
+
+Then, my question applies to both git and git-annex, since the remotes are added in git, not git-annex: I wonder if it is possible to define alternative url for a given remote.
+
+I have tried to use the git remote set --url --add command, but it doesn't really work as I would expect. Indeed, if the nfs url is not reachable, git hangs up and waits.
+
+Any idea?
diff --git a/doc/forum/How_to_define_an_alternative_remote_url_for_a_git_remote_repository__63__/comment_1_52918b5ec25e55837215439fe1bb1a14._comment b/doc/forum/How_to_define_an_alternative_remote_url_for_a_git_remote_repository__63__/comment_1_52918b5ec25e55837215439fe1bb1a14._comment
new file mode 100644
index 000000000..5bafa57d9
--- /dev/null
+++ b/doc/forum/How_to_define_an_alternative_remote_url_for_a_git_remote_repository__63__/comment_1_52918b5ec25e55837215439fe1bb1a14._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="comment 1"
+ date="2012-08-21T12:42:16Z"
+ content="""
+I don't think having multiple remotes for the same repository confuses git-annex since it uses the UUID not the url to identify them.
+"""]]
diff --git a/doc/forum/How_to_define_an_alternative_remote_url_for_a_git_remote_repository__63__/comment_2_3a1567c9f484b5e12e5560cdcc2cfddd._comment b/doc/forum/How_to_define_an_alternative_remote_url_for_a_git_remote_repository__63__/comment_2_3a1567c9f484b5e12e5560cdcc2cfddd._comment
new file mode 100644
index 000000000..859804678
--- /dev/null
+++ b/doc/forum/How_to_define_an_alternative_remote_url_for_a_git_remote_repository__63__/comment_2_3a1567c9f484b5e12e5560cdcc2cfddd._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.29"
+ subject="Justin is right"
+ date="2012-08-21T15:57:46Z"
+ content="""
+git-annex doesn't care how many git remotes you have pointing to a given repo, that repo's uuid still only counts as one copy.
+"""]]
diff --git a/doc/forum/How_to_define_an_alternative_remote_url_for_a_git_remote_repository__63__/comment_3_48c3a80c14a85f27d742482b2ccbe628._comment b/doc/forum/How_to_define_an_alternative_remote_url_for_a_git_remote_repository__63__/comment_3_48c3a80c14a85f27d742482b2ccbe628._comment
new file mode 100644
index 000000000..7a0054c49
--- /dev/null
+++ b/doc/forum/How_to_define_an_alternative_remote_url_for_a_git_remote_repository__63__/comment_3_48c3a80c14a85f27d742482b2ccbe628._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/speredenn#aaf38"
+ nickname="Jean-Baptiste Carré"
+ subject="comment 3"
+ date="2012-08-21T18:15:48Z"
+ content="""
+You're totally right: The UUIDs are the same. So it shouldn't matter if there are many repositories pointing to the same folder, as you state it. Thanks a lot!
+"""]]
diff --git a/doc/forum/How_to_delete_a_remote__63__.mdwn b/doc/forum/How_to_delete_a_remote__63__.mdwn
new file mode 100644
index 000000000..6aebaf5f5
--- /dev/null
+++ b/doc/forum/How_to_delete_a_remote__63__.mdwn
@@ -0,0 +1 @@
+I have a repository with an S3 remote named `cloud`. I now no longer want to use that remote. I've dropped all the data from it (`git annex drop . --from cloud`). How do I tell my repository to forget about the remote?
diff --git a/doc/forum/How_to_delete_a_remote__63__/comment_1_8cba186bb67079ff41bf6d0b04613f4a._comment b/doc/forum/How_to_delete_a_remote__63__/comment_1_8cba186bb67079ff41bf6d0b04613f4a._comment
new file mode 100644
index 000000000..e60eb3d5d
--- /dev/null
+++ b/doc/forum/How_to_delete_a_remote__63__/comment_1_8cba186bb67079ff41bf6d0b04613f4a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnldTTAP8PAifJUmqhRar6RAWNWlRcencw"
+ nickname="Marco"
+ subject="You can set the trust to &quot;dead&quot;"
+ date="2013-01-23T19:02:22Z"
+ content="""
+Simple answer: You can't fully delete a remote - with annex commands. You can mark it as dead.
+
+You can give this a try as a workaround: [[Truly_purging_dead_repositories/#comment-51ab797094f4c07bf5327fd21cad5835]]
+"""]]
diff --git a/doc/forum/How_to_delete_a_remote__63__/comment_2_33c429ffa7e9e2ed9c5fac760ee8e82c._comment b/doc/forum/How_to_delete_a_remote__63__/comment_2_33c429ffa7e9e2ed9c5fac760ee8e82c._comment
new file mode 100644
index 000000000..2866710c8
--- /dev/null
+++ b/doc/forum/How_to_delete_a_remote__63__/comment_2_33c429ffa7e9e2ed9c5fac760ee8e82c._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4830:1600:187::2"
+ subject="comment 2"
+ date="2013-09-04T06:43:26Z"
+ content="""
+Recently git-annex has gotten the ability to do this: `git annex forget --drop-dead`
+
+That prunes all history relating to all dead remotes. You need to be running a git-annex that supports this on all computers you use the repos on, or the pruned history will get merged back in.
+
+I don't recommend doing this just because you want to \"clean history\". Think of it as something you can do at some point in the future if the .git/objects somehow gets too large or too slow. Put off deleting data until tomorrow if you don't absolutely need to do it today.
+"""]]
diff --git a/doc/forum/How_to_delete_a_remote__63__/comment_3_e9c5508092ca2983f458b16bf1e07082._comment b/doc/forum/How_to_delete_a_remote__63__/comment_3_e9c5508092ca2983f458b16bf1e07082._comment
new file mode 100644
index 000000000..337ef2efe
--- /dev/null
+++ b/doc/forum/How_to_delete_a_remote__63__/comment_3_e9c5508092ca2983f458b16bf1e07082._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="konubinix"
+ ip="82.243.233.186"
+ subject="Dropping dead repositories"
+ date="2013-09-04T07:40:22Z"
+ content="""
+Actually, it may be a good idea to remove repositories made for tests purposes.
+
+I now have 2 dead repositories that are USB_test1 and USB_test2 that I created before knowing I could reuse the annex uuid.
+
+They are now there and it is difficult to remove them.
+
+For that special case, the --drop-dead feature is very welcome.
+"""]]
diff --git a/doc/forum/How_to_destroy_a_master_annex_and_all_remotes_with_git_annex_assistant_and_ext4.mdwn b/doc/forum/How_to_destroy_a_master_annex_and_all_remotes_with_git_annex_assistant_and_ext4.mdwn
new file mode 100644
index 000000000..c67d4e77f
--- /dev/null
+++ b/doc/forum/How_to_destroy_a_master_annex_and_all_remotes_with_git_annex_assistant_and_ext4.mdwn
@@ -0,0 +1,28 @@
+Git annex is really amazing software, and this cute little scenario is actually Linux's fault. But it's a nasty situation nonetheless, and worth passing on.
+
+...
+
+Create a client repository on your laptop and two backup repositories on external USB drives. Keep all repositories mounted and connected. Now drop 60GB of data spread over 30,000 files into your annex, and watch git annex assistant start adding and syncing. So far, so good.
+
+Now wait a few hours, and watch some kernel crypto code—probably ecryptfs—fall over with a segfault.
+
+Since your laptop and USB drives are all running ext4, the sudden kernel panic will leave you with hundreds of 0-length files. Because git annex assistant was busily adding and syncing files, those 0-length files are spread randomly throughout all your git repositories (typically in `.git/objects`) and throughout all the associated annexes. Unfortunately, because `git annex assistant` generates _tons_ of commits, this is pretty much unrecoverable using standard git tools unless you're willing to get deep into the repositories' internals.
+
+So what should you do, if you want to add 10s of 1000s of files and there's some risk of kernel panic or accidentally bumping a USB cable? Here's my recommendation to limit the damage:
+
+1. Use the command line if possible.
+2. Add all your files with your remotes offline.
+3. Run `git gc` on your central repository, just on general principals.
+4. Mount one repository at a time.
+5. Sync the pure git data first, and then make sure that all disk I/O is flushed (`sync; sleep 10` is a good approximation).
+6. Use `git annex copy --to` to move the annex data.
+7. Unmount the USB repository cleanly and move onto the next one.
+
+If you _do_ bump a USB cable in the middle of step (6), then:
+
+1. Run 'git annex fsck' to clean up any garbage files.
+2. Try another 'git annex copy --to' where you left off.
+
+Wiser minds than I are encouraged to suggest optimizations for the recovery steps.
+
+The theory behind these steps is to only do one thing at a time, and to expose as few remotes as possible to a power failure or crash. A secondary goal is to make sure that pure git operations complete very quickly, limiting the risk that they will be interrupted, because they're the hardest operations to recover from after a crash.
diff --git a/doc/forum/How_to_destroy_a_master_annex_and_all_remotes_with_git_annex_assistant_and_ext4/comment_1_42ca6cfbbb79fe63514805b8119ac16b._comment b/doc/forum/How_to_destroy_a_master_annex_and_all_remotes_with_git_annex_assistant_and_ext4/comment_1_42ca6cfbbb79fe63514805b8119ac16b._comment
new file mode 100644
index 000000000..f6d8396b7
--- /dev/null
+++ b/doc/forum/How_to_destroy_a_master_annex_and_all_remotes_with_git_annex_assistant_and_ext4/comment_1_42ca6cfbbb79fe63514805b8119ac16b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 1"
+ date="2013-07-23T14:45:05Z"
+ content="""
+It seems to me that it would be better to avoid using kernel features that crash. And, set up a git repository on another machine, which will serve as a real backup if something goes catostrophically wrong. The only potential failure mode then would be if a kernel/hardware issue zeroed some of your files, in direct mode the assistant might commit those new corrupt files and ship them over to the backup. But, if your offsite backup is accumulating old versions of files, you can recover from this by reverting the bad commit.
+"""]]
diff --git a/doc/forum/How_to_destroy_a_master_annex_and_all_remotes_with_git_annex_assistant_and_ext4/comment_2_c94ce6a9767c624e2445a7d9eea40396._comment b/doc/forum/How_to_destroy_a_master_annex_and_all_remotes_with_git_annex_assistant_and_ext4/comment_2_c94ce6a9767c624e2445a7d9eea40396._comment
new file mode 100644
index 000000000..347a95539
--- /dev/null
+++ b/doc/forum/How_to_destroy_a_master_annex_and_all_remotes_with_git_annex_assistant_and_ext4/comment_2_c94ce6a9767c624e2445a7d9eea40396._comment
@@ -0,0 +1,29 @@
+[[!comment format=mdwn
+ username="http://emk.myopenid.com/"
+ ip="24.2.150.84"
+ subject="Well, this is the first time it ever panicked"
+ date="2013-07-23T16:32:10Z"
+ content="""
+Well, it's not like my machine kernel panics on a regular basis or anything. :-) This is the first time I ever saw the kernel encryption code do this. I'm running a boring stock install of Ubuntu 12.04 LTS that was preloaded by ZaReason, and I'm using the ecryptfs home directory encryption supplied by Ubuntu. So in this case, \"stop using kernel features that crash\" means \"stop using Ubuntu on supported hardware.\"
+
+The underlying problem is that ext4 allocates file contents lazily and out-of-order, and it may wait a surprisingly long time before actually flushing data to disk:
+
+https://bugs.launchpad.net/ubuntu/+source/linux/+bug/317781
+http://linux.bihlman.com/2010/learn-linux-help/how-to-solve-zero-length-file-problem-in-linuxs-ext4-file-system/
+
+The problem is that `git annex assistant` and `git` don't sync the disks all that often, and that the assistant can generate huge amounts of complicated disk I/O across multiple volumes for hours on end. All you need to do is go through the walkthrough, create the specified repositories including one on a USB drive, and throw 50GB of data into the annex directory. `git annex assistant` will happily grind away overnight, and it anything prevents ext4 from flushing data, there's a good chance you'll wind up with multiple corrupted repositories with hundreds of `git fsck` errors.
+
+There are some potential workarounds:
+
+1. Reconfigure ext4 to run in data write-back mode. This isn't really possible for non-technical users, but it's an excellent idea for large external USB drives.
+2. Somehow convince `git` and `git annex assistant` to call `sync` or `fsync` more aggressively on local volumes.
+3. Use a remote server for at least one remote, as you suggested.
+4. Operate on the repository manually, so that you can ensure that `git`'s data is in a known-good state before trying to copy the annex files. The
+annex files are much easier to recover than git's state.
+
+Anyway, I doubt this is really fixable. And it's not really `git annex`'s fault, in any case. But I'm really glad I had recent backups of all my data last night, which allowed me to checksum everything and start from scratch.
+
+...
+
+Leaving aside this incident, `git annex` is one of the nicest pieces of open source software I've seen in a long time, and it's clearly going to change how I use my computer. And thank you for posting the crowd-funding campaign so we can say \"Thanks!\"
+"""]]
diff --git a/doc/forum/How_to_destroy_a_master_annex_and_all_remotes_with_git_annex_assistant_and_ext4/comment_3_bcda51053b62bbb20ce71a59469e1b26._comment b/doc/forum/How_to_destroy_a_master_annex_and_all_remotes_with_git_annex_assistant_and_ext4/comment_3_bcda51053b62bbb20ce71a59469e1b26._comment
new file mode 100644
index 000000000..5cf8c93f3
--- /dev/null
+++ b/doc/forum/How_to_destroy_a_master_annex_and_all_remotes_with_git_annex_assistant_and_ext4/comment_3_bcda51053b62bbb20ce71a59469e1b26._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 3"
+ date="2013-07-23T17:17:43Z"
+ content="""
+`git config core.fsyncobjectfiles true`
+
+This will make git fsync all the data it writes. Whether it's a good default, I don't know.
+"""]]
diff --git a/doc/forum/How_to_destroy_a_master_annex_and_all_remotes_with_git_annex_assistant_and_ext4/comment_4_48e5b9eae920e5f13812de8d6f6bc640._comment b/doc/forum/How_to_destroy_a_master_annex_and_all_remotes_with_git_annex_assistant_and_ext4/comment_4_48e5b9eae920e5f13812de8d6f6bc640._comment
new file mode 100644
index 000000000..2bac2ca1b
--- /dev/null
+++ b/doc/forum/How_to_destroy_a_master_annex_and_all_remotes_with_git_annex_assistant_and_ext4/comment_4_48e5b9eae920e5f13812de8d6f6bc640._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 4"
+ date="2013-07-23T17:38:50Z"
+ content="""
+I have made the assistant enable the fsync option when it creates a repository on a removable drive. That is, at least in my experience, the thing that most likely needs it. I don't know if it would have saved you in your situation or not.
+"""]]
diff --git a/doc/forum/How_to_destroy_a_master_annex_and_all_remotes_with_git_annex_assistant_and_ext4/comment_5_787c0bfdc1d309db1486c3a37723a957._comment b/doc/forum/How_to_destroy_a_master_annex_and_all_remotes_with_git_annex_assistant_and_ext4/comment_5_787c0bfdc1d309db1486c3a37723a957._comment
new file mode 100644
index 000000000..dd40495ca
--- /dev/null
+++ b/doc/forum/How_to_destroy_a_master_annex_and_all_remotes_with_git_annex_assistant_and_ext4/comment_5_787c0bfdc1d309db1486c3a37723a957._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmkBwMWvNKZZCge_YqobCSILPMeK6xbFw8"
+ nickname="develop"
+ subject="comment 5"
+ date="2013-07-23T17:39:42Z"
+ content="""
+Oh i've had that type of crash from ecryptfs many times over many different versions of Ubuntu, also before i even encountered git-annex.
+
+Git-annex might provoke this issue, but it is by no means the only thing that can crash your system when running ecryptfs.
+
+I highly suggest you try LUKS for a stable experience.
+
+"""]]
diff --git a/doc/forum/How_to_destroy_a_master_annex_and_all_remotes_with_git_annex_assistant_and_ext4/comment_6_8894beb06443f234e9200b03b5f3badf._comment b/doc/forum/How_to_destroy_a_master_annex_and_all_remotes_with_git_annex_assistant_and_ext4/comment_6_8894beb06443f234e9200b03b5f3badf._comment
new file mode 100644
index 000000000..149998aaf
--- /dev/null
+++ b/doc/forum/How_to_destroy_a_master_annex_and_all_remotes_with_git_annex_assistant_and_ext4/comment_6_8894beb06443f234e9200b03b5f3badf._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 6"
+ date="2013-07-23T17:54:00Z"
+ content="""
+If there's an easy way to detect when a directory is inside an ecryptfs volume, I'd be happy to make the assistant automatically enable fsync on it. ;)
+"""]]
diff --git a/doc/forum/How_to_destroy_a_master_annex_and_all_remotes_with_git_annex_assistant_and_ext4/comment_7_457f62ee3e58f68a55f66c5bde6002fd._comment b/doc/forum/How_to_destroy_a_master_annex_and_all_remotes_with_git_annex_assistant_and_ext4/comment_7_457f62ee3e58f68a55f66c5bde6002fd._comment
new file mode 100644
index 000000000..8f545e2eb
--- /dev/null
+++ b/doc/forum/How_to_destroy_a_master_annex_and_all_remotes_with_git_annex_assistant_and_ext4/comment_7_457f62ee3e58f68a55f66c5bde6002fd._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://emk.myopenid.com/"
+ ip="24.2.150.84"
+ subject="Thank you!"
+ date="2013-07-23T18:36:22Z"
+ content="""
+What good idea! I've turned on `core.fsyncobjectfiles`. This should definitely help avoid the worst damage when ext4 filesystems get unmounted while dirty. Thank you very much for addressing this issue so quickly, even if though has more to do with ext4 than git annex.
+
+develop: Thank you for the suggestion to use LUKS; that's good to know.
+"""]]
diff --git a/doc/forum/How_to_destroy_a_master_annex_and_all_remotes_with_git_annex_assistant_and_ext4/comment_8_bd2b412116a66107bc0ff0efd7e39a58._comment b/doc/forum/How_to_destroy_a_master_annex_and_all_remotes_with_git_annex_assistant_and_ext4/comment_8_bd2b412116a66107bc0ff0efd7e39a58._comment
new file mode 100644
index 000000000..0d09a9652
--- /dev/null
+++ b/doc/forum/How_to_destroy_a_master_annex_and_all_remotes_with_git_annex_assistant_and_ext4/comment_8_bd2b412116a66107bc0ff0efd7e39a58._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://emk.myopenid.com/"
+ ip="24.2.150.84"
+ subject="Detecting ecryptfs"
+ date="2013-07-23T18:49:08Z"
+ content="""
+If the string `\" ecryptfs \"` (with surrounding spaces) appears in `/etc/mtab`, then there's at least one ecryptfs volume on the system. More specific parsing will tell you where it's mounted.
+
+Ubuntu released a new kernels fixing the worst ecryptfs bugs in 12.04 LTS. The current version is OK, but perhaps not exactly great. Some older versions are public menaces with awful data corruption bugs.
+"""]]
diff --git a/doc/forum/How_to_expire_old_versions_of_files_that_have_been_edited__63__.mdwn b/doc/forum/How_to_expire_old_versions_of_files_that_have_been_edited__63__.mdwn
new file mode 100644
index 000000000..f06135c24
--- /dev/null
+++ b/doc/forum/How_to_expire_old_versions_of_files_that_have_been_edited__63__.mdwn
@@ -0,0 +1,7 @@
+My annex contains several large files that I have unlocked, edited, and committed again, i.e. the annex contains the version history of those files. However, I don't want the history -- keeping the latest version is good enough for me. Running `git annex unused` won't detect those old versions, though, because they aren't unused as old Git revisions still refer to them. So I wonder:
+
+1. What is the best way to get rid of the old versions of files in the annex?
+
+2. What is the best way to detect old versions of files in the annex?
+
+I guess, I could run `git rebase -i` to squash commits to those files into one commit, thereby getting rid of the references to the old copies, but that approach feels awkward and error prone. Is anyone aware of a better way?
diff --git a/doc/forum/How_to_expire_old_versions_of_files_that_have_been_edited__63__/comment_1_dccf4dc4483d08e5e2936b2cadeafeaf._comment b/doc/forum/How_to_expire_old_versions_of_files_that_have_been_edited__63__/comment_1_dccf4dc4483d08e5e2936b2cadeafeaf._comment
new file mode 100644
index 000000000..ee4fe2e6c
--- /dev/null
+++ b/doc/forum/How_to_expire_old_versions_of_files_that_have_been_edited__63__/comment_1_dccf4dc4483d08e5e2936b2cadeafeaf._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://peter-simons.myopenid.com/"
+ ip="77.186.179.173"
+ subject="comment 1"
+ date="2012-02-09T18:53:00Z"
+ content="""
+Sorry for commmenting on my own question ... I think I just figured out that `git annex unused` *does* in fact do what I want. When I tried it, it just didn't show the obsolete versions of the files I edited because I hadn't yet synchronized all repositories, so that was why the obsolete versions were still considered used.
+"""]]
diff --git a/doc/forum/How_to_expire_old_versions_of_files_that_have_been_edited__63__/comment_2_5710294c1c8652c12b6df2233255a45e._comment b/doc/forum/How_to_expire_old_versions_of_files_that_have_been_edited__63__/comment_2_5710294c1c8652c12b6df2233255a45e._comment
new file mode 100644
index 000000000..576093a87
--- /dev/null
+++ b/doc/forum/How_to_expire_old_versions_of_files_that_have_been_edited__63__/comment_2_5710294c1c8652c12b6df2233255a45e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 2"
+ date="2012-02-09T19:42:28Z"
+ content="""
+Yes, contents are still considered used while tags or refs refer to them. Including remote tracking branches like `remotes/origin/master`
+"""]]
diff --git a/doc/forum/How_to_handle_the_git-annex_branch__63__.mdwn b/doc/forum/How_to_handle_the_git-annex_branch__63__.mdwn
new file mode 100644
index 000000000..49c732e22
--- /dev/null
+++ b/doc/forum/How_to_handle_the_git-annex_branch__63__.mdwn
@@ -0,0 +1,5 @@
+Hi!
+
+When I update one repository to/from another, am I to push/pull only the master branch (and other branches I'd have created myself) or also the git-annex branch?
+
+From what I understand, the git-annex branch is local to one repository and has no interest in being merged in another, but some examples make use of git pull --all (which merges distant git-annex branch into local).
diff --git a/doc/forum/How_to_handle_the_git-annex_branch__63__/comment_1_800bd55b322e72f229882d7fd3888b14._comment b/doc/forum/How_to_handle_the_git-annex_branch__63__/comment_1_800bd55b322e72f229882d7fd3888b14._comment
new file mode 100644
index 000000000..6c5a5144f
--- /dev/null
+++ b/doc/forum/How_to_handle_the_git-annex_branch__63__/comment_1_800bd55b322e72f229882d7fd3888b14._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2012-04-10T16:05:40Z"
+ content="""
+The git-annex branch is how the annex information for the different repositories is communicated around, so yes, you need to push/pull it.
+"""]]
diff --git a/doc/forum/How_to_make_Maven_releases_work_with_git_annex___63__.mdwn b/doc/forum/How_to_make_Maven_releases_work_with_git_annex___63__.mdwn
new file mode 100644
index 000000000..b39e69d7b
--- /dev/null
+++ b/doc/forum/How_to_make_Maven_releases_work_with_git_annex___63__.mdwn
@@ -0,0 +1,5 @@
+Hi,
+
+In normal maven release procedure, it re-clones the gitrepo from the tag to do the release from either git or local file, But as git-annex uses symlinks when the repo is clones by maven, it misses the files. Any recommendations how i can make this work ?
+
+Also would love some data on who is using git-annex in production environment would be good.
diff --git a/doc/forum/How_to_make_Maven_releases_work_with_git_annex___63__/comment_1_9298aa55771b68873de02e6a7964bbdc._comment b/doc/forum/How_to_make_Maven_releases_work_with_git_annex___63__/comment_1_9298aa55771b68873de02e6a7964bbdc._comment
new file mode 100644
index 000000000..ca62bd43e
--- /dev/null
+++ b/doc/forum/How_to_make_Maven_releases_work_with_git_annex___63__/comment_1_9298aa55771b68873de02e6a7964bbdc._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.21"
+ subject="comment 1"
+ date="2013-07-30T18:20:53Z"
+ content="""
+If you can find a way to run `git annex get` in the cloned repo, it will copy over the files. Perhaps there is some way to make Maven do that via a hook script or similar?
+"""]]
diff --git a/doc/forum/How_to_prevent_the_assistant_from_downloading_all_data__63__.mdwn b/doc/forum/How_to_prevent_the_assistant_from_downloading_all_data__63__.mdwn
new file mode 100644
index 000000000..1b1ddff46
--- /dev/null
+++ b/doc/forum/How_to_prevent_the_assistant_from_downloading_all_data__63__.mdwn
@@ -0,0 +1,9 @@
+I have a repository on my laptop with a single remote on a USB drive. Both were created without the assistant.
+
+The remote holds all the content. My understanding is that this would be a "backup" repository, using the group definitions.
+
+The local repository generally holds no content. When I want a file, I make sure the remote is available, and then I `git annex get` it.
+
+This works fine in git annex, but I'm now experimenting with the assistant. As soon as I fire up the assistant, it starts downloading all of the data from the remote. I don't ever want it to automatically get any content from the remote. If it sees new content in the repository, I would like it to push that out to the remote. But never get anything from the remote, and never drop anything that is in the repository.
+
+How can I setup this behaviour in the assistant? I have set the remote's repository group to "backup". The local repository is not in any group, since none of the groups fit my model for this repo.
diff --git a/doc/forum/How_to_prevent_the_assistant_from_downloading_all_data__63__/comment_1_fd8b287758ad77b3527ae71017cffabf._comment b/doc/forum/How_to_prevent_the_assistant_from_downloading_all_data__63__/comment_1_fd8b287758ad77b3527ae71017cffabf._comment
new file mode 100644
index 000000000..326158d95
--- /dev/null
+++ b/doc/forum/How_to_prevent_the_assistant_from_downloading_all_data__63__/comment_1_fd8b287758ad77b3527ae71017cffabf._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn7gQ1zZDdWhXy9H51W2krZYShNmKL3qfM"
+ nickname="Karsten"
+ subject="comment 1"
+ date="2013-01-20T08:11:37Z"
+ content="""
+Run 'git annex vicfg', locate the preferred content setting for your repository, uncomment it and set it to 'present'. Then it shouldn't move content automatically.
+"""]]
diff --git a/doc/forum/How_to_prevent_the_assistant_from_downloading_all_data__63__/comment_2_e8e75b4451aaf55461edf2f3d68797ed._comment b/doc/forum/How_to_prevent_the_assistant_from_downloading_all_data__63__/comment_2_e8e75b4451aaf55461edf2f3d68797ed._comment
new file mode 100644
index 000000000..790567eca
--- /dev/null
+++ b/doc/forum/How_to_prevent_the_assistant_from_downloading_all_data__63__/comment_2_e8e75b4451aaf55461edf2f3d68797ed._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 2"
+ date="2013-01-24T02:01:00Z"
+ content="""
+A recent commit allows you to just choose \"manual mode\" in the webapp to get the same effect.
+"""]]
diff --git a/doc/forum/How_to_rename_a_remote__63__.mdwn b/doc/forum/How_to_rename_a_remote__63__.mdwn
new file mode 100644
index 000000000..be2355a07
--- /dev/null
+++ b/doc/forum/How_to_rename_a_remote__63__.mdwn
@@ -0,0 +1 @@
+I recently created WebDAV remote to my annex which I assumed to be just for testing purposes at the time, so I gave it a strange and long-wided name. It turned out, though, that the remote is stable, works fine, and that I'm going to keep it. Now, I would like to give it a snappier and more descriptive name than the one I originally chose. Is that possible somehow?
diff --git a/doc/forum/How_to_rename_a_remote__63__/comment_1_a9bfbd82f7bb47661f0d9e0e0d904332._comment b/doc/forum/How_to_rename_a_remote__63__/comment_1_a9bfbd82f7bb47661f0d9e0e0d904332._comment
new file mode 100644
index 000000000..31f44c8f6
--- /dev/null
+++ b/doc/forum/How_to_rename_a_remote__63__/comment_1_a9bfbd82f7bb47661f0d9e0e0d904332._comment
@@ -0,0 +1,28 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.3.194"
+ subject="comment 1"
+ date="2013-01-18T18:20:43Z"
+ content="""
+You can rename a git remote with just \"git remote rename <old> <new>\". However, for a special remote, git-remote will fail to rename it unless you first add a dummy remote.<name>.fetch value in .git/config. You can remove it later.
+
+So, for example:
+
+<pre>
+git config remote.$uglyname.fetch dummy
+git remote rename $uglyname $nicename
+git config remote.$nicename.fetch \"\"
+</pre>
+
+(The webapp handles doing this when you edit a remote's name, BTW.)
+
+---
+
+There's actually another place the name of a special remote is recorded, in `remote.log`. That name is only used when you use `git annex initremote` though. It actually is possible to change it, by using `initremote` to change the vale of the name field. Example:
+
+<pre>
+git annex initremote $uglyname name=$newname
+</pre>
+
+Note that for some types of special remotes, this will require you to re-specify some other configuration. For example, with a directory special remote, it wanted me to include a directory= parameter.
+"""]]
diff --git a/doc/forum/How_to_restore_symlinks.mdwn b/doc/forum/How_to_restore_symlinks.mdwn
new file mode 100644
index 000000000..30fb07001
--- /dev/null
+++ b/doc/forum/How_to_restore_symlinks.mdwn
@@ -0,0 +1 @@
+Somehow the symlinks have vanished from one directory of my repository. How can I restore them?
diff --git a/doc/forum/How_to_restore_symlinks/comment_1_c67e752cf7d5431096fab4b3304790a7._comment b/doc/forum/How_to_restore_symlinks/comment_1_c67e752cf7d5431096fab4b3304790a7._comment
new file mode 100644
index 000000000..d9e14dd16
--- /dev/null
+++ b/doc/forum/How_to_restore_symlinks/comment_1_c67e752cf7d5431096fab4b3304790a7._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnldTTAP8PAifJUmqhRar6RAWNWlRcencw"
+ nickname="Marco"
+ subject="git annex fix"
+ date="2012-11-24T08:51:19Z"
+ content="""
+You can try
+ git annex fix yourDirectory
+
+Hope that helps.
+"""]]
diff --git a/doc/forum/How_to_restore_symlinks/comment_2_f9ec6096595e2c149c48924e3b54542f._comment b/doc/forum/How_to_restore_symlinks/comment_2_f9ec6096595e2c149c48924e3b54542f._comment
new file mode 100644
index 000000000..689f32126
--- /dev/null
+++ b/doc/forum/How_to_restore_symlinks/comment_2_f9ec6096595e2c149c48924e3b54542f._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.49"
+ subject="comment 2"
+ date="2012-11-25T18:35:56Z"
+ content="""
+The key thing to realize is that the symlinks used by git-annex are checked into git like any other file would be. So you can use the entire git toolkit to manage them.
+
+For example, you could run `git status` to see if git shows them as recently deleted, and then use `git checkout $file` to restore the deleted files.
+
+Or perhaps the deletion has been committed to git, and then you'd use `git log --stat` to find the commit that deleted your files, and `git revert` could be used to undo it.
+
+(`git annex fix` is not related to this and won't help.)
+"""]]
diff --git a/doc/forum/How_to_restore_symlinks/comment_3_4ff80729787a2a4e2baf05dd1db37da3._comment b/doc/forum/How_to_restore_symlinks/comment_3_4ff80729787a2a4e2baf05dd1db37da3._comment
new file mode 100644
index 000000000..ce0be74b0
--- /dev/null
+++ b/doc/forum/How_to_restore_symlinks/comment_3_4ff80729787a2a4e2baf05dd1db37da3._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="jbee"
+ ip="178.25.68.205"
+ subject="Thanks"
+ date="2012-11-28T11:52:24Z"
+ content="""
+> deletion has been committed to git, and then you'd use git log --stat to find the commit that deleted your files, and git revert could be used to undo it.
+
+That did the trick.
+
+Thanks Joey, for the answer and the magnificence that is git-annex.
+"""]]
diff --git a/doc/forum/How_to_retroactively_annex_a_file_already_in_a_git_repo.mdwn b/doc/forum/How_to_retroactively_annex_a_file_already_in_a_git_repo.mdwn
new file mode 100644
index 000000000..981a53ba0
--- /dev/null
+++ b/doc/forum/How_to_retroactively_annex_a_file_already_in_a_git_repo.mdwn
@@ -0,0 +1,5 @@
+I worked out how to retroactively annex a large file that had been checked into a git repo some time ago. I thought this might be useful for others, so I am posting it here.
+
+> This is a great tip, so I've moved it to
+> [[tips|tips/How_to_retroactively_annex_a_file_already_in_a_git_repo]].
+> --[[Joey]]
diff --git a/doc/forum/How_to_set_up_two_assistants_with_one_shared_transfer_repository__63__.mdwn b/doc/forum/How_to_set_up_two_assistants_with_one_shared_transfer_repository__63__.mdwn
new file mode 100644
index 000000000..8ee5eeea5
--- /dev/null
+++ b/doc/forum/How_to_set_up_two_assistants_with_one_shared_transfer_repository__63__.mdwn
@@ -0,0 +1,15 @@
+This seems like something that should be completely obvious, but I've been trying to get it working for a while without success.
+
+I have a few machines (at least 3) at different locations. I want them all to be synced with a remote server that I have. I've installed git-annex on the server, and setting up the assistant on one of the machines, I can create the remote repository, and all seems to work (it spits out info about syncing... though I don't have any easy way of checking if it's working, as all I have is the one client).
+
+It says in the webapp that setting up a remote git repository in transfer mode will make it easy to have other clients. But I'm wondering how to set that up. I tried just adding the same server with the same path on another machine, but it doesn't seem to be syncing, and I imagine that it is trying to create a fresh repo there instead of syncing with an existing one.
+
+So, how do I set this up? I don't mind adding git remotes, ssh keys, etc, manually, but I haven't been able to figure out what I should be doing! My end goal is to have one annex that is synced between the many computers (ala Dropbox, as the assistant is supposed to be).
+
+Note that the configuration of the test machines:
+client 1 - debian, git-annex built from current cabal
+server - debian, git-annex from apt
+client2 - mac osx, git-annex built from current cabal
+
+Thanks,
+Daniel
diff --git a/doc/forum/How_to_set_up_two_assistants_with_one_shared_transfer_repository__63__/comment_1_bedaf308cfc70b9e751914a400ebcbc2._comment b/doc/forum/How_to_set_up_two_assistants_with_one_shared_transfer_repository__63__/comment_1_bedaf308cfc70b9e751914a400ebcbc2._comment
new file mode 100644
index 000000000..b6a884aa5
--- /dev/null
+++ b/doc/forum/How_to_set_up_two_assistants_with_one_shared_transfer_repository__63__/comment_1_bedaf308cfc70b9e751914a400ebcbc2._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.27"
+ subject="comment 1"
+ date="2012-11-08T21:29:26Z"
+ content="""
+Just adding the same server with the same path is the right thing to do, it will use the existing repo.
+
+Probably the problem you're having is that one client doesn't know when the other client has sent data to the server. I've recently been adding XMPP (Jabber) support to deal with that. That is not yet in a released version of git-annex, but it is available in git master.
+"""]]
diff --git a/doc/forum/How_to_set_up_two_assistants_with_one_shared_transfer_repository__63__/comment_2_d665b1514253c8aa487ebf8b2728e3b1._comment b/doc/forum/How_to_set_up_two_assistants_with_one_shared_transfer_repository__63__/comment_2_d665b1514253c8aa487ebf8b2728e3b1._comment
new file mode 100644
index 000000000..9cb54839f
--- /dev/null
+++ b/doc/forum/How_to_set_up_two_assistants_with_one_shared_transfer_repository__63__/comment_2_d665b1514253c8aa487ebf8b2728e3b1._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlsfh8P7pN2OBr24ztT_7AyYQLCcVqqa-4"
+ nickname="Daniel"
+ subject="comment 2"
+ date="2012-11-09T17:49:32Z"
+ content="""
+The master is segfaulting on one of my machines (the mac), but XMMP sounds good in general.
+
+In the meantime - does git annex sync do what the assistant does? Or is there a command to tell the assistant to check for remote changes? (or a way to get it to auto-poll)
+"""]]
diff --git a/doc/forum/How_to_set_up_two_assistants_with_one_shared_transfer_repository__63__/comment_3_aef42387a3673ab6710fb23e878d7e17._comment b/doc/forum/How_to_set_up_two_assistants_with_one_shared_transfer_repository__63__/comment_3_aef42387a3673ab6710fb23e878d7e17._comment
new file mode 100644
index 000000000..2249c9964
--- /dev/null
+++ b/doc/forum/How_to_set_up_two_assistants_with_one_shared_transfer_repository__63__/comment_3_aef42387a3673ab6710fb23e878d7e17._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.252.11.120"
+ subject="comment 3"
+ date="2012-11-13T17:57:49Z"
+ content="""
+I recently dealt with a segfault caused by a bug in the haskell gnutls library. It could be that's what you were seeing. It's fixed in gnutls (>= 0.1.4)
+
+Yes, you can run `git annex sync` by hand. It does the same syncing of the git repository that the assistant does. I don't think making the assistant poll is a good idea.
+"""]]
diff --git a/doc/forum/How_to_set_up_two_assistants_with_one_shared_transfer_repository__63__/comment_4_bfbcc041db472f4808979e6b3d7c4be2._comment b/doc/forum/How_to_set_up_two_assistants_with_one_shared_transfer_repository__63__/comment_4_bfbcc041db472f4808979e6b3d7c4be2._comment
new file mode 100644
index 000000000..7bd4870a3
--- /dev/null
+++ b/doc/forum/How_to_set_up_two_assistants_with_one_shared_transfer_repository__63__/comment_4_bfbcc041db472f4808979e6b3d7c4be2._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawniCRkhl_W87gOK5eElfsef3FoUsUFpAr4"
+ nickname="Alexandre"
+ subject="Simplifying this kind of setup"
+ date="2012-12-10T14:33:08Z"
+ content="""
+Maybe it is possible to avoid the XMPP account setup and transferring via XMPP, maybe getting notifications through the SSH connection is possible.
+
+I'm thinking about a \"git-annex-shell server\" unix socket to which clients would connect using the SSH connection and get update notifications from other clients.
+"""]]
diff --git a/doc/forum/Howto_remove_a_repository__63__.mdwn b/doc/forum/Howto_remove_a_repository__63__.mdwn
new file mode 100644
index 000000000..4eb4e6869
--- /dev/null
+++ b/doc/forum/Howto_remove_a_repository__63__.mdwn
@@ -0,0 +1,4 @@
+Hello,
+
+I have added a few repositories for testing purpose and would like to remove them.
+Is it possible to remove a repository through assistant?
diff --git a/doc/forum/Howto_remove_a_repository__63__/comment_1_b55fa4e92bb457ecaa5ca8f5cee7be1d._comment b/doc/forum/Howto_remove_a_repository__63__/comment_1_b55fa4e92bb457ecaa5ca8f5cee7be1d._comment
new file mode 100644
index 000000000..642da6575
--- /dev/null
+++ b/doc/forum/Howto_remove_a_repository__63__/comment_1_b55fa4e92bb457ecaa5ca8f5cee7be1d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-03-17T19:05:27Z"
+ content="""
+There's no UI for it in the assistant. [[Relevant bug report|bugs/The_webapp_doesn't_allow_deleting_repositories]]
+"""]]
diff --git a/doc/forum/Howto_remove_unused_files.mdwn b/doc/forum/Howto_remove_unused_files.mdwn
new file mode 100644
index 000000000..db770457b
--- /dev/null
+++ b/doc/forum/Howto_remove_unused_files.mdwn
@@ -0,0 +1,31 @@
+Hello.
+
+My case: I have somehow managed to get my repo, with quite much stuff inside it messed up.
+
+There is single directory 'cities' containing quite many files (>10k) that i would rather see gone (and keep the tar.bz version of it ..). I tried doing
+
+ git drop --force
+
+that works fine, but the files are still there after sync.
+
+git annex unused says just 'ok' so i guess it thinks they are still used somewhere. I tried to look where, but i ended up just doing git annex drop -f my_remote_here test_file_name for each of my remotes. This doesnt help.
+How can i get rid of these files? Doing git annex fsck shows that
+
+
+So, try to search what is the key:
+
+ % ls -lah cities/diskcache/config.cfg
+ lrwxrwxrwx 1 XX XXX 190 Nov 29 05:52 cities/diskcache/config.cfg -> ../../../../.git/annex/objects/qm/M6/SHA256-s32--4f5ce34d1b0b8d854a315530b2fdcbfa9c3067636a2aa5433a04402db4151dce/SHA256-s32--4f5ce34d1b0b8d854a315530b2fdcbfa9c3067636a2aa5433a04402db4151dce
+ sundberg@sundberg-MS-7680 ~/git-repository/ubuntu.iso/Archive/Maps
+ % git log --stat --all -SSHA256-s32--4f5ce34d1b0b8d854a315530b2fdcbfa9c3067636a2aa5433a04402db4151dce/SHA256-s32--4f5ce34d1b0b8d854a315530b2fdcbfa9c3067636a2aa5433a04402db4151dce
+ commit 51a57a023774ff80408210828f298f5c42a7e0be
+ Author: XXXX
+ Date: Sun Dec 9 13:42:40 2012 +0200
+ git-annex automatic sync
+ Archive/Maps/cities/diskcache/config.cfg | 1 +
+ 1 file changed, 1 insertion(+)
+
+So how can i deduce what is the remote i should try to clean up ?
+
+
+Thanks!
diff --git a/doc/forum/Howto_remove_unused_files/comment_1_f2a7948268ce3cb3967a9fdd8ccc570a._comment b/doc/forum/Howto_remove_unused_files/comment_1_f2a7948268ce3cb3967a9fdd8ccc570a._comment
new file mode 100644
index 000000000..b2bf64397
--- /dev/null
+++ b/doc/forum/Howto_remove_unused_files/comment_1_f2a7948268ce3cb3967a9fdd8ccc570a._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkbv1oKTKhbBp0Ljh_WGU7BFSWWxBr7D3U"
+ nickname="Pauli"
+ subject="Just to add"
+ date="2013-04-02T19:01:09Z"
+ content="""
+
+When i do 'git annex get .' on my usb-remote i get these kind of prints:
+
+ get Archive/Maps/cities/diskcache/voices/slovenian_f/slovenian_female/g5ext_000 (not available)
+ No other repository is known to contain the file.
+ failed
+
+
+No repository contains the file? Well why cannot i then get it removed from the listing ..
+"""]]
diff --git a/doc/forum/Howto_remove_unused_files/comment_2_9b4d198c2d8a52adef3d166a8196fc0d._comment b/doc/forum/Howto_remove_unused_files/comment_2_9b4d198c2d8a52adef3d166a8196fc0d._comment
new file mode 100644
index 000000000..ef4219e2f
--- /dev/null
+++ b/doc/forum/Howto_remove_unused_files/comment_2_9b4d198c2d8a52adef3d166a8196fc0d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkbv1oKTKhbBp0Ljh_WGU7BFSWWxBr7D3U"
+ nickname="Pauli"
+ subject="comment 2"
+ date="2013-04-02T19:10:18Z"
+ content="""
+Just to continue my monolog: doing 'git rm -r cities' followed with git annex sync did the trick. Why didn't i find this anywhere ..
+"""]]
diff --git a/doc/forum/Howto_remove_unused_files/comment_3_441d10901d5c055ac3ed2a6cb61c075c._comment b/doc/forum/Howto_remove_unused_files/comment_3_441d10901d5c055ac3ed2a6cb61c075c._comment
new file mode 100644
index 000000000..ffb941ac8
--- /dev/null
+++ b/doc/forum/Howto_remove_unused_files/comment_3_441d10901d5c055ac3ed2a6cb61c075c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-04-02T21:21:21Z"
+ content="""
+git-annex adds large file capabilities to git, but it leaves all the regular git commands there for you to use. So the answer to \"how do I do &lt;something I'd normally do with a git command&gt;\" is always \"run the git command\". You only need to use git-annex to add large files to git, and to move their content around between repositories. Hope that helps clear that up.
+"""]]
diff --git a/doc/forum/Import_options.txt b/doc/forum/Import_options.txt
new file mode 100644
index 000000000..543d1a4ec
--- /dev/null
+++ b/doc/forum/Import_options.txt
@@ -0,0 +1,14 @@
+Thank you for adding import options to handle duplicates. Very handy when consolidating data from various sources.
+
+Can deletion of the source files be decoupled from annex duplication/deduplication options? For example, I would like to import source files without deleting them and at the same time do not import duplicates.
+
+Better yet, since deletion of source files is potentially dangerous, a delete option could be required for deletion to be performed. Example:
+
+git annex import --deduplicate --delete_all_source_files
+git annex import --deduplicate --delete_source_duplicates
+
+Also, it would be great to have import "status" option which goes over files to be imported and logs their status ( to be imported, duplicate etc. ) without actually performing any changes. It would be great for testing and trial runs.
+
+I hope the above make sense. It would make import feature more flexible.
+
+Cheers,
diff --git a/doc/forum/Import_options/comment_1_118a5f978090a3909299876a01c0adec._comment b/doc/forum/Import_options/comment_1_118a5f978090a3909299876a01c0adec._comment
new file mode 100644
index 000000000..3475a0d73
--- /dev/null
+++ b/doc/forum/Import_options/comment_1_118a5f978090a3909299876a01c0adec._comment
@@ -0,0 +1,21 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkeJKC5Sy0stmcTWyePOLEVv0G-x1yaT_w"
+ nickname="Josef"
+ subject="wishlist"
+ date="2013-09-26T11:11:19Z"
+ content="""
+Posted the above yesterday before realizing that it should probably go to wishlist requests. I am sorry about that.
+
+Basically it is a request to extend import options and perhaps make the options easier to use/understand.
+
+Suggested Import Options:
+
+- source directory,
+- destination directory,
+- deduplicate in annex ( yes, no )
+- delete source files ( yes, no )
+- trial run ( screen output only )
+
+Many thanks for a great product!
+
+"""]]
diff --git a/doc/forum/Import_options/comment_2_21da91f08cb6b28ae3e79ade033db516._comment b/doc/forum/Import_options/comment_2_21da91f08cb6b28ae3e79ade033db516._comment
new file mode 100644
index 000000000..a3e259624
--- /dev/null
+++ b/doc/forum/Import_options/comment_2_21da91f08cb6b28ae3e79ade033db516._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkeJKC5Sy0stmcTWyePOLEVv0G-x1yaT_w"
+ nickname="Josef"
+ subject="Additional Comments"
+ date="2013-09-30T21:33:31Z"
+ content="""
+Imported several thousand files to annex and would like to add the following comments:
+
+- it would be great to have an option to exclude hidden dot files from import,
+
+- empty directories should be deleted when files located in the directories are deleted,
+
+- \"git annex add\" seems to process directories and files alphabetically, unfortunately import processes files in a different order, which makes it hard to predict which files are deleted when deduplicating,
+
+Cheers,
+
+"""]]
diff --git a/doc/forum/Is_an_automagic_upgrade_of_the_object_directory_safe__63__.mdwn b/doc/forum/Is_an_automagic_upgrade_of_the_object_directory_safe__63__.mdwn
new file mode 100644
index 000000000..5643f6b7a
--- /dev/null
+++ b/doc/forum/Is_an_automagic_upgrade_of_the_object_directory_safe__63__.mdwn
@@ -0,0 +1,9 @@
+Consider the following two use cases:
+
+* I have a git-annex repo on a portable medium and carry it around between several machines. I use it on a non-important system with the most current git-annex installed, automagic upgrade happens. I am now forced to upgrade git-annex on all other machines. Bonus points if this happens in the background and I don't even notice it until it's too late.
+
+* My system crashes and I use a rescue CD to access local data, including git-annex. The rescue CD includes a newer version of git-annex and once my system is restored, I am forced to upgrade git-annex locally.
+
+My suggestion would be not to upgrade automatically, but to either ask the user if this is OK or to error out and request that they run git annex update by hand.
+
+Optionally, this could be done via a local config variable which should default to error or ask, not upgrade.
diff --git a/doc/forum/Is_an_automagic_upgrade_of_the_object_directory_safe__63__/comment_1_c25900b9d2d62cc0b8c77150bcfebadf._comment b/doc/forum/Is_an_automagic_upgrade_of_the_object_directory_safe__63__/comment_1_c25900b9d2d62cc0b8c77150bcfebadf._comment
new file mode 100644
index 000000000..8420d7bb3
--- /dev/null
+++ b/doc/forum/Is_an_automagic_upgrade_of_the_object_directory_safe__63__/comment_1_c25900b9d2d62cc0b8c77150bcfebadf._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-03-18T00:38:51Z"
+ content="""
+These are good examples; I think you've convinced me at least for upgrades going forward after v2. I'm not sure we have enough users and outdated git-annex installations to worry about it for v1.
+
+(Hoping such upgrades are rare anyway.. Part of the point of changes made in v2 was to allow lots of changes to be made later w/o needing a v3.)
+
+Update: Upgrades from v1 to v2 will no longer be handled automatically
+now.
+"""]]
diff --git a/doc/forum/Is_git-annex_in_a_precarious_state_before_the_initial_commit__63__.mdwn b/doc/forum/Is_git-annex_in_a_precarious_state_before_the_initial_commit__63__.mdwn
new file mode 100644
index 000000000..4fb3d05af
--- /dev/null
+++ b/doc/forum/Is_git-annex_in_a_precarious_state_before_the_initial_commit__63__.mdwn
@@ -0,0 +1,18 @@
+So suppose you put an existing folder under git-annex control, like this:
+
+ cd Archive_of_all_my_files
+ git init .
+ git annex init "Archive Folder"
+ git annex add .
+
+And now you forget the last step:
+
+ git commit -am "init"
+
+Instead, you fool around with git. After all, isn't git designed to keep your data safe and make sure there's no way you can accidentally lose it? The only branch that exists is 'git-annex', so you switch to that branch to see what it is:
+
+ git checkout git-annex
+
+This command switches to the branch git-annex and makes a mess in the working directory. And you can't switch back to master since master does not have any commits. Is there a clean way to go back? I tried 'git checkout --orphan master', but the messy files stayed in the working directory. In the meantime, there should probably be a warning on the walkthrough page.
+
+I think git / git annex should warn you before switching the branch in this rare situation.
diff --git a/doc/forum/Is_git-annex_in_a_precarious_state_before_the_initial_commit__63__/comment_1_f9decde3955f10148febc4646fba5a68._comment b/doc/forum/Is_git-annex_in_a_precarious_state_before_the_initial_commit__63__/comment_1_f9decde3955f10148febc4646fba5a68._comment
new file mode 100644
index 000000000..ed1c52d44
--- /dev/null
+++ b/doc/forum/Is_git-annex_in_a_precarious_state_before_the_initial_commit__63__/comment_1_f9decde3955f10148febc4646fba5a68._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.193"
+ subject="comment 1"
+ date="2013-07-02T05:28:00Z"
+ content="""
+Yes, any git repository where there has not been an initial commit made is in an unusal situation. I've often felt this is a design flaw of git; it could start off with an empty root 00000 commit and avoid this complexity.
+
+There are probably all kinds of fancy git commands that can be used to get out of the situation you describe, but finessing a perfect exit from a situation that has happened in the first 5 minutes of using a new repository seems like overkill. Just run `git annex unannex` to move all your files out of git-annex; run `git rm -rf .` to delete the files from the git-annex branch; run `rm -rf .git`, and you're back where you started with some files and no git repository.
+
+... And no, neither git nor git-annex make any promises about keeping your data secure until you have both committed it and sent it somewhere else.
+"""]]
diff --git a/doc/forum/Is_git-annex_in_a_precarious_state_before_the_initial_commit__63__/comment_2_ed32a48edce4f150bedf24cfe91de254._comment b/doc/forum/Is_git-annex_in_a_precarious_state_before_the_initial_commit__63__/comment_2_ed32a48edce4f150bedf24cfe91de254._comment
new file mode 100644
index 000000000..946fcefa7
--- /dev/null
+++ b/doc/forum/Is_git-annex_in_a_precarious_state_before_the_initial_commit__63__/comment_2_ed32a48edce4f150bedf24cfe91de254._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.193"
+ subject="comment 2"
+ date="2013-07-02T05:29:00Z"
+ content="""
+Oh and no, I don't think it's useful to bog down the walkthrough with warnings and caveats about this type of thing.
+"""]]
diff --git a/doc/forum/Is_git-annex_in_a_precarious_state_before_the_initial_commit__63__/comment_3_ef9618850e5e688bac3c646983f00ed8._comment b/doc/forum/Is_git-annex_in_a_precarious_state_before_the_initial_commit__63__/comment_3_ef9618850e5e688bac3c646983f00ed8._comment
new file mode 100644
index 000000000..f29fc8f81
--- /dev/null
+++ b/doc/forum/Is_git-annex_in_a_precarious_state_before_the_initial_commit__63__/comment_3_ef9618850e5e688bac3c646983f00ed8._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnHRhCe3qwVKQ8_NOGGSYJnAMW6FFyKbOc"
+ nickname="Holger"
+ subject="comment 3"
+ date="2013-07-02T05:52:10Z"
+ content="""
+Thanks for your helpful response. The cleaning procedure that you propose is perfectly fine.
+
+I wasn't suggesting to put up a big warning sign; I just feel like the walkthrough would be a little smoother if it explained something like: hey, 'git annex add .' just moved all of your precious files to '.git/annex/' and renamed them in a way that may scare you. But don't worry: if, at any point, you want to get them out again and put them back in their original place, just run 'git annex unannex'.
+"""]]
diff --git a/doc/forum/Is_git-annex_in_a_precarious_state_before_the_initial_commit__63__/comment_4_4bf460c5826c36b205e418c4f3f7d770._comment b/doc/forum/Is_git-annex_in_a_precarious_state_before_the_initial_commit__63__/comment_4_4bf460c5826c36b205e418c4f3f7d770._comment
new file mode 100644
index 000000000..9d5dc042c
--- /dev/null
+++ b/doc/forum/Is_git-annex_in_a_precarious_state_before_the_initial_commit__63__/comment_4_4bf460c5826c36b205e418c4f3f7d770._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="Xyem"
+ ip="87.194.19.134"
+ subject="comment 4"
+ date="2013-10-22T11:28:52Z"
+ content="""
+I've had this a few times (or situations very similar).
+
+ git init
+is now always followed by
+
+ git commit -m \"CREATE GIT REPOSITORY\" --allow-empty
+
+.. which I should really set as an alias :)
+"""]]
diff --git a/doc/forum/Is_it_possible_to_make_git-sync_not_nullify_symlinks__63__.mdwn b/doc/forum/Is_it_possible_to_make_git-sync_not_nullify_symlinks__63__.mdwn
new file mode 100644
index 000000000..9c41acb70
--- /dev/null
+++ b/doc/forum/Is_it_possible_to_make_git-sync_not_nullify_symlinks__63__.mdwn
@@ -0,0 +1,23 @@
+Hey,
+
+I've found that git annex works great as a way to publish websites to a web server. I can edit my website on my computer, `git annex sync` my working directory to the VPS, and then `git annex get files-I-want-to-publish`. This works great. I can maintain my normal working directory structure on the VPS and I don't have to worry about people seeing files I DIDN'T want to publish, since the dead symlinks just show up as 404s.
+
+There's one small problem.
+
+Say:
+
+ 1) I've already published a file using `git annex get file-to-update`
+
+ 2) I update that file on my computer
+
+ 3) I do `git annex sync`
+
+ 4) I do `git annex get file-to-update`
+
+Between steps 3 and 4, file-to-update goes from being an accessible web resource to being a dead symlink. It's not really a problem for me, as hardly anyone visits my site. But it would be nice if I could make `sync` leave the old symlink to the old file until I `get`ed the new one.
+
+Is this possible?
+
+PS: For those who might follow in my footsteps, remember that you probably don't want people reading the contents of your .git dir, so make a re-write rule for this!
+
+Timothy
diff --git a/doc/forum/Is_it_possible_to_make_git-sync_not_nullify_symlinks__63__/comment_1_d6f2d2cdc5f4ffde9eee9f3a8c215a06._comment b/doc/forum/Is_it_possible_to_make_git-sync_not_nullify_symlinks__63__/comment_1_d6f2d2cdc5f4ffde9eee9f3a8c215a06._comment
new file mode 100644
index 000000000..0c20b9dd6
--- /dev/null
+++ b/doc/forum/Is_it_possible_to_make_git-sync_not_nullify_symlinks__63__/comment_1_d6f2d2cdc5f4ffde9eee9f3a8c215a06._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 1"
+ date="2013-08-07T16:18:52Z"
+ content="""
+I'd recommend that you just copy your files to the repository to publish them before running git-annex sync.
+
+Alternatively, unless your web pages are very large, you can just check them into git directly, still use git-annex sync if you want (and still using git-annex for large files), and avoid the complication of being able to have files that are listed in the repository but whose content is not present.
+"""]]
diff --git a/doc/forum/Lacking_webapp_on_Trisquel__47__Ubuntu_Precise.mdwn b/doc/forum/Lacking_webapp_on_Trisquel__47__Ubuntu_Precise.mdwn
new file mode 100644
index 000000000..d85eefc2c
--- /dev/null
+++ b/doc/forum/Lacking_webapp_on_Trisquel__47__Ubuntu_Precise.mdwn
@@ -0,0 +1,7 @@
+I'd like to have git-annex assistant running so I can use it to sync files, but when I downloaded and ran it the webapp was missing.
+
+I've recently begun using Trisquel, or rather the KDE version Triskel. The current Trisquel is built from Ubuntu Precise, 12.04, the current LTS version. Thus it seems that I'm a bit behind the current Ubuntu software, and my impression is that this relates to my problem.
+
+In [a post](http://git-annex.branchable.com/forum/Cannot_launch_webapp_on_ubuntu_12.04_using_ppa/) on this forum I read that a version of git-annex was built without the webapp, and that this had since been corrected. It appears from my git-annex version data that I have an older version, though I downloaded it only two days ago, and it's older than the corrected version. Is this because my Ubuntu stuff is out of date?
+
+More importantly, is there any way I can get webapp running on my current OS, or must I wait until Trisquel gets to 13.04?
diff --git a/doc/forum/Lacking_webapp_on_Trisquel__47__Ubuntu_Precise/comment_1_6bd27bd31833336c1df783253378ccae._comment b/doc/forum/Lacking_webapp_on_Trisquel__47__Ubuntu_Precise/comment_1_6bd27bd31833336c1df783253378ccae._comment
new file mode 100644
index 000000000..43c8ae525
--- /dev/null
+++ b/doc/forum/Lacking_webapp_on_Trisquel__47__Ubuntu_Precise/comment_1_6bd27bd31833336c1df783253378ccae._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.90"
+ subject="comment 1"
+ date="2013-07-17T19:36:27Z"
+ content="""
+There is a PPA for Ubuntu Precise, which includes the webapp.
+
+Or you can use the standalone tarball, which works nearly everywhere.
+"""]]
diff --git a/doc/forum/Let_watch_selectively_annex_files.mdwn b/doc/forum/Let_watch_selectively_annex_files.mdwn
new file mode 100644
index 000000000..f56b19452
--- /dev/null
+++ b/doc/forum/Let_watch_selectively_annex_files.mdwn
@@ -0,0 +1,27 @@
+Hello,
+
+First of all, thanks to Joey for developing git-annex, good job!
+
+I have a small feature request: when running git annex watch, new files are automatically added to the annex. It would be nice to let this depend on an attribute: add a file to annex if an attribute is set, otherwise do a regular git add.
+
+My use-case is the following: I have a repository containing documents I'm working on (mostly LaTeX), which I'd like to be regular files in git (no annex), and a bunch of extra documentation (pdfs) and images, which I'd like to go to the annex. I currently set a git-attribute (addtoannex), and use a shell script to selectively add files to annex as follows:
+
+Content of .gitattributes:
+
+ *.png addtoannex
+ *.jpg addtoannex
+
+Snippet of add script:
+
+ git check-attr addtoannex "$FILE" | grep -q ": set$"
+ if [ $? -eq 0 ]; then
+ git annex add "$FILE"
+ else
+ git add "$FILE"
+ fi
+
+It would be great if the watcher could honour an attribute.
+
+best regards,
+
+Tom
diff --git a/doc/forum/Let_watch_selectively_annex_files/comment_1_8379de87d16502d9aadf252da01e4d9a._comment b/doc/forum/Let_watch_selectively_annex_files/comment_1_8379de87d16502d9aadf252da01e4d9a._comment
new file mode 100644
index 000000000..415b08894
--- /dev/null
+++ b/doc/forum/Let_watch_selectively_annex_files/comment_1_8379de87d16502d9aadf252da01e4d9a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.3.125"
+ subject="comment 1"
+ date="2013-02-07T18:10:14Z"
+ content="""
+This has been requested a couple of times in different places.
+
+The problem with using a git attribute is it only allows basic matching on filenames. Some users would prefer to use the size of the file. So if/when this gets implemented it will probably not use a git attribute, but some other config setting.
+"""]]
diff --git a/doc/forum/Let_watch_selectively_annex_files/comment_2_2219ff6b4dc927eb2a299cd1af90aed8._comment b/doc/forum/Let_watch_selectively_annex_files/comment_2_2219ff6b4dc927eb2a299cd1af90aed8._comment
new file mode 100644
index 000000000..d6cee26d5
--- /dev/null
+++ b/doc/forum/Let_watch_selectively_annex_files/comment_2_2219ff6b4dc927eb2a299cd1af90aed8._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-06-11T14:28:56Z"
+ content="""
+See [[tips/replacing_Sparkleshare_or_dvcs-autosync_with_the_assistant]]
+"""]]
diff --git a/doc/forum/Links_or_actual_files__63___Confused__33__.mdwn b/doc/forum/Links_or_actual_files__63___Confused__33__.mdwn
new file mode 100644
index 000000000..8d7ef2c17
--- /dev/null
+++ b/doc/forum/Links_or_actual_files__63___Confused__33__.mdwn
@@ -0,0 +1,21 @@
+I don't think it's a bug or a todo, just a request for clarification.
+
+So, I installed git-annex first on a Mac, and created the initial repository, and started dropping stuff into it. All fine.
+
+Created a second repository on an external (but never disconnected, also does Time Machine) drive. All fine. Everything's there.
+
+Went across the room to my Linux desktop, installed git-annex, and tried to pair it to my Mac's git-annex repo. Hit <a href="http://git-annex.branchable.com/bugs/bad_comment_in_ssh_public_key_ssh-rsa/#comment-0ee00f307909723fdf8c73695787f067">this bug</a>, installed latest git-annex from tarball and got past that and got the pairing done. Syncing happened, all looked well...
+
+But when I look in the annex dir on that Linux machine, I now just see symlinks to the actual files in the repo's .git/annex stuff. It kinda works, but it's a bit distracting, especially if you open such a file in any desktop app and you can see it's got the target of the link (some sha-value filename.ext) rather than the sensibly-named link. Including files created and coped into that annex on that machine. (In Nautilus they all show with symlink & lock emblems.)
+
+Look again at some documentation, and apparently it's <a href="http://git-annex.branchable.com/how_it_works/">supposed to do this</a>
+
+Which makes me wonder why it *isn't* doing it on the Mac I started the repository on?
+
+Went to another mac (laptop) and installed git-annex, and set up pairing to the first mac - as far as I can tell, doing the exact same procedure as I did under Linux. TBH through the webapp there's not much scope for doing it a different way. Files sync across...
+
+And there they are, the actual files, directly in the annex dir, not symlinks.
+
+(I am by the way confirming this at the commandline, it's not just what Finder/Nautilus may be displaying to me graphically.)
+
+Now, seeing the actual files in the annex directory is what I *prefer*; but I'm a: confused as to why the Macs are doing it that way but Linux isn't, and b: given the "how it works" link, why everything isn't using the links.
diff --git a/doc/forum/Links_or_actual_files__63___Confused__33__/comment_1_779cee2448d7070b1dd636d01296c01e._comment b/doc/forum/Links_or_actual_files__63___Confused__33__/comment_1_779cee2448d7070b1dd636d01296c01e._comment
new file mode 100644
index 000000000..0122cf45b
--- /dev/null
+++ b/doc/forum/Links_or_actual_files__63___Confused__33__/comment_1_779cee2448d7070b1dd636d01296c01e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.51"
+ subject="comment 1"
+ date="2013-09-12T17:58:24Z"
+ content="""
+When you create a git-annex repository using the webapp, it uses [[direct_mode]]. That is not the default if you create a repository by hand at the command line, although you can enable it if you prefer it.
+"""]]
diff --git a/doc/forum/Links_or_actual_files__63___Confused__33__/comment_2_bccda88697ab7beec0b9fe9ee0230688._comment b/doc/forum/Links_or_actual_files__63___Confused__33__/comment_2_bccda88697ab7beec0b9fe9ee0230688._comment
new file mode 100644
index 000000000..c6a851eff
--- /dev/null
+++ b/doc/forum/Links_or_actual_files__63___Confused__33__/comment_2_bccda88697ab7beec0b9fe9ee0230688._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlEhzszkzOIy8-Rx8b2mcr75QcnIc6O_OA"
+ nickname="Rachel"
+ subject="webapp/direct"
+ date="2013-09-12T18:17:51Z"
+ content="""
+well, i did it using the webapp both times; i've barely scratched at the git-annex commandline so far.
+
+However... I then tried to repeat it on another linux box (running ubuntu saucy and the version of git-annex in that repo) and it worked as expected: Real files in the annex directory, ie: as I understand it, direct mode.
+
+So, went back to the first linux box (running ubuntu raring), and cleared everything off, quit and started again, doing the same thing again, and *it* did the direct mode thing itself this time.
+
+Which I think leaves me with it the way I want it. :-)
+
+My only guess is, maybe it got set up in non-direct mode when I first started using the older git-annex in the raring repos, before failing with the bad comment in ssh public key bug, at which point I switched to the downloaded-today tarball and just tried to resume. Starting from scratch with the newer version worked.
+
+I'm sure more questions to come later; am a Dropbox fugitive by way of ownCloud (won't-fix bug on version upgrades) basically trying to replicate that kind of convenience. But those are for other postings.
+"""]]
diff --git a/doc/forum/Links_or_actual_files__63___Confused__33__/comment_3_c2a9da3f03b55ff294dc0d2010380119._comment b/doc/forum/Links_or_actual_files__63___Confused__33__/comment_3_c2a9da3f03b55ff294dc0d2010380119._comment
new file mode 100644
index 000000000..5df67c605
--- /dev/null
+++ b/doc/forum/Links_or_actual_files__63___Confused__33__/comment_3_c2a9da3f03b55ff294dc0d2010380119._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.51"
+ subject="comment 3"
+ date="2013-09-12T20:22:44Z"
+ content="""
+Yep, relatively ancient (from last year) versions of the webapp didn't use direct mode by default, and have various bugs as well.
+"""]]
diff --git a/doc/forum/Local_and_remote_in_direct_mode.mdwn b/doc/forum/Local_and_remote_in_direct_mode.mdwn
new file mode 100644
index 000000000..128d8eab6
--- /dev/null
+++ b/doc/forum/Local_and_remote_in_direct_mode.mdwn
@@ -0,0 +1,7 @@
+I have two machines (A and B ) both have a directory called "inbox"
+I want to sync these two directories. So I ran git annex assistant on machine A and set up a remote to B with **ssh** and selected **client: a repository on your computer**.
+
+The end result is that I have something that looks like a git bare repo on machine B and I have no files on A from machine B.
+
+What am I doing wrong? What shall I do to achieve my goal?
+It is kind of dropbox functionality what I want. (Which I never used for security/policy reasons.)
diff --git a/doc/forum/Local_and_remote_in_direct_mode/comment_1_45f89ebcb6092d1b2582feebc8a5e9d7._comment b/doc/forum/Local_and_remote_in_direct_mode/comment_1_45f89ebcb6092d1b2582feebc8a5e9d7._comment
new file mode 100644
index 000000000..f7244cabc
--- /dev/null
+++ b/doc/forum/Local_and_remote_in_direct_mode/comment_1_45f89ebcb6092d1b2582feebc8a5e9d7._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-03-19T18:05:58Z"
+ content="""
+The \"Remote server using ssh\" option in the webapp is intended to set up a bare git repository on a server, not a non-bare git repository on a client.
+
+For what you want, both your computers need to be running the git-annex assistant.
+
+* If the computers are on the same network, pick the \"Local computer\" option on one to start a pairing process with the other.
+* If the computers are not on the same network, but can (apparently) access one-another by ssh, then you're a lucky guy. :) But the webapp doesn't cater to this unusual configuration (unless the local pairing option above works). All you need to do though, it manually add a git remote on each that points to the already existing, git-annex assistant managed repository on the other. Eg: `git remote add B ssh://machineB:/~/annex`
+* If the computers are not on the same network, and cannot access each other directly using ssh, you will need
+to use the XMPP option, and a transfer remote that both can access.
+"""]]
diff --git a/doc/forum/Looking_at_the_webapp_on_OSX.mdwn b/doc/forum/Looking_at_the_webapp_on_OSX.mdwn
new file mode 100644
index 000000000..b2c514d83
--- /dev/null
+++ b/doc/forum/Looking_at_the_webapp_on_OSX.mdwn
@@ -0,0 +1,18 @@
+Not logging this in the bugs section, but poking at the new webapp feature...
+
+<pre>
+laplace:annex jtang$ git annex webapp -d
+[2012-07-26 19:02:50 IST] read: git ["--git-dir=/Users/jtang/annex/.git","--work-tree=/Users/jtang/annex","show-ref","git-annex"]
+[2012-07-26 19:02:50 IST] read: git ["--git-dir=/Users/jtang/annex/.git","--work-tree=/Users/jtang/annex","show-ref","--hash","refs/heads/git-annex"]
+[2012-07-26 19:02:50 IST] read: git ["--git-dir=/Users/jtang/annex/.git","--work-tree=/Users/jtang/annex","log","refs/heads/git-annex..731005d121426a38b206c4544da02cdb3b974974","--oneline","-n1"]
+[2012-07-26 19:02:50 IST] read: git ["--git-dir=/Users/jtang/annex/.git","--work-tree=/Users/jtang/annex","log","refs/heads/git-annex..d36d8d88847decc2320f0be22892ad94a8abe594","--oneline","-n1"]
+[2012-07-26 19:02:50 IST] read: git ["--git-dir=/Users/jtang/annex/.git","--work-tree=/Users/jtang/annex","log","refs/heads/git-annex..57bcddc14d03b61028f7002e2dabcc5181d74f3d","--oneline","-n1"]
+[2012-07-26 19:02:50 IST] read: git ["--git-dir=/Users/jtang/annex/.git","--work-tree=/Users/jtang/annex","log","refs/heads/git-annex..372aceaf49b60ebe31cc3fe2e52ba4fbe99c134f","--oneline","-n1"]
+[2012-07-26 19:02:50 IST] chat: git ["--git-dir=/Users/jtang/annex/.git","--work-tree=/Users/jtang/annex","cat-file","--batch"]
+[2012-07-26 19:02:50 IST] read: git ["config","--null","--list"]
+[2012-07-26 19:02:50 IST] call: open ["file:///Users/jtang/annex/.git/annex/webapp.html"]
+The file /Users/jtang/annex/.git/annex/webapp.html does not exist.
+git-annex: failed to start web browser on url file:///Users/jtang/annex/.git/annex/webapp.html
+</pre>
+
+I would have expected the open command to open up http://localhost:port/ instead of a file on my machine. Anyway, its just an observation on the current state of the webapp feature, not expecting it to work enough for me to test it ;)
diff --git a/doc/forum/Looking_at_the_webapp_on_OSX/comment_1_68820f2f469356633c1abb18a47e0c59._comment b/doc/forum/Looking_at_the_webapp_on_OSX/comment_1_68820f2f469356633c1abb18a47e0c59._comment
new file mode 100644
index 000000000..9aa05c8f0
--- /dev/null
+++ b/doc/forum/Looking_at_the_webapp_on_OSX/comment_1_68820f2f469356633c1abb18a47e0c59._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.2.189"
+ subject="comment 1"
+ date="2012-07-26T18:17:40Z"
+ content="""
+This could happen if you already had an old version of git-annex assistant running in that repository.
+
+Try:
+
+git annex assistant --stop ; git annex webapp
+"""]]
diff --git a/doc/forum/Looking_at_the_webapp_on_OSX/comment_2_4ce86546d8a135df9cfab46b4612fa0b._comment b/doc/forum/Looking_at_the_webapp_on_OSX/comment_2_4ce86546d8a135df9cfab46b4612fa0b._comment
new file mode 100644
index 000000000..b24956b8c
--- /dev/null
+++ b/doc/forum/Looking_at_the_webapp_on_OSX/comment_2_4ce86546d8a135df9cfab46b4612fa0b._comment
@@ -0,0 +1,23 @@
+[[!comment format=mdwn
+ username="jtang"
+ ip="79.97.135.214"
+ subject="comment 2"
+ date="2012-07-26T20:42:37Z"
+ content="""
+The last few commits fixed the webapp startup quirk, it doesn't work yet for me as the watch command is probably failing
+
+<pre>
+laplace:annex jtang$ git annex webapp -d
+[2012-07-26 21:41:15 IST] read: git [\"--git-dir=/Users/jtang/annex/.git\",\"--work-tree=/Users/jtang/annex\",\"show-ref\",\"git-annex\"]
+[2012-07-26 21:41:15 IST] read: git [\"--git-dir=/Users/jtang/annex/.git\",\"--work-tree=/Users/jtang/annex\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+[2012-07-26 21:41:15 IST] read: git [\"--git-dir=/Users/jtang/annex/.git\",\"--work-tree=/Users/jtang/annex\",\"log\",\"refs/heads/git-annex..731005d121426a38b206c4544da02cdb3b974974\",\"--oneline\",\"-n1\"]
+[2012-07-26 21:41:15 IST] read: git [\"--git-dir=/Users/jtang/annex/.git\",\"--work-tree=/Users/jtang/annex\",\"log\",\"refs/heads/git-annex..d36d8d88847decc2320f0be22892ad94a8abe594\",\"--oneline\",\"-n1\"]
+[2012-07-26 21:41:15 IST] read: git [\"--git-dir=/Users/jtang/annex/.git\",\"--work-tree=/Users/jtang/annex\",\"log\",\"refs/heads/git-annex..57bcddc14d03b61028f7002e2dabcc5181d74f3d\",\"--oneline\",\"-n1\"]
+[2012-07-26 21:41:15 IST] read: git [\"--git-dir=/Users/jtang/annex/.git\",\"--work-tree=/Users/jtang/annex\",\"log\",\"refs/heads/git-annex..372aceaf49b60ebe31cc3fe2e52ba4fbe99c134f\",\"--oneline\",\"-n1\"]
+[2012-07-26 21:41:15 IST] chat: git [\"--git-dir=/Users/jtang/annex/.git\",\"--work-tree=/Users/jtang/annex\",\"cat-file\",\"--batch\"]
+[2012-07-26 21:41:15 IST] read: git [\"config\",\"--null\",\"--list\"]
+git-annex: failed to start git-annex assistant
+</pre>
+
+it doesn't segfault or anything, it just states that the assistant command failed to start :P
+"""]]
diff --git a/doc/forum/Looking_at_the_webapp_on_OSX/comment_3_6d398a2cceff14a1b774b85ee1725073._comment b/doc/forum/Looking_at_the_webapp_on_OSX/comment_3_6d398a2cceff14a1b774b85ee1725073._comment
new file mode 100644
index 000000000..a139537de
--- /dev/null
+++ b/doc/forum/Looking_at_the_webapp_on_OSX/comment_3_6d398a2cceff14a1b774b85ee1725073._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.2.189"
+ subject="comment 3"
+ date="2012-07-26T22:07:25Z"
+ content="""
+I've been improving this code path, so make sure you're current. I just made it wait for longer than the 10 seconds it was waiting before giving up.
+
+If it still fails, try running `git-annex assistant --debug --foreground`
+in one terminal, wait for it to start up, and then run `git annex webapp` in another.
+If that still fails, check if `.git/annex/webapp.html` exists.
+"""]]
diff --git a/doc/forum/Looking_at_the_webapp_on_OSX/comment_4_5e503787a4b1d3534c5e20da5480b763._comment b/doc/forum/Looking_at_the_webapp_on_OSX/comment_4_5e503787a4b1d3534c5e20da5480b763._comment
new file mode 100644
index 000000000..fde217e63
--- /dev/null
+++ b/doc/forum/Looking_at_the_webapp_on_OSX/comment_4_5e503787a4b1d3534c5e20da5480b763._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.2.189"
+ subject="comment 4"
+ date="2012-07-26T22:08:53Z"
+ content="""
+Oh, wait, you're right, if the assistant process that watch forks off is segfaulting, that error message is about the best we can hope for. You can try the manual startup of the assistant to confirm it's crashing..
+"""]]
diff --git a/doc/forum/Looking_at_the_webapp_on_OSX/comment_5_c735841bc230efc61594ea013fc2902b._comment b/doc/forum/Looking_at_the_webapp_on_OSX/comment_5_c735841bc230efc61594ea013fc2902b._comment
new file mode 100644
index 000000000..47f7be603
--- /dev/null
+++ b/doc/forum/Looking_at_the_webapp_on_OSX/comment_5_c735841bc230efc61594ea013fc2902b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 5"
+ date="2012-07-27T15:53:50Z"
+ content="""
+I can confirm that the watch command is crashing when i start it up manually.
+"""]]
diff --git a/doc/forum/Looking_at_the_webapp_on_OSX/comment_6_0e489fbfc89d282e9eb47f1b814ff70c._comment b/doc/forum/Looking_at_the_webapp_on_OSX/comment_6_0e489fbfc89d282e9eb47f1b814ff70c._comment
new file mode 100644
index 000000000..901492386
--- /dev/null
+++ b/doc/forum/Looking_at_the_webapp_on_OSX/comment_6_0e489fbfc89d282e9eb47f1b814ff70c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="jtang"
+ ip="79.97.135.214"
+ subject="comment 6"
+ date="2012-07-27T18:21:17Z"
+ content="""
+FYI, the webapp starts up and sends me to a web browser with the correct page ;) this is after the other issue of [[Watch command as of commit 6cecc26206c4a539999b04664136c6f785211a41 segfaults]] got fixed.
+"""]]
diff --git a/doc/forum/Make_whereis_output_more_compact.mdwn b/doc/forum/Make_whereis_output_more_compact.mdwn
new file mode 100644
index 000000000..5503e716f
--- /dev/null
+++ b/doc/forum/Make_whereis_output_more_compact.mdwn
@@ -0,0 +1,13 @@
+Hi there,
+
+first of all, great job done on annex! I think I finally found what I was looking for to organize all my data.
+
+My question: when I do git annex whereis Music, I get a detailed list of every single song and its remote locations. I have tens of thousands of songs, so just typing git annex whereis Music gives me way too much information.
+Here is my proposition: in my case, every file of the Music folder resides in the same remote. So, wouldn't it be better to show just one line of output telling me that Music is on remote bla and blub, and then I know that all files in Music are in remotes bla and blub?
+
+Is that possible now already or would that be a feature request? What do you think?
+
+Cheers,
+Moritz.
+
+PS: I know that I can specify filters, e.g. git annex whereis --in bla --and --not --in blub. That is great!
diff --git a/doc/forum/Making_git-annex_a_self-funded_project__63__.mdwn b/doc/forum/Making_git-annex_a_self-funded_project__63__.mdwn
new file mode 100644
index 000000000..29eddaa0c
--- /dev/null
+++ b/doc/forum/Making_git-annex_a_self-funded_project__63__.mdwn
@@ -0,0 +1,10 @@
+With the fundraiser having met its stretch goal of $15,000, I was thinking of how to keep git-annex going beyond another year. What about selling stuff? Not just merch (though being able to buy stickers would be neat), but useful things that would complement the software, like selling hardware for a small remote that you could plug into your home network, or even set up at a friend's house to have online, but offsite.
+
+
+Something like a CubieBoard2 and an HDD for annexes preloaded with all the necessary software and a git-annex apt repo for keeping it updated. Everything would come in a nice little enclosure with a git-annex logo on it; you plug in the power, the ethernet, and boom it's ready to go, with no terminal magic (but it's there if you want it!). You could create them on-demand without having to keep much of a stock (except maybe the enclosure), so there's practically no risk.
+
+
+
+Aesthetically, I was thinking of something that exposed as little of the insides as possible. Basically just power, ethernet, and USB ports.
+
+Maybe material for another Kickstarter?
diff --git a/doc/forum/Making_git-annex_a_self-funded_project__63__/comment_1_4a1ba95b7231ba973ddb672d2419e28c._comment b/doc/forum/Making_git-annex_a_self-funded_project__63__/comment_1_4a1ba95b7231ba973ddb672d2419e28c._comment
new file mode 100644
index 000000000..03ddae483
--- /dev/null
+++ b/doc/forum/Making_git-annex_a_self-funded_project__63__/comment_1_4a1ba95b7231ba973ddb672d2419e28c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="GLITTAH"
+ ip="94.126.178.1"
+ subject="comment 1"
+ date="2013-07-27T01:56:47Z"
+ content="""
+Other ideas welcome!
+"""]]
diff --git a/doc/forum/Making_git-annex_a_self-funded_project__63__/comment_2_7c476ae92e63c991f229708678874ca2._comment b/doc/forum/Making_git-annex_a_self-funded_project__63__/comment_2_7c476ae92e63c991f229708678874ca2._comment
new file mode 100644
index 000000000..70e470c85
--- /dev/null
+++ b/doc/forum/Making_git-annex_a_self-funded_project__63__/comment_2_7c476ae92e63c991f229708678874ca2._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.110"
+ subject="comment 2"
+ date="2013-07-28T00:21:39Z"
+ content="""
+A few people have suggested that idea. I don't know if I want to get into the HW business.
+"""]]
diff --git a/doc/forum/Making_git-annex_less_necessary.mdwn b/doc/forum/Making_git-annex_less_necessary.mdwn
new file mode 100644
index 000000000..086c05139
--- /dev/null
+++ b/doc/forum/Making_git-annex_less_necessary.mdwn
@@ -0,0 +1,5 @@
+http://git-annex.branchable.com/walkthrough/ says "Git wants to first stage the entire contents of the file in its index. That can be slow for big files (sorta why git-annex exists in the first place)."<br/>
+What is git doing that git-annex isn't, other than copying the file to .git/objects rather than just moving it to .git/annex/objects, prepending it with "blob"+length, and compressing it? If git were changed to store the "blob"+length as part of the object filename rather than as part of the object file content, have a config option to use uncompressed objects for large files (and not try to pack them when creating pack files), and were used on a filesystem such as zfs or btrfs which does COW so the copy would be as fast as a move, then what speed advantage would git-annex still have over git? I realize git-annex has more features than just big file handling, and has the worm backend for even faster handling, but I'm just talking about the case with the default sha backend.<br/>
+Have such changes been proposed for git? It seems that for anybody already familiar with the git codebase, adding the config option for uncompressed objects and moving the storage location for "blob"+length would be easy changes to make, and I see no downside to them. It wouldn't break backwards compatibility because the object filename being hash."blob".length rather than just hash would indicate that the new object format is in use, and a ".raw" filename extension could be used for uncompressed objects (or more sensibly, in the new format, no additional extension for uncompressed, and ".compressed" for compressed).<br/>
+This would also eliminate the need for a git-annex object store separate from the git object store, and the complexities involved with having them separate, and the need for symlinks, and the complexities they cause. I don't think that relying on COW for speed is unreasonable once btrfs becomes the default in major Linux distros (the bsds already have zfs and hammerfs); right now part of what git-annex is doing is just working around the functional deficiency of non-COW filesystems.<br/>
+P.S. I recommend a "plain" option for the page type when submitting comments on your wiki, so I don't have to put HTML line break markup at the end of my lines.
diff --git a/doc/forum/Making_git-annex_less_necessary/comment_1_03faaa3866778d24cd03887b85dc9954._comment b/doc/forum/Making_git-annex_less_necessary/comment_1_03faaa3866778d24cd03887b85dc9954._comment
new file mode 100644
index 000000000..3396643f6
--- /dev/null
+++ b/doc/forum/Making_git-annex_less_necessary/comment_1_03faaa3866778d24cd03887b85dc9954._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.2.245"
+ subject="comment 1"
+ date="2012-05-08T18:22:12Z"
+ content="""
+git's code base makes lots of assumptions hardcoding the size of the hash, etc. (grep its source for magic numbers 40 and 42...) I'd like to see git get parameratised hashes. SHA1 insecurity may evenutally push it in that direction. However, when I asked the git developers about this at the Gittogether last year, there were several ideas floated that would avoid parameterisation, and a lot of good thoughts about problems parameterised hashes would cause.
+
+Moving data into git proper would still leave the problems unique to large data of not being able to store it all on every clone. Which means a git-annex like thing is needed to track where the data resides and move it around.
+
+(BTW, in markdown, you separate paragraphs with blank lines. Like in email.)
+"""]]
diff --git a/doc/forum/Making_git-annex_less_necessary/comment_2_2db02a94dffd525885c9d7fc6c5fa464._comment b/doc/forum/Making_git-annex_less_necessary/comment_2_2db02a94dffd525885c9d7fc6c5fa464._comment
new file mode 100644
index 000000000..4b1dbd271
--- /dev/null
+++ b/doc/forum/Making_git-annex_less_necessary/comment_2_2db02a94dffd525885c9d7fc6c5fa464._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/IAg3idYGk.joxsJb2WCxl20gig.0.8hS#d5165"
+ nickname="Kelly"
+ subject="comment 2"
+ date="2012-05-10T15:01:15Z"
+ content="""
+I think my comment a couple days ago got caught in the spam filter, so I'm reposting.
+What were the ideas to avoid parameterisation? What were the problems of parameterisation, other than just the current hardcoded assumptions?
+
+Speaking of hash insecurity, http://static.usenix.org/events/hotos03/tech/full_papers/henson/henson_html/node8.html says compare-by-hash is a bad idea. As I understand, git doesn't have an option of verifying content matches when the hash matches when adding data to the object store (like zfs's \"dedup=verify\" option, which you can use even when using sha256), because the assumption is that the risk of collision (or at least just the risk of accidental collision) is negligible. Would it be worthwhile to add this option to git-annex?
+
+"""]]
diff --git a/doc/forum/Making_git-annex_less_necessary/comment_3_429ec656e0ac02f98843f8d7f3c02d6a._comment b/doc/forum/Making_git-annex_less_necessary/comment_3_429ec656e0ac02f98843f8d7f3c02d6a._comment
new file mode 100644
index 000000000..41b7570e1
--- /dev/null
+++ b/doc/forum/Making_git-annex_less_necessary/comment_3_429ec656e0ac02f98843f8d7f3c02d6a._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/IAg3idYGk.joxsJb2WCxl20gig.0.8hS#d5165"
+ nickname="Kelly"
+ subject="comment 2"
+ date="2012-05-09T01:22:13Z"
+ content="""
+What were the ideas to avoid parameterisation? What were the problems of parameterisation, other than just the current hardcoded assumptions?
+
+Speaking of hash insecurity, http://static.usenix.org/events/hotos03/tech/full_papers/henson/henson_html/node8.html says compare-by-hash is a bad idea. As I understand, git doesn't have an option of verifying content matches when the hash matches when adding data to the object store (like zfs's \"dedup=verify\" option, which you can use even when using sha256), because the assumption is that the risk of collision (or at least just the risk of accidental collision) is negligible. Would it be worthwhile to add this option to git-annex?
+
+"""]]
diff --git a/doc/forum/Making_git-annex_less_necessary/comment_4_384813dd022dfd9c1ef14e0f1479a123._comment b/doc/forum/Making_git-annex_less_necessary/comment_4_384813dd022dfd9c1ef14e0f1479a123._comment
new file mode 100644
index 000000000..40f0e02b0
--- /dev/null
+++ b/doc/forum/Making_git-annex_less_necessary/comment_4_384813dd022dfd9c1ef14e0f1479a123._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="http://christian.amsuess.com/"
+ nickname="chrysn"
+ subject="comment 2"
+ date="2012-05-11T17:40:20Z"
+ content="""
+from my layman's standpoint, i think it would be feasible. i've suggested this previously, but not pushed it too much. quoting from [[my user page|users/chrysn]]:
+
+* **would like git-annex to**: not be required any more as git itself learns to use cow filesystems to avoid abundant disk usage and gets better with sparser checkouts (git-annex might then still be a simpler tool that watches over what can be safely dropped for a sparser checkout)
+
+*concerning hash sizes or parameterized hashes*: the problems with hash sizes could be avoided if instead of putting the objects in the \"normal\" object dir, barefiles would be managed in a similar way as packs are. when a new files gets added, they'd be cow-copied to ``.git/objects/bare/${HA}/${SH}``, and ``.git/objects/bareprefix/${HA}/${SH}`` would contain the \"blob ${SIZE}\0\" prefix that gets concatenated to the object body to form the object itself.
+
+(maybe it'd even be sufficient to *just store the size* in the bareprefix, as all those objects would be blobs, but then again, some flexibility won't hurt.)
+
+if the *pack file format* is flexible enough, the bareprefix files can get packed too. for the adventerous user who modifies bigfiles, the pack file mechanisms should be made aware of their presence, and be able to store deltas between them. the operations for applying those deltas would be difficult to optimize, and could be added at a later stage. a typical example could be storing a pdf file -- the pdf file format is designed for appending, so chances are the new version is just the old version plus several k at the end.
+
+neither of that would affect git's *wire protocol*, so no compatibility problems. (it would be advisable to find a reasonable way to do sparse checkouts, though; something like \"server, pack and send your master, but make it sparse and don't include blobs >1mb\").
+"""]]
diff --git a/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__.mdwn b/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__.mdwn
new file mode 100644
index 000000000..acd9066ec
--- /dev/null
+++ b/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__.mdwn
@@ -0,0 +1,118 @@
+I have come up with a moderately complex solution to a particular use case that I have and am posting it here in case it is useful to someone else, and to get suggestions on how to improve it.
+
+#The problem:
+
+I have a large number of files that are accessed infrequently and stored off-line on DVD-Rs. I need to keep track of which files are on which disc so that when I want a file I can find it.
+
+#The solution:
+
+I currently keep a text file to track which files are on which discs. I would like to organize all the files in a proper filesystem using git annex, allowing me better organization and the ability to keep some smaller related files online near the annexed large files.
+
+#Requirements:
+
+1) Easily locate the DVD-R containing any specific offline file
+
+This is easily taken care of with git annex whereis
+
+2) Automatically de-duplicate stored files with the same contents
+
+This is taken care of with one of the hash backends (E.G. SHA256)
+
+3) The DVD-Rs still need to be usable without git or git-annex (E.G. The stored files should retain their normal human readable names)
+
+This requirement rules out dir and rsync special remotes, they store the files named according to their hash. I have settled on making each disc a separate repo which will satisfy this requirement.
+
+
+#Future goals:
+
+4) Easily incorporate the current DVD-Rs into the new system
+
+I haven't found a way to fulfill this goal yet. I have some convoluted ideas, but nothing so easy as mount disc, run git annex command.
+
+
+#The solution in detail
+Suppose you have the following tree:
+
+<pre>
+~/mainrepo/thing1/file1.bin
+~/mainrepo/thing1/description1.txt
+~/mainrepo/thing2/file2.bin
+~/mainrepo/thing2/description2.txt
+</pre>
+
+You want to store thing1 on disc1 and thing2 on disc2, but you'd like to keep the descriptions online because they are small and useful for figuring out which thing you want later.
+
+1) Create the main repo and annex the files:
+
+<pre>
+cd ~/mainrepo
+git init
+git annex init mainrepo
+git annex add .
+git commit -m 'added files'
+</pre>
+
+2) Create two new unrelated repos and populate them with their respective data and annex:
+
+<pre>
+cd /tmp
+mkdir disc1repo disc2repo
+cd disc1repo
+cp ~/mainrepo/thing1/* .
+git init
+git annex init disc1
+git annex add .
+git commit -m 'added files'
+cd ../disc2repo
+cp ~/mainrepo/thing2/* .
+git init
+git annex init disc2
+git annex add .
+git commit -m 'added files'
+</pre>
+
+3) This is optional, but after annexing the files in these new repos, I replace the symlinks pointing into to the .git/annex/objects/ directory with hard links. This makes the DVD-Rs usable from operating systems that can't deal with symlinks. (mkisofs handles hard links correctly)
+
+<pre>
+cd /tmp
+find disc1repo/ disc2repo/ -type l -execdir sh -c "mv -iv {} {}.symlink && ln -L {}.symlink {} && rm {}.symlink" \;
+</pre>
+
+4) Burn these repos onto DVD-Rs:
+
+<pre>
+cd /tmp
+#make isos
+mkisofs -volid disc1 -rational-rock -joliet -joliet-long -udf -full-iso9660-filenames -iso-level 3 -o disc1.iso disc1repo/
+mkisofs -volid disc2 -rational-rock -joliet -joliet-long -udf -full-iso9660-filenames -iso-level 3 -o disc2.iso disc2repo/
+#burn the isos (untested command)
+cdrecord -v -dao disc1.iso
+cdrecord -v -dao disc2.iso
+</pre>
+
+5) Mount the DVD-Rs and add as a remote and fetch, then drop from the mainrepo:
+
+<pre>
+cd ~/mainrepo
+#disc1
+mount /mnt/cdrom
+git remote add disc1 /mnt/cdrom
+git fetch disc1
+git annex drop thing1/thing1.bin
+umount /mnt/cdrom
+#disc2
+mount /mnt/cdrom
+git remote add disc2 /mnt/cdrom
+git fetch disc2
+git annex drop thing2/thing2.bin
+umount /mnt/cdrom
+</pre>
+
+6) Enjoy! You can now find out what disc things are on simply using git annex whereis, and you can git annex get them or simply use them directly from the disc.
+
+
+I'd appreciate any comments and helpful suggestions. Especially how to simplify the process or easily integrate all the things I already have stored on discs.
+
+Maybe it would be possible to create a special remote using the hooks for the DVD-Rs.
+
+Even though it is a bit tedious and complicated, the current process could be automated using a script.
diff --git a/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_10_a061d300b718ad943c940e122cc57220._comment b/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_10_a061d300b718ad943c940e122cc57220._comment
new file mode 100644
index 000000000..488e9aa7b
--- /dev/null
+++ b/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_10_a061d300b718ad943c940e122cc57220._comment
@@ -0,0 +1,23 @@
+[[!comment format=mdwn
+ username="Steve"
+ ip="92.104.175.136"
+ subject="Web remote works"
+ date="2012-11-25T22:30:46Z"
+ content="""
+Thanks for the suggestion Joey, I found a way to make the web remotes work for adding the files from existing discs. I wound up adding a symlink farm to the repo with a link for each disk pointing at the mount point. This way when I try to retrieve a file, I see the URL which contains the name of the disc:
+
+ $ git annex get bigfile.bin
+ get bigfile.bin (from web...)
+ curl: (37) Couldn't open file /var/tmp/repo/storage/dvd13/bigfile.bin
+
+ Unable to access these remotes: web
+
+ Try making some of these repositories available:
+ 00000000-0000-0000-0000-000000000001 -- web
+ failed
+ git-annex: get: 1 failed
+
+It took me a while as the version of git-annex in portage was rather old and I just didn't get around to updating git-annex on Gentoo for while. If anybody wants to get git-annex 3.20121112 running under Gentoo I detailed the process I used at <http://git-annex.mysteryvortex.com>
+
+Now I'll have to try out the assistant! (Though I didn't get the webapp to compile due to a shakespeare-js error)
+"""]]
diff --git a/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_11_76529080054407570611b4357ce4f3ed._comment b/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_11_76529080054407570611b4357ce4f3ed._comment
new file mode 100644
index 000000000..8823ecf41
--- /dev/null
+++ b/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_11_76529080054407570611b4357ce4f3ed._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="Steve"
+ ip="92.104.175.136"
+ subject="Bad ebuilds"
+ date="2012-12-01T02:45:37Z"
+ content="""
+Just an update for anybody that used the ebuilds I created from the link above. They did not create the git-annex-shell symlink which can cause git-annex to start ignoring your remotes. More details and fixed ebuilds are now on the page.
+"""]]
diff --git a/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_12_9acf5ce41a023f3848a51891cceeb51b._comment b/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_12_9acf5ce41a023f3848a51891cceeb51b._comment
new file mode 100644
index 000000000..aa742361d
--- /dev/null
+++ b/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_12_9acf5ce41a023f3848a51891cceeb51b._comment
@@ -0,0 +1,21 @@
+[[!comment format=mdwn
+ username="https://launchpad.net/~arand"
+ nickname="arand"
+ subject="comment 12"
+ date="2013-03-11T10:34:42Z"
+ content="""
+Without having read this, I've reported a very similar wishlist item at:
+[http://git-annex.branchable.com/todo/wishlist:_recursive_directory_remote_setup__47__addurl](http://git-annex.branchable.com/todo/wishlist:_recursive_directory_remote_setup__47__addurl)
+
+combining a recursive addurl (in my case using --fast) script with the suggestions regarding symlinks here, it's somewhat workable:
+
+ ln -s /media/cdrom /var/tmp/mycdrom123
+ ~/utv/scripts/annex-importdir /var/tmp/mycdrom123
+
+Ideally though, for optical media it would have a couple of more features (some already noted above):
+
+* Ability to form a (reasonably) unique identifier from a disc, using the label and the date of creation
+ * Ability for Annex to identify discs using this and ask for the correct disc if the file does not match (accomodating RW discs where label and date might change, or simply disc copies)
+ * Example: `not the original disc... trying anyway... file hash mismatch... please enable the remote disc with \"MYLABEL\" and creation date \"2001-01-01\"`
+* Option to checksum without importing the actual objects into the annex
+"""]]
diff --git a/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_1_25e65ee3949e7d918376298cf11585f2._comment b/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_1_25e65ee3949e7d918376298cf11585f2._comment
new file mode 100644
index 000000000..e406f1b6f
--- /dev/null
+++ b/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_1_25e65ee3949e7d918376298cf11585f2._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/2grhJvAC049fJnvALDXek.6MRZMTlg--#eec89"
+ nickname="John"
+ subject="Have you seen the dar utility?"
+ date="2012-10-20T19:03:37Z"
+ content="""
+http://dar.linux.free.fr/doc/index.html
+
+Would be nice to have this as another remote option for git-annex, since I too would like to have static (and possibly incrementally extended) remotes that span multiple DVDs
+"""]]
diff --git a/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_2_8a71ca048f9de29a198a6afb17d5315e._comment b/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_2_8a71ca048f9de29a198a6afb17d5315e._comment
new file mode 100644
index 000000000..abff8702e
--- /dev/null
+++ b/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_2_8a71ca048f9de29a198a6afb17d5315e._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="Steve"
+ ip="92.104.175.136"
+ subject="&quot;free-form&quot; special remote / dar utility"
+ date="2012-10-20T22:11:23Z"
+ content="""
+dar looks familiar, I'm sure I have run across it in the past. However, it is not suitable in this case; see requirement #3 above that the DVD-Rs be usable without git or git-annex.
+
+What would work we be some sort of special remote that allows free-form data. Imagine that you create the DVD-R with the files on it, then you mount it and add the mount directory as a free-form special remote. git-annex checksums all the files under the specified directory and stores the relative path to each file somewhere. Then, when you want to fetch a specific hash from the remote it looks up the relative path, adds it to the base directory and transfers it into the local .git/annex/objects/ store.
+
+"""]]
diff --git a/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_3_e3d1d3a3d3d831432ec940a8ab6f31e9._comment b/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_3_e3d1d3a3d3d831432ec940a8ab6f31e9._comment
new file mode 100644
index 000000000..973e97319
--- /dev/null
+++ b/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_3_e3d1d3a3d3d831432ec940a8ab6f31e9._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://lj.rossia.org/users/imz/"
+ ip="79.165.57.104"
+ subject="Yes, I agree, such a special remote for free-form read-only media would be convnient."
+ date="2012-10-20T23:58:45Z"
+ content="""
+I have already stored a lot of large files on DVDs. I did that for arhiving, so I cared that there are several copies. But I want this to be more automated.
+
+I take my disc (or one created by someone else, without any knowledge of Git), checksum its contents in git-annex, and in the projects where I'm using this content, I can check that the file is archived on at least N discs.
+
+Also, I might enhance the content -- this would be refected in a Git commit, so then I want also to be able to check that the new version has also ben archived on severeal discs.
+
+A special remote for such free-form read-only media would be very convenient.
+"""]]
diff --git a/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_4_26a33eae98b4faaf6baf6635e3d28a8f._comment b/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_4_26a33eae98b4faaf6baf6635e3d28a8f._comment
new file mode 100644
index 000000000..44d547dd9
--- /dev/null
+++ b/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_4_26a33eae98b4faaf6baf6635e3d28a8f._comment
@@ -0,0 +1,27 @@
+[[!comment format=mdwn
+ username="Steve"
+ ip="92.104.175.136"
+ subject="Some free-form remote ideas"
+ date="2012-10-21T02:07:40Z"
+ content="""
+This is starting to get interesting. A free-form remote would definitely simplify my use case, and also solve the \"future goal\" of easily incorporating my already existing DVD-Rs.
+
+I haven't really looked into the git-annex internals up to this point, but looking at the [[special_remotes/hook]] page there doesn't seem to be a hook for init which would be needed to populate git-annex's index of files in the remote. (git-annex seems to assume that new special remotes are empty)
+
+Another problem is where to store the hash to path relation information. On a RW remote it would be stored in the remote, but here we need to keep it in the repo somehow. This could be in the git-annex branch, or possibly another branch created specifically for this purpose.
+
+1) initremote needs to:
+
+* hash the contents of all the remote's files
+* update git-annex's index of the remote's contents
+* store the paths to the hashes in the repo
+
+2) store and remove should just fail.
+
+3) retrieve and check present seem straight forward.
+
+The assistant blog mentions adding support for read only remotes but I don't know anything about it: [[design/assistant/blog/day_65__transfer_polish]] (I'm still on 3.20120605)
+
+Let me know if there is anything I haven't thought of yet.
+
+"""]]
diff --git a/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_5_49ac298d39c824b0e52a239961463e09._comment b/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_5_49ac298d39c824b0e52a239961463e09._comment
new file mode 100644
index 000000000..b06891cd8
--- /dev/null
+++ b/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_5_49ac298d39c824b0e52a239961463e09._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.23"
+ subject="comment 5"
+ date="2012-10-21T05:36:36Z"
+ content="""
+I encourage playing around with the hook special remote and see how far you can make it go.
+
+I may be doing something vaguely like this for [[design/assistant/desymlink]], although I'm pretty sure it would still have a git repository associated with the directory of regular files.
+
+One option is to use the web special remote, with file:// urls. Assuming a given disc will always end up mounted somewhere stable, such as /media/dvd1, /media/dvd2, etc, you could then just `git annex addurl file:///media/dvd1/$file`. `git annex whereis` will show the url, which has enough info to work out the disk to mount.
+
+The web special remote did not support file:// urls, but I've just fixed that. The only downside is that, while it will identify files duplicated across disks, and `whereis` will show multiple urls for such files, there's only one web special remote, and so it only counts as 1 copy. This could perhaps be improved; git-annex may eventually get support for remotes reporting how many copies of a file they contain.
+"""]]
diff --git a/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_6_55a4a3616ea59654da1c2f9902561e3b._comment b/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_6_55a4a3616ea59654da1c2f9902561e3b._comment
new file mode 100644
index 000000000..ab971dab5
--- /dev/null
+++ b/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_6_55a4a3616ea59654da1c2f9902561e3b._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://www.openid.albertlash.com/openid/"
+ ip="74.96.185.87"
+ subject="It works!"
+ date="2012-10-24T22:00:31Z"
+ content="""
+This works great! I first tried it with WORM, no-go. I can see why the SHA backends are so powerful, they appear to circumvent the commits which git usually uses for merging. When I first do the merge, it reports this:
+
+warning: no common commits
+
+Compared to how I've managed CD/DVD backups in the past, this is a quantum leap forward, and I don't find it convoluted in comparison. Yes, there is dar, but I prefer this method. In my case, its the perfect solution for original files, which in generally are treated as immutable, and not accessed very often. They are usually large, too! I'm using them for digital pictures.
+
+"""]]
diff --git a/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_7_92a2af3e0e328bb48bcc67a69187ee57._comment b/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_7_92a2af3e0e328bb48bcc67a69187ee57._comment
new file mode 100644
index 000000000..736fc6ce2
--- /dev/null
+++ b/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_7_92a2af3e0e328bb48bcc67a69187ee57._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="Steve"
+ ip="92.104.175.136"
+ subject="web and hook special remotes"
+ date="2012-10-24T23:26:53Z"
+ content="""
+Hi Joey,
+
+Thanks for the advice. I had thought of the web special remote; but as you may have noticed from my example, I don't use automount so my DVDs and CDs all get mounted in the same place. (/mnt/cdrom) so the web special remote won't work for me.
+
+I'll try to play around with the hook special remote this weekend. I had a thought it might be interesting to have it search for the DVDs in some common places or even by parsing the mounted file systems, and allow an override or augmentation through git config.
+
+"""]]
diff --git a/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_8_f6e39e71882d55cdc061166aea3e2bd3._comment b/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_8_f6e39e71882d55cdc061166aea3e2bd3._comment
new file mode 100644
index 000000000..84705d4cd
--- /dev/null
+++ b/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_8_f6e39e71882d55cdc061166aea3e2bd3._comment
@@ -0,0 +1,26 @@
+[[!comment format=mdwn
+ username="Steve"
+ ip="92.104.175.136"
+ subject="no need to merge"
+ date="2012-10-24T23:52:30Z"
+ content="""
+Albert,
+
+Thanks for feedback! I'm glad that somebody else found the method I worked out useful. As I'm going to try and turn it into a proper special remote, let me know if there is any particular use case or feature you'd like me to address.
+
+Note that in my testing, I found that you don't actually need to merge the DVD's branch into the local branch you are using for git annex to be able to find the files on it that are identical to files in your local branch.
+
+I haven't played around with cloning the repo, but I will try that this weekend. I'm thinking it *might* be necessary to create local branches from the DVD remotes so that they'll get carried along when you clone the repo.
+
+As far as the repos on the DVD's not having a shared ancestry with main repo, that was a conscious choice that I made. I wanted to add as little extra data to the DVDs as possible since I usually fill them to the brim anyway. I didn't feel that it would be beneficial for the DVD's to know about the history of the main repo and other files that they don't contain. Furthermore, besides all the links and history, you'd be replicating all the files in the main repo that aren't annexed.
+
+If you want to avoid the error, but still have a local branch for the DVD repos you should be able to do something like the following:
+
+<b>WARNING:</b> these commands are untested!
+<pre>
+git checkout -b disc1 disc1/master
+git checkout -b disc2 disc2/master
+</pre>
+
+Working from the original example, you should then get local branches for the DVDs that don't have a common ancestor with your master local repo. I haven't actually tested that though. Testing will have to wait for this weekend.
+"""]]
diff --git a/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_9_6c45a6264d69e22800c329a0f8a2d470._comment b/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_9_6c45a6264d69e22800c329a0f8a2d470._comment
new file mode 100644
index 000000000..5a3f2885c
--- /dev/null
+++ b/doc/forum/Managing_a_large_number_of_files_archived_on_many_pieces_of_read-only_medium___40__E.G._DVDs__41__/comment_9_6c45a6264d69e22800c329a0f8a2d470._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.138"
+ subject="comment 9"
+ date="2012-10-25T03:33:29Z"
+ content="""
+@Steve, it seems to me you could still use the web special remote, just pointing it at an url that goes through a symlink to the mount point.
+"""]]
diff --git a/doc/forum/Managing_multiple_annexes_with_assistant__63__.mdwn b/doc/forum/Managing_multiple_annexes_with_assistant__63__.mdwn
new file mode 100644
index 000000000..30e059743
--- /dev/null
+++ b/doc/forum/Managing_multiple_annexes_with_assistant__63__.mdwn
@@ -0,0 +1,13 @@
+Is it possible to run more than one instance of the assistant in an account?
+
+A particular example is that I might have two annexes:
+
+1. for my music, and
+2. for some personal documents.
+
+I would like to have my music annex paired with my work laptop and have all the automagical power of git-annex-assistant working for me. However I don't want to put my personal documents on a work machine, hence the second annex.
+
+(I think) An ideal world would have the assistant managing both annexes. Is this possible?
+
+
+I know my question is similar to [one annex versus many annexes?](http://git-annex.branchable.com/forum/one_annex_versus_many_annexes__63__/) but I think it is different enough to warrant a new thread...
diff --git a/doc/forum/Managing_multiple_annexes_with_assistant__63__/comment_1_ba8c70e4a46441b48ad910625636eee5._comment b/doc/forum/Managing_multiple_annexes_with_assistant__63__/comment_1_ba8c70e4a46441b48ad910625636eee5._comment
new file mode 100644
index 000000000..675b5b71c
--- /dev/null
+++ b/doc/forum/Managing_multiple_annexes_with_assistant__63__/comment_1_ba8c70e4a46441b48ad910625636eee5._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.23"
+ subject="comment 1"
+ date="2012-10-19T17:08:39Z"
+ content="""
+If you go to the upper-right menu in the webapp, and select \"New repository\", you can add a separate independant repository. The assistant's autostart will run it on both of them when you log in.
+"""]]
diff --git a/doc/forum/Managing_multiple_annexes_with_assistant__63__/comment_2_4b4f0a7d84a51ae92536e2c190256069._comment b/doc/forum/Managing_multiple_annexes_with_assistant__63__/comment_2_4b4f0a7d84a51ae92536e2c190256069._comment
new file mode 100644
index 000000000..86fa9ebab
--- /dev/null
+++ b/doc/forum/Managing_multiple_annexes_with_assistant__63__/comment_2_4b4f0a7d84a51ae92536e2c190256069._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkk3K0AUduAybbBO_LRRGKOe2zcGeezbzI"
+ nickname="Nathan"
+ subject="Webapp spins when adding a second annex"
+ date="2012-11-20T04:55:05Z"
+ content="""
+I was trying to add a second annex (repository) via the webapp, but it seems like the process never completes: the browser just spins (\"connecting...\"). If I kill the webapp process and restart, I can see the second annex in the list of repositories, but clicking on it gives the same behaviour. Interestingly, the path *is* added to ~/.config/git-annex/autostart, and the webapp does create the path, if needed, and initializes it as a git annex. I've reproduced this on two different machines, both running Ubuntu 12.10 and git annex 3.20121112.
+
+Is there anything I can do to help debug?
+"""]]
diff --git a/doc/forum/Managing_multiple_annexes_with_assistant__63__/comment_3_86daadc565f96db5db13b6dbcbc66db3._comment b/doc/forum/Managing_multiple_annexes_with_assistant__63__/comment_3_86daadc565f96db5db13b6dbcbc66db3._comment
new file mode 100644
index 000000000..6ad879d76
--- /dev/null
+++ b/doc/forum/Managing_multiple_annexes_with_assistant__63__/comment_3_86daadc565f96db5db13b6dbcbc66db3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.49"
+ subject="comment 3"
+ date="2012-11-25T18:59:37Z"
+ content="""
+@Nathan at this point, you should have two separate git-annex processes running, one for each repository. You can try opening a shell, changing to the new repository, and running `git annex webapp --debug` to get debugging information on the new one.
+"""]]
diff --git a/doc/forum/Managing_multiple_annexes_with_assistant__63__/comment_4_e43d71ddfdfdb7bcb13bfb894de6a5ec._comment b/doc/forum/Managing_multiple_annexes_with_assistant__63__/comment_4_e43d71ddfdfdb7bcb13bfb894de6a5ec._comment
new file mode 100644
index 000000000..78570a08d
--- /dev/null
+++ b/doc/forum/Managing_multiple_annexes_with_assistant__63__/comment_4_e43d71ddfdfdb7bcb13bfb894de6a5ec._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.49"
+ subject="comment 4"
+ date="2012-11-28T20:13:11Z"
+ content="""
+@Nathan, I have just noticed and fixed a problem that could cause this to happen if you were using the standalone tarball (or OSX app) builds. It would not affect git-annex installed by other methods.
+"""]]
diff --git a/doc/forum/Managing_multiple_annexes_with_assistant__63__/comment_5_e94d33be83b45918d1a39d6e16fba4b4._comment b/doc/forum/Managing_multiple_annexes_with_assistant__63__/comment_5_e94d33be83b45918d1a39d6e16fba4b4._comment
new file mode 100644
index 000000000..ae9c5c5b6
--- /dev/null
+++ b/doc/forum/Managing_multiple_annexes_with_assistant__63__/comment_5_e94d33be83b45918d1a39d6e16fba4b4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkk3K0AUduAybbBO_LRRGKOe2zcGeezbzI"
+ nickname="Nathan"
+ subject="comment 5"
+ date="2012-12-11T04:15:49Z"
+ content="""
+Thanks, Joey; I was using the standalone build, and it seems to be behaving better now.
+"""]]
diff --git a/doc/forum/Managing_multiple_repositories_concurrently__63__.mdwn b/doc/forum/Managing_multiple_repositories_concurrently__63__.mdwn
new file mode 100644
index 000000000..60942584b
--- /dev/null
+++ b/doc/forum/Managing_multiple_repositories_concurrently__63__.mdwn
@@ -0,0 +1,5 @@
+I have the webapp setup to manage 4 different repositories.
+
+One repository had many gigabytes to upload to a remote. As this was moving along, I wanted to check on the status of one of the other repositories. I knew that this second repository had a lot of data to download. When I switched to the second repo in the webapp, I noticed in my network monitor that the amount of upstream bandwidth I was using dropped and the amount of downstream bandwidth increased. I switched back to the first repo, and my downstream bandwidth dropped and the upstream bandwidth increased.
+
+It looks like git-annex stopped uploading data from the first repo when I switched to the second, and stopped downloading data to the second repo when I switched to the first. Is this correct? I was under the impression that switching repositories in the webapp simply changed the view that I was looking at, but that the assistant would still be managing all the repositories I had setup -- uploading/downloading/syncing concurrently.
diff --git a/doc/forum/Managing_multiple_repositories_concurrently__63__/comment_1_ebec1ddad71e961cdc9b21cbddfbcdaf._comment b/doc/forum/Managing_multiple_repositories_concurrently__63__/comment_1_ebec1ddad71e961cdc9b21cbddfbcdaf._comment
new file mode 100644
index 000000000..c1c5cd917
--- /dev/null
+++ b/doc/forum/Managing_multiple_repositories_concurrently__63__/comment_1_ebec1ddad71e961cdc9b21cbddfbcdaf._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-03-17T18:53:26Z"
+ content="""
+Each repository gets its own git-annex assistant daemon, which is entirely separate from the daemons used by other repositories.
+
+The only affect that switching which repository is in view in the webapp can have is it can start a daemon running on a repository that for some reason did not already have the daemon running. This could happen if it was not set to autostart on login, for example.
+"""]]
diff --git a/doc/forum/Manual_Setup_of_a_Central_Repo.mdwn b/doc/forum/Manual_Setup_of_a_Central_Repo.mdwn
new file mode 100644
index 000000000..82a1c70ba
--- /dev/null
+++ b/doc/forum/Manual_Setup_of_a_Central_Repo.mdwn
@@ -0,0 +1 @@
+My current setup involves 3 computers, one desktop one laptop and a vps. In my current setup I have created annex repos on the server and cloned from it, both machines sync to the server. All three use non base repos. Now I have another annex folder on the desktop that I would like to sync between the three. Both machines are behind NAT so server can not communicate with the machines. In order to init the repo on the vps, I was thinking of setting up a temporary VPN/port forward between the desktop and the VPS then clone from the desktop finally remove the remote section in .git/config on the server so VPS becomes the master again. First of all is there an easier way to do this? if not is it safe to do this? or is it going to cause problems down the line.
diff --git a/doc/forum/Manual_Setup_of_a_Central_Repo/comment_1_3a163fd5629dc40423f1290a78ae1c07._comment b/doc/forum/Manual_Setup_of_a_Central_Repo/comment_1_3a163fd5629dc40423f1290a78ae1c07._comment
new file mode 100644
index 000000000..e5630b331
--- /dev/null
+++ b/doc/forum/Manual_Setup_of_a_Central_Repo/comment_1_3a163fd5629dc40423f1290a78ae1c07._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 1"
+ date="2013-08-26T18:46:06Z"
+ content="""
+You could certainly do that. I don't think it's the easiest way.
+
+Note that this is essentially a git question. It really has nothing to do with git-annex, unless you want to use the git-annex assistant, which can sync a repository over XMPP without needing a central git repository at all.
+
+If I had this problem with git in general, I would make a new empty repository on the server, and push the local repository I have on the one machine to it. Then on the other machine, I would clone from the server. Problem solved, I think?
+"""]]
diff --git a/doc/forum/Manual_mode_option_in_assistant_auto-syncs.mdwn b/doc/forum/Manual_mode_option_in_assistant_auto-syncs.mdwn
new file mode 100644
index 000000000..49b58e529
--- /dev/null
+++ b/doc/forum/Manual_mode_option_in_assistant_auto-syncs.mdwn
@@ -0,0 +1,11 @@
+Hi,
+
+I've recently set-up a server which uses Southpaw's Tactic DAM system and I've initialised a git-annex directory using the assistant which will manage any files which Tactic puts into the git-annex. I plan to make some remote repositories to Amazon S3, friends and some local machines on my home network. The server is running Ubuntu 64-bit and so I've written an upstart job which runs 'git-annex assistant --autostart' as the user 'git-annex' as this user doesn't log-in and run the xdg autostart .desktop at all.
+
+I saw that you can set the purpose of each repository which it will sync to and noticed 'Manual Mode.' From the description, it seems it will only work if I do explicit git-annex commands to it which would be perfect for me as I'd like to write tools which run git-annex add/get/drop/etc. manually on some remotes like ones to friends as I don't want them to sync to everything or any files that they produce, only files which they request with a special tool that I'll write and have Tactic marshal the file changes/names/etc.
+
+I've set those remotes to manual-mode via the assistant and tried copying a file to the remote's directory, but it auto-synced the file anyway. Maybe I'm getting confused at how manual mode works but I'd like to only explicitly set which files to add to the repo by a command and not just 'any' file which gets placed into that directory. If this is more of a wishlist request I guess just move this post into there and I'll reword it as a wish request.
+
+I don't need to use the assistant if that makes more sense, but I would like to be able to still monitor things as the webapp makes for a great GUI to check for that stuff. I can't wait for the https version of webapp too, I currently run git-annex webapp --listen=<ip>:<port> and then run the link it outputs on my desktop machine to manage it from the server.
+
+Thanks, and this is such a great bit of software, especially as my Internet connection is really bad for 2013 standards, and having the option for friends/remote servers to sync up via an encrypted S3 or box.com account is great!
diff --git a/doc/forum/Manual_mode_option_in_assistant_auto-syncs/comment_1_4a0468b6ca2ffff8ef8f19800597567d._comment b/doc/forum/Manual_mode_option_in_assistant_auto-syncs/comment_1_4a0468b6ca2ffff8ef8f19800597567d._comment
new file mode 100644
index 000000000..56e68f779
--- /dev/null
+++ b/doc/forum/Manual_mode_option_in_assistant_auto-syncs/comment_1_4a0468b6ca2ffff8ef8f19800597567d._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 1"
+ date="2013-08-24T16:20:29Z"
+ content="""
+In the assistant, putting a repository in manual mode prevents the assistant from automatically downloading every file that is added to other clones of the repository. As you've noticed, it does not prevent the assistant from automatically adding new files that are put into the local repository, or from uploading those files to other clients that want them (ie, clients not themselves set to use manual mode).
+
+You can prevent the assistant from noticing when you add new files to a repository by clicking on \"syncing enabled\" in the first repository in the list. (The repository labeled as \"here\".) You can then `git annex add` the files you want to add by hand, and manually `copy annex copy` them to other repositories, and manually `git annex sync`.
+"""]]
diff --git a/doc/forum/Manual_webapp_behaviour_on_ARM.mdwn b/doc/forum/Manual_webapp_behaviour_on_ARM.mdwn
new file mode 100644
index 000000000..8b7b8fe27
--- /dev/null
+++ b/doc/forum/Manual_webapp_behaviour_on_ARM.mdwn
@@ -0,0 +1,15 @@
+Hello,
+
+I have a Samsung ARM Chromebook running Ubuntu with crouton (chroot in chromeos). I want to use git-annex, and add the chromebook as a second "device" to my already set up git-annex repo on my main pc. That repo is one folder set up with the assistant, and it has one encrypted ssh(rsync) remote.
+
+I've read that the webapp is not available on ARM, and I've also found a topic with a simple script to replicate git-annex-assistant steps: http://git-annex.branchable.com/forum/Running_assistant_steps_manually/. So, I've used the `cabal` steps to install git-annex manually, which is working.
+
+I want to use git-annex in a dropbox-like fashion, folder and file sync between these two devices (and maybe later on another encrypted ssh remote). However I'm in need of some guidance regarding the command line usage and such.
+
+My questions are:
+
+- How do I "add" the chromebook repo to the existing git-annex setup?
+- The machines are not on at the same time. One is my main workstation and the chromebook is my "mobile friend". The encrypted ssh remote is on a VPS, that is always on.
+ - How do I configure the syncing between the main machine, the chromebook and the encrypted ssh remote on the vps? If possible, bi-directional.
+
+If it is possible, both explanation and command line examples would help a lot.
diff --git a/doc/forum/Missing_git-annex.linux__47__runshell.mdwn b/doc/forum/Missing_git-annex.linux__47__runshell.mdwn
new file mode 100644
index 000000000..3ad7e85c1
--- /dev/null
+++ b/doc/forum/Missing_git-annex.linux__47__runshell.mdwn
@@ -0,0 +1,44 @@
+Hi,
+
+I've said up two clients to sync locally as well as over ssh-rsync.
+
+However, locally one client is complaining about missing `runshell` at a location where `git annex` is not installed. The log is below. On the assistent overview it just says "unfinished repository". Note that I am able to ssh into the other machine and from the other machine I'm also able to ssh into this machine.
+
+
+I'm using the latest prebuild binary package (git-annex-bin at Archlinux AUR). So my `git annex` setup contains
+
+ $> pacman -Ql git-annex-bin
+ git-annex-bin /usr/
+ git-annex-bin /usr/bin/
+ git-annex-bin /usr/bin/git-annex
+ git-annex-bin /usr/bin/git-annex-shell
+
+ $> pacman -Qi git-annex-bin # with chops
+ Name : git-annex-bin
+ Version : 4.20130909-1
+ Description : Precompiled version of git-annex, webapp and assistant
+ included.
+ Architecture : x86_64
+
+Here is a log of one event where it fails to transfer.
+
+ [2013-09-28 18:06:38 CEST] TransferScanner: queued Upload NoUUID config/emacs.d/ac-l-dict/amsmath-c-a-* Nothing : expensive scan found missing object
+ [2013-09-28 18:06:38 CEST] Transferrer: Transferring: Upload NoUUID config/dotfiles/stardict/dic/stardict-oxford-2.4.2/oxford.ifo Nothing
+ [2013-09-28 18:06:38 CEST] call: git-annex ["transferkeys","--readfd","96","--writefd","94"]
+ [2013-09-28 18:06:38 CEST] read: git ["--git-dir=/home/rasmus/annex/.git","--work-tree=/home/rasmus/annex","show-ref","git-annex"]
+ [2013-09-28 18:06:38 CEST] read: git ["--git-dir=/home/rasmus/annex/.git","--work-tree=/home/rasmus/annex","show-ref","--hash","refs/heads/git-annex"]
+ [2013-09-28 18:06:38 CEST] read: git ["--git-dir=/home/rasmus/annex/.git","--work-tree=/home/rasmus/annex[","log2","0r1e3f-s/0h9e-ad2s8/ g1i8t-annex..90df78a0910a6f2998655e6:06:38 CEST] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (X11; Linux x86_64; rv:26.0) Gecko/20100101 Firefox/26.0 Aurora/26.0a2
+ ea47d478ea0589b54","--oneline","-n1"]
+ [2013-09-28 18:06:38 CEST] read: git ["--git-dir=/home/rasmus/annex/.git","--work-tree=/home/rasmus/annex","log","refs/heads/git-annex..5f6870ed24e5ded1764765bbfef2b85aff046569","--oneline","-n1"]
+ [2013-09-28 18:06:38 CEST] chat: git ["--git-dir=/home/rasmus/annex/.git","--work-tree=/home/rasmus/annex","cat-file","--batch"]
+ [2013-09-28 18:06:38 CEST] read: ssh ["-S","/home/rasmus/annex/.git/annex/ssh/00b8ef4cb08290718ba625d9bd86ca0b","-o","ControlMaster=auto","-o","ControlPersist=yes","-T","rasmus@git-annex-192.168.1.107-rasmus_annex","git-annex-shell 'configlist' '/~/annex/'"]
+ /home/rasmus/.ssh/git-annex-shell: line 4: /opt/git-annex.linux/runshell: No such file or directory
+ [2013-09-28 18:06:38 CEST] call: git ["--git-dir=/home/rasmus/annex/.git","--work-tree=/home/rasmus/annex","fetch","--quiet","192.168.1.107_annex"]
+ [2013-09-28 18:06:38 CEST] 127.0.0.1 GET /transfers/NotificationId%201 Mozilla/5.0 (X11; Linux x86_64; rv:26.0) Gecko/20100101 Firefox/26.0 Aurora/26.0a2
+ [2013-09-28 18:06:38 CEST] 127.0.0.1 GET /log Mozilla/5.0 (X11; Linux x86_64; rv:26.0) Gecko/20100101 Firefox/26.0 Aurora/26.0a2
+ /home/rasmus/.ssh/git-annex-shell: line 4: /opt/git-annex.linux/runshell: No such file or directory
+ fatal: Could not read from remote repository.
+
+ Please make sure you have the correct access rights
+ and the repository exists.
+ git-annex: Unknown UUID
diff --git a/doc/forum/Missing_git-annex.linux__47__runshell/comment_1_f29a5105649579ef15e79d983c4e1f8e._comment b/doc/forum/Missing_git-annex.linux__47__runshell/comment_1_f29a5105649579ef15e79d983c4e1f8e._comment
new file mode 100644
index 000000000..a10c4aaf0
--- /dev/null
+++ b/doc/forum/Missing_git-annex.linux__47__runshell/comment_1_f29a5105649579ef15e79d983c4e1f8e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.80"
+ subject="comment 1"
+ date="2013-09-30T16:08:40Z"
+ content="""
+You apparently at one point installed git-annex from the prebuilt tarball, in `/opt/git-annex.linux/`. It set up a ~/.ssh/git-annex-shell that points to this location. If you no longer have it installed that way, you can remove that file.
+"""]]
diff --git a/doc/forum/Moving_large_files_within_the_repo_without_copying___63__.mdwn b/doc/forum/Moving_large_files_within_the_repo_without_copying___63__.mdwn
new file mode 100644
index 000000000..55d51f21d
--- /dev/null
+++ b/doc/forum/Moving_large_files_within_the_repo_without_copying___63__.mdwn
@@ -0,0 +1,19 @@
+Is there a way to move a large file without "git annex unlock"ing it (Which takes very long for copying and then rehashing the file)?
+Using a simple "mv" or "git mv" results in broken symlinks, if the target directory is on a different hierarchy level:
+
+Example:
+
+Initial State:
+
+ $ ls -Hl Pictures:
+ Pictures/showImages.jpg -> ../.git/annex/objects/90/32/SHA1-s8737--a8bfb285d0ae394cb75c86f1eb9f703fb678a51e/SHA1-s8737--a8bfb285d0ae394cb
+
+Move:
+
+ $ mv Pictures/showImages.jpg .
+
+Result:
+
+ $ ls -H showImages.jpg
+ ls: cannot access showImages.jpg: No such file or directory
+
diff --git a/doc/forum/Moving_large_files_within_the_repo_without_copying___63__/comment_1_9e3290138133d5a23a80f72342f47ec4._comment b/doc/forum/Moving_large_files_within_the_repo_without_copying___63__/comment_1_9e3290138133d5a23a80f72342f47ec4._comment
new file mode 100644
index 000000000..d1df9cf51
--- /dev/null
+++ b/doc/forum/Moving_large_files_within_the_repo_without_copying___63__/comment_1_9e3290138133d5a23a80f72342f47ec4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn7gQ1zZDdWhXy9H51W2krZYShNmKL3qfM"
+ nickname="Karsten"
+ subject="comment 1"
+ date="2012-11-28T13:28:21Z"
+ content="""
+Just commit, git-annex will fix the symlinks. Or do it manually with 'git annex fix'.
+"""]]
diff --git a/doc/forum/Moving_large_files_within_the_repo_without_copying___63__/comment_2_232b77894dda51d02cbc34bd25d3213b._comment b/doc/forum/Moving_large_files_within_the_repo_without_copying___63__/comment_2_232b77894dda51d02cbc34bd25d3213b._comment
new file mode 100644
index 000000000..0559e7954
--- /dev/null
+++ b/doc/forum/Moving_large_files_within_the_repo_without_copying___63__/comment_2_232b77894dda51d02cbc34bd25d3213b._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlgyVag95OnpvSzQofjyX0WjW__MOMKsl0"
+ nickname="Sehr"
+ subject="Does not work"
+ date="2012-11-28T14:50:16Z"
+ content="""
+ $ git annex fix
+
+Does not change anything. and
+
+ $ git annex fix showImages.jpg
+ git-annex: showImages.jpg not found
+"""]]
diff --git a/doc/forum/Moving_large_files_within_the_repo_without_copying___63__/comment_3_d35ac1bdb3fa6e303ad92348ba174158._comment b/doc/forum/Moving_large_files_within_the_repo_without_copying___63__/comment_3_d35ac1bdb3fa6e303ad92348ba174158._comment
new file mode 100644
index 000000000..d4d25a705
--- /dev/null
+++ b/doc/forum/Moving_large_files_within_the_repo_without_copying___63__/comment_3_d35ac1bdb3fa6e303ad92348ba174158._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn7gQ1zZDdWhXy9H51W2krZYShNmKL3qfM"
+ nickname="Karsten"
+ subject="comment 3"
+ date="2012-11-28T15:03:42Z"
+ content="""
+In my tests 'git annex fix' works only on symlinks in directories alredy known to git. So if you created a new directory inside your annex, be sure to 'git add' the directory before running 'git annex fix'.
+
+HTH,
+Karsten
+"""]]
diff --git a/doc/forum/Moving_large_files_within_the_repo_without_copying___63__/comment_4_4b443ec6b47eaabe214d0c2222083e4a._comment b/doc/forum/Moving_large_files_within_the_repo_without_copying___63__/comment_4_4b443ec6b47eaabe214d0c2222083e4a._comment
new file mode 100644
index 000000000..cf09b261a
--- /dev/null
+++ b/doc/forum/Moving_large_files_within_the_repo_without_copying___63__/comment_4_4b443ec6b47eaabe214d0c2222083e4a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlgyVag95OnpvSzQofjyX0WjW__MOMKsl0"
+ nickname="Sehr"
+ subject="comment 4"
+ date="2012-11-28T15:14:49Z"
+ content="""
+Thanks. It seems that the file itself has to be added to git annex to be able to bet git annex fixed!
+"""]]
diff --git a/doc/forum/Moving_older_version__39__s_file_content_without_doing_checkout.mdwn b/doc/forum/Moving_older_version__39__s_file_content_without_doing_checkout.mdwn
new file mode 100644
index 000000000..3ed022b48
--- /dev/null
+++ b/doc/forum/Moving_older_version__39__s_file_content_without_doing_checkout.mdwn
@@ -0,0 +1,4 @@
+Hi,
+Is there any way I can move or copy file content of older version without doing checkout to that version, by passing commit hash as parameter in move command itself?
+
+Thank you
diff --git a/doc/forum/Moving_older_version__39__s_file_content_without_doing_checkout/comment_1_f114b75b29123453758b493fae7f5167._comment b/doc/forum/Moving_older_version__39__s_file_content_without_doing_checkout/comment_1_f114b75b29123453758b493fae7f5167._comment
new file mode 100644
index 000000000..a53c6bbd6
--- /dev/null
+++ b/doc/forum/Moving_older_version__39__s_file_content_without_doing_checkout/comment_1_f114b75b29123453758b493fae7f5167._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnpdM9F8VbtQ_H5PaPMpGSxPe_d5L1eJ6w"
+ nickname="Rafael"
+ subject="comment 1"
+ date="2012-05-15T07:59:57Z"
+ content="""
+I had a similiar question in forum/new_microfeatures/. I would like to fetch/copy all the annexed content from a repo, be it on the current branch, another branch, or corresponds to an old version of a file. A command like \"git annex copy --all --from=source [path]\" would then ensure I have access to all the content I need even if I have later no longer access to source. Sure I could use rsync.
+"""]]
diff --git a/doc/forum/Moving_older_version__39__s_file_content_without_doing_checkout/comment_2_e377b7614c2961b460a10e285f3db274._comment b/doc/forum/Moving_older_version__39__s_file_content_without_doing_checkout/comment_2_e377b7614c2961b460a10e285f3db274._comment
new file mode 100644
index 000000000..18ff153ad
--- /dev/null
+++ b/doc/forum/Moving_older_version__39__s_file_content_without_doing_checkout/comment_2_e377b7614c2961b460a10e285f3db274._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.2.51"
+ subject="comment 2"
+ date="2012-05-15T17:00:10Z"
+ content="""
+Yes, I think that [[todo/add_-all_option]] is the right approach for this. Seems unlikely you'd have some files' hashes handy without having them checked out, but operating on all content makes sense.
+
+That page discusses some problems implementing it for some commands, but should not pose a problem for `move`. It would also be possible to support `get` and `copy`, except `--auto` couldn't be used with `--all`. Even `fsck` could support it.
+"""]]
diff --git a/doc/forum/Moving_older_version__39__s_file_content_without_doing_checkout/comment_3_d251958795ab0867c65cf182e54a6ffe._comment b/doc/forum/Moving_older_version__39__s_file_content_without_doing_checkout/comment_3_d251958795ab0867c65cf182e54a6ffe._comment
new file mode 100644
index 000000000..63d1e6800
--- /dev/null
+++ b/doc/forum/Moving_older_version__39__s_file_content_without_doing_checkout/comment_3_d251958795ab0867c65cf182e54a6ffe._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.193"
+ subject="comment 3"
+ date="2013-07-03T18:10:29Z"
+ content="""
+Now the --all option is built. You can, for example, run `git annex copy --all --to backup`
+"""]]
diff --git a/doc/forum/My_first_impressions_after_some_weeks_with_git-annex_assistant.mdwn b/doc/forum/My_first_impressions_after_some_weeks_with_git-annex_assistant.mdwn
new file mode 100644
index 000000000..0614554ad
--- /dev/null
+++ b/doc/forum/My_first_impressions_after_some_weeks_with_git-annex_assistant.mdwn
@@ -0,0 +1,57 @@
+This post is a personal story, a bug report, and a feature request.
+
+I discovered `git-annex assistant` by accident a couple of weeks (months?) ago. I was very impressed by the technical smartness and decided it was worth a try. My current configuration (everything done through the assistant web GUI) is:
+
+* Two machines that act as client repositories and are usually in the same LAN. Both of them run OS X Mountain Lion.
+* One transfer repository which was Box.com, but then I switched to Amazon S3 (today, I’ll explain why).
+* The repository consists of mixed files and is ~4 GB big (very small plain text files, PDFs, some MP3 files, the biggest files are about 20–50 MB). The Finder reports that the repository is ~40 GB big while `du -sh` reports 4.4 GB. It’s probably just a silly Finder bug, but it would be great to know why this happens.
+* I have version 4.20130324 on both clients. The OS X versions seems to be always a little bit behind. It would be great if it could match with other platforms.
+
+Here are some issues which I think are worth mentioning:
+
+1. I had some issues with the assistant, because I initially launched it from the mounted DMG. `git-annex assistant` set the environment up, but it configured the wrong paths (to `/Volumes` instead `/Applications` where the bundle later went). This has caused issues with authentication and some ssh keys. `git-annex` was confused which keys to use and I had to manually remove the first ones from the `.ssh/` directory. This could be very confusing for technically not so savvy users, because the error messages in the GUI were confusing.
+
+2. I’m still very confused about the behavior of `git-annex assistant` when it launches. The application icon bounces in the Dock for quite a long time, then it looks like the process would’ve crashed (I can only *Force Quit* it from the Dock). Then the icon disappears after some minutes / half an hour. I was unsure if the assistant would run if I would *Force Quit* it (yes). The behavior is very strange on OS X. It would be great to have at least a normal icon which bounces a couple of times, stays in the Dock without appearing like a non-responding app, and that launches the web GUI when a user clicks on it. Optimal would be just a menu bar icon which would show the current progress, let me launch the web GUI, check for updates, pause & resume all transfers, and restart & quit `git-annex assistant`.
+
+3. The initial sync went great and pretty fast. I was also impressed by the speed `git-annex` picks up new changes and synchronizes them to other repositories. After adding the Box.com transfer repository everything got worse. Files that were added to one of the client repositories were never synced to the other machine, despite making sure that the client repositories appeared above the Box.com repository in `git-annex assistant`. The transfer was very slow (that’s probably due to the API rate limits of Box.com) and I got the impression that the files were uploaded multiple times (probably true, because the assistant couldn’t upload them in the first place and then just tried it again giving me the impression that it was stuck in some kind of loop). I tried to manually click on a couple of hundred play buttons in the queue in the hope that there would somewhere appear the item which should’ve been synced to the other machine in the first place. I also attached some log messages to the end of this post which could be helpful. At this point `git-annex assistant` basically stopped working for me. I lived somehow with it in the hope that it would upload everything to Box.com in the upcoming days, but it never got better, even after a couple of weeks (in the meantime we copied files manually over an attached network storage which lived outside of the repository). Today I bit the bullet and switched to Amazon S3. All files were uploaded in a couple of minutes and it looks like this setup would be more reliable. It’ll cost us a couple of $ each month, but it’s OK, because it actually works.
+
+4. I read somewhere that transfer repositories where meant to keep only files that are not present on all client repositories. With my configuration `git-annex` just uploads everything to the transfer repository (no matter if it’s Box.com or Amazon S3). Is this the correct behavior? Did I get something wrong or is this just not implemented yet? It’s OK in the current version, but it would be great to store only the missing files in the future.
+
+5. After I switched to Amazon S3 some encrypted file names appear in my queue. They are gone after I restart `git-annex assistant` or when I manually remove them with the `X` button. Is this a bug?
+
+6. It is confusing that the web GUI shows that the transfer failed when the second machine is offline. While technically this is true, it would be much more assuring to know that the client is just offline. If something fails I get the impression that it is broken, but the client was only unreachable and that’s just a temporary state that’ll get automatically fixed when the client goes online again. Adding green / red lights to the repository with a mouse over description would be probably a good idea. Reporting that the client is unreachable instead of showing the error message would also be more appropriate.
+
+7. The biggest issue I have now is that `git-annex assistant` randomly crashes on both machines. I don’t know if this is a known issue or if this an OS X only issue, but it is slightly annoying. If you want to make sure that files really synchronized, you’ve to start `git-annex assistant` just to check if it still runs. I hope that this will get fixed as soon as possible. I would love to help you with debug logs, but I don’t know where to look. There’s nothing meaningful in the system log or the debug log.
+
+8. If the issues with Box.com are because of their API rate limits, I would make this clearer when adding new Box.com repositories or I would remove the feature altogether, because they actually make `git-annex assistant` unusable.
+
+To sum everything up: my biggest issues so far are the constant crashes and the strange behavior of the Dock icon. I’m still pretty impressed by the technical smartness and that the software is available at all. Thank you very much—Joey—for letting us use this software on a daily basis. I’m glad that you launched the Kickstarter campaign. I don’t know if it’s much of a hassle, but a second Kickstarter to make sure that development will continue would be probably a good idea. I would like to help with logs, but I don’t know how. Please let me know if there’s something I can do.
+
+**Box.com logs:**
+
+ 87% 16.0KB/s 2s[2013-04-22 15:14:35 CEST] Pusher: Syncing with 10.0.1.4_jcshared
+ To ssh://rafael@git-annex-10.0.1.4-rafael/~/jc-shared/
+ 7428090..f0d2f9e git-annex -> synced/git-annex
+ 9d2cb35..1f7b678 master -> synced/master
+ Already up-to-date.
+ Already up-to-date.
+ gpg: [stdout]: write error: Broken pipe
+ gpg: DBG: deflate: iobuf_write failed
+ gpg: build_packet failed: file write error
+ gpg: [stdout]: write error: Broken pipe
+ gpg: iobuf_flush failed on close: file write error
+ gpg: symmetric encryption of `[stdin]' failed: file write error
+ ResponseTimeout
+ git-annex: fd:41: hPutBuf: resource vanished (Broken pipe)
+ ResponseTimeout
+ (gpg)
+ 87% 16.0KB/s 2sgpg: [stdout]: write error: Broken pipe
+ gpg: DBG: deflate: iobuf_write failed
+ gpg: build_packet failed: file write error
+ gpg: [stdout]: write error: Broken pipe
+ gpg: iobuf_flush failed on close: file write error
+ gpg: symmetric encryption of `[stdin]' failed: file write error
+ ResponseTimeout
+ git-annex: fd:54: hPutBuf: resource vanished (Broken pipe)
+ send: resource vanished (Connection reset by peer)
+ ResponseTimeout
diff --git a/doc/forum/My_first_impressions_after_some_weeks_with_git-annex_assistant/comment_1_9d4019a54fb508e286a5d6d2660361d9._comment b/doc/forum/My_first_impressions_after_some_weeks_with_git-annex_assistant/comment_1_9d4019a54fb508e286a5d6d2660361d9._comment
new file mode 100644
index 000000000..10e10e06c
--- /dev/null
+++ b/doc/forum/My_first_impressions_after_some_weeks_with_git-annex_assistant/comment_1_9d4019a54fb508e286a5d6d2660361d9._comment
@@ -0,0 +1,26 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-04-23T21:41:31Z"
+ content="""
+This is a lot of stuff. It would be better to file individual detailed bug reports if you want any of this looked at in depth. Otherwise, I just read it to get an impression of how things are working, or not, for you, and try to hit some of the main points:
+
+* The OSX app icon behavior is probably because OSX does not realize that this is supposed to be a daemon. I don't know how to fix that. Clicking on the app icon is supposed to launch the web app, and has been reported to do so by others. I have no access to an OSX desktop.
+
+* Transfer repositories only keep files that have not yet reached all your client repositories. However, it's possible that files
+ may be uploaded to a transfer repository unnecessarily (if there is some other path for the file to get to the other client
+ repositories, ie if you've locally paired them). In this case, the file will be uploaded and then later removed from the transfer
+ repository, without being used.
+
+* I have never seen encrypted filenames appear in the webapp. I don't see how that could happen TBH.
+
+* git-annex logs information to `.git/annex/debug.log` within your repository. You can go to Configuration -> Preferences to enable
+ additional debug logging. I absolutely need these logs to help debug almost any problems with the assistant.
+
+* \"Clicking a couple of hundred play buttons\" could result in it trying to make a couple of hundred uploads to box.com
+ at the same time. This is probably not a good idea.
+
+* The fragment of log you posted shows me some problem that caused gpg to fail to encrypt a file before sending it to somewhere,
+ but it's lacking all context (and starts when the file transfer is already 87% complete!) so I can't say more. I need to see the whole log to make any informed guesses about what might be going on.
+"""]]
diff --git a/doc/forum/My_first_impressions_after_some_weeks_with_git-annex_assistant/comment_2_109534a45881ce94a4586c8a83945f9f._comment b/doc/forum/My_first_impressions_after_some_weeks_with_git-annex_assistant/comment_2_109534a45881ce94a4586c8a83945f9f._comment
new file mode 100644
index 000000000..33b2aa393
--- /dev/null
+++ b/doc/forum/My_first_impressions_after_some_weeks_with_git-annex_assistant/comment_2_109534a45881ce94a4586c8a83945f9f._comment
@@ -0,0 +1,85 @@
+[[!comment format=mdwn
+ username="EmanueleAina"
+ ip="93.38.211.231"
+ subject="comment 2"
+ date="2013-09-11T17:55:14Z"
+ content="""
+I seem to hit the same issue (`ResponseTimeout`) on box.com, but I don't have any log file under .git/annex.
+
+The timeout is quite unpredictable, sometimes I'm able to transfer less than 20% of the file while sometimes it fails after reaching 51%. The file is quite big, 6.2G.
+
+Unfortunately, after the first upload fails, `git-annex` seems to think that the file has been uploaded successfully and will refuse to copy it again. Even `whereis` will list the box.com location.
+
+I think there are really two bugs: the one triggering the timeouts, and the fact that `git-annex` thinks that the failing upload succeeded and is unable to recover the interrupted upload.
+
+Here's the log I got on the shell. Let me know how I can provide any additional information needed. Thanks!
+
+ $ git annex copy --verbose --debug home.tar.gz --to box.com
+ [2013-09-11 17:42:52 CEST] read: git [\"--git-dir=/data/backup/.git\",\"--work-tree=/data/backup\",\"show-ref\",\"git-annex\"]
+ [2013-09-11 17:42:52 CEST] read: git [\"--git-dir=/data/backup/.git\",\"--work-tree=/data/backup\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+ [2013-09-11 17:42:52 CEST] read: git [\"--git-dir=/data/backup/.git\",\"--work-tree=/data/backup\",\"log\",\"refs/heads/git-annex..1e029f92c5c82b094cbe70b55927996c31579e2e\",\"--oneline\",\"-n1\"]
+ [2013-09-11 17:42:52 CEST] read: git [\"--git-dir=/data/backup/.git\",\"--work-tree=/data/backup\",\"log\",\"refs/heads/git-annex..1090c21b121fd8b6e2ab49a772c8eab5235a3930\",\"--oneline\",\"-n1\"]
+ [2013-09-11 17:42:52 CEST] chat: git [\"--git-dir=/data/backup/.git\",\"--work-tree=/data/backup\",\"cat-file\",\"--batch\"]
+ [2013-09-11 17:42:52 CEST] read: git [\"--git-dir=/data/backup/.git\",\"--work-tree=/data/backup\",\"ls-files\",\"--cached\",\"-z\",\"--\",\"home.tar.gz\"]
+ copy home.tar.gz (gpg) [2013-09-11 17:42:52 CEST] chat: gpg [\"--quiet\",\"--trust-model\",\"always\",\"--decrypt\"]
+ (checking box.com...) (to box.com...)
+ [2013-09-11 17:42:57 CEST] chat: gpg [\"--quiet\",\"--trust-model\",\"always\",\"--batch\",\"--passphrase-fd\",\"11\",\"--symmetric\",\"--force-mdc\",\"--no-textmode\"]
+ 35% 660.8KB/s 1h44mResponseTimeout
+ gpg: [stdout]: write error: Broken pipe
+ gpg: DBG: deflate: iobuf_write failed
+ gpg: build_packet failed: file write error
+ gpg: [stdout]: write error: Broken pipe
+ gpg: iobuf_flush failed on close: file write error
+ gpg: [stdout]: write error: Broken pipe
+ gpg: iobuf_flush failed on close: file write error
+ gpg: symmetric encryption of `[stdin]' failed: file write error
+ git-annex: fd:13: hPutBuf: resource vanished (Broken pipe)
+ failed
+ git-annex: copy: 1 failed
+ $ git annex copy --verbose --debug home.tar.gz --to box.com
+ [2013-09-11 19:38:26 CEST] read: git [\"--git-dir=/data/backup/.git\",\"--work-tree=/data/backup\",\"show-ref\",\"git-annex\"]
+ [2013-09-11 19:38:26 CEST] read: git [\"--git-dir=/data/backup/.git\",\"--work-tree=/data/backup\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+ [2013-09-11 19:38:26 CEST] read: git [\"--git-dir=/data/backup/.git\",\"--work-tree=/data/backup\",\"log\",\"refs/heads/git-annex..1e029f92c5c82b094cbe70b55927996c31579e2e\",\"--oneline\",\"-n1\"]
+ [2013-09-11 19:38:26 CEST] read: git [\"--git-dir=/data/backup/.git\",\"--work-tree=/data/backup\",\"log\",\"refs/heads/git-annex..1090c21b121fd8b6e2ab49a772c8eab5235a3930\",\"--oneline\",\"-n1\"]
+ [2013-09-11 19:38:26 CEST] chat: git [\"--git-dir=/data/backup/.git\",\"--work-tree=/data/backup\",\"cat-file\",\"--batch\"]
+ [2013-09-11 19:38:26 CEST] read: git [\"--git-dir=/data/backup/.git\",\"--work-tree=/data/backup\",\"ls-files\",\"--cached\",\"-z\",\"--\",\"home.tar.gz\"]
+ copy home.tar.gz (gpg) [2013-09-11 19:38:26 CEST] chat: gpg [\"--quiet\",\"--trust-model\",\"always\",\"--decrypt\"]
+ (checking box.com...) ok
+ $ git annex whereis --verbose --debug home.tar.gz
+ [2013-09-11 19:38:57 CEST] read: git [\"--git-dir=/data/backup/.git\",\"--work-tree=/data/backup\",\"show-ref\",\"git-annex\"]
+ [2013-09-11 19:38:57 CEST] read: git [\"--git-dir=/data/backup/.git\",\"--work-tree=/data/backup\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+ [2013-09-11 19:38:57 CEST] read: git [\"--git-dir=/data/backup/.git\",\"--work-tree=/data/backup\",\"log\",\"refs/heads/git-annex..1e029f92c5c82b094cbe70b55927996c31579e2e\",\"--oneline\",\"-n1\"]
+ [2013-09-11 19:38:57 CEST] read: git [\"--git-dir=/data/backup/.git\",\"--work-tree=/data/backup\",\"log\",\"refs/heads/git-annex..1090c21b121fd8b6e2ab49a772c8eab5235a3930\",\"--oneline\",\"-n1\"]
+ [2013-09-11 19:38:57 CEST] chat: git [\"--git-dir=/data/backup/.git\",\"--work-tree=/data/backup\",\"cat-file\",\"--batch\"]
+ [2013-09-11 19:38:57 CEST] read: git [\"--git-dir=/data/backup/.git\",\"--work-tree=/data/backup\",\"ls-files\",\"--cached\",\"-z\",\"--\",\"home.tar.gz\"]
+ whereis home.tar.gz (2 copies)
+ d7db543e-5463-11e2-b7dd-9f423f798cc4 -- here (em@ocracy:/data/backup)
+ e71fa45e-5463-11e2-a14e-93ca09c272da -- box.com
+ ok
+ $ git annex fsck --verbose --debug home.tar.gz
+ [2013-09-11 19:39:05 CEST] read: git [\"--git-dir=/data/backup/.git\",\"--work-tree=/data/backup\",\"ls-files\",\"--cached\",\"-z\",\"--\",\"home.tar.gz\"]
+ [2013-09-11 19:39:05 CEST] chat: git [\"--git-dir=/data/backup/.git\",\"--work-tree=/data/backup\",\"check-attr\",\"-z\",\"--stdin\",\"annex.backend\",\"annex.numcopies\",\"--\"]
+ fsck home.tar.gz [2013-09-11 19:39:05 CEST] read: git [\"--git-dir=/data/backup/.git\",\"--work-tree=/data/backup\",\"show-ref\",\"git-annex\"]
+ [2013-09-11 19:39:05 CEST] read: git [\"--git-dir=/data/backup/.git\",\"--work-tree=/data/backup\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+ [2013-09-11 19:39:05 CEST] read: git [\"--git-dir=/data/backup/.git\",\"--work-tree=/data/backup\",\"log\",\"refs/heads/git-annex..1e029f92c5c82b094cbe70b55927996c31579e2e\",\"--oneline\",\"-n1\"]
+ [2013-09-11 19:39:05 CEST] read: git [\"--git-dir=/data/backup/.git\",\"--work-tree=/data/backup\",\"log\",\"refs/heads/git-annex..1090c21b121fd8b6e2ab49a772c8eab5235a3930\",\"--oneline\",\"-n1\"]
+ [2013-09-11 19:39:05 CEST] chat: git [\"--git-dir=/data/backup/.git\",\"--work-tree=/data/backup\",\"cat-file\",\"--batch\"]
+ (checksum...) [2013-09-11 19:39:05 CEST] read: sha256sum [\"/data/backup/.git/annex/objects/mG/kp/SHA256E-s6640317400--dcf0a535728f3f3f787db6339b740a4a6f6529e5ce1d238f28574499a8172670.tar.gz/SHA256E-s6640317400--dcf0a535728f3f3f787db6339b740a4a6f6529e5ce1d238f28574499a8172670.tar.gz\"]
+ ok
+ $ git annex fsck --verbose --debug home.tar.gz --from box.com
+ [2013-09-11 19:42:15 CEST] read: git [\"--git-dir=/data/backup/.git\",\"--work-tree=/data/backup\",\"show-ref\",\"git-annex\"]
+ [2013-09-11 19:42:15 CEST] read: git [\"--git-dir=/data/backup/.git\",\"--work-tree=/data/backup\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+ [2013-09-11 19:42:15 CEST] read: git [\"--git-dir=/data/backup/.git\",\"--work-tree=/data/backup\",\"log\",\"refs/heads/git-annex..1e029f92c5c82b094cbe70b55927996c31579e2e\",\"--oneline\",\"-n1\"]
+ [2013-09-11 19:42:15 CEST] read: git [\"--git-dir=/data/backup/.git\",\"--work-tree=/data/backup\",\"log\",\"refs/heads/git-annex..1090c21b121fd8b6e2ab49a772c8eab5235a3930\",\"--oneline\",\"-n1\"]
+ [2013-09-11 19:42:15 CEST] chat: git [\"--git-dir=/data/backup/.git\",\"--work-tree=/data/backup\",\"cat-file\",\"--batch\"]
+ [2013-09-11 19:42:15 CEST] read: git [\"--git-dir=/data/backup/.git\",\"--work-tree=/data/backup\",\"ls-files\",\"--cached\",\"-z\",\"--\",\"home.tar.gz\"]
+ [2013-09-11 19:42:15 CEST] chat: git [\"--git-dir=/data/backup/.git\",\"--work-tree=/data/backup\",\"check-attr\",\"-z\",\"--stdin\",\"annex.backend\",\"annex.numcopies\",\"--\"]
+ fsck home.tar.gz (gpg) [2013-09-11 19:42:15 CEST] chat: gpg [\"--quiet\",\"--trust-model\",\"always\",\"--decrypt\"]
+ (checking box.com...)
+ [2013-09-11 19:42:28 CEST] chat: gpg [\"--quiet\",\"--trust-model\",\"always\",\"--batch\",\"--passphrase-fd\",\"10\",\"--decrypt\"]
+ gpg: decrypt_message failed: eof
+ ok
+
+
+
+"""]]
diff --git a/doc/forum/Need_new_build_instructions_for_Debian_stable.mdwn b/doc/forum/Need_new_build_instructions_for_Debian_stable.mdwn
new file mode 100644
index 000000000..7db19697c
--- /dev/null
+++ b/doc/forum/Need_new_build_instructions_for_Debian_stable.mdwn
@@ -0,0 +1,5 @@
+The instructions for building git-annex on [[install/Debian]] stable don't seem to be valid anymore.
+
+1. `dpkg-checkbuilddeps` is looking for the wrong packages, e.g. libghc-missingh-dev instead of libghc6-missingh-dev.
+
+2. Not all dependencies are available in the Squeeze repositories anymore (at least not Crypto and hS3), if I am not mistaken.
diff --git a/doc/forum/Need_new_build_instructions_for_Debian_stable/comment_1_8c1eea6dfec8b7e1c7a371b6e9c26118._comment b/doc/forum/Need_new_build_instructions_for_Debian_stable/comment_1_8c1eea6dfec8b7e1c7a371b6e9c26118._comment
new file mode 100644
index 000000000..e464c84da
--- /dev/null
+++ b/doc/forum/Need_new_build_instructions_for_Debian_stable/comment_1_8c1eea6dfec8b7e1c7a371b6e9c26118._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-04-26T15:27:49Z"
+ content="""
+I have updated the instructions.
+"""]]
diff --git a/doc/forum/Need_new_build_instructions_for_Debian_stable/comment_2_f6ff8306c946219dbe39bb8938a349ab._comment b/doc/forum/Need_new_build_instructions_for_Debian_stable/comment_2_f6ff8306c946219dbe39bb8938a349ab._comment
new file mode 100644
index 000000000..40f570610
--- /dev/null
+++ b/doc/forum/Need_new_build_instructions_for_Debian_stable/comment_2_f6ff8306c946219dbe39bb8938a349ab._comment
@@ -0,0 +1,21 @@
+[[!comment format=mdwn
+ username="gernot"
+ ip="213.196.216.21"
+ subject="comment 2"
+ date="2011-04-26T18:56:44Z"
+ content="""
+Thanks for the update, Joey. I think you forgot to change libghc-missingh-dev to libghc6-missingh-dev for the copy & paste instructions though.
+
+Also, after having checked that I have everything installed I'm still getting this error:
+
+ ...
+ [15 of 77] Compiling Annex ( Annex.hs, Annex.o )
+
+ Annex.hs:19:35:
+ Module `Control.Monad.State' does not export `state'
+ make[1]: *** [git-annex] Error 1
+ make[1]: Leaving directory `/home/gernot/dev/git-annex'
+ dh_auto_build: make -j1 returned exit code 2
+ make: *** [binary] Error 2
+
+"""]]
diff --git a/doc/forum/Need_new_build_instructions_for_Debian_stable/comment_3_bcda70cbfc7c1a14fa82da70f9f876e2._comment b/doc/forum/Need_new_build_instructions_for_Debian_stable/comment_3_bcda70cbfc7c1a14fa82da70f9f876e2._comment
new file mode 100644
index 000000000..8b4111643
--- /dev/null
+++ b/doc/forum/Need_new_build_instructions_for_Debian_stable/comment_3_bcda70cbfc7c1a14fa82da70f9f876e2._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 3"
+ date="2011-04-26T23:40:33Z"
+ content="""
+Both problems fixed.
+"""]]
diff --git a/doc/forum/Need_some_help_to_fix_my_repository.mdwn b/doc/forum/Need_some_help_to_fix_my_repository.mdwn
new file mode 100644
index 000000000..e4f6fb593
--- /dev/null
+++ b/doc/forum/Need_some_help_to_fix_my_repository.mdwn
@@ -0,0 +1,31 @@
+Hi,
+first sorry for my poor english it's not my native language.
+
+I have one repository on my laptop and two repository on usb disk. Made with following walkthrough (creating a repository and adding a remote).
+
+Yesterday I have a backup of my repository on usb disk before add some file with
+
+cd /media/usb/annex;git fetch laptop; git merge laptop/master&&git annex get .&&git annex sync
+
+Now the repository on my usb disk is a mess.
+Every file before the commit are lost.
+For example :
+ After the sync : file Z.7z
+Z.7z: broken symbolic link to `../../../../.git/annex/objects/2K/49/SHA256-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855/SHA256-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
+
+The file ../../../../.git/annex/objects/2K/49/SHA256-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855/SHA256-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 doesn't exist.
+
+On the repository before the sync (inside the Backup) :
+file Z.7z
+Z.7z: symbolic link to `../../../../.git/annex/objects/J1/f4/SHA256-s696365035--d2dcc67bf2f05fcfc7f42723b2d415d4f057a2eeadc282b40f5bc3724534f2f4/SHA256-s696365035--d2dcc67bf2f05fcfc7f42723b2d415d4f057a2eeadc282b40f5bc3724534f2f4'
+
+The file ../../../../.git/annex/objects/J1/f4/SHA256-s696365035--d2dcc67bf2f05fcfc7f42723b2d415d4f057a2eeadc282b40f5bc3724534f2f4/SHA256-s696365035--d2dcc67bf2f05fcfc7f42723b2d415d4f057a2eeadc282b40f5bc3724534f2f4 still exist in the repository after the sync.
+
+3 questions, if somebody could help me :
+
+ - what I do wrong ?
+ - why the- symlink for every file had change after "cd /media/usb/annex;git fetch laptop; git merge laptop/master&&git annex get .&&git annex sync"
+ - how could I fix my repository ? recover file from the backup ? how ? Copy every file to start my repository from a new clean state ?
+
+
+
diff --git a/doc/forum/Need_some_help_to_fix_my_repository/comment_1_f0d279c530b796b2c93d793f85d147e8._comment b/doc/forum/Need_some_help_to_fix_my_repository/comment_1_f0d279c530b796b2c93d793f85d147e8._comment
new file mode 100644
index 000000000..6f9a8078f
--- /dev/null
+++ b/doc/forum/Need_some_help_to_fix_my_repository/comment_1_f0d279c530b796b2c93d793f85d147e8._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-04-22T20:00:12Z"
+ content="""
+1. Use `git log --stat` to find the commit that changed your file `Z.7z`
+2. Use `git revert` to revert that commit
+
+That will put things back the way they were.
+
+You should then investigate what caused the bad commit to be made. It seems to have involved the file being reset to be 0 bytes in size.
+"""]]
diff --git a/doc/forum/Need_some_help_to_fix_my_repository/comment_2_a3fcfa1f8eadec5fa8a9efacca174048._comment b/doc/forum/Need_some_help_to_fix_my_repository/comment_2_a3fcfa1f8eadec5fa8a9efacca174048._comment
new file mode 100644
index 000000000..bded393bf
--- /dev/null
+++ b/doc/forum/Need_some_help_to_fix_my_repository/comment_2_a3fcfa1f8eadec5fa8a9efacca174048._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkyQL8VPwrSf8LA0k8PKDWFCEKFH3O5Jds"
+ nickname="marco"
+ subject="Brvo"
+ date="2013-04-22T23:33:10Z"
+ content="""
+Bravo. Mon Hero.
+
+You save my data ! I can't find what happen but thanks a lot.
+"""]]
diff --git a/doc/forum/Need_some_help_to_fix_my_repository/comment_3_7878f9b76ddfa3392c9ec6a1810cb745._comment b/doc/forum/Need_some_help_to_fix_my_repository/comment_3_7878f9b76ddfa3392c9ec6a1810cb745._comment
new file mode 100644
index 000000000..67657110a
--- /dev/null
+++ b/doc/forum/Need_some_help_to_fix_my_repository/comment_3_7878f9b76ddfa3392c9ec6a1810cb745._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="glad I could help"
+ date="2013-04-23T21:16:47Z"
+ content="""
+I'm curious if your repository is using direct mode, and is perhaps on a FAT filesystem, or other filesystem that does not support symlinks?
+
+One way this could have happened is due to a bug in `git annex sync` when used on such a filesystem. I've just fixed this bug in commit 07580dc3dfb2f4d9af9a20bc172cbc32953c49d6
+"""]]
diff --git a/doc/forum/New_git-annex_integration_mode_for_Emacs_users.mdwn b/doc/forum/New_git-annex_integration_mode_for_Emacs_users.mdwn
new file mode 100644
index 000000000..0513e0df8
--- /dev/null
+++ b/doc/forum/New_git-annex_integration_mode_for_Emacs_users.mdwn
@@ -0,0 +1,3 @@
+I've started a another project to provide Emacs integration for git-annex: [[https://github.com/jwiegley/git-annex-el]]
+
+My problem with the existing mode is that it didn't feel at all Emacsy, while my mode just piggy backs on existing paradigms, like using `C-x C-q` in a locked file to make it editable, and allowing you to browse and lock/unlock annexed files from Dired.
diff --git a/doc/forum/New_special_remote_suggeston_-_clean_directory.mdwn b/doc/forum/New_special_remote_suggeston_-_clean_directory.mdwn
new file mode 100644
index 000000000..9fd3c5a20
--- /dev/null
+++ b/doc/forum/New_special_remote_suggeston_-_clean_directory.mdwn
@@ -0,0 +1,15 @@
+The [[special remotes]] available all do great things and enable a ton of different services to be integrated.
+
+Strikingly, the one service I can't satisfactorily integrate with git-annex is a remote folder on a eg NAS (think: computer without git-annex installed) that I want to look like the original annex. As in, when I do a 'tree annexdir' it'd look the same on both locations (except, on the remote there would not be any symlinks, it'd be like it was in directmode, and there would not be a .git subdir).
+
+## Why? Use Case?
+
+I have a Synology NAS that I share access with with my wife. I want her to be able to access the files (photos/videos/music) in a sane manner (ie: not traversing sub-sub-sub 'randomly' named directories) but I also want to be able to manage them with git-annex on my machine (to gain the standard git-annex benefits, specifically the bob the archivist use case). The NAS has the ability to use ssh+rsync, so I'll assume those two tools can be used.
+
+This special remote could be thought of as the 'least common denominator of special remotes'; almost any server with ssh+rsync could be a remote, no matter if you have install privs or if the architecture (eg: ARM) is supported by git-annex.
+
+## Issues?
+
+First and foremost, this can't be (really really shouldn't be) a trusted remote; my wife could accidentally delete all files on the NAS while I am away. So my local git-annex shouldn't assume the NAS counts towards numcopies (unless I'm a real masochist).
+
+Secondly, what to do when files change/are added/removed on the special remote? Probably the same thing that the assistant does with everything. The only thing special is that new/modified files will need to be copied locally from this special remote before being added to the annex (to get hash and such).
diff --git a/doc/forum/New_special_remote_suggeston_-_clean_directory/comment_1_4d81941fe53881eebff97109a07ba2f4._comment b/doc/forum/New_special_remote_suggeston_-_clean_directory/comment_1_4d81941fe53881eebff97109a07ba2f4._comment
new file mode 100644
index 000000000..1ec5bbc54
--- /dev/null
+++ b/doc/forum/New_special_remote_suggeston_-_clean_directory/comment_1_4d81941fe53881eebff97109a07ba2f4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="TroisSinges"
+ ip="82.227.207.5"
+ subject="comment 1"
+ date="2013-11-27T14:59:11Z"
+ content="""
+You could mount this NAS as a network drive on your computer (via samba for example or, even better, nfs), couldn't you? In this case you could use a real annex repository, and not a remote one.
+"""]]
diff --git a/doc/forum/New_special_remote_suggeston_-_clean_directory/comment_2_660a5b764ad42468154b2bb94f8ec004._comment b/doc/forum/New_special_remote_suggeston_-_clean_directory/comment_2_660a5b764ad42468154b2bb94f8ec004._comment
new file mode 100644
index 000000000..89663893e
--- /dev/null
+++ b/doc/forum/New_special_remote_suggeston_-_clean_directory/comment_2_660a5b764ad42468154b2bb94f8ec004._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://grossmeier.net/"
+ nickname="greg"
+ subject="mounting over NFS/etc ..."
+ date="2013-11-27T16:01:50Z"
+ content="""
+TroisSinges: Yeah, I could, but that'd limit me to being on the local network when I want to interact with the repo; not ideal.
+"""]]
diff --git a/doc/forum/New_user_misunderstandings.mdwn b/doc/forum/New_user_misunderstandings.mdwn
new file mode 100644
index 000000000..d1b1df180
--- /dev/null
+++ b/doc/forum/New_user_misunderstandings.mdwn
@@ -0,0 +1,24 @@
+New user? Can't figure out the basics? Add it here - what you wanted, what you tried.
+
+#### I wanted to keep track of some files I had all organized in a directory outside of my ~/annex:
+
+ $ cd ~/annex
+ $ git annex add /path/to/some/photos
+ fatal: '/path/to/some/photos' is outside repository
+
+ But git-annex doesn't work that way. I had to do this instead
+
+ $ rsync -a /path/to/some/photos
+ $ git annex add photos
+ (Recording state in git...)
+ $ git annex status
+ ... lots of helpful info...
+
+#### I just have the OS/X app, can I do commandline stuff?
+
+yes
+
+ $ /Applications/git-annex.app/Contents/MacOS/git-annex add photos/
+ (Recording state in git...)
+
+but perhaps there is a better way.
diff --git a/doc/forum/New_user_misunderstandings/comment_1_c1785924109b5d5cde9aa3d3460cf955._comment b/doc/forum/New_user_misunderstandings/comment_1_c1785924109b5d5cde9aa3d3460cf955._comment
new file mode 100644
index 000000000..b15f5cfb7
--- /dev/null
+++ b/doc/forum/New_user_misunderstandings/comment_1_c1785924109b5d5cde9aa3d3460cf955._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.117"
+ subject="comment 1"
+ date="2012-12-17T16:21:36Z"
+ content="""
+For importing your photos, you can use `git annex import /path/to/some/photos` .. this will move them from the given location into the current directory, and add them to the annex. It preserves subdirectory structure too.
+
+For using the OSX app at the command line, the only thing that is guaranteed to work properly is to run `/Applications/git-annex.app/Contents/MacOS/runshell`, which will modify your PATH and other environment appropriately.
+"""]]
diff --git a/doc/forum/Newbie_stuck_at___34__Unable_to_connect_to_the_Jabber_server__34__.mdwn b/doc/forum/Newbie_stuck_at___34__Unable_to_connect_to_the_Jabber_server__34__.mdwn
new file mode 100644
index 000000000..eb1aa3b50
--- /dev/null
+++ b/doc/forum/Newbie_stuck_at___34__Unable_to_connect_to_the_Jabber_server__34__.mdwn
@@ -0,0 +1,5 @@
+I'm brand new to git-annex and am having trouble getting going. I've got an annex and I get messages like "Ran daily sanity check" and "Synced with web", but I can't get connected to a Jabber account. I've been using my Gmail account, which works fine for logging into this forum but gives me the message "Unable to connect to the Jabber server. Maybe you entered the wrong password?" when I try to configure the Jabber account.
+
+I'm using version 3.20121112ubuntu2. I think a later version might exist but I don't know how to reach it; I've done the standard install for Ubuntu-style OSs (I'm running Kubuntu right now), and that's the git-annex version that arrives.
+
+Any suggestions? Sorry for the simplistic startup question, but it looks like this will be a great tool once I get it running.
diff --git a/doc/forum/Newbie_stuck_at___34__Unable_to_connect_to_the_Jabber_server__34__/comment_1_59158afcedac18a7285d57491b2a468a._comment b/doc/forum/Newbie_stuck_at___34__Unable_to_connect_to_the_Jabber_server__34__/comment_1_59158afcedac18a7285d57491b2a468a._comment
new file mode 100644
index 000000000..45b4a9bdf
--- /dev/null
+++ b/doc/forum/Newbie_stuck_at___34__Unable_to_connect_to_the_Jabber_server__34__/comment_1_59158afcedac18a7285d57491b2a468a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.110"
+ subject="comment 1"
+ date="2013-07-27T22:13:49Z"
+ content="""
+Since 2012 git-annex has had massive improvements to its Jabber support. See [[/install/Ubuntu]] to get a current version.
+"""]]
diff --git a/doc/forum/Newbie_stuck_at___34__Unable_to_connect_to_the_Jabber_server__34__/comment_2_2a70ac08bb95774415b09dab7d7f8605._comment b/doc/forum/Newbie_stuck_at___34__Unable_to_connect_to_the_Jabber_server__34__/comment_2_2a70ac08bb95774415b09dab7d7f8605._comment
new file mode 100644
index 000000000..777a23851
--- /dev/null
+++ b/doc/forum/Newbie_stuck_at___34__Unable_to_connect_to_the_Jabber_server__34__/comment_2_2a70ac08bb95774415b09dab7d7f8605._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlutNrg7ajiNAfi5gqJfD8crv0aimZa27k"
+ nickname="Chuck"
+ subject="Now I'm really confused 8-/"
+ date="2013-07-28T05:26:02Z"
+ content="""
+Yes, I followed the directions on that page and executed \"sudo apt-get install git-annex\" on my 13.04 (Raring) system. I did it again just now to verify, and I got the same result from \"git-annex version\", namely \"3.20121112ubuntu2\". Do I need to add a repo for Raring as for Precise?
+"""]]
diff --git a/doc/forum/Newbie_stuck_at___34__Unable_to_connect_to_the_Jabber_server__34__/comment_3_92a52b523ed4c68b70ddcabc2a050b76._comment b/doc/forum/Newbie_stuck_at___34__Unable_to_connect_to_the_Jabber_server__34__/comment_3_92a52b523ed4c68b70ddcabc2a050b76._comment
new file mode 100644
index 000000000..9b1d95e78
--- /dev/null
+++ b/doc/forum/Newbie_stuck_at___34__Unable_to_connect_to_the_Jabber_server__34__/comment_3_92a52b523ed4c68b70ddcabc2a050b76._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmKKg3Vmzk7KwRGRKjHVdtyoj1JfxLX6NM"
+ nickname="Tom"
+ subject="comment 3"
+ date="2013-10-01T18:33:05Z"
+ content="""
+I've got the same issue on Xubuntu 13.04. I installed using this script: https://github.com/zerodogg/scriptbucket/blob/master/gitannex-install
+
+`git-annex version` makes no mention of DNS or ADNS
+
+`host` command is installed on my machine. any suggestions on how best to fix for this setup?
+"""]]
diff --git a/doc/forum/Newbie_stuck_at___34__Unable_to_connect_to_the_Jabber_server__34__/comment_4_c52a75761ea107f6d69c09bac64f0f0a._comment b/doc/forum/Newbie_stuck_at___34__Unable_to_connect_to_the_Jabber_server__34__/comment_4_c52a75761ea107f6d69c09bac64f0f0a._comment
new file mode 100644
index 000000000..b15edfa5a
--- /dev/null
+++ b/doc/forum/Newbie_stuck_at___34__Unable_to_connect_to_the_Jabber_server__34__/comment_4_c52a75761ea107f6d69c09bac64f0f0a._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmKKg3Vmzk7KwRGRKjHVdtyoj1JfxLX6NM"
+ nickname="Tom"
+ subject="comment 4"
+ date="2013-10-02T21:27:36Z"
+ content="""
+Update to my comment above - it seems my problem is related to ejabberd as discussed here: <http://git-annex.branchable.com/forum/XMPP_authentication_failure/>
+
+Think I might change my server to [Prosody](https://prosody.im/) and see what happens then.
+
+
+"""]]
diff --git a/doc/forum/Newbie_stuck_at___34__Unable_to_connect_to_the_Jabber_server__34__/comment_5_2685e3a87464ccd37d593516d94ba5cf._comment b/doc/forum/Newbie_stuck_at___34__Unable_to_connect_to_the_Jabber_server__34__/comment_5_2685e3a87464ccd37d593516d94ba5cf._comment
new file mode 100644
index 000000000..84d6832ff
--- /dev/null
+++ b/doc/forum/Newbie_stuck_at___34__Unable_to_connect_to_the_Jabber_server__34__/comment_5_2685e3a87464ccd37d593516d94ba5cf._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkr_EUIHZ8CTtOGm-j-guMBzaYuOzrXJwg"
+ nickname="Christoph"
+ subject="be aware of the 2-step verification"
+ date="2013-10-15T20:03:12Z"
+ content="""
+if you enabled the \"2-step verification\" in our google account (Account -> Security -> 2-step verification: Status: ON) you have to make a \"Application-specific passwords\" for your Jabber login.
+
+NoXorius
+"""]]
diff --git a/doc/forum/No_SSL_traffic_for_S3__63__.mdwn b/doc/forum/No_SSL_traffic_for_S3__63__.mdwn
new file mode 100644
index 000000000..c2f4e3717
--- /dev/null
+++ b/doc/forum/No_SSL_traffic_for_S3__63__.mdwn
@@ -0,0 +1,8 @@
+As far I can tell, the encryption mentioned on the wiki for S3 [1] refers to file-level encryption. That is, it encrypts files with GPG before storing them (or after retrieving them) from S3. However, even if I have GPG encryption off, I still want S3 requests to use SSL encryption. As far as I can tell, HTTPS isn't used with S3 remotes. Is there any way to enable it (if so, it should be the default)?
+
+I am using git-annex version: 3.20120406
+
+Cheers,
+--acrefoot
+
+[1] http://git-annex.branchable.com/special_remotes/S3/
diff --git a/doc/forum/No_SSL_traffic_for_S3__63__/comment_1_f509bf273896180e6df8c771438dd093._comment b/doc/forum/No_SSL_traffic_for_S3__63__/comment_1_f509bf273896180e6df8c771438dd093._comment
new file mode 100644
index 000000000..808d4c035
--- /dev/null
+++ b/doc/forum/No_SSL_traffic_for_S3__63__/comment_1_f509bf273896180e6df8c771438dd093._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.238"
+ subject="comment 1"
+ date="2013-01-15T20:25:42Z"
+ content="""
+<http://hackage.haskell.org/package/hS3> is a Haskell library for S3, which git-annex uses. It does not support HTTPS. I'm sure its author would appreciate help, or maybe even just gentle motivation.
+
+FWIW, I think that S3's authorization is designed to be pretty secure even over an un-encrypted transport.
+It uses HMAC to sign the request with your AWS credentials securely, and includes a date that is hopefully used to avoid replay attacks.
+"""]]
diff --git a/doc/forum/No_SSL_traffic_for_S3__63__/comment_2_358635d19c82202c63014ca84de7fc3b._comment b/doc/forum/No_SSL_traffic_for_S3__63__/comment_2_358635d19c82202c63014ca84de7fc3b._comment
new file mode 100644
index 000000000..edf1b6338
--- /dev/null
+++ b/doc/forum/No_SSL_traffic_for_S3__63__/comment_2_358635d19c82202c63014ca84de7fc3b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnRIwPkmDOZSpul-Lx61_jUGHh9f_F3od8"
+ nickname="Michael"
+ subject="comment 2"
+ date="2013-01-15T20:47:50Z"
+ content="""
+The authorization is fine, but it's scary to see your data floating along the wire in plain-text :)
+"""]]
diff --git a/doc/forum/Not_sure_how_to_get_my_s3_remote_back.mdwn b/doc/forum/Not_sure_how_to_get_my_s3_remote_back.mdwn
new file mode 100644
index 000000000..86f8da454
--- /dev/null
+++ b/doc/forum/Not_sure_how_to_get_my_s3_remote_back.mdwn
@@ -0,0 +1,31 @@
+My situation goes something like this:
+
+I have a machine with an annex and a number of special remotes (s3, box, and an rsync'd nas). I also have a git remote that's doesn't have git annex on it, so it's just got the git branches. That machine has some problems so I start getting the annex set up on a different machine. These are the steps that I went through:
+
+* clone from the git remote
+* git annex doesn't think this is an actual annex at this point, so `git annex init` it
+* Now I can start the webapp `git annex webapp`
+* My rsync'd remote works and the assistant starts downloading the files from there (which is great, it's the local network one) but the box and s3 remotes are disabled (sure, not a huge deal).
+* Click enable on the box remote, I have to specify that it's a full backup remote
+* Things start copying from box as well, so I disable it until everything from the local network is done
+* Click enable on the s3 remote and it wants my AWS creds
+* Download those and add it
+* Set the remote up the same way, as a full backup.
+
+At this point, all my files have copied from the rsync remote, so I enable the other remotes.
+
+Now I want to make sure that all the remotes are set up and working properly.
+
+I turn off the webapp, turn off direct mode (I think it was indirect mode by default, but I'd been playing with things before then), and `git annex drop <file>` a file that I don't particularly care about. Everything drops successfully.
+
+I'm able to `git annex get -f <rsync remote> <file>` and from `<box remote>` successfully, but when I try to get from the s3 remote, it doesn't give me any output and doesn't download the file.
+
+Having used regular git annex without the assistant before, I try re-initing the remote `git annex initremote <s3>`. It complains that there's no type, so I `git annex initremote <s3> type=S3`, then it complains about encryption. `git annex initremote <s3> type=S3 encryption=shared`. It says it worked, but I `git annex get -f <s3> <file>` still doesn't do anything.
+
+After more looking around, it turns out that I may have created a second remote with the same name as the original s3 remote... (figure that out). I use the webapp to rename the remotes so they're different, but neither of them will `get -f` successfully.
+
+At this point, I turn to you and ask what the heck I did wrong. I tried editing the remote.log and uuid.log files to remove the new s3 remote (and I figured out which one was which) from the git-annex branch. I also marked the new s3 remote as dead, but I still can't get access to s3.
+
+`git annex fsck -f <s3>` doesn't actually seem to hit s3 (I seem to recall that it used to, it calculated checksums), it just checks some git local information.
+
+I don't mind deleting my current checkout and starting from the clone step again if you think I've made too much of a mess. At least I know I can get my files off my rsync remote and box :)
diff --git a/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_10_ed35a6ec605e8f79ec107856af6d1a46._comment b/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_10_ed35a6ec605e8f79ec107856af6d1a46._comment
new file mode 100644
index 000000000..eda042c83
--- /dev/null
+++ b/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_10_ed35a6ec605e8f79ec107856af6d1a46._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 10"
+ date="2013-04-26T20:33:03Z"
+ content="""
+Oh.. I got confused by you talking about the box remote. Lines you pasted look ok anyway.
+
+Ok, looking at the S3 remote then...
+
+> I did notice that initially the s3 remote was named \"annex\". That was probably the web interface's doing, way back when I added it.
+
+So, you can never change the names used to refer to remotes in remote.log. These names can be different from the names used to refer to the same remotes in .git/config. (Which can vary from repository to repository anyway..) So, if you originally added a s3 remote and called it \"annex\", you still need to use that name when running initremote elsewhere to add that remote to your repository.
+
+The remote with name \"s3\" added in the 11:26 is a separate s3 remote, and I think one you don't want. (And have marked dead?)
+
+I think all you need to do is \"git annex initremote annex\" to add the s3 remote you want to your new repository.
+"""]]
diff --git a/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_11_e48b6efa42159dc83e1be11bfb54abcd._comment b/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_11_e48b6efa42159dc83e1be11bfb54abcd._comment
new file mode 100644
index 000000000..41da88a8d
--- /dev/null
+++ b/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_11_e48b6efa42159dc83e1be11bfb54abcd._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkZktNHFhxC1kYA9KKdKpYJO4clq9WDsjE"
+ nickname="Jason"
+ subject="comment 11"
+ date="2013-04-26T20:37:51Z"
+ content="""
+Ah, I see. It looks like that did solve my problem.
+
+Yes, I did mark the old s3 remote as dead.
+
+At least now I know how to fix it if it ever happens again. I wonder if I'll ever be able to recreate it...
+
+Thanks!
+"""]]
diff --git a/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_12_b58232d0e3fa4649565c0c7d4ce2e82e._comment b/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_12_b58232d0e3fa4649565c0c7d4ce2e82e._comment
new file mode 100644
index 000000000..8b13675fe
--- /dev/null
+++ b/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_12_b58232d0e3fa4649565c0c7d4ce2e82e._comment
@@ -0,0 +1,31 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 12"
+ date="2013-04-26T20:52:36Z"
+ content="""
+It's easy to recreate. As I understand it, the entire process went something like this:
+
+git annex initremote annex type=S3 encryption=blahblah # possibly this was done in the webapp?
+
+git remote rename annex s3 # also possibly done in the webapp
+
+# clone to different computer, and on the new clone:
+
+git annex initremote s3
+
+git-annex: Specify the type of remote with type=
+
+git annex initremote s3 type=S3 encryption=blahblah
+
+The last line creates a *new* remote.
+
+I'm inclined to think the main confusing thing here is that initremote is used to both create a new special remote, and to configure the repository to use an already existing special remote that was created elsewhere. If you had to use `enableremote` for the latter,
+things could be less confusing:
+
+# clone to different computer, and on the new clone:
+
+git annex enableremote s3
+
+git-annex: No existing special remote named s3. Choose from one of these existing special remotes: annex
+"""]]
diff --git a/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_13_85368b60091dc3ce2efb58013ffe9f83._comment b/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_13_85368b60091dc3ce2efb58013ffe9f83._comment
new file mode 100644
index 000000000..c51377dbb
--- /dev/null
+++ b/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_13_85368b60091dc3ce2efb58013ffe9f83._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkZktNHFhxC1kYA9KKdKpYJO4clq9WDsjE"
+ nickname="Jason"
+ subject="comment 13"
+ date="2013-04-26T21:16:30Z"
+ content="""
+I tend to agree with you. At first I liked the idea that initremote could be used to re-initialize a remote, but then I got confused about what the name of that remote was. I suppose git annex status could have told me. I kept wanting to have something like \"git annex remote\" (which would list them) and then \"git annex remote init\" to initialize them. That way the remote actions would follow the same sort of interface as \"git remote\", where you could list, init, create, edit, rename, enable, disable, kill (dead?), etc. The main drawback I see with that is having too many levels to type.
+
+I really like the idea of having the ability to \"git annex remote show s3\" and it will tell me what the type, uuid, options, etc are for that remote.
+"""]]
diff --git a/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_14_e65281bef23e0076936c508728a87897._comment b/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_14_e65281bef23e0076936c508728a87897._comment
new file mode 100644
index 000000000..31fd9d60b
--- /dev/null
+++ b/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_14_e65281bef23e0076936c508728a87897._comment
@@ -0,0 +1,25 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 14"
+ date="2013-04-26T22:25:04Z"
+ content="""
+Have now split out an enableremote command.
+
+<pre>
+joey@gnu:~/tmp/annex>git annex initremote foo
+git-annex: There is already a special remote named \"foo\". (Use enableremote to enable an existing special remote.)
+joey@gnu:~/tmp/annex>git annex enableremote
+git-annex: Specify the name of the special remote to enable. Known special remotes: foo
+</pre>
+
+Also, I wrote something wrong before. It *is* possible to change the name used by initremote (now enableremote).
+
+With the current release of git-annex:
+
+`git annex initremote annex name=mys3`
+
+With the next release:
+
+`git annex enableremote annex name=mys3`
+"""]]
diff --git a/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_1_fffb59ad5a197d2980dd0ec35cf4aafa._comment b/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_1_fffb59ad5a197d2980dd0ec35cf4aafa._comment
new file mode 100644
index 000000000..d8d754309
--- /dev/null
+++ b/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_1_fffb59ad5a197d2980dd0ec35cf4aafa._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-04-24T23:56:54Z"
+ content="""
+What you describe, `git annex get $file --from remote` silently not doing anything, is the expected behavior if the remote doesn't have the file. This allows you to eg, run `git annex get . --from remote` and get all files that the remote does have while skipping the rest.
+
+Did you ever try looking at `git annex whereis $file` ?
+"""]]
diff --git a/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_2_0cfcc2075bff556b9fde5acc3dc1d599._comment b/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_2_0cfcc2075bff556b9fde5acc3dc1d599._comment
new file mode 100644
index 000000000..c673737c1
--- /dev/null
+++ b/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_2_0cfcc2075bff556b9fde5acc3dc1d599._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkZktNHFhxC1kYA9KKdKpYJO4clq9WDsjE"
+ nickname="Jason"
+ subject="comment 2"
+ date="2013-04-25T00:20:59Z"
+ content="""
+When I run `git annex whereis $file` it tells me it's available at box, s3, my rsync remote, the original repo (from the machine I created the annex on), and my temporary usb stick repo (nothing wrong with redundancy...). So it seems that git annex thinks the file is available in the s3 remote, even though it's refusing to download it.
+"""]]
diff --git a/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_3_6fe2ff1282fb14a4ce26ef8dc775d07e._comment b/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_3_6fe2ff1282fb14a4ce26ef8dc775d07e._comment
new file mode 100644
index 000000000..187993a5a
--- /dev/null
+++ b/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_3_6fe2ff1282fb14a4ce26ef8dc775d07e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-04-25T00:50:01Z"
+ content="""
+Does the uuid that whereis prints next to the name of the s3 remote match the annex.<remote>.uuid setting for that remote in .git/config?
+"""]]
diff --git a/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_4_64338d2d77dcbabd16b55eb145f40dc6._comment b/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_4_64338d2d77dcbabd16b55eb145f40dc6._comment
new file mode 100644
index 000000000..d4a05ce8e
--- /dev/null
+++ b/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_4_64338d2d77dcbabd16b55eb145f40dc6._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkZktNHFhxC1kYA9KKdKpYJO4clq9WDsjE"
+ nickname="Jason"
+ subject="comment 4"
+ date="2013-04-25T01:18:00Z"
+ content="""
+Oh! That might be it! During the whole \"I have two remotes with the name s3\" situation, it seems that both of them in my .git/config ended up with the same uuid, even though the original one had a different uuid. If I change it back, I end up getting an access denied when I try to `git annex get ...`. Progress!
+
+I thought that you were supposed to do a `git annex initremote s3` from a clone to enable a remote with the credentials stored in the repo. It seems that internally something still thinks that the \"s3\" remote has the new uuid. When I run that command it changes the uuid back to the new (invalid) one.
+
+Is there a way I can totally remove the bad s3 (which I've partially renamed to s3thefirst) remote from my history/repo (I'm pretty sure it's been synced back up to origin at this point) or properly rename it so it doesn't keep getting confused? Hopefully that will address my problem.
+"""]]
diff --git a/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_5_dd66c9ea0c83388f6826751944330d10._comment b/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_5_dd66c9ea0c83388f6826751944330d10._comment
new file mode 100644
index 000000000..58fba2ca8
--- /dev/null
+++ b/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_5_dd66c9ea0c83388f6826751944330d10._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 5"
+ date="2013-04-25T02:14:18Z"
+ content="""
+Yes, when you run `git annex initremote $remotename` with no other parameters, it enables a remote from the stored configuration.
+Which does not include `AWS_SECRET_ACCESS_KEY` and `AWS_ACCESS_KEY_ID`; you need to set those and then
+you should not get access denied.
+
+You seem to say your .git/config contains two remotes with the same name, but I don't think that's possible.
+
+I don't know how you could end up with two remotes with the same name in `git show git-annex:remote.log`, unless the two were added in separate repositories which were then synced together. Since this is not a usual situation there's not any UI to deal with it. I've just committed a change that will make `initremote` prefer remotes that have not been marked dead when there's a naming comflict.
+
+However, I'm more curious how this situation came about. I have not been able to reproduce the problem when enabling a S3 remote using the webapp.
+"""]]
diff --git a/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_6_dc0c5e395e4c443b7227afdb157194e5._comment b/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_6_dc0c5e395e4c443b7227afdb157194e5._comment
new file mode 100644
index 000000000..c9c352c35
--- /dev/null
+++ b/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_6_dc0c5e395e4c443b7227afdb157194e5._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 6"
+ date="2013-04-25T02:18:56Z"
+ content="""
+What you could do to help track down how this occurred is to check out the `git-annex` branch, and use `git blame` to find out when the second remote with the same name was first added to the `remote.log` file.
+
+Then you should be able to tell, either from the email address used for that commit, or at least the date of the commit, whether this occurred recently when you enabled the S3 remote in the webapp, or perhaps at some time in the past.
+"""]]
diff --git a/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_7_3c0ea4c76cdd889707f7308576e3efa0._comment b/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_7_3c0ea4c76cdd889707f7308576e3efa0._comment
new file mode 100644
index 000000000..b32532894
--- /dev/null
+++ b/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_7_3c0ea4c76cdd889707f7308576e3efa0._comment
@@ -0,0 +1,65 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkZktNHFhxC1kYA9KKdKpYJO4clq9WDsjE"
+ nickname="Jason"
+ subject="comment 7"
+ date="2013-04-26T19:10:15Z"
+ content="""
+http://pastebin.com/CM2EfQ21
+
+This is what the commit log looks like for the remote.log file. There is some interesting stuff in here. I'll try to highlight the changes without giving too much of the important bits away.
+
+The I commit at 2013-04-22 11:57 is when I added the box remote:
+
+0490d177-78e2-421b-a004-47d88ee7a2e3 chunksize=10mb cipher=... davcreds=... embedcreds=yes name=box.com type=webdav url=https://www.box.com/dav/annex timestamp=1366657062.972357s
+1d0ab67c-6a43-11e2-9feb-df22c6d1e308 bucket=annex-1d0ab67c-6a43-11e2-9feb-df22c6d1e308 cipher=... datacenter=US host=s3.amazonaws.com name=annex port=80 storageclass=REDUCED_REDUNDANCY type=S3 timestamp=1359484726.520727s
+
+The contents also includes my nas remote, but I will omit that for brevity's sake. I did notice that initially the s3 remote was named \"annex\". That was probably the web interface's doing, way back when I added it.
+
+The next commit at 2013-04-24 10:55 seems to have added encryption=shared and highRandomQuality=false to the nas remote (I think this was when I re-enabled the nas remote through the webapp).
+
+The commit at 2013-04-24 11:05 looks like it added similar stuff to the box remote (added highRandomQuality=false). Probably this was from enabling it then as well.
+
+At 2013-04-24 11:12 the s3 remote had highRandomQuality=false added also.
+
+At 2013-04-24 11:26, a new remote was added:
+
+4d86972d-9b0a-4095-bc50-f9bec8144c30 bucket=s3-4d86972d-9b0a-4095-bc50-f9bec8144c30 cipher=... datacenter=US host=s3.amazonaws.com name=s3 port=80 storageclass=STANDARD type=S3 timestamp=1366828017.8792s
+
+Very possibly this was me doing a `git annex initremote ...` thinking that the s3 remote was actually named s3 (somehow, I feel like I would have checked that, but I'm going to chalk that up to my own stupidity).
+
+Then at 2013-04-24 11:35, the new s3 remote was changed... but it seems like only the timestamp was altered. I suspect this was from another command line change, but I don't remember exactly what I did at that point. Probably a reference in a different file was also modified, but I'm not looking at those.
+
+At 2013-04-24 11:37, again the new s3 remote was changed, but again it was just the timestamp.
+
+In the merge at 2013-04-24 15:15, a bunch of things happened. This may be where stuff went wrong. I do find it weird because it should have just been a fast forward, given what the history looks like. I suspect that this was caused by a `git annex sync`, but I'm not 100% sure.
+
+In this commit the following happened:
+
+* The box remote was duplicated (with different davcreds and one having highRandomQuality=false)
+* The annex remote was duplicated (with highRandomQuality=false in one)
+* The nas remote was duplicated (one with encryption=shared and highRandomQuality=false and the other without)
+
+In addition, within that commit, my uuid.log file also had duplication that seems to be where part of the confusion comes from:
+
+* The 1d0ab67c-6a43-11e2-9feb-df22c6d1e308 remote shows up twice, once named \"annex\" and the other time named \"s3\".
+* The 4d86972d-9b0a-4095-bc50-f9bec8144c30 remote is only include once in there, but its name is also \"s3\".
+* Other remotes are duplicated, with different timestamps, but no overlapping uuids.
+
+Then at 2013-04-24 18:13, I think things try to fix themselves:
+
+* The older box remote (I guess based on timestamp) is removed. Now there's only one.
+* The older 1d0ab67c-6a43-11e2-9feb-df22c6d1e308 remote (still named annex) is removed. Now there's only one there too.
+* The single 4d86972d-9b0a-4095-bc50-f9bec8144c30 remote is updated with a new timestamp.
+* The older nas remote is also removed.
+
+No duplicates exist in this file and no cross-references exist either.
+
+The uuid.log file seems to be the place where the annex remote is renamed to s3. I have no idea what caused that, but it was probably me.
+
+* In 2013-04-24 11:12, everything is fine in the uuid.log file. The annex timestamp is updated, but no problems.
+* In 2013-04-24 11:13 (which doesn't show up when I look at the remote.log changes, because it didn't change that), a file's location log is updated and the 1d0ab67c-6a43-11e2-9feb-df22c6d1e308 remote is renamed from annex to s3 in uuid.log, but not in remotes.log.
+* In 2013-04-24 11:26, 4d86972d-9b0a-4095-bc50-f9bec8144c30 is added to remotes.log with the name s3 and to uuid.log with the name s3 (which is now a duplicate of the renamed 1d0ab67c-6a43-11e2-9feb-df22c6d1e308, but only in uuid.log).
+
+All of this seems horribly confusing and I don't envy your trying to unwind it.
+
+"""]]
diff --git a/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_8_36519ee4499a19f0864e4fcd264e9933._comment b/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_8_36519ee4499a19f0864e4fcd264e9933._comment
new file mode 100644
index 000000000..39a1ce51d
--- /dev/null
+++ b/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_8_36519ee4499a19f0864e4fcd264e9933._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 8"
+ date="2013-04-26T20:06:34Z"
+ content="""
+Most of this is perfectly normal. The duplication of lines are normal; when two git-annex branches are union merged, it's as if it runs `cat branch1:file branch2:file | uniq > file`. When there are conflicting lines for the same uuid, the one with the newest timestamp is used.
+
+The description of the remote in uuid.log is also not relevant to this bug.
+
+This is the key part:
+
+> The box remote was duplicated (with different davcreds and one having highRandomQuality=false)
+
+As you note, 2013-04-24 15:15 was a merge. So there must have been two branches before, which had different box remotes with different davcreds.
+
+It would probably help if you can paste those lines as they looked after that merge (omitting most of the davcreds).
+
+Also, I'd like to see the box line from the 11:05 commit.
+"""]]
diff --git a/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_9_85b23f375e53469fb09b24b945b3aba9._comment b/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_9_85b23f375e53469fb09b24b945b3aba9._comment
new file mode 100644
index 000000000..be9bd3c0d
--- /dev/null
+++ b/doc/forum/Not_sure_how_to_get_my_s3_remote_back/comment_9_85b23f375e53469fb09b24b945b3aba9._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkZktNHFhxC1kYA9KKdKpYJO4clq9WDsjE"
+ nickname="Jason"
+ subject="comment 9"
+ date="2013-04-26T20:21:05Z"
+ content="""
+Two box lines after 15:15 merge:
+
+0490d177-78e2-421b-a004-47d88ee7a2e3 chunksize=10mb cipher=... davcreds=... embedcreds=yes highRandomQuality=false name=box.com type=webdav url=https://www.box.com/dav/annex timestamp=1366826729.945023s
+0490d177-78e2-421b-a004-47d88ee7a2e3 chunksize=10mb cipher=... davcreds=... embedcreds=yes name=box.com type=webdav url=https://www.box.com/dav/annex timestamp=1366657062.972357s
+
+After the 11:05 commit, the box line looked like this:
+
+0490d177-78e2-421b-a004-47d88ee7a2e3 chunksize=10mb cipher=... davcreds=... embedcreds=yes highRandomQuality=false name=box.com type=webdav url=https://www.box.com/dav/annex timestamp=1366826729.945023s
+
+I am curious why you want to know about box, when s3 is the one that I'm having trouble with...
+"""]]
diff --git a/doc/forum/OSX_Mavericks_anyone__63__.mdwn b/doc/forum/OSX_Mavericks_anyone__63__.mdwn
new file mode 100644
index 000000000..b19133680
--- /dev/null
+++ b/doc/forum/OSX_Mavericks_anyone__63__.mdwn
@@ -0,0 +1,3 @@
+Was anyone able to run git annex on Mavericks?
+
+Didn't have time for qualified troubleshooting, sorry
diff --git a/doc/forum/OSX_Mavericks_anyone__63__/comment_1_3075b02aeb57adcbf4addf9fb4c123ba._comment b/doc/forum/OSX_Mavericks_anyone__63__/comment_1_3075b02aeb57adcbf4addf9fb4c123ba._comment
new file mode 100644
index 000000000..1657d676d
--- /dev/null
+++ b/doc/forum/OSX_Mavericks_anyone__63__/comment_1_3075b02aeb57adcbf4addf9fb4c123ba._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://mike.magin.org/"
+ nickname="mmagin"
+ subject="a little"
+ date="2013-10-24T17:02:18Z"
+ content="""
+Some syncing and copying, nothing other than normal remotes and one S3 remote.
+Haven't even done an \"add\" yet.
+
+Not an assistant user. Still running 4.20130422-gb9341fd on this computer.
+"""]]
diff --git a/doc/forum/OSX_Mavericks_anyone__63__/comment_2_c2b6110fc4a3d3481ed8a4b48efb9635._comment b/doc/forum/OSX_Mavericks_anyone__63__/comment_2_c2b6110fc4a3d3481ed8a4b48efb9635._comment
new file mode 100644
index 000000000..bfc43d682
--- /dev/null
+++ b/doc/forum/OSX_Mavericks_anyone__63__/comment_2_c2b6110fc4a3d3481ed8a4b48efb9635._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="Alex"
+ ip="217.8.62.35"
+ subject="not at all"
+ date="2013-10-24T19:50:11Z"
+ content="""
+I'd love to see an updated OS X build for Mavericks.
+
+Currently I'm getting this error:
+
+ dyld: Symbol not found: _objc_debug_taggedpointer_mask
+ Referenced from: /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
+ Expected in: /Applications/git-annex.app/Contents/MacOS/bundle/I
+ in /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
+ Trace/BPT trap: 5
+
+"""]]
diff --git a/doc/forum/OSX_Mavericks_anyone__63__/comment_3_7df9ba63cb1f385681242b4b58d6a87c._comment b/doc/forum/OSX_Mavericks_anyone__63__/comment_3_7df9ba63cb1f385681242b4b58d6a87c._comment
new file mode 100644
index 000000000..691fd9064
--- /dev/null
+++ b/doc/forum/OSX_Mavericks_anyone__63__/comment_3_7df9ba63cb1f385681242b4b58d6a87c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="67.223.19.96"
+ subject="comment 3"
+ date="2013-10-24T19:53:08Z"
+ content="""
+Mavericks is being discussed [[here|bugs/git annex doesn't work in Max OS X 10.9]]
+"""]]
diff --git a/doc/forum/OSX_Mavericks_anyone__63__/comment_4_740fee31c4ca9d84428f97f63ffc075a._comment b/doc/forum/OSX_Mavericks_anyone__63__/comment_4_740fee31c4ca9d84428f97f63ffc075a._comment
new file mode 100644
index 000000000..3ad5c2344
--- /dev/null
+++ b/doc/forum/OSX_Mavericks_anyone__63__/comment_4_740fee31c4ca9d84428f97f63ffc075a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="Alex"
+ ip="217.8.62.35"
+ subject="comment 4"
+ date="2013-10-24T19:55:56Z"
+ content="""
+Thanks, Joey!
+"""]]
diff --git a/doc/forum/OSX__39__s_default_sshd_behaviour_has_limited_paths_set.mdwn b/doc/forum/OSX__39__s_default_sshd_behaviour_has_limited_paths_set.mdwn
new file mode 100644
index 000000000..5e417b14c
--- /dev/null
+++ b/doc/forum/OSX__39__s_default_sshd_behaviour_has_limited_paths_set.mdwn
@@ -0,0 +1,12 @@
+This is a tip for users who wish to use remotes which are based on OSX systems and have used macports to install some of the required utilities for git-annex to work.
+
+The default behaviour of OSX's sshd is to have a "highly restricted" restricted environment. The defaults that it allows is
+
+ jtang@x00:~ $ ssh x00 echo \$PATH
+ /usr/bin:/bin:/usr/sbin:/sbin
+
+One solution is to enable *PermitUserEnvironment yes* in `/etc/sshd_config` and then in your own `~/.ssh/environment` file you could add something like (the below is an example)
+
+ PATH=/Users/jtang/bin:/opt/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin:/usr/X11/bin:/Users/jtang/.cabal/bin:/opt/local/libexec/gnubin
+
+If the above is not done, cloning from the OSX host will fail if git is not installed in /usr/bin (which it probably won't be).
diff --git a/doc/forum/OSX__39__s_haskell-platform_statically_links_things.mdwn b/doc/forum/OSX__39__s_haskell-platform_statically_links_things.mdwn
new file mode 100644
index 000000000..537c85d01
--- /dev/null
+++ b/doc/forum/OSX__39__s_haskell-platform_statically_links_things.mdwn
@@ -0,0 +1,17 @@
+This isn't really a bug of git-annex, but a problem with haskell-platform/ghc6.12.x so this post might need to be moved to a better place (maybe tips).
+
+OSX's haskell-platform doesn't have the dynamic libraries available, as far as I know it just isn't supported therefore git-annex will always be statically built on OSX, so wrappers like <http://tsocks.sourceforge.net/> or [[!google dsocks]] for preloading connect() calls won't work.
+
+<pre>
+jtang@x00:~/annex $ tsocks git annex get .
+dyld: could not load inserted library: /opt/local/lib/libtsocks.dylib
+
+error: git-annex died of signal 5
+</pre>
+
+The side effect of this means that users who are behind restrictive firewalls that allow only ssh via a socks proxy, they will need to configure ssh to use something like <http://bent.latency.net/bent/git/goto-san-connect-1.85/src/connect.html>.
+
+<pre>
+host remotemyhost
+ ProxyCommand connect -S proxy.mydomain:1080 -R local %h %p
+</pre>
diff --git a/doc/forum/OpenOffice___47___Libre_Office.mdwn b/doc/forum/OpenOffice___47___Libre_Office.mdwn
new file mode 100644
index 000000000..f28ad6259
--- /dev/null
+++ b/doc/forum/OpenOffice___47___Libre_Office.mdwn
@@ -0,0 +1,5 @@
+I'm trying to use git-annex for keeping my company invoices data. It seems a good idea because it's encrypted and whatnot, I'd never upload them to Dropbox. However, Libre Office refuses to work with files copied to annex-tracked folder. It's likely a flaw in LO/OOo, but maybe someone here knows a way to make the two work together.
+
+When opening a spreadsheet, I'm getting a "Document in use - document locked by: Unknown User - Open read-only or open a copy" dialog. I tried opening a copy and saving under a different filename , but I can only save once - any subsequent saves to the same filename result in an error.
+
+A graphic version of my story: http://f.gdr.name/annex-ooo-1.png http://f.gdr.name/annex-ooo-2.png
diff --git a/doc/forum/OpenOffice___47___Libre_Office/comment_1_98ed542fedd820d47bf8deb7d3232725._comment b/doc/forum/OpenOffice___47___Libre_Office/comment_1_98ed542fedd820d47bf8deb7d3232725._comment
new file mode 100644
index 000000000..68dbee166
--- /dev/null
+++ b/doc/forum/OpenOffice___47___Libre_Office/comment_1_98ed542fedd820d47bf8deb7d3232725._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 1"
+ date="2013-01-02T19:10:28Z"
+ content="""
+Files in git-annex are locked normally. You can use `git annex unlock` to unlock a file for editing. Or you can use the new [[direct_mode]].
+"""]]
diff --git a/doc/forum/OpenOffice___47___Libre_Office/comment_2_f313fdaa23863c2ae99cfbfe9ec2e1e0._comment b/doc/forum/OpenOffice___47___Libre_Office/comment_2_f313fdaa23863c2ae99cfbfe9ec2e1e0._comment
new file mode 100644
index 000000000..394f6fb01
--- /dev/null
+++ b/doc/forum/OpenOffice___47___Libre_Office/comment_2_f313fdaa23863c2ae99cfbfe9ec2e1e0._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://launchpad.net/~gdr-go2"
+ nickname="gdr-go2"
+ subject="Thanks"
+ date="2013-01-02T19:58:44Z"
+ content="""
+Direct mode has solved the problem. Great new addition.
+"""]]
diff --git a/doc/forum/Out_of_memory_error_in_fsck__44___whereis__44___find_and_status_cmds.mdwn b/doc/forum/Out_of_memory_error_in_fsck__44___whereis__44___find_and_status_cmds.mdwn
new file mode 100644
index 000000000..8c54f49da
--- /dev/null
+++ b/doc/forum/Out_of_memory_error_in_fsck__44___whereis__44___find_and_status_cmds.mdwn
@@ -0,0 +1,5 @@
+Please file bug reports in [[bugs]], not the forum, so they can be closed
+when fixed.
+
+Moved to [[bug report|bugs/Out_of_memory_error_in_fsck_whereis_find_and_status_cmds]].
+--[[Joey]]
diff --git a/doc/forum/Overwriting_data_without_getting_it.mdwn b/doc/forum/Overwriting_data_without_getting_it.mdwn
new file mode 100644
index 000000000..ccd23b74e
--- /dev/null
+++ b/doc/forum/Overwriting_data_without_getting_it.mdwn
@@ -0,0 +1,3 @@
+My collaborators and I use git annex to track various large data files (among some smaller metadata files managed by ordinary git). Some of these data files need to change completely -- the old ones were just wrong. So I do a git checkout, but don't `git annex get` because it would just be a waste of time and bandwidth. This means that my "data files" are just broken symlinks. Now, I find that by making the necessary directories under `.git/annex/objects/`, I can write to these files in the usual way. The symlinks are preserved, and the files they link to now exist and are full of my corrected data. This seems like it's a problem because the hash has presumably changed. (I'm still a little fuzzy on how exactly git-annex works.) Also, git/git-annex doesn't seem to realize that anything has changed. Is this recoverable?
+
+Would it have been better to just `git rm` (or something) the original version of the file, commit that, and then add the new data? And if so, how should I go about this now that I've created these many very large files? If not, what would be the preferred way to do this?
diff --git a/doc/forum/Overwriting_data_without_getting_it/comment_1_f1c0199ee9bffcc84287370b89361294._comment b/doc/forum/Overwriting_data_without_getting_it/comment_1_f1c0199ee9bffcc84287370b89361294._comment
new file mode 100644
index 000000000..a6092b1f2
--- /dev/null
+++ b/doc/forum/Overwriting_data_without_getting_it/comment_1_f1c0199ee9bffcc84287370b89361294._comment
@@ -0,0 +1,26 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-06-12T16:57:52Z"
+ content="""
+I think you're making this more complicated than it needs to be. You don't need to mess around with .git/annex/objects at all. You can replace git-annex symlinks with new files and git annex add the new content.
+
+For example:
+
+[[!format sh \"\"\"
+joey@gnu:~/tmp/repo>git annex drop --force foo
+drop foo ok
+(Recording state in git...)
+joey@gnu:~/tmp/repo>ls
+foo@
+joey@gnu:~/tmp/repo>rm foo
+joey@gnu:~/tmp/repo>echo \"new good contents\" > foo
+joey@gnu:~/tmp/repo>git annex add foo
+add foo (checksum...) ok
+(Recording state in git...)
+joey@gnu:~/tmp/repo>git commit -m add
+[master ec3ed14] add
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+\"\"\"]]
+"""]]
diff --git a/doc/forum/Overwriting_data_without_getting_it/comment_2_6a1d08dbca206129ef6cf8aa97daeee1._comment b/doc/forum/Overwriting_data_without_getting_it/comment_2_6a1d08dbca206129ef6cf8aa97daeee1._comment
new file mode 100644
index 000000000..698d00c35
--- /dev/null
+++ b/doc/forum/Overwriting_data_without_getting_it/comment_2_6a1d08dbca206129ef6cf8aa97daeee1._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkxmke7K8gEXleVRuQvCK5LHPLIzQA6s0E"
+ nickname="Michael"
+ subject="comment 2"
+ date="2013-06-12T17:14:11Z"
+ content="""
+Yes, it seems I was making this more complicated than it needed to be. Just a plain rm seems to work. But just to be clear, I never had the data so I don't need to drop it, right? (By which I mean, is there some other function of drop that I don't understand?)
+"""]]
diff --git a/doc/forum/Overwriting_data_without_getting_it/comment_3_52958e76e506fdbb6b533681ab619b3b._comment b/doc/forum/Overwriting_data_without_getting_it/comment_3_52958e76e506fdbb6b533681ab619b3b._comment
new file mode 100644
index 000000000..19292b870
--- /dev/null
+++ b/doc/forum/Overwriting_data_without_getting_it/comment_3_52958e76e506fdbb6b533681ab619b3b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-06-12T17:15:26Z"
+ content="""
+Right. I just put the drop in there to get my repository to the state you described.
+"""]]
diff --git a/doc/forum/Permission_denied___40__publickey__41___On_second_Step_...___63__.mdwn b/doc/forum/Permission_denied___40__publickey__41___On_second_Step_...___63__.mdwn
new file mode 100644
index 000000000..caa9fc85a
--- /dev/null
+++ b/doc/forum/Permission_denied___40__publickey__41___On_second_Step_...___63__.mdwn
@@ -0,0 +1,36 @@
+Hello,
+
+I've a strange (for me ;-)) problem.
+<br>I'm trying to use git-annex with 2 debian wheezy (packages from backports)
+<br>I've put my ssh pub key on the server in the autorized_keys for my username account (and for the root account to be sure)
+my username account is member of the sudo group (not sure it's required)
+
+I can create an ssh session directly to the server with :
+
+ ssh username@remoteserver.lan -p 62322
+
+and work inside this session.
+
+ Sep 14 03:42:35 file sshd[8849]: Accepted publickey for username from 80.201.25.4 port 32969 ssh2
+ Sep 14 03:42:35 file sshd[8849]: pam_unix(sshd:session): session opened for user username by (uid=0)
+ ...
+ Sep 14 05:13:14 file sshd[8851]: Received disconnect from 80.201.25.4: 11: disconnected by user
+ Sep 14 05:13:14 file sshd[8849]: pam_unix(sshd:session): session closed for user username
+
+But when I use the git-annex assistant on the same workstation with the same remote server and port,
+<br>the 1st step is OK,
+<br>but when I've to choose between git or rsync encrypted, I'm choosing git and receive :
+
+ "Permission denied (publickey)."
+
+On the server I can only see that the ssh session is immediately closed after opened and before the choice git or rsync is made.
+
+ Sep 14 05:13:42 file sshd[8882]: Accepted publickey for username from 80.201.25.4 port 32984 ssh2
+ Sep 14 05:13:42 file sshd[8882]: pam_unix(sshd:session): session opened for user username by (uid=0)
+ Sep 14 05:13:42 file sshd[8886]: Received disconnect from 80.201.25.4: 11: disconnected by user
+ Sep 14 05:13:42 file sshd[8882]: pam_unix(sshd:session): session closed for user username
+
+Do you think it's the problem ? or whatelse ...
+<br>and could you guide me to a possible solution ?
+
+Best regards
diff --git a/doc/forum/Permission_denied___40__publickey__41___On_second_Step_...___63__/comment_1_6c74f0b43c457fe97b2d8630ca4fde29._comment b/doc/forum/Permission_denied___40__publickey__41___On_second_Step_...___63__/comment_1_6c74f0b43c457fe97b2d8630ca4fde29._comment
new file mode 100644
index 000000000..8d2215772
--- /dev/null
+++ b/doc/forum/Permission_denied___40__publickey__41___On_second_Step_...___63__/comment_1_6c74f0b43c457fe97b2d8630ca4fde29._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="108.236.230.124"
+ subject="comment 1"
+ date="2013-11-08T18:24:27Z"
+ content="""
+The webapp sets up a dedicated ssh public key when you add a ssh repository in there.
+
+You might see some useful debugging info your your problem in ~/annex/.git/annex/daemon.log
+"""]]
diff --git a/doc/forum/Permission_denied___40__publickey__41___On_second_Step_...___63__/comment_2_b7a384e853e1756a684774348fad29e6._comment b/doc/forum/Permission_denied___40__publickey__41___On_second_Step_...___63__/comment_2_b7a384e853e1756a684774348fad29e6._comment
new file mode 100644
index 000000000..ecf26daa1
--- /dev/null
+++ b/doc/forum/Permission_denied___40__publickey__41___On_second_Step_...___63__/comment_2_b7a384e853e1756a684774348fad29e6._comment
@@ -0,0 +1,22 @@
+[[!comment format=mdwn
+ username="Auroch"
+ ip="87.65.174.80"
+ subject="OK,thanx for this"
+ date="2013-11-09T09:10:42Z"
+ content="""
+The problem is not solve, but with your informations, I think i've found somehting.
+
+Is it possible that the problem is linked to my situation of port-forwarding ?
+The remoteserver is a host (proxmox) with iptable port forwarding 62322 to the real port 22 of the VM hosting the git where I try to connect.
+
+So could the problem seems to be that some actions are taken on the host and not the VM ... correct ?
+
+ [2013-11-09 09:51:33 CET] read: ssh-keygen [\"-F\",\"bla.remote.tld\"]
+ [2013-11-09 09:51:33 CET] read: ssh [\"-oNumberOfPasswordPrompts=0\",\"-n\",\"-p\",\"62322\",\"user@bla.remote.tld\",\"sh -c 'echo git-annex-probe loggedin;if which git-annex-shell; then echo git-annex-probe git-annex-shell; fi;if which rsync; then echo git-annex-probe rsync; fi;if which ~/.ssh/git-annex-shell; then echo git-annex-probe ~/.ssh/git-annex-shell; fi'\"]
+ [2013-11-09 09:51:35 CET] chat: ssh [\"user@bla.remote.tld\",\"sh -c 'mkdir -p '\\"'\\"'annex'\\"'\\"'&&cd '\\"'\\"'annex'\\"'\\"'&&if [ ! -d .git ]; then git init --bare --shared; fi&&git annex init'\"]
+
+If it's correct, have you an idea for solving this ?
+
+best regards
+
+"""]]
diff --git a/doc/forum/Permission_denied___40__publickey__41___On_second_Step_...___63__/comment_3_3a8a7f51cb04a92c576549d379b57248._comment b/doc/forum/Permission_denied___40__publickey__41___On_second_Step_...___63__/comment_3_3a8a7f51cb04a92c576549d379b57248._comment
new file mode 100644
index 000000000..546f647ed
--- /dev/null
+++ b/doc/forum/Permission_denied___40__publickey__41___On_second_Step_...___63__/comment_3_3a8a7f51cb04a92c576549d379b57248._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.246"
+ subject="comment 3"
+ date="2013-11-09T18:07:56Z"
+ content="""
+Well, it does look like your git-annex did not pass the port to the second command.
+
+What version are you using? I've just tested with a ssh server only listening on 2222 and it used the port throughout.
+
+You might try upgrading to a recent version. I know that version 4.20130627, at least, had a bug with the ssh port.
+"""]]
diff --git a/doc/forum/Permission_denied___40__publickey__41___On_second_Step_...___63__/comment_4_582ad3ba0c62a77b08a10b37a780c670._comment b/doc/forum/Permission_denied___40__publickey__41___On_second_Step_...___63__/comment_4_582ad3ba0c62a77b08a10b37a780c670._comment
new file mode 100644
index 000000000..c8d8c8b52
--- /dev/null
+++ b/doc/forum/Permission_denied___40__publickey__41___On_second_Step_...___63__/comment_4_582ad3ba0c62a77b08a10b37a780c670._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="Auroch"
+ ip="87.65.174.80"
+ subject="comment 4"
+ date="2013-11-09T19:24:54Z"
+ content="""
+I've the wheezy-backports version
+
+ i 4.20131002~bpo70+1 wheezy-backports 100
+
+I'll have to wait an update and I'll come back to you.
+
+Thanx this amazing work !
+
+"""]]
diff --git a/doc/forum/Please_fix_compatibility_with_ghc_7.0.mdwn b/doc/forum/Please_fix_compatibility_with_ghc_7.0.mdwn
new file mode 100644
index 000000000..d49081bf3
--- /dev/null
+++ b/doc/forum/Please_fix_compatibility_with_ghc_7.0.mdwn
@@ -0,0 +1 @@
+I'm having trouble installing the latest git-annex. It depends on 'base >= 4.5 && base < 5', but ghc 7.0 only ships base 3.0. I've tried upgrading ghc to 7.4 but that breaks a whole bunch of other things; for example, the Crypto module fails to compile, preventing me from installing ghc. Please fix compatibility with ghc 7.0.
diff --git a/doc/forum/Please_fix_compatibility_with_ghc_7.0/comment_1_d1d10217ebd0151e947b3a6cd37399ce._comment b/doc/forum/Please_fix_compatibility_with_ghc_7.0/comment_1_d1d10217ebd0151e947b3a6cd37399ce._comment
new file mode 100644
index 000000000..04b8ce675
--- /dev/null
+++ b/doc/forum/Please_fix_compatibility_with_ghc_7.0/comment_1_d1d10217ebd0151e947b3a6cd37399ce._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2012-03-11T15:50:11Z"
+ content="""
+There is a `ghc7.0` branch in [[git|download]] that is being maintained to work with that version.
+"""]]
diff --git a/doc/forum/Please_publish_new_releases_not_shorter_than_11_days.mdwn b/doc/forum/Please_publish_new_releases_not_shorter_than_11_days.mdwn
new file mode 100644
index 000000000..f67d2d797
--- /dev/null
+++ b/doc/forum/Please_publish_new_releases_not_shorter_than_11_days.mdwn
@@ -0,0 +1,6 @@
+Hi,
+i am following debian testing. The latest git-annex publication has manged to replace the former version on the last possible moment. Now another 10 days waiting.
+Would be nice if you can coordinate with testing.
+
+Thank you for git-annex.
+Jürgen
diff --git a/doc/forum/Please_publish_new_releases_not_shorter_than_11_days/comment_1_da3d39de5be47ebe8b25a42ed1f36510._comment b/doc/forum/Please_publish_new_releases_not_shorter_than_11_days/comment_1_da3d39de5be47ebe8b25a42ed1f36510._comment
new file mode 100644
index 000000000..1fb259c98
--- /dev/null
+++ b/doc/forum/Please_publish_new_releases_not_shorter_than_11_days/comment_1_da3d39de5be47ebe8b25a42ed1f36510._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 1"
+ date="2013-11-03T19:57:24Z"
+ content="""
+I do coordinate with testing. That version had no possibility of ever reaching testing, since it failed to build on several architectures.
+"""]]
diff --git a/doc/forum/Podcast_syncing_use-case.mdwn b/doc/forum/Podcast_syncing_use-case.mdwn
new file mode 100644
index 000000000..6b3c81cab
--- /dev/null
+++ b/doc/forum/Podcast_syncing_use-case.mdwn
@@ -0,0 +1,34 @@
+I've been trying to use git-annex with the following strategy.
+
+* Download podcasts into the annex `gpodder-downloads`
+* Check the podcasts into the annex using `git annex add`.
+* Copy the podcasts over to my mp3 player in the annex `usb-ariaz`.
+ This is a FAT-formatted mp3 player, so I have been using a bare
+ repository.
+* Move the podcasts to a different annex called `gpodder-on-usbdisk`
+ to indicate that they have been successfully put on the mp3 player.
+* `chmod` the files on the mp3 player to `0600` so that I can delete
+ them from the player when I am done listening to them.
+
+Then I go for a run or something and listen to a bunch of podcasts,
+deleting them after I have listened to them. When I get back, I would
+like to find the files that I have listened to and remove them from
+the annexes that are not on the mp3 player. What I have been hoping
+is that something like
+
+ ~/gpodder-on-usbdisk $ git annex find --not --in usb-ariaz --print0 | xargs -0 git rm
+ ~/gpodder-on-usbdisk $ git annex unused
+ ~/gpodder-on-usbdisk $ git annex dropunused `seq X`
+
+would work. However, it appears that `git-annex find` does not
+actually check to see that the file contents are present, but only
+looks at the `git-annex` branch of the `usb-ariaz` repository. Since
+I have not changed that with my sneaky deletions, it has no way of
+knowing that the files have been deleted.
+
+Is there any way to do this properly? (And by properly, I don't mean
+"don't delete the files". That is really the only way I have of
+marking that I have listened to podcasts on this particular mp3 player.)
+
+I tried setting the `usb-ariaz` repository to be untrusted, but that
+did not change the behavior of `git annex find`.
diff --git a/doc/forum/Podcast_syncing_use-case/comment_1_ace6f9d3a950348a3ac0ff592b62e786._comment b/doc/forum/Podcast_syncing_use-case/comment_1_ace6f9d3a950348a3ac0ff592b62e786._comment
new file mode 100644
index 000000000..fe396c39f
--- /dev/null
+++ b/doc/forum/Podcast_syncing_use-case/comment_1_ace6f9d3a950348a3ac0ff592b62e786._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-11-27T17:56:31Z"
+ content="""
+Right, --in goes by git-annex's [[location_tracking]] information; actually checking if a remote still has the files would make --in too expensive in many cases.
+
+So you need to give `gpodder-on-usbdisk` current information. You can do that by going to `usb-ariaz` and doing a `git annex fsck`. That will find the deleted files and update the location information. Then, back on `gpodder-on-usbdisk`, `git pull usb-ariaz`, and then you can proceed with the commands you showed.
+"""]]
diff --git a/doc/forum/Podcast_syncing_use-case/comment_2_930a6620b4d516e69ed952f9da5371bb._comment b/doc/forum/Podcast_syncing_use-case/comment_2_930a6620b4d516e69ed952f9da5371bb._comment
new file mode 100644
index 000000000..97eb3c681
--- /dev/null
+++ b/doc/forum/Podcast_syncing_use-case/comment_2_930a6620b4d516e69ed952f9da5371bb._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://cgray.myopenid.com/"
+ nickname="cgray"
+ subject="comment 2"
+ date="2011-11-27T22:10:44Z"
+ content="""
+Thanks, that works perfectly!
+"""]]
diff --git a/doc/forum/Poor_man__39__s_IMAP.mdwn b/doc/forum/Poor_man__39__s_IMAP.mdwn
new file mode 100644
index 000000000..af53ddc19
--- /dev/null
+++ b/doc/forum/Poor_man__39__s_IMAP.mdwn
@@ -0,0 +1,6 @@
+I have an e-mail server configured to save my mail in ~/Maildir on an account that is available over ssh. I'd like to keep emailserver:~/Maildir in a two-way sync with laptop:~/Mail/private essentially creating a poor man's IMAP — without setting up and maintaining an actual IMAP server. **Is it an appropriate use of git-annex or would another tool be more fitting? And how do I go about doing it?** I'd like to sync the files, the content, not just information about the files or other meta-data.
+
+I tried setting it up with the webUI to the assistant but it only offers encrypted storage[1] on the remote server. I looked into setting it up manually but "git-annex does not notice when files are added to remote rsync repositories."[2]
+
+[1] http://git-annex.branchable.com/bugs/Remote_repositories_have_to_be_setup_encrypted/
+[2] from comments on http://git-annex.branchable.com/special_remotes/rsync/
diff --git a/doc/forum/Poor_man__39__s_IMAP/comment_1_258ff23c462dc88b88ced405c4f5040f._comment b/doc/forum/Poor_man__39__s_IMAP/comment_1_258ff23c462dc88b88ced405c4f5040f._comment
new file mode 100644
index 000000000..8965f18be
--- /dev/null
+++ b/doc/forum/Poor_man__39__s_IMAP/comment_1_258ff23c462dc88b88ced405c4f5040f._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://a-or-b.myopenid.com/"
+ ip="220.244.41.108"
+ subject="comment 1"
+ date="2013-08-14T06:45:56Z"
+ content="""
+I'd say that git-annex is the wrong tool.
+
+OfflineIMAP ([[http://offlineimap.org]]) is simple to set up, is easy to secure over ssh and does exactly what you want.
+
+"""]]
diff --git a/doc/forum/Poor_man__39__s_IMAP/comment_2_c88d1abdda4cb526a6ee45a710c75bc4._comment b/doc/forum/Poor_man__39__s_IMAP/comment_2_c88d1abdda4cb526a6ee45a710c75bc4._comment
new file mode 100644
index 000000000..4ab7af46b
--- /dev/null
+++ b/doc/forum/Poor_man__39__s_IMAP/comment_2_c88d1abdda4cb526a6ee45a710c75bc4._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://a-or-b.myopenid.com/"
+ ip="220.244.41.108"
+ subject="comment 2"
+ date="2013-08-14T06:53:04Z"
+ content="""
+From my massive amount of googling, i.e. 2min, apparently mbsync ([[http://isync.sourceforge.net/mbsync.html]]) is good too.
+
+I've never used it, so YMMV.
+"""]]
diff --git a/doc/forum/Poor_man__39__s_IMAP/comment_3_3847e371db1c2788c075e7dca1fbd33e._comment b/doc/forum/Poor_man__39__s_IMAP/comment_3_3847e371db1c2788c075e7dca1fbd33e._comment
new file mode 100644
index 000000000..a8ed31475
--- /dev/null
+++ b/doc/forum/Poor_man__39__s_IMAP/comment_3_3847e371db1c2788c075e7dca1fbd33e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://spindritf.myopenid.com/"
+ nickname="spindritf"
+ subject="comment 3"
+ date="2013-08-14T07:30:30Z"
+ content="""
+Offlineimap connects to an IMAP server and I was hoping to avoid running one. Thanks though.
+"""]]
diff --git a/doc/forum/Poor_man__39__s_IMAP/comment_4_cf6cc21f2cf2aa5c949844e24a7b4075._comment b/doc/forum/Poor_man__39__s_IMAP/comment_4_cf6cc21f2cf2aa5c949844e24a7b4075._comment
new file mode 100644
index 000000000..bcb698216
--- /dev/null
+++ b/doc/forum/Poor_man__39__s_IMAP/comment_4_cf6cc21f2cf2aa5c949844e24a7b4075._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/FHnTlSBo1eCGJRwueeKeB6.RCaPbGMPr5jxx8A--#ce0d8"
+ nickname="Hamza"
+ subject="comment 4"
+ date="2013-08-14T11:11:59Z"
+ content="""
+IMHO It is not the wrong tool for the job, after all the whole point of assistant is to sync folder across machines. I have a similar setup. I have two folders on two machines plus an encrypted repo on an ssh server. On both folders (local/server) i keep webapp running they sync using the encrypted repo/xmpp. The only downside to this approach is that VPS has two copies of every file one in the folder on in the encrypted git repo.
+"""]]
diff --git a/doc/forum/Poor_man__39__s_IMAP/comment_5_d861fa69475ce526841b3195be8ee356._comment b/doc/forum/Poor_man__39__s_IMAP/comment_5_d861fa69475ce526841b3195be8ee356._comment
new file mode 100644
index 000000000..d5621bb4a
--- /dev/null
+++ b/doc/forum/Poor_man__39__s_IMAP/comment_5_d861fa69475ce526841b3195be8ee356._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://spindritf.myopenid.com/"
+ nickname="spindritf"
+ subject="comment 5"
+ date="2013-08-14T18:08:22Z"
+ content="""
+> IMHO It is not the wrong tool for the job, after all the whole point of assistant is to sync folder across machines.
+
+That's what I thought. OK, so how do I do it? Should I set up this rsync special remote and run sync every once in a while. When starting the e-mail client for example?
+"""]]
diff --git a/doc/forum/Poor_man__39__s_IMAP/comment_6_1e81bd4bb62652bc674cdcd7ed57ac5c._comment b/doc/forum/Poor_man__39__s_IMAP/comment_6_1e81bd4bb62652bc674cdcd7ed57ac5c._comment
new file mode 100644
index 000000000..7e0720456
--- /dev/null
+++ b/doc/forum/Poor_man__39__s_IMAP/comment_6_1e81bd4bb62652bc674cdcd7ed57ac5c._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/FHnTlSBo1eCGJRwueeKeB6.RCaPbGMPr5jxx8A--#ce0d8"
+ nickname="Hamza"
+ subject="comment 6"
+ date="2013-08-16T09:14:52Z"
+ content="""
+You can either keep running 2 webapps paired using xmpp running all the time that gives you push like notifications or if you are ok with syncing every once in a while you can have a check mail script that adds files on the server commits them then calls git annex sync locally,
+
+ ssh $1 \"cd /path/to/annex/;git add .;git commit 'Update'\";git annex sync
+
+should do the trick. The latter method you just need to annex repos no encrypted third repo. Just init your git annex repo on the server and clone on the laptop thats it.
+"""]]
diff --git a/doc/forum/Poor_man__39__s_IMAP/comment_7_b3929281dff6078d77f1b9ae42e25bb6._comment b/doc/forum/Poor_man__39__s_IMAP/comment_7_b3929281dff6078d77f1b9ae42e25bb6._comment
new file mode 100644
index 000000000..aba4cd0de
--- /dev/null
+++ b/doc/forum/Poor_man__39__s_IMAP/comment_7_b3929281dff6078d77f1b9ae42e25bb6._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 7"
+ date="2013-08-23T18:30:04Z"
+ content="""
+I don't feel that git-annex is the best thing to use for this. Maildir has some specific semantics for the filenames used in it that let imap clients resolve inconsistencies, such as a message that was read on machine A, and deleted on machine B. git-annex is unlikely to work as well.
+
+However, I have to say that the very beginning of this thread has a wrong statement in it.
+
+> I tried setting it up with the webUI to the assistant but it only offers encrypted storage[1] on the remote server.
+
+If you install git and git-annex on your remote server, the git-annex assistant will detect this, and offer the choice between a regular git repository, and encrypted storage. If you don't have them installed, it tells you you don't, offers to let you retry once you do install them, and offers encrypted storage as the only option that works given what's installed on the server.
+
+(Also, the bug you linked to in [1] has nothing at all to do with what you were talking about.)
+"""]]
diff --git a/doc/forum/Poor_man__39__s_IMAP/comment_8_69506e8c519196f44b9ed15b32f00106._comment b/doc/forum/Poor_man__39__s_IMAP/comment_8_69506e8c519196f44b9ed15b32f00106._comment
new file mode 100644
index 000000000..18b99a880
--- /dev/null
+++ b/doc/forum/Poor_man__39__s_IMAP/comment_8_69506e8c519196f44b9ed15b32f00106._comment
@@ -0,0 +1,22 @@
+[[!comment format=mdwn
+ username="konubinix"
+ ip="82.243.233.186"
+ subject="And with a lots of mails?"
+ date="2013-08-27T06:44:56Z"
+ content="""
+Hi,
+
+I have a question quite similar, but for a different purpose. I use OfflineImap for imap synchronisation, but in my current situation, I travel a lot between two places: one connected to the Internet and the other not connected.
+
+When I am connected to the Internet, I may synchronize mails, then I rsync my ~/Mail directory to a usb key so that I have access to them in the place without connection. The mails filenames may be changed as Joeyh mentioned while I read or delete them. I rsync them back to the usb key before going back to the place with Internet connection, where the OfflineImap synchronization may occur.
+
+This solution, with rsynced key, works well. But I would love a history of what was done with file names and may be able to retrieve an old mail.
+
+I figured out that that the git annex was a really good solution for that.
+
+The main drawback from my point of view is that I have around 100 000 mails (some would say that's \"[Not much mail](http://notmuchmail.org/)\"), and I am afraid that git will be quite slow with that amount of files.
+
+Did anyone experience an annexed repository with so many items it in?
+
+Best
+"""]]
diff --git a/doc/forum/Post-Kickstarter.mdwn b/doc/forum/Post-Kickstarter.mdwn
new file mode 100644
index 000000000..d774ca25b
--- /dev/null
+++ b/doc/forum/Post-Kickstarter.mdwn
@@ -0,0 +1,5 @@
+We're nearing the end of the year of development funded by Kickstarter. I'm curious to know what the future of the project looks like.
+
+I assume that development will decrease from its current levels as you focus more of your energy on activities that put bread on the table, but is git-annex still something that you foresee actively working on or will it be in more of a feature-freeze-bug-fix stage?
+
+As a backer my only regret is that during the campaign I wasn't able to donate as much as I would have liked. The project has exceeded my expectations since then. I don't know that another Kickstarter campaign is worth the effort, but if you were to ask for donations to fund another month or two or three I would gladly donate. Or perhaps implement a feature-bounty program where users could donate money toward development of a particular feature they would like to see added. Or perhaps you're sick of working for the Internet!
diff --git a/doc/forum/Preserving_file_access_rights_in_directory_tree_below_objects__47__.mdwn b/doc/forum/Preserving_file_access_rights_in_directory_tree_below_objects__47__.mdwn
new file mode 100644
index 000000000..d89bcee29
--- /dev/null
+++ b/doc/forum/Preserving_file_access_rights_in_directory_tree_below_objects__47__.mdwn
@@ -0,0 +1,77 @@
+Hello,
+
+I have the problem that, while git-annex preserves the file access rights (user, group, others) for the actual file, it does not make sure that others can access this file through the directory tree above said file:
+
+ /tmp $ mkdir test
+ /tmp $ chown claudius:media test
+ /tmp $ chmod 750 test
+ /tmp $ ls -dl test
+ drwxr-x--- 2 claudius media 40 2012-01-23 19:27 test/
+ /tmp $ cd test
+ /tmp/test $ git init --shared=all
+ Initialized empty shared Git repository in /tmp/test/.git/
+ /tmp/test $ git annex init "test"
+ init test ok
+ /tmp/test $ echo 123 > abc
+ /tmp/test $ chmod 640 abc
+ /tmp/test $ chown claudius:media abc
+ /tmp/test $ ls -l
+ total 4
+ -rw-r----- 1 claudius media 4 2012-01-23 19:27 abc
+ /tmp/test $ git annex add .
+ add abc (checksum...) ok
+ (Recording state in git...)
+ /tmp/test $ ls -l
+ total 4
+ lrwxrwxrwx 1 claudius claudius 176 2012-01-23 19:27 abc -> .git/annex/objects/8F/pj/SHA256-s4--181210f8f9c779c26da1d9b2075bde0127302ee0e3fca38c9a83f5b1dd8e5d3b/SHA256-s4--181210f8f9c779c26da1d9b2075bde0127302ee0e3fca38c9a83f5b1dd8e5d3b
+ /tmp/test $ ls -l .git/annex/objects/8F/pj/SHA256-s4--181210f8f9c779c26da1d9b2075bde0127302ee0e3fca38c9a83f5b1dd8e5d3b/SHA256-s4--181210f8f9c779c26da1d9b2075bde0127302ee0e3fca38c9a83f5b1dd8e5d3b
+ -r--r----- 1 claudius media 4 2012-01-23 19:27 .git/annex/objects/8F/pj/SHA256-s4--181210f8f9c779c26da1d9b2075bde0127302ee0e3fca38c9a83f5b1dd8e5d3b/SHA256-s4--181210f8f9c779c26da1d9b2075bde0127302ee0e3fca38c9a83f5b1dd8e5d3b
+ /tmp/test $ ls -lR .git/annex/objects/
+ .git/annex/objects/:
+ total 0
+ drwx--S--- 3 claudius claudius 60 2012-01-23 19:28 8F/
+
+ .git/annex/objects/8F:
+ total 0
+ drwx--S--- 3 claudius claudius 60 2012-01-23 19:28 pj/
+
+ .git/annex/objects/8F/pj:
+ total 0
+ dr-x--S--- 2 claudius claudius 60 2012-01-23 19:28 SHA256-s4--181210f8f9c779c26da1d9b2075bde0127302ee0e3fca38c9a83f5b1dd8e5d3b/
+
+ .git/annex/objects/8F/pj/SHA256-s4--181210f8f9c779c26da1d9b2075bde0127302ee0e3fca38c9a83f5b1dd8e5d3b:
+ total 4
+ -r--r----- 1 claudius media 4 2012-01-23 19:27 SHA256-s4--181210f8f9c779c26da1d9b2075bde0127302ee0e3fca38c9a83f5b1dd8e5d3b
+ /tmp/test $ stat .git/annex/objects/
+ File: `.git/annex/objects/'
+ Size: 60 Blocks: 0 IO Block: 4096 directory
+ Device: 11h/17d Inode: 2365970 Links: 3
+ Access: (2700/drwx--S---) Uid: ( 1000/claudius) Gid: ( 1000/claudius)
+ Access: 2012-01-23 19:28:10.614948386 +0100
+ Modify: 2012-01-23 19:28:10.614948386 +0100
+ Change: 2012-01-23 19:28:10.614948386 +0100
+ Birth: -
+
+The use case is that I have a rather large collection of music I would like to manage with git-annex in various locations (all of it on my external hard drive, some on my notebook etc. This music is played by MPD, which can access the collection because it is in the "media" group. After changing to git-annex, however, this fails.
+
+I tried to avoid this specific problem by declaring the git repository to be shared, which does appear to have some effect on the other files in .git:
+
+ /tmp/test $ ls -l .git
+ total 16
+ drwx--S--- 5 claudius claudius 160 2012-01-23 19:28 annex/
+ drwxrwsr-x 2 claudius claudius 40 2012-01-23 19:27 branches/
+ -rw-rw-r-- 1 claudius claudius 218 2012-01-23 19:27 config
+ -rw-rw-r-- 1 claudius claudius 73 2012-01-23 19:27 description
+ -rw-rw-r-- 1 claudius claudius 23 2012-01-23 19:27 HEAD
+ drwxrwsr-x 2 claudius claudius 220 2012-01-23 19:27 hooks/
+ -rw-rw-r-- 1 claudius claudius 104 2012-01-23 19:28 index
+ drwxrwsr-x 2 claudius claudius 60 2012-01-23 19:27 info/
+ drwxrwsr-x 3 claudius claudius 60 2012-01-23 19:27 logs/
+ drwxrwsr-x 15 claudius claudius 300 2012-01-23 19:28 objects/
+ drwxrwsr-x 4 claudius claudius 80 2012-01-23 19:27 refs/
+
+I could obviously try to change the rights of annex/, annex/objects etc., but I would like to avoid having to adapt them each time a new folder is added somewhere below annex/objects/.
+
+My knowledge of git and especially git-annex is not too good, so it might well be that I missed something obvious. Any hints? :)
+
+(And thank you, of course, for taking the time to read all this)
diff --git a/doc/forum/Preserving_file_access_rights_in_directory_tree_below_objects__47__/comment_1_5dd978f9b5a0771f44ab9e086bf5a07f._comment b/doc/forum/Preserving_file_access_rights_in_directory_tree_below_objects__47__/comment_1_5dd978f9b5a0771f44ab9e086bf5a07f._comment
new file mode 100644
index 000000000..d2da5e94d
--- /dev/null
+++ b/doc/forum/Preserving_file_access_rights_in_directory_tree_below_objects__47__/comment_1_5dd978f9b5a0771f44ab9e086bf5a07f._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2012-01-23T19:00:40Z"
+ content="""
+You say you started the repo with \"git init --shared\" .. but what that's really meant for is bare repositories, which can have several users pushing into it, not a non-bare repository.
+
+The strange mode on the directories \"dr-x--S---\" and files \"-r--r-----\" must be due to your umask setting though. My umask is 022 and the directories and files under `.git/annex/objects` are \"drwxr-xr-x\" and \"-r--r--r--\", which allows anyone to read them unless an upper directory blocks it -- and with this umask, none do unless I explicitly remove permissions from one to lock down a repository.
+
+About mpd, the obvious fix is to run mpd not as a system user but as yourself. I put \"@reboot mpd\" in my crontab to do this.
+
+
+"""]]
diff --git a/doc/forum/Preserving_file_access_rights_in_directory_tree_below_objects__47__/comment_2_9f51947b35ee04e473655e20d56c740a._comment b/doc/forum/Preserving_file_access_rights_in_directory_tree_below_objects__47__/comment_2_9f51947b35ee04e473655e20d56c740a._comment
new file mode 100644
index 000000000..5d632ab86
--- /dev/null
+++ b/doc/forum/Preserving_file_access_rights_in_directory_tree_below_objects__47__/comment_2_9f51947b35ee04e473655e20d56c740a._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlB7-aXsqwzOi2BIR_Q4sUF8sjj24H6F3c"
+ nickname="Claudius"
+ subject="comment 2"
+ date="2012-01-23T19:39:17Z"
+ content="""
+Thank you for your comment! Indeed, setting the umask to, for example, 022 has the desired effect that annex/objects etc. are executable (and in this special case also writable), my previous umask setting was 077; the \"strange\" permissions on the git directories was probably due to --shared=all, and the mode of \"440\" on the files within the git-annex tree is correct (the original file was 640 and stripped of its write permission).
+
+Using this umask setting and newgrp to switch the default group, I was successfully able to set up the repositories.
+
+However, I would like to suggest adding the execute bit to the directories below .git/annex/objects/ per default, even if the umask of the current shell differs. As the correct rights are already preserved in the actual files (minus their write permission) together with correct owner and group, the files are still protected the same way as previously, and because +x does not allow directory listings, no additional information can leak out either. Not having to set the umask to something \"sensible\" before operating git-annex would be a huge plus, too :)
+
+The reason why I am not running MPD as my user is that I am a bit wary of running an application even exposed to the local network as my main user, and I see nothing wrong with running it as its own user.
+
+Thank you again for your help and the time you put into this project!
+"""]]
diff --git a/doc/forum/Problem_compiling_current_master.mdwn b/doc/forum/Problem_compiling_current_master.mdwn
new file mode 100644
index 000000000..d79dcd0b4
--- /dev/null
+++ b/doc/forum/Problem_compiling_current_master.mdwn
@@ -0,0 +1,12 @@
+While trying to compile the current master I run in the following error:
+
+ Utility/Yesod.hs:21:14:
+ Couldn't match expected type `String'
+ with actual type `WidgetFileSettings'
+ Expected type: String -> Q Exp
+ Actual type: WidgetFileSettings -> FilePath -> Q Exp
+ In the expression: widgetFileNoReload
+ In an equation for `widgetFile': widgetFile = widgetFileNoReload
+ make: *** [git-annex] Fehler 1
+
+I installed all dependencies from the INSTALL document. What is wrong?
diff --git a/doc/forum/Problem_compiling_current_master/comment_1_135df61ec850c06e3b48ccfef7b5b031._comment b/doc/forum/Problem_compiling_current_master/comment_1_135df61ec850c06e3b48ccfef7b5b031._comment
new file mode 100644
index 000000000..676cc697d
--- /dev/null
+++ b/doc/forum/Problem_compiling_current_master/comment_1_135df61ec850c06e3b48ccfef7b5b031._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.16"
+ subject="comment 1"
+ date="2012-08-29T15:51:15Z"
+ content="""
+I think you're building with the Makefile, not with cabal, and have the recent yesod 1.1.0 release installed. The Makefile contains a -DWITH_OLD_YESOD that you need to remove in that situation.
+"""]]
diff --git a/doc/forum/Problem_compiling_current_master/comment_2_fb3e27b6014e84bd919a7a4a95e39ef9._comment b/doc/forum/Problem_compiling_current_master/comment_2_fb3e27b6014e84bd919a7a4a95e39ef9._comment
new file mode 100644
index 000000000..61c6f3be6
--- /dev/null
+++ b/doc/forum/Problem_compiling_current_master/comment_2_fb3e27b6014e84bd919a7a4a95e39ef9._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmU_2tE75oyG0h2ZPN4lcroIKEMC8G-otE"
+ nickname="Michael"
+ subject="comment 2"
+ date="2012-08-30T11:32:24Z"
+ content="""
+That helped now the compile stops at:
+
+ Utility/WebApp.hs:106:9:
+ Ambiguous occurrence `liftIO'
+ It could refer to either `Yesod.liftIO',
+ imported from `Yesod' at Utility/WebApp.hs:14:1-12
+ (and originally defined in `transformers-0.2.2.0:Control.Monad.IO.Class')
+ or `Control.Monad.IO.Class.liftIO',
+ imported from `Control.Monad.IO.Class' at Utility/WebApp.hs:18:1-29
+ make: *** [git-annex] Fehler 1
+
+
+
+"""]]
diff --git a/doc/forum/Problem_compiling_current_master/comment_3_b737b3945103c5e2aa798b4e65fbce06._comment b/doc/forum/Problem_compiling_current_master/comment_3_b737b3945103c5e2aa798b4e65fbce06._comment
new file mode 100644
index 000000000..12c4b1af0
--- /dev/null
+++ b/doc/forum/Problem_compiling_current_master/comment_3_b737b3945103c5e2aa798b4e65fbce06._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.16"
+ subject="comment 3"
+ date="2012-08-30T17:07:44Z"
+ content="""
+I've fixed this.. I think. I don't have this problem with the version of yesod I have here.
+"""]]
diff --git a/doc/forum/Problem_compiling_current_master/comment_4_28c1b335ae388d4e1f22b711ac1c001f._comment b/doc/forum/Problem_compiling_current_master/comment_4_28c1b335ae388d4e1f22b711ac1c001f._comment
new file mode 100644
index 000000000..d16e17c13
--- /dev/null
+++ b/doc/forum/Problem_compiling_current_master/comment_4_28c1b335ae388d4e1f22b711ac1c001f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmU_2tE75oyG0h2ZPN4lcroIKEMC8G-otE"
+ nickname="Michael"
+ subject="comment 4"
+ date="2012-08-31T08:04:18Z"
+ content="""
+Success! Now it compiles fine on Ubuntu 12.04 with make. Thank you.
+"""]]
diff --git a/doc/forum/Problems_syncing_with_box.com.mdwn b/doc/forum/Problems_syncing_with_box.com.mdwn
new file mode 100644
index 000000000..e536ccdb6
--- /dev/null
+++ b/doc/forum/Problems_syncing_with_box.com.mdwn
@@ -0,0 +1,26 @@
+I have a repository synchronized between two PCs and box.com . I chose encryption for box.com. Today on my work computer I changed files, on box.com I see that there are changed files today. When I got home, I still see files with yesterday's date.
+One thing to mention is that currently the work PC is not accessible.
+
+1. How do I debug this problem? I have logging set to debug via web console, saved, restarted daemon, but after restart the debug checkbox is unchecked.
+From logs it looks like that after failing to connect to work pc via ssh it gives up:
+
+ [2013-05-09 21:42:52 CEST] main: Syncing with box.com
+this is first and last line mentioning box today, I restarted the daemon several times around 22:14 :
+
+ [2013-05-09 22:11:40 CEST] TransferScanner: Syncing with [work pc repo]
+ Already up-to-date.
+
+ (scanning...) [2013-05-09 22:11:40 CEST] Watcher: Performing startup scan
+ Already up-to-date.
+
+ (started...) ssh: connect to host [work pc] port 22: No route to host
+ fatal: The remote end hung up unexpectedly
+
+
+2. where is the configuration for box.com stored? How can I check gpg key ID mentioned at http://git-annex.branchable.com/tips/using_box.com_as_a_special_remote/
+3. how do I manually trigger sync with box.com? git fetch box.com neither git annex sync box.com doesn't work.
+
+
+---
+Version: 4.20130501
+Build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP
diff --git a/doc/forum/Problems_syncing_with_box.com/comment_1_8db642849da4d42cd9a43142e2b7cb70._comment b/doc/forum/Problems_syncing_with_box.com/comment_1_8db642849da4d42cd9a43142e2b7cb70._comment
new file mode 100644
index 000000000..b60fc03e0
--- /dev/null
+++ b/doc/forum/Problems_syncing_with_box.com/comment_1_8db642849da4d42cd9a43142e2b7cb70._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-05-13T17:56:35Z"
+ content="""
+From what you've described, the box.com special remote is the only remote you have connecting your two computers.
+
+But special remotes are only used to transfer the contents of files. They do not have the content of the git repository.
+
+You need to set up a git remote that both computers can access. Or you can use the webapp to set up XMPP to sync between the computers directly. If you start the webapp, it will detect you're missing a git remote, and suggest setting up XMPP. [[/assistant/xmppnudge.png]]
+"""]]
diff --git a/doc/forum/Problems_syncing_with_box.com/comment_2_cd18f33647aebc04af5469e4ce1fbcd2._comment b/doc/forum/Problems_syncing_with_box.com/comment_2_cd18f33647aebc04af5469e4ce1fbcd2._comment
new file mode 100644
index 000000000..d156622df
--- /dev/null
+++ b/doc/forum/Problems_syncing_with_box.com/comment_2_cd18f33647aebc04af5469e4ce1fbcd2._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="tomas"
+ ip="188.167.111.235"
+ subject="Problems syncing with box.com"
+ date="2013-05-19T19:56:09Z"
+ content="""
+Thanks for the answer Joey.
+My setup is really 2 PCs that are usually not turned on at the same time (usually) and are unable to connect directly (usually). I've dropped box.com because there are bugs. When I sync a file, I see a broken link sometimes. That happens even in situation when the two PCs see each other. Other repos work as expected. So I assume this is a box.com issue. I tried to remove the box repo from both sides, but it is still in 'cleaning out' state even after few days and a lot of daemon restarts. I also have a queue to box. If I delete the transfers, they would appear later. Any way of sorting that out?
+I know that reporting bugs like this is not really efficient. What would be the best way to make it reproducible? E.g. using vagrant and two VMs?
+
+"""]]
diff --git a/doc/forum/Problems_using_submodules_with_git-annex__63__.mdwn b/doc/forum/Problems_using_submodules_with_git-annex__63__.mdwn
new file mode 100644
index 000000000..39ebe855c
--- /dev/null
+++ b/doc/forum/Problems_using_submodules_with_git-annex__63__.mdwn
@@ -0,0 +1 @@
+Are there any problems using submodules with git-annex? I have not tried it yet, I'm just asking.
diff --git a/doc/forum/Problems_using_submodules_with_git-annex__63__/comment_1_c7a927736d419d3c31c912001ff16ee4._comment b/doc/forum/Problems_using_submodules_with_git-annex__63__/comment_1_c7a927736d419d3c31c912001ff16ee4._comment
new file mode 100644
index 000000000..3c2f5addb
--- /dev/null
+++ b/doc/forum/Problems_using_submodules_with_git-annex__63__/comment_1_c7a927736d419d3c31c912001ff16ee4._comment
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ subject="comment 1"
+ date="2012-07-05T17:04:34Z"
+ content="""
+I haven't tried it either, but I think it should work ok, as long as you bear in mind that to git-annex, each submodule will be treated as a separate git repository.
+"""]]
diff --git a/doc/forum/Problems_with_large_numbers_of_files.mdwn b/doc/forum/Problems_with_large_numbers_of_files.mdwn
new file mode 100644
index 000000000..1dbddd3e2
--- /dev/null
+++ b/doc/forum/Problems_with_large_numbers_of_files.mdwn
@@ -0,0 +1,8 @@
+I'm trying to use git-annex to archive scientific data. I'm often dealing with large numbers of files, sometimes 10k or more. When I try to git-annex add these files I get this error:
+
+
+ Stack space overflow: current size 8388608 bytes.
+ Use `+RTS -Ksize' to increase it.
+
+
+This is with the latest version of git-annex and a current version of git on OS 10.6.7. After this error occurs, I am unable to un-annex the files and I'm forced to recover from a backup.
diff --git a/doc/forum/Problems_with_large_numbers_of_files/comment_1_08791cb78b982087c2a07316fe3ed46c._comment b/doc/forum/Problems_with_large_numbers_of_files/comment_1_08791cb78b982087c2a07316fe3ed46c._comment
new file mode 100644
index 000000000..94043a700
--- /dev/null
+++ b/doc/forum/Problems_with_large_numbers_of_files/comment_1_08791cb78b982087c2a07316fe3ed46c._comment
@@ -0,0 +1,22 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 1"
+ date="2011-04-05T07:27:46Z"
+ content="""
+Heh, cool, I was thinking throwing about 28million files at git-annex. Let me know how it goes, I suspect you have just run into a default limits OSX problem.
+
+You probably just need to up some system limits (you will need to read the error messages that first appear) then do something like
+
+<pre>
+# this is really for the run time, you can set these settings in /etc/sysctl.conf
+sudo sysctl -w kern.maxproc=2048
+sudo sysctl -w kern.maxprocperuid=1024
+
+# tell launchd about having higher limits
+sudo echo \"limit maxfiles 1024 unlimited\" >> /etc/launchd.conf
+sudo echo \"limit maxproc 1024 2048\" >> /etc/launchd.conf
+</pre>
+
+There are other system limits which you can check by doing a \"ulimit -a\", once you make the above changes, you will need to reboot to make the changes take affect. I am unsure if the above will help as it is an example of what I did on 10.6.6 a few months ago to fix some forking issues. From the error you got you will probably need to increase the stacksize to something bigger or even make it unlimited if you feel lucky, the default stacksize on OSX is 8192, try making it say 10times that size first and see what happens.
+"""]]
diff --git a/doc/forum/Problems_with_large_numbers_of_files/comment_2_0392a11219463e40c53bae73c8188b69._comment b/doc/forum/Problems_with_large_numbers_of_files/comment_2_0392a11219463e40c53bae73c8188b69._comment
new file mode 100644
index 000000000..8ea5531f4
--- /dev/null
+++ b/doc/forum/Problems_with_large_numbers_of_files/comment_2_0392a11219463e40c53bae73c8188b69._comment
@@ -0,0 +1,25 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 2"
+ date="2011-04-05T17:46:03Z"
+ content="""
+This message comes from ghc's runtime memory manager. Apparently your ghc defaults to limiting the stack to 80 mb.
+Mine seems to limit it slightly higher -- I have seen haskell programs successfully grow as large as 350 mb, although generally not intentionally. :)
+
+Here's how to adjust the limit at runtime, obviously you'd want a larger number:
+
+<pre>
+# git-annex +RTS -K100 -RTS find
+Stack space overflow: current size 100 bytes.
+Use `+RTS -Ksize -RTS' to increase it.
+</pre>
+
+I've tried to avoid git-annex using quantities of memory that scale with the number of files in the repo, and I think in general successfully -- I run it on 32 mb and 128 mb machines, FWIW. There are some tricky cases, and haskell makes it easy to accidentally write code that uses much more memory than would be expected.
+
+One well known case is `git annex unused`, which *has* to build a structure of every annexed file. I have been considering using a bloom filter or something to avoid that.
+
+Another possible case is when running a command like `git annex add`, and passing it a lot of files/directories. Some code tries to preserve the order of your input after passing it through `git ls-files` (which destroys ordering), and to do so it needs to buffer both the input and the result in ram.
+
+It's possible to build git-annex with memory profiling and generate some quite helpful profiling data. Edit the Makefile and add this to GHCFLAGS: `-prof -auto-all -caf-all -fforce-recomp` then when running git-annex, add the parameters: `+RTS -p -RTS` , and look for the git-annex.prof file.
+"""]]
diff --git a/doc/forum/Problems_with_large_numbers_of_files/comment_3_537e9884c1488a7a4bcf131ea63b71f7._comment b/doc/forum/Problems_with_large_numbers_of_files/comment_3_537e9884c1488a7a4bcf131ea63b71f7._comment
new file mode 100644
index 000000000..8e4101e37
--- /dev/null
+++ b/doc/forum/Problems_with_large_numbers_of_files/comment_3_537e9884c1488a7a4bcf131ea63b71f7._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 3"
+ date="2011-04-05T18:02:05Z"
+ content="""
+Oh, you'll need profiling builds of various haskell libraries to build with profiling support. If that's not easily accomplished, if you could show me the form of the command you're running, and also how git annex unannex fails, that would be helpful for investigating.
+"""]]
diff --git a/doc/forum/Problems_with_large_numbers_of_files/comment_4_7cb65d013e72bd2b7e90452079d42ac9._comment b/doc/forum/Problems_with_large_numbers_of_files/comment_4_7cb65d013e72bd2b7e90452079d42ac9._comment
new file mode 100644
index 000000000..bac9fd7ca
--- /dev/null
+++ b/doc/forum/Problems_with_large_numbers_of_files/comment_4_7cb65d013e72bd2b7e90452079d42ac9._comment
@@ -0,0 +1,29 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkhdKAhe3l_UyGt5SdfRBPYVwe-9f8P2dM"
+ nickname="Justin"
+ subject="comment 4"
+ date="2011-04-05T21:14:12Z"
+ content="""
+@joey
+
+OK, I'll try increasing the stack size and see if that helps.
+
+For reference, I was running:
+
+git annex add .
+
+on a directory containing about 100k files spread over many nested subdirectories. I actually have more than a dozen projects like this that I plan to keep in git annex, possibly in separate repositories if necessary. I could probably tar the data and then archive that, but I like the idea of being able to see the structure of my data even though the contents of the files are on a different machine.
+
+After the crash, running:
+
+git annex unannex
+
+does nothing and returns instantly. What exactly is 'git annex add' doing? I know that it's moving files into the key-value store and adding symlinks, but I don't know what else it does.
+
+--Justin
+
+
+
+If
+
+"""]]
diff --git a/doc/forum/Problems_with_large_numbers_of_files/comment_5_86a42ee3173a5d38f803e64b79496ab3._comment b/doc/forum/Problems_with_large_numbers_of_files/comment_5_86a42ee3173a5d38f803e64b79496ab3._comment
new file mode 100644
index 000000000..7dcccef2e
--- /dev/null
+++ b/doc/forum/Problems_with_large_numbers_of_files/comment_5_86a42ee3173a5d38f803e64b79496ab3._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 5"
+ date="2011-04-07T16:41:00Z"
+ content="""
+I think what is happening with \"git annex unannex\" is that \"git annex add\" crashes before it can \"git add\" the symlinks. unannex only looks at files that \"git ls-files\" shows, and so files that are not added to git are not seen. So, this can be recovered from by looking at git status and manually adding the symlinks to git, and then unannex.
+
+That also suggests that \"git annex add .\" has done something before crashing. That's consistent with you passing it < 2 parameters; it's not just running out of memory trying to expand and preserve order of its parameters (like it might if you ran \"git annex add experiment-1/ experiment-2/\")
+
+I'm pretty sure I know where the space leak is now. git-annex builds up a queue of git commands, so that it can run git a minimum number of times. Currently, this queue is only flushed at the end. I had been meaning to work on having it flush the queue periodically to avoid it growing without bounds, and I will prioritize doing that.
+
+(The only other thing that \"git annex add\" does is record location log information.)
+"""]]
diff --git a/doc/forum/Problems_with_large_numbers_of_files/comment_6_4551274288383c9cc27cbf85b122d307._comment b/doc/forum/Problems_with_large_numbers_of_files/comment_6_4551274288383c9cc27cbf85b122d307._comment
new file mode 100644
index 000000000..fff8f7cdd
--- /dev/null
+++ b/doc/forum/Problems_with_large_numbers_of_files/comment_6_4551274288383c9cc27cbf85b122d307._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 6"
+ date="2011-04-07T18:09:13Z"
+ content="""
+I've committed the queue flush improvements, so it will buffer up to 10240 git actions, and then flush the queue.
+
+There may be other memory leaks at scale (besides the two I mentioned earlier), but this seems promising. I'm well into running `git annex add` on a half million files and it's using 18 mb ram and has flushed the queue several times. This run
+will fail due to running out of inodes for the log files, not due to memory. :)
+"""]]
diff --git a/doc/forum/Problems_with_large_numbers_of_files/comment_7_d18cf944352f8303799c86f2c0354e8e._comment b/doc/forum/Problems_with_large_numbers_of_files/comment_7_d18cf944352f8303799c86f2c0354e8e._comment
new file mode 100644
index 000000000..7d2ad5eba
--- /dev/null
+++ b/doc/forum/Problems_with_large_numbers_of_files/comment_7_d18cf944352f8303799c86f2c0354e8e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 7"
+ date="2011-04-08T21:55:36Z"
+ content="""
+http://xfs.org/index.php/XFS_FAQ#Q:_Performance:_mkfs.xfs_-n_size.3D64k_option
+"""]]
diff --git a/doc/forum/Pruning_out_unwanted_Git_objects.mdwn b/doc/forum/Pruning_out_unwanted_Git_objects.mdwn
new file mode 100644
index 000000000..36397b267
--- /dev/null
+++ b/doc/forum/Pruning_out_unwanted_Git_objects.mdwn
@@ -0,0 +1,3 @@
+I have a backups repository with a few files in it, that at one point had some huge filesets erroneously added to it. As a result, even though there are only 23,334 annexed files, the number of non-dangling Git objects in the repository comes to 593,584.
+
+Normally I would use `git filter-branch` to clear out the deadwood in situations like this, since it is a completely private repository. What I'm wondering is, is any such thing possible with git-annex, or is the best option just to start over, copy all the files into the new repository, and then `git-add` them all?
diff --git a/doc/forum/Pruning_out_unwanted_Git_objects/comment_1_0cf7a12bfa2957260f4b2f79b0cadf2f._comment b/doc/forum/Pruning_out_unwanted_Git_objects/comment_1_0cf7a12bfa2957260f4b2f79b0cadf2f._comment
new file mode 100644
index 000000000..fbf538afa
--- /dev/null
+++ b/doc/forum/Pruning_out_unwanted_Git_objects/comment_1_0cf7a12bfa2957260f4b2f79b0cadf2f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/2grhJvAC049fJnvALDXek.6MRZMTlg--#eec89"
+ nickname="John"
+ subject="comment 1"
+ date="2013-08-29T07:23:13Z"
+ content="""
+Maybe one way to solve this that would be general is to have some kind of `prune-history` command, which keeps only the HEAD and drops everything else. Because there are some repositories that I want to manage with `git-annex` for many reasons, but I don't care about keep history around at all.
+"""]]
diff --git a/doc/forum/Pruning_out_unwanted_Git_objects/comment_2_7472943c02cfe2808b0d566e06caa1a5._comment b/doc/forum/Pruning_out_unwanted_Git_objects/comment_2_7472943c02cfe2808b0d566e06caa1a5._comment
new file mode 100644
index 000000000..0c2646351
--- /dev/null
+++ b/doc/forum/Pruning_out_unwanted_Git_objects/comment_2_7472943c02cfe2808b0d566e06caa1a5._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/2grhJvAC049fJnvALDXek.6MRZMTlg--#eec89"
+ nickname="John"
+ subject="comment 2"
+ date="2013-08-30T06:18:42Z"
+ content="""
+This was answered quite thoroughly in:http://git-annex.branchable.com/forum/safely_dropping_git-annex_history/
+"""]]
diff --git a/doc/forum/Pruning_out_unwanted_Git_objects/comment_3_6a1e7a83d94394454fc085f6d2728cd7._comment b/doc/forum/Pruning_out_unwanted_Git_objects/comment_3_6a1e7a83d94394454fc085f6d2728cd7._comment
new file mode 100644
index 000000000..90951961f
--- /dev/null
+++ b/doc/forum/Pruning_out_unwanted_Git_objects/comment_3_6a1e7a83d94394454fc085f6d2728cd7._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4830:1600:187::2"
+ subject="comment 3"
+ date="2013-09-04T06:36:15Z"
+ content="""
+`git annex forget` automates this now. Needs a version of git-annex supporting it installed on *all* the computers you use the repo on.
+"""]]
diff --git a/doc/forum/Purge_a_remote.txt b/doc/forum/Purge_a_remote.txt
new file mode 100644
index 000000000..f1b04ead2
--- /dev/null
+++ b/doc/forum/Purge_a_remote.txt
@@ -0,0 +1,2 @@
+How could I delete and purge a remote? I want to remove all traces of it
+but I can't find out how to achieve this.
diff --git a/doc/forum/Purge_a_remote/comment_1_78b3b77f457c65d31fd8a5abf714905d._comment b/doc/forum/Purge_a_remote/comment_1_78b3b77f457c65d31fd8a5abf714905d._comment
new file mode 100644
index 000000000..a7eff3a99
--- /dev/null
+++ b/doc/forum/Purge_a_remote/comment_1_78b3b77f457c65d31fd8a5abf714905d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 1"
+ date="2013-11-05T16:17:22Z"
+ content="""
+In the git-annex webapp, each repository has a settings menu with \"delete repository\".
+"""]]
diff --git a/doc/forum/Purge_a_remote/comment_2_dc65719157dee63b3979563ed57ee0ce._comment b/doc/forum/Purge_a_remote/comment_2_dc65719157dee63b3979563ed57ee0ce._comment
new file mode 100644
index 000000000..ddcab44dd
--- /dev/null
+++ b/doc/forum/Purge_a_remote/comment_2_dc65719157dee63b3979563ed57ee0ce._comment
@@ -0,0 +1,10 @@
+[[!comment format=txt
+ username="https://www.google.com/accounts/o8/id?id=AItOawkzwmw_zyMpZC9_J7ey--woeYPoZkAOgGw"
+ nickname="dxtrish"
+ subject="comment 2"
+ date="2013-11-05T17:46:02Z"
+ content="""
+When I use that Delete button it seems to still have records of it
+because when I delete the repo on the other end and create a new bare
+one it complains about some UUID mismatch.
+"""]]
diff --git a/doc/forum/Purge_a_remote/comment_3_63e0280273b816fa4b837724e102f813._comment b/doc/forum/Purge_a_remote/comment_3_63e0280273b816fa4b837724e102f813._comment
new file mode 100644
index 000000000..621bda508
--- /dev/null
+++ b/doc/forum/Purge_a_remote/comment_3_63e0280273b816fa4b837724e102f813._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 3"
+ date="2013-11-05T18:03:26Z"
+ content="""
+Hmm well, it's true that deleting a repository does not clean out any git remotes that other repositories might have configured using it, and the uuid of the old remote is cached in there. This is only a problem if you put back another repository in the same location as the old one. `git remote remove` should clean that up for you.
+"""]]
diff --git a/doc/forum/Purge_a_remote/comment_4_7fad1c4798ca03a4095ac3241c279f6d._comment b/doc/forum/Purge_a_remote/comment_4_7fad1c4798ca03a4095ac3241c279f6d._comment
new file mode 100644
index 000000000..afb4dc92e
--- /dev/null
+++ b/doc/forum/Purge_a_remote/comment_4_7fad1c4798ca03a4095ac3241c279f6d._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkzwmw_zyMpZC9_J7ey--woeYPoZkAOgGw"
+ nickname="dxtrish"
+ subject="comment 4"
+ date="2013-11-06T14:24:21Z"
+ content="""
+That is exactly what I have wanted to do a couple of times now and 'git remote remove' does not seem to remove it all either.
+When I try to create a new repository in the same place it still complains about that darn UUID :)
+
+What is working is to manually add the new UUID to .git/config
+"""]]
diff --git a/doc/forum/Push__47__Pull_with_the_Assistant.mdwn b/doc/forum/Push__47__Pull_with_the_Assistant.mdwn
new file mode 100644
index 000000000..315ad38d8
--- /dev/null
+++ b/doc/forum/Push__47__Pull_with_the_Assistant.mdwn
@@ -0,0 +1 @@
+If I use git-annex with a centralized bare git repository as [described here](http://git-annex.branchable.com/tips/centralized_git_repository_tutorial/), will the Assistant automatically `git push` and `git pull` the master and git-annex branches? Or does it basically just do a `git annex sync`?
diff --git a/doc/forum/Push__47__Pull_with_the_Assistant/comment_1_f7b63d379c2d21794adf8658f546f8a7._comment b/doc/forum/Push__47__Pull_with_the_Assistant/comment_1_f7b63d379c2d21794adf8658f546f8a7._comment
new file mode 100644
index 000000000..0477218bc
--- /dev/null
+++ b/doc/forum/Push__47__Pull_with_the_Assistant/comment_1_f7b63d379c2d21794adf8658f546f8a7._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.252.11.120"
+ subject="comment 1"
+ date="2012-11-17T20:25:03Z"
+ content="""
+The assistant will push, pull, and merge the master and git-annex branches (which is exactly what git annex sync does).
+
+Additionally, the assistant will transfer file contents to the bare repository, either to make it have a copy of everything, or as needed to transfer to other repositories that also use that bare repository. This behavior is configurable using the webapp.
+"""]]
diff --git a/doc/forum/Push__47__Pull_with_the_Assistant/comment_2_aec8cc20576e7ffd5a8be4348d1a0073._comment b/doc/forum/Push__47__Pull_with_the_Assistant/comment_2_aec8cc20576e7ffd5a8be4348d1a0073._comment
new file mode 100644
index 000000000..20be4c6ce
--- /dev/null
+++ b/doc/forum/Push__47__Pull_with_the_Assistant/comment_2_aec8cc20576e7ffd5a8be4348d1a0073._comment
@@ -0,0 +1,21 @@
+[[!comment format=mdwn
+ username="annexuser"
+ ip="85.159.236.214"
+ subject="comment 2"
+ date="2012-11-17T20:44:53Z"
+ content="""
+When I make a change in the repository and run a plain old `git annex sync`, it pushes out to any other available annex, but not to my bare hub. If I run `git annex sync` a second time it tells me that I'm ahead of the hub:
+
+ commit
+ # On branch master
+ # Your branch is ahead of 'hub/master' by 1 commit.
+ #
+ nothing to commit, working directory clean
+ ok
+
+In order to push the changes out to the hub I have to do `git push --all`.
+
+The same thing with pulling. If I make a change on the annex, push it to the hub, and then go to a second annex that knows about the hub but not the first annex, a `git annex sync` does not pull the changes in from the hub. I have to do `git pull` to get them.
+
+Do I have something setup incorrectly?
+"""]]
diff --git a/doc/forum/Pushing_git_repo_to_AWS_S3_from_behind_proxy.mdwn b/doc/forum/Pushing_git_repo_to_AWS_S3_from_behind_proxy.mdwn
new file mode 100644
index 000000000..03676502b
--- /dev/null
+++ b/doc/forum/Pushing_git_repo_to_AWS_S3_from_behind_proxy.mdwn
@@ -0,0 +1,9 @@
+I want to setup my remote git repo on S3
+Referred to
+http://git-annex.branchable.com/tips/using_Amazon_S3/
+http://git-annex.branchable.com/special_remotes/S3/
+
+I need support for AWS.config param proxy_uri
+http://docs.amazonwebservices.com/AWSRubySDK/latest/AWS.html
+
+Can some one help?
diff --git a/doc/forum/Reappearing_repos_in_webapp_and_vicfg.mdwn b/doc/forum/Reappearing_repos_in_webapp_and_vicfg.mdwn
new file mode 100644
index 000000000..41a64630d
--- /dev/null
+++ b/doc/forum/Reappearing_repos_in_webapp_and_vicfg.mdwn
@@ -0,0 +1,43 @@
+Hi,
+
+Whenever I do a git annex vicfg (as pasted below) the long gone repo 40da403e-6f74-4705-aae0-433aa656b55e keeps automatically being added back into the configuration. Worse in the webapp this manifests itself as a repository list item that's empty of text (and when buttons are clicked there's a complaint about missing UUIDs).
+
+In addition to removing the lines via git-annex vicfg, I've switched my repository into indirect mode, manually checked out the the git-annex branch and deleted the offending key from the preferred content and group files (it oddly didn't appear in the uuid file). However they keep coming back :-(
+
+Everything seems to be okay bar this rogue entry which in the web-app irrationally bothers me.
+
+I'm running the very latest git-annex release.
+
+Any thoughts?
+
+Cheers,
+
+Matt.
+
+
+ # git-annex configuration
+ #
+ # Changes saved to this file will be recorded in the git-annex branch.
+ #
+ # Lines in this file have the format:
+ # setting uuid = value
+
+ # Repository trust configuration
+ # (Valid trust levels: trusted semitrusted untrusted dead)
+ # (for mattford63 (matt@descartes.rss.mhs.man.ac.uk:~/current))
+ trust 88733342-45ef-420f-8f1b-9a5ed8d8e070 = semitrusted
+
+ # Repository groups
+ # (Standard groups: client transfer backup incrementalbackup smallarchive archive source manual public unwanted)
+ # (Separate group names with spaces)
+ # (for )
+ group 40da403e-6f74-4705-aae0-433aa656b55e = client
+ # (for mattford63 (matt@descartes.rss.mhs.man.ac.uk:~/current))
+ group 88733342-45ef-420f-8f1b-9a5ed8d8e070 = client
+
+ # Repository preferred contents
+ # (for )
+ content 40da403e-6f74-4705-aae0-433aa656b55e = standard
+ # (for mattford63 (matt@descartes.rss.mhs.man.ac.uk:~/current))
+ content 88733342-45ef-420f-8f1b-9a5ed8d8e070 = standard
+
diff --git a/doc/forum/Reappearing_repos_in_webapp_and_vicfg/comment_1_bd977e864ae89816fa7f4ff69879b15f._comment b/doc/forum/Reappearing_repos_in_webapp_and_vicfg/comment_1_bd977e864ae89816fa7f4ff69879b15f._comment
new file mode 100644
index 000000000..983dd8478
--- /dev/null
+++ b/doc/forum/Reappearing_repos_in_webapp_and_vicfg/comment_1_bd977e864ae89816fa7f4ff69879b15f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.193"
+ subject="comment 1"
+ date="2013-07-02T16:56:42Z"
+ content="""
+Run: `git annex dead 40da403e-6f74-4705-aae0-433aa656b55e`
+"""]]
diff --git a/doc/forum/Reappearing_repos_in_webapp_and_vicfg/comment_2_05749f9e75689d0111339b7126c12300._comment b/doc/forum/Reappearing_repos_in_webapp_and_vicfg/comment_2_05749f9e75689d0111339b7126c12300._comment
new file mode 100644
index 000000000..bd56c6670
--- /dev/null
+++ b/doc/forum/Reappearing_repos_in_webapp_and_vicfg/comment_2_05749f9e75689d0111339b7126c12300._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnXybLxkPMYpP3yw4b_I6IdC3cKTD-xEdU"
+ nickname="Matt"
+ subject="comment 2"
+ date="2013-07-02T19:48:19Z"
+ content="""
+Hi,
+
+I should have mentioned I can't do this either:
+
+ ~/current $ git annex dead 40da403e-6f74-4705-aae0-433aa656b55e
+ dead 40da403e-6f74-4705-aae0-433aa656b55e git-annex: there is no available git remote named \"40da403e-6f74-4705-aae0-433aa656b55e\"
+
+I can't quite remember how I removed the remote - it was a whilst back, I think maybe I just edited it out of the git config file....
+"""]]
diff --git a/doc/forum/Reappearing_repos_in_webapp_and_vicfg/comment_3_b1531994eea0fbbf4cb097e604378a53._comment b/doc/forum/Reappearing_repos_in_webapp_and_vicfg/comment_3_b1531994eea0fbbf4cb097e604378a53._comment
new file mode 100644
index 000000000..a079e3b12
--- /dev/null
+++ b/doc/forum/Reappearing_repos_in_webapp_and_vicfg/comment_3_b1531994eea0fbbf4cb097e604378a53._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.193"
+ subject="comment 3"
+ date="2013-07-02T19:58:30Z"
+ content="""
+It seems that the uuid is present in the group.log and preferred-content.log files in the git-annex branch, but not in the uuid.log file. I missed that in your description before. That's weird, don't know how that could happen.
+
+However, when I manually configure things this way, I do not see the repository in the webapp. Which makes sense; uuid.log is the canonical list of repositories.
+
+I guess if I were you I'd manually edit the uuid into uuid.log and then mark it dead.
+"""]]
diff --git a/doc/forum/Reappearing_repos_in_webapp_and_vicfg/comment_4_f1eba3e8aa4116e3c20747ec1d6e24e5._comment b/doc/forum/Reappearing_repos_in_webapp_and_vicfg/comment_4_f1eba3e8aa4116e3c20747ec1d6e24e5._comment
new file mode 100644
index 000000000..6c5e8835e
--- /dev/null
+++ b/doc/forum/Reappearing_repos_in_webapp_and_vicfg/comment_4_f1eba3e8aa4116e3c20747ec1d6e24e5._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnXybLxkPMYpP3yw4b_I6IdC3cKTD-xEdU"
+ nickname="Matt"
+ subject="comment 4"
+ date="2013-07-02T20:45:29Z"
+ content="""
+I tried as you suggested. It worked as far in so far that I was able to mark the repository dead. However, I still see an empty line in the web app so perhaps this odd repo isn't the cause (but I'm deeply suspicious of it). Looking at the HTML source the line in the web-app does not have any UUID at all (see the screen shot [here](http://dancingfrog.hopto.org/~matt/git-annex.png)).
+
+What causes the code to add back a previously deleted repository (I vaguely remember something about this being due to the merge algorithm...and why one can only mark repos as deleted)? Why would it only add back to the group and trust logs and not the UUID? The code that generates the web-app HTML must use something else or things in addition to the UUID log?
+
+The logs don't really say much - how can I help debug this further?
+"""]]
diff --git a/doc/forum/Recommended_number_of_repositories.mdwn b/doc/forum/Recommended_number_of_repositories.mdwn
new file mode 100644
index 000000000..9e9f2838d
--- /dev/null
+++ b/doc/forum/Recommended_number_of_repositories.mdwn
@@ -0,0 +1,4 @@
+With git it is easy to create one repository per project, and it almost always makes sense to do so. When using git-annex, what is the recommended setup?
+
+Should one have a single annex containing all files, or is it recommended to create different repositories for things like 'photos', 'music', 'isos' ?
+
diff --git a/doc/forum/Recommended_number_of_repositories/comment_1_3ef256230756be8a9679b107cdbfd018._comment b/doc/forum/Recommended_number_of_repositories/comment_1_3ef256230756be8a9679b107cdbfd018._comment
new file mode 100644
index 000000000..46ce0e8d5
--- /dev/null
+++ b/doc/forum/Recommended_number_of_repositories/comment_1_3ef256230756be8a9679b107cdbfd018._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="depends ..."
+ date="2011-11-04T19:59:24Z"
+ content="""
+It makes sense to have separate repositories when you have well-defined uses for them.
+
+I have a separate repository just for music and podcasts, which I can put various places where I have no need of the overhead of a tree of other files.
+
+If you're using it for whatever arbitrary large files you accumulate, I find it's useful to have them in one repository. This way I can rearrange things as makes sense. It might make sense to have \"photos\" and \"isos\" as categories today, but next year you might prefer to move those under 2011/{photos,isos}. It would certainly make sense to have different repositories for home, work, etc.
+
+How to split repositories up for a home directory is a general problem that the [vcs-home](http://vcs-home.branchable.com)
+project has surely considered at one time or another.
+"""]]
diff --git a/doc/forum/Relocating_annex_directory.mdwn b/doc/forum/Relocating_annex_directory.mdwn
new file mode 100644
index 000000000..f2e271333
--- /dev/null
+++ b/doc/forum/Relocating_annex_directory.mdwn
@@ -0,0 +1 @@
+I have around 70 GBs of data spread around 4 repositories on a Linux (Ubuntu) box. My problem is I need to reformat the drive they are on. I would like to move them to an external usb drive temporarily during reinstall then move them back to their original location. When I started with annex I did try to mv annexFolder/ toNewLoc/ which failed leaving behind a corrupt repo. What is a safe way to move an annex folder? My primary connection is a 3G modem so I am trying to avoid re downloading everything. Another thing I am trying to avoid is cloning the repos to the external drive, reinstall, clone it back to the internal drive and mark original and external repos as dead, but AFAIK those dead repos will show up in the output of whereis, so everytime I reformat I gonna have two extra dead repos.
diff --git a/doc/forum/Relocating_annex_directory/comment_1_13ff5438baa1db110beb6aab3a783def._comment b/doc/forum/Relocating_annex_directory/comment_1_13ff5438baa1db110beb6aab3a783def._comment
new file mode 100644
index 000000000..5136941c5
--- /dev/null
+++ b/doc/forum/Relocating_annex_directory/comment_1_13ff5438baa1db110beb6aab3a783def._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="comment 1"
+ date="2013-08-16T03:42:00Z"
+ content="""
+moving the annex should work fine, provided:
+
+* You are moving it to a proper unix filesystem - NOT fat32
+* The assistant is shutdown. If it is running, bad things will happen.
+"""]]
diff --git a/doc/forum/Relocating_annex_directory/comment_2_6d88ff03fcf00ae872442e8a86c968ed._comment b/doc/forum/Relocating_annex_directory/comment_2_6d88ff03fcf00ae872442e8a86c968ed._comment
new file mode 100644
index 000000000..e7b361675
--- /dev/null
+++ b/doc/forum/Relocating_annex_directory/comment_2_6d88ff03fcf00ae872442e8a86c968ed._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 2"
+ date="2013-08-24T18:56:11Z"
+ content="""
+`git annex whereis` does not show dead repositories.
+
+Anyway Justin is of course right: Provided the assistant is not running in a repository, the repository is just a collection of files in a directory, and can be moved around, tarred up, untarred, etc just like any other repository. If the assistant is running it may become unhappy if its repository vanishes out from underneath it.
+"""]]
diff --git a/doc/forum/Removing_files_not_found_by_git_annex_unused.mdwn b/doc/forum/Removing_files_not_found_by_git_annex_unused.mdwn
new file mode 100644
index 000000000..ce0aedc51
--- /dev/null
+++ b/doc/forum/Removing_files_not_found_by_git_annex_unused.mdwn
@@ -0,0 +1,29 @@
+Hi,
+
+I've removed some large files with git remove, but seem to be unable to remove the corresponding annex content.
+
+Example:
+
+kheymann@corax:~/annex$ find -name "*s24576--10daa3d9007edad720dc057e4272a9c6cda930bef34a83e3bc1d93f1c55b9cac"
+
+./.git/annex/objects/jF/j7/SHA256-s24576--10daa3d9007edad720dc057e4272a9c6cda930bef34a83e3bc1d93f1c55b9cac
+
+./.git/annex/objects/jF/j7/SHA256-s24576--10daa3d9007edad720dc057e4272a9c6cda930bef34a83e3bc1d93f1c55b9cac/SHA256-s24576--10daa3d9007edad720dc057e4272a9c6cda930bef34a83e3bc1d93f1c55b9cac
+
+kheymann@corax:~/annex$ git annex dropkey -vvv --backend SHA256 s24576--10daa3d9007edad720dc057e4272a9c6cda930bef34a83e3bc1d93f1c55b9cac
+
+No output but the files remain in the annex. Git annex fsck and git annex unused run without listing files to be removes. What can I do apart from deleting the files manually from the annex?
+
+Some info:
+
+ kheymann@corax:~/annex$ git annex version
+ git-annex version: 3.20121017
+ local repository version: 3
+ default repository version: 3
+ supported repository versions: 3
+ upgrade supported from repository versions: 0 1 2
+
+Any hints?
+
+Best,
+Karsten
diff --git a/doc/forum/Removing_files_not_found_by_git_annex_unused/comment_1_420c6230e68de0a0ac7d7da91ac60801._comment b/doc/forum/Removing_files_not_found_by_git_annex_unused/comment_1_420c6230e68de0a0ac7d7da91ac60801._comment
new file mode 100644
index 000000000..f932f779c
--- /dev/null
+++ b/doc/forum/Removing_files_not_found_by_git_annex_unused/comment_1_420c6230e68de0a0ac7d7da91ac60801._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn7gQ1zZDdWhXy9H51W2krZYShNmKL3qfM"
+ nickname="Karsten"
+ subject="comment 1"
+ date="2012-11-09T19:37:24Z"
+ content="""
+Please ignore my previous post, by following the instructions in the comment in http://git-annex.branchable.com/walkthrough/unused_data/ I was able to get rid of the data.
+"""]]
diff --git a/doc/forum/Repo_accessible_from___34__dumb__34___client_without_git-annex.mdwn b/doc/forum/Repo_accessible_from___34__dumb__34___client_without_git-annex.mdwn
new file mode 100644
index 000000000..bcf2a87a3
--- /dev/null
+++ b/doc/forum/Repo_accessible_from___34__dumb__34___client_without_git-annex.mdwn
@@ -0,0 +1,11 @@
+Hi,
+
+I'm trying to figure out if it's possible to have a remote that allows access from _clients without git-annex_. That is a remote type that presents itself as a client repo. I'm probably missing something obvious.
+
+Ideally I'd like to use my Nokia N900 phone as a ssh remote from which I can open files on any computer when the device is connected via usb in mass storage mode. This would allow me to access my files when I'm using a computer at work or at a friends house without installing git-annex. The phone has an ext3 partition so links are possible. Naturally I'd have to ensure the files I want are on the device before I leave the house.
+
+I'd also like to be able to scp files from my ssh remote when on git-annex less devices. Unfortunately the ssh/rsync repo presents no links or normal filenames.
+
+Git annex, and the assistant is working really smoothly between my local computers and my server on the internet. Setting things up with the webapp is super simple. Great work!
+
+
diff --git a/doc/forum/Repo_accessible_from___34__dumb__34___client_without_git-annex/comment_1_077c492fd37d335f74a5c886ff0d524f._comment b/doc/forum/Repo_accessible_from___34__dumb__34___client_without_git-annex/comment_1_077c492fd37d335f74a5c886ff0d524f._comment
new file mode 100644
index 000000000..4e724ff55
--- /dev/null
+++ b/doc/forum/Repo_accessible_from___34__dumb__34___client_without_git-annex/comment_1_077c492fd37d335f74a5c886ff0d524f._comment
@@ -0,0 +1,32 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="99.54.57.201"
+ subject="comment 1"
+ date="2013-01-20T20:20:06Z"
+ content="""
+This is off the top of my head, so I may be wrong on details:
+
+An ssh remote, or a USB remote, when you create it with the assistant, is a bare repo. The files in it are not visible or accessible except through a clone of it (such as your client repo).
+
+You *could* make an SSH remote or USB remote as a *non-bare repo*, in which case the files within it would be visible and accessible just like on a client repo. You could set that up using the command line; the assistant doesn't do it, but once you got it set up on the command line the assistant would use it just like normal.
+
+There is a catch though. Though potentially available, the files in that repo don't actually show up until you run \"git annex sync\" in that repo. Because git annex does not update the checked out branch of a remote. So you'd have to cd into that repo manually and run \"git annex sync\" to make the latest-and-greatest files available.
+
+Here's how I'd do this...
+
+If the git annex assistant is running, turn it off.
+
+follow the instructions here: http://git-annex.branchable.com/walkthrough/ under \"adding a remote\" on your usb drive. You now have a non-bare remote.
+
+Fire up the assistant and you'll see that that is now one of your remotes. Configure it to \"backup\" or whatever you want. Let the assistant fill it up with content.
+
+When you want to take it someplace, get on the command line and \"cd /wherever/my/usb/drive/is/annex\" and then do: \"git annex sync\" -- that will update the links to the content so you can actually see it.
+
+You now have all your content available on your USB drive.
+
+You can do a similar process to manually create a non-bare SSH remote, and you can ssh in and run \"git annex sync\" to update its links and make the content available, which you can then retrieve va scp or sftp, or for that matter, you could configure a web server or WebDAV to serve it up if you like.
+
+The only complication is running git-annex sync to update your links.
+
+Again, this is all off the top of my head, I haven't looked up or tested anything here so I welcome correction. But I think what you want to do can be pretty straightforward if you're willing to go behind Assistant's back to do the setup work, and run \"git annex sync\" when you need to.
+"""]]
diff --git a/doc/forum/Repo_accessible_from___34__dumb__34___client_without_git-annex/comment_2_00e6576e3e60d2650461eeb0f918e6e5._comment b/doc/forum/Repo_accessible_from___34__dumb__34___client_without_git-annex/comment_2_00e6576e3e60d2650461eeb0f918e6e5._comment
new file mode 100644
index 000000000..64f111921
--- /dev/null
+++ b/doc/forum/Repo_accessible_from___34__dumb__34___client_without_git-annex/comment_2_00e6576e3e60d2650461eeb0f918e6e5._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn7gQ1zZDdWhXy9H51W2krZYShNmKL3qfM"
+ nickname="Karsten"
+ subject="comment 2"
+ date="2013-01-21T07:02:17Z"
+ content="""
+An alternative to running git annex sync in the non-bare remote is running an assistant there.
+"""]]
diff --git a/doc/forum/Repo_accessible_from___34__dumb__34___client_without_git-annex/comment_3_c36a9562c53ac683b62fc4471405aa2a._comment b/doc/forum/Repo_accessible_from___34__dumb__34___client_without_git-annex/comment_3_c36a9562c53ac683b62fc4471405aa2a._comment
new file mode 100644
index 000000000..db7dec37f
--- /dev/null
+++ b/doc/forum/Repo_accessible_from___34__dumb__34___client_without_git-annex/comment_3_c36a9562c53ac683b62fc4471405aa2a._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawk3HGoDpnOPob5jOjvIootmkve1-nCpRiI"
+ nickname="Kalle"
+ subject="Thanks for the help"
+ date="2013-01-21T20:40:39Z"
+ content="""
+I take it all the above requires mounting an sshfs filsystem of the remote client to run the git-annex or the assistant \"locally\" on the desktop or laptop. Or am I missing something.
+
+For the usb usecase a normal mount would suffice of course.
+
+The lack of automation means running a rsync script from (or to) the phone is easier. Not as clever though :( and means running a separate \"system\" for distributing files to the phone.
+
+Thanks again!
+
+"""]]
diff --git a/doc/forum/Restricting_git-annex-shell_to_a_specific_repository.mdwn b/doc/forum/Restricting_git-annex-shell_to_a_specific_repository.mdwn
new file mode 100644
index 000000000..bed019e41
--- /dev/null
+++ b/doc/forum/Restricting_git-annex-shell_to_a_specific_repository.mdwn
@@ -0,0 +1,25 @@
+Is there a way to restrict git-annex-shell to a specific directory?
+Currently, if git-annex is paired to a remote repository, it adds this to the authorized_keys:
+
+
+ $ cat ~/.ssh/authorized_keys
+ command="~/.ssh/git-annex-shell",no-agent-forwarding,no-port-forwarding,no-X11-forwarding ssh-rsa AAAAB3...
+
+ $ cat ~/.ssh/git-annex-shell
+ #!/bin/sh
+ set -e
+ exec git-annex-shell -c "$SSH_ORIGINAL_COMMAND"
+
+That gives whoever has the pubkey the right to access all repositories of one user.
+It would be nice to have a manual way to limit the access to a specific repository like
+
+
+ $ cat ~/.ssh/git-annex-shell
+ #!/bin/sh
+ set -e
+ export GIT_ANNEX_SHELL_REPO=~/annex
+ exec git-annex-shell -c "$SSH_ORIGINAL_COMMAND"
+
+
+Or maybe some chroot hackery is the way to go?
+
diff --git a/doc/forum/Restricting_git-annex-shell_to_a_specific_repository/comment_1_66544520bff71181e4a03ca583b0b458._comment b/doc/forum/Restricting_git-annex-shell_to_a_specific_repository/comment_1_66544520bff71181e4a03ca583b0b458._comment
new file mode 100644
index 000000000..141f96494
--- /dev/null
+++ b/doc/forum/Restricting_git-annex-shell_to_a_specific_repository/comment_1_66544520bff71181e4a03ca583b0b458._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.194"
+ subject="comment 1"
+ date="2012-11-05T16:40:39Z"
+ content="""
+I've added a `GIT_ANNEX_SHELL_DIRECTORY` environment variable, that, if set, prevents git-annex-shell from operating on any other directory.
+
+I've made the assistant include that setting in `authorized_keys` that it sets up. For example:
+
+ command=\"GIT_ANNEX_SHELL_DIRECTORY=/home/me/annex ~/.ssh/git-annex-shell\" ...
+"""]]
diff --git a/doc/forum/Restricting_git-annex-shell_to_a_specific_repository/comment_2_2a210255e8535712c71fa183e56ab600._comment b/doc/forum/Restricting_git-annex-shell_to_a_specific_repository/comment_2_2a210255e8535712c71fa183e56ab600._comment
new file mode 100644
index 000000000..42b6c1758
--- /dev/null
+++ b/doc/forum/Restricting_git-annex-shell_to_a_specific_repository/comment_2_2a210255e8535712c71fa183e56ab600._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://olg.myid.net/"
+ ip="93.218.131.119"
+ subject="comment 2"
+ date="2012-11-05T23:34:20Z"
+ content="""
+Wow, thank you for implementing this so quickly!
+
+
+Just one question: As far as I understood git-annex-shell relays all unknown commands to git-shell. In this case are there the same restrictions active, too?
+
+Thanks again...
+"""]]
diff --git a/doc/forum/Restricting_git-annex-shell_to_a_specific_repository/comment_3_52cd4bd9694b2100b0e0dd2eafa9e828._comment b/doc/forum/Restricting_git-annex-shell_to_a_specific_repository/comment_3_52cd4bd9694b2100b0e0dd2eafa9e828._comment
new file mode 100644
index 000000000..e198f8e09
--- /dev/null
+++ b/doc/forum/Restricting_git-annex-shell_to_a_specific_repository/comment_3_52cd4bd9694b2100b0e0dd2eafa9e828._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.27"
+ subject="comment 3"
+ date="2012-11-05T23:42:10Z"
+ content="""
+All commands usually run by `git-shell` have the repository directory as their last parameter, and git-annex-shell depends on that being the case and checks them. It's possible to add some commands to git-shell by putting them in a special directory, and if those commands don't take the directory last, they wouldn't work.
+"""]]
diff --git a/doc/forum/Retrieve_previous_version_in_direct_mode.mdwn b/doc/forum/Retrieve_previous_version_in_direct_mode.mdwn
new file mode 100644
index 000000000..c74b55b36
--- /dev/null
+++ b/doc/forum/Retrieve_previous_version_in_direct_mode.mdwn
@@ -0,0 +1,5 @@
+I use the assistant with a local directory in direct mode. I have read in different places that direct mode does not ensure that past versions of files are preserved.
+
+What precisely happens to past versions? Under which conditions are past versions kept?
+
+How would I go about retrieving the past version of a file in direct mode?
diff --git a/doc/forum/Retrieve_previous_version_in_direct_mode/comment_1_ca3a999ed64c42b8df810115de205d2f._comment b/doc/forum/Retrieve_previous_version_in_direct_mode/comment_1_ca3a999ed64c42b8df810115de205d2f._comment
new file mode 100644
index 000000000..dce26832b
--- /dev/null
+++ b/doc/forum/Retrieve_previous_version_in_direct_mode/comment_1_ca3a999ed64c42b8df810115de205d2f._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="64.134.31.139"
+ subject="comment 1"
+ date="2013-10-21T22:16:16Z"
+ content="""
+If you change a direct mode file and that file has not yet been transferred to some other repository, you've changed the only copy of the file, and so you cannot get back the old version.
+
+Other than that, git-annex always preserves old versions of direct mode files, the same as it preserves old versions of indirect mode files.
+
+To get back an old version of a file, use `git annex indirect` to get out of direct mode, use regular git commands to check out the version of the repository that has the file you need, and use `git annex get` to retrieve the file if it's not available in the local repository.
+"""]]
diff --git a/doc/forum/Retrieve_previous_version_in_direct_mode/comment_2_1292b34ff6d9976b2bd08748e1ba4e7a._comment b/doc/forum/Retrieve_previous_version_in_direct_mode/comment_2_1292b34ff6d9976b2bd08748e1ba4e7a._comment
new file mode 100644
index 000000000..47ab2b742
--- /dev/null
+++ b/doc/forum/Retrieve_previous_version_in_direct_mode/comment_2_1292b34ff6d9976b2bd08748e1ba4e7a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmNu4V5fvpLlBhaCUfXXOB0MI5NXwh8SkU"
+ nickname="Adam"
+ subject="Disk space?"
+ date="2013-11-02T01:33:10Z"
+ content="""
+Sorry, I'm confused: does using regular client repositories in direct mode still store old versions of files? If so, for how long? I don't have unlimited disk space, and if it stored in git every copy of every file forever, especially large ones, I'd run out of space...and then what?
+"""]]
diff --git a/doc/forum/Retrieve_previous_version_in_direct_mode/comment_3_699e816c0397f6db924feeab906f1151._comment b/doc/forum/Retrieve_previous_version_in_direct_mode/comment_3_699e816c0397f6db924feeab906f1151._comment
new file mode 100644
index 000000000..77fa9b0e7
--- /dev/null
+++ b/doc/forum/Retrieve_previous_version_in_direct_mode/comment_3_699e816c0397f6db924feeab906f1151._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 3"
+ date="2013-11-02T17:36:23Z"
+ content="""
+You can use `git annex unused` and `git annex dropunused` to remove old versions of files.
+"""]]
diff --git a/doc/forum/Retrieve_previous_version_in_direct_mode/comment_4_d900388753de5870b7b9c0e8b8c06ed7._comment b/doc/forum/Retrieve_previous_version_in_direct_mode/comment_4_d900388753de5870b7b9c0e8b8c06ed7._comment
new file mode 100644
index 000000000..deb26163e
--- /dev/null
+++ b/doc/forum/Retrieve_previous_version_in_direct_mode/comment_4_d900388753de5870b7b9c0e8b8c06ed7._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmNu4V5fvpLlBhaCUfXXOB0MI5NXwh8SkU"
+ nickname="Adam"
+ subject="comment 4"
+ date="2013-11-02T22:30:07Z"
+ content="""
+Thank you. Just curious, are there plans to put that in the webapp?
+"""]]
diff --git a/doc/forum/Revert_file_linkage_to_original_files.mdwn b/doc/forum/Revert_file_linkage_to_original_files.mdwn
new file mode 100644
index 000000000..ba83cfd15
--- /dev/null
+++ b/doc/forum/Revert_file_linkage_to_original_files.mdwn
@@ -0,0 +1,9 @@
+I've recently found the following problem:
+
+I really really want to get back my original folder structure - which includes the real files, not the symlinks. I've searched for quite a while, but I simply could not find an acceptable solution...
+
+So I thought I would like to ask you guys here, if anybody experienced similar problems (or at least knows a solution for my problem)?
+
+Greetings
+
+Pethor
diff --git a/doc/forum/Revert_file_linkage_to_original_files/comment_1_898ca2c9976e92d22470c7404aa9813f._comment b/doc/forum/Revert_file_linkage_to_original_files/comment_1_898ca2c9976e92d22470c7404aa9813f._comment
new file mode 100644
index 000000000..a72a2cfdd
--- /dev/null
+++ b/doc/forum/Revert_file_linkage_to_original_files/comment_1_898ca2c9976e92d22470c7404aa9813f._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 1"
+ date="2013-08-15T09:02:38Z"
+ content="""
+Sounds like you want to switch to [[direct mode]].
+
+(Or possibly to run `git annex unannex`, if you don't want to use git-annex for these files.)
+"""]]
diff --git a/doc/forum/Running_assistant_on_a_server___40__no_X_available__41__.mdwn b/doc/forum/Running_assistant_on_a_server___40__no_X_available__41__.mdwn
new file mode 100644
index 000000000..4116577bb
--- /dev/null
+++ b/doc/forum/Running_assistant_on_a_server___40__no_X_available__41__.mdwn
@@ -0,0 +1,2 @@
+How can I run the assistant on a server and access the webinterface over the network from my client pc?
+The use case I have in mind is that the server can automatically synchronize files, pushed over XMPP.
diff --git a/doc/forum/Running_assistant_on_a_server___40__no_X_available__41__/comment_1_dd75d78ef63f2689199a302ed1846017._comment b/doc/forum/Running_assistant_on_a_server___40__no_X_available__41__/comment_1_dd75d78ef63f2689199a302ed1846017._comment
new file mode 100644
index 000000000..ec31212e5
--- /dev/null
+++ b/doc/forum/Running_assistant_on_a_server___40__no_X_available__41__/comment_1_dd75d78ef63f2689199a302ed1846017._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn7gQ1zZDdWhXy9H51W2krZYShNmKL3qfM"
+ nickname="Karsten"
+ subject="comment 1"
+ date="2013-01-17T08:30:54Z"
+ content="""
+You don't need the webapp to run the assistant, but if you want, you can forward it to your local system. You will find the URL in .git/annex/url and have to extract the port from it (http://127.0.0.1:<someport>/.../), afterwards forward that port either via ssh port forwarding or via a webserver acting as a reverse proxy.
+"""]]
diff --git a/doc/forum/Running_assistant_on_a_server___40__no_X_available__41__/comment_2_df654df60c5fa6a84d786d248928a352._comment b/doc/forum/Running_assistant_on_a_server___40__no_X_available__41__/comment_2_df654df60c5fa6a84d786d248928a352._comment
new file mode 100644
index 000000000..ff43a083d
--- /dev/null
+++ b/doc/forum/Running_assistant_on_a_server___40__no_X_available__41__/comment_2_df654df60c5fa6a84d786d248928a352._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.238"
+ subject="comment 2"
+ date="2013-01-17T16:29:39Z"
+ content="""
+If this is a true server, with a static IP (or some dynamic DNS), there is no need to run the assistant on it; clients using the assistant can ssh in and sync data to it directly.
+
+Anyway, you can git config web.browser to run some script with the url it will be passed to the webapp when the webapp is started. I sometimes configure it to just echo the url out; it'd also be possible to automate
+setting up a redirection for a remote browser, I suppose.
+"""]]
diff --git a/doc/forum/Running_assistant_steps_manually.mdwn b/doc/forum/Running_assistant_steps_manually.mdwn
new file mode 100644
index 000000000..b3b683433
--- /dev/null
+++ b/doc/forum/Running_assistant_steps_manually.mdwn
@@ -0,0 +1,20 @@
+Unfortunately one of the machines that I am running git-annex on is too old to handle the watcher thread.
+
+The error message is:
+
+ Watcher crashed: Need at least OSX 10.7.0 for file-level FSEvents
+
+
+I am however interested in duplicating the assistant steps manually. I'm happy to accept that I won't have the great, auto-magic, coverage, but, how I run the steps that the assistant runs?
+
+I'm guessing there is a:
+
+ git annex add .
+ git commit -m "[blah]"
+ git annex sync
+
+but how do I get the pushing to backup/transfer/whatever remotes to work? And what order should I do these?
+
+What I would *like* to do is get a script that runs all of the needed annex steps and then kick it off in a cron job 2-5 times a day.
+
+Any thoughts?
diff --git a/doc/forum/Running_assistant_steps_manually/comment_1_e14e0a1d55d01cb4f67a94bbe349b872._comment b/doc/forum/Running_assistant_steps_manually/comment_1_e14e0a1d55d01cb4f67a94bbe349b872._comment
new file mode 100644
index 000000000..6629ff024
--- /dev/null
+++ b/doc/forum/Running_assistant_steps_manually/comment_1_e14e0a1d55d01cb4f67a94bbe349b872._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-05-19T20:18:11Z"
+ content="""
+Essentially, you want to run this:
+
+<pre>
+git annex add
+git annex sync
+for remote in $(git remote); do
+ git annex copy --auto --to $remote
+ git annex get --auto --from $remote
+done
+git annex drop --auto
+</pre>
+
+Of course this cannot sync with XMPP remotes. Otherwise it will get you to essentially the same place as the assistant.
+"""]]
diff --git a/doc/forum/Running_assistant_steps_manually/comment_2_3192f614c929b8060d4fbde56a7adec1._comment b/doc/forum/Running_assistant_steps_manually/comment_2_3192f614c929b8060d4fbde56a7adec1._comment
new file mode 100644
index 000000000..b6c10ee88
--- /dev/null
+++ b/doc/forum/Running_assistant_steps_manually/comment_2_3192f614c929b8060d4fbde56a7adec1._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnRai_qFYPVvEgC6i1nlM1bh-C__jbhqS0"
+ nickname="Matthew"
+ subject="Looks great"
+ date="2013-08-29T12:45:10Z"
+ content="""
+This looks great as I have:
+
+ * A preference for multiple small repositories.
+ * Old versions for `git-annex` due to being on Ubuntu LTS for my server.
+ * A Samsung Galaxy Nexus which somehow seems too slow to run the assistant.
+
+So these steps combined with some locking and maybe `inotify` seem perfect
+"""]]
diff --git a/doc/forum/Running_out_of__inodes.mdwn b/doc/forum/Running_out_of__inodes.mdwn
new file mode 100644
index 000000000..417de18de
--- /dev/null
+++ b/doc/forum/Running_out_of__inodes.mdwn
@@ -0,0 +1,17 @@
+When syncing with a huge git annex repository on usb disk, my small laptop partition runs out of inodes.
+
+Any workaround for this?
+
+- Use bare repository?
+
+ Some git annex command are not supported.
+ This makes managing (particularly adding) files difficult.
+
+- Use a loop file partition with tiny block size and large inode numbers?
+
+ Operations on a huge git repository are slow.
+ On a loop file partition will be slower.
+
+- Maybe shrink the partition and make room for a specific partition for git annex repository?
+
+Any opinions?
diff --git a/doc/forum/Running_out_of__inodes/comment_1_abc73d9ad662ef642337b683bf0a0253._comment b/doc/forum/Running_out_of__inodes/comment_1_abc73d9ad662ef642337b683bf0a0253._comment
new file mode 100644
index 000000000..11f2f7b7e
--- /dev/null
+++ b/doc/forum/Running_out_of__inodes/comment_1_abc73d9ad662ef642337b683bf0a0253._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.51"
+ subject="comment 1"
+ date="2013-09-12T20:37:05Z"
+ content="""
+Define \"huge\"? Checking out a git repository necessarily requires one inode per file in the repository, plus a smaller quantity for the things in .git. A git-annex repository is much the same as any other git repository.
+
+Even when I make a really tiny 100 mb ext4 filesystem, it defaults to 25000 inodes, which would be enough to contain a checkout of my second largest git-annex repository.
+
+Anyway, using git branches seems like a reasonable workaround, to the extent I understand your problem. Make a branch with the files in it you want to have available on the small drive, or check out an empty branch on the small drive and `git annex add` files in there. You can merge the branch back into your master branch on the large drive.
+"""]]
diff --git a/doc/forum/Same_Jabber_account_for_different_annexes.mdwn b/doc/forum/Same_Jabber_account_for_different_annexes.mdwn
new file mode 100644
index 000000000..f58d4abd0
--- /dev/null
+++ b/doc/forum/Same_Jabber_account_for_different_annexes.mdwn
@@ -0,0 +1 @@
+Is it possible to use the same jabber account for different annexes? I think I've mixed up several repositories by using the same jabber account for synchronizing...
diff --git a/doc/forum/Same_Jabber_account_for_different_annexes/comment_1_90c3954fe11980eef42b5f5d34f83488._comment b/doc/forum/Same_Jabber_account_for_different_annexes/comment_1_90c3954fe11980eef42b5f5d34f83488._comment
new file mode 100644
index 000000000..e39b7b52b
--- /dev/null
+++ b/doc/forum/Same_Jabber_account_for_different_annexes/comment_1_90c3954fe11980eef42b5f5d34f83488._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-04-11T15:02:40Z"
+ content="""
+This is a limitation of how jabber is currently used. You need different accounts to sync different repositories over jabber. Supporting using 1 account is the main open todo item on the [[design/assistant/xmpp]] page.
+"""]]
diff --git a/doc/forum/Same_Jabber_account_for_different_annexes/comment_2_802600b3568e5f94d0550092b22975db._comment b/doc/forum/Same_Jabber_account_for_different_annexes/comment_2_802600b3568e5f94d0550092b22975db._comment
new file mode 100644
index 000000000..6be7841ef
--- /dev/null
+++ b/doc/forum/Same_Jabber_account_for_different_annexes/comment_2_802600b3568e5f94d0550092b22975db._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="paulvt"
+ ip="2001:1af8:ff19:0:a288:b4ff:fe2c:f600"
+ subject="Resources"
+ date="2013-07-13T08:14:35Z"
+ content="""
+XMPP resources (carrying annex.uuid) cannot be of any help here?
+"""]]
diff --git a/doc/forum/Securing_a_shared_ssh_server.mdwn b/doc/forum/Securing_a_shared_ssh_server.mdwn
new file mode 100644
index 000000000..3e0006cb3
--- /dev/null
+++ b/doc/forum/Securing_a_shared_ssh_server.mdwn
@@ -0,0 +1,3 @@
+Hi, I'd like to share files with friends, to do so we need a shared server to exchange the files. I could setup an ssh access on one of my servers but I don't want others to have a full access. I assume I can restrict this using a `command='wrapper-around-git'` prefix in `.ssh/authorized_keys`, where `wrapper-around-git` is simply a script that checks if `SSH_ORIGINAL_COMMAND` is an authorised command and runs it. This is exactly the approach used with Mercurial (hg-ssh) and presumably git also relies on this mechanism.
+
+But to do so, I need to know what commands can be executed over ssh when using git-annex assistant. Could you document about this? Thanks!
diff --git a/doc/forum/Securing_a_shared_ssh_server/comment_1_ea971b57d94db5b8d487f728faa5e9a8._comment b/doc/forum/Securing_a_shared_ssh_server/comment_1_ea971b57d94db5b8d487f728faa5e9a8._comment
new file mode 100644
index 000000000..f82a57295
--- /dev/null
+++ b/doc/forum/Securing_a_shared_ssh_server/comment_1_ea971b57d94db5b8d487f728faa5e9a8._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-05-24T15:35:16Z"
+ content="""
+The git-annex assistant automatically sets up a ssh key that is locked down this way when you select \"ssh server\" in the webapp.
+
+The command you need to allow to run is git-annex-shell. This has been designed to be secure.
+"""]]
diff --git a/doc/forum/Securing_a_shared_ssh_server/comment_2_421a19f6e1fb40db6ee205daf8e3f867._comment b/doc/forum/Securing_a_shared_ssh_server/comment_2_421a19f6e1fb40db6ee205daf8e3f867._comment
new file mode 100644
index 000000000..3d92c8b27
--- /dev/null
+++ b/doc/forum/Securing_a_shared_ssh_server/comment_2_421a19f6e1fb40db6ee205daf8e3f867._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkwjBDXkP9HAQKhjTgThGOxUa1B99y_WRA"
+ nickname="Franck"
+ subject="comment 2"
+ date="2013-05-24T15:47:36Z"
+ content="""
+Thanks for your quick answer! But this is true only for servers where git-annex is installed. On a server that just does SSH, things must be different. So, I've started to use the SSH `command=` mechanism to log the commands and discovered so far four of them:
+
+ * `sh -c 'echo git-annex-probe...` and `sh -c 'mkdir -p ...` when the server is first connected by a client
+ * `rsync --server -vre.iLsf --partial-dir .rsync-partial . DIR/` and `rsync --server --sender -e31.14 --inplace . DIR//bd1/469/TEXT` when files are transfered between clients
+
+I want to derive patterns from this but if you could give them to me (ie, tell me which parts are fixed and which are variable) this will be safer. Moreover, I'm quite sure there are somme commands missing from my logs... By the way, parameter `-e31.14` to `rsync` surprises me because `-e` is supposed to set the remote shell (like `--rsh`).
+
+Cheers, Franck
+"""]]
diff --git a/doc/forum/Securing_a_shared_ssh_server/comment_3_acdbf92f646dbbf691621f08b3d94c26._comment b/doc/forum/Securing_a_shared_ssh_server/comment_3_acdbf92f646dbbf691621f08b3d94c26._comment
new file mode 100644
index 000000000..ea48a2caf
--- /dev/null
+++ b/doc/forum/Securing_a_shared_ssh_server/comment_3_acdbf92f646dbbf691621f08b3d94c26._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-05-27T19:14:37Z"
+ content="""
+I am confident that it will be *easier* to install git-annex-shell on your ssh server than it will be to lock down rsync.
+
+All you need to do is go get the standalone linux tarball of git-annex, untar it, and add its directory to PATH.
+
+You can google for perl scripts that lock down rsync, but I have never been happy with any of the ones I found.
+"""]]
diff --git a/doc/forum/Securing_a_shared_ssh_server/comment_4_67533d08e1b8706b844262e9c483d982._comment b/doc/forum/Securing_a_shared_ssh_server/comment_4_67533d08e1b8706b844262e9c483d982._comment
new file mode 100644
index 000000000..107c7b3cc
--- /dev/null
+++ b/doc/forum/Securing_a_shared_ssh_server/comment_4_67533d08e1b8706b844262e9c483d982._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkwjBDXkP9HAQKhjTgThGOxUa1B99y_WRA"
+ nickname="Franck"
+ subject="comment 4"
+ date="2013-05-28T06:34:04Z"
+ content="""
+Thanks, but my server is a synology nas and as you know from another thread of comments, having git-annex work on it is not that simple. ;-)
+Moreover, I'd like to be able to use ssh accounts where I don't have a root access and not necessarily git. So, a general method to restrict ssh would interest me.
+
+But your answer seems to suggest that almost arbitrary rsync commands may be given. If so, I agree that there are few hopes to build a secured jail around this... But if really a limited subset of commands is used, I think it should be possible to check them securely.
+
+Now on I'm focused on having git-annex work because this looks like the most promising way. But I'll have another question regarding it: I noticed that we can restrict access to a specific repository using an appropriate environnement variable. But it's it possible to provide a list of repositories instead of just one? My collaborators will typically have access to several shares but not to all of them.
+
+Thanks for your responsiveness, after trying tens of candidates git-annex appears to be the only serious solution to replace Dropbox and I'm really glad that you actively help your users!
+"""]]
diff --git a/doc/forum/Securing_a_shared_ssh_server/comment_5_bf193e02b388b4358632a169d2425b5c._comment b/doc/forum/Securing_a_shared_ssh_server/comment_5_bf193e02b388b4358632a169d2425b5c._comment
new file mode 100644
index 000000000..d0f78da92
--- /dev/null
+++ b/doc/forum/Securing_a_shared_ssh_server/comment_5_bf193e02b388b4358632a169d2425b5c._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 5"
+ date="2013-05-29T16:56:37Z"
+ content="""
+I can't say what options rsync will choose to pass to the server, when the rsync special remote uses rsync. It's up to that command.
+
+`GIT_ANNEX_SHELL_DIRECTORY` currently only supports specifying one directory.
+"""]]
diff --git a/doc/forum/Securing_a_shared_ssh_server/comment_6_50d391992cd444080ebc70db30b215c5._comment b/doc/forum/Securing_a_shared_ssh_server/comment_6_50d391992cd444080ebc70db30b215c5._comment
new file mode 100644
index 000000000..fce7ab3df
--- /dev/null
+++ b/doc/forum/Securing_a_shared_ssh_server/comment_6_50d391992cd444080ebc70db30b215c5._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkwjBDXkP9HAQKhjTgThGOxUa1B99y_WRA"
+ nickname="Franck"
+ subject="comment 6"
+ date="2013-05-29T17:41:25Z"
+ content="""
+OK, I understand now why it is complicated to secure rsync, the best I can hope is to chroot it on a restricted account. Thanks! And the \"currently\" regarding ˋGIT_ANNEX_SHELL_DIRECTORYˋ gives me hope about a future change. :-)
+Cheers, Franck
+"""]]
diff --git a/doc/forum/Setup_of_rsync_special_remote_with_non-standard_ssh_port.mdwn b/doc/forum/Setup_of_rsync_special_remote_with_non-standard_ssh_port.mdwn
new file mode 100644
index 000000000..85755e982
--- /dev/null
+++ b/doc/forum/Setup_of_rsync_special_remote_with_non-standard_ssh_port.mdwn
@@ -0,0 +1,13 @@
+I want to setup a rsync special remote on my server with a non-standard ssh port.
+
+I tried the following steps:
+
+ git annex initremote rsync-encrypted type=rsync rsyncurl=1.2.3.4:/encrypted-annex encryption=AAAAAAAAA
+ git config remote.rsync-encrypted.annex-rsync-options "-e \'ssh -p 443\'"
+
+But I just get this error:
+
+ [2012-11-22 21:04:30 CET] read: rsync ["-e","'ssh","-p","443'","--progress","--recursive","--partial","-- partial-dir=.rsync-partial","/home/marco/annex/.git/annex/tmp/rsynctmp/15309/","1.2.3.4:/encrypted-annex"]
+ Missing trailing-' in remote-shell command.
+
+I tried some ways to escape the config but I don't have a clue. Anybody?
diff --git a/doc/forum/Setup_of_rsync_special_remote_with_non-standard_ssh_port/comment_1_1eb6990e93ec92cb6fd7dbee59f31072._comment b/doc/forum/Setup_of_rsync_special_remote_with_non-standard_ssh_port/comment_1_1eb6990e93ec92cb6fd7dbee59f31072._comment
new file mode 100644
index 000000000..5af84acc0
--- /dev/null
+++ b/doc/forum/Setup_of_rsync_special_remote_with_non-standard_ssh_port/comment_1_1eb6990e93ec92cb6fd7dbee59f31072._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmLB39PC89rfGaA8SwrsnB6tbumezj-aC0"
+ nickname="Tobias"
+ subject="comment 1"
+ date="2012-11-22T22:44:11Z"
+ content="""
+Add the host to your .ssh/config like this
+
+Host myotherpc
+ HostName 10.0.0.10
+ Port 2222
+
+"""]]
diff --git a/doc/forum/Setup_of_rsync_special_remote_with_non-standard_ssh_port/comment_2_c85d5167e7ccce1ecf1de396e72ce7bc._comment b/doc/forum/Setup_of_rsync_special_remote_with_non-standard_ssh_port/comment_2_c85d5167e7ccce1ecf1de396e72ce7bc._comment
new file mode 100644
index 000000000..c336be0d1
--- /dev/null
+++ b/doc/forum/Setup_of_rsync_special_remote_with_non-standard_ssh_port/comment_2_c85d5167e7ccce1ecf1de396e72ce7bc._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnldTTAP8PAifJUmqhRar6RAWNWlRcencw"
+ nickname="Marco"
+ subject="~/.ssh/config"
+ date="2012-11-23T05:08:47Z"
+ content="""
+Thank you very much. Works like a charm.
+"""]]
diff --git a/doc/forum/Share_only_certain_files_of_a_repo___40__Assistant__41__.mdwn b/doc/forum/Share_only_certain_files_of_a_repo___40__Assistant__41__.mdwn
new file mode 100644
index 000000000..53d0e0165
--- /dev/null
+++ b/doc/forum/Share_only_certain_files_of_a_repo___40__Assistant__41__.mdwn
@@ -0,0 +1,6 @@
+Hi,
+
+When using git-annex assistant, is there a possibility to share only certain files or directories from a repository (similar to what Dropbox can do), or do we have to share whole repositories so far?
+Could this be a nice wishlist item, or is there a strong reason against adding this feature to git-annex?
+
+Thanks a lot!
diff --git a/doc/forum/Share_only_certain_files_of_a_repo___40__Assistant__41__/comment_1_ec0d56cb31b918023a9184cee168b406._comment b/doc/forum/Share_only_certain_files_of_a_repo___40__Assistant__41__/comment_1_ec0d56cb31b918023a9184cee168b406._comment
new file mode 100644
index 000000000..8fa6f7b40
--- /dev/null
+++ b/doc/forum/Share_only_certain_files_of_a_repo___40__Assistant__41__/comment_1_ec0d56cb31b918023a9184cee168b406._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.255.110"
+ subject="comment 1"
+ date="2013-09-09T19:44:57Z"
+ content="""
+Everyone can see the names of every file that is put into the git repository. Whether the contents of those files is transferred from the machine where they were created to other clones of the repository is configurable using [[preferred_content]], but it's not really intended as an access control mechanism.
+"""]]
diff --git a/doc/forum/Share_with_friend_copies_only_sym_links.mdwn b/doc/forum/Share_with_friend_copies_only_sym_links.mdwn
new file mode 100644
index 000000000..8f31b6337
--- /dev/null
+++ b/doc/forum/Share_with_friend_copies_only_sym_links.mdwn
@@ -0,0 +1,38 @@
+I just setup git-annex across three macs, using git-annex assistant. I have one repository working fine, which successfully syncs between two of my own accounts on two different machines, via S3.
+
+Now I'm trying to get the "share with a friend" feature to work. The problem is that only Mac Alias's / sym links are created, for example:
+
+Machine 1:
+- Copy file into ~/annex/
+
+Machine 2:
+- The file is synced as a sym-link, with a link into a file in .git that doesn't exist.
+
+The config is:
+- Version: 4.20130909-ga29f960 - Build flags: Assistant Webapp Pairing Testsuite S3 WebDAV FsEvents XMPP DNS Feeds Quvi
+- Two macs
+- Share with friend over Jabber
+- Use Box as the cloud sync service with encryption enabled. Box is setup as a transfer repository.
+
+I've looked through the logs in .git/annex/daemon.log* and there doesn't look to be any problems.
+
+This is what the log looks like:
+
+ [2013-09-14 19:55:47 PDT] Committer: Adding 20120101-..084-1.jpg
+ failed
+ add /Users/nick/Shared/20120101-GOPR0084-1.jpg (checksum...) ok
+ add /Users/nick/Shared/20120101-GOPR0084-1.jpg (checksum...) ok
+ add /Users/nick/Shared/20120101-GOPR0084-1.jpg (checksum...) ok
+ add /Users/nick/Shared/20120101-GOPR0084-1.jpg (checksum...) ok
+ add /Users/nick/Shared/20120101-GOPR0084-1.jpg (checksum...) [2013-09-14 19:55:47 PDT] Committer: Committing changes to git
+ [2013-09-14 19:55:48 PDT] XMPPSendPack: Syncing with USER2
+ Already up-to-date.
+ To xmpp::USER2@gmail.com
+ 7b65b15..183b91c git-annex -> refs/synced/6163ef8e-c36a-4b09-919b-9c18ade55234/bmlja2JsYWNrMUBnbWFpbC5jb20=/git-annex
+ 3104275..96afa09 master -> refs/synced/6163ef8e-c36a-4b09-919b-9c18ade55234/bmlja2JsYWNrMUBnbWFpbC5jb20=/master
+ [2013-09-14 19:55:49 PDT] XMPPSendPack: Syncing with USER2
+ Everything up-to-date
+ recv: resource vanished (Connection reset by peer)
+
+
+Any ideas what I should look at next? Thanks in advance :-)
diff --git a/doc/forum/Share_with_friend_copies_only_sym_links/comment_1_a8d22dfefb219f0c9130cc294364b198._comment b/doc/forum/Share_with_friend_copies_only_sym_links/comment_1_a8d22dfefb219f0c9130cc294364b198._comment
new file mode 100644
index 000000000..84217711a
--- /dev/null
+++ b/doc/forum/Share_with_friend_copies_only_sym_links/comment_1_a8d22dfefb219f0c9130cc294364b198._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.14.105"
+ subject="comment 1"
+ date="2013-09-19T17:41:47Z"
+ content="""
+git-annex can only share the contents of files with a friend when you both have access to a transfer repository. Your friend's git-annex webapp should detect that it does not have such a repository, and should be displaying an alert like this:
+
+[[assistant/cloudnudge.png]]
+(But in this case it should say \"Unable to download files from YourName\")
+
+So, you need to give your friend access to the S3 repository that you're already using to keep your 2 computers in sync. Or, set up some other transfer repository that you both can access.
+
+There is a way in S3 to create another key that can read and write to a S3 bucket. You can then give that key to your friend.
+
+Or, you could set up a shared git repository on a ssh server you both have access to. Or, set up a box.com remote -- the webapp will offer to store the box.com credentials and share them with your friend.
+"""]]
diff --git a/doc/forum/Sharing_annex_with_local_clones.mdwn b/doc/forum/Sharing_annex_with_local_clones.mdwn
new file mode 100644
index 000000000..756075ef9
--- /dev/null
+++ b/doc/forum/Sharing_annex_with_local_clones.mdwn
@@ -0,0 +1 @@
+Hi, is there any particular problem with symlinking one .git/annex to share between multiple repos?
diff --git a/doc/forum/Sharing_annex_with_local_clones/comment_1_2b60e13e5f7b8cee56cf2ddc6c47f64d._comment b/doc/forum/Sharing_annex_with_local_clones/comment_1_2b60e13e5f7b8cee56cf2ddc6c47f64d._comment
new file mode 100644
index 000000000..892bc50f5
--- /dev/null
+++ b/doc/forum/Sharing_annex_with_local_clones/comment_1_2b60e13e5f7b8cee56cf2ddc6c47f64d._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="don't do that"
+ date="2012-03-19T18:23:13Z"
+ content="""
+Suppose you do that to repos A and B. Now, in A, you `git annex drop` a file that is only present in those repositories. A checks B to make sure it still has a copy of the file. It sees the (same) file there, so assumes it's safe to drop. The file is removed from A, also removing it from B, and losing data.
+
+It is possible to configure A and B to mutually distrust one-another and avoid this problem, but there will be other problems too.
+
+Instead, git-annex supports using `cp --reflink=auto`, which on filesystems supporting Copy On Write (eg, btrfs), avoids duplicating contents when A and B are on the same filesystem.
+"""]]
diff --git a/doc/forum/Sharing_annex_with_local_clones/comment_2_24ff2c1eb643077daa37c01644cebcd2._comment b/doc/forum/Sharing_annex_with_local_clones/comment_2_24ff2c1eb643077daa37c01644cebcd2._comment
new file mode 100644
index 000000000..88f495da6
--- /dev/null
+++ b/doc/forum/Sharing_annex_with_local_clones/comment_2_24ff2c1eb643077daa37c01644cebcd2._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnhsaESlYphzLTzpJy5IxxGFxxctIhWYfo"
+ nickname="Bryon"
+ subject="comment 2"
+ date="2012-03-19T18:46:13Z"
+ content="""
+Ah, OK. Is there a configuration step to set this up, or is this included magic in a new enough git-annex client?
+"""]]
diff --git a/doc/forum/Sharing_annex_with_local_clones/comment_3_5359b8eada24d27be83214ac0ae62f23._comment b/doc/forum/Sharing_annex_with_local_clones/comment_3_5359b8eada24d27be83214ac0ae62f23._comment
new file mode 100644
index 000000000..3e5fd1154
--- /dev/null
+++ b/doc/forum/Sharing_annex_with_local_clones/comment_3_5359b8eada24d27be83214ac0ae62f23._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnhsaESlYphzLTzpJy5IxxGFxxctIhWYfo"
+ nickname="Bryon"
+ subject="comment 3"
+ date="2012-03-19T18:55:03Z"
+ content="""
+Nevermind, found it. (git-annex 0.08)
+"""]]
diff --git a/doc/forum/Simple_check_out_with_assistant__63__.mdwn b/doc/forum/Simple_check_out_with_assistant__63__.mdwn
new file mode 100644
index 000000000..755b237e4
--- /dev/null
+++ b/doc/forum/Simple_check_out_with_assistant__63__.mdwn
@@ -0,0 +1,2 @@
+I want to use the annex assistant instead of the command line. Which is the recommended method to check out a file that I want to edit?
+
diff --git a/doc/forum/Simple_check_out_with_assistant__63__/comment_1_ade8a0743ef1ec933c8a40ed64eeac2d._comment b/doc/forum/Simple_check_out_with_assistant__63__/comment_1_ade8a0743ef1ec933c8a40ed64eeac2d._comment
new file mode 100644
index 000000000..dbb018b53
--- /dev/null
+++ b/doc/forum/Simple_check_out_with_assistant__63__/comment_1_ade8a0743ef1ec933c8a40ed64eeac2d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmaXxj2aPZrtRkWzwswTNep8hFif1cXykw"
+ nickname="Erik"
+ subject="Follow-up: check-in"
+ date="2012-11-08T08:59:14Z"
+ content="""
+And the obvious follow-up question: How to I check in and sync the file that I just edited? (Note: I want to avoid the command line)
+"""]]
diff --git a/doc/forum/Slightly_finer_control_over_file_whereabouts.mdwn b/doc/forum/Slightly_finer_control_over_file_whereabouts.mdwn
new file mode 100644
index 000000000..2caf332af
--- /dev/null
+++ b/doc/forum/Slightly_finer_control_over_file_whereabouts.mdwn
@@ -0,0 +1,18 @@
+I have previously been confused by how to have a bit more manual control over where files are (as in [[bugs/git-annex_immediately_re-gets_dropped_files/]]).
+
+I thought perhaps something like an archive directory would work, but as I might want different computers to have different content, perhaps a per-computer archive repository.
+
+To that end, I have
+
+<pre>walter@dionysus:~/annex$ git annex content .
+(exclude=archive/dionysus/* or (not (copies=archive:1 or copies=smallarchive:1))) or (not copies=semitrusted+:1)
+ok</pre>
+
+which is a modified version of the archive [[preferred_content]], but with the intention that I change the part after `exclude` to be different for each client.
+I also set the group to client for this client (dionysus).
+
+However, it does not seem to drop files when I move them into `archive/dionysus/`, and I cannot see anything in the logs to suggest why.
+
+What am I doing wrong here? Or, is this the wrong approach?
+
+--Walter
diff --git a/doc/forum/Slightly_finer_control_over_file_whereabouts/comment_10_bcb883d46a637dd1a8ef9a92733d202a._comment b/doc/forum/Slightly_finer_control_over_file_whereabouts/comment_10_bcb883d46a637dd1a8ef9a92733d202a._comment
new file mode 100644
index 000000000..5064de49d
--- /dev/null
+++ b/doc/forum/Slightly_finer_control_over_file_whereabouts/comment_10_bcb883d46a637dd1a8ef9a92733d202a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="108.236.230.124"
+ subject="comment 10"
+ date="2013-11-08T18:32:12Z"
+ content="""
+If I could comprehensively fix that bug I would.
+
+But, it's supposed to already be fixed when using direct mode. Were you using indirect mode when you saw the problem?
+"""]]
diff --git a/doc/forum/Slightly_finer_control_over_file_whereabouts/comment_11_b7a8b9eaf114f883866fbf2be51b622f._comment b/doc/forum/Slightly_finer_control_over_file_whereabouts/comment_11_b7a8b9eaf114f883866fbf2be51b622f._comment
new file mode 100644
index 000000000..7155b560f
--- /dev/null
+++ b/doc/forum/Slightly_finer_control_over_file_whereabouts/comment_11_b7a8b9eaf114f883866fbf2be51b622f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnSenxKyE_2Z6Wb-EBMO8FciyRywjx1ZiQ"
+ nickname="Walter"
+ subject="comment 11"
+ date="2013-11-09T06:02:36Z"
+ content="""
+No, this was using direct mode.
+"""]]
diff --git a/doc/forum/Slightly_finer_control_over_file_whereabouts/comment_1_6236bcfa9beba705ead3ec2141c5d835._comment b/doc/forum/Slightly_finer_control_over_file_whereabouts/comment_1_6236bcfa9beba705ead3ec2141c5d835._comment
new file mode 100644
index 000000000..b9f598a1f
--- /dev/null
+++ b/doc/forum/Slightly_finer_control_over_file_whereabouts/comment_1_6236bcfa9beba705ead3ec2141c5d835._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.14.105"
+ subject="comment 1"
+ date="2013-09-19T17:57:22Z"
+ content="""
+That sound like it should work. I suggest you play around with `git annex drop --auto` at the command line. It will probably tell you why it is unable to drop a file if the problem is something like not enough copies located elsewhere. Or, if it doesn't try to drop the file at all, you'll know your preferred content expression makes it want to keep the file.
+"""]]
diff --git a/doc/forum/Slightly_finer_control_over_file_whereabouts/comment_2_ea935b37ca93e73c85d04df7c9bf6057._comment b/doc/forum/Slightly_finer_control_over_file_whereabouts/comment_2_ea935b37ca93e73c85d04df7c9bf6057._comment
new file mode 100644
index 000000000..50f113aa3
--- /dev/null
+++ b/doc/forum/Slightly_finer_control_over_file_whereabouts/comment_2_ea935b37ca93e73c85d04df7c9bf6057._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnSenxKyE_2Z6Wb-EBMO8FciyRywjx1ZiQ"
+ nickname="Walter"
+ subject="comment 2"
+ date="2013-09-19T22:22:03Z"
+ content="""
+So, it sort of works...
+
+I realised that I don't have `archive` repository but instead `backup` ones, so adding that makes `git annex drop --auto` want to drop files in archive/dionysus.
+
+However, the webapp then gets them. This I don't understand.
+"""]]
diff --git a/doc/forum/Slightly_finer_control_over_file_whereabouts/comment_3_f89a8e38283ac4c8c4a3b74c413d67a1._comment b/doc/forum/Slightly_finer_control_over_file_whereabouts/comment_3_f89a8e38283ac4c8c4a3b74c413d67a1._comment
new file mode 100644
index 000000000..41bb0cb58
--- /dev/null
+++ b/doc/forum/Slightly_finer_control_over_file_whereabouts/comment_3_f89a8e38283ac4c8c4a3b74c413d67a1._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.14.105"
+ subject="comment 3"
+ date="2013-09-20T00:15:07Z"
+ content="""
+does `git annex get --auto` also get them?
+"""]]
diff --git a/doc/forum/Slightly_finer_control_over_file_whereabouts/comment_4_07a0a754a089c46ff69dc97ea7ba9384._comment b/doc/forum/Slightly_finer_control_over_file_whereabouts/comment_4_07a0a754a089c46ff69dc97ea7ba9384._comment
new file mode 100644
index 000000000..30e3965af
--- /dev/null
+++ b/doc/forum/Slightly_finer_control_over_file_whereabouts/comment_4_07a0a754a089c46ff69dc97ea7ba9384._comment
@@ -0,0 +1,22 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnSenxKyE_2Z6Wb-EBMO8FciyRywjx1ZiQ"
+ nickname="Walter"
+ subject="comment 4"
+ date="2013-09-20T02:41:22Z"
+ content="""
+I am testing on my laptop, and the content expression there is
+`(exclude=archive/kronos/* ) or (not copies=semitrusted+:1)`
+to simplify things; I interpret this to mean it wants everything not in archive/kronos, and it wants things there where that's the only copy.
+
+The problem is that `git annex drop --auto` does indeed drop things, but `git annex get --auto` gets them; surely it should not be possible for that to happen?
+
+I also tried the preferred content expression of `(exclude=archive/kronos/* )`, and the same thing happens.
+
+The version of git-annex that I am using is
+<pre>git-annex version: 4.20130919-g9be7762
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP DNS Feeds Quvi
+local repository version: 4
+default repository version: 3
+supported repository versions: 3 4
+upgrade supported from repository versions: 0 1 2</pre>
+"""]]
diff --git a/doc/forum/Slightly_finer_control_over_file_whereabouts/comment_5_e884c001a556a0c693d1cc9a97c068ac._comment b/doc/forum/Slightly_finer_control_over_file_whereabouts/comment_5_e884c001a556a0c693d1cc9a97c068ac._comment
new file mode 100644
index 000000000..50e5cf9af
--- /dev/null
+++ b/doc/forum/Slightly_finer_control_over_file_whereabouts/comment_5_e884c001a556a0c693d1cc9a97c068ac._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4830:1600:187::2"
+ subject="comment 5"
+ date="2013-09-20T15:31:18Z"
+ content="""
+Ok. This seems to be a bug in git-annex then. While it's surprisingly difficult to do so, it tries to interpet preferred content expressions in a stable way -- that is, they should not want to get a file when it's missing and then want to drop it when it's present.
+"""]]
diff --git a/doc/forum/Slightly_finer_control_over_file_whereabouts/comment_6_3e8674b5857e4994dfbc26be4f4b2855._comment b/doc/forum/Slightly_finer_control_over_file_whereabouts/comment_6_3e8674b5857e4994dfbc26be4f4b2855._comment
new file mode 100644
index 000000000..eff5d9339
--- /dev/null
+++ b/doc/forum/Slightly_finer_control_over_file_whereabouts/comment_6_3e8674b5857e4994dfbc26be4f4b2855._comment
@@ -0,0 +1,25 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4830:1600:187::2"
+ subject="comment 6"
+ date="2013-09-20T15:36:25Z"
+ content="""
+I tried to reproduce this behavior, but failed. My configuration was 2 repos, A and B, with B the origin of A. A was configured with \"exclude=archive/kronos/*\"
+(also tried \"(exclude=archive/kronos/* ) or (not copies=semitrusted+:1)\")
+
+<pre>
+joey@darkstar:~/tmp/A>git annex get --auto
+joey@darkstar:~/tmp/A>git annex get
+get archive/kronos/foo (from origin...) ok
+(Recording state in git...)
+joey@darkstar:~/tmp/A>git annex drop --auto
+drop archive/kronos/foo ok
+(Recording state in git...)
+joey@darkstar:~/tmp/A>git annex get --auto
+joey@darkstar:~/tmp/A>
+</pre>
+
+... Which is how you want it to behave.
+
+So I wonder if it's something else in your configuration. The best thing to do would be if you can come up with a series of commands I can follow to build repositories that exhibit the problem.
+"""]]
diff --git a/doc/forum/Slightly_finer_control_over_file_whereabouts/comment_7_7aeabc2e52a39423e83fbd04560e8f91._comment b/doc/forum/Slightly_finer_control_over_file_whereabouts/comment_7_7aeabc2e52a39423e83fbd04560e8f91._comment
new file mode 100644
index 000000000..145a913e9
--- /dev/null
+++ b/doc/forum/Slightly_finer_control_over_file_whereabouts/comment_7_7aeabc2e52a39423e83fbd04560e8f91._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4830:1600:187::2"
+ subject="comment 7"
+ date="2013-09-20T15:37:48Z"
+ content="""
+Also, please check if you're running into [[bugs/Handling_of_files_inside_and_outside_archive_directory_at_the_same_time]]
+"""]]
diff --git a/doc/forum/Slightly_finer_control_over_file_whereabouts/comment_8_53b95449cfad2fe0f72d2ad642822c03._comment b/doc/forum/Slightly_finer_control_over_file_whereabouts/comment_8_53b95449cfad2fe0f72d2ad642822c03._comment
new file mode 100644
index 000000000..d866380f2
--- /dev/null
+++ b/doc/forum/Slightly_finer_control_over_file_whereabouts/comment_8_53b95449cfad2fe0f72d2ad642822c03._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnSenxKyE_2Z6Wb-EBMO8FciyRywjx1ZiQ"
+ nickname="Walter"
+ subject="comment 8"
+ date="2013-09-20T20:30:52Z"
+ content="""
+Hmm, that could be it; the same content is both inside and outside the archive directory.
+
+What I really want to do (because maybe I'm not going about this the best way) is to use the assistant not in manual mode, but allow for some repos not having some files.
+I thought by placing them in an archive directory, then they would be dropped, and to get them again, I can just delete from the archive dir, and they will be got (as the file is also outside the archive dir.
+
+But, if that is not going to work, is there a better way to manage that?
+
+By the way, I really appreciate all the work you put into this awesome project.
+"""]]
diff --git a/doc/forum/Slightly_finer_control_over_file_whereabouts/comment_9_a17c102a45e4fc3f101a79acb8eb4081._comment b/doc/forum/Slightly_finer_control_over_file_whereabouts/comment_9_a17c102a45e4fc3f101a79acb8eb4081._comment
new file mode 100644
index 000000000..56d22c7fd
--- /dev/null
+++ b/doc/forum/Slightly_finer_control_over_file_whereabouts/comment_9_a17c102a45e4fc3f101a79acb8eb4081._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnSenxKyE_2Z6Wb-EBMO8FciyRywjx1ZiQ"
+ nickname="Walter"
+ subject="comment 9"
+ date="2013-09-23T21:58:42Z"
+ content="""
+Thinking about this further, I'm not entirely sure what I want. I think the confusion arises from git-annex sometimes (mostly) caring about file *contents* (ie dependent on the hash of the file), but sometimes (preferred content, not sure of anywhere else) caring about file *location*.
+
+What I think I actually want is a way of specifying locations that are not synced, such that if the file is changed somewhere (on another computer), the new version should not be downloaded. But, if the same content is in another location as well, the behaviour should be stable, I don't know how that should work though.
+
+So, perhaps the best strategy is to have an explicit list of locations that I don't want, in the preferred content expression, if it could cope with files being in and out of some location at the same time. I think this would be easiest if I could avoid manually editing the expression all the time, maybe make a file with a list of file locations, if it would be possible for git-annex to handle that? I think it isn't at the moment, and my haskell is non-existent. That way, I could write some helper to add and remove files from this list. For example `dont-want file1 file2 dir1` would add these locations to a file, and `want file1 file2 dir1` would remove them from this list. Actually, I suppose I could make it just create an appropriate preferred-content expression, and then it doesn't need to support some file of locations.
+
+So, after that ramble, I guess I'm envisaging a preferred content expression like `content=(exclude=path/to/file1 and exclude=path/to/file1 and exclude=path/to/dir1/*) or (some statement about numcopies)`, which I imagine updating whenever I decide I do/don't want some file. The only obstacle to this working is [[bugs/Handling of files inside and outside archive directory at the same time]] (as I understand that bug, could be wrong on the implications of it), meaning (of course) if there are two files with the same content, and I exclude one of them, and not the other, then it both wants and doesn't want the file, and it (and I) get really confused.
+
+I suppose a short-term (well, slow) solution is to find duplicates of files I don't want, and if that exists either add the duplicate to my content expression (to say I don't want it), or remove the one I don't want from the expression (to say I do). This doesn't work well for when the content of one of the files changes (and so they are no longer duplicates), but I think I would search for them each time I generate the expression, so at that time it would no longer find the duplicate.
+
+So, @joey, I guess my question is, what are the chances of that bug being resolved somehow? Or if that is not likely to happen soon, I might try to implement my solution outline from the previous two paragraphs.
+"""]]
diff --git a/doc/forum/Some_mounted_devices_not_detected.mdwn b/doc/forum/Some_mounted_devices_not_detected.mdwn
new file mode 100644
index 000000000..6146ef14f
--- /dev/null
+++ b/doc/forum/Some_mounted_devices_not_detected.mdwn
@@ -0,0 +1,3 @@
+Automounted USB devices are not detected by the git-annex webapp on my Debian testing/squeeze installation, only drives with entries in /etc/fstab show up in the device list. Is there any way to tweak/get around this?
+
+I'm running version 4.20131106 (couldn't manage to build the package for sid).
diff --git a/doc/forum/Some_mounted_devices_not_detected/comment_1_0ba07b95f12f57ea63bb450b88430c45._comment b/doc/forum/Some_mounted_devices_not_detected/comment_1_0ba07b95f12f57ea63bb450b88430c45._comment
new file mode 100644
index 000000000..5cd472c8e
--- /dev/null
+++ b/doc/forum/Some_mounted_devices_not_detected/comment_1_0ba07b95f12f57ea63bb450b88430c45._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.64"
+ subject="comment 1"
+ date="2013-11-24T16:04:23Z"
+ content="""
+can you post an example line from /proc/mounts for one of these devices?
+"""]]
diff --git a/doc/forum/Some_mounted_devices_not_detected/comment_2_4f8c7bcd0f20dafa5635a3580ec8d1f6._comment b/doc/forum/Some_mounted_devices_not_detected/comment_2_4f8c7bcd0f20dafa5635a3580ec8d1f6._comment
new file mode 100644
index 000000000..60512d418
--- /dev/null
+++ b/doc/forum/Some_mounted_devices_not_detected/comment_2_4f8c7bcd0f20dafa5635a3580ec8d1f6._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmyEv6SesaYeke389mHdiHlavirPkGHzHI"
+ nickname="Albin"
+ subject="comment 2"
+ date="2013-11-26T14:35:58Z"
+ content="""
+I missed your reply on IRC. Sorry for that!
+
+Here's an example from /proc/mounts:
+
+ /dev/sdf1 /media/SoderUSB ext4 rw,nosuid,nodev,noexec,relatime,errors=remount-ro,data=ordered 0 0
+
+"""]]
diff --git a/doc/forum/Some_mounted_devices_not_detected/comment_3_06c0db7d670d9b82823102d22db15a36._comment b/doc/forum/Some_mounted_devices_not_detected/comment_3_06c0db7d670d9b82823102d22db15a36._comment
new file mode 100644
index 000000000..53c76e210
--- /dev/null
+++ b/doc/forum/Some_mounted_devices_not_detected/comment_3_06c0db7d670d9b82823102d22db15a36._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.64"
+ subject="comment 3"
+ date="2013-11-26T19:59:42Z"
+ content="""
+Hmm, that looks fine.
+
+Perhaps the user you're running git-annex as cannot write to `/media/SoderUSB` ? The webapp avoids listing places you can't write, since it would fail to make a repository there. (Also because this is an easy way for it to avoid listing `/`, `/usr`, or whatever other OS-level mounts a system might have..)
+"""]]
diff --git a/doc/forum/Some_mounted_devices_not_detected/comment_4_80820a29361c5be4a94672dacfdefa6f._comment b/doc/forum/Some_mounted_devices_not_detected/comment_4_80820a29361c5be4a94672dacfdefa6f._comment
new file mode 100644
index 000000000..03b917a69
--- /dev/null
+++ b/doc/forum/Some_mounted_devices_not_detected/comment_4_80820a29361c5be4a94672dacfdefa6f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmyEv6SesaYeke389mHdiHlavirPkGHzHI"
+ nickname="Albin"
+ subject="comment 4"
+ date="2013-11-27T17:33:22Z"
+ content="""
+Actually, that (write permissions) seems to have been the problem. Thanks! Can't imagine why pmount would not mount a device writable by my user, though.
+"""]]
diff --git a/doc/forum/Special_remote_without_chmod.mdwn b/doc/forum/Special_remote_without_chmod.mdwn
new file mode 100644
index 000000000..46ace443b
--- /dev/null
+++ b/doc/forum/Special_remote_without_chmod.mdwn
@@ -0,0 +1,12 @@
+Apparently, the tablet computer I'm using (Galaxy Tab 2, non-rooted) does not export the sd cards via mass storage protocol (UMS) any more. In order to be able to use a special remote for my mp3-files, I installed an ftp/ssh server on the tablet device and used curlftpfs/sshfs (fuse file systems) to mount the sd cards on my local Linux machine. In this way, it is is quite easy to setup the special remote (e.g. "git-annex initremote galaxy-tab type=directory directory=$HOME/mnt/galaxy-tab encryption=none").
+
+Problems arise, when files are transferred to the special remote. From the logs of the ftp server, I can see that the actual copy operation is successful (the data is written to the file system), but the subsequent "chmod" that changes the permissions to read-only fails. The output on the console of a "git-annex copy -t galaxy-tab" is
+
+ copy 01 some.mp3 (to galaxy-tab...)
+ failed
+ git-annex: copy: 1 failed
+
+
+Therefore my question: is it possible to perform a file transfer to a special remote (type=directory) without the final "chmod"-operation?
+
+Thank you.
diff --git a/doc/forum/Special_remote_without_chmod/comment_1_4f5f9506cae72a1f321296fc5a5f339a._comment b/doc/forum/Special_remote_without_chmod/comment_1_4f5f9506cae72a1f321296fc5a5f339a._comment
new file mode 100644
index 000000000..225cfa6cb
--- /dev/null
+++ b/doc/forum/Special_remote_without_chmod/comment_1_4f5f9506cae72a1f321296fc5a5f339a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.49"
+ subject="comment 1"
+ date="2012-11-25T22:00:12Z"
+ content="""
+That could be hacked into directory as a configuration setting, but I think it makes more sense to add a proper sftp special remote, and avoid the rather complex stack you're using.
+"""]]
diff --git a/doc/forum/Storing_uncontrolled_files_in_an_annex.mdwn b/doc/forum/Storing_uncontrolled_files_in_an_annex.mdwn
new file mode 100644
index 000000000..e2111f0b9
--- /dev/null
+++ b/doc/forum/Storing_uncontrolled_files_in_an_annex.mdwn
@@ -0,0 +1,3 @@
+Is there a way to store a file in an annex repo without the assistant trying to commit it? My particular issue is that git annex watch tries to add my .thunderbird folder, and I don't want it in annex. Is that a supported use case?
+
+Also, for my better understanding, does watch keep track of what files it saw last time and only look for new things on startup? Or does it try to commit anything that's not already in git (whether symlink or not)?
diff --git a/doc/forum/Storing_uncontrolled_files_in_an_annex/comment_1_175645a90be0c79221c129308adf643e._comment b/doc/forum/Storing_uncontrolled_files_in_an_annex/comment_1_175645a90be0c79221c129308adf643e._comment
new file mode 100644
index 000000000..2932efa39
--- /dev/null
+++ b/doc/forum/Storing_uncontrolled_files_in_an_annex/comment_1_175645a90be0c79221c129308adf643e._comment
@@ -0,0 +1,27 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 1"
+ date="2012-12-16T00:10:39Z"
+ content="""
+wow, are you git annexing your whole home directory? that sounds extreme and problematic, since everything in git annex becomes read-only!!
+
+This how to make git annex ignore something though: make git ignore it in the first place.
+
+Stop the git assistant if it's running.
+
+create a file called \".gitignore\" in the root of your annex directory; add a line to that file for everything you want git (and therefore git annex) to ignore, e.g. \".thunderbird\"
+
+
+e.g.:
+
+ echo '.thunderbird' > '.gitignore'
+
+check that file into git:
+
+
+ git add .gitignore
+ git commit -m 'check in .gitignore'
+
+Now you should be able to start up git-annex again and have it ignore .thunderbird, or any other path you put in .gitignore
+"""]]
diff --git a/doc/forum/Storing_uncontrolled_files_in_an_annex/comment_2_d29f214eadfe3bfd098bbc3bcf07129a._comment b/doc/forum/Storing_uncontrolled_files_in_an_annex/comment_2_d29f214eadfe3bfd098bbc3bcf07129a._comment
new file mode 100644
index 000000000..395f08d24
--- /dev/null
+++ b/doc/forum/Storing_uncontrolled_files_in_an_annex/comment_2_d29f214eadfe3bfd098bbc3bcf07129a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="andy"
+ ip="108.92.50.62"
+ subject="Thanks!"
+ date="2012-12-16T00:31:09Z"
+ content="""
+That does what I needed. I'd forgotten about that. :)
+"""]]
diff --git a/doc/forum/Storing_uncontrolled_files_in_an_annex/comment_3_286b502e7906cca50e9e747db735bc88._comment b/doc/forum/Storing_uncontrolled_files_in_an_annex/comment_3_286b502e7906cca50e9e747db735bc88._comment
new file mode 100644
index 000000000..f23854cbf
--- /dev/null
+++ b/doc/forum/Storing_uncontrolled_files_in_an_annex/comment_3_286b502e7906cca50e9e747db735bc88._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.117"
+ subject="comment 3"
+ date="2012-12-17T16:32:31Z"
+ content="""
+AFAIK, the assistant does *not* currently honor .gitgnore completely. There are parts of it that do, and places where running git commands to check .gitignore would be very expensive, and so I've TODOed it for later, as I'll need to write my own .gitignore parser.
+
+So, use caution..
+"""]]
diff --git a/doc/forum/Stupid_mistake:_recoverable__63__.mdwn b/doc/forum/Stupid_mistake:_recoverable__63__.mdwn
new file mode 100644
index 000000000..8e25d7081
--- /dev/null
+++ b/doc/forum/Stupid_mistake:_recoverable__63__.mdwn
@@ -0,0 +1,31 @@
+Hi,
+
+I was a bit hasty the other day and did something stupid. I
+added a new folder to git annex. Something like
+
+ git annex add my-important folder
+
+my-important folder contains a lot of files and it took a couple
+of minutes to add. When I then tried to do
+
+ git commit -am 'added files'
+
+per the walkthrough I got an error (9, as I recall). I thought
+I'd added too many files or something so I wanted to start over
+and perhaps I didn't fully understand the mechanisms of annex I
+did the following
+
+ git reset --hard .
+
+Unfortunately, did replaced my files with a bunch of symlinks,
+rather than making git annex forget and go back to the previous
+stage as I had hoped.
+
+I have managed to recover most of my files from backup, but some
+of them I still can't recover. Is there any way back? It seems
+I still have the files in my git folder.
+
+Thanks,
+Rasmus
+
+PS: Sorry, I shouldn't have made this text rather than Markdown.
diff --git a/doc/forum/Stupid_mistake:_recoverable__63__/comment_1_00ceb3a5e37825c4bbc806f532893706._comment b/doc/forum/Stupid_mistake:_recoverable__63__/comment_1_00ceb3a5e37825c4bbc806f532893706._comment
new file mode 100644
index 000000000..ebc8073f7
--- /dev/null
+++ b/doc/forum/Stupid_mistake:_recoverable__63__/comment_1_00ceb3a5e37825c4bbc806f532893706._comment
@@ -0,0 +1,23 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-04-01T18:24:20Z"
+ content="""
+The file contents are still there in `.git/annex/objects/`.
+
+When I run `git reset --hard`, it deletes any files that have been added, but not committed. You say you still have symlinks to the content. If so, you can just `git add` the symlinks and be back how git-annex wants things to be.
+
+If, instead, you are missing the symlinks, then since you never committed the symlinks to git, there is no record anywhere in git of the filenames that go with the file contents.
+
+What you can do is ask git-annex to put back symlinks to the file contents:
+
+<pre>
+git annex unused
+git annex addunused 1-10000
+</pre>
+
+This will make you have a bunch of files in the repository with names starting with \"unused\". You can then rename them manually.
+
+BTW, I would of course be interested in any error message from `git commit`.
+"""]]
diff --git a/doc/forum/Stupid_mistake:_recoverable__63__/comment_2_cbedc29678d9b6af3b3c0bb1915d2391._comment b/doc/forum/Stupid_mistake:_recoverable__63__/comment_2_cbedc29678d9b6af3b3c0bb1915d2391._comment
new file mode 100644
index 000000000..f552cfb18
--- /dev/null
+++ b/doc/forum/Stupid_mistake:_recoverable__63__/comment_2_cbedc29678d9b6af3b3c0bb1915d2391._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="Rasmus"
+ ip="213.120.148.111"
+ subject="comment 2"
+ date="2013-04-01T23:23:55Z"
+ content="""
+Joey,
+
+Thanks for your useful tips and for providing this software. It seems incredibly powerful and useful. I made a copy of the folder which I messed up. I will try the tips and report back (I'm on the road right now).
+
+The other day all the Haskell deps worked out and I managed to build git annex. Hopefully, this will give more reliable results as it seemed that some of my bugs were caused by the 32bit prebuild on 64bit. If I succeed in recreating my files I will try to recreate the error :)
+"""]]
diff --git a/doc/forum/Stupid_mistake:_recoverable__63__/comment_3_86aa4d92a1330811862da1ba568b3037._comment b/doc/forum/Stupid_mistake:_recoverable__63__/comment_3_86aa4d92a1330811862da1ba568b3037._comment
new file mode 100644
index 000000000..b642cde98
--- /dev/null
+++ b/doc/forum/Stupid_mistake:_recoverable__63__/comment_3_86aa4d92a1330811862da1ba568b3037._comment
@@ -0,0 +1,42 @@
+[[!comment format=mdwn
+ username="Rasmus"
+ ip="213.120.148.111"
+ subject="comment 3"
+ date="2013-04-02T23:25:45Z"
+ content="""
+Joey,
+
+Sorry for asking again, but I haven't been able to resolve this using the symlinks.
+
+Consider this file
+
+ ElgarCEH.pdf -> ../.git/annex/objects/g6/q8/SHA256E-759787--3ec5f8d64cc4f84dec74ed7f0f7a640b3e672a03faf0f5fc3daf0b823d596f03.pdf/SHA256E-759787--3ec5f8d64cc4f84dec74ed7f0f7a640b3e672a03faf0f5fc3daf0b823d596f03.pdf
+
+The file that the symlink points to doesn't exist. I'm not sure it should. The file with {.map,.cahce} extensions does exist, in this case
+
+ sh>ls ../.git/annex/objects/g6/q8/SHA256E-s759787--3ec5f8d64cc4f84dec74ed7f0f7a640b3e672a03faf0f5fc3daf0b823d596f03.pdf/
+ SHA256E-s759787--3ec5f8d64cc4f84dec74ed7f0f7a640b3e672a03faf0f5fc3daf0b823d596f03.pdf.cache
+ SHA256E-s759787--3ec5f8d64cc4f84dec74ed7f0f7a640b3e672a03faf0f5fc3daf0b823d596f03.pdf.map
+
+The content of the .cache file is
+
+ 1703824 411810 1350480334
+
+and the content of the .map file is
+
+ documents/ElgarCEH.pdf
+
+However, for all of the following
+
+ git add ElgarCEH.pdf
+ git add --force ElgarCEH.pdf
+ git annex add ElgarCEH.pdf
+
+the files are not staged, and I get the message usual
+
+ no changes added to commit.
+
+with `git log`.
+
+So do I need to something more in order to get `git` to add my symlinks?
+"""]]
diff --git a/doc/forum/Stupid_mistake:_recoverable__63__/comment_4_6d15bf8a3c3c27cc92957070161675a9._comment b/doc/forum/Stupid_mistake:_recoverable__63__/comment_4_6d15bf8a3c3c27cc92957070161675a9._comment
new file mode 100644
index 000000000..97a4cd0db
--- /dev/null
+++ b/doc/forum/Stupid_mistake:_recoverable__63__/comment_4_6d15bf8a3c3c27cc92957070161675a9._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 4"
+ date="2013-04-02T23:39:48Z"
+ content="""
+If you `git add` a file and `git commit` says \"no changes added to commit\", what would you think would be the reason?
+
+I'd think it was because the file was already committed to git. So that must be the case with your symlink.
+
+You seem to have told git-annex to do something to the content of that file. You could use `git annex whereis` to find where it is, or `git annex get` to get it. (Assuming you have not used `git annex drop --force` on the file to nuke its content earlier.)
+"""]]
diff --git a/doc/forum/Stupid_mistake:_recoverable__63__/comment_5_f836b9b1d03d94c49e3798961790b2ba._comment b/doc/forum/Stupid_mistake:_recoverable__63__/comment_5_f836b9b1d03d94c49e3798961790b2ba._comment
new file mode 100644
index 000000000..d28c247e1
--- /dev/null
+++ b/doc/forum/Stupid_mistake:_recoverable__63__/comment_5_f836b9b1d03d94c49e3798961790b2ba._comment
@@ -0,0 +1,21 @@
+[[!comment format=mdwn
+ username="Rasmus"
+ ip="213.120.148.111"
+ subject="comment 5"
+ date="2013-04-03T00:45:05Z"
+ content="""
+> [links not being added].
+Right. Obliviously. Sorry.
+
+
+I think the problem is more severe as all of the files have somehow ended up in the .git/objects folder. I have no idea how, but I have been unsuccessful with both methods (the second methods gives me
+
+ getFileStatus: does not exist (No such file or directory)
+
+which I guess is related to the fact that my files somehow ended up in the git objects folder rather than the git annex objects folder.
+
+I appreciated the help.
+
+Cheers,
+Rasmus
+"""]]
diff --git a/doc/forum/Suggestion:_Put_ssh_server_back_into_android_version.mdwn b/doc/forum/Suggestion:_Put_ssh_server_back_into_android_version.mdwn
new file mode 100644
index 000000000..1f8730514
--- /dev/null
+++ b/doc/forum/Suggestion:_Put_ssh_server_back_into_android_version.mdwn
@@ -0,0 +1,9 @@
+Hi!
+
+Just tried various android ssh servers which do work, but have no access to the command line tools shipped with git annex.
+
+From what I gather from the planning docs, sshd was stripped from the android tools to save space. If this were the case, it (naively) seems to me it would have to be simple to re-enable.
+
+Rationale: It would make it super convenient to use command line git annex on my phone alongside the assistant, through letting me type on my desktop. Not to mention that the command line tools shipped with git annex are by far the best around for android work.
+
+Carlo
diff --git a/doc/forum/Suggestion:_Put_ssh_server_back_into_android_version/comment_1_5c2f376a82458c6387560355940419d3._comment b/doc/forum/Suggestion:_Put_ssh_server_back_into_android_version/comment_1_5c2f376a82458c6387560355940419d3._comment
new file mode 100644
index 000000000..9a39a2e4c
--- /dev/null
+++ b/doc/forum/Suggestion:_Put_ssh_server_back_into_android_version/comment_1_5c2f376a82458c6387560355940419d3._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 1"
+ date="2013-11-02T19:42:13Z"
+ content="""
+sshd was removed from the bundle because it's not needed for git-annex to be used on Android, and it would be very complicated to get it to work. (And would require rooting the device at least for port 22 and probably also since sshd needs to run as root generally.)
+
+If there are android ssh servers that let you choose which user to log in as, you could log in as the app_NN user corresponding to the git-annex android app, and have all the tools available, once you ran runshell. I belive there's also an equivilant to su on android that lets you change to an app_NN user, although you probably already need root.
+
+I think it's more usual to use adb in these situations.
+"""]]
diff --git a/doc/forum/Suggestion:_Put_ssh_server_back_into_android_version/comment_2_6321dec0b2f22f841f3cb986e063113f._comment b/doc/forum/Suggestion:_Put_ssh_server_back_into_android_version/comment_2_6321dec0b2f22f841f3cb986e063113f._comment
new file mode 100644
index 000000000..b1ce5a1a5
--- /dev/null
+++ b/doc/forum/Suggestion:_Put_ssh_server_back_into_android_version/comment_2_6321dec0b2f22f841f3cb986e063113f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnZEanlyzay_QlEAL0CWpyZcRTyN7vay8U"
+ nickname="Carlo"
+ subject="comment 2"
+ date="2013-11-03T09:48:53Z"
+ content="""
+Ah, the \"very complicated to get it to work\" part is what I didn't know, thanks for explaining and or the tips.
+"""]]
diff --git a/doc/forum/Sync_with_one_offline_peer.txt b/doc/forum/Sync_with_one_offline_peer.txt
new file mode 100644
index 000000000..6ee05c6e6
--- /dev/null
+++ b/doc/forum/Sync_with_one_offline_peer.txt
@@ -0,0 +1,11 @@
+Hello,
+
+I use the assistant to set up two repositories A and B synced using jabber. A third repository C on my server is used as rsync transfer. Syncing works fine between both repos when both are online.
+
+But when either A or B is offline the sync does not happen when it comes online again, though the file was synced to C.
+
+Is this because C is only a rsync repository and can't hold metadata? How can I achieve that the sync happens also when one of the repositories is offline?
+
+I also tried using the static build of git annex on my server. It seemed to run fine but during the setup the assistant got an error about too many command line arguments. On A und B I use the ArchLinux AUR build (https://aur.archlinux.org/packages/git-annex-standalone/), on C I use the static build. Could it be a version mismatch?
+
+Thanks!
diff --git a/doc/forum/Sync_with_one_offline_peer/comment_1_3859d842d4f7e2ef44877b05ebe881fb._comment b/doc/forum/Sync_with_one_offline_peer/comment_1_3859d842d4f7e2ef44877b05ebe881fb._comment
new file mode 100644
index 000000000..5fe670d35
--- /dev/null
+++ b/doc/forum/Sync_with_one_offline_peer/comment_1_3859d842d4f7e2ef44877b05ebe881fb._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnsuhFUIfWNT-Q-C02FDaSQqceFDge5M9w"
+ nickname="Florian"
+ subject="comment 1"
+ date="2013-09-09T21:49:17Z"
+ content="""
+Another try on the layout:
+
+Hello,
+
+I use the assistant to set up two repositories A and B synced using jabber. A third repository C on my server is used as rsync transfer. Syncing works fine between both repos when both are online.
+
+But when either A or B is offline the sync does not happen when it comes online again, though the file was synced to C.
+
+Is this because C is only a rsync repository and can't hold metadata? How can I achieve that the sync happens also when one of the repositories is offline?
+
+I also tried using the static build of git annex on my server. It seemed to run fine but during the setup the assistant got an error about too many command line arguments. On A und B I use the ArchLinux AUR build (https://aur.archlinux.org/packages/git-annex-standalone/), on C I use the static build. Could it be a version mismatch?
+
+Thanks!
+"""]]
diff --git a/doc/forum/Sync_with_one_offline_peer/comment_2_c9ba3983b37b0c1868269616fd81e518._comment b/doc/forum/Sync_with_one_offline_peer/comment_2_c9ba3983b37b0c1868269616fd81e518._comment
new file mode 100644
index 000000000..20b82dd3e
--- /dev/null
+++ b/doc/forum/Sync_with_one_offline_peer/comment_2_c9ba3983b37b0c1868269616fd81e518._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.51"
+ subject="comment 2"
+ date="2013-09-12T21:13:36Z"
+ content="""
+Yes, the rsync repository is not a git repository and so does not hold metadata. If you can install git-annex on your server, you can add a regular git repository there, and then the clients can sync to it even when the other is offline.
+
+This is also why I an working on adding support for [[special_remotes/gcrypt]] repositories, so you can have a fully encrypted git repository on the server and sync through that.
+
+> during the setup the assistant got an error about too many command line arguments
+
+I have never heard about such a problem. You should file a bug report with the details.
+"""]]
diff --git a/doc/forum/Sync_with_one_offline_peer/comment_3_28b9c003b4560c3ce90c9ebf808b091b._comment b/doc/forum/Sync_with_one_offline_peer/comment_3_28b9c003b4560c3ce90c9ebf808b091b._comment
new file mode 100644
index 000000000..332cd83c3
--- /dev/null
+++ b/doc/forum/Sync_with_one_offline_peer/comment_3_28b9c003b4560c3ce90c9ebf808b091b._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnsuhFUIfWNT-Q-C02FDaSQqceFDge5M9w"
+ nickname="Florian"
+ subject="comment 3"
+ date="2013-09-13T10:52:33Z"
+ content="""
+Thanks for your reply. The bug report is at <http://git-annex.branchable.com/bugs/git-annex:_Argument_list_too_long/>
+
+I'll be happy to provide any more help if I can!
+"""]]
diff --git a/doc/forum/Sync_without_jabber_account.mdwn b/doc/forum/Sync_without_jabber_account.mdwn
new file mode 100644
index 000000000..b459f3310
--- /dev/null
+++ b/doc/forum/Sync_without_jabber_account.mdwn
@@ -0,0 +1,9 @@
+Hi,
+
+It is possible to keep devices sync only using a box.com account as a transfer remote, without Jabber? I can't use Jabber because of firewall restrictions.
+
+It would be nice to be able to use the transfer remote, in my case box.net, as the sync "provider", for example by polling a file with the needed changes in a pre-defined interval.
+
+Regards,
+
+Stone
diff --git a/doc/forum/Sync_without_jabber_account/comment_1_3e95ac2e67451f953cf0538094109f8b._comment b/doc/forum/Sync_without_jabber_account/comment_1_3e95ac2e67451f953cf0538094109f8b._comment
new file mode 100644
index 000000000..1a601848c
--- /dev/null
+++ b/doc/forum/Sync_without_jabber_account/comment_1_3e95ac2e67451f953cf0538094109f8b._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.90"
+ subject="comment 1"
+ date="2013-07-17T19:06:59Z"
+ content="""
+We don't currently have a way to store a git repository on box.com, and you need such a git repo on a server somewhere if you're not using Jabber.
+
+Of course you can mount the box.com, using either davfs2 or something else, and put a bare git repository in its directory, and if you set this up on multiple computers, it might just work (or they might both try to write to it at the same time and fail.. I have not tried).
+"""]]
diff --git a/doc/forum/Synchronize_large_files___40__VM_images__41__.mdwn b/doc/forum/Synchronize_large_files___40__VM_images__41__.mdwn
new file mode 100644
index 000000000..71de3ee7c
--- /dev/null
+++ b/doc/forum/Synchronize_large_files___40__VM_images__41__.mdwn
@@ -0,0 +1,10 @@
+Hi,
+
+i'm thinking to use git-annex to synchronize my virtual machine directory (Virtualbox) between 3 pc. It's quite big: more than 200GB and some of the images are 40Gb in size.
+
+The synchronization will be over a lan (obviously). It is already in place with 2pc and unison but the configuration of the 3rd pc is cumbersome.
+Does anybody have experiences with git-annex and such amount of data?
+
+Thanks in advance
+
+Gabriele
diff --git a/doc/forum/Synchronize_large_files___40__VM_images__41__/comment_1_619f6ed2d7da5832ab253d61b6dd8044._comment b/doc/forum/Synchronize_large_files___40__VM_images__41__/comment_1_619f6ed2d7da5832ab253d61b6dd8044._comment
new file mode 100644
index 000000000..292ee3b7b
--- /dev/null
+++ b/doc/forum/Synchronize_large_files___40__VM_images__41__/comment_1_619f6ed2d7da5832ab253d61b6dd8044._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.49"
+ subject="comment 1"
+ date="2012-11-28T18:01:31Z"
+ content="""
+This volume of data should be no problem for git-annex.
+
+The only catch would be if you're running those VM images and want to sync them as they're changed. With git-annex, you'd need to `git annex unlock` a file to allow it to be modified, and then `git annex add` it back and commit changes made to it.
+"""]]
diff --git a/doc/forum/Syncing_machines_on_different_networks.mdwn b/doc/forum/Syncing_machines_on_different_networks.mdwn
new file mode 100644
index 000000000..6851a6c01
--- /dev/null
+++ b/doc/forum/Syncing_machines_on_different_networks.mdwn
@@ -0,0 +1,9 @@
+I've been using git-annex locally for a couple months. So far I've only used it to keep track of files on my laptop and local usb hard drives. Now I would like to add a network into the picture, and hopefully start to move away from Dropbox.
+
+I have Dropbox on two computers: my home machine and my work machine. The home machine is only on when I'm at home and the work machine is only on when I'm at work, so the computers are never on at the same time and thus can never communicate directly. What are my options for keeping annexes on these two machines in sync?
+
+Initially I was hoping that I could use an S3 special remote for this, but I see that special remotes only hold the actual file data, not any of the git stuff. So I can't push my changes to S3 at work and then pull those changes in at home.
+
+From what I can tell from the documentation, the only way I can handle this problem is to have an annex sitting on a VPS or someplace that both my home and work machines can talk to. Is that correct? That would be ok, but if I'm going to put my annex out there in the cloud somewhere, I want the files to be encrypted. It looks like git-annex only supports encryption of file data with special remotes, not a full annex. Is there no way to have some sort of encrypted git-annex hub?
+
+I backed the assistant and have been following the development blog, but I haven't tried it out yet. Am I correct in thinking that nothing in the assistant will address this particular issue?
diff --git a/doc/forum/Syncing_machines_on_different_networks/comment_1_1c3523c722c178a96b096a68b9be4165._comment b/doc/forum/Syncing_machines_on_different_networks/comment_1_1c3523c722c178a96b096a68b9be4165._comment
new file mode 100644
index 000000000..dcc59017b
--- /dev/null
+++ b/doc/forum/Syncing_machines_on_different_networks/comment_1_1c3523c722c178a96b096a68b9be4165._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn7gQ1zZDdWhXy9H51W2krZYShNmKL3qfM"
+ nickname="Karsten"
+ subject="comment 1"
+ date="2012-11-02T07:21:15Z"
+ content="""
+I might be thinking too simple, but can't you just put another annex repository on an usbdrive and use it to carry the metadata around? Add it as a remote to both compuers annex repositories and sync when you come/leave. As it does not have to carry the actual data some 100M will usually suffice. Just don't use any special remotes, but simply a cloned git repository.
+"""]]
diff --git a/doc/forum/Syncing_machines_on_different_networks/comment_2_d7b14ffee65072329cfe9ab08a0dba50._comment b/doc/forum/Syncing_machines_on_different_networks/comment_2_d7b14ffee65072329cfe9ab08a0dba50._comment
new file mode 100644
index 000000000..6f0f04496
--- /dev/null
+++ b/doc/forum/Syncing_machines_on_different_networks/comment_2_d7b14ffee65072329cfe9ab08a0dba50._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="annexuser"
+ ip="50.125.40.225"
+ subject="comment 2"
+ date="2012-11-02T19:41:27Z"
+ content="""
+That's what I've started to do. It gets the job done, but I don't like that I have to remember to plug in the stick and sync to it at the end of the work day, and then plug in the stick and sync from it when I get home. I'm hoping that there is some way to accomplish the syncing automagically, more akin to the Dropbox experience.
+"""]]
diff --git a/doc/forum/Syncing_machines_on_different_networks/comment_3_65d1dae9b76fccb5f2b8fd8c69b60075._comment b/doc/forum/Syncing_machines_on_different_networks/comment_3_65d1dae9b76fccb5f2b8fd8c69b60075._comment
new file mode 100644
index 000000000..2fa7ac055
--- /dev/null
+++ b/doc/forum/Syncing_machines_on_different_networks/comment_3_65d1dae9b76fccb5f2b8fd8c69b60075._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.194"
+ subject="comment 3"
+ date="2012-11-04T19:44:11Z"
+ content="""
+You need two things:
+
+1. A special remote in the cloud. S3, or rsync.net, or whatever.
+2. A git repository hosted in the cloud. You could just use github (paying them if you want to avoid it being public).
+
+Is it possible to have an encrypted git remote repository? It's not directly supported by git. The way git needs to be able to request arbitrary objects by SHA, kind of prevents encrypting things to any useful level. The only way I can think of to do that would be to use some cloud storage that can be mounted as a filesystem, and store an encrypted filesystem containing the git repo in a file inside that. Not easy.
+
+The git-annex assistant is going to get around this by not requiring a central git repository and transferring git data peer-to-peer, but that will require both the peers be on the network at the same time.
+"""]]
diff --git a/doc/forum/Syncing_machines_on_different_networks/comment_4_2ec67428af69d6c0ea051c6a67d58905._comment b/doc/forum/Syncing_machines_on_different_networks/comment_4_2ec67428af69d6c0ea051c6a67d58905._comment
new file mode 100644
index 000000000..34d37ce4f
--- /dev/null
+++ b/doc/forum/Syncing_machines_on_different_networks/comment_4_2ec67428af69d6c0ea051c6a67d58905._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="annexuser"
+ ip="50.125.40.225"
+ subject="comment 4"
+ date="2012-11-05T02:07:00Z"
+ content="""
+Thanks for the feedback.
+
+I'm thinking the smartest move will be for me to invest in some sort of wall-wart, like a SheevaPlug or RasberryPi. I can use that as the centralized hub and still avoid putting my files on the big bad interwebs.
+"""]]
diff --git a/doc/forum/Syncing_machines_on_different_networks/comment_5_5ce093f82a2aad3fd8d7ccd5fdcab94f._comment b/doc/forum/Syncing_machines_on_different_networks/comment_5_5ce093f82a2aad3fd8d7ccd5fdcab94f._comment
new file mode 100644
index 000000000..c3d9d52b2
--- /dev/null
+++ b/doc/forum/Syncing_machines_on_different_networks/comment_5_5ce093f82a2aad3fd8d7ccd5fdcab94f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn7gQ1zZDdWhXy9H51W2krZYShNmKL3qfM"
+ nickname="Karsten"
+ subject="comment 5"
+ date="2012-11-05T06:43:25Z"
+ content="""
+Just a small add-up: I've already used a truecrypt volume file on a dropbox successfully, although not for a git repository. Maybe that's worth a try.
+"""]]
diff --git a/doc/forum/Syncing_machines_on_different_networks/comment_6_a55982c28d7b90e0b70ec2bb5e594e08._comment b/doc/forum/Syncing_machines_on_different_networks/comment_6_a55982c28d7b90e0b70ec2bb5e594e08._comment
new file mode 100644
index 000000000..d5ccdcf87
--- /dev/null
+++ b/doc/forum/Syncing_machines_on_different_networks/comment_6_a55982c28d7b90e0b70ec2bb5e594e08._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="annexuser"
+ ip="24.16.193.140"
+ subject="comment 6"
+ date="2012-11-05T17:20:50Z"
+ content="""
+Right now I use Dropbox with encfs. I could do the same thing with git-annex, but it's kind of a hassle.
+"""]]
diff --git a/doc/forum/Syncing_machines_on_different_networks/comment_7_c519d546e1a2a4e834609f3de3a605b0._comment b/doc/forum/Syncing_machines_on_different_networks/comment_7_c519d546e1a2a4e834609f3de3a605b0._comment
new file mode 100644
index 000000000..ea4aeeaf2
--- /dev/null
+++ b/doc/forum/Syncing_machines_on_different_networks/comment_7_c519d546e1a2a4e834609f3de3a605b0._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnZEanlyzay_QlEAL0CWpyZcRTyN7vay8U"
+ nickname="Carlo"
+ subject="Quick Cloud Tip"
+ date="2012-11-21T13:16:54Z"
+ content="""
+If you have broadband, get a raspberry pi and hook up a thumb drive. Then allow ssh access through your router for really cheap cloud storage.
+"""]]
diff --git a/doc/forum/Syncing_machines_on_different_networks/comment_8_84a822238ddbaf211cce5f527c3559d3._comment b/doc/forum/Syncing_machines_on_different_networks/comment_8_84a822238ddbaf211cce5f527c3559d3._comment
new file mode 100644
index 000000000..78c3190db
--- /dev/null
+++ b/doc/forum/Syncing_machines_on_different_networks/comment_8_84a822238ddbaf211cce5f527c3559d3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="spwhitton"
+ ip="163.1.167.50"
+ subject="s3ql"
+ date="2012-11-29T17:58:35Z"
+ content="""
+I am achieving success on this issue using afuse to automatically mount an s3ql volume. Though of course you have to manually push and pull from the git repo.
+"""]]
diff --git a/doc/forum/Syncing_with_an_encrypted_remote_from_a_different_computer__63__.mdwn b/doc/forum/Syncing_with_an_encrypted_remote_from_a_different_computer__63__.mdwn
new file mode 100644
index 000000000..9315d9218
--- /dev/null
+++ b/doc/forum/Syncing_with_an_encrypted_remote_from_a_different_computer__63__.mdwn
@@ -0,0 +1,4 @@
+I created an "full archive" repo on my local pc and an encrypted "full backup" repo on Box.com. I 'm copying files on the local repo and they are getting encrypted and uploaded to Box. Superb so far :)
+
+What I am wondering though is, suppose my local pc dies. How do I get the data out of Box unencrypted from a new pc?
+
diff --git a/doc/forum/Syncing_with_an_encrypted_remote_from_a_different_computer__63__/comment_1_cd55d06a4065b9d3f14d50674c3fcaf7._comment b/doc/forum/Syncing_with_an_encrypted_remote_from_a_different_computer__63__/comment_1_cd55d06a4065b9d3f14d50674c3fcaf7._comment
new file mode 100644
index 000000000..5a5ec3589
--- /dev/null
+++ b/doc/forum/Syncing_with_an_encrypted_remote_from_a_different_computer__63__/comment_1_cd55d06a4065b9d3f14d50674c3fcaf7._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/FHnTlSBo1eCGJRwueeKeB6.RCaPbGMPr5jxx8A--#ce0d8"
+ nickname="Hamza"
+ subject="comment 1"
+ date="2013-09-22T21:18:17Z"
+ content="""
+Just clone the repository on another computer or usb drive and enable box.com remote as long as you have the clone of the repo you can download your files back.
+"""]]
diff --git a/doc/forum/Syncing_with_an_encrypted_remote_from_a_different_computer__63__/comment_2_25cbdf478091af9923090e049c432a7d._comment b/doc/forum/Syncing_with_an_encrypted_remote_from_a_different_computer__63__/comment_2_25cbdf478091af9923090e049c432a7d._comment
new file mode 100644
index 000000000..69db183e2
--- /dev/null
+++ b/doc/forum/Syncing_with_an_encrypted_remote_from_a_different_computer__63__/comment_2_25cbdf478091af9923090e049c432a7d._comment
@@ -0,0 +1,22 @@
+[[!comment format=mdwn
+ username="John"
+ ip="109.242.130.160"
+ subject="comment 2"
+ date="2013-09-22T22:20:22Z"
+ content="""
+Thank you Hamza!
+
+I 'm new on git, so please excuse my trivial questions:
+
+a) I am using the git-annex assistant, is it something I can do from there or is it command line only?
+I googled a bit and from what I can tell, I should make a directory on the usb drive, go there and do
+> $ git clone /path/to/fullArchiveRepo
+
+Would that be correct?
+
+b) Assuming I 've done it correctly, then I put the USB on a drawer and leave it there for a month. In the meantime, I 've been using the repo on my pc and more files have been archived encrypted on Box.com. Then my local pc dies. When I plug the usb on the new pc, will I be able to recover all the encrypted files, or only those up to 1 month ago?
+
+c) What is the proper process to use the cloned repo on a new pc? Plug the usb drive, open the git-annex assistant and go through the \"create new repo\" but use the path for the existing repo on the usb? Then add another repo from Box (with the same account and the same directory there? Would that work?
+
+Thank you for your time & knowledge! :)
+"""]]
diff --git a/doc/forum/Syncing_with_an_encrypted_remote_from_a_different_computer__63__/comment_3_7e71d355457d6b1a0391d4cdae6895e6._comment b/doc/forum/Syncing_with_an_encrypted_remote_from_a_different_computer__63__/comment_3_7e71d355457d6b1a0391d4cdae6895e6._comment
new file mode 100644
index 000000000..81de3fc45
--- /dev/null
+++ b/doc/forum/Syncing_with_an_encrypted_remote_from_a_different_computer__63__/comment_3_7e71d355457d6b1a0391d4cdae6895e6._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/FHnTlSBo1eCGJRwueeKeB6.RCaPbGMPr5jxx8A--#ce0d8"
+ nickname="Hamza"
+ subject="comment 3"
+ date="2013-09-23T00:34:24Z"
+ content="""
+I do not use the assistant I prefer command line but try adding an USB drive (last I used it it had the option) It should do the clone and init it check the resulting folder if it contains a .git/ folder you have a clone of your git repo.
+
+a) For manual cloning follow http://git-annex.branchable.com/walkthrough/adding_a_remote/
+
+b) you need to keep syncing to the clone too. asistant should automatically sync to that repo. AFAIK asisstant detects when the usb repo is plugged and automatically syncs to it (again I do not use it but I seem to remember one of joey's talks showing that. YMMV)
+
+If you lose all your repos then you lose the keys to un encrypt files they are gone!, if you have a outdated repo you can get the files back using the key stored in it but without the directory structure.
+
+Correct workflow depends on how you use annex. I sync 3 computers with annex so if one dies I can clone the repo from another one. But if you are only using it on a single computer I would use a clone on an external usb drive that is always connected, so you have two clones one on the internal disk and one on the external disk so you can survive one of the drives crashing.
+"""]]
diff --git a/doc/forum/Syncing_with_an_encrypted_remote_from_a_different_computer__63__/comment_4_a73f67f2fcf0762fbd7c8366b3844af6._comment b/doc/forum/Syncing_with_an_encrypted_remote_from_a_different_computer__63__/comment_4_a73f67f2fcf0762fbd7c8366b3844af6._comment
new file mode 100644
index 000000000..7e649f858
--- /dev/null
+++ b/doc/forum/Syncing_with_an_encrypted_remote_from_a_different_computer__63__/comment_4_a73f67f2fcf0762fbd7c8366b3844af6._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.220"
+ subject="comment 4"
+ date="2013-09-23T20:18:38Z"
+ content="""
+Other good options to supplement an offline backup drive:
+
+* A clone of the repository on another computer of yours, or on an Adroid tablet or phone.
+* An encrypted git repository stored on a remote ssh server. (Supported by recent git-annex releases, although the assistant does not yet have a UI to set this up it's not very hard to do it manually at the command line and then the assistant will use it.)
+"""]]
diff --git a/doc/forum/Syncronisation_of_syncronisation_between_3_repositories__63__.mdwn b/doc/forum/Syncronisation_of_syncronisation_between_3_repositories__63__.mdwn
new file mode 100644
index 000000000..988ec3029
--- /dev/null
+++ b/doc/forum/Syncronisation_of_syncronisation_between_3_repositories__63__.mdwn
@@ -0,0 +1,11 @@
+Hello Joey,
+
+I just want to know if file transfers between three inter-connected repositories somehow gets syncronized. I have a laptop, a local file server in my home and a virtual server on the internet.
+
+Both my laptop and my file server are configured with a full git repository and connected through pairing and xmpp. The server on the internet is configured as a rsync special remote.
+
+I want the local file server to hold a copy of everything in my annex, the rsync remote should get everything except the folder "media" (too large to upload and not that important) and the laptop whatever I manually decide (preferred content is set to "present").
+
+I have added some files to the repository on the local file server and transferred their content to my laptop by using "git annex get". But when I started the web interface, I saw that those files who are present on both the file server and on the laptop get uploaded to the remote server from both computers, often the same file at the same time. Previously I though the two assistants would somehow talk to each other via xmpp so that doubled effort like that would be avoided. I'm also worried about data consistency because two apparently separate processes rsync to the same remote repository at the same time.
+
+So my question would be: Is your xmpp protocol designed to deal with situations like this and I did not set it up correctly or is what I'm trying to accomplish simply not (yet) possible?
diff --git a/doc/forum/Syncronisation_of_syncronisation_between_3_repositories__63__/comment_1_ca5192a26950627a1c2efcb55d6d2fa3._comment b/doc/forum/Syncronisation_of_syncronisation_between_3_repositories__63__/comment_1_ca5192a26950627a1c2efcb55d6d2fa3._comment
new file mode 100644
index 000000000..dccd1d8d5
--- /dev/null
+++ b/doc/forum/Syncronisation_of_syncronisation_between_3_repositories__63__/comment_1_ca5192a26950627a1c2efcb55d6d2fa3._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.238"
+ subject="comment 1"
+ date="2013-01-14T16:22:33Z"
+ content="""
+git-annex does not currently prevent multiple uploads of the same file to a rsync special remote. It is able to guard against this when uploading to a git remote, since then the remote runs git-annex-shell, which can detect when an upload is already running. You might want to convert your rsync remote to a git remote.
+
+I hope that rsyncing the same file twice at the same time is safe, but it's certainly excessively expensive.
+"""]]
diff --git a/doc/forum/The_ability_to_leave_a_file_unlocked_for_a_bit_while_committing_it_repeatedly__63__.mdwn b/doc/forum/The_ability_to_leave_a_file_unlocked_for_a_bit_while_committing_it_repeatedly__63__.mdwn
new file mode 100644
index 000000000..627e3b736
--- /dev/null
+++ b/doc/forum/The_ability_to_leave_a_file_unlocked_for_a_bit_while_committing_it_repeatedly__63__.mdwn
@@ -0,0 +1,3 @@
+Sometimes I'm doing something crazy like working in a large GIMP file, and I just want to be able to keep "committing" the changes to the annex but I hate running into the problem of having to keep unlocking the file over and over again while saving. I guess one solution to this might be to use git-annex assistant? But I'm not sure I really want a daemon running, and I don't want this auto-added... I just want to be able to leave the file unlocked while I'm actively working on it, then eventually say "I'm done with this!" and set it back to a state where it's locked.
+
+Basically, I hate running into "permission denied" errors all the time when I'm saving! I guess I could do some sort of command where I commit to the annex and then immediately unlock again... is there a better way?
diff --git a/doc/forum/The_ability_to_leave_a_file_unlocked_for_a_bit_while_committing_it_repeatedly__63__/comment_1_3cbe520b184d323219cb402ff046c3b4._comment b/doc/forum/The_ability_to_leave_a_file_unlocked_for_a_bit_while_committing_it_repeatedly__63__/comment_1_3cbe520b184d323219cb402ff046c3b4._comment
new file mode 100644
index 000000000..fac362892
--- /dev/null
+++ b/doc/forum/The_ability_to_leave_a_file_unlocked_for_a_bit_while_committing_it_repeatedly__63__/comment_1_3cbe520b184d323219cb402ff046c3b4._comment
@@ -0,0 +1,29 @@
+[[!comment format=mdwn
+ username="http://identi.ca/cwebber/"
+ nickname="cwebber"
+ subject="Reasonable solution?"
+ date="2012-11-27T21:24:49Z"
+ content="""
+I think I have built a reasonable solution... this function checks a specific file into git and then immediately unlocks it.
+
+ function git-annex-unlocked-commit {
+ if [ $# -ne 2 ]; then
+ echo \"Wrong number of args.\"
+ return 1
+ fi
+
+ if [ ! -e \"$1\" ]; then
+ echo \"Need a filename!\"
+ return 1
+ fi
+
+ read -p \"Really do an unlocked commit? (y/n): \"
+ if [ \"$REPLY\" == \"y\" ]; then
+ git commit $1 -m \"$2\" && git annex unlock $1
+ fi
+ }
+
+Use it like:
+
+ git-annex-unlocked-commit mediagoblin_postcard.xcf \"Starting to fill in spencer\"
+"""]]
diff --git a/doc/forum/The_ability_to_leave_a_file_unlocked_for_a_bit_while_committing_it_repeatedly__63__/comment_2_6afe7f593e955db2eefe87d9fa01882b._comment b/doc/forum/The_ability_to_leave_a_file_unlocked_for_a_bit_while_committing_it_repeatedly__63__/comment_2_6afe7f593e955db2eefe87d9fa01882b._comment
new file mode 100644
index 000000000..c515372b1
--- /dev/null
+++ b/doc/forum/The_ability_to_leave_a_file_unlocked_for_a_bit_while_committing_it_repeatedly__63__/comment_2_6afe7f593e955db2eefe87d9fa01882b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.49"
+ subject="comment 2"
+ date="2012-11-27T21:27:33Z"
+ content="""
+The only thing I would do differently is \"git annex add\" the file before \"git commit\". This is more efficient for large files since it avoids git looking at the whole file content.
+"""]]
diff --git a/doc/forum/The_ability_to_leave_a_file_unlocked_for_a_bit_while_committing_it_repeatedly__63__/comment_3_209399487fc4f76b29f03ad82dbc2d6f._comment b/doc/forum/The_ability_to_leave_a_file_unlocked_for_a_bit_while_committing_it_repeatedly__63__/comment_3_209399487fc4f76b29f03ad82dbc2d6f._comment
new file mode 100644
index 000000000..c59c7fe6f
--- /dev/null
+++ b/doc/forum/The_ability_to_leave_a_file_unlocked_for_a_bit_while_committing_it_repeatedly__63__/comment_3_209399487fc4f76b29f03ad82dbc2d6f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://identi.ca/cwebber/"
+ nickname="cwebber"
+ subject="comment 3"
+ date="2012-11-27T21:30:11Z"
+ content="""
+Just in case, since I don't see licensing stuff on this wiki: copyright to that code waived under CC0. :) http://creativecommons.org/publicdomain/zero/1.0/
+"""]]
diff --git a/doc/forum/The_ability_to_leave_a_file_unlocked_for_a_bit_while_committing_it_repeatedly__63__/comment_4_f33fd6f72cb9ad7dd20a04c82199413b._comment b/doc/forum/The_ability_to_leave_a_file_unlocked_for_a_bit_while_committing_it_repeatedly__63__/comment_4_f33fd6f72cb9ad7dd20a04c82199413b._comment
new file mode 100644
index 000000000..ba6baad91
--- /dev/null
+++ b/doc/forum/The_ability_to_leave_a_file_unlocked_for_a_bit_while_committing_it_repeatedly__63__/comment_4_f33fd6f72cb9ad7dd20a04c82199413b._comment
@@ -0,0 +1,26 @@
+[[!comment format=mdwn
+ username="http://identi.ca/cwebber/"
+ nickname="cwebber"
+ subject="comment 4"
+ date="2012-11-27T23:58:10Z"
+ content="""
+Ah, thanks Joey... here's an updated version:
+
+ function git-annex-unlocked-commit {
+ if [ $# -ne 2 ]; then
+ echo \"Wrong number of args.\"
+ return 1
+ fi
+
+ if [ ! -e \"$1\" ]; then
+ echo \"Need a filename!\"
+ return 1
+ fi
+
+ read -p \"Really do an unlocked commit? (y/n): \"
+ if [ \"$REPLY\" == \"y\" ]; then
+ git add $1 && git commit $1 -m \"$2\" && git annex unlock $1
+ fi
+ }
+
+"""]]
diff --git a/doc/forum/Transfer_remotes.mdwn b/doc/forum/Transfer_remotes.mdwn
new file mode 100644
index 000000000..eb03f3166
--- /dev/null
+++ b/doc/forum/Transfer_remotes.mdwn
@@ -0,0 +1,3 @@
+Hi!
+
+I have a laptop A on which I setup a box.com special remote as a transfer encrypted repository. It is quite unclear to me how I should configure laptop B to use the same box.com remote and share files between the two machines.
diff --git a/doc/forum/Transfer_remotes/comment_1_c08cf3bda00d7f20a3ca3d0fdba19c9c._comment b/doc/forum/Transfer_remotes/comment_1_c08cf3bda00d7f20a3ca3d0fdba19c9c._comment
new file mode 100644
index 000000000..7b5de17a0
--- /dev/null
+++ b/doc/forum/Transfer_remotes/comment_1_c08cf3bda00d7f20a3ca3d0fdba19c9c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawniayrgSdVLUc3c6bf93VbO-_HT4hzxmyo"
+ nickname="Tobias"
+ subject="Screencast"
+ date="2013-04-11T09:59:24Z"
+ content="""
+Maybe this screencasts helps: [git-annex assistant remote sharing](http://git-annex.branchable.com/videos/git-annex_assistant_remote_sharing/)
+"""]]
diff --git a/doc/forum/Transfer_remotes/comment_2_98930629d398329f1161135464a966a5._comment b/doc/forum/Transfer_remotes/comment_2_98930629d398329f1161135464a966a5._comment
new file mode 100644
index 000000000..1ce26e5b2
--- /dev/null
+++ b/doc/forum/Transfer_remotes/comment_2_98930629d398329f1161135464a966a5._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://cyprio.net/"
+ nickname="oz"
+ subject="versions?"
+ date="2013-04-15T22:50:31Z"
+ content="""
+Well, in the screencast it seems to work alright.
+
+I only get a \"Syncing with laptop B\" on one side, nothing more happens. I'm not sure if there is a recommended version to follow this screencast, or if the versions need to match (I'm syncing between macos & linux/debian, and the mac packages are lagging behind).
+
+My guess is that the assistant is simply \"not there yet\": using git-annex manually works just fine, but the assistant... ew. :/
+"""]]
diff --git a/doc/forum/Trouble_installing_from_cabal_on_debian-testing.mdwn b/doc/forum/Trouble_installing_from_cabal_on_debian-testing.mdwn
new file mode 100644
index 000000000..28c3a1749
--- /dev/null
+++ b/doc/forum/Trouble_installing_from_cabal_on_debian-testing.mdwn
@@ -0,0 +1,15 @@
+I'm having trouble install from cabal on Debian-testing since the new beta released.
+
+ % sudo aptitude remove --purge cabal-install
+ % rm -rf $HOME/.cabal
+ % sudo aptitude install cabal-install
+ % cabal update
+ % cabal install git-annex
+
+The output all follows this general syntax:
+
+ <package> depends on <anotherpackage> which failed to install
+
+On the flip side, I upgrade my Debian to sid and it installed just fine through aptitude.
+
+(Apologies for my English, and if this is simply a user error)
diff --git a/doc/forum/Trouble_installing_from_cabal_on_debian-testing/comment_1_0d3e9d7cffafc34bc212557e8bbb987d._comment b/doc/forum/Trouble_installing_from_cabal_on_debian-testing/comment_1_0d3e9d7cffafc34bc212557e8bbb987d._comment
new file mode 100644
index 000000000..d312ba7b1
--- /dev/null
+++ b/doc/forum/Trouble_installing_from_cabal_on_debian-testing/comment_1_0d3e9d7cffafc34bc212557e8bbb987d._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.14.141"
+ subject="comment 1"
+ date="2012-09-25T16:13:08Z"
+ content="""
+The difficulty with using cabal on Debian testing (and unstable) is that Debian has an older version of Yesod, and I have not managed to get cabal to work with both versions at once.
+
+If you build using the Makefile, it currently uses the old version of Yesod, so that'll work.
+
+The [package from unstable](http://packages.debian.org/sid/git-annex) should install ok on testing.
+"""]]
diff --git a/doc/forum/Truly_purging_dead_repositories.mdwn b/doc/forum/Truly_purging_dead_repositories.mdwn
new file mode 100644
index 000000000..8a231439c
--- /dev/null
+++ b/doc/forum/Truly_purging_dead_repositories.mdwn
@@ -0,0 +1 @@
+Since I'm just starting out with git-annex, I've had several false starts in getting things setup nicely between three machines. In the course of so doing, I've ended up with several repositories which no longer exist, and which I've marked dead. However, this is making the "git annex status" report a bit ugly, since these repositories no longer exist and can never exist again. Is there a way to truly purge dead repositories from my annex? I'd be fine with a command that must be ran in tandem on all annexes before doing a sync...
diff --git a/doc/forum/Truly_purging_dead_repositories/comment_1_a4c75d49714b3543a9f1617a15d4a2d1._comment b/doc/forum/Truly_purging_dead_repositories/comment_1_a4c75d49714b3543a9f1617a15d4a2d1._comment
new file mode 100644
index 000000000..6b778ed56
--- /dev/null
+++ b/doc/forum/Truly_purging_dead_repositories/comment_1_a4c75d49714b3543a9f1617a15d4a2d1._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.23"
+ subject="comment 1"
+ date="2012-10-18T02:20:25Z"
+ content="""
+If you really want to, check out the git-annex branch and delete the line from uuid.log, and do this on every repo in tandem. But it seems a lot of bother for something that is entirely hidden except for this one place.
+"""]]
diff --git a/doc/forum/Truly_purging_dead_repositories/comment_2_3da60a02e7323a204c5c5dd02ba04d6c._comment b/doc/forum/Truly_purging_dead_repositories/comment_2_3da60a02e7323a204c5c5dd02ba04d6c._comment
new file mode 100644
index 000000000..8a89eee96
--- /dev/null
+++ b/doc/forum/Truly_purging_dead_repositories/comment_2_3da60a02e7323a204c5c5dd02ba04d6c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.23"
+ subject="comment 2"
+ date="2012-10-18T02:23:54Z"
+ content="""
+Another possibilty is to reuse the dead uuids for later repos. You can do this by just setting annex.uuid in .git/config before you run `git annex init`, and then run `git annex fsck`.
+"""]]
diff --git a/doc/forum/Truly_purging_dead_repositories/comment_3_2576e45436008ff5a7ae5a38cade658e._comment b/doc/forum/Truly_purging_dead_repositories/comment_3_2576e45436008ff5a7ae5a38cade658e._comment
new file mode 100644
index 000000000..2b78ab0e0
--- /dev/null
+++ b/doc/forum/Truly_purging_dead_repositories/comment_3_2576e45436008ff5a7ae5a38cade658e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/2grhJvAC049fJnvALDXek.6MRZMTlg--#eec89"
+ nickname="John"
+ subject="Another idea"
+ date="2012-10-18T05:38:07Z"
+ content="""
+What if git annex status didnn't show dead repository unless I specified \"git annex status --dead\"? If you're OK with that, I'll try adding it.
+"""]]
diff --git a/doc/forum/Truly_purging_dead_repositories/comment_4_477e3c213c5a5d4a33afd42a5b94c718._comment b/doc/forum/Truly_purging_dead_repositories/comment_4_477e3c213c5a5d4a33afd42a5b94c718._comment
new file mode 100644
index 000000000..3f39803b2
--- /dev/null
+++ b/doc/forum/Truly_purging_dead_repositories/comment_4_477e3c213c5a5d4a33afd42a5b94c718._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4830:1600:187::2"
+ subject="comment 4"
+ date="2013-09-04T06:44:42Z"
+ content="""
+Status no longer shows dead repositories.
+
+See also, answer here: <http://git-annex.branchable.com/forum/How_to_delete_a_remote__63__/#comment-7ebf3804709a5aa64f1ca057a7df74f9>
+"""]]
diff --git a/doc/forum/Two_computer_setup:___34__transfer__34___or___34__full_backup__34___repository_groups__63__.mdwn b/doc/forum/Two_computer_setup:___34__transfer__34___or___34__full_backup__34___repository_groups__63__.mdwn
new file mode 100644
index 000000000..5495e2649
--- /dev/null
+++ b/doc/forum/Two_computer_setup:___34__transfer__34___or___34__full_backup__34___repository_groups__63__.mdwn
@@ -0,0 +1,18 @@
+Hi,
+
+Here is my setup:
+
+* I have a locally networked server Server-A with a large storage hard drive auto-mounted.
+* I have two personal client computers: Client-A and Client-B.
+* Client-A is my primary (desktop) computer.
+* Client-B is my secondary (laptop) computer that I use less often.
+* Git-annex is installed on all 3 computers and I use git-annex assistant on both Client-A and Client-B.
+* Both Client-A and Client-B need to share the same repository/files.
+
+
+What is the best or recommended git-annex assistant repository configuration for this setup? Ideally I want Server-A to have a full backup of the shared repository. I currently have a client repository for both Client-A and Client-B. Also, both Client-A and Client-B have a "full backup" repository pointing to the same repository hosted on Server-A. Is this OK? Should only one of the the client's have this repository as a "full backup"? Will this current setup also have git annex assistant auto-sync the repositories between the clients? I have both clients setup right now and they have both successfully cloned the shared repository, but I have noticed that they have yet to sync up modifications made on the other client. An alternative setup I can think of would be to have Client-A keep its current configuration and have Client-B switch the "full backup" repository to be just a "transfer" repository.
+
+I hope my intentions are clear. Please give me your recommendations.
+
+Regards,
+Blake
diff --git a/doc/forum/Two_computer_setup:___34__transfer__34___or___34__full_backup__34___repository_groups__63__/comment_1_b8702892280447193e6e80be22a580a0._comment b/doc/forum/Two_computer_setup:___34__transfer__34___or___34__full_backup__34___repository_groups__63__/comment_1_b8702892280447193e6e80be22a580a0._comment
new file mode 100644
index 000000000..915e7209b
--- /dev/null
+++ b/doc/forum/Two_computer_setup:___34__transfer__34___or___34__full_backup__34___repository_groups__63__/comment_1_b8702892280447193e6e80be22a580a0._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlkA6XinbeOdnEDxEGQUWyjqPGh0kdMXr4"
+ nickname="Blake"
+ subject="update"
+ date="2013-10-30T07:19:56Z"
+ content="""
+It seems both Client-A and Client-B ARE actually syncing with this current setup. I think Client-B was just delayed due to the initial startup scan. So I guess at this point I am more or less asking if having both Client-A and Client-B have the remote repository being a \"full backup\" type is appropriate or if there is a better configuration that achieves what I am hoping to have.
+
+Regards,
+Blake
+"""]]
diff --git a/doc/forum/Two_computer_setup:___34__transfer__34___or___34__full_backup__34___repository_groups__63__/comment_2_50cafde7e30b928480d1f142ddd763d2._comment b/doc/forum/Two_computer_setup:___34__transfer__34___or___34__full_backup__34___repository_groups__63__/comment_2_50cafde7e30b928480d1f142ddd763d2._comment
new file mode 100644
index 000000000..4495401b2
--- /dev/null
+++ b/doc/forum/Two_computer_setup:___34__transfer__34___or___34__full_backup__34___repository_groups__63__/comment_2_50cafde7e30b928480d1f142ddd763d2._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 2"
+ date="2013-11-01T16:47:18Z"
+ content="""
+git-annex keeps track of the repository group on a per repository basis. That is, if the repository on Server-A is a full backup, both Client-A and Client-B will consider it to be one, and use it appropriately. You can't have just Client-A think it's a full backup; this setting will be automatically synced to Client-B.
+
+Your setup sounds ok, although you might need to set up a XMPP account in order for Client-A and Client-B to immediately message one-another when they have new changes to sync. Otherwise, they might only poll Server-A occasionally for changes.
+"""]]
diff --git a/doc/forum/USB_backup_with_files_visible.mdwn b/doc/forum/USB_backup_with_files_visible.mdwn
new file mode 100644
index 000000000..747de85ff
--- /dev/null
+++ b/doc/forum/USB_backup_with_files_visible.mdwn
@@ -0,0 +1,7 @@
+Quick question: I want to create a repository on my removable USB drive that will acquire all files (eg. "full backup" repository group), but where the files will be visible and usable if you load the drive on another computer.
+
+How do I do that from within the assistant?
+
+Thanks,
+
+Zellyn
diff --git a/doc/forum/USB_backup_with_files_visible/comment_1_2832f8ae24dfb0f101e06f7c18283028._comment b/doc/forum/USB_backup_with_files_visible/comment_1_2832f8ae24dfb0f101e06f7c18283028._comment
new file mode 100644
index 000000000..c08a0c692
--- /dev/null
+++ b/doc/forum/USB_backup_with_files_visible/comment_1_2832f8ae24dfb0f101e06f7c18283028._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.193"
+ subject="comment 1"
+ date="2013-07-02T17:00:41Z"
+ content="""
+This is not something the assistant really handles yet. The issue is that if you have a non-bare repository on the USB drive, something has to run `git annex sync` in it when changes are pushed to it, to update it to display the files that are in the repository.
+
+One way to do this is to set up a non-bare repository by hand and add a git post-receive hook that runs `git annex sync`
+"""]]
diff --git a/doc/forum/USB_backup_with_files_visible/comment_2_6163e01aa441f8435091f026cc6da337._comment b/doc/forum/USB_backup_with_files_visible/comment_2_6163e01aa441f8435091f026cc6da337._comment
new file mode 100644
index 000000000..591dc847d
--- /dev/null
+++ b/doc/forum/USB_backup_with_files_visible/comment_2_6163e01aa441f8435091f026cc6da337._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkQafKy7hNSEolLs6TvbgUnkklTctUY9LI"
+ nickname="Zellyn"
+ subject="comment 2"
+ date="2013-07-02T17:10:59Z"
+ content="""
+Aah, perfect. I did in fact set up a non-bare git annex on the drive. I was just lacking the `git annex sync` command. Thanks!
+"""]]
diff --git a/doc/forum/USB_backup_with_files_visible/comment_3_ee92ff320eb5d9a031bdd1896aee0d86._comment b/doc/forum/USB_backup_with_files_visible/comment_3_ee92ff320eb5d9a031bdd1896aee0d86._comment
new file mode 100644
index 000000000..98a3c1cc5
--- /dev/null
+++ b/doc/forum/USB_backup_with_files_visible/comment_3_ee92ff320eb5d9a031bdd1896aee0d86._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawln3ckqKx0x_xDZMYwa9Q1bn4I06oWjkog"
+ nickname="Michael"
+ subject="post-receive hook looks troublesome"
+ date="2013-07-03T16:11:13Z"
+ content="""
+I just tried setting up a post-receive hook with just \"git annex sync\" in it.
+The end result is that files (git annex symlinks, really) are getting removed somehow as a result after a couple of git annex sync's done manually.
+It would be nice if this actually worked.
+
+"""]]
diff --git a/doc/forum/USB_backup_with_files_visible/comment_4_437c8342c0b65e3a89129800313eb73c._comment b/doc/forum/USB_backup_with_files_visible/comment_4_437c8342c0b65e3a89129800313eb73c._comment
new file mode 100644
index 000000000..a45b05b25
--- /dev/null
+++ b/doc/forum/USB_backup_with_files_visible/comment_4_437c8342c0b65e3a89129800313eb73c._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.193"
+ subject="comment 4"
+ date="2013-07-03T19:54:21Z"
+ content="""
+Seems to me that any such problems would be caused by the environment variables git sets in the hook, or possibly the current working directory in use when the hook runs. So it might take some finessing to get right.
+
+Meanwhile, I've committed a change that makes `git annex merge` merge in changes synced to the repo from other repositories. So that can be used the same way `git annex sync` can, but without the added overhead of committing, pushing, and pulling.
+"""]]
diff --git a/doc/forum/USB_backup_with_files_visible/comment_5_5e10cffe8465ea4ecaa71c03a4c29ea4._comment b/doc/forum/USB_backup_with_files_visible/comment_5_5e10cffe8465ea4ecaa71c03a4c29ea4._comment
new file mode 100644
index 000000000..20853a4a0
--- /dev/null
+++ b/doc/forum/USB_backup_with_files_visible/comment_5_5e10cffe8465ea4ecaa71c03a4c29ea4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="99.54.57.201"
+ subject="comment 5"
+ date="2013-07-04T05:11:46Z"
+ content="""
+Oh! git annex merge is very nice.
+"""]]
diff --git a/doc/forum/USB_backup_with_files_visible/comment_6_add048a16837f7940a859f21426cdbe9._comment b/doc/forum/USB_backup_with_files_visible/comment_6_add048a16837f7940a859f21426cdbe9._comment
new file mode 100644
index 000000000..95f749574
--- /dev/null
+++ b/doc/forum/USB_backup_with_files_visible/comment_6_add048a16837f7940a859f21426cdbe9._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmNu4V5fvpLlBhaCUfXXOB0MI5NXwh8SkU"
+ nickname="Adam"
+ subject="Confused"
+ date="2013-11-03T00:13:47Z"
+ content="""
+Sorry, I'm confused. I set up a Full Backup repo on a second hard drive, but the files are visible in its directory just like in my Client repos' directories. Are the files not supposed to be visible? Is something wrong?
+"""]]
diff --git a/doc/forum/USB_backup_with_files_visible/comment_7_de227ca9911fe57d7a6d3e037f574fe9._comment b/doc/forum/USB_backup_with_files_visible/comment_7_de227ca9911fe57d7a6d3e037f574fe9._comment
new file mode 100644
index 000000000..0f74efac0
--- /dev/null
+++ b/doc/forum/USB_backup_with_files_visible/comment_7_de227ca9911fe57d7a6d3e037f574fe9._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 7"
+ date="2013-11-03T01:09:16Z"
+ content="""
+You can set it up that way, but the often confusing behavior (including not being able to umount a drive that has the git-annex assistant deamon running in it!) is why the webapp attempt to steer users toward making bare reposotories on USB drives.
+
+If you click on \"Add another repository\" -> \"Removable drive\", you get a bare repository.
+
+If you click on upper-right menu -> \"Add another local repository\" and enter a path, and tell it to combine the repositories, you get a synced non-bare repository, and potentially problems unmounting the drive since you now have 2 assistant daemons running.
+
+I have now added a further link to the nice removable drive path to that second UI path.
+"""]]
diff --git a/doc/forum/USB_backup_with_files_visible/comment_8_0c0ed0e038f7f0e2d2d4ed69b7b29fbc._comment b/doc/forum/USB_backup_with_files_visible/comment_8_0c0ed0e038f7f0e2d2d4ed69b7b29fbc._comment
new file mode 100644
index 000000000..6511343e8
--- /dev/null
+++ b/doc/forum/USB_backup_with_files_visible/comment_8_0c0ed0e038f7f0e2d2d4ed69b7b29fbc._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmNu4V5fvpLlBhaCUfXXOB0MI5NXwh8SkU"
+ nickname="Adam"
+ subject="comment 8"
+ date="2013-11-03T01:13:26Z"
+ content="""
+Thanks for the explanation, Joey. I just posted a [comment](http://git-annex.branchable.com/bugs/Unnecessary_remote_transfers/#comment-f7110e694a9951d8ab546b8dec568bfa) about this on the bug report too. Maybe the problem is simply that the Removable Drive option doesn't allow using internal, non-removable drives.
+
+BTW, I don't know if this is relevant, but I only see one \"git-annex assistant\" process running.
+"""]]
diff --git a/doc/forum/USB_drive_in_transfer_group_keeps_growing_-_assistant.txt b/doc/forum/USB_drive_in_transfer_group_keeps_growing_-_assistant.txt
new file mode 100644
index 000000000..6b1c03d9a
--- /dev/null
+++ b/doc/forum/USB_drive_in_transfer_group_keeps_growing_-_assistant.txt
@@ -0,0 +1,22 @@
+1. Set up two computers with a client repository.
+2. Add a removable drive repository and set it to transfer group.
+3. Start adding files to computer #1 repository. See how the files get synced to the usb drive.
+4. Connect the usb drive to computer #2 and see the files getting transferred to computer #2. Everything is looking good.
+
+
+5. Connect the usb drive to computer #1 again.
+6. Add a file that is larger than the remaining size of the usb drive, BUT smaller than the original size of the usb drive.
+7. The file does not get transferred to the usb drive due to lack of disk space.
+
+I would expect the assistant to make some space on the usb drive. Removing the files it knows has been transferred to computer #2, and then transfer the new file to the usb drive. But this does not seem to happen.
+
+Have I missed something about how the transfer group is supposed to work?
+
+
+Using version:
+git-annex version: 4.20130802-g0a52f02
+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP
+
+Pre built tar file.
+
+
diff --git a/doc/forum/USB_drive_in_transfer_group_keeps_growing_-_assistant/comment_1_0a6f6054d70009979f4a036e24b7c500._comment b/doc/forum/USB_drive_in_transfer_group_keeps_growing_-_assistant/comment_1_0a6f6054d70009979f4a036e24b7c500._comment
new file mode 100644
index 000000000..f298b56cd
--- /dev/null
+++ b/doc/forum/USB_drive_in_transfer_group_keeps_growing_-_assistant/comment_1_0a6f6054d70009979f4a036e24b7c500._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 1"
+ date="2013-08-24T19:22:05Z"
+ content="""
+The assistant is supposed to remove files from transfer repositories once the file has been transferred to all known clients. This generally seems to work, with all the transfer repositories I've tested it with. Nothing is special about USB drives compared with other transfer repositories.
+
+Perhaps you have not configured the USB drive as a transfer repository? Or perhaps you have another client repository (even a client repository you had once but have now deleted).
+"""]]
diff --git a/doc/forum/Ubuntu_PPA.mdwn b/doc/forum/Ubuntu_PPA.mdwn
new file mode 100644
index 000000000..b97cc1aec
--- /dev/null
+++ b/doc/forum/Ubuntu_PPA.mdwn
@@ -0,0 +1,3 @@
+Is there a PPA that Ubuntu people are using to track the latest git-annex?
+
+The [Ubuntu install page](http://git-annex.branchable.com/install/Ubuntu/) mentions [https://launchpad.net/~rubiojr/+archive/git-annex](https://launchpad.net/~rubiojr/+archive/git-annex) which hasn't been updated for a while.
diff --git a/doc/forum/Ubuntu_PPA/comment_1_b55535258b1b4bcfc802235f0cba075d._comment b/doc/forum/Ubuntu_PPA/comment_1_b55535258b1b4bcfc802235f0cba075d._comment
new file mode 100644
index 000000000..d91a0d1eb
--- /dev/null
+++ b/doc/forum/Ubuntu_PPA/comment_1_b55535258b1b4bcfc802235f0cba075d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmeki7KlfJpAAN9CUmi9EdwhwBmIhDMYuE"
+ nickname="Marvin"
+ subject="comment 1"
+ date="2013-03-11T09:40:43Z"
+ content="""
+im also looking for a PPA with newer git-annex versions. mostly because of the glacier support...
+"""]]
diff --git a/doc/forum/Ubuntu_PPA/comment_2_adc4d644fed058d1811acf0b35db9c18._comment b/doc/forum/Ubuntu_PPA/comment_2_adc4d644fed058d1811acf0b35db9c18._comment
new file mode 100644
index 000000000..bc91500c7
--- /dev/null
+++ b/doc/forum/Ubuntu_PPA/comment_2_adc4d644fed058d1811acf0b35db9c18._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmVICFY2CDP08xdsPr3cgmScomy9HA-1sk"
+ nickname="Andrew"
+ subject="comment 2"
+ date="2013-03-13T02:31:52Z"
+ content="""
+It's perfectly possible (though slightly messy) to install git-annex on Ubuntu via [[/install/cabal]], though you need to find and install all the required dependencies yourself (haskell, libidn, libgnutls, libgsasl etc). If you want to get crazy with this look at <http://developer.ubuntu.com/packaging/html/>
+"""]]
diff --git a/doc/forum/Ubuntu_PPA/comment_3_fc9cd51558c47718f243437202a11803._comment b/doc/forum/Ubuntu_PPA/comment_3_fc9cd51558c47718f243437202a11803._comment
new file mode 100644
index 000000000..4c77308d0
--- /dev/null
+++ b/doc/forum/Ubuntu_PPA/comment_3_fc9cd51558c47718f243437202a11803._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="fmarier"
+ ip="121.98.93.240"
+ subject="My PPA (Ubuntu Precise) has git-annex 4.20130417"
+ date="2013-04-27T11:12:26Z"
+ content="""
+I just went through the pain of backporting 90+ Haskell packages from Debian unstable: https://launchpad.net/~fmarier/+archive/ppa
+"""]]
diff --git a/doc/forum/Ubuntu_PPA/comment_4_3a8bbd0a7450a7f5323cd13144824aea._comment b/doc/forum/Ubuntu_PPA/comment_4_3a8bbd0a7450a7f5323cd13144824aea._comment
new file mode 100644
index 000000000..335cc57ba
--- /dev/null
+++ b/doc/forum/Ubuntu_PPA/comment_4_3a8bbd0a7450a7f5323cd13144824aea._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://grossmeier.net/"
+ nickname="greg"
+ subject="All PPAs are outdated"
+ date="2013-05-08T17:38:04Z"
+ content="""
+My work preinstalled Ubuntu machine is now on Raring, and even there the version of git-annex is only 3.20121112ubuntu3; too old to have the webapp option enabled :/ The two PPAs mentioned here aren't configured to build for Raring, so even though the one from François has a build from May 1st (7 days ago), it doesn't help me ;)
+
+François: mind updating your PPA to support Raring? Thanks much if you do!
+
+Either that, or I'll take the time some day to do a proper install on this machine (read: Debian). ;-)
+"""]]
diff --git a/doc/forum/Ubuntu_PPA/comment_5_2e1beaeebda0201c635db8b276cedf20._comment b/doc/forum/Ubuntu_PPA/comment_5_2e1beaeebda0201c635db8b276cedf20._comment
new file mode 100644
index 000000000..0d94ba6f2
--- /dev/null
+++ b/doc/forum/Ubuntu_PPA/comment_5_2e1beaeebda0201c635db8b276cedf20._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="comment 5"
+ date="2013-05-08T23:25:37Z"
+ content="""
+If you are on raring you can still use
+
+ deb http://ppa.launchpad.net/fmarier/ppa/ubuntu precise main
+
+It's worked fine for me so far.
+"""]]
diff --git a/doc/forum/Ubuntu_PPA/comment_6_bd99fb70399fc58d98781a89c6d38428._comment b/doc/forum/Ubuntu_PPA/comment_6_bd99fb70399fc58d98781a89c6d38428._comment
new file mode 100644
index 000000000..8252fe5d9
--- /dev/null
+++ b/doc/forum/Ubuntu_PPA/comment_6_bd99fb70399fc58d98781a89c6d38428._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkx5V3MTbzCXS3J7Mn9FEq8M9bPPYMkAHY"
+ nickname="Pedro"
+ subject="comment 6"
+ date="2013-05-20T15:52:40Z"
+ content="""
+Be careful that the fmarier ppa includes more than just git-annex.
+"""]]
diff --git a/doc/forum/Ubuntu_PPA/comment_7_c3f7ec8573934c59d70a48e36e321c13._comment b/doc/forum/Ubuntu_PPA/comment_7_c3f7ec8573934c59d70a48e36e321c13._comment
new file mode 100644
index 000000000..849381ec2
--- /dev/null
+++ b/doc/forum/Ubuntu_PPA/comment_7_c3f7ec8573934c59d70a48e36e321c13._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://openid.fmarier.org/"
+ nickname="fmarier"
+ subject="New location for my git-annex PPA"
+ date="2013-06-15T07:42:13Z"
+ content="""
+My Ubuntu Precise PPA has moved here: https://launchpad.net/~fmarier/+archive/git-annex
+
+It contains version 20130601 of git-annex.
+
+As Pedro suggested, it's now in a separate PPA with only git-annex and the 220 Haskell packages it depends on.
+"""]]
diff --git a/doc/forum/Un-git-annex__63__.mdwn b/doc/forum/Un-git-annex__63__.mdwn
new file mode 100644
index 000000000..68e8068fc
--- /dev/null
+++ b/doc/forum/Un-git-annex__63__.mdwn
@@ -0,0 +1,6 @@
+Hi,
+
+I am using git-annex assistant on my Fedora Linux computer. Everything seems to be working perfectly, however I have noticed that almost all of my files are now symbolic links to cryptic file names located in the .git/ directory. Oddly though it seems files inside git-annex assistant does not move/symbolic link files within git repositories inside my git-annex assist directories. My question is: how can I safely uninstall git-annex from my machine and restore all files to their non-symbolic link states? When I click on the settings drop-down for a repository inside git-annex assistant and choose disable it goes to the same page as the delete option. Any ideas?
+
+Regards,
+Blake
diff --git a/doc/forum/Un-git-annex__63__/comment_1_6059265afb66190d325083e0f28bcf33._comment b/doc/forum/Un-git-annex__63__/comment_1_6059265afb66190d325083e0f28bcf33._comment
new file mode 100644
index 000000000..907293f99
--- /dev/null
+++ b/doc/forum/Un-git-annex__63__/comment_1_6059265afb66190d325083e0f28bcf33._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="99.54.57.201"
+ subject="comment 1"
+ date="2013-10-06T06:45:14Z"
+ content="""
+\"git annex uninit\" is the command which will revert an entire git annex repository back to a bunch of ordinary files, untracked by git annex (or git). I'm not sure whether there is a way to issue that command from the assistant though.
+
+
+"""]]
diff --git a/doc/forum/Un-git-annex__63__/comment_2_fac4bfb81dbbf0dc82059aace261eb51._comment b/doc/forum/Un-git-annex__63__/comment_2_fac4bfb81dbbf0dc82059aace261eb51._comment
new file mode 100644
index 000000000..2b1a7381a
--- /dev/null
+++ b/doc/forum/Un-git-annex__63__/comment_2_fac4bfb81dbbf0dc82059aace261eb51._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlOc-EOD5ZyggsAp6lOnU7x5MxizwLtUXA"
+ nickname="Hendrik"
+ subject="comment 2"
+ date="2013-10-06T18:35:14Z"
+ content="""
+I had uninit'd my annex several time for testing git-annex. What I discovered was that is worked reliably but for all files that are duplicates. For duplicates only 1 of the files got restored properly. All that was 1 year ago - so your results my differ. I had found a piece of script in the forum / tips sections that will show all duplicates.
+
+Hope this helps...
+"""]]
diff --git a/doc/forum/Undo_Git_Annex_Changes_To_Linked_Files.mdwn b/doc/forum/Undo_Git_Annex_Changes_To_Linked_Files.mdwn
new file mode 100644
index 000000000..c299041f0
--- /dev/null
+++ b/doc/forum/Undo_Git_Annex_Changes_To_Linked_Files.mdwn
@@ -0,0 +1,7 @@
+Hello,
+
+I was recently evaluating git-annex as a file sync tool, but I've got my files in a state where they are a mess. The short version is that I have a local repo, and then an Encrypted S3 remote. Once I encrypted the files, they got renamed and so forth and the files are now just symbolic links to files within the .git directory somewhere. This has made some of them unusable for me and I need to revert the files back to not being symlinks any longer. How would I go about doing that?
+
+Thanks,
+
+Brandon
diff --git a/doc/forum/Undo_Git_Annex_Changes_To_Linked_Files/comment_1_568dde820c2608d86d05b07444146a26._comment b/doc/forum/Undo_Git_Annex_Changes_To_Linked_Files/comment_1_568dde820c2608d86d05b07444146a26._comment
new file mode 100644
index 000000000..21cf45522
--- /dev/null
+++ b/doc/forum/Undo_Git_Annex_Changes_To_Linked_Files/comment_1_568dde820c2608d86d05b07444146a26._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.110"
+ subject="comment 1"
+ date="2013-07-28T00:09:45Z"
+ content="""
+Run:
+
+`git annex get $file`
+`git annex unannex $file`
+
+$file will now be back how it was before you used git-annex. Can also run above on whole directories.
+"""]]
diff --git a/doc/forum/Undo_Git_Annex_Changes_To_Linked_Files/comment_2_a8cf71cdf1217d9c8596cd9006eb83f5._comment b/doc/forum/Undo_Git_Annex_Changes_To_Linked_Files/comment_2_a8cf71cdf1217d9c8596cd9006eb83f5._comment
new file mode 100644
index 000000000..2e9c387ad
--- /dev/null
+++ b/doc/forum/Undo_Git_Annex_Changes_To_Linked_Files/comment_2_a8cf71cdf1217d9c8596cd9006eb83f5._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmRFsVANDSwNHzCWk-iP2_nXnfYKPJWziE"
+ nickname="Brandon"
+ subject="comment 2"
+ date="2013-07-28T03:26:23Z"
+ content="""
+Thanks, much appreciated. Got all of my files back successfully.
+"""]]
diff --git a/doc/forum/Unknown_remote_type_S3.mdwn b/doc/forum/Unknown_remote_type_S3.mdwn
new file mode 100644
index 000000000..ae8432286
--- /dev/null
+++ b/doc/forum/Unknown_remote_type_S3.mdwn
@@ -0,0 +1,5 @@
+I have an annex set up with an s3 special remote. It works fine on one computer. I cloned the annex to a USB stick, plugged the stick into a second computer and cloned the annex to that machine. When I try to `git annex initremote cloud` on the second machine, I get the following error:
+
+ git-annex: Unknown remote type S3
+
+The second machine is running git-annex 3.20121017.
diff --git a/doc/forum/Unknown_remote_type_S3/comment_1_2aea2cd51286c809427d16519606cd37._comment b/doc/forum/Unknown_remote_type_S3/comment_1_2aea2cd51286c809427d16519606cd37._comment
new file mode 100644
index 000000000..80e1b11aa
--- /dev/null
+++ b/doc/forum/Unknown_remote_type_S3/comment_1_2aea2cd51286c809427d16519606cd37._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.27"
+ subject="comment 1"
+ date="2012-11-07T18:57:17Z"
+ content="""
+It's possible to build git-annex without S3 support. I think a few Linux distros ship it this way due to not having all the necessary haskell libraries.
+"""]]
diff --git a/doc/forum/Unknown_remote_type_S3/comment_2_06f775062cd30767979fe56bcb3cf7bf._comment b/doc/forum/Unknown_remote_type_S3/comment_2_06f775062cd30767979fe56bcb3cf7bf._comment
new file mode 100644
index 000000000..75864aedc
--- /dev/null
+++ b/doc/forum/Unknown_remote_type_S3/comment_2_06f775062cd30767979fe56bcb3cf7bf._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="annexuser"
+ ip="24.16.193.140"
+ subject="comment 2"
+ date="2012-11-07T20:12:27Z"
+ content="""
+That was the issue. Thank you!
+"""]]
diff --git a/doc/forum/Unlock_files_when_assistant_is_running__63__.mdwn b/doc/forum/Unlock_files_when_assistant_is_running__63__.mdwn
new file mode 100644
index 000000000..0c514368a
--- /dev/null
+++ b/doc/forum/Unlock_files_when_assistant_is_running__63__.mdwn
@@ -0,0 +1,13 @@
+I just started using the assistant on an existing annex. I fire up the assistant like so:
+
+ $ git annex webapp
+
+Everything syncs and looks to be working fine. In another terminal, I then create a new file:
+
+ $ touch testfile.txt
+
+The assistant sees that file, immediately adds it and syncs. Ok. So now I want to edit that file.
+
+ $ git annex unlock testfile.txt
+
+As soon as I unlock the file, the assistant re-adds it to the annex and syncs, preventing me from editing the file. How can I edit files with the assistant running?
diff --git a/doc/forum/Unlock_files_when_assistant_is_running__63__/comment_1_3f4aadf0c856c81e15c6f5ae7f1992b4._comment b/doc/forum/Unlock_files_when_assistant_is_running__63__/comment_1_3f4aadf0c856c81e15c6f5ae7f1992b4._comment
new file mode 100644
index 000000000..f17fc5634
--- /dev/null
+++ b/doc/forum/Unlock_files_when_assistant_is_running__63__/comment_1_3f4aadf0c856c81e15c6f5ae7f1992b4._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.27"
+ subject="comment 1"
+ date="2012-11-11T16:06:42Z"
+ content="""
+I suspect you have an old build of the assistant. Version 3.20121009 was supposed to fix this.
+
+I re-tested with current git head today, and found I was able to unlock a file, repeatedly edit it in place without the assistant re-adding it, and then run \"git annex add\" and the assistant auto-committed the changed file. Better behavior than I was expecting in fact -- the ability to repeatedly edit is a pleasant surprise.
+"""]]
diff --git a/doc/forum/Unlock_files_when_assistant_is_running__63__/comment_2_a76797ee9e05e43af7947508cadd7bed._comment b/doc/forum/Unlock_files_when_assistant_is_running__63__/comment_2_a76797ee9e05e43af7947508cadd7bed._comment
new file mode 100644
index 000000000..556720523
--- /dev/null
+++ b/doc/forum/Unlock_files_when_assistant_is_running__63__/comment_2_a76797ee9e05e43af7947508cadd7bed._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="annexuser"
+ ip="24.16.193.140"
+ subject="comment 2"
+ date="2012-11-12T20:09:20Z"
+ content="""
+ $ git annex version
+ git-annex version: 3.20121017
+"""]]
diff --git a/doc/forum/Use_case_with_syncing_only_a_subset_possible__63__.mdwn b/doc/forum/Use_case_with_syncing_only_a_subset_possible__63__.mdwn
new file mode 100644
index 000000000..0d102b0d4
--- /dev/null
+++ b/doc/forum/Use_case_with_syncing_only_a_subset_possible__63__.mdwn
@@ -0,0 +1,13 @@
+I'm trying to figure out if git-annex can be used for the following use case:
+
+- 2 repos in direct mode A and B
+- A is on a local filesystem, B could be a NFS mountpoint or ssh
+- B contains a number of toplevel directories, A contains a subset of those
+- For the subset in A all changes in those directories that happen on A or B should be synced automatically between both repos, including file removals.
+- A can decide to not carry a toplevel dir any more, but it must still exist in B.
+- A can copy new toplevel dirs from B and those should be synced from then on.
+
+I've been looking at the docs and played with two test repos, but I cannot seem to make the above work. To me it looks like I would need a possibility include/exclude paths from syncing via a regex.
+
+Thanks,
+Felix
diff --git a/doc/forum/Use_case_with_syncing_only_a_subset_possible__63__/comment_1_a0a272a0931b27e5c94b93e42656b62c._comment b/doc/forum/Use_case_with_syncing_only_a_subset_possible__63__/comment_1_a0a272a0931b27e5c94b93e42656b62c._comment
new file mode 100644
index 000000000..3e930b542
--- /dev/null
+++ b/doc/forum/Use_case_with_syncing_only_a_subset_possible__63__/comment_1_a0a272a0931b27e5c94b93e42656b62c._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.51"
+ subject="comment 1"
+ date="2013-09-12T20:39:51Z"
+ content="""
+I guess you might be using the git-annex assistant. If you were just using git-annex at the command line, you could simply only run `git annex get` on the files or directories you wanted to get.
+
+You can control which directories the git-annex assistant downloads/uploads files for using [[preferred_content]] expressions. Or the easy solution is to use the webapp to put the repository into \"manual mode\" and then manually run `git annex get` as described above to get just the files you want. (And `git annex copy --to remote` to share new files you make.)
+"""]]
diff --git a/doc/forum/Use_local_files_instead_of_re-downloading_from_S3_remote.mdwn b/doc/forum/Use_local_files_instead_of_re-downloading_from_S3_remote.mdwn
new file mode 100644
index 000000000..67e7971d2
--- /dev/null
+++ b/doc/forum/Use_local_files_instead_of_re-downloading_from_S3_remote.mdwn
@@ -0,0 +1,3 @@
+I have a question on setting up a new repo. Is it possible to initialize a new repo using files which are already local on say my laptop, instead of downloading them from a S3 remote repository? Sorry if this is unclear. But I'm trying to make use of the files that are local on my laptop so I don's have to go through the ordeal of downloading them from S3.
+
+I should also mention that I don't have a complete set of all the files locally on the laptop vs. what's already in the S3 repository.
diff --git a/doc/forum/Use_local_files_instead_of_re-downloading_from_S3_remote/comment_1_cfb6021a36eee087705967a69967f327._comment b/doc/forum/Use_local_files_instead_of_re-downloading_from_S3_remote/comment_1_cfb6021a36eee087705967a69967f327._comment
new file mode 100644
index 000000000..0d1f74e83
--- /dev/null
+++ b/doc/forum/Use_local_files_instead_of_re-downloading_from_S3_remote/comment_1_cfb6021a36eee087705967a69967f327._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn7gQ1zZDdWhXy9H51W2krZYShNmKL3qfM"
+ nickname="Karsten"
+ subject="comment 1"
+ date="2013-05-27T18:13:43Z"
+ content="""
+Hi,
+
+just copy the local File into the annex again, replacing the symlinks. If you have the assistant running, it should re-add the files automatically, otherwise you can 'git annex add' them manually.
+"""]]
diff --git a/doc/forum/Use_local_files_instead_of_re-downloading_from_S3_remote/comment_2_7268b194ba72331858bc3274996b780e._comment b/doc/forum/Use_local_files_instead_of_re-downloading_from_S3_remote/comment_2_7268b194ba72331858bc3274996b780e._comment
new file mode 100644
index 000000000..b066c85db
--- /dev/null
+++ b/doc/forum/Use_local_files_instead_of_re-downloading_from_S3_remote/comment_2_7268b194ba72331858bc3274996b780e._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-05-27T18:47:17Z"
+ content="""
+You can also use `git annex reinject` to feed in contents of specific files, without needing to directly touch the files in the repository.
+
+Or, you can check all the local files into a temporary directory. Either the assistant or a manual `git annex add` will
+notice if these files have the same content as files already in the repository. The files will then be available in two locations, the temp directory and wherever it was checked into your repository before. You can then delete the temp directory.
+"""]]
diff --git a/doc/forum/Use_reflinks_on_BTRFS_instead_of_symlinks___63__.mdwn b/doc/forum/Use_reflinks_on_BTRFS_instead_of_symlinks___63__.mdwn
new file mode 100644
index 000000000..d33fda600
--- /dev/null
+++ b/doc/forum/Use_reflinks_on_BTRFS_instead_of_symlinks___63__.mdwn
@@ -0,0 +1 @@
+On BTRFS it is possible to use [reflinks / clones](https://en.wikipedia.org/wiki/Btrfs#Cloning). This is the equivalent of hardlinks except that when the file is modified, a copy is performed (copy on write). Perhaps git-annex could detect the availability of this feature and use it in case it is available (and the repository and the file are in the same filesystem).
diff --git a/doc/forum/Use_reflinks_on_BTRFS_instead_of_symlinks___63__/comment_1_85806316ed28d7a891f04fab4027141b._comment b/doc/forum/Use_reflinks_on_BTRFS_instead_of_symlinks___63__/comment_1_85806316ed28d7a891f04fab4027141b._comment
new file mode 100644
index 000000000..b175204e5
--- /dev/null
+++ b/doc/forum/Use_reflinks_on_BTRFS_instead_of_symlinks___63__/comment_1_85806316ed28d7a891f04fab4027141b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://thkoch2001.myopenid.com/"
+ nickname="thkoch"
+ subject="It would also be nice, if git-annex would use btrfs reflinks on unlock"
+ date="2013-08-24T12:46:40Z"
+ content="""
+I don't know whether git-annex already does use btrfs reflinks, but I suspect, that I double the size of my git-annex repo folder on disk when I unlink all files.
+"""]]
diff --git a/doc/forum/Use_reflinks_on_BTRFS_instead_of_symlinks___63__/comment_2_ecb411a2c4d67917b734a90bd460d44b._comment b/doc/forum/Use_reflinks_on_BTRFS_instead_of_symlinks___63__/comment_2_ecb411a2c4d67917b734a90bd460d44b._comment
new file mode 100644
index 000000000..a4ade5792
--- /dev/null
+++ b/doc/forum/Use_reflinks_on_BTRFS_instead_of_symlinks___63__/comment_2_ecb411a2c4d67917b734a90bd460d44b._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 2"
+ date="2013-08-24T15:54:02Z"
+ content="""
+git-annex has always used cp --reflink=auto, including when it cp's the file in `git annex unlock`.
+
+You can verify this with --debug.
+"""]]
diff --git a/doc/forum/Using_Git-Annex___40__Assistant__41___to_manage_photos_with_Shotwell.mdwn b/doc/forum/Using_Git-Annex___40__Assistant__41___to_manage_photos_with_Shotwell.mdwn
new file mode 100644
index 000000000..d3e2cef00
--- /dev/null
+++ b/doc/forum/Using_Git-Annex___40__Assistant__41___to_manage_photos_with_Shotwell.mdwn
@@ -0,0 +1,13 @@
+Hello,
+
+I'm very excited about Git Annex and Git Annex Assistant.
+
+One big issue that I have is that I currently have all of my photos (70-80GB) on a HTPC because it has a large hard drive. I have a decent laptop/screen set-up where I would prefer to manage the photos, but the hard drive in there is a small SSD.
+
+I use Shotwell to manage my photos (currently on the HTPC). I would be happy to keep things simple and only access them on the laptop. I have 100GB of box.com storage (and another 100GB of Mega.co.nz storage, but I don't think that is supported by GAA yet).
+
+Ideally, what I would like is for a cache of, say, 10GB of my recently-accessed photos to live on my laptop, with the remaining 70GB living on both my HTPC and box.com. If I ever needed the underlying files for non-cached files (say if I was trying to view full-quality versions of them or send them to someone), it could try to pull these from my HTPC over the local network or, if I was "on the road", box.com. As I understand it, Shotwell has its own database and a set of thumbnails etc that you can use to manage and browse your photos while very rarely accessing the underlying photos.
+
+Is this possible with the existing GAA/Shotwell, or does one or the other require changes? Could I solve the problem by using something like the sharebox Git-Annex FUSE filesystem, so that Shotwell thinks that the files are local, but runs away and grabs them if they are remote?
+
+I would appreciate any thoughts that anyone has - particularly if anyone has made this work.
diff --git a/doc/forum/Using_Git-Annex___40__Assistant__41___to_manage_photos_with_Shotwell/comment_1_5e8d54daf6b7ff357619ac65fe39a2d7._comment b/doc/forum/Using_Git-Annex___40__Assistant__41___to_manage_photos_with_Shotwell/comment_1_5e8d54daf6b7ff357619ac65fe39a2d7._comment
new file mode 100644
index 000000000..7ec8ac2fc
--- /dev/null
+++ b/doc/forum/Using_Git-Annex___40__Assistant__41___to_manage_photos_with_Shotwell/comment_1_5e8d54daf6b7ff357619ac65fe39a2d7._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-05-27T19:09:50Z"
+ content="""
+Mega can be used via [[/tips/megaannex]]. I don't have personal experience with it, but if you set up a repository manually using that, the assistant can use that repository just as it uses any other repository.
+
+git-annex at the command line is great for small local repositories that pull files from various larger remotes as needed. You just run \"git annex get\" when you want a file and \"git annex drop\" when you want to free disk space. You can also use this mode with the assistant, by configuring the local repository to be in \"manual mode\".
+
+By default though, the way the assistant handles this kind of use case is with `archive` directories. It tries to move any files in an archive directory away from your local disk, and it tries to get any files not in an archive directory to be locally available. So you can just move files around between directories to control where they are stored. See [[assistant/archival_walkthrough]] for details an an example video.
+"""]]
diff --git a/doc/forum/Using_Linux_static_builds.mdwn b/doc/forum/Using_Linux_static_builds.mdwn
new file mode 100644
index 000000000..ee856f72c
--- /dev/null
+++ b/doc/forum/Using_Linux_static_builds.mdwn
@@ -0,0 +1,25 @@
+Hello,
+
+I want to use git-annex on a couple of machines that are not under my control (and one that is). For that I use the provided static build, but encountered several problems:
+
+I suppose the first step for command line use is to execute runshell:
+
+On one machine:
+
+flindner@yoko:~> software/git-annex.linux/runshell
+/bin/bash: /lib64/libc.so.6: version `GLIBC_2.11' not found (required by /home/flindner/software/git-annex.linux//lib/x86_64-linux-gnu/libreadline.so.6)
+
+Is there anything I can do about it?
+
+On the other machine:
+
+flindner@bladefoam2:~$ software/git-annex.linux/runshell
+bash-4.1$
+
+It starts a bare, non-configured shell instance. Can I modifiy and source the script to only set the environment and not start up a new shell?
+
+Another question: If using ssh:// remotes, how can I tell git-annex the first command to set up the environment need in order to execute command via SSH?
+
+Thanks,
+
+Florian
diff --git a/doc/forum/Using_Linux_static_builds/comment_1_22fd266cbe68af3e754a10f1f1295e9b._comment b/doc/forum/Using_Linux_static_builds/comment_1_22fd266cbe68af3e754a10f1f1295e9b._comment
new file mode 100644
index 000000000..b40ae7695
--- /dev/null
+++ b/doc/forum/Using_Linux_static_builds/comment_1_22fd266cbe68af3e754a10f1f1295e9b._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.149"
+ subject="comment 1"
+ date="2012-10-09T15:10:45Z"
+ content="""
+Yes, it seems glibc 2.11 is the oldest version you can get away with. At least until we get a build machine with some truely ancient libc, but modern versions of everything else. Statically linking libc, or including it in the tarball are unfortunatly not technically possible.
+
+You don't need to use runshell if you just want to use the assistant. Which is what this static build is really targeted for. If you want to use all of git-annex, you're probably better off installing it properly.
+It is possible to use \"runshell git annex\" to run a single command inside the shell. Or even make shell script wrappers that do that.. but it seems more difficult than installing git-annex normally.
+
+The static build can be used with ssh. The git-annex assistant should set things up properly. If you want to do it by hand, when it does is configure the ssh key to run ~/.ssh/git-annex-shell, and that file is then made a shell script that runs `runshell git-annex-shell -c \"$SSH_ORIGINAL_COMMAND\"`
+"""]]
diff --git a/doc/forum/Using_Linux_static_builds/comment_2_36f69f30117ff8696425a754ab19a08b._comment b/doc/forum/Using_Linux_static_builds/comment_2_36f69f30117ff8696425a754ab19a08b._comment
new file mode 100644
index 000000000..4f43034a3
--- /dev/null
+++ b/doc/forum/Using_Linux_static_builds/comment_2_36f69f30117ff8696425a754ab19a08b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnsuhFUIfWNT-Q-C02FDaSQqceFDge5M9w"
+ nickname="Florian"
+ subject="comment 2"
+ date="2012-10-10T10:48:04Z"
+ content="""
+Installing it properly seems to be quite a bit of effort, given the long list of Haskell dependencies. Most of the machines I plan to use it on are not under my control and seem to be somewhat outdated. What way of installing it properly would you suggest?
+"""]]
diff --git a/doc/forum/Using_Linux_static_builds/comment_3_64506833dad0202626239e00d1eb6490._comment b/doc/forum/Using_Linux_static_builds/comment_3_64506833dad0202626239e00d1eb6490._comment
new file mode 100644
index 000000000..af301bd7e
--- /dev/null
+++ b/doc/forum/Using_Linux_static_builds/comment_3_64506833dad0202626239e00d1eb6490._comment
@@ -0,0 +1,23 @@
+[[!comment format=mdwn
+ username="http://colberg.org/"
+ ip="2001:470:1d:4d4:2d4b:7654:2c00:b95c"
+ subject="comment 3"
+ date="2012-11-12T05:05:39Z"
+ content="""
+Hi Florian,
+
+I maintain a makefile for GNU/Linux systems that builds git-annex from scratch using a single command.
+
+ git clone http://git.colberg.org/packages.git
+
+ nice make -f packages.mk CONCURRENCY_LEVEL=16 PREFIX=$HOME/usr/rhel6-x64_64 install-git-annex
+
+The makefile fetches pre-compiled GHC 6.x (x86_64), which works on old systems (e.g. RHEL 5), builds a recent GHC 7.x from source, a minimal Haskell environment with cabal-install, and finally git-annex. I have succesfully compiled git-annex on RHEL 5.x and 6.x, and CentOS 6.x.
+
+If the build fails using the system's GCC, there is also a newer GCC in the same makefile:
+
+ nice make -f packages.mk CONCURRENCY_LEVEL=16 PREFIX=$HOME/usr/rhel6-x64_64 install-gcc
+
+Regards,
+Peter
+"""]]
diff --git a/doc/forum/Using___34__sync__34___to_sink_all_branches__63__.mdwn b/doc/forum/Using___34__sync__34___to_sink_all_branches__63__.mdwn
new file mode 100644
index 000000000..99ddcc328
--- /dev/null
+++ b/doc/forum/Using___34__sync__34___to_sink_all_branches__63__.mdwn
@@ -0,0 +1,9 @@
+Is there a way to sync all (or a subset of) local branches, not just the currently checked out branch?
+
+Does this make sense at all, or does this show I am missing some important point in git-annex?
+
+I am asking because I would like to use git-annex to keep git repositories with normal git files (with versioned and branched content) in sync.
+
+If it's not currently possible, could you provide some pointers on where to start, if I wanted to change to Haskell source?
+
+Thnx
diff --git a/doc/forum/Using___34__sync__34___to_sink_all_branches__63__/comment_1_ef3d5c5e2600ffa36dd933c8a42cdf96._comment b/doc/forum/Using___34__sync__34___to_sink_all_branches__63__/comment_1_ef3d5c5e2600ffa36dd933c8a42cdf96._comment
new file mode 100644
index 000000000..2b060197b
--- /dev/null
+++ b/doc/forum/Using___34__sync__34___to_sink_all_branches__63__/comment_1_ef3d5c5e2600ffa36dd933c8a42cdf96._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlgyVag95OnpvSzQofjyX0WjW__MOMKsl0"
+ nickname="Sehr"
+ subject="comment 1"
+ date="2012-10-29T17:04:30Z"
+ content="""
+Ok, this is what I have come up with:
+
+Merges can only be done on checked out branches. That's why the only way to do this without breaking the whole idea of git-annex (sync) is to check out each branch and run it separately.
+
+What would be the easiest way to do this? Considering possible unsaved changes in worktree and index?
+
+Maybe simply using git-clone /tmp locally, which uses hardlinks for .git/objects/ which should make it perform ok?
+
+
+"""]]
diff --git a/doc/forum/Using___34__sync__34___to_sink_all_branches__63__/comment_2_424b0c6fdfe87ca08f5d408b7684ab08._comment b/doc/forum/Using___34__sync__34___to_sink_all_branches__63__/comment_2_424b0c6fdfe87ca08f5d408b7684ab08._comment
new file mode 100644
index 000000000..1c4b9445b
--- /dev/null
+++ b/doc/forum/Using___34__sync__34___to_sink_all_branches__63__/comment_2_424b0c6fdfe87ca08f5d408b7684ab08._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlgyVag95OnpvSzQofjyX0WjW__MOMKsl0"
+ nickname="Sehr"
+ subject="comment 2"
+ date="2012-10-29T18:52:59Z"
+ content="""
+It turns out, this is even easier:
+
+As the behavior of \"git-annex sync\" includes performing a \"git commit -a\", any pending changes in the work tree will be committed anyway. This means, that it is safe to simply checkout and sync any branch, one wants to sync.
+"""]]
diff --git a/doc/forum/Using___34__sync__34___to_sink_all_branches__63__/comment_3_adaf9114c69f1268330adcebd8018fa0._comment b/doc/forum/Using___34__sync__34___to_sink_all_branches__63__/comment_3_adaf9114c69f1268330adcebd8018fa0._comment
new file mode 100644
index 000000000..146785ad3
--- /dev/null
+++ b/doc/forum/Using___34__sync__34___to_sink_all_branches__63__/comment_3_adaf9114c69f1268330adcebd8018fa0._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.194"
+ subject="comment 3"
+ date="2012-11-04T20:08:02Z"
+ content="""
+Yes, that's right, `git annex sync` handles the current branch, and you can use it on different branches if desired.
+
+(It is actually possible to merge non-checked out branches, but I have not implemented that for sync.)
+"""]]
diff --git a/doc/forum/Using_a_single_backup_repo_for_multiple_independent_client_repos__63__.mdwn b/doc/forum/Using_a_single_backup_repo_for_multiple_independent_client_repos__63__.mdwn
new file mode 100644
index 000000000..985bff87c
--- /dev/null
+++ b/doc/forum/Using_a_single_backup_repo_for_multiple_independent_client_repos__63__.mdwn
@@ -0,0 +1,36 @@
+I don't know if this is an "unusual setup" or something that should be supported, but it seems like a reasonable use case to me, so here goes:
+
+I have three systems: a desktop, a laptop, and a little netbook. I have one main annex that is currently synced between the desktop and the laptop at ~/annex on both, and to a secondary, Full Backup repo on the desktop, under /mnt.
+
+I have some music on my laptop, and I like to sync ~/Music between the laptop and the netbook. So I thought I'd make a new git-annex repo at ~/Music on both and sync them. I want this to be kept separate from ~/annex.
+
+I also thought it would be good to backup the music, so I thought I'd connect laptop:~/Music to the Full Backup repo at desktop:/mnt. So I paired the repo at laptop:~/Music to the repo at desktop:/mnt.
+
+So I had set up these repos:
+
+* desktop:
+ * /mnt (Full Backup)
+ * ~/annex (Client)
+* laptop:
+ * ~/annex (Client)
+ * ~/Music (Client)
+* netbook:
+ * ~/Music (Client)
+
+As I feared--but I wasn't sure, since I'm new to git-annex--since the desktop:/mnt repo was connected to laptop:~/Music, and desktop:~/mnt was also connected to desktop:~/annex, this caused everything in laptop:~/Music to be synced to desktop:~/annex, because they were part of the same "set" of repos; they were all in the same .git/config files.
+
+So now I have a few problems:
+
+1. How do I get all these music files out of my ~/annex repos? I tried removing the remote repos from ~/annex/.git/config and then running 'git-annex unused', but that didn't result in it thinking all the music files were unused. Do I have to delete them all manually? (There are a *lot* of directories from ~/Music now in ~/annex).
+
+2. It seems that desktop:~/annex/.git is...now over 600 MB, even though few of the actual music files have synced over. Is it possible to clean out ~/annex/.git and restore it to the pre-mess state without starting from scratch?
+
+3. Is it possible--or reasonable--to use a single Full Backup repo for multiple independent client repos? That is, is it possible to do that without the independent client repos "cross-pollinating"? Or do I need to use separate Full Backup repos for each "set" of client repos?
+
+4. I'm not sure if this is a separate problem, but I just want to make sure I understand the best way to handle things like this. I wanted to disconnect desktop:~/annex from laptop:~/Music, but I thought that if I used the webapp to "Delete" the laptop:~/Music repo, it would actually start deleting the music files in laptop:~/Music, after moving them to desktop:~/annex. Am I correct that that would have happened? If so, "Deleting" a repo seems like a dangerous operation that should warn and prompt the user. Maybe an "unlink repo" option needs to be available to simply disconnect two repos and leave their respective contents intact.
+
+I apologize if these are newbie problems. Despite reading every dev blog entry--both before and after the switchover--I'm still new to actually using git-annex. I'm not sure if it's supposed to work this way or if I'm using it wrong.
+
+If I am using it wrong...well, I can imagine other git-annex newbies doing similar things and ending up with similar messes, so maybe this needs to...be considered or something. :) Since I'm still experimenting with git-annex, I haven't put any "live" data in it, so I can blow away all the annexes and start over, but I would like to learn how to properly fix a situation like this in case I goof up in the future.
+
+Thanks for your help.
diff --git a/doc/forum/Using_a_single_backup_repo_for_multiple_independent_client_repos__63__/comment_1_c61c28600f1079fb03ddabc950307f27._comment b/doc/forum/Using_a_single_backup_repo_for_multiple_independent_client_repos__63__/comment_1_c61c28600f1079fb03ddabc950307f27._comment
new file mode 100644
index 000000000..b7119aa2d
--- /dev/null
+++ b/doc/forum/Using_a_single_backup_repo_for_multiple_independent_client_repos__63__/comment_1_c61c28600f1079fb03ddabc950307f27._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 1"
+ date="2013-11-05T16:14:34Z"
+ content="""
+1. Turn off the assistant, switch to indirect mode (`git annex indirect`), use `git log --stat` to find the commit(s) that added the music files, and `git revert` the commits, in reverse chronological order. Or delete the files manually.
+2. You have merged two git repositories. Without some serious git repository surgery (ie, resetting to an old version and deleting the reflog), the full history of both is going to remain stored in git going forward. However, a simple `git gc` might pack that down to a much smaller amount of disk space.
+3. Combining two repositories merges their git histories. You then have two clones of one repository containing the full contents and git history of both. Don't do that if that's not what you want. The webapp is always careful to tell you when an action will combine two repositories.
+4. Once you have combined two repositories, you have two synced repositories that contain the same data. Deleting one of them will just delete one copy of the data. It won't result in data loss, but neither will it untangle the two git trees that were previously combined.
+"""]]
diff --git a/doc/forum/Using_for_Music_repo.mdwn b/doc/forum/Using_for_Music_repo.mdwn
new file mode 100644
index 000000000..25f1365fb
--- /dev/null
+++ b/doc/forum/Using_for_Music_repo.mdwn
@@ -0,0 +1,13 @@
+Hi,
+
+I am looking into using git-annex to sync my Music between 3 sources: desktop, laptop, backup, but I'm not sure if this will work ok.
+
+I notice on the wiki that: "Normally, the content of files in the annex is prevented from being modified. That's a good thing, because it might be the only copy, you wouldn't want to lose it in a fumblefingered mistake."
+
+But most music players will download artwork, and some of course will dynamically modify/rename files according to meta data. And I may be downloading and/or playing music on both the desktop and laptop. So obviously I wouldn't want to be manually unlocking individual files here. It would kinda interrupt the music listening experience. So how would this work?
+
+I am assuming that I would always have to do a git annex add *.mp3 *.flac *.jpg before doing a git annex sync. But can I just keep everything unlocked? Any side effects here? Will this work or should I just use rsync?
+
+Regards,
+
+bk
diff --git a/doc/forum/Using_for_Music_repo/comment_1_3488ed85ad98f14cb17f229225ece26e._comment b/doc/forum/Using_for_Music_repo/comment_1_3488ed85ad98f14cb17f229225ece26e._comment
new file mode 100644
index 000000000..6176f755d
--- /dev/null
+++ b/doc/forum/Using_for_Music_repo/comment_1_3488ed85ad98f14cb17f229225ece26e._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-04-18T20:01:50Z"
+ content="""
+You can use [[direct_mode]] to keep all files unlocked all the time.
+
+You can use the [[assistant]] to automatically commit whatever changes are made to the directory, as well as automatically sync them to your other computers.
+"""]]
diff --git a/doc/forum/Using_for_Music_repo/comment_2_c794648878cfc77558f8db862271f997._comment b/doc/forum/Using_for_Music_repo/comment_2_c794648878cfc77558f8db862271f997._comment
new file mode 100644
index 000000000..9ce874307
--- /dev/null
+++ b/doc/forum/Using_for_Music_repo/comment_2_c794648878cfc77558f8db862271f997._comment
@@ -0,0 +1,25 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmgXUaPZHcAY8Wv4sTnX88CbJfYdYdKO-Y"
+ nickname="Boyd"
+ subject="comment 2"
+ date="2013-04-18T23:33:10Z"
+ content="""
+Thanks Joey! Anyway I see that with Fedora, I don't have the 'assistant'. I don't even seem to have the 'direct mode'. Also tried to do a cabal install git-annex, but ran into dependency hell. Oh well, this is goin on the back burner for a while. Looks very promising though!
+
+Boyd
+
+[root@zbox Music]# git annex direct
+git-annex: Unknown command 'direct'
+
+Did you mean one of these?
+ reinject
+
+[root@zbox Music]# git annex version
+git-annex version: 3.20120615
+local repository version: 3
+default repository version: 3
+supported repository versions: 3
+upgrade supported from repository versions: 0 1 2
+[root@zbox Music]#
+
+"""]]
diff --git a/doc/forum/Using_for_Music_repo/comment_3_8c5e820f5ff7d717d64b1fd66927941b._comment b/doc/forum/Using_for_Music_repo/comment_3_8c5e820f5ff7d717d64b1fd66927941b._comment
new file mode 100644
index 000000000..842a83052
--- /dev/null
+++ b/doc/forum/Using_for_Music_repo/comment_3_8c5e820f5ff7d717d64b1fd66927941b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-04-19T18:05:49Z"
+ content="""
+Fedora has an old version of git-annex. You can use the [[install/Linux_standalone]] tarball.
+"""]]
diff --git a/doc/forum/Using_git-annex_as_a_library.mdwn b/doc/forum/Using_git-annex_as_a_library.mdwn
new file mode 100644
index 000000000..3727679dd
--- /dev/null
+++ b/doc/forum/Using_git-annex_as_a_library.mdwn
@@ -0,0 +1 @@
+I am looking to use git-annex as a library/tool to bring syncing to another application. Is there any documentation or open examples of doing something like this?
diff --git a/doc/forum/Using_git-annex_as_a_library/comment_1_1f8e74c5856f21c53d5a91892cbef0c6._comment b/doc/forum/Using_git-annex_as_a_library/comment_1_1f8e74c5856f21c53d5a91892cbef0c6._comment
new file mode 100644
index 000000000..6ba664aea
--- /dev/null
+++ b/doc/forum/Using_git-annex_as_a_library/comment_1_1f8e74c5856f21c53d5a91892cbef0c6._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlaQ9Hd5o_wjCIcfC9MAx8GRli5-LyBang"
+ nickname="George"
+ subject="comment 1"
+ date="2013-06-29T16:07:45Z"
+ content="""
+I should say specifically interfacing with git-annex
+"""]]
diff --git a/doc/forum/Using_git-annex_as_a_library/comment_2_11a243fa7d8ac947aa9a798228dbd191._comment b/doc/forum/Using_git-annex_as_a_library/comment_2_11a243fa7d8ac947aa9a798228dbd191._comment
new file mode 100644
index 000000000..4177d7d20
--- /dev/null
+++ b/doc/forum/Using_git-annex_as_a_library/comment_2_11a243fa7d8ac947aa9a798228dbd191._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.193"
+ subject="comment 2"
+ date="2013-06-30T18:08:52Z"
+ content="""
+I think there are two approaches to doing this.
+
+1. Use the git-annex command line interface from your program. You can use the --json switch to enable machine-parsable output of many git-annex commands. If something needs work to be more suitable to be used as \"plumbing\" in this way, we can improve it to meet your needs.
+
+2. Use the git-annex Haskell code as a library for your program. The git-annex assistant is a great example of how far you can take this. It has the benefit that by accessing git-annex's internals, you can sometimes do things more efficiently than by using the CLI. Much of git-annex's code is already well modularized and suitable for use as a library in this way. The build system doesn't currently spit out git-annex libraries, but it would not be hard to make it do so. Of course this would entail writing at least some of your program in Haskell.
+"""]]
diff --git a/doc/forum/Using_git-annex_via_command_line_in_OS_X.mdwn b/doc/forum/Using_git-annex_via_command_line_in_OS_X.mdwn
new file mode 100644
index 000000000..5eba701bd
--- /dev/null
+++ b/doc/forum/Using_git-annex_via_command_line_in_OS_X.mdwn
@@ -0,0 +1,3 @@
+After installing the binary for Mac OS X and including some larger directories, my computer now seems quite busy (for the last days) with the import process. I see a process called git-annex causing the load, so it seems OK. As the git-annex assistant seems to hang quite a bit, I would like to see the progress using a command line interface. However, I cannot use the "git annex" command as I get the message "git: 'annex' is not a git command. See 'git --help'."
+
+I guess this is my normal git version, installed by homebrew (the OS X version for apt-get) that does not know anything about the installed binary. Can I still use the CLI with this version? Or better, is there or will there be a way to install git-annex from source, or even better using "brew install git-annex"?
diff --git a/doc/forum/Using_git-annex_via_command_line_in_OS_X/comment_1_1c9e121f60fb6868c07f1a53b03c4ed0._comment b/doc/forum/Using_git-annex_via_command_line_in_OS_X/comment_1_1c9e121f60fb6868c07f1a53b03c4ed0._comment
new file mode 100644
index 000000000..1f51e6c97
--- /dev/null
+++ b/doc/forum/Using_git-annex_via_command_line_in_OS_X/comment_1_1c9e121f60fb6868c07f1a53b03c4ed0._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnaZYaspvzx1lQiM56UQo-X82BnPiAaiEY"
+ nickname="Martin"
+ subject="comment 1"
+ date="2013-08-19T18:07:04Z"
+ content="""
+One more question. When running the git-annex binary the webapp opens. After closing the window I cannot access the webapp anymore. Using the IP + port number (http://127.0.0.1:53027/) does not work. Would be handy to have a bookmark for the webapp that works as long as the assistant is running.
+"""]]
diff --git a/doc/forum/Using_git-annex_via_command_line_in_OS_X/comment_2_52d8ffba82e29ac2722a8e43e469cc47._comment b/doc/forum/Using_git-annex_via_command_line_in_OS_X/comment_2_52d8ffba82e29ac2722a8e43e469cc47._comment
new file mode 100644
index 000000000..b30773cd2
--- /dev/null
+++ b/doc/forum/Using_git-annex_via_command_line_in_OS_X/comment_2_52d8ffba82e29ac2722a8e43e469cc47._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnaZYaspvzx1lQiM56UQo-X82BnPiAaiEY"
+ nickname="Martin"
+ subject="git-annex via comand line"
+ date="2013-08-19T21:53:11Z"
+ content="""
+Just found the page how to install the CLI on OS X: http://git-annex.branchable.com/install/OSX/
+That solved all my questions for now.
+"""]]
diff --git a/doc/forum/Using_git_annex_with_Android_tablet_which_only_has_exFAT_and_no_symlinks.mdwn b/doc/forum/Using_git_annex_with_Android_tablet_which_only_has_exFAT_and_no_symlinks.mdwn
new file mode 100644
index 000000000..3420c129f
--- /dev/null
+++ b/doc/forum/Using_git_annex_with_Android_tablet_which_only_has_exFAT_and_no_symlinks.mdwn
@@ -0,0 +1,8 @@
+Hallo,
+
+I have got a Samsung Galaxy Note 10.1 I want to sync with a remote ssh-Server, but the tablet only supports exFAT and FAT file Systems, so I cannot use symlinks.
+
+Does any solution exist for this?
+
+Mebus
+
diff --git a/doc/forum/Using_git_annex_with_Android_tablet_which_only_has_exFAT_and_no_symlinks/comment_1_b9f202a30ba7e3bc264064d24454c099._comment b/doc/forum/Using_git_annex_with_Android_tablet_which_only_has_exFAT_and_no_symlinks/comment_1_b9f202a30ba7e3bc264064d24454c099._comment
new file mode 100644
index 000000000..f5d4b3cdd
--- /dev/null
+++ b/doc/forum/Using_git_annex_with_Android_tablet_which_only_has_exFAT_and_no_symlinks/comment_1_b9f202a30ba7e3bc264064d24454c099._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="64.134.31.139"
+ subject="comment 1"
+ date="2013-10-22T17:37:44Z"
+ content="""
+The sad state of affairs that in the supposedly modern 21st century, popular operating systems are regressing in functionality?
+
+Yes, git-annex can deal with this. `git annex init` will detect when it's run on a crippled filesystem and enable various workarounds, including [[direct_mode]].
+
+The git-annex android app deals with all this automatically when creating a repository.
+"""]]
diff --git a/doc/forum/Using_git_annex_with_Android_tablet_which_only_has_exFAT_and_no_symlinks/comment_2_1334a8d9f4bb60f3bf3ebabc656d98d9._comment b/doc/forum/Using_git_annex_with_Android_tablet_which_only_has_exFAT_and_no_symlinks/comment_2_1334a8d9f4bb60f3bf3ebabc656d98d9._comment
new file mode 100644
index 000000000..493aaf65e
--- /dev/null
+++ b/doc/forum/Using_git_annex_with_Android_tablet_which_only_has_exFAT_and_no_symlinks/comment_2_1334a8d9f4bb60f3bf3ebabc656d98d9._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="Mebus"
+ ip="2001:4dd0:ff00:29::2"
+ subject="comment 2"
+ date="2013-10-31T23:39:42Z"
+ content="""
+Hallo,
+
+I tried it again.
+
+On the Android tablet I get many files, which have got a size of 200 Bytes. And they should at least be a view kB.
+
+Why?
+
+Mebus
+
+
+"""]]
diff --git a/doc/forum/Using_git_annex_with_Android_tablet_which_only_has_exFAT_and_no_symlinks/comment_3_076f22d05fad140068a540e4d835106f._comment b/doc/forum/Using_git_annex_with_Android_tablet_which_only_has_exFAT_and_no_symlinks/comment_3_076f22d05fad140068a540e4d835106f._comment
new file mode 100644
index 000000000..0fb4f61e2
--- /dev/null
+++ b/doc/forum/Using_git_annex_with_Android_tablet_which_only_has_exFAT_and_no_symlinks/comment_3_076f22d05fad140068a540e4d835106f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 3"
+ date="2013-11-01T16:42:33Z"
+ content="""
+Files in the git repository whose content has not yet been downloaded will appear as these short placeholder files when using a filesystem that does not support symlinks. Once the files have been downloaded, that is replaced with their actual content. You may need to set up a way to your android tablet to download the files from the place they're being created.
+"""]]
diff --git a/doc/forum/Using_git_annex_with_Android_tablet_which_only_has_exFAT_and_no_symlinks/comment_4_c8446ee1b817f1824fa0df07e742015c._comment b/doc/forum/Using_git_annex_with_Android_tablet_which_only_has_exFAT_and_no_symlinks/comment_4_c8446ee1b817f1824fa0df07e742015c._comment
new file mode 100644
index 000000000..cd42b6c15
--- /dev/null
+++ b/doc/forum/Using_git_annex_with_Android_tablet_which_only_has_exFAT_and_no_symlinks/comment_4_c8446ee1b817f1824fa0df07e742015c._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="Mebus"
+ ip="2001:4dd0:ff00:29::2"
+ subject="comment 4"
+ date="2013-11-11T20:24:11Z"
+ content="""
+Does it have to be the place, where they were created or can this also be a central server, I pushed everything to?
+
+Mebus
+
+
+"""]]
diff --git a/doc/forum/Using_git_annex_with_Android_tablet_which_only_has_exFAT_and_no_symlinks/comment_5_f746c1b85ee8e4b57b6819ccceabd28b._comment b/doc/forum/Using_git_annex_with_Android_tablet_which_only_has_exFAT_and_no_symlinks/comment_5_f746c1b85ee8e4b57b6819ccceabd28b._comment
new file mode 100644
index 000000000..676e7b6f1
--- /dev/null
+++ b/doc/forum/Using_git_annex_with_Android_tablet_which_only_has_exFAT_and_no_symlinks/comment_5_f746c1b85ee8e4b57b6819ccceabd28b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.246"
+ subject="comment 5"
+ date="2013-11-13T16:37:46Z"
+ content="""
+The git-annex app will download the files from any remote you set up that has a copy of the file. A transfer remote in the cloud would work well.
+"""]]
diff --git a/doc/forum/Using_git_annex_with_a_SMB__47__FTP_TV_NAS_with_preconfigured_dirs.mdwn b/doc/forum/Using_git_annex_with_a_SMB__47__FTP_TV_NAS_with_preconfigured_dirs.mdwn
new file mode 100644
index 000000000..1e6443038
--- /dev/null
+++ b/doc/forum/Using_git_annex_with_a_SMB__47__FTP_TV_NAS_with_preconfigured_dirs.mdwn
@@ -0,0 +1,5 @@
+I've got a Freebox Revolution set-top box / TV NAS at home, with some preconfigured layou for videos, photos and music.
+
+I'd like to use it as a git-annex remote, but am afraid there's no support for FTP (authenticated) or SMB shares exported by the NAS (I don't think it supports other protocols even though runs Linux internally, AFAIK).
+
+Is there any option to store much on that NAS and sync it with git-annex ?
diff --git a/doc/forum/Using_git_annex_with_a_SMB__47__FTP_TV_NAS_with_preconfigured_dirs/comment_1_bd73c8d10028e1b45da9ea8f657e5064._comment b/doc/forum/Using_git_annex_with_a_SMB__47__FTP_TV_NAS_with_preconfigured_dirs/comment_1_bd73c8d10028e1b45da9ea8f657e5064._comment
new file mode 100644
index 000000000..d5e8d5404
--- /dev/null
+++ b/doc/forum/Using_git_annex_with_a_SMB__47__FTP_TV_NAS_with_preconfigured_dirs/comment_1_bd73c8d10028e1b45da9ea8f657e5064._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://cstork.org/"
+ nickname="Chris Stork"
+ subject="Similar to &quot;direct special remotes&quot;"
+ date="2013-08-16T17:57:26Z"
+ content="""
+You have a very similar problem as I do.
+
+See my post where I called this [direct special remotes](http://git-annex.branchable.com/forum/Direct_special_remotes/).
+"""]]
diff --git a/doc/forum/Using_git_annex_with_a_SMB__47__FTP_TV_NAS_with_preconfigured_dirs/comment_2_16c3c994ee8fcb466e52ca0e812e5915._comment b/doc/forum/Using_git_annex_with_a_SMB__47__FTP_TV_NAS_with_preconfigured_dirs/comment_2_16c3c994ee8fcb466e52ca0e812e5915._comment
new file mode 100644
index 000000000..93eef7322
--- /dev/null
+++ b/doc/forum/Using_git_annex_with_a_SMB__47__FTP_TV_NAS_with_preconfigured_dirs/comment_2_16c3c994ee8fcb466e52ca0e812e5915._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://olivier.berger.myopenid.com/"
+ nickname="obergix"
+ subject="Except I don't have rsync/sftp on the NAS AFAICT"
+ date="2013-08-17T08:56:37Z"
+ content="""
+There seemed to be some hope with rsync in your case, but not mine. Thanks anyway for the pointer.
+"""]]
diff --git a/doc/forum/Using_git_annex_with_a_SMB__47__FTP_TV_NAS_with_preconfigured_dirs/comment_3_ac60f6edb76bdd541711e472eec9591a._comment b/doc/forum/Using_git_annex_with_a_SMB__47__FTP_TV_NAS_with_preconfigured_dirs/comment_3_ac60f6edb76bdd541711e472eec9591a._comment
new file mode 100644
index 000000000..8729a8481
--- /dev/null
+++ b/doc/forum/Using_git_annex_with_a_SMB__47__FTP_TV_NAS_with_preconfigured_dirs/comment_3_ac60f6edb76bdd541711e472eec9591a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://olivier.berger.myopenid.com/"
+ nickname="obergix"
+ subject="Experimenting with a CIFS mount point of the NAS and direct mode"
+ date="2013-08-17T22:11:19Z"
+ content="""
+I've been experimenting with a direct mode repo on a CIFS mount of the SMB share of the NAS.
+
+Unfortunately, it seems I can't propagate changes made on the laptop to the mount point by issueing a git pull or merge, as it is part of the unsafe commands that don't support direct mode (see details in <http://git-annex.branchable.com/direct_mode/#comment-fca93776b9526341e6aae4fe2c53038c>)... direct mode wouldn't be very useful then : I intend to mirror on the NAS the files I've been managing locally. For instance I will sort my photos in subdirs, on the laptop, and intend to mirror that on the NAS.
+"""]]
diff --git a/doc/forum/Using_git_annex_with_a_SMB__47__FTP_TV_NAS_with_preconfigured_dirs/comment_4_2194f0600d9a90f0d9c947ea9cc213a3._comment b/doc/forum/Using_git_annex_with_a_SMB__47__FTP_TV_NAS_with_preconfigured_dirs/comment_4_2194f0600d9a90f0d9c947ea9cc213a3._comment
new file mode 100644
index 000000000..4a59acdeb
--- /dev/null
+++ b/doc/forum/Using_git_annex_with_a_SMB__47__FTP_TV_NAS_with_preconfigured_dirs/comment_4_2194f0600d9a90f0d9c947ea9cc213a3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 4"
+ date="2013-08-23T17:55:39Z"
+ content="""
+Just run `git annex sync` to update the direct mode repository on your NAS.
+"""]]
diff --git a/doc/forum/Using_git_annex_with_a_SMB__47__FTP_TV_NAS_with_preconfigured_dirs/comment_5_eb7d13f6b6fa674a2536bde51bfc3fd1._comment b/doc/forum/Using_git_annex_with_a_SMB__47__FTP_TV_NAS_with_preconfigured_dirs/comment_5_eb7d13f6b6fa674a2536bde51bfc3fd1._comment
new file mode 100644
index 000000000..e014efb86
--- /dev/null
+++ b/doc/forum/Using_git_annex_with_a_SMB__47__FTP_TV_NAS_with_preconfigured_dirs/comment_5_eb7d13f6b6fa674a2536bde51bfc3fd1._comment
@@ -0,0 +1,48 @@
+[[!comment format=mdwn
+ username="http://olivier.berger.myopenid.com/"
+ nickname="obergix"
+ subject="So it seems I have found a sequence that seems to be operating fine"
+ date="2013-08-23T20:28:45Z"
+ content="""
+Here's a script, which I think makes it work, using git clone, git annex copy and git annex sync :
+ # The \"master\" remote which is with default indirect mode, on a Linux FS
+ BASE1=~/tmp
+ REPO1=$BASE1/annex-test
+
+ # The \"slave\" remote on the NAS (a Samba server), which has been mounted with cifs, and thus will be in direct mode
+ BASE2=/mnt/freebox-server/
+ REPO2=$BASE2/annex-test
+
+ cd $BASE1
+ mkdir $REPO1
+ cd $REPO1
+ git init
+ git annex init \"my laptop\"
+
+ cd $REPO1
+ cp -Lr ~/some_large_files ./
+ git annex add some_large_files
+ git commit -m \"added\"
+
+ cd $BASE2
+ git clone $REPO1 $REPO2
+ cd $REPO2
+
+ git annex init \"freebox server\"
+ # This is not really needed, but if you want to replicate on a non cifs mount
+ git annex direct
+
+ cd $REPO1
+ git remote add freebox-server $REPO2
+
+ git annex copy --to freebox-server
+ git annex sync
+
+ cd $REPO2
+ git remote add laptop $REPO1
+ #git annex sync
+
+After this, you should have your .git and plain \"direct\" files on the NAS, mirrored from what's on the laptop.
+
+Hope this helps.
+"""]]
diff --git a/doc/forum/Using_git_annex_with_a_SMB__47__FTP_TV_NAS_with_preconfigured_dirs/comment_6_ae323b16ddb9342e91be955408eca3b1._comment b/doc/forum/Using_git_annex_with_a_SMB__47__FTP_TV_NAS_with_preconfigured_dirs/comment_6_ae323b16ddb9342e91be955408eca3b1._comment
new file mode 100644
index 000000000..44d3f5a85
--- /dev/null
+++ b/doc/forum/Using_git_annex_with_a_SMB__47__FTP_TV_NAS_with_preconfigured_dirs/comment_6_ae323b16ddb9342e91be955408eca3b1._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 6"
+ date="2013-08-24T15:58:28Z"
+ content="""
+You can run any of these operations in any order and it will work. Ie, this is far more complicated and detailed than it needs to be. Just run git-annex commands in any order to do what you want to do. If they don't, file a (detailed) bug report.
+"""]]
diff --git a/doc/forum/Walkthrough_does_not_work_for_me__44___what_am_i_doing_wrong__63__.mdwn b/doc/forum/Walkthrough_does_not_work_for_me__44___what_am_i_doing_wrong__63__.mdwn
new file mode 100644
index 000000000..c6cb35912
--- /dev/null
+++ b/doc/forum/Walkthrough_does_not_work_for_me__44___what_am_i_doing_wrong__63__.mdwn
@@ -0,0 +1,16 @@
+I'm trying to use git-annex as a dropbox-replacement, but I'm hitting unexpected things although I'm doing exactly what I see in the walkthrough screencast and/or the walkthrough commands. I'm using Ubuntu 13.10, installed git-annex with apt-get. It is version 4.20130815.
+
+1) I launch the webapp and create an ~/annex folder as my initial repo. I copy some small text files in it, I see in webapp that they are added.
+2) I add a new "Removable Storage" repo, in my usb drive. I do not touch any other settings, leave it as is. (ie in transfer group for example). It is successfully added to the repo list and I see sync complete and files synced on the webapp.
+3) When I check the contents of the usb disk annex folder, I see the following, while I was expecting to see the files I synced instead.
+
+emre@emrenb:~$ ls /media/emre/348B-78F0/annex/
+annex branches config description HEAD hooks info objects refs
+
+However, I expect the below which is the content of my ~/annex folder:
+emre@emrenb:~$ ls annex/
+unison-sync.log unison-1.log unison-2.log unison.log
+
+In the walkthrough video, when Joey adds a USB storage, the filenames & thir contents sync to the usb drive. Why doesn't it work for me?
+
+Note that I tried also android app and also the zipped tarball build. Same result, I never see actual files.
diff --git a/doc/forum/Walkthrough_does_not_work_for_me__44___what_am_i_doing_wrong__63__/comment_1_cdac15fec6fc41d5487b7f653fa718a4._comment b/doc/forum/Walkthrough_does_not_work_for_me__44___what_am_i_doing_wrong__63__/comment_1_cdac15fec6fc41d5487b7f653fa718a4._comment
new file mode 100644
index 000000000..437e2ecdc
--- /dev/null
+++ b/doc/forum/Walkthrough_does_not_work_for_me__44___what_am_i_doing_wrong__63__/comment_1_cdac15fec6fc41d5487b7f653fa718a4._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawk3HGoDpnOPob5jOjvIootmkve1-nCpRiI"
+ nickname="Kalle"
+ subject="Default removable storage repo not readable without git annex"
+ date="2013-10-21T08:50:50Z"
+ content="""
+Hi,
+
+Sounds to me you are expecting the files to be readable by a filemanager? By default a removable drive repo is only readable by git-annex.
+
+The standard use case is to move files between computers with git-annex installed. I agree this is not what you´d expect.
+
+Read <http://git-annex.branchable.com/forum/USB_backup_with_files_visible/> and the last post of <http://git-annex.branchable.com/forum/Can__39__t_get_git-annex_merge_to_work_from_git_hook/> for more info.
+"""]]
diff --git a/doc/forum/Walkthrough_does_not_work_for_me__44___what_am_i_doing_wrong__63__/comment_2_82050b7dc367ca5968ab0306db9bd7e3._comment b/doc/forum/Walkthrough_does_not_work_for_me__44___what_am_i_doing_wrong__63__/comment_2_82050b7dc367ca5968ab0306db9bd7e3._comment
new file mode 100644
index 000000000..edcc49a35
--- /dev/null
+++ b/doc/forum/Walkthrough_does_not_work_for_me__44___what_am_i_doing_wrong__63__/comment_2_82050b7dc367ca5968ab0306db9bd7e3._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="64.134.31.139"
+ subject="comment 2"
+ date="2013-10-21T22:29:14Z"
+ content="""
+Kalle is right (I seem to keep saying that, Kalle!)
+
+Following the walkthrough commands will get you a non-bare git repository on a removable drive, and you can run \"git annex sync\" in there periodically and see all the files in your repository on the removable drive. The webapp does not make that kind of repository though, and in the screencast I'm showing the normal behavior of the webapp.
+"""]]
diff --git a/doc/forum/Watch__47__assistant__47__webapp_documentation.mdwn b/doc/forum/Watch__47__assistant__47__webapp_documentation.mdwn
new file mode 100644
index 000000000..3d185ba80
--- /dev/null
+++ b/doc/forum/Watch__47__assistant__47__webapp_documentation.mdwn
@@ -0,0 +1,12 @@
+Hello,
+
+I'm not sure about the differences and interactions between watch / assistant / webapp / direct mode. I think I figured the following out, can someone confirm this, and perhaps a few words to the documentation / man page?
+
+- git annex watch uses inotify to find new files, and runs git annex add on them (it does not do regular git add)
+- git annex assistant does the same as watch, but also runs git annex sync for each new file (does it also enable direct mode?)
+- git annex webapp does the same as assistant, and also starts a webapp (in my case it immediately started sending files to origin, without asking for confirmation, which was surprising, I guess this is because I have * annex.numcopies=2 set, and there was only one copy. Still I interpreted the documentation as if it would only show me an interface, not start doing things right away.)
+
+Do these commands do anything else than what I described above?
+
+best regards,
+Tom
diff --git a/doc/forum/Watch__47__assistant__47__webapp_documentation/comment_1_adb377589dbae7fc91001df235c6b48e._comment b/doc/forum/Watch__47__assistant__47__webapp_documentation/comment_1_adb377589dbae7fc91001df235c6b48e._comment
new file mode 100644
index 000000000..556cf4f9b
--- /dev/null
+++ b/doc/forum/Watch__47__assistant__47__webapp_documentation/comment_1_adb377589dbae7fc91001df235c6b48e._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.3.125"
+ subject="comment 1"
+ date="2013-02-07T18:12:17Z"
+ content="""
+Most of this is explained pretty well on the [[man page|git-annex]].
+
+`git annex webapp` doesn't do anything on its own, other than start the assistant if it is not already running, and point your browser at its built-in webapp. Starting the assistant manually will always have the same effect as opening the webapp.
+
+The assistant syncs files as configured by the preferred content settings of repositories. There's an interface to disable this syncing in the webapp, or change the setting to something that doesn't prefer all content be synced to a repository. This syncing of content is different from `git annex sync`, which only syncs git repository data. It's more like running `git annex copy --auto`
+
+The assistant enables direct mode when a new repository is created (using the webapp). It does not enable direct mode when run in an existing repository.
+"""]]
diff --git a/doc/forum/Webapp_on_ARM.mdwn b/doc/forum/Webapp_on_ARM.mdwn
new file mode 100644
index 000000000..c9766dd8c
--- /dev/null
+++ b/doc/forum/Webapp_on_ARM.mdwn
@@ -0,0 +1,6 @@
+Webapp on ARM?
+==============
+
+Since the webapp is apparently now available on Android (not tested yet, but I plan to do it soon ;)), I was wondering what was the status of the webapp on ARM. Does it build, does it work, and if it does would it be possible to enable it in the Debian package for the next release?
+
+For the record, I'm using git-annex on my NAS (Synology DS413j). I'm using the Debian armel package and running it in an Arch Linux chroot (a very simple setup). It works really well, and I'm extremely satisfied with git-annex. Thanks a lot for all your work, Joey *et al.*!
diff --git a/doc/forum/Webapp_on_ARM/comment_1_82ac40cef5b59070136527b8d81a5ce2._comment b/doc/forum/Webapp_on_ARM/comment_1_82ac40cef5b59070136527b8d81a5ce2._comment
new file mode 100644
index 000000000..00e3fed26
--- /dev/null
+++ b/doc/forum/Webapp_on_ARM/comment_1_82ac40cef5b59070136527b8d81a5ce2._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.1.10"
+ subject="comment 1"
+ date="2013-07-22T19:13:38Z"
+ content="""
+To build the WebApp on arm, you need a ghc that supports template haskell on arm. While I have heard persistent rumors of such a thing existing, I have yet to see it.
+
+It's possible to build the WebApp on arm without that, but it's a complicated process, involving first building on x86 with the same versions of the haskell libraries that you have on the arm system, and then using the EvilSplicer to generate a source tree with the template haskell expanded, which can then be built on arm. This build process is not really suitable for a Debian package.
+"""]]
diff --git a/doc/forum/Weird_behavior_with_OS_X_Finder_and_Preview.app.mdwn b/doc/forum/Weird_behavior_with_OS_X_Finder_and_Preview.app.mdwn
new file mode 100644
index 000000000..055a09e2a
--- /dev/null
+++ b/doc/forum/Weird_behavior_with_OS_X_Finder_and_Preview.app.mdwn
@@ -0,0 +1,12 @@
+I am having some weird issues with git annex under OS X. I am new to git annex, and am generally familiar with git. I really like the concept of git-annex and am trying to lean how to fit it into my workflow, but Im running into problems.
+
+I have a folder that I would like to keep in sync across multiple computers and thumb drives. Right now this folder consists of other folders and PDF files. After initializing git and git-annex, all of the files turn into symlinks, as expected.
+
+Looking at this folder in OSX's finder, none of the symlinks have preview images unfortunately, as expected. Also, when trying to open the file (or symlink, and in this case PDFs) in finder, it opens the console which outputs a bunch of crap and then nothing happens. Right clicking on the symlink in finder and using Open with... the default application to open the symlink to the PDF is OSX's Preview.app, as expected, however for some reason this isn't being used when simple double clicking. If you click on the Preview.app option under the right click menu, Preview.app launches, but never opens the file. Selecting an alternative such as the Skim.app pdf viewer (if installed) successfully launches the application and opens the file.
+
+My questions are:
+1. What is the cause of not being able to launch the file in the correct app by simply double clicking it? Do I have something mis-configued? Is it a bug with git-annex? Is git-annex simply not set up to work with finder yet?
+2. How come preview can't open the file but skim can? This might be directly related to the above question, but maybe not.
+3. Is it possible to get file previews for the symlinks in your annex folder? Are there plans to enable this kind of thing in the future, if even possible?
+
+Details about my setup. I am running on a 32-bit Core Duo Macbook pro from 2006, so enviably I have to run 10.6.8 and its the highest OS version I can reach right now. All my CLI packages are installed and up to date with Mac Homebrew. I am running git version 1.7.12. I freshly installed haskell-platform: stable 2012.2.0.0 via homebrew. From there I installed git-annex-3.20120825.
diff --git a/doc/forum/Weird_behavior_with_OS_X_Finder_and_Preview.app/comment_1_8c8d86790a9d31518f9bb96a2d2dafee._comment b/doc/forum/Weird_behavior_with_OS_X_Finder_and_Preview.app/comment_1_8c8d86790a9d31518f9bb96a2d2dafee._comment
new file mode 100644
index 000000000..4234eac2b
--- /dev/null
+++ b/doc/forum/Weird_behavior_with_OS_X_Finder_and_Preview.app/comment_1_8c8d86790a9d31518f9bb96a2d2dafee._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.30"
+ subject="comment 1"
+ date="2012-09-09T17:22:58Z"
+ content="""
+It is unfortunate that certain badly-coded programs fall over on symlinks. In theory, any program that doesn't try to be too smart for its own good will see a symlink as just like the file it links to, and should behave the same. This is the theory that led me to use symlinks in git-annex. But some programs say \"oh, a symlink! Let's see what file that's pointing at, and behave differently!\" I don't understand the mindset that leads to this kind of program being written, unless it's a program like `cp`, that has very good reasons for (at your command) following symlinks or not.
+
+I know absolutely nothing about Mac OSX, having never used it (except for in a ssh session while porting git-annex to it). But I have seen a similar problem with the FBReader ebook viewer. [Bug report](http://bugs.debian.org/685433)
+
+I was able to work around that bug by migrating my files to the SHA256E backend. This ensures that the keys stored in git-annex have extensions like .pdf etc, similar to the symlinks that point to them. You might try migrating some of your files too, and see if it makes OSX behave better. Although I thought OSX didn't rely on file extensions to determine file type..
+
+Anyway, the command is:
+
+ git annex migrate --backend=SHA256E
+
+I have been considering switching the default backend to SHA256E to avoid this type of problem. Your testing will be important grist for that decision.
+"""]]
diff --git a/doc/forum/Weird_behavior_with_OS_X_Finder_and_Preview.app/comment_2_b538dc2c6f122b9ce5f7569de1b03f3e._comment b/doc/forum/Weird_behavior_with_OS_X_Finder_and_Preview.app/comment_2_b538dc2c6f122b9ce5f7569de1b03f3e._comment
new file mode 100644
index 000000000..ee09be502
--- /dev/null
+++ b/doc/forum/Weird_behavior_with_OS_X_Finder_and_Preview.app/comment_2_b538dc2c6f122b9ce5f7569de1b03f3e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://mike.magin.org/"
+ nickname="mmagin"
+ subject="comment 2"
+ date="2012-09-11T15:27:58Z"
+ content="""
+I've been using git-annex mostly on Mac OS X, and it rapidly caused me to switch to SHA256E. I'd certainly be in favor of it being the default. Aside from [[bugs/fsck thinks file content is bad when it isn't]] (fixed by the time I encountered it), I have had no issues with it so far.
+"""]]
diff --git a/doc/forum/Weird_behavior_with_OS_X_Finder_and_Preview.app/comment_3_16e6724fa184392d4decbe0c4eb6efe6._comment b/doc/forum/Weird_behavior_with_OS_X_Finder_and_Preview.app/comment_3_16e6724fa184392d4decbe0c4eb6efe6._comment
new file mode 100644
index 000000000..0315feb64
--- /dev/null
+++ b/doc/forum/Weird_behavior_with_OS_X_Finder_and_Preview.app/comment_3_16e6724fa184392d4decbe0c4eb6efe6._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkurjhi0CRJvgm7QNaZDWS9hitBtavqIpc"
+ nickname="Bret"
+ subject="comment 3"
+ date="2012-09-12T09:23:51Z"
+ content="""
+Sorry for the delayed response. I am in the middle of an apartment move.
+
+I tried changing my default PDF viewer to Skim to see if that improved anything. Nada. Same thing. Finder opens the terminal and outputs a bunch of nonsense.
+
+I tried `git annex migrate --backend=SHA256E` and it seemed to really improve things from finders point of view. Still not icon previews, but you can launch every file by double clicking it and preview is able to follow the symlink.
+
+Note, I am on OS X 10.6. I cant upgrade to 10.7+ due to my laptops aging processor (10.7+ requires 64-bit intel chips) and thus can't test git-annex on a more modern OS version. Someone should test it out on a newer version of OS X before chaining any defaults, however, it seems to really improve things for the setup I have.
+"""]]
diff --git a/doc/forum/Weird_behavior_with_OS_X_Finder_and_Preview.app/comment_4_e514fe2d4d0ad6a10e281939e6ab4266._comment b/doc/forum/Weird_behavior_with_OS_X_Finder_and_Preview.app/comment_4_e514fe2d4d0ad6a10e281939e6ab4266._comment
new file mode 100644
index 000000000..aa50ab57c
--- /dev/null
+++ b/doc/forum/Weird_behavior_with_OS_X_Finder_and_Preview.app/comment_4_e514fe2d4d0ad6a10e281939e6ab4266._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="comment 4"
+ date="2012-09-12T20:32:52Z"
+ content="""
+I see a migration to SHA256E currently outputs:
+
+migrate issue.txt (checksum...) (Recording state in git...)
+ok
+
+Is that verifying the existing checksum or re-computing it to re-name the file? If the latter, couldn't the SHA256 to SHA256E migration just rename the file?
+
+I would be worried about this process hiding data corruption.. If it isn't using the old checksum but instead re-computing a new one then it would be easy to miss the fact that a files checksum changed during this process.
+"""]]
diff --git a/doc/forum/Weird_behavior_with_OS_X_Finder_and_Preview.app/comment_5_e0eec765f72f7bf6f5a2a92c9b5dacad._comment b/doc/forum/Weird_behavior_with_OS_X_Finder_and_Preview.app/comment_5_e0eec765f72f7bf6f5a2a92c9b5dacad._comment
new file mode 100644
index 000000000..254a524aa
--- /dev/null
+++ b/doc/forum/Weird_behavior_with_OS_X_Finder_and_Preview.app/comment_5_e0eec765f72f7bf6f5a2a92c9b5dacad._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.30"
+ subject="comment 5"
+ date="2012-09-14T04:20:27Z"
+ content="""
+Good catch, I've made it verify the old checksum first.
+
++/- E migrations are not currently optimised.
+"""]]
diff --git a/doc/forum/What_can_be_done_in_case_of_conflict.mdwn b/doc/forum/What_can_be_done_in_case_of_conflict.mdwn
new file mode 100644
index 000000000..42167a609
--- /dev/null
+++ b/doc/forum/What_can_be_done_in_case_of_conflict.mdwn
@@ -0,0 +1,7 @@
+Hi,
+
+How can I resolve the conflict when it occurs?
+
+Suppose I have 2 branches (master, current), When I merge these branches or while doing cherry-pick, if I get conflict how can I resolve it?
+
+Thank You
diff --git a/doc/forum/What_can_be_done_in_case_of_conflict/comment_1_5ca86b099dfa08a50f656ea03bf1dcd9._comment b/doc/forum/What_can_be_done_in_case_of_conflict/comment_1_5ca86b099dfa08a50f656ea03bf1dcd9._comment
new file mode 100644
index 000000000..6f1d24130
--- /dev/null
+++ b/doc/forum/What_can_be_done_in_case_of_conflict/comment_1_5ca86b099dfa08a50f656ea03bf1dcd9._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2012-04-23T14:29:03Z"
+ content="""
+You handle conflicts in annexed files the same as you would handle them in other binary files checked into git.
+
+For example, you might choose to `git rm` or `git add` the file to resolve the conflict.
+
+[[Previous_discussion|forum/A_really_stupid_question]]
+"""]]
diff --git a/doc/forum/What_can_be_done_in_case_of_conflict/comment_2_69ee17959a92bb8359c0fd7b2a9d8dfb._comment b/doc/forum/What_can_be_done_in_case_of_conflict/comment_2_69ee17959a92bb8359c0fd7b2a9d8dfb._comment
new file mode 100644
index 000000000..f4293d9c1
--- /dev/null
+++ b/doc/forum/What_can_be_done_in_case_of_conflict/comment_2_69ee17959a92bb8359c0fd7b2a9d8dfb._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlYu7QmD7wrbHWkoxuriaA9XcijM-g5vrQ"
+ nickname="Royal"
+ subject="Resolving conflict"
+ date="2012-04-24T03:59:31Z"
+ content="""
+Hi,
+Now I am able to resolve the conflict.
+Thank you.
+"""]]
diff --git a/doc/forum/What_can_be_done_in_case_of_conflict/comment_3_017f4bac57a040c496e0c9d068dcfd9e._comment b/doc/forum/What_can_be_done_in_case_of_conflict/comment_3_017f4bac57a040c496e0c9d068dcfd9e._comment
new file mode 100644
index 000000000..a0d3ded39
--- /dev/null
+++ b/doc/forum/What_can_be_done_in_case_of_conflict/comment_3_017f4bac57a040c496e0c9d068dcfd9e._comment
@@ -0,0 +1,41 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlYu7QmD7wrbHWkoxuriaA9XcijM-g5vrQ"
+ nickname="Royal"
+ subject="Resolving conflict"
+ date="2012-04-23T15:49:30Z"
+ content="""
+Thanks for the reply.
+
+I am executing the following commands.
+
+git init main
+cd main
+git annex init main
+echo a > a
+git annex add a
+git commit -m Initial
+git annex unlock a
+echo aa > a
+git annex add a
+git commit -m first
+git annex unlock a
+echo aaa > a
+git annex add a
+git commit -m second
+git log
+git cherry-pick <Hash of first commit>
+
+--------------------
+Error:
+
+error: could not apply 2be8f38... first
+hint: after resolving the conflicts, mark the corrected paths
+hint: with 'git add <paths>' or 'git rm <paths>'
+hint: and commit the result with 'git commit'
+
+How can resolve the the above conflict.
+If I see the content of the file I will get the content of second commit.
+Is there any way I can get the content for first commit(Like in git we have 'theirs' option.)
+
+Thank you.
+"""]]
diff --git a/doc/forum/What_happened_to_the_walkthrough__63__.mdwn b/doc/forum/What_happened_to_the_walkthrough__63__.mdwn
new file mode 100644
index 000000000..e8098d29a
--- /dev/null
+++ b/doc/forum/What_happened_to_the_walkthrough__63__.mdwn
@@ -0,0 +1 @@
+As of right now (2012-05-24 at 18:00 UTC), the [[Walkthrough]] page is basically empty. Its entire contents are "A walkthrough of the basic features of git-annex." No links (other than the autogenerated "what links to this page" list at the bottom) and no contents. Any idea what happened?
diff --git a/doc/forum/What_happened_to_the_walkthrough__63__/comment_1_70db0e3cfb1318e95671c23726e5541d._comment b/doc/forum/What_happened_to_the_walkthrough__63__/comment_1_70db0e3cfb1318e95671c23726e5541d._comment
new file mode 100644
index 000000000..cbf852dbf
--- /dev/null
+++ b/doc/forum/What_happened_to_the_walkthrough__63__/comment_1_70db0e3cfb1318e95671c23726e5541d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 1"
+ date="2012-05-24T19:18:55Z"
+ content="""
+It seems the pages that are supposed to be inlined are not being found even though they are in `doc/walkthrough/`.
+"""]]
diff --git a/doc/forum/What_happened_to_the_walkthrough__63__/comment_2_f9305dd19b9b5f35e66d915b8c30374b._comment b/doc/forum/What_happened_to_the_walkthrough__63__/comment_2_f9305dd19b9b5f35e66d915b8c30374b._comment
new file mode 100644
index 000000000..9720adfbc
--- /dev/null
+++ b/doc/forum/What_happened_to_the_walkthrough__63__/comment_2_f9305dd19b9b5f35e66d915b8c30374b._comment
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ subject="comment 2"
+ date="2012-05-24T20:15:19Z"
+ content="""
+Broken last night during upgrade, fixed now, thanks for noticing.
+"""]]
diff --git a/doc/forum/What_is_the_best_way_to___34__git_annex_mv__34___file__63__.mdwn b/doc/forum/What_is_the_best_way_to___34__git_annex_mv__34___file__63__.mdwn
new file mode 100644
index 000000000..6dd5c16df
--- /dev/null
+++ b/doc/forum/What_is_the_best_way_to___34__git_annex_mv__34___file__63__.mdwn
@@ -0,0 +1 @@
+Since all the annexed (in indirect mode) files are symlinks to topdir/.git/annex/... moving files among directories at different levels is not that straightforward since symlinks would get broken. And since there is not 'annex mv' command -- what is the best way? (unlock is not the resolution since it copies the file, which might be prohibitively large and inefficient)
diff --git a/doc/forum/What_is_the_best_way_to___34__git_annex_mv__34___file__63__/comment_1_02d305f307b4d2ff7acd98cb36508a2f._comment b/doc/forum/What_is_the_best_way_to___34__git_annex_mv__34___file__63__/comment_1_02d305f307b4d2ff7acd98cb36508a2f._comment
new file mode 100644
index 000000000..9eae8ef7a
--- /dev/null
+++ b/doc/forum/What_is_the_best_way_to___34__git_annex_mv__34___file__63__/comment_1_02d305f307b4d2ff7acd98cb36508a2f._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-06-12T16:42:54Z"
+ content="""
+You can move the symlinks however you like (git mv, or regular mv and git add).
+
+To fix up broken symlinks, you can either run `git annex fix`, or just commit the move. The pre-commit hook fixes up links automatically.
+"""]]
diff --git a/doc/forum/What_is_the_difference_between___34__local_computer__34___and___34__remote_server__34__.mdwn b/doc/forum/What_is_the_difference_between___34__local_computer__34___and___34__remote_server__34__.mdwn
new file mode 100644
index 000000000..7222e07b5
--- /dev/null
+++ b/doc/forum/What_is_the_difference_between___34__local_computer__34___and___34__remote_server__34__.mdwn
@@ -0,0 +1,3 @@
+What is the difference between "local computer" and "remote server" in the assistant's repository configuration menu? How does git-annex treat the targets differently?
+
+
diff --git a/doc/forum/What_is_the_difference_between___34__local_computer__34___and___34__remote_server__34__/comment_1_68734a118b7dc0c88ba67eca20953a55._comment b/doc/forum/What_is_the_difference_between___34__local_computer__34___and___34__remote_server__34__/comment_1_68734a118b7dc0c88ba67eca20953a55._comment
new file mode 100644
index 000000000..167d008f9
--- /dev/null
+++ b/doc/forum/What_is_the_difference_between___34__local_computer__34___and___34__remote_server__34__/comment_1_68734a118b7dc0c88ba67eca20953a55._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 1"
+ date="2013-01-25T22:39:20Z"
+ content="""
+Local computer pairs with another computer on your LAN. You don't need an account on that computer, it can belong to someone else and has to be running the webapp as well for them to verify the pairing.
+
+Remote server is for people with a ssh server out there, and does not require it be running the assistant, or even have git-annex installed. (Though it works better if at least git-annex is installed on it.)
+"""]]
diff --git a/doc/forum/What_to_do_when_computer_is_lost_and_only_an_encrypted_ssh_remote_is_left__63__.mdwn b/doc/forum/What_to_do_when_computer_is_lost_and_only_an_encrypted_ssh_remote_is_left__63__.mdwn
new file mode 100644
index 000000000..1504d10cd
--- /dev/null
+++ b/doc/forum/What_to_do_when_computer_is_lost_and_only_an_encrypted_ssh_remote_is_left__63__.mdwn
@@ -0,0 +1 @@
+What do I do when I have set up git-annex to back up a folder to an encrypted remote on a vps, and my laptop was stolen? This recently happened, and luckally I had another backup, but what would I do in the case that I have 1 computer using git-annex, backung ip a folder to an encrypted ssh remote on a vps, and I loose the computer? How do I get the data back then?
diff --git a/doc/forum/What_to_do_when_computer_is_lost_and_only_an_encrypted_ssh_remote_is_left__63__/comment_1_67ee446ca6d66e2c259ea771c2c9a2b2._comment b/doc/forum/What_to_do_when_computer_is_lost_and_only_an_encrypted_ssh_remote_is_left__63__/comment_1_67ee446ca6d66e2c259ea771c2c9a2b2._comment
new file mode 100644
index 000000000..832c931b4
--- /dev/null
+++ b/doc/forum/What_to_do_when_computer_is_lost_and_only_an_encrypted_ssh_remote_is_left__63__/comment_1_67ee446ca6d66e2c259ea771c2c9a2b2._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 1"
+ date="2013-07-26T03:57:06Z"
+ content="""
+I'm glad you had another backup. That is wise.
+
+When you have a special remote, that does not store your git repository, but only the contents of files. So if you lose all copies of your git repositories, you have lost all record of the file name associated with a file. It's the same as if `fsck` rescued inodes to `lost+found`; you'd have to manually rename the files to new names.
+
+Then there's the added complication of the encryption. This depends on how it was set up. If you set up the remote using a GPG key (and didn't lose the key too), you can manually use that key to decrypt the files. On the other hand, if it generated its own key and stored it in the git repo (default with the assistant), then when you lose all copies of the git repo, the key is gone, and your encrypted files are useless.
+"""]]
diff --git a/doc/forum/What_to_do_when_computer_is_lost_and_only_an_encrypted_ssh_remote_is_left__63__/comment_2_6d3cce3c8048e4aea8f0ed76473f6af1._comment b/doc/forum/What_to_do_when_computer_is_lost_and_only_an_encrypted_ssh_remote_is_left__63__/comment_2_6d3cce3c8048e4aea8f0ed76473f6af1._comment
new file mode 100644
index 000000000..308df9a18
--- /dev/null
+++ b/doc/forum/What_to_do_when_computer_is_lost_and_only_an_encrypted_ssh_remote_is_left__63__/comment_2_6d3cce3c8048e4aea8f0ed76473f6af1._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawln3ckqKx0x_xDZMYwa9Q1bn4I06oWjkog"
+ nickname="Michael"
+ subject="comment 2"
+ date="2013-07-26T15:04:31Z"
+ content="""
+I thought the key was checked into .git in any case, but encrypted in the case of GPG. So .git gone => everything gone in any case.
+"""]]
diff --git a/doc/forum/What_to_do_when_computer_is_lost_and_only_an_encrypted_ssh_remote_is_left__63__/comment_3_bd506e1ca7307660b3b9769eb97beddb._comment b/doc/forum/What_to_do_when_computer_is_lost_and_only_an_encrypted_ssh_remote_is_left__63__/comment_3_bd506e1ca7307660b3b9769eb97beddb._comment
new file mode 100644
index 000000000..4591a559e
--- /dev/null
+++ b/doc/forum/What_to_do_when_computer_is_lost_and_only_an_encrypted_ssh_remote_is_left__63__/comment_3_bd506e1ca7307660b3b9769eb97beddb._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 3"
+ date="2013-07-26T16:45:26Z"
+ content="""
+Michael, you're right. Thanks for fact checking my late night comment! ;)
+"""]]
diff --git a/doc/forum/Which_cloud_providers_are_supported__63___.mdwn b/doc/forum/Which_cloud_providers_are_supported__63___.mdwn
new file mode 100644
index 000000000..9f8afc3fc
--- /dev/null
+++ b/doc/forum/Which_cloud_providers_are_supported__63___.mdwn
@@ -0,0 +1,3 @@
+So Box.net and Amazon is supported, any way to get google drive in there?
+
+thanks for cool software!
diff --git a/doc/forum/Which_cloud_providers_are_supported__63___/comment_1_1f9398840144e0452a2fed9336046547._comment b/doc/forum/Which_cloud_providers_are_supported__63___/comment_1_1f9398840144e0452a2fed9336046547._comment
new file mode 100644
index 000000000..9d8f0ecf7
--- /dev/null
+++ b/doc/forum/Which_cloud_providers_are_supported__63___/comment_1_1f9398840144e0452a2fed9336046547._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.140"
+ subject="comment 1"
+ date="2013-07-18T17:40:36Z"
+ content="""
+[[tips/googledriveannex]]
+
+See [[special_remotes]] for a full list of things people have gotten to work.
+"""]]
diff --git a/doc/forum/Why_can__39__t_encryption_be_enabled_for_removable_drives__63__.mdwn b/doc/forum/Why_can__39__t_encryption_be_enabled_for_removable_drives__63__.mdwn
new file mode 100644
index 000000000..9ff6f11fb
--- /dev/null
+++ b/doc/forum/Why_can__39__t_encryption_be_enabled_for_removable_drives__63__.mdwn
@@ -0,0 +1,7 @@
+I currently have a pair of hard drives that I store backups etc on and that I would like to use as archive repositories for Git-Annex. I want everything on these to be encrypted, because I can't guarantee physical security of them.
+
+When I am setting up a removable drive as a repository, there is no option to encrypt to it. I understand that there is a "Directory" special remote, but it seems odd to have to use a different special remote that is not built into the webapp. Wouldn't it be good to have a checkbox for encryption when setting up a removable drive as a repository?
+
+Is there something that I'm missing here?
+
+Thanks for a great piece of software!
diff --git a/doc/forum/Why_can__39__t_encryption_be_enabled_for_removable_drives__63__/comment_1_4341898d5ae4f09a5b06d24f5fe6192d._comment b/doc/forum/Why_can__39__t_encryption_be_enabled_for_removable_drives__63__/comment_1_4341898d5ae4f09a5b06d24f5fe6192d._comment
new file mode 100644
index 000000000..0ddf26666
--- /dev/null
+++ b/doc/forum/Why_can__39__t_encryption_be_enabled_for_removable_drives__63__/comment_1_4341898d5ae4f09a5b06d24f5fe6192d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.90"
+ subject="comment 1"
+ date="2013-07-16T19:45:42Z"
+ content="""
+git-annex stores a clone of the git repository on the removable drive. To encrypt a git remote, you can use the [git-remote-gcrypt](https://github.com/blake2-ppc/git-remote-gcrypt) tool. This will work with git-annex, but it needs integration into the webapp to support setting it up, and further integration so git-annex can detect when a git remote is encrypted and also encrypt the contents of file is stores there.
+"""]]
diff --git a/doc/forum/Why_does_the_bup_remote_use___126____47__.bup__63__.mdwn b/doc/forum/Why_does_the_bup_remote_use___126____47__.bup__63__.mdwn
new file mode 100644
index 000000000..c250ef7c1
--- /dev/null
+++ b/doc/forum/Why_does_the_bup_remote_use___126____47__.bup__63__.mdwn
@@ -0,0 +1,5 @@
+I created a test remote using the command:
+
+ git annex initremote mybup type=bup encryption=none buprepo=/tmp/mybup
+
+I can copy files to and from the remote just fine. However, every time I do so it makes changes inside `~/.bup`. If I delete `~/.bup` it will recreate it. Is this expected? Are the files in `~/.bup` of any consequence?
diff --git a/doc/forum/Why_does_the_bup_remote_use___126____47__.bup__63__/comment_1_da9c7c0e93aefc2da7409de5b138d86f._comment b/doc/forum/Why_does_the_bup_remote_use___126____47__.bup__63__/comment_1_da9c7c0e93aefc2da7409de5b138d86f._comment
new file mode 100644
index 000000000..cbb3c8d6d
--- /dev/null
+++ b/doc/forum/Why_does_the_bup_remote_use___126____47__.bup__63__/comment_1_da9c7c0e93aefc2da7409de5b138d86f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/2grhJvAC049fJnvALDXek.6MRZMTlg--#eec89"
+ nickname="John"
+ subject="Ah"
+ date="2012-10-18T23:52:03Z"
+ content="""
+I get now why ~/.bup is being used: -r DIR specifies a local DIR as the bup directory, but ~/.bup is still used for the local temp files. It would be nice, therefore, if BUP_DIR were set in the case that -r specifies a local directory, so that only that directory is used. Unless, of course, that leads to space limitations in the bup directory. Hmm... maybe this should just be left as is in that case.
+"""]]
diff --git a/doc/forum/Will_git-annex_solve_my_problem__63__.mdwn b/doc/forum/Will_git-annex_solve_my_problem__63__.mdwn
new file mode 100644
index 000000000..0aa2ded52
--- /dev/null
+++ b/doc/forum/Will_git-annex_solve_my_problem__63__.mdwn
@@ -0,0 +1,7 @@
+Here's my current situation:
+
+I have a box which creates about a dozen files periodically. All files add up to about 1GB in size. The files are text and sorted. I then rsync the files to n servers. The rsync diff algorithm transfers way less than n * 1GB because the files are largely the same. However, this distribution technique is inefficient because I must run n rsync processes in parallel and the rsync diff algorithm takes a lot of CPU.
+
+How could I use git-annex instead of rsync?
+
+Because the box producing the new files also has the old files, then presumably git could calculate the diffs for each file once instead of n times as with the rsync solution? Then only the diffs need be distributed to the n servers... using git-annex? And finally the newly updated version of the dozen files needs to be available on each of the n servers. Ideally, the diffs would not mount up over time on either the publishing server or the n servers, thus causing out of disk problems etc. How to deploy git-annex to solve my problem?
diff --git a/doc/forum/Will_git-annex_solve_my_problem__63__/comment_1_35acbdd1a7727df204d776c2e8f02b53._comment b/doc/forum/Will_git-annex_solve_my_problem__63__/comment_1_35acbdd1a7727df204d776c2e8f02b53._comment
new file mode 100644
index 000000000..a4f27f46e
--- /dev/null
+++ b/doc/forum/Will_git-annex_solve_my_problem__63__/comment_1_35acbdd1a7727df204d776c2e8f02b53._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-03-27T22:48:16Z"
+ content="""
+git-annex will not perform better than rsync. It uses rsync. It also does not yet use old versions of files as a rsync basis when transferring a new version of a file, so is not as efficient in this scenario.
+"""]]
diff --git a/doc/forum/Will_git-annex_solve_my_problem__63__/comment_2_230256c19ac139dea207d89c06f70782._comment b/doc/forum/Will_git-annex_solve_my_problem__63__/comment_2_230256c19ac139dea207d89c06f70782._comment
new file mode 100644
index 000000000..2b7b7e5f7
--- /dev/null
+++ b/doc/forum/Will_git-annex_solve_my_problem__63__/comment_2_230256c19ac139dea207d89c06f70782._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkaBh9VNJ-RZ26wJZ4BEhMN1IlPT-DK6JA"
+ nickname="Alex"
+ subject="Bup"
+ date="2013-04-03T05:47:41Z"
+ content="""
+I think bup will solve your use case. Make a local bup repo and backup there then clone that repo n times. If you run git annex on top of bup you can then retrieve the subset of files you need at each destination. This will work best if you don't need every file on every remote or if your network is much slower than local disk access.
+"""]]
diff --git a/doc/forum/Will_git_annex_work_on_a_FAT32_formatted_key__63__.mdwn b/doc/forum/Will_git_annex_work_on_a_FAT32_formatted_key__63__.mdwn
new file mode 100644
index 000000000..f458ba72e
--- /dev/null
+++ b/doc/forum/Will_git_annex_work_on_a_FAT32_formatted_key__63__.mdwn
@@ -0,0 +1,3 @@
+FAT32 does not support symlinks, so I wonder if there's going to be a problem with that.
+
+Generally speaking, I am wondering about portability of git annex on windows and on android...
diff --git a/doc/forum/Will_git_annex_work_on_a_FAT32_formatted_key__63__/comment_1_426482e6eb3a27687a48f24f6ef2332f._comment b/doc/forum/Will_git_annex_work_on_a_FAT32_formatted_key__63__/comment_1_426482e6eb3a27687a48f24f6ef2332f._comment
new file mode 100644
index 000000000..119c9e535
--- /dev/null
+++ b/doc/forum/Will_git_annex_work_on_a_FAT32_formatted_key__63__/comment_1_426482e6eb3a27687a48f24f6ef2332f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-03-07T19:13:14Z"
+ content="""
+See [[bugs/fat_support]]. A bare git repo will have to be used to avoid symlink problems, at least for now. The other problem is that git-annex key files have colons in their filenames.
+"""]]
diff --git a/doc/forum/Will_git_annex_work_on_a_FAT32_formatted_key__63__/comment_2_af4f8b52526d8bea2904c95406fd2796._comment b/doc/forum/Will_git_annex_work_on_a_FAT32_formatted_key__63__/comment_2_af4f8b52526d8bea2904c95406fd2796._comment
new file mode 100644
index 000000000..ca599b285
--- /dev/null
+++ b/doc/forum/Will_git_annex_work_on_a_FAT32_formatted_key__63__/comment_2_af4f8b52526d8bea2904c95406fd2796._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 2"
+ date="2011-03-19T15:37:22Z"
+ content="""
+Now it's fully supported, so long as you put a bare git repo on your key.
+"""]]
diff --git a/doc/forum/Windows_support.mdwn b/doc/forum/Windows_support.mdwn
new file mode 100644
index 000000000..0e9e8dcb6
--- /dev/null
+++ b/doc/forum/Windows_support.mdwn
@@ -0,0 +1,6 @@
+Hi,
+
+Do you have any news about Windows support?
+Is this something you're currently working on?
+
+Thanks!
diff --git a/doc/forum/Windows_support/comment_1_23fa9aa3b00940a1c1b3876c35eef019._comment b/doc/forum/Windows_support/comment_1_23fa9aa3b00940a1c1b3876c35eef019._comment
new file mode 100644
index 000000000..95323ff99
--- /dev/null
+++ b/doc/forum/Windows_support/comment_1_23fa9aa3b00940a1c1b3876c35eef019._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2012-03-12T06:43:02Z"
+ content="""
+[[todo/windows_support]] has everything I know about making a windows port. This badly needs someone who understand Windows to dive into it. The question of how to create a symbolic link (or the relevant Windows equivilant) from haskell on Windows
+is a good starting point..
+"""]]
diff --git a/doc/forum/Windows_usage_instructions.mdwn b/doc/forum/Windows_usage_instructions.mdwn
new file mode 100644
index 000000000..0b7b94625
--- /dev/null
+++ b/doc/forum/Windows_usage_instructions.mdwn
@@ -0,0 +1,25 @@
+Having a spot of bother in setting up for windows usage.
+
+I'm attempting to have a windows box syncing to a server (over ssh) and a linux box also syncing against that*
+
+So, on each machine I do
+
+ git init
+ git annex init
+
+
+On the windows and linux desktops I then do a
+
+ git remote add server serverdetails.
+
+Now the problem is that if I don't add files to the repos on the machines, they won't sync as there is no branch checked out; and if I do then the first one is fine but the second will fail as it doesn't allow fast-forwards. What am I doing wrong? I've tried making the server repo bare / not bare.
+
+I'm using the latest nightly windows build, and a build from git from today (29d5bb94b4512cfe3072c9ff840cb0ce9f2af744)
+
+
+
+
+
+
+
+*Actually I'm trying to do something a little more complex than that, but this is the simplest version I can come up with.
diff --git a/doc/forum/Windows_usage_instructions/comment_1_d43dbd9406da3b9747b147715eca94ac._comment b/doc/forum/Windows_usage_instructions/comment_1_d43dbd9406da3b9747b147715eca94ac._comment
new file mode 100644
index 000000000..6162b9540
--- /dev/null
+++ b/doc/forum/Windows_usage_instructions/comment_1_d43dbd9406da3b9747b147715eca94ac._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmhfodZquCI_EEl-f3h7HkROTszlsQL6yA"
+ nickname="Joe"
+ subject="comment 1"
+ date="2013-06-16T11:29:36Z"
+ content="""
+This may be related to [this](http://git-annex.branchable.com/bugs/windows_port_-_repo_can__39__t_pull_newly_added_files_/#comment-a023dca06c2bcb9636d8a332f8e95ae4)
+"""]]
diff --git a/doc/forum/Wishlist:_Bittorrent-like_transfers.mdwn b/doc/forum/Wishlist:_Bittorrent-like_transfers.mdwn
new file mode 100644
index 000000000..7ec663216
--- /dev/null
+++ b/doc/forum/Wishlist:_Bittorrent-like_transfers.mdwn
@@ -0,0 +1,5 @@
+**EDIT: Mistakenly posted this thread in the forum. I created a new post in [[todo|todo/Bittorrent-like_features]]
+
+Do you think it would be possible to have bittorrent-like transfers between remotes, so that no one remote gets pegged too hard with transfers? It would be great if you distribute your files between multiple bandwidth-capped remotes, and want fast down speed. Obviously, this isn't a simple task, but the protocol is already there, it just needs to be adapted for the purpose (and re-written in Haskell...). Maybe some day in the future after the more important stuff gets taken care of? It could be an enticing stretch goal.
+
+PS: still working on getting BTC, will be donating soon!
diff --git a/doc/forum/Wishlist:_Bittorrent-like_transfers/comment_1_13544d54fb0418af4ca9200cdb045d91._comment b/doc/forum/Wishlist:_Bittorrent-like_transfers/comment_1_13544d54fb0418af4ca9200cdb045d91._comment
new file mode 100644
index 000000000..73295478f
--- /dev/null
+++ b/doc/forum/Wishlist:_Bittorrent-like_transfers/comment_1_13544d54fb0418af4ca9200cdb045d91._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://a-or-b.myopenid.com/"
+ ip="203.45.2.230"
+ subject="comment 1"
+ date="2013-07-19T02:33:36Z"
+ content="""
+I agree. I mentioned it briefly here:
+
+[[http://git-annex.branchable.com/design/assistant/polls/what_is_preventing_me_from_using_git-annex_assistant/#comment-5a5d46967b826f602c423d7f72ac6f5e]]
+
+
+I did *briefly* look into torrents and the like, but couldn't work out a way to lock it down so only authorized users could use either the tracker or connect to pull the data down...
+
+The security aspect is the kicker in my mind.
+"""]]
diff --git a/doc/forum/Wishlist:_Bittorrent-like_transfers/comment_2_9a7dad35bf80c684ad97892420d7370c._comment b/doc/forum/Wishlist:_Bittorrent-like_transfers/comment_2_9a7dad35bf80c684ad97892420d7370c._comment
new file mode 100644
index 000000000..affd07efd
--- /dev/null
+++ b/doc/forum/Wishlist:_Bittorrent-like_transfers/comment_2_9a7dad35bf80c684ad97892420d7370c._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="GLITTAH"
+ ip="37.130.227.133"
+ subject="comment 2"
+ date="2013-07-19T07:38:47Z"
+ content="""
+Okay I've got some ideas, but they need refining. I should be posting more tomorrow.
+
+One thing I thought of though, there could be two types of torrent support:
+
+1. You use a torrent file or magnet link as a special remote URL. This remote is read-only, naturally, and you'd only be able to leech (and seed, I suppose) the file in the torrent. Neat feature maybe. I wasn't previously thinking of this.
+
+2. This isn't really bittorrent, just inspired by it. You use a bittorrent-type protocol to transfer between your private remotes. You could download from multiple remotes at once to get a file (like leeching, without a tracker, just pre-defined peers...aka remotes), or you could superseed to remotes to push a file, and have the remotes then share the parts of the file amongst themselves to each get a complete copy. Remote groups could possibly be built on, or special groups could be coded in to define the swarm. You update (add/remove) the swarm members locally, and push the changes to each of the old swarm members so they can add/remove other remotes (or themselves) from the swarm. Possibly, you could just push the updated swarm list to one remote already in the swarm, it adopts the new list, and shares it with the rest of the swarm. Each remote does the same. Maybe the swarm list should be GPG-signed and verified before adopted and passed forward?
+
+The more I think about it, the more awesome I think it could be, but holy shit it would be a LOT of work.
+"""]]
diff --git a/doc/forum/Wishlist:_Bittorrent-like_transfers/comment_3_e5de748bc5da12a4a01e08cde2407dd1._comment b/doc/forum/Wishlist:_Bittorrent-like_transfers/comment_3_e5de748bc5da12a4a01e08cde2407dd1._comment
new file mode 100644
index 000000000..ba8da25f0
--- /dev/null
+++ b/doc/forum/Wishlist:_Bittorrent-like_transfers/comment_3_e5de748bc5da12a4a01e08cde2407dd1._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmLB39PC89rfGaA8SwrsnB6tbumezj-aC0"
+ nickname="Tobias"
+ subject="comment 3"
+ date="2013-07-19T07:50:09Z"
+ content="""
+Personally i think the easiest implementation to make would be smart transfers.
+
+You have a repo on your laptop, and a repo at work. And you have(say) 5 special remotes in between them that they need to use to transfer data.
+
+The laptop could upload 5 different files to those repositories. Wouldn't quite be bittorent transfer(not even close). But it would probably be much simpler to implement. And when syncing a lot of files(instead of just one really big one) the speed gain should really be about the same as if all the special remotes used some kind of bittorent thing.
+
+Just a thought.
+"""]]
diff --git a/doc/forum/Wishlist:_Bittorrent-like_transfers/comment_4_e51530178f1e034c0fdd5c9aa9945567._comment b/doc/forum/Wishlist:_Bittorrent-like_transfers/comment_4_e51530178f1e034c0fdd5c9aa9945567._comment
new file mode 100644
index 000000000..d3e0d3314
--- /dev/null
+++ b/doc/forum/Wishlist:_Bittorrent-like_transfers/comment_4_e51530178f1e034c0fdd5c9aa9945567._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmLB39PC89rfGaA8SwrsnB6tbumezj-aC0"
+ nickname="Tobias"
+ subject="comment 4"
+ date="2013-07-19T07:51:39Z"
+ content="""
+Of course all files should be uploaded to all remote(to match with numcopies). but the initial push could be spread out over all existing remotes, to facility faster initial download/transfer.
+"""]]
diff --git a/doc/forum/Wishlist:_Bittorrent-like_transfers/comment_5_81ea9c129d8c02097f09ef8c68f1bb11._comment b/doc/forum/Wishlist:_Bittorrent-like_transfers/comment_5_81ea9c129d8c02097f09ef8c68f1bb11._comment
new file mode 100644
index 000000000..1ef2b25ac
--- /dev/null
+++ b/doc/forum/Wishlist:_Bittorrent-like_transfers/comment_5_81ea9c129d8c02097f09ef8c68f1bb11._comment
@@ -0,0 +1,27 @@
+[[!comment format=mdwn
+ username="GLITTAH"
+ ip="37.130.227.133"
+ subject="comment 5"
+ date="2013-07-19T21:23:35Z"
+ content="""
+Disclaimer: I'm thinking out loud of what could make git-annex even more awesome. I don't expect this to be implemented any time soon. Please pardon any dumbassery.
+
+Much easier to implement, but having your remotes (optionally!) act like a swarm would be an awesome feature to have because you bring in a lot of new features that optimize storage, bandwidth, and overall traffic usage. This would be made a lot easier if parts of it were implemented in small steps that added a nifty feature. The best part is, each of these could be implemented by themselves, and they're all features that would be really useful.
+
+Step 1. Concurrent downloads of a file from remotes.
+
+This would make sense to have, it saves upload traffic on your remotes, and you also get faster DL speeds on the receiving end.
+
+
+Step 2. Implementing part of the super-seeding capabilities.
+
+You upload pieces of a file to different remotes from your laptop, and on your desktop you can download all those pieces and put them together again to get a complete file. If you *really* wanted to get fancy, you could build in redundancy (ala RAID) so if a remote or two gets lost, you don't lose the entire file. This would be a very efficient use of storage if you have a bunch of free cloud storage accounts (~1GB each) and some big files you want to back up.
+
+
+Step 3. Setting it up so that those remotes could talk to one another and share those pieces.
+
+This is where it gets more like bittorrent. Useful because you upload one copy and in a few hours, have say, 5 complete copies spread across your remotes. You could add or remove remotes from a swarm locally, and push those changes to those remotes, which then adapt themselves to suit the new rules and share those with other remotes in the swarm (rules should be GPG-signed as a safety precaution). Also, if/when deltas get implemented, you could push that delta to the swarm and have all the remotes adopt it. This is cooler than regular bittorrent because the shared file can be updated. As a safety precaution, the delta could be GPG signed so a corrupt file doesn't contaminate the entire swarm. Each remote could have bandwidth/storage limits set in a dotfile.
+
+This is a high-level idea of how it might work, and it's also a HUGE set of features to add, but if implemented, you'd be saving a ton of resources, adding new use cases, and making git-annex more flexible.
+
+"""]]
diff --git a/doc/forum/Wishlist:_Bittorrent-like_transfers/comment_6_3b5798414f89686526da3dfa72c0c4f2._comment b/doc/forum/Wishlist:_Bittorrent-like_transfers/comment_6_3b5798414f89686526da3dfa72c0c4f2._comment
new file mode 100644
index 000000000..7a027c909
--- /dev/null
+++ b/doc/forum/Wishlist:_Bittorrent-like_transfers/comment_6_3b5798414f89686526da3dfa72c0c4f2._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="GLITTAH"
+ ip="37.130.227.133"
+ subject="comment 6"
+ date="2013-07-19T21:28:58Z"
+ content="""
+Obviously, Step 3 would only work on remotes that you have control of processes on, but if given login credentials to cloud storage remotes (potentially dangerous!) they could read/write to something like dropbox or rsync.
+
+Another thing, this would be completely trackerless. You just use remote groups (or create swarm definitions) and share those with your remotes. It's completely decentralized!
+"""]]
diff --git a/doc/forum/Wishlist:_Don__39__t_make_files_readonly.mdwn b/doc/forum/Wishlist:_Don__39__t_make_files_readonly.mdwn
new file mode 100644
index 000000000..4d67f93b1
--- /dev/null
+++ b/doc/forum/Wishlist:_Don__39__t_make_files_readonly.mdwn
@@ -0,0 +1,3 @@
+Maybe this explained somewhere else, but what is the purpose of marking files readonly. To me this is an annoyance that doesn't make sense. I want to be able to change my files, having to go through an unlock step, to do that seems like unnecessary work. Interestingly, Microsoft's Team Foundation Server source control does the same thing and I don't like it there either.
+
+In addition why replace files with symlinks? Why not just leave the real files in place, or do the reverse and put the symlink to the file in the repository.
diff --git a/doc/forum/Wishlist:_Don__39__t_make_files_readonly/comment_1_7148527961e2d27793810966588c8d35._comment b/doc/forum/Wishlist:_Don__39__t_make_files_readonly/comment_1_7148527961e2d27793810966588c8d35._comment
new file mode 100644
index 000000000..b7a6f55f4
--- /dev/null
+++ b/doc/forum/Wishlist:_Don__39__t_make_files_readonly/comment_1_7148527961e2d27793810966588c8d35._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmL8pteP2jbYJUn1M3CbeLDvz2SWAA1wtg"
+ nickname="Kristian"
+ subject="comment 1"
+ date="2012-11-22T23:38:33Z"
+ content="""
+By using symlinks gits problems with big files goes away. You simply can't put 600 GB in a git repo - that's the way I use git-annex. Also having files read only by default eliminates the need to store two copies of all files in one form or another.
+
+
+"""]]
diff --git a/doc/forum/Wishlist:_Is_it_possible_to___34__unlock__34___files_without_copying_the_file_data__63__.mdwn b/doc/forum/Wishlist:_Is_it_possible_to___34__unlock__34___files_without_copying_the_file_data__63__.mdwn
new file mode 100644
index 000000000..1a7930fec
--- /dev/null
+++ b/doc/forum/Wishlist:_Is_it_possible_to___34__unlock__34___files_without_copying_the_file_data__63__.mdwn
@@ -0,0 +1,6 @@
+I have a DLink Boxee media player and it can not play content from symbolic links, it needs to access regular media files. Unfortunately unlocking/locking is quite slow for such a large amount of data due to the required data copying, but it should not even be needed since I do not need write access to any file to watch the movie or to play the song.
+
+Is it currently possible or would it be possible to add a commands like "unlock" which would not copy the file data but simply move files out from the data store into the tree while still keeping the files read only? A corresponding "lock" command would also be needed to restore the normal symbolic link tree structure.
+
+Update:
+I tried the rsync special remote http://git-annex.branchable.com/special_remotes/rsync/ and it works but the file structure created reflects the data store not the view given by the symbolic links.
diff --git a/doc/forum/Wishlist:_Is_it_possible_to___34__unlock__34___files_without_copying_the_file_data__63__/comment_1_1cf4ab29dfa2cff59b86305fc0018251._comment b/doc/forum/Wishlist:_Is_it_possible_to___34__unlock__34___files_without_copying_the_file_data__63__/comment_1_1cf4ab29dfa2cff59b86305fc0018251._comment
new file mode 100644
index 000000000..3ab518714
--- /dev/null
+++ b/doc/forum/Wishlist:_Is_it_possible_to___34__unlock__34___files_without_copying_the_file_data__63__/comment_1_1cf4ab29dfa2cff59b86305fc0018251._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-07-07T15:27:28Z"
+ content="""
+The rsync or directory special remotes would work if the media player uses metadata in the files, rather than directory locations.
+
+Beyond that there is the [[todo/smudge]] idea, which is hoped to be supported sometime.
+"""]]
diff --git a/doc/forum/Wishlist:_Is_it_possible_to___34__unlock__34___files_without_copying_the_file_data__63__/comment_2_f5ebb7f43dcef861ecc13373fb1e263f._comment b/doc/forum/Wishlist:_Is_it_possible_to___34__unlock__34___files_without_copying_the_file_data__63__/comment_2_f5ebb7f43dcef861ecc13373fb1e263f._comment
new file mode 100644
index 000000000..960100379
--- /dev/null
+++ b/doc/forum/Wishlist:_Is_it_possible_to___34__unlock__34___files_without_copying_the_file_data__63__/comment_2_f5ebb7f43dcef861ecc13373fb1e263f._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmL8pteP2jbYJUn1M3CbeLDvz2SWAA1wtg"
+ nickname="Kristian"
+ subject="Solution"
+ date="2011-07-31T15:24:25Z"
+ content="""
+Yes, it can read id3-tags and guess titles from movie filenames but it sometimes gets confused by the filename metadata provided by the WORM-backend.
+
+I think I have a good enough solution to this problem. It's not efficient when it comes to renames but handles adding and deletion just fine
+
+ rsync -vaL --delete source dest
+
+The -L flag looks at symbolic links and copies the actual data they are pointing to. Of course \"source\" must have all data locally for this to work.
+
+"""]]
diff --git a/doc/forum/Wishlist:_Ways_of_selecting_files_based_on_meta-information.mdwn b/doc/forum/Wishlist:_Ways_of_selecting_files_based_on_meta-information.mdwn
new file mode 100644
index 000000000..1de06f7cd
--- /dev/null
+++ b/doc/forum/Wishlist:_Ways_of_selecting_files_based_on_meta-information.mdwn
@@ -0,0 +1,15 @@
+It would be extremely useful to have some additional ways to select files (for git annex copy/move/get and maybe others) based on the meta-information available to git-annex, rather than just by file or directory name.
+
+An example of what I'd like to do is this:
+
+ host1$ git annex copy --to usb-drive --missing-on host2
+
+This would check location tracking information and copy each file from host1's annex which is not present on host2 onto the usb-drive annex -- i.e. it's what I want when I need to do a sneakernet synchronisation of host1 and host2 (for backup purposes, for example). Note that of course I could copy --to host2, assuming network connectivity, but that would take a long time.
+
+There's probably other selectors that we can imagine; an obvious one could be --present-on <annex> -- useful for judiciously dropping only those files that you have easily available in a local annex (as you may want to keep files that are hard to make available even if --numcopies would nominally be satisfied).
+
+Other similar ideas for file content selectors:
+
+ * Files that have less than n, exactly n or more than n copies -- for when you need to satisfy your --numcopies policy over sneakernet.
+ * Files that are present (or not present) on some trusted annex -- for making sure you have trusted copies of everything.
+ * Boolean combinations of these filters -- "git annex drop --present-on lanserver1 --or --present-on lanserver2" or similar syntax, although obviously doing this in full generality may be quite fiddly.
diff --git a/doc/forum/Wishlist:_Ways_of_selecting_files_based_on_meta-information/comment_1_818f38aa988177d3a9415055e084f0fb._comment b/doc/forum/Wishlist:_Ways_of_selecting_files_based_on_meta-information/comment_1_818f38aa988177d3a9415055e084f0fb._comment
new file mode 100644
index 000000000..11b44b809
--- /dev/null
+++ b/doc/forum/Wishlist:_Ways_of_selecting_files_based_on_meta-information/comment_1_818f38aa988177d3a9415055e084f0fb._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://christian.amsuess.com/chrysn"
+ nickname="chrysn"
+ subject="filtering based on git-commits"
+ date="2011-06-23T13:56:35Z"
+ content="""
+additional filter criteria could come from the git history:
+
+* `git annex get --touched-in HEAD~5..` to fetch what has recently been worked on
+* `git annex get --touched-by chrysn --touched-in version-1.0..HEAD` to fetch what i've been workin on recently (based on regexp or substring match in author; git experts could probably craft much more meaningful expressions)
+
+these options could also apply to `git annex find` -- actually, looking at the normal file system tools for such tasks, that might even be sufficient (think `git annex find --numcopies-gt 3 --present-on lanserver1 --drop` like `find -iname '*foo*' -delete`
+
+(i was about to open a new forum discussion for commit-based getting, but this is close enough to be usefully joint in a discussion)
+"""]]
diff --git a/doc/forum/Wishlist:_Ways_of_selecting_files_based_on_meta-information/comment_2_97e2ed48bd552d02918c4f98f963e6e1._comment b/doc/forum/Wishlist:_Ways_of_selecting_files_based_on_meta-information/comment_2_97e2ed48bd552d02918c4f98f963e6e1._comment
new file mode 100644
index 000000000..787cf8f5d
--- /dev/null
+++ b/doc/forum/Wishlist:_Ways_of_selecting_files_based_on_meta-information/comment_2_97e2ed48bd552d02918c4f98f963e6e1._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 2"
+ date="2011-09-19T18:46:35Z"
+ content="""
+This is now almost completely implemented. See [[walkthrough/powerful_file_matching]].
+
+"""]]
diff --git a/doc/forum/Wishlist:_automatic_reinject.mdwn b/doc/forum/Wishlist:_automatic_reinject.mdwn
new file mode 100644
index 000000000..f975c7521
--- /dev/null
+++ b/doc/forum/Wishlist:_automatic_reinject.mdwn
@@ -0,0 +1,14 @@
+I think it would be useful to supplement the `reinject` command with an automatic
+mode which calculates the checksum of the source file and injects the file if it
+is known to the repository (without the need to provide a destination filename).
+In addition, this could be done recursively if the user provides a directory to
+inject. All this can probably be done already with some plumbing, but a simple
+`reinject --auto` (or `scour`, or `scavenge`, if you like) would be a nice addition.
+Of course this would only work for the checksum backends.
+
+Example use cases would be:
+
+* Recovering data from lost+found easily
+* Making use of old (pre-git-annex) archival volumes with useful files
+ scattered among non-useful files
+* Sneaker-netting files between disconnected git-annex repositories
diff --git a/doc/forum/Wishlist:_getting_the_disk_used_by_a_subtree_of_files.mdwn b/doc/forum/Wishlist:_getting_the_disk_used_by_a_subtree_of_files.mdwn
new file mode 100644
index 000000000..7bdd93654
--- /dev/null
+++ b/doc/forum/Wishlist:_getting_the_disk_used_by_a_subtree_of_files.mdwn
@@ -0,0 +1,10 @@
+I'm not sure if this _feature_ exists already wrapped or provided as a recipe for users or not yet. But it would be nice to be able to do a
+
+ git annex du [PATH]
+
+Such that the output that git annex would return is the total disk used locally in the PATH and the theoretical disk used by the PATH if it was fully populated locally. e.g.
+
+ $ git annex du FSL0001_ANALYSIS
+ $ Local: 1000kb, Annex: 2000kb
+
+or something along the lines of that?
diff --git a/doc/forum/Wishlist:_getting_the_disk_used_by_a_subtree_of_files/comment_1_7abb1155081a23ce4829ee69b2064541._comment b/doc/forum/Wishlist:_getting_the_disk_used_by_a_subtree_of_files/comment_1_7abb1155081a23ce4829ee69b2064541._comment
new file mode 100644
index 000000000..bff5b2ea7
--- /dev/null
+++ b/doc/forum/Wishlist:_getting_the_disk_used_by_a_subtree_of_files/comment_1_7abb1155081a23ce4829ee69b2064541._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.2.25"
+ subject="comment 1"
+ date="2012-06-27T12:36:08Z"
+ content="""
+Use `du -L` for the disk space used locally. The other number is not currently available, but it would be nice to have. I also sometimes would like to have data on which backends are used how much, so making this `git annex status --subdir` is tempting. Unfortunatly, it's current implementation scans `.git/annex/objects`
+and not the disk tree (better for accurate numbers due to copies), so it would not be a very easy thing to add. Not massively hard, but not something I can pound out before I start work today..
+"""]]
diff --git a/doc/forum/Wishlist:_getting_the_disk_used_by_a_subtree_of_files/comment_2_b4c6ebada7526263e04c70eac312fda9._comment b/doc/forum/Wishlist:_getting_the_disk_used_by_a_subtree_of_files/comment_2_b4c6ebada7526263e04c70eac312fda9._comment
new file mode 100644
index 000000000..551c685d4
--- /dev/null
+++ b/doc/forum/Wishlist:_getting_the_disk_used_by_a_subtree_of_files/comment_2_b4c6ebada7526263e04c70eac312fda9._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="comment 2"
+ date="2012-06-27T12:45:42Z"
+ content="""
+I have a hacked up version of sharebox that does this.. I need to fix it up and push it to github..
+
+the short of it is that you can do
+
+ def calculate_size(path):
+ annexfile = os.path.basename(os.readlink(path))
+ #SHA256-s2007550713--....
+ size = annexfile.split(\"-\")[1]
+ return int(size[1:])
+
+to get the size of files.. a 'git-annex du' should be pretty straightforward...
+"""]]
diff --git a/doc/forum/Wishlist:_getting_the_disk_used_by_a_subtree_of_files/comment_3_ded71b270b94617a8ebb3a713d46a274._comment b/doc/forum/Wishlist:_getting_the_disk_used_by_a_subtree_of_files/comment_3_ded71b270b94617a8ebb3a713d46a274._comment
new file mode 100644
index 000000000..ddc9ae147
--- /dev/null
+++ b/doc/forum/Wishlist:_getting_the_disk_used_by_a_subtree_of_files/comment_3_ded71b270b94617a8ebb3a713d46a274._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-03-11T05:27:38Z"
+ content="""
+You can now use \"git annex status .\"
+
+Example:
+
+<pre>
+git annex status roms
+directory: roms
+local annex keys: 1
+local annex size: 248 megabytes
+known annex keys: 277
+known annex size: 12 gigabytes
+</pre>
+"""]]
diff --git a/doc/forum/Wishlist:_logging_to_file_when_running_as_a_daemon___40__for_the_assistant__41__.mdwn b/doc/forum/Wishlist:_logging_to_file_when_running_as_a_daemon___40__for_the_assistant__41__.mdwn
new file mode 100644
index 000000000..c3f915e7d
--- /dev/null
+++ b/doc/forum/Wishlist:_logging_to_file_when_running_as_a_daemon___40__for_the_assistant__41__.mdwn
@@ -0,0 +1 @@
+Logging to file would be nice when running git-annex as a daemon so when something fails or when certain events happens one can look at the logs to see what has failed, unless I'm missing something this probably should be on the wishlist or roadmap.
diff --git a/doc/forum/Wishlist:_logging_to_file_when_running_as_a_daemon___40__for_the_assistant__41__/comment_1_42aa2b61b880f4048d874210212aa63b._comment b/doc/forum/Wishlist:_logging_to_file_when_running_as_a_daemon___40__for_the_assistant__41__/comment_1_42aa2b61b880f4048d874210212aa63b._comment
new file mode 100644
index 000000000..c0746a5a7
--- /dev/null
+++ b/doc/forum/Wishlist:_logging_to_file_when_running_as_a_daemon___40__for_the_assistant__41__/comment_1_42aa2b61b880f4048d874210212aa63b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.14.60"
+ subject="comment 1"
+ date="2012-06-23T14:30:22Z"
+ content="""
+The logging format could be improved, but the daemon already logs to .git/annex/daemon.log. It also automatically rotates the log file.
+"""]]
diff --git a/doc/forum/Wishlist:_logging_to_file_when_running_as_a_daemon___40__for_the_assistant__41__/comment_2_3e201039fa0e611554171ee30e69a414._comment b/doc/forum/Wishlist:_logging_to_file_when_running_as_a_daemon___40__for_the_assistant__41__/comment_2_3e201039fa0e611554171ee30e69a414._comment
new file mode 100644
index 000000000..b1a76ce2d
--- /dev/null
+++ b/doc/forum/Wishlist:_logging_to_file_when_running_as_a_daemon___40__for_the_assistant__41__/comment_2_3e201039fa0e611554171ee30e69a414._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 1"
+ date="2012-06-23T08:00:12Z"
+ content="""
+actually, scratch that, i found it. it was in _.git/annex/daemon.log_ along with the other bits and pieces
+"""]]
diff --git a/doc/forum/Wishlist:_logging_to_file_when_running_as_a_daemon___40__for_the_assistant__41__/comment_3_d1074724c44f3296cb438b2d526d8728._comment b/doc/forum/Wishlist:_logging_to_file_when_running_as_a_daemon___40__for_the_assistant__41__/comment_3_d1074724c44f3296cb438b2d526d8728._comment
new file mode 100644
index 000000000..eb1862829
--- /dev/null
+++ b/doc/forum/Wishlist:_logging_to_file_when_running_as_a_daemon___40__for_the_assistant__41__/comment_3_d1074724c44f3296cb438b2d526d8728._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 2"
+ date="2012-07-03T14:48:16Z"
+ content="""
+Adding a date and timestamp would be a nice start to improving things.
+"""]]
diff --git a/doc/forum/Wishlist:_mark_remotes_offline.mdwn b/doc/forum/Wishlist:_mark_remotes_offline.mdwn
new file mode 100644
index 000000000..046c62210
--- /dev/null
+++ b/doc/forum/Wishlist:_mark_remotes_offline.mdwn
@@ -0,0 +1,12 @@
+I have several remotes which are not always accessible. For example they can
+be on hosts only accessible by LAN or on a portable hard drive which is not
+plugged in. When running sync these remotes are checked as well, leading to
+unnecessary error messages and possibly git-annex waiting for a few minutes
+on each remote for a timeout.
+
+In this situation it would be useful to mark some remotes as offline
+(`git annex offline <remotename>`), so that git-annex would not even attempt
+to contact them. Then, I could configure my system to automatically, for example,
+mark a portable hard disk remote online when plugging it in, and offline when
+unplugging it, and similarly marking remotes offline and online depending on
+whether I have an internet connection or a connection to a specific network.
diff --git a/doc/forum/Wishlist:_mark_remotes_offline/comment_1_9e3901f0123abb66034cce95cc5a941a._comment b/doc/forum/Wishlist:_mark_remotes_offline/comment_1_9e3901f0123abb66034cce95cc5a941a._comment
new file mode 100644
index 000000000..c24a786c9
--- /dev/null
+++ b/doc/forum/Wishlist:_mark_remotes_offline/comment_1_9e3901f0123abb66034cce95cc5a941a._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ subject="comment 1"
+ date="2012-07-06T13:04:07Z"
+ content="""
+You can already do this:
+
+ git config remote.foo.annex-ignore true
+
+There's no need to do anything for portable drives that are sometimes mounted and sometimes not -- git-annex will automatically avoid using repositories in directories that do not currently exist.
+
+I thought git-annex also had a way to run a command and use its exit status to control whether a repo was
+ignored or not, but it seems I never actually implemented that. It might be worth adding, although the command would necessarily run whenever git-annex is transferring data around.
+"""]]
diff --git a/doc/forum/Wishlist:_mark_remotes_offline/comment_2_d10e3d90cf421ae425e64ab266ea811b._comment b/doc/forum/Wishlist:_mark_remotes_offline/comment_2_d10e3d90cf421ae425e64ab266ea811b._comment
new file mode 100644
index 000000000..e14cfa822
--- /dev/null
+++ b/doc/forum/Wishlist:_mark_remotes_offline/comment_2_d10e3d90cf421ae425e64ab266ea811b._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawncBlzaDI248OZGjKQMXrLVQIx4XrZrzFo"
+ nickname="Perttu"
+ subject="comment 2"
+ date="2012-07-07T17:45:43Z"
+ content="""
+Ah, I didn't read the man page carefully enough. My apologies.
+
+Setting the ignore status based on an exit status would be
+even better, since this avoids re-writing a new config file for
+each repository each time I enter or exit my LAN.
+"""]]
diff --git a/doc/forum/Wishlist:_options_for_syncing_meta-data_and_data.mdwn b/doc/forum/Wishlist:_options_for_syncing_meta-data_and_data.mdwn
new file mode 100644
index 000000000..d1df6628e
--- /dev/null
+++ b/doc/forum/Wishlist:_options_for_syncing_meta-data_and_data.mdwn
@@ -0,0 +1,13 @@
+Since _transfer queueing_ and syncing of data works now in the assistant branch (been playing with it), there are times when I really don't want to sync the data, I would like to just sync meta-data and manually do a _get_ on files that I would want or selectively sync data in a subtree.
+
+It would be nice to have the syncing/watch feature to have the option of syncing only *meta-data* or *meta-data and data*, I think this sort of option was already planned? It would also be nice to be able to automatically sync data for only a subtree.
+
+My use case is, I have a big stash of files somewhere at home or work, and I want to keep what I am actually using on my laptop and be able to selectively just take a subtree or a set of subtree's of files. I would not always want to suck down all the data but still have the functionally to add files and push them upstream and sync meta-data.
+
+that is...
+
+> * Site A: big master annex in a server room with lots of disk (or machines), watches a directory and syncs both data and meta-data, it should always try and pull data from all it's child repos. That way I will always have a master copy of my data somewhere, it would be even nicer if I could have clones of the annex, where each annex is on a different machine which is configured to only sync a subtree of files so I can distribute my annex across different systems and disks.
+> * Site A: machine A: syncs Folder A
+> * Site A: machine B: syncs Folder B
+> * and so on with selectively syncing sites and directories
+> * Laptop: has a clone of the annex, and watches a directory, syncs meta-data as usual and only uploads files to a remote (all or a designated one) but it never downloads files automatically or it should only occur inside a selected subtree.
diff --git a/doc/forum/Wishlist:_rename_files__47__dirs_w__47___special_characters_if_filesystem_is_FAT.mdwn b/doc/forum/Wishlist:_rename_files__47__dirs_w__47___special_characters_if_filesystem_is_FAT.mdwn
new file mode 100644
index 000000000..847ff01bd
--- /dev/null
+++ b/doc/forum/Wishlist:_rename_files__47__dirs_w__47___special_characters_if_filesystem_is_FAT.mdwn
@@ -0,0 +1,5 @@
+Hi Joey,
+ I recently tried cloning a music annex to a microSD card to play on rockbox (FAT only) with my Sansa Clip, but 'git clone' stops the first time it runs into something with a special character in a file or directory, like a colon in an album title. After this happens, there doesn't seem to be a way to get a full annex file/directory listing for the annex; it only has up to where git failed since FAT can't handle the name. Is it possible for git-annex to replace special characters in directory/filenames with a space or underscore if it's on a crippled filesystem? Also, would it be possible to then clone from that annex to a non-crippled FS, preserving the original filenames with special characters? I've been meaning to ask about this for a while, so I'm a teeny bit fuzzy on the specifics...if you want, I'll reproduce the problem and cough up some more details.
+
+
+PS: I love git-annex!
diff --git a/doc/forum/Wishlist:_rename_files__47__dirs_w__47___special_characters_if_filesystem_is_FAT/comment_1_5d33bcbd862537f53edd91dcff2b8977._comment b/doc/forum/Wishlist:_rename_files__47__dirs_w__47___special_characters_if_filesystem_is_FAT/comment_1_5d33bcbd862537f53edd91dcff2b8977._comment
new file mode 100644
index 000000000..42fad62b9
--- /dev/null
+++ b/doc/forum/Wishlist:_rename_files__47__dirs_w__47___special_characters_if_filesystem_is_FAT/comment_1_5d33bcbd862537f53edd91dcff2b8977._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-04-06T21:13:44Z"
+ content="""
+I think this is a general git question, not specific to git-annex. At the point in time that you run `git clone` on the FAT filesystem, git-annex is not running at all.
+
+You could ask the git community about this. I know that git already has a core.precomposeunicode setting that is used to work around a somewhat similar problem on Mac OS.
+
+What git-annex *does* let you do is set up a [[directory_special_remote|special_remote/directory]] on the FAT filesystem. This way,
+there is no git repository there, and the filenames stored in git are not used at all on FAT. If your media player looks at mp3 metadata to get song titles, etc and doesn't care about the filenames at all, this would be a good option.
+"""]]
diff --git a/doc/forum/XBMC__44___NFS___38___git-annex_.txt b/doc/forum/XBMC__44___NFS___38___git-annex_.txt
new file mode 100644
index 000000000..fc5cd702a
--- /dev/null
+++ b/doc/forum/XBMC__44___NFS___38___git-annex_.txt
@@ -0,0 +1,27 @@
+Hi,
+
+this is not a git-annex problem, but more likely a way some software handles symlinks and/or do file-type detection.
+
+my setup is a following:
+- multiple pc/laptop (linux)
+- one NAS (debian) - main repo for music/films/photos - all in git-annex
+- a Raspberry Pi (Raspbmc) - connected to the TV
+
+I want to share all my films/music/.. to the Pi.
+So, i setup a r/o NFS and mounted that in the XBMC.
+So far this works, I see directories but XBMC do not recognize the media files.
+It works, if I "git-annex edit ..." the file.
+
+My _assumption_ is, that it follows the symlink, finds a file with no extension - and ignores that.
+In XBMC-config there is a list of supported filetypes by extension. ( .avi,.mpg,.foo,.bar )
+
+What I have think of so far:
+- tell XBMC somehow to load all the files (did not work)
+- having some kind of (FUSE?) filter, which hides the symlink in a transparent way
+- creating via script hard-links in a seperate folder with same structure, mount that.
+- using some alternative to NFS ( like ftp, smb ) or a other kind of media-server (server-side)
+
+any comments, ideas ?
+If i find a solution, I'll post it here.
+
+.ka
diff --git a/doc/forum/XBMC__44___NFS___38___git-annex_/comment_1_86480f31d410e903766f82e6ecf83e1c._comment b/doc/forum/XBMC__44___NFS___38___git-annex_/comment_1_86480f31d410e903766f82e6ecf83e1c._comment
new file mode 100644
index 000000000..e82522548
--- /dev/null
+++ b/doc/forum/XBMC__44___NFS___38___git-annex_/comment_1_86480f31d410e903766f82e6ecf83e1c._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="Samba works"
+ date="2013-05-30T14:22:46Z"
+ content="""
+I use samba. Just need to set
+
+ unix extensions = no
+
+which causes samba to handle the symlinks internally.
+"""]]
diff --git a/doc/forum/XBMC__44___NFS___38___git-annex_/comment_2_d8ed4dd51d3050db691a8abdec24cd42._comment b/doc/forum/XBMC__44___NFS___38___git-annex_/comment_2_d8ed4dd51d3050db691a8abdec24cd42._comment
new file mode 100644
index 000000000..0b3cb22c1
--- /dev/null
+++ b/doc/forum/XBMC__44___NFS___38___git-annex_/comment_2_d8ed4dd51d3050db691a8abdec24cd42._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-05-30T15:20:51Z"
+ content="""
+The default git-annex backend for over a year now is SHA256E, which includes the filename extension in the key to deal with programs that rely on them. If you're not using that backend, you can `git annex migrate` to it.
+
+Or you can turn on direct mode, which will certainly solve the problem.
+"""]]
diff --git a/doc/forum/XBMC__44___NFS___38___git-annex_/comment_3_42b80ee51ce25775bf4532f53a8ecfe3._comment b/doc/forum/XBMC__44___NFS___38___git-annex_/comment_3_42b80ee51ce25775bf4532f53a8ecfe3._comment
new file mode 100644
index 000000000..00fbf6a20
--- /dev/null
+++ b/doc/forum/XBMC__44___NFS___38___git-annex_/comment_3_42b80ee51ce25775bf4532f53a8ecfe3._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="ka7"
+ ip="2001:7b8:155d:0:222:64ff:fe16:dc52"
+ subject="comment 3"
+ date="2013-05-31T15:45:51Z"
+ content="""
+ah, great.
+I'll try the samba way.
+And i guess my git-annex is too old (using the git-annex version: 3.20120629~bpo60+2 from debian-backports)
+thanks !
+"""]]
diff --git a/doc/forum/XBMC__44___NFS___38___git-annex_/comment_4_01767f3f864954cf8080274e206da9d4._comment b/doc/forum/XBMC__44___NFS___38___git-annex_/comment_4_01767f3f864954cf8080274e206da9d4._comment
new file mode 100644
index 000000000..58f00af15
--- /dev/null
+++ b/doc/forum/XBMC__44___NFS___38___git-annex_/comment_4_01767f3f864954cf8080274e206da9d4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="ka7"
+ ip="2001:7b8:155d:0:222:64ff:fe16:dc52"
+ subject="comment 4"
+ date="2013-05-31T18:46:29Z"
+ content="""
+after a quick check I realized that sha256E is available -- migrate and yepey!
+"""]]
diff --git a/doc/forum/XMPP_authentication_failure.mdwn b/doc/forum/XMPP_authentication_failure.mdwn
new file mode 100644
index 000000000..3c4c41bc2
--- /dev/null
+++ b/doc/forum/XMPP_authentication_failure.mdwn
@@ -0,0 +1,15 @@
+Hi,
+
+Not sure if this is a bug or not, so posting it here rather than in the bug tracker.
+
+Basically, I am unable to add an XMPP identity via the webapp, I continually get the error message: "Unable to connect to the Jabber server. Maybe you entered the wrong password? (Error message: AuthenticationFailure)"
+
+I didn't enter the wrong password, I copy/pasted it from my password manager and the same account/password work fine with Pidgin. The log doesn't show anything of interest that I can see.
+
+Using git annex version 4.20130405 from Debain Unstable. The server is ejabberd running on my VPS with a self signed certificate.
+
+Anyone got any idea what might be going on?
+
+Cheers,
+
+Rob
diff --git a/doc/forum/XMPP_authentication_failure/comment_1_19c7c3aa79d209d613d2e061e3129690._comment b/doc/forum/XMPP_authentication_failure/comment_1_19c7c3aa79d209d613d2e061e3129690._comment
new file mode 100644
index 000000000..a5862e58f
--- /dev/null
+++ b/doc/forum/XMPP_authentication_failure/comment_1_19c7c3aa79d209d613d2e061e3129690._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-04-09T18:31:01Z"
+ content="""
+I installed ejabberd and was able to trivially reproduce this bug. Pidgin works, git-annex fails, and I just created the user with `ejabberdctl register`. Filed an upstream bug report against the haskell network-protocol-xmpp library, by email, since there's no upstream BTS:
+"""]]
diff --git a/doc/forum/XMPP_authentication_failure/comment_2_870059fed451e8377e5d382464ecc34b._comment b/doc/forum/XMPP_authentication_failure/comment_2_870059fed451e8377e5d382464ecc34b._comment
new file mode 100644
index 000000000..bcf4e22ac
--- /dev/null
+++ b/doc/forum/XMPP_authentication_failure/comment_2_870059fed451e8377e5d382464ecc34b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="robconnolly"
+ ip="203.167.218.84"
+ subject="comment 2"
+ date="2013-04-09T23:01:44Z"
+ content="""
+Excellent, thanks for the quick response/action!
+"""]]
diff --git a/doc/forum/XMPP_authentication_failure/comment_3_1a7ff955e9173f13d10b75f203792384._comment b/doc/forum/XMPP_authentication_failure/comment_3_1a7ff955e9173f13d10b75f203792384._comment
new file mode 100644
index 000000000..587daa0ed
--- /dev/null
+++ b/doc/forum/XMPP_authentication_failure/comment_3_1a7ff955e9173f13d10b75f203792384._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-04-12T22:25:12Z"
+ content="""
+John has gotten back to me with some analysis. The authentication failure is when SCRAM-SHA-1 is used. Ejabberd is rejecting the client's authentication request with a reason of \"bad-protocol\". It's not clear if ejabberd is broken or if gsasl is generating a bad SCRAM-SHA-1 authentication. We're inclined toward the latter, and will be forwarding this on to ejabberd.
+
+The only way to turn off this authentication in ejabberd is to configure it to store passwords in plain text, or downgrade to a version older than 2.1.9, which first added it. Note that debian stable contains 2.1.5.3, so is not currently affected, for example.
+"""]]
diff --git a/doc/forum/XMPP_authentication_failure/comment_4_d59031ebc0dd3abc1f4c96878328362c._comment b/doc/forum/XMPP_authentication_failure/comment_4_d59031ebc0dd3abc1f4c96878328362c._comment
new file mode 100644
index 000000000..e3e927818
--- /dev/null
+++ b/doc/forum/XMPP_authentication_failure/comment_4_d59031ebc0dd3abc1f4c96878328362c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 4"
+ date="2013-04-17T13:26:45Z"
+ content="""
+Upstream bug report, with patch https://support.process-one.net/browse/EJAB-1632
+"""]]
diff --git a/doc/forum/XMPP_authentication_failure/comment_5_c37ef477bef7efdb79dd05dce90dfde6._comment b/doc/forum/XMPP_authentication_failure/comment_5_c37ef477bef7efdb79dd05dce90dfde6._comment
new file mode 100644
index 000000000..37a3365d0
--- /dev/null
+++ b/doc/forum/XMPP_authentication_failure/comment_5_c37ef477bef7efdb79dd05dce90dfde6._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkF8_uQjLYm5Mf5F_JuVW-BxlvzpWjvR_o"
+ nickname="Andrew"
+ subject="Wheezy is affected"
+ date="2013-05-25T12:00:21Z"
+ content="""
+Now that Wheezy is out, Debian Stable appears to be affected by this issue. It has ejabberd v2.1.10 .
+
+The patch on the linked bug report doesn't apply cleanly to v2.1.10. I'll try and look at this again tomorrow.
+"""]]
diff --git a/doc/forum/XMPP_authentication_failure/comment_6_48cabea4c2caf5b3bd854df3aaa17d3d._comment b/doc/forum/XMPP_authentication_failure/comment_6_48cabea4c2caf5b3bd854df3aaa17d3d._comment
new file mode 100644
index 000000000..fe4ab0744
--- /dev/null
+++ b/doc/forum/XMPP_authentication_failure/comment_6_48cabea4c2caf5b3bd854df3aaa17d3d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 6"
+ date="2013-05-25T17:57:43Z"
+ content="""
+Debian has it fixed in 2.1.10-5 but this has unfortunately not made it to the wheezy release.
+"""]]
diff --git a/doc/forum/XMPP_authentication_failure/comment_7_14cd9b67806db93c3af055d88c9a910a._comment b/doc/forum/XMPP_authentication_failure/comment_7_14cd9b67806db93c3af055d88c9a910a._comment
new file mode 100644
index 000000000..38a873392
--- /dev/null
+++ b/doc/forum/XMPP_authentication_failure/comment_7_14cd9b67806db93c3af055d88c9a910a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkF8_uQjLYm5Mf5F_JuVW-BxlvzpWjvR_o"
+ nickname="Andrew"
+ subject="comment 7"
+ date="2013-05-25T20:27:32Z"
+ content="""
+Ah ha, so it is. I've installed ejabberd from Jessie onto my Wheezy box and now git-annex can authenticate.
+
+Thank you!
+"""]]
diff --git a/doc/forum/XMPP_authentication_failure/comment_8_151d3fd7d3cceb30fd20a8f3bd54036c._comment b/doc/forum/XMPP_authentication_failure/comment_8_151d3fd7d3cceb30fd20a8f3bd54036c._comment
new file mode 100644
index 000000000..2700343ca
--- /dev/null
+++ b/doc/forum/XMPP_authentication_failure/comment_8_151d3fd7d3cceb30fd20a8f3bd54036c._comment
@@ -0,0 +1,24 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnVTPaZaIfnZqDbkmW97pqxwi2QuZIJAF4"
+ nickname="Boris"
+ subject="jabberd also affected"
+ date="2013-06-25T13:00:46Z"
+ content="""
+I tried logging in to my local 'jabberd' server and got the same response:
+
+AuthenticationError \"No supported authentication mechanism\"
+
+checking the version gives:
+
+ jabberd -v
+ jabberd14 version 1.6.1.1
+
+ The following optional features have been enabled:
+ - support for IPv6.
+ - support for TLS using GNU TLS
+ - support for MySQL
+ - support for PostgreSQL
+
+--------------
+Can I do anything, investigate something?
+"""]]
diff --git a/doc/forum/XMPP_authentication_failure/comment_9_fbb9eba65fbb72201f08511945fbcf8c._comment b/doc/forum/XMPP_authentication_failure/comment_9_fbb9eba65fbb72201f08511945fbcf8c._comment
new file mode 100644
index 000000000..e019056de
--- /dev/null
+++ b/doc/forum/XMPP_authentication_failure/comment_9_fbb9eba65fbb72201f08511945fbcf8c._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.193"
+ subject="comment 9"
+ date="2013-06-25T17:18:56Z"
+ content="""
+Boris, that seems like an unrelated problem to the one affecting ejabberd. Different error message.
+
+"""]]
diff --git a/doc/forum/XMPP_email_setup_says_wrong_password_but_it__39__s_correct._Can_I_provide_some_kind_of_debug_data__63__.mdwn b/doc/forum/XMPP_email_setup_says_wrong_password_but_it__39__s_correct._Can_I_provide_some_kind_of_debug_data__63__.mdwn
new file mode 100644
index 000000000..f29637c0d
--- /dev/null
+++ b/doc/forum/XMPP_email_setup_says_wrong_password_but_it__39__s_correct._Can_I_provide_some_kind_of_debug_data__63__.mdwn
@@ -0,0 +1,9 @@
+git-annex-assistant is so exciting...
+
+Can't set up XMPP sharing. The web app says "Wrong Password" for my gmail/home-google-apps/work-google-apps addresses, but they are correct.
+
+I'd love to send some debug output, can anyone tell me how to get it? Of course if I'm just doing something wrong and you have an FAQ link or similar, feel free to RTFM me :)
+
+I'm on Ubuntu 12.04 running https://downloads.kitenet.net/git-annex/linux/3.20121112/git-annex-standalone-amd64.tar.gz
+
+Carlo
diff --git a/doc/forum/XMPP_email_setup_says_wrong_password_but_it__39__s_correct._Can_I_provide_some_kind_of_debug_data__63__/comment_1_1ba0735141fc6a21ac15913f4cacefae._comment b/doc/forum/XMPP_email_setup_says_wrong_password_but_it__39__s_correct._Can_I_provide_some_kind_of_debug_data__63__/comment_1_1ba0735141fc6a21ac15913f4cacefae._comment
new file mode 100644
index 000000000..d3f408690
--- /dev/null
+++ b/doc/forum/XMPP_email_setup_says_wrong_password_but_it__39__s_correct._Can_I_provide_some_kind_of_debug_data__63__/comment_1_1ba0735141fc6a21ac15913f4cacefae._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn7gQ1zZDdWhXy9H51W2krZYShNmKL3qfM"
+ nickname="Karsten"
+ subject="comment 1"
+ date="2012-11-13T14:38:28Z"
+ content="""
+Just an idea: Do you have two-factor-authorisation set up for your google account, you need to generate an application specific password, as the 'normal' password will not work.
+"""]]
diff --git a/doc/forum/XMPP_email_setup_says_wrong_password_but_it__39__s_correct._Can_I_provide_some_kind_of_debug_data__63__/comment_2_16994dc86b87592fc62799e2d206d172._comment b/doc/forum/XMPP_email_setup_says_wrong_password_but_it__39__s_correct._Can_I_provide_some_kind_of_debug_data__63__/comment_2_16994dc86b87592fc62799e2d206d172._comment
new file mode 100644
index 000000000..2c5f408e7
--- /dev/null
+++ b/doc/forum/XMPP_email_setup_says_wrong_password_but_it__39__s_correct._Can_I_provide_some_kind_of_debug_data__63__/comment_2_16994dc86b87592fc62799e2d206d172._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.252.11.120"
+ subject="comment 2"
+ date="2012-11-13T17:21:35Z"
+ content="""
+@Karsten that seems likely.
+
+I've made a change so it shows the error message from the XMPP library I'm using. Which may or may not be useful..
+"""]]
diff --git a/doc/forum/XMPP_email_setup_says_wrong_password_but_it__39__s_correct._Can_I_provide_some_kind_of_debug_data__63__/comment_3_6afd424edc4095b8f71b136de2a9e64d._comment b/doc/forum/XMPP_email_setup_says_wrong_password_but_it__39__s_correct._Can_I_provide_some_kind_of_debug_data__63__/comment_3_6afd424edc4095b8f71b136de2a9e64d._comment
new file mode 100644
index 000000000..eab2e796b
--- /dev/null
+++ b/doc/forum/XMPP_email_setup_says_wrong_password_but_it__39__s_correct._Can_I_provide_some_kind_of_debug_data__63__/comment_3_6afd424edc4095b8f71b136de2a9e64d._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnZEanlyzay_QlEAL0CWpyZcRTyN7vay8U"
+ nickname="Carlo"
+ subject="XMPP"
+ date="2012-11-13T23:26:50Z"
+ content="""
+Just tried a fresh jabber.org address, same error.
+
+Will see if I can get the changed version built. Or are there nightlies?
+"""]]
diff --git a/doc/forum/XMPP_email_setup_says_wrong_password_but_it__39__s_correct._Can_I_provide_some_kind_of_debug_data__63__/comment_4_1381b6a927410642c6a93aa8354be791._comment b/doc/forum/XMPP_email_setup_says_wrong_password_but_it__39__s_correct._Can_I_provide_some_kind_of_debug_data__63__/comment_4_1381b6a927410642c6a93aa8354be791._comment
new file mode 100644
index 000000000..9cdca6fc1
--- /dev/null
+++ b/doc/forum/XMPP_email_setup_says_wrong_password_but_it__39__s_correct._Can_I_provide_some_kind_of_debug_data__63__/comment_4_1381b6a927410642c6a93aa8354be791._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnZEanlyzay_QlEAL0CWpyZcRTyN7vay8U"
+ nickname="Carlo"
+ subject="Now Works! For jabber.org, gmail, but NOT google apps"
+ date="2012-11-27T11:40:43Z"
+ content="""
+Hi again!
+
+With the latest version, 3.20121126, pairing works for both something@gmail.com and something@jabber.org! Yay!
+
+What still fails is my google apps address, something@somedomain.com, seems to behave same as before. the assistant says
+
+ Unable to connect to the Jabber server. Maybe you entered the wrong password? (Error message: connect: timeout (Connection timed out))
+
+If you would like a google apps address on my domain, so you don't have to set up your own, just let me know.
+
+"""]]
diff --git a/doc/forum/XMPP_email_setup_says_wrong_password_but_it__39__s_correct._Can_I_provide_some_kind_of_debug_data__63__/comment_5_c5b33c7a8aa8e6d0f9349510dac2366d._comment b/doc/forum/XMPP_email_setup_says_wrong_password_but_it__39__s_correct._Can_I_provide_some_kind_of_debug_data__63__/comment_5_c5b33c7a8aa8e6d0f9349510dac2366d._comment
new file mode 100644
index 000000000..58fb0242b
--- /dev/null
+++ b/doc/forum/XMPP_email_setup_says_wrong_password_but_it__39__s_correct._Can_I_provide_some_kind_of_debug_data__63__/comment_5_c5b33c7a8aa8e6d0f9349510dac2366d._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.49"
+ subject="comment 5"
+ date="2012-11-27T20:32:47Z"
+ content="""
+Hmm, I can't think of anything I've changed that would make it work where it didn't before.
+
+I suspect the google apps problem is because it looks for a SRV record in DNS to find the jabber server, and something is wrong there. Without knowing what \"something@somedomain.com\" is standing for, it's hard to tell. :)
+
+If you'd like to set me up something to test with, my email address is id@joeyh.name
+"""]]
diff --git a/doc/forum/XMPP_email_setup_says_wrong_password_but_it__39__s_correct._Can_I_provide_some_kind_of_debug_data__63__/comment_6_9913d2983ba2744ed24911f74988e4c7._comment b/doc/forum/XMPP_email_setup_says_wrong_password_but_it__39__s_correct._Can_I_provide_some_kind_of_debug_data__63__/comment_6_9913d2983ba2744ed24911f74988e4c7._comment
new file mode 100644
index 000000000..cc633e8fb
--- /dev/null
+++ b/doc/forum/XMPP_email_setup_says_wrong_password_but_it__39__s_correct._Can_I_provide_some_kind_of_debug_data__63__/comment_6_9913d2983ba2744ed24911f74988e4c7._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnZEanlyzay_QlEAL0CWpyZcRTyN7vay8U"
+ nickname="Carlo"
+ subject="comment 6"
+ date="2012-11-29T15:37:46Z"
+ content="""
+Weird, 20121112 works too now.
+
+Looks like some kind of edge case... I'll let you know if I find it.
+
+"""]]
diff --git a/doc/forum/XMPP_email_setup_says_wrong_password_but_it__39__s_correct._Can_I_provide_some_kind_of_debug_data__63__/comment_7_ad6f385a2b95803eb9d81dfe76359551._comment b/doc/forum/XMPP_email_setup_says_wrong_password_but_it__39__s_correct._Can_I_provide_some_kind_of_debug_data__63__/comment_7_ad6f385a2b95803eb9d81dfe76359551._comment
new file mode 100644
index 000000000..de8403c52
--- /dev/null
+++ b/doc/forum/XMPP_email_setup_says_wrong_password_but_it__39__s_correct._Can_I_provide_some_kind_of_debug_data__63__/comment_7_ad6f385a2b95803eb9d81dfe76359551._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlutNrg7ajiNAfi5gqJfD8crv0aimZa27k"
+ nickname="Chuck"
+ subject="I'm having this problem too"
+ date="2013-07-21T19:14:21Z"
+ content="""
+I'm a git-annex newbie looking for Dropbox-like functionality. I've got git-annex and the webapp running on my desktop and laptop, and I believe I've got a Jabber account working since Kopete seems happy with my account info. But when I enter the correct Gmail UID and password I get the above error.
+
+I'm running the version of git-annex that's current in the standard Ubuntu repos (I'm actually running Kubuntu if that matters), and that version is 20121112ubuntu2. If this is an issue that was fixed in the 20121126 release, how would I get that? Doing the standard install gets me the version I have now...
+"""]]
diff --git a/doc/forum/_Does_git_annex_find___40____38___friends__41___batch_queries_to_the_location_log__63__.mdwn b/doc/forum/_Does_git_annex_find___40____38___friends__41___batch_queries_to_the_location_log__63__.mdwn
new file mode 100644
index 000000000..a9db915da
--- /dev/null
+++ b/doc/forum/_Does_git_annex_find___40____38___friends__41___batch_queries_to_the_location_log__63__.mdwn
@@ -0,0 +1,45 @@
+Hi,
+
+Some time ago I asked [[here|git_annex_copy_--fast_--to_blah_much_slower_than_--from_blah]]
+about possible improvements in git `copy --fast --to`, since it was painfully slow
+on moderately large repos.
+
+Now I found a way to make it much faster for my particular use case, by
+accessing some annex internals. And I realized that maybe commands like `git
+annex find --in=repo` do not batch queries to the location log. This is based on
+the following timings, on a new repo (only a few commits) and about 30k files.
+
+ > time git annex find --in=skynet > /dev/null
+
+ real 0m55.838s
+ user 0m30.000s
+ sys 0m1.583s
+
+
+ > time git ls-tree -r git-annex | cut -d ' ' -f 3 | cut -f 1 | git cat-file --batch > /dev/null
+
+ real 0m0.334s
+ user 0m0.517s
+ sys 0m0.030s
+
+Those numbers are on linux (with an already warm file cache) and an ext4 filesystem on a SSD.
+
+The second command above is feeding a list of objects to a single `git cat-file`
+process that cats them all to stdout, preceeding every file dump by the object
+being cat-ed. It is a trivial matter to parse this output and use it for
+whatever annex needs.
+
+Above I wrote a `git ls-tree` on the git-annex branch for simplicity, but we could
+just as well do a `ls-tree | ... | git cat-file` on HEAD to get the keys for the
+annexed files matching some path and then feed those keys to a cat-file on
+the git-annex branch. And this still would be an order of magnitude faster than
+what currently annex seems to do.
+
+I'm assuming the bottleneck is in that annex does not batch the `cat-file`, as the rest of logic needed for a find will be fast. Is that right?
+
+Now, if the queries to the location log for `copy --to` and `find` could be batched this way, the
+performance of several useful things to do, like checking how many annexed files
+we are missing, would be bastly improved. Hell, I could even put that number on
+the command line prompt!
+
+I'm not yet very fluent in Haskell, but I'm willing to help if this is something that makes sense and can be done.
diff --git a/doc/forum/_Does_git_annex_find___40____38___friends__41___batch_queries_to_the_location_log__63__/comment_1_01cbfc513c790faef3a3ede5315d3589._comment b/doc/forum/_Does_git_annex_find___40____38___friends__41___batch_queries_to_the_location_log__63__/comment_1_01cbfc513c790faef3a3ede5315d3589._comment
new file mode 100644
index 000000000..6b4a6b2a0
--- /dev/null
+++ b/doc/forum/_Does_git_annex_find___40____38___friends__41___batch_queries_to_the_location_log__63__/comment_1_01cbfc513c790faef3a3ede5315d3589._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 1"
+ date="2013-11-06T22:21:33Z"
+ content="""
+git-annex uses cat-file --batch, yes. You can verify this with --debug. Or you can read Annex/CatFile.hs and Git/CatFile.hs
+
+git-annex has to ensure that the git-annex branch is up-to-date and that any info synced into the repository is merged into it. This can require several calls to git log. Your command does not do that. git-annex find also runs `git ls-files --cached`, which has to examine the state of the index and of files on disk, in order to only show files that are in the working tree. Your command also omits that.
+"""]]
diff --git a/doc/forum/_Does_git_annex_find___40____38___friends__41___batch_queries_to_the_location_log__63__/comment_2_fe28dfb360caa12d5d5bc186def3eb45._comment b/doc/forum/_Does_git_annex_find___40____38___friends__41___batch_queries_to_the_location_log__63__/comment_2_fe28dfb360caa12d5d5bc186def3eb45._comment
new file mode 100644
index 000000000..4ba4c8264
--- /dev/null
+++ b/doc/forum/_Does_git_annex_find___40____38___friends__41___batch_queries_to_the_location_log__63__/comment_2_fe28dfb360caa12d5d5bc186def3eb45._comment
@@ -0,0 +1,35 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkkyBDsfOB7JZvPZ4a8F3rwv0wk6Nb9n48"
+ nickname="Abdó"
+ subject="comment 2"
+ date="2013-11-06T23:14:03Z"
+ content="""
+Ok, then I don't understand where annex spends its time. git annex takes 55
+seconds! vs less than a second for a batched query on all the keys in the
+location log. Checking that branches are in sync, or traversing the working dir
+shouldn't amount the extra 54 seconds! At least not on a recently synced repo
+with up to date index and clean working dir.
+
+> git-annex has to ensure that the git-annex branch is up-to-date and that any info synced into the repository is merged into it. This can require several calls to git log
+
+Ok, I understand that. Checking that should be typically fast though, isn't it? On a repo that has just been synced, it doesn't need to go very far on the log.
+
+> git-annex find also runs git ls-files --cached, which has to examine the state of the index and of files on disk, in order to only show files that are in the working tree
+
+I understand that too. For my particular use case, I know I do the `git copy` when the
+repo is in sync and the working dir has no uncommited changes. So I use HEAD to retrieve the keys for
+the files in the working tree. I do something like that:
+
+ time git ls-tree -r HEAD | grep -e '^120000' | cut -d ' ' -f 3 | cut -f 1 | git cat-file --batch > /dev/null
+
+ real 0m0.178s
+ user 0m0.277s
+ sys 0m0.037s
+
+That plus some fast parsing of the output gets the list of keys for the files in HEAD in less than a second. Where do the 54 extra seconds hide, then?
+
+Mm... how does annex retrieve the keys for files in the working tree? Does it follow
+the actual symlinks on the filesystem? I can believe that following 30k symlinks may be slow (although not 55 second slow).
+
+Sorry for being so insistent on this... It is just that I do think the same can be done much faster, and such an improvement in performance would be very interesting, not only for me.
+"""]]
diff --git a/doc/forum/_Does_git_annex_find___40____38___friends__41___batch_queries_to_the_location_log__63__/comment_3_9bb30ab62febe4ef63bed49f831a473a._comment b/doc/forum/_Does_git_annex_find___40____38___friends__41___batch_queries_to_the_location_log__63__/comment_3_9bb30ab62febe4ef63bed49f831a473a._comment
new file mode 100644
index 000000000..c92be8ad5
--- /dev/null
+++ b/doc/forum/_Does_git_annex_find___40____38___friends__41___batch_queries_to_the_location_log__63__/comment_3_9bb30ab62febe4ef63bed49f831a473a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 3"
+ date="2013-11-07T18:12:09Z"
+ content="""
+It's hard to say until some profiling has actually been done. Comparing apples and oranges, or perhaps better to say, orange blossoms and oranges, is not very useful.
+"""]]
diff --git a/doc/forum/_Does_git_annex_find___40____38___friends__41___batch_queries_to_the_location_log__63__/comment_4_7832f0347a41b8204538c01b72487803._comment b/doc/forum/_Does_git_annex_find___40____38___friends__41___batch_queries_to_the_location_log__63__/comment_4_7832f0347a41b8204538c01b72487803._comment
new file mode 100644
index 000000000..3e7eb01db
--- /dev/null
+++ b/doc/forum/_Does_git_annex_find___40____38___friends__41___batch_queries_to_the_location_log__63__/comment_4_7832f0347a41b8204538c01b72487803._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkkyBDsfOB7JZvPZ4a8F3rwv0wk6Nb9n48"
+ nickname="Abdó"
+ subject="comment 4"
+ date="2013-11-07T18:40:27Z"
+ content="""
+Ok, thanks.
+
+I understand that annex is more sophisticated than what I'm proposing. I'm also
+not comparing apples to oranges, what I'm saying is this: All the
+logic and checking and git calls that I thought annex needs to do, take
+much much less time than those 55 seconds. So either I'm missing something big (about 98% of it in execution time), or
+annex is doing something very inefficient. That's all I'm saying, and I was
+hoping that you could clarify that, since you already know the code.
+
+Also I'm sorry for being so annoying. If annex were writen in C, I would either have understood those 55 seconds or sent you a patch making annex faster. Being in
+haskell means that it will take me considerably more time and effort. But if I manage to
+improve things and if it is ok with you I'll send you patches... eventually.
+"""]]
diff --git a/doc/forum/__34__Pairing__34___more_than_two_computers.mdwn b/doc/forum/__34__Pairing__34___more_than_two_computers.mdwn
new file mode 100644
index 000000000..099c7a663
--- /dev/null
+++ b/doc/forum/__34__Pairing__34___more_than_two_computers.mdwn
@@ -0,0 +1,11 @@
+I need some help understanding here.
+
+We use AeroFS at work to sync the normal user files across computers. I'll quite likely be replacing that with git annex as soon as Windows port is stable enough.
+
+How it works is that you create a repo, and share it with one or more users. Then AeroFS discovers what other repos are online and if they're on the local network, and syncs from wherever is most convenient.
+
+This sounds a little like pairing, but with pairing you need to arrange more than 2 devices in a "star" or "chain". This is fine for my own devices, but it becomes brittle if you have lots of devices syncing from each other, which may or may not be online at any given time. The only way around it seems to be to pair each device with each other device, with the labor rising exponentially.
+
+Is this correct? Best compromise for my use case seems to be to just do a star setup and pair everything with an always-on machine. Do you agree?
+
+Thanks! Carlo
diff --git a/doc/forum/__34__Pairing__34___more_than_two_computers/comment_1_80f7a4bb3c66b11e566043407b611bbf._comment b/doc/forum/__34__Pairing__34___more_than_two_computers/comment_1_80f7a4bb3c66b11e566043407b611bbf._comment
new file mode 100644
index 000000000..026681f79
--- /dev/null
+++ b/doc/forum/__34__Pairing__34___more_than_two_computers/comment_1_80f7a4bb3c66b11e566043407b611bbf._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="64.134.31.139"
+ subject="comment 1"
+ date="2013-10-22T17:41:58Z"
+ content="""
+You're basically correct. Typically if you have a central machine, it's a server, so at that point you're not pairing, but are just adding a ssh server, or some other type of remote.
+
+I think that systems like AeroFS are pretty neat, but my goal is not really to build another one of those. I'd rather make git-annex be able to use such things as [[special_remotes]].
+"""]]
diff --git a/doc/forum/__34__du__34___equivalent_on_an_annex__63__.mdwn b/doc/forum/__34__du__34___equivalent_on_an_annex__63__.mdwn
new file mode 100644
index 000000000..7485958c0
--- /dev/null
+++ b/doc/forum/__34__du__34___equivalent_on_an_annex__63__.mdwn
@@ -0,0 +1,5 @@
+One reason to use git-annex is to save disk space by tossing files you don't use that often.
+
+I can find big files in the repository with git annex find --largerthan=100M, but is there a way to find large *directories*? In an ordinary filesystem I'd use "du -h" with a maxdepth to get an idea of what parts of a directory are taking up my disk space, but obviously that won't work with git annex because all the content is in .git/annex. Any ideas?
+
+(I can get a listing of file sizes in a directory with the handy -L flag of ls -- "ls -lL" shows me the sizes of the link targets -- but that won't summarize all the sizes of subdirectories. Unless my ls-fu is just weak.)
diff --git a/doc/forum/__34__du__34___equivalent_on_an_annex__63__/comment_1_a41bd02361aa961e5285aeaf1ea062be._comment b/doc/forum/__34__du__34___equivalent_on_an_annex__63__/comment_1_a41bd02361aa961e5285aeaf1ea062be._comment
new file mode 100644
index 000000000..0b69a4142
--- /dev/null
+++ b/doc/forum/__34__du__34___equivalent_on_an_annex__63__/comment_1_a41bd02361aa961e5285aeaf1ea062be._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://sunny256.sunbase.org/"
+ nickname="sunny256"
+ subject="comment 1"
+ date="2012-11-28T23:21:11Z"
+ content="""
+du(1) also accepts the -L option, so if you for example want to find what directories occupies most storage:
+
+ $ du -L | sort -n
+"""]]
diff --git a/doc/forum/__34__du__34___equivalent_on_an_annex__63__/comment_2_28ba62a546f5cc8f416491423d743d8a._comment b/doc/forum/__34__du__34___equivalent_on_an_annex__63__/comment_2_28ba62a546f5cc8f416491423d743d8a._comment
new file mode 100644
index 000000000..019cb8b81
--- /dev/null
+++ b/doc/forum/__34__du__34___equivalent_on_an_annex__63__/comment_2_28ba62a546f5cc8f416491423d743d8a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://sunny256.sunbase.org/"
+ nickname="sunny256"
+ subject="comment 2"
+ date="2012-11-28T23:24:11Z"
+ content="""
+And if you want to find the biggest files in a directory tree:
+
+ $ find -type l -print0 | xargs -0 du -L | sort -n | tail -500
+"""]]
diff --git a/doc/forum/__34__du__34___equivalent_on_an_annex__63__/comment_3_8d97f40c1d14b7230f3656a00a99cf80._comment b/doc/forum/__34__du__34___equivalent_on_an_annex__63__/comment_3_8d97f40c1d14b7230f3656a00a99cf80._comment
new file mode 100644
index 000000000..0a11f7cc9
--- /dev/null
+++ b/doc/forum/__34__du__34___equivalent_on_an_annex__63__/comment_3_8d97f40c1d14b7230f3656a00a99cf80._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 3"
+ date="2012-11-29T02:03:24Z"
+ content="""
+Sweet! I should have RTFM a bit more. Thanks. :)
+"""]]
diff --git a/doc/forum/__34__du__34___equivalent_on_an_annex__63__/comment_4_baa8fbbdd5c449a0dc2bb622cb4a47ce._comment b/doc/forum/__34__du__34___equivalent_on_an_annex__63__/comment_4_baa8fbbdd5c449a0dc2bb622cb4a47ce._comment
new file mode 100644
index 000000000..227c74b02
--- /dev/null
+++ b/doc/forum/__34__du__34___equivalent_on_an_annex__63__/comment_4_baa8fbbdd5c449a0dc2bb622cb4a47ce._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="Steve"
+ ip="92.104.175.136"
+ subject="comment 4"
+ date="2012-11-29T23:51:21Z"
+ content="""
+I've been thinking about writing a sort of git-annex du. I'm surprised to find someone else looking for such a thing. While \"du -L\" will tell you how much space is used by files you actually have, I was interested in knowing (approximately) how much space would be used if you were to git-annex get everything you don't yet have.
+
+There are many options and variations to think about, such as:
+
+* do you want to count duplicate files once or as many times as they appear (as if you 'git-annex lock'd them all)
+* maybe you want to know how much space is used by files that reside only on a certain remote or set of remotes
+* you might want to know how much space would be used by all the files you don't yet have, but not count the files you already have
+
+All of the backends so so far seem to store the size of the files in the filename, so my plan was to read it out of the links. If anybody has a better idea about how to get the sizes of annexed files or options that would be handy for a git-annex du, let me know. I'll see if I can get the start of something useful this weekend. I'll post here when I have something to share.
+
+I'm also open to suggestions for the executable name. Right now I'm thinking \"gadu\" for git-annex disk usage.
+"""]]
diff --git a/doc/forum/__34__du__34___equivalent_on_an_annex__63__/comment_5_2ee6cbbfe54a2e7b6e8eb539c18e663d._comment b/doc/forum/__34__du__34___equivalent_on_an_annex__63__/comment_5_2ee6cbbfe54a2e7b6e8eb539c18e663d._comment
new file mode 100644
index 000000000..021614405
--- /dev/null
+++ b/doc/forum/__34__du__34___equivalent_on_an_annex__63__/comment_5_2ee6cbbfe54a2e7b6e8eb539c18e663d._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://sunny256.sunbase.org/"
+ nickname="sunny256"
+ subject="comment 5"
+ date="2012-11-30T00:29:44Z"
+ content="""
+Steve, that would be a very useful utility. I've been thinking of such a tool, but haven't gotten around to write it yet. It would be practical to have before copying big/many files from another drive. If I've been short of free space, I've executed `du -L` in the source directory, but that's a bit cumbersome.
+
+And \"gadu\" is a fine name, yes. Goes well along with my \"ga\" shortcut for \"git annex\", which I created two hours after I started using git-annex. I've probably saved thousands of keystrokes because of that. &#x263a;
+"""]]
diff --git a/doc/forum/__34__du__34___equivalent_on_an_annex__63__/comment_6_48f6a2761a34b7f991325f1d24e2c5ff._comment b/doc/forum/__34__du__34___equivalent_on_an_annex__63__/comment_6_48f6a2761a34b7f991325f1d24e2c5ff._comment
new file mode 100644
index 000000000..1c456e24b
--- /dev/null
+++ b/doc/forum/__34__du__34___equivalent_on_an_annex__63__/comment_6_48f6a2761a34b7f991325f1d24e2c5ff._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="Steve"
+ ip="92.104.175.136"
+ subject="gadu 0.01 is up"
+ date="2012-12-08T06:22:50Z"
+ content="""
+I've got an initial try at gadu up over at <http://git-annex.mysteryvortex.com/git-annex-utils.html> I created a separate thread for it: <http://git-annex.branchable.com/forum/gadu_-_git-annex_disk_usage/>
+"""]]
diff --git a/doc/forum/__34__du__34___equivalent_on_an_annex__63__/comment_7_d632baff41b8582f1a79bc5018c68545._comment b/doc/forum/__34__du__34___equivalent_on_an_annex__63__/comment_7_d632baff41b8582f1a79bc5018c68545._comment
new file mode 100644
index 000000000..6fa2659f9
--- /dev/null
+++ b/doc/forum/__34__du__34___equivalent_on_an_annex__63__/comment_7_d632baff41b8582f1a79bc5018c68545._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/2grhJvAC049fJnvALDXek.6MRZMTlg--#eec89"
+ nickname="John"
+ subject="Also try sizes"
+ date="2013-01-02T22:05:39Z"
+ content="""
+The \"sizes\" tool on Hackage is a git-annex aware du-like utility. Just give it the \"-A\" flag to have it interpret annex symlinks as if they were normal files, and to also ignore files inside a .git/annex.
+"""]]
diff --git a/doc/forum/__34__git_annex_copy_--to___60__REMOTE__62___.__34___doesn__39__t_send_it_to_working_directory..mdwn b/doc/forum/__34__git_annex_copy_--to___60__REMOTE__62___.__34___doesn__39__t_send_it_to_working_directory..mdwn
new file mode 100644
index 000000000..ea0ad80ba
--- /dev/null
+++ b/doc/forum/__34__git_annex_copy_--to___60__REMOTE__62___.__34___doesn__39__t_send_it_to_working_directory..mdwn
@@ -0,0 +1,11 @@
+I tried to "git annex copy --to SSH-REMOTE" it says it sends it:
+copy Test (checking SSH-REMOTE...) (to SSH-REMOTE...)
+SHA256E-s6--8283daccd02d2b2797da53446d367e39dc0fb1615bcae4274460f44455bd9822
+ 6 100% 0.00kB/s 0:00:00 (xfer#1, to-check=0/1)
+
+sent 146 bytes received 31 bytes 354.00 bytes/sec
+total size is 6 speedup is 0.03
+ok
+(Recording state in git...)
+
+But I can't find it in the working directory. Can anyone help me?
diff --git a/doc/forum/__34__git_annex_copy_--to___60__REMOTE__62___.__34___doesn__39__t_send_it_to_working_directory./comment_1_0c0a5999a92bf5880f2113177dc67cc2._comment b/doc/forum/__34__git_annex_copy_--to___60__REMOTE__62___.__34___doesn__39__t_send_it_to_working_directory./comment_1_0c0a5999a92bf5880f2113177dc67cc2._comment
new file mode 100644
index 000000000..18c41f1c9
--- /dev/null
+++ b/doc/forum/__34__git_annex_copy_--to___60__REMOTE__62___.__34___doesn__39__t_send_it_to_working_directory./comment_1_0c0a5999a92bf5880f2113177dc67cc2._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://www.rfc1149.net/"
+ nickname="Sam"
+ subject="comment 1"
+ date="2013-08-05T09:49:56Z"
+ content="""
+`git annex copy` will only push objects (content) into git annex private directory. You have to issue a `git annex merge` (or `git annex sync`) on the receiving end, or run `git annex assistant` there to update the working directory.
+
+Note that you can run `git annex merge` as a post-update hook if you want this to be done automatically.
+
+"""]]
diff --git a/doc/forum/__34__git_annex_copy_--to___60__REMOTE__62___.__34___doesn__39__t_send_it_to_working_directory./comment_2_c18083d9054f66f0bd51d63452af07eb._comment b/doc/forum/__34__git_annex_copy_--to___60__REMOTE__62___.__34___doesn__39__t_send_it_to_working_directory./comment_2_c18083d9054f66f0bd51d63452af07eb._comment
new file mode 100644
index 000000000..da0a86929
--- /dev/null
+++ b/doc/forum/__34__git_annex_copy_--to___60__REMOTE__62___.__34___doesn__39__t_send_it_to_working_directory./comment_2_c18083d9054f66f0bd51d63452af07eb._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmqaNwDQ367zpW6cIRviLz6zJZZFODgoEI"
+ nickname="Zack"
+ subject="It worked!"
+ date="2013-08-05T09:57:25Z"
+ content="""
+Thanks for the help, it worked.
+"""]]
diff --git a/doc/forum/__34__git_annex_lock__34___very_slow_for_big_repo.mdwn b/doc/forum/__34__git_annex_lock__34___very_slow_for_big_repo.mdwn
new file mode 100644
index 000000000..9bacf28dc
--- /dev/null
+++ b/doc/forum/__34__git_annex_lock__34___very_slow_for_big_repo.mdwn
@@ -0,0 +1,7 @@
+I found the command "git annex lock" very slow (much slower than the initial "git annex add" with SHA1), for a not so big directory, when run in a big repo.
+It seems that each underlying git command is not fast, so I thought it would be better to run them once with all files as arguments.
+I had to stop the lock command, and ran "git checkout ." (I did not change any file), is this a correct alternative?
+
+Thanks a LOT for this software, one that I missed since a long time (but wasn't able to write)!
+
+Rafaël
diff --git a/doc/forum/__34__git_annex_lock__34___very_slow_for_big_repo/comment_1_044f1c5e5f7a939315c28087495a8ba8._comment b/doc/forum/__34__git_annex_lock__34___very_slow_for_big_repo/comment_1_044f1c5e5f7a939315c28087495a8ba8._comment
new file mode 100644
index 000000000..0e2773bda
--- /dev/null
+++ b/doc/forum/__34__git_annex_lock__34___very_slow_for_big_repo/comment_1_044f1c5e5f7a939315c28087495a8ba8._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="fixed"
+ date="2011-05-31T18:51:13Z"
+ content="""
+Running `git checkout` by hand is fine, of course.
+
+Underlying problem is that git has some O(N) scalability of operations on the index with regards to the number of files in the repo. So a repo with a whole lot of files will have a big index, and any operation that changes the index, like the `git reset` this needs to do, has to read in the entire index, and write out a new, modified version. It seems that git could be much smarter about its index data structures here, but I confess I don't understand the index's data structures at all. I hope someone takes it on, as git's scalability to number of files in the repo is becoming a new pain point, now that scalability to large files is \"solved\". ;)
+
+Still, it is possible to speed this up at git-annex's level. Rather than doing a `git reset` followed by a git checkout, it can just `git checkout HEAD -- file`, and since that's one command, it can then be fed into the queueing machinery in git-annex (that exists mostly to work around this git malfescence), and so only a single git command will need to be run to lock multiple files.
+
+I've just implemented the above. In my music repo, this changed an lock of a CD's worth of files from taking ctrl-c long to 1.75 seconds. Enjoy!
+
+(Hey, this even speeds up the one file case greatly, since `git reset -- file` is slooooow -- it seems to scan the *entire* repository tree. Yipes.)
+"""]]
diff --git a/doc/forum/__34__git_annex_lock__34___very_slow_for_big_repo/comment_2_e854b93415d5ab80eda8e3be3b145ec2._comment b/doc/forum/__34__git_annex_lock__34___very_slow_for_big_repo/comment_2_e854b93415d5ab80eda8e3be3b145ec2._comment
new file mode 100644
index 000000000..9e9e778ce
--- /dev/null
+++ b/doc/forum/__34__git_annex_lock__34___very_slow_for_big_repo/comment_2_e854b93415d5ab80eda8e3be3b145ec2._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnpdM9F8VbtQ_H5PaPMpGSxPe_d5L1eJ6w"
+ nickname="Rafaël"
+ subject="comment 2"
+ date="2011-05-31T21:43:22Z"
+ content="""
+Nice!
+So if I understand correctly, 'git reset -- file' was there to discard staged (but not commited) changes made to 'file', before checking out, so that it is equivalent to directly 'git checkout HEAD -- file' ?
+I'm curious about the \"queueing machinery in git-annex\": does it end up calling the one git command with multiple files as arguments? does it correspond to the message \"(Recording state in git...)\" ?
+Thanks!
+
+
+"""]]
diff --git a/doc/forum/__34__git_annex_lock__34___very_slow_for_big_repo/comment_3_95c110500bc54013bc1969c1a9c8f842._comment b/doc/forum/__34__git_annex_lock__34___very_slow_for_big_repo/comment_3_95c110500bc54013bc1969c1a9c8f842._comment
new file mode 100644
index 000000000..87da0c396
--- /dev/null
+++ b/doc/forum/__34__git_annex_lock__34___very_slow_for_big_repo/comment_3_95c110500bc54013bc1969c1a9c8f842._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 3"
+ date="2011-05-31T21:54:23Z"
+ content="""
+@Rafaël , you're correct on all counts.
+"""]]
diff --git a/doc/forum/__34__next_time_Im_online_I_would_like_to_have_file_x_y_z__34__.mdwn b/doc/forum/__34__next_time_Im_online_I_would_like_to_have_file_x_y_z__34__.mdwn
new file mode 100644
index 000000000..a5492dc86
--- /dev/null
+++ b/doc/forum/__34__next_time_Im_online_I_would_like_to_have_file_x_y_z__34__.mdwn
@@ -0,0 +1,5 @@
+git-annex is seriously cool, however I havent figured out an important detail:
+in the short presentation Richard Hartmann mentions the Nomad use case and says "... next time Im online I would like to have file x y z ... "
+How can this be achieved exactly? If I do a git annex copy/get then it will want to do it instantly, not queuing it.
+thanks a lot!
+Aron
diff --git a/doc/forum/__34__next_time_Im_online_I_would_like_to_have_file_x_y_z__34__/comment_1_bfeb1446dee4d2f52ef25fabfb8cc8f6._comment b/doc/forum/__34__next_time_Im_online_I_would_like_to_have_file_x_y_z__34__/comment_1_bfeb1446dee4d2f52ef25fabfb8cc8f6._comment
new file mode 100644
index 000000000..0789316dc
--- /dev/null
+++ b/doc/forum/__34__next_time_Im_online_I_would_like_to_have_file_x_y_z__34__/comment_1_bfeb1446dee4d2f52ef25fabfb8cc8f6._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="comment 1"
+ date="2012-07-19T14:41:39Z"
+ content="""
+What I do for this is maintain a `todo` directory and `cp -a` + `git annex add` files I want to download into this directory.
+the `cp -a` maintains the symlinks and `git annex add` fixes them if needed.
+
+Also this works the same way if the situation is reversed and the machine you want to download the files onto is not online. You can add files to the `todo` directory on the server, then once the client machine is online do a `git annex sync` + `git annex get todo`.
+"""]]
diff --git a/doc/forum/__34__next_time_Im_online_I_would_like_to_have_file_x_y_z__34__/comment_2_e60f2bbc1c058993472fd920edbc75fc._comment b/doc/forum/__34__next_time_Im_online_I_would_like_to_have_file_x_y_z__34__/comment_2_e60f2bbc1c058993472fd920edbc75fc._comment
new file mode 100644
index 000000000..b0a8066ee
--- /dev/null
+++ b/doc/forum/__34__next_time_Im_online_I_would_like_to_have_file_x_y_z__34__/comment_2_e60f2bbc1c058993472fd920edbc75fc._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnbBRfl5F8gKRr1ko8Ai6FbEZStXXNF1S4"
+ nickname="Áron"
+ subject="comment 2"
+ date="2012-07-19T22:41:53Z"
+ content="""
+hmm not bad workaround but still not very comfortable, thanks though.
+"""]]
diff --git a/doc/forum/__34__permission_denied__34___in_fsck_on_shared_repo.mdwn b/doc/forum/__34__permission_denied__34___in_fsck_on_shared_repo.mdwn
new file mode 100644
index 000000000..f13aed2c2
--- /dev/null
+++ b/doc/forum/__34__permission_denied__34___in_fsck_on_shared_repo.mdwn
@@ -0,0 +1,17 @@
+i'm getting errors in ``git annex fsck`` on a shared bare git repo with git-annex 3.20120418 local repo version 3:
+
+``git-annex: ${PATH}/${MYREPO}.git/annex/objects/${HA}/${SH}/SHA1-${HASH}/SHA1-${HASH}: setFileMode: permission denied (Operation not permitted)``
+
+the repository is shared among several users in a common group, and the repo is set up with sticky group, and with appropriate umasks, everything should work.
+
+however, even with the file having permissions -rw-rw-r-- in the directory with permissions drwxrwsr-x, owned by someone else but by a group i'm currently in (as verified by issuing `groups`), i get said error message.
+
+a strace reveals that the failing syscall is:
+
+``[pid 17626] chmod("${FILENAME}", 0100555) = -1 EPERM (Operation not permitted)``
+
+(maybe related: git annex looks for the file in another ${HA}/${SH} combination (of three digits instead of two digits each) before, i take it this is just a new feature not used by the data in my repo? also, i should add that the repository dates back to git-annex 0.13.)
+
+as a workaround, i'm currently ``sudo chown``ing all files to me before the check.
+
+why does fsck try to set permissions even if they are ok? is this a bug in my setup, and if yes, how is a shared repository set up correctly?
diff --git a/doc/forum/__34__permission_denied__34___in_fsck_on_shared_repo/comment_1_3a5202ef2116ebb5559b6f4d920755fc._comment b/doc/forum/__34__permission_denied__34___in_fsck_on_shared_repo/comment_1_3a5202ef2116ebb5559b6f4d920755fc._comment
new file mode 100644
index 000000000..5a5cafa72
--- /dev/null
+++ b/doc/forum/__34__permission_denied__34___in_fsck_on_shared_repo/comment_1_3a5202ef2116ebb5559b6f4d920755fc._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2012-04-21T16:09:19Z"
+ content="""
+Well, the modes you show are wrong. Nothing in the annex should be writable. fsck needs to fix those. (It's true that it also always chmods even correct mode files/directories.. I've made a change avoiding that.)
+
+I have not thought or tried shared git annex repos with multiple unix users writing to them. ([[tips/Using_gitolite_with_git-annex]] would be an alternative.) Seems to me that removing content from the annex would also be a problem, since the directory will need to be chmodded to allow deleting the content from it, and that will fail if it's owned by someone else. Perhaps git-annex needs to honor core.sharedRepository and avoid these nice safeguards on file modes then.
+"""]]
diff --git a/doc/forum/__34__permission_denied__34___in_fsck_on_shared_repo/comment_2_86663eeb75b0477f53c45f26c8e4b051._comment b/doc/forum/__34__permission_denied__34___in_fsck_on_shared_repo/comment_2_86663eeb75b0477f53c45f26c8e4b051._comment
new file mode 100644
index 000000000..1c9bfbfe4
--- /dev/null
+++ b/doc/forum/__34__permission_denied__34___in_fsck_on_shared_repo/comment_2_86663eeb75b0477f53c45f26c8e4b051._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 2"
+ date="2012-04-21T23:46:42Z"
+ content="""
+All right, I've made all the changes so it supports `core.sharedRepository`.
+"""]]
diff --git a/doc/forum/__34__permission_denied__34___in_fsck_on_shared_repo/comment_3_c336b2b07cd006d378e5be9639ff17ec._comment b/doc/forum/__34__permission_denied__34___in_fsck_on_shared_repo/comment_3_c336b2b07cd006d378e5be9639ff17ec._comment
new file mode 100644
index 000000000..fd75f2f85
--- /dev/null
+++ b/doc/forum/__34__permission_denied__34___in_fsck_on_shared_repo/comment_3_c336b2b07cd006d378e5be9639ff17ec._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://christian.amsuess.com/chrysn"
+ nickname="chrysn"
+ subject="comment 3"
+ date="2012-04-23T14:14:28Z"
+ content="""
+thanks, that's great. will there be a way to have sharedRepository work for shared remotes (rsync, directory) too, or is that better taken care of by acls?
+
+@not thought of shared repos: we're having our family photo archive spread over our laptops, and backed up on our home storage server and on an rsync+encryption off-site server, with everyone naturally having their own accounts on all systems -- just if you need a use case.
+"""]]
diff --git a/doc/forum/__34__permission_denied__34___in_fsck_on_shared_repo/comment_4_1339cd27ca2955f30b01ecf4da7d6fe8._comment b/doc/forum/__34__permission_denied__34___in_fsck_on_shared_repo/comment_4_1339cd27ca2955f30b01ecf4da7d6fe8._comment
new file mode 100644
index 000000000..568f11330
--- /dev/null
+++ b/doc/forum/__34__permission_denied__34___in_fsck_on_shared_repo/comment_4_1339cd27ca2955f30b01ecf4da7d6fe8._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 4"
+ date="2012-04-23T14:35:39Z"
+ content="""
+I'm not currently planning to support sharedRepository perms on special remotes. I suppose I could be convinced otherwise, it's perhaps doable for the ones you mention (rsync might be tricky). (bup special remote already supports it of course.)
+
+thanks for the use case!
+"""]]
diff --git a/doc/forum/__34__unable_to_resolve_reference_refs__47__heads__47__git-annex__34__.mdwn b/doc/forum/__34__unable_to_resolve_reference_refs__47__heads__47__git-annex__34__.mdwn
new file mode 100644
index 000000000..19aacf021
--- /dev/null
+++ b/doc/forum/__34__unable_to_resolve_reference_refs__47__heads__47__git-annex__34__.mdwn
@@ -0,0 +1,34 @@
+After a `git annex copy --auto -t m3` I got this error:
+
+ (Recording state in git...)
+ error: unable to resolve reference refs/heads/git-annex: No such file or directory
+ fatal: Cannot lock the ref 'refs/heads/git-annex'.
+ git-annex: git [Param "update-ref",Param "refs/heads/git-annex",Param "d768b20f76ce40157214a713fb0ccb9cfc9134c2"] failed
+
+I did a `git annex sync m3` and got
+
+ [...]
+ push m3
+ Counting objects: 2976, done.
+ Delta compression using up to 2 threads.
+ Compressing objects: 100% (2052/2052), done.
+ Writing objects: 100% (2379/2379), 392.33 KiB, done.
+ Total 2379 (delta 1652), reused 460 (delta 316)
+ Auto packing the repository for optimum performance.
+ error: bad ref for refs/heads/git-annex
+ error: bad ref for refs/heads/git-annex
+ error: bad ref for refs/heads/git-annex
+ To /media/m3/annex
+ 87c82c5..06219eb git-annex -> synced/git-annex
+ be7ff5e..6625634 master -> synced/master
+ ok
+
+And then I ran the command git-annex was trying to run:
+
+ $ git update-ref refs/heads/git-annex d768b20f76ce40157214a713fb0ccb9cfc9134c2
+ error: Trying to write ref refs/heads/git-annex with nonexistent object d768b20f76ce40157214a713fb0ccb9cfc9134c2
+ fatal: Cannot update the ref 'refs/heads/git-annex'.
+
+`git fsck --full` gives no errors.
+
+What does this error mean? Should I be worried? Thanks.
diff --git a/doc/forum/__34__unable_to_resolve_reference_refs__47__heads__47__git-annex__34__/comment_1_e50188896df347f1d92e20a52053aa14._comment b/doc/forum/__34__unable_to_resolve_reference_refs__47__heads__47__git-annex__34__/comment_1_e50188896df347f1d92e20a52053aa14._comment
new file mode 100644
index 000000000..b7ad4a13a
--- /dev/null
+++ b/doc/forum/__34__unable_to_resolve_reference_refs__47__heads__47__git-annex__34__/comment_1_e50188896df347f1d92e20a52053aa14._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-04-01T18:33:37Z"
+ content="""
+I'm afraid that this looks like a partially corrupted git repository to me. Something seems to have gone wrong with `.git/refs/heads/git-annex`. Also, git object d768b20f76ce40157214a713fb0ccb9cfc9134c2 seems to have been present before, and be gone now.
+
+I would run `git fsck`, then look at what's happened in `.git/refs/heads`, and if the repository does seem to be damanged, re-clone it. (You can copy over `.git/config` and `.git/annex/` to keep your annexed data in the new clone.) You should probably also run `git annex fsck`, as it could have lost some location log changes.
+"""]]
diff --git a/doc/forum/__34__unable_to_resolve_reference_refs__47__heads__47__git-annex__34__/comment_2_d67793f7c969f64943d1fd54a1208c2b._comment b/doc/forum/__34__unable_to_resolve_reference_refs__47__heads__47__git-annex__34__/comment_2_d67793f7c969f64943d1fd54a1208c2b._comment
new file mode 100644
index 000000000..1dff89121
--- /dev/null
+++ b/doc/forum/__34__unable_to_resolve_reference_refs__47__heads__47__git-annex__34__/comment_2_d67793f7c969f64943d1fd54a1208c2b._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="spwhitton"
+ ip="163.1.166.255"
+ subject="comment 2"
+ date="2013-04-06T19:06:24Z"
+ content="""
+Thanks for taking the time to reply.
+
+1) The corruption spread between repositories so I resorted to restoring from a backup from some days ago, and then I restored newly added files by manually copying the symlinks from the old repo into the new one. Of course I can't update the git-annex branch by hand. I've run `git annex fsck`: does that re-create the location log information for the symlinks that I re-added, at least for the local repository even if it doesn't know about copies elsewhere?
+
+2) I initially tried to git clone from my restored backup, rather than just moving the restore into place. But then while this clone showed no errors on a `git fsck --full`, any git-annex command, such as `init` (following [this](http://git-annex.branchable.com/tips/what_to_do_when_a_repository_is_corrupted/)), gives the following sort of error:
+
+ error: invalid object 100644 <long-SHA-string> for '<path to one of git annex's log files>'
+(unfortunately I lost my xterm so don't have one of my actual errors in full). Can you think of any reason why doing a clone of the backup copy would cause this? Instead I have just mv'd the backup copy into place and it works fine.
+"""]]
diff --git a/doc/forum/__34__unable_to_resolve_reference_refs__47__heads__47__git-annex__34__/comment_3_3523884833b5fd458a35f898797bf897._comment b/doc/forum/__34__unable_to_resolve_reference_refs__47__heads__47__git-annex__34__/comment_3_3523884833b5fd458a35f898797bf897._comment
new file mode 100644
index 000000000..21511d2ec
--- /dev/null
+++ b/doc/forum/__34__unable_to_resolve_reference_refs__47__heads__47__git-annex__34__/comment_3_3523884833b5fd458a35f898797bf897._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-04-08T17:23:24Z"
+ content="""
+1. I don't understand how corruption could spread between git repositories. git is supposed to use checksums to prevent bad data propigating. I would be running a lot of `git fsck` if I were you. Yes, `git annex fsck` will update location log information for files it finds in the local repository.
+
+2. Again this looks like something is corrupting your repository when git writes it. Perhaps bad memory? I think you need to get to the root of the problem with the corrupting git repositories.
+"""]]
diff --git a/doc/forum/__34__unable_to_resolve_reference_refs__47__heads__47__git-annex__34__/comment_4_02c32c2521ba1a1eaa19eaca7281f2a6._comment b/doc/forum/__34__unable_to_resolve_reference_refs__47__heads__47__git-annex__34__/comment_4_02c32c2521ba1a1eaa19eaca7281f2a6._comment
new file mode 100644
index 000000000..25d07e8ad
--- /dev/null
+++ b/doc/forum/__34__unable_to_resolve_reference_refs__47__heads__47__git-annex__34__/comment_4_02c32c2521ba1a1eaa19eaca7281f2a6._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="spwhitton"
+ ip="163.1.167.50"
+ subject="comment 4"
+ date="2013-04-17T17:02:11Z"
+ content="""
+I didn't think that git would let corruption spread either, but it did: the repository m3 which I showed a push to in my original post showed a broken refs/heads/git-annex too. You can see it happening when git tries to repack m3 after pushing to it in my original post.
+
+I am pretty sure that my HDD on the machine where this first occurred needs replacing; I've marked the remote as untrusted.
+"""]]
diff --git a/doc/forum/__91__Installation__93___base-3.0.3.2_requires_syb___61____61__0.1.0.2.mdwn b/doc/forum/__91__Installation__93___base-3.0.3.2_requires_syb___61____61__0.1.0.2.mdwn
new file mode 100644
index 000000000..950b8ee19
--- /dev/null
+++ b/doc/forum/__91__Installation__93___base-3.0.3.2_requires_syb___61____61__0.1.0.2.mdwn
@@ -0,0 +1,16 @@
+Hi, another installation issue on Ubuntu Lucid:
+
+I started with a clean `~/.cabal` directory and did the following:
+
+ andreas@antares:~$ sudo aptitude install cabal-install
+ andreas@antares:~$ cabal update
+ andreas@antares:~$ cabal install git-annex -v --bindir=$HOME/
+
+However, I got some dpendancy error:
+
+ cabal: dependencies conflict: base-3.0.3.2 requires syb ==0.1.0.2 however
+ syb-0.1.0.2 was excluded because json-0.5 requires syb >=0.3.3
+
+Any ideas?
+
+Thanks for your help!
diff --git a/doc/forum/__91__Installation__93___base-3.0.3.2_requires_syb___61____61__0.1.0.2/comment_1_fae6e88115d175239fc55cef4c33fb2c._comment b/doc/forum/__91__Installation__93___base-3.0.3.2_requires_syb___61____61__0.1.0.2/comment_1_fae6e88115d175239fc55cef4c33fb2c._comment
new file mode 100644
index 000000000..c04cc335b
--- /dev/null
+++ b/doc/forum/__91__Installation__93___base-3.0.3.2_requires_syb___61____61__0.1.0.2/comment_1_fae6e88115d175239fc55cef4c33fb2c._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2012-01-15T19:53:35Z"
+ content="""
+This is now about different build failure than the bug you reported, which was already fixed. Conflating the two is just confusing.
+
+The error message about `syb` is because by using cabal-install on an Ubuntu system from 2010, you're mixing the very old versions of some haskell libraries in Ubuntu with the new versions cabal wants to install. The solution is to stop mixing two package management systems --
+
+* Either install git-annex without using cabal, and use apt-get to install all its dependencies from Ubuntu, assuming your distribution has all the necessary haskell libraries packaged.
+* Or `apt-get remove ghc`, and manually install a current version of [The Haskell Platform](http://hackage.haskell.org/platform/) and use cabal.
+"""]]
diff --git a/doc/forum/__91__Installation__93___base-3.0.3.2_requires_syb___61____61__0.1.0.2/comment_2_4c7a75638e8717132ccde949018d6008._comment b/doc/forum/__91__Installation__93___base-3.0.3.2_requires_syb___61____61__0.1.0.2/comment_2_4c7a75638e8717132ccde949018d6008._comment
new file mode 100644
index 000000000..3a3106a63
--- /dev/null
+++ b/doc/forum/__91__Installation__93___base-3.0.3.2_requires_syb___61____61__0.1.0.2/comment_2_4c7a75638e8717132ccde949018d6008._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://openid.stackexchange.com/user/fd55c6e3-966a-4626-865f-5d0f73e1eb88"
+ nickname="Andreas H."
+ subject="Thanks and sorry"
+ date="2012-01-15T20:54:55Z"
+ content="""
+Joey, thanks for you quick help! I'll try the manual haskell-platform install once I have quicker internet again, i.e. tomorrow.
+
+And sorry for the mess-up; I splitted the post into two. Hope it's clearer now.
+"""]]
diff --git a/doc/forum/_preferred_content:_lastpresent.mdwn b/doc/forum/_preferred_content:_lastpresent.mdwn
new file mode 100644
index 000000000..e8730eb00
--- /dev/null
+++ b/doc/forum/_preferred_content:_lastpresent.mdwn
@@ -0,0 +1 @@
+Is there any kind of "lastpresent" in the preferred-content expression? If set, git-annex would see if "git log --follow $path -n 1" (or some configurable -n) was present.
diff --git a/doc/forum/_preferred_content:_lastpresent/comment_1_7610cd866b256d36646b642eb5f8cae5._comment b/doc/forum/_preferred_content:_lastpresent/comment_1_7610cd866b256d36646b642eb5f8cae5._comment
new file mode 100644
index 000000000..d5910c6d0
--- /dev/null
+++ b/doc/forum/_preferred_content:_lastpresent/comment_1_7610cd866b256d36646b642eb5f8cae5._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.246"
+ subject="comment 1"
+ date="2013-11-15T20:39:43Z"
+ content="""
+The idea seems to be to match files that have been deleted.
+
+I don't see how that could work; preferred content expressions are always matched against files in the working tree.
+
+Even if it were doable, it would be quite expensive if every preferred content query involved a `git log`...
+
+What are you trying to achieve with this?
+"""]]
diff --git a/doc/forum/_preferred_content:_lastpresent/comment_2_d25666a173b78213d583f029fd166d06._comment b/doc/forum/_preferred_content:_lastpresent/comment_2_d25666a173b78213d583f029fd166d06._comment
new file mode 100644
index 000000000..4714034c3
--- /dev/null
+++ b/doc/forum/_preferred_content:_lastpresent/comment_2_d25666a173b78213d583f029fd166d06._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn1QhtPvsRBV7pfaDW_ZTPFv_ZIxSzQ8Rg"
+ nickname="Paul Léo"
+ subject="comment 2"
+ date="2013-11-16T13:12:35Z"
+ content="""
+The aim is to be able to have some semi-automatic mode (using \"git-annex wanted . (lastpresent)\"), where file paths which you \"git-annex get\" one time always get updated to the latest version.
+
+Or, you could also use some variant of it the other way round (using \"git-annex wanted . (notlastpresent)\"): all files would be present by default, but paths which you \"git-annex drop\"ed once wouldn't become present again.
+"""]]
diff --git a/doc/forum/advantages_of_SHA__42___over_WORM.mdwn b/doc/forum/advantages_of_SHA__42___over_WORM.mdwn
new file mode 100644
index 000000000..5b544593f
--- /dev/null
+++ b/doc/forum/advantages_of_SHA__42___over_WORM.mdwn
@@ -0,0 +1,5 @@
+Thanks for creating git-annex.
+
+I am confused about the advantages of the SHA* backends over WORM. The "backends" page in this wiki says that with WORM, files "can be moved around, but should never be added to or changed". But I don't see any difference to SHA* files as long as the premise of WORM that "any file with the same basename, size, and modification time has the same content" is true. Using "git annex unlock", WORM files can be modified in the same way as SHA* files.
+
+If the storage I use is dependable (i.e. I don't need SHA checksums for detection of corruption), and I don't need to optimize for the case that the modification date of a file is changed but the contents stay the same, and if it is unlikely that several files will be identical, is there actually any advantage in using SHA*?
diff --git a/doc/forum/advantages_of_SHA__42___over_WORM/comment_1_96c354cac4b5ce5cf6664943bc84db1d._comment b/doc/forum/advantages_of_SHA__42___over_WORM/comment_1_96c354cac4b5ce5cf6664943bc84db1d._comment
new file mode 100644
index 000000000..218027ca5
--- /dev/null
+++ b/doc/forum/advantages_of_SHA__42___over_WORM/comment_1_96c354cac4b5ce5cf6664943bc84db1d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-08-29T16:10:38Z"
+ content="""
+You're right -- as long as nothing changes a file without letting the modification time update, editing WORM files is safe.
+"""]]
diff --git a/doc/forum/android_binary-only_download.mdwn b/doc/forum/android_binary-only_download.mdwn
new file mode 100644
index 000000000..90204fbf4
--- /dev/null
+++ b/doc/forum/android_binary-only_download.mdwn
@@ -0,0 +1,9 @@
+It would be really neat if there was a way to get just the `git-annex` binary on Android, without getting the entire APK. This can be useful when one is already using their own shell and rootfs, for example I work with <a href="https://sites.google.com/site/taldewandroid/">this</a>.
+
+This way, one can just use parts of git-annex, without having to have a whole APK and its dependencies, and the space it takes up, etc.
+
+So would you be able to add a download link for this?
+
+
+
+Thanks for the wonderful project!
diff --git a/doc/forum/android_binary-only_download/comment_1_aab206e0bf0bb5ff47c7cc9795f12f92._comment b/doc/forum/android_binary-only_download/comment_1_aab206e0bf0bb5ff47c7cc9795f12f92._comment
new file mode 100644
index 000000000..d8e6d81fc
--- /dev/null
+++ b/doc/forum/android_binary-only_download/comment_1_aab206e0bf0bb5ff47c7cc9795f12f92._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.193"
+ subject="comment 1"
+ date="2013-07-02T16:57:43Z"
+ content="""
+This seems a pretty unusual use case. Can't you just unpack the apk (it's a regular zip file) and get out the parts you want?
+"""]]
diff --git a/doc/forum/annexed_file_key_for_web_remote_with_SHA256E_backend.mdwn b/doc/forum/annexed_file_key_for_web_remote_with_SHA256E_backend.mdwn
new file mode 100644
index 000000000..6c428e375
--- /dev/null
+++ b/doc/forum/annexed_file_key_for_web_remote_with_SHA256E_backend.mdwn
@@ -0,0 +1,12 @@
+First off, thanks so much for your hard work, git-annex is amazing.
+
+I just started using the [web as a special remote](http://git-annex.branchable.com/tips/using_the_web_as_a_special_remote/) feature with the SHA256E backend, and I noticed that although the annexed file has the correct backend prefix (SHA256E) it does not have the extension of the file in the URL. The URL is `https://...IMG_1234.JPG` but the annexed file is `SHA256E-...832c99` with no extension.
+
+This is fine for most use cases, but I actually access an S3 remote directly from another app (independent of git-annex) to render photos, and in that app I'm using the extensions to figure out file types, so not having that info is slightly inconvenient.
+
+Is there any way to either:
+
+1. tell git-annex to preserve the extension of a file on the web in the annexed file, or
+2. alternatively, change the annexed filename (add the extension manually) without screwing anything up?
+
+Any help would be much appreciated, thanks!
diff --git a/doc/forum/annexed_file_key_for_web_remote_with_SHA256E_backend/comment_1_d1605a6e3b4d6863f4089218994ce564._comment b/doc/forum/annexed_file_key_for_web_remote_with_SHA256E_backend/comment_1_d1605a6e3b4d6863f4089218994ce564._comment
new file mode 100644
index 000000000..8b78618a9
--- /dev/null
+++ b/doc/forum/annexed_file_key_for_web_remote_with_SHA256E_backend/comment_1_d1605a6e3b4d6863f4089218994ce564._comment
@@ -0,0 +1,29 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-05-06T15:43:06Z"
+ content="""
+You don't say what version of git-annex you're using. I tested with the current version, 4.20130405:
+
+[[!format sh \"\"\"
+joey@gnu:~/tmp/rr>git annex addurl http://localhost/~joey/header_background.png
+addurl localhost_~joey_header_background.png (downloading http://localhost/~joey/header_background.png ...) --2013-05-06 11:36:41-- http://localhost/~joey/header_background.png
+Resolving localhost (localhost)... ::1, 127.0.0.1, 127.0.1.1
+Connecting to localhost (localhost)|::1|:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 53693 (52K) [image/png]
+Saving to: ‘/home/joey/tmp/rr/.git/annex/tmp/URL--http&c%%localhost%~joey%header_background.png’
+
+100%[======================================>] 53,693 --.-K/s in 0.001s
+
+2013-05-06 11:36:41 (58.9 MB/s) - '/home/joey/tmp/rr/.git/annex/tmp/URL--http&c%%localhost%~joey%header_background.png' saved [53693/53693]
+
+(checksum...) ok
+(Recording state in git...)
+joey@gnu:~/tmp/rr>dir
+lrwxrwxrwx 1 joey joey 194 Sep 11 2010 localhost_~joey_header_background.png -> .git/annex/objects/M1/p0/SHA256E-s53693--3f065e8e2db1248765d0753cf483e40ae0eaf9bffe34b0cf738158815d0884e3.png/SHA256E-s53693--3f065e8e2db1248765d0753cf483e40ae0eaf9bffe34b0cf738158815d0884e3.png
+\"\"\"]]
+
+Looks like it's doing the right thing with the extension!
+"""]]
diff --git a/doc/forum/annexed_file_key_for_web_remote_with_SHA256E_backend/comment_2_d249ff27fa3d9ac3ca32485cdef49930._comment b/doc/forum/annexed_file_key_for_web_remote_with_SHA256E_backend/comment_2_d249ff27fa3d9ac3ca32485cdef49930._comment
new file mode 100644
index 000000000..3d5814bc6
--- /dev/null
+++ b/doc/forum/annexed_file_key_for_web_remote_with_SHA256E_backend/comment_2_d249ff27fa3d9ac3ca32485cdef49930._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnkBYpLu_NOj7Uq0-acvLgWhxF8AUEIJbo"
+ nickname="Chris"
+ subject="comment 2"
+ date="2013-05-07T03:37:24Z"
+ content="""
+Thanks very much! That's great news. I'm using 3.20120629, I'll just update then.
+"""]]
diff --git a/doc/forum/archaeology_of_deleted_files.mdwn b/doc/forum/archaeology_of_deleted_files.mdwn
new file mode 100644
index 000000000..a4ed66dc8
--- /dev/null
+++ b/doc/forum/archaeology_of_deleted_files.mdwn
@@ -0,0 +1,36 @@
+Earlier this week, I somehow lost a ton of files from my annex -- by switching on the command line from indirect to direct mode while the assistant was running, I think. I'm not sure.
+
+Anyway, by "lost" I mean "lost the symlinks to," because git-annex defaults to keeping content around till you tell it otherwise. So I still had the content in the repos on my two backup drives. All I needed was the symlinks back.
+
+But how to figure out exactly what I lost and get it back?
+
+I found that out here:
+
+http://stackoverflow.com/questions/953481/restore-a-deleted-file-in-a-git-repo
+
+Here's a magical formula you can use to find every single file deletion in the history of your repo:
+
+ git log --diff-filter=D --summary
+
+That will give you every commit that deleted things, and what was deleted.
+
+To bring back all the files deleted in a given commit, where COMMITHASH is the commit hash, use this command:
+
+ git checkout COMMITHASH^1 -- .
+
+to bring back only a specific file:
+
+ git checkout COMMITHASH^1 -- path/to/file.txt
+
+to bring back only a subdirectory:
+
+ git checkout COMMITHASH^1 -- sub/directory
+
+that will bring them back into the staging area. You can see which ones just reappeared by typing:
+
+ git status
+
+then you can actually make the restore permanent by typing:
+
+ git commit -m "I just resurrected some files"
+
diff --git a/doc/forum/archaeology_of_deleted_files/comment_1_48f27df03ec18d2c27cf6b70dcf71dc5._comment b/doc/forum/archaeology_of_deleted_files/comment_1_48f27df03ec18d2c27cf6b70dcf71dc5._comment
new file mode 100644
index 000000000..3647193b8
--- /dev/null
+++ b/doc/forum/archaeology_of_deleted_files/comment_1_48f27df03ec18d2c27cf6b70dcf71dc5._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="99.54.57.201"
+ subject="comment 1"
+ date="2013-01-25T14:07:36Z"
+ content="""
+seems I inadvertently got caught by Markdown -- I tried to write COMMITHASH-hat-1 and it turned into COMMITHASH superscript 1.
+
+Tilde (~) would also have worked instead of hat (^)
+"""]]
diff --git a/doc/forum/archaeology_of_deleted_files/comment_2_c698cd10c8038bac45bd1049506a27c3._comment b/doc/forum/archaeology_of_deleted_files/comment_2_c698cd10c8038bac45bd1049506a27c3._comment
new file mode 100644
index 000000000..363d32079
--- /dev/null
+++ b/doc/forum/archaeology_of_deleted_files/comment_2_c698cd10c8038bac45bd1049506a27c3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="comment 2"
+ date="2013-01-25T14:27:47Z"
+ content="""
+I fixed it for you
+"""]]
diff --git a/doc/forum/archival_and_multiple_users.mdwn b/doc/forum/archival_and_multiple_users.mdwn
new file mode 100644
index 000000000..da451d9fb
--- /dev/null
+++ b/doc/forum/archival_and_multiple_users.mdwn
@@ -0,0 +1,8 @@
+The assistant archival walk-through describes how files get removed from local repo if moved into archive repos.
+What if the files in question aren't needed immediately (and can be archived) for one user of a shared repo, but needed by someone else on their own machine?
+git-annex directory arrangement propagation wouldn't work for this case, it seems. Could assistant handle this case?
+
+It looks like having a browser of the directory tree in git-annex assistant webpage with say right-click menu with "get" and "drop" would be the most flexible.
+
+Or maybe it could be more about integration with Linux etc file browsers (but then it's system specific, unlike with webapp).
+
diff --git a/doc/forum/archival_and_multiple_users/comment_1_fc4ee256f03a7c189d687caf4a34e21e._comment b/doc/forum/archival_and_multiple_users/comment_1_fc4ee256f03a7c189d687caf4a34e21e._comment
new file mode 100644
index 000000000..090091a8a
--- /dev/null
+++ b/doc/forum/archival_and_multiple_users/comment_1_fc4ee256f03a7c189d687caf4a34e21e._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 1"
+ date="2013-07-24T15:30:51Z"
+ content="""
+A feature I would love to see is a file manager integrated with the webapp, so that you could browse your files and retrieve or drop them manually as if you were using the command line. Then you could have your repo set on \"manual\" and not worry about those archive directories. Just manually drop content if you got low on space.
+
+"""]]
diff --git a/doc/forum/archival_and_multiple_users/comment_2_a96d57d4bb567ac9b0b9167d5b1be011._comment b/doc/forum/archival_and_multiple_users/comment_2_a96d57d4bb567ac9b0b9167d5b1be011._comment
new file mode 100644
index 000000000..cf97f28fd
--- /dev/null
+++ b/doc/forum/archival_and_multiple_users/comment_2_a96d57d4bb567ac9b0b9167d5b1be011._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 2"
+ date="2013-07-25T18:42:59Z"
+ content="""
+I believe that the world has enough (or too many) file managers, and do not want to build another one just for git-annex. In any case \"git annex get\" or any GUI wrapping around it is not going to help with the described use case, because the problem is that the files are archived away in my offline drive, while you want to access them in your repository, which does not have access to that drive.
+
+The way to handle this situation is to copy or move the files you want out of the archive directory, and back to the parent directory. This move of the file will be synced from your repository to all the other repositories. When the repository that does have access to the archive notices this, it will get the files that have been moved out of the archive. Normal assistant syncing will then arrange to get them transferred back to the repository of the user who had wanted them.
+
+Of course, if the archive is on an offline drive, this won't happen until that drive is plugged back in.
+"""]]
diff --git a/doc/forum/archival_and_multiple_users/comment_3_bd44634b04732ffb91154c61ef9cf828._comment b/doc/forum/archival_and_multiple_users/comment_3_bd44634b04732ffb91154c61ef9cf828._comment
new file mode 100644
index 000000000..20b67976e
--- /dev/null
+++ b/doc/forum/archival_and_multiple_users/comment_3_bd44634b04732ffb91154c61ef9cf828._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawln3ckqKx0x_xDZMYwa9Q1bn4I06oWjkog"
+ nickname="Michael"
+ subject="comment 3"
+ date="2013-07-25T19:16:20Z"
+ content="""
+> The way to handle this situation is to copy or move the files you want out of the archive directory, and back to the parent directory. This move of the file will be synced from your repository to all the other repositories. When the repository that does have access to the archive notices this, it will get the files that have been moved out of the archive. Normal assistant syncing will then arrange to get them transferred back to the repository of the user who had wanted them.
+
+But won't it also transfer the same files into repos of all other users (who didn't want the files)?
+On a related note, allowing moving files for everyone could jeopardise integrity of the master archive. Is there a way to limit what kind of ops the users can do (e.g. copy but not move)?
+
+Re offline drives, the case I was thinking of is actually where each user has access to e.g. special remotes directly. So a manual get/put would solve the problem at hand.
+
+"""]]
diff --git a/doc/forum/archival_and_multiple_users/comment_4_b89a56a5f1cd641f87925c7a5f74bcec._comment b/doc/forum/archival_and_multiple_users/comment_4_b89a56a5f1cd641f87925c7a5f74bcec._comment
new file mode 100644
index 000000000..332e0a0a0
--- /dev/null
+++ b/doc/forum/archival_and_multiple_users/comment_4_b89a56a5f1cd641f87925c7a5f74bcec._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 4"
+ date="2013-07-25T19:23:30Z"
+ content="""
+Moving files shouldn't jepardize anything. If a user makes a change they shouldn't have made, it can be reverted.
+
+If you have the archive drive available locally you can set your repository to manual mode and just use `git annex get` on content you want. Or you could set it to be a backup repository and the assistant would get all content.
+Or write a custom [[preferred_content]] expression for your repository to make it want files in `archive/stillusing/`
+
+
+"""]]
diff --git a/doc/forum/archival_and_multiple_users/comment_5_81293bf5dc8ad4552712c2083fd589c9._comment b/doc/forum/archival_and_multiple_users/comment_5_81293bf5dc8ad4552712c2083fd589c9._comment
new file mode 100644
index 000000000..b7b93fdf4
--- /dev/null
+++ b/doc/forum/archival_and_multiple_users/comment_5_81293bf5dc8ad4552712c2083fd589c9._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmkBwMWvNKZZCge_YqobCSILPMeK6xbFw8"
+ nickname="develop"
+ subject="comment 5"
+ date="2013-07-26T08:20:21Z"
+ content="""
+I think i agree that this should be implemented.
+
+Not only to be able to \"get/drop\" from the assistant without the use of archive folders.
+
+But mainly because i think this will be needed anyways, to do a \"recover previous version of file\" option. Which should definitely be in the web assistant.
+
+We can't expect family and friends to figure out all command line stuff, thus they need to use the assistant. And i really think it would be a shame to not have an easy way to recover old versions, when the old versions are actually stored.
+
+Always think about having a good WAF(Wife acceptance factor).
+
+Just my 2 bits (and a haircut).
+
+"""]]
diff --git a/doc/forum/assistant__44___direct_mode__44___large_files__44___command_line_-_how_do_these_play_together__63__.mdwn b/doc/forum/assistant__44___direct_mode__44___large_files__44___command_line_-_how_do_these_play_together__63__.mdwn
new file mode 100644
index 000000000..e48bf4cf6
--- /dev/null
+++ b/doc/forum/assistant__44___direct_mode__44___large_files__44___command_line_-_how_do_these_play_together__63__.mdwn
@@ -0,0 +1,10 @@
+Hi,
+
+I am trying to understand git-annex, and the walkthroughs on the page did help a lot. I *feel* that git-annex is the solution for my use case: having a large archive, several computers, NAS both at work and at home, being offline during commuting, …
+
+Everything seems to be clear for me when using the command line version. Using annex assistant looks promising, and it is easy to create repositories that match my usage. But now I see that these repositories are in direct mode by default; and I am not sure how this impacts my ability to work with large files. I do not want to end up with git (without annex) handling huge files.
+
+So - can somebody explain how direct mode affects this? Can I switch to indirect mode with the assistant? Am I asking the wrong questions?
+
+thanks,
+Ulli
diff --git a/doc/forum/assistant__44___direct_mode__44___large_files__44___command_line_-_how_do_these_play_together__63__/comment_1_d90d1d599ce557af03c6f0f2ea188212._comment b/doc/forum/assistant__44___direct_mode__44___large_files__44___command_line_-_how_do_these_play_together__63__/comment_1_d90d1d599ce557af03c6f0f2ea188212._comment
new file mode 100644
index 000000000..d762791da
--- /dev/null
+++ b/doc/forum/assistant__44___direct_mode__44___large_files__44___command_line_-_how_do_these_play_together__63__/comment_1_d90d1d599ce557af03c6f0f2ea188212._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.246"
+ subject="comment 1"
+ date="2013-11-09T17:36:01Z"
+ content="""
+Files in direct mode are stored in the git annex the same way as when using indirect mode. But you're perhaps right to be wary of using direct mode, it's been quite easy to mess up while using it at the command line until very recently when the [[todo/direct_mode_guard]] was implemented.
+
+You can switch repositories created using the assistant from direct to indirect mode if you like. The assistant works in either mode.
+"""]]
diff --git a/doc/forum/assistant__44___direct_mode__44___large_files__44___command_line_-_how_do_these_play_together__63__/comment_2_58b1af497cab132acb28cb5f9283ec2a._comment b/doc/forum/assistant__44___direct_mode__44___large_files__44___command_line_-_how_do_these_play_together__63__/comment_2_58b1af497cab132acb28cb5f9283ec2a._comment
new file mode 100644
index 000000000..45cec4db5
--- /dev/null
+++ b/doc/forum/assistant__44___direct_mode__44___large_files__44___command_line_-_how_do_these_play_together__63__/comment_2_58b1af497cab132acb28cb5f9283ec2a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmkXtBdMgE1d9nCz2iBc4f85xh4izZ_auU"
+ nickname="Ulrich"
+ subject="Thanks"
+ date="2013-11-12T08:57:36Z"
+ content="""
+Ok, thanks for the explanation. I still have to figure out what happens when I annex drop files on a direct repository, and how well all this plays with the Finder on Mac…
+"""]]
diff --git a/doc/forum/assistant__44___direct_mode__44___large_files__44___command_line_-_how_do_these_play_together__63__/comment_3_37d4fd8f69e8066b5aa19454b714e443._comment b/doc/forum/assistant__44___direct_mode__44___large_files__44___command_line_-_how_do_these_play_together__63__/comment_3_37d4fd8f69e8066b5aa19454b714e443._comment
new file mode 100644
index 000000000..71a091930
--- /dev/null
+++ b/doc/forum/assistant__44___direct_mode__44___large_files__44___command_line_-_how_do_these_play_together__63__/comment_3_37d4fd8f69e8066b5aa19454b714e443._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmkXtBdMgE1d9nCz2iBc4f85xh4izZ_auU"
+ nickname="Ulrich"
+ subject="So what does &quot;git annex drop&quot; do in direct mode?"
+ date="2013-11-15T15:07:57Z"
+ content="""
+I just tried a git annex drop on a file in a direct mode repository, and that just did not change anything at all, as far as I can see. Actually I don't know what to expect, but doesn't that mean that I should have to switch to indirect mode in order to be able to drop large files to save space?
+
+Funny is that git annex drop did not complain at all but just reported \"ok\" after quite a while. And when I tried to drop a file that was not available in any other repository, it failed (which is expected behavior). So what is it what was \"ok\"?
+
+"""]]
diff --git a/doc/forum/assistant__44___direct_mode__44___large_files__44___command_line_-_how_do_these_play_together__63__/comment_4_a974e2105774d4f82ad286ff0792ba84._comment b/doc/forum/assistant__44___direct_mode__44___large_files__44___command_line_-_how_do_these_play_together__63__/comment_4_a974e2105774d4f82ad286ff0792ba84._comment
new file mode 100644
index 000000000..587d704d3
--- /dev/null
+++ b/doc/forum/assistant__44___direct_mode__44___large_files__44___command_line_-_how_do_these_play_together__63__/comment_4_a974e2105774d4f82ad286ff0792ba84._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.246"
+ subject="comment 4"
+ date="2013-11-15T20:33:47Z"
+ content="""
+Drop in direct mode does the same thing as in indirect mode.
+
+If you are using git-annex on a crippled filesystem without symlinks, git-annex cannot represent a file whose content has been dropped using a broken symlink, so it instead represents it with a nearly empty file.
+"""]]
diff --git a/doc/forum/assistant_created_encrypted__backup_remote:_Howto_restore__63__.mdwn b/doc/forum/assistant_created_encrypted__backup_remote:_Howto_restore__63__.mdwn
new file mode 100644
index 000000000..c18dfb6ca
--- /dev/null
+++ b/doc/forum/assistant_created_encrypted__backup_remote:_Howto_restore__63__.mdwn
@@ -0,0 +1,38 @@
+Hi,
+
+I have a question about encryption keys.
+Basically I do not know how to use the data which was copied in case my local
+machine dies?
+
+
+## I have done the following:
+---
+1. copied my ssh public key to a remote server
+1. created a directory and started git annex assistant
+
+ mkdir ~/test_annex
+
+ cd ~/test_annex
+
+ git annex webapp
+
+1. clicked Repository->Add another local repository
+1. Assistant: Where do you want to put this new repository? Me: ~/test_annex "Make Repository"
+1. Assistant "Combine repositories?" Me: "Keep repositories separate"
+1. clicked "Add another repository" clicked "remote server"
+1. filled out "Adding a remote server using ssh" form and clicked "Check this server"
+1. choose "Use an encrypted rsync repository on the server"
+1. Assistant "Repository created" I select "Full backup" as repository group.
+
+So far so good. If I now add a file on my local machine into ~/test_annex something not human readable is created on the remote machine.
+
+What I do not understand is how I use this backup later. I am expecting something along the "hybrid encryption keys" scheme
+explained in this wiki. However I was not able to determine which of my gpg keys was used or how the data was encrypted.
+
+So my question is: "How do I use the encrypted backup remote on a second machine?"
+
+
+
+
+
+
diff --git a/doc/forum/assistant_created_encrypted__backup_remote:_Howto_restore__63__/comment_1_70200f871b9df49261f32752a6bb0e67._comment b/doc/forum/assistant_created_encrypted__backup_remote:_Howto_restore__63__/comment_1_70200f871b9df49261f32752a6bb0e67._comment
new file mode 100644
index 000000000..9d457a9d2
--- /dev/null
+++ b/doc/forum/assistant_created_encrypted__backup_remote:_Howto_restore__63__/comment_1_70200f871b9df49261f32752a6bb0e67._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 1"
+ date="2013-10-27T21:19:45Z"
+ content="""
+When you create an encrypted rsync repository using the webapp like that, its encryption key is stored in your git repository, using the [[shared encryption scheme|encryption#index2h2]]. No gpg key needs to be used to decrypt files from the rsync repository; anyone with a clone of your git repository can do so. This has its plusses and its minuses; the webapp picks that type of encryption because it's easy to use.
+
+So, the answer is to just make a clone of your repository on the other machine, and then you can use it. There are lots of ways to do that; if you stay in the webapp, go to Add Another Repisitory and any of the \"Share with your other devices\", \"Share with a friend\", or \"Local computer\" options are easy ways to do it.
+
+----
+
+Now, if you had, manually, set up a rsync repository encrypted with the [[hybrid encryption key scheme|encryption#index1h2]], to access it from another computer with clone of the repository you would need to have a gpg key that has been given access to the repository. So you would either copy your gpg secret key to the other computer, or if you don't want to trust that other computer with the your main gpg key, you could make another gpg secret key for that computer, and add that key as one of the keys that can access the encrypted repository. (Or, if the computer belonged to a friend, you could just get their gpg key, and add it.)
+"""]]
diff --git a/doc/forum/assistant_created_encrypted__backup_remote:_Howto_restore__63__/comment_2_173da510b45f0320ae8aa2df9f14ae7b._comment b/doc/forum/assistant_created_encrypted__backup_remote:_Howto_restore__63__/comment_2_173da510b45f0320ae8aa2df9f14ae7b._comment
new file mode 100644
index 000000000..dbf2178f5
--- /dev/null
+++ b/doc/forum/assistant_created_encrypted__backup_remote:_Howto_restore__63__/comment_2_173da510b45f0320ae8aa2df9f14ae7b._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="Frank"
+ ip="31.19.114.93"
+ subject="Comment 2"
+ date="2013-11-07T19:45:16Z"
+ content="""
+Thank you very much for the explanation! Have fun!
+
+
+
+"""]]
diff --git a/doc/forum/assistant_overzealously_moving_stuff_to_other_repos.mdwn b/doc/forum/assistant_overzealously_moving_stuff_to_other_repos.mdwn
new file mode 100644
index 000000000..0cf3f2726
--- /dev/null
+++ b/doc/forum/assistant_overzealously_moving_stuff_to_other_repos.mdwn
@@ -0,0 +1,5 @@
+Debian Squeeze, git version 1.7.10.4, git-annex version 3.20121211
+
+The machine has a clone of the annex with preferred content string: `present or include=calibre/* or include=img/* or include=mail/* or include=music/* or include=sounds/*`
+
+This, I believe, should mean the assistant should never drop anything. However for the past two days it's been moving files to an encrypted rsync remote so that there are two copies (there is another copy on an external HDD) and then it's dropping them from the current annex. I want to keep the files here; can anyone think of any reason why they would be moved away?
diff --git a/doc/forum/assistant_overzealously_moving_stuff_to_other_repos/comment_1_6bd240edf1868615024ff11c24c3d52c._comment b/doc/forum/assistant_overzealously_moving_stuff_to_other_repos/comment_1_6bd240edf1868615024ff11c24c3d52c._comment
new file mode 100644
index 000000000..ad4b23f29
--- /dev/null
+++ b/doc/forum/assistant_overzealously_moving_stuff_to_other_repos/comment_1_6bd240edf1868615024ff11c24c3d52c._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 1"
+ date="2012-12-19T17:19:28Z"
+ content="""
+I had similar issues when I tried to use \"present\" settings a while back, except it was with adding files. I would add a file and then it would be immediately dropped (because it was not yet \"present\" while it was being added?). I gave up and just started using \"archive\" subdirectories for things I didn't want to be present. Even so I'm having some confusing issues with the assistant. It keeps dropping certain files which are in \"backup\" repositories and therefore should never have anything dropped. I haven't isolated what's going on to the degree I can get a good bug report together. But I'm having a hard time trusting assistant and its content settings to do what I want. I have a couple scripts that do things like:
+
+git annex copy --not --in=usbdrive --to=usbdrive
+
+to populate my backup repos, and these seem much more reliable than the assistant.
+
+"""]]
diff --git a/doc/forum/assistant_overzealously_moving_stuff_to_other_repos/comment_2_37c5e9a7669b5b94fbadb8792a765316._comment b/doc/forum/assistant_overzealously_moving_stuff_to_other_repos/comment_2_37c5e9a7669b5b94fbadb8792a765316._comment
new file mode 100644
index 000000000..58292aa14
--- /dev/null
+++ b/doc/forum/assistant_overzealously_moving_stuff_to_other_repos/comment_2_37c5e9a7669b5b94fbadb8792a765316._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.117"
+ subject="comment 2"
+ date="2012-12-19T18:20:50Z"
+ content="""
+I've found and fixed a bug in transfer log parsing that could cause the assistant to get confused about the name of the file it had just transferred, and think it was not preferred content and drop it. I think this was causing both problems reported above.
+"""]]
diff --git a/doc/forum/assistant_overzealously_moving_stuff_to_other_repos/comment_3_87aa4c5942929be81ddc1e2795d56f0e._comment b/doc/forum/assistant_overzealously_moving_stuff_to_other_repos/comment_3_87aa4c5942929be81ddc1e2795d56f0e._comment
new file mode 100644
index 000000000..f4d6240bc
--- /dev/null
+++ b/doc/forum/assistant_overzealously_moving_stuff_to_other_repos/comment_3_87aa4c5942929be81ddc1e2795d56f0e._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 3"
+ date="2012-12-20T00:05:08Z"
+ content="""
+Thanks, I'll give it another shot!
+
+"""]]
diff --git a/doc/forum/assistant_without_watch__63__.mdwn b/doc/forum/assistant_without_watch__63__.mdwn
new file mode 100644
index 000000000..34aa3e441
--- /dev/null
+++ b/doc/forum/assistant_without_watch__63__.mdwn
@@ -0,0 +1,13 @@
+"watch" is described as
+
+> With this running as a daemon in the background, you no longer need to manually run git commands when manipulating your files.
+
+and "assistant" is described as
+
+> Like watch, but also automatically syncs changes to other remotes.
+
+I would like the behaviour of assistant, without the watch part:
+
+I have an archive of large files, which I think would be useful to manage manually using git. But I don't want to manually enforce the "numcopies=" requirement, playing with the assistant and webapp it seems really nice to have it take care of that.
+
+Is there currently an "assistant-without-watch" option? If not, is it planned?
diff --git a/doc/forum/assistant_without_watch__63__/comment_1_be1f7c038426e53209a85ae1119269d5._comment b/doc/forum/assistant_without_watch__63__/comment_1_be1f7c038426e53209a85ae1119269d5._comment
new file mode 100644
index 000000000..dc64ef7d2
--- /dev/null
+++ b/doc/forum/assistant_without_watch__63__/comment_1_be1f7c038426e53209a85ae1119269d5._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.253.75"
+ subject="comment 1"
+ date="2013-02-22T22:31:29Z"
+ content="""
+Not quite.
+
+Recent versions allow you to disable the automatic committing while the assistant is running by setting annex.autocommit=false .. or just by going into the webapp repository list and pausing syncing for the \"here\" repository.
+
+But, with automatic committing disabled, the assistant doesn't know when new files are added, so will not transfer them. The rest of it still works, so for example if another clone of the repository makes changes
+the assistant will merge them in and download the new files.
+
+To transfer new files you created, you could use `git annex copy --auto --to someremote`, which will only copy them if needed to satisfy numcopies.
+"""]]
diff --git a/doc/forum/autobuilders_for_git-annex_to_aid_development.mdwn b/doc/forum/autobuilders_for_git-annex_to_aid_development.mdwn
new file mode 100644
index 000000000..2c1280e51
--- /dev/null
+++ b/doc/forum/autobuilders_for_git-annex_to_aid_development.mdwn
@@ -0,0 +1,34 @@
+This is a continuation of the conversation from [[the comments|design/assistant/#comment-77e54e7ebfbd944c370173014b535c91]] section in the design of git-assistant. In summary, I've setup an auto builder which should help [[Joey]] have an easier time developing on git-annex on non-linux/debian platforms. This builder is currently running on OSX 10.7 with the 64bit version of Haskell Platform.
+
+The builder output can be found at <http://www.sgenomics.org/~jtang/gitbuilder-git-annex-x00-x86_64-apple-darwin10.8.0/>, the CGI on this site does not work as my OSX workstation is pushing the output from another location.
+
+The builder currently tries to build all branches except
+
+* debian-stable
+* pristine-tar
+* setup
+
+It also does not build any of the tags as well, Joey had suggested to ignore the bpo named tags, but for now it's easier for me to not build any tags. To continue on this discussion, if anyone wants to setup a gitbuilder instance, here is the build.sh script that I am using.
+
+<pre>
+#!/bin/bash -x
+
+# Macports
+export PATH=/opt/local/bin:$PATH
+
+# Haskell userland
+export PATH=$PATH:$HOME/.cabal/bin
+
+# Macports gnu
+export PATH=/opt/local/libexec/gnubin:$PATH
+
+make || exit 3
+
+make -q test
+if [ "$?" = 1 ]; then
+ # run "make test", but give it a time limit in case a test gets stuck
+ ../maxtime 1800 make test || exit 4
+fi
+</pre>
+
+It's also using the branches-local script for sorting and prioritising the branches to build, this branches-local script can be found at the [autobuild-ceph](https://github.com/ceph/autobuild-ceph/blob/master/branches-local) repository. If there are other people interested in setting up their own instances of gitbuilder for git-annex, please let me know and I will setup an aggregator page to collect status of the builds. The builder runs and updates on a very regular basis.
diff --git a/doc/forum/autobuilders_for_git-annex_to_aid_development/comment_1_7e88f815e8d9652ef18ea6d54b118962._comment b/doc/forum/autobuilders_for_git-annex_to_aid_development/comment_1_7e88f815e8d9652ef18ea6d54b118962._comment
new file mode 100644
index 000000000..82380cd60
--- /dev/null
+++ b/doc/forum/autobuilders_for_git-annex_to_aid_development/comment_1_7e88f815e8d9652ef18ea6d54b118962._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 1"
+ date="2012-07-02T16:25:55Z"
+ content="""
+I've some binaries for OSX which can be found at <http://www.sgenomics.org/~jtang/gitbuilder-git-annex-x00-x86_64-apple-darwin10.8.0-binary/dist/> its just the master branch, and it's built on a system that runs macports. Binaries are built and updated whenever there are changes made to the master branch of git-annex.
+"""]]
diff --git a/doc/forum/autobuilders_for_git-annex_to_aid_development/comment_2_fef17a10226af5671495c2929653c337._comment b/doc/forum/autobuilders_for_git-annex_to_aid_development/comment_2_fef17a10226af5671495c2929653c337._comment
new file mode 100644
index 000000000..da3cd6e67
--- /dev/null
+++ b/doc/forum/autobuilders_for_git-annex_to_aid_development/comment_2_fef17a10226af5671495c2929653c337._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 2"
+ date="2012-09-29T09:01:11Z"
+ content="""
+I'm currently playing with the autobuilder to get it to do more sensible things so it may be broken for a day or two
+"""]]
diff --git a/doc/forum/bainstorming:_git_annex_push___38___pull.mdwn b/doc/forum/bainstorming:_git_annex_push___38___pull.mdwn
new file mode 100644
index 000000000..8a6c552b8
--- /dev/null
+++ b/doc/forum/bainstorming:_git_annex_push___38___pull.mdwn
@@ -0,0 +1,28 @@
+Wouldn't it make sense to offer
+
+ git annex pull
+
+which would basically do
+
+ git pull
+ git annex get
+
+and
+
+ git annex push
+
+which would do
+
+ git annex commit .
+ git annex put # (the proposed "send to default annex" command)
+ git commit -a -m "$HOST $(date +%F-%H-%M-%S)" # or similar
+ git push
+
+Resulting in commands that are totally analogous to git push & pull: Sync all data from/to a remote.
+
+> Update:
+
+This is useful:
+
+ git config [--global] alias.annex-push '!git pull && git annex add . && git annex copy . --to $REMOTE --fast --quiet && git commit -a -m "$HOST $(date +%F--%H-%M-%S-%Z)" && git push'
+
diff --git a/doc/forum/bainstorming:_git_annex_push___38___pull/comment_1_3a0bf74b51586354b7a91f8b43472376._comment b/doc/forum/bainstorming:_git_annex_push___38___pull/comment_1_3a0bf74b51586354b7a91f8b43472376._comment
new file mode 100644
index 000000000..3d69e8f29
--- /dev/null
+++ b/doc/forum/bainstorming:_git_annex_push___38___pull/comment_1_3a0bf74b51586354b7a91f8b43472376._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-04-05T18:05:00Z"
+ content="""
+Maybe, otoh, part of the point of git-annex is that the data may be too large to pull down all of it.
+
+I find mr useful as a policy layer over top of git-annex, so \"mr update\" can pull down appropriate quantities of data from
+appropriate locations.
+"""]]
diff --git a/doc/forum/bainstorming:_git_annex_push___38___pull/comment_2_b02ca09914e788393c01196686f95831._comment b/doc/forum/bainstorming:_git_annex_push___38___pull/comment_2_b02ca09914e788393c01196686f95831._comment
new file mode 100644
index 000000000..e0ecc1a81
--- /dev/null
+++ b/doc/forum/bainstorming:_git_annex_push___38___pull/comment_2_b02ca09914e788393c01196686f95831._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 2"
+ date="2011-04-05T20:52:52Z"
+ content="""
+No-so-subtle sarcasm taken and acknowledged :)
+
+Arguably, git-annex should know about any local limits and not have them implemented via mr from the outside. I guess my concern boils down to having git-annex do the right thing all by itself with minimal user interaction. And while I really do appreciate the flexibility of chaining commands, I am a firm believer in exposing the common use cases as easily as possible.
+
+And yes, I am fully aware that not all annexes are created equal. Point in case, I would never use git annex pull on my laptop, but I would git annex push extensively.
+
+
+"""]]
diff --git a/doc/forum/bash_completion.mdwn b/doc/forum/bash_completion.mdwn
new file mode 100644
index 000000000..649ad0457
--- /dev/null
+++ b/doc/forum/bash_completion.mdwn
@@ -0,0 +1 @@
+I wrote more than 2 years ago a bash completion file for git-annex (did I miss an official version?) I just updated it today to match current version of git-annex, it is far from perfect, still incomplete, and probably buggy, but works for me. I tried to attach the file in case it could be useful to someone, but it seems that I can't; is it ok to paste the code directly?
diff --git a/doc/forum/bash_completion/comment_1_5c42c0c8e7fc3224bf5406880f9fd0c4._comment b/doc/forum/bash_completion/comment_1_5c42c0c8e7fc3224bf5406880f9fd0c4._comment
new file mode 100644
index 000000000..7f2f0afd0
--- /dev/null
+++ b/doc/forum/bash_completion/comment_1_5c42c0c8e7fc3224bf5406880f9fd0c4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="ringprince"
+ ip="134.76.140.110"
+ subject="comment 1"
+ date="2013-10-10T07:08:21Z"
+ content="""
+I hope it is. I'd love to use it.
+"""]]
diff --git a/doc/forum/bash_completion/comment_2_6cbe3c825db99bf9188a0de8bb937d5b._comment b/doc/forum/bash_completion/comment_2_6cbe3c825db99bf9188a0de8bb937d5b._comment
new file mode 100644
index 000000000..72d5e3fc4
--- /dev/null
+++ b/doc/forum/bash_completion/comment_2_6cbe3c825db99bf9188a0de8bb937d5b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://id.koumbit.net/anarcat"
+ ip="72.0.72.144"
+ subject="comment 2"
+ date="2013-10-10T09:22:00Z"
+ content="""
+it is, please publish.
+"""]]
diff --git a/doc/forum/bash_completion/comment_3_948c40f1e46ca220d61365aebcd4f6d7._comment b/doc/forum/bash_completion/comment_3_948c40f1e46ca220d61365aebcd4f6d7._comment
new file mode 100644
index 000000000..fbe659164
--- /dev/null
+++ b/doc/forum/bash_completion/comment_3_948c40f1e46ca220d61365aebcd4f6d7._comment
@@ -0,0 +1,136 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkUwqII7LhbatqAQY1T5ZZOdPEFcQJKG6I"
+ nickname="Rafael"
+ subject="comment 3"
+ date="2013-10-13T16:14:34Z"
+ content="""
+This code needs the bash-completion file for git by Shawn O. Pearce, I think it is distributed by default on debian. Any feed-back or improvement is welcome! I'm far from expert, use at your own risks.
+
+
+ #!bash
+ #
+ # bash completion support for git-annex
+
+ # depends on git completion file (by Shawn O. Pearce):
+ [ -n \"$__git_whitespacelist\" ] || . $BASH_COMPLETION_DIR/git
+
+
+ # almost copy of __git_aliased_command
+ # requires 2 arguments: alias and main command (after git)
+ __git_aliased_subcommand ()
+ {
+ local word cmdline=$(git --git-dir=\"$(__gitdir)\" \
+ config --get \"alias.$1\")
+ for word in $cmdline; do
+ case \"$word\" in
+ \!*) : shell command alias ;;
+ -*) : option ;;
+ *=*) : setting env ;;
+ git) : git itself ;;
+ \"$2\") : main command
+ local found=1 ;;
+ *)
+ [ -n \"${found-}\" ] && echo \"$word\"
+ return
+ esac
+ done
+ }
+
+
+ _git_annex ()
+ {
+ _get_comp_words_by_ref -n =: cur words
+ # $ git annex 2>&1 |sed '1,6d '|grep -v '^$'|grep -v 'commands:$'|cut -c1-12
+ local subcommands=\"
+ add addurl assistant copy drop edit get import importfeed lock
+ mirror move rmurl sync unlock watch webapp content dead describe
+ direct enableremote group indirect init initremote semitrust
+ trust ungroup untrust vicfg addunused dropunused fix forget fsck
+ merge unused upgrade find help list log map status version
+ whereis migrate reinject unannex uninit dropkey
+ \"
+ # plumbing (to complete?): fromkey fuzztest pre-commit rekey test
+ # transferkey transferkeys xmppgit
+ local subcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"
+ if [ -z \"$subcommand\" ]; then
+ ## search for aliased subcommand
+ ## works only if the alias is invoked just after git
+ ## (simpler, cf _git function)
+ local maybesubcom maybealias=${words[1]}
+ [ -n \"$maybealias\" ] && # false with a bash alias='git annex'
+ [ \"${maybealias:0:1}\" != '-' ] &&
+ maybesubcom=$(__git_aliased_subcommand \"$maybealias\" annex)
+ for subcommand in $subcommands \"\"; do
+ [ \"$maybesubcom\" = \"$subcommand\" ] && break
+ done
+ [ -z \"$subcommand\" ] &&
+ __gitcomp \"$subcommands\" &&
+ return
+ fi
+ case \"$cur\" in
+ --from=*|--to=*|--trust=*|--semitrust=*|--untrust=*|--in=*)
+ __gitcomp \"here $(__git_remotes)\" \"\" \"${cur##*=}\"
+ ;;
+ --*)
+ __gitcomp \"
+ --force --fast --auto --all --unused --quiet --verbose --json --debug
+ --no-debug --from= --to= --numcopies= --time-limit= --trust= --semitrust=
+ --untrust= --trust-glacier-inventory --backend= --format= --user-agent=
+ --exclude= --include= --in= --copies= --inbackend= --inallgroup=
+ --smallerthan= --largerthan= --not --and --or
+ \"
+ ;;
+ # -*)
+ # __gitcomp \"-( -) -c\"
+ # ;;
+ *)
+ case \"$subcommand\" in
+ # subcommands with PATH (currently outputs wrongly \"uninit\",
+ # and not \"reinject\")
+ # $ tr ' ' '|' <<< $(git annex 2>&1 |sed '1,6d '|grep -v '^$' | \
+ # grep -v 'commands:$'|grep PATH |cut -c1-12)
+ add|copy|drop|edit|get|import|lock|mirror|move|unlock|fix| \
+ fsck|find|list|log|status|whereis|migrate|unannex| \
+ fromkey|pre-commit|rekey|reinject)
+ COMPREPLY=() # complete with paths
+ ;;
+ addurl|importfeed|rmurl) # URL commands
+ COMPREPLY=() # at least works with file://...
+ ;;
+ init|uninit|unused|merge|status|map|upgrade|version|assistant| \
+ watch|webapp|direct|indirect|vicfg|forget|help) # | plumbing...
+ COMPREPLY= # no more args expected
+ # is 'COMPREPLY=' correct? (seems not standard practice...)
+ ;;
+ describe|trust|untrust|semitrust|sync|content|dead|group|ungroup)
+ __gitcomp \"here $(__git_remotes)\"
+ # TODO: handle git-annex special remotes
+ ;;
+ initremote|enableremote)
+ case \"$cur\" in
+ type=*)
+ __gitcomp \"S3 bup directory rsync gcrypt webdav\" \"\" \"${cur##type=}\"
+ ;;
+ encryption=*)
+ __gitcomp \"none hybrid shared pubkey\" \"\" \"${cur##encryption=}\"
+ ;;
+
+ buprepo=|directory=|rsyncurl=)
+ COMPREPLY=()
+ # use COMPREPLY (and compgen below) directly because
+ # __gitcomp does not handle '*=*' pattern, only '--*=*'
+ # Writing a __gitannexcomp function may be worth it.
+ ;;
+ *)
+ local initremoteopts=\"
+ type= encryption= buprepo= directory= rsyncurl= \"
+ COMPREPLY=($(compgen -W \"$initremoteopts \" -- \"$cur\"))
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ esac
+ }
+
+"""]]
diff --git a/doc/forum/bash_completion/comment_4_dbae348b230b780cda91ed8576b8f9fa._comment b/doc/forum/bash_completion/comment_4_dbae348b230b780cda91ed8576b8f9fa._comment
new file mode 100644
index 000000000..525a613b0
--- /dev/null
+++ b/doc/forum/bash_completion/comment_4_dbae348b230b780cda91ed8576b8f9fa._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="64.134.31.139"
+ subject="comment 4"
+ date="2013-10-15T17:53:21Z"
+ content="""
+@Rafael, you should put a license on that code..
+"""]]
diff --git a/doc/forum/batch_check_on_remote_when_using_copy.mdwn b/doc/forum/batch_check_on_remote_when_using_copy.mdwn
new file mode 100644
index 000000000..633b61d6f
--- /dev/null
+++ b/doc/forum/batch_check_on_remote_when_using_copy.mdwn
@@ -0,0 +1,34 @@
+When I copy my local repository with SHA* to a remote repo with SHA*, every single file is checked by itself which seems rather inefficient. When my remote is accessed via ssh, git-annex opens a new connections for every check. If you are not using a ssh key or key agent, this gets tedious...
+
+For all locked files, either git's built-in mechanisms should be used or, if that's not possible, a few hundred checksums (assuming SHA* backend) should be transfered at once and then checked locally before deciding that to transfer.
+
+Once all checks are done, one single transfer session should be started. Creating new sessions and waiting for TCP's slowstart to get going is a lot less than efficient.
+
+
+-- RichiH
+
+> (Use of SHA is irrelevant here, copy does not checksum anything.)
+>
+> I think what you're seeing is
+> that `git annex copy --to remote` is slow, going to the remote repository
+> every time to see if it has the file, while `git annex copy --from remote`
+> is fast, since it looks at what files are locally present.
+>
+> That is something I mean to improve. At least `git annex copy --fast --to remote`
+> could easily do a fast copy of all files that are known to be missing from
+> the remote repository. When local and remote git repos are not 100% in sync,
+> relying on that data could miss some files that the remote doesn't have anymore,
+> but local doesn't know it dropped. That's why it's a candidate for `--fast`.
+>
+> I've just implemented that.
+>
+> While I do hope to improve ssh usage so that it sshs once, and feeds
+> `git-annex-shell` a series of commands to run, that is a much longer-term
+> thing. --[[Joey]]
+
+>> FYI, in a repo with 1228 files, all small, repos _completely in sync_.
+
+ % git annex copy . --to foo # 1200 seconds
+ % git annex copy . --to foo --fast # 20 seconds
+
+>> RichiH
diff --git a/doc/forum/benefit_of_splitting_a_repository.mdwn b/doc/forum/benefit_of_splitting_a_repository.mdwn
new file mode 100644
index 000000000..111feb2cf
--- /dev/null
+++ b/doc/forum/benefit_of_splitting_a_repository.mdwn
@@ -0,0 +1,10 @@
+I am evaluating the best strategy to use git-annex to manage my media library. It consists of about 300.000 files totaling 1 TB of data.
+
+My question is, wheither it would be of advantage to split the repo into several smaller ones (Like Photos, Videos, Musik, Books, ...)?
+
+Would this affect performance of certain operations? I.e. Operations that have superlinear (O(n^a) with a > 1) complexity?
+
+I am thinking about "git annex unused", which takes 22 minutes on my machine performed on the full repo.
+
+
+Do you have more interesting information on using git-annex in this scale?
diff --git a/doc/forum/benefit_of_splitting_a_repository/comment_1_93a86cb03b66e7ab5dd7146e7b86c9e8._comment b/doc/forum/benefit_of_splitting_a_repository/comment_1_93a86cb03b66e7ab5dd7146e7b86c9e8._comment
new file mode 100644
index 000000000..72ea4f29b
--- /dev/null
+++ b/doc/forum/benefit_of_splitting_a_repository/comment_1_93a86cb03b66e7ab5dd7146e7b86c9e8._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.49"
+ subject="comment 1"
+ date="2012-11-28T18:16:10Z"
+ content="""
+`git-annex unused` needs to scan the entire repository. But it uses a bloom filter, so its complexity is O(n) to the number of keys.
+
+`git annex fsck` scans the entire repository and also reads all available file content. But we have incremental fsck support now.
+
+The rest of git-annex is designed to have good locality.
+
+The main problem you are likely to run into is innefficiencies with git's index file. This file records the status of every file in the repository, and commands like `git add` rewrite the whole file. git-annex uses a journal to minimise operations that need to rewrite the git index file, but this won't help you when you're using raw git commands in the repository.
+
+"""]]
diff --git a/doc/forum/benefit_of_splitting_a_repository/comment_2_4e2fed247298d620fee7be883a1e86a6._comment b/doc/forum/benefit_of_splitting_a_repository/comment_2_4e2fed247298d620fee7be883a1e86a6._comment
new file mode 100644
index 000000000..c102243f4
--- /dev/null
+++ b/doc/forum/benefit_of_splitting_a_repository/comment_2_4e2fed247298d620fee7be883a1e86a6._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlgyVag95OnpvSzQofjyX0WjW__MOMKsl0"
+ nickname="Sehr"
+ subject="comment 2"
+ date="2012-12-02T19:24:59Z"
+ content="""
+The biggest problem I am facing actually is the git pack-objects command, which takes forever.
+
+I am not starting it manually, but \"git annex sync\" is.
+
+Any advice on how to make this faster?
+Does it make sense at all to pack a bunch of uncompressible simlinks?
+
+I already tried the delta=false attrigute, without any (major) effect.
+"""]]
diff --git a/doc/forum/cabal_install_fails_on_uuid.mdwn b/doc/forum/cabal_install_fails_on_uuid.mdwn
new file mode 100644
index 000000000..606f7954d
--- /dev/null
+++ b/doc/forum/cabal_install_fails_on_uuid.mdwn
@@ -0,0 +1,23 @@
+Hey, so I am trying to compile git-annex through cabal but it fails on building uuid. It gives me this strange error:
+
+ Resolving dependencies...
+ Configuring uuid-1.3.1...
+ Building uuid-1.3.1...
+ Preprocessing library uuid-1.3.1...
+ [ 1 of 10] Compiling Data.UUID.Builder ( Data/UUID/Builder.hs, dist/build/Data/UUID/Builder.o )
+ [ 2 of 10] Compiling Data.Word.Util ( Data/Word/Util.hs, dist/build/Data/Word/Util.o )
+ [ 3 of 10] Compiling Data.UUID.Internal ( Data/UUID/Internal.hs, dist/build/Data/UUID/Internal.o )
+ Data/UUID/Internal.hs:394:20: Not in scope: `BL.fromStrict'
+ Data/UUID/Internal.hs:399:48: Not in scope: `BL.toStrict'
+ cabal: Error: some packages failed to install:
+ git-annex-4.20131002 depends on uuid-1.3.1 which failed to install.
+ uuid-1.3.1 failed during the building phase. The exception was:
+ ExitFailure 1
+
+Any advice on how to proceed?
+
+System is: Debian Wheezy (CrunchBang Waldorf) 64bit
+
+versions are:
+ uuid-dev: 2.20.1-5.3
+ cabal: 1.14.0
diff --git a/doc/forum/cabal_install_fails_on_uuid/comment_1_2a3963e21bc7ff526124b902cb0b6ad2._comment b/doc/forum/cabal_install_fails_on_uuid/comment_1_2a3963e21bc7ff526124b902cb0b6ad2._comment
new file mode 100644
index 000000000..47fe7e5ff
--- /dev/null
+++ b/doc/forum/cabal_install_fails_on_uuid/comment_1_2a3963e21bc7ff526124b902cb0b6ad2._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="64.134.31.139"
+ subject="comment 1"
+ date="2013-10-22T17:52:10Z"
+ content="""
+That version of the haskell uuid library installs ok on my Debian sid system. Seems to me you have a too old version of the haskell bytestring library, which added `fromStrict` in version 0.10.0.0. Probably `cabal install bytestring` will fix it up for you, but building git-annex from source using cabal is a complicated thing that can go wrong in many ways. Have you considered one of the prebuilt binaries?
+"""]]
diff --git a/doc/forum/cabal_install_fails_on_uuid/comment_2_1609525998e2b36c04d67f4d988139c0._comment b/doc/forum/cabal_install_fails_on_uuid/comment_2_1609525998e2b36c04d67f4d988139c0._comment
new file mode 100644
index 000000000..0f308df0b
--- /dev/null
+++ b/doc/forum/cabal_install_fails_on_uuid/comment_2_1609525998e2b36c04d67f4d988139c0._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkj7tMEJKcZpNXIFkHAAcNi5qJFSFyjn6o"
+ nickname="thissideup"
+ subject="comment 2"
+ date="2013-10-23T11:15:20Z"
+ content="""
+I contacted the maintainer of the uuid-package and he fixed the issue in the current release, so everythings fine now. and: everything compiled beautifully.
+
+But to answer your question: I tend to rather compile things myself if I don't find them (or a current enough version) in the repos - but that's purely personal. ;)
+"""]]
diff --git a/doc/forum/can_I_only_add_my_own_files__63__.mdwn b/doc/forum/can_I_only_add_my_own_files__63__.mdwn
new file mode 100644
index 000000000..555429582
--- /dev/null
+++ b/doc/forum/can_I_only_add_my_own_files__63__.mdwn
@@ -0,0 +1,27 @@
+Hi,
+
+[ sorry for the wrong bugreport in the last version of this entry ]
+
+It seems as if I can only add my own file to the annex, even if I have group write permissions. Is that correct? Can that be circumvented other than copying/deleting the large file?
+
+Here is some demonstration:
+
+ > git init
+ > git config user.name dtr
+ > git config user.email dtrn@dtrn.com
+
+ > dd if/dev/zero of=test2.bin count=1000
+
+ > ll
+ -rw-rw-r-- 1 dtr dtr 512000 Sep 16 2013 test2.bin
+
+ > sudo chown someone test2.bin
+ > ll
+ -rw-rw-r-- 1 someone dtr 512000 Sep 16 2013 test2.bin
+
+ > git annex init
+ > git annex add test2.bin
+ add test2.bin (checksum...)
+ git-annex: /test-git-annex/.git/annex/objects/Fq/f6/SHA256-s512000--2d4da04b861bb9dbe77c871415931785a18138d6db035f1bbcd0cf8277c6fc23/SHA256-s512000--2d4da04b861bb9dbe77c871415931785a18138d6db035f1bbcd0cf8277c6fc23: setFileMode: permission denied (Operation not permitted)
+ failed
+ git-annex: add: 1 failed
diff --git a/doc/forum/can_I_only_add_my_own_files__63__/comment_1_767d647af9d0345f337338d6319071fa._comment b/doc/forum/can_I_only_add_my_own_files__63__/comment_1_767d647af9d0345f337338d6319071fa._comment
new file mode 100644
index 000000000..80efaf04b
--- /dev/null
+++ b/doc/forum/can_I_only_add_my_own_files__63__/comment_1_767d647af9d0345f337338d6319071fa._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.220"
+ subject="comment 1"
+ date="2013-09-25T18:42:00Z"
+ content="""
+git-annex needs to be able to lock down files to ensure that nobody can write to them, and to do this it needs to remove the write bit, and you can't remove the write bit from a file you don't own.
+
+Note that if you configure git's core.sharedRepository when making a repository (git init --shared), then all files in both git and git-annex will be group writable. Put you and the other person you wanted to be able to write to the file in a group, and you can both access the repository. So that's the right way to do it.
+"""]]
diff --git a/doc/forum/can_I_only_add_my_own_files__63__/comment_2_0c3306ffb38b97b54e1e0436d12c1876._comment b/doc/forum/can_I_only_add_my_own_files__63__/comment_2_0c3306ffb38b97b54e1e0436d12c1876._comment
new file mode 100644
index 000000000..5a63a7176
--- /dev/null
+++ b/doc/forum/can_I_only_add_my_own_files__63__/comment_2_0c3306ffb38b97b54e1e0436d12c1876._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="ringprince"
+ ip="134.76.140.110"
+ subject="comment 2"
+ date="2013-09-26T06:32:48Z"
+ content="""
+Thanks a lot. The solution with --shared was really helpful.
+"""]]
diff --git a/doc/forum/can_git-annex_replace_ddm__63__.mdwn b/doc/forum/can_git-annex_replace_ddm__63__.mdwn
new file mode 100644
index 000000000..8d49652c3
--- /dev/null
+++ b/doc/forum/can_git-annex_replace_ddm__63__.mdwn
@@ -0,0 +1,13 @@
+Hi,
+a few years ago I wrote a tool called 'ddm'. The code is overengineered and the script is more complicated then it should be,
+but I think it demonstrates some good use cases, and I wonder how well git-annex can fulfill the requirements for those use cases - maybe I should remove ddm and start hacking with git-annex instead.
+
+To answer this question, you should read the section about the possible dataset types on http://dieter.plaetinck.be/ddm_a_distributed_data_manager.html, and the example at the bottom of that page. it demonstrates the idea behind the "selection" dataset to always try to keep a subset (the most appropriate, based on the output of some script) of files "checked out".
+the introduction section on https://github.com/Dieterbe/ddm/raw/358f7cf92c0ba7b336dc97638351d4e324461afa/MANUAL should further clarify things, as well as give some more good use cases (as you can see it's a bit more about [semi-]automated workflows then purely tracking what's where)
+
+So I'm not sure, maybe the way to go for me is to make git-annex my "housekeeping about which data is where" backend and make ddm into a set of policies and tools on top of git-annex.
+
+Any input?
+
+Thanks,
+Dieter
diff --git a/doc/forum/can_git-annex_replace_ddm__63__/comment_1_aa05008dfe800474ff76678a400099e1._comment b/doc/forum/can_git-annex_replace_ddm__63__/comment_1_aa05008dfe800474ff76678a400099e1._comment
new file mode 100644
index 000000000..eb824971f
--- /dev/null
+++ b/doc/forum/can_git-annex_replace_ddm__63__/comment_1_aa05008dfe800474ff76678a400099e1._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-02-14T22:08:54Z"
+ content="""
+Yes, there is value in layering something over git-annex to use a policy to choose what goes where.
+
+I use [mr](http://kitenet.net/~joey/code/mr/) to update and manage all my repositories, and since mr can be made to run arbitrary commands when doing eg, an update, I use its config file as such a policy layer. For example, my podcasts are pulled into my sound repository in a subdirectory; boxes that consume podcasts run \"git pull; git annex get podcasts --exclude=\"*/out/*\"; git annex drop podcasts/*/out\". I move podcasts to \"out\" directories once done with them (I have yet to teach mpd to do that for me..), and the next time I run \"mr update\" to update everything, it pulls down new ones and removes old ones.
+
+I don't see any obstacle to doing what you want. May be that you'd need better querying facilities in git-annex (so the policy layer can know what is available where), or finer control (--exclude is a good enough hammer for me, but maybe not for you).
+"""]]
diff --git a/doc/forum/can_git-annex_replace_ddm__63__/comment_2_008554306dd082d7f543baf283510e92._comment b/doc/forum/can_git-annex_replace_ddm__63__/comment_2_008554306dd082d7f543baf283510e92._comment
new file mode 100644
index 000000000..ab114bb1c
--- /dev/null
+++ b/doc/forum/can_git-annex_replace_ddm__63__/comment_2_008554306dd082d7f543baf283510e92._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="http://dieter-be.myopenid.com/"
+ nickname="dieter"
+ subject="comment 2"
+ date="2011-02-16T21:32:04Z"
+ content="""
+thanks Joey,
+
+is it possible to run some git annex command that tells me, for a specific directory, which files are available in an other remote? (and which remote, and which filenames?)
+I guess I could run that, do my own policy thingie, and run `git annex get` for the files I want.
+
+For your podcast use case (and some of my use cases) don't you think git [annex] might actually be overkill? For example your podcasts use case, what value does git annex give over a simple rsync/rm script?
+such a script wouldn't even need a data store to store its state, unlike git. it seems simpler and cleaner to me.
+
+for the mpd thing, check http://alip.github.com/mpdcron/ (bad project name, it's a plugin based \"event handler\")
+you should be able to write a simple plugin for mpdcron that does what you want (or even interface with mpd yourself from perl/python/.. to use its idle mode to get events)
+
+Dieter
+"""]]
diff --git a/doc/forum/can_git-annex_replace_ddm__63__/comment_3_4c69097fe2ee81359655e59a03a9bb8d._comment b/doc/forum/can_git-annex_replace_ddm__63__/comment_3_4c69097fe2ee81359655e59a03a9bb8d._comment
new file mode 100644
index 000000000..5cdd6aa0c
--- /dev/null
+++ b/doc/forum/can_git-annex_replace_ddm__63__/comment_3_4c69097fe2ee81359655e59a03a9bb8d._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 3"
+ date="2011-03-16T03:01:17Z"
+ content="""
+Whups, the comment above got stuck in moderation queue for 27 days. I will try to check that more frequently.
+
+In the meantime, I've implemented \"git annex whereis\" -- enjoy!
+
+I find keeping my podcasts in the annex useful because it allows me to download individual episodes or poscasts easily when low bandwidth is available (ie, dialup), or over sneakernet. And generally keeps everything organised.
+"""]]
diff --git a/doc/forum/cannot_fetch_from___40__gpg-encrypted__41___rsync_remote_on_MacOSX.mdwn b/doc/forum/cannot_fetch_from___40__gpg-encrypted__41___rsync_remote_on_MacOSX.mdwn
new file mode 100644
index 000000000..59ca2e9fc
--- /dev/null
+++ b/doc/forum/cannot_fetch_from___40__gpg-encrypted__41___rsync_remote_on_MacOSX.mdwn
@@ -0,0 +1,18 @@
+I have a remote rsync with gpg encryption and can restore without problems on my thinkpad (FreeBSD) - but not on my MacOSX:
+
+$ git annex whereis DSC_7615.JPG
+whereis DSC_7615.JPG (2 copies)
+ 6855de17-c8fb-11e1-9948-f0def1c18073 -- thinkpad
+ e388bcf6-c8fc-11e1-a96f-6ffcbceb4af4 -- backup (rsync xxxx)
+ok
+
+$ git annex get --from backup DSC_7615.JPG
+fatal: Could not switch to '../../../.git/annex/objects/Pw/XP/SHA256-s1028494--SHA256': No such file or directory
+
+git-annex: <file descriptor: 6>: hGetLine: end of file
+failed
+git-annex: get: 1 failed
+
+$ git annex version
+git-annex version: 3.20120629
+local repository version: 3
diff --git a/doc/forum/cannot_fetch_from___40__gpg-encrypted__41___rsync_remote_on_MacOSX/comment_1_21f0101447623f5a0cf9e72c3ff463bb._comment b/doc/forum/cannot_fetch_from___40__gpg-encrypted__41___rsync_remote_on_MacOSX/comment_1_21f0101447623f5a0cf9e72c3ff463bb._comment
new file mode 100644
index 000000000..c6c962c40
--- /dev/null
+++ b/doc/forum/cannot_fetch_from___40__gpg-encrypted__41___rsync_remote_on_MacOSX/comment_1_21f0101447623f5a0cf9e72c3ff463bb._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="comment 1"
+ date="2012-08-07T13:11:48Z"
+ content="""
+Do the remotes in `.git/config` look the same?
+"""]]
diff --git a/doc/forum/cannot_fetch_from___40__gpg-encrypted__41___rsync_remote_on_MacOSX/comment_2_6234ca64bd03a0e15efbe8f5c204338a._comment b/doc/forum/cannot_fetch_from___40__gpg-encrypted__41___rsync_remote_on_MacOSX/comment_2_6234ca64bd03a0e15efbe8f5c204338a._comment
new file mode 100644
index 000000000..5ae18235b
--- /dev/null
+++ b/doc/forum/cannot_fetch_from___40__gpg-encrypted__41___rsync_remote_on_MacOSX/comment_2_6234ca64bd03a0e15efbe8f5c204338a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="hannes"
+ ip="130.226.133.37"
+ subject="they do"
+ date="2012-08-07T14:06:55Z"
+ content="""
+I was also able to copy from the macosx to the rsync backup...
+"""]]
diff --git a/doc/forum/cannot_fetch_from___40__gpg-encrypted__41___rsync_remote_on_MacOSX/comment_3_5ac2b520a907e232984eb513ce088054._comment b/doc/forum/cannot_fetch_from___40__gpg-encrypted__41___rsync_remote_on_MacOSX/comment_3_5ac2b520a907e232984eb513ce088054._comment
new file mode 100644
index 000000000..d80a01a0b
--- /dev/null
+++ b/doc/forum/cannot_fetch_from___40__gpg-encrypted__41___rsync_remote_on_MacOSX/comment_3_5ac2b520a907e232984eb513ce088054._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="hannes"
+ ip="130.226.133.37"
+ subject="also, fsck works"
+ date="2012-08-07T14:12:20Z"
+ content="""
+git annex fsck -fbackup some-local-and-remote-file works fine.
+"""]]
diff --git a/doc/forum/cannot_fetch_from___40__gpg-encrypted__41___rsync_remote_on_MacOSX/comment_4_183dd1c29f66539193e7c0b73f329430._comment b/doc/forum/cannot_fetch_from___40__gpg-encrypted__41___rsync_remote_on_MacOSX/comment_4_183dd1c29f66539193e7c0b73f329430._comment
new file mode 100644
index 000000000..6ab9ebb25
--- /dev/null
+++ b/doc/forum/cannot_fetch_from___40__gpg-encrypted__41___rsync_remote_on_MacOSX/comment_4_183dd1c29f66539193e7c0b73f329430._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ subject="comment 4"
+ date="2012-08-07T17:53:35Z"
+ content="""
+I recently encountered this problem on OSX, and I'm pretty sure I fixed it. But I don't remember the details of how. I'm sorry I don't have more detail, but I recommend trying a newer version of git-annex.
+
+And if the problem persists, --debug will show the git commands and should help identify the one that's being passed bad parameters.
+"""]]
diff --git a/doc/forum/cannot_fetch_from___40__gpg-encrypted__41___rsync_remote_on_MacOSX/comment_5_c920d04ffe332caed9d223fa0ac42746._comment b/doc/forum/cannot_fetch_from___40__gpg-encrypted__41___rsync_remote_on_MacOSX/comment_5_c920d04ffe332caed9d223fa0ac42746._comment
new file mode 100644
index 000000000..32420ac66
--- /dev/null
+++ b/doc/forum/cannot_fetch_from___40__gpg-encrypted__41___rsync_remote_on_MacOSX/comment_5_c920d04ffe332caed9d223fa0ac42746._comment
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ subject="remember now"
+ date="2012-08-07T19:37:22Z"
+ content="""
+This was a bug in determining the git version at compile time. Fixed in commit bafc50e05e098234d2d22886085d9844fc763e0e which was included in version 3.20120721.
+"""]]
diff --git a/doc/forum/cannot_fetch_from___40__gpg-encrypted__41___rsync_remote_on_MacOSX/comment_6_7a3cf0853a8ec7b996e19b5e80145d21._comment b/doc/forum/cannot_fetch_from___40__gpg-encrypted__41___rsync_remote_on_MacOSX/comment_6_7a3cf0853a8ec7b996e19b5e80145d21._comment
new file mode 100644
index 000000000..9ffb376a7
--- /dev/null
+++ b/doc/forum/cannot_fetch_from___40__gpg-encrypted__41___rsync_remote_on_MacOSX/comment_6_7a3cf0853a8ec7b996e19b5e80145d21._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="hannes"
+ ip="130.226.133.37"
+ subject="awesome, thanks"
+ date="2012-08-08T12:25:19Z"
+ content="""
+works with an updated git-annex!
+"""]]
diff --git a/doc/forum/central_non-bare_and_git_push.txt b/doc/forum/central_non-bare_and_git_push.txt
new file mode 100644
index 000000000..ecc81096e
--- /dev/null
+++ b/doc/forum/central_non-bare_and_git_push.txt
@@ -0,0 +1,9 @@
+hi,
+
+i have a usecase that i think many people have. a cental server which should be non-bare to be able to browse the files also via webdav.
+multiple clients behind nat so only pushes via xmpp are possible.
+
+i set everything up without xmpp, it works but if files are updated, none of the clients gets a git push of course because ssh works only unidirectional.
+i couldnt figure out how to set up xmpp push and have a non-bare central repo at the same time because i have to choose between ssh and xmpp git remote on the clients to the server.
+
+thanks!
diff --git a/doc/forum/central_non-bare_and_git_push/comment_1_76d0c73c8985e860eb86333c63be6340._comment b/doc/forum/central_non-bare_and_git_push/comment_1_76d0c73c8985e860eb86333c63be6340._comment
new file mode 100644
index 000000000..6bf3d1a5e
--- /dev/null
+++ b/doc/forum/central_non-bare_and_git_push/comment_1_76d0c73c8985e860eb86333c63be6340._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 1"
+ date="2013-07-25T17:05:00Z"
+ content="""
+Simply set up xmpp on your clients in addition to the central repository you have now. When one client pushes over ssh to the central repo, it will use XMPP to inform other clients of the change.
+"""]]
diff --git a/doc/forum/clear_box.com_repository.mdwn b/doc/forum/clear_box.com_repository.mdwn
new file mode 100644
index 000000000..0de67cf62
--- /dev/null
+++ b/doc/forum/clear_box.com_repository.mdwn
@@ -0,0 +1 @@
+Using webapp I cannot get rid of box.com repository, it is locked in 'cleaning out' state for more than two weeks. How can I remove the repository from the list?
diff --git a/doc/forum/clear_box.com_repository/comment_1_2e839d8f974269c80a9fca183712350f._comment b/doc/forum/clear_box.com_repository/comment_1_2e839d8f974269c80a9fca183712350f._comment
new file mode 100644
index 000000000..939e9b893
--- /dev/null
+++ b/doc/forum/clear_box.com_repository/comment_1_2e839d8f974269c80a9fca183712350f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-06-14T16:21:54Z"
+ content="""
+We need to first understand why it's not finishing the process. Does the box.com repository still contain files? You can find out by running the command: `git annex find --in box.com` (substitute the name of your remote for box.com as needed).
+"""]]
diff --git a/doc/forum/clear_box.com_repository/comment_2_8f9c7248a148a24ae2aba39c4a79a6d1._comment b/doc/forum/clear_box.com_repository/comment_2_8f9c7248a148a24ae2aba39c4a79a6d1._comment
new file mode 100644
index 000000000..9725c96e5
--- /dev/null
+++ b/doc/forum/clear_box.com_repository/comment_2_8f9c7248a148a24ae2aba39c4a79a6d1._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="tomas"
+ ip="188.167.111.235"
+ subject="comment 2"
+ date="2013-06-16T13:32:31Z"
+ content="""
+The result of that command returned without writing any files.
+"""]]
diff --git a/doc/forum/clear_box.com_repository/comment_3_f64ad21e5abfbf4e1f925b3d651bdba3._comment b/doc/forum/clear_box.com_repository/comment_3_f64ad21e5abfbf4e1f925b3d651bdba3._comment
new file mode 100644
index 000000000..6b19da5c7
--- /dev/null
+++ b/doc/forum/clear_box.com_repository/comment_3_f64ad21e5abfbf4e1f925b3d651bdba3._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-06-17T17:34:04Z"
+ content="""
+In that case, I'd expect the assistant will notice it can remove the remote on the next full scan, and prompt you to finish the removal. Full scans are run in a few situations, but the only guaranteed way to run one is to stop and restart the assistant.
+
+You could also enable debug mode when starting it, I'm sure the log would be useful if it somehow doesn't behave how it should.
+"""]]
diff --git a/doc/forum/clear_box.com_repository/comment_4_f8c06ac9b23b51cf18d362c260fc47a9._comment b/doc/forum/clear_box.com_repository/comment_4_f8c06ac9b23b51cf18d362c260fc47a9._comment
new file mode 100644
index 000000000..a36ca1237
--- /dev/null
+++ b/doc/forum/clear_box.com_repository/comment_4_f8c06ac9b23b51cf18d362c260fc47a9._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="tomas"
+ ip="188.167.111.235"
+ subject="comment 4"
+ date="2013-06-17T20:17:30Z"
+ content="""
+Hi, I cannot enable debug logging via webapp, because after restart the checkbox is unchecked again. I saw nothing at all in logs after restart, the box repo is still hanging there. I would prefer using command line to remove the last traces of this repository.
+Another similar question - how do I unassociate two repositories? The web app warns me that about deleting repo, not sure if it would also wipe it out. Is there a CLI command to add and remove the associations (git remote rm?)? Overall great work, but I am lost with the webapp. It is good for learning the concepts, but I would love to know which commands it actually executes on the backend to make the gui -> cli transition easier.
+
+Version: 4.20130516.1
+Build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP
+
+"""]]
diff --git a/doc/forum/clear_box.com_repository/comment_5_61d401b29322802cb25896503f3e6514._comment b/doc/forum/clear_box.com_repository/comment_5_61d401b29322802cb25896503f3e6514._comment
new file mode 100644
index 000000000..122e054a9
--- /dev/null
+++ b/doc/forum/clear_box.com_repository/comment_5_61d401b29322802cb25896503f3e6514._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 5"
+ date="2013-06-17T23:53:24Z"
+ content="""
+Use the --debug switch to enable debugging on startup.
+"""]]
diff --git a/doc/forum/cloud_services_to_support.mdwn b/doc/forum/cloud_services_to_support.mdwn
new file mode 100644
index 000000000..4d6bde1b5
--- /dev/null
+++ b/doc/forum/cloud_services_to_support.mdwn
@@ -0,0 +1,16 @@
+git-annex can already be used to store data in several cloud services:
+Amazon S3, rsync.net, Tahoe-LAFS, The Internet Archive.
+
+I would like to support as many other cloud services as possible/reasonable.
+
+* [[swift|todo/wishlist:_swift_backend]]
+* Dropbox (I had been reluctant to go there due to it using a non-free client,
+ which I have no interest in installing, but there is actually an API,
+ and already a
+ [haskell module to use it](http://hackage.haskell.org/package/dropbox-sdk).
+ Would need to register for an API key.
+ <http://www.dropbox.com/developers/start/core>.
+ Annoyingly, Dropbox reviews each app before granting it production status.
+ Whoops my interest level dropped by 99%.)
+
+Post others in the comments. --[[Joey]]
diff --git a/doc/forum/cloudcmd.mdwn b/doc/forum/cloudcmd.mdwn
new file mode 100644
index 000000000..a572abf1c
--- /dev/null
+++ b/doc/forum/cloudcmd.mdwn
@@ -0,0 +1,6 @@
+Hi,
+
+Glad to see this project appears to be doing well. I just wanted to mention that there's a similar project called cloudcmd that has many of the same use cases in spirit: https://github.com/briangu/cloudcmd
+
+Cheers,
+Brian
diff --git a/doc/forum/commit_current_workdir_state_in_direct_mode.mdwn b/doc/forum/commit_current_workdir_state_in_direct_mode.mdwn
new file mode 100644
index 000000000..63945f790
--- /dev/null
+++ b/doc/forum/commit_current_workdir_state_in_direct_mode.mdwn
@@ -0,0 +1,5 @@
+I'd like to commit the current workdir state in direct mode in a script. This is what git annex watch does but I can not reliably start and stop git annex watch in a cron script.
+
+Is this already possible with the current api or could we have something like git annex watch --once?
+
+Thank you, Thomas Koch
diff --git a/doc/forum/commit_current_workdir_state_in_direct_mode/comment_1_748481ff00374f570284bd4571584874._comment b/doc/forum/commit_current_workdir_state_in_direct_mode/comment_1_748481ff00374f570284bd4571584874._comment
new file mode 100644
index 000000000..50bd6661c
--- /dev/null
+++ b/doc/forum/commit_current_workdir_state_in_direct_mode/comment_1_748481ff00374f570284bd4571584874._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.21"
+ subject="comment 1"
+ date="2013-07-31T16:25:34Z"
+ content="""
+It should be sufficient to run: `git annex add; git annex sync`
+
+That adds any new files and then commits those along with any changed or deleted files.
+"""]]
diff --git a/doc/forum/confusion_with_remotes__44___map.mdwn b/doc/forum/confusion_with_remotes__44___map.mdwn
new file mode 100644
index 000000000..0ae75d4e9
--- /dev/null
+++ b/doc/forum/confusion_with_remotes__44___map.mdwn
@@ -0,0 +1,113 @@
+I'm starting out with git-annex and running into some confusion with setting up the remotes.
+
+I have three systems I'm trying to set up (domains edited):
+
+* psychosis: ssh://psychosis.foo.com/vid
+* bacon: ssh://bucket.foo.com/vid
+* bucket: ssh://bucket.bar.org/vid
+
+And one bare repository so that I can have a single place to push/pull:
+
+* origin: https://git.foo.com/jim/vid.git
+
+On psychosis:
+
+ psychosis$ git config --list | grep ^remote | sort
+ remote.bacon.annex-uuid=8f1f0898-f8c1-11e0-9bf2-b387af26ee63
+ remote.bacon.fetch=+refs/heads/*:refs/remotes/bacon/*
+ remote.bacon.url=ssh://bucket.foo.com/vid
+ remote.bucket.annex-uuid=82814942-f8e0-11e0-b053-e70a61e98e19
+ remote.bucket.fetch=+refs/heads/*:refs/remotes/bucket/*
+ remote.bucket.url=ssh://bucket.bar.org/vid
+ remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
+ remote.origin.url=https://git.foo.com/jim/vid.git
+
+ psychosis$ git annex status
+ supported backends: WORM SHA1 SHA256 SHA512 SHA224 SHA384 SHA1E SHA256E SHA512E SHA224E SHA384E URL
+ supported remote types: git S3 bup directory rsync web hook
+ known repositories:
+ 09c0b436-f8de-11e0-842f-b7644539d57f -- here (psychosis)
+ 82814942-f8e0-11e0-b053-e70a61e98e19 -- bucket
+ local annex keys: 2256
+ local annex size: 449 gigabytes
+ total annex keys: 2256
+ total annex size: 449 gigabytes
+ backend usage:
+ WORM: 2256
+
+**First point of confusion**: Why doesn't "bacon" show up in "git annex status"? I can "git annex copy --to bacon filename" and it will copy it there. Is there some step of setting it up that I missed? I basically just did "git remote add bacon ssh://bucket.foo.com/vid".
+
+Now I've started setting up the remotes on each host:
+
+On bacon:
+
+ bacon$ git config --list | grep ^remote | sort
+ remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
+ remote.origin.url=https://git.foo.com/jim/vid.git
+ remote.psychosis.annex-uuid=09c0b436-f8de-11e0-842f-b7644539d57f
+ remote.psychosis.fetch=+refs/heads/*:refs/remotes/psychosis/*
+ remote.psychosis.url=ssh://psychosis.foo.com/vid
+
+ bacon$ git annex status
+ supported backends: WORM SHA1 SHA256 SHA512 SHA224 SHA384 SHA1E SHA256E SHA512E SHA224E SHA384E URL
+ supported remote types: git S3 bup directory rsync web hook
+ known repositories:
+ 09c0b436-f8de-11e0-842f-b7644539d57f -- psychosis
+ 8f1f0898-f8c1-11e0-9bf2-b387af26ee63 -- here (bacon)
+ temporary directory size: 366 megabytes (clean up with git-annex unused)
+ local annex keys: 1
+ local annex size: 308 bytes
+ total annex keys: 2256
+ total annex size: 449 gigabytes
+ backend usage:
+ WORM: 2256
+
+On bucket:
+
+ bucket$ git config --list | grep ^remote | sort
+ remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
+ remote.origin.url=https://git.foo.com/jim/vid.git
+ remote.psychosis.annex-uuid=09c0b436-f8de-11e0-842f-b7644539d57f
+ remote.psychosis.fetch=+refs/heads/*:refs/remotes/psychosis/*
+ remote.psychosis.url=ssh://psychosis.foo.com/vid
+
+ bucket$ git annex status
+ supported backends: WORM SHA1 SHA256 SHA512 SHA224 SHA384 SHA1E SHA256E SHA512E SHA224E SHA384E URL
+ supported remote types: git S3 bup directory rsync web hook
+ known repositories:
+ 09c0b436-f8de-11e0-842f-b7644539d57f -- psychosis
+ 82814942-f8e0-11e0-b053-e70a61e98e19 -- here (bucket)
+ temporary directory size: 183 megabytes (clean up with git-annex unused)
+ local annex keys: 3
+ local annex size: 550 megabytes
+ total annex keys: 2256
+ total annex size: 449 gigabytes
+ backend usage:
+ WORM: 2256
+
+But I'm getting weird results if I try to show the map from psychosis:
+
+ psychosis$ git annex map
+ $ git annex map
+ map /vid/tv ok
+ map bacon (sshing...)
+ ok
+ map bucket (sshing...)
+ ok
+ map origin
+ failed
+ map psychosis (sshing...)
+ jim@psychosis.foo.com's password:
+ ok
+ map psychosis (sshing...)
+ jim@psychosis.foo.com's password:
+ ok
+
+ running: dot -Tx11 map.dot
+
+**Second confusion**: it's as if psychosis was considered a new remote each time?
+The generated map has psychosis listed with several redundant links:
+
+![Map](http://jim.sh/~jim/tmp/map.png)
+
+Is this some bug or do I just need to be hit with the clue bat?
diff --git a/doc/forum/confusion_with_remotes__44___map/comment_1_a38ded23b7f288292a843abcb1a56f38._comment b/doc/forum/confusion_with_remotes__44___map/comment_1_a38ded23b7f288292a843abcb1a56f38._comment
new file mode 100644
index 000000000..97de93d9e
--- /dev/null
+++ b/doc/forum/confusion_with_remotes__44___map/comment_1_a38ded23b7f288292a843abcb1a56f38._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-10-17T19:01:21Z"
+ content="""
+My guess is that psychosis has not pulled the git-annex branch since bacon was set up (or that bacon's git-annex branch has not been pushed to origin). git-annex status only shows remotes present in git-annex:uuid.log This may be a bug.
+
+The duplicate links in the map I don't quite understand. I only see duplicate links in my maps when I have the same repository configured as two different git remotes (for example, because the same repository can be accessed two different ways). You don't seem to have that in your config.
+"""]]
diff --git a/doc/forum/confusion_with_remotes__44___map/comment_2_cd1c98b1276444e859a22c3dbd6f2a79._comment b/doc/forum/confusion_with_remotes__44___map/comment_2_cd1c98b1276444e859a22c3dbd6f2a79._comment
new file mode 100644
index 000000000..a61b126c0
--- /dev/null
+++ b/doc/forum/confusion_with_remotes__44___map/comment_2_cd1c98b1276444e859a22c3dbd6f2a79._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 2"
+ date="2011-10-17T19:02:50Z"
+ content="""
+Actually, there is a hint that, while you ran the git annex map on psychosis, it decided to ssh to itself two times. That seems to be where the duplicate links came from, I guess you must have some git remotes you did not show.
+"""]]
diff --git a/doc/forum/confusion_with_remotes__44___map/comment_3_18531754089c991b6caefc57a5c17fe9._comment b/doc/forum/confusion_with_remotes__44___map/comment_3_18531754089c991b6caefc57a5c17fe9._comment
new file mode 100644
index 000000000..4c7722261
--- /dev/null
+++ b/doc/forum/confusion_with_remotes__44___map/comment_3_18531754089c991b6caefc57a5c17fe9._comment
@@ -0,0 +1,24 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnBJ6Dv1glxzzi4qIzGFNa6F-mfHIvv9Ck"
+ nickname="Jim"
+ subject="comment 3"
+ date="2011-10-17T19:50:06Z"
+ content="""
+No extra remotes (that I'm aware of); that output was only edited to change hostnames.
+
+On all three hosts, \"git push origin\" and \"git pull origin\" say everything is up to date.
+
+I'm using git-annex 3.20111011 on all hosts (although some were running 3.20110928 when I created the repositories).
+
+Regarding the multiple links, I've put a copy of the dot file [here](http://jim.sh/~jim/tmp/map.dot).
+It shows psychosis in three separate subgraphs, that are just getting rendered together as one,
+if that helps clarify anything.
+
+Wait, I just realized you said \"the git-annex branch\". My origin only has \"master\".
+Do you mean the one specifically named \"git-annex\"? I thought that was something that
+gets managed automatically, or is it something I need to manually check out and deal with?
+
+Any other info I could provide?
+
+
+"""]]
diff --git a/doc/forum/confusion_with_remotes__44___map/comment_4_3b89b6d1518267fcbc050c9de038b9ca._comment b/doc/forum/confusion_with_remotes__44___map/comment_4_3b89b6d1518267fcbc050c9de038b9ca._comment
new file mode 100644
index 000000000..f6e5993c8
--- /dev/null
+++ b/doc/forum/confusion_with_remotes__44___map/comment_4_3b89b6d1518267fcbc050c9de038b9ca._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnBJ6Dv1glxzzi4qIzGFNa6F-mfHIvv9Ck"
+ nickname="Jim"
+ subject="comment 4"
+ date="2011-10-17T20:36:51Z"
+ content="""
+Ok, after pushing the \"git-annex\" branch to origin, then \"git annex status\" knows all repositories on all hosts, so that part makes sense now. Thanks for the tip. But the \"git annex map\" output hasn't changed.
+
+
+
+"""]]
diff --git a/doc/forum/confusion_with_remotes__44___map/comment_5_27801584325d259fa490f67273f2ff71._comment b/doc/forum/confusion_with_remotes__44___map/comment_5_27801584325d259fa490f67273f2ff71._comment
new file mode 100644
index 000000000..77a2c4adb
--- /dev/null
+++ b/doc/forum/confusion_with_remotes__44___map/comment_5_27801584325d259fa490f67273f2ff71._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnBJ6Dv1glxzzi4qIzGFNa6F-mfHIvv9Ck"
+ nickname="Jim"
+ subject="comment 5"
+ date="2011-10-18T04:59:13Z"
+ content="""
+I think:
+
+* The first extra edge is because bucket had \"ssh://psychosis.foo.com/vid/\", while
+bacon had \"ssh://psychosis.foo.com/vid\" with no trailing slash. That got lost in the hostname/path editing I did, sorry.
+Maybe those should be considered matching?
+* The second extra edge is because, when running \"git annex map\" from psychosis, it doesn't recognize the remote's
+remote URL as pointing back to itself.
+
+For the second case, after the \"spurious\" SSH, it could still recognize that the repositories are the same by the duplicated annex uuid, which currently shows up in `map.dot` twice. I wonder what it would take to avoid the spurious SSH -- maybe some config that lists \"alternate\" URLs that should be considered the same as the current repository? Or actually list URLs in uuid.log? Fortunately, I think this only affects the map, so it's not a big problem.
+"""]]
diff --git a/doc/forum/confusion_with_remotes__44___map/comment_6_496b0d9b86869bbac3a1356d53a3dda4._comment b/doc/forum/confusion_with_remotes__44___map/comment_6_496b0d9b86869bbac3a1356d53a3dda4._comment
new file mode 100644
index 000000000..412937f3f
--- /dev/null
+++ b/doc/forum/confusion_with_remotes__44___map/comment_6_496b0d9b86869bbac3a1356d53a3dda4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 6"
+ date="2011-10-22T01:18:27Z"
+ content="""
+Hmm, I don't see the spurious ssh edge in the dot file -- that is, I don't see any ssh:// uris in it?
+"""]]
diff --git a/doc/forum/confusion_with_remotes__44___map/comment_7_9a456f61f956a3d5e81e723d5a90794c._comment b/doc/forum/confusion_with_remotes__44___map/comment_7_9a456f61f956a3d5e81e723d5a90794c._comment
new file mode 100644
index 000000000..85ede3a89
--- /dev/null
+++ b/doc/forum/confusion_with_remotes__44___map/comment_7_9a456f61f956a3d5e81e723d5a90794c._comment
@@ -0,0 +1,27 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnBJ6Dv1glxzzi4qIzGFNa6F-mfHIvv9Ck"
+ nickname="Jim"
+ subject="comment 7"
+ date="2011-10-22T05:25:47Z"
+ content="""
+I think that's because the SSH was successful (I entered the password and let it connect), so it got the UUID and put that in the .dot instead. The same UUID (for psychosis) then ended up in two different \"subgraph\" stanzas, and Graphviz just plotted them together as one node.
+
+<p>Maybe this will clarify:
+
+<p>On psychosis, run \"git annex map\" and press ^C at the ssh password prompt: [map-nossh.dot](http://jim.sh/~jim/tmp/map-nossh.dot)
+![Map](http://jim.sh/~jim/tmp/map-nossh.png)
+
+<p>On psychosis, run \"git annex map\" and type the correct password: [map-goodssh.dot](http://jim.sh/~jim/tmp/map-goodssh.dot)
+![Map](http://jim.sh/~jim/tmp/map-goodssh.png)
+
+As I see it:
+
+* psychosis (\"localhost\") connects to each of its remotes
+* some of them point back to ssh://psychosis
+* psychosis doesn't know that ssh://psychosis is itself, so it tries to connect
+* if successful:
+ * psychosis gets put twice in the .dot as if it was two different hosts, one \"local\" and one \"ssh://psychosis\"
+ * graphviz recognizes it as the same node because the UUID is the same, but graphviz still draws the extra connecting lines
+* if unsuccessful:
+ * ssh://psychosis is shown as an additional host that can't be reached
+"""]]
diff --git a/doc/forum/correct_way_to_add_two_preexisting_datasets.mdwn b/doc/forum/correct_way_to_add_two_preexisting_datasets.mdwn
new file mode 100644
index 000000000..bfc1a6272
--- /dev/null
+++ b/doc/forum/correct_way_to_add_two_preexisting_datasets.mdwn
@@ -0,0 +1,25 @@
+I've been syncronizing my data since long time, mainly using rsync or unison. Thus I had two 3.5Gb datasets set1 (usb drive, hfs+ partition) and set2 (hdd, ext4 ubuntu 13.04 box) which differed only in 50Mb (new on set1 ). This was double checked using diff -r before doing anything.
+
+I created a git annex repo in direct mode for set2 from command line, and after that I let the assistant scan it.
+After that created the repo for set1 and added it to the assistant. I think here comes my mistake (I think).
+
+Instead of keeping them apart, at told assistant to sync with set2.
+Why I think this was a mistake? Because set2 was indexed and set1 no, and I'm seeing a lot of file moving a copying, which in my humble opinion should not happen.
+What I expected it only the difference to be transferred from set1 to set2.
+What it seems to be doing is moving away all content in set1, and copying it back from set2. I think it will end correctly, but with a lot of unnecessary and risky operations.
+
+I think I should have independently added both datasets, let them be scanned and then connect to each other.
+So, now the questions:
+
+1. Is that the correct way to proceed?
+2. What if I have to identical files with different modifying times, I hope they are not synced, right?
+3. Is it posssible to achieve this behaviour of copying only the 50Mb?
+
+Thanks in advance and keep up the good work.
+Best regards,
+ Juan
+
+EDIT: a couple of questions more:
+
+4. after finishing, set2 ended with a lot of symlinks but only in one subfolder. To prevent this should I put numcopies in 2?
+5. This data is composed of input datasets and output simulations. Thus, I need to change them often, but not as often as code and in a very partial way (chunks of 50Mb). For me direct mode is the best (or plain git). However, I was wondering, it is possible to drop some files (even in direct mode) and use simlinks instead?
diff --git a/doc/forum/correct_way_to_add_two_preexisting_datasets/comment_1_c5c3ff25c9f5e34db222b5f4ae58b093._comment b/doc/forum/correct_way_to_add_two_preexisting_datasets/comment_1_c5c3ff25c9f5e34db222b5f4ae58b093._comment
new file mode 100644
index 000000000..13e2a58d2
--- /dev/null
+++ b/doc/forum/correct_way_to_add_two_preexisting_datasets/comment_1_c5c3ff25c9f5e34db222b5f4ae58b093._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/FHnTlSBo1eCGJRwueeKeB6.RCaPbGMPr5jxx8A--#ce0d8"
+ nickname="Hamza"
+ subject="comment 1"
+ date="2013-08-23T16:17:58Z"
+ content="""
+I did something similar for my videos, I've created the repo on one machine add the video files then cloned it on the other machine then reinjected the files in to the cloned repo.
+
+http://joeyh.name/blog/entry/moving_my_email_archives_and_packages_to_git-annex/
+"""]]
diff --git a/doc/forum/correct_way_to_add_two_preexisting_datasets/comment_2_ee3ecc86990ac5a8d0c4fdfb482a7594._comment b/doc/forum/correct_way_to_add_two_preexisting_datasets/comment_2_ee3ecc86990ac5a8d0c4fdfb482a7594._comment
new file mode 100644
index 000000000..d1e259afd
--- /dev/null
+++ b/doc/forum/correct_way_to_add_two_preexisting_datasets/comment_2_ee3ecc86990ac5a8d0c4fdfb482a7594._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 2"
+ date="2013-08-23T18:23:52Z"
+ content="""
+If you need to preserve mtimes, or differentiate between files with identical content but different mtimes, neither git nor git-annex is going to do what you want, since git doesn't care about preserving much file metadata.
+
+As far as importing two sets of files on two computers, the best thing to do is import each, and then let the two sync up. Otherwise, when you're running the assistant it will start downloading the first set you import to the second computer, before the second set is added there, and do extra work. Although once the duplicate files from the second set land in the second git repository, the assistant will avoid any additional redundant transfers.
+
+(The assistant never *moves* files, if both repositories are configured to be in the default client repository group. It only copies.)
+
+I don't understand question #1. \"set2 ended with a lot of symlinks but only in one subfolder\" doesn't make sense to me, or rather I could interpret it to mean any of dozen things (none of which seem likely)
+
+You can `git annex drop` files in direct mode. However, if you're running the assistant, it will try to get them back. You can configure your repository to be in manual mode to prevent the assistant doing that, or not use the assistant, or configure a [[preferred_content]] expression to make the assistant do something more custom like not try to get files located in a \"olddata\" directory.
+"""]]
diff --git a/doc/forum/correct_way_to_add_two_preexisting_datasets/comment_3_e29bf8b848da04c761dc601ac979ac14._comment b/doc/forum/correct_way_to_add_two_preexisting_datasets/comment_3_e29bf8b848da04c761dc601ac979ac14._comment
new file mode 100644
index 000000000..d750e9581
--- /dev/null
+++ b/doc/forum/correct_way_to_add_two_preexisting_datasets/comment_3_e29bf8b848da04c761dc601ac979ac14._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmTNrhkVQ26GBLaLD5-zNuEiR8syTj4mI8"
+ nickname="Juan"
+ subject="comment 3"
+ date="2013-08-25T13:00:04Z"
+ content="""
+Thanks. It is very clear now. I think I got it running. I have 2 direct mode copies in my ubuntu box and in the USB drive and one indirect in my ultrabook (small SSD).
+What I meant is that even in direct mode, after sync ended, the set I indexed first ended with the contents of a folder in the .git dir using symlinks. But it might have been a leftover of previous attempts.
+I think I got confused by the great amount of flexibility it provides.
+Thanks.
+"""]]
diff --git a/doc/forum/could_not_read_from_remote_repository.mdwn b/doc/forum/could_not_read_from_remote_repository.mdwn
new file mode 100644
index 000000000..6103bfd36
--- /dev/null
+++ b/doc/forum/could_not_read_from_remote_repository.mdwn
@@ -0,0 +1,36 @@
+hi, i'm trying to set up my notebook and desktop pc to sync my documents. so i used local computers in the web app as a sync option, but on my notebook i get the following error:
+
+ [2013-11-26 11:29:03 CET] main: Pairing in progress
+ X11 forwarding request failed
+ /home/max/.ssh/git-annex-shell: line 4: exec: git-annex-shell: not found
+ X11 forwarding request failed on channel 0
+ /home/max/.ssh/git-annex-shell: line 4: exec: git-annex-shell: not found
+ fatal: Could not read from remote repository.
+
+ Please make sure you have the correct access rights
+ and the repository exists.
+ [2013-11-26 11:29:31 CET] PairListener: Syncing with desk_Private_Dokumente
+ X11 forwarding request failed on channel 0
+ /home/max/.ssh/git-annex-shell: line 4: exec: git-annex-shell: not found
+ fatal: Could not read from remote repository.
+
+ Please make sure you have the correct access rights
+ and the repository exists.
+
+ merge: refs/remotes/desk_Private_Dokumente/master - not something we can merge
+
+ merge: refs/remotes/desk_Private_Dokumente/synced/master - not something we can merge
+ X11 forwarding request failed
+ /home/max/.ssh/git-annex-shell: line 4: exec: git-annex-shell: not found
+ X11 forwarding request failed on channel 0
+ /home/max/.ssh/git-annex-shell: line 4: exec: git-annex-shell: not found
+ fatal: Could not read from remote repository.
+
+ Please make sure you have the correct access rights
+ and the repository exists.
+
+my desktop succeeded in adding the repository.
+
+any idea whats going wrong ?
+
+thanks
diff --git a/doc/forum/could_not_read_from_remote_repository/comment_1_27d4d1556a80c06505ed3d8a9422d082._comment b/doc/forum/could_not_read_from_remote_repository/comment_1_27d4d1556a80c06505ed3d8a9422d082._comment
new file mode 100644
index 000000000..aaf094693
--- /dev/null
+++ b/doc/forum/could_not_read_from_remote_repository/comment_1_27d4d1556a80c06505ed3d8a9422d082._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.64"
+ subject="comment 1"
+ date="2013-11-26T20:18:26Z"
+ content="""
+The problem seems to be on your desktop computer. /home/max/.ssh/git-annex-shell is a script that is created if you install git-annex from the standalone tarball (assuming you're using linux?). It seems that your desktop has that script, but you must have deleted that instalation of git-annex (perhaps you switched to installing it some other way), so the script doesn't work. As long as you have git-annex-shell in your PATH somehow, you can just remove /home/max/.ssh/git-annex-shell
+"""]]
diff --git a/doc/forum/dot_git_slash_annex_slash_tmp.mdwn b/doc/forum/dot_git_slash_annex_slash_tmp.mdwn
new file mode 100644
index 000000000..5f1262c7a
--- /dev/null
+++ b/doc/forum/dot_git_slash_annex_slash_tmp.mdwn
@@ -0,0 +1,5 @@
+When I was checking out disk usage on my home directory, I noticed a bunch of files stored in .git/annex/tmp under their own filenames, rather than in .git/annex/objects. Checking a couple, they seem to be redundant with stuff in .git/annex/objects.
+
+Is there any way to clean that stuff up? Will the assistant eventually clean it up?
+
+Thanks!
diff --git a/doc/forum/dot_git_slash_annex_slash_tmp/comment_10_14b74438bb1e3e02cff7926d774ba09a._comment b/doc/forum/dot_git_slash_annex_slash_tmp/comment_10_14b74438bb1e3e02cff7926d774ba09a._comment
new file mode 100644
index 000000000..fe7a71dcb
--- /dev/null
+++ b/doc/forum/dot_git_slash_annex_slash_tmp/comment_10_14b74438bb1e3e02cff7926d774ba09a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 10"
+ date="2013-06-06T13:16:50Z"
+ content="""
+Huh, at some point this happened again. Ended up with 8 gigs of files in that tmp dir. Cleaning out again. Yay, disk space!
+"""]]
diff --git a/doc/forum/dot_git_slash_annex_slash_tmp/comment_11_b1f717342c1c8ea42a451caa2d936622._comment b/doc/forum/dot_git_slash_annex_slash_tmp/comment_11_b1f717342c1c8ea42a451caa2d936622._comment
new file mode 100644
index 000000000..c882a8573
--- /dev/null
+++ b/doc/forum/dot_git_slash_annex_slash_tmp/comment_11_b1f717342c1c8ea42a451caa2d936622._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="stoile"
+ ip="2a01:198:242:0:219:66ff:fef2:c021"
+ subject="Same problem here"
+ date="2013-11-16T12:10:55Z"
+ content="""
+I got the same problem on linux. Under what circumstances does \"git annex unused\" not find files in .git/annex/tmp? Maybe it is possible to improve \"git annex unused\"...
+"""]]
diff --git a/doc/forum/dot_git_slash_annex_slash_tmp/comment_12_e2c6ad99333018c8c46e736da416b8ef._comment b/doc/forum/dot_git_slash_annex_slash_tmp/comment_12_e2c6ad99333018c8c46e736da416b8ef._comment
new file mode 100644
index 000000000..153a617b5
--- /dev/null
+++ b/doc/forum/dot_git_slash_annex_slash_tmp/comment_12_e2c6ad99333018c8c46e736da416b8ef._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmkXtBdMgE1d9nCz2iBc4f85xh4izZ_auU"
+ nickname="Ulrich"
+ subject="Wow. Found >180 GB of data in annex/tmp"
+ date="2013-11-24T21:53:29Z"
+ content="""
+… no wonder my disk was filling up. On Mac OS X 10.9…
+"""]]
diff --git a/doc/forum/dot_git_slash_annex_slash_tmp/comment_1_1a35ef8cb89e0cd392f6e9fcee1fb92c._comment b/doc/forum/dot_git_slash_annex_slash_tmp/comment_1_1a35ef8cb89e0cd392f6e9fcee1fb92c._comment
new file mode 100644
index 000000000..d00f68144
--- /dev/null
+++ b/doc/forum/dot_git_slash_annex_slash_tmp/comment_1_1a35ef8cb89e0cd392f6e9fcee1fb92c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.49"
+ subject="comment 1"
+ date="2012-11-29T19:35:41Z"
+ content="""
+These are partially downloaded files. You can use `git annex unused` to clean them up. The assistant doesn't yet explicitly clean these up, but it does keep retrying (and when possible, resuming) failed downloads until they succeed, at which point the temp file is moved into the objects directory.
+"""]]
diff --git a/doc/forum/dot_git_slash_annex_slash_tmp/comment_2_f4cc36c493d7c20fbaf949edd38e1252._comment b/doc/forum/dot_git_slash_annex_slash_tmp/comment_2_f4cc36c493d7c20fbaf949edd38e1252._comment
new file mode 100644
index 000000000..8aeaf63cf
--- /dev/null
+++ b/doc/forum/dot_git_slash_annex_slash_tmp/comment_2_f4cc36c493d7c20fbaf949edd38e1252._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 2"
+ date="2012-11-29T19:53:33Z"
+ content="""
+that's odd... these files are on my client machine, and shouldn't be downloaded from anywhere, just uploaded to other places. There are lots and lots of them.
+
+git-annex unused only found two files, and there are dozens and dozens of these files in my .git/annex/tmp directory.
+
+Would it be safe to delete them by hand?
+
+(The only thing I can think of that might e relevant is, some of these have definitely been moved from place to place within my repo. I use \"git mv\" when I do that. Maybe I messed that up somehow, and git-annex thought they had disappeared and needed to be re-downloaded from a remote repo?)
+
+"""]]
diff --git a/doc/forum/dot_git_slash_annex_slash_tmp/comment_3_69268f8aa29e807a56248f1fac86aa41._comment b/doc/forum/dot_git_slash_annex_slash_tmp/comment_3_69268f8aa29e807a56248f1fac86aa41._comment
new file mode 100644
index 000000000..d9863375a
--- /dev/null
+++ b/doc/forum/dot_git_slash_annex_slash_tmp/comment_3_69268f8aa29e807a56248f1fac86aa41._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.49"
+ subject="comment 3"
+ date="2012-11-29T20:22:01Z"
+ content="""
+No, moving files within the repository is unlikely to be related.
+
+If you can show me what the filenames look like I'll have a much better chance of getting somewhere, since they do not seem to be filenames that `git annex unused` knows how to deal with, and so I don't know what they could be.
+"""]]
diff --git a/doc/forum/dot_git_slash_annex_slash_tmp/comment_4_0ffb0c803c232a1587f956f16113aeb7._comment b/doc/forum/dot_git_slash_annex_slash_tmp/comment_4_0ffb0c803c232a1587f956f16113aeb7._comment
new file mode 100644
index 000000000..11da78841
--- /dev/null
+++ b/doc/forum/dot_git_slash_annex_slash_tmp/comment_4_0ffb0c803c232a1587f956f16113aeb7._comment
@@ -0,0 +1,27 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 4"
+ date="2012-11-29T20:33:09Z"
+ content="""
+They're the full actual filenames (but not directories) of particular files in my repository, sometimes with numeric suffixes (or rather, numbers before the file suffixes), like this:
+
+746.DS_Store
+747.DS_Store
+748.DS_Store
+749.DS_Store
+Birdplane87712.mp4
+Birdplane87713.mp4
+Bodyrock87712.mp4
+Bodyrock87713.mp4
+Dubstep Violin- Lindsey Stirling- Crystallize746.mp4
+Dubstep Violin- Lindsey Stirling- Crystallize87712.mp4
+Dubstep Violin- Lindsey Stirling- Crystallize87713.mp4
+Handlebars (fan video)87712.mp4
+Handlebars (fan video)87713.mp4
+Handlebars (official)87712.mp4
+Handlebars (official)87713.mp4
+
+Most of them are videos, and I've moved videos around a lot in my repository, and made some mistakes doing so from time to time when I was first learning git-annex, and fooling around on the command line -- breaking symlinks and figuring out how to fix that with git-annex fix.
+
+"""]]
diff --git a/doc/forum/dot_git_slash_annex_slash_tmp/comment_5_c303e28825241733d69fca74f2015fc6._comment b/doc/forum/dot_git_slash_annex_slash_tmp/comment_5_c303e28825241733d69fca74f2015fc6._comment
new file mode 100644
index 000000000..60896ab5c
--- /dev/null
+++ b/doc/forum/dot_git_slash_annex_slash_tmp/comment_5_c303e28825241733d69fca74f2015fc6._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 5"
+ date="2012-11-29T20:47:36Z"
+ content="""
+Oh, another stupid thing I might have done --
+
+* added files to the repo, and not realizing it might take assistant a while to recognize and add them all, gotten impatient
+* added them myself, but did it with \"import\" instead of \"add\" so I was git-annex importing files from *inside* git-annex, with an assistant process running at the same time.
+
+Might not be relevant, just trying to think of weird things I've done.
+"""]]
diff --git a/doc/forum/dot_git_slash_annex_slash_tmp/comment_6_3f0b376e37bd092b8d46c46bb1940e35._comment b/doc/forum/dot_git_slash_annex_slash_tmp/comment_6_3f0b376e37bd092b8d46c46bb1940e35._comment
new file mode 100644
index 000000000..0fc7f5c15
--- /dev/null
+++ b/doc/forum/dot_git_slash_annex_slash_tmp/comment_6_3f0b376e37bd092b8d46c46bb1940e35._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.49"
+ subject="comment 6"
+ date="2012-11-29T20:53:34Z"
+ content="""
+Ah, I think I know what this is. When the assistant notices a new file appear, it makes a hard link in the temp directory to the new file, and waits for it to stop being written to.
+
+If the hard link is broken before the assistant is done adding the file to the annex, it looks like it could leave the temp file behind. I've committed a change that should avoid that.
+
+Since some of these are OSX DS_Store files, and the rest have a strange number added (which git-annex did not do), I suspect you moved them into the annexed directory using the OSX Finder or something like that, and whatever was putting them into the directory first wrote them with the names we see here. Then, while git-annex was still processing them, they got renamed.
+
+I'd say you can safely delete them.
+"""]]
diff --git a/doc/forum/dot_git_slash_annex_slash_tmp/comment_7_615641b3dd176d4b3a5bbfb521098e38._comment b/doc/forum/dot_git_slash_annex_slash_tmp/comment_7_615641b3dd176d4b3a5bbfb521098e38._comment
new file mode 100644
index 000000000..20e8b205f
--- /dev/null
+++ b/doc/forum/dot_git_slash_annex_slash_tmp/comment_7_615641b3dd176d4b3a5bbfb521098e38._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 7"
+ date="2012-11-29T22:15:11Z"
+ content="""
+Sounds likely!! I'll get to deleting, and when I get a chance I'll grab your latest commit and recompile.
+
+"""]]
diff --git a/doc/forum/dot_git_slash_annex_slash_tmp/comment_8_4600fa9234a787004ea0e0dbb36184b9._comment b/doc/forum/dot_git_slash_annex_slash_tmp/comment_8_4600fa9234a787004ea0e0dbb36184b9._comment
new file mode 100644
index 000000000..3325f598a
--- /dev/null
+++ b/doc/forum/dot_git_slash_annex_slash_tmp/comment_8_4600fa9234a787004ea0e0dbb36184b9._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 8"
+ date="2012-11-29T22:15:55Z"
+ content="""
+(thanks very much!)
+"""]]
diff --git a/doc/forum/dot_git_slash_annex_slash_tmp/comment_9_4f5cd0d0d4db0479c1ad86ffdc5ae434._comment b/doc/forum/dot_git_slash_annex_slash_tmp/comment_9_4f5cd0d0d4db0479c1ad86ffdc5ae434._comment
new file mode 100644
index 000000000..cc996c825
--- /dev/null
+++ b/doc/forum/dot_git_slash_annex_slash_tmp/comment_9_4f5cd0d0d4db0479c1ad86ffdc5ae434._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl2Jj8q2upJL4ZQAc2lp7ugTxJiGtcICv8"
+ nickname="Michael"
+ subject="comment 9"
+ date="2013-02-20T10:23:12Z"
+ content="""
+I'm seeing this too, and the number being added to the file name is the PID of the git-annex process.
+"""]]
diff --git a/doc/forum/dropping_files_not_working_when_using_git_annex_assistant.txt b/doc/forum/dropping_files_not_working_when_using_git_annex_assistant.txt
new file mode 100644
index 000000000..05680a740
--- /dev/null
+++ b/doc/forum/dropping_files_not_working_when_using_git_annex_assistant.txt
@@ -0,0 +1,18 @@
+Just playing with git-annex which looks great so far, but I noticed that when you make use off "git annex assistant" to watch and sync your repo with the remote it doesn't drop files anymore. They just stay in the repo.
+
+What I have is the following:
+
+- 2 repo's in direct mode
+- they both have each other as remote
+- they're synced and stay synced with the assistant daemon running (in both repo's started "git annex assistant")
+- is see changes coming and precessed, so so far so good.
+
+Then I drop in one repo a path for instance like : git annex drop iso
+Afterwards I still see the files (and contents) in that repo. New files in the iso path are still synced to the other and vise versa.
+
+Then I kill the assistant on both side's and drop the path again. This time it's dropped as expected and the contents of the file in the iso path are gone.
+Starting the assistant again brings is back though :(
+
+I really liked the assistant feature and possibility of dropping the files from one repo, but they don't seem to work together.
+
+Is this a bur or expected behaviour? I think the latter since the assistant also does the git annex get commands so sounds logical?
diff --git a/doc/forum/endless_password_prompt_loop.mdwn b/doc/forum/endless_password_prompt_loop.mdwn
new file mode 100644
index 000000000..bfdd3c1db
--- /dev/null
+++ b/doc/forum/endless_password_prompt_loop.mdwn
@@ -0,0 +1,8 @@
+Hi,
+
+I setup a first repository on local disk, it went fine. Next I tried setting up repo on my nas to clone the files. I installed git-annex on the NAS (it's armel arch) and created the repository via webapp, I entered the password once. Git-annex started syncing the remote repo and after few seconds password pop-up hell broke loose. I was flooded with password-prompt pop-up windows. The synchronization was continuing regardless of correctly/incorrectly entered passwords. What's more, these popups grab the keyboard and you cannot do (appropriate word) with your system.
+
+I checked this topic: http://git-annex.branchable.com/forum/ssh_password/ and ssh config is in place on my computer and on the NAS.
+
+What is causing this and how can I get rid of this?
+
diff --git a/doc/forum/endless_password_prompt_loop/comment_1_cceba12ed25cd671c7cee5a28631163e._comment b/doc/forum/endless_password_prompt_loop/comment_1_cceba12ed25cd671c7cee5a28631163e._comment
new file mode 100644
index 000000000..d162ff3e5
--- /dev/null
+++ b/doc/forum/endless_password_prompt_loop/comment_1_cceba12ed25cd671c7cee5a28631163e._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.193"
+ subject="comment 1"
+ date="2013-06-25T19:49:25Z"
+ content="""
+What version of git-annex? Did more than one password prompt window somehow appear at the same time? What is doing the ssh password prompting, is it ssh-askpass, or something provided by your desktop environment?
+
+What happens if you manually ssh from your computer to the NAS, using the special hostname that git-annex has configured (you can find this hostname in the `.git/config`). `ssh -v` is generally a good way to track these problems down.
+"""]]
diff --git a/doc/forum/endless_password_prompt_loop/comment_2_f0cb86b45eb289f35197c43f83660a8f._comment b/doc/forum/endless_password_prompt_loop/comment_2_f0cb86b45eb289f35197c43f83660a8f._comment
new file mode 100644
index 000000000..45f87d136
--- /dev/null
+++ b/doc/forum/endless_password_prompt_loop/comment_2_f0cb86b45eb289f35197c43f83660a8f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmUcCZeEK9HKV40JrcHMXAXpPKQPERt7iM"
+ nickname="Włodek"
+ subject="comment 2"
+ date="2013-07-10T22:00:47Z"
+ content="""
+Thanks for the answer. I found out that the public key auth is not working at all and ssh falls back to password auth, this is the reason for password prompts. What I don't know yet is why popups appear despite giving correct password. I'm looking for a solution. This can take some time though because my disk died few days ago = I cannot check versions. Once I've got it solved I'll post back.
+"""]]
diff --git a/doc/forum/error_in_installation_of_base-4.5.0.0.mdwn b/doc/forum/error_in_installation_of_base-4.5.0.0.mdwn
new file mode 100644
index 000000000..673222ed6
--- /dev/null
+++ b/doc/forum/error_in_installation_of_base-4.5.0.0.mdwn
@@ -0,0 +1,14 @@
+Hi,
+
+I was trying to install git-annex, but then, I got a warning saying that I need to install base-4.5.0.0 first.
+
+So, I did "sudo cabal install base-4.5.0.0". Everything was going well, until I got this error:
+
+config.status: error: cannot find input file: `base.buildinfo.in'
+cabal: Error: some packages failed to install:
+base-4.5.0.0 failed during the configure step. The exception was:
+ExitFailure 1
+
+I tried to look for information on the internet, but I did not find anything useful.
+
+I know that this is not totally related to git-annex, but anyone has any thoughts on this?
diff --git a/doc/forum/error_in_installation_of_base-4.5.0.0/comment_1_0b2f79c014e0dd9badd52b8b6aa47e0c._comment b/doc/forum/error_in_installation_of_base-4.5.0.0/comment_1_0b2f79c014e0dd9badd52b8b6aa47e0c._comment
new file mode 100644
index 000000000..5a52a28ab
--- /dev/null
+++ b/doc/forum/error_in_installation_of_base-4.5.0.0/comment_1_0b2f79c014e0dd9badd52b8b6aa47e0c._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2012-04-22T05:39:28Z"
+ content="""
+git-annex needs ghc 7.4, that's why it depends on that base version that comes with it. So you either need to upgrade your ghc, or you can build from the `ghc7.0` branch in [[git|download]], like this:
+
+<pre>
+git clone git://git-annex.branchable.com/ git-annex
+cd git-annex
+git checkout ghc7.0
+cabal update
+cabal install --only-dependencies
+cabal configure
+cabal build
+cabal install --bindir=$HOME/bin
+</pre>
+"""]]
diff --git a/doc/forum/error_in_installation_of_base-4.5.0.0/comment_2_3badd64e48fbb174cd7de1ac9589bedf._comment b/doc/forum/error_in_installation_of_base-4.5.0.0/comment_2_3badd64e48fbb174cd7de1ac9589bedf._comment
new file mode 100644
index 000000000..3ad1a1138
--- /dev/null
+++ b/doc/forum/error_in_installation_of_base-4.5.0.0/comment_2_3badd64e48fbb174cd7de1ac9589bedf._comment
@@ -0,0 +1,31 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkaT0B6s9jQuMzQUYRVBgWqtO7BhT_ZSaE"
+ nickname="Fernando Seabra"
+ subject="comment 2"
+ date="2012-04-22T14:09:33Z"
+ content="""
+Thanks for the fast response!
+
+Unfortunately, I had another problem:
+
+==================================
+Building git-annex-3.20120419...
+Utility/libdiskfree.c: In function ‘diskfree’:
+
+Utility/libdiskfree.c:61:0:
+ warning: ‘statfs64’ is deprecated (declared at /usr/include/sys/mount.h:379)
+[ 6 of 157] Compiling Build.SysConfig ( Build/SysConfig.hs, dist/build/git-annex/git-annex-tmp/Build/SysConfig.o )
+[ 15 of 157] Compiling Utility.Touch ( dist/build/git-annex/git-annex-tmp/Utility/Touch.hs, dist/build/git-annex/git-annex-tmp/Utility/Touch.o )
+
+Utility/Touch.hsc:118:21: Not in scope: `noop'
+cabal: Error: some packages failed to install:
+git-annex-3.20120419 failed during the building phase. The exception was:
+ExitFailure 1
+==================================
+
+I also tried to look for information on the internet, and I did not find anything useful.
+Any idea of what happened?
+
+Thanks again!
+
+"""]]
diff --git a/doc/forum/error_in_installation_of_base-4.5.0.0/comment_3_d8190061ac1c683a7b699cf42e9db694._comment b/doc/forum/error_in_installation_of_base-4.5.0.0/comment_3_d8190061ac1c683a7b699cf42e9db694._comment
new file mode 100644
index 000000000..d9de5089e
--- /dev/null
+++ b/doc/forum/error_in_installation_of_base-4.5.0.0/comment_3_d8190061ac1c683a7b699cf42e9db694._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 3"
+ date="2012-04-22T15:23:26Z"
+ content="""
+That's my fault, I made a change last night that caused the noop problem. Fixed now.
+"""]]
diff --git a/doc/forum/error_in_installation_of_base-4.5.0.0/comment_4_49a4fcd2dc4f97d4055b5051feea5e3b._comment b/doc/forum/error_in_installation_of_base-4.5.0.0/comment_4_49a4fcd2dc4f97d4055b5051feea5e3b._comment
new file mode 100644
index 000000000..ba9933451
--- /dev/null
+++ b/doc/forum/error_in_installation_of_base-4.5.0.0/comment_4_49a4fcd2dc4f97d4055b5051feea5e3b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkaT0B6s9jQuMzQUYRVBgWqtO7BhT_ZSaE"
+ nickname="Fernando Seabra"
+ subject="comment 4"
+ date="2012-04-22T16:08:55Z"
+ content="""
+Thanks, it worked now!
+"""]]
diff --git a/doc/forum/example_of_massively_disconnected_operation.mdwn b/doc/forum/example_of_massively_disconnected_operation.mdwn
new file mode 100644
index 000000000..00a5d8d6c
--- /dev/null
+++ b/doc/forum/example_of_massively_disconnected_operation.mdwn
@@ -0,0 +1,33 @@
+I found this archival drive that had been offline since October 26th 2010. Since I released git-annex 0.02 on October 27th, this must have been made using the very first release of git-annex, ever.
+
+So, I synced it back up! :) --[[Joey]]
+
+<pre>
+commit 4151f4595fe6205d4aed653617ab23eb3335130a
+Author: Joey Hess <joey@kitenet.net>
+Date: Tue Oct 26 02:18:03 2010 -0400
+
+joey> git pull
+remote: Counting objects: 428782, done.
+remote: Compressing objects: 100% (280714/280714), done.
+remote: Total 416692 (delta 150923), reused 389593 (delta 125143)
+Receiving objects: 100% (416692/416692), 44.71 MiB | 495 KiB/s, done.
+Resolving deltas: 100% (150923/150923), completed with 818 local objects.
+ * [new branch] git-annex -> origin/git-annex
+ 1893f9c..9ebcc0e master -> origin/master
+Updating 1893f9c..9ebcc0e
+Checking out files: 100% (76884/76884), done.
+joey> git annex version
+git-annex version: 3.20110611
+local repository version: unknown
+default repository version: 3
+supported repository versions: 3
+upgrade supported from repository versions: 0 1 2
+joey> git config annex.version 0
+joey> git annex upgrade
+upgrade . (v0 to v1...) (v1 to v2) (moving content...) (updating symlinks...) (moving location logs...) (v2 to v3) (merging origin/git-annex into git-annex...)
+
+ git-annex branch created
+ Be sure to push this branch when pushing to remotes.
+ok
+</pre>
diff --git a/doc/forum/exclude_files_from_annex.mdwn b/doc/forum/exclude_files_from_annex.mdwn
new file mode 100644
index 000000000..c1707afb1
--- /dev/null
+++ b/doc/forum/exclude_files_from_annex.mdwn
@@ -0,0 +1,10 @@
+I'm wanting to do essentially [[/tips/replacing_Sparkleshare_or_dvcs-autosync_with_the_assistant/]], that is prevent git-annex from annexing certain files (by extension), and rather manage them in git only.
+
+This seems to work fine, and the assistant auto-adds them to git, and commits when I make changes, when in indirect mode.
+
+However, in a direct mode repository, then the files are automatically annexed, and even if I create them in an indirect repo, and then change it, they are annexed.
+
+Is this expected behaviour? Does the annex.largefiles setting only make sense in indirect mode?
+
+
+--Walter
diff --git a/doc/forum/exclude_files_from_annex/comment_1_82e7de5e631bae3b347815586274a936._comment b/doc/forum/exclude_files_from_annex/comment_1_82e7de5e631bae3b347815586274a936._comment
new file mode 100644
index 000000000..23ad6aac9
--- /dev/null
+++ b/doc/forum/exclude_files_from_annex/comment_1_82e7de5e631bae3b347815586274a936._comment
@@ -0,0 +1,25 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-05-19T20:29:14Z"
+ content="""
+I don't seem to be seeing the problem you describe in direct mode:
+
+[[!format sh \"\"\"
+
+joey@gnu:~/tmp/r2>git init
+joey@gnu:~/tmp/r2>git annex init
+joey@gnu:~/tmp/r2>git config annex.largefiles \"largerthan=100kb and not (include=*.c or include=*.h)\"
+joey@gnu:~/tmp/r2>git annex direct
+joey@gnu:~/tmp/r2>git annex assistant
+joey@gnu:~/tmp/r2>dd if=/dev/urandom of=bigfile bs=1M count=1
+1+0 records in
+1+0 records out
+joey@gnu:~/tmp/r2>echo \"main() { printf(\"hello, world!\n\") }\" > hello.c
+\"\"\"]]
+
+At that point, the bigfile was annexed, and the hello.c file was checked into git as a regular file.
+
+Are you sure you have annex.largefiles correctly configured to exclude the files you don't want to be annexed?
+"""]]
diff --git a/doc/forum/exclude_files_from_annex/comment_2_03d4599fdceb3dff184eed82824674bc._comment b/doc/forum/exclude_files_from_annex/comment_2_03d4599fdceb3dff184eed82824674bc._comment
new file mode 100644
index 000000000..7d8f6ce77
--- /dev/null
+++ b/doc/forum/exclude_files_from_annex/comment_2_03d4599fdceb3dff184eed82824674bc._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnSenxKyE_2Z6Wb-EBMO8FciyRywjx1ZiQ"
+ nickname="Walter"
+ subject="comment 2"
+ date="2013-05-19T21:35:37Z"
+ content="""
+This seems to have stopped happening, after I installed a newer version (from git) of git-annex.
+
+I might try and recreate it later, but for now it seems to work as expected.
+
+Thanks for your help.
+"""]]
diff --git a/doc/forum/expire_files__44___move_to_other_hosts.mdwn b/doc/forum/expire_files__44___move_to_other_hosts.mdwn
new file mode 100644
index 000000000..9ead2f899
--- /dev/null
+++ b/doc/forum/expire_files__44___move_to_other_hosts.mdwn
@@ -0,0 +1,19 @@
+Before turning this into a 'todo' item i'd like to discuss the possibilities...
+
+The idea is following:
+
+Having a Laptop with a rather small SSD or some other mobile device i'd like to move files away which are not needed anymore.
+The first thing is that the --to destination should be semi-automatically choosen, including ensuring enough replicas
+
+ git annex move --away <path..>
+
+should pick remotes which are suitable (either by configuration and/or other rules like disk utilization on the remote side).
+
+I am rather new to git-annex and wondering if there is currently already something which gives similar results, esp not need to hand pick the remotes where to move files.
+
+Further on there needs to be some way to find out which files are not needed anymore. On a first thought filtering by 'atime' would be nice, but nowadays mounting with noatime/relatime is common which would make this infeasible. To accomplish this, the assistant could (optionally) manage a lazy-atime by setting inotify or fanotify watches on all annexed files in a repository (close_nowrite) and queue/batch atime updates coarsely together. Then atimes on disk are only lazily updated (after some time expires, when the queue becomes full or at shutdown of the assistant), we can afford to loose some atime updates here in case of unexpected shutdowns (i rather wonder why the kernel has no lazy-atime option).
+
+Then the assistant (or by crontab) one can schedule some regular maintenance. There are certainly plenty of options to consider here, for example a mobile device might prefer only to send files if connected to Wlan, someone wants to move files away until a certain threshold of free disk space is reached etc...
+
+While at this, the assistant could also watch (fanotify) if someone tries to open a not available (dead symlinked) file, block that request, get the file and then proceed with the request.
+
diff --git a/doc/forum/expire_files__44___move_to_other_hosts/comment_1_ddcc2a00be1ae96a352d75a443458bcf._comment b/doc/forum/expire_files__44___move_to_other_hosts/comment_1_ddcc2a00be1ae96a352d75a443458bcf._comment
new file mode 100644
index 000000000..a23a21494
--- /dev/null
+++ b/doc/forum/expire_files__44___move_to_other_hosts/comment_1_ddcc2a00be1ae96a352d75a443458bcf._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.21"
+ subject="comment 1"
+ date="2013-07-30T19:14:25Z"
+ content="""
+I think that you're conflating two different features.
+
+First, there's the question of determining which remotes should store a file. The [[preferred_content]] expressions are a way to let the user define this in a way that makes sense for their setup. There's also the annex.diskreserve setting, to allow a remote to reject a file if it doesn't have space. The git-annex assistant can automatically apply those, and arrange to transfer files to all remotes that want a copy. Or you can do it on the command line using --auto. Perhaps it would be nice to have a `git annex copy --auto --to any`, to avoid needing to run copy multiple times to send to different remotes.
+
+Second, there's the concept of expiring files. I don't think relatime would prevent using atime for this (git-annex could just set the atime to 0 when it first gets a file to work around relatime), and I don't like the idea of inotify watching all files just to work around noatime. I suppose that the preferred content expressions could have an atime check operation added to them. Although I guess you could just as well use `find`..
+
+(Finally, I don't think there's a good way to block processes that are trying to open files that are not there, without using FuSE. And I don't know that a system that could block any program indefinitely waiting on some large files being pulled down from wherever would be one I'd want to use. This has prevented me from going down that path so far.)
+"""]]
diff --git a/doc/forum/expire_files__44___move_to_other_hosts/comment_2_7a4c3858c5eae409d04de3f9da43b57e._comment b/doc/forum/expire_files__44___move_to_other_hosts/comment_2_7a4c3858c5eae409d04de3f9da43b57e._comment
new file mode 100644
index 000000000..ea1e68074
--- /dev/null
+++ b/doc/forum/expire_files__44___move_to_other_hosts/comment_2_7a4c3858c5eae409d04de3f9da43b57e._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="cehteh"
+ ip="217.8.62.137"
+ subject="comment 2"
+ date="2013-07-30T20:29:11Z"
+ content="""
+I agree here are even more than 2 features involved.
+
+I'd appreciate a 'git annex copy --auto --to any' like feature. The point is that this should not only copy data until diskreserve is hit but distribute data in some (configureable) way around all remotes. Preferred content is one part of that, available disksize another. The user might also choose destinations depending on location and bandwidth and balance load over multiple servers until enough replicas are distributed. Details have to be worked out.
+
+Expiring content is another thing, i also thinking its most likely improper to add some atime watching thing to git-annex. Instead of that I am thinking to write a dedicated daemon which handles atime updates in userspace, this then could add some more rules to ignore accesses by other system tools (file indexers, users, etc). This makes such a expire facility completely independent from git annex and a user can choose if/what he likes.
+
+Filtering out files which are not accessed recently can then be done by 'find' or something similar and piped into 'git annex move/copy/drop'.
+
+And for your final note: fanotify can block accesses to files, it might be a bit ugly and certainly this is not for everyone, perhaps this could be externalized into some watching daemon too or if integrated to git-annex be treated very carefully and only be used if explicitly configured.
+
+"""]]
diff --git a/doc/forum/exporting_annexed_files.mdwn b/doc/forum/exporting_annexed_files.mdwn
new file mode 100644
index 000000000..0b8d6f36b
--- /dev/null
+++ b/doc/forum/exporting_annexed_files.mdwn
@@ -0,0 +1,4 @@
+Is there an easy way to export annexed files out of the repository? (e.g. to make a copy elsewhere, send a file by email...)
+
+Thanks,
+Denis.
diff --git a/doc/forum/exporting_annexed_files/comment_1_e08e4c79588e17fb2f1cdf53d9fab7ea._comment b/doc/forum/exporting_annexed_files/comment_1_e08e4c79588e17fb2f1cdf53d9fab7ea._comment
new file mode 100644
index 000000000..69fc46245
--- /dev/null
+++ b/doc/forum/exporting_annexed_files/comment_1_e08e4c79588e17fb2f1cdf53d9fab7ea._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.135"
+ subject="comment 1"
+ date="2012-06-15T19:25:59Z"
+ content="""
+Sure, you can simply:
+
+ cp annexedfile ~
+
+Or just attach the file right from the git repository to an email, like any other file. Should work fine.
+
+If you wanted to copy a whole directory to export, you'd need to use the -L flag to make cp follow the symlinks and copy the real contents:
+
+ cp -r -L annexeddirectory /media/usbdrive/
+"""]]
diff --git a/doc/forum/exporting_annexed_files/comment_2_15dc3024417b5b2ff3544a08beacab34._comment b/doc/forum/exporting_annexed_files/comment_2_15dc3024417b5b2ff3544a08beacab34._comment
new file mode 100644
index 000000000..3621f9b89
--- /dev/null
+++ b/doc/forum/exporting_annexed_files/comment_2_15dc3024417b5b2ff3544a08beacab34._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://denis.laxalde.org/"
+ nickname="dlax"
+ subject="nautilus"
+ date="2012-06-15T19:57:31Z"
+ content="""
+Ah! I was fooled by nautilus which is not able to properly handle symlinks when copying. It copies links instead of target [[!gnomebug 623580]].
+"""]]
diff --git a/doc/forum/exporting_annexed_files/comment_3_86f0e0f767a84a0f583e121d36cb7d48._comment b/doc/forum/exporting_annexed_files/comment_3_86f0e0f767a84a0f583e121d36cb7d48._comment
new file mode 100644
index 000000000..db6f90d88
--- /dev/null
+++ b/doc/forum/exporting_annexed_files/comment_3_86f0e0f767a84a0f583e121d36cb7d48._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.135"
+ subject="comment 3"
+ date="2012-06-16T03:26:37Z"
+ content="""
+That nautilous behavior is a bad thing when trying to export files out, but it's a good thing when just moving files around inside your repository...
+"""]]
diff --git a/doc/forum/fail_to_git_annex_add_some_files:_getFileStatus:_does_not_exist__40__v_3.20111231__41__.mdwn b/doc/forum/fail_to_git_annex_add_some_files:_getFileStatus:_does_not_exist__40__v_3.20111231__41__.mdwn
new file mode 100644
index 000000000..633ff6f9b
--- /dev/null
+++ b/doc/forum/fail_to_git_annex_add_some_files:_getFileStatus:_does_not_exist__40__v_3.20111231__41__.mdwn
@@ -0,0 +1,26 @@
+First, I'm using a 2011 version because i'm getting this kind of errors from cabal install (on Fedora 16 and 17):
+
+ $ cabal install git-annex --bindir=$HOME/.local/bin
+ Resolving dependencies...
+ cabal: cannot configure git-annex-3.20120406. It requires base >=4.5 && <5
+ For the dependency on base >=4.5 && <5 there are these packages: base-4.5.0.0.
+ However none of them are available.
+ base-4.5.0.0 was excluded because of the top level dependency base -any
+
+So I installed a 2011 version and it worked.
+
+Now, when I add some files in the git annex repository I get an error:
+
+ $ git annex add Photo\ Library/2010/06/28/IMG_4926.JPG
+ add Photo Library/2010/06/28/IMG_4926.JPG (checksum...)
+ git-annex: Photo Library/2010/06/28/IMG_4926.JPG: getFileStatus: does not exist (No such file or directory)
+ failed
+ git-annex: add: 1 failed
+
+None of the other files in the same directory are a problem. The file content is not a problem either as I can move the file elsewhere and git annex add it w/o any problem. It's this file in this directory that causes the problem.
+
+Something interesting though. If I move the file elsewhere, and git annex add it, there is no problem. Now, if I git mv the file back into its original location, and git annex fix the file, the symbolic link is wrong: instead of pointing to `../../../../.git/annex/objects/somefile` it points to `../../../annex/objects/somefile` (notice the missing `../.git/` part of the path).
+
+I can fix that by hand, and it works well, but that's very annoying. There are not much files having that bug though.
+
+[Mildred](http://mildred.fr)
diff --git a/doc/forum/fail_to_git_annex_add_some_files:_getFileStatus:_does_not_exist__40__v_3.20111231__41__/comment_1_990197bf01351dc1ccbe1940d5084adb._comment b/doc/forum/fail_to_git_annex_add_some_files:_getFileStatus:_does_not_exist__40__v_3.20111231__41__/comment_1_990197bf01351dc1ccbe1940d5084adb._comment
new file mode 100644
index 000000000..7164de760
--- /dev/null
+++ b/doc/forum/fail_to_git_annex_add_some_files:_getFileStatus:_does_not_exist__40__v_3.20111231__41__/comment_1_990197bf01351dc1ccbe1940d5084adb._comment
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="http://mildred.pip.verisignlabs.com/"
+ subject="Manually fixing links doesn't even work"
+ date="2012-04-12T15:46:54Z"
+ content="""
+I'm just answering myself: manually fixing symlinks doesn't always works. Sometimes the pre-commit hook will just rewrite the link to some wrong path.
+"""]]
diff --git a/doc/forum/fail_to_git_annex_add_some_files:_getFileStatus:_does_not_exist__40__v_3.20111231__41__/comment_2_3bb1d21b7f0d0bd6d59190ae9d246d46._comment b/doc/forum/fail_to_git_annex_add_some_files:_getFileStatus:_does_not_exist__40__v_3.20111231__41__/comment_2_3bb1d21b7f0d0bd6d59190ae9d246d46._comment
new file mode 100644
index 000000000..2fa6cc01a
--- /dev/null
+++ b/doc/forum/fail_to_git_annex_add_some_files:_getFileStatus:_does_not_exist__40__v_3.20111231__41__/comment_2_3bb1d21b7f0d0bd6d59190ae9d246d46._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 2"
+ date="2012-04-12T16:29:58Z"
+ content="""
+This bug was fixed in git-annex 3.20120230. You have a few options to get the fix:
+
+* Upgrade to ghc 7.4, the need for which is the cause of the cabal error message you pasted.
+* Manually [[download]] from git, and `git checkout ghc7.0` -- that branch will build with your old ghc and has the fix.
+* cherry-pick commit 51338486dcf9ab86de426e41b1eb31af1d3a6c87
+"""]]
diff --git a/doc/forum/fail_to_git_annex_add_some_files:_getFileStatus:_does_not_exist__40__v_3.20111231__41__/comment_3_692f268218690437138ae0540c879425._comment b/doc/forum/fail_to_git_annex_add_some_files:_getFileStatus:_does_not_exist__40__v_3.20111231__41__/comment_3_692f268218690437138ae0540c879425._comment
new file mode 100644
index 000000000..d5c84b431
--- /dev/null
+++ b/doc/forum/fail_to_git_annex_add_some_files:_getFileStatus:_does_not_exist__40__v_3.20111231__41__/comment_3_692f268218690437138ae0540c879425._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://mildred.pip.verisignlabs.com/"
+ subject="Thank you a lot"
+ date="2012-04-13T07:28:10Z"
+ content="""
+Thank you,
+
+I imagined it was something like that.
+I 'm just sorry I posted that on the forum and not on the bugs section (I hadn't discovered it at that time). but now, if people search for this error, they should find this.
+
+Note for Fedora users: unfortunately GHC 7.4 will not be shipped with Fedora 17 (which is still not released). The [feature page](https://fedoraproject.org/wiki/Features/GHC74) mention it for Fedora 18. I feel like I am using debian ... outdated packages the day of the release.
+
+And many thanks for this wonderful piece of software.
+
+Mildred
+"""]]
diff --git a/doc/forum/first-time_setup_git-annex.mdwn b/doc/forum/first-time_setup_git-annex.mdwn
new file mode 100644
index 000000000..735d74621
--- /dev/null
+++ b/doc/forum/first-time_setup_git-annex.mdwn
@@ -0,0 +1,7 @@
+I have a git installation on my web server (web faction hosting). It allows me to run repositories from my hosting account.
+
+What I want is to use git-annex as a dropbox replacement. Specifically, the central repository being my web server and then using local installations on my 2 mac laptops (primarily), access through browser on windows, and access on android as well (browser or some other method).
+
+I'm looking at the install instructions, walkthrough, etc. What I'm initially not clear on is whether I need to install git-annex on my (linux centOS) webserver and any machine through which I'm accessing the repo? Seems like that would be the case of course, but I wanted to validate.
+
+Am I going to run into issues that folks might already be able to warn me about? Anything I need to know?
diff --git a/doc/forum/first-time_setup_git-annex/comment_1_a58d83ee3a7c2251d9a775847223f8ca._comment b/doc/forum/first-time_setup_git-annex/comment_1_a58d83ee3a7c2251d9a775847223f8ca._comment
new file mode 100644
index 000000000..8b86d7b17
--- /dev/null
+++ b/doc/forum/first-time_setup_git-annex/comment_1_a58d83ee3a7c2251d9a775847223f8ca._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-05-13T18:39:59Z"
+ content="""
+Sorry it took so long to get back to you.
+
+You do not necessarily have to have git-annex installed on your web server. But it will open up one of the nicest ways to use git-annex with a server, which is to put a bare git repository on the server, and let git-annex send the contents of large files to that repository. It's fine to install any old version of git-annex on the server, they're all forwards and backwards compatable.
+
+In any case, you need git-annex installed on any computers where you want to access the repository, certainly.
+
+"""]]
diff --git a/doc/forum/flickrannex_--_not_sure_I_get_it.mdwn b/doc/forum/flickrannex_--_not_sure_I_get_it.mdwn
new file mode 100644
index 000000000..fa69d6158
--- /dev/null
+++ b/doc/forum/flickrannex_--_not_sure_I_get_it.mdwn
@@ -0,0 +1,7 @@
+flickrannex -- is it a way to upload your images to flickr by putting them in a git annex directory, and make them retrievable from it handily that way?
+
+Or is it a hack to exploit flickr's free storage, by allowing you to somehow wrap your files in images and uploading them?
+
+My python and knowledge of how git annex's hooks work is not good enough for me to be certain by reading the code.
+
+Thanks
diff --git a/doc/forum/flickrannex_--_not_sure_I_get_it/comment_1_57ea9f26760f970a70f09934d31a79b5._comment b/doc/forum/flickrannex_--_not_sure_I_get_it/comment_1_57ea9f26760f970a70f09934d31a79b5._comment
new file mode 100644
index 000000000..3d5da7d37
--- /dev/null
+++ b/doc/forum/flickrannex_--_not_sure_I_get_it/comment_1_57ea9f26760f970a70f09934d31a79b5._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-05-27T01:48:43Z"
+ content="""
+Little bit of both I think. Pictures uploaded by it are visible on flickr. You can configure a [[preferred_content]] expression so the flickr remote only wants *.jpg etc. Any other file is wrapped inside an image so flickr will accept it. It would probably be a good idea to configure git-annex to `untrust` your repository if using it this way.
+"""]]
diff --git a/doc/forum/flickrannex_--_not_sure_I_get_it/comment_2_ba93563b4ce1f6497a9f1d5e6eb0d1bb._comment b/doc/forum/flickrannex_--_not_sure_I_get_it/comment_2_ba93563b4ce1f6497a9f1d5e6eb0d1bb._comment
new file mode 100644
index 000000000..cb9b65f6a
--- /dev/null
+++ b/doc/forum/flickrannex_--_not_sure_I_get_it/comment_2_ba93563b4ce1f6497a9f1d5e6eb0d1bb._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="99.54.57.201"
+ subject="comment 2"
+ date="2013-05-27T01:57:25Z"
+ content="""
+Cool, thanks! I ran into some issues setting it up, I'll take those to github (I hadn't been able to get as far as setting it up with an annex)
+"""]]
diff --git a/doc/forum/flickrannex_--_not_sure_I_get_it/comment_3_74f143965f48c89a3583acf1b6a7635a._comment b/doc/forum/flickrannex_--_not_sure_I_get_it/comment_3_74f143965f48c89a3583acf1b6a7635a._comment
new file mode 100644
index 000000000..21fcde85d
--- /dev/null
+++ b/doc/forum/flickrannex_--_not_sure_I_get_it/comment_3_74f143965f48c89a3583acf1b6a7635a._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmkBwMWvNKZZCge_YqobCSILPMeK6xbFw8"
+ nickname="develop"
+ subject="I noticed you stopped filing issues on github"
+ date="2013-06-02T10:38:04Z"
+ content="""
+Does that mean the hook is working properly for you properly now?
+
+"""]]
diff --git a/doc/forum/flickrannex_--_not_sure_I_get_it/comment_4_493bb86dedfa91ccc0c9be4045953ee4._comment b/doc/forum/flickrannex_--_not_sure_I_get_it/comment_4_493bb86dedfa91ccc0c9be4045953ee4._comment
new file mode 100644
index 000000000..dd474ef59
--- /dev/null
+++ b/doc/forum/flickrannex_--_not_sure_I_get_it/comment_4_493bb86dedfa91ccc0c9be4045953ee4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="99.54.57.201"
+ subject="comment 4"
+ date="2013-06-02T20:27:08Z"
+ content="""
+it is, thank you! working perfectly.
+"""]]
diff --git a/doc/forum/flickrannex_--_not_sure_I_get_it/comment_5_2c410aa478b21c0e6eb0e4d54bc8c362._comment b/doc/forum/flickrannex_--_not_sure_I_get_it/comment_5_2c410aa478b21c0e6eb0e4d54bc8c362._comment
new file mode 100644
index 000000000..f55a894a8
--- /dev/null
+++ b/doc/forum/flickrannex_--_not_sure_I_get_it/comment_5_2c410aa478b21c0e6eb0e4d54bc8c362._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmkBwMWvNKZZCge_YqobCSILPMeK6xbFw8"
+ nickname="develop"
+ subject="comment 5"
+ date="2013-06-02T20:29:48Z"
+ content="""
+Good :)
+"""]]
diff --git a/doc/forum/fsck_gives_false_positives.mdwn b/doc/forum/fsck_gives_false_positives.mdwn
new file mode 100644
index 000000000..2fae57c4e
--- /dev/null
+++ b/doc/forum/fsck_gives_false_positives.mdwn
@@ -0,0 +1,6 @@
+Hi,
+
+I use git-annex 3.20120123 on a debian-testing amd-64 machine with software RAID6 and LVM2 on it. I needed to move the whole `/home` directory to another LV (the new LV is on encrypted PV, the old LV is encrypted and not properly aligned; I'm changing from encrypted `/home` only to encrypted everything except `/boot`), so I have used the `rsync -aAXH` from a `ro` mounted `/home` to a new LV mounted on `/mnt/home_2`. After the move was complete I run the `git annex fsck` on my (4TB of) data. The fsck finds some files bad, and moves them to the `..../bad` directory. So far so good, this is how it should be, right? But then- I have a file with sha1sum of all my files. So - I checked the 'bad' file against that. It was OK. Then I computed the SHA256 of the file - this is used by `git annex fsck`. It was OK, too. So how did it happen, that the file was marked as bad? Do I miss something here? Could it be related to the hardware (HDDs) and silent data corruption? Or is it the undesirable effect of rsync? Or maybe the fsck is at fault here?
+
+Any ideas?
+
diff --git a/doc/forum/fsck_gives_false_positives/comment_1_b91070218b9d5fb687eeee1f244237ad._comment b/doc/forum/fsck_gives_false_positives/comment_1_b91070218b9d5fb687eeee1f244237ad._comment
new file mode 100644
index 000000000..c65eaf51d
--- /dev/null
+++ b/doc/forum/fsck_gives_false_positives/comment_1_b91070218b9d5fb687eeee1f244237ad._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2012-02-14T16:58:33Z"
+ content="""
+Well, it should only move files to `.git/annex/bad/` if their filesize is wrong, or their checksum is wrong.
+
+You can try moving a file out of `.git/annex/bad/` and re-run fsck and see if it fails it again. (And if it does, paste in a log!)
+
+To do that --
+Suppose you have a file `.git/annex/bad/SHA256-s33--5dc45521382f1c7974d9dbfcff1246370404b952` and you know that file `foobar` was supposed to have that content (you can check that `foobar` is a symlink to that SHA value). Then reinject it:
+
+`git annex reinject .git/annex/bad/SHA256-s33--5dc45521382f1c7974d9dbfcff1246370404b952 foobar`
+"""]]
diff --git a/doc/forum/fsck_gives_false_positives/comment_2_f51c53f3f6e6ee1ad463992657db5828._comment b/doc/forum/fsck_gives_false_positives/comment_2_f51c53f3f6e6ee1ad463992657db5828._comment
new file mode 100644
index 000000000..1e0111e67
--- /dev/null
+++ b/doc/forum/fsck_gives_false_positives/comment_2_f51c53f3f6e6ee1ad463992657db5828._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="antymat"
+ ip="77.190.74.127"
+ subject="comment 2"
+ date="2012-02-14T22:48:37Z"
+ content="""
+Thanks, joey, but I still do not know, why the file that has been (and *is*) OK according to separate sha1 and sha256 checks, has been marked 'bad' by `fsck` and moved to `.git/annex/bad`. What could be a reason for that? Could have `rsync` caused it? I know too little about internal workings of `git-annex` to answer this question.
+
+But one thing I know for certain - the false positives should *not* happen, unless something *is* wrong with the file. Otherwise, if it is unreliable, if I have to check twice, it is useless. I might as well just keep checksums of all the files and do all checks by hand...
+"""]]
diff --git a/doc/forum/fsck_gives_false_positives/comment_3_692d6d4cd2f75a497e7d314041a768d2._comment b/doc/forum/fsck_gives_false_positives/comment_3_692d6d4cd2f75a497e7d314041a768d2._comment
new file mode 100644
index 000000000..bd807f404
--- /dev/null
+++ b/doc/forum/fsck_gives_false_positives/comment_3_692d6d4cd2f75a497e7d314041a768d2._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 3"
+ date="2012-02-14T22:57:29Z"
+ content="""
+All that git annex fsck does is checksum the file and move it away if the checksum fails.
+
+If bad data was somehow read from the disk that one time, what you describe could occur. I cannot think of any other way it could happen.
+"""]]
diff --git a/doc/forum/fsck_gives_false_positives/comment_4_7ceb395bf8a2e6a041ccd8de63b1b6eb._comment b/doc/forum/fsck_gives_false_positives/comment_4_7ceb395bf8a2e6a041ccd8de63b1b6eb._comment
new file mode 100644
index 000000000..038d41620
--- /dev/null
+++ b/doc/forum/fsck_gives_false_positives/comment_4_7ceb395bf8a2e6a041ccd8de63b1b6eb._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="antymat"
+ ip="77.190.74.127"
+ subject="comment 4"
+ date="2012-02-15T07:13:12Z"
+ content="""
+OK, thanks. I was just wondering - since there are links in git(-annex), and a hard links too, that maybe the issue has been caused by `rsync`.
+
+I will keep my eye on that and run checks with my own checksum and `fsck` from time to time, and see what happens. I will post my results here, but the whole run (`fsck` or checksum) takes almost 2 days, so I will not do it too often... ;)
+"""]]
diff --git a/doc/forum/fsck_gives_false_positives/comment_5_86484a504c3bbcecd5876982b9c95688._comment b/doc/forum/fsck_gives_false_positives/comment_5_86484a504c3bbcecd5876982b9c95688._comment
new file mode 100644
index 000000000..7f0fbf96a
--- /dev/null
+++ b/doc/forum/fsck_gives_false_positives/comment_5_86484a504c3bbcecd5876982b9c95688._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 5"
+ date="2012-02-15T15:22:56Z"
+ content="""
+The symlinks are in the git repository. So if the rsync damanged one, git would see the change. And nothing that happens to the symlinks can affect fsck.
+
+git-annex does not use hard links at all.
+
+fsck corrects mangled file permissions. It is possible to screw up the permissions so badly that it cannot see the files at all (ie, chmod 000 on a file under .git/annex/objects), but then fsck will complain and give up, not move the files to bad.
+So I don't see how a botched rsync could result in fsck moving a file with correct content to bad.
+"""]]
diff --git a/doc/forum/fsck_gives_false_positives/comment_6_1d4fbbd212fa92967abda346323031f4._comment b/doc/forum/fsck_gives_false_positives/comment_6_1d4fbbd212fa92967abda346323031f4._comment
new file mode 100644
index 000000000..294778cbf
--- /dev/null
+++ b/doc/forum/fsck_gives_false_positives/comment_6_1d4fbbd212fa92967abda346323031f4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmWQTrnPloMWiPFg8Y2Y5g-2IYe26D0KKw"
+ nickname="Jim"
+ subject="comment 6"
+ date="2012-07-07T16:18:06Z"
+ content="""
+It's also possible you got a one-time DRAM corruption. You have to expect those to happen every so often unless you're using ECC memory.
+"""]]
diff --git a/doc/forum/gadu_-_git-annex_disk_usage.mdwn b/doc/forum/gadu_-_git-annex_disk_usage.mdwn
new file mode 100644
index 000000000..c7a20c327
--- /dev/null
+++ b/doc/forum/gadu_-_git-annex_disk_usage.mdwn
@@ -0,0 +1,7 @@
+Based on the thread over at <http://git-annex.branchable.com/forum/__34__du__34___equivalent_on_an_annex__63__/> I decided to finally write a du like utility for git-annex. A 0.01 version is up over at <http://git-annex.mysteryvortex.com/git-annex-utils.html>. It works, but I intend to make it smarter about handling git repos and annexed files, as well as adding more of the options available in the standard du utility.
+
+Currently it will tally up the sizes of links that look like they are annexed files. I plan to make it actually interact with git and git-annex to verify the files are annexed and enable options like tallying files only from specific remotes, only missing files, not double counting files which are annexed multiple times but stored only once, etc...
+
+I'll have time to work on this on the weekends, and plan to get my git repo up soon. After gadu is mostly complete I might work on some other tools.
+
+Releases are signed with a PGP key with fingerprint 5E1A 65D7 D5E9 56F1 C239 43DF C6C8 9A0B 6003 8953 (available on the website)
diff --git a/doc/forum/gadu_-_git-annex_disk_usage/comment_10_f632a62c4dbbf01b29f146893d7725f9._comment b/doc/forum/gadu_-_git-annex_disk_usage/comment_10_f632a62c4dbbf01b29f146893d7725f9._comment
new file mode 100644
index 000000000..602cc4363
--- /dev/null
+++ b/doc/forum/gadu_-_git-annex_disk_usage/comment_10_f632a62c4dbbf01b29f146893d7725f9._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="Steve"
+ ip="92.104.175.136"
+ subject="comment 10"
+ date="2013-01-14T01:54:12Z"
+ content="""
+No problem, glad to see it is useful. I'm not exactly a web guy, but I want to get some sort of comment/discussion system up there soon so we aren't filling up Joey's web site with semi-offtopic discussion. (also a little beautification is in order)
+
+Yes, contributions are welcome. GPG/PGP encrypted email is the preferred mode of communication.
+
+Currently I ask for copyright assignment in case I want to change licenses in the future. I pledge not to go to a non-free license, but the GPL3 license choice was fairly arbitrary. I might want to add the \"or any later version\" clause, for example. There is also potential for a library to be split off which might benefit from something like LGPL licensing or similar. I haven't really studied the licensing situation since GPL3 came around, so I need to take some time to look into it.
+
+I don't want to have a licensing discussion here though as it would be offtopic. Feel free to email me and we can discuss.
+
+"""]]
diff --git a/doc/forum/gadu_-_git-annex_disk_usage/comment_11_73461da2d55d040cb43e0db286975821._comment b/doc/forum/gadu_-_git-annex_disk_usage/comment_11_73461da2d55d040cb43e0db286975821._comment
new file mode 100644
index 000000000..5f9a8bbec
--- /dev/null
+++ b/doc/forum/gadu_-_git-annex_disk_usage/comment_11_73461da2d55d040cb43e0db286975821._comment
@@ -0,0 +1,21 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 11"
+ date="2013-03-11T05:31:04Z"
+ content="""
+I don't want to steal gadu's thunder, and I really quite like having an ecosystem of tools develop around git-annex.
+
+With that said, \"git annex status .\" now shows the disk used for all files in the current directory and below. It also shows the number of keys, and the total amount of disk those keys would use.
+
+Additionally, you can use all the standard git-annex file limiting options. For example, here I'm finding out how much disk space is used by files located on a *remote* system:
+
+<pre>
+git annex status . --in turtle
+directory: .
+local annex keys: 0
+local annex size: 0 bytes
+known annex keys: 10
+known annex size: 3 gigabytes
+</pre>
+"""]]
diff --git a/doc/forum/gadu_-_git-annex_disk_usage/comment_12_6c4fb123091bde435c18ac3dfd5a9b77._comment b/doc/forum/gadu_-_git-annex_disk_usage/comment_12_6c4fb123091bde435c18ac3dfd5a9b77._comment
new file mode 100644
index 000000000..d228e196d
--- /dev/null
+++ b/doc/forum/gadu_-_git-annex_disk_usage/comment_12_6c4fb123091bde435c18ac3dfd5a9b77._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 12"
+ date="2013-03-11T05:33:09Z"
+ content="""
+BTW, I think gadu still has its own uses, due to having a du like output, that can list space used by subdirectories. You can do that with git annex status *, but it's much more verbose, and doesn't show a break down by deeper subdirectories.
+"""]]
diff --git a/doc/forum/gadu_-_git-annex_disk_usage/comment_1_067d0ffe8900751bd2d2743254ac4d77._comment b/doc/forum/gadu_-_git-annex_disk_usage/comment_1_067d0ffe8900751bd2d2743254ac4d77._comment
new file mode 100644
index 000000000..9699b6ee6
--- /dev/null
+++ b/doc/forum/gadu_-_git-annex_disk_usage/comment_1_067d0ffe8900751bd2d2743254ac4d77._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="Steve"
+ ip="92.104.175.136"
+ subject="0.02 is up"
+ date="2012-12-08T14:20:16Z"
+ content="""
+I fixed some bugs that gave the wrong answer occasionally, and made gadu much smarter now.
+
+It now searches for the .git dir an makes sure the git-annex links are well formed before counting them.
+I also added a few more du like options.
+"""]]
diff --git a/doc/forum/gadu_-_git-annex_disk_usage/comment_2_ec8b57426e4d82c3392eb7dd683f2ddc._comment b/doc/forum/gadu_-_git-annex_disk_usage/comment_2_ec8b57426e4d82c3392eb7dd683f2ddc._comment
new file mode 100644
index 000000000..04c6c3f65
--- /dev/null
+++ b/doc/forum/gadu_-_git-annex_disk_usage/comment_2_ec8b57426e4d82c3392eb7dd683f2ddc._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="http://sunny256.sunbase.org/"
+ nickname="sunny256"
+ subject="comment 2"
+ date="2012-12-08T15:35:16Z"
+ content="""
+Have downloaded v0.02 and experimented a bit, and it seems to work nicely. A couple of things, though:
+
+- It displays the sizes in 512 byte blocks as default. I find that very confusing, and the standard `du`(1) from GNU coreutils uses 1024kB as default. AFAIK 512 byte blocks is an old way of measuring sizes from the really ancient UNIX days. Traditionally correct, maybe, but not very useful these days.
+- When not specifying a path, can it use \"`.`\" as default?
+- A human-readable format would've been nice, like 234M or 13G. The `du`(1) from GNU coreutils uses `-h` for this, but that option is already used for `--help`. And that's OK, I think `-h` should be reserved for that purpose. IMHO using `-h` as a synonym for `--human-readable` was a bad choice by coreutils, but it's too late to change that now.
+
+Is there any Git repository available for git-annex-utils somewhere? That's my preferred way of getting updates and follow the development.
+
+Anyway, thanks. :)
+
+"""]]
diff --git a/doc/forum/gadu_-_git-annex_disk_usage/comment_3_38296fef5a2dc5794c2dc09df676b8c1._comment b/doc/forum/gadu_-_git-annex_disk_usage/comment_3_38296fef5a2dc5794c2dc09df676b8c1._comment
new file mode 100644
index 000000000..42e4f5a71
--- /dev/null
+++ b/doc/forum/gadu_-_git-annex_disk_usage/comment_3_38296fef5a2dc5794c2dc09df676b8c1._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="Steve"
+ ip="92.104.175.136"
+ subject="gadu 0.03 is up"
+ date="2012-12-09T13:05:10Z"
+ content="""
+* 1K blocksize is now the default
+* \".\" is now the default path
+* implemented -B/--block-size option
+* --help is no longer -h, it only has a long option like du
+* implemented -h/--human-readable option
+
+du will take up to yottabytes for the --block-size option. I had been fudging the sizes with a size_t thinking 16 exabytes was plenty big enough for now, but since I was implementing --block-size I went ahead and converted everything to use the GNU MP. So libgmp is now a dependency.
+
+--human-readable probably doesn't have exactly the same output, but I think it is good enough. I tried to make the options work mostly the same as du from core-utils. Let me know if you find other discrepancies.
+
+I'll see about making the git tree available soon, but it may have to wait until next weekend. I may also look into a forum for the website, or a mailing list.
+"""]]
diff --git a/doc/forum/gadu_-_git-annex_disk_usage/comment_4_1bcc94f9982c6cfd0888f3dba0f9221e._comment b/doc/forum/gadu_-_git-annex_disk_usage/comment_4_1bcc94f9982c6cfd0888f3dba0f9221e._comment
new file mode 100644
index 000000000..807dac1b3
--- /dev/null
+++ b/doc/forum/gadu_-_git-annex_disk_usage/comment_4_1bcc94f9982c6cfd0888f3dba0f9221e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://sunny256.sunbase.org/"
+ nickname="sunny256"
+ subject="comment 4"
+ date="2012-12-09T20:13:47Z"
+ content="""
+Thanks a lot, Steve. Awesome, got everything on my wishlist. :) A very useful utility, and works perfectly. Will be using this a lot. git-annex-utils is a good name for this, I'm sure if you place it on GitHub or somewhere else you'll get lots of contributions and this could grow to be a project containing many useful utilities for git-annex.
+"""]]
diff --git a/doc/forum/gadu_-_git-annex_disk_usage/comment_5_4365cd3031456fac1b563ee72984638e._comment b/doc/forum/gadu_-_git-annex_disk_usage/comment_5_4365cd3031456fac1b563ee72984638e._comment
new file mode 100644
index 000000000..e2611dbaa
--- /dev/null
+++ b/doc/forum/gadu_-_git-annex_disk_usage/comment_5_4365cd3031456fac1b563ee72984638e._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="Steve"
+ ip="92.104.175.136"
+ subject="comment 5"
+ date="2012-12-10T04:07:53Z"
+ content="""
+I pay attention to feedback ;)
+
+I'm not done with it yet, I want to add in some options to limit what gets counted.
+
+For example: If you have two annexed files that contain the same content using the same backend, they will be stored only once in the .git/annex/objects directory but be counted twice by gadu.
+
+I want to fix that, but I'll leave an option to keep that behavior if you want. I also want to add options to count or not count files that exist in a certain repo. It will be very easy to add options to only count files that you have or don't have locally as well.
+
+Making it pay attention to environment variables that git and git-annex do would also be a good idea. (like GIT_DIR, etc...)
+
+I'm open to good ideas that anybody has, unfortunately I can only work on it on the weekends for now.
+"""]]
diff --git a/doc/forum/gadu_-_git-annex_disk_usage/comment_6_2b03d7b857497cb811e992f85700cdcc._comment b/doc/forum/gadu_-_git-annex_disk_usage/comment_6_2b03d7b857497cb811e992f85700cdcc._comment
new file mode 100644
index 000000000..9b8d04908
--- /dev/null
+++ b/doc/forum/gadu_-_git-annex_disk_usage/comment_6_2b03d7b857497cb811e992f85700cdcc._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="markus"
+ ip="79.243.252.165"
+ subject="Great util!"
+ date="2012-12-28T17:45:27Z"
+ content="""
+Hi
+
+gadu is a great util! The speed increase compared to \"du -smL\" will make it my fav. util for size calc!
+
+ciao markus
+"""]]
diff --git a/doc/forum/gadu_-_git-annex_disk_usage/comment_7_03a4dfaf3bd73d41c6f3c3fab0a6a922._comment b/doc/forum/gadu_-_git-annex_disk_usage/comment_7_03a4dfaf3bd73d41c6f3c3fab0a6a922._comment
new file mode 100644
index 000000000..05f20ddcc
--- /dev/null
+++ b/doc/forum/gadu_-_git-annex_disk_usage/comment_7_03a4dfaf3bd73d41c6f3c3fab0a6a922._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/2grhJvAC049fJnvALDXek.6MRZMTlg--#eec89"
+ nickname="John"
+ subject="sizes has git-annex support"
+ date="2012-12-30T22:47:42Z"
+ content="""
+Just to note that I already added git-annex support to my \"sizes\" utility on Hackage several months back. With -A, it shows you storage totals with annex symlinks computed fully resolved.
+"""]]
diff --git a/doc/forum/gadu_-_git-annex_disk_usage/comment_8_fc6ddb4dc075ee42368863c1b026dbf7._comment b/doc/forum/gadu_-_git-annex_disk_usage/comment_8_fc6ddb4dc075ee42368863c1b026dbf7._comment
new file mode 100644
index 000000000..642ad3d96
--- /dev/null
+++ b/doc/forum/gadu_-_git-annex_disk_usage/comment_8_fc6ddb4dc075ee42368863c1b026dbf7._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="Steve"
+ ip="92.104.175.136"
+ subject="git repo is now up"
+ date="2013-01-01T23:39:33Z"
+ content="""
+sunny256, the git repo is now accessible at <http://git.mysteryvortex.com>
+
+Markus, never used the -m option myself. I added it in git it'll be in the next tarball. (I plan to go through the du man page and add all appropriate options soon)
+
+John, I wasn't aware of your sizes utility. I'll look into it.
+
+"""]]
diff --git a/doc/forum/gadu_-_git-annex_disk_usage/comment_9_f03254e518cbdda73e4b88e72476275d._comment b/doc/forum/gadu_-_git-annex_disk_usage/comment_9_f03254e518cbdda73e4b88e72476275d._comment
new file mode 100644
index 000000000..d3ebbae61
--- /dev/null
+++ b/doc/forum/gadu_-_git-annex_disk_usage/comment_9_f03254e518cbdda73e4b88e72476275d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://sunny256.sunbase.org/"
+ nickname="sunny256"
+ subject="The git-annex-utils repo"
+ date="2013-01-09T09:39:16Z"
+ content="""
+Thanks for setting up the git-annex-utils repo, Steve. Will install the newest gadu(1) on my computers now. I'll probably contribute some patches for some utility scripts or programs, if that's OK. What's your preferred way to receive patches? GPG-encrypted mail to your address in the commit log?
+"""]]
diff --git a/doc/forum/get_and_copy_with_bare_repositories.mdwn b/doc/forum/get_and_copy_with_bare_repositories.mdwn
new file mode 100644
index 000000000..846887f96
--- /dev/null
+++ b/doc/forum/get_and_copy_with_bare_repositories.mdwn
@@ -0,0 +1,7 @@
+is `git annex get` and `git annex copy --to somewhere` expected to work with bare repos? the [[bare repositories]] page doesn't indicate otherwise, but a `git annex get` does plain nothing in my setup.
+
+if it's supposed not to work, there should be an error message saying that and an indication on the [[bare repositories]], otherwise, how can i trace it down?
+
+in case it is just unimplemented for lack of use cases: my setup consists of several laptops using parts of a 200gb+ photo collection, a central trusted server that should host everything, and an external encrypted remote backup. clients *should* copy everything they add to both central locations, but i'd prefer the trusted server to sync the two of them too.
+
+`get` and `copy` usually operate on the current directory, which in case of a bare repo does not contain any relevant files, but i tried explicitly specifying files too. `git annex` should either look them up in master, or always operate on all files (as indexed in the `git-annex` branch) unconditionally.
diff --git a/doc/forum/get_and_copy_with_bare_repositories/comment_1_a6e4628c0770e3f5e81348a6f29dd845._comment b/doc/forum/get_and_copy_with_bare_repositories/comment_1_a6e4628c0770e3f5e81348a6f29dd845._comment
new file mode 100644
index 000000000..a19dd8631
--- /dev/null
+++ b/doc/forum/get_and_copy_with_bare_repositories/comment_1_a6e4628c0770e3f5e81348a6f29dd845._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.252.11.120"
+ subject="comment 1"
+ date="2012-11-13T17:30:31Z"
+ content="""
+git-annex commands only operate on files in the currently checked out working copy. You can send files to/from bare repos from non-bare repos. But you cannot do anything with them inside the bare repo, just as regular git doesn't let you commit inside a bare repo.
+
+There is talk about [[todo/add_-all_option]], which would be usable in bare repos.
+"""]]
diff --git a/doc/forum/get_and_copy_with_bare_repositories/comment_2_652fa1bae5c2bb63dcffcbda97a567c4._comment b/doc/forum/get_and_copy_with_bare_repositories/comment_2_652fa1bae5c2bb63dcffcbda97a567c4._comment
new file mode 100644
index 000000000..fdf9f91a2
--- /dev/null
+++ b/doc/forum/get_and_copy_with_bare_repositories/comment_2_652fa1bae5c2bb63dcffcbda97a567c4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.193"
+ subject="comment 2"
+ date="2013-07-03T18:13:25Z"
+ content="""
+`git annex get` and `git annex copy`, as well as `git annex move` can now be used in a bare repository. In this mode, they behave as if --all were specified, and so operate on every single version of every single file.
+"""]]
diff --git a/doc/forum/getting_git_annex_to_do_a_force_copy_to_a_remote.mdwn b/doc/forum/getting_git_annex_to_do_a_force_copy_to_a_remote.mdwn
new file mode 100644
index 000000000..cc9091ae5
--- /dev/null
+++ b/doc/forum/getting_git_annex_to_do_a_force_copy_to_a_remote.mdwn
@@ -0,0 +1,11 @@
+I'm not sure if this is my stupidity or if it's a bug, but
+
+ git annex copy --force --to REMOTE .
+
+just zip's through really quickly and doesn't actually force a copy to a
+remote location. This is just following up on the
+[[bugs/git-annex_directory_hashing_problems_on_osx]]. I want to just do a force copy of all my data to my portable disk to really make sure that the data is really there. I would similarly would want to make sure I can force a
+
+ git annex copy --force --from REMOTE .
+
+to pull down files from a remote.
diff --git a/doc/forum/getting_git_annex_to_do_a_force_copy_to_a_remote/comment_1_3deb2c31cad37a49896f00d600253ee3._comment b/doc/forum/getting_git_annex_to_do_a_force_copy_to_a_remote/comment_1_3deb2c31cad37a49896f00d600253ee3._comment
new file mode 100644
index 000000000..d2692f26f
--- /dev/null
+++ b/doc/forum/getting_git_annex_to_do_a_force_copy_to_a_remote/comment_1_3deb2c31cad37a49896f00d600253ee3._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-04-03T16:49:01Z"
+ content="""
+How remote is REMOTE? If it's a directory on the same computer, then git-annex copy --to is actually quickly checking that each file is present on the remote, and when it is, skipping copying it again.
+
+If the remote is ssh, git-annex copy talks to the remote to see if it has the file. This makes copy --to slow, as Rich [[complained_before|forum/batch_check_on_remote_when_using_copy]]. :)
+
+So, copy --to does not trust location tracking information (unless --fast is specified), which means that it should be doing exactly what you want it to do in your situation -- transferring every file that is really not present in the destination repository already.
+
+Neither does copy --from, by the way. It always checks if each file is present in the current repository's annex before trying to download it.
+"""]]
diff --git a/doc/forum/getting_git_annex_to_do_a_force_copy_to_a_remote/comment_2_627f54d158d3ca4b72e45b4da70ff5cd._comment b/doc/forum/getting_git_annex_to_do_a_force_copy_to_a_remote/comment_2_627f54d158d3ca4b72e45b4da70ff5cd._comment
new file mode 100644
index 000000000..107930319
--- /dev/null
+++ b/doc/forum/getting_git_annex_to_do_a_force_copy_to_a_remote/comment_2_627f54d158d3ca4b72e45b4da70ff5cd._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 2"
+ date="2011-04-03T16:59:47Z"
+ content="""
+Remote as in \"another physical machine\". I assumed that
+
+ git annex copy --force --to REMOTE .
+
+would have not trusted the contents in the current directory (or the remote that is being copied to) and then just go off and re-download/upload all the files and overwrite what is already there. I expected the combination of *--force* and copy *--to* that it would not bother to check if the files are there or not and just copy it regardless of the outcome.
+"""]]
diff --git a/doc/forum/getting_git_annex_to_do_a_force_copy_to_a_remote/comment_3_3f49dab11aae5df0c4eb5e4b8d741379._comment b/doc/forum/getting_git_annex_to_do_a_force_copy_to_a_remote/comment_3_3f49dab11aae5df0c4eb5e4b8d741379._comment
new file mode 100644
index 000000000..c3df21498
--- /dev/null
+++ b/doc/forum/getting_git_annex_to_do_a_force_copy_to_a_remote/comment_3_3f49dab11aae5df0c4eb5e4b8d741379._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 3"
+ date="2011-04-03T17:12:35Z"
+ content="""
+On second thought maybe the current behaviour is better than what I am suggesting that the force command should do. I guess it's better to be safe than sorry.
+"""]]
diff --git a/doc/forum/git-annex___38___ikiwiki_experiment.mdwn b/doc/forum/git-annex___38___ikiwiki_experiment.mdwn
new file mode 100644
index 000000000..5b426a180
--- /dev/null
+++ b/doc/forum/git-annex___38___ikiwiki_experiment.mdwn
@@ -0,0 +1,28 @@
+Hi,
+
+I've been experimenting with combining [ikiwiki](http://ikiwiki.info) with git-annex and it seems to work. Thought I'd post my process. I've [commented](http://ikiwiki.info/todo/git-annex_support/discussion/) on the ikiwiki website as well but perhaps it'd be of interest to git-annex folks.
+
+I have very little understanding of any of the tools involved and have just attempted to make it work using my limited knowledge. I don't use the web interface for ikiwiki which simplifies things.
+
+The [website in question](http://stockholm.kalleswork.net) just went online and is currently an archive of architectural photographs and the site relies heavily on the ikiwiki osm and album plugins.
+
+### Setting things up
+
+To start with I set up the wiki on the server and git clone to into `$wrkdir` on my laptop. I then initialize a git-annex repo in the `$srcdir` on the server. Leaving the `$gitdir` untouched. The `$scrdir` git-annex repo has to be in `direct` mode. Before doing any syncing I add `annex-ignore = true` and `annex-sync = false` to `.git/config` in the origin repo (`$gitdir`): this is to prevent polluting `$gitdir` with git-annex data. The same process is repeated in the `$wrkdir` on the laptop.
+
+### Pushing and syncing
+
+With this setup I can then `git add remote $srcdir`, `git add $file` and `git-push` mdwn files and other lightweight data from the laptop. While `git annex-add`, `git-annex sync` and `git-annex copy --to $srcdir` jpg's and other heavy files. All pure git commands work as expected with ikiwiki and the website recompiles etc.
+
+### Snags
+
+I'm frequently left with (non-dangling) symlinks in the `$srcdir` despite the annex repo being in direct mode. When this happens `git-annex fsck` sorts things out.
+
+Uploading image files does require a bit of manual work. But as this is done less frequently it's not much of an issue for me. I'm guessing that by doing things it the correct order (whatever that might be) I could avoid some of the manual work.
+
+The thing to keep in mind is to never `git-add` the typechanged annexed files in the $srcdir. In general I never use git commands in the $srcdir.
+
+The main problem is the symlinks though as they demand a manual `git-annex fsck`. I have no idea what causes the symlinks in a direct mode repo.
+
+Any comments?
+
diff --git a/doc/forum/git-annex___38___ikiwiki_experiment/comment_1_9f74449ec91577dbf6095f4beafac293._comment b/doc/forum/git-annex___38___ikiwiki_experiment/comment_1_9f74449ec91577dbf6095f4beafac293._comment
new file mode 100644
index 000000000..332f77bcc
--- /dev/null
+++ b/doc/forum/git-annex___38___ikiwiki_experiment/comment_1_9f74449ec91577dbf6095f4beafac293._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://id.koumbit.net/anarcat"
+ ip="72.0.72.144"
+ subject="how about the web interface?"
+ date="2013-09-25T11:09:58Z"
+ content="""
+I understand you do not use the web interface - but what if you did? would it commit all those files into git?
+
+Could we add the git-annex files to a .gitignore file?
+"""]]
diff --git a/doc/forum/git-annex___38___ikiwiki_experiment/comment_2_e034585c8b51cc30b35c1f7ae68205bf._comment b/doc/forum/git-annex___38___ikiwiki_experiment/comment_2_e034585c8b51cc30b35c1f7ae68205bf._comment
new file mode 100644
index 000000000..2201813fe
--- /dev/null
+++ b/doc/forum/git-annex___38___ikiwiki_experiment/comment_2_e034585c8b51cc30b35c1f7ae68205bf._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawk3HGoDpnOPob5jOjvIootmkve1-nCpRiI"
+ nickname="Kalle"
+ subject="comment 2"
+ date="2013-09-25T11:58:42Z"
+ content="""
+I have very poor understanding of what ikiwiki actually does behind the scenes including how it uses the $srcdir and $gitdir.
+
+The only way I could see the web interface working would be to use the git-annex content expressions and having the assistant running on the server. That still doesn't prevent large files from being checked into git though? That all depends on which order ikiwiki can be made to do things.
+
+I might be able to test on a local wiki but that would have to wait a while.
+
+
+"""]]
diff --git a/doc/forum/git-annex___38___ikiwiki_experiment/comment_3_fbbd47c3dbe8de24b0df664e4afd5cb8._comment b/doc/forum/git-annex___38___ikiwiki_experiment/comment_3_fbbd47c3dbe8de24b0df664e4afd5cb8._comment
new file mode 100644
index 000000000..63919bd22
--- /dev/null
+++ b/doc/forum/git-annex___38___ikiwiki_experiment/comment_3_fbbd47c3dbe8de24b0df664e4afd5cb8._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.220"
+ subject="comment 3"
+ date="2013-09-25T17:03:29Z"
+ content="""
+Interesting experiment.
+
+I don't know why you don't want to let git-annex sync its data to $gitdir.
+
+The symlinks could be occuring because of a bug in direct mode. (I have fixed many past bugs that caused that.) But just as likely it's because ikiwiki will run `git pull` in the srcdir.
+
+I think it would make more sense to use the underlay plugin and keep your annexed repository in a separate underlay. This would guarantee ikiwiki doesn't run git commands in there, and would ensure that nothing done with the web interface could mess with the annex.
+"""]]
diff --git a/doc/forum/git-annex___38___ikiwiki_experiment/comment_4_55da5c3c41c13b08590ce1ff8117cef6._comment b/doc/forum/git-annex___38___ikiwiki_experiment/comment_4_55da5c3c41c13b08590ce1ff8117cef6._comment
new file mode 100644
index 000000000..6299326a8
--- /dev/null
+++ b/doc/forum/git-annex___38___ikiwiki_experiment/comment_4_55da5c3c41c13b08590ce1ff8117cef6._comment
@@ -0,0 +1,23 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawk3HGoDpnOPob5jOjvIootmkve1-nCpRiI"
+ nickname="Kalle"
+ subject="comment 4"
+ date="2013-09-25T18:28:40Z"
+ content="""
+@Joey
+
+ > I don't know why you don't want to let git-annex sync its data to $gitdir.
+
+Well neither do I! :) It seemed to be the way to avoid duplicating data while still having the images picked up by the ikiwiki album plugin. Wouldn't the files in the $gitdir end up duplicated in $srcdir?
+
+ > The symlinks could be occuring because of a bug in direct mode.
+ > (I have fixed many past bugs that caused that.) But just as likely
+ > it's because ikiwiki will run git pull in the srcdir.
+
+When you mention it I've had similar problems with my vfat usb annex repos. Using the post-receive merge hook to make files visible for non git-annex devices about town. Nothing I can reliably recreate but I will keep my eye out for bugs.
+
+ > I think it would make more sense to use the underlay plugin and keep
+ > your annexed repository in a separate underlay.
+
+Yep that would be ideal. For my usecase the album plugin is vital and I can't understand how album would pick up and deal with images in an underlay dir. This is a bit OT for this site though most of my questions are ikiwiki related.
+"""]]
diff --git a/doc/forum/git-annex___38___ikiwiki_experiment/comment_5_f67823351164ddfe7d595685c3679652._comment b/doc/forum/git-annex___38___ikiwiki_experiment/comment_5_f67823351164ddfe7d595685c3679652._comment
new file mode 100644
index 000000000..2701bd4af
--- /dev/null
+++ b/doc/forum/git-annex___38___ikiwiki_experiment/comment_5_f67823351164ddfe7d595685c3679652._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawk3HGoDpnOPob5jOjvIootmkve1-nCpRiI"
+ nickname="Kalle"
+ subject="comment 5"
+ date="2013-09-26T06:56:49Z"
+ content="""
+Turns out using the underlay was a piece of cake! Just mirror the folder structure of the repo in your underlaydir put your jpegs there and off you go. Images are picked up by the album plugin and it all just works. No need to coax git-annex into doing odd stuff.
+
+Thought I'd post this for other ikiwikers.
+"""]]
diff --git a/doc/forum/git-annex___38___ikiwiki_experiment/comment_6_d5cc91164772849d027fed5f962d9000._comment b/doc/forum/git-annex___38___ikiwiki_experiment/comment_6_d5cc91164772849d027fed5f962d9000._comment
new file mode 100644
index 000000000..1d3abdf5d
--- /dev/null
+++ b/doc/forum/git-annex___38___ikiwiki_experiment/comment_6_d5cc91164772849d027fed5f962d9000._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://id.koumbit.net/anarcat"
+ ip="72.0.72.144"
+ subject="step by step?"
+ date="2013-09-26T09:40:57Z"
+ content="""
+So how does this actually work in practice? Is the underlay directory a completely disconnected repository?
+
+Can we have step by step instructions on how to set this up?
+"""]]
diff --git a/doc/forum/git-annex___38___ikiwiki_experiment/comment_7_cb4ec7ed3c39d0649133191a85ea6ab3._comment b/doc/forum/git-annex___38___ikiwiki_experiment/comment_7_cb4ec7ed3c39d0649133191a85ea6ab3._comment
new file mode 100644
index 000000000..8e387d89a
--- /dev/null
+++ b/doc/forum/git-annex___38___ikiwiki_experiment/comment_7_cb4ec7ed3c39d0649133191a85ea6ab3._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawk3HGoDpnOPob5jOjvIootmkve1-nCpRiI"
+ nickname="Kalle"
+ subject="comment 7"
+ date="2013-09-26T13:05:53Z"
+ content="""
+@anarcat
+
+ > Can we have step by step instructions on how to set this up?
+
+[I described the ikiwiki album setup](http://ikiwiki.info/forum/ikiwiki_with_album___38___underlay_plugins/) on the ikiwiki website as there are no git-annex tricks anymore. Just standard behaviour.
+
+ > So how does this actually work in practice? Is the underlay directory a
+ > completely disconnected repository?
+
+Yes they are completely separate repos. Really the underlay dir could be managed in any way you like svn, rsync, ftp etc. I didn't expect the album plugin to pick everything up but apparently it does! Perhaps underlays are completely integrated and appear as 'normal' to all of ikiwiki?
+"""]]
diff --git a/doc/forum/git-annex___38___ikiwiki_experiment/comment_8_86565e5e1508ff1862f88975446650a2._comment b/doc/forum/git-annex___38___ikiwiki_experiment/comment_8_86565e5e1508ff1862f88975446650a2._comment
new file mode 100644
index 000000000..473551f65
--- /dev/null
+++ b/doc/forum/git-annex___38___ikiwiki_experiment/comment_8_86565e5e1508ff1862f88975446650a2._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://id.koumbit.net/anarcat"
+ ip="72.0.72.144"
+ subject="comment 8"
+ date="2013-09-26T13:10:25Z"
+ content="""
+Yes, I believe that is the way the underlay works - the files are just picked up.
+
+As for the ikiwiki forum post - maybe you should move it to the \"tips\" section? :)
+
+Thanks for the documentation!!
+"""]]
diff --git a/doc/forum/git-annex_across_two_filesystems.mdwn b/doc/forum/git-annex_across_two_filesystems.mdwn
new file mode 100644
index 000000000..1e95a793c
--- /dev/null
+++ b/doc/forum/git-annex_across_two_filesystems.mdwn
@@ -0,0 +1,30 @@
+Hi everyone,
+
+I need some suggestions on how to operate git-annex best in my setup.
+
+I need git-annex mainly for its ability to have directories of all my data on all my nodes but not for the data redundancy it can provide.
+I have one node that contains 2 filesystems that I want to merge in one git-annex repository. One filesystem (lets call it SAFE) is on top of a RAID1 between two 1TB hds. The other (BIG) is on top of a 3TB hd. SAFE holds data I do not want to loose (like digital pictures). BIG holds data that I can loose.
+
+I do not have enough disk space on other nodes to get rid of the RAID1.
+
+This is how I mount my filesystems:
+
+SAFE at ~/AllData/
+
+BIG at ~/AllData/bigfiles/
+
+The root of the git repository is at ~/AllData/ however when I do:
+
+git-annex add ~/AllData/bigfiles/file1
+It says:
+add bigfiles/file1 failed
+
+I assume that is because of file1 being on a different filesystem.
+
+Do I have to create two repositories: one for each filesystem or do you have any ideas on how to use git-annex best in this scenario?
+Having two repositories also has the disadvantage that I need two repositories on all other nodes am I right?
+
+Thanks for you suggestions
+
+
+
diff --git a/doc/forum/git-annex_across_two_filesystems/comment_1_53167648b8b70b41d19ca662a5f3687e._comment b/doc/forum/git-annex_across_two_filesystems/comment_1_53167648b8b70b41d19ca662a5f3687e._comment
new file mode 100644
index 000000000..cd363948c
--- /dev/null
+++ b/doc/forum/git-annex_across_two_filesystems/comment_1_53167648b8b70b41d19ca662a5f3687e._comment
@@ -0,0 +1,26 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-04-22T19:48:55Z"
+ content="""
+git-annex stores the contents of files inside `.git/annex/objects`. The `git annex add` is failing because it cannot `rename()` the file into that directory, because it is on a different filesystem. Even if it did a more expensive move of the file, it would not do what you want, because all the files would be moved to the `.git/annex/objects` directory, which is stored on your smaller drive.
+
+The way git-annex is intended to be used with multiple drives is this:
+
+* Make a separate git repository on each drive.
+* Set up git remotes connecting these repositories together. You don't have to connect them all up, but at least make
+ the git repository on your main filesystem have a remote for each git repository on other drives.
+* Use `git annex sync` to keep the git repositories in sync. (Or do it manually with `git pull`)
+* When you want a file to be available in the local repository, use `git annex get $file` to get it.
+* When your local repository is getting too full, use `git annex drop` or `git annex move` to flush files
+ out to the other drive(s).
+
+The [[walkthrough]] goes through an example of adding a removable USB drive this way, but you can do the same thing for
+non-removable drives.
+
+> Having two repositories also has the disadvantage that I need two repositories on all other nodes am I right?
+
+No -- you combine the two repositories, so any clone of either one contains all the files in both. Other notes then only need one
+repository. However, for another node to be able to get files from both repositories on this node, it will need to have two git remotes configured, one for each repository.
+"""]]
diff --git a/doc/forum/git-annex_across_two_filesystems/comment_2_39adeebc1af9c437f1fc2e00c07509bf._comment b/doc/forum/git-annex_across_two_filesystems/comment_2_39adeebc1af9c437f1fc2e00c07509bf._comment
new file mode 100644
index 000000000..ef57bdfec
--- /dev/null
+++ b/doc/forum/git-annex_across_two_filesystems/comment_2_39adeebc1af9c437f1fc2e00c07509bf._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://pradermecker.myopenid.com/"
+ ip="81.244.215.244"
+ subject="comment 2"
+ date="2013-04-27T17:14:43Z"
+ content="""
+It works fine. After it is set up with the client as described, sync is automatic from the Assistant.
+
+What I find cumbersome is the fact that I need to manually call \"git annex sync\" on the remote (usb or local ssh) to view (generate) the link. Is there a way to avoid this extra step ?
+
+"""]]
diff --git a/doc/forum/git-annex_across_two_filesystems/comment_3_f4e3f28db005301adeef7ccd2c9998fb._comment b/doc/forum/git-annex_across_two_filesystems/comment_3_f4e3f28db005301adeef7ccd2c9998fb._comment
new file mode 100644
index 000000000..52a8f5565
--- /dev/null
+++ b/doc/forum/git-annex_across_two_filesystems/comment_3_f4e3f28db005301adeef7ccd2c9998fb._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmp1ThsNNAbSn46ju-gwFELfStlhl8usJo"
+ nickname="Marek"
+ subject="I should have thought of this"
+ date="2013-04-30T19:55:19Z"
+ content="""
+Thanks joey, I thought of the object storage just yesterday and that the drive where it resides needs to be the big one.
+
+I think that I will do it as you described with one addition:
+
+I set up the git-annex repository on my big drive. Lets call that BIG.
+Then I set up another on the smaller drive (or raid) and set both to sync. Lets call that RAID.
+
+BUT: Can I use num copies to tell BIG to only sync files in certain directories to RAID. Or will syncing sync everything regardless?
+
+Thanks for your help
+
+"""]]
diff --git a/doc/forum/git-annex_across_two_filesystems/comment_4_53fa7ac6f80e3281768a7bfd3d438b34._comment b/doc/forum/git-annex_across_two_filesystems/comment_4_53fa7ac6f80e3281768a7bfd3d438b34._comment
new file mode 100644
index 000000000..bab1a8b02
--- /dev/null
+++ b/doc/forum/git-annex_across_two_filesystems/comment_4_53fa7ac6f80e3281768a7bfd3d438b34._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmp1ThsNNAbSn46ju-gwFELfStlhl8usJo"
+ nickname="Marek"
+ subject="Another correction"
+ date="2013-04-30T20:11:57Z"
+ content="""
+sync just syncs the meta data but not the objects itself right? I have to do an explicit git-annex copy -to or copy -from?
+
+
+"""]]
diff --git a/doc/forum/git-annex_across_two_filesystems/comment_5_2e1be54c01970ef3456e8af4aaf00cbf._comment b/doc/forum/git-annex_across_two_filesystems/comment_5_2e1be54c01970ef3456e8af4aaf00cbf._comment
new file mode 100644
index 000000000..83644a554
--- /dev/null
+++ b/doc/forum/git-annex_across_two_filesystems/comment_5_2e1be54c01970ef3456e8af4aaf00cbf._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 5"
+ date="2013-04-30T21:57:13Z"
+ content="""
+Yes, `git annex sync` only syncs the metadata.
+
+If you have numcopies set to to, and run `git annex copy --to RAID --auto`, it will only copy files that have less than 2 copies. (Same with `git annex copy --from BIG --auto` or `git annex get --auto`)
+"""]]
diff --git a/doc/forum/git-annex_and_tagfs.mdwn b/doc/forum/git-annex_and_tagfs.mdwn
new file mode 100644
index 000000000..1ef40aea1
--- /dev/null
+++ b/doc/forum/git-annex_and_tagfs.mdwn
@@ -0,0 +1,14 @@
+Hi,
+
+Thanks for git-annex, really a great project.
+Another related feature which would be useful to have is described by tagfs [3][] [4][], experimental implementations such as [tagfs over fuse][1], and [tagsistant][2] exist, but having a solution within the power of git-annex would really be attractive.
+
+How hard would this be to implement within the existing infrastructure?
+Thanks.
+
+related post: [[multiple_sym_links___40__for_tagging_photos__41____63__]]
+
+[1]: http://code.google.com/p/tagfs/
+[2]: www.tagsistant.net/
+[3]: http://site.xam.de/2006/01-tagfs.pdf
+[4]: http://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=6&ved=0CE4QFjAF&url=http%3A%2F%2Fweb.mit.edu%2F6.033%2F2011%2Fwwwdocs%2Fwriting-samples%2Fsbezek_dp1.pdf&ei=ILQkUdqxMueR0QWgx4CwDw&usg=AFQjCNE1eWeFxmaxzOLZYVsb0tomqWNQaw&bvm=bv.42661473,d.d2k
diff --git a/doc/forum/git-annex_and_tagfs/comment_1_887c74cb61d30198322ef74ebc80f950._comment b/doc/forum/git-annex_and_tagfs/comment_1_887c74cb61d30198322ef74ebc80f950._comment
new file mode 100644
index 000000000..95739bd93
--- /dev/null
+++ b/doc/forum/git-annex_and_tagfs/comment_1_887c74cb61d30198322ef74ebc80f950._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.210"
+ subject="comment 1"
+ date="2013-02-24T21:52:41Z"
+ content="""
+I welcome people doing this kind of thing with git-annex. Since you can have multiple files linking to the same content easily, it should be a reasonable platform with which to build something like this.
+"""]]
diff --git a/doc/forum/git-annex_assistant_with_2_dedicated_servers.mdwn b/doc/forum/git-annex_assistant_with_2_dedicated_servers.mdwn
new file mode 100644
index 000000000..1544b14ef
--- /dev/null
+++ b/doc/forum/git-annex_assistant_with_2_dedicated_servers.mdwn
@@ -0,0 +1,11 @@
+Hello,
+
+I am looking for a solution to replicate lots of files between 2 servers (with dedicated IP address) over WAN. (I already looked at GlusterFS, DRBD, Bittorent-Sync and ownCloud, but comments are welcome). Now I am evaluating git-annex but it is (kind of) hard to get the concepts as I am not familiar with git.
+
+I could already connect the servers by following the steps of "remote sharing walkthrough" but I feel that using a 3rd special node (as "transfer repository" / rsync or ssh) is an overhead and should not be needed. But no matter how hard I tried, I couldn't make the 2 servers do a sync without a special node.
+
+Could you please give me a hint how to do it? Or even better, some detailed steps. :)
+
+Thanks,
+
+David
diff --git a/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_10_533ade2215c879cd46782fd66a97b167._comment b/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_10_533ade2215c879cd46782fd66a97b167._comment
new file mode 100644
index 000000000..ec7dc0f86
--- /dev/null
+++ b/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_10_533ade2215c879cd46782fd66a97b167._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="David"
+ ip="178.21.48.117"
+ subject="comment 10"
+ date="2013-11-16T23:15:49Z"
+ content="""
+Great. Understood. :) Thanks.
+
+Although there is one more thing that I don't really understand. Why do we need 2 repositories. In my mind (without knowing git) I thout it would work with one repository, where both server1 and server2 can upload/download files and they got synced through this.
+
+ server1 <-> repository (somewhere, eother server1 or server2) <-> server2
+
+Now they use different repositories and I don't get why. Also I don't get how conflict-handling can be done if there are 2 repositories for the 2 transfer-ways.
+
+Sorry to bother you with this.
+"""]]
diff --git a/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_11_c9ae51d7b772cf7a91d90925f74d2b60._comment b/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_11_c9ae51d7b772cf7a91d90925f74d2b60._comment
new file mode 100644
index 000000000..f614d066d
--- /dev/null
+++ b/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_11_c9ae51d7b772cf7a91d90925f74d2b60._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.64"
+ subject="comment 11"
+ date="2013-11-16T23:25:26Z"
+ content="""
+When using git, each place you access your files is a separate repository. Thus, you have:
+
+server1 (repository) <--> server2 (repository)
+"""]]
diff --git a/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_12_41fbee0ec9bc890e309bcd48a58c3851._comment b/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_12_41fbee0ec9bc890e309bcd48a58c3851._comment
new file mode 100644
index 000000000..d707de6e1
--- /dev/null
+++ b/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_12_41fbee0ec9bc890e309bcd48a58c3851._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="David"
+ ip="178.21.48.117"
+ subject="comment 12"
+ date="2013-11-18T11:25:06Z"
+ content="""
+Hello,
+
+Thanks for your help and explanation. Now I had some time to test git-annex and I had a sad experience. I tried to sync the files from server1 to server2 (as described before). We are talking about 87000 small files (these are maildir folders and each file is an e-mail) with the total size of 19 Gbytes. After a few hours git-annex assistant consumed all memory on both servers ... and then all swap ... and then kernel killed git-annex. The servers have 512 MB RAM and 1 GB swap.
+
+According to the Scalability page (http://git-annex.branchable.com/scalability/) the \"memory usage should be constant\" and I am sure I didn't run \"git-annex unused\".
+
+Is this memory consumption normal or it might be a bug? What shall we do?
+
+Thanks,
+
+David
+"""]]
diff --git a/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_13_571cffc0beb8ba5fc936db6971cd3d62._comment b/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_13_571cffc0beb8ba5fc936db6971cd3d62._comment
new file mode 100644
index 000000000..aefe98813
--- /dev/null
+++ b/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_13_571cffc0beb8ba5fc936db6971cd3d62._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="David"
+ ip="178.21.48.117"
+ subject="comment 13"
+ date="2013-11-19T09:17:26Z"
+ content="""
+Please tell me if/how I can help you. For example if you need access to servers to test...
+"""]]
diff --git a/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_1_53a79af2d8e3abe50b983bf91972b8f2._comment b/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_1_53a79af2d8e3abe50b983bf91972b8f2._comment
new file mode 100644
index 000000000..f6f058988
--- /dev/null
+++ b/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_1_53a79af2d8e3abe50b983bf91972b8f2._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.246"
+ subject="comment 1"
+ date="2013-11-16T17:42:48Z"
+ content="""
+The [[assistant/remote sharing walkthrough]] assumes that the computers are not servers, so they might not be turned on at the same time, and cannot directly contect each other.
+
+With 2 servers, it's much simpler. Just add a git remote on each pointing at the git repository on the other server, and run the git-annex assistant on both to keep them in sync.
+
+You can add the git remote with `git remote add otherserver ssh://otherserver/path/to/repo`, or you can use the webapp to do it (Add another repository -> Remote server)
+
+(If your WAN puts the servers on the same virtual subnet, ie a VPN, you can also probably use local pairing over the WAN to get to the same setup by a different route.)
+"""]]
diff --git a/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_2_c0ba3e8b7fbf8a5ed718001cec8df676._comment b/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_2_c0ba3e8b7fbf8a5ed718001cec8df676._comment
new file mode 100644
index 000000000..8c4bb5922
--- /dev/null
+++ b/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_2_c0ba3e8b7fbf8a5ed718001cec8df676._comment
@@ -0,0 +1,35 @@
+[[!comment format=mdwn
+ username="David"
+ ip="178.21.48.117"
+ subject="still need some clarification"
+ date="2013-11-16T22:02:46Z"
+ content="""
+Hello,
+
+Thanks for your reply. I guessed that there is an easier, direct way to do it. But unfortunately I still need some clarification. This is how I tried:
+
+1. Cleared everything to start from scratch.
+2. I started git-annex on server1: screen git annex webapp --listen=server1_ip, opened the webapp and created the local repository /media/mail
+3. I configured the XMPP account on server1.
+4. Started git-annex on server2: screen git annex webapp --listen=server2_ip, opened the webapp and created the local repository /media/mail
+5. I configured the XMPP account on server2.
+
+And here comes the confusing part:
+
+6. On server1 I clicked Add another repository / Remote server: and configured ssh server2 to the same folder: /media/mail. I chose client repository group instead of transfer. (I am not sure if I did it right) ... but server1 started sync-ing.
+7. On server2 I clicked Add another repository / Remote server: and configured ssh server1 to the same folder: /media/mail. Then I received an error message:
+
+ Failed to make repository
+ Something went wrong setting up the repository on the remote server.
+
+ Transcript:
+
+ init error: could not lock config file /media/mail-test/mail/.git/config: Permission denied
+ git-annex: git [Param \"config\",Param \"annex.version\",Param \"3\"] failed
+
+Cold you please help me where I did wrong?
+
+Thanks,
+
+David
+"""]]
diff --git a/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_3_60c39bc8ef74e80e72381d514b6dd223._comment b/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_3_60c39bc8ef74e80e72381d514b6dd223._comment
new file mode 100644
index 000000000..f9e405b70
--- /dev/null
+++ b/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_3_60c39bc8ef74e80e72381d514b6dd223._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.246"
+ subject="comment 3"
+ date="2013-11-16T22:18:20Z"
+ content="""
+It seems to me that you probably told git-annex to log into server2 as a user that does not have write access to sever2:/media/mail. Check the username field in the remote repository form.
+"""]]
diff --git a/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_4_6241120b4325c905661ef72881f4d7af._comment b/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_4_6241120b4325c905661ef72881f4d7af._comment
new file mode 100644
index 000000000..bb7c19389
--- /dev/null
+++ b/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_4_6241120b4325c905661ef72881f4d7af._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="David"
+ ip="178.21.48.117"
+ subject="still need some clarification"
+ date="2013-11-16T22:31:07Z"
+ content="""
+Hey,
+
+Yes, you were right. The ssh user did not have privileges to read/write the folder. Now I have corrected this issue and things started sync-ing.
+
+But I am afraid, this is not exactly the thing I wanted to achieve. My goal was to sync from folder to folder ... and not from folder to repository both ways.
+
+So, what I would like to do is that if I create a file at server1 (e.g. /media/mail/test01.txt) then it should appear at server2 at /media/mail/test01.txt.
+
+How can I achieve this?
+
+Thanks a lot.
+
+David
+"""]]
diff --git a/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_5_cab00b8fa195340f4d3fdaf5af975b57._comment b/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_5_cab00b8fa195340f4d3fdaf5af975b57._comment
new file mode 100644
index 000000000..179a65a99
--- /dev/null
+++ b/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_5_cab00b8fa195340f4d3fdaf5af975b57._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.64"
+ subject="comment 5"
+ date="2013-11-16T22:55:34Z"
+ content="""
+Well, that's what should happen. What behavior are you seeing? What version of git-annex are you using?
+"""]]
diff --git a/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_6_e24df9a1c68724a912b8ac6533d9bd25._comment b/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_6_e24df9a1c68724a912b8ac6533d9bd25._comment
new file mode 100644
index 000000000..a28e947dd
--- /dev/null
+++ b/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_6_e24df9a1c68724a912b8ac6533d9bd25._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="David"
+ ip="178.21.48.117"
+ subject="comment 6"
+ date="2013-11-16T22:58:15Z"
+ content="""
+Hello,
+
+Yes, meanwhile files started appearing. :) Maybe I just did not wait enough time.
+
+So, I have just one more question. Shall I set the remote ssh repositories to client or transfer? I read the docs and understand the difference, but in my case I simply cannot decide.
+
+Thanks a lot for your hard work and great support.
+
+David
+"""]]
diff --git a/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_7_ace3dc7c60c710a04b0a587206b341c4._comment b/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_7_ace3dc7c60c710a04b0a587206b341c4._comment
new file mode 100644
index 000000000..c41fe492f
--- /dev/null
+++ b/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_7_ace3dc7c60c710a04b0a587206b341c4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.64"
+ subject="comment 7"
+ date="2013-11-16T23:04:29Z"
+ content="""
+In your situation, you do not have or need a repository whose only job is to transfer files between two other client repositories. So the right choice for your repositories is client -- or something else possibly -- but almost certainly not transfer.
+"""]]
diff --git a/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_8_9a96bc970a17ed62b0ceb7aa3f0a6f8b._comment b/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_8_9a96bc970a17ed62b0ceb7aa3f0a6f8b._comment
new file mode 100644
index 000000000..1d0f1db52
--- /dev/null
+++ b/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_8_9a96bc970a17ed62b0ceb7aa3f0a6f8b._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="David"
+ ip="178.21.48.117"
+ subject="comment 8"
+ date="2013-11-16T23:09:32Z"
+ content="""
+Okay. One last question. Could you please help me understand how this sync works now?
+
+So for example if I save a file on server1, it gets pushed to server2's repository. But how is it translated back to a normal file from the repository?
+
+And in this case will this file be on server2's repository as well (so are there 2 copies on server2, one in the repository and one human-readabl)?
+
+Thanks!
+"""]]
diff --git a/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_9_ea88e0696f6e25e6904248a323f6cc36._comment b/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_9_ea88e0696f6e25e6904248a323f6cc36._comment
new file mode 100644
index 000000000..cafac1077
--- /dev/null
+++ b/doc/forum/git-annex_assistant_with_2_dedicated_servers/comment_9_ea88e0696f6e25e6904248a323f6cc36._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.64"
+ subject="comment 9"
+ date="2013-11-16T23:11:58Z"
+ content="""
+Since you created these repositories with the webapp, they default to using [[direct_mode]]. git-annex handles putting the files in place when they are transferred to the repository. Only 1 copy is made, there is no separate copy in the repository.
+"""]]
diff --git a/doc/forum/git-annex_build_for_Nokia_N9___40__Meego_Harmattan__41___and_Sailfish_OS.mdwn b/doc/forum/git-annex_build_for_Nokia_N9___40__Meego_Harmattan__41___and_Sailfish_OS.mdwn
new file mode 100644
index 000000000..e2be4fd22
--- /dev/null
+++ b/doc/forum/git-annex_build_for_Nokia_N9___40__Meego_Harmattan__41___and_Sailfish_OS.mdwn
@@ -0,0 +1,7 @@
+Hi,
+
+Is there a chance to get a build of git-annex for the Nokia N9 smartphone with Meego Harmattan and later for Sailfish OS (Jolla phone)?
+Git is already available for Meego Harmattan: http://www.who.is.free.fr/wiki/doku.php?id=harmattan
+
+Cheers,
+Tobias
diff --git a/doc/forum/git-annex_build_for_Nokia_N9___40__Meego_Harmattan__41___and_Sailfish_OS/comment_1_301a51c48c3d54f9d37feace26a772f8._comment b/doc/forum/git-annex_build_for_Nokia_N9___40__Meego_Harmattan__41___and_Sailfish_OS/comment_1_301a51c48c3d54f9d37feace26a772f8._comment
new file mode 100644
index 000000000..d6464b679
--- /dev/null
+++ b/doc/forum/git-annex_build_for_Nokia_N9___40__Meego_Harmattan__41___and_Sailfish_OS/comment_1_301a51c48c3d54f9d37feace26a772f8._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="paulvt"
+ ip="2001:1af8:ff19:0:a288:b4ff:fe2c:f600"
+ subject="comment 1"
+ date="2013-07-13T08:21:29Z"
+ content="""
+I've just checked and almost all of the depends that Debian Sid on my laptop has, the N9 has. But in the case of build-depends, they are nowhere near since the entire Haskell stack is not available...
+"""]]
diff --git a/doc/forum/git-annex_communication_channels.mdwn b/doc/forum/git-annex_communication_channels.mdwn
new file mode 100644
index 000000000..8c56ac36a
--- /dev/null
+++ b/doc/forum/git-annex_communication_channels.mdwn
@@ -0,0 +1,10 @@
+Thought I'd ask how y'all are finding the current communication by this forum/website/git repo only.
+
+Would there be a benefit to having an irc channel for git-annex?
+
+Maybe a mailing list? (Any persuasive reason why it would be better than this forum?)
+
+Are the existing RSS feeds on this site, for eg, new [[comments]] and posts to this forum, sufficient to keep up with
+things?
+
+--[[Joey]]
diff --git a/doc/forum/git-annex_communication_channels/comment_1_198325d2e9337c90f026396de89eec0e._comment b/doc/forum/git-annex_communication_channels/comment_1_198325d2e9337c90f026396de89eec0e._comment
new file mode 100644
index 000000000..163aae02c
--- /dev/null
+++ b/doc/forum/git-annex_communication_channels/comment_1_198325d2e9337c90f026396de89eec0e._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 1"
+ date="2011-03-28T15:48:08Z"
+ content="""
+No matter what you end up doing, I would appreciate a git-annex-announce@ list.
+
+I really like the persistence of ikiwiki, but it's not ideal for quick communication. I would be fine with IRC and/or ML. The advantage of a ML over ikiwiki is that it doesn't seem to be as \"wasteful\" to mix normal chat with actual problem-solving. But maybe that's merely my own perception.
+
+Speaking of RSS: I thought I had added a wishlist item to ikiwiki about providing per-subsite RSS feeds. For example there is no (obvious) way to subscribe to changes in http://git-annex.branchable.com/forum/git-annex_communication_channels/ .
+
+FWIW, I resorted to tagging my local clone of git-annex to keep track of what I've read, already.
+
+
+-- RichiH
+"""]]
diff --git a/doc/forum/git-annex_communication_channels/comment_2_c7aeefa6ef9a2e75d8667b479ade1b7f._comment b/doc/forum/git-annex_communication_channels/comment_2_c7aeefa6ef9a2e75d8667b479ade1b7f._comment
new file mode 100644
index 000000000..09a2b8c1a
--- /dev/null
+++ b/doc/forum/git-annex_communication_channels/comment_2_c7aeefa6ef9a2e75d8667b479ade1b7f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 2"
+ date="2011-03-28T18:35:50Z"
+ content="""
+I think the forums/website currently is sufficient, I do at times wish there was a mailing list or anonymous git push to the wiki as I find editing posts through the web browser is some times tedious (the lack of !fmt or alt-q bugs me at times ;) ). The main advantage of keeping stuff on the site/forum is that everything gets saved and passed on to anyone who checks out the git repo of the code base.
+"""]]
diff --git a/doc/forum/git-annex_communication_channels/comment_3_1ff08a3e0e63fa0e560cbc9602245caa._comment b/doc/forum/git-annex_communication_channels/comment_3_1ff08a3e0e63fa0e560cbc9602245caa._comment
new file mode 100644
index 000000000..72a48445e
--- /dev/null
+++ b/doc/forum/git-annex_communication_channels/comment_3_1ff08a3e0e63fa0e560cbc9602245caa._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 3"
+ date="2011-03-28T20:47:23Z"
+ content="""
+Push access to the non-code bits of git-annex' ikiwiki would be very welcome indeed. Given the choice, I would rather edit everything in Vim than in a browser. -- RichiH
+"""]]
diff --git a/doc/forum/git-annex_communication_channels/comment_4_1ba6ddf54843c17c7d19a9996f2ab712._comment b/doc/forum/git-annex_communication_channels/comment_4_1ba6ddf54843c17c7d19a9996f2ab712._comment
new file mode 100644
index 000000000..d6bba9365
--- /dev/null
+++ b/doc/forum/git-annex_communication_channels/comment_4_1ba6ddf54843c17c7d19a9996f2ab712._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnx8kHW66N3BqmkVpgtXDlYMvr8TJ5VvfY"
+ nickname="Yaroslav"
+ subject="comment 4"
+ date="2011-04-13T17:53:26Z"
+ content="""
+.1 cents: Having IRC would be really nice for seeking quick help. E.g. like I was trying to do now, google lead me to this page.
+"""]]
diff --git a/doc/forum/git-annex_communication_channels/comment_5_404b723a681eb93fee015cea8024b6bc._comment b/doc/forum/git-annex_communication_channels/comment_5_404b723a681eb93fee015cea8024b6bc._comment
new file mode 100644
index 000000000..042dcc1f3
--- /dev/null
+++ b/doc/forum/git-annex_communication_channels/comment_5_404b723a681eb93fee015cea8024b6bc._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkptNW1PzrVjYlJWP_9e499uH0mjnBV6GQ"
+ nickname="Christian"
+ subject="comment 5"
+ date="2011-04-14T11:24:59Z"
+ content="""
+I would also like an git-annex channel. Would be #git-annex@OFTC ok?
+"""]]
diff --git a/doc/forum/git-annex_communication_channels/comment_6_0d87d0e26461494b1d7f8a701a924729._comment b/doc/forum/git-annex_communication_channels/comment_6_0d87d0e26461494b1d7f8a701a924729._comment
new file mode 100644
index 000000000..8dfd0f820
--- /dev/null
+++ b/doc/forum/git-annex_communication_channels/comment_6_0d87d0e26461494b1d7f8a701a924729._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 6"
+ date="2011-04-15T19:32:08Z"
+ content="""
+We seem to be using #vcs-home @ OFTC for now. madduck is fine with it and joeyh pokes his head in there, as well. I just added a CIA bot to #vcs-home and this comment is a test if pushing works. -- RichiH
+"""]]
diff --git a/doc/forum/git-annex_communication_channels/comment_7_2c87c7a0648fe87c2bf6b4391f1cc468._comment b/doc/forum/git-annex_communication_channels/comment_7_2c87c7a0648fe87c2bf6b4391f1cc468._comment
new file mode 100644
index 000000000..830d678ca
--- /dev/null
+++ b/doc/forum/git-annex_communication_channels/comment_7_2c87c7a0648fe87c2bf6b4391f1cc468._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="anonymous git push"
+ date="2011-05-19T19:21:51Z"
+ content="""
+@Jimmy mentioned anonymous git push -- that is now enabled for this wiki. Enjoy!
+
+I may try to spend more time on #vcs-home -- or I can be summoned there from my other lurking places on irc, I guess.
+"""]]
diff --git a/doc/forum/git-annex_on_OSX.mdwn b/doc/forum/git-annex_on_OSX.mdwn
new file mode 100644
index 000000000..a00548366
--- /dev/null
+++ b/doc/forum/git-annex_on_OSX.mdwn
@@ -0,0 +1 @@
+See [[install/OSX]].
diff --git a/doc/forum/git-annex_on_Samba_share.mdwn b/doc/forum/git-annex_on_Samba_share.mdwn
new file mode 100644
index 000000000..0235820c0
--- /dev/null
+++ b/doc/forum/git-annex_on_Samba_share.mdwn
@@ -0,0 +1,9 @@
+I want to put my photos into a git-annex repository, syncing it with my girlfriends computer and our NAS.
+If possible, I'd like to be able to add files to the NAS and have them synced, so I guess a special remote doesn't work here.
+
+Unfortunately, git-annex doesn't run on my NAS directly (yet), so I thought of mounting the NAS with CIFS, and creating an annex there that syncs with the local ones.
+While this seems to work fine with one computer, I wonder what will happen if I mount the Samba share on my and my girlfriend's computer at the same time.
+
+In theory, the NAS supports Samba Unix extensions which includes POSIX locking, but a weird bug that prevents you from removing a named pipe from Samba, making git-annex init fail (sent a bug report to Synology). When I disable Unix extensions it works. It then detects a crippled file system though.
+
+Any thoughts?
diff --git a/doc/forum/git-annex_on_Samba_share/comment_1_3e9cfdf2c088e48c967ad08f79966742._comment b/doc/forum/git-annex_on_Samba_share/comment_1_3e9cfdf2c088e48c967ad08f79966742._comment
new file mode 100644
index 000000000..dead48316
--- /dev/null
+++ b/doc/forum/git-annex_on_Samba_share/comment_1_3e9cfdf2c088e48c967ad08f79966742._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmqz6wCn-Q1vzrsHGvEJHOt_T5ZESilxhc"
+ nickname="Sören"
+ subject="Update"
+ date="2013-06-26T17:26:05Z"
+ content="""
+After reading trough this again, I'd like to rephrase my question.
+
+Is it safe if two independent assistants access the same repository at the same time (assuming locking works)?
+
+But, much more important, a big thanks for creating git-annex! I'm using it successfully to keep my files in sync at home and at work and I think it is a really amazing tool. So thanks for the hard work!
+"""]]
diff --git a/doc/forum/git-annex_on_Samba_share/comment_2_9d3df393b7b727653598453d94dd33db._comment b/doc/forum/git-annex_on_Samba_share/comment_2_9d3df393b7b727653598453d94dd33db._comment
new file mode 100644
index 000000000..7b17cb2a2
--- /dev/null
+++ b/doc/forum/git-annex_on_Samba_share/comment_2_9d3df393b7b727653598453d94dd33db._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.193"
+ subject="comment 2"
+ date="2013-06-26T17:40:21Z"
+ content="""
+If you're asking if you can run two git-annex assistant programs inside the same repository at the same time, the answer is no. Assuming locking works (grin), the second program will detect the first is running and refuse to start.
+
+If your question is, can two or more git-annex assistant or other programs, running in separate repositories, access files in the same remote safely at the same time, the answer is yes! You can, for that matter, run multiple git-annex commands at the same time in the same repository, and they're also entirely safe, thanks to some locking it does.
+
+You should post your story to [[design/assistant/blog/day_288__success_stories]]!
+"""]]
diff --git a/doc/forum/git-annex_on_Ubuntu_13.04_and_13.10_not_working.mdwn b/doc/forum/git-annex_on_Ubuntu_13.04_and_13.10_not_working.mdwn
new file mode 100644
index 000000000..1a00326d7
--- /dev/null
+++ b/doc/forum/git-annex_on_Ubuntu_13.04_and_13.10_not_working.mdwn
@@ -0,0 +1,12 @@
+I am trying to get git-annex working on Ubuntu, specifically 13.04 and now 13.10 (I thought upgrading to a new distro. would fix the issue).
+
+I have tried:
+
+ * installing via apt-get install git-annex
+ * installing via cabal (full-build)
+
+Both times git-annex install successfully with no errors. I then start the webapp and create a repository (which git-annex creates successfully), I then add the folders and files I want it to sync. Git-annex finds the files and says it has began syncing them, but it never moves past the first batch of files it 'says' it had started syncing. I have waited 5+ hours at one point and nothing has changed. Also, the webapp is incredibly slow, it takes 15+ seconds to perform ANY action (such as saving options or viewing the logs). The issue definitely isn't my computer as I am using an high-end SSD, core i7, DDR3 RAM, etc...
+
+Also the logs produce no errors of any kind and actually show git-annex adding files, most of the log entries say add 'filedirectory/filename.txt' as an example.
+
+I have gotten this to successfully work on Fedora, but Ubuntu (13.04/13.10) is having serious problems.
diff --git a/doc/forum/git-annex_on_Ubuntu_13.04_and_13.10_not_working/comment_1_209956f3812450a43986d4ca5e647da6._comment b/doc/forum/git-annex_on_Ubuntu_13.04_and_13.10_not_working/comment_1_209956f3812450a43986d4ca5e647da6._comment
new file mode 100644
index 000000000..2c4cbd291
--- /dev/null
+++ b/doc/forum/git-annex_on_Ubuntu_13.04_and_13.10_not_working/comment_1_209956f3812450a43986d4ca5e647da6._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="64.134.31.139"
+ subject="comment 1"
+ date="2013-10-22T17:57:27Z"
+ content="""
+I don't really understand the problem you're describing. Is the problem with it uploading the files it's added to another remote? Does it sit there saying \"syncing with $remote\" forever? Or what?
+
+As to the webapp speed problem, it seems likely to me this is not related to CPU speed or load. It sounds rather like a DNS timeout problem, or an ipv6 to ipv4 fallback problem. Although since the URL to the webapp is http://127.0.0.1, it can't really be either of those..
+"""]]
diff --git a/doc/forum/git-annex_on_Ubuntu_13.04_and_13.10_not_working/comment_3_12a58b8efe545e09b64760c87849839b._comment b/doc/forum/git-annex_on_Ubuntu_13.04_and_13.10_not_working/comment_3_12a58b8efe545e09b64760c87849839b._comment
new file mode 100644
index 000000000..6e2d780ec
--- /dev/null
+++ b/doc/forum/git-annex_on_Ubuntu_13.04_and_13.10_not_working/comment_3_12a58b8efe545e09b64760c87849839b._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlEeLtIxQCU0qe4q5lbrZp8AcUSUUcRrkg"
+ nickname="Zach"
+ subject="comment 3"
+ date="2013-10-23T02:01:09Z"
+ content="""
+The problem is not with a remote annex. The issue I am having is git-annex never finishes syncing.
+
+Maybe a screenshot will help. http://i.imgur.com/9HSr8bl.png
+
+It never gets passed the Startup scan.
+"""]]
diff --git a/doc/forum/git-annex_on_Ubuntu_13.04_and_13.10_not_working/comment_3_e0f7328603256f25c3be3706ecc9c76c._comment b/doc/forum/git-annex_on_Ubuntu_13.04_and_13.10_not_working/comment_3_e0f7328603256f25c3be3706ecc9c76c._comment
new file mode 100644
index 000000000..413a807ad
--- /dev/null
+++ b/doc/forum/git-annex_on_Ubuntu_13.04_and_13.10_not_working/comment_3_e0f7328603256f25c3be3706ecc9c76c._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="64.134.31.139"
+ subject="comment 3"
+ date="2013-10-23T15:27:40Z"
+ content="""
+Your screenshot shows git-annex is in the process of adding 6244 files. Depending on the size of those files, it could take some time to read their contents in order to calculate a checksum and add them to the repository. This would not normally take hours, unless your disk is very slow or the files are extremely big.
+
+You might get some useful information if you enable debugging (Configuration -> Preferences -> Enable debug logging) and look at the log.
+
+(This is not \"syncing\" btw. You have not set up any other repository for it to sync data with.)
+"""]]
diff --git a/doc/forum/git-annex_on_Ubuntu_13.04_and_13.10_not_working/comment_4_6bb8e4522241556fb82784d9b834cbfe._comment b/doc/forum/git-annex_on_Ubuntu_13.04_and_13.10_not_working/comment_4_6bb8e4522241556fb82784d9b834cbfe._comment
new file mode 100644
index 000000000..314d01e89
--- /dev/null
+++ b/doc/forum/git-annex_on_Ubuntu_13.04_and_13.10_not_working/comment_4_6bb8e4522241556fb82784d9b834cbfe._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlEeLtIxQCU0qe4q5lbrZp8AcUSUUcRrkg"
+ nickname="Zach"
+ subject="comment 4"
+ date="2013-10-25T20:40:26Z"
+ content="""
+Everything works, it was just taking a while on one the folders; let it run overnight, and it was done.
+
+Thanks for the help!
+"""]]
diff --git a/doc/forum/git-annex_on_Ubuntu_13.04_and_13.10_not_working/comment_5_89a5296b461d400b51006074a13a4560._comment b/doc/forum/git-annex_on_Ubuntu_13.04_and_13.10_not_working/comment_5_89a5296b461d400b51006074a13a4560._comment
new file mode 100644
index 000000000..e6508fe54
--- /dev/null
+++ b/doc/forum/git-annex_on_Ubuntu_13.04_and_13.10_not_working/comment_5_89a5296b461d400b51006074a13a4560._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 5"
+ date="2013-10-26T15:53:28Z"
+ content="""
+Can you confirm that the files in the directory it was adding were so large that it would normally take hours to checksum them all?
+"""]]
diff --git a/doc/forum/git-annex_on_Ubuntu_13.04_and_13.10_not_working/comment_6_62daef4b4392c951b914a01b3effac11._comment b/doc/forum/git-annex_on_Ubuntu_13.04_and_13.10_not_working/comment_6_62daef4b4392c951b914a01b3effac11._comment
new file mode 100644
index 000000000..4adcc568f
--- /dev/null
+++ b/doc/forum/git-annex_on_Ubuntu_13.04_and_13.10_not_working/comment_6_62daef4b4392c951b914a01b3effac11._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlEeLtIxQCU0qe4q5lbrZp8AcUSUUcRrkg"
+ nickname="Zach"
+ subject="comment 6"
+ date="2013-10-26T21:05:07Z"
+ content="""
+The folder that took a while is actually only 291.5 MB total, containing 25,977 items in total. I know that is the folder that was having some issues because I committed each folder separately.
+"""]]
diff --git a/doc/forum/git-annex_on_archlinuxarm__44___armv6.mdwn b/doc/forum/git-annex_on_archlinuxarm__44___armv6.mdwn
new file mode 100644
index 000000000..edfd0ad4e
--- /dev/null
+++ b/doc/forum/git-annex_on_archlinuxarm__44___armv6.mdwn
@@ -0,0 +1,20 @@
+Hi!
+
+I can't get git-annex to run on my archlinuxARM sytem. It fails with
+
+ $ git annex test
+ error: git-annex died of signal 11
+
+ Its a RaspberryPi (model B I think) so its an ARM11 (armv6h if I'm not mistaken). I use archlinuxarm because I am familiar with the distribution and you can have a very lean system. There is a very crude package for git-annex arm and armv7 that is build like this: https://github.com/archlinuxarm/PKGBUILDs/blob/master/alarm/git-annex/PKGBUILD . Crude, because it just takes the debian package, changes the version of libraries where apropriate and packs it as archlinux package. Two problems: 1) It's not been tested on armv6. 2) The 4.20130417 version does not exist anymore on the debian mirrors.
+
+1. The debian package is not marked as armv5 or armv7 specific and is runs on the RaspberryPi with Raspbian (but in an pretty old version if I remember correctly). So I would have imagined it runs on armv6h in general.\\
+2. I just did the same magic as in the linked PKGBUILD with a more current version to build the package but it still crashes. Can I get the old version anywhere to check if it works with that?
+
+
+Cheers,
+ Hannes
+
+Background for whoever's interested :)
+I tried to set up a RaspberryPi to manage my files, contacts and calendars. That shouts out loud for owncloud because of its convenience (caldav, carddav, webdav and a nice interface bundled together). However, compared to git-annex owncloud is unbearably slow (on an RaspberryPi) and lacks git-annex's easy way to keep your files sorted even if you don't have them on your local disk.
+
+For these reasons I tried to install a hybrid git-annex/owncloud system. There, basically, the files are served by owncloud but at the same time also managed (and served) by git-annex (+ssh). As far as I can see that should not have any noticeable side effects in my use case (mostly single user). I have some external hard drives connected to the RaspberryPi of which I will just symlink the appropriate folders to the owncloud 'files' folder. This way I can also just take the drives with me and still have the same (UUID) git annex repository on them. Any comments?
diff --git a/doc/forum/git-annex_on_archlinuxarm__44___armv6/comment_1_88fa644df8614c2db0d092b3eb1d3156._comment b/doc/forum/git-annex_on_archlinuxarm__44___armv6/comment_1_88fa644df8614c2db0d092b3eb1d3156._comment
new file mode 100644
index 000000000..516ec0017
--- /dev/null
+++ b/doc/forum/git-annex_on_archlinuxarm__44___armv6/comment_1_88fa644df8614c2db0d092b3eb1d3156._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.51"
+ subject="comment 1"
+ date="2013-09-12T16:56:50Z"
+ content="""
+You seem to be trying to take a binary built for one distribution with one CPU architecture and use it on another distribution on another CPU architecture. It's not very susprising that this does not work.
+
+Compiling git-annex from source for your particular architecture and distribution should not be difficult.
+"""]]
diff --git a/doc/forum/git-annex_pre-commit_eats_all_my_4GB_of_ram.mdwn b/doc/forum/git-annex_pre-commit_eats_all_my_4GB_of_ram.mdwn
new file mode 100644
index 000000000..82ca06b85
--- /dev/null
+++ b/doc/forum/git-annex_pre-commit_eats_all_my_4GB_of_ram.mdwn
@@ -0,0 +1,24 @@
+Hi all,
+
+git-annex basically renders my repository unmanageble. What is the
+best and save (!) way to recover?
+
+Here is my situation:
+
+I have a fairly large repository with ~8000 managed files taking about
+65GB of disk space.
+
+git-annex worked well there. But some programs choke on the
+symlinks. So, I converted the repository to direct mode. The
+transition worked well.
+
+Now git status reports a type change for the ~8000 files.
+
+But as soon as I run
+
+ git commit -m "typechange" even-only-one-of-the-files
+
+the process `git-annex pre-commit .` eats 3.5GB of ram, where I
+usually kill it, as I only have 4GB of ram....
+
+-- Andreas
diff --git a/doc/forum/git-annex_pre-commit_eats_all_my_4GB_of_ram/comment_1_ff16c7932b60b85c744bafc48bb040e4._comment b/doc/forum/git-annex_pre-commit_eats_all_my_4GB_of_ram/comment_1_ff16c7932b60b85c744bafc48bb040e4._comment
new file mode 100644
index 000000000..23e5e79e8
--- /dev/null
+++ b/doc/forum/git-annex_pre-commit_eats_all_my_4GB_of_ram/comment_1_ff16c7932b60b85c744bafc48bb040e4._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/FHnTlSBo1eCGJRwueeKeB6.RCaPbGMPr5jxx8A--#ce0d8"
+ nickname="Hamza"
+ subject="comment 1"
+ date="2013-09-18T07:19:49Z"
+ content="""
+AFAIK in direct mode you are not supposed to commit you just run
+
+ git annex sync
+
+and it will commit if files are changed. you only add new files annexed files are handled by sync
+
+"""]]
diff --git a/doc/forum/git-annex_pre-commit_eats_all_my_4GB_of_ram/comment_2_5599cddf579d18f70cab6e48d04ae99d._comment b/doc/forum/git-annex_pre-commit_eats_all_my_4GB_of_ram/comment_2_5599cddf579d18f70cab6e48d04ae99d._comment
new file mode 100644
index 000000000..337c1627f
--- /dev/null
+++ b/doc/forum/git-annex_pre-commit_eats_all_my_4GB_of_ram/comment_2_5599cddf579d18f70cab6e48d04ae99d._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="ringprince"
+ ip="134.76.140.110"
+ subject="comment 2"
+ date="2013-09-18T12:27:38Z"
+ content="""
+Hi Hamza,
+
+thanks for that comment. I thought `git annex sync` is just a wrapper around `git commit -a` (among others).
+
+Using `git annex sync` does not help, as it just means that now `git annex sync` eats all my memory until swapping starts.
+"""]]
diff --git a/doc/forum/git-annex_pre-commit_eats_all_my_4GB_of_ram/comment_3_412941e9385f63153b23695641e71deb._comment b/doc/forum/git-annex_pre-commit_eats_all_my_4GB_of_ram/comment_3_412941e9385f63153b23695641e71deb._comment
new file mode 100644
index 000000000..6349500ca
--- /dev/null
+++ b/doc/forum/git-annex_pre-commit_eats_all_my_4GB_of_ram/comment_3_412941e9385f63153b23695641e71deb._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.14.105"
+ subject="comment 3"
+ date="2013-09-19T18:49:05Z"
+ content="""
+git-annex sync is a wrapper around git commit. But not -a! git commit -a will stage every one of your large files directly into the git repository, wasting much memory and worse, disk space. It is ok to use `git commit` or `git commit --staged` in direct mode after eg `git annex add`. But not `git commit -a` or `git commit even-only-one-of-the-files`. It's best to just use `git annex sync` rather than `git commit`, as it avoids finger memory causing you to run the wrong type of commit command. Please see [[direct_mode]] for the details.
+
+I was able to make pre-commit take a lot of memory by committing a 1 gb file directly to git. git-annex was buffering the whole file content in memory
+due to not thinking to check first if it was a symlink. I have fixed that bug.
+
+So I think you must have run that command you showed, and you now have a lot of data stored in your git repository that you had meant git-annex to handle. You might need to use git-filter-branch to remove it..
+
+This kind of thing is why I need to write the [[todo/direct_mode_guard]].
+"""]]
diff --git a/doc/forum/git-annex_pre-commit_eats_all_my_4GB_of_ram/comment_4_112ad140d9006c530db2121bec24de30._comment b/doc/forum/git-annex_pre-commit_eats_all_my_4GB_of_ram/comment_4_112ad140d9006c530db2121bec24de30._comment
new file mode 100644
index 000000000..e5ebfa328
--- /dev/null
+++ b/doc/forum/git-annex_pre-commit_eats_all_my_4GB_of_ram/comment_4_112ad140d9006c530db2121bec24de30._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="ringprince"
+ ip="134.76.140.110"
+ subject="comment 4"
+ date="2013-09-19T20:06:39Z"
+ content="""
+Let me ask a simple question: All files are regular files (no symlinks). If I can live with loosing the history, is it save to just remove the .git directory and start over? Or do I risk anything?
+
+PS: .git is about 7GB
+"""]]
diff --git a/doc/forum/git-annex_pre-commit_eats_all_my_4GB_of_ram/comment_5_9178023b95683a649355f291165a1467._comment b/doc/forum/git-annex_pre-commit_eats_all_my_4GB_of_ram/comment_5_9178023b95683a649355f291165a1467._comment
new file mode 100644
index 000000000..7f5047ddd
--- /dev/null
+++ b/doc/forum/git-annex_pre-commit_eats_all_my_4GB_of_ram/comment_5_9178023b95683a649355f291165a1467._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.14.105"
+ subject="comment 5"
+ date="2013-09-19T20:57:18Z"
+ content="""
+You can safely delete the git repository in the situation you describe. Better yet: Tar it up, and check the tarball into git-annex with the other files when you start over. :) Then if I'm wrong, you still have that data.
+"""]]
diff --git a/doc/forum/git-annex_pre-commit_eats_all_my_4GB_of_ram/comment_6_9251203421c1c3c3aed7828c4b97ecb8._comment b/doc/forum/git-annex_pre-commit_eats_all_my_4GB_of_ram/comment_6_9251203421c1c3c3aed7828c4b97ecb8._comment
new file mode 100644
index 000000000..ebb378e95
--- /dev/null
+++ b/doc/forum/git-annex_pre-commit_eats_all_my_4GB_of_ram/comment_6_9251203421c1c3c3aed7828c4b97ecb8._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="ringprince"
+ ip="134.76.140.110"
+ subject="comment 6"
+ date="2013-09-19T22:27:38Z"
+ content="""
+Thanks a bunch! That is what I did now. Seems good.
+
+May I additionally suggest a change in the man page of git annex? There I read
+
+ sync [remote ...]
+ ...
+ The sync process involves first committing all local changes (git commit -a), ...
+ ...
+
+which made me think, I could do `git commit -a` manually as well.
+"""]]
diff --git a/doc/forum/git-annex_teams___47___groups.mdwn b/doc/forum/git-annex_teams___47___groups.mdwn
new file mode 100644
index 000000000..b499f3a6e
--- /dev/null
+++ b/doc/forum/git-annex_teams___47___groups.mdwn
@@ -0,0 +1,5 @@
+Hi,
+
+Does git-annex (preferably assistant) have any management of users / groups or teams? Our use case is we have many users which should only have access to certain folders (repos). Is this a planned feature or any manual way to work around this for now?
+
+Thanks!
diff --git a/doc/forum/git-annex_teams___47___groups/comment_1_0450673ab74f184a47ac7bab568d26dc._comment b/doc/forum/git-annex_teams___47___groups/comment_1_0450673ab74f184a47ac7bab568d26dc._comment
new file mode 100644
index 000000000..4b77da8f5
--- /dev/null
+++ b/doc/forum/git-annex_teams___47___groups/comment_1_0450673ab74f184a47ac7bab568d26dc._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.193"
+ subject="comment 1"
+ date="2013-06-25T17:10:17Z"
+ content="""
+Anyone with access to a git repository can access all the files stored in it. git-annex does not try to change this, so you need to find a way to have one repository for each group.
+"""]]
diff --git a/doc/forum/git-annex_unused_not_dropping_deleted_files.mdwn b/doc/forum/git-annex_unused_not_dropping_deleted_files.mdwn
new file mode 100644
index 000000000..1669461bc
--- /dev/null
+++ b/doc/forum/git-annex_unused_not_dropping_deleted_files.mdwn
@@ -0,0 +1,34 @@
+I've been organizing my music collection deleted/replaces some files but git-annex unused does not show any unused files even though they are deleted and all repos are in sync.
+
+
+ git log --stat --all -S'SHA256E-s8034842--5c3475d7fef6f0c3545721f34e7cbfb6727a00708bdde192f0f1d53af251b444'
+ commit a0fecdc02f7564f8bce9726f6b934fefc11de58b
+ Date: Thu Sep 12 17:04:53 2013 +0300
+
+ Deleted
+
+ .../Dido - Sitting On the Roof of the World.mp3 | 1 -
+ 1 file changed, 1 deletion(-)
+
+ commit 7f216228fc0e6298f0290ee1d8646bc9b16eca10
+ Date: Mon Aug 5 03:49:55 2013 +0200
+
+ Initial Import
+
+ .../Dido - Sitting On the Roof of the World.mp3 | 1 +
+ 1 file changed, 1 insertion(+)`
+
+even though the file is deleted its still present in annex objects,
+
+ find .git -name '*5c3475d7fef6f0c3545721f34e7cbfb6727a00708bdde192f0f1d53af251b444*' -exec ls -al '{}' \;
+ total 7856
+ dr-xr-xr-x 2 user user 4096 Sep 9 01:24 .
+ drwxrwxr-x 3 user user 4096 Sep 9 01:24 ..
+ -r--r--r-- 1 user user 8034842 Aug 5 04:52 SHA256E-s8034842--5c3475d7fef6f0c3545721f34e7cbfb6727a00708bdde192f0f1d53af251b444.mp3
+ -r--r--r-- 1 user user 8034842 Aug 5 04:52 .git/annex/objects/Jz/74/SHA256E-s8034842--5c3475d7fef6f0c3545721f34e7cbfb6727a00708bdde192f0f1d53af251b444.mp3/SHA256E-s8034842--5c3475d7fef6f0c3545721f34e7cbfb6727a00708bdde192f0f1d53af251b444.mp3
+
+I got around 200 files that should be deleted but not showing up in unused. I though maybe one of the dead repos is causing the problem so i did a,
+
+ git annex forget --drop-dead
+
+and synced all repos. Still I can not get them to drop.
diff --git a/doc/forum/git-annex_unused_not_dropping_deleted_files/comment_1_2152cfb09675e46e7492e198dd3ea094._comment b/doc/forum/git-annex_unused_not_dropping_deleted_files/comment_1_2152cfb09675e46e7492e198dd3ea094._comment
new file mode 100644
index 000000000..72ed0bbe1
--- /dev/null
+++ b/doc/forum/git-annex_unused_not_dropping_deleted_files/comment_1_2152cfb09675e46e7492e198dd3ea094._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.2.134"
+ subject="comment 1"
+ date="2013-09-13T15:34:03Z"
+ content="""
+The most likely explanation is that you have a branch in git that still contains the deleted file, which will prevent unused from removing it. Try `git branch -a` to see all branches (a tag could also do it).
+"""]]
diff --git a/doc/forum/git-annex_unused_not_dropping_deleted_files/comment_2_97e666dbac9de2a5e688921cba8a42e9._comment b/doc/forum/git-annex_unused_not_dropping_deleted_files/comment_2_97e666dbac9de2a5e688921cba8a42e9._comment
new file mode 100644
index 000000000..134106482
--- /dev/null
+++ b/doc/forum/git-annex_unused_not_dropping_deleted_files/comment_2_97e666dbac9de2a5e688921cba8a42e9._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/FHnTlSBo1eCGJRwueeKeB6.RCaPbGMPr5jxx8A--#ce0d8"
+ nickname="Hamza"
+ subject="comment 2"
+ date="2013-09-13T15:59:29Z"
+ content="""
+I did not create tags or branches, running returns,
+
+ git branch -a
+
+ git-annex
+ * master
+ synced/git-annex
+ synced/master
+ remotes/origin/HEAD -> origin/master
+ remotes/origin/git-annex
+ remotes/origin/master
+ remotes/origin/synced/master
+
+"""]]
diff --git a/doc/forum/git-annex_unused_not_dropping_deleted_files/comment_3_d7b0e9515bface28f3650b8aa20ec2f4._comment b/doc/forum/git-annex_unused_not_dropping_deleted_files/comment_3_d7b0e9515bface28f3650b8aa20ec2f4._comment
new file mode 100644
index 000000000..666172b28
--- /dev/null
+++ b/doc/forum/git-annex_unused_not_dropping_deleted_files/comment_3_d7b0e9515bface28f3650b8aa20ec2f4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.2.134"
+ subject="comment 3"
+ date="2013-09-13T16:17:39Z"
+ content="""
+Depending on your git configuration, `git annex sync` might not be updating certian of these branches, such as remotes/origin/HEAD. You can check the branches out and see which still contains your deleted files.
+"""]]
diff --git a/doc/forum/git-annex_unused_not_dropping_deleted_files/comment_4_5816f6cab42e27e724e735368f693b09._comment b/doc/forum/git-annex_unused_not_dropping_deleted_files/comment_4_5816f6cab42e27e724e735368f693b09._comment
new file mode 100644
index 000000000..e1a503d23
--- /dev/null
+++ b/doc/forum/git-annex_unused_not_dropping_deleted_files/comment_4_5816f6cab42e27e724e735368f693b09._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/FHnTlSBo1eCGJRwueeKeB6.RCaPbGMPr5jxx8A--#ce0d8"
+ nickname="Hamza"
+ subject="comment 4"
+ date="2013-09-13T17:57:38Z"
+ content="""
+Which one of those branches I can safely delete? this is a central repo all other clients drop their stuff here it does not have any remotes (I did clones it from a client then removed origin section from config.)
+"""]]
diff --git a/doc/forum/git-annex_unused_not_dropping_deleted_files/comment_5_8e97f39225515f0bf8b168dfd6a0efab._comment b/doc/forum/git-annex_unused_not_dropping_deleted_files/comment_5_8e97f39225515f0bf8b168dfd6a0efab._comment
new file mode 100644
index 000000000..1da1f80db
--- /dev/null
+++ b/doc/forum/git-annex_unused_not_dropping_deleted_files/comment_5_8e97f39225515f0bf8b168dfd6a0efab._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.2.134"
+ subject="comment 5"
+ date="2013-09-13T18:23:02Z"
+ content="""
+So this is a bare repository?
+
+It seems to have had an origin at one point; see the remotes/origin/* branches. If it no longer has that remote, then of course those branches will not be getting updated, and so will contain the old files and that's why unused won't find them. In that case, you could safely remove the remotes/origin/* branches.
+"""]]
diff --git a/doc/forum/git-annex_unused_not_dropping_deleted_files/comment_6_bef37f8ec9c337387b79ffd6d56fe425._comment b/doc/forum/git-annex_unused_not_dropping_deleted_files/comment_6_bef37f8ec9c337387b79ffd6d56fe425._comment
new file mode 100644
index 000000000..fe1c94eca
--- /dev/null
+++ b/doc/forum/git-annex_unused_not_dropping_deleted_files/comment_6_bef37f8ec9c337387b79ffd6d56fe425._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/FHnTlSBo1eCGJRwueeKeB6.RCaPbGMPr5jxx8A--#ce0d8"
+ nickname="Hamza"
+ subject="comment 6"
+ date="2013-09-13T18:41:30Z"
+ content="""
+It is a non bare repo, I am using the following setup,
+
+http://git-annex.branchable.com/forum/Annex_dropping_files/
+"""]]
diff --git a/doc/forum/git-assistant_clarification.mdwn b/doc/forum/git-assistant_clarification.mdwn
new file mode 100644
index 000000000..472f96c6a
--- /dev/null
+++ b/doc/forum/git-assistant_clarification.mdwn
@@ -0,0 +1,11 @@
+I've noticed that if I'm using git-assistant, it wants to pull down all my files from other repos onto my laptop, even after I've dropped them. (My laptop is set up as "client," my usb drive and an ssh server as "backup".)
+
+I want to use git annex to save space on my laptop, but of course when I'm running the assistant, it pulls everything down there, even things I've manually dropped.
+
+Is my "I want to save space, with a partial archive on my laptop" use case simply out of scope for the assistant? So I should just be using the command line for my needs? That's fine if that's the case.
+
+Or maybe something like this is what I should be doing? http://git-annex.branchable.com/assistant/archival_walkthrough/ ? so instead of manually "git annex drop"-ping files in place, I should set up a directory called "archive" on my machine, from which files will magically disappear and get backed up elsewhere?
+
+If it's the case that a directory named "archive" in your checkout has the magical property of having the assistant drop and archive its contents, that's awesome, maybe just what I need, but if that behavior is spelled out in so many words anywhere I managed to miss it.
+
+Apologies for all these questions, just enjoying the software immensely and wanting to get to know it.
diff --git a/doc/forum/git-assistant_clarification/comment_1_8f553e59da12f798b854a457b96b5778._comment b/doc/forum/git-assistant_clarification/comment_1_8f553e59da12f798b854a457b96b5778._comment
new file mode 100644
index 000000000..03f9dc273
--- /dev/null
+++ b/doc/forum/git-assistant_clarification/comment_1_8f553e59da12f798b854a457b96b5778._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn7gQ1zZDdWhXy9H51W2krZYShNmKL3qfM"
+ nickname="Karsten"
+ subject="comment 1"
+ date="2012-11-30T08:26:24Z"
+ content="""
+I'm second this request. Also, I'm posting this to enable the rss comment subscription button for this post.
+
+Maybe these design documents are interesting:
+
+<http://git-annex.branchable.com/design/assistant/transfer_control/>
+
+<http://git-annex.branchable.com/design/assistant/partial_content/>
+"""]]
diff --git a/doc/forum/git-assistant_clarification/comment_2_06cf62b599edea6ad8396776f0081494._comment b/doc/forum/git-assistant_clarification/comment_2_06cf62b599edea6ad8396776f0081494._comment
new file mode 100644
index 000000000..90137e722
--- /dev/null
+++ b/doc/forum/git-assistant_clarification/comment_2_06cf62b599edea6ad8396776f0081494._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.49"
+ subject="comment 2"
+ date="2012-11-30T16:31:21Z"
+ content="""
+The archive directory is a new feature, but yes, it does work. Just use the webapp to edit the configuration of a remote, put it into the \"small archive\" group, and the contents of archive directories will be sent to it.
+
+This is a particular application of [[preferred_content]] settings, which give you a large amount of control over which data end up where when using the assistant.
+"""]]
diff --git a/doc/forum/git-assistant_clarification/comment_3_36f0bd6e7a824e6ef40a309850bb087b._comment b/doc/forum/git-assistant_clarification/comment_3_36f0bd6e7a824e6ef40a309850bb087b._comment
new file mode 100644
index 000000000..1cf51c296
--- /dev/null
+++ b/doc/forum/git-assistant_clarification/comment_3_36f0bd6e7a824e6ef40a309850bb087b._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 3"
+ date="2012-11-30T18:49:37Z"
+ content="""
+Very cool!
+
+So not only is archive/ a magic subdirectory due to the \"preferred content settings\" for \"client,\" but *every* subdirectory named \"archive\" similarly drops content when possible. That's awesome to know.
+
+Also if I really wanted to manually manage all my content and still have git-annex assistant running, I could simply use \"present\" for my preferred content settings on my laptop, and it would respect my manual gets and drops.
+
+Thank you!
+
+"""]]
diff --git a/doc/forum/git-remote-gcrypt.mdwn b/doc/forum/git-remote-gcrypt.mdwn
new file mode 100644
index 000000000..eaf5889e7
--- /dev/null
+++ b/doc/forum/git-remote-gcrypt.mdwn
@@ -0,0 +1 @@
+Back in January Joey [mentioned](http://git-annex.branchable.com/design/assistant/blog/day_179__brief_updates/) the [git-remote-gcrypt](https://github.com/blake2-ppc/git-remote-gcrypt) and possibly adding support for it in the Assistant. I think this would be a great addition. Now that the first big Android push is complete, is there a schedule for this feature?
diff --git a/doc/forum/git-remote-gcrypt/comment_1_175c8c35d9bbb470fcc17697eb8cc6b8._comment b/doc/forum/git-remote-gcrypt/comment_1_175c8c35d9bbb470fcc17697eb8cc6b8._comment
new file mode 100644
index 000000000..ca38da4cd
--- /dev/null
+++ b/doc/forum/git-remote-gcrypt/comment_1_175c8c35d9bbb470fcc17697eb8cc6b8._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-03-07T18:42:37Z"
+ content="""
+I have not put it on the schedule (and don't think I'll get to it this month), but I have added it to the [[roadmap|design/assistant]].
+
+The main use cases it adds are encrypting git remotes on ssh servers, and on USB drives. Both are useful for sure..
+
+It also opens the possibility of using github for encrypted git remotes, but with xmpp git push that is not a pressing use case. With significantly more work, encrypted git remotes could be stored on S3 etc, but again xmpp git push covers the same use cases.
+"""]]
diff --git a/doc/forum/git-remote-gcrypt/comment_2_fdcaf507e14c995636dd93a41e488df3._comment b/doc/forum/git-remote-gcrypt/comment_2_fdcaf507e14c995636dd93a41e488df3._comment
new file mode 100644
index 000000000..a20fc7e76
--- /dev/null
+++ b/doc/forum/git-remote-gcrypt/comment_2_fdcaf507e14c995636dd93a41e488df3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="spwhitton"
+ ip="82.36.235.9"
+ subject="comment 2"
+ date="2013-03-12T09:33:17Z"
+ content="""
+The use case this is really good for, that XMPP push can't help with, is for when two paired machines are almost never both turned on at once.
+"""]]
diff --git a/doc/forum/git-remote-gcrypt/comment_3_f4e830f961dbe1c60ddd277b9d888133._comment b/doc/forum/git-remote-gcrypt/comment_3_f4e830f961dbe1c60ddd277b9d888133._comment
new file mode 100644
index 000000000..03ac7b0f5
--- /dev/null
+++ b/doc/forum/git-remote-gcrypt/comment_3_f4e830f961dbe1c60ddd277b9d888133._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="annexuser"
+ ip="50.125.45.235"
+ subject="comment 3"
+ date="2013-05-25T22:58:16Z"
+ content="""
+I'm still hoping to see this. The feature received some attention on the [April poll](http://git-annex.branchable.com/design/assistant/polls/goals_for_April/).
+"""]]
diff --git a/doc/forum/git-status_typechange_in_direct_mode.mdwn b/doc/forum/git-status_typechange_in_direct_mode.mdwn
new file mode 100644
index 000000000..6438fb890
--- /dev/null
+++ b/doc/forum/git-status_typechange_in_direct_mode.mdwn
@@ -0,0 +1,48 @@
+Hi all,
+
+how can I get rid of all those 'typechange' messages in `git status`
+when in direct mode?
+
+Here is an example session:
+
+ > git init
+ Initialized empty Git repository in /some/path/.git/
+ > git config user.name dtrn
+ > git config user.email drn@drn.com
+ > git annex init
+ init ok
+ (Recording state in git...)
+ > git annex direct
+ commit
+ # On branch master
+ #
+ # Initial commit
+ #
+ nothing to commit (create/copy files and use "git add" to track)
+ ok
+ direct ok
+ > dd if=/dev/zero of=testfile.bin count=1000
+ 1000+0 records in
+ 1000+0 records out
+ 512000 bytes (512 kB) copied, 0.00317424 s, 161 MB/s
+ > git annex add testfile.bin
+ add testfile.bin (checksum...) ok
+ (Recording state in git...)
+ > git commit -m "annexed testfile.bin"
+ ok
+ [master (root-commit) 281e740] annexed testfile.bin
+ 1 file changed, 1 insertion(+)
+ create mode 120000 testfile.bin
+ > git status
+ # On branch master
+ # Changes not staged for commit:
+ # (use "git add <file>..." to update what will be committed)
+ # (use "git checkout -- <file>..." to discard changes in working directory)
+ #
+ # typechange: testfile.bin
+ #
+ no changes added to commit (use "git add" and/or "git commit -a")
+
+
+Regards,
+Andreas
diff --git a/doc/forum/git-status_typechange_in_direct_mode/comment_1_12c8b67aadbfa2b073e12997a55d49a7._comment b/doc/forum/git-status_typechange_in_direct_mode/comment_1_12c8b67aadbfa2b073e12997a55d49a7._comment
new file mode 100644
index 000000000..31e476087
--- /dev/null
+++ b/doc/forum/git-status_typechange_in_direct_mode/comment_1_12c8b67aadbfa2b073e12997a55d49a7._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4830:1600:187::2"
+ subject="comment 1"
+ date="2013-09-20T15:24:25Z"
+ content="""
+These messages are normal in direct mode.
+
+They happen because git status does not know about git-annex's direct mode. So it sees a file that has a symlink checked into git, but a normal file in place in the working tree. Thus, its type has changed. Short of hacking or wrapping git, or switching to indirect mode ;), there's not much that can be done about this.
+
+You might want to read [[direct_mode]] for more about this, and some of the problems it can cause when running certian git commands.
+"""]]
diff --git a/doc/forum/git-status_typechange_in_direct_mode/comment_2_005d1b17f3c2ae192aa30c6e5163989e._comment b/doc/forum/git-status_typechange_in_direct_mode/comment_2_005d1b17f3c2ae192aa30c6e5163989e._comment
new file mode 100644
index 000000000..c598b212f
--- /dev/null
+++ b/doc/forum/git-status_typechange_in_direct_mode/comment_2_005d1b17f3c2ae192aa30c6e5163989e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="ringprince"
+ ip="134.76.140.110"
+ subject="comment 2"
+ date="2013-09-20T20:16:47Z"
+ content="""
+Thanks for the info and the quick reply.
+"""]]
diff --git a/doc/forum/git-subtree_support__63__.mdwn b/doc/forum/git-subtree_support__63__.mdwn
new file mode 100644
index 000000000..a95277a23
--- /dev/null
+++ b/doc/forum/git-subtree_support__63__.mdwn
@@ -0,0 +1,9 @@
+Hi,
+
+I am a happy user of [git-subtree](http://github.com/apenwarr/git-subtree), and I wonder whether it integrates nicely with git-annex?
+
+My use-case looks like this: I have two annex repositories -- one at home and one at work. The annex at work is a strict subset of the one at home, i.e. all files that I have at work ought to be part of the annex at home, but not the other way round. Now, I realize that I could have one annex and selectively copy files to the checked out copy at work, but I don't want to do that because I don't want to have (broken) symlinks for all kinds of stuff visible on my machine at work that is not supposed to be there (such as MP3 files, etc.). Instead, I would like to use git-subtree to import the work annex into a sub-directory of the one at home, so that both annex are logically separate, but still the one at home always contains everything that the one at work contains.
+
+Is that possible?
+
+And if not, is there maybe another way to accomplish this kind of thing?
diff --git a/doc/forum/git-subtree_support__63__/comment_1_4f333cb71ed1ff259bbfd86704806aa6._comment b/doc/forum/git-subtree_support__63__/comment_1_4f333cb71ed1ff259bbfd86704806aa6._comment
new file mode 100644
index 000000000..e4ded4c57
--- /dev/null
+++ b/doc/forum/git-subtree_support__63__/comment_1_4f333cb71ed1ff259bbfd86704806aa6._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2012-01-03T17:00:53Z"
+ content="""
+I have no experience using git-subtree, but as long as the home repository has the work one as a git remote, it will automatically merge work's git-annex branch with its own git-annex branch, and so will know what files are present at work, and will be able to get them.
+
+Probably you won't want to make work have home as a remote, so work's git-annex will not know which files home has, nor will it be able to copy files to home (but home will be able to copy files to work).
+"""]]
diff --git a/doc/forum/git-subtree_support__63__/comment_2_73d2a015b1ac79ec99e071a8b1e29034._comment b/doc/forum/git-subtree_support__63__/comment_2_73d2a015b1ac79ec99e071a8b1e29034._comment
new file mode 100644
index 000000000..9bac6e997
--- /dev/null
+++ b/doc/forum/git-subtree_support__63__/comment_2_73d2a015b1ac79ec99e071a8b1e29034._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://peter-simons.myopenid.com/"
+ ip="77.188.44.113"
+ subject="comment 2"
+ date="2012-01-03T18:11:37Z"
+ content="""
+The point of git-subtree is that I can import another repository into sub-directory, i.e. I can have a directory called \"work\" that contains all files from the annex I have at work. If I make the other annex a remote and merge its contents, then all contents is going to be merged at the top-level, which is somewhat undesirable in my particular case.
+"""]]
diff --git a/doc/forum/git-subtree_support__63__/comment_3_c533400e22c306c033fcd56e64761b0b._comment b/doc/forum/git-subtree_support__63__/comment_3_c533400e22c306c033fcd56e64761b0b._comment
new file mode 100644
index 000000000..83edaf743
--- /dev/null
+++ b/doc/forum/git-subtree_support__63__/comment_3_c533400e22c306c033fcd56e64761b0b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 3"
+ date="2012-01-03T18:42:08Z"
+ content="""
+You can make it a remote without merging its contents. Git will not merge its contents by default unless it's named \"origin\". git-annex will be prefectly happy with that.
+"""]]
diff --git a/doc/forum/git-subtree_support__63__/comment_4_75b0e072e668aa46ff0a8d62a6620306._comment b/doc/forum/git-subtree_support__63__/comment_4_75b0e072e668aa46ff0a8d62a6620306._comment
new file mode 100644
index 000000000..642f952e4
--- /dev/null
+++ b/doc/forum/git-subtree_support__63__/comment_4_75b0e072e668aa46ff0a8d62a6620306._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://peter-simons.myopenid.com/"
+ ip="77.188.44.113"
+ subject="comment 4"
+ date="2012-01-03T19:17:36Z"
+ content="""
+Okay, I see, but is `git annex get --auto .` going to import all those files from the work remote into my home if the `master` branch of that remote isn't merged?
+"""]]
diff --git a/doc/forum/git-subtree_support__63__/comment_5_f5ec9649d9f1dc122e715de5533bc674._comment b/doc/forum/git-subtree_support__63__/comment_5_f5ec9649d9f1dc122e715de5533bc674._comment
new file mode 100644
index 000000000..5b2f3dad5
--- /dev/null
+++ b/doc/forum/git-subtree_support__63__/comment_5_f5ec9649d9f1dc122e715de5533bc674._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 5"
+ date="2012-01-03T19:31:45Z"
+ content="""
+Yes; git-annex uses the git-annex branch independently of the branch you have checked out. You may find [[internals]] interesting reading, but the short answer is it will work.
+"""]]
diff --git a/doc/forum/git-subtree_support__63__/comment_6_85df530f7b6d76b74ac8017c6034f95e._comment b/doc/forum/git-subtree_support__63__/comment_6_85df530f7b6d76b74ac8017c6034f95e._comment
new file mode 100644
index 000000000..77af85258
--- /dev/null
+++ b/doc/forum/git-subtree_support__63__/comment_6_85df530f7b6d76b74ac8017c6034f95e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://peter-simons.myopenid.com/"
+ ip="77.188.44.113"
+ subject="comment 6"
+ date="2012-01-03T19:47:11Z"
+ content="""
+Very cool! Thank you for the explanation.
+"""]]
diff --git a/doc/forum/git_annex_add_crash_and_subsequent_recovery.mdwn b/doc/forum/git_annex_add_crash_and_subsequent_recovery.mdwn
new file mode 100644
index 000000000..3f3b943a0
--- /dev/null
+++ b/doc/forum/git_annex_add_crash_and_subsequent_recovery.mdwn
@@ -0,0 +1,25 @@
+Perhaps stupidly I added some very large bare git repos into a git-annex.
+
+This took a very long time, used lot's of memory, and then crashed. I didn't catch the error (which is annoying) - sorry about that. IIRC it is the same error if one Ctrl-c's the addition.
+
+I ran `git annex add .` a second time and eventually killed it (I perhaps should have waited - I now think it was working).
+
+A `git annex unannex` fixed up some files but somehow I managed to end up with tonnes of files all sym-linked into the git annex object directory but not somehow recognised as annexed files. I'm assuming that they somehow didn't make it into git annex's meta-data layer (or equivalent).
+
+Commands such as `git annex {fsck,whereis,unannex} weirdfile` immediately returned without error.
+
+I've now spent a lot of manual time copying the files back. Doing the following, not the cleverest but I was a little panicky about my data...
+
+ find . -type l -exec mv \{} \{}.link \; #Move link names out of the way
+ find . -type l -exec cp \{} \{}.cp \; #Copy follows links so we can copy target back to link location
+ find . -type f -name "*.link.cp" | xargs -n 1 rename 's/\.link\.cp//' #Change to original name
+ find . -type l -exec rm \{} \; #Ditch the links
+ git annex unused
+ git annex dropunused `seq 9228`
+
+9228 files were found to be unused, this gives an idea of the scale of the number of "lost" files for want of a better term.
+
+A pretty poor bug report as these things go. Anyone any idea what might have happened (it didn't seem space or memory related)? Or how I might have fixed it a little more cleverly?
+
+For reference I am using stable Debian, git annex version 3.20111011.
+
diff --git a/doc/forum/git_annex_add_crash_and_subsequent_recovery/comment_1_062d0153a379c1ba1df8585b90220d3d._comment b/doc/forum/git_annex_add_crash_and_subsequent_recovery/comment_1_062d0153a379c1ba1df8585b90220d3d._comment
new file mode 100644
index 000000000..e879441ff
--- /dev/null
+++ b/doc/forum/git_annex_add_crash_and_subsequent_recovery/comment_1_062d0153a379c1ba1df8585b90220d3d._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnXybLxkPMYpP3yw4b_I6IdC3cKTD-xEdU"
+ nickname="Matt"
+ subject="comment 1"
+ date="2011-12-06T12:50:27Z"
+ content="""
+Ah HA! Looks like I found the cause of this.
+
+ [matt@rss01:~/files/matt_ford]0> git annex add mhs
+ add mhs/Accessing_Web_Manager_V10.pdf ok
+ ....
+ add mhs/MAHSC Costing Request Form Dual
+ Organisations - FINAL v20 Oct 2010.xls git-annex: unknown response from git cat-file refs/heads/git-annex:8d5/ed4/WORM-s568832-m1323164214--MAHSC Costing Request Form Dual missing
+
+Spot the file name with a newline character in it! This causes the error message above. It seems that the files proceeding this badly named file are sym-linked but not registered.
+
+Perhaps a bug?
+"""]]
diff --git a/doc/forum/git_annex_add_crash_and_subsequent_recovery/comment_2_6fc6be43c488c468a4811cd0a1360225._comment b/doc/forum/git_annex_add_crash_and_subsequent_recovery/comment_2_6fc6be43c488c468a4811cd0a1360225._comment
new file mode 100644
index 000000000..38f2434f4
--- /dev/null
+++ b/doc/forum/git_annex_add_crash_and_subsequent_recovery/comment_2_6fc6be43c488c468a4811cd0a1360225._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 2"
+ date="2011-12-06T17:08:37Z"
+ content="""
+The bug with newlines is now fixed.
+
+Thought I'd mention how to clean up from interrupting `git annex add`.
+When you do that, it doesn't get a chance to `git add` the files it's
+added (this is normally done at the end, or sometimes at points in the middle when you're adding a *lot* of files).
+Which is also why fsck, whereis, and unannex wouldn't operate on them, since they only deal with files in git.
+
+So the first step is to manually use `git add` on any symlinks.
+
+Then, `git commit` as usual.
+
+At that point, `git annex unannex` would get you back to your starting state.
+"""]]
diff --git a/doc/forum/git_annex_add_crash_and_subsequent_recovery/comment_3_45efaaf27d9b580c4c75cbcdc4f65b64._comment b/doc/forum/git_annex_add_crash_and_subsequent_recovery/comment_3_45efaaf27d9b580c4c75cbcdc4f65b64._comment
new file mode 100644
index 000000000..b58f81c5b
--- /dev/null
+++ b/doc/forum/git_annex_add_crash_and_subsequent_recovery/comment_3_45efaaf27d9b580c4c75cbcdc4f65b64._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnXybLxkPMYpP3yw4b_I6IdC3cKTD-xEdU"
+ nickname="Matt"
+ subject="comment 3"
+ date="2011-12-07T07:39:15Z"
+ content="""
+Ah - very good to know that recovery is easier than the method I used.
+
+I wonder if it could be made a feature to automatically and safely recover/resume from an interrupted `git add`?
+"""]]
diff --git a/doc/forum/git_annex_add_crash_and_subsequent_recovery/comment_4_c560eae40867512b0af2cbef161fc8ac._comment b/doc/forum/git_annex_add_crash_and_subsequent_recovery/comment_4_c560eae40867512b0af2cbef161fc8ac._comment
new file mode 100644
index 000000000..8fca16cad
--- /dev/null
+++ b/doc/forum/git_annex_add_crash_and_subsequent_recovery/comment_4_c560eae40867512b0af2cbef161fc8ac._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 4"
+ date="2011-12-07T20:54:51Z"
+ content="""
+Good idea! I've made `git annex add` recover when ran a second time.
+"""]]
diff --git a/doc/forum/git_annex_alternative.mdwn b/doc/forum/git_annex_alternative.mdwn
new file mode 100644
index 000000000..d7c41e66d
--- /dev/null
+++ b/doc/forum/git_annex_alternative.mdwn
@@ -0,0 +1,10 @@
+I really like git-annex and am thankfull to its creator!
+
+I especially like the high level of abstraction it provides when handling backups or syncing.
+
+But git and my ext4 filesystem and HDD just hate the amount of files/folder/symlinks it throws at them and I am asking, what the alternatives are. I am especially looking for the numcopies and "--auto" functionallity.
+
+
+Most alternatives I checked out (eps. distributed redundant filesystems) come up with other burdens or restrictions.
+
+Do you have any experience with different systems?
diff --git a/doc/forum/git_annex_assistant__44___share_with_other_devices.mdwn b/doc/forum/git_annex_assistant__44___share_with_other_devices.mdwn
new file mode 100644
index 000000000..faebb14a1
--- /dev/null
+++ b/doc/forum/git_annex_assistant__44___share_with_other_devices.mdwn
@@ -0,0 +1,3 @@
+I am trying to share files between my PC at home at that at work using the walkthrough here: http://git-annex.branchable.com/assistant/remote_sharing_walkthrough/. However, I don't have the option on my machine to "Share with other devices". Any ideas why this would be missing? I am using Ubuntu 13.04 if that helps.
+
+Update: it now works after a software update, I guess I just had an older version of git-annex. Now, I have version 4.20130723.
diff --git a/doc/forum/git_annex_copy_--fast_--to_blah_much_slower_than_--from_blah.mdwn b/doc/forum/git_annex_copy_--fast_--to_blah_much_slower_than_--from_blah.mdwn
new file mode 100644
index 000000000..37b86c462
--- /dev/null
+++ b/doc/forum/git_annex_copy_--fast_--to_blah_much_slower_than_--from_blah.mdwn
@@ -0,0 +1,15 @@
+I keep a repo synced between machines over ssh. Assuming all the files are in sync, so no actual file transfer needs to takes place, when I do
+
+```
+git annex copy --fast --quiet --to blah
+```
+
+is quite slow, about 10 seconds, using 100% CPU on one core, just to decide nothing needs to be done. On the other hand, doing
+
+```
+ git annex copy --fast --quiet --from blah
+```
+
+takes about 1 second.
+
+I'm confused, as it seems to me that, since I'm using --fast, both transactions should use only locally available data, and both should need about the same amount of computing. Am I missing something? Can this be fixed?
diff --git a/doc/forum/git_annex_copy_--fast_--to_blah_much_slower_than_--from_blah/comment_1_5b6e0b749b01a97a6b52a2c1cca6e35a._comment b/doc/forum/git_annex_copy_--fast_--to_blah_much_slower_than_--from_blah/comment_1_5b6e0b749b01a97a6b52a2c1cca6e35a._comment
new file mode 100644
index 000000000..90d429278
--- /dev/null
+++ b/doc/forum/git_annex_copy_--fast_--to_blah_much_slower_than_--from_blah/comment_1_5b6e0b749b01a97a6b52a2c1cca6e35a._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.90"
+ subject="comment 1"
+ date="2013-07-17T19:11:38Z"
+ content="""
+How many files are in the directory tree you're copying?
+
+`copy --fast --to` does indeed avoid the check to see if the remote already has the file before copying it.
+
+However, it still needs to look in the location log to see which files are already present on the remote. Whereas `copy --from` can do a single stat of the file on disk to see if it's present in the local repo. Location log lookups are about as fast as I can make them, but they still require requesting info from out of the git repository. If you have a lot of files this otherwise minor difference in speed can stack up..
+"""]]
diff --git a/doc/forum/git_annex_copy_--fast_--to_blah_much_slower_than_--from_blah/comment_2_8f2567f4c4f6db2078211a87689757d3._comment b/doc/forum/git_annex_copy_--fast_--to_blah_much_slower_than_--from_blah/comment_2_8f2567f4c4f6db2078211a87689757d3._comment
new file mode 100644
index 000000000..c0bfe9df2
--- /dev/null
+++ b/doc/forum/git_annex_copy_--fast_--to_blah_much_slower_than_--from_blah/comment_2_8f2567f4c4f6db2078211a87689757d3._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkkyBDsfOB7JZvPZ4a8F3rwv0wk6Nb9n48"
+ nickname="Abdó"
+ subject="comment 2"
+ date="2013-07-17T20:45:17Z"
+ content="""
+That example I gave: 10 sec vs 1 sec is on a repository of pictures with about 6200 files on a SSD.
+
+Oh, I think I understand the source of the asymmetry, now! So, `git annex copy --to` queries the location log file by file? I've tested a `git grep` on the git-annex branch as follows
+
+```
+git grep -e <repo uuid> git-annex
+```
+
+and seems to be quite fast, less than a second on my test repo. Could git annex make use of this to speed up bulk queries to the location log?
+
+"""]]
diff --git a/doc/forum/git_annex_copy_--fast_--to_blah_much_slower_than_--from_blah/comment_3_ab98121076b88f351fc8cd9197e6bf64._comment b/doc/forum/git_annex_copy_--fast_--to_blah_much_slower_than_--from_blah/comment_3_ab98121076b88f351fc8cd9197e6bf64._comment
new file mode 100644
index 000000000..d5f399b30
--- /dev/null
+++ b/doc/forum/git_annex_copy_--fast_--to_blah_much_slower_than_--from_blah/comment_3_ab98121076b88f351fc8cd9197e6bf64._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.140"
+ subject="comment 3"
+ date="2013-07-18T17:39:37Z"
+ content="""
+Using git grep like that would only be an optimisation when it's acting on every file in the repository. If it's only copying a subdirectory, or a single file, git grep is likely to come out much slower.
+"""]]
diff --git a/doc/forum/git_annex_copy_--fast_--to_blah_much_slower_than_--from_blah/comment_4_cb13328add1b7a812efd817ad3dd1a4f._comment b/doc/forum/git_annex_copy_--fast_--to_blah_much_slower_than_--from_blah/comment_4_cb13328add1b7a812efd817ad3dd1a4f._comment
new file mode 100644
index 000000000..0c70777a4
--- /dev/null
+++ b/doc/forum/git_annex_copy_--fast_--to_blah_much_slower_than_--from_blah/comment_4_cb13328add1b7a812efd817ad3dd1a4f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkkyBDsfOB7JZvPZ4a8F3rwv0wk6Nb9n48"
+ nickname="Abdó"
+ subject="comment 4"
+ date="2013-07-18T22:58:24Z"
+ content="""
+I see. Thanks!
+"""]]
diff --git a/doc/forum/git_annex_failing_to_get_non-English_filenames.__Rsync_problem__63__.mdwn b/doc/forum/git_annex_failing_to_get_non-English_filenames.__Rsync_problem__63__.mdwn
new file mode 100644
index 000000000..c9dcf2eda
--- /dev/null
+++ b/doc/forum/git_annex_failing_to_get_non-English_filenames.__Rsync_problem__63__.mdwn
@@ -0,0 +1,22 @@
+Whenever I try to get a file with a non-English character, git annex gives me trouble that I don't have with English filenames from the same repo. I'm hesitant to file a bug report here since the problem seems to stem from rsync not being able to handle the characters. Here's the output (everything enclosed in pointy brackets are redacted):
+
+ get <artist>/<album>/<track> (from origin...)
+ git-annex: /home/<username>/Music/.git/annex/transfer/upload/53e11324-041f-11e2-93ca-27250d76416f/SHA256-s7941079--c5a31f15302d57563d8cd35e43ba34669b5485a99b617a83c89fba02fb2ca981: commitBuffer: invalid argument (invalid character)
+ protocol version mismatch -- is your shell clean?
+ (see the rsync man page for an explanation)
+ rsync error: protocol incompatibility (code 2) at compat.c(174) [Receiver=3.0.9]
+
+ git-annex-shell: sendkey: 1 failed
+ rsync failed -- run git annex again to resume file transfer
+
+ Unable to access these remotes: origin
+
+ Try making some of these repositories available:
+ 604f093f-a980-4740-a9df-d21b580a2ba4 -- origin (<remote>)
+ failed
+
+
+
+It spits out similar errors for all files with Japanese/German/French/special characters, and ends with this on the last line:
+
+ git-annex: get: 138 failed
diff --git a/doc/forum/git_annex_failing_to_get_non-English_filenames.__Rsync_problem__63__/comment_1_292ee7c8b37cbd13f03eb67d0359b99e._comment b/doc/forum/git_annex_failing_to_get_non-English_filenames.__Rsync_problem__63__/comment_1_292ee7c8b37cbd13f03eb67d0359b99e._comment
new file mode 100644
index 000000000..3542dbd22
--- /dev/null
+++ b/doc/forum/git_annex_failing_to_get_non-English_filenames.__Rsync_problem__63__/comment_1_292ee7c8b37cbd13f03eb67d0359b99e._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="sauluskahn"
+ ip="67.171.218.222"
+ subject="comment 1"
+ date="2012-09-21T21:40:30Z"
+ content="""
+Also, git annex is 3.20120825 on both machines, and rsync is 3.0.9
+
+Both have no problem handling the characters on their own, but when I try to rsync them I get trouble.
+"""]]
diff --git a/doc/forum/git_annex_failing_to_get_non-English_filenames.__Rsync_problem__63__/comment_2_f6341119fcfde5d8160c8f603b1a6fea._comment b/doc/forum/git_annex_failing_to_get_non-English_filenames.__Rsync_problem__63__/comment_2_f6341119fcfde5d8160c8f603b1a6fea._comment
new file mode 100644
index 000000000..080dba0e9
--- /dev/null
+++ b/doc/forum/git_annex_failing_to_get_non-English_filenames.__Rsync_problem__63__/comment_2_f6341119fcfde5d8160c8f603b1a6fea._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.14.141"
+ subject="comment 2"
+ date="2012-09-21T23:23:04Z"
+ content="""
+git-annex 3.20120825 is not an actual release, just some version number used in git head.
+
+This bug, TTBOMK, was introduced in version 3.20120721, and fixed by git commit 0b12db64d834979d49ed378235b0c19b34e4a4d6 last Sunday.
+"""]]
diff --git a/doc/forum/git_annex_failing_to_get_non-English_filenames.__Rsync_problem__63__/comment_3_8ad3a1d1fe5995d61e5e137280bc76c3._comment b/doc/forum/git_annex_failing_to_get_non-English_filenames.__Rsync_problem__63__/comment_3_8ad3a1d1fe5995d61e5e137280bc76c3._comment
new file mode 100644
index 000000000..b61eff506
--- /dev/null
+++ b/doc/forum/git_annex_failing_to_get_non-English_filenames.__Rsync_problem__63__/comment_3_8ad3a1d1fe5995d61e5e137280bc76c3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.14.141"
+ subject="comment 3"
+ date="2012-09-21T23:23:52Z"
+ content="""
+I take that back about 3.20120825, it was so a real release! :) Anyway, bug is fixed in git head, and there will be a release along soon with it.
+"""]]
diff --git a/doc/forum/git_annex_failing_to_get_non-English_filenames.__Rsync_problem__63__/comment_4_86b61b0484f3f4ecff657e46333b3d4f._comment b/doc/forum/git_annex_failing_to_get_non-English_filenames.__Rsync_problem__63__/comment_4_86b61b0484f3f4ecff657e46333b3d4f._comment
new file mode 100644
index 000000000..678c13b7a
--- /dev/null
+++ b/doc/forum/git_annex_failing_to_get_non-English_filenames.__Rsync_problem__63__/comment_4_86b61b0484f3f4ecff657e46333b3d4f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="sauluskahn"
+ ip="67.171.218.222"
+ subject="comment 4"
+ date="2012-09-22T03:01:02Z"
+ content="""
+Sounds good, I'll get the next version through cabal and let you know if it's fixed. Thanks for your time!
+"""]]
diff --git a/doc/forum/git_annex_failing_to_get_non-English_filenames.__Rsync_problem__63__/comment_5_5ffac00d08d26acaba8c3513b24c4d65._comment b/doc/forum/git_annex_failing_to_get_non-English_filenames.__Rsync_problem__63__/comment_5_5ffac00d08d26acaba8c3513b24c4d65._comment
new file mode 100644
index 000000000..c328519d7
--- /dev/null
+++ b/doc/forum/git_annex_failing_to_get_non-English_filenames.__Rsync_problem__63__/comment_5_5ffac00d08d26acaba8c3513b24c4d65._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="sauluskahn"
+ ip="67.171.218.222"
+ subject="comment 5"
+ date="2012-09-22T03:02:15Z"
+ content="""
+>I'll let you know if it's *not* fixed.
+
+Typo.
+"""]]
diff --git a/doc/forum/git_annex_get_creates_a_new_uuid.mdwn b/doc/forum/git_annex_get_creates_a_new_uuid.mdwn
new file mode 100644
index 000000000..72dcd9737
--- /dev/null
+++ b/doc/forum/git_annex_get_creates_a_new_uuid.mdwn
@@ -0,0 +1,6 @@
+From git-annex(1), init should precede any operation of git-annex as a safety feature.
+
+However git cloning a repo and running `git annex get` created a new uuid for that repo, which got
+propagated via sync.
+
+Is this intended behaviour?
diff --git a/doc/forum/git_annex_get_creates_a_new_uuid/comment_1_004c87183968c326058bd3159a5baa0b._comment b/doc/forum/git_annex_get_creates_a_new_uuid/comment_1_004c87183968c326058bd3159a5baa0b._comment
new file mode 100644
index 000000000..3a07bf0af
--- /dev/null
+++ b/doc/forum/git_annex_get_creates_a_new_uuid/comment_1_004c87183968c326058bd3159a5baa0b._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.21"
+ subject="comment 1"
+ date="2013-07-30T20:24:06Z"
+ content="""
+From the man page:
+
+> Until a repository (**or one of its remotes**) has been initialized
+> git-annex will refuse to operate on it, to avoid accidentially
+> using it in a repository that was not intended tohave an annex.
+
+So, yes, it assumes that if a repository has a git-annex branch already, git-annex is being used, and no explicit init is necessary. You can still run `git annex init` after the fact if you like.
+"""]]
diff --git a/doc/forum/git_annex_ls___47___metadata_in_git_annex_whereis.mdwn b/doc/forum/git_annex_ls___47___metadata_in_git_annex_whereis.mdwn
new file mode 100644
index 000000000..f1aa5cc06
--- /dev/null
+++ b/doc/forum/git_annex_ls___47___metadata_in_git_annex_whereis.mdwn
@@ -0,0 +1 @@
+I just started experimenting with git annex, and I found that I would like to have a way to figure out metadata (well, size. Maybe modification date) of a non-local file. I first checked if there is "git annex ls" (which could list known files in an ls-like way) and found "git annex whereis" as somewhat a replacement, but it does not give metadata information.
diff --git a/doc/forum/git_annex_ls___47___metadata_in_git_annex_whereis/comment_1_7fba10b85f4d9289c7782eccef46949e._comment b/doc/forum/git_annex_ls___47___metadata_in_git_annex_whereis/comment_1_7fba10b85f4d9289c7782eccef46949e._comment
new file mode 100644
index 000000000..379b9f976
--- /dev/null
+++ b/doc/forum/git_annex_ls___47___metadata_in_git_annex_whereis/comment_1_7fba10b85f4d9289c7782eccef46949e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-11-14T22:46:35Z"
+ content="""
+When I want that, I ls -l the file and look at the symlink to the key. Ie, in SHA1-s10481423--efc7eec0d711212842cd6bb8f957e1628146d6ed the size is 10481423 bytes.
+"""]]
diff --git a/doc/forum/git_annex_ls___47___metadata_in_git_annex_whereis/comment_2_7dcec124ea7d0291ed40d80e2ffd5c7e._comment b/doc/forum/git_annex_ls___47___metadata_in_git_annex_whereis/comment_2_7dcec124ea7d0291ed40d80e2ffd5c7e._comment
new file mode 100644
index 000000000..3dd14bf01
--- /dev/null
+++ b/doc/forum/git_annex_ls___47___metadata_in_git_annex_whereis/comment_2_7dcec124ea7d0291ed40d80e2ffd5c7e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 2"
+ date="2011-11-14T22:48:03Z"
+ content="""
+It might make sense to put this functionality in git annex find. Perhaps a format string with a %s for example.
+"""]]
diff --git a/doc/forum/git_annex_sync_dies___40__sometimes__41__.mdwn b/doc/forum/git_annex_sync_dies___40__sometimes__41__.mdwn
new file mode 100644
index 000000000..84f9d1125
--- /dev/null
+++ b/doc/forum/git_annex_sync_dies___40__sometimes__41__.mdwn
@@ -0,0 +1,22 @@
+I've set up git annex on my laptop and on a remote server using the gitolite v3 git-annex branch.
+When I 'git annex sync' from my laptop (mac OSX) to the server, and 'git annex copy . --to server' all works fine.
+
+Later, I tried to clone the repository on another machine (linux 2.6.32). again all is well. I 'git annex init' in the new clone and then try to 'git annex sync' -- now I run into problems.
+
+Specifically, the first request for the configlist (when I do 'git annex --debug sync' all is fine until the configlist request) somehow breaks and my ssh session shows:
+
+muxserver_listen bind(): Input/output error
+
+This seems to confuse the client, who now believes that git annex is not installed on the server (it is).
+
+If I issue the same command as git annex via ssh, all seems to work ok with the caveats below:
+
+I have a feeling it's related to the -o 'ControlPersist=yes' argument that git-annex appears to be giving ssh. If I include this option when I run via ssh, ssh dies:
+
+>ssh git@server -o "ControlMaster=auto" -o "ControlPersist=yes" "git-annex-shell 'configlist' '/~/PRJ'"
+command-line: line 0: Bad configuration option: ControlPersist
+
+
+(note that it appears to be ok to leave "ControlMaster=auto" in).
+
+any thoughts?
diff --git a/doc/forum/git_annex_sync_dies___40__sometimes__41__/comment_1_48bbac0545bf13bbf04da723e418d037._comment b/doc/forum/git_annex_sync_dies___40__sometimes__41__/comment_1_48bbac0545bf13bbf04da723e418d037._comment
new file mode 100644
index 000000000..9445421a4
--- /dev/null
+++ b/doc/forum/git_annex_sync_dies___40__sometimes__41__/comment_1_48bbac0545bf13bbf04da723e418d037._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="64.134.31.139"
+ subject="comment 1"
+ date="2013-10-15T18:16:23Z"
+ content="""
+Since this seems to be a problem with ssh connection caching, you can disable that:
+
+git config annex.sshcaching false
+
+Seems like the problem would be in the version of ssh you have installed on your linux client. Or possibly some interaction between its version and the server's version.
+
+Since linux 2.6.32 is quite old, I'll bet you have an old ssh too.. what version?
+"""]]
diff --git a/doc/forum/git_annex_test_on_windows.mdwn b/doc/forum/git_annex_test_on_windows.mdwn
new file mode 100644
index 000000000..4e2f8dea6
--- /dev/null
+++ b/doc/forum/git_annex_test_on_windows.mdwn
@@ -0,0 +1,5 @@
+is it worth sharing back git annex test failures occourring on some windows setup ?
+i'm having 3 failures, what kind of report can i produce shall it be of any use ?
+is it enough a test log coming from git annex test > test.log 2>&1 ?
+thanks again
+
diff --git a/doc/forum/git_annex_test_on_windows/comment_1_258ac5cfa2f5d24e737d94dc48f06899._comment b/doc/forum/git_annex_test_on_windows/comment_1_258ac5cfa2f5d24e737d94dc48f06899._comment
new file mode 100644
index 000000000..d7968c16e
--- /dev/null
+++ b/doc/forum/git_annex_test_on_windows/comment_1_258ac5cfa2f5d24e737d94dc48f06899._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.246"
+ subject="comment 1"
+ date="2013-11-15T20:53:17Z"
+ content="""
+Yes, it's fine to file a bug about test failures. Be sure you try with a current autobuild.
+
+The redirection you show would work on linux, I don't know about windows. But capturing a transcript of the test output is certainly what I need.
+"""]]
diff --git a/doc/forum/git_pull_remote_git-annex.mdwn b/doc/forum/git_pull_remote_git-annex.mdwn
new file mode 100644
index 000000000..349610693
--- /dev/null
+++ b/doc/forum/git_pull_remote_git-annex.mdwn
@@ -0,0 +1,11 @@
+I thought I'd followed the walk through when initially setting up my repos.
+
+However I find that I have to do the following to sync my annex's.
+
+ git pull remote master
+ git checkout git-annex
+ git pull remote git-annex
+ git checkout master
+ git annex get .
+
+Has something gone wrong? I see no mention of syncing git-annex repos in the walk-through...
diff --git a/doc/forum/git_pull_remote_git-annex/comment_1_9c245db3518d8b889ecdf5115ad9e053._comment b/doc/forum/git_pull_remote_git-annex/comment_1_9c245db3518d8b889ecdf5115ad9e053._comment
new file mode 100644
index 000000000..989ab9bcd
--- /dev/null
+++ b/doc/forum/git_pull_remote_git-annex/comment_1_9c245db3518d8b889ecdf5115ad9e053._comment
@@ -0,0 +1,36 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-12-06T16:43:29Z"
+ content="""
+You're taking a very long and strange way to a place that you can reach as follows:
+
+<pre>
+git pull remote
+git annex get .
+</pre>
+
+Which is just as shown in [[walkthrough/getting_file_content]].
+
+In particular, \"git pull remote\" first fetches all branches from the remote, including the git-annex branch.
+When you say \"git pull remote master\", you're preventing it from fetching the git-annex branch.
+If for some reason you want the slightly longer way around, it is:
+
+<pre>
+git pull remote master
+git fetch remote git-annex
+git annex get .
+</pre>
+
+Or, eqivilantly but with less network connections:
+
+<pre>
+git fetch remote
+git merge remote/master
+git annex get .
+</pre>
+
+BTW, notice that this is all bog-standard git branch pulling stuff, not specific to git-annex in the least.
+Consult your extensive and friendly git documentation for details. :)
+"""]]
diff --git a/doc/forum/git_pull_remote_git-annex/comment_2_0f7f4a311b0ec1d89613e80847e69b42._comment b/doc/forum/git_pull_remote_git-annex/comment_2_0f7f4a311b0ec1d89613e80847e69b42._comment
new file mode 100644
index 000000000..198f95cee
--- /dev/null
+++ b/doc/forum/git_pull_remote_git-annex/comment_2_0f7f4a311b0ec1d89613e80847e69b42._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnXybLxkPMYpP3yw4b_I6IdC3cKTD-xEdU"
+ nickname="Matt"
+ subject="comment 2"
+ date="2011-12-06T23:23:29Z"
+ content="""
+Doh! Total brain melt on my part. Thanks for the additional info. Not taking my time and reading things properly - kept assuming that the full remote pull failed due to the warning:
+
+ You asked to pull from the remote 'rss', but did not specify
+ a branch. Because this is not the default configured remote
+ for your current branch, you must specify a branch on the command line.
+
+Rookie mistake indeed.
+"""]]
diff --git a/doc/forum/git_pull_remote_git-annex/comment_3_1aa89725b5196e40a16edeeb5ccfa371._comment b/doc/forum/git_pull_remote_git-annex/comment_3_1aa89725b5196e40a16edeeb5ccfa371._comment
new file mode 100644
index 000000000..0ead32dad
--- /dev/null
+++ b/doc/forum/git_pull_remote_git-annex/comment_3_1aa89725b5196e40a16edeeb5ccfa371._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnXybLxkPMYpP3yw4b_I6IdC3cKTD-xEdU"
+ nickname="Matt"
+ subject="comment 3"
+ date="2011-12-21T16:06:25Z"
+ content="""
+hmmmm - I'm still not sure I get this.
+
+If I'm using a whole bunch of distributed annexs with no central repo, then I can not do a `git pull remote` without either specifying the branch to use or changing default tracked remote via `git branch --set-upstream`. The former like you note doesn't pull the git-annex branch down the latter only works one-at-a-time.
+
+The docs read to me as though I ought to be able to do a `git pull remote ; git annex get .` using anyone of my distributed annexs.
+
+Am I doing something wrong? Or is the above correct?
+"""]]
diff --git a/doc/forum/git_pull_remote_git-annex/comment_4_646f2077edcabc000a7d9cb75a93cf55._comment b/doc/forum/git_pull_remote_git-annex/comment_4_646f2077edcabc000a7d9cb75a93cf55._comment
new file mode 100644
index 000000000..6ba179693
--- /dev/null
+++ b/doc/forum/git_pull_remote_git-annex/comment_4_646f2077edcabc000a7d9cb75a93cf55._comment
@@ -0,0 +1,37 @@
+[[!comment format=mdwn
+ username="http://adamspiers.myopenid.com/"
+ nickname="Adam"
+ subject="I think Matt is right."
+ date="2011-12-23T14:04:44Z"
+ content="""
+I got bitten by this too. It seems that the user is expected to fetch
+remote git-annex branches themselves, but this is not documented
+anywhere.
+
+The man page says of \"git annex merge\":
+
+ Automatically merges any changes from remotes into the git-annex
+ branch.
+
+I am not a git newbie, but even so I had incorrectly assumed that git
+annex merge would take care of pulling the git-annex branch from the
+remote prior to merging, thereby ensuring all versions of the
+git-annex branch would be merged, and that the location tracking data
+would be synced across all peer repositories.
+
+My master branches do not track any specific upstream branch, because
+I am operating in a decentralized fashion. Therefore the error
+message caused by `git pull $remote` succeeded in encouraging me to
+instead use `git pull $remote master`, and this excludes the git-annex
+branch from the fetch. Even worse, a git newbie might realise this
+and be tempted to do `git pull $remote git-annex`.
+
+Therefore I think it needs to be explicitly documented that
+
+ git fetch $remote
+ git merge $remote/master
+
+is required when the local branch doesn't track an upstream branch.
+Or maybe a `--fetch` option could be added to `git annex merge` to
+perform the fetch from all remotes before running the merge(s).
+"""]]
diff --git a/doc/forum/git_pull_remote_git-annex/comment_5_4f2a05ef6551806dd0ec65372f183ca4._comment b/doc/forum/git_pull_remote_git-annex/comment_5_4f2a05ef6551806dd0ec65372f183ca4._comment
new file mode 100644
index 000000000..c01f24120
--- /dev/null
+++ b/doc/forum/git_pull_remote_git-annex/comment_5_4f2a05ef6551806dd0ec65372f183ca4._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 5"
+ date="2011-12-23T16:50:26Z"
+ content="""
+My goal for `git-annex merge` is that users should not need to know about it, so it should not be doing expensive pulls.
+
+I hope that `git annex sync` will grow some useful features to support fully distributed git usage, as being discussed in [[pure_git-annex_only_workflow]]. I still use centralized git to avoid these problems myself.
+"""]]
diff --git a/doc/forum/git_pull_remote_git-annex/comment_6_3925d1aa56bce9380f712e238d63080f._comment b/doc/forum/git_pull_remote_git-annex/comment_6_3925d1aa56bce9380f712e238d63080f._comment
new file mode 100644
index 000000000..f4b5ebec2
--- /dev/null
+++ b/doc/forum/git_pull_remote_git-annex/comment_6_3925d1aa56bce9380f712e238d63080f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://adamspiers.myopenid.com/"
+ nickname="Adam"
+ subject="comment 6"
+ date="2011-12-23T17:14:03Z"
+ content="""
+Extending `git annex sync` would be nice, although auto-commit does not suit every use case, so it would be better not to couple one to the other.
+"""]]
diff --git a/doc/forum/git_pull_remote_git-annex/comment_7_24c45ee981b18bc78325c768242e635d._comment b/doc/forum/git_pull_remote_git-annex/comment_7_24c45ee981b18bc78325c768242e635d._comment
new file mode 100644
index 000000000..dad2c0af2
--- /dev/null
+++ b/doc/forum/git_pull_remote_git-annex/comment_7_24c45ee981b18bc78325c768242e635d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://adamspiers.myopenid.com/"
+ nickname="Adam"
+ subject="comment 7"
+ date="2011-12-23T17:24:58Z"
+ content="""
+P.S. I see you already [fixed the docs](http://source.git-annex.branchable.com/?p=source.git;a=commitdiff;h=a0227e81f9c82afc12ac1bd1cecd63cc0894d751) - thanks! :)
+"""]]
diff --git a/doc/forum/git_pull_remote_git-annex/comment_8_7e76ee9b6520cbffaf484c9299a63ad3._comment b/doc/forum/git_pull_remote_git-annex/comment_8_7e76ee9b6520cbffaf484c9299a63ad3._comment
new file mode 100644
index 000000000..5943d9312
--- /dev/null
+++ b/doc/forum/git_pull_remote_git-annex/comment_8_7e76ee9b6520cbffaf484c9299a63ad3._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="git tweak-fetch"
+ date="2011-12-26T18:50:35Z"
+ content="""
+The git tweak-fetch hook that I have been developing, and hope will be accepted into git soon, provides some abilities that could be used to make \"git pull remote\" always merge remote/master. Normall, git can only be configured to do that merge automatically for one remote (ie, origin). But the tweak-fetch hook can flag arbitrary branches as needing merge.
+
+So, it could always flag tracking branches of the currently checked out branch for merge. This would be enabled by some setting, probably, since it's not necessarily the case that everyone wants to auto-merge when they pull like this. (Which is why git doesn't do it by default after all.)
+
+(The tweak-fetch hook will also entirely eliminate the need to run git annex merge manually, since it can always take care of merging the git-annex branch.)
+"""]]
diff --git a/doc/forum/git_tag_missing_for_3.20111011.mdwn b/doc/forum/git_tag_missing_for_3.20111011.mdwn
new file mode 100644
index 000000000..781d0c91a
--- /dev/null
+++ b/doc/forum/git_tag_missing_for_3.20111011.mdwn
@@ -0,0 +1 @@
+Well, the subject pretty much says it all :)
diff --git a/doc/forum/git_tag_missing_for_3.20111011/comment_1_7a53bf273f3078ab3351369ef2b5f2a6._comment b/doc/forum/git_tag_missing_for_3.20111011/comment_1_7a53bf273f3078ab3351369ef2b5f2a6._comment
new file mode 100644
index 000000000..87cda998b
--- /dev/null
+++ b/doc/forum/git_tag_missing_for_3.20111011/comment_1_7a53bf273f3078ab3351369ef2b5f2a6._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="fixed that"
+ date="2011-10-13T15:36:59Z"
+ content="""
+:)
+"""]]
diff --git a/doc/forum/git_unannex_speed.mdwn b/doc/forum/git_unannex_speed.mdwn
new file mode 100644
index 000000000..a5e6ad571
--- /dev/null
+++ b/doc/forum/git_unannex_speed.mdwn
@@ -0,0 +1 @@
+It was fast to git annex a bunch of files. But git unannex seems a lot slower. Is there a faster way to get files out of git annex? Or to replace the symlinks with real files and then I could just remove the .git directory? I shouldn't have put so many in as a test but they are there now.
diff --git a/doc/forum/git_unannex_speed/comment_1_10cf326248f4e89e1f75bf97d7574763._comment b/doc/forum/git_unannex_speed/comment_1_10cf326248f4e89e1f75bf97d7574763._comment
new file mode 100644
index 000000000..39fc4793c
--- /dev/null
+++ b/doc/forum/git_unannex_speed/comment_1_10cf326248f4e89e1f75bf97d7574763._comment
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ subject="comment 1"
+ date="2012-08-02T16:58:41Z"
+ content="""
+It currently commits once per file, which is slow. `Command/Unannex.hs` explains why this is necessary. If I think of a way to avoid that, I will.
+"""]]
diff --git a/doc/forum/glacier_-_range_retrievals_and_daily_free_retrieval_allowance.mdwn b/doc/forum/glacier_-_range_retrievals_and_daily_free_retrieval_allowance.mdwn
new file mode 100644
index 000000000..d9db436c6
--- /dev/null
+++ b/doc/forum/glacier_-_range_retrievals_and_daily_free_retrieval_allowance.mdwn
@@ -0,0 +1,6 @@
+I propose to add some functionality to git-annex, to automatically "throttle" the data retrieval from amazon glacier to stay within the daily free retrieval allowance. If someone would need to get his/her files faster, there should be an option to disable this throttling (or even better, specify the retrieval rate).
+
+As far as I understand glacier, this could be implemented using range retrievals. In short range retrievals enable you, to only retrieve a part of an archive in glacier. This can be used to only retrieve / request so much data, that you stay within the free retrieval allowance. ( please see [Q: Why would I retrieve only a range of an archive?](http://aws.amazon.com/glacier/faqs/#Why_would_I_retrieve_only_a_range_of_an_archive) ).
+
+
+This would be somewhat similar to the [smart retrieval feature in cloudberry](http://blog.cloudberrylab.com/2012/12/introducing-smart-restore-for-amazon.html) .
diff --git a/doc/forum/hashing_objects_directories.mdwn b/doc/forum/hashing_objects_directories.mdwn
new file mode 100644
index 000000000..5b7708fb5
--- /dev/null
+++ b/doc/forum/hashing_objects_directories.mdwn
@@ -0,0 +1,27 @@
+I'm wondering how easy the addition of hashing to the directories of the objects would be.
+
+Currently a tree directory structure becomes a flat two level tree under the .git/annex/objects directory ([[internals]]). This, through the 555 mode on the directory prevents the accidental destruction of content, which is _good_. However file and directory numbers soon add up in there and as such any file-systems with sub directory limitations will quickly realize the limit (certainly quicker than maybe expected).
+
+Suggestion is therefore to change from
+
+ `.git/annex/objects/SHA1:123456789abcdef0123456789abcdef012345678/SHA1:123456789abcdef0123456789abcdef012345678`
+
+to
+
+ `.git/annex/objects/SHA1:1/2/3456789abcdef0123456789abcdef012345678/SHA1:123456789abcdef0123456789abcdef012345678`
+
+or anything in between to a paranoid
+
+ `.git/annex/objects/SHA1:123/456/789/abc/def/012/345/678/9ab/cde/f01/234/5678/SHA1:123456789abcdef0123456789abcdef012345678`
+
+Also the use of a colon specifically breaks FAT32 ([[bugs/fat_support]]), must it be a colon or could an extra directory be used? i.e. `.git/annex/objects/SHA1/*/...`
+
+`git annex init` could also create all but the last level directory on initialization. I'm thinking `SHA1/1/1, SHA1/1/2, ..., SHA256/f/f, ..., URL/f/f, ..., WORM/f/f`
+
+> This is done now with a 2-level hash. It also hashes .git-annex/ log
+> files which were the worse problem really. Scales to hundreds of millions
+> of files with each dir having 1024 or fewer contents. Example:
+>
+> `me -> .git/annex/objects/71/9t/WORM-s3-m1300247299--me/WORM-s3-m1300247299--me`
+>
+> --[[Joey]]
diff --git a/doc/forum/hashing_objects_directories/comment_1_c55c56076be4f54251b0b7f79f28a607._comment b/doc/forum/hashing_objects_directories/comment_1_c55c56076be4f54251b0b7f79f28a607._comment
new file mode 100644
index 000000000..3a19310b6
--- /dev/null
+++ b/doc/forum/hashing_objects_directories/comment_1_c55c56076be4f54251b0b7f79f28a607._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-03-14T16:12:49Z"
+ content="""
+My experience is that modern filesystems are not going to have many issues with tens to hundreds of thousands of items in the directory. However, if a transition does happen for FAT support I will consider adding hashing. Although getting a good balanced hash in general without, say, checksumming the filename and taking part of the checksum, is difficult.
+
+I prefer to keep all the metadata in the filename, as this eases recovery if the files end up in lost+found. So while \"SHA/\" is a nice workaround for the FAT colon problem, I'll be doing something else. (What I'm not sure yet.)
+
+There is no point in creating unused hash directories on initialization. If anything, with a bad filesystem that just guarantees worst performance from the beginning..
+"""]]
diff --git a/doc/forum/hashing_objects_directories/comment_2_504c96959c779176f991f4125ea22009._comment b/doc/forum/hashing_objects_directories/comment_2_504c96959c779176f991f4125ea22009._comment
new file mode 100644
index 000000000..64f1e16b5
--- /dev/null
+++ b/doc/forum/hashing_objects_directories/comment_2_504c96959c779176f991f4125ea22009._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 2"
+ date="2011-03-15T13:52:16Z"
+ content="""
+Can't you just use an underscore instead of a colon?
+
+Would it be feasible to split directories dynamically? I.e. start with SHA1_123456789abcdef0123456789abcdef012345678/SHA1_123456789abcdef0123456789abcdef012345678 and, at a certain cut-off point, switch to shorter directory names? This could even be done per subdirectory and based purely on a locally-configured number. Different annexes on different file systems or with different file subsets might even have different thresholds. This would ensure scale while not forcing you to segment from the start. Also, while segmenting with longer directory names means a flatter tree, segments longer than four characters might not make too much sense. Segmenting too often could lead to some directories becoming too populated, bringing us back to the dynamic segmentation.
+
+All of the above would make merging annexes by hand a _lot_ harder, but I don't know if this is a valid use case. And if all else fails, one could merge everything with the unsegemented directory names and start again from there.
+
+-- RichiH
+"""]]
diff --git a/doc/forum/hashing_objects_directories/comment_3_9134bde0a13aac0b6a4e5ebabd7f22e8._comment b/doc/forum/hashing_objects_directories/comment_3_9134bde0a13aac0b6a4e5ebabd7f22e8._comment
new file mode 100644
index 000000000..51deb2f95
--- /dev/null
+++ b/doc/forum/hashing_objects_directories/comment_3_9134bde0a13aac0b6a4e5ebabd7f22e8._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 3"
+ date="2011-03-16T03:13:39Z"
+ content="""
+It is unfortunatly not possible to do system-dependant hashing, so long as git-annex stores symlinks to the content in git.
+
+It might be possible to start without hashing, and add hashing for new files after a cutoff point. It would add complexity.
+
+I'm currently looking at a 2 character hash directory segment, based on an md5sum of the key, which splits it into 1024 buckets. git uses just 256 buckets for its object directory, but then its objects tend to get packed away. I sorta hope that one level is enough, but guess I could go to 2 levels (objects/ab/cd/key), which would provide 1048576 buckets, probably plenty, as if you are storing more than a million files, you are probably using a modern enough system to have a filesystem that doesn't need hashing.
+"""]]
diff --git a/doc/forum/hashing_objects_directories/comment_4_0de9170e429cbfea66f5afa8980d45ac._comment b/doc/forum/hashing_objects_directories/comment_4_0de9170e429cbfea66f5afa8980d45ac._comment
new file mode 100644
index 000000000..b29eea1b2
--- /dev/null
+++ b/doc/forum/hashing_objects_directories/comment_4_0de9170e429cbfea66f5afa8980d45ac._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 4"
+ date="2011-03-16T04:06:19Z"
+ content="""
+The .git-annex/ directory is what really needs hashing.
+
+Consider that when git looks for changes in there, it has to scan every file in the directory. With hashing, it should be able to more quickly identify just the subdirectories that contained changed files, by the directory mtimes.
+
+And the real kicker is that when committing there, git has to create a tree object containing every single file, even if only 1 file changed. That will be a lot of extra work; with hashed subdirs it will instead create just 2 or 3 small tree objects leading down to the changed file. (Probably these trees both pack down to similar size pack files, not sure.)
+"""]]
diff --git a/doc/forum/hashing_objects_directories/comment_5_ef6cfd49d24c180c2d0a062e5bd3a0be._comment b/doc/forum/hashing_objects_directories/comment_5_ef6cfd49d24c180c2d0a062e5bd3a0be._comment
new file mode 100644
index 000000000..c558ee65e
--- /dev/null
+++ b/doc/forum/hashing_objects_directories/comment_5_ef6cfd49d24c180c2d0a062e5bd3a0be._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 5"
+ date="2011-03-16T15:47:17Z"
+ content="""
+If you can't segment the names retroactively, it's better to start with segmenting, imo.
+
+As subdirectories are cheap, going with ab/cd/rest or even ab/cd/ef/rest by default wouldn't hurt.
+
+Your point about git not needing to create as many tree objects is a kicker indeed. If I were you, I would default to segmentation.
+"""]]
diff --git a/doc/forum/help_running_git-annex_on_top_of_existing_repo.mdwn b/doc/forum/help_running_git-annex_on_top_of_existing_repo.mdwn
new file mode 100644
index 000000000..365ad71db
--- /dev/null
+++ b/doc/forum/help_running_git-annex_on_top_of_existing_repo.mdwn
@@ -0,0 +1,12 @@
+## Question
+Can git-annex run passively with an existing repo?
+
+## Scenario
+We have an existing web application with large binary assets spread throughout modules in the repo. The project is in constant development with weekly deploys to production and there are many developers working on the project.
+
+## Goal
+We need to maintain the directory structure for these assets without actually committing large binaries to the main remote (hosted on GitHub). I need a solution that has a low barrier of entry when on-boarding new developers. I was thinking maybe a script the is executed on every commit that would filter binaries files based on extensions and commit them to the git-annex remote instead. We are flexible on the type of remote storage type (SSH, S3, etc)
+
+## Notes
+I have gone through the last couple months of forum posts and done a bit of Googling but have come up empty. If anyone can point me in the right direction that would be great.
+Thanks!
diff --git a/doc/forum/help_running_git-annex_on_top_of_existing_repo/comment_1_4cb38d71c943657c5ba0896cd70d2e64._comment b/doc/forum/help_running_git-annex_on_top_of_existing_repo/comment_1_4cb38d71c943657c5ba0896cd70d2e64._comment
new file mode 100644
index 000000000..b98ad6323
--- /dev/null
+++ b/doc/forum/help_running_git-annex_on_top_of_existing_repo/comment_1_4cb38d71c943657c5ba0896cd70d2e64._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn7gQ1zZDdWhXy9H51W2krZYShNmKL3qfM"
+ nickname="Karsten"
+ subject="comment 1"
+ date="2013-06-01T09:21:54Z"
+ content="""
+Mixing files controlled by git directly and files controlled by git annex is possible, simply 'git annex add' the large files and 'git add' the rest. You will not be able to use direct mode and you should not run the git annex assisstant, as it will add all files to the annex.
+"""]]
diff --git a/doc/forum/help_running_git-annex_on_top_of_existing_repo/comment_2_b5e94c10ebbed9125c7e2332f75709ca._comment b/doc/forum/help_running_git-annex_on_top_of_existing_repo/comment_2_b5e94c10ebbed9125c7e2332f75709ca._comment
new file mode 100644
index 000000000..ba321df6b
--- /dev/null
+++ b/doc/forum/help_running_git-annex_on_top_of_existing_repo/comment_2_b5e94c10ebbed9125c7e2332f75709ca._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9FMhhhM2sJ68Zjx_RmWd8cTdpI-mrkbE"
+ nickname="Hans"
+ subject="what about with git-svn?"
+ date="2013-06-04T08:00:15Z"
+ content="""
+I'm trying to wrap my head around a similar situation.
+I've tested this by git cloning my repo; the symlinks are copied, and end up broken because the annex directory under .git doesn't exist in the new repo.
+
+So to be specific: can I conclude that when I use git to copy my repo, as long as I don't explicitly use git-annex in the process, I end up with a 'bare' git repo and I don't have to worry about my annexed files coming along?
+
+Also: anyone know of anything that would be different about using git-svn? (i.e. git svn dcommit to push my changes to an svn repo)?
+"""]]
diff --git a/doc/forum/help_running_git-annex_on_top_of_existing_repo/comment_3_2b3b93bbc60fbc24d436231954d6822a._comment b/doc/forum/help_running_git-annex_on_top_of_existing_repo/comment_3_2b3b93bbc60fbc24d436231954d6822a._comment
new file mode 100644
index 000000000..8d2fd0dff
--- /dev/null
+++ b/doc/forum/help_running_git-annex_on_top_of_existing_repo/comment_3_2b3b93bbc60fbc24d436231954d6822a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 3"
+ date="2013-06-04T12:29:04Z"
+ content="""
+As long as you're not using Direct Mode, then a git-annex repo is just an absolutely ordinary git repo, which happens to contain some symlinks that point to .git/annex/objects/*
+
+
+"""]]
diff --git a/doc/forum/help_running_git-annex_on_top_of_existing_repo/comment_4_2dfda33ffa39b92b16c8bd9005e1cefe._comment b/doc/forum/help_running_git-annex_on_top_of_existing_repo/comment_4_2dfda33ffa39b92b16c8bd9005e1cefe._comment
new file mode 100644
index 000000000..e9f22adfd
--- /dev/null
+++ b/doc/forum/help_running_git-annex_on_top_of_existing_repo/comment_4_2dfda33ffa39b92b16c8bd9005e1cefe._comment
@@ -0,0 +1,21 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9J51AO9t75xN5k0sJgg8taUo4y0a4hpQ"
+ nickname="Daniel"
+ subject="comment 4"
+ date="2013-06-07T23:02:29Z"
+ content="""
+I'm trying to find a way to prevent developers from adding certain file types to the main repo. Is there something like a pre-add hook that could be used?
+
+I found this in another forum but I'm not sure how it was intended to be implemented.
+
+```
+git check-attr addtoannex \"$FILE\" | grep -q \": set$\"
+if [ $? -eq 0 ]; then
+ git annex add \"$FILE\"
+else
+ git add \"$FILE\"
+fi
+```
+
+[http://git-annex.branchable.com/forum/Let_watch_selectively_annex_files/](http://git-annex.branchable.com/forum/Let_watch_selectively_annex_files/)
+"""]]
diff --git a/doc/forum/help_running_git-annex_on_top_of_existing_repo/comment_5_96b1eb1e8e9f315c646f4686870f9b52._comment b/doc/forum/help_running_git-annex_on_top_of_existing_repo/comment_5_96b1eb1e8e9f315c646f4686870f9b52._comment
new file mode 100644
index 000000000..6435fc252
--- /dev/null
+++ b/doc/forum/help_running_git-annex_on_top_of_existing_repo/comment_5_96b1eb1e8e9f315c646f4686870f9b52._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 5"
+ date="2013-06-11T14:30:08Z"
+ content="""
+I think the most useful thing for people in this thread to know about is [[tips/replacing_Sparkleshare_or_dvcs-autosync_with_the_assistant]].
+
+This doesn't solve it at the command line, where you still need to choose between git add and git annex add, but you can use git annex watch to automatically commit small files to git, and large files to the git annex.
+"""]]
diff --git a/doc/forum/help_running_git-annex_on_top_of_existing_repo/comment_6_e85c3fa1d17f1d6ec625b9c4f9b698c3._comment b/doc/forum/help_running_git-annex_on_top_of_existing_repo/comment_6_e85c3fa1d17f1d6ec625b9c4f9b698c3._comment
new file mode 100644
index 000000000..6220a4416
--- /dev/null
+++ b/doc/forum/help_running_git-annex_on_top_of_existing_repo/comment_6_e85c3fa1d17f1d6ec625b9c4f9b698c3._comment
@@ -0,0 +1,47 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9J51AO9t75xN5k0sJgg8taUo4y0a4hpQ"
+ nickname="Daniel"
+ subject="comment 6"
+ date="2013-06-11T22:28:52Z"
+ content="""
+This is what I ended up doing.
+[https://gist.github.com/ifnull/5761255](https://gist.github.com/ifnull/5761255)
+
+Basically you just add the extensions of the files you want to exclude to .gitignore_large_binaries and run \"git a .\" instead of \"git add .\"
+
+ #######################
+ # Setup
+ #######################
+ mkdir annex-test
+ cd annex-test
+ git init
+ git annex init master
+
+ #######################
+ # Fab setup task
+ #######################
+ git config --local core.excludesfile ./.gitignore_large_binaries
+ git config --local alias.a '! sh ./git-add.sh'
+
+ #######################
+ # git a (git-add.sh)
+ #######################
+
+ # Generate annex include arg from .gitignore_large_binaries
+ include_str=\"--include='.lazy'\";
+
+ while read line
+ do
+ if [[ \"$line\" != *\"#\"* ]] && [[ \"$line\" != \"\" ]]; then
+ include_str=\"$include_str --or --include=${line}\";
+ fi
+ done < \"./.gitignore_large_binaries\"
+
+ # git annex add
+ git config --local core.excludesfile ./.gitignore;
+ git annex add $1 $include_str;
+
+ # git add
+ git config --local core.excludesfile ./.gitignore_large_binaries;
+ git add $1
+"""]]
diff --git a/doc/forum/how_to_decrypt_file_from_encrypted_special_remote__63__.mdwn b/doc/forum/how_to_decrypt_file_from_encrypted_special_remote__63__.mdwn
new file mode 100644
index 000000000..d16131eea
--- /dev/null
+++ b/doc/forum/how_to_decrypt_file_from_encrypted_special_remote__63__.mdwn
@@ -0,0 +1,14 @@
+I have an encrypted S3 remote with which I recently ran:
+
+$> git annex move . --from cloud
+
+which moved all my files to the local repo. When I looked at my S3 bucket, I saw some files left. I then ran:
+
+$> git annex unused --from cloud
+
+to get all the unused data. I dropped each unused data from cloud so that now I think git annex believes it has nothing on the cloud remote.
+
+However there is still one file left on the bucket. Is this normal? (if not I'll create a bug report)
+More importantly, how can I decrypt this file so I can run git log -S'KEY' to figure out what it is (I want to make sure I haven't lost any data).
+
+To be clear, when I currently run 'git annex move . --from cloud' it moves nothing and when I run 'git annex unused --from cloud' it reports no unused data.
diff --git a/doc/forum/how_to_decrypt_file_from_encrypted_special_remote__63__/comment_1_d4dc451892e7a6e230bf32adb7f3f9fa._comment b/doc/forum/how_to_decrypt_file_from_encrypted_special_remote__63__/comment_1_d4dc451892e7a6e230bf32adb7f3f9fa._comment
new file mode 100644
index 000000000..c1eccfb0f
--- /dev/null
+++ b/doc/forum/how_to_decrypt_file_from_encrypted_special_remote__63__/comment_1_d4dc451892e7a6e230bf32adb7f3f9fa._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkiAsTXFXZbLE8iyy6yDtvz4MPFbzsk3c0"
+ nickname="Tony"
+ subject="comment 1"
+ date="2013-07-27T22:14:11Z"
+ content="""
+one more thing, I forgot to mention I use gpg keys for encryption on the remote and not a shared key.
+"""]]
diff --git a/doc/forum/how_to_decrypt_file_from_encrypted_special_remote__63__/comment_2_79340bf3c0691073a9808c5ac2da0a3d._comment b/doc/forum/how_to_decrypt_file_from_encrypted_special_remote__63__/comment_2_79340bf3c0691073a9808c5ac2da0a3d._comment
new file mode 100644
index 000000000..0cea29414
--- /dev/null
+++ b/doc/forum/how_to_decrypt_file_from_encrypted_special_remote__63__/comment_2_79340bf3c0691073a9808c5ac2da0a3d._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.110"
+ subject="comment 2"
+ date="2013-07-27T22:30:50Z"
+ content="""
+I suppose this could happen if you have a tag or a branch or another repository that still refers to the file that's stored in S3. It would then not be found by `unused`.
+
+git-annex 4.20130709 has a nice new --all switch you can use: `git annex move --all --from cloud`
+
+If that doesn't move the file, nothing in the entire history of the git repository refers to it. The question then would be how did that file get there.
+
+It's by [[design|design/encryption]] not possible to get from the name of an encrypted file back to the key, unless you already know all the possible keys that the file could be. It's possible to decrypt the content if you have the gpg key and the git repository, but this space is a bit too small to explain every step in doing so, and I have some nice code that explains how in detail. ;)
+"""]]
diff --git a/doc/forum/how_to_decrypt_file_from_encrypted_special_remote__63__/comment_3_6302fb6e5bb7cbddf2cfe74d98d32897._comment b/doc/forum/how_to_decrypt_file_from_encrypted_special_remote__63__/comment_3_6302fb6e5bb7cbddf2cfe74d98d32897._comment
new file mode 100644
index 000000000..5c8d6356c
--- /dev/null
+++ b/doc/forum/how_to_decrypt_file_from_encrypted_special_remote__63__/comment_3_6302fb6e5bb7cbddf2cfe74d98d32897._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkiAsTXFXZbLE8iyy6yDtvz4MPFbzsk3c0"
+ nickname="Tony"
+ subject="comment 3"
+ date="2013-07-27T22:47:14Z"
+ content="""
+thanks, running
+
+'git annex move --all --from cloud'
+
+grabbed the one remaining file from the bucket.
+"""]]
diff --git a/doc/forum/how_to_decrypt_file_from_encrypted_special_remote__63__/comment_4_e3d95bc09c9fb21e8e9bbacc642aa60f._comment b/doc/forum/how_to_decrypt_file_from_encrypted_special_remote__63__/comment_4_e3d95bc09c9fb21e8e9bbacc642aa60f._comment
new file mode 100644
index 000000000..493fa3ba1
--- /dev/null
+++ b/doc/forum/how_to_decrypt_file_from_encrypted_special_remote__63__/comment_4_e3d95bc09c9fb21e8e9bbacc642aa60f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.110"
+ subject="comment 4"
+ date="2013-07-27T22:52:00Z"
+ content="""
+Great! And it should have also printed out the key it downloaded, if you're curious about looking where that file is used in your git repository.
+"""]]
diff --git a/doc/forum/how_to_decrypt_file_from_encrypted_special_remote__63__/comment_5_f2f0a1c2fb0c6323707b11e2b06aa2db._comment b/doc/forum/how_to_decrypt_file_from_encrypted_special_remote__63__/comment_5_f2f0a1c2fb0c6323707b11e2b06aa2db._comment
new file mode 100644
index 000000000..042704e52
--- /dev/null
+++ b/doc/forum/how_to_decrypt_file_from_encrypted_special_remote__63__/comment_5_f2f0a1c2fb0c6323707b11e2b06aa2db._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkiAsTXFXZbLE8iyy6yDtvz4MPFbzsk3c0"
+ nickname="Tony"
+ subject="comment 5"
+ date="2013-07-27T23:02:19Z"
+ content="""
+yeah it did print out the name of the file so I was able to verify that it was nothing I was worried about losing. thanks again :D
+"""]]
diff --git a/doc/forum/how_to_decrypt_file_from_encrypted_special_remote__63__/comment_6_66fe80e634a8f13cce18fe68974ec67a._comment b/doc/forum/how_to_decrypt_file_from_encrypted_special_remote__63__/comment_6_66fe80e634a8f13cce18fe68974ec67a._comment
new file mode 100644
index 000000000..8e79b4dc2
--- /dev/null
+++ b/doc/forum/how_to_decrypt_file_from_encrypted_special_remote__63__/comment_6_66fe80e634a8f13cce18fe68974ec67a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.110"
+ subject="comment 6"
+ date="2013-07-27T23:06:38Z"
+ content="""
+I'm curious, why didn't `git annex unused --from cloud` show the file? Was it a tag/branch/etc still referring to it?
+"""]]
diff --git a/doc/forum/how_to_remove_files_and_symlinks_but_keep_historical_file_contents.mdwn b/doc/forum/how_to_remove_files_and_symlinks_but_keep_historical_file_contents.mdwn
new file mode 100644
index 000000000..4f24117f6
--- /dev/null
+++ b/doc/forum/how_to_remove_files_and_symlinks_but_keep_historical_file_contents.mdwn
@@ -0,0 +1,7 @@
+It would be nice to have a way to drop files without leaving broken symlinks around, at least while in direct mode.
+
+Here is my user case. I have a collection of music CDs ripped in FLAC formats. At the same time I convert all these files to MP3 files to that I can use them in various other devices and to save space.
+
+The problem is that if I `git annex drop` the FLAC files once they are converted and copied, they leave broken symlinks around; this result in various annoying error messages in almost all the music playback I tried. At the same time, if I `rm` or `git rm` these symlinks, the content of these files will be removed also from the remotes as they are signalled as no longer wanted.
+
+Couldn't git-annex keep a separate index of files that have been removed but are meant to be kept?
diff --git a/doc/forum/how_to_remove_files_and_symlinks_but_keep_historical_file_contents/comment_1_cba76311e146dabb8ffc789bf4c8b714._comment b/doc/forum/how_to_remove_files_and_symlinks_but_keep_historical_file_contents/comment_1_cba76311e146dabb8ffc789bf4c8b714._comment
new file mode 100644
index 000000000..c490c826a
--- /dev/null
+++ b/doc/forum/how_to_remove_files_and_symlinks_but_keep_historical_file_contents/comment_1_cba76311e146dabb8ffc789bf4c8b714._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://svario.it/gioele"
+ ip="2001:1418:100:262::2"
+ subject="Maybe using branches?"
+ date="2013-05-16T10:22:48Z"
+ content="""
+A suggestion from #git-annex:
+
+> &lt;mhameed&gt; i think others are already doing this, using branches, but not sure if we have a writeup/tutorial of it
+>
+> &lt;mhameed&gt; gioele: instead of working on master branch, switch to laptop branch, git rm the files that are not wanted and commit
+>
+> &lt;gioele&gt; mhameed: I'm lazy, I'd like git-annex to do that for me :)
+"""]]
diff --git a/doc/forum/how_to_remove_files_and_symlinks_but_keep_historical_file_contents/comment_2_8d99c50fc1347367ccc0714e8d1af385._comment b/doc/forum/how_to_remove_files_and_symlinks_but_keep_historical_file_contents/comment_2_8d99c50fc1347367ccc0714e8d1af385._comment
new file mode 100644
index 000000000..f0b20f1a4
--- /dev/null
+++ b/doc/forum/how_to_remove_files_and_symlinks_but_keep_historical_file_contents/comment_2_8d99c50fc1347367ccc0714e8d1af385._comment
@@ -0,0 +1,40 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-05-19T20:43:43Z"
+ content="""
+The original poster seems to have a misunderstanding of what git-annex does with the content of files. Deleting a file does not remove the content of the file. You can always use git to check out a previous version of a file, and the content from the annex will still be there (or you can `git annex get` it to get it from whereever git-annex stored the content).
+
+The only exception to this rule is is you, manually, chose to run `git annex unused` and then `git annex dropunused`. That can delete the contents of files, when no branch or tag refers to them. As long as some branch refers to the content of the files, even if it's not the currently checked out branch, the file content is retained.
+
+So a branch *is* the \"index of files that have been removed but are wanted to be kept\".
+
+For example, you could do:
+
+[[!format sh \"\"\"
+git checkout -b keepflacs
+
+cdrom-rip-command
+git annex add *.flac
+git commit -m \"ripped a cd\"
+flac-convert-command
+git annex add *.mp3
+git commit -m \"converted to mp3\"
+
+git checkout master
+git merge keepflacs
+git rm *.flac
+git commit -m \"removed flac files from this branch. They are still available in the keepflacs branch\"
+\"\"\"]]
+
+As long as you always switch to the keepflacs branch to add flac files, and never merge the master branch into keepflacs,
+but only merge keepflacs into master, keepflacs will have every flac file you have ripped. And so git-annex will retain those files
+even when you `git annex unused; git-annex dropunused`.
+
+Or, just make a promise to yourself that you'll never run `git-annex unused`, similarly to how you'd probably never run `rm -rf .git/objects/$rand`, and you don't need the branches; like git, git-annex will retain all data that has ever been checked into it.
+
+(The branches are still a good idea. For one thing, they let you run `git annex fsck` and other repository maintenance commands with the keepflacs branch checked out.)
+
+I am going to move this thread to the [[forum]], because it's not really a TODO item, but is something others may want to read.
+"""]]
diff --git a/doc/forum/how_to_remove_files_and_symlinks_but_keep_historical_file_contents/comment_3_a7a9c55c2ad448179dff5d5b69976c7d._comment b/doc/forum/how_to_remove_files_and_symlinks_but_keep_historical_file_contents/comment_3_a7a9c55c2ad448179dff5d5b69976c7d._comment
new file mode 100644
index 000000000..39ed8306c
--- /dev/null
+++ b/doc/forum/how_to_remove_files_and_symlinks_but_keep_historical_file_contents/comment_3_a7a9c55c2ad448179dff5d5b69976c7d._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-05-20T17:46:08Z"
+ content="""
+Erm, I missed that you want to use direct mode. All this fun with git won't really work in direct mode, and indeed direct mode is not able to guarantee that old versions of modified files are retained.
+
+Direct mode is nice for some applications involving syncing and less than ideal devices, but not for this.
+"""]]
diff --git a/doc/forum/howto_update_feed.mdwn b/doc/forum/howto_update_feed.mdwn
new file mode 100644
index 000000000..5323e92eb
--- /dev/null
+++ b/doc/forum/howto_update_feed.mdwn
@@ -0,0 +1,14 @@
+I am using the importfeed [1] functionality.
+
+How am I supposed to update the feed/feeds?
+
+I understand that running
+
+ cd annex; git annex importfeed http://url/to/podcast
+
+a second time will 'do the right thing'. But that is cumbersome as I have to know the url again. Is there sth like git annex updatefeeds?
+
+
+
+
+[1] http://joeyh.name/blog/entry/git-annex_as_a_podcatcher/
diff --git a/doc/forum/howto_update_feed/comment_1_bec356619f370a618f19a187d09d2e35._comment b/doc/forum/howto_update_feed/comment_1_bec356619f370a618f19a187d09d2e35._comment
new file mode 100644
index 000000000..fa87e3494
--- /dev/null
+++ b/doc/forum/howto_update_feed/comment_1_bec356619f370a618f19a187d09d2e35._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 1"
+ date="2013-08-26T18:11:07Z"
+ content="""
+I have purposefully kept a list of feeds out of git-annex. I handle this by having a `feeds` file, which I check into git. Then a cron job runs: `xargs git-annex importfeed < feeds`
+"""]]
diff --git a/doc/forum/howto_update_feed/comment_2_84dfb80ba3db8d41164eb97022becae3._comment b/doc/forum/howto_update_feed/comment_2_84dfb80ba3db8d41164eb97022becae3._comment
new file mode 100644
index 000000000..4f28d8f4e
--- /dev/null
+++ b/doc/forum/howto_update_feed/comment_2_84dfb80ba3db8d41164eb97022becae3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="ringprince"
+ ip="134.76.140.110"
+ subject="comment 2"
+ date="2013-08-26T19:04:21Z"
+ content="""
+Thanks for that. I'll do the same ;-)
+"""]]
diff --git a/doc/forum/howto_update_feed/comment_3_20166db298c10074e062aecad59ffd71._comment b/doc/forum/howto_update_feed/comment_3_20166db298c10074e062aecad59ffd71._comment
new file mode 100644
index 000000000..73f48ac9b
--- /dev/null
+++ b/doc/forum/howto_update_feed/comment_3_20166db298c10074e062aecad59ffd71._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="http://a-or-b.myopenid.com/"
+ ip="203.45.2.230"
+ subject="comment 3"
+ date="2013-08-28T01:32:38Z"
+ content="""
+One thing I do slightly differently is put comments in my ```feeds``` file so I know what feed is what...
+
+ # NPR - Wait Wait... Don't Tell Me!
+ http://www.npr.org/rss/podcast.php?id=35
+ # NPR - Car Talk
+ http://www.npr.org/rss/podcast.php?id=510208
+
+
+Then I use
+
+ grep -v '^#' feeds| xargs git-annex importfeed --relaxed
+
+I reckon that makes maintenance easier.
+"""]]
diff --git a/doc/forum/howto_update_feed/comment_4_f040e31b763fc9a7aa092442b4d6b8e8._comment b/doc/forum/howto_update_feed/comment_4_f040e31b763fc9a7aa092442b4d6b8e8._comment
new file mode 100644
index 000000000..f7a35d1b6
--- /dev/null
+++ b/doc/forum/howto_update_feed/comment_4_f040e31b763fc9a7aa092442b4d6b8e8._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="arand"
+ ip="130.243.226.21"
+ subject="comment 4"
+ date="2013-09-01T18:06:51Z"
+ content="""
+Yet another solution, keeping it all in one script
+
+ #!/bin/sh
+
+ while IFS= read line
+ do
+ test -n \"${line%%#*}\" && echo git annex importfeed --relaxed \"$line\"
+ done <<EOF
+ # FooCast - Alice & Bob
+ http://feeds.foo.com/foocast
+ # FrobCast
+ http://meep.moop.com/feed
+ EOF
+"""]]
diff --git a/doc/forum/incompatible_versions__63__.mdwn b/doc/forum/incompatible_versions__63__.mdwn
new file mode 100644
index 000000000..13eb18149
--- /dev/null
+++ b/doc/forum/incompatible_versions__63__.mdwn
@@ -0,0 +1 @@
+Are versions 0.14 and 0.20110522 incompatible? I can't seem to copy files from a system running 0.14 to one running 20110522.
diff --git a/doc/forum/incompatible_versions__63__/comment_1_629f28258746d413e452cbd42a1a43f4._comment b/doc/forum/incompatible_versions__63__/comment_1_629f28258746d413e452cbd42a1a43f4._comment
new file mode 100644
index 000000000..3702fde6e
--- /dev/null
+++ b/doc/forum/incompatible_versions__63__/comment_1_629f28258746d413e452cbd42a1a43f4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-06-08T00:40:54Z"
+ content="""
+They are not. See [[upgrades]]
+"""]]
diff --git a/doc/forum/known_and_local_annex_keys.mdwn b/doc/forum/known_and_local_annex_keys.mdwn
new file mode 100644
index 000000000..7dcef8693
--- /dev/null
+++ b/doc/forum/known_and_local_annex_keys.mdwn
@@ -0,0 +1,14 @@
+I have a direct repository with the assistant running (v4.20131002). The repo is in the backup group and should be grabbing every known annex file. Yet `git annex status` says:
+
+ local annex keys: 1386
+ local annex size: 94.53 gigabytes
+ known annex keys: 1387
+ known annex size: 94.53 gigabytes
+
+As you can seem there is one more known annex key than there are local ones. Neither `git annex get` nor `git annex sync` changes the numbers. According to `tree` the repo dir contains exactly 1387 files, which means that the missing file must exist on disk.
+
+1) How do I find out which is the file in question? How do I get it synchronized?
+
+Yesterday there were 1376 known annex keys. Today there are 1387. For some reason the number of keys went up by 11, and I would like to know how and why. The log suggests that a couple of files have been added from inside the repo directory, but I am positive that these files already existed in the annex directory yesterday, and that I ran `git annex sync` manually without the number of local and/or known keys going up.
+
+2) Why weren't the files synced before? Is there a way to find out whether they were or were not part of the annex yesterday - maybe list all files sorted by the date they were added?
diff --git a/doc/forum/known_and_local_annex_keys/comment_1_3cb4828dc7116e4cf49e119f055ae9a3._comment b/doc/forum/known_and_local_annex_keys/comment_1_3cb4828dc7116e4cf49e119f055ae9a3._comment
new file mode 100644
index 000000000..24a5ef03e
--- /dev/null
+++ b/doc/forum/known_and_local_annex_keys/comment_1_3cb4828dc7116e4cf49e119f055ae9a3._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 1"
+ date="2013-10-28T16:56:20Z"
+ content="""
+I think you're stressing way too much about a number.
+
+It's quite possible for the known and local key counts to diverge while no data is missing. For example:
+
+<pre>
+joey@darkstar:~/tmp/test>touch foo
+joey@darkstar:~/tmp/test>touch bar
+joey@darkstar:~/tmp/test>git annex add foo bar
+
+local annex keys: 1
+known annex keys: 2
+</pre>
+
+"""]]
diff --git a/doc/forum/known_and_local_annex_keys/comment_2_68f20c881eafe986694bde10571cf1c0._comment b/doc/forum/known_and_local_annex_keys/comment_2_68f20c881eafe986694bde10571cf1c0._comment
new file mode 100644
index 000000000..944ec9caf
--- /dev/null
+++ b/doc/forum/known_and_local_annex_keys/comment_2_68f20c881eafe986694bde10571cf1c0._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="RaspberryPie"
+ ip="77.247.181.165"
+ subject="comment 2"
+ date="2013-10-28T18:31:21Z"
+ content="""
+I don't think I'm stressing too much. Rather, I'm inquiring about why git-annex is giving me wrong (or at least unclear) output that makes me worry about losing data. I plan to trust git-annex with a lot of important files, and in order to do that I want to make sure it's trustworthy. And that's where the inaccurate key numbers get in the way.
+
+So why do the local and known numbers diverge anyway? Would you consider adjusting the status output to be more accurate, or at least less confusing? I just want to be able to check that every single file in the repo is being backed up.
+"""]]
diff --git a/doc/forum/known_and_local_annex_keys/comment_3_e195a7091a06ce0427bb28aca9a17d04._comment b/doc/forum/known_and_local_annex_keys/comment_3_e195a7091a06ce0427bb28aca9a17d04._comment
new file mode 100644
index 000000000..fd9228b4f
--- /dev/null
+++ b/doc/forum/known_and_local_annex_keys/comment_3_e195a7091a06ce0427bb28aca9a17d04._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 3"
+ date="2013-10-28T19:06:00Z"
+ content="""
+I have adjusted the labels to be more clear.
+"""]]
diff --git a/doc/forum/known_and_local_annex_keys/comment_4_d81f0bf7465832cb676fd89f5d53ec18._comment b/doc/forum/known_and_local_annex_keys/comment_4_d81f0bf7465832cb676fd89f5d53ec18._comment
new file mode 100644
index 000000000..fccc576d3
--- /dev/null
+++ b/doc/forum/known_and_local_annex_keys/comment_4_d81f0bf7465832cb676fd89f5d53ec18._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="RaspberryPie"
+ ip="77.247.181.165"
+ subject="comment 4"
+ date="2013-10-28T19:24:12Z"
+ content="""
+Thanks, I'll check it out. And if you ever got around to introduce a means that can answer the above-mentioned integrity questions, that'd be really awesome.
+"""]]
diff --git a/doc/forum/linux_standalone_tarballs.mdwn b/doc/forum/linux_standalone_tarballs.mdwn
new file mode 100644
index 000000000..1c6380a7d
--- /dev/null
+++ b/doc/forum/linux_standalone_tarballs.mdwn
@@ -0,0 +1 @@
+Just saw that there is now a linux standalone tarball, I've a SL5 (RHEL5) based machine which I can churn out git-annex binaries if there is interest.
diff --git a/doc/forum/linux_standalone_tarballs/comment_1_5c3ceb845a45e50784f7098bfbf94df1._comment b/doc/forum/linux_standalone_tarballs/comment_1_5c3ceb845a45e50784f7098bfbf94df1._comment
new file mode 100644
index 000000000..64a37f366
--- /dev/null
+++ b/doc/forum/linux_standalone_tarballs/comment_1_5c3ceb845a45e50784f7098bfbf94df1._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.149"
+ subject="comment 1"
+ date="2012-09-29T16:03:36Z"
+ content="""
+I'll be curious to see if the standalone tarball works on such a system.. it might need a newer libc
+than RHEL5 has.
+
+Conversely, that'd make it a good system to build the tarball on, so it's built to work with a nice old libc. :)
+
+I have a machine where I could put chroots to do both 64 bit and 32 bit builds, but I don't know if I'll automate it there. Too lazy..
+"""]]
diff --git a/doc/forum/location_tracking_cleanup.mdwn b/doc/forum/location_tracking_cleanup.mdwn
new file mode 100644
index 000000000..7e2e230af
--- /dev/null
+++ b/doc/forum/location_tracking_cleanup.mdwn
@@ -0,0 +1,24 @@
+I recently started experimenting with git annex, adding files that I've had
+floating across several computers to repositories. During the testing I had
+a few occasions where I wrecked a repository somehow, and decided to wipe it
+and start anew (at this point there was no important files in them so I thought
+this is the easiest way). Well, as it turns out this interacts badly with location
+tracking, since now `git annex whereis` shows files residing in all those destroyed
+repositories, all having same names as some existing repositories. This makes it hard
+to follow whether a repo actually has a file, or was the file only seen in some dead
+repo with the same name.
+
+I planned on cleaning this up by looking up the UUIDs of the now stable, existing
+repos and untrusting all the dead copies (they should effectively disappear from
+git annex´s output then, right?), but I didn't find an easy way to look up the UUID
+of the current repository (maybe this could be included in `git annex status`?)
+I also noticed that untrust cannot remove the trust based on the UUID -- if I try
+it I simply get "there is no git remote named "11908472-...", so I guess untrust
+works with git remote names, which I find a bit confusing, since trust.log logs the
+trust levels based on the UUID. I could just write into trust.log manually, but I'm
+unsure how the changes would get propagated.
+
+What should I do? As a related wishlist item I would ask for some additional mechanisms
+for purging known-dead repositories from the location tracking database. And the ability
+to look up the UUID of the current repo, and to use the UUID to specify repositories when
+applicable (untrust and describe maybe).
diff --git a/doc/forum/location_tracking_cleanup/comment_1_7d6319e8c94dfe998af9cfcbf170efb2._comment b/doc/forum/location_tracking_cleanup/comment_1_7d6319e8c94dfe998af9cfcbf170efb2._comment
new file mode 100644
index 000000000..8915ea351
--- /dev/null
+++ b/doc/forum/location_tracking_cleanup/comment_1_7d6319e8c94dfe998af9cfcbf170efb2._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-09-30T06:55:34Z"
+ content="""
+Specifying the UUID was supposed to work, I think I broke it a while ago. Fixed now in git.
+
+I'm not sure why you need to look up the UUID of the current repository. You can always refer to the current repository as \".\". Anyway, the UUID of the current repository is in `.git/config`, or use `git config annex.uuid`.
+"""]]
diff --git a/doc/forum/location_tracking_cleanup/comment_2_e7395cb6e01f42da72adf71ea3ebcde4._comment b/doc/forum/location_tracking_cleanup/comment_2_e7395cb6e01f42da72adf71ea3ebcde4._comment
new file mode 100644
index 000000000..f612e53a4
--- /dev/null
+++ b/doc/forum/location_tracking_cleanup/comment_2_e7395cb6e01f42da72adf71ea3ebcde4._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawncBlzaDI248OZGjKQMXrLVQIx4XrZrzFo"
+ nickname="Perttu"
+ subject="comment 2"
+ date="2011-09-30T11:55:35Z"
+ content="""
+Thanks for the quick reply :)
+
+I wanted to look up the UUID of the current repo so that I can find out which repo is alive from the collection of repos with the same name.
+I could have looked for it in .git/config though, since it's pretty obvious. I just looked into the git-annex branch and didn't find it there.
+Thanks for the tip about using \".\". By the way, could there be some kind of warning about using non-unique names for repos? That would make this
+scenario less likely. Or maybe that is a bad idea given the decentralized nature of git.
+
+By the way, do the trust settings propagate to other repos? If I mark some UUID as untrusted on one computer does it become globally untrusted?
+"""]]
diff --git a/doc/forum/location_tracking_cleanup/comment_3_c15428cec90e969284a5e690fb4b2fde._comment b/doc/forum/location_tracking_cleanup/comment_3_c15428cec90e969284a5e690fb4b2fde._comment
new file mode 100644
index 000000000..c676b9b61
--- /dev/null
+++ b/doc/forum/location_tracking_cleanup/comment_3_c15428cec90e969284a5e690fb4b2fde._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 3"
+ date="2011-09-30T16:47:27Z"
+ content="""
+`git annex status` now includes a list of all known repositories.
+
+Yes, trust setting propigate on git push/pull like any other git-annex information.
+"""]]
diff --git a/doc/forum/lost_in_walkthrough....txt b/doc/forum/lost_in_walkthrough....txt
new file mode 100644
index 000000000..89f4af026
--- /dev/null
+++ b/doc/forum/lost_in_walkthrough....txt
@@ -0,0 +1,78 @@
+I'm trying to follow the steps of the "walkthrough" but I'm experiencing the following issue: when
+I sync one repository and do "git annex get ." I don't get the files from the other repository.
+Here is the transcript of the steps I followed - I've put them in a script (ga.sh) so I can replay
+them and show them on the shell while executing.
+Basically I have two repositories, "/tmp/a/annex" and "/tmp/b/annex", the second cloned from
+the first. All the other steps are the same as in the walkthrough.
+-----------------------------------
+> bash -x ga.sh
++ cd /tmp
++ mkdir a
++ mkdir b
++ cd a
++ mkdir annex
++ cd annex
++ git init
+Initialized empty Git repository in /tmp/a/annex/.git/
++ git annex init a
+init a ok
+(Recording state in git...)
++ cd /tmp/b
++ git clone /tmp/a/annex
+Cloning into 'annex'...
+done.
+warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
++ cd annex
++ git annex init b
+init b ok
+(Recording state in git...)
++ git remote add a /tmp/a/annex
++ cd /tmp/a/annex
++ git remote add b /tmp/b/annex
++ dd if=/dev/urandom of=first bs=1024 count=1
+1+0 records in
+1+0 records out
+1024 bytes (1.0 kB) copied, 9.9167e-05 s, 10.3 MB/s
++ dd if=/dev/urandom of=second bs=1024 count=1
+1+0 records in
+1+0 records out
+1024 bytes (1.0 kB) copied, 0.000241635 s, 4.2 MB/s
++ git annex add .
+add first (checksum...) ok
+add second (checksum...) ok
+(Recording state in git...)
++ git commit -am added
+[master (root-commit) 5078564] added
+ 2 files changed, 2 insertions(+)
+ create mode 120000 first
+ create mode 120000 second
++ git mv first e
++ mkdir x
++ git mv second x
++ git commit -m moved
+fix x/second ok
+(Recording state in git...)
+[master 422492d] moved
+ 3 files changed, 1 insertion(+), 1 deletion(-)
+ rename first => e (100%)
+ delete mode 120000 second
+ create mode 120000 x/second
++ cd /tmp/b/annex
++ git annex sync a
+(merging origin/git-annex into git-annex...)
+(Recording state in git...)
+commit
+ok
+git-annex: no branch is checked out
++ git annex get .
+-------------------
+
+The last "git annex get ." does not retrieve the files in /tmp/a/annex ... why?
+I guess the issue starts when cloning /tmp/a/annex where no commit was done.
+
+Emanuele
+
+PS: I'm using git v1.7.9.5 (ubuntu 12.04) and the latest git-annex static binary
+downloaded a few minutes ago from the git-annex website.
+
diff --git a/doc/forum/lost_in_walkthrough.../comment_1_51b703b961ca762f0359e1c169f1ee75._comment b/doc/forum/lost_in_walkthrough.../comment_1_51b703b961ca762f0359e1c169f1ee75._comment
new file mode 100644
index 000000000..a5c574b4a
--- /dev/null
+++ b/doc/forum/lost_in_walkthrough.../comment_1_51b703b961ca762f0359e1c169f1ee75._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 1"
+ date="2013-11-02T19:32:50Z"
+ content="""
+I have fixed `git annex sync` to work even when run in a repository with no master branch.
+"""]]
diff --git a/doc/forum/lost_in_walkthrough.../comment_2_a9de0401a103bdd4401ba2d5983dc54a._comment b/doc/forum/lost_in_walkthrough.../comment_2_a9de0401a103bdd4401ba2d5983dc54a._comment
new file mode 100644
index 000000000..4a8110eb4
--- /dev/null
+++ b/doc/forum/lost_in_walkthrough.../comment_2_a9de0401a103bdd4401ba2d5983dc54a._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn2MI-Ci-bS9W5NITngsBJiL8LqWYcJ458"
+ nickname="Emanuele"
+ subject="comment 2"
+ date="2013-11-02T23:36:54Z"
+ content="""
+Great thanks! I'm glad my feedback helped improve git-annex!
+
+<https://github.com/joeyh/git-annex/commit/bc18cde32589cf53080c399e81b5680e4b>af6cef
+
+"""]]
diff --git a/doc/forum/making_good_use_of_my_shiny_new_rsync.net_account.mdwn b/doc/forum/making_good_use_of_my_shiny_new_rsync.net_account.mdwn
new file mode 100644
index 000000000..aef5a58a7
--- /dev/null
+++ b/doc/forum/making_good_use_of_my_shiny_new_rsync.net_account.mdwn
@@ -0,0 +1,20 @@
+So I got a shiny new rsync.net account, but it's not (yet) big enough for my bloated, kitchen-sink annex. How do I make the best use of it? Well, on the whole small files are more valuable to me than large. Large files are usually replaceable, like ripped DVDs. Small files are more likely to be family photos and such. So I shut down the assistant, and I've been doing a series of these:
+
+ git annex copy --to=rsyncnet --smallerthan 10M --not --in=rsyncnet # I called my remote "rsyncnet"
+
+ git annex copy --to=rsyncnet --smallerthan 20M --not --in=rsyncnet
+
+ git annex copy --to=rsyncnet --smallerthan 40M --not --in=rsyncnet
+
+until the repo fills up. With a few of these thrown in to check on my progress and what's ahead.
+
+
+ git annex status . --in=rsyncnet # how much have I already done?
+ git annex status . --smallerthan 40M --not --in=rsyncnet # how much will this next command copy?
+
+
+It'd be possible to write a script to do all this automagically but at least this time it's easier to do by hand.
+
+Just sharing in case anybody's in a similar situation.
+
+(You could let the assistant do this for you if you configured a preferred content expression designating small files for the rsyncnet remote, of course.)
diff --git a/doc/forum/making_good_use_of_my_shiny_new_rsync.net_account/comment_1_0ebe509b768d46081db2100f5b712ef7._comment b/doc/forum/making_good_use_of_my_shiny_new_rsync.net_account/comment_1_0ebe509b768d46081db2100f5b712ef7._comment
new file mode 100644
index 000000000..617c87d97
--- /dev/null
+++ b/doc/forum/making_good_use_of_my_shiny_new_rsync.net_account/comment_1_0ebe509b768d46081db2100f5b712ef7._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawln3ckqKx0x_xDZMYwa9Q1bn4I06oWjkog"
+ nickname="Michael"
+ subject="comment 1"
+ date="2013-07-26T16:16:04Z"
+ content="""
+How about
+
+ git annex find . --format='${bytesize} ${file}\n' |sort -n|sed 's/[0-9]* //'|while read file; do git annex copy \"$file\" --to=your_remote; done
+"""]]
diff --git a/doc/forum/making_good_use_of_my_shiny_new_rsync.net_account/comment_2_ef63d893531d93d2eb09f48f8baff4dd._comment b/doc/forum/making_good_use_of_my_shiny_new_rsync.net_account/comment_2_ef63d893531d93d2eb09f48f8baff4dd._comment
new file mode 100644
index 000000000..229a2dda9
--- /dev/null
+++ b/doc/forum/making_good_use_of_my_shiny_new_rsync.net_account/comment_2_ef63d893531d93d2eb09f48f8baff4dd._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 2"
+ date="2013-07-26T16:44:35Z"
+ content="""
+Note that you don't need to shut down the assistant; you can run multiple git-annex commands simulantaneously safely.
+You will probably want to set that repository to be in the manual group in the assistant though.
+
+Another way to do it is to make rsync.net a small archive, and move or copy your important files into `archive` directories.
+
+You can also set up multiple remotes using the same rsync.net account. So you could have a transfer remote that's used to ship files between clients, as well as your archive remote.
+"""]]
diff --git a/doc/forum/man_pages_in_the_prebuilt_linux_tarball.mdwn b/doc/forum/man_pages_in_the_prebuilt_linux_tarball.mdwn
new file mode 100644
index 000000000..045dccb82
--- /dev/null
+++ b/doc/forum/man_pages_in_the_prebuilt_linux_tarball.mdwn
@@ -0,0 +1 @@
+Is there an easy way for a noob to get the man pages, after installing the prebuilt tarball?
diff --git a/doc/forum/man_pages_in_the_prebuilt_linux_tarball/comment_1_a7bc2e84e6d7c0e2de5900685207af78._comment b/doc/forum/man_pages_in_the_prebuilt_linux_tarball/comment_1_a7bc2e84e6d7c0e2de5900685207af78._comment
new file mode 100644
index 000000000..01f0109e3
--- /dev/null
+++ b/doc/forum/man_pages_in_the_prebuilt_linux_tarball/comment_1_a7bc2e84e6d7c0e2de5900685207af78._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.49"
+ subject="comment 1"
+ date="2012-11-27T20:27:37Z"
+ content="""
+Yes, go to http://git-annex.branchable.com/git-annex/ and http://git-annex.branchable.com/git-annex-shell/
+
+"""]]
diff --git a/doc/forum/managing_multiple_repositories.mdwn b/doc/forum/managing_multiple_repositories.mdwn
new file mode 100644
index 000000000..7450b4271
--- /dev/null
+++ b/doc/forum/managing_multiple_repositories.mdwn
@@ -0,0 +1,3 @@
+I tried about 2 weeks ago using the assistant to create on my netbook and my home laptop 3 repositores, for music, pictures and documents. Since I was also going to be away from home, I set up jabber pairing and box.com for a transfer repository, and then watched everything crash as I didn't know yet about jabber only really working for 1 repository at a time.
+
+So my new idea is this: one repository at ~/annex, and changing documents, music and pictures to be symlinks to actual documents, music and pictures folders inside ~/annex, allowing me to have just 1 annex to manage. Is this the best way to put everything together if I want to just jabber pairing (and just 1 jabber account)?
diff --git a/doc/forum/manual_update_of_.git__47__annex__47__objects.txt b/doc/forum/manual_update_of_.git__47__annex__47__objects.txt
new file mode 100644
index 000000000..9de5779c1
--- /dev/null
+++ b/doc/forum/manual_update_of_.git__47__annex__47__objects.txt
@@ -0,0 +1,8 @@
+Let's suppose that I've manually modified files in .git/annex/objects,
+for example I ran an rsync or some other file synchronization software
+to copy files. As a result, some objects have disappeared, others have
+appeared. After that `git annex whereis .' displays stale information,
+it doesn't take the manual modifications to accound. `git annex fsck'
+seems to fix this, but it runs the rehashing of all new files, so it's
+slow. Is there a fast alternative, which notices all the object file
+changes, trusts them, and just updates .git/annex/index quickly?
diff --git a/doc/forum/manual_update_of_.git__47__annex__47__objects/comment_1_ea6ec91150c8962e2711631f2422bf3a._comment b/doc/forum/manual_update_of_.git__47__annex__47__objects/comment_1_ea6ec91150c8962e2711631f2422bf3a._comment
new file mode 100644
index 000000000..f721e21a5
--- /dev/null
+++ b/doc/forum/manual_update_of_.git__47__annex__47__objects/comment_1_ea6ec91150c8962e2711631f2422bf3a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.51"
+ subject="comment 1"
+ date="2013-09-12T17:11:41Z"
+ content="""
+I do not recommend manually messing with the contents of .git/annex/objects. It is a good way to lose data.
+
+If you look at the documentation for fsck in git-annex's man page, you will find the answer to your question.
+"""]]
diff --git a/doc/forum/many_remotes.mdwn b/doc/forum/many_remotes.mdwn
new file mode 100644
index 000000000..4e463cb3c
--- /dev/null
+++ b/doc/forum/many_remotes.mdwn
@@ -0,0 +1,24 @@
+Thanks Joey for the great work.
+
+I'm using git annex for my tv-shows and movies Folder.
+
+I have 3 USB HDD (ext.150Gb,ext.200Gb, ext.2Tb) and a USB Stick (ATV), which are traveling between 3 Devices
+
+2 Notebooks (Lappi,Kiste) and a Nas.
+
+First of all, I'm made a mistake and mixed the remote Locations from the tvshows folder with the movies folder and did a git annex sync, ( this happened about two weeks ago)
+I think i can't undo this, only unannex will help.
+
+I've now watched the annex status output and noticed that there are many Remotes, some of them have a timestamp as name.
+
+see log file at http://pastebin.com/79bRVkK6
+
+Running git annex on ubuntu 12.04
+
+ christian@Lappi:~/Serien$ git annex version
+ git-annex version: 4.20130417
+ local repository version: 3
+ default repository version: 3
+ supported repository versions: 3 4
+ upgrade supported from repository versions: 0 1 2
+ build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP DNS
diff --git a/doc/forum/migrate_existing_git_repository_to_git-annex.mdwn b/doc/forum/migrate_existing_git_repository_to_git-annex.mdwn
new file mode 100644
index 000000000..f673de765
--- /dev/null
+++ b/doc/forum/migrate_existing_git_repository_to_git-annex.mdwn
@@ -0,0 +1,66 @@
+I have a large git repository with binary files scattered over different branches. I want to switch to git-annex mainly for performance reasons, but I don't want to loose my history.
+
+I tried to rewrite the (cloned) repository with git-filter-branch but failed miserably for several reasons:
+
+* --tree-filter performs its operations in a temporary directory (.git-rewrite/t/) so the symlinks point to the wrong destination (../../.git/annex/).
+* annex log files are stored in .git-annex/ instead of .git-rewrite/t/.git-annex/ so the filter operation misses them
+
+Any suggestions how to proceed?
+
+EDIT 3/2/2010
+I finally got it working for my purposes. Hardest part was preserving the branches while injecting the new `git annex setup` base commit.
+
+#### Clone repository
+ git clone original migrate
+ cd migrate
+ git checkout mybranch
+ git checkout master
+ git remote rm origin
+
+#### Inject `git annex setup` base commit and repair branches
+ git symbolic-ref HEAD refs/heads/newroot
+ git rm --cached *
+ git clean -f -d
+ git annex init master
+ echo \*.rpm annex.backend=SHA1 >> .gitattributes
+ git commit -m "store rpms in git annex" .gitattributes
+ git cherry-pick $(git rev-list --reverse master | head -1)
+ git rebase --onto newroot newroot master
+ git rebase --onto master mybranch~1 mybranch
+ git branch -d newroot
+
+#### Migrate repository
+ mkdir .temp
+ cp .git-annex/* .temp/
+ MYWORKDIR=$(pwd) git filter-branch \
+ --tag-name-filter cat \
+ --tree-filter '
+ mkdir -p .git-annex;
+ cp ${MYWORKDIR}/.temp/* .git-annex/;
+ for rpm in $(git ls-files | grep "\.rpm$"); do
+ echo;
+ git annex add $rpm;
+ annexdest=$(readlink $rpm);
+ if [ -e .git-annex/$(basename $annexdest).log ]; then
+ echo "FOUND $(basename $annexdest).log";
+ else
+ echo "COPY $(basename $annexdest).log";
+ cp ${MYWORKDIR}/.git-annex/$(basename $annexdest).log .git-annex/;
+ cp ${MYWORKDIR}/.git-annex/$(basename $annexdest).log ${MYWORKDIR}/.temp/;
+ fi;
+ ln -sf ${annexdest#../../} $rpm;
+ done;
+ git reset HEAD .git-rewrite;
+ :
+ ' -- $(git branch | cut -c 3-)
+ rm -rf .temp
+ git reset --hard
+
+
+TODO:
+
+* Find a way to repair branches automatically (detect branch points and run appropriate `git rebase` commands)
+
+I'll be happy to try any suggestions to improve this migration script.
+
+P.S. Is there a way to edit comments?
diff --git a/doc/forum/migrate_existing_git_repository_to_git-annex/comment_1_4181bf34c71e2e8845e6e5fb55d53381._comment b/doc/forum/migrate_existing_git_repository_to_git-annex/comment_1_4181bf34c71e2e8845e6e5fb55d53381._comment
new file mode 100644
index 000000000..e88794d62
--- /dev/null
+++ b/doc/forum/migrate_existing_git_repository_to_git-annex/comment_1_4181bf34c71e2e8845e6e5fb55d53381._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-02-25T05:16:48Z"
+ content="""
+I don't know how to approach this yet, but I support the idea -- it would be great if there was a tool that could punch files out of git history and put them in the annex. (Of course with typical git history rewriting caveats.)
+
+Sounds like it might be enough to add a switch to git-annex that overrides where it considers the top of the git repository to be?
+"""]]
diff --git a/doc/forum/migrate_existing_git_repository_to_git-annex/comment_2_5f08da5e21c0b3b5a8d1e4408c0d6405._comment b/doc/forum/migrate_existing_git_repository_to_git-annex/comment_2_5f08da5e21c0b3b5a8d1e4408c0d6405._comment
new file mode 100644
index 000000000..71a40ad8c
--- /dev/null
+++ b/doc/forum/migrate_existing_git_repository_to_git-annex/comment_2_5f08da5e21c0b3b5a8d1e4408c0d6405._comment
@@ -0,0 +1,60 @@
+[[!comment format=mdwn
+ username="tyger"
+ ip="80.66.20.180"
+ subject="comment 2"
+ date="2011-03-01T14:07:50Z"
+ content="""
+My current workflow looks like this (I'm still experimenting):
+
+### Create backup clone for migration
+
+ git clone original migrate
+ cd migrate
+ for branch in $(git branch -a | grep remotes/origin | grep -v HEAD); do git checkout --track $branch; done
+
+### Inject git annex initialization at repository base
+
+ git symbolic-ref HEAD refs/heads/newroot
+ git rm --cached *.rpm
+ git clean -f -d
+ git annex init master
+ git cherry-pick $(git rev-list --reverse master | head -1)
+ git rebase --onto newroot newroot master
+ git rebase master mybranch # how to automate this for all branches?
+ git branch -d newroot
+
+### Start migration with tree filter
+
+ echo \*.rpm annex.backend=SHA1 > .git/info/attributes
+ MYWORKDIR=$(pwd) git filter-branch --tree-filter ' \
+ if [ ! -d .git-annex ]; then \
+ mkdir .git-annex; \
+ cp ${MYWORKDIR}/.git-annex/uuid.log .git-annex/; \
+ cp ${MYWORKDIR}/.gitattributes .; \
+ fi
+ for rpm in $(git ls-files | grep \"\.rpm$\"); do \
+ echo; \
+ git annex add $rpm; \
+ annexdest=$(readlink $rpm); \
+ if [ -e .git-annex/$(basename $annexdest).log ]; then \
+ echo \"FOUND $(basename $annexdest).log\"; \
+ else \
+ echo \"COPY $(basename $annexdest).log\"; \
+ cp ${MYWORKDIR}/.git-annex/$(basename $annexdest).log .git-annex/; \
+ fi; \
+ ln -sf ${annexdest#../../} $rpm; \
+ done; \
+ git reset HEAD .git-rewrite; \
+ : \
+ ' -- $(git branch | cut -c 3-)
+ rm -rf .temp
+ git reset --hard
+
+
+There are still some drawbacks:
+
+* git history shows that git annex log files are modified with each checkin
+* branches have to be rebased manually before starting migration
+
+
+"""]]
diff --git a/doc/forum/migrate_existing_git_repository_to_git-annex/comment_3_f483038c006cf7dcccf1014fa771744f._comment b/doc/forum/migrate_existing_git_repository_to_git-annex/comment_3_f483038c006cf7dcccf1014fa771744f._comment
new file mode 100644
index 000000000..90bf23b6c
--- /dev/null
+++ b/doc/forum/migrate_existing_git_repository_to_git-annex/comment_3_f483038c006cf7dcccf1014fa771744f._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="tyger"
+ ip="80.66.20.180"
+ subject="comment 3"
+ date="2011-03-02T08:15:37Z"
+ content="""
+> Sounds like it might be enough to add a switch to git-annex that overrides where it considers the top of the git repository to be?
+
+It should sufficient to honor GIT_DIR/GIT_WORK_TREE/GIT_INDEX_FILE environment variables. git filter-branch sets GIT_WORK_TREE to ., but this can be mitigated by starting the filter script with 'GIT_WORK_TREE=$(pwd $GIT_WORK_TREE)'. E.g. GIT_DIR=/home/tyger/repo/.git, GIT_WORK_TREE=/home/tyger/repo/.git-rewrite/t, then git annex should be able to compute the correct relative path or maybe use absolute pathes in symlinks.
+
+Another problem I observed is that git annex add automatically commits the symlink; this behaviour doesn't work well with filter-tree. git annex commits the wrong path (.git-rewrite/t/LINK instead of LINK). Also filter-tree doesn't expect that the filter script commmits anything; new files in the temporary work tree will be committed by filter-tree on each iteration of the filter script (missing files will be removed).
+"""]]
diff --git a/doc/forum/migration_to_git-annex_and_rsync.mdwn b/doc/forum/migration_to_git-annex_and_rsync.mdwn
new file mode 100644
index 000000000..d99dab872
--- /dev/null
+++ b/doc/forum/migration_to_git-annex_and_rsync.mdwn
@@ -0,0 +1,33 @@
+When migrating large file repositories to git-annex that are backuped in a way that uses an rsync-style mechanism (e.g. [dirvish](http://www.dirvish.org/)) and thus keeps incremental backups small by using hardlinks, space can be saved by manually reflecting the migration on the backup. So, instead of making a last pre-git-annex backup, migrating, and duplicating all backupped data with the next backup, I used the <del>attached</del> migrate.py file below, and it saved me roughly a day of backuping.
+
+A note on terminology: "migrating" here means migrating from not using git-annex at all to using it, not to the ``git annex migrate`` command, for which a similar but different solution may be created.
+
+**WARNING**: This is a quickly hacked-together script. It worked for me, but is untested apart from that. It's just a dozen lines of code, so have a look at it and make sure you understand what it does, and what migrate.sh looks like. Take special care as this tampers with your backups, and if something goes wrong, well...
+
+First, have an up-to-date backup; then, git annex init / add etc as described in the [[walkthrough]]. In the directory in which you use git-annex, run:
+
+ $ python migrate.py > migrate.sh
+
+Then copy the resulting migrate.sh to the equivalent location inside your backups and run it there. It will move all files that are now symlinked on the master to their new positions according to the symlinks (inside .git/annex/objects), but not create the symlinks (you will do a backup later anyway).
+
+After that, do a backup as usual. As rsync sees the moved files at their new locations, it will accept them and not duplicate the data.
+
+**migrate.py**:
+
+ #!/usr/bin/env python
+
+ import os
+ from pipes import quote
+
+ print "#!/bin/sh"
+ print "set -e"
+ print ""
+
+ for (dirpath, dirnames, filenames) in os.walk("."):
+ for f in filenames:
+ fn = os.path.join(dirpath, f)
+ if os.path.islink(fn):
+ link = os.path.normpath(os.path.join(dirpath, os.readlink(fn)))
+ assert link.startswith(".git/annex/objects/")
+ print "mkdir -p %s"%quote(os.path.dirname(link))
+ print "mv %s %s"%(quote(fn), quote(link))
diff --git a/doc/forum/mistakenly_checked___42__files__42___into_an_annex.__bummer..mdwn b/doc/forum/mistakenly_checked___42__files__42___into_an_annex.__bummer..mdwn
new file mode 100644
index 000000000..1e2e44cfa
--- /dev/null
+++ b/doc/forum/mistakenly_checked___42__files__42___into_an_annex.__bummer..mdwn
@@ -0,0 +1,3 @@
+A couple times working in an annex manually, I accidentally did "git add" instead of "git annex add" and ended up with files checked into my repo instead of symlinks. So now there is some file content in git, rather than in the annex. Is there any way to root that out, or is it there forever? (My limited knowledge of git says: it's there forever, unless maybe you go into the branches where it lives, do an interactive rebase to the time before it was added, remove that commit, replay history, and then garbage collect, but I have no idea if that would suddenly break git annex, and it sounds painful anyway.)
+
+If say I were a neat freak and wanted to just start over with a clean annex, I imagine the thing to do would be to just start the hell over -- and if I wanted to do that, the way to go would be to get into a full repository, do a "git annex uninit" and then throw away the .git directory, then do "git init" and "git annex init" and then "git annex add ." ?
diff --git a/doc/forum/mistakenly_checked___42__files__42___into_an_annex.__bummer./comment_1_752db25abb647804a1cc12c5b247378a._comment b/doc/forum/mistakenly_checked___42__files__42___into_an_annex.__bummer./comment_1_752db25abb647804a1cc12c5b247378a._comment
new file mode 100644
index 000000000..486d43480
--- /dev/null
+++ b/doc/forum/mistakenly_checked___42__files__42___into_an_annex.__bummer./comment_1_752db25abb647804a1cc12c5b247378a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.49"
+ subject="comment 1"
+ date="2012-12-02T05:41:56Z"
+ content="""
+You can rebase or use git-filter-branch to rewrite history. As long as you don't touch the git-annex branch, git-annex won't care, at all. Have at it!
+
+Your uninit plan would also work.
+"""]]
diff --git a/doc/forum/mistakenly_checked___42__files__42___into_an_annex.__bummer./comment_2_db6f4959c35732f72e7a90bd9f4c665c._comment b/doc/forum/mistakenly_checked___42__files__42___into_an_annex.__bummer./comment_2_db6f4959c35732f72e7a90bd9f4c665c._comment
new file mode 100644
index 000000000..9c7f35a77
--- /dev/null
+++ b/doc/forum/mistakenly_checked___42__files__42___into_an_annex.__bummer./comment_2_db6f4959c35732f72e7a90bd9f4c665c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 2"
+ date="2012-12-03T15:46:48Z"
+ content="""
+Thanks! I ended up going with the uninit plan.
+"""]]
diff --git a/doc/forum/multiple_routes_to_same_repository.mdwn b/doc/forum/multiple_routes_to_same_repository.mdwn
new file mode 100644
index 000000000..a94acac2f
--- /dev/null
+++ b/doc/forum/multiple_routes_to_same_repository.mdwn
@@ -0,0 +1,2 @@
+I am trying to configure the local repo to be connected with remote computer. It can either find this computer on local network using local host name, or go through public IP host where I have ssh tunnel. First confusing thing is, that when setting up remote server, it successfuly establishes connection, but then asks me if the folder should be git or rsync - I believe this step should be skipped if the git repo is already there. Also choosing repository group should be detected from the repo itself.
+But the real problem is that I cannot add the public IP repo at all. Is this a known limitation?
diff --git a/doc/forum/multiple_routes_to_same_repository/comment_1_26c1734d41d5374f18fc688d862d6b8e._comment b/doc/forum/multiple_routes_to_same_repository/comment_1_26c1734d41d5374f18fc688d862d6b8e._comment
new file mode 100644
index 000000000..94eadcd55
--- /dev/null
+++ b/doc/forum/multiple_routes_to_same_repository/comment_1_26c1734d41d5374f18fc688d862d6b8e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmZ9EwisYI1DDev8HXY6zFjPrLKt60-3QI"
+ nickname="Yo"
+ subject="comment 1"
+ date="2013-06-24T12:23:15Z"
+ content="""
+I believe I have a similar set up as you're trying to achieve. What I did was just add a repository using the public domain name only (DDNS). My home router seems to be smart enough to realize the IP the domain name resolves to is its own, so I get gigabit speeds when at home, and I can still access it when I'm not at home.
+"""]]
diff --git a/doc/forum/multiple_routes_to_same_repository/comment_2_d119ab485fb2d5512c15372efdb2327d._comment b/doc/forum/multiple_routes_to_same_repository/comment_2_d119ab485fb2d5512c15372efdb2327d._comment
new file mode 100644
index 000000000..48cae0211
--- /dev/null
+++ b/doc/forum/multiple_routes_to_same_repository/comment_2_d119ab485fb2d5512c15372efdb2327d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.193"
+ subject="comment 2"
+ date="2013-06-25T20:05:46Z"
+ content="""
+I don't see anything that prevents you from adding two repositories that use different names for the same server.
+"""]]
diff --git a/doc/forum/multiple_sym_links___40__for_tagging_photos__41____63__.mdwn b/doc/forum/multiple_sym_links___40__for_tagging_photos__41____63__.mdwn
new file mode 100644
index 000000000..c5c6f3a94
--- /dev/null
+++ b/doc/forum/multiple_sym_links___40__for_tagging_photos__41____63__.mdwn
@@ -0,0 +1,11 @@
+I saw a cool page talking about "tagging" photos by using symlinks: http://www.trueelena.org/computers/articles/photo_management_with_git-annex_and_bash.html
+
+so say I have a photo in git annex, called DSC_3285.JPG, which of course is really a symlink to ../.git/annex/objects/Zk/kj/WORM-s5296770-m1338516288--DSC_3285.JPG/WORM-s5296770-m1338516288--DSC_3285.JPG.
+
+I want to make an additional link to that photo in a directory called tags/.
+
+should I link to the symlink (DSC_3285.JPG), or to the annexed file? (../.git/annex/objects/Zk/kj/WORM-s5296770-m1338516288--DSC_3285.JPG/WORM-s5296770-m1338516288--DSC_3285.JPG)
+
+I might occasionally rename DSC_3285.JPG or edit the photo itself. will the git annex commit hooks update both links, or should I prepare a script to update links in tags/ after I change DSC_3285 or the annexed data?
+
+thank you.
diff --git a/doc/forum/multiple_sym_links___40__for_tagging_photos__41____63__/comment_1_96beb9ea895c80285748adb940b4f57d._comment b/doc/forum/multiple_sym_links___40__for_tagging_photos__41____63__/comment_1_96beb9ea895c80285748adb940b4f57d._comment
new file mode 100644
index 000000000..b4d2433aa
--- /dev/null
+++ b/doc/forum/multiple_sym_links___40__for_tagging_photos__41____63__/comment_1_96beb9ea895c80285748adb940b4f57d._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.236"
+ subject="comment 1"
+ date="2012-09-05T19:56:06Z"
+ content="""
+I'd recommend linking to the annexed file. Which is what `cp -a` does BTW. Then it'll just be a peice of content that is used by more than one filename, which git-annex handles well. However, if you then edited
+one file, git-annex would not update the other link to point to the new content.
+"""]]
diff --git a/doc/forum/multiple_sym_links___40__for_tagging_photos__41____63__/comment_2_985065c1feed9300631dac7a2701f669._comment b/doc/forum/multiple_sym_links___40__for_tagging_photos__41____63__/comment_2_985065c1feed9300631dac7a2701f669._comment
new file mode 100644
index 000000000..a53fe06b5
--- /dev/null
+++ b/doc/forum/multiple_sym_links___40__for_tagging_photos__41____63__/comment_2_985065c1feed9300631dac7a2701f669._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnh0pv5PyOJH8dHB1Ly2rHJM4nvVd17CZ0"
+ nickname="Kevin"
+ subject="comment 2"
+ date="2012-09-05T19:57:36Z"
+ content="""
+Thank you very much! (for your answer, and for git annex)
+"""]]
diff --git a/doc/forum/multiple_urls_for_the_same_UUID.mdwn b/doc/forum/multiple_urls_for_the_same_UUID.mdwn
new file mode 100644
index 000000000..2f8106b59
--- /dev/null
+++ b/doc/forum/multiple_urls_for_the_same_UUID.mdwn
@@ -0,0 +1,26 @@
+I've been doing a sort of experiment but I'm not sure if it's working or, really, how to even tell.
+
+I have two macbooks that are both configured as clients as well as a USB HDD, an rsync endpoint on a home NAS, and a glacier endpoint.
+
+For the purposes of this example, lets call the macbooks "chrissy" and "brodie". Chrissy's was initially configured with a remote for brodie with the url as
+
+ ssh://Brodie.88195848.members.btmm.icloud.com./Users/akraut/Desktop/annex
+
+This allows me to leverage the "Back To My Mac" free IPv6 roaming I get from Apple. Now, occasionally, that dns resolution fails. Since I'm frequently on the same network, I can also use the mDNS address of brodie.local. which is much more reliable.
+
+So my brilliant/terrible idea was to put this in my git config:
+
+ [remote "brodie"]
+ url = ssh://Brodie.88195848.members.btmm.icloud.com./Users/akraut/Desktop/annex
+ fetch = +refs/heads/*:refs/remotes/brodie/*
+ annex-uuid = BF4BCA6D-9252-4B5B-BE12-36DD755FAF4B
+ annex-cost-command = /Users/akraut/Desktop/annex/tools/annex-cost6.sh Brodie.88195848.members.btmm.icloud.com.
+ [remote "brodie-local"]
+ url = ssh://brodie.local./Users/akraut/Desktop/annex
+ fetch = +refs/heads/*:refs/remotes/brodie/*
+ annex-uuid = BF4BCA6D-9252-4B5B-BE12-36DD755FAF4B
+ annex-cost-command = /Users/akraut/Desktop/annex/tools/annex-cost.sh brodie.local.
+
+Is there any reason why I shouldn't do this? Is annex smart enough to know that it can reach the same remote through both urls? Will the cost calculations be considered and the "local" url chosen if it's cost is less than the other?
+
+(I posted the annex-cost.sh stuff at [[forum/Calculating Annex Cost by Ping Times]].)
diff --git a/doc/forum/multiple_urls_for_the_same_UUID/comment_1_de7410d8824a864c4d106c9f1afaec3f._comment b/doc/forum/multiple_urls_for_the_same_UUID/comment_1_de7410d8824a864c4d106c9f1afaec3f._comment
new file mode 100644
index 000000000..c06cf01c3
--- /dev/null
+++ b/doc/forum/multiple_urls_for_the_same_UUID/comment_1_de7410d8824a864c4d106c9f1afaec3f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.6"
+ subject="comment 1"
+ date="2012-12-30T04:19:48Z"
+ content="""
+Yes, this is absolutely supported. If it's trying to `get` a file and it fails to access the first remote, it'll even automatically fall back to using the second. I do similar things with my own remote, for example I have a foo that uses ssh with a foo-local that uses NFS.
+"""]]
diff --git a/doc/forum/multiple_urls_for_the_same_UUID/comment_2_309a86cf7e08448be64357a30d8b56ae._comment b/doc/forum/multiple_urls_for_the_same_UUID/comment_2_309a86cf7e08448be64357a30d8b56ae._comment
new file mode 100644
index 000000000..9d0dc9f66
--- /dev/null
+++ b/doc/forum/multiple_urls_for_the_same_UUID/comment_2_309a86cf7e08448be64357a30d8b56ae._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawln3ckqKx0x_xDZMYwa9Q1bn4I06oWjkog"
+ nickname="Michael"
+ subject="multiple ways to access a special remote?"
+ date="2013-07-10T05:52:28Z"
+ content="""
+The use case is like this: an external USB drive could be accessed both locally (as a special directory remote) or it could be mounted remotely (then it would need to be an rsync special remote).
+Is there a way to handle this?
+
+Failing that, can one switch the same remote from being a directory to an rsync without having to --move all of the content?
+
+Finally, what's the best way to check directory remote's directory= parameter?
+"""]]
diff --git a/doc/forum/multiple_urls_for_the_same_UUID/comment_3_fa97a45fc1392935fd5e0714db999bc2._comment b/doc/forum/multiple_urls_for_the_same_UUID/comment_3_fa97a45fc1392935fd5e0714db999bc2._comment
new file mode 100644
index 000000000..c6f5dfde9
--- /dev/null
+++ b/doc/forum/multiple_urls_for_the_same_UUID/comment_3_fa97a45fc1392935fd5e0714db999bc2._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.235"
+ subject="comment 3"
+ date="2013-07-10T16:38:04Z"
+ content="""
+@Michael, like I said above, this use case is completely supported. That's why git-annex uses UUIDs to uniquely identify repositories, no matter where or how many urls are used for them.
+
+Just set up the remotes you need, and if they end up pointing to the same repository by different routes, git-annex will automatically notice.
+
+---
+
+The directory= parameter used when initializing a directory remote is only used to set up the remote in the .git/config file. It is not stored anywhere else, since the directory could be mounted at different locations on different computers, eg when a drive is moved between computers.
+"""]]
diff --git a/doc/forum/multiple_urls_for_the_same_UUID/comment_4_139178b1ba45b62eec0c89a660c0c81e._comment b/doc/forum/multiple_urls_for_the_same_UUID/comment_4_139178b1ba45b62eec0c89a660c0c81e._comment
new file mode 100644
index 000000000..945aa3b6b
--- /dev/null
+++ b/doc/forum/multiple_urls_for_the_same_UUID/comment_4_139178b1ba45b62eec0c89a660c0c81e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawln3ckqKx0x_xDZMYwa9Q1bn4I06oWjkog"
+ nickname="Michael"
+ subject="comment 4"
+ date="2013-07-10T21:26:06Z"
+ content="""
+Very cool, thanks Joey.
+"""]]
diff --git a/doc/forum/new_microfeatures.mdwn b/doc/forum/new_microfeatures.mdwn
new file mode 100644
index 000000000..bfe44272a
--- /dev/null
+++ b/doc/forum/new_microfeatures.mdwn
@@ -0,0 +1,59 @@
+I'm soliciting ideas for new small features that let git-annex do things that currently have to be done manually or whatever.
+
+Here are a few I've been considering:
+
+---
+
+* --numcopies would be a useful command line switch.
+ > Update: Added. Also allows for things like `git annex drop --numcopies=2` when in a repo that normally needs 3 copies, if you need
+ > to urgently free up space.
+* A way to make `drop` and other commands temporarily trust a given remote, or possibly all remotes.
+
+Combined, this would allow `git annex drop --numcopies=2 --trust=repoa --trust=repob` to remove files that have been replicated out to the other 2 repositories, which could be offline. (Slightly unsafe, but in this case the files are podcasts so not really.)
+
+> Update: done --[[Joey]]
+
+---
+
+[[wishlist:_git-annex_replicate]] suggests some way for git-annex to have the smarts to copy content around on its own to ensure numcopies is satisfied. I'd be satisfied with a `git annex copy --to foo --if-needed-by-numcopies`
+
+ > Contrary to the "basic" solution, I would love to have a git annex distribute which is smart enough to simply distribute all data according to certain rules. My ideal, personal use case during the next holidays where I will have two external disks, several SD cards with 32 GB each and a local disk with 20 GB (yes....) would be:
+
+ cd ~/photos.annex # this repository does not have any objects!
+ git annex inject --bare /path/to/SD/card # this adds softlinks, but does **not** add anything to the index. it would calculate checksums (if enabled) and have to add a temporary location list, though
+ git annex distribute # this checks the config. it would see that my two external disks have a low cost whereas the two remotes have a higher cost.
+ # check numcopies. it's 3
+ # copy to external disk one (cost x)
+ # copy to external disk two (cost x)
+ # copy to remote one (cost x * 2)
+ # remove file from temporary tracking list
+ git annex fsck # everything ok. yay!
+
+Come to think of it, the inject --bare thing is probably not a microfeature. Should I add a new wishlist item for that? -- RichiH
+
+> I've thought about such things before; does not seem really micro and I'm unsure how well it would work, but it would be worth a [[todo]]. --[[Joey]]
+
+>> Update: Done as --auto. --[[Joey]]
+
+---
+
+Along similar lines, it might be nice to have a mode where git-annex tries to fill up a disk up to the `annex.diskreserve` with files, preferring files that have relatively few copies. Then as storage prices continue to fall, new large drives could just be plopped in and git-annex used to fill it up in a way that improves the overall redundancy without needing to manually pick and choose.
+
+> Update: git annex get --auto basically does this; you can tune
+> --numcopies on the fly to make it get more files than needed by the
+> current numcopies setting. --[[Joey]]
+
+---
+
+If a remote could send on received files to another remote, I could use my own local bandwith efficiently while still having my git-annex repos replicate data. -- RichiH
+
+---
+
+Really micro:
+
+ % grep annex-push .git/config
+ annex-push = !git pull && git annex add . && git annex copy . --to origin --fast --quiet && git commit -a -m "$HOST $(date +%F--%H-%M-%S-%Z)" && git push
+ %
+
+-- RichiH
+--[[Joey]]
diff --git a/doc/forum/new_microfeatures/comment_1_058bd517c6fffaf3446b1f5d5be63623._comment b/doc/forum/new_microfeatures/comment_1_058bd517c6fffaf3446b1f5d5be63623._comment
new file mode 100644
index 000000000..84fdd325d
--- /dev/null
+++ b/doc/forum/new_microfeatures/comment_1_058bd517c6fffaf3446b1f5d5be63623._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 1"
+ date="2011-06-01T17:36:50Z"
+ content="""
+I've been longing for an automated way of removing references to a remote assuming I know the exact uuid that I want to remove. i.e. I have lost a portable HDD due to a destructive process, I now want to delete all references to copies of data that was on that disk. Unless this feature exists, I would love to see it implemented.
+"""]]
diff --git a/doc/forum/new_microfeatures/comment_2_41ad904c68e89c85e1fc49c9e9106969._comment b/doc/forum/new_microfeatures/comment_2_41ad904c68e89c85e1fc49c9e9106969._comment
new file mode 100644
index 000000000..4451e20ba
--- /dev/null
+++ b/doc/forum/new_microfeatures/comment_2_41ad904c68e89c85e1fc49c9e9106969._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 2"
+ date="2011-06-01T20:24:33Z"
+ content="""
+@jimmy [[walkthrough/what_to_do_when_you_lose_a_repository]].. I have not seen a convincing argument that removing the location tracking data entirely serves any purpose
+"""]]
diff --git a/doc/forum/new_microfeatures/comment_3_a1a9347b5bc517f2a89a8b292c3f8517._comment b/doc/forum/new_microfeatures/comment_3_a1a9347b5bc517f2a89a8b292c3f8517._comment
new file mode 100644
index 000000000..4bb3aa684
--- /dev/null
+++ b/doc/forum/new_microfeatures/comment_3_a1a9347b5bc517f2a89a8b292c3f8517._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnpdM9F8VbtQ_H5PaPMpGSxPe_d5L1eJ6w"
+ nickname="Rafaël"
+ subject="git annex unlock --readonly"
+ date="2011-06-02T11:34:42Z"
+ content="""
+This was already asked [here](http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=606577), but I have a use case where I need to unlock with the files being hardlinked instead of copied (my fs does not support CoW), even though 'git annex lock' is now much faster ;-) . The idea is that 1) I want the external world see my repo \"as if\" it wasn't annexed (because of its own limitation to deal with soft links), and 2) I know what I do, and am sure that files won't be written to but only read.
+
+My case is: the repo contains a snapshot A1 of a certain remote directory. Later I want to rsync this dir into a new snapshot A2. Of course, I want to transfer only new or changed files, with the --copy-dest=A1 (or --compare-dest) rsync's options. Unfortunately, rsync won't recognize soft-links from git-annex, and will re-transfer everything.
+
+
+Maybe I'm overusing git-annex ;-) but still, I find it is a legitimate use case, and even though there are workarounds (I don't even remember what I had to do), it would be much more straightforward to have 'git annex unlock --readonly' (or '--readonly-unsafe'?), ... or have rsync take soft-links into account, but I did not see the author ask for microfeatures ideas :) (it was discussed, and only some convoluted workarounds were proposed). Thanks.
+
+
+"""]]
diff --git a/doc/forum/new_microfeatures/comment_4_5a6786dc52382fff5cc42fdb05770196._comment b/doc/forum/new_microfeatures/comment_4_5a6786dc52382fff5cc42fdb05770196._comment
new file mode 100644
index 000000000..cc98109e6
--- /dev/null
+++ b/doc/forum/new_microfeatures/comment_4_5a6786dc52382fff5cc42fdb05770196._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnpdM9F8VbtQ_H5PaPMpGSxPe_d5L1eJ6w"
+ nickname="Rafaël"
+ subject="git annex unused"
+ date="2011-06-02T11:55:58Z"
+ content="""
+Before dropping unsused items, sometimes I want to check the content of the files manually.
+But currently, from e.g. a sha1 key, I don't know how to find the corresponding file, except with
+'find .git/annex/objects -type f -name 'SHA1-s1678--70....', wich is too slow (I'm in the case where \"git log --stat -S'KEY'\"
+won't work, either because it is too slow or it was never commited). By the way,
+is it documented somewhere how to determine the 2 (nested) sub-directories in which a given
+(by name) object is located?
+
+So I would like 'git-annex unused' be able to give me the list of *paths* to the unused items.
+Also, I would really appreciate a command like 'git annex unused --log NUMBER [NUMBER2...]' which would do for me the suggested command
+\"git log --stat -S'KEY'\", where NUMBER is from the 'git annex unused' output.
+Thanks.
+"""]]
diff --git a/doc/forum/new_microfeatures/comment_5_3c627d275586ff499d928a8f8136babf._comment b/doc/forum/new_microfeatures/comment_5_3c627d275586ff499d928a8f8136babf._comment
new file mode 100644
index 000000000..f7361f5d1
--- /dev/null
+++ b/doc/forum/new_microfeatures/comment_5_3c627d275586ff499d928a8f8136babf._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnpdM9F8VbtQ_H5PaPMpGSxPe_d5L1eJ6w"
+ nickname="Rafaël"
+ subject="git annex unused"
+ date="2011-06-02T19:51:49Z"
+ content="""
+ps: concerning the command 'find .git/annex/objects -type f -name 'SHA1-s1678--70....' from my previous comment, it is \"significantly\" faster to search for the containing directory which have the same name: 'find .git/annex/objects -maxdepth 2 -mindepth 2 -type d -name 'SHA1-s1678--70....'. I am just curious: what is the need to have each file object in its own directory, itself nested under two more sub-directories?
+"""]]
diff --git a/doc/forum/new_microfeatures/comment_6_31ea08c008500560c0b96c6601bc6362._comment b/doc/forum/new_microfeatures/comment_6_31ea08c008500560c0b96c6601bc6362._comment
new file mode 100644
index 000000000..868e9677c
--- /dev/null
+++ b/doc/forum/new_microfeatures/comment_6_31ea08c008500560c0b96c6601bc6362._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnpdM9F8VbtQ_H5PaPMpGSxPe_d5L1eJ6w"
+ nickname="Rafaël"
+ subject="git annex fetch"
+ date="2011-07-03T14:39:41Z"
+ content="""
+I'm not sure it is worth adding a command for such a small feature, but I would certainly use it: having something like \"git annex fetch remote\" do \"git fetch remote && git annex copy --from=remote\", and \"git annex push remote\" do \"git push remote && git annex copy --to=remote\". And maybe the same for a pull operation?
+"""]]
diff --git a/doc/forum/new_microfeatures/comment_7_94045b9078b1fff877933b012d1b49e2._comment b/doc/forum/new_microfeatures/comment_7_94045b9078b1fff877933b012d1b49e2._comment
new file mode 100644
index 000000000..e39e16232
--- /dev/null
+++ b/doc/forum/new_microfeatures/comment_7_94045b9078b1fff877933b012d1b49e2._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnpdM9F8VbtQ_H5PaPMpGSxPe_d5L1eJ6w"
+ nickname="Rafaël"
+ subject="git annex fetch"
+ date="2011-07-03T17:57:00Z"
+ content="""
+My last comment is a bit confused. The \"git fetch\" command allows to get all the information from a remote, and it is then possible to merge while being offline (without access to the remote). I would like a \"git annex fetch remote\" command to be able to get all annexed files from remote, so that if I later merge with remote, all annexed files are already here. And \"git annex fetch\" could (optionally) call \"git fetch\" before getting the files.
+
+It seems also that in my last post, I should have written \"git annex get --from=remote\" instead of \"git annex copy --from=remote\", because \"annex copy --from\" copies all files, even if the local repo already have them (is this the case? if yes, when is it useful?)
+"""]]
diff --git a/doc/forum/nntp__47__usenet_special_remote.mdwn b/doc/forum/nntp__47__usenet_special_remote.mdwn
new file mode 100644
index 000000000..86efa48cf
--- /dev/null
+++ b/doc/forum/nntp__47__usenet_special_remote.mdwn
@@ -0,0 +1,18 @@
+Over the last few weeks i've been working on a seperate python nntp project. But decided that it would be fun to make it usable with git-annex.
+
+The code is almost complete. One major feature left(make it usable without a mysql/sqlite database, and without fetching headers). And of course a lot of bugfixes.
+
+I'm wondering if there is any interest in this special remote hook.
+
+The thought is, buy unlimited usenet account, and you can have a git-annex repository without any upper size limit. You want 100GB, well that'll be 10$ a month, want 100000GB, well that'll be 10$ a month.
+
+Of course there are plenty of caveats(retention on server, it is doubtfull the data will stay up for more than 4 years.). Because the code is in python3 i had to use a lot of external tools (uudeview, par2, ydecode/yydecode) and parse their output. Which is a horrid horrid solution. Since the code is nearing "beta" stage i might see if i can improve on that(possibly with ctypes), if there is any interest.
+
+Currently working on freebsd, ubuntu, debian, mac os x(10.7, not tested in 10.8)
+
+The last feature to be done (and this is UUUUUGLY) is to make it get nzb files from a source like this: http://nzbindex.nl/search/?q=GPGHMACSHA (yes, that is my git-annex repo) instead of from a mysql database.
+
+So, this is a call to see if anyone is interested, and if anyone proficient in *NIX want to test it out.
+
+Sincerely
+Tobias
diff --git a/doc/forum/nntp__47__usenet_special_remote/comment_1_171a0b95b1f95cfd82073e88bdefaab9._comment b/doc/forum/nntp__47__usenet_special_remote/comment_1_171a0b95b1f95cfd82073e88bdefaab9._comment
new file mode 100644
index 000000000..ff14f6f2e
--- /dev/null
+++ b/doc/forum/nntp__47__usenet_special_remote/comment_1_171a0b95b1f95cfd82073e88bdefaab9._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-05-19T20:49:06Z"
+ content="""
+I think it's a neat idea. I can't see using it for my own data due to retention, but if I had a use case where I wanted to spread data around and didn't care if it vanished after X months, I can see using it.
+
+I think you should publish the details, if getting it to a state others can use is not too much work,
+"""]]
diff --git a/doc/forum/nntp__47__usenet_special_remote/comment_2_48736ed17c98ffcfb13ec00b901b2dd6._comment b/doc/forum/nntp__47__usenet_special_remote/comment_2_48736ed17c98ffcfb13ec00b901b2dd6._comment
new file mode 100644
index 000000000..90b264f7b
--- /dev/null
+++ b/doc/forum/nntp__47__usenet_special_remote/comment_2_48736ed17c98ffcfb13ec00b901b2dd6._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmkBwMWvNKZZCge_YqobCSILPMeK6xbFw8"
+ nickname="develop"
+ subject="comment 2"
+ date="2013-09-11T07:46:07Z"
+ content="""
+Only played a tiny bit with this since the initial post.
+
+I've decided that sql backend should be dropped entirely. Mostly the SQL backend was there because the code does something else entirely, and this was just a test.
+
+But since there has been no interest it will probably take ages before i actually get this finished :)
+
+"""]]
diff --git a/doc/forum/non-bare_repo_on_cloud_remote.mdwn b/doc/forum/non-bare_repo_on_cloud_remote.mdwn
new file mode 100644
index 000000000..3949e18da
--- /dev/null
+++ b/doc/forum/non-bare_repo_on_cloud_remote.mdwn
@@ -0,0 +1,6 @@
+Hi,
+
+I wondered if it's possible to have a non-bare repo on a cloud remote. I want to have some sort of Dropbox-like workflow were I simply put stuff into a directory on my drive and it gets synced via SSH to a central VPS so I can also always access it via HTTP, for example.
+
+Regards,
+Lukas
diff --git a/doc/forum/non-bare_repo_on_cloud_remote/comment_1_da0c023af7c78f1ef1cfe1143a900a9f._comment b/doc/forum/non-bare_repo_on_cloud_remote/comment_1_da0c023af7c78f1ef1cfe1143a900a9f._comment
new file mode 100644
index 000000000..17476db0a
--- /dev/null
+++ b/doc/forum/non-bare_repo_on_cloud_remote/comment_1_da0c023af7c78f1ef1cfe1143a900a9f._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.1.10"
+ subject="comment 1"
+ date="2013-07-22T22:04:53Z"
+ content="""
+Sure you can.. That's how <http://downloads.kitenet.net/> works, which is where people download git-annex builds from!
+
+[[tips/setup_a_public_repository_on_a_web_site]]
+"""]]
diff --git a/doc/forum/non-bare_repo_on_cloud_remote/comment_2_71baea93f6caaf7b81a9ac00bee91e5e._comment b/doc/forum/non-bare_repo_on_cloud_remote/comment_2_71baea93f6caaf7b81a9ac00bee91e5e._comment
new file mode 100644
index 000000000..145c57120
--- /dev/null
+++ b/doc/forum/non-bare_repo_on_cloud_remote/comment_2_71baea93f6caaf7b81a9ac00bee91e5e._comment
@@ -0,0 +1,67 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawniayrgSdVLUc3c6bf93VbO-_HT4hzxmyo"
+ nickname="Tobias"
+ subject="comment 2"
+ date="2013-08-08T19:05:07Z"
+ content="""
+Seems that I don't get it... Here is what I did:
+
+First, I create a new repo with the assistant on `user@laptop ~/temp/annex-test`, then:
+
+ user@laptop ~/temp/annex-test % echo test1 > test1
+ user@laptop ~/temp/annex-test % echo test2 > test2
+
+ user@server ~/tmp % mkdir annex-test
+ user@server ~/tmp % cd annex-test
+ user@server ~/tmp/annex-test % git init
+ Initialized empty Git repository in /home/tobru/tmp/annex-test/.git/
+ user@server ~/tmp/annex-test % git annex init
+ init ok
+ (Recording state in git...)
+ user@server ~/tmp/annex-test % mv .git/hooks/post-update.sample .git/hooks/post-update
+ user@server ~/tmp/annex-test % cat .git/hooks/post-update
+ #!/bin/sh
+ #
+ # An example hook script to prepare a packed repository for use over
+ # dumb transports.
+ #
+ # To enable this hook, rename this file to \"post-update\".
+
+ exec git update-server-info
+ user@server ~/tmp/annex-test % chmod +x .git/hooks/post-update
+ user@server ~/tmp/annex-test % echo '#!/bin/sh\ngit annex merge' > .git/hooks/post-receive
+ user@server ~/tmp/annex-test % chmod +x .git/hooks/post-receive
+
+ user@laptop ~/temp/annex-test % git remote add server ssh://user@server/home/tobru/tmp/annex-test
+ user@laptop ~/temp/annex-test % git annex assistant --stop
+ user@laptop ~/temp/annex-test % git annex sync
+ commit
+ ok
+ pull server
+ warning: no common commits
+ remote: Counting objects: 5, done.
+ remote: Compressing objects: 100% (3/3), done.
+ remote: Total 5 (delta 1), reused 0 (delta 0)
+ Unpacking objects: 100% (5/5), done.
+ From ssh://server.tobru.local/home/tobru/tmp/annex-test
+ * [new branch] git-annex -> server/git-annex
+ ok
+ (merging server/git-annex into git-annex...)
+ (Recording state in git...)
+ push server
+ Counting objects: 27, done.
+ Delta compression using up to 4 threads.
+ Compressing objects: 100% (20/20), done.
+ Writing objects: 100% (25/25), 2.36 KiB, done.
+ Total 25 (delta 2), reused 0 (delta 0)
+ remote: merge git-annex (merging synced/git-annex into git-annex...)
+ remote: ok
+ To ssh://tobru@server.tobru.local/home/tobru/tmp/annex-test
+ * [new branch] git-annex -> synced/git-annex
+ * [new branch] master -> synced/master
+ ok
+ user@laptop ~/temp/annex-test % git annex assistant
+
+Now I expect the files `test1` and `test2` to be at `user@server ~/tmp/annex-test`. But they are not displayed.
+What am I doing wrong? The main thing I wan't to achieve: Push the files from `laptop` to `server` without adding `laptop` as remote on the server.
+"""]]
diff --git a/doc/forum/not_getting_file_contents.mdwn b/doc/forum/not_getting_file_contents.mdwn
new file mode 100644
index 000000000..23150216d
--- /dev/null
+++ b/doc/forum/not_getting_file_contents.mdwn
@@ -0,0 +1 @@
+I have 2 computers successfully exchanging files, but the contexts are incomplete. Used text files, documents, mp3s as tests. Both computers report in the webapp that they are synched and file names are there. But file sizes are wrong by 75% less and contents are unusable. Is there something in the config? Both machines on LinuxMint 13.
diff --git a/doc/forum/not_getting_file_contents/comment_1_4a0f7f4de9c9bc4d13db033cb75d20af._comment b/doc/forum/not_getting_file_contents/comment_1_4a0f7f4de9c9bc4d13db033cb75d20af._comment
new file mode 100644
index 000000000..e03ec333a
--- /dev/null
+++ b/doc/forum/not_getting_file_contents/comment_1_4a0f7f4de9c9bc4d13db033cb75d20af._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.235"
+ subject="comment 1"
+ date="2013-07-11T16:06:59Z"
+ content="""
+That certainly shouldn't be happening!
+
+Are these computers syncing via local pairing, or are you using a transfer remote, and if so, which one?
+"""]]
diff --git a/doc/forum/not_getting_file_contents/comment_2_dc7403e1b551552f9fd00da6a1453570._comment b/doc/forum/not_getting_file_contents/comment_2_dc7403e1b551552f9fd00da6a1453570._comment
new file mode 100644
index 000000000..499176b01
--- /dev/null
+++ b/doc/forum/not_getting_file_contents/comment_2_dc7403e1b551552f9fd00da6a1453570._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="trilobite"
+ ip="71.17.134.14"
+ subject="comment 2"
+ date="2013-07-11T23:23:41Z"
+ content="""
+I did this with local synch in home lan. Filenames do travel both directions. Just not contents. They are identifed as symlinks rather than files.
+"""]]
diff --git a/doc/forum/one_annex_versus_many_annexes__63__.mdwn b/doc/forum/one_annex_versus_many_annexes__63__.mdwn
new file mode 100644
index 000000000..cafe2aa9f
--- /dev/null
+++ b/doc/forum/one_annex_versus_many_annexes__63__.mdwn
@@ -0,0 +1,10 @@
+I'm curious how other people are using git-annex:
+
+ * A single annex containing everything they want to keep track of (albeit with some files only available in some remotes).
+ * Several annexes for different purposes.
+
+I'm mostly asking because I don't want to get too far into using git-annex without thinking clearly about which is the most suitable choice for me. At present I have things split into two annexes, one for things I really wouldn't want to lose (and some of which are somewhat private), and another for comparatively throwaway items. However, given the possibility of setting different annex.numcopies on different file globs or directories, it seems like it might be kind of silly to make my life more complicated by having more than one annex.
+
+Primarily, I'm curious if there are some implications of the decision that I haven't considered. It seems like an obvious point that one would want different annexes is if they're used in distinctly different security-level environments (e.g. I'm happy to copy my FLAC (music) files over to my work computer which lives at the office, but I wouldn't want to copy personal financial documents - or even the filenames - there.)
+
+-Mike
diff --git a/doc/forum/one_or_many_annexes__63__.mdwn b/doc/forum/one_or_many_annexes__63__.mdwn
new file mode 100644
index 000000000..57b311c18
--- /dev/null
+++ b/doc/forum/one_or_many_annexes__63__.mdwn
@@ -0,0 +1,7 @@
+Just a question about other peoples' annex usage. I've got one uber-annex (in ~/annex of course) where I keep ALL THE THINGS, movies, music, pictures, whatever.
+
+It's very big, of course. And I worry about doing anything unusual with it (like trying out direct mode) because, hey, that's all my stuff.
+
+Like, just now, I tried flipping it into direct mode, and a handful of files stayed symlinks, which weirded me out. (Maybe because I had the assistant running while I switched it, and that caused chaos?) Then I flipped it back to indirect, and a bunch of files were left un-tracked, as real files rather than links! I kind of freaked out, and did a big "git annex add" to add them all back. I haven't left a bug report because it's not something I want to try again experimentally to reproduce, I just want my repo back, you know?
+
+Anyways, this kind of thing might not happen if I kept multiple small repos. I was wondering if anybody else worked that way, and what advantages/disadvantages you've found compared to having one super-repo.
diff --git a/doc/forum/one_or_many_annexes__63__/comment_1_656d96011801d67a45b0b3bb3d70fa63._comment b/doc/forum/one_or_many_annexes__63__/comment_1_656d96011801d67a45b0b3bb3d70fa63._comment
new file mode 100644
index 000000000..240f9868f
--- /dev/null
+++ b/doc/forum/one_or_many_annexes__63__/comment_1_656d96011801d67a45b0b3bb3d70fa63._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn7gQ1zZDdWhXy9H51W2krZYShNmKL3qfM"
+ nickname="Karsten"
+ subject="comment 1"
+ date="2013-01-21T21:25:12Z"
+ content="""
+That's an interesting question. Personally, I have two annexes. One for my \"digital library\": movies, music, ebooks, downloads, everything I want to keep but was not created by me. I don't want to loose them because getting them back would be expensive and cumbersome. The other is my personal archive for Photos and Videos I've taken, which are valuable as they contain many memories which would be impossible to recreate if lost. With the first one, I'm experimenting quite a lot, with the second one I'm very conservative. Hope that helps.
+"""]]
diff --git a/doc/forum/performance_and_multiple_replication_problems.mdwn b/doc/forum/performance_and_multiple_replication_problems.mdwn
new file mode 100644
index 000000000..7f2f90fdd
--- /dev/null
+++ b/doc/forum/performance_and_multiple_replication_problems.mdwn
@@ -0,0 +1,17 @@
+Hi,
+
+I just was setting um my git-annex repository and started to sync my whole stuff in it.
+
+Background: I have choosen git-annex to sync my whole stuff (pictures, mp3s, documents, etc) between my pc, notebook and a home-server
+
+My Problems:
+1) When I'm starting the git-annex deamon, the "Performing startup scan" message occurs for hours
+2) git-annex synchronizes folders from the server which already on my pc, and that every time I restart the deamon on client
+
+My Questions:
+For 1) is git-annex when running one repository suitable to manage > 100gb and > 50000 files?
+For 2) do I have to wait until every tasks are completed (everything is committed) to get rid of multiple downloads of the same folders/files
+3) what is the best schema to sync between >2 devices should I use a Mesh or Star Schema (where my server is in the middle)
+
+Thank You in advance!
+Regards J
diff --git a/doc/forum/performance_and_multiple_replication_problems/comment_1_a2cdf1a4840f099f6bc941fd8de966c7._comment b/doc/forum/performance_and_multiple_replication_problems/comment_1_a2cdf1a4840f099f6bc941fd8de966c7._comment
new file mode 100644
index 000000000..aab0ec17f
--- /dev/null
+++ b/doc/forum/performance_and_multiple_replication_problems/comment_1_a2cdf1a4840f099f6bc941fd8de966c7._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-06-11T15:06:58Z"
+ content="""
+It sounds like you are using git-annex to sync a *lot* of files. The startup scan is a basic check that there are no new, deleted, or modified files since the last time it ran. This requires a little work, like statting the files, but won't take long for reasonable numbers of files.
+
+The size of files doesn't affect the length of the scan. I have a repository with on the order of 50k files, and the startup scan takes only a few minutes. One thing that could matter is that my repository is in indirect mode. Direct mode is less efficient. You could try to switch your repository to indirect mode: `git annex indirect` (you can always switch back: `git annex direct`)
+
+It would be possible to disable that scan, but at the expense of not being able to sync changes made while git-annex is not running. There's also a trick you can use: Start the assistant running in a subdirectory and it will only scan that subdirectory (it will only notice new files in that subdirectory too..)
+
+I don't quite understand what you mean with problem #2. If files were repeatedly being uploaded or downloaded, that have already been sent, that would be a bug. Please file a bug report with full debug logs if that is the case.
+
+Which topology is best? I think the best way is to start with the one you like, and if it doesn't work well, add more links between repositories. A star topology will certainly work ok. A mesh can work ok but can be hard to maintain.
+"""]]
diff --git a/doc/forum/performance_and_multiple_replication_problems/comment_2_e65b360706c66ede6e0e841b2ebbbfbc._comment b/doc/forum/performance_and_multiple_replication_problems/comment_2_e65b360706c66ede6e0e841b2ebbbfbc._comment
new file mode 100644
index 000000000..3ce2447bc
--- /dev/null
+++ b/doc/forum/performance_and_multiple_replication_problems/comment_2_e65b360706c66ede6e0e841b2ebbbfbc._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/bBy7WkgQicYHIiiyj.Vm0TcMbxi2quzbPFef#6f9f7"
+ nickname="Frederik Vanrenterghem"
+ subject="comment 2"
+ date="2013-06-12T00:47:21Z"
+ content="""
+I have witnessed that second problem as well, to the point where I've stopped autostarting (and hence using) git annex for the moment. I'll try to get some debugging data.
+"""]]
diff --git a/doc/forum/performance_improvement:_git_on_ssd__44___annex_on_spindle_disk.mdwn b/doc/forum/performance_improvement:_git_on_ssd__44___annex_on_spindle_disk.mdwn
new file mode 100644
index 000000000..f70c12702
--- /dev/null
+++ b/doc/forum/performance_improvement:_git_on_ssd__44___annex_on_spindle_disk.mdwn
@@ -0,0 +1,12 @@
+This works with bind-mount, I might try with softlinks as well.
+
+Going through git's data on push/pull can take ages on a spindle disk even
+if the repo is rather small in size. This is especially true if you are
+used to ssd speeds, but ssd storage is expensive. Storing the annex objects
+on a cheap spindle disk and everything else on a ssd makes things a _lot_
+faster.
+
+> Update: git-annex supports `.git/annex/` being moved to a different disk
+> than the rest of the repisitory, but does *not* support individual
+> subdirectories, like `.git/annex/objects/` being on a different disk
+> than the main `.git/annex/` directory. --[[Joey]]
diff --git a/doc/forum/performance_improvement:_git_on_ssd__44___annex_on_spindle_disk/comment_1_b3f22f9be02bc4f2d5a121db3d753ff5._comment b/doc/forum/performance_improvement:_git_on_ssd__44___annex_on_spindle_disk/comment_1_b3f22f9be02bc4f2d5a121db3d753ff5._comment
new file mode 100644
index 000000000..124993bcf
--- /dev/null
+++ b/doc/forum/performance_improvement:_git_on_ssd__44___annex_on_spindle_disk/comment_1_b3f22f9be02bc4f2d5a121db3d753ff5._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-04-02T17:48:29Z"
+ content="""
+Either option should work fine, but git gc --aggressive will probably avoid most of git's seeking.
+"""]]
diff --git a/doc/forum/performance_improvement:_git_on_ssd__44___annex_on_spindle_disk/comment_2_f94abce32ef818176b42a3cc860691ae._comment b/doc/forum/performance_improvement:_git_on_ssd__44___annex_on_spindle_disk/comment_2_f94abce32ef818176b42a3cc860691ae._comment
new file mode 100644
index 000000000..eddc8c631
--- /dev/null
+++ b/doc/forum/performance_improvement:_git_on_ssd__44___annex_on_spindle_disk/comment_2_f94abce32ef818176b42a3cc860691ae._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 2"
+ date="2011-04-02T21:34:24Z"
+ content="""
+I'll give it a try as soon as I get rid of this:
+
+ % git annex fsck
+fatal: index file smaller than expected
+fatal: index file smaller than expected
+ % git status
+fatal: index file smaller than expected
+ %
+
+And no, I am not sure where that is coming from all of a sudden... (it might have to do with a hard lockup of the whole system due to a faulty hdd I tested, but I didn't do anything to it for ages before that lock-up. So meh. Also, this is prolly off topic in here)
+
+
+Richard
+"""]]
diff --git a/doc/forum/performance_improvement:_git_on_ssd__44___annex_on_spindle_disk/comment_3_0c8e77fe248e00bd990d568623e5a5c9._comment b/doc/forum/performance_improvement:_git_on_ssd__44___annex_on_spindle_disk/comment_3_0c8e77fe248e00bd990d568623e5a5c9._comment
new file mode 100644
index 000000000..fc29236c6
--- /dev/null
+++ b/doc/forum/performance_improvement:_git_on_ssd__44___annex_on_spindle_disk/comment_3_0c8e77fe248e00bd990d568623e5a5c9._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 3"
+ date="2011-04-03T01:48:57Z"
+ content="""
+For future reference, git can recover from a corrupted index file with `rm .git/index; git reset --mixed`.
+
+Of course, you lose any staged changes that were in the old index file, and may need to re-stage some files.
+"""]]
diff --git a/doc/forum/performance_improvement:_git_on_ssd__44___annex_on_spindle_disk/comment_4_4b7e8f9521d61900d9ad418e74808ffb._comment b/doc/forum/performance_improvement:_git_on_ssd__44___annex_on_spindle_disk/comment_4_4b7e8f9521d61900d9ad418e74808ffb._comment
new file mode 100644
index 000000000..ec0f88d13
--- /dev/null
+++ b/doc/forum/performance_improvement:_git_on_ssd__44___annex_on_spindle_disk/comment_4_4b7e8f9521d61900d9ad418e74808ffb._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 4"
+ date="2011-04-03T09:03:22Z"
+ content="""
+Thanks a lot. I tried various howtos around the net, but none of them worked; yours did. (I tried it in one of the copies of the broken repo which I keep around for obvious reasons).
+"""]]
diff --git a/doc/forum/performance_improvement:_git_on_ssd__44___annex_on_spindle_disk/comment_5_7abbbe7db3988a2d239d11b0a4c597e7._comment b/doc/forum/performance_improvement:_git_on_ssd__44___annex_on_spindle_disk/comment_5_7abbbe7db3988a2d239d11b0a4c597e7._comment
new file mode 100644
index 000000000..651fc8144
--- /dev/null
+++ b/doc/forum/performance_improvement:_git_on_ssd__44___annex_on_spindle_disk/comment_5_7abbbe7db3988a2d239d11b0a4c597e7._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="stoile"
+ ip="2a01:198:242:0:219:66ff:fef2:c021"
+ subject="Error with .git/annex as a symlink"
+ date="2013-11-16T12:20:58Z"
+ content="""
+I had my git annex directory on a ssd and .git/annex on a hdd (using a symlink). I got errors when adding files because a move failed. I forgot to copy the error message. When I had .git/annex/objects on a hdd, everything worked as expected, there were no problems.
+
+So what exactly will go wrong if I only have this one subdirectory on another filesystem?
+"""]]
diff --git a/doc/forum/performance_improvement:_git_on_ssd__44___annex_on_spindle_disk/comment_6_46bd45fdc25d9c583f4ebe3a9730ab9f._comment b/doc/forum/performance_improvement:_git_on_ssd__44___annex_on_spindle_disk/comment_6_46bd45fdc25d9c583f4ebe3a9730ab9f._comment
new file mode 100644
index 000000000..0c0e3e495
--- /dev/null
+++ b/doc/forum/performance_improvement:_git_on_ssd__44___annex_on_spindle_disk/comment_6_46bd45fdc25d9c583f4ebe3a9730ab9f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="stoile"
+ ip="2a01:198:242:0:219:66ff:fef2:c021"
+ subject="Bug report answering my question"
+ date="2013-11-17T10:28:40Z"
+ content="""
+My question was answered in <http://git-annex.branchable.com/bugs/not_possible_to_have_annex_on_a_separate_filesystem/>.
+"""]]
diff --git a/doc/forum/post-copy__47__sync_hook.mdwn b/doc/forum/post-copy__47__sync_hook.mdwn
new file mode 100644
index 000000000..05fbc0b29
--- /dev/null
+++ b/doc/forum/post-copy__47__sync_hook.mdwn
@@ -0,0 +1,14 @@
+Hi,
+
+I have the following setup:
+- normal git repository with website code.
+- git annex repository to hold large set of binary data (pdfs, flashmovies, etc) that belongs to the site.
+
+I use git annex so I (and other developers) don't need to copy 1.4Gb+ of binary data for every working copy. (Data that is mostly left untouched.) Using git annex copy --to=origin I can simply only add new additions to this media/binary repository, without first pulling all the data. So far so good.
+
+When commits are pushed to a certain branch on the normal git repository, a post-receive hook exports (GIT_WORK_TREE=/data/site/ git checkout $branch -f) the updated repository to an apache documentroot. Thereby updating the staging server of the website.
+
+My question is, how can I do the same thing for my git annex repository? Since post-receive fires on receiving the annex hashes, and not the actual files. Those are rsynced, and I cannot find a way to trigger an action after all files are copied by git annex via rsync.
+
+Any tips?
+
diff --git a/doc/forum/post-copy__47__sync_hook/comment_1_c8322d4b9bbf5eac80b48c312a42fbcf._comment b/doc/forum/post-copy__47__sync_hook/comment_1_c8322d4b9bbf5eac80b48c312a42fbcf._comment
new file mode 100644
index 000000000..04a6f4668
--- /dev/null
+++ b/doc/forum/post-copy__47__sync_hook/comment_1_c8322d4b9bbf5eac80b48c312a42fbcf._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2012-03-14T16:23:25Z"
+ content="""
+I've made git-annex-shell run the git `hooks/annex-content` after content is received or dropped.
+
+Note that the clients need to be running at least git-annex version 3.20120227 , which runs git-annex-shell commit, which runs the hook.
+
+"""]]
diff --git a/doc/forum/preferred_content.mdwn b/doc/forum/preferred_content.mdwn
new file mode 100644
index 000000000..b4c215328
--- /dev/null
+++ b/doc/forum/preferred_content.mdwn
@@ -0,0 +1,11 @@
+Hello all,
+
+I'm trying to use "preferred content" with git-annex but I suspect that my version doesn't provide it.
+
+I'm using Debian "wheezy" that packs git-annex 3.20120629.
+
+I appreciate any help you can give.
+
+Thanks.
+
+Zaka.
diff --git a/doc/forum/preferred_content/comment_1_9c9e5f2ee5ae4d8459358ad16f879ef1._comment b/doc/forum/preferred_content/comment_1_9c9e5f2ee5ae4d8459358ad16f879ef1._comment
new file mode 100644
index 000000000..24de5840b
--- /dev/null
+++ b/doc/forum/preferred_content/comment_1_9c9e5f2ee5ae4d8459358ad16f879ef1._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 1"
+ date="2013-11-07T18:38:22Z"
+ content="""
+The first version of git-annex to support preferred content settings was 3.20121009.
+
+There is a quite up-to-date backport available for Debian stable.
+"""]]
diff --git a/doc/forum/preferred_content_settings_for_multiple_symlinks.mdwn b/doc/forum/preferred_content_settings_for_multiple_symlinks.mdwn
new file mode 100644
index 000000000..3c67a93a5
--- /dev/null
+++ b/doc/forum/preferred_content_settings_for_multiple_symlinks.mdwn
@@ -0,0 +1,7 @@
+I have my music library in `music/` and some really old files I recently added in `reallyold/`. There are some MP3s in the really old files and some are the same as my library, so of course git annex is only keeping one copy. Now, I have an rsync remote, `ma`, which prefers content from `music/` but doesn't want anything from `reallyold/`. So while right now it is trying to drop stuff, I suspect at some point that it will try to re-add them in virtue of being in `music/`, as I've got a loop.
+
+I want to eliminate this by using the present keyword to disable dropping for stuff in `reallyold/` and `music/`. Here is my attempt, which doesn't work--I am hoping someone can spot what's wrong.
+
+ (present and include=music/*) or (present and include=reallyold/*) or (exclude=reallyold/* and exclude=video/* and exclude= ...)
+
+Note that music is included by virtue of not being excluded so it should satisfy the third disjunct. Thanks.
diff --git a/doc/forum/preferred_content_settings_for_multiple_symlinks/comment_1_70da012d96ab576151fe3e081ef905d1._comment b/doc/forum/preferred_content_settings_for_multiple_symlinks/comment_1_70da012d96ab576151fe3e081ef905d1._comment
new file mode 100644
index 000000000..b5fbd345e
--- /dev/null
+++ b/doc/forum/preferred_content_settings_for_multiple_symlinks/comment_1_70da012d96ab576151fe3e081ef905d1._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.210"
+ subject="Ever figure this out?"
+ date="2013-02-24T22:00:40Z"
+ content="""
+I find it's useful, when stuck on this kind of thing, to run `git annex find` at the command line passing it parts of the expression and making sure it works, and gradually building up to the complete expression.
+
+You have to do some conversion due to differences between command line and preferred content expression format. For example `git annex find -\( --in here --and --include \"music/*\" -\)`
+"""]]
diff --git a/doc/forum/preferred_content_settings_for_multiple_symlinks/comment_2_ccea74d8b5a4de1f3cd1f6da6694ae0e._comment b/doc/forum/preferred_content_settings_for_multiple_symlinks/comment_2_ccea74d8b5a4de1f3cd1f6da6694ae0e._comment
new file mode 100644
index 000000000..09b9d8564
--- /dev/null
+++ b/doc/forum/preferred_content_settings_for_multiple_symlinks/comment_2_ccea74d8b5a4de1f3cd1f6da6694ae0e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="spwhitton"
+ ip="82.36.235.9"
+ subject="comment 2"
+ date="2013-03-12T09:34:08Z"
+ content="""
+Thanks for the tip--I will definitely make another attempt at some point.
+"""]]
diff --git a/doc/forum/preferred_content_settings_for_multiple_symlinks/comment_3_fab70c642d5aaf26de05270860281030._comment b/doc/forum/preferred_content_settings_for_multiple_symlinks/comment_3_fab70c642d5aaf26de05270860281030._comment
new file mode 100644
index 000000000..12c49a89c
--- /dev/null
+++ b/doc/forum/preferred_content_settings_for_multiple_symlinks/comment_3_fab70c642d5aaf26de05270860281030._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="spwhitton"
+ ip="82.36.235.9"
+ subject="Impossible?"
+ date="2013-06-24T17:48:02Z"
+ content="""
+I have now investigated this further and believe that what I am trying to do is impossible. Suppose we have a file `song.mp3` in both `music/` and `old/` and the special remote's preferred content expression is set-up to prefer `music/` and not to prefer `old/`. So initially, git-annex won't try to upload the content when it scans `old/song.mp3`, but it will when it scans `music/song.mp3`. Fine. Now consider a later scan. On scanning the filename `music/song.mp3` git-annex will suppose the file was dropped from the remote, and then see it would be preferred again so won't drop it. But then when it gets to scanning the filename `old/song.mp3` it will see that it wouldn't be preferred and will drop the content. So we get the loop.
+
+In order to stop the unwanted drop here, the preferred content expression must prefer \"files in old/* that is also in music/*\" but since preferred content expressions concern filenames without reference to their contents, this is impossible to express. The expression `include=music/* and include=old/*` will never match anything.
+"""]]
diff --git a/doc/forum/preferred_content_settings_for_multiple_symlinks/comment_4_3cbd06de53b6a13e2741124a8e7b5b5b._comment b/doc/forum/preferred_content_settings_for_multiple_symlinks/comment_4_3cbd06de53b6a13e2741124a8e7b5b5b._comment
new file mode 100644
index 000000000..1868e9736
--- /dev/null
+++ b/doc/forum/preferred_content_settings_for_multiple_symlinks/comment_4_3cbd06de53b6a13e2741124a8e7b5b5b._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.193"
+ subject="comment 4"
+ date="2013-06-25T17:22:53Z"
+ content="""
+spwhitton, your analysis is correct -- except this problem was finessed in git-annex version 4.20130621. Now, when using direct mode, it knows that `old/song.mp3` is also `music/song.mp3`, and so it only drops it if the preferred content expression allows dropping both files.
+
+Still doesn't work in indirect mode, and I think not likely to in the forseeable future. See [[bugs/Handling_of_files_inside_and_outside_archive_directory_at_the_same_time]]
+"""]]
diff --git a/doc/forum/preferred_content_settings_for_multiple_symlinks/comment_5_963558ab261d8a6315402d371e8348f9._comment b/doc/forum/preferred_content_settings_for_multiple_symlinks/comment_5_963558ab261d8a6315402d371e8348f9._comment
new file mode 100644
index 000000000..f7ae3216a
--- /dev/null
+++ b/doc/forum/preferred_content_settings_for_multiple_symlinks/comment_5_963558ab261d8a6315402d371e8348f9._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="spwhitton"
+ ip="82.36.235.9"
+ subject="comment 5"
+ date="2013-06-25T19:47:19Z"
+ content="""
+I assume you mean that if I use direct mode locally, it will get things right. I didn't think a special remote could ever be in direct mode.
+
+Thank you for the info. I don't want to lose the safeguards of indirect mode just for this, so I'll stick with my inelegant manual preferred content strings for now.
+"""]]
diff --git a/doc/forum/public-web-frontend.mdwn b/doc/forum/public-web-frontend.mdwn
new file mode 100644
index 000000000..d3fdb9b94
--- /dev/null
+++ b/doc/forum/public-web-frontend.mdwn
@@ -0,0 +1,16 @@
+Hi,
+
+Use case: I would like to have a "Public" top-level directory in my annex, which gets files in there published over HTTP on a particular server.
+
+How I see doing this:
+
+1. Put my annex to an http server with exported-over-http `/Public/` directory.
+2. Configure a `post-update` hook with the following:
+
+ $ git annex fix
+
+3. Push files on `/Public/` to that annex.
+
+Does it make sense? If yes, are there any gotchas I should beware of?
+
+Thanks.
diff --git a/doc/forum/public-web-frontend/comment_1_c73bd2dfe020c25eaad1c0707dd2db01._comment b/doc/forum/public-web-frontend/comment_1_c73bd2dfe020c25eaad1c0707dd2db01._comment
new file mode 100644
index 000000000..b9f6c9867
--- /dev/null
+++ b/doc/forum/public-web-frontend/comment_1_c73bd2dfe020c25eaad1c0707dd2db01._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ subject="should work.."
+ date="2012-08-05T17:18:47Z"
+ content="""
+I see no need for `git annex fix` here.
+
+Web server default configurations may not allow following symlinks outside the web server document root. On apache, it can be enabled with `Options FollowSymLinks`
+"""]]
diff --git a/doc/forum/public-web-frontend/comment_2_0026d7be6b17e50d86b3b54985882f80._comment b/doc/forum/public-web-frontend/comment_2_0026d7be6b17e50d86b3b54985882f80._comment
new file mode 100644
index 000000000..bfb60ede1
--- /dev/null
+++ b/doc/forum/public-web-frontend/comment_2_0026d7be6b17e50d86b3b54985882f80._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmdLmVxigDvxiGhnQ34xhyAaxl0CRRe9gs"
+ nickname="Bryan"
+ subject="Alternate version - smarter integration with other remotes/web special remote?"
+ date="2013-03-03T14:19:12Z"
+ content="""
+I love the idea of pushing files to \"visible\" using annex, but I'm wondering how difficult to would be to make this even fancier.
+
+For instance, if there are files that were originally imported from the web special remote (and have http:// prefixes, since that's not guaranteed), and they're not actually in the pushed annex, generate a redirect for all of them and write a special remote-local .htaccess file.
+
+Or, similarly, allow each remote to have some metadata which specifies what, if any, the URL prefix for a directory in annex is. Then, whenever you update a web remote, the auto-generated redirects list could contain not only files not present but with web-remote locations, but also other remotes which have the file under a web-visible path prefix. Bonus for allowing URL prefixes for S3-style remotes that are not encrypted.
+
+My use case for this sort of fancy is that I have a large server with gobs of space but on a personal (slower) internet connection, and a much smaller hosted instance with much faster bandwidth. With this smarts, I could push and pull large/expected high traffic files to the higher bandwidth/smaller machine ahead of, say, announcing a new feature or sharing a link to a video via e-mail.. or even reactively if the lower-bandwidth server is getting overwhelmed.
+"""]]
diff --git a/doc/forum/pulling_from_encrypted_remote.mdwn b/doc/forum/pulling_from_encrypted_remote.mdwn
new file mode 100644
index 000000000..e9486b597
--- /dev/null
+++ b/doc/forum/pulling_from_encrypted_remote.mdwn
@@ -0,0 +1,12 @@
+Is there a way to pull from an encrypted remote?
+
+Use case:
+
+1. Have annex in an encrypted public rsync remote
+2. Have USB stick with PGP keys (but not the annex repository)
+3. Get to a new computer
+4. Set up a new annex using the PGP keys I have.
+
+1-3 work fine :) However, 4'th is the issue:
+
+How would I do `git pull <remote>` for an encrypted remote? Is it possible?
diff --git a/doc/forum/pulling_from_encrypted_remote/comment_1_e9d6a9a6e01d01edb41a11b0da11d74d._comment b/doc/forum/pulling_from_encrypted_remote/comment_1_e9d6a9a6e01d01edb41a11b0da11d74d._comment
new file mode 100644
index 000000000..2da698f4a
--- /dev/null
+++ b/doc/forum/pulling_from_encrypted_remote/comment_1_e9d6a9a6e01d01edb41a11b0da11d74d._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="comment 1"
+ date="2012-07-10T18:14:31Z"
+ content="""
+You just need to `git clone` the existing repository and make sure the `git remote`s are setup.
+
+the 'rsync remote' is not actually the annex, it's just a collection of encrypted files with obfuscated names. You need a copy of the actual repository to restore the files.
+"""]]
diff --git a/doc/forum/pulling_from_encrypted_remote/comment_2_8d0db2ff65ce935c6e68044a3e0721a8._comment b/doc/forum/pulling_from_encrypted_remote/comment_2_8d0db2ff65ce935c6e68044a3e0721a8._comment
new file mode 100644
index 000000000..8fd73cd92
--- /dev/null
+++ b/doc/forum/pulling_from_encrypted_remote/comment_2_8d0db2ff65ce935c6e68044a3e0721a8._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmLB39PC89rfGaA8SwrsnB6tbumezj-aC0"
+ nickname="Tobias"
+ subject="Thats a fair solution"
+ date="2012-07-22T13:51:25Z"
+ content="""
+Until you don't have(access to) an existing repository to clone from.
+
+I really hope you revisit this when you come to the encryption part of the assistant.
+
+Btw, I also run FreeBSD if you need a tester on that at some point.
+
+Sincerely
+Tobias Ussing
+
+"""]]
diff --git a/doc/forum/pure_git-annex_only_workflow.mdwn b/doc/forum/pure_git-annex_only_workflow.mdwn
new file mode 100644
index 000000000..36648a905
--- /dev/null
+++ b/doc/forum/pure_git-annex_only_workflow.mdwn
@@ -0,0 +1,46 @@
+I’m using git annex to manage my movie collection on various devices – my laptop, a NSLU tucked away somewhere with lots of space, some external hard drives. For this use case, I do not need the full power of git as a version control system, so having to run "git commit" and coming up with commit messages is annoying. Also, this makes sense for a version control system, but not for my media collection:
+
+ $ git annex add Hot\ Fuzz\ -\ English.mkv
+ add Hot Fuzz - English.mkv (checksum...) ok
+ (Recording state in git...)
+ $ git commit -m 'another movie added'
+ [master 851dc8a] another movie added
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+ create mode 120000 00 Noch nicht gesehen/Hot Fuzz - English.mkv
+ $ git push jeff
+ Counting objects: 38, done.
+ Delta compression using up to 2 threads.
+ Compressing objects: 100% (20/20), done.
+ Writing objects: 100% (26/26), 2.00 KiB, done.
+ Total 26 (delta 11), reused 0 (delta 0)
+ remote: error: refusing to update checked out branch: refs/heads/master
+ remote: error: By default, updating the current branch in a non-bare repository
+ remote: error: is denied, because it will make the index and work tree inconsistent
+ remote: error: with what you pushed, and will require 'git reset --hard' to match
+ remote: error: the work tree to HEAD.
+ remote: error:
+ remote: error: You can set 'receive.denyCurrentBranch' configuration variable to
+ remote: error: 'ignore' or 'warn' in the remote repository to allow pushing into
+ remote: error: its current branch; however, this is not recommended unless you
+ remote: error: arranged to update its work tree to match what you pushed in some
+ remote: error: other way.
+ remote: error:
+ remote: error: To squelch this message and still keep the default behaviour, set
+ remote: error: 'receive.denyCurrentBranch' configuration variable to 'refuse'.
+ To jeff:/mnt/media/Movies
+ ! [rejected] git-annex -> git-annex (non-fast-forward)
+ ! [remote rejected] master -> master (branch is currently checked out)
+ error: failed to push some refs to 'jeff:/mnt/media/Movies'
+ To prevent you from losing history, non-fast-forward updates were rejected
+ Merge the remote changes (e.g. 'git pull') before pushing again. See the
+ 'Note about fast-forwards' section of 'git push --help' for details.
+
+It seems that to successfully make the new files known to the other side, I have to log into jeff and pull _from_ my current machine.
+
+What I would like to have is that
+
+* git annex add does not require a commit afterwards.
+* Changes to the files are automatically picked up with the next git-annex call (similar to how etckeeper works).
+* Commands "git annex push" and "git annex pull" that will sync the metadata (i.e. the list of files) in both directions without further manual intervention, at least not until the two repositories have diverged in a way that is not possible to merge sensible.
+
+Summay: git-annex is great. git is not always. Please make it possible to use git annex without having to use git.
diff --git a/doc/forum/pure_git-annex_only_workflow/comment_10_683768c9826b0bf0f267e8734b9eb872._comment b/doc/forum/pure_git-annex_only_workflow/comment_10_683768c9826b0bf0f267e8734b9eb872._comment
new file mode 100644
index 000000000..dc499cbc9
--- /dev/null
+++ b/doc/forum/pure_git-annex_only_workflow/comment_10_683768c9826b0bf0f267e8734b9eb872._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://www.joachim-breitner.de/"
+ nickname="nomeata"
+ subject="Finally some code"
+ date="2011-12-29T19:58:31Z"
+ content="""
+The repository at http://git.nomeata.de/?p=git-annex.git;a=summary contains changes to Commands/Sync.hs (and to the manpage) that implements this behavior. The functionality should be fine; the progress output is not very nice yet, but I’m not sure if I really understood the various Command types. It also should be more easily discoverable how to activate the behavior (by running \"git branch synced/master\") by providing a helpful message, at least unless git annex init creates the branch by default.
+"""]]
diff --git a/doc/forum/pure_git-annex_only_workflow/comment_11_6b541ed834ef45606f3b98779a25a148._comment b/doc/forum/pure_git-annex_only_workflow/comment_11_6b541ed834ef45606f3b98779a25a148._comment
new file mode 100644
index 000000000..30932e301
--- /dev/null
+++ b/doc/forum/pure_git-annex_only_workflow/comment_11_6b541ed834ef45606f3b98779a25a148._comment
@@ -0,0 +1,30 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 11"
+ date="2011-12-30T21:49:06Z"
+ content="""
+OMG, my first sizable haskell patch!
+
+So trying this out..
+
+In each repo I want to sync, I first `git branch synced/master`
+
+Then in each repo, I found I had to pull from each of its remotes, to get the tracking branches that `defaultSyncRemotes` looks for to know those remotes are syncable. This was the surprising thing for me, I had expected sync to somehow work out which remotes were syncable without my explicit pull. And it was not very obvious that sync was not doing its thing before I did that, since it still does a lot of \"stuff\".
+
+Once set up properly, `git annex sync` fetches from each remote, merges, and then pushes to each remote that has a synced branch. Changes propigate around even when some links are one-directional. Cool!
+
+So it works fine, but I think more needs to be done to make setting up syncing easier. Ideally, all a user would need to do is run \"git annex sync\" and it syncs from all remotes, without needing to manually set up the synced/master branch.
+
+While this would lose the ability to control which remotes are synced, I think that being able to `git annex sync origin` and only sync from/to origin is sufficient, for the centralized use case.
+
+---
+
+Code review:
+
+Why did you make `branch` strict?
+
+There is a bit of a bug in your use of Command.Merge.start. The git-annex branch merge code only runs once per git-annex run, and often this comes before sync fetches from the remotes, leading to a push conflict. I've fixed this in my \"sync\" branch, along with a few other minor things.
+
+`mergeRemote` merges from `refs/remotes/foo/synced/master`. But that will only be up-to-date if `git annex sync` has recently been run there. Is there any reason it couldn't merge from `refs/remotes/foo/master`?
+"""]]
diff --git a/doc/forum/pure_git-annex_only_workflow/comment_12_ca8ca35d6cd4a9f94568536736c12adc._comment b/doc/forum/pure_git-annex_only_workflow/comment_12_ca8ca35d6cd4a9f94568536736c12adc._comment
new file mode 100644
index 000000000..5b0259b97
--- /dev/null
+++ b/doc/forum/pure_git-annex_only_workflow/comment_12_ca8ca35d6cd4a9f94568536736c12adc._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 12"
+ date="2011-12-30T23:45:57Z"
+ content="""
+I have made a new `autosync` branch, where all that the user needs to do is run `git annex sync` and it automatically sets up the synced/master branch. I find this very easy to use, what do you think?
+
+Note that `autosync` is also pretty smart about not running commands like \"git merge\" and \"git push\" when they would not do anything. So you may find `git annex sync` not showing all the steps you'd expect. The only step a sync always performs now is pulling from the remotes.
+"""]]
diff --git a/doc/forum/pure_git-annex_only_workflow/comment_13_00c82d320c7b4bb51078beba17e14dc8._comment b/doc/forum/pure_git-annex_only_workflow/comment_13_00c82d320c7b4bb51078beba17e14dc8._comment
new file mode 100644
index 000000000..84515ec6c
--- /dev/null
+++ b/doc/forum/pure_git-annex_only_workflow/comment_13_00c82d320c7b4bb51078beba17e14dc8._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 13"
+ date="2011-12-31T18:34:31Z"
+ content="""
+I have merged my autosync branch, the improved sync command will be in this year's last git-annex release!
+"""]]
diff --git a/doc/forum/pure_git-annex_only_workflow/comment_14_b63568b327215ef8f646a39d760fdfc0._comment b/doc/forum/pure_git-annex_only_workflow/comment_14_b63568b327215ef8f646a39d760fdfc0._comment
new file mode 100644
index 000000000..194415dfb
--- /dev/null
+++ b/doc/forum/pure_git-annex_only_workflow/comment_14_b63568b327215ef8f646a39d760fdfc0._comment
@@ -0,0 +1,32 @@
+[[!comment format=mdwn
+ username="http://www.joachim-breitner.de/"
+ nickname="nomeata"
+ subject="comment 14"
+ date="2012-01-02T14:02:04Z"
+ content="""
+Sorry for not replying earlier, but my non-mailinglist-communications-workflows are suboptimal :-)
+
+> Then in each repo, I found I had to pull from each of its remotes, to get the tracking branches that defaultSyncRemotes looks for to know those remotes are syncable. This was the surprising thing for me, I had expected sync to somehow work out which remotes were syncable without my explicit pull. And it was not very obvious that sync was not doing its thing before I did that, since it still does a lot of \"stuff\".
+
+Right. But \"git fetch\" ought to be enough.
+
+Personally, I’d just pull and push everywhere, but you pointed out that it ought to be manageable. The existence of the synced/master branch is the flag that indicates this, so you need to propagate this once. Note that if the branch were already created by \"git annex init\", then this would not be a problem.
+
+It is not required to use \"git fetch\" once, you can also call \"git annex sync <remote>\" once with the remote explicitly mentioned; this would involve a fetch.
+
+> While this would lose the ability to control which remotes are synced, I think that being able to git annex sync origin and only sync from/to origin is sufficient, for the centralized use case.
+
+I’d leave this decision to you. But I see that you took the decision already, as your code now creates the synced/master branch when it does not exist (e290f4a8).
+
+> Why did you make branch strict?
+
+Because it did not work otherwise :-). It uses pipeRead, which is lazy, and for some reason git and/or your utility functions did not like that the output of the command was not consumed before the next git command was called. I did not investigate further. For better code, I’d suggest to add a function like pipeRead that completely reads the git output before returning, thus avoiding any issues with lazyIO.
+
+> mergeRemote merges from refs/remotes/foo/synced/master. But that will only be up-to-date if git annex sync has recently been run there. Is there any reason it couldn't merge from refs/remotes/foo/master?
+
+Hmm, good question. It is probably save to merge from both, and push only to synced/master. But which one first? synced/master can be ahead if the repo was synced to from somewhere else, master can be ahead if there are local changes. Maybe git merge should be called on all remote heads simultaniously, thus generating only one commit for the merge. I don’t know how well that works in practice.
+
+Thanks for including my code,
+Joachim
+
+"""]]
diff --git a/doc/forum/pure_git-annex_only_workflow/comment_15_cb7c856d8141b2de3cc95874753f1ee5._comment b/doc/forum/pure_git-annex_only_workflow/comment_15_cb7c856d8141b2de3cc95874753f1ee5._comment
new file mode 100644
index 000000000..a526d5db8
--- /dev/null
+++ b/doc/forum/pure_git-annex_only_workflow/comment_15_cb7c856d8141b2de3cc95874753f1ee5._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 15"
+ date="2012-01-02T16:01:49Z"
+ content="""
+With a lazy branch, I get \"git-annex: no branch is checked out\". Weird.. my best guess is that it's because this is running at the seek stage, which is unusual, and the value is not used until a later stage and so perhaps the git command gets reaped by some cleanup code before its output is read.
+
+(pipeRead is lazy because often it's used to read large quantities of data from git that are processed progressively.)
+
+I did make it merge both branches, separately. It would be possible to do one single merge, but it's probably harder for the user to recover if there are conflicts in an octopus merge. The order of the merges does not seem to me to matter much, barring conflicts it will work either way. Dealing with conflicts during sync is probably a weakness of all this; after the first conflict the rest of the sync will continue failing.
+"""]]
diff --git a/doc/forum/pure_git-annex_only_workflow/comment_1_a32f7efd18d174845099a4ed59e6feae._comment b/doc/forum/pure_git-annex_only_workflow/comment_1_a32f7efd18d174845099a4ed59e6feae._comment
new file mode 100644
index 000000000..def1794a3
--- /dev/null
+++ b/doc/forum/pure_git-annex_only_workflow/comment_1_a32f7efd18d174845099a4ed59e6feae._comment
@@ -0,0 +1,32 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-12-09T22:56:11Z"
+ content="""
+First, you need a bare git repository that you can push to, and pull from. This simplifies most git workflow.
+
+Secondly, I use [mr](http://kitenet.net/~joey/code/mr/), with this in `.mrconfig`:
+
+<pre>
+[DEFAULT]
+lib =
+ annexupdate() {
+ git commit -a -m update || true
+ git pull \"$@\"
+ git annex merge
+ git push || true
+ }
+
+[lib/sound]
+update = annexupdate
+[lib/big]
+update = annexupdate
+</pre>
+
+Which makes \"mr update\" in repositories where I rarely care about git details take care of syncing my changes.
+
+I also make \"mr update\" do a \"git annex get\" of some files in some repositories that I want to always populate. git-annex and mr go well together. :)
+
+Perhaps my annexupdate above should be available as \"git annex sync\"?
+"""]]
diff --git a/doc/forum/pure_git-annex_only_workflow/comment_2_66dc9b65523a9912411db03c039ba848._comment b/doc/forum/pure_git-annex_only_workflow/comment_2_66dc9b65523a9912411db03c039ba848._comment
new file mode 100644
index 000000000..473a0287d
--- /dev/null
+++ b/doc/forum/pure_git-annex_only_workflow/comment_2_66dc9b65523a9912411db03c039ba848._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://www.joachim-breitner.de/"
+ nickname="nomeata"
+ subject="comment 2"
+ date="2011-12-10T16:28:29Z"
+ content="""
+Thanks for the tips so far. I guess a bare-only repo helps, but as well is something that I don’t _need_ (for my use case), any only have to do because git works like this.
+
+Also, if I have a mobile device that I want to push to, then I’d have to have two repositories on the device, as I might not be able to reach my main bare repository when traveling, but I cannot push to the „real“ repo on the mobile device from my computer. I guess I am spoiled by darcs, which will happily push to a checked out
+remote repository, updating the checkout if possible without conflict.
+
+If I introduce a central bare repository to push to and from; I’d still have to have the other non-bare repos as remotes, so that git-annex will know about them and their files, right?
+
+I’d appreciate a \"git annex sync\" that does what you described (commit all, pull, merge, push). Especially if it comes in a \"git annex sync --all\" variant that syncs all reachable repositories.
+"""]]
diff --git a/doc/forum/pure_git-annex_only_workflow/comment_3_9b7d89da52f7ebb7801f9ec8545c3aba._comment b/doc/forum/pure_git-annex_only_workflow/comment_3_9b7d89da52f7ebb7801f9ec8545c3aba._comment
new file mode 100644
index 000000000..9b6e6d7c4
--- /dev/null
+++ b/doc/forum/pure_git-annex_only_workflow/comment_3_9b7d89da52f7ebb7801f9ec8545c3aba._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 3"
+ date="2011-12-10T19:43:04Z"
+ content="""
+Git can actually push into a non-bare repository, so long as the branch you change there is not a checked out one. Pushing into `remotes/$foo/master` and `remotes/$foo/git-annex` would work, however determining the value that the repository expects for `$foo` is something git cannot do on its own. And of course you'd still have to `git merge remotes/$foo/master` to get the changes.
+
+Yes, you still keep the non-bare repos as remotes when adding a bare repository, so git-annex knows how to get to them.
+
+I've made `git annex sync` run the simple script above. Perhaps it can later be improved to sync all repositories.
+"""]]
diff --git a/doc/forum/pure_git-annex_only_workflow/comment_4_dc8a3f75533906ad3756fcc47f7e96bb._comment b/doc/forum/pure_git-annex_only_workflow/comment_4_dc8a3f75533906ad3756fcc47f7e96bb._comment
new file mode 100644
index 000000000..1ac9e798a
--- /dev/null
+++ b/doc/forum/pure_git-annex_only_workflow/comment_4_dc8a3f75533906ad3756fcc47f7e96bb._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="http://www.joachim-breitner.de/"
+ nickname="nomeata"
+ subject="comment 4"
+ date="2011-12-13T18:16:08Z"
+ content="""
+I thought about this some more, and I think I have a pretty decent solution that avoids a central bare repository. Instead of pushing to master (which git does not like) or trying to guess the remote branch name on the other side, there is a well-known branch name, say git-annex-master. Then a sync command would do something like this (untested):
+
+ git commit -a -m 'git annex sync' # ideally with a description derived from the diff
+ git merge git-annex-master
+ git pull someremote git-annex-master # for all reachable remotes. Or better to use fetch and then merge everything in one command?
+ git branch -f git-annex-master # (or checkout git-annex-master, merge master, checkout master, but since we merged before this should have the same effect
+ git annex merge
+ git push someremote git-annex-master # for all reachable remotes
+
+The nice things are: One can push to any remote repository, and thus avoid the issue of pushing to a portable device; the merging happens on the master branch, so if it fails to merge automatically, regular git foo can resolve it, and all changes eventually reach every repository.
+
+What do you think?
+
+"""]]
diff --git a/doc/forum/pure_git-annex_only_workflow/comment_5_afe5035a6b35ed2c7e193fb69cc182e2._comment b/doc/forum/pure_git-annex_only_workflow/comment_5_afe5035a6b35ed2c7e193fb69cc182e2._comment
new file mode 100644
index 000000000..0847daae9
--- /dev/null
+++ b/doc/forum/pure_git-annex_only_workflow/comment_5_afe5035a6b35ed2c7e193fb69cc182e2._comment
@@ -0,0 +1,24 @@
+[[!comment format=mdwn
+ username="http://www.joachim-breitner.de/"
+ nickname="nomeata"
+ subject="comment 5"
+ date="2011-12-13T18:47:18Z"
+ content="""
+After some experimentation, this seems to work better:
+
+ git commit -a -m 'git annex sync'
+ git merge git-annex-master
+ for remote in $(git remote)
+ do
+ git fetch $remote
+ git merge $remote git-annex-master
+ done
+ git branch -f git-annex-master
+ git annex merge
+ for remote in $(git remote)
+ do
+ git push $remote git-annex git-annex-master
+ done
+
+Maybe this approach can be enhance to skip stuff gracefully if there is no git-annex-master branch and then be added to what \"git annex sync\" does, this way those who want to use the feature can do so by running \"git branch git-annex-master\" once. Or, if you like this and want to make it default, just make git-annex-init create the git-annex-master branch :-)
+"""]]
diff --git a/doc/forum/pure_git-annex_only_workflow/comment_6_3660d45c5656f68924acbd23790024ee._comment b/doc/forum/pure_git-annex_only_workflow/comment_6_3660d45c5656f68924acbd23790024ee._comment
new file mode 100644
index 000000000..fc66fbb8e
--- /dev/null
+++ b/doc/forum/pure_git-annex_only_workflow/comment_6_3660d45c5656f68924acbd23790024ee._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 6"
+ date="2011-12-13T20:53:23Z"
+ content="""
+It would be clearer to call \"git-annex-master\" \"synced/master\" (or really \"synced/$current_branch\"). That does highlight that this method of syncing is not particularly specific to git-annex.
+
+I think this would be annoying to those who do use a central bare repository, because of the unnecessary pushing and pulling to other repos, which could be expensive to do, especially if you have a lot of interconnected repos. So having a way to enable/disable it seems best.
+
+Maybe you should work up a patch to Command/Sync.hs, since I know you know haskell :)
+"""]]
diff --git a/doc/forum/pure_git-annex_only_workflow/comment_7_33db51096f568c65b22b4be0b5538c0d._comment b/doc/forum/pure_git-annex_only_workflow/comment_7_33db51096f568c65b22b4be0b5538c0d._comment
new file mode 100644
index 000000000..753a2af16
--- /dev/null
+++ b/doc/forum/pure_git-annex_only_workflow/comment_7_33db51096f568c65b22b4be0b5538c0d._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://www.joachim-breitner.de/"
+ nickname="nomeata"
+ subject="comment 7"
+ date="2011-12-18T12:08:51Z"
+ content="""
+I agree on the naming suggestions, and that it does not suit everybody. Maybe I’ll think some more about it. The point is: I’m trying to make live easy for those who do not want to manually create some complicated setup, so if it needs configuration, it is already off that track. But turning the current behavior into something people have to configure is also not well received by the users.
+
+Given that \"git annex sync\" is a new command, maybe it is fine to have this as a default behavior, and offer an easy way out. The easy way out could be one of two flags that can be set for a repo (or a remote):
+
+* \"central\", which makes git annex sync only push and pull to and that repo (unless a different remote is given on the command line)
+* \"unsynced\", which makes git annex sync skip the repo.
+
+Maybe central is enough.
+"""]]
diff --git a/doc/forum/pure_git-annex_only_workflow/comment_8_6e5b42fdb7801daadc0b3046cbc3d51e._comment b/doc/forum/pure_git-annex_only_workflow/comment_8_6e5b42fdb7801daadc0b3046cbc3d51e._comment
new file mode 100644
index 000000000..67953860a
--- /dev/null
+++ b/doc/forum/pure_git-annex_only_workflow/comment_8_6e5b42fdb7801daadc0b3046cbc3d51e._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 8"
+ date="2011-12-19T18:29:01Z"
+ content="""
+I don't mind changing the behavior of git-annex sync, certainly..
+
+Looking thru git's documentation, I found some existing configuration that could be reused following your idea.
+There is a remote.name.skipDefaultUpdate and a remote.name.skipFetchAll. Though both have to do with fetches, not pushes.
+Another approach might be to use git's remote group stuff.
+"""]]
diff --git a/doc/forum/pure_git-annex_only_workflow/comment_9_ace319652f9c7546883b5152ddc82591._comment b/doc/forum/pure_git-annex_only_workflow/comment_9_ace319652f9c7546883b5152ddc82591._comment
new file mode 100644
index 000000000..de656d662
--- /dev/null
+++ b/doc/forum/pure_git-annex_only_workflow/comment_9_ace319652f9c7546883b5152ddc82591._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://www.joachim-breitner.de/"
+ nickname="nomeata"
+ subject="comment 9"
+ date="2011-12-19T22:56:26Z"
+ content="""
+Another option that would please the naive user without hindering the more advanced user: \"git annex init\", by default, creates a synced/master branch. \"git annex sync\" will pull from every <remote>/sync/master branch it finds, and also push to any <remote>/sync/master branch it finds, but will not create any. So by default (at least for new users), this provides simple one-step syncing.
+
+Advanced users can disable this per-repo by just deleting the synced/master branch. Presumably the logic will be: Every repo that should not be pushed to, because it has access to some central repo, should not have a synced/master branch. Every other repo, including the (or one of the few) central repos, will have the branch.
+
+This is not the most expressive solution, as it does not allow configuring syncing between arbitrary pairs of repos, but it feels like a good compromise between that and simplicity and transparency.
+
+I think it's about time that I provide less talk and more code. I’ll see when I find the time :-)
+"""]]
diff --git a/doc/forum/purge_files_with_no_copies.mdwn b/doc/forum/purge_files_with_no_copies.mdwn
new file mode 100644
index 000000000..5761d9290
--- /dev/null
+++ b/doc/forum/purge_files_with_no_copies.mdwn
@@ -0,0 +1,3 @@
+Hi guys, as a result of some improper handling I am left with a couple of files with no copies scattered all around my repos. Now, while my data loss is unfortunate, it is not tragic. What I would like to do now is to purge all of these files without having to look for them one by one. Is there any easy way to do this?
+
+Cheers
diff --git a/doc/forum/purge_files_with_no_copies/comment_1_12b578689eb8d5d38c06261ec65e2109._comment b/doc/forum/purge_files_with_no_copies/comment_1_12b578689eb8d5d38c06261ec65e2109._comment
new file mode 100644
index 000000000..0ea81ecfe
--- /dev/null
+++ b/doc/forum/purge_files_with_no_copies/comment_1_12b578689eb8d5d38c06261ec65e2109._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.14.105"
+ subject="comment 1"
+ date="2013-09-19T20:59:32Z"
+ content="""
+This will output all files in your repository that git-annex thinks have no copies left:
+
+`git annex find --not --copies=1`
+
+Piping it to git rm is left as an excercise for the reader..
+"""]]
diff --git a/doc/forum/question_about_assistant_and___47__archive__47__.mdwn b/doc/forum/question_about_assistant_and___47__archive__47__.mdwn
new file mode 100644
index 000000000..af8cee4c9
--- /dev/null
+++ b/doc/forum/question_about_assistant_and___47__archive__47__.mdwn
@@ -0,0 +1,22 @@
+I have a git-annex repository located at ~/annex which has been set up using git-annex assistant.
+
+This repository is configured as "client".
+
+My other repository is a huge USB drive configured as "full archive".
+
+Now everything seems to work fine except there is one thing I don't understand:
+
+ alip@client:~/annex> git-annex whereis ./archive/kus.png
+ whereis archive/kus.png (1 copy)
+ e79a4cf6-4c48-4833-93de-98ba6eb625d6 -- deniz
+ ok
+
+Fine, there is only one copy according to git-annex but the file is still present
+in **this** client repository:
+
+ alip@client:> du -hs ~/annex/archive
+ 20G /home/alip/annex/archive/
+
+How do I free this space? Am I supposed to call git-annex drop manually?
+
+git-annex version: 3.20130124
diff --git a/doc/forum/question_about_assistant_and___47__archive__47__/comment_1_97890e26072af9277144651e3fdcada0._comment b/doc/forum/question_about_assistant_and___47__archive__47__/comment_1_97890e26072af9277144651e3fdcada0._comment
new file mode 100644
index 000000000..2736016c5
--- /dev/null
+++ b/doc/forum/question_about_assistant_and___47__archive__47__/comment_1_97890e26072af9277144651e3fdcada0._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="comment 1"
+ date="2013-01-30T18:44:52Z"
+ content="""
+Give this a try:
+
+http://git-annex.branchable.com/walkthrough/unused_data/
+"""]]
diff --git a/doc/forum/question_about_assistant_and___47__archive__47__/comment_2_542bf265e35a976ac76767762d67d617._comment b/doc/forum/question_about_assistant_and___47__archive__47__/comment_2_542bf265e35a976ac76767762d67d617._comment
new file mode 100644
index 000000000..00cc06374
--- /dev/null
+++ b/doc/forum/question_about_assistant_and___47__archive__47__/comment_2_542bf265e35a976ac76767762d67d617._comment
@@ -0,0 +1,104 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkZktNHFhxC1kYA9KKdKpYJO4clq9WDsjE"
+ nickname="Jason"
+ subject="comment 2"
+ date="2013-01-30T19:14:48Z"
+ content="""
+I'm seeing the same thing and I think it's a bug. Everything I'm reading says that when you move a file from anywhere into an archive directory, it's supposed to upload it to an archive and drop it locally.
+
+If I copy the file from outside my annex into the archive directory it will usually do exactly that and I'll end up with a symlink, but not always. Sometimes I'll end up with a file.
+
+If I move the file from within my annex into the archive, everything gets confused. Here is an example:
+
+ [jchu@april annex(master)]$ mkdir testdir
+ [jchu@april annex(master)]$ cd testdir/
+ [jchu@april testdir(master)]$ ls
+ [jchu@april testdir(master)]$ cat > test.txt << EOF
+ > I have a file. It is very nice.
+ > EOF
+ [jchu@april testdir(master)]$ ls -l
+ total 4
+ -rw-r--r-- 1 jchu users 33 Jan 30 10:53 test.txt
+ [jchu@april testdir(master)]$ mkdir archive
+ [jchu@april testdir(master)]$ mv test.txt archive/
+ [jchu@april testdir(master)]$ ls -l
+ total 0
+ drwxr-xr-x 2 jchu users 21 Jan 30 10:54 archive
+ [jchu@april testdir(master)]$ ls -l archive/
+ total 4
+ -rw-r--r-- 1 jchu users 33 Jan 30 10:53 test.txt
+ [jchu@april testdir(master)]$ # Shouldn't this be a symlink?
+ [jchu@april testdir(master)]$ git show
+ commit 2fb2cba3fae98e0e0b8b7891b1af0cc655754896
+ Author: Jason Chu <jchu@xentac.net>
+ Date: Wed Jan 30 10:54:11 2013 -0800
+
+ diff --git a/testdir/archive/test.txt b/testdir/archive/test.txt
+ new file mode 120000
+ index 0000000..5bd7982
+ --- /dev/null
+ +++ b/testdir/archive/test.txt
+ @@ -0,0 +1 @@
+ +../../.git/annex/objects/x5/Q1/SHA256E-s33--1859a57b635b0702dd3813dd7637f11842730b0464c35a4ad361dd0d37fc3dab.txt/SHA256E-s33--1859a57b635b0702dd3813dd7637f11842730b0464c35a4ad3
+ \ No newline at end of file
+ [jchu@april testdir(master)]$ git show HEAD^
+ commit 410f58f782348599d42496db2c9b21cfb2e59124
+ Author: Jason Chu <jchu@xentac.net>
+ Date: Wed Jan 30 10:54:10 2013 -0800
+
+ diff --git a/testdir/test.txt b/testdir/test.txt
+ deleted file mode 120000
+ index 82343e3..0000000
+ --- a/testdir/test.txt
+ +++ /dev/null
+ @@ -1 +0,0 @@
+ -../.git/annex/objects/x5/Q1/SHA256E-s33--1859a57b635b0702dd3813dd7637f11842730b0464c35a4ad361dd0d37fc3dab.txt/SHA256E-s33--1859a57b635b0702dd3813dd7637f11842730b0464c35a4ad361d
+ \ No newline at end of file
+
+From what I can see here, the file was archived properly and the delete in git was issued correctly. The daemon.log shows me that the file was uploaded correctly when it was initially created and then added to the archive directory, but I don't see a direct delete in the log file (even though the git log shows me it happened).
+
+Now on to the really weird part. If I restart the daemon (or there are other ways to trigger it, but this seems to be the easiest for me), I see that log lines that say testdir/archive/test.txt was dropped (good) but then testdir/test.txt is re-downloaded and appears back in that directory. I wanted the file deleted from testdir, why is it back?!? Since it gets redownloaded and readded, my new logs look like this:
+
+ [jchu@april testdir(master)]$ git show
+ commit 850464dd2f8ae5cd407a214543afab668d4b34eb
+ Author: Jason Chu <jchu@xentac.net>
+ Date: Wed Jan 30 11:00:03 2013 -0800
+
+ diff --git a/testdir/archive/test.txt b/testdir/archive/test.txt
+ deleted file mode 120000
+ index 5bd7982..0000000
+ --- a/testdir/archive/test.txt
+ +++ /dev/null
+ @@ -1 +0,0 @@
+ -../../.git/annex/objects/x5/Q1/SHA256E-s33--1859a57b635b0702dd3813dd7637f11842730b0464c35a4ad361dd0d37fc3dab.txt/SHA256E-s33--1859a57b635b0702dd3813dd7637f11842730b0464c35a4ad3
+ \ No newline at end of file
+ [jchu@april testdir(master)]$ git show HEAD^
+ commit 8cf9019e66e5a2cb0478e965fda352c742972591
+ Author: Jason Chu <jchu@xentac.net>
+ Date: Wed Jan 30 11:00:00 2013 -0800
+
+ diff --git a/testdir/test.txt b/testdir/test.txt
+ new file mode 120000
+ index 0000000..82343e3
+ --- /dev/null
+ +++ b/testdir/test.txt
+ @@ -0,0 +1 @@
+ +../.git/annex/objects/x5/Q1/SHA256E-s33--1859a57b635b0702dd3813dd7637f11842730b0464c35a4ad361dd0d37fc3dab.txt/SHA256E-s33--1859a57b635b0702dd3813dd7637f11842730b0464c35a4ad361d
+ \ No newline at end of file
+
+And the filesystem looks like this:
+
+ [jchu@april testdir(master)]$ ls -lR
+ .:
+ total 4
+ drwxr-xr-x 2 jchu users 21 Jan 30 11:00 archive
+ -rw-r--r-- 1 jchu users 33 Jan 30 11:00 test.txt
+
+ ./archive:
+ total 4
+ -rw-r--r-- 1 jchu users 33 Jan 30 11:00 test.txt
+
+I have 3 remotes set up: a usb drive (client, it was created like that directly by annex when I created a Removable drive repo, it's a bare repo), s3 (archive), and nas (a remote server repo, that connects over ssh and uses rsync). I thought maybe that the usb drive still had a record of testdir/test.txt existing, but the logs in refs/heads/synced/master match.
+
+It's as if the git annex thinks that the original content is still within a non-archive directory, so the data can't be dropped, but everywhere I look the references to that content are gone. The only way I've found to fix this is to convert to indirect mode and delete the symlinks from there (which seems to work better). It seems to be an interaction between direct mode, the archive, and maybe my filesystem (xfs).
+"""]]
diff --git a/doc/forum/question_about_assistant_and___47__archive__47__/comment_3_bafe99159df2adcd5fecc0d67bbf05a5._comment b/doc/forum/question_about_assistant_and___47__archive__47__/comment_3_bafe99159df2adcd5fecc0d67bbf05a5._comment
new file mode 100644
index 000000000..b1c9e1774
--- /dev/null
+++ b/doc/forum/question_about_assistant_and___47__archive__47__/comment_3_bafe99159df2adcd5fecc0d67bbf05a5._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.3.125"
+ subject="comment 3"
+ date="2013-02-05T17:46:56Z"
+ content="""
+@alip I've just fixed a bug which made the assistant get location tracking info wrong for files it added in direct mode. That probably explains what you're seeing. You can run `git annex fsck` to fix the location log info, and if you restart the assistant it'll probably then realize the files are locally present and drop them. Of course, the USB drive has to be connected for that to work; git-annex needs to verify the files have been moved to it before it can drop them.
+"""]]
diff --git a/doc/forum/question_about_assistant_and___47__archive__47__/comment_4_e77fa2992d9302a49a05f514c81612ca._comment b/doc/forum/question_about_assistant_and___47__archive__47__/comment_4_e77fa2992d9302a49a05f514c81612ca._comment
new file mode 100644
index 000000000..3f78b4813
--- /dev/null
+++ b/doc/forum/question_about_assistant_and___47__archive__47__/comment_4_e77fa2992d9302a49a05f514c81612ca._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.3.125"
+ subject="comment 4"
+ date="2013-02-05T19:05:49Z"
+ content="""
+@Jason That is a bug. Please don't report what are obviously bugs in the forum!
+
+I've posted a bug report about it here: [[bugs/direct_mode_renames]]
+"""]]
diff --git a/doc/forum/receiving_indirect_renames_on_direct_repo___63__.mdwn b/doc/forum/receiving_indirect_renames_on_direct_repo___63__.mdwn
new file mode 100644
index 000000000..51a3aa7b6
--- /dev/null
+++ b/doc/forum/receiving_indirect_renames_on_direct_repo___63__.mdwn
@@ -0,0 +1,254 @@
+I've been playing with a mixed setup, and I frequentely end up with conflicts which can be ascribed to mixing direct windows repos with indirect linux one(s), and making renames on the indirect ones.
+Possibly someone can address what I miss of the git-annex/git interaction.
+
+#### versions involved ####
+
+linux: git-annex version: 4.20131024
+win: git-annex version: 4.20131024-gca7b71e
+
+### Steps to reproduce behaviour ###
+
+###### 1. On linux, i setup bare origin "casa" and client repo "local":
+
+ [michele@home ~]$ git init --bare casa
+ Initialized empty Git repository in /home/sambahome/michele/casa/
+ [michele@home ~]$ cd casa
+ [michele@home casa]$ git annex init casa
+ init casa ok
+ (Recording state in git...)
+ [michele@home ~]$ cd ..; git clone casa local
+ Cloning into 'local'...
+ done.
+ warning: remote HEAD refers to nonexistent ref, unable to checkout.
+ [michele@home ~]$ cd local; git annex init local
+ init local ok
+ (Recording state in git...)
+ [michele@home local]$ echo lintest > lintest
+ [michele@home local]$ git annex add lintest
+ add lintest (checksum...) ok
+ (Recording state in git...)
+ [michele@home local]$ git annex sync
+ (merging origin/git-annex into git-annex...)
+ (Recording state in git...)
+ commit
+ ok
+ pull origin
+ ok
+ push origin
+ Counting objects: 18, done.
+ Delta compression using up to 4 threads.
+ Compressing objects: 100% (12/12), done.
+ Writing objects: 100% (16/16), 1.48 KiB | 0 bytes/s, done.
+ Total 16 (delta 1), reused 0 (delta 0)
+ To /home/sambahome/michele/casa
+ * [new branch] git-annex -> synced/git-annex
+ * [new branch] master -> synced/master
+ ok
+ ```
+
+###### 2. On windows I clone origin, and I sync empty
+
+ ```cmd
+ M:\>git clone ssh://michele@home/home/michele/casa win
+ Cloning into 'win'...
+ remote: Counting objects: 20, done.
+ remote: Compressing objects: 100% (15/15), done.
+ remote: Total 20 (delta 3), reused 0 (delta 0)
+ Receiving objects: 100% (20/20), done.
+ Resolving deltas: 100% (3/3), done.
+ M:\>cd win
+ M:\win>git annex status
+ Detected a crippled filesystem.
+ Enabling direct mode.
+ Detected a filesystem without fifo support.
+ Disabling ssh connection caching.
+ repository mode: direct
+ trusted repositories: (merging origin/git-annex origin/synced/git-annex into git-annex...)
+ (Recording state in git...)
+ 0
+ semitrusted repositories: 4
+ 00000000-0000-0000-0000-000000000001 -- web
+ 598ecfac-087d-49a3-b48d-beafd0d71805 -- origin (casa)
+ b2699c17-d0bc-40a0-b447-a64ad109b2a2 -- here (ALICUDI:M:\win)
+ bd4166eb-296b-4f0f-a3be-6c25e4c7cbb0 -- local
+ untrusted repositories: 0
+ transfers in progress: none
+ available local disk space: unknown
+ local annex keys: 0
+ local annex size: 0 bytes
+ known annex keys: 1
+ known annex size: 8 bytes
+ bloom filter size: 16 mebibytes (0% full)
+ backend usage:
+ SHA256E: 1
+ ```
+
+###### 3. I copy content from local to win
+
+ ```bash
+ [michele@home local]$ git annex copy --to origin lintest
+ copy lintest (to origin...) ok
+ (Recording state in git...)
+ [michele@home local]$ git annex sync
+ ...runs ok...
+ ```
+
+###### 4. and
+
+ ```cmd
+ M:\win>git annex sync
+ ...works
+ M:\win>git annex get .
+ ...works
+ M:\win>cat lintest
+ lintest
+ ```
+
+so far so good.
+###### 5. Now the renaming part (performed on linux indirect repo)
+
+ ```bash
+ [michele@home local]$ git mv lintest renamed
+ [michele@home local]$ git annex list
+ here
+ |origin
+ ||web
+ |||
+ XX_ renamed
+ [michele@home local]$ git annex sync
+ ...works
+ ```
+
+###### 6. now, by issuing sync on windows I start getting a "push issue":
+
+ ```
+ M:\win>git annex sync
+ commit
+ ok
+ pull origin
+ remote: Counting objects: 3, done.
+ remote: Total 2 (delta 0), reused 0 (delta 0)
+ Unpacking objects: 100% (2/2), done.
+ From ssh://home/home/michele/casa
+ c3b7a63..a0854bf master -> origin/master
+ c3b7a63..a0854bf synced/master -> origin/synced/master
+ ok
+ push origin
+ Counting objects: 9, done.
+ Delta compression using up to 2 threads.
+ Compressing objects: 100% (4/4), done.
+ Writing objects: 100% (5/5), 484 bytes, done.
+ Total 5 (delta 1), reused 0 (delta 0)
+ To ssh://michele@home/home/michele/casa
+ 6c18669..8cc74a0 git-annex -> synced/git-annex
+ ! [rejected] master -> synced/master (non-fast-forward)
+ error: failed to push some refs to 'ssh://michele@home/home/michele/casa'
+ hint: Updates were rejected because a pushed branch tip is behind its remote
+ hint: counterpart. Check out this branch and merge the remote changes
+ hint: (e.g. 'git pull') before pushing again.
+ hint: See the 'Note about fast-forwards' in 'git push --help' for details.
+ failed
+ git-annex: sync: 1 failed
+
+ M:\win>
+ ```
+
+at this stage I tried to issue a git annex merge, git annex sync, leading to same result.
+
+somewhere in the forum I read i could try issuing a git pull origin master (this could be the problem).
+and the result is as such:
+
+ ```
+ M:\win>git pull master
+ fatal: 'master' does not appear to be a git repository
+ fatal: The remote end hung up unexpectedly
+
+ M:\win>git pull origin master
+ From ssh://home/home/michele/casa
+ * branch master -> FETCH_HEAD
+ Updating c3b7a63..a0854bf
+ error: Your local changes to the following files would be overwritten by merge:
+ lintest
+ Please, commit your changes or stash them before you can merge.
+ Aborting
+
+ M:\win>git status
+ # On branch master
+ # Your branch is behind 'origin/master' by 1 commit, and can be fast-forwarded.
+ #
+ # Changes not staged for commit:
+ # (use "git add <file>..." to update what will be committed)
+ # (use "git checkout -- <file>..." to discard changes in working directory)
+ #
+ # modified: lintest
+ #
+ no changes added to commit (use "git add" and/or "git commit -a")
+
+ M:\win>cat lintest
+ lintest
+ ```
+
+well, ok it appears modified for some weirdness (crlf?), we can live with it.
+
+ ```
+ M:\win>git checkout -->> this replaces files contents with simlink (due to git pull above?)
+ ```
+
+at this stage content is lost, and annex has no knowledge about it.
+
+ ```
+ M:\win>git annex fsck
+ fsck lintest ok
+
+ M:\win>cat lintest
+ .git/annex/objects/9Z/82/SHA256E-s8--2b721dbe9afe6031cce3004e909dd62e0b4b2f3944438b6a000dffc7ad657715/SHA256E-s8--2b721dbe9afe6031cce3004e90
+ M:\win>git annex list
+ here
+ |origin
+ ||web
+ |||
+ XX_ lintest
+ ```
+
+still I cannot sync, but now i can pull origin master:
+
+ ```cmd
+ M:\win>git pull origin master From ssh://home/home/michele/casa * branch master -> FETCH_HEAD Updating c3b7a63..a0854bf Fast-forward lintest => renamed | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename lintest => renamed (100%)
+ ```
+
+this doesnt restore content (annex thinks its already there:
+
+ ```
+ M:\win>cat renamed
+ .git/annex/objects/9Z/82/SHA256E-s8--2b721dbe9afe6031cce3004e909dd62e0b4b2f3944438b6a000dffc7ad657715/SHA256E-s8--2b721dbe9afe6031cce3004e909dd62e0b4b2f3944438b6a000dffc7ad657715
+ ```
+
+I think my mistake is the use of the ```git checkout``` in direct mode. But why is the file detected as modified in the first place ?
+
+note: as long as i didn't drop on origin, i still can recover contents by 'forcing' a content refresh:
+
+ ```
+ M:\win>git annex get renamed --from origin
+ get renamed (from origin...)
+ SHA256E-s8--2b721dbe9afe6031cce3004e909dd62e0b4b2f3944438b6a000dffc7ad657715
+ 8 100% 7.81kB/s 0:00:00 (xfer#1, to-check=0/1)
+
+ sent 30 bytes received 153 bytes 8.13 bytes/sec
+ total size is 8 speedup is 0.04
+ ok
+ (Recording state in git...)
+
+ M:\win>cat renamed
+ .git/annex/objects/9Z/82/SHA256E-s8--2b721dbe9afe6031cce3004e909dd62e0b4b2f3944438b6a000dffc7ad657715/SHA256E-s8--2b721dbe9afe6031cce3004e909d
+ M:\win>git annex fsck
+ fsck renamed (fixing direct mode) (checksum...) ok
+
+ M:\win>cat renamed
+ lintest
+```
+
+
+
+
+
+
diff --git a/doc/forum/receiving_indirect_renames_on_direct_repo___63__/comment_1_f4b0a14373c75cb752597c832e296bcc._comment b/doc/forum/receiving_indirect_renames_on_direct_repo___63__/comment_1_f4b0a14373c75cb752597c832e296bcc._comment
new file mode 100644
index 000000000..7b38c6af4
--- /dev/null
+++ b/doc/forum/receiving_indirect_renames_on_direct_repo___63__/comment_1_f4b0a14373c75cb752597c832e296bcc._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 1"
+ date="2013-10-26T19:35:46Z"
+ content="""
+You should **never, ever, ever** run `git pull`, or `git checkout` inside a direct repository. You need to read [[direct_mode]]. If you do not fully understand it, you should avoid running any git commands that are not `git annex foo` in a direct mode repository. If you forget and do run such git commands, you can generally recover by running `git annex fsck`, although it's possible that the git command you run overwrites your only copy of a file, and so you'd lose it.
+
+<pre>
+To ssh://michele@home/home/michele/casa
+ 6c18669..8cc74a0 git-annex -> synced/git-annex
+ ! [rejected] master -> synced/master (non-fast-forward)
+error: failed to push some refs to 'ssh://michele@home/home/michele/casa'
+</pre>
+
+I'll bet that if you look at the `git config` of this repository it failed to push to, you'll find that it has `receive.denyNonFastforwards` set to true. If you unset that, the push should work.
+"""]]
diff --git a/doc/forum/receiving_indirect_renames_on_direct_repo___63__/comment_2_8c86dfc99f0b9040402c9d746decda53._comment b/doc/forum/receiving_indirect_renames_on_direct_repo___63__/comment_2_8c86dfc99f0b9040402c9d746decda53._comment
new file mode 100644
index 000000000..8b4ff46a4
--- /dev/null
+++ b/doc/forum/receiving_indirect_renames_on_direct_repo___63__/comment_2_8c86dfc99f0b9040402c9d746decda53._comment
@@ -0,0 +1,41 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkJafmCf-sg9_OM0pynFYM3AO4WCgJiaMI"
+ nickname="Michele"
+ subject="still cannot push when remote has renames"
+ date="2013-10-27T23:06:03Z"
+ content="""
+now, I went again through docs, and i realized how stupid was issuing a git pull on a direct repo. thanks for your patience.
+
+but, i double checked the configuration, I assume \"receive.denyNonFastForwards\" is false by default, but anyway I set it up explicitely so that now my git config (on the linux indirect repo - with respect to my previous example, I got rid of the \"extra\" bare repo in the middle) shows:
+
+ $ git config --list
+ user.email=m@g.com
+ user.name=michele
+ core.repositoryformatversion=0
+ core.filemode=true
+ core.bare=false
+ core.logallrefupdates=true
+ annex.uuid=d084e0fd-95a7-4c98-a206-fbf2c85b779d
+ annex.version=3
+ receive.denynonfastforwards=false
+
+still I am receiving the push refusal:
+
+ M:\win>git annex sync
+ commit
+ ok
+ pull origin
+ ok
+ push origin
+ To ssh://michele@home/home/michele/casa
+ ! [rejected] master -> synced/master (non-fast-forward)
+ error: failed to push some refs to 'ssh://michele@home/home/michele/casa'
+ hint: Updates were rejected because a pushed branch tip is behind its remote
+ hint: counterpart. Check out this branch and merge the remote changes
+ hint: (e.g. 'git pull') before pushing again.
+ hint: See the 'Note about fast-forwards' in 'git push --help' for details.
+ failed
+ git-annex: sync: 1 failed
+
+Same happens with a bare repository in the middle. BTW: the windows \"client\" repository is behind NAT, so that the linux indirect doesn't actively sync against it: could that be source of the problem ?
+"""]]
diff --git a/doc/forum/receiving_indirect_renames_on_direct_repo___63__/comment_3_0246fff6c7c75f6be45bd257ec3872a5._comment b/doc/forum/receiving_indirect_renames_on_direct_repo___63__/comment_3_0246fff6c7c75f6be45bd257ec3872a5._comment
new file mode 100644
index 000000000..0ffb2a097
--- /dev/null
+++ b/doc/forum/receiving_indirect_renames_on_direct_repo___63__/comment_3_0246fff6c7c75f6be45bd257ec3872a5._comment
@@ -0,0 +1,75 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkJafmCf-sg9_OM0pynFYM3AO4WCgJiaMI"
+ nickname="Michele"
+ subject="possible explanation"
+ date="2013-10-29T11:56:21Z"
+ content="""
+now, i tried to understand what happens. Instead of issuing the *git annex sync*, I relied on *git pull origin, git merge origin/master*, (I red [[http://git-annex.branchable.com/forum/Help_Windows_walkthrough/]] and I assume that pull origin / merge origin/master would work similarly to the \"download\" part of sync, *except for losing all my direct content*) just to understand what was going on, with a clarifying result:
+
+while git annex sync fails on push, git pull origin fails on pull:
+
+ M:\win>git pull origin
+ Updating 5408d6f..c566a69
+ error: Your local changes to the following files would be overwritten by merge:
+ myfile
+ Please, commit your changes or stash them before you can merge.
+ Aborting
+
+note that the file has not been modified locally (just got it through git annex get).
+issuing a git diff, reveals:
+
+ M:\win>git diff myfile
+ diff --git a/myfile b/myfile
+ index beaf3e8..dc5b4ff 120000
+ --- a/myfile
+ +++ b/myfile
+ @@ -1 +1 @@
+ -.git/annex/objects/z5/v7/SHA256E-s8--6090923ed0931dcc6699f32fb66fa4ba32c10924088b12c66fb4ce35a91ba98c/SHA256E-s8\ No newline at end of file
+ +linux.1
+ (END)
+
+ok, i follow suggestion, and I perform a git stash. that still wouldn't suffice for git annex sync:
+
+ M:\win>git annex sync
+ commit
+ ok
+ pull origin
+ ok
+ push origin
+ To ssh://michele@home/home/michele/homebase
+ ! [rejected] master -> synced/master (non-fast-forward)
+ error: failed to push some refs to 'ssh://michele@home/home/michele/homebase'
+ hint: Updates were rejected because a pushed branch tip is behind its remote
+ hint: counterpart. Check out this branch and merge the remote changes
+ hint: (e.g. 'git pull') before pushing again.
+ hint: See the 'Note about fast-forwards' in 'git push --help' for details.
+ failed
+ git-annex: sync: 1 failed
+
+now, i can perform instead a *git pull origin*, since I am confident my content is stashed.
+
+ M:\win>git pull origin
+ Updating 5408d6f..c566a69
+ Fast-forward
+ myfile => myfile.renamed | 0
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+ rename myfile => myfile.renamed (100%)
+
+merge is not doing anything more: at this stage content has gone (file is a direct-mode symlink nad it cannot be fixed by fsck).
+But i can recover it from stash (and I must do it unless I want to get the annex to think i still have content).
+
+ git stash apply
+
+voilà: the content is there! and the repos seems in good order.
+this only adds up that this is possibily a bug in the fact that git reports direct content as modified when indeed it hasn't been modified: but this affects git annex sync only when merging renaming files.
+git annex sync now works perfectly .
+
+to sum it up, I have two questions:
+
+1) does using stash to circumvent the problem expose me to any risk ?
+2) would the behaviour on receiving renames in the abovementioned situation worth to be signaled as a bug ?
+
+
+
+
+"""]]
diff --git a/doc/forum/recover_deleted_files___63__.mdwn b/doc/forum/recover_deleted_files___63__.mdwn
new file mode 100644
index 000000000..7bec36968
--- /dev/null
+++ b/doc/forum/recover_deleted_files___63__.mdwn
@@ -0,0 +1,66 @@
+hi,
+
+i think of use git-annex as the backbone of a archival systems. at first point no distributed storage, just 1 node.
+but now i run into the topic below ( deleted the "named" symlink of the "object" -- how to recover ?)
+
+maybe someone can enlighten me...
+
+thanks,
+.ka
+
+// about the version. ( debian-squeeze, bpo )
+
+$ git-annex version
+git-annex version: 3.20120629~bpo60+2
+local repository version: 3
+default repository version: 3
+supported repository versions: 3
+upgrade supported from repository versions: 0 1 2
+
+// building up a testcase.
+
+$ git init
+Initialized empty Git repository in ...test2/.git/
+
+$ git annex init
+init ok
+(Recording state in git...)
+
+$ echo "aaa" > 1.txt
+
+$ echo "bbb" > 2.txt
+
+$ git-annex add .
+add 1.txt (checksum...) ok
+add 2.txt (checksum...) ok
+(Recording state in git...)
+
+$ git commit -a -m "added 2 files"
+fatal: No HEAD commit to compare with (yet)
+fatal: No HEAD commit to compare with (yet)
+[master (root-commit) fc2a5d7] added 2 files
+ Committer: userhere user <bla@bla>
+Your name and email address were configured automatically based
+on your username and hostname. Please check that they are accurate.
+...
+ 2 files changed, 2 insertions(+), 0 deletions(-)
+ create mode 120000 1.txt
+ create mode 120000 2.txt
+
+// ok, so far standard. i have now 2 files - lets delete one.
+
+$ rm 2.txt
+$ ls -l
+lrwxrwxrwx 1 xp xp 176 24. Okt 22:55 1.txt -> .git/annex/objects/Z6/7q/SHA256-s4--17e682f060b5f8e47ea04c5c4855908b0a5ad612022260fe50e11ecb0cc0ab76/SHA256-s4--17e682f060b5f8e47ea04c5c4855908b0a5ad612022260fe50e11ecb0cc0ab76
+
+// eek, delete of 2.txt was a bad idea (it was just the symlink) -- try to recover...
+
+$ git-annex fix
+$ git-annex fsck
+fsck 1.txt (checksum...) ok
+$ ls
+1.txt
+
+// still not here.. how to recover the link to 2.txt ???
+// i still see the content of the file in the object folder
+// if I want to use git-annex as the backend of a archival system, this is important.
diff --git a/doc/forum/recover_deleted_files___63__/comment_1_d7abb7c45c6ec2723a04f153ed215453._comment b/doc/forum/recover_deleted_files___63__/comment_1_d7abb7c45c6ec2723a04f153ed215453._comment
new file mode 100644
index 000000000..646e7ad54
--- /dev/null
+++ b/doc/forum/recover_deleted_files___63__/comment_1_d7abb7c45c6ec2723a04f153ed215453._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://ciffer.net/~svend/"
+ ip="2001:1938:81:1ff::2"
+ subject="git checkout"
+ date="2012-10-24T22:50:05Z"
+ content="""
+You can use `git checkout -- file` to restore the link. `git status` will display information for restoring the file.
+"""]]
diff --git a/doc/forum/recover_deleted_files___63__/comment_2_8ea2acaa30d3ee7e9f75310f4ec859b2._comment b/doc/forum/recover_deleted_files___63__/comment_2_8ea2acaa30d3ee7e9f75310f4ec859b2._comment
new file mode 100644
index 000000000..c99461ae0
--- /dev/null
+++ b/doc/forum/recover_deleted_files___63__/comment_2_8ea2acaa30d3ee7e9f75310f4ec859b2._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.138"
+ subject="it's a git repository..."
+ date="2012-10-25T03:29:20Z"
+ content="""
+So any git stuff can be used. If you deleted a file, committed it, and want to undo that, you can `git log --stat` to find the commit, and `git revert` it. If you deleted a file, haven't committed yet, and want one more look at it, you can `git stash` to get it back, and `git stash apply` to re-stash the change. Or yeah, just `git checkout` to get back a deleted file you have not committed yet.
+"""]]
diff --git a/doc/forum/recover_deleted_files___63__/comment_3_376de81c70799bf409be189a48234815._comment b/doc/forum/recover_deleted_files___63__/comment_3_376de81c70799bf409be189a48234815._comment
new file mode 100644
index 000000000..89edb17eb
--- /dev/null
+++ b/doc/forum/recover_deleted_files___63__/comment_3_376de81c70799bf409be189a48234815._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="ka7"
+ ip="2001:7b8:155d:0:222:64ff:fe16:dc52"
+ subject="ok, that worked."
+ date="2012-10-25T20:15:26Z"
+ content="""
+i think of a kind of \"WORM-library\", so basically just add, not allow to remove content. (at least not for the user thru the mounted device)
+- so a script to add/commit -- but as stag-1 check for delete files and get them back. some git magic needed, but should be doable.
+- or thru \"samba\" parameters set to add but not delete/overwrite files. (read yes, write yes, delete no) -- to be proved thats possible, but not your job :) ( annex-ing via cron every /5 or via inotify)
+so yea, will play for a while and maybe come back with new. thanks to everybody.
+<3 git-annex <3
+"""]]
diff --git a/doc/forum/recovering_from_repo_corruption.mdwn b/doc/forum/recovering_from_repo_corruption.mdwn
new file mode 100644
index 000000000..42df61b78
--- /dev/null
+++ b/doc/forum/recovering_from_repo_corruption.mdwn
@@ -0,0 +1,11 @@
+In my current annex config, I have 4 computers with "traditional" git annexes as well as an external drive that is a git annex, an rsync'd backup annex, and a glacier archive. Today, one of the computers got a corrupted git repo. It was complaining that a pack file was invalid. In my attempts to fix it, a commit was logged that deleted every file in the annex. I didn't find this out until I did 'git annex sync' and watched git delete everything, then send all those commits to my other 3 systems and the external drive. *facepalm*
+
+Fortunately, I had one of those other systems in direct mode and I copied everything from the annex as a backup. Now, when I try to re-add files to the annex, I'm running into some errors. These appear to be "collisions" within the annex part of the .git folder:
+
+ % › git annex add House.netspd
+ add House.netspd (checksum...)
+ git-annex: /Users/akraut/Desktop/annex/.git/annex/objects/31/Gw/SHA256E-s167433--41e68ea0adb5a4086a0b7b39d0556b9b86523ffb6b498d58f12f96460da315e9/SHA256E-s167433--41e68ea0adb5a4086a0b7b39d0556b9b86523ffb6b498d58f12f96460da315e9.map.tmp62699: openFile: permission denied (Permission denied)
+ failed
+ git-annex: add: 1 failed
+
+Any ideas on what's going on here? Perhaps how to get things added back in or recovered? It seems all the actual file contents are here, but annex doesn't seem to know they're there anymore.
diff --git a/doc/forum/recovering_from_repo_corruption/comment_1_01fc85037e24fc70e5c5329898cf6781._comment b/doc/forum/recovering_from_repo_corruption/comment_1_01fc85037e24fc70e5c5329898cf6781._comment
new file mode 100644
index 000000000..ab65b42cb
--- /dev/null
+++ b/doc/forum/recovering_from_repo_corruption/comment_1_01fc85037e24fc70e5c5329898cf6781._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="99.54.57.201"
+ subject="comment 1"
+ date="2013-01-26T07:11:35Z"
+ content="""
+speaking strictly from the git point of view, you can create a new commit that reverses an old commit completely.
+
+ git revert <commit>
+
+creates a new commit which does the exact opposite of the commit you specify. Theoretically it bring everything back to you quick and clean!
+
+
+
+"""]]
diff --git a/doc/forum/recovering_from_repo_corruption/comment_2_3bd1c0bf25a0e892e711a60f53cd5298._comment b/doc/forum/recovering_from_repo_corruption/comment_2_3bd1c0bf25a0e892e711a60f53cd5298._comment
new file mode 100644
index 000000000..c8df9c0a0
--- /dev/null
+++ b/doc/forum/recovering_from_repo_corruption/comment_2_3bd1c0bf25a0e892e711a60f53cd5298._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmRFKwny4rArBaz-36xTcsJYqKIgdDaw5Q"
+ nickname="Andrew"
+ subject="comment 2"
+ date="2013-01-26T08:13:34Z"
+ content="""
+Oh! Good call. That worked, though I did have to sync and revert alternately a few times to get things resolved. I still haven't figured out what exactly happened, though. In two separate instances, the commit message was \"git-annex automatic sync\"
+"""]]
diff --git a/doc/forum/recovering_from_repo_corruption/comment_3_679dde8ca0081fc6854d6d2e8a42abdb._comment b/doc/forum/recovering_from_repo_corruption/comment_3_679dde8ca0081fc6854d6d2e8a42abdb._comment
new file mode 100644
index 000000000..9b724b143
--- /dev/null
+++ b/doc/forum/recovering_from_repo_corruption/comment_3_679dde8ca0081fc6854d6d2e8a42abdb._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 3"
+ date="2013-01-26T09:11:00Z"
+ content="""
+I've fixed the bug that led to the permissions denied error.
+"""]]
diff --git a/doc/forum/reinstalled_os__44___cloned_annex__44___does_not_recognize_remote.mdwn b/doc/forum/reinstalled_os__44___cloned_annex__44___does_not_recognize_remote.mdwn
new file mode 100644
index 000000000..2c437fe35
--- /dev/null
+++ b/doc/forum/reinstalled_os__44___cloned_annex__44___does_not_recognize_remote.mdwn
@@ -0,0 +1,8 @@
+Hi,
+
+I switched distribution and cloned my annex from the backup afterwards. getting the files from my backup worked fine, but i have a remote on an external disk and git-annex keeps saying it's unavailable despite it being there. I have the same username and hostname as on my old system so and the remote repo still has the uuid 3d661c5e-c84e-4902-b52e-decbafadfa4f. The only thing that changed is the path, it's know mounted unter /var/run/media/phaer/95... but a symlinked to the path below did not help. Any suggestions?
+
+ 3d661c5e-c84e-4902-b52e-decbafadfa4f -- phaer@kassiopeia:/media/phaer/9502bc14-b83e-471a-95a8-80ff9072a4ab/annex
+
+
+and thank you for this amazing piece of software.
diff --git a/doc/forum/reinstalled_os__44___cloned_annex__44___does_not_recognize_remote/comment_1_c1962d757dd22f49e774afa13a9862ca._comment b/doc/forum/reinstalled_os__44___cloned_annex__44___does_not_recognize_remote/comment_1_c1962d757dd22f49e774afa13a9862ca._comment
new file mode 100644
index 000000000..1223b2414
--- /dev/null
+++ b/doc/forum/reinstalled_os__44___cloned_annex__44___does_not_recognize_remote/comment_1_c1962d757dd22f49e774afa13a9862ca._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="64.134.31.139"
+ subject="comment 1"
+ date="2013-10-21T22:24:35Z"
+ content="""
+It might help if you pasted the actual error message that git-annex shows when you try to use this remote. Along with the part of .git/config that configures this remote.
+
+In general, git-annex does not are if you've reinstalled your OS, moved things around, etc. As long as the git remote's path points to a repository, git-annex will see it and be able to use it.
+"""]]
diff --git a/doc/forum/reinstalled_os__44___cloned_annex__44___does_not_recognize_remote/comment_2_1f0f4a1dc89643cee81ff7199b55e747._comment b/doc/forum/reinstalled_os__44___cloned_annex__44___does_not_recognize_remote/comment_2_1f0f4a1dc89643cee81ff7199b55e747._comment
new file mode 100644
index 000000000..f38c0c752
--- /dev/null
+++ b/doc/forum/reinstalled_os__44___cloned_annex__44___does_not_recognize_remote/comment_2_1f0f4a1dc89643cee81ff7199b55e747._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBhQgaA5QrFwT67-Bo0qPIx0HD9roDrso"
+ nickname="Paul"
+ subject="comment 2"
+ date="2013-11-20T11:20:13Z"
+ content="""
+The problem was just a missing git remote. Sorry & thanks
+"""]]
diff --git a/doc/forum/reliability__47__completeness_of_XMPP_updates.mdwn b/doc/forum/reliability__47__completeness_of_XMPP_updates.mdwn
new file mode 100644
index 000000000..fc558aad6
--- /dev/null
+++ b/doc/forum/reliability__47__completeness_of_XMPP_updates.mdwn
@@ -0,0 +1,7 @@
+This falls into the category of "noob questions" I think.
+
+The one piece of the git-annex assistant puzzle I've never messed with is XMPP pairing. I'm wondering how well a pair of repos can keep in sync with each other if their only connection is via XMPP. Will things go badly if changes are made to one while the other is offline? Do messages get queued up to deliver when they're both online? (Or do they get queued on the server side so they can be delivered even if one of them is online, makes changes, then goes offline, and the other one comes online later?)
+
+If some xmpp messages don't go through for whatever reason, will the remotes be able to "catch up" with each other later on and make up for lost time?
+
+Just hoping for a general sense of the limitations of XMPP pairing. TIA.
diff --git a/doc/forum/reliability__47__completeness_of_XMPP_updates/comment_1_e0f7aa48d54fc0564f41c3a569c723b7._comment b/doc/forum/reliability__47__completeness_of_XMPP_updates/comment_1_e0f7aa48d54fc0564f41c3a569c723b7._comment
new file mode 100644
index 000000000..d72cad5b9
--- /dev/null
+++ b/doc/forum/reliability__47__completeness_of_XMPP_updates/comment_1_e0f7aa48d54fc0564f41c3a569c723b7._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.90"
+ subject="comment 1"
+ date="2013-07-16T19:27:07Z"
+ content="""
+Both clients have to be online at the same time for XMPP push to work. Once they're able to see each other, they'll sync up, even if they've diverged since the last sync.
+
+If you tend to only have one client or the other online, you should set up a git repo on a ssh server. Then clients will drop off their changes there, and the other one will check it when it comes online. (You don't really need to use XMPP at all in this case.)
+
+The most robust and fast combo is to use XMPP pairing, and also have a git repo on a ssh server. This way, when both clients are online, they'll use XMPP to instantly propagate changes, and when not the server is there to fall back to.
+"""]]
diff --git a/doc/forum/reliability__47__completeness_of_XMPP_updates/comment_2_4e74039a673c16c0163f2cfb406dc4c3._comment b/doc/forum/reliability__47__completeness_of_XMPP_updates/comment_2_4e74039a673c16c0163f2cfb406dc4c3._comment
new file mode 100644
index 000000000..b4e329441
--- /dev/null
+++ b/doc/forum/reliability__47__completeness_of_XMPP_updates/comment_2_4e74039a673c16c0163f2cfb406dc4c3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 2"
+ date="2013-07-16T23:36:22Z"
+ content="""
+Thanks, that was exactly the kind of explanation I needed.
+"""]]
diff --git a/doc/forum/reliability__47__completeness_of_XMPP_updates/comment_3_41ade4fe72804b2f06cd4dbf405c1746._comment b/doc/forum/reliability__47__completeness_of_XMPP_updates/comment_3_41ade4fe72804b2f06cd4dbf405c1746._comment
new file mode 100644
index 000000000..a212dbd09
--- /dev/null
+++ b/doc/forum/reliability__47__completeness_of_XMPP_updates/comment_3_41ade4fe72804b2f06cd4dbf405c1746._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="Flo"
+ ip="141.76.46.31"
+ subject="Git repositery?"
+ date="2013-07-19T08:56:04Z"
+ content="""
+I'm not sure to know what you mean with \"git repository on a SSH server\". I tried to use the assistant to add this git synchronization fall-back if XMPP is not available. However, it synchronizes all files too with this new repository. I tried to make it manual, unwanted, etc. But it stills send all my files on the transfer repository on rsync.net. I don't want that...
+"""]]
diff --git a/doc/forum/relying_on_git_for_numcopies.mdwn b/doc/forum/relying_on_git_for_numcopies.mdwn
new file mode 100644
index 000000000..37b46cf4e
--- /dev/null
+++ b/doc/forum/relying_on_git_for_numcopies.mdwn
@@ -0,0 +1,47 @@
+**&lt;out-of-date-warning&gt;**The main problems this is supposed to solve are addressed in a different way with [[todo/hidden files]] and the `--fast` option introduced in [[batch check on remote when using copy]], so while this is not technically obsolete, the main reasons for it are gone. --[[chrysn]]**&lt;/out-of-date-warning&gt;**
+
+This is a rough sketch of a modification of git-annex to rely more on git commit semantics. It might be flawed due to my lack of understanding of git-annex internals. --[[chrysn]]
+
+Summary
+=========
+
+Currently, [[location tracking]] is only used for informational purposes unless a repository is [[trust]]ed, in which case there is no checking at all. It is proposed to use the location tracking information as a commitment to keep track of a file until another repository takes over responsibility.
+
+git's semantics for atomic commits are proposed to be used, which makes sure that before files are actually deleted, another repository has accepted the deletion.
+
+Modified git-annex-drop behavior
+==========================
+
+The most important (if not only) git-annex command that is affected by this is `git annex drop`. Currently, for dropping a large number of files, every file is checked with another (or multiple, if so configured) host if it's safe to delete.
+
+The new behavior would be to
+
+* decrement the location tracking counter for all files to be dropped,
+* commit that change,
+* try to push it to at least as many repositories that the numcopies constraints are met,
+* revert if that fails,
+* otherwise really drop the files from the backend.
+
+Unlike explicit checking, this never looks at the remote backend if the file is really present -- otoh, git-annex already relies on the files in the backend to not be touched by anyone but git-annex itself, and git-annex would only drop them if they were derefed and committed, in which case git would not accept the push. (git by itself would accept a merged push, but even if the reverting step failed due to a power outage or similar, git-annex would, before really deleting files from the backend, check again if the numcopies restraint is still met, and revert its own delete commit as the files are still present anyway.)
+
+Implications for trust
+==============
+
+The proposed change also changes the semantics of trust. Trust can now be controlled in a finer-grained way between untrusted and semi-trusted, as best illustrated by a use case:
+
+> Alice takes her netbook with her on a trip through Spain, and will fill most of its disk up with pictures she takes. As she expects to meet some old friends during the first days, she wants to take older pictures with her, which are safely backed up at home, so they can be deleted on demand.
+>
+> She tells her netbook's repository to dereference the old images (but not other parts of the repository she has not copied anywhere yet) and pushes to the server before leaving. When she adds pictures from her camera to the repository, git-annex can now free up space as needed.
+
+Dereferencing could be implemented as `git annex drop --no-rm` (or `move --no-rm`), freeing space is similar to `dropunused`.
+
+A trusted repository with the new semantics would mean that the repository would not accept dropping anything, just as before.
+
+Advantages / Disadvantages
+=====================
+
+The advantage of this proposal is that the round trips required for dropping something could be greatly reduced.
+
+There should also be simplifications in the `git annex drop` command as it doesn't need to take care of locking any more (git should already do that between checking if HEAD is a parent of the pushed commit and replacing HEAD).
+
+Besides being a major change in git-annex (with the requirement to track hosts' git-annex versions for migration, as the new trust system is incompatible with the old one), no disadvantages of that stragegy are known to the author (hoping for discussion below).
diff --git a/doc/forum/relying_on_git_for_numcopies/comment_1_8ad3cccd7f66f6423341d71241ba89fc._comment b/doc/forum/relying_on_git_for_numcopies/comment_1_8ad3cccd7f66f6423341d71241ba89fc._comment
new file mode 100644
index 000000000..83a908da8
--- /dev/null
+++ b/doc/forum/relying_on_git_for_numcopies/comment_1_8ad3cccd7f66f6423341d71241ba89fc._comment
@@ -0,0 +1,36 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-02-22T18:44:28Z"
+ content="""
+I see the following problems with this scheme:
+
+- Disallows removal of files when disconnected. It's currently safe to force that, as long as
+ git-annex tells you enough other repos are belived to have the file. Just as long as you
+ only force on one machine (say your laptop). With your scheme, if you drop a file while
+ disconnected, any other host could see that the counter is still at N, because your
+ laptop had the file last time it was online, and can decide to drop the file, and lose the last
+version.
+
+- pushing a changed counter commit to other repos is tricky, because they're not bare, and
+ the network topology to get the commit pulled into the other repo could vary.
+
+- Merging counter files issues. If the counter file doesn't automerge, two repos dropping the same file will conflict. But, if it does automerge, it breaks the counter conflict detection.
+
+- Needing to revert commits is going to be annoying. An actual git revert
+ could probably not reliably be done. It's need to construct a revert
+ and commit it as a new commit. And then try to push that to remotes, and
+ what if *that* push conflicts?
+
+- I do like the pre-removal dropping somewhat as an alternative to
+ trust checking. I think that can be done with current git-annex though,
+ just remove the files from the location log, but keep them in-annex.
+ Dropping a file only looks at repos that the location log says have a
+ file; so other repos can have retained a copy of a file secretly like
+ this, and can safely remove it at any time. I'd need to look into this a bit more to be 100% sure it's safe, but have started [[todo/hidden_files]].
+
+- I don't see any reduced round trips. It still has to contact N other
+ repos on drop. Now, rather than checking that they have a file, it needs
+ to push a change to them.
+"""]]
diff --git a/doc/forum/relying_on_git_for_numcopies/comment_2_be6acbc26008a9cb54e7b8f498f2c2a2._comment b/doc/forum/relying_on_git_for_numcopies/comment_2_be6acbc26008a9cb54e7b8f498f2c2a2._comment
new file mode 100644
index 000000000..d9ce8b50e
--- /dev/null
+++ b/doc/forum/relying_on_git_for_numcopies/comment_2_be6acbc26008a9cb54e7b8f498f2c2a2._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="http://christian.amsuess.com/chrysn"
+ nickname="chrysn"
+ subject="comment 2"
+ date="2011-02-23T16:43:59Z"
+ content="""
+i'll comment on each of the points separately, well aware that even a single little leftover issue can show that my plan is faulty:
+
+* force removal: well, yes -- but the file that is currently force-removed on the laptop could just as well be the last of its kind itself. i see the problem, but am not sure if it's fatal (after all, if we rely on out-of-band knowledge when forcing something, we could just as well ask a little more)
+* non-bare repos: pushing is tricky with non-bare repos now just as well; a post-commit hook could auto-accept counter changes. (but pushing causes problems with counters anyway, doesn't it?)
+* merging: i'd have them auto-merge. git-annex will have to check the validity of the current state anyway, and a situation in which a counter-decrementing commit is not a fast-forward one would be reverted in the next step (or upon discovery, in case the next step never took place).
+* reverting: my wording was bad as \"revert\" is already taken in git-lingo. the correct term for what i was thinking of is \"reset\". (as the commit could not be pushed, it would be rolled back completely).
+ * we might have to resort to reverting, though, if the commit has already been pused to a first server of many.
+* [[todo/hidden files]]: yes, this solves pre-removal dropping :-)
+* round trips: it's not the number of servers, it's the number of files (up to 30k in my case). it seems to me that an individual request was made for every single file i wanted to drop (that would be N*M roundtrips for N affected servers and M files, and N roundtrips with git managed numcopies)
+
+all together, it seems to be a bit more complicated than i imagined, although not completely impossible. a combination of [[todo/hidden files]] and maybe a simpler reduction of the number of requests might though achieve the important goals as well.
+"""]]
diff --git a/doc/forum/relying_on_git_for_numcopies/comment_3_43d8e1513eb9947f8a503f094c03f307._comment b/doc/forum/relying_on_git_for_numcopies/comment_3_43d8e1513eb9947f8a503f094c03f307._comment
new file mode 100644
index 000000000..27076a877
--- /dev/null
+++ b/doc/forum/relying_on_git_for_numcopies/comment_3_43d8e1513eb9947f8a503f094c03f307._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://christian.amsuess.com/chrysn"
+ nickname="chrysn"
+ subject="relation to [[todo/branching]]"
+ date="2011-02-23T21:48:14Z"
+ content="""
+the non-bare repository issue would go away if this was combined with the \"alternate\" approach to [[todo/branching]]. (with the \"fleshed out proposal\" of branching, this would not work at all for lack of shared commits.)
+"""]]
diff --git a/doc/forum/remote_server_client_repositories_are_bare__33____63__.mdwn b/doc/forum/remote_server_client_repositories_are_bare__33____63__.mdwn
new file mode 100644
index 000000000..21c756836
--- /dev/null
+++ b/doc/forum/remote_server_client_repositories_are_bare__33____63__.mdwn
@@ -0,0 +1,17 @@
+I've gone through most of the screen casts and lots of documentation,
+but my first attempt produced an unexpected result.
+
+I wanted to use git-annex is a Dropbox-simplistic setting - syncing
+a directory between my notebook (OSX) and my desktop (OpenSUSE 12.3).
+Running the assistant on OSX and adding a "Remote server" repository,
+changing the repository group to client produced a bare repository
+on the desktop.
+
+Am I missing something obvious?
+
+I've tried a few different version of git-annex, most recently
+
+ git-annex version: 4.20130727-g9399845
+ build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP
+
+but it remains the same.
diff --git a/doc/forum/remote_server_client_repositories_are_bare__33____63__/comment_1_234241460f6c75a8376b303b8dd4e882._comment b/doc/forum/remote_server_client_repositories_are_bare__33____63__/comment_1_234241460f6c75a8376b303b8dd4e882._comment
new file mode 100644
index 000000000..41e599c6d
--- /dev/null
+++ b/doc/forum/remote_server_client_repositories_are_bare__33____63__/comment_1_234241460f6c75a8376b303b8dd4e882._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmg8DSRA425Aik2clIuge8Jj-s7VJltsBI"
+ nickname="Tommy"
+ subject="comment 1"
+ date="2013-07-28T06:05:48Z"
+ content="""
+I found a partial answer on http://git-annex.branchable.com/forum/Add_a___34__local__34___remote :
+\"The webapp does not set up remote non-bare repositories because unless the user is comfortable with the cli, nothing is going to keep them up-to-date.\"
+
+So, clearly \"Remote server\" isn't what I want, but my \"desktop\" is headless and using jabber seems a silly complication when I have a perfectly fine ssh connection. This isn't as trivial as I had expected.
+"""]]
diff --git a/doc/forum/remote_server_client_repositories_are_bare__33____63__/comment_2_42dfc382d07af2a4f29c76016084f87c._comment b/doc/forum/remote_server_client_repositories_are_bare__33____63__/comment_2_42dfc382d07af2a4f29c76016084f87c._comment
new file mode 100644
index 000000000..84a2f36d6
--- /dev/null
+++ b/doc/forum/remote_server_client_repositories_are_bare__33____63__/comment_2_42dfc382d07af2a4f29c76016084f87c._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.21"
+ subject="comment 2"
+ date="2013-07-30T18:56:00Z"
+ content="""
+Make a non-bare git repository on your server. Run `git annex init` in it. Run `git annex assistant` in it.
+
+Now on your notebook, you can tell the assistant to use a remote ssh server, and point it at that directory. It will see the repository already exists, and use it, rather than making a new bare repository. The assistant daemon you've run on the server will notice when changes are pushed to the directory, and update it.
+
+You can further set up XMPP, so that the server can tell the notebook if you make any modifications to the server. You can do this by running `git annex webapp --listen=IPADDRESS` on the server, and opening the url it prints out. But this is optional, only needed if you're going to be editing files on the server.
+"""]]
diff --git a/doc/forum/reserving_space_with_directory_special_remotes.mdwn b/doc/forum/reserving_space_with_directory_special_remotes.mdwn
new file mode 100644
index 000000000..fea762c39
--- /dev/null
+++ b/doc/forum/reserving_space_with_directory_special_remotes.mdwn
@@ -0,0 +1,2 @@
+Can diskreserve be done with directory special remotes?
+Where should such per directory remote setting be put?
diff --git a/doc/forum/reserving_space_with_directory_special_remotes/comment_1_cd17b624704d93b51931023f69573323._comment b/doc/forum/reserving_space_with_directory_special_remotes/comment_1_cd17b624704d93b51931023f69573323._comment
new file mode 100644
index 000000000..83ef649ea
--- /dev/null
+++ b/doc/forum/reserving_space_with_directory_special_remotes/comment_1_cd17b624704d93b51931023f69573323._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.235"
+ subject="comment 1"
+ date="2013-07-10T23:50:53Z"
+ content="""
+Not currently supported. I've added a todo: [[todo/free_space_checking_for_local_special_remotes]]
+"""]]
diff --git a/doc/forum/reserving_space_with_directory_special_remotes/comment_2_877ca1be23d1484a8a30cdaeb6630053._comment b/doc/forum/reserving_space_with_directory_special_remotes/comment_2_877ca1be23d1484a8a30cdaeb6630053._comment
new file mode 100644
index 000000000..c34052ae3
--- /dev/null
+++ b/doc/forum/reserving_space_with_directory_special_remotes/comment_2_877ca1be23d1484a8a30cdaeb6630053._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawln3ckqKx0x_xDZMYwa9Q1bn4I06oWjkog"
+ nickname="Michael"
+ subject="comment 2"
+ date="2013-07-10T23:56:08Z"
+ content="""
+I was looking at git-annex git and saw this and thought it might be supported.
+
+commit 5cc76098ca7b702772ccf37a47f03da088148003
+Author: Joey Hess <joey@kitenet.net>
+Date: Fri Apr 20 16:24:44 2012 -0400
+
+ Directory special remotes now check annex.diskreserve.
+
+"""]]
diff --git a/doc/forum/reserving_space_with_directory_special_remotes/comment_3_65910eeaf3c6fcfd03f22c2957293232._comment b/doc/forum/reserving_space_with_directory_special_remotes/comment_3_65910eeaf3c6fcfd03f22c2957293232._comment
new file mode 100644
index 000000000..245849c5f
--- /dev/null
+++ b/doc/forum/reserving_space_with_directory_special_remotes/comment_3_65910eeaf3c6fcfd03f22c2957293232._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.235"
+ subject="comment 3"
+ date="2013-07-11T16:17:36Z"
+ content="""
+Shows what I know! It is supported. Repurposed the bug report to allow configuring a different diskreserve for the remote than the main annex.diskreserve..
+"""]]
diff --git a/doc/forum/retrieving_previous_versions.mdwn b/doc/forum/retrieving_previous_versions.mdwn
new file mode 100644
index 000000000..7626b7935
--- /dev/null
+++ b/doc/forum/retrieving_previous_versions.mdwn
@@ -0,0 +1,7 @@
+Hi,
+
+This might be a stupid question, but I did not find any information about it.
+Can I retrieve previous versions of a file?
+Let's say, I wanna do a "git annex get file", but considering a specific commit id. Is it possible? Are all the versions of the files kept inside .git/annex/objects?
+
+Thanks!
diff --git a/doc/forum/retrieving_previous_versions/comment_1_a4e83f688d4ec9177e7bf520f12ed26d._comment b/doc/forum/retrieving_previous_versions/comment_1_a4e83f688d4ec9177e7bf520f12ed26d._comment
new file mode 100644
index 000000000..ab2ecee31
--- /dev/null
+++ b/doc/forum/retrieving_previous_versions/comment_1_a4e83f688d4ec9177e7bf520f12ed26d._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2012-04-24T21:14:15Z"
+ content="""
+To get to a specific version of a file, you need to have a tag or a branch that includes that version of the file. Check out the branch and `git annex get $file`.
+
+(Of course, even without a tag or branch, old file versions are retained, unless dropped with `unused`/`dropunused`.
+So you could even `git checkout $COMMITID`.)
+"""]]
diff --git a/doc/forum/rsync_over_ssh__63__.mdwn b/doc/forum/rsync_over_ssh__63__.mdwn
new file mode 100644
index 000000000..9c0c9add6
--- /dev/null
+++ b/doc/forum/rsync_over_ssh__63__.mdwn
@@ -0,0 +1,2 @@
+[Walkthrough](http://git-annex.branchable.com/walkthrough/using_ssh_remotes/) says that when using ssh remotes rsync is used for transfering files. Is rsync used via ssh or unsecure?
+-- Michael K.
diff --git a/doc/forum/rsync_over_ssh__63__/comment_1_ee21f32e90303e20339e0a568321bbbe._comment b/doc/forum/rsync_over_ssh__63__/comment_1_ee21f32e90303e20339e0a568321bbbe._comment
new file mode 100644
index 000000000..2b9fc9552
--- /dev/null
+++ b/doc/forum/rsync_over_ssh__63__/comment_1_ee21f32e90303e20339e0a568321bbbe._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-03-06T15:59:37Z"
+ content="""
+Everything is done over ssh unless both repos are on the same system (or unless you NFS mount a repo)
+"""]]
diff --git a/doc/forum/rsync_over_ssh__63__/comment_2_aa690da6ecfb2b30fc5080ad76dc77b1._comment b/doc/forum/rsync_over_ssh__63__/comment_2_aa690da6ecfb2b30fc5080ad76dc77b1._comment
new file mode 100644
index 000000000..49003937b
--- /dev/null
+++ b/doc/forum/rsync_over_ssh__63__/comment_2_aa690da6ecfb2b30fc5080ad76dc77b1._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://m-f-k.myopenid.com/"
+ ip="92.194.43.135"
+ subject="comment 2"
+ date="2011-03-06T16:33:19Z"
+ content="""
+Great! This was the only thing about git-annex which could have kept me from using it. --Michael
+"""]]
diff --git a/doc/forum/rsync_remote_is_not_available_from_a_cloned_repo/comment_1_2e340c5a6473f165dc06cc35db38e5c0._comment b/doc/forum/rsync_remote_is_not_available_from_a_cloned_repo/comment_1_2e340c5a6473f165dc06cc35db38e5c0._comment
new file mode 100644
index 000000000..2b6ff45df
--- /dev/null
+++ b/doc/forum/rsync_remote_is_not_available_from_a_cloned_repo/comment_1_2e340c5a6473f165dc06cc35db38e5c0._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="hannes"
+ ip="130.226.142.243"
+ subject="original repo git annex version"
+ date="2012-07-08T11:55:42Z"
+ content="""
+is 3.20120629
+"""]]
diff --git a/doc/forum/rsyncing_.git__47__annex__47__objects.mdwn b/doc/forum/rsyncing_.git__47__annex__47__objects.mdwn
new file mode 100644
index 000000000..876b5e04a
--- /dev/null
+++ b/doc/forum/rsyncing_.git__47__annex__47__objects.mdwn
@@ -0,0 +1,24 @@
+In short: is it safe to rsync .git/annex/objects/ to other clones?
+
+I'm in the process of migrating a lot of my files to a new backend. Most them
+still use the old non-file-size-tracking SHA1 backend from when WORM was the
+default. I have multiple clones that each use about 460 GB of their 500 GB
+drives.
+
+I've noticed that git-annex creates hardlinks to migrated content in
+.git/annex/objects, so I'm able to migrate all content despite only having 40
+GB of free space. Excellent.
+
+Now I'm planning to `rsync -a --hard-links .git/annex/objects/
+${CLONE}/.git/annex/objects/` to recreate the hardlinks and save space on the
+clones as well. If I `fsck` afterwards, this should be fine, right?
+
+I've tried this with a test repository and it works but I'd like to be extra
+sure that I'm not missing something crucial.
+
+The alternatives that I'm aware of are:
+
+ * making space first: `git annex dropunused "1-20000"` and `git annex get .`
+ * running `git annex migrate` in each clone.
+
+I expect rsync to be safer and faster than these alternatives.
diff --git a/doc/forum/rsyncing_.git__47__annex__47__objects/comment_1_25eb9f7be5730337b9efd96dce9efd2e._comment b/doc/forum/rsyncing_.git__47__annex__47__objects/comment_1_25eb9f7be5730337b9efd96dce9efd2e._comment
new file mode 100644
index 000000000..8d9e22a7e
--- /dev/null
+++ b/doc/forum/rsyncing_.git__47__annex__47__objects/comment_1_25eb9f7be5730337b9efd96dce9efd2e._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.246"
+ subject="comment 1"
+ date="2013-11-16T17:36:48Z"
+ content="""
+As long as you fsck afterwards, this is fine.
+
+You might want to `git annex fsck --all` in case you have objects for old versions of files.
+"""]]
diff --git a/doc/forum/rsyncing_.git__47__annex__47__objects/comment_2_d7ceae666c8a1951021d3c6e6ac39a11._comment b/doc/forum/rsyncing_.git__47__annex__47__objects/comment_2_d7ceae666c8a1951021d3c6e6ac39a11._comment
new file mode 100644
index 000000000..f9c449f5e
--- /dev/null
+++ b/doc/forum/rsyncing_.git__47__annex__47__objects/comment_2_d7ceae666c8a1951021d3c6e6ac39a11._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="gernot"
+ ip="89.0.237.214"
+ subject="comment 2"
+ date="2013-11-18T15:09:59Z"
+ content="""
+Thanks for the confirmation, Joey! I also wouldn't have thought of `--all`.
+"""]]
diff --git a/doc/forum/s3_vs_ssh_Performance_Problems.mdwn b/doc/forum/s3_vs_ssh_Performance_Problems.mdwn
new file mode 100644
index 000000000..5176e196f
--- /dev/null
+++ b/doc/forum/s3_vs_ssh_Performance_Problems.mdwn
@@ -0,0 +1,8 @@
+I backup/sync my music using annex. I used to have one repo with 3 clones, one full copy on my vps, one full copy and one partial copy on my laptops. I decided to move all data to s3. Declared my vps repo dead, purged history (I do not care about history for this particular repo) pushed the git repo to a different computer (bare repo no data) and data to s3 (gpg encrypted). I've just finished uploading all files (around 200gb) couple files failed during the initial upload so I did a `git annex copy --quiet --to mys3 --fast` this command used to take 15 20 secs on my laptop when sending data to vps using ssh but now it took 2 hours to complete (pushing mem usage to 90%).
+
+I have one other repo (1.5gb in size 42k files using indirect mode, data gpg encrypted on s3) using the same setup except this repos content has always been on s3 i had the same behavior on this repo too. adding a file and running a copy to push content to s3 took couple hours even if I add a single 1kb file. I used to blame my hard drive, damn thing is slow but now I think this is related to s3. is there any workaround for this?
+
+Both machines are using,
+
+ git-annex version: 4.20130913-gd20a4f2
+ build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP Feeds Quvi
diff --git a/doc/forum/s3_vs_ssh_Performance_Problems/comment_1_65f064f09d7850abecab97007b0d30f0._comment b/doc/forum/s3_vs_ssh_Performance_Problems/comment_1_65f064f09d7850abecab97007b0d30f0._comment
new file mode 100644
index 000000000..aa3e06cc0
--- /dev/null
+++ b/doc/forum/s3_vs_ssh_Performance_Problems/comment_1_65f064f09d7850abecab97007b0d30f0._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="comment 1"
+ date="2013-11-21T04:09:15Z"
+ content="""
+Is
+
+ git annex copy --not --in mys3 --to mys3 .
+
+any faster?
+"""]]
diff --git a/doc/forum/s3_vs_ssh_Performance_Problems/comment_2_baaf2384d9196077268e9ca9bbe3b871._comment b/doc/forum/s3_vs_ssh_Performance_Problems/comment_2_baaf2384d9196077268e9ca9bbe3b871._comment
new file mode 100644
index 000000000..f54e49b2b
--- /dev/null
+++ b/doc/forum/s3_vs_ssh_Performance_Problems/comment_2_baaf2384d9196077268e9ca9bbe3b871._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/FHnTlSBo1eCGJRwueeKeB6.RCaPbGMPr5jxx8A--#ce0d8"
+ nickname="Hamza"
+ subject="comment 2"
+ date="2013-11-21T17:47:57Z"
+ content="""
+No difference. Both take roughly the same time but I did time a couple of runs with both commands they usually take 3 to 5 minutes to complete. Maybe git did something behind the scenes like gc? But still slower than it used to be. My other repo (one with 42k files) still takes a 2 hours.
+"""]]
diff --git a/doc/forum/s3_vs_ssh_Performance_Problems/comment_3_dc44be42070c073d150c476406e9b425._comment b/doc/forum/s3_vs_ssh_Performance_Problems/comment_3_dc44be42070c073d150c476406e9b425._comment
new file mode 100644
index 000000000..cbd460818
--- /dev/null
+++ b/doc/forum/s3_vs_ssh_Performance_Problems/comment_3_dc44be42070c073d150c476406e9b425._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="comment 3"
+ date="2013-11-22T20:21:11Z"
+ content="""
+Well it's not related to s3... that copy command won't even do any network traffic if there is nothing to copy. I have a similarly configured annex with 4500 files and that command takes 10 seconds to run.
+
+I do remember there being a recent fix that reduced the algorithmic complexity of an operation, but I forget which.
+"""]]
diff --git a/doc/forum/safely_dropping_git-annex_history.mdwn b/doc/forum/safely_dropping_git-annex_history.mdwn
new file mode 100644
index 000000000..a6d8e6677
--- /dev/null
+++ b/doc/forum/safely_dropping_git-annex_history.mdwn
@@ -0,0 +1,20 @@
+the git-annex branch of a repository i've had running since 2010 has grown to unmanagable dimensions (5gb in a fresh clone of the git-annex branch, while the master branch has merely 40mb, part of which is due to checked-in files), resulting in git-annex-merges to take in the order of magnitude of 15 minutes. getting an initial clone of the git-annex branch (not the data) takes hours alone in the "remote: Counting objects" phase (admittedly, the origin server is limited in ram, so it spends its time swapping the git process back and forth).
+
+is there a recommended way for how to reset the git-annex branch in a coordinated way? of course, this would have to happen on all copies of the repo at the same time.
+
+the workflow i currently imagine is
+
+* rename all copies of the repository (the_repo → the_repo-old, the_repo.git → the_repo-old.git)
+* clone the old origin repository to a new origin with --single-branch. (this would be *the* oportunity to ``git filter-branch --prune-empty --index-filter 'git rm --cached --ignore-unmatch .git-annex -r' master`` as well, to get rid of commits of pre-whatever versions)
+* ``git annex init`` on the master repository
+* clone it to all the other copies and ``git annex init`` there
+* set all the configuration options (untrusted repos etc) again
+* either
+ * ``git annex reinject`` the files that are already present on the respective machines, or
+ * move the .git/annex/objects files over from the original locations, and use ``git annex fsck`` to make git-annex discover which files it already has, if that works. (i have numcopies=2, thus i'd dare to move instead of copy even when trying this out the first time. complete copies, even of partially checked out clones, will exceed the capacities of most clients)
+
+my questions in that endeavor are:
+
+* is there already a standard workflow for this?
+* if not, will the above do the trick?
+* can anything be done to avoid such problems in future?
diff --git a/doc/forum/safely_dropping_git-annex_history/comment_10_a4b93a3fbc98d9b86e942f95e0039862._comment b/doc/forum/safely_dropping_git-annex_history/comment_10_a4b93a3fbc98d9b86e942f95e0039862._comment
new file mode 100644
index 000000000..b24a058f6
--- /dev/null
+++ b/doc/forum/safely_dropping_git-annex_history/comment_10_a4b93a3fbc98d9b86e942f95e0039862._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.140"
+ subject="comment 10"
+ date="2013-07-20T20:03:20Z"
+ content="""
+Since you seem to have found a way that works, I'm only answering for completeness: To resolve a conflicted merge on the git-annex branch, you can just add all lines present in either side of the merge, in any order. This won't necessarily be the most minimal resolution, but it is guaranteed to always be a valid one. There is a git-union-merge program in the git-annex source (not built by default) that can do that when merging any set of branches.
+"""]]
diff --git a/doc/forum/safely_dropping_git-annex_history/comment_11_383882fafd32f25ed22b5eb2fb3691b9._comment b/doc/forum/safely_dropping_git-annex_history/comment_11_383882fafd32f25ed22b5eb2fb3691b9._comment
new file mode 100644
index 000000000..fbfe64156
--- /dev/null
+++ b/doc/forum/safely_dropping_git-annex_history/comment_11_383882fafd32f25ed22b5eb2fb3691b9._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawln3ckqKx0x_xDZMYwa9Q1bn4I06oWjkog"
+ nickname="Michael"
+ subject="propagating squashed history to other remotes"
+ date="2013-08-12T01:44:59Z"
+ content="""
+The easiest method seems to be to force-push git-annex and master to other remotes, e.g.
+
+ git push -f myremote git-annex:refs/heads/git-annex
+
+Before doing this, make sure location logs etc had a chance to propagate across all remotes.
+
+It's a good idea to remove synched/ branches before doing git-annex sync on the repos with rewritten history, too:
+ git branch -D synced/master
+ git branch -D synced/annex
+
+
+"""]]
diff --git a/doc/forum/safely_dropping_git-annex_history/comment_12_47794a2abf29bf4ea2763ff89d872ab4._comment b/doc/forum/safely_dropping_git-annex_history/comment_12_47794a2abf29bf4ea2763ff89d872ab4._comment
new file mode 100644
index 000000000..5c0931604
--- /dev/null
+++ b/doc/forum/safely_dropping_git-annex_history/comment_12_47794a2abf29bf4ea2763ff89d872ab4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4830:1600:187::2"
+ subject="comment 12"
+ date="2013-09-04T06:38:00Z"
+ content="""
+`git annex forget` automates this now, without needing to force-push or have a flag day. Needs a version of git-annex supporting it installed on *all* the computers you use the repo on. Repos notice they need to forget when git annex is run in them, and do, automatically.
+"""]]
diff --git a/doc/forum/safely_dropping_git-annex_history/comment_1_4fd76d10a93fe01588fce7a621f9254d._comment b/doc/forum/safely_dropping_git-annex_history/comment_1_4fd76d10a93fe01588fce7a621f9254d._comment
new file mode 100644
index 000000000..e46f7291a
--- /dev/null
+++ b/doc/forum/safely_dropping_git-annex_history/comment_1_4fd76d10a93fe01588fce7a621f9254d._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.194"
+ subject="comment 1"
+ date="2012-10-31T16:03:55Z"
+ content="""
+Yes, you can use fsck like that. I outlined a similar approach [here](http://git-annex.branchable.com/forum/Delete_unused_files__47__metadata/#comment-e2bd822214df96606a60e8aee2c8637a), and I think you don't even need to make new git repositories, just delete the old branch and git gc it -- but I've not heard of anyone doing this yet.
+
+So, since 2010, your repo must have gone through at least one and probably two repository format changes, which bloated the git branch. Hopefully we'll have no more of those. My largest repo that also went through that is under 150 mb however.
+
+There was a recent bug fix where `git annex copy` unnecessarily updated location log even when the file was already copied. That kind of thing can bloat the repository, especially if you had that in a cron job... You might find `git annex log` useful to look through history of files and see if there have been a lot of location changes logged for whatever reason.
+"""]]
diff --git a/doc/forum/safely_dropping_git-annex_history/comment_2_10ecf3220ffcbbe94ba09da225458f18._comment b/doc/forum/safely_dropping_git-annex_history/comment_2_10ecf3220ffcbbe94ba09da225458f18._comment
new file mode 100644
index 000000000..21befd41a
--- /dev/null
+++ b/doc/forum/safely_dropping_git-annex_history/comment_2_10ecf3220ffcbbe94ba09da225458f18._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://christian.amsuess.com/chrysn"
+ nickname="chrysn"
+ subject="worked well"
+ date="2012-11-04T12:23:56Z"
+ content="""
+the procedure i outlined originally worked well for me; the method chosen for reinjection was moving over the .git/annex/objects directory and doing a ``git annex fsck``.
+
+special care had to be taken of the special remote (rsync+gpg) -- i guess that's why they are called special ;-) . as described in the forum post you linked, i had to copy over remote.log and the uuid.log line from the old git-annex branch -- otherwise, a ``git annex initremote`` would have generated a new hmac, effectively resetting the remote repo.
+
+the formerly 5gb git-annex branch (admittedly not ``git gc``'d recently, but that just wasn't feasible any more) shrunk down to around 25mb of current location information. i'll keep an eye on how it's growing to see if the problem is inherent or if it was just old bugs causing trouble.
+"""]]
diff --git a/doc/forum/safely_dropping_git-annex_history/comment_3_e3beb8acb075faaeef6c052aecbf0a41._comment b/doc/forum/safely_dropping_git-annex_history/comment_3_e3beb8acb075faaeef6c052aecbf0a41._comment
new file mode 100644
index 000000000..fbcbdbc4f
--- /dev/null
+++ b/doc/forum/safely_dropping_git-annex_history/comment_3_e3beb8acb075faaeef6c052aecbf0a41._comment
@@ -0,0 +1,50 @@
+[[!comment format=mdwn
+ username="http://vjt.myopenid.com/"
+ nickname="vjt"
+ subject="drop &quot;content removed from annex&quot; history"
+ date="2013-06-18T02:12:01Z"
+ content="""
+Joey,
+
+dropping the git-annex branch and subsequent fsck worked. Moreover, as I turned my repository in containing over 700k objects due to a silly cycle of `git annex add` / `git annex unannex`, bloating *both* `git-annex` and `master` history, to clean up I successfully performed a squashed rebase of master onto itself.
+
+Here's what I did, in detail:
+
+ $ git checkout git-annex
+ $ cp *.log ..
+ $ git checkout master
+ $ git br -D git-annex
+ $ git br -D synced/git-annex
+ $ git checkout <first commit>
+ $ git checkout -b git-annex
+ $ cp ../*.log .
+ $ <remove the changes done in the first commit, my case just adding a .gitignore>
+ $ git add *.log
+ $ git commit --amend -m 'Init'
+
+With this, I got rid of the many `update` commits. Now, the fun part:
+
+ $ git checkout master
+ $ git rebase -i <first commit>
+ <In the git-rebase-todo, I squashed almost everything, except a few commits I wanted to preserve>
+ $ :wq
+
+Rebase went fine, and I was left with a clean master. I brought also `synced/master` up to date:
+
+ $ git checkout synced/master
+ $ git reset --hard master
+
+Now I re-created all the location links with fsck:
+
+ $ git annex fsck
+
+And eventually, got rid of the redundant history:
+
+ $ git reflog expire --expire=now --expire-unreachable=now --all
+ $ git gc --prune=now
+ $ git repack
+ $ git prune
+
+yay, 500k objects less ^_^'.
+
+"""]]
diff --git a/doc/forum/safely_dropping_git-annex_history/comment_4_61a5fe2e7e47c60a8b237ea69404a37f._comment b/doc/forum/safely_dropping_git-annex_history/comment_4_61a5fe2e7e47c60a8b237ea69404a37f._comment
new file mode 100644
index 000000000..d257e6f62
--- /dev/null
+++ b/doc/forum/safely_dropping_git-annex_history/comment_4_61a5fe2e7e47c60a8b237ea69404a37f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawln3ckqKx0x_xDZMYwa9Q1bn4I06oWjkog"
+ nickname="Michael"
+ subject="would git annex fsck also recreate location tracking info for special remotes?"
+ date="2013-07-17T17:02:50Z"
+ content="""
+Suppose I want to drop history like discussed in this entry. How well does this deal with special (e.g. directory on an offline disk) remotes?
+"""]]
diff --git a/doc/forum/safely_dropping_git-annex_history/comment_5_426d02e2f2a2ae4ec7eae02dfe4519b3._comment b/doc/forum/safely_dropping_git-annex_history/comment_5_426d02e2f2a2ae4ec7eae02dfe4519b3._comment
new file mode 100644
index 000000000..aafa8fa1b
--- /dev/null
+++ b/doc/forum/safely_dropping_git-annex_history/comment_5_426d02e2f2a2ae4ec7eae02dfe4519b3._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawln3ckqKx0x_xDZMYwa9Q1bn4I06oWjkog"
+ nickname="Michael"
+ subject="comment 5"
+ date="2013-07-17T17:06:39Z"
+ content="""
+Also, would simply squashing git-annex branch history (without fsck etc) work?
+This seems easier.
+"""]]
diff --git a/doc/forum/safely_dropping_git-annex_history/comment_6_410a7296c2cee16d3d5bb618a5a41c1d._comment b/doc/forum/safely_dropping_git-annex_history/comment_6_410a7296c2cee16d3d5bb618a5a41c1d._comment
new file mode 100644
index 000000000..05ac27361
--- /dev/null
+++ b/doc/forum/safely_dropping_git-annex_history/comment_6_410a7296c2cee16d3d5bb618a5a41c1d._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.90"
+ subject="comment 6"
+ date="2013-07-17T18:57:12Z"
+ content="""
+You can use `git annex fsck --from remote` to verify that every file location tracking thinks is on the remote still is. It's innefficient though -- it has to download the whole file to check the special remote still has the right content! That transfer can be avoided by adding --fast.
+
+This is documented in the man page. :)
+"""]]
diff --git a/doc/forum/safely_dropping_git-annex_history/comment_7_42cf492fc98a9eba8176387749ef12e0._comment b/doc/forum/safely_dropping_git-annex_history/comment_7_42cf492fc98a9eba8176387749ef12e0._comment
new file mode 100644
index 000000000..5c10b988c
--- /dev/null
+++ b/doc/forum/safely_dropping_git-annex_history/comment_7_42cf492fc98a9eba8176387749ef12e0._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.90"
+ subject="comment 7"
+ date="2013-07-17T18:59:03Z"
+ content="""
+I don't see any reason why squashing git-annex branch history would not work. If you squash it to the same sha in each clone, things would be very happy, but even if you squash it to different shas, the union merge should result in those different versions of the same data automatically merging together.
+"""]]
diff --git a/doc/forum/safely_dropping_git-annex_history/comment_8_c0327ada073d8b69535f71b4dc6aa57e._comment b/doc/forum/safely_dropping_git-annex_history/comment_8_c0327ada073d8b69535f71b4dc6aa57e._comment
new file mode 100644
index 000000000..120e4daef
--- /dev/null
+++ b/doc/forum/safely_dropping_git-annex_history/comment_8_c0327ada073d8b69535f71b4dc6aa57e._comment
@@ -0,0 +1,21 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawln3ckqKx0x_xDZMYwa9Q1bn4I06oWjkog"
+ nickname="Michael"
+ subject="git annex merge driver?"
+ date="2013-07-19T17:04:53Z"
+ content="""
+
+I've tried rebasing git-annex branch, and I hit a bunch of conflicts (both in uuid.log and for individual content file logs) of the form:
+
+<pre><code>
+<<<<<<< HEAD
+1369615760.859476s 1 016d9095-0cbc-4734-a498-4e0421e257d7
+=======
+1369615760.845334s 1 016d9095-0cbc-4734-a498-4e0421e257d7
+>>>>>>> 52e60e8... update
+1369615359.195672s 1 38c359dc-a7d9-498d-a818-2e9beae995b8
+</code></pre>
+
+As I understand, git-annex has a special timestamp-based merge driver to deal with these. Is there a way to use that with git rebase?
+
+"""]]
diff --git a/doc/forum/safely_dropping_git-annex_history/comment_9_f83d6090aea2b7d5d54c876df940cbad._comment b/doc/forum/safely_dropping_git-annex_history/comment_9_f83d6090aea2b7d5d54c876df940cbad._comment
new file mode 100644
index 000000000..cbfd67850
--- /dev/null
+++ b/doc/forum/safely_dropping_git-annex_history/comment_9_f83d6090aea2b7d5d54c876df940cbad._comment
@@ -0,0 +1,40 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawln3ckqKx0x_xDZMYwa9Q1bn4I06oWjkog"
+ nickname="Michael"
+ subject="git checkout --orphan"
+ date="2013-07-19T17:49:37Z"
+ content="""
+Instead of rebase, --orphan seems to be the right answer for pruning history: create a new git-annex orphan branch and git add and commit the files. So:
+<pre><code>
+
+git status
+
+# verify there are no uncommitted or untracked files
+
+# master branch
+git branch -m old-master
+git checkout --orphan master
+git add .
+git commit -m 'first commit'
+
+# git annex branch
+git branch -m git-annex old-git-annex
+git checkout git-annex
+git checkout --orphan git-annex
+git add .
+git commit -m 'first commit'
+git checkout master
+
+# at this point, you may want to double-check that everything is still OK
+
+# finally, remove branches and clean up the objects:
+git branch -D old-master old-git-annex
+git reflog expire --expire=now --all
+git prune
+git gc
+
+</code></pre>
+
+The repo remains functional and .git is smaller.
+
+"""]]
diff --git a/doc/forum/seems_to_build_fine_on_haskell_platform_2011.mdwn b/doc/forum/seems_to_build_fine_on_haskell_platform_2011.mdwn
new file mode 100644
index 000000000..60014a7f5
--- /dev/null
+++ b/doc/forum/seems_to_build_fine_on_haskell_platform_2011.mdwn
@@ -0,0 +1 @@
+This is just a comment on git-annex building on haskell platform 2011.2.0.0 on archlinux. It just works.
diff --git a/doc/forum/shared_cipher_tries_to_use_gpg.mdwn b/doc/forum/shared_cipher_tries_to_use_gpg.mdwn
new file mode 100644
index 000000000..ccaa0c59d
--- /dev/null
+++ b/doc/forum/shared_cipher_tries_to_use_gpg.mdwn
@@ -0,0 +1,10 @@
+I tried
+
+ git annex initremote encsharedtest type=directory encryption=shared directory=/home/lee/gitannexplay
+
+and got errors:
+
+ initremote encsharedtest gpg: error reading key: public key not found
+
+Looks like it thinks "shared" should be the name of a key rather than an instruction to use the shared cipher.
+Am I doing something wrong?
diff --git a/doc/forum/shared_cipher_tries_to_use_gpg/comment_1_760961eaaa7d5c254dd71c5792437c9e._comment b/doc/forum/shared_cipher_tries_to_use_gpg/comment_1_760961eaaa7d5c254dd71c5792437c9e._comment
new file mode 100644
index 000000000..e97118b8a
--- /dev/null
+++ b/doc/forum/shared_cipher_tries_to_use_gpg/comment_1_760961eaaa7d5c254dd71c5792437c9e._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.23"
+ subject="comment 1"
+ date="2012-10-23T19:51:03Z"
+ content="""
+That's the right syntax, and it works when I try it, even if I move my `~/.gnupg` directory away.
+
+You sure you have a new enough git-annex for the shared cipher feature? It appeared in version 3.20120430
+
+You could try passing the `--debug` option to see what it's trying to do with gpg when it fails.
+"""]]
diff --git a/doc/forum/shared_cipher_tries_to_use_gpg/comment_2_f3260aea3a5bb9b95a9bdf1d0dfce090._comment b/doc/forum/shared_cipher_tries_to_use_gpg/comment_2_f3260aea3a5bb9b95a9bdf1d0dfce090._comment
new file mode 100644
index 000000000..7c36e7cf4
--- /dev/null
+++ b/doc/forum/shared_cipher_tries_to_use_gpg/comment_2_f3260aea3a5bb9b95a9bdf1d0dfce090._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlFUH5H4OUj9vMJIoXQs8bheiptgANQ6fU"
+ nickname="lee"
+ subject="A little too old"
+ date="2012-10-23T20:47:40Z"
+ content="""
+That's the problem, then. I have 3.20120406. For my purposes a gpg key with no passphrase works, though. Thanks.
+"""]]
diff --git a/doc/forum/something_really_good_happened_with_3.20130124.mdwn b/doc/forum/something_really_good_happened_with_3.20130124.mdwn
new file mode 100644
index 000000000..73b283822
--- /dev/null
+++ b/doc/forum/something_really_good_happened_with_3.20130124.mdwn
@@ -0,0 +1,5 @@
+The web app used to be unresponsive without manual refreshes. Now it's all snappy and responsive and quickly reflects what the assistant is doing.
+
+It used to be a complete crapshoot whether the assistant actually shut down when you told it to (either on the command line or through the webapp). I used to have to manually kill leftover assistants and child processes routinely. Now... you want it gone, and it's gone instantly, every time.
+
+Something really good happened with this last version, thank you joey!
diff --git a/doc/forum/something_really_good_happened_with_3.20130124/comment_1_1712bddd2f483a353f6313aa626445f1._comment b/doc/forum/something_really_good_happened_with_3.20130124/comment_1_1712bddd2f483a353f6313aa626445f1._comment
new file mode 100644
index 000000000..e0a4907c6
--- /dev/null
+++ b/doc/forum/something_really_good_happened_with_3.20130124/comment_1_1712bddd2f483a353f6313aa626445f1._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 1"
+ date="2013-01-25T22:35:00Z"
+ content="""
+We fixed some broken javascript that only worked in all the browsers I tried, but not yours. It's always been this cool, just glad you can also experience it now!
+"""]]
diff --git a/doc/forum/sparse_git_checkouts_with_annex.mdwn b/doc/forum/sparse_git_checkouts_with_annex.mdwn
new file mode 100644
index 000000000..97d2f445d
--- /dev/null
+++ b/doc/forum/sparse_git_checkouts_with_annex.mdwn
@@ -0,0 +1,31 @@
+I checked in my music collection into git annex (about 25000 files) and i'm really impressed by the performance of git annex (after i've done an git-repack). Now i'm also moving my movies into the same git-annex, but i have the following layout of my disk drives:
+
+* small raid-1 for important stuff (music, documents), which is also backupped (aka: raid)
+* big bulk data store (aka: media)
+
+In the git-annex the following layout of files is used:
+
+* documents/ <- on raid
+* music/ <- on raid
+* videos/ <- on media
+
+Now i didn't simply clone the raid-annex to media, but did an sparse-checkout (possible since version 1.7.0)
+
+* raid: .git-annex/, documents/ and music
+* media: .git-annex/, videos/
+
+As you can see i have to checkout the .git-annex directory with the file-logs twice which slows down git operations. Everything else works fine until now. git-annex doesn't have any problem, that only a part of the symlinks are present, which is really great. Is there a possibility to sparse checkout the .git-annex directory also? Perhaps splitting the log files in .git-annex/ into N subfolders, corresponding to the toplevel subfolders, like this?
+
+Before:
+
+ $ ls .git-annex
+ 00 01 02....
+
+After:
+
+ $ ls .git-annex
+ documents/ music/ videos/
+ $ ls .git-annex/documents
+ 00 01 02....
+
+This would make it possible to checkout only the part of the log files which i'm interested in.
diff --git a/doc/forum/sparse_git_checkouts_with_annex/comment_1_c7dc199c5740a0e7ba606dfb5e3e579a._comment b/doc/forum/sparse_git_checkouts_with_annex/comment_1_c7dc199c5740a0e7ba606dfb5e3e579a._comment
new file mode 100644
index 000000000..7adf4fc4d
--- /dev/null
+++ b/doc/forum/sparse_git_checkouts_with_annex/comment_1_c7dc199c5740a0e7ba606dfb5e3e579a._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-04-07T16:32:04Z"
+ content="""
+That's awesome, I had not heard of git sparse checkouts before.
+
+It does not make sense to tie the log files to the directory of the corresponding files, as then the logs would have to move when the files are moved, which would be a PITA and likely make merging log file changes very complex. Also, of course, multiple files in different locations can point at the same content, which has the same log file. And, to cap it off, git-annex can need to access the log file for a given key without having the slightest idea what file in the repository might point to it, and it would be very expensive to scan the whole repository to find out what that file is in order to lookup the filename of the log file.
+
+The most likely change in git-annex that will make this better is in [[this_todo_item|todo/branching]] -- but it's unknown how to do it yet.
+"""]]
diff --git a/doc/forum/sparse_git_checkouts_with_annex/comment_2_e357db3ccc4079f07a291843975535eb._comment b/doc/forum/sparse_git_checkouts_with_annex/comment_2_e357db3ccc4079f07a291843975535eb._comment
new file mode 100644
index 000000000..d8088a2d8
--- /dev/null
+++ b/doc/forum/sparse_git_checkouts_with_annex/comment_2_e357db3ccc4079f07a291843975535eb._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 2"
+ date="2011-04-07T16:33:30Z"
+ content="""
+BTW, git-annex unused *will* have a problem that not all the symlinks are present. It will suggest dropping content belonging to the excluded symlinks.
+"""]]
diff --git a/doc/forum/sparse_git_checkouts_with_annex/comment_3_fcfafca994194d57dccf5319c7c9e646._comment b/doc/forum/sparse_git_checkouts_with_annex/comment_3_fcfafca994194d57dccf5319c7c9e646._comment
new file mode 100644
index 000000000..1b849ef89
--- /dev/null
+++ b/doc/forum/sparse_git_checkouts_with_annex/comment_3_fcfafca994194d57dccf5319c7c9e646._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkptNW1PzrVjYlJWP_9e499uH0mjnBV6GQ"
+ nickname="Christian"
+ subject="comment 3"
+ date="2011-04-08T07:31:03Z"
+ content="""
+So perhaps checking if git-status (or similar) complains about missing files is a possible solution for this?
+"""]]
diff --git a/doc/forum/sparse_git_checkouts_with_annex/comment_4_04dc14880f31eee2b6d767d4d4258c5a._comment b/doc/forum/sparse_git_checkouts_with_annex/comment_4_04dc14880f31eee2b6d767d4d4258c5a._comment
new file mode 100644
index 000000000..9280fc51d
--- /dev/null
+++ b/doc/forum/sparse_git_checkouts_with_annex/comment_4_04dc14880f31eee2b6d767d4d4258c5a._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkptNW1PzrVjYlJWP_9e499uH0mjnBV6GQ"
+ nickname="Christian"
+ subject="comment 4"
+ date="2011-04-08T07:54:37Z"
+ content="""
+And something else i've done is, that i symlinked the video/ directory from the media annex to the normal raid annex
+
+ ln -s ~/media/annex/video ~/annex
+
+And it's working out great.
+
+ ~annex $ git annex whereis video/series/episode1.avi
+ whereis video/series/episode1.avi(1 copy)
+ f210b45a-60d3-11e0-b593-3318d96f2520 -- Trantor - Media
+ ok
+
+I really like this, perhaps it is a good idea to store all log files in every repo, but maybe there is a possibilitiy to to pack multiple log files into one single file, where not only the time, the present bit and the annex-repository is stored, but also the file key. I don't know if this format would also be merged correctly by the union merge driver.
+
+"""]]
diff --git a/doc/forum/special_remote_for_IMAP.mdwn b/doc/forum/special_remote_for_IMAP.mdwn
new file mode 100644
index 000000000..2aa956551
--- /dev/null
+++ b/doc/forum/special_remote_for_IMAP.mdwn
@@ -0,0 +1,44 @@
+I have implemented a special remote that stores files as email messages on an imap server. You need to install three utilities that the hooks invoke to deal with the email: mutt, imaputils, and munpack. I use mutt to send the email with the file as a mime attachment; imaputils talks to the imap server to check for and retrieve the message containing the desired file; and munpack extracts and decodes the attachment to get our file back.
+
+Several programs could be used in place of mutt, but the latter has a convenient command-line option for attaching files; mutt is of course available in the repositories of most linux distributions.
+
+imaputils is a perl program available at http://sourceforge.net/projects/imaputils/
+It has several perl library dependencies that you might need to download using the cpan tool.
+What imaputils does for you is provide a command line tool for interacting with the mail server. You can search for mail with a particular subject (for example), delete mail, retrieve messages, and in general do anything that you can do with a mail client such as mutt, but from the command line rather than a curses interface. This allows you to in turn write scripts that talk to imap servers.
+
+munpack is part of the mpack package. This is included in the Ubuntu and Debian repositories, and can probably be easily obtained for most linuxes. munpack extracts and decodes mime attachments from the command line.
+
+I define the special remote with
+
+ git annex initremote hogneygmail type=hook encryption=gitannex hooktype=hogneygmail
+
+The pgp key "gitannex" is a key established just for this purpose, that has no passphrase. This allows me to use encryption transparently. You could also use encryption=shared if your version of git-annex is recent enough. I also did
+
+ git annex untrust hogneygmail
+
+Here are the hooks:
+
+ hogneygmail-store-hook = mutt -n -s $ANNEX_KEY -a $ANNEX_FILE -- {email address} < /dev/null
+ hogneygmail-checkpresent-hook = "(imaputils.pl --conf {imap config file} --subject $ANNEX_KEY --count | grep -q \"1 messages\" -) && echo $ANNEX_KEY"
+ hogneygmail-retrieve-hook = "imaputils.pl --conf {imap config file} --subject $ANNEX_KEY --display | munpack -fq && mv $ANNEX_KEY $ANNEX_FILE; rm $ANNEX_KEY.desc"
+ hogneygmail-remove-hook = "imaputils.pl --conf {imap config file} --subject $ANNEX_KEY --delete"
+
+The bits inside of the curly brackets, for example {email address}, are what you need to specialize for your particular case (removing the brackets as well). The {imap config file} is a file that contains some configuration for imaputils. In my case it contains
+
+ ssl
+ pass {password}
+ host {mail host}
+ user {mail username}
+ box {name of mailbox to check}
+
+The first line tells imaputils to use ssl, and the third line is the address of the mail host. I include my username and password so I won't need to type these in repeatedly. Of course this means that you need to protect this file carefully.
+
+
+
+The operation of the hooks is pretty straightforward. The store-hook attaches the file to an otherwise empty email message with a subject equal to the name of the key, and mails it off. Note that if you use encryption then the keys generated by git-annex here will not be the same ones you see on your local disc. The checkpresent-hook asks the imap server how many emails have the subject equal to the key we are looking for; only if the reply contains "1 messages" are we sure the right one is there. The retrieve-hook uses the "--display" option to imaputils to stream the message, pipes it to munpack to silently extract the attachment (which is our (encrypted) file), and moves the result into the file contents. It then cleans up by deleting the .desc file that I can't prevent munpack from leaving on the disk, even when the message is blank. The remove-hook passes the "-- delete" option to imaputils to supposedly delete the target message from the mail server.
+
+I've performed very limited testing of this, and my knowledge of git and, especially, git-annex is very primitive, so I'm sure this could be vastly improved. In my testing with gmail this seems to work fine, except that messages do not get deleted from the server - I don't know why.
+
+I've developed this as an experiment and proof of concept, and have no knowledge of whether actually using this is in accord with the terms of service of gmail or any other mail service you might be using, nor whether it is safe or a good idea.
+
+-- Lee
diff --git a/doc/forum/special_remote_for_IMAP/comment_1_7c7d4b57a1b6508fff1a6b0508c861f8._comment b/doc/forum/special_remote_for_IMAP/comment_1_7c7d4b57a1b6508fff1a6b0508c861f8._comment
new file mode 100644
index 000000000..8d81dcfd0
--- /dev/null
+++ b/doc/forum/special_remote_for_IMAP/comment_1_7c7d4b57a1b6508fff1a6b0508c861f8._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="Neat idea"
+ date="2012-10-26T18:35:21Z"
+ content="""
+I imagine that most mail servers have a maximum attachment size; that seems the most likely problem with using this.
+
+The directory special remote has support for splitting up keys into chunks to work around file size limits. It would be good, I suppose, to add that to the hook special remote too.
+"""]]
diff --git a/doc/forum/special_remote_for_IMAP/comment_2_9c46fe8a857aa7a5ce797288144386bd._comment b/doc/forum/special_remote_for_IMAP/comment_2_9c46fe8a857aa7a5ce797288144386bd._comment
new file mode 100644
index 000000000..50358ea53
--- /dev/null
+++ b/doc/forum/special_remote_for_IMAP/comment_2_9c46fe8a857aa7a5ce797288144386bd._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlFUH5H4OUj9vMJIoXQs8bheiptgANQ6fU"
+ nickname="lee"
+ subject="chunking"
+ date="2012-10-26T22:05:16Z"
+ content="""
+That's a good point. But the splitting could easily be added to the hooks, and wouldn't need to be built in to git-annex.
+"""]]
diff --git a/doc/forum/special_remote_for_IMAP/comment_3_27e3b644df6942ce4c103236d0d5cb1b._comment b/doc/forum/special_remote_for_IMAP/comment_3_27e3b644df6942ce4c103236d0d5cb1b._comment
new file mode 100644
index 000000000..b5d9137e6
--- /dev/null
+++ b/doc/forum/special_remote_for_IMAP/comment_3_27e3b644df6942ce4c103236d0d5cb1b._comment
@@ -0,0 +1,23 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmWg4VvDTer9f49Y3z-R0AH16P4d1ygotA"
+ nickname="Tobias"
+ subject="comment 3"
+ date="2013-05-22T09:53:47Z"
+ content="""
+I had to change the checkpresent hook to:
+
+ hogneygmail-checkpresent-hook = (imaputils.pl --subject $ANNEX_KEY --count | grep -q \\"1 messages\\" -) && echo $ANNEX_KEY || exit 0
+
+Also, i have 5 files more than 30MB in size, that refuse to transfer.
+
+ postdrop: warning: uid=1001: File too large
+ sendmail: fatal: tou(1001): message file too big
+ Error sending message, child exited 75 (Deferred.).
+ Could not send the message.
+
+ store hook exited nonzero!
+ failed
+
+This really needs some split operations to support large files.
+
+"""]]
diff --git a/doc/forum/special_remote_for_iPods.mdwn b/doc/forum/special_remote_for_iPods.mdwn
new file mode 100644
index 000000000..eddda5936
--- /dev/null
+++ b/doc/forum/special_remote_for_iPods.mdwn
@@ -0,0 +1,5 @@
+I know versions of this question have been asked before, but I'm looking for a different answer.
+
+I would like a braindead special remote that can be used with devices such as portable music players. No symbolic links, no hashing, no rewriting of the filenames. The remote can be untrusted, file identity can be checked with just the filename and maybe the size. The "directory" special remote with the WORM backend seems to come closest, but does too much.
+
+Should I just try to roll it using hooks?
diff --git a/doc/forum/special_remote_for_iPods/comment_1_37cc3dc740341cc663074fd3bfb85947._comment b/doc/forum/special_remote_for_iPods/comment_1_37cc3dc740341cc663074fd3bfb85947._comment
new file mode 100644
index 000000000..35ac105c1
--- /dev/null
+++ b/doc/forum/special_remote_for_iPods/comment_1_37cc3dc740341cc663074fd3bfb85947._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.149"
+ subject="comment 1"
+ date="2012-10-05T00:39:43Z"
+ content="""
+I've been thinking in similar directions on this page: [[design/assistant/desymlink]]
+"""]]
diff --git a/doc/forum/speed_up_assistant_startup_on_large_repositories.mdwn b/doc/forum/speed_up_assistant_startup_on_large_repositories.mdwn
new file mode 100644
index 000000000..e43476c7b
--- /dev/null
+++ b/doc/forum/speed_up_assistant_startup_on_large_repositories.mdwn
@@ -0,0 +1 @@
+Starting the assistant on a repository with a huge amount of files (f.e. `annexed files in working tree: 22087`) takes a very long time. Is there a way to speed it up? F.e. just checking the file stamps and comparing them with the last assistant run time? Checking if the files are modified could be done with the regular repository check. Thoughts?
diff --git a/doc/forum/speed_up_assistant_startup_on_large_repositories/comment_1_5ba637a0f6d01ba24fe25e6265134e0a._comment b/doc/forum/speed_up_assistant_startup_on_large_repositories/comment_1_5ba637a0f6d01ba24fe25e6265134e0a._comment
new file mode 100644
index 000000000..0abe4dec8
--- /dev/null
+++ b/doc/forum/speed_up_assistant_startup_on_large_repositories/comment_1_5ba637a0f6d01ba24fe25e6265134e0a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 1"
+ date="2013-11-05T16:43:26Z"
+ content="""
+Checking the time stamps is what it does.
+
+How long is a very long time?
+"""]]
diff --git a/doc/forum/speed_up_assistant_startup_on_large_repositories/comment_2_d65746697977f8971a4b59f5b413f926._comment b/doc/forum/speed_up_assistant_startup_on_large_repositories/comment_2_d65746697977f8971a4b59f5b413f926._comment
new file mode 100644
index 000000000..e6915d232
--- /dev/null
+++ b/doc/forum/speed_up_assistant_startup_on_large_repositories/comment_2_d65746697977f8971a4b59f5b413f926._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawne_amN4fko4p5cRY_9EYwaYuJKNn7LRio"
+ nickname="Tobias"
+ subject="measuring how-to"
+ date="2013-11-08T16:55:58Z"
+ content="""
+How can I measure how much time the startup scan takes? I tried to find it out using the debug log, but couldn't find any usable notice when the startup scan was finished. Maybe this two lines?
+
+ [...]
+ [2013-11-08 16:00:45 CET] Watcher: Performing startup scan
+ [...]
+ [2013-11-08 16:15:30 CET] Watcher: watching
+"""]]
diff --git a/doc/forum/speed_up_assistant_startup_on_large_repositories/comment_3_be6c4fe5a0c745688438b716973791cc._comment b/doc/forum/speed_up_assistant_startup_on_large_repositories/comment_3_be6c4fe5a0c745688438b716973791cc._comment
new file mode 100644
index 000000000..d3fe6ef4c
--- /dev/null
+++ b/doc/forum/speed_up_assistant_startup_on_large_repositories/comment_3_be6c4fe5a0c745688438b716973791cc._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="108.236.230.124"
+ subject="comment 3"
+ date="2013-11-08T17:04:23Z"
+ content="""
+That's right.
+
+15 minutes is certainly a very long time.
+
+Is this on a slow spinning disk? USB disk?
+"""]]
diff --git a/doc/forum/speed_up_assistant_startup_on_large_repositories/comment_4_a07472338a08c068a9b88b2176fc2bee._comment b/doc/forum/speed_up_assistant_startup_on_large_repositories/comment_4_a07472338a08c068a9b88b2176fc2bee._comment
new file mode 100644
index 000000000..41e69ab1e
--- /dev/null
+++ b/doc/forum/speed_up_assistant_startup_on_large_repositories/comment_4_a07472338a08c068a9b88b2176fc2bee._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawniayrgSdVLUc3c6bf93VbO-_HT4hzxmyo"
+ nickname="Tobias"
+ subject="comment 4"
+ date="2013-11-17T17:28:06Z"
+ content="""
+The mentioned repository is stored on spinning disk.
+Maybe it would help to store the .git directory on an SSD, but I'm not sure how to do it.
+"""]]
diff --git a/doc/forum/ssh_password.mdwn b/doc/forum/ssh_password.mdwn
new file mode 100644
index 000000000..855e5992f
--- /dev/null
+++ b/doc/forum/ssh_password.mdwn
@@ -0,0 +1,3 @@
+Currently I have my netbook running git annex and a raspberry pi as a remote storage set up as a git repository. I currently have it set up so that from the terminal i can just do 'ssh pi@mypi -p XXX -C' and it has the password saved. Currently I'm having a problem that any time I add a file to my annex folder on my netbook I have to reenter my password for ssh-askpass for it to upload the file. Once that file is uploaded, it looks to me like it closes the connection and then reopens it and asks for my password again.
+
+I'm looking in ~/.ssh/ and I'm sure that something there needs to be edited or copied, I'm not really sure what though. Any suggestions?
diff --git a/doc/forum/ssh_password/comment_1_a3e5a41e1d4da683d577976b134b11ee._comment b/doc/forum/ssh_password/comment_1_a3e5a41e1d4da683d577976b134b11ee._comment
new file mode 100644
index 000000000..7ef938330
--- /dev/null
+++ b/doc/forum/ssh_password/comment_1_a3e5a41e1d4da683d577976b134b11ee._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://a-or-b.myopenid.com/"
+ ip="203.45.2.230"
+ subject="comment 1"
+ date="2013-05-30T00:08:52Z"
+ content="""
+It sounds like you don't have the ssh-agent set up properly in your environment.
+
+Try starting the git annex agent from the command line and see if that helps. If it works then it is a problem with environment variables.
+"""]]
diff --git a/doc/forum/ssh_password/comment_2_fa261676a99d49d4b237b0d43048d76d._comment b/doc/forum/ssh_password/comment_2_fa261676a99d49d4b237b0d43048d76d._comment
new file mode 100644
index 000000000..b7a47c9fe
--- /dev/null
+++ b/doc/forum/ssh_password/comment_2_fa261676a99d49d4b237b0d43048d76d._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-05-30T15:49:27Z"
+ content="""
+If you set this repository up using the git-annex webapp, and choosing \"remote ssh server\", it will generate a new ssh key, stored in `~/.ssh/git-annex/`, and it will configure `~/.ssh/config` to use this key for a special made-up hostname which is used in the url for the git remote. On the server, it will set up `~/.ssh/authorized_keys` to allow this ssh key to connect without a password and run git-annex-shell.
+
+I don't know if you used the webapp to set this up. If not, you can try to replicate this setup on your own. If you did and it's not working, you now know where all the peices it sets up are, to figure out what went wrong.
+"""]]
diff --git a/doc/forum/ssh_remote_-_no___34__use_a_git_repository__34___option_during_setup__63__.mdwn b/doc/forum/ssh_remote_-_no___34__use_a_git_repository__34___option_during_setup__63__.mdwn
new file mode 100644
index 000000000..06b58f973
--- /dev/null
+++ b/doc/forum/ssh_remote_-_no___34__use_a_git_repository__34___option_during_setup__63__.mdwn
@@ -0,0 +1,3 @@
+Hi,
+
+I own a computer that I use as a home server. I'm just getting started with git-annex, and I was trying to add an ssh remote. It connected fine, but only gave me the "encrypted rsync" option. I'd like to be able to access these files on the server as well, but the "use a git repository" option didn't show up. How do I enable this?
diff --git a/doc/forum/ssh_remote_-_no___34__use_a_git_repository__34___option_during_setup__63__/comment_1_7244794579a191a677190c60758f32e7._comment b/doc/forum/ssh_remote_-_no___34__use_a_git_repository__34___option_during_setup__63__/comment_1_7244794579a191a677190c60758f32e7._comment
new file mode 100644
index 000000000..14e51e79a
--- /dev/null
+++ b/doc/forum/ssh_remote_-_no___34__use_a_git_repository__34___option_during_setup__63__/comment_1_7244794579a191a677190c60758f32e7._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmR-xG9O2HWoybxYZPVbYVYxwitfcfDgtE"
+ nickname="Charles"
+ subject="comment 1"
+ date="2013-09-09T00:29:14Z"
+ content="""
+Oh actually, I just clicked the available option and it gave me a \"connection refused\" due to my using a port other than 22. I edited the .ssh/config, but it decided to use 22 anyway?
+"""]]
diff --git a/doc/forum/ssh_remote_-_no___34__use_a_git_repository__34___option_during_setup__63__/comment_2_277cf12907bd7c5930eb4f137b115e29._comment b/doc/forum/ssh_remote_-_no___34__use_a_git_repository__34___option_during_setup__63__/comment_2_277cf12907bd7c5930eb4f137b115e29._comment
new file mode 100644
index 000000000..55f50b3f5
--- /dev/null
+++ b/doc/forum/ssh_remote_-_no___34__use_a_git_repository__34___option_during_setup__63__/comment_2_277cf12907bd7c5930eb4f137b115e29._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmR-xG9O2HWoybxYZPVbYVYxwitfcfDgtE"
+ nickname="Charles"
+ subject="comment 2"
+ date="2013-09-09T14:50:42Z"
+ content="""
+Never mind, I simply didn't have git-annex installed on the other computer. I'm going to make a thread in bugs about assistant always assuming port 22, you can delete this thread.
+"""]]
diff --git a/doc/forum/start_assistant_from_command_line.mdwn b/doc/forum/start_assistant_from_command_line.mdwn
new file mode 100644
index 000000000..3f48dd6d3
--- /dev/null
+++ b/doc/forum/start_assistant_from_command_line.mdwn
@@ -0,0 +1,11 @@
+I wanted to try out this probably great piece of software you wrote, alas I do not use a Debian distro with managed software menus (i.e. I use OpenBox), so I cannot simply open the assistant through my programs-menu. In fact, to do that I'd need the command to start the assistant so I can add it manually myself. Sadly, the man page did not gave me any advices... :(
+
+Any chance to give me the terminal command to start the assistant?
+
+***
+edit: just to update the thread: everythings okay now. Thanks for this great program!
+
+the commands (as posted by Paul):
+
+ git annex assistant
+ git annex webapp
diff --git a/doc/forum/start_assistant_from_command_line/comment_1_f8dfce1fca9f1212ccaf84e431db71a9._comment b/doc/forum/start_assistant_from_command_line/comment_1_f8dfce1fca9f1212ccaf84e431db71a9._comment
new file mode 100644
index 000000000..dc35d61bc
--- /dev/null
+++ b/doc/forum/start_assistant_from_command_line/comment_1_f8dfce1fca9f1212ccaf84e431db71a9._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBhQgaA5QrFwT67-Bo0qPIx0HD9roDrso"
+ nickname="Paul"
+ subject="comment 1"
+ date="2013-10-21T19:20:28Z"
+ content="""
+ git annex assitant
+
+starts the assitant itself, you propably want the gui which you start by
+
+ git annex webapp
+"""]]
diff --git a/doc/forum/start_assistant_from_command_line/comment_2_e769c5d09afbff85961363ddc5eb4019._comment b/doc/forum/start_assistant_from_command_line/comment_2_e769c5d09afbff85961363ddc5eb4019._comment
new file mode 100644
index 000000000..b970990d4
--- /dev/null
+++ b/doc/forum/start_assistant_from_command_line/comment_2_e769c5d09afbff85961363ddc5eb4019._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkj7tMEJKcZpNXIFkHAAcNi5qJFSFyjn6o"
+ nickname="thissideup"
+ subject="comment 2"
+ date="2013-10-22T11:05:13Z"
+ content="""
+ah okay. That was what I was trying to do, but git-annex failed on my. Remembering that I was on Debian and checking the version (which was June 2012) - I supposed that I wasn't able to use the assistant yet.
+
+So now I am trying to compile from source using cabal, however I sadly ran into a roadblock: http://git-annex.branchable.com/forum/cabal_install_fails_on_uuid/
+"""]]
diff --git a/doc/forum/switching_backends.mdwn b/doc/forum/switching_backends.mdwn
new file mode 100644
index 000000000..dedf1ffcb
--- /dev/null
+++ b/doc/forum/switching_backends.mdwn
@@ -0,0 +1,12 @@
+so git annex migrate can switch a file from using one backend to the other.
+
+I've done that with a bunch of files.
+
+The old files should become "unused" right? But they don't seem to be. "git annex unused" still shows me only 2 unused files, and I've just migrated dozens of files from SHA256 to SHA256E.
+
+Is it possible they're still "used" by other repos? I have two other repos, one reached by SSH and one on a USB drive. Neither one of them is "bare." So maybe those files are still used by the "master" branches there, I thought... I went over and did "git annex sync" on each. Still my newly migrated files are not showing up as "unused."
+
+I'm worried that my repo is going to bloat with unused files with the SHA256 backend, which mysteriously do not show up as "unused" in git annex unused, if I migrate any more.
+
+any ideas what piece of the puzzle I could be missing here?
+
diff --git a/doc/forum/switching_backends/comment_1_ecf4109c1148dafde3519243ae3c5a03._comment b/doc/forum/switching_backends/comment_1_ecf4109c1148dafde3519243ae3c5a03._comment
new file mode 100644
index 000000000..29bc9f9c3
--- /dev/null
+++ b/doc/forum/switching_backends/comment_1_ecf4109c1148dafde3519243ae3c5a03._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="99.54.57.201"
+ subject="comment 1"
+ date="2013-01-28T03:20:38Z"
+ content="""
+Just noticed this -- http://git-annex.branchable.com/bugs/git_annex_migrate_leaves_old_backend_versions_around/
+
+so I don't need to worry about disk space bloat; they're all just hardlinks. That's cool. Still would be nice to know why they don't show up as \"unused.\" But not as important.
+"""]]
diff --git a/doc/forum/switching_backends/comment_2_21f465a18f40b95dafd307fce0de659a._comment b/doc/forum/switching_backends/comment_2_21f465a18f40b95dafd307fce0de659a._comment
new file mode 100644
index 000000000..82c9f2621
--- /dev/null
+++ b/doc/forum/switching_backends/comment_2_21f465a18f40b95dafd307fce0de659a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 2"
+ date="2013-01-28T06:28:28Z"
+ content="""
+It won't show as unused as long as there are git refs that still refer to the file. That could be branches, or more likely you have not synced everything to the local repo yet.
+"""]]
diff --git a/doc/forum/switching_backends/comment_4_4c13d22c1695195e6b101bd20ef6bb42._comment b/doc/forum/switching_backends/comment_4_4c13d22c1695195e6b101bd20ef6bb42._comment
new file mode 100644
index 000000000..7ffa519e0
--- /dev/null
+++ b/doc/forum/switching_backends/comment_4_4c13d22c1695195e6b101bd20ef6bb42._comment
@@ -0,0 +1,35 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 4"
+ date="2013-01-28T14:30:55Z"
+ content="""
+If by \"synced to the local repo\" you mean run a git annex sync, then yes, I have done that.
+
+Here's an example of what I'm seeing:
+
+ annex$ readlink subdir/subdir/file.txt
+ ../../.git/annex/objects/zV/57/SHA256E-s3952--cb67d2cbadfea373ed8aa5ec434f246acccb33471a7e28a444138cc4fe8552c2.txt/SHA256E-s3952--cb67d2cbadfea373ed8aa5ec434f246acccb33471a7e28a444138cc4fe8552c2.txt
+ annex$ find .git/annex/objects/ -name SHA256-s3952--cb67d2cbadfea373ed8aa5ec434f246acccb33471a7e28a444138cc4fe8552c2
+ .git/annex/objects//1w/Q4/SHA256-s3952--cb67d2cbadfea373ed8aa5ec434f246acccb33471a7e28a444138cc4fe8552c2
+ .git/annex/objects//1w/Q4/SHA256-s3952--cb67d2cbadfea373ed8aa5ec434f246acccb33471a7e28a444138cc4fe8552c2/SHA256-s3952--cb67d2cbadfea373ed8aa5ec434f246acccb33471a7e28a444138cc4fe8552c2
+ annex$ git annex sync
+ commit
+ # On branch master
+ nothing to commit, working directory clean
+ ok
+ pull homeworld
+ ok
+ push homeworld
+ Everything up-to-date
+ ok
+ annex$ git annex unused
+ unused . (checking for unused data...) (checking master...) (checking sync/master...) (checking homeworld/master...) (checking toshiba/master...) (checking toshiba/synced/master...) ok
+ annex$ find .git/annex/objects/ -name SHA256-s3952--cb67d2cbadfea373ed8aa5ec434f246acccb33471a7e28a444138cc4fe8552c2
+ .git/annex/objects//1w/Q4/SHA256-s3952--cb67d2cbadfea373ed8aa5ec434f246acccb33471a7e28a444138cc4fe8552c2
+ .git/annex/objects//1w/Q4/SHA256-s3952--cb67d2cbadfea373ed8aa5ec434f246acccb33471a7e28a444138cc4fe8552c2/SHA256-s3952--cb67d2cbadfea373ed8aa5ec434f246acccb33471a7e28a444138cc4fe8552c2
+ annex$
+
+
+As you can see, there are two remotes, \"toshiba\" and \"homeworld\". Neither of them is bare, they have checked out \"master\" branches. Could they be the reason that some of this data isn't \"unused\"? (I ask because I notice it reports that it is checking homeworld/master and toshiba/master when it does the unused check)
+"""]]
diff --git a/doc/forum/switching_backends/comment_4_e1d4a48baac23fd3f67b20eba4eee8af._comment b/doc/forum/switching_backends/comment_4_e1d4a48baac23fd3f67b20eba4eee8af._comment
new file mode 100644
index 000000000..d5f4e021e
--- /dev/null
+++ b/doc/forum/switching_backends/comment_4_e1d4a48baac23fd3f67b20eba4eee8af._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.3.125"
+ subject="comment 4"
+ date="2013-02-05T19:16:48Z"
+ content="""
+If you have not yet run `git annex sync` on the remotes, then they are still referring to the old unmigrated keys, which is why `unused` will not remove them.
+"""]]
diff --git a/doc/forum/switching_to__47__from_direct_mode_while_assistant_is_running.mdwn b/doc/forum/switching_to__47__from_direct_mode_while_assistant_is_running.mdwn
new file mode 100644
index 000000000..f92b5aca3
--- /dev/null
+++ b/doc/forum/switching_to__47__from_direct_mode_while_assistant_is_running.mdwn
@@ -0,0 +1,2 @@
+Is that really unsafe? Because I did that and the switch to direct mode seemed to leave a lot of files still as links, and when I panicked and switched back to indirect mode, a whole lot of stuff seemed to have become unannexed and I reannexed it.
+
diff --git a/doc/forum/switching_to__47__from_direct_mode_while_assistant_is_running/comment_1_7832243a36613c48d0077b438dbf8b4a._comment b/doc/forum/switching_to__47__from_direct_mode_while_assistant_is_running/comment_1_7832243a36613c48d0077b438dbf8b4a._comment
new file mode 100644
index 000000000..b27115bbb
--- /dev/null
+++ b/doc/forum/switching_to__47__from_direct_mode_while_assistant_is_running/comment_1_7832243a36613c48d0077b438dbf8b4a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="99.54.57.201"
+ subject="comment 1"
+ date="2013-01-25T03:39:16Z"
+ content="""
+This may have been an unrelated issue -- I just realized that I somehow ended up with a bunch of files in the annex under the directory \"misc\" and others under the directory \"Misc\" -- I'm not sure how they got that way, since I'm on OS X and those are supposed to be the same directory -- but they get synced over to a linux box where they're different directories. This may be the source of some of the weirdness I saw; I'm not sure. I tried to fix it all up on the linux box so everything was in its own directory.
+
+
+"""]]
diff --git a/doc/forum/syncing_home_directories.mdwn b/doc/forum/syncing_home_directories.mdwn
new file mode 100644
index 000000000..fcd391732
--- /dev/null
+++ b/doc/forum/syncing_home_directories.mdwn
@@ -0,0 +1,7 @@
+Hi,
+
+I synchronize home directories on a couple of machines using unison. Is there a recommended way to do the equivalent using git-annex?
+
+Thanks,
+
+John
diff --git a/doc/forum/syncing_home_directories/comment_1_220a6e0ffe0ea610921a63c0a6e3beab._comment b/doc/forum/syncing_home_directories/comment_1_220a6e0ffe0ea610921a63c0a6e3beab._comment
new file mode 100644
index 000000000..f4699e74a
--- /dev/null
+++ b/doc/forum/syncing_home_directories/comment_1_220a6e0ffe0ea610921a63c0a6e3beab._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-03-05T20:34:22Z"
+ content="""
+There are a few problems you are likely to run into if you try to store everything in git-annex:
+
+* git does not store certain things, including special file permissions, in a git repository
+* you can't check a .git directory into another git repository
+* git-annex locks files to prevent them being changed and this involves replacing them with symlinks (much less of a problem now that it has the direct mode)
+
+For these reasons, I currently encourage users to use one or more git-annex repositories to store and sync whatever large data files they need, but to confine this to subdirectories of the home directory. There are other tools like vcsh that are better suited to storing things like dotfiles in git, rather than using git-annex for that. And other tools like mr can make it easy to work with a set of repositories, so you can have your dotfiles stored in one or more repositories and your large files in others and update them all with one command.
+
+See <http://vcs-home.branchable.com/> for more on this..
+"""]]
diff --git a/doc/forum/syncing_non-git_trees_with_git-annex.mdwn b/doc/forum/syncing_non-git_trees_with_git-annex.mdwn
new file mode 100644
index 000000000..997378261
--- /dev/null
+++ b/doc/forum/syncing_non-git_trees_with_git-annex.mdwn
@@ -0,0 +1,46 @@
+I have a bunch of directory trees with large data files scattered over various computers and disk drives - they contain photos, videos, music, and so on. In many cases I initially copied one of these trees from one machine to another just as a cheap and dirty backup, and then made small modifications to both trees in ways I no longer remember. For example, I returned from a trip with a bunch of new photos, and then might have rotated some of them 90 degrees on one machine, and edited or renamed them on another.
+
+What I want to do now is use git-annex as a way of initially synchronising the trees, and then fully managing them on an ongoing basis. Note that the trees are *not* yet git repositories. In order to be able to detect straight-forward file renames, I believe that [[the SHA1 backend|tips/using_the_SHA1_backend]] probably makes the most sense.
+
+I've been playing around and arrived at the following setup procedure. For the sake of discussion, I assume that we have two trees `a` and `b` which live in the same directory referred to by `$td`, and that all large files end with the `.avi` suffix.
+
+ # Setup git in 'a'.
+ cd $td/a
+ git init
+
+ # Setup git-annex in 'a'.
+ echo '* annex.backend=SHA1' > .gitattributes
+ git add .gitattributes
+ git commit -m'use SHA1 backend'
+ git annex init
+
+ # Annex all large files.
+ find -name \*.avi | xargs git annex add
+ git add .
+ git commit -m'Initial import'
+
+ # Setup git in 'b'.
+ cd $td/b
+ git clone -n $td/a new
+ mv new/.git .
+ rmdir new
+ git reset # reset git index to b's wd - hangover from cloning from 'a'
+
+ # Setup git-annex in 'b'.
+ # This merges a's (origin's) git-annex branch into the local git-annex branch.
+ git annex init
+
+ # Annex all large files - because we're using SHA1 backend, some
+ # should hash to the same keys as in 'a'.
+ find -name \*.avi | xargs git annex add
+ git add .
+ git commit -m'Changes in b tree'
+
+ git remote add a $td/a
+
+ # Now pull changes in 'b' back to 'a'.
+ cd $td/a
+ git remote add b $td/b
+ git pull b master
+
+This seems to work, but have I missed anything?
diff --git a/doc/forum/syncing_non-git_trees_with_git-annex/comment_1_7f9593bdfd95e4a8814e6cc5c44619e6._comment b/doc/forum/syncing_non-git_trees_with_git-annex/comment_1_7f9593bdfd95e4a8814e6cc5c44619e6._comment
new file mode 100644
index 000000000..bdec50879
--- /dev/null
+++ b/doc/forum/syncing_non-git_trees_with_git-annex/comment_1_7f9593bdfd95e4a8814e6cc5c44619e6._comment
@@ -0,0 +1,24 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-12-14T17:31:31Z"
+ content="""
+This is an entirely reasonable way to go about it.
+
+However, doing it this way causes files in B to always \"win\" -- If the same filename is in both repositories, with differing content, the version added in B will superscede the version from A. If A has a file that is not in B, a git commit -a in B will commit a deletion of that file.
+
+I might do it your way and look at the changes in B before (or even after) committing them to see if files from A were deleted or changed.
+
+Or, I might just instead keep B in a separate subdirectory in the repository, set up like so:
+
+<pre>
+mv b old_b
+git clone a b
+cd b
+mv ../old_b .
+git annex add old_b --not --exclude '*.avi'
+</pre>
+
+Or, a third way would be to commit A to a branch like branchA and B to a separate branchB, and not merge the branches at all.
+"""]]
diff --git a/doc/forum/syncing_non-git_trees_with_git-annex/comment_2_49f15478781a0ad5e46e75319070335c._comment b/doc/forum/syncing_non-git_trees_with_git-annex/comment_2_49f15478781a0ad5e46e75319070335c._comment
new file mode 100644
index 000000000..94b5c2ec1
--- /dev/null
+++ b/doc/forum/syncing_non-git_trees_with_git-annex/comment_2_49f15478781a0ad5e46e75319070335c._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmKPMUX0YHBjE93eBsEnacwZsddSDue3PY"
+ nickname="Oliver"
+ subject="comment 2"
+ date="2011-12-23T22:04:08Z"
+ content="""
+As joey points out the problem is B overwrites A, so that any files in A that aren't in B will be removed. But the suggestion to keep B in a separate subdirectory in the repository means I'll end up with duplicates of files in both A and B. What I want is to have the merged superset of all files from both A and B with only one copy of identical files.
+
+The problem is that unique symlinks in A/master are deleted when B/master is merged in. To add back the deleted files after the merge you can do this:
+
+ git checkout master~1 deleted_file_name #checkout a single deleted file called deleted_file_name
+ git diff master~1 master --numstat --name-only --diff-filter=D #get the names of all files deleted between master and master~1
+ git diff master~1 master --numstat --name-only --diff-filter=D | xargs git checkout master~1 #checkout all deleted files between master and master~1
+
+Once the first merge has been done after set up, you can continue to make changes to A and B and future merges won't require accounting for deleted files in this way.
+"""]]
diff --git a/doc/forum/syncing_non-git_trees_with_git-annex/comment_3_6d8f399f0549eddd1d1f5c9c9a10c654._comment b/doc/forum/syncing_non-git_trees_with_git-annex/comment_3_6d8f399f0549eddd1d1f5c9c9a10c654._comment
new file mode 100644
index 000000000..1793e686f
--- /dev/null
+++ b/doc/forum/syncing_non-git_trees_with_git-annex/comment_3_6d8f399f0549eddd1d1f5c9c9a10c654._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://adamspiers.myopenid.com/"
+ nickname="Adam"
+ subject="re-annexing previously annexed files"
+ date="2012-03-29T21:41:54Z"
+ content="""
+Here's another handy command-line which annexes all files in repo B which have already been annexed in repo A:
+
+ git status --porcelain | sed -n '/^ T /{s///;p}' | xargs git annex add
+
+The 'T' outputted by git status for these files indicates a type change: it's a symlink to the annex in repo A, but a normal file in repo B.
+
+"""]]
diff --git a/doc/forum/taskwarrior.mdwn b/doc/forum/taskwarrior.mdwn
new file mode 100644
index 000000000..3e44cc610
--- /dev/null
+++ b/doc/forum/taskwarrior.mdwn
@@ -0,0 +1,11 @@
+I try to sync my taskWarrior files .task/*.data with git-annex ... but there is two problem :
+
+- i need to chmod 755 my files because taskWarrior doesn't recognize them, or say "problem with permission"
+
+- taskwarrior seems crazy with symbolic link used by git-annex, undo not work, task appear multiple times , etc.
+
+Is there any solution ?
+Any user experienced the same problem?
+
+Thanks
+Sr.
diff --git a/doc/forum/taskwarrior/comment_1_1c3a29e7d292cb602d9d349f8009b51e._comment b/doc/forum/taskwarrior/comment_1_1c3a29e7d292cb602d9d349f8009b51e._comment
new file mode 100644
index 000000000..c8682b378
--- /dev/null
+++ b/doc/forum/taskwarrior/comment_1_1c3a29e7d292cb602d9d349f8009b51e._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 1"
+ date="2013-08-06T12:44:11Z"
+ content="""
+* You could try metastore (not merge friendly), git-cache-meta (pretty minimal) or metamonger (not done yet) to sync your file permissions
+* Look into direct mode to avoid symlinks
+* Alternatively, check your taskwarrior files into git, not git-annex, to avoid symlinks
+"""]]
diff --git a/doc/forum/tell_us_how_you__39__re_using_git-annex.mdwn b/doc/forum/tell_us_how_you__39__re_using_git-annex.mdwn
new file mode 100644
index 000000000..d289b9f50
--- /dev/null
+++ b/doc/forum/tell_us_how_you__39__re_using_git-annex.mdwn
@@ -0,0 +1,6 @@
+Tell your git-annex stories here. Feel free to give as little or as much detail
+as appropriate about how you're using it. How's it working out for you?
+
+See [[testimonials]] for some other stories.
+
+[[!meta author=Joey]]
diff --git a/doc/forum/tell_us_how_you__39__re_using_git-annex/comment_1_4884803ddee7f642a3ac995a19967a6a._comment b/doc/forum/tell_us_how_you__39__re_using_git-annex/comment_1_4884803ddee7f642a3ac995a19967a6a._comment
new file mode 100644
index 000000000..2351378bc
--- /dev/null
+++ b/doc/forum/tell_us_how_you__39__re_using_git-annex/comment_1_4884803ddee7f642a3ac995a19967a6a._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="http://mildred.fr/"
+ subject="just amazing"
+ date="2012-04-12T17:12:41Z"
+ content="""
+git-annex is just amazing. I just started using it and for once, I have hope to be able to organize my files a little better than now.
+
+Currently, I have a huge homedir. From time to time, I move file away in external hard drives, then forget about them. When I want to look at them back, I just can't because I have forgotten where they are. I have also a ton of files on those drives that I can't access because they are not indexed. With git-annex I have hope to put all of these files on a git repository. I will be able to see them everywhere, and find them when I need to.
+
+I might stop loosing files for once.
+
+I might avoid having multiple copies of the same things over and over again, without knowing so. and regain some more disk space.
+
+For the moment, I'm archiving my photographs. But there is one thing that might not go very well: directory hierarchies where everything is important (file owner, specific permissions, symlinks). I won't just be able to blindly annex all of these files. But for the moment I'll stick at archiving ocuments and it should be amazing.
+
+[Mildred](http://mildred.fr)
+"""]]
diff --git a/doc/forum/tell_us_how_you__39__re_using_git-annex/comment_2_61f5054918e7b36c191454365bc7f3b7._comment b/doc/forum/tell_us_how_you__39__re_using_git-annex/comment_2_61f5054918e7b36c191454365bc7f3b7._comment
new file mode 100644
index 000000000..3bd981c5d
--- /dev/null
+++ b/doc/forum/tell_us_how_you__39__re_using_git-annex/comment_2_61f5054918e7b36c191454365bc7f3b7._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://cgray.myopenid.com/"
+ nickname="cgray"
+ subject="comment 2"
+ date="2012-04-14T01:18:53Z"
+ content="""
+Git-annex has really helped me with my media files. I have a big NAS drive where I keep all my music, tv, and movies files, each in their own git annex. I tend to keep the media that I want to watch or listen to on my laptop and then drop it when it is done. This way I don't have too much on my laptop at any one time, but I have a nice selection for when I'm traveling and don't have access to my NAS.
+
+Additionally, I have a mp3 player that will format itself randomly every few months or so. I keep my podcasts on it in a git annex and in a git annex on my laptop. When I am done with a podcast, I can delete it from the mp3 player and then sync that information with my laptop. With this method, I have a backup of what should be on my mp3 player, so I don't need to worry about losing it all when the mp3 player decides it's had enough.
+"""]]
diff --git a/doc/forum/tell_us_how_you__39__re_using_git-annex/comment_3_db07e8703be606c998c831e91d300d69._comment b/doc/forum/tell_us_how_you__39__re_using_git-annex/comment_3_db07e8703be606c998c831e91d300d69._comment
new file mode 100644
index 000000000..1a80bb480
--- /dev/null
+++ b/doc/forum/tell_us_how_you__39__re_using_git-annex/comment_3_db07e8703be606c998c831e91d300d69._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://bergey.dreamwidth.org/"
+ ip="66.80.90.109"
+ subject="git-annex, media, emacs"
+ date="2012-08-31T01:47:36Z"
+ content="""
+I've been using git-annex for a month or two to manage my music collection. It's great to know I can drop files if I need space on the laptop, knowing exactly where I have other copies. Now I'm writing an emacs mode to help me keep track: https://gitorious.org/emacs-contrib/annex-mode
+
+Locally available files are colored differently, and pressing g runs `git annex get` on the file at point.
+"""]]
diff --git a/doc/forum/tell_us_how_you__39__re_using_git-annex/comment_4_a58595969cdd42ed20210e9615b42e42._comment b/doc/forum/tell_us_how_you__39__re_using_git-annex/comment_4_a58595969cdd42ed20210e9615b42e42._comment
new file mode 100644
index 000000000..d80423eac
--- /dev/null
+++ b/doc/forum/tell_us_how_you__39__re_using_git-annex/comment_4_a58595969cdd42ed20210e9615b42e42._comment
@@ -0,0 +1,22 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnZEanlyzay_QlEAL0CWpyZcRTyN7vay8U"
+ nickname="Carlo"
+ subject="Best thing since sliced bread"
+ date="2012-11-21T13:08:57Z"
+ content="""
+It's amazing how perfect git annex is for my use case.
+
+I record music, which results in a bunch of big files that don't change, and a bunch of small files which change often.
+
+I also need these files to be preserved for the long haul, and be verified now and then. They also need to be backed up three or four times, because they're original files! Keeping track of all that was a headache before git annex, and I was also constantly awake at night because it was impossible to verify if everything's still okay.
+
+Now I just dump everything into my archive annex and I know where everything is, and that it's safe, period. I even set myself up a raspberry pi with a usb drive adapter and put some spindown code in a cron job. Now I have a hard drive at rest that I can access from anywhere at any time. The whole thing gets backed up by Amazon Glacier, but if Amazon starts getting pesky I can just add another backend and sync it up. I can even version my small files if I want to by putting them directly into git. This entire thing would have been such a huge undertaking but now it's easy. I dump everything into the annex and to the actual backups whenever I get round to it. It just has a natural flow to it.
+
+Et voila. Professional grade backups, at home, independant from any specific vendor. I absolutely never have to worry about my files going anywhere, and if I get super paranoid, I can just \"git annex fsck\" and mathematically prove to myself everything's still there.
+
+It's totally sad how many creative people will be losing their life's work in a couple of years because they rely on regular filesystems on their USB drives. Stuff like DropBox and SpiderOak is better than nothing but trusting single vendor to not screw up or mess with your life's work is just plain creepy.
+
+I just have a huge, warm fuzzy feeling now. If this sounds like I'm relentlessly hyping git annex, it's because I am! It deserves it!
+
+
+"""]]
diff --git a/doc/forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs.mdwn b/doc/forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs.mdwn
new file mode 100644
index 000000000..8981200d8
--- /dev/null
+++ b/doc/forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs.mdwn
@@ -0,0 +1,22 @@
+This is work in progress, since there is now a [[special_remotes/hook]] for users to plug in whatever they want as a remote, here's my recipe for using tahoe-lafs as a remote, this is a copy and paste the relavent section from my .git/config file
+
+ tahoe-store-hook = tahoe put $ANNEX_FILE tahoe:$ANNEX_KEY
+ tahoe-retrieve-hook = tahoe get tahoe:$ANNEX_KEY $ANNEX_FILE
+ tahoe-remove-hook = tahoe rm tahoe:$ANNEX_KEY
+ tahoe-checkpresent-hook = tahoe ls tahoe:$ANNEX_KEY 2>&1 || echo FAIL
+
+Where `tahoe:` is a tahoe-lafs alias, ideally you should create a new alias (DIR-CAP or whatever the terminolgy is) to store your files, I just used the default `tahoe:` alias for testing.
+
+The only quirk I've noticed is this...
+
+<pre>
+$ git annex whereis .
+whereis frink.jar (2 copies)
+ 084603a8-7243-11e0-b1f5-83102bcd7953 -- here (testtest)
+ 1d1bc312-7243-11e0-a9ce-5f10c0ce9b0a
+ok
+</pre>
+
+1d1bc312-7243-11e0-a9ce-5f10c0ce9b0a is my [[!google tahoe-lafs]] remote, but there is no label/description on it. The checkpresent-hook was a little confusing when I was setting it up, I'm currently unsure if I am doing the right thing or not with my hook. My get and put commands are a little verbose for now, i might redirect it to /dev/null once I am happier with the overall performance/behaviour my setup.
+
+Other than the quirks above, I am able to put and get files from my tahoe-lafs remote. The only thing that I have not figured out is how to "remove a file" on the remote to free up space on the remote.
diff --git a/doc/forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs/comment_1_76bb33ce45ce6a91b86454147463193b._comment b/doc/forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs/comment_1_76bb33ce45ce6a91b86454147463193b._comment
new file mode 100644
index 000000000..388641f69
--- /dev/null
+++ b/doc/forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs/comment_1_76bb33ce45ce6a91b86454147463193b._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="whereis labels"
+ date="2011-04-29T13:08:35Z"
+ content="""
+You should be able to fix the missing label by editing .git-annex/uuid.log and adding
+
+ 1d1bc312-7243-11e0-a9ce-5f10c0ce9b0a tahoe
+"""]]
diff --git a/doc/forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs/comment_2_4d9b9d47d01d606a475678f630797bf9._comment b/doc/forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs/comment_2_4d9b9d47d01d606a475678f630797bf9._comment
new file mode 100644
index 000000000..e7c3d619d
--- /dev/null
+++ b/doc/forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs/comment_2_4d9b9d47d01d606a475678f630797bf9._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 2"
+ date="2011-04-29T15:24:56Z"
+ content="""
+If `tahoe ls` outputs only the key, on its own line, and exits nonzero if it's not present, then I think you did the right thing.
+
+To remove a file, use `git annex move file --from tahoe` and then you can drop it locally.
+"""]]
diff --git a/doc/forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs/comment_3_8a812b11fcc2dc3b6fcf01cdbbb8459d._comment b/doc/forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs/comment_3_8a812b11fcc2dc3b6fcf01cdbbb8459d._comment
new file mode 100644
index 000000000..16ad9e988
--- /dev/null
+++ b/doc/forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs/comment_3_8a812b11fcc2dc3b6fcf01cdbbb8459d._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 3"
+ date="2011-04-29T15:33:24Z"
+ content="""
+@justin, I discovered that \"git annex describe\" did what I wanted
+
+@joey, yep that is the behaviour of \"tahoe ls\", thanks for the tip on removing the file from the remote.
+
+It seems to be working okay for now, the only concern is that on the remote everything is dumped into the same directory, but I can live with that, since I want to track biggish blobs and not lots of small little files.
+"""]]
diff --git a/doc/forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs/comment_4_fc98c819bc5eb4d7c9e74d87fb4f6f3b._comment b/doc/forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs/comment_4_fc98c819bc5eb4d7c9e74d87fb4f6f3b._comment
new file mode 100644
index 000000000..5d271c6f3
--- /dev/null
+++ b/doc/forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs/comment_4_fc98c819bc5eb4d7c9e74d87fb4f6f3b._comment
@@ -0,0 +1,39 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 4"
+ date="2011-04-29T16:17:11Z"
+ content="""
+I've just tried to use the ANNEX_HASH_ variables, example of my configuration
+
+<pre>
+ git config annex.tahoe-store-hook 'tahoe mkdir $ANNEX_HASH_1 && tahoe put $ANNEX_FILE tahoe:$ANNEX_HASH_1/$ANNEX_KEY'
+ git config annex.tahoe-retrieve-hook 'tahoe get tahoe:$ANNEX_HASH_1/$ANNEX_KEY $ANNEX_FILE'
+ git config annex.tahoe-remove-hook 'tahoe rm tahoe:$ANNEX_HASH_1/$ANNEX_KEY'
+ git config annex.tahoe-checkpresent-hook 'tahoe ls tahoe:$ANNEX_HASH_1/$ANNEX_KEY 2>&1 || echo FAIL'
+ git annex initremote library type=hook hooktype=tahoe encryption=none
+ git annex describe 1d1bc312-7243-11e0-a9ce-5f10c0ce9b0a library
+</pre>
+
+It's seems to work quite well for me now, I did run across this when I tried to drop a file locally, leaving the file on my remote
+
+<pre>
+jtang@x00:/tmp/annex3 $ git annex drop .
+drop frink.sh (checking library...) (unsafe)
+ Could only verify the existence of 0 out of 1 necessary copies
+ Try making some of these repositories available:
+ 1d1bc312-7243-11e0-a9ce-5f10c0ce9b0a -- library
+ (Use --force to override this check, or adjust annex.numcopies.)
+failed
+drop t/frink.jar (checking library...) (unsafe)
+ Could only verify the existence of 0 out of 1 necessary copies
+ Try making some of these repositories available:
+ 1d1bc312-7243-11e0-a9ce-5f10c0ce9b0a -- library
+ (Use --force to override this check, or adjust annex.numcopies.)
+failed
+git-annex: 2 failed
+1|jtang@x00:/tmp/annex3 $
+</pre>
+
+I do know that the files exist in my library as I have just inserted them, it seemed to work when I didnt have the hashing, it appears that the checkpresent doesn't seem to pass the ANNEX_HASH_* variables (from the limited debugging I did)
+"""]]
diff --git a/doc/forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs/comment_5_c459fb479fe7b13eaea2377cfc1923a6._comment b/doc/forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs/comment_5_c459fb479fe7b13eaea2377cfc1923a6._comment
new file mode 100644
index 000000000..9127cdeea
--- /dev/null
+++ b/doc/forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs/comment_5_c459fb479fe7b13eaea2377cfc1923a6._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 5"
+ date="2011-04-29T18:01:04Z"
+ content="""
+I've corrected the missing `ANNEX_HASH_*` oversight. (It also affected removal, btw.)
+"""]]
diff --git a/doc/forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs/comment_6_2e9da5a919bbbc27b32de3b243867d4f._comment b/doc/forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs/comment_6_2e9da5a919bbbc27b32de3b243867d4f._comment
new file mode 100644
index 000000000..80874db31
--- /dev/null
+++ b/doc/forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs/comment_6_2e9da5a919bbbc27b32de3b243867d4f._comment
@@ -0,0 +1,23 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 6"
+ date="2011-04-29T20:11:08Z"
+ content="""
+Cool, that seems to make things work as expected, here's an updated recipe
+
+
+<pre>
+git config annex.tahoe-store-hook 'tahoe mkdir tahoe:$ANNEX_HASH_1/$ANNEX_HASH_2 && tahoe put $ANNEX_FILE tahoe:$ANNEX_HASH_1/$ANNEX_HASH_2/$ANNEX_KEY'
+git config annex.tahoe-retrieve-hook 'tahoe get tahoe:$ANNEX_HASH_1/$ANNEX_HASH_2/$ANNEX_KEY $ANNEX_FILE'
+git config annex.tahoe-remove-hook 'tahoe rm tahoe:$ANNEX_HASH_1/$ANNEX_HASH_2/$ANNEX_KEY'
+git config annex.tahoe-checkpresent-hook 'tahoe ls tahoe:$ANNEX_HASH_1/$ANNEX_HASH_2/$ANNEX_KEY 2>&1 || echo FAIL'
+git annex initremote library type=hook hooktype=tahoe encryption=none
+git annex describe 1d1bc312-7243-11e0-a9ce-5f10c0ce9b0a library
+</pre>
+
+
+I just needs some of the output redirected to /dev/null.
+
+(I updated this comment to fix a bug. --[[Joey]])
+"""]]
diff --git a/doc/forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs/comment_7_d636c868524b2055ee85832527437f90._comment b/doc/forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs/comment_7_d636c868524b2055ee85832527437f90._comment
new file mode 100644
index 000000000..1d75fb963
--- /dev/null
+++ b/doc/forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs/comment_7_d636c868524b2055ee85832527437f90._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="zooko"
+ ip="97.118.97.117"
+ subject="request for information, plus some ideas"
+ date="2011-05-14T05:07:17Z"
+ content="""
+Hey Jimmy: how's this working for you now? I would expect it to go slower and slower since Tahoe-LAFS has an O(N) algorithm for reading or updating directories.
+
+Of course, if it is still fast enough for your uses then that's okay. :-)
+
+(We're working on optimizations of this for future releases of Tahoe-LAFS.)
+
+I'd like to understand the desired behavior of store-hook and retrieve-hook better, in order to see if there is a more efficient way to use Tahoe-LAFS for this.
+
+Off to look for docs.
+
+Regards,
+
+Zooko
+"""]]
diff --git a/doc/forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs/comment_8_39dc449cc60a787c3bfbfaaac6f9be0c._comment b/doc/forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs/comment_8_39dc449cc60a787c3bfbfaaac6f9be0c._comment
new file mode 100644
index 000000000..dc97128bd
--- /dev/null
+++ b/doc/forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs/comment_8_39dc449cc60a787c3bfbfaaac6f9be0c._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 8"
+ date="2011-05-14T10:02:26Z"
+ content="""
+@joey thanks for the update in the previous comment, I had forgotten about updating it.
+
+@zooko it's working okay for me right now, since I'm only putting fairly big blogs on stuff on to it and only things that I *really* care about. On the performance side, if it ran faster then it would be nicer :)
+"""]]
diff --git a/doc/forum/ui.mdwn b/doc/forum/ui.mdwn
new file mode 100644
index 000000000..2ef8841a9
--- /dev/null
+++ b/doc/forum/ui.mdwn
@@ -0,0 +1,11 @@
+I just briefly tried git-annex. It's an interesting concept.
+
+My main frustration so far: I find it difficult to visualise and use the annex. Shell script contortions can obviously show you anything, but I don't have the ready knowledge to compose them. It would be nice to have some more user-friendly commands or even a GUI.
+
+'annex whereis' is fine for one file, but unweildly for many (e.g. a directory whose contents are always together, never divided between repositories). Is it possible to treat a given directory and all its contents as a single object?
+
+It is not clear what files are immediately available. Sometimes you don't care about annexed files that aren't stored in the current repository. Might it be nice to temporarily remove or hide symlinks for files that are not here right now? Then you could treat the repository more like a normal file heirarchy. Or how about something like 'git annex ls' to show only currently available files?
+
+assistant and sharebox fs sound like great basic synch options, but it would be really cool to have a fuse fs somewhere between raw git-annex and assistant. Putting a file in the directory would trigger git-annex to add it and sync. rm <file> on that new file would not work by default because it's the only copy. rm --annex to get rid of the file from all repos. mv/cp <file> <remote> to transfer between repos. ls to show only the files that are here now, ls --annex to display complete information in a clear way (well-formatted, colorized). Something like that.
+
+This has just been a random brain dump from a new user, hopefully it made some sense.
diff --git a/doc/forum/ui/comment_1_f3e3446b05d6b573e29e6cad300fb635._comment b/doc/forum/ui/comment_1_f3e3446b05d6b573e29e6cad300fb635._comment
new file mode 100644
index 000000000..84f30c5ea
--- /dev/null
+++ b/doc/forum/ui/comment_1_f3e3446b05d6b573e29e6cad300fb635._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.140"
+ subject="comment 1"
+ date="2013-07-20T19:51:19Z"
+ content="""
+It's pretty easy to configure ls to show broken symlinks in a different color. Run dircolors, and alias ls='ls --color==auto'. Then you can see which files are not there at a glance.
+
+The Linux file manager's I've tried (nautilus and thunar) also shows which files are present; you get a X on the icon of annexed files that are not present.
+"""]]
diff --git a/doc/forum/ui/comment_2_b493ee97eb2378e72c12f3d137109580._comment b/doc/forum/ui/comment_2_b493ee97eb2378e72c12f3d137109580._comment
new file mode 100644
index 000000000..ee7995883
--- /dev/null
+++ b/doc/forum/ui/comment_2_b493ee97eb2378e72c12f3d137109580._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://mylesenglish.myopenid.com/"
+ ip="217.39.94.195"
+ subject="comment 2"
+ date="2013-09-16T19:21:31Z"
+ content="""
+This shell function behaves more like ls and shows the files that are present:
+
+ ga-ls () {
+ CWD=`pwd`
+ cd ${1:-.} && git annex find | cut -d / -f 1 | uniq
+ cd ${CWD}
+ }
+
+"""]]
diff --git a/doc/forum/unannex_alternatives.mdwn b/doc/forum/unannex_alternatives.mdwn
new file mode 100644
index 000000000..efd05838e
--- /dev/null
+++ b/doc/forum/unannex_alternatives.mdwn
@@ -0,0 +1,9 @@
+what is the work flow to get a file that is in git-annex out of there and into git? (current situation: `git-annex add`ed a bunch of pictures, later found make files in there which i'd rather have in git for proper source code control)
+
+the most intuitive thing to do is `git unannex`, which at first seemed to do the right thing, but when committing there came the hook and everything was back to where it was before.
+
+i could disable the hook as a workaround, but that doesn't smell like a good work flow.
+
+the [[man page|git-annex]] does warn that `unannex` is only supposed to be used against unintentional `git annex add`s (probably meaning that it should be used before something is committed), but the alternatives it suggests (`git rm` and `git annex drop`) don't to what i want to do.
+
+am i missing something or is there really no work flow for this? --[[chrysn]]
diff --git a/doc/forum/unannex_alternatives/comment_1_dcd4cd41280b41512bbdffafaf307993._comment b/doc/forum/unannex_alternatives/comment_1_dcd4cd41280b41512bbdffafaf307993._comment
new file mode 100644
index 000000000..7f278d2bc
--- /dev/null
+++ b/doc/forum/unannex_alternatives/comment_1_dcd4cd41280b41512bbdffafaf307993._comment
@@ -0,0 +1,46 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-02-02T00:39:10Z"
+ content="""
+Git-annex's commit hook does not prevent unannex being used. The file you unannex will not be checked into git anymore and will be a regular file again, not a git-annex symlink.
+
+For example, here's a transcript:
+
+<pre>
+joey@gnu:~/tmp>mkdir demo
+joey@gnu:~/tmp>cd demo
+joey@gnu:~/tmp/demo>git init
+Initialized empty Git repository in /home/joey/tmp/demo/.git/
+joey@gnu:~/tmp/demo>git annex init demo
+init demo ok
+joey@gnu:~/tmp/demo>echo hi > file
+joey@gnu:~/tmp/demo>git annex add file
+add file ok
+(Recording state in git...)
+joey@gnu:~/tmp/demo>git commit -m add
+[master 64cf267] add
+ 2 files changed, 2 insertions(+), 0 deletions(-)
+ create mode 100644 .git-annex/WORM:1296607093:3:file.log
+ create mode 120000 file
+joey@gnu:~/tmp/demo>git annex unannex file
+unannex file ok
+(Recording state in git...)
+joey@gnu:~/tmp/demo>ls -l file
+-rw-r--r-- 1 joey joey 3 Feb 1 20:38 file
+joey@gnu:~/tmp/demo>git commit
+[master 78a09cc] unannex
+ 2 files changed, 1 insertions(+), 2 deletions(-)
+ delete mode 120000 file
+joey@gnu:~/tmp/demo>ls -l file
+-rw-r--r-- 1 joey joey 3 Feb 1 20:38 file
+joey@gnu:~/tmp/demo>git status
+# On branch master
+# Untracked files:
+# (use \"git add <file>...\" to include in what will be committed)
+#
+# file
+nothing added to commit but untracked files present (use \"git add\" to track)
+</pre>
+"""]]
diff --git a/doc/forum/unannex_alternatives/comment_2_58a72a9fe0f58c7af0b4d7927a2dd21d._comment b/doc/forum/unannex_alternatives/comment_2_58a72a9fe0f58c7af0b4d7927a2dd21d._comment
new file mode 100644
index 000000000..91ddadf8c
--- /dev/null
+++ b/doc/forum/unannex_alternatives/comment_2_58a72a9fe0f58c7af0b4d7927a2dd21d._comment
@@ -0,0 +1,36 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 2"
+ date="2011-02-02T00:41:24Z"
+ content="""
+And following on to my transcript, you can then add the file to git in the regular git way, and it works fine:
+
+<pre>
+joey@gnu:~/tmp/demo>git add file
+joey@gnu:~/tmp/demo>git commit
+[master 225ffc0] added as regular git file, not in annex
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+ create mode 100644 file
+joey@gnu:~/tmp/demo>ls -l file
+-rw-r--r-- 1 joey joey 3 Feb 1 20:38 file
+joey@gnu:~/tmp/demo>git log file
+commit 225ffc048f5af7c0466b3b1fe549a6d5e9a9e9fe
+Author: Joey Hess <joey@kitenet.net>
+Date: Tue Feb 1 20:43:13 2011 -0400
+
+ added as regular git file, not in annex
+
+commit 78a09cc791b875c3b859ca9401e5b6472bf19d08
+Author: Joey Hess <joey@kitenet.net>
+Date: Tue Feb 1 20:38:30 2011 -0400
+
+ unannex
+
+commit 64cf267734adae05c020d9fd4d5a7ff7c64390db
+Author: Joey Hess <joey@kitenet.net>
+Date: Tue Feb 1 20:38:18 2011 -0400
+
+ add
+</pre>
+"""]]
diff --git a/doc/forum/unannex_alternatives/comment_3_b1687fc8f9e7744327bbeb6f0635d1cd._comment b/doc/forum/unannex_alternatives/comment_3_b1687fc8f9e7744327bbeb6f0635d1cd._comment
new file mode 100644
index 000000000..9f3223578
--- /dev/null
+++ b/doc/forum/unannex_alternatives/comment_3_b1687fc8f9e7744327bbeb6f0635d1cd._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 3"
+ date="2011-02-02T00:46:00Z"
+ content="""
+Sorry for all the followups, but I see now that if you unannex, then add the file to git normally, and commit, the hook *does* misbehave.
+
+This seems to be a bug. git-annex's hook thinks that you have used git annex unlock (or \"git annex edit\") on the file and are now committing a changed version, and the right thing to do there is to add the new content to the annex and update the symlink accordingly. I'll track this bug over at [[bugs/unannex_vs_unlock_hook_confusion]].
+
+So, committing after unannex, and before checking the file into git in the
+usual way, is a workaround. But only if you do a "git commit" to commit
+staged changes.
+
+Anyway, this confusing point is fixed in git now!
+"""]]
diff --git a/doc/forum/unknown_response_from_git_cat-file.mdwn b/doc/forum/unknown_response_from_git_cat-file.mdwn
new file mode 100644
index 000000000..e4c559815
--- /dev/null
+++ b/doc/forum/unknown_response_from_git_cat-file.mdwn
@@ -0,0 +1,8 @@
+Hi,
+
+when running git annex add in my direct mode repository, since a few days ago I only get:
+
+$ git annex add
+git-annex: unknown response from git cat-file (":./Archiv/Someone missing",:./Archiv/Someone Like You Cover-fCvjvEGkTu4.flv)
+
+The :./Archiv/Someone missing part strikes me odd because it so much looks like broken shell meta-character escaping in git-annex, but I doubt that because it stopped working just suddenly.
diff --git a/doc/forum/unknown_response_from_git_cat-file/comment_1_f26ba569e715fe69b6de3093930362ee._comment b/doc/forum/unknown_response_from_git_cat-file/comment_1_f26ba569e715fe69b6de3093930362ee._comment
new file mode 100644
index 000000000..0ddef17af
--- /dev/null
+++ b/doc/forum/unknown_response_from_git_cat-file/comment_1_f26ba569e715fe69b6de3093930362ee._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 1"
+ date="2013-08-07T16:34:18Z"
+ content="""
+This is a bug in the 1.8.4 pre-release version of git. It will be fixed in the 1.8.4 release or another pre-release. git-annex version 4.20130802 has a workaround for this problem.
+"""]]
diff --git a/doc/forum/unlock__47__lock_always_gets_me.mdwn b/doc/forum/unlock__47__lock_always_gets_me.mdwn
new file mode 100644
index 000000000..0891eed0e
--- /dev/null
+++ b/doc/forum/unlock__47__lock_always_gets_me.mdwn
@@ -0,0 +1,11 @@
+Several times now I've done something like:
+
+ $ git annex unlock movie.avi
+ $ mv /tmp/fixed.avi movie.avi
+ $ git annex lock movie.avi
+
+Oops, I just lost my fixed.avi! That really feels like the right sequence of operations to me, so I'm always surprised when I make that mistake. I would like to see the current `lock` renamed to something like `undo-unlock`, or have the behavior changed to be the same as `add`, or maybe warn and require a `--force` when the file has been changed.
+
+If changing current behavior is undesirable, maybe `unlock` could just print a reminder that `git annex add` is the correct next step after making changes?
+
+Failing that, I suppose I could slowly start to learn from my mistakes.
diff --git a/doc/forum/unlock__47__lock_always_gets_me/comment_1_dee73a7ea3e1a5154601adb59782831f._comment b/doc/forum/unlock__47__lock_always_gets_me/comment_1_dee73a7ea3e1a5154601adb59782831f._comment
new file mode 100644
index 000000000..c37561665
--- /dev/null
+++ b/doc/forum/unlock__47__lock_always_gets_me/comment_1_dee73a7ea3e1a5154601adb59782831f._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2012-01-07T17:15:31Z"
+ content="""
+Well, lock could check for modifications and require --force to lose them. But the check could be expensive for large files.
+
+But `git annex lock` is just a convenient way to run `git checkout`. And running `git checkout` or `git reset --hard` will lose your uncommitted file the same way obviously.
+
+Perhaps the best fix would be to get rid of `lock` entirely, and let the user use the underlying git commands same as they would to drop modifications to other files. It would then also make sense to remove `unlock`, leaving only `edit`.
+"""]]
diff --git a/doc/forum/unlock__47__lock_always_gets_me/comment_2_f89b4349dde840c355a3bc28908decdf._comment b/doc/forum/unlock__47__lock_always_gets_me/comment_2_f89b4349dde840c355a3bc28908decdf._comment
new file mode 100644
index 000000000..f732c87da
--- /dev/null
+++ b/doc/forum/unlock__47__lock_always_gets_me/comment_2_f89b4349dde840c355a3bc28908decdf._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnRai_qFYPVvEgC6i1nlM1bh-C__jbhqS0"
+ nickname="Matthew"
+ subject="comment 2"
+ date="2013-09-07T12:26:46Z"
+ content="""
+I too was totally flummoxed by this.
+"""]]
diff --git a/doc/forum/unsynced_folder.mdwn b/doc/forum/unsynced_folder.mdwn
new file mode 100644
index 000000000..ceb04011e
--- /dev/null
+++ b/doc/forum/unsynced_folder.mdwn
@@ -0,0 +1,3 @@
+If I have an archive with a lot of big files, is it possible to get one of them without using the command line, and without it popping up on other clients of that repository?
+Is it possible to have a folder that will not be synced with other clients but will still download the file when i copy it from archive?
+.gitignore probably wont work because that will not get the file from archive.
diff --git a/doc/forum/updating_the___34__number_of_copies__34__.mdwn b/doc/forum/updating_the___34__number_of_copies__34__.mdwn
new file mode 100644
index 000000000..c28d26530
--- /dev/null
+++ b/doc/forum/updating_the___34__number_of_copies__34__.mdwn
@@ -0,0 +1,14 @@
+Is it possible to let git-annex check and update the "number of copies" or "whereis" information without recalculating the checksome?
+
+The use case is this:
+
+I have a very large "repo1": 300.000 files 1.5 TB.
+
+I copy it using low level tools for performance (clone the partition, netcat over network, or whatever...)
+
+Then i do "git annex init 'repo2'".
+All files exist in both repos and the simlinks are valid, but git-annex does not know about it.
+The "git-annex wehereis" only shows "repo1". How can I tell him without rehashing 1.6TB?
+
+Thx
+
diff --git a/doc/forum/updating_the___34__number_of_copies__34__/comment_1_327bdb0d9c190c60c7147b3acf07af09._comment b/doc/forum/updating_the___34__number_of_copies__34__/comment_1_327bdb0d9c190c60c7147b3acf07af09._comment
new file mode 100644
index 000000000..2fd4ffaee
--- /dev/null
+++ b/doc/forum/updating_the___34__number_of_copies__34__/comment_1_327bdb0d9c190c60c7147b3acf07af09._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.49"
+ subject="comment 1"
+ date="2012-12-01T18:40:46Z"
+ content="""
+Well, first of all, after copying a repository like this, you need to edit its .git/config and delete the annex.uuid setting. Otherwise, you will have two repositories with the same UUID, which is not good.
+
+Once you've done that, run `git annex fsck` in the new repository and it will do what you want.
+"""]]
diff --git a/doc/forum/updating_the___34__number_of_copies__34__/comment_2_7e11c839637e0894332e413cde02cee9._comment b/doc/forum/updating_the___34__number_of_copies__34__/comment_2_7e11c839637e0894332e413cde02cee9._comment
new file mode 100644
index 000000000..269fc22bc
--- /dev/null
+++ b/doc/forum/updating_the___34__number_of_copies__34__/comment_2_7e11c839637e0894332e413cde02cee9._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlgyVag95OnpvSzQofjyX0WjW__MOMKsl0"
+ nickname="Sehr"
+ subject="comment 2"
+ date="2012-12-01T19:27:59Z"
+ content="""
+Ok, that did the trick, except that it recalculates all cehcksums, which is exactly wat I do not want, as it is unnecessary and takes at 40MB/s just too long. Any other way? I think about adding the whereis info by hand, which simply feels wrong!
+"""]]
diff --git a/doc/forum/updating_the___34__number_of_copies__34__/comment_3_8b7a70fb3bb41e4eda412302834730bb._comment b/doc/forum/updating_the___34__number_of_copies__34__/comment_3_8b7a70fb3bb41e4eda412302834730bb._comment
new file mode 100644
index 000000000..c13095090
--- /dev/null
+++ b/doc/forum/updating_the___34__number_of_copies__34__/comment_3_8b7a70fb3bb41e4eda412302834730bb._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.49"
+ subject="comment 3"
+ date="2012-12-01T19:37:26Z"
+ content="""
+git annex fsck --fast will skip the checksumming.
+"""]]
diff --git a/doc/forum/use_existing_ssh_keys__63__.mdwn b/doc/forum/use_existing_ssh_keys__63__.mdwn
new file mode 100644
index 000000000..7f73c18bc
--- /dev/null
+++ b/doc/forum/use_existing_ssh_keys__63__.mdwn
@@ -0,0 +1,5 @@
+Hi, a new user trying out git-annex 3.20130124 here. So far looks really promising, thanks.
+
+I setup a local annex using the assistant webapp. I then created a rsync cloud repo over ssh to my shell box in a nearby data center for it. Works ok. I already have ssh key setup inclding ssh-agent for quick logins to the server. It would be great if you could configure the assistant to use these existing keys instead of creating a new set of keys. Maybe keep the defaults as is, but provide the config for this hidden behind "trust me, I know what I'm doing" check box or something.
+
+Thanks again, I keep researching.
diff --git a/doc/forum/use_existing_ssh_keys__63__/comment_1_c420c53f022bbd1b28494bc44d076feb._comment b/doc/forum/use_existing_ssh_keys__63__/comment_1_c420c53f022bbd1b28494bc44d076feb._comment
new file mode 100644
index 000000000..93cb92c55
--- /dev/null
+++ b/doc/forum/use_existing_ssh_keys__63__/comment_1_c420c53f022bbd1b28494bc44d076feb._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.3.125"
+ subject="comment 1"
+ date="2013-02-07T18:11:30Z"
+ content="""
+Hmm. The assistant already tries to cater to this case of having an existing key. When setting up a rsync or ssh remote, it first tries to ssh to the server without allowing a password to be prompted for. If this succeeds, it assumes you have a passwordless key and uses it. Otherwise, it sshes in once with a password prompt, and sets up its own key.
+"""]]
diff --git a/doc/forum/use_existing_ssh_keys__63__/comment_2_e4cae848e5701852073ced307832872b._comment b/doc/forum/use_existing_ssh_keys__63__/comment_2_e4cae848e5701852073ced307832872b._comment
new file mode 100644
index 000000000..4aaaeacce
--- /dev/null
+++ b/doc/forum/use_existing_ssh_keys__63__/comment_2_e4cae848e5701852073ced307832872b._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnwz07HJdp3nzLwCAl7OGKn_3m0tTO4Mxw"
+ nickname="Teemu"
+ subject="use existing ssh keys?"
+ date="2013-03-02T12:05:30Z"
+ content="""
+I also found the key setup confusing. I have many identity files for several server / service combinations, so the webapp key setup for an ssh+rsync cloud server always failed with too many identification attempts before I had the sense to move my keys temporarily away from ~/.ssh
+
+It would be really nice if the webapp would allow one either to pick an existing identity, or to create a new one with the aid of a couple of password logins.
+
+Also, having the created key to be restricted to only running rsync in the server would improve the chances of 'Share with a friend' use case being used. I don't think many people will want to give out full shell access to their servers in order to share some files.
+"""]]
diff --git a/doc/forum/use_existing_ssh_keys__63__/comment_3_a97c20b6df74c49e5f57c7caf962f1e2._comment b/doc/forum/use_existing_ssh_keys__63__/comment_3_a97c20b6df74c49e5f57c7caf962f1e2._comment
new file mode 100644
index 000000000..e90ed07be
--- /dev/null
+++ b/doc/forum/use_existing_ssh_keys__63__/comment_3_a97c20b6df74c49e5f57c7caf962f1e2._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-03-03T16:57:22Z"
+ content="""
+When pairing with a local computer, both systems set up locked down ssh keys that only allow the pair to run git-annex on the repository being paired with. This does *not* involve full shell access.
+
+The \"remote server\" necessarily involves you already having shell access to the remote server. However, the ssh key that the assistant generates is again locked down to only being able to run git-annex on a single repository on the remote server.
+"""]]
diff --git a/doc/forum/using_git_annex_to_merge_and_synchronize_2_directories___40__like_unison__41__.mdwn b/doc/forum/using_git_annex_to_merge_and_synchronize_2_directories___40__like_unison__41__.mdwn
new file mode 100644
index 000000000..86e317da8
--- /dev/null
+++ b/doc/forum/using_git_annex_to_merge_and_synchronize_2_directories___40__like_unison__41__.mdwn
@@ -0,0 +1,7 @@
+I would like to use git-annex to synchronize 2 directories in the same manner as unison.
+
+I'm starting with 2 directories. There is an overlap of the same set of files in each directory, but each directory also has additional files as well.
+
+I create a git annex in each directory but when I do a git pull it merges and produces conflicts on those files that are the same.
+
+What is the correct workflow for this type of scenario?
diff --git a/doc/forum/using_git_annex_to_merge_and_synchronize_2_directories___40__like_unison__41__/comment_1_5c3ee8a8aaa6d0918c0cc9683ce177ae._comment b/doc/forum/using_git_annex_to_merge_and_synchronize_2_directories___40__like_unison__41__/comment_1_5c3ee8a8aaa6d0918c0cc9683ce177ae._comment
new file mode 100644
index 000000000..4682ea64f
--- /dev/null
+++ b/doc/forum/using_git_annex_to_merge_and_synchronize_2_directories___40__like_unison__41__/comment_1_5c3ee8a8aaa6d0918c0cc9683ce177ae._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://www.joachim-breitner.de/"
+ nickname="nomeata"
+ subject="comment 1"
+ date="2011-12-18T13:57:33Z"
+ content="""
+Are the files identical or different? I today did something like that with similar, but not identical directories containing media files, and git happily merged them. but there, same files had same content.
+
+Also, make sure you use the same backend. In my case, one of the machines runs Debian stable, so I use the WORM backend, not the SHA backend.
+"""]]
diff --git a/doc/forum/using_git_annex_to_merge_and_synchronize_2_directories___40__like_unison__41__/comment_2_648946353c6d90c57351cce4010f1301._comment b/doc/forum/using_git_annex_to_merge_and_synchronize_2_directories___40__like_unison__41__/comment_2_648946353c6d90c57351cce4010f1301._comment
new file mode 100644
index 000000000..bdd4b25e4
--- /dev/null
+++ b/doc/forum/using_git_annex_to_merge_and_synchronize_2_directories___40__like_unison__41__/comment_2_648946353c6d90c57351cce4010f1301._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 2"
+ date="2011-12-19T18:24:59Z"
+ content="""
+I'd recommend using the SHA backend for this, the WORM backend would produce conflicts if the files' modification times changed.
+
+[[syncing_non-git_trees_with_git-annex]] describes one way to do it.
+"""]]
diff --git a/doc/forum/version_3_upgrade.mdwn b/doc/forum/version_3_upgrade.mdwn
new file mode 100644
index 000000000..7fdbcbc80
--- /dev/null
+++ b/doc/forum/version_3_upgrade.mdwn
@@ -0,0 +1,9 @@
+after upgrading to git-annex 3, i'm stuck with diverging git-annex branches -- i didn't manage to follow this line in the directions:
+
+> After this upgrade, you should make sure you include the git-annex branch when git pushing and pulling.
+
+could you explain how to do that in a littel more detail? git pull seems to only merge master, although i have these ``.git/config`` settings:
+
+ [branch "git-annex"]
+ remote = origin
+ merge = git-annex
diff --git a/doc/forum/version_3_upgrade/comment_1_05fc9c9cad26c520bebb98c852c71e35._comment b/doc/forum/version_3_upgrade/comment_1_05fc9c9cad26c520bebb98c852c71e35._comment
new file mode 100644
index 000000000..18746225e
--- /dev/null
+++ b/doc/forum/version_3_upgrade/comment_1_05fc9c9cad26c520bebb98c852c71e35._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-08-17T01:33:08Z"
+ content="""
+It's ok that `git pull` does not merge the git-annex branch. You can merge it with `git annex merge`, or it will be done
+automatically when you use other git-annex commands.
+
+If you use `git pull` and `git push` without any options, the defaults will make git pull and push the git-annex branch automatically.
+
+But if you're in the habit of doing `git push origin master`, that won't cause the git-annex branch to be pushed (use `git push origin git-annex` to manually push it then). Similarly, `git pull origin master` won't pull it. And also, the `remote.origin.fetch` setting in `.git/config` can be modified in ways that make `git pull` not automatically pull the git-annex branch. So those are the things to avoid after upgrade to v3, basically.
+"""]]
diff --git a/doc/forum/vlc_and_git-annex.mdwn b/doc/forum/vlc_and_git-annex.mdwn
new file mode 100644
index 000000000..cb07f8183
--- /dev/null
+++ b/doc/forum/vlc_and_git-annex.mdwn
@@ -0,0 +1,11 @@
+I used to save movies with the srt subtitle files next to them.
+
+Usually vlc finds it because it's on the same directory than the movie file, however with git annex the link is located on another folder.
+So after adding movies to git, the subtitles doesn't load anymore.
+
+couldn't find a quick fix. I'm thinking a bash script, but wanted to discuss it here with all annex users.
+
+I know It's out of annex scope, but I think a movie archive is a great scenario for git-annex.
+most of my HD is filled up with movies from the camcorder, screencast, etc...
+And we usually don't modify those files
+
diff --git a/doc/forum/vlc_and_git-annex/comment_1_9c9ab8ce463cf74418aa2f385955f165._comment b/doc/forum/vlc_and_git-annex/comment_1_9c9ab8ce463cf74418aa2f385955f165._comment
new file mode 100644
index 000000000..700b3808d
--- /dev/null
+++ b/doc/forum/vlc_and_git-annex/comment_1_9c9ab8ce463cf74418aa2f385955f165._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-12-23T16:16:19Z"
+ content="""
+From what you say, it seems that vlc is following the symlink to the movie content, and then looking for subtitles next to the file the symlink points to. It would have to explicitly realpath the symlink to have this behavior, and this sounds like a misfeature.. perhaps you could point out to the vlc people the mistake in doing so?
+
+There's a simple use-case where this behavior is obviously wrong, without involving git-annex. Suppose I have a movie, and one version of subtitles for it, in directory `foo`. I want to modify the subtitles, so I make a new directory `bar`, symlink the large movie file from `foo` to save space, and copy over and edit the subtitles from `foo`. Now I run vlc in `bar` to test my new subtitles. If it ignores the locally present subtitles and goes off looking for the ones in `bar`, I say this is broken behavior.
+"""]]
diff --git a/doc/forum/vlc_and_git-annex/comment_2_037f94c1deeac873dbdb36cd4c927e45._comment b/doc/forum/vlc_and_git-annex/comment_2_037f94c1deeac873dbdb36cd4c927e45._comment
new file mode 100644
index 000000000..3c69f5fe4
--- /dev/null
+++ b/doc/forum/vlc_and_git-annex/comment_2_037f94c1deeac873dbdb36cd4c927e45._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 2"
+ date="2011-12-23T18:43:05Z"
+ content="""
+Since subtitle files are typically pretty small, a workaround is to simply check them into git directly, and only use git-annex for the movies. (Or `git annex unannex` the ones you've already annexed.)
+"""]]
diff --git a/doc/forum/webapp___47___assistant_without_watch.mdwn b/doc/forum/webapp___47___assistant_without_watch.mdwn
new file mode 100644
index 000000000..9bb1fcf1a
--- /dev/null
+++ b/doc/forum/webapp___47___assistant_without_watch.mdwn
@@ -0,0 +1,9 @@
+I did not recieve feedback on my comment [1], so I try to post my question again but more clearly.
+
+Is it possible to run the assistent/the webapp without the functionality of 'git annex watch'?
+
+I'd like to use the assistant and to have the automatic syncing but I do not want the local repository to be watched. Instead I prefer to manually add/drop my files.
+
+I do not see the 'pause button' mentioned in my earlier question [1].
+
+[1] http://git-annex.branchable.com/forum/webapp_and_manual_mode/
diff --git a/doc/forum/webapp___47___assistant_without_watch/comment_1_1bcd99aa81f937ded683e19a69d33dd9._comment b/doc/forum/webapp___47___assistant_without_watch/comment_1_1bcd99aa81f937ded683e19a69d33dd9._comment
new file mode 100644
index 000000000..c76128ae3
--- /dev/null
+++ b/doc/forum/webapp___47___assistant_without_watch/comment_1_1bcd99aa81f937ded683e19a69d33dd9._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 1"
+ date="2013-08-26T18:14:17Z"
+ content="""
+The assistant is currently only able to transfer files that it has added itself. So if you disable syncing, you have to manually upload any files you add.
+
+I doubt that I will change this in the assistant, because supporting this use case would complicate it unnecessarily for a use case that is not what it's designed to do. It's more likely that `git annex sync` will get an option to also transfer file contents.
+"""]]
diff --git a/doc/forum/webapp___47___assistant_without_watch/comment_2_9f5b3f5bf7fedcd5baec519d97d3aa8c._comment b/doc/forum/webapp___47___assistant_without_watch/comment_2_9f5b3f5bf7fedcd5baec519d97d3aa8c._comment
new file mode 100644
index 000000000..a44155876
--- /dev/null
+++ b/doc/forum/webapp___47___assistant_without_watch/comment_2_9f5b3f5bf7fedcd5baec519d97d3aa8c._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="ringprince"
+ ip="134.76.140.110"
+ subject="comment 2"
+ date="2013-08-26T18:54:40Z"
+ content="""
+Thanks for the clarification.
+
+Although
+
+* not what I hoped for ;-)
+* I don't see that it would get complicated
+* I do not consider my use case special
+
+Anyway, thanks for this great piece of software.
+"""]]
diff --git a/doc/forum/webapp_and_manual_mode.mdwn b/doc/forum/webapp_and_manual_mode.mdwn
new file mode 100644
index 000000000..f7a903387
--- /dev/null
+++ b/doc/forum/webapp_and_manual_mode.mdwn
@@ -0,0 +1,7 @@
+Somehow I seemingly have not understood the manual mode.
+
+If I have a file in my repository, that is not yet in the annex (or in git), and I start the webapp, that file is automatically added to git-annex (and git).
+
+Why is that?
+
+And how can I use the webapp without such interference?
diff --git a/doc/forum/webapp_and_manual_mode/comment_1_5b5df5ffeb6ee15779972f13fdc11729._comment b/doc/forum/webapp_and_manual_mode/comment_1_5b5df5ffeb6ee15779972f13fdc11729._comment
new file mode 100644
index 000000000..677dd0414
--- /dev/null
+++ b/doc/forum/webapp_and_manual_mode/comment_1_5b5df5ffeb6ee15779972f13fdc11729._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.140"
+ subject="comment 1"
+ date="2013-07-21T17:17:58Z"
+ content="""
+Setting a repository to manual mode prevents the assistant from transferring new files into that repository. You have to manually run `git annex get`.
+
+To prevent the assistant from automatically adding files, you can click the pause button next to the current repository in the webapp.
+"""]]
diff --git a/doc/forum/webapp_and_manual_mode/comment_2_a1f06b50d1317c78a301b47eb05d2617._comment b/doc/forum/webapp_and_manual_mode/comment_2_a1f06b50d1317c78a301b47eb05d2617._comment
new file mode 100644
index 000000000..99efad90a
--- /dev/null
+++ b/doc/forum/webapp_and_manual_mode/comment_2_a1f06b50d1317c78a301b47eb05d2617._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="ringprince"
+ ip="134.76.2.1"
+ subject="comment 2"
+ date="2013-07-23T08:47:58Z"
+ content="""
+Not sure, what you mean.
+
+Disabling sync?
+But that also disables sync, right? ;-) So, if I add a file manually (via command line) that file is not synced automatically, correct?
+
+I do not see any other 'pause' button next to the repository.
+
+I am fine with git-annex doing the syncing automatically for me, but I want to be in control over the files git annex actually uses.
+
+If I just downloaded a big file, I might want to check it first before having git-annex move it to other repositories.
+
+
+"""]]
diff --git a/doc/forum/webapp_listen_port_with_autostart.mdwn b/doc/forum/webapp_listen_port_with_autostart.mdwn
new file mode 100644
index 000000000..fc9d1241b
--- /dev/null
+++ b/doc/forum/webapp_listen_port_with_autostart.mdwn
@@ -0,0 +1,3 @@
+To start the webapp on a X-less server it's possible to use the parameter `--listen` and then connect from a client with X to it.
+
+How can I start the webapp on all annex repos on this server like on a client with `assistant --autostart`? Would be nice to start the assistant on all configured repos which listens on a defined port, f.e. `git annex assistant --autostart --listen 0.0.0.0:8888`. It would be even nicer to have a parameter to chose a autostart configuration file, f.e. `git annex assistant --autostart --autostart-config /etc/git-annex/autostart --listen 0.0.0.0:8888`, so this could end up in a real server application, a init script would be easy to write...
diff --git a/doc/forum/webapp_listen_port_with_autostart/comment_1_65dbcf3d8f6c16568f5a326242eab9c5._comment b/doc/forum/webapp_listen_port_with_autostart/comment_1_65dbcf3d8f6c16568f5a326242eab9c5._comment
new file mode 100644
index 000000000..0c430cf7c
--- /dev/null
+++ b/doc/forum/webapp_listen_port_with_autostart/comment_1_65dbcf3d8f6c16568f5a326242eab9c5._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-05-13T18:49:25Z"
+ content="""
+Well, it would be possible to add a configuration setting in the repository that tells the assistant what address:port to listen on.
+
+But maybe it would be better to not use `assistant --autostart` in your situation? That command is basically the same as this shell script:
+
+[[!format sh "
+#!/bin/sh
+for dir in $(cat $HOME/.config/git-annex/autostart); do
+ cd $dir
+ git annex webapp &
+done
+"]]
+
+So you can write similar shell scripts that start the webapp with whatever options you like.
+"""]]
diff --git a/doc/forum/webapp_listen_port_with_autostart/comment_2_39664f833dedc1a4fe083eec9bc4a7cd._comment b/doc/forum/webapp_listen_port_with_autostart/comment_2_39664f833dedc1a4fe083eec9bc4a7cd._comment
new file mode 100644
index 000000000..0d48ba825
--- /dev/null
+++ b/doc/forum/webapp_listen_port_with_autostart/comment_2_39664f833dedc1a4fe083eec9bc4a7cd._comment
@@ -0,0 +1,75 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmiqeXJtP04fzHOjXs17kHO33v7dWR2xwA"
+ nickname="Jaco"
+ subject="Init Script"
+ date="2013-11-23T08:28:32Z"
+ content="""
+Hi Joey,
+
+Could you help out with writing an init.d script to safely start and stop the webapp on a headless server?
+I made an attempt below based on examples from the internet, but have no idea if it will work.
+
+ #!/bin/bash
+ # git-annex
+ # chkconfig: 345 20 80
+ # description: Git Annex WebApp startup and shutdown script.
+ # processname: git-annex
+
+
+ DAEMON=git-annex webapp
+
+ NAME=git-annex
+ DESC=\"Git Annex WebApp init script\"
+ PIDFILE=/var/run/$NAME.pid
+ SCRIPTNAME=/etc/init.d/$NAME
+
+ case \"$1\" in
+ start)
+ printf \"%-50s\" \"Starting $NAME...\"
+ for dir in $(cat $HOME/.config/git-annex/autostart); do
+ cd $dir
+ PID=`$DAEMON > /dev/null 2>&1 & echo $!`
+ #echo \"Saving PID\" $PID \" to \" $PIDFILE
+ if [ -z $PID ]; then
+ printf \"%s\n\" \"Fail\"
+ else
+ echo $PID > $PIDFILE
+ printf \"%s\n\" \"Ok\"
+ fi
+ done
+ ;;
+ status)
+ printf \"%-50s\" \"Checking $NAME...\"
+ if [ -f $PIDFILE ]; then
+ for PID in $(cat $PIDFILE); do
+ if [ -z \"`ps axf | grep ${PID} | grep -v grep`\" ]; then
+ printf \"%s\n\" \"Process dead but pidfile exists\"
+ else
+ echo \"Running\"
+ fi
+ done
+ else
+ printf \"%s\n\" \"Service not running\"
+ fi
+ ;;
+ stop)
+ printf \"%-50s\" \"Stopping $NAME\"
+ if [ -f $PIDFILE ]; then
+ for PID in $(cat $PIDFILE); do
+ kill -HUP $PID
+ printf \"%s\n\" \"Ok\"
+ done
+ rm -f $PIDFILE
+ else
+ printf \"%s\n\" \"pidfile not found\"
+ fi
+ ;;
+ restart)
+ $0 stop
+ $0 start
+ ;;
+ *)
+ echo \"Usage: $0 {status|start|stop|restart}\"
+ exit 1
+ esac
+"""]]
diff --git a/doc/forum/windows_port__63__.mdwn b/doc/forum/windows_port__63__.mdwn
new file mode 100644
index 000000000..092b8f8e1
--- /dev/null
+++ b/doc/forum/windows_port__63__.mdwn
@@ -0,0 +1,2 @@
+Any progress on Windows port? That would be very nice to have!
+Depending on the scale of it, I might be able to help.
diff --git a/doc/forum/windows_port__63__/comment_1_23fa9aa3b00940a1c1b3876c35eef019._comment b/doc/forum/windows_port__63__/comment_1_23fa9aa3b00940a1c1b3876c35eef019._comment
new file mode 100644
index 000000000..95323ff99
--- /dev/null
+++ b/doc/forum/windows_port__63__/comment_1_23fa9aa3b00940a1c1b3876c35eef019._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2012-03-12T06:43:02Z"
+ content="""
+[[todo/windows_support]] has everything I know about making a windows port. This badly needs someone who understand Windows to dive into it. The question of how to create a symbolic link (or the relevant Windows equivilant) from haskell on Windows
+is a good starting point..
+"""]]
diff --git a/doc/forum/wishlist:_get__47__drop_via_webapp_file_explorer.mdwn b/doc/forum/wishlist:_get__47__drop_via_webapp_file_explorer.mdwn
new file mode 100644
index 000000000..3be01480e
--- /dev/null
+++ b/doc/forum/wishlist:_get__47__drop_via_webapp_file_explorer.mdwn
@@ -0,0 +1 @@
+Know what'd be a sweet feature? A file explorer in the webapp that lets you get and drop files (for a Manual local repository). Especially when the webapp becomes available on Android. I'd love to be able to select what is and isn't present on a small device by some means other than moving files around.
diff --git a/doc/forum/wishlist:_get__47__drop_via_webapp_file_explorer/comment_1_c818a6d44dc13a56460b1865f70eb97c._comment b/doc/forum/wishlist:_get__47__drop_via_webapp_file_explorer/comment_1_c818a6d44dc13a56460b1865f70eb97c._comment
new file mode 100644
index 000000000..6cc0cf38b
--- /dev/null
+++ b/doc/forum/wishlist:_get__47__drop_via_webapp_file_explorer/comment_1_c818a6d44dc13a56460b1865f70eb97c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-04-11T14:55:43Z"
+ content="""
+There's a page called [[design/assistant/partial_content]] that discusses this idea and related things.
+"""]]
diff --git a/doc/forum/wishlist:_make_copy_stop_on_exhausted_disk_space.mdwn b/doc/forum/wishlist:_make_copy_stop_on_exhausted_disk_space.mdwn
new file mode 100644
index 000000000..8896fee37
--- /dev/null
+++ b/doc/forum/wishlist:_make_copy_stop_on_exhausted_disk_space.mdwn
@@ -0,0 +1,4 @@
+I'm trying to distribute a large annex to a number of smaller archive drives.
+
+While copying to a directory special remote, the current behaviour is to continue trying copying files into a remote, even as diskspace there has been exhausted.
+It would make sense for git-annex copy to actually stop instead.
diff --git a/doc/forum/wishlist:_make_copy_stop_on_exhausted_disk_space/comment_1_467e5e3db3e836030bc4b4f15846951f._comment b/doc/forum/wishlist:_make_copy_stop_on_exhausted_disk_space/comment_1_467e5e3db3e836030bc4b4f15846951f._comment
new file mode 100644
index 000000000..5c5f17ca9
--- /dev/null
+++ b/doc/forum/wishlist:_make_copy_stop_on_exhausted_disk_space/comment_1_467e5e3db3e836030bc4b4f15846951f._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.140"
+ subject="comment 1"
+ date="2013-07-18T19:49:43Z"
+ content="""
+Hmm, it might make sense to stop if there is no more space at all. However, just because the first file doesn't fit doesn't mean several following, smaller files can't be copied into the remaining space.
+
+Since it checks the free space before actually copying anything, it's not like there's much overhead in running through the list of files it was asked to copy and trying to copy them all, either.
+
+So, I'm unconvinced on this one.
+"""]]
diff --git a/doc/forum/wishlist:_make_copy_stop_on_exhausted_disk_space/comment_2_e3ca3db9bea11d3e085ee9c3c56b33fe._comment b/doc/forum/wishlist:_make_copy_stop_on_exhausted_disk_space/comment_2_e3ca3db9bea11d3e085ee9c3c56b33fe._comment
new file mode 100644
index 000000000..ee535549f
--- /dev/null
+++ b/doc/forum/wishlist:_make_copy_stop_on_exhausted_disk_space/comment_2_e3ca3db9bea11d3e085ee9c3c56b33fe._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawln3ckqKx0x_xDZMYwa9Q1bn4I06oWjkog"
+ nickname="Michael"
+ subject="comment 2"
+ date="2013-07-18T20:22:05Z"
+ content="""
+Actually with 4.20130709, I see the drive (ntfs-3g under Linux, gpg-encrypted special remote) being filled to 0 remaining space, even with reservespace of 300mb. Guess it's another bug anyway.
+"""]]
diff --git a/doc/forum/wishlist:_make_copy_stop_on_exhausted_disk_space/comment_3_0ef8c37350fc192d9b784fbab1d9f318._comment b/doc/forum/wishlist:_make_copy_stop_on_exhausted_disk_space/comment_3_0ef8c37350fc192d9b784fbab1d9f318._comment
new file mode 100644
index 000000000..a33cbcd27
--- /dev/null
+++ b/doc/forum/wishlist:_make_copy_stop_on_exhausted_disk_space/comment_3_0ef8c37350fc192d9b784fbab1d9f318._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.140"
+ subject="comment 3"
+ date="2013-07-20T20:33:37Z"
+ content="""
+Indeed, that was a bug with encrypted directory special remotes. Fixed it.
+"""]]
diff --git a/doc/forum/working_without_git-annex_commits.mdwn b/doc/forum/working_without_git-annex_commits.mdwn
new file mode 100644
index 000000000..00a61f3f0
--- /dev/null
+++ b/doc/forum/working_without_git-annex_commits.mdwn
@@ -0,0 +1,20 @@
+Is it possible to use git-annex without having [[location tracking]] commits in the style of "got a video I want to rewatch on the plane" or "freed up space" in the main tree?
+
+I consider these changes to be volatile, and irrelevant to the archive history. While they are unproblematic when it comes to merging, they make the commit tree rather complicated, especially with multiple users (as opposed to a single user managing his files on an external disk, a server and his laptop). Some users might even want to contribute to a shared repository without reporting on what they checked out.
+
+As a minimal solution, I configured a repository to ``.gitignore`` ``.git-annex/*:*.log``, but even when using modes that do not require that information (``git annex copy --from`` instead of ``git annex get``), that failes when git-annex tried to git-add ignored files.
+
+A more elaborate solution might be to keep location tracking information in a branch on its own (as suggested in [[todo/branching]]), keeping the main tree clean of such commits. A stealth user could then configure that branch to never be pushed. (Alternatively, if git-annex respects .gitignore and doesn't try to check in changes on ignored files, he could locally ``.gitignore`` ``.git-annex/*:*.log``.)
+
+> A stealth user can simply avoid pushing, and so keep their repository
+> in a forked state, that can still pull changes from origin.
+>
+> Beyond that, [[todo/branching]] is the best solution.
+>
+> I don't think that gitignoring the log files is a good plan, because
+> if the files are left modified and uncommitted, git will not be able to
+> merge other changes it pulls. The automerging of log files only works
+> if any local changes to them have been committed.
+>
+> It would be possible to add a knob that
+> simply blocks all local modifications to the log files. --[[Joey]]
diff --git a/doc/future_proofing.mdwn b/doc/future_proofing.mdwn
new file mode 100644
index 000000000..c9d1f068c
--- /dev/null
+++ b/doc/future_proofing.mdwn
@@ -0,0 +1,38 @@
+Imagine putting a git-annex drive in a time capsule. In 20, or 50, or 100
+years, you'd like its contents to be as accessible as possible to whoever
+digs it up.
+
+This is a hard problem. git-annex cannot completely solve it, but it does
+its best to not contribute to the problem. Here are some aspects of the
+problem:
+
+* How are files accessed? Git-annex carefully adds minimal complexity
+ to access files in a repository. Nothing needs to be done to extract
+ files from the repository; they are there on disk in the usual way,
+ with just some symlinks pointing at the annexed file contents.
+ Neither git-annex nor git is needed to get at the file contents.
+
+ (Also, git-annex provides an "uninit" command that moves everything out
+ of the annex, if you should ever want to stop using it.)
+
+* What file formats are used? Will they still be readable? To deal with
+ this, it's best to stick to plain text files, and the most common
+ image, sound, etc formats. Consider storing the same content in multiple
+ formats.
+
+* What filesystem is used on the drive? Will that filesystem still be
+ available? Whatever you choose to use, git-annex can put files on it.
+ Even if you choose (ugh) FAT.
+
+* What is the hardware interface of the drive? Will hardware still exist
+ to talk to it?
+
+* What if some of the data is damaged? git-annex facilitates storing a
+ configurable number of [[copies]] of the file contents. The metadata
+ about your files is stored in git, and so every clone of the repository
+ means another copy of that is stored. Also, git-annex uses filenames
+ for the data that encode everything needed to match it back to the
+ metadata. So if a filesystem is badly corrupted and all your annexed
+ files end up in `lost+found`, they can easily be lifted back out into
+ another clone of the repository. Even if the filenames are lost,
+ it's possible to [[tips/recover_data_from_lost+found]].
diff --git a/doc/git-annex-shell.mdwn b/doc/git-annex-shell.mdwn
new file mode 100644
index 000000000..c866154ac
--- /dev/null
+++ b/doc/git-annex-shell.mdwn
@@ -0,0 +1,120 @@
+# NAME
+
+git-annex-shell - Restricted login shell for git-annex only SSH access
+
+# SYNOPSIS
+
+git-annex-shell [-c] command [params ...]
+
+# DESCRIPTION
+
+git-annex-shell is a restricted shell, similar to git-shell, which
+can be used as a login shell for SSH accounts.
+
+Since its syntax is identical to git-shell's, it can be used as a drop-in
+replacement anywhere git-shell is used. For example it can be used as a
+user's restricted login shell.
+
+# COMMANDS
+
+Any command not listed below is passed through to git-shell.
+
+Note that the directory parameter should be an absolute path, otherwise
+it is assumed to be relative to the user's home directory. Also the
+first "/~/" or "/~user/" is expanded to the specified home directory.
+
+* configlist directory
+
+ This outputs a subset of the git configuration, in the same form as
+ `git config --list`
+
+* inannex directory [key ...]
+
+ This checks if all specified keys are present in the annex,
+ and exits zero if so.
+
+* dropkey directory [key ...]
+
+ This drops the annexed data for the specified keys.
+
+* recvkey directory key
+
+ This runs rsync in server mode to receive the content of a key,
+ and stores the content in the annex.
+
+* sendkey directory key
+
+ This runs rsync in server mode to transfer out the content of a key.
+
+* transferinfo directory key
+
+ This is typically run at the same time as sendkey is sending a key
+ to the remote. Using it is optional, but is used to update
+ progress information for the transfer of the key.
+
+ It reads lines from standard input, each giving the number of bytes
+ that have been received so far.
+
+* commit directory
+
+ This commits any staged changes to the git-annex branch.
+ It also runs the annex-content hook.
+
+* gcryptsetup gcryptid
+
+ Sets up a repository as a gcrypt repository.
+
+# OPTIONS
+
+Most options are the same as in git-annex. The ones specific
+to git-annex-shell are:
+
+* --uuid=UUID
+
+ git-annex uses this to specify the UUID of the repository it was expecting
+ git-annex-shell to access, as a sanity check.
+
+* -- fields=val fields=val.. --
+
+ Additional fields may be specified this way, to retain compatability with
+ past versions of git-annex-shell (that ignore these, but would choke
+ on new dashed options).
+
+ Currently used fields include remoteuuid=, associatedfile=,
+ and direct=
+
+# HOOK
+
+After content is received or dropped from the repository by git-annex-shell,
+it runs a hook, `.git/hooks/annex-content` (or `hooks/annex-content` on a bare
+repository). The hook is not currently passed any information about what
+changed.
+
+# ENVIRONMENT
+
+* GIT_ANNEX_SHELL_READONLY
+
+ If set, disallows any command that could modify the repository.
+
+* GIT_ANNEX_SHELL_LIMITED
+
+ If set, disallows running git-shell to handle unknown commands.
+
+* GIT_ANNEX_SHELL_DIRECTORY
+
+ If set, git-annex-shell will refuse to run commands that do not operate
+ on the specified directory.
+
+# SEE ALSO
+
+[[git-annex]](1)
+
+git-shell(1)
+
+# AUTHOR
+
+Joey Hess <joey@kitenet.net>
+
+<http://git-annex.branchable.com/>
+
+Warning: Automatically converted into a man page by mdwn2man. Edit with care
diff --git a/doc/git-annex.mdwn b/doc/git-annex.mdwn
new file mode 100644
index 000000000..25e1045db
--- /dev/null
+++ b/doc/git-annex.mdwn
@@ -0,0 +1,1419 @@
+# NAME
+
+git-annex - manage files with git, without checking their contents in
+
+# SYNOPSIS
+
+git annex command [params ...]
+
+# DESCRIPTION
+
+git-annex allows managing files with git, without checking the file
+contents into git. While that may seem paradoxical, it is useful when
+dealing with files larger than git can currently easily handle, whether due
+to limitations in memory, checksumming time, or disk space.
+
+Even without file content tracking, being able to manage files with git,
+move files around and delete files with versioned directory trees, and use
+branches and distributed clones, are all very handy reasons to use git. And
+annexed files can co-exist in the same git repository with regularly
+versioned files, which is convenient for maintaining documents, Makefiles,
+etc that are associated with annexed files but that benefit from full
+revision control.
+
+When a file is annexed, its content is moved into a key-value store, and
+a symlink is made that points to the content. These symlinks are checked into
+git and versioned like regular files. You can move them around, delete
+them, and so on. Pushing to another git repository will make git-annex
+there aware of the annexed file, and it can be used to retrieve its
+content from the key-value store.
+
+# EXAMPLES
+
+ # git annex get video/hackity_hack_and_kaxxt.mov
+ get video/_why_hackity_hack_and_kaxxt.mov (not available)
+ I was unable to access these remotes: server
+ Try making some of these repositories available:
+ 5863d8c0-d9a9-11df-adb2-af51e6559a49 -- my home file server
+ 58d84e8a-d9ae-11df-a1aa-ab9aa8c00826 -- portable USB drive
+ ca20064c-dbb5-11df-b2fe-002170d25c55 -- backup SATA drive
+ failed
+ # sudo mount /media/usb
+ # git remote add usbdrive /media/usb
+ # git annex get video/hackity_hack_and_kaxxt.mov
+ get video/hackity_hack_and_kaxxt.mov (from usbdrive...) ok
+
+ # git annex add iso
+ add iso/Debian_5.0.iso ok
+
+ # git annex drop iso/Debian_4.0.iso
+ drop iso/Debian_4.0.iso ok
+
+ # git annex move iso --to=usbdrive
+ move iso/Debian_5.0.iso (moving to usbdrive...) ok
+
+# COMMONLY USED COMMANDS
+
+Like many git commands, git-annex can be passed a path that
+is either a file or a directory. In the latter case it acts on all relevant
+files in the directory. When no path is specified, most git-annex commands
+default to acting on all relevant files in the current directory (and
+subdirectories).
+
+* `add [path ...]`
+
+ Adds files in the path to the annex. Files that are already checked into
+ git, or that git has been configured to ignore will be silently skipped.
+ (Use `--force` to add ignored files.) Dotfiles are skipped unless explicitly
+ listed.
+
+* `get [path ...]`
+
+ Makes the content of annexed files available in this repository. This
+ will involve copying them from another repository, or downloading them,
+ or transferring them from some kind of key-value store.
+
+ Normally git-annex will choose which repository to copy the content from,
+ but you can override this using the `--from` option.
+
+* `drop [path ...]`
+
+ Drops the content of annexed files from this repository.
+
+ git-annex will refuse to drop content if it cannot verify it is
+ safe to do so. This can be overridden with the `--force` switch.
+
+ To drop content from a remote, specify `--from`.
+
+* `move [path ...]`
+
+ When used with the `--from` option, moves the content of annexed files
+ from the specified repository to the current one.
+
+ When used with the `--to` option, moves the content of annexed files from
+ the current repository to the specified one.
+
+* `copy [path ...]`
+
+ When used with the `--from` option, copies the content of annexed files
+ from the specified repository to the current one.
+
+ When used with the `--to` option, copies the content of annexed files from
+ the current repository to the specified one.
+
+ To avoid contacting the remote to check if it has every file, specify `--fast`
+
+* `status` [path ...]`
+
+ Similar to `git status --short`, displays the status of the files in the
+ working tree. Shows files that are not checked into git, files that
+ have been deleted, and files that have been modified.
+ Particulary useful in direct mode.
+
+* `unlock [path ...]`
+
+ Normally, the content of annexed files is protected from being changed.
+ Unlocking a annexed file allows it to be modified. This replaces the
+ symlink for each specified file with a copy of the file's content.
+ You can then modify it and `git annex add` (or `git commit`) to inject
+ it back into the annex.
+
+* `edit [path ...]`
+
+ This is an alias for the unlock command. May be easier to remember,
+ if you think of this as allowing you to edit an annexed file.
+
+* `lock [path ...]`
+
+ Use this to undo an unlock command if you don't want to modify
+ the files, or have made modifications you want to discard.
+
+* `sync [remote ...]`
+
+ Use this command when you want to synchronize the local repository with
+ one or more of its remotes. You can specifiy the remotes to sync with;
+ the default is to sync with all remotes. Or specify `--fast` to sync with
+ the remotes with the lowest annex-cost value.
+
+ The sync process involves first committing all local changes
+ then fetching and merging the `synced/master` and the `git-annex` branch
+ from the remote repositories and finally pushing the changes back to
+ those branches on the remote repositories. You can use standard git
+ commands to do each of those steps by hand, or if you don't want to
+ worry about the details, you can use sync.
+
+ Merge conflicts are automatically resolved 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
+ are pushed to the remote, so can be merged into its working tree
+ by running "git annex sync" on the remote.
+
+ Note that sync does not transfer any file contents from or to the remote
+ repositories.
+
+* `merge`
+
+ This performs the same merging that is done by the sync command, but
+ without pushing or pulling any data.
+
+ One way to use this is to put `git annex merge` into a repository's
+ post-receive hook. Then any syncs to the repository will update its working
+ copy automatically.
+
+* `mirror [path ...]`
+
+ This causes a destination repository to mirror a source repository.
+
+ To use the local repository as the source repository,
+ specify mirror `--to` remote.
+
+ To use a remote as the source repository, specify mirror `--from` remote.
+
+ Each specified file in the source repository is mirrored to the destination
+ repository. If a file's content is present in the source repository, it is
+ copied to the destination repository. If a file's content is not present in
+ the source repository, it will be dropped from the destination repository
+ when possible.
+
+ Note that mirror does not sync the git repository, but only the file
+ contents.
+
+* `addurl [url ...]`
+
+ Downloads each url to its own file, which is added to the annex.
+
+ To avoid immediately downloading the url, specify `--fast`.
+
+ To avoid storing the size of the url's content, and accept whatever
+ is there at a future point, specify `--relaxed`. (Implies `--fast`.)
+
+ Normally the filename is based on the full url, so will look like
+ "www.example.com_dir_subdir_bigfile". For a shorter filename, specify
+ `--pathdepth=N`. For example, `--pathdepth=1` will use "dir/subdir/bigfile",
+ while `--pathdepth=3` will use "bigfile". It can also be negative;
+ `--pathdepth=-2` will use the last two parts of the url.
+
+ Or, to directly specify what file the url is added to, specify `--file`.
+ This changes the behavior; now all the specified urls are recorded as
+ alternate locations from which the file can be downloaded. In this mode,
+ addurl can be used both to add new files, or to add urls to existing files.
+
+ When quvi is installed, urls are automatically tested to see if they
+ are on a video hosting site, and the video is downloaded instead.
+
+* `rmurl file url`
+
+ Record that the file is no longer available at the url.
+
+* `import [path ...]`
+
+ Moves files from somewhere outside the git working copy, and adds them to
+ the annex. Individual files to import can be specified.
+ If a directory is specified, the entire directory is imported.
+
+ git annex import /media/camera/DCIM/*
+
+ By default, importing two files with the same contents from two different
+ locations will result in both files being added to the repository.
+ (With all checksumming backends, including the default SHA256E,
+ only one copy of the data will be stored.)
+
+ To not delete files from the import location, use the
+ `--duplicate` option. This could allow importing the same files repeatedly
+ to different locations in a repository. More likely, it could be used to
+ import the same files to a number of different branches or separate git
+ repositories.
+
+ To only import files whose content has not been seen before by git-annex,
+ use the `--deduplicate` option. Duplicate files will be deleted from the
+ import location.
+
+ The `--clean-duplicates` option does not import any new files, but any files
+ found in the import location that are duplicates of content in the annex
+ are deleted.
+
+ (Note that using `--deduplicate` or `--clean-duplicates` with the WORM
+ backend does not look at file content, but filename and mtime.)
+
+* `importfeed [url ...]`
+
+ Imports the contents of podcast feeds. Only downloads files whose
+ urls have not already been added to the repository before, so you can
+ delete, rename, etc the resulting files and repeated runs won't duplicate
+ them. (Use `--force` to force downloading urls it's seen before.)
+
+ Use `--template` to control where the files are stored.
+ The default template is '${feedtitle}/${itemtitle}${extension}'
+ (Other available variables: feedauthor, itemauthor, itemsummary, itemdescription, itemrights, itemid)
+
+ The `--relaxed` and `--fast` options behave the same as they do in addurl.
+
+* `watch`
+
+ Watches for changes to files in the current directory and its subdirectories,
+ and takes care of automatically adding new files, as well as dealing with
+ deleted, copied, and moved files. With this running as a daemon in the
+ background, you no longer need to manually run git commands when
+ manipulating your files.
+
+ By default, all files in the directory will be added to the repository.
+ (Including dotfiles.) To block some files from being added, use
+ `.gitignore` files.
+
+ By default, all files that are added are added to the annex, the same
+ as when you run `git annex add`. If you configure annex.largefiles,
+ files that it does not match will instead be added with `git add`.
+
+ To not daemonize, run with `--foreground` ; to stop a running daemon,
+ run with `--stop`
+
+* `assistant`
+
+ Like watch, but also automatically syncs changes to other remotes.
+ Typically started at boot, or when you log in.
+
+ With the `--autostart` option, the assistant is started in any repositories
+ it has created. These are listed in `~/.config/git-annex/autostart`
+
+* `webapp`
+
+ Opens a web app, that allows easy setup of a git-annex repository,
+ and control of the git-annex assistant.
+
+ By default, the webapp can only be accessed from localhost, and running
+ it opens a browser window.
+
+ With the `--listen=address[:port]` option, the webapp can be made to listen
+ for connections on the specified address. This disables running a
+ local web browser, and outputs the url you can use to open the webapp
+ from a remote computer.
+ Note that this does not yet use HTTPS for security, so use with caution!
+
+# REPOSITORY SETUP COMMANDS
+
+* `init [description]`
+
+ Until a repository (or one of its remotes) has been initialized,
+ git-annex will refuse to operate on it, to avoid accidentially
+ using it in a repository that was not intended to have an annex.
+
+ It's useful, but not mandatory, to initialize each new clone
+ of a repository with its own description. If you don't provide one,
+ one will be generated.
+
+* `describe repository description`
+
+ Changes the description of a repository.
+
+ The repository to describe can be specified by git remote name or
+ by uuid. To change the description of the current repository, use
+ "here".
+
+* `initremote name [param=value ...]`
+
+ Creates a new special remote, and adds it to `.git/config`.
+
+ The remote's configuration is specified by the parameters. Different
+ types of special remotes need different configuration values. The
+ command will prompt for parameters as needed.
+
+ All special remotes support encryption. You can either specify
+ `encryption=none` to disable encryption, or specify
+ `encryption=hybrid keyid=$keyid ...` to specify a gpg key id (or an email
+ address associated with a key.)
+
+ There are actually three schemes that can be used for management of the
+ encryption keys. When using the encryption=hybrid scheme, additional
+ gpg keys can be given access to the encrypted special remote easily
+ (without re-encrypting everything). When using encryption=shared,
+ a shared key is generated and stored in the git repository, allowing
+ anyone who can clone the git repository to access it. Finally, when using
+ encryption=pubkey, content in the special remote is directly encrypted
+ to the specified gpg keys, and additional ones cannot easily be given
+ access.
+
+ Note that with encryption enabled, a cryptographic key is created.
+ This requires sufficient entropy. If initremote seems to hang or take
+ a long time while generating the key, you may want to ctrl-c it and
+ re-run with `--fast`, which causes it to use a lower-quality source of
+ randomness.
+
+ Example Amazon S3 remote:
+
+ git annex initremote mys3 type=S3 encryption=hybrid keyid=me@example.com datacenter=EU
+
+* `enableremote name [param=value ...]`
+
+ Enables use of an existing special remote in the current repository,
+ which may be a different repository than the one in which it was
+ originally created with the initremote command.
+
+ The name of the remote is the same name used when origianlly
+ creating that remote with "initremote". Run "git annex enableremote"
+ with no parameters to get a list of special remote names.
+
+ Some special remotes may need parameters to be specified every time.
+ For example, the directory special remote requires a directory= parameter.
+
+ This command can also be used to modify the configuration of an existing
+ special remote, by specifying new values for parameters that were
+ originally set when using initremote. (However, some settings such as
+ the as the encryption scheme cannot be changed once a special remote
+ has been created.)
+
+ The gpg keys that an encrypted special remote is encrypted to can be
+ changed using the keyid+= and keyid-= parameters. These respectively
+ add and remove keys from the list. However, note that removing a key
+ does NOT necessarily prevent the key's owner from accessing data
+ in the encrypted special remote
+ (which is by design impossible, short of deleting the remote).
+
+ One use-case of keyid-= is to replace a revoked key with
+ a new key:
+
+ git annex enableremote mys3 keyid-=revokedkey keyid+=newkey
+
+ Also, note that for encrypted special remotes using plain public-key
+ encryption (encryption=pubkey), adding or removing a key has NO effect
+ on files that have already been copied to the remote. Hence using
+ keyid+= and keyid-= with such remotes should be used with care, and
+ make little sense except in cases like the revoked key example above.
+
+* `trust [repository ...]`
+
+ Records that a repository is trusted to not unexpectedly lose
+ content. Use with care.
+
+ To trust the current repository, use "here".
+
+* `untrust [repository ...]`
+
+ Records that a repository is not trusted and could lose content
+ at any time.
+
+* `semitrust [repository ...]`
+
+ Returns a repository to the default semi trusted state.
+
+* `dead [repository ...]`
+
+ Indicates that the repository has been irretrevably lost.
+ (To undo, use semitrust.)
+
+* `group repository groupname`
+
+ Adds a repository to a group, such as "archival", "enduser", or "transfer".
+ The groupname must be a single word.
+
+* `ungroup repository groupname`
+
+ Removes a repository from a group.
+
+* `wanted repository [expression]`
+
+ When run with an expression, configures the content that is preferred
+ to be held in the archive. See PREFERRED CONTENT below.
+
+ For example:
+
+ git annex wanted . "include=*.mp3 or include=*.ogg"
+
+ Without an expression, displays the current preferred content setting
+ of the repository.
+
+* `schedule repository [expression]`
+
+ When run with an expression, configures scheduled jobs to run at a
+ particular time. This can be used to make the assistant periodically run
+ incremental fscks. See SCHEDULED JOBS below.
+
+* `vicfg`
+
+ Opens EDITOR on a temp file containing most of the above configuration
+ settings, and when it exits, stores any changes made back to the git-annex
+ branch.
+
+* `direct`
+
+ Switches a repository to use direct mode, where rather than symlinks to
+ files, the files are directly present in the repository.
+
+ As part of the switch to direct mode, any changed files will be committed.
+
+ Note that git commands that operate on the work tree are often unsafe to
+ use in direct mode repositories, and can result in data loss or other
+ bad behavior.
+
+* `indirect`
+
+ Switches a repository back from direct mode to the default, indirect mode.
+
+ As part of the switch from direct mode, any changed files will be committed.
+
+# REPOSITORY MAINTENANCE COMMANDS
+
+* `fsck [path ...]`
+
+ With no parameters, this command checks the whole annex for consistency,
+ and warns about or fixes any problems found. This is a good compliment to
+ `git fsck`.
+
+ With parameters, only the specified files are checked.
+
+ To check a remote to fsck, specify `--from`.
+
+ To avoid expensive checksum calculations (and expensive transfers when
+ fscking a remote), specify `--fast`.
+
+ To start a new incremental fsck, specify `--incremental`. Then
+ the next time you fsck, you can specify `--more` to skip over
+ files that have already been checked, and continue where it left off.
+
+ The `--incremental-schedule` option makes a new incremental fsck be
+ started a configurable time after the last incremental fsck was started.
+ Once the current incremental fsck has completely finished, it causes
+ a new one to start.
+
+ Maybe you'd like to run a fsck for 5 hours at night, picking up each
+ night where it left off. You'd like this to continue until all files
+ have been fscked. And once it's done, you'd like a new fsck pass to start,
+ but no more often than once a month. Then put this in a nightly cron job:
+
+ git annex fsck --incremental-schedule 30d --time-limit 5h
+
+ To verify data integrity only while disregarding required number of copies,
+ use `--numcopies=1`.
+
+* `unused`
+
+ Checks the annex for data that does not correspond to any files present
+ in any tag or branch, and prints a numbered list of the data.
+
+ To only show unused temp and bad files, specify `--fast`.
+
+ To check for annexed data on a remote, specify `--from`.
+
+ After running this command, you can use the `--unused` option to
+ operate on all the unused data that was found. For example, to
+ move all unused data to origin:
+
+ git annex unused; git annex move --unused --to origin
+
+* `dropunused [number|range ...]`
+
+ Drops the data corresponding to the numbers, as listed by the last
+ `git annex unused`
+
+ You can also specify ranges of numbers, such as "1-1000".
+ Or, specify "all" to drop all unused data.
+
+ To drop the data from a remote, specify `--from.`
+
+* `addunused [number|range ...]`
+
+ Adds back files for the content corresponding to the numbers or ranges,
+ as listed by the last `git annex unused`. The files will have names
+ starting with "unused."
+
+* `fix [path ...]`
+
+ Fixes up symlinks that have become broken to again point to annexed content.
+ This is useful to run if you have been moving the symlinks around,
+ but is done automatically when committing a change with git too.
+
+* `upgrade`
+
+ Upgrades the repository to current layout.
+
+* `forget`
+
+ Causes the git-annex branch to be rewritten, throwing away historical
+ data about past locations of files. The resulting branch will use less
+ space, but `git annex log` will not be able to show where
+ files used to be located.
+
+ To also prune references to repositories that have been marked as dead,
+ specify `--drop-dead`.
+
+ When this rewritten branch is merged into other clones of
+ the repository, `git-annex` will automatically perform the same rewriting
+ to their local `git-annex` branches. So the forgetfulness will automatically
+ propigate out from its starting point until all repositories running
+ git-annex have forgotten their old history. (You may need to force
+ git to push the branch to any git repositories not running git-annex.)
+
+* `repair`
+
+ This can repair many of the problems with git repositories that `git fsck`
+ detects, but does not itself fix. It's useful if a repository has become
+ badly damaged. One way this can happen is if a repisitory used by git-annex
+ is on a removable drive that gets unplugged at the wrong time.
+
+ This command can actually be used inside git repositories that do not
+ use git-annex at all; when used in a repository using git-annex, it
+ does additional repairs of the git-annex branch.
+
+ It works by deleting any corrupt objects from the git repository, and
+ retriving all missing objects it can from the remotes of the repository.
+
+ If that is not sufficient to fully recover the repository, it can also
+ reset branches back to commits before the corruption happened, delete
+ branches that are no longer available due to the lost data, and remove any
+ missing files from the index. It will only do this if run with the
+ `--force` option, since that rewrites history and throws out missing data.
+ Note that the `--force` option never touches tags, even if they are no
+ longer usable due to missing data.
+
+ After running this command, you will probably want to run `git fsck` to
+ verify it fixed the repository. Note that fsck may still complain about
+ objects referenced by the reflog, or the stash, if they were unable to be
+ recovered. This command does not try to clean up either the reflog or the
+ stash.
+
+ It is also a good idea to run `git annex fsck --fast` after this command,
+ to make sure that the git-annex branch reflects reality.
+
+# QUERY COMMANDS
+
+* `find [path ...]`
+
+ Outputs a list of annexed files in the specified path. With no path,
+ finds files in the current directory and its subdirectories.
+
+ By default, only lists annexed files whose content is currently present.
+ This can be changed by specifying file matching options. To list all
+ annexed files, present or not, specify `--include "*"`. To list all
+ annexed files whose content is not present, specify `--not --in=here`
+
+ To output filenames terminated with nulls, for use with xargs -0,
+ specify `--print0`. Or, a custom output formatting can be specified using
+ `--format`. The default output format is the same as `--format='${file}\\n'`
+
+ These variables are available for use in formats: file, key, backend,
+ bytesize, humansize
+
+* `whereis [path ...]`
+
+ Displays a information about where the contents of files are located.
+
+* `list [path ...]`
+
+ Displays a table of remotes that contain the contents of the specified
+ files. This is similar to whereis but a more compact display. Only
+ configured remotes are shown by default; specify --allrepos to list
+ all repositories.
+
+* `log [path ...]`
+
+ Displays the location log for the specified file or files,
+ showing each repository they were added to ("+") and removed from ("-").
+
+ To limit how far back to seach for location log changes, the options
+ `--since`, `--after`, `--until`, `--before`, and `--max-count` can be specified.
+ They are passed through to git log. For example, `--since "1 month ago"`
+
+ To generate output suitable for the gource visualisation program,
+ specify `--gource`.
+
+* `info [directory ...]`
+
+ Displays some statistics and other information, including how much data
+ is in the annex and a list of all known repositories.
+
+ To only show the data that can be gathered quickly, use `--fast`.
+
+ When a directory is specified, shows a differently formatted info
+ display for that directory. In this mode, all of the file matching
+ options can be used to filter the files that will be included in
+ the information.
+
+ For example, suppose you want to run "git annex get .", but
+ would first like to see how much disk space that will use.
+ Then run:
+
+ git annex info --fast . --not --in here
+* `version`
+
+ Shows the version of git-annex, as well as repository version information.
+
+* `map`
+
+ Helps you keep track of your repositories, and the connections between them,
+ by going out and looking at all the ones it can get to, and generating a
+ Graphviz file displaying it all. If the `dot` command is available, it is
+ used to display the file to your screen (using x11 backend). (To disable
+ this display, specify `--fast`)
+
+ This command only connects to hosts that the host it's run on can
+ directly connect to. It does not try to tunnel through intermediate hosts.
+ So it might not show all connections between the repositories in the network.
+
+ Also, if connecting to a host requires a password, you might have to enter
+ it several times as the map is being built.
+
+ Note that this subcommand can be used to graph any git repository; it
+ is not limited to git-annex repositories.
+
+# UTILITY COMMANDS
+
+* `migrate [path ...]`
+
+ Changes the specified annexed files to use the default key-value backend
+ (or the one specified with `--backend`). Only files whose content
+ is currently available are migrated.
+
+ Note that the content is also still available using the old key after
+ migration. Use `git annex unused` to find and remove the old key.
+
+ Normally, nothing will be done to files already using the new backend.
+ However, if a backend changes the information it uses to construct a key,
+ this can also be used to migrate files to use the new key format.
+
+* `reinject src dest`
+
+ Moves the src file into the annex as the content of the dest file.
+ This can be useful if you have obtained the content of a file from
+ elsewhere and want to put it in the local annex.
+
+ Automatically runs fsck on dest to check that the expected content was
+ provided.
+
+ Example:
+
+ git annex reinject /tmp/foo.iso foo.iso
+
+* `unannex [path ...]`
+
+ Use this to undo an accidental `git annex add` command. It puts the
+ file back how it was before the add.
+
+ Note that for safety, the content of the file remains in the annex,
+ until you use `git annex unused` and `git annex dropunused`.
+
+ This is not the command you should use if you intentionally annexed a
+ file and don't want its contents any more. In that case you should use
+ `git annex drop` instead, and you can also `git rm` the file.
+
+ Normally this does a slow copy of the file. In `--fast` mode, it
+ instead makes a hard link from the file to the content in the annex.
+ But use --fast mode with caution, because editing the file will
+ change the content in the annex.
+
+* `uninit`
+
+ Use this to stop using git annex. It will unannex every file in the
+ repository, and remove all of git-annex's other data, leaving you with a
+ git repository plus the previously annexed files.
+
+# PLUMBING COMMANDS
+
+* `pre-commit [path ...]`
+
+ This is meant to be called from git's pre-commit hook. `git annex init`
+ automatically creates a pre-commit hook using this.
+
+ Fixes up symlinks that are staged as part of a commit, to ensure they
+ point to annexed content. Also handles injecting changes to unlocked
+ files into the annex.
+
+* `update-hook refname olvrev newrev`
+
+ This is meant to be called from git's update hook. `git annex init`
+ automatically creates an update hook using this.
+
+ This denies updates being pushed for the currently checked out branch.
+ While receive.denyCurrentBranch normally prevents that, it does
+ not for fake bare repositories, as used by direct mode.
+
+* `fromkey key file`
+
+ This plumbing-level command can be used to manually set up a file
+ in the git repository to link to a specified key.
+
+* `dropkey [key ...]`
+
+ This plumbing-level command drops the annexed data for the specified
+ keys from this repository.
+
+ This can be used to drop content for arbitrary keys, which do not need
+ to have a file in the git repository pointing at them.
+
+ Example:
+
+ git annex dropkey SHA1-s10-7da006579dd64330eb2456001fd01948430572f2
+
+* `transferkeys`
+
+ This plumbing-level command is used by the assistant to transfer data.
+
+* `rekey [file key ...]`
+
+ This plumbing-level command is similar to migrate, but you specify
+ both the file, and the new key to use for it.
+
+ With `--force`, even files whose content is not currently available will
+ be rekeyed. Use with caution.
+
+* `test`
+
+ This runs git-annex's built-in test suite.
+
+* `xmppgit`
+
+ This command is used internally to perform git pulls over XMPP.
+
+# OPTIONS
+
+* `--force`
+
+ Force unsafe actions, such as dropping a file's content when no other
+ source of it can be verified to still exist, or adding ignored files.
+ Use with care.
+
+* `--fast`
+
+ Enables less expensive, but also less thorough versions of some commands.
+ What is avoided depends on the command.
+
+* `--auto`
+
+ Enables automatic mode. Commands that get, drop, or move file contents
+ will only do so when needed to help satisfy the setting of annex.numcopies,
+ and preferred content configuration.
+
+* `--all`
+
+ Operate on all data that has been stored in the git annex,
+ including old versions of files. This is the default behavior when
+ running git-annex in a bare repository; in a non-bare repository the
+ normal behavior is to only operate on specified files in the working
+ tree.
+
+* `--unused`
+
+ Operate on all data that has been determined to be unused by
+ a previous run of `git-annex unused`.
+
+* `--quiet`
+
+ Avoid the default verbose display of what is done; only show errors
+ and progress displays.
+
+* `--verbose`
+
+ Enable verbose display.
+
+* `--json`
+
+ Rather than the normal output, generate JSON. This is intended to be
+ parsed by programs that use git-annex. Each line of output is a JSON
+ object. Note that json output is only usable with some git-annex commands,
+ like info and find.
+
+* `--debug`
+
+ Show debug messages.
+
+* `--no-debug`
+
+ Disable debug messages.
+
+* `--from=repository`
+
+ Specifies a repository that content will be retrieved from, or that
+ should otherwise be acted on.
+
+ It should be specified using the name of a configured remote.
+
+* `--to=repository`
+
+ Specifies a repository that content will be sent to.
+
+ It should be specified using the name of a configured remote.
+
+* `--numcopies=n`
+
+ Overrides the `annex.numcopies` setting, forcing git-annex to ensure the
+ specified number of copies exist.
+
+ Note that setting numcopies to 0 is very unsafe.
+
+* `--time-limit=time`
+
+ Limits how long a git-annex command runs. The time can be something
+ like "5h", or "30m" or even "45s" or "10d".
+
+ Note that git-annex may continue running a little past the specified
+ time limit, in order to finish processing a file.
+
+ Also, note that if the time limit prevents git-annex from doing all it
+ was asked to, it will exit with a special code, 101.
+
+* `--trust=repository`
+* `--semitrust=repository`
+* `--untrust=repository`
+
+ Overrides trust settings for a repository. May be specified more than once.
+
+ The repository should be specified using the name of a configured remote,
+ or the UUID or description of a repository.
+
+* `--trust-glacier-inventory`
+
+ Amazon Glacier inventories take hours to retrieve, and may not represent
+ the current state of a repository. So git-annex does not trust that
+ files that the inventory claims are in Glacier are really there.
+ This switch can be used to allow it to trust the inventory.
+
+ Be careful using this, especially if you or someone else might have recently
+ removed a file from Glacier. If you try to drop the only other copy of the
+ file, and this switch is enabled, you could lose data!
+
+* `--backend=name`
+
+ Specifies which key-value backend to use. This can be used when
+ adding a file to the annex, or migrating a file. Once files
+ are in the annex, their backend is known and this option is not
+ necessary.
+
+* `--format=value`
+
+ Specifies a custom output format. The value is a format string,
+ in which '${var}' is expanded to the value of a variable. To right-justify
+ a variable with whitespace, use '${var;width}' ; to left-justify
+ a variable, use '${var;-width}'; to escape unusual characters in a variable,
+ use '${escaped_var}'
+
+ Also, '\\n' is a newline, '\\000' is a NULL, etc.
+
+* `--user-agent=value`
+
+ Overrides the User-Agent to use when downloading files from the web.
+
+* `-c name=value`
+
+ Used to override git configuration settings. May be specified multiple times.
+
+# FILE MATCHING OPTIONS
+
+These options can all be specified multiple times, and can be combined to
+limit which files git-annex acts on.
+
+Arbitrarily complicated expressions can be built using these options.
+For example:
+
+ --exclude '*.mp3' --and --not -( --in=usbdrive --or --in=archive -)
+
+The above example prevents git-annex from working on mp3 files whose
+file contents are present at either of two repositories.
+
+* `--exclude=glob`
+
+ Skips files matching the glob pattern. The glob is matched relative to
+ the current directory. For example:
+
+ --exclude='*.mp3' --exclude='subdir/*'
+
+* `--include=glob`
+
+ Skips files not matching the glob pattern. (Same as `--not --exclude`.)
+ For example, to include only mp3 and ogg files:
+
+ --include='*.mp3' --or --include='*.ogg'
+
+* `--in=repository`
+
+ Matches only files that git-annex believes have their contents present
+ in a repository. Note that it does not check the repository to verify
+ that it still has the content.
+
+ The repository should be specified using the name of a configured remote,
+ or the UUID or description of a repository. For the current repository,
+ use `--in=here`
+
+* `--copies=number`
+
+ Matches only files that git-annex believes to have the specified number
+ of copies, or more. Note that it does not check remotes to verify that
+ the copies still exist.
+
+* `--copies=trustlevel:number`
+
+ Matches only files that git-annex believes have the specified number of
+ copies, on remotes with the specified trust level. For example,
+ `--copies=trusted:2`
+
+ To match any trust level at or higher than a given level,
+ use 'trustlevel+'. For example, `--copies=semitrusted+:2`
+
+* `--copies=groupname:number`
+
+ Matches only files that git-annex believes have the specified number of
+ copies, on remotes in the specified group. For example,
+ `--copies=archive:2`
+
+* `--inbackend=name`
+
+ Matches only files whose content is stored using the specified key-value
+ backend.
+
+* `--inallgroup=groupname`
+
+ Matches only files that git-annex believes are present in all repositories
+ in the specified group.
+
+* `--smallerthan=size`
+* `--largerthan=size`
+
+ Matches only files whose content is smaller than, or larger than the
+ specified size.
+
+ The size can be specified with any commonly used units, for example,
+ "0.5 gb" or "100 KiloBytes"
+
+* `--want-get`
+
+ Matches files that the preferred content settings for the repository
+ make it want to get. Note that this will match even files that are
+ already present, unless limited with eg, `--not --in .`
+
+* `--want-drop`
+
+ Matches files that the preferred content settings for the repository
+ make it want to drop. Note that this will match even files that have
+ already been dropped, unless limited with eg, `--in .`
+
+* `--not`
+
+ Inverts the next file matching option. For example, to only act on
+ files with less than 3 copies, use `--not --copies=3`
+
+* `--and`
+
+ Requires that both the previous and the next file matching option matches.
+ The default.
+
+* `--or`
+
+ Requires that either the previous, or the next file matching option matches.
+
+* `-(`
+
+ Opens a group of file matching options.
+
+* `-)`
+
+ Closes a group of file matching options.
+
+# PREFERRED CONTENT
+
+Each repository has a preferred content setting, which specifies content
+that the repository wants to have present. These settings can be configured
+using `git annex vicfg` or `git annex wanted`.
+They are used by the `--auto` option, and by the git-annex assistant.
+
+The preferred content settings are similar, but not identical to
+the file matching options specified above, just without the dashes.
+For example:
+
+ exclude=archive/* and (include=*.mp3 or smallerthan=1mb)
+
+The main differences are that `exclude=` and `include=` always
+match relative to the top of the git repository, and that there is
+no equivilant to `--in`.
+
+When a repository is in one of the standard predefined groups, like "backup"
+and "client", setting its preferred content to "standard" will use a
+built-in preferred content expression ddeveloped for that group.
+
+# SCHEDULED JOBS
+
+The git-annex assistant daemon can be configured to run scheduled jobs.
+This is similar to cron and anacron (and you can use them if you prefer),
+but has the advantage of being integrated into git-annex, and so being able
+to eg, fsck a repository on a removable drive when the drive gets
+connected.
+
+The scheduled jobs can be configured using `git annex vicfg` or
+`git annex schedule`.
+
+These actions are available: "fsck self", "fsck UUID" (where UUID
+is the UUID of a remote to fsck). After the action comes the duration
+to allow the action to run, and finally the schedule of when to run it.
+
+To schedule multiple jobs, separate them with "; ".
+
+Some examples:
+
+ fsck self 30m every day at any time
+ fsck self 1h every month at 3 AM
+ fsck self 1h on day 1 of every month at any time
+ fsck self 1h every week divisible by 2 at any time
+
+# CONFIGURATION VIA .git/config
+
+Like other git commands, git-annex is configured via `.git/config`.
+Here are all the supported configuration settings.
+
+* `annex.uuid`
+
+ A unique UUID for this repository (automatically set).
+
+* `annex.numcopies`
+
+ Number of copies of files to keep across all repositories. (default: 1)
+
+ Note that setting numcopies to 0 is very unsafe.
+
+* `annex.backends`
+
+ Space-separated list of names of the key-value backends to use.
+ The first listed is used to store new files by default.
+
+* `annex.diskreserve`
+
+ Amount of disk space to reserve. Disk space is checked when transferring
+ content to avoid running out, and additional free space can be reserved
+ via this option, to make space for more important content (such as git
+ commit logs). Can be specified with any commonly used units, for example,
+ "0.5 gb" or "100 KiloBytes"
+
+ The default reserve is 1 megabyte.
+
+* `annex.largefiles`
+
+ Allows configuring which files `git annex add` and the assistant consider
+ to be large enough to need to be added to the annex. By default,
+ all files are added to the annex.
+
+ The value is a preferred content expression. See PREFERRED CONTENT
+ for details.
+
+ Example:
+
+ annex.largefiles = largerthan=100kb and not (include=*.c or include=*.h)
+
+* `annex.queuesize`
+
+ git-annex builds a queue of git commands, in order to combine similar
+ commands for speed. By default the size of the queue is limited to
+ 10240 commands; this can be used to change the size. If you have plenty
+ of memory and are working with very large numbers of files, increasing
+ the queue size can speed it up.
+
+* `annex.bloomcapacity`
+
+ The `git annex unused` command uses a bloom filter to determine
+ what data is no longer used. The default bloom filter is sized to handle
+ up to 500000 keys. If your repository is larger than that,
+ you can adjust this to avoid `git annex unused` not noticing some unused
+ data files. Increasing this will make `git-annex unused` consume more memory;
+ run `git annex info` for memory usage numbers.
+
+* `annex.bloomaccuracy`
+
+ Adjusts the accuracy of the bloom filter used by
+ `git annex unused`. The default accuracy is 1000 --
+ 1 unused file out of 1000 will be missed by `git annex unused`. Increasing
+ the accuracy will make `git annex unused` consume more memory;
+ run `git annex info` for memory usage numbers.
+
+* `annex.sshcaching`
+
+ By default, git-annex caches ssh connections
+ (if built using a new enough ssh). To disable this, set to `false`.
+
+* `annex.alwayscommit`
+
+ By default, git-annex automatically commits data to the git-annex branch
+ after each command is run. To disable these commits,
+ set to `false`. Then data will only be committed when
+ running `git annex merge` (or by automatic merges) or `git annex sync`.
+
+* `annex.delayadd`
+
+ Makes the watch and assistant commands delay for the specified number of
+ seconds before adding a newly created file to the annex. Normally this
+ is not needed, because they already wait for all writers of the file
+ to close it. On Mac OSX, when not using direct mode this defaults to
+ 1 second, to work around a bad interaction with software there.
+
+* `annex.fscknudge`
+
+ When set to false, prevents the webapp from reminding you when using
+ repositories that lack consistency checks.
+
+* `annex.autoupgrade`
+
+ When set to ask (the default), the webapp will check for new versions
+ and prompt if they should be upgraded to. When set to true, automatically
+ upgrades without prompting (on some supported platforms). When set to
+ false, disables any upgrade checking.
+
+ Note that upgrade checking is only done when git-annex is installed
+ from one of the prebuilt images from its website. This does not
+ bypass eg, a Linux distribution's own upgrade handling code.
+
+ This setting also controls whether to restart the git-annex assistant
+ when the git-annex binary is detected to have changed. That is useful
+ no matter how you installed git-annex.
+
+* `annex.autocommit`
+
+ Set to false to prevent the git-annex assistant from automatically
+ committing changes to files in the repository.
+
+* `annex.debug`
+
+ Set to true to enable debug logging by default.
+
+* `annex.version`
+
+ Automatically maintained, and used to automate upgrades between versions.
+
+* `annex.direct`
+
+ Set to true when the repository is in direct mode. Should not be set
+ manually; use the "git annex direct" and "git annex indirect" commands
+ instead.
+
+* `annex.crippledfilesystem`
+
+ Set to true if the repository is on a crippled filesystem, such as FAT,
+ which does not support symbolic links, or hard links, or unix permissions.
+ This is automatically probed by "git annex init".
+
+* `remote.<name>.annex-cost`
+
+ When determining which repository to
+ transfer annexed files from or to, ones with lower costs are preferred.
+ The default cost is 100 for local repositories, and 200 for remote
+ repositories.
+
+* `remote.<name>.annex-cost-command`
+
+ If set, the command is run, and the number it outputs is used as the cost.
+ This allows varying the cost based on eg, the current network. The
+ cost-command can be any shell command line.
+
+* `remote.<name>.annex-start-command`
+
+ A command to run when git-annex begins to use the remote. This can
+ be used to, for example, mount the directory containing the remote.
+
+ The command may be run repeatedly when multiple git-annex processes
+ are running concurrently.
+
+* `remote.<name>.annex-stop-command`
+
+ A command to run when git-annex is done using the remote.
+
+ The command will only be run once *all* running git-annex processes
+ are finished using the remote.
+
+* `remote.<name>.annex-ignore`
+
+ If set to `true`, prevents git-annex
+ from storing file contents on this remote by default.
+ (You can still request it be used by the `--from` and `--to` options.)
+
+ This is, for example, useful if the remote is located somewhere
+ without git-annex-shell. (For example, if it's on GitHub).
+ Or, it could be used if the network connection between two
+ repositories is too slow to be used normally.
+
+ This does not prevent git-annex sync (or the git-annex assistant) from
+ syncing the git repository to the remote.
+
+* `remote.<name>.annex-sync`
+
+ If set to `false`, prevents git-annex sync (and the git-annex assistant)
+ from syncing with this remote.
+
+* `remote.<name>.annexUrl`
+
+ Can be used to specify a different url than the regular `remote.<name>.url`
+ for git-annex to use when talking with the remote. Similar to the `pushUrl`
+ used by git-push.
+
+* `remote.<name>.annex-uuid`
+
+ git-annex caches UUIDs of remote repositories here.
+
+* `remote.<name>.annex-trustlevel`
+
+ Configures a local trust level for the remote. This overrides the value
+ configured by the trust and untrust commands. The value can be any of
+ "trusted", "semitrusted" or "untrusted".
+
+* `remote.<name>.annex-ssh-options`
+
+ Options to use when using ssh to talk to this remote.
+
+* `remote.<name>.annex-rsync-options`
+
+ Options to use when using rsync
+ to or from this remote. For example, to force ipv6, and limit
+ the bandwidth to 100Kbyte/s, set it to `-6 --bwlimit 100`
+
+* `remote.<name>.annex-rsync-transport`
+
+ The remote shell to use to connect to the rsync remote. Possible
+ values are `ssh` (the default) and `rsh`, together with their
+ arguments, for instance `ssh -p 2222 -c blowfish`; Note that the
+ remote hostname should not appear there, see rsync(1) for details.
+ When the transport used is `ssh`, connections are automatically cached
+ unless `annex.sshcaching` is unset.
+
+* `remote.<name>.annex-bup-split-options`
+
+ Options to pass to bup split when storing content in this remote.
+ For example, to limit the bandwidth to 100Kbyte/s, set it to `--bwlimit 100k`
+ (There is no corresponding option for bup join.)
+
+* `remote.<name>.annex-gnupg-options`
+
+ Options to pass to GnuPG for symmetric encryption. For instance, to
+ use the AES cipher with a 256 bits key and disable compression, set it
+ to `--cipher-algo AES256 --compress-algo none`. (These options take
+ precedence over the default GnuPG configuration, which is otherwise
+ used.)
+
+* `annex.ssh-options`, `annex.rsync-options`, `annex.bup-split-options`,
+ `annex.gnupg-options`
+
+ Default ssh, rsync, wget/curl, bup, and GnuPG options to use if a
+ remote does not have specific options.
+
+* `annex.web-options`
+
+ Options to use when using wget or curl to download a file from the web.
+ (wget is always used in preference to curl if available.)
+ For example, to force ipv4 only, set it to "-4"
+
+* `annex.quvi-options`
+
+ Options to pass to quvi when using it to find the url to download for a
+ video.
+
+* `annex.http-headers`
+
+ HTTP headers to send when downloading from the web. Multiple lines of
+ this option can be set, one per header.
+
+* `annex.http-headers-command`
+
+ If set, the command is run and each line of its output is used as a HTTP
+ header. This overrides annex.http-headers.
+
+* `annex.web-download-command`
+
+ Use to specify a command to run to download a file from the web.
+ (The default is to use wget or curl.)
+
+ In the command line, %url is replaced with the url to download,
+ and %file is replaced with the file that it should be saved to.
+ Note that both these values will automatically be quoted, since
+ the command is run in a shell.
+
+* `remote.<name>.rsyncurl`
+
+ Used by rsync special remotes, this configures
+ the location of the rsync repository to use. Normally this is automatically
+ set up by `git annex initremote`, but you can change it if needed.
+
+* `remote.<name>.buprepo`
+
+ Used by bup special remotes, this configures
+ the location of the bup repository to use. Normally this is automatically
+ set up by `git annex initremote`, but you can change it if needed.
+
+* `remote.<name>.directory`
+
+ Used by directory special remotes, this configures
+ the location of the directory where annexed files are stored for this
+ remote. Normally this is automatically set up by `git annex initremote`,
+ but you can change it if needed.
+
+* `remote.<name>.s3`
+
+ Used to identify Amazon S3 special remotes.
+ Normally this is automatically set up by `git annex initremote`.
+
+* `remote.<name>.glacier`
+
+ Used to identify Amazon Glacier special remotes.
+ Normally this is automatically set up by `git annex initremote`.
+
+* `remote.<name>.webdav`
+
+ Used to identify webdav special remotes.
+ Normally this is automatically set up by `git annex initremote`.
+
+* `remote.<name>.annex-xmppaddress`
+
+ Used to identify the XMPP address of a Jabber buddy.
+ Normally this is set up by the git-annex assistant when pairing over XMPP.
+
+* `remote.<name>.gcrypt`
+
+ Used to identify gcrypt special remotes.
+ Normally this is automatically set up by `git annex initremote`.
+
+ It is set to "true" if this is a gcrypt remote.
+ If the gcrypt remote is accessible over ssh and has git-annex-shell
+ available to manage it, it's set to "shell"
+
+# CONFIGURATION VIA .gitattributes
+
+The key-value backend used when adding a new file to the annex can be
+configured on a per-file-type basis via `.gitattributes` files. In the file,
+the `annex.backend` attribute can be set to the name of the backend to
+use. For example, this here's how to use the WORM backend by default,
+but the SHA256E backend for ogg files:
+
+ * annex.backend=WORM
+ *.ogg annex.backend=SHA256E
+
+The numcopies setting can also be configured on a per-file-type basis via
+the `annex.numcopies` attribute in `.gitattributes` files. This overrides
+any value set using `annex.numcopies` in `.git/config`.
+For example, this makes two copies be needed for wav files:
+
+ *.wav annex.numcopies=2
+
+Note that setting numcopies to 0 is very unsafe.
+
+# FILES
+
+These files are used by git-annex:
+
+`.git/annex/objects/` in your git repository contains the annexed file
+contents that are currently available. Annexed files in your git
+repository symlink to that content.
+
+`.git/annex/` in your git repository contains other run-time information
+used by git-annex.
+
+`~/.config/git-annex/autostart` is a list of git repositories
+to start the git-annex assistant in.
+
+# SEE ALSO
+
+Most of git-annex's documentation is available on its web site,
+<http://git-annex.branchable.com/>
+
+If git-annex is installed from a package, a copy of its documentation
+should be included, in, for example, `/usr/share/doc/git-annex/`
+
+# AUTHOR
+
+Joey Hess <joey@kitenet.net>
+
+<http://git-annex.branchable.com/>
+
+Warning: Automatically converted into a man page by mdwn2man. Edit with care
diff --git a/doc/git-union-merge.mdwn b/doc/git-union-merge.mdwn
new file mode 100644
index 000000000..8e3c34f8f
--- /dev/null
+++ b/doc/git-union-merge.mdwn
@@ -0,0 +1,38 @@
+# NAME
+
+git-union-merge - Join branches together using a union merge
+
+# SYNOPSIS
+
+git union-merge ref ref newref
+
+# DESCRIPTION
+
+Does a union merge between two refs, storing the result in the
+specified newref.
+
+The union merge will always succeed, but assumes that files can be merged
+simply by concacenating together lines from all the oldrefs, in any order.
+So, this is useful only for branches containing log-type data.
+
+Note that this does not touch the checked out working copy. It operates
+entirely on git refs and branches.
+
+# EXAMPLE
+
+ git union-merge git-annex origin/git-annex refs/heads/git-annex
+
+Merges the current git-annex branch, and a version from origin,
+storing the result in the git-annex branch.
+
+# BUGS
+
+File modes are not currently merged.
+
+# AUTHOR
+
+Joey Hess <joey@kitenet.net>
+
+<http://git-annex.branchable.com/>
+
+Warning: Automatically converted into a man page by mdwn2man. Edit with care
diff --git a/doc/how_it_works.mdwn b/doc/how_it_works.mdwn
new file mode 100644
index 000000000..0acf20565
--- /dev/null
+++ b/doc/how_it_works.mdwn
@@ -0,0 +1,41 @@
+This page gives a high-level view of git-annex. For a detailed
+low-level view, see [[the_man_page|git-annex]] and [[internals]].
+
+You do not need to read this page to get started with using git-annex. The
+[[walkthrough]] provides step-by-step instructions.
+
+Still reading? Ok. Git's man page calls it "a stupid content
+tracker". With git-annex, git is instead "a stupid filename and metadata"
+tracker. The contents of large files are not stored in git, only the
+names of the files and some other metadata remain there.
+
+The contents of the files are kept by git-annex in a distributed key/value
+store consisting of every clone of a given git repository. That's a fancy
+way to say that git-annex stores the actual file content somewhere under
+`.git/annex/`. (See [[internals]] for details.)
+
+That was the values; what about the keys? Well, a key is calculated for a
+given file when it's first added into git-annex. Normally this uses a hash
+of its contents, but various [[backends]] can produce different sorts of
+keys. The file that gets checked into git is just a symlink to the key
+under `.git/annex/`. If the content of a file is modified, that produces
+a different key (and the symlink is changed).
+
+A file's content can be [[transferred|transferring_data]] from one
+repository to another by git-annex. Which repositories contain a given
+value is tracked by git-annex (see [[location_tracking]]). It stores this
+tracking information in a separate branch, named "git-annex". All you ever
+do with the "git-annex" branch is push/pull it around between repositories,
+to [[sync]] up git-annex's view of the world.
+
+That's really all there is to it. Oh, there are [[special_remotes]] that
+let values be stored other places than git repositories (anything from
+Amazon S3 to a USB key), and there's a pile of commands listed in
+[[the_man_page|git-annex]] to handle moving the values around and managing
+them. But if you grok the description above, you can see through all that.
+It's really just symlinks, keys, values, and a git-annex branch to store
+additional metadata.
+
+---
+
+Next: [[install]] or [[walkthrough]]
diff --git a/doc/how_it_works/comment_1_b3bdd6a06d5764db521ae54878131f5f._comment b/doc/how_it_works/comment_1_b3bdd6a06d5764db521ae54878131f5f._comment
new file mode 100644
index 000000000..60aeab732
--- /dev/null
+++ b/doc/how_it_works/comment_1_b3bdd6a06d5764db521ae54878131f5f._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnaH44G3QbxBAYyDwy0PbvL0ls60XoaR3Y"
+ nickname="Nigel"
+ subject="minor suggestion"
+ date="2013-08-10T14:31:31Z"
+ content="""
+The contents of large files are not stored in git, only the names of the files and some other metadata remain there.
+
+Would this read better to the newbie as:
+
+The contents of 'annexed' files are not stored in git, only the names of the files and some other metadata remain there.
+
+First time for me, the note about large files made me think that maybe annex operated on files above a certain size.
+"""]]
diff --git a/doc/ikiwiki/pagespec.mdwn b/doc/ikiwiki/pagespec.mdwn
new file mode 100644
index 000000000..0f298ad78
--- /dev/null
+++ b/doc/ikiwiki/pagespec.mdwn
@@ -0,0 +1,86 @@
+[[!meta robots="noindex, follow"]]
+To select a set of pages, such as pages that are locked, pages
+whose commit emails you want subscribe to, or pages to combine into a
+blog, the wiki uses a PageSpec. This is an expression that matches
+a set of pages.
+
+The simplest PageSpec is a simple list of pages. For example, this matches
+any of the three listed pages:
+
+ foo or bar or baz
+
+More often you will want to match any pages that have a particular thing in
+their name. You can do this using a glob pattern. "`*`" stands for any part
+of a page name, and "`?`" for any single letter of a page name. So this
+matches all pages about music, and any [[SubPage]]s of the SandBox, but does
+not match the SandBox itself:
+
+ *music* or SandBox/*
+
+You can also prefix an item with "`!`" to skip pages that match it. So to
+match all pages except for Discussion pages and the SandBox:
+
+ * and !SandBox and !*/Discussion
+
+Some more elaborate limits can be added to what matches using these functions:
+
+* "`glob(someglob)`" - matches pages and other files that match the given glob.
+ Just writing the glob by itself is actually a shorthand for this function.
+* "`page(glob)`" - like `glob()`, but only matches pages, not other files
+* "`link(page)`" - matches only pages that link to a given page (or glob)
+* "`tagged(tag)`" - matches pages that are tagged or link to the given tag (or
+ tags matched by a glob)
+* "`backlink(page)`" - matches only pages that a given page links to
+* "`creation_month(month)`" - matches only files created on the given month
+ number
+* "`creation_day(mday)`" - or day of the month
+* "`creation_year(year)`" - or year
+* "`created_after(page)`" - matches only files created after the given page
+ was created
+* "`created_before(page)`" - matches only files created before the given page
+ was created
+* "`internal(glob)`" - like `glob()`, but matches even internal-use
+ pages that globs do not usually match.
+* "`title(glob)`", "`author(glob)`", "`authorurl(glob)`",
+ "`license(glob)`", "`copyright(glob)`", "`guid(glob)`"
+ - match pages that have the given metadata, matching the specified glob.
+* "`user(username)`" - tests whether a modification is being made by a
+ user with the specified username. If openid is enabled, an openid can also
+ be put here. Glob patterns can be used in the username. For example,
+ to match all openid users, use `user(*://*)`
+* "`admin()`" - tests whether a modification is being made by one of the
+ wiki admins.
+* "`ip(address)`" - tests whether a modification is being made from the
+ specified IP address. Glob patterns can be used in the address. For
+ example, `ip(127.0.0.*)`
+* "`comment(glob)`" - matches comments to a page matching the glob.
+* "`comment_pending(glob)`" - matches unmoderated, pending comments.
+* "`postcomment(glob)`" - matches only when comments are being
+ posted to a page matching the specified glob
+
+For example, to match all pages in a blog that link to the page about music
+and were written in 2005:
+
+ blog/* and link(music) and creation_year(2005)
+
+Note the use of "and" in the above example, that means that only pages that
+match each of the three expressions match the whole. Use "and" when you
+want to combine expression like that; "or" when it's enough for a page to
+match one expression. Note that it doesn't make sense to say "index and
+SandBox", since no page can match both expressions.
+
+More complex expressions can also be created, by using parentheses for
+grouping. For example, to match pages in a blog that are tagged with either
+of two tags, use:
+
+ blog/* and (tagged(foo) or tagged(bar))
+
+Note that page names in PageSpecs are matched against the absolute
+filenames of the pages in the wiki, so a pagespec "foo" used on page
+"a/b" will not match a page named "a/foo" or "a/b/foo". To match
+relative to the directory of the page containing the pagespec, you can
+use "./". For example, "./foo" on page "a/b" matches page "a/foo".
+
+To indicate the name of the page the PageSpec is used in, you can
+use a single dot. For example, `link(.)` matches all the pages
+linking to the page containing the PageSpec.
diff --git a/doc/index.mdwn b/doc/index.mdwn
new file mode 100644
index 000000000..57bfe2408
--- /dev/null
+++ b/doc/index.mdwn
@@ -0,0 +1,45 @@
+[[!inline raw=yes pages="summary"]]
+
+[[!sidebar content="""
+[[!inline feeds=no template=bare pages=sidebar]]
+
+[[Feeds]]:
+
+<small>
+[[!inline pages="internal(feeds/*)" archive=yes show=8 feeds=no]]
+</small>
+"""]]
+
+<table>
+<tr>
+<td width="33%" valign="top">[[!inline feeds=no template=bare pages=links/key_concepts]]</td>
+<td width="33%" valign="top">[[!inline feeds=no template=bare pages=links/the_details]]</td>
+<td width="33%" valign="top">[[!inline feeds=no template=bare pages=links/other_stuff]]</td>
+</tr>
+</table>
+
+<table>
+<tr>
+<td width="50%" valign="top">[[!inline feeds=no template=bare pages=use_case/bob]]</td>
+<td width="50%" valign="top">[[!inline feeds=no template=bare pages=use_case/alice]]</td>
+</tr>
+</table>
+
+If that describes you, or if you're some from column A and some from column
+B, then git-annex may be the tool you've been looking for to expand from
+keeping all your small important files in git, to managing your large
+files with git.
+
+<table>
+<tr>
+<td width="50%" valign="top">[[!inline feeds=no template=bare pages=footer/column_a]]</td>
+<td widtd="50%" valign="top">[[!inline feeds=no template=bare pages=footer/column_b]]</td>
+</tr>
+</table>
+
+----
+
+git-annex is [[Free Software|license]]
+
+git-annex's wiki is powered by [Ikiwiki](http://ikiwiki.info/) and
+hosted by [Branchable](http://branchable.com/).
diff --git a/doc/install.mdwn b/doc/install.mdwn
new file mode 100644
index 000000000..ecbf11a15
--- /dev/null
+++ b/doc/install.mdwn
@@ -0,0 +1,31 @@
+## Pick your OS
+
+[[!table format=dsv header=yes data="""
+detailed instructions | quick install
+[[OSX]] | [download git-annex.app](http://downloads.kitenet.net/git-annex/OSX/current/)
+[[Android]] | [download git-annex.apk](http://downloads.kitenet.net/git-annex/android/current/) **beta**
+[[Linux|linux_standalone]] | [download prebuilt linux tarball](http://downloads.kitenet.net/git-annex/linux/current/)
+&nbsp;&nbsp;[[Debian]] | `apt-get install git-annex`
+&nbsp;&nbsp;[[Ubuntu]] | `apt-get install git-annex`
+&nbsp;&nbsp;[[Fedora]] | `yum install git-annex`
+&nbsp;&nbsp;[[FreeBSD]] | `pkg_add -r hs-git-annex`
+&nbsp;&nbsp;[[ArchLinux]] | `yaourt -Sy git-annex`
+&nbsp;&nbsp;[[NixOS]] | `nix-env -i git-annex`
+&nbsp;&nbsp;[[Gentoo]] | `emerge git-annex`
+&nbsp;&nbsp;[[ScientificLinux5]] |
+&nbsp;&nbsp;[[openSUSE]] |
+[[Windows]] | [download installer](http://downloads.kitenet.net/git-annex/windows/current/) **alpha**
+"""]]
+
+## Using cabal
+
+As a haskell package, git-annex can be installed from source pretty easily
+[[using cabal|cabal]].
+
+## Installation from scratch
+
+This is not recommended, but if you really want to, see [[fromscratch]].
+
+## See also
+
+[[autobuild overview|builds]]
diff --git a/doc/install/Android.mdwn b/doc/install/Android.mdwn
new file mode 100644
index 000000000..537f6d518
--- /dev/null
+++ b/doc/install/Android.mdwn
@@ -0,0 +1,37 @@
+Now git-annex can be used on Android!
+
+[[Documentation for using git-annex on Android|/android]]
+
+## Android app
+
+First, ensure your Android device is configured to allow installation
+of the app. Go to Setup -&gt; Security, and enable "Unknown Sources".
+
+Then download the git-annex.apk for your version of Android, and
+open it to install.
+
+* [Android 4.4 and 4.3 git-annex.apk](http://downloads.kitenet.net/git-annex/android/current/4.3/git-annex.apk)
+* [Android 4.0 to 4.2 git-annex.apk](http://downloads.kitenet.net/git-annex/android/current/4.0/git-annex.apk)
+
+## autobuilds
+
+A daily build is also available, thanks to Mesar Hameed and the University
+of Bath CS department.
+
+* [Android 4.4 and 4.3 git-annex.apk](http://downloads.kitenet.net/git-annex/autobuild/android/4.3/git-annex.apk)
+* [Android 4.0 to 4.2 git-annex.apk](http://downloads.kitenet.net/git-annex/autobuild/android/4.0/git-annex.apk)
+* [build logs](http://downloads.kitenet.net/git-annex/autobuild/android/)
+
+## building it yourself
+
+git-annex can be built from source for Android.
+
+1. Run `standalone/android/buildchroot` as root (requires debootstrap).
+ This builds a chroot with an `androidbuilder` user.
+ The rest of the build will run in this chroot as that user.
+2. Then run `standalone/android/install-haskell-packages`
+ Note that this will break from time to time as new versions of packages
+ are released, and the patches it applies have to be updated when
+ this happens.
+3. Finally, once the chroot is set up, you can build an Android binary
+ with `make android`, and `make androidapp` will build the complete APK.
diff --git a/doc/install/Android/comment_10_225f2c6fe255be93702cfbd4dc172f3b._comment b/doc/install/Android/comment_10_225f2c6fe255be93702cfbd4dc172f3b._comment
new file mode 100644
index 000000000..f6a71981e
--- /dev/null
+++ b/doc/install/Android/comment_10_225f2c6fe255be93702cfbd4dc172f3b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://id.clacke.se/"
+ nickname="clacke"
+ subject="+1 F-Droid"
+ date="2013-09-24T18:36:48Z"
+ content="""
+Availability in F-Droid would be really neat. I imagine the unusual build requirements would require some work though.
+"""]]
diff --git a/doc/install/Android/comment_11_4e970633d9073fcf4bc33f3fff2525b2._comment b/doc/install/Android/comment_11_4e970633d9073fcf4bc33f3fff2525b2._comment
new file mode 100644
index 000000000..f57fb8d79
--- /dev/null
+++ b/doc/install/Android/comment_11_4e970633d9073fcf4bc33f3fff2525b2._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmK0703vNSIQsP1mGf-4MAPnsBZiSc6yVo"
+ nickname="Emre"
+ subject="What am I missing?"
+ date="2013-10-15T21:54:07Z"
+ content="""
+I've setup repositories on both my linux PC & android mini pc and added jabber account on both. They are both at my home network. They detected each other fine. But when it comes to syncing files, there's a message which says \"Unable to download files from your other devices\" with a button for \"add a cloud repository\". I don't need to add a cloud repository since both computers are at the same network? Or am I missing something in the architecture of git-annex that even to sync two local computers in the same LAN, annex would still need an external repo? (and if so, why would that be?)
+I'm not really willing to add an external repository as I intend to add large files and I don't want that they are first uploaded using a slow connection & then re-downloaded.
+What am I missing?
+"""]]
diff --git a/doc/install/Android/comment_12_87da4f379a0276b662583e7e22061218._comment b/doc/install/Android/comment_12_87da4f379a0276b662583e7e22061218._comment
new file mode 100644
index 000000000..772fa1d6a
--- /dev/null
+++ b/doc/install/Android/comment_12_87da4f379a0276b662583e7e22061218._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="64.134.31.139"
+ subject="comment 12"
+ date="2013-10-16T16:05:45Z"
+ content="""
+To make computers on your network directly communicate, they must be connected together using the user interface. This is normally using the local pairing interface. But local pairing does not yet work on Android. The best you can do to instead on your Android device, add the Linux PC as a ssh server. This will let the Android device send/receive files directly with it over the local network.
+"""]]
diff --git a/doc/install/Android/comment_1_f9ced494a530e6ae3e76cfbaddb89f5d._comment b/doc/install/Android/comment_1_f9ced494a530e6ae3e76cfbaddb89f5d._comment
new file mode 100644
index 000000000..13f9c659f
--- /dev/null
+++ b/doc/install/Android/comment_1_f9ced494a530e6ae3e76cfbaddb89f5d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://josh.easyid.net/"
+ ip="208.100.171.144"
+ subject="Minimum version of Android?"
+ date="2013-06-18T22:05:02Z"
+ content="""
+Does this require 4.x?
+"""]]
diff --git a/doc/install/Android/comment_2_74cccae04ea23a8600069c7e658143aa._comment b/doc/install/Android/comment_2_74cccae04ea23a8600069c7e658143aa._comment
new file mode 100644
index 000000000..bf5978674
--- /dev/null
+++ b/doc/install/Android/comment_2_74cccae04ea23a8600069c7e658143aa._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.193"
+ subject="comment 2"
+ date="2013-06-25T17:58:57Z"
+ content="""
+I have not heard of anyone using older than 4.x with success. In particular, several people reported 2.3 doesn't work.
+"""]]
diff --git a/doc/install/Android/comment_3_82c7cb31d19d4e18ca5548da5ca19a79._comment b/doc/install/Android/comment_3_82c7cb31d19d4e18ca5548da5ca19a79._comment
new file mode 100644
index 000000000..c049bfcab
--- /dev/null
+++ b/doc/install/Android/comment_3_82c7cb31d19d4e18ca5548da5ca19a79._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmhfodZquCI_EEl-f3h7HkROTszlsQL6yA"
+ nickname="Joe"
+ subject="comment 3"
+ date="2013-07-04T15:06:36Z"
+ content="""
+Is it safe to upgrade by installing a daily build over an existing version? Will that overwrite any settings?
+"""]]
diff --git a/doc/install/Android/comment_4_cebaa8ee5bbed27d9b2d032ca7bdec6e._comment b/doc/install/Android/comment_4_cebaa8ee5bbed27d9b2d032ca7bdec6e._comment
new file mode 100644
index 000000000..2745044a4
--- /dev/null
+++ b/doc/install/Android/comment_4_cebaa8ee5bbed27d9b2d032ca7bdec6e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.193"
+ subject="comment 4"
+ date="2013-07-05T00:53:00Z"
+ content="""
+It is safe to re-install, all your data and settings are stored in /sdcard and will not be touched, even if you delete the app!
+"""]]
diff --git a/doc/install/Android/comment_8_34f7c42050fa48769a6bfae60d72e477._comment b/doc/install/Android/comment_8_34f7c42050fa48769a6bfae60d72e477._comment
new file mode 100644
index 000000000..efba6aeeb
--- /dev/null
+++ b/doc/install/Android/comment_8_34f7c42050fa48769a6bfae60d72e477._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmrb8I1K5jjNr7ZrLSvgmkeQGjYauPeGJU"
+ nickname="Martin"
+ subject="comment 8"
+ date="2013-08-18T16:44:02Z"
+ content="""
+Any chance that older versions of Android will be supported in the future?
+"""]]
diff --git a/doc/install/Android/comment_9_f3d289b78d6bdb3cc65689495a8439a5._comment b/doc/install/Android/comment_9_f3d289b78d6bdb3cc65689495a8439a5._comment
new file mode 100644
index 000000000..989304242
--- /dev/null
+++ b/doc/install/Android/comment_9_f3d289b78d6bdb3cc65689495a8439a5._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://openlifechallenge.wordpress.com/"
+ nickname="O"
+ subject="Add to F-Droid"
+ date="2013-09-08T09:56:38Z"
+ content="""
+Hi,
+Really enjoy this app for Android! Super simple to use but it would be great if you could fix a folder navigator option when choosing location for device repo, right now it does not work.
+
+Could you also add it to the F-Droid repository?
+"""]]
diff --git a/doc/install/ArchLinux.mdwn b/doc/install/ArchLinux.mdwn
new file mode 100644
index 000000000..68e8b81f1
--- /dev/null
+++ b/doc/install/ArchLinux.mdwn
@@ -0,0 +1,19 @@
+There is a non-official source package for git-annex in
+[AUR](https://aur.archlinux.org/packages.php?ID=44272).
+
+You can then build it yourself or use a wrapper for AUR
+such as yaourt:
+
+<pre>
+$ yaourt -Sy git-annex
+</pre>
+
+----
+
+I'm told the AUR has some dependency problems currently.
+If it doesn't work, you can just use cabal:
+
+<pre>
+pacman -S git rsync curl wget gpg openssh cabal-install
+cabal install git-annex --bindir=$HOME/bin
+</pre>
diff --git a/doc/install/ArchLinux/comment_1_da5919c986d2ae187bc2f73de9633978._comment b/doc/install/ArchLinux/comment_1_da5919c986d2ae187bc2f73de9633978._comment
new file mode 100644
index 000000000..d4db23292
--- /dev/null
+++ b/doc/install/ArchLinux/comment_1_da5919c986d2ae187bc2f73de9633978._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlwYMdU0H7P7MMlD0v_BcczO-ZkYHY4zuY"
+ nickname="Morris"
+ subject="Arch Linux"
+ date="2012-10-17T13:21:24Z"
+ content="""
+For Arch Linux there should be the AUR package [git-annex-bin](https://aur.archlinux.org/packages.php?ID=63503) mentioned, because it's easier to install (no haskell dependencies to be installed) and is based on the prebuild linux binary tarball.
+"""]]
diff --git a/doc/install/ArchLinux/comment_2_e5f923e6d81cfb3fba7a72f60baaf4ab._comment b/doc/install/ArchLinux/comment_2_e5f923e6d81cfb3fba7a72f60baaf4ab._comment
new file mode 100644
index 000000000..9b1f29623
--- /dev/null
+++ b/doc/install/ArchLinux/comment_2_e5f923e6d81cfb3fba7a72f60baaf4ab._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://olivier.mehani.name/"
+ nickname="olivier-mehani"
+ subject="Stalling when creating repository in assistant"
+ date="2013-09-13T05:09:49Z"
+ content="""
+I am experiencing a weird issue with any install I've had on this one (and only) ArchLinux machine: all of aur/git-annex 4.20130516-1, aur/git-annex-bin-4.20130909-1, aur/git-annex-standalone-4.20130909-1 and a Cabal install just stall when trying to create the initial Git annex repo in the webapp.
+
+When started, it offers me to create the annex in ~/annex/ or ~/Desktop/annex/, where ~ gets turned into /home/USER when I press “Make repository”, but nothing else happens. This is regardless of if that repo exists when I try to create it or start the webapp.
+
+If I start the webapp from an existing annex (now in ~/annex), it seems to work a bit better, but any other remote (SSH) server that I try to add fails. I just get a fleeting Bootstrap message box when I click “Check this server”, and nothing in the logs of eithr git annex webapp or the ssh logs of the server.
+
+Any idea? Where should I look for more debug information?
+.
+
+"""]]
diff --git a/doc/install/ArchLinux/comment_3_8e607cd883ec174571e9dfe3b25bfd05._comment b/doc/install/ArchLinux/comment_3_8e607cd883ec174571e9dfe3b25bfd05._comment
new file mode 100644
index 000000000..48a2888a2
--- /dev/null
+++ b/doc/install/ArchLinux/comment_3_8e607cd883ec174571e9dfe3b25bfd05._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.2.134"
+ subject="comment 3"
+ date="2013-09-13T15:35:59Z"
+ content="""
+Please post a [[bug report|bugs]] and start the webapp with the --debug option.
+"""]]
diff --git a/doc/install/ArchLinux/comment_4_a378391dd218859f381c479259dd8fe3._comment b/doc/install/ArchLinux/comment_4_a378391dd218859f381c479259dd8fe3._comment
new file mode 100644
index 000000000..9146da9c8
--- /dev/null
+++ b/doc/install/ArchLinux/comment_4_a378391dd218859f381c479259dd8fe3._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://olivier.mehani.name/"
+ nickname="olivier-mehani"
+ subject="comment 4"
+ date="2013-09-16T01:23:58Z"
+ content="""
+Done [0]. Not much debug output, unfortunately...
+
+[0] http://git-annex.branchable.com/bugs/Assistant_stalls_when_adding__47__creating_repo_on_ArchLinux/?updated
+"""]]
diff --git a/doc/install/Debian.mdwn b/doc/install/Debian.mdwn
new file mode 100644
index 000000000..c71d4d244
--- /dev/null
+++ b/doc/install/Debian.mdwn
@@ -0,0 +1,20 @@
+## Debian testing or unstable
+
+ sudo apt-get install git-annex
+
+## Debian 7.0 "wheezy":
+
+ sudo apt-get install git-annex
+
+Note: This version does not include support for the [[assistant]].
+A backport is available with the assistant and other new features.
+
+Follow the instructions to [enable backports](http://backports.debian.org/Instructions/).
+
+ sudo apt-get -t wheezy-backports install git-annex
+
+## Debian 6.0 "squeeze"
+
+Follow the instructions to [enable backports](http://backports.debian.org/Instructions/).
+
+ sudo apt-get -t squeeze-backports install git-annex
diff --git a/doc/install/Debian/comment_10_d5da996e106d2e4d8a822aa9bcc78596._comment b/doc/install/Debian/comment_10_d5da996e106d2e4d8a822aa9bcc78596._comment
new file mode 100644
index 000000000..a03038dc8
--- /dev/null
+++ b/doc/install/Debian/comment_10_d5da996e106d2e4d8a822aa9bcc78596._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 10"
+ date="2013-05-30T19:42:05Z"
+ content="""
+As of today, I have backported everything except for haskell-lens, haskell-dav, and haskell-network-protocol-xmpp. The last is the only real blocker (I can build a backport without webdav support..).
+
+The haskell-network-protocol-xmpp in stable is actually ok, except it needs to be rebuilt against the haskell-gnutls I uploaded today. This fixes a bad segfault bug. I don't know how to handle this situation in backports TBH, and so am stuck waiting for a newer version of haskell-network-protocol-xmpp to reach testing, to get around backport's requirements that the backport version be in testing.
+
+In other words, it'll happen in 2 to 5 weeks, probably..
+"""]]
diff --git a/doc/install/Debian/comment_11_84283676da247c401bc9b4bb12c2b453._comment b/doc/install/Debian/comment_11_84283676da247c401bc9b4bb12c2b453._comment
new file mode 100644
index 000000000..4507f36db
--- /dev/null
+++ b/doc/install/Debian/comment_11_84283676da247c401bc9b4bb12c2b453._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://hands.com/~phil/"
+ nickname="hands"
+ subject="comment 11"
+ date="2013-05-30T19:56:07Z"
+ content="""
+Fair enough -- that's more positive than I was expecting TBH -- Thanks Joey :-)
+"""]]
diff --git a/doc/install/Debian/comment_12_0aca83b055d0a9dd8589c50250a8bbea._comment b/doc/install/Debian/comment_12_0aca83b055d0a9dd8589c50250a8bbea._comment
new file mode 100644
index 000000000..419520c80
--- /dev/null
+++ b/doc/install/Debian/comment_12_0aca83b055d0a9dd8589c50250a8bbea._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmF3Klaj8Q0Czfh1F3jaLF6issqeAhmru4"
+ nickname="Keith"
+ subject="Wheezy Support"
+ date="2013-07-05T21:21:39Z"
+ content="""
+Joey,
+
+What's the status on the wheezy backport. I'm itching to try the assistant.
+
+thanks,
+Keith
+"""]]
diff --git a/doc/install/Debian/comment_13_167a091764e5e99ec0f35a65e95a22de._comment b/doc/install/Debian/comment_13_167a091764e5e99ec0f35a65e95a22de._comment
new file mode 100644
index 000000000..9f05fea93
--- /dev/null
+++ b/doc/install/Debian/comment_13_167a091764e5e99ec0f35a65e95a22de._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.254.222"
+ subject="comment 13"
+ date="2013-07-07T17:21:10Z"
+ content="""
+I remain stuck where I was stuck previously on the backport. In the meantime, use [[Linux_standalone]] :(
+"""]]
diff --git a/doc/install/Debian/comment_14_a34e23d9aa3027012ab1236aa4f7d5cb._comment b/doc/install/Debian/comment_14_a34e23d9aa3027012ab1236aa4f7d5cb._comment
new file mode 100644
index 000000000..86f1d6050
--- /dev/null
+++ b/doc/install/Debian/comment_14_a34e23d9aa3027012ab1236aa4f7d5cb._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="Miles"
+ ip="88.175.62.104"
+ subject="installed git-annex on debian but cannot find it"
+ date="2013-08-19T23:29:24Z"
+ content="""
+I am an absolute beginner when it comes to linux in debian in particular. I installed git-annex via the root terminal, but now I do not know where to find it. I searched for in the file system but could not locate it. Any help is appreciated.
+"""]]
diff --git a/doc/install/Debian/comment_15_20d8271ba3f6cfe3c8849c3d41607630._comment b/doc/install/Debian/comment_15_20d8271ba3f6cfe3c8849c3d41607630._comment
new file mode 100644
index 000000000..6f32c2b0b
--- /dev/null
+++ b/doc/install/Debian/comment_15_20d8271ba3f6cfe3c8849c3d41607630._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawk_GWOEjK4Sn4hUB6ofFlE3CNeC7tO56J8"
+ nickname="John"
+ subject="Re: installed git-annex on debian but cannot find it "
+ date="2013-08-20T00:50:28Z"
+ content="""
+@Miles - The command is git annex webapp to bring up the web interface.
+"""]]
diff --git a/doc/install/Debian/comment_1_029486088d098c2d4f1099f2f0e701a9._comment b/doc/install/Debian/comment_1_029486088d098c2d4f1099f2f0e701a9._comment
new file mode 100644
index 000000000..9a4ed7c31
--- /dev/null
+++ b/doc/install/Debian/comment_1_029486088d098c2d4f1099f2f0e701a9._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawla7u6eLKNYZ09Z7xwBffqLaXquMQC07fU"
+ nickname="Matthias"
+ subject="squeeze-backports update?"
+ date="2011-08-17T12:34:46Z"
+ content="""
+Is there going to be an update of git-annex in debian squeeze-backports to a version that supports repository version 3?
+Thx
+"""]]
diff --git a/doc/install/Debian/comment_2_648e3467e260cdf233acdb0b53313ce0._comment b/doc/install/Debian/comment_2_648e3467e260cdf233acdb0b53313ce0._comment
new file mode 100644
index 000000000..b8b3d68f3
--- /dev/null
+++ b/doc/install/Debian/comment_2_648e3467e260cdf233acdb0b53313ce0._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="Re: squeeze-backports update?"
+ date="2011-08-17T15:34:29Z"
+ content="""
+Yes, I uploaded it last night.
+"""]]
diff --git a/doc/install/Debian/comment_3_4d922e11249627634ecc35bba4044d9e._comment b/doc/install/Debian/comment_3_4d922e11249627634ecc35bba4044d9e._comment
new file mode 100644
index 000000000..98d65740b
--- /dev/null
+++ b/doc/install/Debian/comment_3_4d922e11249627634ecc35bba4044d9e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkstq9oH1vHXY_VP0nYO9Gg3eKnKerDGRI"
+ nickname="Hadi"
+ subject="ARM"
+ date="2012-07-31T15:13:06Z"
+ content="""
+is there any package for Debian armhf? I'd love to install git-annex on my raspberry pi
+"""]]
diff --git a/doc/install/Debian/comment_4_2a93ab18b05ccb90e7acc5885866fca2._comment b/doc/install/Debian/comment_4_2a93ab18b05ccb90e7acc5885866fca2._comment
new file mode 100644
index 000000000..8436f0354
--- /dev/null
+++ b/doc/install/Debian/comment_4_2a93ab18b05ccb90e7acc5885866fca2._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ subject="comment 4"
+ date="2012-07-31T15:41:43Z"
+ content="""
+Yes, git-annex is available for every Debian architecture which supports Haskell, including all arm ports:
+
+<pre>git-annex | 3.20120629 | wheezy | source, amd64, armel, armhf, i386, kfreebsd-amd64, kfreebsd-i386, mips, mipsel, powerpc, s390, s390x, sparc</pre>
+"""]]
diff --git a/doc/install/Debian/comment_5_38e6399083e10a6a274f35bddc15d4ac._comment b/doc/install/Debian/comment_5_38e6399083e10a6a274f35bddc15d4ac._comment
new file mode 100644
index 000000000..fae6c4df8
--- /dev/null
+++ b/doc/install/Debian/comment_5_38e6399083e10a6a274f35bddc15d4ac._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawk3eiQwrpDGJ3MJb9NWB84m4tzQ6XjVZnY"
+ nickname="Allard"
+ subject="wheezy support"
+ date="2012-11-23T20:47:58Z"
+ content="""
+Hey Joey,
+
+As a backer, I'd like to see a backport of git annex assistant to wheezy.
+
+It is currently impossible to get this assistant in wheezy without compiling it with cabal.
+
+It would be nice to see it in backports or something :)
+
+Best,
+
+Allard
+"""]]
diff --git a/doc/install/Debian/comment_6_2e7bbdbaabbfb9d89de22e913066e822._comment b/doc/install/Debian/comment_6_2e7bbdbaabbfb9d89de22e913066e822._comment
new file mode 100644
index 000000000..c4ce6b32a
--- /dev/null
+++ b/doc/install/Debian/comment_6_2e7bbdbaabbfb9d89de22e913066e822._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://svend.ciffer.net/"
+ ip="2001:4978:f:52e::2"
+ subject="comment 6"
+ date="2012-11-23T21:38:29Z"
+ content="""
+The git-annex packages in unstable install on testing (wheezy).
+"""]]
diff --git a/doc/install/Debian/comment_7_1bccc7bf7a4ef61a9b30024b9b22ba7d._comment b/doc/install/Debian/comment_7_1bccc7bf7a4ef61a9b30024b9b22ba7d._comment
new file mode 100644
index 000000000..6d8cae2f0
--- /dev/null
+++ b/doc/install/Debian/comment_7_1bccc7bf7a4ef61a9b30024b9b22ba7d._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://mey.vn/"
+ ip="46.65.14.106"
+ subject="libc6 dep version on amd64"
+ date="2013-05-28T15:28:47Z"
+ content="""
+hi Joey,
+
+i see from the release notes of the 4.20130521 release that the Debian package should now be built with libc6 2.13, which appears to be the case except for the amd64 arch (hence the amd64 package won't install as is on Wheezy on amd64) - is this a build glitch or is 2.14 needed on amd64 (i imagine as a dependency of one of git-annex's deps on that arch)?
+
+thanks!
+"""]]
diff --git a/doc/install/Debian/comment_8_5b5a3b0e8abe8831a6a15a4e258d14fd._comment b/doc/install/Debian/comment_8_5b5a3b0e8abe8831a6a15a4e258d14fd._comment
new file mode 100644
index 000000000..253df3d07
--- /dev/null
+++ b/doc/install/Debian/comment_8_5b5a3b0e8abe8831a6a15a4e258d14fd._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 8"
+ date="2013-05-29T16:23:10Z"
+ content="""
+@mey.vn, Debian packages of git-annex, as uploaded to the Debian repositories, are built with whatever libc version the Debian autobuilder is running. You cannot, in general, install packages from Debian unstable into stable without upgrading your libc6.
+
+The release notes were not talking about the Debian packages, but about the [[Linux_standalone]] tarballs. Those are built with libc 2.13.
+"""]]
diff --git a/doc/install/Debian/comment_9_97eaed998ffd1ed79585075ed5cff06e._comment b/doc/install/Debian/comment_9_97eaed998ffd1ed79585075ed5cff06e._comment
new file mode 100644
index 000000000..d58f294b6
--- /dev/null
+++ b/doc/install/Debian/comment_9_97eaed998ffd1ed79585075ed5cff06e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://hands.com/~phil/"
+ nickname="hands"
+ subject="any chance of a wheezy-backports upload?"
+ date="2013-05-30T18:43:52Z"
+ content="""
+I note that the instructions at the top of the page suggest that one can install the unstable version into wheezy, but as mentioned by [mey.vn](#comment-f9811cbd46471d4159d09d814ac9cf15) this is not the case with 4.20130521 (on amd64 at least) because of the libc6 version dependency. That being the case, it would be really nice to see this in wheezy-backports as well, or would that require backporting a huge pile of haskell as well? (in which case I can see why you're not keen).
+"""]]
diff --git a/doc/install/Fedora.mdwn b/doc/install/Fedora.mdwn
new file mode 100644
index 000000000..9a6006e97
--- /dev/null
+++ b/doc/install/Fedora.mdwn
@@ -0,0 +1,39 @@
+git-annex is available in recent versions of Fedora. Although it is
+not currently a very recent version, it should work ok.
+[status](http://koji.fedoraproject.org/koji/packageinfo?packageID=14145)
+
+Should be as simple as: `yum install git-annex`
+
+----
+
+To install the latest version of git-annex on Fedora 18 and later, you can use `cabal`:
+
+<pre>
+# Install dependencies
+sudo yum install libxml2-devel gnutls-devel libgsasl-devel ghc cabal-install happy alex libidn-devel
+# Update the cabal list
+cabal update
+# Install c2hs, required by dependencies of git-annex, but not automatically installed
+cabal install --bindir=$HOME/bin c2hs
+# Install git-annex
+cabal install --bindir=$HOME/bin git-annex
+</pre>
+
+----
+
+Older version? Here's an installation recipe for Fedora 14 through 15.
+
+<pre>
+sudo yum install ghc cabal-install
+git clone git://git-annex.branchable.com/ git-annex
+cd git-annex
+git checkout ghc7.0
+cabal update
+cabal install --only-dependencies
+cabal configure
+cabal build
+cabal install --bindir=$HOME/bin
+</pre>
+
+Note: You can't just use `cabal install git-annex`, because Fedora does
+not yet ship ghc 7.4.
diff --git a/doc/install/Fedora/comment_1_c4db84e672ad4b45b522db735706b00f._comment b/doc/install/Fedora/comment_1_c4db84e672ad4b45b522db735706b00f._comment
new file mode 100644
index 000000000..bdc8c9e06
--- /dev/null
+++ b/doc/install/Fedora/comment_1_c4db84e672ad4b45b522db735706b00f._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://mebus.myopenid.com/"
+ ip="2a01:198:3eb:0:4a5b:39ff:fea4:55b3"
+ subject="RPM of version 4.2"
+ date="2013-07-30T01:09:54Z"
+ content="""
+Hi!
+
+Isn't there an rpm package of version 4.2 available for Fedora 17 or 18?
+
+Thanks!
+
+Mebus
+
+
+"""]]
diff --git a/doc/install/Fedora/comment_2_f98c488c09bef86e2b0414589ce9e141._comment b/doc/install/Fedora/comment_2_f98c488c09bef86e2b0414589ce9e141._comment
new file mode 100644
index 000000000..0a1de29b5
--- /dev/null
+++ b/doc/install/Fedora/comment_2_f98c488c09bef86e2b0414589ce9e141._comment
@@ -0,0 +1,25 @@
+[[!comment format=mdwn
+ username="http://mebus.pip.verisignlabs.com/"
+ nickname="Bussard"
+ subject="comment 2"
+ date="2013-07-30T20:41:07Z"
+ content="""
+When I try to build in from source on Fedora 17, I get this error:
+
+[ 77 of 163] Compiling Utility.DiskFree ( Utility/DiskFree.hs, dist/build/git-annex/git-annex-tmp/Utility/DiskFree.o )
+[ 78 of 163] Compiling Utility.Url ( Utility/Url.hs, dist/build/git-annex/git-annex-tmp/Utility/Url.o )
+
+Utility/Url.hs:111:88:
+ Couldn't match expected type `Maybe URI' with actual type `URI'
+ In the second argument of `fromMaybe', namely
+ `(newURI `relativeTo` u)'
+ In the expression: fromMaybe newURI (newURI `relativeTo` u)
+ In an equation for `newURI_abs':
+ newURI_abs = fromMaybe newURI (newURI `relativeTo` u)
+
+Any help?
+
+Mebus
+
+
+"""]]
diff --git a/doc/install/Fedora/comment_3_d872acf8865fe7c99a9b712db5b38ea4._comment b/doc/install/Fedora/comment_3_d872acf8865fe7c99a9b712db5b38ea4._comment
new file mode 100644
index 000000000..4a8624961
--- /dev/null
+++ b/doc/install/Fedora/comment_3_d872acf8865fe7c99a9b712db5b38ea4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.21"
+ subject="comment 3"
+ date="2013-07-30T21:25:32Z"
+ content="""
+Edit Utility/Url.hs and play around with the version in the `MIN_VERSION_network` define. It seems to me that your system needs to build with the #else branch of the #ifdef, despite having a version of the haskell network package older than 2.4.0. It's possible that the haskell network package has been modified by Fedora.
+"""]]
diff --git a/doc/install/Fedora/comment_4_93b3402e4c51e1a5c96f907bb528164b._comment b/doc/install/Fedora/comment_4_93b3402e4c51e1a5c96f907bb528164b._comment
new file mode 100644
index 000000000..afdbf1dc1
--- /dev/null
+++ b/doc/install/Fedora/comment_4_93b3402e4c51e1a5c96f907bb528164b._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkJafmCf-sg9_OM0pynFYM3AO4WCgJiaMI"
+ nickname="Michele"
+ subject="installing on fc19"
+ date="2013-10-18T21:05:56Z"
+ content="""
+i share my experience in installing from source on fc19, I must admit these are useful only for haskell novices:
+should cabal complain about missing libffi.so.5 (as it happened to me), do
+
+ yum install compat-libffi
+
+and you'll get the missing library (the shipping version with fc19 is libffi.so.6)
+also: in order for the git annex to be picked up globally or better to end up in the default path i had to:
+
+ cabal install --global
+"""]]
diff --git a/doc/install/Fedora/comment_5_0427e0503764b29e57abf9e97155136b._comment b/doc/install/Fedora/comment_5_0427e0503764b29e57abf9e97155136b._comment
new file mode 100644
index 000000000..df518ea11
--- /dev/null
+++ b/doc/install/Fedora/comment_5_0427e0503764b29e57abf9e97155136b._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://mebus.myopenid.com/"
+ ip="2a01:198:3eb:0:4a5b:39ff:fea4:55b3"
+ subject="Error on Fedora 19"
+ date="2013-10-19T14:57:12Z"
+ content="""
+On Fedora 19, I am getting this error:
+
+http://pastebin.com/raw.php?i=c9SNjbXV
+
+Mebus
+
+
+
+"""]]
diff --git a/doc/install/Fedora/comment_6_1b1b38a79251fe2e8c1e4debbe3bc3c5._comment b/doc/install/Fedora/comment_6_1b1b38a79251fe2e8c1e4debbe3bc3c5._comment
new file mode 100644
index 000000000..ffb6f0605
--- /dev/null
+++ b/doc/install/Fedora/comment_6_1b1b38a79251fe2e8c1e4debbe3bc3c5._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://mebus.myopenid.com/"
+ ip="2a01:198:3eb:0:4a5b:39ff:fea4:55b3"
+ subject="comment 6"
+ date="2013-10-19T15:09:34Z"
+ content="""
+Worked! I forgot to install c2hs.
+
+Mebus
+
+
+"""]]
diff --git a/doc/install/FreeBSD.mdwn b/doc/install/FreeBSD.mdwn
new file mode 100644
index 000000000..72b402c38
--- /dev/null
+++ b/doc/install/FreeBSD.mdwn
@@ -0,0 +1,2 @@
+git-annex is in FreeBSD ports in
+[devel/git-annex](http://www.freshports.org/devel/hs-git-annex/)
diff --git a/doc/install/Gentoo.mdwn b/doc/install/Gentoo.mdwn
new file mode 100644
index 000000000..feeaad739
--- /dev/null
+++ b/doc/install/Gentoo.mdwn
@@ -0,0 +1,3 @@
+Gentoo users can: `emerge git-annex`
+
+A possibly more up-to-date version is in the haskell portage overlay.
diff --git a/doc/install/Linux_standalone.mdwn b/doc/install/Linux_standalone.mdwn
new file mode 100644
index 000000000..e8df8adc0
--- /dev/null
+++ b/doc/install/Linux_standalone.mdwn
@@ -0,0 +1,34 @@
+If your Linux distribution does not have git-annex packaged up for you,
+you can either build it [[fromscratch]], or you can use a handy
+prebuilt tarball of the most recent release.
+
+This tarball should work on most Linux systems. It does not depend
+on anything except for glibc.
+
+[download tarball](https://downloads.kitenet.net/git-annex/linux/current/)
+
+To use, just unpack the tarball, `cd git-annex.linux` and run `./runshell`
+-- this sets up an environment where you can use `git annex`, as well
+as everything else included in the bundle.
+
+Alternatively, you can unpack the tarball, and add the directory to your
+`PATH`. This lets you use `git annex`, without overriding your system's
+own versions of git, etc.
+
+Warning: This is a last resort. Most Linux users should instead
+[[install]] git-annex from their distribution of choice.
+
+## autobuilds
+
+A daily build is also available, thanks to Mesar Hameed and the University
+of Bath CS department.
+
+* i386: [download tarball](https://downloads.kitenet.net/git-annex/autobuild/i386/git-annex-standalone-i386.tar.gz) ([build logs](https://downloads.kitenet.net/git-annex/autobuild/i386/))
+* amd64: [download tarball](https://downloads.kitenet.net/git-annex/autobuild/amd64/git-annex-standalone-amd64.tar.gz) ([build logs](https://downloads.kitenet.net/git-annex/autobuild/amd64/))
+
+## gitannex-install
+
+Eskild Hustvedt has contributed a
+[gitannex-install](https://github.com/zerodogg/scriptbucket/blob/master/gitannex-install)
+script to manage keeping up to date with new releases using the standalone
+build.
diff --git a/doc/install/NixOS.mdwn b/doc/install/NixOS.mdwn
new file mode 100644
index 000000000..115f9fa53
--- /dev/null
+++ b/doc/install/NixOS.mdwn
@@ -0,0 +1,6 @@
+Users of the [Nix package manager](http://nixos.org/) can install it by running:
+
+ nix-env -i git-annex
+
+The build status of the package within Nix can be seen on the [Hydra Build
+Farm](http://hydra.nixos.org/job/nixpkgs/trunk/gitAndTools.gitAnnex).
diff --git a/doc/install/OSX.mdwn b/doc/install/OSX.mdwn
new file mode 100644
index 000000000..e3b15069d
--- /dev/null
+++ b/doc/install/OSX.mdwn
@@ -0,0 +1,71 @@
+## git-annex.app
+
+[[!img /assistant/osx-app.png align=right link=/assistant]]
+For easy installation, use the prebuilt app bundle.
+
+* 10.9 Mavericks: [git-annex.dmg](https://downloads.kitenet.net/git-annex/OSX/current/10.9_Mavericks/git-annex.dmg)
+* 10.8.2 Mountain Lion: [git-annex.dmg.bz2](https://downloads.kitenet.net/git-annex/OSX/current/10.8.2_Mountain_Lion/git-annex.dmg.bz2) **warning: not being updated any longer**
+* 10.7.5 Lion: [git-annex.dmg](https://downloads.kitenet.net/git-annex/OSX/current/10.7.5_Lion/git-annex.dmg)
+
+To run the [[git-annex_assistant|/assistant]], just
+install the app, look for the icon, and start it up.
+
+To use git-annex at the command line, you can add
+`git-annex.app/Contents/MacOS` to your `PATH`
+
+Alternatively, from the command line you can run
+`git-annex.app/Contents/MacOS/runshell`, which makes your shell use all the
+programs bundled inside the app, including not just git-annex, but git, and
+several more. Handy if you don't otherwise have git installed.
+
+## autobuilds
+
+[Jimmy Tang](http://www.sgenomics.org/~jtang/) autobuilds
+the app for OSX Lion.
+
+* [autobuild of git-annex.dmg](http://www.sgenomics.org/~jtang/gitbuilder-git-annex-x00-x86_64-apple-darwin10.8.0-binary/ref/master/git-annex.dmg.bz2) ([build logs](http://www.sgenomics.org/~jtang/gitbuilder-git-annex-x00-x86_64-apple-darwin10.8.0-binary/))
+ * [past builds](http://www.sgenomics.org/~jtang/gitbuilder-git-annex-x00-x86_64-apple-darwin10.8.0-binary/sha1/) -- directories are named from the commitid's
+
+[[Joey]] autobuilds the app for Mavericks.
+
+* [autobuild of git-annex.dmg](https://downloads.kitenet.net/git-annex/autobuild/x86_64-apple-mavericks/git-annex.dmg) ([build logs](https://downloads.kitenet.net/git-annex/autobuild/x86_64-apple-mavericks/))
+
+## using Brew
+
+<pre>
+brew update
+brew install haskell-platform git ossp-uuid md5sha1sum coreutils libgsasl gnutls libidn libgsasl pkg-config libxml2
+brew link libxml2 --force
+cabal update
+mkdir $HOME/bin
+PATH=$HOME/bin:$PATH
+PATH=$HOME/.cabal/bin:$PATH
+cabal install c2hs --bindir=$HOME/bin
+cabal install gnuidn
+cabal install git-annex --bindir=$HOME/bin
+</pre>
+
+## using MacPorts
+
+Install the Haskell Platform from [[http://hackage.haskell.org/platform/mac.html]].
+The version provided by Macports is too old to work with current versions of git-annex.
+Then execute
+
+<pre>
+sudo port install git-core ossp-uuid md5sha1sum coreutils gnutls libxml2 libgsasl pkgconfig
+sudo cabal update
+PATH=$HOME/bin:$PATH
+cabal install c2hs git-annex --bindir=$HOME/bin
+</pre>
+
+## PATH setup
+
+Do not forget to add to your PATH variable your ~/bin folder. In your .bashrc, for example:
+<pre>
+PATH=$HOME/bin:$PATH
+</pre>
+
+See also:
+
+* [[forum/OSX__39__s_haskell-platform_statically_links_things]]
+* [[forum/OSX__39__s_default_sshd_behaviour_has_limited_paths_set]]
diff --git a/doc/install/OSX/comment_10_cd2120552ef894a37933b328136fa4cc._comment b/doc/install/OSX/comment_10_cd2120552ef894a37933b328136fa4cc._comment
new file mode 100644
index 000000000..c2b43b2dd
--- /dev/null
+++ b/doc/install/OSX/comment_10_cd2120552ef894a37933b328136fa4cc._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnaYy6kTuKAHmsa4BtGls2oqa42Jo2w2v0"
+ nickname="Pere"
+ subject="Segmentation Fault"
+ date="2013-01-19T16:10:08Z"
+ content="""
+I guess my adventure ends here. :'(
+"""]]
diff --git a/doc/install/OSX/comment_11_740fa80e2e54e6fb570f820ff1f56440._comment b/doc/install/OSX/comment_11_740fa80e2e54e6fb570f820ff1f56440._comment
new file mode 100644
index 000000000..d0c74d609
--- /dev/null
+++ b/doc/install/OSX/comment_11_740fa80e2e54e6fb570f820ff1f56440._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmyFvkaewo432ELwtCoecUGou4v3jCP0Pc"
+ nickname="Eric"
+ subject="Updating to latest build"
+ date="2013-01-25T06:05:35Z"
+ content="""
+What is the appropriate way to update to the latest build of git-annex using cabal?
+"""]]
diff --git a/doc/install/OSX/comment_12_a84028080578a8b60115b6c4ef823627._comment b/doc/install/OSX/comment_12_a84028080578a8b60115b6c4ef823627._comment
new file mode 100644
index 000000000..cc57cbdfb
--- /dev/null
+++ b/doc/install/OSX/comment_12_a84028080578a8b60115b6c4ef823627._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnaYy6kTuKAHmsa4BtGls2oqa42Jo2w2v0"
+ nickname="Pere"
+ subject="git annex on Snow Leopard"
+ date="2013-01-25T14:36:52Z"
+ content="""
+Is there any way I can try to solve or by-pass the Segmentation Fault I commeted before?
+"""]]
diff --git a/doc/install/OSX/comment_13_d6f1db401858ffea23c123db49f5b296._comment b/doc/install/OSX/comment_13_d6f1db401858ffea23c123db49f5b296._comment
new file mode 100644
index 000000000..875db34f1
--- /dev/null
+++ b/doc/install/OSX/comment_13_d6f1db401858ffea23c123db49f5b296._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.3.125"
+ subject="comment 13"
+ date="2013-02-05T19:46:29Z"
+ content="""
+@eric `cabal update && cabal upgrade git-annex`
+"""]]
diff --git a/doc/install/OSX/comment_14_035f856923276b0edad879e196e94097._comment b/doc/install/OSX/comment_14_035f856923276b0edad879e196e94097._comment
new file mode 100644
index 000000000..1072dbc39
--- /dev/null
+++ b/doc/install/OSX/comment_14_035f856923276b0edad879e196e94097._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmCmNS-oUgYfNg85-LPuxzTZJUp0sIgprM"
+ nickname="Jonas"
+ subject="more homebrew"
+ date="2013-02-16T19:46:47Z"
+ content="""
+i had macports installed. then i installed brew, instaled haskell via brew. i needed to set
+ PATH=$HOME/bin:/usr/local/bin:$PATH
+"""]]
diff --git a/doc/install/OSX/comment_15_336e0acb00e84943715e69917643a69e._comment b/doc/install/OSX/comment_15_336e0acb00e84943715e69917643a69e._comment
new file mode 100644
index 000000000..05f5654bc
--- /dev/null
+++ b/doc/install/OSX/comment_15_336e0acb00e84943715e69917643a69e._comment
@@ -0,0 +1,35 @@
+[[!comment format=mdwn
+ username="https://launchpad.net/~wincus"
+ nickname="Juan Moyano"
+ subject="git annex on Snow Leopard"
+ date="2013-03-26T16:02:54Z"
+ content="""
+I'm having the same issue as @Pere, with a newer version of DAV :(
+
+cabal: Error: some packages failed to install:
+DAV-0.3.1 failed during the building phase. The exception was:
+ExitFailure 11
+git-annex-4.20130323 depends on shakespeare-css-1.0.3 which failed to install.
+persistent-1.1.5.1 failed during the building phase. The exception was:
+ExitFailure 11
+persistent-template-1.1.3.1 depends on persistent-1.1.5.1 which failed to
+install.
+shakespeare-css-1.0.3 failed during the building phase. The exception was:
+ExitFailure 11
+yesod-1.1.9.2 depends on shakespeare-css-1.0.3 which failed to install.
+yesod-auth-1.1.5.3 depends on shakespeare-css-1.0.3 which failed to install.
+yesod-core-1.1.8.2 depends on shakespeare-css-1.0.3 which failed to install.
+yesod-default-1.1.3.2 depends on shakespeare-css-1.0.3 which failed to
+install.
+yesod-form-1.2.1.3 depends on shakespeare-css-1.0.3 which failed to install.
+yesod-json-1.1.2.2 depends on shakespeare-css-1.0.3 which failed to install.
+yesod-persistent-1.1.0.1 depends on shakespeare-css-1.0.3 which failed to
+install.
+yesod-static-1.1.2.2 depends on shakespeare-css-1.0.3 which failed to install.
+
+
+
+*Any ideas?*
+
+
+"""]]
diff --git a/doc/install/OSX/comment_16_1befafa862b7d07b1f6e57c0182497cf._comment b/doc/install/OSX/comment_16_1befafa862b7d07b1f6e57c0182497cf._comment
new file mode 100644
index 000000000..0098e745d
--- /dev/null
+++ b/doc/install/OSX/comment_16_1befafa862b7d07b1f6e57c0182497cf._comment
@@ -0,0 +1,36 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkurjhi0CRJvgm7QNaZDWS9hitBtavqIpc"
+ nickname="Bret"
+ subject="Snow Leopard Issues"
+ date="2013-04-14T20:17:17Z"
+ content="""
+I was able to build snow leopard completely for the first time over last night (it took a very long time to build all the tools and dependancies). Woohoo!
+
+The way I was able to fully build on a 32-bit 10.6 machine was this
+
+1. Delete ~/.ghc and ~/.cabal. They were full of random things and were causing problems.
+2. `brew uninstall ghc and haskell-platform`
+3. `brew update`
+4. `brew install git ossp-uuid md5sha1sum coreutils libgsasl gnutls libidn libgsasl pkg-config libxml2`
+5. `brew upgrade git ossp-uuid md5sha1sum coreutils libgsasl gnutls libidn libgsasl pkg-config libxml2` (Some of these were already installed/up to date.
+6. `brew link libxml2`
+7. `brew install haskell-platform` (This takes a long, long time).
+8. `cabal update` (assuming you have added `~/.cabal/bin` to your path
+9. `cabal install cablal-install`
+10. `cabal install c2hs`
+11. `cabal install git-annex`
+
+
+It also appears to be running fairly smoothly than it had in the past on a 32-bit SL system. Thats also neat.
+
+The problem is that it seems to not really work as git annex though, probably due to the error relating you get when you start up the webapp:
+Running
+`git annex webapp`
+The browser starts up, and I get 3 of these errors:
+`Watcher crashed: Need at least OSX 10.7.0 for file-level FSEvents`
+
+Pairing with a local computer appears to work to systems running 10.7, but when you complete the process, they never show up in the repository list.
+
+
+Also on a side note, when running `git annex webapp` it triggers the opening of an html file in whatever the default html file handler is. I edit a lot of html, so for me that is usually a text editor. I had to change the file handler to open html files with my web browser for the `git annex webapp` to actually work. Is there a way to change that so that `git annex webapp` uses the default web browser for the system rather than the default html file handler?
+"""]]
diff --git a/doc/install/OSX/comment_17_19c08b2c6c2c5cd88bf96d2bcbbd9055._comment b/doc/install/OSX/comment_17_19c08b2c6c2c5cd88bf96d2bcbbd9055._comment
new file mode 100644
index 000000000..8955ab20b
--- /dev/null
+++ b/doc/install/OSX/comment_17_19c08b2c6c2c5cd88bf96d2bcbbd9055._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 17"
+ date="2013-04-16T20:31:10Z"
+ content="""
+@Bret, the assistant relies on FSEvents pretty heavily. It seems to me your best bet is to upgrade OSX to a version that supports FSEvents.
+
+You can certainly use the rest of git-annex on Snow Leopard without FSEvents.
+"""]]
diff --git a/doc/install/OSX/comment_18_537fad5d8854e765499d47602d1ab398._comment b/doc/install/OSX/comment_18_537fad5d8854e765499d47602d1ab398._comment
new file mode 100644
index 000000000..9d8d8f755
--- /dev/null
+++ b/doc/install/OSX/comment_18_537fad5d8854e765499d47602d1ab398._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkurjhi0CRJvgm7QNaZDWS9hitBtavqIpc"
+ nickname="Bret"
+ subject="Can't update"
+ date="2013-04-18T00:58:19Z"
+ content="""
+The laptop is one of the first macbook pro's with a 32 bit chip, which apple dropped support for in 10.7, so the furthest it can update to is 10.6.x. :(
+"""]]
diff --git a/doc/install/OSX/comment_19_18d4377f4ded5604d395d73783ba82c9._comment b/doc/install/OSX/comment_19_18d4377f4ded5604d395d73783ba82c9._comment
new file mode 100644
index 000000000..f244951e8
--- /dev/null
+++ b/doc/install/OSX/comment_19_18d4377f4ded5604d395d73783ba82c9._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="99.54.57.201"
+ subject="comment 19"
+ date="2013-04-18T02:05:34Z"
+ content="""
+sounds like a prime candidate for a nice lightweight linux distro ;)
+"""]]
diff --git a/doc/install/OSX/comment_20_3e6a3c00444badf2cf7a9ee3d54af11e._comment b/doc/install/OSX/comment_20_3e6a3c00444badf2cf7a9ee3d54af11e._comment
new file mode 100644
index 000000000..ef273bf7b
--- /dev/null
+++ b/doc/install/OSX/comment_20_3e6a3c00444badf2cf7a9ee3d54af11e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnEgT3Gxm4AAK4zu3ft5-PsUmY6dr1F-gE"
+ nickname="David"
+ subject="OSX app bundle"
+ date="2013-06-05T17:35:49Z"
+ content="""
+I'm using the annex assistant from the annex bundle for the convenience, but sometimes I use git-annex directly from the command line. I have /Applications/git-annex.app/Contents/MacOS/ in my path, but is there any way you could build the app bundle with the manpage in there so I could add it to my MANPATH?
+"""]]
diff --git a/doc/install/OSX/comment_21_987f1302f56107c926b6daf83e124654._comment b/doc/install/OSX/comment_21_987f1302f56107c926b6daf83e124654._comment
new file mode 100644
index 000000000..e7d42b534
--- /dev/null
+++ b/doc/install/OSX/comment_21_987f1302f56107c926b6daf83e124654._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmJdzisfT6DhorwRz0kKJ_9-zQbccCopu4"
+ nickname="Alejandro"
+ subject="Macports _iconv"
+ date="2013-07-18T14:23:02Z"
+ content="""
+If you get an error like `undefined symbol _iconv for x86_64`, you're most likely using libiconv installed by macports. You can fix this by running
+
+ cabal install c2hs git-annex --bindir=$HOME/bin --extra-lib-dirs=/usr/lib
+
+"""]]
diff --git a/doc/install/OSX/comment_22_6b5f44a98f9d37a1c6ecfe19a60fe6c5._comment b/doc/install/OSX/comment_22_6b5f44a98f9d37a1c6ecfe19a60fe6c5._comment
new file mode 100644
index 000000000..7dfa48132
--- /dev/null
+++ b/doc/install/OSX/comment_22_6b5f44a98f9d37a1c6ecfe19a60fe6c5._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmRFKwny4rArBaz-36xTcsJYqKIgdDaw5Q"
+ nickname="Andrew"
+ subject="comment 22"
+ date="2013-07-25T02:19:53Z"
+ content="""
+Rather than specifying --bindir on the command line for cabal, I edited my ~/.cabal/config to add this line:
+
+ symlink-bindir: /usr/local/bin
+
+This installs the binaries to ~/.cabal/bin but symlinks them into /usr/local/bin alongside the links that homebrew installs. Additionally, I symlinked /usr/local/bin/git-annex-shell to /usr/local/bin/git-annex which made things work great from remote hosts via ssh.
+"""]]
diff --git a/doc/install/OSX/comment_23_3d82a270dd4b0159f4aab5675166e1e3._comment b/doc/install/OSX/comment_23_3d82a270dd4b0159f4aab5675166e1e3._comment
new file mode 100644
index 000000000..08792aa21
--- /dev/null
+++ b/doc/install/OSX/comment_23_3d82a270dd4b0159f4aab5675166e1e3._comment
@@ -0,0 +1,30 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmL8pteP2jbYJUn1M3CbeLDvz2SWAA1wtg"
+ nickname="Kristian"
+ subject="Build failure using Haskel Platform"
+ date="2013-09-15T18:49:01Z"
+ content="""
+I get this error when I try to build git-annex using \"cabal install git-annex\"
+
+ [ 34 of 347] Compiling Utility.Misc ( Utility/Misc.hs, dist/build/git-annex/git-annex-tmp/Utility/Misc.o )
+ [ 35 of 347] Compiling Utility.Process ( Utility/Process.hs, dist/build/git-annex/git-annex-tmp/Utility/Process.o )
+ [ 36 of 347] Compiling Utility.Network ( Utility/Network.hs, dist/build/git-annex/git-annex-tmp/Utility/Network.o )
+ [ 37 of 347] Compiling Utility.SRV ( Utility/SRV.hs, dist/build/git-annex/git-annex-tmp/Utility/SRV.o )
+
+ Utility/SRV.hs:70:54:
+ Couldn't match expected type `Maybe
+ [(Int, Int, Integer, B8.ByteString)]'
+ with actual type `Either
+ dns-1.0.0:Network.DNS.Internal.DNSError
+ [(Int, Int, Int, dns-1.0.0:Network.DNS.Internal.Domain)]'
+ In the third argument of `maybe', namely `r'
+ In the second argument of `($)', namely
+ `maybe [] (orderHosts . map tohosts) r'
+ In a stmt of a 'do' block:
+ return $ maybe [] (orderHosts . map tohosts) r
+ Failed to install git-annex-4.20130909
+ cabal: Error: some packages failed to install:
+ git-annex-4.20130909 failed during the building phase. The exception was:
+ ExitFailure 1
+
+"""]]
diff --git a/doc/install/OSX/comment_24_b9d3563a2cc3d769f27876e028dc344d._comment b/doc/install/OSX/comment_24_b9d3563a2cc3d769f27876e028dc344d._comment
new file mode 100644
index 000000000..4b4bf3eb7
--- /dev/null
+++ b/doc/install/OSX/comment_24_b9d3563a2cc3d769f27876e028dc344d._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.128"
+ subject="comment 24"
+ date="2013-09-17T15:56:17Z"
+ content="""
+@Kristian, a new version of the DNS library has caused this. A workaround is to pass `-f-DNS` to the cabal command.
+
+I am in the process of adding support for the new DNS library version in git now.
+
+By the way, please [[file_a_bug|bugs]] if you have a big ugly looking build failure like that, so as to not clutter up this page.
+"""]]
diff --git a/doc/install/OSX/comment_25_db90984062a07576a4777b2d743161f1._comment b/doc/install/OSX/comment_25_db90984062a07576a4777b2d743161f1._comment
new file mode 100644
index 000000000..2a924e8f9
--- /dev/null
+++ b/doc/install/OSX/comment_25_db90984062a07576a4777b2d743161f1._comment
@@ -0,0 +1,24 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnyMzZZLS1xGW1raqc_9Md6Ksdkvx5rUJU"
+ nickname="Michael"
+ subject="confusion with bundled programs"
+ date="2013-10-02T21:39:11Z"
+ content="""
+I have fiddled with the fresh (as of Oct 2nd) build of assistant on OS X 10.8.5, and there has been a lot of problems with bundled software
+
+bundled git is an old 1.7.x version which keeps saying in the daemon logs it is too old to honor .gitignores etc
+at the same time I have git 1.8.4 installed through homebrew which works very nicely throughout my system
+
+I also have homebrew-installed gpg2:
+
+$ gpg2 --version
+gpg (GnuPG) 2.0.21
+libgcrypt 1.5.3
+
+(and have briefly experimented with using GPGSuite from gpgtools.org, which kept bailing with invalid autolocate directive in gpg.conf)
+
+however there is some unidentifiable gpg binary bundled with the assistant, which cannot connect to gpg-agent from gpg2, and doesn't work with GPGSuite (see above)
+
+is there a way to completely forgo usage of bundled software and have the webapp use whatever is already available on the system?
+
+"""]]
diff --git a/doc/install/OSX/comment_27_2a60108a440231ba83f5a54b6bcc5488._comment b/doc/install/OSX/comment_27_2a60108a440231ba83f5a54b6bcc5488._comment
new file mode 100644
index 000000000..9a5b9c9c1
--- /dev/null
+++ b/doc/install/OSX/comment_27_2a60108a440231ba83f5a54b6bcc5488._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnZEanlyzay_QlEAL0CWpyZcRTyN7vay8U"
+ nickname="Carlo"
+ subject="comment 27"
+ date="2013-10-16T09:40:23Z"
+ content="""
+The [FSevents framework itself has been around since leopard](http://arstechnica.com/apple/2007/10/mac-os-x-10-5/7/).
+
+[This fsevents wrapper project](https://github.com/rastersize/CDEvents) supports snow leopard and even leopard, maybe it will provide some clues on how it was done.
+
+I'm guessing it would be worth it, [snow leopard is still the most popular OSX as of April](http://www.patentlyapple.com/patently-apple/2013/04/snow-leopard-remains-the-most-popular-version-of-os-x.html). From my own experience, snow leopard is a huge life extender for 2+ year old hardware. Lion just makes them sluggishly painful to use.
+
+Maybe someone could volunteer an SL machine for remote development? Sorry, mine are tied down :(
+"""]]
diff --git a/doc/install/OSX/comment_27_d453510b9bb62072a4c663206c12c8a4._comment b/doc/install/OSX/comment_27_d453510b9bb62072a4c663206c12c8a4._comment
new file mode 100644
index 000000000..cc9b44c1a
--- /dev/null
+++ b/doc/install/OSX/comment_27_d453510b9bb62072a4c663206c12c8a4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="64.134.31.139"
+ subject="comment 27"
+ date="2013-10-16T15:14:53Z"
+ content="""
+The git-annex assistant uses **file level** FSevents to detect which files have been changed. Would it be possible to make it work with older versions that don't provide file-level events? Probably. The code for BSD kqueue deals with similar limitations in needing to scan the directory to find the files that actually changed. If someone cares about old versions of OSX and wants to do that work I'll happily support you.
+"""]]
diff --git a/doc/install/OSX/comment_28_0970bfd63137ea48701dff6aea1b4bcb._comment b/doc/install/OSX/comment_28_0970bfd63137ea48701dff6aea1b4bcb._comment
new file mode 100644
index 000000000..a672a70c4
--- /dev/null
+++ b/doc/install/OSX/comment_28_0970bfd63137ea48701dff6aea1b4bcb._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="http://alan.petitepomme.net/"
+ nickname="Alan Schmitt"
+ subject="dbus support?"
+ date="2013-10-18T08:24:11Z"
+ content="""
+Hello,
+
+I just compiled git-annex using cabal on OS X, and I see there is no dbus support:
+
+ Assistant/Threads/NetWatcher.hs:26:0:
+ warning: #warning Building without dbus support; will poll for network connection changes
+
+ Assistant/Threads/MountWatcher.hs:33:0:
+ warning: #warning Building without dbus support; will use mtab polling
+
+Is this problematic? I see I can install dbus using homebrew. If I do so, will I have dbus support (after recompiling git-annex)?
+"""]]
diff --git a/doc/install/OSX/comment_29_8622ed56c6a8034c20fb311418d94003._comment b/doc/install/OSX/comment_29_8622ed56c6a8034c20fb311418d94003._comment
new file mode 100644
index 000000000..c0552d9d9
--- /dev/null
+++ b/doc/install/OSX/comment_29_8622ed56c6a8034c20fb311418d94003._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnZEanlyzay_QlEAL0CWpyZcRTyN7vay8U"
+ nickname="Carlo"
+ subject="comment 29"
+ date="2013-10-18T15:58:59Z"
+ content="""
+I think I dragged you out of dev mode for commenting unnecessarily, sorry about that. Apparently, [Lion](http://www.redmondpie.com/os-x-lion-vs-os-x-snow-leopard-head-to-head-performance-showdown/) and [Mountain Lion are fine on older hardware](http://apple.stackexchange.com/questions/58453/will-mountain-lion-make-an-older-computer-run-faster-or-slower). For a while [a daemon cause Lion slowdowns for a day after upgrade](https://discussions.apple.com/message/15719036) for a while, which was enough to cause a reputation.
+"""]]
diff --git a/doc/install/OSX/comment_2_25552ff2942048fafe97d653757f1ad6._comment b/doc/install/OSX/comment_2_25552ff2942048fafe97d653757f1ad6._comment
new file mode 100644
index 000000000..8d7010a1b
--- /dev/null
+++ b/doc/install/OSX/comment_2_25552ff2942048fafe97d653757f1ad6._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ subject="comment 2"
+ date="2012-07-24T15:09:29Z"
+ content="""
+I've moved some outdated comments about installing on OSX to [[old_comments]].
+And also moved away some comments that helped build the instructions above.
+"""]]
diff --git a/doc/install/OSX/comment_30_ce58633ef5b2f8f4caa7e626358f33be._comment b/doc/install/OSX/comment_30_ce58633ef5b2f8f4caa7e626358f33be._comment
new file mode 100644
index 000000000..9fcf7aa03
--- /dev/null
+++ b/doc/install/OSX/comment_30_ce58633ef5b2f8f4caa7e626358f33be._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="64.134.31.139"
+ subject="comment 30"
+ date="2013-10-19T15:31:45Z"
+ content="""
+@Alan you don't need to install dbus on OSX. The polling code will work. On the other hand if you'd like to experiment with installing dbus and report back, perhaps it's worth a try. It's nice when the git-annex assistant can instantly detect when drives are plugged in, and then the network connection changes and react to it. On Linux, dbus gives it that capability.
+"""]]
diff --git a/doc/install/OSX/comment_31_09084a7b3cf06bfa3add0f4991476ffe._comment b/doc/install/OSX/comment_31_09084a7b3cf06bfa3add0f4991476ffe._comment
new file mode 100644
index 000000000..df9134194
--- /dev/null
+++ b/doc/install/OSX/comment_31_09084a7b3cf06bfa3add0f4991476ffe._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://alan.petitepomme.net/"
+ nickname="Alan Schmitt"
+ subject="dbus and homebrew"
+ date="2013-10-20T17:25:04Z"
+ content="""
+I'm trying to build git-annex with dbus support, and even though I installed dbus (through homebrew), at the end of compilation I get the warning about \"building without dbus\". Is there something special I need to do for git-annex to see I have installed dbus?
+
+(Also, it tells me at the beginning that I don't have gcrypt, but libgcrypt is installed.)
+"""]]
diff --git a/doc/install/OSX/comment_32_a46d8e3e7795b9afb1e1c2be943d12af._comment b/doc/install/OSX/comment_32_a46d8e3e7795b9afb1e1c2be943d12af._comment
new file mode 100644
index 000000000..290da58f8
--- /dev/null
+++ b/doc/install/OSX/comment_32_a46d8e3e7795b9afb1e1c2be943d12af._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="64.134.31.139"
+ subject="comment 32"
+ date="2013-10-21T22:47:14Z"
+ content="""
+You probably need to install libdbus dev stuff, and then the haskell dbus library. But it's certainly going to need code changes to make git-annex use dbus in any way on OSX, assuming there are even useful dbus events generated for network connections and drives being mounted on OSX.
+
+It was saying \"gcrypt\" when it meant \"git-remote-gcrypt\".
+"""]]
diff --git a/doc/install/OSX/comment_33_203a36322b3c453c05c8906c64e62e06._comment b/doc/install/OSX/comment_33_203a36322b3c453c05c8906c64e62e06._comment
new file mode 100644
index 000000000..7e2853a4e
--- /dev/null
+++ b/doc/install/OSX/comment_33_203a36322b3c453c05c8906c64e62e06._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://alan.petitepomme.net/"
+ nickname="Alan Schmitt"
+ subject="comment 33"
+ date="2013-10-23T11:39:51Z"
+ content="""
+I installed the haskell DBus library, but it's still not picking it up. Is there some additional option to pass to cabal, or is it supposed to find it automatically?
+"""]]
diff --git a/doc/install/OSX/comment_34_c9362141d15a2f68a75df9f8bfe29da0._comment b/doc/install/OSX/comment_34_c9362141d15a2f68a75df9f8bfe29da0._comment
new file mode 100644
index 000000000..65a7e0ea7
--- /dev/null
+++ b/doc/install/OSX/comment_34_c9362141d15a2f68a75df9f8bfe29da0._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl-xMSPoRHcT5d2nAc1K8pWVi-AexKkYik"
+ nickname="Ralf"
+ subject="Mac OS X Maverick - symbol not found"
+ date="2013-10-27T21:02:45Z"
+ content="""
+Just to mention that the beta dated 24 Oct 2013 and Joey's autobuild of 27 Oct both don't start with the following error message for git-annex, git-annex-webapp under Mac OS X 10.9 Maverick with latest XCode installed:
+
+ dyld: Symbol not found: _objc_debug_taggedpointer_mask
+ Referenced from: /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
+ Expected in: /Applications/git-annex.app/Contents/MacOS/bundle/I
+ in /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
+
+ Trace/BPT trap: 5
+
+Many thanks. Can I help?
+"""]]
diff --git a/doc/install/OSX/comment_35_8106196c3fef70652cb2106e2d5857db._comment b/doc/install/OSX/comment_35_8106196c3fef70652cb2106e2d5857db._comment
new file mode 100644
index 000000000..697dafa0b
--- /dev/null
+++ b/doc/install/OSX/comment_35_8106196c3fef70652cb2106e2d5857db._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 35"
+ date="2013-10-27T21:06:57Z"
+ content="""
+We do not yet have an autobuild for 10.9. You can build from source: <http://git-annex.branchable.com/bugs/git_annex_doesn__39__t_work_in_Max_OS_X_10.9/#comment-8e8ee5e50506a6fde029d236f4809df8>
+"""]]
diff --git a/doc/install/OSX/comment_3_47a77a03040fe628109bd54f82f9ad7a._comment b/doc/install/OSX/comment_3_47a77a03040fe628109bd54f82f9ad7a._comment
new file mode 100644
index 000000000..69f3f0fee
--- /dev/null
+++ b/doc/install/OSX/comment_3_47a77a03040fe628109bd54f82f9ad7a._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlDDW-g2WLLsLpcnCm4LykAquFY_nwbIrU"
+ nickname="Daniel"
+ subject="comment 3"
+ date="2013-01-15T15:22:43Z"
+ content="""
+Installing via the MacPorts method. I ran into this error.
+
+ \"_locale_charset\", referenced from: _localeEncoding in libHSbase-4.5.1.0.a(PrelIOUtils.o)
+ ld: symbol(s) not found for architecture x86_64
+
+I was able to solve and get git-annex to build buy providing the --extra-lib-dirs parameter
+
+ cabal install c2hs git-annex --bindir=$HOME/bin --extra-lib-dirs=/usr/lib
+
+Cheers, [Daniel Wozniak](http://woz.io)
+"""]]
diff --git a/doc/install/OSX/comment_4_25cac8bcd84a5210fc0a5243260b8cc7._comment b/doc/install/OSX/comment_4_25cac8bcd84a5210fc0a5243260b8cc7._comment
new file mode 100644
index 000000000..703f502f7
--- /dev/null
+++ b/doc/install/OSX/comment_4_25cac8bcd84a5210fc0a5243260b8cc7._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnaYy6kTuKAHmsa4BtGls2oqa42Jo2w2v0"
+ nickname="Pere"
+ subject="Snow Leopard"
+ date="2013-01-18T15:51:48Z"
+ content="""
+Hi,
+
+Are there plans to provide a git-annex.app that works on Snow Leopard?
+
+Currently there are only installers for the Lions.
+
+http://downloads.kitenet.net/git-annex/OSX/current/
+
+Thanks :-)
+
+
+"""]]
diff --git a/doc/install/OSX/comment_4_bbe99673033e4c48c8bb3db24ee419f9._comment b/doc/install/OSX/comment_4_bbe99673033e4c48c8bb3db24ee419f9._comment
new file mode 100644
index 000000000..f3838e890
--- /dev/null
+++ b/doc/install/OSX/comment_4_bbe99673033e4c48c8bb3db24ee419f9._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 4"
+ date="2012-12-10T17:00:43Z"
+ content="""
+For those that care, I've updated my autobuilder to the latest version of haskell-platform 2012.4.0.0 and it appears to be building correctly.
+"""]]
diff --git a/doc/install/OSX/comment_5_39b4b748b4586bf32b37edfefef84bba._comment b/doc/install/OSX/comment_5_39b4b748b4586bf32b37edfefef84bba._comment
new file mode 100644
index 000000000..c188d8125
--- /dev/null
+++ b/doc/install/OSX/comment_5_39b4b748b4586bf32b37edfefef84bba._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.3.194"
+ subject="comment 5"
+ date="2013-01-18T17:25:36Z"
+ content="""
+What we need to provide a Snow Leopard or other version build, is access to a box running that version of OSX, or someone with a box that doesn't mind compiling stuff and setting up the autobuilder (not very hard).
+"""]]
diff --git a/doc/install/OSX/comment_6_1a9c91ef43edc4148947f202ff604114._comment b/doc/install/OSX/comment_6_1a9c91ef43edc4148947f202ff604114._comment
new file mode 100644
index 000000000..a16e4cad0
--- /dev/null
+++ b/doc/install/OSX/comment_6_1a9c91ef43edc4148947f202ff604114._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnaYy6kTuKAHmsa4BtGls2oqa42Jo2w2v0"
+ nickname="Pere"
+ subject="Snow Leopard"
+ date="2013-01-18T17:57:40Z"
+ content="""
+If the process is very automatic I might contribute. I mean, if you tell me, install this and that package and run this script once a week, I might be able to help. I have a MacBook from 2007 with Snow Leopard. I also have macports installed, but I'm not a programmer.
+"""]]
diff --git a/doc/install/OSX/comment_7_892f7e65f95f43697164267c4b71c0d5._comment b/doc/install/OSX/comment_7_892f7e65f95f43697164267c4b71c0d5._comment
new file mode 100644
index 000000000..3c7e2b8b6
--- /dev/null
+++ b/doc/install/OSX/comment_7_892f7e65f95f43697164267c4b71c0d5._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.3.194"
+ subject="comment 7"
+ date="2013-01-18T20:16:52Z"
+ content="""
+If you can get it to build using the instructions for Brew (or MacPorts) on this page, it's easy to get from there to a distributable app.
+"""]]
diff --git a/doc/install/OSX/comment_8_38d9c2eea1090674de2361274eab5b0e._comment b/doc/install/OSX/comment_8_38d9c2eea1090674de2361274eab5b0e._comment
new file mode 100644
index 000000000..bdc1698b7
--- /dev/null
+++ b/doc/install/OSX/comment_8_38d9c2eea1090674de2361274eab5b0e._comment
@@ -0,0 +1,29 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnaYy6kTuKAHmsa4BtGls2oqa42Jo2w2v0"
+ nickname="Pere"
+ subject="I couldn't install it on Snow Leopard"
+ date="2013-01-19T15:04:27Z"
+ content="""
+Bad news, it looks like I'm not able to install git-annex to my machine: When I run
+
+ sudo cabal install c2hs git-annex --bindir=$HOME/bin
+
+I get the following error:
+
+ cabal: Error: some packages failed to install:
+ DAV-0.3 failed during the building phase. The exception was:
+ ExitFailure 11
+ git-annex-3.20130114 depends on yesod-core-1.1.7.1 which failed to install.
+ yesod-1.1.7.2 depends on yesod-core-1.1.7.1 which failed to install.
+ yesod-auth-1.1.3 depends on yesod-core-1.1.7.1 which failed to install.
+ yesod-core-1.1.7.1 failed during the building phase. The exception was:
+ ExitFailure 11
+ yesod-default-1.1.3 depends on yesod-core-1.1.7.1 which failed to install.
+ yesod-form-1.2.0.2 depends on yesod-core-1.1.7.1 which failed to install.
+ yesod-json-1.1.2 depends on yesod-core-1.1.7.1 which failed to install.
+ yesod-persistent-1.1.0.1 depends on yesod-core-1.1.7.1 which failed to
+ install.
+ yesod-static-1.1.1.2 depends on yesod-core-1.1.7.1 which failed to install.
+
+What does *ExitFailure 11* mean?
+"""]]
diff --git a/doc/install/OSX/comment_9_35bf3812db6f3ef25da9b3bc84f147c5._comment b/doc/install/OSX/comment_9_35bf3812db6f3ef25da9b3bc84f147c5._comment
new file mode 100644
index 000000000..afb733443
--- /dev/null
+++ b/doc/install/OSX/comment_9_35bf3812db6f3ef25da9b3bc84f147c5._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.3.194"
+ subject="comment 9"
+ date="2013-01-19T16:02:35Z"
+ content="""
+sig11 is a Segmentation Fault, probably from a C library used by DAV for HTTP in this case.
+"""]]
diff --git a/doc/install/OSX/old_comments.mdwn b/doc/install/OSX/old_comments.mdwn
new file mode 100644
index 000000000..ccb6785fd
--- /dev/null
+++ b/doc/install/OSX/old_comments.mdwn
@@ -0,0 +1 @@
+Moved a bunch of outdated comments here, AFAIK all these issues are fixed.
diff --git a/doc/install/OSX/old_comments/comment_10_4d15bfc4fc26e7249953bebfbb09e0aa._comment b/doc/install/OSX/old_comments/comment_10_4d15bfc4fc26e7249953bebfbb09e0aa._comment
new file mode 100644
index 000000000..d655da725
--- /dev/null
+++ b/doc/install/OSX/old_comments/comment_10_4d15bfc4fc26e7249953bebfbb09e0aa._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkp-1EQboBDqZ05MxOHNkwNQDM4luWYioA"
+ nickname="Charles"
+ subject="comment 10"
+ date="2012-11-15T13:26:57Z"
+ content="""
+Installing it with brew, I had to do the following steps before the final `cabal` command:
+
+* `cabal install c2hs`
+* add `$HOME/.cabal/bin` to my `$PATH` (so that c2hs program can be found)
+"""]]
diff --git a/doc/install/OSX/old_comments/comment_10_798000aab19af2944b6e44dbc550c6fe._comment b/doc/install/OSX/old_comments/comment_10_798000aab19af2944b6e44dbc550c6fe._comment
new file mode 100644
index 000000000..675a90eee
--- /dev/null
+++ b/doc/install/OSX/old_comments/comment_10_798000aab19af2944b6e44dbc550c6fe._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.2.25"
+ subject="comment 10"
+ date="2012-06-25T15:38:44Z"
+ content="""
+@Agustin you should be able to work around that with: cabal install git-annex --flags=-Inotify
+
+I've fixed it properly for the next release, it should only be using that library on Linux.
+"""]]
diff --git a/doc/install/OSX/old_comments/comment_11_707a1a27a15b2de8dfc8d1a30420ab4c._comment b/doc/install/OSX/old_comments/comment_11_707a1a27a15b2de8dfc8d1a30420ab4c._comment
new file mode 100644
index 000000000..69a4f9128
--- /dev/null
+++ b/doc/install/OSX/old_comments/comment_11_707a1a27a15b2de8dfc8d1a30420ab4c._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkwR9uOA38yi5kEUvcEWNtRiZwpxXskayE"
+ nickname="Agustin"
+ subject="comment 11"
+ date="2012-06-27T08:54:52Z"
+ content="""
+Hi @joey! Perfect!... I'll do that then!
+
+Thanks for your time man!
+"""]]
diff --git a/doc/install/OSX/old_comments/comment_12_60d13f2c8e008af1041bea565a392c83._comment b/doc/install/OSX/old_comments/comment_12_60d13f2c8e008af1041bea565a392c83._comment
new file mode 100644
index 000000000..e2e85aaa9
--- /dev/null
+++ b/doc/install/OSX/old_comments/comment_12_60d13f2c8e008af1041bea565a392c83._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnHrjHxJAm39x8DR4bnbazQO6H0nMNuY9c"
+ nickname="Damien"
+ subject="sha256 alternative"
+ date="2012-06-30T14:34:11Z"
+ content="""
+in reply to comment 6: On my Mac (10.7.4) there's `/usr/bin/shasum -a 256 <file>` command that will produce the same output as `sha256sum <file>`.
+"""]]
diff --git a/doc/install/OSX/old_comments/comment_13_a6f48c87c2d6eabe379d6e10a6cac453._comment b/doc/install/OSX/old_comments/comment_13_a6f48c87c2d6eabe379d6e10a6cac453._comment
new file mode 100644
index 000000000..e5ce62b13
--- /dev/null
+++ b/doc/install/OSX/old_comments/comment_13_a6f48c87c2d6eabe379d6e10a6cac453._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnHrjHxJAm39x8DR4bnbazQO6H0nMNuY9c"
+ nickname="Damien"
+ subject="gnu commands"
+ date="2012-07-01T17:03:57Z"
+ content="""
+…and another approach to the same problem: apparently git-annex also relies on the GNU coreutils (for instance, when doing `git annex get .`, `cp` complains about `illegal option -- -`). I do have the GNU coreutils installed with Homebrew, but they are all prefixed with `g`. So maybe you should try `gsha256sum` and `gcp` before `sha256sum` and `cp`, that seems like a more general solution.
+"""]]
diff --git a/doc/install/OSX/old_comments/comment_14_6ef2ddb7b11ce6ad54578ae118ed346e._comment b/doc/install/OSX/old_comments/comment_14_6ef2ddb7b11ce6ad54578ae118ed346e._comment
new file mode 100644
index 000000000..35e0bb6ed
--- /dev/null
+++ b/doc/install/OSX/old_comments/comment_14_6ef2ddb7b11ce6ad54578ae118ed346e._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ subject="comment 14"
+ date="2012-07-04T12:43:54Z"
+ content="""
+@Damien, hmm, it should not be using any cp options, unless when it was built there was a cp in the path that supported some option like -p. Can you check with --debug what cp parameters it's trying to use?
+
+
+"""]]
diff --git a/doc/install/OSX/old_comments/comment_15_6fd1fad5b6d9f36620e5a0e99edd2f89._comment b/doc/install/OSX/old_comments/comment_15_6fd1fad5b6d9f36620e5a0e99edd2f89._comment
new file mode 100644
index 000000000..0005328c4
--- /dev/null
+++ b/doc/install/OSX/old_comments/comment_15_6fd1fad5b6d9f36620e5a0e99edd2f89._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ subject="comment 15"
+ date="2012-07-04T13:14:00Z"
+ content="""
+git-annex will now fall back to slower pure Haskell hashing code if `sha256sum`, etc programs are not in PATH. I'd still recommend installing the coreutils, as they're probably faster.
+
+(The `shasum` command seems to come from a perl library, so I have not tried to make git-annex use that one.)
+"""]]
diff --git a/doc/install/OSX/old_comments/comment_16_af6fe3540032cdf4400478de87771058._comment b/doc/install/OSX/old_comments/comment_16_af6fe3540032cdf4400478de87771058._comment
new file mode 100644
index 000000000..5da4b22c6
--- /dev/null
+++ b/doc/install/OSX/old_comments/comment_16_af6fe3540032cdf4400478de87771058._comment
@@ -0,0 +1,30 @@
+[[!comment format=mdwn
+ username="https://a-or-b.myopenid.com/"
+ ip="203.45.2.230"
+ subject="Compiling git-annex on OSX (with 32 bit Haskell)"
+ date="2012-07-24T03:26:45Z"
+ content="""
+I came across an issue when following the instructions here:
+ <http://git-annex.branchable.com/install/OSX/>
+
+I'm compiling the 'assistant' branch (522f568450a005ae81b24f63bb37e75320b51219).
+
+
+The pre-compiled version of Haskell for OSX recommends the 32 bit installer, however git-annex compiles
+
+> Utility/libdiskfree.o Utility/libkqueue.o Utility/libmounts.o
+
+as 64 bit. The 'make' command fails on linking 32- and 64-bit code.
+
+So... I made a small change to the Makefile
+
+> CFLAGS=-Wall
+
+becomes
+
+> CFLAGS=-Wall -m32
+
+I don't know if there is an easy way to programmatically check for this, or even if you'd want to spend time doing it, but it might help someone else out.
+
+<https://gist.github.com/3167798>
+"""]]
diff --git a/doc/install/OSX/old_comments/comment_17_8d3a0596db67108041728b20f2790f31._comment b/doc/install/OSX/old_comments/comment_17_8d3a0596db67108041728b20f2790f31._comment
new file mode 100644
index 000000000..782f2fd75
--- /dev/null
+++ b/doc/install/OSX/old_comments/comment_17_8d3a0596db67108041728b20f2790f31._comment
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ subject="comment 17"
+ date="2012-07-24T15:03:49Z"
+ content="""
+The instructions say to use cabal for a reason -- it's more likely to work. But I have made the Makefile detect the mismatched GHC and C compiler and force the C compiler to 32 bit.
+"""]]
diff --git a/doc/install/OSX/old_comments/comment_1_0a1760bf0db1f1ba89bdb4c62032f631._comment b/doc/install/OSX/old_comments/comment_1_0a1760bf0db1f1ba89bdb4c62032f631._comment
new file mode 100644
index 000000000..1148a87ca
--- /dev/null
+++ b/doc/install/OSX/old_comments/comment_1_0a1760bf0db1f1ba89bdb4c62032f631._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://www.schleptet.net/~cfm/"
+ ip="64.30.148.100"
+ subject="comment 1"
+ date="2011-08-30T14:31:36Z"
+ content="""
+You can also use Homebrew instead of MacPorts. Homebrew's `haskell-platform` is up-to-date, too:
+
+ brew install haskell-platform git ossp-uuid md5sha1sum coreutils pcre
+ ln -s /usr/local/include/pcre.h /usr/include/pcre.h
+
+As of this writing, however, Homebrew's `md5sha1sum` has a broken mirror. I wound up getting that from MacPorts anyway.
+"""]]
diff --git a/doc/install/OSX/old_comments/comment_2_0327c64b15249596add635d26f4ce67f._comment b/doc/install/OSX/old_comments/comment_2_0327c64b15249596add635d26f4ce67f._comment
new file mode 100644
index 000000000..5768d8b93
--- /dev/null
+++ b/doc/install/OSX/old_comments/comment_2_0327c64b15249596add635d26f4ce67f._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkEUhIcw37X2Kh-dznSMIb9Vgcq0frfdWs"
+ nickname="Ethan"
+ subject="GHC 7"
+ date="2012-03-28T19:06:51Z"
+ content="""
+The Haskell Platform installer for OSX uses GHC 7.0.4, which doesn't seem able to support the current version of git-annex.
+
+Cabal throws a very cryptic error about not being able to use the proper base package.
+
+I was able to install it by
+
+1. cloning the repo
+2. merging the ghc7.0 branch
+3. resolving merge conflicts in git-annex.cabal
+4. cabal install git-annex.cabal
+
+(Note I also tried this with homebrew and had similar results)
+"""]]
diff --git a/doc/install/OSX/old_comments/comment_2_7683740a98182de06cb329792e0c0a25._comment b/doc/install/OSX/old_comments/comment_2_7683740a98182de06cb329792e0c0a25._comment
new file mode 100644
index 000000000..113ef687a
--- /dev/null
+++ b/doc/install/OSX/old_comments/comment_2_7683740a98182de06cb329792e0c0a25._comment
@@ -0,0 +1,25 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmYiJgOvC4IDYkr2KIjMlfVD9r_1Sij_jY"
+ nickname="Douglas"
+ subject="setup: standalone/macos/git-annex.app/Contents/Info.plist: does not exist"
+ date="2012-10-06T14:46:55Z"
+ content="""
+I tried installing with cabal and homebrew on Mountain Lion. After cabal install git-annex I get:
+
+ Linking dist/build/git-annex/git-annex ...
+ Installing executable(s) in /Users/dfc/.cabal/bin
+ setup: standalone/macos/git-annex.app/Contents/Info.plist: does not exist
+ cabal: Error: some packages failed to install:
+ git-annex-3.20121001 failed during the final install step. The exception was:
+ ExitFailure 1
+
+
+There is no directory named macos inside of standalone:
+
+ jumbo:git-annex-3.20121001 dfc$ ls -l standalone/
+ total 112
+ -rw-r--r--+ 1 dfc staff 55614 Oct 6 10:40 licences.gz
+ drwxr-xr-x+ 6 dfc staff 204 Oct 6 10:40 linux
+ drwxr-xr-x+ 3 dfc staff 102 Oct 6 10:40 osx
+
+"""]]
diff --git a/doc/install/OSX/old_comments/comment_3_47c682a779812dda77601c24a619923c._comment b/doc/install/OSX/old_comments/comment_3_47c682a779812dda77601c24a619923c._comment
new file mode 100644
index 000000000..251375cbe
--- /dev/null
+++ b/doc/install/OSX/old_comments/comment_3_47c682a779812dda77601c24a619923c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="ghc 7.0"
+ date="2012-03-28T19:18:58Z"
+ content="""
+You did the right thing, although just checking out the ghc-7.0 branch will avoid merge conflicts. I am trying to keep it fairly close to up-to-date.
+"""]]
diff --git a/doc/install/OSX/old_comments/comment_3_733147cebe501c60f2141b711f1d7f24._comment b/doc/install/OSX/old_comments/comment_3_733147cebe501c60f2141b711f1d7f24._comment
new file mode 100644
index 000000000..51e667ab6
--- /dev/null
+++ b/doc/install/OSX/old_comments/comment_3_733147cebe501c60f2141b711f1d7f24._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnnIQkoUQo4RYzjUNyiB3v6yJ5aR41WG8k"
+ nickname="Markus"
+ subject="Updated install instructions with homebrew"
+ date="2012-08-07T06:46:47Z"
+ content="""
+To install git annex with homebrew simply do:
+
+ brew update
+ brew install haskell-platform git ossp-uuid md5sha1sum coreutils pcre
+ cabal install git-annex
+
+Then link the binary to your `PATH` e.g. with
+
+ ln -s ~/.cabal/bin/git-annex* /usr/local/bin/
+"""]]
diff --git a/doc/install/OSX/old_comments/comment_3_b090f40fe5a32e00b472a5ab2b850b4a._comment b/doc/install/OSX/old_comments/comment_3_b090f40fe5a32e00b472a5ab2b850b4a._comment
new file mode 100644
index 000000000..a437704a3
--- /dev/null
+++ b/doc/install/OSX/old_comments/comment_3_b090f40fe5a32e00b472a5ab2b850b4a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.149"
+ subject="comment 3"
+ date="2012-10-06T21:05:45Z"
+ content="""
+@Douglas, I've fixed that in git. FWIW, the program is installed before that point. Actually, I am leaning toward not having cabal install that plist file at all.
+"""]]
diff --git a/doc/install/OSX/old_comments/comment_3_fc092412e99cf4c5f095b0ef710bc4de._comment b/doc/install/OSX/old_comments/comment_3_fc092412e99cf4c5f095b0ef710bc4de._comment
new file mode 100644
index 000000000..47ad9feaf
--- /dev/null
+++ b/doc/install/OSX/old_comments/comment_3_fc092412e99cf4c5f095b0ef710bc4de._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 17"
+ date="2012-07-24T06:33:13Z"
+ content="""
+@a-or-b that issue is logged here [[bugs/subtle build issue on OSX 10.7 and Haskell Platform (if you have the 32bit version installed)]], you can use cabal to build and install git-annex and it will detect if its 32 or 64bit automatically.
+"""]]
diff --git a/doc/install/OSX/old_comments/comment_4_d513e21512a9b207983d38abf348d00f._comment b/doc/install/OSX/old_comments/comment_4_d513e21512a9b207983d38abf348d00f._comment
new file mode 100644
index 000000000..049f7e962
--- /dev/null
+++ b/doc/install/OSX/old_comments/comment_4_d513e21512a9b207983d38abf348d00f._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm_-2XlXNyd6cCLI4n_jaBNqVUOWwJquko"
+ nickname="David"
+ subject="installing via homebrew"
+ date="2012-09-05T11:11:55Z"
+ content="""
+I had to:
+
+ cabal update
+
+before:
+
+ cabal install git-annex
+
+
+"""]]
diff --git a/doc/install/OSX/old_comments/comment_4_d68c36432c7be3f4a76f4f0d7300bac9._comment b/doc/install/OSX/old_comments/comment_4_d68c36432c7be3f4a76f4f0d7300bac9._comment
new file mode 100644
index 000000000..b274707fb
--- /dev/null
+++ b/doc/install/OSX/old_comments/comment_4_d68c36432c7be3f4a76f4f0d7300bac9._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmY_4MvT5yEeztrS7UIJseStUe4mtgp6YE"
+ nickname="Сергей"
+ subject="Have error"
+ date="2012-10-10T11:47:09Z"
+ content="""
+[ 98 of 248] Compiling Utility.DiskFree ( Utility/DiskFree.hs, dist/build/git-annex/git-annex-tmp/Utility/DiskFree.o )
+[ 99 of 248] Compiling Utility.Url ( Utility/Url.hs, dist/build/git-annex/git-annex-tmp/Utility/Url.o )
+
+Utility/Url.hs:111:88:
+ Couldn't match expected type `Maybe URI' with actual type `URI'
+ In the second argument of `fromMaybe', namely
+ `(newURI `relativeTo` u)'
+ In the expression: fromMaybe newURI (newURI `relativeTo` u)
+ In an equation for `newURI_abs':
+ newURI_abs = fromMaybe newURI (newURI `relativeTo` u)
+cabal: Error: some packages failed to install:
+git-annex-3.20121009 failed during the building phase. The exception was:
+ExitFailure 1
+"""]]
diff --git a/doc/install/OSX/old_comments/comment_4_e6109a964064a2a799768a370e57801d._comment b/doc/install/OSX/old_comments/comment_4_e6109a964064a2a799768a370e57801d._comment
new file mode 100644
index 000000000..be3ba2be4
--- /dev/null
+++ b/doc/install/OSX/old_comments/comment_4_e6109a964064a2a799768a370e57801d._comment
@@ -0,0 +1,30 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkO9tsPZkAxEulq2pGCdwz4md-LqB0RcMw"
+ nickname="Reimund"
+ subject="Problems with Base & Crypto"
+ date="2012-04-25T22:56:18Z"
+ content="""
+I got the following error message trying to install git-annex:
+
+ cabal: cannot configure git-annex-3.20120418. It requires base >=4.5 && <5
+ For the dependency on base >=4.5 && <5 there are these packages: base-4.5.0.0.
+ However none of them are available.
+ base-4.5.0.0 was excluded because of the top level dependency base -any
+
+These are the steps I performed to make it work
+
+1. Download [Ghc 7.4](http://www.haskell.org/ghc/download).
+2. Run `sudo cabal install git-annex --bindir=$HOME/bin`.
+3. Compilation of the Crypto-4.2.4 dependency failed since it's not updated to work with Ghc 7.4. You need to patch SHA2.hs (steps below).
+4. Run `sudo cabal install git-annex --bindir=$HOME/bin` a second time.
+
+The steps I did to patch the SHA2.hs file in Crypto-4.2.4:
+
+1. `cabal unpack crypto-4.2.4`
+2. `cd Crypto-4.2.4`
+3. `patch -p1 < crypto-4.2.4-ghc-7.4.patch`
+4. `sudo cabal install`.
+
+PS: I used [this patchfile](http://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/dev-haskell/crypto/files/crypto-4.2.4-ghc-7.4.patch?revision=1.1).
+Then I did the last step a third time.
+"""]]
diff --git a/doc/install/OSX/old_comments/comment_5_50777853f808d57b957f8ce9a0f84b3d._comment b/doc/install/OSX/old_comments/comment_5_50777853f808d57b957f8ce9a0f84b3d._comment
new file mode 100644
index 000000000..eca176178
--- /dev/null
+++ b/doc/install/OSX/old_comments/comment_5_50777853f808d57b957f8ce9a0f84b3d._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnHrjHxJAm39x8DR4bnbazQO6H0nMNuY9c"
+ nickname="Damien"
+ subject="sha256"
+ date="2012-06-01T16:13:05Z"
+ content="""
+If you're missing the `sha256sum` command with Homebrew, it's provided by `coreutils`. You have to change your `$PATH` before running `cabal install git-annex.cabal`:
+
+ PATH=\"$(brew --prefix coreutils)/libexec/gnubin:$PATH\"
+"""]]
diff --git a/doc/install/OSX/old_comments/comment_5_626a4b4bf302d4ae750174f860402f70._comment b/doc/install/OSX/old_comments/comment_5_626a4b4bf302d4ae750174f860402f70._comment
new file mode 100644
index 000000000..1b79a11e6
--- /dev/null
+++ b/doc/install/OSX/old_comments/comment_5_626a4b4bf302d4ae750174f860402f70._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.248.164"
+ subject="comment 5"
+ date="2012-10-10T15:34:23Z"
+ content="""
+@Сергей, I've fixeed that in git.
+"""]]
diff --git a/doc/install/OSX/old_comments/comment_6_18a8df794aa0ddd294dbf17d3d4c7fe2._comment b/doc/install/OSX/old_comments/comment_6_18a8df794aa0ddd294dbf17d3d4c7fe2._comment
new file mode 100644
index 000000000..5cb813776
--- /dev/null
+++ b/doc/install/OSX/old_comments/comment_6_18a8df794aa0ddd294dbf17d3d4c7fe2._comment
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ subject="comment 6"
+ date="2012-06-01T17:24:29Z"
+ content="""
+Last night I made it look in /opt/local/libexec/gnubin .. if there's another directory it could look in, let me know. I am reluctant to make it run the brew command directly.
+"""]]
diff --git a/doc/install/OSX/old_comments/comment_7_2ce7acab15403d3f993cec94ec7f3bc6._comment b/doc/install/OSX/old_comments/comment_7_2ce7acab15403d3f993cec94ec7f3bc6._comment
new file mode 100644
index 000000000..32093ee51
--- /dev/null
+++ b/doc/install/OSX/old_comments/comment_7_2ce7acab15403d3f993cec94ec7f3bc6._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://www.davidhaslem.com/"
+ nickname="David"
+ subject="comment 7"
+ date="2012-06-19T04:41:27Z"
+ content="""
+$(brew --prefix) should, in most cases, be /usr/local. That's the recommended install location for homebrew.
+
+I already had git installed and homebrew as my package manager - my install steps were as follows:
+
+1. brew install haskell-platform ossp-uuid md5sha1sum coreutils pcre
+2. PATH=\"$(brew --prefix coreutils)/libexec/gnubin:$PATH\" cabal install git-annex
+
+"""]]
diff --git a/doc/install/OSX/old_comments/comment_8_a93ad4b67c5df4243268bcf32562f6be._comment b/doc/install/OSX/old_comments/comment_8_a93ad4b67c5df4243268bcf32562f6be._comment
new file mode 100644
index 000000000..cd128a6f1
--- /dev/null
+++ b/doc/install/OSX/old_comments/comment_8_a93ad4b67c5df4243268bcf32562f6be._comment
@@ -0,0 +1,39 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkwR9uOA38yi5kEUvcEWNtRiZwpxXskayE"
+ nickname="Agustin"
+ subject="Installation not working on OS X 10.6.8"
+ date="2012-06-25T02:21:40Z"
+ content="""
+I try installing with brew because I already had brew setup in my machine, but all run ok but when I try to run cabal install git-annex I got an error with the hinotify-0.3.2 library complaining about a header file.
+
+Full trace:
+
+~~~
+sudo cabal install git-annex
+Resolving dependencies...
+Configuring hinotify-0.3.2...
+Building hinotify-0.3.2...
+Preprocessing library hinotify-0.3.2...
+INotify.hsc:35:25: error: sys/inotify.h: No such file or directory
+INotify.hsc: In function ‘main’:
+INotify.hsc:259: error: invalid use of undefined type ‘struct inotify_event’
+INotify.hsc:260: error: invalid use of undefined type ‘struct inotify_event’
+INotify.hsc:261: error: invalid use of undefined type ‘struct inotify_event’
+INotify.hsc:262: error: invalid use of undefined type ‘struct inotify_event’
+INotify.hsc:265: error: invalid use of undefined type ‘struct inotify_event’
+INotify.hsc:266: error: invalid application of ‘sizeof’ to incomplete type ‘struct inotify_event’
+compiling dist/build/System/INotify_hsc_make.c failed (exit code 1)
+command was: /usr/bin/gcc -c dist/build/System/INotify_hsc_make.c -o dist/build/System/INotify_hsc_make.o -m64 -fno-stack-protector -m64 -D__GLASGOW_HASKELL__=704 -Ddarwin_BUILD_OS -Ddarwin_HOST_OS -Dx86_64_BUILD_ARCH -Dx86_64_HOST_ARCH -I/usr/local/Cellar/ghc/7.4.1/lib/ghc-7.4.1/directory-1.1.0.2/include -Idist/build/autogen -include dist/build/autogen/cabal_macros.h -I/usr/local/Cellar/ghc/7.4.1/lib/ghc-7.4.1/unix-2.5.1.0/include -Idist/build/autogen -include dist/build/autogen/cabal_macros.h -I/usr/local/Cellar/ghc/7.4.1/lib/ghc-7.4.1/old-time-1.1.0.0/include -Idist/build/autogen -include dist/build/autogen/cabal_macros.h -Idist/build/autogen -include dist/build/autogen/cabal_macros.h -Idist/build/autogen -include dist/build/autogen/cabal_macros.h -Idist/build/autogen -include dist/build/autogen/cabal_macros.h -Idist/build/autogen -include dist/build/autogen/cabal_macros.h -I/usr/local/Cellar/ghc/7.4.1/lib/ghc-7.4.1/bytestring-0.9.2.1/include -Idist/build/autogen -include dist/build/autogen/cabal_macros.h -Idist/build/autogen -include dist/build/autogen/cabal_macros.h -I/usr/local/Cellar/ghc/7.4.1/lib/ghc-7.4.1/base-4.5.0.0/include -Idist/build/autogen -include dist/build/autogen/cabal_macros.h -Idist/build/autogen -include dist/build/autogen/cabal_macros.h -Idist/build/autogen -include dist/build/autogen/cabal_macros.h -I/usr/local/Cellar/ghc/7.4.1/lib/ghc-7.4.1/include -Idist/build/autogen -include dist/build/autogen/cabal_macros.h -I/usr/local/Cellar/ghc/7.4.1/lib/ghc-7.4.1/include/
+cabal: Error: some packages failed to install:
+git-annex-3.20120624 depends on hinotify-0.3.2 which failed to install.
+hinotify-0.3.2 failed during the building phase. The exception was:
+ExitFailure 1
+~~~
+
+Anyone has an idea how can I solve this.
+
+Thanks for the time!
+
+Agustin
+
+"""]]
diff --git a/doc/install/OSX/old_comments/comment_9_ae3ed5345bc84f57e44251d2e6c39342._comment b/doc/install/OSX/old_comments/comment_9_ae3ed5345bc84f57e44251d2e6c39342._comment
new file mode 100644
index 000000000..70fbc6c3c
--- /dev/null
+++ b/doc/install/OSX/old_comments/comment_9_ae3ed5345bc84f57e44251d2e6c39342._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkwR9uOA38yi5kEUvcEWNtRiZwpxXskayE"
+ nickname="Agustin"
+ subject="For the moment"
+ date="2012-06-25T02:51:10Z"
+ content="""
+Hi Joey! I just comment that I could not install it but the issue is with the last version (the one you just release today, so no problem!! man on sunday?? you're awesome!!!) so I installed the previous one and no problem at all
+
+Thanks for all the efford and if you need me to try os whatever, feel free to ask!
+
+Thanks again
+
+Agustin
+"""]]
diff --git a/doc/install/OSX/old_comments/comment_9_c6b1b31d16f2144ad08abd8c767b6ab9._comment b/doc/install/OSX/old_comments/comment_9_c6b1b31d16f2144ad08abd8c767b6ab9._comment
new file mode 100644
index 000000000..faa7b1b43
--- /dev/null
+++ b/doc/install/OSX/old_comments/comment_9_c6b1b31d16f2144ad08abd8c767b6ab9._comment
@@ -0,0 +1,23 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnBEsNDl_6O4rHb2en3I0-fg-6fUxglaRQ"
+ nickname="chee"
+ subject="Recent install for OS X"
+ date="2012-11-13T04:40:05Z"
+ content="""
+if you are having trouble installing with `cabal install git-annex` at the moment, trouble of the XML kind, you'll need to do a couple things:
+
+`brew update`
+`brew install libxml2`
+`cabal update`
+`cabal install libxml --extra-include-dirs=/usr/local/Cellar/libxml2/2.8.0/include/libxml2 --extra-lib-dirs=/usr/local/Cellar/libxml2/2.8.0/lib`
+
+well, then i hit a brick wall.
+
+well.
+
+I got it to work by manually symlinking from `../Cellar/libxml2/2.8.0/lib/`* into `/usr/local` and from `../../Cellar/libxml2/2.8.0/lib/` to `/usr/local/pkgconfig`, but i can't recommend it or claim to be too proud about it all.
+
+OS X already has an old libxml knocking around so this might ruin everything for me.
+
+let's find out !
+"""]]
diff --git a/doc/install/ScientificLinux5.mdwn b/doc/install/ScientificLinux5.mdwn
new file mode 100644
index 000000000..52d83f0d9
--- /dev/null
+++ b/doc/install/ScientificLinux5.mdwn
@@ -0,0 +1,62 @@
+For SL6/CentOS6 install the EPEL repo and yum install git-annex.
+
+I was waiting for my backups to be done hence this article, as I was using
+_git-annex_ to manage my files and I decided I needed to have
+git-annex on a SL5 based machine. SL5 is just an opensource
+clone/recompile of RHEL5.
+
+I haven't tried to install the newer versions of Haskell Platform and
+GHC in a while on SL5 to install git-annex. But the last time I checked
+when GHC7 was out, it was a pain to install GHC on SL5.
+
+However I have discovered that someone has gone through the trouble of
+packaging up GHC and Haskell Platform for RHEL based distros.
+
+* <http://justhub.org/download> - Packaged GHC and Haskell Platform
+ RPM's for RHEL based systems.
+
+I'm primarily interested in installing _git-annex_ on SL5 based
+systems. The installation process goes as such...
+
+First install GHC and Haskell Platform (you need root for these
+following steps)
+
+ $ wget http://sherkin.justhub.org/el5/RPMS/x86_64/justhub-release-2.0-4.0.el5.x86_64.rpm
+ $ rpm -ivh justhub-release-2.0-4.0.el5.x86_64.rpm
+ $ yum install haskell
+
+The RPM's don't place the files in /usr/bin, so you must add the
+following to your .bashrc (from here on you don't need root if you
+don't want things to be system wide)
+
+ $ export PATH=/usr/hs/bin:$PATH
+
+Once the packages are installed and are in your execution path, using
+cabal to configure and build git-annex just makes life easier, it
+should install all the needed dependancies.
+
+ $ cabal update
+ $ git clone git://git.kitenet.net/git-annex
+ $ cd git-annex
+ $ make git-annex.1
+ $ cabal configure
+ $ cabal build
+ $ cabal install
+
+Or if you want to install it globallly for everyone (otherwise it will
+get installed into $HOME/.cabal/bin)
+
+ $ cabal install --global
+
+The above will take a while to compile and install the needed
+dependancies. I would suggest any user who does should run the tests
+that comes with git-annex to make sure everything is functioning as
+expected.
+
+I haven't had a chance or need to install git-annex on a SL6 based
+system yet, but I would assume something similar to the above steps
+would be required to do so.
+
+The above is almost a cut and paste of <http://jcftang.github.com/2012/06/15/installing-git-annex-on-sl5/>, the above could probably be refined, it was what worked for me on SL5. Please feel free to re-edit and chop out or add useless bits of text in the above!
+
+Note: from the minor testing, it appears the compiled binaries from SL5 will work on SL6.
diff --git a/doc/install/Ubuntu.mdwn b/doc/install/Ubuntu.mdwn
new file mode 100644
index 000000000..61b1489ff
--- /dev/null
+++ b/doc/install/Ubuntu.mdwn
@@ -0,0 +1,39 @@
+## Saucy
+
+ sudo apt-get install git-annex
+
+Warning: The version of git-annex shipped in Ubuntu Saucy had
+[a bug that can cause problems when creating repositories using the webapp](http://git-annex.branchable.com/bugs/Freshly_initialized_repo_has_staged_change___34__deleted:_uuid.log__34__/).
+
+## Raring
+
+ sudo apt-get install git-annex
+
+Note: This version is too old to include the [[assistant]] or its WebApp,
+but is otherwise usable.
+
+## Precise
+
+ sudo apt-get install git-annex
+
+Note: This version is too old to include the [[assistant]] or its WebApp,
+but is otherwise usable.
+
+## Precise PPA
+
+<https://launchpad.net/~fmarier/+archive/git-annex>
+
+A newer version of git-annex, including the [[assistant]] and WebApp.
+(Maintained by François Marier)
+
+ sudo add-apt-repository ppa:fmarier/git-annex
+ sudo apt-get update
+ sudo apt-get install git-annex
+
+## Oneiric
+
+ sudo apt-get install git-annex
+
+Warning: The version of git-annex shipped in Ubuntu Oneiric
+had [a bug that prevents upgrades from v1 git-annex repositories](https://bugs.launchpad.net/ubuntu/+source/git-annex/+bug/875958).
+If you need to upgrade such a repository, get a newer version of git-annex.
diff --git a/doc/install/Ubuntu/comment_10_490e065314693423ab6969d8ae6978fe._comment b/doc/install/Ubuntu/comment_10_490e065314693423ab6969d8ae6978fe._comment
new file mode 100644
index 000000000..d598adfba
--- /dev/null
+++ b/doc/install/Ubuntu/comment_10_490e065314693423ab6969d8ae6978fe._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkdiXn5s1wX2Zncy1S7_h-yPTv2gt0bmmY"
+ nickname="Jacob"
+ subject="comment 10"
+ date="2013-10-16T11:43:36Z"
+ content="""
+would be great to get the PPA updated with the latest git-annex; i'm finding synchronisation bugs (ie. updates made to word documents aren't replicated), and discovered its rather old now.
+"""]]
diff --git a/doc/install/Ubuntu/comment_11_4ebac3fb43de854ed1a3b1d2ea94011a._comment b/doc/install/Ubuntu/comment_11_4ebac3fb43de854ed1a3b1d2ea94011a._comment
new file mode 100644
index 000000000..68a889176
--- /dev/null
+++ b/doc/install/Ubuntu/comment_11_4ebac3fb43de854ed1a3b1d2ea94011a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="fmarier"
+ ip="207.134.53.206"
+ subject="Re: comment 10"
+ date="2013-10-16T13:43:37Z"
+ content="""
+Jacob: make sure you have the right URL for the PPA: https://launchpad.net/~fmarier/+archive/git-annex
+
+It used to be in my main PPA, now it's in a separate PPA by itself. The package was removed from the original PPA (hence it won't update) but is fully up to date in the new one.
+"""]]
diff --git a/doc/install/Ubuntu/comment_12_38f69dffe2db0d15e4c4e5cb47f40ef8._comment b/doc/install/Ubuntu/comment_12_38f69dffe2db0d15e4c4e5cb47f40ef8._comment
new file mode 100644
index 000000000..7cbf8c0ae
--- /dev/null
+++ b/doc/install/Ubuntu/comment_12_38f69dffe2db0d15e4c4e5cb47f40ef8._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmNu4V5fvpLlBhaCUfXXOB0MI5NXwh8SkU"
+ nickname="Adam"
+ subject="Raring?"
+ date="2013-11-01T20:28:04Z"
+ content="""
+I'm also on Raring and the latest version available is 3.20121112ubuntu4, nearly a year old. The PPA is only for Precise. The tarball is a daily snapshot, and I would much rather run a released version right now. What can I do? Can't the PPA be built automatically for Raring and Saucy?
+"""]]
diff --git a/doc/install/Ubuntu/comment_1_d1c511153fe94bf33e19a1281f1c92f2._comment b/doc/install/Ubuntu/comment_1_d1c511153fe94bf33e19a1281f1c92f2._comment
new file mode 100644
index 000000000..3b48bb406
--- /dev/null
+++ b/doc/install/Ubuntu/comment_1_d1c511153fe94bf33e19a1281f1c92f2._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkx5V3MTbzCXS3J7Mn9FEq8M9bPPYMkAHY"
+ nickname="Pedro"
+ subject="comment 1"
+ date="2013-05-20T15:53:25Z"
+ content="""
+Note that the fmarier ppa includes more than just git-annex. I've asked the author if he could segregate git-annex into a separate ppa.
+"""]]
diff --git a/doc/install/Ubuntu/comment_2_ad13886c1c1f76d1cd995ea7b7d8471c._comment b/doc/install/Ubuntu/comment_2_ad13886c1c1f76d1cd995ea7b7d8471c._comment
new file mode 100644
index 000000000..2d8221be1
--- /dev/null
+++ b/doc/install/Ubuntu/comment_2_ad13886c1c1f76d1cd995ea7b7d8471c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlQ7ZdQxAps4v0cl5J3wKGWD8243Gy8-m0"
+ nickname="Phil"
+ subject="PPA Package Pinning"
+ date="2013-05-23T21:18:14Z"
+ content="""
+@Pedro, see <http://askubuntu.com/a/170265> for blocking all packages except git-annex from François's repo.
+"""]]
diff --git a/doc/install/Ubuntu/comment_3_a08817322739b03cf0fec97283b16f1a._comment b/doc/install/Ubuntu/comment_3_a08817322739b03cf0fec97283b16f1a._comment
new file mode 100644
index 000000000..6d47d49be
--- /dev/null
+++ b/doc/install/Ubuntu/comment_3_a08817322739b03cf0fec97283b16f1a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://openid.fmarier.org/"
+ nickname="fmarier"
+ subject="New PPA only contains git-annex"
+ date="2013-06-15T07:45:13Z"
+ content="""
+As Pedro suggested, I've moved my git-annex backport to a separate PPA with only git-annex and the 220 Haskell packages it depends on.
+"""]]
diff --git a/doc/install/Ubuntu/comment_4_fe0997e56136bd30749f0995cbf19b56._comment b/doc/install/Ubuntu/comment_4_fe0997e56136bd30749f0995cbf19b56._comment
new file mode 100644
index 000000000..04992f31e
--- /dev/null
+++ b/doc/install/Ubuntu/comment_4_fe0997e56136bd30749f0995cbf19b56._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmhGq_ii5HaDkp9nx2m9qIMe-xxI4HV5wo"
+ nickname="Jeff"
+ subject="Packages way out of date"
+ date="2013-07-27T19:02:38Z"
+ content="""
+I'm setting up git-annex for myself (wanting to use the assistant to build myself a replacement for dropbox/box/ownCloud, etc.) and I installed the ubuntu package. Unfortunately, it is way out of date (3.20120406: amd64 i386). I didn't think to check the version. It's deceiving as the UI's are all the same, but it doesn't seem to work at all (syncing fails to remote servers, odd things happen with symlinking files to git object files, changing file permissions).
+
+It gives a bad first intro into git-annex on ubuntu (*nix?) machines. It might be best just to point people at the cabal install for now so we get the lastest and greatest.
+
+Anyway, thanks for the great tool, I'm looking forward to using it.
+"""]]
diff --git a/doc/install/Ubuntu/comment_5_fbb5306a162db1a1ee9efa3523aac952._comment b/doc/install/Ubuntu/comment_5_fbb5306a162db1a1ee9efa3523aac952._comment
new file mode 100644
index 000000000..fc525af96
--- /dev/null
+++ b/doc/install/Ubuntu/comment_5_fbb5306a162db1a1ee9efa3523aac952._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.110"
+ subject="comment 5"
+ date="2013-07-27T20:12:33Z"
+ content="""
+Jeff, AFAIK the 3.20120406 in precise does not include the assistant at all. The Precise PPA is well up-to-date.
+I don't think git-annex has anyone in Ubuntu updating the package, so it's whatever version is synced periodically from Debian.
+
+(AFAICS, all the problems Jeff had were due to manually creating an indirect mode repository when he expected direct mode.)
+"""]]
diff --git a/doc/install/Ubuntu/comment_6_a97e7f0e62ac685c3ded423bddeaa67f._comment b/doc/install/Ubuntu/comment_6_a97e7f0e62ac685c3ded423bddeaa67f._comment
new file mode 100644
index 000000000..3f9a2fd19
--- /dev/null
+++ b/doc/install/Ubuntu/comment_6_a97e7f0e62ac685c3ded423bddeaa67f._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmhGq_ii5HaDkp9nx2m9qIMe-xxI4HV5wo"
+ nickname="Jeff"
+ subject="comment 6"
+ date="2013-07-27T21:51:11Z"
+ content="""
+Ah, does it only have the webapp? I was able to boot the webapp and see messages, and it looked mostly the same, I assumed it was broken since no syncing was happening, but that would be due to the assistant not being there.
+
+I guess it's hard as a new user that goes straight for the easy/out-of-the box solution, via the assistant, after watching your video on it. I just assumed things were broken since I was seeing slightly different things. I didn't understand that the assistant was separate from the webapp (and was missing).
+
+Maybe mentioning the minimum required version on the assistant page to at least prompt users to check the version they're getting? I assumed following the link to the install guide, and installing the package for Ubuntu, would give me what I needed.
+
+
+"""]]
diff --git a/doc/install/Ubuntu/comment_7_921a223fd7e679b9ced3d8ba5ce688e0._comment b/doc/install/Ubuntu/comment_7_921a223fd7e679b9ced3d8ba5ce688e0._comment
new file mode 100644
index 000000000..2cc1f6652
--- /dev/null
+++ b/doc/install/Ubuntu/comment_7_921a223fd7e679b9ced3d8ba5ce688e0._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmhGq_ii5HaDkp9nx2m9qIMe-xxI4HV5wo"
+ nickname="Jeff"
+ subject="comment 7"
+ date="2013-07-27T21:53:45Z"
+ content="""
+I see how I missed this page too. I just saw the `apt-get install git-annex` and didn't even register Ubuntu as a link with more information.
+"""]]
diff --git a/doc/install/Ubuntu/comment_8_1f943cb084fa8e21bc6ee5fc3118f02f._comment b/doc/install/Ubuntu/comment_8_1f943cb084fa8e21bc6ee5fc3118f02f._comment
new file mode 100644
index 000000000..d51ac5345
--- /dev/null
+++ b/doc/install/Ubuntu/comment_8_1f943cb084fa8e21bc6ee5fc3118f02f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.110"
+ subject="comment 8"
+ date="2013-07-27T21:53:57Z"
+ content="""
+The webapp is part of the assistant. I was told Precise didn't have it, but IIRC they were working on fixing that build, and perhaps that has happened now.
+"""]]
diff --git a/doc/install/Ubuntu/comment_9_c2f8b35ada873acb1ce593b04e2899fe._comment b/doc/install/Ubuntu/comment_9_c2f8b35ada873acb1ce593b04e2899fe._comment
new file mode 100644
index 000000000..828b80e39
--- /dev/null
+++ b/doc/install/Ubuntu/comment_9_c2f8b35ada873acb1ce593b04e2899fe._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://openid.stackexchange.com/user/2eeca722-8d1c-41fe-8fda-13af7eaff6ae"
+ nickname="Diggory"
+ subject="Outdated in 13.04"
+ date="2013-10-08T16:36:10Z"
+ content="""
+13.04 Raring also has fairly outdated packages: 3.20121112ubuntu4
+Is there a PPA or some such for this? I suppose since Saucy will be out soon this is less critical, but would still be useful.
+
+These don't have direct mode, which (I think; I haven't tested it yet) is the feature I've been waiting for.
+"""]]
diff --git a/doc/install/Windows.mdwn b/doc/install/Windows.mdwn
new file mode 100644
index 000000000..74017d699
--- /dev/null
+++ b/doc/install/Windows.mdwn
@@ -0,0 +1,34 @@
+git-annex has recently been ported to Windows!
+
+* First, [install git](http://git-scm.com/downloads)
+* Then, [install git-annex](https://downloads.kitenet.net/git-annex/windows/current/)
+
+This port is in an early state. While it works well enough to use
+git-annex, many things will not work. See [[todo/windows_support]] for
+current status. Note especially that git-annex always uses [[direct_mode]]
+on Windows.
+
+The autobuilder is not currently able to run the test suite, so
+testing git-annex on Windows is up to you! To check that the build of
+git-annex works in your Windows system, you are encouraged to run the test
+suite before using git-annex on real data. After installation, run `git
+annex test`. There will be a lot of output; the important thing is that it
+should end with "All tests ok".
+
+## autobuilds
+
+A daily build is also available, thanks to Yury V. Zaytsev and
+[NEST](http://nest-initiative.org/).
+
+* [download](https://qa.nest-initiative.org/view/msysGit/job/msysgit-git-annex-assistant-test/lastSuccessfulBuild/artifact/git-annex/git-annex-installer.exe) ([build logs](https://qa.nest-initiative.org/view/msysGit/job/msysgit-git-annex-assistant-test/))
+
+## building it yourself
+
+To build git-annex from source on Windows, you need to install
+the Haskell Platform, Mingw, and Cygwin. Use Cygwin to install
+gcc, rsync, git, wget, ssh, and gnupg. To build the git-annex installer,
+you also need to install the NulSoft installer system.
+
+There is a shell script `standalone/windows/build.sh` that can be
+used to build git-annex. Note that this shell script cannot be run
+in Cygwin; run it with the Mingw sh.
diff --git a/doc/install/cabal.mdwn b/doc/install/cabal.mdwn
new file mode 100644
index 000000000..3270dd0f9
--- /dev/null
+++ b/doc/install/cabal.mdwn
@@ -0,0 +1,58 @@
+As a haskell package, git-annex can be installed using cabal.
+
+This involves building a lot of haskell packages from source, and so it has
+a lot of moving parts, and it's not uncommon for it to be broken from time
+to time.
+
+If you are not comfortable tracking down and dealing with library build
+problems, installing git-annex with cabal is probably not the right choice
+for you!
+
+## prerequisites
+
+Start by installing the [Haskell Platform][]. In Debian, this is as
+simple as:
+
+ sudo apt-get install haskell-platform
+
+ [Haskell Platform]: http://hackage.haskell.org/platform/
+
+## minimal build
+
+This builds git-annex without some features that require C libraries, that
+can be harder to get installed. This is plenty to get started using it,
+although it does not include the assistant or webapp.
+
+ cabal update
+ PATH=$HOME/bin:$PATH
+ cabal install git-annex --bindir=$HOME/bin -f"-assistant -webapp -webdav -pairing -xmpp -dns"
+
+## full build
+
+To build with all features enabled, including the assistant and webapp,
+you will need to install several C libraries and their headers,
+including libgnutls, libgsasl, libxml2, and zlib. Then run:
+
+ cabal update
+ PATH=$HOME/bin:$PATH
+ cabal install c2hs --bindir=$HOME/bin
+ cabal install git-annex --bindir=$HOME/bin
+
+## building from git checkout
+
+But maybe you want something newer (or older). Then [[download]] the version
+you want, and use cabal as follows inside its source tree:
+
+ cabal update
+ PATH=$HOME/bin:$PATH
+ cabal install c2hs --bindir=$HOME/bin
+ cabal install --only-dependencies
+ cabal configure
+ cabal build
+ cabal install --bindir=$HOME/bin
+
+## EKG
+
+When building with cabal, you can optionally enable the
+[[EKG monitoring interface|ekg]]. This is great for debugging resource
+usage problems.
diff --git a/doc/install/cabal/comment_10_7ebe353b05d4df29897dc9a4f45c8a91._comment b/doc/install/cabal/comment_10_7ebe353b05d4df29897dc9a4f45c8a91._comment
new file mode 100644
index 000000000..5b813baba
--- /dev/null
+++ b/doc/install/cabal/comment_10_7ebe353b05d4df29897dc9a4f45c8a91._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.110"
+ subject="comment 10"
+ date="2013-07-27T17:49:07Z"
+ content="""
+@Henning; see the [[OSX]] page for full installation instructions for OSX. Which include all the neccesary brew incantations.
+"""]]
diff --git a/doc/install/cabal/comment_11_0d06702e6e0ae3cd331cf748a9f6f273._comment b/doc/install/cabal/comment_11_0d06702e6e0ae3cd331cf748a9f6f273._comment
new file mode 100644
index 000000000..94919710f
--- /dev/null
+++ b/doc/install/cabal/comment_11_0d06702e6e0ae3cd331cf748a9f6f273._comment
@@ -0,0 +1,44 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlXEIT2PEAuHuInLP4UYVzWE0lceMYd2lA"
+ nickname="Gregor"
+ subject="Installation on tonidoplug"
+ date="2013-08-03T07:19:54Z"
+ content="""
+I tried various ways to install git-annex on my [TonidoPlug](http://www.tonidoplug.com/).
+
+System Info:
+
+ root@TonidoPlug2:~# uname -a
+ Linux TonidoPlug2 2.6.31.8-topkick1281p2-001-004-20101214 #1 Thu Jun 16 10:06:20 CST 2011 armv5tel GNU/Linux
+
+`apt-get` didn't work.
+
+ root@TonidoPlug2:~# apt-get install git-annex
+ Reading package lists... Done
+ Building dependency tree
+ Reading state information... Done
+ E: Unable to locate package git-annex
+
+The Linux standalone installation results in an error message like this, when calling `git-annex` (or `git annex`)
+
+ ~$ git-annex.linux/git-annex
+ /home/gitolite/git-annex.linux/bin/git-annex: 1: Syntax error: \")\" unexpected
+
+(git-annex.linux/bin/git-annex is a binary file and works fine on other distros)
+
+When installing with cabal, I get the error message (tried as root and gitolite user)
+
+ ~$ cabal install git-annex --bindir=$HOME/bin -f\"-assistant -webapp -webdav -pairing -xmpp -dns\"
+ Resolving dependencies...
+ cabal: cannot configure git-annex-4.20130802. It requires base >=4.5 && <4.8
+ For the dependency on base >=4.5 && <4.8 there are these packages:
+ base-4.5.0.0, base-4.5.1.0, base-4.6.0.0 and base-4.6.0.1. However none of
+ them are available.
+ base-4.5.0.0 was excluded because of the top level dependency base -any
+ base-4.5.1.0 was excluded because of the top level dependency base -any
+ base-4.6.0.0 was excluded because of the top level dependency base -any
+ base-4.6.0.1 was excluded because of the top level dependency base -any
+
+Any help is appreciated.
+Thanks for providing git-annex. I started cleaning up my backups with it yesterday and really like it.
+"""]]
diff --git a/doc/install/cabal/comment_12_b93ca271dffca3f948645d3e1326c1d9._comment b/doc/install/cabal/comment_12_b93ca271dffca3f948645d3e1326c1d9._comment
new file mode 100644
index 000000000..8d9c97898
--- /dev/null
+++ b/doc/install/cabal/comment_12_b93ca271dffca3f948645d3e1326c1d9._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 12"
+ date="2013-08-07T16:31:30Z"
+ content="""
+The Linux standalone builds for i386 and amd64 will not work on Arm systems.
+
+There are builds of git-annex for arm in eg, Debian. You should be able to use one of those if this system is running Debian. You may need to upgrade to eg, Debian stable, which includes git-annex.
+
+It looks like you have an old and/or broken GHC compiler too. You could upgrade that to a newer version (eg from Debian stable) and build it that way, but it seems like the long way around if you have a Debian system there.
+"""]]
diff --git a/doc/install/cabal/comment_13_3dac019cda71bf99878c0a1d9382323b._comment b/doc/install/cabal/comment_13_3dac019cda71bf99878c0a1d9382323b._comment
new file mode 100644
index 000000000..80e3a6ad1
--- /dev/null
+++ b/doc/install/cabal/comment_13_3dac019cda71bf99878c0a1d9382323b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlXEIT2PEAuHuInLP4UYVzWE0lceMYd2lA"
+ nickname="Gregor"
+ subject="TonidoPlug"
+ date="2013-08-09T17:46:28Z"
+ content="""
+@Joey Thanks for the answer. I didn't want to mess around too much with the TonidoPlug. I am currently setting up a raspberry pi, which works fine.
+"""]]
diff --git a/doc/install/cabal/comment_14_14b46470593f84f8c3768a91cb77bdab._comment b/doc/install/cabal/comment_14_14b46470593f84f8c3768a91cb77bdab._comment
new file mode 100644
index 000000000..93fca1653
--- /dev/null
+++ b/doc/install/cabal/comment_14_14b46470593f84f8c3768a91cb77bdab._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlfIVXjkzrYE9qJAO2A0H7K6tKGMaSgc3U"
+ nickname="Daniel"
+ subject="Problems with cryptocipher"
+ date="2013-08-22T01:36:50Z"
+ content="""
+I had problems following these directions on recent releases of Fedora/Ubuntu. The install attempts failed on cryptocipher-0.3.1, which I think came as a dependency of Yesod.
+I was able to work around this by installing yesod-platform with cabal first, then installing git-annex.
+"""]]
diff --git a/doc/install/cabal/comment_15_c3a5b0aad28a90e0bb8da31a430578eb._comment b/doc/install/cabal/comment_15_c3a5b0aad28a90e0bb8da31a430578eb._comment
new file mode 100644
index 000000000..fc64af234
--- /dev/null
+++ b/doc/install/cabal/comment_15_c3a5b0aad28a90e0bb8da31a430578eb._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="RaspberryPie"
+ ip="77.247.181.162"
+ subject="git-annex assistant on Arm"
+ date="2013-08-23T03:07:11Z"
+ content="""
+I'd like to use the assistant's power on a Raspberry Pi to build an always-on file/sync server. Is there a way to get the assistant running on Arm? I know there's a Debian package, but it's Version 3.20120629 and comes without the assistant. Has anyone ever successfully built a recent git-annex version on Arm? What would I need in order to do it myself?
+"""]]
diff --git a/doc/install/cabal/comment_16_4faf214f97f9516898d7c17d743ef825._comment b/doc/install/cabal/comment_16_4faf214f97f9516898d7c17d743ef825._comment
new file mode 100644
index 000000000..be14b3908
--- /dev/null
+++ b/doc/install/cabal/comment_16_4faf214f97f9516898d7c17d743ef825._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 16"
+ date="2013-08-23T17:37:52Z"
+ content="""
+The git-annex assistant can easily be built on arm. But not the webapp. It's entirely possible to use the assistant without the webapp though; you just have to make the git repository and configure the remotes by hand, and then the assistant will sync them the same way the webapp does.
+
+It is possible but very involved to build the webapp for arm. I do not anticipate doing it in the Debian package until ghc gets proper template haskell support for arm. See [[forum/Webapp_on_ARM]]
+"""]]
diff --git a/doc/install/cabal/comment_17_2a9d6807a3a13815c824985521757167._comment b/doc/install/cabal/comment_17_2a9d6807a3a13815c824985521757167._comment
new file mode 100644
index 000000000..c0b570dfb
--- /dev/null
+++ b/doc/install/cabal/comment_17_2a9d6807a3a13815c824985521757167._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="RaspberryPie"
+ ip="77.247.181.162"
+ subject="comment 17"
+ date="2013-08-23T18:51:51Z"
+ content="""
+Thanks for the quick answer. I will try to build git-annex with just the assistant, as you suggest, and once it works set up the server by hand as you suggest.
+
+BTW: Awesome job you're doing with git-annex. I appreciate your enthusiasm.
+"""]]
diff --git a/doc/install/cabal/comment_18_1efa0c7a963ec452fc6336fbe4964f6e._comment b/doc/install/cabal/comment_18_1efa0c7a963ec452fc6336fbe4964f6e._comment
new file mode 100644
index 000000000..e3a523e22
--- /dev/null
+++ b/doc/install/cabal/comment_18_1efa0c7a963ec452fc6336fbe4964f6e._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="RaspberryPie"
+ ip="96.47.226.20"
+ subject="git-annex assistant for the Raspberry Pi"
+ date="2013-09-04T03:58:37Z"
+ content="""
+It took a while and a few tries, but I finally built the git-annex binary including the assistant on a Raspberry Pi. The build comes without the flags webapp, webdav, and dbus as these rely on a Template Haskell compiler that hasn't been ported to Arm architecture yet.
+
+I put the binary up on Github in case anyone's interested: <https://github.com/tradloff/git-annex-RPi>
+"""]]
diff --git a/doc/install/cabal/comment_19_6f42f9234f9ff6a2ca6bbb4d2643843e._comment b/doc/install/cabal/comment_19_6f42f9234f9ff6a2ca6bbb4d2643843e._comment
new file mode 100644
index 000000000..27a3e8c62
--- /dev/null
+++ b/doc/install/cabal/comment_19_6f42f9234f9ff6a2ca6bbb4d2643843e._comment
@@ -0,0 +1,44 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlu7K3h7Ry1uDAU_ERYGuqt0LoGNJqGuRo"
+ nickname="Nathan"
+ subject="Cabal installing git-annex on Ubuntu 12.04 Precise with GHC 7.6.3"
+ date="2013-09-25T22:39:04Z"
+ content="""
+I now realize [there is a Ubuntu 12.04 Precise PPA with a current
+version of
+git-annex](http://git-annex.branchable.com/install/Ubuntu/), so that's
+probably a better choice, but here's how I cabal isntalled git-annex.
+
+1. Apt install non-cabal dependencies:
+
+ sudo aptitude install c2hs libgsasl7-dev libxml2-dev
+
+2. Manually cabal install yesod-platform to avoid the [cryptocipher problem
+ mentioned above](
+ http://git-annex.branchable.com/install/cabal/#comment-1807da37dc144b572b76aaf4b574bb54):
+
+ cabal install yesod-platform
+
+3. Cabal install git-annex with DNS flag disabled:
+
+ cabal install git-annex -f\"-dns\"
+
+I was getting this error building git-annex before disabling the DNS flag:
+
+ Utility/SRV.hs:70:54:
+ Couldn't match expected type `Maybe
+ [(Int, Int, Integer, B8.ByteString)]'
+ with actual type `Either
+ dns-1.0.0:Network.DNS.Internal.DNSError
+ [(Int, Int, Int, dns-1.0.0:Network.DNS.Internal.Domain)]'
+ In the third argument of `maybe', namely `r'
+ In the second argument of `($)', namely
+ `maybe [] (orderHosts . map tohosts) r'
+ In a stmt of a 'do' block:
+ return $ maybe [] (orderHosts . map tohosts) r
+
+Looking at Utiltity/SRV.hs, it appears that disabling the DNS flag
+just makes git annex use a different DNS library (ADNS), not
+actually disable DNS lookups.
+
+"""]]
diff --git a/doc/install/cabal/comment_1_f04df6bcd50d1d01eb34868bb00ac35c._comment b/doc/install/cabal/comment_1_f04df6bcd50d1d01eb34868bb00ac35c._comment
new file mode 100644
index 000000000..b280d3d3d
--- /dev/null
+++ b/doc/install/cabal/comment_1_f04df6bcd50d1d01eb34868bb00ac35c._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlJemqsekZTC5dvc-MAByUWaBvsYE-mFUo"
+ nickname="Gábor"
+ subject="Cabal dependencies"
+ date="2013-05-12T12:52:20Z"
+ content="""
+After finishing the installation the cabal way, here are the packages I installed. It is possible that there are other packages I installed previously as dependency for other packages.
+
+ $ lsb_release -a
+ No LSB modules are available.
+ Distributor ID: Ubuntu
+ Description: Ubuntu 12.04.2 LTS
+ Release: 12.04
+ Codename: precise
+
+ $ apt-get install cabal-install libgnutls28-dev libgsasl7-dev c2hs libghc-libxml-sax-dev zlib1g-dev libghc-zlib-dev
+ $ cabal install git-annex --bindir=$HOME/bin
+"""]]
diff --git a/doc/install/cabal/comment_20_0f553be2a4c666e3bed58b2bce549406._comment b/doc/install/cabal/comment_20_0f553be2a4c666e3bed58b2bce549406._comment
new file mode 100644
index 000000000..288c0e017
--- /dev/null
+++ b/doc/install/cabal/comment_20_0f553be2a4c666e3bed58b2bce549406._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlkA6XinbeOdnEDxEGQUWyjqPGh0kdMXr4"
+ nickname="Blake"
+ subject="Updating git-annex via cabal"
+ date="2013-10-09T21:21:22Z"
+ content="""
+What is the best way to update git-annex and the dependencies via cabal? Just the `$ cabal install *` commands again?
+"""]]
diff --git a/doc/install/cabal/comment_21_f91a6ec21e96eced73ea9579fd8cbd15._comment b/doc/install/cabal/comment_21_f91a6ec21e96eced73ea9579fd8cbd15._comment
new file mode 100644
index 000000000..ef8a3d2a3
--- /dev/null
+++ b/doc/install/cabal/comment_21_f91a6ec21e96eced73ea9579fd8cbd15._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.22"
+ subject="comment 21"
+ date="2013-10-11T17:09:33Z"
+ content="""
+If you run the \"cabal update\" command followed by the \"cabal install\" command it'll upgrade git-annex.
+"""]]
diff --git a/doc/install/cabal/comment_22_2f27b78215f97ade1986ca806c634cb3._comment b/doc/install/cabal/comment_22_2f27b78215f97ade1986ca806c634cb3._comment
new file mode 100644
index 000000000..d7ff05617
--- /dev/null
+++ b/doc/install/cabal/comment_22_2f27b78215f97ade1986ca806c634cb3._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="RaspberryPie"
+ ip="96.44.189.100"
+ subject="&quot;Could not find module Crypto.Hash&quot; error when building git-annex "
+ date="2013-10-21T19:55:12Z"
+ content="""
+Lately I get this error message when trying to build git-annex-v4.20131002:
+
+ Utility/Hash.hs:7:8:
+ Could not find module `Crypto.Hash'
+ Perhaps you meant
+ Crypto.HMAC (needs flag -package crypto-api-0.10.2)
+ Use -v to see a list of the files searched for.
+
+crypto-api-0.10.2 is installed as a debian dev package. All the dependencies are met. I have no idea what's going on.
+"""]]
diff --git a/doc/install/cabal/comment_23_c34d2b1d95830a3e58671a5b566a1758._comment b/doc/install/cabal/comment_23_c34d2b1d95830a3e58671a5b566a1758._comment
new file mode 100644
index 000000000..03a5b87ce
--- /dev/null
+++ b/doc/install/cabal/comment_23_c34d2b1d95830a3e58671a5b566a1758._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="64.134.31.139"
+ subject="comment 23"
+ date="2013-10-21T22:09:05Z"
+ content="""
+git-annex needs cryptohash version 0.10.0 or greater. You appear to have an old version. You can cabal `configure -f-CryptoHash` if it's for some reason failing to disable the cryptohash support despite the declared dependency not being met.
+"""]]
diff --git a/doc/install/cabal/comment_24_40cbde8ec067b3a860e6df1a9bea5f76._comment b/doc/install/cabal/comment_24_40cbde8ec067b3a860e6df1a9bea5f76._comment
new file mode 100644
index 000000000..3bb160546
--- /dev/null
+++ b/doc/install/cabal/comment_24_40cbde8ec067b3a860e6df1a9bea5f76._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="RaspberryPie"
+ ip="37.130.227.133"
+ subject="comment 24"
+ date="2013-10-22T17:55:32Z"
+ content="""
+I fixed the error by installing a newer version of cryptohash. Thanks for pointing out the culprit.
+"""]]
diff --git a/doc/install/cabal/comment_25_8a7664e6f9271718dc607a0782366c5b._comment b/doc/install/cabal/comment_25_8a7664e6f9271718dc607a0782366c5b._comment
new file mode 100644
index 000000000..929956ede
--- /dev/null
+++ b/doc/install/cabal/comment_25_8a7664e6f9271718dc607a0782366c5b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="RaspberryPie"
+ ip="141.138.141.208"
+ subject="Bad version on Hackage"
+ date="2013-10-30T18:56:25Z"
+ content="""
+Quick note: The latest version in the Hackage repository (git-annex-4.20131024) fails to build, due to a faulty version of Assistant/Threads/Cronner.hs.
+"""]]
diff --git a/doc/install/cabal/comment_26_bd455c732639728bce2bfc39e32871d2._comment b/doc/install/cabal/comment_26_bd455c732639728bce2bfc39e32871d2._comment
new file mode 100644
index 000000000..5b1f06023
--- /dev/null
+++ b/doc/install/cabal/comment_26_bd455c732639728bce2bfc39e32871d2._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 26"
+ date="2013-11-01T16:33:25Z"
+ content="""
+@RaspberryPie that only affected builds without the webapp, in any case it's fixed now.
+"""]]
diff --git a/doc/install/cabal/comment_27_c080e9239b6eec88d329c28da7bb4141._comment b/doc/install/cabal/comment_27_c080e9239b6eec88d329c28da7bb4141._comment
new file mode 100644
index 000000000..4c007c9ad
--- /dev/null
+++ b/doc/install/cabal/comment_27_c080e9239b6eec88d329c28da7bb4141._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="RaspberryPie"
+ ip="37.221.160.203"
+ subject="comment 27"
+ date="2013-11-02T12:52:18Z"
+ content="""
+Okay, the error doesn't show up anymore. I didn't even get to Cronner though, because this time I got a different error:
+
+ Assistant/Alert.hs:195:20:
+ Couldn't match expected type `Assistant ()' with actual type `()'
+ Expected type: Maybe Remote -> Assistant ()
+ Actual type: Maybe Remote -> ()
+ In the expression: noop
+ In an equation for `notFsckedNudge': notFsckedNudge _ = noop
+
+This is from trying to compile 4.20131101 with `-f\"-webapp -webdav\"`
+"""]]
diff --git a/doc/install/cabal/comment_28_15951dd070a675300420eea137a28ef9._comment b/doc/install/cabal/comment_28_15951dd070a675300420eea137a28ef9._comment
new file mode 100644
index 000000000..19a570cae
--- /dev/null
+++ b/doc/install/cabal/comment_28_15951dd070a675300420eea137a28ef9._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 28"
+ date="2013-11-02T17:40:18Z"
+ content="""
+Unfortunate about that. I've fixed it in git.
+
+(It would be best to file bug reports about build failures to avoid cluttering up this page.)
+"""]]
diff --git a/doc/install/cabal/comment_29_ac082dca67f4a29b06070c0283130f52._comment b/doc/install/cabal/comment_29_ac082dca67f4a29b06070c0283130f52._comment
new file mode 100644
index 000000000..524a0db0c
--- /dev/null
+++ b/doc/install/cabal/comment_29_ac082dca67f4a29b06070c0283130f52._comment
@@ -0,0 +1,39 @@
+[[!comment format=mdwn
+ username="robohack"
+ ip="24.67.98.78"
+ subject="cabal install failing due to problems building pcre-light-0.4"
+ date="2013-11-21T20:17:10Z"
+ content="""
+After a fresh install of Haskell, and following the instructions above, I end up with the following rather bizarre and unexpected problem:
+
+ $ cabal install git-annex --bindir=$HOME/bin -f\"-assistant -webapp -webdav -pairing -xmpp -dns\"
+ Resolving dependencies...
+ Configuring pcre-light-0.4...
+ Building pcre-light-0.4...
+ Preprocessing library pcre-light-0.4...
+ Base.hsc:103:18: error: pcre.h: No such file or directory
+ Base.hsc: In function ‘main’:
+ Base.hsc:402: error: ‘PCRE_ANCHORED’ undeclared (first use in this function)
+ Base.hsc:402: error: (Each undeclared identifier is reported only once
+ Base.hsc:402: error: for each function it appears in.)
+ Base.hsc:405: error: ‘PCRE_AUTO_CALLOUT’ undeclared (first use in this function)
+
+(followed by an error for every other macro that was expected to be defined in the header...)
+
+ compiling dist/build/Text/Regex/PCRE/Light/Base_hsc_make.c failed (exit code 1)
+ command was: /usr/bin/gcc -c dist/build/Text/Regex/PCRE/Light/Base_hsc_make.c -o dist/build/Text/Regex/PCRE/Light/Base_hsc_make.o -m64 -fno-stack-protector -m64 -fno-stack-protector -m64 -D__GLASGOW_HASKELL__=700 -Ddarwin_BUILD_OS -Ddarwin_HOST_OS -Dx86_64_BUILD_ARCH -Dx86_64_HOST_ARCH -I/sw/lib/ghc-7.0.4/bytestring-0.9.1.10/include -Idist/build/autogen -include dist/build/autogen/cabal_macros.h -I/sw/lib/ghc-7.0.4/base-4.3.1.0/include -Idist/build/autogen -include dist/build/autogen/cabal_macros.h -Idist/build/autogen -include dist/build/autogen/cabal_macros.h -Idist/build/autogen -include dist/build/autogen/cabal_macros.h -I/sw/lib/ghc-7.0.4/include -Idist/build/autogen -include dist/build/autogen/cabal_macros.h -I/sw/lib/ghc-7.0.4/include -Idist/build/autogen -include dist/build/autogen/cabal_macros.h -I/sw/lib/ghc-7.0.4/include/
+ Failed to install pcre-light-0.4
+ cabal: Error: some packages failed to install:
+ git-annex-3.20120230 depends on pcre-light-0.4 which failed to install.
+ pcre-light-0.4 failed during the building phase. The exception was:
+ ExitFailure 1
+
+This is a somewhat older Mac OS X 10.6.8 system.
+
+I do have PCRE already installed via Fink, and pcre.h is in /sw/include. I see other -I/sw/... things in the compile command above, but obviously /sw/include is not one of them.
+
+Any clues for me?
+
+(Why the heck does git-annex need pcre in particular anyway??? I saw another regex library get installed earlier somewhere in this (massive) process.)
+
+"""]]
diff --git a/doc/install/cabal/comment_2_a69d17c55e56a707ec6606d5cdddee25._comment b/doc/install/cabal/comment_2_a69d17c55e56a707ec6606d5cdddee25._comment
new file mode 100644
index 000000000..5a7beea37
--- /dev/null
+++ b/doc/install/cabal/comment_2_a69d17c55e56a707ec6606d5cdddee25._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnaH44G3QbxBAYyDwy0PbvL0ls60XoaR3Y"
+ nickname="Nigel"
+ subject="E: Unable to locate package libghc-libxml-sax-dev"
+ date="2013-05-30T15:05:47Z"
+ content="""
+I get an error from the command as above:
+$ sudo apt-get install cabal-install libgnutls28-dev libgsasl7-dev c2hs libghc libxml-sax-dev zlib1g-dev libghc-zlib-dev
+
+$ lsb_release -a
+No LSB modules are available.
+Distributor ID: Ubuntu
+Description: Ubuntu 12.04.2 LTS
+Release: 12.04
+Codename: precise
+
+"""]]
diff --git a/doc/install/cabal/comment_30_ad639c07cb79e89406e95c1dafce3a01._comment b/doc/install/cabal/comment_30_ad639c07cb79e89406e95c1dafce3a01._comment
new file mode 100644
index 000000000..f068944b0
--- /dev/null
+++ b/doc/install/cabal/comment_30_ad639c07cb79e89406e95c1dafce3a01._comment
@@ -0,0 +1,35 @@
+[[!comment format=mdwn
+ username="robohack"
+ ip="24.67.98.78"
+ subject="hmmm... ok, the PCRE problem was odd, but now this:"
+ date="2013-11-21T20:30:54Z"
+ content="""
+The PCRE problem is solved trivially in my case with a couple more cabal install options, though the need for these seems oddly dissatisfying given the reams of other stuff that was successfully built and installed without these options.
+
+Now however I seem to have encountered a deeper problem:
+
+ $ cabal install git-annex --bindir=$HOME/bin --extra-include-dirs=/sw/include --extra-lib-dirs=/sw/lib
+ Resolving dependencies...
+ [1 of 1] Compiling Main ( /var/folders/7h/7hWHR5m8HPKOnUEvQU7HU++++TI/-Tmp-/git-annex-3.20120230-84797/git-annex-3.20120230/Setup.hs, /var/folders/7h/7hWHR5m8HPKOnUEvQU7HU++++TI/-Tmp-/git-annex-3.20120230-84797/git-annex-3.20120230/dist/setup/Main.o )
+ Linking /var/folders/7h/7hWHR5m8HPKOnUEvQU7HU++++TI/-Tmp-/git-annex-3.20120230-84797/git-annex-3.20120230/dist/setup/setup ...
+ hsc2hs Utility/StatFS.hsc
+ perl -i -pe 's/^{-# INCLUDE.*//' Utility/StatFS.hs
+ ghc -O2 -Wall -ignore-package monads-fd --make configure
+
+ Utility/StatFS.hsc:54:8:
+ Could not find module `GHC.Foreign':
+ Use -v to see a list of the files searched for.
+ make: *** [Build/SysConfig.hs] Error 1
+ Configuring git-annex-3.20120230...
+ Building git-annex-3.20120230...
+ Preprocessing executable 'git-annex' for git-annex-3.20120230...
+
+ Git/Version.hs:11:18:
+ Could not find module `Build.SysConfig':
+ Use -v to see a list of the files searched for.
+ Failed to install git-annex-3.20120230
+ cabal: Error: some packages failed to install:
+ git-annex-3.20120230 failed during the building phase. The exception was:
+ ExitFailure 1
+
+"""]]
diff --git a/doc/install/cabal/comment_31_4763b24a29627d55f465b9ea260ea7ec._comment b/doc/install/cabal/comment_31_4763b24a29627d55f465b9ea260ea7ec._comment
new file mode 100644
index 000000000..224c1dc19
--- /dev/null
+++ b/doc/install/cabal/comment_31_4763b24a29627d55f465b9ea260ea7ec._comment
@@ -0,0 +1,22 @@
+[[!comment format=mdwn
+ username="robohack"
+ ip="24.67.98.78"
+ subject="a different error trying to build from the git repo...."
+ date="2013-11-21T21:14:54Z"
+ content="""
+I'm using the ghc7.0 branch because Fink's GHC is still at 7.0.4....
+
+ $ cabal build
+ Building git-annex-3.20120523...
+ Preprocessing executable 'git-annex' for git-annex-3.20120523...
+ [ 78 of 163] Compiling Utility.Url ( Utility/Url.hs, dist/build/git-annex/git-annex-tmp/Utility/Url.o )
+
+ Utility/Url.hs:111:88:
+ Couldn't match expected type `Maybe URI' with actual type `URI'
+ In the second argument of `fromMaybe', namely
+ `(newURI `relativeTo` u)'
+ In the expression: fromMaybe newURI (newURI `relativeTo` u)
+ In an equation for `newURI_abs':
+ newURI_abs = fromMaybe newURI (newURI `relativeTo` u)
+
+"""]]
diff --git a/doc/install/cabal/comment_32_1d34c294486c85b1149675fa5861ae35._comment b/doc/install/cabal/comment_32_1d34c294486c85b1149675fa5861ae35._comment
new file mode 100644
index 000000000..8b2ae67f9
--- /dev/null
+++ b/doc/install/cabal/comment_32_1d34c294486c85b1149675fa5861ae35._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.64"
+ subject="comment 32"
+ date="2013-11-22T16:27:36Z"
+ content="""
+@robohack, the ghc7.0 branch is not being maintained, and is so old I don't recommend it. To build it against current cabal you will probably need to version its dependency on network to an older version than 2.4.0.
+
+Also, git-annex has not depended on pcre for a long time. But you're building thoroughly old version so get to trip over every bug that's been reported for the past 2 years..
+"""]]
diff --git a/doc/install/cabal/comment_3_55bed050bdb768543dbe1b86edec057d._comment b/doc/install/cabal/comment_3_55bed050bdb768543dbe1b86edec057d._comment
new file mode 100644
index 000000000..7a53b2b64
--- /dev/null
+++ b/doc/install/cabal/comment_3_55bed050bdb768543dbe1b86edec057d._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-05-30T15:25:29Z"
+ content="""
+If you're installing git-annex with cabal, there is no need to install any haskell library packages with apt-get. That includes libghc-libxml-sax-dev and libghc-zlib-dev. Without those, the apt-get line may work to install the C libraries needed for cabal to install the haskell libraries.
+
+However, see the the [[Ubuntu]] page for much easier ways to get git-annex installed.
+"""]]
diff --git a/doc/install/cabal/comment_4_2ff7f8a3b03bea7e860248829d595bd1._comment b/doc/install/cabal/comment_4_2ff7f8a3b03bea7e860248829d595bd1._comment
new file mode 100644
index 000000000..4a04303ce
--- /dev/null
+++ b/doc/install/cabal/comment_4_2ff7f8a3b03bea7e860248829d595bd1._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnaH44G3QbxBAYyDwy0PbvL0ls60XoaR3Y"
+ nickname="Nigel"
+ subject="Re: Comment 3"
+ date="2013-05-30T15:48:44Z"
+ content="""
+@Joey Many thanks.
+I am new to Haskell (vaguely looked at it with DARCS) and git-annex.
+After installing with apt-get on Ubuntu 12.04 LTS I found webapp was missing, hence have come here.
+I am going through the correct steps now, it should be awesome when done.
+
+This seems to be a long build process (still going on my old laptop, much longer than apt-get).
+Ubuntu git-annex packages from 13.10 Saucy I think are updated to include webapp.
+"""]]
diff --git a/doc/install/cabal/comment_5_8789fc27466714faa5a3a7a6b8ec6e5d._comment b/doc/install/cabal/comment_5_8789fc27466714faa5a3a7a6b8ec6e5d._comment
new file mode 100644
index 000000000..52606082e
--- /dev/null
+++ b/doc/install/cabal/comment_5_8789fc27466714faa5a3a7a6b8ec6e5d._comment
@@ -0,0 +1,24 @@
+[[!comment format=txt
+ username="https://www.google.com/accounts/o8/id?id=AItOawnaH44G3QbxBAYyDwy0PbvL0ls60XoaR3Y"
+ nickname="Nigel"
+ subject="Re: Comment 3"
+ date="2013-05-30T16:29:12Z"
+ content="""
+At the end of the build I got these errors:
+Registering yesod-static-1.1.2.3...
+Installing library in /home/nrb/.cabal/lib/yesod-static-1.1.2.3/ghc-7.4.1
+Registering yesod-static-1.1.2.3...
+cabal: Error: some packages failed to install:
+c2hs-0.16.4 depends on language-c-0.3.2.1 which failed to install.
+dbus-0.10.4 depends on libxml-sax-0.7.4 which failed to install.
+git-annex-4.20130521.2 depends on libxml-sax-0.7.4 which failed to install.
+language-c-0.3.2.1 failed during the configure step. The exception was:
+ExitFailure 1
+libxml-sax-0.7.4 failed during the configure step. The exception was:
+ExitFailure 1
+network-protocol-xmpp-0.4.5 depends on libxml-sax-0.7.4 which failed to
+install.
+
+One way I could fix this myself is to put together a VM with 13.10 or Debian in it and work inside that.
+Or if I can get help to fix my issues here that would be great ;)
+"""]]
diff --git a/doc/install/cabal/comment_6_5afb2d081e8b603bc338cd460ad9317d._comment b/doc/install/cabal/comment_6_5afb2d081e8b603bc338cd460ad9317d._comment
new file mode 100644
index 000000000..1ff7b4f76
--- /dev/null
+++ b/doc/install/cabal/comment_6_5afb2d081e8b603bc338cd460ad9317d._comment
@@ -0,0 +1,21 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnaH44G3QbxBAYyDwy0PbvL0ls60XoaR3Y"
+ nickname="Nigel"
+ subject="Some errors after the build"
+ date="2013-05-30T16:38:37Z"
+ content="""
+ Registering yesod-static-1.1.2.3...
+ Installing library in /home/nrb/.cabal/lib/yesod-static-1.1.2.3/ghc-7.4.1
+ Registering yesod-static-1.1.2.3...
+ cabal: Error: some packages failed to install:
+ c2hs-0.16.4 depends on language-c-0.3.2.1 which failed to install.
+ dbus-0.10.4 depends on libxml-sax-0.7.4 which failed to install.
+ git-annex-4.20130521.2 depends on libxml-sax-0.7.4 which failed to install.
+ language-c-0.3.2.1 failed during the configure step. The exception was:
+ ExitFailure 1
+ libxml-sax-0.7.4 failed during the configure step. The exception was:
+ ExitFailure 1
+ network-protocol-xmpp-0.4.5 depends on libxml-sax-0.7.4 which failed to
+ install.
+
+"""]]
diff --git a/doc/install/cabal/comment_7_129c4f2e404c874e5adfa52902a81104._comment b/doc/install/cabal/comment_7_129c4f2e404c874e5adfa52902a81104._comment
new file mode 100644
index 000000000..40b202d4e
--- /dev/null
+++ b/doc/install/cabal/comment_7_129c4f2e404c874e5adfa52902a81104._comment
@@ -0,0 +1,22 @@
+[[!comment format=mdwn
+ username="krig"
+ ip="46.194.28.123"
+ subject="Could not resolve dependencies for yesod"
+ date="2013-06-25T06:14:18Z"
+ content="""
+I'm having problems installing from cabal, and it seems related to yesod. I found an older discussion on something similar, where a constraint to require a newer version of yesod had been added, but I haven't figured out what was done to solve it.
+
+The problem seems to be that git-annex requires yesod < 1.2, but cabal is unable to install an older version.
+
+ $ cabal install git-annex --bindir=$HOME/bin
+ Resolving dependencies...
+ cabal: Could not resolve dependencies:
+ trying: git-annex-4.20130601
+ trying: git-annex-4.20130601:+webapp
+ rejecting: yesod-1.2.1.1, 1.2.1, 1.2.0.1, 1.2.0 (conflict:
+ git-annex-4.20130601:webapp => yesod(<1.2))
+ trying: yesod-1.1.9.3
+ $
+
+From what I can tell, the problem is fixed in github master since yesod >= 1.2 is supported again.
+"""]]
diff --git a/doc/install/cabal/comment_8_738c108f131e3aab0d720bc4fd6a81fd._comment b/doc/install/cabal/comment_8_738c108f131e3aab0d720bc4fd6a81fd._comment
new file mode 100644
index 000000000..536f30da0
--- /dev/null
+++ b/doc/install/cabal/comment_8_738c108f131e3aab0d720bc4fd6a81fd._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.193"
+ subject="comment 8"
+ date="2013-06-25T17:16:46Z"
+ content="""
+git-annex 4.20130621 once again builds with the current version of yesod.
+"""]]
diff --git a/doc/install/cabal/comment_9_5ddbba419d96a7411f7edddaa4d7b739._comment b/doc/install/cabal/comment_9_5ddbba419d96a7411f7edddaa4d7b739._comment
new file mode 100644
index 000000000..3284c8caa
--- /dev/null
+++ b/doc/install/cabal/comment_9_5ddbba419d96a7411f7edddaa4d7b739._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl7dGdYtCHb7xleEOp6n8yaUQ4UtaiAEEs"
+ nickname="Henning"
+ subject="libxml-sax Error on OS X fresh install"
+ date="2013-07-27T13:11:23Z"
+ content="""
+I had - maybe the same problem as Nigel - with ExitFailure 1 libxml-sax-0.7.4 .
+
+I could fix this by forcing the link of libxml2 package with \"brew link libxml2 --force\". Maybe you should update your guide. I had this problem on 2 different machines running both the current versions of OS X.
+
+After this the build finished successfull. Maybe this helps.
+"""]]
diff --git a/doc/install/fromscratch.mdwn b/doc/install/fromscratch.mdwn
new file mode 100644
index 000000000..ae9065cd0
--- /dev/null
+++ b/doc/install/fromscratch.mdwn
@@ -0,0 +1,72 @@
+To install git-annex from scratch, you need a lot of stuff. Really
+quite a lot.
+
+* Haskell stuff
+ * [The Haskell Platform](http://haskell.org/platform/) (GHC 7.4 or newer)
+ * [mtl](http://hackage.haskell.org.package/mtl) (2.1.1 or newer)
+ * [MissingH](http://github.com/jgoerzen/missingh/wiki)
+ * [utf8-string](http://hackage.haskell.org/package/utf8-string)
+ * [SHA](http://hackage.haskell.org/package/SHA)
+ * [cryptohash](http://hackage.haskell.org/package/cryptohash) (optional but recommended)
+ * [dataenc](http://hackage.haskell.org/package/dataenc)
+ * [monad-control](http://hackage.haskell.org/package/monad-control)
+ * [QuickCheck 2](http://hackage.haskell.org/package/QuickCheck)
+ * [json](http://hackage.haskell.org/package/json)
+ * [aeson](http://hackage.haskell.org/package/aeson)
+ * [IfElse](http://hackage.haskell.org/package/IfElse)
+ * [dlist](http://hackage.haskell.org/package/dlist)
+ * [bloomfilter](http://hackage.haskell.org/package/bloomfilter)
+ * [edit-distance](http://hackage.haskell.org/package/edit-distance)
+ * [hS3](http://hackage.haskell.org/package/hS3) (optional)
+ * [DAV](http://hackage.haskell.org/package/DAV) (optional)
+ * [SafeSemaphore](http://hackage.haskell.org/package/SafeSemaphore)
+ * [UUID](http://hackage.haskell.org/package/uuid)
+ * [regex-tdfa](http://hackage.haskell.org/package/regex-tdfa)
+ * [extensible-exceptions](http://hackage.haskell.org/package/extensible-exceptions)
+ * [feed](http://hackage.haskell.org/package/feed)
+ * [async](http://hackage.haskell.org/package/async)
+* Optional haskell stuff, used by the [[assistant]] and its webapp
+ * [stm](http://hackage.haskell.org/package/stm)
+ (version 2.3 or newer)
+ * [hinotify](http://hackage.haskell.org/package/hinotify)
+ (Linux only)
+ * [dbus](http://hackage.haskell.org/package/dbus)
+ * [yesod](http://hackage.haskell.org/package/yesod)
+ * [yesod-static](http://hackage.haskell.org/package/yesod-static)
+ * [yesod-default](http://hackage.haskell.org/package/yesod-default)
+ * [data-default](http://hackage.haskell.org/package/data-default)
+ * [case-insensitive](http://hackage.haskell.org/package/case-insensitive)
+ * [http-types](http://hackage.haskell.org/package/http-types)
+ * [wai](http://hackage.haskell.org/package/wai)
+ * [wai-logger](http://hackage.haskell.org/package/wai-logger)
+ * [warp](http://hackage.haskell.org/package/warp)
+ * [blaze-builder](http://hackage.haskell.org/package/blaze-builder)
+ * [crypto-api](http://hackage.haskell.org/package/crypto-api)
+ * [hamlet](http://hackage.haskell.org/package/hamlet)
+ * [clientsession](http://hackage.haskell.org/package/clientsession)
+ * [network-multicast](http://hackage.haskell.org/package/network-multicast)
+ * [network-info](http://hackage.haskell.org/package/network-info)
+ * [network-protocol-xmpp](http://hackage.haskell.org/package/network-protocol-xmpp)
+ * [dns](http://hackage.haskell.org/package/dns)
+ * [xml-types](http://hackage.haskell.org/package/xml-types)
+ * [HTTP](http://hackage.haskell.org/package/HTTP)
+ * [unix-compat](http://hackage.haskell.org/package/unix-compat)
+ * [MonadCatchIO-transformers](http://hackage.haskell.org/package/MonadCatchIO-transformers)
+* Shell commands
+ * [git](http://git-scm.com/)
+ * [xargs](http://savannah.gnu.org/projects/findutils/)
+ * [rsync](http://rsync.samba.org/)
+ * [curl](http://http://curl.haxx.se/) (optional, but recommended)
+ * [wget](http://www.gnu.org/software/wget/) (optional)
+ * [sha1sum](ftp://ftp.gnu.org/gnu/coreutils/) (optional, but recommended;
+ a sha1 command will also do)
+ * [gpg](http://gnupg.org/) (optional; needed for encryption)
+ * [lsof](ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/)
+ (optional; recommended for watch mode)
+ * [gcrypt](https://github.com/joeyh/git-remote-gcrypt)
+ (optional)
+ * multicast DNS support, provided on linux by [nss-mdns](http://www.0pointer.de/lennart/projects/nss-mdns/)
+ (optional; recommended for the assistant to support pairing well)
+ * [ikiwiki](http://ikiwiki.info) (optional; used to build the docs)
+
+Then just [[download]] git-annex and run: `make; make install`
diff --git a/doc/install/openSUSE.mdwn b/doc/install/openSUSE.mdwn
new file mode 100644
index 000000000..760def98c
--- /dev/null
+++ b/doc/install/openSUSE.mdwn
@@ -0,0 +1,3 @@
+Haskell Platform is now [officially available for openSUSE](http://software.opensuse.org/package/haskell-platform) via 1-Click Install.
+
+At the time of writing, there are [unofficial packages of git-annex](http://software.opensuse.org/package/git-annex) available for openSUSE. It should also be possible to build it via cabal or from source as described on the [[install]] page.
diff --git a/doc/internals.mdwn b/doc/internals.mdwn
new file mode 100644
index 000000000..4665d38df
--- /dev/null
+++ b/doc/internals.mdwn
@@ -0,0 +1,132 @@
+In the world of git, we're not scared about internal implementation
+details, and sometimes we like to dive in and tweak things by hand. Here's
+some documentation to that end.
+
+## `.git/annex/objects/aa/bb/*/*`
+
+This is where locally available file contents are actually stored.
+Files added to the annex get a symlink checked into git that points
+to the file content.
+
+First there are two levels of directories used for hashing, to prevent
+too many things ending up in any one directory.
+See [[hashing]] for details.
+
+Each subdirectory has the [[name_of_a_key|key_format]] in one of the
+[[key-value_backends|backends]]. The file inside also has the name of the key.
+This two-level structure is used because it allows the write bit to be removed
+from the subdirectories as well as from the files. That prevents accidentially
+deleting or changing the file contents. See [[lockdown]] for details.
+
+In [[direct_mode]], file contents are not stored in here, and instead
+are stored directly in the file. However, the same symlinks are still
+committed to git, internally.
+
+Also in [[direct_mode]], some additional data is stored in these directories.
+`.cache` files contain cached file stats used in detecting when a file has
+changed, and `.map` files contain a list of file(s) in the work directory
+that contain the key.
+
+## The git-annex branch
+
+This branch is managed by git-annex, with the contents listed below.
+
+The file `.git/annex/index` is a separate git index file it uses
+to accumulate changes for the git-annex branch.
+Also, `.git/annex/journal/` is used to record changes before they
+are added to git.
+
+This branch operates on objects exclusively. No file names will ever
+be stored in this branch.
+
+### `uuid.log`
+
+Records the UUIDs of known repositories, and associates them with a
+description of the repository. This allows git-annex to display something
+more useful than a UUID when it refers to a repository that does not have
+a configured git remote pointing at it.
+
+The file format is simply one line per repository, with the uuid followed by a
+space and then the description, followed by a timestamp. Example:
+
+ e605dca6-446a-11e0-8b2a-002170d25c55 laptop timestamp=1317929189.157237s
+ 26339d22-446b-11e0-9101-002170d25c55 usb disk timestamp=1317929330.769997s
+
+If there are multiple lines for the same uuid, the one with the most recent
+timestamp wins. git-annex union merges this and other files.
+
+## `remote.log`
+
+Holds persistent configuration settings for [[special_remotes]] such as
+Amazon S3.
+
+The file format is one line per remote, starting with the uuid of the
+remote, followed by a space, and then a series of var=value pairs,
+each separated by whitespace, and finally a timestamp.
+
+Encrypted special remotes store their encryption key here,
+in the "cipher" value. It is base64 encoded, and unless shared [[encryption]]
+is used, is encrypted to one or more gpg keys. The first 256 bytes of
+the cipher is used as the HMAC SHA1 encryption key, to encrypt filenames
+stored on the special remote. The remainder of the cipher is used as a gpg
+symmetric encryption key, to encrypt the content of files stored on the special
+remote.
+
+## `trust.log`
+
+Records the [[trust]] information for repositories. Does not exist unless
+[[trust]] values are configured.
+
+The file format is one line per repository, with the uuid followed by a
+space, and then either `1` (trusted), `0` (untrusted), `?` (semi-trusted),
+`X` (dead) and finally a timestamp.
+
+Example:
+
+ e605dca6-446a-11e0-8b2a-002170d25c55 1 timestamp=1317929189.157237s
+ 26339d22-446b-11e0-9101-002170d25c55 ? timestamp=1317929330.769997s
+
+Repositories not listed are semi-trusted.
+
+## `group.log`
+
+Used to group repositories together.
+
+The file format is one line per repository, with the uuid followed by a space,
+and then a space-separated list of groups this repository is part of,
+and finally a timestamp.
+
+## `preferred-content.log`
+
+Used to indicate which repositories prefer to contain which file contents.
+
+The file format is one line per repository, with the uuid followed by a space,
+then a boolean expression, and finally a timestamp.
+
+Files matching the expression are preferred to be retained in the
+repository, while files not matching it are preferred to be stored
+somewhere else.
+
+## `aaa/bbb/*.log`
+
+These log files record [[location_tracking]] information
+for file contents. Again these are placed in two levels of subdirectories
+for hashing. See [[hashing]] for details.
+
+The name of the key is the filename, and the content
+consists of a timestamp, either 1 (present) or 0 (not present), and
+the UUID of the repository that has or lacks the file content.
+
+Example:
+
+ 1287290776.765152s 1 e605dca6-446a-11e0-8b2a-002170d25c55
+ 1287290767.478634s 0 26339d22-446b-11e0-9101-002170d25c55
+
+These files are designed to be auto-merged using git's [[union merge driver|git-union-merge]].
+The timestamps allow the most recent information to be identified.
+
+## `aaa/bbb/*.log.web`
+
+These log files record urls used by the
+[[web_special_remote|special_remotes/web]]. Their format is similar
+to the location tracking files, but with urls rather than UUIDs.
diff --git a/doc/internals/comment_1_4b8ed353dca4f484b3b6eb463fa02fd8._comment b/doc/internals/comment_1_4b8ed353dca4f484b3b6eb463fa02fd8._comment
new file mode 100644
index 000000000..b42cd2fd8
--- /dev/null
+++ b/doc/internals/comment_1_4b8ed353dca4f484b3b6eb463fa02fd8._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="stoile"
+ ip="2a01:198:242:0:219:66ff:fef2:c021"
+ subject="tmp missing"
+ date="2013-11-16T12:16:48Z"
+ content="""
+There's no information about .git/annex/tmp here.
+"""]]
diff --git a/doc/internals/comment_2_c19232d5cc4976c2e5b014aef6e8d9ec._comment b/doc/internals/comment_2_c19232d5cc4976c2e5b014aef6e8d9ec._comment
new file mode 100644
index 000000000..3c5f87bd5
--- /dev/null
+++ b/doc/internals/comment_2_c19232d5cc4976c2e5b014aef6e8d9ec._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.246"
+ subject="comment 2"
+ date="2013-11-16T17:23:02Z"
+ content="""
+.git/annex/tmp is not very interesting. It's a temporary file directory. When transferring a key's content, git-annex uses a stable filename, which allows resuming interrupted downloads, or cleaning up aborted downloads with `git annex unused`.
+"""]]
diff --git a/doc/internals/hashing.mdwn b/doc/internals/hashing.mdwn
new file mode 100644
index 000000000..f479cfc47
--- /dev/null
+++ b/doc/internals/hashing.mdwn
@@ -0,0 +1,30 @@
+In both the .git/annex directory and the git-annex branch, two levels of
+hash directories are used, to avoid issues with too many files in one
+directory.
+
+Two separate hash methods are used. One, the old hash format, is only used
+for non-bare git repositories. The other, the new hash format, is used for
+bare git repositories, the git-annex branch, and on special remotes as
+well.
+
+## new hash format
+
+This uses two directories, each with a three-letter name, such as "f87/4d5"
+
+The directory names come from the md5sum of the [[key|key_format]].
+
+For example:
+
+ echo -n "SHA256E-s0--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" | md5sum
+
+## old hash format
+
+This uses two directories, each with a two-letter name, such as "pX/1J"
+
+It takes the md5sum of the key, but rather than a string, represents it as 4
+32bit words. Only the first word is used. It is converted into a string by the
+same mechanism that would be used to encode a normal md5sum value into a
+string, but where that would normally encode the bits using the 16 characters
+0-9a-f, this instead uses the 32 characters "0123456789zqjxkmvwgpfZQJXKMVWGPF".
+The first 2 letters of the resulting string are the first directory, and the
+second 2 are the second directory.
diff --git a/doc/internals/key_format.mdwn b/doc/internals/key_format.mdwn
new file mode 100644
index 000000000..f08055234
--- /dev/null
+++ b/doc/internals/key_format.mdwn
@@ -0,0 +1,20 @@
+A git-annex key has this format:
+
+ BACKEND-sNNNN-mNNNN--NAME
+
+For example:
+
+ SHA256E-s31390--f50d7ac4c6b9031379986bc362fcefb65f1e52621ce1708d537e740fefc59cc0.mp3
+
+* The backend is one of the [[key-value_backends|backends]], which
+ are always upper-cased.
+* The name field at the end has a format dependent on the backend. It is
+ always the last field, and is prefixed with "--". Unlike other fields,
+ it may contain "-" in its content. It should not contain newline characters;
+ otherwise nearly anything goes.
+* The "-s" field is optional, and is the size of the content in bytes.
+* The "-m" field is optional, and is the mtime of the file when it was
+ added to git-annex, expressed as seconds from the epoch.
+ This is currently only used by the WORM backend.
+* Other fields could be added in the future, if needed.
+* Fields may appear, in any order (though always before the name field).
diff --git a/doc/internals/lockdown.mdwn b/doc/internals/lockdown.mdwn
new file mode 100644
index 000000000..a7775cd3a
--- /dev/null
+++ b/doc/internals/lockdown.mdwn
@@ -0,0 +1,44 @@
+Object files stored in `.git/annex/objects` are each put in their own directory.
+This allows the write bit to be removed from both the file, and its directory,
+which prevents accidentially deleting or changing the file contents.
+
+The reasoning for doing this follows:
+
+Normally with git, once you have committed a file, editing the file in the
+working tree cannot cause you to lose the committed version. This is an
+important property of git. Of course you can `rm -rf .git` and delete
+commits if you like (before you've pushed them). But you can't lose a
+committed version of the file because of something you do with the working
+tree version.
+
+It's easy for git to do this, because committing a file makes a copy of it.
+But git-annex does not make a local copy of a file added to it, because
+the file could be very large.
+
+So, it's important for git-annex to find another way to preserve the expected
+property that once committed, you cannot accidentially lose a file.
+The most important protection it makes is just to remove the write bit of
+the file. Thus preventing programs from modifying it.
+
+But, that does not prevent any program that might follow the symlink and
+delete the symlinked file. This might seem an unlikely thing for a program to
+do at first, but consider a command like:
+`tar cf foo.tar foo --remove-files --dereference`
+
+When I tested this, I didn't know if it would remove the file foo symlinked
+to or not! It turned out that my tar doesn't remove it. But it could
+have easily went the other way.
+
+Rather than needing to worry about every possible program that might
+decide to do something like this, git-annex removes the write bit from the
+directory containing the annexed object, as well as removing the write
+bit from the file. (The only bad consequence of this is that `rm -rf .git`
+doesn't work unless you first run `chmod -R +w .git`)
+
+----
+
+It's known that this lockdown mechanism is incomplete. The worst hole in
+it is that if you explicitly run `chmod +w` on an annexed file in the working
+tree, this follows the symlink and allows writing to the file. It would be
+better to make the files fully immutable. But most systems either don't
+support immutable attributes, or only let root make files immutable.
diff --git a/doc/license.mdwn b/doc/license.mdwn
new file mode 100644
index 000000000..837fd8c3b
--- /dev/null
+++ b/doc/license.mdwn
@@ -0,0 +1,14 @@
+git-annex is Free Software.
+
+The majority of git-annex is licensed under the [[GPL]], version 3 or
+higher.
+
+The git-annex webapp is licensed under the [[AGPL]], version 3 or higher.
+Note that builds of git-annex that include the webapp may be licensed
+under the AGPL as a whole. git-annex built without the webapp does
+not include this code, so remains GPLed.
+
+git-annex contains a variety of other code, artwork, etc copyright by
+others, under a variety of licences, including the [[LGPL]], BSD,
+MIT, and Apache 2.0 licenses. For details, see
+[this file](http://source.git-annex.branchable.com/?p=source.git;a=blob_plain;f=debian/copyright;hb=HEAD).
diff --git a/doc/license/AGPL b/doc/license/AGPL
new file mode 100644
index 000000000..dba13ed2d
--- /dev/null
+++ b/doc/license/AGPL
@@ -0,0 +1,661 @@
+ GNU AFFERO GENERAL PUBLIC LICENSE
+ Version 3, 19 November 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU Affero General Public License is a free, copyleft license for
+software and other kinds of works, specifically designed to ensure
+cooperation with the community in the case of network server software.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+our General Public Licenses are intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ Developers that use our General Public Licenses protect your rights
+with two steps: (1) assert copyright on the software, and (2) offer
+you this License which gives you legal permission to copy, distribute
+and/or modify the software.
+
+ A secondary benefit of defending all users' freedom is that
+improvements made in alternate versions of the program, if they
+receive widespread use, become available for other developers to
+incorporate. Many developers of free software are heartened and
+encouraged by the resulting cooperation. However, in the case of
+software used on network servers, this result may fail to come about.
+The GNU General Public License permits making a modified version and
+letting the public access it on a server without ever releasing its
+source code to the public.
+
+ The GNU Affero General Public License is designed specifically to
+ensure that, in such cases, the modified source code becomes available
+to the community. It requires the operator of a network server to
+provide the source code of the modified version running there to the
+users of that server. Therefore, public use of a modified version, on
+a publicly accessible server, gives the public access to the source
+code of the modified version.
+
+ An older license, called the Affero General Public License and
+published by Affero, was designed to accomplish similar goals. This is
+a different license, not a version of the Affero GPL, but Affero has
+released a new version of the Affero GPL which permits relicensing under
+this license.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU Affero General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Remote Network Interaction; Use with the GNU General Public License.
+
+ Notwithstanding any other provision of this License, if you modify the
+Program, your modified version must prominently offer all users
+interacting with it remotely through a computer network (if your version
+supports such interaction) an opportunity to receive the Corresponding
+Source of your version by providing access to the Corresponding Source
+from a network server at no charge, through some standard or customary
+means of facilitating copying of software. This Corresponding Source
+shall include the Corresponding Source for any work covered by version 3
+of the GNU General Public License that is incorporated pursuant to the
+following paragraph.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the work with which it is combined will remain governed by version
+3 of the GNU General Public License.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU Affero General Public License from time to time. Such new versions
+will be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU Affero General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU Affero General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU Affero General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If your software can interact with users remotely through a computer
+network, you should also make sure that it provides a way for users to
+get its source. For example, if your program is a web application, its
+interface could display a "Source" link that leads users to an archive
+of the code. There are many ways you could offer source, and different
+solutions will be better for different programs; see section 13 for the
+specific requirements.
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU AGPL, see
+<http://www.gnu.org/licenses/>.
diff --git a/doc/license/GPL b/doc/license/GPL
new file mode 100644
index 000000000..94a9ed024
--- /dev/null
+++ b/doc/license/GPL
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/doc/license/LGPL b/doc/license/LGPL
new file mode 100644
index 000000000..4362b4915
--- /dev/null
+++ b/doc/license/LGPL
@@ -0,0 +1,502 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/doc/links/key_concepts.mdwn b/doc/links/key_concepts.mdwn
new file mode 100644
index 000000000..f1754e0c8
--- /dev/null
+++ b/doc/links/key_concepts.mdwn
@@ -0,0 +1,7 @@
+### key concepts
+
+* [[git-annex man page|git-annex]]
+* [[how_it_works]]
+* [[special_remotes]]
+* [[sync]]
+* [[direct_mode]]
diff --git a/doc/links/other_stuff.mdwn b/doc/links/other_stuff.mdwn
new file mode 100644
index 000000000..74ec2d5e6
--- /dev/null
+++ b/doc/links/other_stuff.mdwn
@@ -0,0 +1,7 @@
+### other stuff
+
+* [[testimonials]]
+* [[privacy]]
+* [[what git annex is not|not]]
+* [[related_software]]
+* [[sitemap]]
diff --git a/doc/links/the_details.mdwn b/doc/links/the_details.mdwn
new file mode 100644
index 000000000..a7f8633a8
--- /dev/null
+++ b/doc/links/the_details.mdwn
@@ -0,0 +1,8 @@
+### the details
+
+* [[encryption]]
+* [[key-value backends|backends]]
+* [[bare_repositories]]
+* [[internals]]
+* [[scalability]]
+* [[design]]
diff --git a/doc/location_tracking.mdwn b/doc/location_tracking.mdwn
new file mode 100644
index 000000000..d40a7206f
--- /dev/null
+++ b/doc/location_tracking.mdwn
@@ -0,0 +1,30 @@
+git-annex keeps track of in which repositories it last saw a file's content.
+This location tracking information is stored in the git-annex branch.
+Repositories record their UUID and the date when they get or drop
+a file's content.
+
+This location tracking information is useful if you have multiple
+repositories, and not all are always accessible. For example, perhaps one
+is on a home file server, and you are away from home. Then git-annex can
+tell you what git remote it needs access to in order to get a file:
+
+ # git annex get myfile
+ get myfile (not available)
+ I was unable to access these remotes: home
+
+Another way the location tracking comes in handy is if you put repositories
+on removable USB drives, that might be archived away offline in a safe
+place. In this sort of case, you probably don't have a git remotes
+configured for every USB drive. So git-annex may have to resort to talking
+about repository UUIDs. If you have previously used "git annex init"
+to attach descriptions to those repositories, it will include their
+descriptions to help you with finding them:
+
+ # git annex get myfile
+ get myfile (not available)
+ Try making some of these repositories available:
+ c0a28e06-d7ef-11df-885c-775af44f8882 -- USB archive drive 1
+ e1938fee-d95b-11df-96cc-002170d25c55
+
+In certain cases you may want to configure git-annex to [[trust]]
+that location tracking information is always correct for a repository.
diff --git a/doc/logo-old-bw.svg b/doc/logo-old-bw.svg
new file mode 100644
index 000000000..11d362e5f
--- /dev/null
+++ b/doc/logo-old-bw.svg
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="640px"
+ height="480px"
+ id="svg3134"
+ version="1.1"
+ inkscape:version="0.48.3.1 r9886"
+ sodipodi:docname="New document 11">
+ <defs
+ id="defs3136" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.77472527"
+ inkscape:cx="317.41844"
+ inkscape:cy="245.16312"
+ inkscape:current-layer="layer1"
+ inkscape:document-units="px"
+ showgrid="false"
+ inkscape:window-width="800"
+ inkscape:window-height="564"
+ inkscape:window-x="0"
+ inkscape:window-y="12"
+ inkscape:window-maximized="0" />
+ <metadata
+ id="metadata3139">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <path
+ style="fill:#000000"
+ d="m 302.43431,440.4468 c -14.88228,-4.33874 -18.89443,-6.47398 -28.38217,-15.10481 -13.08558,-11.90371 -17.72561,-23.29726 -17.72561,-43.52501 0,-18.30772 4.14768,-29.96528 14.34194,-40.30981 7.27131,-7.37848 18.36439,-13.25052 25.03206,-13.25052 4.73347,0 4.8315,0.27458 4.8315,13.5325 l 0,13.5325 -6.57204,3.04787 c -9.16684,4.25125 -13.05127,12.36242 -12.09267,25.25093 1.53891,20.69072 13.75689,28.81207 43.34566,28.81207 14.25099,0 19.3577,-0.72886 23.91428,-3.41316 12.51899,-7.37499 18.80704,-23.65294 14.28477,-36.97908 -2.56222,-7.55028 -13.65238,-17.88336 -19.19364,-17.88336 -3.36269,0 -3.73837,1.31029 -3.73837,13.03841 l 0,13.0384 -11.88928,-0.55077 -11.88929,-0.55079 0,-25.90026 0,-25.90027 35.19228,0 35.19228,0 0.57499,9.7126 c 0.49269,8.32267 0.0845,9.71665 -2.85343,9.74093 -8.20311,0.0677 -8.706,2.84359 -2.15276,11.88256 6.12053,8.44215 6.33349,9.33743 6.33349,26.62529 0,15.38301 -0.65924,19.1446 -4.70538,26.84845 -9.93611,18.91837 -28.93477,29.1492 -56.00199,30.15722 -10.88743,0.40545 -20.4551,-0.28006 -25.84662,-1.85189 z m -45.65485,-139.01542 0,-13.87514 65.62885,0 65.62884,0 0,13.87514 0,13.87514 -65.62884,0 -65.62885,0 0,-13.87514 z m 49.45942,-38.8504 0,-15.72516 -24.72971,0 -24.72971,0 0,-12.95013 0,-12.95014 24.72971,0 24.72971,0 0,-16.65017 0,-16.65017 15.21829,0 15.21828,0 0,16.65017 0,16.65017 25.68085,0 25.68085,0 0,12.89643 0,12.89645 -25.20528,0.51619 -25.20528,0.51621 -0.5525,15.26265 -0.5525,15.26266 -15.14135,0 -15.14136,0 0,-15.72516 z m 90.58314,-28.97078 c -1.413,-6.87082 -1.79669,-6.34506 5.78198,-7.92291 5.58749,-1.16331 6.09939,-0.83956 7.33692,4.64003 1.45579,6.44604 -0.79787,9.0505 -7.87441,9.1001 -3.02463,0.0211 -4.34501,-1.44337 -5.24449,-5.81722 z m -160.69546,0.49827 c -1.79783,-1.10787 -2.17745,-3.37832 -1.25087,-7.48118 1.23754,-5.47959 1.74944,-5.80335 7.33693,-4.64004 7.57866,1.57785 7.19497,1.05209 5.78198,7.92291 -1.24077,6.03343 -6.10031,7.75249 -11.86804,4.19831 z m 190.42463,-6.76941 c -1.85277,-5.87101 -1.66966,-6.25919 3.83255,-8.12458 3.17805,-1.07743 5.9948,-1.95896 6.25947,-1.95896 0.91633,0 4.67209,11.70301 3.97372,12.38219 -0.38574,0.37517 -3.27056,1.39869 -6.41068,2.27453 -5.34046,1.48954 -5.83503,1.19409 -7.65506,-4.57318 z m -216.85329,0.64986 c -3.40034,-0.87401 -6.18243,-1.85733 -6.18243,-2.18515 0,-0.32782 0.94953,-3.24505 2.11007,-6.48271 1.73496,-4.84015 2.83405,-5.67166 6.18243,-4.67733 7.88037,2.34017 8.42794,3.15845 6.18018,9.23554 -1.96709,5.31825 -2.52062,5.59264 -8.29025,4.10965 z m 245.52541,-10.67191 c -2.12815,-5.48318 -2.11652,-5.49574 11.85359,-12.82409 22.7641,-11.94143 40.5838,-25.97488 57.05249,-44.93026 l 7.53031,-8.66734 5.41145,4.25151 5.41145,4.25151 -17.60152,17.90565 c -16.73035,17.01941 -37.6183,32.42395 -56.39658,41.59159 -10.27596,5.01677 -10.722,4.96367 -13.26119,-1.57857 z m -286.33038,-6.27889 c -21.55151,-11.9442 -31.63729,-19.70355 -49.98909,-38.45829 l -16.54083,-16.90401 5.39695,-4.24028 5.39696,-4.24026 7.53031,8.66734 c 16.46869,18.95538 34.28839,32.98883 57.05248,44.93026 13.97012,7.32835 13.98175,7.34091 11.8536,12.82409 -1.17162,3.01872 -3.03333,5.48856 -4.13709,5.48856 -1.10378,0 -8.55726,-3.63034 -16.56329,-8.06741 z m 375.66016,-70.84688 c -3.97648,-2.69927 -4.05764,-3.18834 -1.36824,-8.24615 2.7937,-5.254 2.98784,-5.31188 8.50732,-2.53606 6.47782,3.25777 6.35114,2.92151 3.44074,9.13364 -2.52039,5.37967 -4.60478,5.70447 -10.57982,1.64857 z M 89.683687,134.84263 c -2.910382,-6.21213 -3.037055,-5.87587 3.440759,-9.13364 5.520337,-2.77624 5.713305,-2.71854 8.512274,2.54533 2.72546,5.12566 2.63957,5.52893 -1.77689,8.3432 -6.255304,3.98601 -7.594703,3.75504 -10.176143,-1.75489 z M 558.86885,114.49806 c -4.66412,-2.46246 -4.94939,-3.21135 -3.14292,-8.25101 1.09275,-3.04849 2.20334,-5.54273 2.46799,-5.54273 1.15984,0 12.46263,4.10838 12.46263,4.52996 0,2.20567 -4.45138,12.10382 -5.41738,12.04614 -0.68234,-0.0407 -3.54898,-1.29279 -6.37032,-2.78236 z M 76.248436,107.82834 c -1.1486,-3.20438 -2.088367,-6.03672 -2.088367,-6.2941 0,-0.42158 11.30279,-4.529954 12.462632,-4.529954 0.264646,0 1.376722,2.498376 2.471297,5.551964 1.832586,5.11256 1.553673,5.77145 -3.524022,8.32508 -7.178882,3.61035 -6.90035,3.70158 -9.32154,-3.05299 z M 568.27869,86.478917 c -4.16144,-1.0576 -4.15124,-1.435966 0.47558,-17.673656 4.71707,-16.554414 4.76128,-15.866207 -0.95115,-14.804204 -3.51666,0.653779 -4.75571,0.08973 -4.75571,-2.164633 0,-1.67682 1.09334,-3.456779 2.42964,-3.95547 1.33629,-0.498709 4.53447,-4.218875 7.10707,-8.267031 3.85384,-6.064326 5.73436,-7.360301 10.68013,-7.360301 4.78765,0 6.24005,0.919681 7.17525,4.543462 0.64491,2.498894 2.13408,6.869564 3.30925,9.712599 4.714,11.40422 2.47433,18.328434 -4.06643,12.571786 -3.92535,-3.4548 -3.4906,-4.351652 -9.63904,19.885132 -2.24473,8.848659 -3.45803,9.62341 -11.76459,7.512316 z M 62.514449,66.506779 57.950276,48.599557 52.639,52.662624 c -2.921206,2.234675 -5.630041,3.75306 -6.019648,3.374157 -0.389608,-0.378884 0.859281,-4.428205 2.775301,-8.998492 1.916001,-4.570287 3.965028,-9.76649 4.553405,-11.547134 0.734891,-2.224093 3.046111,-3.237533 7.383397,-3.237533 5.021102,0 8.14882,1.812001 15.277977,8.851138 4.930401,4.868122 8.964349,10.279427 8.964349,12.025124 0,4.517598 -2.081195,3.939726 -6.8916,-1.913568 -2.299596,-2.798153 -4.818203,-4.473179 -5.596904,-3.722293 -0.778719,0.750904 0.522064,8.499468 2.890599,17.219014 2.368555,8.719565 3.936551,16.213492 3.484473,16.653149 -0.452097,0.439676 -3.422934,1.3053 -6.601862,1.923613 l -5.779866,1.12422 -4.564172,-17.90724 z"
+ id="path3050"
+ inkscape:connector-curvature="0" />
+ </g>
+</svg>
diff --git a/doc/logo-old.png b/doc/logo-old.png
new file mode 100644
index 000000000..38d335a45
--- /dev/null
+++ b/doc/logo-old.png
Binary files differ
diff --git a/doc/logo-old.svg b/doc/logo-old.svg
new file mode 100644
index 000000000..5741ffeb5
--- /dev/null
+++ b/doc/logo-old.svg
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="640px"
+ height="480px"
+ id="svg3134"
+ version="1.1"
+ inkscape:version="0.48.3.1 r9886"
+ sodipodi:docname="git-annex.svg">
+ <defs
+ id="defs3136" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.77472527"
+ inkscape:cx="398.6665"
+ inkscape:cy="232.05718"
+ inkscape:current-layer="layer1"
+ inkscape:document-units="px"
+ showgrid="false"
+ inkscape:window-width="1024"
+ inkscape:window-height="566"
+ inkscape:window-x="0"
+ inkscape:window-y="12"
+ inkscape:window-maximized="0" />
+ <metadata
+ id="metadata3139">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <g
+ id="g4187"
+ transform="matrix(2.0184211,0,0,1.9796558,-320.30102,-235.1316)">
+ <path
+ sodipodi:nodetypes="cccccccccccccccccccccccccssscssssssssscssssssssssscccssssscccssssssssssssssssssscssssssssssscsssssssccscsssssssssscc"
+ inkscape:connector-curvature="0"
+ id="path3050"
+ d="m 306.53525,253.83733 0,-8.5 -13,0 -13,0 0,-7 0,-7 13,0 13,0 0,-9 0,-9 8,0 8,0 0,9 0,9 13.5,0 13.5,0 0,6.97097 0,6.97098 -13.25,0.27902 -13.25,0.27903 -0.29044,8.25 -0.29044,8.25 -7.95956,0 -7.95956,0 z m 47.61806,-15.65972 c -0.74279,-3.71392 -0.94449,-3.42973 3.03949,-4.28261 2.93725,-0.62881 3.20635,-0.45381 3.8569,2.5081 0.76528,3.48431 -0.41943,4.89211 -4.13945,4.91892 -1.59,0.0114 -2.2841,-0.78019 -2.75694,-3.14441 z m -84.47495,0.26933 c -0.94509,-0.59884 -1.14465,-1.8261 -0.65756,-4.04384 0.65055,-2.96191 0.91965,-3.13691 3.8569,-2.5081 3.98398,0.85288 3.78228,0.56869 3.03949,4.28261 -0.65225,3.26128 -3.20683,4.19049 -6.23883,2.26933 z m 100.10308,-3.6591 c -0.97397,-3.17349 -0.87771,-3.38331 2.01471,-4.39162 1.67065,-0.58239 3.15137,-1.05889 3.2905,-1.05889 0.4817,0 2.45604,6.32589 2.08892,6.69301 -0.20278,0.20279 -1.71928,0.75604 -3.36999,1.22946 -2.80739,0.80515 -3.06738,0.64545 -4.02414,-2.47196 z m -113.99619,0.35127 c -1.7875,-0.47243 -3.25,-1.00395 -3.25,-1.18115 0,-0.1772 0.49915,-1.75406 1.10923,-3.50413 0.91204,-2.61627 1.48981,-3.06573 3.25,-2.52826 4.14258,1.26494 4.43043,1.70725 3.24882,4.99213 -1.03407,2.8747 -1.32505,3.02302 -4.35805,2.22141 z m 129.06865,-5.76854 c -1.11873,-2.96385 -1.11262,-2.97064 6.23124,-6.93187 11.96671,-6.45476 21.33423,-14.04033 29.99155,-24.28638 l 3.95856,-4.685 2.84471,2.29809 2.84471,2.29809 -9.25283,9.67863 c -8.79487,9.19959 -19.77532,17.52628 -29.64675,22.48171 -5.4019,2.71174 -5.63638,2.68304 -6.97119,-0.85327 z m -150.51915,-3.39396 c -11.32927,-6.45626 -16.6312,-10.65046 -26.27844,-20.78805 l -8.69524,-9.13721 2.83709,-2.29202 2.83709,-2.29201 3.95856,4.685 c 8.65732,10.24605 18.02484,17.83162 29.99155,24.28638 7.34386,3.96123 7.34997,3.96802 6.23124,6.93187 -0.6159,1.63172 -1.59457,2.96676 -2.1748,2.96676 -0.58024,0 -4.49841,-1.96233 -8.70705,-4.36072 z m 197.47834,-38.29522 c -2.09037,-1.45905 -2.13303,-1.72341 -0.71926,-4.45733 1.4686,-2.83997 1.57066,-2.87126 4.47216,-1.37083 3.40528,1.76094 3.33869,1.57918 1.80874,4.93705 -1.32493,2.9079 -2.42066,3.08347 -5.56164,0.89111 z m -239.11733,-2.89111 c -1.52994,-3.35787 -1.59653,-3.17611 1.80875,-4.93705 2.90195,-1.50066 3.00339,-1.46947 4.47476,1.37584 1.43273,2.7706 1.38758,2.98858 -0.93408,4.50979 -3.28831,2.15458 -3.99241,2.02973 -5.34943,-0.94858 z m 246.64289,-10.99695 c -2.45185,-1.33105 -2.60181,-1.73585 -1.65218,-4.45996 0.57444,-1.64782 1.15826,-2.99604 1.29738,-2.99604 0.60971,0 6.5514,2.22072 6.5514,2.4486 0,1.19224 -2.34002,6.54254 -2.84783,6.51136 -0.35869,-0.022 -1.86564,-0.6988 -3.34877,-1.50396 z m -253.70558,-3.60522 c -0.6038,-1.73208 -1.09782,-3.26306 -1.09782,-3.40218 0,-0.22788 5.94169,-2.4486 6.5514,-2.4486 0.13912,0 0.72372,1.35046 1.29912,3.00103 0.96336,2.76352 0.81674,3.11967 -1.85252,4.5 -3.77382,1.95152 -3.6274,2.00083 -4.90018,-1.65025 z M 444.28525,158.648 c -2.1876,-0.57167 -2.18224,-0.77619 0.25,-9.55323 2.47969,-8.94824 2.50293,-8.57624 -0.5,-8.00219 -1.84865,0.35339 -2.5,0.0485 -2.5,-1.17006 0,-0.90638 0.57475,-1.86851 1.27722,-2.13807 0.70247,-0.26957 2.3837,-2.28045 3.73607,-4.46862 2.0259,-3.27798 3.01446,-3.9785 5.61437,-3.9785 2.51679,0 3.28029,0.49712 3.77191,2.4559 0.33902,1.35074 1.12185,3.71324 1.73962,5.25 2.47807,6.16438 1.30071,9.90716 -2.13766,6.79549 -2.06349,-1.86744 -1.83495,-2.35222 -5.06708,10.74861 -1.18002,4.78301 -1.81783,5.20179 -6.18445,4.06067 z m -265.87191,-10.79564 -2.39931,-9.67948 -2.79205,2.19623 c -1.53563,1.20792 -2.95962,2.02866 -3.16443,1.82385 -0.20481,-0.2048 0.45171,-2.3936 1.45893,-4.864 1.00721,-2.4704 2.08435,-5.27913 2.39365,-6.24163 0.38632,-1.2022 1.60129,-1.75 3.88133,-1.75 2.63951,0 4.2837,0.97945 8.03138,4.78435 2.59183,2.63139 4.71241,5.55639 4.71241,6.5 0,2.44192 -1.09405,2.12956 -3.6228,-1.03435 -1.20886,-1.5125 -2.53285,-2.41791 -2.9422,-2.01203 -0.40936,0.40589 0.27444,4.59426 1.51954,9.30748 1.24511,4.71323 2.06938,8.76396 1.83173,9.00161 -0.23766,0.23766 -1.79938,0.70556 -3.47049,1.03978 l -3.03838,0.60768 z"
+ style="fill:#40bf4c;fill-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ style="fill:#d8372c;fill-opacity:1"
+ d="m 280.84173,275.15053 0,-7.5 34.5,0 34.5,0 0,7.5 0,7.5 -34.5,0 -34.5,0 z"
+ id="path4113"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="sssssscssssssscccccccsssssss"
+ style="fill:#666666;fill-opacity:1;fill-rule:nonzero"
+ d="m 305.37638,349.62884 c -7.82337,-2.34524 -9.93249,-3.49941 -14.92004,-8.16468 -6.87887,-6.43437 -9.31806,-12.59298 -9.31806,-23.52679 0,-9.89596 2.18037,-16.19728 7.53932,-21.78886 3.82241,-3.98833 9.65386,-7.16237 13.15894,-7.16237 2.48831,0 2.53984,0.14842 2.53984,7.31479 l 0,7.31479 -3.45481,1.64748 c -4.81886,2.29795 -6.86084,6.68232 -6.35692,13.64901 0.80898,11.18406 7.23177,15.57393 22.7861,15.57393 7.49151,0 10.17602,-0.39397 12.57134,-1.84493 6.58103,-3.98644 9.88655,-12.78524 7.50927,-19.98849 -1.34692,-4.08119 -7.17683,-9.66658 -10.08978,-9.66658 -1.76771,0 -1.9652,0.70826 -1.9652,7.04772 l 0,7.04771 -6.25,-0.29771 -6.25,-0.29772 0,-14 0,-14 18.5,0 18.5,0 0.30226,5.25 c 0.259,4.49869 0.0444,5.25219 -1.5,5.26531 -4.31224,0.0366 -4.5766,1.53706 -1.13167,6.42294 3.21746,4.56328 3.32941,5.04721 3.32941,14.3919 0,8.31506 -0.34655,10.34833 -2.47354,14.51253 -5.22325,10.22604 -15.21053,15.75616 -29.43932,16.30103 -5.72334,0.21916 -10.75291,-0.15138 -13.58714,-1.00101 z"
+ id="path4115"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+</svg>
diff --git a/doc/logo-old_small.png b/doc/logo-old_small.png
new file mode 100644
index 000000000..867fecf86
--- /dev/null
+++ b/doc/logo-old_small.png
Binary files differ
diff --git a/doc/logo.mdwn b/doc/logo.mdwn
new file mode 100644
index 000000000..ae132bd2d
--- /dev/null
+++ b/doc/logo.mdwn
@@ -0,0 +1,13 @@
+Variants of the git-annex logo.
+
+[[logo_small.png]]
+
+[[logo.svg]]
+
+[[logo-old.png]]
+
+[[logo-old_small.png]]
+
+[[logo-old.svg]]
+
+[[logo-old-bw.svg]]
diff --git a/doc/logo.svg b/doc/logo.svg
new file mode 100644
index 000000000..bd87eefef
--- /dev/null
+++ b/doc/logo.svg
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg2"
+ sodipodi:version="0.32"
+ inkscape:version="0.47 r22583"
+ width="251.1875"
+ height="240.34375"
+ version="1.0"
+ sodipodi:docname="gitlogo.svg">
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="Git Logo">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs5">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 94 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="97 : 94 : 1"
+ inkscape:persp3d-origin="48.5 : 62.666667 : 1"
+ id="perspective11" />
+ <inkscape:perspective
+ id="perspective3682"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 0.5 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ </defs>
+ <sodipodi:namedview
+ inkscape:window-height="825"
+ inkscape:window-width="1440"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ guidetolerance="10.0"
+ gridtolerance="10.0"
+ objecttolerance="10.0"
+ borderopacity="1.0"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base"
+ inkscape:zoom="1.7347111"
+ inkscape:cx="79.460121"
+ inkscape:cy="96.862066"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:current-layer="svg2"
+ showguides="false"
+ showgrid="false"
+ inkscape:window-maximized="1" />
+ <path
+ sodipodi:nodetypes="ccccccccccccccccccc"
+ id="path1927"
+ d="m 115.03986,236.92929 c -15.769481,-2.03151 -31.998702,-16.94187 -34.26618,-34.43444 -2.174671,-14.62409 0.962744,-31.69413 13.051455,-41.34542 5.302266,-3.61399 12.514875,-7.66322 18.875285,-7.18134 0.1905,6.47429 -0.19049,14.34359 0,20.81788 -7.57578,0.84345 -14.909032,9.45432 -14.756408,17.33851 0.185705,10.26001 4.726478,19.68681 14.597668,22.75753 10.91859,3.67394 23.41726,2.62901 33.52469,-3.47905 8.34971,-6.50563 9.12218,-18.61836 4.75506,-27.83618 -1.96442,-5.07246 -6.19899,-8.79638 -11.94647,-8.78081 l 0,18.05778 -16.20641,0 0,-38.87566 49.07678,0 0,13.97989 -13.44239,0.12434 c 12.54392,7.15066 13.82967,22.58379 13.18688,33.29078 0.45188,18.39283 -17.71936,33.38895 -35.74198,35.39399 -6.52041,0.48886 -12.03738,0.51459 -20.70798,0.1722 z"
+ style="fill:#666666;fill-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path1925"
+ d="m 79.977992,146.2455 -0.103031,-20.40175 91.999999,0 -0.0106,20.5 -91.886388,-0.0983 z"
+ style="fill:#d8382d;fill-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccccccccccccc"
+ id="path1917"
+ d="m 115.04163,118.67709 0,-21.83334 -35.666669,0 0,-19 35.666669,0 0,-24.5 21.33333,0 0,24.5 35.5,0 0,19 -35.5,0 -0.35168,21.78777 -20.98165,0.0456 z"
+ style="fill:#40bf4c;fill-opacity:1" />
+ <path
+ style="fill:#40bf4c;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="M 21.28125,0 0,29.75 l 11.8125,0 c 0.02423,3.288346 0.302477,6.52723 0.78125,9.6875 L 31.375,36.59375 C 31.03908,34.358787 30.836567,32.072528 30.8125,29.75 l 11.75,0 L 21.28125,0 z M 32.84375,43.28125 14.6875,48.75 c 0.923692,3.063035 2.046663,6.043138 3.375,8.90625 L 35.28125,49.6875 c -0.956041,-2.062577 -1.776322,-4.198284 -2.4375,-6.40625 z m 5.6875,12.25 L 22.5625,65.8125 C 29.747774,76.954156 40.108616,85.860221 52.375,91.21875 L 59.96875,73.8125 C 51.136943,69.958114 43.695592,63.555939 38.53125,55.53125 z m 27.75,20.5 -5.125,18.3125 c 2.899536,0.810722 5.86596,1.421431 8.90625,1.84375 l 2.625,-18.8125 c -2.184482,-0.307312 -4.321319,-0.760497 -6.40625,-1.34375 z"
+ id="path2836" />
+ <path
+ style="fill:#40bf4c;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 229.90625,0 -21.28125,29.75 11.8125,0 c -0.024,2.322528 -0.22658,4.608787 -0.5625,6.84375 l 18.78125,2.84375 c 0.47877,-3.16027 0.75698,-6.399154 0.78125,-9.6875 l 11.75,0 L 229.90625,0 z m -11.5,43.28125 c -0.66118,2.207966 -1.48146,4.343673 -2.4375,6.40625 l 17.21875,7.96875 c 1.32834,-2.863112 2.45131,-5.843215 3.375,-8.90625 l -18.15625,-5.46875 z m -5.6875,12.25 c -5.16434,8.024689 -12.60569,14.426864 -21.4375,18.28125 L 198.875,91.21875 C 211.14138,85.860221 221.50223,76.954156 228.6875,65.8125 L 212.71875,55.53125 z m -27.75,20.5 c -2.08493,0.583253 -4.22177,1.036438 -6.40625,1.34375 l 2.625,18.8125 c 3.04029,-0.422319 6.00671,-1.033028 8.90625,-1.84375 l -5.125,-18.3125 z"
+ id="path3649" />
+</svg>
diff --git a/doc/logo_small.png b/doc/logo_small.png
new file mode 100644
index 000000000..252b761d0
--- /dev/null
+++ b/doc/logo_small.png
Binary files differ
diff --git a/doc/meta.mdwn b/doc/meta.mdwn
new file mode 100644
index 000000000..5ee36f8c0
--- /dev/null
+++ b/doc/meta.mdwn
@@ -0,0 +1,5 @@
+This wiki contains [[!pagecount pages="*"]] pages.
+
+Broken links:
+
+[[!brokenlinks ]]
diff --git a/doc/news.mdwn b/doc/news.mdwn
new file mode 100644
index 000000000..95114cdcf
--- /dev/null
+++ b/doc/news.mdwn
@@ -0,0 +1,11 @@
+[[!if test="news/*" then="""
+This is where announcements of new releases, features, and other news is
+posted. git-annex users are recommended to subscribe to this page's RSS
+feed.
+
+[[!inline pages="./news/* and !./news/*/* and !*/Discussion" rootpage="news" show="30"]]
+
+"""
+else="""
+(Please see the changelog.)
+"""]]
diff --git a/doc/news/2013_git-annex_user_survey.mdwn b/doc/news/2013_git-annex_user_survey.mdwn
new file mode 100644
index 000000000..269496e64
--- /dev/null
+++ b/doc/news/2013_git-annex_user_survey.mdwn
@@ -0,0 +1,5 @@
+Similar to the yearly git user survey, I am doing a
+[2013 git-annex user survey](http://git-annex-survey.branchable.com/polls/2013/).
+
+If you use git-annex,
+please take a few minutes to answer my questions!
diff --git a/doc/news/LWN_article.mdwn b/doc/news/LWN_article.mdwn
new file mode 100644
index 000000000..c1c0c4047
--- /dev/null
+++ b/doc/news/LWN_article.mdwn
@@ -0,0 +1,2 @@
+[Linux Weekly News](http://lwn.net/) has a nice
+[article on git-annex](http://lwn.net/Articles/418337/) in it this week.
diff --git a/doc/news/Presentation_at_FOSDEM.mdwn b/doc/news/Presentation_at_FOSDEM.mdwn
new file mode 100644
index 000000000..48daf2678
--- /dev/null
+++ b/doc/news/Presentation_at_FOSDEM.mdwn
@@ -0,0 +1,4 @@
+git-annex will be briefly presented at FOSDEM, on Sunday February 4th at 15:40.
+[Details](http://fosdem.org/2012/schedule/event/gitannex).
+
+Thanks to Richard Hartmann for making this presentation.
diff --git a/doc/news/git_annex_fall_of_code.mdwn b/doc/news/git_annex_fall_of_code.mdwn
new file mode 100644
index 000000000..79e0ff690
--- /dev/null
+++ b/doc/news/git_annex_fall_of_code.mdwn
@@ -0,0 +1,27 @@
+Thanks to my recent successful git-annex
+[crowdfunding campaign](http://campaign.joeyh.name/), $1000 has been set
+aside to award others for their contributions to git-annex by
+the end of 2013. This is not a lot of money, but I hope that the
+reward and recognition will encourage some more people to work on git-annex.
+
+You don't need to know Haskell! You could contribute some interesting and
+useful special remote hooks, or write better documentation.
+
+On the other hand, if you have learned Haskell, this might be your first
+chance to make some money with it! Some ideas for things to work on that
+would be particularly award-worthy:
+
+* Port git-annex to IOS, using [ghc-ios](https://github.com/ghc-ios).
+ I don't plan to ever do this myself, but you could make it happen.
+* Get the git-annex assistant working in Windows, building on the existing
+ port to Windows. Otherwise, this is on my roadmap for February.
+* Solve existing [[bugs]] or [[todo]] items. There are more than I can
+ keep up with.
+
+The amount of the awards will vary depending on the size of the
+contribution. Since this is getting started later than is ideal,
+I reserve the right to extend it past the end of the year if I don't get
+enough participants.
+
+If you'd like to participate in this program, just email me at
+<id@joeyh.name>. --[[Joey]]
diff --git a/doc/news/sharebox_a_FUSE_filesystem_for_git-annex.mdwn b/doc/news/sharebox_a_FUSE_filesystem_for_git-annex.mdwn
new file mode 100644
index 000000000..8eab9a34a
--- /dev/null
+++ b/doc/news/sharebox_a_FUSE_filesystem_for_git-annex.mdwn
@@ -0,0 +1,19 @@
+[[!meta title="sharebox: a FUSE filesystem for git-annex"]]
+
+Christophe-Marie Duquesne has just announced
+[Sharebox](https://github.com/chmduquesne/sharebox-fs), a FUSE filesystem
+relying on git-annex:
+
+<blockquote>
+<pre>
+What are your goals?
+Seamless synchronization "à la dropbox".
+Ability to use with big binary files such as mp3/movies.
+Entirely decentralized.
+Don't use unnecessary space
+Keep it simple: avoid special VCS commands and keep a filesystem
+interface as much as possible.
+</pre>
+</blockquote>
+
+While still alpha, this is promising. --[[Joey]]
diff --git a/doc/news/sharebox_a_FUSE_filesystem_for_git-annex/comment_1_e238d1734238e37bb55ff952b32e06b8._comment b/doc/news/sharebox_a_FUSE_filesystem_for_git-annex/comment_1_e238d1734238e37bb55ff952b32e06b8._comment
new file mode 100644
index 000000000..8754a7f9a
--- /dev/null
+++ b/doc/news/sharebox_a_FUSE_filesystem_for_git-annex/comment_1_e238d1734238e37bb55ff952b32e06b8._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlatTbI0K-qydpeYHl37iseqPNvERcdIMk"
+ nickname="Tiago"
+ subject="comment 1"
+ date="2012-09-27T00:08:19Z"
+ content="""
+This is what the assistant should aim to be...\"Like Dropbox\", but even better.
+I would guess many people who pledged were thinking of this.
+"""]]
diff --git a/doc/news/version_4.20130827/comment_1_937cbaccf235d6d9118aacd49058bb4f._comment b/doc/news/version_4.20130827/comment_1_937cbaccf235d6d9118aacd49058bb4f._comment
new file mode 100644
index 000000000..293938867
--- /dev/null
+++ b/doc/news/version_4.20130827/comment_1_937cbaccf235d6d9118aacd49058bb4f._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://sunny256.sunbase.org/"
+ nickname="sunny256"
+ subject="Missing from the downloads.kitenet.net annex"
+ date="2013-08-29T18:05:38Z"
+ content="""
+Great release, thanks a lot. It's missing from the annex at downloads.kitenet.net, though.
+
+Cheers,<br />
+Øyvind (sunny256)
+"""]]
diff --git a/doc/news/version_4.20130827/comment_2_faa5cf0645728b4ade850a691fa472db._comment b/doc/news/version_4.20130827/comment_2_faa5cf0645728b4ade850a691fa472db._comment
new file mode 100644
index 000000000..0002e8607
--- /dev/null
+++ b/doc/news/version_4.20130827/comment_2_faa5cf0645728b4ade850a691fa472db._comment
@@ -0,0 +1,25 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.7"
+ subject="comment 2"
+ date="2013-08-29T18:26:00Z"
+ content="""
+It seems to be there on downloads.kitenet.net. When I run `git log` in there I see commit 82de1ed1a354e389bc71a15af1a3e67b5bd56f23 which added the release to the annex, and all the files seem to be present. For example, git-annex-standalone-amd64.tar.gz is pointing at the key `SHA256E-s20143752--388c33138185fb2eb5fdb00bf2155a9168e5a76501216887ea1ffa7ada06b776.tar.gz`, which is right.
+
+<pre>
+joey@wren:~>wget http://downloads.kitenet.net/git-annex/linux/current/git-annex-standalone-amd64.tar.gz
+--2013-08-29 14:25:00-- http://downloads.kitenet.net/git-annex/linux/current/git-annex-standalone-amd64.tar.gz
+Resolving downloads.kitenet.net (downloads.kitenet.net)... 2001:41c8:125:49::10, 80.68.85.49
+Connecting to downloads.kitenet.net (downloads.kitenet.net)|2001:41c8:125:49::10|:80... connected.
+HTTP request sent, awaiting response... 200 OK
+Length: 20143752 (19M) [application/x-gzip]
+Saving to: ‘git-annex-standalone-amd64.tar.gz’
+
+100%[======================================>] 20,143,752 48.9MB/s in 0.4s
+
+2013-08-29 14:25:01 (48.9 MB/s) - ‘git-annex-standalone-amd64.tar.gz’ saved [20143752/20143752]
+
+joey@wren:~>sha256sum git-annex-standalone-amd64.tar.gz
+388c33138185fb2eb5fdb00bf2155a9168e5a76501216887ea1ffa7ada06b776 git-annex-standalone-amd64.tar.gz
+</pre>
+"""]]
diff --git a/doc/news/version_4.20130827/comment_3_ad156d6199b525884114ff823d265bf7._comment b/doc/news/version_4.20130827/comment_3_ad156d6199b525884114ff823d265bf7._comment
new file mode 100644
index 000000000..538395f90
--- /dev/null
+++ b/doc/news/version_4.20130827/comment_3_ad156d6199b525884114ff823d265bf7._comment
@@ -0,0 +1,39 @@
+[[!comment format=mdwn
+ username="http://sunny256.sunbase.org/"
+ nickname="sunny256"
+ subject="comment 3"
+ date="2013-08-30T11:43:44Z"
+ content="""
+Hm, commit 82de1ed1a3 doesn't exist here after git-annex sync. This is the output from another computer, running Linux Mint 15:
+
+ $ ga sync
+ commit
+ ok
+ pull linode
+ ok
+ pull kitenet
+ WARNING: gnome-keyring:: couldn't connect to: /run/user/sunny/keyring-WSsS6N/pkcs11: No such file or directory
+ ok
+ push linode
+ Everything up-to-date
+ ok
+ push kitenet
+ WARNING: gnome-keyring:: couldn't connect to: /run/user/sunny/keyring-WSsS6N/pkcs11: No such file or directory
+ WARNING: gnome-keyring:: couldn't connect to: /run/user/sunny/keyring-WSsS6N/pkcs11: No such file or directory
+ error: Cannot access URL http://downloads.kitenet.net/.git/, return code 22
+ fatal: git-http-push failed
+ failed
+ git-annex: sync: 1 failed
+ $ git log -1
+ commit e4d2f03d9b37b2fac9508bf755ff7619bf46590c (HEAD, linode/synced/master, linode/master, linode/HEAD, kitenet/synced/master, kitenet/master, synced/master, master)
+ Author: Joey Hess <joey@kitenet.net>
+ Date: 3 weeks ago
+
+ update
+ 2013-08-30 13:36:37 sunny@passp:~/src/other/annex/downloads.kitenet.net/git-annex (master u=)
+ $ git log 82de1ed1a354e389bc71a15af1a3e67b5bd56f23
+ fatal: bad object 82de1ed1a354e389bc71a15af1a3e67b5bd56f23
+
+There's some warnings from gnome-keyring and a failed push (sorry about that, happens automatically), but the fetch from kitenet seems to succeed.
+
+"""]]
diff --git a/doc/news/version_4.20130827/comment_4_877061eb24d9d9543cc9cd229906bd64._comment b/doc/news/version_4.20130827/comment_4_877061eb24d9d9543cc9cd229906bd64._comment
new file mode 100644
index 000000000..5828a36c7
--- /dev/null
+++ b/doc/news/version_4.20130827/comment_4_877061eb24d9d9543cc9cd229906bd64._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://sunny256.sunbase.org/"
+ nickname="sunny256"
+ subject="comment 4"
+ date="2013-08-30T11:49:20Z"
+ content="""
+And some additional info, I'm using `http://downloads.kitenet.net/.git/` as the address to your annex. Maybe this repo is missing a `git update-server-info` in the `post-update` hook or something.
+"""]]
diff --git a/doc/news/version_4.20130827/comment_5_8991648dda991768e3a58477a4c3c923._comment b/doc/news/version_4.20130827/comment_5_8991648dda991768e3a58477a4c3c923._comment
new file mode 100644
index 000000000..55fa6d10a
--- /dev/null
+++ b/doc/news/version_4.20130827/comment_5_8991648dda991768e3a58477a4c3c923._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.7"
+ subject="sorry for delay.."
+ date="2013-09-03T18:07:34Z"
+ content="""
+That's weird.. I have a post-update hook that runs git-update-server-info, but I reproduced the problem, and manually running that fixed it.
+
+Guess I will need to keep an eye on this at the next release to see if it was a one-off problem..
+"""]]
diff --git a/doc/news/version_4.20131024.mdwn b/doc/news/version_4.20131024.mdwn
new file mode 100644
index 000000000..9cd65eb72
--- /dev/null
+++ b/doc/news/version_4.20131024.mdwn
@@ -0,0 +1,43 @@
+git-annex 4.20131024 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+ * webapp: Fix bug when adding a remote and git-remote-gcrypt
+ is not installed.
+ * The assitant can now run scheduled incremental fsck jobs on the local
+ repository and remotes. These can be configured using vicfg or with the
+ webapp.
+ * repair: New command, which can repair damaged git repositories
+ (even ones not using git-annex).
+ * webapp: When git repository damange is detected, repairs can be
+ done using the webapp UI.
+ * Automatically and safely detect and recover from dangling
+ .git/annex/index.lock files, which would prevent git from
+ committing to the git-annex branch, eg after a crash.
+ * assistant: Detect stale git lock files at startup time, and remove them.
+ * addurl: Better sanitization of generated filenames.
+ * Better sanitization of problem characters when generating URL and WORM
+ keys.
+ * The control socket path passed to ssh needs to be 17 characters
+ shorter than the maximum unix domain socket length, because ssh
+ appends stuff to it to make a temporary filename. Closes: #[725512](http://bugs.debian.org/725512)
+ * status: Fix space leak in local mode, introduced in version 4.20130920.
+ * import: Skip .git directories.
+ * Remove bogus runshell loop check.
+ * addurl: Improve message when adding url with wrong size to existing file.
+ * Fixed handling of URL keys that have no recorded size.
+ * status: Fix a crash if a temp file went away while its size was
+ being checked for status.
+ * Deal with git check-attr -z output format change in git 1.8.5.
+ * Work around sed output difference that led to version containing a newline
+ on OSX.
+ * sync: Fix automatic resolution of merge conflicts where one side is an
+ annexed file, and the other side is a non-annexed file, or a directory.
+ * S3: Try to ensure bucket name is valid for archive.org.
+ * assistant: Bug fix: When run in a subdirectory, files from incoming merges
+ were wrongly added to that subdirectory, and removed from their original
+ locations.
+ * Windows: Deal with strange msysgit 1.8.4 behavior of not understanding
+ DOS formatted paths for --git-dir and --work-tree.
+ * Removed workaround for bug in git 1.8.4r0.
+ * Added git-recover-repository command to git-annex source
+ (not built by default; this needs to move to someplace else).
+ * webapp: Move sidebar to the right hand side of the screen."""]] \ No newline at end of file
diff --git a/doc/news/version_4.20131101.mdwn b/doc/news/version_4.20131101.mdwn
new file mode 100644
index 000000000..2c6bb309d
--- /dev/null
+++ b/doc/news/version_4.20131101.mdwn
@@ -0,0 +1,29 @@
+git-annex 4.20131101 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+ * The "git annex content" command is renamed to "git annex wanted".
+ * New --want-get and --want-drop options which can be used to
+ test preferred content settings.
+ For example, "git annex find --in . --want-drop"
+ * assistant: When autostarted, wait 5 seconds before running the startup
+ scan, to avoid contending with the user's desktop login process.
+ * webapp: When setting up a bare shared repository, enable non-fast-forward
+ pushes.
+ * sync: Show a hint about receive.denyNonFastForwards when a push fails.
+ * directory, webdav: Fix bug introduced in version 4.20131002 that
+ caused the chunkcount file to not be written. Work around repositories
+ without such a file, so files can still be retreived from them.
+ * assistant: Automatically repair damanged git repository, if it can
+ be done without losing data.
+ * assistant: Support repairing git remotes that are locally accessible
+ (eg, on removable drives).
+ * add: Fix reversion in 4.20130827 when adding unlocked files that have
+ not yet been committed.
+ * unannex: New, much slower, but more safe behavior: Copies files out of
+ the annex. This avoids an unannex of one file breaking other files that
+ link to the same content. Also, it means that the content
+ remains in the annex using up space until cleaned up with
+ "git annex unused".
+ (The behavior of unannex --fast has not changed; it still hard links
+ to content in the annex. --fast was not made the default because it is
+ potentially unsafe; editing such a hard linked file can unexpectedly
+ change content stored in the annex.)"""]] \ No newline at end of file
diff --git a/doc/news/version_4.20131106.mdwn b/doc/news/version_4.20131106.mdwn
new file mode 100644
index 000000000..061d02100
--- /dev/null
+++ b/doc/news/version_4.20131106.mdwn
@@ -0,0 +1,18 @@
+git-annex 4.20131106 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+ * Improve local pairing behavior when two computers both try to start
+ the pairing process separately.
+ * sync: Work even when the local git repository is new and empty,
+ with no master branch.
+ * gcrypt, bup: Fix bug that prevented using these special remotes
+ with encryption=pubkey.
+ * Fix enabling of gcrypt repository accessed over ssh;
+ git-annex-shell gcryptsetup had a bug that caused it to fail
+ with permission denied.
+ * Fix zombie process that occurred when switching between repository
+ views in the webapp.
+ * map: Work when there are gcrypt remotes.
+ * Fix build w/o webapp.
+ * Fix exception handling bug that could cause .git/annex/index to be used
+ for git commits outside the git-annex branch. Known to affect git-annex
+ when used with the git shipped with Ubuntu 13.10."""]] \ No newline at end of file
diff --git a/doc/news/version_5.20131118.mdwn b/doc/news/version_5.20131118.mdwn
new file mode 100644
index 000000000..2323ec63b
--- /dev/null
+++ b/doc/news/version_5.20131118.mdwn
@@ -0,0 +1,42 @@
+git-annex 5.20131118 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+ * Direct mode repositories now have core.bare=true set, to prevent
+ accidentally running git commands that try to operate on the work tree,
+ and so do the wrong thing in direct mode.
+ * annex.version is now set to 5 for direct mode repositories.
+ This upgrade is handled fully automatically, no need to run
+ git annex upgrade
+ * The "status" command has been renamed to "info", to allow
+ "git annex status" to be used in direct mode repositories, now that
+ "git status" won't work in them.
+ * The -c option now not only modifies the git configuration seen by
+ git-annex, but it is passed along to every git command git-annex runs.
+ * watcher: Avoid loop when adding a file owned by someone else fails
+ in indirect mode because its permissions cannot be modified.
+ * webapp: Avoid encoding problems when displaying the daemon log file.
+ * webapp: Improve UI around remote that have no annex.uuid set,
+ either because setup of them is incomplete, or because the remote
+ git repository is not a git-annex repository.
+ * Include ssh-keygen in standalone bundle.
+ * Allow optionally configuring git-annex with -fEKG to enable awesome
+ remote monitoring interfaceat http://localhost:4242/
+ * Fix bug that caused bad information to be written to the git-annex branch
+ when running describe or other commands with a remote that has no uuid.
+ * Work around Android linker problem that had prevented git-annex from
+ running on Android 4.3 and 4.4.
+ * repair: Handle case where index file is corrupt, but all objects are ok.
+ * assistant: Notice on startup when the index file is corrupt, and
+ auto-repair.
+ * Fix direct mode merge bug when a direct mode file was deleted and replaced
+ with a directory. An ordering problem caused the directory to not get
+ created in this case.
+ Thanks to Tim for the test case.
+ * Direct mode .git/annex/objects directories are no longer left writable,
+ because that allowed writing to symlinks of files that are not present,
+ which followed the link and put bad content in an object location.
+ Thanks to Tim for the test case.
+ * fsck: Fix up .git/annex/object directory permissions.
+ * Switched to the tasty test framework.
+ * Android: Adjust default .gitignore to ignore .thumbnails at any location
+ in the tree, not just at its top.
+ * webapp: Check annex.version."""]] \ No newline at end of file
diff --git a/doc/news/version_5.20131120.mdwn b/doc/news/version_5.20131120.mdwn
new file mode 100644
index 000000000..0470e3336
--- /dev/null
+++ b/doc/news/version_5.20131120.mdwn
@@ -0,0 +1,11 @@
+git-annex 5.20131120 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+ * Fix Debian package to not try to run test suite, since haskell-tasty
+ is not out of new or in Build-Depends yet.
+ * dropunused, addunused: Allow "all" instead of a range to
+ act on all unused data.
+ * Ensure execute bit is set on directories when core.sharedrepository is set.
+ * Ensure that core.sharedrepository is honored when creating the .git/annex
+ directory.
+ * Improve repair code in the case where the index file is corrupt,
+ and this hides other problems from git fsck."""]] \ No newline at end of file
diff --git a/doc/not.mdwn b/doc/not.mdwn
new file mode 100644
index 000000000..3b7cdc1cf
--- /dev/null
+++ b/doc/not.mdwn
@@ -0,0 +1,55 @@
+[[!meta title="what git-annex is not"]]
+
+* git-annex is not a backup system. It may be a useful component of an
+ [[archival|use_case/bob]] system, or a way to deliver files to a backup
+ system. For a backup system that uses git and that git-annex supports
+ storing data in, see [[special_remotes/bup]].
+
+* git-annex is not a filesystem or DropBox clone. However, the git-annex
+ [[assistant]] is addressing some of the same needs in its own unique ways.
+ (There is also a FUSE filesystem built on top of git-annex, called
+ [ShareBox](https://github.com/chmduquesne/sharebox-fs).)
+
+* git-annex is not unison, but if you're finding unison's checksumming
+ too slow, or its strict mirroring of everything to both places too
+ limiting, then git-annex could be a useful alternative.
+
+* git-annex is more than just a workaround for git scalability
+ limitations that might eventually be fixed by efforts like
+ [git-bigfiles](http://caca.zoy.org/wiki/git-bigfiles). In particular,
+ git-annex's [[location_tracking]] allows having many repositories
+ with a partial set of files, that are copied around as desired.
+
+* git-annex is not some flaky script that was quickly thrown together.
+ I wrote it in Haskell because I wanted it to be solid and to compile
+ down to a binary. And it has a fairly extensive test suite. (Don't be
+ fooled by "make test" only showing a few dozen test cases; each test
+ involves checking dozens to hundreds of assertions.)
+
+* git-annex is not [git-media](https://github.com/schacon/git-media),
+ although they both approach the same problem from a similar direction.
+ I only learned of git-media after writing git-annex, but I probably
+ would have still written git-annex instead of using it. Currently,
+ git-media has the advantage of using git smudge filters rather than
+ git-annex's pile of symlinks, and it may be a tighter fit for certain
+ situations. It lacks git-annex's support for widely distributed storage,
+ using only a single backend data store. It also does not support
+ partial checkouts of file contents, like git-annex does.
+
+* git-annex is similarly not [git-fat](https://github.com/jedbrown/git-fat),
+ which also uses git smudge filters, and also lacks git-annex' widely
+ distributed storage and partial checkouts.
+
+* git-annex is also not [boar](http://code.google.com/p/boar/),
+ although it shares many of its goals and characteristics. Boar implements
+ its own version control system, rather than simply embracing and
+ extending git. And while boar supports distributed clones of a repository,
+ it does not support keeping different files in different clones of the
+ same repository, which git-annex does, and is an important feature for
+ large-scale archiving.
+
+* git-annex is not the [Mercurial largefiles extension](http://mercurial.selenic.com/wiki/LargefilesExtension).
+ Although mercurial and git have some of the same problems around large
+ files, and both try to solve them in similar ways (standin files using
+ mostly hashes of the real content).
+
diff --git a/doc/not/comment_1_ab41bec1ccc884e71780cb9458439170._comment b/doc/not/comment_1_ab41bec1ccc884e71780cb9458439170._comment
new file mode 100644
index 000000000..6a7eed33b
--- /dev/null
+++ b/doc/not/comment_1_ab41bec1ccc884e71780cb9458439170._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://bergey.dreamwidth.org/"
+ ip="66.80.90.109"
+ subject="git-media"
+ date="2012-07-14T15:42:05Z"
+ content="""
+I haven't used git-media, but from the README it looks as though they now support several backends. Might want to update the (very helpful!) comparison.
+"""]]
diff --git a/doc/not/comment_2_0e19ff7deb5ed65f2bc685d4c516d816._comment b/doc/not/comment_2_0e19ff7deb5ed65f2bc685d4c516d816._comment
new file mode 100644
index 000000000..926df6bc1
--- /dev/null
+++ b/doc/not/comment_2_0e19ff7deb5ed65f2bc685d4c516d816._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkurjhi0CRJvgm7QNaZDWS9hitBtavqIpc"
+ nickname="Bret"
+ subject="Sparkleshare"
+ date="2012-09-06T08:09:17Z"
+ content="""
+How does [sparkleshare](http://sparkleshare.org/) and git-annex (and git-annex assistant) compare?
+"""]]
diff --git a/doc/not/comment_3_bab9584c41a25dda934ad230e3eb732d._comment b/doc/not/comment_3_bab9584c41a25dda934ad230e3eb732d._comment
new file mode 100644
index 000000000..eb66e0b3d
--- /dev/null
+++ b/doc/not/comment_3_bab9584c41a25dda934ad230e3eb732d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.236"
+ subject="comment 3"
+ date="2012-09-06T14:50:43Z"
+ content="""
+My understanding of sparkleshare (I've not used it) is that it uses a regular git repository, so has git's problems with large files and will not support partial checkouts. However, you might want to try it out and see if it works for you.
+"""]]
diff --git a/doc/not/comment_4_b2a0d5a45ab8ddd66c29dde9412d7a12._comment b/doc/not/comment_4_b2a0d5a45ab8ddd66c29dde9412d7a12._comment
new file mode 100644
index 000000000..10baf5f45
--- /dev/null
+++ b/doc/not/comment_4_b2a0d5a45ab8ddd66c29dde9412d7a12._comment
@@ -0,0 +1,51 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn4bbuawnh-nSo9pAh8irYAcV4MQCcfdHo"
+ nickname="Stefan"
+ subject="Sparkleshare"
+ date="2012-09-15T01:28:05Z"
+ content="""
+Hi,
+
+I used sparkleshare lately in a project involving 3 computers and 2 people. and for ascii texts and even a few smaller binary things it works ok.
+
+But it does \"to much\" for media. at least at the moment, it just uses git for saving the data. That has a possitive and a negative aspect.
+
+possitive:
+
+1. you have a full history, if you delete a file its not gone for ever, so if you change it, the older version is still recoverable.
+2. if you would as example use it from a laptop in a train without internet and you use a git server in the internet for the central server, and would change some files, then you or somebody else would write on the same txt file as example (html or something... latex...) you would be able to merge this files.
+3. its not totaly bad for backup, because you can restore old files even if you delete it localy, because it will hold all history
+
+
+negative:
+
+1. for bigger data its cracy. if you use it for movies as example, you would in git annex delete some stuff you want not to see anytime again, so you would delete it everywhere. and its really away, not beeing still there in the history
+2. git as it is has issues with saving/transfairing very big files, and its slow on even mid-sized files lets say 100 5mb big files it would be slow. because at the moment sparkleshare uses git all this disatvantages are there.
+3. as many clients you use lets say a projekt with 10 people, each of them have all files and all the history of this projekt/directory on their pc.
+4. you need a central data-store git folder you can use a seperate pc for that or save it on a client, if you use a client for that you have to save the data double on this pc.
+
+(so you see for big files even if git would handle them faster you would waste massivly hard disk space) but again for pdfs a few pictures text files even some office files and stuff <100mb its great and easy to do.
+
+
+I try it in a few words, sparkleshare is like dropbox but with file history ( I think dropbox dont have that???) but because git is not designed (yet) for big files it works somewhat ok for < 100mb stuff if you go very much higher > 1GB it will not be optimal.
+
+git annex dont saves the data itself in git but only the locations and the checksums. so its more like a adress book of your data. its a abstraction layer to your data, you can see on as many devises as you want even without no netzwerk internet connection active and only a very small hd see all your 5 Terrabyte of Data you might have, and move around directories sort around them... delete stuff you dont want if you can deside that by the name... and then when you come back to the connection you sync your actions and it does it to the files.
+
+And one big feature like joey said is that you cannot partialy load files from the repos to your device if it has as example only enough space for 1/10 of it.
+
+There is another thing, but because it is \"only\" a abstraction layer, it is theoreticaly easy to implement extentions to save your data on anything not only git repositories...
+
+Sparkleshare will switch to something else than git, maybe but then it will switch to this single protocol and stick to that. because it does not abstract stuff so hard.
+
+btw there is a alternative out there it forces you not to use git as vcs but you have to use a vcs (like git) and you dont have to use the client written in mono but only a smaller python script:
+
+http://www.mayrhofer.eu.org/dvcs-autosync
+
+but the idea behind it is the same except this 2 points ;)
+
+
+but many free software developers dont like mono, so the change that it gets more love from more people is not totaly unlikely.
+
+
+So way to long post but hope that helps somebody ;)
+"""]]
diff --git a/doc/not/comment_5_f2829ecbe80a61aa9a8411d2403de69e._comment b/doc/not/comment_5_f2829ecbe80a61aa9a8411d2403de69e._comment
new file mode 100644
index 000000000..02597ceb8
--- /dev/null
+++ b/doc/not/comment_5_f2829ecbe80a61aa9a8411d2403de69e._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn4bbuawnh-nSo9pAh8irYAcV4MQCcfdHo"
+ nickname="Stefan"
+ subject="comment 5"
+ date="2012-09-15T01:35:06Z"
+ content="""
+or to make it more simple ;)
+
+sparkleshare is for proejects and maybe backup your documents folder
+
+annex is for managing big binary files that not get modified most of the time and only added/synced or deleted.
+
+hope thats on the point, try to start using it also now, but am a bit blowen away what it all can do and what not... and how to get a good use case, and mixing media-management with backup of home and thinking on solving that all with annex without having it used ever ;)
+"""]]
diff --git a/doc/not/comment_6_547fc59b19ad66d7280c53a7f923ea08._comment b/doc/not/comment_6_547fc59b19ad66d7280c53a7f923ea08._comment
new file mode 100644
index 000000000..9980f0e4c
--- /dev/null
+++ b/doc/not/comment_6_547fc59b19ad66d7280c53a7f923ea08._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlatTbI0K-qydpeYHl37iseqPNvERcdIMk"
+ nickname="Tiago"
+ subject="comment 6"
+ date="2012-09-27T10:17:18Z"
+ content="""
+Stefan: \"annex is for managing big binary files that not get modified most of the time and only added/synced or deleted.\"
+
+While this is true, the kickstarter title for assistant was \"Like dropbox\", and dropbox makes it transparent to edit files and they work with the filesystem.
+So with assistant, lock/unlock should be automated and transparent to the user. Otherwise it's confusing and not simple at all to use, and at least OSX keeps giving errors because of the way it handles aliases.
+So something like sharebox is essential to be included in assistant in my opinion.
+
+"""]]
diff --git a/doc/not/comment_7_581e23cca0219711f8a4500a8d5d20fc._comment b/doc/not/comment_7_581e23cca0219711f8a4500a8d5d20fc._comment
new file mode 100644
index 000000000..f1bb83353
--- /dev/null
+++ b/doc/not/comment_7_581e23cca0219711f8a4500a8d5d20fc._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="l3iggs"
+ ip="24.130.145.126"
+ subject="comment 7"
+ date="2013-02-03T03:57:05Z"
+ content="""
+hi joey,
+
+i'm excited by your project here but also confused by its direction. the kickstarter page has the header: \"git-annex assistant: Like DropBox, but with your own cloud.\" this page says \"git-annex is not a ... DropBox clone.\" these seem to be in direct opposition.
+
+i'm looking for what is described by the header on your kickstarter page. i assume your backers are looking for the the same thing (a self hosted DropBox). for my use, dropbox is perfect, except for the fact that i have to pay a monthly fee to store my data on someone else's server when i would like to buy my own storage medium and run some open source dropbox clone on my own server.
+
+can you explain more clearly what dropbox features your project lacks (/will lack)? and why where is a difference between your fundraising page and this one?
+
+maybe i'm just confused by the difference between git-annex and git-annex assistant. does git-annex assistant truely aim to be a dropbox clone?
+"""]]
diff --git a/doc/not/comment_8_5c61457f117de38ef487e5cc2780d554._comment b/doc/not/comment_8_5c61457f117de38ef487e5cc2780d554._comment
new file mode 100644
index 000000000..1a955c862
--- /dev/null
+++ b/doc/not/comment_8_5c61457f117de38ef487e5cc2780d554._comment
@@ -0,0 +1,24 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="99.54.57.201"
+ subject="comment 8"
+ date="2013-02-04T03:17:06Z"
+ content="""
+It's pretty much exactly what he said:
+
+> git-annex is not a filesystem or DropBox clone. However, the git-annex assistant is addressing some of the same needs in its own unique ways.
+
+The git-annex assistant is not exactly like DropBox; it's not a drop-in replacement that works exactly the way dropbox works. But as it stands, right now, it can (like Dropbox) run in the background and make sure that all of your files in a special directory are mirrored to another place (a USB drive, or a server to which you have SSH access, or another computer on your home network, or another computer somewhere else which has access to the same USB drive from time to time, or has accesss to the same SSH server or S3 repository or....
+
+It works as is but is still under heavy development and features are being added rapidly. For example, up until a month or two ago, the files in your annex were replaced with softlinks whose content resided in a hidden directory. This caused some problems esp. on OS X where native programs don't handle softlinked files very gracefully. So Joey added an entirely new way of operating called \"direct mode\" which uses ordinary files, much like Dropbox does.
+
+So -- what you should expect from git-annex assistant is a program which solves many of the same problems Dropbox does (keeping a set of files magically in sync across computers) but does it in its own way, which won't be *exactly* like Dropbox; it will be more flexible but might require a little learning to figure out exactly how to use it the way you want. It's possible to get a very Dropbox-like system out of the box, especially now that you don't need to use softlinks, if you've got a place on the network you can use as a central remote repository for your files, or if you only want to synchronize two or more computers on the same local network.
+
+\"git-annex\" itself is the plumbing used by git-annex assistant, or to put it another way, the engine that the assistant has under the hood. Git-annex itself is extremely simple and stable but should only be used by people already familiar with the command line, perhaps even people already familiar with git.
+
+That's my point of view as an enthusiastic user. Joey may have his own perspective to share. :)
+
+
+
+
+"""]]
diff --git a/doc/polls.mdwn b/doc/polls.mdwn
new file mode 100644
index 000000000..55c779867
--- /dev/null
+++ b/doc/polls.mdwn
@@ -0,0 +1,2 @@
+* [[2013 git-annex user survey|2013]]
+* [[old polls|design/assistant/polls]]
diff --git a/doc/polls/2013.mdwn b/doc/polls/2013.mdwn
new file mode 100644
index 000000000..bda584d64
--- /dev/null
+++ b/doc/polls/2013.mdwn
@@ -0,0 +1,5 @@
+This has moved to a separate site due to load issues.
+
+<http://git-annex-survey.branchable.com/polls/2013/>
+
+Any votes you made here were carried over, so no need to vote twice!
diff --git a/doc/preferred_content.mdwn b/doc/preferred_content.mdwn
new file mode 100644
index 000000000..6a5364f67
--- /dev/null
+++ b/doc/preferred_content.mdwn
@@ -0,0 +1,207 @@
+git-annex tries to ensure that the configured number of [[copies]] of your
+data always exist, and leaves it up to you to use commands like `git annex
+get` and `git annex drop` to move the content to the repositories you want
+to contain it. But sometimes, it can be good to have more fine-grained
+control over which repositories prefer to have which content. Configuring
+this allows `git annex get --auto`, `git annex drop --auto`, etc to do
+smarter things.
+
+Preferred content settings can be edited using `git
+annex vicfg`, or viewed and set at the command line with `git annex wanted`.
+Each repository can have its own settings, and other repositories may also
+try to honor those settings. So there's no local `.git/config` setting it.
+
+The idea is that you write an expression that files are matched against.
+If a file matches, it's preferred to have its content stored in the
+repository. If it doesn't, it's preferred to drop its content from
+the repository (if there are enough copies elsewhere).
+
+The expressions are very similar to the file matching options documented
+on the [[git-annex]] man page. At the command line, you can use those
+options in commands like this:
+
+ git annex get --include='*.mp3' --and -'(' --not --largerthan=100mb -')'
+
+The equivilant preferred content expression looks like this:
+
+ include=*.mp3 and (not largerthan=100mb)
+
+So, just remove the dashes, basically. However, there are some differences
+from the command line options to keep in mind:
+
+### difference: file matching
+
+While --include and --exclude match files relative to the current
+directory, preferred content expressions always match files relative to the
+top of the git repository. Perhaps you put files into `archive` directories
+when you're done with them. Then you could configure your laptop to prefer
+to not retain those files, like this:
+
+ exclude=*/archive/*
+
+### difference: no "in="
+
+Preferred content expressions have no direct equivilant to `--in`.
+
+Often, it's best to add repositories to groups, and match against
+the groups in a preferred content expression. So rather than
+`--in=usbdrive`, put all the USB drives into a "transfer" group,
+and use "copies=transfer:1"
+
+### difference: dropping
+
+To decide if content should be dropped, git-annex evaluates the preferred
+content expression under the assumption that the content has *already* been
+dropped. If the content would not be preferred then, the drop can be done.
+So, for example, `copies=2` in a preferred content expression lets
+content be dropped only when there are currently 3 copies of it, including
+the repo it's being dropped from. This is different than running `git annex
+drop --copies=2`, which will drop files that currently have 2 copies.
+
+### difference: "present"
+
+There's a special "present" keyword you can use in a preferred content
+expression. This means that content is preferred if it's present,
+and not otherwise. This leaves it up to you to use git-annex manually
+to move content around. You can use this to avoid preferred content
+settings from affecting a subdirectory. For example:
+
+ auto/* or (include=ad-hoc/* and present)
+
+Note that `not present` is a very bad thing to put in a preferred content
+expression. It'll make it prefer to get content that's not present, and
+drop content that is present! Don't go there..
+
+### difference: "inpreferreddir"
+
+There's a special "inpreferreddir" keyword you can use in a
+preferred content expression of a special remote. This means that the
+content is preferred if it's in a directory (located anywhere in the tree)
+with a special name.
+
+The name of the directory can be configured using
+`git annex enableremote $remote preferreddir=$dirname`
+
+(If no directory name is configured, it uses "public" by default.)
+
+## testing preferred content settings
+
+To check at the command line which files are matched by preferred content
+settings, you can use the --want-get and --want-drop options.
+
+For example, "git annex find --want-get --not --in ." will find all the
+files that "git annex get --auto" will want to get, and "git annex find
+--want-drop --in ." will find all the files that "git annex drop --auto"
+will want to drop.
+
+## standard expressions
+
+git-annex comes with some standard preferred content expressions, that can
+be used with repositories that are in some pre-defined groups. To make a
+repository use one of these, just set its preferred content expression
+to "standard", and put it in one of these groups.
+
+(Note that most of these standard expressions also make the repository
+prefer any content that is only currently available on untrusted and
+dead repositories. So if an untrusted repository gets connected,
+any repository that can will back it up.)
+
+### client
+
+All content is preferred, unless it's for a file in a "archive" directory,
+which has reached an archive repository.
+
+`((exclude=*/archive/* and exclude=archive/*) or (not (copies=archive:1 or copies=smallarchive:1))) or (not copies=semitrusted+:1)`
+
+### transfer
+
+Use for repositories that are used to transfer data between other
+repositories, but do not need to retain data themselves. For
+example, a repository on a server, or in the cloud, or a small
+USB drive used in a sneakernet.
+
+The preferred content expression for these causes them to get and retain
+data until all clients have a copy.
+
+`(not (inallgroup=client and copies=client:2) and ($client)`
+
+The "copies=client:2" part of the above handles the case where
+there is only one client repository. It makes a transfer repository
+speculatively prefer content in this case, even though it as of yet
+has nowhere to transfer it to. Presumably, another client repository
+will be added later.
+
+### backup
+
+All content is preferred.
+
+`include=*`
+
+### incremental backup
+
+Only prefers content that's not already backed up to another backup
+or incremental backup repository.
+
+`(include=* and (not copies=backup:1) and (not copies=incrementalbackup:1)) or (not copies=semitrusted+:1)`
+
+### small archive
+
+Only prefers content that's located in an "archive" directory, and
+only if it's not already been archived somewhere else.
+
+`((include=*/archive/* or include=archive/*) and not (copies=archive:1 or copies=smallarchive:1)) or (not copies=semitrusted+:1)`
+
+### full archive
+
+All content is preferred, unless it's already been archived somewhere else.
+
+`(not (copies=archive:1 or copies=smallarchive:1)) or (not copies=semitrusted+:1)`
+
+Note that if you want to archive multiple copies (not a bad idea!),
+you should instead configure all your archive repositories with a
+version of the above preferred content expression with a larger
+number of copies.
+
+### source
+
+Use for repositories where files are often added, but that do not need to
+retain files for local use. For example, a repository on a camera, where
+it's desirable to remove photos as soon as they're transferred elsewhere.
+
+The preferred content expression for these causes them to only retain
+data until a copy has been sent to some other repository.
+
+`not (copies=1)`
+
+### manual
+
+This gives you nearly full manual control over what content is stored in the
+repository. This allows using the [[assistant]] without it trying to keep a
+local copy of every file. Instead, you can manually run `git annex get`,
+`git annex drop`, etc to manage content. Only content that is present
+is preferred.
+
+The exception to this manual control is that content that a client
+repository would not want is not preferred. So, files in archive
+directories are not preferred once their content has
+reached an archive repository.
+
+`present and ($client)`
+
+### public
+
+This is used for publishing information to a repository that can be
+publically accessed. Only files in a directory with a particular name
+will be published. (The directory can be located anywhere in the
+repository.)
+
+The name of the directory can be configured using
+`git annex enableremote $remote preferreddir=$dirname`
+
+### unwanted
+
+Use for repositories that you don't want to exist. This will result
+in any content on them being moved away to other repositories. (Works
+best when the unwanted repository is also marked as untrusted or dead.)
+
+`exclude=*`
diff --git a/doc/preferred_content/comment_10_f0bce3c67f293eaba97b92f0942876b6._comment b/doc/preferred_content/comment_10_f0bce3c67f293eaba97b92f0942876b6._comment
new file mode 100644
index 000000000..cd7c36fe4
--- /dev/null
+++ b/doc/preferred_content/comment_10_f0bce3c67f293eaba97b92f0942876b6._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.22"
+ subject="comment 10"
+ date="2013-10-11T17:12:00Z"
+ content="""
+Georg, `drop --auto` will only drop files that are not preferred content. I'd need to know what preferred content expression you're using to say more.
+"""]]
diff --git a/doc/preferred_content/comment_1_7d45e21dfb016e9ffa4715346dd0c1a6._comment b/doc/preferred_content/comment_1_7d45e21dfb016e9ffa4715346dd0c1a6._comment
new file mode 100644
index 000000000..728e23dc2
--- /dev/null
+++ b/doc/preferred_content/comment_1_7d45e21dfb016e9ffa4715346dd0c1a6._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlgyVag95OnpvSzQofjyX0WjW__MOMKsl0"
+ nickname="Sehr"
+ subject="Interplay with numcopies"
+ date="2012-12-05T20:41:26Z"
+ content="""
+How does the preferred content settings interfere with the numcopies setting?
+
+I could not get behind it. E.g. a case I do not unterstand:
+
+I have a preferred setting evaluating to true and still
+
+ git annex get --auto
+
+does nothing, if the number of copies produced would surpass the numcopies setting.
+
+
+Thx
+"""]]
diff --git a/doc/preferred_content/comment_2_1ccd90b009245667ad59f4d29d2a3a37._comment b/doc/preferred_content/comment_2_1ccd90b009245667ad59f4d29d2a3a37._comment
new file mode 100644
index 000000000..51e5f2701
--- /dev/null
+++ b/doc/preferred_content/comment_2_1ccd90b009245667ad59f4d29d2a3a37._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.253.113"
+ subject="comment 2"
+ date="2012-12-06T17:24:29Z"
+ content="""
+Yeah, that didn't make sense. I've fixed it, so it gets files if needed for either numcopies or preferred content.
+"""]]
diff --git a/doc/preferred_content/comment_4_384025b5fa23a3f175985a081438149f._comment b/doc/preferred_content/comment_4_384025b5fa23a3f175985a081438149f._comment
new file mode 100644
index 000000000..e6d13ca04
--- /dev/null
+++ b/doc/preferred_content/comment_4_384025b5fa23a3f175985a081438149f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.117"
+ subject="comment 4"
+ date="2012-12-10T19:46:01Z"
+ content="""
+It was a bug in the backup group's preferred content pagespec, introduced by the changes I made to fix the previous problem. Now fixed.
+"""]]
diff --git a/doc/preferred_content/comment_4_6a9bc657bc7415f0e118357d8c6664c6._comment b/doc/preferred_content/comment_4_6a9bc657bc7415f0e118357d8c6664c6._comment
new file mode 100644
index 000000000..0ac5dec52
--- /dev/null
+++ b/doc/preferred_content/comment_4_6a9bc657bc7415f0e118357d8c6664c6._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 4"
+ date="2012-12-07T20:24:18Z"
+ content="""
+Built a new copy of git-annex yesterday. I have a \"client\" on my macbook, and two \"backup\"s, one on an external HD, one on an ssh git remote.
+
+git annex get --auto works beautifully!
+
+It doesn't seem to work for copying content *to* a place where it's needed, though.
+
+If I drop a file from my \"backup\" USB drive, and then go back to my macbook and do a \"git annex sync\" and \"git annex copy --to=usbdrive --auto\" it does not send the file out to the USB drive, even though by preferred content settings, the USB drive should \"want\" the file because it's a backup drive and it wants all content.
+
+Similarly, if I add a new file on my macbook and then do a \"git annex copy --to=usbdrive auto\" it does not get copied to the USB drive.
+
+Is this missing functionality, or should the preferred content setting for remotes only affect the assistant?
+"""]]
diff --git a/doc/preferred_content/comment_5_f0a957e67297c4bb5a8778c11b3c9fd4._comment b/doc/preferred_content/comment_5_f0a957e67297c4bb5a8778c11b3c9fd4._comment
new file mode 100644
index 000000000..7074541eb
--- /dev/null
+++ b/doc/preferred_content/comment_5_f0a957e67297c4bb5a8778c11b3c9fd4._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 5"
+ date="2012-12-11T16:03:04Z"
+ content="""
+thanks!
+
+"""]]
diff --git a/doc/preferred_content/comment_6_b434c0e2aaa132020fd4a01551285376._comment b/doc/preferred_content/comment_6_b434c0e2aaa132020fd4a01551285376._comment
new file mode 100644
index 000000000..12deccb35
--- /dev/null
+++ b/doc/preferred_content/comment_6_b434c0e2aaa132020fd4a01551285376._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmRFKwny4rArBaz-36xTcsJYqKIgdDaw5Q"
+ nickname="Andrew"
+ subject="comment 6"
+ date="2013-01-10T03:00:52Z"
+ content="""
+Is there a way to change these definitions for a given annex?
+
+ie: in this repo make \"client\" mean
+
+ present and exclude=*/archive/* and exclude=archive/*
+"""]]
diff --git a/doc/preferred_content/comment_7_c4acaa237bf1a8512c5e8ea4cdbd11b9._comment b/doc/preferred_content/comment_7_c4acaa237bf1a8512c5e8ea4cdbd11b9._comment
new file mode 100644
index 000000000..3beac6ba8
--- /dev/null
+++ b/doc/preferred_content/comment_7_c4acaa237bf1a8512c5e8ea4cdbd11b9._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.238"
+ subject="comment 7"
+ date="2013-01-10T03:51:38Z"
+ content="""
+Sorry, there's not. The expressions used for \"standard\" are built in.
+"""]]
diff --git a/doc/preferred_content/comment_8_ff2a2dc9c566ebd9f570bdfcd7bfc030._comment b/doc/preferred_content/comment_8_ff2a2dc9c566ebd9f570bdfcd7bfc030._comment
new file mode 100644
index 000000000..3c914ee92
--- /dev/null
+++ b/doc/preferred_content/comment_8_ff2a2dc9c566ebd9f570bdfcd7bfc030._comment
@@ -0,0 +1,27 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmRFKwny4rArBaz-36xTcsJYqKIgdDaw5Q"
+ nickname="Andrew"
+ subject="comment 8"
+ date="2013-01-10T10:24:28Z"
+ content="""
+By way of a feature request: Maybe the way to do this is to have an additional keyword like \"config\" or \"repo\" that allows you to use vicfg and/or git config to set alternative rules and even additional group names.
+
+In git config:
+
+ annex.groups.<groupname> = present and exclude=*/archive/* and exclude=archive/*
+
+in vicfg:
+
+ # (for passport)
+ #trust A0637025-ED47-4F95-A887-346121F1B4A0 = semitrusted
+
+ # (for passport)
+ group A0637025-ED47-4F95-A887-346121F1B4A0 = transfer
+
+ # (for passport)
+ preferred-content A0637025-ED47-4F95-A887-346121F1B4A0 = repo
+
+ # (for transfer)
+ group-content transfer = present and exclude=*/archive/* and exclude=archive/*
+
+"""]]
diff --git a/doc/preferred_content/comment_9_f82538be42428691d7cab60a7add2e74._comment b/doc/preferred_content/comment_9_f82538be42428691d7cab60a7add2e74._comment
new file mode 100644
index 000000000..e1c2d4164
--- /dev/null
+++ b/doc/preferred_content/comment_9_f82538be42428691d7cab60a7add2e74._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkC0W3ZQERUaTkHoks6k68Tsp1tz510nGo"
+ nickname="Georg"
+ subject="drop only files located in archive"
+ date="2013-10-08T17:53:08Z"
+ content="""
+Is there a way to drop only the files that are located in an \"archive\" directory?
+I want to drop all files when calling
+
+ git annex drop --auto
+
+if I move them to the archive. But I want to keep the files that are outside of the archive, even if they are already present in other repos. As far as I have seen and tested, as soon as I have the files in an other repo all files get dropped, also the ones outside the archive directory. Or do I have to increase \"numcopies\" in order to circumvent the \"(not copies=semitrusted+:1)\" case?
+"""]]
diff --git a/doc/privacy.mdwn b/doc/privacy.mdwn
new file mode 100644
index 000000000..5bf16999a
--- /dev/null
+++ b/doc/privacy.mdwn
@@ -0,0 +1,47 @@
+git-annex users entrust it with data that is often intensively private.
+Here's some things to know about how to maintain your privacy while using
+git-annex.
+
+## browsing this web site
+
+This website supports https. [Use it.](https://git-annex.branchable.com/privacy/)
+
+## repository contents
+
+In general, anyone who can clone a git repository gets the ability to see
+all current and past filenames in the repository, and their contents.
+It's best to assume this also holds true for git-annex, as a general rule.
+
+There are some obvious exceptions: If you `git annex dropunused` old
+content from all your repositories, then it's *gone*. If you `git annex
+move` files to a offline drive then only those with physical access can see
+their content. (The names of the files are still visible to anyone with a
+clone of the repository.)
+
+git-annex can encrypt data stored in special remotes. This allows you to
+store files in the cloud without exposing their file names, or their
+contents. See [[design/encryption]] for details.
+
+When using the shared enctyption method, the encryption key gets stored
+in git, and so anyone who has a clone of your repository can decrypt files
+from the encrypted special remote.
+
+When using encryption with a GPG key or keys, only those with access to the
+GPG key can decrypt the content of files stored in an encrypted special
+remote.
+
+## bug reporting
+
+When you file a [[bug]] report on git-annex, you may need to provide
+debugging output or details about your repository. In general, git-annex
+does not sanitize `--debug` output at all, so it may include the names of
+files or other repository details. You should review any debug or other
+output you post, and feel free to remove identifying information.
+
+Note that the git-annex assistant *does* sanitize XMPP protocol information
+logged when debugging is enabled.
+
+If you prefer not to post information publically, you can send a GPG
+encrypted mail to Joey Hess <id@joeyh.name> (gpg key ID 2512E3C7).
+Or you can post a public bug report, and send a followup email with private
+details.
diff --git a/doc/related_software.mdwn b/doc/related_software.mdwn
new file mode 100644
index 000000000..024a155e3
--- /dev/null
+++ b/doc/related_software.mdwn
@@ -0,0 +1,12 @@
+Some folks have built other software on top of git-annex, or that is
+designed to interoperate with it.
+
+* The [[git-annex assistant|assistant]] is included in git-annex,
+ and extends its use cases into new territory.
+* [git-annex-watcher](https://github.com/rubiojr/git-annex-watcher)
+ is a status icon for your desktop.
+* [[forum/gadu_-_git-annex_disk_usage]] is a du like utility that
+ is git-annex aware.
+* [sizes](http://hackage.haskell.org/package/sizes) is another du-like
+ utility, with a `-A` switch that enables git-annex support.
+* Emacs Org mode can auto-commit attached files to git-annex.
diff --git a/doc/repomap.png b/doc/repomap.png
new file mode 100644
index 000000000..dcd777e12
--- /dev/null
+++ b/doc/repomap.png
Binary files differ
diff --git a/doc/scalability.mdwn b/doc/scalability.mdwn
new file mode 100644
index 000000000..9a4ff95ef
--- /dev/null
+++ b/doc/scalability.mdwn
@@ -0,0 +1,44 @@
+git-annex is designed for scalability. The key points are:
+
+* Arbitrarily large files can be managed. The only constraint
+ on file size are how large a file your filesystem can hold.
+
+ While git-annex does checksum files by default, there
+ is a [[WORM_backend|backends]] available that avoids the checksumming
+ overhead, so you can add new, enormous files, very fast. This also
+ allows it to be used on systems with very slow disk IO.
+
+* Memory usage should be constant. This is a "should", because there
+ can sometimes be leaks (and this is one of haskell's weak spots),
+ but git-annex is designed so that it does not need to hold all
+ the details about your repository in memory.
+
+ The one exception is that [[todo/git-annex_unused_eats_memory]],
+ because it *does* need to hold the whole repo state in memory. But
+ that is still considered a bug, and hoped to be solved one day.
+ Luckily, that command is not often used.
+
+* Many files can be managed. The limiting factor is git's own
+ limitations in scaling to repositories with a lot of files, and as git
+ improves this will improve. Scaling to hundreds of thousands of files
+ is not a problem, scaling beyond that and git will start to get slow.
+
+ To some degree, git-annex works around inefficiencies in git; for
+ example it batches input sent to certain git commands that are slow
+ when run in an enormous repository.
+
+* It can use as much, or as little bandwidth as is available. In
+ particular, any interrupted file transfer can be resumed by git-annex.
+
+## scalability tips
+
+* If the files are so big that checksumming becomes a bottleneck, consider
+ using the [[WORM_backend|backends]]. You can always `git annex migrate`
+ files to a checksumming backend later on.
+
+* If you're adding a huge number of files at once (hundreds of thousands),
+ you'll soon notice that git-annex periodically stops and say
+ "Recording state in git" while it runs a `git add` command that
+ becomes increasingly expensive. Consider adjusting the `annex.queuesize`
+ to a higher value, at the expense of it using more memory.
+
diff --git a/doc/shortcuts.mdwn b/doc/shortcuts.mdwn
new file mode 100644
index 000000000..d0f647a64
--- /dev/null
+++ b/doc/shortcuts.mdwn
@@ -0,0 +1,12 @@
+[[!if test="enabled(shortcut)"
+ then="This wiki has shortcuts **enabled**."
+ else="This wiki has shortcuts **disabled**."]]
+
+This page controls what shortcut links the wiki supports.
+
+* [[!shortcut name=debbug url="http://bugs.debian.org/%S" desc="Debian bug #%s"]]
+* [[!shortcut name=iki url="http://ikiwiki.info/%S/"]]
+* [[!shortcut name=rfc url="https://www.ietf.org/rfc/rfc%s.txt" desc="RFC %s"]]
+* [[!shortcut name=cve url="https://cve.mitre.org/cgi-bin/cvename.cgi?name=%s"]]
+* [[!shortcut name=hackage url="http://hackage.haskell.org/package/%s"]]
+* [[!shortcut name=commit url="http://source.git-annex.branchable.com/?p=source.git;a=commitdiff;h=%s"]]
diff --git a/doc/sidebar.mdwn b/doc/sidebar.mdwn
new file mode 100644
index 000000000..d6bf4bfae
--- /dev/null
+++ b/doc/sidebar.mdwn
@@ -0,0 +1,15 @@
+[[!img logo_small.png link=no]]
+
+* [[install]]
+* [[assistant]]
+* [[walkthrough]]
+* [[tips]]
+* [[bugs]]
+* [[todo]]
+* [[forum]]
+* [[comments]]
+* [[contact]]
+
+[crowdfunding campaign underway!](https://campaign.joeyh.name/)
+
+<!-- * <a href="http://flattr.com/thing/84843/git-annex"><img src="https://api.flattr.com/button/flattr-badge-large.png" alt="Flattr this" title="Flattr this" /></a> -->
diff --git a/doc/sitemap.mdwn b/doc/sitemap.mdwn
new file mode 100644
index 000000000..c854ed639
--- /dev/null
+++ b/doc/sitemap.mdwn
@@ -0,0 +1,4 @@
+[[!map pages="page(*) and !*/discussion and !recentchanges
+and !bugs/* and !examples/*/* and !news/* and !tips/* and !videos/*
+and !design/assistant/blog/*
+and !forum/* and !todo/* and !users/* and !ikiwiki/*"]]
diff --git a/doc/special_remotes.mdwn b/doc/special_remotes.mdwn
new file mode 100644
index 000000000..6878a1f88
--- /dev/null
+++ b/doc/special_remotes.mdwn
@@ -0,0 +1,63 @@
+git-annex can transfer data to and from configured git remotes.
+Normally those remotes are normal git repositories (bare and non-bare;
+local and remote), that store the file contents in their own git-annex
+directory.
+
+But, git-annex also extends git's concept of remotes, with these special
+types of remotes. These can be used just like any normal remote by git-annex.
+They cannot be used by other git commands though.
+
+* [[S3]] (Amazon S3, and other compatible services)
+* [[Amazon_Glacier|glacier]]
+* [[bup]]
+* [[gcrypt]] (encrypted git repositories!)
+* [[directory]]
+* [[rsync]]
+* [[webdav]]
+* [[web]]
+* [[xmpp]]
+* [[hook]]
+
+The above special remotes can be used to tie git-annex
+into many cloud services.
+
+There are many use cases for a special remote. You could use it as a backup. You could use it to archive files offline in a drive with encryption enabled so if the drive is stolen your data is not. You could git annex move --to specialremote large files when your local drive is getting full, and then git annex move the files back when free space is again available. You could have one repository copy files to a special remote, and then git annex get them on another repository, to transfer the files between computers that do not communicate directly.
+
+The git-annex assistant makes it easy to set up rsync remotes using this last scenario, which is referred to as a transfer repository, and arranges to drop files from the transfer repository once they have been transferred to all known clients.
+
+None of these use cases are particular to particular special remote types. Most special remotes can all be used in these and other ways. It largely doesn't matter for your use what underlying transport the special remote uses.
+
+Here are specific instructions
+for using git-annex with various services:
+
+* [[Amazon_S3|tips/using_Amazon_S3]]
+* [[Amazon_Glacier|tips/using_Amazon_Glacier]]
+* [[tips/Internet_Archive_via_S3]]
+* [[tahoe-lafs|forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs]]
+* [[Box.com|tips/using_box.com_as_a_special_remote]]
+* [[Google drive|tips/googledriveannex]]
+* [[Google Cloud Storage|tips/using_Google_Cloud_Storage]]
+* [[Mega.co.nz|tips/megaannex]]
+* [[SkyDrive|tips/skydriveannex]]
+* [[OwnCloud|tips/owncloudannex]]
+* [[Flickr|tips/flickrannex]]
+* [[IMAP|forum/special_remote_for_IMAP]]
+* [[Usenet|forum/nntp__47__usenet special remote]]
+* [chef-vault](https://github.com/3ofcoins/knife-annex/)
+
+## Unused content on special remotes
+
+Over time, special remotes can accumulate file content that is no longer
+referred to by files in git. Normally, unused content in the current
+repository is found by running `git annex unused`. To detect unused content
+on special remotes, instead use `git annex unused --from`. Example:
+
+ $ git annex unused --from mys3
+ unused mys3 (checking for unused data...)
+ Some annexed data on mys3 is not used by any files in this repository.
+ NUMBER KEY
+ 1 WORM-s3-m1301674316--foo
+ (To see where data was previously used, try: git log --stat -S'KEY')
+ (To remove unwanted data: git-annex dropunused --from mys3 NUMBER)
+ $ git annex dropunused --from mys3 1
+ dropunused 12948 (from mys3...) ok
diff --git a/doc/special_remotes/S3.mdwn b/doc/special_remotes/S3.mdwn
new file mode 100644
index 000000000..5291a4eb6
--- /dev/null
+++ b/doc/special_remotes/S3.mdwn
@@ -0,0 +1,53 @@
+This special remote type stores file contents in a bucket in Amazon S3
+or a similar service.
+
+See [[tips/using_Amazon_S3]] and
+[[tips/Internet_Archive_via_S3]] for usage examples.
+
+## configuration
+
+The standard environment variables `AWS_ACCESS_KEY_ID` and
+`AWS_SECRET_ACCESS_KEY` are used to supply login credentials
+for Amazon. You need to set these only when running
+`git annex initremote`, as they will be cached in a file only you
+can read inside the local git repository.
+
+A number of parameters can be passed to `git annex initremote` to configure
+the S3 remote.
+
+* `encryption` - One of "none", "hybrid", "shared", or "pubkey".
+ See [[encryption]].
+
+* `keyid` - Specifies the gpg key to use for [[encryption]].
+
+* `embedcreds` - Optional. Set to "yes" embed the login credentials inside
+ the git repository, which allows other clones to also access them. This is
+ the default when gpg encryption is enabled; the credentials are stored
+ encrypted and only those with the repository's keys can access them.
+
+ It is not the default when using shared encryption, or no encryption.
+ Think carefully about who can access your repository before using
+ embedcreds without gpg encryption.
+
+* `datacenter` - Defaults to "US". Other values include "EU",
+ "us-west-1", and "ap-southeast-1".
+
+* `storageclass` - Default is "STANDARD". If you have configured git-annex
+ to preserve multiple [[copies]], consider setting this to "REDUCED_REDUNDANCY"
+ to save money.
+
+* `host` and `port` - Specify in order to use a different, S3 compatable
+ service.
+
+* `bucket` - S3 requires that buckets have a globally unique name,
+ so by default, a bucket name is chosen based on the remote name
+ and UUID. This can be specified to pick a bucket name.
+
+* `fileprefix` - By default, git-annex places files in a tree rooted at the
+ top of the S3 bucket. When this is set, it's prefixed to the filenames
+ used. For example, you could set it to "foo/" in one special remote,
+ and to "bar/" in another special remote, and both special remotes could
+ then use the same bucket.
+
+* `x-amz-*` are passed through as http headers when storing keys
+ in S3.
diff --git a/doc/special_remotes/S3/comment_10_c366f020c9b97a365e21878a33360079._comment b/doc/special_remotes/S3/comment_10_c366f020c9b97a365e21878a33360079._comment
new file mode 100644
index 000000000..bc06156cf
--- /dev/null
+++ b/doc/special_remotes/S3/comment_10_c366f020c9b97a365e21878a33360079._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 10"
+ date="2013-05-23T20:04:03Z"
+ content="""
+You can enable a special remote on a clone by running `git annex enableremote $name`, where $name is the name you used to originally create the special remote. (Older versions of git-annex used `git annex initremote` to enable the special remote on the clone.)
+
+(Just in case, I have verified that embedcreds does cause the cipher= to be stored in the remote.log. It does.)
+"""]]
diff --git a/doc/special_remotes/S3/comment_11_c1da387e082d91feec13dde91ccb111a._comment b/doc/special_remotes/S3/comment_11_c1da387e082d91feec13dde91ccb111a._comment
new file mode 100644
index 000000000..5cd9b7311
--- /dev/null
+++ b/doc/special_remotes/S3/comment_11_c1da387e082d91feec13dde91ccb111a._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="basak"
+ ip="2001:8b0:1c8::2"
+ subject="comment 11"
+ date="2013-05-24T09:38:40Z"
+ content="""
+Thanks Joey - initremote on my slightly older version appears to work. I'll use `enableremote` when I can.
+
+> (Just in case, I have verified that embedcreds does cause the cipher= to be stored in the remote.log. It does.)
+
+This doesn't do what I expect. The documentation suggests that my S3 _login_ credentials would be stored. I understand that the cipher would be stored; but isn't this a separate concept? Instead, I'm being asked to set `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`; my understanding was that git-annex will keep them in the repository for me, so that I don't have to set them after running `initremote` before cloning. This works, apart from surviving the cloning. I'm using `encryption=shared`; does this affect anything? Or am I using a version of git-annex (3.20121112ubuntu3) that's too old?
+"""]]
diff --git a/doc/special_remotes/S3/comment_12_59c3ecab7dbc8be53258460473cac21c._comment b/doc/special_remotes/S3/comment_12_59c3ecab7dbc8be53258460473cac21c._comment
new file mode 100644
index 000000000..47b0aaefa
--- /dev/null
+++ b/doc/special_remotes/S3/comment_12_59c3ecab7dbc8be53258460473cac21c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 12"
+ date="2013-05-24T15:33:12Z"
+ content="""
+Ah -- No, your AWS creds are not stored. While some other special remotes, like webdav, can store all necessary credentials, it's not done for AWS. I didn't want git-annex to be responsible for someone accidentially publishing their AWS creds to their friends, since that could cost them a lot of money.
+"""]]
diff --git a/doc/special_remotes/S3/comment_13_0789a21d980825188bb09f7fc8bba8be._comment b/doc/special_remotes/S3/comment_13_0789a21d980825188bb09f7fc8bba8be._comment
new file mode 100644
index 000000000..c8e84021b
--- /dev/null
+++ b/doc/special_remotes/S3/comment_13_0789a21d980825188bb09f7fc8bba8be._comment
@@ -0,0 +1,33 @@
+[[!comment format=mdwn
+ username="basak"
+ ip="2001:8b0:1c8::2"
+ subject="comment 13"
+ date="2013-05-24T15:47:14Z"
+ content="""
+That's not what the documentation here says! It even warns me: \"Think carefully about who can access your repository before using embedcreds without gpg encryption.\"
+
+My use case:
+
+Occasional use of EC2, and a desire to store some persistent stuff in S3, since the dataset is large and I have limited bandwidth. I want to destroy the EC2 instance when I'm not using it, leaving the data in S3 for later.
+
+If I use git-annex to manage the S3 store, then I get the ability to clone the repository and destroy the instance. Later, I can start a new instance, push the repo back up, and would like to be able to then pull the data back out of S3 again.
+
+I'd really like the login credentials to persist in the repository (as the documentation here says it should). Even if I have to add a --yes-i-know-my-s3-credentials-will-end-up-available-to-anyone-who-can-see-my-git-repo flag. This is because I use some of my git repos to store private data, too.
+
+If I use an Amazon IAM policy as follows, I can generate a set of credentials that are limited to access to a particular prefix of a specific S3 bucket only - effectively creating a sandboxed area just for git-annex:
+
+ {
+ \"Statement\": [{\"Sid\": \"Stmt1368780615583\",
+ \"Action\": [\"s3:GetObject\", \"s3:PutObject\", \"s3:DeleteObject\"],
+ \"Effect\": \"Allow\",
+ \"Resource\": [\"arn:aws:s3:::bucketname/prefix/*\"]}
+ ],
+ \"Statement\": [{\"Sid\": \"Stmt1368781573129\",
+ \"Action\": [\"s3:GetBucketLocation\"],
+ \"Effect\": \"Allow\",
+ \"Resource\": [\"arn:aws:s3:::bucketname\"]}
+ ]
+ }
+
+Doing this means that I have a different set of credentials for every annex, so it would be really useful to be able have these stored and managed within the repository itself. Each set is limited to what the annex stores, so there is no bigger compromise I have to worry about apart from the compromise of the data that the annex itself manages.
+"""]]
diff --git a/doc/special_remotes/S3/comment_14_29574a51d5831c51e2e765eb2c06e567._comment b/doc/special_remotes/S3/comment_14_29574a51d5831c51e2e765eb2c06e567._comment
new file mode 100644
index 000000000..2285e9062
--- /dev/null
+++ b/doc/special_remotes/S3/comment_14_29574a51d5831c51e2e765eb2c06e567._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 14"
+ date="2013-05-24T16:45:25Z"
+ content="""
+I apologise for incorrect information. I was thinking about defaults when using the webapp.
+
+I have verified that embedcreds=yes stores the AWS creds, always.
+
+
+"""]]
diff --git a/doc/special_remotes/S3/comment_15_ceb9048c743135f6beca57a23505f0a3._comment b/doc/special_remotes/S3/comment_15_ceb9048c743135f6beca57a23505f0a3._comment
new file mode 100644
index 000000000..a8b5573e7
--- /dev/null
+++ b/doc/special_remotes/S3/comment_15_ceb9048c743135f6beca57a23505f0a3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawne_amN4fko4p5cRY_9EYwaYuJKNn7LRio"
+ nickname="Tobias"
+ subject="different s3 storage URLs"
+ date="2013-08-23T08:59:32Z"
+ content="""
+Is it possible to change the S3 endpoint hosts? I'm running a radosgw with S3 support which I'd like to define as S3 remote for git-annex
+"""]]
diff --git a/doc/special_remotes/S3/comment_16_7b79f8b5ef88a2775d61b5ac5774d3e0._comment b/doc/special_remotes/S3/comment_16_7b79f8b5ef88a2775d61b5ac5774d3e0._comment
new file mode 100644
index 000000000..508cedca4
--- /dev/null
+++ b/doc/special_remotes/S3/comment_16_7b79f8b5ef88a2775d61b5ac5774d3e0._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 16"
+ date="2013-08-23T17:39:56Z"
+ content="""
+Yes, you can specify the host to use when setting up the remote. It's actually documented earlier on this very page, if ou search for \"host\". Any S3 compatabile host will probably work -- the Internet Archive's S3 does, for example.
+"""]]
diff --git a/doc/special_remotes/S3/comment_1_4a1f7a230dad6caa84831685b236fd73._comment b/doc/special_remotes/S3/comment_1_4a1f7a230dad6caa84831685b236fd73._comment
new file mode 100644
index 000000000..17e35e7d9
--- /dev/null
+++ b/doc/special_remotes/S3/comment_1_4a1f7a230dad6caa84831685b236fd73._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnoUOqs_lbuWyZBqyU6unHgUduJwDDgiKY"
+ nickname="Matt"
+ subject="environment variables"
+ date="2012-05-29T12:40:25Z"
+ content="""
+Just noting that the environment variables `ANNEX_S3_ACCESS_KEY_ID` and `ANNEX_S3_SECRET_ACCESS_KEY` seem to have been changed to `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`
+"""]]
diff --git a/doc/special_remotes/S3/comment_2_5b22d67de946f4d34a4a3c7449d32988._comment b/doc/special_remotes/S3/comment_2_5b22d67de946f4d34a4a3c7449d32988._comment
new file mode 100644
index 000000000..f535559ae
--- /dev/null
+++ b/doc/special_remotes/S3/comment_2_5b22d67de946f4d34a4a3c7449d32988._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.81.112"
+ subject="comment 2"
+ date="2012-05-29T19:10:46Z"
+ content="""
+Thanks, I've fixed that. (You could have too.. this is a wiki ;)
+"""]]
diff --git a/doc/special_remotes/S3/comment_3_bcab2bd0f168954243aa9bcc9671bd94._comment b/doc/special_remotes/S3/comment_3_bcab2bd0f168954243aa9bcc9671bd94._comment
new file mode 100644
index 000000000..abb6aacc9
--- /dev/null
+++ b/doc/special_remotes/S3/comment_3_bcab2bd0f168954243aa9bcc9671bd94._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnoUOqs_lbuWyZBqyU6unHgUduJwDDgiKY"
+ nickname="Matt"
+ subject="comment 3"
+ date="2012-05-30T00:26:33Z"
+ content="""
+Thanks! Being new here, I didn't want to overstep my boundaries. I've gone ahead and made a small edit and will do so elsewhere as needed.
+"""]]
diff --git a/doc/special_remotes/S3/comment_4_38c0b062997fde1ad28facc05d973e83._comment b/doc/special_remotes/S3/comment_4_38c0b062997fde1ad28facc05d973e83._comment
new file mode 100644
index 000000000..8c17f7d64
--- /dev/null
+++ b/doc/special_remotes/S3/comment_4_38c0b062997fde1ad28facc05d973e83._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmX5gPNK35Dub-HzR0Yb3KXllbqc0rYRYs"
+ nickname="Eduardo"
+ subject="bucket/folder s3 remotes"
+ date="2012-08-09T10:52:07Z"
+ content="""
+it'd be really nice being able to configure a S3 remote of the form `<bucket>/<folder>` (not really a folder, of course, just the usual prefix trick used to simulate folders at S3). The remote = bucket architecture is not scalable at all, in terms of number of repositories.
+
+how hard would it be to support this?
+
+thanks, this is the only thing that's holding us back from using git-annex, nice tool!
+"""]]
diff --git a/doc/special_remotes/S3/comment_5_409bc2b56382417cf26bb222fb783ba7._comment b/doc/special_remotes/S3/comment_5_409bc2b56382417cf26bb222fb783ba7._comment
new file mode 100644
index 000000000..325db6799
--- /dev/null
+++ b/doc/special_remotes/S3/comment_5_409bc2b56382417cf26bb222fb783ba7._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ subject="comment 5"
+ date="2012-08-09T18:01:06Z"
+ content="""
+I guess this could be useful if you have a *lot* of buckets already in use at S3, or if you want to be able to have a lot of distinct S3 special remotes. Implemented the `fileprefix` setting. Note that I have not tested it, beyond checking it builds, since I let my S3 account expire. Your testing would be appreciated.
+
+"""]]
diff --git a/doc/special_remotes/S3/comment_6_78da9e233882ec0908962882ea8c4056._comment b/doc/special_remotes/S3/comment_6_78da9e233882ec0908962882ea8c4056._comment
new file mode 100644
index 000000000..742dbedc2
--- /dev/null
+++ b/doc/special_remotes/S3/comment_6_78da9e233882ec0908962882ea8c4056._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnY9ObrNrQuRp8Xs0XvdtJJssm5cp4NMZA"
+ nickname="alan"
+ subject="Rackspace Cloud Files support?"
+ date="2012-08-23T21:00:11Z"
+ content="""
+Any chance I could bribe you to setup Rackspace Cloud Files support? We are using them and would hate to have a S3 bucket only for this.
+
+https://github.com/rackspace/python-cloudfiles
+"""]]
diff --git a/doc/special_remotes/S3/comment_7_6af9781004d982d8e6b20a83ad29eead._comment b/doc/special_remotes/S3/comment_7_6af9781004d982d8e6b20a83ad29eead._comment
new file mode 100644
index 000000000..c243cde13
--- /dev/null
+++ b/doc/special_remotes/S3/comment_7_6af9781004d982d8e6b20a83ad29eead._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmyFvkaewo432ELwtCoecUGou4v3jCP0Pc"
+ nickname="Eric"
+ subject="S3 Remote Future Proof?"
+ date="2013-01-20T09:21:50Z"
+ content="""
+Joey, I'm curious to understand how future proof an S3 remote is. Can I restore my files without git-annex?
+"""]]
diff --git a/doc/special_remotes/S3/comment_8_0fa68d584ee7f6b5c9058fba7e911a11._comment b/doc/special_remotes/S3/comment_8_0fa68d584ee7f6b5c9058fba7e911a11._comment
new file mode 100644
index 000000000..6997719d1
--- /dev/null
+++ b/doc/special_remotes/S3/comment_8_0fa68d584ee7f6b5c9058fba7e911a11._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="68.119.100.5"
+ subject="comment 8"
+ date="2013-01-20T20:37:09Z"
+ content="""
+If encryption is not used, the files are stored in S3 as-is, and can be accessed directly. They are stored in a hashed directory structure with the names of their key used, rather than the original filename. To get back to the original filename, a copy of the git repo would also be needed.
+
+With encryption, you need the gpg key used in the encryption, or, for shared encryption, a symmetric key which is stored in the git repo.
+
+See [[future proofing]] for non-S3 specific discussion of this topic.
+"""]]
diff --git a/doc/special_remotes/S3/comment_9_7ad757b3865b04967c79af0a263bb3b0._comment b/doc/special_remotes/S3/comment_9_7ad757b3865b04967c79af0a263bb3b0._comment
new file mode 100644
index 000000000..51b7ab16a
--- /dev/null
+++ b/doc/special_remotes/S3/comment_9_7ad757b3865b04967c79af0a263bb3b0._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="basak"
+ ip="2001:8b0:1c8::2"
+ subject="Recovering from a clone"
+ date="2013-05-22T18:32:05Z"
+ content="""
+How do I recover a special remote from a clone, please? I see that `remote.log` has most of the details, but my remote is not configured on my clone and I see no obvious way to do it. And I used `embedcreds`, but the only credentials I can see are stored in .git/annex/creds/ so did not survive a clone. I'm confused because the documentation here for `embedcreds` says that clones should have access.
+
+As a workaround, it looks like copying the remote over from `.git/config` as well as the credentials from `.git/annex/creds/` seems to work. Is there some other way I'm supposed to do this, or is this the intended way?
+"""]]
diff --git a/doc/special_remotes/bup.mdwn b/doc/special_remotes/bup.mdwn
new file mode 100644
index 000000000..f2d465e77
--- /dev/null
+++ b/doc/special_remotes/bup.mdwn
@@ -0,0 +1,39 @@
+This special remote type stores file contents in a
+[bup](http://github.com/bup/bup) repository. By using git-annex
+in the front-end, and bup as a remote, you get an easy git-style
+interface to large files, and easy backups of the file contents using git.
+
+This is particularly well suited to collaboration on projects involving
+large files, since both the git-annex and bup repositories can be
+accessed like any other git repository.
+
+See [[walkthrough/using_bup]] for usage examples.
+
+Each individual key is stored in a bup remote using `bup split`, with
+a git branch named the same as the key name. Content is retrieved from
+bup using `bup join`. All other bup operations are up to you -- consider
+running `bup fsck --generate` in a cron job to generate recovery blocks,
+for example; or clone bup's git repository to further back it up.
+
+## configuration
+
+These parameters can be passed to `git annex initremote` to configure bup:
+
+* `encryption` - One of "none", "hybrid", "shared", or "pubkey".
+ See [[encryption]].
+
+* `keyid` - Specifies the gpg key to use for [[encryption]].
+
+* `buprepo` - Required. This is passed to `bup` as the `--remote`
+ to use to store data. To create the repository,`bup init` will be run.
+ Example: "buprepo=example.com:/big/mybup" or "buprepo=/big/mybup"
+ (To use the default `~/.bup` repository on the local host, specify "buprepo=")
+
+Options to pass to `bup split` when sending content to bup can also
+be specified, by using `git config annex.bup-split-options`. This
+can be used to, for example, limit its bandwidth.
+
+## notes
+
+[[git-annex-shell]] does not support bup, due to the wacky way that bup
+starts its server. So, to use bup, you need full shell access to the server.
diff --git a/doc/special_remotes/bup/comment_10_f78c1ed97d2e4c6ebffaa7482cfe0c9b._comment b/doc/special_remotes/bup/comment_10_f78c1ed97d2e4c6ebffaa7482cfe0c9b._comment
new file mode 100644
index 000000000..97f9b9ea9
--- /dev/null
+++ b/doc/special_remotes/bup/comment_10_f78c1ed97d2e4c6ebffaa7482cfe0c9b._comment
@@ -0,0 +1,23 @@
+[[!comment format=mdwn
+ username="http://sekenre.wordpress.com/"
+ nickname="sekenre"
+ subject="Synchronizing Bup repositories"
+ date="2013-05-07T16:46:34Z"
+ content="""
+Hi All,
+
+I managed to answer my questions above about copying changes between local bup repositories efficiently.
+
+You run the following commands
+
+ git annex copy . --to bup_repo_1 # Uses bup split in the background (slow)
+ rsync -av /mnt/repodisk1/repo/ /mnt/repodisk2/repo/ \
+ --exclude=config --exclude=*.bloom --exclude=*.midx # rsync without bup-specific indices (speed depends on delta between repositories)
+ BUP_DIR=/mnt/repodisk2/repo/ bup midx -a && bup bloom # rebuild bup-specific indices on the target (this is extremely fast)
+ git annex copy . --to bup_repo_2 # Records file is now available in repo2 (also extremely fast)
+
+Now `git annex whereis` will show the correct location and `git annex get <file> --from bup_repo_2` will work.
+
+So far in my testing I haven't found any problems...
+
+"""]]
diff --git a/doc/special_remotes/bup/comment_11_b53bceb0058acf4d1ab12ea4853ee443._comment b/doc/special_remotes/bup/comment_11_b53bceb0058acf4d1ab12ea4853ee443._comment
new file mode 100644
index 000000000..c699c6241
--- /dev/null
+++ b/doc/special_remotes/bup/comment_11_b53bceb0058acf4d1ab12ea4853ee443._comment
@@ -0,0 +1,24 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnAvbXOnK57sqgvZvxkbG74NUKBDwKDcuk"
+ nickname="Tim"
+ subject="bup location data not synced through annex assistant"
+ date="2013-05-15T15:08:54Z"
+ content="""
+I set up 2 servers running git annex assistant, both with a ~/annex dir and an additional ~/annex-bup bup repo. There is no additional cloud repository.
+For test, I added my /etc dir which uploaded correctly from server1, but which never arrived on server2
+
+ bup@bup1:~/annex/etc$ git annex whereis updatedb.conf
+ whereis updatedb.conf (3 copies)
+ 687d3a7f-4798-4dbe-8774-1785b8ab6b7d -- here (bup@bup1:~/annex)
+ adfc1307-771f-40e9-b794-bae2e1f21b8b -- bup2-annex-bup
+ e4e0ac0b-992a-4312-a4ac-fc8d3d9f7c0f -- bup1-annex-bup
+ ok
+
+ bup@bup2:~/annex/etc$ git annex whereis updatedb.conf
+ whereis updatedb.conf (1 copy)
+ 687d3a7f-4798-4dbe-8774-1785b8ab6b7d -- bup1 (bup@bup1:~/annex)
+ ok
+
+As you can see, server 2 just doesn't know the data is already on it's own disk in it's local bup repo.
+Is there a reason this data does not get synced? Should I set up a transfer repo?
+"""]]
diff --git a/doc/special_remotes/bup/comment_12_65d923226cf6120349d807c5c60f640c._comment b/doc/special_remotes/bup/comment_12_65d923226cf6120349d807c5c60f640c._comment
new file mode 100644
index 000000000..a790daea3
--- /dev/null
+++ b/doc/special_remotes/bup/comment_12_65d923226cf6120349d807c5c60f640c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnAvbXOnK57sqgvZvxkbG74NUKBDwKDcuk"
+ nickname="Tim"
+ subject="my bad"
+ date="2013-05-15T15:39:31Z"
+ content="""
+Sorry, looks like I did initremote twice on the same folder, instead of enableremote the second time...
+"""]]
diff --git a/doc/special_remotes/bup/comment_1_96179a003da4444f6fc08867872cda0a._comment b/doc/special_remotes/bup/comment_1_96179a003da4444f6fc08867872cda0a._comment
new file mode 100644
index 000000000..02691c690
--- /dev/null
+++ b/doc/special_remotes/bup/comment_1_96179a003da4444f6fc08867872cda0a._comment
@@ -0,0 +1,43 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkgbXwQtPQSG8igdS7U8l031N8sqDmuyvk"
+ nickname="Albert"
+ subject="Error with bup and gnupg"
+ date="2012-10-22T20:56:56Z"
+ content="""
+Hello,
+
+I get this error when trying to use git-annex with bup and gnupg:
+
+<pre>
+move importable_pilot_surveys.tar (gpg) (checking localaseebup...) (to localaseebup...)
+Traceback (most recent call last):
+ File \"/usr/lib/bup/cmd/bup-split\", line 133, in <module>
+ progress=prog)
+ File \"/usr/lib/bup/bup/hashsplit.py\", line 167, in split_to_shalist
+ for (sha,size,bits) in sl:
+ File \"/usr/lib/bup/bup/hashsplit.py\", line 118, in _split_to_blobs
+ for (blob, bits) in hashsplit_iter(files, keep_boundaries, progress):
+ File \"/usr/lib/bup/bup/hashsplit.py\", line 86, in _hashsplit_iter
+ bnew = next(fi)
+ File \"/usr/lib/bup/bup/helpers.py\", line 86, in next
+ return it.next()
+ File \"/usr/lib/bup/bup/hashsplit.py\", line 49, in blobiter
+ for filenum,f in enumerate(files):
+ File \"/usr/lib/bup/cmd/bup-split\", line 128, in <genexpr>
+ files = extra and (open(fn) for fn in extra) or [sys.stdin]
+IOError: [Errno 2] No such file or directory: '-'
+</pre>
+
+
+I was able to work-around this issue by altering /usr/lib/bup/cmd/bup-split (though I don't think its a bup bug) to just pull from stdin:
+
+files = [sys.stdin]
+
+on ~ line 128.
+
+Any ideas? Also, do you think that bup's data-deduplication does anything when gnupg is enabled, i.e. is it just as well to use a directory remote with gnupg?
+
+Thanks! Git annex rules!
+
+Albert
+"""]]
diff --git a/doc/special_remotes/bup/comment_2_612b038c15206f9f3c2e23c7104ca627._comment b/doc/special_remotes/bup/comment_2_612b038c15206f9f3c2e23c7104ca627._comment
new file mode 100644
index 000000000..97af184f3
--- /dev/null
+++ b/doc/special_remotes/bup/comment_2_612b038c15206f9f3c2e23c7104ca627._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.23"
+ subject="comment 2"
+ date="2012-10-23T20:01:43Z"
+ content="""
+@Albert, thanks for reporting this bug (but put them in [[bugs]] in future please).
+
+This is specific to using the bup special remote with encryption. Without encryption it works. And no, it won't manage to deduplicate anything that's encrypted, as far as I know.
+
+I think bup-split must have used - for stdin in the past, but now, it just reads from stdin when no file is specified, so I've updated git-annex.
+"""]]
diff --git a/doc/special_remotes/bup/comment_3_1186def82741ddab1ade256fb2e59e6f._comment b/doc/special_remotes/bup/comment_3_1186def82741ddab1ade256fb2e59e6f._comment
new file mode 100644
index 000000000..2e3e38992
--- /dev/null
+++ b/doc/special_remotes/bup/comment_3_1186def82741ddab1ade256fb2e59e6f._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="http://sekenre.wordpress.com/"
+ nickname="sekenre"
+ subject="Bup remotes in git-annex assistant"
+ date="2013-03-13T12:54:56Z"
+ content="""
+Hi,
+
+Is the bup remote available via the Assistant user interface?
+
+Unrelated question;
+
+If you are syncing files between two bup repos on local usb drives, does it use git to sync the changes or does it use \"bup split\" to re-add the file? (Basically, is the syncing as efficient as possible using git-annex or would I have to go to a lower level)
+
+Many Thanks,
+Sek
+"""]]
diff --git a/doc/special_remotes/bup/comment_4_7d22a805dd2914971e7ca628ceea69be._comment b/doc/special_remotes/bup/comment_4_7d22a805dd2914971e7ca628ceea69be._comment
new file mode 100644
index 000000000..0607e5f6c
--- /dev/null
+++ b/doc/special_remotes/bup/comment_4_7d22a805dd2914971e7ca628ceea69be._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 4"
+ date="2013-03-13T16:05:50Z"
+ content="""
+I don't plan to support creating bup spefial remotes in the assistant, currently. Of course the assistant can use bup special remotes you set up.
+
+Your two bup repos would be synced using bup-split.
+"""]]
diff --git a/doc/special_remotes/bup/comment_6_5942333cde09fd98e26c4f1d389cb76f._comment b/doc/special_remotes/bup/comment_6_5942333cde09fd98e26c4f1d389cb76f._comment
new file mode 100644
index 000000000..288f8765d
--- /dev/null
+++ b/doc/special_remotes/bup/comment_6_5942333cde09fd98e26c4f1d389cb76f._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnZWCbRYPVnwscdkdEDwgQHZJLwW6H_AHo"
+ nickname="Tobias"
+ subject="bup fail?"
+ date="2013-03-31T21:05:32Z"
+ content="""
+I've run into problems storing a huge number of files in the bup repo. It seems that thousands of branches are a problem. I don't know if it's a problem of git-annex, bup, or the filesystem.
+
+How about adding an option to store tree/commit ids in git-annex instead of using branches in bup?
+"""]]
diff --git a/doc/special_remotes/bup/comment_7_cb1a0d3076e9d06e7a24204478f6fa98._comment b/doc/special_remotes/bup/comment_7_cb1a0d3076e9d06e7a24204478f6fa98._comment
new file mode 100644
index 000000000..a2284c3e1
--- /dev/null
+++ b/doc/special_remotes/bup/comment_7_cb1a0d3076e9d06e7a24204478f6fa98._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 7"
+ date="2013-04-02T21:24:06Z"
+ content="""
+`bup-split` uses a git branch to name the objects stored in the bup repository. So it will be limited by any scalability issues affecting large numbers of git branches. I don't know what those are.
+
+Yes, it would be possible to make git-annex store this in the git-annex branch instead.
+"""]]
diff --git a/doc/special_remotes/bup/comment_8_4cbc67e5911748d13cee3c483d7ece8a._comment b/doc/special_remotes/bup/comment_8_4cbc67e5911748d13cee3c483d7ece8a._comment
new file mode 100644
index 000000000..62376a6e4
--- /dev/null
+++ b/doc/special_remotes/bup/comment_8_4cbc67e5911748d13cee3c483d7ece8a._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlsXhOlsW6RaGR83VNSMxPh159l5dFau70"
+ nickname="Yung-Chin"
+ subject="re scaling issue"
+ date="2013-05-03T14:57:51Z"
+ content="""
+Tobias/joey,
+
+I think there are at least two scaling issues that may be causing you trouble. One is that bup writes pack+idx files rather than bare objects, and if you send 1 file per call to bup-split, you end up with a pair of pack and idx files for each such call. When you later try to retrieve a blob, bup currently just calls git, and git will have to traverse all these tiny idx files looking for the right hash (bare objects you could at least find by name). You can probably ameliorate the pain by calling git repack (look at the -a and --max-pack-size switches) on your bup repository. The other is the \"thousands of branches\" issue, and I think \"git pack-refs --all\" (that's again on your bup repository) might help a little bit.
+
+It would certainly help performance if you could store blob/tree ids in git-annex instead of branch names. For small files, all bup would need to store is a blob, but currently you end up storing a blob, a tree, and a commit (and looking-up all of those, plus the ref too, on calling bup-join). (you might want to patch bup-split, so it would allow you to ask it for \"--blob-or-tree\", because currently if you say you pass it -b for blob-ids, then for bigger files you get a series of IDs, whereas you'd be much better off with a tree-id there)
+"""]]
diff --git a/doc/special_remotes/bup/comment_9_ca7096a759961af375e6bd49663b45b3._comment b/doc/special_remotes/bup/comment_9_ca7096a759961af375e6bd49663b45b3._comment
new file mode 100644
index 000000000..d6021f764
--- /dev/null
+++ b/doc/special_remotes/bup/comment_9_ca7096a759961af375e6bd49663b45b3._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlsXhOlsW6RaGR83VNSMxPh159l5dFau70"
+ nickname="Yung-Chin"
+ subject="comment 9"
+ date="2013-05-03T16:34:05Z"
+ content="""
+Thinking about this some more, a very elegant way to make a bup remote could actually be to just pass the whole .git/annex tree into bup-index/save (you could avoid sending some files by only bup-indexing select subtrees, or by using --exclude-*'s, but you'd run bup-save over the whole .git/annex tree). You could then use bup-restore to retrieve files or whole subtrees, and you'd refer to the files you're retrieving by their actual pathname under which they live in .git/annex (if that doesn't make sense it's because I've misunderstood how git-annex is organised!), so something like \"bup restore branch_name/latest/.git/annex/aa/bb/sha-of-some-sort\" would work - that's cute, right? And you'd only have 1 branch.
+
+However... somebody who is good with lazy-evaluation would need to rework bup.vfs: currently, if you'd call bup-restore on a path like that, it would instantiate a _lot_ of vfs-nodes you don't need - to begin with, it would make a node for every commit you ever made (on any branch!) - on a big repository you'd wait ages for it to just find the commit objects...
+"""]]
diff --git a/doc/special_remotes/comment_10_e9881290486a1770bd260f8650ada9c6._comment b/doc/special_remotes/comment_10_e9881290486a1770bd260f8650ada9c6._comment
new file mode 100644
index 000000000..79cbe3713
--- /dev/null
+++ b/doc/special_remotes/comment_10_e9881290486a1770bd260f8650ada9c6._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkQqKSVY98PVGDIaYZdK9CodJdbh7cFfhY"
+ nickname="Ashwin"
+ subject="Rackspace Cloud Files support"
+ date="2013-03-22T08:20:40Z"
+ content="""
+It'd be really cool to have Rackspace cloud files support. Like the guy above me said, I would submit a patch but not if I have to learn Haskell first :)
+"""]]
diff --git a/doc/special_remotes/comment_11_e01b5cc5a0d81b071e93e27e7b91fe2a._comment b/doc/special_remotes/comment_11_e01b5cc5a0d81b071e93e27e7b91fe2a._comment
new file mode 100644
index 000000000..f2f9c4a8f
--- /dev/null
+++ b/doc/special_remotes/comment_11_e01b5cc5a0d81b071e93e27e7b91fe2a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="andy"
+ ip="99.48.75.171"
+ subject="Re: Webhook special remote"
+ date="2013-04-12T08:54:47Z"
+ content="""
+@Alex: You might see if the newly-added [[todo/wishlist: allow configuration of downloader for addurl]] could be made to do what you need... I've not played around with it yet, but perhaps you could set the downloader to be something that can sort out the various URLs and send them to the correct downloading tool?
+"""]]
diff --git a/doc/special_remotes/comment_12_13237170ef5b6646e0e25d3421af3fe5._comment b/doc/special_remotes/comment_12_13237170ef5b6646e0e25d3421af3fe5._comment
new file mode 100644
index 000000000..5146cca36
--- /dev/null
+++ b/doc/special_remotes/comment_12_13237170ef5b6646e0e25d3421af3fe5._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://yarikoptic.myopenid.com/"
+ nickname="site-myopenid"
+ subject="How to establish local preference for (special) remotes"
+ date="2013-05-22T14:06:48Z"
+ content="""
+Sorry if it is RTFM... If I have multiple original (reachable) remotes, how could I establish my preference for which one to be used in any given location?
+
+usecase: if I clone a repository within amazon cloud instance -- I would now prefer if this (or all -- user-wide configuration somehow?) repository 'get's load from URLs originating in the cloud of this zone (e.g. having us-east-1.s3.amazonaws.com/ in their URLs).
+"""]]
diff --git a/doc/special_remotes/comment_13_1a36a0483a9db04d36e0234a192ebad8._comment b/doc/special_remotes/comment_13_1a36a0483a9db04d36e0234a192ebad8._comment
new file mode 100644
index 000000000..8e5a8015d
--- /dev/null
+++ b/doc/special_remotes/comment_13_1a36a0483a9db04d36e0234a192ebad8._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmkBwMWvNKZZCge_YqobCSILPMeK6xbFw8"
+ nickname="develop"
+ subject="Remote costs"
+ date="2013-05-22T14:15:03Z"
+ content="""
+This should be implemented with costs
+
+I refer you too: http://git-annex.branchable.com/design/assistant/blog/day_213__costs/
+
+This has been implemented in the assistant, so if you use that, changing priority should be as simple as changing the order of the remotes on the web interface. Whichever remote is highest on the list, is the one your client will fetch from.
+"""]]
diff --git a/doc/special_remotes/comment_14_a8419963dc024b1d9eb73807596012dc._comment b/doc/special_remotes/comment_14_a8419963dc024b1d9eb73807596012dc._comment
new file mode 100644
index 000000000..cd0a8eb58
--- /dev/null
+++ b/doc/special_remotes/comment_14_a8419963dc024b1d9eb73807596012dc._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 14"
+ date="2013-05-22T14:30:00Z"
+ content="""
+You do not need to use the assistant to configure the costs of remotes. Just set `remote.<name>.annex-cost` to appropriate values. See also the documentation for the `remote.<name>.annex-cost-command` which allows your own code to calculate costs.
+"""]]
diff --git a/doc/special_remotes/comment_15_95ccfdd22a2391daa99e0beb04adedd6._comment b/doc/special_remotes/comment_15_95ccfdd22a2391daa99e0beb04adedd6._comment
new file mode 100644
index 000000000..3e2ea9948
--- /dev/null
+++ b/doc/special_remotes/comment_15_95ccfdd22a2391daa99e0beb04adedd6._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://yarikoptic.myopenid.com/"
+ nickname="site-myopenid"
+ subject="remotes costs"
+ date="2013-05-22T18:33:11Z"
+ content="""
+Thank you -- that is nice!
+
+Could costs be presented in 'whereis' and 'status' commands? e.g. like we know APT repositories priorities from apt-cache policy -- now I do not see them (at least in 4.20130501... updating to sid's 0521 now)
+
+"""]]
diff --git a/doc/special_remotes/comment_16_b9d238fb15ad7628e33c90b071e07bb0._comment b/doc/special_remotes/comment_16_b9d238fb15ad7628e33c90b071e07bb0._comment
new file mode 100644
index 000000000..8b1fcd831
--- /dev/null
+++ b/doc/special_remotes/comment_16_b9d238fb15ad7628e33c90b071e07bb0._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://yarikoptic.myopenid.com/"
+ nickname="site-myopenid"
+ subject="compression -- storage and transfer"
+ date="2013-05-22T18:48:59Z"
+ content="""
+Is there any remote which would not only compress during transfer (I believe rsync does that, right?) but also store objects compressed?
+
+I thought bup would do both -- but it seems that git annex receives data uncompressed from a bup remote, and bup remote requires ssh access.
+
+In my case I want to make publicly available files which are binary blobs which could be compressed very well. It would be a pity if I waste storage on my end and also incur significant traffic, which could be avoided if data load was transferred compressed. May be HTTP compression (http://en.wikipedia.org/wiki/HTTP_compression) could somehow be used efficiently for this purpose (not sure if load then originally could already reside in a compressed form to avoid server time to re-compress it)?
+"""]]
diff --git a/doc/special_remotes/comment_17_cc21b81a8f809f6efa5f5b6332513fc3._comment b/doc/special_remotes/comment_17_cc21b81a8f809f6efa5f5b6332513fc3._comment
new file mode 100644
index 000000000..f576e2723
--- /dev/null
+++ b/doc/special_remotes/comment_17_cc21b81a8f809f6efa5f5b6332513fc3._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://yarikoptic.myopenid.com/"
+ nickname="site-myopenid"
+ subject="Re: compression -- storage and transfer"
+ date="2013-05-22T19:17:33Z"
+ content="""
+ha -- apparently it is trivial to configure apache to serve pre-compressed files (e.g. see http://stackoverflow.com/questions/75482/how-can-i-pre-compress-files-with-mod-deflate-in-apache-2-x) and they arrive compressed to client with
+
+Content-Encoding: gzip
+
+but unfortunately git-annex doesn't like those (fails to \"verify\") -- do you think it could be implemented for web \"special remotes\"? that would be really nice -- then I could store such load on another website, and addurl links to the compressed content
+"""]]
diff --git a/doc/special_remotes/comment_18_3fe750118ff1edbe91a110b86fb5b662._comment b/doc/special_remotes/comment_18_3fe750118ff1edbe91a110b86fb5b662._comment
new file mode 100644
index 000000000..2345bba21
--- /dev/null
+++ b/doc/special_remotes/comment_18_3fe750118ff1edbe91a110b86fb5b662._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 18"
+ date="2013-05-23T23:25:02Z"
+ content="""
+All special remotes store files compressed when you enable encryption. Not otherwise, though.
+
+As far as the web special remote and pre-compressed files, files are downloaded from the web using `wget` or (of wget is not available) `curl`. So if you can make it work with those commands, it should work.
+"""]]
diff --git a/doc/special_remotes/comment_19_6794eb52bd87c28ef1df3172aa7d5780._comment b/doc/special_remotes/comment_19_6794eb52bd87c28ef1df3172aa7d5780._comment
new file mode 100644
index 000000000..b8c701ade
--- /dev/null
+++ b/doc/special_remotes/comment_19_6794eb52bd87c28ef1df3172aa7d5780._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://yarikoptic.myopenid.com/"
+ nickname="site-myopenid"
+ subject="compressed storage/transfer -- gzip Content-Type"
+ date="2013-05-25T06:41:37Z"
+ content="""
+FWIW -- eh -- unfortunately it seems not that transparent. wget seems to not support decompression at all, curl can do with explicit --compressed, BUT it doesn't distinguish url to a \"natively\" .gz file and pre-compressed content. And I am not sure if it is possible to anyhow reliably distinguish the two urls. In the case of obtaining pre-compressed file from my sample apache server the only difference in the http response header is that it gets \"compound\" ETag:
+compare ETag: \"3acb0e-17b38-4dd5343744660\" (for directly asking zeros100.gz) vs \"3acb0e-17b38-4dd5343744660;4dd5344e1537e\" (requesting zeros100) where portion past \";\" I guess signals the caching tag for gzipping, but not exactly sure on that since it seems to be not a part of standard. Also for zeros100 I am getting \"TCN: choice\"... once again not sure if that is any how reliably indicative for my purpose. So I guess there is no good way ATM via Content-Type request.
+"""]]
diff --git a/doc/special_remotes/comment_1_961276c18e9353ca8e25cad53e7ec51f._comment b/doc/special_remotes/comment_1_961276c18e9353ca8e25cad53e7ec51f._comment
new file mode 100644
index 000000000..ec1bea419
--- /dev/null
+++ b/doc/special_remotes/comment_1_961276c18e9353ca8e25cad53e7ec51f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawk9nck8WX8-ADF3Fdh5vFo4Qrw1I_bJcR8"
+ nickname="Jon Ander"
+ subject="MediaFire"
+ date="2013-01-17T12:17:54Z"
+ content="""
+MediaFire offers 50GB of free storage (max size 200MB). It would be great to support it as a new special remote.
+"""]]
diff --git a/doc/special_remotes/comment_20_6b7242721f2f2c77b634568cb737e3e3._comment b/doc/special_remotes/comment_20_6b7242721f2f2c77b634568cb737e3e3._comment
new file mode 100644
index 000000000..b17896a68
--- /dev/null
+++ b/doc/special_remotes/comment_20_6b7242721f2f2c77b634568cb737e3e3._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnWvnTWY6LrcPB4BzYEBn5mRTpNhg5EtEg"
+ nickname="Bence"
+ subject="Testing a special remote"
+ date="2013-11-24T08:24:36Z"
+ content="""
+Is there a unit test or integration test to check for the behavior of a special remote implementation and/or validity?
+
+I don't speak Haskell, so maybe there are some in the source but maybe I wouldn't recognize, so I haven't checked. If there are any tests how should I use it?
+
+Thank you,
+Bence
+"""]]
diff --git a/doc/special_remotes/comment_21_5c11e69c28b9ed4cbe238a36c0839a47._comment b/doc/special_remotes/comment_21_5c11e69c28b9ed4cbe238a36c0839a47._comment
new file mode 100644
index 000000000..1645e03e6
--- /dev/null
+++ b/doc/special_remotes/comment_21_5c11e69c28b9ed4cbe238a36c0839a47._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.64"
+ subject="comment 21"
+ date="2013-11-24T15:58:30Z"
+ content="""
+@Bence the closest I have is some tests of particular special remotes inside Test.hs. The shell equivilant of that code is:
+
+[[!format sh \"\"\"
+set -e
+git annex copy file --to remote # tests store
+git annex drop file # tests checkpresent when remote has file
+git annex move file --from remote # tests retrieve and remove
+\"\"\"]]
+"""]]
diff --git a/doc/special_remotes/comment_2_97543acfa7434e332ebea5672e446317._comment b/doc/special_remotes/comment_2_97543acfa7434e332ebea5672e446317._comment
new file mode 100644
index 000000000..840a9d626
--- /dev/null
+++ b/doc/special_remotes/comment_2_97543acfa7434e332ebea5672e446317._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.238"
+ subject="comment 2"
+ date="2013-01-17T16:44:25Z"
+ content="""
+Mediafire does not appear to offer any kind of API for its storage.
+"""]]
diff --git a/doc/special_remotes/comment_3_9229776623c234204c8b164edff95da0._comment b/doc/special_remotes/comment_3_9229776623c234204c8b164edff95da0._comment
new file mode 100644
index 000000000..84fe385e0
--- /dev/null
+++ b/doc/special_remotes/comment_3_9229776623c234204c8b164edff95da0._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawk9nck8WX8-ADF3Fdh5vFo4Qrw1I_bJcR8"
+ nickname="Jon Ander"
+ subject="MediaFire REST API"
+ date="2013-01-17T16:53:41Z"
+ content="""
+Wouldn't this be enough? http://developers.mediafire.com/index.php/REST_API
+"""]]
diff --git a/doc/special_remotes/comment_4_3bbda479d13f6bf393dcd59ed94ddeaa._comment b/doc/special_remotes/comment_4_3bbda479d13f6bf393dcd59ed94ddeaa._comment
new file mode 100644
index 000000000..c5979f819
--- /dev/null
+++ b/doc/special_remotes/comment_4_3bbda479d13f6bf393dcd59ed94ddeaa._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmRFKwny4rArBaz-36xTcsJYqKIgdDaw5Q"
+ nickname="Andrew"
+ subject="JABOF special remote"
+ date="2013-01-19T08:34:32Z"
+ content="""
+Similar to a JABOD, this would be Just A Bunch Of Files. I already have a NAS with a file structure conducive to serving media to my TV. However, it's not capable (currently) of running git-annex locally. It would be great to be able to tell annex the path to a file there as a remote much like a web remote from \"git annex addurl\". That way I can safely drop all the files I took with me on my trip, while annex still verifies and counts the file on the NAS as a location.
+
+There are some interesting things to figure out for this to be efficient. For example, SHAs of the files. Maybe store that in a metadata file in the directory of the files? Or perhaps use the WORM backend by default?
+"""]]
diff --git a/doc/special_remotes/comment_5_f7000975d38077828ab11a99095b39eb._comment b/doc/special_remotes/comment_5_f7000975d38077828ab11a99095b39eb._comment
new file mode 100644
index 000000000..1a9eb390a
--- /dev/null
+++ b/doc/special_remotes/comment_5_f7000975d38077828ab11a99095b39eb._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.3.194"
+ subject="comment 5"
+ date="2013-01-19T16:05:13Z"
+ content="""
+The web special remote is recently able to use file:// URL's, so you can just point to files on some arbitrary storage if you want to.
+"""]]
diff --git a/doc/special_remotes/comment_6_5d2bd7c1e1493d3c3784708a9b0bc001._comment b/doc/special_remotes/comment_6_5d2bd7c1e1493d3c3784708a9b0bc001._comment
new file mode 100644
index 000000000..0f11973f7
--- /dev/null
+++ b/doc/special_remotes/comment_6_5d2bd7c1e1493d3c3784708a9b0bc001._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlBia1J9-PoXgZYj2LASf7Bs__IqK3T8qQ"
+ nickname="Greg"
+ subject="Rackspace US/UK"
+ date="2013-01-30T11:33:12Z"
+ content="""
+It'd be awesome to be able to use Rackspace as remote storage as an alternative to S3, I would submit a patch, but know 0 Haskell :D
+"""]]
diff --git a/doc/special_remotes/comment_7_af01ee5ce31b1490af565cb087d65277._comment b/doc/special_remotes/comment_7_af01ee5ce31b1490af565cb087d65277._comment
new file mode 100644
index 000000000..043ad8eb5
--- /dev/null
+++ b/doc/special_remotes/comment_7_af01ee5ce31b1490af565cb087d65277._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn-UoTjMBsVh6q4HNViGwJi-5FNaCVQB7E"
+ nickname="Nico"
+ subject="Rapidshare"
+ date="2013-02-02T16:49:58Z"
+ content="""
+Would it be possible to support Rapidshare as a new special remote?
+They offer unlimited storage for 6-10€ per month. It would be great for larger backups.
+Their API can be found here: http://images.rapidshare.com/apidoc.txt
+"""]]
diff --git a/doc/special_remotes/comment_8_3d4ffec566d68d601eafe8758a616756._comment b/doc/special_remotes/comment_8_3d4ffec566d68d601eafe8758a616756._comment
new file mode 100644
index 000000000..85e663296
--- /dev/null
+++ b/doc/special_remotes/comment_8_3d4ffec566d68d601eafe8758a616756._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlRThEwuPnr8_bcuuCTQ0rQd3w6AfeMiLY"
+ nickname="Alex"
+ subject="'webhook' special remote?"
+ date="2013-02-24T15:05:27Z"
+ content="""
+Is there any chance a special remote that functions like a hybrid of 'web' and 'hook'? At least in theory, it should be relatively simple, since it would only support 'get' and the only meaningful parameters to pass would be the URL and the output file name.
+
+Maybe make it something like git config annex.myprogram-webhook 'myprogram $ANNEX_URL $ANNEX_FILE', and fetching could work by adding a --handler or --type parameter to addurl.
+
+The use case here is anywhere that simple 'fetch the file over HTTP/FTP/etc' isn't workable - maybe it's on rapidshare and you need to use plowshare to download it; maybe it's a youtube video and you want to use youtube-dl, maybe it's a chapter of a manga and you want to turn it into a CBZ file when you fetch it.
+
+"""]]
diff --git a/doc/special_remotes/comment_9_26af468952f0403171370b56e127830a._comment b/doc/special_remotes/comment_9_26af468952f0403171370b56e127830a._comment
new file mode 100644
index 000000000..88f021c6a
--- /dev/null
+++ b/doc/special_remotes/comment_9_26af468952f0403171370b56e127830a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlRThEwuPnr8_bcuuCTQ0rQd3w6AfeMiLY"
+ nickname="Alex"
+ subject="comment 9"
+ date="2013-02-24T15:13:16Z"
+ content="""
+A *ridiculously* cool possibility would be to allow them to match against URLs and then handle those (youtube-dl for youtube video URLs, for instance), but that would be additional work on your end and isn't really necessary.
+"""]]
diff --git a/doc/special_remotes/directory.mdwn b/doc/special_remotes/directory.mdwn
new file mode 100644
index 000000000..4d72e8bee
--- /dev/null
+++ b/doc/special_remotes/directory.mdwn
@@ -0,0 +1,33 @@
+This special remote type stores file contents in directory.
+
+One use case for this would be if you have a removable drive that
+you want to use it to sneakernet files between systems (possibly with
+[[encrypted|encryption]] contents). Just set up both systems to use
+the drive's mountpoint as a directory remote.
+
+If you just want two copies of your repository with the files "visible"
+in the tree in both, the directory special remote is not what you want.
+Instead, you should use a regular `git clone` of your git-annex repository.
+
+## configuration
+
+These parameters can be passed to `git annex initremote` to configure the
+remote:
+
+* `encryption` - One of "none", "hybrid", "shared", or "pubkey".
+ See [[encryption]].
+
+* `keyid` - Specifies the gpg key to use for [[encryption]].
+
+* `chunksize` - Avoid storing files larger than the specified size in the
+ directory. For use on directories on mount points that have file size
+ limitations. The default is to never chunk files.
+ The value can use specified using any commonly used units.
+ Example: `chunksize=100 megabytes`
+ Note that enabling chunking on an existing remote with non-chunked
+ files is not recommended.
+
+Setup example:
+
+ # git annex initremote usbdrive type=directory directory=/media/usbdrive/ encryption=none
+ # git annex describe usbdrive "usb drive on /media/usbdrive/"
diff --git a/doc/special_remotes/directory/comment_11_86f8c1b09cbd82bcd76378dfa1b3ca07._comment b/doc/special_remotes/directory/comment_11_86f8c1b09cbd82bcd76378dfa1b3ca07._comment
new file mode 100644
index 000000000..f29d54b59
--- /dev/null
+++ b/doc/special_remotes/directory/comment_11_86f8c1b09cbd82bcd76378dfa1b3ca07._comment
@@ -0,0 +1,49 @@
+[[!comment format=mdwn
+ username="dietz"
+ ip="128.119.40.196"
+ subject="annexing external files"
+ date="2013-07-18T20:57:53Z"
+ content="""
+This is great work. I've developed a serious annex-addiction and now I want to use it everywhere! In particular I was hoping to apply it to this use case:
+
+I have large files/directories (approx 5 TB) on an nfs mount to which is a) write-protected (think \"read-only medium\") and b) used by non-git users. Both reasons prevent me from setting up a git-annex repos there. However, I would like to use git-annex to keep track of the paths and get/drop files from my different computers.
+
+On one of my servers, I set up a git annex repos, hoping to only manage the structure, the locations, and the number of copies. I don't want to have copies of the 5TB files in that repository, as disk space is not unlimited (just for the sake of making them available to my laptop).
+
+I as banking on using a special remote (either directory or rsync) to tell the git-annex repos where the actual data is.
+
+I am not concerned with data loss, as it is backed up in regular time intervals by our sysadmin.
+
+
+I tried both directory remote and rsync remote but there seems to be a missing piece (I suppose its add). Any ideas?
+
+This is what I did:
+
+
+I added the directory remote and an rsync remote
+
+- $ git annex initremote collections type=directory directory=/my/nfs/dir encryption=none
+- $ git annex initremote rsync type=rsync rsyncurl=ssh://myserver/mnt/nfs/dir encryption=none
+
+the copy command fails without complaints
+ $ git annex copy --from collections
+
+I tried adding virtual files to git annex
+
+- $ git annex add file/inside/dir
+
+but still any kind of get/copy command does not get any new files
+
+
+It would be awesome if I could use git-annex for this, to keep track of my copies and copies of copies. And then I could also keep track of data on my write-protected DVDs.
+
+Is there any chance?
+
+Thanks a lot!
+
+-- Laura
+
+
+
+
+"""]]
diff --git a/doc/special_remotes/directory/comment_12._comment b/doc/special_remotes/directory/comment_12._comment
new file mode 100644
index 000000000..608fb62cd
--- /dev/null
+++ b/doc/special_remotes/directory/comment_12._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.2.25"
+ subject="comment 2"
+ date="2013-07-19T13:54:10Z"
+ content="""
+@Laura the directory special remote requires files to
+be in a particular directory structure with special names
+git-annex comes up with. So you can't use it on an existing
+tree of files like that.
+
+What you can do is use the [[web_special_remote|web]],
+with a `file://` url to point to the files wherever
+they are stored. So for example,
+`git annex addurl file:///media/dvd/file`
+"""]]
diff --git a/doc/special_remotes/directory/comment_12_311cd013fd8db47856d84161119e059d._comment b/doc/special_remotes/directory/comment_12_311cd013fd8db47856d84161119e059d._comment
new file mode 100644
index 000000000..21ab5aaa9
--- /dev/null
+++ b/doc/special_remotes/directory/comment_12_311cd013fd8db47856d84161119e059d._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="dietz"
+ ip="128.119.40.196"
+ subject="comment 12"
+ date="2013-07-20T06:06:31Z"
+ content="""
+Using the web remote is a pretty nice trick!
+
+Thanks, Joey - I would not have guessed that.
+
+-- Laura
+"""]]
diff --git a/doc/special_remotes/directory/comment_1_e8a53592adb13f7d7f212a2eb5a18a31._comment b/doc/special_remotes/directory/comment_1_e8a53592adb13f7d7f212a2eb5a18a31._comment
new file mode 100644
index 000000000..b2a041c53
--- /dev/null
+++ b/doc/special_remotes/directory/comment_1_e8a53592adb13f7d7f212a2eb5a18a31._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlc1og3PqIGudOMkFNrCCNg66vB7s-jLpc"
+ nickname="Paul"
+ subject="how is this different than rsync?"
+ date="2012-06-22T22:10:19Z"
+ content="""
+Thanks for this great tool! I was wondering what the differences are between using `type=directory`, `type=rsync`, or a bare git repo for directories?
+
+I guess I can't use just a regular repo because my USB drive is formatted as `vfat` -- which threw me for a loop the first time I heard about `git-annex` about a year ago, because I followed the walkthrough, and it didn't work as expected and gave up (now I know it was just a case of PEBKAC). It might be worth adding a note about [vfat](http://git-annex.branchable.com/bugs/fat_support/) to the \"Adding a remote\" section of the [walkthrough](http://git-annex.branchable.com/walkthrough/), since the unstated assumption there is that the USB drive is formatted as a filesystem that supports symlinks.
+
+Thanks again, my scientific data management just got a lot more sane!
+"""]]
diff --git a/doc/special_remotes/directory/comment_2_d949edad6a330079f9e15f703f9091e3._comment b/doc/special_remotes/directory/comment_2_d949edad6a330079f9e15f703f9091e3._comment
new file mode 100644
index 000000000..77b4c4d22
--- /dev/null
+++ b/doc/special_remotes/directory/comment_2_d949edad6a330079f9e15f703f9091e3._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.2.25"
+ subject="comment 2"
+ date="2012-06-25T15:29:29Z"
+ content="""
+The directory and rsync special remotes intentionally use the same layout. So the same directory could be set up as both types of special remotes.
+
+The main reason to use this rather than a bare git repo is that it supports encryption.
+"""]]
diff --git a/doc/special_remotes/directory/comment_3_49009f4e9e335c9a9d0422aa59c9a432._comment b/doc/special_remotes/directory/comment_3_49009f4e9e335c9a9d0422aa59c9a432._comment
new file mode 100644
index 000000000..b8ec51049
--- /dev/null
+++ b/doc/special_remotes/directory/comment_3_49009f4e9e335c9a9d0422aa59c9a432._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://dzsino.myopenid.com/"
+ nickname="dzsino"
+ subject="dropping a directory remote?"
+ date="2013-01-15T22:29:15Z"
+ content="""
+How do I drop a directory remote after initremote? Say I want to start over and enable chunking (not supposed to be enabled on an existing directory), can I simply git remote rm it?
+"""]]
diff --git a/doc/special_remotes/directory/comment_4_f5e9b0b477c4e521f8633fd274757fa3._comment b/doc/special_remotes/directory/comment_4_f5e9b0b477c4e521f8633fd274757fa3._comment
new file mode 100644
index 000000000..53fc857a3
--- /dev/null
+++ b/doc/special_remotes/directory/comment_4_f5e9b0b477c4e521f8633fd274757fa3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.238"
+ subject="comment 4"
+ date="2013-01-17T18:22:26Z"
+ content="""
+The best way to remove a special remote is to first `git annex move --from $remote` to get all the content out of it, then `git annex dead $remote` and finally you can `git remote rm $remote`
+"""]]
diff --git a/doc/special_remotes/directory/comment_5_e790718423c41f5ea8047ea5225bfacd._comment b/doc/special_remotes/directory/comment_5_e790718423c41f5ea8047ea5225bfacd._comment
new file mode 100644
index 000000000..dae22fc8f
--- /dev/null
+++ b/doc/special_remotes/directory/comment_5_e790718423c41f5ea8047ea5225bfacd._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawk3HGoDpnOPob5jOjvIootmkve1-nCpRiI"
+ nickname="Kalle"
+ subject="Directory remote with files accessible from non git-annex system?"
+ date="2013-01-20T15:44:16Z"
+ content="""
+
+
+
+
+"""]]
diff --git a/doc/special_remotes/directory/comment_6_325aac80b86588912c4fd61339ccbd0b._comment b/doc/special_remotes/directory/comment_6_325aac80b86588912c4fd61339ccbd0b._comment
new file mode 100644
index 000000000..7b9d21605
--- /dev/null
+++ b/doc/special_remotes/directory/comment_6_325aac80b86588912c4fd61339ccbd0b._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://nicolas-schodet.myopenid.com/"
+ ip="2a01:e35:8ae6:f130:1e4b:d6ff:fe78:1ddb"
+ subject="comment 6"
+ date="2013-06-26T17:52:12Z"
+ content="""
+I tried the suggestion on comment 4, but when I add again a remote with the same path, it gets the same repository identifier and is considered dead. Is that expected?
+
+My use case: I use a usb drive to transfer some large files from one git annex to another, then I use the usb drive for something else and the special remote is removed. Later I want to use the same usb drive again, but when I create the repository, it starts in the dead state.
+"""]]
diff --git a/doc/special_remotes/directory/comment_7_4206db69d68d9917623ce02500387021._comment b/doc/special_remotes/directory/comment_7_4206db69d68d9917623ce02500387021._comment
new file mode 100644
index 000000000..b1a3b953e
--- /dev/null
+++ b/doc/special_remotes/directory/comment_7_4206db69d68d9917623ce02500387021._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.193"
+ subject="comment 7"
+ date="2013-06-26T18:30:39Z"
+ content="""
+@nicolas, I suspect you are using `git annex initremote` with the same name that you used for the now dead-and-buried remote. That causes it to be reanimated, which is not what you want.
+
+Since git-annex version 4.20130501, `git annex initremote` is reserved for creating new remotes, not enabling old ones, so it will refuse to do this. That's to avoid exactly this confusion.
+
+Using `git annex initremote` with a different remote name, and the same directory should work just fine.
+"""]]
diff --git a/doc/special_remotes/directory/comment_8_acd9023511fe43817718bc89430f96c3._comment b/doc/special_remotes/directory/comment_8_acd9023511fe43817718bc89430f96c3._comment
new file mode 100644
index 000000000..29801fa36
--- /dev/null
+++ b/doc/special_remotes/directory/comment_8_acd9023511fe43817718bc89430f96c3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmRFKwny4rArBaz-36xTcsJYqKIgdDaw5Q"
+ nickname="Andrew"
+ subject="comment 8"
+ date="2013-06-26T18:46:40Z"
+ content="""
+For the use case you're describing, it might be better to define the usb key as a remote set to \"manual.\" Then, you can copy over the things you want with git annex copy --to=usbkey and when you're done drop everything with git annex drop --from=usbkey and never destroy the remote.
+"""]]
diff --git a/doc/special_remotes/directory/comment_9_d330eb808a990bb71034613c297a265e._comment b/doc/special_remotes/directory/comment_9_d330eb808a990bb71034613c297a265e._comment
new file mode 100644
index 000000000..47ac7541d
--- /dev/null
+++ b/doc/special_remotes/directory/comment_9_d330eb808a990bb71034613c297a265e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://nicolas-schodet.myopenid.com/"
+ ip="2a01:e35:8ae6:f130:1e4b:d6ff:fe78:1ddb"
+ subject="comment 9"
+ date="2013-06-26T20:05:20Z"
+ content="""
+Thanks for your answers. You're right, the simplest solution for me is to never remove the remote. If my directory is lost, I realized that I can simply create an empty directory.
+"""]]
diff --git a/doc/special_remotes/gcrypt.mdwn b/doc/special_remotes/gcrypt.mdwn
new file mode 100644
index 000000000..ac98c43bb
--- /dev/null
+++ b/doc/special_remotes/gcrypt.mdwn
@@ -0,0 +1,45 @@
+[git-remote-gcrypt](https://github.com/joeyh/git-remote-gcrypt/)
+adds support for encrypted remotes to git. The git-annex gcrypt special
+remote allows git-annex to also store its files in such repositories.
+Naturally, git-annex encrypts the files it stores too, so everything
+stored on the remote is encrypted.
+
+See [[tips/fully_encrypted_git_repositories_with_gcrypt]] for some examples
+of using gcrypt.
+
+## configuration
+
+These parameters can be passed to `git annex initremote` to configure
+gcrypt:
+
+* `encryption` - One of "none", "hybrid", "shared", or "pubkey".
+ See [[encryption]].
+
+* `keyid` - Specifies the gpg key to use for encryption of both the files
+ git-annex stores in the repository, as well as to encrypt the git
+ repository itself. May be repeated when multiple participants
+ should have access to the repository.
+
+* `gitrepo` - Required. The path or url to the git repository
+ for gcrypt to use. This repository should be either empty, or an existing
+ gcrypt repositry.
+
+* `shellescape` - See [[rsync]] for the details of this option.
+
+## notes
+
+For git-annex to store files in a repository on a remote server, you need
+shell access, and `rsync` must be installed. Those are the minimum
+requirements, but it's also recommended to install git-annex on the remote
+server, so that [[git-annex-shell]] can be used.
+
+While you can use git-remote-gcrypt with servers like github, git-annex
+can't store files on them. In such a case, you can just use
+git-remote-gcrypt directly.
+
+If you use encryption=hybrid, you can add more gpg keys that can access
+the files git-annex stored in the gcrypt repository. However, due to the
+way git-remote-gcrypt encrypts the git repository, you will need to somehow
+force it to re-push everything again, so that the encrypted repository can
+be decrypted by the added keys. Probably this can be done by setting
+`GCRYPT_FULL_REPACK` and doing a forced push of branches.
diff --git a/doc/special_remotes/glacier.mdwn b/doc/special_remotes/glacier.mdwn
new file mode 100644
index 000000000..b55b9adbb
--- /dev/null
+++ b/doc/special_remotes/glacier.mdwn
@@ -0,0 +1,47 @@
+This special remote type stores file contents in Amazon Glacier.
+
+To use it, you need to have [glacier-cli](http://github.com/basak/glacier-cli)
+installed.
+
+The unusual thing about Amazon Glacier is the multiple-hour delay it takes
+to retrieve information out of Glacier. To deal with this, commands like
+"git-annex get" request Glacier start the retrieval process, and will fail
+due to the data not yet being available. You can then wait appriximately
+four hours, re-run the same command, and this time, it will actually
+download the data.
+
+## configuration
+
+The standard environment variables `AWS_ACCESS_KEY_ID` and
+`AWS_SECRET_ACCESS_KEY` are used to supply login credentials
+for Amazon. You need to set these only when running
+`git annex initremote`, as they will be cached in a file only you
+can read inside the local git repository.
+
+A number of parameters can be passed to `git annex initremote` to configure
+the Glacier remote.
+
+* `encryption` - One of "none", "hybrid", "shared", or "pubkey".
+ See [[encryption]].
+
+* `keyid` - Specifies the gpg key to use for [[encryption]].
+
+* `embedcreds` - Optional. Set to "yes" embed the login credentials inside
+ the git repository, which allows other clones to also access them. This is
+ the default when gpg encryption is enabled; the credentials are stored
+ encrypted and only those with the repository's keys can access them.
+
+ It is not the default when using shared encryption, or no encryption.
+ Think carefully about who can access your repository before using
+ embedcreds without gpg encryption.
+
+* `datacenter` - Defaults to "us-east-1".
+
+* `vault` - By default, a vault name is chosen based on the remote name
+ and UUID. This can be specified to pick a vault name.
+
+* `fileprefix` - By default, git-annex places files in a tree rooted at the
+ top of the Glacier vault. When this is set, it's prefixed to the filenames
+ used. For example, you could set it to "foo/" in one special remote,
+ and to "bar/" in another special remote, and both special remotes could
+ then use the same vault.
diff --git a/doc/special_remotes/glacier/comment_1_fcd856b99dc6b3f9141b65fe639ef76b._comment b/doc/special_remotes/glacier/comment_1_fcd856b99dc6b3f9141b65fe639ef76b._comment
new file mode 100644
index 000000000..1d6d89433
--- /dev/null
+++ b/doc/special_remotes/glacier/comment_1_fcd856b99dc6b3f9141b65fe639ef76b._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmUJBh1lYmvfCCiGr3yrdx-QhuLCSRnU5c"
+ nickname="Justin"
+ subject="comment 1"
+ date="2013-05-16T00:54:21Z"
+ content="""
+The glacier-cli tool seems to have been abandoned, and there are a number of outstanding issues with it. boto has a `glacier` tool, but it doesn't seem to include caching, which seems to be something git annex needs.
+
+Looking through the PRs, it seems like we should build a tool specifically tailored to git annex's needs. It seems that there are at least three of us willing to hack on this if it's in Python. I'm not sure any of us knows haskell, though...
+"""]]
diff --git a/doc/special_remotes/glacier/comment_2_38fcca87074f6ea31a12569a822aa8c9._comment b/doc/special_remotes/glacier/comment_2_38fcca87074f6ea31a12569a822aa8c9._comment
new file mode 100644
index 000000000..939832b32
--- /dev/null
+++ b/doc/special_remotes/glacier/comment_2_38fcca87074f6ea31a12569a822aa8c9._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="basak"
+ ip="2001:8b0:1c8::2"
+ subject="comment 2"
+ date="2013-05-17T08:35:10Z"
+ content="""
+I'm the glacier-cli author. It is not abandoned!
+
+glacier-cli is supposed to map to Glacier exactly, so that it is compatible with all other tools. Most of the outstanding PRs break this essential behaviour, so I have not merged them. Many of the feature requests and bugs related to the upstream boto library, which is just about the best maintained client library that exists for AWS on any platform (and Amazon have adopted it now, IIRC). I have written appropriate reviews on all the PRs.
+
+If there is specific behaviour that git-annex needs, them I am happy to accept PRs for this, provided that they do not break the ability (and default) for glacier-cli to talk to Glacier natively without an extra layer of interpretation. If an extra layer of interpretation is needed (eg. forbidding duplicate \"keys\"), then this needs to be an option, or wrapped in a separate tool, or written into git-annex's Glacier special remote.
+"""]]
diff --git a/doc/special_remotes/glacier/comment_3_cea5bcb162e4288847ba5f25464a0406._comment b/doc/special_remotes/glacier/comment_3_cea5bcb162e4288847ba5f25464a0406._comment
new file mode 100644
index 000000000..8a8b914ad
--- /dev/null
+++ b/doc/special_remotes/glacier/comment_3_cea5bcb162e4288847ba5f25464a0406._comment
@@ -0,0 +1,28 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmUJBh1lYmvfCCiGr3yrdx-QhuLCSRnU5c"
+ nickname="Justin"
+ subject="comment 3"
+ date="2013-05-19T05:56:45Z"
+ content="""
+Hi! :)
+
+The main issue I'm hitting is the \"Multiple rows were found for one()\" error. I think I get this when git-annex tries to upload the same file twice (which may be a bug in git-annex, which could apply de-duplication earlier), but I think I also get it when trying to upload a file whose upload I've canceled in the past.
+
+I don't quite understand what git-annex needs here, and I totally understand that you're writing a general-purpose tool. But there does seem to be an issue that git-annex needs fixed one way or another.
+
+I'm happy to try fixing it myself if you can help me understand what's going on (I didn't quite understand your review in the PR), but if I'm the only person in the world using git-annex to back up to glacier, that scares me a little!
+
+ copy foo/bar/baz (checking glacier...) Traceback (most recent call last):
+ File \"/home/jlebar/code/glacier-cli/glacier\", line 694, in <module>
+ App().main()
+ File \"/home/jlebar/code/glacier-cli/glacier\", line 680, in main
+ args.func(args)
+ File \"/home/jlebar/code/glacier-cli/glacier\", line 579, in archive_checkpresent
+ last_seen = self.cache.get_archive_last_seen(args.vault, args.name)
+ File \"/home/jlebar/code/glacier-cli/glacier\", line 157, in get_archive_last_seen
+ result = self._get_archive_query_by_ref(vault, ref).one()
+ File \"/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/query.py\", line 2182, in one
+ \"Multiple rows were found for one()\")
+ sqlalchemy.orm.exc.MultipleResultsFound: Multiple rows were found for one()
+
+"""]]
diff --git a/doc/special_remotes/glacier/comment_4_0c92cc82c7ac513130f862391a02d329._comment b/doc/special_remotes/glacier/comment_4_0c92cc82c7ac513130f862391a02d329._comment
new file mode 100644
index 000000000..2de6632eb
--- /dev/null
+++ b/doc/special_remotes/glacier/comment_4_0c92cc82c7ac513130f862391a02d329._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="basak"
+ ip="2001:8b0:1c8::2"
+ subject="comment 4"
+ date="2013-05-22T18:10:32Z"
+ content="""
+Let's discuss this in a bug. I've created http://git-annex.branchable.com/bugs/Glacier_remote_uploads_duplicates/
+"""]]
diff --git a/doc/special_remotes/glacier/comment_5_8d1dcb4bf48386314bfb248ea6eeeb68._comment b/doc/special_remotes/glacier/comment_5_8d1dcb4bf48386314bfb248ea6eeeb68._comment
new file mode 100644
index 000000000..ee535e1f1
--- /dev/null
+++ b/doc/special_remotes/glacier/comment_5_8d1dcb4bf48386314bfb248ea6eeeb68._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://id.clacke.se/"
+ nickname="clacke"
+ subject="comment 5"
+ date="2013-06-03T09:03:57Z"
+ content="""
+You are not the only one, Justin. I am just getting into git-annex and I am setting up a glacier remote as I write this.
+"""]]
diff --git a/doc/special_remotes/glacier/comment_6_adb1db354dc4941e4b004e4ba34660d7._comment b/doc/special_remotes/glacier/comment_6_adb1db354dc4941e4b004e4ba34660d7._comment
new file mode 100644
index 000000000..717060fcb
--- /dev/null
+++ b/doc/special_remotes/glacier/comment_6_adb1db354dc4941e4b004e4ba34660d7._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmZgZuUhZlHpd_AbbcixY0QQiutb2I7GWY"
+ nickname="Jimmy"
+ subject="I know this thread is old but..."
+ date="2013-11-18T00:27:50Z"
+ content="""
+It's working well for me, though I seem to sometimes still hit the duplicate bug listed above.
+"""]]
diff --git a/doc/special_remotes/glacier/comment_7_747e403aac5acaba00e220931e926951._comment b/doc/special_remotes/glacier/comment_7_747e403aac5acaba00e220931e926951._comment
new file mode 100644
index 000000000..045fb6041
--- /dev/null
+++ b/doc/special_remotes/glacier/comment_7_747e403aac5acaba00e220931e926951._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlq4ClC5EMN1Vq1DpWXAqP5TiDnCK1mSfk"
+ nickname="Jonas"
+ subject="Expected cost for a repository"
+ date="2013-11-24T22:32:16Z"
+ content="""
+Is there a way to estimate the cost of storing a repo on glacier?
+
+I'm especially worried because of the cost of STORE and RETRIEVE requests; there are hundreds of thousands of small files in my annex repo, so that request cost could easily dominate storage cost. Does the glacier remote do anything to minimize the number of objects stored in glacier?
+"""]]
diff --git a/doc/special_remotes/hook.mdwn b/doc/special_remotes/hook.mdwn
new file mode 100644
index 000000000..eaea940a7
--- /dev/null
+++ b/doc/special_remotes/hook.mdwn
@@ -0,0 +1,103 @@
+This special remote type lets you store content in a remote of your own
+devising.
+
+It's not recommended to use this remote type when another like [[rsync]]
+or [[directory]] will do. If your hooks are not carefully written, data
+could be lost.
+
+## example
+
+Here's a simple example that stores content on clay tablets. If you
+implement this example in the real world, I'd appreciate a tour
+next Apert! :) --[[Joey]]
+
+ # git config annex.cuneiform-store-hook 'tocuneiform < "$ANNEX_FILE" | tablet-writer --implement=stylus --title="$ANNEX_KEY" | tablet-proofreader | librarian --shelve --floor=$ANNEX_HASH_1 --shelf=$ANNEX_HASH_2'
+ # git config annex.cuneiform-retrieve-hook 'librarian --get --floor=$ANNEX_HASH_1 --shelf=$ANNEX_HASH_2 --title="$ANNEX_KEY" | tablet-reader --implement=coffee --implement=glasses --force-monastic-dedication | fromcuneiform > "$ANNEX_FILE"'
+ # git config annex.cuneiform-remove-hook 'librarian --get --floor=$ANNEX_HASH_1 --shelf=$ANNEX_HASH_2 --title="$ANNEX_KEY" | goon --hit-with-hammer'
+ # git config annex.cuneiform-checkpresent-hook 'librarian --find --force-distrust-catalog --floor=$ANNEX_HASH_1 --shelf=$ANNEX_HASH_2 --title="$ANNEX_KEY" --shout-title'
+ # git annex initremote library type=hook hooktype=cuneiform encryption=none
+ # git annex describe library "the reborn Library of Alexandria (upgrade to bronze plates pending)"
+
+Can you spot the potential data loss bugs in the above simple example?
+(Hint: What happens when the `tablet-proofreader` exits nonzero?)
+
+## configuration
+
+These parameters can be passed to `git annex initremote`:
+
+* `hooktype` - Required. This specifies a collection of hooks to use for
+ this remote.
+
+* `encryption` - One of "none", "hybrid", "shared", or "pubkey".
+ See [[encryption]].
+
+* `keyid` - Specifies the gpg key to use for [[encryption]].
+
+## hooks
+
+Each type of hook remote is specified by a collection of hook commands.
+Each hook command is run as a shell command line, and should return nonzero
+on failure, and zero on success.
+
+These environment variables are used to communicate with the hook commands:
+
+* `ANNEX_KEY` - name of a key to store, retrieve, remove, or check.
+* `ANNEX_FILE` - a file containing the key's content
+* `ANNEX_HASH_1` - short stable value, based on the key, can be used for hashing
+ into 1024 buckets.
+* `ANNEX_HASH_2` - another hash value, can be used for a second level of hashing
+
+The settings to use in git config for the hook commands are as follows:
+
+* `annex.$hooktype-store-hook` - Command run to store a key in the special remote.
+ `ANNEX_FILE` contains the content to be stored.
+
+* `annex.$hooktype-retrieve-hook` - Command run to retrieve a key from the special remote.
+ `ANNEX_FILE` is a file that the retrieved content should be written to.
+ The file may already exist with a partial
+ copy of the content (or possibly just garbage), to allow for resuming
+ of partial transfers.
+
+* `annex.$hooktype-remove-hook` - Command to remove a key from the special remote.
+
+* `annex.$hooktype-checkpresent-hook` - Command to check if a key is present
+ in the special remote. Should output the key name to stdout, on its own line,
+ if and only if the key has been actively verified to be present in the
+ special remote (caching presence information is a very bad idea);
+ all other output to stdout will be ignored.
+
+## combined hook program
+
+Rather than setting all of the above hooks, you can write a single
+program that handles everything, and set a single hook to make it be used.
+
+ # git config annex.demo-hook /usr/local/bin/annexdemo
+ # git annex initremote mydemorepo type=hook hooktype=demo encryption=none
+
+The program just needs to look at the `ANNEX_ACTION` environment variable
+to see what it's being asked to do For example:
+
+[[!format sh """
+#!/bin/sh
+set -e
+case "$ANNEX_ACTION" in
+ store)
+ demo-upload "$ANNEX_HASH_1/$ANNEX_HASH_2/$ANNEX_KEY" < "$ANNEX_FILE"
+ ;;
+ retrieve)
+ demo-download "$ANNEX_HASH_1/$ANNEX_HASH_2/$ANNEX_KEY" > "$ANNEX_FILE"
+ ;;
+ remove)
+ demo-nuke "$ANNEX_HASH_1/$ANNEX_HASH_2/$ANNEX_KEY"
+ ;;
+ checkpresent)
+ if demo-exists "$ANNEX_HASH_1/$ANNEX_HASH_2/$ANNEX_KEY"; then
+ echo "$ANNEX_KEY"
+ fi
+ ;;
+ *)
+ echo "unknown ANNEX_ACTION: $ANNEX_ACTION" >&2
+ exit 1
+ ;;
+esac
+"""]]
diff --git a/doc/special_remotes/hook/comment_1_6a74a25891974a28a8cb42b87cb53c26._comment b/doc/special_remotes/hook/comment_1_6a74a25891974a28a8cb42b87cb53c26._comment
new file mode 100644
index 000000000..2163ba76d
--- /dev/null
+++ b/doc/special_remotes/hook/comment_1_6a74a25891974a28a8cb42b87cb53c26._comment
@@ -0,0 +1,32 @@
+[[!comment format=mdwn
+ username="helmut"
+ ip="89.0.176.236"
+ subject="Asynchronous hooks?"
+ date="2012-10-13T09:46:14Z"
+ content="""
+Is there a way to use asynchronous remotes? Interaction with git annex would have to
+split the part of initiating some action from completing it.
+
+I imagine I could `git annex copy` a file to an asynchronous remote and the command
+would almost immediately complete. Later I would learn that the transfer is
+completed, so the hook must be able to record that information in the `git-annex`
+branch. An additional plumbing command seems required here as well as a way to
+indicate that even though the store-hook completed, the file is not transferred.
+
+Similarly `git annex get` would immediately return without actually fetching the
+file. This should already be possible by returning non-zero from the retrieve-hook.
+Later the hook could use plumbing level commands to actually stick the received file
+into the repository.
+
+The remove-hook should need no changes, but the checkpresent-hook would be more like
+a trigger without any actual result. The extension of the plumbing required for the
+extension to the receive-hook could update the location log. A downside here is that
+you never know when a fsck has completed.
+
+My proposal does not include a way to track the completion of actions, but relies on
+the hook to always complete them reliably. It is not clear that this is the best road
+for asynchronous hooks.
+
+One use case for this would be a remote that is only accessible via uucp. Are there
+other use cases? Is the drafted interface useful?
+"""]]
diff --git a/doc/special_remotes/hook/comment_2_ee7c43b93c5b787216334f019643f6a0._comment b/doc/special_remotes/hook/comment_2_ee7c43b93c5b787216334f019643f6a0._comment
new file mode 100644
index 000000000..ec64dd96d
--- /dev/null
+++ b/doc/special_remotes/hook/comment_2_ee7c43b93c5b787216334f019643f6a0._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnWvnTWY6LrcPB4BzYEBn5mRTpNhg5EtEg"
+ nickname="Bence"
+ subject="More environment variables"
+ date="2013-07-09T10:28:58Z"
+ content="""
+Could you please include the original filename+path in the environment variables (_next to ANNEX_KEY & ANNEX_FILE_)? Like ANNEX_FILENAME and ANNEX_PATH.
+
+Having these infos in a hook would help eg. a flickr backend to be more usefull. [Tags](http://www.flickr.com/help/tags/) would contain the ANNEX_KEY and the image title could be the original filename (ANNEX_FILENAME). Also, having directory path (ANNEX_PATH) for the given file, the uploading process could put images into the proper sets/collections. Voila, you have a \"filesystem based\" flickr image gallery (almost like flickrfs).
+
+Other backends, like AmazonS3 having [meta data](http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html) also could benefit from this.
+
+To build the Death Star further, an _annex.$hooktype-**sync**-hook_ would instruct the backend to sync data, eg. place or move images/files in the proper image-sets/directories after they are moved/repositioned in git-annex, but that would be the backend's job, not git-annex's. Maybe the sync-hook would be called when _git annex sync_ is called. This is just an idea.
+
+While writing this, a new hook for sharing came into my mind: _annex.$hooktype-**share**-hook_.
+Calling this on a file/directory (_git annex share my_image_to_share.jpg_) would return a publicly shareable (short)url pointing to the file/directory. This would work for web-backends like AmazonS3, flickr, DropBox, Google Drive, ...
+"""]]
diff --git a/doc/special_remotes/hook/comment_3_2593291795e732994862d08bf2ed467b._comment b/doc/special_remotes/hook/comment_3_2593291795e732994862d08bf2ed467b._comment
new file mode 100644
index 000000000..0f8c80254
--- /dev/null
+++ b/doc/special_remotes/hook/comment_3_2593291795e732994862d08bf2ed467b._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmWg4VvDTer9f49Y3z-R0AH16P4d1ygotA"
+ nickname="Tobias"
+ subject="comment 3"
+ date="2013-07-09T10:54:58Z"
+ content="""
+I have requested this before. But it doesn't seem to be entirely doable because some items may have multiple equally correct filenames/paths. And some items may have zero filenames/paths.
+
+That said I hope a solution can be found because I really want this feature too. And would implement it in all my hooks.
+
+And for some of the cases i don't really see it as an issue. If you have a public flickr repo with clean(unencrypted) files. It is because you want to access existing files. If an object has no filename/path the hook could/would/should just ignore the file, sure this means no backup of old versions of files, but you can have other backends for those versions.
+
+The bigger issue is with the same file existing multiple places in the annex, which filename/path should be used? And the filename/path can change between sync(if it is deleted from one of the positions). I personally still see this as being entirely doable. The key for downloading would always be the same, so worst case scenario is the image may be duplicated on flickr. Or that the picture only one of the multiple folders it should be in on flickr. Still, i see these issues as being minor, and that usability would increase if this was implemented, even with these caveats.
+
+And there probably is some issues I haven't realized/know about.
+
+"""]]
diff --git a/doc/special_remotes/hook/comment_4_35d79b5ffa5a19056efcdc805070bc4b._comment b/doc/special_remotes/hook/comment_4_35d79b5ffa5a19056efcdc805070bc4b._comment
new file mode 100644
index 000000000..988d17def
--- /dev/null
+++ b/doc/special_remotes/hook/comment_4_35d79b5ffa5a19056efcdc805070bc4b._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnWvnTWY6LrcPB4BzYEBn5mRTpNhg5EtEg"
+ nickname="Bence"
+ subject="checkpresent success and failure"
+ date="2013-07-31T13:06:21Z"
+ content="""
+What value should be returned in the \"checkpresent-hook\" to signal that the given file does not exist in the given backend?
+
+Should the called hook process return an exit code less or greater then zero? In this case the following is displayed:
+>(user error (sh [\"-c\",\"name_of_the_process\"] exited 1)) failed
+
+This tells that the process failed (no internet connection or something that prevents the process from doing its job) and not that result is false, which would mean the file/entry does not exist in the given backend.
+If the return code is zero the file is treated as existing file/entry (no matter what I write to stderr).
+
+Also I think, the \"checkpresent\" block misses the ending ;; in the example.
+
+Here is my work-in-progress hook: https://gist.github.com/parhuzamos/31bf4516eea434e0d248
+"""]]
diff --git a/doc/special_remotes/hook/comment_5_6fbf1e963fa3ea4b2eb8ca5a3819762d._comment b/doc/special_remotes/hook/comment_5_6fbf1e963fa3ea4b2eb8ca5a3819762d._comment
new file mode 100644
index 000000000..a4c7b525e
--- /dev/null
+++ b/doc/special_remotes/hook/comment_5_6fbf1e963fa3ea4b2eb8ca5a3819762d._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.21"
+ subject="comment 5"
+ date="2013-07-31T16:25:55Z"
+ content="""
+The checkpresent hook should always exit 0 unless there was an exceptional condition (eg, perhaps it cannot check if the file exists one way or the other). Like the documentation for it says, the important thing is what it outputs to stdout, which should contain the key name if it's present, and should not contain the key name if it's not present.
+
+I hope you post to this website about your special remote when you get it fully working!
+"""]]
diff --git a/doc/special_remotes/hook/comment_6_e0ab48d5333e5de85f016b097e6fdac1._comment b/doc/special_remotes/hook/comment_6_e0ab48d5333e5de85f016b097e6fdac1._comment
new file mode 100644
index 000000000..e7c218f57
--- /dev/null
+++ b/doc/special_remotes/hook/comment_6_e0ab48d5333e5de85f016b097e6fdac1._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnWvnTWY6LrcPB4BzYEBn5mRTpNhg5EtEg"
+ nickname="Bence"
+ subject="comment 6"
+ date="2013-07-31T17:34:50Z"
+ content="""
+Roger that.
+
+If this is acceptable: [terminal output screenshot](http://i.imgur.com/lsJJYwF.png), than I'm almost done and will publish soon.
+(Of course a REST API using client would much be better, but this is just the start.)
+
+"""]]
diff --git a/doc/special_remotes/hook/comment_7_cc2b1243c2c36e63241513bcaddfea67._comment b/doc/special_remotes/hook/comment_7_cc2b1243c2c36e63241513bcaddfea67._comment
new file mode 100644
index 000000000..68cdf6545
--- /dev/null
+++ b/doc/special_remotes/hook/comment_7_cc2b1243c2c36e63241513bcaddfea67._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.21"
+ subject="comment 7"
+ date="2013-07-31T17:42:22Z"
+ content="""
+If I were you I'd suppress that \"File not found\" error.
+
+Hook special remotes *can* output messages to stderr, and it's also fine to output eg, progress bars to stdout when seding/receving files. But unnecessary cluttery output should be avoided.
+"""]]
diff --git a/doc/special_remotes/hook/comment_8_bbae315233bda48eb04662dfd48cf1ae._comment b/doc/special_remotes/hook/comment_8_bbae315233bda48eb04662dfd48cf1ae._comment
new file mode 100644
index 000000000..81cc32511
--- /dev/null
+++ b/doc/special_remotes/hook/comment_8_bbae315233bda48eb04662dfd48cf1ae._comment
@@ -0,0 +1,30 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnWvnTWY6LrcPB4BzYEBn5mRTpNhg5EtEg"
+ nickname="Bence"
+ subject="checkpresent again"
+ date="2013-08-01T23:18:38Z"
+ content="""
+In the current [HEAD](https://github.com/joeyh/git-annex/commit/bb74db6ef094324062adcf26a677113ee6fd0e58) the \"checkpresent\" method in [Hook.hs](https://github.com/joeyh/git-annex/blob/master/Remote/Hook.hs#L145) is missing a \"return\" while other hooks have a return value eg. [Directory.hs](https://github.com/joeyh/git-annex/blob/master/Remote/Directory.hs#L241), [Rsync.hs](https://github.com/joeyh/git-annex/blob/master/Remote/Rsync.hs#L272), ...
+
+
+I noticed that if my *checkpresent* hook does not output anything (to be exact: I commented out all the lines in the block) it behaves strangely. I copied the test file to \"copyrepo\", removed it by hand (so git-annex does not know about the change) and executed a fsck.
+
+ ~/annex5/test1/123 $ git annex fsck --from copyrepo --fast
+ fsck somefile.1 (checking copyrepo...) (fixing location log)
+ ** Based on the location log, somefile.1
+ ** was expected to be present, but its content is missing.
+ failed
+
+running the check again
+
+ ~/annex5/test1/123 $ ga fsck --from copyrepo --fast
+ fsck somefile.1 (checking copyrepo...) ok
+
+and running the check again without --fast
+
+ ~/annex5/test1/123 $ ga fsck --from copyrepo
+ fsck somefile.1 (checking copyrepo...) ok
+
+It thinks, the file is in the repo but it is not.
+
+"""]]
diff --git a/doc/special_remotes/hook/comment_9_037523d1994c702239ca96791156fe65._comment b/doc/special_remotes/hook/comment_9_037523d1994c702239ca96791156fe65._comment
new file mode 100644
index 000000000..89719adfb
--- /dev/null
+++ b/doc/special_remotes/hook/comment_9_037523d1994c702239ca96791156fe65._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.145"
+ subject="comment 9"
+ date="2013-08-01T23:51:48Z"
+ content="""
+The behavior you show with `fsck --from` is that the first time it's run against the damaged remote it notices the file is not present using the checkpresent hook. It then updates the location log. The subsequent times it's run, it sees that the location log says the file is not present in the remote. It verifies this is the case by calling the checkpresent hook. Since the two data sources agree, and numcopies is still satisfied, it prints \"ok\". There does not seem to be a bug here.
+
+(`return` in Haskell does not do what you would expect to happen in a traditional imperative language. It does not alter control flow, and any function using `return` can be mechanically converted to one that does not use `return`.)
+"""]]
diff --git a/doc/special_remotes/rsync.mdwn b/doc/special_remotes/rsync.mdwn
new file mode 100644
index 000000000..b2a9d23f5
--- /dev/null
+++ b/doc/special_remotes/rsync.mdwn
@@ -0,0 +1,56 @@
+This special remote type rsyncs file contents to somewhere else.
+
+Setup example:
+
+ # git annex initremote myrsync type=rsync rsyncurl=rsync://rsync.example.com/myrsync keyid=joey@kitenet.net
+ # git annex describe myrsync "rsync server"
+
+Or for using rsync over SSH
+
+ # git annex initremote myrsync type=rsync rsyncurl=ssh.example.com:/myrsync keyid=joey@kitenet.net
+ # git annex describe myrsync "rsync server"
+
+## configuration
+
+These parameters can be passed to `git annex initremote` to configure rsync:
+
+* `encryption` - One of "none", "hybrid", "shared", or "pubkey".
+ See [[encryption]].
+
+* `keyid` - Specifies the gpg key to use for [[encryption]].
+
+* `rsyncurl` - Required. This is the url or `hostname:/directory` to
+ pass to rsync to tell it where to store content.
+
+* `shellescape` - Optional. Set to "no" to avoid shell escaping normally
+ done when using rsync over ssh. That escaping is needed with typical
+ setups, but not with some hosting providers that do not expose rsynced
+ filenames to the shell. You'll know you need this option if `git annex get`
+ from the special remote fails with an error message containing a single
+ quote (`'`) character. If that happens, you can run enableremote
+ setting shellescape=no.
+
+The `annex-rsync-options` git configuration setting can be used to pass
+parameters to rsync.
+
+## annex-rsync-transport
+
+You can use the `annex-rsync-transport` git configuration setting to choose
+whether we run rsync over ssh or rsh. This setting is also used to specify
+parameters that git annex will pass to ssh/rsh.
+
+ssh is the default transport; if you'd like to run rsync over rsh, modify your
+.git/config to include
+
+ annex-rsync-transport = rsh
+
+under the appropriate remote.
+
+To pass parameters to ssh/rsh, include the parameters after "rsh" or
+"ssh". For example, to configure ssh to use the private key at
+`/path/to/private/key`, specify
+
+ annex-rsync-transport = ssh -i /path/to/private/key
+
+Note that environment variables aren't expanded here, so for example, you
+cannot specify `-i $HOME/.ssh/private_key`.
diff --git a/doc/special_remotes/rsync/comment_10_43e8fa3517c1f5935f02ad06fbed63dc._comment b/doc/special_remotes/rsync/comment_10_43e8fa3517c1f5935f02ad06fbed63dc._comment
new file mode 100644
index 000000000..185bd97ec
--- /dev/null
+++ b/doc/special_remotes/rsync/comment_10_43e8fa3517c1f5935f02ad06fbed63dc._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://cstork.org/"
+ nickname="Chris Stork"
+ subject="comment 10"
+ date="2013-08-25T20:59:41Z"
+ content="""
+@joey I don't understand you last comment where you state that special remotes can act as transfer repositories \"to transfer the files between computers that do not communicate directly\". If there's no communication, ie git pushes or pulls, between the computers then they don't know what file names the files on the special remote map to. They need to somehow communicate the git repo too, don't they?
+"""]]
diff --git a/doc/special_remotes/rsync/comment_11_8cafc1a8b37e6fb056185ec058c0c3e8._comment b/doc/special_remotes/rsync/comment_11_8cafc1a8b37e6fb056185ec058c0c3e8._comment
new file mode 100644
index 000000000..c8fc8831a
--- /dev/null
+++ b/doc/special_remotes/rsync/comment_11_8cafc1a8b37e6fb056185ec058c0c3e8._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 11"
+ date="2013-08-26T18:36:03Z"
+ content="""
+@Chris yes in that case you still need, a central git repository (which need not be on a host that supports git-annex), or the assistant can use xmpp to sync the git data.
+"""]]
diff --git a/doc/special_remotes/rsync/comment_1_9e180c397486989beab21699b8e8f103._comment b/doc/special_remotes/rsync/comment_1_9e180c397486989beab21699b8e8f103._comment
new file mode 100644
index 000000000..a4c403e7e
--- /dev/null
+++ b/doc/special_remotes/rsync/comment_1_9e180c397486989beab21699b8e8f103._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="diepes"
+ ip="105.227.34.36"
+ subject="rsync description and example"
+ date="2013-03-29T15:57:20Z"
+ content="""
+Hi, I would like to see a example of setting up / using e.g. rsync.net as a repo.
+
+
+Please also provide a highlevel description of how the rsync repo fits in with git-annex.
+
+
+Q1. can you adds files to the remote rsync repo, and will they be detected and synced back ?
+Q2. is all the git history rsync'd to remote ? how do i recover if i loose all data except the remote rsync repo ?
+
+"""]]
diff --git a/doc/special_remotes/rsync/comment_2_25545dc0b53f09ae73b29899c8884b02._comment b/doc/special_remotes/rsync/comment_2_25545dc0b53f09ae73b29899c8884b02._comment
new file mode 100644
index 000000000..3a6e25b0d
--- /dev/null
+++ b/doc/special_remotes/rsync/comment_2_25545dc0b53f09ae73b29899c8884b02._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-03-29T17:12:47Z"
+ content="""
+No, special remotes do not contain a copy of the git repository, and no, git-annex does not notice when files are added to remote rsync repositories. Suggest you read [[special_remotes]].
+"""]]
diff --git a/doc/special_remotes/rsync/comment_3_960a89b1ae7e3888ffba06baa963dc21._comment b/doc/special_remotes/rsync/comment_3_960a89b1ae7e3888ffba06baa963dc21._comment
new file mode 100644
index 000000000..37911a7e7
--- /dev/null
+++ b/doc/special_remotes/rsync/comment_3_960a89b1ae7e3888ffba06baa963dc21._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="diepes"
+ ip="105.227.34.36"
+ subject="sshfs ? and no sync from special remote to 2nd git-annex ?"
+ date="2013-03-29T22:09:49Z"
+ content="""
+* It sound to me it would be 1st prize if the cloud provider supported the git-annex functionality over ssh.
+* Then it could be a full git-annex repo, and used for recovery if my laptop with the git info gets lost.
+* From special remotes \"These can be used just like any normal remote by git-annex\"
+* Your comment \"No, special remotes do not contain a copy of the git repository\"
+
+ * so a special remote is
+
+1. \"A. just a remote filesystem, that contains the objects with sha1 names ? \"
+2. \"B. there is no git info and thus no file name & directory details or am i missing something ?\"
+3. \"C. you can't use the remote as a cloud drive to sync changes e.g. file moves, renames between two other git-annex repositories ? (no meta data)\"
+4. \"D. the data on the cloud/rsync storage can not be used directly it has to moved into a git-annex capable storage location. \"
+
+* Would it not be better to mount the remote storage over ssh(sshfs) and then use full git-annex on mounted directory ?
+"""]]
diff --git a/doc/special_remotes/rsync/comment_4_db84816c31239953dd21f23a8c557b43._comment b/doc/special_remotes/rsync/comment_4_db84816c31239953dd21f23a8c557b43._comment
new file mode 100644
index 000000000..4e95fac20
--- /dev/null
+++ b/doc/special_remotes/rsync/comment_4_db84816c31239953dd21f23a8c557b43._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="diepes"
+ ip="41.160.8.49"
+ subject="rsync.net support git and rsync, not git-annex"
+ date="2013-05-13T14:44:53Z"
+ content="""
+how would i use rsync.net as a full repository ? (annex files and git repo)
+
+It support's rsync, and I discovered now git as well.
+
+I had a look at the webapp and can't figure out how to set it up, so I can have multiple remote's sync to rsync.net for annex files and git sync.
+
+Link: http://www.rsync.net/resources/howto/github_integration.html
+
+"""]]
diff --git a/doc/special_remotes/rsync/comment_5_ccaffa4aded9dab88c76a856b96ea5b9._comment b/doc/special_remotes/rsync/comment_5_ccaffa4aded9dab88c76a856b96ea5b9._comment
new file mode 100644
index 000000000..3368b59ed
--- /dev/null
+++ b/doc/special_remotes/rsync/comment_5_ccaffa4aded9dab88c76a856b96ea5b9._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="cehteh"
+ ip="217.8.62.137"
+ subject="rsync daemon mode"
+ date="2013-07-27T01:35:37Z"
+ content="""
+rsync has a --daemon mode with a simple challenge-response authentication but no encryption. This offers a nice lightweight alternative to ssh, especially when we
+store/transfer encrypted content anyways. Is this already supported in git-annex, if yes how to set it up?
+"""]]
diff --git a/doc/special_remotes/rsync/comment_6_e687b9482b177e1351c8c65ea617d3fa._comment b/doc/special_remotes/rsync/comment_6_e687b9482b177e1351c8c65ea617d3fa._comment
new file mode 100644
index 000000000..a5cf0514b
--- /dev/null
+++ b/doc/special_remotes/rsync/comment_6_e687b9482b177e1351c8c65ea617d3fa._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.246.110"
+ subject="comment 6"
+ date="2013-07-28T00:11:38Z"
+ content="""
+The first example on this page shows using rsync:// to store files on a system using the rsync daemon.
+"""]]
diff --git a/doc/special_remotes/rsync/comment_7_e122979ea811d9ef835ba05bb936190f._comment b/doc/special_remotes/rsync/comment_7_e122979ea811d9ef835ba05bb936190f._comment
new file mode 100644
index 000000000..8cb1d72b4
--- /dev/null
+++ b/doc/special_remotes/rsync/comment_7_e122979ea811d9ef835ba05bb936190f._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://olivier.berger.myopenid.com/"
+ nickname="obergix"
+ subject="rsync remote is basically more intended for backups ?"
+ date="2013-08-17T17:40:47Z"
+ content="""
+If I get it correctly, it is mainly useable as a backup, which will accumulate contents of the objects managed by git-annex over time.
+
+It would be great to have a use case illustrating its use in concrete matters. Thanks in advance.
+"""]]
diff --git a/doc/special_remotes/rsync/comment_8_d566113318d0aa7500d76ffe1bd46069._comment b/doc/special_remotes/rsync/comment_8_d566113318d0aa7500d76ffe1bd46069._comment
new file mode 100644
index 000000000..1e6bf8aa4
--- /dev/null
+++ b/doc/special_remotes/rsync/comment_8_d566113318d0aa7500d76ffe1bd46069._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 8"
+ date="2013-08-22T18:02:00Z"
+ content="""
+There are many use cases for a rsync special remote. You could use it as a backup. You could use it to archive files offline in a drive with encryption enabled so if the drive is stolen your data is not. You could `git annex move --to rsyncremote` large files when your local drive is getting full, and then `git annex move` the files back when free space is again available. You could have one repository copy files to a rsync remote, and then `git annex get` them on another repository, to transfer the files between computers that do not communicate directly. The git-annex assistant makes it easy to set up rsync remotes using this last scenario, which is referred to as a transfer repository, and arranges to drop files from the transfer repository once they have been transferred to all known clients.
+
+None of these use cases are particular to rsync remotes. Most special remotes can all be used in these and other ways. It largely doesn't matter for your use what underlying transport the special remote uses.
+"""]]
diff --git a/doc/special_remotes/rsync/comment_9_5dcf10a502b2d4feac46b620d43e9d00._comment b/doc/special_remotes/rsync/comment_9_5dcf10a502b2d4feac46b620d43e9d00._comment
new file mode 100644
index 000000000..b7690cf68
--- /dev/null
+++ b/doc/special_remotes/rsync/comment_9_5dcf10a502b2d4feac46b620d43e9d00._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://olivier.berger.myopenid.com/"
+ nickname="obergix"
+ subject="Added use cases to &quot;special remotes&quot;"
+ date="2013-08-22T20:23:13Z"
+ content="""
+Thanks @joeyh. I've taken the liberty to add your use case description to [[special remotes]]. Hope this helps.
+"""]]
diff --git a/doc/special_remotes/web.mdwn b/doc/special_remotes/web.mdwn
new file mode 100644
index 000000000..cd20a93bb
--- /dev/null
+++ b/doc/special_remotes/web.mdwn
@@ -0,0 +1,11 @@
+git-annex can use the WWW as a special remote, downloading urls to files.
+See [[tips/using_the_web_as_a_special_remote]] for usage examples.
+
+## notes
+
+Currently git-annex only supports downloading content from the web;
+it cannot upload to it or remove content.
+
+This special remote uses arbitrary urls on the web as the source for content.
+git-annex can also download content from a normal git remote, accessible by
+http.
diff --git a/doc/special_remotes/web/comment_1_0bd570025f6cd551349ea88a4729ac8e._comment b/doc/special_remotes/web/comment_1_0bd570025f6cd551349ea88a4729ac8e._comment
new file mode 100644
index 000000000..d01e17da3
--- /dev/null
+++ b/doc/special_remotes/web/comment_1_0bd570025f6cd551349ea88a4729ac8e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://olivier.berger.myopenid.com/"
+ nickname="obergix"
+ subject="Which URL prefix are supported ?"
+ date="2013-08-17T08:44:05Z"
+ content="""
+It is not clear whether only http:// URLs are supported. Can you list others ?
+"""]]
diff --git a/doc/special_remotes/web/comment_2_333141cc9ec6c26ffd19aa95303a91e3._comment b/doc/special_remotes/web/comment_2_333141cc9ec6c26ffd19aa95303a91e3._comment
new file mode 100644
index 000000000..ff2018117
--- /dev/null
+++ b/doc/special_remotes/web/comment_2_333141cc9ec6c26ffd19aa95303a91e3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 2"
+ date="2013-08-17T08:59:11Z"
+ content="""
+When it says \"arbitrary urls\", it means it. The only requirement is that the url be well formed and that wget or whatever command you have it configured to use via annex.web-download-command knows how to download it.
+"""]]
diff --git a/doc/special_remotes/webdav.mdwn b/doc/special_remotes/webdav.mdwn
new file mode 100644
index 000000000..251075b09
--- /dev/null
+++ b/doc/special_remotes/webdav.mdwn
@@ -0,0 +1,42 @@
+This special remote type stores file contents in a WebDAV server.
+
+## configuration
+
+The environment variables `WEBDAV_USERNAME` and `WEBDAV_PASSWORD` are used
+to supply login credentials. You need to set these only when running
+`git annex initremote`, as they will be cached in a file only you
+can read inside the local git repository.
+
+A number of parameters can be passed to `git annex initremote` to configure
+the webdav remote.
+
+* `encryption` - One of "none", "hybrid", "shared", or "pubkey".
+ See [[encryption]].
+
+* `keyid` - Specifies the gpg key to use for [[encryption]].
+
+* `embedcreds` - Optional. Set to "yes" embed the login credentials inside
+ the git repository, which allows other clones to also access them. This is
+ the default when gpg encryption is enabled; the credentials are stored
+ encrypted and only those with the repository's keys can access them.
+
+ It is not the default when using shared encryption, or no encryption.
+ Think carefully about who can access your repository before using
+ embedcreds without gpg encryption.
+
+* `url` - Required. The URL to the WebDAV directory where files will be
+ stored. This can be a subdirectory of a larger WebDAV repository, and will
+ be created as needed. Use of a https URL is strongly
+ encouraged, since HTTP basic authentication is used.
+
+* `chunksize` - Avoid storing files larger than the specified size in
+ WebDAV. For use when the WebDAV server has file size
+ limitations. The default is to never chunk files.
+ The value can use specified using any commonly used units.
+ Example: `chunksize=75 megabytes`
+ Note that enabling chunking on an existing remote with non-chunked
+ files is not recommended.
+
+Setup example:
+
+ # WEBDAV_USERNAME=joey@kitenet.net WEBDAV_PASSWORD=xxxxxxx git annex initremote box.com type=webdav url=https://www.box.com/dav/git-annex chunksize=75mb keyid=joey@kitenet.net
diff --git a/doc/special_remotes/webdav/comment_1_6b523eea78eae1d19fe2a9950ee33e3a._comment b/doc/special_remotes/webdav/comment_1_6b523eea78eae1d19fe2a9950ee33e3a._comment
new file mode 100644
index 000000000..768720fe5
--- /dev/null
+++ b/doc/special_remotes/webdav/comment_1_6b523eea78eae1d19fe2a9950ee33e3a._comment
@@ -0,0 +1,26 @@
+[[!comment format=mdwn
+ username="http://rfhbuk.myopenid.com/"
+ ip="109.145.123.81"
+ subject="git-annex initremote failing for webdav servers"
+ date="2012-12-01T10:18:04Z"
+ content="""
+Unfortunately, trying to set up the following webdav servers fail. Some of the terminal output of git-annex --debug initremote ... is below, but it may not really helpful. Can I help any further, can a webdav remote be set up in a different way? (The box.com webdav initremote worked fine.) Cheers
+
+
+With livedrive.com:
+
+ [2012-12-01 10:15:12 GMT] chat: gpg [\"--batch\",\"--no-tty\",\"--use-agent\",\"--quiet\",\"--trust-model\",\"always\",\"--encrypt\",\"--no-encrypt-to\",\"--no-default-recipient\",\"--recipient\",\"xxxxxxxxxxxxxx\"]
+ (encryption setup with gpg key xxxxxxxxxxxxxx) (testing WebDAV server...)
+ git-annex: \"Bad Request\": user error
+ failed
+ git-annex: initremote: 1 failed
+
+
+With sd2dav.1und1.de:
+
+ [2012-12-01 10:13:10 GMT] chat: gpg [\"--batch\",\"--no-tty\",\"--use-agent\",\"--quiet\",\"--trust-model\",\"always\",\"--encrypt\",\"--no-encrypt-to\",\"--no-default-recipient\",\"--recipient\",\"xxxxxxxxxxxxxx\"]
+ (encryption setup with gpg key xxxxxxxxxxxxxx) (testing WebDAV server...)
+ git-annex: \"Locked\": user error
+ failed
+ git-annex: initremote: 1 failed
+"""]]
diff --git a/doc/special_remotes/webdav/comment_2_83fc4e7d9ba7a05c8500da659f561b8f._comment b/doc/special_remotes/webdav/comment_2_83fc4e7d9ba7a05c8500da659f561b8f._comment
new file mode 100644
index 000000000..8a23ad493
--- /dev/null
+++ b/doc/special_remotes/webdav/comment_2_83fc4e7d9ba7a05c8500da659f561b8f._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.49"
+ subject="comment 2"
+ date="2012-12-01T18:34:05Z"
+ content="""
+I tried signing up for livedrive, but I cannot log into it with WebDav at all. Do they require a Pro account to use WebDav?
+
+When it's \"testing webdav server\", it tries to make a collection (a subdirectory), and uploads a file to it, and sets the file's properties, and deletes the file. One of these actions must be failing, perhaps because the webdav server implementation does not support it. Or perhaps because the webdav client library is doing something wrong. I've instrumented the test, so it'll say which one.
+"""]]
diff --git a/doc/special_remotes/webdav/comment_3_239367ad639c61ecdf87a89f7ac53efe._comment b/doc/special_remotes/webdav/comment_3_239367ad639c61ecdf87a89f7ac53efe._comment
new file mode 100644
index 000000000..2d559b7af
--- /dev/null
+++ b/doc/special_remotes/webdav/comment_3_239367ad639c61ecdf87a89f7ac53efe._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.49"
+ subject="comment 3"
+ date="2012-12-01T20:13:36Z"
+ content="""
+I've identified the problem keeping it working with livedrive. Once a patch I've written is applied to the Haskell DAV library, I'll be able to update git-annex to support it.
+
+I don't know about sd2dav.1und1.de. The error looks like it doesn't support WebDAV file locking.
+"""]]
diff --git a/doc/special_remotes/webdav/comment_4_ffa52f7776cdc8caa28667b5eadae123._comment b/doc/special_remotes/webdav/comment_4_ffa52f7776cdc8caa28667b5eadae123._comment
new file mode 100644
index 000000000..24dd85bf5
--- /dev/null
+++ b/doc/special_remotes/webdav/comment_4_ffa52f7776cdc8caa28667b5eadae123._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.49"
+ subject="comment 4"
+ date="2012-12-01T21:14:34Z"
+ content="""
+Good news, livedrive is supported now, by git-annex's master branch.
+"""]]
diff --git a/doc/special_remotes/webdav/comment_5_5b8cbdb5e9a1b90d748a5074997e1cd5._comment b/doc/special_remotes/webdav/comment_5_5b8cbdb5e9a1b90d748a5074997e1cd5._comment
new file mode 100644
index 000000000..7d5f3af5d
--- /dev/null
+++ b/doc/special_remotes/webdav/comment_5_5b8cbdb5e9a1b90d748a5074997e1cd5._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://peter-simons.myopenid.com/"
+ ip="192.100.130.7"
+ subject="WebDAV without locking"
+ date="2013-01-16T12:44:16Z"
+ content="""
+Hi Joey,
+
+you are right, the 1-und-1.de implementation of WebDAV does not support locking.
+
+Do you think there is a way to make that service work with git-annex anyhow -- say, by allowing the user to disable file-locking? I've worked around the problem with 1-und-1.de by using fuse+davfs2 to mount the storage in my file system and access it through the directory backend, but FUSE is dead slow, unfortunately, and this solution really sucks.
+"""]]
diff --git a/doc/special_remotes/webdav/comment_6_d3be3e588c3a2abb2025ceb82c18b0ef._comment b/doc/special_remotes/webdav/comment_6_d3be3e588c3a2abb2025ceb82c18b0ef._comment
new file mode 100644
index 000000000..150c984a8
--- /dev/null
+++ b/doc/special_remotes/webdav/comment_6_d3be3e588c3a2abb2025ceb82c18b0ef._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.238"
+ subject="comment 6"
+ date="2013-01-17T18:23:27Z"
+ content="""
+It seems it must advertise it supports the LOCK and UNLOCK http actions, but fails when they're used.
+
+The DAV library I am using always locks if it seems the server supports it. So this will need changes to that library. I've filed a bug requesting the changes. <http://bugs.debian.org/698379>
+"""]]
diff --git a/doc/special_remotes/webdav/comment_7_6fa7e11331db5a943015bd5367eb3d73._comment b/doc/special_remotes/webdav/comment_7_6fa7e11331db5a943015bd5367eb3d73._comment
new file mode 100644
index 000000000..324760c4c
--- /dev/null
+++ b/doc/special_remotes/webdav/comment_7_6fa7e11331db5a943015bd5367eb3d73._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawniayrgSdVLUc3c6bf93VbO-_HT4hzxmyo"
+ nickname="Tobias"
+ subject="SSL certificates"
+ date="2013-03-25T16:09:54Z"
+ content="""
+Trying to use webdav leads in:
+
+ git-annex: HandshakeFailed (Error_Protocol (\"certificate rejected: not coping with anything else Start (Container Context 0)\",True,CertificateUnknown))
+
+How can I disable the SSL certificate check?
+"""]]
diff --git a/doc/special_remotes/webdav/comment_8_2627b41f80c7511b27464e2040b128a8._comment b/doc/special_remotes/webdav/comment_8_2627b41f80c7511b27464e2040b128a8._comment
new file mode 100644
index 000000000..96ae19d11
--- /dev/null
+++ b/doc/special_remotes/webdav/comment_8_2627b41f80c7511b27464e2040b128a8._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 8"
+ date="2013-03-27T16:38:47Z"
+ content="""
+I don't think the checking of SSL certificates can currently be disabled.
+"""]]
diff --git a/doc/special_remotes/xmpp.mdwn b/doc/special_remotes/xmpp.mdwn
new file mode 100644
index 000000000..86f6a7c0b
--- /dev/null
+++ b/doc/special_remotes/xmpp.mdwn
@@ -0,0 +1,39 @@
+XMPP (Jabber) is used by the [[assistant]] as a git remote. This is,
+technically not a git-annex special remote (large files are not transferred
+over XMPP; only git commits are sent).
+
+Typically XMPP will be set up using the web app, but here's how a manual
+set up could be accomplished:
+
+1. xmpp login credentials need to be stored in `.git/annex/creds/xmpp`.
+ Obviously this file should be mode 600. An example file:
+
+ XMPPCreds {xmppUsername = "joeyhess", xmppPassword = "xxxx", xmppHostname = "xmpp.l.google.com.", xmppPort = 5222, xmppJID = "joeyhess@gmail.com"}
+
+2. A git remote is created using a special url, of the form `xmpp::user@host`
+ For the above example, it would be `url = xmpp::joeyhess@gmail.com`
+
+3. The uuid of one of the other clients using XMPP should be configured
+ using the `annex.uuid` setting, the same as is set up for other remotes.
+
+With the above configuration, the [[assistant]] will use xmpp remotes much as
+any other git remote. Since XMPP requires a client that is continually running
+to see incoming pushes, the XMPP remote cannot be used with git at the
+command line.
+
+## XMPP server support status
+[[!table data="""
+Provider|Status|Type|Notes
+[[Gmail|http://gmail.com]]|Working|?|Google Apps: [setup your SRV records](http://www.olark.com/gtalk/check_srv) or configure `.git/annex/creds/xmpp` manually
+[[Coderollers|http://www.coderollers.com/xmpp-server/]]|Working|[[Openfire|http://www.igniterealtime.org/projects/openfire/]]
+[[jabber.me|http://jabber.me/]]|Working|[[Tigase|http://www.tigase.org/]]
+[[xmpp.ru.net|https://www.xmpp.ru.net]]|Working|[[jabberd2|http://jabberd2.org/]]
+[[jabber.org|http://jabber.org]]|Working|[[Isode M-Link|http://www.isode.com/products/m-link.html]]
+-|Working|[[Prosody|http://prosody.im/]]|No providers tested.
+-|Working|[[Metronome|http://www.lightwitch.org/]]|No providers tested.
+-|[[Failing|http://git-annex.branchable.com/forum/XMPP_authentication_failure/]]|ejabberd|[[Authentication bug|https://support.process-one.net/browse/EJAB-1632]]: Fixed in debian unstable with version 2.1.10-5
+-|[[Failing|http://git-annex.branchable.com/forum/XMPP_authentication_failure/#comment-4ce5aeabd12ca3016290b3d8255f6ef1]]|jabberd14|No further information
+"""]]
+List of providers: [[http://xmpp.net/]]
+
+See also: [[xmpp_protocol_design_notes|design/assistant/xmpp]]
diff --git a/doc/special_remotes/xmpp/comment_10_c7c2e2e81cb5b2b9a5272430c835dd39._comment b/doc/special_remotes/xmpp/comment_10_c7c2e2e81cb5b2b9a5272430c835dd39._comment
new file mode 100644
index 000000000..0380af359
--- /dev/null
+++ b/doc/special_remotes/xmpp/comment_10_c7c2e2e81cb5b2b9a5272430c835dd39._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmZilYULa6CDEGfuagoDlesyakBgnf-dF8"
+ nickname="Maarten"
+ subject="Google Apps & SRV"
+ date="2013-11-27T18:13:18Z"
+ content="""
+To make XMPP via a Google Apps account work out of the box, all you need to do is add the correct SRV records to your domain's DNS zone. If you do, you don't need to manually create creds/xmpp, you can just use the web interface, enter your full apps email address and password (remember, if 2-factor, this needs to be an application-specific password).
+
+To create the correct SRV records (and check whether they're correct), see http://www.olark.com/gtalk/check_srv
+"""]]
diff --git a/doc/special_remotes/xmpp/comment_1_568247938929a2934e8198fca80b7184._comment b/doc/special_remotes/xmpp/comment_1_568247938929a2934e8198fca80b7184._comment
new file mode 100644
index 000000000..060aa5bd7
--- /dev/null
+++ b/doc/special_remotes/xmpp/comment_1_568247938929a2934e8198fca80b7184._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmWg4VvDTer9f49Y3z-R0AH16P4d1ygotA"
+ nickname="Tobias"
+ subject="User defined server"
+ date="2013-04-17T09:45:59Z"
+ content="""
+It would be nice if you could expand the XMPP setup in the assistant to support an \"advanced\" settings view where a custom server could be defined.
+
+Example: I have a google Apps domain called mytest.com, with the users bla1@mytest.com and bla2@mytest.com. When trying to add either of those accounts to the assistant XMPP will try to use mytest.com as the jabber server, and not googles server.
+
+"""]]
diff --git a/doc/special_remotes/xmpp/comment_2_9fc3f512020b7eb2591d6b7b2e8de2d7._comment b/doc/special_remotes/xmpp/comment_2_9fc3f512020b7eb2591d6b7b2e8de2d7._comment
new file mode 100644
index 000000000..02f70d0f2
--- /dev/null
+++ b/doc/special_remotes/xmpp/comment_2_9fc3f512020b7eb2591d6b7b2e8de2d7._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmRFKwny4rArBaz-36xTcsJYqKIgdDaw5Q"
+ nickname="Andrew"
+ subject="comment 2"
+ date="2013-04-17T22:28:39Z"
+ content="""
+Yeah, I agree, this would be nice.
+
+For your own domain, you can configure DNS like this: [[http://support.google.com/a/bin/answer.py?hl=en&answer=34143]] to make XMPP find the right server. But for some that's not an option and the \"advanced\" mode would be useful in that case.
+"""]]
diff --git a/doc/special_remotes/xmpp/comment_3_48ddbba1402d89acaea07cff747c48e0._comment b/doc/special_remotes/xmpp/comment_3_48ddbba1402d89acaea07cff747c48e0._comment
new file mode 100644
index 000000000..7643d4d7d
--- /dev/null
+++ b/doc/special_remotes/xmpp/comment_3_48ddbba1402d89acaea07cff747c48e0._comment
@@ -0,0 +1,28 @@
+[[!comment format=mdwn
+ username="RaspberryPie"
+ ip="46.19.143.203"
+ subject="Missing prerequisites for XMPP syncing?"
+ date="2013-09-17T06:53:59Z"
+ content="""
+I set up two fresh annexes that can talk via XMPP and no other way. After I fire up the assistants I expect them to sync their metadata, but nothing happens. One log gives me an 'XMPPClient: received: [\"Unknown message\"]' message every two minutes. The other one doesn't contain the string XMPP at all, not once. So my suspicion is that this particular version of git-annex doesn't support XMPP, which is weird because:
+
+ $ git annex version
+ git-annex version: 4.20130909
+ build flags: Assistant Pairing Testsuite S3 Inotify XMPP DNS Feeds
+ local repository version: 3
+ default repository version: 3
+ supported repository versions: 3 4
+ upgrade supported from repository versions: 0 1 2
+
+This is the version output from the other machine:
+
+ $ git annex version
+ git-annex version: 4.20130827
+ build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP
+ local repository version: 3
+ default repository version: 3
+ supported repository versions: 3 4
+ upgrade supported from repository versions: 0 1 2
+
+What am I missing? Are there more build flags for XMPP than the one called XMPP? (Also, no, I can't just copy versions between machines b/c the architectures are different. And yep, the one giving me trouble is ARM.)
+"""]]
diff --git a/doc/special_remotes/xmpp/comment_4_59857879abaae22bde444a215e00bf18._comment b/doc/special_remotes/xmpp/comment_4_59857879abaae22bde444a215e00bf18._comment
new file mode 100644
index 000000000..db217cff9
--- /dev/null
+++ b/doc/special_remotes/xmpp/comment_4_59857879abaae22bde444a215e00bf18._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.14.105"
+ subject="comment 4"
+ date="2013-09-19T21:07:35Z"
+ content="""
+If you have the XMPP flag in your git-annex build, it will support XMPP. Are you sure you set up the xmpp creds file and the xmpp special remote correctly on the ARM machine? (I assume it has no webapp, so you had to set that up manually..)
+
+Here's how you can do that manually:
+
+1. Run git-annex on a machine with the webapp, set up XMPP, and copy the .git/annex/creds/xmpp to the machine without the webapp.
+2. On the machine without the webapp, add a git remote that has its \"url = xmpp::loginname@xmppserver.com\" and its annex-uuid set to the annex.uuid of the repository on the first machine.
+3. Run git-annex assistant on the machine without the webapp.
+"""]]
diff --git a/doc/special_remotes/xmpp/comment_5_583ee374bd34fcc9ae26c2fd690e8c47._comment b/doc/special_remotes/xmpp/comment_5_583ee374bd34fcc9ae26c2fd690e8c47._comment
new file mode 100644
index 000000000..298c4392a
--- /dev/null
+++ b/doc/special_remotes/xmpp/comment_5_583ee374bd34fcc9ae26c2fd690e8c47._comment
@@ -0,0 +1,73 @@
+[[!comment format=mdwn
+ username="RaspberryPie"
+ ip="37.221.161.234"
+ subject="Nope"
+ date="2013-09-24T22:05:55Z"
+ content="""
+Your guess is right, Joey, I'm configuring by hand as the ARM machine has no webapp. And yes, I'm mostly sure I set up everything correctly. The XMPP account is working, and my configuration of git-annex is all but identical to your example.
+
+Here's what I do. First on the machine with the webapp:
+
+ mkdir ~/test
+ cd ~/test
+ git init
+ git annex init
+ git annex webapp
+
+I set up XMPP from within the webapp. The file ~/test/.git/annex/creds/xmpp is created with the correct credentials. (BTW: The file's default permissions are 620 instead of 600 - is that a bug?)
+
+I add a file or two to the annex for good measure. Then, on the ARM machine:
+
+ mkdir ~/test
+ cd ~/test
+ git init
+ git annex init
+ mkdir .git/annex/creds
+ scp -2 webappmachine:~/test/.git/annex/creds/xmpp .git/annex/creds
+ chmod 600 .git/annex/creds/xmpp
+ git remote add webappmachine xmpp::login@server
+
+The final step is to edit .git/config on the ARM machine. The [remote] section now looks like this:
+
+ [remote \"webappmachine\"]
+ url = xmpp::login@server
+ fetch = +refs/heads/*:refs/remotes/webappmachine/*
+ annex-uuid = aaaaaaaa-bbbb-cccc-dddddddddddd
+
+where aaaaaaaa-bbbb-cccc-dddddddddddd is the return value of `git config --get annex.uuid` on the webapp machine.
+
+I then run `git annex assistant` on the ARM machine and expect the two machines to synchronize their metadata, e.g. the number of knownn annex keys in the repo. But it doesn't happen.
+
+So I set `debug = true`, restart the assistants and check the log. This is what I get on the webapp machine:
+
+ [2013-09-24 17:45:41 EDT] XMPPClient: connected a5/25577ac4-3248-4c83-8391-bd93708bcf2b
+ [2013-09-24 17:45:41 EDT] XMPPClient: received: [\"Presence from a5/dc9bcde8-fe18-47de-807c-c620019279f2 Just (Element {elementName = Name {nameLocalName = \\"git-annex\\", nameNamespace = Just \\"git-annex\\", namePrefix = Nothing}, elementAttributes = [(Name {nameLocalName = \\"query\\", nameNamespace = Nothing, namePrefix = Nothing},[ContentText \\"\\"])], elementNodes = []})\",\"QueryPresence\"]
+ [2013-09-24 17:45:42 EDT] XMPPClient: received: [\"Presence from a5/900e3b6e-a7f4-4a6a-8d12-ed94de429258 Just (Element {elementName = Name {nameLocalName = \\"git-annex\\", nameNamespace = Just \\"git-annex\\", namePrefix = Nothing}, elementAttributes = [(Name {nameLocalName = \\"push\\", nameNamespace = Nothing, namePrefix = Nothing},[ContentText \\"43357474-abbb-4667-a334-e4615ea6d4a2\\"])], elementNodes = []})\",\"NotifyPush [UUID \\"43357474-abbb-4667-a334-e4615ea6d4a2\\"]\"]
+ [2013-09-24 17:45:42 EDT] XMPPClient: push notification for
+ [2013-09-24 17:45:42 EDT] read: git [\"--git-dir=/home/pi/test/.git\",\"--work-tree=/home/pi/test\",\"symbolic-ref\",\"HEAD\"]
+ [2013-09-24 17:45:42 EDT] read: git [\"--git-dir=/home/pi/test/.git\",\"--work-tree=/home/pi/test\",\"show-ref\",\"refs/heads/master\"]
+ [2013-09-24 17:45:42 EDT] XMPPClient: received: [\"Pushing \\"a59\\" (CanPush (UUID \\"d50c4cc9-e7c0-4ef0-84c6-f11012051eb9\\") [34f875cc7fa1198414f93990af9ab78e6cee893e,6fad42234060361435d6cf2ab4bd40e438c2d05c])\"]
+ [2013-09-24 17:45:42 EDT] read: git [\"--git-dir=/home/pi/test/.git\",\"--work-tree=/home/pi/test\",\"show-ref\",\"git-annex\"]
+ [2013-09-24 17:45:42 EDT] read: git [\"--git-dir=/home/pi/test/.git\",\"--work-tree=/home/pi/test\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+ [2013-09-24 17:45:42 EDT] read: git [\"--git-dir=/home/pi/test/.git\",\"--work-tree=/home/pi/test\",\"log\",\"refs/heads/git-annex..6fad42234060361435d6cf2ab4bd40e438c2d05c\",\"--oneline\",\"-n1\"]
+ [2013-09-24 17:45:42 EDT] chat: git [\"--git-dir=/home/pi/test/.git\",\"--work-tree=/home/pi/test\",\"cat-file\",\"--batch\"]
+ [2013-09-24 17:45:42 EDT] XMPPClient: received: [\"Ignorable Presence from a5/25577ac4-3248-4c83-8391-bd93708bcf2b Just (Element {elementName = Name {nameLocalName = \\"git-annex\\", nameNamespace = Just \\"git-annex\\", namePrefix = Nothing}, elementAttributes = [], elementNodes = []})\"]
+ [2013-09-24 17:45:42 EDT] XMPPClient: received: [\"Unknown message\"]
+ [2013-09-24 17:45:42 EDT] XMPPClient: received: [\"Pushing \\"a59\\" (PushRequest (UUID \\"d50c4cc9-e7c0-4ef0-84c6-f11012051eb9\\"))\"]
+ [2013-09-24 17:45:42 EDT] XMPPSendPack: started running push Pushing \"a59\" (PushRequest (UUID \"d50c4cc9-e7c0-4ef0-84c6-f11012051eb9\"))
+ [2013-09-24 17:45:42 EDT] read: git [\"--git-dir=/home/pi/test/.git\",\"--work-tree=/home/pi/test\",\"symbolic-ref\",\"HEAD\"]
+ [2013-09-24 17:45:42 EDT] XMPPClient: received: [\"Ignorable Presence from a5/25577ac4-3248-4c83-8391-bd93708bcf2b Just (Element {elementName = Name {nameLocalName = \\"git-annex\\", nameNamespace = Just \\"git-annex\\", namePrefix = Nothing}, elementAttributes = [], elementNodes = []})\"]
+ [2013-09-24 17:45:42 EDT] read: git [\"--git-dir=/home/pi/test/.git\",\"--work-tree=/home/pi/test\",\"show-ref\",\"refs/heads/master\"]
+ [2013-09-24 17:45:42 EDT] call: git [\"--git-dir=/home/pi/test/.git\",\"--work-tree=/home/pi/test\",\"branch\",\"-f\",\"synced/master\"]
+ [2013-09-24 17:45:42 EDT] XMPPSendPack: finished running push Pushing \"a59\" (PushRequest (UUID \"d50c4cc9-e7c0-4ef0-84c6-f11012051eb9\")) False
+
+And from then on, in two-minute intervals:
+
+ [2013-09-24 17:47:42 EDT] XMPPClient: received: [\"Unknown message\"]
+ [2013-09-24 17:49:42 EDT] XMPPClient: received: [\"Unknown message\"]
+ [2013-09-24 17:51:42 EDT] XMPPClient: received: [\"Unknown message\"]
+
+The log on the ARM machine is rather unhelpful. Actually it doesn't even contain the string \"XMPP\". This looks to me like the webapp machine tries to communicate via Jabber but doesn't get any intelligible answer. And this is the reason I wondered whether the problem lies with my self-compiled ARM git-annex binary. I actually spent a while compiling 4.20130909 with all flags but webapp and webdav, but the result is still the same.
+
+Any other ideas what I'm doing wrong here?
+"""]]
diff --git a/doc/special_remotes/xmpp/comment_6_8f0b5bba1271d031a67e7f0c175d67d5._comment b/doc/special_remotes/xmpp/comment_6_8f0b5bba1271d031a67e7f0c175d67d5._comment
new file mode 100644
index 000000000..750e0874a
--- /dev/null
+++ b/doc/special_remotes/xmpp/comment_6_8f0b5bba1271d031a67e7f0c175d67d5._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.220"
+ subject="comment 6"
+ date="2013-09-25T18:13:24Z"
+ content="""
+If you're not getting an \"XMPPClient: connected\", then my guess would be that your git-annex build's XMPP is screwed up somehow. For example, if it hung forever when connecting to the XMPP server, it would never get as far as printing that message. (If it tried and failed to connect, you'd get a message about the connection having failed.)
+"""]]
diff --git a/doc/special_remotes/xmpp/comment_7_ac7acbded03325b015959d82ae77faf1._comment b/doc/special_remotes/xmpp/comment_7_ac7acbded03325b015959d82ae77faf1._comment
new file mode 100644
index 000000000..0ad65336b
--- /dev/null
+++ b/doc/special_remotes/xmpp/comment_7_ac7acbded03325b015959d82ae77faf1._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="RaspberryPie"
+ ip="46.165.221.166"
+ subject="comment 7"
+ date="2013-09-26T03:46:18Z"
+ content="""
+I see. Is there a way to check whether the build is corrupt? The build logs gave me nothing.
+
+Anyway, XMPP is not the most important feature to me. It still bugs me though that it doesn't work when it should.
+"""]]
diff --git a/doc/special_remotes/xmpp/comment_8_81a9636a1e8a36a58185468a26f8633d._comment b/doc/special_remotes/xmpp/comment_8_81a9636a1e8a36a58185468a26f8633d._comment
new file mode 100644
index 000000000..79dd2892b
--- /dev/null
+++ b/doc/special_remotes/xmpp/comment_8_81a9636a1e8a36a58185468a26f8633d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnZEanlyzay_QlEAL0CWpyZcRTyN7vay8U"
+ nickname="Carlo"
+ subject="comment 8"
+ date="2013-10-22T14:30:58Z"
+ content="""
+Same setup, same problem... no log output on raspberry pi.
+"""]]
diff --git a/doc/special_remotes/xmpp/comment_9_eda76b826491c96b1ce072aacf9d3adf._comment b/doc/special_remotes/xmpp/comment_9_eda76b826491c96b1ce072aacf9d3adf._comment
new file mode 100644
index 000000000..3505f3aaf
--- /dev/null
+++ b/doc/special_remotes/xmpp/comment_9_eda76b826491c96b1ce072aacf9d3adf._comment
@@ -0,0 +1,23 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlu-fdXIt_RF9ggvg4zP0yBbtjWQwHAMS4"
+ nickname="Jörn"
+ subject="Same problem, no XMPP showing up in daemon.log"
+ date="2013-11-21T21:13:16Z"
+ content="""
+I have the same setup like @RaspberryPie, except that my server is not running on the Pi but on Debian7-amd64. On my client (OSX, self-compiled using cabal) I can see XMPP log entries like @RaspberryPi, however, on the Debian7 machine (also self-compiled) I do not see any XMPP entry in the daemon.log. Setup regarding .git/annex/creds/xmpp and the special xmpp remote is correct (checked a thousand times).
+
+Do you have any idea what could be wrong, Joey? Thanks a lot.
+
+Output of git annex version:
+
+ git-annex version: 5.20131120
+ build flags: Assistant Pairing Testsuite S3 WebDAV Inotify DBus XMPP DNS Feeds Quvi CryptoHash
+ key/value backends: SHA256E SHA1E SHA512E SHA224E SHA384E SKEIN256E SKEIN512E SHA256 SHA1 SHA512 SHA224 SHA384 SKEIN256 SKEIN512 WORM URL
+ remote types: git gcrypt S3 bup directory rsync web webdav glacier hook
+ local repository version: 4
+ default repository version: 3
+ supported repository versions: 3 5
+ upgrade supported from repository versions: 0 1 2 4
+
+Jörn
+"""]]
diff --git a/doc/summary.mdwn b/doc/summary.mdwn
new file mode 100644
index 000000000..be7b2cc2c
--- /dev/null
+++ b/doc/summary.mdwn
@@ -0,0 +1,11 @@
+git-annex allows managing files with git, without checking the file
+contents into git. While that may seem paradoxical, it is useful when
+dealing with files larger than git can currently easily handle, whether due
+to limitations in memory, time, or disk space.
+
+[[!img assistant/thumbnail.png link=assistant align=right]]
+git-annex is designed for git users who love the command line.
+For everyone else, the [[git-annex assistant|assistant]] turns
+git-annex into an easy to use folder synchroniser.
+
+To get a feel for git-annex, see the [[walkthrough]].
diff --git a/doc/sync.mdwn b/doc/sync.mdwn
new file mode 100644
index 000000000..37b2b1b45
--- /dev/null
+++ b/doc/sync.mdwn
@@ -0,0 +1,38 @@
+The `git annex sync` command provides an easy way to keep several
+repositories in sync.
+
+Often git is used in a centralized fashion with a central bare repository
+which changes are pulled and pushed to using normal git commands.
+That works fine, if you don't mind having a central repository.
+
+But it can be harder to use git in a fully decentralized fashion, with no
+central repository and still keep repositories in sync with one another.
+You have to remember to pull from each remote, and merge the appropriate
+branch after pulling. It's difficult to *push* to a remote, since git does
+not allow pushes into the currently checked out branch.
+
+`git annex sync` makes it easier using a scheme devised by Joachim
+Breitner. The idea is to have a branch `synced/master` (actually,
+`synced/$currentbranch`), that is never directly checked out, and serves
+as a drop-point for other repositories to use to push changes.
+
+When you run `git annex sync`, it merges the `synced/master` branch
+into `master`, receiving anything that's been pushed to it. (If there is a
+conflict in this merge, [[automatic_conflict_resolution]] is used to
+resolve it). Then it fetches from each remote, and merges in any changes that
+have been made to the remotes too. Finally, it updates `synced/master`
+to reflect the new state of `master`, and pushes it out to each of the remotes.
+
+This way, changes propagate around between repositories as `git annex sync`
+is run on each of them. Every repository does not need to be able to talk
+to every other repository; as long as the graph of repositories is
+connected, and `git annex sync` is run from time to time on each, a given
+change, made anywhere, will eventually reach every other repository.
+
+The workflow for using `git annex sync` is simple:
+
+* Make some changes to files in the repository, using `git-annex`,
+ or anything else.
+* Run `git annex sync` to save the changes.
+* Next time you're working on a different clone of that repository,
+ run `git annex sync` to update it.
diff --git a/doc/sync/comment_1_59681be5568f568f5c54eb0445163dd2._comment b/doc/sync/comment_1_59681be5568f568f5c54eb0445163dd2._comment
new file mode 100644
index 000000000..fa228c5ae
--- /dev/null
+++ b/doc/sync/comment_1_59681be5568f568f5c54eb0445163dd2._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://adamspiers.myopenid.com/"
+ nickname="Adam"
+ subject="very nice"
+ date="2012-02-25T15:02:18Z"
+ content="""
+Here's a way to get from a starting point of two or more peer directory trees *not* tracked by git or git-annex, to the point where they can be synced in the manner described above: [[forum/syncing_non-git_trees_with_git-annex/]]
+"""]]
diff --git a/doc/sync/comment_2_9301ff5e81d37475f594e74fbe32f24e._comment b/doc/sync/comment_2_9301ff5e81d37475f594e74fbe32f24e._comment
new file mode 100644
index 000000000..901bb41bd
--- /dev/null
+++ b/doc/sync/comment_2_9301ff5e81d37475f594e74fbe32f24e._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlDDW-g2WLLsLpcnCm4LykAquFY_nwbIrU"
+ nickname="Daniel"
+ subject="Its just grand"
+ date="2013-01-04T14:45:35Z"
+ content="""
+I cam upon git-annex a few months ago. I saw immidiately how it could help with some frustrations I've been having. One in particlar is keeping my vimrc in sync accross multiple locations and platforms. I finally took the time to give it a try after I finally hit my boiling point this morning. I went through the [walkthrough](http://git-annex.branchable.com/walkthrough/) and now I have an annax everywhere I need it. `git annex sync` and my vimrc is up-to-date, simply grand!
+
+Thanks so much for making git-annex,
+[Daniel Wozniak](http://woz.io)
+"""]]
diff --git a/doc/sync/comment_3_49560003da47490e4fabd4ab0089f2d7._comment b/doc/sync/comment_3_49560003da47490e4fabd4ab0089f2d7._comment
new file mode 100644
index 000000000..b3b45a1e4
--- /dev/null
+++ b/doc/sync/comment_3_49560003da47490e4fabd4ab0089f2d7._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnVX_teMpJeQkyheivad_1XSCFSjpiWgx8"
+ nickname="Diggory"
+ subject="synchronising stored files with a bare repository"
+ date="2013-01-11T16:52:38Z"
+ content="""
+Good for syncing indexes, but if I want to synchronise all data files too (specifically pushing to a remote bare repository), how do I do that?
+"""]]
diff --git a/doc/sync/comment_4_cf29326408e62575085d1f980087c923._comment b/doc/sync/comment_4_cf29326408e62575085d1f980087c923._comment
new file mode 100644
index 000000000..1ba0e61ad
--- /dev/null
+++ b/doc/sync/comment_4_cf29326408e62575085d1f980087c923._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.238"
+ subject="comment 4"
+ date="2013-01-11T18:18:07Z"
+ content="""
+Yes, sync only syncs the git branches, not git-annex data. To sync the date, you can run a command such as `git annex copy --to bareremote`. You could run that in cron. Or, the [[assistant]] can be run as a daemon, and automatically syncs git-annex data.
+"""]]
diff --git a/doc/sync/comment_5_18c396c59907147bb2bf713e55392b6b._comment b/doc/sync/comment_5_18c396c59907147bb2bf713e55392b6b._comment
new file mode 100644
index 000000000..dd7be6f45
--- /dev/null
+++ b/doc/sync/comment_5_18c396c59907147bb2bf713e55392b6b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://elmimmo.myopenid.com/"
+ nickname="chocolate.camera"
+ subject="How to sync content with git-annex, not assistant"
+ date="2013-10-11T09:58:12Z"
+ content="""
+Sure assistant can sync git-annex data across remotes. But how do I tell a repo to sync git-annex data, but not so manually as to having to know what exactly needs to be copied from/to where?
+"""]]
diff --git a/doc/sync/comment_6_012e9d4468d0b88ee3c5dad3911c3606._comment b/doc/sync/comment_6_012e9d4468d0b88ee3c5dad3911c3606._comment
new file mode 100644
index 000000000..24381237f
--- /dev/null
+++ b/doc/sync/comment_6_012e9d4468d0b88ee3c5dad3911c3606._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkI9AR8BqG4RPw_Ov2lnDCJWMuM6WMRobQ"
+ nickname="Dav"
+ subject="Syncing only a specific branch"
+ date="2013-11-24T17:48:22Z"
+ content="""
+By default, `git annex sync` will sync to all remotes, unless you specify a remote. So, I have to specify, e.g., `git annex sync origin`. I can simplify this with aliases, I suppose, but I do a lot of teaching non-programmer scientists... so it'd be nice to be able to configure this (so beginning users don't have to keep track of as many things).
+
+Is there (or will there be) a way to do this?
+"""]]
diff --git a/doc/sync/comment_7_6276e100d1341f1a0be368f54de0ae7b._comment b/doc/sync/comment_7_6276e100d1341f1a0be368f54de0ae7b._comment
new file mode 100644
index 000000000..c40a31200
--- /dev/null
+++ b/doc/sync/comment_7_6276e100d1341f1a0be368f54de0ae7b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.64"
+ subject="comment 7"
+ date="2013-11-26T20:08:33Z"
+ content="""
+I feel that syncing with all remotes by default is the right thing for git annex sync to do.
+"""]]
diff --git a/doc/templates/bare.tmpl b/doc/templates/bare.tmpl
new file mode 100644
index 000000000..2d476b716
--- /dev/null
+++ b/doc/templates/bare.tmpl
@@ -0,0 +1 @@
+<TMPL_VAR CONTENT>
diff --git a/doc/templates/bugtemplate.mdwn b/doc/templates/bugtemplate.mdwn
new file mode 100644
index 000000000..6214e8f74
--- /dev/null
+++ b/doc/templates/bugtemplate.mdwn
@@ -0,0 +1,18 @@
+### Please describe the problem.
+
+
+### What steps will reproduce the problem?
+
+
+### What version of git-annex are you using? On what operating system?
+
+
+### Please provide any additional information below.
+
+[[!format sh """
+# If you can, paste a complete transcript of the problem occurring here.
+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log
+
+
+# End of transcript or log.
+"""]]
diff --git a/doc/templates/walkthrough.tmpl b/doc/templates/walkthrough.tmpl
new file mode 100644
index 000000000..a500a5a86
--- /dev/null
+++ b/doc/templates/walkthrough.tmpl
@@ -0,0 +1,2 @@
+<h2><a href="<TMPL_VAR PAGEURL>"><TMPL_VAR TITLE></a></h2>
+<TMPL_VAR CONTENT>
diff --git a/doc/testimonials.mdwn b/doc/testimonials.mdwn
new file mode 100644
index 000000000..65fe8adce
--- /dev/null
+++ b/doc/testimonials.mdwn
@@ -0,0 +1,34 @@
+<div>
+<blockquote class="twitter-tweet"><p>Git annex. Brilliant. Powerful. <a href="http://t.co/AM9B6peM" title="http://git-annex.branchable.com/">git-annex.branchable.com</a></p>&mdash; Gert van Dijk (@gertvdijk) <a href="https://twitter.com/gertvdijk/status/186456474246053888" data-datetime="2012-04-01T14:14:22+00:00">April 1, 2012</a></blockquote>
+<script src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
+<blockquote class="twitter-tweet"><p>git-annex is like dropbox without the chrome. <a href="http://t.co/qcENNt3g" title="http://git-annex.branchable.com/">git-annex.branchable.com</a></p>&mdash; Wil Chung (@iamwil) <a href="https://twitter.com/iamwil/status/185997581229367296" data-datetime="2012-03-31T07:50:53+00:00">March 31, 2012</a></blockquote>
+<script src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
+<blockquote class="twitter-tweet"><p>blender 2.62 + ffmpeg + dnxhd + git-annex = who needs final cut?</p>&mdash; cdotwright (@cdotwright) <a href="https://twitter.com/cdotwright/status/187645142864375808" data-datetime="2012-04-04T20:57:42+00:00">April 4, 2012</a></blockquote>
+<script src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
+<blockquote class="twitter-tweet"><p>I want <a href="https://twitter.com/search/%2523git">#git</a>-annex whereis for all the stuff (not) in my room.</p>&mdash; topr (@derwelle) <a href="https://twitter.com/derwelle/status/172356564072673280" data-datetime="2012-02-22T16:26:21+00:00">February 22, 2012</a></blockquote>
+<script src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
+<blockquote class="twitter-tweet"><p>Git-annex now auto-syncing photos from my android phone to a Tor hidden SSH service I control (via <a href="https://twitter.com/guardianproject">@guardianproject</a>&#39;s Orbot) <a href="https://twitter.com/search?q=%23prismbreak&amp;src=hash">#prismbreak</a></p>&mdash; Richard King (@graphiclunarkid) <a href="https://twitter.com/graphiclunarkid/statuses/347658443479449601">June 20, 2013</a></blockquote>
+<script src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
+</div>
+
+<blockquote>
+What excites me about GIT ANNEX is how it fundamentally tracks the
+backup and availability of any data you own, and allows you to share
+data with a large or small audience, ensuring that the data survives.
+</blockquote>
+-- Jason Scott <http://ascii.textfiles.com/archives/3625>
+
+Seen on IRC:
+<pre>
+oh my god, git-annex is amazing
+this is the revolution in fucking with gigantic piles of files that I've been waiting for
+</pre>
+
+And then my own story: I have a ton of drives. I have a lot of servers. I
+live in a cabin on **dialup** and often have 1 hour on broadband in a week
+to get everything I need. Without git-annex, managing all this would not be
+possible. It works perfectly for me, not a surprise since I wrote it, but
+still, it's a different level of "perfect" than anything I could put
+together before. --[[Joey]]
+
+See also: [[design/assistant/blog/day_288__success_stories]]
diff --git a/doc/testimonials/comment_1_2bf439f7a3bc3d6fab91849017946182._comment b/doc/testimonials/comment_1_2bf439f7a3bc3d6fab91849017946182._comment
new file mode 100644
index 000000000..2c5facd1f
--- /dev/null
+++ b/doc/testimonials/comment_1_2bf439f7a3bc3d6fab91849017946182._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="gjost"
+ ip="108.205.152.179"
+ subject="distributed digital repository"
+ date="2013-11-14T00:39:49Z"
+ content="""
+I am in the process of building a distributed digital repository using Git and git-annex as a foundation. Our project is to collect and preserve archival-quality audio and video from multiple bandwidth-challenged remote sites. We're using git-annex to help us sneakernet the metadata and binaries around and to maintain multiple copies in geographically separate locations. Git very neatly addresses the problem of tracking changes, while git-annex makes it possible to track the flow of information through a network of distributed repositories.
+"""]]
diff --git a/doc/tips.mdwn b/doc/tips.mdwn
new file mode 100644
index 000000000..eda84c867
--- /dev/null
+++ b/doc/tips.mdwn
@@ -0,0 +1,4 @@
+This page is a place to document tips and techniques for using git-annex.
+
+[[!inline pages="tips/* and !tips/*/*" archive="yes"
+rootpage="tips" postformtext="Add a new tip about:" show=0]]
diff --git a/doc/tips/Building_git-annex_on_Debian_OR___37____164____35____34____164____37____38____34____35___Haskell__33__.mdwn b/doc/tips/Building_git-annex_on_Debian_OR___37____164____35____34____164____37____38____34____35___Haskell__33__.mdwn
new file mode 100644
index 000000000..c32eb966f
--- /dev/null
+++ b/doc/tips/Building_git-annex_on_Debian_OR___37____164____35____34____164____37____38____34____35___Haskell__33__.mdwn
@@ -0,0 +1,111 @@
+I've been wrestling with git-annex to try to make it build on Debian, or more specifically, wrestling with Haskell dependencies.
+
+After a fair amount of futzing around, and pestering a bunch of people in the process (thanks for the help! :) ) I finally managed to make it build.
+
+I figured I would post the steps here, since it's not completely trivial, and I expect that a few others might be interested in building newer versions as well.
+
+There appears to currently be two methods:
+
+* Debian packages on Wheezy plus Sid
+ * Starting out on Wheezy, and then picking the rest from Sid (it seems at least libghc-safesemaphore-dev from Sid is critical for newer git-annex)
+ * WebDAV suport will not be available with this method
+* Cabal packages
+
+
+#Debian packages on Wheezy plus Sid
+
+##Start off with a clean wheezy chroot
+
+ sudo debootstrap wheezy debian-wheezy
+ sudo chroot debian-wheezy
+
+##Install some build tools
+
+ apt-get update
+ apt-get install devscripts git
+
+##Get git-annex (either by cloning or simply moving the source into the chroot)
+
+ mkdir /src
+ cd /src
+ git clone git://git-annex.branchable.com/source.git git-annex
+ cd git-annex
+
+##Remove WebDAV dependency which can't be satisfied anywhere
+
+ sed '/libghc-dav-dev/d' -i debian/control
+
+##Create dummy build-depends package and install all available Wheezy dependencies using it
+
+ mk-build-deps
+ dpkg -i git-annex-build-deps*.deb
+ apt-get install -f
+
+(this will remove the build-depends package)
+
+##Add Sid sources and install all available Sid dependencies
+
+ echo "deb http://http.debian.net/debian sid main" >>/etc/apt/sources.list
+ apt-get update
+ dpkg -i git-annex-build-deps*.deb
+ apt-get install -f
+
+(the build-depends package should now be fully installed)
+
+##Disable the 'make test' that fails due to missing hothasktags
+
+ echo >>debian/rules
+ echo "override_dh_auto_test:" >>debian/rules
+
+##Build!
+
+ debuild -us -uc -Igit
+
+
+#Cabal packages
+
+##Start off with a clean Sid(/Wheezy) chroot
+
+ sudo debootstrap sid debian-sid
+ sudo chroot debian-sid
+
+##Install a smaller set of tools and build-depends from Debian (cabal needs these to compile the Haskell stuff)
+
+ apt-get update
+ apt-get install ghc cabal-install devscripts libz-dev pkg-config c2hs libgsasl7-dev libxml2-dev libgnutls-dev c2hs git debhelper ikiwiki perlmagick uuid rsync openssh-client fakeroot
+
+##Get git-annex (either by cloning or simply moving the source into the chroot)
+
+ mkdir /src
+ cd /src
+ git clone git://git-annex.branchable.com/source.git git-annex
+ cd git-annex
+
+##Install the Haskell build-dependencies from cabal
+
+ cabal update
+ cabal install --only-dependencies
+
+##Optional step which doesn't work (might in the future)
+If we want to run the 'make test' after build we need hothasktags, which is only available via cabal
+
+ apt-get install happy
+ cabal install hothasktags
+ export PATH=$PATH:~/.cabal/bin
+
+But this currently fails silently inside make test->fast->tags, and if you dig a bit (manually edit the makefile to be more verbose) you see
+
+ hothasktags: ./Command/AddUnused.hs: hGetContents: invalid argument (invalid byte sequence)
+
+##Disable the 'make test' that fails
+
+ echo >>debian/rules
+ echo "override_dh_auto_test:" >>debian/rules
+
+##Remove all Debian package haskell depends (taken care of by cabal instead)
+
+ sed '/\tlibghc/d' -i debian/control
+
+## Build!
+
+ debuild -us -uc -Igit
diff --git a/doc/tips/Building_git-annex_on_Debian_OR___37____164____35____34____164____37____38____34____35___Haskell__33__/comment_1_835a3608df3e9d044cabe822d0f3e7e4._comment b/doc/tips/Building_git-annex_on_Debian_OR___37____164____35____34____164____37____38____34____35___Haskell__33__/comment_1_835a3608df3e9d044cabe822d0f3e7e4._comment
new file mode 100644
index 000000000..55cf0b97b
--- /dev/null
+++ b/doc/tips/Building_git-annex_on_Debian_OR___37____164____35____34____164____37____38____34____35___Haskell__33__/comment_1_835a3608df3e9d044cabe822d0f3e7e4._comment
@@ -0,0 +1,27 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkCw26IdxXXPBoLcZsQFslM67OJSJynb1w"
+ nickname="Alexander"
+ subject="can't install git-annex on OS X Mountain Lion without disabling WebDAV support"
+ date="2013-04-29T17:57:03Z"
+ content="""
+possibly related to this Debian issue:
+
+trying to install git-annex with cabal on OS X 10.8.3, the build fails with
+
+
+ Loading package DAV-0.4 ... linking ... ghc:
+ lookupSymbol failed in relocateSection (relocate external)
+ ~/.cabal/lib/DAV-0.4/ghc-7.4.2/HSDAV-0.4.o: unknown symbol `_DAVzm0zi4_PathszuDAV_version1_closure'
+ ghc: unable to load package `DAV-0.4'
+ Failed to install git-annex-4.20130417
+ cabal: Error: some packages failed to install:
+ git-annex-4.20130417 failed during the building phase. The exception was:
+ ExitFailure 1
+
+
+This was after following all of the instructions for the Homebrew install at [http://git-annex.branchable.com/install/OSX/](http://git-annex.branchable.com/install/OSX/)
+I was able to work around this issue by installing with the WebDAV flag disabled (ie, added the option --flags=\"-WebDAV\" to last command in the OS X install instructions):
+
+ cabal install git-annex --bindir=$HOME/bin --flags=\"-WebDAV\"
+
+"""]]
diff --git a/doc/tips/Building_git-annex_on_Debian_OR___37____164____35____34____164____37____38____34____35___Haskell__33__/comment_2_080b30cba72a718e73ea715e259e1cfb._comment b/doc/tips/Building_git-annex_on_Debian_OR___37____164____35____34____164____37____38____34____35___Haskell__33__/comment_2_080b30cba72a718e73ea715e259e1cfb._comment
new file mode 100644
index 000000000..7e8e295fd
--- /dev/null
+++ b/doc/tips/Building_git-annex_on_Debian_OR___37____164____35____34____164____37____38____34____35___Haskell__33__/comment_2_080b30cba72a718e73ea715e259e1cfb._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-04-30T21:51:50Z"
+ content="""
+@Alexander that DAV-0.4 problem is a bug in DAV, not git-annex. I've informed its author and it should be fixed soon, in a new version of DAV.
+"""]]
diff --git a/doc/tips/Crude_Windows_Sync.mdwn b/doc/tips/Crude_Windows_Sync.mdwn
new file mode 100644
index 000000000..88138a0b1
--- /dev/null
+++ b/doc/tips/Crude_Windows_Sync.mdwn
@@ -0,0 +1,35 @@
+Here's a workaround to start syncing folders on Windows right now. It's a bit command line heavy, so you might need to set this up for your users. But I would much rather do this than use some other syncing solution and then have to migrate.
+
+(1) Create a remote server git annex repository with the assistant on Linux or Mac.
+
+(2) [Install git](http://git-scm.com/) on the Windows machine.
+
+(3) [Install git-annex for Windows](http://git-annex.branchable.com/install/Windows/) on the Windows machine. Don't forget to run the installer as administrator.
+
+(4) Run _Git Bash_ from the system menu, and run these commands to clone your repository.
+
+ ssh-keygen
+ cat .ssh/id_rsa.pub | ssh username@my-server.com "cat >> ~/.ssh/authorized_keys"
+ git clone username@my-server.com:/path/to/annex
+ cd annex
+ git annex init
+
+(5) Create a script that will trigger a full sync
+
+ echo '
+ #!/bin/bash
+ git annex sync
+ git annex get *
+ git annex add .
+ git annex sync
+ git annex copy * --to origin
+ ' > sync.sh
+ chmod +x sync.sh
+ ./sync.sh
+
+(6) Copy the "Git Bash" shortcut from your windows menu to your desktop, and change the link target to:
+
+ C:\Program Files\Git\bin\sh.exe" --login -i "annex/sync.sh"
+
+Now ask your users to run this shortcut before and after they change files. You can also put it into the "autostart" folder to sync at boot.
+
diff --git a/doc/tips/Decentralized_repository_behind_a_Firewall.mdwn b/doc/tips/Decentralized_repository_behind_a_Firewall.mdwn
new file mode 100644
index 000000000..9e347c73f
--- /dev/null
+++ b/doc/tips/Decentralized_repository_behind_a_Firewall.mdwn
@@ -0,0 +1,59 @@
+If you're anything like me¹, you have a copy of your annex on a computer running at home², set up so you can access it from anywhere like this:
+
+ ssh myhome.no-ip.org
+
+This is totally great! Except, there is no way for your home computer to pull your changes, because there is no *on-the-go.no-ip.org*. You can get clunky and use a *bare git repository and git push*, but there is a better way.
+
+First, install *openssh-server* on your *on-the-go* computer
+
+ sudo apt-get install openssh-server # Adjust to your flavor of unix
+
+Then, log into your *home* computer, with *port forwarding*:
+
+ ssh me@myhome.no-ip.org -R 2201:localhost:22
+
+Your *home* computer can now ssh into your *on-the-go* computer, as long as you keep the above shell running.
+
+You can now add your *on-the-go* computer as a remote on your *home* computer. Use the port forwarding shell you just connected with the command above, if you like.
+
+ ssh-keygen -t rsa
+ ssh-copy-id "me@localhost -p 2201"
+ cd ~/annex
+ git remote add on-the-go ssh://me@localhost:2201/home/myuser/annex
+
+Now you can run normal annex operations, as long as the port forwarding shell is running³.
+
+ git annex sync
+ git annex get on-the-go some/big/file
+ git annex info
+
+You can add more computers by repeating with a different port, e.g. 2202 or 2203 (or any other).
+
+If you're security paranoid (like me), read on. If you're not, that's it! Thanks for reading!
+
+---
+Paranoid Area
+
+Note you're granting passwordless access to your on-the-go computer to your home computer. I believe that's all right, as long as:
+
+* Your home computer is really in your home, and not at a friend's house or some datacenter
+* Your home computer can be accessed only by ssh, and not HTTP or Samba or NTP or (shoot me now!) FTP
+* Only you (and perhaps trustworthy family) have access to your home computer
+* You have reasonably strong passwords or key-only logins on both your home and on-the-go computers.
+* You regularly install security updates on both computers (sudo apt-get update && sudo apt-get upgrade)
+
+In any case, the setup is much, much, much more secure than Dropbox. With Dropbox, you have exactly the same setup, but:
+
+* Your data is stored in some datacenter. It's supposed to be encrypted. It might not be.
+* Lot's of people have routine access to your files, and plausible reason to. Bored employees might regularly be doing some 'maintenance work' involving your pictures.
+* The dropbox software can do anything it likes on your computer, and it's closed source so you don't know if it does. A disgruntled employee could put a trojan into it.
+* Dropbox might have a backdoor for employee access to any file on your computer. This might be done with the best of intentions, but a mal-intentioned or careless employee might still erase things or send sensitive files from your computer by email.
+* A truly huge amount of eyes connected to incredibly smart brains have looked at openssh and found it secure. Everybody trusts openssh. With dropbox, there is, well, dropbox. Whoever that is.
+
+-----
+
+¹ Me=Carlo, not Joey. I'm pretty sure doing what I wrote here is a good idea, but in case it turns out to be catastrophically dumb, it's my fault, not his.
+
+² My always-on computer at home is a raspberry pi with a 32GB USB stick. Best self-hosted dropbox you could imagine.
+
+³ You can just forward the port, but not open a shell, by adding the -N command. This could be useful for connecting on startup, e.g. in /etc/rc.local. I prefer to open the shell to forward the ports, maybe use it, and close it to stop it.
diff --git a/doc/tips/Decentralized_repository_behind_a_Firewall/comment_1_78b9035234a690ca5a7c9f3cc78fa092._comment b/doc/tips/Decentralized_repository_behind_a_Firewall/comment_1_78b9035234a690ca5a7c9f3cc78fa092._comment
new file mode 100644
index 000000000..71a1db9c8
--- /dev/null
+++ b/doc/tips/Decentralized_repository_behind_a_Firewall/comment_1_78b9035234a690ca5a7c9f3cc78fa092._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.49"
+ subject="comment 1"
+ date="2012-11-30T16:25:58Z"
+ content="""
+If you don't trust your home computer with shell access, you can lock it down in `.ssh/authorized_keys` to only be able to run git-annex-shell. See [[forum/Restricting_git-annex-shell_to_a_specific_repository]]
+"""]]
diff --git a/doc/tips/Delay_Assistant_Startup_on_Login.mdwn b/doc/tips/Delay_Assistant_Startup_on_Login.mdwn
new file mode 100644
index 000000000..74652308a
--- /dev/null
+++ b/doc/tips/Delay_Assistant_Startup_on_Login.mdwn
@@ -0,0 +1,13 @@
+# Problem
+I noticed that after installing git-annex assistant, my start up times greatly increased because the assistant does a startup scan while everything else is loading.
+# Solution (for people using Gnome)
+The solution I came up with is to delay the assistant's startup, as well as setting its IO priority as idle. To do this in Gnome 3, run:
+
+ gnome-session-properties
+Find the "Git Annex Assistant" entry in the Startup Programs tab, then click edit. Change this:
+
+ /usr/local/bin/git-annex assistant --autostart (your location of git-annex may be different)
+to this:
+
+ bash -c "sleep 30; ionice -c3 /usr/local/bin/git-annex assistant --autostart" (replace /usr/local/bin to wherever git-annex is installed)
+The "sleep 30" command delays the startup of the assistant by 30 seconds, and "ionice -c3" sets git-annex's IO priority to "idle," the lowest level.
diff --git a/doc/tips/Delay_Assistant_Startup_on_Login/comment_1_c63917150527efab4b1106183b3aa7ef._comment b/doc/tips/Delay_Assistant_Startup_on_Login/comment_1_c63917150527efab4b1106183b3aa7ef._comment
new file mode 100644
index 000000000..fe8cb80ba
--- /dev/null
+++ b/doc/tips/Delay_Assistant_Startup_on_Login/comment_1_c63917150527efab4b1106183b3aa7ef._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://launchpad.net/~alphapapa"
+ nickname="alphapapa"
+ subject="ionice not supported by deadline scheduler"
+ date="2013-06-28T17:43:47Z"
+ content="""
+Linux's deadline I/O scheduler does not support ionice. It is now the default on some distros, including Ubuntu. CFQ does support ionice.
+"""]]
diff --git a/doc/tips/Git_annex_and_Calibre.mdwn b/doc/tips/Git_annex_and_Calibre.mdwn
new file mode 100644
index 000000000..71f955656
--- /dev/null
+++ b/doc/tips/Git_annex_and_Calibre.mdwn
@@ -0,0 +1,120 @@
+The problem
+===========
+
+[Calibre](http://calibre-ebook.com/) is a ebook manager that is
+available in [debian](http://packages.debian.org/sid/calibre). I use
+it to maintain my library, but also to dowload every day an epub
+version of a French newspaper and then put it on my kobo.
+
+Configuring git annex for this
+==============================
+
+I wanted to use git-annex, so
+
+ $ git init
+ $ git annex init "some useful name"
+
+But I don't want every thing in annex, because Calibre use some text
+file to save some metadata, so I used:
+
+ $ git config annex.largefiles "include=* exclude=*.opf exclude=*.json"
+
+then lets add everything
+
+ $ git annex add *
+ $ git add *
+ $ git commit -m "first commit"
+
+Calibre need read and write access on the its database, so let unlock it:
+
+ $ git annex unlock metadata.db
+
+On my other computer I only need to do
+
+ $ git clone $user@$host:Calibre\ library
+ $ cd Calibre\ library
+ $ git annex init "another useful name"
+ $ git annex get .
+ $ git annex unlock metadata.db
+
+The problem is that every time you will `git annex sync`, git annex
+will lock again the metadata.db, so lets unlock it automatically. I
+use git hooks, in `.git/hooks/post-commit` I have
+
+ #!/bin/bash
+
+ git annex edit metadata.db
+
+don't forget to make this file executable
+
+ $ chmod a+x .git/hooks/post-commit
+
+Day to day operation
+====================
+
+ $ git annex add .
+
+Will put new file into the annex
+
+ $ git add .
+
+Will take care of the files that should no go into annex
+
+ $ git annex sync
+
+Will make the repositories exchange informations about all this, and
+make remote change local
+
+ $ git annex get .
+
+Will make remote book locally available
+
+Merge conflict
+--------------
+You should not run calibre on the two computer simultaneously, or
+without syncing before it. If you do, you will have a conflict that
+git-annex will automatically *solve* by rename both of the file.
+
+You can then either:
+
+ - Choose one. If no books have been changed or added on one of the
+ computer, to use the other `metadata.db` will not make you loose
+ any information
+ - rebuild it. `calibredb restore_database` won't do it, but will tell
+ you how to do it.
+
+Checking the library
+--------------------
+You can use `calibredb check_library` to check you library is
+correct. If you use git for it, it will always tell you that it is not
+correct: there is this author ".git" it doesn't know about. Just don't
+care about it.
+
+Maybe this can be solved by using `vcsh` but apparently
+`vcsh`+`git annex` it not well tested yet.
+
+Automatic stuff
+---------------
+I use `mr` to automatically run all this, but some config could be
+done (I believe) to have `git annex copy --auto` do what it should.
+
+There are also the git annex assistant for this kind of automatic
+synchronizations of contents, but I don't know if my automatic
+unlocking of one file will break this.
+
+It might be interesting to find someway to unlock and lock the library
+only when running calibre, a simple script to launch calibre will do
+that. Note that each time you will lock and unlock, you will have a
+new commit in git.
+
+Another solution
+===================
+You could also use direct mode in place of the auto unlock feature
+
+ git annex direct
+
+The remove the `post-commit` git hook (or do not add it). Its a
+simpler solution, but remember that interaction between git annex direct
+repositories and plain git are complex and sometimes downright dangerous. See [[direct mode]] for details.
+
+In particular, do *not* called `git add *` in the above steps, as that will commit all books into git.
diff --git a/doc/tips/How_to_retroactively_annex_a_file_already_in_a_git_repo.mdwn b/doc/tips/How_to_retroactively_annex_a_file_already_in_a_git_repo.mdwn
new file mode 100644
index 000000000..97f5828d3
--- /dev/null
+++ b/doc/tips/How_to_retroactively_annex_a_file_already_in_a_git_repo.mdwn
@@ -0,0 +1,19 @@
+I worked out how to retroactively annex a large file that had been checked into a git repo some time ago. I thought this might be useful for others, so I am posting it here.
+
+Suppose you have a git repo where somebody had checked in a large file you would like to have annexed, but there are a bunch of commits after it and you don't want to loose history, but you also don't want everybody to have to retrieve the large file when they clone the repo. This will re-write history as if the file had been annexed when it was originally added.
+
+This command works for me, it relies on the current behavior of git which is to use a directory named .git-rewrite/t/ at the top of the git tree for the extracted tree. This will not be fast and it will rewrite history, so be sure that everybody who has a copy of your repo is OK with accepting the new history. If the behavior of git changes, you can specify the directory to use with the -d option. Currently, the t/ directory is created inside the directory you specify, so "-d ./.git-rewrite/" should be roughly equivalent to the default.
+
+Enough with the explanation, on to the command:
+<pre>
+git filter-branch --tree-filter 'for FILE in file1 file2 file3;do if [ -f "$FILE" ] && [ ! -L "$FILE" ];then git rm --cached "$FILE";git annex add "$FILE";ln -sf `readlink "$FILE"|sed -e "s:^../../::"` "$FILE";fi;done' --tag-name-filter cat -- --all
+</pre>
+
+replace file1 file2 file3... with whatever paths you want retroactively annexed. If you wanted bigfile1.bin in the top dir and subdir1/bigfile2.bin to be retroactively annexed try:
+<pre>
+git filter-branch --tree-filter 'for FILE in bigfile1.bin subdir1/bigfile2.bin;do if [ -f "$FILE" ] && [ ! -L "$FILE" ];then git rm --cached "$FILE";git annex add "$FILE";ln -sf `readlink "$FILE"|sed -e "s:^../../::"` "$FILE";fi;done' --tag-name-filter cat -- --all
+</pre>
+
+**If your repo has tags** then you should take a look at the git-filter-branch man page about the --tag-name-filter option and decide what you want to do. By default this will re-write the tags "nearly properly".
+
+You'll probably also want to look at the git-filter-branch man page's section titled "CHECKLIST FOR SHRINKING A REPOSITORY" if you want to free up the space in the existing repo that you just changed history on.
diff --git a/doc/tips/How_to_retroactively_annex_a_file_already_in_a_git_repo/comment_1_7eaf73fb3355bd706ab18a43790b3c10._comment b/doc/tips/How_to_retroactively_annex_a_file_already_in_a_git_repo/comment_1_7eaf73fb3355bd706ab18a43790b3c10._comment
new file mode 100644
index 000000000..d4e34e8cd
--- /dev/null
+++ b/doc/tips/How_to_retroactively_annex_a_file_already_in_a_git_repo/comment_1_7eaf73fb3355bd706ab18a43790b3c10._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 1"
+ date="2012-12-16T00:11:38Z"
+ content="""
+Man, I wish you'd written this a couple weeks ago. :) I was never able to figure that incantation out and ended up unannexing and re-annexing the whole thing to get rid of the file I inadvertently checked into git instead of the annex.
+"""]]
diff --git a/doc/tips/How_to_retroactively_annex_a_file_already_in_a_git_repo/comment_2_dac1a171204f30d7c906e878eb6bd461._comment b/doc/tips/How_to_retroactively_annex_a_file_already_in_a_git_repo/comment_2_dac1a171204f30d7c906e878eb6bd461._comment
new file mode 100644
index 000000000..a3ea62385
--- /dev/null
+++ b/doc/tips/How_to_retroactively_annex_a_file_already_in_a_git_repo/comment_2_dac1a171204f30d7c906e878eb6bd461._comment
@@ -0,0 +1,45 @@
+[[!comment format=mdwn
+ username="https://launchpad.net/~arand"
+ nickname="arand"
+ subject="comment 2"
+ date="2013-03-13T12:05:49Z"
+ content="""
+Based on the hints given here I've worked on a filter to both annex and add urls via filter-branch:
+
+[https://gitorious.org/arand-scripts/arand-scripts/blobs/master/annex-filter](https://gitorious.org/arand-scripts/arand-scripts/blobs/master/annex-filter)
+
+The script above is very specific but I think there are a few ideas that can be used in general, the general structure is
+
+ #!/bin/bash
+
+ # links that already exist
+ links=$(mktemp)
+ find . -type l >\"$links\"
+
+ # remove from staging area first to not block and then annex
+ git rm --cached --ignore-unmatch -r bin*
+ git annex add -c annex.alwayscommit=false bin*
+
+ # compare links before and after annexing, remove links that existed before
+ newlinks=$(mktemp -u)
+ mkfifo \"$newlinks\"
+ comm -13 <(sort \"$links\") <(find . -type l | sort) > \"$newlinks\" &
+
+ # rewrite links
+ while IFS= read -r file
+ do
+ # link is created below .git-rewrite/t/ during filter-branch, strip two parents for correct target
+ ln -sf \"$(readlink \"$file\" | sed -e 's%^\.\./\.\./%%')\" \"$file\"
+ done < \"$newlinks\"
+
+ git annex merge
+
+which would be run using
+
+ git filter-branch --tree-filter path/annex-filter --tag-filter cat -- --all
+
+or similar.
+
+* I'm using `find` to make sure the only rewritten symlinks are for the newly annexed files, this way it is possible to annex an unknown set of filenames
+* If doing several git annex commands using `-c annex.alwayscommit=false` and doing a `git annex merge` at the end instead might be faster.
+"""]]
diff --git a/doc/tips/How_to_retroactively_annex_a_file_already_in_a_git_repo/comment_3_b62ec0b848d2487d68d7032682622193._comment b/doc/tips/How_to_retroactively_annex_a_file_already_in_a_git_repo/comment_3_b62ec0b848d2487d68d7032682622193._comment
new file mode 100644
index 000000000..9b8aa58f8
--- /dev/null
+++ b/doc/tips/How_to_retroactively_annex_a_file_already_in_a_git_repo/comment_3_b62ec0b848d2487d68d7032682622193._comment
@@ -0,0 +1,36 @@
+[[!comment format=mdwn
+ username="arand"
+ ip="130.238.245.202"
+ subject="comment 3"
+ date="2013-03-18T14:39:52Z"
+ content="""
+One thing I noticed is that git-annex needs to checksum each file even if they were previously annexed (rather obviously since there is no general way to tell if the file is the same as the old one without checksumming), but in the specific case that we are replacing files that are already in git, we do actually have the sha1 checksum for each file in question, which could be used.
+
+So, trying to work with this, I wrote a filter script that starts out annexing stuff in the first commit, and continously writes out sha1<->filename<->git-annex-object triplets to a global file, when it then starts with the next commit, it compares the sha1s of the index with those of the global file, and any matches are manually symlinked directly to the corresponding git-annex-object without checksumming.
+
+I've done a few tests and this seems to be considerably faster than letting git-annex checksum everything.
+
+This is from a git-svn import of the (free software) Red Eclipse game project, there are approximately 3500 files (images, maps, models, etc.) being annexed in each commit (and around 5300 commits, hence why I really, really care about speed):
+
+10 commits: ~7min
+
+100 commits: ~38min
+
+For comparison, the old and new method (the difference should increase with the amount of commits):
+
+old, 20 commits ~32min
+
+new, 20 commits: ~11min
+
+The script itself is a bit of a monstrosity in bash(/grep/sed/awk/git), and the files that are annexed are hardcoded (removed in forming $oldindexfiles), but should be fairly easy to adapt:
+
+[https://gitorious.org/arand-scripts/arand-scripts/blobs/master/annex-ffilter](https://gitorious.org/arand-scripts/arand-scripts/blobs/master/annex-ffilter)
+
+The usage would be something like:
+
+ rm /tmp/annex-ffilter.log; git filter-branch --tree-filter 'ANNEX_FFILTER_LOG=/tmp/annex-ffilter.log ~/utv/scripts/annex-ffilter' --tag-name-filter cat -- branchname
+
+I suggest you use it with at least two orders of magnitude more caution than normal filter-branch.
+
+Hope it might be useful for someone else wrestling with filter-branch and git-annex :)
+"""]]
diff --git a/doc/tips/How_to_retroactively_annex_a_file_already_in_a_git_repo/comment_4_2423904e41a86cd1c6bc155d7b733642._comment b/doc/tips/How_to_retroactively_annex_a_file_already_in_a_git_repo/comment_4_2423904e41a86cd1c6bc155d7b733642._comment
new file mode 100644
index 000000000..ab1d4e006
--- /dev/null
+++ b/doc/tips/How_to_retroactively_annex_a_file_already_in_a_git_repo/comment_4_2423904e41a86cd1c6bc155d7b733642._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawknOATcOkmzX4jKuET5Z2RsaFUNnLKnQsU"
+ nickname="Stephen"
+ subject="comment 4"
+ date="2013-06-22T07:43:09Z"
+ content="""
+Thanks for the tip :) One question though: how do I push this new history out throughout my other Annexes?
+All I managed to make it do was revert the rewrite so the raw file appeared again...
+"""]]
diff --git a/doc/tips/Internet_Archive_via_S3.mdwn b/doc/tips/Internet_Archive_via_S3.mdwn
new file mode 100644
index 000000000..eba28961d
--- /dev/null
+++ b/doc/tips/Internet_Archive_via_S3.mdwn
@@ -0,0 +1,58 @@
+[The Internet Archive](http://www.archive.org/) allows members to upload
+collections using an Amazon S3
+[compatible API](http://www.archive.org/help/abouts3.txt), and this can
+be used with git-annex's [[special_remotes/S3]] support.
+
+So, you can locally archive things with git-annex, define remotes that
+correspond to "items" at the Internet Archive, and use git-annex to upload
+your files to there. Of course, your use of the Internet Archive must
+comply with their [terms of service](http://www.archive.org/about/terms.php).
+
+A nice added feature is that whenever git-annex sends a file to the
+Internet Archive, it records its url, the same as if you'd run `git annex
+addurl`. So any users who can clone your repository can download the files
+from archive.org, without needing any login or password info. This makes
+the Internet Archive a nice way to publish the large files associated with
+a public git repository.
+
+----
+
+Sign up for an account, and get your access keys here:
+<http://www.archive.org/account/s3.php>
+
+ # export AWS_ACCESS_KEY_ID=blahblah
+ # export AWS_SECRET_ACCESS_KEY=xxxxxxx
+
+Specify `host=s3.us.archive.org` when doing `initremote` to set up
+a remote at the Archive. This will enable a special Internet Archive mode:
+Encryption is not allowed; you are required to specify a bucket name
+rather than having git-annex pick a random one; and you can optionally
+specify `x-archive-meta*` headers to add metadata as explained in their
+[documentation](http://www.archive.org/help/abouts3.txt).
+
+ # git annex initremote archive-panama type=S3 \
+ host=s3.us.archive.org bucket=panama-canal-lock-blueprints \
+ x-archive-meta-mediatype=texts x-archive-meta-language=eng \
+ x-archive-meta-title="original Panama Canal lock design blueprints"
+ initremote archive-panama (Internet Archive mode) ok
+ # git annex describe archive-panama "a man, a plan, a canal: panama"
+ describe archive-panama ok
+
+Then you can annex files and copy them to the remote as usual:
+
+ # git annex add photo1.jpeg --backend=SHA1E
+ add photo1.jpeg (checksum...) ok
+ # git annex copy photo1.jpeg --fast --to archive-panama
+ copy (to archive-panama...) ok
+
+Once a file has been stored on archive.org, it cannot be (easily) removed
+from it. Also, git-annex whereis will tell you a public url for the file
+on archive.org. (It may take a while for archive.org to make the file
+publically visibile.)
+
+Note the use of the SHA1E [[backend|backends]] when adding files. That is
+the default backend used by git-annex, but even if you don't normally use
+it, it makes most sense to use the WORM or SHA1E backend for files that
+will be stored in the Internet Archive, since the key name will be exposed
+as the filename there, and since the Archive does special processing of
+files based on their extension.
diff --git a/doc/tips/Internet_Archive_via_S3/comment_1_d53a3848c20dce61867283fc03c2adaa._comment b/doc/tips/Internet_Archive_via_S3/comment_1_d53a3848c20dce61867283fc03c2adaa._comment
new file mode 100644
index 000000000..7c2ce48fc
--- /dev/null
+++ b/doc/tips/Internet_Archive_via_S3/comment_1_d53a3848c20dce61867283fc03c2adaa._comment
@@ -0,0 +1,34 @@
+[[!comment format=mdwn
+ username="https://id.koumbit.net/anarcat"
+ ip="72.0.72.144"
+ subject="how to use with simply addurl?"
+ date="2013-10-09T22:27:27Z"
+ content="""
+It doesn't seem like git annex addurl by itself supports the archive.org urls...
+
+[[!format txt \"\"\"
+anarcat@marcos:presentations$ git annex addurl --file=re_publica_2012___Eben_Moglen___Freedom_of_Thought_Requires_Free_Media.webm http://archive.org/download/Republica2012-EbenMoglen-FreedomOfThoughtRequiresFreeMedia/re_publica_2012___Eben_Moglen___Freedom_of_Thought_Requires_Free_Media.webm
+addurl re_publica_2012___Eben_Moglen___Freedom_of_Thought_Requires_Free_Media.webm
+ failed to verify url exists: http://archive.org/download/Republica2012-EbenMoglen-FreedomOfThoughtRequiresFreeMedia/re_publica_2012___Eben_Moglen___Freedom_of_Thought_Requires_Free_Media.webm
+failed
+git-annex: addurl: 1 failed
+\"\"\"]]
+
+I also tried the \"details\" url (<http://archive.org/details/Republica2012-EbenMoglen-FreedomOfThoughtRequiresFreeMedia>) - but that just downloads the webpage, not the video either...
+
+Even the ultimate video URL doesn't work:
+
+[[!format txt \"\"\"
+anarcat@marcos:presentations$ git annex addurl --debug --file=re_publica_2012___Eben_Moglen___Freedom_of_Thought_Requires_Free_Media.webm http://ia601009.us.archive.org/9/items/Republica2012-EbenMoglen-FreedomOfThoughtRequiresFreeMedia/re_publica_2012___Eben_Moglen___Freedom_of_Thought_Requires_Free_Media.webm
+[2013-10-09 18:26:30 EDT] call: quvi [\"-v\",\"mute\",\"--support\",\"http://ia601009.us.archive.org/9/items/Republica2012-EbenMoglen-FreedomOfThoughtRequiresFreeMedia/re_publica_2012___Eben_Moglen___Freedom_of_Thought_Requires_Free_Media.webm\"]
+addurl re_publica_2012___Eben_Moglen___Freedom_of_Thought_Requires_Free_Media.webm [2013-10-09 18:26:30 EDT] read: curl [\"-s\",\"--head\",\"-L\",\"http://ia601009.us.archive.org/9/items/Republica2012-EbenMoglen-FreedomOfThoughtRequiresFreeMedia/re_publica_2012___Eben_Moglen___Freedom_of_Thought_Requires_Free_Media.webm\",\"-w\",\"%{http_code}\"]
+
+ failed to verify url exists: http://ia601009.us.archive.org/9/items/Republica2012-EbenMoglen-FreedomOfThoughtRequiresFreeMedia/re_publica_2012___Eben_Moglen___Freedom_of_Thought_Requires_Free_Media.webm
+failed
+git-annex: addurl: 1 failed
+\"\"\"]]
+
+... even though that URL actually gives out a proper 200 OK response code.
+
+Any ideas? --[[anarcat]]
+"""]]
diff --git a/doc/tips/Internet_Archive_via_S3/comment_2_91c1472da27b00e5d682d22bc1ef04e0._comment b/doc/tips/Internet_Archive_via_S3/comment_2_91c1472da27b00e5d682d22bc1ef04e0._comment
new file mode 100644
index 000000000..9b4ac58b2
--- /dev/null
+++ b/doc/tips/Internet_Archive_via_S3/comment_2_91c1472da27b00e5d682d22bc1ef04e0._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.22"
+ subject="comment 2"
+ date="2013-10-11T17:08:27Z"
+ content="""
+This was a misleading error message. The url you are trying to add to the file does not match the size recorded for the file already in the annex. (Or possibly the file's key has no recorded size). If you really want to add the url to the file despite it being a different encoding, you can use --relaxed, although fsck may not like the result if you ever end up downloading that url..
+
+(Please file bug reports for problems in the future, rather than posting comments on only vaguely related pages which as we can see here can turn out to be entirely offtopic.)
+"""]]
diff --git a/doc/tips/Internet_Archive_via_S3/comment_3_e23cf781c532f80d47d52265f2b2c87e._comment b/doc/tips/Internet_Archive_via_S3/comment_3_e23cf781c532f80d47d52265f2b2c87e._comment
new file mode 100644
index 000000000..3745d544c
--- /dev/null
+++ b/doc/tips/Internet_Archive_via_S3/comment_3_e23cf781c532f80d47d52265f2b2c87e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://id.koumbit.net/anarcat"
+ ip="72.0.72.144"
+ subject="still a bug, filed separately!"
+ date="2013-10-11T18:49:06Z"
+ content="""
+Aaah, of course, sorry for the noise here. It turns out that this is *not* because the filesize (or even the checksum, for that matter) are different, so there's clearly a bug there, and i filed it in [[bugs/addurl_fails_on_the_internet_archive]]. Thanks!
+"""]]
diff --git a/doc/tips/The_perfect_preferred_content_settings_for_my_android_phone.mdwn b/doc/tips/The_perfect_preferred_content_settings_for_my_android_phone.mdwn
new file mode 100644
index 000000000..1afac15d5
--- /dev/null
+++ b/doc/tips/The_perfect_preferred_content_settings_for_my_android_phone.mdwn
@@ -0,0 +1,32 @@
+I have an annex that syncs my personal files on all my computers. It works great. Phones are different.
+
+For one, everything's a bit slower to sync, there's battery considerations, and I just don't need every last old file on my phone. Then there's some files I explicitly don't want on my phone in case it gets lost, like family pictures, passport scans, or private keys.
+
+But I still want photos, videos and voice recordings I make on my phone to be synced to my server. A transfer repo would work, but I want to keep them. Then there's my PDF book collection; that would certainly be nice to always have around in case I have half on hour on a bus. And my music collection ought to be around as well.
+
+So I came up with this solution, and I'm very happy with it.
+
+ include=Music/* or include=Books/* or present
+
+This will sync my music and book collections to my phone whenever I add something new on my computers, and it will sync and keep anything I add to the annex on my phone. Best of all worlds! Impressed how flexible preferred content is. More full-sync folders can be added like this:
+
+ include=Music/* or include=Books/* or Notes/* or present
+
+To add them, I first had to figure out the uuid of my phone repo. So I added a new tab on android, and did
+
+ cd /sdcard/annex
+ git config annex.uuid
+
+Then I went to one of my computers, and did
+
+ git annex vicfg
+
+And changed the line
+
+ content [phone-uuid] = standard
+
+to
+
+ content [phone-uuid] = include=Music/* or include=Books/* or Notes/* or present
+
+And waited for it to sync.
diff --git a/doc/tips/The_perfect_preferred_content_settings_for_my_android_phone/comment_1_393d1636bb313530be383a075bd3440a._comment b/doc/tips/The_perfect_preferred_content_settings_for_my_android_phone/comment_1_393d1636bb313530be383a075bd3440a._comment
new file mode 100644
index 000000000..8938684f8
--- /dev/null
+++ b/doc/tips/The_perfect_preferred_content_settings_for_my_android_phone/comment_1_393d1636bb313530be383a075bd3440a._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.246"
+ subject="comment 1"
+ date="2013-11-16T17:29:03Z"
+ content="""
+That's great, that's how I hoped people would be able to use preferred content settings.
+
+I'd suggest adding support for archive directories to this. So if you create a file on the phone and are done with it, you can move it to an archive directory, and it will then be dropped from the phone once it reaches an archive repository.
+
+This should accomplish that. (Untested)
+
+`((exclude=*/archive/* and exclude=archive/*) or (not (copies=archive:1 or copies=smallarchive:1))) and (include=Music/* or include=Books/* or present)`
+"""]]
diff --git a/doc/tips/Using_Git-annex_as_a_web_browsing_assistant.mdwn b/doc/tips/Using_Git-annex_as_a_web_browsing_assistant.mdwn
new file mode 100644
index 000000000..4ee023de3
--- /dev/null
+++ b/doc/tips/Using_Git-annex_as_a_web_browsing_assistant.mdwn
@@ -0,0 +1,46 @@
+[[todo/wishlist: an "assistant" for web-browsing -- tracking the sources of the downloads]] suggests using git-annex as a tool to store downloads tied
+to their URLs. This also enables people to have their files stored offline,
+while being able to git annex drop them at any time and redownload them
+with git annex get. Additionally, a clone of the repo can be used to
+download whatever files are desired from online.
+
+This tip explains how to implement a similar system to the one described in
+the linked wishlist with existing software and features of git-annex.
+
+The first step is to install the Firefox plugin
+[FlashGot](http://flashgot.net/). We will use it to provide the Firefox
+shortcuts to add things to our annex.
+
+We also need a normal download manager, if we want to get status updates as
+the download is done. We'll need to configure git-annex to use it by
+setting `annex.web-download-command` as Joey describes in his comment on
+[[todo/wishlist: allow configuration of downloader for addurl]]. See the
+manpage [[git-annex]] for more information on setting configuration.
+
+Once we have installed all that, we need a script that has an interface
+which FlashGot can treat as a downloader, but which calls git-annex to do
+the actual downloading. Such a script is available from
+<https://gist.github.com/andyg0808/5342434>. Download it and store it
+somewhere it can live, or cut and paste:
+
+[[!format sh """
+#!/bin/bash
+# $1=folder to cd to (must be a git annex repo)
+# $2=URL to download
+
+cd "$1"
+git-annex addurl "$2"
+"""]]
+
+Finally, we need to configure FlashGot to use the script as a downloader.
+Go to Tools > Add-ons in Firefox. Click "Preferences" on FlashGot. Click
+the Add button next to the list of download managers. Enter a name for the
+git-annex downloader. Choose the script that was downloaded from the
+"Locate executable file" dialog that appears. Now set the command line
+arguments template to be "[FOLDER] [URL]" (you can find more substitution
+expressions in the Placeholders dropdown above the Command line arguments
+template field). You're done!
+
+Go ahead and test it by trying to download a file using FlashGot. It should
+offer as one of its available download managers the new manager you created
+just above. Select it and have fun!
diff --git a/doc/tips/Using_Git-annex_as_a_web_browsing_assistant/comment_1_74167f9fff400f148916003468c77de4._comment b/doc/tips/Using_Git-annex_as_a_web_browsing_assistant/comment_1_74167f9fff400f148916003468c77de4._comment
new file mode 100644
index 000000000..a091b8e48
--- /dev/null
+++ b/doc/tips/Using_Git-annex_as_a_web_browsing_assistant/comment_1_74167f9fff400f148916003468c77de4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-04-11T20:16:02Z"
+ content="""
+As of my last commit, you don't really need a separate download manager. The webapp will now display urls that `git annex addurl` is downloading in amoung the other transfers.
+"""]]
diff --git a/doc/tips/assume-unstaged.mdwn b/doc/tips/assume-unstaged.mdwn
new file mode 100644
index 000000000..63f5f820a
--- /dev/null
+++ b/doc/tips/assume-unstaged.mdwn
@@ -0,0 +1,31 @@
+[[!meta title="using assume-unstages to speed up git with large trees of annexed files"]]
+
+Git update-index's assume-unstaged feature can be used to speed
+up `git status` and stuff by not statting the whole tree looking for changed
+files.
+
+This feature works quite well with git-annex. Especially because git
+annex's files are immutable, so aren't going to change out from under it,
+this is a nice fit. If you have a very large tree and `git status` is
+annoyingly slow, you can turn it on:
+
+ git config core.ignoreStat true
+
+When `git mv` and `git rm` are used, those changes *do* get noticed, even
+on assume-unchanged files. When new files are added, eg by `git annex add`,
+they are also noticed.
+
+There are two gotchas. Both occur because `git add` does not stage
+assume-unchanged files.
+
+1. When an annexed file is moved to a different directory, it updates
+ the symlink, and runs `git add` on it. So the file will move,
+ but the changed symlink will not be noticed by git and it will commit a
+ dangling symlink.
+2. When using `git annex migrate`, it changes the symlink and `git adds`
+ it. Again this won't be committed.
+
+These can be worked around by running `git update-index --really-refresh`
+after performing such operations. I hope that `git add` will be changed
+to stage changes to assume-unchanged files, which would remove this
+only complication. --[[Joey]]
diff --git a/doc/tips/assume-unstaged/comment_1_44abd811ef79a85e557418e17a3927be._comment b/doc/tips/assume-unstaged/comment_1_44abd811ef79a85e557418e17a3927be._comment
new file mode 100644
index 000000000..d253feb5b
--- /dev/null
+++ b/doc/tips/assume-unstaged/comment_1_44abd811ef79a85e557418e17a3927be._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/2djv2EYwk43rfJIAQXjYt_vfuOU-#a11a6"
+ nickname="Olivier R"
+ subject="It doesn't work 100%"
+ date="2012-05-03T21:42:54Z"
+ content="""
+When you remove tracked files... it doesn't show the new status. it's like if the file was ignored.
+
+
+"""]]
diff --git a/doc/tips/assume-unstaged/comment_2_5b589f37cfc03bf7be33a51826cc4dba._comment b/doc/tips/assume-unstaged/comment_2_5b589f37cfc03bf7be33a51826cc4dba._comment
new file mode 100644
index 000000000..474d7b399
--- /dev/null
+++ b/doc/tips/assume-unstaged/comment_2_5b589f37cfc03bf7be33a51826cc4dba._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnxlx1UrzVhdy6_gFjzmF42x6QXxBUxg00"
+ nickname="Jakukyo"
+ subject="comment 2"
+ date="2013-09-05T12:14:42Z"
+ content="""
+> There are two gotchas...
+
+So just always run `git annex add` after editing a file
+and `git update-index --really-refresh` after migrating
+backend?
+
+"""]]
diff --git a/doc/tips/automatically_getting_files_on_checkout.mdwn b/doc/tips/automatically_getting_files_on_checkout.mdwn
new file mode 100644
index 000000000..bbb3b302e
--- /dev/null
+++ b/doc/tips/automatically_getting_files_on_checkout.mdwn
@@ -0,0 +1,15 @@
+Normally git-annex does not retrieve file contents when checking out a
+tree. In some use cases, it makes sense to always have the contents of
+files available after a `git checkout` or `git update`. This can be
+accomplished by installing the following as `.git/hooks/post-checkout`
+
+ #!/bin/sh
+ # Uses git-annex to get all files in the specified directories
+ # (relative to the top of the repository) on checkout.
+ dirs=.
+ top="$(git rev-parse --show-toplevel)"
+ for dir in "$dirs"; do git annex get $top/$dir"; done
+
+By default, all files in the whole repository will be made available. The
+`dirs` setting can be configured if you only want to get files in certian
+directories.
diff --git a/doc/tips/beware_of_SSD_wear_when_doing_fsck_on_large_special_remotes.mdwn b/doc/tips/beware_of_SSD_wear_when_doing_fsck_on_large_special_remotes.mdwn
new file mode 100644
index 000000000..0983c7d31
--- /dev/null
+++ b/doc/tips/beware_of_SSD_wear_when_doing_fsck_on_large_special_remotes.mdwn
@@ -0,0 +1,2 @@
+When git annex does fsck on (for example) a GPG-encrypted special directory remote, it first transfers the whole file into .git/annex/tmp directory.
+If your annex is on an SSD, it's a good idea to make .git/annex/tmp a symlink to say /var/tmp so SSD isn't worn down. This actually may be a better default.
diff --git a/doc/tips/beware_of_SSD_wear_when_doing_fsck_on_large_special_remotes/comment_1_e7c5c46112a2406b873d08bbf53c40d8._comment b/doc/tips/beware_of_SSD_wear_when_doing_fsck_on_large_special_remotes/comment_1_e7c5c46112a2406b873d08bbf53c40d8._comment
new file mode 100644
index 000000000..9c7bc2ed1
--- /dev/null
+++ b/doc/tips/beware_of_SSD_wear_when_doing_fsck_on_large_special_remotes/comment_1_e7c5c46112a2406b873d08bbf53c40d8._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawln3ckqKx0x_xDZMYwa9Q1bn4I06oWjkog"
+ nickname="Michael"
+ subject="comment 1"
+ date="2013-07-31T15:15:41Z"
+ content="""
+Of course, this only works when /var/tmp isn't on SSD itself. Perhaps tmpfs (e.g. a /tmp on many distros) is good -- after checking that there's enough space to transfer a particular file.
+"""]]
diff --git a/doc/tips/beware_of_SSD_wear_when_doing_fsck_on_large_special_remotes/comment_2_daf45ce29fed986fa9aa8b173760d0b7._comment b/doc/tips/beware_of_SSD_wear_when_doing_fsck_on_large_special_remotes/comment_2_daf45ce29fed986fa9aa8b173760d0b7._comment
new file mode 100644
index 000000000..929019705
--- /dev/null
+++ b/doc/tips/beware_of_SSD_wear_when_doing_fsck_on_large_special_remotes/comment_2_daf45ce29fed986fa9aa8b173760d0b7._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawln3ckqKx0x_xDZMYwa9Q1bn4I06oWjkog"
+ nickname="Michael"
+ subject="there's a problem"
+ date="2013-08-04T17:15:05Z"
+ content="""
+If .git/annex/tmp is a symlink to another fs, then adding doesn't work:
+
+ add file1.jpg (checksum...)
+ git-annex: /path/to/.git/annex/tmp/tmp30148: rename: unsupported operation (Invalid cross-device link)
+
+It looks like it would be good to have two types of tmp directories here, one for adding, another one for verifying (and that one could be redirected off SSD).
+
+"""]]
diff --git a/doc/tips/beware_of_SSD_wear_when_doing_fsck_on_large_special_remotes/comment_3_72d222020af4a9c6c753eb1ee7e1f1cf._comment b/doc/tips/beware_of_SSD_wear_when_doing_fsck_on_large_special_remotes/comment_3_72d222020af4a9c6c753eb1ee7e1f1cf._comment
new file mode 100644
index 000000000..2624a4fd3
--- /dev/null
+++ b/doc/tips/beware_of_SSD_wear_when_doing_fsck_on_large_special_remotes/comment_3_72d222020af4a9c6c753eb1ee7e1f1cf._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="guilhem"
+ ip="46.239.117.180"
+ subject="comment 3"
+ date="2013-08-19T01:05:40Z"
+ content="""
+A nice feature would be to perform the `fsck` on the (encrypted) remote itself, as it would avoid to clutter either the network or the tmpdir. However, that requires some changes in git-annex's backend. Indeed it would no longer be enough to store a single digest per (plain) file: a new digest needs to be stored for each encrypted copy. It is not necessarily a big deal, but the backend would need to be reorganized carefully.
+"""]]
diff --git a/doc/tips/centralised_repository:_starting_from_nothing.mdwn b/doc/tips/centralised_repository:_starting_from_nothing.mdwn
new file mode 100644
index 000000000..b12246d36
--- /dev/null
+++ b/doc/tips/centralised_repository:_starting_from_nothing.mdwn
@@ -0,0 +1,75 @@
+If you are starting from nothing (no existing `git` or `git-annex` repository) and want to use a server as a centralised repository, try the following steps.
+
+On the server where you'll hold the "master" repository:
+
+ server$ cd /one/git
+ server$ mkdir m
+ server$ cd m
+ server$ git init --bare
+ Initialized empty Git repository in /one/git/m/
+ server$ git annex init origin
+ init origin ok
+ server$
+
+Clone that to the laptop:
+
+ laptop$ cd /other
+ laptop$ git clone ssh://server//one/git/m
+ Cloning into 'm'...
+ Warning: No xauth data; using fake authentication data for X11 forwarding.
+ remote: Counting objects: 5, done.
+ remote: Compressing objects: 100% (3/3), done.
+ remote: Total 5 (delta 0), reused 0 (delta 0)
+ Receiving objects: 100% (5/5), done.
+ warning: remote HEAD refers to nonexistent ref, unable to checkout.
+
+ laptop$ cd m
+ laptop$ git annex init laptop
+ init laptop ok
+ laptop$
+
+Merge the `git-annex` repository (this is the bit that is often
+overlooked!):
+
+ laptop$ git annex merge
+ merge . (merging "origin/git-annex" into git-annex...)
+ ok
+ laptop$
+
+Add some content:
+
+ laptop$ git annex addurl http://kitenet.net/~joey/screencasts/git-annex_coding_in_haskell.ogg
+ "kitenet.net_~joey_screencasts_git-annex_coding_in_haskell.ogg"
+ addurl kitenet.net_~joey_screencasts_git-annex_coding_in_haskell.ogg (downloading http://kitenet.net/~joey/screencasts/git-annex_coding_in_haskell.ogg ...) --2011-12-15 08:13:10-- http://kitenet.net/~joey/screencasts/git-annex_coding_in_haskell.ogg
+ Resolving kitenet.net (kitenet.net)... 2001:41c8:125:49::10, 80.68.85.49
+ Connecting to kitenet.net (kitenet.net)|2001:41c8:125:49::10|:80... connected.
+ HTTP request sent, awaiting response... 200 OK
+ Length: 39362757 (38M) [audio/ogg]
+ Saving to: `/other/m/.git/annex/tmp/URL--http&c%%kitenet.net%~joey%screencasts%git-annex_coding_in_haskell.ogg'
+
+ 100%[======================================>] 39,362,757 2.31M/s in 17s
+
+ 2011-12-15 08:13:27 (2.21 MB/s) - `/other/m/.git/annex/tmp/URL--http&c%%kitenet.net%~joey%screencasts%git-annex_coding_in_haskell.ogg' saved [39362757/39362757]
+
+ (checksum...) ok
+ (Recording state in git...)
+ laptop$ git commit -m 'See Joey play.'
+ [master (root-commit) 106e923] See Joey play.
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+ create mode 120000 kitenet.net_~joey_screencasts_git-annex_coding_in_haskell.ogg
+ laptop$
+
+All fine, now push it back to the centralised master:
+
+ laptop$ git push
+ Counting objects: 20, done.
+ Delta compression using up to 4 threads.
+ Compressing objects: 100% (11/11), done.
+ Writing objects: 100% (18/18), 1.50 KiB, done.
+ Total 18 (delta 1), reused 1 (delta 0)
+ To ssh://server//one/git/m
+ 3ba1386..ad3bc9e git-annex -> git-annex
+ laptop$
+
+You can add more "client" repositories by following the `laptop`
+sequence of operations.
diff --git a/doc/tips/centralised_repository:_starting_from_nothing/comment_1_b0d22822017646775869ce1292e676f4._comment b/doc/tips/centralised_repository:_starting_from_nothing/comment_1_b0d22822017646775869ce1292e676f4._comment
new file mode 100644
index 000000000..22857af3e
--- /dev/null
+++ b/doc/tips/centralised_repository:_starting_from_nothing/comment_1_b0d22822017646775869ce1292e676f4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-12-23T19:19:53Z"
+ content="""
+See also: [[centralized_git_repository_tutorial]]
+"""]]
diff --git a/doc/tips/centralized_git_repository_tutorial.mdwn b/doc/tips/centralized_git_repository_tutorial.mdwn
new file mode 100644
index 000000000..00283829f
--- /dev/null
+++ b/doc/tips/centralized_git_repository_tutorial.mdwn
@@ -0,0 +1,140 @@
+The [[walkthrough]] builds up a decentralized git repository setup, but
+git-annex can also be used with a centralized bare repository, just like
+git can. This tutorial shows how to set up a centralized repository hosted on
+GitHub.
+
+## set up the repository, and make a checkout
+
+I've created a repository for technical talk videos, which you can
+[fork on Github](https://github.com/joeyh/techtalks).
+Or make your own repository on GitHub (or elsewhere) now.
+
+On your laptop, [[install]] git-annex, and clone the repository:
+
+ # git clone git@github.com:joeyh/techtalks.git
+ # cd techtalks
+
+Tell git-annex to use the repository, and describe where this clone is
+located:
+
+ # git annex init 'my laptop'
+ init my laptop ok
+
+Let's tell git-annex that GitHub doesn't support running git-annex-shell there.
+This means you can't store annexed file *contents* on GitHub; it would
+really be better to host the bare repository on your own server, which
+would not have this limitation. (If you want to do that, check out
+[[using_gitolite_with_git-annex]].)
+
+ # git config remote.origin.annex-ignore true
+
+## add files to the repository
+
+Add some files, obtained however.
+
+ # youtube-dl -t 'http://www.youtube.com/watch?v=b9FagOVqxmI'
+ # git annex add *.mp4
+ add Haskell_Amuse_Bouche-b9FagOVqxmI.mp4 (checksum) ok
+ (Recording state in git...)
+ # git commit -m "added a video. I have not watched it yet but it sounds interesting"
+
+This file is available directly from the web; so git-annex can download it:
+
+ # git annex addurl http://kitenet.net/~joey/screencasts/git-annex_coding_in_haskell.ogg
+ addurl kitenet.net_~joey_screencasts_git-annex_coding_in_haskell.ogg
+ (downloading http://kitenet.net/~joey/screencasts/git-annex_coding_in_haskell.ogg ...)
+ (checksum...) ok
+ (Recording state in git...)
+ # git commit -a -m 'added a screencast I made'
+
+Feel free the rename the files, etc, using normal git commands:
+
+ # git mv Haskell_Amuse_Bouche-b9FagOVqxmI.mp4 Haskell_Amuse_Bouche.mp4
+ # git mv kitenet.net_~joey_screencasts_git-annex_coding_in_haskell.ogg git-annex_coding_in_haskell.ogg
+ # git commit -m 'better filenames'
+
+Now push your changes back to the central repository. This first time,
+remember to push the git-annex branch, which is used to track the file
+contents.
+
+ # git push origin master git-annex
+ To git@github.com:joeyh/techtalks.git
+ * [new branch] master -> master
+ * [new branch] git-annex -> git-annex
+
+That push went fast, because it didn't upload large videos to GitHub.
+To check this, you can ask git-annex where the contents of the videos are:
+
+ # git annex whereis
+ whereis Haskell_Amuse_Bouche.mp4 (1 copy)
+ 767e8558-0955-11e1-be83-cbbeaab7fff8 -- here
+ ok
+ whereis git-annex_coding_in_haskell.ogg (2 copies)
+ 00000000-0000-0000-0000-000000000001 -- web
+ 767e8558-0955-11e1-be83-cbbeaab7fff8 -- here
+ ok
+
+## make more checkouts
+
+So far you have a central repository, and a checkout on a laptop.
+Let's make another checkout that's used as a backup. You can put it anywhere
+you like, just make it be somewhere your laptop can access. A few options:
+
+* Put it on a USB drive that you can plug into the laptop.
+* Put it on a desktop.
+* Put it on some server in the local network.
+* Put it on a remote VPS.
+
+I'll use the VPS option, but these instructions should work for
+any of the above.
+
+ # ssh server
+ server# sudo apt-get install git-annex
+
+Clone the central repository as before. (If the clone fails, you need
+to add your server's ssh public key to github -- see
+[this page](http://help.github.com/ssh-issues/).)
+
+ server# git clone git@github.com:joeyh/techtalks.git
+ server# cd techtalks
+ server# git config remote.origin.annex-ignore true
+ server# git annex init 'backup'
+ init backup (merging origin/git-annex into git-annex...) ok
+
+Notice that the server does not have the contents of any of the files yet.
+If you run `ls`, you'll see broken symlinks. We want to populate this
+backup with the file contents, by copying them from your laptop.
+
+Back on your laptop, you need to configure a git remote for the backup.
+Adjust the ssh url as needed to point to wherever the backup is. (If it
+was on a local USB drive, you'd use the path to the repository instead.)
+
+ # git remote add backup ssh://server/~/techtalks
+
+Now git-annex on your laptop knows how to reach the backup repository,
+and can do things like copy files to it:
+
+ # git annex copy --to backup git-annex_coding_in_haskell.ogg
+ copy git-annex_coding_in_haskell.ogg (checking backup...)
+ 12877824 2% 255.11kB/s 00:00
+ ok
+
+You can also `git annex move` files to it, to free up space on your laptop.
+And then you can `git annex get` files back to your laptop later on, as
+desired.
+
+After you use git-annex to move files around, remember to push,
+which will broadcast its updated location information.
+
+ # git push
+
+## take it farther
+
+Of course you can create as many checkouts as you desire. If you have a
+desktop machine too, you can make a checkout there, and use `git remote
+add` to also let your desktop access the backup repository.
+
+You can add remotes for each direct connection between machines you find you
+need -- so make the laptop have the desktop as a remote, and the desktop
+have the laptop as a remote, and then on either machine git-annex can
+access files stored on the other.
diff --git a/doc/tips/centralized_git_repository_tutorial/comment_1_9072ebc0c61446d7b151fcfab616fea9._comment b/doc/tips/centralized_git_repository_tutorial/comment_1_9072ebc0c61446d7b151fcfab616fea9._comment
new file mode 100644
index 000000000..c509d7579
--- /dev/null
+++ b/doc/tips/centralized_git_repository_tutorial/comment_1_9072ebc0c61446d7b151fcfab616fea9._comment
@@ -0,0 +1,33 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkC0W3ZQERUaTkHoks6k68Tsp1tz510nGo"
+ nickname="Georg"
+ subject="sync, push, pull with/to/from centralized bare repository"
+ date="2013-10-07T06:45:19Z"
+ content="""
+Hi Joey,
+
+thanks for tutorial with the centralized repo. I am currently trying to set up a central bare repo for two clients (they cannot communicate directly with each other). I am not sure if I am pushing/pulling the right way.
+
+On the server I did:
+
+ git init --bare
+ git annex init origin
+
+On Cĺient Alice (I want to give Bob a chance get call \"git annex get\" from \"origin\"):
+
+ git clone ssh://tktest@192.168.56.104/~/annex .
+ git annex init Alice
+ git annex merge
+ git annex add .
+ git commit -a -m \"Added tutorial\"
+ git push origin master git-annex
+ git annex copy . --to origin
+
+On Client Bob I have called \"clone, init, merge, add, push, copy\" also.
+
+Now the tricky part - do I have to call \"git annex sync\" at Alice's side to get the updates from Bob over origin?
+I ran into troubles if I called \"copy --to origin\" before \"git push origin master git-annex\". How can I resolve a non-fast-forware on the git-annex branch?
+Some notes about how to sync over a central bare repo would be nice here =)
+
+Thanks a lot, Georg
+"""]]
diff --git a/doc/tips/centralized_git_repository_tutorial/comment_2_528e92b21f0551fde4adb956654953ae._comment b/doc/tips/centralized_git_repository_tutorial/comment_2_528e92b21f0551fde4adb956654953ae._comment
new file mode 100644
index 000000000..21b286fff
--- /dev/null
+++ b/doc/tips/centralized_git_repository_tutorial/comment_2_528e92b21f0551fde4adb956654953ae._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.253.80"
+ subject="How can I resolve a non-fast-forware on the git-annex branch?"
+ date="2013-10-07T17:08:32Z"
+ content="""
+By either running `git annex sync`, or if you want to pull and push yourself, by running `git annex merge` before pushing.
+"""]]
diff --git a/doc/tips/downloading_podcasts.mdwn b/doc/tips/downloading_podcasts.mdwn
new file mode 100644
index 000000000..2e0ec0e30
--- /dev/null
+++ b/doc/tips/downloading_podcasts.mdwn
@@ -0,0 +1,63 @@
+You can use git-annex as a podcatcher, to download podcast contents.
+No additional software is required, but your git-annex must be built
+with the Feeds feature (run `git annex version` to check).
+
+All you need to do is put something like this in a cron job:
+
+`cd somerepo && git annex importfeed http://url/to/podcast http://other/podcast/url`
+
+This downloads the urls, and parses them as RSS, Atom, or RDF feeds.
+All enclosures are downloaded and added to the repository, the same as if you
+had manually run `git annex addurl` on each of them.
+
+git-annex will avoid downloading a file from a feed if its url has already
+been stored in the repository before. So once a file is downloaded,
+you can move it around, delete it, `git annex drop` its content, etc,
+and it will not be downloaded again by repeated runs of
+`git annex importfeed`. Just how a podcatcher should behave.
+
+## templates
+
+To control the filenames used for items downloaded from a feed,
+there's a --template option. The default is
+`--template='${feedtitle}/${itemtitle}${extension}'`
+
+Other available template variables:
+feedauthor, itemauthor, itemsummary, itemdescription, itemrights, itemid
+
+## catching up
+
+To catch up on a feed without downloading its contents,
+use `git annex importfeed --relaxed`, and delete the symlinks it creates.
+Next time you run `git annex addurl` it will only fetch any new items.
+
+## fast mode
+
+To add a feed without downloading its contents right now,
+use `git annex importfeed --fast`. Then you can use `git annex get` as
+usual to download the content of an item.
+
+## storing the podcast list in git
+
+You can check the list of podcast urls into git right next to the
+files it downloads. Just make a file named feeds and add one podcast url
+per line.
+
+Then you can run git-annex on all the feeds:
+
+`xargs git-annex importfeed < feeds`
+
+## distributed podcatching
+
+A nice benefit of using git-annex as a podcatcher is that you can
+run `git annex importfeed` on the same url in different clones
+of a repository, and `git annex sync` will sync it all up.
+
+## centralized podcatching
+
+You can also have a designated machine which always fetches all podcstas
+to local disk and stores them. That way, you can archive podcasts with
+time-delayed deletion of upstream content. You can also work around slow
+downloads upstream by podcatching to a server with ample bandwidth or work
+around a slow local Internet connection by podcatching to your home server
+and transferring to your laptop on demand.
diff --git a/doc/tips/downloading_podcasts/comment_10_4d4f6c22070b58918ee8d34c5e7290ad._comment b/doc/tips/downloading_podcasts/comment_10_4d4f6c22070b58918ee8d34c5e7290ad._comment
new file mode 100644
index 000000000..3bf5afe68
--- /dev/null
+++ b/doc/tips/downloading_podcasts/comment_10_4d4f6c22070b58918ee8d34c5e7290ad._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 10"
+ date="2013-08-05T16:47:30Z"
+ content="""
+`cabal install feed` should get the necessary library installed so that git-annex will build with feeds support.
+"""]]
diff --git a/doc/tips/downloading_podcasts/comment_11_d8d77048c7e2524968c188e1ad517873._comment b/doc/tips/downloading_podcasts/comment_11_d8d77048c7e2524968c188e1ad517873._comment
new file mode 100644
index 000000000..fd3459926
--- /dev/null
+++ b/doc/tips/downloading_podcasts/comment_11_d8d77048c7e2524968c188e1ad517873._comment
@@ -0,0 +1,24 @@
+[[!comment format=mdwn
+ username="http://a-or-b.myopenid.com/"
+ ip="220.244.41.108"
+ subject="comment 11"
+ date="2013-08-06T04:20:16Z"
+ content="""
+ $ cabal install feed
+ Resolving dependencies...
+ All the requested packages are already installed:
+ feed-0.3.9.1
+ Use --reinstall if you want to reinstall anyway.
+
+Then I reinstalled `git-annex` but it still doesn't find the feeds flag.
+
+ $ git annex version
+ git-annex version: 4.20130802
+ build flags: Assistant Webapp Pairing Testsuite S3 WebDAV FsEvents XMPP DNS
+
+Do I need to do something like:
+
+ cabal install git-annex --bindir=$HOME/bin -f\"-assistant -webapp -webdav -pairing -xmpp -dns -feed\"
+
+...but what are the default flags to include in addition to `-feed`
+"""]]
diff --git a/doc/tips/downloading_podcasts/comment_12_0859317471b43c88744dd3df95c879f7._comment b/doc/tips/downloading_podcasts/comment_12_0859317471b43c88744dd3df95c879f7._comment
new file mode 100644
index 000000000..e75a44a8c
--- /dev/null
+++ b/doc/tips/downloading_podcasts/comment_12_0859317471b43c88744dd3df95c879f7._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 12"
+ date="2013-08-06T04:24:10Z"
+ content="""
+-f-Feed will disable the feature. -fFeed will try to force it on.
+
+You can probably work out what's going wrong using cabal install -v3
+"""]]
diff --git a/doc/tips/downloading_podcasts/comment_13_e8c3c97282d17e2a1d47fb9d5e2b2f7b._comment b/doc/tips/downloading_podcasts/comment_13_e8c3c97282d17e2a1d47fb9d5e2b2f7b._comment
new file mode 100644
index 000000000..8d1242818
--- /dev/null
+++ b/doc/tips/downloading_podcasts/comment_13_e8c3c97282d17e2a1d47fb9d5e2b2f7b._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="http://a-or-b.myopenid.com/"
+ ip="220.244.41.108"
+ subject="comment 13"
+ date="2013-08-06T05:42:45Z"
+ content="""
+So I ran `cabal install -v3` and looked at the output,
+
+ Flags chosen: feed=True, tdfa=True, testsuite=True, android=False,
+ production=True, dns=True, xmpp=True, pairing=True, webapp=True,
+ assistant=True, dbus=True, inotify=True, webdav=True, s3=True
+
+This looks like feed should be on.
+
+There doesn't appear to be any errors in the compile either.
+
+Is it as simple as a bug where this flag just doesn't show in the `git annex version` command?
+"""]]
diff --git a/doc/tips/downloading_podcasts/comment_14_05a3694052de36848fbbad6eeeada895._comment b/doc/tips/downloading_podcasts/comment_14_05a3694052de36848fbbad6eeeada895._comment
new file mode 100644
index 000000000..4bc831f7f
--- /dev/null
+++ b/doc/tips/downloading_podcasts/comment_14_05a3694052de36848fbbad6eeeada895._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 14"
+ date="2013-08-07T16:03:12Z"
+ content="""
+Yes, it did turn out to be as simple as my having forgotten that I have to manually add features to the version list.
+"""]]
diff --git a/doc/tips/downloading_podcasts/comment_15_21028bed8858c2dae1ac9c2d014fd2a1._comment b/doc/tips/downloading_podcasts/comment_15_21028bed8858c2dae1ac9c2d014fd2a1._comment
new file mode 100644
index 000000000..0f998d066
--- /dev/null
+++ b/doc/tips/downloading_podcasts/comment_15_21028bed8858c2dae1ac9c2d014fd2a1._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://23.gs/"
+ ip="46.165.197.5"
+ subject="No file extension?"
+ date="2013-08-12T13:21:50Z"
+ content="""
+It seems git-annex is a bit overzealous when sanitizing the file extension, currently I get: \"Nerdkunde/Let_s_go_to_the_D_M_C_A_m4a\" from http://www.nerdkunde.de/episodes.m4a.rss with the default template and only \"Nerdkunde/Let_s_go_to_the_D_M_C_A._m4a\" if I add the \".\" in the template myself...
+"""]]
diff --git a/doc/tips/downloading_podcasts/comment_16_4869fb5c9f896acc477c44de06c36ca7._comment b/doc/tips/downloading_podcasts/comment_16_4869fb5c9f896acc477c44de06c36ca7._comment
new file mode 100644
index 000000000..4419d02a8
--- /dev/null
+++ b/doc/tips/downloading_podcasts/comment_16_4869fb5c9f896acc477c44de06c36ca7._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="arand"
+ ip="130.243.226.21"
+ subject="comment 16"
+ date="2013-08-12T13:32:46Z"
+ content="""
+The filename extension is a known issue and already fixed in the development version, see <http://git-annex.branchable.com/bugs/importfeed_uses___34____95__foo__34___as_extension/>
+"""]]
diff --git a/doc/tips/downloading_podcasts/comment_17_2e278ff200c1c15efd27c46a3e0aed40._comment b/doc/tips/downloading_podcasts/comment_17_2e278ff200c1c15efd27c46a3e0aed40._comment
new file mode 100644
index 000000000..bc49e5dd0
--- /dev/null
+++ b/doc/tips/downloading_podcasts/comment_17_2e278ff200c1c15efd27c46a3e0aed40._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlpKmTa1OPwy5Jk24pOoD8Vlo2jahzTPnw"
+ nickname="Stephen"
+ subject="rss authentication"
+ date="2013-08-13T13:32:52Z"
+ content="""
+If a podcast requires authentication, is there a way to pass credentials through? I tried `http://user:pass@site.com/rss.xml` but it didn't work.
+
+"""]]
diff --git a/doc/tips/downloading_podcasts/comment_18_382f2b970738d9b1af577955c3083e90._comment b/doc/tips/downloading_podcasts/comment_18_382f2b970738d9b1af577955c3083e90._comment
new file mode 100644
index 000000000..9e3244315
--- /dev/null
+++ b/doc/tips/downloading_podcasts/comment_18_382f2b970738d9b1af577955c3083e90._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://www.joachim-breitner.de/"
+ nickname="nomeata"
+ subject="--fast and --relaxed"
+ date="2013-08-16T07:27:59Z"
+ content="""
+Hi,
+
+the explanations to --fast and --relaxed on this page could be extended a bit. I looked it up in the man page, but it is not yet clear to me when I would use one or the other with feeds. Also, does “Next time you run git annex addurl it will only fetch any new items.” really only apply to --relaxed, and not --fast?
+
+Furthermore, it would be good if there were a template variable `itemnum` that I can use to ensure that `ls` prints the casts in the right order, even when the titles of the items are not helpful.
+
+Greetings,
+Joachim
+"""]]
diff --git a/doc/tips/downloading_podcasts/comment_19_f76fc6835e5787b0156380bf09fd81ca._comment b/doc/tips/downloading_podcasts/comment_19_f76fc6835e5787b0156380bf09fd81ca._comment
new file mode 100644
index 000000000..41313a87d
--- /dev/null
+++ b/doc/tips/downloading_podcasts/comment_19_f76fc6835e5787b0156380bf09fd81ca._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 19"
+ date="2013-08-22T15:25:02Z"
+ content="""
+I would expect user:pass@site.com to work if the site is using http basic auth. `importfeed` just runs `wget` (or `curl`) to do all downloads, and wget's documentation says that works. It also says you can use ~/.netrc to store the password for a site.
+"""]]
diff --git a/doc/tips/downloading_podcasts/comment_1_f04bc32a34baeeffcd691e9f7cce0230._comment b/doc/tips/downloading_podcasts/comment_1_f04bc32a34baeeffcd691e9f7cce0230._comment
new file mode 100644
index 000000000..014fe3f50
--- /dev/null
+++ b/doc/tips/downloading_podcasts/comment_1_f04bc32a34baeeffcd691e9f7cce0230._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="ckeen"
+ ip="79.249.110.228"
+ subject="Filename too long"
+ date="2013-07-30T14:39:44Z"
+ content="""
+It seems that some of my feeds get stored into keys that generate a too long filename:
+
+ podcasts/.git/annex/tmp/b1f_325_URL-s143660317--http&c%%feedproxy.google.com%~r%mixotic%~5%urTIRWQK2OQ%Mixotic__258__-__Michael__Miller__-__Galactic__Technolgies.mp3.log.web:
+ openBinaryFile: invalid argument (File name too long)
+
+Is there a way to work around this?
+"""]]
diff --git a/doc/tips/downloading_podcasts/comment_20_65ebf3a3bbf0a2aebd2b69640b757e16._comment b/doc/tips/downloading_podcasts/comment_20_65ebf3a3bbf0a2aebd2b69640b757e16._comment
new file mode 100644
index 000000000..6060be655
--- /dev/null
+++ b/doc/tips/downloading_podcasts/comment_20_65ebf3a3bbf0a2aebd2b69640b757e16._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 20"
+ date="2013-08-22T15:29:11Z"
+ content="""
+The git-annex man page has a bit more to say about --relaxed and --fast. Their behavior when used with `importfeed` is the same as with `addurl`.
+
+If the podcast feed provides an `itemid`, you can use that in the filename template. I don't know how common that is. Due to the way `importfeed` works, it cannot keep track of eg, an incrementing item number itself.
+"""]]
diff --git a/doc/tips/downloading_podcasts/comment_2_a9a98cad7358d16792853a2ee413fe6c._comment b/doc/tips/downloading_podcasts/comment_2_a9a98cad7358d16792853a2ee413fe6c._comment
new file mode 100644
index 000000000..f8ba1155c
--- /dev/null
+++ b/doc/tips/downloading_podcasts/comment_2_a9a98cad7358d16792853a2ee413fe6c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.21"
+ subject="comment 2"
+ date="2013-07-30T17:16:07Z"
+ content="""
+@ckeen You seem to be using a filesystem that does not support filenames 150 characters long. This is unusual -- even windows and android can support a filename up to 255 characters in length. `git-annex addurl` already deals with this sort of problem by limiting the filename to 255 characters. If you'd like to file a bug report with details about your system, I can try to make git-annex support its limitations, I suppose.
+"""]]
diff --git a/doc/tips/downloading_podcasts/comment_3_5a8068a5cb0fd864581157a3aa5d1113._comment b/doc/tips/downloading_podcasts/comment_3_5a8068a5cb0fd864581157a3aa5d1113._comment
new file mode 100644
index 000000000..7e5633865
--- /dev/null
+++ b/doc/tips/downloading_podcasts/comment_3_5a8068a5cb0fd864581157a3aa5d1113._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://www.joachim-breitner.de/"
+ nickname="nomeata"
+ subject="Great stuff!"
+ date="2013-07-30T21:21:57Z"
+ content="""
+Looking forward to seeing it in Debian unstable; where it will definitely replace my hpodder setup.
+
+I guess there is no easy way to re-use the files already downloaded with hpodder? At first I thought that `git annex importfeed --relaxed` followed by adding the files to the git annex would work, but `importfeed` stores URLs, not content-based hashes, so it wouldn’t match up.
+"""]]
diff --git a/doc/tips/downloading_podcasts/comment_4_e7072a9da30b4c4b4c526013144238d4._comment b/doc/tips/downloading_podcasts/comment_4_e7072a9da30b4c4b4c526013144238d4._comment
new file mode 100644
index 000000000..1693c4bdc
--- /dev/null
+++ b/doc/tips/downloading_podcasts/comment_4_e7072a9da30b4c4b4c526013144238d4._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.21"
+ subject="comment 4"
+ date="2013-07-30T21:29:50Z"
+ content="""
+@nomeata, well, you can, but it has to download the files again.
+
+When run without --fast, `importfeed` does use content based hashes, so if you run it in a temporary directory, it will download the content redundantly, hash it and see it's the same, and add the url to that hash. You can then delete the temporary directory, and the files hpodder had downloaded will have the url attached to them now. I don't know if this really buys you anything over deleting the hpodder files and starting over though.
+"""]]
diff --git a/doc/tips/downloading_podcasts/comment_5_79b3f8d678ac9f67df4c0cd649657283._comment b/doc/tips/downloading_podcasts/comment_5_79b3f8d678ac9f67df4c0cd649657283._comment
new file mode 100644
index 000000000..f5df9910f
--- /dev/null
+++ b/doc/tips/downloading_podcasts/comment_5_79b3f8d678ac9f67df4c0cd649657283._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="ckeen"
+ ip="79.249.110.228"
+ subject="Force a reload of a feed?"
+ date="2013-07-31T10:35:50Z"
+ content="""
+Currently I have my podcasts imported with --fast. For some reason there are podcast episodes missing. This has been done propably during my period of toying with the feature. If I retry on a clean annex I see all episodes. My suspicion is that git-annex has been interrupted during downloading a feed but now somehow thinks it's already there. How can I debug this situation and/or force git annex to retry all the links in a feed?
+"""]]
diff --git a/doc/tips/downloading_podcasts/comment_6_35106fee5458bdd5c21868fbc49d3616._comment b/doc/tips/downloading_podcasts/comment_6_35106fee5458bdd5c21868fbc49d3616._comment
new file mode 100644
index 000000000..caeca0151
--- /dev/null
+++ b/doc/tips/downloading_podcasts/comment_6_35106fee5458bdd5c21868fbc49d3616._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.21"
+ subject="use the force"
+ date="2013-07-31T16:20:39Z"
+ content="""
+The only way it can skip downloading a file is if its url has already been seen before. Perhaps you deleted them?
+
+I've made `importfeed --force` re-download files it's seen before.
+"""]]
diff --git a/doc/tips/downloading_podcasts/comment_7_ceb16498b7aadbf04a27acd5d6561d46._comment b/doc/tips/downloading_podcasts/comment_7_ceb16498b7aadbf04a27acd5d6561d46._comment
new file mode 100644
index 000000000..ac2c89a36
--- /dev/null
+++ b/doc/tips/downloading_podcasts/comment_7_ceb16498b7aadbf04a27acd5d6561d46._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="ckeen"
+ ip="78.108.63.46"
+ subject="--force reload all URLs"
+ date="2013-08-01T09:47:34Z"
+ content="""
+Is it intentionally saving URLs with a prefixed 2_? I have sorted out all missing URLs and renamed it, so no harm done, but it has been a bit of a hassle to get there.
+"""]]
diff --git a/doc/tips/downloading_podcasts/comment_8_147397603f0b3fdb42ca387d1da7c5ef._comment b/doc/tips/downloading_podcasts/comment_8_147397603f0b3fdb42ca387d1da7c5ef._comment
new file mode 100644
index 000000000..0995d8075
--- /dev/null
+++ b/doc/tips/downloading_podcasts/comment_8_147397603f0b3fdb42ca387d1da7c5ef._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.145"
+ subject="comment 8"
+ date="2013-08-01T16:05:10Z"
+ content="""
+I've now made importfeed --force a bit smarter about reusing existing files.
+"""]]
diff --git a/doc/tips/downloading_podcasts/comment_9_6a26a6cc7683d38fae0f23c5a52d1e23._comment b/doc/tips/downloading_podcasts/comment_9_6a26a6cc7683d38fae0f23c5a52d1e23._comment
new file mode 100644
index 000000000..3045c9894
--- /dev/null
+++ b/doc/tips/downloading_podcasts/comment_9_6a26a6cc7683d38fae0f23c5a52d1e23._comment
@@ -0,0 +1,24 @@
+[[!comment format=mdwn
+ username="http://a-or-b.myopenid.com/"
+ ip="220.244.41.108"
+ subject="How do I switch on the 'feeds' feature?"
+ date="2013-08-05T04:52:41Z"
+ content="""
+Joey - your initial post said:
+
+ git-annex must be built with the Feeds feature (run git annex version to check).
+
+...but how do I actually switch on the feeds feature?
+
+I install git-annex from cabal, so I do
+
+ cabal update
+ cabal install git-annex
+
+which I did this morning and now `git annex version` gives me:
+
+ git-annex version: 4.20130802
+ build flags: Assistant Webapp Pairing Testsuite S3 WebDAV FsEvents XMPP DNS
+
+So it is the latest version, but without Feeds. :-(
+"""]]
diff --git a/doc/tips/dropboxannex.mdwn b/doc/tips/dropboxannex.mdwn
new file mode 100644
index 000000000..926e142ca
--- /dev/null
+++ b/doc/tips/dropboxannex.mdwn
@@ -0,0 +1,28 @@
+dropboxannex
+=========
+
+Hook program for gitannex to use dropbox as backend
+
+# Requirements:
+
+ python2
+
+Credit for the Dropbox api interface goes to Dropbox.
+
+# Install
+Clone the git repository in your home folder.
+
+ git clone git://github.com/TobiasTheViking/dropboxannex.git
+
+This should make a ~/dropboxannex folder
+
+# Setup
+Run the program once to set it up.
+
+ cd ~/dropboxannex; python2 dropboxannex.py
+
+# Commands for gitannex:
+
+ git config annex.dropbox-hook '/usr/bin/python2 ~/dropboxannex/dropboxannex.py'
+ git annex initremote dropbox type=hook hooktype=dropbox encryption=shared
+ git annex describe dropbox "the dropbox library"
diff --git a/doc/tips/emacs_integration.mdwn b/doc/tips/emacs_integration.mdwn
new file mode 100644
index 000000000..12f16888a
--- /dev/null
+++ b/doc/tips/emacs_integration.mdwn
@@ -0,0 +1,20 @@
+bergey has developed an emacs mode for browsing git-annex repositories,
+dired style.
+
+<https://gitorious.org/emacs-contrib/annex-mode>
+
+Locally available files are colored differently, and pressing g runs
+`git annex get` on the file at point.
+
+----
+
+John Wiegley has developed a brand new git-annex interaction mode for
+Emacs, which aims to integrate with the standard facilities
+(C-x C-q, M-x dired, etc) rather than invent its own interface.
+
+<https://github.com/jwiegley/git-annex-el>
+
+He has also added support to org-attach; if
+`org-attach-git-annex-cutoff' is non-nil and smaller than the size
+ of the file you're attaching then org-attach will `git annex add the
+file`; otherwise it will "git add" it.
diff --git a/doc/tips/finding_duplicate_files.mdwn b/doc/tips/finding_duplicate_files.mdwn
new file mode 100644
index 000000000..94fc85400
--- /dev/null
+++ b/doc/tips/finding_duplicate_files.mdwn
@@ -0,0 +1,21 @@
+Maybe you had a lot of files scattered around on different drives, and you
+added them all into a single git-annex repository. Some of the files are
+surely duplicates of others.
+
+While git-annex stores the file contents efficiently, it would still
+help in cleaning up this mess if you could find, and perhaps remove
+the duplicate files.
+
+Here's a command line that will show duplicate sets of files grouped together:
+
+ git annex find --include '*' --format='${file} ${escaped_key}\n' | \
+ sort -k2 | uniq --all-repeated=separate -f1 | \
+ sed 's/ [^ ]*$//'
+
+Here's a command line that will remove one of each duplicate set of files:
+
+ git annex find --include '*' --format='${file} ${escaped_key}\n' | \
+ sort -k2 | uniq --repeated -f1 | sed 's/ [^ ]*$//' | \
+ xargs -d '\n' git rm
+
+--[[Joey]]
diff --git a/doc/tips/finding_duplicate_files/comment_10_2ed5aa8c632048b13e01d358883fa383._comment b/doc/tips/finding_duplicate_files/comment_10_2ed5aa8c632048b13e01d358883fa383._comment
new file mode 100644
index 000000000..77a308b90
--- /dev/null
+++ b/doc/tips/finding_duplicate_files/comment_10_2ed5aa8c632048b13e01d358883fa383._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmTNrhkVQ26GBLaLD5-zNuEiR8syTj4mI8"
+ nickname="Juan"
+ subject="comment 10"
+ date="2013-08-31T18:20:58Z"
+ content="""
+I'm already spreading the word. Handling scientific papers, data, simulations and code has been quite a challenge during my academic career. While code was solved long ago, the three first items remained a huge problem.
+I'm sure many of my colleagues will be happy to use it.
+Is there any hashtag or twitter account? I've seen that you collected some of my tweets, but I don't know how you did it. Did you search for git-annex?
+Best,
+ Juan
+"""]]
diff --git a/doc/tips/finding_duplicate_files/comment_1_ddb477ca242ffeb21e0df394d8fdf5d2._comment b/doc/tips/finding_duplicate_files/comment_1_ddb477ca242ffeb21e0df394d8fdf5d2._comment
new file mode 100644
index 000000000..d1bd4475e
--- /dev/null
+++ b/doc/tips/finding_duplicate_files/comment_1_ddb477ca242ffeb21e0df394d8fdf5d2._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://adamspiers.myopenid.com/"
+ nickname="Adam"
+ subject="Cool"
+ date="2011-12-23T19:16:50Z"
+ content="""
+Very nice :) Just for reference, here's [my Perl implementation](https://github.com/aspiers/git-config/blob/master/bin/git-annex-finddups). As per [this discussion](http://git-annex.branchable.com/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/#comment-fb15d5829a52cd05bcbd5dc53edaffb2) it would be interesting to benchmark these two approaches and see if one is substantially more efficient than the other w.r.t. CPU and memory usage.
+"""]]
diff --git a/doc/tips/finding_duplicate_files/comment_2_900eafe0a781018ff44b35ac232e3ad3._comment b/doc/tips/finding_duplicate_files/comment_2_900eafe0a781018ff44b35ac232e3ad3._comment
new file mode 100644
index 000000000..605c804dd
--- /dev/null
+++ b/doc/tips/finding_duplicate_files/comment_2_900eafe0a781018ff44b35ac232e3ad3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="bremner"
+ ip="156.34.89.108"
+ subject="problems with spaces in filenames"
+ date="2012-09-05T02:12:18Z"
+ content="""
+note that the sort -k2 doesn't work right for filenames with spaces in them. On the other hand, git-rm doesn't seem to like the escaped names from escaped_file.
+"""]]
diff --git a/doc/tips/finding_duplicate_files/comment_3._comment b/doc/tips/finding_duplicate_files/comment_3._comment
new file mode 100644
index 000000000..44eeb5075
--- /dev/null
+++ b/doc/tips/finding_duplicate_files/comment_3._comment
@@ -0,0 +1,39 @@
+[[!comment format=mdwn
+ username="mhameed"
+ ip="82.32.202.53"
+ subject="problems with spaces in filenames"
+ date="Wed Sep 5 09:38:56 BST 2012"
+ content="""
+
+Spaces, and other special chars can make filename handeling ugly.
+If you don't have a restriction on keeping the exact filenames, then
+it might be easiest just to get rid of the problematic chars.
+
+ #!/bin/bash
+
+ function process() {
+ dir="$1"
+ echo "processing $dir"
+ pushd $dir >/dev/null 2>&1
+
+ for fileOrDir in *; do
+ nfileOrDir=`echo "$fileOrDir" | sed -e 's/\[//g' -e 's/\]//g' -e 's/ /_/g' -e "s/'//g" `
+ if [ "$fileOrDir" != "$nfileOrDir" ]; then
+ echo renaming $fileOrDir to $nfileOrDir
+ git mv "$fileOrDir" "$nfileOrDir"
+ else
+ echo "skipping $fileOrDir, no need to rename."
+ fi
+ done
+
+ find ./ -mindepth 1 -maxdepth 1 -type d | while read d; do
+ process "$d"
+ done
+ popd >/dev/null 2>&1
+ }
+
+ process .
+
+Maybe you can run something like this before checking for duplicates.
+
+"""]]
diff --git a/doc/tips/finding_duplicate_files/comment_4_1494143a74cc1e9fbe4720c14b73d42b._comment b/doc/tips/finding_duplicate_files/comment_4_1494143a74cc1e9fbe4720c14b73d42b._comment
new file mode 100644
index 000000000..f1a86f43c
--- /dev/null
+++ b/doc/tips/finding_duplicate_files/comment_4_1494143a74cc1e9fbe4720c14b73d42b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="bremner"
+ ip="156.34.89.108"
+ subject="more about spaces..."
+ date="2012-09-09T19:33:01Z"
+ content="""
+Ironically, previous renaming to remove spaces, plus some synching is how I ended up with these duplicates. For what it is worth, aspiers perl script worked out for me with a small modification. I just only printed out the duplicates with spaces in them (quoted).
+"""]]
diff --git a/doc/tips/finding_duplicate_files/comment_5_1a35ca360468bcb84a67ad8d62a2ef7d._comment b/doc/tips/finding_duplicate_files/comment_5_1a35ca360468bcb84a67ad8d62a2ef7d._comment
new file mode 100644
index 000000000..23beb779f
--- /dev/null
+++ b/doc/tips/finding_duplicate_files/comment_5_1a35ca360468bcb84a67ad8d62a2ef7d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkaBh9VNJ-RZ26wJZ4BEhMN1IlPT-DK6JA"
+ nickname="Alex"
+ subject="printing keys first is the easiest workaround"
+ date="2013-04-01T23:32:23Z"
+ content="""
+Since the keys are sure to have nos paces in them, putting them first makes working with the output with tools like sort, uniq, and awk simpler.
+"""]]
diff --git a/doc/tips/finding_duplicate_files/comment_6_a6e88c93b31f67c933523725ff61b287._comment b/doc/tips/finding_duplicate_files/comment_6_a6e88c93b31f67c933523725ff61b287._comment
new file mode 100644
index 000000000..31601a989
--- /dev/null
+++ b/doc/tips/finding_duplicate_files/comment_6_a6e88c93b31f67c933523725ff61b287._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnkBYpLu_NOj7Uq0-acvLgWhxF8AUEIJbo"
+ nickname="Chris"
+ subject="Find files by key"
+ date="2013-05-03T04:14:55Z"
+ content="""
+Is there any simple way to search for files with a given key?
+
+At the moment, the best I've come up with is this:
+
+````
+git annex find --include '*' --format='${key} ${file}' | grep <KEY>
+````
+
+where `<KEY>` is the key. This seems like an awfully longwinded approach, but I don't see anything in the docs indicating a simpler way to do it. Am I missing something?
+"""]]
diff --git a/doc/tips/finding_duplicate_files/comment_7_347b0186755a809594bd42feda6363e2._comment b/doc/tips/finding_duplicate_files/comment_7_347b0186755a809594bd42feda6363e2._comment
new file mode 100644
index 000000000..d97b0d500
--- /dev/null
+++ b/doc/tips/finding_duplicate_files/comment_7_347b0186755a809594bd42feda6363e2._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 7"
+ date="2013-05-13T18:42:14Z"
+ content="""
+@Chris I guess there's no really easy way because searching for a given key is not something many people need to do.
+
+However, git does provide a way. Try `git log --stat -S $KEY`
+"""]]
diff --git a/doc/tips/finding_duplicate_files/comment_8_3af51722da0980b724facb184f0f66e9._comment b/doc/tips/finding_duplicate_files/comment_8_3af51722da0980b724facb184f0f66e9._comment
new file mode 100644
index 000000000..26c34fcfa
--- /dev/null
+++ b/doc/tips/finding_duplicate_files/comment_8_3af51722da0980b724facb184f0f66e9._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmTNrhkVQ26GBLaLD5-zNuEiR8syTj4mI8"
+ nickname="Juan"
+ subject="This is an awesome feature"
+ date="2013-08-28T13:40:23Z"
+ content="""
+Thanks. I have quite a lot of papers in PDF formats. Now I'm saving space, have them controlled, synchronized with many devices and found more than 200 duplicates.
+Is there a way to donate to the project? You really deserve it.
+Thanks.
+"""]]
diff --git a/doc/tips/finding_duplicate_files/comment_9_7b4b78a5cd253abfe4f6001049bf64f3._comment b/doc/tips/finding_duplicate_files/comment_9_7b4b78a5cd253abfe4f6001049bf64f3._comment
new file mode 100644
index 000000000..a20ca16ed
--- /dev/null
+++ b/doc/tips/finding_duplicate_files/comment_9_7b4b78a5cd253abfe4f6001049bf64f3._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.7"
+ subject="comment 9"
+ date="2013-08-28T20:25:20Z"
+ content="""
+@Juan the best thing to do is tell people about git-annex, help them use it, and file bug reports. Just generally be part of the git-annex community.
+
+(If you really want to donate to me, <http://campaign.joeyh.name/> is still open.)
+"""]]
diff --git a/doc/tips/flickrannex.mdwn b/doc/tips/flickrannex.mdwn
new file mode 100644
index 000000000..d8e54b4c3
--- /dev/null
+++ b/doc/tips/flickrannex.mdwn
@@ -0,0 +1,62 @@
+# Latest version 0.1.10
+Hook program for gitannex to use flickr as backend.
+
+This allows storing any type of file on flickr, not only images and movies.
+
+# Requirements:
+
+ python2
+
+Credit for the flickr api interface goes to: <http://stuvel.eu/flickrapi>
+Credit for the png library goes to: <https://github.com/drj11/pypng>
+Credit for the png tEXt patch goes to: <https://code.google.com/p/pypng/issues/detail?id=65>
+
+# Install
+
+Clone the git repository in your home folder.
+
+ git clone git://github.com/TobiasTheViking/flickrannex.git
+
+This should make a ~/flickrannex folder
+
+# Setup
+
+Run the program once to set it up.
+
+ cd ~/flickrannex; python2 flickrannex.py
+
+After the setup has finished, it will print the git-annex configure lines.
+
+# Configuring git-annex
+
+ git config annex.flickr-hook '/usr/bin/python2 ~/flickrannex/flickrannex.py'
+ git annex initremote flickr type=hook hooktype=flickr encryption=shared
+ git annex describe flickr "the flickr library"
+
+# Notes
+
+## Unencrypted mode
+The photo name on flickr is currently the GPGHMACSHA1 version.
+
+Run the following command in your annex directory
+ git annex wanted flickr uuid include=*.jpg or include=*.jpeg or include=*.gif or include=*.png
+
+## Encrypted mode
+The current version base64 encodes all the data, which results in ~35% larger filesize.
+
+I might look into yyenc instead. I'm not sure if it will work in the tEXt field.
+
+Run the following command in your annex directory
+ git annex wanted flickr exclude=largerthan=30mb
+
+## Including directories as tags
+Get get each of the directories below the top level git directory added as tags to uploads:
+
+ git config annex.flickr-hook 'GIT_TOP_LEVEL=`git rev-parse --show-toplevel` /usr/bin/python2 %s/flickrannex.py'
+
+In this case the image:
+ /home/me/annex-photos/holidays/2013/Greenland/img001.jpg
+would get the following tags: "holidays" "2013" "Greenland"
+(assuming "/home/me/annex-photos" is the top level in the annex...)
+
+Caveat Emptor - Tags will *always* be NULL for indirect repos - we don't (easily) know the human-readable file name.
diff --git a/doc/tips/flickrannex/comment_10_50707f259abe5829ce075dfbecd5a4ba._comment b/doc/tips/flickrannex/comment_10_50707f259abe5829ce075dfbecd5a4ba._comment
new file mode 100644
index 000000000..7bda45e5c
--- /dev/null
+++ b/doc/tips/flickrannex/comment_10_50707f259abe5829ce075dfbecd5a4ba._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmkBwMWvNKZZCge_YqobCSILPMeK6xbFw8"
+ nickname="develop"
+ subject="comment 10"
+ date="2013-06-07T09:39:59Z"
+ content="""
+I'm not even sure if chunksize is exposed to the hooks at all.
+
+As it is, the hook will check the filesize, and if the filesize is more than 30mbyte it will exit 1.
+
+Chunking may be implemented down the road. I do believe joeyh might have some plans that will touch this issue, so I'd rather wait. Than re-invent the wheel yet again.
+
+"""]]
diff --git a/doc/tips/flickrannex/comment_11_ab5bcb025381b3da4d7c6dfd0c7310dd._comment b/doc/tips/flickrannex/comment_11_ab5bcb025381b3da4d7c6dfd0c7310dd._comment
new file mode 100644
index 000000000..e59aa6500
--- /dev/null
+++ b/doc/tips/flickrannex/comment_11_ab5bcb025381b3da4d7c6dfd0c7310dd._comment
@@ -0,0 +1,46 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnaH44G3QbxBAYyDwy0PbvL0ls60XoaR3Y"
+ nickname="Nigel"
+ subject="git annex get failed"
+ date="2013-08-02T14:29:30Z"
+ content="""
+Hi, I am coming back to this and testing Flickr as a repository for moving files about and have run into what may be my very basic misunderstanding with vanilla annex.
+
+I copied one file to Flickr and dropped it elsewhere (--force). I assumed that the file was on Flickr ok but that the numcopies setting required the force because of the semi-trust level of the Flickr remote.
+
+Then I find I can't get the file back, even though there is a record of it from whereis.
+
+Can you help enlighten me as to what am I missing? I assumed whereis would only report files that exist and can be copied back. If not my error, I can raise bug or search for logs. Thanks in advance for any help.
+
+[[!format perl \"\"\"
+
+
+nrb@nrb-ThinkPad-T61:~/tmp$ git annex whereis
+whereis libpeerconnection.log (3 copies)
+ 31124688-0792-4214-9e00-7ed115aa6b8e -- flickr (the flickr library)
+ 3e3d40d7-de8f-4591-a4ab-747d74a3b278 -- origin (my laptop)
+ ec2d64fc-30d6-48b4-99bf-7b1bc22d420d -- portable USB drive
+ok
+whereis test.cgi (1 copy)
+ 31124688-0792-4214-9e00-7ed115aa6b8e -- flickr (the flickr library)
+ok
+whereis walkthrough.sh (3 copies)
+ 31124688-0792-4214-9e00-7ed115aa6b8e -- flickr (the flickr library)
+ 3e3d40d7-de8f-4591-a4ab-747d74a3b278 -- origin (my laptop)
+ ec2d64fc-30d6-48b4-99bf-7b1bc22d420d -- portable USB drive
+ok
+whereis walkthrough.sh~ (3 copies)
+ 31124688-0792-4214-9e00-7ed115aa6b8e -- flickr (the flickr library)
+ 3e3d40d7-de8f-4591-a4ab-747d74a3b278 -- origin (my laptop)
+ ec2d64fc-30d6-48b4-99bf-7b1bc22d420d -- portable USB drive
+ok
+nrb@nrb-ThinkPad-T61:~/tmp$ git annex get test.cgi
+get test.cgi (from flickr...)
+
+git-annex: /home/nrb/tmp/.git/annex/tmp/SHA256E-s48--a01eedbee949120aeda41e566f9ae8faef1c2bacaa6d7bb8e45050fb8df6d09d.cgi: rename: does not exist (No such file or directory)
+failed
+git-annex: get: 1 failed
+nrb@nrb-ThinkPad-T61:~/tmp$
+
+\"\"\"]]
+"""]]
diff --git a/doc/tips/flickrannex/comment_12_90a331275d888221bc695003c8acbe46._comment b/doc/tips/flickrannex/comment_12_90a331275d888221bc695003c8acbe46._comment
new file mode 100644
index 000000000..003755f30
--- /dev/null
+++ b/doc/tips/flickrannex/comment_12_90a331275d888221bc695003c8acbe46._comment
@@ -0,0 +1,58 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnaH44G3QbxBAYyDwy0PbvL0ls60XoaR3Y"
+ nickname="Nigel"
+ subject="re: git annex get failed"
+ date="2013-08-02T15:02:14Z"
+ content="""
+Another try - this time a slightly simpler setup using my version of the walkthrough commands
+
+[[!format bash \"\"\"
+
+nrb@nrb-ThinkPad-T61:~/repos/annex/laptop-annex$ git annex drop walkthrough.sh --from usbdrive
+drop usbdrive walkthrough.sh ok
+(Recording state in git...)
+nrb@nrb-ThinkPad-T61:~/repos/annex/laptop-annex$ git annex move walkthrough.sh --to flickr
+move walkthrough.sh (gpg) (checking flickr...) (to flickr...)
+/home/nrb/repos/gits/flickrannex/flickrannex.py:92: FutureWarning: The behavior of this method will change in future versions. Use specific 'len(elem)' or 'elem is not None' test instead.
+ if res:
+/home/nrb/repos/gits/flickrannex/flickrannex.py:100: FutureWarning: The behavior of this method will change in future versions. Use specific 'len(elem)' or 'elem is not None' test instead.
+ if res:
+ok
+(Recording state in git...)
+nrb@nrb-ThinkPad-T61:~/repos/annex/laptop-annex$ git annex whereis
+whereis walkthrough.sh (1 copy)
+ 161b7af0-2075-4314-9767-308a49b86018 -- flickr (the flickr library)
+ok
+whereis walkthrough.sh~ (3 copies)
+ 161b7af0-2075-4314-9767-308a49b86018 -- flickr (the flickr library)
+ 7803d853-d231-4bb4-b696-f12a950fb96b -- here (my laptop)
+ d60d75f9-d878-4214-af20-fa055134ae77 -- usbdrive (portable USB drive)
+ok
+nrb@nrb-ThinkPad-T61:~/repos/annex/laptop-annex$ git annex get walkthrough.sh
+get walkthrough.sh (from flickr...) (gpg)
+git-annex: /home/nrb/repos/annex/laptop-annex/.git/annex/tmp/GPGHMACSHA1--02f600d7e8b071d2945270fd5e7fc26dd066ff31: openBinaryFile: does not exist (No such file or directory)
+gpg: decrypt_message failed: eof
+
+ Unable to access these remotes: flickr
+
+ Try making some of these repositories available:
+ 161b7af0-2075-4314-9767-308a49b86018 -- flickr (the flickr library)
+failed
+git-annex: get: 1 failed
+nrb@nrb-ThinkPad-T61:~/repos/annex/laptop-annex$ git annex fsck --from flickr
+fsck walkthrough.sh (gpg) (checking flickr...) (fixing location log)
+ ** Based on the location log, walkthrough.sh
+ ** was expected to be present, but its content is missing.
+
+ ** No known copies exist of walkthrough.sh
+failed
+fsck walkthrough.sh~ (checking flickr...) (fixing location log)
+ ** Based on the location log, walkthrough.sh~
+ ** was expected to be present, but its content is missing.
+failed
+(Recording state in git...)
+git-annex: fsck: 2 failed
+nrb@nrb-ThinkPad-T61:~/repos/annex/laptop-annex$
+
+\"\"\" ]]
+"""]]
diff --git a/doc/tips/flickrannex/comment_13_1596e70dca71c853fd1d6fc9bde02b18._comment b/doc/tips/flickrannex/comment_13_1596e70dca71c853fd1d6fc9bde02b18._comment
new file mode 100644
index 000000000..19faa585e
--- /dev/null
+++ b/doc/tips/flickrannex/comment_13_1596e70dca71c853fd1d6fc9bde02b18._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmkBwMWvNKZZCge_YqobCSILPMeK6xbFw8"
+ nickname="develop"
+ subject="Version 0.1.10 pushed"
+ date="2013-09-11T20:31:25Z"
+ content="""
+Since the initial release of this hook a lot of issues have been fixed, and a few features added.
+
+I would highly suggest that everyone who is using this hook update to the latest version as i would consider one of the bugs to be fairly major.
+
+
+"""]]
diff --git a/doc/tips/flickrannex/comment_2_d74c4fc7edf8e47f7482564ce0ef4d12._comment b/doc/tips/flickrannex/comment_2_d74c4fc7edf8e47f7482564ce0ef4d12._comment
new file mode 100644
index 000000000..d015dc195
--- /dev/null
+++ b/doc/tips/flickrannex/comment_2_d74c4fc7edf8e47f7482564ce0ef4d12._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmkBwMWvNKZZCge_YqobCSILPMeK6xbFw8"
+ nickname="develop"
+ subject="comment 2"
+ date="2013-06-05T21:33:42Z"
+ content="""
+Get the statically linked version from here http://git-annex.branchable.com/install/Linux_standalone/
+
+I believe the new hook format was introduced in version 4.20130521
+"""]]
diff --git a/doc/tips/flickrannex/comment_2_f53d0d5520e2835e9705bea4e75556f0._comment b/doc/tips/flickrannex/comment_2_f53d0d5520e2835e9705bea4e75556f0._comment
new file mode 100644
index 000000000..14d7a1b7c
--- /dev/null
+++ b/doc/tips/flickrannex/comment_2_f53d0d5520e2835e9705bea4e75556f0._comment
@@ -0,0 +1,30 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnaH44G3QbxBAYyDwy0PbvL0ls60XoaR3Y"
+ nickname="Nigel"
+ subject="missing configuration for flickr-checkpresent-hook"
+ date="2013-06-05T20:44:25Z"
+ content="""
+<https://github.com/TobiasTheViking/flickrannex/issues/3>
+
+9 days ago: [the annex] \"hook format a few versions ago, and this is using the new hook format\".
+
+Looks very handy. I am just starting with this, but can't seem to get it working as a remote after following the simple walkthrough. All goes well until:
+
+ $ git annex copy . --to flickr
+ copy walkthrough.sh (checking flickr...)
+ missing configuration for flickr-checkpresent-hook
+ git-annex: checkpresent hook misconfigured
+
+my Ubuntu 12.04:
+
+ $ git annex version
+ git-annex version: 4.20130516.1
+ build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP
+ local repository version: 3
+ default repository version: 3
+ supported repository versions: 3 4
+ upgrade supported from repository versions: 0 1 2
+
+I guess my \"git-annex version is still too old\"? Any idea what version is needed? Even better if I can figure out which Linux distribution/release has the most up to date version of annex.
+
+"""]]
diff --git a/doc/tips/flickrannex/comment_4_9ebba4d61140f6c2071e988c9328cf7e._comment b/doc/tips/flickrannex/comment_4_9ebba4d61140f6c2071e988c9328cf7e._comment
new file mode 100644
index 000000000..741b0c5ba
--- /dev/null
+++ b/doc/tips/flickrannex/comment_4_9ebba4d61140f6c2071e988c9328cf7e._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmkBwMWvNKZZCge_YqobCSILPMeK6xbFw8"
+ nickname="develop"
+ subject="comment 4"
+ date="2013-06-05T22:02:29Z"
+ content="""
+The path for the binary \"/usr/bin/python2\" is wrong.
+
+It could be any of /usr/bin/python /usr/bin/python2.6 /usr/bin/python2.7
+
+Or maybe in /usr/local/bin
+
+you can try running \"which python\" or \"which python2\" to get the real path.
+"""]]
diff --git a/doc/tips/flickrannex/comment_5_4470dae270613dd8712623474bc80ab0._comment b/doc/tips/flickrannex/comment_5_4470dae270613dd8712623474bc80ab0._comment
new file mode 100644
index 000000000..1c19711df
--- /dev/null
+++ b/doc/tips/flickrannex/comment_5_4470dae270613dd8712623474bc80ab0._comment
@@ -0,0 +1,24 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnaH44G3QbxBAYyDwy0PbvL0ls60XoaR3Y"
+ nickname="Nigel"
+ subject="missing configuration for flickr-checkpresent-hook"
+ date="2013-06-05T22:00:48Z"
+ content="""
+Many thanks.
+
+I used gitannex-install and was left with a slight anomaly:
+
+ Installing...........done
+ git-annex version 4.20130601 has been installed
+ $ git-annex version
+ git-annex version: 4.20130531-g5df09b5
+
+But I guess this includes the new hook format. I get a bit further:
+
+ $ git annex copy . --to flickr
+ copy walkthrough.sh (checking flickr...) (user error (sh [\"-c\",\"/usr/bin/python2 /home/nrb/repos/gits/flickrannex/flickrannex.py\"] exited 1)) failed
+ copy walkthrough.sh~ (checking flickr...) (user error (sh [\"-c\",\"/usr/bin/python2 /home/nrb/repos/gits/flickrannex/flickrannex.py\"] exited 1)) failed
+ git-annex: copy: 2 failed
+
+
+"""]]
diff --git a/doc/tips/flickrannex/comment_5_d395cdcf815cb430e374ff05c1a63ff4._comment b/doc/tips/flickrannex/comment_5_d395cdcf815cb430e374ff05c1a63ff4._comment
new file mode 100644
index 000000000..dbeaafb73
--- /dev/null
+++ b/doc/tips/flickrannex/comment_5_d395cdcf815cb430e374ff05c1a63ff4._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnaH44G3QbxBAYyDwy0PbvL0ls60XoaR3Y"
+ nickname="Nigel"
+ subject="comment 5"
+ date="2013-06-05T22:11:14Z"
+ content="""
+Thanks, but on my machine I get:
+
+ $ which python2
+ /usr/bin/python2
+
+I have scripted all my walkthrough commands, blowing away the test repositories and flickr settings first each time. This re-runs the flickr scripts and git config annex.flickr-hook etc.
+
+I can't spot anything here.
+
+
+"""]]
diff --git a/doc/tips/flickrannex/comment_6_8cf730097001ffe106f2c743edce9d0a._comment b/doc/tips/flickrannex/comment_6_8cf730097001ffe106f2c743edce9d0a._comment
new file mode 100644
index 000000000..8e7b15ed0
--- /dev/null
+++ b/doc/tips/flickrannex/comment_6_8cf730097001ffe106f2c743edce9d0a._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmWg4VvDTer9f49Y3z-R0AH16P4d1ygotA"
+ nickname="Tobias"
+ subject="comment 6"
+ date="2013-06-06T09:44:11Z"
+ content="""
+That's weird...
+
+You could try adding \"--dbglevel 1 --stderr\" arguments to the hook command and give me the output. But the way i read the log it seems like it doesn't even launch the python intrepreter. I might be wrong though.
+
+
+"""]]
diff --git a/doc/tips/flickrannex/comment_7_a80c8087c4e1562a4c98a24edc182e5a._comment b/doc/tips/flickrannex/comment_7_a80c8087c4e1562a4c98a24edc182e5a._comment
new file mode 100644
index 000000000..9e0eb0a73
--- /dev/null
+++ b/doc/tips/flickrannex/comment_7_a80c8087c4e1562a4c98a24edc182e5a._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnaH44G3QbxBAYyDwy0PbvL0ls60XoaR3Y"
+ nickname="Nigel"
+ subject="Unencrypted flickr can only accept picture and video files"
+ date="2013-06-06T10:24:58Z"
+ content="""
+Thanks and sorry to trouble you, it is my error, I picked unencrypted option (thinking it would be less of an issue) and am using a text file for test, gave an error line:
+
+ 10:53:07 [flickrannex-0.1.5] main : 'Unencrypted flickr can only accept picture and video files'
+
+I've not looked through your code yet, but could that message be printed when not in debug mode?
+"""]]
diff --git a/doc/tips/flickrannex/comment_8_94f84254c32cf0f7dd1441b7da5d2bc6._comment b/doc/tips/flickrannex/comment_8_94f84254c32cf0f7dd1441b7da5d2bc6._comment
new file mode 100644
index 000000000..ff11a618a
--- /dev/null
+++ b/doc/tips/flickrannex/comment_8_94f84254c32cf0f7dd1441b7da5d2bc6._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmWg4VvDTer9f49Y3z-R0AH16P4d1ygotA"
+ nickname="Tobias"
+ subject="comment 8"
+ date="2013-06-06T10:51:39Z"
+ content="""
+I'll make it so, in the next version i push.
+"""]]
diff --git a/doc/tips/flickrannex/comment_9_5299b4cab4a4cb8e8fd4d2b39f0ea59c._comment b/doc/tips/flickrannex/comment_9_5299b4cab4a4cb8e8fd4d2b39f0ea59c._comment
new file mode 100644
index 000000000..f25cd04c1
--- /dev/null
+++ b/doc/tips/flickrannex/comment_9_5299b4cab4a4cb8e8fd4d2b39f0ea59c._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawleVyKk2kQsB_HgEdS7w1s0BmgRGy1aay0"
+ nickname="Milan"
+ subject="chunksize"
+ date="2013-06-07T09:09:56Z"
+ content="""
+Hi! Does this backend support chunksize option? If yes, is it possible to set it after the remote has been added to the repository?
+Thanks, Milan.
+"""]]
diff --git a/doc/tips/fully_encrypted_git_repositories_with_gcrypt.mdwn b/doc/tips/fully_encrypted_git_repositories_with_gcrypt.mdwn
new file mode 100644
index 000000000..5934747f0
--- /dev/null
+++ b/doc/tips/fully_encrypted_git_repositories_with_gcrypt.mdwn
@@ -0,0 +1,127 @@
+[git-remote-gcrypt](https://github.com/joeyh/git-remote-gcrypt/)
+adds support for encrypted remotes to git. The git-annex
+[[gcrypt special remote|special_remotes/gcrypt]] allows git-annex to
+also store its files in such repositories. Naturally, git-annex encrypts
+the files it stores too, so everything stored on the remote is encrypted.
+
+Here are some ways you can use this awesome stuff..
+
+[[!toc ]]
+
+This page will show how to set it up at the command line, but the git-annex
+[[assistant]] can also be used to help you set up encrypted git
+repositories.
+
+## prerequisites
+
+* Install
+[git-remote-gcrypt](https://github.com/joeyh/git-remote-gcrypt/)
+* Install git-annex version 4.20130909 or newer.
+
+## encrypted backup drive
+
+Let's make a USB drive into an encrypted backup repository. It will contain
+both the full contents of your git repository, and all the files you
+instruct git-annex to store on it, and everything will be encrypted so that
+only you can see it.
+
+First, you need to set up a gpg key. You might consider generating a
+special purpose key just for this use case, since you may end up wanting to
+put the key on multiple machines that you would not trust with your
+main gpg key.
+
+You need to tell git-annex the keyid of the key when setting up the
+encrypted repository:
+
+ git init --bare /mnt/encryptedbackup
+ git annex initremote encryptedbackup type=gcrypt gitrepo=/mnt/encryptedbackup keyid=$mykey
+ git annex sync encryptedbackup
+
+Now you can copy (or even move) files to the repository. After
+sending files to it, you'll probably want to do a sync, which pushes
+the git repository changes to it as well.
+
+ git annex copy --to encryptedbackup ...
+ git annex sync encryptedbackup
+
+Note that if you lose your gpg key, it will be *impossible* to get the
+data out of your encrypted backup. You need to find a secure way to store a
+backup of your gpg key. Printing it out and storing it in a safe deposit box,
+for example.
+
+You can actually specifiy keyid= as many times as you like to allow any one
+of a set of gpg keys to access this repository. So you could add a friend's
+key, or another gpg key you have.
+
+To restore from the backup, just plug the drive into any machine that has
+the gpg key used to encrypt it, and then:
+
+ git clone gcrypt::/mnt/encryptedbackup restored
+ cd restored
+ git annex enableremote encryptedbackup gitrepo=/mnt/encryptedbackup
+ git annex get --from encryptedbackup
+
+## encrypted git-annex repository on a ssh server
+
+If you have a ssh server that has rsync installed, you can set up an
+encrypted repository there. Works just like the encrypted drive except
+without the cable.
+
+First, on the server, run:
+
+ git init --bare encryptedrepo
+
+(Also, install git-annex on the server if it's possible & easy to do so.
+While this will work without git-annex being installed on the server, it
+is recommended to have it installed.)
+
+Now, in your existing git-annex repository, set up the encrypted remote:
+
+ git annex initremote encryptedrepo type=gcrypt gitrepo=ssh://my.server/home/me/encryptedrepo keyid=$mykey
+ git annex sync encryptedrepo
+
+If you're going to be sharing this repository with others, be sure to also
+include their keyids, by specifying keyid= repeatedly.
+
+Now you can copy (or even move) files to the repository. After
+sending files to it, you'll probably want to do a sync, which pushes
+the git repository changes to it as well.
+
+ git annex copy --to encryptedrepo ...
+ git annex sync encryptedbackup
+
+Anyone who has access to the repo it and has one of the keys
+used to encrypt it can check it out:
+
+ git clone gcrypt::ssh://my.server/home/me/encryptedrepo myrepo
+ cd myrepo
+ git annex enableremote encryptedrepo gitrepo=ssh://my.server/home/me/encryptedrepo
+ git annex get --from encryptedrepo
+
+## private encrypted git remote on hosting site
+
+You can use gcrypt to store your git repository in encrypted form on any
+hosting site that supports git. Only you can decrypt its contents.
+Using it this way, git-annex does not store large files on the hosting site; it's
+only used to store your git repository itself.
+
+ git remote add encrypted gcrypt::ssh://hostingsite/myrepo.git
+ git push encrypted master git-annex
+
+Now you can carry on using git-annex with your new repository. For example,
+`git annex sync` will sync with it.
+
+To check out the repository from the hosting site, use the same gcrypt::
+url you used when setting it up:
+
+ git clone gcrypt::ssh://hostingsite/myrepo.git
+
+## multiuser encrypted git remote on hosting site
+
+Suppose two users want to share an encrypted git remote. Both of you
+need to set up the remote, and configure gcrypt to encrypt it so that both
+of you can see it.
+
+ git remote add sharedencrypted gcrypt::ssh://hostingsite/myrepo.git
+ git config remote.sharedencrypted.gcryt-participants "$mykey $friendkey"
+ git config git push sharedencrypted master git-annex
diff --git a/doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_10_4440a80d64c60c7312d5c405d54e607a._comment b/doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_10_4440a80d64c60c7312d5c405d54e607a._comment
new file mode 100644
index 000000000..4ee70bcd7
--- /dev/null
+++ b/doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_10_4440a80d64c60c7312d5c405d54e607a._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="tanen"
+ ip="83.128.159.25"
+ subject="comment 10"
+ date="2013-11-04T17:58:36Z"
+ content="""
+> \"We could symetrically encrypt the repository with a keyfile that's stored in the repository itself\"
+> Then you would need to decrypt the repository in order get the key you need to decrypt the repository. The impossibility of this design is why I didn't do that!
+
+Sorry, I ment that the file containing the symmetric encryption key should obviously not be used to encrypt itself, it would be stored in the repository \"unencrypted\" (but protected with a passphrase)
+
+> store a non-encrypted gpg key alongside the repsitory encrypted with it, but then you have to rely on a passphrase for all your security.
+
+Exactly. I think such a mode be a great addition. It might not be as secure as encryption based on a private key - depending on the passphrase strength -, but it would certainly be a lot more convenient and portable (and still much more secure than the shared encryption method).
+"""]]
diff --git a/doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_1_5c54690586f2a781905ea4b25aa1147f._comment b/doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_1_5c54690586f2a781905ea4b25aa1147f._comment
new file mode 100644
index 000000000..71305e650
--- /dev/null
+++ b/doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_1_5c54690586f2a781905ea4b25aa1147f._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkbpbjP5j8MqWt_K4NASwv0WvB8T4rQ-pM"
+ nickname="Fabrice"
+ subject="Is there a way to specify a preferred pgp key?"
+ date="2013-11-01T18:57:38Z"
+ content="""
+Hi,
+
+I think the current behavior of the special remote is a bit annoying when one has several pgp keys.
+
+Indeed, I've followed the encrypted backup drive example specifying the id of a dedicated key in the initremote step, so far so good. Doing that, I was prompted for my key phrase by the gnome keyring daemon, as expected.
+
+The annoying part starts right at the git annex sync step. Indeed, when git-remote-gcrypt tries to decrypt the manifest from the encrypted remote, rather than trying only the key specified during the initremote step, it tries all my (secret) keys. This means that I get prompted for the key phrase of all those keys (minus the correct one which is already unlocked...).
+
+In the future, this might possible to avoid by allowing gcrypt to fetch a preferred key from git config and to use with the --try-secret-key option available gnupg 2.1.x. But for 1.x or 2.0.x, the simpler option --default-key does not seem to alter the order in which keys are tried to decrypt the manifest. Also, it does not seem to be a problem of the gnome keyring daemon, but rather a gpg problem as when the daemon is replaced by the standard gpg-agent, the same problem occurs.
+
+Meanwhile, is there any way to avoid this problem?
+"""]]
diff --git a/doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_2_07feedb4348f8c31176cc744c19368a1._comment b/doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_2_07feedb4348f8c31176cc744c19368a1._comment
new file mode 100644
index 000000000..b154263fe
--- /dev/null
+++ b/doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_2_07feedb4348f8c31176cc744c19368a1._comment
@@ -0,0 +1,21 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkbpbjP5j8MqWt_K4NASwv0WvB8T4rQ-pM"
+ nickname="Fabrice"
+ subject="A possible solution"
+ date="2013-11-02T14:22:13Z"
+ content="""
+I'm answering to myself :-). A possible solution to the annoying pass phrase asking with current gnupg is to use a specialized secret keyring. One first exports the secret key used for this repository in a specific keyring as follows:
+
+`gpg --export-secret-keys keyid | gpg --import --no-default-keyring --secret-keyring mygitannexsecret.gpg`
+
+This will create a keyring in $HOME/.gnupg with only the specific key.
+
+Then, in the git-remote-gcrypt shell script, gpg should be called as follows
+
+`gpg --no-default-keyring --secret-keyring mygitannexsecret.gpg -q -d ...`
+
+when decrypting the manifest in order to try only the specific key. This behavior can be easily triggered via some git configuration variable.
+
+Any comment?
+
+"""]]
diff --git a/doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_3_c2f873dffa015f1d72ad0c3921909316._comment b/doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_3_c2f873dffa015f1d72ad0c3921909316._comment
new file mode 100644
index 000000000..0ce74d767
--- /dev/null
+++ b/doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_3_c2f873dffa015f1d72ad0c3921909316._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 3"
+ date="2013-11-02T17:32:28Z"
+ content="""
+Fabrice, I've filed a bug report about this: <https://github.com/blake2-ppc/git-remote-gcrypt/issues/9>
+"""]]
diff --git a/doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_4_f8a6e4415f4fe6da14f6a3b7334bc952._comment b/doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_4_f8a6e4415f4fe6da14f6a3b7334bc952._comment
new file mode 100644
index 000000000..9b1307df4
--- /dev/null
+++ b/doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_4_f8a6e4415f4fe6da14f6a3b7334bc952._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="tanen"
+ ip="83.128.159.25"
+ subject="comment 4"
+ date="2013-11-03T22:35:07Z"
+ content="""
+The way I would want to setup git-annex (assistant) is \"Wuala/Spideroak style\": two computers with a full checkout of the repository, changes automatically being synced between them, even if the two computers are never online simultaneously, and encryption should be done locally: the (special) remote should not be able to view file listings or content.
+
+Do I understand it correctly that the gcrypt remote is the only way to make this happen? I tried to create such a setup via the webapp but failed. Adding the repository and remote (via \"Encrypt with GnuPG key\") on the first computer went OK*, but trying to enable that remote on the other computer fails: clicking enable asks me for the SSH password, but after that I just get redirected to a blank screen, with nothing to see in the logfile after the succesful call to ssh-keygen. No entry for the second computer is being added to authorized_keys on the remote.
+
+Perhaps this is because at this point the assistant is unable to actually parse the content of the encrypted repository? I tried importing the private key that was used while creating the repository on the other computer, but that made no difference.
+
+Thinking about this for a while, I believe gpg keys aren't actually particularly suited for this usecase. Even without the bug above, one would either have to awkwardly copy a private key to all hosts that are syncing to the repository; or, every time a new (or reinstalled) host wants to sync the repository, you would manually have to add the new keyid to the config and do the forced push + GCRYPT_FULL_REPACK, presumably having to reupload your entire history. Apart from this, having to backup a private key (outside of your git-annex based backups!) would be quite inconvenient.
+
+How would you feel about adding a new mode of operation where encryption is simply based on a passphrase? We could symetrically encrypt the repository with a keyfile that's stored in the repository itself, protecting the keyfile with a passphrase which - if stored at all - would be stored on the individual computers, outside of the repository.
+
+*although it erroneously used \"E0D2F776E7F674E3\" as key-id while the actual id is E7F674E3; where did that other half come from?
+"""]]
diff --git a/doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_5_11b8e82d2a234f65b58b823e71c6d6a2._comment b/doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_5_11b8e82d2a234f65b58b823e71c6d6a2._comment
new file mode 100644
index 000000000..8e767254c
--- /dev/null
+++ b/doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_5_11b8e82d2a234f65b58b823e71c6d6a2._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmNu4V5fvpLlBhaCUfXXOB0MI5NXwh8SkU"
+ nickname="Adam"
+ subject="comment 5"
+ date="2013-11-04T04:40:53Z"
+ content="""
+> How would you feel about adding a new mode of operation where encryption is simply based on a passphrase? We could symetrically encrypt the repository with a keyfile that's stored in the repository itself, protecting the keyfile with a passphrase which - if stored at all - would be stored on the individual computers, outside of the repository.
+
+Isn't that what the regular shared-encryption remote already does? Except it doesn't put a passphrase on the key, because anyone who has access to the local repo wouldn't need access to the remote one anyway.
+"""]]
diff --git a/doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_6_3e41948e1beffcf279bb05ef8e61cc07._comment b/doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_6_3e41948e1beffcf279bb05ef8e61cc07._comment
new file mode 100644
index 000000000..1a5d7f6e1
--- /dev/null
+++ b/doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_6_3e41948e1beffcf279bb05ef8e61cc07._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkbpbjP5j8MqWt_K4NASwv0WvB8T4rQ-pM"
+ nickname="Fabrice"
+ subject="comment 6"
+ date="2013-11-04T07:39:21Z"
+ content="""
+> _How would you feel about adding a new mode of operation where encryption is simply based on a passphrase? We could symetrically encrypt the repository with a keyfile that's stored in the repository itself, protecting the keyfile with a passphrase which - if stored at all - would be stored on the individual computers, outside of the repository._
+
+As Adam wrote, without a passphrase, this is the shared encryption method. With an encrypted key, this is more or less the hybrid (default) scheme. The thing is that you have to share a secret to have a encrypted remote. I don't use the webapp, so I don't know what's happening in your case, but this is how it should work with the command line tools. First Alice create the encrypted remote with her pgp key. As far as I understand, git annex creates (via gpg) a key for a symmetric cypher which is stored in the repository, encrypted with Alice public key. If Alice wants to share the repository with Bob, she must either give a key pair (so the private key also, of course) to Bob or ask Bob for his public key. In the first case, Bob can clone the repository directly (upon reception of the key pair), while in the second case, Alice has to active Bob's public key (with `git annex enableremote myremote keyid+=bobsId`). In this case, again as far as I understand, the symmetric key is reencrypted for both Alice and Bob in the repo.
+
+I understand that you tried the first case with the webapp and that it did not work. I had a similar problem documented in this [http://git-annex.branchable.com/bugs/git-annex-shell:_gcryptsetup_permission_denied](bug). Maybe you could had some comments to this bug description?
+
+> _*although it erroneously used \"E0D2F776E7F674E3\" as key-id while the actual id is E7F674E3; where did that other half come from?_
+
+This is the long id of your pgp key (16 characters as opposed to 8 for the short id).
+"""]]
diff --git a/doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_7_4ce0b26b25b336f07b2e27246cdfba3e._comment b/doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_7_4ce0b26b25b336f07b2e27246cdfba3e._comment
new file mode 100644
index 000000000..dfb2a3b92
--- /dev/null
+++ b/doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_7_4ce0b26b25b336f07b2e27246cdfba3e._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="tanen"
+ ip="83.128.159.25"
+ subject="comment 7"
+ date="2013-11-04T09:01:13Z"
+ content="""
+Thanks for the responses. Please correct me if I'm wrong, but the way I understood it, using the shared encryption scheme creates a conflict between \"changes being synced between them, even if the two computers are never online simultaneously\" and \"encryption should be done locally: the (special) remote should not be able to view file listings or content.\"
+
+- If I use shared encryption \"the webapp way\", only the file contents will be rsynced to the remote, not the repository itself. This means that different hosts are unable to sync unless they are online simultaneously, so that commit data can be sent directly between them via XMPP. In practice, this would mean my hosts are never synced (because I don't keep my home computer running when I leave for work, and vice versa)
+
+- If I use shared encryption and additionally put the repository itself on a remote, that remote would have the keys to fully decrypt the repository, that's not acceptable.
+
+Reading through the docs again, the hybrid scheme actually seems to be closer to what I want than the shared scheme, but it still has a major downside: the encryption only applies to the files itself, so in order to get \"offline sync\" there still has to be a 'remote' for the repository itself, which will contain all your metadata unencrypted. And also it would depend on the user being able to manually setup and backup a set of gpg keys instead of just memorizing a secure passphrase.
+
+@Fabrice Looks like the bug you found could very well be the cause of the problem I had; I'll try it again when a new version is available.
+"""]]
diff --git a/doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_8_49aa34d75d24a2066baa8a585bc9c2e9._comment b/doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_8_49aa34d75d24a2066baa8a585bc9c2e9._comment
new file mode 100644
index 000000000..86f3f5cad
--- /dev/null
+++ b/doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_8_49aa34d75d24a2066baa8a585bc9c2e9._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkbpbjP5j8MqWt_K4NASwv0WvB8T4rQ-pM"
+ nickname="Fabrice"
+ subject="comment 8"
+ date="2013-11-04T10:31:56Z"
+ content="""
+I think you are (at least partially) right. Of course, the only way to sync completely computers that are not on together is to use either a usb drive or a third always on computer. (I've to confess I did not understand first when I read git annex docs, shame on me ;-) If you don't want to trust completely this computer (I don't, for instance), you must :
+
+* use an encrypted git repository on this computer;
+
+* and use either hybrid or pubkey encryption.
+
+But contrarily to what you seem to imply (I hope I understand you correctly), if you do that, the third computer can still figure out a few things (usage patterns, such as where connections come from), but that's all. You've got full sync and everything is encrypted, both the git part and the files handled by the annex. This applied only to encrypted git special remotes as other remotes do not store the git part.
+"""]]
diff --git a/doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_9_3784e0c828cd60b6a9075c2d32d070cc._comment b/doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_9_3784e0c828cd60b6a9075c2d32d070cc._comment
new file mode 100644
index 000000000..24e5f5b83
--- /dev/null
+++ b/doc/tips/fully_encrypted_git_repositories_with_gcrypt/comment_9_3784e0c828cd60b6a9075c2d32d070cc._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 9"
+ date="2013-11-04T17:07:55Z"
+ content="""
+\"We could symetrically encrypt the repository with a keyfile that's stored in the repository itself\"
+
+Then you would need to decrypt the repository in order get the key you need to decrypt the repository. The impossibility of this design is why I didn't do that!
+
+It would certainly be possible to store a non-encrypted gpg key alongside the repsitory encrypted with it, but then you have to rely on a passphrase for all your security.
+
+You should file a bug report for the bug you saw..
+"""]]
diff --git a/doc/tips/googledriveannex.mdwn b/doc/tips/googledriveannex.mdwn
new file mode 100644
index 000000000..abecf10cf
--- /dev/null
+++ b/doc/tips/googledriveannex.mdwn
@@ -0,0 +1,28 @@
+googledriveannex
+=========
+
+Hook program for gitannex to use Google Drive as backend
+
+# Requirements:
+
+ python2
+
+Credit for the googledrive api interface goes to google
+
+## Install
+Clone the git repository in your home folder.
+
+ git clone git://github.com/TobiasTheViking/googledriveannex.git
+
+This should make a ~/googledriveannex folder
+
+## Setup
+Run the program once to make an empty config file
+
+ cd ~/googledriveannex; python2 googledriveannex.py
+
+## Commands for gitannex:
+
+ git config annex.googledrive-hook '/usr/bin/python2 ~/googledriveannex/googledriveannex.py'
+ git annex initremote googledrive type=hook hooktype=googledrive encryption=shared
+ git annex describe googledrive "the googledrive library"
diff --git a/doc/tips/imapannex.mdwn b/doc/tips/imapannex.mdwn
new file mode 100644
index 000000000..e9963df34
--- /dev/null
+++ b/doc/tips/imapannex.mdwn
@@ -0,0 +1,27 @@
+imapannex
+=========
+
+Hook program for gitannex to use imap as backend
+
+# Requirements:
+
+ python2
+
+# Install
+Clone the git repository in your home folder.
+
+ git clone git://github.com/TobiasTheViking/imapannex.git
+
+This should make a ~/imapannex folder
+
+# Setup
+Run the program once to set it up.
+
+ cd ~/imapannex; python2 imapannex.py
+
+# Commands for gitannex:
+
+ git config annex.imap-hook '/usr/bin/python2 ~/imapannex/imapannex.py'
+ git annex initremote imap type=hook hooktype=imap encryption=shared
+ git annex describe imap "the imap library"
+ git annex wanted imap exclude=largerthan=30mb
diff --git a/doc/tips/megaannex.mdwn b/doc/tips/megaannex.mdwn
new file mode 100644
index 000000000..8edbf4421
--- /dev/null
+++ b/doc/tips/megaannex.mdwn
@@ -0,0 +1,41 @@
+[Megaannex](https://github.com/TobiasTheViking/megaannex)
+is a hook program for git-annex to use mega.co.nz as backend
+
+# Requirements:
+
+ python2
+ requests>=0.10
+ pycrypto
+
+Credit for the mega api interface goes to:
+<https://github.com/richardasaurus/mega.py>
+
+## Install
+
+Clone the git repository in your home folder.
+
+ git clone git://github.com/TobiasTheViking/megaannex.git
+
+This should make a ~/megannex folder
+
+## Setup
+
+Run the program once to make an empty config file.
+
+ cd ~/megaannex; python2 megaannex.py
+
+Edit the megaannex.conf file. Add your mega.co.nz username, password, and folder name.
+
+## Configuring git-annex
+
+ git config annex.mega-hook '/usr/bin/python2 ~/megaannex/megaannex.py'
+
+ git annex initremote mega type=hook hooktype=mega encryption=shared
+ git annex describe mega "the mega.co.nz library"
+
+## Notes
+
+You may need to use a different command than "python2", depending
+on your python installation.
+
+-- Tobias
diff --git a/doc/tips/migrating_data_to_a_new_backend.mdwn b/doc/tips/migrating_data_to_a_new_backend.mdwn
new file mode 100644
index 000000000..b9acb8bd1
--- /dev/null
+++ b/doc/tips/migrating_data_to_a_new_backend.mdwn
@@ -0,0 +1,16 @@
+Maybe you started out using the WORM backend, and have now configured
+git-annex to use SHA1. But files you added to the annex before still
+use the WORM backend. There is a simple command that can migrate that
+data:
+
+ # git annex migrate my_cool_big_file
+ migrate my_cool_big_file (checksum...) ok
+
+You can only migrate files whose content is currently available. Other
+files will be skipped.
+
+After migrating a file to a new backend, the old content in the old backend
+will still be present. That is necessary because multiple files
+can point to the same content. The `git annex unused` subcommand can be
+used to clear up that detritus later. Note that hard links are used,
+to avoid wasting disk space.
diff --git a/doc/tips/migrating_two_seperate_disconnected_directories_to_git_annex.mdwn b/doc/tips/migrating_two_seperate_disconnected_directories_to_git_annex.mdwn
new file mode 100644
index 000000000..1209d1217
--- /dev/null
+++ b/doc/tips/migrating_two_seperate_disconnected_directories_to_git_annex.mdwn
@@ -0,0 +1,77 @@
+Scenario
+--------
+
+You are a new git-annex user. You have already files spread around many computers and wish to migrate those into git-annex, without having to recopy all files all over the place.
+
+Let's say, for example, you have a server, named `marcos` and a workstation named `angela`. You have your audio collection stored in `/srv/mp3` in `marcos` and `~/mp3` on `angela`, but only `marcos` has all the files, and `angela` only has a subset.
+
+We also assume that `marcos` has an SSH server.
+
+How do you add all this stuff to git-annex?
+
+Create the biggest git-annex repository
+---------------------------------------
+
+Start with `marcos`, with the complete directory:
+
+ cd /srv/mp3
+ git init
+ git annex init
+ git annex add .
+ git commit -m"git annex yay"
+
+This will checksum all files and add them to the `git-annex` branch of the git repository. Wait for this process to complete.
+
+Create the smaller repo and synchronise
+---------------------------------------
+
+On `angela`, we want to synchronise the git annex metadata with `marcos`. We need to initialize a git repo with `marcos` as a remote:
+
+ cd ~/mp3
+ git init
+ git remote add marcos marcos.example.com:/srv/mp3
+ git fetch marcos
+ git annex info # this should display the two repos
+ git annex add .
+
+This will, again, checksum all files and add them to git annex. Once that is done, you can verify that the files are really the same as marcos with `whereis`:
+
+ git annex whereis
+
+This should display something like:
+
+ whereis Orange Seeds/I remember.wav (2 copies)
+ b7802161-c984-4c9f-8d05-787a29c41cfe -- marcos (anarcat@marcos:/srv/mp3)
+ c2ca4a13-9a5f-461b-a44b-53255ed3e2f9 -- here (anarcat@angela)
+ ok
+
+Once you are sure things went on okay, you can synchronise this with `marcos`:
+
+ git annex sync
+
+This will push the metadata information to marcos, so it knows which files are available on `angela`. From there on, you can freely get and move files between the two repos!
+
+Importing files from a third directory
+--------------------------------------
+
+Say that some files on `angela` are actually spread out outside of the `~/mp3` directory. You can use the `git annex import` command to add those extra directories:
+
+ cd ~/mp3
+ git annex import ~/music/
+
+(!) Be careful that `~/music` is not a git-annex repository, or this will [[destroy it!|bugs/git annex import destroys a fellow git annex repository]].
+
+Deleting deleted files
+----------------------
+
+It is quite possible some files were removed (or renamed!) on `marcos` but not on `angela`, since it was synchronised only some time ago. A good way to find out about those files is to use the `--not --in` argument, for example, on `angela`:
+
+ git annex whereis --in here --not --in marcos
+
+This will show files that are on `angela` and not on `marcos`. They could be new files that were only added on `angela`, so be careful! A manual analysis is necessary, but let's say you are certain those files are not relevant anymore, you can delete them from `angela`:
+
+ git annex drop <file>
+
+If the file is a renamed or modified version from the original, you may need to use `--force`, but be careful! If you delete the wrong file, it will be lost forever!
+
+> (!) Maybe this wouldn't happen with [[direct mode]] and an fsck? --[[anarcat]]
diff --git a/doc/tips/offline_archive_drives.mdwn b/doc/tips/offline_archive_drives.mdwn
new file mode 100644
index 000000000..eff123e8b
--- /dev/null
+++ b/doc/tips/offline_archive_drives.mdwn
@@ -0,0 +1,69 @@
+After you've used git-annex for a while, you will have data in your repository
+that you don't want to keep in the limited disk space of a laptop or a server,
+but that you don't want to entirely delete.
+
+This is where git-annex's support for offline archive drives shines.
+You can move old files to an archive drive, which can be kept offline if
+it's not practical to keep it spinning. Better, you can move old files to
+two or more archive drives, in case one of them later fails to spin up.
+(One consideration when [[future_proofing]] your archive.)
+
+To set up an archive drive, you can take any removable drive, format
+it with a filesystem you'll be able to read some years later, and then follow
+the [[walkthrough]] to set up a repository on it that is a git remote of
+the repository in your computer you want to archive. In short:
+
+ cd /media/archive
+ git clone ~/annex
+ cd ~/annex
+ git remote add archivedrive /media/archive/annex
+ git annex sync archivedrive
+
+Don't forget to tell git-annex this is an archive drive (or perhaps a backup
+drive). Also, give the drive a description that matches something you write on
+its label, so you can find it later:
+
+ git annex group archivedrive archive
+ git annex wanted archivedrive standard
+ git annex describe archivedrive "my first archive drive (SATA)"
+
+Or you can use the assistant to set up the drive for you.
+(Nice video tutorial here: [[videos/git-annex_assistant_archiving]])
+
+(Keeping the archive drive in an offsite location? Consider encrypting
+it! See [[fully_encrypted_git_repositories_with_gcrypt]].)
+
+Then, when the archive drive is plugged in, you can easily copy files to
+it:
+
+ cd ~/annex
+ git-annex copy --auto --to archivedrive
+
+Or, if you're using the assistant, it will automatically notice when the drive
+gets plugged in and copy files that need to be archived.
+
+When you want to get rid of the local file, leaving only the copy on the
+archive, you can just:
+
+ git annex drop file
+
+The archive drive has to be plugged in for this to work, so git-annex
+can verify it still has the file. If you had configured git-annex to
+always store 2 [[copies]], it will need 2 archive drives plugged in.
+You may find it useful to configure a [[trust]] setting for the drive to
+avoid needing to haul it out of storage to drop a file.
+
+Now the really nice thing. When your archive drive gets filled up, you
+can simply remove it, store it somewhere safe, and replace it with a new
+drive, which can be mounted at the same location for simplicity. Set up
+the new drive the same way described above, and use it to archive even more
+files.
+
+Finally, when you want to access one of the files you archived, you can
+just ask for it:
+
+ git annex get file
+
+If necessary git-annex will tell you which archive drive you need to
+pull out of storage to get the file back. This is where the description
+you entered earlier comes in handy.
diff --git a/doc/tips/offline_archive_drives/comment_1_3d4fdf42191a9d81434d00f51c3609ff._comment b/doc/tips/offline_archive_drives/comment_1_3d4fdf42191a9d81434d00f51c3609ff._comment
new file mode 100644
index 000000000..5855b0f7a
--- /dev/null
+++ b/doc/tips/offline_archive_drives/comment_1_3d4fdf42191a9d81434d00f51c3609ff._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkC0W3ZQERUaTkHoks6k68Tsp1tz510nGo"
+ nickname="Georg"
+ subject="git annex sync"
+ date="2013-10-06T08:59:24Z"
+ content="""
+Shouldn't it be
+git annex sync archivedrive
+instead of
+git annex sync archive
+in the first examples. As the name of the remote is \"archivedrive\", IMO \"sync\" should be called with the name of the remote.
+"""]]
diff --git a/doc/tips/offline_archive_drives/comment_2_864c752aa8d064791a4b14dbbe2e6882._comment b/doc/tips/offline_archive_drives/comment_2_864c752aa8d064791a4b14dbbe2e6882._comment
new file mode 100644
index 000000000..3ff074ff3
--- /dev/null
+++ b/doc/tips/offline_archive_drives/comment_2_864c752aa8d064791a4b14dbbe2e6882._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkC0W3ZQERUaTkHoks6k68Tsp1tz510nGo"
+ nickname="Georg"
+ subject="git annex copy not working"
+ date="2013-10-06T10:18:10Z"
+ content="""
+Is the feature \"git-annex copy --auto --to usb\" working?
+I have created a backup repo on my usb drive but when I call \"git-annex copy --auto --to usb\" nothing happens.
+
+I have called \"git annex group usb backup\" and \"git annex sync usb\" to set up the repo.
+
+What is the correct way to get the data out to the backup repo?
+
+Best regards, Georg
+"""]]
diff --git a/doc/tips/offline_archive_drives/comment_3_7be2ccaf70c9ecfc9a34384e0e31f490._comment b/doc/tips/offline_archive_drives/comment_3_7be2ccaf70c9ecfc9a34384e0e31f490._comment
new file mode 100644
index 000000000..cd5888009
--- /dev/null
+++ b/doc/tips/offline_archive_drives/comment_3_7be2ccaf70c9ecfc9a34384e0e31f490._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.243"
+ subject="thanks for your checking.."
+ date="2013-10-06T17:04:24Z"
+ content="""
+The example was missing a preferred content setting, without which --auto doesn't copy anything unless needed to satisfy numcopies:
+
+git annex wanted archivedrive standard
+"""]]
diff --git a/doc/tips/owncloudannex.mdwn b/doc/tips/owncloudannex.mdwn
new file mode 100644
index 000000000..ad40c67e3
--- /dev/null
+++ b/doc/tips/owncloudannex.mdwn
@@ -0,0 +1,28 @@
+owncloudannex
+=========
+
+Hook program for gitannex to use owncloud as backend
+
+# Requirements:
+
+ python2
+
+Credit for the Owncloud api interface goes to me.
+
+# Install
+Clone the git repository in your home folder.
+
+ git clone git://github.com/TobiasTheViking/owncloudannex.git
+
+This should make a ~/owncloudannex folder
+
+# Setup
+Run the program once to set it up.
+
+ cd ~/owncloudannex; python2 owncloudannex.py
+
+# Commands for gitannex:
+
+ git config annex.owncloud-hook '/usr/bin/python2 ~/owncloudannex/owncloudannex.py'
+ git annex initremote owncloud type=hook hooktype=owncloud encryption=shared
+ git annex describe owncloud "the owncloud library"
diff --git a/doc/tips/owncloudannex/comment_1_129652308c3c499462828dcaf8e747a4._comment b/doc/tips/owncloudannex/comment_1_129652308c3c499462828dcaf8e747a4._comment
new file mode 100644
index 000000000..47e33042e
--- /dev/null
+++ b/doc/tips/owncloudannex/comment_1_129652308c3c499462828dcaf8e747a4._comment
@@ -0,0 +1,40 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkQvRLq7nMMEGoEKuYx9oaf67IC0nZfmVI"
+ nickname="chung yan"
+ subject="owncloud hook exited nonzero"
+ date="2013-07-10T05:03:47Z"
+ content="""
+hi
+
+I got the above message, and cannot sync to my owncloud. Here is the log file i had:
+
+>[2013-07-10 12:30:31 HKT] main: starting assistant version 4.20130627
+(scanning...) [2013-07-10 12:30:31 HKT] Watcher: Performing startup scan
+(started...) git-annex: Daemon is already running.
+git-annex: Daemon is already running.
+[2013-07-10 12:44:04 HKT] Committer: Adding sync2Servers.sh
+
+>add syncByRsync/sync2Servers.sh (checksum...) [2013-07-10 12:44:04 HKT] Committer: Committing changes to git
+(gpg)
+
+>owncloud hook exited nonzero!
+>git-annex: Daemon is already running.
+[2013-07-10 12:51:07 HKT] main: Syncing with owncloud
+
+>owncloud hook exited nonzero!
+>[2013-07-10 12:53:10 HKT] Committer: Adding 2 files
+ok
+(Recording state in git...)
+(Recording state in git...)
+add syncByRsync/DSCN1810.JPG (checksum...) ok
+add syncByRsync/DSCN1810.JPG (checksum...) [2013-07-10 12:53:10 HKT] Committer: Committing changes to git
+
+>owncloud hook exited nonzero!
+[2013-07-10 12:53:50 HKT] main: Syncing with owncloud
+ owncloud hook exited nonzero!
+ owncloud hook exited nonzero!
+
+thanks
+
+yan
+"""]]
diff --git a/doc/tips/owncloudannex/comment_2_38604990368666f654d41891ba99ac61._comment b/doc/tips/owncloudannex/comment_2_38604990368666f654d41891ba99ac61._comment
new file mode 100644
index 000000000..6ea0b033c
--- /dev/null
+++ b/doc/tips/owncloudannex/comment_2_38604990368666f654d41891ba99ac61._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmLB39PC89rfGaA8SwrsnB6tbumezj-aC0"
+ nickname="Tobias"
+ subject="comment 2"
+ date="2013-07-10T08:21:39Z"
+ content="""
+Personally i've only seen that when the server ran out of space. But lets see what is going on.
+
+Please run this command
+
+git config annex.owncloud-hook '/usr/bin/python2 ~/owncloudannex/owncloudannex.py --dbglevel 1 --stderr'
+
+And then replicate the error. It should give me some debug information to work with.
+
+"""]]
diff --git a/doc/tips/owncloudannex/comment_3_1bfd290d00d6536da7d31818db46f8ec._comment b/doc/tips/owncloudannex/comment_3_1bfd290d00d6536da7d31818db46f8ec._comment
new file mode 100644
index 000000000..f7e3f0ee4
--- /dev/null
+++ b/doc/tips/owncloudannex/comment_3_1bfd290d00d6536da7d31818db46f8ec._comment
@@ -0,0 +1,87 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkQvRLq7nMMEGoEKuYx9oaf67IC0nZfmVI"
+ nickname="chung yan"
+ subject="comment 3"
+ date="2013-07-10T08:46:27Z"
+ content="""
+hi Tobias
+
+Thanks your suggestion for list of my error log, here it is:
+
+[2013-07-10 16:27:58 HKT] main: starting assistant version 4.20130627
+(scanning...) [2013-07-10 16:27:58 HKT] Watcher: Performing startup scan
+(started...) [2013-07-10 16:28:14 HKT] Committer: Adding 2 files
+
+add syncByRsync/sync2Servers.sh (checksum...) ok
+add syncByRsync/sync2Servers.sh (checksum...) [2013-07-10 16:28:14 HKT] Committer: Committing changes to git
+[2013-07-10 16:31:12 HKT] Watcher: add direct DSCN1810.JPG
+[2013-07-10 16:31:12 HKT] read: lsof [\"-F0can\",\"+d\",\"/home/yan/annex_testing/.git/annex/tmp/\"]
+[2013-07-10 16:31:12 HKT] Committer: Adding DSCN1810.JPG
+ok
+(Recording state in git...)
+(Recording state in git...)
+add DSCN1810.JPG [2013-07-10 16:31:12 HKT](checksum...) Watcher: add direct DSCN1810.JPG
+[2013-07-10 16:31:12 HKT] read: sha256sum [\"/home/yan/annex_testing/.git/annex/tmp/DSCN181012023.JPG\"]
+
+ DSCN1810.JPG changed while it was being added
+[2013-07-10 16:31:12 HKT] Committer: delaying commit of 1 changes
+[2013-07-10 16:31:13 HKT] read: lsof [\"-F0can\",\"+d\",\"/home/yan/annex_testing/.git/annex/tmp/\"]
+[2013-07-10 16:31:13 HKT] Committer: Adding 2 files
+failed
+add DSCN1810.JPG (checksum...) [2013-07-10 16:31:13 HKT] read: sha256sum [\"/home/yan/annex_testing/.git/annex/tmp/DSCN181012023.JPG\"]
+[2013-07-10 16:31:13 HKT] chat: git [\"--git-dir=/home/yan/annex_testing/.git\",\"--work-tree=/home/yan/annex_testing\",\"hash-object\",\"-t\",\"blob\",\"-w\",\"--stdin\",\"--no-filters\"]
+ok
+add DSCN1810.JPG (checksum...) [2013-07-10 16:31:13 HKT] read: sha256sum [\"/home/yan/annex_testing/.git/annex/tmp/DSCN181012024.JPG\"]
+[2013-07-10 16:31:13 HKT] chat: git [\"--git-dir=/home/yan/annex_testing/.git\",\"--work-tree=/home/yan/annex_testing\",\"hash-object\",\"-t\",\"blob\",\"-w\",\"--stdin\",\"--no-filters\"]
+[2013-07-10 16:31:13 HKT] Committer: committing 2 changes
+[2013-07-10 16:31:13 HKT] Committer: Committing changes to git
+[2013-07-10 16:31:13 HKT] feed: git [\"--git-dir=/home/yan/annex_testing/.git\",\"--work-tree=/home/yan/annex_testing\",\"update-index\",\"-z\",\"--index-info\"]
+[2013-07-10 16:31:13 HKT] read: git [\"--git-dir=/home/yan/annex_testing/.git\",\"--work-tree=/home/yan/annex_testing\",\"commit\",\"--allow-empty-message\",\"--no-edit\",\"-m\",\"\",\"--quiet\",\"--no-verify\"]
+[2013-07-10 16:31:13 HKT] Committer: queued Upload UUID \"df02d32a-7e3a-4e12-a417-7f1d1a1cf1a6\" DSCN1810.JPG Nothing : new file created
+[2013-07-10 16:31:13 HKT] chat: git [\"--git-dir=/home/yan/annex_testing/.git\",\"--work-tree=/home/yan/annex_testing\",\"hash-object\",\"-w\",\"--stdin-paths\",\"--no-filters\"]
+[2013-07-10 16:31:13 HKT] feed: git [\"--git-dir=/home/yan/annex_testing/.git\",\"--work-tree=/home/yan/annex_testing\",\"update-index\",\"-z\",\"--index-info\"]
+[2013-07-10 16:31:13 HKT] read: git [\"--git-dir=/home/yan/annex_testing/.git\",\"--work-tree=/home/yan/annex_testing\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+[2013-07-10 16:31:13 HKT] read: git [\"--git-dir=/home/yan/annex_testing/.git\",\"--work-tree=/home/yan/annex_testing\",\"write-tree\"]
+[2013-07-10 16:31:13 HKT] chat: git [\"--git-dir=/home/yan/annex_testing/.git\",\"--work-tree=/home/yan/annex_testing\",\"commit-tree\",\"a8337a989b58b29eee5fd2fa7a4c0b8ec45d5e59\",\"-p\",\"refs/heads/git-annex\"]
+[2013-07-10 16:31:13 HKT] call: git [\"--git-dir=/home/yan/annex_testing/.git\",\"--work-tree=/home/yan/annex_testing\",\"update-ref\",\"refs/heads/git-annex\",\"267bf35da4d9abe5ed7fe82ea5df8a8df2ddf940\"]
+[2013-07-10 16:31:13 HKT] read: git [\"--git-dir=/home/yan/annex_testing/.git\",\"--work-tree=/home/yan/annex_testing\",\"symbolic-ref\",\"HEAD\"]
+[2013-07-10 16:31:13 HKT] read: git [\"--git-dir=/home/yan/annex_testing/.git\",\"--work-tree=/home/yan/annex_testing\",\"show-ref\",\"refs/heads/master\"]
+[2013-07-10 16:31:13 HKT] Transferrer: Transferring: Upload UUID \"df02d32a-7e3a-4e12-a417-7f1d1a1cf1a6\" DSCN1810.JPG Nothing
+[2013-07-10 16:31:13 HKT] read: git [\"--git-dir=/home/yan/annex_testing/.git\",\"--work-tree=/home/yan/annex_testing\",\"show-ref\",\"git-annex\"]
+[2013-07-10 16:31:13 HKT] call: git-annex [\"transferkeys\",\"--readfd\",\"46\",\"--writefd\",\"36\"]
+[2013-07-10 16:31:13 HKT] read: git [\"--git-dir=/home/yan/annex_testing/.git\",\"--work-tree=/home/yan/annex_testing\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+[2013-07-10 16:31:13 HKT] read: git [\"--git-dir=/home/yan/annex_testing/.git\",\"--work-tree=/home/yan/annex_testing\",\"log\",\"refs/heads/git-annex..267bf35da4d9abe5ed7fe82ea5df8a8df2ddf940\",\"--oneline\",\"-n1\"]
+[2013-07-10 16:31:13 HKT] read: git [\"--git-dir=/home/yan/annex_testing/.git\",\"--work-tree=/home/yan/annex_testing\",\"show-ref\",\"git-annex\"]
+[2013-07-10 16:31:13 HKT] read:[2013-07-10 16:31:13 HKT] read: git [\"--git-dir=/home/yan/annex_testing/.git\",\"--work-tree=/home/yan/annex_testing\",\"ls-tree\",\"-z\",\"--\",\"refs/heads/git-annex\",\"uuid.log\",\"remote.log\",\"trust.log\",\"group.log\",\"preferred-content.log\"]
+ git [\"--git-dir=/home/yan/annex_testing/.git\",\"--work-tree=/home/yan/annex_testing\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+[2013-07-10 16:31:13 HKT] read: git [\"--git-dir=/home/yan/annex_testing/.git\",\"--work-tree=/home/yan/annex_testing\",\"log\",\"refs/heads/git-annex..267bf35da4d9abe5ed7fe82ea5df8a8df2ddf940\",\"--oneline\",\"-n1\"]
+[2013-07-10 16:31:13 HKT] chat: git [\"--git-dir=/home/yan/annex_testing/.git\",\"--work-tree=/home/yan/annex_testing\",\"cat-file\",\"--batch\"]
+(gpg) [2013-07-10 16:31:13 HKT] TransferWatcher: transfer starting: Upload UUID \"df02d32a-7e3a-4e12-a417-7f1d1a1cf1a6\" DSCN1810.JPG Nothing
+[2013-07-10 16:31:13 HKT] chat: gpg [\"--batch\",\"--no-tty\",\"--use-agent\",\"--quiet\",\"--trust-model\",\"always\",\"--batch\",\"--passphrase-fd\",\"48\",\"--symmetric\",\"--force-mdc\"]
+[2013-07-10 16:31:14 HKT] call: sh [\"-c\",\"/usr/bin/python2 /home/yan/annex/SocialBusiness/Resources/Infrastructure/Computer_Tools/Records/AsusU24/owncloudannex/owncloudannex.py --dbglevel 1 --stderr\"]
+
+ 16:31:16 [owncloudannex-0.1.1] <module> : 'START'
+ 16:31:16 [owncloudannex-0.1.1] main : 'ARGS: 'ANNEX_ACTION=store ANNEX_KEY=GPGHMACSHA1--0179fbbf559d5c25cf69b4e92025ff1f007d4f1f ANNEX_HASH_1=fp ANNEX_HASH_2=23 ANNEX_FILE=/home/yan/annex_testing/.git/annex/tmp/GPGHMACSHA1--0179fbbf559d5c25cf69b4e92025ff1f007d4f1f /home/yan/annex/SocialBusiness/Resources/Infrastructure/Computer_Tools/Records/AsusU24/owncloudannex/owncloudannex.py --dbglevel 1 --stderr''
+ 16:31:16 [owncloudannex-0.1.1] readFile : ''/home/yan/annex/SocialBusiness/Resources/Infrastructure/Computer_Tools/Records/AsusU24/owncloudannex/owncloudannex.conf' - 'r''
+ 16:31:16 [owncloudannex-0.1.1] readFile : 'Done'
+ 16:31:16 [owncloudannex-0.1.1] login : ''
+ 16:31:16 [owncloudannex-0.1.1] login : 'Using base: wingyan.no-ip.org - {'Authorization': 'Basic Y2h1bmd5YW41QGdtYWlsLmNvbTp5YW5fd2lraQ=='}'
+ 16:31:16 [owncloudannex-0.1.1] login : 'res: <davlib.DAV instance at 0x12915f0>'
+ 16:31:16 [owncloudannex-0.1.1] findInFolder : 'u'gitannex'(<type 'unicode'>) - '/'(<type 'str'>)'
+ 16:31:17 [owncloudannex-0.1.1] findInFolder : 'propfind: /owncloud/remote.php/webdav - '<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<d:error xmlns:d=\"DAV:\" xmlns:s=\"http://sabredav.org/ns\">\n <s:exception>Sabre_DAV_Exception_NotAuthenticated</s:exception>\n <s:message>Username or password does not match</s:message>\n <s:sabredav-version>1.7.6</s:sabredav-version>\n</d:error>\n''
+ 16:31:17 [owncloudannex-0.1.1] findInFolder : 'Failure'
+ 16:31:17 [owncloudannex-0.1.1] createFolder : '/gitannex'
+ 16:31:18 [owncloudannex-0.1.1] createFolder : 'Failure: 401 - '<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<d:error xmlns:d=\"DAV:\" xmlns:s=\"http://sabredav.org/ns\">\n <s:exception>Sabre_DAV_Exception_NotAuthenticated</s:exception>\n <s:message>Username or password does not match</s:message>\n <s:sabredav-version>1.7.6</s:sabredav-version>\n</d:error>\n''
+
+
+ owncloud hook exited nonzero!
+[2013-07-10 16:31:18 HKT] TransferWatcher: transfer finishing: Transfer {transferDirection = Upload, transferUUID = UUID \"df02d32a-7e3a-4e12-a417-7f1d1a1cf1a6\", transferKey = Key {keyName = \"911ba6148fbcbe4afe53772f1216b8204f403ed4ee06cb90c3c3ac25e56d9402.JPG\", keyBackendName = \"SHA256E\", keySize = Just 1893431, keyMtime = Nothing}}
+
+I figured out it is a *Username or password does not match*, and i saw the content of owncloudannex.conf as \"uname\": \"myGmail@gmail.com\", but i quickly saw my WebDAV login to owncloud as my user name, not gmail address, so i changed this \"uname\": \"my_normal_user_name_not_gmail_acc\" inside owncloudannex.conf. Finally, i got it work. So, i think, user name should not be a gmail address, should be owncloud login user name.
+
+Another issue, i had a look into /WebDAV.../gitannex/, it is git repos. file, for my user opinion, it is better that it is a real file content that we can see the file(such as photos) by owncloud web client directly, rather that owncloud is a file server to keep git repos only.
+
+Thanks
+
+yan
+"""]]
diff --git a/doc/tips/owncloudannex/comment_4_492b6922a7c5bb5464fedb46b0c5303b._comment b/doc/tips/owncloudannex/comment_4_492b6922a7c5bb5464fedb46b0c5303b._comment
new file mode 100644
index 000000000..c7a0875df
--- /dev/null
+++ b/doc/tips/owncloudannex/comment_4_492b6922a7c5bb5464fedb46b0c5303b._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmLB39PC89rfGaA8SwrsnB6tbumezj-aC0"
+ nickname="Tobias"
+ subject="comment 4"
+ date="2013-07-10T08:54:13Z"
+ content="""
+Hm, an error like that it really should print without the need of debug information. I'll look into it.
+
+And if you want the real file content, not encrypted, just change \"shared\" to \"none\" in the line:
+
+git annex initremote owncloud type=hook hooktype=owncloud encryption=shared
+
+I'm not sure if you can change this after you initialized the remote though. And also, the folder structure and filenames will be as you see them now on the owncloud. I'd need some more data from gitannex to make it show the real directory structure. But that doesn't seem feasible.
+
+Why would you even want the data unencrypted on owncloud anyways? i mean on flickr, or googledocs, i kinda get it. but for owncloud?
+
+"""]]
diff --git a/doc/tips/owncloudannex/comment_5_1d48ac08714fadcb06d874570d745bd8._comment b/doc/tips/owncloudannex/comment_5_1d48ac08714fadcb06d874570d745bd8._comment
new file mode 100644
index 000000000..170e8b857
--- /dev/null
+++ b/doc/tips/owncloudannex/comment_5_1d48ac08714fadcb06d874570d745bd8._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkQvRLq7nMMEGoEKuYx9oaf67IC0nZfmVI"
+ nickname="chung yan"
+ subject="comment 5"
+ date="2013-07-10T09:43:55Z"
+ content="""
+hi Tobias
+
+thanks your sharing, i am still in have a trial of git-annex, so i do not yet have real data on the server, so i just del. all and re-create both client and server repos in owncloud, i can got what you said, and see my photo.
+
+Actually, i am studying git-annex. 1) It can syncs the data from my client computer to server. 2) i would like that other and anywhere computers through browser can view my server data which do not need to download all data into a new client. So my original goal is i can have a web to display the content of my files, and see owncloud have a nice web.
+
+Regarding to GDoc, flickr, etc. they have space limitation, so i install owncloud as my own computer. I also see the <http://git-annex.branchable.com/design/assistant/partial_content/>, but it is not yet at roadmap.
+
+thanks
+"""]]
diff --git a/doc/tips/owncloudannex/comment_6_65959f49a2f56bffd6fe48670c0c8d5a._comment b/doc/tips/owncloudannex/comment_6_65959f49a2f56bffd6fe48670c0c8d5a._comment
new file mode 100644
index 000000000..7b10068c5
--- /dev/null
+++ b/doc/tips/owncloudannex/comment_6_65959f49a2f56bffd6fe48670c0c8d5a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmLB39PC89rfGaA8SwrsnB6tbumezj-aC0"
+ nickname="Tobias"
+ subject="comment 6"
+ date="2013-07-10T09:50:14Z"
+ content="""
+A 1 terabyte limit(for flickr) should be enough for most people. No?
+"""]]
diff --git a/doc/tips/owncloudannex/comment_7_7482002991672ef67836bae43b8d0be8._comment b/doc/tips/owncloudannex/comment_7_7482002991672ef67836bae43b8d0be8._comment
new file mode 100644
index 000000000..56e71276d
--- /dev/null
+++ b/doc/tips/owncloudannex/comment_7_7482002991672ef67836bae43b8d0be8._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkQvRLq7nMMEGoEKuYx9oaf67IC0nZfmVI"
+ nickname="chung yan"
+ subject="comment 7"
+ date="2013-07-10T09:56:54Z"
+ content="""
+i have not got this 1 terabyte limit from flick before. I will have a look. I still consider some my own data, it is better to keep at my own server.
+"""]]
diff --git a/doc/tips/powerful_file_matching.mdwn b/doc/tips/powerful_file_matching.mdwn
new file mode 100644
index 000000000..47f8c8a64
--- /dev/null
+++ b/doc/tips/powerful_file_matching.mdwn
@@ -0,0 +1,36 @@
+git-annex has a powerful syntax for making it act on only certain files.
+
+The simplest thing is to exclude some files, using wild cards:
+
+ git annex get --exclude '*.mp3' --exclude '*.ogg'
+
+But you can also exclude files that git-annex's [[location_tracking]]
+information indicates are present in a given repository. For example,
+if you want to populate newarchive with files, but not those already
+on oldarchive, you could do it like this:
+
+ git annex copy --not --in oldarchive --to newarchive
+
+Without the --not, --in makes it act on files that *are* in the specified
+repository. So, to remove files that are on oldarchive:
+
+ git annex drop --in oldarchive
+
+Or maybe you're curious which files have a lot of copies, and then
+also want to know which files have only one copy:
+
+ git annex find --copies 7
+ git annex find --not --copies 2
+
+The above are the simple examples of specifying what files git-annex
+should act on. But you can specify anything you can dream up by combining
+the things above, with --and --or -( and -). Those last two strange-looking
+options are parentheses, for grouping other options. You will probably
+have to escape them from your shell.
+
+Here are the mp3 files that are in either of two repositories, but have
+less than 3 copies:
+
+ git annex find --not --exclude '*.mp3' --and \
+ -\( --in usbdrive --or --in archive -\) --and \
+ --not --copies 3
diff --git a/doc/tips/recover_data_from_lost+found.mdwn b/doc/tips/recover_data_from_lost+found.mdwn
new file mode 100644
index 000000000..48ef2a1d7
--- /dev/null
+++ b/doc/tips/recover_data_from_lost+found.mdwn
@@ -0,0 +1,19 @@
+Suppose something goes wrong, and fsck puts all the files in lost+found.
+It's actually very easy to recover from this disaster.
+
+First, check out the git repository again. Then, in the new checkout:
+
+ $ mkdir recovered-content
+ $ sudo mv ../lost+found/* recovered-content
+ $ sudo chown you:you recovered-content
+ $ chmod -R u+w recovered-content
+ $ git annex add recovered-content
+ $ git rm recovered-content
+ $ git commit -m "recovered some content"
+ $ git annex fsck
+
+The way that works is that when git-annex adds the same content that was in
+the repository before, all the old links to that content start working
+again. This works particularly well if the SHA* backends are used, but even
+with the default backend it will work pretty well, as long as fsck
+preserved the modification time of the files.
diff --git a/doc/tips/recovering_from_a_corrupt_git_repository.mdwn b/doc/tips/recovering_from_a_corrupt_git_repository.mdwn
new file mode 100644
index 000000000..084f76852
--- /dev/null
+++ b/doc/tips/recovering_from_a_corrupt_git_repository.mdwn
@@ -0,0 +1,17 @@
+I have found this the most reliable way to recover from a corrupt git repository. I have had a lot of them lately, there might be a regression in btrfs in Ubuntu's Linux 3.8.0-33 (!).
+
+1. Create a clone of a known good repository.
+2. Add the clone as an object alternate to the broken repository.
+3. Do a `git-repack -a -d` to lift the external objects into repo-local packs.
+4. Remove the clone
+
+[[!format sh """
+$ cd /tmp/
+$ git clone good-host:/path/to/good-repo
+$ cd /home/user/broken-repo
+$ echo /tmp/good-repo/.git/objects/ > .git/objects/info/alternates
+$ git repack -a -d
+$ rm -rf /tmp/good-repo
+"""]]
+
+... and push early, push often. ;-)
diff --git a/doc/tips/recovering_from_a_corrupt_git_repository/comment_1_f5827be97f78dbae113a5ba0c9ced896._comment b/doc/tips/recovering_from_a_corrupt_git_repository/comment_1_f5827be97f78dbae113a5ba0c9ced896._comment
new file mode 100644
index 000000000..d212e23f3
--- /dev/null
+++ b/doc/tips/recovering_from_a_corrupt_git_repository/comment_1_f5827be97f78dbae113a5ba0c9ced896._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.246"
+ subject="comment 1"
+ date="2013-11-11T16:01:59Z"
+ content="""
+Better, since version 4.20131024, `git annex repair` can be run to automatically do this, and more. (Including recovering data in corrupt git repositories that you forgot to push!)
+"""]]
diff --git a/doc/tips/recovering_from_a_corrupt_git_repository/comment_2_e98df7275bb032308bb87e3607bdde32._comment b/doc/tips/recovering_from_a_corrupt_git_repository/comment_2_e98df7275bb032308bb87e3607bdde32._comment
new file mode 100644
index 000000000..c018c4ca5
--- /dev/null
+++ b/doc/tips/recovering_from_a_corrupt_git_repository/comment_2_e98df7275bb032308bb87e3607bdde32._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://id.clacke.se/"
+ nickname="clacke"
+ subject="comment 2"
+ date="2013-11-12T16:14:50Z"
+ content="""
+I am using git-annex 20131106 and I tried `git annex repair` first. It seems git is making assumptions that if I have object A then I must have object B that A depends on. Or maybe it freaks out because the object is not missing, just full of zeroes. I haven't done any analysis on exactly what situation causes this. When I have time, I will.
+"""]]
diff --git a/doc/tips/recovering_from_a_corrupt_git_repository/comment_3_11bece6dfac090edbcd783b266c482a3._comment b/doc/tips/recovering_from_a_corrupt_git_repository/comment_3_11bece6dfac090edbcd783b266c482a3._comment
new file mode 100644
index 000000000..63f443a31
--- /dev/null
+++ b/doc/tips/recovering_from_a_corrupt_git_repository/comment_3_11bece6dfac090edbcd783b266c482a3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://id.clacke.se/"
+ nickname="clacke"
+ subject="comment 3"
+ date="2013-11-12T16:17:42Z"
+ content="""
+Luckily, so far the objects getting corrupted have been in past commits (maybe only in packfiles?), not the latest ones, so I have been able to recover even though HEAD has been unique to the local repo.
+"""]]
diff --git a/doc/tips/recovering_from_a_corrupt_git_repository/comment_4_86e99017f7585ac2f76753051214637e._comment b/doc/tips/recovering_from_a_corrupt_git_repository/comment_4_86e99017f7585ac2f76753051214637e._comment
new file mode 100644
index 000000000..8d454fc3e
--- /dev/null
+++ b/doc/tips/recovering_from_a_corrupt_git_repository/comment_4_86e99017f7585ac2f76753051214637e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://id.clacke.se/"
+ nickname="clacke"
+ subject="comment 4"
+ date="2013-11-12T17:10:06Z"
+ content="""
+Hm. This is bad. My hunch that btrfs was the culprit seems to have been wrong. After having switched things around, along with lots of `git annex sync` in various places, I now have a corrupt repo on ext4. It must be git or git-annex that does something wrong.
+"""]]
diff --git a/doc/tips/recovering_from_a_corrupt_git_repository/comment_6_c8953732ce353cdf0c4fb81ddc98c04a._comment b/doc/tips/recovering_from_a_corrupt_git_repository/comment_6_c8953732ce353cdf0c4fb81ddc98c04a._comment
new file mode 100644
index 000000000..eeb3ceef2
--- /dev/null
+++ b/doc/tips/recovering_from_a_corrupt_git_repository/comment_6_c8953732ce353cdf0c4fb81ddc98c04a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.246"
+ subject="comment 6"
+ date="2013-11-12T18:10:21Z"
+ content="""
+If you can reliably corrupt a git repository, it's highly likely your hardware (disk or memory) is broken.
+"""]]
diff --git a/doc/tips/recovering_from_a_corrupt_git_repository/comment_6_d0da84df0241dc6ccf0aa0c7598917df._comment b/doc/tips/recovering_from_a_corrupt_git_repository/comment_6_d0da84df0241dc6ccf0aa0c7598917df._comment
new file mode 100644
index 000000000..16b2329b9
--- /dev/null
+++ b/doc/tips/recovering_from_a_corrupt_git_repository/comment_6_d0da84df0241dc6ccf0aa0c7598917df._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://id.clacke.se/"
+ nickname="clacke"
+ subject="comment 6"
+ date="2013-11-12T17:22:01Z"
+ content="""
+This is my symptom too: [[forum/Git annex 'corrupting' itself]]
+"""]]
diff --git a/doc/tips/recovering_from_a_corrupt_git_repository/comment_7_addf49556e4c33d55a41c393f519d0a4._comment b/doc/tips/recovering_from_a_corrupt_git_repository/comment_7_addf49556e4c33d55a41c393f519d0a4._comment
new file mode 100644
index 000000000..5047bcca4
--- /dev/null
+++ b/doc/tips/recovering_from_a_corrupt_git_repository/comment_7_addf49556e4c33d55a41c393f519d0a4._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.246"
+ subject="comment 7"
+ date="2013-11-12T18:12:49Z"
+ content="""
+> I tried git annex repair first. It seems git is making assumptions that if I have object A then I must have object B that A depends on. Or maybe it freaks out because the object is not missing
+
+`git annex repair` is supposed to deal with these situations. If it fails to fix such a broken repository, please file a detailed bug report, ideally with a link to a copy of the repository.
+"""]]
diff --git a/doc/tips/recovering_from_a_corrupt_git_repository/comment_8_505a2fc2b841fe8eb419801f923ef35f._comment b/doc/tips/recovering_from_a_corrupt_git_repository/comment_8_505a2fc2b841fe8eb419801f923ef35f._comment
new file mode 100644
index 000000000..78144b893
--- /dev/null
+++ b/doc/tips/recovering_from_a_corrupt_git_repository/comment_8_505a2fc2b841fe8eb419801f923ef35f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://id.clacke.se/"
+ nickname="clacke"
+ subject="comment 8"
+ date="2013-11-14T10:00:20Z"
+ content="""
+Several machines started showing this behavior around 4.20131106 or 4.20131101. I will find a way to reproduce when I can find the time.
+"""]]
diff --git a/doc/tips/replacing_Sparkleshare_or_dvcs-autosync_with_the_assistant.mdwn b/doc/tips/replacing_Sparkleshare_or_dvcs-autosync_with_the_assistant.mdwn
new file mode 100644
index 000000000..4363dc85d
--- /dev/null
+++ b/doc/tips/replacing_Sparkleshare_or_dvcs-autosync_with_the_assistant.mdwn
@@ -0,0 +1,41 @@
+Sparkleshare and dvcs-autosync are tools to automatically commit your
+changes to git and keep them in sync with other repositories. Unlike
+git-annex, they don't store the file content on the side, but directly in
+the git repository. Great for small files, less good for big files.
+
+Here's how to use the [[git-annex assistant|/assistant]] to do the same
+thing, but even better!
+
+----
+
+First, get git-annex version 4.20130329 or newer.
+
+----
+
+Let's suppose you're delveloping a video game, written in C. You have
+source code, and some large game assets. You want to ensure the source
+code is stored in git -- that's what git's for! And you want to store
+the game assets in the git annex -- to avod bloating your git repos with
+possibly enormous files, but still version control them.
+
+All you need to do is configure git-annex to treat your C files
+as small files. And treat any file larger than, say, 100kb as a large
+file that is stored in the annex.
+
+ git config annex.largefiles "largerthan=100kb and not (include=*.c or include=*.h)"
+
+Now if you run `git annex add`, it will only add the large files to the
+annex. You can `git add` the small files directly to git.
+
+Better, if you run `git annex assistant`, it will *automatically*
+add the large files to the annex, and store the small files in git.
+It'll notice every time you modify a file, and immediately commit it,
+too. And sync it out to other repositories you configure using `git annex
+webapp`.
+
+----
+
+It's also possible to disable the use of the annex entirely, and just
+have the assistant *always* put every file into git, no matter its size:
+
+ git config annex.largefiles "exclude=*"
diff --git a/doc/tips/replacing_Sparkleshare_or_dvcs-autosync_with_the_assistant/comment_1_907e4032ca4a39adb846cf16dbf447dc._comment b/doc/tips/replacing_Sparkleshare_or_dvcs-autosync_with_the_assistant/comment_1_907e4032ca4a39adb846cf16dbf447dc._comment
new file mode 100644
index 000000000..b0ff0114a
--- /dev/null
+++ b/doc/tips/replacing_Sparkleshare_or_dvcs-autosync_with_the_assistant/comment_1_907e4032ca4a39adb846cf16dbf447dc._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://hands.com/~phil/"
+ nickname="hands"
+ subject="software from the future?"
+ date="2013-03-31T17:30:34Z"
+ content="""
+I think you probably meant at least version 4.20130323 ;-)
+"""]]
diff --git a/doc/tips/replacing_Sparkleshare_or_dvcs-autosync_with_the_assistant/comment_2_902d001ba86657ef0f8cca5b175f99ca._comment b/doc/tips/replacing_Sparkleshare_or_dvcs-autosync_with_the_assistant/comment_2_902d001ba86657ef0f8cca5b175f99ca._comment
new file mode 100644
index 000000000..2367c938d
--- /dev/null
+++ b/doc/tips/replacing_Sparkleshare_or_dvcs-autosync_with_the_assistant/comment_2_902d001ba86657ef0f8cca5b175f99ca._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-03-31T18:50:35Z"
+ content="""
+I meant 4.20130329
+"""]]
diff --git a/doc/tips/replacing_Sparkleshare_or_dvcs-autosync_with_the_assistant/comment_3_a1cf93f9b29658f0f26e9e0ae6057ee3._comment b/doc/tips/replacing_Sparkleshare_or_dvcs-autosync_with_the_assistant/comment_3_a1cf93f9b29658f0f26e9e0ae6057ee3._comment
new file mode 100644
index 000000000..91122360a
--- /dev/null
+++ b/doc/tips/replacing_Sparkleshare_or_dvcs-autosync_with_the_assistant/comment_3_a1cf93f9b29658f0f26e9e0ae6057ee3._comment
@@ -0,0 +1,60 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawniayrgSdVLUc3c6bf93VbO-_HT4hzxmyo"
+ nickname="Tobias"
+ subject="Trying this feature"
+ date="2013-04-14T13:04:55Z"
+ content="""
+I just gave this feature a try, but it seems it doesn't work as expected or maybe I don't understand it:
+
+ ~/annex/largefilestest % git init
+ ~/annex/largefilestest (git)-[master] % git annex init \"test repo\"
+ ~/annex/largefilestest (git)-[master] % git config annex.largefiles \"not include=*.txt\"
+
+Now I copy two files to this directory and add both to the annex
+
+ ~/annex/largefilestest (git)-[master] % ll
+ total 100
+ -rw-rw-r-- 1 tobru tobru 93709 Oct 19 16:14 dpkg-get-selections.txt
+ -rw-rw-r-- 1 tobru tobru 7256 Jan 6 15:52 x3400.jpg
+ ~/annex/largefilestest (git)-[master] % git annex add .
+ add x3400.jpg (checksum...) ok
+ (Recording state in git...)
+ ~/annex/largefilestest (git)-[master] % git status
+ # On branch master
+ #
+ # Initial commit
+ #
+ # Changes to be committed:
+ # (use \"git rm --cached <file>...\" to unstage)
+ #
+ # new file: x3400.jpg
+ #
+ # Untracked files:
+ # (use \"git add <file>...\" to include in what will be committed)
+ #
+ # dpkg-get-selections.txt
+ ~/annex/largefilestest (git)-[master] % ll
+ total 96
+ -rw-rw-r-- 1 tobru tobru 93709 Oct 19 16:14 dpkg-get-selections.txt
+ lrwxrwxrwx 1 tobru tobru 192 Jan 6 15:52 x3400.jpg -> .git/annex/objects/vf/QX/SHA256E-s7256--60e5b69ade5619e37f7fcaa964626da9c415959d861241aa13e2516fffc2dddf.jpg/SHA256E-s7256--60e5b69ade5619e37f7fcaa964626da9c415959d861241aa13e2516fffc2dddf.jpg
+
+So the picture is added to the annex as expected. But the .txt file is not added to git. Do I have to manually add this to git? And why is the picture seen as new file by git?
+
+The second question could be answered by: \"run git annex sync\". Is this correct? Because after running this command, git does not see this file as a new file anymore:
+
+ ~/annex/largefilestest (git)-[master] % git annex sync
+ commit
+ [master (root-commit) a0afb14] git-annex automatic sync
+ 1 file changed, 1 insertion(+)
+ create mode 120000 x3400.jpg
+ ok
+ git-annex: no branch is checked out
+ ~/annex/largefilestest (git)-[master] % git status
+ # On branch master
+ # Untracked files:
+ # (use \"git add <file>...\" to include in what will be committed)
+ #
+ # dpkg-get-selections.txt
+ nothing added to commit but untracked files present (use \"git add\" to track)
+
+"""]]
diff --git a/doc/tips/replacing_Sparkleshare_or_dvcs-autosync_with_the_assistant/comment_4_e10671908b58c554375787d0f76e2366._comment b/doc/tips/replacing_Sparkleshare_or_dvcs-autosync_with_the_assistant/comment_4_e10671908b58c554375787d0f76e2366._comment
new file mode 100644
index 000000000..14a909014
--- /dev/null
+++ b/doc/tips/replacing_Sparkleshare_or_dvcs-autosync_with_the_assistant/comment_4_e10671908b58c554375787d0f76e2366._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 4"
+ date="2013-04-14T18:37:50Z"
+ content="""
+Like it says in the tip, `git annex add` will add the large files to git. You can add the small files with `git add`; git-annex won't do that for you.
+
+To automatically add both sorts of files, you can use the `git annex watch` or `git annex assistant` daemons. The latter also keeps files in sync between repositories automatically.
+
+(Why did the picture show up as a new file in git? Because you hadn't committed it. This is the same as when you `git add` a file;
+it's only staged in the index; `git status` will show it is new until you `git commit`)
+"""]]
diff --git a/doc/tips/replacing_Sparkleshare_or_dvcs-autosync_with_the_assistant/comment_5_4114380f66b6376c851e93f6876d590b._comment b/doc/tips/replacing_Sparkleshare_or_dvcs-autosync_with_the_assistant/comment_5_4114380f66b6376c851e93f6876d590b._comment
new file mode 100644
index 000000000..5d638a3b8
--- /dev/null
+++ b/doc/tips/replacing_Sparkleshare_or_dvcs-autosync_with_the_assistant/comment_5_4114380f66b6376c851e93f6876d590b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawniayrgSdVLUc3c6bf93VbO-_HT4hzxmyo"
+ nickname="Tobias"
+ subject="mimetypes"
+ date="2013-05-01T20:37:33Z"
+ content="""
+Does `annex.largefiles` support mimetypes? F.e. `git config annex.largefiles \"not mimetype=text/plain\"`
+"""]]
diff --git a/doc/tips/replacing_Sparkleshare_or_dvcs-autosync_with_the_assistant/comment_6_6a5d6af107b297afd008b021f73d787b._comment b/doc/tips/replacing_Sparkleshare_or_dvcs-autosync_with_the_assistant/comment_6_6a5d6af107b297afd008b021f73d787b._comment
new file mode 100644
index 000000000..bd2212ffb
--- /dev/null
+++ b/doc/tips/replacing_Sparkleshare_or_dvcs-autosync_with_the_assistant/comment_6_6a5d6af107b297afd008b021f73d787b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnPOttrEmm9CQYxzWrmgGN7LXy98gDkrlM"
+ nickname="binet"
+ subject="annex.largefiles and direct mode"
+ date="2013-09-16T22:50:48Z"
+ content="""
+I was wondering if the annex.largefiles feature was compatible with direct mode?
+"""]]
diff --git a/doc/tips/replacing_Sparkleshare_or_dvcs-autosync_with_the_assistant/comment_7_74d57cf503a86d8f7ace2d769dbb58be._comment b/doc/tips/replacing_Sparkleshare_or_dvcs-autosync_with_the_assistant/comment_7_74d57cf503a86d8f7ace2d769dbb58be._comment
new file mode 100644
index 000000000..2144b0ec8
--- /dev/null
+++ b/doc/tips/replacing_Sparkleshare_or_dvcs-autosync_with_the_assistant/comment_7_74d57cf503a86d8f7ace2d769dbb58be._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.14.105"
+ subject="comment 7"
+ date="2013-09-19T18:03:29Z"
+ content="""
+annex.largefiles does not support mime types. I agree it would be a useful addition.
+
+annex.largefiles can be used with direct mode. I would only recommending using it this way using the assistant, which will keep straight which files are which and commit them appropriately.
+"""]]
diff --git a/doc/tips/setup_a_public_repository_on_a_web_site.mdwn b/doc/tips/setup_a_public_repository_on_a_web_site.mdwn
new file mode 100644
index 000000000..8251cabf6
--- /dev/null
+++ b/doc/tips/setup_a_public_repository_on_a_web_site.mdwn
@@ -0,0 +1,55 @@
+Let's say you want to distribute some big files to the whole world.
+You can of course, just drop them onto a website. But perhaps you'd like to
+use git-annex to manage those files. And as an added bonus, why not let
+anyone in the world clone your site and use `git-annex get`!
+
+My site like this is [downloads.kitenet.net](https://downloads.kitenet.net).
+Here's how I set it up. --[[Joey]]
+
+1. Set up a web site. I used Apache, and configured it to follow symlinks.
+ `Options FollowSymLinks`
+2. Put some files on the website. Make sure it works.
+3. `git init; git annex init`
+4. `git config core.sharedrepository world` (Makes sure files
+ are always added with permissions that allow everyone to read them.)
+5. We want users to be able to clone the git repository over http, because
+ git-annex can download files from it over http as well. For this to
+ work, `git update-server-info` needs to get run after commits. The
+ git `post-update` hook will take care of this, you just need to enable
+ the hook. `chmod +x .git/hooks/post-update`
+6. `git annex add; git commit -m added`
+7. Make sure users can still download files from the site directly.
+8. Instruct advanced users to clone a http url that ends with the "/.git/"
+ directory. For example, for downloads.kitenet.net, the clone url
+ is `https://downloads.kitenet.net/.git/`
+9. Set up a git `post-receive` hook to update the repository's working tree
+ when changes are pushed to it. See below for details.
+
+When users clone over http, and run git-annex, it will
+automatically learn all about your repository and be able to download files
+right out of it, also using http.
+
+## post-receive hook
+
+If you have git-annex 4.20130703, the post-receive hook mentioned above
+in step 8 just needs to run `git annex merge`.
+
+With older versions of git-annex, you can instead use `git annex sync`.
+
+There are two gotchas with some versions of git to be aware of when writing
+this post-receive hook.
+
+1. The hook may be run with the current directory set to the `.git`
+ directory, and not the top of your work tree. So you need to `cd ..` or
+ similar in the hook.
+2. `GIT_DIR` may be set to `.`, which will not be right after changing
+ directory. So you will probably want to unset it.
+
+Here's a post-receive hook that takes these problems into account:
+
+<pre>
+#!/bin/sh
+unset GIT_DIR
+cd ..
+git annex merge
+</pre>
diff --git a/doc/tips/setup_a_public_repository_on_a_web_site/comment_1_1d0fa6da33e401df1d7ff31979247fec._comment b/doc/tips/setup_a_public_repository_on_a_web_site/comment_1_1d0fa6da33e401df1d7ff31979247fec._comment
new file mode 100644
index 000000000..cc0a0f2b3
--- /dev/null
+++ b/doc/tips/setup_a_public_repository_on_a_web_site/comment_1_1d0fa6da33e401df1d7ff31979247fec._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnYLUTs4jFpBPwOlIIJ6qD8xdqZPboJafM"
+ nickname="Oluf"
+ subject="Combine this with a 'public' repository-group"
+ date="2013-07-16T09:44:26Z"
+ content="""
+Hi,
+
+would it be possible to do this whith the contents of a public repository-group (a non-bare public repository)?
+"""]]
diff --git a/doc/tips/setup_a_public_repository_on_a_web_site/comment_2_b98b761dee9d923153e3c288c1d987ee._comment b/doc/tips/setup_a_public_repository_on_a_web_site/comment_2_b98b761dee9d923153e3c288c1d987ee._comment
new file mode 100644
index 000000000..7bfb89b36
--- /dev/null
+++ b/doc/tips/setup_a_public_repository_on_a_web_site/comment_2_b98b761dee9d923153e3c288c1d987ee._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.90"
+ subject="comment 2"
+ date="2013-07-16T17:54:28Z"
+ content="""
+You can choose which files get stored in the public repository, and are thus accessible to the public.
+However, note that since the git repository is published, anyone could clone it and see all the names and hashes of your files, even if you've not pushed the file contents to the public repository.
+
+Currently the way the \"public\" [[repository group|preferred_content]] works only makes it be usable with special remotes. This is because it uses a `preferreddir` setting in the special remote configuration.
+"""]]
diff --git a/doc/tips/shared_git_annex_directory_between_multiple_users.mdwn b/doc/tips/shared_git_annex_directory_between_multiple_users.mdwn
new file mode 100644
index 000000000..5ca3b45ec
--- /dev/null
+++ b/doc/tips/shared_git_annex_directory_between_multiple_users.mdwn
@@ -0,0 +1,39 @@
+Scenario
+========
+
+You have a server where you want to welcome other people to push files, say for a family photo album. People have their own user account, so by default they will not be able to read/write from each other's repositories, due to git-annex strict restrictions.
+
+Solution
+========
+
+Setup a shared git repository:
+
+ git init shared ; cd shared # you can also do this on an existing git annex repo
+ git config core.sharedrepository group
+ chmod g+rwX -R .
+ chown -R :media .
+
+The idea here is to use the new (since [[news/version 4.20130909]]) support for git's `sharedRepository` configuration and restrict access to a specific group (instead of the default, a single user). You can also this to make the files accessible to all users on the system:
+
+ git config core.sharedrepository world
+ chmod a+rwX -R .
+
+This will make sure that you anyone can operate that git annex repository remotely.
+
+Third party applications
+------------------------
+
+Now if another application that is not aware of git's `sharedRepository` configuration (say a [[bittorrent]] daemon) writes files there, you may want to make sure that the files created are also writable by everyone. This is more tricky, but one way of doing this is with the [[!wikipedia setgid]] bit:
+
+ find -type d -exec chmod g+s {} \;
+
+You will also need to start the process with a proper [[!wikipedia umask]] (`002` instead of `022`).
+
+(!) I haven't actually tested this part. --[[anarcat]]
+
+See also
+========
+
+ * [[tips/setup a public repository on a web site]]
+ * [[news/version 4.20130909]]
+ * [[bugs/acl not honoured in rsync remote]]: why this does not work on encrypted remotes
diff --git a/doc/tips/skydriveannex.mdwn b/doc/tips/skydriveannex.mdwn
new file mode 100644
index 000000000..56acdd96c
--- /dev/null
+++ b/doc/tips/skydriveannex.mdwn
@@ -0,0 +1,29 @@
+skydriveannex
+=========
+
+Hook program for gitannex to use [skydrive](http://en.wikipedia.org/wiki/SkyDrive) (previously *Windows Live SkyDrive* and *Windows Live Folders*) as backend
+
+# Requirements:
+
+ python2
+ python-yaml
+
+Credit for the Skydrive api interface goes to https://github.com/mk-fg/python-skydrive
+
+# Install
+Clone the git repository in your home folder.
+
+ git clone git://github.com/TobiasTheViking/skydriveannex.git
+
+This should make a ~/skydriveannex folder
+
+# Setup
+Run the program once to set it up.
+
+ cd ~/skydriveannex; python2 skydriveannex.py
+
+# Commands for gitannex:
+
+ git config annex.skydrive-hook '/usr/bin/python2 ~/skydriveannex/skydriveannex.py'
+ git annex initremote skydrive type=hook hooktype=skydrive encryption=shared
+ git annex describe skydrive "the skydrive library"
diff --git a/doc/tips/untrusted_repositories.mdwn b/doc/tips/untrusted_repositories.mdwn
new file mode 100644
index 000000000..cdb5da7c3
--- /dev/null
+++ b/doc/tips/untrusted_repositories.mdwn
@@ -0,0 +1,28 @@
+Suppose you have a USB thumb drive and are using it as a git annex
+repository. You don't trust the drive, because you could lose it, or
+accidentally run it through the laundry. Or, maybe you have a drive that
+you know is dying, and you'd like to be warned if there are any files
+on it not backed up somewhere else. Maybe the drive has already died
+or been lost.
+
+You can let git-annex know that you don't trust a repository, and it will
+adjust its behavior to avoid relying on that repositories's continued
+availability.
+
+ # git annex untrust usbdrive
+ untrust usbdrive ok
+
+Now when you do a fsck, you'll be warned appropriately:
+
+ # git annex fsck .
+ fsck my_big_file
+ Only these untrusted locations may have copies of this file!
+ 05e296c4-2989-11e0-bf40-bad1535567fe -- portable USB drive
+ Back it up to trusted locations with git-annex copy.
+ failed
+
+Also, git-annex will refuse to drop a file from elsewhere just because
+it can see a copy on the untrusted repository.
+
+It's also possible to tell git-annex that you have an unusually high
+level of trust for a repository. See [[trust]] for details.
diff --git a/doc/tips/using_Amazon_Glacier.mdwn b/doc/tips/using_Amazon_Glacier.mdwn
new file mode 100644
index 000000000..5aac7fa91
--- /dev/null
+++ b/doc/tips/using_Amazon_Glacier.mdwn
@@ -0,0 +1,75 @@
+Amazon Glacier provides low-cost storage, well suited for archiving and
+backup. But it takes around 4 hours to get content out of Glacier.
+
+Recent versions of git-annex support Glacier. To use it, you need to have
+[glacier-cli](http://github.com/basak/glacier-cli) installed.
+
+First, export your Amazon AWS credentials:
+
+ # export AWS_ACCESS_KEY_ID="08TJMT99S3511WOZEP91"
+ # export AWS_SECRET_ACCESS_KEY="s3kr1t"
+
+Now, create a gpg key, if you don't already have one. This will be used
+to encrypt everything stored in Glacier, for your privacy. Once you have
+a gpg key, run `gpg --list-secret-keys` to look up its key id, something
+like "2512E3C7"
+
+Next, create the Glacier remote.
+
+ # git annex initremote glacier type=glacier keyid=2512E3C7
+ initremote glacier (encryption setup with gpg key C910D9222512E3C7) (gpg) ok
+
+The configuration for the Glacier remote is stored in git. So to make another
+repository use the same Glacier remote is easy:
+
+ # cd /media/usb/annex
+ # git pull laptop
+ # git annex initremote glacier
+ initremote glacier (gpg) ok
+
+Now the remote can be used like any other remote.
+
+ # git annex move my_cool_big_file --to glacier
+ copy my_cool_big_file (gpg) (checking glacier...) (to glacier...) ok
+
+But, when you try to get a file out of Glacier, it'll queue a retrieval
+job:
+
+ # git annex get my_cool_big_file
+ get my_cool_big_file (from glacier...) (gpg)
+ glacier: queued retrieval job for archive 'GPGHMACSHA1--862afd4e67e3946587a9ef7fa5beb4e8f1aeb6b8'
+ Recommend you wait up to 4 hours, and then run this command again.
+ failed
+
+Like it says, you'll need to run the command again later. Let's remember to
+do that:
+
+ # at now + 4 hours
+ at> git annex get my_cool_big_file
+
+Another oddity of Glacier is that git-annex is never entirely sure
+if a file is still in Glacier. Glacier inventories take hours to retrieve,
+and even when retrieved do not necessarily represent the current state.
+
+So, git-annex plays it safe, and avoids trusting the inventory:
+
+ # git annex copy important_file --to glacier
+ copy important_file (gpg) (checking glacier...) (to glacier...) ok
+ # git annex drop important_file
+ drop important_file (gpg) (checking glacier...)
+ Glacier's inventory says it has a copy.
+ However, the inventory could be out of date, if it was recently removed.
+ (Use --trust-glacier if you're sure it's still in Glacier.)
+
+ (unsafe)
+ Could only verify the existence of 0 out of 1 necessary copies
+
+Like it says, you can use `--trust-glacier` if you're sure
+Glacier's inventory is correct and up-to-date.
+
+A final potential gotcha with Glacier is that glacier-cli keeps a local
+mapping of file names to Glacier archives. If this cache is lost, or
+you want to retrieve files on a different box than the one that put them in
+glacier, you'll need to use `glacier vault sync` to rebuild this cache.
+
+See [[special_remotes/Glacier]] for details.
diff --git a/doc/tips/using_Amazon_S3.mdwn b/doc/tips/using_Amazon_S3.mdwn
new file mode 100644
index 000000000..0c68c7387
--- /dev/null
+++ b/doc/tips/using_Amazon_S3.mdwn
@@ -0,0 +1,37 @@
+git-annex extends git's usual remotes with some [[special_remotes]], that
+are not git repositories. This way you can set up a remote using say,
+Amazon S3, and use git-annex to transfer files into the cloud.
+
+First, export your Amazon AWS credentials:
+
+ # export AWS_ACCESS_KEY_ID="08TJMT99S3511WOZEP91"
+ # export AWS_SECRET_ACCESS_KEY="s3kr1t"
+
+Now, create a gpg key, if you don't already have one. This will be used
+to encrypt everything stored in S3, for your privacy. Once you have
+a gpg key, run `gpg --list-secret-keys` to look up its key id, something
+like "2512E3C7"
+
+Next, create the S3 remote, and describe it.
+
+ # git annex initremote cloud type=S3 keyid=2512E3C7
+ initremote cloud (encryption setup with gpg key C910D9222512E3C7) (checking bucket) (creating bucket in US) (gpg) ok
+ # git annex describe cloud "at Amazon's US datacenter"
+ describe cloud ok
+
+The configuration for the S3 remote is stored in git. So to make another
+repository use the same S3 remote is easy:
+
+ # cd /media/usb/annex
+ # git pull laptop
+ # git annex initremote cloud
+ initremote cloud (gpg) (checking bucket) ok
+
+Now the remote can be used like any other remote.
+
+ # git annex copy my_cool_big_file --to cloud
+ copy my_cool_big_file (gpg) (checking cloud...) (to cloud...) ok
+ # git annex move video/hackity_hack_and_kaxxt.mov --to cloud
+ move video/hackity_hack_and_kaxxt.mov (checking cloud...) (to cloud...) ok
+
+See [[special_remotes/S3]] for details.
diff --git a/doc/tips/using_Amazon_S3/comment_1_666a26f95024760c99c627eed37b1966._comment b/doc/tips/using_Amazon_S3/comment_1_666a26f95024760c99c627eed37b1966._comment
new file mode 100644
index 000000000..60d96cb44
--- /dev/null
+++ b/doc/tips/using_Amazon_S3/comment_1_666a26f95024760c99c627eed37b1966._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnoUOqs_lbuWyZBqyU6unHgUduJwDDgiKY"
+ nickname="Matt"
+ subject="ANNEX_S3 vs AWS for keys"
+ date="2012-05-29T12:24:25Z"
+ content="""
+The instructions state ANNEX_S3_ACCESS_KEY_ID and ANNEX_SECRET_ACCESS_KEY but git-annex cannot connect with those constants. git-annex tells me to set both \"AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY\" instead, which works. This is with Xubuntu 12.04.
+"""]]
diff --git a/doc/tips/using_Amazon_S3/comment_2_f5a0883be7dbb421b584c6dc0165f1ef._comment b/doc/tips/using_Amazon_S3/comment_2_f5a0883be7dbb421b584c6dc0165f1ef._comment
new file mode 100644
index 000000000..dc809cb12
--- /dev/null
+++ b/doc/tips/using_Amazon_S3/comment_2_f5a0883be7dbb421b584c6dc0165f1ef._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.81.112"
+ subject="comment 2"
+ date="2012-05-29T19:10:42Z"
+ content="""
+Thanks, I've fixed that. (You could have too.. this is a wiki ;)
+"""]]
diff --git a/doc/tips/using_Google_Cloud_Storage.mdwn b/doc/tips/using_Google_Cloud_Storage.mdwn
new file mode 100644
index 000000000..d44e4f17f
--- /dev/null
+++ b/doc/tips/using_Google_Cloud_Storage.mdwn
@@ -0,0 +1,9 @@
+[Google Cloud Storage](https://cloud.google.com/products/cloud-storage)
+supports the same API as Amazon S3, so the
+[[S3 special remote|special_remotes/S3]] can be used with it.
+Here is a configuration example:
+
+ git annex initremote cloud type=S3 encryption=none host=storage.googleapis.com port=80
+
+Thanks to jterrance for the [original tip](https://gist.github.com/4576324).
+--[[Joey]]
diff --git a/doc/tips/using_Google_Cloud_Storage/comment_1_c576182f39563ae68767391c4227a177._comment b/doc/tips/using_Google_Cloud_Storage/comment_1_c576182f39563ae68767391c4227a177._comment
new file mode 100644
index 000000000..3a4d02f32
--- /dev/null
+++ b/doc/tips/using_Google_Cloud_Storage/comment_1_c576182f39563ae68767391c4227a177._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnaH44G3QbxBAYyDwy0PbvL0ls60XoaR3Y"
+ nickname="Nigel"
+ subject="AWS credentials"
+ date="2013-05-31T10:23:23Z"
+ content="""
+This looks very valuable - Google are offering a free 5GB up until 2013 June 30th
+
+Sign in here[1] get your credentials here[2] under the section “Interoperable Access” (Source[3])
+
+ # Set up AWS credentials
+ $ export AWS_ACCESS_KEY_ID=\"YOUR-KEY\"
+ $ export AWS_SECRET_ACCESS_KEY=\"YOUR-SECRET\"
+
+1. http://gs-signup-redirect.appspot.com/ -or- https://developers.google.com/storage/docs/signup
+2. https://storage.cloud.google.com/m
+3. http://fog.io/storage/
+"""]]
diff --git a/doc/tips/using_box.com_as_a_special_remote.mdwn b/doc/tips/using_box.com_as_a_special_remote.mdwn
new file mode 100644
index 000000000..254d0a554
--- /dev/null
+++ b/doc/tips/using_box.com_as_a_special_remote.mdwn
@@ -0,0 +1,71 @@
+[Box.com](http://box.com/) is a file storage service, currently notable
+for providing 50 gb of free storage if you sign up with its Android client.
+(Or a few gb free otherwise.)
+
+git-annex can use Box as a [[special remote|special_remotes]].
+Recent versions of git-annex make this very easy to set up:
+
+ WEBDAV_USERNAME=you@example.com WEBDAV_PASSWORD=xxxxxxx git annex initremote box.com type=webdav url=https://www.box.com/dav/git-annex chunksize=75mb encryption=shared
+
+Note the use of chunksize; Box has a 100 mb maximum file size, and this
+breaks up large files into chunks before that limit is reached.
+
+# old davfs2 method
+
+This method is deprecated, but still documented here just in case.
+Note that the files stored using this method cannot reliably be retreived
+using the webdav special remote.
+
+## davfs2 setup
+
+* First, install
+ the [davfs2](http://savannah.nongnu.org/projects/davfs2) program,
+ which can mount Box using WebDAV. On Debian, just `sudo apt-get install davfs2`
+* Allow users to mount davfs filesystems, by ensuring that
+ `/sbin/mount.davfs` is setuid root. On Debian, just `sudo dpkg-reconfigure davfs2`
+* Add yourself to the davfs2 group.
+
+ sudo adduser $(whoami) davfs2
+
+* Edit `/etc/fstab`, and add a line to mount Box using davfs.
+
+ sudo mkdir -p /media/box.com
+ echo "https://www.box.com/dav/ /media/box.com davfs noauto,user 0 0" | sudo tee -a /etc/fstab
+
+* Create `~/.davfs2/davfs2.conf` with some important settings:
+
+ mkdir ~/.davfs2/
+ echo use_locks 0 > ~/.davfs2/davfs2.conf
+ echo cache_size 1 >> ~/.davfs2/davfs2.conf
+ echo delay_upload 0 >> ~/.davfs2/davfs2.conf
+
+* Create `~/.davfs2/secrets`. This file contains your Box.com login and password.
+ Your login is probably the email address you signed up with.
+
+ echo "/media/box.com joey@kitenet.net mypassword" > ~/.davfs2/secrets
+ chmod 600 ~/.davfs2/secrets
+
+* Now you should be able to mount Box, as a non-root user:
+
+ mount /media/box.com
+
+## git-annex setup
+
+You need git-annex version 3.20120303 or newer, which adds support for chunking
+files larger than Box's 100 mb limit.
+
+Create the special remote, in your git-annex repository.
+** This example is non-encrypted; fill in your gpg key ID for a securely
+encrypted special remote! **
+
+ git annex initremote box.com type=directory directory=/media/box.com chunksize=2mb encryption=none
+
+Now git-annex can copy files to box.com, get files from it, etc, just like
+with any other special remote.
+
+ % git annex copy bigfile --to box.com
+ bigfile (to box.com...) ok
+ % git annex drop bigfile
+ bigfile (checking box.com...) ok
+ % git annex get bigfile
+ bigfile (from box.com...) ok
diff --git a/doc/tips/using_git_annex_with_no_fixed_hostname_and_optimising_ssh.mdwn b/doc/tips/using_git_annex_with_no_fixed_hostname_and_optimising_ssh.mdwn
new file mode 100644
index 000000000..594d8c480
--- /dev/null
+++ b/doc/tips/using_git_annex_with_no_fixed_hostname_and_optimising_ssh.mdwn
@@ -0,0 +1,59 @@
+## Intro
+
+This tip is based on my (Matt Ford) experience of using `git annex` with my out-and-about netbook which hits many different wifi networks and has no fixed home or address.
+
+I'm not using a bare repository that allows pushing (an alternative solution) nor do I fancy allowing `git push` to run against my desktop checked out repository (perhaps I worry over nothing?)
+
+None of this is really `git annex` specific but I think it is useful to know...
+
+## Dealing with no fixed hostname
+
+Essentially set up two repos as per the [[walkthrough]].
+
+Desktop as follows:
+
+ cd ~/annex
+ git init
+ git annex init "desktop"
+
+And the laptop like this
+
+ git clone ssh://desktop/annex
+ git init
+ git annex init "laptop"
+
+Now we want to add the the repos as remotes of each other.
+
+For the laptop it is easy:
+
+ git remote add desktop ssh://desktop/~/annex
+
+However for the desktop to add an ever changing laptops hostname it's a little tricky. We make use of remote SSH tunnels to do this. Essentially we have the laptop (which always knows it's own name and address and knows the address of the desktop) create a tunnel starting on an arbitrary port at the desktop and heads back to the laptop on it's own SSH server port (22).
+
+To do this make part of your laptop's SSH config look like this:
+
+ Host desktop
+ User matt
+ HostName desktop.example.org
+ RemoteForward 2222 localhost:22
+
+Now on the desktop to connect over the tunnel to the laptop's SSH port you need this:
+
+ Host laptop
+ User matt
+ HostName localhost
+ port 2222
+
+So to add the desktop's remote:
+
+a) From the laptop ensure the tunnel is up
+
+ ssh desktop
+
+b) From the desktop add the remote
+
+ git remote add laptop ssh://laptop/~/annex
+
+So now you can work on the train, pop on the wifi at work upon arrival, and sync up with a `git pull && git annex get`.
+
+An alternative solution may be to use direct tunnels over Openvpn.
diff --git a/doc/tips/using_git_annex_with_no_fixed_hostname_and_optimising_ssh/comment_1_c0b7682a2b6f3078457b85683c825baf._comment b/doc/tips/using_git_annex_with_no_fixed_hostname_and_optimising_ssh/comment_1_c0b7682a2b6f3078457b85683c825baf._comment
new file mode 100644
index 000000000..e627ead47
--- /dev/null
+++ b/doc/tips/using_git_annex_with_no_fixed_hostname_and_optimising_ssh/comment_1_c0b7682a2b6f3078457b85683c825baf._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://adamspiers.myopenid.com/"
+ nickname="Adam"
+ subject="comment 1"
+ date="2011-12-23T13:31:33Z"
+ content="""
+ControlPersist is awesome - thanks!
+
+Here's [an alternative, git-specific approach](http://thread.gmane.org/gmane.comp.version-control.home-dir/502).
+"""]]
diff --git a/doc/tips/using_gitolite_with_git-annex.mdwn b/doc/tips/using_gitolite_with_git-annex.mdwn
new file mode 100644
index 000000000..fcc3f96c3
--- /dev/null
+++ b/doc/tips/using_gitolite_with_git-annex.mdwn
@@ -0,0 +1,89 @@
+[Gitolite](https://github.com/sitaramc/gitolite) is a git repository
+manager. Here's how to add git-annex support to gitolite, so you can
+`git annex copy` files to a gitolite repository, and `git annex get`
+files from it.
+
+Warning : The method described here works with gitolite version g2, avaible in the g2 branch on github. There is an experimental support for g3 in the git-annex branch, if you tested it please add some feedback.
+
+A nice feature of using gitolite with git-annex is that users can be given
+read-only access to a repository, and this allows them to `git annex get`
+file contents, but not change anything.
+
+First, you need new enough versions:
+
+* gitolite 2.2 is needed -- this version contains a git-annex-shell ADC
+ and supports "ua" ADCs.
+* git-annex 3.20111016 or newer needs to be installed on the gitolite
+ server. Don't install an older version, it wouldn't be secure!
+
+And here's how to set it up. The examples are for gitolite as installed
+on Debian with apt-get, but the changes described can be made to any
+gitolite installation, just with different paths.
+
+Set `$GL_ADC_PATH` in `.gitolite.rc`, if you have not already done so.
+
+<pre>
+echo '$GL_ADC_PATH = "/usr/local/lib/gitolite/adc/";' >>~gitolite/.gitolite.rc
+</pre>
+
+Make the ADC directory, and a "ua" subdirectory.
+
+<pre>
+mkdir -p /usr/local/lib/gitolite/adc/ua
+</pre>
+
+Install the git-annex-shell ADC into the "ua" subdirectory from the gitolie repository.
+
+<pre>
+cd /usr/local/lib/gitolite/adc/ua/
+cp gitolite/contrib/adc/git-annex-shell .
+</pre>
+
+Now all gitolite repositories can be used with git-annex just as any
+ssh remote normally would be used. For example:
+
+<pre>
+# git clone gitolite@localhost:testing
+Cloning into testing...
+Receiving objects: 100% (18/18), done.
+# cd testing
+# git annex init
+init ok
+# cp /etc/passwd my-cool-big-file
+# git annex add my-cool-big-file
+add my-cool-big-file ok
+(Recording state in git...)
+# git commit -m added
+[master d36c8b4] added
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+ create mode 120000 my-cool-big-file
+# git push --all
+Counting objects: 17, done.
+Delta compression using up to 2 threads.
+Compressing objects: 100% (12/12), done.
+Writing objects: 100% (14/14), 1.39 KiB, done.
+Total 14 (delta 0), reused 1 (delta 0)
+To gitolite@localhost:testing
+ c552a38..db4653e git-annex -> git-annex
+ 29cd204..d36c8b4 master -> master
+# git annex copy --to origin
+copy my-cool-big-file (checking origin...) (to origin...)
+WORM-s2502-m1318875140--my-cool-big-file
+ 2502 100% 0.00kB/s 0:00:00 (xfer#1, to-check=0/1)
+
+sent 2606 bytes received 31 bytes 1758.00 bytes/sec
+total size is 2502 speedup is 0.95
+ok
+</pre>
+
+
+### Troubleshooting
+
+I got an error like this when setting up gitolite *after* setting up a local git repo and git annex:
+
+<pre>
+git-annex-shell: First run: git-annex init
+Command ssh ["git@git.example.com","git-annex-shell 'configlist' '/~/myrepo.git'"] failed; exit code 1
+</pre>
+
+because I forgot to "git push --all" after adding the new gitolite remote.
diff --git a/doc/tips/using_gitolite_with_git-annex/comment_10_8767bc8014b459a3cd76f275fd4fa8d6._comment b/doc/tips/using_gitolite_with_git-annex/comment_10_8767bc8014b459a3cd76f275fd4fa8d6._comment
new file mode 100644
index 000000000..b01779cb4
--- /dev/null
+++ b/doc/tips/using_gitolite_with_git-annex/comment_10_8767bc8014b459a3cd76f275fd4fa8d6._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://ertai.myopenid.com/"
+ nickname="npouillard"
+ subject="git-annex no longer supported by gitolite g3"
+ date="2013-03-25T12:47:21Z"
+ content="""
+See http://gitolite.com/gitolite/dev-status.html for some details.
+"""]]
diff --git a/doc/tips/using_gitolite_with_git-annex/comment_11_00715e0b47f09130e0e536e29f7b9258._comment b/doc/tips/using_gitolite_with_git-annex/comment_11_00715e0b47f09130e0e536e29f7b9258._comment
new file mode 100644
index 000000000..1fbbd9b8a
--- /dev/null
+++ b/doc/tips/using_gitolite_with_git-annex/comment_11_00715e0b47f09130e0e536e29f7b9258._comment
@@ -0,0 +1,31 @@
+[[!comment format=mdwn
+ username="http://mildred.fr/"
+ nickname="mildred"
+ subject="Problems with URL ending with &quot;.git&quot;"
+ date="2013-05-24T12:15:16Z"
+ content="""
+Hi,
+
+I noticed using the git-annex branch of gitolite v3 that the same URL with \".git\" at the end would not work in git-annex. For example my test repository was `git@git2.mildred.fr:u/mildred/Annex.git` but it didn't work until I converted it to `git@git2.mildred.fr:u/mildred/Annex`
+
+On the server, the repository is in `repositories/u/mildred/Annex.git`
+
+If I try a copy with git-annex for example, I would get:
+
+ $ git annex copy titi --to test
+ copy titi (checking test...) FATAL: u/mildred/Annex.git mildred DENIED
+
+ (unable to check test) failed
+ git-annex: copy: 1 failed
+
+(test is the name of my remote and titi is my file)
+
+Note, in my gitolite conf, I have:
+
+ repo u/CREATOR/[a-zA-Z0-9].*
+ C = @all
+ RW+D = CREATOR
+ RW = WRITERS
+ R = READERS
+
+"""]]
diff --git a/doc/tips/using_gitolite_with_git-annex/comment_12_7027ce60265b8f24c8ab54553e544068._comment b/doc/tips/using_gitolite_with_git-annex/comment_12_7027ce60265b8f24c8ab54553e544068._comment
new file mode 100644
index 000000000..f692dd93e
--- /dev/null
+++ b/doc/tips/using_gitolite_with_git-annex/comment_12_7027ce60265b8f24c8ab54553e544068._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn5RcmefXjrl1vmbHIiOWQyXGXVKxlm3rg"
+ nickname="Kavin"
+ subject="comment 12"
+ date="2013-07-25T03:20:15Z"
+ content="""
+latest code of gitolite does not support git-annex ? I could not find a way to make it work ?
+"""]]
diff --git a/doc/tips/using_gitolite_with_git-annex/comment_13_75218b7409c0e281cb01c9b2791e8cdf._comment b/doc/tips/using_gitolite_with_git-annex/comment_13_75218b7409c0e281cb01c9b2791e8cdf._comment
new file mode 100644
index 000000000..bc674a592
--- /dev/null
+++ b/doc/tips/using_gitolite_with_git-annex/comment_13_75218b7409c0e281cb01c9b2791e8cdf._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm9tgeFE5v-arAYYftSv3yUTI5Q4qB2C9M"
+ nickname="Khaije"
+ subject="git-annex with gitolite FTW"
+ date="2013-08-13T15:13:07Z"
+ content="""
+The steps to activate git-annex integration have changed/simplified for v3.
+
+
+1) during install, be sure to use the 'git-annex' branch, rather than master[fn:1].
+
+2) to enable git-annex-shell, open ~/.gitolite.rc and insert 'git-annex-shell' => 'ua' into the hash list in the COMMANDS array.[fn:2]
+#'git-annex-shell' => 'ua',
+
+
+
+
+[fn:1] We'd like to have this feature-branch merged to master, so please send Sitaram feedback, positive and negative, based on your experiences.
+[fn:2] There is no GL_ADC_PATH and no \"ua\" subdirectory here, and nothing to \"install\"; the command now comes with gitolite.
+"""]]
diff --git a/doc/tips/using_gitolite_with_git-annex/comment_14_7d4d4515218d1259d32be3baeb5ee56e._comment b/doc/tips/using_gitolite_with_git-annex/comment_14_7d4d4515218d1259d32be3baeb5ee56e._comment
new file mode 100644
index 000000000..048dfa698
--- /dev/null
+++ b/doc/tips/using_gitolite_with_git-annex/comment_14_7d4d4515218d1259d32be3baeb5ee56e._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSbvo_NbY-ev1VKtzwo7nEqUmvRO6rXGA"
+ nickname="François"
+ subject="comment 14"
+ date="2013-09-22T18:30:45Z"
+ content="""
+@khaije
+
+Could you paste your config file? Here is mine: http://paste.debian.net/44856/
+I don't have any COMMANDS array. Could you elaborate your modifications please?
+
+Thanks.
+"""]]
diff --git a/doc/tips/using_gitolite_with_git-annex/comment_15_dc6f21b5a3d5931c8d949a9753411b9e._comment b/doc/tips/using_gitolite_with_git-annex/comment_15_dc6f21b5a3d5931c8d949a9753411b9e._comment
new file mode 100644
index 000000000..f07116983
--- /dev/null
+++ b/doc/tips/using_gitolite_with_git-annex/comment_15_dc6f21b5a3d5931c8d949a9753411b9e._comment
@@ -0,0 +1,29 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnRaueN1AcM8pIMofH5-wQ1Kr4T0GBe8sA"
+ nickname="wayne"
+ subject="git-annex with gitolite-rc"
+ date="2013-10-19T17:03:32Z"
+ content="""
+@François
+
+The proper array in .gitolite.rc seems to be the \"ENABLE\" array, which it appears is parsed into the COMMANDS array in src/lib/Gitolite/Rc.pm
+
+@Khaije
+
+Using 'git-annex-shell' => 'ua' doesn't seem to work for me. The program still fails in src/gitolite-shell around line 163 (gitolite repo version b1d3c05):
+
+ _die \"suspicious characters loitering about '$soc'\"
+ if $rc{COMMANDS}{ words[0] } ne 'ua' and $soc !~ $REMOTE_COMMAND_PATT;
+
+When I insert $rc{COMMANDS}{ words[0] } into the _die message, it shows up as \"1\" instead of \"ua\" as I was expecting.
+
+When I manually set $rc{COMMANDS}{ words[0] } to 'ua' slightly earlier in the script, the git-annex-shell command gets run but it seems to fail to parse the result of the configlist command properly because then I get
+
+ Failed to get annex.uuid configuration of repository origin
+
+ Instead, got: \"annex.uuid=\ncore.gcrypt=\n\"
+
+
+I am actually about to give up on the notion of using git-annex and gitolite together. Maybe. I am interested to know if anyone else is having similar problems.
+
+"""]]
diff --git a/doc/tips/using_gitolite_with_git-annex/comment_16_8e5039e6655fc80dc863b6cdf44ef02a._comment b/doc/tips/using_gitolite_with_git-annex/comment_16_8e5039e6655fc80dc863b6cdf44ef02a._comment
new file mode 100644
index 000000000..5e0e6acd6
--- /dev/null
+++ b/doc/tips/using_gitolite_with_git-annex/comment_16_8e5039e6655fc80dc863b6cdf44ef02a._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmbo-yMzW_lkBrS4ICNn5XMr8saYtI1_WY"
+ nickname="Douglas"
+ subject="Any further info regarding gitolite support?"
+ date="2013-11-14T03:20:31Z"
+ content="""
+We have reached the same point as the previous poster from 25 days ago.
+$ git annex copy --to origin
+FATAL: suspicious characters loitering about 'git-annex-shell 'configlist' '/~/testing''
+
+ Remote origin does not have git-annex installed; setting remote.origin.annex-ignore
+git-annex: cannot determine uuid for origin
+
+Anyone actually have this working?
+"""]]
diff --git a/doc/tips/using_gitolite_with_git-annex/comment_17_9c40e1da8bb44f7207e802377f5cf923._comment b/doc/tips/using_gitolite_with_git-annex/comment_17_9c40e1da8bb44f7207e802377f5cf923._comment
new file mode 100644
index 000000000..57152bad7
--- /dev/null
+++ b/doc/tips/using_gitolite_with_git-annex/comment_17_9c40e1da8bb44f7207e802377f5cf923._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm9tgeFE5v-arAYYftSv3yUTI5Q4qB2C9M"
+ nickname="Khaije"
+ subject="comment 17"
+ date="2013-11-23T02:14:12Z"
+ content="""
+my gitolite.rc is available at https://gist.github.com/khaije1/7609848
+
+For whatever reason I've found this to be very simple to get working so I'd guess there's a missing ingredient somewhere. The combination of gitolite and git-annex is valuable to me so I'll add documents to the url above in hopes it will assist some people with getting the same value.
+
+"""]]
diff --git a/doc/tips/using_gitolite_with_git-annex/comment_1_9a2a2a8eac9af97e0c984ad105763a73._comment b/doc/tips/using_gitolite_with_git-annex/comment_1_9a2a2a8eac9af97e0c984ad105763a73._comment
new file mode 100644
index 000000000..807180660
--- /dev/null
+++ b/doc/tips/using_gitolite_with_git-annex/comment_1_9a2a2a8eac9af97e0c984ad105763a73._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://www.openid.albertlash.com/openid/"
+ ip="71.178.29.218"
+ subject="comment 1"
+ date="2011-12-24T06:08:45Z"
+ content="""
+Looks like you are missing a closing double quote on the line:
+
+
+echo '$GL_ADC_PATH = \"/usr/local/lib/gitolite/adc/;' >>~gitolite/.gitolite.rc
+
+right after /;
+
+I got this working by the way - great stuff.
+"""]]
diff --git a/doc/tips/using_gitolite_with_git-annex/comment_2_d8efea4ab9576555fadbb47666ecefa9._comment b/doc/tips/using_gitolite_with_git-annex/comment_2_d8efea4ab9576555fadbb47666ecefa9._comment
new file mode 100644
index 000000000..007a009ea
--- /dev/null
+++ b/doc/tips/using_gitolite_with_git-annex/comment_2_d8efea4ab9576555fadbb47666ecefa9._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 2"
+ date="2011-12-24T16:54:31Z"
+ content="""
+I've fixed the typo (anyone can edit pages in this wiki FWIW.)
+"""]]
diff --git a/doc/tips/using_gitolite_with_git-annex/comment_3_807035f38509ccb9f93f1929ecd37417._comment b/doc/tips/using_gitolite_with_git-annex/comment_3_807035f38509ccb9f93f1929ecd37417._comment
new file mode 100644
index 000000000..243764054
--- /dev/null
+++ b/doc/tips/using_gitolite_with_git-annex/comment_3_807035f38509ccb9f93f1929ecd37417._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="bremner"
+ ip="156.34.79.193"
+ subject="repo name conventions?"
+ date="2011-12-30T21:41:13Z"
+ content="""
+I'm confused by the fact that the git-annex-shell adc rejects any repo names that don't start with /~/ since none of my repos start that way. It seems work ok if I just delete /\~ from the front of the regex, but I feel like I must be missing something.
+"""]]
diff --git a/doc/tips/using_gitolite_with_git-annex/comment_4_eb81f824aadc97f098379c5f7e4fba4c._comment b/doc/tips/using_gitolite_with_git-annex/comment_4_eb81f824aadc97f098379c5f7e4fba4c._comment
new file mode 100644
index 000000000..c53ce01d9
--- /dev/null
+++ b/doc/tips/using_gitolite_with_git-annex/comment_4_eb81f824aadc97f098379c5f7e4fba4c._comment
@@ -0,0 +1,33 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 4"
+ date="2011-12-31T00:29:45Z"
+ content="""
+Well a repo url like `gitolite@localhost:testing` puts it in the gitolite user's /~/testing
+
+This worked when I added the gitolite stuff, anyway.. Let's see if it still does:
+
+<pre>
+joey@gnu:~/tmp>mkdir g
+joey@gnu:~/tmp>cd g
+joey@gnu:~/tmp/g>git init
+Initialized empty Git repository in /home/joey/tmp/g/.git/
+joey@gnu:~/tmp/g>git annex init
+init ok
+joey@gnu:~/tmp/g>git remote add test 'gitolite@localhost:testing'
+joey@gnu:~/tmp/g>touch foo
+joey@gnu:~/tmp/g>git annex add foo
+add foo (checksum...) ok
+(Recording state in git...)
+joey@gnu:~/tmp/g>git annex copy foo --to test --debug
+git [\"--git-dir=/home/joey/tmp/g/.git\",\"--work-tree=/home/joey/tmp/g\",\"ls-files\",\"--cached\",\"-z\",\"--\",\"foo\"]
+git [\"--git-dir=/home/joey/tmp/g/.git\",\"--work-tree=/home/joey/tmp/g\",\"check-attr\",\"annex.numcopies\",\"-z\",\"--stdin\"]
+git [\"--git-dir=/home/joey/tmp/g/.git\",\"--work-tree=/home/joey/tmp/g\",\"show-ref\",\"--hash\",\"refs/heads/git-annex\"]
+git [\"--git-dir=/home/joey/tmp/g/.git\",\"--work-tree=/home/joey/tmp/g\",\"show-ref\",\"git-annex\"]
+git [\"--git-dir=/home/joey/tmp/g/.git\",\"--work-tree=/home/joey/tmp/g\",\"cat-file\",\"--batch\"]
+Running: ssh [\"-4\",\"gitolite@localhost\",\"git-annex-shell 'configlist' '/~/testing'\"]
+</pre>
+
+Still seems right, the ADC's regexp will match this the git-annex shell command.
+"""]]
diff --git a/doc/tips/using_gitolite_with_git-annex/comment_5_f688309532d2993630e9e72e87fb9c46._comment b/doc/tips/using_gitolite_with_git-annex/comment_5_f688309532d2993630e9e72e87fb9c46._comment
new file mode 100644
index 000000000..052fc90d6
--- /dev/null
+++ b/doc/tips/using_gitolite_with_git-annex/comment_5_f688309532d2993630e9e72e87fb9c46._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="bremner"
+ ip="156.34.79.193"
+ subject="gitolite gets different paths for different urls"
+ date="2011-12-31T01:50:49Z"
+ content="""
+I guess there is some path rewriting going in in gitolite proper because if try a url of the form
+ssh://git@localhost/testing, then it still works with gitolite, but fails with the ADC because
+the repo is passed as /testing:
+<pre>
+Running: ssh [\"git@host\",\"git-annex-shell 'configlist' '/recommend'\"]
+Running: ssh [\"git@host\",\"git-annex-shell 'configlist' '/recommend'\"]
+</pre>
+
+What I have to ask Sitaram and or find in the docs is if this is a bug or a feature in gitolite. I can see how the leading slash would get swallowed up by this line
+<pre>
+$repo = \"'$REPO_BASE/$repo.git'\"
+</pre>
+in gl-auth-command, but I guess that isn't the whole story.
+"""]]
diff --git a/doc/tips/using_gitolite_with_git-annex/comment_6_3e203e010a4df5bf03899f867718adc5._comment b/doc/tips/using_gitolite_with_git-annex/comment_6_3e203e010a4df5bf03899f867718adc5._comment
new file mode 100644
index 000000000..ce888cb13
--- /dev/null
+++ b/doc/tips/using_gitolite_with_git-annex/comment_6_3e203e010a4df5bf03899f867718adc5._comment
@@ -0,0 +1,25 @@
+[[!comment format=mdwn
+ username="bremner"
+ ip="156.34.79.193"
+ subject="ssh://gitolite-host/repo-name is supposed to work"
+ date="2011-12-31T03:34:17Z"
+ content="""
+I confirmed with Sitaram that this is intentional, if probably under-documented.
+Since the ADC strips the leading /~/ in assigning $start anyway, I guess something like the following will work
+<pre>
+
+diff --git a/contrib/adc/git-annex-shell b/contrib/adc/git-annex-shell
+index 7f9f5b8..523dfed 100755
+--- a/contrib/adc/git-annex-shell
++++ b/contrib/adc/git-annex-shell
+@@ -28,7 +28,7 @@ my $cmd=$ENV{SSH_ORIGINAL_COMMAND};
+ # the second parameter.
+ # Further parameters are not validated here (see below).
+ die \"bad git-annex-shell command: $cmd\"
+- unless $cmd =~ m#^(git-annex-shell '\w+' ')/\~/([0-9a-zA-Z][0-9a-zA-Z._\@/+-
++ unless $cmd =~ m#^(git-annex-shell '\w+' ')/(?:\~\/)?([0-9a-zA-Z][0-9a-zA-Z.
+ my $start = $1;
+ my $repo = $2;
+ my $end = $3;
+</pre>
+"""]]
diff --git a/doc/tips/using_gitolite_with_git-annex/comment_7_f8fd08b6ab47378ad88c87348057220d._comment b/doc/tips/using_gitolite_with_git-annex/comment_7_f8fd08b6ab47378ad88c87348057220d._comment
new file mode 100644
index 000000000..bdbecd4d9
--- /dev/null
+++ b/doc/tips/using_gitolite_with_git-annex/comment_7_f8fd08b6ab47378ad88c87348057220d._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 7"
+ date="2011-12-31T18:32:28Z"
+ content="""
+That patch seems ok, it doesn't seem to allow through any repo locations that were blocked before.
+
+So, it has my blessing.. but the ADC is in gitolite and will need to be patched there.
+"""]]
diff --git a/doc/tips/using_gitolite_with_git-annex/comment_8_8249772c142117f88e37975d058aa936._comment b/doc/tips/using_gitolite_with_git-annex/comment_8_8249772c142117f88e37975d058aa936._comment
new file mode 100644
index 000000000..0717bab1c
--- /dev/null
+++ b/doc/tips/using_gitolite_with_git-annex/comment_8_8249772c142117f88e37975d058aa936._comment
@@ -0,0 +1,29 @@
+[[!comment format=mdwn
+ username="bremner"
+ ip="156.34.79.193"
+ subject="afaict git annex normalizes urls on the client side."
+ date="2011-12-31T22:29:38Z"
+ content="""
+After some debugging printing, here is my current understanding.
+
+- urls of the form git@host:~repo or ssh://git@host
+
+ - git sends commands like \"git-receive-pack '~/repo'
+ - gitolite converts these to $REPO_BASE/~/repo which fails. ~/repo would also fail fwiw.
+ - git-annex sends seems /~/repo, which works
+
+- urls of the form git@host:/repo or ssh://git@host/repo
+
+ - git sends \"git-receive-pack '/db/cs3383'\"
+ - gitolite converts this to $REPO_BASE/repo which works
+ - git annex sends \"git-annex-shell 'inannex' '/repo' ...\" which works, but only with the patch above.
+
+- urls of the form git@host:repo
+
+ - git sends \"git-receive-pack 'repo'
+ - gitolite converts this to $REPO_BASE/repo, which works
+ - git-annex sends \"git-annex-shell 'inannex' '/~/db/cs3383'...\", which also works for git-annex-shell.
+
+So the weird case is the last one where git and git-annex are sending different things over the wire.
+I don't know if you have other motivations for doing the url normalization on the client side, but it isn't needed for gitolite, and in some sense complicates things a little. On the other hand, now that I see what is going on, it isn't a big deal to just strip the leading /~ off in the adc. It does lead to the odd situation of some URLs working for git-annex but not git.
+"""]]
diff --git a/doc/tips/using_gitolite_with_git-annex/comment_9_28418635a6ed7231b89e02211cd3c236._comment b/doc/tips/using_gitolite_with_git-annex/comment_9_28418635a6ed7231b89e02211cd3c236._comment
new file mode 100644
index 000000000..fc297ff17
--- /dev/null
+++ b/doc/tips/using_gitolite_with_git-annex/comment_9_28418635a6ed7231b89e02211cd3c236._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 9"
+ date="2012-01-02T16:27:55Z"
+ content="""
+Ah right. git-annex normalizes all git ssh style user@host:dir to valid uris, which is where the `/~/` comes from. I don't anticipate this changing on the git-annex side.
+"""]]
diff --git a/doc/tips/using_the_SHA1_backend.mdwn b/doc/tips/using_the_SHA1_backend.mdwn
new file mode 100644
index 000000000..70dc2ef75
--- /dev/null
+++ b/doc/tips/using_the_SHA1_backend.mdwn
@@ -0,0 +1,11 @@
+A handy alternative to the default [[backend|backends]] is the
+SHA1 backend. This backend provides more git-style assurance that your data
+has not been damaged. And the checksum means that when you add the same
+content to the annex twice, only one copy need be stored in the backend.
+
+The only reason it's not the default is that it needs to checksum
+files when they're added to the annex, and this can slow things down
+significantly for really big files. To make SHA1 the default, just
+add something like this to `.gitattributes`:
+
+ * annex.backend=SHA1
diff --git a/doc/tips/using_the_web_as_a_special_remote.mdwn b/doc/tips/using_the_web_as_a_special_remote.mdwn
new file mode 100644
index 000000000..e04ba800d
--- /dev/null
+++ b/doc/tips/using_the_web_as_a_special_remote.mdwn
@@ -0,0 +1,101 @@
+The web can be used as a [[special_remote|special_remotes]] too.
+
+ # git annex addurl http://example.com/video.mpeg
+ addurl example.com_video.mpeg (downloading http://example.com/video.mpeg)
+ ########################################################## 100.0%
+ ok
+
+Now the file is downloaded, and has been added to the annex like any other
+file. So it can be renamed, copied to other repositories, and so on.
+
+To add a lot of urls at once, just list them all as parameters to
+`git annex addurl`.
+
+## trust issues
+
+Note that git-annex assumes that, if the web site does not 404, and has the
+right file size, the file is still present on the web, and this counts as
+one [[copy|copies]] of the file. If the file still seems to be present
+on the web, it will let you remove your last copy, trusting it can be
+downloaded again:
+
+ # git annex drop example.com_video.mpeg
+ drop example.com_video.mpeg (checking http://example.com/video.mpeg) ok
+
+If you don't [[trust]] the web to this degree, just let git-annex know:
+
+ # git annex untrust web
+ untrust web ok
+
+With the result that it will hang onto files:
+
+ # git annex drop example.com_video.mpeg
+ drop example.com_video.mpeg (unsafe)
+ Could only verify the existence of 0 out of 1 necessary copies
+ Also these untrusted repositories may contain the file:
+ 00000000-0000-0000-0000-000000000001 -- web
+ (Use --force to override this check, or adjust annex.numcopies.)
+ failed
+
+## attaching urls to existing files
+
+You can also attach urls to any file already in the annex:
+
+ # git annex addurl --file my_cool_big_file http://example.com/cool_big_file
+ addurl my_cool_big_file ok
+ # git annex whereis my_cool_big_file
+ whereis my_cool_big_file (2 copies)
+ 00000000-0000-0000-0000-000000000001 -- web
+ 27a9510c-760a-11e1-b9a0-c731d2b77df9 -- here
+
+## configuring filenames
+
+By default, `addurl` will generate a filename for you. You can use
+`--file=` to specify the filename to use.
+
+If you're adding a bunch of related files to a directory, or just don't
+like the default filenames generated by `addurl`, you can use `--pathdepth`
+to specify how many parts of the url are put in the filename.
+A positive number drops that many paths from the beginning, while a negative
+number takes that many paths from the end.
+
+ # git annex addurl http://example.com/videos/2012/01/video.mpeg
+ addurl example.com_videos_2012_01_video.mpeg (downloading http://example.com/videos/2012/01/video.mpeg)
+ # git annex addurl http://example.com/videos/2012/01/video.mpeg --pathdepth=2
+ addurl 2012_01_video.mpeg (downloading http://example.com/videos/2012/01/video.mpeg)
+ # git annex addurl http://example.com/videos/2012/01/video.mpeg --pathdepth=-2
+ addurl 01_video.mpeg (downloading http://example.com/videos/2012/01/video.mpeg)
+
+## videos
+
+<a name=quvi></a>
+
+There's support for downloading videos from sites like YouTube, Vimeo,
+and many more. This relies on [quvi](http://quvi.sourceforge.net/) to find
+urls to the actual videos files.
+
+When you have quvi installed, you can just
+`git annex addurl http://youtube.com/foo` and it will detect that
+it is a video and download the video content for offline viewing.
+
+Later, in another clone of the repository, you can run `git annex get` on
+the file and it will also be downloaded with the help of quvi. This works
+even if the video host has transcoded or otherwise changed the video
+in the meantime; the assumption is that these video files are equivilant.
+
+There is an `annex.quvi-options` configuration setting that can be used
+to pass parameters to quvi. For example, you could set `git config
+annex.quvi-options "--format low"` to configure it to download low
+quality videos from YouTube.
+
+Note that for performance reasons, the url is not checked for redirects,
+so some shortened urls will not be detected. You can
+either load the short url in a browser to get the full url, or you
+can force use of quvi with redirect detection, by prepending "quvi:" to the
+url.
+
+Downloading whole YouTube playlists is not currently supported by quvi.
+
+## podcasts
+
+This is done using `git annex importfeed`. See [[downloading podcasts]].
diff --git a/doc/tips/using_the_web_as_a_special_remote/comment_1_321a41d611c6fe45e047af9c96c5176c._comment b/doc/tips/using_the_web_as_a_special_remote/comment_1_321a41d611c6fe45e047af9c96c5176c._comment
new file mode 100644
index 000000000..ee1a271ea
--- /dev/null
+++ b/doc/tips/using_the_web_as_a_special_remote/comment_1_321a41d611c6fe45e047af9c96c5176c._comment
@@ -0,0 +1,26 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlc1og3PqIGudOMkFNrCCNg66vB7s-jLpc"
+ nickname="Paul"
+ subject="can addurl use hashing once the file is downloaded?"
+ date="2012-09-20T21:01:30Z"
+ content="""
+There are resources that I want to add to my annex that are currently available
+via a URL, but it seems like if I add these using `git-annex addurl`, they get
+symlinked to file in the annex/objects directory that starts with `URL-...`,
+instead of the more typical `SHA256-...`, and this does not change even after
+the files are downloaded.
+
+My concern is that I really want to ensure that these files don't change, which
+is the appeal of content-addressable symlinking of normal files (as opposed to
+URL addressable ones).
+
+Would there be a way to automate the injection of hash-based symlinking for
+files that are added via addurl? Sometimes I add a bunch of files via ``addurl
+--fast``, and after I've download them via ``get``, it would be nice to have
+those files have the same level of data integrity as when I download them using
+something outside of git-annex, add them to the annex, and do an ``addurl
+--file`` afterward.
+
+Thanks for all of your hard work!
+
+"""]]
diff --git a/doc/tips/using_the_web_as_a_special_remote/comment_2_dfe9c8c49aadff80d2020288584e0390._comment b/doc/tips/using_the_web_as_a_special_remote/comment_2_dfe9c8c49aadff80d2020288584e0390._comment
new file mode 100644
index 000000000..b015cdcec
--- /dev/null
+++ b/doc/tips/using_the_web_as_a_special_remote/comment_2_dfe9c8c49aadff80d2020288584e0390._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ subject="comment 2"
+ date="2012-09-20T21:55:57Z"
+ content="""
+`addurl` only uses the URL- keys if you run it with --fast. Otherwise it downloads the content and hashes it the same as `add` does.
+
+If you use `--fast`, you can go back and `git annex migrate` the file once it's been downloaded, to convert
+it to the SHA backend.
+"""]]
diff --git a/doc/tips/using_the_web_as_a_special_remote/comment_3_ed8dd3bbd9b9ae7f2309b72b94f61eb1._comment b/doc/tips/using_the_web_as_a_special_remote/comment_3_ed8dd3bbd9b9ae7f2309b72b94f61eb1._comment
new file mode 100644
index 000000000..0601f3005
--- /dev/null
+++ b/doc/tips/using_the_web_as_a_special_remote/comment_3_ed8dd3bbd9b9ae7f2309b72b94f61eb1._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnx8kHW66N3BqmkVpgtXDlYMvr8TJ5VvfY"
+ nickname="Yaroslav"
+ subject="how to drop one of the urls?"
+ date="2013-04-12T14:53:29Z"
+ content="""
+is there a way to remove one of the urls? e.g. if I have
+
+ $> git annex whereis fail2ban_logo.png
+ whereis fail2ban_logo.png (1 copy)
+ 00000000-0000-0000-0000-000000000001 -- web
+
+ web: http://www.fail2ban.org/fail2ban_logo.png
+ web: http://www.onerussian.com/tmp/statsmodes.png
+ ok
+
+and would like to remove the fail2ban.org one... ?
+"""]]
diff --git a/doc/tips/using_the_web_as_a_special_remote/comment_4_c1133a524989a940f1b5db588707157a._comment b/doc/tips/using_the_web_as_a_special_remote/comment_4_c1133a524989a940f1b5db588707157a._comment
new file mode 100644
index 000000000..bd55a7872
--- /dev/null
+++ b/doc/tips/using_the_web_as_a_special_remote/comment_4_c1133a524989a940f1b5db588707157a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 4"
+ date="2013-04-22T21:28:03Z"
+ content="""
+You can use `git annex rmurl $file $url`, which I just added to git-annex.
+
+(Also, `git annex drop $file --from web` will remove all the urls..)
+"""]]
diff --git a/doc/tips/visualizing_repositories_with_gource.mdwn b/doc/tips/visualizing_repositories_with_gource.mdwn
new file mode 100644
index 000000000..25a69c1b7
--- /dev/null
+++ b/doc/tips/visualizing_repositories_with_gource.mdwn
@@ -0,0 +1,22 @@
+[Gource](http://code.google.com/p/gource/) is an amazing animated
+visualisation of a git repository.
+
+Normally, gource shows files being added, removed, and changed in
+the repository, and the user(s) making the changes. Of course it can be
+used in this way in a repository using git-annex too; just run `gource`.
+
+The other way to use gource with git-annex is to visualise the movement of
+annexed file contents between repositories. In this view, the "users" are
+repositories, and they move around the file contents that are being added
+or removed from them with git-annex.
+
+[[!img screenshot.jpg]]
+
+To use gource this way, first go into the directory you want to visualize,
+and use `git annex log` to make an input file for `gource`:
+
+ git annex log --gource | tee gource.log
+ sort gource.log | gource --log-format custom -
+
+The `git annex log` can take a while, to speed it up you can use something
+like `--after "4 months ago"` to limit how far back it goes.
diff --git a/doc/tips/visualizing_repositories_with_gource/screenshot.jpg b/doc/tips/visualizing_repositories_with_gource/screenshot.jpg
new file mode 100644
index 000000000..9d3096b99
--- /dev/null
+++ b/doc/tips/visualizing_repositories_with_gource/screenshot.jpg
Binary files differ
diff --git a/doc/tips/what_to_do_when_a_repository_is_corrupted.mdwn b/doc/tips/what_to_do_when_a_repository_is_corrupted.mdwn
new file mode 100644
index 000000000..80cb046d9
--- /dev/null
+++ b/doc/tips/what_to_do_when_a_repository_is_corrupted.mdwn
@@ -0,0 +1,22 @@
+A git-annex repository on a removable USB drive is great, until the cable
+falls out at the wrong time and git's repository gets trashed. The way
+git checksums everything and the poor quality of USB media makes this
+perhaps more likely than you would expect. If this happens to you,
+here's a way to recover that makes the most of whatever data is left
+on the drive.
+
+* First, run `git fsck`. If it does not report any problems, your data
+ is fine, and you don't need to proceed further.
+* So `git fsck` says the git repository is corrupted. But probably the data
+ git-annex stored is fine. Your first step is to clone another copy
+ of the git repository from somewhere else. Let's call this clone
+ "$good", and the corrupted repository "$bad".
+* Preserve your git configuration changes, and the `annex.uuid` setting:
+ `mv $bad/.git/config $good/.git/config`
+* Move annexed data into the new repository: `mkdir $good/.git/annex; mv
+ $bad/.git/annex/objects $good/.git/annex/objects`
+* Reinitalize git-annex: `cd $good; git annex init`
+* Check for any problems with the annexed data: `cd $good; git annex fsck`
+* Now you can remove the corrupted repository, the new one is ready to use.
+
+--[[Joey]]
diff --git a/doc/tips/what_to_do_when_you_lose_a_repository.mdwn b/doc/tips/what_to_do_when_you_lose_a_repository.mdwn
new file mode 100644
index 000000000..363eeea4e
--- /dev/null
+++ b/doc/tips/what_to_do_when_you_lose_a_repository.mdwn
@@ -0,0 +1,19 @@
+So you lost a thumb drive containing a git-annex repository. Or a hard
+drive died or some other misfortune has befallen your data.
+
+Unless you configured backups, git-annex can't get your data back. But it
+can help you deal with the loss.
+
+Go somewhere that knows about the lost repository, and mark it as
+dead:
+
+ git annex dead usbdrive
+
+This retains the [[location_tracking]] information for the repository,
+but avoids trying to access it, or list it as a location where files
+are present.
+
+If you later found the drive, you could let git-annex know it's found
+like so:
+
+ git annex semitrust usbdrive
diff --git a/doc/tips/what_to_do_when_you_lose_a_repository/comment_1_cf19b8dc304dc37c26717174c4a98aa4._comment b/doc/tips/what_to_do_when_you_lose_a_repository/comment_1_cf19b8dc304dc37c26717174c4a98aa4._comment
new file mode 100644
index 000000000..a7fce26ef
--- /dev/null
+++ b/doc/tips/what_to_do_when_you_lose_a_repository/comment_1_cf19b8dc304dc37c26717174c4a98aa4._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://dlaxalde.myopenid.com/"
+ nickname="dl"
+ subject="comment 1"
+ date="2012-05-31T14:36:33Z"
+ content="""
+Is there a way to have git-annex completely ignore a repository? I see that
+the `dead` command adds the uuid of the repository to `trust.log` but does
+not change `uuid.log`. Is it enough to remove the corresponding line in
+`uuid.log` and `trust.log`?
+"""]]
diff --git a/doc/tips/what_to_do_when_you_lose_a_repository/comment_3_fa9ca81668f5faebf2f61b10f82c97d2._comment b/doc/tips/what_to_do_when_you_lose_a_repository/comment_3_fa9ca81668f5faebf2f61b10f82c97d2._comment
new file mode 100644
index 000000000..a8d044c28
--- /dev/null
+++ b/doc/tips/what_to_do_when_you_lose_a_repository/comment_3_fa9ca81668f5faebf2f61b10f82c97d2._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.8.243"
+ subject="comment 3"
+ date="2012-05-31T17:01:37Z"
+ content="""
+`dead` is the best we can do. The automatic merging used on the git-annex branch tends to re-add lines that are deleted in one repo when merging with another that still has them.
+"""]]
diff --git a/doc/tips/yet_another_simple_disk_usage_like_utility.mdwn b/doc/tips/yet_another_simple_disk_usage_like_utility.mdwn
new file mode 100644
index 000000000..961776e19
--- /dev/null
+++ b/doc/tips/yet_another_simple_disk_usage_like_utility.mdwn
@@ -0,0 +1,9 @@
+Here's the annex-du script that I use:
+
+#!/bin/sh
+git annex find "$@" --include '*' --format='${bytesize}\n' |awk '{ sum += $1; nfiles++; } END { printf "%d files, %.3f MB\n", nfiles, sum/1000000 } '
+
+This one can be slow on a large number of files, but it has an advantage of being able to use all of the filtering available in git annex find.
+For example, to figure out how much is stored in remote X, do
+
+annex-du --in=X
diff --git a/doc/tips/yet_another_simple_disk_usage_like_utility/comment_1_41b212bde8bc88d2a5dea93bd0dc75f1._comment b/doc/tips/yet_another_simple_disk_usage_like_utility/comment_1_41b212bde8bc88d2a5dea93bd0dc75f1._comment
new file mode 100644
index 000000000..4c3e3c22b
--- /dev/null
+++ b/doc/tips/yet_another_simple_disk_usage_like_utility/comment_1_41b212bde8bc88d2a5dea93bd0dc75f1._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawln3ckqKx0x_xDZMYwa9Q1bn4I06oWjkog"
+ nickname="Michael"
+ subject="comment 1"
+ date="2013-07-12T19:36:28Z"
+ content="""
+Ah, I just found that git annex info can do the same :)
+Disregard this.
+"""]]
diff --git a/doc/tips/yet_another_simple_disk_usage_like_utility/comment_2_73698913837bfd5a58cf15721211e43e._comment b/doc/tips/yet_another_simple_disk_usage_like_utility/comment_2_73698913837bfd5a58cf15721211e43e._comment
new file mode 100644
index 000000000..fe4b3d0d2
--- /dev/null
+++ b/doc/tips/yet_another_simple_disk_usage_like_utility/comment_2_73698913837bfd5a58cf15721211e43e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/2grhJvAC049fJnvALDXek.6MRZMTlg--#eec89"
+ nickname="John"
+ subject="comment 2"
+ date="2013-08-30T06:09:29Z"
+ content="""
+You may want to try my `sizes` tool on Hackage. Just pass `-A` and it will be aware of the annex and report sizes as if no files were annexed. The only downside is that it reports file usage for replicated content multiple times, as if you'd copied the data out of the annex rather than hardlinked all duplicate copies (although, this may be exactly the behavior some people want).
+"""]]
diff --git a/doc/todo.mdwn b/doc/todo.mdwn
new file mode 100644
index 000000000..79552298b
--- /dev/null
+++ b/doc/todo.mdwn
@@ -0,0 +1,4 @@
+This is git-annex's todo list. Link items to [[todo/done]] when done.
+
+[[!inline pages="./todo/* and !./todo/done and !link(done)
+and !*/Discussion" actions=yes postform=yes show=0 archive=yes]]
diff --git a/doc/todo/A_really_simple_way_to_pair_devices_like_bittorent_sync.mdwn b/doc/todo/A_really_simple_way_to_pair_devices_like_bittorent_sync.mdwn
new file mode 100644
index 000000000..93ccc083d
--- /dev/null
+++ b/doc/todo/A_really_simple_way_to_pair_devices_like_bittorent_sync.mdwn
@@ -0,0 +1,7 @@
+I like the way btsync search for the peer. So if I need to sync my laptop and other family laptop both with a total different and changing network setup the two device found each other do NAT traversal if needed use relays but the end the two folders are synced. But its closed-source :( I like git and git-annex looks really great. I'm learning it now.
+
+First I thought with xmpp I can sync files without ssh/rsync or other remote access to my devices just with two jabber account. Now I know I can't. :(
+
+It would be just great to have some means to sync files without cloud just the two device. Without the ssh / rsync jut share some secret and the devices do the rest. :-o
+
+Anyway thanks for hearing. I'm looking forward to know more about git-annex. Thank you for that sw. =-<>-=
diff --git a/doc/todo/A_really_simple_way_to_pair_devices_like_bittorent_sync/comment_1_d828bc374e50a49101c0b863f9b33080._comment b/doc/todo/A_really_simple_way_to_pair_devices_like_bittorent_sync/comment_1_d828bc374e50a49101c0b863f9b33080._comment
new file mode 100644
index 000000000..13571e681
--- /dev/null
+++ b/doc/todo/A_really_simple_way_to_pair_devices_like_bittorent_sync/comment_1_d828bc374e50a49101c0b863f9b33080._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkEHjHAWnJ0BJzdv_hePwU1my8X4wCseh8"
+ nickname="Sz"
+ subject="comment 1"
+ date="2013-07-23T11:00:21Z"
+ content="""
+Why not use xmpp for file transfer too not only for git sync?
+"""]]
diff --git a/doc/todo/A_really_simple_way_to_pair_devices_like_bittorent_sync/comment_2_a4badfc248be428e6426a936212cc896._comment b/doc/todo/A_really_simple_way_to_pair_devices_like_bittorent_sync/comment_2_a4badfc248be428e6426a936212cc896._comment
new file mode 100644
index 000000000..2bff793f0
--- /dev/null
+++ b/doc/todo/A_really_simple_way_to_pair_devices_like_bittorent_sync/comment_2_a4badfc248be428e6426a936212cc896._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://johan.kiviniemi.name/"
+ ip="83.145.237.224"
+ subject="comment 2"
+ date="2013-07-23T11:37:53Z"
+ content="""
+Transferring the data over XMPP would almost certainly take too much XMPP server bandwidth, but using something like [libjingle](https://developers.google.com/talk/libjingle/) to set up P2P connections should work nicely. That would require libjingle (or equivalent) bindings for Haskell, though. Libjingle negotiates over XMPP to set up the P2P connection and provides a TCP-like layer for reliable, ordered communication. One could use that for both git metadata and the file transfers.
+"""]]
diff --git a/doc/todo/A_really_simple_way_to_pair_devices_like_bittorent_sync/comment_3_0b04089d3d33fdb48eeb46bf168e9a3c._comment b/doc/todo/A_really_simple_way_to_pair_devices_like_bittorent_sync/comment_3_0b04089d3d33fdb48eeb46bf168e9a3c._comment
new file mode 100644
index 000000000..d0c000d2b
--- /dev/null
+++ b/doc/todo/A_really_simple_way_to_pair_devices_like_bittorent_sync/comment_3_0b04089d3d33fdb48eeb46bf168e9a3c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkEHjHAWnJ0BJzdv_hePwU1my8X4wCseh8"
+ nickname="Sz"
+ subject="comment 3"
+ date="2013-07-24T09:08:45Z"
+ content="""
+I'm for it! +1
+"""]]
diff --git a/doc/todo/A_really_simple_way_to_pair_devices_like_bittorent_sync/comment_4_2bcab1b7998b4df08fca41b8d810f115._comment b/doc/todo/A_really_simple_way_to_pair_devices_like_bittorent_sync/comment_4_2bcab1b7998b4df08fca41b8d810f115._comment
new file mode 100644
index 000000000..f3bafca89
--- /dev/null
+++ b/doc/todo/A_really_simple_way_to_pair_devices_like_bittorent_sync/comment_4_2bcab1b7998b4df08fca41b8d810f115._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 4"
+ date="2013-08-03T07:12:40Z"
+ content="""
+NAT traversal requires central infrastructure and is unreliable at best. Obviously, a for-profit entity like bittorrent can shoulder that.
+
+For LAN situations, [zeroconf](http://www.zeroconf.org/) along with passphrase-based pairing may be the long-term answer. Arguably, that would enhance vanilla Git almost as much as it would enhance git-annex, but that does not seem likely to happen.
+"""]]
diff --git a/doc/todo/A_really_simple_way_to_pair_devices_like_bittorent_sync/comment_5_677e958c3f2effec7528b484aeb6478d._comment b/doc/todo/A_really_simple_way_to_pair_devices_like_bittorent_sync/comment_5_677e958c3f2effec7528b484aeb6478d._comment
new file mode 100644
index 000000000..07b001c2e
--- /dev/null
+++ b/doc/todo/A_really_simple_way_to_pair_devices_like_bittorent_sync/comment_5_677e958c3f2effec7528b484aeb6478d._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5iosFbL2By7UFeViqkc6v-hoAtqILeDA"
+ nickname="Laszlo"
+ subject="comment 5"
+ date="2013-08-25T07:48:18Z"
+ content="""
+What is the problem with bittorrent protocol in general?
+It is some technicality or purely philosophical?
+
+Best,
+ Laszlo
+
+"""]]
diff --git a/doc/todo/A_really_simple_way_to_pair_devices_like_bittorent_sync/comment_6_56e53803fdede895cba717e6b6e9a1bb._comment b/doc/todo/A_really_simple_way_to_pair_devices_like_bittorent_sync/comment_6_56e53803fdede895cba717e6b6e9a1bb._comment
new file mode 100644
index 000000000..41e1bda78
--- /dev/null
+++ b/doc/todo/A_really_simple_way_to_pair_devices_like_bittorent_sync/comment_6_56e53803fdede895cba717e6b6e9a1bb._comment
@@ -0,0 +1,23 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmkBwMWvNKZZCge_YqobCSILPMeK6xbFw8"
+ nickname="develop"
+ subject="comment 6"
+ date="2013-08-25T08:39:15Z"
+ content="""
+I just did a cursory search on haskell torrent support. And the required pieces do seem to be be there.
+https://github.com/jlouis/combinatorrent or https://github.com/astro/haskell-torrent for downloading. i'm not sure if either supports DHT, but that exists here https://github.com/aninhumer/haskell-dht
+
+That said, i think implementing this would require some quite major overhauls in the system. It probably won't be trivial to implement.
+
+Note: This is for straight \"bittorrent\", not for \"bittorrent sync\". Bittorrent sync is closed source, and while an API might come at some point, it doesn't currently exist.
+
+I do seem to recall joeyh talking about supporting further transport protocols(perhaps through hooks). So I'm adding the above links for future reference if this does get implemented.
+
+But IMHO, this doesn't seem like a trivial feature to add. It might have to take some refactoring of some core git-annex parts. Certain things have to be changed quite a bit.
+
+Currently a git-annex client doesn't really require anything(except rsync) to sync from a remote. With bittorrent with DHT support to share between clients, suddenly git-annex will have to maintain a constant bittorrent thread(maybe multiple) that constantly seeds all the files in the git-annex repository, while waiting for a potential remote to request data.
+
+So even if this happens, it is probably gonna take some time.
+
+Just my 2cents.
+"""]]
diff --git a/doc/todo/Bittorrent-like_features.mdwn b/doc/todo/Bittorrent-like_features.mdwn
new file mode 100644
index 000000000..41988a422
--- /dev/null
+++ b/doc/todo/Bittorrent-like_features.mdwn
@@ -0,0 +1,45 @@
+There are two different possible ways git-annex could use bittorrent:
+
+Let's describe those one by one.
+
+[[!toc]]
+
+Downloading files from multiple git-annex sources simultaneously
+================================================================
+
+Having your remotes (optionally!) act like a swarm would be an awesome feature to have because you bring in a lot of new features that optimize storage, bandwidth, and overall traffic usage. This would be made a lot easier if parts of it were implemented in small steps that added a nifty feature. The best part is, each of these could be implemented by themselves, and they're all features that would be really useful.
+
+ 1. Concurrent downloads of a file from remotes.
+
+ This would make sense to have, it saves upload traffic on your remotes, and you also get faster DL speeds on the receiving end.
+
+ 2. Implementing part of the super-seeding capabilities.
+
+ You upload pieces of a file to different remotes from your laptop, and on your desktop you can download all those pieces and put them together again to get a complete file. If you really wanted to get fancy, you could build in redundancy (ala RAID) so if a remote or two gets lost, you don't lose the entire file. This would be a very efficient use of storage if you have a bunch of free cloud storage accounts (~1GB each) and some big files you want to back up.
+
+ 3. Setting it up so that those remotes could talk to one another and share those pieces.
+
+ This is where it gets more like bittorrent. Useful because you upload 1 copy and in a few hours, have say, 5 complete copies on 5 different remotes. You could add or remove remotes from a swarm locally, and push those changes to those remotes, which then adapt themselves to suit the new rules and share those with other remotes in the swarm (rules should be GPG-signed as a safety precaution). Also, if/when deltas get implemented, you could push that delta to the swarm and have all the remotes adopt it. This is cooler than regular bittorrent because the shared file can be updated. As a safety precaution, the delta could be GPG signed so a corrupt file doesn't contaminate the entire swarm. Each remote could have bandwidth/storage limits set in a dotfile.
+
+This is a high-level idea of how it might work, and it's also a HUGE set of features to add, but if implemented, you'd be saving a ton of resources, adding new use cases, and making git-annex more flexible.
+
+Obviously, Step 3 would only work on remotes that you have control of processes on, but if given login credentials to cloud storage remotes (potentially dangerous!) they could read/write to something like dropbox or rsync.
+
+Another thing, this would be completely trackerless. You just use remote groups (or create swarm definitions) and share those with your remotes. **It's completely decentralized!**
+
+This was originally posted [[as a forum post|forum/Wishlist:_Bittorrent-like_transfers]] by [[users/GLITTAH]].
+
+Using an external client (addurl torrent support)
+=================================================
+
+The alternative to this would be to add `addurl` support for bittorrent files. The same way we can now add Youtube videos to a git-annex repository thanks to [[quvi]], we could also simply do:
+
+ git annex addtorrent debian-live-7.0.0-amd64-standard.iso.torrent
+
+or even better:
+
+ git annex addurl http://cdimage.debian.org/debian-cd/current-live/amd64/bt-hybrid/debian-live-7.0.0-amd64-standard.iso.torrent
+
+This way, a torrent would just become another source for a specific file. When we `get` the file, it fires up `$YOUR_FAVORITE_TORRENT_CLIENT` to download the file.
+
+That way we avoid the implementation complexity of shoving a complete bittorrent client within the assistant. The `get` operation would block until the torrent is downloaded, i guess... --[[anarcat]]
diff --git a/doc/todo/Bittorrent-like_features/comment_1_f4c110ef35ebf4fd89f06edf2c4f0c48._comment b/doc/todo/Bittorrent-like_features/comment_1_f4c110ef35ebf4fd89f06edf2c4f0c48._comment
new file mode 100644
index 000000000..eba291af9
--- /dev/null
+++ b/doc/todo/Bittorrent-like_features/comment_1_f4c110ef35ebf4fd89f06edf2c4f0c48._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="Gastlag"
+ ip="109.190.97.30"
+ subject="Gittorrent"
+ date="2013-08-28T21:49:56Z"
+ content="""
+May this could interest you : few years ago somes tried to mix Git and Bittorrent.
+
+http://www.advogato.org/article/994.html
+http://utsl.gen.nz/gittorrent/rfc.html
+http://code.google.com/p/gittorrent/
+https://git.wiki.kernel.org/index.php/SoC2010Application#Did_your_organization_participate_in_past_GSoCs.3F_If_so.2C_please_summarize_your_involvement_and_the_successes_and_challenges_of_your_participation
+"""]]
diff --git a/doc/todo/Build_for_Synology_DSM.mdwn b/doc/todo/Build_for_Synology_DSM.mdwn
new file mode 100644
index 000000000..be45ea631
--- /dev/null
+++ b/doc/todo/Build_for_Synology_DSM.mdwn
@@ -0,0 +1 @@
+It would be wonderful if a pre-built package would be available for Synology NAS. Basically, this is an ARM-based Linux. It has most of the required shell commands either out of the box or easily available (through ipkg). But I think it would be difficult to install the Haskell compiler and all the required modules, so it would probably be better to cross-compile targeting ARM.
diff --git a/doc/todo/Build_for_Synology_DSM/comment_10_e351084d9a83db3fd6d9d983227a6410._comment b/doc/todo/Build_for_Synology_DSM/comment_10_e351084d9a83db3fd6d9d983227a6410._comment
new file mode 100644
index 000000000..b62a929d7
--- /dev/null
+++ b/doc/todo/Build_for_Synology_DSM/comment_10_e351084d9a83db3fd6d9d983227a6410._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkwjBDXkP9HAQKhjTgThGOxUa1B99y_WRA"
+ nickname="Franck"
+ subject="comment 10"
+ date="2013-06-02T17:23:43Z"
+ content="""
+I updated the C program to simplify it so it uses a static path for `_chrooter`. In the previous version, I suspect that one can play with symlinks and use it to get a root shell. So, if `_chrooter` is not installed in `/opt/bin` this file has to be edited too before compilation.
+"""]]
diff --git a/doc/todo/Build_for_Synology_DSM/comment_11_cc67a584f5c460a6fb63cf099c20e573._comment b/doc/todo/Build_for_Synology_DSM/comment_11_cc67a584f5c460a6fb63cf099c20e573._comment
new file mode 100644
index 000000000..324fa8423
--- /dev/null
+++ b/doc/todo/Build_for_Synology_DSM/comment_11_cc67a584f5c460a6fb63cf099c20e573._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkwjBDXkP9HAQKhjTgThGOxUa1B99y_WRA"
+ nickname="Franck"
+ subject="comment 11"
+ date="2013-06-03T09:55:54Z"
+ content="""
+A last update and I stop spamming this thread: I've implemented access control and simplified customisation. All this has been moved to https://bitbucket.org/franckp/gasp
+
+"""]]
diff --git a/doc/todo/Build_for_Synology_DSM/comment_12_94023593d294b9cf69090fcfd6ca0e5a._comment b/doc/todo/Build_for_Synology_DSM/comment_12_94023593d294b9cf69090fcfd6ca0e5a._comment
new file mode 100644
index 000000000..39c243ec4
--- /dev/null
+++ b/doc/todo/Build_for_Synology_DSM/comment_12_94023593d294b9cf69090fcfd6ca0e5a._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlJEI45rGczFAnuM7gRSj4C6s9AS9yPZDc"
+ nickname="Kevin"
+ subject="SynoCommunity"
+ date="2013-06-26T18:12:39Z"
+ content="""
+Creating an installable git-annex package available via [SynoCommunity](http://www.synocommunity.com/) would be awesome. They have created [cross-compilation tools](https://github.com/SynoCommunity/spksrc) to help build the packages and integrate the start/stop scripts with the package manager.
+
+"""]]
diff --git a/doc/todo/Build_for_Synology_DSM/comment_13_314255fd503d125b5aeae2f62acfd592._comment b/doc/todo/Build_for_Synology_DSM/comment_13_314255fd503d125b5aeae2f62acfd592._comment
new file mode 100644
index 000000000..3c54a9271
--- /dev/null
+++ b/doc/todo/Build_for_Synology_DSM/comment_13_314255fd503d125b5aeae2f62acfd592._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnrP-0DGtHDJbWSXeiyk0swNkK1aejoN3c"
+ nickname="sebastien"
+ subject="comment 13"
+ date="2013-08-06T12:18:35Z"
+ content="""
+I post an issue to github synocommunity for that, i hope somenone have some time to package this great features.
+"""]]
diff --git a/doc/todo/Build_for_Synology_DSM/comment_15_9525cd0d75ff4c15182d10a855774b69._comment b/doc/todo/Build_for_Synology_DSM/comment_15_9525cd0d75ff4c15182d10a855774b69._comment
new file mode 100644
index 000000000..c3edf99e2
--- /dev/null
+++ b/doc/todo/Build_for_Synology_DSM/comment_15_9525cd0d75ff4c15182d10a855774b69._comment
@@ -0,0 +1,30 @@
+[[!comment format=mdwn
+ username="lorenzo"
+ ip="84.75.27.69"
+ subject="Running Debian squeeze binaries on libc 2.5 based NAS"
+ date="2013-10-27T23:56:26Z"
+ content="""
+Following the suggestions in this page I tried to run the binaries that debian provides on my Lacie NetworkSpace which is another one of these NAS devices with old libc. After uploading the binaries and required libraries and using `LD_LIBRARY_PATH` to force the loader to use the version I uploaded of the libraries I was still having a segfault (similar to what Franck was experiencing) while running git-annex in a chroot was working.
+
+It turns out that it is possible to solve the problem without having to use chroot by not loading the binary directly but by substituting it with a script that calls the correct `ld-linux.so.3`. Assume you have uncompressed the files from the deb packages in `/opt/git-annex`.
+
+First create a directory `/opt/git-annex/usr/bin/git-annex.exec` and copy the executable `/opt/git-annex/usr/bin/git-annex` there.
+
+Then create script `/opt/git-annex/usr/bin/git-annex` with the following contents:
+
+ #!/bin/bash
+
+ PREFIX=/opt/git-annex
+
+ export GCONV_PATH=$PREFIX/usr/lib/gconv
+
+ exec $PREFIX/lib/ld-linux.so.3 --library-path $PREFIX/lib/:$PREFIX/usr/lib/ $PREFIX/usr/bin/git-annex.exec/git-annex \"$@\"
+
+The `GCONV_PATH` setting is important to prevent the app from failing with the message:
+
+ git-annex.exec: mkTextEncoding: invalid argument (Invalid argument)
+
+The original executable is moved to a different directory instead of being simply renamed to make sure that `$0` is correct when the executable starts. The parameter for the linker `--library-path` is used instead of the environment variable `LD_LIBRARY_PATH` to make sure that the programs exec'ed by git-annex do not have the variable set.
+
+Some more info about the approach: [[http://www.novell.com/coolsolutions/feature/11775.html]]
+"""]]
diff --git a/doc/todo/Build_for_Synology_DSM/comment_1_4059016fa8da6af7a3eba8966821e8eb._comment b/doc/todo/Build_for_Synology_DSM/comment_1_4059016fa8da6af7a3eba8966821e8eb._comment
new file mode 100644
index 000000000..074ba998c
--- /dev/null
+++ b/doc/todo/Build_for_Synology_DSM/comment_1_4059016fa8da6af7a3eba8966821e8eb._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-05-24T15:55:42Z"
+ content="""
+There are already git-annex builds for arm available from eg, Debian. There's a good chance that, assuming you match up the arm variant (armel, armhf, etc) and that the NAS uses glibc and does not have too old a version, that the binary could just be copied in, possibly with some other libraries, and work. This is what's done for the existing Linux standalone builds.
+
+So, I look at this bug report as \"please add a standalone build for arm\", not as a request to support a specific NAS which I don't have ;)
+"""]]
diff --git a/doc/todo/Build_for_Synology_DSM/comment_2_8900c2985ab68b3b566c9f5d326471d6._comment b/doc/todo/Build_for_Synology_DSM/comment_2_8900c2985ab68b3b566c9f5d326471d6._comment
new file mode 100644
index 000000000..40e6398f0
--- /dev/null
+++ b/doc/todo/Build_for_Synology_DSM/comment_2_8900c2985ab68b3b566c9f5d326471d6._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkwjBDXkP9HAQKhjTgThGOxUa1B99y_WRA"
+ nickname="Franck"
+ subject="comment 2"
+ date="2013-05-24T21:31:44Z"
+ content="""
+I tried to run the binary from the Debian package, unfortunately, after installing tons of libraries, git-annex fails complaining that GLIBC is not recent enough. Perhaps a static build for ARM (armel) can solve the problem? Thanks again for your help!
+"""]]
diff --git a/doc/todo/Build_for_Synology_DSM/comment_3_f2b77368473d42b7f21e9d51d6415b58._comment b/doc/todo/Build_for_Synology_DSM/comment_3_f2b77368473d42b7f21e9d51d6415b58._comment
new file mode 100644
index 000000000..651edacd7
--- /dev/null
+++ b/doc/todo/Build_for_Synology_DSM/comment_3_f2b77368473d42b7f21e9d51d6415b58._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 3"
+ date="2013-05-25T04:42:22Z"
+ content="""
+Which Debian package? Different ones link to different libcs.
+
+(It's not really possible to statically link something with as many dependencies as git-annex on linux anymore, unfortunately.)
+"""]]
diff --git a/doc/todo/Build_for_Synology_DSM/comment_4_a55fea734044c270ceb10adf9c8d9a76._comment b/doc/todo/Build_for_Synology_DSM/comment_4_a55fea734044c270ceb10adf9c8d9a76._comment
new file mode 100644
index 000000000..50ae82ca0
--- /dev/null
+++ b/doc/todo/Build_for_Synology_DSM/comment_4_a55fea734044c270ceb10adf9c8d9a76._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkwjBDXkP9HAQKhjTgThGOxUa1B99y_WRA"
+ nickname="Franck"
+ subject="comment 4"
+ date="2013-05-25T07:40:13Z"
+ content="""
+I've actually tried several ones: 4.20130521 on sid, 3.20120629~bpo60+2 on squeeze-backports, 3.20120629 on wheezy and jessie, plus a package for Ubuntu 11.02. All of them try to load GLIBC 2.6/2.7 while my system has 2.5 only... I'll try a different approach: install Debian in a chroot on the NAS and extract all the required files, including all libraries.
+"""]]
diff --git a/doc/todo/Build_for_Synology_DSM/comment_5_59865ada057c640ac29855c65cf45dd9._comment b/doc/todo/Build_for_Synology_DSM/comment_5_59865ada057c640ac29855c65cf45dd9._comment
new file mode 100644
index 000000000..725025283
--- /dev/null
+++ b/doc/todo/Build_for_Synology_DSM/comment_5_59865ada057c640ac29855c65cf45dd9._comment
@@ -0,0 +1,23 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkwjBDXkP9HAQKhjTgThGOxUa1B99y_WRA"
+ nickname="Franck"
+ subject="comment 5"
+ date="2013-05-25T10:03:24Z"
+ content="""
+Unfortunately, chroot approach does not work either. While git-annex works fine when I'm in the chroot, it doesn't work any more outside. If I don't copy libc, I get a version error (just like before so this is normal):
+
+ git-annex: /lib/libc.so.6: version `GLIBC_2.7' not found (required by /opt/share/git-annex/bin/git-annex)
+ git-annex: /lib/libc.so.6: version `GLIBC_2.6' not found (required by /opt/share/git-annex/bin/git-annex)
+ git-annex: /lib/libc.so.6: version `GLIBC_2.7' not found (required by /opt/share/git-annex/lib/libgmp.so.10)
+
+When I copy libc from the Debian chroot, then, it complains about libpthread:
+
+ git-annex: relocation error: /lib/libpthread.so.0: symbol __default_rt_sa_restorer, version GLIBC_PRIVATE not defined in file libc.so.6 with link time reference
+
+If then I copy libpthread also, I get:
+
+ Illegal instruction (core dumped)
+
+So, I'm stuck... :-(
+I'll try to find a way using the version in the chroot instead of trying to export it to the host system...
+"""]]
diff --git a/doc/todo/Build_for_Synology_DSM/comment_6_6d860b1ad8816077b5fa596a71b12d5c._comment b/doc/todo/Build_for_Synology_DSM/comment_6_6d860b1ad8816077b5fa596a71b12d5c._comment
new file mode 100644
index 000000000..417293db3
--- /dev/null
+++ b/doc/todo/Build_for_Synology_DSM/comment_6_6d860b1ad8816077b5fa596a71b12d5c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawln3ckqKx0x_xDZMYwa9Q1bn4I06oWjkog"
+ nickname="Michael"
+ subject="bind mount"
+ date="2013-05-25T15:55:52Z"
+ content="""
+You could bind-mount (e.g. mount -o bind /data /chroot/data ) your main Synology fs into the chroot for git-annex to use.
+"""]]
diff --git a/doc/todo/Build_for_Synology_DSM/comment_7_19ef2d293ba3bc7ece443d7278371c3f._comment b/doc/todo/Build_for_Synology_DSM/comment_7_19ef2d293ba3bc7ece443d7278371c3f._comment
new file mode 100644
index 000000000..47d092331
--- /dev/null
+++ b/doc/todo/Build_for_Synology_DSM/comment_7_19ef2d293ba3bc7ece443d7278371c3f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkwjBDXkP9HAQKhjTgThGOxUa1B99y_WRA"
+ nickname="Franck"
+ subject="comment 7"
+ date="2013-05-25T19:01:29Z"
+ content="""
+This is indeed what I'm doing. But I need to make a wrapper that will call the command in the chroot. Thanks for the tip anyway. :-)
+"""]]
diff --git a/doc/todo/Build_for_Synology_DSM/comment_8_609b7ad87dfbba49ec1f8c6fc2739ccd._comment b/doc/todo/Build_for_Synology_DSM/comment_8_609b7ad87dfbba49ec1f8c6fc2739ccd._comment
new file mode 100644
index 000000000..8a3490956
--- /dev/null
+++ b/doc/todo/Build_for_Synology_DSM/comment_8_609b7ad87dfbba49ec1f8c6fc2739ccd._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmqz6wCn-Q1vzrsHGvEJHOt_T5ZESilxhc"
+ nickname="Sören"
+ subject="comment 8"
+ date="2013-05-26T13:50:31Z"
+ content="""
+I have a Synology NAS too, so I thought I could try to run git-annex in a Debian chroot.
+As it [turns out](http://forum.synology.com/wiki/index.php/What_kind_of_CPU_does_my_NAS_have), my model (DS213+) runs on a PowerPC CPU instead of ARM. Unfortunately, it isn't compatible with PPC in Debian either because it is a different PowerPC variant.
+There is an unofficial Debian port called [powerpcspe](http://wiki.debian.org/PowerPCSPEPort), but ghc doesn't build there yet for [some reason](http://buildd.debian-ports.org/status/package.php?p=git-annex&suite=sid).
+
+Any chance that there will be a build for this architecture at some point in the future or should I better look for another NAS? ;-)
+"""]]
diff --git a/doc/todo/Build_for_Synology_DSM/comment_9_d94a73b9a07c5cadf191005f817fd59a._comment b/doc/todo/Build_for_Synology_DSM/comment_9_d94a73b9a07c5cadf191005f817fd59a._comment
new file mode 100644
index 000000000..c8b45fc60
--- /dev/null
+++ b/doc/todo/Build_for_Synology_DSM/comment_9_d94a73b9a07c5cadf191005f817fd59a._comment
@@ -0,0 +1,29 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkwjBDXkP9HAQKhjTgThGOxUa1B99y_WRA"
+ nickname="Franck"
+ subject="comment 9"
+ date="2013-06-02T13:14:56Z"
+ content="""
+Hi, I finally succeeded! :-)
+
+Here are the main steps:
+
+ 1. install `debian-chroot` on the NAS
+ 2. create an account `gitannex` in Debian
+ 3. configure git on this account (this is important otherwise git complains and fails) `git config --global user.email YOUR_EMAIL` and `git config --global user.name YOUR_NAME`
+ 4. install `gcc` on the NAS (using `ipkg`)
+ 5. download the files here: https://www.dropbox.com/sh/b7z68a730aj3mnm/95nFOzE1QP
+ 6. edit `_chrooter` to fit your settings (probably there is nothing to change if your Debian is freshly installed)
+ 7. run `make install`, everything goes to `/opt/bin`, if you change this, you should also edit line 17 in file `gasp`
+ 8. create an account `gitannex` on the NAS (doesn't need to be the same name as in Debian, but I feel it is easier)
+ 9. edit its `.ssh/authorized_keys` to prefix lines as follows `command=\"gasp\" THE_PUBLIC_KEY_AS_USUAL`
+ 10. it should work
+ 11. the repositories will be in the Debian account, but it's easy to symlink them in the NAS account if you wish
+
+The principle is as follows: `command=\"gasp\"` allows to launch `gasp` on SSH connexion instead of the original command given to `ssh`. This command is retrieved by `gasp` and prefixed with `chrooter-` (so, eg, running `ssh git` on the client results in running `chrooter-git` on the NAS). `chrooter-*` commands are symlinks to `chrooter`, this is a setuid root binary that launches `_chrooter`. (This intermediary binary is necessary because `_chrooter` is a script which cannot be setuid, and setuid is required for the chroot and identity change.) Finally, `_chrooter` starts the `debian-chroot` service, chroot to the target dir, changes identity and eventually launches the original command as if it was lauched directly by `gitannex` user in Debian. `_chrooter` and `gasp` are Python scripts, I did not use shell in order to avoid error-prone issues with spaces in arguments (that need to be passed around several times in the process).
+
+I'll try now to add command-line parameters to `gasp` in order to restrict the commands that can be run through SSH and the repositories allowed.
+
+Cheers,
+Franck
+"""]]
diff --git a/doc/todo/Check_if_an_upgrade_is_available_in_the_webapp.mdwn b/doc/todo/Check_if_an_upgrade_is_available_in_the_webapp.mdwn
new file mode 100644
index 000000000..e102606ca
--- /dev/null
+++ b/doc/todo/Check_if_an_upgrade_is_available_in_the_webapp.mdwn
@@ -0,0 +1,5 @@
+Especially on Mac OSX (and Windows, and maybe Android), it would be great to be able to check in the webapp if an upgrade is available. A deeper integration with these OS would be even better: for example on Mac OSX, an icon on the status bar list available upgrades for some programs, including LibreOffice and others which are not installed by default.
+
+Also, it would be great to be able to download and install git-annex upgrades directly from the webapp.
+
+> comprehensively [[done]]; [[design/assistant/upgrading]] --[[Joey]]
diff --git a/doc/todo/Check_if_an_upgrade_is_available_in_the_webapp/comment_1_c904182f6bff8b1a42070bbc038eb34e._comment b/doc/todo/Check_if_an_upgrade_is_available_in_the_webapp/comment_1_c904182f6bff8b1a42070bbc038eb34e._comment
new file mode 100644
index 000000000..750e3b83a
--- /dev/null
+++ b/doc/todo/Check_if_an_upgrade_is_available_in_the_webapp/comment_1_c904182f6bff8b1a42070bbc038eb34e._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.246"
+ subject="comment 1"
+ date="2013-11-15T20:51:18Z"
+ content="""
+I have thought about doing this, especially if there is ever a security hole in git-annex.
+
+All it needs is a file containing the version number to be written along-side the git-annex build, and git-annex knowing if it was built as a standalone build, and should check that.
+
+As for actually performing the upgrade:
+
+* Easy on Linux
+* Not sure on OSX.. Is it possible to use hdiutil attach to replace a dmg while a program contained in it is currently running?
+* Probably impossible on Android, at least not without using double the space. Probably better to get git-annex into an app store.
+* Doable on Windows, but would need git-annex to be distributed in a form that was not a installer.exe.
+"""]]
diff --git a/doc/todo/Deleting_Unused_Files_by_Age.mdwn b/doc/todo/Deleting_Unused_Files_by_Age.mdwn
new file mode 100644
index 000000000..b72768bca
--- /dev/null
+++ b/doc/todo/Deleting_Unused_Files_by_Age.mdwn
@@ -0,0 +1,13 @@
+I periodically move unused files to one of my servers. What I would like to
+do is drop any unused file that has been unused for say more than 6 months?
+I would like to not drop all unused files.
+
+> It strikes me that this is quite similar to how git handles deleting
+> stale refs with the reflog. So, if `git annex unused` were changed to
+> also look at the reflog, it would keep all files referred to by all refs
+> in the reflog, until the reflog expires. You could then set reflog expiry
+> to 6 months, and be done.
+>
+> However, I think that many users expect git annex unused to be able to
+> immediately find and remove a file after it's been deleted. So this
+> probably needs to be a configurable behavior. --[[Joey]]
diff --git a/doc/todo/Move_ssh_config_to___126____47__ssh__47__git-annex__47__config.mdwn b/doc/todo/Move_ssh_config_to___126____47__ssh__47__git-annex__47__config.mdwn
new file mode 100644
index 000000000..5dc063100
--- /dev/null
+++ b/doc/todo/Move_ssh_config_to___126____47__ssh__47__git-annex__47__config.mdwn
@@ -0,0 +1,7 @@
+### Please describe the problem.
+Instead of storing config for each remote in ~/.ssh/config, which mixes the user own config with that of git-annex-assistant, which is irritating if (like me) you store your ssh config in a vcs. Since the option -F allows the choice of the config file, it should be possible to move the config into ~/.ssh/git-annex/config. The only issue I see is according to the ssh man page on my system states that the system-wide config is ignored if a config file is specified on the command line.
+
+### What version of git-annex are you using? On what operating system?
+I'm using git-annex 4.20130601 on a Debian Testing/Unstable/Experimental mix.
+
+[[!tag design/assistant]]
diff --git a/doc/todo/Move_ssh_config_to___126____47__ssh__47__git-annex__47__config/comment_1_284c806e83a32af81b02aea7c7bc285a._comment b/doc/todo/Move_ssh_config_to___126____47__ssh__47__git-annex__47__config/comment_1_284c806e83a32af81b02aea7c7bc285a._comment
new file mode 100644
index 000000000..5997664e0
--- /dev/null
+++ b/doc/todo/Move_ssh_config_to___126____47__ssh__47__git-annex__47__config/comment_1_284c806e83a32af81b02aea7c7bc285a._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-06-11T14:44:47Z"
+ content="""
+The only interface git provides to do this is `GIT_SSH`, which would have to be set to a wrapper script that runs ssh with the desirned options.
+
+And if that were used, `git pull` by itself would not work on the repositories set up by the assistant. I don't consider that very nice.
+"""]]
diff --git a/doc/todo/Move_ssh_config_to___126____47__ssh__47__git-annex__47__config/comment_2_1f55ad6b39906458779b2d604b003ffe._comment b/doc/todo/Move_ssh_config_to___126____47__ssh__47__git-annex__47__config/comment_2_1f55ad6b39906458779b2d604b003ffe._comment
new file mode 100644
index 000000000..3cf75df08
--- /dev/null
+++ b/doc/todo/Move_ssh_config_to___126____47__ssh__47__git-annex__47__config/comment_2_1f55ad6b39906458779b2d604b003ffe._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-06-11T14:48:01Z"
+ content="""
+Also, if you're going to set up something like local pairing, why would you *not* want to commit that config to git along with your other ssh configs? Config files in $HOME are quite frequently edited by helper programs to configure changes, and I personally commit those changes all the time.
+
+Perhaps your real problem is that you have one `.ssh/config` that is shared between multiple hosts, and the git-annex settings are specific to a single host. Have you considered using [vcsh](https://github.com/RichiH/vcsh)?
+"""]]
diff --git a/doc/todo/Move_ssh_config_to___126____47__ssh__47__git-annex__47__config/comment_3_b00dce2374aac6968317d05d23bcfaf7._comment b/doc/todo/Move_ssh_config_to___126____47__ssh__47__git-annex__47__config/comment_3_b00dce2374aac6968317d05d23bcfaf7._comment
new file mode 100644
index 000000000..3442fb2b2
--- /dev/null
+++ b/doc/todo/Move_ssh_config_to___126____47__ssh__47__git-annex__47__config/comment_3_b00dce2374aac6968317d05d23bcfaf7._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawk3Wgg0XiqYFwM_Pw1RxZwlpNFi65g17sM"
+ nickname="James"
+ subject="comment 3"
+ date="2013-06-12T01:12:24Z"
+ content="""
+Ah, ok, I presumed there was an option in git to set a per-repository ssh command. I've looked at vcsh, but I'm not that confident with git remotes, so I don't use it (I use hg). If a per-repository ssh command added to git, would you consider adding this?
+"""]]
diff --git a/doc/todo/Move_ssh_config_to___126____47__ssh__47__git-annex__47__config/comment_4_743d0b077110c5cac1e2f47187b75333._comment b/doc/todo/Move_ssh_config_to___126____47__ssh__47__git-annex__47__config/comment_4_743d0b077110c5cac1e2f47187b75333._comment
new file mode 100644
index 000000000..5a22c98f7
--- /dev/null
+++ b/doc/todo/Move_ssh_config_to___126____47__ssh__47__git-annex__47__config/comment_4_743d0b077110c5cac1e2f47187b75333._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 4"
+ date="2013-06-12T19:23:50Z"
+ content="""
+If it were sane, I'd probably use it.
+
+In the meantime, I'm moving this to [[todo]].
+"""]]
diff --git a/doc/todo/Not_working_on_Android-x86.mdwn b/doc/todo/Not_working_on_Android-x86.mdwn
new file mode 100644
index 000000000..56f2ce962
--- /dev/null
+++ b/doc/todo/Not_working_on_Android-x86.mdwn
@@ -0,0 +1,19 @@
+[[!meta title="Android is only autobuilt for arm, not x86 or mips"]]
+
+### Please describe the problem.
+
+git-annex doesn't start on [Android-x86](http://www.android-x86.org) in VirtualBox (version 4.1.18-dfsg-2+deb7u1).
+
+On Android 4.2.2 (android-x86-4.2-20130228.iso) it starts the terminal which prints nothing but `[Terminal session finished]`.
+On Android 4.3 (android-x86-4.3-20130725.iso) it starts the terminal and prints:
+
+ In mgmain JNI_OnLoad
+
+ [Terminal session finished]
+
+The browser/webapp is never started.
+
+### What version of git-annex are you using? On what operating system?
+
+Version 1.0.52 for Android. I made sure to install the correct APK files for each version of Android.
+
diff --git a/doc/todo/Not_working_on_Android-x86/comment_1_5eec4d7530c9df68f1bd1b1ca7021ef5._comment b/doc/todo/Not_working_on_Android-x86/comment_1_5eec4d7530c9df68f1bd1b1ca7021ef5._comment
new file mode 100644
index 000000000..4bcca0ab4
--- /dev/null
+++ b/doc/todo/Not_working_on_Android-x86/comment_1_5eec4d7530c9df68f1bd1b1ca7021ef5._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.64"
+ subject="comment 1"
+ date="2013-11-22T16:37:36Z"
+ content="""
+git-annex is a native binary, and is currently only being built for arm android.
+
+Is Android on x86 a thing used on real-world hardware? I have only seen it in the context of a developer's test environment.
+
+The instructions for building git-annex from source for Android should work on x86. The ghc-android build would need to be tweaked to build a cross compiler targeting that architecture. This can be done by editing settings near the top of ghc-android's `build.sh`.
+
+I am going to move this from bugs/ to todo/ after posting this comment, because it is certiantly not a bug, but a wishlist item at best.
+"""]]
diff --git a/doc/todo/Option_for_browser_to_launch_webapp_with.mdwn b/doc/todo/Option_for_browser_to_launch_webapp_with.mdwn
new file mode 100644
index 000000000..dae601169
--- /dev/null
+++ b/doc/todo/Option_for_browser_to_launch_webapp_with.mdwn
@@ -0,0 +1,7 @@
+Firefox is my default browser, but as we all know, it doesn't load quickly. If I don't have Firefox running but I want to access the git-annex webapp, I'd rather launch the webapp in some small, quick browser like QupZilla than wait for Firefox to load.
+
+Could git-annex have a setting, maybe a "webapp --browser" option and/or a setting in the config file, to specify the browser to launch?
+
+> git-annex uses the standard `git config web.browser` if you set it.
+> [[done]]
+> --[[Joey]]
diff --git a/doc/todo/Please_abort_build_if___34__make_test__34___fails.mdwn b/doc/todo/Please_abort_build_if___34__make_test__34___fails.mdwn
new file mode 100644
index 000000000..592b5e077
--- /dev/null
+++ b/doc/todo/Please_abort_build_if___34__make_test__34___fails.mdwn
@@ -0,0 +1,7 @@
+A failure during "make test" should be signalled to the caller by means of
+a non-zero exit code. Without that signal, it's very hard to run the
+regression test suite in an automated fashion.
+
+> git-annex used to have a Makefile that ignored make test exit status,
+> but that was fixed in commit dab5bddc64ab4ad479a1104748c15d194e138847,
+> in October 6th. [[done]] --[[Joey]]
diff --git a/doc/todo/Please_add_support_for_monad-control_0.3.x.mdwn b/doc/todo/Please_add_support_for_monad-control_0.3.x.mdwn
new file mode 100644
index 000000000..f82224991
--- /dev/null
+++ b/doc/todo/Please_add_support_for_monad-control_0.3.x.mdwn
@@ -0,0 +1,9 @@
+Git-annex doesn't compile with the latest version of monad-control. Would it be hard to support that new version?
+
+> I have been waiting for it to land in Debian before trying to
+> deal with its changes.
+>
+> There is now a branch in git called `new-monad-control` that will build
+> with the new monad-control. --[[Joey]]
+
+>> Now merged to master. [[done]] --[[Joey]]
diff --git a/doc/todo/S3.mdwn b/doc/todo/S3.mdwn
new file mode 100644
index 000000000..7e417336f
--- /dev/null
+++ b/doc/todo/S3.mdwn
@@ -0,0 +1,24 @@
+Support Amazon S3 as a file storage backend.
+
+There's a haskell library that looks good. Not yet in Debian.
+
+Multiple ways of using S3 are possible. Currently implemented as
+a special type of git remote.
+
+Before this can be close, I need to fix:
+
+## encryption
+
+TODO
+
+## unused checking
+
+One problem is `git annex unused`. Currently it only looks at the local
+repository, not remotes. But if something is dropped from the local repo,
+and you forget to drop it from S3, cruft can build up there.
+
+This could be fixed by adding a hook to list all keys present in a remote.
+Then unused could scan remotes for keys, and if they were not used locally,
+offer the possibility to drop them from the remote.
+
+[[done]]
diff --git a/doc/todo/Show_repo_type_in_repo_list.mdwn b/doc/todo/Show_repo_type_in_repo_list.mdwn
new file mode 100644
index 000000000..40fbe6537
--- /dev/null
+++ b/doc/todo/Show_repo_type_in_repo_list.mdwn
@@ -0,0 +1 @@
+It would be helpful to show each repo's type in the list.
diff --git a/doc/todo/Show_repo_type_in_repo_list/comment_1_ac6eb1072ef902a094b79dd8e0917c4d._comment b/doc/todo/Show_repo_type_in_repo_list/comment_1_ac6eb1072ef902a094b79dd8e0917c4d._comment
new file mode 100644
index 000000000..10c0c17df
--- /dev/null
+++ b/doc/todo/Show_repo_type_in_repo_list/comment_1_ac6eb1072ef902a094b79dd8e0917c4d._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 1"
+ date="2013-11-02T23:45:39Z"
+ content="""
+Currently if you go to the edit page for the repository, it shows some information about it, including its type and often its location, at the bottom of the page.
+
+I tend to feel that putting anything else in the repo list would result in it being too cluttered.
+"""]]
diff --git a/doc/todo/Show_repo_type_in_repo_list/comment_2_6979c487f707a724a048d20e2e5744e6._comment b/doc/todo/Show_repo_type_in_repo_list/comment_2_6979c487f707a724a048d20e2e5744e6._comment
new file mode 100644
index 000000000..7d4a36324
--- /dev/null
+++ b/doc/todo/Show_repo_type_in_repo_list/comment_2_6979c487f707a724a048d20e2e5744e6._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmNu4V5fvpLlBhaCUfXXOB0MI5NXwh8SkU"
+ nickname="Adam"
+ subject="comment 2"
+ date="2013-11-02T23:59:16Z"
+ content="""
+I understand. Well, here's what I'm looking at right now. :)
+
+[[http://alphapapa.net/outbox/view.png]]
+
+I just think it would be very useful to say \"Client\" or \"Transfer\" or \"Full Backup\" next to each one, and there's often plenty of room, depending on the size of the window. Especially when one's trying to wrap one's head around git-annex, being reminded what each repo is for would help a lot. Otherwise you basically have to put it in the name or description yourself...so why not just go ahead and show it? :)
+
+Another option might be to have an icon for each type.
+"""]]
diff --git a/doc/todo/Show_repo_type_in_repo_list/comment_3_529254a6cc20de7259d60a3cbc5ccaf7._comment b/doc/todo/Show_repo_type_in_repo_list/comment_3_529254a6cc20de7259d60a3cbc5ccaf7._comment
new file mode 100644
index 000000000..3f8b82695
--- /dev/null
+++ b/doc/todo/Show_repo_type_in_repo_list/comment_3_529254a6cc20de7259d60a3cbc5ccaf7._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 3"
+ date="2013-11-03T00:19:34Z"
+ content="""
+I'd be happy to put in some icons if someone finds some good (and suitably licensed) ones that cover the different types of repositories.
+"""]]
diff --git a/doc/todo/Slow_transfer_for_a_lot_of_small_files..mdwn b/doc/todo/Slow_transfer_for_a_lot_of_small_files..mdwn
new file mode 100644
index 000000000..00cdad0fe
--- /dev/null
+++ b/doc/todo/Slow_transfer_for_a_lot_of_small_files..mdwn
@@ -0,0 +1,20 @@
+What steps will reproduce the problem?
+Sync a lot of small files.
+
+What is the expected output? What do you see instead?
+The expected output is hopefully a fast transfer.
+
+But currently it seems like git-annex is only using one thread to transfer(per host or total?)
+
+An option to select number of transfer threads to use(possibly per host) would be very nice.
+
+> Opening a lot of connections to a single host is probably not desirable.
+>
+> I do want to do something to allow slow hosts to not hold up transfers to
+> other hosts, which might involve running multiple queued transfers at
+> once. The webapp already allows the user to force a given transfer to
+> happen immediately. --[[Joey]]
+
+And maybe also an option to limit how long a queue the browser should show, it can become quite resource intensive with a long queue.
+
+> The queue is limited to 20 items for this reason. --[[Joey]]
diff --git a/doc/todo/Sync_repo_names__63__.mdwn b/doc/todo/Sync_repo_names__63__.mdwn
new file mode 100644
index 000000000..d3bb59f04
--- /dev/null
+++ b/doc/todo/Sync_repo_names__63__.mdwn
@@ -0,0 +1,10 @@
+It's very confusing to me that the same repo viewed from different client systems can have different names and descriptions. This implies that making changes to a remote repo from one system only affects how that system sees the repo, but it seems to affect how the entire git-annex "pair" or "network of repos" sees it.
+
+I think it would be good if the names and descriptions of repos were synced across clients.
+
+> The descriptions of repositories are synced. (They're stored in git-annex:uuid.log)
+>
+> git allows for the same repository to be referred to using as many different remote names as you want to set up. git-annex inherits this,
+> and I can't see this changing; there are very good reasons for remotes to
+> have this flexability. [[done]]
+> --[[Joey]]
diff --git a/doc/todo/Use_MediaScannerConnection_on_Android.mdwn b/doc/todo/Use_MediaScannerConnection_on_Android.mdwn
new file mode 100644
index 000000000..afce9308d
--- /dev/null
+++ b/doc/todo/Use_MediaScannerConnection_on_Android.mdwn
@@ -0,0 +1,7 @@
+Currently if photos or videos are copied into the Camera/DCIM directory on an Android device, or deleted the Gallery doesn't notice the changes.
+
+It is necessary to call MediaScannerConnection - http://developer.android.com/reference/android/media/MediaScannerConnection.html - to notify the system of the change.
+
+More info, and some sample Java code: http://stackoverflow.com/questions/13270789/how-to-run-media-scanner-in-android
+
+It'd be awesome if the assistant did this on files it has changed. Possibly just under Camera/DCIM, but perhaps it should be configurable. MediaScannerConnection is also used to notify and index new music files.
diff --git a/doc/todo/Use_a_remote_as_a_sharing_site_for_files_with_obfuscated_URLs.mdwn b/doc/todo/Use_a_remote_as_a_sharing_site_for_files_with_obfuscated_URLs.mdwn
new file mode 100644
index 000000000..a42a81d02
--- /dev/null
+++ b/doc/todo/Use_a_remote_as_a_sharing_site_for_files_with_obfuscated_URLs.mdwn
@@ -0,0 +1,7 @@
+There are times when it is handy to be able to upload a file to a web host somewhere and share a link for that file to a select few people.
+
+It seems to be that the assistant could handle this scenario. It could generate a directory with a random name on the remote, and transfer the file there (using the existing filename) and the appropriate URL could be displayed in the assistant webapp to allow the user to copy the URL to send it to the appropriate people.
+
+Note: Joey and I had a quick chat about this use case at LCA2013.
+
+[[!tag design/assistant]]
diff --git a/doc/todo/Use_a_remote_as_a_sharing_site_for_files_with_obfuscated_URLs/comment_1_1a1f34f4f389267d67e79409c0ca8b1d._comment b/doc/todo/Use_a_remote_as_a_sharing_site_for_files_with_obfuscated_URLs/comment_1_1a1f34f4f389267d67e79409c0ca8b1d._comment
new file mode 100644
index 000000000..35f735191
--- /dev/null
+++ b/doc/todo/Use_a_remote_as_a_sharing_site_for_files_with_obfuscated_URLs/comment_1_1a1f34f4f389267d67e79409c0ca8b1d._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="99.54.57.201"
+ subject="comment 1"
+ date="2013-02-09T22:38:56Z"
+ content="""
+This would be an extremely cool feature to rip off from Dropbox. :)
+
+"""]]
diff --git a/doc/todo/Wishlist:_additional_environment_variables_for_hooks.mdwn b/doc/todo/Wishlist:_additional_environment_variables_for_hooks.mdwn
new file mode 100644
index 000000000..6e852b9f2
--- /dev/null
+++ b/doc/todo/Wishlist:_additional_environment_variables_for_hooks.mdwn
@@ -0,0 +1,14 @@
+It would be nice if a couple of additional environment variables to be set for hook uses.
+
+In particular:
+
+ GIT_ANNEX_DIRECT=`git config annex.direct`
+
+and
+
+ GIT_TOP_LEVEL=`git rev-parse --show-toplevel`
+
+
+I've made some changes to flickrannex to allow the sub-directories above the uploaded image to be added as tags. This change has been merged into trunk: [[https://github.com/TobiasTheViking/flickrannex]]
+
+What I needed was both the environment variables mentioned above. One is set as part of the annex-hook and the other I guestimate from the file path. If it was set in git-annex it would be much cleaner (and accurate). So...I think this info would be useful for other hook.
diff --git a/doc/todo/Wishlist:_sanitychecker_fix_wrong_UUID__47__duplicate_remote.mdwn b/doc/todo/Wishlist:_sanitychecker_fix_wrong_UUID__47__duplicate_remote.mdwn
new file mode 100644
index 000000000..ff7773d3e
--- /dev/null
+++ b/doc/todo/Wishlist:_sanitychecker_fix_wrong_UUID__47__duplicate_remote.mdwn
@@ -0,0 +1,7 @@
+In certain situations different client annexes might get the same remote repository added, but before being synced.
+
+Once the two clients sync they will both have two remotes with the same name. But only one UUID will have any content(Assuming only one client pushed).
+
+It would be nice to have some (automatic?) way to resolve this conflict.
+
+Not sure if anything sane can be done if both clients have pushed?
diff --git a/doc/todo/__96__git_annex_import_--lazy__96___--_Delete_everything_that__39__s_in_the_source_directory_and_also_in_the_target_annex.mdwn b/doc/todo/__96__git_annex_import_--lazy__96___--_Delete_everything_that__39__s_in_the_source_directory_and_also_in_the_target_annex.mdwn
new file mode 100644
index 000000000..996c03461
--- /dev/null
+++ b/doc/todo/__96__git_annex_import_--lazy__96___--_Delete_everything_that__39__s_in_the_source_directory_and_also_in_the_target_annex.mdwn
@@ -0,0 +1,29 @@
+As per IRC
+
+ 22:13:10 < RichiH> joeyh: btw, i have been pondering a `git annex import --lazy` or some such which basically goes through a directory and deletes everything i find in the annex it run from
+ 22:50:39 < joeyh> not sure of the use case
+ 23:41:06 < RichiH> joeyh: the use case is "i have important a ton of data into my annexes. now, i am going through the usual crud of cp -ax'ed, rsync'ed, and other random 'new disk, move stuff around and just put a full dump over there' file dumps and would like to delete everything that's annexed already"
+ 23:41:33 < RichiH> joeyh: that would allow me to spend time on dealing with the files which are not yet annexed
+ 23:41:54 < RichiH> instead of verifying file after file which has been imported already
+ 23:43:19 < joeyh> have you tried just running git annex import in a subdirectory and then deleting the dups?
+ 23:45:34 < joeyh> or in a separate branch for that matter, which you could then merge in, etc
+ 23:54:08 < joeyh> Thinking anout it some more, it would need to scan the whole work tree to see what keys were there, and populate a lookup table. I prefer to avoid things that need git-annex to do such a large scan and use arbitrary amounts of memory.
+ 00:58:11 < RichiH> joeyh: that would force everything into the annex, though
+ 00:58:20 < RichiH> a plain import, that is
+ 00:58:53 < RichiH> in a usual data dump directory, there's tons of stuff i will never import
+ 00:59:00 < RichiH> i want to delete large portions of it
+ 00:59:32 < RichiH> but getting rid of duplicates first allows me to spend my time focused on stuff humans are good at: deciding
+ 00:59:53 < RichiH> whereas the computer can focus on stuff it's good at: mindless comparision of bits
+ 01:00:15 < RichiH> joeyh: as you're saying this is complex, maybe i need to rephrase
+ 01:01:40 < RichiH> what i envision is git annex import --foo to 1) decide what hashing algorithm should be used for this file 2) hash that file 3) look into the annex if that hash is annexed 3a) optionally verify numcopies within the annex 4) delete the file in the source directory
+ 01:01:47 < RichiH> and then move on to the next file
+ 01:02:00 < RichiH> if the hash does not exist in the annex, leave it alone
+ 01:02:50 < RichiH> if the hash exists in annex, but numcopies is not fulfilled, just import it as a normal import would
+ 01:03:50 < RichiH> that sounds quite easy, to me; in fact i will prolly script it if you decide not to implement it
+ 01:04:07 < RichiH> but i think it's useful for a _lot_ of people who migrate tons of data into annexes
+ 01:04:31 < RichiH> thus i would rather see this upstream and not hacked locally
+
+The only failure mode I see in the above is "file has been dropped elsewhere, numcopies not fulfilled, but that info is not synched to the local repo, yet" -- This could be worked around by always importing the data.
+
+> [[done]] as `git annex import --deduplicate`.
+> --[[Joey]]
diff --git a/doc/todo/__96__git_annex_import_--lazy__96___--_Delete_everything_that__39__s_in_the_source_directory_and_also_in_the_target_annex/comment_1_0cc16eb17151309113cec6d1cccf203d._comment b/doc/todo/__96__git_annex_import_--lazy__96___--_Delete_everything_that__39__s_in_the_source_directory_and_also_in_the_target_annex/comment_1_0cc16eb17151309113cec6d1cccf203d._comment
new file mode 100644
index 000000000..0b4e22e7c
--- /dev/null
+++ b/doc/todo/__96__git_annex_import_--lazy__96___--_Delete_everything_that__39__s_in_the_source_directory_and_also_in_the_target_annex/comment_1_0cc16eb17151309113cec6d1cccf203d._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 1"
+ date="2013-08-06T14:22:03Z"
+ content="""
+To expand a bit on the use case:
+
+I have several migration directories which I simply moved to new systems or disks with the help of `cp -ax` or `rsync`.
+As I don't _need_ the data per se and merely want to hold on to it in case I ever happen to need it again and as disk space is laughably cheap, I have a lot of duplicates.
+While I can at least detect bit flips with the help of checksum lists, cleaning those duplicates of duplicated duplicates is quite some effort.
+To make things worse, photos, music, videos, letter and whatnot are thrown into the same container directories.
+
+All in all, getting data out of those data dumps and into a clean structure is quite an effort.
+`git annex import --lazy` would help with this effort as I could start with the first directory, sort stuff by hand, and annex it.
+As soon as data lives in any of my annexes, I could simply run `git annex import --lazy` to get rid of all duplicates while retaining the unannexed files.
+Iterating through this process a few times, I will be left with clean annexes on the one hand and stuff I can simply delete on the other hand.
+
+I could script all this by hand on my own machine, but I am _certain_ that others would find easy, integrated, and unit tested support for whittling down data dumps over time useful.
+"""]]
diff --git a/doc/todo/__96__git_annex_status__47__version__96___should_print_the_local_OS.mdwn b/doc/todo/__96__git_annex_status__47__version__96___should_print_the_local_OS.mdwn
new file mode 100644
index 000000000..9c2afecb4
--- /dev/null
+++ b/doc/todo/__96__git_annex_status__47__version__96___should_print_the_local_OS.mdwn
@@ -0,0 +1,6 @@
+That would make assessing weird reports like [[bugs/Should_UUID__39__s_for_Remotes_be_case_sensitive__63__/]] easier and quicker.
+
+> No, if people want to file a bug report, it's up to them to tell me
+> relevant details about their OS. I'm not going down the rathole
+> of making git-annex muck about trying to gather such information.
+> [[done]] --[[Joey]]
diff --git a/doc/todo/__96__git_annex_sync_--auto__96___or___96__git_annex_auto__96___--_synchronize_symlinks__44___tracking_info__44___and_actual_data.mdwn b/doc/todo/__96__git_annex_sync_--auto__96___or___96__git_annex_auto__96___--_synchronize_symlinks__44___tracking_info__44___and_actual_data.mdwn
new file mode 100644
index 000000000..d48b4426f
--- /dev/null
+++ b/doc/todo/__96__git_annex_sync_--auto__96___or___96__git_annex_auto__96___--_synchronize_symlinks__44___tracking_info__44___and_actual_data.mdwn
@@ -0,0 +1,3 @@
+As per DebConf13: Introduce a one-shot command to synchronize everything, including data, with the other remotes.
+
+Especially useful for the debconf annex.
diff --git a/doc/todo/add_--exclude_option_to_git_annex_find.mdwn b/doc/todo/add_--exclude_option_to_git_annex_find.mdwn
new file mode 100644
index 000000000..a797e97f5
--- /dev/null
+++ b/doc/todo/add_--exclude_option_to_git_annex_find.mdwn
@@ -0,0 +1,4 @@
+Seems pretty self-explanatory.
+
+> This was already implemented, the --exclude option can be used
+> for find as well as most any other subcommand. --[[Joey]] [[done]]
diff --git a/doc/todo/add_-all_option.mdwn b/doc/todo/add_-all_option.mdwn
new file mode 100644
index 000000000..2f25759c2
--- /dev/null
+++ b/doc/todo/add_-all_option.mdwn
@@ -0,0 +1,22 @@
+`--all` would make git-annex operate on either every key with content
+present (or in some cases like `get` and `copy --from` on
+every keys with content not present).
+
+This would be useful when a repository has a history with deleted files
+whose content you want to keep (so you're not using `dropunused`).
+Or when you have a lot of branches and just want to be able to fsck
+every file referenced in any branch (or indeed, any file referenced in any
+ref). It could also be useful (or even a
+good default) in a bare repository.
+
+A problem with the idea is that `.gitattributes` values for keys not
+currently in the tree would not be available (without horrific anounts of
+grubbing thru history to find where/when the key used to exist). So
+`numcopies` set via `.gitattributes` would not work. This would be a
+particular problem for `drop` and for `--auto`.
+
+--[[Joey]]
+
+> [[done]]. The .gitattributes problem was solved simply by not
+> supporting `drop --all`. `--auto` also cannot be mixed with --all for
+> similar reasons. --[[Joey]]
diff --git a/doc/todo/add_a_git_backend.mdwn b/doc/todo/add_a_git_backend.mdwn
new file mode 100644
index 000000000..2b224710e
--- /dev/null
+++ b/doc/todo/add_a_git_backend.mdwn
@@ -0,0 +1,18 @@
+There should be a backend where the file content is stored.. in a git
+repository!
+
+This way, you know your annexed content is safe & versioned, but you only
+have to deal with the pain of git with large files in one place, and can
+use all of git-annex's features everywhere else.
+
+> Speaking as a future user, do very, very much want. -- RichiH
+
+>> Might also be interesting to use `bup` in the git backend, to work
+>> around git's big file issues there. So git-annex would pull data out
+>> of the git backend using bup. --[[Joey]]
+
+>>> Very much so. Generally speaking, having one or more versioned storage back-ends with current data in the local annexes sounds incredibly useful. Still being able to get at old data in via the back-end and/or making offline backups of the full history are excellent use cases. -- RichiH
+
+[[done]], the bup special remote type is written! --[[Joey]]
+
+> Yay! -- RichiH
diff --git a/doc/todo/add_an_icon_for_the_.desktop_file.mdwn b/doc/todo/add_an_icon_for_the_.desktop_file.mdwn
new file mode 100644
index 000000000..3be158a0a
--- /dev/null
+++ b/doc/todo/add_an_icon_for_the_.desktop_file.mdwn
@@ -0,0 +1 @@
+Maybe add the icon /usr/share/doc/git-annex/html/logo.svg to the .desktp file.
diff --git a/doc/todo/add_metadata_to_annexed_files.mdwn b/doc/todo/add_metadata_to_annexed_files.mdwn
new file mode 100644
index 000000000..0fc3e8953
--- /dev/null
+++ b/doc/todo/add_metadata_to_annexed_files.mdwn
@@ -0,0 +1,5 @@
+I would like to attach metadata to annexed files (objects) without cluttering the workdir with files containing this metadata. A common use case would be to add titles to my photo collection that could than end up in a generated photo album.
+
+Depending on the implementation it might also be possible to use the metadata facility for a threaded commenting system.
+
+The first question is whether the metadata is attached to the objects and thus shared by all paths pointing to the same data object or to paths in the worktree. I've no preference here at this point.
diff --git a/doc/todo/add_metadata_to_annexed_files/comment_1_38af9b352020194e9ace34d7dde188cf._comment b/doc/todo/add_metadata_to_annexed_files/comment_1_38af9b352020194e9ace34d7dde188cf._comment
new file mode 100644
index 000000000..8460300a7
--- /dev/null
+++ b/doc/todo/add_metadata_to_annexed_files/comment_1_38af9b352020194e9ace34d7dde188cf._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 1"
+ date="2013-08-24T19:58:54Z"
+ content="""
+I don't know if git-annex is the right vehicle to fix this. It seems that a more generic fix that would work in non-git-annex repos would be better.
+
+I can answer your question though: The metadata such as urls and locations that git-annex stores in the git-annex branch is attached to objects, and not to work tree paths.
+"""]]
diff --git a/doc/todo/assistant_cannot_set_up_remote_repo_via_an_ssh_alias_or_an_ip_address.mdwn b/doc/todo/assistant_cannot_set_up_remote_repo_via_an_ssh_alias_or_an_ip_address.mdwn
new file mode 100644
index 000000000..a7b30ded5
--- /dev/null
+++ b/doc/todo/assistant_cannot_set_up_remote_repo_via_an_ssh_alias_or_an_ip_address.mdwn
@@ -0,0 +1,48 @@
+What steps will reproduce the problem?
+
+Using the assistant, create an SSH remote. Try to use an alias as the name
+of the remote (e.g. I have a server which I have aliased to "homeworld" in
+my .ssh/config. When I'm at home, that is an alias for 192.168.1.253.
+When I'm not at home, I edit .ssh/config so that "homeworld" becomes an
+alias for a hostname at no-ip.com.) Despite the fact that "homeworld" is a
+viable ssh target because of the alias, the assistant doesn't recognize it
+as a valid host to ssh to.
+
+I had trouble with an ip address the first time I tried it but just tried
+it again and it worked fine, so please disregard that part of the title of
+this bug report.
+
+
+What is the expected output? What do you see instead?
+
+expected output = move to the "create a repository -- rsync or regular" page.
+observed output = "cannot resolve host name"
+
+
+What version of git-annex are you using? On what operating system?
+
+ Version: 3.20130102 OS X Lion
+
+
+Please provide any additional information below.
+
+I realize this is kind of a power user whine. Using an ssh alias which
+does not correspond to an actual resolvable hostname (and cannot, because
+it's supposed to be a layer of indirection over the hostname) is not an
+everyday problem for an average user.
+
+> The assistant tries to resolve the hostname explicitly
+> to catch user's typos, and also expands it to a FQDN, to make
+> it more likely to be able to reach the host when roaming to other
+> networks.
+>
+> Also, the assistant sets up it *own* .ssh/config hostname alias,
+> in order to make it use the special ssh key that it generates for the host.
+> So that is not compatable with using a ssh host alias you've set up.
+> Even if it knew about your alias, it would set up a new hostname alias, and
+> whatever machinery you have to update the alias would not work.
+>
+> You can, of course, add git remotes using any ssh alias you like, by
+> hand, and restart the assistant and it will use them. --[[Joey]]
+
+[[!tag /design/assistant]]
diff --git a/doc/todo/assistant_git_sync_laddering.mdwn b/doc/todo/assistant_git_sync_laddering.mdwn
new file mode 100644
index 000000000..7dbc6480a
--- /dev/null
+++ b/doc/todo/assistant_git_sync_laddering.mdwn
@@ -0,0 +1,10 @@
+When the [[design/assistant]] is running on a pair of remotes, I've seen
+them get out of sync, such that every pull and merge results in a conflict,
+that then has to be auto-resolved.
+
+This seems similar to the laddering problem described in this old bug:
+[[bugs/making_annex-merge_try_a_fast-forward]]
+
+--[[Joey]]
+
+Think I've fixed this. [[done]] --[[Joey]]
diff --git a/doc/todo/assistant_parallel_file_transfers.txt b/doc/todo/assistant_parallel_file_transfers.txt
new file mode 100644
index 000000000..aafddf038
--- /dev/null
+++ b/doc/todo/assistant_parallel_file_transfers.txt
@@ -0,0 +1,15 @@
+Hi and thank you for an incredible piece of software and great work!
+
+I've noticed that when I add new files to a repository and I have my USB drive connected, the assistant alternate it's transfers of files. And only transfers one queued file at the time.
+
+file1 -->> Internet offsite computer
+file1 -->> USB drive
+file2 -->> Internet offsite computer
+file2 -->> USB drive
+
+
+I would prefer a logic where the assistant transfer files in parallel to my different repositories. I know that it might not be a good thing doing that with network accessed repositories, but when I have "low cost", locally attached USB drives it would be great if the transfers could be done in parallel.
+
+
+Is there a configuration option for this already?
+
diff --git a/doc/todo/assistant_smarter_archive_directory_handling.mdwn b/doc/todo/assistant_smarter_archive_directory_handling.mdwn
new file mode 100644
index 000000000..fa5a3e4fc
--- /dev/null
+++ b/doc/todo/assistant_smarter_archive_directory_handling.mdwn
@@ -0,0 +1,31 @@
+Client repos do not want files in archive directories. This can turn
+out to be confusing to users who are using archive directories for their
+own purposes and not aware of this special case in the assistant. It can
+seem like the assistant is failing to sync their files.
+
+I thought, first, that it should have a checkbox to enable the archive
+directory behavior.
+
+However, I think I have a better idea. Change the preferred content
+expression for clients, so they want files in archive directories, *until*
+those files land in an archive.
+
+This way, only users who set up an archive repo get this behavior. And they
+asked for it by setting up that repo!
+
+Also, the new behavior will mean that files in archive directories still
+propigate around to clients. Consider this topology:
+
+ client A ---- client B ---- archive
+
+If a file is created in client A, and moved to an archive directory before
+it syncs to B, it will never get to the archive, and will continue wasting
+space on A. With the new behavior, A and B serve as effectively, transfer
+repositories for archived content.
+
+Something vaguely like this should work as the preferred content
+expression for the clients:
+
+ exclude=archive/* or (include=archive/* and (not (copies=archive:1 or copies=smallarchive:1)))
+
+> [[done]] --[[Joey]]
diff --git a/doc/todo/assistant_threaded_runtime.mdwn b/doc/todo/assistant_threaded_runtime.mdwn
new file mode 100644
index 000000000..03ba66acf
--- /dev/null
+++ b/doc/todo/assistant_threaded_runtime.mdwn
@@ -0,0 +1,40 @@
+The [[design/assistant]] would be better if git-annex used ghc's threaded
+runtime (`ghc -threaded`).
+
+Currently, whenever the assistant code runs some external command, all
+threads are blocked waiting for it to finish.
+
+For transfers, the assistant works around this problem by forking separate
+upload processes, and not waiting on them until it sees an indication that
+they have finished the transfer. While this works, it's messy.. threaded
+would be better.
+
+When pulling, pushing, and merging, the assistant runs external git
+commands, and this does block all other threads. The threaded runtime would
+really help here.
+
+[[done]]; the assistant now builds with the threaded runtime.
+Some work still remains to run certian long-running external git commands
+in their own threads to prevent them blocking things, but that is easy to
+do, now. --[[Joey]]
+
+---
+
+Currently, git-annex seems unstable when built with the threaded runtime.
+The test suite tends to hang when testing add. `git-annex` occasionally
+hangs, apparently in a futex lock. This is not the assistant hanging, and
+git-annex does not otherwise use threads, so this is surprising. --[[Joey]]
+
+> I've spent a lot of time debugging this, and trying to fix it, in the
+> "threaded" branch. There are still deadlocks. --[[Joey]]
+
+>> Fixed, by switching from `System.Cmd.Utils` to `System.Process`
+>> --[[Joey]]
+
+---
+
+It would be possible to not use the threaded runtime. Instead, we could
+have a child process pool, with associated continuations to run after a
+child process finishes. Then periodically do a nonblocking waitpid on each
+process in the pool in turn (waiting for any child could break anything not
+using the pool!). This is probably a last resort...
diff --git a/doc/todo/auto_remotes.mdwn b/doc/todo/auto_remotes.mdwn
new file mode 100644
index 000000000..715dea720
--- /dev/null
+++ b/doc/todo/auto_remotes.mdwn
@@ -0,0 +1,29 @@
+It should be possible for clones to learn about how to contact
+each other without remotes needing to always be explicitly set
+up. Say that `.git-annex/remote.log` is maintained by git-annex
+to contain:
+
+ UUID hostname URI
+
+The URI comes from configured remotes and maybe from
+`file://$(pwd)`, or even `ssh://$(hostname -f)`
+for the current repo. This format will merge without
+conflicts or data loss.
+
+Then when content is belived to be in a UUID, and no
+configured remote has it, the remote.log can be consulted and
+URIs that look likely tried. (file:// ones if the hostname
+is the same (or maybe always -- a removable drive might tend
+to be mounted at the same location on different hosts),
+otherwise ssh:// ones.)
+
+Question: When should git-annex update the remote.log?
+(If not just on init.) Whenever it reads in a repo's remotes?
+
+> This sounds useful and the log should be updated every time any remote is being accessed. A counter or timestamp (yes, distributed times may be wrong/different) could be used to auto-prune old entries via a global and per-remote config setting. -- RichiH
+
+---
+
+I no longer think I'd use this myself, I find that my repositories quickly
+grow the paths I actually use, somewhat organically. Unofficial paths
+across university quads come to mind. [[done]] --[[Joey]]
diff --git a/doc/todo/auto_remotes/discussion.mdwn b/doc/todo/auto_remotes/discussion.mdwn
new file mode 100644
index 000000000..b9e1522a8
--- /dev/null
+++ b/doc/todo/auto_remotes/discussion.mdwn
@@ -0,0 +1,7 @@
+Remotes log should probably be stored in ".git/annex/remote.log"
+instead of ".git-annex/remote.log" to prevent leaking credentials.
+
+> The idea is to distribute the info between repositories, which is
+> why it'd go in `.git-annex`. Of course that does mean that repository
+> location information would be included, and if that'd not desirable
+> this feature would need to be turned off. --[[Joey]]
diff --git a/doc/todo/automatic_bookkeeping_watch_command.mdwn b/doc/todo/automatic_bookkeeping_watch_command.mdwn
new file mode 100644
index 000000000..28b02aff2
--- /dev/null
+++ b/doc/todo/automatic_bookkeeping_watch_command.mdwn
@@ -0,0 +1,15 @@
+A "git annex watch" command would help make git-annex usable by users who
+don't know how to use git, or don't want to bother typing the git commands.
+It would run, in the background, watching via inotify for changes, and
+automatically annexing new files, etc.
+
+The blue sky goal would be something automated like dropbox, except fully
+distributed. All files put into the repository would propagate out
+to all the other clones of it, as network links allow. Note that while
+dropbox allows modifying files, git-annex freezes them upon creation,
+so this would not be 100% equivalent to dropbox. --[[Joey]]
+
+This is a big project with its own [[design pages|design/assistant]].
+
+> [[done]].. at least, we have a watch command an an assistant, which
+> is still being developed. --[[Joey]]
diff --git a/doc/todo/automatic_merge_of_synced_branches_upon___34__git_annex_sync__34__.mdwn b/doc/todo/automatic_merge_of_synced_branches_upon___34__git_annex_sync__34__.mdwn
new file mode 100644
index 000000000..361585a78
--- /dev/null
+++ b/doc/todo/automatic_merge_of_synced_branches_upon___34__git_annex_sync__34__.mdwn
@@ -0,0 +1,16 @@
+When maintaining several replica of the same git-annex repo "git annex sync" is quite handy.
+But it would be even handier if "git annex sync" would also perform automatic "git merge synced/*" actions on all remotes.
+
+Clearly, this is beneficial when the user wants to keep all working copies synchronized.
+This is likely the case in git annex assistant like scenarios. And it's always the case in my day to day scenarios :-)
+I'm not sure about other use cases that I've hard time imagining...
+
+As just discussed on IRC (#vcs-home/OFTC), this could be implemented in various ways:
+
+1) By doing ssh on each remote and running the appropriate "git merge ..." commands there.
+ The drawback of this is that quite often it won't be permitted to ssh on the remote and run arbitrary commands there.
+
+2) Having a default post-receive hook, created at the time of "git annex init" that automatically does the merges when contacted by other remotes as a consequence of "git annex sync".
+
+
+Thanks for git-annex!
diff --git a/doc/todo/avoid_unnecessary_union_merges.mdwn b/doc/todo/avoid_unnecessary_union_merges.mdwn
new file mode 100644
index 000000000..5cd4b6437
--- /dev/null
+++ b/doc/todo/avoid_unnecessary_union_merges.mdwn
@@ -0,0 +1,20 @@
+Some commands cause a union merge unnecessarily. For example, `git annex add`
+modifies the location log, which first requires reading the current log (if
+any), which triggers a merge.
+
+Would be good to avoid these unnecessary union merges. First because it's
+faster and second because it avoids a possible delay when a user might
+ctrl-c and leave the repo in an inconsistent state. In the case of an add,
+the file will be in the annex, but no location log will exist for it (fsck
+fixes that).
+
+It may be that all that's needed is to modify Annex.Branch.change
+to read the current value, without merging. Then commands like `get`, that
+query the branch, will still cause merges, and commands like `add` that
+only modify it, will not. Note that for a command like `get`, the merge
+occurs before it has done anything, so ctrl-c should not be a problem
+there.
+
+This is a delicate change, I need to take care.. --[[Joey]]
+
+> [[done]] (assuming I didn't miss any cases where this is not safe!) --[[Joey]]
diff --git a/doc/todo/backendSHA1.mdwn b/doc/todo/backendSHA1.mdwn
new file mode 100644
index 000000000..8c16b75ad
--- /dev/null
+++ b/doc/todo/backendSHA1.mdwn
@@ -0,0 +1,7 @@
+This backend is not finished.
+
+In particular, while files can be added using it, git-annex will not notice
+when their content changes, and will not create a new key for the new sha1
+of the net content.
+
+[[done]]; use unlock subcommand and commit changes with git
diff --git a/doc/todo/branching.mdwn b/doc/todo/branching.mdwn
new file mode 100644
index 000000000..ad7ece6f1
--- /dev/null
+++ b/doc/todo/branching.mdwn
@@ -0,0 +1,159 @@
+[[done]] !!!
+
+The use of `.git-annex` to store logs means that if a repo has branches
+and the user switched between them, git-annex will see different logs in
+the different branches, and so may miss info about what remotes have which
+files (though it can re-learn).
+
+An alternative would be to store the log data directly in the git repo
+as `pristine-tar` does. Problem with that approach is that git won't merge
+conflicting changes to log files if they are not in the currently checked
+out branch.
+
+It would be possible to use a branch with a tree like this, to avoid
+conflicts:
+
+key/uuid/time/status
+
+As long as new files are only added, and old timestamped files deleted,
+there would be no conflicts.
+
+A related problem though is the size of the tree objects git needs to
+commit. Having the logs in a separate branch doesn't help with that.
+As more keys are added, the tree object size will increase, and git will
+take longer and longer to commit, and use more space. One way to deal with
+this is simply by splitting the logs amoung subdirectories. Git then can
+reuse trees for most directories. (Check: Does it still have to build
+dup trees in memory?)
+
+Another approach would be to have git-annex *delete* old logs. Keep logs
+for the currently available files, or something like that. If other log
+info is needed, look back through history to find the first occurance of a
+log. Maybe even look at other branches -- so if the logs were on master,
+a new empty branch could be made and git-annex would still know where to
+get keys in that branch.
+
+Would have to be careful about conflicts when deleting and bringing back
+files with the same name. And would need to avoid expensive searching thru
+all history to try to find an old log file.
+
+## fleshed out proposal
+
+Let's use one branch per uuid, named git-annex/$UUID.
+
+- I came to realize this would be a good idea when thinking about how
+ to upgrade. Each individual annex will be upgraded independantly,
+ so each will want to make a branch, and if the branches aren't distinct,
+ they will merge conflict for sure.
+- TODO: What will need to be done to git to make it push/pull these new
+ branches?
+- A given repo only ever writes to its UUID branch. So no conflicts.
+ - **problem**: git annex move needs to update log info for other repos!
+ (possibly solvable by having git-annex-shell update the log info
+ when content is moved using it)
+- (BTW, UUIDs probably don't compress well, and this reduces the bloat of having
+ them repeated lots of times in the tree.)
+- Per UUID branches mean that if it wants to find a file's location
+ amoung configured remotes, it can examine only their branches, if
+ desired.
+- It's important that the per-repo branches propigate beyond immediate
+ remotes. If there is a central bare repo, that means push --all. Without
+ one, it means that when repo B pulls from A, and then C pulls from B,
+ C needs to get A's branch -- which means that B should have a tracking
+ branch for A's branch.
+
+In the branch, only one file is needed. Call it locationlog. git-annex
+can cache location log changes and write them all to locationlog in
+a single git operation on shutdown.
+
+- TODO: what if it's ctrl-c'd with changes pending? Perhaps it should
+ collect them to .git/annex/locationlog, and inject that file on shutdown?
+- This will be less overhead than the current staging of all the log files.
+
+The log is not appended to, so in git we have a series of commits each of
+which replaces the log's entire contens.
+
+To find locations of a key, all (or all relevant) branches need to be
+examined, looking backward through the history of each until a log
+with a indication of the presense/absense of the key is found.
+
+- This will be less expensive for files that have recently been added
+ or transfered.
+- It could get pretty slow when digging deeper.
+- Only 3 places in git-annex will be affected by any slowdown: move --from,
+ get and drop. (Update: Now also unused, whereis, fsck)
+
+## alternate
+
+As above, but use a single git-annex branch, and keep the per-UUID
+info in their own log files. Hope that git can auto-merge as long as
+each observing repo only writes to its own files. (Well, it can, but for
+non-fast-forward merges, the git-annex branch would need to be checked out,
+which is problimatic.)
+
+Use filenames like:
+
+ <observing uuid>/<location uuid>
+
+That allows one repo to record another's state when doing a
+`move`.
+
+## outside the box approach
+
+If the problem is limited to only that the `.git-annex/` files make
+branching difficult (and not to the related problem that commits to them
+and having them in the tree are sorta annoying), then a simple approach
+would be to have git-annex look in other branches for location log info
+too.
+
+The problem would then be that any locationlog lookup would need to look in
+all other branches (any branch could have more current info after all),
+which could get expensive.
+
+## way outside the box approach
+
+Another approach I have been mulling over is keeping the log file
+branch checked out in .git/annex/logs/ -- this would be a checkout of a git
+repository inside a git repository, using "git fake bare" techniques. This
+would solve the merge problem, since git auto merge could be used. It would
+still mean all the log files are on-disk, which annoys some. It would
+require some tighter integration with git, so that after a pull, the log
+repo is updated with the data pulled. --[[Joey]]
+
+> Seems I can't use git fake bare exactly. Instead, the best option
+> seems to be `git clone --shared` to make a clone that uses
+> `.git/annex/logs/.git` to hold its index etc, but (mostly) uses
+> objects from the main repo. There would be some bloat,
+> as commits to the logs made in there would not be shared with the main
+> repo. Using `GIT_OBJECT_DIRECTORY` might be a way to avoid that bloat.
+
+## notes
+
+Another approach could be to use git-notes. It supports merging branches
+of notes, with union merge strategy (a hook would have to do this after
+a pull, it's not done automatically).
+
+Problem: Notes are usually attached to git
+objects, and there are no git objects corresponding to git-annex keys.
+
+Problem: Notes are not normally copied when cloning.
+
+------
+
+## elminating the merge problem
+
+Most of the above options are complicated by the problem of how to merge
+changes from remotes. It should be possible to deal with the merge
+problem generically. Something like this:
+
+* We have a local branch `B`.
+* For remotes, there are also `origin/B`, `otherremote/B`, etc.
+* To merge two branches `B` and `foo/B`, construct a merge commit that
+ makes each file have all lines that were in either version of the file,
+ with duplicates removed (probably). Do this without checking out a tree.
+ -- now implemented as git-union-merge
+* As a `post-merge` hook, merge `*/B` into `B`. This will ensure `B`
+ is always up-to-date after a pull from a remote.
+* When pushing to a remote, nothing need to be done, except ensure
+ `B` is either successfully pushed, or the push fails (and a pull needs to
+ be done to get the remote's changes merged into `B`).
diff --git a/doc/todo/cache_key_info.mdwn b/doc/todo/cache_key_info.mdwn
new file mode 100644
index 000000000..d4352ccf7
--- /dev/null
+++ b/doc/todo/cache_key_info.mdwn
@@ -0,0 +1,37 @@
+Most of git-annex is designed to be fast no matter how many other files are
+in the annex. Things like add/get/drop/move/fsck have good locality;
+they will only operate on as many files as you need them to.
+
+(git commit can get a little slow with a great deal of files,
+but that's out of scope -- and recent git-annex versions use queuing
+to save git add from piling up too much in the index.)
+
+But currently two git-annex commands are quite slow when annexes become large
+in quantity of files. These are unused and status.
+(Both have --fast versions that don't do as much).
+> (Update: status has become acceptably fast; most of its slowdown was due to using a bad data structure; scanning the tree is not particularly slow and it no longer looks at the git-annex branch.)
+
+unused is slow because it needs two pieces of information that are not
+quick to look up, and require examining the whole repo, very seekily:
+
+1. The keys present in the annex. Found by looking thru .git/annex/objects
+2. The keys referenced by files in git. Found by finding every file
+ in git, and looking at its symlink.
+
+Of these, the first is less expensive (typically, an annex does not have every
+key in it). It could be optimized fairly simply, by adding a database
+of keys present in the annex that is optimised to list them all. The
+database would be updated by the few functions that move content in and
+out.
+
+The second is harder to optimise, because the user can delete, revert,
+copy, add, etc files in git at will, and git-annex does not have a good way
+to watch that and maintain a database of what keys are being referenced.
+
+It could use a post-commit hook and examine files changed by commits, etc.
+But then staged files would be left out. It might be sufficient to
+make --fast trust the database... except unused will suggest *deleting*
+data if nothing references it. Or maybe it could be required to have a
+clean tree with nothing staged before running git-annex unused.
+
+Anyway, this is a semi-longterm item for me. --[[Joey]]
diff --git a/doc/todo/cache_key_info/comment_1_578df1b3b2cbfdc4aa1805378f35dc48._comment b/doc/todo/cache_key_info/comment_1_578df1b3b2cbfdc4aa1805378f35dc48._comment
new file mode 100644
index 000000000..086e7f3e8
--- /dev/null
+++ b/doc/todo/cache_key_info/comment_1_578df1b3b2cbfdc4aa1805378f35dc48._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 1"
+ date="2011-05-17T07:27:02Z"
+ content="""
+Sounds like a good idea.
+
+* git annex fsck (or similar) should check/rebuild the caches
+* I would simply require a clean tree with a verbose error. 80/20 rule and defaulting to save actions.
+"""]]
diff --git a/doc/todo/checkout.mdwn b/doc/todo/checkout.mdwn
new file mode 100644
index 000000000..50da2d62e
--- /dev/null
+++ b/doc/todo/checkout.mdwn
@@ -0,0 +1,23 @@
+The checkout subcommand replaces the symlink that normally points at a
+file's content, with a copy of the file. Once you've checked a file out,
+you can edit it, and `git commit` it. On commit, git-annex will detect
+if the file has been changed, and if it has, `add` its content to the
+annex.
+
+> Internally, this will need to store the original symlink to the file, in
+> `.git/annex/checkedout/$filename`.
+>
+> * git-annex uncheckout moves that back
+> * git-annex pre-commit hook checks each file being committed to see if
+> it has a symlink there, and if so, removes the symlink and adds the new
+> content to the annex.
+>
+> And it seems the file content should be copied, not moved or hard linked:
+>
+> * Makes sure other annexes can find it if transferring it from
+> this annex.
+> * Ensures it's always available for uncheckout.
+> * Avoids the last copy of a file's content being lost when
+> the checked out file is modified.
+
+[[done]]
diff --git a/doc/todo/checksum_verification_on_transfer.mdwn b/doc/todo/checksum_verification_on_transfer.mdwn
new file mode 100644
index 000000000..c9d505aec
--- /dev/null
+++ b/doc/todo/checksum_verification_on_transfer.mdwn
@@ -0,0 +1,7 @@
+Since most file transfers, particularly to/from encrypted special remotes involve git-annex streaming through the contents of the file anyway, it should be possible to add a verification of the checksum nearly for free. The main thing needed is probably a faster haskell checksum library than Data.Digest.Pure.Sha, which is probably slow enough to be annoying.
+
+I have not verified if an upload could be aborted before sending the data to the remote if a checksum failure is detected. It may be dependent on the individual special remote implementations. Some probably stream the encrypted data directly out the wire, while others need to set up a temp file to run a command on. It would certainly be possible to at least make the upload abort and fail if a bad checksum was detected.
+
+Doing the same for downloads is less useful, because the data is there locally to be fscked. The real advantage would be doing the check for uploads, to ensure that hard-to-detect corrupted files don't reach special remotes.
+
+--[[Joey]]
diff --git a/doc/todo/checksum_verification_on_transfer/comment_1_30f77e631608b9751f9032f97d58cc30._comment b/doc/todo/checksum_verification_on_transfer/comment_1_30f77e631608b9751f9032f97d58cc30._comment
new file mode 100644
index 000000000..5de1251da
--- /dev/null
+++ b/doc/todo/checksum_verification_on_transfer/comment_1_30f77e631608b9751f9032f97d58cc30._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 1"
+ date="2013-09-09T11:50:05Z"
+ content="""
+Doing this during downloads would still be nice.
+
+While the files are easier to fsck, users will need to actually do this. If it happenend automatically, it would increase safety and reduce disk i/o.
+
+Of course, this will not detect degradation during/after writing.
+
+If you don't make it the default, please at least make it optional for us bordering on OCD when it comes to data storage.
+
+
+Richard
+"""]]
diff --git a/doc/todo/direct_mode_guard.mdwn b/doc/todo/direct_mode_guard.mdwn
new file mode 100644
index 000000000..bb7f90897
--- /dev/null
+++ b/doc/todo/direct_mode_guard.mdwn
@@ -0,0 +1,105 @@
+Currently [[/direct_mode]] allows the user to point many normally safe
+git commands at his foot and pull the trigger. At LCA2013, a git-annex
+user suggested modifying direct mode to make this impossible.
+
+One way to do it would be to move the .git directory. Instead, make there
+be a .git-annex directory in direct mode repositories. git-annex would know
+how to use it, and would be extended to support all known safe git
+commands, passing parameters through, and in some cases verifying them.
+
+So, for example, `git annex commit` would run `git commit --git-dir=.git-annex`
+
+However, `git annex commit -a` would refuse to run, or even do something
+intelligent that does not involve staging every direct mode file.
+
+----
+
+One source of problems here is that there is some overlap between git-annex
+and git commands. Ie, `git annex add` cannot be a passthrough for `git
+add`. The git wrapper could instead be another program, or it could be
+something like `git annex git add`
+
+--[[Joey]]
+
+----
+
+Or, no git wrapper could be provided. Limit the commands to only git-annex
+commands. This should be all that is needed to manage a direct mode
+repository simply, and if the user is doing something complicated that
+needs git access, they can set `GIT_DIR=.git-annex` and be careful not to
+shoot off their foot. (Or can just switch to indirect mode!)
+
+This wins on simplicity, and if it's the wrong choice a git wrapper
+can be added later. --[[Joey]]
+
+---
+
+Implementation: Pretty simple really. Already did the hard lifting to
+support `GIT_DIR`, so only need to override the default git directory
+in direct mode when that's not set to `.git-annex`.
+
+A few things hardcode ".git", including Assistant.Threads.Watcher.ignored
+and `Seek.withPathContents`, and parts of `Git.Construct`.
+
+---
+
+Transition: git-annex should detect when it's in a direct mode repository
+with a .git directory and no .git-annex directory, and transparently
+do the move to transition to the new scheme. (And remember that `git annex
+indirect` needs to move it back.)
+
+# alternative approach: move index
+
+Rather than moving .git, maybe move .git/index?
+
+This would cause git to think that all files in the tree were deleted.
+So git commit -a would make a commit that removes them from git history.
+But, the files in the work tree are not touched by this.
+
+Also, git checkout, git merge, and other things that manipulate the work
+tree refuse to do anything if they'd change a file that they think is
+untracked.
+
+Hmm, this does't solve the user accidentially running git add on an annexed
+file; the whole file still gets added.
+
+# alternative approach: fake bare repo
+
+Set core.bare to true. This prevents all work tree operations,
+so prevents any foot shooting. It still lets the user run commands like
+git log, even on files in the tree, and git fetch, and push, and git
+config, etc.
+
+Even better, it integrates with other tools, like `mr`, so they know
+it's a git repo.
+
+This seems really promising. But of course, git-annex has its own set of
+behaviors in a bare repo, so will need to recognise that this repo is not
+really bare, and avoid them.
+
+> [[done]]!! --[[Joey]]
+
+(Git may also have some bare repo behaviors that are unwanted. One example
+is that git allows pushes to the current branch in a bare repo,
+even when `receive.denyCurrentBranch` is set.)
+
+> This is indeed a problem. Indeed, `git annex sync` successfully
+> pushes changes to the master branch of a fake bare direct mode repo.
+>
+> And then, syncing in the repo that was pushed to causes the changes
+> that were pushed to the master branch to get reverted! This happens
+> because sync commits; commit sees that files are staged in index
+> differing from the (pushed) master, and commits the "changes"
+> which revert it.
+>
+> Could fix this using an update hook, to reject the updated of the master
+> branch. However, won't work on crippled filesystems! (No +x bit)
+>
+> Could make git annex sync detect this. It could reset the master
+> branch to the last one committed, before committing. Seems very racy
+> and hard to get right!
+>
+> Could make direct mode operate on a different branch, like
+> `annex/direct/master` rather than `master`. Avoid pushing to that
+> branch (`git annex sync` can map back from it to `master` and push there
+> instead). A bit clumsy, but works.
diff --git a/doc/todo/direct_mode_guard/comment_1_431b6e1577bbd30b07dce9002a8fe1a2._comment b/doc/todo/direct_mode_guard/comment_1_431b6e1577bbd30b07dce9002a8fe1a2._comment
new file mode 100644
index 000000000..01cddc8a3
--- /dev/null
+++ b/doc/todo/direct_mode_guard/comment_1_431b6e1577bbd30b07dce9002a8fe1a2._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn-KDr_Z4CMkjS0v_TxQ08SzAB5ecHG3K0"
+ nickname="Glen"
+ subject="This sounds good"
+ date="2013-06-25T10:30:07Z"
+ content="""
+I think we might have been talking about this feature.. Seems like a good idea to me.
+
+Glen
+"""]]
diff --git a/doc/todo/direct_mode_guard/comment_2_85bdb9dc601b87bd7c77150d7b0a5cde._comment b/doc/todo/direct_mode_guard/comment_2_85bdb9dc601b87bd7c77150d7b0a5cde._comment
new file mode 100644
index 000000000..7cf37a917
--- /dev/null
+++ b/doc/todo/direct_mode_guard/comment_2_85bdb9dc601b87bd7c77150d7b0a5cde._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm7AuSfii_tCkLyspL6Mr0ATlO6OxLNYOo"
+ nickname="Georg"
+ subject="comment 2"
+ date="2013-09-20T11:29:04Z"
+ content="""
+Maybe make a git sub-namespace of commands. Yeah, I know, something like git annex git-add sounds a bit on the verbose side, but it would allow access to possibly all git commands regardless of name clashes.
+"""]]
diff --git a/doc/todo/done.mdwn b/doc/todo/done.mdwn
new file mode 100644
index 000000000..e7c98081b
--- /dev/null
+++ b/doc/todo/done.mdwn
@@ -0,0 +1,4 @@
+recently fixed [[todo]] items.
+
+[[!inline pages="./* and link(./done) and !*/Discussion" sort=mtime show=10
+archive=yes]]
diff --git a/doc/todo/dumb_plaindir_remote___40__e.g._for_NAS_mounts__41__.mdwn b/doc/todo/dumb_plaindir_remote___40__e.g._for_NAS_mounts__41__.mdwn
new file mode 100644
index 000000000..8ce910ac3
--- /dev/null
+++ b/doc/todo/dumb_plaindir_remote___40__e.g._for_NAS_mounts__41__.mdwn
@@ -0,0 +1,5 @@
+I've an external USB hard disc attached to my (fritzbox) router that is only accessible through SMB/CIFS. I'd like have all my annexed files on this drive in kind of direct-mode so that I can also access the files without git-annex.
+
+I tried to put a direct-mode repo on the drive but this is painfully slow. The git-annex process than runs on my desktop and accesses the repo over SMB over the slow fritzbox over USB.
+
+I'd wish that git-annex could be told to just use a (mounted) folder as a direct-mode remote.
diff --git a/doc/todo/dumb_plaindir_remote___40__e.g._for_NAS_mounts__41__/comment_1_5ed9a2336b432b842c1805add6d96509._comment b/doc/todo/dumb_plaindir_remote___40__e.g._for_NAS_mounts__41__/comment_1_5ed9a2336b432b842c1805add6d96509._comment
new file mode 100644
index 000000000..bff1b2fcd
--- /dev/null
+++ b/doc/todo/dumb_plaindir_remote___40__e.g._for_NAS_mounts__41__/comment_1_5ed9a2336b432b842c1805add6d96509._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.64"
+ subject="comment 1"
+ date="2013-11-23T19:03:58Z"
+ content="""
+It's not clear to me what you are requesting here.
+
+You seem to say that running git-annex inside a mountpoint is slow. Ok. So, what possible changes to git-annex could make it fast, given that the bottleneck is the SMB/USB?
+"""]]
diff --git a/doc/todo/dumb_plaindir_remote___40__e.g._for_NAS_mounts__41__/comment_2_e6ba58c5c31ba23a4575f1189689946f._comment b/doc/todo/dumb_plaindir_remote___40__e.g._for_NAS_mounts__41__/comment_2_e6ba58c5c31ba23a4575f1189689946f._comment
new file mode 100644
index 000000000..d60cb2d4d
--- /dev/null
+++ b/doc/todo/dumb_plaindir_remote___40__e.g._for_NAS_mounts__41__/comment_2_e6ba58c5c31ba23a4575f1189689946f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnR6E5iUghMWdUGlbA9CCs8DKaoigMjJXw"
+ nickname="Efraim"
+ subject="comment 2"
+ date="2013-11-26T09:26:53Z"
+ content="""
+perhaps he's looking to be able to expand the addurl option to include file://path/to/video.mp4, or for over smb://... , to import a file without changing its location to being inside the annex.
+"""]]
diff --git a/doc/todo/exclude_files_on_a_given_remote.mdwn b/doc/todo/exclude_files_on_a_given_remote.mdwn
new file mode 100644
index 000000000..e8bb357d3
--- /dev/null
+++ b/doc/todo/exclude_files_on_a_given_remote.mdwn
@@ -0,0 +1,18 @@
+Say I have some files on remote A. But I'm away from it, and transferring
+files from B to C. I'd like to avoid transferring any files I already have
+on A.
+
+Something like:
+
+ git annex copy --to C --exclude-on A
+
+This would not contact A, just use its cached location log info.
+
+I suppose I might also sometime want to only act on files that are
+thought/known to be on A.
+
+ git annex drop --only-on A
+
+--[[Joey]]
+
+[[done]]
diff --git a/doc/todo/faster_gnupg_cipher.mdwn b/doc/todo/faster_gnupg_cipher.mdwn
new file mode 100644
index 000000000..f5ff062d2
--- /dev/null
+++ b/doc/todo/faster_gnupg_cipher.mdwn
@@ -0,0 +1,9 @@
+Apparently newer gnupg has support for hardware-accelerated AES-NI. It
+would be good to have an option to use that. I also wonder if using the
+same symmetric key for many files presents a security issues (and whether
+using GPG keys directly would be more secure).
+
+> [[done]]; you can now use encryption=pubkey when setting up a special
+> remote to use pure public keys without the hybrid symmetric key scheme.
+> Which you choose is up to you. Also, annex.gnupg-options can configure
+> the ciphers used. --[[Joey]]
diff --git a/doc/todo/faster_gnupg_cipher/comment_1_8f61f7c724a8224e61c015be68f43db7._comment b/doc/todo/faster_gnupg_cipher/comment_1_8f61f7c724a8224e61c015be68f43db7._comment
new file mode 100644
index 000000000..1bf550cdf
--- /dev/null
+++ b/doc/todo/faster_gnupg_cipher/comment_1_8f61f7c724a8224e61c015be68f43db7._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.145"
+ subject="comment 1"
+ date="2013-08-01T17:10:56Z"
+ content="""
+There is a remote.name.annex-gnupg-options git-config setting that can be used to pass options to gpg on a per-remote basis.
+
+> also wonder if using the same symmetric key for many files presents a security issues (and whether using GPG keys directly would be more secure).
+
+I am not a cryptographer, but I have today run this question by someone with a good amount of crypo knowledge. My understanding is that reusing a symmetric key is theoretically vulnerable to eg known-plaintext or chosen-plaintext attacks. And that modern ciphers like AES and CAST (gpg default) are designed to resist such attacks.
+
+If someone was particularly concerned about these attack vectors, it would be pretty easy to add a mode where git-annex uses public key encryption directly. With the disadvantage, of course, that once a file was sent to a special remote and encrypted for a given set of public keys, other keys could not later be granted access to it.
+"""]]
diff --git a/doc/todo/faster_gnupg_cipher/comment_2_36e1f227a320527653500b445f7c001c._comment b/doc/todo/faster_gnupg_cipher/comment_2_36e1f227a320527653500b445f7c001c._comment
new file mode 100644
index 000000000..08f69d6b8
--- /dev/null
+++ b/doc/todo/faster_gnupg_cipher/comment_2_36e1f227a320527653500b445f7c001c._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 2"
+ date="2013-08-02T07:21:50Z"
+ content="""
+Using symmetric keys is significantly cheaper, computation-wise.
+
+The scheme of encrypting symmetric keys with asymmetric ones is ancient, well-proven, and generally accepted as a good approach.
+
+Using per-key files makes access control more fine-grained and is only a real performance issue once while creating the private key and a little bit every time more than one file needs to be decrypted as more than one symmetric key needs to be taken care of.
+"""]]
diff --git a/doc/todo/faster_gnupg_cipher/comment_3_bd0c975494333dfe558de048d888ace8._comment b/doc/todo/faster_gnupg_cipher/comment_3_bd0c975494333dfe558de048d888ace8._comment
new file mode 100644
index 000000000..d0b98b7f6
--- /dev/null
+++ b/doc/todo/faster_gnupg_cipher/comment_3_bd0c975494333dfe558de048d888ace8._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="guilhem"
+ ip="129.16.20.209"
+ subject="comment 3"
+ date="2013-08-19T13:44:35Z"
+ content="""
+AES-NI acceleration will be used by default providing you're using
+the new modularized GnuPG (v2.x) and libgcrypt ≥ 1.5.0. Of course it
+only speeds up AES encryption, while GnuPG uses CAST by default; you can
+either set `personal-cipher-preferences` to AES or AES256 in your
+`gpg.conf` or, as joeyh hinted at, set `remote.<name>.annex-gnupg-options`
+as described in the manpage.
+
+By the way, I observed a significant speed up when using `--compress-algo none`.
+Image, music and video files are typically hard to compress further, and it seems
+that's where gpg spent most of its time, at least on the few files I benchmarked.
+"""]]
diff --git a/doc/todo/faster_rsync_remotes.mdwn b/doc/todo/faster_rsync_remotes.mdwn
new file mode 100644
index 000000000..8c40b2816
--- /dev/null
+++ b/doc/todo/faster_rsync_remotes.mdwn
@@ -0,0 +1,4 @@
+Using an rsync remote is currently very slow when there are a lot of files, since rsync appears to be called for each file copied. It would be awesome if each call to rsync was amortized to copy many files; rsync is very good at copying many small files quickly.
+
+> [[done]]; bug submitter was apparently not using a version
+> with rsync connection caching. --[[Joey]]
diff --git a/doc/todo/faster_rsync_remotes/comment_1_0bc3ee0ae563357675eeccf42461e59a._comment b/doc/todo/faster_rsync_remotes/comment_1_0bc3ee0ae563357675eeccf42461e59a._comment
new file mode 100644
index 000000000..2f320fee2
--- /dev/null
+++ b/doc/todo/faster_rsync_remotes/comment_1_0bc3ee0ae563357675eeccf42461e59a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.145"
+ subject="comment 1"
+ date="2013-08-01T16:06:42Z"
+ content="""
+I cannot see a way to do this using rsync's current command-line interface. Ideas how to do it welcomed.
+"""]]
diff --git a/doc/todo/faster_rsync_remotes/comment_2_ccf6f75450c89ca498c8130054f8d32d._comment b/doc/todo/faster_rsync_remotes/comment_2_ccf6f75450c89ca498c8130054f8d32d._comment
new file mode 100644
index 000000000..67b5feab0
--- /dev/null
+++ b/doc/todo/faster_rsync_remotes/comment_2_ccf6f75450c89ca498c8130054f8d32d._comment
@@ -0,0 +1,24 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawln4uCaqZRd5_nRQ-iLcJyGctIdw8ebUiM"
+ nickname="Edward"
+ subject="Just put multiple source files"
+ date="2013-08-01T16:29:04Z"
+ content="""
+It seems like you can just put multiple source files on the command line:
+
+ ed@ed-Ubu64 /tmp$ touch a b c d
+ ed@ed-Ubu64 /tmp$ mkdir test
+ ed@ed-Ubu64 /tmp$ rsync -avz a b c d test
+ sending incremental file list
+ a
+ b
+ c
+ d
+
+ sent 197 bytes received 88 bytes 570.00 bytes/sec
+ total size is 0 speedup is 0.00
+ ed@ed-Ubu64 /tmp$ ls test
+ a b c d
+
+It also appears to work with remote transfers too.
+"""]]
diff --git a/doc/todo/faster_rsync_remotes/comment_3_2f6a9d23cb8351fbf0f60ed93752e76e._comment b/doc/todo/faster_rsync_remotes/comment_3_2f6a9d23cb8351fbf0f60ed93752e76e._comment
new file mode 100644
index 000000000..1911048be
--- /dev/null
+++ b/doc/todo/faster_rsync_remotes/comment_3_2f6a9d23cb8351fbf0f60ed93752e76e._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.145"
+ subject="comment 3"
+ date="2013-08-01T16:58:49Z"
+ content="""
+git-annex needs to build a specific directory structure on the rsync remote though. It seems it would need to build the whole tree locally, containing only the files it wants to send.
+
+When using encryption, it would need to encrypt all the files it's going to send and store them locally until it's built the tree. That could use a lot of disk space.
+
+Also, there's the problem of checking which files are already present in the remote, to avoid re-encrypting and re-sending them. Currently this is done by running rsync with the url of the file, and checking its exit code. rsync does not seem to have an interface that would allow checking multiple files in one call. So any optimisation of the number of rsync calls would only eliminate 1/2 of the current number.
+
+When using ssh:// urls, the rsync special remote already uses ssh connection caching, which I'd think would eliminate most of the overhead. (If you have a version of git-annex older than 4.20130417, you should upgrade to get this feature.) It should not take very long to start up a new rsync over a cached ssh connection. rsync:// is probably noticably slower.
+"""]]
diff --git a/doc/todo/faster_rsync_remotes/comment_4_3a2f45defebae3dde336ee5f40c26d7e._comment b/doc/todo/faster_rsync_remotes/comment_4_3a2f45defebae3dde336ee5f40c26d7e._comment
new file mode 100644
index 000000000..44d7d5511
--- /dev/null
+++ b/doc/todo/faster_rsync_remotes/comment_4_3a2f45defebae3dde336ee5f40c26d7e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawln4uCaqZRd5_nRQ-iLcJyGctIdw8ebUiM"
+ nickname="Edward"
+ subject="Thanks"
+ date="2013-08-01T17:03:23Z"
+ content="""
+I am using an old version of git-annex. I'll try the newer one and see if the connection caching helps!
+"""]]
diff --git a/doc/todo/file_copy_progress_bar.mdwn b/doc/todo/file_copy_progress_bar.mdwn
new file mode 100644
index 000000000..847c1d1eb
--- /dev/null
+++ b/doc/todo/file_copy_progress_bar.mdwn
@@ -0,0 +1,5 @@
+Find a way to copy a file with a progress bar, while still preserving
+stat. Easiest way might be to use pv and fix up the permissions etc
+after?
+
+[[done]]
diff --git a/doc/todo/free_space_checking_for_local_special_remotes.mdwn b/doc/todo/free_space_checking_for_local_special_remotes.mdwn
new file mode 100644
index 000000000..0fd2eac59
--- /dev/null
+++ b/doc/todo/free_space_checking_for_local_special_remotes.mdwn
@@ -0,0 +1,4 @@
+Should be possible to configure an annex.diskreserve setting for local
+special remotes, such as a directory special remote or possibly a bup
+special remote. (Although bup's deltas will make storing some versions of
+files take less space than git-annex would have to assume it would take.)
diff --git a/doc/todo/free_space_checking_for_local_special_remotes/comment_1_47c254cec58cbbb3ea84c93ef8282f01._comment b/doc/todo/free_space_checking_for_local_special_remotes/comment_1_47c254cec58cbbb3ea84c93ef8282f01._comment
new file mode 100644
index 000000000..00c4c5625
--- /dev/null
+++ b/doc/todo/free_space_checking_for_local_special_remotes/comment_1_47c254cec58cbbb3ea84c93ef8282f01._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.7.235"
+ subject="comment 1"
+ date="2013-07-11T16:19:26Z"
+ content="""
+Directory special remotes do already honor annex.diskreserve, it turns out. Let's repurpose this bug to be about adding a per-remote configuration, in case the main annex.diskreserve is not appropriate.
+"""]]
diff --git a/doc/todo/fsck.mdwn b/doc/todo/fsck.mdwn
new file mode 100644
index 000000000..1dcaad9a5
--- /dev/null
+++ b/doc/todo/fsck.mdwn
@@ -0,0 +1,11 @@
+add a git annex fsck that finds keys that have no referring file
+
+(done)
+
+* Need per-backend fsck support. sha1 can checksum all files in the annex.
+ WORM can check filesize.
+
+* Both can check that annex.numcopies is satisfied. Probably only
+ querying the locationlog, not doing an online verification.
+
+[[done]]
diff --git a/doc/todo/fsck_special_remotes.mdwn b/doc/todo/fsck_special_remotes.mdwn
new file mode 100644
index 000000000..7196baafe
--- /dev/null
+++ b/doc/todo/fsck_special_remotes.mdwn
@@ -0,0 +1,13 @@
+`git annex fsck --from remote`
+
+Basically, this needs to receive each file in turn from the remote, to a
+temp file, and then run the existing fsck code on it. Could be quite
+expensive, but sometimes you really want to check.
+
+An unencrypted directory special remote could be optimised, by not actually
+copying the file, just dropping a symlink, etc.
+
+The WORM backend doesn't care about file content, so it would be nice to
+avoid transferring the content at all, and only send the size.
+
+> [[done]] --[[Joey]]
diff --git a/doc/todo/git-annex-shell.mdwn b/doc/todo/git-annex-shell.mdwn
new file mode 100644
index 000000000..a9e3b43ed
--- /dev/null
+++ b/doc/todo/git-annex-shell.mdwn
@@ -0,0 +1,15 @@
+[[done]]
+
+I've been considering adding a `git-annex-shell` command. This would
+be similar to `git-shell` (and in fact would pass unknown commands off to
+`git-shell`).
+
+## Reasons
+
+* Allows locking down an account to only be able to use git-annex (and
+ git).
+* Avoids needing to construct complex shell commands to run on the remote
+ system. (Mostly already avoided by the plumbing level commands.)
+* Could possibly allow multiple things to be done with one ssh connection
+ in future.
+* Allows expanding `~` and `~user` in repopath on the remote system.
diff --git a/doc/todo/git-annex_unused_eats_memory.mdwn b/doc/todo/git-annex_unused_eats_memory.mdwn
new file mode 100644
index 000000000..760a6ccf5
--- /dev/null
+++ b/doc/todo/git-annex_unused_eats_memory.mdwn
@@ -0,0 +1,32 @@
+`git-annex unused` has to compare large sets of data
+(all keys with content present in the repository,
+with all keys used by files in the repository), and so
+uses more memory than git-annex typically needs.
+
+It used to be a lot worse (hundreds of megabytes).
+
+Now it only needs enough memory to store a Set of all Keys that currently
+have content in the annex. On a lightly populated repository, it runs in
+quite low memory use (like 8 mb) even if the git repo has 100 thousand
+files. On a repository with lots of file contents, it will use more.
+
+Still, I would like to reduce this to a purely constant memory use,
+as running in constant memory no matter the repo size is a git-annex design
+goal.
+
+One idea is to use a bloom filter.
+For example, construct a bloom filter of all keys used by files in
+the repository. Then for each key with content present, check if it's
+in the bloom filter. Since there can be false positives, this might
+miss finding some unused keys. The probability/size of filter
+could be tunable.
+
+> Fixed in `bloom` branch in git. --[[Joey]]
+>> [[done]]! --[[Joey]]
+
+Another way might be to scan the git log for files that got removed
+or changed what key they pointed to. Correlate with keys with content
+currently present in the repository (possibly using a bloom filter again),
+and that would yield a shortlist of keys that are probably not used.
+Then scan thru all files in the repo to make sure that none point to keys
+on the shortlist.
diff --git a/doc/todo/git_annex_init_:_include_repo_description_and__47__or_UUID_in_commit_message.mdwn b/doc/todo/git_annex_init_:_include_repo_description_and__47__or_UUID_in_commit_message.mdwn
new file mode 100644
index 000000000..be7e2dacc
--- /dev/null
+++ b/doc/todo/git_annex_init_:_include_repo_description_and__47__or_UUID_in_commit_message.mdwn
@@ -0,0 +1,13 @@
+Would help alot when having to add large(ish) amounts of remotes.
+
+Maybe detect this kind of commit message and ask user whether to automatically add them? See [[auto_remotes]]:
+> Question: When should git-annex update the remote.log? (If not just on init.) Whenever it reads in a repo's remotes?
+
+----
+
+I'm not sure that the above suggestion is going down a path that really
+makes sense. If you want a list of repository UUIDs and descriptions,
+it's there in machine-usable form in `.git-annex/uuid.log`, there is no
+need to try to pull this info out of git commit messages. --[[Joey]]
+
+[[done]]
diff --git a/doc/todo/gitolite_and_gitosis_support.mdwn b/doc/todo/gitolite_and_gitosis_support.mdwn
new file mode 100644
index 000000000..2fca83986
--- /dev/null
+++ b/doc/todo/gitolite_and_gitosis_support.mdwn
@@ -0,0 +1,39 @@
+gitosis and gitolite should support git-annex being used to send/receive
+files from the repositories they manage. Users with read-only access
+could only get files, while users with write access could also put and drop
+files.
+
+Doing this right requires modifying both programs, to add [[git-annex-shell]]
+to the list of things they can run, and only allow through appropriate
+git-annex-shell subcommands to read-only users.
+
+I have posted an RFC for modifying gitolite to the
+[gitolite mailing list](http://groups.google.com/group/gitolite?lnk=srg).
+
+> I have not developed a patch yet, but all that git-annex needs is a way
+> to ssh to the server and run the git-annex-shell command there.
+> git-annex-shell is very similar to git-shell. So, one way to enable
+> it is simply to set GL_ADC_PATH to a directory containing git-annex-shell.
+>
+> But, that's not optimal, since git-annex-shell will send off receive-pack
+> commands to git, which would bypass gitolite's permissions checking.
+> Also, it makes sense to limit readonly users to only download, not
+> upload/delete files from git-annex. Instead, I suggest adding something
+> like this to gitolite's config:
+
+ # If set, users with W access can write file contents into the git-annex,
+ # and users with R access can read file contents from the git-annex.
+ $GL_GIT_ANNEX = 0;
+
+> If this makes sense, I'm sure I can put a patch together for your
+> review. It would involve modifying gl-auth-command so it knows how
+> to run git-annex-shell, and how to parse out the "verb" from a
+> git-annex-shell command line, and modifying R_COMMANDS and W_COMMANDS.
+
+As I don't write python, someone else is needed to work on gitosis.
+--[[Joey]]
+
+> [[done]]; support for gitolite is in its `pu` branch, and some changes
+> made to git-annefor gitolite is in its `pu` branch, and some changes
+> made to git-annex. Word is gitosis is not being maintained so I won't
+> worry about try to support it. --[[Joey]]
diff --git a/doc/todo/gitrm.mdwn b/doc/todo/gitrm.mdwn
new file mode 100644
index 000000000..e41c33462
--- /dev/null
+++ b/doc/todo/gitrm.mdwn
@@ -0,0 +1,5 @@
+how to handle git rm file? (should try to drop keys that have no
+referring file, if it seems safe..)
+
+[[done]] -- I think that git annex unused and dropunused are the best
+solution to this.
diff --git a/doc/todo/hidden_files.mdwn b/doc/todo/hidden_files.mdwn
new file mode 100644
index 000000000..191e9c328
--- /dev/null
+++ b/doc/todo/hidden_files.mdwn
@@ -0,0 +1,30 @@
+Add a `git annex hide $file` that behaves like drop, checking counter info
+and updating location log to say the current repo no longer has a file --
+but does not actually remove the content.
+
+Then `git annex unused` can be used to clean it up later. And in the
+meantime, it's still locally accessible. This can be useful if you're
+planning to need to free up space later, but want to hold onto the content
+for a while. Possibly you'll be disconnected later, so it's easier to push
+out that intent now.
+
+--
+
+TODO:
+
+* Make 100% sure this is safe. Drop, etc should never check content files
+ are present on other repos if the location log doesn't say the repo
+ has the content.
+
+* What will `git annex get` do if it's asked to get a file that has been
+ hidden?
+
+> Unless I am missing something: Make sure the data is correct (for SHA1 or other tracking) and restore locally. If that's not the case, delete and restore from remote. -- RichiH
+
+----
+
+Is 'unused' a good name? 'clean' and 'autoclean' would make more sense, imo. 'clean' deletes everything, whereas an optional 'autoclean' could try to be smart based on disk usage and/or SHA1, etc. -- RichiH
+
+> Nah, `git annex unused/dropunused` already exist. --[[Joey]]
+
+>> OK, in that case forget what I said. No idea about your internal policy, but feel free to delete this part of the page, then. -- RichiH
diff --git a/doc/todo/http_git_annex_404_retry.mdwn b/doc/todo/http_git_annex_404_retry.mdwn
new file mode 100644
index 000000000..38ab860bb
--- /dev/null
+++ b/doc/todo/http_git_annex_404_retry.mdwn
@@ -0,0 +1,16 @@
+A repository like http://annex.debconf.org/debconf-share/ has a git repo
+published via http. When getting files from such a repo, git-annex tries
+two urls. One url would be used by a bare repo, and the other by a non-bare
+repo. (This is due to the directory hashing change.) Result is every file
+download from a non-bare http repo starts with a 404 and then it retries
+with the right url.
+
+Since git-annex already downloads the .git/config to find the uuid of the
+http repo, it could also look at it to see if the repo is bare. If not,
+set a flag, and try the two urls in reverse order, which would almost
+always avoid this 404 problem.
+
+(The real solution is probably to flag day and get rid of the old-style
+directory hashing, but that's been discussed elsewhere.)
+
+--[[Joey]]
diff --git a/doc/todo/http_headers.mdwn b/doc/todo/http_headers.mdwn
new file mode 100644
index 000000000..9f61bdc93
--- /dev/null
+++ b/doc/todo/http_headers.mdwn
@@ -0,0 +1,8 @@
+The IA would find it useful to be able to control the http headers
+git-annex get, addurl, etc uses. This will allow setting cookies, for
+example.
+
+* annex-web-headers=blah
+* Perhaps also annex-web-headers-command=blah
+
+[[done]]
diff --git a/doc/todo/immutable_annexed_files.mdwn b/doc/todo/immutable_annexed_files.mdwn
new file mode 100644
index 000000000..b26838e95
--- /dev/null
+++ b/doc/todo/immutable_annexed_files.mdwn
@@ -0,0 +1,8 @@
+> josh: Do you do anything in git-annex to try to make the files immutable?
+> For instance, removing write permission, or even chattr?
+> joey: I don't, but that's a very good idea
+> josh: Oh, I just thought of another slightly crazy but handy idea.
+> josh: I'd hate to run into a program which somehow followed the symlink and then did an unlink to replace the file.
+> josh: To break that, you could create a new directory under annex's internal directory for each file, and make the directory have no write permission.
+
+[[done]] and done --[[Joey]]
diff --git a/doc/todo/importfeed:_allow___36____123__itemdate__125___with_--template.mdwn b/doc/todo/importfeed:_allow___36____123__itemdate__125___with_--template.mdwn
new file mode 100644
index 000000000..46d9de34f
--- /dev/null
+++ b/doc/todo/importfeed:_allow___36____123__itemdate__125___with_--template.mdwn
@@ -0,0 +1,5 @@
+It would be great to be able to use the pubDate of the entries with the --template option of importfeed.
+
+Text.Feed.Query has a getItemPublishDate (and a getFeedPubDate, if we want some kind of ${feeddate}).
+
+The best would be to allow a reformating of the date(s) with (for example) %Y-%m-%D
diff --git a/doc/todo/importfeed:_allow___36____123__itemdate__125___with_--template/comment_1_62752c760fc12eca0c34d67d58753d00._comment b/doc/todo/importfeed:_allow___36____123__itemdate__125___with_--template/comment_1_62752c760fc12eca0c34d67d58753d00._comment
new file mode 100644
index 000000000..cc3d85faf
--- /dev/null
+++ b/doc/todo/importfeed:_allow___36____123__itemdate__125___with_--template/comment_1_62752c760fc12eca0c34d67d58753d00._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="gueux"
+ ip="2a01:240:fe6d:0:7986:3659:a8bd:64f1"
+ subject="syntax"
+ date="2013-09-12T14:05:16Z"
+ content="""
+use \"itemdate\" and \"feeddate\" as names?
+
+use ${itemdate=%Y-%m-%D} syntax option?
+"""]]
diff --git a/doc/todo/importfeed:_allow___36____123__itemdate__125___with_--template/comment_2_21672360060f48bc2eacfa535ff4c94d._comment b/doc/todo/importfeed:_allow___36____123__itemdate__125___with_--template/comment_2_21672360060f48bc2eacfa535ff4c94d._comment
new file mode 100644
index 000000000..c8770ec6e
--- /dev/null
+++ b/doc/todo/importfeed:_allow___36____123__itemdate__125___with_--template/comment_2_21672360060f48bc2eacfa535ff4c94d._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.2.134"
+ subject="comment 2"
+ date="2013-09-13T19:53:52Z"
+ content="""
+getItemPublishDate returns a String, which can contain any of several date formats. Deferred until the feed library has something more sane.
+Upstream bug: <https://github.com/sof/feed/issues/6>
+
+As for how to format the date in the feed, I would be ok with having itemdate (YYYYMMDD), itemyear (YYYY), itemmonth (MM) and itemday (DD). Full date formatting seems like overkill here.
+"""]]
diff --git a/doc/todo/incremental_fsck.mdwn b/doc/todo/incremental_fsck.mdwn
new file mode 100644
index 000000000..7c56328b9
--- /dev/null
+++ b/doc/todo/incremental_fsck.mdwn
@@ -0,0 +1,24 @@
+Justin Azoff realized git-annex should have an incremental fsck.
+
+This requires storing the last fsck time of each object.
+
+I would not be strongly opposed to sqlite, but I think there are other
+places the data could be stored. One possible place is the mode or mtime
+of the .git/annex/objects/xx/yy/$key directories (the parent directories
+of where the content is stored). Perhaps the sticky bit could be used to
+indicate the content has been fsked, and the mtime indicate the time
+of last fsck. Anything that dropped or put in content would need to
+clear the sticky bit. --[[Joey]]
+
+> Basic incremental fsck is done now.
+>
+> Some enhancements would include:
+>
+> * --max-age=30d Once the incremental fsck completes and was started 30 days ago,
+> start a new one.
+> * --time-limit --size-limit --file-limit: Limit how long the fsck runs.
+
+>> Calling this [[done]]. The `--incremental-schedule` option
+>> allows scheduling time between incremental fscks. `--time-limit` is
+>> done. I implemented `--smallerthan` independently. Not clear what
+>> `--file-limit` would be. --[[Joey]]
diff --git a/doc/todo/incremental_fsck/comment_1_609b21141dd5686b2c0eaef2b8d63229._comment b/doc/todo/incremental_fsck/comment_1_609b21141dd5686b2c0eaef2b8d63229._comment
new file mode 100644
index 000000000..709ba078c
--- /dev/null
+++ b/doc/todo/incremental_fsck/comment_1_609b21141dd5686b2c0eaef2b8d63229._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="comment 1"
+ date="2012-09-20T14:11:57Z"
+ content="""
+I have a [proof of concept written in python](https://github.com/JustinAzoff/git-annex-background-fsck/blob/master/git-annex-background-fsck).
+
+You can run it and point it the root of an annex or to a subdirectory. In my brief testing it seems to work :-)
+
+the goal would be to have options like
+
+ git annex fsck /data/annex --check-older-than 1w --check-for 2h --max-load-avg 0.5
+"""]]
diff --git a/doc/todo/keep_annexed_files_for_a_while.mdwn b/doc/todo/keep_annexed_files_for_a_while.mdwn
new file mode 100644
index 000000000..cf85b11f3
--- /dev/null
+++ b/doc/todo/keep_annexed_files_for_a_while.mdwn
@@ -0,0 +1,8 @@
+I don't want files that I dropped to immediately disappear from my local or all of my remotes repos on the next sync. Especially in situations where changes to the git-annex repo get automatically and immediately replicated to remote repos, I want a configurable "grace" period before files in .git/annex/objects get really deleted.
+
+This has similarities to the "trash" on a desktop. It might also be nice to
+
+* configure a maximum amount of space of the "trash"
+* have a way to see the contents of the trash to easily recover deleted files
+
+Maybe it would make sense to just move dropped files to the desktops trash? "git annex trash" as an alternative to drop?
diff --git a/doc/todo/link_file_to_remote_repo_feature.mdwn b/doc/todo/link_file_to_remote_repo_feature.mdwn
new file mode 100644
index 000000000..d6b41e805
--- /dev/null
+++ b/doc/todo/link_file_to_remote_repo_feature.mdwn
@@ -0,0 +1,52 @@
+I have two repos, using SHA1 backend and both using git.
+The first one is a laptop, the second one is a usb drive.
+
+When I drop a file on the laptop repo, the file is not available on that repo until I run *git annex get*
+But when the usb drive is plugged in the file is actually available.
+
+How about adding a feature to link some/all files to the remote repo?
+
+e.g.
+We have *railscasts/196-nested-model-form-part-1.mp4* file added to git, and only available on the usb drive:
+
+ $ git annex whereis 196-nested-model-form-part-1.mp4
+ whereis 196-nested-model-form-part-1.mp4 (1 copy)
+ a7b7d7a4-2a8a-11e1-aebc-d3c589296e81 -- origin (Portable usb drive)
+
+I can see the link with:
+
+ $ cd railscasts
+ $ ls -ls 196*
+ 8 lrwxr-xr-x 1 framallo staff 193 Dec 20 05:49 196-nested-model-form-part-1.mp4 -> ../.git/annex/objects/Wz/6P/SHA256-s16898930--43679c67cd968243f58f8f7fb30690b5f3f067574e318d609a01613a2a14351e/SHA256-s16898930--43679c67cd968243f58f8f7fb30690b5f3f067574e318d609a01613a2a14351e
+
+I save this in a variable just to make the example more clear:
+
+ ID=".git/annex/objects/Wz/6P/SHA256-s16898930--43679c67cd968243f58f8f7fb30690b5f3f067574e318d609a01613a2a14351e/SHA256-s16898930--43679c67cd968243f58f8f7fb30690b5f3f067574e318d609a01613a2a14351e"
+
+The file doesn't exist on the local repo:
+
+ $ ls ../$ID
+ ls: ../$ID: No such file or directory
+
+however I can create a link to access that file on the remote repo.
+First I create a needed dir:
+
+ $ mkdir ../.git/annex/objects/Wz/6P/SHA256-s16898930--43679c67cd968243f58f8f7fb30690b5f3f067574e318d609a01613a2a14351e/
+
+Then I link to the remote file:
+
+ $ ln -s /mnt/usb_drive/repo_folder/$ID ../$ID
+
+now I can open the file in the laptop repo.
+
+
+I think it could be easy to implement. Maybe It's a naive approach, but looks apealing.
+Checking if it's a real file or a link shouldn't impact on performance.
+The limitation is that it would work only with remote repos on local dirs
+
+Also allows you to have one directory structure like AFS or other distributed FS. If the file is not local I go to the remote server.
+Which is great for apps like Picasa, Itunes, and friends that depends on the file location.
+
+> This is a duplicate of [[union_mounting]]. So closing it: [[done]].
+>
+> It's a good idea, but making sure git-annex correctly handles these links in all cases is a subtle problem that has not yet been tackled. --[[Joey]]
diff --git a/doc/todo/makefile:_respect___36__PREFIX.mdwn b/doc/todo/makefile:_respect___36__PREFIX.mdwn
new file mode 100644
index 000000000..12d7274b9
--- /dev/null
+++ b/doc/todo/makefile:_respect___36__PREFIX.mdwn
@@ -0,0 +1,25 @@
+The `Makefile` should respect a `PREFIX` passed on the commandline so git-annex can be installed in (say) `$HOME`.
+
+Simple patch:
+
+[[!format diff """
+diff --git a/Makefile b/Makefile
+index b8995b2..5b1a6d4 100644
+--- a/Makefile
++++ b/Makefile
+@@ -3,7 +3,7 @@ all=git-annex $(mans) docs
+
+ GHC?=ghc
+ GHCMAKE=$(GHC) $(GHCFLAGS) --make
+-PREFIX=/usr
++PREFIX?=/usr
+ CABAL?=cabal # set to "./Setup" if you lack a cabal program
+
+ # Am I typing :make in vim? Do a fast build.
+"""]]
+
+--[[anarcat]]
+
+> [[done]] --[[Joey]]
+
+> > [[thanks]]! ;) --[[anarcat]]
diff --git a/doc/todo/mdwn2man:_make_backticks_bold.mdwn b/doc/todo/mdwn2man:_make_backticks_bold.mdwn
new file mode 100644
index 000000000..21707a309
--- /dev/null
+++ b/doc/todo/mdwn2man:_make_backticks_bold.mdwn
@@ -0,0 +1,22 @@
+The traditionnal way of marking commandline flags in a manpage is with a `.B` (for Bold, I guess). It doesn't seem to be used by mdwn2man, which makes the manpage look a little more dull than it could.
+
+The following patch makes those options come out more obviously:
+
+[[!format diff """
+diff --git a/Build/mdwn2man b/Build/mdwn2man
+index ba5919b..7f819ad 100755
+--- a/Build/mdwn2man
++++ b/Build/mdwn2man
+@@ -8,6 +8,7 @@ print ".TH $prog $section\n";
+
+ while (<>) {
+ s{(\\?)\[\[([^\s\|\]]+)(\|[^\s\]]+)?\]\]}{$1 ? "[[$2]]" : $2}eg;
++ s/\`([^\`]*)\`/\\fB$1\\fP/g;
+ s/\`//g;
+ s/^\s*\./\\&./g;
+ if (/^#\s/) {
+"""]]
+
+I tested it against the git-annex manpage and it seems to work well. --[[anarcat]]
+
+> [[done]], thanks --[[Joey]]
diff --git a/doc/todo/network_remotes.mdwn b/doc/todo/network_remotes.mdwn
new file mode 100644
index 000000000..42efa832f
--- /dev/null
+++ b/doc/todo/network_remotes.mdwn
@@ -0,0 +1,5 @@
+Support for remote git repositories (ssh:// specifically can be made to
+work, although the other end probably needs to have git-annex
+installed..)
+
+[[done]], at least get and put work..
diff --git a/doc/todo/nicer_whereis_output.mdwn b/doc/todo/nicer_whereis_output.mdwn
new file mode 100644
index 000000000..871eee01a
--- /dev/null
+++ b/doc/todo/nicer_whereis_output.mdwn
@@ -0,0 +1,100 @@
+We had some informal discussions on IRC about improving the output of the `whereis` command.
+
+[[!toc levels=2]]
+
+First version: columns
+======================
+
+[[mastensg]] started by implementing a [simple formatter](https://gist.github.com/mastensg/6500982) that would display things in columns [screenshot](http://www.ping.uio.no/~mastensg/whereis.png)
+
+Second version: Xs
+==================
+
+After some suggestions from [[joey]], [[mastensg]] changed the format slightly ([screenshot](http://www.ping.uio.no/~mastensg/whereis2.png)):
+
+[[!format txt """
+17:01:34 <joeyh> foo
+17:01:34 <joeyh> |bar
+17:01:34 <joeyh> ||baz (untrusted)
+17:01:34 <joeyh> |||
+17:01:34 <joeyh> XXx 3? img.png
+17:01:36 <joeyh> _X_ 1! bigfile
+17:01:37 <joeyh> XX_ 2 zort
+17:01:39 <joeyh> __x 1?! maybemissing
+17:02:09 * joeyh does a s/\?/+/ in the above
+17:02:24 <joeyh> and decrements the counters for untrusted
+17:03:37 <joeyh> __x 0+! maybemissing
+"""]]
+
+Third version: incremental
+==========================
+
+Finally, [[anarcat]] worked on making it run faster on large repositories, in a [fork](https://gist.github.com/anarcat/6502988) of that first gist. Then paging was added (so headers are repeated).
+
+Fourth version: tuning and blocked
+==================================
+
+[[TobiasTheViking]] provided some bugfixes, and the next step was to implement the trusted/untrusted detection, and have a counter.
+
+This required more advanced parsing of the remotes, and instead of starting to do some JSON parsing, [[anarcat]] figured it was time to learn some Haskell instead.
+
+Current status: needs merge
+===========================
+
+So right now, the most recent version of the python script is in [anarcat's gist](https://gist.github.com/anarcat/6502988) and works reasonably well. However, it doesn't distinguish between trusted and untrusted repos and so on.
+
+Furthermore, we'd like to see this factored into the `whereis` command directly. A [raw.hs](http://codepad.org/miVJb5oK) file has been programmed by `mastensg`, and is now available in the above gist. It fits the desired output and prototypes, and has been `haskellized` thanks to [[guilhem]].
+
+Now we just need to merge those marvelous functions in `Whereis.hs` - but I can't quite figure out where to throw that code, so I'll leave it to someone more familiar with the internals of git-annex. The most recent version is still in [anarcat's gist](https://gist.github.com/anarcat/6502988). --[[anarcat]]
+
+Desired output
+--------------
+
+The output we're aiming for is:
+
+ foo
+ |bar
+ ||baz (untrusted)
+ |||
+ XXx 2+ img.png
+ _X_ 1! bigfile
+ XX_ 2 zort
+ __x 0+! maybemissing
+
+Legend:
+
+ * `_` - file missing from repo
+ * `x` - file may be present in untrusted repo
+ * `X` - file is present in trusted repo
+ * `[0-9]` - number of copies present in trusted repos
+ * `+` - indicates there may be more copies present
+ * `!` - indicates only one copy is left
+
+Implementation notes
+--------------------
+
+[[!format txt """
+20:48:18 <joeyh> if someone writes me a headerWhereis :: [(RemoteName, TrustLevel)] -> String and a formatWhereis :: [(RemoteName, TrustLevel, UUID)] -> [UUD] -> FileName -> String , I can do the rest ;)
+20:49:22 <joeyh> make that second one formatWhereis :: [(RemoteName, TrueLevel, Bool)] -> FileName -> String
+20:49:37 <joeyh> gah, typos
+20:49:45 <joeyh> suppose you don't need the RemoteName either
+"""]]
+
+> So, I incorporated this, in a new remotes command.
+> Showing all known repositories seemed a bit much
+> (I have 30-some known repositories in some cases),
+> so just showing configured remotes seems a good simplification.
+> [[done]]
+> --[[Joey]]
+
+> > I would have prefered this to be optional since I don't explicitely configure all remotes in git, especially if I can't reach them all the time (e.g. my laptop). It seems to me this should at least be an option, but I am confused as to why `Remote.List.remoteList` doesn't list all remotes the same way `Remote.remote_list` does... Also, it's unfortunate that the +/!/count flags have been dropped, it would have been useful... Thanks for the merge anyways! --[[done]]
+> >
+> > The more I look at this, the more i think there are a few things wrong with the new `remotes` command.
+> >
+> > 1. the name is confusing: being a git addict, I would expect the `git annex remote` command to behave like the `git remote` command: list remotes, add remotes, remove remotes and so on. it would actually be useful to have such a command (which would replace `initremote`, I guess). i recommend replacing the current `whereis` command, even if enabled through a special flag
+> >
+> > 2. its behavior is inconsistent with other git annex commands: `git annex status`, for example, lists information about all remotes, regardless of whether they are configured in git. `remotes` (whatever it's called), should do the same, or at least provide an option to allow the user to list files on all remotes. The way things stand, there is no way to list files on non-git remotes, even if they are added explicitely as a remote, if the remote is not actually reachable: the files are just marked as absent (even thought `whereis` actually finds them). i recommend showing all remotes regardless, either opt-in or opt-out using a flag.
+> >
+> > 3. having the `!` flag, at least, would be useful because it would allow users to intuitively grep for problematic files without having to learn extra syntax. same with + and having an explicit count.
+> >
+> > thanks. --[[anarcat]]
diff --git a/doc/todo/object_dir_reorg_v2.mdwn b/doc/todo/object_dir_reorg_v2.mdwn
new file mode 100644
index 000000000..49666ddc7
--- /dev/null
+++ b/doc/todo/object_dir_reorg_v2.mdwn
@@ -0,0 +1,25 @@
+Several things suggest now would be a good time to reorgaize the object
+directory. This would be annex.version=2. It will be slightly painful for
+all users, so this should be the *last* reorg in the forseeable future.
+
+1. Remove colons from filenames, for [[bugs/fat_support]]
+
+2. Add hashing, since some filesystems do suck (like er, fat at least :)
+ [[forum/hashing_objects_directories]]
+ (Also, may as well hash .git-annex/* while at it -- that's what
+ really gets big.)
+
+3. Add filesize metadata for [[bugs/free_space_checking]]. (Currently only
+ present in WORM, and in an ad-hoc way.)
+
+4. Perhaps use a generic format that will allow further metadata to be
+ added later. For example,
+ "bSHA1,s101111,kf3101c30bb23467deaec5d78c6daa71d395d1879"
+
+ (Probably everything after ",k" should be part of the key, even if it
+ contains the "," separator character. Otherwise an escaping mechanism
+ would be needed.)
+
+[[done]] now!
+
+Although [[bugs/free_space_checking]] is not quite there --[[Joey]]
diff --git a/doc/todo/object_dir_reorg_v2/comment_1_ba03333dc76ff49eccaba375e68cb525._comment b/doc/todo/object_dir_reorg_v2/comment_1_ba03333dc76ff49eccaba375e68cb525._comment
new file mode 100644
index 000000000..261c2a51f
--- /dev/null
+++ b/doc/todo/object_dir_reorg_v2/comment_1_ba03333dc76ff49eccaba375e68cb525._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 1"
+ date="2011-03-16T01:16:48Z"
+ content="""
+If you support generic meta-data, keep in mind that you will need to do conflict resolution. Timestamps may not be synched across all systems, so keeping a log of old metadata could be used, sorting by history and using the latest. Which leaves the situation of two incompatible changes. This would probably mean manual conflict resolution. You will probably have thought of this already, but I still wanted to make sure this is recorded. -- RichiH
+"""]]
diff --git a/doc/todo/object_dir_reorg_v2/comment_2_81276ac309959dc741bc90101c213ab7._comment b/doc/todo/object_dir_reorg_v2/comment_2_81276ac309959dc741bc90101c213ab7._comment
new file mode 100644
index 000000000..9785f1989
--- /dev/null
+++ b/doc/todo/object_dir_reorg_v2/comment_2_81276ac309959dc741bc90101c213ab7._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 2"
+ date="2011-03-16T01:19:25Z"
+ content="""
+Hmm, I added quite a few comments at work, but they are stuck in moderation. Maybe I forgot to log in before adding them. I am surprised this one appeared immediately. -- RichiH
+"""]]
diff --git a/doc/todo/object_dir_reorg_v2/comment_3_79bdf9c51dec9f52372ce95b53233bb2._comment b/doc/todo/object_dir_reorg_v2/comment_3_79bdf9c51dec9f52372ce95b53233bb2._comment
new file mode 100644
index 000000000..886941be7
--- /dev/null
+++ b/doc/todo/object_dir_reorg_v2/comment_3_79bdf9c51dec9f52372ce95b53233bb2._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 1"
+ date="2011-03-15T14:08:41Z"
+ content="""
+What is the potential time-frame for this change? As I am not using git-annex for production yet, I can see myself waiting to avoid any potential hassle.
+
+Supporting generic metadata seems like a great idea. Though if you are going this path, wouldn't it make sense to avoid metastore for mtime etc and support this natively without outside dependencies?
+
+-- RichiH
+"""]]
diff --git a/doc/todo/object_dir_reorg_v2/comment_4_93aada9b1680fed56cc6f0f7c3aca5e5._comment b/doc/todo/object_dir_reorg_v2/comment_4_93aada9b1680fed56cc6f0f7c3aca5e5._comment
new file mode 100644
index 000000000..475359abb
--- /dev/null
+++ b/doc/todo/object_dir_reorg_v2/comment_4_93aada9b1680fed56cc6f0f7c3aca5e5._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 4"
+ date="2011-03-16T03:22:45Z"
+ content="""
+Well, I spent a few hours playing this evening in the 'reorg' branch in git. It seems to be shaping up pretty well; type-based refactoring in haskell makes these kind of big systematic changes a matter of editing until it compiles. And it compiles and test suite passes. But, so far I've only covered 1. 3. and 4. on the list, and have yet to deal with upgrades.
+
+I'd recommend you not wait before using git-annex. I am committed to provide upgradability between annexes created with all versions of git-annex, going forward. This is important because we can have offline archival drives that sit unused for years. Git-annex will upgrade a repository to current standard the first time it sees it, and I hope the upgrade will be pretty smooth. It was not bad for the annex.version 0 to 1 upgrade earlier. The only annoyance with upgrades is that it will result in some big commits to git, as every symlink in the repo gets changed, and log files get moved to new names.
+
+(The metadata being stored with keys is data that a particular backend can use, and is static to a given key, so there are no merge issues (and it won't be used to preserve mtimes, etc).)
+"""]]
diff --git a/doc/todo/object_dir_reorg_v2/comment_5_821c382987f105da72a50e0a5ce61fdc._comment b/doc/todo/object_dir_reorg_v2/comment_5_821c382987f105da72a50e0a5ce61fdc._comment
new file mode 100644
index 000000000..2032bce3c
--- /dev/null
+++ b/doc/todo/object_dir_reorg_v2/comment_5_821c382987f105da72a50e0a5ce61fdc._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 5"
+ date="2011-03-16T15:51:30Z"
+ content="""
+Hashing & segmenting seems to be around the corner, which is nice :)
+
+Is there a chance that you will optionally add mtime to your native metadata store? If yes, I'd rather wait for v2 to start with the native system from the start. If not, I will probably set it up tonight.
+
+PS: While posting from work, my comments are held for moderation once again. I am somewhat confused as to why this happens when I can just submit directly from home. And yes, I am using the same auth provider and user in both cases.
+"""]]
diff --git a/doc/todo/object_dir_reorg_v2/comment_6_8834c3a3f1258c4349d23aff8549bf35._comment b/doc/todo/object_dir_reorg_v2/comment_6_8834c3a3f1258c4349d23aff8549bf35._comment
new file mode 100644
index 000000000..ff86e3970
--- /dev/null
+++ b/doc/todo/object_dir_reorg_v2/comment_6_8834c3a3f1258c4349d23aff8549bf35._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 6"
+ date="2011-03-16T16:32:52Z"
+ content="""
+The mtime cannot be stored for all keys. Consider a SHA1 key. The mtime is irrelevant; 2 files with different mtimes, when added to the SHA1 backend, should get the same key.
+
+Probably our spam filter doesn't like your work IP.
+"""]]
diff --git a/doc/todo/object_dir_reorg_v2/comment_7_42501404c82ca07147e2cce0cff59474._comment b/doc/todo/object_dir_reorg_v2/comment_7_42501404c82ca07147e2cce0cff59474._comment
new file mode 100644
index 000000000..fc866c57a
--- /dev/null
+++ b/doc/todo/object_dir_reorg_v2/comment_7_42501404c82ca07147e2cce0cff59474._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 7"
+ date="2011-03-16T21:05:38Z"
+ content="""
+Ah, OK. I assumed the metadata would be attached to a key, not part of the key. This seems to make upgrades/extensions down the line harder than they need to be, but you are right that this way, merges are not, and never will be, an issue.
+
+Though with the SHA1 backend, changing files can be tracked. This means that tracking changes in mtime or other is possible. It also means that there are potential merge issues. But I won't argue the point endlessly. I can accept design decisions :)
+
+The prefix at work is from a university netblock so yes, it might be on a few hundred proxy lists etc.
+"""]]
diff --git a/doc/todo/optimise_git-annex_merge.mdwn b/doc/todo/optimise_git-annex_merge.mdwn
new file mode 100644
index 000000000..91d18ebd7
--- /dev/null
+++ b/doc/todo/optimise_git-annex_merge.mdwn
@@ -0,0 +1,23 @@
+Typically `git-annex merge` is fast, but it could still be sped up.
+
+`git-annex merge` runs `git-hash-object` once per file that needs to be
+merged. Elsewhere in git-annex, `git-hash-object` is used in a faster mode,
+reading files from disk via `--stdin-paths`. But here, the data is not
+in raw files on disk, and I doubt writing them is the best approach.
+Instead, I'd like a way to stream multiple objects into git using stdin.
+Sometime, should look at either extending git-hash-object to support that,
+or possibly look at using git-fast-import instead.
+
+---
+
+`git-annex merge` also runs `git show` once per file that needs to be
+merged. This could be reduced to a single call to `git-cat-file --batch`,
+There is already a Git.CatFile library that can do this easily. --[[Joey]]
+
+> This is now done, part above remains todo. --[[Joey]]
+
+---
+
+Merging used to use memory proportional to the size of the diff. It now
+streams data, running in constant space. This probably sped it up a lot,
+as there's much less allocation and GC action. --[[Joey]]
diff --git a/doc/todo/optinally_transfer_file_unencryptedly.mdwn b/doc/todo/optinally_transfer_file_unencryptedly.mdwn
new file mode 100644
index 000000000..ef27dc521
--- /dev/null
+++ b/doc/todo/optinally_transfer_file_unencryptedly.mdwn
@@ -0,0 +1,6 @@
+I have a git-annex repository on a NSLU 2, and transfers are much slower over ssh compared to unencrypted transfers (no wonder at that CPU speed). For the files that I am transferring, no encryption would be necessary. Unfortunately, ssh in Debian does not support "-c none" to disable encryption.
+
+It would be nice if git-annex would have a way of conveniently transferring files in another way than SSH. I’m not sure what a good way would be – maybe launching a one-shot HTTP-server on the sending end? Haskell libraries for that would be available... Of course it is not always the case that the host reachable with "ssh foo" is also reachable via TCP at "foo:1234"... And there are surely more problem. But still, it would be nice :-)
+
+> Setting `remote.name.annex-rsync-transport = rsh` will now
+> make rsync special remotes use rsh instead of ssh. [[done]]
diff --git a/doc/todo/optinally_transfer_file_unencryptedly/comment_1_4be47e7ac85d0f4e7029a96b615545a7._comment b/doc/todo/optinally_transfer_file_unencryptedly/comment_1_4be47e7ac85d0f4e7029a96b615545a7._comment
new file mode 100644
index 000000000..948845b23
--- /dev/null
+++ b/doc/todo/optinally_transfer_file_unencryptedly/comment_1_4be47e7ac85d0f4e7029a96b615545a7._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="guilhem"
+ ip="129.16.20.212"
+ subject="rsh?"
+ date="2013-04-09T16:11:50Z"
+ content="""
+I don't use it myself, but rsync can be used with others remote shells, among which rsh supports unencrypted streams. You probably want to set up a secure authorization mechanism to deny access to intruders, and for that kerberos comes to the rescue :-) I didn't try the combination, but it should work over git-annex already.
+"""]]
diff --git a/doc/todo/parallel_possibilities.mdwn b/doc/todo/parallel_possibilities.mdwn
new file mode 100644
index 000000000..9c0e69e29
--- /dev/null
+++ b/doc/todo/parallel_possibilities.mdwn
@@ -0,0 +1,13 @@
+One of my reasons for using haskell was that it provides the possibility of
+some parallell processing. Although since git-annex hits the filesystem
+heavily and mostly runs other git commands, maybe not a whole lot.
+
+Anyway, each git-annex command is broken down into a series of independant
+actions, which has some potential for parallelism.
+
+Each action has 3 distinct phases, basically "check", "perform", and
+"cleanup". The perform actions are probably parellizable; the cleanup may be
+(but not if it has to run git commands to stage state; it can queue
+commands though); the check should be easily parallelizable, although they
+may access the disk or run minor git query commands, so would probably not
+want to run too many of them at once.
diff --git a/doc/todo/parallel_possibilities/comment_1_d8e34fc2bc4e5cf761574608f970d496._comment b/doc/todo/parallel_possibilities/comment_1_d8e34fc2bc4e5cf761574608f970d496._comment
new file mode 100644
index 000000000..4aceb3abd
--- /dev/null
+++ b/doc/todo/parallel_possibilities/comment_1_d8e34fc2bc4e5cf761574608f970d496._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkptNW1PzrVjYlJWP_9e499uH0mjnBV6GQ"
+ nickname="Christian"
+ subject="comment 1"
+ date="2011-04-08T12:41:43Z"
+ content="""
+I also think, that fetching keys via rsync can be done by one rsync process, when the keys are fetched from one host. This would avoid establishing a new TCP connection for every file.
+"""]]
diff --git a/doc/todo/parallel_possibilities/comment_2_adb76f06a7997abe4559d3169a3181c3._comment b/doc/todo/parallel_possibilities/comment_2_adb76f06a7997abe4559d3169a3181c3._comment
new file mode 100644
index 000000000..6ecce52c4
--- /dev/null
+++ b/doc/todo/parallel_possibilities/comment_2_adb76f06a7997abe4559d3169a3181c3._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://ertai.myopenid.com/"
+ nickname="npouillard"
+ subject="comment 2"
+ date="2011-05-20T20:14:15Z"
+ content="""
+I agree with Christian.
+
+One should first make a better use of connections to remotes before exploring parallel possibilities. One should pipeline the requests and answers.
+
+Of course this could be implemented using parallel&concurrency features of Haskell to do this.
+"""]]
diff --git a/doc/todo/parallel_possibilities/comment_3_145fb974f45da99b7d4b117a3699cccf._comment b/doc/todo/parallel_possibilities/comment_3_145fb974f45da99b7d4b117a3699cccf._comment
new file mode 100644
index 000000000..a72a1456c
--- /dev/null
+++ b/doc/todo/parallel_possibilities/comment_3_145fb974f45da99b7d4b117a3699cccf._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.90"
+ subject="comment 3"
+ date="2013-07-17T19:59:50Z"
+ content="""
+Note that git-annex now uses locks to communicate amoung multiple processes, so it's now possible to eg run two `git annex get` processes, and one will skip over the file the other is downloading and go on to the next file, and so on.
+
+This is an especially nice speedup when downloading encrypted data, since the decryption of one file will tend to happen while the other process is downloading the next file (assuming files of approximately the same size, and that decryption takes approxiately as long as downloading).
+
+The only thing preventing this being done by threads in one process, enabled by a -jN option, is that the output would be a jumbled mess.
+"""]]
diff --git a/doc/todo/pushpull.mdwn b/doc/todo/pushpull.mdwn
new file mode 100644
index 000000000..6828b35b2
--- /dev/null
+++ b/doc/todo/pushpull.mdwn
@@ -0,0 +1,4 @@
+--push/--pull should take a reponame and files, and push those files
+ to that repo; dropping them from the current repo
+
+[[done]] (move --from/--to)
diff --git a/doc/todo/quvi_0.9_support.mdwn b/doc/todo/quvi_0.9_support.mdwn
new file mode 100644
index 000000000..36280452a
--- /dev/null
+++ b/doc/todo/quvi_0.9_support.mdwn
@@ -0,0 +1,8 @@
+quvi 0.9 has a completely different interface; git-annex needs to be made
+to detect and use it.
+
+I have already fixed the worst problem, which caused git-annex addurl to
+think that every url was a valid quvi url. --[[Joey]]
+
+> [[done]], 0.9 is supported, although the version is detected at build
+> time. --[[Joey]]
diff --git a/doc/todo/redundancy_stats_in_status.mdwn b/doc/todo/redundancy_stats_in_status.mdwn
new file mode 100644
index 000000000..56095fd33
--- /dev/null
+++ b/doc/todo/redundancy_stats_in_status.mdwn
@@ -0,0 +1,23 @@
+Currently, `git annex status` only shows the size of 1 copy of each file.
+If numcopies is being used for redundancy, much more disk can actually be
+in use than status shows.
+
+One idea:
+
+ known annex size: 2 terabytes (plus 4 terabytes of redundant copies)
+
+But, to get that number, it would have to walk every location log,
+counting how many copies currently exist of each file. That would make
+status a lot slower than it is.
+
+One option is to just put it at the end of the status:
+
+ redundancy: 300% (4 terabytes of copies)
+
+And ctrl-c if it's taking too long.
+
+Hmm, fsck looks at that same info. Maybe it could cache the redundancy
+level it discovers? Since fsck can be run incrementally, it would be tricky
+to get an overall number. And the number would tend to be stale, but
+then again it might also be nice if status shows how long ago the last fsck
+was.
diff --git a/doc/todo/redundancy_stats_in_status/comment_1_9f1c10f8cea4fa60a99cbcc8306dd5de._comment b/doc/todo/redundancy_stats_in_status/comment_1_9f1c10f8cea4fa60a99cbcc8306dd5de._comment
new file mode 100644
index 000000000..801c1da03
--- /dev/null
+++ b/doc/todo/redundancy_stats_in_status/comment_1_9f1c10f8cea4fa60a99cbcc8306dd5de._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 1"
+ date="2012-10-30T08:09:13Z"
+ content="""
+I like the idea of using fsck as a pre-run for status.
+
+Basically, it's the same as `updatedb` and `locate`; locate will warn the user if it considers its cache to be too old, as well.
+"""]]
diff --git a/doc/todo/redundancy_stats_in_status/comment_2_686ced0684d10511caf07953c64cd5b6._comment b/doc/todo/redundancy_stats_in_status/comment_2_686ced0684d10511caf07953c64cd5b6._comment
new file mode 100644
index 000000000..a4711b2a3
--- /dev/null
+++ b/doc/todo/redundancy_stats_in_status/comment_2_686ced0684d10511caf07953c64cd5b6._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.220"
+ subject="comment 2"
+ date="2013-09-25T18:03:55Z"
+ content="""
+`git annex status .` or otherwise running it with a directory has recently started walking all the location logs for all files in the directory in order to display variance from configured numcopies. It would be easy to add a redundancy counter to that.
+
+It would slow down the global status when not passed a directory to add redundancy info there. Maybe local is enough?
+"""]]
diff --git a/doc/todo/resuming_encrypted_uploads.mdwn b/doc/todo/resuming_encrypted_uploads.mdwn
new file mode 100644
index 000000000..b3aaa7f96
--- /dev/null
+++ b/doc/todo/resuming_encrypted_uploads.mdwn
@@ -0,0 +1,22 @@
+Resuming interrupted uploads to encrypted special remotes is not currently
+possible, because gpg does not produce consistent output. Special remotes
+that could support resuming include rsync and glacier.
+
+Without consistent output, git-annex would need to locally cache the encrypted
+file, and reuse that cache when resuming an upload. This would make
+encrypted uploads more expensive in terms of both file IO and disk space
+used.
+
+[It would be possible to write to the cache at the same time the special
+remote is being fed data, and if the special remote upload fails, continue
+writing the rest of the file. That would avoid half the overhead, since
+the file would not need to be read from, just written to. (Although OS
+caching may accomplish the same thing.)]
+
+Also, `git annex unused` would need to show temp files for uploads,
+the same as it currently shows temp files for downloads, and users would
+sometimes need to manually dropunused old uploads, that never completed.
+
+The question, then, is whether resuming uploads is useful enough to add
+this overhead and user-visible complexity.
+--[[Joey]]
diff --git a/doc/todo/resuming_encrypted_uploads/comment_1_1832a6fb78e8ad7c838582f46731ac3b._comment b/doc/todo/resuming_encrypted_uploads/comment_1_1832a6fb78e8ad7c838582f46731ac3b._comment
new file mode 100644
index 000000000..cf35de049
--- /dev/null
+++ b/doc/todo/resuming_encrypted_uploads/comment_1_1832a6fb78e8ad7c838582f46731ac3b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://phil.0x539.de/"
+ nickname="Philipp Kern"
+ subject="comment 1"
+ date="2012-12-28T23:23:29Z"
+ content="""
+Doesn't the encryption part already write an encrypted version completely to disk before starting to upload? (At least with the rsync remote?) So the disk space and I/O usage is already there. (Except that it's probably a temporary file that's deleted after it was created, so that it's not kept around by the filesystem when certain destructive events strike.)
+"""]]
diff --git a/doc/todo/resuming_encrypted_uploads/comment_2_2ecc8e782f49e90ed1549e9179eb1a1e._comment b/doc/todo/resuming_encrypted_uploads/comment_2_2ecc8e782f49e90ed1549e9179eb1a1e._comment
new file mode 100644
index 000000000..a2bab9244
--- /dev/null
+++ b/doc/todo/resuming_encrypted_uploads/comment_2_2ecc8e782f49e90ed1549e9179eb1a1e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawln3ckqKx0x_xDZMYwa9Q1bn4I06oWjkog"
+ nickname="Michael"
+ subject="comment 2"
+ date="2012-12-29T08:00:56Z"
+ content="""
+Being able to resume transfers of encrypted files would absolutely be useful! Disk space is cheap, but bandwidth is not.
+"""]]
diff --git a/doc/todo/rsync.mdwn b/doc/todo/rsync.mdwn
new file mode 100644
index 000000000..3353f19c4
--- /dev/null
+++ b/doc/todo/rsync.mdwn
@@ -0,0 +1,4 @@
+Transferring a file from a ssh:// remote should use rsync to allow resuming
+of a prior transfer.
+
+[[done]]
diff --git a/doc/todo/smudge.mdwn b/doc/todo/smudge.mdwn
new file mode 100644
index 000000000..6103ffa61
--- /dev/null
+++ b/doc/todo/smudge.mdwn
@@ -0,0 +1,162 @@
+git-annex should use smudge/clean filters.
+
+----
+
+Update: Currently, this does not look likely to work. In particular,
+the clean filter needs to consume all stdin from git, which consists of the
+entire content of the file. It cannot optimise by directly accessing
+the file in the repository, because git may be cleaning a different
+version of the file during a merge.
+
+So every `git status` would need to read the entire content of all
+available files, and checksum them, which is too expensive.
+
+> Update from GitTogether: Peff thinks a new interface could be added to
+> git to handle this sort of case in an efficient way.. just needs someone
+> to do the work. --[[Joey]]
+
+----
+
+The clean filter is run when files are staged for commit. So a user could copy
+any file into the annex, git add it, and git-annex's clean filter causes
+the file's key to be staged, while its value is added to the annex.
+
+The smudge filter is run when files are checked out. Since git annex
+repos have partial content, this would not git annex get the file content.
+Instead, if the content is not currently available, it would need to do
+something like return empty file content. (Sadly, it cannot create a
+symlink, as git still wants to write the file afterwards.)
+
+So the nice current behavior of unavailable files being clearly missing due
+to dangling symlinks, would be lost when using smudge/clean filters.
+(Contact git developers to get an interface to do this?)
+
+Instead, we get the nice behavior of not having to remeber to `git annex
+add` files, and just being able to use `git add` or `git commit -a`,
+and have it use git-annex when .gitattributes says to. Also, annexed
+files can be directly modified without having to `git annex unlock`.
+
+### design
+
+In .gitattributes, the user would put something like "* filter=git-annex".
+This way they could control which files are annexed vs added normally.
+
+(git-annex could have further controls to allow eg, passing small files
+through to regular processing. At least .gitattributes is a special case,
+it should never be annexed...)
+
+For files not configured this way, git-annex could continue to use
+its symlink method -- this would preserve backwards compatability,
+and even allow mixing the two methods in a repo as desired.
+
+To find files in the repository that are annexed, git-annex would do
+`ls-files` as now, but would check if found files have the appropriate
+filter, rather than the current symlink checks. To determine the key
+of a file, rather than reading its symlink, git-annex would need to
+look up the git blob associated with the file -- this can be done
+efficiently using the existing code in `Branch.catFile`.
+
+The clean filter would inject the file's content into the annex, and hard
+link from the annex to the file. Avoiding duplication of data.
+
+The smudge filter can't do that, so to avoid duplication of data, it
+might always create an empty file. To get the content, `git annex get`
+could be used (which would hard link it). A `post-checkout` hook might
+be used to set up hard links for all currently available content.
+
+#### clean
+
+The trick is doing it efficiently. Since git a2b665d, v1.7.4.1,
+something like this works to provide a filename to the clean script:
+
+ git config --global filter.huge.clean huge-clean %f
+
+This could avoid it needing to read all the current file content from stdin
+when doing eg, a git status or git commit. Instead it is passed the
+filename that git is operating on, in the working directory.
+(Update: No, doesn't work; git may be cleaning a different file content
+than is currently on disk, and git requires all stdin be consumed too.)
+
+So, WORM could just look at that file and easily tell if it is one
+it already knows (same mtime and size). If so, it can short-circuit and
+do nothing, file content is already cached.
+
+SHA1 has a harder job. Would not want to re-sha1 the file every time,
+probably. So it'd need a local cache of file stat info, mapped to known
+objects.
+
+But: Even with %f, git actually passes the full file content to the clean
+filter, and if it fails to consume it all, it will crash (may only happen
+if the file is larger than some chunk size; tried with 500 mb file and
+saw a SIGPIPE.) This means unnecessary works needs to be done,
+and it slows down *everything*, from `git status` to `git commit`.
+**showstopper** I have sent a patch to the git mailing list to address
+this. <http://marc.info/?l=git&m=131465033512157&w=2> (Update: apparently
+can't be fixed.)
+
+#### smudge
+
+The smudge script can also be provided a filename with %f, but it
+cannot directly write to the file or git gets unhappy.
+
+### dealing with partial content availability
+
+The smudge filter cannot be allowed to fail, that leaves the tree and
+index in a weird state. So if a file's content is requested by calling
+the smudge filter, the trick is to instead provide dummy content,
+indicating it is not available (and perhaps saying to run "git-annex get").
+
+Then, in the clean filter, it has to detect that it's cleaning a file
+with that dummy content, and make sure to provide the same identifier as
+it would if the file content was there.
+
+I've a demo implementation of this technique in the scripts below.
+
+----
+
+### test files
+
+huge-smudge:
+
+<pre>
+#!/bin/sh
+read f
+file="$1"
+echo "smudging $f" >&2
+if [ -e ~/$f ]; then
+ cat ~/$f # possibly expensive copy here
+else
+ echo "$f not available"
+fi
+</pre>
+
+huge-clean:
+
+<pre>
+#!/bin/sh
+file="$1"
+cat >/tmp/file
+# in real life, this should be done more efficiently, not trying to read
+# the whole file content!
+if grep -q 'not available' /tmp/file; then
+ awk '{print $1}' /tmp/file # provide what we would if the content were avail!
+ exit 0
+fi
+echo "cleaning $file" >&2
+# XXX store file content here
+echo $file
+</pre>
+
+.gitattributes:
+
+<pre>
+*.huge filter=huge
+</pre>
+
+in .git/config:
+
+<pre>
+[filter "huge"]
+ clean = huge-clean %f
+ smudge = huge-smudge %f
+<pre>
diff --git a/doc/todo/smudge/comment_1_4ea616bcdbc9e9a6fae9f2e2795c31c9._comment b/doc/todo/smudge/comment_1_4ea616bcdbc9e9a6fae9f2e2795c31c9._comment
new file mode 100644
index 000000000..a4eb3cf23
--- /dev/null
+++ b/doc/todo/smudge/comment_1_4ea616bcdbc9e9a6fae9f2e2795c31c9._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://christian.amsuess.com/chrysn"
+ nickname="chrysn"
+ subject="git-add instead of git-annex-add"
+ date="2011-02-26T21:43:21Z"
+ content="""
+would, with these modifications in place, there still be a way to *really* git-add a file? (my main repository contains both normal git and git-annex files.)
+"""]]
diff --git a/doc/todo/smudge/comment_2_e04b32caa0d2b4c577cdaf382a3ff7f6._comment b/doc/todo/smudge/comment_2_e04b32caa0d2b4c577cdaf382a3ff7f6._comment
new file mode 100644
index 000000000..3a223e1c7
--- /dev/null
+++ b/doc/todo/smudge/comment_2_e04b32caa0d2b4c577cdaf382a3ff7f6._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://dieter-be.myopenid.com/"
+ nickname="dieter"
+ subject="symlinks"
+ date="2011-04-03T20:30:21Z"
+ content="""
+> (Sadly, it cannot create a symlink, as git still wants to write the file afterwards.
+> So the nice current behavior of unavailable files being clearly missing due to dangling symlinks, would be lost when using smudge/clean filters. (Contact git developers to get an interface to do this?)
+
+Have you checked what the smudge filter sees when the input is a symlink? Because git supports tracking symlinks, so it should also support pushing symlinks through a smudge filter, right?
+Either way: yes, contact the git devs, one can only ask and hope. And if you can demonstrate the awesomeness of git-annex they might get more 1interested :)
+"""]]
diff --git a/doc/todo/smudge/comment_3_4e7c25fe24a1e71f58a8354fa64f41c2._comment b/doc/todo/smudge/comment_3_4e7c25fe24a1e71f58a8354fa64f41c2._comment
new file mode 100644
index 000000000..cd64b7001
--- /dev/null
+++ b/doc/todo/smudge/comment_3_4e7c25fe24a1e71f58a8354fa64f41c2._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawn1QhtPvsRBV7pfaDW_ZTPFv_ZIxSzQ8Rg"
+ nickname="Paul Léo"
+ subject="comment 3"
+ date="2013-11-13T20:41:52Z"
+ content="""
+> SHA1 has a harder job. Would not want to re-sha1 the file every time, probably. So it'd need a local cache of file stat info, mapped to known objects.
+
+I think that is not true? If gits wants the file to be cleaned, it thinks that the file was changed. So you would have to SHA1 it anyway if you don't want rely on WORM (which git already does in the first step anyway).
+"""]]
diff --git a/doc/todo/special_remote_for_amazon_glacier.mdwn b/doc/todo/special_remote_for_amazon_glacier.mdwn
new file mode 100644
index 000000000..9b8b9d74e
--- /dev/null
+++ b/doc/todo/special_remote_for_amazon_glacier.mdwn
@@ -0,0 +1,30 @@
+Amazon's new glacier service would be a nice special remote to support for
+long-term archival.
+
+The main difficulty is that glacier is organized into vaults, and accessing
+a file in a vault takes ~4 hours. A naive implementation would make `git
+annex get` wait for 4 hours, which is certainly not reasonable.
+
+One approach I am pondering is to make each glacier vault a separate
+special remote. You could then request git-annex to spin up a remote, and
+come back later, and be able to access the data stored in it (need to check
+if glacier would also allow adding new data to it then). This is
+conceptually similar to using git-annex with offline removable drives,
+except with glacier, you have a controllable robot to get them plugged in. :)
+
+Ideally, git-annex would arrange for glacier to send it a message when the
+vault becomes available, and the user could queue a list of commands to
+run, or files to transfer, at that point.
+
+--[[Joey]]
+
+> [[done]]! --[[Joey]]
+
+-----
+
+> In the coming months, Amazon S3 will introduce an option that will allow customers to seamlessly move data between Amazon S3 and Amazon Glacier based on data lifecycle policies.
+
+-- <http://aws.amazon.com/glacier/faqs/#How_should_I_choose_between_Amazon_Glacier_and_Amazon_S3>
+
+>> They did, but it's IMHO not very useful for git-annex. It's rather
+>> intended to allow aging S3 storage out to Glacier. --[[Joey]]
diff --git a/doc/todo/special_remote_for_amazon_glacier/comment_1_68f129441eefcbfebf7a9db680f52759._comment b/doc/todo/special_remote_for_amazon_glacier/comment_1_68f129441eefcbfebf7a9db680f52759._comment
new file mode 100644
index 000000000..68593be42
--- /dev/null
+++ b/doc/todo/special_remote_for_amazon_glacier/comment_1_68f129441eefcbfebf7a9db680f52759._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://mike.magin.org/"
+ nickname="mmagin"
+ subject="comment 1"
+ date="2012-09-14T04:19:53Z"
+ content="""
+When I first heard about Glacier, it sounded great for a cheap backup copy, and I was thinking about writing a \"hook\" remote, but once I read some better analysis of the pricing (e.g. [[http://www.daemonology.net/blog/2012-09-04-thoughts-on-glacier-pricing.html]]) I rapidly lost interest.
+"""]]
diff --git a/doc/todo/special_remote_for_amazon_glacier/comment_2_c5eeaf8ceee414fa0379831ca52e290c._comment b/doc/todo/special_remote_for_amazon_glacier/comment_2_c5eeaf8ceee414fa0379831ca52e290c._comment
new file mode 100644
index 000000000..701047f91
--- /dev/null
+++ b/doc/todo/special_remote_for_amazon_glacier/comment_2_c5eeaf8ceee414fa0379831ca52e290c._comment
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="basak"
+ subject="comment 2"
+ date="2012-09-21T22:21:04Z"
+ content="""
+I've created a glacier command line interface that integrates with git-annex [here](https://github.com/basak/glacier-cli), currently using the hook special remote mechanism. To get around the time delay, operations which require a job submission will submit the job and then fail. Retrying again four hours later should then succeed. It seems to work pretty well with git-annex.
+"""]]
diff --git a/doc/todo/speed_up_fsck.mdwn b/doc/todo/speed_up_fsck.mdwn
new file mode 100644
index 000000000..5d5e867f8
--- /dev/null
+++ b/doc/todo/speed_up_fsck.mdwn
@@ -0,0 +1,40 @@
+moving to the git-annex branch has slowed down fsck worse than most
+commands. Actually, some commands have sped up, while others like get
+are slightly slower but are swamped by the normal runtime.
+
+For fsck though, it has to pull each file's location log info out of git.
+And, it's typically run on the entire tree.
+
+Another slow one in `git annex copy --from`.
+
+It would be possible to run a single `git cat-file --batch` and pass it
+sha1s of location logs for file that is going to be fsked (gotten via
+`read-tree`). Then just read its output until the next requested sha1 to
+chunk it, and pass this in to fsck in a closure.
+
+The difficulty, besides writing that is that everything that works with
+location logs now reads them out of git, would need to find a way to
+provide the info on a side channel of some sort.
+
+If this is implemented, the same infrastructure could be used for other
+commands like whereis and add. --[[Joey]]
+
+> Updated plan:
+>
+> Run `git ls-file --batch`, and cache its stdin and out handles in Branch
+> state.
+>
+> To see a git-annex branch file, send it something like
+> "git-annex:uuid.log", and read the content fron stdout handle.
+>
+> To detect the end of content, send "TOKEN\n", and look for
+> "TOKEN missing" in its output. A good choice for TOKEN is anything
+> that will never exist in the repo; 40 0's would be a fairly good choice,
+> but even better seems to be something completely invalid and impossible
+> to have as a sha1 or filename or ref: "".
+>
+> Hmm, except that's actually an error message sent to stderr. Unless
+> stderr is connected to stdout, it might be better to look for a known,
+> empty object. Could just add a git-annex:empty file to that end.
+
+[[done]] --[[Joey]]
diff --git a/doc/todo/stream_feature__63__.mdwn b/doc/todo/stream_feature__63__.mdwn
new file mode 100644
index 000000000..860edfc81
--- /dev/null
+++ b/doc/todo/stream_feature__63__.mdwn
@@ -0,0 +1,23 @@
+I am just asking myself, is it stupid to think that streaming in git annex would be a good idea and wouldnt it be totaly easy to implement?
+
+Ok just tried to link to files over ssh, it creates a link but you cant open with it its content ^^
+
+But at least the files you have access over some filesystem as example samba/sshfs or just a other directory or usb-drive you could stream instead of "get"
+
+you could add another mode like direct and indirect, like symbolic-links or something like that?
+
+Sadly linux is to stupid to allow direct ssh links ( thats maybe one of the biggest features hurd has over linux ) but you could mount with sshfs readonly (checking first if sshfs is installed) to mount the files there and then map the links there.
+
+ok I am not so shure how hard it would be and how much bug potentials it creates, but it would be great I guess.
+
+git annex is a bit like a telephone book, where you get a list of where the targets are. So using it to call the persons so that they drive to you to talk with you is nice. But I think the better feature would be if you just talk with the guy over the telephone directly bevore he comes to you (streaming)
+
+I mean you did one great thing, you did make cloudy thing peer to peer, like git is targeted too but for smaller files, yes there are may use cases without this feature, but I would be really glad if it could do that too, if I give annex 5 locations on other pcs usb-sticks etc, I find it stupid to additionaly do setup all this sources again a second time for streaming, and then I have maybe even 2 different file names because you map stuff in git.
+
+So sorry its late here, I am a bit tired so I maybe dont know what I am talking right now, my english isnt the best, too, but I think it would be a great feature.
+
+I mean on your setup, with slow internet, you maybe always make a get command, but here, if I link to youtube, I have no problem to stream it, or even on internal network between my pcs I have gb-lan, I start directly movies streaming, I would only use get, in rare cases where I need them on a train, the normal thing is to stream stuff.
+
+So I have to go sleep now
+
+bye
diff --git a/doc/todo/support-non-utf8-locales.mdwn b/doc/todo/support-non-utf8-locales.mdwn
new file mode 100644
index 000000000..da40118d5
--- /dev/null
+++ b/doc/todo/support-non-utf8-locales.mdwn
@@ -0,0 +1,26 @@
+Currenty, git-annex forces output, particularly of filenames, in a utf-8
+locale.
+
+Note that this does not mean it cannot be used with filenames in other
+encodings. git-annex is entirely encoding agnostic when it comes to
+manipulating filenames. It just *displays* their names always converted to
+utf-8, which may not look right when you have a non-utf8 locale.
+
+This had to be done to work around some bugs with haskell's handling
+of filename encodings. In particular,
+
+* [[bugs/unhappy_without_UTF8_locale]]: haskell crashes when told to output
+ a string with characters > 255 in a non-utf8 locale.
+* [[bugs/problems_with_utf8_names]]: On many OSs, haskell expects
+ non-decoded raw char8 in FilePaths. In order to display a filename,
+ though, it needs to first be decoded, and git-annex currently assumes
+ it was encoded as utf8.
+
+git-annex's behavior is unlikely to improve much until haskell's
+support for utf8 filenames improves. --[[Joey]]
+
+> [[done]] -- I just turned off all encoding handling on stdout and stderr,
+> which avoids these problems nicely. Git-annex now displays just what it
+> input, at least on platforms where haskell does not decode unicode in
+> FilePaths. This will later be a problem when it gets localized, but for
+> now works great. --[[Joey]]
diff --git a/doc/todo/support_S3_multipart_uploads.mdwn b/doc/todo/support_S3_multipart_uploads.mdwn
new file mode 100644
index 000000000..711ac41b2
--- /dev/null
+++ b/doc/todo/support_S3_multipart_uploads.mdwn
@@ -0,0 +1,14 @@
+Did not know of this when I wrote S3 support. Ability to resume large
+uploads would be good.
+
+<http://aws.typepad.com/aws/2010/11/amazon-s3-multipart-upload.html>
+
+Also allows supporting files > 5 gb, a S3 limit I was not aware of.
+
+NB: It would work just as well to split the object and upload the N parts
+to S3, but not bother with S3's paperwork to rejoin them into one object.
+Only reasons not to do that are a) backwards compatability with
+the existing S3 remote and b) this would not allow accessing the content
+in S3 w/o using git-annex, which could be useful in some scenarios.
+
+--[[Joey]]
diff --git a/doc/todo/support_for_lossy_remotes.mdwn b/doc/todo/support_for_lossy_remotes.mdwn
new file mode 100644
index 000000000..23083b2d7
--- /dev/null
+++ b/doc/todo/support_for_lossy_remotes.mdwn
@@ -0,0 +1,11 @@
+I'm curious if there's a possibility to support lossy remotes. It may be handy to support syncing to special remotes that do lossy compression on the files (e.g., videos and images). For example, one could imagine having a YouTube special remote that only syncs video files. The original files wouldn't be available for download due to the transcoding and compression that YouTube does, so they wouldn't count towards the number of copies. In this YouTube example, the user gains:
+
+1. an online place that their videos are available from
+2. a worst-case scenario "backup"
+3. a remote that they could download smaller video files
+
+> [[done]]; lossy remotes are supported as seen with `git annex addurl
+> --fast` and also with the new addurl support for using quvi to get
+> videos fro youtube. Just make a key with a URL or something in it, and
+> no size or checksum, and any content will be assumed to be the right
+> content. --[[Joey]]
diff --git a/doc/todo/support_for_lossy_remotes/comment_1_f5cd9f9deab13ab2d2290ad763906dd3._comment b/doc/todo/support_for_lossy_remotes/comment_1_f5cd9f9deab13ab2d2290ad763906dd3._comment
new file mode 100644
index 000000000..1e895944c
--- /dev/null
+++ b/doc/todo/support_for_lossy_remotes/comment_1_f5cd9f9deab13ab2d2290ad763906dd3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.90"
+ subject="comment 1"
+ date="2013-07-16T19:16:54Z"
+ content="""
+There is already one example of a lossy remote: If you use `git annex addurl --relaxed` it generates a key that just uses the url, without its size. When retreiving such a key, any content will be accepted.
+"""]]
diff --git a/doc/todo/support_for_writing_external_special_remotes.mdwn b/doc/todo/support_for_writing_external_special_remotes.mdwn
new file mode 100644
index 000000000..2d7cd9d15
--- /dev/null
+++ b/doc/todo/support_for_writing_external_special_remotes.mdwn
@@ -0,0 +1,25 @@
+It would be good to have something in between the hook special remote and
+the built-in special remotes. The hook is easy to set up, but its simple
+interface misses some features that a more full-features interface could
+provide to a third-party program that wants to provide the best possible
+special remote it can w/o being written in haskell:
+
+* No way to send progress updates when uploading, so no progress bars for uploads from hook special remotes in the webapp.
+* No way to verify the `initremote` parameters include all needed configuration, and do any initalization needed.
+* No way to query and/or set the remote.log while it's running. (Well, technically, `git annex enableremote` can set values..)
+* No way to store per-key information to the git-annex branch.
+* No (easy) way to split files into chunks.
+
+Some of these features could be added to git-annex as subcommands. Which would
+improve the general programmability and flexability of git-annex. OTOH,
+running `git-annex upload-progress` repeatedly is pretty ugly. Or the
+interface could provide a channel for the program and git-annex to
+communicate back and forth on. Maybe a mix of the two?
+
+A final feature such an interface should provide is the ability to drop a
+program into PATH and have it just work, without the user needing to do any
+configuration beyond `initremote`. So, `git annex initremote foo type=$bar`
+should look for `git-annex-remote-$bar` in PATH if that's not a built-in
+special remote name.
+
+--[[Joey]]
diff --git a/doc/todo/support_fsck_in_bare_repos.mdwn b/doc/todo/support_fsck_in_bare_repos.mdwn
new file mode 100644
index 000000000..32ced467e
--- /dev/null
+++ b/doc/todo/support_fsck_in_bare_repos.mdwn
@@ -0,0 +1,17 @@
+What is says on the tin:
+
+ 22:56:54 < RichiH> joeyh_: by the way, i have been thinking about fsck on bare repos
+ 22:57:37 < RichiH> joeyh_: the best i could come with is to have a bare and a non-bare access the same repo store
+ 22:58:00 < RichiH> joeyh_: alternatively, with the SHA* backend, you have all the information to verify that the local data is correct
+ 22:58:41 < RichiH> and verifying that would already be a plus. if there really _is_ a problem, having the SHA is enough to track issues down
+ 23:09:50 < joeyh_> oh, I think I have code that fsck could use on bare repos already.. just a matter of wiring it up
+ 23:10:42 < joeyh_> feel free to reopen a bug or whatever so I remember.. the unused command's branch content enumeration could be used in a bare repo
+ 23:14:51 < joeyh_> unused/dropunused could work in bare repos too btw
+
+> Also `status`'s total annex keys/size could be handled for bare repos. --[[Joey]]
+
+>> Fsck is done. Rest not done yet. --[[Joey]]
+
+>>> all [[done]]! --[[Joey]]
+
+[[!meta title="support unused, dropunused in bare repos"]]
diff --git a/doc/todo/symlink_farming_commit_hook.mdwn b/doc/todo/symlink_farming_commit_hook.mdwn
new file mode 100644
index 000000000..3e93cb34b
--- /dev/null
+++ b/doc/todo/symlink_farming_commit_hook.mdwn
@@ -0,0 +1,14 @@
+TODO: implement below
+
+git-annex does use a lot of symlinks. Specicially, relative symlinks,
+that are checked into git. To allow you to move those around without
+annoyance, git-annex can run as a post-commit hook. This way, you can `git mv`
+a symlink to an annexed file, and as soon as you commit, it will be fixed
+up.
+
+`git annex init` tries to set up a post-commit hook that is itself a symlink
+back to git-annex. If you want to have your own shell script in the post-commit
+hook, just make it call `git annex` with no parameters. git-annex will detect
+when it's run from a git hook and do the necessary fixups.
+
+[[done]]
diff --git a/doc/todo/sync_my_local_git-annex_from_a_dump_remote.mdwn b/doc/todo/sync_my_local_git-annex_from_a_dump_remote.mdwn
new file mode 100644
index 000000000..524782bc7
--- /dev/null
+++ b/doc/todo/sync_my_local_git-annex_from_a_dump_remote.mdwn
@@ -0,0 +1,6 @@
+As discussed on debconf, I have the following use case:
+
+* I have a dump remote, a folder on my webserver where files are uploaded through the web app. I don't have git on the webserver, just a plain folder.
+* I have git-annex repo on a development server. The development server polls the webserver (ssh/ftp) once in an hour and synchronizes the state of the local git-annex repo with the state found on the webserver and commits that.
+* This is not meant to be backup facility. I just want to be able to have a state on my development machine that is very likely to the state on the webserver.
+
diff --git a/doc/todo/sync_my_local_git-annex_from_a_dump_remote/comment_1_81d63854f89f00855cda5ace0fc8262a._comment b/doc/todo/sync_my_local_git-annex_from_a_dump_remote/comment_1_81d63854f89f00855cda5ace0fc8262a._comment
new file mode 100644
index 000000000..d9abb3a3c
--- /dev/null
+++ b/doc/todo/sync_my_local_git-annex_from_a_dump_remote/comment_1_81d63854f89f00855cda5ace0fc8262a._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 1"
+ date="2013-08-13T21:44:17Z"
+ content="""
+We had a conversation about this IRL. At the time, I thought I understood what you wanted. Reading the above, I am not so sure.
+
+What I thought you wanted was something like `git annex mirror --from remote`, which would, for each object known to git-annex that the location log said was present on the remote, make sure that the local repo had the object too, and for each object that the location log said was not present on the remote, drop it from the local repo (if numcopies etc allowed).
+
+`git annex mirror --to remote` could also be used as the complement of the above.
+
+If that's not the sort of thing you meant, let me know.
+"""]]
diff --git a/doc/todo/sync_my_local_git-annex_from_a_dump_remote/comment_2_66822b72b1450e79e8edd0c6c21d5aa6._comment b/doc/todo/sync_my_local_git-annex_from_a_dump_remote/comment_2_66822b72b1450e79e8edd0c6c21d5aa6._comment
new file mode 100644
index 000000000..3d459371f
--- /dev/null
+++ b/doc/todo/sync_my_local_git-annex_from_a_dump_remote/comment_2_66822b72b1450e79e8edd0c6c21d5aa6._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://thkoch2001.myopenid.com/"
+ nickname="thkoch"
+ subject="pseudocode"
+ date="2013-08-14T04:58:22Z"
+ content="""
+lets say my local annex is in direct mode, then the following might already do what I want:
+
+cd $LOCAL_ANNEX
+rsync --recursive --delete $REMOTE .
+git annex add && git commit
+
+It would however be nice if I could do the same with an annex in indirect mode or even a bare annex.
+"""]]
diff --git a/doc/todo/sync_my_local_git-annex_from_a_dump_remote/comment_3_b9f73375e2c732e798495f8ee6970c7c._comment b/doc/todo/sync_my_local_git-annex_from_a_dump_remote/comment_3_b9f73375e2c732e798495f8ee6970c7c._comment
new file mode 100644
index 000000000..df4be033b
--- /dev/null
+++ b/doc/todo/sync_my_local_git-annex_from_a_dump_remote/comment_3_b9f73375e2c732e798495f8ee6970c7c._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 3"
+ date="2013-08-24T16:35:33Z"
+ content="""
+Seems to me that this could easily be dealt with by installing git-annex on the webserver, making the directory there a git repository, and using either a cron job or `git annex watch` to commit files as they were changed there.
+
+Then you can make a direct mode, indirect mode, or even a bare clone on your local machine and use git-annex to get the files.
+
+Maybe you have good reasons for not wanting to go that route. And rsync on a direct mode repository should work, provided to tell it to not delete `.git`. :P I don't see any way to make rsync work in an indirect mode repository. As for trying to make git-annex handle this import over rsync itself in a way that would work in an indirect mode repository, let alone a bare repository -- I don't see a good way to do it and it seems quite special case and likely to get quite complicated to implement.
+
+In the meantime, I did implement `git annex mirror`, which I think is a much more interesting and generally useful tool to have. And could even be used in my recommended solution above.
+"""]]
diff --git a/doc/todo/tahoe_lfs_for_reals.mdwn b/doc/todo/tahoe_lfs_for_reals.mdwn
new file mode 100644
index 000000000..9019767eb
--- /dev/null
+++ b/doc/todo/tahoe_lfs_for_reals.mdwn
@@ -0,0 +1,21 @@
+[[forum/tips:_special__95__remotes__47__hook_with_tahoe-lafs]] is a good
+start, but Zooko points out that using Tahoe's directory translation layer
+incurs O(N^2) overhead as the number of objects grows. Also, making
+hash subdirectories in Tahoe is expensive. Instead it would be good to use
+it as a key/value store directly. The catch is that doing so involves
+sending the content to Tahoe, and getting back a key identifier.
+
+This would be fairly easy to do as a [[backend|backends]], which can assign its
+own key names (although typically done before data is stored in it),
+but a tahoe-lafs special remote would be more flexible.
+
+To support a special remote, a mapping is needed from git-annex keys to
+Tahoe keys.
+
+The best place to store this mapping is perhaps as a new field in the
+location log:
+
+ date present repo-uuid newfields
+
+This way, each remote can store its own key-specfic data in the same place
+as other key-specific data, with minimal overhead.
diff --git a/doc/todo/tahoe_lfs_for_reals/comment_1_0a4793ce6a867638f6e510e71dd4bb44._comment b/doc/todo/tahoe_lfs_for_reals/comment_1_0a4793ce6a867638f6e510e71dd4bb44._comment
new file mode 100644
index 000000000..16ef882a4
--- /dev/null
+++ b/doc/todo/tahoe_lfs_for_reals/comment_1_0a4793ce6a867638f6e510e71dd4bb44._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="zooko"
+ ip="97.118.97.117"
+ subject="performance"
+ date="2011-05-17T19:20:39Z"
+ content="""
+Hm... O(N^2)? I think it just takes O(N). To read an entry out of a directory you have to download the entire directory (and store it in RAM and parse it). The constants are basically \"too big to be good but not big enough to be prohibitive\", I think. jctang has reported that his special remote hook performs well enough to use, but it would be nice if it were faster.
+
+The Tahoe-LAFS folks are working on speeding up mutable files, by the way, after which we would be able to speed up directories.
+"""]]
diff --git a/doc/todo/tahoe_lfs_for_reals/comment_2_80b9e848edfdc7be21baab7d0cef0e3a._comment b/doc/todo/tahoe_lfs_for_reals/comment_2_80b9e848edfdc7be21baab7d0cef0e3a._comment
new file mode 100644
index 000000000..6dba86c47
--- /dev/null
+++ b/doc/todo/tahoe_lfs_for_reals/comment_2_80b9e848edfdc7be21baab7d0cef0e3a._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 2"
+ date="2011-05-17T19:57:33Z"
+ content="""
+Whoops! You'd only told me O(N) twice before..
+
+So this is not too high priority. I think I would like to get the per-remote storage sorted out anyway, since probably it will be the thing needed to convert the URL backend into a special remote, which would then allow ripping out the otherwise unused pluggable backend infrastructure.
+
+Update: Per-remote storage is now sorted out, so this could be implemented
+if it actually made sense to do so.
+"""]]
diff --git a/doc/todo/union_mounting.mdwn b/doc/todo/union_mounting.mdwn
new file mode 100644
index 000000000..c42a05502
--- /dev/null
+++ b/doc/todo/union_mounting.mdwn
@@ -0,0 +1,10 @@
+It should be possible to union mount annexes. So if multiple drives have
+content, an annex mounting them both would have available all the
+content from all the drives.
+
+This could be done by just making .git/annex/KEY link to the actual content
+on the mounted annex.
+
+(Need to make sure the [[copy_tracking|copies]] code does not
+confused and think the symlink is a copy of the content.. Also need to make
+sure that code that writes to .git/annex does not follow symlinks.))
diff --git a/doc/todo/union_mounting/comment_1_cb08435812dd7766de26199c73f38e8b._comment b/doc/todo/union_mounting/comment_1_cb08435812dd7766de26199c73f38e8b._comment
new file mode 100644
index 000000000..3fadf6fa3
--- /dev/null
+++ b/doc/todo/union_mounting/comment_1_cb08435812dd7766de26199c73f38e8b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawln3ckqKx0x_xDZMYwa9Q1bn4I06oWjkog"
+ nickname="Michael"
+ subject="comment 1"
+ date="2013-03-01T01:26:36Z"
+ content="""
+This would indeed be very helpful when remotely mounting a photo/video collection over samba.
+"""]]
diff --git a/doc/todo/union_mounting/comment_2_240b1736f6bd4fbf87c372d3a46e661b._comment b/doc/todo/union_mounting/comment_2_240b1736f6bd4fbf87c372d3a46e661b._comment
new file mode 100644
index 000000000..08901ee17
--- /dev/null
+++ b/doc/todo/union_mounting/comment_2_240b1736f6bd4fbf87c372d3a46e661b._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://edheil.wordpress.com/"
+ ip="173.162.44.162"
+ subject="comment 2"
+ date="2013-03-01T04:50:28Z"
+ content="""
++1 this would be sweet as hell
+
+"""]]
diff --git a/doc/todo/untracked_remotes.mdwn b/doc/todo/untracked_remotes.mdwn
new file mode 100644
index 000000000..883b5acff
--- /dev/null
+++ b/doc/todo/untracked_remotes.mdwn
@@ -0,0 +1,9 @@
+Seems that a fairly common desire in some use cases is to be able to make a
+clone of a repository and be able to get files, without updating the
+location tracking information. (And without even recording a uuid in the
+remote.log.) Use cases include wanting to have temporary
+clones without cluttering history, and centralized development where the
+developers don't care to know about one-another's systems.
+
+It seems that such an untracked repository would need to automatically
+consider itself untrusted. Is that enough to avoid losing data?
diff --git a/doc/todo/use_cp_reflink.mdwn b/doc/todo/use_cp_reflink.mdwn
new file mode 100644
index 000000000..39518abf1
--- /dev/null
+++ b/doc/todo/use_cp_reflink.mdwn
@@ -0,0 +1,7 @@
+The unlock command needs to copy a file, and it would be great to use this:
+ cp --reflink=auto src dst
+
+O(1) overhead on BTRFS. Needs coreutils 7.6; and remember that git-annex
+may be used on systems without coreutils..
+
+[[done]]
diff --git a/doc/todo/using_url_backend.mdwn b/doc/todo/using_url_backend.mdwn
new file mode 100644
index 000000000..1f3cd5628
--- /dev/null
+++ b/doc/todo/using_url_backend.mdwn
@@ -0,0 +1,11 @@
+There is no way to `git annex add` a file using the URL [[backend|backends]].
+
+For now, we have to manually make the symlink. Something like this:
+
+ ln -s .git/annex/URL:http:%%www.example.com%foo.tar.gz
+
+Note the escaping of slashes.
+
+A `git annex register <url>` command could do this..
+
+[[done]]
diff --git a/doc/todo/whishlist:_git_annex_drop_--dry-run.mdwn b/doc/todo/whishlist:_git_annex_drop_--dry-run.mdwn
new file mode 100644
index 000000000..6bbfd7a4d
--- /dev/null
+++ b/doc/todo/whishlist:_git_annex_drop_--dry-run.mdwn
@@ -0,0 +1,5 @@
+It'd be useful to be able to see what `git annex drop` would do *before* asking it to drop any files.
+
+For example, I just set up my preferred contents expressions, and I don't know if I got them right. Before dropping anything from this repo, it'd be nice to check what would happen. I know git annex drop will only drop files that are above their minimum numcopies, but I'd still like to avoid heavyweight copying in case I got my preferred contents expressions wrong.
+
+> [[done]]; added --want-get and --want-drop. --[[Joey]]
diff --git a/doc/todo/whishlist:_git_annex_drop_--dry-run/comment_1_20ecfa8ffa52c238d21b904076ac69a2._comment b/doc/todo/whishlist:_git_annex_drop_--dry-run/comment_1_20ecfa8ffa52c238d21b904076ac69a2._comment
new file mode 100644
index 000000000..098d399e3
--- /dev/null
+++ b/doc/todo/whishlist:_git_annex_drop_--dry-run/comment_1_20ecfa8ffa52c238d21b904076ac69a2._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 1"
+ date="2013-10-28T17:11:04Z"
+ content="""
+It would be nice, but it adds quite a lot of complexity to have a --dry-run, and if I add it to just drop, the next bug is going to ask for get to have it..
+
+I feel that the right approach is to add a --wanted, which could then be used with find to find files that are and are not wanted, according to the preferred content settings. To see what it would want to get: `git annex find --wanted --not --in .` To see what it would want to drop: `git annex find --not --wanted --in .`
+"""]]
diff --git a/doc/todo/whishlist:_git_annex_drop_--dry-run/comment_2_d19bc268c9467d24baa8d8f77a6e5e09._comment b/doc/todo/whishlist:_git_annex_drop_--dry-run/comment_2_d19bc268c9467d24baa8d8f77a6e5e09._comment
new file mode 100644
index 000000000..3f1102985
--- /dev/null
+++ b/doc/todo/whishlist:_git_annex_drop_--dry-run/comment_2_d19bc268c9467d24baa8d8f77a6e5e09._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnWwEEA3CurHkBjIYaJsJzFc4jtY2SCkrQ"
+ nickname="Diego"
+ subject="comment 2"
+ date="2013-10-29T00:28:51Z"
+ content="""
+That makes sense, and thanks for adding this feature so quickly!
+"""]]
diff --git a/doc/todo/windows_support.mdwn b/doc/todo/windows_support.mdwn
new file mode 100644
index 000000000..a8cbd6db8
--- /dev/null
+++ b/doc/todo/windows_support.mdwn
@@ -0,0 +1,23 @@
+The git-annex Windows port is not ready for prime time. But it does exist
+now! --[[Joey]]
+
+## status
+
+* Does not work with Cygwin's build of git (that git does not consistently
+ support use of DOS style paths, which git-annex uses on Windows).
+ Must use the upstream build of git for Windows.
+* rsync special remotes are known buggy.
+* Bad file locking, it's probably not safe to run more than one git-annex
+ process at the same time on Windows.
+* Ssh connection caching does not work on Windows, so `git annex get`
+ has to connect twice to the remote system over ssh per file, which
+ is much slower than on systems supporting connection caching.
+* Webapp doesn't build yet.
+* `git annex watch` builds, but does not quite work.
+* `git annex assistant` builds, but has not been tested, and is known
+ to not download any files. (transferrer doesn't built yet)
+* watch and assistant cannot be built with cabal. Possibly due to too many
+ files overflowing command line length limit at link stage.
+ To build a binary with them:
+ `ghc --make git-annex.hs -threaded -XPackageImports -DWITH_ASSISTANT=1 -DWITH_WIN32NOTIFY=1`
+ (should add all the other flags cabal uses)
diff --git a/doc/todo/windows_support/comment_10_394127e34e07ab3dc0e7b94ee6898866._comment b/doc/todo/windows_support/comment_10_394127e34e07ab3dc0e7b94ee6898866._comment
new file mode 100644
index 000000000..fb061962e
--- /dev/null
+++ b/doc/todo/windows_support/comment_10_394127e34e07ab3dc0e7b94ee6898866._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.145"
+ subject="comment 10"
+ date="2013-08-04T18:23:00Z"
+ content="""
+Encryption is now working on Windows.
+"""]]
diff --git a/doc/todo/windows_support/comment_1_3cc26ad8101a22e95a8c60cf0c4dedcc._comment b/doc/todo/windows_support/comment_1_3cc26ad8101a22e95a8c60cf0c4dedcc._comment
new file mode 100644
index 000000000..fd5b6f5cd
--- /dev/null
+++ b/doc/todo/windows_support/comment_1_3cc26ad8101a22e95a8c60cf0c4dedcc._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkRITTYYsN0TFKN7G5sZ6BWGZOTQ88Pz4s"
+ nickname="Zoltán"
+ subject="cygwin"
+ date="2012-05-15T00:14:08Z"
+ content="""
+What about [Cygwin](http://cygwin.com/)? It emulates POSIX fairly well under Windows (including signals, forking, fs (also things like /dev/null, /proc), unix file permissions), has all standard gnu utilities. It also emulates symlinks, but they are unfortunately incompatible with NTFS symlinks introduced in Vista [due to some stupid restrictions on Windows](http://cygwin.com/ml/cygwin/2009-10/msg00756.html).
+
+If git-annex could be modified to not require symlinks to work, the it would be a pretty neat solution (and you get a real shell, not some command.com on drugs (aka cmd.exe))
+"""]]
diff --git a/doc/todo/windows_support/comment_2_8acae818ce468967499050bbe3c532ea._comment b/doc/todo/windows_support/comment_2_8acae818ce468967499050bbe3c532ea._comment
new file mode 100644
index 000000000..e37a55575
--- /dev/null
+++ b/doc/todo/windows_support/comment_2_8acae818ce468967499050bbe3c532ea._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawk5cj-itfFHq_yhJHdzk3QOPp-PNW_MjPU"
+ nickname="Michael"
+ subject="+1 Cygwin"
+ date="2012-05-23T19:30:21Z"
+ content="""
+Windows support is a must. In my experience, binary file means proprietary editor, which means Windows.
+
+Unfortunately, there's not much overlap between people who use graphical editors in Windows all day vs. people who are willing to tolerate Cygwin's setup.exe, compile a Haskell program, learn git and git-annex's 90-odd subcommands, and use a mintty terminal to manage their repository, especially now that there's a sexy GitHub app for Windows.
+
+That aside, I think Windows-based content producers are still *the* audience for git-annex. First Windows support, then a GUI, then the world.
+"""]]
diff --git a/doc/todo/windows_support/comment_3_bd0a12f4c9b884ab8a06082842381a01._comment b/doc/todo/windows_support/comment_3_bd0a12f4c9b884ab8a06082842381a01._comment
new file mode 100644
index 000000000..0b48db750
--- /dev/null
+++ b/doc/todo/windows_support/comment_3_bd0a12f4c9b884ab8a06082842381a01._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://xolus.net/openid/max"
+ nickname="B0FH"
+ subject="What about NTFS support ?"
+ date="2012-08-02T17:45:10Z"
+ content="""
+Has git-annex been tested with an NTFS-formatted disk under Linux ? NTFS is supposed to be case-sensitive and to allow symlinks, and these are supposed to work with ntfs3g.
+"""]]
diff --git a/doc/todo/windows_support/comment_4_ad06b98b2ddac866ffee334e41fee6a8._comment b/doc/todo/windows_support/comment_4_ad06b98b2ddac866ffee334e41fee6a8._comment
new file mode 100644
index 000000000..66f9ca71f
--- /dev/null
+++ b/doc/todo/windows_support/comment_4_ad06b98b2ddac866ffee334e41fee6a8._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlc1og3PqIGudOMkFNrCCNg66vB7s-jLpc"
+ nickname="Paul"
+ subject="Re: What about NTFS support?"
+ date="2012-08-16T19:30:38Z"
+ content="""
+I successfully use git-annex on an NTFS formatted external USB drive, so yes, it is possible and works well.
+"""]]
diff --git a/doc/todo/windows_support/comment_5_444fc7251f57db241b6e80abae41851c._comment b/doc/todo/windows_support/comment_5_444fc7251f57db241b6e80abae41851c._comment
new file mode 100644
index 000000000..8f76ee258
--- /dev/null
+++ b/doc/todo/windows_support/comment_5_444fc7251f57db241b6e80abae41851c._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/dASECLNzvckz4VwqUGYsvthiplY.#d2c27"
+ nickname="A. D. Sicks"
+ subject="comment 5"
+ date="2012-09-09T23:48:21Z"
+ content="""
+Haskell has C++ binding, so it should be possible to port it to .net/Mono with a VB GUI for Windows users. Windows has a primitive form of symlinks called shortcuts. Perhaps shortcut support in Windows could replace the use of symlinks. I've used shortcuts since XP to put my home Windows directory on another partition and never had a hitch...
+
+If anyone is interested in working on this, hit me up. I would like to use this in my XP vbox to have access to files on my host OS...I have a student edition of Visual Studio 2005 to do an open source port...
+"""]]
diff --git a/doc/todo/windows_support/comment_6_34f1f60b570c389bb1e741b990064a7e._comment b/doc/todo/windows_support/comment_6_34f1f60b570c389bb1e741b990064a7e._comment
new file mode 100644
index 000000000..bf9f86f41
--- /dev/null
+++ b/doc/todo/windows_support/comment_6_34f1f60b570c389bb1e741b990064a7e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnlwEMhiNYv__mEUABW4scn83yMraC3hqE"
+ nickname="Sean"
+ subject="NTFS symlinks"
+ date="2013-01-11T21:44:21Z"
+ content="""
+It seems that NTFS (from Vista forward) has full POSIX support for symlinks. At least, Wikipedia [seems to think so.](http://en.wikipedia.org/wiki/NTFS_symbolic_link). What about doing like GitHub and using MinGW for compatibility? Cygwin absolutely blows in terms of installation size and compatability with the rest of Windows.
+"""]]
diff --git a/doc/todo/windows_support/comment_7_a5ca56c487257434650420acfa60e39f._comment b/doc/todo/windows_support/comment_7_a5ca56c487257434650420acfa60e39f._comment
new file mode 100644
index 000000000..0ee09ac5a
--- /dev/null
+++ b/doc/todo/windows_support/comment_7_a5ca56c487257434650420acfa60e39f._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlpSOjMH7Iaz56v6Pr9KCFSpbvMXvg-y9o"
+ nickname="Dominik"
+ subject="So close :-)"
+ date="2013-06-30T12:46:40Z"
+ content="""
+I was fighting my way forward until I read here that special remote with ssh+rsync and encryption doesn't work. Interestingly I got everything working so far, ssh login is keybased, gpg -k works and the remote setup also correctly cooperated with gpg... but it just didn't sync. Any ideas how complex it is to get this last missing piece moving?
+"""]]
diff --git a/doc/todo/windows_support/comment_8_61214de7d967740d42905f3823ce2f65._comment b/doc/todo/windows_support/comment_8_61214de7d967740d42905f3823ce2f65._comment
new file mode 100644
index 000000000..fe193f7e0
--- /dev/null
+++ b/doc/todo/windows_support/comment_8_61214de7d967740d42905f3823ce2f65._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.193"
+ subject="comment 8"
+ date="2013-06-30T17:58:08Z"
+ content="""
+It should be easy to fix whatever's wrong the the rsync special remote. Just a matter of debugging that.
+
+Adding encryption support on Windows is stuck at a roadblock I don't know the way around. To drive gpg, git-annex uses the `--passphrase-fd` option, and sends the \"passphrase\" (really a big block of binary foo!) over a file descriptor of a pipe that it set up.
+
+Windows, AFAIK, doesn't have file descriptors, or at least there is no equivilant to them that I have access to in the Haskell POSIX compatability layer for Windows. I am reluctant to fall back to using `--passphrase-file` on Windows, since that would be a massive security hole (as would passing the passphrase as a parameter via `--passphrase=`).
+"""]]
diff --git a/doc/todo/windows_support/comment_9_259a0b1a6f4d8d1944173380adc5e7c8._comment b/doc/todo/windows_support/comment_9_259a0b1a6f4d8d1944173380adc5e7c8._comment
new file mode 100644
index 000000000..9ae337886
--- /dev/null
+++ b/doc/todo/windows_support/comment_9_259a0b1a6f4d8d1944173380adc5e7c8._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlpSOjMH7Iaz56v6Pr9KCFSpbvMXvg-y9o"
+ nickname="Dominik"
+ subject="comment 9"
+ date="2013-07-31T10:29:51Z"
+ content="""
+The tradeoff for me is a \"local\" security hole (where I can secure my own laptop) vs. a remotely exploitable thing... If it needs to go through a file, so be it -- it would however be good if that file would be overwritten with garbage before being deleted :-)
+"""]]
diff --git a/doc/todo/wishlist:_Add_to_Android_version_to_Google_Play.mdwn b/doc/todo/wishlist:_Add_to_Android_version_to_Google_Play.mdwn
new file mode 100644
index 000000000..f9016fb4d
--- /dev/null
+++ b/doc/todo/wishlist:_Add_to_Android_version_to_Google_Play.mdwn
@@ -0,0 +1,9 @@
+If possible a frequently updated daily build in separate package for those more adventurous of us.
+
+It would make installing and testing much easier and no need to change configuration settings to allow untrusted source.
+
+> While it's vaid to wish that someone might put the apk into Google Play,
+> I a) don't feel it's ready b) don't know if I want to go through
+> the rigamarole required to use that service and c) don't feel this
+> bug tracker is an appropriate place to track what is effectively a
+> nontechnical request. [[done]] --[[Joey]]
diff --git a/doc/todo/wishlist:_Advanced_settings_for_xmpp_and_webdav.mdwn b/doc/todo/wishlist:_Advanced_settings_for_xmpp_and_webdav.mdwn
new file mode 100644
index 000000000..96552eecc
--- /dev/null
+++ b/doc/todo/wishlist:_Advanced_settings_for_xmpp_and_webdav.mdwn
@@ -0,0 +1,7 @@
+It would be very nice with an "advanced settings" for jabber and webdav support.
+
+Currently XMPP fails if you use a google apps account. Since the domain provided in the email is not the same as the XMPP server.
+
+Same goes for webdav support. If i have my own webdav server somewhere on the internet there is no way to set it up in the assistant.
+
+[[!tag /design/assistant]]
diff --git a/doc/todo/wishlist:_Advanced_settings_for_xmpp_and_webdav/comment_1_11c7444ab4988c60732af505b52bde3c._comment b/doc/todo/wishlist:_Advanced_settings_for_xmpp_and_webdav/comment_1_11c7444ab4988c60732af505b52bde3c._comment
new file mode 100644
index 000000000..61cd3fc2e
--- /dev/null
+++ b/doc/todo/wishlist:_Advanced_settings_for_xmpp_and_webdav/comment_1_11c7444ab4988c60732af505b52bde3c._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmWg4VvDTer9f49Y3z-R0AH16P4d1ygotA"
+ nickname="Tobias"
+ subject="Hooks too"
+ date="2013-05-22T10:40:33Z"
+ content="""
+It would actually be very nice if this could be done with hooks too.
+
+Especially with the new hook method.
+
+Take this hook
+
+ mega-hook = /usr/bin/python2 ~/sources/megaannex/megaannex.py
+
+git-annex could make a request with either the parameter(or environment variable) \"getsettingsobject\" that could return. {\"username\": \"\", \"password\": \"\", \"folder\": \"\"}.
+
+The point being git-annex can request from the hooks program what settings it takes, and give a web interface to set it. Then store the information in the creds folder(ew ew, that folder is unencrypted, oh well) and pass it to the hook on run.
+
+The advantage being that users wouldn't have to edit a settings file manually (this is currently also the case for the IMAP special remote, which also requires a settings file).
+"""]]
diff --git a/doc/todo/wishlist:_An_--all_option_for_dropunused.mdwn b/doc/todo/wishlist:_An_--all_option_for_dropunused.mdwn
new file mode 100644
index 000000000..bd35c0e55
--- /dev/null
+++ b/doc/todo/wishlist:_An_--all_option_for_dropunused.mdwn
@@ -0,0 +1,4 @@
+Cleaning out a repository is presently a fairly manual process. Am I missing a UI trick? "dropunsed" with no arguments prints nothing at all; I think in that case it should display the list of what could be dropped.
+
+> [[done]]; comments seem satisfactory and I see no reason to complicate
+> dropunused to output something unused already outputs. --[[Joey]]
diff --git a/doc/todo/wishlist:_An_--all_option_for_dropunused/comment_1_d8726d108b3b40116b4ec3c9935f2dff._comment b/doc/todo/wishlist:_An_--all_option_for_dropunused/comment_1_d8726d108b3b40116b4ec3c9935f2dff._comment
new file mode 100644
index 000000000..6c728a5d0
--- /dev/null
+++ b/doc/todo/wishlist:_An_--all_option_for_dropunused/comment_1_d8726d108b3b40116b4ec3c9935f2dff._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.23"
+ subject="comment 1"
+ date="2012-10-22T15:35:30Z"
+ content="""
+`git annex unused` prints the list
+"""]]
diff --git a/doc/todo/wishlist:_An_--all_option_for_dropunused/comment_2_578248f7686ba2d80d7dc8b17c0cdf52._comment b/doc/todo/wishlist:_An_--all_option_for_dropunused/comment_2_578248f7686ba2d80d7dc8b17c0cdf52._comment
new file mode 100644
index 000000000..a87a367d6
--- /dev/null
+++ b/doc/todo/wishlist:_An_--all_option_for_dropunused/comment_2_578248f7686ba2d80d7dc8b17c0cdf52._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://hands.com/~phil/"
+ nickname="hands"
+ subject="and you can specify ranges to dropunused"
+ date="2012-11-02T09:07:48Z"
+ content="""
+so having run:
+
+ git annex unused
+
+you can then run:
+
+ git annex dropunused 1-10000
+
+or whatever, and it deletes the items in that range from the most recent <tt>unused</tt> invocation
+"""]]
diff --git a/doc/todo/wishlist:_An_option_like_--git-dir.mdwn b/doc/todo/wishlist:_An_option_like_--git-dir.mdwn
new file mode 100644
index 000000000..cb9d374b3
--- /dev/null
+++ b/doc/todo/wishlist:_An_option_like_--git-dir.mdwn
@@ -0,0 +1,3 @@
+I'm currently integrating git-annex support into a filesystem synchronization tool that I use, and I have a use case where I'd like to run "git annex sync' on a local directory, and then automatically ssh over to remote hosts and run "git annex sync" in the related annex on that remote host. However, while I can easily "cd" on the local, there is no really easy way to "cd" on the remote without a hack.
+
+If I could say: git annex --annex-dir=PATH sync, where PATH is the annex directory, it would solve all my problems, and would also provide a nice correlation to the --git-dir option used by most Git commands. The basic idea is that I shouldn't have to be IN the directory to run git-annex commands, I should be able to tell git-annex which directory to apply its commands to.
diff --git a/doc/todo/wishlist:_An_option_like_--git-dir/comment_1_5d877d90b8bdf21d4b8649744d229efd._comment b/doc/todo/wishlist:_An_option_like_--git-dir/comment_1_5d877d90b8bdf21d4b8649744d229efd._comment
new file mode 100644
index 000000000..8e7c3c03e
--- /dev/null
+++ b/doc/todo/wishlist:_An_option_like_--git-dir/comment_1_5d877d90b8bdf21d4b8649744d229efd._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="What about..."
+ date="2012-10-16T16:43:29Z"
+ content="""
+ ssh remotehost \"cd /path/to/annex && git annex sync\"
+"""]]
diff --git a/doc/todo/wishlist:_An_option_like_--git-dir/comment_2_462264821cbc48a433330cbf7ec6044d._comment b/doc/todo/wishlist:_An_option_like_--git-dir/comment_2_462264821cbc48a433330cbf7ec6044d._comment
new file mode 100644
index 000000000..980658dc6
--- /dev/null
+++ b/doc/todo/wishlist:_An_option_like_--git-dir/comment_2_462264821cbc48a433330cbf7ec6044d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 2"
+ date="2012-10-17T18:31:58Z"
+ content="""
+You can use `GIT_DIR`. It would not be hard to add a --git-dir option, the only catch is how to communicate that state on to where it constructs its git repository data structure. (I suppose it could just set GIT_DIR..)
+"""]]
diff --git a/doc/todo/wishlist:_An_option_like_--git-dir/comment_3_0c3709b07a0a1091ceeee73b69e0f7ac._comment b/doc/todo/wishlist:_An_option_like_--git-dir/comment_3_0c3709b07a0a1091ceeee73b69e0f7ac._comment
new file mode 100644
index 000000000..a76c42d9d
--- /dev/null
+++ b/doc/todo/wishlist:_An_option_like_--git-dir/comment_3_0c3709b07a0a1091ceeee73b69e0f7ac._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/2grhJvAC049fJnvALDXek.6MRZMTlg--#eec89"
+ nickname="John"
+ subject="Response"
+ date="2012-10-20T05:21:13Z"
+ content="""
+@Justin If you have full shell access on the remote your solution works fine, but not if git-annex is the only binary you are allowed to execute.
+"""]]
diff --git a/doc/todo/wishlist:_Freeing_X_space_on_remote_Y.mdwn b/doc/todo/wishlist:_Freeing_X_space_on_remote_Y.mdwn
new file mode 100644
index 000000000..5fec39d98
--- /dev/null
+++ b/doc/todo/wishlist:_Freeing_X_space_on_remote_Y.mdwn
@@ -0,0 +1 @@
+As suggested during the first Gitify BoF during DebConf13: Adding a way to have on-demand dropping of content in a given remote would allow a user to quickly free up disk space on demand while still heeding numcopies etc.
diff --git a/doc/todo/wishlist:_GnuPG_options.mdwn b/doc/todo/wishlist:_GnuPG_options.mdwn
new file mode 100644
index 000000000..2cadf8213
--- /dev/null
+++ b/doc/todo/wishlist:_GnuPG_options.mdwn
@@ -0,0 +1,16 @@
+[Maybe I should have extented [[wishlist:_simpler_gpg_usage/]], but I thought I'd make my own since it's perhaps too old.]
+
+I second Justin and [[his idea|wishlist:_simpler_gpg_usage/#comment-e120f8ede0d4cffce17cbf84564211c1]] of having per-remote GnuPG options. I'd even go one step further, and propose the option in the <tt>.gitattributes</tt> file. Indeed by default GnuPG compresses the data before encryption, which doesn't make a lot of sense for git-annex (in my use-case at least); My work-around to save this waste of CPU cycles was to customize my <tt>gpg.conf</tt>, but it's somewhat dirty since I do want to use compression in general.
+
+Here is how I envision the <tt>.git/config</tt>:
+<pre> <code>[annex]
+ gnupg-options = --s2k-cipher-algo AES256 --s2k-digest-algo SHA512 --s2k-count 8388608 --cipher-algo AES256 --compress-algo none
+</code></pre>
+
+And compression could be enabled on say, text files, with a suitable wildcard in the <tt>.gitattributes</tt> file.
+<pre> <code>*.txt annex.gnupg-options="--s2k-cipher-algo AES256 --s2k-digest-algo SHA512 --s2k-count 8388608 --cipher-algo AES256 --compress-algo zlib"
+</code></pre>
+
+This is something I could probably hack on if you think it'd be a worthwhile option ;-)
+
+> Done, and [[done]]! --[[Joey]]
diff --git a/doc/todo/wishlist:_GnuPG_options/comment_1_6662e8a71ce20acc62147ef41ecffa50._comment b/doc/todo/wishlist:_GnuPG_options/comment_1_6662e8a71ce20acc62147ef41ecffa50._comment
new file mode 100644
index 000000000..b756eccad
--- /dev/null
+++ b/doc/todo/wishlist:_GnuPG_options/comment_1_6662e8a71ce20acc62147ef41ecffa50._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-03-09T01:54:30Z"
+ content="""
+I'd be happy to apply a patch implementing annex.gnupg-options and/or per-remote remote.annex-gnupg-options, and I don't think it would be very hard to do.
+
+The gitattributes thing would be harder to do efficiently, and seems overkill.
+
+
+"""]]
diff --git a/doc/todo/wishlist:_Have_a_preview_of_download_or_upload_size.mdwn b/doc/todo/wishlist:_Have_a_preview_of_download_or_upload_size.mdwn
new file mode 100644
index 000000000..12688951d
--- /dev/null
+++ b/doc/todo/wishlist:_Have_a_preview_of_download_or_upload_size.mdwn
@@ -0,0 +1,10 @@
+When using SSH remote repository, git-annex uses rsync to download or upload files one at a time. I would like to have a preview of the overall transfer size so that I can estimate the transfer duration.
+
+This could be done as an option of get, move or copy, or as a separated command.
+
+If part of get, move or copy, git-annex could print how much has been done or how much left between every files.
+
+Thanks.
+
+> [[done]]; `git-annex status .` seems to cover the requested use case.
+> --[[Joey]]
diff --git a/doc/todo/wishlist:_Have_a_preview_of_download_or_upload_size/comment_1_019a2457e07377510feaa089a93bd76c._comment b/doc/todo/wishlist:_Have_a_preview_of_download_or_upload_size/comment_1_019a2457e07377510feaa089a93bd76c._comment
new file mode 100644
index 000000000..4a59f37f1
--- /dev/null
+++ b/doc/todo/wishlist:_Have_a_preview_of_download_or_upload_size/comment_1_019a2457e07377510feaa089a93bd76c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.193"
+ subject="comment 1"
+ date="2013-06-25T17:26:25Z"
+ content="""
+git-annex is designed to work with really large trees of files, and so it processes files one at a time in a stream. To get an overall estimate of the size, it would need to traverse the whole directory to get the total, and then traverse it again to perform the transfer. This would make no-op transfers take twice as long, which is why I'm unlikely to implement it.
+"""]]
diff --git a/doc/todo/wishlist:_Have_a_preview_of_download_or_upload_size/comment_3_29a154699339bf040af0ee8aa24034f1._comment b/doc/todo/wishlist:_Have_a_preview_of_download_or_upload_size/comment_3_29a154699339bf040af0ee8aa24034f1._comment
new file mode 100644
index 000000000..9f0c04017
--- /dev/null
+++ b/doc/todo/wishlist:_Have_a_preview_of_download_or_upload_size/comment_3_29a154699339bf040af0ee8aa24034f1._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnHRhCe3qwVKQ8_NOGGSYJnAMW6FFyKbOc"
+ nickname="Holger"
+ subject="comment 3"
+ date="2013-07-02T04:05:06Z"
+ content="""
+What do you think of the following simpler variant:
+
+ % git annex size myfile1.zip
+ myfile1.zip is 1329 MB
+ % git annex size mydir/
+ mydir contains 2803 files totaling 328 GB.
+
+If you're worried about running over the tree twice, it may be a good idea to store the size of a subtree along with the other metadata.
+"""]]
diff --git a/doc/todo/wishlist:_Have_a_preview_of_download_or_upload_size/comment_3_8f7e1c4a5c714cbd719ee170354d79fa._comment b/doc/todo/wishlist:_Have_a_preview_of_download_or_upload_size/comment_3_8f7e1c4a5c714cbd719ee170354d79fa._comment
new file mode 100644
index 000000000..fa9fdfb56
--- /dev/null
+++ b/doc/todo/wishlist:_Have_a_preview_of_download_or_upload_size/comment_3_8f7e1c4a5c714cbd719ee170354d79fa._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.193"
+ subject="comment 3"
+ date="2013-07-02T17:04:47Z"
+ content="""
+You can get info like that by running `git annex status .`
+
+This can also be used to find out how big a download is before starting it. For example, to find all files that are not present locally before running git-annex get:
+
+`git annex status . --not --in here`
+"""]]
diff --git a/doc/todo/wishlist:_Have_a_preview_of_download_or_upload_size/comment_4_c7335f757e5546aa841cab38fffe7605._comment b/doc/todo/wishlist:_Have_a_preview_of_download_or_upload_size/comment_4_c7335f757e5546aa841cab38fffe7605._comment
new file mode 100644
index 000000000..b9212a24d
--- /dev/null
+++ b/doc/todo/wishlist:_Have_a_preview_of_download_or_upload_size/comment_4_c7335f757e5546aa841cab38fffe7605._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnHRhCe3qwVKQ8_NOGGSYJnAMW6FFyKbOc"
+ nickname="Holger"
+ subject="comment 4"
+ date="2013-07-02T21:09:03Z"
+ content="""
+That's so cool, thanks!
+
+Do you think it'd be a major change to the repository format if the size of any directory was stored there so that this kind of status lookup becomes a constant time operation? The two most important operations are probably:
+
+* The total size of a directory, counting only files present here
+* The total size of a directory, counting all files present at any location
+
+Of course, if the above two were constant time operations, you get --not here for free, too.
+
+To implement this, each node in the directory tree could have two additional 64 bit fields that hold the number of bytes in all files present anywhere (and this set of numbers is synchronized between all repositories), and the number of bytes in all files present here (only kept locally). This is only a small storage overhead (<16 MB if you have a million nodes) and suffices for repositories of size at most 2^64 bytes = 16 exabytes (probably more since most users will be ok with float accuracy). The numbers can be updated in logarithmic time every time a file changes. Instead of two numbers, it may not be that costly to store k numbers where k is the number of locations that a repository is connected to, since k is typically pretty small.
+
+The number of files can be stored in a similar way.
+"""]]
diff --git a/doc/todo/wishlist:_Have_a_preview_of_download_or_upload_size/comment_5_d2a845354f23d07880612740cf99ddd4._comment b/doc/todo/wishlist:_Have_a_preview_of_download_or_upload_size/comment_5_d2a845354f23d07880612740cf99ddd4._comment
new file mode 100644
index 000000000..7e160bebf
--- /dev/null
+++ b/doc/todo/wishlist:_Have_a_preview_of_download_or_upload_size/comment_5_d2a845354f23d07880612740cf99ddd4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnHRhCe3qwVKQ8_NOGGSYJnAMW6FFyKbOc"
+ nickname="Holger"
+ subject="comment 5"
+ date="2013-07-03T02:43:32Z"
+ content="""
+Btw, this would also provide a cheap test for whether we need to recurse into the folder in certain copy or get actions (e.g., if number of bytes present here equals number of bytes globally present, we don't need to recurse).
+"""]]
diff --git a/doc/todo/wishlist:_Option_to_specify_max_transfer_rate.mdwn b/doc/todo/wishlist:_Option_to_specify_max_transfer_rate.mdwn
new file mode 100644
index 000000000..3ecb42197
--- /dev/null
+++ b/doc/todo/wishlist:_Option_to_specify_max_transfer_rate.mdwn
@@ -0,0 +1,3 @@
+A big part of my online use is done via a low-speed connection over my mobile phone, this is limited to 16KB/sec because I always use up my 500MB quota the very first day of the month. `;-/` So when I need to download big files, I first download them to my online server, then transfer the files to my laptop with git-annex. If I'm connected via GSM, this occupies all the bandwidth and everything else moves like a heavily sedated slug. So if I want to work via VNC or SSH, I have to terminate ongoing transfers with Ctrl-C and then hopefully remember to restart it when I work locally. I know git-annex is robust enough to handle this gracefully, but it would be really nice to have a continuous connection going on in the background, limited to a value I choose.
+
+rsync(1) has a `--bwlimit` (bandwidth limit) where you can specify max download/upload speed in kilobytes/sec. It would be great if a similar option was integrated into git-annex. Thanks in advance.
diff --git a/doc/todo/wishlist:_Option_to_specify_max_transfer_rate/comment_1_4fd870e14b5b70c8a6ade41406294387._comment b/doc/todo/wishlist:_Option_to_specify_max_transfer_rate/comment_1_4fd870e14b5b70c8a6ade41406294387._comment
new file mode 100644
index 000000000..78ca76939
--- /dev/null
+++ b/doc/todo/wishlist:_Option_to_specify_max_transfer_rate/comment_1_4fd870e14b5b70c8a6ade41406294387._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="trickle"
+ date="2013-01-22T22:44:52Z"
+ content="""
+not exactly integrated, but you can easily use trickle for this.
+
+ trickle -d 50 git annex ...
+"""]]
diff --git a/doc/todo/wishlist:_Option_to_specify_max_transfer_rate/comment_2_dd854f297ad6a94b54be9f3edfd0f766._comment b/doc/todo/wishlist:_Option_to_specify_max_transfer_rate/comment_2_dd854f297ad6a94b54be9f3edfd0f766._comment
new file mode 100644
index 000000000..70f04c616
--- /dev/null
+++ b/doc/todo/wishlist:_Option_to_specify_max_transfer_rate/comment_2_dd854f297ad6a94b54be9f3edfd0f766._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://sunny256.sunbase.org/"
+ nickname="sunny256"
+ subject="Yay, trickle works"
+ date="2013-01-23T01:36:21Z"
+ content="""
+Justin, thanks a lot! trickle(1) works great. I didn't know about this program, but I'm not surprised that such a program is available. It never ceases to amaze me what's possible in a *NIX environment.
+"""]]
diff --git a/doc/todo/wishlist:_Option_to_specify_max_transfer_rate/comment_3_a8b7e90a473d5937807cc7eb456efe33._comment b/doc/todo/wishlist:_Option_to_specify_max_transfer_rate/comment_3_a8b7e90a473d5937807cc7eb456efe33._comment
new file mode 100644
index 000000000..a5f8f6a1b
--- /dev/null
+++ b/doc/todo/wishlist:_Option_to_specify_max_transfer_rate/comment_3_a8b7e90a473d5937807cc7eb456efe33._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 3"
+ date="2013-01-24T01:55:10Z"
+ content="""
+In addition to trickle, the git-annex man page has examples of how to make rsync use --bwlimit
+
+Something like trickle is needed to limit rates for remotes not using rsync, however.
+"""]]
diff --git a/doc/todo/wishlist:_Prevent_repeated_password_prompts_for_one_command.mdwn b/doc/todo/wishlist:_Prevent_repeated_password_prompts_for_one_command.mdwn
new file mode 100644
index 000000000..341a9afa4
--- /dev/null
+++ b/doc/todo/wishlist:_Prevent_repeated_password_prompts_for_one_command.mdwn
@@ -0,0 +1,45 @@
+Simple, when performing various git annex command over ssh, in particular a multi-file get, and using password authentication, git annex will prompt more than once for a user password. This makes batch updates very inconvenient.
+
+> I'd suggest using ssh-agent, or a passwordless ssh key. Possibly in
+> combination with [[git-annex-shell]] if you want to lock down a
+> particular ssh key to only being able to use git-annex and git-daemon.
+>
+> Combining multiple operations into a single ssh is on the todo list, but
+> very far down it. --[[Joey]]
+
+>> OTOH, automatically running ssh in ControlMaster mode (and stopping it
+>> at exit) would be useful and not hard thing for git-annex to do.
+>>
+>> It'd just need to set the appropriate config options, setting
+>> ControlPath to a per-remote socket location that includes git-annex's
+>> pid. Then at shutdown, run `ssh -O exit` on each such socket.
+>>
+>> Complicated slightly by not doing this if the user has already set up
+>> more broad ssh connection caching.
+>>
+>> [[done]]! --[[Joey]]
+
+---
+
+Slightly more elaborate design for using ssh connection caching:
+
+* Per-uuid ssh socket in `.git/annex/ssh/user@host.socket`
+* Can be shared amoung concurrent git-annex processes as well as ssh
+ invocations inside the current git-annex.
+* Also a lock file, `.git/annex/ssh/user@host.lock`.
+ Open and take shared lock before running ssh; store lock in lock pool.
+ (Not locking socket directly, because ssh might want to.)
+* Run ssh like: `ssh -S .git/annex/ssh/user@host.socket -o ControlMaster=auto -o ControlPersist=yes user@host`
+* At shutdown, enumerate all existing sockets, and on each:
+ 1. Drop any shared lock.
+ 2. Attempt to take an exclusive lock (non-blocking).
+ 3. `ssh -q -S .git/annex/ssh/user@host.socket -o ControlMaster=auto -o ControlPersist=yes -O stop user@host`
+ (Will exit nonzero if ssh is not running on that socket.)
+ 4. And then remove the socket and the lock file.
+* Do same *at startup*. Why? In case an old git-annex was interrupted
+ and left behind a ssh. May have moved to a different network
+ in the meantime, etc, and be stalled waiting for a response from the
+ network, or talking to the wrong interface or something.
+ (Ie, the reason why I don't use ssh connection caching by default.)
+* User should be able to override this, to use their own preferred
+ connection caching setup. `annex.sshcaching=false`
diff --git a/doc/todo/wishlist:_Prevent_repeated_password_prompts_for_one_command/comment_1_3f9c0d08932c2ede61c802a91261a1f7._comment b/doc/todo/wishlist:_Prevent_repeated_password_prompts_for_one_command/comment_1_3f9c0d08932c2ede61c802a91261a1f7._comment
new file mode 100644
index 000000000..2801d8e68
--- /dev/null
+++ b/doc/todo/wishlist:_Prevent_repeated_password_prompts_for_one_command/comment_1_3f9c0d08932c2ede61c802a91261a1f7._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 1"
+ date="2011-05-06T18:30:02Z"
+ content="""
+Unless you are forced to use a password, you should really be using a ssh key.
+
+ ssh-keygen
+ #put local .ssh/id_?sa.pub into remote .ssh/authorized_keys (which needs to be chmod 600)
+ ssh-add
+ git annex whatever
+
+"""]]
diff --git a/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates.mdwn b/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates.mdwn
new file mode 100644
index 000000000..933653578
--- /dev/null
+++ b/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates.mdwn
@@ -0,0 +1,28 @@
+(Hi, this is paulproteus@debian, AKA Asheesh).
+
+I've been enjoying using git-annex to archive my data.
+
+It's great that, by using git-annex and the SHA1 backend, I get a space-saving kind of deduplication through the symbolic links.
+
+I'm looking for the ability to filter files, before they get added to the annex, so that I don't add new files whose content is already in the annex.look That would help me in terms of personal file organization.
+
+It seems there is not, so this is a wishlist bug filed so that maybe such a thing might exist. What I would really like to do is:
+
+* $ git annex add --no-add-if-already-present .
+* $ git commit -m "Slurping in some photos I found on my old laptop hard drive"
+
+And then I'd do something like:
+
+* $ git clean -f
+
+to remove the files that didn't get annexed in this run. That way, only one filename would ever point to a particular SHA1.
+
+I want this because I have copies of various of mine (photos, in particular) scattered across various hard disks. If this feature existed, I could comfortably toss them all into one git annex that grew, bit by bit, to store all of these files exactly once.
+
+(I would be even happier for "git annex add --unlink-duplicates .")
+
+(Another way to do this would be to "git annex add" them all, and then use a "git annex remove-duplicates" that could prompt me about which files are duplicates of each other, and then I could pipe that command's output into xargs git rm.)
+
+(As I write this, I realize it's possible to parse the destination of the symlink in a way that does this..)
+
+> [[done]]; see [[tips/finding_duplicate_files]] --[[Joey]]
diff --git a/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_10_d78d79fb2f3713aa69f45d2691cf8dfe._comment b/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_10_d78d79fb2f3713aa69f45d2691cf8dfe._comment
new file mode 100644
index 000000000..5dbb66cf6
--- /dev/null
+++ b/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_10_d78d79fb2f3713aa69f45d2691cf8dfe._comment
@@ -0,0 +1,68 @@
+[[!comment format=mdwn
+ username="http://adamspiers.myopenid.com/"
+ nickname="Adam"
+ subject="comment 10"
+ date="2011-12-23T17:22:11Z"
+ content="""
+> Your perl script is not O(n). Inserting into perl hash tables has
+> overhead of minimum O(n log n).
+
+What's your source for this assertion? I would expect an amortized
+average of `O(1)` per insertion, i.e. `O(n)` for full population.
+
+> Not counting the overhead of resizing hash tables,
+> the grevious slowdown if the bucket size is overcome by data (it
+> probably falls back to a linked list or something then), and the
+> overhead of traversing the hash tables to get data out.
+
+None of which necessarily change the algorithmic complexity. However
+real benchmarks are far more useful here than complexity analysis, and
+[the dangers of premature optimization](http://c2.com/cgi/wiki?PrematureOptimization)
+should not be forgotten.
+
+> Your memory size calculations ignore the overhead of a hash table or
+> other data structure to store the data in, which will tend to be
+> more than the actual data size it's storing. I estimate your 50
+> million number is off by at least one order of magnitude, and more
+> likely two;
+
+Sure, I was aware of that, but my point still stands. Even 500k keys
+per 1GB of RAM does not sound expensive to me.
+
+> in any case I don't want git-annex to use 1 gb of ram.
+
+Why not? What's the maximum it should use? 512MB? 256MB?
+32MB? I don't see the sense in the author of a program
+dictating thresholds which are entirely dependent on the context
+in which the program is *run*, not the context in which it's *written*.
+That's why systems have files such as `/etc/security/limits.conf`.
+
+You said you want git-annex to scale to enormous repositories. If you
+impose an arbitrary memory restriction such as the above, that means
+avoiding implementing *any* kind of functionality which requires `O(n)`
+memory or worse. Isn't it reasonable to assume that many users use
+git-annex on repositories which are *not* enormous? Even when they do
+work with enormous repositories, just like with any other program,
+they would naturally expect certain operations to take longer or
+become impractical without sufficient RAM. That's why I say that this
+restriction amounts to throwing out the baby with the bathwater.
+It just means that those who need the functionality would have to
+reimplement it themselves, assuming they are able, which is likely
+to result in more wheel reinventions. I've already shared
+[my implementation](https://github.com/aspiers/git-config/blob/master/bin/git-annex-finddups)
+but how many people are likely to find it, let alone get it working?
+
+> Little known fact: sort(1) will use a temp file as a buffer if too
+> much memory is needed to hold the data to sort.
+
+Interesting. Presumably you are referring to some undocumented
+behaviour, rather than `--batch-size` which only applies when merging
+multiple files, and not when only sorting STDIN.
+
+> It's also written in the most efficient language possible and has
+> been ruthlessly optimised for 30 years, so I would be very surprised
+> if it was not the best choice.
+
+It's the best choice for sorting. But sorting purely to detect
+duplicates is a dismally bad choice.
+"""]]
diff --git a/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_11_4316d9d74312112dc4c823077af7febe._comment b/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_11_4316d9d74312112dc4c823077af7febe._comment
new file mode 100644
index 000000000..286487eee
--- /dev/null
+++ b/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_11_4316d9d74312112dc4c823077af7febe._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 11"
+ date="2011-12-23T17:52:21Z"
+ content="""
+I don't think that [[tips/finding_duplicate_files]] is hard to find, and the multiple different ways it shows to deal with the duplicate files shows the flexability of the unix pipeline approach.
+"""]]
diff --git a/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_12_ed6d07f16a11c6eee7e3d5005e8e6fa3._comment b/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_12_ed6d07f16a11c6eee7e3d5005e8e6fa3._comment
new file mode 100644
index 000000000..909beed83
--- /dev/null
+++ b/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_12_ed6d07f16a11c6eee7e3d5005e8e6fa3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 12"
+ date="2011-12-23T18:02:24Z"
+ content="""
+BTW, sort -S '90%' benchmarks consistently 2x as fast as perl's hashes all the way up to 1 million files. Of course the pipeline approach allows you to swap in perl or whatever else is best for you at scale.
+"""]]
diff --git a/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_1_fd213310ee548d8726791d2b02237fde._comment b/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_1_fd213310ee548d8726791d2b02237fde._comment
new file mode 100644
index 000000000..094e4526e
--- /dev/null
+++ b/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_1_fd213310ee548d8726791d2b02237fde._comment
@@ -0,0 +1,29 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-01-27T18:29:44Z"
+ content="""
+Hey Asheesh, I'm happy you're finding git-annex useful.
+
+So, there are two forms of duplication going on here. There's duplication of the content, and duplication of the filenames
+pointing at that content.
+
+Duplication of the filenames is probably not a concern, although it's what I thought you were talking about at first. It's probably info worth recording that backup-2010/some_dir/foo and backup-2009/other_dir/foo are two names you've used for the same content in the past. If you really wanted to remove backup-2009/foo, you could do it by writing a script that looks at the basenames of the symlink targets and removes files that point to the same content as other files.
+
+Using SHA1 ensures that the same key is used for identical files, so generally avoids duplication of content. But if you have 2 disks with an identical file on each, and make them both into annexes, then git-annex will happily retain both
+copies of the content, one per disk. It generally considers keeping copies of content a good thing. :)
+
+So, what if you want to remove the unnecessary copies? Well, there's a really simple way:
+
+<pre>
+cd /media/usb-1
+git remote add other-disk /media/usb-0
+git annex add
+git annex drop
+</pre>
+
+This asks git-annex to add everything to the annex, but then remove any file contents that it can safely remove. What can it safely remove? Well, anything that it can verify is on another repository such as \"other-disk\"! So, this will happily drop any duplicated file contents, while leaving all the rest alone.
+
+In practice, you might not want to have all your old backup disks mounted at the same time and configured as remotes. Look into configuring [[trust]] to avoid needing do to that. If usb-0 is already a trusted disk, all you need is a simple \"git annex drop\" on usb-1.
+"""]]
diff --git a/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_2_4394bde1c6fd44acae649baffe802775._comment b/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_2_4394bde1c6fd44acae649baffe802775._comment
new file mode 100644
index 000000000..04d58a459
--- /dev/null
+++ b/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_2_4394bde1c6fd44acae649baffe802775._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkjvjLHW9Omza7x1VEzIFQ8Z5honhRB90I"
+ nickname="Asheesh"
+ subject="I actually *do* want to avoid duplication of filenames"
+ date="2011-01-28T07:30:05Z"
+ content="""
+I really do want just one filename per file, at least for some cases.
+
+For my photos, there's no benefit to having a few filenames point to the same file. As I'm putting them all into the git-annex, that is a good time to remove the pure duplicates so that I don't e.g. see them twice when browsing the directory as a gallery. Also, I am uploading my photos to the web, and I want to avoid uploading the same photo (by content) twice.
+
+I hope that makes things clearer!
+
+For now I'm just doing this:
+
+* paulproteus@renaissance:/mnt/backups-terabyte/paulproteus/sd-card-from-2011-01-06/sd-cards/DCIM/100CANON $ for file in *; do hash=$(sha1sum \"$file\"); if ls /home/paulproteus/Photos/in-flickr/.git-annex | grep -q \"$hash\"; then echo already annexed ; else flickr_upload \"$file\" && mv \"$file\" \"/home/paulproteus/Photos/in-flickr/2011-01-28/from-some-nested-sd-card-bk\" && (cd /home/paulproteus/Photos/in-flickr/2011-01-28/from-some-nested-sd-card-bk && git annex add . && git commit -m ...) ; fi; done
+
+(Yeah, Flickr for my photos for now. I feel sad about betraying the principle of autonomo.us-ness.)
+"""]]
diff --git a/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_3_076cb22057583957d5179d8ba9004605._comment b/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_3_076cb22057583957d5179d8ba9004605._comment
new file mode 100644
index 000000000..d11119bc3
--- /dev/null
+++ b/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_3_076cb22057583957d5179d8ba9004605._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkjvjLHW9Omza7x1VEzIFQ8Z5honhRB90I"
+ nickname="Asheesh"
+ subject="Duplication of the filenames is what I am concerned about"
+ date="2011-04-29T11:48:22Z"
+ content="""
+For what it's worth, yes, I want to actually forget I ever had the same file in the filesystem with a duplicated name. I'm not just aiming to clean up the disk's space usage; I'm also aiming to clean things up so that navigating the filesystem is easier.
+
+I can write my own script to do that based on the symlinks' target (and I wrote something along those lines), but I still think it'd be nicer if git-annex supported this use case.
+
+Perhaps:
+
+<pre>git annex drop --by-contents</pre>
+
+could let me remove a file from git-annex if the contents are available through a different name. (Right now, \"git annex drop\" requires the name *and* contents match.)
+
+-- Asheesh.
+"""]]
diff --git a/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_4_f120d1e83c1a447f2ecce302fc69cf74._comment b/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_4_f120d1e83c1a447f2ecce302fc69cf74._comment
new file mode 100644
index 000000000..a218ee3d5
--- /dev/null
+++ b/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_4_f120d1e83c1a447f2ecce302fc69cf74._comment
@@ -0,0 +1,35 @@
+[[!comment format=mdwn
+ username="http://adamspiers.myopenid.com/"
+ nickname="Adam"
+ subject="List the duplicate filenames, then let the user decide what to do"
+ date="2011-12-22T12:31:29Z"
+ content="""
+I have the same use case as Asheesh but I want to be able to see which filenames point to the same objects and then decide which of the duplicates to drop myself. I think
+
+ git annex drop --by-contents
+
+would be the wrong approach because how does git-annex know which ones to drop? There's too much potential for error.
+
+Instead it would be great to have something like
+
+ git annex finddups
+
+While it's easy enough to knock up a bit of shell or Perl to achieve this, that relies on knowledge of the annex symlink structure, so I think really it belongs inside git-annex.
+
+If this command gave output similar to the excellent `fastdup` utility:
+
+ Scanning for files... 672 files in 10.439 seconds
+ Comparing 2 sets of files...
+
+ 2 files (70.71 MB/ea)
+ /home/adam/media/flat/tour/flat-tour.3gp
+ /home/adam/videos/tour.3gp
+
+ Found 1 duplicate of 1 file (70.71 MB wasted)
+ Scanned 672 files (1.96 GB) in 11.415 seconds
+
+then you could do stuff like
+
+ git annex finddups | grep /home/adam/media/flat | xargs rm
+
+"""]]
diff --git a/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_5_5c30294b3c59fdebb1eef0ae5da4cd4f._comment b/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_5_5c30294b3c59fdebb1eef0ae5da4cd4f._comment
new file mode 100644
index 000000000..e48a4a9b3
--- /dev/null
+++ b/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_5_5c30294b3c59fdebb1eef0ae5da4cd4f._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://adamspiers.myopenid.com/"
+ nickname="Adam"
+ subject="Here's a Perl version"
+ date="2011-12-22T15:43:51Z"
+ content="""
+https://github.com/aspiers/git-config/blob/master/bin/git-annex-finddups
+
+but it would be better in git-annex itself ...
+"""]]
diff --git a/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_6_f24541ada1c86d755acba7e9fa7cff24._comment b/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_6_f24541ada1c86d755acba7e9fa7cff24._comment
new file mode 100644
index 000000000..5d8ac8e61
--- /dev/null
+++ b/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_6_f24541ada1c86d755acba7e9fa7cff24._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 6"
+ date="2011-12-22T16:39:24Z"
+ content="""
+My main concern with putting this in git-annex is that finding duplicates necessarily involves storing a list of every key and file in the repository, and git-annex is very carefully built to avoid things that require non-constant memory use, so that it can scale to very big repositories. (The only exception is the `unused` command, and reducing its memory usage is a continuing goal.)
+
+So I would rather come at this from a different angle.. like providing a way to output a list of files and their associated keys, which the user can then use in their own shell pipelines to find duplicate keys:
+
+ git annex find --include '*' --format='${file} ${key}\n' | sort --key 2 | uniq --all-repeated --skip-fields=1
+
+Which is implemented now!
+
+(Making that pipeline properly handle filenames with spaces is left as an exercise for the reader..)
+"""]]
diff --git a/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_7_c39f1bb7c61a89b238c61bee1c049767._comment b/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_7_c39f1bb7c61a89b238c61bee1c049767._comment
new file mode 100644
index 000000000..a33700280
--- /dev/null
+++ b/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_7_c39f1bb7c61a89b238c61bee1c049767._comment
@@ -0,0 +1,54 @@
+[[!comment format=mdwn
+ username="http://adamspiers.myopenid.com/"
+ nickname="Adam"
+ subject="comment 7"
+ date="2011-12-22T20:04:14Z"
+ content="""
+> My main concern with putting this in git-annex is that finding
+> duplicates necessarily involves storing a list of every key and file
+> in the repository
+
+Only if you want to search the *whole* repository for duplicates, and if
+you do, then you're necessarily going to have to chew up memory in
+some process anyway, so what difference whether it's git-annex or
+(say) a Perl wrapper?
+
+> and git-annex is very carefully built to avoid things that require
+> non-constant memory use, so that it can scale to very big
+> repositories.
+
+That's a worthy goal, but if everything could be implemented with an
+O(1) memory footprint then we'd be in much more pleasant world :-)
+Even O(n) isn't that bad ...
+
+That aside, I like your `--format=\"%f %k\n\"` idea a lot. That opens
+up the \"black box\" of `.git/annex/objects` and makes nice things
+possible, as your pipeline already demonstrates. However, I'm not
+sure why you think `git annex find | sort | uniq` would be more
+efficient. Not only does the sort require the very thing you were
+trying to avoid (i.e. the whole list in memory), but it's also
+O(n log n) which is significantly slower than my O(n) Perl script
+linked above.
+
+More considerations about this pipeline:
+
+* Doesn't it only include locally available files? Ideally it should
+ spot duplicates even when the backing blob is not available locally.
+* What's the point of `--include '*'` ? Doesn't `git annex find`
+ with no arguments already include all files, modulo the requirement
+ above that they're locally available?
+* Any user using this `git annex find | ...` approach is likely to
+ run up against its limitations sooner rather than later, because
+ they're already used to the plethora of options `find(1)` provides.
+ Rather than reinventing the wheel, is there some way `git annex find`
+ could harness the power of `find(1)` ?
+
+Those considerations aside, a combined approach would be to implement
+
+ git annex find --format=...
+
+and then alter my Perl wrapper to `popen(2)` from that rather than using
+`File::Find`. But I doubt you would want to ship Perl wrappers in the
+distribution, so if you don't provide a Haskell equivalent then users
+who can't code are left high and dry.
+"""]]
diff --git a/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_8_221ed2e53420278072a6d879c6f251d1._comment b/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_8_221ed2e53420278072a6d879c6f251d1._comment
new file mode 100644
index 000000000..5ac292afe
--- /dev/null
+++ b/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_8_221ed2e53420278072a6d879c6f251d1._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://adamspiers.myopenid.com/"
+ nickname="Adam"
+ subject="How much memory would it actually use anyway?"
+ date="2011-12-22T20:15:22Z"
+ content="""
+Another thought - an SHA1 digest is 20 bytes. That means you can fit over 50 million keys into 1GB of RAM. Granted you also need memory to store the values (pathnames) which in many cases will be longer, and some users may also choose more expensive backends than SHA1 ... but even so, it seems to me that you are at risk of throwing the baby out with the bath water.
+"""]]
diff --git a/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_9_aecfa896c97b9448f235bce18a40621d._comment b/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_9_aecfa896c97b9448f235bce18a40621d._comment
new file mode 100644
index 000000000..82c6921eb
--- /dev/null
+++ b/doc/todo/wishlist:_Provide_a___34__git_annex__34___command_that_will_skip_duplicates/comment_9_aecfa896c97b9448f235bce18a40621d._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 9"
+ date="2011-12-23T16:07:39Z"
+ content="""
+Adam, to answer a lot of points breifly..
+
+* --include='*' makes find list files whether their contents are present or not
+* Your perl script is not O(n). Inserting into perl hash tables has overhead of minimum O(n log n). Not counting the overhead of resizing hash tables, the grevious slowdown if the bucket size is overcome by data (it probably falls back to a linked list or something then), and the overhead of traversing the hash tables to get data out.
+* I think that git-annex's set of file matching options is coming along nicely, and new ones can easily be added, so see no need to pull in unix find(1).
+* Your memory size calculations ignore the overhead of a hash table or other data structure to store the data in, which will tend to be more than the actual data size it's storing. I estimate your 50 million number is off by at least one order of magnitude, and more likely two; in any case I don't want git-annex to use 1 gb of ram.
+* Little known fact: sort(1) will use a temp file as a buffer if too much memory is needed to hold the data to sort. It's also written in the most efficient language possible and has been ruthlessly optimised for 30 years, so I would be very surprised if it was not the best choice.
+"""]]
diff --git a/doc/todo/wishlist:_Restore_s3_files_moved_to_Glacier.mdwn b/doc/todo/wishlist:_Restore_s3_files_moved_to_Glacier.mdwn
new file mode 100644
index 000000000..85fc2785c
--- /dev/null
+++ b/doc/todo/wishlist:_Restore_s3_files_moved_to_Glacier.mdwn
@@ -0,0 +1,7 @@
+I would like to use the automated AWS lifecycle rules to move the git annex files store on S3 to Glacier after a bit of time. Git annex need must support this kind of S3 files explicitly in order for it to work.
+
+This is different from the adding a Glacier remote to git annex because of the reasons explained in <http://aws.typepad.com/aws/2012/11/archive-s3-to-glacier.html>.
+
+Basically, the files moved by AWS from S3 to Glacier are not available under the normal Glacier API. In fact, the moved S3 files are listed as available but under the `GLACIER` storage class and need a RESTORE request before they can be GET like other S3 files. Trying to GET an S3 file that has been moved to Glacier will not restore it from Glacier and will result in an 403 error.
+
+I suppose DELETE needs special care as well.
diff --git a/doc/todo/wishlist:_Tell_git_annex___40__assistant__41___which_files___40__not__41___to_annex_via_.gitattributes.mdwn b/doc/todo/wishlist:_Tell_git_annex___40__assistant__41___which_files___40__not__41___to_annex_via_.gitattributes.mdwn
new file mode 100644
index 000000000..f65a95f45
--- /dev/null
+++ b/doc/todo/wishlist:_Tell_git_annex___40__assistant__41___which_files___40__not__41___to_annex_via_.gitattributes.mdwn
@@ -0,0 +1,9 @@
+Title says it all.
+
+It would be nice if I could tell git annex (assistant) which files (not) to annex (automatically).
+
+[[!tag /design/assistant]]
+
+> [[done]]; use `annex.largefiles` git config to configure criteria for
+> which files should be annexed. The rest will be added to git as normal
+> files. --[[Joey]]
diff --git a/doc/todo/wishlist:___34__git_annex_add__34___multiple_processes.mdwn b/doc/todo/wishlist:___34__git_annex_add__34___multiple_processes.mdwn
new file mode 100644
index 000000000..a04af05b4
--- /dev/null
+++ b/doc/todo/wishlist:___34__git_annex_add__34___multiple_processes.mdwn
@@ -0,0 +1,10 @@
+Hello,
+
+i'm in the process of managing my music collection with git-annex. The initial "git annex add" using the sha1 banckend is quite long an i was wondering that it could be nice to launch multiple "sha1sum" processes in parallel to speed up things.
+
+Anyway, thanks for this wonderful piece of software.
+
+Jean-Baptiste
+
+> closing as dup of [[parallel possibilities]] (also see comments below)
+> [[done]] --[[Joey]]
diff --git a/doc/todo/wishlist:___34__git_annex_add__34___multiple_processes/comment_1_85b14478411a33e6186a64bd41f0910d._comment b/doc/todo/wishlist:___34__git_annex_add__34___multiple_processes/comment_1_85b14478411a33e6186a64bd41f0910d._comment
new file mode 100644
index 000000000..2364b7fb8
--- /dev/null
+++ b/doc/todo/wishlist:___34__git_annex_add__34___multiple_processes/comment_1_85b14478411a33e6186a64bd41f0910d._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-02-25T19:12:42Z"
+ content="""
+I'd expect the checksumming to be disk bound, not CPU bound, on most systems.
+
+I suggest you start off on the WORM backend, and then you can run a job later to [[migrate|walkthrough#index14h2]] to the SHA1 backend.
+"""]]
diff --git a/doc/todo/wishlist:___34__git_annex_add__34___multiple_processes/comment_2_82e857f463cfdf73c70f6c0a9f9a31d6._comment b/doc/todo/wishlist:___34__git_annex_add__34___multiple_processes/comment_2_82e857f463cfdf73c70f6c0a9f9a31d6._comment
new file mode 100644
index 000000000..9b8240658
--- /dev/null
+++ b/doc/todo/wishlist:___34__git_annex_add__34___multiple_processes/comment_2_82e857f463cfdf73c70f6c0a9f9a31d6._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 2"
+ date="2011-02-25T19:54:28Z"
+ content="""
+But, see [[todo/parallel_possibilities]]
+"""]]
diff --git a/doc/todo/wishlist:___34__git_annex_add__34___multiple_processes/comment_3_8af85eba7472d9025c6fae4f03e3ad75._comment b/doc/todo/wishlist:___34__git_annex_add__34___multiple_processes/comment_3_8af85eba7472d9025c6fae4f03e3ad75._comment
new file mode 100644
index 000000000..ee769f0dd
--- /dev/null
+++ b/doc/todo/wishlist:___34__git_annex_add__34___multiple_processes/comment_3_8af85eba7472d9025c6fae4f03e3ad75._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="jbd"
+ ip="89.158.228.148"
+ subject="comment 3"
+ date="2011-02-26T10:26:12Z"
+ content="""
+Thank your for your answer and the link !
+"""]]
diff --git a/doc/todo/wishlist:___34__quiet__34___annex_get_for_centralized_use_case.mdwn b/doc/todo/wishlist:___34__quiet__34___annex_get_for_centralized_use_case.mdwn
new file mode 100644
index 000000000..d53fa56ab
--- /dev/null
+++ b/doc/todo/wishlist:___34__quiet__34___annex_get_for_centralized_use_case.mdwn
@@ -0,0 +1,14 @@
+We're using git-annex to manage large files as part of a team.
+
+We have a central repository of large files that everyone grabs from.
+
+We would like to be able to get the files without updating the `git-annex` branch. This way it doesn't pollute the history with essentially always unreachable locations.
+
+I think the easiest way would be to just add an option to not update the `git-annex` branch when `annex get` is executed.
+
+Thoughts?
+
+> See [[untracked_remotes]] for a todo item that will probably
+> be useful in this sitation. Since that describes better what
+> this bug report seems to be asking for, I am closing this one.
+> [[closed|done]] --[[Joey]]
diff --git a/doc/todo/wishlist:___34__quiet__34___annex_get_for_centralized_use_case/comment_1_5c8812973cf91b046e7fc44d7e86c78e._comment b/doc/todo/wishlist:___34__quiet__34___annex_get_for_centralized_use_case/comment_1_5c8812973cf91b046e7fc44d7e86c78e._comment
new file mode 100644
index 000000000..61d82e2ae
--- /dev/null
+++ b/doc/todo/wishlist:___34__quiet__34___annex_get_for_centralized_use_case/comment_1_5c8812973cf91b046e7fc44d7e86c78e._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.48"
+ subject="comment 1"
+ date="2013-07-17T23:23:50Z"
+ content="""
+I'm interested to hear that your team is using git-annex.
+
+Have you tried `git config annex.alwayscommit false`? This will avoid committing, and just store the info in a local journal -- so even `git annex fsck` will still work.
+
+Hmm, perhaps you want to update the branch when running `git annex copy` to put files onto the server, but not when getting them? A switch to disable updating the branch would then make sense. Any use of fsck would notice the inconsistency though, and commit a fix to the git-annex branch -- unless you also used the new switch when running fsck.
+
+But what happens if someone makes a change, pushes to the server, but forgets to `git annex copy` the file? Everyone would then be left with a missing file that git annex doesn't know where it is. One of the reasons it tracks the locations is so that if necessary you know which repository such a misplaced fail is stored in. And can go track down that person's laptop and apply a cluebat. ;) Do you do something on the server to prevent this scenario?
+"""]]
diff --git a/doc/todo/wishlist:___34__quiet__34___annex_get_for_centralized_use_case/comment_2_f36b6a5b128423211aac91a252ecf85f._comment b/doc/todo/wishlist:___34__quiet__34___annex_get_for_centralized_use_case/comment_2_f36b6a5b128423211aac91a252ecf85f._comment
new file mode 100644
index 000000000..3379742d2
--- /dev/null
+++ b/doc/todo/wishlist:___34__quiet__34___annex_get_for_centralized_use_case/comment_2_f36b6a5b128423211aac91a252ecf85f._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="http://caust1c.myopenid.com/"
+ nickname="asbraithwaite"
+ subject="comment 2"
+ date="2013-07-17T23:42:25Z"
+ content="""
+What would happen if we wanted to copy a file to the server
+with that set? or even when running `git annex add`
+You understood me exactly though.
+We'd like to be able to get the files without a commit, but copy them
+with a commit of the changes.
+The way we operate, if somebody makes a change with regards to
+largefiles, they should also add a test for it.
+Ideally, the test suite would catch it. That or people would
+realize that theres a new big file and send around an email to
+see who was trying to a largefile when they couldn't reach it.
+
+"""]]
diff --git a/doc/todo/wishlist:___34__quiet__34___annex_get_for_centralized_use_case/comment_3_ad1569b2405acacd2e37f42b82f24c88._comment b/doc/todo/wishlist:___34__quiet__34___annex_get_for_centralized_use_case/comment_3_ad1569b2405acacd2e37f42b82f24c88._comment
new file mode 100644
index 000000000..14ab5f65a
--- /dev/null
+++ b/doc/todo/wishlist:___34__quiet__34___annex_get_for_centralized_use_case/comment_3_ad1569b2405acacd2e37f42b82f24c88._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.48"
+ subject="comment 3"
+ date="2013-07-18T00:12:39Z"
+ content="""
+Actually, when a file is sent to a git repository on the server, it will update the location log on that side. So even if the client has alwayscommit=false, other clients will learn the file has reached the server.
+
+So that might just work for you.
+"""]]
diff --git a/doc/todo/wishlist:___34__quiet__34___annex_get_for_centralized_use_case/comment_4_8aba90150fe178ce9712ad951628f3d6._comment b/doc/todo/wishlist:___34__quiet__34___annex_get_for_centralized_use_case/comment_4_8aba90150fe178ce9712ad951628f3d6._comment
new file mode 100644
index 000000000..c1f148fdb
--- /dev/null
+++ b/doc/todo/wishlist:___34__quiet__34___annex_get_for_centralized_use_case/comment_4_8aba90150fe178ce9712ad951628f3d6._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawln3ckqKx0x_xDZMYwa9Q1bn4I06oWjkog"
+ nickname="Michael"
+ subject="comment 4"
+ date="2013-07-18T18:03:00Z"
+ content="""
+If you can have developers only add large files on the central server, avoiding using git annex sync and only pulling from git repo should work, I think.
+"""]]
diff --git a/doc/todo/wishlist:___34__quiet__34___annex_get_for_centralized_use_case/comment_5_6f42d240e0021f4dfa37146bea3f5d7e._comment b/doc/todo/wishlist:___34__quiet__34___annex_get_for_centralized_use_case/comment_5_6f42d240e0021f4dfa37146bea3f5d7e._comment
new file mode 100644
index 000000000..aa547d790
--- /dev/null
+++ b/doc/todo/wishlist:___34__quiet__34___annex_get_for_centralized_use_case/comment_5_6f42d240e0021f4dfa37146bea3f5d7e._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://caust1c.myopenid.com/"
+ nickname="asbraithwaite"
+ subject="comment 5"
+ date="2013-07-18T21:17:45Z"
+ content="""
+Wow. This worked better than expected. I'm still trying to understand the implementation (I'm not familiar with Haskell), but there is some magic going on.
+
+To explain:
+
+I didn't expect that when I added a file (Locally and to the annex remote) that when somebody else did a pull, git-annex would recognize this and update the working copy to download and include that file.
+
+I'm not sure if this is intended behavior or not (since I thought all commands had to go through git-annex) but I like it nonetheless.
+
+Thanks again for the tips!
+"""]]
diff --git a/doc/todo/wishlist:___34__quiet__34___annex_get_for_centralized_use_case/comment_6_5fda455febf728b079f26fe42bf7bcab._comment b/doc/todo/wishlist:___34__quiet__34___annex_get_for_centralized_use_case/comment_6_5fda455febf728b079f26fe42bf7bcab._comment
new file mode 100644
index 000000000..3f10e48ad
--- /dev/null
+++ b/doc/todo/wishlist:___34__quiet__34___annex_get_for_centralized_use_case/comment_6_5fda455febf728b079f26fe42bf7bcab._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://caust1c.myopenid.com/"
+ nickname="asbraithwaite"
+ subject="comment 6"
+ date="2013-07-18T21:23:58Z"
+ content="""
+Disregard that. I was testing it with a particular file that didn't exactly play nice.
+
+Basically, to test this before production I used `dd bs=1024 count=100000 if=/dev/zero of=bigfile`.
+
+When I did a `git pull`, it showed the symlink as being valid.
+
+When I changed the command to `dd bs=1024 count=100000 if=/dev/urandom of=bigfile` then it showed the symlink as bad after pulling.
+
+Weird!
+"""]]
diff --git a/doc/todo/wishlist:___34__quiet__34___annex_get_for_centralized_use_case/comment_7_f1052ab997f1a2cccbabfd1533fc0a59._comment b/doc/todo/wishlist:___34__quiet__34___annex_get_for_centralized_use_case/comment_7_f1052ab997f1a2cccbabfd1533fc0a59._comment
new file mode 100644
index 000000000..deb25a9ce
--- /dev/null
+++ b/doc/todo/wishlist:___34__quiet__34___annex_get_for_centralized_use_case/comment_7_f1052ab997f1a2cccbabfd1533fc0a59._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawln3ckqKx0x_xDZMYwa9Q1bn4I06oWjkog"
+ nickname="Michael"
+ subject="comment 7"
+ date="2013-07-18T21:48:06Z"
+ content="""
+If you wanted to auto-get files on git pull, you could trying putting git annex get into .git/hooks/post-merge (needs to be marked as executable).
+"""]]
diff --git a/doc/todo/wishlist:___34__quiet__34___annex_get_for_centralized_use_case/comment_8_07804647b6023436878756bd97a23f32._comment b/doc/todo/wishlist:___34__quiet__34___annex_get_for_centralized_use_case/comment_8_07804647b6023436878756bd97a23f32._comment
new file mode 100644
index 000000000..4901a2d97
--- /dev/null
+++ b/doc/todo/wishlist:___34__quiet__34___annex_get_for_centralized_use_case/comment_8_07804647b6023436878756bd97a23f32._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.140"
+ subject="comment 8"
+ date="2013-07-20T20:07:53Z"
+ content="""
+`dd bs=1024 count=100000 if=/dev/zero of=bigfile` obviously creates the same data each time, so if that same size empty file has previously been in a repository, and the content is still present there, the symlink will automatically point to it when it gets added. In other words, git-annex performs automatic deduplication of file contents, and so it was able to save you a download in this case.
+"""]]
diff --git a/doc/todo/wishlist:___39__get__39___queue_and_schedule..mdwn b/doc/todo/wishlist:___39__get__39___queue_and_schedule..mdwn
new file mode 100644
index 000000000..8919bae3f
--- /dev/null
+++ b/doc/todo/wishlist:___39__get__39___queue_and_schedule..mdwn
@@ -0,0 +1,30 @@
+During the campaign adding a chunking feature to obscure filesize for encrypted files was added to the roadmap. But there is still one potentially valuable set* of data that git-annex can help obscure: when you access your remotes.
+
+This data can be used to determine when a user is actively using a remote, but if a remote is always accessed at the same time that data becomes less useful. Somebody could still monitor total traffic over a long period and figure out that a remote was more active in a given week or month, but scheduling reduces the resolution of your access times and their data. Maybe this isn't the most important feature to add, but it would be nice to have, and could possibly be built on top of the existing git-annex scheduler. It could work by queuing inter-remote transactions ('get', 'copy', 'sync', etc.), so that jobs start at the same time every day, or even the same time and day every week.
+
+Possible syntax examples:
+###Setting up the schedule:
+git annex queue schedule Monday:1730 (starts every monday at 5:30PM)
+
+git annex queue schedule 1400 (starts every day at 2PM)
+
+###Queuing git-annex commands:
+git annex queue prepend sync (pretends 'sync' to the very front of the queue)
+
+git annex queue append get file.ISO (appends to queue file.ISO for retrieval from a repo)
+
+###Viewing/editing queue:
+git annex queue view (view the current queue, jobs displayed with corresponding numbers)
+
+git annex queue rm 20 (removes job 20 from queue)
+
+
+\*The four I can think of are:
+
+* File contents (solved by crypto)
+
+* File size (solved on the remote by chunking, but total traffic usage can't be helped)
+
+* User IP/Remote IP (solved by VPN - outside scope of git-annex, unless someone writes a plugin)
+
+* Access times (obscured by a queue and scheduling)
diff --git a/doc/todo/wishlist:___39__whereis__39___support_in_the_webapp.mdwn b/doc/todo/wishlist:___39__whereis__39___support_in_the_webapp.mdwn
new file mode 100644
index 000000000..c074988b0
--- /dev/null
+++ b/doc/todo/wishlist:___39__whereis__39___support_in_the_webapp.mdwn
@@ -0,0 +1,4 @@
+I've looked for this feature in the webapp but can't find it...
+
+I mainly use the webapp and have been wondering 'how many copies of file X are there' and 'where are the copies of file Y'?
+This is available in the commandline interface but it would be nice to have this in the webapp too.
diff --git a/doc/todo/wishlist:___96__git_annex_drop_--relaxed__96__.mdwn b/doc/todo/wishlist:___96__git_annex_drop_--relaxed__96__.mdwn
new file mode 100644
index 000000000..626f5a03f
--- /dev/null
+++ b/doc/todo/wishlist:___96__git_annex_drop_--relaxed__96__.mdwn
@@ -0,0 +1,5 @@
+Also suggested during the first Gitify BoF during DebConf13:
+
+`git annex drop` deletes immediately. In some situations a mechanism to tell git-annex "I would like to hold onto this data if possible, but if you need the space, please delete it" could be nice.
+
+An obvious question would be how to do cleanups. With the assistant, that's easy. On CLI, at the very least `git annex fsck` should list, and optionally delete, that data.
diff --git a/doc/todo/wishlist:___96__git_annex_drop_--relaxed__96__/comment_1_c83a6cddd0ce222205a149cfa41ca395._comment b/doc/todo/wishlist:___96__git_annex_drop_--relaxed__96__/comment_1_c83a6cddd0ce222205a149cfa41ca395._comment
new file mode 100644
index 000000000..32d0c0112
--- /dev/null
+++ b/doc/todo/wishlist:___96__git_annex_drop_--relaxed__96__/comment_1_c83a6cddd0ce222205a149cfa41ca395._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://cstork.org/"
+ nickname="Chris Stork"
+ subject="How should this interact with the trust model and location tracking?"
+ date="2013-10-04T11:13:11Z"
+ content="""
+This could become complicated. AFAIU, right now git-annex keeps track of files as either present or absent. With this feature it's tempting to introduce a third state 'potentially dropped' (or 'dropped in a relaxed fashion') but do you then treat them as if they were dropped depending in wether they are on a trusted or untrusted repo? Or maybe a potentially dropped file in a trusted repo is treated as a file in a semitrusted repo? This becomes convoluted. You also need a command to undrop a file in case you decide that you really want to keep it and in order to do this you need a command to see which files are up for relaxed dropping....
+
+As an alternative approach maybe it makes sense to extend [[preferred content]] expressions to take file sizes and disk usage into account.
+"""]]
diff --git a/doc/todo/wishlist:___96__git_annex_drop_--relaxed__96__/comment_2_353fbc2bcc40cb8c9af42907a34c6e5a._comment b/doc/todo/wishlist:___96__git_annex_drop_--relaxed__96__/comment_2_353fbc2bcc40cb8c9af42907a34c6e5a._comment
new file mode 100644
index 000000000..40f299fa0
--- /dev/null
+++ b/doc/todo/wishlist:___96__git_annex_drop_--relaxed__96__/comment_2_353fbc2bcc40cb8c9af42907a34c6e5a._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.243"
+ subject="comment 2"
+ date="2013-10-04T20:17:07Z"
+ content="""
+I don't think that a third state would be necessary. Actually dropping the file when it happens would need to do the same numcopies verification that `git annex drop` does now.
+
+I agree it might be simpler to first improve the power of preferred content expressions. Unfortunately one thing that cannot be put in them is anything that probes the current state of the system. This is because repo A on machine X needs to be able to calculate the preferred content of repo B on machine Y.
+But I could certainly add file size as a preferred content term, since that info is known throughout the network.
+"""]]
diff --git a/doc/todo/wishlist:___96__git_annex_fsck_--checksums__96___--_verify_checksums_but_disregard_annex.numcopies.mdwn b/doc/todo/wishlist:___96__git_annex_fsck_--checksums__96___--_verify_checksums_but_disregard_annex.numcopies.mdwn
new file mode 100644
index 000000000..67a7e13e1
--- /dev/null
+++ b/doc/todo/wishlist:___96__git_annex_fsck_--checksums__96___--_verify_checksums_but_disregard_annex.numcopies.mdwn
@@ -0,0 +1,12 @@
+As the title says, I would like to see an option where git-annex verifies
+that all checksums are OK but not that the required number of copies or
+other possible metrics are fulfilled.
+
+-- RichiH
+
+> --numcopies is provided for times when you want to temporarily override
+> annex.numcopies. So, `git annex fsck --numcopies=0`
+>
+> I don't see any reason to want to disable the other checks and fixups
+> fsck does (of bad location log data, for example). So, [[done]]
+> --[[Joey]]
diff --git a/doc/todo/wishlist:___96__git_annex_fsck_--checksums__96___--_verify_checksums_but_disregard_annex.numcopies/comment_1_6bcf067e4860bdfeb1d7b9fd1702a43a._comment b/doc/todo/wishlist:___96__git_annex_fsck_--checksums__96___--_verify_checksums_but_disregard_annex.numcopies/comment_1_6bcf067e4860bdfeb1d7b9fd1702a43a._comment
new file mode 100644
index 000000000..c8f40caf7
--- /dev/null
+++ b/doc/todo/wishlist:___96__git_annex_fsck_--checksums__96___--_verify_checksums_but_disregard_annex.numcopies/comment_1_6bcf067e4860bdfeb1d7b9fd1702a43a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 1"
+ date="2013-07-10T23:09:31Z"
+ content="""
+As a side note, --numcopies was broken, but it's been fixed with 4.20130709.
+"""]]
diff --git a/doc/todo/wishlist:___96__git_annex_import__96___--_An_easy_way_to_get_data_into_an_annex.mdwn b/doc/todo/wishlist:___96__git_annex_import__96___--_An_easy_way_to_get_data_into_an_annex.mdwn
new file mode 100644
index 000000000..cd679485b
--- /dev/null
+++ b/doc/todo/wishlist:___96__git_annex_import__96___--_An_easy_way_to_get_data_into_an_annex.mdwn
@@ -0,0 +1,13 @@
+`git annex import` would copy data over from external places into the annex. It would be run from within the annex and in the target location where the files need to end up.
+
+Two basic modes of operation:
+
+* If run on a normal directory, e.g. an SD card, it would simply copy over and `git annex add $newstuff`
+
+* If run on another indirect annex, it would copy over the symlinks, copy over the object data, verify that the checksums are OK and add to the annex
+
+An optional `git annex import --copy-only` would copy over and verify the data, but not yet add it. That would allow the user to import into a decent data structure. If run on non-annexed data, `git annex import --copy-only` would ideally calculate checksums and create symlinks already; thus ensuring data integrity as early as possible.
+
+-- RichiH
+
+> [[done]] --[[Joey]] in 2012
diff --git a/doc/todo/wishlist:___96__git_annex_import__96___--_An_easy_way_to_get_data_into_an_annex/comment_1_b9fd1bfaf9a3d238fdb7bc9c2d75fe5f._comment b/doc/todo/wishlist:___96__git_annex_import__96___--_An_easy_way_to_get_data_into_an_annex/comment_1_b9fd1bfaf9a3d238fdb7bc9c2d75fe5f._comment
new file mode 100644
index 000000000..ff9030c99
--- /dev/null
+++ b/doc/todo/wishlist:___96__git_annex_import__96___--_An_easy_way_to_get_data_into_an_annex/comment_1_b9fd1bfaf9a3d238fdb7bc9c2d75fe5f._comment
@@ -0,0 +1,22 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.254.222"
+ subject="comment 1"
+ date="2013-07-07T18:09:20Z"
+ content="""
+This is such a good idea that I went into the time machine and arranged for it to be implemented in June 2012:
+
+<pre>
+ import [path ...]
+ Moves files from somewhere outside the git work‐
+ ing copy, and adds them to the annex. Individual
+ files to import can be specified. If a direc‐
+ tory is specified, all files in it are imported,
+ and any subdirectory structure inside it is pre‐
+ served.
+
+ git annex import /media/camera/DCIM/
+</pre>
+
+I don't see much use for `--copy-only` though. so did not implement it them (also I needed to spend some of my time at the race track). It seems to me that using `--copy-only` as you describe it would do everything except for add the files to git. You can get the same behavior by using `git annex import`, which only stages the new files but does not commit them, and then moving files around and running `git annex add` on them, followed by committing.
+"""]]
diff --git a/doc/todo/wishlist:___96__git_annex_import__96___--_An_easy_way_to_get_data_into_an_annex/comment_2_56f6972413c6f0d9f414245b6f4d27b9._comment b/doc/todo/wishlist:___96__git_annex_import__96___--_An_easy_way_to_get_data_into_an_annex/comment_2_56f6972413c6f0d9f414245b6f4d27b9._comment
new file mode 100644
index 000000000..ccdf2e704
--- /dev/null
+++ b/doc/todo/wishlist:___96__git_annex_import__96___--_An_easy_way_to_get_data_into_an_annex/comment_2_56f6972413c6f0d9f414245b6f4d27b9._comment
@@ -0,0 +1,62 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 2"
+ date="2013-07-10T23:25:52Z"
+ content="""
+Ugh, learn to read, etc...
+
+It's not possible to import from other annexes, though. Importing just the files from an indirect repo does nothing:
+
+ ~/test-annex--foo % git annex status
+ supported backends: SHA256E SHA1E SHA512E SHA224E SHA384E SHA256 SHA1 SHA512 SHA224 SHA384 WORM URL
+ supported remote types: git S3 bup directory rsync web webdav glacier hook
+ repository mode: indirect
+ trusted repositories: 0
+ semitrusted repositories: 2
+ 00000000-0000-0000-0000-000000000001 -- web
+ 8105410b-d8ca-4de4-bb6a-91b9772250dc -- here (richih@adamantium:~/test-annex--foo)
+ untrusted repositories: 0
+ transfers in progress: none
+ available local disk space: 52 gigabytes (+1 megabyte reserved)
+ local annex keys: 1
+ local annex size: 4 bytes
+ known annex keys: 1
+ known annex size: 4 bytes
+ bloom filter size: 16 mebibytes (0% full)
+ backend usage:
+ SHA256E: 2
+ ~/test-annex--foo % ls -l
+ total 4
+ lrwxrwxrwx 1 richih richih 178 Jul 11 01:21 bar -> .git/annex/objects/g7/9v/SHA256E-s4--7d865e959b2466918c9863afca942d0fb89d7c9ac0c99bafc3749504ded97730/SHA256E-s4--7d865e959b2466918c9863afca942d0fb89d7c9ac0c99bafc3749504ded97730
+ ~/test-annex--foo % cd ../test-annex
+ ~/test-annex % git annex status
+ supported backends: SHA256E SHA1E SHA512E SHA224E SHA384E SHA256 SHA1 SHA512 SHA224 SHA384 WORM URL
+ supported remote types: git S3 bup directory rsync web webdav glacier hook
+ repository mode: indirect
+ trusted repositories: (merging synced/git-annex into git-annex...)
+ 0
+ semitrusted repositories: 3
+ 00000000-0000-0000-0000-000000000001 -- web
+ 7c50da8c-dc76-4b4a-b46d-8dd16385691a -- here (richih@adamantium:~/test-annex)
+ d4104a13-a2eb-4f5c-ba54-990ece5c81df -- richih@adamantium:~/test-annex-2
+ untrusted repositories: 0
+ transfers in progress: none
+ available local disk space: 52 gigabytes (+1 megabyte reserved)
+ local annex keys: 1
+ local annex size: 4 bytes
+ known annex keys: 1
+ known annex size: 4 bytes
+ bloom filter size: 16 mebibytes (0% full)
+ backend usage:
+ SHA256E: 2
+ ~/test-annex % ls -l
+ total 4
+ lrwxrwxrwx 1 richih richih 178 Jul 11 01:20 foo -> .git/annex/objects/91/9x/SHA256E-s4--b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c/SHA256E-s4--b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c
+ ~/test-annex % git annex import ../test-annex--foo/bar
+ ~/test-annex % ls -l
+ total 4
+ lrwxrwxrwx 1 richih richih 178 Jul 11 01:20 foo -> .git/annex/objects/91/9x/SHA256E-s4--b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c/SHA256E-s4--b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c
+ ~/test-annex %
+
+"""]]
diff --git a/doc/todo/wishlist:___96__git_annex_import__96___--_An_easy_way_to_get_data_into_an_annex/comment_3_2c094bef802a2182de4fcd0def1ad29b._comment b/doc/todo/wishlist:___96__git_annex_import__96___--_An_easy_way_to_get_data_into_an_annex/comment_3_2c094bef802a2182de4fcd0def1ad29b._comment
new file mode 100644
index 000000000..d3870e7c9
--- /dev/null
+++ b/doc/todo/wishlist:___96__git_annex_import__96___--_An_easy_way_to_get_data_into_an_annex/comment_3_2c094bef802a2182de4fcd0def1ad29b._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 3"
+ date="2013-07-11T11:54:25Z"
+ content="""
+To expand on this a bit:
+
+* I meant \"ugh, me\" not \"ugh, anyone else\"; I simply did not see it...
+* `git annex import` on a separate annex should copy over the symlinks and the objects behind it and then run `git annex add`, thus verifying, fixing symlinks, etc, imo.
+* Something that may not be said often enough: Thanks :)
+"""]]
diff --git a/doc/todo/wishlist:___96__git_annex_import__96___--_An_easy_way_to_get_data_into_an_annex/comment_4_14915c43001f7f72c9fe5119a104ef5c._comment b/doc/todo/wishlist:___96__git_annex_import__96___--_An_easy_way_to_get_data_into_an_annex/comment_4_14915c43001f7f72c9fe5119a104ef5c._comment
new file mode 100644
index 000000000..4d4c1fbc5
--- /dev/null
+++ b/doc/todo/wishlist:___96__git_annex_import__96___--_An_easy_way_to_get_data_into_an_annex/comment_4_14915c43001f7f72c9fe5119a104ef5c._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 4"
+ date="2013-07-13T15:25:56Z"
+ content="""
+After more deliberation, there should probably be an option to not have `git annex import` run `git annex add` automagically (but still call `git annex fix`) so manual shuffling around of files is still possible.
+
+See [[doc/bugs/__96__git_annex_fix__96___run_on_non-annexed_files_is_no-op]] for more of the rationale on this.
+"""]]
diff --git a/doc/todo/wishlist:___96__git_annex_sync_-m__96__.mdwn b/doc/todo/wishlist:___96__git_annex_sync_-m__96__.mdwn
new file mode 100644
index 000000000..92b5dee27
--- /dev/null
+++ b/doc/todo/wishlist:___96__git_annex_sync_-m__96__.mdwn
@@ -0,0 +1,10 @@
+Similar to how
+
+ git commit -m 'foo'
+
+works, if I run
+
+ git annex sync -m 'my hovercraft is full of eels'
+
+git annex should use that commit message instead of the default ones. That way, I could use [[sync]] directly and not be forced to commit prior to syncing just to make sure I have a useful commit message.
+
diff --git a/doc/todo/wishlist:_a_spec.remote_for_network_directories_that_would_mount_them_whenever_needed___40__e.g.__44___with_WebDAV__41__.mdwn b/doc/todo/wishlist:_a_spec.remote_for_network_directories_that_would_mount_them_whenever_needed___40__e.g.__44___with_WebDAV__41__.mdwn
new file mode 100644
index 000000000..f2c4254ad
--- /dev/null
+++ b/doc/todo/wishlist:_a_spec.remote_for_network_directories_that_would_mount_them_whenever_needed___40__e.g.__44___with_WebDAV__41__.mdwn
@@ -0,0 +1,25 @@
+I've seen the [[tips/using box.com as a special remote]] for using mounted WebDAV remote directory for storage of the tracked files.
+
+It's quite close to a scenario familiar to me, although with a difference.
+
+Let me describe my situation.
+
+I worked on a supplement to a set of textbooks. My work was dependent on the revision of the textbooks (for correct references, etc.). The textbooks were being edited by the author, and published in a WebDAV directory.
+
+So I set up a Git repo for my work, and also a branch to track the revisions of the textbooks which [I updated by copying them from the WebDAV directory (after mounting it)](http://unix.stackexchange.com/q/25015/4319). The branch where my work was in was either based on the textbooks branch (and rebased/merged and edited to reflect the changes in the new revisions of the textbooks when needed) or contained the repo with textbooks as a submodule.
+
+The textbooks were large files, so I didn't want them be a part of the Git repo with my supplement work when I publish the repo. But I wanted for those who looked into my public repo to understand how to get the textbooks I'm referring to.
+
+I haven't solved this problem for myself completely. Now I see I could use git-annex for this. I t would track the state of the textbooks in the repo, without actually storing them there, and whenever one would need to get the missing textbooks in a clone of the repo, git-annex could handle the download from the WebDAV directory for him, right?
+
+I simply wrote down the rules for reproducing these downloading and saving operations, together with source URL (as a [Makefile](https://gitorious.org/primary-school-informatics-problems/received_2011-11-mathinf-initial-edition/blobs/RULES/Makefile)):
+
+whenever I wanted to update the revisions of the textbooks (or to download them the first time), I would checkout the branch which included this Makefile and was for holding the textbooks, and the run:
+
+ make get
+
+-- this target had the temporary mountpoint for the remote directory as prerequisite, and there was a rule to create it, and mount the specified URL at it; then it would sync the files, and I could use Git to track the changes. After I was done inspecting the remote directory, I had to clean up the temporary mountpoint fby unmounting and deleting it. I didn't make it do this automatically after a `get` operation for performance reasons (caching of the remote directory would help if I wanted to access it once again).
+
+So, this differs from [[tips/using box.com as a special remote]] in that the tip for WebDAV suggest to handle the mounting manually, and git-annex knows nothing about the WebDAV URL where the content comes from.
+
+So here's my wish: a [[special remote|special remotes]] to track the WebDAV URLs in the repo, and mount the remote directory automatically under the hood, whenever one wants to get a file from there. (Then I assume it should also unmount it immediately in order to clean up after itself, despite possible inefficiencies).
diff --git a/doc/todo/wishlist:_a_spec.remote_for_network_directories_that_would_mount_them_whenever_needed___40__e.g.__44___with_WebDAV__41__/comment_1_f46b0c9b49607e9f4f7a27f5a331ce83._comment b/doc/todo/wishlist:_a_spec.remote_for_network_directories_that_would_mount_them_whenever_needed___40__e.g.__44___with_WebDAV__41__/comment_1_f46b0c9b49607e9f4f7a27f5a331ce83._comment
new file mode 100644
index 000000000..32dd9c039
--- /dev/null
+++ b/doc/todo/wishlist:_a_spec.remote_for_network_directories_that_would_mount_them_whenever_needed___40__e.g.__44___with_WebDAV__41__/comment_1_f46b0c9b49607e9f4f7a27f5a331ce83._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.14.141"
+ subject="comment 1"
+ date="2012-09-25T22:56:22Z"
+ content="""
+Note that git-annex already has the git configs `remote.<name>.annex-start-command` and `remote.<name>.annex-stop-command` which can be used to handle mounting and umounting.
+"""]]
diff --git a/doc/todo/wishlist:_a_spec.remote_for_network_directories_that_would_mount_them_whenever_needed___40__e.g.__44___with_WebDAV__41__/comment_2_1b34e1dd72011c65e881dec2543a0373._comment b/doc/todo/wishlist:_a_spec.remote_for_network_directories_that_would_mount_them_whenever_needed___40__e.g.__44___with_WebDAV__41__/comment_2_1b34e1dd72011c65e881dec2543a0373._comment
new file mode 100644
index 000000000..80c5ed2a9
--- /dev/null
+++ b/doc/todo/wishlist:_a_spec.remote_for_network_directories_that_would_mount_them_whenever_needed___40__e.g.__44___with_WebDAV__41__/comment_2_1b34e1dd72011c65e881dec2543a0373._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://lj.rossia.org/users/imz/"
+ ip="79.165.56.162"
+ subject="comment 2"
+ date="2012-09-25T23:33:23Z"
+ content="""
+I see, thanks for pointing at these config options! Perhaps, that'll be enough.
+
+I'll have to see whether the information on how to access the remote copy (the source URL and how to mount it) saved in config variables will be transferred to the clones of the repo.
+
+AFAIU [[location tracking]], usually, git-annex would transfer the information on where to look for copies from one repo to another.
+"""]]
diff --git a/doc/todo/wishlist:_add_systemd_services_file_samples_for_assistant_and_webapp.mdwn b/doc/todo/wishlist:_add_systemd_services_file_samples_for_assistant_and_webapp.mdwn
new file mode 100644
index 000000000..85c8874fc
--- /dev/null
+++ b/doc/todo/wishlist:_add_systemd_services_file_samples_for_assistant_and_webapp.mdwn
@@ -0,0 +1,6 @@
+It could be useful for Linux users and package maintainers to have systemd .service file samples to launch the assistant and the webapp.
+
+For multi-user systems, we could have a git-annex-webapp@username.service .
+
+See [systemd documentation](http://www.freedesktop.org/software/systemd/man/systemd.service.html) for informations about those files.
+See [archlinux wiki](https://wiki.archlinux.org/index.php/Systemd/Services) for .service examples.
diff --git a/doc/todo/wishlist:_add_systemd_services_file_samples_for_assistant_and_webapp/comment_1_b89e90f9a70748c95aaf81740a40b76e._comment b/doc/todo/wishlist:_add_systemd_services_file_samples_for_assistant_and_webapp/comment_1_b89e90f9a70748c95aaf81740a40b76e._comment
new file mode 100644
index 000000000..5e8c8a374
--- /dev/null
+++ b/doc/todo/wishlist:_add_systemd_services_file_samples_for_assistant_and_webapp/comment_1_b89e90f9a70748c95aaf81740a40b76e._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="64.134.31.139"
+ subject="comment 1"
+ date="2013-10-19T15:33:18Z"
+ content="""
+Wouldn't this involve running it as root or a dedicated user? Neither is ideal. git-annex already uses .desktop files to auto-start when the user who is using it logs in.
+"""]]
diff --git a/doc/todo/wishlist:_add_systemd_services_file_samples_for_assistant_and_webapp/comment_2_d64361380cb18b98ddb43ada1c9f540a._comment b/doc/todo/wishlist:_add_systemd_services_file_samples_for_assistant_and_webapp/comment_2_d64361380cb18b98ddb43ada1c9f540a._comment
new file mode 100644
index 000000000..5dfeedf37
--- /dev/null
+++ b/doc/todo/wishlist:_add_systemd_services_file_samples_for_assistant_and_webapp/comment_2_d64361380cb18b98ddb43ada1c9f540a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmVE2R20dyfPQIzdi6urVUUAXtD6eeBsr0"
+ nickname="Benoît"
+ subject="comment 2"
+ date="2013-10-19T15:43:36Z"
+ content="""
+ Not necessarily. I have a systemd instance handling my userland services. See [archlinux wiki systemd/User](https://wiki.archlinux.org/index.php/Systemd/User).
+"""]]
diff --git a/doc/todo/wishlist:_addurl_https:.mdwn b/doc/todo/wishlist:_addurl_https:.mdwn
new file mode 100644
index 000000000..0a62eda6d
--- /dev/null
+++ b/doc/todo/wishlist:_addurl_https:.mdwn
@@ -0,0 +1,11 @@
+It would be nice if "git annex addurl" allowed https: urls, rather than just http:.
+To give an example, here is a PDF file:
+
+ https://www.fbo.gov/utils/view?id=59ba4c8aa59101a09827ab7b9a787b05
+
+If you switch the https: to http: it redirects you back to https:.
+
+As more sites provide https: for non-secret traffic, this becomes more of an issue.
+
+> I've gotten rid of the use of the HTTP library, now it just uses curl.
+> [[done]] --[[Joey]]
diff --git a/doc/todo/wishlist:_addurl_https:/comment_1_4e8f5e1fc52c3000eb2a1dad0624906e._comment b/doc/todo/wishlist:_addurl_https:/comment_1_4e8f5e1fc52c3000eb2a1dad0624906e._comment
new file mode 100644
index 000000000..fa500b1dd
--- /dev/null
+++ b/doc/todo/wishlist:_addurl_https:/comment_1_4e8f5e1fc52c3000eb2a1dad0624906e._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 1"
+ date="2013-01-26T08:44:38Z"
+ content="""
+This works fine with \"git annex addurl\".
+
+However, with --fast, it fails:
+
+ git-annex: user error (https not supported)
+
+This is because the Haskell HTTP library doesn't support https yet. <https://github.com/haskell/HTTP/issues/17> Seems to be very little momentum on fixing that, perhaps I need to switch the code to use http-enumerator, which does.
+"""]]
diff --git a/doc/todo/wishlist:_allow_configuration_of_downloader_for_addurl.mdwn b/doc/todo/wishlist:_allow_configuration_of_downloader_for_addurl.mdwn
new file mode 100644
index 000000000..81f7ee4c0
--- /dev/null
+++ b/doc/todo/wishlist:_allow_configuration_of_downloader_for_addurl.mdwn
@@ -0,0 +1,3 @@
+It would be neat if Git annex addurl allowed a configuration option for a download manager command to do the actual download in place of wget/curl with a placeholder for the file name to save to & URL to get from (if that's all annex needs). That would allow the user to choose a graphical download manager if desired to make progress easier to monitor. The specific circumstance I'm seeing is with [[wishlist:_an___34__assistant__34___for_web-browsing_--_tracking_the_sources_of_the_downloads]]. I found that the existing Firefox addon [FlashGot](http://flashgot.net/) can run any command with arbitrary arguments including placeholders. Right now I've got a [script](https://gist.github.com/andyg0808/5342434) that changes to a user-selected directory and then runs git-annex addurl in it with the provided url. It works fine as a download manager for FlashGot. The issue is that there is no progress information for large file downloads. If git-annex could start a separate download manager to do the actual download, then the user would be able to check status at any time, even though the git-annex command was run from a GUI and not a terminal.
+
+> [[done]], you can use `annex.web-download-command` now. --[[Joey]]
diff --git a/doc/todo/wishlist:_allow_the_same_remote_to_be_accissable_via_different_methods.mdwn b/doc/todo/wishlist:_allow_the_same_remote_to_be_accissable_via_different_methods.mdwn
new file mode 100644
index 000000000..849e73cc3
--- /dev/null
+++ b/doc/todo/wishlist:_allow_the_same_remote_to_be_accissable_via_different_methods.mdwn
@@ -0,0 +1,5 @@
+This is a wishlist item:
+
+Please allow the same remote to be available via different remotes. So in my LAN my remote is available using a ssh-connection, and when I travel with my laptop, the git-annex can also reach this remote using the Jabber transport.
+
+> [[done]]; this has always been fully supported. --[[Joey]]
diff --git a/doc/todo/wishlist:_allow_the_same_remote_to_be_accissable_via_different_methods/comment_1_abb6263f3807160222bba1122475c89c._comment b/doc/todo/wishlist:_allow_the_same_remote_to_be_accissable_via_different_methods/comment_1_abb6263f3807160222bba1122475c89c._comment
new file mode 100644
index 000000000..a95ba56f9
--- /dev/null
+++ b/doc/todo/wishlist:_allow_the_same_remote_to_be_accissable_via_different_methods/comment_1_abb6263f3807160222bba1122475c89c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="2001:4978:f:21a::2"
+ subject="comment 1"
+ date="2013-08-07T16:09:26Z"
+ content="""
+You can have as many git remotes as you like all pointing at the same repository via different paths. git-annex fully supports this AFAIK. Are you having some problem with it?
+"""]]
diff --git a/doc/todo/wishlist:_allow_users_to_provide_UUID_when_running___96__git_annex_init__96__.mdwn b/doc/todo/wishlist:_allow_users_to_provide_UUID_when_running___96__git_annex_init__96__.mdwn
new file mode 100644
index 000000000..0dc9ec08a
--- /dev/null
+++ b/doc/todo/wishlist:_allow_users_to_provide_UUID_when_running___96__git_annex_init__96__.mdwn
@@ -0,0 +1,5 @@
+As there's no way to permanently hide remotes and I have to recreate two repos now, I would love to be able to re-use the old UUIDs to remove clutter.
+
+> git-annex already provides a way to do this: Copy `.git/config` from the
+> original repo (or use `git-config` to set `annex.uuid`) *before* running
+> `git annex init`. [[done]] --[[Joey]]
diff --git a/doc/todo/wishlist:_an___34__assistant__34___for_web-browsing_--_tracking_the_sources_of_the_downloads.mdwn b/doc/todo/wishlist:_an___34__assistant__34___for_web-browsing_--_tracking_the_sources_of_the_downloads.mdwn
new file mode 100644
index 000000000..c910ace83
--- /dev/null
+++ b/doc/todo/wishlist:_an___34__assistant__34___for_web-browsing_--_tracking_the_sources_of_the_downloads.mdwn
@@ -0,0 +1,28 @@
+A replacement for a web-browser's downloads menu that uses git-annex internally ([[`addurl`|tips/using the web as a special remote]] command for the download, and `drop` or `git rm` for the clean up) would be quite helpful:
+
+say, when working on a topic, writing a paper or similar things, I usually have a Git repo with my text, all relevant data and processing code, and possibly other background information. It's nice to store the literature you needed at the same place where you work. (So that it is easy to catch up with what I was doing and thinking over when I left this work aside for a while, perhaps after cloning the repo from another location.)
+
+When I find an interesting literature, I save the file to the directory with my work, and read it. Then I might return to it to re-read it. There might be references to this document from my work, so I'd like them to work as links (perhaps pointing at the local file, but also at the source URL for the case when my document is read by someone else not on my system).
+
+I need to keep track of the source URLs for the documents I have saved which I read and use.
+
+That's a task that fits well git-annex.
+
+Note that doing the dull work of copying and pasting the URL and the downloading it and then opening it for reading is a pain to do every time I'm interested in a document I have found on the web. (Of course, I would need to fill out the bibliogrphic information for this document if I want to refer to it, but that can be done later. Initially, I wish I just don't lose the source URL of a document at the moment when I get interested in it and start reading.)
+
+So, I could be assisted by a replacement of the "downloads" menu of, say, Firefox: whenever I want to open a file for viewing (like a PDF), it should ask me where to save it, and I'd choose the directory with my work, then it should register it with git-annex (so that the source URL is saved, and perhaps it should also write down the referring page's URL somewhere nearby automatically), download it, and open with a viewer for reading.
+
+Then I'll have the interesting literature there when I'm offline; the source URLs would be saved, so that they can be put into the references. Also, if I distribute this work with Git, at another location git-annex can be used to easily get all the literature again.
+
+(Hmmm... probably, the browser that this will be simplest for me to implement for is emacs-w3m; simply, some functions calling git-annex...)
+
+> This seems fairly doable to implement since the git-annex [[design/assistant]]
+> already has a webapp. So a javascript toolbar thing could be made that
+> submits the current url (or maybe links dragged into it?) to the webapp
+> for adding to the annex.
+>
+> The only wrinkle is that the webapp runs under a new url each time
+> it starts, due to using a high port and embedding some auth token in the
+> url. --[[Joey]]
+
+[[!tag /design/assistant]]
diff --git a/doc/todo/wishlist:_an___34__assistant__34___for_web-browsing_--_tracking_the_sources_of_the_downloads/comment_1_36ae3c75053d5ec278b5e6eb2084d57a._comment b/doc/todo/wishlist:_an___34__assistant__34___for_web-browsing_--_tracking_the_sources_of_the_downloads/comment_1_36ae3c75053d5ec278b5e6eb2084d57a._comment
new file mode 100644
index 000000000..4c20561c7
--- /dev/null
+++ b/doc/todo/wishlist:_an___34__assistant__34___for_web-browsing_--_tracking_the_sources_of_the_downloads/comment_1_36ae3c75053d5ec278b5e6eb2084d57a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="comment 1"
+ date="2012-09-25T23:55:44Z"
+ content="""
+You know about `git annex addurl` right? It doesn't help with the browser integration (though I bet there are existing download manager extensions you could re-use for this) but it takes care of the other use cases.
+"""]]
diff --git a/doc/todo/wishlist:_an___34__assistant__34___for_web-browsing_--_tracking_the_sources_of_the_downloads/comment_3_be8eb800523db8cf7a2c68a28fbf5ea5._comment b/doc/todo/wishlist:_an___34__assistant__34___for_web-browsing_--_tracking_the_sources_of_the_downloads/comment_3_be8eb800523db8cf7a2c68a28fbf5ea5._comment
new file mode 100644
index 000000000..c958fd08f
--- /dev/null
+++ b/doc/todo/wishlist:_an___34__assistant__34___for_web-browsing_--_tracking_the_sources_of_the_downloads/comment_3_be8eb800523db8cf7a2c68a28fbf5ea5._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://m-f-k.myopenid.com/"
+ ip="93.207.162.28"
+ subject="+1"
+ date="2012-10-05T20:00:31Z"
+ content="""
+Copy+Paste+Open is to much for lazy people like me;) I like the idea of a direct browser download manager integration. This would make it so much easier to find find the original source of a downloaded file when you're to lazy to write it down somewhere in the first place …
+"""]]
diff --git a/doc/todo/wishlist:_an___34__assistant__34___for_web-browsing_--_tracking_the_sources_of_the_downloads/comment_3_d9f725de41a8572c85e4c6d9b4bcc927._comment b/doc/todo/wishlist:_an___34__assistant__34___for_web-browsing_--_tracking_the_sources_of_the_downloads/comment_3_d9f725de41a8572c85e4c6d9b4bcc927._comment
new file mode 100644
index 000000000..30515a49b
--- /dev/null
+++ b/doc/todo/wishlist:_an___34__assistant__34___for_web-browsing_--_tracking_the_sources_of_the_downloads/comment_3_d9f725de41a8572c85e4c6d9b4bcc927._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://lj.rossia.org/users/imz/"
+ ip="79.165.56.162"
+ subject="the scheme to follow to use the addurl command is longer"
+ date="2012-09-26T00:07:11Z"
+ content="""
+Justin, yes, I know. To use [[addurl|tips/using the web as a special remote]], I should force myself not to click on a link to view it, but rather to copy it, paste into the command line with addurl (then it will be downloaded, and I can run a command to view it...). Not terrible, probably learnable.
+"""]]
diff --git a/doc/todo/wishlist:_an___34__assistant__34___for_web-browsing_--_tracking_the_sources_of_the_downloads/comment_4_f52492e4cc6f965515800bd1c0e05c90._comment b/doc/todo/wishlist:_an___34__assistant__34___for_web-browsing_--_tracking_the_sources_of_the_downloads/comment_4_f52492e4cc6f965515800bd1c0e05c90._comment
new file mode 100644
index 000000000..7efd583c0
--- /dev/null
+++ b/doc/todo/wishlist:_an___34__assistant__34___for_web-browsing_--_tracking_the_sources_of_the_downloads/comment_4_f52492e4cc6f965515800bd1c0e05c90._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="andy"
+ ip="99.48.75.171"
+ subject="I've just written a script that does this (with a Firefox download manager)"
+ date="2013-04-09T02:51:26Z"
+ content="""
+So I've just written a two-line shell script that makes [FlashGot](http://flashgot.net/) able to do this. It's available on GitHub at <https://gist.github.com/andyg0808/5342434>.
+
+This could be even neater if Git-annex had the ability to set the download manager... Wishlist created: [[wishlist:_allow_configuration_of_downloader_for_addurl]]
+"""]]
diff --git a/doc/todo/wishlist:_an___34__assistant__34___for_web-browsing_--_tracking_the_sources_of_the_downloads/comment_5_5b36656fc5fa124e763f06711d9da32b._comment b/doc/todo/wishlist:_an___34__assistant__34___for_web-browsing_--_tracking_the_sources_of_the_downloads/comment_5_5b36656fc5fa124e763f06711d9da32b._comment
new file mode 100644
index 000000000..494aab7a8
--- /dev/null
+++ b/doc/todo/wishlist:_an___34__assistant__34___for_web-browsing_--_tracking_the_sources_of_the_downloads/comment_5_5b36656fc5fa124e763f06711d9da32b._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 5"
+ date="2013-04-09T03:36:29Z"
+ content="""
+Wishlist implemented ;)
+
+A full example of doing this would make a nice addition to [[tips]] ...
+"""]]
diff --git a/doc/todo/wishlist:_an___34__assistant__34___for_web-browsing_--_tracking_the_sources_of_the_downloads/comment_6_285215a4466806baf85b8606f680494a._comment b/doc/todo/wishlist:_an___34__assistant__34___for_web-browsing_--_tracking_the_sources_of_the_downloads/comment_6_285215a4466806baf85b8606f680494a._comment
new file mode 100644
index 000000000..d0545153f
--- /dev/null
+++ b/doc/todo/wishlist:_an___34__assistant__34___for_web-browsing_--_tracking_the_sources_of_the_downloads/comment_6_285215a4466806baf85b8606f680494a._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 6"
+ date="2013-04-11T15:12:00Z"
+ content="""
+See [[tips/Using_Git-annex_as_a_web_browsing_assistant]].
+
+I am leaving this bug open for now, as some javascript that passes the url off to the webapp is still a nice idea to build.
+
+A solution to the webapp's url always changing could be to have a file:/// url that the webapp creates, and javascript submits to, that then passes the request off to the webapp, probably by using additional javadcript in the html file. Assuming javascript security allows this.
+"""]]
diff --git a/doc/todo/wishlist:_an___34__assistant__34___for_web-browsing_--_tracking_the_sources_of_the_downloads/comment_7_15bf62e46db4b84ed3156f550f03de42._comment b/doc/todo/wishlist:_an___34__assistant__34___for_web-browsing_--_tracking_the_sources_of_the_downloads/comment_7_15bf62e46db4b84ed3156f550f03de42._comment
new file mode 100644
index 000000000..484db1e81
--- /dev/null
+++ b/doc/todo/wishlist:_an___34__assistant__34___for_web-browsing_--_tracking_the_sources_of_the_downloads/comment_7_15bf62e46db4b84ed3156f550f03de42._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 7"
+ date="2013-04-11T15:41:16Z"
+ content="""
+A less round-about method would be to have the webapp listen for links dropped into its page. You could then have the webapp open in a tab, and just drag urls there to add them to the annex.
+
+I'm not sure if it's possible to intercept drags into a tab. Default browser behavior is certainly to redirect the tab to the url dropped into it.
+
+If someone finds out how to do this, I will build it.
+"""]]
diff --git a/doc/todo/wishlist:_annex.largefiles_configuration_in_webapp_and_sync.mdwn b/doc/todo/wishlist:_annex.largefiles_configuration_in_webapp_and_sync.mdwn
new file mode 100644
index 000000000..873988eea
--- /dev/null
+++ b/doc/todo/wishlist:_annex.largefiles_configuration_in_webapp_and_sync.mdwn
@@ -0,0 +1 @@
+The `annex.largefiles` feature is very nice to mix annexed files with normal git managed files. I'd like to be able to configure this setting on the webapp and that the configuration directive would be synchronized accross all remotes.
diff --git a/doc/todo/wishlist:_annex.largefiles_configuration_in_webapp_and_sync/comment_1_db632de391ce9fce42af51a770ed3aeb._comment b/doc/todo/wishlist:_annex.largefiles_configuration_in_webapp_and_sync/comment_1_db632de391ce9fce42af51a770ed3aeb._comment
new file mode 100644
index 000000000..e402d26c3
--- /dev/null
+++ b/doc/todo/wishlist:_annex.largefiles_configuration_in_webapp_and_sync/comment_1_db632de391ce9fce42af51a770ed3aeb._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.47"
+ subject="comment 1"
+ date="2013-11-05T16:46:28Z"
+ content="""
+It might make sense to sync this across remotes and have it edited with `git annex vicfg`
+
+Putting it in the webapp would need some nice interface for constructing the underlying expression. Might be doable for at least simple filtering (ie, files larger than XX or with extensions .A, .B, .C). I tend to think of this as a setting for people comfortable with the command line though.
+"""]]
diff --git a/doc/todo/wishlist:_annex.largefiles_configuration_in_webapp_and_sync/comment_2_4a0931d9884054d764fde315d4fe4851._comment b/doc/todo/wishlist:_annex.largefiles_configuration_in_webapp_and_sync/comment_2_4a0931d9884054d764fde315d4fe4851._comment
new file mode 100644
index 000000000..0e24014d2
--- /dev/null
+++ b/doc/todo/wishlist:_annex.largefiles_configuration_in_webapp_and_sync/comment_2_4a0931d9884054d764fde315d4fe4851._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawne_amN4fko4p5cRY_9EYwaYuJKNn7LRio"
+ nickname="Tobias"
+ subject="feedback"
+ date="2013-11-05T21:23:11Z"
+ content="""
+> It might make sense to sync this across remotes and have it edited with git annex vicfg
+
+That would be great!
+
+> Putting it in the webapp would need some nice interface for constructing the underlying expression. Might be doable for at least simple filtering (ie, files larger than XX or with extensions .A, .B, .C). I tend to think of this as a setting for people comfortable with the command line though.
+
+I could live with a simple filtering interface without too many fancy stuff. The fancy stuff could be done on the command line if needed...
+"""]]
diff --git a/doc/todo/wishlist:_annex.largefiles_support_for_mimetypes.mdwn b/doc/todo/wishlist:_annex.largefiles_support_for_mimetypes.mdwn
new file mode 100644
index 000000000..f38e41dd3
--- /dev/null
+++ b/doc/todo/wishlist:_annex.largefiles_support_for_mimetypes.mdwn
@@ -0,0 +1 @@
+It would be nice to have mimetype support on the `annex.largefiles` configuration directive. F.e. `git config annex.largefiles "not mimetype=text/plain"`
diff --git a/doc/todo/wishlist:_annex.largefiles_support_for_mimetypes/comment_1_304431bb62b5b8a64edc37a11bbaff59._comment b/doc/todo/wishlist:_annex.largefiles_support_for_mimetypes/comment_1_304431bb62b5b8a64edc37a11bbaff59._comment
new file mode 100644
index 000000000..b06008475
--- /dev/null
+++ b/doc/todo/wishlist:_annex.largefiles_support_for_mimetypes/comment_1_304431bb62b5b8a64edc37a11bbaff59._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlhE8Xar6m4x3JSILXdm-Y5KhwHTH5qzKQ"
+ nickname="bruno"
+ subject="+1"
+ date="2013-10-14T14:43:11Z"
+ content="""
+Big +1 for this feature: this would really help configuring annex.largefiles
+"""]]
diff --git a/doc/todo/wishlist:_archive_from_remote_with_the_least_free_space.mdwn b/doc/todo/wishlist:_archive_from_remote_with_the_least_free_space.mdwn
new file mode 100644
index 000000000..acc8b363e
--- /dev/null
+++ b/doc/todo/wishlist:_archive_from_remote_with_the_least_free_space.mdwn
@@ -0,0 +1 @@
+An interesting feature, when an archived file cannot be removed from all clients because of the minimum number of copies required, would be to remove it from the repositories with the smallest amount of free space available.
diff --git a/doc/todo/wishlist:_archive_from_remote_with_the_least_free_space/comment_1_6813fdc7ecc98765a5d35d34163a1712._comment b/doc/todo/wishlist:_archive_from_remote_with_the_least_free_space/comment_1_6813fdc7ecc98765a5d35d34163a1712._comment
new file mode 100644
index 000000000..89fe4c069
--- /dev/null
+++ b/doc/todo/wishlist:_archive_from_remote_with_the_least_free_space/comment_1_6813fdc7ecc98765a5d35d34163a1712._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.14.105"
+ subject="comment 1"
+ date="2013-09-19T21:01:30Z"
+ content="""
+That might be useful in some cases. git-annex can only tell how much free space is available on remotes that are mounted to the local filesystem. Did you use case involve removable drives?
+"""]]
diff --git a/doc/todo/wishlist:_archive_from_remote_with_the_least_free_space/comment_2_21a249cedca1ceb80d10784004735524._comment b/doc/todo/wishlist:_archive_from_remote_with_the_least_free_space/comment_2_21a249cedca1ceb80d10784004735524._comment
new file mode 100644
index 000000000..d2b29c239
--- /dev/null
+++ b/doc/todo/wishlist:_archive_from_remote_with_the_least_free_space/comment_2_21a249cedca1ceb80d10784004735524._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmOsy6nbvPyXLd--qqjPMLnVIzxgZwtKlQ"
+ nickname="Nicolas"
+ subject="comment 2"
+ date="2013-09-20T19:03:13Z"
+ content="""
+I was not thinking of removable drives, but only of \"client\" repositories. Ideally, git-annex would query the remaining space of all connected client repositories to choose on which repositories to drop a copy.
+"""]]
diff --git a/doc/todo/wishlist:_assistant_autostart_port_and_secret_configuration.mdwn b/doc/todo/wishlist:_assistant_autostart_port_and_secret_configuration.mdwn
new file mode 100644
index 000000000..f0d27d0b1
--- /dev/null
+++ b/doc/todo/wishlist:_assistant_autostart_port_and_secret_configuration.mdwn
@@ -0,0 +1 @@
+When starting the assistant when logging in to the system (`--autostart`) it choses a new port an secret everytime. Having the assistant open in a pinned firefox tab which automatically restores when firefox starts we need to get the url from `.git/annex/url` and copy/paste it into the pinned tab. It would be very nice to have a configuration option which assigns a fixed port and secret so everytime the assistant is autostarted it uses the same settings and firefox is happy to open it automatically on start.
diff --git a/doc/todo/wishlist:_assistant_autostart_port_and_secret_configuration/comment_1_be53b8456eed7eadad5d4b8465c8a42b._comment b/doc/todo/wishlist:_assistant_autostart_port_and_secret_configuration/comment_1_be53b8456eed7eadad5d4b8465c8a42b._comment
new file mode 100644
index 000000000..651937802
--- /dev/null
+++ b/doc/todo/wishlist:_assistant_autostart_port_and_secret_configuration/comment_1_be53b8456eed7eadad5d4b8465c8a42b._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="209.250.56.64"
+ subject="comment 1"
+ date="2013-11-22T16:58:51Z"
+ content="""
+It's impossible to guarantee a program will be able to get a particular port. Any other program could be using that port number.
+
+This is why `git annex webapp` opens the webapp using whatever url the assistant has picked. I recommend that rather than using a pinned tab, you make an icon on your desktop that runs `git annex webapp`, and use that to open the app when you want it, much as you'd open any other app. If you wanted to, you could make your system run `git annex webapp` on startup instead of `git annex assistant --autostart`, and you'd get the browser tab opened automatically on start.
+"""]]
diff --git a/doc/todo/wishlist:_command_options_changes.mdwn b/doc/todo/wishlist:_command_options_changes.mdwn
new file mode 100644
index 000000000..b15440181
--- /dev/null
+++ b/doc/todo/wishlist:_command_options_changes.mdwn
@@ -0,0 +1,17 @@
+Some suggestions for changes to command options:
+
+ * --verbose:
+ * add alternate: -v
+
+ * --from:
+ * replace with: -s $SOURCE || --source=$SOURCE
+
+ * --to:
+ * replace with: -d $DESTINATION || --destination=$DESTINATION
+
+ * --force:
+ * add alternate: -F
+ * "-f" was removed in v0.20110417
+ * since it forces unsafe operations, should be capitalized to reduce chance of accidental usage.
+
+[[done]], see comments
diff --git a/doc/todo/wishlist:_command_options_changes/comment_1_bfba72a696789bf21b2435dea15f967a._comment b/doc/todo/wishlist:_command_options_changes/comment_1_bfba72a696789bf21b2435dea15f967a._comment
new file mode 100644
index 000000000..0ab113211
--- /dev/null
+++ b/doc/todo/wishlist:_command_options_changes/comment_1_bfba72a696789bf21b2435dea15f967a._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 1"
+ date="2011-04-17T23:46:37Z"
+ content="""
+--to and --from seem to have different semantics than --source and --destination. Subtle, but still different.
+
+That being said, I am not sure --from and --to are needed at all. Calling the local repo . and all remotes by their name, they are arguably redundant and removing them would make the syntax a lot prettier; mv and cp don't need them, either.
+
+I am not sure changing syntax at this point is considered good style though personally, I wouldn't mind adapting and would actually prefer it over using --to and --from.
+
+-v and -q would be nice.
+
+
+Richard
+"""]]
diff --git a/doc/todo/wishlist:_command_options_changes/comment_2_f6a637c78c989382e3c22d41b7fb4cc2._comment b/doc/todo/wishlist:_command_options_changes/comment_2_f6a637c78c989382e3c22d41b7fb4cc2._comment
new file mode 100644
index 000000000..0072ae1d7
--- /dev/null
+++ b/doc/todo/wishlist:_command_options_changes/comment_2_f6a637c78c989382e3c22d41b7fb4cc2._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 2"
+ date="2011-04-19T20:13:10Z"
+ content="""
+Let's see..
+
+* -v is already an alias for --verbose
+
+* I don't find --source and --destination as easy to type or as clear as --from or --to.
+
+* -F is fast, so it cannot be used for --force. And I have no desire to make it easy to mistype a short option and enable --force; it can lose data.
+
+@richard while it would be possible to support some syntax like \"git annex copy . remote\"; what is it supposed to do if there are local files named foo and bar, and a remotes named foo and bar? Does \"git annex copy foo bar\" copy file foo to remote bar, or file bar from remote foo? I chose to use --from/--to to specify remotes independant of files to avoid such
+ambiguity, which plain old `cp` doesn't have since it's operating entirely on filesystem objects, not both filesystem objects and abstract remotes.
+
+Seems like nothing to do here. [[done]] --[[Joey]]
+"""]]
diff --git a/doc/todo/wishlist:_command_options_changes/comment_3_bf1114533d2895804e531e76eb6b8095._comment b/doc/todo/wishlist:_command_options_changes/comment_3_bf1114533d2895804e531e76eb6b8095._comment
new file mode 100644
index 000000000..9fcbae6d2
--- /dev/null
+++ b/doc/todo/wishlist:_command_options_changes/comment_3_bf1114533d2895804e531e76eb6b8095._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 3"
+ date="2011-04-20T21:28:06Z"
+ content="""
+Good point. scp fixes this by using a colon, but as colons aren't needed in git-annex remotes' names... -- RichiH
+"""]]
diff --git a/doc/todo/wishlist:_define_remotes_that_must_have_all_files.mdwn b/doc/todo/wishlist:_define_remotes_that_must_have_all_files.mdwn
new file mode 100644
index 000000000..156cfb009
--- /dev/null
+++ b/doc/todo/wishlist:_define_remotes_that_must_have_all_files.mdwn
@@ -0,0 +1,18 @@
+I would like to be able to name a few remotes that must retain *all* annexed
+files. `git-annex fsck` should warn me if any files are missing from those
+remotes, even if `annex.numcopies` has been satisfied by other remotes.
+
+I imagine this could also be useful for bup remotes, but I haven't actually
+looked at those yet.
+
+Based on existing output, this is what a warning message could look like:
+
+ fsck FILE
+ 3 of 3 trustworthy copies of FILE exist.
+ FILE is, however, still missing from these required remotes:
+ UUID -- Backup Drive 1
+ UUID -- Backup Drive 2
+ Back it up with git-annex copy.
+ Warning
+
+What do you think?
diff --git a/doc/todo/wishlist:_define_remotes_that_must_have_all_files/comment_1_cceccc1a1730ac688d712b81a44e31c3._comment b/doc/todo/wishlist:_define_remotes_that_must_have_all_files/comment_1_cceccc1a1730ac688d712b81a44e31c3._comment
new file mode 100644
index 000000000..1f65fd982
--- /dev/null
+++ b/doc/todo/wishlist:_define_remotes_that_must_have_all_files/comment_1_cceccc1a1730ac688d712b81a44e31c3._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-04-23T16:27:13Z"
+ content="""
+Seems to have a scalability problem, what happens when such a repository becomes full?
+
+Another way to accomplish I think the same thing is to pick the repositories that you would include in such a set, and make all other repositories untrusted. And set numcopies as desired. Then git-annex will never remove files from the set of non-untrusted repositories, and fsck will warn if a file is present on only an untrusted repository.
+"""]]
diff --git a/doc/todo/wishlist:_define_remotes_that_must_have_all_files/comment_2_eec848fcf3979c03cbff2b7407c75a7a._comment b/doc/todo/wishlist:_define_remotes_that_must_have_all_files/comment_2_eec848fcf3979c03cbff2b7407c75a7a._comment
new file mode 100644
index 000000000..1855cdda0
--- /dev/null
+++ b/doc/todo/wishlist:_define_remotes_that_must_have_all_files/comment_2_eec848fcf3979c03cbff2b7407c75a7a._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="gernot"
+ ip="87.79.209.169"
+ subject="comment 2"
+ date="2011-04-24T11:20:05Z"
+ content="""
+Right, I have thought about untrusting all but a few remotes to achieve
+something similar before and I'm sure it would kind of work. It would be more
+of an ugly workaround, however, because I would have to untrust remotes that
+are, in reality, at least semi-trusted. That's why an extra option/attribute
+for that kind of purpose/remote would be nice.
+
+Obviously I didn't see the scalability problem though. Good Point. Maybe I can
+achieve the same thing by writing a log parsing script for myself?
+
+"""]]
diff --git a/doc/todo/wishlist:_detection_of_merge_conflicts.mdwn b/doc/todo/wishlist:_detection_of_merge_conflicts.mdwn
new file mode 100644
index 000000000..1b4caeff0
--- /dev/null
+++ b/doc/todo/wishlist:_detection_of_merge_conflicts.mdwn
@@ -0,0 +1,13 @@
+A conflict during sync or merge is something that requires user intervention, or at least notification. For that reason it would be nice if git annex returned a nonzero exit status when such a conflict happened during a sync or a merge. This is what git does after a conflicting pull, and would make it easier to spot a conflict in automated syncs without having to parse annex output or the logs.
+
+> Good idea, [[done]]. --[[Joey]]
+
+Also, it would be nice if your new `git annex status` were able to inform about remaining conflicts in the repo, for instance by reporting files with variant-XXX suffix.
+
+> Hmm, that would need a separate pass through the whole tree, since
+> currently it can use `git ls-files` to find only modified/deleted/new
+> files. I would rather not make the new `git annex status` slower for
+> this.
+>
+> It would be possible to add it to `git annex info` (old `status`)
+> which already has to look through the entire work tree.
diff --git a/doc/todo/wishlist:_disable_automatic_commits.mdwn b/doc/todo/wishlist:_disable_automatic_commits.mdwn
new file mode 100644
index 000000000..14c131796
--- /dev/null
+++ b/doc/todo/wishlist:_disable_automatic_commits.mdwn
@@ -0,0 +1,36 @@
+When using the [[/assistant]] on some of my repositories, I would like to
+retain manual control over the granularity and contents of the commit
+history. Some motivating reasons:
+
+* manually specified commit messages makes the history easier to follow
+* make a series of minor changes to a file over a period of a few hours would result in a single commit rather than capturing intermediate incomplete edits
+
+* manual choice of which files to annex (based on predicted usage) could be useful, e.g. a repo might contain a 4MB PDF which you want available in *every* remote even without `git annex get`, and also some 2MB images which are only required in some remotes
+
+> This particular case is now catered to by the "manual" repository group
+> in preferred content settings. --[[Joey]]
+
+Obviously this needs to be configurable at least per repository, and
+ideally perhaps even per remote, since usage habits can vary from machine
+to machine (e.g. I could choose to commit manually from my desktop machine
+which has a nice comfy keyboard and large screen, but this would be too
+much pain to do from my tiny netbook).
+
+In fact, this is vaguely related to [[design/assistant/partial_content]],
+since the usefulness of the commit history depends on the context of the
+data being manipulated, which in turn depends on which subdirectories are
+being touched. So any mechanism for disabling sync per directory could
+potentially be reused for disabling auto-commit per directory.
+
+According to Joey, it should be easy to arrange for the watcher thread not
+to run, but would need some more work for the assistant to notice manual
+commits in order to sync them; however the assistant already does some
+crazy inotify watching of git refs, in order to detect incoming pushes, so
+detecting manual commits wouldn't be a stretch.
+
+[[!tag design/assistant]]
+
+> You can do this now by pausing committing via the webapp,
+> or setting `annex.autocommit=false`.
+>
+> The assistant probably doesn't push such commits yet.
diff --git a/doc/todo/wishlist:_display_name_of_object_when_addWatcher_gets_a_permission_denied.mdwn b/doc/todo/wishlist:_display_name_of_object_when_addWatcher_gets_a_permission_denied.mdwn
new file mode 100644
index 000000000..837f0a587
--- /dev/null
+++ b/doc/todo/wishlist:_display_name_of_object_when_addWatcher_gets_a_permission_denied.mdwn
@@ -0,0 +1,6 @@
+When addWatcher gets a permission denied, it would be helpful to display the name of the object on which the permission was denied, in the error message which shows in the webapp.
+
+> I have made the inotify code more robust; now it doesn't crash if it
+> cannot read a directory or a file, and only logs a warning, which includes
+> the directory name.
+> [[done]] --[[Joey]]
diff --git a/doc/todo/wishlist:_display_name_of_object_when_addWatcher_gets_a_permission_denied/comment_1_d2665e7347689b520d37561cfddf0aa8._comment b/doc/todo/wishlist:_display_name_of_object_when_addWatcher_gets_a_permission_denied/comment_1_d2665e7347689b520d37561cfddf0aa8._comment
new file mode 100644
index 000000000..de0528855
--- /dev/null
+++ b/doc/todo/wishlist:_display_name_of_object_when_addWatcher_gets_a_permission_denied/comment_1_d2665e7347689b520d37561cfddf0aa8._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.220"
+ subject="comment 1"
+ date="2013-09-25T18:47:13Z"
+ content="""
+This is an exception from the inotify library, which is what contains the `addWatch` function. I catch and display the exception. Since `addWatch` is only passed a directory to watch, the most I could do is tack on the name of the directory when displaying the exception. That does not seem likely to be much help?
+"""]]
diff --git a/doc/todo/wishlist:_display_name_of_object_when_addWatcher_gets_a_permission_denied/comment_2_db153571a32fb072453ed583e3e9ccf4._comment b/doc/todo/wishlist:_display_name_of_object_when_addWatcher_gets_a_permission_denied/comment_2_db153571a32fb072453ed583e3e9ccf4._comment
new file mode 100644
index 000000000..e0199a42d
--- /dev/null
+++ b/doc/todo/wishlist:_display_name_of_object_when_addWatcher_gets_a_permission_denied/comment_2_db153571a32fb072453ed583e3e9ccf4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl-g0hYpGY11pBP_42lHh5GWTyFuB4UwH8"
+ nickname="Nicolas"
+ subject="comment 2"
+ date="2013-09-25T23:08:56Z"
+ content="""
+Well, of course it would not be as helpful as if the inotify exception would contain the name of the exact object on which it got a permission denied (would this be a valid wishlist request for inotify?), but I think that displaying the name of the directory would already be better than nothing.
+"""]]
diff --git a/doc/todo/wishlist:_display_status_of_remotes_in_the_webapp.mdwn b/doc/todo/wishlist:_display_status_of_remotes_in_the_webapp.mdwn
new file mode 100644
index 000000000..741466994
--- /dev/null
+++ b/doc/todo/wishlist:_display_status_of_remotes_in_the_webapp.mdwn
@@ -0,0 +1 @@
+It would be nice to have an indication of the status of the remotes in the webapp, for example with a field showing "In Sync", "Syncing", or the date of the last successful synchronization for unreachable remotes.
diff --git a/doc/todo/wishlist:_do_round_robin_downloading_of_data.mdwn b/doc/todo/wishlist:_do_round_robin_downloading_of_data.mdwn
new file mode 100644
index 000000000..6299899e4
--- /dev/null
+++ b/doc/todo/wishlist:_do_round_robin_downloading_of_data.mdwn
@@ -0,0 +1,5 @@
+Given that git/config will have information on remotes and maybe costs, it might be a good idea to do a simple round robin selection of remotes to download files where the costs are the same.
+
+This of course assumes that we like the idea of "parallel" launching and running of curl/rsync processes...
+
+This wish item is probably only useful for the paranoid people who store more than 1 copy of their data.
diff --git a/doc/todo/wishlist:_do_round_robin_downloading_of_data/comment_1_460335b0e59ad03871c524f1fe812357._comment b/doc/todo/wishlist:_do_round_robin_downloading_of_data/comment_1_460335b0e59ad03871c524f1fe812357._comment
new file mode 100644
index 000000000..6a5fd3d53
--- /dev/null
+++ b/doc/todo/wishlist:_do_round_robin_downloading_of_data/comment_1_460335b0e59ad03871c524f1fe812357._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-04-03T16:39:35Z"
+ content="""
+I dunno about parrallel downloads -- eek! -- but there is at least room for improvement of what \"git annex get\" does when there are multiple remotes that have a file, and the one it decides to use is not available, or very slow, or whatever.
+"""]]
diff --git a/doc/todo/wishlist:_dropping_git-annex_history.mdwn b/doc/todo/wishlist:_dropping_git-annex_history.mdwn
new file mode 100644
index 000000000..8286699c7
--- /dev/null
+++ b/doc/todo/wishlist:_dropping_git-annex_history.mdwn
@@ -0,0 +1,28 @@
+In real life discussions with git-annex users at DebConf, the idea was proposed to have a way to drop the history of the git-annex branch, and replace it with a new branch with just the current state of the repository.
+
+The only thing that breaks when this is done, in theory, is `git annex log`, which can't show the location history
+of files.
+
+The crucial thing is that this operation would only need to be done in one repository, and it would then record some information in its (new) git-annex branch, so when it was pushed to other repositories, git-annex there could notice that history had been dropped, and do the same. So, even if you have rarely used offline archive repositories, the history dropping would eventually reach them, without needing to remember to do it.
+
+There was speculation that it would be enough to record eg, the SHA of the top commit on the old branch. That may not be good enough, because another remote may have not gotten that SHA into its branch yet, or may have commits on top of that SHA.
+
+Maybe instead we want to record the SHA of the *first* commit to the old git-annex branch. This way, we can tell if the branch that got deleted is the one we're currently using. And if it is, we create a new branch with the current state of *our* branch, and then union merge the other branch into it.
+
+Hmm, another wrinkle is that, when this indication propigates from remote A to remote B, remote B may also have some git-annex branches available for remotes C and D, which have not transitioned, and E, which has transitioned already. It seems B should first union merge C and D into B, and then flatten B to B', and then union merge A and E into B'.
+
+I think that'd work!
+
+--[[Joey]]
+
+Will also allow dropping dead remotes from history. Just remove all
+references to them when rewriting the branch. May or may not be desirable;
+I sometimes care about dead remotes that I hope to one day recuscitate.
+(OTOH, I can always run git annex fsck in them to get their location
+tracking back, if I do manage to get them back.)
+
+--[[Joey]]
+
+See also : [[forum/safely_dropping_git-annex_history]]
+
+> [[done]] --[[Joey]]
diff --git a/doc/todo/wishlist:_dropping_git-annex_history/comment_1_a4bee2e26b22a9bdaadc05b7227769ef._comment b/doc/todo/wishlist:_dropping_git-annex_history/comment_1_a4bee2e26b22a9bdaadc05b7227769ef._comment
new file mode 100644
index 000000000..043e674ed
--- /dev/null
+++ b/doc/todo/wishlist:_dropping_git-annex_history/comment_1_a4bee2e26b22a9bdaadc05b7227769ef._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 1"
+ date="2013-08-24T19:39:45Z"
+ content="""
+BTW, a motivation for this is that some of us have old repositories that have been upgrades all the way from annex.version 1 and have a lot of cruft in them because of it. (I have repos that have been upgraded from annex.version 0, but this would not help with that cruft which is on the master branch!)
+
+Also, people worry that eg, a large copy back and forth bloats history, and having a way to unbloat it if it ever gets actually annoyingly bloated would stop them pestering me. ;)
+"""]]
diff --git a/doc/todo/wishlist:_dropping_git-annex_history/comment_2_f6d750bfe0c9d8a2aa6bc218ca5c49cc._comment b/doc/todo/wishlist:_dropping_git-annex_history/comment_2_f6d750bfe0c9d8a2aa6bc218ca5c49cc._comment
new file mode 100644
index 000000000..a60973b82
--- /dev/null
+++ b/doc/todo/wishlist:_dropping_git-annex_history/comment_2_f6d750bfe0c9d8a2aa6bc218ca5c49cc._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 2"
+ date="2013-08-27T20:02:23Z"
+ content="""
+If starting commit id _and_ commit id from when history is being dropped are documented, you could potentially drop more data.
+
+* Don't have any commits in common? Full merge.
+* Only share the starting ids? Reduce local history as much as possible, and then merge.
+* Share both starting id and have the last id somewhere in history? Take history from last id up to current, reduce that, and merge.
+
+-- RichiH
+"""]]
diff --git a/doc/todo/wishlist:_encrypted_git_remote_on_hosting_site_from_webapp.mdwn b/doc/todo/wishlist:_encrypted_git_remote_on_hosting_site_from_webapp.mdwn
new file mode 100644
index 000000000..b7b1bad0c
--- /dev/null
+++ b/doc/todo/wishlist:_encrypted_git_remote_on_hosting_site_from_webapp.mdwn
@@ -0,0 +1 @@
+It would be great to be able to do **private encrypted git remote on hosting site** and **multiuser encrypted git remote on hosting site** as explained in [[tips/fully encrypted git repositories with gcrypt]] through the webapp. I think it's a pretty common usecase that can be very useful for people not owning a proper server.
diff --git a/doc/todo/wishlist:_generic_annex.cost-command.mdwn b/doc/todo/wishlist:_generic_annex.cost-command.mdwn
new file mode 100644
index 000000000..6adf1460e
--- /dev/null
+++ b/doc/todo/wishlist:_generic_annex.cost-command.mdwn
@@ -0,0 +1,17 @@
+### Current setup
+
+ATM git-annex has
+
+remote.<name>.annex-cost
+remote.<name>.annex-cost-command # command is not provided cmdline options by annex
+
+to set the cost for a given remote. That requires setting up one of those variables per each host, and possibly hardcoding options for the annex-cost-command providing e.g. the remote name.
+
+### Suggestion
+
+wouldn't it be more general and thus more flexible to have a repository-wide
+
+annex.cost-command
+
+which could take options %remote, %file and assessed accordingly per each file upon '--get' request to allow maximal flexibility: e.g. some files might better be fetched from remotes supporting transfer compression, some from the web, etc. Also it might be worth providing %remote_kind ("special" vs "git") to disambiguate %remote's?
+
diff --git a/doc/todo/wishlist:_git-annex_replicate.mdwn b/doc/todo/wishlist:_git-annex_replicate.mdwn
new file mode 100644
index 000000000..0d926b337
--- /dev/null
+++ b/doc/todo/wishlist:_git-annex_replicate.mdwn
@@ -0,0 +1,12 @@
+I'd like to be able to do something like the following:
+
+ * Create encrypted git-annex remotes on a couple of semi-trusted machines - ones that have good connectivity, but non-redundant hardware
+ * set numcopies=3
+ * run `git-annex replicate` and have git-annex run the appropriate copy commands to make sure every file is on at least 3 machines
+
+There would also likely be a `git annex rebalance` command which could be used if remotes were added or removed. If possible, it should copy files between servers directly, rather than proxy through a potentially slow client.
+
+There might be the need to have a 'replication_priority' option for each remote that configures which machines would be preferred. That way you could set your local server to a high priority to ensure that it is always 1 of the 3 machines used and files are distributed across 2 of the remaining remotes. Other than priority, other options that might help:
+
+ * maxspace - A self imposed quota per remote machine. git-annex replicate should try to replicate files first to machines with more free space. maxspace would change the free space calculation to be `min(actual_free_space, maxspace - space_used_by_git_annex)
+ * bandwidth - when replication files, copies should be done between machines with the highest available bandwidth. ( I think this option could be useful for git-annex get in general)
diff --git a/doc/todo/wishlist:_git-annex_replicate/comment_1_9926132ec6052760cdf28518a24e2358._comment b/doc/todo/wishlist:_git-annex_replicate/comment_1_9926132ec6052760cdf28518a24e2358._comment
new file mode 100644
index 000000000..cec971ee3
--- /dev/null
+++ b/doc/todo/wishlist:_git-annex_replicate/comment_1_9926132ec6052760cdf28518a24e2358._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 1"
+ date="2011-04-22T18:27:00Z"
+ content="""
+While having remotes redistribute introduces some obvious security concerns, I might use it.
+
+As remotes support a cost factor already, you can basically implement bandwidth through that.
+"""]]
diff --git a/doc/todo/wishlist:_git-annex_replicate/comment_2_c43932f4194aba8fb2470b18e0817599._comment b/doc/todo/wishlist:_git-annex_replicate/comment_2_c43932f4194aba8fb2470b18e0817599._comment
new file mode 100644
index 000000000..9d50d1531
--- /dev/null
+++ b/doc/todo/wishlist:_git-annex_replicate/comment_2_c43932f4194aba8fb2470b18e0817599._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 2"
+ date="2011-04-23T16:22:07Z"
+ content="""
+Besides the cost values, annex.diskreserve was recently added. (But is not available for special remotes.)
+
+I have held off on adding high-level management stuff like this to git-annex, as it's hard to make it generic enough to cover use cases.
+
+A low-level way to accomplish this would be to have a way for `git annex get` and/or `copy` to skip files when `numcopies` is already satisfied. Then cron jobs could be used.
+"""]]
diff --git a/doc/todo/wishlist:_git-annex_replicate/comment_3_c13f4f9c3d5884fc6255fd04feadc2b1._comment b/doc/todo/wishlist:_git-annex_replicate/comment_3_c13f4f9c3d5884fc6255fd04feadc2b1._comment
new file mode 100644
index 000000000..e7eb06b3b
--- /dev/null
+++ b/doc/todo/wishlist:_git-annex_replicate/comment_3_c13f4f9c3d5884fc6255fd04feadc2b1._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="comment 3"
+ date="2011-04-23T17:54:42Z"
+ content="""
+Hmm, so it seems there is almost a way to do this already.
+
+I think the one thing that isn't currently possible is to have 'plain' ssh remotes.. basically something just like the directory remote, but able to take a ssh user@host/path url. something like sshfs could be used to fake this, but for things like fsck you would want to do the sha1 calculations on the remote host.
+"""]]
diff --git a/doc/todo/wishlist:_git-annex_replicate/comment_4_63f24abf086d644dced8b01e1a9948c9._comment b/doc/todo/wishlist:_git-annex_replicate/comment_4_63f24abf086d644dced8b01e1a9948c9._comment
new file mode 100644
index 000000000..3805464a6
--- /dev/null
+++ b/doc/todo/wishlist:_git-annex_replicate/comment_4_63f24abf086d644dced8b01e1a9948c9._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 4"
+ date="2011-09-19T18:54:46Z"
+ content="""
+git annex get/copy/drop all now support a --auto flag, which makes them only act on files that have not enough or too many copies. This allows for some crude replication; it doesn't take into account which repositories should be filled up more (beyond honoring annex.diskreserve), nor does it try to optimally use bandwidth (beyond honoring configured annex-cost). You have to run it in every repository that you want to participate in the replication, too. But it's probably a Good Enough solution. See [[walkthrough/automatically_managing_content]].
+"""]]
diff --git a/doc/todo/wishlist:_git_annex_diff.mdwn b/doc/todo/wishlist:_git_annex_diff.mdwn
new file mode 100644
index 000000000..4acfee255
--- /dev/null
+++ b/doc/todo/wishlist:_git_annex_diff.mdwn
@@ -0,0 +1,9 @@
+git diff is not very helpful for annexed files.
+
+How about a git annex diff command that allows to compare two versions of an annexed file?
+
+Should be relatively simple, only there would have to be a way to deal with the situation where not both versions are present in the repository. Either abort with a message showing the command you need to run to get the missing version(s). Or even interactively volunteer to get it automatically, asking the user for confirmation.
+
+Of course you wouldn't want to diff two large files, but with git annex assistant, all files are annexed by default (right?), so this would be useful.
+
+There might already be a way to easily diff two versions of an annexed file which I'm missing -- in that case please point me to it! :)
diff --git a/doc/todo/wishlist:_git_annex_put_--_same_as_get__44___but_for_defaults.mdwn b/doc/todo/wishlist:_git_annex_put_--_same_as_get__44___but_for_defaults.mdwn
new file mode 100644
index 000000000..9cd56749e
--- /dev/null
+++ b/doc/todo/wishlist:_git_annex_put_--_same_as_get__44___but_for_defaults.mdwn
@@ -0,0 +1,17 @@
+I am running centralized git-annex exclusively.
+
+Similar to
+
+ git annex get
+
+I'd like to have a
+
+ git annex put
+
+which would put all files on the default remote(s).
+
+My main reason for not wanting to use copy --to is that I need to specify the remote's name in this case which makes writing a wrapper unnecessarily hard. Also, this would allow
+
+ mr push
+
+to do the right thing all by itself.
diff --git a/doc/todo/wishlist:_git_annex_put_--_same_as_get__44___but_for_defaults/comment_1_d5413c8acce308505e4e2bec82fb1261._comment b/doc/todo/wishlist:_git_annex_put_--_same_as_get__44___but_for_defaults/comment_1_d5413c8acce308505e4e2bec82fb1261._comment
new file mode 100644
index 000000000..fe1d5520f
--- /dev/null
+++ b/doc/todo/wishlist:_git_annex_put_--_same_as_get__44___but_for_defaults/comment_1_d5413c8acce308505e4e2bec82fb1261._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-04-04T18:13:46Z"
+ content="""
+This begs the question: What is the default remote? It's probably *not* the same repository that git's master branch is tracking (ie, origin/master). It seems there would have to be an annex.defaultremote setting.
+
+BTW, mr can easily be configured on a per-repo basis so that \"mr push\" copies to somewhere: `push = git push; git annex push wherever`
+"""]]
diff --git a/doc/todo/wishlist:_git_annex_put_--_same_as_get__44___but_for_defaults/comment_2_0aa227c85d34dfff4e94febca44abea8._comment b/doc/todo/wishlist:_git_annex_put_--_same_as_get__44___but_for_defaults/comment_2_0aa227c85d34dfff4e94febca44abea8._comment
new file mode 100644
index 000000000..3090b575b
--- /dev/null
+++ b/doc/todo/wishlist:_git_annex_put_--_same_as_get__44___but_for_defaults/comment_2_0aa227c85d34dfff4e94febca44abea8._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 2"
+ date="2011-04-04T20:45:30Z"
+ content="""
+In my case, the remotes are the same, but adding a new option could make sense.
+
+And while I can tell mr what to do explicitly, I would prefer if it did the right thing all by itself. Having to change configs in two separate places is less than ideal.
+
+I am not sure what you mean by `git annex push` as that does not exist. Did you mean copy?
+"""]]
diff --git a/doc/todo/wishlist:_git_annex_put_--_same_as_get__44___but_for_defaults/comment_3_2082f4d708a584a1403cc1d4d005fb56._comment b/doc/todo/wishlist:_git_annex_put_--_same_as_get__44___but_for_defaults/comment_3_2082f4d708a584a1403cc1d4d005fb56._comment
new file mode 100644
index 000000000..01dc7813f
--- /dev/null
+++ b/doc/todo/wishlist:_git_annex_put_--_same_as_get__44___but_for_defaults/comment_3_2082f4d708a584a1403cc1d4d005fb56._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 1"
+ date="2011-04-04T10:28:01Z"
+ content="""
+Going one step further, a --min-copy could put all files so that numcopies is satisfied. --all could push to all available ones.
+
+To take everything another step further, if it was possible to group remotes, one could act on the groups. \"all\" would be an obvious choice for a group that always exists, everything else would be set up by the user.
+"""]]
diff --git a/doc/todo/wishlist:_git_annex_status.mdwn b/doc/todo/wishlist:_git_annex_status.mdwn
new file mode 100644
index 000000000..6bb5d71f1
--- /dev/null
+++ b/doc/todo/wishlist:_git_annex_status.mdwn
@@ -0,0 +1,21 @@
+Ideally, it would look similar to this. And yes, I put "put" in there ;)
+
+ non-annex % git annex status
+ git annex status: error: not a git annex repository
+ annex % git annex status
+ annex object storage version: A
+ annex backend engine: {WORM,SHA512,...}
+ Estimated local annex size: B MiB
+ Estimated total annex size: C MiB
+ Files without file size information in local annex: D
+ Files without file size information in total annex: E
+ Last fsck: datetime
+ Last git pull: datetime - $annex_name
+ Last git push: datetime - $annex_name
+ Last git annex get: datetime - $annex_name
+ Last git annex put: datetime - $annex_name
+ annex %
+
+Datetime could be ISO's YYYY-MM-DDThh:mm:ss or, personal preference, YYYY-MM-DD--hh-mm-ss. I prefer the latter as it's DNS-, tag- and filename-safe which is why I am using it for everything. In a perfect world, ISO would standardize YYYY-MM-DD-T-hh-mm-ss-Z[-SSSSSSSS][--$timezone], but meh.
+
+[[done]]
diff --git a/doc/todo/wishlist:_git_annex_status/comment_1_994bfd12c5d82e08040d6116915c5090._comment b/doc/todo/wishlist:_git_annex_status/comment_1_994bfd12c5d82e08040d6116915c5090._comment
new file mode 100644
index 000000000..7b5e7bd44
--- /dev/null
+++ b/doc/todo/wishlist:_git_annex_status/comment_1_994bfd12c5d82e08040d6116915c5090._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 1"
+ date="2011-04-08T07:23:08Z"
+ content="""
++1 for this feature, I've been longing for something like this other than rolling my own perl/shell scripts to parse the outputs of \"git annex whereis .\" to see how many files are on my machine or not.
+"""]]
diff --git a/doc/todo/wishlist:_git_annex_status/comment_2_c2b0ce025805b774dc77ce264a222824._comment b/doc/todo/wishlist:_git_annex_status/comment_2_c2b0ce025805b774dc77ce264a222824._comment
new file mode 100644
index 000000000..21f9d713c
--- /dev/null
+++ b/doc/todo/wishlist:_git_annex_status/comment_2_c2b0ce025805b774dc77ce264a222824._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://christian.amsuess.com/chrysn"
+ nickname="chrysn"
+ subject="format, respect working directory"
+ date="2011-04-26T12:31:02Z"
+ content="""
+we could include the information about the current directory as well, if the command is not issued in the local git root directory. to avoid large numbers of similar lines, that could look like this:
+
+ Estimated annex size: B MiB (of C MiB; [B/C]%)
+ Estimated annex size in $PWD: B' MiB (of C' MiB; [B'/C']%)
+
+with the percentages being replaced with \"complete\" if really all files are present (and not just many enough for the value to be rounded to 100%).
+"""]]
diff --git a/doc/todo/wishlist:_git_annex_status/comment_3_d1fd70c67243971c96d59e1ffb7ef6e7._comment b/doc/todo/wishlist:_git_annex_status/comment_3_d1fd70c67243971c96d59e1ffb7ef6e7._comment
new file mode 100644
index 000000000..39986144b
--- /dev/null
+++ b/doc/todo/wishlist:_git_annex_status/comment_3_d1fd70c67243971c96d59e1ffb7ef6e7._comment
@@ -0,0 +1,23 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 3"
+ date="2011-05-17T01:15:10Z"
+ content="""
+What a good idea!
+
+150 lines of haskell later, I have this:
+
+<pre>
+# git annex status
+supported backends: WORM SHA1 SHA256 SHA512 SHA224 SHA384 SHA1E SHA256E SHA512E SHA224E SHA384E URL
+supported remote types: git S3 bup directory rsync hook
+local annex keys: 32
+local annex size: 58 megabytes
+total annex keys: 38158
+total annex size: 6 terabytes (but 1632 keys have unknown size)
+backend usage:
+ SHA1: 1789
+ WORM: 36369
+</pre>
+"""]]
diff --git a/doc/todo/wishlist:_git_annex_status/comment_4_9aeeb83d202dc8fb33ff364b0705ad94._comment b/doc/todo/wishlist:_git_annex_status/comment_4_9aeeb83d202dc8fb33ff364b0705ad94._comment
new file mode 100644
index 000000000..f006f88a0
--- /dev/null
+++ b/doc/todo/wishlist:_git_annex_status/comment_4_9aeeb83d202dc8fb33ff364b0705ad94._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://christian.amsuess.com/chrysn"
+ nickname="chrysn"
+ subject="status of other remotes?"
+ date="2011-06-15T08:39:24Z"
+ content="""
+using the location tracking information, it should be possible to show the status of other remotes as well. what about supporting `--from=...` or `--all`? (thus, among other things, one could determine if a remote has a complete checkout.)
+"""]]
diff --git a/doc/todo/wishlist:_git_backend_for_git-annex.mdwn b/doc/todo/wishlist:_git_backend_for_git-annex.mdwn
new file mode 100644
index 000000000..fd1b40bff
--- /dev/null
+++ b/doc/todo/wishlist:_git_backend_for_git-annex.mdwn
@@ -0,0 +1,9 @@
+Preamble: Obviously, the core feature of git-annex is the ability to keep a subset of files in a local repo. The main trade-off is that you don't get version tracking.
+
+Use case: On my laptop, I might not have enough disk space to store everything. Not so for my main box nor my backup server. And I would _really_ like to have proper version tracking for many of my files. Thus...
+
+Wish: ...why not use git as a version backend? That way, I could just push all my stuff to the central instance(s) and have the best of both worlds. Depending on what backend is used in the local repos, it might make sense to define a list of supported client backends with pre-computed keys.
+
+-- RichiH
+
+[[done]] (bup)
diff --git a/doc/todo/wishlist:_git_backend_for_git-annex/comment_1_04319051fedc583e6c326bb21fcce5a5._comment b/doc/todo/wishlist:_git_backend_for_git-annex/comment_1_04319051fedc583e6c326bb21fcce5a5._comment
new file mode 100644
index 000000000..a691393b1
--- /dev/null
+++ b/doc/todo/wishlist:_git_backend_for_git-annex/comment_1_04319051fedc583e6c326bb21fcce5a5._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-03-28T16:01:30Z"
+ content="""
+Indeed, see [[todo/add_a_git_backend]], where you and I have already discussed this idea. :)
+
+With the new support for special remotes, which will be used by S3, it would be possible to make such a git repo, using bup, be a special remote. I think it would be pretty easy to implement now. Not a priority for me though.
+"""]]
diff --git a/doc/todo/wishlist:_git_backend_for_git-annex/comment_2_7f529f19a47e10b571f65ab382e97fd5._comment b/doc/todo/wishlist:_git_backend_for_git-annex/comment_2_7f529f19a47e10b571f65ab382e97fd5._comment
new file mode 100644
index 000000000..14798e7a7
--- /dev/null
+++ b/doc/todo/wishlist:_git_backend_for_git-annex/comment_2_7f529f19a47e10b571f65ab382e97fd5._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 2"
+ date="2011-03-28T17:47:38Z"
+ content="""
+On the plus side, the past me wanted exactly what I had in mind.
+
+On the meh side, I really forgot about this conversation :/
+
+When you say this todo is not a priority, does that mean there's no ETA at all and that it will most likely sleep for a long time? Or the almost usual \"what the heck, I will just wizard it up in two lines of haskell\"?
+
+-- RichiH
+"""]]
diff --git a/doc/todo/wishlist:_git_backend_for_git-annex/comment_3_a077bbad3e4b07cce019eb55a45330e7._comment b/doc/todo/wishlist:_git_backend_for_git-annex/comment_3_a077bbad3e4b07cce019eb55a45330e7._comment
new file mode 100644
index 000000000..8c3286d27
--- /dev/null
+++ b/doc/todo/wishlist:_git_backend_for_git-annex/comment_3_a077bbad3e4b07cce019eb55a45330e7._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 3"
+ date="2011-03-28T20:05:13Z"
+ content="""
+Probably more like 150 lines of haskell. Maybe just 50 lines if the bup repository is required to be on the same computer as the git-annex repository.
+
+Since I do have some repositories where I'd appreciate this level of assurance that data not be lost, it's mostly a matter of me finding a free day.
+"""]]
diff --git a/doc/todo/wishlist:_git_backend_for_git-annex/comment_4_ecca429e12d734b509c671166a676c9d._comment b/doc/todo/wishlist:_git_backend_for_git-annex/comment_4_ecca429e12d734b509c671166a676c9d._comment
new file mode 100644
index 000000000..cf649a8a2
--- /dev/null
+++ b/doc/todo/wishlist:_git_backend_for_git-annex/comment_4_ecca429e12d734b509c671166a676c9d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 4"
+ date="2011-03-28T20:45:35Z"
+ content="""
+Personally, I would not mind a requirement to keep a local bup repo. I wouldn't want my data to to unncessarily complex setups, anyway. -- RichiH
+"""]]
diff --git a/doc/todo/wishlist:_git_backend_for_git-annex/comment_5_3459f0b41d818c23c8fb33edb89df634._comment b/doc/todo/wishlist:_git_backend_for_git-annex/comment_5_3459f0b41d818c23c8fb33edb89df634._comment
new file mode 100644
index 000000000..a1300f2e6
--- /dev/null
+++ b/doc/todo/wishlist:_git_backend_for_git-annex/comment_5_3459f0b41d818c23c8fb33edb89df634._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 5"
+ date="2011-04-08T20:59:37Z"
+ content="""
+My estimates were pretty close -- the new bup special remote type took 133 lines of code, and 2 hours to write. A testament to the flexibility of the special remote infrastructure. :)
+"""]]
diff --git a/doc/todo/wishlist:_history_of_operations.mdwn b/doc/todo/wishlist:_history_of_operations.mdwn
new file mode 100644
index 000000000..a79f500ff
--- /dev/null
+++ b/doc/todo/wishlist:_history_of_operations.mdwn
@@ -0,0 +1,8 @@
+Hi,
+
+I would love to have a page of "history" or "events" in the webapp. Similar to how Dropbox or Box show it.
+I've been using git-annex for my personal files for a few months now, and I feel like this is the only feature missing to start using it in a production multi-user environment.
+
+Thanks
+
+[[!tag design/assistant]]
diff --git a/doc/todo/wishlist:_history_of_operations/comment_1_f9a77ce83c6f39b6272d5c577ffbb9f9._comment b/doc/todo/wishlist:_history_of_operations/comment_1_f9a77ce83c6f39b6272d5c577ffbb9f9._comment
new file mode 100644
index 000000000..bb872532d
--- /dev/null
+++ b/doc/todo/wishlist:_history_of_operations/comment_1_f9a77ce83c6f39b6272d5c577ffbb9f9._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawlJEI45rGczFAnuM7gRSj4C6s9AS9yPZDc"
+ nickname="Kevin"
+ subject="I second this wishlist item"
+ date="2013-07-24T16:48:59Z"
+ content="""
+I too would like to see a recent history of events in the assistant webapp. A simple listing of what changed when and by whom would be sufficient.
+"""]]
diff --git a/doc/todo/wishlist:_incremental_unannex___40__currently_requires_twice_the_size_of_repo_to_complete__41__.mdwn b/doc/todo/wishlist:_incremental_unannex___40__currently_requires_twice_the_size_of_repo_to_complete__41__.mdwn
new file mode 100644
index 000000000..420fb882c
--- /dev/null
+++ b/doc/todo/wishlist:_incremental_unannex___40__currently_requires_twice_the_size_of_repo_to_complete__41__.mdwn
@@ -0,0 +1,10 @@
+I recently tried to use unannex for a large repo and it failed because the repo size was more than half the disk size. Unannex should work incrementally so this isn't a problem.
+
+Proposed solution:
+copy a file, hash it, iff hash check is okay, delete from objects, continue to next file
+
+> That won't work, because multiple files can point to a key.
+>
+> I am not happy with unannex's behavior, but I was less happy
+> when people were constantly filing bugs about it misbehaving in that
+> situttion. If you dislike the copying, use --fast. [[done]] --[[Joey]]
diff --git a/doc/todo/wishlist:_incremental_unannex___40__currently_requires_twice_the_size_of_repo_to_complete__41__/comment_1_067b29fc47d26b9da0766f9810684ae8._comment b/doc/todo/wishlist:_incremental_unannex___40__currently_requires_twice_the_size_of_repo_to_complete__41__/comment_1_067b29fc47d26b9da0766f9810684ae8._comment
new file mode 100644
index 000000000..372bb621f
--- /dev/null
+++ b/doc/todo/wishlist:_incremental_unannex___40__currently_requires_twice_the_size_of_repo_to_complete__41__/comment_1_067b29fc47d26b9da0766f9810684ae8._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="GLITTAH"
+ ip="78.108.63.46"
+ subject="comment 1"
+ date="2013-11-19T18:15:15Z"
+ content="""
+Perhaps when unannex is invoked, it could check to see if there is enough disk space before it begins copying files. Maybe even warn the user of too little disk space and remind them of --fast.
+
+(Sorry for the dupe!)
+"""]]
diff --git a/doc/todo/wishlist:_make_git_annex_reinject_work_in_direct_mode.mdwn b/doc/todo/wishlist:_make_git_annex_reinject_work_in_direct_mode.mdwn
new file mode 100644
index 000000000..ffdee8840
--- /dev/null
+++ b/doc/todo/wishlist:_make_git_annex_reinject_work_in_direct_mode.mdwn
@@ -0,0 +1,21 @@
+### Please describe the problem.
+
+`git annex reinject` refuses to work while in direct mode.
+
+When in direct mode git annex reinject could simply perform `rm $symlink; mv $file_copy .; git annex add $file`. I prefer having git annex doing that so I am sure I am not messing up (mistakenly adding new files for instance) and everything is properly managed.
+
+### What version of git-annex are you using? On what operating system?
+
+git-annex 4.20130516.1
+
+~~~~
+$ lsb_release -a
+No LSB modules are available.
+Distributor ID: Ubuntu
+Description: Ubuntu 12.04.2 LTS
+Release: 12.04
+Codename: precise
+~~~~
+
+> [[fixed|done]]. Why did I take so long to do this, it was a trivial 1
+> word change! --[[Joey]]
diff --git a/doc/todo/wishlist:_make_partial_files_available_during_transfer.mdwn b/doc/todo/wishlist:_make_partial_files_available_during_transfer.mdwn
new file mode 100644
index 000000000..b021c9091
--- /dev/null
+++ b/doc/todo/wishlist:_make_partial_files_available_during_transfer.mdwn
@@ -0,0 +1,18 @@
+Imagine this situation:
+You have a laptop and a NAS.
+On your laptop you want to consume a large media file located on the NAS.
+So you type:
+
+ git annex get --from nas mediafile
+
+But now you have to wait for the download to complete, unless either
+
+* rsync is pointed directly to the file in the object storage ("--inplace")
+or
+* the symlink temporarily points to the partial file during a transfer
+
+which would allow you instantaneous consumption of your media.
+It might make sense to make this behavior configurable, because not everyone might agree with having partial content (that mismatches its key) around.
+
+
+So what do you say?
diff --git a/doc/todo/wishlist:_make_partial_files_available_during_transfer/comment_3_1304a721da6f5133fdfa1dac507f1ecb._comment b/doc/todo/wishlist:_make_partial_files_available_during_transfer/comment_3_1304a721da6f5133fdfa1dac507f1ecb._comment
new file mode 100644
index 000000000..8e955fd48
--- /dev/null
+++ b/doc/todo/wishlist:_make_partial_files_available_during_transfer/comment_3_1304a721da6f5133fdfa1dac507f1ecb._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.194"
+ subject="comment 3"
+ date="2012-11-04T19:58:28Z"
+ content="""
+I'm not at all comfortable with either idea. Temporarily repointing the symlink could lead to accidentially git committing a bad symlink. Or the user accidentially doing something with a partially transferred file. Running rsync in place would break lots of things that assume that, once the file is present, it can be assumed to be the full and correct file. (Obviously fsck doesn't assume that, but checks made by `git annex drop` do, for example.)
+
+However, you can access partially transferred files by key in `.git/annex/tmp`. It would be easy to write some hack that looks at the symlink to get the key, and then spits out the name of the partial file in `.git/annex/tmp.`.
+"""]]
diff --git a/doc/todo/wishlist:_more_descriptive_commit_messages_in_git-annex_branch.mdwn b/doc/todo/wishlist:_more_descriptive_commit_messages_in_git-annex_branch.mdwn
new file mode 100644
index 000000000..3a891fc9b
--- /dev/null
+++ b/doc/todo/wishlist:_more_descriptive_commit_messages_in_git-annex_branch.mdwn
@@ -0,0 +1,39 @@
+as of git-annex version 3.20110719, all git-annex commits only contain the word "update" as a commit message. given that the contents of the commit are pretty non-descriptive (SHA1 hashes for file names, uuids for repository names), i suggest to have more descriptive commit messages, as shown here:
+
+ /mnt/usb_disk/photos/2011$ git annex get
+ /mnt/usb_disk/photos/2011$ git show git-annex
+ [...]
+ usb-disk-photos: get 2011
+
+ * 10 files retrieved from 2 sources (9 from local-harddisk, 1 from my-server)
+ * 120 files were already present
+ * 2 files could not be retrieved
+ /mnt/usb_disk/photos/2011$ cd ~/photos/2011/07
+ ~/photos/2011/07$ git copy --to my-server
+ ~/photos/2011/07$ git show git-annex
+ [...]
+ local-harddisk: copy 2011/07 to my-server
+
+ * 20 files pushed
+ ~/photos/2011/07$
+
+in my opinion, the messages should at least contain
+
+* what command was used
+* in which repository they were executed
+* which files or directories they affected (not necessarily all files, but what was given on command line or implicitly from the working directory)
+
+--[[chrysn]]
+
+> The implementation of the git-annex branch precludes more descriptive
+> commit messages, since a single commit can include changes that were
+> previously staged to the branch's index file, or spooled to its journal
+> by other git-annex commands (either concurrently running or
+> interrupted commands, or even changes needed to automatically merge
+> other git-annex branches).
+>
+> It would be possible to make it *less* verbose, with an empty commit
+> message. :) --[[Joey]]
+
+>> Closing as this is literally impossible to do without making
+>> git-annex worse. [[done]] --[[Joey]]
diff --git a/doc/todo/wishlist:_more_info_in_the_standard_commit_message_of___96__sync__96__.mdwn b/doc/todo/wishlist:_more_info_in_the_standard_commit_message_of___96__sync__96__.mdwn
new file mode 100644
index 000000000..4e5e3a171
--- /dev/null
+++ b/doc/todo/wishlist:_more_info_in_the_standard_commit_message_of___96__sync__96__.mdwn
@@ -0,0 +1,3 @@
+Could you include the REPO and UUID information in the "automatic sync" commit message?
+
+This would make troubleshooting easier. (not there was much trouble with git-annex!)
diff --git a/doc/todo/wishlist:_move_pending_transfers_for_a_host_to_the_end_of_the_queue_when_one_fails.mdwn b/doc/todo/wishlist:_move_pending_transfers_for_a_host_to_the_end_of_the_queue_when_one_fails.mdwn
new file mode 100644
index 000000000..e50ebbde5
--- /dev/null
+++ b/doc/todo/wishlist:_move_pending_transfers_for_a_host_to_the_end_of_the_queue_when_one_fails.mdwn
@@ -0,0 +1,7 @@
+Right now the assistant can have a huge list of pending transfers for certain hosts if its data is a bit outdated, or a host hasn't been synced lately. When starting up it will then attempt each transfer to said host (which will in turn fail, but at times take time to time out), possibly before doing other stuff like attempting to download new files, or copy files to online hosts.
+
+I suggest that if a transfer fails for host X, and there are other pending transfers, say to host Y and from Z, then all other pending transfers to/from X gets pushed to the back of the queue, to avoid having to wait a long time for several transfers to time out before doing useful stuff.
+
+The prime example for me was this morning, when a laptop that was turned off had a huge amount of queued transfers to it, resulting in the assistant attempting a load of transfers to that host before it retrieved a new file that I had created on another machine yesterday.
+
+[[!tag design/assistant]]
diff --git a/doc/todo/wishlist:_move_pending_transfers_for_a_host_to_the_end_of_the_queue_when_one_fails/comment_1_82ee9de610a0ac55cd1c27c211079e5b._comment b/doc/todo/wishlist:_move_pending_transfers_for_a_host_to_the_end_of_the_queue_when_one_fails/comment_1_82ee9de610a0ac55cd1c27c211079e5b._comment
new file mode 100644
index 000000000..3b6101ed5
--- /dev/null
+++ b/doc/todo/wishlist:_move_pending_transfers_for_a_host_to_the_end_of_the_queue_when_one_fails/comment_1_82ee9de610a0ac55cd1c27c211079e5b._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.6.49"
+ subject="comment 1"
+ date="2012-12-01T19:22:03Z"
+ content="""
+There are several difficulties with reordering the queue that way. One is that the failure may be intermittent; another is that the queue is fed by a scanning process, so doesn't always have a well-defined end.
+
+Another way to deal with this problem, which I think I prefer, is to allow multiple actions from the queue to run at once. Then slow or unreachable remotes don't block it from using other remotes.
+"""]]
diff --git a/doc/todo/wishlist:_move_pending_transfers_for_a_host_to_the_end_of_the_queue_when_one_fails/comment_2_bea55156bd32cf9e6dd9b946ba1bb8c1._comment b/doc/todo/wishlist:_move_pending_transfers_for_a_host_to_the_end_of_the_queue_when_one_fails/comment_2_bea55156bd32cf9e6dd9b946ba1bb8c1._comment
new file mode 100644
index 000000000..62d46bccd
--- /dev/null
+++ b/doc/todo/wishlist:_move_pending_transfers_for_a_host_to_the_end_of_the_queue_when_one_fails/comment_2_bea55156bd32cf9e6dd9b946ba1bb8c1._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="EskildHustvedt"
+ ip="84.48.83.221"
+ subject="comment 2"
+ date="2012-12-01T19:31:18Z"
+ content="""
+I agree your method might be preferable, the end result is the same, and would have avoided the issues I had (and, of course, running multiple transfers at once has other benefits as well).
+
+An alternate way would be to push every transfer NOT from host X to the front of the queue (avoiding most of the \"no defined end\" issue and largely solving the problem), but if multiple actions at once is feasible then that'd still be much nicer.
+"""]]
diff --git a/doc/todo/wishlist:_option_to_disable_url_checking_with_addurl.mdwn b/doc/todo/wishlist:_option_to_disable_url_checking_with_addurl.mdwn
new file mode 100644
index 000000000..d0b847933
--- /dev/null
+++ b/doc/todo/wishlist:_option_to_disable_url_checking_with_addurl.mdwn
@@ -0,0 +1,9 @@
+I'm testing out an idea of using filter-branch on a git repository to both retroactively annex and AND record a weburl for all relevant files.
+
+c.f. [http://git-annex.branchable.com/tips/How_to_retroactively_annex_a_file_already_in_a_git_repo/](http://git-annex.branchable.com/tips/How_to_retroactively_annex_a_file_already_in_a_git_repo/)
+
+The bottleneck I'm hitting here seems to be the fact that `git annex addurl` diligently checks each url to see that it is accessible, which adds up quickly if many files are to be processed.
+
+It would be great if addurl had an option to disable checking the url, in order to speed up large batch jobs like this.
+
+> --relaxed added [[done]] --[[Joey]]
diff --git a/doc/todo/wishlist:_option_to_disable_url_checking_with_addurl/comment_1_868a380faa1e55faa3c2d314e3258e86._comment b/doc/todo/wishlist:_option_to_disable_url_checking_with_addurl/comment_1_868a380faa1e55faa3c2d314e3258e86._comment
new file mode 100644
index 000000000..4bdf4c97b
--- /dev/null
+++ b/doc/todo/wishlist:_option_to_disable_url_checking_with_addurl/comment_1_868a380faa1e55faa3c2d314e3258e86._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 1"
+ date="2013-03-11T18:19:34Z"
+ content="""
+It does this to get the size of the url, so it can record this in the key. It would be possible to add a flag to skip that (--fast is already taken of course), but then you tend to get a lot of keys in your repository with no size info attached, which makes `git annex status` complain that it cannot tell you exactly how big your repo is, and is generally not the best. It also defeats annex.diskreserve checking, for example.
+
+With --fast, the size is the only info available to ensure that the content behind the url has not changed when downloading it later. I suppose for some urls you may not want that checked, and so a --relaxed type option could make sense in that use case as well, although with the above caveat.
+"""]]
diff --git a/doc/todo/wishlist:_option_to_print_more_info_with___39__unused__39__.mdwn b/doc/todo/wishlist:_option_to_print_more_info_with___39__unused__39__.mdwn
new file mode 100644
index 000000000..7a9b81f72
--- /dev/null
+++ b/doc/todo/wishlist:_option_to_print_more_info_with___39__unused__39__.mdwn
@@ -0,0 +1,37 @@
+It would be nice if the 'unused' command could optionally display info about the actual files behind its cryptic keys.
+
+I created a (very rough) bash script that simply splices in some info from git log -S'KEY' --numstat into the unused list, like so:
+
+ arand@mas:~/annex(master)$ bash ~/utv/scripts/annex-vunused
+ unused . (checking for unused data...) (checking master...) (checking synced/master...) (checking origin/HEAD...) (checking seagate/master...)
+ Some annexed data is no longer used by any files:
+ NUMBER KEY
+ 1 SHA256E-s1073741824--49bc20df15e412a64472421e13fe86ff1c5165e18b2afccf160d4dc19fe68a14.img
+ 8f479a4 Sat Feb 23 16:14:12 2013 +0100 remove bigfile
+ 0 1 dummy_bigfile.img
+ 2988d18 Sat Feb 23 16:13:48 2013 +0100 dummy file
+ 1 0 dummy_bigfile.img
+ (To see where data was previously used, try: git log --stat -S'KEY')To remove unwanted data: git-annex dropunused NUMBER
+ ok
+The script:
+
+ #!/bin/bash
+
+ pipe="$(mktemp -u)"
+ mkfifo "$pipe"
+
+ git annex unused >"$pipe" || exit 1 &
+
+ while read -r line
+ do
+ key="$(echo "$line" | sed 's/^[^-]*-\([^-]*\)-.*/\1/')"
+ echo -n "$line"
+ test -n "$key" && \
+ echo && \
+ git log --format="%h %cd %s" --numstat -S"$key" | \
+ sed '/^$/d;/git-annex automatic sync/,/^ /d;s/^/\t\t/'
+
+ done < "$pipe"
+ rm "$pipe"
+
+It would be nice if something like this was available as an option, since it's good way to get a quick overview of what the content is, and if it's safe to drop it.
diff --git a/doc/todo/wishlist:_perform_fsck_remotely.mdwn b/doc/todo/wishlist:_perform_fsck_remotely.mdwn
new file mode 100644
index 000000000..f2187d912
--- /dev/null
+++ b/doc/todo/wishlist:_perform_fsck_remotely.mdwn
@@ -0,0 +1,39 @@
+Currently, when `fsck`'ing a remote, files are first downloaded to a temporary
+file locally, decrypted if needed, and finally digested; the temporary file is
+then either thrown away, or quarantined, depending on the value of that digest.
+
+Whereas this approach works with any kind of remote, in the particular case
+where the user is granted execution rights on the digest command, one could
+avoid cluttering the network and digest the file remotely. I propose the
+addition of a per-remote git option `annex-remote-fsck` to switch between the
+two behaviors.
+
+
+There is an issue with encrypted specialremotes, though. As hinted at
+[[here|tips/beware_of_SSD_wear_when_doing_fsck_on_large_special_remotes/#comment-70055f166f7eeca976021d24a736b471]],
+since the digest of a ciphertext can't be deduced from that of a plaintext in
+general one would needs, before sending an encrypted file to such a remote, to
+digest it and store that digest somewhere (together with the cipher's size and
+perhaps other meta-information).
+
+The usual directory structure (`.../.../{backend}-s{size}--{digest}.log`) seems
+perfectly suitable to store these informations. Lines there would look like
+`{timestamp}s {numcopy} {UUID} {remote digest}`. Of course, it implies that
+remote digest commands are trustworthy (are doing the right thing), and that
+the digest output are not tampered by others who have access to the git repo.
+But that's outside the current threat model, I guess.
+
+Actually, since git-annex always includes a MDC in the ciphertexts, we could do
+something clever and even avoid running a digest algorithm. According to the
+[[OpenPGP standard|https://tools.ietf.org/html/rfc4880#section-5.14]] the MDC
+is essentially a SHA-1 hash of the plaintext. I'm still investigating if it's
+even possible, but in theory it would be enough (with non-chained ciphers at
+least) to download a few bytes from the encrypted remote, decrypt those bytes
+to retrieve the hash, and compare that hash with the known value. Of course
+there is a downside here, namely that files tampered anywhere but on the MDC
+packets would not be detected by `fsck` (but gpg will warn when decrypting the
+file).
+
+
+My 2 cents :-) Is there something I missed? I suppose there was a reason to
+perform `fsck` locally at the first place...
diff --git a/doc/todo/wishlist:_perform_fsck_remotely/comment_1_db92311dcdb1ef0ab0413f83e191c70c._comment b/doc/todo/wishlist:_perform_fsck_remotely/comment_1_db92311dcdb1ef0ab0413f83e191c70c._comment
new file mode 100644
index 000000000..6bf6af23a
--- /dev/null
+++ b/doc/todo/wishlist:_perform_fsck_remotely/comment_1_db92311dcdb1ef0ab0413f83e191c70c._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 1"
+ date="2013-08-22T15:18:35Z"
+ content="""
+The only reason fsck is done locally for remotes is ease of implementation and it being a generic operation that supports any kind of special remote.
+
+Seems that the the only types of remotes where a remote fsck is a possibility are some rsync remotes and git remotes.
+git remotes already have git-annex installed, so the fsck could be run locally on the remote system using it.
+
+I don't know if I see a benefit with the MDC check. Any non-malicious data corruption on the remote is likely to affect the body of the file and not the small portion that holds the MDC. So checking the MDC does not seem much better than the current existence check done by `git annex fsck --fast --from remote`.
+
+As for storing the remote digest on the git-annex branch, my initial reaction was just that it's potentially a lot of bloat. Thinking about it some more, when using non-shared encryption, there is currently no way, given just a clone of a git repository, to match up files in git with encrypted objects stored on a special remote. So storing the remote digest might be considered to weaken the security.
+"""]]
diff --git a/doc/todo/wishlist:_perform_fsck_remotely/comment_2_2f0dbaf143d94290bfbebb6869eb7241._comment b/doc/todo/wishlist:_perform_fsck_remotely/comment_2_2f0dbaf143d94290bfbebb6869eb7241._comment
new file mode 100644
index 000000000..5418ff991
--- /dev/null
+++ b/doc/todo/wishlist:_perform_fsck_remotely/comment_2_2f0dbaf143d94290bfbebb6869eb7241._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="guilhem"
+ ip="129.16.20.209"
+ subject="comment 2"
+ date="2013-08-22T16:56:55Z"
+ content="""
+Oh yeah, the MDC paragraph was pretty much pointless indeed. Oops :-P
+
+I agree that this would potentially add some noise to the index, and weaken the
+security, but depending on the threat model and people's preferences that's an
+option that's worth considering IMHO.
+"""]]
diff --git a/doc/todo/wishlist:_print_locations_for_files_in_rsync_remote.mdwn b/doc/todo/wishlist:_print_locations_for_files_in_rsync_remote.mdwn
new file mode 100644
index 000000000..3876f2197
--- /dev/null
+++ b/doc/todo/wishlist:_print_locations_for_files_in_rsync_remote.mdwn
@@ -0,0 +1,6 @@
+Based on an irc conversation earlier today:
+
+19:50 < warp> joeyh: what is the best way to figure out the (remote) filename for a file stored in an rsync remote?
+
+20:43 < joeyh> warp: re your other question, probably the best thing would be to make the whereis command print out locations for each remote, as it always does for the web special remotes
+
diff --git a/doc/todo/wishlist:_push_to_cia.vc_from_the_website__39__s_repo__44___not_your_personal_one.mdwn b/doc/todo/wishlist:_push_to_cia.vc_from_the_website__39__s_repo__44___not_your_personal_one.mdwn
new file mode 100644
index 000000000..f9b4c8c35
--- /dev/null
+++ b/doc/todo/wishlist:_push_to_cia.vc_from_the_website__39__s_repo__44___not_your_personal_one.mdwn
@@ -0,0 +1,3 @@
+I just added a CIA bot to #vcs-home and tracking commits immediately would be nice. -- RichiH
+
+[[done]]
diff --git a/doc/todo/wishlist:_push_to_cia.vc_from_the_website__39__s_repo__44___not_your_personal_one/comment_1_3480b0ec629ef29a151408d869186bf8._comment b/doc/todo/wishlist:_push_to_cia.vc_from_the_website__39__s_repo__44___not_your_personal_one/comment_1_3480b0ec629ef29a151408d869186bf8._comment
new file mode 100644
index 000000000..5d0edce2e
--- /dev/null
+++ b/doc/todo/wishlist:_push_to_cia.vc_from_the_website__39__s_repo__44___not_your_personal_one/comment_1_3480b0ec629ef29a151408d869186bf8._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-09-19T18:57:52Z"
+ content="""
+JFTR, pushing now happens automatically from branchable.
+"""]]
diff --git a/doc/todo/wishlist:_query_things_like_description__44___trust_level.mdwn b/doc/todo/wishlist:_query_things_like_description__44___trust_level.mdwn
new file mode 100644
index 000000000..d158850cd
--- /dev/null
+++ b/doc/todo/wishlist:_query_things_like_description__44___trust_level.mdwn
@@ -0,0 +1,4 @@
+It would be helpful to have a way to query things like a repository's description and trust level, without having to poke in the git-annex branch. For example, "git annex describe ." currently clears the description but could print the current one instead.
+
+> `git annex status` now breaks down the repository list by type. [[done]]
+> --[[Joey]]
diff --git a/doc/todo/wishlist:_query_things_like_description__44___trust_level/comment_1_14311384788312b96e550749ab7de9ea._comment b/doc/todo/wishlist:_query_things_like_description__44___trust_level/comment_1_14311384788312b96e550749ab7de9ea._comment
new file mode 100644
index 000000000..3ac4ba267
--- /dev/null
+++ b/doc/todo/wishlist:_query_things_like_description__44___trust_level/comment_1_14311384788312b96e550749ab7de9ea._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-10-27T17:09:33Z"
+ content="""
+`git annex describe` only sets the description to avoid complication. Imagine using it in a script for example.
+
+`git annex status` shows the description. It does not show the trust level because I have not thought of a visually pleasing and compact way to show it in the repository list there.. suggestions appreciated, since the same list is used by `whereis`, and showing trust levels there would be particularly useful.
+"""]]
diff --git a/doc/todo/wishlist:_query_things_like_description__44___trust_level/comment_2_342d1ac07573c7ef4e27f003a692e261._comment b/doc/todo/wishlist:_query_things_like_description__44___trust_level/comment_2_342d1ac07573c7ef4e27f003a692e261._comment
new file mode 100644
index 000000000..3bb92919f
--- /dev/null
+++ b/doc/todo/wishlist:_query_things_like_description__44___trust_level/comment_2_342d1ac07573c7ef4e27f003a692e261._comment
@@ -0,0 +1,32 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 2"
+ date="2011-10-29T18:28:13Z"
+ content="""
+Possible solutions:
+
+This:
+
+ trusted repositories:
+ UUID -- foo
+ semi-trusted repositories:
+ UUID -- bar
+ untrusted repositories:
+ UUID -- baz
+
+or this:
+
+ UUID -- trusted -- foo
+ UUID -- semi-trusted -- bar
+ UUID -- untrusted -- baz
+
+or this:
+
+ known repositories (!/*/X):
+ UUID -- ! foo
+ UUID -- * bar
+ UUID -- X baz
+
+If you want to reformat this output, putting 'here', 'origin', etc into fixed formatting might make sense, as well. -- Richard
+"""]]
diff --git a/doc/todo/wishlist:_recursive_directory_remote_setup__47__addurl.mdwn b/doc/todo/wishlist:_recursive_directory_remote_setup__47__addurl.mdwn
new file mode 100644
index 000000000..2bfb90b54
--- /dev/null
+++ b/doc/todo/wishlist:_recursive_directory_remote_setup__47__addurl.mdwn
@@ -0,0 +1,7 @@
+I think it would be interesting to have a way to recursively import a local directory without actually moving files around. And to be able to checksum these files as well (without moving them into the annex).
+
+This would work somewhat similar to looping over a directory and adding file:// remotes for each file.
+
+A use case is importing optical media (read-only), whilst keeping that media as a remote, and being able to calculate checksums directly without moving any files around.
+
+For single files, it would also be interesting if addurl had a "--localchecksum" option that would only work for file:// urls, and make it checksum files directly from their source location?)
diff --git a/doc/todo/wishlist:_recursive_directory_remote_setup__47__addurl/comment_1_b79976afc2242791523e63831f30af71._comment b/doc/todo/wishlist:_recursive_directory_remote_setup__47__addurl/comment_1_b79976afc2242791523e63831f30af71._comment
new file mode 100644
index 000000000..caefee9a8
--- /dev/null
+++ b/doc/todo/wishlist:_recursive_directory_remote_setup__47__addurl/comment_1_b79976afc2242791523e63831f30af71._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://launchpad.net/~arand"
+ nickname="arand"
+ subject="comment 1"
+ date="2013-03-10T23:29:55Z"
+ content="""
+Recursively adding urls is already feasiable with some simple scripting:
+
+[https://gitorious.org/arand-scripts/arand-scripts/blobs/master/annex-importdir](https://gitorious.org/arand-scripts/arand-scripts/blobs/master/annex-importdir)
+
+but this is obviously missing the checksumming bit though.
+"""]]
diff --git a/doc/todo/wishlist:_recursive_directory_remote_setup__47__addurl/comment_2_1741d2392006a9af9cfd1f3b847600b9._comment b/doc/todo/wishlist:_recursive_directory_remote_setup__47__addurl/comment_2_1741d2392006a9af9cfd1f3b847600b9._comment
new file mode 100644
index 000000000..64d592479
--- /dev/null
+++ b/doc/todo/wishlist:_recursive_directory_remote_setup__47__addurl/comment_2_1741d2392006a9af9cfd1f3b847600b9._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-03-11T03:04:44Z"
+ content="""
+See also: [[forum/Managing a large number of files archived on many pieces of read-only medium (E.G. DVDs)]]
+particularly [[this comment|forum/Managing a large number of files archived on many pieces of read-only medium (E.G. DVDs)#comment-908dbe02f29e011f030bba4ab5ef73d1]]
+"""]]
diff --git a/doc/todo/wishlist:_simple_url_for_webapp.mdwn b/doc/todo/wishlist:_simple_url_for_webapp.mdwn
new file mode 100644
index 000000000..4549f2e74
--- /dev/null
+++ b/doc/todo/wishlist:_simple_url_for_webapp.mdwn
@@ -0,0 +1,36 @@
+### Please describe the problem.
+
+The environment is os/x with chrome as the browser.
+
+Let's say I close the tab with the webapp running in it. The 'git-annex webapp' process is still running, according to 'ps'.
+
+So I open a new tab, but then what do I type into the browser url bar to get the app back? What is usually there is a loopback address and an authorisation hash.
+
+* Should I double-click on the git-annex icon in the dock (or Applications directory)?
+* I figured out from observing the startup that if I give the url ://localhost/Users/me/annex/.git/annex/webapp.html I will get redirected to the right place.
+Should I set up a bookmark for that?
+
+### What steps will reproduce the problem?
+
+see above.
+
+### What version of git-annex are you using? On what operating system?
+
+Version: 4.20130723-ge023649
+Build flags: Assistant Webapp Pairing Testsuite S3 WebDAV FsEvents XMPP DNS
+os: os/x 10.8.4
+
+### Please provide any additional information below.
+
+I notice that in the webapp ui, all the items at the top of the page highlight when one hovers over them and have useful URLs attached,
+with the exception of the 'git-annex' item at the far left.What if that had the entry point url attached to it (so one could bookmark that)?
+
+> The git-annex assistant is designed to stay running in the background whether you have the web browser open or not. You can open the web display at any time by
+> using the git-annex menu item (on linux) or running the git-annex-webapp
+> program (which is in the DMG on OSX).
+>
+> If the file:// url were exposed to users, it would not work if
+> the assistant had not already been started. This is why there is a program
+> to open the webapp, not an url.
+>
+> Not a bug; [[done]] --[[Joey]]
diff --git a/doc/todo/wishlist:_simple_url_for_webapp/comment_1_552aad504fbb68d1f85abfde8c535e69._comment b/doc/todo/wishlist:_simple_url_for_webapp/comment_1_552aad504fbb68d1f85abfde8c535e69._comment
new file mode 100644
index 000000000..1211be9b5
--- /dev/null
+++ b/doc/todo/wishlist:_simple_url_for_webapp/comment_1_552aad504fbb68d1f85abfde8c535e69._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkfHTPsiAcHEEN7Xl7WxiZmYq-vX7azxFY"
+ nickname="Vincent"
+ subject="comment 1"
+ date="2013-07-24T14:46:22Z"
+ content="""
+typo
+
+url should be - file://localhost/Users/me/annex/.git/annex/webapp.html
+"""]]
diff --git a/doc/todo/wishlist:_simpler_gpg_usage.mdwn b/doc/todo/wishlist:_simpler_gpg_usage.mdwn
new file mode 100644
index 000000000..1236ee234
--- /dev/null
+++ b/doc/todo/wishlist:_simpler_gpg_usage.mdwn
@@ -0,0 +1,12 @@
+This is my current understanding on how one must use gpg with git-annex:
+
+ * Generate(or copy around) a gpg key on every machine that needs to access the encrypted remote.
+ * git annex initremote myremote encryption=KEY for each key that you generated
+
+What I'm trying to figure out is if I can generate a no-passphrase gpg key and commit it to the repository, and have git-annex use that. That way any new clones of the annex automatically have access to any encrypted remotes, without having to do any key management.
+
+I think I can generate a no-passphrase key, but then I still have to manually copy it around to each machine.
+
+I'm not a huge gpg user so part of this is me wanting to avoid having to manage and keeping track of the keys. This would probably be a non-issue if I used gpg on more machines and was more comfortable with it.
+
+[[done]]
diff --git a/doc/todo/wishlist:_simpler_gpg_usage/comment_1_6923fa6ebc0bbe7d93edb1d01d7c46c5._comment b/doc/todo/wishlist:_simpler_gpg_usage/comment_1_6923fa6ebc0bbe7d93edb1d01d7c46c5._comment
new file mode 100644
index 000000000..f96f5c377
--- /dev/null
+++ b/doc/todo/wishlist:_simpler_gpg_usage/comment_1_6923fa6ebc0bbe7d93edb1d01d7c46c5._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="comment 1"
+ date="2012-04-29T01:41:57Z"
+ content="""
+Thinking about this more, I think minimally git-annex could support a
+
+ remote.<name>.gpg-options
+
+or
+
+ remote.<name>.gpg-keyring
+
+for options to be passed to gpg. I'm not sure how automatically setting it to $ANNEX_ROOT/.gnupg/.. would work.
+
+
+I need to read the encryption code to fully understand it, but I also wonder if there is not also a way to just bypass gpg entirely and store the remote-encryption keys locally in plain text.
+"""]]
diff --git a/doc/todo/wishlist:_simpler_gpg_usage/comment_2_6fc874b6c391df242bd2592c4a65eae8._comment b/doc/todo/wishlist:_simpler_gpg_usage/comment_2_6fc874b6c391df242bd2592c4a65eae8._comment
new file mode 100644
index 000000000..2e12d86d4
--- /dev/null
+++ b/doc/todo/wishlist:_simpler_gpg_usage/comment_2_6fc874b6c391df242bd2592c4a65eae8._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 2"
+ date="2012-04-29T02:39:20Z"
+ content="""
+The encryption uses a symmetric cipher that is stored in the git repository already. It's just stored encrypted to the various gpg keys that have been configured to use it. It would certainly be possible to store the symmetric cipher unencrypted in the git repo.
+
+I don't see your idea of gpg-options saving any work. It would still require you to do key distribution and run commands in each repo to set it up.
+"""]]
diff --git a/doc/todo/wishlist:_simpler_gpg_usage/comment_3_012f340c8c572fe598fc860c1046dabd._comment b/doc/todo/wishlist:_simpler_gpg_usage/comment_3_012f340c8c572fe598fc860c1046dabd._comment
new file mode 100644
index 000000000..051f17a24
--- /dev/null
+++ b/doc/todo/wishlist:_simpler_gpg_usage/comment_3_012f340c8c572fe598fc860c1046dabd._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 3"
+ date="2012-04-29T02:41:38Z"
+ content="""
+BTW re your Tweet.. I was so happy to be able to use 'c i a' in Crypto.hs. :)
+"""]]
diff --git a/doc/todo/wishlist:_simpler_gpg_usage/comment_4_e0c2a13217b795964f3b630c001661ef._comment b/doc/todo/wishlist:_simpler_gpg_usage/comment_4_e0c2a13217b795964f3b630c001661ef._comment
new file mode 100644
index 000000000..c9e337541
--- /dev/null
+++ b/doc/todo/wishlist:_simpler_gpg_usage/comment_4_e0c2a13217b795964f3b630c001661ef._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmBUR4O9mofxVbpb8JV9mEbVfIYv670uJo"
+ nickname="Justin"
+ subject="comment 4"
+ date="2012-04-29T03:09:03Z"
+ content="""
+I got a good laugh out of it :-)
+
+Storing the key unencrypted would make things easier.. I think at least for my use-cases I don't require another layer of protection on top of the ssh keys that provide access to the encrypted remotes themselves.
+"""]]
diff --git a/doc/todo/wishlist:_simpler_gpg_usage/comment_5_9668b58eb71901e1db8da7db38e068ca._comment b/doc/todo/wishlist:_simpler_gpg_usage/comment_5_9668b58eb71901e1db8da7db38e068ca._comment
new file mode 100644
index 000000000..60b98bde5
--- /dev/null
+++ b/doc/todo/wishlist:_simpler_gpg_usage/comment_5_9668b58eb71901e1db8da7db38e068ca._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 5"
+ date="2012-04-29T18:04:13Z"
+ content="""
+encryption=shared is now supported
+"""]]
diff --git a/doc/todo/wishlist:_spec.remotes_for_other_peer_network_data_stores___40__gnunet__44___freenet__41__.mdwn b/doc/todo/wishlist:_spec.remotes_for_other_peer_network_data_stores___40__gnunet__44___freenet__41__.mdwn
new file mode 100644
index 000000000..545bd861d
--- /dev/null
+++ b/doc/todo/wishlist:_spec.remotes_for_other_peer_network_data_stores___40__gnunet__44___freenet__41__.mdwn
@@ -0,0 +1,26 @@
+Apart from Tahoe-LAFS (covered by [[todo/tahoe lfs for reals]] and [[forum/tips: special_remotes/hook with tahoe-lafs]]), [[special remotes]] (which I understand as real storage backends) for other other [peer network data stores](http://en.wikipedia.org/wiki/Distributed_data_store#Peer_network_node_data_stores_2) would be interesting.
+
+I mean gnunet, freenet, BitTorrent (also trackerless).
+
+Before dropping a file locally, the BitTorrent client should check that all parts are still available from the peers.
+
+Of course, there is no guarantee assumed that the content won't disappear from the peer network in future: they act more like a cache rather than an archive on whose lifespan you decide. (I'm only not sure about gnunet now: whether there is a rule of dropping unused content from it, like in freenet.)
+
+So, a copy in peer networks shouldn't be counted on by git-annex as much as a copy on a storage you control: probably, by efault, it shouldn't let you delete the local copy if there is a copy in a peer network unless you saved it somewhere else.
+
+(Think of such a scenario: I could save some of my public large data on external disks/DVDs and keep them at home, and also put them onto peer networks with the same nterface of git-annex which I would be used to; I would also use the git-annex interface to check from time to time that the content is still present, i.e. "cached", on the peer networks. Whenever I'm away from home, and unexpectedly need to show this content to someone, or have a look at it for some reason, I could get it from the peer network "cache".)
+
+Also networks like namecoin (derived from bitcoin) can be used as a key-value store. Despite being a peer network, a system like namecoin actually could offer the publisher more control over the lifespan of the content: he should be able to offer "financial" reward for others processing his key-value data. (But I'm not sure namecoin is designed reasonably for this reward system to work actually; but there might be appearing other similar systems.)
+
+## A different view: extend the key-value backends with ways to look for the content in other content-addressable storage systems
+We might want to look for the registered files in other [content-addressable storage systems](http://en.wikipedia.org/wiki/Content-addressable_storage#Open-source_implementations) (and also to be able to put the files there for storage).
+
+For example:
+
+* [**GNUnet**](http://en.wikipedia.org/wiki/Gnunet) uses its own hash format to address the content. git-annex could extend its own [[backends]] with a one to work with GNUnet, and by default have a built-in [[special remote|special remotes]] that would interact with GNUnet when looking for a content or storing some content. No special setup of the special remote in each repo should be necessary, because GNUnet is "global", so we'd just use the user's already configured GNUnet client. Just turning the builtin GNUnet special remote on or off should be an option (in the repo configuration, and when calling the commands that would query it, like `whereis`).
+* **freenet** is similar.
+* Similarly, a backend for the hashes used in **BitTorrent** and **magnet links** could be used. If we want a trackerless mode, then probably it's a similar case for a "global"/built-in special remote that needs no local setup in each repo. Using a selected tracker would mean setting up a special remote in our repo.
+* **Git** itself can be viwed as place to look for the content. There could be a corresponding backend and a builtin special remote (needing no extra setup) to look for the content among the objects stored in the local Git repo. (What if we have a copy of a file that we've put under the control of git-annex in a previous Git commit? We could get it from the object store of Git.)
+* **Venti**, [[**Tahoe-LAFS**|todo/tahoe lfs for reals]] would need a backend for their hashes, and a specially setup special remote in each repo where we'd like to use them--because these are not "global" system, we must setup the path to the instance of the filesystem we'd like to use.
+* probably, there must be other interesting cases of this kind...
+* (I'm also thinking about using somethng like a **bibliographic information** as a key, but then it wouldn't guarantee identical files: the same paper can be stored in different formats, etc. Cf. [**URNs**](http://en.wikipedia.org/wiki/Uniform_resource_name#Examples), via <http://it.slashdot.org/comments.pl?sid=3032489&cid=40907233>. Also, an URN like bibliographic information can't be computed from the file, it will have to be entered manually or obtained from another directory of URNs.)
diff --git a/doc/todo/wishlist:_spec.remotes_for_other_peer_network_data_stores___40__gnunet__44___freenet__41__/comment_1_e2c2047e7401cb95a82ffb686a732859._comment b/doc/todo/wishlist:_spec.remotes_for_other_peer_network_data_stores___40__gnunet__44___freenet__41__/comment_1_e2c2047e7401cb95a82ffb686a732859._comment
new file mode 100644
index 000000000..80a245d14
--- /dev/null
+++ b/doc/todo/wishlist:_spec.remotes_for_other_peer_network_data_stores___40__gnunet__44___freenet__41__/comment_1_e2c2047e7401cb95a82ffb686a732859._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.14.141"
+ subject="comment 1"
+ date="2012-09-25T22:57:19Z"
+ content="""
+The best first step to adding such kinds of data stores to git-annex is probably to use the [[special_remotes/hook]] special remote to access them.
+"""]]
diff --git a/doc/todo/wishlist:_spec.remotes_for_other_peer_network_data_stores___40__gnunet__44___freenet__41__/comment_2_472b576afdb169b233edd01adcb2123d._comment b/doc/todo/wishlist:_spec.remotes_for_other_peer_network_data_stores___40__gnunet__44___freenet__41__/comment_2_472b576afdb169b233edd01adcb2123d._comment
new file mode 100644
index 000000000..c58f97c1c
--- /dev/null
+++ b/doc/todo/wishlist:_spec.remotes_for_other_peer_network_data_stores___40__gnunet__44___freenet__41__/comment_2_472b576afdb169b233edd01adcb2123d._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://lj.rossia.org/users/imz/"
+ ip="79.165.56.162"
+ subject="comment 2"
+ date="2012-09-25T23:29:49Z"
+ content="""
+I see. But then, as with Tahoe-LAFS, they also have their own formats for checksums, keys, which could be re-used in git-annex, and that needs special treatment.
+"""]]
diff --git a/doc/todo/wishlist:_special-case_handling_of_Youtube_URLs_in_Web_special_remote.mdwn b/doc/todo/wishlist:_special-case_handling_of_Youtube_URLs_in_Web_special_remote.mdwn
new file mode 100644
index 000000000..229dc258b
--- /dev/null
+++ b/doc/todo/wishlist:_special-case_handling_of_Youtube_URLs_in_Web_special_remote.mdwn
@@ -0,0 +1,22 @@
+The [[Web special remote|special remotes/web]] could possibly be improved by detecting when URLs reference a Youtube video page and using [youtube-dl](http://rg3.github.com/youtube-dl/) instead of wget to download the page. Youtube-dl can also handle several other video sites such as vimeo.com and blip.tv, so if this idea were to be implemented, it might make sense to borrow the regular expressions that youtube-dl uses to identify video URLs. A quick grep through the youtube-dl source for the identifier _VALID_URL should find those regexes (in Python's regex format).
+
+> This is something I've thought about doing for a while..
+> Two things I have not figured out:
+>
+> * Seems that this should really be user-configurable or a plugin system,
+> to handle more than just this one case.
+> * Youtube-dl breaks from time to time, I really trust these urls a lot
+> less than regular urls. Perhaps per-url trust levels are called for by
+> this.
+>
+> --[[Joey]]
+
+> > There's a library for this called [quvi](http://quvi.sourceforge.net/) which supports many
+> > different sites and also allows fetching the URL (as opposed to just
+> > downloading the file). It seems to me this would be the best tool
+> > for this task. One problem to consider here is that a single youtube
+> > URL may yield different file contents depending on the quality
+> > chosen. Also, it seems that the URLs guessed by quvi may be
+> > ephemeral. --[[anarcat]]
+
+> [[done]]!!! --[[Joey]]
diff --git a/doc/todo/wishlist:_special-case_handling_of_Youtube_URLs_in_Web_special_remote/comment_1_1a383c30df4fb1767f13d8c670b0c0b5._comment b/doc/todo/wishlist:_special-case_handling_of_Youtube_URLs_in_Web_special_remote/comment_1_1a383c30df4fb1767f13d8c670b0c0b5._comment
new file mode 100644
index 000000000..5569ff94a
--- /dev/null
+++ b/doc/todo/wishlist:_special-case_handling_of_Youtube_URLs_in_Web_special_remote/comment_1_1a383c30df4fb1767f13d8c670b0c0b5._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://rmunn.myopenid.com/"
+ nickname="rmunn"
+ subject="comment 1"
+ date="2012-06-12T15:52:35Z"
+ content="""
+* One way to handle the configuration might be with regular expressions. If the URL matches regex A, handle it with downloader A' (with option set A''). If the URL matches regex B, handle it with downloader B' and option set B''. And so on. Then if nothing is matched, the default downloader is wget/curl.
+
+* In my experience, youtube-dl breakages are fixed relatively quickly; a much more serious problem from a trust standpoint is that Youtube videos often disappear. Sometimes due to a legitimate copyright claim, sometimes due to illegitimate copyright claims. (I've seen both happen). Or because the video uploader decided to upload *other* videos that violated copyright, and Youtube closed his/her account, thereby removing *all* his/her videos from the Web. Youtube is definitely an untrustworthy repository as far as \"the file will still be there later on\" is concerned. Perhaps a default trust relationship could go along with the regexes? URLs matching regex A are semitrusted, while URLs matching regex B are untrusted.
+"""]]
diff --git a/doc/todo/wishlist:_special-case_handling_of_Youtube_URLs_in_Web_special_remote/comment_2_81f7f893ac36c145b31f02db6a682a17._comment b/doc/todo/wishlist:_special-case_handling_of_Youtube_URLs_in_Web_special_remote/comment_2_81f7f893ac36c145b31f02db6a682a17._comment
new file mode 100644
index 000000000..a25b3c89d
--- /dev/null
+++ b/doc/todo/wishlist:_special-case_handling_of_Youtube_URLs_in_Web_special_remote/comment_2_81f7f893ac36c145b31f02db6a682a17._comment
@@ -0,0 +1,20 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="quvi thoughts. excited!"
+ date="2013-08-22T18:22:51Z"
+ content="""
+Anarcat's quvi suggestion is interesting, because it seems to simplify the whole thing down to just `addurl`, which git-annex is already good at.
+
+If quvi manages to find the url that can be used to download the actual video file, without needing to run a special downloader, then all you really need, it seems, is `git annex addurl --relaxed $(quvi youtube-url)` The --relaxed will make git-annex not care if the content or size of the url's content varies in the future. Since --relaxed skips the actual download, you'd want to follow that with `git annex get`, since we don't know how long these urls will last..
+
+I suppose git-annex could, if quvi is available, make any attempt to download a web special remote url that
+matches the `quvi --support` output run the url through quvi to get the real url and download that instead. The difficulties with this approach:
+
+* would need to read and parse `quvi --support` every time it gets an url from the web special remote? (I don't think I'd want to link with libquvi, although that would be possible, just because this is an edge thing.)
+* what it an url that had been supported stopped being supported -- we'd not want to download the raw url in that case
+* putting the quvi support here doesn't allow relaxed mode to be set when `addurl` adds the url.
+
+Maybe it would be better to keep the support in `addurl`, and record the url generated by quvi. That url would probably be more likely to break in the future, but that kind of breakage is why `git annex untrust web` is wise..
+Keeping the support in `addurl` would also let it use the title that quvi also returns to determine the filename it creates.
+"""]]
diff --git a/doc/todo/wishlist:_special-case_handling_of_Youtube_URLs_in_Web_special_remote/comment_3_a7e3cd68c5e5f05139151a58f358df95._comment b/doc/todo/wishlist:_special-case_handling_of_Youtube_URLs_in_Web_special_remote/comment_3_a7e3cd68c5e5f05139151a58f358df95._comment
new file mode 100644
index 000000000..c4d8cf754
--- /dev/null
+++ b/doc/todo/wishlist:_special-case_handling_of_Youtube_URLs_in_Web_special_remote/comment_3_a7e3cd68c5e5f05139151a58f358df95._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.0.63"
+ subject="comment 3"
+ date="2013-08-22T18:44:15Z"
+ content="""
+Since the quvi urls are quite likely to break as the CDNs etc change things around, maybe it would be better to somehow have addurl tag an url as needing to be downloaded with quvi. Then `git annex get` could re-run quvi to get an url to download.
+
+We could expand url syntax for this. `quvi:http://youtube.com/foo`
+This also allows for future expansion for other similar things.
+
+I'd be inclined to still make `addurl` automatically try quvi to see if an url is supported, rather than requiring the user fix up the url themselves. But if trying quvi turns out to be too expensive, manually specifying it in the url would also work.
+"""]]
diff --git a/doc/todo/wishlist:_special-case_handling_of_Youtube_URLs_in_Web_special_remote/comment_4_a57947ed257b28bbe995a68bfeb5eeaa._comment b/doc/todo/wishlist:_special-case_handling_of_Youtube_URLs_in_Web_special_remote/comment_4_a57947ed257b28bbe995a68bfeb5eeaa._comment
new file mode 100644
index 000000000..ee0ab45e7
--- /dev/null
+++ b/doc/todo/wishlist:_special-case_handling_of_Youtube_URLs_in_Web_special_remote/comment_4_a57947ed257b28bbe995a68bfeb5eeaa._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://rmunn.myopenid.com/"
+ nickname="rmunn"
+ subject="comment 4"
+ date="2013-08-24T15:31:36Z"
+ content="""
+Either quvi or youtube-dl might be a good possibility: youtube-dl has the --get-url option (or -g for short) that outputs just the download URL (and nothing else) to stdout. So if for some reason quvi turned out not to be suitable, it wouldn't necessarily mean the idea would have to be abandoned.
+"""]]
diff --git a/doc/todo/wishlist:_special-case_handling_of_Youtube_URLs_in_Web_special_remote/comment_5_a0612ae05dbda7f7935be648b42b30fc._comment b/doc/todo/wishlist:_special-case_handling_of_Youtube_URLs_in_Web_special_remote/comment_5_a0612ae05dbda7f7935be648b42b30fc._comment
new file mode 100644
index 000000000..38ac09511
--- /dev/null
+++ b/doc/todo/wishlist:_special-case_handling_of_Youtube_URLs_in_Web_special_remote/comment_5_a0612ae05dbda7f7935be648b42b30fc._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://id.koumbit.net/anarcat"
+ ip="72.0.72.144"
+ subject="aaaaawesome!"
+ date="2013-08-26T04:43:27Z"
+ content="""
+wow, thanks! i am happy my little suggestion led to an actual implentation, great!
+"""]]
diff --git a/doc/todo/wishlist:_special_remote_Ubuntu_One.mdwn b/doc/todo/wishlist:_special_remote_Ubuntu_One.mdwn
new file mode 100644
index 000000000..b88a038ea
--- /dev/null
+++ b/doc/todo/wishlist:_special_remote_Ubuntu_One.mdwn
@@ -0,0 +1 @@
+Special remote support for [Ubuntu One](http://one.ubuntu.com) would be nice. They're [using propietary but open protocol](https://wiki.ubuntu.com/UbuntuOne/TechnicalDetails#ubuntuone-storageprotocol) based on [Google Protocol Buffers](http://code.google.com/p/protobuf/). There's [protobuf for Haskell](http://code.google.com/p/protobuf-haskell/) so it should be possible to compile [the protocol file](http://bazaar.launchpad.net/~ubuntuone-control-tower/ubuntuone-storage-protocol/trunk/view/head:/ubuntuone/storageprotocol/protocol.proto) to Haskell code and then use that to implement the native Ubuntu special remote.
diff --git a/doc/todo/wishlist:_special_remote_for_sftp_or_rsync.mdwn b/doc/todo/wishlist:_special_remote_for_sftp_or_rsync.mdwn
new file mode 100644
index 000000000..d3c855655
--- /dev/null
+++ b/doc/todo/wishlist:_special_remote_for_sftp_or_rsync.mdwn
@@ -0,0 +1,28 @@
+i think it would be useful to have a fourth kind of [[special_remotes]]
+that connects to a dumb storage using sftp or rsync. this can be emulated
+by using sshfs, but that means lots of round-trips through the system and
+is limited to platforms where sshfs is available.
+
+typical use cases are backups to storate shared between a group of people
+where each user only has limited access (sftp or rsync), when using
+[[special_remotes/bup]] is not an option.
+
+an alternative to implementing yet another special remote would be to have
+some kind of plugin system by which external programs can provide an
+interface to key-value stores (i'd implement the sftp backend myself, but
+haven't learned haskell yet).
+
+> Ask and ye [[shall receive|special_remotes/rsync]].
+>
+> Sometimes I almost think that a generic configurable special remote that
+> just uses configured shell commands would be useful.. But there's really
+> no comparison with sitting down and writing code tuned to work with
+> a given transport like rsync, when it comes to reliability and taking
+> advantage of its abilities (like resuming). --[[Joey]]
+
+>> big thanks, and bonus points for identical formats, so converting from
+>> directory to rsync is just a matter of changing ``type`` from ``directory``
+>> to ``rsync`` in ``.git-annex/remote.log`` and replacing the directory info
+>> with ``annex-rsyncurl = <host>:<dir>`` in ``.git/config``. --[[chrysn]]
+
+[[done]]
diff --git a/doc/todo/wishlist:_special_remote_for_sftp_or_rsync/comment_1_6f07d9cc92cf8b4927b3a7d1820c9140._comment b/doc/todo/wishlist:_special_remote_for_sftp_or_rsync/comment_1_6f07d9cc92cf8b4927b3a7d1820c9140._comment
new file mode 100644
index 000000000..c513ed400
--- /dev/null
+++ b/doc/todo/wishlist:_special_remote_for_sftp_or_rsync/comment_1_6f07d9cc92cf8b4927b3a7d1820c9140._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 1"
+ date="2011-04-28T07:47:38Z"
+ content="""
++1 for a generic user configurable backend that a user can put shell commands in, which has a disclaimer such that if a user hangs themselves with misconfiguration then its their own fault :P
+
+I would love to be able to quickly plugin an irods/sector set of put/get/delete/stat(get info) commands into git-annex to access my private clouds which aren't s3 compatible.
+"""]]
diff --git a/doc/todo/wishlist:_special_remote_for_sftp_or_rsync/comment_2_84e4414c88ae91c048564a2cdc2d3250._comment b/doc/todo/wishlist:_special_remote_for_sftp_or_rsync/comment_2_84e4414c88ae91c048564a2cdc2d3250._comment
new file mode 100644
index 000000000..6243708f9
--- /dev/null
+++ b/doc/todo/wishlist:_special_remote_for_sftp_or_rsync/comment_2_84e4414c88ae91c048564a2cdc2d3250._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 2"
+ date="2011-04-28T21:22:03Z"
+ content="""
+Ask and ye shalle receive with an Abbot on top: [[special_remotes/hook]]
+"""]]
diff --git a/doc/todo/wishlist:_special_remote_for_sftp_or_rsync/comment_3_79de7ac44e3c0f0f5691a56d3fb88897._comment b/doc/todo/wishlist:_special_remote_for_sftp_or_rsync/comment_3_79de7ac44e3c0f0f5691a56d3fb88897._comment
new file mode 100644
index 000000000..dc21ec488
--- /dev/null
+++ b/doc/todo/wishlist:_special_remote_for_sftp_or_rsync/comment_3_79de7ac44e3c0f0f5691a56d3fb88897._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 3"
+ date="2011-04-29T10:43:31Z"
+ content="""
+Cool!, I just tried adding tahoe-lafs as a remote, and it wasn't too hard.
+"""]]
diff --git a/doc/todo/wishlist:_special_remote_mega.co.nz.mdwn b/doc/todo/wishlist:_special_remote_mega.co.nz.mdwn
new file mode 100644
index 000000000..41164084a
--- /dev/null
+++ b/doc/todo/wishlist:_special_remote_mega.co.nz.mdwn
@@ -0,0 +1,3 @@
+mega.co.nz has 50gb for free accounts. They also have an API, so I guess it wouldn't be too hard to use it as a special remote.
+
+[[done]], see [[tips/megaannex]].
diff --git a/doc/todo/wishlist:_special_remote_mega.co.nz/comment_2_6ca08ef808d4336fc42d0f279d6627b5._comment b/doc/todo/wishlist:_special_remote_mega.co.nz/comment_2_6ca08ef808d4336fc42d0f279d6627b5._comment
new file mode 100644
index 000000000..542b92a67
--- /dev/null
+++ b/doc/todo/wishlist:_special_remote_mega.co.nz/comment_2_6ca08ef808d4336fc42d0f279d6627b5._comment
@@ -0,0 +1,44 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmLB39PC89rfGaA8SwrsnB6tbumezj-aC0"
+ nickname="Tobias"
+ subject="Usage of mega hook"
+ date="2013-05-21T09:09:28Z"
+ content="""
+megaannex
+=========
+
+Hook program for gitannex to use mega.co.nz as backend
+
+# Requirements:
+
+ requests>=0.10
+ pycrypto
+
+Credit for the mega api interface goes to: https://github.com/richardasaurus/mega.py
+
+## Install
+Clone the git repository in your home folder.
+
+ git clone git://github.com/TobiasTheViking/megaannex.git
+
+This should make a ~/megannex folder
+
+## Setup
+Run the program once to make an empty config file
+
+ cd ~/megaannex; python2 megaannex.py
+
+Edit the megaannex.conf file. Add your mega.co.nz username and password
+
+Note: The folder option in the megaannex.conf file isn't yet used.
+
+## Commands for gitannex:
+
+ git config annex.mega-store-hook '/usr/bin/python2 ~/megaannex/megaannex.py store --subject $ANNEX_KEY --file $ANNEX_FILE'
+ git config annex.mega-retrieve-hook '/usr/bin/python2 ~/megaannex/megaannex.py getfile --subject $ANNEX_KEY --file $ANNEX_FILE'
+ git config annex.mega-checkpresent-hook '/usr/bin/python2 ~/megaannex/megaannex.py fileexists --subject $ANNEX_KEY'
+ git config annex.mega-remove-hook '/usr/bin/python2 ~/megaannex/megaannex.py delete --subject $ANNEX_KEY'
+ git annex initremote mega type=hook hooktype=mega encryption=shared
+ git annex describe mega \"the mega.co.nz library\"
+
+"""]]
diff --git a/doc/todo/wishlist:_support_copy_--from__61__x_--to__61__y.mdwn b/doc/todo/wishlist:_support_copy_--from__61__x_--to__61__y.mdwn
new file mode 100644
index 000000000..b4f966abb
--- /dev/null
+++ b/doc/todo/wishlist:_support_copy_--from__61__x_--to__61__y.mdwn
@@ -0,0 +1,29 @@
+I'd like to be able to:
+
+ git annex copy --from=x --to=y .
+
+Use case (true story) follows:
+
+My desktop hard drive was filling up. I dropped some large files which are also stored (via git-annex) on my backup drive. While these aren't irreplaceable files, I'd prefer to have at least two copies of everything I've decided I care enough about to archive. Later, I get a 2nd external drive, and I:
+
+ git annex copy --to=new-external-drive .
+
+Fantastic! Now I've got everything that was important/useful enough to keep on my desktop backed up a 2nd time onto my new drive.
+
+But my new drive doesn't have a copy of any of the files I dropped from my desktop. I would like to be able to:
+
+ git annex copy --from=old-external-drive --to=new-external-drive .
+
+on my desktop, and then my new drive would have a copy of everything, and my desktop drive would still have plenty of space (ie the files I'd dropped to make space would still not be stored on the desktop).
+
+The git repos on these external drives are both bare (as in ``git init --bare``) because they are used only for backups. Thus I operate on them only as remotes from my main (desktop) repo.
+
+> I have now implemented the --all option, and it's the default when
+> running `git annex get` inside a bare repo.
+>
+> So, the solution is to `cd` to the repository on old-external-drive,
+> and `git remote add newdrive /path/to/new/drive/repo`. Then run `git
+> annex copy --all --to newdrive` and it'll move everything.
+>
+> Calling this [[done]] unless there are other use cases where the double
+> copy method is really needed? --[[Joey]]
diff --git a/doc/todo/wishlist:_support_copy_--from__61__x_--to__61__y/comment_1_cf8e0f16b723516374c95a93e4da42fc._comment b/doc/todo/wishlist:_support_copy_--from__61__x_--to__61__y/comment_1_cf8e0f16b723516374c95a93e4da42fc._comment
new file mode 100644
index 000000000..cee50a345
--- /dev/null
+++ b/doc/todo/wishlist:_support_copy_--from__61__x_--to__61__y/comment_1_cf8e0f16b723516374c95a93e4da42fc._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.154.4.193"
+ subject="comment 1"
+ date="2013-06-30T17:43:50Z"
+ content="""
+A reasonable use case indeed.
+
+It seems to me that [[add_-all_option]] could also satisfy this use case, as then you could run `git annex get --all` in the new bare remote.
+
+That would have the benefit of not doing a double copy.
+"""]]
diff --git a/doc/todo/wishlist:_support_copy_--from__61__x_--to__61__y/comment_2_d35359c9dd4dd4365d9a7caf695ff833._comment b/doc/todo/wishlist:_support_copy_--from__61__x_--to__61__y/comment_2_d35359c9dd4dd4365d9a7caf695ff833._comment
new file mode 100644
index 000000000..8305679a3
--- /dev/null
+++ b/doc/todo/wishlist:_support_copy_--from__61__x_--to__61__y/comment_2_d35359c9dd4dd4365d9a7caf695ff833._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="http://jasonwoof.com/"
+ nickname="JasonWoof"
+ subject="thanks, good enough for now."
+ date="2013-07-15T19:27:58Z"
+ content="""
+the ``--all`` option works for this use case. That takes care of my problem. Thank you!
+
+I can imagine other use cases where I'd want ``--from`` and ``--to`` at once, such as:
+
+1. same situation with my two bare external drives, but I want to only copy my audio-book collection to the new drive, and not my movies.
+
+2. I've got a large online storage (eg rsync.net) and want copy everything from there onto my new external drive.
+
+I leave it up to your good judgement when/if this is worth doing.
+"""]]
diff --git a/doc/todo/wishlist:_support_drop__44___find_on_special_remotes.mdwn b/doc/todo/wishlist:_support_drop__44___find_on_special_remotes.mdwn
new file mode 100644
index 000000000..24cacbf71
--- /dev/null
+++ b/doc/todo/wishlist:_support_drop__44___find_on_special_remotes.mdwn
@@ -0,0 +1,18 @@
+Currently there is no way to drop files, or list what files are available, on a special remote.
+It would be good if "git annex drop" and "git annex find" supported the --from argument.
+
+> I agree, drop should support --from.
+>> [[done]] --[[Joey]]
+>
+> To find files *believed* to be present in a given remote, use
+> `git annex find --in remote`
+> Note that it might show out of date info, since it does not actually go
+> check the current contents of the remote. The only reason to support
+> `find --from` would be to always check, but I don't think that's needed.
+> --[[Joey]]
+
+For commands that don't support the --from argument, it would also be nice to print an error.
+Currently running "git annex drop --from usbdrive" doesn't behave as hoped and instead drops
+all content from the local annex.
+
+> This is done now. --[[Joey]]
diff --git a/doc/todo/wishlist:_support_drop__44___find_on_special_remotes/comment_1_f11ed642a83d965076778a162f701e84._comment b/doc/todo/wishlist:_support_drop__44___find_on_special_remotes/comment_1_f11ed642a83d965076778a162f701e84._comment
new file mode 100644
index 000000000..6028933b4
--- /dev/null
+++ b/doc/todo/wishlist:_support_drop__44___find_on_special_remotes/comment_1_f11ed642a83d965076778a162f701e84._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 1"
+ date="2011-10-27T17:13:43Z"
+ content="""
+Well, I don't think you mean \"special remotes\", but just any old remote (special or not).
+"""]]
diff --git a/doc/todo/wishlist:_support_for_more_ssh_urls_.mdwn b/doc/todo/wishlist:_support_for_more_ssh_urls_.mdwn
new file mode 100644
index 000000000..55b8120a7
--- /dev/null
+++ b/doc/todo/wishlist:_support_for_more_ssh_urls_.mdwn
@@ -0,0 +1,22 @@
+git-annex does not seem to support all kinds of urls that git does.
+
+Specifically, if I have ~/bar set up on host foo:
+
+ [remote "foo"]
+ ## this one is not recognized as ssh url at all
+ # url = foo:bar
+ ## this one makes git-annex try to access '/~/bar' literally
+ # url = ssh://foo/~/bar
+ ## this one works
+ url = ssh://foo/home/tv/bar
+
+> scp-style is now supported.
+
+> `~` expansions (for the user's home, or other users)
+> are somewhat tricky to support as they require running
+> code on the remote to lookup homedirs. If git-annex grows a
+> `git annex shell` that is run on the remote side
+> (something I am [[considering|todo/git-annex-shell]] for other reasons), it
+> could handle the expansions there. --[[Joey]]
+
+> Update: Now `~` expansions are supported. [[done]]
diff --git a/doc/todo/wishlist:_swift_backend.mdwn b/doc/todo/wishlist:_swift_backend.mdwn
new file mode 100644
index 000000000..28bd265fa
--- /dev/null
+++ b/doc/todo/wishlist:_swift_backend.mdwn
@@ -0,0 +1,5 @@
+[swift](http://swift.openstack.org/) is the object storage of Openstack. Think S3, but fully open source. As it's backed by rackspace.com, NASA, Dell and several other major players, adoption rates will explode.
+
+I can provide a test account soonish if need be, else rackspace.com if offering swift storage. Their API gateway lives at https://auth.api.rackspacecloud.com/v1.0
+
+Richard
diff --git a/doc/todo/wishlist:_swift_backend/comment_1_e6efbb35f61ee521b473a92674036788._comment b/doc/todo/wishlist:_swift_backend/comment_1_e6efbb35f61ee521b473a92674036788._comment
new file mode 100644
index 000000000..98a998c1c
--- /dev/null
+++ b/doc/todo/wishlist:_swift_backend/comment_1_e6efbb35f61ee521b473a92674036788._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkSq2FDpK2n66QRUxtqqdbyDuwgbQmUWus"
+ nickname="Jimmy"
+ subject="comment 1"
+ date="2011-05-14T10:04:36Z"
+ content="""
+I don't suppose this SWIFT api is compatible with the eucalytpus walrus api ?
+"""]]
diff --git a/doc/todo/wishlist:_swift_backend/comment_2_5d8c83b0485112e98367b7abaab3f4e3._comment b/doc/todo/wishlist:_swift_backend/comment_2_5d8c83b0485112e98367b7abaab3f4e3._comment
new file mode 100644
index 000000000..97863b095
--- /dev/null
+++ b/doc/todo/wishlist:_swift_backend/comment_2_5d8c83b0485112e98367b7abaab3f4e3._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 2"
+ date="2011-05-14T15:00:51Z"
+ content="""
+It does offer a S3 compability layer, but that is de facto non-functioning as of right now.
+"""]]
diff --git a/doc/todo/wishlist:_swift_backend/comment_3_bf8625b909c3a7321cae40e6f145e874._comment b/doc/todo/wishlist:_swift_backend/comment_3_bf8625b909c3a7321cae40e6f145e874._comment
new file mode 100644
index 000000000..90af10c41
--- /dev/null
+++ b/doc/todo/wishlist:_swift_backend/comment_3_bf8625b909c3a7321cae40e6f145e874._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://ertai.myopenid.com/"
+ nickname="npouillard"
+ subject="+1"
+ date="2012-09-18T08:52:21Z"
+ content="""
+OVH (french IT company) is migrating its could storage infrastructure to swift/openstack and the next few weeks.
+"""]]
diff --git a/doc/todo/wishlist:_swift_backend/comment_4_4d97d12ddd99834788e94648c8eebef9._comment b/doc/todo/wishlist:_swift_backend/comment_4_4d97d12ddd99834788e94648c8eebef9._comment
new file mode 100644
index 000000000..21fa52aaf
--- /dev/null
+++ b/doc/todo/wishlist:_swift_backend/comment_4_4d97d12ddd99834788e94648c8eebef9._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawm5Z8wzidsumLYQnHdrVxpCx8vsd9llSlg"
+ nickname="Emanuele"
+ subject="comment 4"
+ date="2013-11-22T15:52:42Z"
+ content="""
+OVH is offering free accounts with 25GB of storage on their hubiC service: https://hubic.com/en/
+
+The API documentation (based on OAuth2 and OpenStack Swift) is available at https://api.hubic.com/
+"""]]
diff --git a/doc/todo/wishlist:_traffic_accounting_for_git-annex.mdwn b/doc/todo/wishlist:_traffic_accounting_for_git-annex.mdwn
new file mode 100644
index 000000000..4b661101d
--- /dev/null
+++ b/doc/todo/wishlist:_traffic_accounting_for_git-annex.mdwn
@@ -0,0 +1,3 @@
+As git annex keeps logs about file transfers anyway, it should be relatively easy to add traffic accounting to a repo. That would allow me to monitor how much traffic a given repo generates. As I might end up hosting git-annex repos for a few personal friends, I need/want a way to track the heavy hitters. -- RichiH
+
+PS: If you ever plan to host git-annex similar branchable, this would probably be of interest to you, as well :)
diff --git a/doc/todo/wishlist:_unify_directory_scheme_for_the_store.mdwn b/doc/todo/wishlist:_unify_directory_scheme_for_the_store.mdwn
new file mode 100644
index 000000000..83ce53127
--- /dev/null
+++ b/doc/todo/wishlist:_unify_directory_scheme_for_the_store.mdwn
@@ -0,0 +1,20 @@
+In regular repos, objects are stored in files of the form: .git/annex/objects/xY/z1/SHA1-.../SHA1-.... (scheme 1)
+
+On (some) special remotes, the corresponding file is stored at: .../abc/def/SHA1-... (scheme 2)
+
+I'm not sure why the same scheme as in .git/objects isn't used, but it would be useful that the two-directory prefix were the same for all objects stores.
+
+My use case is: I synchronize a git repo, say containing photos, to a server on which I can't install git-annex. I want the server to store all annexed files. For the photos to be viewed online, the annex store must use the scheme 1 (because the symlinks point to files with scheme 1). So I need to rsync .git/annex/objects manually from my desktop, because a git-annex rsync remote uses scheme 2. On the other hand, the repo on this server is not known by git-annex (like it would if I used a rsync remote).
+
+At least it would be valuable (to get around above problem) to have a plumbing command giving the 2-directory prefix from a given key, for example:
+
+$ git annex prefix-dir SHA1-s2--3f786850e387550fdab836ed7e6dc881
+
+7w/88
+
+f18/122
+
+
+Even if the 2 schemes were unified, this prefix-dir command would still be useful when hacking around git-annex (for now I need to maintain a dictionary structure).
+
+Thanks a lot.
diff --git a/doc/todo/wishlist:_unify_directory_scheme_for_the_store/comment_1_44da58beaaab359ecaba7fb905ca4ae1._comment b/doc/todo/wishlist:_unify_directory_scheme_for_the_store/comment_1_44da58beaaab359ecaba7fb905ca4ae1._comment
new file mode 100644
index 000000000..86c33d434
--- /dev/null
+++ b/doc/todo/wishlist:_unify_directory_scheme_for_the_store/comment_1_44da58beaaab359ecaba7fb905ca4ae1._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.243"
+ subject="comment 1"
+ date="2013-10-04T20:50:33Z"
+ content="""
+Using the mixed case hash directory names is not desirable because people want to use git-annex on a variety of filesystems and operating systems that treat them in a variety of broken ways. However, migrating to the all lower case hash directory names would require changing every git-annex symlink in every git repository, and I do not want to inflict that on my users.
+
+It seems to me that the best solution to your problem is to install git-annex on your server, which should not be very hard.
+"""]]
diff --git a/doc/todo/wishlist:_unify_directory_scheme_for_the_store/comment_2_bc698c501ecdb56df57171f4f3bb831a._comment b/doc/todo/wishlist:_unify_directory_scheme_for_the_store/comment_2_bc698c501ecdb56df57171f4f3bb831a._comment
new file mode 100644
index 000000000..5c5269f8c
--- /dev/null
+++ b/doc/todo/wishlist:_unify_directory_scheme_for_the_store/comment_2_bc698c501ecdb56df57171f4f3bb831a._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnpdM9F8VbtQ_H5PaPMpGSxPe_d5L1eJ6w"
+ nickname="Rafaël"
+ subject="comment 2"
+ date="2013-10-05T10:45:16Z"
+ content="""
+Thank you for prompt answer. I didn't know there were tarballs,
+and indeed I managed to install them easily (although I had to
+manually install glibc version 2.9, only 2.7 was installed).
+
+I found that bare git repos also use lower case hash directory
+names... I still would be happy with an optional migration to all
+lower case, with a new key-value backend, to avoid this little
+complication which happens sometimes (say when converting a repo
+from non-bare to bare).
+"""]]
diff --git a/doc/todo/wishlist:_unify_directory_scheme_for_the_store/comment_3_e555d0dbbaa05528806905c6a940724b._comment b/doc/todo/wishlist:_unify_directory_scheme_for_the_store/comment_3_e555d0dbbaa05528806905c6a940724b._comment
new file mode 100644
index 000000000..e6acad3b9
--- /dev/null
+++ b/doc/todo/wishlist:_unify_directory_scheme_for_the_store/comment_3_e555d0dbbaa05528806905c6a940724b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawnpdM9F8VbtQ_H5PaPMpGSxPe_d5L1eJ6w"
+ nickname="Rafaël"
+ subject="comment 3"
+ date="2013-10-07T13:33:40Z"
+ content="""
+By the way, I just had the case above, i.e. convert a bare repo to non-bare. In order to keep the annex files, I cloned the bare one, and git-annex move'ed all annex content to the new repo, and to my surprise it was slow, as if all files where copied (or maybe they were only checksummed?), instead of being only renamed (old and new repos were on the same partition). So I restate that at least a command line tool giving the prefix dirs would be useful, to allow scripting for this kind of situation.
+"""]]
diff --git a/doc/todo/wishlist:_use_hardlinks_for_local_clones.mdwn b/doc/todo/wishlist:_use_hardlinks_for_local_clones.mdwn
new file mode 100644
index 000000000..4b0694422
--- /dev/null
+++ b/doc/todo/wishlist:_use_hardlinks_for_local_clones.mdwn
@@ -0,0 +1,9 @@
+as far as I know, if you `git clone` locally a git-annex enabled repository, it will not have all the files available. you would need to use `git annex get` and all files would be copied over, wasting a significant amount of space.
+
+`git-clone` has this `--local` flags which hardlinks objects in `.git/objects`, but also, maybe more interestingly, has a `--shared` option to simply tell git to look in another repo for objects. it seems to me git-annex could leverage those functionalities to avoid file duplication when using local repositories.
+
+this would be especially useful for [ikiwiki](http://ikiwiki.info/forum/ikiwiki_and_big_files).
+
+This is a [[wishlist]], but I would also welcome implementation pointers to do this myself, thanks! --[[anarcat]]
+
+> [[dup|done]]
diff --git a/doc/todo/wishlist:_use_hardlinks_for_local_clones/comment_1_85064fafe472a5bd395d60ce8f7acb56._comment b/doc/todo/wishlist:_use_hardlinks_for_local_clones/comment_1_85064fafe472a5bd395d60ce8f7acb56._comment
new file mode 100644
index 000000000..4ef5f8414
--- /dev/null
+++ b/doc/todo/wishlist:_use_hardlinks_for_local_clones/comment_1_85064fafe472a5bd395d60ce8f7acb56._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.152.108.220"
+ subject="comment 1"
+ date="2013-09-25T17:14:28Z"
+ content="""
+git-annex uses cp --reflink=auto. So on a filesystem supporting COW file copies, like btrfs, `git annex get` will not use any disk space when getting from the same filesystem.
+
+I do not like the idea of using hardlinks, because changing the file in one repository would change it in the other, which may not be desired.
+
+[[union_mounting]] seems to cover this item pretty well, so I will close this as a duplicate.
+"""]]
diff --git a/doc/todo/wishlist:_vicfg_possible_repo_group_names.mdwn b/doc/todo/wishlist:_vicfg_possible_repo_group_names.mdwn
new file mode 100644
index 000000000..e30cc619a
--- /dev/null
+++ b/doc/todo/wishlist:_vicfg_possible_repo_group_names.mdwn
@@ -0,0 +1,16 @@
+git annex vicfg should display valid repository group names
+
+For trust levels the possible values are displayed:
+
+ # Repository trust configuration
+ # (Valid trust levels: trusted semitrusted untrusted dead)
+ ...
+
+The same is not currently done for repository groups
+
+ # Repository groups
+ # (Separate group names with spaces)
+
+Thanks.
+
+> [[done]] --[[Joey]]
diff --git a/doc/todo/wishlist:alias_system.mdwn b/doc/todo/wishlist:alias_system.mdwn
new file mode 100644
index 000000000..1f5012966
--- /dev/null
+++ b/doc/todo/wishlist:alias_system.mdwn
@@ -0,0 +1 @@
+To implement things like my custom `git annex-push` without the dash, i.e. `git annex push`, an alias system for git-annex would be nice.
diff --git a/doc/todo/wishlist_degraded_files.mdwn b/doc/todo/wishlist_degraded_files.mdwn
new file mode 100644
index 000000000..0b265c5eb
--- /dev/null
+++ b/doc/todo/wishlist_degraded_files.mdwn
@@ -0,0 +1,5 @@
+This is an idea to have a small placeholder file that is put into
+place when the file's actual content is not available in the local
+annex.
+
+Details being discussed here: <http://bugs.debian.org/728552>
diff --git a/doc/transferring_data.mdwn b/doc/transferring_data.mdwn
new file mode 100644
index 000000000..d1ec5963f
--- /dev/null
+++ b/doc/transferring_data.mdwn
@@ -0,0 +1,19 @@
+git-annex can transfer data to or from any of a repository's git remotes.
+Depending on where the remote is, the data transfer is done using rsync
+(over ssh or locally), or plain cp (with copy-on-write
+optimisations on supported filesystems), or using curl (for repositories
+on the web). Some [[special_remotes]] are also supported that are not
+traditional git remotes.
+
+If a data transfer is interrupted, git-annex retains the partial transfer
+to allow it to be automatically resumed later.
+
+It's equally easy to transfer a single file to or from a repository,
+or to launch a retrievel of a massive pile of files from whatever
+repositories they are scattered amongst.
+
+git-annex automatically uses whatever remotes are currently accessible,
+preferring ones that are less expensive to talk to.
+
+[[!img repomap.png caption="A real-world repository interconnection map
+(generated by git-annex map)"]]
diff --git a/doc/trust.mdwn b/doc/trust.mdwn
new file mode 100644
index 000000000..1fd47fd1d
--- /dev/null
+++ b/doc/trust.mdwn
@@ -0,0 +1,59 @@
+Git-annex supports several levels of trust of a repository:
+
+* semitrusted (default)
+* untrusted
+* trusted
+* dead
+
+## semitrusted
+
+Normally, git-annex does not fully trust its stored [[location_tracking]]
+information. When removing content, it will directly check
+that other repositories have enough [[copies]].
+
+Generally that explicit checking is a good idea. Consider that the current
+[[location_tracking]] information for a remote may not yet have propagated
+out. Or, a remote may have suffered a catastrophic loss of data, or itself
+been lost.
+
+There is still some trust involved here. A semitrusted repository is
+depended on to retain a copy of the file content; possibly the only
+[[copy|copies]].
+
+(Being semitrusted is the default. The `git annex semitrust` command
+restores a repository to this default, when it has been overridden.
+The `--semitrust` option can temporarily restore a repository to this
+default.)
+
+## untrusted
+
+An untrusted repository is not trusted to retain data at all. Git-annex
+will retain sufficient [[copies]] of data elsewhere.
+
+This is a good choice for eg, portable drives that could get lost. Or,
+if a disk is known to be dying, you can set it to untrusted and let
+`git annex fsck` warn about data that needs to be copied off it.
+
+To configure a repository as untrusted, use the `git annex untrust`
+command.
+
+## trusted
+
+Sometimes, you may have reasons to fully trust the location tracking
+information for a repository. For example, it may be an offline
+archival drive, from which you rarely or never remove content. Deciding
+when it makes sense to trust the tracking info is up to you.
+
+One way to handle this is just to use `--force` when a command cannot
+access a remote you trust. Or to use `--trust` to specify a repisitory to
+trust temporarily.
+
+To configure a repository as fully and permanently trusted,
+use the `git annex trust` command.
+
+## dead
+
+This is used to indicate that you have no trust that the repository
+exists at all. It's appropriate to use when a drive has been lost,
+or a directory irretrevably deleted. It will make git-annex avoid
+even showing the repository as a place where data might still reside.
diff --git a/doc/upgrades.mdwn b/doc/upgrades.mdwn
new file mode 100644
index 000000000..5cf4093dc
--- /dev/null
+++ b/doc/upgrades.mdwn
@@ -0,0 +1,106 @@
+Occasionally improvments are made to how git-annex stores its data,
+that require an upgrade process to convert repositories made with an older
+version to be used by a newer version. It's annoying, it should happen
+rarely, but sometimes, it's worth it.
+
+There's a committment that git-annex will always support upgrades from all
+past versions. After all, you may have offline drives from an earlier
+git-annex, and might want to use them with a newer git-annex.
+
+git-annex will notice if it is run in a repository that
+needs an upgrade, and refuse to do anything. To upgrade,
+use the "git annex upgrade" command.
+
+The upgrade process is guaranteed to be conflict-free. Unless you
+already have git conflicts in your repository or between repositories.
+Upgrading a repository with conflicts is not recommended; resolve the
+conflicts first before upgrading git-annex.
+
+## Upgrade events, so far
+
+### v4 -> v5 (git-annex version 5.x)
+
+v5 is only used for [[direct_mode]]. The upgrade from v4 to v5 is handled
+automatically.
+
+This upgrade involves changing direct mode repositories to operate with
+core.bare=true.
+
+### v3 -> v4 (git-annex version 4.x)
+
+v4 was only used for [[direct_mode]], to ensure that a version of git-annex
+that understands direct mode was used with a direct mode repository.
+
+### v2 -> v3 (git-annex version 3.x)
+
+Involved moving the .git-annex/ directory into a separate git-annex branch.
+
+After this upgrade, you should make sure you include the git-annex branch
+when git pushing and pulling.
+
+### tips for this upgrade
+
+This upgrade is easier (and faster!) than the previous upgrades.
+You don't need to upgrade every repository at once; it's sufficient
+to upgrade each repository only when you next use it.
+
+Example upgrade process:
+
+ cd localrepo
+ git pull
+ git annex upgrade
+ git commit -m "upgrade v2 to v3"
+ git gc
+
+### v1 -> v2 (git-annex version 0.20110316)
+
+Involved adding hashing to .git/annex/ and changing the names of all keys.
+Symlinks changed.
+
+Also, hashing was added to location log files in .git-annex/.
+And .gitattributes needed to have another line added to it.
+
+Previously, files added to the SHA [[backends]] did not have their file
+size tracked, while files added to the WORM backend did. Files added to
+the SHA backends after the conversion will have their file size tracked,
+and that information will be used by git-annex for disk free space checking.
+To ensure that information is available for all your annexed files, see
+[[upgrades/SHA_size]].
+
+### tips for this upgrade
+
+This upgrade can tend to take a while, if you have a lot of files.
+
+Each clone of a repository should be individually upgraded.
+Until a repository's remotes have been upgraded, git-annex
+will refuse to communicate with them.
+
+Start by upgrading one repository, and then you can commit
+the changes git-annex staged during upgrade, and push them out to other
+repositories. And then upgrade those other repositories. Doing it this
+way avoids git-annex doing some duplicate work during the upgrade.
+
+Example upgrade process:
+
+ cd localrepo
+ git pull
+ git annex upgrade
+ git commit -m "upgrade v1 to v2"
+ git push
+
+ ssh remote
+ cd remoterepo
+ git pull
+ git annex upgrade
+ ...
+
+### v0 -> v1 (git-annex version 0.04)
+
+Involved a reorganisation of the layout of .git/annex/. Symlinks changed.
+
+Handled more or less transparently, although git-annex was just 2 weeks
+old at the time, and had few users other than Joey.
+
+Before doing this upgrade, set annex.version:
+
+ git config annex.version 0
diff --git a/doc/upgrades/SHA_size.mdwn b/doc/upgrades/SHA_size.mdwn
new file mode 100644
index 000000000..97603ba91
--- /dev/null
+++ b/doc/upgrades/SHA_size.mdwn
@@ -0,0 +1,20 @@
+Before version 2 of the git-annex repository, files added to the SHA
+[[backends]] did not have their file size tracked, while files added to the
+WORM backend did. The file size information is used for disk free space
+checking.
+
+Files added to the SHA backends after the conversion will have their file
+size tracked automatically. This disk free space checking is an optional
+feature and since you're more likely to be using more recently added files,
+you're unlikely to see any bad effect if you do nothing.
+
+That said, if you have old files added to SHA backends that lack file size
+tracking info, here's how you can add that info. After [[upgrading|upgrades]]
+to repository version 2, in each repository run:
+
+ git annex migrate
+ git commit -m 'migrated keys for v2'
+
+The usual caveats about [[tips/migrating_data_to_a_new_backend]]
+apply; you will end up with unused keys that you can later clean up with
+`git annex unused`.
diff --git a/doc/upgrades/SHA_size/comment_1_20f9b7b75786075de666b2146dc13a60._comment b/doc/upgrades/SHA_size/comment_1_20f9b7b75786075de666b2146dc13a60._comment
new file mode 100644
index 000000000..7b6be1532
--- /dev/null
+++ b/doc/upgrades/SHA_size/comment_1_20f9b7b75786075de666b2146dc13a60._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkjvjLHW9Omza7x1VEzIFQ8Z5honhRB90I"
+ nickname="Asheesh"
+ subject="The fact that the keys changed causes merge conflicts"
+ date="2012-06-25T00:28:59Z"
+ content="""
+FYI, I have run into a problem where if you 'git annex sync' between various 'git annex v3' repositories, if the different repositories are using different encodings of the SHA1 information (one including size, one not), then the 'git merge' will declare that they conflict.
+
+There's no indication that 'git annex migrate' is the right tool to run, except from perusing the 'git annex' man page. In my opinion this is a major user interface problem.
+
+-- Asheesh.
+"""]]
diff --git a/doc/upgrades/gcrypt.mdwn b/doc/upgrades/gcrypt.mdwn
new file mode 100644
index 000000000..65f80f86e
--- /dev/null
+++ b/doc/upgrades/gcrypt.mdwn
@@ -0,0 +1,25 @@
+Unfortunately the initial gcrypt repository layout had to be changed
+after git-annex version 4.20130920. If you have an encrypted git repository
+created using version 4.20130920 or 4.20130909, you need to manually
+upgrade it.
+
+If you look at the contents of your gcrypt repository, you will
+see a bare git repository, with a few three-letter subdirectories,
+which are where git-annex stores its encrypted file contents:
+
+<pre>
+27f/ branches/ description hooks/ objects/
+HEAD config f37/ info/ refs/
+</pre>
+
+In the example above, the subdirectories are `27f` and `f37`.
+
+All you need to do to transition is move those subdirectories
+into an `annex/objects` directory.
+
+ mkdir annex ; mkdir annex/objects ; mv 27f f37 annex/objects
+
+Probably those are the only 3 letter things inside your git repository,
+so this will probably work:
+
+ mkdir annex ; mkdir annex/objects ; mv ??? annex/objects
diff --git a/doc/upgrades/gcrypt/comment_1_606c1527735996ae671f78948e4ad84b._comment b/doc/upgrades/gcrypt/comment_1_606c1527735996ae671f78948e4ad84b._comment
new file mode 100644
index 000000000..8805f4a8d
--- /dev/null
+++ b/doc/upgrades/gcrypt/comment_1_606c1527735996ae671f78948e4ad84b._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmj3kEGlCiy_Y-wb6AIBBnJ0B_SiPHV5Bo"
+ nickname="Thomas"
+ subject="small omission"
+ date="2013-09-25T04:59:03Z"
+ content="""
+In your second example, `mv ??? annex` has to be `mv ??? annex/objects`, I think.
+"""]]
diff --git a/doc/use_case/Alice.mdwn b/doc/use_case/Alice.mdwn
new file mode 100644
index 000000000..cdd3ea546
--- /dev/null
+++ b/doc/use_case/Alice.mdwn
@@ -0,0 +1,24 @@
+### use case: The Nomad
+
+Alice is always on the move, often with her trusty netbook and a small
+handheld terabyte USB drive, or a smaller USB keydrive. She has a server
+out there on the net. She stores data, encrypted in the Cloud.
+
+All these things can have different files on them, but Alice no longer
+has to deal with the tedious process of keeping them manually in sync,
+or remembering where she put a file. git-annex manages all these data
+sources as if they were git remotes.
+<small>[[more about special remotes|special_remotes]]</small>
+
+When she has 1 bar on her cell, Alice queues up interesting files on her
+server for later. At a coffee shop, she has git-annex download them to her
+USB drive. High in the sky or in a remote cabin, she catches up on
+podcasts, videos, and games, first letting git-annex copy them from
+her USB drive to the netbook (this saves battery power).
+<small>[[more about transferring data|transferring_data]]</small>
+
+When she's done, she tells git-annex which to keep and which to remove.
+They're all removed from her netbook to save space, and Alice knows
+that next time she syncs up to the net, her changes will be synced back
+to her server.
+<small>[[more about distributed version control|distributed_version_control]]</small>
diff --git a/doc/use_case/Bob.mdwn b/doc/use_case/Bob.mdwn
new file mode 100644
index 000000000..7a90cdd11
--- /dev/null
+++ b/doc/use_case/Bob.mdwn
@@ -0,0 +1,25 @@
+### use case: The Archivist
+
+Bob has many drives to archive his data, most of them
+[[kept offline|tips/offline_archive_drives]], in a safe place.
+
+With git-annex, Bob has a single directory tree that includes all
+his files, even if their content is being stored offline. He can
+reorganize his files using that tree, committing new versions to git,
+without worry about accidentally deleting anything.
+
+When Bob needs access to some files, git-annex can tell him which drive(s)
+they're on, and easily make them available. Indeed, every drive knows what
+is on every other drive.
+<small>[[more about location tracking|location_tracking]]</small>
+
+Bob thinks long-term, and so he appreciates that git-annex uses a simple
+repository format. He knows his files will be accessible in the future
+even if the world has forgotten about git-annex and git.
+<small>[[more about future-proofing|future_proofing]]</small>
+
+Run in a cron job, git-annex adds new files to archival drives at night. It
+also helps Bob keep track of intentional, and unintentional copies of
+files, and logs information he can use to decide when it's time to duplicate
+the content of old drives.
+<small>[[more about backup copies|copies]]</small>
diff --git a/doc/users.mdwn b/doc/users.mdwn
new file mode 100644
index 000000000..b9bab48ec
--- /dev/null
+++ b/doc/users.mdwn
@@ -0,0 +1,9 @@
+Users of this wiki, feel free to create a subpage of this one and talk
+about yourself on it, within reason. You can link to it to sign your
+comments.
+
+List of users
+=============
+[[!inline pages="users/* and !users/*/* and !*/Discussion"
+feeds=no archive=yes sort=title template=titlepage
+rootpage="users" postformtext="Add yourself as an git-annex user:"]]
diff --git a/doc/users/anarcat.mdwn b/doc/users/anarcat.mdwn
new file mode 100644
index 000000000..c7054ff19
--- /dev/null
+++ b/doc/users/anarcat.mdwn
@@ -0,0 +1,41 @@
+I use git-annex to manage huge files, mostly video and audio attached to other git repositories (such as presentations), but I also use git-annex to manage my music collection across multiple devices. I also use it to manage the `ISO` images I download, podcasts, and youtube videos.
+
+See <http://anarc.at/>.
+
+[[!toc]]
+
+My tips
+=======
+
+... or the ones I commented it, to be more precise.
+
+[[!inline pages="tips/* and and link(users/anarcat) and !bugs/*/*" sort=mtime feeds=no actions=yes archive=yes show=0]]
+
+
+My todos
+========
+
+... same.
+
+[[!inline pages="todo/* and !todo/done and !link(todo/done) and
+link(users/anarcat) and !todo/*/*" sort=mtime feeds=no actions=yes archive=yes show=0]]
+
+Done
+----
+
+[[!inline pages="todo/* and !todo/done and link(todo/done) and
+link(users/anarcat) and !todo/*/*" feeds=no actions=yes archive=yes show=0]]
+
+My bugs
+=======
+
+... same.
+
+[[!inline pages="bugs/* and !bugs/done and !link(bugs/done) and
+link(users/anarcat) and !bugs/*/*" sort=mtime feeds=no actions=yes archive=yes show=0]]
+
+Fixed
+-----
+
+[[!inline pages="bugs/* and !bugs/done and link(bugs/done) and
+link(users/anarcat) and !bugs/*/*" feeds=no actions=yes archive=yes show=0]]
diff --git a/doc/users/chrysn.mdwn b/doc/users/chrysn.mdwn
new file mode 100644
index 000000000..ba4261567
--- /dev/null
+++ b/doc/users/chrysn.mdwn
@@ -0,0 +1,11 @@
+* **name**: chrysn
+* **website**: <http://christian.amsuess.com/>
+* **uses git-annex for** managing the family's photos (and possibly videos and music in the future).
+* **likes git-annex because** it adds a layer of commit semantics over a regular file system without keeping everything in duplicate locally.
+* **would like git-annex not to** be required any more at all when
+ * git itself learns to use cow filesystems to avoid abundant disk usage, and
+ * git gets better with shallow clones.
+
+ git-annex might then still be a simpler tool that watches over what can be safely dropped from a particular shallow clone
+
+ (the issues with shallow clones seem to relate primarily to shallow history; i haven't read anything about what would happen if all commits were checked out, but not all trees and blobs)
diff --git a/doc/users/clacke.mdwn b/doc/users/clacke.mdwn
new file mode 100644
index 000000000..c48cd311f
--- /dev/null
+++ b/doc/users/clacke.mdwn
@@ -0,0 +1,3 @@
+Claes Wallin (韋嘉誠)
+
+[[https://microca.st/clacke]]
diff --git a/doc/users/fmarier.mdwn b/doc/users/fmarier.mdwn
new file mode 100644
index 000000000..d04b6968d
--- /dev/null
+++ b/doc/users/fmarier.mdwn
@@ -0,0 +1,6 @@
+# François Marier
+
+Free Software and Debian Developer. Lead developer of [Libravatar](https://www.libravatar.org)
+
+* [Blog](http://feeding.cloud.geek.nz) and [homepage](http://fmarier.org)
+* [Identica](http://identi.ca/fmarier) / [Twitter](https://twitter.com/fmarier)
diff --git a/doc/users/gebi.mdwn b/doc/users/gebi.mdwn
new file mode 100644
index 000000000..121bedbdd
--- /dev/null
+++ b/doc/users/gebi.mdwn
@@ -0,0 +1 @@
+Michael Gebetsroither <michael@mgeb.org>
diff --git a/doc/users/joey.mdwn b/doc/users/joey.mdwn
new file mode 100644
index 000000000..306e1cc76
--- /dev/null
+++ b/doc/users/joey.mdwn
@@ -0,0 +1,2 @@
+Joey Hess <joey@kitenet.net>
+<http://kitenet.net/~joey/>
diff --git a/doc/users/tobiastheviking.mdwn b/doc/users/tobiastheviking.mdwn
new file mode 100644
index 000000000..0629e34a9
--- /dev/null
+++ b/doc/users/tobiastheviking.mdwn
@@ -0,0 +1,20 @@
+Tobias Ussing
+
+See:
+
+[[https://github.com/TobiasTheViking/flickrannex/]]
+
+[[https://github.com/TobiasTheViking/imapannex]]
+
+[[https://github.com/TobiasTheViking/dropboxannex]]
+
+[[https://github.com/TobiasTheViking/skydriveannex]]
+
+[[https://github.com/TobiasTheViking/googledriveannex]]
+
+[[https://github.com/TobiasTheViking/owncloudannex]]
+
+[[https://github.com/TobiasTheViking/megaannex]]
+
+[[http://git-annex.branchable.com/forum/nntp__47__usenet_special_remote/]]
+
diff --git a/doc/videos.mdwn b/doc/videos.mdwn
new file mode 100644
index 000000000..f1adeeac4
--- /dev/null
+++ b/doc/videos.mdwn
@@ -0,0 +1,8 @@
+Talks and screencasts about git-annex.
+
+These videos are also available in a public git-annex repository
+`git clone http://downloads.kitenet.net/.git/`
+
+[[!inline pages="./videos/* and !./videos/*/* and !*/Discussion" show="2"]]
+
+[[!inline pages="./videos/* and !./videos/*/* and !*/Discussion" show="0" archive=yes skip=2 feeds=no]]
diff --git a/doc/videos/FOSDEM2012.mdwn b/doc/videos/FOSDEM2012.mdwn
new file mode 100644
index 000000000..30d1e37d5
--- /dev/null
+++ b/doc/videos/FOSDEM2012.mdwn
@@ -0,0 +1,7 @@
+<video controls
+src="http://video.fosdem.org/2012/lightningtalks/git_annex___manage_files_with_git,_without_checking_their_contents_into_git.webm"></video><br>
+A <a href="http://video.fosdem.org/2012/lightningtalks/git_annex___manage_files_with_git,_without_checking_their_contents_into_git.webm">15 minute introduction to git-annex</a>,
+presented by Richard Hartmann at FOSDEM 2012.
+
+[[!meta date="1 Jan 2012"]]
+[[!meta title="git-annex presentation by Richard Hartmann at FOSDEM 2012"]]
diff --git a/doc/videos/LCA2013.mdwn b/doc/videos/LCA2013.mdwn
new file mode 100644
index 000000000..0f29ce052
--- /dev/null
+++ b/doc/videos/LCA2013.mdwn
@@ -0,0 +1,8 @@
+<video controls>
+<source type="video/mp4" src="http://mirror.linux.org.au/linux.conf.au/2013/mp4/gitannex.mp4">
+<source type="video/ogg" src="http://mirror.linux.org.au/linux.conf.au/2013/ogv/gitannex.ogv">
+</video><br>
+A <a href="http://mirror.linux.org.au/linux.conf.au/2013/mp4/gitannex.mp4">45 minute talk and demo of git-annex and the assistant</a>), presented by Joey Hess at LCA 2013.
+
+[[!meta date="1 Feb 2013"]]
+[[!meta title="git-annex presentation by Joey Hess at Linux.Conf.Au 2013"]]
diff --git a/doc/videos/git-annex_assistant_archiving.mdwn b/doc/videos/git-annex_assistant_archiving.mdwn
new file mode 100644
index 000000000..7e891c2f7
--- /dev/null
+++ b/doc/videos/git-annex_assistant_archiving.mdwn
@@ -0,0 +1,5 @@
+<video controls width=400>
+<source src="https://downloads.kitenet.net/videos/git-annex/git-annex-assistant-archiving.ogv">
+</video><br>
+A <a href="https://downloads.kitenet.net/videos/git-annex/git-annex-assistant-archiving.ogv">9 minute screencast</a>
+covering archiving your files with the [[git-annex assistant|/assistant]]</a>.
diff --git a/doc/videos/git-annex_assistant_introduction.mdwn b/doc/videos/git-annex_assistant_introduction.mdwn
new file mode 100644
index 000000000..93f9df1ba
--- /dev/null
+++ b/doc/videos/git-annex_assistant_introduction.mdwn
@@ -0,0 +1,5 @@
+<video controls width=400>
+<source src="https://downloads.kitenet.net/videos/git-annex/git-annex-assistant-intro.ogv">
+</video><br>
+A <a href="https://downloads.kitenet.net/videos/git-annex/git-annex-assistant-intro.ogv">8 minute screencast</a>
+introducing the [[git-annex assistant|/assistant]]</a>.
diff --git a/doc/videos/git-annex_assistant_introduction/comment_1_f42ad4183c2c28319d3705a82fceb82f._comment b/doc/videos/git-annex_assistant_introduction/comment_1_f42ad4183c2c28319d3705a82fceb82f._comment
new file mode 100644
index 000000000..c969bacbc
--- /dev/null
+++ b/doc/videos/git-annex_assistant_introduction/comment_1_f42ad4183c2c28319d3705a82fceb82f._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="modules"
+ ip="85.16.227.39"
+ subject="Great screencast"
+ date="2013-03-16T14:16:37Z"
+ content="""
+I am starting to understand the concept :) Thank you.
+
+The assistant is working perfect with local repos and removable drives but i have problems to setup a remote repos. On a fresh debian server with base setup and rsync installed and ssh-keys for login. I got a green \"Scanned 93.xxx.xx.xxx_annex\" message on dashboard, but there is never a finished transfer. Its \"queued\" on all files and nothing seems to happens on clicking the \"play\" button behind files (x-ing files removes them from dashboard). Also i saw there is a second option in your screencast for remote servers (\"Use a git reposoitory on the server\") which does not show up on my side. Do i need to setup git-annex on server for second option? (with git-annex version 4.20130314).
+
+
+
+
+
+"""]]
diff --git a/doc/videos/git-annex_assistant_introduction/comment_2_b62f4eeeac1138570f7cb8c98d41c2cb._comment b/doc/videos/git-annex_assistant_introduction/comment_2_b62f4eeeac1138570f7cb8c98d41c2cb._comment
new file mode 100644
index 000000000..8b6d2a1e9
--- /dev/null
+++ b/doc/videos/git-annex_assistant_introduction/comment_2_b62f4eeeac1138570f7cb8c98d41c2cb._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 2"
+ date="2013-03-16T16:04:30Z"
+ content="""
+@modules: Yes, you're only given the option to use a git repository on the server if it has both git and git-annex installed. You can install any version of git-annex there. For example, Debian stable ships with one that will work.
+I plan to make that screen clearer when the git repository option is not available.
+
+I'm not sure what'd going on with your rsync transfers not running. I can say that if the \"play\" icon is visible, the transfer has been paused. While a transfer is running, the \"pause\" icon is visible instead, to let you pause it.
+This may be as simple as you having misunderstood the icons and paused the currently running transfer, which prevents any transfers from running. If not, suggest you enable debug logs in the Preferences page, and consider filing a [[bug_report|bugs]].
+"""]]
diff --git a/doc/videos/git-annex_assistant_remote_sharing.mdwn b/doc/videos/git-annex_assistant_remote_sharing.mdwn
new file mode 100644
index 000000000..6d9a97e8e
--- /dev/null
+++ b/doc/videos/git-annex_assistant_remote_sharing.mdwn
@@ -0,0 +1,6 @@
+<video controls width=400>
+<source src="https://downloads.kitenet.net/videos/git-annex/git-annex-xmpp-pairing.ogv">
+</video><br>
+A <a href="https://downloads.kitenet.net/videos/git-annex/git-annex-xmpp-pairing.ogv">6 minute screencast</a>
+showing how to share files between your computers in different locations,
+such as home and work.
diff --git a/doc/videos/git-annex_assistant_sync_demo.mdwn b/doc/videos/git-annex_assistant_sync_demo.mdwn
new file mode 100644
index 000000000..2df2a3a91
--- /dev/null
+++ b/doc/videos/git-annex_assistant_sync_demo.mdwn
@@ -0,0 +1,8 @@
+A screencast demoing the git-annex assistant syncing between Nicaragua
+and the United Kingdom for the first time.
+
+<video controls src="http://joeyh.name/screencasts/git-annex-assistant.ogg"></video>
+
+[video](http://joeyh.name/screencasts/git-annex-assistant.ogg)
+
+[[!meta date="Thu Jul 5 16:36:06 2012 -0600"]]
diff --git a/doc/videos/git-annex_watch_demo.mdwn b/doc/videos/git-annex_watch_demo.mdwn
new file mode 100644
index 000000000..3909f73b5
--- /dev/null
+++ b/doc/videos/git-annex_watch_demo.mdwn
@@ -0,0 +1,7 @@
+A quick screencast demoing the `git annex watch` daemon.
+
+<video controls src="http://joeyh.name/screencasts/git-annex-watch.ogg"></video>
+
+[video](http://joeyh.name/screencasts/git-annex-watch.ogg)
+
+[[!meta date="Mon Jun 11 16:02:14 2012 -0400"]]
diff --git a/doc/videos/git-annex_weppapp_demo.mdwn b/doc/videos/git-annex_weppapp_demo.mdwn
new file mode 100644
index 000000000..b982d32fd
--- /dev/null
+++ b/doc/videos/git-annex_weppapp_demo.mdwn
@@ -0,0 +1,8 @@
+A quick screencast demoing the early `git annex webapp` and
+automatic USB drive mount detection and syncing.
+
+<video controls src="http://joeyh.name/screencasts/git-annex-webapp.ogg"></video>
+
+[video](http://joeyh.name/screencasts/git-annex-webapp.ogg)
+
+[[!meta date="Sun Jul 29 14:41:41 2012 -0400"]]
diff --git a/doc/walkthrough.mdwn b/doc/walkthrough.mdwn
new file mode 100644
index 000000000..f401524f5
--- /dev/null
+++ b/doc/walkthrough.mdwn
@@ -0,0 +1,25 @@
+A walkthrough of the basic features of git-annex.
+
+[[!toc]]
+
+[[!inline feeds=no trail=yes show=0 template=walkthrough pagenames="""
+ walkthrough/creating_a_repository
+ walkthrough/adding_a_remote
+ walkthrough/adding_files
+ walkthrough/renaming_files
+ walkthrough/getting_file_content
+ walkthrough/syncing
+ walkthrough/transferring_files:_When_things_go_wrong
+ walkthrough/removing_files
+ walkthrough/removing_files:_When_things_go_wrong
+ walkthrough/modifying_annexed_files
+ walkthrough/using_ssh_remotes
+ walkthrough/moving_file_content_between_repositories
+ walkthrough/using_tags_and_branches
+ walkthrough/unused_data
+ walkthrough/fsck:_verifying_your_data
+ walkthrough/fsck:_when_things_go_wrong
+ walkthrough/backups
+ walkthrough/automatically_managing_content
+ walkthrough/more
+"""]]
diff --git a/doc/walkthrough/adding_a_remote.mdwn b/doc/walkthrough/adding_a_remote.mdwn
new file mode 100644
index 000000000..97690dfcd
--- /dev/null
+++ b/doc/walkthrough/adding_a_remote.mdwn
@@ -0,0 +1,19 @@
+Like any other git repository, git-annex repositories have remotes.
+Let's start by adding a USB drive as a remote.
+
+ # sudo mount /media/usb
+ # cd /media/usb
+ # git clone ~/annex
+ # cd annex
+ # git annex init "portable USB drive"
+ # git remote add laptop ~/annex
+ # cd ~/annex
+ # git remote add usbdrive /media/usb/annex
+
+This is all standard ad-hoc distributed git repository setup.
+The only git-annex specific part is telling it the name
+of the new repository created on the USB drive.
+
+Notice that both repos are set up as remotes of one another. This lets
+either get annexed files from the other. You'll want to do that even
+if you are using git in a more centralized fashion.
diff --git a/doc/walkthrough/adding_a_remote/comment_1_0a59355bd33a796aec97173607e6adc9._comment b/doc/walkthrough/adding_a_remote/comment_1_0a59355bd33a796aec97173607e6adc9._comment
new file mode 100644
index 000000000..4b0b9c0fd
--- /dev/null
+++ b/doc/walkthrough/adding_a_remote/comment_1_0a59355bd33a796aec97173607e6adc9._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 1"
+ date="2011-03-19T01:18:49Z"
+ content="""
+After doing the above with two required copy per file, `git annex fsck` complained that I had only one copy per file even though I had created my clone, already. Once I `git pull`ed from the second repo, not getting any changes for obvious reasons, `git annex fsck` was happy. So I am not sure how my addition was incorrect. -- RichiH
+"""]]
diff --git a/doc/walkthrough/adding_a_remote/comment_2_f8cd79ef1593a8181a7f1086a87713e8._comment b/doc/walkthrough/adding_a_remote/comment_2_f8cd79ef1593a8181a7f1086a87713e8._comment
new file mode 100644
index 000000000..015417a4f
--- /dev/null
+++ b/doc/walkthrough/adding_a_remote/comment_2_f8cd79ef1593a8181a7f1086a87713e8._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 2"
+ date="2011-03-19T15:35:38Z"
+ content="""
+Yes, you have to pull down location tracking information in order for fsck to be satisfied in that situation. But since this is a walkthrough, and neither fsck or numcopies settings are mentioned until later, it's ok for this pull to be described a few steps along in [[getting file content]].
+
+"""]]
diff --git a/doc/walkthrough/adding_a_remote/comment_3_60691af4400521b5a8c8d75efe3b44cb._comment b/doc/walkthrough/adding_a_remote/comment_3_60691af4400521b5a8c8d75efe3b44cb._comment
new file mode 100644
index 000000000..9280f2dcc
--- /dev/null
+++ b/doc/walkthrough/adding_a_remote/comment_3_60691af4400521b5a8c8d75efe3b44cb._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="http://dieter-be.myopenid.com/"
+ nickname="dieter"
+ subject="comment 3"
+ date="2011-04-02T20:24:33Z"
+ content="""
+ * why the `git remote add laptop ~/annex` ? this remote already exists under the name origin.
+ * doesn't the last command need to be `git remote add usbdrive /media/usb/annex`? because the actual repo would be in /media/usb/annex, not /media/usb?
+"""]]
diff --git a/doc/walkthrough/adding_a_remote/comment_4_6f7cf5c330272c96b3abeb6612075c9d._comment b/doc/walkthrough/adding_a_remote/comment_4_6f7cf5c330272c96b3abeb6612075c9d._comment
new file mode 100644
index 000000000..b4dcb6422
--- /dev/null
+++ b/doc/walkthrough/adding_a_remote/comment_4_6f7cf5c330272c96b3abeb6612075c9d._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 4"
+ date="2011-04-03T02:32:17Z"
+ content="""
+Good spotting on the last line, fixed.
+
+The laptop remote is indeed redundant, but it leads to clearer views of what is going on later in the walkthrough (\"git pull laptop master\", \"(copying from laptop...)\"). And if the original clone is made from a central bare repo, this reinforces that you'll want to set up remotes for other repos on the computer.
+"""]]
diff --git a/doc/walkthrough/adding_files.mdwn b/doc/walkthrough/adding_files.mdwn
new file mode 100644
index 000000000..d1b5a04f7
--- /dev/null
+++ b/doc/walkthrough/adding_files.mdwn
@@ -0,0 +1,11 @@
+ # cd ~/annex
+ # cp /tmp/big_file .
+ # cp /tmp/debian.iso .
+ # git annex add .
+ add big_file (checksum...) ok
+ add debian.iso (checksum...) ok
+ # git commit -a -m added
+
+When you add a file to the annex and commit it, only a symlink to
+the annexed content is committed. The content itself is stored in
+git-annex's backend.
diff --git a/doc/walkthrough/automatically_managing_content.mdwn b/doc/walkthrough/automatically_managing_content.mdwn
new file mode 100644
index 000000000..0080ebcb5
--- /dev/null
+++ b/doc/walkthrough/automatically_managing_content.mdwn
@@ -0,0 +1,45 @@
+Once you have multiple repositories, and have perhaps configured numcopies,
+any given file can have many more copies than is needed, or perhaps fewer
+than you would like. How to manage this?
+
+The whereis subcommand can be used to see how many copies of a file are known,
+but then you have to decide what to get or drop. In this example, there
+are perhaps not enough copies of the first file, and too many of the second
+file.
+
+ # cd /media/usbdrive
+ # git annex whereis
+ whereis my_cool_big_file (1 copy)
+ 0c443de8-e644-11df-acbf-f7cd7ca6210d -- laptop
+ whereis other_file (3 copies)
+ 0c443de8-e644-11df-acbf-f7cd7ca6210d -- laptop
+ 62b39bbe-4149-11e0-af01-bb89245a1e61 -- here (usb drive)
+ 7570b02e-15e9-11e0-adf0-9f3f94cb2eaa -- backup drive
+
+What would be handy is some automated versions of get and drop, that only
+gets a file if there are not yet enough copies of it, or only drops a file
+if there are too many copies. Well, these exist, just use the --auto option.
+
+ # git annex get --auto --numcopies=2
+ get my_cool_big_file (from laptop...) ok
+ # git annex drop --auto --numcopies=2
+ drop other_file ok
+
+With two quick commands, git-annex was able to decide for you how to
+work toward having two copies of your files.
+
+ # git annex whereis
+ whereis my_cool_big_file (2 copies)
+ 0c443de8-e644-11df-acbf-f7cd7ca6210d -- laptop
+ 62b39bbe-4149-11e0-af01-bb89245a1e61 -- here (usb drive)
+ whereis other_file (2 copies)
+ 0c443de8-e644-11df-acbf-f7cd7ca6210d -- laptop
+ 7570b02e-15e9-11e0-adf0-9f3f94cb2eaa -- backup drive
+
+The --auto option can also be used with the copy command,
+again this lets git-annex decide whether to actually copy content.
+
+The above shows how to use --auto to manage content based on the number
+of copies. It's also possible to configure, on a per-repository basis,
+which content is desired. Then --auto also takes that into account
+see [[preferred_content]] for details.
diff --git a/doc/walkthrough/backups.mdwn b/doc/walkthrough/backups.mdwn
new file mode 100644
index 000000000..9723022b4
--- /dev/null
+++ b/doc/walkthrough/backups.mdwn
@@ -0,0 +1,25 @@
+git-annex can be configured to require more than one copy of a file exists,
+as a simple backup for your data. This is controlled by the "annex.numcopies"
+setting, which defaults to 1 copy. Let's change that to require 2 copies,
+and send a copy of every file to a USB drive.
+
+ # echo "* annex.numcopies=2" >> .gitattributes
+ # git annex copy . --to usbdrive
+
+Now when we try to `git annex drop` a file, it will verify that it
+knows of 2 other repositories that have a copy before removing its
+content from the current repository.
+
+You can also vary the number of copies needed, depending on the file name.
+So, if you want 3 copies of all your flac files, but only 1 copy of oggs:
+
+ # echo "*.ogg annex.numcopies=1" >> .gitattributes
+ # echo "*.flac annex.numcopies=3" >> .gitattributes
+
+Or, you might want to make a directory for important stuff, and configure
+it so anything put in there is backed up more thoroughly:
+
+ # mkdir important_stuff
+ # echo "* annex.numcopies=3" > important_stuff/.gitattributes
+
+For more details about the numcopies setting, see [[copies]].
diff --git a/doc/walkthrough/creating_a_repository.mdwn b/doc/walkthrough/creating_a_repository.mdwn
new file mode 100644
index 000000000..51ff1c72b
--- /dev/null
+++ b/doc/walkthrough/creating_a_repository.mdwn
@@ -0,0 +1,6 @@
+This is very straightforward. Just tell it a description of the repository.
+
+ # mkdir ~/annex
+ # cd ~/annex
+ # git init
+ # git annex init "my laptop"
diff --git a/doc/walkthrough/fsck:_verifying_your_data.mdwn b/doc/walkthrough/fsck:_verifying_your_data.mdwn
new file mode 100644
index 000000000..d036332fb
--- /dev/null
+++ b/doc/walkthrough/fsck:_verifying_your_data.mdwn
@@ -0,0 +1,16 @@
+You can use the fsck subcommand to check for problems in your data. What
+can be checked depends on the key-value [[backend|backends]] you've used
+for the data. For example, when you use the SHA1 backend, fsck will verify
+that the checksums of your files are good. Fsck also checks that the
+annex.numcopies setting is satisfied for all files.
+
+ # git annex fsck
+ fsck some_file (checksum...) ok
+ fsck my_cool_big_file (checksum...) ok
+ ...
+
+You can also specify the files to check. This is particularly useful if
+you're using sha1 and don't want to spend a long time checksumming everything.
+
+ # git annex fsck my_cool_big_file
+ fsck my_cool_big_file (checksum...) ok
diff --git a/doc/walkthrough/fsck:_when_things_go_wrong.mdwn b/doc/walkthrough/fsck:_when_things_go_wrong.mdwn
new file mode 100644
index 000000000..85d9f20fe
--- /dev/null
+++ b/doc/walkthrough/fsck:_when_things_go_wrong.mdwn
@@ -0,0 +1,13 @@
+Fsck never deletes possibly bad data; instead it will be moved to
+`.git/annex/bad/` for you to recover. Here is a sample of what fsck
+might say about a badly messed up annex:
+
+ # git annex fsck
+ fsck my_cool_big_file (checksum...)
+ git-annex: Bad file content; moved to .git/annex/bad/SHA1:7da006579dd64330eb2456001fd01948430572f2
+ git-annex: ** No known copies exist of my_cool_big_file
+ failed
+ fsck important_file
+ git-annex: Only 1 of 2 copies exist. Run git annex get somewhere else to back it up.
+ failed
+ git-annex: 2 failed
diff --git a/doc/walkthrough/getting_file_content.mdwn b/doc/walkthrough/getting_file_content.mdwn
new file mode 100644
index 000000000..f92704ff3
--- /dev/null
+++ b/doc/walkthrough/getting_file_content.mdwn
@@ -0,0 +1,12 @@
+A repository does not always have all annexed file contents available.
+When you need the content of a file, you can use "git annex get" to
+make it available.
+
+We can use this to copy everything in the laptop's annex to the
+USB drive.
+
+ # cd /media/usb/annex
+ # git annex sync laptop
+ # git annex get .
+ get my_cool_big_file (from laptop...) ok
+ get iso/debian.iso (from laptop...) ok
diff --git a/doc/walkthrough/modifying_annexed_files.mdwn b/doc/walkthrough/modifying_annexed_files.mdwn
new file mode 100644
index 000000000..693eae944
--- /dev/null
+++ b/doc/walkthrough/modifying_annexed_files.mdwn
@@ -0,0 +1,44 @@
+Normally, the content of files in the annex is prevented from being modified.
+(Unless your repository is using [[direct_mode]].)
+
+That's a good thing, because it might be the only copy, you wouldn't
+want to lose it in a fumblefingered mistake.
+
+ # echo oops > my_cool_big_file
+ bash: my_cool_big_file: Permission denied
+
+In order to modify a file, it should first be unlocked.
+
+ # git annex unlock my_cool_big_file
+ unlock my_cool_big_file (copying...) ok
+
+That replaces the symlink that normally points at its content with a copy
+of the content. You can then modify the file like any regular file. Because
+it is a regular file.
+
+(If you decide you don't need to modify the file after all, or want to discard
+modifications, just use `git annex lock`.)
+
+When you `git commit`, git-annex's pre-commit hook will automatically
+notice that you are committing an unlocked file, and add its new content
+to the annex. The file will be replaced with a symlink to the new content,
+and this symlink is what gets committed to git in the end.
+
+ # echo "now smaller, but even cooler" > my_cool_big_file
+ # git commit my_cool_big_file -m "changed an annexed file"
+ add my_cool_big_file ok
+ [master 64cda67] changed an annexed file
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+There is one problem with using `git commit` like this: Git wants to first
+stage the entire contents of the file in its index. That can be slow for
+big files (sorta why git-annex exists in the first place). So, the
+automatic handling on commit is a nice safety feature, since it prevents
+the file content being accidentally committed into git. But when working with
+big files, it's faster to explicitly add them to the annex yourself
+before committing.
+
+ # echo "now smaller, but even cooler yet" > my_cool_big_file
+ # git annex add my_cool_big_file
+ add my_cool_big_file ok
+ # git commit my_cool_big_file -m "changed an annexed file"
diff --git a/doc/walkthrough/modifying_annexed_files/comment_1_624b4a0b521b553d68ab6049f7dbaf8c._comment b/doc/walkthrough/modifying_annexed_files/comment_1_624b4a0b521b553d68ab6049f7dbaf8c._comment
new file mode 100644
index 000000000..5fc26496e
--- /dev/null
+++ b/doc/walkthrough/modifying_annexed_files/comment_1_624b4a0b521b553d68ab6049f7dbaf8c._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="http://lj.rossia.org/users/imz/"
+ ip="79.165.56.162"
+ subject="sorta why git-annex exists in the first place -- not only the slow index "
+ date="2012-09-25T22:04:01Z"
+ content="""
+> Git wants to first stage the entire contents of the file in its index. That can be slow for big files (sorta why git-annex exists in the first place)
+
+I think that git-annex's usefulness is not only because of the Git's index overhead: I like its idea because it will help track the copies in the \"[[special remotes]]\", which are not Git because
+
+* they are either not under my control (e.g., web URLs),
+* or because it's not convenient to hold a Git repo there (an external disk/DVD with files can be viewed easily by a human, but imposing a Git repo structure on it would either at least double the consume space: for the history of the commits and for the working dir, or make it \"unreadable\" for a human, if it is a bare repo);
+* or because it's nearly impossible to put a Git repo on a storage like peer networks without special tools.
+"""]]
diff --git a/doc/walkthrough/modifying_annexed_files/comment_2_b000622304535d32b69db17d51156b21._comment b/doc/walkthrough/modifying_annexed_files/comment_2_b000622304535d32b69db17d51156b21._comment
new file mode 100644
index 000000000..6a2d2c2a6
--- /dev/null
+++ b/doc/walkthrough/modifying_annexed_files/comment_2_b000622304535d32b69db17d51156b21._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://yarikoptic.myopenid.com/"
+ nickname="site-myopenid"
+ subject="feature request: unlock --drop"
+ date="2013-05-30T20:26:52Z"
+ content="""
+ATM unlock copies original file for modifications, so that original copy remains under annex and possibly to-be-edited copy created.
+But if I am \"unlock\"ing file I might simply not be interested in a previous copy and want to maintain only a single (possibly edited) new copy.
+What if there was a mode where the actual file is simply moved into \"unlocked\" location for editing, thus effectively dropping the actual content from git annex. That would allow to not inquire lengthy copying/wasting local space. If then I would need a previous copy I would just \"get\" it again.
+"""]]
diff --git a/doc/walkthrough/more.mdwn b/doc/walkthrough/more.mdwn
new file mode 100644
index 000000000..0a4a5b94e
--- /dev/null
+++ b/doc/walkthrough/more.mdwn
@@ -0,0 +1,3 @@
+So ends the walkthrough. By now you should be able to use git-annex.
+
+Want more? See [[tips]] for lots more features and advice.
diff --git a/doc/walkthrough/moving_file_content_between_repositories.mdwn b/doc/walkthrough/moving_file_content_between_repositories.mdwn
new file mode 100644
index 000000000..3ffcc1175
--- /dev/null
+++ b/doc/walkthrough/moving_file_content_between_repositories.mdwn
@@ -0,0 +1,13 @@
+Often you will want to move some file contents from a repository to some
+other one. For example, your laptop's disk is getting full; time to move
+some files to an external disk before moving another file from a file
+server to your laptop. Doing that by hand (by using `git annex get` and
+`git annex drop`) is possible, but a bit of a pain. `git annex move`
+makes it very easy.
+
+ # git annex move my_cool_big_file --to usbdrive
+ move my_cool_big_file (to usbdrive...) ok
+ # git annex move video/hackity_hack_and_kaxxt.mov --from fileserver
+ move video/hackity_hack_and_kaxxt.mov (from fileserver...)
+ SHA256-s86050597--6ae2688bc533437766a48aa19f2c06be14d1bab9c70b468af445d4f07b65f41e 100% 82MB 199.1KB/s 07:02
+ ok
diff --git a/doc/walkthrough/moving_file_content_between_repositories/comment_1_4c30ade91fc7113a95960aa3bd1d5427._comment b/doc/walkthrough/moving_file_content_between_repositories/comment_1_4c30ade91fc7113a95960aa3bd1d5427._comment
new file mode 100644
index 000000000..b3dc8fe7a
--- /dev/null
+++ b/doc/walkthrough/moving_file_content_between_repositories/comment_1_4c30ade91fc7113a95960aa3bd1d5427._comment
@@ -0,0 +1,19 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 1"
+ date="2011-03-22T23:41:51Z"
+ content="""
+I may be missing something obvious, but when I copy to a remote repository, the object files are created, but no softlinks are created. When I pull everything from the remote, it pulls only files the local repo knows about already.
+
+ A
+ / \
+ B C
+
+Moving from B to A creates no symlinks in A but the object files are moved to A. Copying back from A to B restores the object files in B and keeps them in A.
+
+Copying from A to an empty C does not create any object files nor symlinks. Copying from C to A creates no symlinks in A but the object files are copied to A.
+
+-- RichiH
+
+"""]]
diff --git a/doc/walkthrough/moving_file_content_between_repositories/comment_2_7d90e1e150e7524ba31687108fcc38d6._comment b/doc/walkthrough/moving_file_content_between_repositories/comment_2_7d90e1e150e7524ba31687108fcc38d6._comment
new file mode 100644
index 000000000..a6f8e9cf9
--- /dev/null
+++ b/doc/walkthrough/moving_file_content_between_repositories/comment_2_7d90e1e150e7524ba31687108fcc38d6._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 2"
+ date="2011-03-23T00:38:10Z"
+ content="""
+`git annex move` only moves content. All symlink management is handled by git, so you have to keep repositories in sync using git as you would any other repo. When you `git pull B` in A, it will get whatever symlinks were added to B.
+
+(It can be useful to use a central bare repo and avoid needing to git pull from one repo to another, then you can just always push commits to the central repo, and pull down all changes from other repos.)
+"""]]
diff --git a/doc/walkthrough/moving_file_content_between_repositories/comment_3_558d80384434207b9cfc033763863de3._comment b/doc/walkthrough/moving_file_content_between_repositories/comment_3_558d80384434207b9cfc033763863de3._comment
new file mode 100644
index 000000000..9a128f1ed
--- /dev/null
+++ b/doc/walkthrough/moving_file_content_between_repositories/comment_3_558d80384434207b9cfc033763863de3._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawl9sYlePmv1xK-VvjBdN-5doOa_Xw-jH4U"
+ nickname="Richard"
+ subject="comment 3"
+ date="2011-03-23T02:07:49Z"
+ content="""
+Ah yes, I feel kinda stupid in hindsight.
+
+As the central server is most likely a common use case, would you object if I added that to the walkthrough? If you have any best practices on how to automate a push with every copy to a bare remote? AFAIK, git does not store information about bare/non-bare remotes, but this could easily be put into .git/config by git annex.
+
+-- RichiH
+"""]]
diff --git a/doc/walkthrough/moving_file_content_between_repositories/comment_4_a2f343eceed9e9fba1670f21e0fc6af4._comment b/doc/walkthrough/moving_file_content_between_repositories/comment_4_a2f343eceed9e9fba1670f21e0fc6af4._comment
new file mode 100644
index 000000000..8b4d9a053
--- /dev/null
+++ b/doc/walkthrough/moving_file_content_between_repositories/comment_4_a2f343eceed9e9fba1670f21e0fc6af4._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 4"
+ date="2011-03-23T15:28:00Z"
+ content="""
+I would not mind if the walkthrough documented the central git repo case. But I don't want to complicate it unduely (it's long enough), and it's important that the fully distributed case be shown to work, and I assume that people already have basic git knowledge, so documenting the details of set up of a bare git repo is sorta out of scope. (There are also a lot of way to do it, using github, or gitosis, or raw git, etc.)
+"""]]
diff --git a/doc/walkthrough/removing_files.mdwn b/doc/walkthrough/removing_files.mdwn
new file mode 100644
index 000000000..9b85d9c3b
--- /dev/null
+++ b/doc/walkthrough/removing_files.mdwn
@@ -0,0 +1,17 @@
+When you're using git-annex you can `git rm` a file just like you usually
+would with git. Just like with git, this removes the file from your work
+tree, but it does not remove the file's content from the git repository.
+If you check the file back out, or revert the removal, you can get it back.
+
+Git-annex adds the ability to remove the content of a file from your local
+repository to save space. This is called "dropping" the file.
+
+You can always drop files safely. Git-annex checks that some other
+repository still has the file before removing it.
+
+ # git annex drop iso/debian.iso
+ drop iso/Debian_5.0.iso ok
+
+Once dropped, the file will still appear in your work tree as a broken symlink.
+You can use `git annex get` to as usual to get this file back to your local
+repository.
diff --git a/doc/walkthrough/removing_files/comment_1_cb65e7c510b75be1c51f655b058667c6._comment b/doc/walkthrough/removing_files/comment_1_cb65e7c510b75be1c51f655b058667c6._comment
new file mode 100644
index 000000000..1c8719cec
--- /dev/null
+++ b/doc/walkthrough/removing_files/comment_1_cb65e7c510b75be1c51f655b058667c6._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="DavidEdmondson"
+ subject="Is it necessary to commit after the 'drop'?"
+ date="2011-09-05T15:43:25Z"
+ content="""
+In fact is it possible? Nothing changed as far as git is concerned.
+
+"""]]
diff --git a/doc/walkthrough/removing_files/comment_2_64709ea4558915edd5c8ca4486965b07._comment b/doc/walkthrough/removing_files/comment_2_64709ea4558915edd5c8ca4486965b07._comment
new file mode 100644
index 000000000..f5fb8dc7f
--- /dev/null
+++ b/doc/walkthrough/removing_files/comment_2_64709ea4558915edd5c8ca4486965b07._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joey.kitenet.net/"
+ nickname="joey"
+ subject="comment 2"
+ date="2011-09-05T15:59:27Z"
+ content="""
+Good catch. It used to be necessary before there was a git-annex branch, but not now.
+"""]]
diff --git a/doc/walkthrough/removing_files:_When_things_go_wrong.mdwn b/doc/walkthrough/removing_files:_When_things_go_wrong.mdwn
new file mode 100644
index 000000000..2d3c0cde0
--- /dev/null
+++ b/doc/walkthrough/removing_files:_When_things_go_wrong.mdwn
@@ -0,0 +1,24 @@
+Before dropping a file, git-annex wants to be able to look at other
+remotes, and verify that they still have a file. After all, it could
+have been dropped from them too. If the remotes are not mounted/available,
+you'll see something like this.
+
+ # git annex drop important_file other.iso
+ drop important_file (unsafe)
+ Could only verify the existence of 0 out of 1 necessary copies
+ Unable to access these remotes: usbdrive
+ Try making some of these repositories available:
+ 58d84e8a-d9ae-11df-a1aa-ab9aa8c00826 -- portable USB drive
+ ca20064c-dbb5-11df-b2fe-002170d25c55 -- backup SATA drive
+ (Use --force to override this check, or adjust annex.numcopies.)
+ failed
+ drop other.iso (unsafe)
+ Could only verify the existence of 0 out of 1 necessary copies
+ No other repository is known to contain the file.
+ (Use --force to override this check, or adjust annex.numcopies.)
+ failed
+
+Here you might --force it to drop `important_file` if you [[trust]] your backup.
+But `other.iso` looks to have never been copied to anywhere else, so if
+it's something you want to hold onto, you'd need to transfer it to
+some other repository before dropping it.
diff --git a/doc/walkthrough/renaming_files.mdwn b/doc/walkthrough/renaming_files.mdwn
new file mode 100644
index 000000000..85964d1ea
--- /dev/null
+++ b/doc/walkthrough/renaming_files.mdwn
@@ -0,0 +1,13 @@
+ # cd ~/annex
+ # git mv big_file my_cool_big_file
+ # mkdir iso
+ # git mv debian.iso iso/
+ # git commit -m moved
+
+You can use any normal git operations to move files around, or even
+make copies or delete them.
+
+Notice that, since annexed files are represented by symlinks,
+the symlink will break when the file is moved into a subdirectory.
+But, git-annex will fix this up for you when you commit --
+it has a pre-commit hook that watches for and corrects broken symlinks.
diff --git a/doc/walkthrough/syncing.mdwn b/doc/walkthrough/syncing.mdwn
new file mode 100644
index 000000000..0c8d52559
--- /dev/null
+++ b/doc/walkthrough/syncing.mdwn
@@ -0,0 +1,27 @@
+Notice that in the [[previous example|getting_file_content]], `git annex
+sync` was used. This lets git-annex know what has changed in the other
+repositories like the laptop, and so it knows about the files present there and can
+get them.
+
+Let's look at what the sync command does in more detail:
+
+ # cd /media/usb/annex
+ # git annex sync
+ commit
+ nothing to commit (working directory clean)
+ ok
+ pull laptop
+ ok
+ push laptop
+ ok
+
+After you run sync, the repository will be updated with all changes made to
+its remotes, and any changes in the repository will be pushed out to its
+remotes, where a sync will get them. This is especially useful when using
+git in a distributed fashion, without a
+[[central bare repository|tips/centralized_git_repository_tutorial]]. See
+[[sync]] for details.
+
+Note that syncing only syncs the metadata about your files that is stored
+in git. It does not sync the contents of files, that are managed by
+git-annex.
diff --git a/doc/walkthrough/transferring_files:_When_things_go_wrong.mdwn b/doc/walkthrough/transferring_files:_When_things_go_wrong.mdwn
new file mode 100644
index 000000000..cfb70aaf9
--- /dev/null
+++ b/doc/walkthrough/transferring_files:_When_things_go_wrong.mdwn
@@ -0,0 +1,17 @@
+After a while, you'll have several annexes, with different file contents.
+You don't have to try to keep all that straight; git-annex does
+[[location_tracking]] for you. If you ask it to get a file and the drive
+or file server is not accessible, it will let you know what it needs to get
+it:
+
+ # git annex get video/hackity_hack_and_kaxxt.mov
+ get video/_why_hackity_hack_and_kaxxt.mov (not available)
+ Unable to access these remotes: usbdrive, server
+ Try making some of these repositories available:
+ 5863d8c0-d9a9-11df-adb2-af51e6559a49 -- my home file server
+ 58d84e8a-d9ae-11df-a1aa-ab9aa8c00826 -- portable USB drive
+ ca20064c-dbb5-11df-b2fe-002170d25c55 -- backup SATA drive
+ failed
+ # sudo mount /media/usb
+ # git annex get video/hackity_hack_and_kaxxt.mov
+ get video/hackity_hack_and_kaxxt.mov (from usbdrive...) ok
diff --git a/doc/walkthrough/unused_data.mdwn b/doc/walkthrough/unused_data.mdwn
new file mode 100644
index 000000000..1d655b89a
--- /dev/null
+++ b/doc/walkthrough/unused_data.mdwn
@@ -0,0 +1,35 @@
+It's possible for data to accumulate in the annex that no files in any
+branch point to anymore. One way it can happen is if you `git rm` a file
+without first calling `git annex drop`. And, when you modify an annexed
+file, the old content of the file remains in the annex. Another way is when
+migrating between key-value [[backends]].
+
+This might be historical data you want to preserve, so git-annex defaults to
+preserving it. So from time to time, you may want to check for such data:
+
+ # git annex unused
+ unused . (checking for unused data...)
+ Some annexed data is no longer used by any files in the repository.
+ NUMBER KEY
+ 1 SHA256-s86050597--6ae2688bc533437766a48aa19f2c06be14d1bab9c70b468af445d4f07b65f41e
+ 2 SHA1-s14--f1358ec1873d57350e3dc62054dc232bc93c2bd1
+ (To see where data was previously used, try: git log --stat -S'KEY')
+ (To remove unwanted data: git-annex dropunused NUMBER)
+ ok
+
+After running `git annex unused`, you can follow the instructions to examine
+the history of files that used the data, and if you decide you don't need that
+data anymore, you can easily remove it from your local repository.
+
+ # git annex dropunused 1
+ dropunused 1 ok
+
+Hint: To drop a lot of unused data, use a command like this:
+
+ # git annex dropunused 1-1000
+
+Rather than removing the data, you can instead send it to other
+repositories:
+
+ # git annex copy --unused --to backup
+ # git annex move --unused --to archive
diff --git a/doc/walkthrough/unused_data/comment_1_684b7b652d3a8ec04f32129c5528f1ab._comment b/doc/walkthrough/unused_data/comment_1_684b7b652d3a8ec04f32129c5528f1ab._comment
new file mode 100644
index 000000000..2be2a6463
--- /dev/null
+++ b/doc/walkthrough/unused_data/comment_1_684b7b652d3a8ec04f32129c5528f1ab._comment
@@ -0,0 +1,22 @@
+[[!comment format=mdwn
+ username="bremner"
+ ip="156.34.89.108"
+ subject="finding data that isn't unused, but should be."
+ date="2012-10-17T20:32:11Z"
+ content="""
+Sometimes links to annexed data still exists on some branch, when it was supposed to be dropped. Here is how I found these; perhaps there is a simpler way.
+
+ % git annex find --format '${key}\n' | sort > /tmp/known-keys
+ % find .git/annex/objects -type f -exec basename {} \; | sort > /tmp/local-keys
+ % comm -23 /tmp/local-keys /tmp/known-keys
+
+to look for what branch these are on, try
+
+ % git log --stat --all -S$key
+
+for one of the keys output above. In my case it was the same remote branch keeping them all alive.
+
+
+*EDIT* sort key lists to make comm work properly
+
+"""]]
diff --git a/doc/walkthrough/using_bup.mdwn b/doc/walkthrough/using_bup.mdwn
new file mode 100644
index 000000000..3a6a8776a
--- /dev/null
+++ b/doc/walkthrough/using_bup.mdwn
@@ -0,0 +1,37 @@
+Another [[special_remote|special_remotes]] that git-annex can use is
+a [[special_remotes/bup]] repository. Bup stores large file contents
+in a git repository of its own, with deduplication. Combined with
+git-annex, you can have git on both the frontend and the backend.
+
+Here's how to create a bup remote, and describe it.
+
+[[!template id=note text="""
+Instead of specifying a remote system, you could choose to make a bup
+remote that is only accessible on the current system, by passing
+"buprepo=/big/mybup".
+"""]]
+
+ # git annex initremote mybup type=bup encryption=none buprepo=example.com:/big/mybup
+ initremote bup (bup init)
+ Initialized empty Git repository in /big/mybup/
+ ok
+ # git annex describe mybup "my bup repository at example.com"
+ describe mybup ok
+
+Now the remote can be used like any other remote.
+
+ # git annex move my_cool_big_file --to mybup
+ move my_cool_big_file (to mybup...)
+ Receiving index from server: 1100/1100, done.
+ ok
+
+Note that, unlike other remotes, bup does not really support removing
+content from its git repositories. This is a feature. :)
+
+ # git annex move my_cool_big_file --from mybup
+ move my_cool_big_file (from mybup...)
+ content cannot be removed from bup remote
+ failed
+ git-annex: 1 failed
+
+See [[special_remotes/bup]] for details.
diff --git a/doc/walkthrough/using_ssh_remotes.mdwn b/doc/walkthrough/using_ssh_remotes.mdwn
new file mode 100644
index 000000000..1dc8fa55b
--- /dev/null
+++ b/doc/walkthrough/using_ssh_remotes.mdwn
@@ -0,0 +1,33 @@
+So far in this walkthrough, git-annex has been used with a remote
+repository on a USB drive. But it can also be used with a git remote
+that is truly remote, a host accessed by ssh.
+
+Say you have a desktop on the same network as your laptop and want
+to clone the laptop's annex to it:
+
+ # git clone ssh://mylaptop/home/me/annex ~/annex
+ # cd ~/annex
+ # git annex init "my desktop"
+
+Now you can get files and they will be transferred (using `rsync` via `ssh`):
+
+ # git annex get my_cool_big_file
+ get my_cool_big_file (getting UUID for origin...) (from origin...)
+ SHA256-s86050597--6ae2688bc533437766a48aa19f2c06be14d1bab9c70b468af445d4f07b65f41e 100% 2159 2.1KB/s 00:00
+ ok
+
+When you drop files, git-annex will ssh over to the remote and make
+sure the file's content is still there before removing it locally:
+
+ # git annex drop my_cool_big_file
+ drop my_cool_big_file (checking origin..) ok
+
+Note that normally git-annex prefers to use non-ssh remotes, like
+a USB drive, before ssh remotes. They are assumed to be faster/cheaper to
+access, if available. There is a annex-cost setting you can configure in
+`.git/config` to adjust which repositories it prefers. See
+[[the_man_page|git-annex]] for details.
+
+Also, note that you need full shell access for this to work --
+git-annex needs to be able to ssh in and run commands. Or at least,
+your shell needs to be able to run the [[git-annex-shell]] command.
diff --git a/doc/walkthrough/using_ssh_remotes/comment_10_98e97c4d7fbbcd449eddf683967a71d6._comment b/doc/walkthrough/using_ssh_remotes/comment_10_98e97c4d7fbbcd449eddf683967a71d6._comment
new file mode 100644
index 000000000..6cd9bb848
--- /dev/null
+++ b/doc/walkthrough/using_ssh_remotes/comment_10_98e97c4d7fbbcd449eddf683967a71d6._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawla7u6eLKNYZ09Z7xwBffqLaXquMQC07fU"
+ nickname="Matthias"
+ subject="Hint for Debian/Ubuntu"
+ date="2012-11-07T13:10:15Z"
+ content="""
+In Debian/Ubuntu the default .bashrc returns immediately if the shell is non-interactive. Make sure to setup the PATH such that it is updated with the location of git-annex-shell before this check! This just cost me an hour of debugging as I didn't notice the return statement early on...
+"""]]
diff --git a/doc/walkthrough/using_ssh_remotes/comment_11_f2775a151ed50caba27057bd9c38bae2._comment b/doc/walkthrough/using_ssh_remotes/comment_11_f2775a151ed50caba27057bd9c38bae2._comment
new file mode 100644
index 000000000..9768300dc
--- /dev/null
+++ b/doc/walkthrough/using_ssh_remotes/comment_11_f2775a151ed50caba27057bd9c38bae2._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawniXLhO9mLn-7EDfawdENZ2fQwlGy5w_oc"
+ nickname="Michał"
+ subject="unrecognized command"
+ date="2013-03-12T06:32:56Z"
+ content="""
+Thanks Matthias, I fought with this as well, this was the tip I needed to move on. I'm using the Linux standalone, and I had 2 issues getting everything to work without getting git-annex-shell errors.
+
+1. The autoinstalled wrapper could not be found, I had to comment the \"Ubuntu exit\" line and add the $HOME/.ssh to path to get rid of \"command not found\"
+2. Had to modify the wrapper by replacing the \"$SSH_ORIGINAL_COMMAND\" by \"$@\" to get rid of \"fatal: unrecognized command ''\"
+
+
+"""]]
diff --git a/doc/walkthrough/using_ssh_remotes/comment_12_a8bc6110128431ca2a8624ddc75ea364._comment b/doc/walkthrough/using_ssh_remotes/comment_12_a8bc6110128431ca2a8624ddc75ea364._comment
new file mode 100644
index 000000000..28c3aa92d
--- /dev/null
+++ b/doc/walkthrough/using_ssh_remotes/comment_12_a8bc6110128431ca2a8624ddc75ea364._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ nickname="joey"
+ subject="comment 12"
+ date="2013-03-12T11:15:11Z"
+ content="""
+@Michael, the standalone tarball is really meant to run the git-annex assistant. The first time \"git annex webapp\" is run, it will set up the ssh wrapper for you.
+
+I have updated the wrapper to work when ssh is not configured to force a key to run a command.
+"""]]
diff --git a/doc/walkthrough/using_ssh_remotes/comment_2_365db5820d96d5daa62c19fd76fcdf1e._comment b/doc/walkthrough/using_ssh_remotes/comment_2_365db5820d96d5daa62c19fd76fcdf1e._comment
new file mode 100644
index 000000000..8973978ad
--- /dev/null
+++ b/doc/walkthrough/using_ssh_remotes/comment_2_365db5820d96d5daa62c19fd76fcdf1e._comment
@@ -0,0 +1,13 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.81.112"
+ subject="comment 2"
+ date="2012-05-27T20:53:05Z"
+ content="""
+When `git annex get` does nothing, it's because it doesn't know a place to get the file from.
+
+This can happen if the `git-annex` branch has not propigated from the place where the file was added.
+For example, if on the laptop you had run `git pull ssh master`, that would only pull the master branch, not the git-annex branch.
+
+An easy way to ensure the git-annex branch is kept in sync is to run `git annex sync`
+"""]]
diff --git a/doc/walkthrough/using_ssh_remotes/comment_2_451fd0c6a25ee61ef137e8e5be0c286b._comment b/doc/walkthrough/using_ssh_remotes/comment_2_451fd0c6a25ee61ef137e8e5be0c286b._comment
new file mode 100644
index 000000000..212140196
--- /dev/null
+++ b/doc/walkthrough/using_ssh_remotes/comment_2_451fd0c6a25ee61ef137e8e5be0c286b._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkaT0B6s9jQuMzQUYRVBgWqtO7BhT_ZSaE"
+ nickname="Fernando Seabra"
+ subject="cannot get files"
+ date="2012-05-27T20:33:09Z"
+ content="""
+Hi,
+
+I could successfully clone my ssh repo's annex to my laptop, following these instructions.
+I'm also able to sync the repositories (laptop and ssh) when I commit new files in the ssh repo.
+
+However, every time I try to get files from the ssh repo (using 'git annex get some_file'), nothing happens.
+Do you know what can be happening?
+
+Thanks!
+"""]]
diff --git a/doc/walkthrough/using_ssh_remotes/comment_3_b2f15a46620385da26d5fe8f11ebfc1a._comment b/doc/walkthrough/using_ssh_remotes/comment_3_b2f15a46620385da26d5fe8f11ebfc1a._comment
new file mode 100644
index 000000000..75a133d84
--- /dev/null
+++ b/doc/walkthrough/using_ssh_remotes/comment_3_b2f15a46620385da26d5fe8f11ebfc1a._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkaT0B6s9jQuMzQUYRVBgWqtO7BhT_ZSaE"
+ nickname="Fernando Seabra"
+ subject="comment 3"
+ date="2012-05-27T21:13:50Z"
+ content="""
+Thanks for the quick replay!
+
+I already did 'git annex sync', but it didn't work. The steps were: 'git clone ssh...', then 'cd annex', then 'git annex init \"laptop\"'
+
+After that, I did a 'git annex sync', and tried to get the file, but nothing happens. That's why I found it weird.
+Any other thing that might have happened?
+
+Thanks again!
+"""]]
diff --git a/doc/walkthrough/using_ssh_remotes/comment_4_433ccc87fbb0a13e32d59d77f0b4e56c._comment b/doc/walkthrough/using_ssh_remotes/comment_4_433ccc87fbb0a13e32d59d77f0b4e56c._comment
new file mode 100644
index 000000000..3df03abc2
--- /dev/null
+++ b/doc/walkthrough/using_ssh_remotes/comment_4_433ccc87fbb0a13e32d59d77f0b4e56c._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.81.112"
+ subject="comment 4"
+ date="2012-05-27T21:33:11Z"
+ content="""
+Try running `git annex whereis` on the file and see where it says it is.
+"""]]
diff --git a/doc/walkthrough/using_ssh_remotes/comment_5_a9805c7965da0b88a1c9f7f207c450a1._comment b/doc/walkthrough/using_ssh_remotes/comment_5_a9805c7965da0b88a1c9f7f207c450a1._comment
new file mode 100644
index 000000000..703b89ebf
--- /dev/null
+++ b/doc/walkthrough/using_ssh_remotes/comment_5_a9805c7965da0b88a1c9f7f207c450a1._comment
@@ -0,0 +1,18 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkaT0B6s9jQuMzQUYRVBgWqtO7BhT_ZSaE"
+ nickname="Fernando Seabra"
+ subject="comment 5"
+ date="2012-05-27T21:42:56Z"
+ content="""
+Hi,
+
+I guess the problem is with git-annex-shell. I tried to do 'git annex get file --from name_ssh_repo', and I got the following:
+
+bash: git-annex-shell: command not found; failed; exit code 127
+
+The same thing happens if I try to do 'git annex whereis'
+
+git-annex-shell is indeed installed. How can I make my shell recognize this command?
+
+Thanks a lot!
+"""]]
diff --git a/doc/walkthrough/using_ssh_remotes/comment_6_9d5c12c056892b706cf100ea01866685._comment b/doc/walkthrough/using_ssh_remotes/comment_6_9d5c12c056892b706cf100ea01866685._comment
new file mode 100644
index 000000000..4d5961ca9
--- /dev/null
+++ b/doc/walkthrough/using_ssh_remotes/comment_6_9d5c12c056892b706cf100ea01866685._comment
@@ -0,0 +1,12 @@
+[[!comment format=mdwn
+ username="http://joeyh.name/"
+ ip="4.153.81.112"
+ subject="comment 6"
+ date="2012-05-27T22:08:50Z"
+ content="""
+git-annex-shell needs to be installed in the `PATH` on any host that will hold annexed files.
+
+If you installed with cabal, it might be `.cabal/bin/`. Whereever it was installed to is apparently not on the PATH that is set when you ssh into that host.
+
+
+"""]]
diff --git a/doc/walkthrough/using_ssh_remotes/comment_7_725e7dbb2d0a74a035127cb01ee0442c._comment b/doc/walkthrough/using_ssh_remotes/comment_7_725e7dbb2d0a74a035127cb01ee0442c._comment
new file mode 100644
index 000000000..700b170ad
--- /dev/null
+++ b/doc/walkthrough/using_ssh_remotes/comment_7_725e7dbb2d0a74a035127cb01ee0442c._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawkaT0B6s9jQuMzQUYRVBgWqtO7BhT_ZSaE"
+ nickname="Fernando Seabra"
+ subject="comment 7"
+ date="2012-05-27T23:35:17Z"
+ content="""
+Hi,
+
+It was already installed in PATH. In fact, I can call it from the command line, and it is recognized (e.g. calling 'git-annex-shell' gives me 'git-annex-shell: bad parameters'). However, every time I do a 'git annex whereis' or 'git annex get file --from repo', it gives me the following error:
+
+bash: git-annex-shell: command not found
+Command ssh [\"-S\",\"/Users/username/annex/.git/annex/ssh/username@example.edu\",\"-o\",\"ControlMaster=auto\",\"-o\",\"ControlPersist=yes\",\"username@example.edu\",\"git-annex-shell 'configlist' '/~/annex'\"] failed; exit code 127
+
+I tried to run this ssh command, but it gives me the same 'command not found' error. It seems that the problem is with the ssh repo?
+The ssh repo has a git-annex-shell working and installed in PATH.
+"""]]
diff --git a/doc/walkthrough/using_ssh_remotes/comment_8_8448e55026d2c2b50d8da41707686bea._comment b/doc/walkthrough/using_ssh_remotes/comment_8_8448e55026d2c2b50d8da41707686bea._comment
new file mode 100644
index 000000000..148f016db
--- /dev/null
+++ b/doc/walkthrough/using_ssh_remotes/comment_8_8448e55026d2c2b50d8da41707686bea._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmB-gCGEs--zfmvYU-__Hj2FbliUXgxMDs"
+ nickname="Jakub"
+ subject="Path problems"
+ date="2012-07-13T19:15:15Z"
+ content="""
+Hi,
+
+I have a same 'git-annex-shell command not found' problem as above. I've installed git annex via cabal into my ~/.haskell_bin directory. Then I've added this dir both to ~/.bashrc and ~/.zshrc. I can run git annex or 'git annex-shell' and everything is fine. My guess is that haskell is trying to spawn git-annex-shell with some current $PATH unaware shell like dash maybe?
+
+I've fixed this behavior by using a really ugly hack - I've symlinked ~/.haskell_bin/git-annex-shell to /usr/bin/git-annex-shell on all my machines and the problem is gone. Somehow haskell (or whatever is trying to call git-annex-shell) is unaware of path modifications from .bashrc/.zshrc
+
+Here is the path modification I've used:
+
+export PATH=~/.haskell_bin:$PATH
+"""]]
diff --git a/doc/walkthrough/using_ssh_remotes/comment_9_61833299a9878f23ac57598fa6da8839._comment b/doc/walkthrough/using_ssh_remotes/comment_9_61833299a9878f23ac57598fa6da8839._comment
new file mode 100644
index 000000000..ddb96da36
--- /dev/null
+++ b/doc/walkthrough/using_ssh_remotes/comment_9_61833299a9878f23ac57598fa6da8839._comment
@@ -0,0 +1,23 @@
+[[!comment format=mdwn
+ username="https://www.google.com/accounts/o8/id?id=AItOawmB-gCGEs--zfmvYU-__Hj2FbliUXgxMDs"
+ nickname="Jakub"
+ subject="Fixed"
+ date="2012-07-13T19:27:46Z"
+ content="""
+Found the problem:
+
+One should never use ~ in such path:
+
+WRONG export PATH=~/somedir:$PATH
+
+Instead one should use $HOME:
+
+GOOD export PATH=$HOME/somedir:$PATH
+
+Can I surpress the message that shell failed with status 255 when a repo is unavailible? I've got two repos pointing to one machine - either via vpn or local lan and I keep getting erros if one is unavailible:
+
+ssh: connect to host 10.9.0.1 port 39882: No route to host
+Command ssh [\"-S\",\"/home/pielgrzym/annex/.git/annex/ssh/nas\",\"-o\",\"ControlMaster=auto\",\"-o\",\"ControlPersist=yes\",\"nas\",\"git-annex-shell 'configlist' '/~/annex'\"] failed; exit code 255
+
+
+"""]]
diff --git a/doc/walkthrough/using_tags_and_branches.mdwn b/doc/walkthrough/using_tags_and_branches.mdwn
new file mode 100644
index 000000000..b147ea466
--- /dev/null
+++ b/doc/walkthrough/using_tags_and_branches.mdwn
@@ -0,0 +1,14 @@
+Like git, git-annex hangs on to every old version of a file (by default),
+so you can make tags and branches, and can check them out later to look at
+the old files.
+
+ # git tag 1.0
+ # rm -f my_cool_big_file
+ # git commit -m deleted
+ # git checkout 1.0
+ # cat my_cool_big_file
+ yay! old version still here
+
+Of course, when you `git checkout` an old branch, some old versions of
+files may not be locally available, and may be stored in some other
+repository. You can use `git annex get` to get them as usual.
diff --git a/ghci b/ghci
new file mode 100755
index 000000000..206bbbc7a
--- /dev/null
+++ b/ghci
@@ -0,0 +1,4 @@
+#!/bin/sh
+# ghci using objects built by cabal
+make dist/caballog
+$(grep 'ghc --make' dist/caballog | head -n 1 | perl -pe 's/--make/--interactive/; s/.\/[^\.\s]+.hs//; s/-package-id [^\s]+//g; s/-hide-all-packages//; s/-threaded//; s/-O//') $@
diff --git a/git-annex.cabal b/git-annex.cabal
new file mode 100644
index 000000000..da78c7def
--- /dev/null
+++ b/git-annex.cabal
@@ -0,0 +1,201 @@
+Name: git-annex
+Version: 5.20131120
+Cabal-Version: >= 1.8
+License: GPL-3
+Maintainer: Joey Hess <joey@kitenet.net>
+Author: Joey Hess
+Stability: Stable
+Copyright: 2010-2013 Joey Hess
+License-File: COPYRIGHT
+Homepage: http://git-annex.branchable.com/
+Build-type: Custom
+Category: Utility
+Synopsis: manage files with git, without checking their contents into git
+Description:
+ git-annex allows managing files with git, without checking the file
+ contents into git. While that may seem paradoxical, it is useful when
+ dealing with files larger than git can currently easily handle, whether due
+ to limitations in memory, time, or disk space.
+ .
+ Even without file content tracking, being able to manage files with git,
+ move files around and delete files with versioned directory trees, and use
+ branches and distributed clones, are all very handy reasons to use git. And
+ annexed files can co-exist in the same git repository with regularly
+ versioned files, which is convenient for maintaining documents, Makefiles,
+ etc that are associated with annexed files but that benefit from full
+ revision control.
+
+Flag S3
+ Description: Enable S3 support
+
+Flag WebDAV
+ Description: Enable WebDAV support
+
+Flag Inotify
+ Description: Enable inotify support
+
+Flag Dbus
+ Description: Enable dbus support
+
+Flag Assistant
+ Description: Enable git-annex assistant and watch command
+
+Flag Webapp
+ Description: Enable git-annex webapp
+
+Flag Pairing
+ Description: Enable pairing
+
+Flag XMPP
+ Description: Enable notifications using XMPP
+
+Flag DNS
+ Description: Enable the haskell DNS library for DNS lookup
+
+Flag Production
+ Description: Enable production build (slower build; faster binary)
+
+Flag Android
+ Description: Cross building for Android
+ Default: False
+
+Flag AndroidSplice
+ Description: Building to get TH splices for Android
+ Default: False
+
+Flag TestSuite
+ Description: Embed the test suite into git-annex
+
+Flag TDFA
+ Description: Use regex-tdfa for wildcards
+
+Flag Feed
+ Description: Enable podcast feed support
+
+Flag Quvi
+ Description: Enable use of quvi to download videos
+
+Flag CryptoHash
+ Description: Enable use of cryptohash for checksumming
+
+Flag EKG
+ Description: Enable use of EKG to monitor git-annex as it runs (at http://localhost:4242/)
+ Default: False
+
+Executable git-annex
+ Main-Is: git-annex.hs
+ Build-Depends: MissingH, hslogger, directory, filepath,
+ containers, utf8-string, network (>= 2.0), mtl (>= 2),
+ bytestring, old-locale, time, HTTP,
+ extensible-exceptions, dataenc, SHA, process, json,
+ base (>= 4.5 && < 4.9), monad-control, MonadCatchIO-transformers,
+ IfElse, text, QuickCheck >= 2.1, bloomfilter, edit-distance, process,
+ SafeSemaphore, uuid, random, dlist, unix-compat, async
+ -- Need to list these because they're generated from .hsc files.
+ Other-Modules: Utility.Touch Utility.Mounts
+ Include-Dirs: Utility
+ C-Sources: Utility/libdiskfree.c Utility/libmounts.c
+ CC-Options: -Wall
+ GHC-Options: -Wall
+ CPP-Options: -DWITH_CLIBS
+ Extensions: PackageImports
+ -- Some things don't work with the non-threaded RTS.
+ GHC-Options: -threaded
+
+ if flag(Production)
+ GHC-Options: -O2
+
+ if (! os(windows))
+ Build-Depends: unix
+
+ if flag(TestSuite)
+ Build-Depends: tasty, tasty-hunit, tasty-quickcheck
+ CPP-Options: -DWITH_TESTSUITE
+
+ if flag(TDFA)
+ Build-Depends: regex-tdfa
+ CPP-Options: -DWITH_TDFA
+
+ if flag(CryptoHash)
+ Build-Depends: cryptohash (>= 0.10.0)
+ CPP-Options: -DWITH_CRYPTOHASH
+
+ if flag(S3)
+ Build-Depends: hS3
+ CPP-Options: -DWITH_S3
+
+ if flag(WebDAV)
+ Build-Depends: DAV (>= 0.3), http-conduit, xml-conduit, http-types
+ CPP-Options: -DWITH_WEBDAV
+
+ if flag(Assistant) && ! os(solaris)
+ Build-Depends: stm (>= 2.3)
+ CPP-Options: -DWITH_ASSISTANT
+
+ if flag(Assistant)
+ if os(linux) && flag(Inotify)
+ Build-Depends: hinotify
+ CPP-Options: -DWITH_INOTIFY
+ else
+ if os(darwin)
+ Build-Depends: hfsevents
+ CPP-Options: -DWITH_FSEVENTS
+ else
+ if os(windows)
+ Build-Depends: Win32-notify
+ CPP-Options: -DWITH_WIN32NOTIFY
+ else
+ if (! os(solaris) && ! os(linux))
+ if flag(Android)
+ Build-Depends: hinotify
+ CPP-Options: -DWITH_INOTIFY
+ else
+ CPP-Options: -DWITH_KQUEUE
+ C-Sources: Utility/libkqueue.c
+
+ if os(linux) && flag(Dbus)
+ Build-Depends: dbus (>= 0.10.3)
+ CPP-Options: -DWITH_DBUS
+
+ if flag(Android)
+ Build-Depends: data-endian
+ CPP-Options: -D__ANDROID__ -DANDROID_SPLICES
+ if flag(AndroidSplice)
+ CPP-Options: -DANDROID_SPLICES
+
+ if flag(Webapp) && (! os(windows))
+ Build-Depends:
+ yesod, yesod-default, yesod-static, yesod-form, yesod-core,
+ case-insensitive, http-types, transformers, wai, wai-logger, warp,
+ blaze-builder, crypto-api, hamlet, clientsession,
+ template-haskell, data-default, aeson
+ CPP-Options: -DWITH_WEBAPP
+
+ if flag(Pairing)
+ Build-Depends: network-multicast, network-info
+ CPP-Options: -DWITH_PAIRING
+
+ if flag(XMPP) && (! os(windows))
+ Build-Depends: network-protocol-xmpp, gnutls (>= 0.1.4), xml-types
+ CPP-Options: -DWITH_XMPP
+
+ if flag(DNS)
+ Build-Depends: dns
+ CPP-Options: -DWITH_DNS
+
+ if flag(Feed)
+ Build-Depends: feed
+ CPP-Options: -DWITH_FEED
+
+ if flag(Quvi)
+ Build-Depends: aeson
+ CPP-Options: -DWITH_QUVI
+
+ if flag(EKG)
+ Build-Depends: ekg
+ GHC-Options: -with-rtsopts=-T
+ CPP-Options: -DWITH_EKG
+
+source-repository head
+ type: git
+ location: git://git-annex.branchable.com/
diff --git a/git-annex.hs b/git-annex.hs
new file mode 100644
index 000000000..0f45f53eb
--- /dev/null
+++ b/git-annex.hs
@@ -0,0 +1,34 @@
+{- git-annex main program stub
+ -
+ - Copyright 2010-2013 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+{-# LANGUAGE CPP #-}
+
+import System.Environment
+import System.FilePath
+
+import qualified GitAnnex
+import qualified GitAnnexShell
+#ifdef WITH_TESTSUITE
+import qualified Test
+#endif
+
+main :: IO ()
+main = run =<< getProgName
+ where
+ run n
+ | isshell n = go GitAnnexShell.run
+ | otherwise = go GitAnnex.run
+ isshell n = takeFileName n == "git-annex-shell"
+ go a = do
+ ps <- getArgs
+#ifdef WITH_TESTSUITE
+ if ps == ["test"]
+ then Test.main
+ else a ps
+#else
+ a ps
+#endif
diff --git a/git-union-merge.hs b/git-union-merge.hs
new file mode 100644
index 000000000..0e4cd644c
--- /dev/null
+++ b/git-union-merge.hs
@@ -0,0 +1,48 @@
+{- git-union-merge program
+ -
+ - Copyright 2011 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+import System.Environment
+
+import Common
+import qualified Git.UnionMerge
+import qualified Git.Config
+import qualified Git.CurrentRepo
+import qualified Git.Branch
+import qualified Git.Index
+import qualified Git
+
+header :: String
+header = "Usage: git-union-merge ref ref newref"
+
+usage :: IO a
+usage = error $ "bad parameters\n\n" ++ header
+
+tmpIndex :: Git.Repo -> FilePath
+tmpIndex g = Git.localGitDir g </> "index.git-union-merge"
+
+setup :: Git.Repo -> IO ()
+setup = cleanup -- idempotency
+
+cleanup :: Git.Repo -> IO ()
+cleanup g = nukeFile $ tmpIndex g
+
+parseArgs :: IO [String]
+parseArgs = do
+ args <- getArgs
+ if length args /= 3
+ then usage
+ else return args
+
+main :: IO ()
+main = do
+ [aref, bref, newref] <- map Git.Ref <$> parseArgs
+ g <- Git.Config.read =<< Git.CurrentRepo.get
+ _ <- Git.Index.override $ tmpIndex g
+ setup g
+ Git.UnionMerge.merge aref bref g
+ _ <- Git.Branch.commit "union merge" newref [aref, bref] g
+ cleanup g
diff --git a/standalone/android/Makefile b/standalone/android/Makefile
new file mode 100644
index 000000000..f5cd67b26
--- /dev/null
+++ b/standalone/android/Makefile
@@ -0,0 +1,167 @@
+# Cross-compiles utilities needed for git-annex on Android,
+# and builds the Android app.
+
+# Add Android cross-compiler to PATH (as installed by ghc-android)
+ANDROID_CROSS_COMPILER?=$(HOME)/.ghc/$(shell cat abiversion)/bin
+PATH:=$(ANDROID_CROSS_COMPILER):$(PATH)
+
+# Paths to the Android SDK and NDK.
+export ANDROID_SDK_ROOT?=$(HOME)/.android/adt-bundle-linux-x86/sdk
+export ANDROID_NDK_ROOT?=$(HOME)/.android/android-ndk
+
+# Where to store the source tree used to build utilities. This
+# directory will be created by `make source`.
+GIT_ANNEX_ANDROID_SOURCETREE?=$(HOME)/.android/git-annex-sourcetree
+
+GITTREE=$(GIT_ANNEX_ANDROID_SOURCETREE)/git/installed-tree
+
+VER=$(shell perl -e '$$_=<>;print m/\((.*?)\)/'<../../CHANGELOG)
+
+build: start
+ if [ ! -e "$(GIT_ANNEX_ANDROID_SOURCETREE)" ]; then $(MAKE) source; fi
+ $(MAKE) $(GIT_ANNEX_ANDROID_SOURCETREE)/openssl/build-stamp
+ $(MAKE) $(GIT_ANNEX_ANDROID_SOURCETREE)/openssh/build-stamp
+ $(MAKE) $(GIT_ANNEX_ANDROID_SOURCETREE)/busybox/build-stamp
+ $(MAKE) $(GIT_ANNEX_ANDROID_SOURCETREE)/rsync/build-stamp
+ $(MAKE) $(GIT_ANNEX_ANDROID_SOURCETREE)/gnupg/build-stamp
+ $(MAKE) $(GIT_ANNEX_ANDROID_SOURCETREE)/git/build-stamp
+ $(MAKE) $(GIT_ANNEX_ANDROID_SOURCETREE)/term/build-stamp
+
+ perl -i -pe 's/(android:versionName=)"[^"]+"/$$1"'$(VER)'"/' $(GIT_ANNEX_ANDROID_SOURCETREE)/term/AndroidManifest.xml
+
+ # Debug build because it does not need signing keys.
+ cd $(GIT_ANNEX_ANDROID_SOURCETREE)/term && tools/build-debug
+
+ # Install executables as pseudo-libraries so they will be
+ # unpacked from the .apk.
+ mkdir -p $(GIT_ANNEX_ANDROID_SOURCETREE)/term/libs/armeabi
+ cp $(GIT_ANNEX_ANDROID_SOURCETREE)/busybox/busybox $(GIT_ANNEX_ANDROID_SOURCETREE)/term/libs/armeabi/lib.busybox.so
+ cp $(GIT_ANNEX_ANDROID_SOURCETREE)/openssh/ssh $(GIT_ANNEX_ANDROID_SOURCETREE)/term/libs/armeabi/lib.ssh.so
+ cp $(GIT_ANNEX_ANDROID_SOURCETREE)/openssh/ssh-keygen $(GIT_ANNEX_ANDROID_SOURCETREE)/term/libs/armeabi/lib.ssh-keygen.so
+ cp $(GIT_ANNEX_ANDROID_SOURCETREE)/rsync/rsync $(GIT_ANNEX_ANDROID_SOURCETREE)/term/libs/armeabi/lib.rsync.so
+ cp $(GIT_ANNEX_ANDROID_SOURCETREE)/gnupg/g10/gpg $(GIT_ANNEX_ANDROID_SOURCETREE)/term/libs/armeabi/lib.gpg.so
+ cp $(GIT_ANNEX_ANDROID_SOURCETREE)/git/git $(GIT_ANNEX_ANDROID_SOURCETREE)/term/libs/armeabi/lib.git.so
+ cp $(GIT_ANNEX_ANDROID_SOURCETREE)/git/git-shell $(GIT_ANNEX_ANDROID_SOURCETREE)/term/libs/armeabi/lib.git-shell.so
+ cp $(GIT_ANNEX_ANDROID_SOURCETREE)/git/git-upload-pack $(GIT_ANNEX_ANDROID_SOURCETREE)/term/libs/armeabi/lib.git-upload-pack.so
+ arm-linux-androideabi-strip --strip-unneeded --remove-section=.comment --remove-section=.note $(GIT_ANNEX_ANDROID_SOURCETREE)/term/libs/armeabi/*
+ cp runshell $(GIT_ANNEX_ANDROID_SOURCETREE)/term/libs/armeabi/lib.runshell.so
+ cp start $(GIT_ANNEX_ANDROID_SOURCETREE)/term/libs/armeabi/lib.start.so
+
+ # remove git stuff we don't need to save space
+ rm -rf $(GITTREE)/bin/git-cvsserver \
+ $(GITTREE)/libexec/git-core/git-daemon \
+ $(GITTREE)/libexec/git-core/git-show-index \
+ $(GITTREE)/libexec/git-core/mergetools \
+ $(GITTREE)/libexec/git-core/git-credential-* \
+ $(GITTREE)/libexec/git-core/git-cvsserver \
+ $(GITTREE)/libexec/git-core/git-cvsimport \
+ $(GITTREE)/libexec/git-core/git-fast-import \
+ $(GITTREE)/libexec/git-core/git-http-backend \
+ $(GITTREE)/libexec/git-core/git-imap-send \
+ $(GITTREE)/libexec/git-core/git-instaweb \
+ $(GITTREE)/libexec/git-core/git-p4 \
+ $(GITTREE)/libexec/git-core/git-remote-test* \
+ $(GITTREE)/libexec/git-core/git-submodule \
+ $(GITTREE)/libexec/git-core/git-svn \
+ $(GITTREE)/libexec/git-core/git-web--browse
+ # Most of git is in one multicall binary, but a few important
+ # commands are still shell scripts. Those are put into
+ # a tarball, along with a list of all the links that should be
+ # set up.
+ cd $(GITTREE) && mkdir -p links
+ cd $(GITTREE) && find -samefile bin/git -not -wholename ./bin/git > links/git
+ cd $(GITTREE) && find -samefile bin/git-shell -not -wholename ./bin/git-shell > links/git-shell
+ cd $(GITTREE) && find -samefile bin/git-upload-pack -not -wholename ./bin/git-upload-pack > links/git-upload-pack
+ cd $(GITTREE) && find -type f -not -samefile bin/git -not -samefile bin/git-shell -not -samefile bin/git-upload-pack|tar czf ../git.tar.gz -T -
+ cp $(GIT_ANNEX_ANDROID_SOURCETREE)/git/git.tar.gz $(GIT_ANNEX_ANDROID_SOURCETREE)/term/libs/armeabi/lib.git.tar.gz.so
+
+ git rev-parse HEAD > $(GIT_ANNEX_ANDROID_SOURCETREE)/term/libs/armeabi/lib.version.so
+
+ mkdir -p ../../tmp/4.0 ../../tmp/4.3
+
+ cp ../../tmp/androidtree/dist/build/git-annex/4.3/git-annex $(GIT_ANNEX_ANDROID_SOURCETREE)/term/libs/armeabi/lib.git-annex.so
+ arm-linux-androideabi-strip --strip-unneeded --remove-section=.comment --remove-section=.note $(GIT_ANNEX_ANDROID_SOURCETREE)/term/libs/armeabi/lib.git-annex.so
+ cd $(GIT_ANNEX_ANDROID_SOURCETREE)/term && ant debug
+ cp $(GIT_ANNEX_ANDROID_SOURCETREE)/term/bin/Term-debug.apk ../../tmp/4.3/git-annex.apk
+
+ cp ../../tmp/androidtree/dist/build/git-annex/4.0/git-annex $(GIT_ANNEX_ANDROID_SOURCETREE)/term/libs/armeabi/lib.git-annex.so
+ arm-linux-androideabi-strip --strip-unneeded --remove-section=.comment --remove-section=.note $(GIT_ANNEX_ANDROID_SOURCETREE)/term/libs/armeabi/lib.git-annex.so
+ cd $(GIT_ANNEX_ANDROID_SOURCETREE)/term && ant debug
+ cp $(GIT_ANNEX_ANDROID_SOURCETREE)/term/bin/Term-debug.apk ../../tmp/4.0/git-annex.apk
+
+$(GIT_ANNEX_ANDROID_SOURCETREE)/openssl/build-stamp:
+ cd $(GIT_ANNEX_ANDROID_SOURCETREE)/openssl && CC=$$(which cc) ./Configure android
+ cd $(GIT_ANNEX_ANDROID_SOURCETREE)/openssl && $(MAKE)
+ touch $@
+
+$(GIT_ANNEX_ANDROID_SOURCETREE)/openssh/build-stamp: openssh.patch openssh.config.h
+ # This is a known-good version that the patch works with.
+ # TODO: Upgrade
+ cd $(GIT_ANNEX_ANDROID_SOURCETREE)/openssh && git reset --hard 0a8617ed5af2f0248d0e9648e26b224e16ada742
+ cd $(GIT_ANNEX_ANDROID_SOURCETREE)/openssh && ./configure --host=arm-linux-androideabi --with-ssl-dir=../openssl --without-openssl-header-check
+ cat openssh.patch | (cd $(GIT_ANNEX_ANDROID_SOURCETREE)/openssh && patch -p1)
+ cp openssh.config.h $(GIT_ANNEX_ANDROID_SOURCETREE)/openssh/config.h
+ cd $(GIT_ANNEX_ANDROID_SOURCETREE)/openssh && sed -i -e 's/getrrsetbyname.o //' openbsd-compat/Makefile
+ cd $(GIT_ANNEX_ANDROID_SOURCETREE)/openssh && sed -i -e 's/auth-passwd.o //' Makefile
+ cd $(GIT_ANNEX_ANDROID_SOURCETREE)/openssh && $(MAKE) ssh ssh-keygen
+ touch $@
+
+$(GIT_ANNEX_ANDROID_SOURCETREE)/busybox/build-stamp: busybox_config
+ cp busybox_config $(GIT_ANNEX_ANDROID_SOURCETREE)/busybox/.config
+ cd $(GIT_ANNEX_ANDROID_SOURCETREE)/busybox && yes '' | $(MAKE) oldconfig
+ cd $(GIT_ANNEX_ANDROID_SOURCETREE)/busybox && $(MAKE)
+ touch $@
+
+$(GIT_ANNEX_ANDROID_SOURCETREE)/git/build-stamp:
+ cd $(GIT_ANNEX_ANDROID_SOURCETREE)/git && $(MAKE) install NO_OPENSSL=1 NO_GETTEXT=1 NO_GECOS_IN_PWENT=1 NO_GETPASS=1 NO_NSEC=1 NO_MKDTEMP=1 NO_PTHREADS=1 NO_PERL=1 NO_CURL=1 NO_EXPAT=1 NO_TCLTK=1 NO_ICONV=1 prefix= DESTDIR=installed-tree
+ touch $@
+
+$(GIT_ANNEX_ANDROID_SOURCETREE)/rsync/build-stamp: rsync.patch
+ # This is a known-good version that the patch works with.
+ cat rsync.patch | (cd $(GIT_ANNEX_ANDROID_SOURCETREE)/rsync && git reset --hard eec26089b1c7bdbb260674480ffe6ece257bca63 && git am)
+ cp $(GIT_ANNEX_ANDROID_SOURCETREE)/automake/lib/config.sub $(GIT_ANNEX_ANDROID_SOURCETREE)/automake/lib/config.guess $(GIT_ANNEX_ANDROID_SOURCETREE)/rsync/
+ cd $(GIT_ANNEX_ANDROID_SOURCETREE)/rsync && ./configure --host=arm-linux-androideabi --disable-locale --disable-iconv-open --disable-iconv --disable-acl-support --disable-xattr-support
+ cd $(GIT_ANNEX_ANDROID_SOURCETREE)/rsync && $(MAKE)
+ touch $@
+
+$(GIT_ANNEX_ANDROID_SOURCETREE)/gnupg/build-stamp:
+ cd $(GIT_ANNEX_ANDROID_SOURCETREE)/gnupg && git checkout gnupg-1.4.15
+ cd $(GIT_ANNEX_ANDROID_SOURCETREE)/gnupg && ./autogen.sh
+ cd $(GIT_ANNEX_ANDROID_SOURCETREE)/gnupg && ./configure --host=arm-linux-androideabi --disable-gnupg-iconv --disable-card-support --disable-agent-support --disable-photo-viewers --disable-keyserver-helpers --disable-nls
+ cd $(GIT_ANNEX_ANDROID_SOURCETREE)/gnupg; $(MAKE) || true # expected failure in doc build
+ touch $@
+
+$(GIT_ANNEX_ANDROID_SOURCETREE)/term/build-stamp: term.patch icons
+ # This is a known-good version that the patch works with.
+ cd $(GIT_ANNEX_ANDROID_SOURCETREE)/term && git reset --hard 3d34b3c42295c215b62e70f3ee696dd664ba08ce
+ cat term.patch | (cd $(GIT_ANNEX_ANDROID_SOURCETREE)/term && patch -p1)
+ (cd icons && tar c .) | (cd $(GIT_ANNEX_ANDROID_SOURCETREE)/term/res && tar x)
+ # This renaming has a purpose. It makes the path to the app's
+ # /data directory shorter, which makes ssh connection caching
+ # sockets placed there have more space for their filenames.
+ # Also, it avoids overlap with the Android Terminal Emulator
+ # app, if it's also installed.
+ cd $(GIT_ANNEX_ANDROID_SOURCETREE)/term && find -name .git -prune -o -type f -print0 | xargs -0 perl -pi -e 's/jackpal/ga/g'
+ cd $(GIT_ANNEX_ANDROID_SOURCETREE)/term && perl -pi -e 's/Terminal Emulator/Git Annex/g' res/*/strings.xml
+ cd $(GIT_ANNEX_ANDROID_SOURCETREE)/term && echo y | tools/update.sh
+ touch $@
+
+source: $(GIT_ANNEX_ANDROID_SOURCETREE)
+
+$(GIT_ANNEX_ANDROID_SOURCETREE):
+ mkdir -p $(GIT_ANNEX_ANDROID_SOURCETREE)
+ git clone git://git.savannah.gnu.org/automake.git $(GIT_ANNEX_ANDROID_SOURCETREE)/automake
+ git clone git://git.debian.org/git/d-i/busybox $(GIT_ANNEX_ANDROID_SOURCETREE)/busybox
+ git clone git://git.kernel.org/pub/scm/git/git.git $(GIT_ANNEX_ANDROID_SOURCETREE)/git
+ git clone git://git.samba.org/rsync.git $(GIT_ANNEX_ANDROID_SOURCETREE)/rsync
+ git clone git://git.gnupg.org/gnupg.git $(GIT_ANNEX_ANDROID_SOURCETREE)/gnupg
+ git clone git://git.openssl.org/openssl $(GIT_ANNEX_ANDROID_SOURCETREE)/openssl
+ git clone git://github.com/CyanogenMod/android_external_openssh.git $(GIT_ANNEX_ANDROID_SOURCETREE)/openssh
+ git clone git://github.com/jackpal/Android-Terminal-Emulator.git $(GIT_ANNEX_ANDROID_SOURCETREE)/term
+
+clean:
+ rm -rf $(GITTREE)
+ rm -f start
+
+reallyclean: clean
+ rm -rf $(GIT_ANNEX_ANDROID_SOURCETREE)
diff --git a/standalone/android/abiversion b/standalone/android/abiversion
new file mode 100644
index 000000000..4cc4c14cd
--- /dev/null
+++ b/standalone/android/abiversion
@@ -0,0 +1 @@
+android-14/arm-linux-androideabi-4.8
diff --git a/standalone/android/buildchroot b/standalone/android/buildchroot
new file mode 100755
index 000000000..44337eb0c
--- /dev/null
+++ b/standalone/android/buildchroot
@@ -0,0 +1,27 @@
+#!/bin/sh
+set -e
+if [ "$(whoami)" != root ]; then
+ echo "Must run this as root!" >&2
+ exit 1
+fi
+
+debootstrap --arch=i386 stable debian-stable-android
+cp $0-inchroot debian-stable-android/tmp
+cp $0-inchroot-asuser debian-stable-android/tmp
+cp $(dirname $0)/abiversion debian-stable-android/tmp
+
+# Don't use these vars in the chroot.
+unset TMP
+unset TEMP
+unset TMPDIR
+unset TEMPDIR
+
+chroot debian-stable-android "tmp/$(basename $0)-inchroot"
+
+echo
+echo
+echo "debian-stable-android is set up, with a user androidbuilder"
+echo "your next step is probably to check out git-annex in this chroot"
+echo "and run standalone/android/install-haskell-packages"
+echo
+echo
diff --git a/standalone/android/buildchroot-inchroot b/standalone/android/buildchroot-inchroot
new file mode 100755
index 000000000..70deea0ab
--- /dev/null
+++ b/standalone/android/buildchroot-inchroot
@@ -0,0 +1,25 @@
+#!/bin/sh
+# Runs inside the chroot set up by buildchroot
+set -e
+if [ "$(whoami)" != root ]; then
+ echo "Must run this as root!" >&2
+ exit 1
+fi
+
+# java needs this mounted to work
+mount -t proc proc /proc
+
+echo "deb-src http://ftp.us.debian.org/debian stable main" >> /etc/apt/sources.list
+apt-get update
+apt-get -y install build-essential ghc git libncurses5-dev cabal-install
+apt-get -y install llvm-3.0 # not 3.1; buggy on arm. 3.2 is ok too
+apt-get -y install ca-certificates curl file m4 autoconf zlib1g-dev
+apt-get -y install libgnutls-dev libxml2-dev libgsasl7-dev pkg-config c2hs
+apt-get -y install ant default-jdk rsync wget gnupg lsof
+apt-get -y install gettext unzip python
+apt-get clean
+wget http://snapshot.debian.org/archive/debian/20130903T155330Z/pool/main/a/automake-1.14/automake_1.14-1_all.deb
+dpkg -i automake*.deb
+rm *.deb
+useradd androidbuilder --create-home
+su androidbuilder -c $0-asuser
diff --git a/standalone/android/buildchroot-inchroot-asuser b/standalone/android/buildchroot-inchroot-asuser
new file mode 100755
index 000000000..710e76e46
--- /dev/null
+++ b/standalone/android/buildchroot-inchroot-asuser
@@ -0,0 +1,38 @@
+#!/bin/sh
+# Runs inside the chroot set up by buildchroot, as the user it creates
+set -e
+
+cd
+rm -rf .ghc .cabal
+cabal update
+cabal install happy alex --bindir=$HOME/bin
+PATH=$HOME/bin:$PATH
+export PATH
+mkdir -p .android
+cd .android
+git clone https://github.com/joeyh/ghc-android
+cd ghc-android
+git checkout stable-ghc-snapshot
+./build
+
+# This saves 2 gb, and the same sources are in build-*/ghc
+rm -rf stage0
+
+# Set up android SDK where the git-annex android Makefile
+# expects to find it.
+cd ..
+ln -s ghc-android/android-ndk-* android-ndk
+wget http://dl.google.com/android/adt/adt-bundle-linux-x86-20130917.zip
+unzip adt*.zip
+rm adt*.zip
+mv adt-bundle-linux-x86-* adt-bundle-linux-x86
+rm -rf adt-bundle-linux-x86/eclipse
+
+# The git-annex android Makefile needs this cc symlink.
+ln -s arm-linux-androideabi-gcc $HOME/.ghc/$(cat /tmp/abiversion)/bin/cc
+
+cd
+git clone git://git-annex.branchable.com/ git-annex
+
+git config --global user.email androidbuilder@example.com
+git config --global user.name androidbuilder
diff --git a/standalone/android/busybox_config b/standalone/android/busybox_config
new file mode 100644
index 000000000..28ea880d9
--- /dev/null
+++ b/standalone/android/busybox_config
@@ -0,0 +1,997 @@
+# Run "make android2_defconfig", then "make".
+#
+# Tested with the standalone toolchain from ndk r6:
+# android-ndk-r6/build/tools/make-standalone-toolchain.sh --platform=android-8
+#
+CONFIG_HAVE_DOT_CONFIG=y
+
+#
+# Busybox Settings
+#
+
+#
+# General Configuration
+#
+# CONFIG_DESKTOP is not set
+# CONFIG_EXTRA_COMPAT is not set
+# CONFIG_INCLUDE_SUSv2 is not set
+# CONFIG_USE_PORTABLE_CODE is not set
+CONFIG_PLATFORM_LINUX=y
+CONFIG_FEATURE_BUFFERS_USE_MALLOC=y
+# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set
+# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set
+# CONFIG_SHOW_USAGE is not set
+# CONFIG_FEATURE_VERBOSE_USAGE is not set
+# CONFIG_FEATURE_COMPRESS_USAGE is not set
+CONFIG_FEATURE_INSTALLER=y
+# CONFIG_INSTALL_NO_USR is not set
+# CONFIG_LOCALE_SUPPORT is not set
+# CONFIG_UNICODE_SUPPORT is not set
+# CONFIG_UNICODE_USING_LOCALE is not set
+# CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set
+CONFIG_SUBST_WCHAR=0
+CONFIG_LAST_SUPPORTED_WCHAR=0
+# CONFIG_UNICODE_COMBINING_WCHARS is not set
+# CONFIG_UNICODE_WIDE_WCHARS is not set
+# CONFIG_UNICODE_BIDI_SUPPORT is not set
+# CONFIG_UNICODE_NEUTRAL_TABLE is not set
+# CONFIG_UNICODE_PRESERVE_BROKEN is not set
+# CONFIG_LONG_OPTS is not set
+# CONFIG_FEATURE_DEVPTS is not set
+# CONFIG_FEATURE_CLEAN_UP is not set
+# CONFIG_FEATURE_UTMP is not set
+# CONFIG_FEATURE_WTMP is not set
+# CONFIG_FEATURE_PIDFILE is not set
+# CONFIG_FEATURE_SUID is not set
+# CONFIG_FEATURE_SUID_CONFIG is not set
+# CONFIG_FEATURE_SUID_CONFIG_QUIET is not set
+# CONFIG_SELINUX is not set
+# CONFIG_FEATURE_PREFER_APPLETS is not set
+CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe"
+CONFIG_FEATURE_SYSLOG=y
+# CONFIG_FEATURE_HAVE_RPC is not set
+
+#
+# Build Options
+#
+# CONFIG_STATIC is not set
+# CONFIG_PIE is not set
+# CONFIG_NOMMU is not set
+# CONFIG_BUILD_LIBBUSYBOX is not set
+# CONFIG_FEATURE_INDIVIDUAL is not set
+# CONFIG_FEATURE_SHARED_BUSYBOX is not set
+# CONFIG_LFS is not set
+CONFIG_CROSS_COMPILER_PREFIX="arm-linux-androideabi-"
+CONFIG_EXTRA_CFLAGS=""
+
+#
+# Debugging Options
+#
+# CONFIG_DEBUG is not set
+# CONFIG_DEBUG_PESSIMIZE is not set
+# CONFIG_WERROR is not set
+CONFIG_NO_DEBUG_LIB=y
+# CONFIG_DMALLOC is not set
+# CONFIG_EFENCE is not set
+
+#
+# Installation Options ("make install" behavior)
+#
+CONFIG_INSTALL_APPLET_SYMLINKS=y
+# CONFIG_INSTALL_APPLET_HARDLINKS is not set
+# CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS is not set
+# CONFIG_INSTALL_APPLET_DONT is not set
+# CONFIG_INSTALL_SH_APPLET_SYMLINK is not set
+# CONFIG_INSTALL_SH_APPLET_HARDLINK is not set
+# CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER is not set
+CONFIG_PREFIX="./_install"
+
+#
+# Busybox Library Tuning
+#
+# CONFIG_FEATURE_SYSTEMD is not set
+# CONFIG_FEATURE_RTMINMAX is not set
+CONFIG_PASSWORD_MINLEN=6
+CONFIG_MD5_SMALL=1
+# CONFIG_FEATURE_FAST_TOP is not set
+# CONFIG_FEATURE_ETC_NETWORKS is not set
+CONFIG_FEATURE_USE_TERMIOS=y
+# CONFIG_FEATURE_EDITING is not set
+CONFIG_FEATURE_EDITING_MAX_LEN=0
+# CONFIG_FEATURE_EDITING_VI is not set
+CONFIG_FEATURE_EDITING_HISTORY=0
+# CONFIG_FEATURE_EDITING_SAVEHISTORY is not set
+# CONFIG_FEATURE_TAB_COMPLETION is not set
+# CONFIG_FEATURE_USERNAME_COMPLETION is not set
+# CONFIG_FEATURE_EDITING_FANCY_PROMPT is not set
+# CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set
+# CONFIG_FEATURE_NON_POSIX_CP is not set
+# CONFIG_FEATURE_VERBOSE_CP_MESSAGE is not set
+CONFIG_FEATURE_COPYBUF_KB=4
+# CONFIG_FEATURE_SKIP_ROOTFS is not set
+# CONFIG_MONOTONIC_SYSCALL is not set
+# CONFIG_IOCTL_HEX2STR_ERROR is not set
+# CONFIG_FEATURE_HWIB is not set
+
+#
+# Applets
+#
+
+#
+# Archival Utilities
+#
+CONFIG_FEATURE_SEAMLESS_XZ=y
+CONFIG_FEATURE_SEAMLESS_LZMA=y
+CONFIG_FEATURE_SEAMLESS_BZ2=y
+CONFIG_FEATURE_SEAMLESS_GZ=y
+CONFIG_FEATURE_SEAMLESS_Z=y
+CONFIG_AR=y
+CONFIG_FEATURE_AR_LONG_FILENAMES=y
+CONFIG_FEATURE_AR_CREATE=y
+CONFIG_BUNZIP2=y
+CONFIG_BZIP2=y
+CONFIG_CPIO=y
+CONFIG_FEATURE_CPIO_O=y
+CONFIG_FEATURE_CPIO_P=y
+CONFIG_DPKG=y
+CONFIG_DPKG_DEB=y
+# CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY is not set
+CONFIG_GUNZIP=y
+CONFIG_GZIP=y
+# CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set
+CONFIG_LZOP=y
+CONFIG_LZOP_COMPR_HIGH=y
+CONFIG_RPM2CPIO=y
+CONFIG_RPM=y
+CONFIG_TAR=y
+CONFIG_FEATURE_TAR_CREATE=y
+CONFIG_FEATURE_TAR_AUTODETECT=y
+CONFIG_FEATURE_TAR_FROM=y
+CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY=y
+CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY=y
+CONFIG_FEATURE_TAR_GNU_EXTENSIONS=y
+# CONFIG_FEATURE_TAR_LONG_OPTIONS is not set
+# CONFIG_FEATURE_TAR_TO_COMMAND is not set
+CONFIG_FEATURE_TAR_UNAME_GNAME=y
+CONFIG_FEATURE_TAR_NOPRESERVE_TIME=y
+# CONFIG_FEATURE_TAR_SELINUX is not set
+CONFIG_UNCOMPRESS=y
+CONFIG_UNLZMA=y
+CONFIG_FEATURE_LZMA_FAST=y
+CONFIG_LZMA=y
+CONFIG_UNXZ=y
+CONFIG_XZ=y
+CONFIG_UNZIP=y
+
+#
+# Coreutils
+#
+CONFIG_BASENAME=y
+CONFIG_CAT=y
+# CONFIG_DATE is not set
+# CONFIG_FEATURE_DATE_ISOFMT is not set
+# CONFIG_FEATURE_DATE_NANO is not set
+# CONFIG_FEATURE_DATE_COMPAT is not set
+# CONFIG_ID is not set
+# CONFIG_GROUPS is not set
+CONFIG_TEST=y
+CONFIG_FEATURE_TEST_64=y
+CONFIG_TOUCH=y
+CONFIG_TR=y
+CONFIG_FEATURE_TR_CLASSES=y
+CONFIG_FEATURE_TR_EQUIV=y
+CONFIG_BASE64=y
+CONFIG_CAL=y
+CONFIG_CATV=y
+CONFIG_CHGRP=y
+CONFIG_CHMOD=y
+CONFIG_CHOWN=y
+# CONFIG_FEATURE_CHOWN_LONG_OPTIONS is not set
+CONFIG_CHROOT=y
+CONFIG_CKSUM=y
+CONFIG_COMM=y
+CONFIG_CP=y
+# CONFIG_FEATURE_CP_LONG_OPTIONS is not set
+CONFIG_CUT=y
+CONFIG_DD=y
+CONFIG_FEATURE_DD_SIGNAL_HANDLING=y
+CONFIG_FEATURE_DD_THIRD_STATUS_LINE=y
+CONFIG_FEATURE_DD_IBS_OBS=y
+# CONFIG_DF is not set
+# CONFIG_FEATURE_DF_FANCY is not set
+CONFIG_DIRNAME=y
+CONFIG_DOS2UNIX=y
+CONFIG_UNIX2DOS=y
+CONFIG_DU=y
+CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K=y
+CONFIG_ECHO=y
+CONFIG_FEATURE_FANCY_ECHO=y
+# CONFIG_ENV is not set
+# CONFIG_FEATURE_ENV_LONG_OPTIONS is not set
+CONFIG_EXPAND=y
+# CONFIG_FEATURE_EXPAND_LONG_OPTIONS is not set
+# CONFIG_EXPR is not set
+# CONFIG_EXPR_MATH_SUPPORT_64 is not set
+CONFIG_FALSE=y
+CONFIG_FOLD=y
+# CONFIG_FSYNC is not set
+CONFIG_HEAD=y
+CONFIG_FEATURE_FANCY_HEAD=y
+# CONFIG_HOSTID is not set
+CONFIG_INSTALL=y
+# CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set
+CONFIG_LN=y
+# CONFIG_LOGNAME is not set
+CONFIG_LS=y
+CONFIG_FEATURE_LS_FILETYPES=y
+CONFIG_FEATURE_LS_FOLLOWLINKS=y
+CONFIG_FEATURE_LS_RECURSIVE=y
+CONFIG_FEATURE_LS_SORTFILES=y
+CONFIG_FEATURE_LS_TIMESTAMPS=y
+CONFIG_FEATURE_LS_USERNAME=y
+# CONFIG_FEATURE_LS_COLOR is not set
+# CONFIG_FEATURE_LS_COLOR_IS_DEFAULT is not set
+CONFIG_MD5SUM=y
+CONFIG_MKDIR=y
+# CONFIG_FEATURE_MKDIR_LONG_OPTIONS is not set
+CONFIG_MKFIFO=y
+CONFIG_MKNOD=y
+CONFIG_MV=y
+# CONFIG_FEATURE_MV_LONG_OPTIONS is not set
+CONFIG_NICE=y
+CONFIG_NOHUP=y
+CONFIG_OD=y
+CONFIG_PRINTENV=y
+CONFIG_PRINTF=y
+CONFIG_PWD=y
+CONFIG_READLINK=y
+CONFIG_FEATURE_READLINK_FOLLOW=y
+CONFIG_REALPATH=y
+CONFIG_RM=y
+CONFIG_RMDIR=y
+# CONFIG_FEATURE_RMDIR_LONG_OPTIONS is not set
+CONFIG_SEQ=y
+CONFIG_SHA1SUM=y
+CONFIG_SHA256SUM=y
+CONFIG_SHA512SUM=y
+CONFIG_SLEEP=y
+CONFIG_FEATURE_FANCY_SLEEP=y
+CONFIG_FEATURE_FLOAT_SLEEP=y
+CONFIG_SORT=y
+CONFIG_FEATURE_SORT_BIG=y
+CONFIG_SPLIT=y
+CONFIG_FEATURE_SPLIT_FANCY=y
+# CONFIG_STAT is not set
+# CONFIG_FEATURE_STAT_FORMAT is not set
+CONFIG_STTY=y
+CONFIG_SUM=y
+CONFIG_SYNC=y
+CONFIG_TAC=y
+CONFIG_TAIL=y
+CONFIG_FEATURE_FANCY_TAIL=y
+CONFIG_TEE=y
+CONFIG_FEATURE_TEE_USE_BLOCK_IO=y
+CONFIG_TRUE=y
+# CONFIG_TTY is not set
+CONFIG_UNAME=y
+CONFIG_UNEXPAND=y
+# CONFIG_FEATURE_UNEXPAND_LONG_OPTIONS is not set
+CONFIG_UNIQ=y
+# CONFIG_USLEEP is not set
+CONFIG_UUDECODE=y
+CONFIG_UUENCODE=y
+CONFIG_WC=y
+CONFIG_FEATURE_WC_LARGE=y
+# CONFIG_WHO is not set
+CONFIG_WHOAMI=y
+CONFIG_YES=y
+
+#
+# Common options for cp and mv
+#
+CONFIG_FEATURE_PRESERVE_HARDLINKS=y
+
+#
+# Common options for ls, more and telnet
+#
+CONFIG_FEATURE_AUTOWIDTH=y
+
+#
+# Common options for df, du, ls
+#
+CONFIG_FEATURE_HUMAN_READABLE=y
+
+#
+# Common options for md5sum, sha1sum, sha256sum, sha512sum
+#
+CONFIG_FEATURE_MD5_SHA1_SUM_CHECK=y
+
+#
+# Console Utilities
+#
+CONFIG_CHVT=y
+CONFIG_FGCONSOLE=y
+CONFIG_CLEAR=y
+CONFIG_DEALLOCVT=y
+CONFIG_DUMPKMAP=y
+# CONFIG_KBD_MODE is not set
+# CONFIG_LOADFONT is not set
+CONFIG_LOADKMAP=y
+CONFIG_OPENVT=y
+CONFIG_RESET=y
+CONFIG_RESIZE=y
+CONFIG_FEATURE_RESIZE_PRINT=y
+CONFIG_SETCONSOLE=y
+# CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set
+# CONFIG_SETFONT is not set
+# CONFIG_FEATURE_SETFONT_TEXTUAL_MAP is not set
+CONFIG_DEFAULT_SETFONT_DIR=""
+CONFIG_SETKEYCODES=y
+CONFIG_SETLOGCONS=y
+CONFIG_SHOWKEY=y
+# CONFIG_FEATURE_LOADFONT_PSF2 is not set
+# CONFIG_FEATURE_LOADFONT_RAW is not set
+
+#
+# Debian Utilities
+#
+CONFIG_MKTEMP=y
+CONFIG_PIPE_PROGRESS=y
+CONFIG_RUN_PARTS=y
+# CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS is not set
+CONFIG_FEATURE_RUN_PARTS_FANCY=y
+CONFIG_START_STOP_DAEMON=y
+CONFIG_FEATURE_START_STOP_DAEMON_FANCY=y
+# CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS is not set
+CONFIG_WHICH=y
+
+#
+# Editors
+#
+CONFIG_PATCH=y
+CONFIG_VI=y
+CONFIG_FEATURE_VI_MAX_LEN=0
+# CONFIG_FEATURE_VI_8BIT is not set
+# CONFIG_FEATURE_VI_COLON is not set
+# CONFIG_FEATURE_VI_YANKMARK is not set
+CONFIG_FEATURE_VI_SEARCH=y
+# CONFIG_FEATURE_VI_REGEX_SEARCH is not set
+CONFIG_FEATURE_VI_USE_SIGNALS=y
+# CONFIG_FEATURE_VI_DOT_CMD is not set
+# CONFIG_FEATURE_VI_READONLY is not set
+# CONFIG_FEATURE_VI_SETOPTS is not set
+# CONFIG_FEATURE_VI_SET is not set
+CONFIG_FEATURE_VI_WIN_RESIZE=y
+# CONFIG_FEATURE_VI_ASK_TERMINAL is not set
+# CONFIG_FEATURE_VI_OPTIMIZE_CURSOR is not set
+# CONFIG_AWK is not set
+# CONFIG_FEATURE_AWK_LIBM is not set
+CONFIG_CMP=y
+CONFIG_DIFF=y
+# CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set
+CONFIG_FEATURE_DIFF_DIR=y
+# CONFIG_ED is not set
+CONFIG_SED=y
+# CONFIG_FEATURE_ALLOW_EXEC is not set
+
+#
+# Finding Utilities
+#
+CONFIG_FIND=y
+CONFIG_FEATURE_FIND_PRINT0=y
+CONFIG_FEATURE_FIND_MTIME=y
+# CONFIG_FEATURE_FIND_MMIN is not set
+CONFIG_FEATURE_FIND_PERM=y
+CONFIG_FEATURE_FIND_TYPE=y
+# CONFIG_FEATURE_FIND_XDEV is not set
+# CONFIG_FEATURE_FIND_MAXDEPTH is not set
+# CONFIG_FEATURE_FIND_NEWER is not set
+# CONFIG_FEATURE_FIND_INUM is not set
+# CONFIG_FEATURE_FIND_EXEC is not set
+# CONFIG_FEATURE_FIND_USER is not set
+# CONFIG_FEATURE_FIND_GROUP is not set
+# CONFIG_FEATURE_FIND_NOT is not set
+# CONFIG_FEATURE_FIND_DEPTH is not set
+# CONFIG_FEATURE_FIND_PAREN is not set
+# CONFIG_FEATURE_FIND_SIZE is not set
+# CONFIG_FEATURE_FIND_PRUNE is not set
+# CONFIG_FEATURE_FIND_DELETE is not set
+# CONFIG_FEATURE_FIND_PATH is not set
+# CONFIG_FEATURE_FIND_REGEX is not set
+# CONFIG_FEATURE_FIND_CONTEXT is not set
+# CONFIG_FEATURE_FIND_LINKS is not set
+CONFIG_GREP=y
+# CONFIG_FEATURE_GREP_EGREP_ALIAS is not set
+# CONFIG_FEATURE_GREP_FGREP_ALIAS is not set
+# CONFIG_FEATURE_GREP_CONTEXT is not set
+CONFIG_XARGS=y
+CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION=y
+CONFIG_FEATURE_XARGS_SUPPORT_QUOTES=y
+CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT=y
+CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM=y
+
+#
+# Init Utilities
+#
+# CONFIG_BOOTCHARTD is not set
+# CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER is not set
+# CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE is not set
+# CONFIG_HALT is not set
+# CONFIG_FEATURE_CALL_TELINIT is not set
+# CONFIG_TELINIT_PATH=""
+# CONFIG_INIT is not set
+# CONFIG_FEATURE_USE_INITTAB is not set
+# CONFIG_FEATURE_KILL_REMOVED is not set
+# CONFIG_FEATURE_KILL_DELAY=0
+# CONFIG_FEATURE_INIT_SCTTY is not set
+# CONFIG_FEATURE_INIT_SYSLOG is not set
+# CONFIG_FEATURE_EXTRA_QUIET is not set
+# CONFIG_FEATURE_INIT_COREDUMPS is not set
+# CONFIG_FEATURE_INITRD is not set
+# CONFIG_INIT_TERMINAL_TYPE="linux"
+# CONFIG_MESG is not set
+# CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP=y
+
+#
+# Login/Password Management Utilities
+#
+# CONFIG_ADD_SHELL is not set
+# CONFIG_REMOVE_SHELL is not set
+# CONFIG_FEATURE_SHADOWPASSWDS is not set
+# CONFIG_USE_BB_PWD_GRP is not set
+# CONFIG_USE_BB_SHADOW is not set
+# CONFIG_USE_BB_CRYPT is not set
+# CONFIG_USE_BB_CRYPT_SHA is not set
+# CONFIG_ADDUSER is not set
+# CONFIG_FEATURE_ADDUSER_LONG_OPTIONS is not set
+# CONFIG_FEATURE_CHECK_NAMES is not set
+CONFIG_FIRST_SYSTEM_ID=0
+CONFIG_LAST_SYSTEM_ID=0
+# CONFIG_ADDGROUP is not set
+# CONFIG_FEATURE_ADDGROUP_LONG_OPTIONS is not set
+# CONFIG_FEATURE_ADDUSER_TO_GROUP is not set
+# CONFIG_DELUSER is not set
+# CONFIG_DELGROUP is not set
+# CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set
+# CONFIG_GETTY is not set
+# CONFIG_LOGIN is not set
+# CONFIG_PAM is not set
+# CONFIG_LOGIN_SCRIPTS is not set
+# CONFIG_FEATURE_NOLOGIN is not set
+# CONFIG_FEATURE_SECURETTY is not set
+# CONFIG_PASSWD is not set
+# CONFIG_FEATURE_PASSWD_WEAK_CHECK is not set
+# CONFIG_CRYPTPW is not set
+# CONFIG_CHPASSWD is not set
+# CONFIG_SU is not set
+# CONFIG_FEATURE_SU_SYSLOG is not set
+# CONFIG_FEATURE_SU_CHECKS_SHELLS is not set
+# CONFIG_SULOGIN is not set
+# CONFIG_VLOCK is not set
+
+#
+# Linux Ext2 FS Progs
+#
+CONFIG_CHATTR=y
+# CONFIG_FSCK is not set
+CONFIG_LSATTR=y
+CONFIG_TUNE2FS=y
+
+#
+# Linux Module Utilities
+#
+# CONFIG_MODINFO is not set
+# CONFIG_MODPROBE_SMALL is not set
+# CONFIG_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE=y
+# CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED=y
+# CONFIG_INSMOD is not set
+# CONFIG_RMMOD is not set
+# CONFIG_LSMOD is not set
+# CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT is not set
+# CONFIG_MODPROBE is not set
+# CONFIG_FEATURE_MODPROBE_BLACKLIST is not set
+# CONFIG_DEPMOD is not set
+
+#
+# Options common to multiple modutils
+#
+# CONFIG_FEATURE_2_4_MODULES is not set
+# CONFIG_FEATURE_INSMOD_TRY_MMAP is not set
+# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set
+# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set
+# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set
+# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set
+# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set
+# CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set
+# CONFIG_FEATURE_MODUTILS_ALIAS is not set
+# CONFIG_FEATURE_MODUTILS_SYMBOLS is not set
+# CONFIG_DEFAULT_MODULES_DIR="/lib/modules"
+# CONFIG_DEFAULT_DEPMOD_FILE="modules.dep"
+
+#
+# Linux System Utilities
+#
+CONFIG_BLOCKDEV=y
+CONFIG_REV=y
+# CONFIG_ACPID is not set
+# CONFIG_FEATURE_ACPID_COMPAT is not set
+CONFIG_BLKID=y
+# CONFIG_FEATURE_BLKID_TYPE is not set
+CONFIG_DMESG=y
+CONFIG_FEATURE_DMESG_PRETTY=y
+CONFIG_FBSET=y
+CONFIG_FEATURE_FBSET_FANCY=y
+CONFIG_FEATURE_FBSET_READMODE=y
+CONFIG_FDFLUSH=y
+CONFIG_FDFORMAT=y
+CONFIG_FDISK=y
+CONFIG_FDISK_SUPPORT_LARGE_DISKS=y
+CONFIG_FEATURE_FDISK_WRITABLE=y
+# CONFIG_FEATURE_AIX_LABEL is not set
+# CONFIG_FEATURE_SGI_LABEL is not set
+# CONFIG_FEATURE_SUN_LABEL is not set
+# CONFIG_FEATURE_OSF_LABEL is not set
+# CONFIG_FEATURE_GPT_LABEL is not set
+CONFIG_FEATURE_FDISK_ADVANCED=y
+CONFIG_FINDFS=y
+CONFIG_FLOCK=y
+CONFIG_FREERAMDISK=y
+# CONFIG_FSCK_MINIX is not set
+# CONFIG_MKFS_EXT2 is not set
+# CONFIG_MKFS_MINIX is not set
+# CONFIG_FEATURE_MINIX2 is not set
+# CONFIG_MKFS_REISER is not set
+# CONFIG_MKFS_VFAT is not set
+CONFIG_GETOPT=y
+CONFIG_FEATURE_GETOPT_LONG=y
+CONFIG_HEXDUMP=y
+CONFIG_FEATURE_HEXDUMP_REVERSE=y
+CONFIG_HD=y
+# CONFIG_HWCLOCK is not set
+# CONFIG_FEATURE_HWCLOCK_LONG_OPTIONS is not set
+# CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set
+# CONFIG_IPCRM is not set
+# CONFIG_IPCS is not set
+CONFIG_LOSETUP=y
+CONFIG_LSPCI=y
+CONFIG_LSUSB=y
+# CONFIG_MDEV is not set
+# CONFIG_FEATURE_MDEV_CONF is not set
+# CONFIG_FEATURE_MDEV_RENAME is not set
+# CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set
+# CONFIG_FEATURE_MDEV_EXEC is not set
+# CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set
+CONFIG_MKSWAP=y
+CONFIG_FEATURE_MKSWAP_UUID=y
+CONFIG_MORE=y
+# CONFIG_MOUNT is not set
+# CONFIG_FEATURE_MOUNT_FAKE is not set
+# CONFIG_FEATURE_MOUNT_VERBOSE is not set
+# CONFIG_FEATURE_MOUNT_HELPERS is not set
+# CONFIG_FEATURE_MOUNT_LABEL is not set
+# CONFIG_FEATURE_MOUNT_NFS is not set
+# CONFIG_FEATURE_MOUNT_CIFS is not set
+# CONFIG_FEATURE_MOUNT_FLAGS is not set
+# CONFIG_FEATURE_MOUNT_FSTAB is not set
+# CONFIG_PIVOT_ROOT is not set
+# CONFIG_RDATE is not set
+CONFIG_RDEV=y
+CONFIG_READPROFILE=y
+CONFIG_RTCWAKE=y
+CONFIG_SCRIPT=y
+CONFIG_SCRIPTREPLAY=y
+# CONFIG_SETARCH is not set
+# CONFIG_SWAPONOFF is not set
+# CONFIG_FEATURE_SWAPON_PRI is not set
+# CONFIG_SWITCH_ROOT is not set
+# CONFIG_UMOUNT is not set
+# CONFIG_FEATURE_UMOUNT_ALL is not set
+# CONFIG_FEATURE_MOUNT_LOOP is not set
+# CONFIG_FEATURE_MOUNT_LOOP_CREATE is not set
+# CONFIG_FEATURE_MTAB_SUPPORT is not set
+CONFIG_VOLUMEID=y
+
+#
+# Filesystem/Volume identification
+#
+CONFIG_FEATURE_VOLUMEID_EXT=y
+CONFIG_FEATURE_VOLUMEID_BTRFS=y
+CONFIG_FEATURE_VOLUMEID_REISERFS=y
+CONFIG_FEATURE_VOLUMEID_FAT=y
+CONFIG_FEATURE_VOLUMEID_HFS=y
+CONFIG_FEATURE_VOLUMEID_JFS=y
+CONFIG_FEATURE_VOLUMEID_XFS=y
+CONFIG_FEATURE_VOLUMEID_NTFS=y
+CONFIG_FEATURE_VOLUMEID_ISO9660=y
+CONFIG_FEATURE_VOLUMEID_UDF=y
+CONFIG_FEATURE_VOLUMEID_LUKS=y
+CONFIG_FEATURE_VOLUMEID_LINUXSWAP=y
+CONFIG_FEATURE_VOLUMEID_CRAMFS=y
+CONFIG_FEATURE_VOLUMEID_ROMFS=y
+CONFIG_FEATURE_VOLUMEID_SYSV=y
+CONFIG_FEATURE_VOLUMEID_OCFS2=y
+CONFIG_FEATURE_VOLUMEID_LINUXRAID=y
+
+#
+# Miscellaneous Utilities
+#
+# CONFIG_CONSPY is not set
+# CONFIG_NANDWRITE is not set
+CONFIG_NANDDUMP=y
+CONFIG_SETSERIAL=y
+# CONFIG_UBIATTACH is not set
+# CONFIG_UBIDETACH is not set
+# CONFIG_UBIMKVOL is not set
+# CONFIG_UBIRMVOL is not set
+# CONFIG_UBIRSVOL is not set
+# CONFIG_UBIUPDATEVOL is not set
+# CONFIG_ADJTIMEX is not set
+# CONFIG_BBCONFIG is not set
+# CONFIG_FEATURE_COMPRESS_BBCONFIG is not set
+CONFIG_BEEP=y
+CONFIG_FEATURE_BEEP_FREQ=4000
+CONFIG_FEATURE_BEEP_LENGTH_MS=30
+CONFIG_CHAT=y
+CONFIG_FEATURE_CHAT_NOFAIL=y
+# CONFIG_FEATURE_CHAT_TTY_HIFI is not set
+CONFIG_FEATURE_CHAT_IMPLICIT_CR=y
+CONFIG_FEATURE_CHAT_SWALLOW_OPTS=y
+CONFIG_FEATURE_CHAT_SEND_ESCAPES=y
+CONFIG_FEATURE_CHAT_VAR_ABORT_LEN=y
+CONFIG_FEATURE_CHAT_CLR_ABORT=y
+CONFIG_CHRT=y
+# CONFIG_CROND is not set
+# CONFIG_FEATURE_CROND_D is not set
+# CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set
+CONFIG_FEATURE_CROND_DIR=""
+# CONFIG_CRONTAB is not set
+CONFIG_DC=y
+CONFIG_FEATURE_DC_LIBM=y
+# CONFIG_DEVFSD is not set
+# CONFIG_DEVFSD_MODLOAD is not set
+# CONFIG_DEVFSD_FG_NP is not set
+# CONFIG_DEVFSD_VERBOSE is not set
+# CONFIG_FEATURE_DEVFS is not set
+CONFIG_DEVMEM=y
+# CONFIG_EJECT is not set
+# CONFIG_FEATURE_EJECT_SCSI is not set
+CONFIG_FBSPLASH=y
+CONFIG_FLASHCP=y
+CONFIG_FLASH_LOCK=y
+CONFIG_FLASH_UNLOCK=y
+# CONFIG_FLASH_ERASEALL is not set
+# CONFIG_IONICE is not set
+CONFIG_INOTIFYD=y
+# CONFIG_LAST is not set
+# CONFIG_FEATURE_LAST_SMALL is not set
+# CONFIG_FEATURE_LAST_FANCY is not set
+# CONFIG_LESS is not set
+CONFIG_FEATURE_LESS_MAXLINES=0
+# CONFIG_FEATURE_LESS_BRACKETS is not set
+# CONFIG_FEATURE_LESS_FLAGS is not set
+# CONFIG_FEATURE_LESS_MARKS is not set
+# CONFIG_FEATURE_LESS_REGEXP is not set
+# CONFIG_FEATURE_LESS_WINCH is not set
+# CONFIG_FEATURE_LESS_DASHCMD is not set
+# CONFIG_FEATURE_LESS_LINENUMS is not set
+CONFIG_HDPARM=y
+CONFIG_FEATURE_HDPARM_GET_IDENTITY=y
+CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF=y
+CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF=y
+CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET=y
+CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF=y
+CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA=y
+CONFIG_MAKEDEVS=y
+# CONFIG_FEATURE_MAKEDEVS_LEAF is not set
+CONFIG_FEATURE_MAKEDEVS_TABLE=y
+CONFIG_MAN=y
+# CONFIG_MICROCOM is not set
+# CONFIG_MOUNTPOINT is not set
+# CONFIG_MT is not set
+CONFIG_RAIDAUTORUN=y
+# CONFIG_READAHEAD is not set
+# CONFIG_RFKILL is not set
+# CONFIG_RUNLEVEL is not set
+CONFIG_RX=y
+CONFIG_SETSID=y
+CONFIG_STRINGS=y
+# CONFIG_TASKSET is not set
+# CONFIG_FEATURE_TASKSET_FANCY is not set
+CONFIG_TIME=y
+CONFIG_TIMEOUT=y
+CONFIG_TTYSIZE=y
+CONFIG_VOLNAME=y
+# CONFIG_WALL is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Networking Utilities
+#
+# CONFIG_NAMEIF is not set
+# CONFIG_FEATURE_NAMEIF_EXTENDED is not set
+CONFIG_NBDCLIENT=y
+CONFIG_NC=y
+CONFIG_NC_SERVER=y
+CONFIG_NC_EXTRA=y
+# CONFIG_NC_110_COMPAT is not set
+# CONFIG_PING is not set
+# CONFIG_PING6 is not set
+# CONFIG_FEATURE_FANCY_PING is not set
+CONFIG_WHOIS=y
+# CONFIG_FEATURE_IPV6 is not set
+# CONFIG_FEATURE_UNIX_LOCAL is not set
+# CONFIG_FEATURE_PREFER_IPV4_ADDRESS is not set
+# CONFIG_VERBOSE_RESOLUTION_ERRORS is not set
+CONFIG_ARP=y
+# CONFIG_ARPING is not set
+# CONFIG_BRCTL is not set
+# CONFIG_FEATURE_BRCTL_FANCY is not set
+# CONFIG_FEATURE_BRCTL_SHOW is not set
+CONFIG_DNSD=y
+# CONFIG_ETHER_WAKE is not set
+CONFIG_FAKEIDENTD=y
+CONFIG_FTPD=y
+CONFIG_FEATURE_FTP_WRITE=y
+CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST=y
+CONFIG_FTPGET=y
+CONFIG_FTPPUT=y
+# CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set
+# CONFIG_HOSTNAME is not set
+CONFIG_HTTPD=y
+CONFIG_FEATURE_HTTPD_RANGES=y
+CONFIG_FEATURE_HTTPD_USE_SENDFILE=y
+CONFIG_FEATURE_HTTPD_SETUID=y
+CONFIG_FEATURE_HTTPD_BASIC_AUTH=y
+# CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set
+CONFIG_FEATURE_HTTPD_CGI=y
+CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR=y
+CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV=y
+CONFIG_FEATURE_HTTPD_ENCODE_URL_STR=y
+CONFIG_FEATURE_HTTPD_ERROR_PAGES=y
+CONFIG_FEATURE_HTTPD_PROXY=y
+CONFIG_FEATURE_HTTPD_GZIP=y
+CONFIG_IFCONFIG=y
+CONFIG_FEATURE_IFCONFIG_STATUS=y
+# CONFIG_FEATURE_IFCONFIG_SLIP is not set
+CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ=y
+CONFIG_FEATURE_IFCONFIG_HW=y
+CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS=y
+# CONFIG_IFENSLAVE is not set
+# CONFIG_IFPLUGD is not set
+CONFIG_IFUPDOWN=y
+CONFIG_IFUPDOWN_IFSTATE_PATH="/var/run/ifstate"
+CONFIG_FEATURE_IFUPDOWN_IP=y
+CONFIG_FEATURE_IFUPDOWN_IP_BUILTIN=y
+# CONFIG_FEATURE_IFUPDOWN_IFCONFIG_BUILTIN is not set
+CONFIG_FEATURE_IFUPDOWN_IPV4=y
+# CONFIG_FEATURE_IFUPDOWN_IPV6 is not set
+CONFIG_FEATURE_IFUPDOWN_MAPPING=y
+# CONFIG_FEATURE_IFUPDOWN_EXTERNAL_DHCP is not set
+# CONFIG_INETD is not set
+# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO is not set
+# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD is not set
+# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME is not set
+# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME is not set
+# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN is not set
+# CONFIG_FEATURE_INETD_RPC is not set
+CONFIG_IP=y
+CONFIG_FEATURE_IP_ADDRESS=y
+CONFIG_FEATURE_IP_LINK=y
+CONFIG_FEATURE_IP_ROUTE=y
+CONFIG_FEATURE_IP_TUNNEL=y
+CONFIG_FEATURE_IP_RULE=y
+CONFIG_FEATURE_IP_SHORT_FORMS=y
+# CONFIG_FEATURE_IP_RARE_PROTOCOLS is not set
+CONFIG_IPADDR=y
+CONFIG_IPLINK=y
+CONFIG_IPROUTE=y
+CONFIG_IPTUNNEL=y
+CONFIG_IPRULE=y
+CONFIG_IPCALC=y
+CONFIG_FEATURE_IPCALC_FANCY=y
+# CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set
+CONFIG_NETSTAT=y
+CONFIG_FEATURE_NETSTAT_WIDE=y
+CONFIG_FEATURE_NETSTAT_PRG=y
+# CONFIG_NSLOOKUP is not set
+# CONFIG_NTPD is not set
+# CONFIG_FEATURE_NTPD_SERVER is not set
+CONFIG_PSCAN=y
+CONFIG_ROUTE=y
+# CONFIG_SLATTACH is not set
+CONFIG_TCPSVD=y
+# CONFIG_TELNET is not set
+# CONFIG_FEATURE_TELNET_TTYPE is not set
+# CONFIG_FEATURE_TELNET_AUTOLOGIN is not set
+# CONFIG_TELNETD is not set
+# CONFIG_FEATURE_TELNETD_STANDALONE is not set
+# CONFIG_FEATURE_TELNETD_INETD_WAIT is not set
+# CONFIG_TFTP is not set
+# CONFIG_TFTPD is not set
+# CONFIG_FEATURE_TFTP_GET is not set
+# CONFIG_FEATURE_TFTP_PUT is not set
+# CONFIG_FEATURE_TFTP_BLOCKSIZE is not set
+# CONFIG_FEATURE_TFTP_PROGRESS_BAR is not set
+# CONFIG_TFTP_DEBUG is not set
+# CONFIG_TRACEROUTE is not set
+# CONFIG_TRACEROUTE6 is not set
+# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set
+# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set
+# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set
+CONFIG_TUNCTL=y
+CONFIG_FEATURE_TUNCTL_UG=y
+# CONFIG_UDHCPD is not set
+# CONFIG_DHCPRELAY is not set
+# CONFIG_DUMPLEASES is not set
+# CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY is not set
+# CONFIG_FEATURE_UDHCPD_BASE_IP_ON_MAC is not set
+CONFIG_DHCPD_LEASES_FILE=""
+CONFIG_UDHCPC=y
+CONFIG_FEATURE_UDHCPC_ARPING=y
+# CONFIG_FEATURE_UDHCP_PORT is not set
+CONFIG_UDHCP_DEBUG=9
+CONFIG_FEATURE_UDHCP_RFC3397=y
+CONFIG_FEATURE_UDHCP_8021Q=y
+CONFIG_UDHCPC_DEFAULT_SCRIPT="/usr/share/udhcpc/default.script"
+CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=80
+CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="-R -n"
+# CONFIG_UDPSVD is not set
+# CONFIG_VCONFIG is not set
+CONFIG_WGET=y
+CONFIG_FEATURE_WGET_STATUSBAR=y
+CONFIG_FEATURE_WGET_AUTHENTICATION=y
+# CONFIG_FEATURE_WGET_LONG_OPTIONS is not set
+CONFIG_FEATURE_WGET_TIMEOUT=y
+# CONFIG_ZCIP is not set
+
+#
+# Print Utilities
+#
+CONFIG_LPD=y
+CONFIG_LPR=y
+CONFIG_LPQ=y
+
+#
+# Mail Utilities
+#
+CONFIG_MAKEMIME=y
+CONFIG_FEATURE_MIME_CHARSET="us-ascii"
+CONFIG_POPMAILDIR=y
+CONFIG_FEATURE_POPMAILDIR_DELIVERY=y
+CONFIG_REFORMIME=y
+CONFIG_FEATURE_REFORMIME_COMPAT=y
+CONFIG_SENDMAIL=y
+
+#
+# Process Utilities
+#
+CONFIG_IOSTAT=y
+CONFIG_MPSTAT=y
+CONFIG_NMETER=y
+CONFIG_PMAP=y
+# CONFIG_POWERTOP is not set
+CONFIG_PSTREE=y
+CONFIG_PWDX=y
+CONFIG_SMEMCAP=y
+# CONFIG_FREE is not set
+CONFIG_FUSER=y
+# CONFIG_KILL is not set
+# CONFIG_KILLALL is not set
+# CONFIG_KILLALL5 is not set
+# CONFIG_PGREP is not set
+CONFIG_PIDOF=y
+CONFIG_FEATURE_PIDOF_SINGLE=y
+CONFIG_FEATURE_PIDOF_OMIT=y
+# CONFIG_PKILL is not set
+# CONFIG_PS is not set
+# CONFIG_FEATURE_PS_WIDE is not set
+# CONFIG_FEATURE_PS_TIME is not set
+# CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set
+# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set
+CONFIG_RENICE=y
+CONFIG_BB_SYSCTL=y
+CONFIG_TOP=y
+CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE=y
+CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS=y
+CONFIG_FEATURE_TOP_SMP_CPU=y
+CONFIG_FEATURE_TOP_DECIMALS=y
+CONFIG_FEATURE_TOP_SMP_PROCESS=y
+CONFIG_FEATURE_TOPMEM=y
+CONFIG_FEATURE_SHOW_THREADS=y
+# CONFIG_UPTIME is not set
+CONFIG_WATCH=y
+
+#
+# Runit Utilities
+#
+CONFIG_RUNSV=y
+CONFIG_RUNSVDIR=y
+# CONFIG_FEATURE_RUNSVDIR_LOG is not set
+CONFIG_SV=y
+CONFIG_SV_DEFAULT_SERVICE_DIR="/var/service"
+CONFIG_SVLOGD=y
+CONFIG_CHPST=y
+CONFIG_SETUIDGID=y
+CONFIG_ENVUIDGID=y
+CONFIG_ENVDIR=y
+CONFIG_SOFTLIMIT=y
+# CONFIG_CHCON is not set
+# CONFIG_FEATURE_CHCON_LONG_OPTIONS is not set
+# CONFIG_GETENFORCE is not set
+# CONFIG_GETSEBOOL is not set
+# CONFIG_LOAD_POLICY is not set
+# CONFIG_MATCHPATHCON is not set
+# CONFIG_RESTORECON is not set
+# CONFIG_RUNCON is not set
+# CONFIG_FEATURE_RUNCON_LONG_OPTIONS is not set
+# CONFIG_SELINUXENABLED is not set
+# CONFIG_SETENFORCE is not set
+# CONFIG_SETFILES is not set
+# CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set
+# CONFIG_SETSEBOOL is not set
+# CONFIG_SESTATUS is not set
+
+#
+# Shells
+#
+CONFIG_ASH=y
+# CONFIG_ASH_BASH_COMPAT is not set
+# CONFIG_ASH_IDLE_TIMEOUT is not set
+CONFIG_ASH_JOB_CONTROL=y
+# CONFIG_ASH_ALIAS is not set
+CONFIG_ASH_GETOPTS=y
+# CONFIG_ASH_BUILTIN_ECHO is not set
+# CONFIG_ASH_BUILTIN_PRINTF is not set
+# CONFIG_ASH_BUILTIN_TEST is not set
+# CONFIG_ASH_CMDCMD is not set
+# CONFIG_ASH_MAIL is not set
+# CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set
+# CONFIG_ASH_RANDOM_SUPPORT is not set
+# CONFIG_ASH_EXPAND_PRMT is not set
+CONFIG_CTTYHACK=y
+# CONFIG_HUSH is not set
+# CONFIG_HUSH_BASH_COMPAT is not set
+# CONFIG_HUSH_BRACE_EXPANSION is not set
+# CONFIG_HUSH_HELP is not set
+# CONFIG_HUSH_INTERACTIVE is not set
+# CONFIG_HUSH_SAVEHISTORY is not set
+# CONFIG_HUSH_JOB is not set
+# CONFIG_HUSH_TICK is not set
+# CONFIG_HUSH_IF is not set
+# CONFIG_HUSH_LOOPS is not set
+# CONFIG_HUSH_CASE is not set
+# CONFIG_HUSH_FUNCTIONS is not set
+# CONFIG_HUSH_LOCAL is not set
+# CONFIG_HUSH_RANDOM_SUPPORT is not set
+# CONFIG_HUSH_EXPORT_N is not set
+# CONFIG_HUSH_MODE_X is not set
+# CONFIG_MSH is not set
+CONFIG_FEATURE_SH_IS_ASH=y
+# CONFIG_FEATURE_SH_IS_HUSH is not set
+# CONFIG_FEATURE_SH_IS_NONE is not set
+# CONFIG_FEATURE_BASH_IS_ASH is not set
+# CONFIG_FEATURE_BASH_IS_HUSH is not set
+CONFIG_FEATURE_BASH_IS_NONE=y
+# CONFIG_SH_MATH_SUPPORT is not set
+# CONFIG_SH_MATH_SUPPORT_64 is not set
+# CONFIG_FEATURE_SH_EXTRA_QUIET is not set
+CONFIG_FEATURE_SH_STANDALONE=y
+# CONFIG_FEATURE_SH_NOFORK is not set
+# CONFIG_FEATURE_SH_HISTFILESIZE is not set
+
+#
+# System Logging Utilities
+#
+# CONFIG_SYSLOGD is not set
+# CONFIG_FEATURE_ROTATE_LOGFILE is not set
+# CONFIG_FEATURE_REMOTE_LOG is not set
+# CONFIG_FEATURE_SYSLOGD_DUP is not set
+# CONFIG_FEATURE_SYSLOGD_CFG is not set
+CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=0
+# CONFIG_FEATURE_IPC_SYSLOG is not set
+CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0
+# CONFIG_LOGREAD is not set
+# CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set
+CONFIG_KLOGD=y
+CONFIG_FEATURE_KLOGD_KLOGCTL=y
+# CONFIG_LOGGER is not set
diff --git a/standalone/android/clean-haskell-packages b/standalone/android/clean-haskell-packages
new file mode 100755
index 000000000..b8c6132d6
--- /dev/null
+++ b/standalone/android/clean-haskell-packages
@@ -0,0 +1,6 @@
+#!/bin/sh
+# Removes all currently installed cross-compiled haskell packages
+# except those part of ghc.
+# Useful if the build failed.
+rm -f $(grep -l $HOME/.ghc/$(cat abiversion)/.cabal/lib/ $HOME/.ghc/android-14/arm-linux-androideabi-4.8/lib/*-ghc-*/package.conf.d/*.conf)
+$HOME/.ghc/$(cat abiversion)/arm-linux-androideabi/bin/ghc-pkg recache
diff --git a/standalone/android/dropbear.patch b/standalone/android/dropbear.patch
new file mode 100644
index 000000000..84c7dfb6d
--- /dev/null
+++ b/standalone/android/dropbear.patch
@@ -0,0 +1,55 @@
+From 014dadb02fd984828a6232534c47dba8e2f7818a Mon Sep 17 00:00:00 2001
+From: Joey Hess <joey@kitenet.net>
+Date: Wed, 13 Feb 2013 15:29:52 -0400
+Subject: [PATCH] android patch for dropbear
+
+* Disable HOME override
+* Use urandom to avoid blocking on every ssh connection.
+* Enable use of netbsd_getpass.c
+---
+ cli-auth.c | 1 +
+ cli-main.c | 2 --
+ options.h | 2 +-
+ 3 files changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/cli-auth.c b/cli-auth.c
+index 4c17a21..91dfdf8 100644
+--- a/cli-auth.c
++++ b/cli-auth.c
+@@ -31,6 +31,7 @@
+ #include "ssh.h"
+ #include "packet.h"
+ #include "runopts.h"
++#include "netbsd_getpass.c"
+
+ void cli_authinitialise() {
+
+diff --git a/cli-main.c b/cli-main.c
+index 106006b..68cf023 100644
+--- a/cli-main.c
++++ b/cli-main.c
+@@ -47,8 +47,6 @@ int main(int argc, char ** argv) {
+ _dropbear_exit = cli_dropbear_exit;
+ _dropbear_log = cli_dropbear_log;
+
+- putenv("HOME=/data/local");
+-
+ disallow_core();
+
+ cli_getopts(argc, argv);
+diff --git a/options.h b/options.h
+index 7625151..48e404d 100644
+--- a/options.h
++++ b/options.h
+@@ -159,7 +159,7 @@ etc) slower (perhaps by 50%). Recommended for most small systems. */
+ * however significantly reduce the security of your ssh connections
+ * if the PRNG state becomes guessable - make sure you know what you are
+ * doing if you change this. */
+-#define DROPBEAR_RANDOM_DEV "/dev/random"
++#define DROPBEAR_RANDOM_DEV "/dev/urandom"
+
+ /* prngd must be manually set up to produce output */
+ /*#define DROPBEAR_PRNGD_SOCKET "/var/run/dropbear-rng"*/
+--
+1.7.10.4
+
diff --git a/standalone/android/evilsplicer-headers.hs b/standalone/android/evilsplicer-headers.hs
new file mode 100644
index 000000000..ee4d6f1a3
--- /dev/null
+++ b/standalone/android/evilsplicer-headers.hs
@@ -0,0 +1,32 @@
+
+
+{- This file was modified by the EvilSplicer, adding these headers,
+ - and expanding Template Haskell.
+ -
+ - ** DO NOT COMMIT **
+ -}
+import qualified Data.Monoid
+import qualified Data.Set
+import qualified Data.Map
+import qualified Data.Map as Data.Map.Base
+import qualified Data.Foldable
+import qualified Data.Text
+import qualified Data.Text.Lazy.Builder
+import qualified Text.Shakespeare
+import qualified Text.Hamlet
+import qualified Text.Julius
+import qualified Text.Css
+import qualified "blaze-markup" Text.Blaze.Internal
+import qualified Yesod.Core.Widget
+import qualified Yesod.Routes.TH.Types
+import qualified Yesod.Routes.Dispatch
+import qualified WaiAppStatic.Storage.Embedded
+import qualified WaiAppStatic.Storage.Embedded.Runtime
+import qualified Data.FileEmbed
+import qualified Data.ByteString.Internal
+import qualified Data.Text.Encoding
+import qualified Network.Wai
+import qualified Yesod.Core.Types
+{- End EvilSplicer headers. -}
+
+
diff --git a/standalone/android/haskell-patches/DAV_build-without-TH.patch b/standalone/android/haskell-patches/DAV_build-without-TH.patch
new file mode 100644
index 000000000..b871fa9ef
--- /dev/null
+++ b/standalone/android/haskell-patches/DAV_build-without-TH.patch
@@ -0,0 +1,377 @@
+From 2b5fc33607720d0cccd7d8f9cb7232042ead73e6 Mon Sep 17 00:00:00 2001
+From: foo <foo@bar>
+Date: Sun, 22 Sep 2013 00:36:56 +0000
+Subject: [PATCH] expand TH
+
+used the EvilSplicer
++ manual fix ups
+---
+ DAV.cabal | 20 +--
+ Network/Protocol/HTTP/DAV.hs | 73 ++++++-----
+ Network/Protocol/HTTP/DAV/TH.hs | 196 +++++++++++++++++++++++++++-
+ dist/build/HSDAV-0.4.1.o | Bin 140080 -> 0 bytes
+ dist/build/Network/Protocol/HTTP/DAV.hi | Bin 34549 -> 57657 bytes
+ dist/build/Network/Protocol/HTTP/DAV.o | Bin 160248 -> 201932 bytes
+ dist/build/Network/Protocol/HTTP/DAV/TH.hi | Bin 17056 -> 18733 bytes
+ dist/build/Network/Protocol/HTTP/DAV/TH.o | Bin 19672 -> 28120 bytes
+ dist/build/autogen/Paths_DAV.hs | 18 ++-
+ dist/build/autogen/cabal_macros.h | 45 +++----
+ dist/build/libHSDAV-0.4.1.a | Bin 200082 -> 260188 bytes
+ dist/package.conf.inplace | 2 -
+ dist/setup-config | 2 -
+ 13 files changed, 266 insertions(+), 90 deletions(-)
+ delete mode 100644 dist/build/HSDAV-0.4.1.o
+ delete mode 100644 dist/package.conf.inplace
+ delete mode 100644 dist/setup-config
+
+diff --git a/DAV.cabal b/DAV.cabal
+index 06b3a8b..90368c6 100644
+--- a/DAV.cabal
++++ b/DAV.cabal
+@@ -38,25 +38,7 @@ library
+ , transformers >= 0.3
+ , xml-conduit >= 1.0 && <= 1.2
+ , xml-hamlet >= 0.4 && <= 0.5
+-executable hdav
+- main-is: hdav.hs
+- ghc-options: -Wall
+- build-depends: base >= 4.5 && <= 5
+- , bytestring
+- , bytestring
+- , case-insensitive >= 0.4
+- , containers
+- , http-conduit >= 1.9.0
+- , http-types >= 0.7
+- , lens >= 3.0
+- , lifted-base >= 0.1
+- , mtl >= 2.1
+- , network >= 2.3
+- , optparse-applicative
+- , resourcet >= 0.3
+- , transformers >= 0.3
+- , xml-conduit >= 1.0 && <= 1.2
+- , xml-hamlet >= 0.4 && <= 0.5
++ , text
+
+ source-repository head
+ type: git
+diff --git a/Network/Protocol/HTTP/DAV.hs b/Network/Protocol/HTTP/DAV.hs
+index 8ffc270..d064a8f 100644
+--- a/Network/Protocol/HTTP/DAV.hs
++++ b/Network/Protocol/HTTP/DAV.hs
+@@ -28,12 +28,12 @@ module Network.Protocol.HTTP.DAV (
+ , deleteContent
+ , moveContent
+ , makeCollection
+- , caldavReport
+ , module Network.Protocol.HTTP.DAV.TH
+ ) where
+
+ import Network.Protocol.HTTP.DAV.TH
+
++import qualified Data.Text
+ import Control.Applicative (liftA2)
+ import Control.Exception.Lifted (catchJust, finally, bracketOnError)
+ import Control.Lens ((.~), (^.))
+@@ -200,11 +200,6 @@ props2patch = XML.renderLBS XML.def . patch . props . fromDocument
+ , "{DAV:}supportedlock"
+ ]
+
+-caldavReportM :: MonadResourceBase m => DAVState m XML.Document
+-caldavReportM = do
+- let ahs = [(hContentType, "application/xml; charset=\"utf-8\"")]
+- calrresp <- davRequest "REPORT" ahs (xmlBody calendarquery)
+- return $ (XML.parseLBS_ def . responseBody) calrresp
+
+ getProps :: String -> B.ByteString -> B.ByteString -> Maybe Depth -> IO XML.Document
+ getProps url username password md = withDS url username password md getPropsM
+@@ -246,9 +241,6 @@ moveContent :: String -> B.ByteString -> B.ByteString -> B.ByteString -> IO ()
+ moveContent url newurl username password = withDS url username password Nothing $
+ moveContentM newurl
+
+-caldavReport :: String -> B.ByteString -> B.ByteString -> IO XML.Document
+-caldavReport url username password = withDS url username password (Just Depth1) $ caldavReportM
+-
+ -- | Creates a WebDAV collection, which is similar to a directory.
+ --
+ -- Returns False if the collection could not be made due to an intermediate
+@@ -264,28 +256,45 @@ makeCollection url username password = withDS url username password Nothing $
+ propname :: XML.Document
+ propname = XML.Document (XML.Prologue [] Nothing []) root []
+ where
+- root = XML.Element "D:propfind" (Map.fromList [("xmlns:D", "DAV:")]) [xml|
+-<D:allprop>
+-|]
+-
++ root = XML.Element "D:propfind" (Map.fromList [("xmlns:D", "DAV:")]) $ concat
++ [[XML.NodeElement
++ (XML.Element
++ (XML.Name
++ (Data.Text.pack "D:allprop") Nothing Nothing)
++ Map.empty
++ (concat []))]]
+ locky :: XML.Document
+ locky = XML.Document (XML.Prologue [] Nothing []) root []
+- where
+- root = XML.Element "D:lockinfo" (Map.fromList [("xmlns:D", "DAV:")]) [xml|
+-<D:lockscope>
+- <D:exclusive>
+-<D:locktype>
+- <D:write>
+-<D:owner>Haskell DAV user
+-|]
+-
+-calendarquery :: XML.Document
+-calendarquery = XML.Document (XML.Prologue [] Nothing []) root []
+- where
+- root = XML.Element "C:calendar-query" (Map.fromList [("xmlns:D", "DAV:"),("xmlns:C", "urn:ietf:params:xml:ns:caldav")]) [xml|
+-<D:prop>
+- <D:getetag>
+- <C:calendar-data>
+-<C:filter>
+- <C:comp-filter name="VCALENDAR">
+-|]
++ where
++ root = XML.Element "D:lockinfo" (Map.fromList [("xmlns:D", "DAV:")]) $ concat
++ [[XML.NodeElement
++ (XML.Element
++ (XML.Name
++ (Data.Text.pack "D:lockscope") Nothing Nothing)
++ Map.empty
++ (concat
++ [[XML.NodeElement
++ (XML.Element
++ (XML.Name
++ (Data.Text.pack "D:exclusive") Nothing Nothing)
++ Map.empty
++ (concat []))]]))],
++ [XML.NodeElement
++ (XML.Element
++ (XML.Name
++ (Data.Text.pack "D:locktype") Nothing Nothing)
++ Map.empty
++ (concat
++ [[XML.NodeElement
++ (XML.Element
++ (XML.Name (Data.Text.pack "D:write") Nothing Nothing)
++ Map.empty
++ (concat []))]]))],
++ [XML.NodeElement
++ (XML.Element
++ (XML.Name (Data.Text.pack "D:owner") Nothing Nothing)
++ Map.empty
++ (concat
++ [[XML.NodeContent
++ (Data.Text.pack "Haskell DAV user")]]))]]
++
+diff --git a/Network/Protocol/HTTP/DAV/TH.hs b/Network/Protocol/HTTP/DAV/TH.hs
+index 9fb3495..18b8df7 100644
+--- a/Network/Protocol/HTTP/DAV/TH.hs
++++ b/Network/Protocol/HTTP/DAV/TH.hs
+@@ -20,7 +20,8 @@
+
+ module Network.Protocol.HTTP.DAV.TH where
+
+-import Control.Lens (makeLenses)
++import qualified Control.Lens.Type
++import qualified Data.Functor
+ import qualified Data.ByteString as B
+ import Network.HTTP.Conduit (Manager, Request)
+
+@@ -46,4 +47,195 @@ data DAVContext a = DAVContext {
+ , _basicpassword :: B.ByteString
+ , _depth :: Maybe Depth
+ }
+-makeLenses ''DAVContext
++allowedMethods ::
++ Control.Lens.Type.Lens' (DAVContext a_a4I4) [B.ByteString]
++allowedMethods
++ _f_a5GM
++ (DAVContext __allowedMethods'_a5GN
++ __baseRequest_a5GP
++ __complianceClasses_a5GQ
++ __httpManager_a5GR
++ __lockToken_a5GS
++ __basicusername_a5GT
++ __basicpassword_a5GU
++ __depth_a5GV)
++ = ((\ __allowedMethods_a5GO
++ -> DAVContext
++ __allowedMethods_a5GO
++ __baseRequest_a5GP
++ __complianceClasses_a5GQ
++ __httpManager_a5GR
++ __lockToken_a5GS
++ __basicusername_a5GT
++ __basicpassword_a5GU
++ __depth_a5GV)
++ Data.Functor.<$> (_f_a5GM __allowedMethods'_a5GN))
++{-# INLINE allowedMethods #-}
++baseRequest ::
++ Control.Lens.Type.Lens (DAVContext a_a4I4) (DAVContext a_a5GW) (Request a_a4I4) (Request a_a5GW)
++baseRequest
++ _f_a5GX
++ (DAVContext __allowedMethods_a5GY
++ __baseRequest'_a5GZ
++ __complianceClasses_a5H1
++ __httpManager_a5H2
++ __lockToken_a5H3
++ __basicusername_a5H4
++ __basicpassword_a5H5
++ __depth_a5H6)
++ = ((\ __baseRequest_a5H0
++ -> DAVContext
++ __allowedMethods_a5GY
++ __baseRequest_a5H0
++ __complianceClasses_a5H1
++ __httpManager_a5H2
++ __lockToken_a5H3
++ __basicusername_a5H4
++ __basicpassword_a5H5
++ __depth_a5H6)
++ Data.Functor.<$> (_f_a5GX __baseRequest'_a5GZ))
++{-# INLINE baseRequest #-}
++basicpassword ::
++ Control.Lens.Type.Lens' (DAVContext a_a4I4) B.ByteString
++basicpassword
++ _f_a5H7
++ (DAVContext __allowedMethods_a5H8
++ __baseRequest_a5H9
++ __complianceClasses_a5Ha
++ __httpManager_a5Hb
++ __lockToken_a5Hc
++ __basicusername_a5Hd
++ __basicpassword'_a5He
++ __depth_a5Hg)
++ = ((\ __basicpassword_a5Hf
++ -> DAVContext
++ __allowedMethods_a5H8
++ __baseRequest_a5H9
++ __complianceClasses_a5Ha
++ __httpManager_a5Hb
++ __lockToken_a5Hc
++ __basicusername_a5Hd
++ __basicpassword_a5Hf
++ __depth_a5Hg)
++ Data.Functor.<$> (_f_a5H7 __basicpassword'_a5He))
++{-# INLINE basicpassword #-}
++basicusername ::
++ Control.Lens.Type.Lens' (DAVContext a_a4I4) B.ByteString
++basicusername
++ _f_a5Hh
++ (DAVContext __allowedMethods_a5Hi
++ __baseRequest_a5Hj
++ __complianceClasses_a5Hk
++ __httpManager_a5Hl
++ __lockToken_a5Hm
++ __basicusername'_a5Hn
++ __basicpassword_a5Hp
++ __depth_a5Hq)
++ = ((\ __basicusername_a5Ho
++ -> DAVContext
++ __allowedMethods_a5Hi
++ __baseRequest_a5Hj
++ __complianceClasses_a5Hk
++ __httpManager_a5Hl
++ __lockToken_a5Hm
++ __basicusername_a5Ho
++ __basicpassword_a5Hp
++ __depth_a5Hq)
++ Data.Functor.<$> (_f_a5Hh __basicusername'_a5Hn))
++{-# INLINE basicusername #-}
++complianceClasses ::
++ Control.Lens.Type.Lens' (DAVContext a_a4I4) [B.ByteString]
++complianceClasses
++ _f_a5Hr
++ (DAVContext __allowedMethods_a5Hs
++ __baseRequest_a5Ht
++ __complianceClasses'_a5Hu
++ __httpManager_a5Hw
++ __lockToken_a5Hx
++ __basicusername_a5Hy
++ __basicpassword_a5Hz
++ __depth_a5HA)
++ = ((\ __complianceClasses_a5Hv
++ -> DAVContext
++ __allowedMethods_a5Hs
++ __baseRequest_a5Ht
++ __complianceClasses_a5Hv
++ __httpManager_a5Hw
++ __lockToken_a5Hx
++ __basicusername_a5Hy
++ __basicpassword_a5Hz
++ __depth_a5HA)
++ Data.Functor.<$> (_f_a5Hr __complianceClasses'_a5Hu))
++{-# INLINE complianceClasses #-}
++depth ::
++ Control.Lens.Type.Lens' (DAVContext a_a4I4) (Maybe Depth)
++depth
++ _f_a5HB
++ (DAVContext __allowedMethods_a5HC
++ __baseRequest_a5HD
++ __complianceClasses_a5HE
++ __httpManager_a5HF
++ __lockToken_a5HG
++ __basicusername_a5HH
++ __basicpassword_a5HI
++ __depth'_a5HJ)
++ = ((\ __depth_a5HK
++ -> DAVContext
++ __allowedMethods_a5HC
++ __baseRequest_a5HD
++ __complianceClasses_a5HE
++ __httpManager_a5HF
++ __lockToken_a5HG
++ __basicusername_a5HH
++ __basicpassword_a5HI
++ __depth_a5HK)
++ Data.Functor.<$> (_f_a5HB __depth'_a5HJ))
++{-# INLINE depth #-}
++httpManager ::
++ Control.Lens.Type.Lens' (DAVContext a_a4I4) Manager
++httpManager
++ _f_a5HL
++ (DAVContext __allowedMethods_a5HM
++ __baseRequest_a5HN
++ __complianceClasses_a5HO
++ __httpManager'_a5HP
++ __lockToken_a5HR
++ __basicusername_a5HS
++ __basicpassword_a5HT
++ __depth_a5HU)
++ = ((\ __httpManager_a5HQ
++ -> DAVContext
++ __allowedMethods_a5HM
++ __baseRequest_a5HN
++ __complianceClasses_a5HO
++ __httpManager_a5HQ
++ __lockToken_a5HR
++ __basicusername_a5HS
++ __basicpassword_a5HT
++ __depth_a5HU)
++ Data.Functor.<$> (_f_a5HL __httpManager'_a5HP))
++{-# INLINE httpManager #-}
++lockToken ::
++ Control.Lens.Type.Lens' (DAVContext a_a4I4) (Maybe B.ByteString)
++lockToken
++ _f_a5HV
++ (DAVContext __allowedMethods_a5HW
++ __baseRequest_a5HX
++ __complianceClasses_a5HY
++ __httpManager_a5HZ
++ __lockToken'_a5I0
++ __basicusername_a5I2
++ __basicpassword_a5I3
++ __depth_a5I4)
++ = ((\ __lockToken_a5I1
++ -> DAVContext
++ __allowedMethods_a5HW
++ __baseRequest_a5HX
++ __complianceClasses_a5HY
++ __httpManager_a5HZ
++ __lockToken_a5I1
++ __basicusername_a5I2
++ __basicpassword_a5I3
++ __depth_a5I4)
++ Data.Functor.<$> (_f_a5HV __lockToken'_a5I0))
++{-# INLINE lockToken #-}
diff --git a/standalone/android/haskell-patches/HTTP_4000.2.8-0001-build-with-base-4.8.patch b/standalone/android/haskell-patches/HTTP_4000.2.8-0001-build-with-base-4.8.patch
new file mode 100644
index 000000000..dfcdc387f
--- /dev/null
+++ b/standalone/android/haskell-patches/HTTP_4000.2.8-0001-build-with-base-4.8.patch
@@ -0,0 +1,25 @@
+From 5c57c4ae7dac0c1aa940005f5ea55fdcd4fcd1f5 Mon Sep 17 00:00:00 2001
+From: foo <foo@bar>
+Date: Sat, 21 Sep 2013 22:46:42 +0000
+Subject: [PATCH] fix build with new base
+
+---
+ HTTP.cabal | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/HTTP.cabal b/HTTP.cabal
+index 76cb5d6..bb38f24 100644
+--- a/HTTP.cabal
++++ b/HTTP.cabal
+@@ -85,7 +85,7 @@ Library
+ Network.HTTP.Utils
+ Paths_HTTP
+ GHC-options: -fwarn-missing-signatures -Wall
+- Build-depends: base >= 2 && < 4.7, network < 2.5, parsec
++ Build-depends: base >= 2 && < 4.9, network < 2.5, parsec
+ Extensions: FlexibleInstances
+ if flag(old-base)
+ Build-depends: base < 3
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/MissingH_1.2.0.0_0001-fix-build-not-Android-specific.patch b/standalone/android/haskell-patches/MissingH_1.2.0.0_0001-fix-build-not-Android-specific.patch
new file mode 100644
index 000000000..50f641da7
--- /dev/null
+++ b/standalone/android/haskell-patches/MissingH_1.2.0.0_0001-fix-build-not-Android-specific.patch
@@ -0,0 +1,34 @@
+From 8c4220e4dd48ad197aa0ad49214e6e7bd768044e Mon Sep 17 00:00:00 2001
+From: Joey Hess <joey@kitenet.net>
+Date: Thu, 28 Feb 2013 23:28:57 -0400
+Subject: [PATCH] fix build (not Android specific)
+
+---
+ src/System/Cmd/Utils.hs | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/System/Cmd/Utils.hs b/src/System/Cmd/Utils.hs
+index a9fa46f..6c6aba2 100644
+--- a/src/System/Cmd/Utils.hs
++++ b/src/System/Cmd/Utils.hs
+@@ -325,7 +325,7 @@ forceSuccess (PipeHandle pid fp args funcname) =
+ Just (Exited (ExitSuccess)) -> return ()
+ Just (Exited (ExitFailure fc)) ->
+ cmdfailed funcname fp args fc
+- Just (Terminated sig) ->
++ Just (Terminated sig _) ->
+ warnfail fp args $ "Terminated by signal " ++ show sig
+ Just (Stopped sig) ->
+ warnfail fp args $ "Stopped by signal " ++ show sig
+@@ -351,7 +351,7 @@ safeSystem command args =
+ case ec of
+ Exited ExitSuccess -> return ()
+ Exited (ExitFailure fc) -> cmdfailed "safeSystem" command args fc
+- Terminated s -> cmdsignalled "safeSystem" command args s
++ Terminated s _ -> cmdsignalled "safeSystem" command args s
+ Stopped s -> cmdsignalled "safeSystem" command args s
+ #endif
+
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/MonadCatchIO-transformers_hack-to-get-to-build-with-new-ghc.patch b/standalone/android/haskell-patches/MonadCatchIO-transformers_hack-to-get-to-build-with-new-ghc.patch
new file mode 100644
index 000000000..9881d35d6
--- /dev/null
+++ b/standalone/android/haskell-patches/MonadCatchIO-transformers_hack-to-get-to-build-with-new-ghc.patch
@@ -0,0 +1,56 @@
+From 083c9d135ec68316db173235994c63603ad76444 Mon Sep 17 00:00:00 2001
+From: foo <foo@bar>
+Date: Sat, 21 Sep 2013 23:01:35 +0000
+Subject: [PATCH] hack to get to build with new ghc
+
+Copied the old implemenations of block and unblock from old Control.Exception
+since these deprecated functions have now been removed.
+---
+ MonadCatchIO-transformers.cabal | 2 +-
+ src/Control/Monad/CatchIO.hs | 13 +++++++++++--
+ 2 files changed, 12 insertions(+), 3 deletions(-)
+
+diff --git a/MonadCatchIO-transformers.cabal b/MonadCatchIO-transformers.cabal
+index fe6674d..b9f559f 100644
+--- a/MonadCatchIO-transformers.cabal
++++ b/MonadCatchIO-transformers.cabal
+@@ -26,4 +26,4 @@ Library
+ Exposed-Modules:
+ Control.Monad.CatchIO
+ Hs-Source-Dirs: src
+- Ghc-options: -Wall
++ Ghc-options: -Wall -fglasgow-exts
+diff --git a/src/Control/Monad/CatchIO.hs b/src/Control/Monad/CatchIO.hs
+index 62afb83..853996b 100644
+--- a/src/Control/Monad/CatchIO.hs
++++ b/src/Control/Monad/CatchIO.hs
+@@ -19,6 +19,9 @@ where
+ import Prelude hiding ( catch )
+ import Control.Applicative ((<$>))
+ import qualified Control.Exception.Extensible as E
++import qualified Control.Exception.Base as E
++import GHC.Base (maskAsyncExceptions#)
++import GHC.IO (unsafeUnmask, IO(..))
+
+ import Control.Monad.IO.Class (MonadIO,liftIO)
+
+@@ -51,8 +54,14 @@ class MonadIO m => MonadCatchIO m where
+
+ instance MonadCatchIO IO where
+ catch = E.catch
+- block = E.block
+- unblock = E.unblock
++ block = oldblock
++ unblock = oldunblock
++
++oldblock :: IO a -> IO a
++oldblock (IO io) = IO $ maskAsyncExceptions# io
++
++oldunblock :: IO a -> IO a
++oldunblock = unsafeUnmask
+
+ -- | Warning: this instance is somewhat contentious.
+ --
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/SafeSemaphore_fix-build-with-new-base.patch b/standalone/android/haskell-patches/SafeSemaphore_fix-build-with-new-base.patch
new file mode 100644
index 000000000..a79ca519a
--- /dev/null
+++ b/standalone/android/haskell-patches/SafeSemaphore_fix-build-with-new-base.patch
@@ -0,0 +1,36 @@
+From 010db89634eb0f64e7961581e65da3acbb2b9f3d Mon Sep 17 00:00:00 2001
+From: foo <foo@bar>
+Date: Sat, 21 Sep 2013 22:05:41 +0000
+Subject: [PATCH] fix build with new base
+
+---
+ src/Control/Concurrent/MSampleVar.hs | 6 +-----
+ 1 file changed, 1 insertion(+), 5 deletions(-)
+
+diff --git a/src/Control/Concurrent/MSampleVar.hs b/src/Control/Concurrent/MSampleVar.hs
+index d029c64..16ad6c5 100644
+--- a/src/Control/Concurrent/MSampleVar.hs
++++ b/src/Control/Concurrent/MSampleVar.hs
+@@ -30,7 +30,7 @@ module Control.Concurrent.MSampleVar
+ import Control.Monad(void,join)
+ import Control.Concurrent.MVar(MVar,newMVar,newEmptyMVar,tryTakeMVar,takeMVar,putMVar,withMVar,isEmptyMVar)
+ import Control.Exception(mask_)
+-import Data.Typeable(Typeable1(typeOf1),mkTyCon,mkTyConApp)
++import Data.Typeable(mkTyConApp)
+
+ -- |
+ -- Sample variables are slightly different from a normal 'MVar':
+@@ -62,10 +62,6 @@ data MSampleVar a = MSampleVar { readQueue :: MVar ()
+ , lockedStore :: MVar (MVar a) }
+ deriving (Eq)
+
+-instance Typeable1 MSampleVar where
+- typeOf1 _ = mkTyConApp tc []
+- where tc = mkTyCon "MSampleVar"
+-
+
+ -- | 'newEmptySV' allocates a new MSampleVar in an empty state. No futher
+ -- allocation is done when using the 'MSampleVar'.
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/async_fix-build-with-new-ghc.patch b/standalone/android/haskell-patches/async_fix-build-with-new-ghc.patch
new file mode 100644
index 000000000..727720ad4
--- /dev/null
+++ b/standalone/android/haskell-patches/async_fix-build-with-new-ghc.patch
@@ -0,0 +1,25 @@
+From 0035f0366e426af213244b2eb25ffb63cb9e74d0 Mon Sep 17 00:00:00 2001
+From: foo <foo@bar>
+Date: Sun, 22 Sep 2013 06:14:50 +0000
+Subject: [PATCH] fix build with new ghc
+
+---
+ async.cabal | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/async.cabal b/async.cabal
+index 8e47d9d..98e6312 100644
+--- a/async.cabal
++++ b/async.cabal
+@@ -70,7 +70,7 @@ source-repository head
+
+ library
+ exposed-modules: Control.Concurrent.Async
+- build-depends: base >= 4.3 && < 4.7, stm >= 2.2 && < 2.5
++ build-depends: base >= 4.3 && < 4.9, stm >= 2.2 && < 2.5
+
+ test-suite test-async
+ type: exitcode-stdio-1.0
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/bloomfilter_fix-build-with-newer-base.patch b/standalone/android/haskell-patches/bloomfilter_fix-build-with-newer-base.patch
new file mode 100644
index 000000000..d2f783a7f
--- /dev/null
+++ b/standalone/android/haskell-patches/bloomfilter_fix-build-with-newer-base.patch
@@ -0,0 +1,26 @@
+From 09bcaf4f203c39c967a6951d56fd015347bb5dae Mon Sep 17 00:00:00 2001
+From: foo <foo@bar>
+Date: Sat, 21 Sep 2013 21:57:21 +0000
+Subject: [PATCH] fix build with newer base
+
+---
+ Data/BloomFilter/Array.hs | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/Data/BloomFilter/Array.hs b/Data/BloomFilter/Array.hs
+index e085bbe..d94757a 100644
+--- a/Data/BloomFilter/Array.hs
++++ b/Data/BloomFilter/Array.hs
+@@ -3,7 +3,8 @@
+
+ module Data.BloomFilter.Array (newArray) where
+
+-import Control.Monad.ST (ST, unsafeIOToST)
++import Control.Monad.ST (ST)
++import Control.Monad.ST.Unsafe (unsafeIOToST)
+ import Data.Array.Base (MArray, STUArray(..), unsafeNewArray_)
+ #if __GLASGOW_HASKELL__ >= 704
+ import Foreign.C.Types (CInt(..), CSize(..))
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/comonad_cross-build.patch b/standalone/android/haskell-patches/comonad_cross-build.patch
new file mode 100644
index 000000000..ee8ae4268
--- /dev/null
+++ b/standalone/android/haskell-patches/comonad_cross-build.patch
@@ -0,0 +1,25 @@
+From 589c6a87ec62e35942c9a86ea8d91b443c80da99 Mon Sep 17 00:00:00 2001
+From: dummy <dummy@example.com>
+Date: Fri, 18 Oct 2013 23:07:02 +0000
+Subject: [PATCH] cross build
+
+---
+ comonad.cabal | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/comonad.cabal b/comonad.cabal
+index 5d34b13..756ed92 100644
+--- a/comonad.cabal
++++ b/comonad.cabal
+@@ -13,7 +13,7 @@ copyright: Copyright (C) 2008-2013 Edward A. Kmett,
+ Copyright (C) 2004-2008 Dave Menendez
+ synopsis: Comonads
+ description: Comonads
+-build-type: Custom
++build-type: Simple
+ extra-source-files:
+ .ghci
+ .gitignore
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/crypto-numbers_build-fix.patch b/standalone/android/haskell-patches/crypto-numbers_build-fix.patch
new file mode 100644
index 000000000..f8bdd1c39
--- /dev/null
+++ b/standalone/android/haskell-patches/crypto-numbers_build-fix.patch
@@ -0,0 +1,235 @@
+From f6ed5c3093111ffe0276f5b5bb6241783611ab1c Mon Sep 17 00:00:00 2001
+From: androidbuilder <androidbuilder@example.com>
+Date: Mon, 11 Nov 2013 01:54:25 +0000
+Subject: [PATCH] hack to build
+
+---
+ Crypto/Number/Basic.hs | 17 -----------------
+ Crypto/Number/ModArithmetic.hs | 29 -----------------------------
+ Crypto/Number/Prime.hs | 18 ------------------
+ crypto-numbers.cabal | 2 +-
+ 4 files changed, 1 insertion(+), 65 deletions(-)
+
+diff --git a/Crypto/Number/Basic.hs b/Crypto/Number/Basic.hs
+index af03052..5de8518 100644
+--- a/Crypto/Number/Basic.hs
++++ b/Crypto/Number/Basic.hs
+@@ -1,8 +1,5 @@
+ {-# LANGUAGE BangPatterns #-}
+ {-# LANGUAGE CPP #-}
+-#if MIN_VERSION_integer_gmp(0,5,1)
+-{-# LANGUAGE UnboxedTuples #-}
+-#endif
+ -- |
+ -- Module : Crypto.Number.Basic
+ -- License : BSD-style
+@@ -17,11 +14,7 @@ module Crypto.Number.Basic
+ , areEven
+ ) where
+
+-#if MIN_VERSION_integer_gmp(0,5,1)
+-import GHC.Integer.GMP.Internals
+-#else
+ import Data.Bits
+-#endif
+
+ -- | sqrti returns two integer (l,b) so that l <= sqrt i <= b
+ -- the implementation is quite naive, use an approximation for the first number
+@@ -60,25 +53,16 @@ sqrti i
+ -- gcde 'a' 'b' find (x,y,gcd(a,b)) where ax + by = d
+ --
+ gcde :: Integer -> Integer -> (Integer, Integer, Integer)
+-#if MIN_VERSION_integer_gmp(0,5,1)
+-gcde a b = (s, t, g)
+- where (# g, s #) = gcdExtInteger a b
+- t = (g - s * a) `div` b
+-#else
+ gcde a b = if d < 0 then (-x,-y,-d) else (x,y,d) where
+ (d, x, y) = f (a,1,0) (b,0,1)
+ f t (0, _, _) = t
+ f (a', sa, ta) t@(b', sb, tb) =
+ let (q, r) = a' `divMod` b' in
+ f t (r, sa - (q * sb), ta - (q * tb))
+-#endif
+
+ -- | get the extended GCD of two integer using the extended binary algorithm (HAC 14.61)
+ -- get (x,y,d) where d = gcd(a,b) and x,y satisfying ax + by = d
+ gcde_binary :: Integer -> Integer -> (Integer, Integer, Integer)
+-#if MIN_VERSION_integer_gmp(0,5,1)
+-gcde_binary = gcde
+-#else
+ gcde_binary a' b'
+ | b' == 0 = (1,0,a')
+ | a' >= b' = compute a' b'
+@@ -102,7 +86,6 @@ gcde_binary a' b'
+ in if u2 >= v2
+ then loop g x y (u2 - v2) v2 (a2 - c2) (b2 - d2) c2 d2
+ else loop g x y u2 (v2 - u2) a2 b2 (c2 - a2) (d2 - b2)
+-#endif
+
+ -- | check if a list of integer are all even
+ areEven :: [Integer] -> Bool
+diff --git a/Crypto/Number/ModArithmetic.hs b/Crypto/Number/ModArithmetic.hs
+index 031f477..38b22b7 100644
+--- a/Crypto/Number/ModArithmetic.hs
++++ b/Crypto/Number/ModArithmetic.hs
+@@ -26,12 +26,8 @@ module Crypto.Number.ModArithmetic
+ import Control.Exception (throw, Exception)
+ import Data.Typeable
+
+-#if MIN_VERSION_integer_gmp(0,5,1)
+-import GHC.Integer.GMP.Internals
+-#else
+ import Crypto.Number.Basic (gcde_binary)
+ import Data.Bits
+-#endif
+
+ -- | Raised when two numbers are supposed to be coprimes but are not.
+ data CoprimesAssertionError = CoprimesAssertionError
+@@ -52,13 +48,7 @@ expSafe :: Integer -- ^ base
+ -> Integer -- ^ exponant
+ -> Integer -- ^ modulo
+ -> Integer -- ^ result
+-#if MIN_VERSION_integer_gmp(0,5,1)
+-expSafe b e m
+- | odd m = powModSecInteger b e m
+- | otherwise = powModInteger b e m
+-#else
+ expSafe = exponentiation
+-#endif
+
+ -- | Compute the modular exponentiation of base^exponant using
+ -- the fastest algorithm without any consideration for
+@@ -71,11 +61,7 @@ expFast :: Integer -- ^ base
+ -> Integer -- ^ modulo
+ -> Integer -- ^ result
+ expFast =
+-#if MIN_VERSION_integer_gmp(0,5,1)
+- powModInteger
+-#else
+ exponentiation
+-#endif
+
+ -- note on exponentiation: 0^0 is treated as 1 for mimicking the standard library;
+ -- the mathematic debate is still open on whether or not this is true, but pratically
+@@ -84,22 +70,15 @@ expFast =
+ -- | exponentiation_rtl_binary computes modular exponentiation as b^e mod m
+ -- using the right-to-left binary exponentiation algorithm (HAC 14.79)
+ exponentiation_rtl_binary :: Integer -> Integer -> Integer -> Integer
+-#if MIN_VERSION_integer_gmp(0,5,1)
+-exponentiation_rtl_binary = expSafe
+-#else
+ exponentiation_rtl_binary 0 0 m = 1 `mod` m
+ exponentiation_rtl_binary b e m = loop e b 1
+ where sq x = (x * x) `mod` m
+ loop !0 _ !a = a `mod` m
+ loop !i !s !a = loop (i `shiftR` 1) (sq s) (if odd i then a * s else a)
+-#endif
+
+ -- | exponentiation computes modular exponentiation as b^e mod m
+ -- using repetitive squaring.
+ exponentiation :: Integer -> Integer -> Integer -> Integer
+-#if MIN_VERSION_integer_gmp(0,5,1)
+-exponentiation = expSafe
+-#else
+ exponentiation b e m
+ | b == 1 = b
+ | e == 0 = 1
+@@ -107,7 +86,6 @@ exponentiation b e m
+ | even e = let p = (exponentiation b (e `div` 2) m) `mod` m
+ in (p^(2::Integer)) `mod` m
+ | otherwise = (b * exponentiation b (e-1) m) `mod` m
+-#endif
+
+ --{-# DEPRECATED exponantiation_rtl_binary "typo in API name it's called exponentiation_rtl_binary #-}
+ exponantiation_rtl_binary :: Integer -> Integer -> Integer -> Integer
+@@ -119,17 +97,10 @@ exponantiation = exponentiation
+
+ -- | inverse computes the modular inverse as in g^(-1) mod m
+ inverse :: Integer -> Integer -> Maybe Integer
+-#if MIN_VERSION_integer_gmp(0,5,1)
+-inverse g m
+- | r == 0 = Nothing
+- | otherwise = Just r
+- where r = recipModInteger g m
+-#else
+ inverse g m
+ | d > 1 = Nothing
+ | otherwise = Just (x `mod` m)
+ where (x,_,d) = gcde_binary g m
+-#endif
+
+ -- | Compute the modular inverse of 2 coprime numbers.
+ -- This is equivalent to inverse except that the result
+diff --git a/Crypto/Number/Prime.hs b/Crypto/Number/Prime.hs
+index 2060f4d..61d37c0 100644
+--- a/Crypto/Number/Prime.hs
++++ b/Crypto/Number/Prime.hs
+@@ -1,8 +1,6 @@
+ {-# LANGUAGE CPP #-}
+ {-# LANGUAGE BangPatterns #-}
+-#if MIN_VERSION_integer_gmp(0,5,1)
+ {-# LANGUAGE MagicHash #-}
+-#endif
+ -- |
+ -- Module : Crypto.Number.Prime
+ -- License : BSD-style
+@@ -27,12 +25,7 @@ import Crypto.Number.Generate
+ import Crypto.Number.Basic (sqrti, gcde_binary)
+ import Crypto.Number.ModArithmetic (exponantiation)
+
+-#if MIN_VERSION_integer_gmp(0,5,1)
+-import GHC.Integer.GMP.Internals
+-import GHC.Base
+-#else
+ import Data.Bits
+-#endif
+
+ -- | returns if the number is probably prime.
+ -- first a list of small primes are implicitely tested for divisibility,
+@@ -75,21 +68,11 @@ findPrimeFromWith rng prop !n
+ -- | find a prime from a starting point with no specific property.
+ findPrimeFrom :: CPRG g => g -> Integer -> (Integer, g)
+ findPrimeFrom rng n =
+-#if MIN_VERSION_integer_gmp(0,5,1)
+- (nextPrimeInteger n, rng)
+-#else
+ findPrimeFromWith rng (\g _ -> (True, g)) n
+-#endif
+
+ -- | Miller Rabin algorithm return if the number is probably prime or composite.
+ -- the tries parameter is the number of recursion, that determines the accuracy of the test.
+ primalityTestMillerRabin :: CPRG g => g -> Int -> Integer -> (Bool, g)
+-#if MIN_VERSION_integer_gmp(0,5,1)
+-primalityTestMillerRabin rng (I# tries) !n =
+- case testPrimeInteger n tries of
+- 0# -> (False, rng)
+- _ -> (True, rng)
+-#else
+ primalityTestMillerRabin rng tries !n
+ | n <= 3 = error "Miller-Rabin requires tested value to be > 3"
+ | even n = (False, rng)
+@@ -126,7 +109,6 @@ primalityTestMillerRabin rng tries !n
+ | x2 == 1 = False
+ | x2 /= nm1 = loop' ws ((x2*x2) `mod` n) (r+1)
+ | otherwise = loop ws
+-#endif
+
+ {-
+ n < z -> witness to test
+diff --git a/crypto-numbers.cabal b/crypto-numbers.cabal
+index 05c00c1..8da5e2a 100644
+--- a/crypto-numbers.cabal
++++ b/crypto-numbers.cabal
+@@ -15,7 +15,7 @@ Extra-Source-Files: Tests/*.hs
+
+ Flag integer-gmp
+ Description: Are we using integer-gmp?
+- Default: True
++ Default: False
+
+ Library
+ Build-Depends: base >= 4 && < 5
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/distributive_0.3-0001-fixes-for-cross-build.patch b/standalone/android/haskell-patches/distributive_0.3-0001-fixes-for-cross-build.patch
new file mode 100644
index 000000000..4859be9a4
--- /dev/null
+++ b/standalone/android/haskell-patches/distributive_0.3-0001-fixes-for-cross-build.patch
@@ -0,0 +1,25 @@
+From 6cd7b7d3a8e38ada9b1e3989770525c63f9f1d7d Mon Sep 17 00:00:00 2001
+From: androidbuilder <androidbuilder@example.com>
+Date: Fri, 18 Oct 2013 23:10:16 +0000
+Subject: [PATCH] cross build
+
+---
+ distributive.cabal | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/distributive.cabal b/distributive.cabal
+index 5d4ac69..82d7593 100644
+--- a/distributive.cabal
++++ b/distributive.cabal
+@@ -12,7 +12,7 @@ bug-reports: http://github.com/ekmett/distributive/issues
+ copyright: Copyright (C) 2011-2013 Edward A. Kmett
+ synopsis: Haskell 98 Distributive functors -- Dual to Traversable
+ description: Haskell 98 Distributive functors -- Dual to Traversable
+-build-type: Custom
++build-type: Simple
+ extra-source-files:
+ .ghci
+ .travis.yml
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/entropy_cross-build.patch b/standalone/android/haskell-patches/entropy_cross-build.patch
new file mode 100644
index 000000000..5e09fdc8f
--- /dev/null
+++ b/standalone/android/haskell-patches/entropy_cross-build.patch
@@ -0,0 +1,25 @@
+From 10da50b5eea1e615af1d3b242f422ad278c9f268 Mon Sep 17 00:00:00 2001
+From: dummy <dummy@example.com>
+Date: Fri, 18 Oct 2013 23:16:41 +0000
+Subject: [PATCH] cross build
+
+---
+ entropy.cabal | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/entropy.cabal b/entropy.cabal
+index e69dec4..4fa3774 100644
+--- a/entropy.cabal
++++ b/entropy.cabal
+@@ -14,7 +14,7 @@ category: Data, Cryptography
+ homepage: https://github.com/TomMD/entropy
+ bug-reports: https://github.com/TomMD/entropy/issues
+ stability: stable
+-build-type: Custom
++build-type: Simple
+ cabal-version: >=1.10
+ tested-with: GHC == 7.6.3
+ -- data-files:
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/gnuidn_fix-build-with-new-base.patch b/standalone/android/haskell-patches/gnuidn_fix-build-with-new-base.patch
new file mode 100644
index 000000000..ff9d8f245
--- /dev/null
+++ b/standalone/android/haskell-patches/gnuidn_fix-build-with-new-base.patch
@@ -0,0 +1,50 @@
+From afdec6c9e66211a0ac8419fffe191b059d1fd00c Mon Sep 17 00:00:00 2001
+From: foo <foo@bar>
+Date: Sun, 22 Sep 2013 17:24:33 +0000
+Subject: [PATCH] fix build with new base
+
+---
+ Data/Text/IDN/IDNA.chs | 1 +
+ Data/Text/IDN/Punycode.chs | 1 +
+ Data/Text/IDN/StringPrep.chs | 1 +
+ 3 files changed, 3 insertions(+)
+
+diff --git a/Data/Text/IDN/IDNA.chs b/Data/Text/IDN/IDNA.chs
+index ed29ee4..dbb4ba5 100644
+--- a/Data/Text/IDN/IDNA.chs
++++ b/Data/Text/IDN/IDNA.chs
+@@ -31,6 +31,7 @@ import Foreign
+ import Foreign.C
+
+ import Data.Text.IDN.Internal
++import System.IO.Unsafe
+
+ #include <idna.h>
+ #include <idn-free.h>
+diff --git a/Data/Text/IDN/Punycode.chs b/Data/Text/IDN/Punycode.chs
+index 24b5fa6..4e62555 100644
+--- a/Data/Text/IDN/Punycode.chs
++++ b/Data/Text/IDN/Punycode.chs
+@@ -32,6 +32,7 @@ import Data.List (unfoldr)
+ import qualified Data.ByteString as B
+ import qualified Data.Text as T
+
++import System.IO.Unsafe
+ import Foreign
+ import Foreign.C
+
+diff --git a/Data/Text/IDN/StringPrep.chs b/Data/Text/IDN/StringPrep.chs
+index 752dc9e..5e9fd84 100644
+--- a/Data/Text/IDN/StringPrep.chs
++++ b/Data/Text/IDN/StringPrep.chs
+@@ -39,6 +39,7 @@ import qualified Data.ByteString as B
+ import qualified Data.Text as T
+ import qualified Data.Text.Encoding as TE
+
++import System.IO.Unsafe
+ import Foreign
+ import Foreign.C
+
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/gnutls_0.1.4-0001-statically-link-with-gnutls.patch b/standalone/android/haskell-patches/gnutls_0.1.4-0001-statically-link-with-gnutls.patch
new file mode 100644
index 000000000..24f17cc6f
--- /dev/null
+++ b/standalone/android/haskell-patches/gnutls_0.1.4-0001-statically-link-with-gnutls.patch
@@ -0,0 +1,37 @@
+From 67435289745b2f96fc9d1cd8e0263ef0565e4789 Mon Sep 17 00:00:00 2001
+From: Joey Hess <joey@kitenet.net>
+Date: Tue, 26 Nov 2013 19:18:28 +0000
+Subject: [PATCH] hack gnutls to statically link
+
+This uses a hardcoded path to the library, which includes the
+arm-linux-androideabi-4.8 part. Will need to be changed when that changes..
+---
+ gnutls.cabal | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/gnutls.cabal b/gnutls.cabal
+index 5bfe687..ff1d08c 100644
+--- a/gnutls.cabal
++++ b/gnutls.cabal
+@@ -31,16 +31,14 @@ source-repository this
+ library
+ hs-source-dirs: lib
+ ghc-options: -Wall -O2
++ LD-Options: -L /home/androidbuilder/.ghc/android-14/arm-linux-androideabi-4.8/sysroot/usr/lib/ -l:libgnutls.a -l:libnettle.a -l:libhogweed.a -l:libgmp.a
+
+ build-depends:
+ base >= 4.0 && < 5.0
+- , bytestring >= 0.9
++ , bytestring >= 0.10.3.0
+ , transformers >= 0.2
+ , monads-tf >= 0.1 && < 0.2
+
+- extra-libraries: gnutls
+- pkgconfig-depends: gnutls
+-
+ exposed-modules:
+ Network.Protocol.TLS.GNU
+
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/gsasl_0.3.5-0001-link-with-libgsasl.patch b/standalone/android/haskell-patches/gsasl_0.3.5-0001-link-with-libgsasl.patch
new file mode 100644
index 000000000..42206a1cf
--- /dev/null
+++ b/standalone/android/haskell-patches/gsasl_0.3.5-0001-link-with-libgsasl.patch
@@ -0,0 +1,25 @@
+From df0f41f92d003f7d59ef927737ffec3a9bd61827 Mon Sep 17 00:00:00 2001
+From: Joey Hess <joey@kitenet.net>
+Date: Tue, 7 May 2013 18:41:01 -0400
+Subject: [PATCH] avoid cabal hell
+
+---
+ gsasl.cabal | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/gsasl.cabal b/gsasl.cabal
+index d991873..c5c2b19 100644
+--- a/gsasl.cabal
++++ b/gsasl.cabal
+@@ -31,7 +31,7 @@ library
+ build-depends:
+ base >= 4.0 && < 5.0
+ , transformers >= 0.2
+- , bytestring >= 0.9
++ , bytestring >= 0.10.3.0
+
+ pkgconfig-depends: libgsasl >= 1.1
+
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/iproute_1.2.11_0001-build-without-IPv6-stuff.patch b/standalone/android/haskell-patches/iproute_1.2.11_0001-build-without-IPv6-stuff.patch
new file mode 100644
index 000000000..bb9caec77
--- /dev/null
+++ b/standalone/android/haskell-patches/iproute_1.2.11_0001-build-without-IPv6-stuff.patch
@@ -0,0 +1,47 @@
+From 7beec2e707d59f9573aa2dc7c57bd2a62f16b480 Mon Sep 17 00:00:00 2001
+From: Joey Hess <joey@kitenet.net>
+Date: Wed, 15 May 2013 19:06:03 -0400
+Subject: [PATCH] build without IPv6 stuff
+
+---
+ Data/IP.hs | 2 +-
+ Data/IP/Addr.hs | 3 +++
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/Data/IP.hs b/Data/IP.hs
+index cffef93..ea486c9 100644
+--- a/Data/IP.hs
++++ b/Data/IP.hs
+@@ -6,7 +6,7 @@ module Data.IP (
+ -- ** IP data
+ IP (..)
+ , IPv4, toIPv4, fromIPv4, fromHostAddress, toHostAddress
+- , IPv6, toIPv6, fromIPv6, fromHostAddress6, toHostAddress6
++ , IPv6, toIPv6, fromIPv6 -- , fromHostAddress6, toHostAddress6
+ -- ** IP range data
+ , IPRange (..)
+ , AddrRange (addr, mask, mlen)
+diff --git a/Data/IP/Addr.hs b/Data/IP/Addr.hs
+index faaf0c7..5b556fb 100644
+--- a/Data/IP/Addr.hs
++++ b/Data/IP/Addr.hs
+@@ -312,6 +312,7 @@ toHostAddress (IP4 addr4)
+ | byteOrder == LittleEndian = fixByteOrder addr4
+ | otherwise = addr4
+
++{-
+ -- | The 'fromHostAddress6' function converts 'HostAddress6' to 'IPv6'.
+ fromHostAddress6 :: HostAddress6 -> IPv6
+ fromHostAddress6 = IP6
+@@ -320,6 +321,8 @@ fromHostAddress6 = IP6
+ toHostAddress6 :: IPv6 -> HostAddress6
+ toHostAddress6 (IP6 addr6) = addr6
+
++-}
++
+ fixByteOrder :: Word32 -> Word32
+ fixByteOrder s = d1 .|. d2 .|. d3 .|. d4
+ where
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/language-javascript_fix-build-with-new-ghc.patch b/standalone/android/haskell-patches/language-javascript_fix-build-with-new-ghc.patch
new file mode 100644
index 000000000..6182cba44
--- /dev/null
+++ b/standalone/android/haskell-patches/language-javascript_fix-build-with-new-ghc.patch
@@ -0,0 +1,25 @@
+From cb5252db1a0d515da69d9167a8b2facd839940b2 Mon Sep 17 00:00:00 2001
+From: androidbuilder <androidbuilder@example.com>
+Date: Mon, 11 Nov 2013 02:29:06 +0000
+Subject: [PATCH] fix build with new ghc
+
+---
+ src/Language/JavaScript/Parser/Lexer.hs | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/Language/JavaScript/Parser/Lexer.hs b/src/Language/JavaScript/Parser/Lexer.hs
+index 79fa9c5..fa96e29 100644
+--- a/src/Language/JavaScript/Parser/Lexer.hs
++++ b/src/Language/JavaScript/Parser/Lexer.hs
+@@ -712,7 +712,7 @@ alex_scan_tkn user orig_input len input s last_acc =
+ (offset) = (base +# ord_c)
+ (check) = alexIndexInt16OffAddr alex_check offset
+
+- (new_s) = if (offset >=# 0#) && (check ==# ord_c)
++ (new_s) = if (tagToEnum# (offset >=# 0#)) && (tagToEnum# (check ==# ord_c))
+ then alexIndexInt16OffAddr alex_table offset
+ else alexIndexInt16OffAddr alex_deflt s
+ in
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/lens_various-hacking-to-cross-build.patch b/standalone/android/haskell-patches/lens_various-hacking-to-cross-build.patch
new file mode 100644
index 000000000..274efc71e
--- /dev/null
+++ b/standalone/android/haskell-patches/lens_various-hacking-to-cross-build.patch
@@ -0,0 +1,385 @@
+From 41706061810410cc38f602ccc9a4c9560502251f Mon Sep 17 00:00:00 2001
+From: dummy <dummy@example.com>
+Date: Sat, 19 Oct 2013 01:44:52 +0000
+Subject: [PATCH] hackity
+
+---
+ lens.cabal | 12 +-----------
+ src/Control/Exception/Lens.hs | 2 +-
+ src/Control/Lens.hs | 6 +++---
+ src/Control/Lens/Equality.hs | 4 ++--
+ src/Control/Lens/Fold.hs | 6 +++---
+ src/Control/Lens/Internal.hs | 2 +-
+ src/Control/Lens/Internal/Exception.hs | 26 +-------------------------
+ src/Control/Lens/Internal/Instances.hs | 14 --------------
+ src/Control/Lens/Internal/Zipper.hs | 2 +-
+ src/Control/Lens/Iso.hs | 2 --
+ src/Control/Lens/Lens.hs | 2 +-
+ src/Control/Lens/Operators.hs | 2 +-
+ src/Control/Lens/Plated.hs | 2 +-
+ src/Control/Lens/Prism.hs | 2 --
+ src/Control/Lens/Setter.hs | 2 --
+ src/Control/Lens/TH.hs | 2 +-
+ src/Data/Data/Lens.hs | 6 +++---
+ 17 files changed, 20 insertions(+), 74 deletions(-)
+
+diff --git a/lens.cabal b/lens.cabal
+index b25adf4..3e5c30c 100644
+--- a/lens.cabal
++++ b/lens.cabal
+@@ -10,7 +10,7 @@ stability: provisional
+ homepage: http://github.com/ekmett/lens/
+ bug-reports: http://github.com/ekmett/lens/issues
+ copyright: Copyright (C) 2012-2013 Edward A. Kmett
+-build-type: Custom
++build-type: Simple
+ tested-with: GHC == 7.6.3
+ synopsis: Lenses, Folds and Traversals
+ description:
+@@ -235,14 +235,12 @@ library
+ Control.Lens.Review
+ Control.Lens.Setter
+ Control.Lens.Simple
+- Control.Lens.TH
+ Control.Lens.Traversal
+ Control.Lens.Tuple
+ Control.Lens.Type
+ Control.Lens.Wrapped
+ Control.Lens.Zipper
+ Control.Lens.Zoom
+- Control.Monad.Error.Lens
+ Control.Parallel.Strategies.Lens
+ Control.Seq.Lens
+ Data.Array.Lens
+@@ -266,12 +264,8 @@ library
+ Data.Typeable.Lens
+ Data.Vector.Lens
+ Data.Vector.Generic.Lens
+- Generics.Deriving.Lens
+- GHC.Generics.Lens
+ System.Exit.Lens
+ System.FilePath.Lens
+- System.IO.Error.Lens
+- Language.Haskell.TH.Lens
+ Numeric.Lens
+
+ if flag(safe)
+@@ -370,7 +364,6 @@ test-suite doctests
+ deepseq,
+ doctest >= 0.9.1,
+ filepath,
+- generic-deriving,
+ mtl,
+ nats,
+ parallel,
+@@ -396,7 +389,6 @@ benchmark plated
+ comonad,
+ criterion,
+ deepseq,
+- generic-deriving,
+ lens,
+ transformers
+
+@@ -431,7 +423,6 @@ benchmark unsafe
+ comonads-fd,
+ criterion,
+ deepseq,
+- generic-deriving,
+ lens,
+ transformers
+
+@@ -448,6 +439,5 @@ benchmark zipper
+ comonads-fd,
+ criterion,
+ deepseq,
+- generic-deriving,
+ lens,
+ transformers
+diff --git a/src/Control/Exception/Lens.hs b/src/Control/Exception/Lens.hs
+index 0619335..c97ad9b 100644
+--- a/src/Control/Exception/Lens.hs
++++ b/src/Control/Exception/Lens.hs
+@@ -112,7 +112,7 @@ import Prelude
+ , Maybe(..), Either(..), Functor(..), String, IO
+ )
+
+-{-# ANN module "HLint: ignore Use Control.Exception.catch" #-}
++
+
+ -- $setup
+ -- >>> :set -XNoOverloadedStrings
+diff --git a/src/Control/Lens.hs b/src/Control/Lens.hs
+index 242c3c1..2ab9cdb 100644
+--- a/src/Control/Lens.hs
++++ b/src/Control/Lens.hs
+@@ -59,7 +59,7 @@ module Control.Lens
+ , module Control.Lens.Review
+ , module Control.Lens.Setter
+ , module Control.Lens.Simple
+-#ifndef DISABLE_TEMPLATE_HASKELL
++#if 0
+ , module Control.Lens.TH
+ #endif
+ , module Control.Lens.Traversal
+@@ -89,7 +89,7 @@ import Control.Lens.Reified
+ import Control.Lens.Review
+ import Control.Lens.Setter
+ import Control.Lens.Simple
+-#ifndef DISABLE_TEMPLATE_HASKELL
++#if 0
+ import Control.Lens.TH
+ #endif
+ import Control.Lens.Traversal
+@@ -99,4 +99,4 @@ import Control.Lens.Wrapped
+ import Control.Lens.Zipper
+ import Control.Lens.Zoom
+
+-{-# ANN module "HLint: ignore Use import/export shortcut" #-}
++
+diff --git a/src/Control/Lens/Equality.hs b/src/Control/Lens/Equality.hs
+index 982c2d7..3a3fe1a 100644
+--- a/src/Control/Lens/Equality.hs
++++ b/src/Control/Lens/Equality.hs
+@@ -28,8 +28,8 @@ module Control.Lens.Equality
+ import Control.Lens.Internal.Setter
+ import Control.Lens.Type
+
+-{-# ANN module "HLint: ignore Use id" #-}
+-{-# ANN module "HLint: ignore Eta reduce" #-}
++
++
+
+ -- $setup
+ -- >>> import Control.Lens
+diff --git a/src/Control/Lens/Fold.hs b/src/Control/Lens/Fold.hs
+index 32a4073..cc7da1e 100644
+--- a/src/Control/Lens/Fold.hs
++++ b/src/Control/Lens/Fold.hs
+@@ -163,9 +163,9 @@ import Data.Traversable
+ -- >>> let g :: Expr -> Expr; g = Debug.SimpleReflect.Vars.g
+ -- >>> let timingOut :: NFData a => a -> IO a; timingOut = fmap (fromMaybe (error "timeout")) . timeout (5*10^6) . evaluate . force
+
+-{-# ANN module "HLint: ignore Eta reduce" #-}
+-{-# ANN module "HLint: ignore Use camelCase" #-}
+-{-# ANN module "HLint: ignore Use curry" #-}
++
++
++
+
+ infixl 8 ^.., ^?, ^?!, ^@.., ^@?, ^@?!
+
+diff --git a/src/Control/Lens/Internal.hs b/src/Control/Lens/Internal.hs
+index 295662e..539642d 100644
+--- a/src/Control/Lens/Internal.hs
++++ b/src/Control/Lens/Internal.hs
+@@ -43,4 +43,4 @@ import Control.Lens.Internal.Review
+ import Control.Lens.Internal.Setter
+ import Control.Lens.Internal.Zoom
+
+-{-# ANN module "HLint: ignore Use import/export shortcut" #-}
++
+diff --git a/src/Control/Lens/Internal/Exception.hs b/src/Control/Lens/Internal/Exception.hs
+index 387203e..8bea89b 100644
+--- a/src/Control/Lens/Internal/Exception.hs
++++ b/src/Control/Lens/Internal/Exception.hs
+@@ -36,6 +36,7 @@ import Data.Monoid
+ import Data.Proxy
+ import Data.Reflection
+ import Data.Typeable
++import Data.Typeable
+ import System.IO.Unsafe
+
+ ------------------------------------------------------------------------------
+@@ -128,18 +129,6 @@ class Handleable e (m :: * -> *) (h :: * -> *) | h -> e m where
+ handler_ l = handler l . const
+ {-# INLINE handler_ #-}
+
+-instance Handleable SomeException IO Exception.Handler where
+- handler = handlerIO
+-
+-instance Handleable SomeException m (CatchIO.Handler m) where
+- handler = handlerCatchIO
+-
+-handlerIO :: forall a r. Getting (First a) SomeException a -> (a -> IO r) -> Exception.Handler r
+-handlerIO l f = reify (preview l) $ \ (_ :: Proxy s) -> Exception.Handler (\(Handling a :: Handling a s IO) -> f a)
+-
+-handlerCatchIO :: forall m a r. Getting (First a) SomeException a -> (a -> m r) -> CatchIO.Handler m r
+-handlerCatchIO l f = reify (preview l) $ \ (_ :: Proxy s) -> CatchIO.Handler (\(Handling a :: Handling a s m) -> f a)
+-
+ ------------------------------------------------------------------------------
+ -- Helpers
+ ------------------------------------------------------------------------------
+@@ -159,21 +148,8 @@ supply = unsafePerformIO $ newIORef 0
+ -- | This permits the construction of an \"impossible\" 'Control.Exception.Handler' that matches only if some function does.
+ newtype Handling a s (m :: * -> *) = Handling a
+
+--- the m parameter exists simply to break the Typeable1 pattern, so we can provide this without overlap.
+--- here we simply generate a fresh TypeRep so we'll fail to compare as equal to any other TypeRep.
+-instance Typeable (Handling a s m) where
+- typeOf _ = unsafePerformIO $ do
+- i <- atomicModifyIORef supply $ \a -> let a' = a + 1 in a' `seq` (a', a)
+- return $ mkTyConApp (mkTyCon3 "lens" "Control.Lens.Internal.Exception" ("Handling" ++ show i)) []
+- {-# INLINE typeOf #-}
+-
+ -- The @Handling@ wrapper is uninteresting, and should never be thrown, so you won't get much benefit here.
+ instance Show (Handling a s m) where
+ showsPrec d _ = showParen (d > 10) $ showString "Handling ..."
+ {-# INLINE showsPrec #-}
+
+-instance Reifies s (SomeException -> Maybe a) => Exception (Handling a s m) where
+- toException _ = SomeException HandlingException
+- {-# INLINE toException #-}
+- fromException = fmap Handling . reflect (Proxy :: Proxy s)
+- {-# INLINE fromException #-}
+diff --git a/src/Control/Lens/Internal/Instances.hs b/src/Control/Lens/Internal/Instances.hs
+index 6783f33..17715ce 100644
+--- a/src/Control/Lens/Internal/Instances.hs
++++ b/src/Control/Lens/Internal/Instances.hs
+@@ -24,26 +24,12 @@ import Data.Traversable
+ -- Orphan Instances
+ -------------------------------------------------------------------------------
+
+-instance Foldable ((,) b) where
+- foldMap f (_, a) = f a
+-
+ instance Foldable1 ((,) b) where
+ foldMap1 f (_, a) = f a
+
+-instance Traversable ((,) b) where
+- traverse f (b, a) = (,) b <$> f a
+-
+ instance Traversable1 ((,) b) where
+ traverse1 f (b, a) = (,) b <$> f a
+
+-instance Foldable (Either a) where
+- foldMap _ (Left _) = mempty
+- foldMap f (Right a) = f a
+-
+-instance Traversable (Either a) where
+- traverse _ (Left b) = pure (Left b)
+- traverse f (Right a) = Right <$> f a
+-
+ instance Foldable (Const m) where
+ foldMap _ _ = mempty
+
+diff --git a/src/Control/Lens/Internal/Zipper.hs b/src/Control/Lens/Internal/Zipper.hs
+index 95875b7..76060be 100644
+--- a/src/Control/Lens/Internal/Zipper.hs
++++ b/src/Control/Lens/Internal/Zipper.hs
+@@ -53,7 +53,7 @@ import Data.Profunctor.Unsafe
+ -- >>> import Control.Lens
+ -- >>> import Data.Char
+
+-{-# ANN module "HLint: ignore Use foldl" #-}
++
+
+ ------------------------------------------------------------------------------
+ -- * Jacket
+diff --git a/src/Control/Lens/Iso.hs b/src/Control/Lens/Iso.hs
+index 1152af4..80c3175 100644
+--- a/src/Control/Lens/Iso.hs
++++ b/src/Control/Lens/Iso.hs
+@@ -82,8 +82,6 @@ import Data.Maybe
+ import Data.Profunctor
+ import Data.Profunctor.Unsafe
+
+-{-# ANN module "HLint: ignore Use on" #-}
+-
+ -- $setup
+ -- >>> :set -XNoOverloadedStrings
+ -- >>> import Control.Lens
+diff --git a/src/Control/Lens/Lens.hs b/src/Control/Lens/Lens.hs
+index b26cc06..6f84943 100644
+--- a/src/Control/Lens/Lens.hs
++++ b/src/Control/Lens/Lens.hs
+@@ -126,7 +126,7 @@ import Data.Profunctor.Rep
+ import Data.Profunctor.Unsafe
+ import Data.Void
+
+-{-# ANN module "HLint: ignore Use ***" #-}
++
+
+ -- $setup
+ -- >>> :set -XNoOverloadedStrings
+diff --git a/src/Control/Lens/Operators.hs b/src/Control/Lens/Operators.hs
+index 11868e0..475c945 100644
+--- a/src/Control/Lens/Operators.hs
++++ b/src/Control/Lens/Operators.hs
+@@ -108,4 +108,4 @@ import Control.Lens.Review
+ import Control.Lens.Setter
+ import Control.Lens.Zipper
+
+-{-# ANN module "HLint: ignore Use import/export shortcut" #-}
++
+diff --git a/src/Control/Lens/Plated.hs b/src/Control/Lens/Plated.hs
+index a8c4d20..cef574e 100644
+--- a/src/Control/Lens/Plated.hs
++++ b/src/Control/Lens/Plated.hs
+@@ -95,7 +95,7 @@ import Data.Data.Lens
+ import Data.Monoid
+ import Data.Tree
+
+-{-# ANN module "HLint: ignore Reduce duplication" #-}
++
+
+ -- | A 'Plated' type is one where we know how to extract its immediate self-similar children.
+ --
+diff --git a/src/Control/Lens/Prism.hs b/src/Control/Lens/Prism.hs
+index 45b5cfe..88c7ff9 100644
+--- a/src/Control/Lens/Prism.hs
++++ b/src/Control/Lens/Prism.hs
+@@ -53,8 +53,6 @@ import Unsafe.Coerce
+ import Data.Profunctor.Unsafe
+ #endif
+
+-{-# ANN module "HLint: ignore Use camelCase" #-}
+-
+ -- $setup
+ -- >>> :set -XNoOverloadedStrings
+ -- >>> import Control.Lens
+diff --git a/src/Control/Lens/Setter.hs b/src/Control/Lens/Setter.hs
+index 2acbfa6..4a12c6b 100644
+--- a/src/Control/Lens/Setter.hs
++++ b/src/Control/Lens/Setter.hs
+@@ -87,8 +87,6 @@ import Data.Profunctor
+ import Data.Profunctor.Rep
+ import Data.Profunctor.Unsafe
+
+-{-# ANN module "HLint: ignore Avoid lambda" #-}
+-
+ -- $setup
+ -- >>> import Control.Lens
+ -- >>> import Control.Monad.State
+diff --git a/src/Control/Lens/TH.hs b/src/Control/Lens/TH.hs
+index a05eb07..49218b5 100644
+--- a/src/Control/Lens/TH.hs
++++ b/src/Control/Lens/TH.hs
+@@ -87,7 +87,7 @@ import Language.Haskell.TH
+ import Language.Haskell.TH.Syntax
+ import Language.Haskell.TH.Lens
+
+-{-# ANN module "HLint: ignore Use foldl" #-}
++
+
+ -- | Flags for 'Lens' construction
+ data LensFlag
+diff --git a/src/Data/Data/Lens.hs b/src/Data/Data/Lens.hs
+index cf1e7c9..b39dacf 100644
+--- a/src/Data/Data/Lens.hs
++++ b/src/Data/Data/Lens.hs
+@@ -65,9 +65,9 @@ import Data.Monoid
+ import GHC.Exts (realWorld#)
+ #endif
+
+-{-# ANN module "HLint: ignore Eta reduce" #-}
+-{-# ANN module "HLint: ignore Use foldl" #-}
+-{-# ANN module "HLint: ignore Reduce duplication" #-}
++
++
++
+
+ -- $setup
+ -- >>> :set -XNoOverloadedStrings
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/lifted-base_crossbuild.patch b/standalone/android/haskell-patches/lifted-base_crossbuild.patch
new file mode 100644
index 000000000..945aee491
--- /dev/null
+++ b/standalone/android/haskell-patches/lifted-base_crossbuild.patch
@@ -0,0 +1,25 @@
+From 8a98fa29048b508c64d5bb1e03ef89bfad8adc01 Mon Sep 17 00:00:00 2001
+From: foo <foo@bar>
+Date: Sat, 21 Sep 2013 21:34:17 +0000
+Subject: [PATCH] crossbuild
+
+---
+ lifted-base.cabal | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lifted-base.cabal b/lifted-base.cabal
+index 24f2860..3bef225 100644
+--- a/lifted-base.cabal
++++ b/lifted-base.cabal
+@@ -9,7 +9,7 @@ Copyright: (c) 2011-2012 Bas van Dijk, Anders Kaseorg
+ Homepage: https://github.com/basvandijk/lifted-base
+ Bug-reports: https://github.com/basvandijk/lifted-base/issues
+ Category: Control
+-Build-type: Custom
++Build-type: Simple
+ Cabal-version: >= 1.8
+ Description: @lifted-base@ exports IO operations from the base library lifted to
+ any instance of 'MonadBase' or 'MonadBaseControl'.
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/network_2.4.1.0_0001-android-port-fixes.patch b/standalone/android/haskell-patches/network_2.4.1.0_0001-android-port-fixes.patch
new file mode 100644
index 000000000..d7d0608d2
--- /dev/null
+++ b/standalone/android/haskell-patches/network_2.4.1.0_0001-android-port-fixes.patch
@@ -0,0 +1,1960 @@
+From 9750532bd6200353fe09dda65ee6fb59702c4ac1 Mon Sep 17 00:00:00 2001
+From: Joey Hess <joey@kitenet.net>
+Date: Thu, 28 Feb 2013 23:32:15 -0400
+Subject: [PATCH] android port fixes
+
+Build note: Ensure a hsc2hs in PATH is modified to pass -x to the real
+one, to enable cross-compiling.
+---
+ Network/Socket.hsc | 22 +-
+ Network/Socket/ByteString.hsc | 2 +-
+ Network/Socket/Internal.hsc | 2 +-
+ Network/Socket/Types.hsc | 4 +-
+ cbits/HsNet.c | 14 +
+ config.guess | 562 ++++++++++++++++++++++-------------------
+ config.sub | 384 ++++++++++++++++++++--------
+ configure | 1 +
+ include/HsNetworkConfig.h | 8 +-
+ 9 files changed, 612 insertions(+), 387 deletions(-)
+
+diff --git a/Network/Socket.hsc b/Network/Socket.hsc
+index 259e843..e6c0feb 100644
+--- a/Network/Socket.hsc
++++ b/Network/Socket.hsc
+@@ -38,7 +38,7 @@ module Network.Socket
+ , SockAddr(..)
+ , SocketStatus(..)
+ , HostAddress
+-#if defined(IPV6_SOCKET_SUPPORT)
++#if defined(IPV6_SOCKET_SUPPORTNO)
+ , HostAddress6
+ , FlowInfo
+ , ScopeID
+@@ -55,7 +55,7 @@ module Network.Socket
+ , HostName
+ , ServiceName
+
+-#if defined(IPV6_SOCKET_SUPPORT)
++#if defined(IPV6_SOCKET_SUPPORT) || 1
+ , AddrInfo(..)
+
+ , AddrInfoFlag(..)
+@@ -134,7 +134,7 @@ module Network.Socket
+ -- * Special constants
+ , aNY_PORT
+ , iNADDR_ANY
+-#if defined(IPV6_SOCKET_SUPPORT)
++#if defined(IPV6_SOCKET_SUPPORTNO)
+ , iN6ADDR_ANY
+ #endif
+ , sOMAXCONN
+@@ -330,16 +330,6 @@ socket family stype protocol = do
+ setNonBlockIfNeeded fd
+ socket_status <- newMVar NotConnected
+ let sock = MkSocket fd family stype protocol socket_status
+-#if HAVE_DECL_IPV6_V6ONLY
+-# if defined(mingw32_HOST_OS)
+- -- the IPv6Only option is only supported on Windows Vista and later,
+- -- so trying to change it might throw an error
+- when (family == AF_INET6) $
+- E.catch (setSocketOption sock IPv6Only 0) $ (\(_ :: E.IOException) -> return ())
+-# else
+- when (family == AF_INET6) $ setSocketOption sock IPv6Only 0
+-# endif
+-#endif
+ return sock
+
+ -- | Build a pair of connected socket objects using the given address
+@@ -1043,9 +1033,9 @@ aNY_PORT = 0
+ iNADDR_ANY :: HostAddress
+ iNADDR_ANY = htonl (#const INADDR_ANY)
+
+-foreign import CALLCONV unsafe "htonl" htonl :: Word32 -> Word32
++foreign import CALLCONV unsafe "my_htonl" htonl :: Word32 -> Word32
+
+-#if defined(IPV6_SOCKET_SUPPORT)
++#if defined(IPV6_SOCKET_SUPPORTNO)
+ -- | The IPv6 wild card address.
+
+ iN6ADDR_ANY :: HostAddress6
+@@ -1219,7 +1209,7 @@ unpackBits ((k,v):xs) r
+ -----------------------------------------------------------------------------
+ -- Address and service lookups
+
+-#if defined(IPV6_SOCKET_SUPPORT)
++#if defined(IPV6_SOCKET_SUPPORT) || 1
+
+ -- | Flags that control the querying behaviour of 'getAddrInfo'.
+ data AddrInfoFlag
+diff --git a/Network/Socket/ByteString.hsc b/Network/Socket/ByteString.hsc
+index bec2eb9..cb8ed8c 100644
+--- a/Network/Socket/ByteString.hsc
++++ b/Network/Socket/ByteString.hsc
+@@ -201,7 +201,7 @@ sendMany sock@(MkSocket fd _ _ _ _) cs = do
+ liftM fromIntegral . withIOVec cs $ \(iovsPtr, iovsLen) ->
+ throwSocketErrorWaitWrite sock "writev" $
+ c_writev (fromIntegral fd) iovsPtr
+- (fromIntegral (min iovsLen (#const IOV_MAX)))
++ (fromIntegral (min iovsLen (0x0026)))
+ #else
+ sendMany sock = sendAll sock . B.concat
+ #endif
+diff --git a/Network/Socket/Internal.hsc b/Network/Socket/Internal.hsc
+index 96fe9c6..df5ce64 100644
+--- a/Network/Socket/Internal.hsc
++++ b/Network/Socket/Internal.hsc
+@@ -24,7 +24,7 @@ module Network.Socket.Internal
+ (
+ -- * Socket addresses
+ HostAddress
+-#if defined(IPV6_SOCKET_SUPPORT)
++#if defined(IPV6_SOCKET_SUPPORTNO)
+ , HostAddress6
+ , FlowInfo
+ , ScopeID
+diff --git a/Network/Socket/Types.hsc b/Network/Socket/Types.hsc
+index 7ad24f1..dad1d1d 100644
+--- a/Network/Socket/Types.hsc
++++ b/Network/Socket/Types.hsc
+@@ -705,8 +705,8 @@ intToPortNumber v = PortNum (htons (fromIntegral v))
+ portNumberToInt :: PortNumber -> Int
+ portNumberToInt (PortNum po) = fromIntegral (ntohs po)
+
+-foreign import CALLCONV unsafe "ntohs" ntohs :: Word16 -> Word16
+-foreign import CALLCONV unsafe "htons" htons :: Word16 -> Word16
++foreign import CALLCONV unsafe "my_ntohs" ntohs :: Word16 -> Word16
++foreign import CALLCONV unsafe "my_htons" htons :: Word16 -> Word16
+ --foreign import CALLCONV unsafe "ntohl" ntohl :: Word32 -> Word32
+
+ instance Enum PortNumber where
+diff --git a/cbits/HsNet.c b/cbits/HsNet.c
+index 86b55dc..5ea1199 100644
+--- a/cbits/HsNet.c
++++ b/cbits/HsNet.c
+@@ -6,3 +6,17 @@
+
+ #define INLINE
+ #include "HsNet.h"
++
++#include <sys/endian.h>
++uint16_t my_htons(uint16_t v)
++{
++ htons(v);
++}
++uint32_t my_htonl(uint32_t v)
++{
++ htonl(v);
++}
++uint16_t my_ntohs(uint16_t v)
++{
++ ntohs(v);
++}
+diff --git a/config.guess b/config.guess
+index c38553d..1804e9f 100644
+--- a/config.guess
++++ b/config.guess
+@@ -1,13 +1,14 @@
+ #! /bin/sh
+ # Attempt to guess a canonical system name.
+ # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+-# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
++# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
++# 2011, 2012, 2013 Free Software Foundation, Inc.
+
+-timestamp='2006-02-23'
++timestamp='2012-12-29'
+
+ # This file is free software; you can redistribute it and/or modify it
+ # under the terms of the GNU General Public License as published by
+-# the Free Software Foundation; either version 2 of the License, or
++# the Free Software Foundation; either version 3 of the License, or
+ # (at your option) any later version.
+ #
+ # This program is distributed in the hope that it will be useful, but
+@@ -16,26 +17,22 @@ timestamp='2006-02-23'
+ # General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+-# 02110-1301, USA.
++# along with this program; if not, see <http://www.gnu.org/licenses/>.
+ #
+ # As a special exception to the GNU General Public License, if you
+ # distribute this file as part of a program that contains a
+ # configuration script generated by Autoconf, you may include it under
+-# the same distribution terms that you use for the rest of that program.
+-
+-
+-# Originally written by Per Bothner <per@bothner.com>.
+-# Please send patches to <config-patches@gnu.org>. Submit a context
+-# diff and a properly formatted ChangeLog entry.
++# the same distribution terms that you use for the rest of that
++# program. This Exception is an additional permission under section 7
++# of the GNU General Public License, version 3 ("GPLv3").
++#
++# Originally written by Per Bothner.
+ #
+-# This script attempts to guess a canonical system name similar to
+-# config.sub. If it succeeds, it prints the system name on stdout, and
+-# exits with 0. Otherwise, it exits with 1.
++# You can get the latest version of this script from:
++# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+ #
+-# The plan is that this can be called by configure scripts if you
+-# don't specify an explicit build system type.
++# Please send patches with a ChangeLog entry to config-patches@gnu.org.
++
+
+ me=`echo "$0" | sed -e 's,.*/,,'`
+
+@@ -55,8 +52,9 @@ version="\
+ GNU config.guess ($timestamp)
+
+ Originally written by Per Bothner.
+-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+-Free Software Foundation, Inc.
++Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
++2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
++2012, 2013 Free Software Foundation, Inc.
+
+ This is free software; see the source for copying conditions. There is NO
+ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+@@ -143,7 +141,7 @@ UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ *:NetBSD:*:*)
+ # NetBSD (nbsd) targets should (where applicable) match one or
+- # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
++ # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
+ # switched to ELF, *-*-netbsd* would select the old
+ # object file format. This provides both forward
+@@ -160,6 +158,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ arm*) machine=arm-unknown ;;
+ sh3el) machine=shl-unknown ;;
+ sh3eb) machine=sh-unknown ;;
++ sh5el) machine=sh5le-unknown ;;
+ *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+ esac
+ # The Operating System including object format, if it has switched
+@@ -168,7 +167,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+ eval $set_cc_for_build
+ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+- | grep __ELF__ >/dev/null
++ | grep -q __ELF__
+ then
+ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+ # Return netbsd for either. FIX?
+@@ -178,7 +177,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ fi
+ ;;
+ *)
+- os=netbsd
++ os=netbsd
+ ;;
+ esac
+ # The OS release
+@@ -199,6 +198,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ echo "${machine}-${os}${release}"
+ exit ;;
++ *:Bitrig:*:*)
++ UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
++ echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
++ exit ;;
+ *:OpenBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+@@ -210,7 +213,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+ exit ;;
+ macppc:MirBSD:*:*)
+- echo powerppc-unknown-mirbsd${UNAME_RELEASE}
++ echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ *:MirBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+@@ -221,7 +224,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ ;;
+ *5.*)
+- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
++ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ ;;
+ esac
+ # According to Compaq, /usr/sbin/psrinfo has been available on
+@@ -267,7 +270,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+- exit ;;
++ # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
++ exitcode=$?
++ trap '' 0
++ exit $exitcode ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+@@ -293,12 +299,12 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ echo s390-ibm-zvmoe
+ exit ;;
+ *:OS400:*:*)
+- echo powerpc-ibm-os400
++ echo powerpc-ibm-os400
+ exit ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit ;;
+- arm:riscos:*:*|arm:RISCOS:*:*)
++ arm*:riscos:*:*|arm*:RISCOS:*:*)
+ echo arm-unknown-riscos
+ exit ;;
+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+@@ -322,14 +328,33 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ case `/usr/bin/uname -p` in
+ sparc) echo sparc-icl-nx7; exit ;;
+ esac ;;
++ s390x:SunOS:*:*)
++ echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
++ exit ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+- i86pc:SunOS:5.*:*)
+- echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
++ i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
++ echo i386-pc-auroraux${UNAME_RELEASE}
++ exit ;;
++ i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
++ eval $set_cc_for_build
++ SUN_ARCH="i386"
++ # If there is a compiler, see if it is configured for 64-bit objects.
++ # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
++ # This test works for both compilers.
++ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
++ if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
++ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
++ grep IS_64BIT_ARCH >/dev/null
++ then
++ SUN_ARCH="x86_64"
++ fi
++ fi
++ echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+@@ -373,23 +398,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+- echo m68k-atari-mint${UNAME_RELEASE}
++ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+- exit ;;
++ exit ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+- echo m68k-atari-mint${UNAME_RELEASE}
++ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+- echo m68k-milan-mint${UNAME_RELEASE}
+- exit ;;
++ echo m68k-milan-mint${UNAME_RELEASE}
++ exit ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+- echo m68k-hades-mint${UNAME_RELEASE}
+- exit ;;
++ echo m68k-hades-mint${UNAME_RELEASE}
++ exit ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+- echo m68k-unknown-mint${UNAME_RELEASE}
+- exit ;;
++ echo m68k-unknown-mint${UNAME_RELEASE}
++ exit ;;
+ m68k:machten:*:*)
+ echo m68k-apple-machten${UNAME_RELEASE}
+ exit ;;
+@@ -459,8 +484,8 @@ EOF
+ echo m88k-motorola-sysv3
+ exit ;;
+ AViiON:dgux:*:*)
+- # DG/UX returns AViiON for all architectures
+- UNAME_PROCESSOR=`/usr/bin/uname -p`
++ # DG/UX returns AViiON for all architectures
++ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+@@ -473,7 +498,7 @@ EOF
+ else
+ echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+- exit ;;
++ exit ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit ;;
+@@ -530,7 +555,7 @@ EOF
+ echo rs6000-ibm-aix3.2
+ fi
+ exit ;;
+- *:AIX:*:[45])
++ *:AIX:*:[4567])
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+@@ -573,52 +598,52 @@ EOF
+ 9000/[678][0-9][0-9])
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+- sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+- case "${sc_cpu_version}" in
+- 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+- 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+- 532) # CPU_PA_RISC2_0
+- case "${sc_kernel_bits}" in
+- 32) HP_ARCH="hppa2.0n" ;;
+- 64) HP_ARCH="hppa2.0w" ;;
++ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
++ case "${sc_cpu_version}" in
++ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
++ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
++ 532) # CPU_PA_RISC2_0
++ case "${sc_kernel_bits}" in
++ 32) HP_ARCH="hppa2.0n" ;;
++ 64) HP_ARCH="hppa2.0w" ;;
+ '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
+- esac ;;
+- esac
++ esac ;;
++ esac
+ fi
+ if [ "${HP_ARCH}" = "" ]; then
+ eval $set_cc_for_build
+- sed 's/^ //' << EOF >$dummy.c
++ sed 's/^ //' << EOF >$dummy.c
+
+- #define _HPUX_SOURCE
+- #include <stdlib.h>
+- #include <unistd.h>
++ #define _HPUX_SOURCE
++ #include <stdlib.h>
++ #include <unistd.h>
+
+- int main ()
+- {
+- #if defined(_SC_KERNEL_BITS)
+- long bits = sysconf(_SC_KERNEL_BITS);
+- #endif
+- long cpu = sysconf (_SC_CPU_VERSION);
++ int main ()
++ {
++ #if defined(_SC_KERNEL_BITS)
++ long bits = sysconf(_SC_KERNEL_BITS);
++ #endif
++ long cpu = sysconf (_SC_CPU_VERSION);
+
+- switch (cpu)
+- {
+- case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+- case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+- case CPU_PA_RISC2_0:
+- #if defined(_SC_KERNEL_BITS)
+- switch (bits)
+- {
+- case 64: puts ("hppa2.0w"); break;
+- case 32: puts ("hppa2.0n"); break;
+- default: puts ("hppa2.0"); break;
+- } break;
+- #else /* !defined(_SC_KERNEL_BITS) */
+- puts ("hppa2.0"); break;
+- #endif
+- default: puts ("hppa1.0"); break;
+- }
+- exit (0);
+- }
++ switch (cpu)
++ {
++ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
++ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
++ case CPU_PA_RISC2_0:
++ #if defined(_SC_KERNEL_BITS)
++ switch (bits)
++ {
++ case 64: puts ("hppa2.0w"); break;
++ case 32: puts ("hppa2.0n"); break;
++ default: puts ("hppa2.0"); break;
++ } break;
++ #else /* !defined(_SC_KERNEL_BITS) */
++ puts ("hppa2.0"); break;
++ #endif
++ default: puts ("hppa1.0"); break;
++ }
++ exit (0);
++ }
+ EOF
+ (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ test -z "$HP_ARCH" && HP_ARCH=hppa
+@@ -638,7 +663,7 @@ EOF
+ # => hppa64-hp-hpux11.23
+
+ if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+- grep __LP64__ >/dev/null
++ grep -q __LP64__
+ then
+ HP_ARCH="hppa2.0w"
+ else
+@@ -709,22 +734,22 @@ EOF
+ exit ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+- exit ;;
++ exit ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+- exit ;;
++ exit ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+- exit ;;
++ exit ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+- exit ;;
++ exit ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+- exit ;;
++ exit ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+@@ -748,14 +773,14 @@ EOF
+ exit ;;
+ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+ FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+- FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+- echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+- exit ;;
++ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
++ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
++ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
++ exit ;;
+ 5000:UNIX_System_V:4.*:*)
+- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+- FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+- echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
++ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
++ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
++ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+@@ -767,38 +792,51 @@ EOF
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:FreeBSD:*:*)
+- case ${UNAME_MACHINE} in
+- pc98)
+- echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
++ UNAME_PROCESSOR=`/usr/bin/uname -p`
++ case ${UNAME_PROCESSOR} in
++ amd64)
++ echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ *)
+- echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
++ echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ esac
+ exit ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit ;;
+- i*:MINGW*:*)
+- echo ${UNAME_MACHINE}-pc-mingw32
++ *:MINGW64*:*)
++ echo ${UNAME_MACHINE}-pc-mingw64
+ exit ;;
+- i*:MSYS_NT-*:*:*)
++ *:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit ;;
++ i*:MSYS*:*)
++ echo ${UNAME_MACHINE}-pc-msys
++ exit ;;
+ i*:windows32*:*)
+- # uname -m includes "-pc" on this system.
+- echo ${UNAME_MACHINE}-mingw32
++ # uname -m includes "-pc" on this system.
++ echo ${UNAME_MACHINE}-mingw32
+ exit ;;
+ i*:PW*:*)
+ echo ${UNAME_MACHINE}-pc-pw32
+ exit ;;
+- x86:Interix*:[345]*)
+- echo i586-pc-interix${UNAME_RELEASE}
+- exit ;;
+- EM64T:Interix*:[345]*)
+- echo x86_64-unknown-interix${UNAME_RELEASE}
+- exit ;;
++ *:Interix*:*)
++ case ${UNAME_MACHINE} in
++ x86)
++ echo i586-pc-interix${UNAME_RELEASE}
++ exit ;;
++ authenticamd | genuineintel | EM64T)
++ echo x86_64-unknown-interix${UNAME_RELEASE}
++ exit ;;
++ IA64)
++ echo ia64-unknown-interix${UNAME_RELEASE}
++ exit ;;
++ esac ;;
+ [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+ echo i${UNAME_MACHINE}-pc-mks
+ exit ;;
++ 8664:Windows_NT:*)
++ echo x86_64-pc-mks
++ exit ;;
+ i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+@@ -828,17 +866,68 @@ EOF
+ i*86:Minix:*:*)
+ echo ${UNAME_MACHINE}-pc-minix
+ exit ;;
++ aarch64:Linux:*:*)
++ echo ${UNAME_MACHINE}-unknown-linux-gnu
++ exit ;;
++ aarch64_be:Linux:*:*)
++ UNAME_MACHINE=aarch64_be
++ echo ${UNAME_MACHINE}-unknown-linux-gnu
++ exit ;;
++ alpha:Linux:*:*)
++ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
++ EV5) UNAME_MACHINE=alphaev5 ;;
++ EV56) UNAME_MACHINE=alphaev56 ;;
++ PCA56) UNAME_MACHINE=alphapca56 ;;
++ PCA57) UNAME_MACHINE=alphapca56 ;;
++ EV6) UNAME_MACHINE=alphaev6 ;;
++ EV67) UNAME_MACHINE=alphaev67 ;;
++ EV68*) UNAME_MACHINE=alphaev68 ;;
++ esac
++ objdump --private-headers /bin/sh | grep -q ld.so.1
++ if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
++ echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
++ exit ;;
+ arm*:Linux:*:*)
++ eval $set_cc_for_build
++ if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
++ | grep -q __ARM_EABI__
++ then
++ echo ${UNAME_MACHINE}-unknown-linux-gnu
++ else
++ if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
++ | grep -q __ARM_PCS_VFP
++ then
++ echo ${UNAME_MACHINE}-unknown-linux-gnueabi
++ else
++ echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
++ fi
++ fi
++ exit ;;
++ avr32*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ cris:Linux:*:*)
+- echo cris-axis-linux-gnu
++ echo ${UNAME_MACHINE}-axis-linux-gnu
+ exit ;;
+ crisv32:Linux:*:*)
+- echo crisv32-axis-linux-gnu
++ echo ${UNAME_MACHINE}-axis-linux-gnu
+ exit ;;
+ frv:Linux:*:*)
+- echo frv-unknown-linux-gnu
++ echo ${UNAME_MACHINE}-unknown-linux-gnu
++ exit ;;
++ hexagon:Linux:*:*)
++ echo ${UNAME_MACHINE}-unknown-linux-gnu
++ exit ;;
++ i*86:Linux:*:*)
++ LIBC=gnu
++ eval $set_cc_for_build
++ sed 's/^ //' << EOF >$dummy.c
++ #ifdef __dietlibc__
++ LIBC=dietlibc
++ #endif
++EOF
++ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
++ echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+ exit ;;
+ ia64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+@@ -849,74 +938,33 @@ EOF
+ m68*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+- mips:Linux:*:*)
+- eval $set_cc_for_build
+- sed 's/^ //' << EOF >$dummy.c
+- #undef CPU
+- #undef mips
+- #undef mipsel
+- #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+- CPU=mipsel
+- #else
+- #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+- CPU=mips
+- #else
+- CPU=
+- #endif
+- #endif
+-EOF
+- eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+- /^CPU/{
+- s: ::g
+- p
+- }'`"
+- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+- ;;
+- mips64:Linux:*:*)
++ mips:Linux:*:* | mips64:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+- #undef mips64
+- #undef mips64el
++ #undef ${UNAME_MACHINE}
++ #undef ${UNAME_MACHINE}el
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+- CPU=mips64el
++ CPU=${UNAME_MACHINE}el
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+- CPU=mips64
++ CPU=${UNAME_MACHINE}
+ #else
+ CPU=
+ #endif
+ #endif
+ EOF
+- eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+- /^CPU/{
+- s: ::g
+- p
+- }'`"
++ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+ ;;
+ or32:Linux:*:*)
+- echo or32-unknown-linux-gnu
+- exit ;;
+- ppc:Linux:*:*)
+- echo powerpc-unknown-linux-gnu
++ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+- ppc64:Linux:*:*)
+- echo powerpc64-unknown-linux-gnu
++ padre:Linux:*:*)
++ echo sparc-unknown-linux-gnu
+ exit ;;
+- alpha:Linux:*:*)
+- case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+- EV5) UNAME_MACHINE=alphaev5 ;;
+- EV56) UNAME_MACHINE=alphaev56 ;;
+- PCA56) UNAME_MACHINE=alphapca56 ;;
+- PCA57) UNAME_MACHINE=alphapca56 ;;
+- EV6) UNAME_MACHINE=alphaev6 ;;
+- EV67) UNAME_MACHINE=alphaev67 ;;
+- EV68*) UNAME_MACHINE=alphaev68 ;;
+- esac
+- objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+- if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+- echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
++ parisc64:Linux:*:* | hppa64:Linux:*:*)
++ echo hppa64-unknown-linux-gnu
+ exit ;;
+ parisc:Linux:*:* | hppa:Linux:*:*)
+ # Look for CPU level
+@@ -926,14 +974,17 @@ EOF
+ *) echo hppa-unknown-linux-gnu ;;
+ esac
+ exit ;;
+- parisc64:Linux:*:* | hppa64:Linux:*:*)
+- echo hppa64-unknown-linux-gnu
++ ppc64:Linux:*:*)
++ echo powerpc64-unknown-linux-gnu
++ exit ;;
++ ppc:Linux:*:*)
++ echo powerpc-unknown-linux-gnu
+ exit ;;
+ s390:Linux:*:* | s390x:Linux:*:*)
+ echo ${UNAME_MACHINE}-ibm-linux
+ exit ;;
+ sh64*:Linux:*:*)
+- echo ${UNAME_MACHINE}-unknown-linux-gnu
++ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ sh*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+@@ -941,75 +992,18 @@ EOF
+ sparc:Linux:*:* | sparc64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
++ tile*:Linux:*:*)
++ echo ${UNAME_MACHINE}-unknown-linux-gnu
++ exit ;;
+ vax:Linux:*:*)
+ echo ${UNAME_MACHINE}-dec-linux-gnu
+ exit ;;
+ x86_64:Linux:*:*)
+- echo x86_64-unknown-linux-gnu
++ echo ${UNAME_MACHINE}-unknown-linux-gnu
++ exit ;;
++ xtensa*:Linux:*:*)
++ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+- i*86:Linux:*:*)
+- # The BFD linker knows what the default object file format is, so
+- # first see if it will tell us. cd to the root directory to prevent
+- # problems with other programs or directories called `ld' in the path.
+- # Set LC_ALL=C to ensure ld outputs messages in English.
+- ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+- | sed -ne '/supported targets:/!d
+- s/[ ][ ]*/ /g
+- s/.*supported targets: *//
+- s/ .*//
+- p'`
+- case "$ld_supported_targets" in
+- elf32-i386)
+- TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+- ;;
+- a.out-i386-linux)
+- echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+- exit ;;
+- coff-i386)
+- echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+- exit ;;
+- "")
+- # Either a pre-BFD a.out linker (linux-gnuoldld) or
+- # one that does not give us useful --help.
+- echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+- exit ;;
+- esac
+- # Determine whether the default compiler is a.out or elf
+- eval $set_cc_for_build
+- sed 's/^ //' << EOF >$dummy.c
+- #include <features.h>
+- #ifdef __ELF__
+- # ifdef __GLIBC__
+- # if __GLIBC__ >= 2
+- LIBC=gnu
+- # else
+- LIBC=gnulibc1
+- # endif
+- # else
+- LIBC=gnulibc1
+- # endif
+- #else
+- #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__sun)
+- LIBC=gnu
+- #else
+- LIBC=gnuaout
+- #endif
+- #endif
+- #ifdef __dietlibc__
+- LIBC=dietlibc
+- #endif
+-EOF
+- eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+- /^LIBC/{
+- s: ::g
+- p
+- }'`"
+- test x"${LIBC}" != x && {
+- echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+- exit
+- }
+- test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
+- ;;
+ i*86:DYNIX/ptx:4*:*)
+ # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+ # earlier versions are messed up and put the nodename in both
+@@ -1017,11 +1011,11 @@ EOF
+ echo i386-sequent-sysv4
+ exit ;;
+ i*86:UNIX_SV:4.2MP:2.*)
+- # Unixware is an offshoot of SVR4, but it has its own version
+- # number series starting with 2...
+- # I am not positive that other SVR4 systems won't match this,
++ # Unixware is an offshoot of SVR4, but it has its own version
++ # number series starting with 2...
++ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+- # Use sysv4.2uw... so that sysv4* matches it.
++ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit ;;
+ i*86:OS/2:*:*)
+@@ -1038,7 +1032,7 @@ EOF
+ i*86:syllable:*:*)
+ echo ${UNAME_MACHINE}-pc-syllable
+ exit ;;
+- i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
++ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ i*86:*DOS:*:*)
+@@ -1053,7 +1047,7 @@ EOF
+ fi
+ exit ;;
+ i*86:*:5:[678]*)
+- # UnixWare 7.x, OpenUNIX and OpenServer 6.
++ # UnixWare 7.x, OpenUNIX and OpenServer 6.
+ case `/bin/uname -X | grep "^Machine"` in
+ *486*) UNAME_MACHINE=i486 ;;
+ *Pentium) UNAME_MACHINE=i586 ;;
+@@ -1081,10 +1075,13 @@ EOF
+ exit ;;
+ pc:*:*:*)
+ # Left here for compatibility:
+- # uname -m prints for DJGPP always 'pc', but it prints nothing about
+- # the processor, so we play safe by assuming i386.
+- echo i386-pc-msdosdjgpp
+- exit ;;
++ # uname -m prints for DJGPP always 'pc', but it prints nothing about
++ # the processor, so we play safe by assuming i586.
++ # Note: whatever this is, it MUST be the same as what config.sub
++ # prints for the "djgpp" host, or else GDB configury will decide that
++ # this is a cross-build.
++ echo i586-pc-msdosdjgpp
++ exit ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit ;;
+@@ -1119,8 +1116,18 @@ EOF
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+- && { echo i486-ncr-sysv4; exit; } ;;
++ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
++ && { echo i486-ncr-sysv4; exit; } ;;
++ NCR*:*:4.2:* | MPRAS*:*:4.2:*)
++ OS_REL='.3'
++ test -r /etc/.relid \
++ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
++ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
++ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
++ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
++ && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
++ /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
++ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+@@ -1133,7 +1140,7 @@ EOF
+ rs6000:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+- PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
++ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
+ echo powerpc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ SM[BE]S:UNIX_SV:*:*)
+@@ -1153,10 +1160,10 @@ EOF
+ echo ns32k-sni-sysv
+ fi
+ exit ;;
+- PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+- # says <Richard.M.Bartel@ccMail.Census.GOV>
+- echo i586-unisys-sysv4
+- exit ;;
++ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
++ # says <Richard.M.Bartel@ccMail.Census.GOV>
++ echo i586-unisys-sysv4
++ exit ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+@@ -1182,11 +1189,11 @@ EOF
+ exit ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+- echo mips-nec-sysv${UNAME_RELEASE}
++ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+- echo mips-unknown-sysv${UNAME_RELEASE}
++ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+- exit ;;
++ exit ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit ;;
+@@ -1196,6 +1203,12 @@ EOF
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit ;;
++ BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
++ echo i586-pc-haiku
++ exit ;;
++ x86_64:Haiku:*:*)
++ echo x86_64-unknown-haiku
++ exit ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit ;;
+@@ -1205,6 +1218,15 @@ EOF
+ SX-6:SUPER-UX:*:*)
+ echo sx6-nec-superux${UNAME_RELEASE}
+ exit ;;
++ SX-7:SUPER-UX:*:*)
++ echo sx7-nec-superux${UNAME_RELEASE}
++ exit ;;
++ SX-8:SUPER-UX:*:*)
++ echo sx8-nec-superux${UNAME_RELEASE}
++ exit ;;
++ SX-8R:SUPER-UX:*:*)
++ echo sx8r-nec-superux${UNAME_RELEASE}
++ exit ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+@@ -1214,6 +1236,16 @@ EOF
+ *:Darwin:*:*)
+ UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+ case $UNAME_PROCESSOR in
++ i386)
++ eval $set_cc_for_build
++ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
++ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
++ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
++ grep IS_64BIT_ARCH >/dev/null
++ then
++ UNAME_PROCESSOR="x86_64"
++ fi
++ fi ;;
+ unknown) UNAME_PROCESSOR=powerpc ;;
+ esac
+ echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+@@ -1229,7 +1261,10 @@ EOF
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit ;;
+- NSE-?:NONSTOP_KERNEL:*:*)
++ NEO-?:NONSTOP_KERNEL:*:*)
++ echo neo-tandem-nsk${UNAME_RELEASE}
++ exit ;;
++ NSE-*:NONSTOP_KERNEL:*:*)
+ echo nse-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSR-?:NONSTOP_KERNEL:*:*)
+@@ -1274,13 +1309,13 @@ EOF
+ echo pdp10-unknown-its
+ exit ;;
+ SEI:*:*:SEIUX)
+- echo mips-sei-seiux${UNAME_RELEASE}
++ echo mips-sei-seiux${UNAME_RELEASE}
+ exit ;;
+ *:DragonFly:*:*)
+ echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit ;;
+ *:*VMS:*:*)
+- UNAME_MACHINE=`(uname -p) 2>/dev/null`
++ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ case "${UNAME_MACHINE}" in
+ A*) echo alpha-dec-vms ; exit ;;
+ I*) echo ia64-dec-vms ; exit ;;
+@@ -1295,11 +1330,14 @@ EOF
+ i*86:rdos:*:*)
+ echo ${UNAME_MACHINE}-pc-rdos
+ exit ;;
++ i*86:AROS:*:*)
++ echo ${UNAME_MACHINE}-pc-aros
++ exit ;;
++ x86_64:VMkernel:*:*)
++ echo ${UNAME_MACHINE}-unknown-esx
++ exit ;;
+ esac
+
+-#echo '(No uname command or uname output not recognized.)' 1>&2
+-#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+-
+ eval $set_cc_for_build
+ cat >$dummy.c <<EOF
+ #ifdef _SEQUENT_
+@@ -1317,11 +1355,11 @@ main ()
+ #include <sys/param.h>
+ printf ("m68k-sony-newsos%s\n",
+ #ifdef NEWSOS4
+- "4"
++ "4"
+ #else
+- ""
++ ""
+ #endif
+- ); exit (0);
++ ); exit (0);
+ #endif
+ #endif
+
+@@ -1455,9 +1493,9 @@ This script, last modified $timestamp, has failed to recognize
+ the operating system you are using. It is advised that you
+ download the most up to date version of the config scripts from
+
+- http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
++ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+ and
+- http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
++ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+ If the version you run ($0) is already up to date, please
+ send the following data and any information you think might be
+diff --git a/config.sub b/config.sub
+index ad9f395..802a224 100644
+--- a/config.sub
++++ b/config.sub
+@@ -1,43 +1,42 @@
+ #! /bin/sh
+ # Configuration validation subroutine script.
+ # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+-# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
++# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
++# 2011, 2012, 2013 Free Software Foundation, Inc.
+
+-timestamp='2006-02-23'
++timestamp='2012-12-29'
+
+-# This file is (in principle) common to ALL GNU software.
+-# The presence of a machine in this file suggests that SOME GNU software
+-# can handle that machine. It does not imply ALL GNU software can.
+-#
+-# This file is free software; you can redistribute it and/or modify
+-# it under the terms of the GNU General Public License as published by
+-# the Free Software Foundation; either version 2 of the License, or
++# This file is free software; you can redistribute it and/or modify it
++# under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 3 of the License, or
+ # (at your option) any later version.
+ #
+-# This program is distributed in the hope that it will be useful,
+-# but WITHOUT ANY WARRANTY; without even the implied warranty of
+-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-# GNU General Public License for more details.
++# This program is distributed in the hope that it will be useful, but
++# WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++# General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+-# 02110-1301, USA.
++# along with this program; if not, see <http://www.gnu.org/licenses/>.
+ #
+ # As a special exception to the GNU General Public License, if you
+ # distribute this file as part of a program that contains a
+ # configuration script generated by Autoconf, you may include it under
+-# the same distribution terms that you use for the rest of that program.
++# the same distribution terms that you use for the rest of that
++# program. This Exception is an additional permission under section 7
++# of the GNU General Public License, version 3 ("GPLv3").
+
+
+-# Please send patches to <config-patches@gnu.org>. Submit a context
+-# diff and a properly formatted ChangeLog entry.
++# Please send patches with a ChangeLog entry to config-patches@gnu.org.
+ #
+ # Configuration subroutine to validate and canonicalize a configuration type.
+ # Supply the specified configuration type as an argument.
+ # If it is invalid, we print an error message on stderr and exit with code 1.
+ # Otherwise, we print the canonical config type on stdout and succeed.
+
++# You can get the latest version of this script from:
++# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
++
+ # This file is supposed to be the same for all GNU packages
+ # and recognize all the CPU types, system types and aliases
+ # that are meaningful with *any* GNU software.
+@@ -71,8 +70,9 @@ Report bugs and patches to <config-patches@gnu.org>."
+ version="\
+ GNU config.sub ($timestamp)
+
+-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+-Free Software Foundation, Inc.
++Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
++2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
++2012, 2013 Free Software Foundation, Inc.
+
+ This is free software; see the source for copying conditions. There is NO
+ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+@@ -119,12 +119,18 @@ esac
+ # Here we must recognize all the valid KERNEL-OS combinations.
+ maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+ case $maybe_os in
+- nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
+- uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
++ nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
++ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
++ knetbsd*-gnu* | netbsd*-gnu* | \
++ kopensolaris*-gnu* | \
+ storm-chaos* | os2-emx* | rtmk-nova*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
++ android-linux)
++ os=-linux-android
++ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
++ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+@@ -147,10 +153,13 @@ case $os in
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+- -apple | -axis | -knuth | -cray)
++ -apple | -axis | -knuth | -cray | -microblaze*)
+ os=
+ basic_machine=$1
+ ;;
++ -bluegene*)
++ os=-cnk
++ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+ basic_machine=$1
+@@ -165,10 +174,10 @@ case $os in
+ os=-chorusos
+ basic_machine=$1
+ ;;
+- -chorusrdb)
+- os=-chorusrdb
++ -chorusrdb)
++ os=-chorusrdb
+ basic_machine=$1
+- ;;
++ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+@@ -213,6 +222,12 @@ case $os in
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
++ -lynx*178)
++ os=-lynxos178
++ ;;
++ -lynx*5)
++ os=-lynxos5
++ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+@@ -237,23 +252,34 @@ case $basic_machine in
+ # Some are omitted here because they have special meanings below.
+ 1750a | 580 \
+ | a29k \
++ | aarch64 | aarch64_be \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | am33_2.0 \
+- | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
++ | arc \
++ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
++ | avr | avr32 \
++ | be32 | be64 \
+ | bfin \
+ | c4x | clipper \
+ | d10v | d30v | dlx | dsp16xx \
+- | fr30 | frv \
++ | epiphany \
++ | fido | fr30 | frv \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
++ | hexagon \
+ | i370 | i860 | i960 | ia64 \
+ | ip2k | iq2000 \
+- | m32r | m32rle | m68000 | m68k | m88k | maxq | mb | microblaze | mcore \
++ | le32 | le64 \
++ | lm32 \
++ | m32c | m32r | m32rle | m68000 | m68k | m88k \
++ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+- | mips64vr | mips64vrel \
++ | mips64octeon | mips64octeonel \
+ | mips64orion | mips64orionel \
++ | mips64r5900 | mips64r5900el \
++ | mips64vr | mips64vrel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+@@ -266,31 +292,42 @@ case $basic_machine in
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipstx39 | mipstx39el \
+ | mn10200 | mn10300 \
++ | moxie \
+ | mt \
+ | msp430 \
++ | nds32 | nds32le | nds32be \
+ | nios | nios2 \
+ | ns16k | ns32k \
++ | open8 \
+ | or32 \
+ | pdp10 | pdp11 | pj | pjl \
+- | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
++ | powerpc | powerpc64 | powerpc64le | powerpcle \
+ | pyramid \
+- | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
++ | rl78 | rx \
++ | score \
++ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+- | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \
+- | sparcv8 | sparcv9 | sparcv9b \
+- | strongarm \
+- | tahoe | thumb | tic4x | tic80 | tron \
+- | v850 | v850e \
++ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
++ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
++ | spu \
++ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
++ | ubicom32 \
++ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+ | we32k \
+- | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \
+- | z8k)
++ | x86 | xc16x | xstormy16 | xtensa \
++ | z8k | z80)
+ basic_machine=$basic_machine-unknown
+ ;;
+- m32c)
+- basic_machine=$basic_machine-unknown
++ c54x)
++ basic_machine=tic54x-unknown
++ ;;
++ c55x)
++ basic_machine=tic55x-unknown
+ ;;
+- m6811 | m68hc11 | m6812 | m68hc12)
+- # Motorola 68HC11/12.
++ c6x)
++ basic_machine=tic6x-unknown
++ ;;
++ m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+@@ -300,6 +337,21 @@ case $basic_machine in
+ basic_machine=mt-unknown
+ ;;
+
++ strongarm | thumb | xscale)
++ basic_machine=arm-unknown
++ ;;
++ xgate)
++ basic_machine=$basic_machine-unknown
++ os=-none
++ ;;
++ xscaleeb)
++ basic_machine=armeb-unknown
++ ;;
++
++ xscaleel)
++ basic_machine=armel-unknown
++ ;;
++
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+@@ -314,29 +366,37 @@ case $basic_machine in
+ # Recognize the basic CPU types with company name.
+ 580-* \
+ | a29k-* \
++ | aarch64-* | aarch64_be-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
+- | avr-* \
++ | avr-* | avr32-* \
++ | be32-* | be64-* \
+ | bfin-* | bs2000-* \
+- | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
++ | c[123]* | c30-* | [cjt]90-* | c4x-* \
+ | clipper-* | craynv-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
+ | elxsi-* \
+- | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
++ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
++ | hexagon-* \
+ | i*86-* | i860-* | i960-* | ia64-* \
+ | ip2k-* | iq2000-* \
+- | m32r-* | m32rle-* \
++ | le32-* | le64-* \
++ | lm32-* \
++ | m32c-* | m32r-* | m32rle-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+- | m88110-* | m88k-* | maxq-* | mcore-* \
++ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
++ | microblaze-* | microblazeel-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+- | mips64vr-* | mips64vrel-* \
++ | mips64octeon-* | mips64octeonel-* \
+ | mips64orion-* | mips64orionel-* \
++ | mips64r5900-* | mips64r5900el-* \
++ | mips64vr-* | mips64vrel-* \
+ | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* \
+ | mips64vr5000-* | mips64vr5000el-* \
+@@ -351,29 +411,36 @@ case $basic_machine in
+ | mmix-* \
+ | mt-* \
+ | msp430-* \
++ | nds32-* | nds32le-* | nds32be-* \
+ | nios-* | nios2-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
++ | open8-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+- | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
++ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+ | pyramid-* \
+- | romp-* | rs6000-* \
+- | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \
++ | rl78-* | romp-* | rs6000-* | rx-* \
++ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+- | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \
++ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+ | sparclite-* \
+- | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+- | tahoe-* | thumb-* \
++ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
++ | tahoe-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
++ | tile*-* \
+ | tron-* \
+- | v850-* | v850e-* | vax-* \
++ | ubicom32-* \
++ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
++ | vax-* \
+ | we32k-* \
+- | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \
+- | xstormy16-* | xtensa-* \
++ | x86-* | x86_64-* | xc16x-* | xps100-* \
++ | xstormy16-* | xtensa*-* \
+ | ymp-* \
+- | z8k-*)
++ | z8k-* | z80-*)
+ ;;
+- m32c-*)
++ # Recognize the basic CPU types without company name, with glob match.
++ xtensa*)
++ basic_machine=$basic_machine-unknown
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+@@ -391,7 +458,7 @@ case $basic_machine in
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+- abacus)
++ abacus)
+ basic_machine=abacus-unknown
+ ;;
+ adobe68k)
+@@ -437,6 +504,10 @@ case $basic_machine in
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
++ aros)
++ basic_machine=i386-pc
++ os=-aros
++ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+@@ -445,10 +516,35 @@ case $basic_machine in
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
++ blackfin)
++ basic_machine=bfin-unknown
++ os=-linux
++ ;;
++ blackfin-*)
++ basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
++ os=-linux
++ ;;
++ bluegene*)
++ basic_machine=powerpc-ibm
++ os=-cnk
++ ;;
++ c54x-*)
++ basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
++ ;;
++ c55x-*)
++ basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
++ ;;
++ c6x-*)
++ basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
++ ;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
++ cegcc)
++ basic_machine=arm-unknown
++ os=-cegcc
++ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+@@ -477,8 +573,8 @@ case $basic_machine in
+ basic_machine=craynv-cray
+ os=-unicosmp
+ ;;
+- cr16c)
+- basic_machine=cr16c-unknown
++ cr16 | cr16-*)
++ basic_machine=cr16-unknown
+ os=-elf
+ ;;
+ crds | unos)
+@@ -516,6 +612,10 @@ case $basic_machine in
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
++ dicos)
++ basic_machine=i686-pc
++ os=-dicos
++ ;;
+ djgpp)
+ basic_machine=i586-pc
+ os=-msdosdjgpp
+@@ -631,7 +731,6 @@ case $basic_machine in
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+-# I'm not sure what "Sysv32" means. Should this be sysv3.2?
+ i*86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+@@ -670,6 +769,14 @@ case $basic_machine in
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
++ m68knommu)
++ basic_machine=m68k-unknown
++ os=-linux
++ ;;
++ m68knommu-*)
++ basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
++ os=-linux
++ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+@@ -681,10 +788,21 @@ case $basic_machine in
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
++ microblaze*)
++ basic_machine=microblaze-xilinx
++ ;;
++ mingw64)
++ basic_machine=x86_64-pc
++ os=-mingw64
++ ;;
+ mingw32)
+ basic_machine=i386-pc
+ os=-mingw32
+ ;;
++ mingw32ce)
++ basic_machine=arm-unknown
++ os=-mingw32ce
++ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+@@ -713,10 +831,18 @@ case $basic_machine in
+ ms1-*)
+ basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+ ;;
++ msys)
++ basic_machine=i386-pc
++ os=-msys
++ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
++ nacl)
++ basic_machine=le32-unknown
++ os=-nacl
++ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+@@ -781,6 +907,12 @@ case $basic_machine in
+ np1)
+ basic_machine=np1-gould
+ ;;
++ neo-tandem)
++ basic_machine=neo-tandem
++ ;;
++ nse-tandem)
++ basic_machine=nse-tandem
++ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+@@ -811,6 +943,14 @@ case $basic_machine in
+ basic_machine=i860-intel
+ os=-osf
+ ;;
++ parisc)
++ basic_machine=hppa-unknown
++ os=-linux
++ ;;
++ parisc-*)
++ basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
++ os=-linux
++ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+@@ -855,9 +995,10 @@ case $basic_machine in
+ ;;
+ power) basic_machine=power-ibm
+ ;;
+- ppc) basic_machine=powerpc-unknown
++ ppc | ppcbe) basic_machine=powerpc-unknown
+ ;;
+- ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
++ ppc-* | ppcbe-*)
++ basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+@@ -882,7 +1023,11 @@ case $basic_machine in
+ basic_machine=i586-unknown
+ os=-pw32
+ ;;
+- rdos)
++ rdos | rdos64)
++ basic_machine=x86_64-pc
++ os=-rdos
++ ;;
++ rdos32)
+ basic_machine=i386-pc
+ os=-rdos
+ ;;
+@@ -912,6 +1057,10 @@ case $basic_machine in
+ sb1el)
+ basic_machine=mipsisa64sb1el-unknown
+ ;;
++ sde)
++ basic_machine=mipsisa32-sde
++ os=-elf
++ ;;
+ sei)
+ basic_machine=mips-sei
+ os=-seiux
+@@ -923,6 +1072,9 @@ case $basic_machine in
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
++ sh5el)
++ basic_machine=sh5le-unknown
++ ;;
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
+@@ -944,6 +1096,9 @@ case $basic_machine in
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
++ strongarm-* | thumb-*)
++ basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
++ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+@@ -1000,17 +1155,9 @@ case $basic_machine in
+ basic_machine=t90-cray
+ os=-unicos
+ ;;
+- tic54x | c54x*)
+- basic_machine=tic54x-unknown
+- os=-coff
+- ;;
+- tic55x | c55x*)
+- basic_machine=tic55x-unknown
+- os=-coff
+- ;;
+- tic6x | c6x*)
+- basic_machine=tic6x-unknown
+- os=-coff
++ tile*)
++ basic_machine=$basic_machine-unknown
++ os=-linux-gnu
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+@@ -1079,6 +1226,9 @@ case $basic_machine in
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
++ xscale-* | xscalee[bl]-*)
++ basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
++ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+@@ -1087,6 +1237,10 @@ case $basic_machine in
+ basic_machine=z8k-unknown
+ os=-sim
+ ;;
++ z80-*-coff)
++ basic_machine=z80-unknown
++ os=-sim
++ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+@@ -1125,10 +1279,10 @@ case $basic_machine in
+ we32k)
+ basic_machine=we32k-att
+ ;;
+- sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
++ sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+ basic_machine=sh-unknown
+ ;;
+- sparc | sparcv8 | sparcv9 | sparcv9b)
++ sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+@@ -1172,9 +1326,12 @@ esac
+ if [ x"$os" != x"" ]
+ then
+ case $os in
+- # First match some system type aliases
+- # that might get confused with valid system types.
++ # First match some system type aliases
++ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
++ -auroraux)
++ os=-auroraux
++ ;;
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+@@ -1195,21 +1352,23 @@ case $os in
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+- | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+- | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
++ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
++ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
++ | -sym* | -kopensolaris* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+- | -aos* \
++ | -aos* | -aros* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+- | -openbsd* | -solidbsd* \
++ | -bitrig* | -openbsd* | -solidbsd* \
+ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+- | -chorusos* | -chorusrdb* \
+- | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+- | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
++ | -chorusos* | -chorusrdb* | -cegcc* \
++ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
++ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
++ | -linux-newlib* | -linux-musl* | -linux-uclibc* \
+ | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+@@ -1217,7 +1376,7 @@ case $os in
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+- | -skyos* | -haiku* | -rdos*)
++ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+@@ -1256,7 +1415,7 @@ case $os in
+ -opened*)
+ os=-openedition
+ ;;
+- -os400*)
++ -os400*)
+ os=-os400
+ ;;
+ -wince*)
+@@ -1305,7 +1464,7 @@ case $os in
+ -sinix*)
+ os=-sysv4
+ ;;
+- -tpf*)
++ -tpf*)
+ os=-tpf
+ ;;
+ -triton*)
+@@ -1347,6 +1506,11 @@ case $os in
+ -zvmoe)
+ os=-zvmoe
+ ;;
++ -dicos*)
++ os=-dicos
++ ;;
++ -nacl*)
++ ;;
+ -none)
+ ;;
+ *)
+@@ -1369,6 +1533,12 @@ else
+ # system, and we'll never get to this point.
+
+ case $basic_machine in
++ score-*)
++ os=-elf
++ ;;
++ spu-*)
++ os=-elf
++ ;;
+ *-acorn)
+ os=-riscix1.2
+ ;;
+@@ -1378,9 +1548,21 @@ case $basic_machine in
+ arm*-semi)
+ os=-aout
+ ;;
+- c4x-* | tic4x-*)
+- os=-coff
+- ;;
++ c4x-* | tic4x-*)
++ os=-coff
++ ;;
++ hexagon-*)
++ os=-elf
++ ;;
++ tic54x-*)
++ os=-coff
++ ;;
++ tic55x-*)
++ os=-coff
++ ;;
++ tic6x-*)
++ os=-coff
++ ;;
+ # This must come before the *-dec entry.
+ pdp10-*)
+ os=-tops20
+@@ -1399,13 +1581,13 @@ case $basic_machine in
+ ;;
+ m68000-sun)
+ os=-sunos3
+- # This also exists in the configure program, but was not the
+- # default.
+- # os=-sunos4
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
++ mep-*)
++ os=-elf
++ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+@@ -1430,7 +1612,7 @@ case $basic_machine in
+ *-ibm)
+ os=-aix
+ ;;
+- *-knuth)
++ *-knuth)
+ os=-mmixware
+ ;;
+ *-wec)
+@@ -1535,7 +1717,7 @@ case $basic_machine in
+ -sunos*)
+ vendor=sun
+ ;;
+- -aix*)
++ -cnk*|-aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+diff --git a/configure b/configure
+index a9e9814..7fd6318 100755
+--- a/configure
++++ b/configure
+@@ -1,4 +1,5 @@
+ #! /bin/sh
++set -- --host=arm-linux-androideabi
+ # Guess values for system-dependent variables and create Makefiles.
+ # Generated by GNU Autoconf 2.69 for Haskell network package 2.3.0.14.
+ #
+diff --git a/include/HsNetworkConfig.h b/include/HsNetworkConfig.h
+index c6e704d..4edc892 100644
+--- a/include/HsNetworkConfig.h
++++ b/include/HsNetworkConfig.h
+@@ -8,7 +8,7 @@
+ #define HAVE_ARPA_INET_H 1
+
+ /* Define to 1 if you have a BSDish sendfile(2) implementation. */
+-#define HAVE_BSD_SENDFILE 1
++/* #undef HAVE_BSD_SENDFILE */
+
+ /* Define to 1 if you have the declaration of `AI_ADDRCONFIG', and to 0 if you
+ don't. */
+@@ -55,7 +55,7 @@
+ #define HAVE_LIMITS_H 1
+
+ /* Define to 1 if you have a Linux sendfile(2) implementation. */
+-/* #undef HAVE_LINUX_SENDFILE */
++#define HAVE_LINUX_SENDFILE 1
+
+ /* Define to 1 if you have the <memory.h> header file. */
+ #define HAVE_MEMORY_H 1
+@@ -91,10 +91,10 @@
+ #define HAVE_STRUCT_MSGHDR_MSG_CONTROL 1
+
+ /* Define to 1 if `sa_len' is a member of `struct sockaddr'. */
+-#define HAVE_STRUCT_SOCKADDR_SA_LEN 1
++/* #undef HAVE_STRUCT_SOCKADDR_SA_LEN */
+
+ /* Define to 1 if you have both SO_PEERCRED and struct ucred. */
+-/* #undef HAVE_STRUCT_UCRED */
++#define HAVE_STRUCT_UCRED 1
+
+ /* Define to 1 if you have the `symlink' function. */
+ #define HAVE_SYMLINK 1
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/network_2.4.1.0_0002-remove-Network.BSD-symbols-not-available-in-bionic.patch b/standalone/android/haskell-patches/network_2.4.1.0_0002-remove-Network.BSD-symbols-not-available-in-bionic.patch
new file mode 100644
index 000000000..324809ad9
--- /dev/null
+++ b/standalone/android/haskell-patches/network_2.4.1.0_0002-remove-Network.BSD-symbols-not-available-in-bionic.patch
@@ -0,0 +1,157 @@
+From 8456a3b26261212052bad4d1de207504a3f85995 Mon Sep 17 00:00:00 2001
+From: Joey Hess <joey@kitenet.net>
+Date: Fri, 19 Apr 2013 15:14:10 -0400
+Subject: [PATCH] remove Network.BSD symbols not available in bionic
+
+---
+ Network/BSD.hsc | 98 ---------------------------------------------------------
+ 1 file changed, 98 deletions(-)
+
+diff --git a/Network/BSD.hsc b/Network/BSD.hsc
+index c199036..f0c9f5b 100644
+--- a/Network/BSD.hsc
++++ b/Network/BSD.hsc
+@@ -30,15 +30,6 @@ module Network.BSD
+ , getHostByAddr
+ , hostAddress
+
+-#if defined(HAVE_GETHOSTENT) && !defined(cygwin32_HOST_OS) && !defined(mingw32_HOST_OS) && !defined(_WIN32)
+- , getHostEntries
+-
+- -- ** Low level functionality
+- , setHostEntry
+- , getHostEntry
+- , endHostEntry
+-#endif
+-
+ -- * Service names
+ , ServiceEntry(..)
+ , ServiceName
+@@ -64,14 +55,6 @@ module Network.BSD
+ , getProtocolNumber
+ , defaultProtocol
+
+-#if !defined(cygwin32_HOST_OS) && !defined(mingw32_HOST_OS) && !defined(_WIN32)
+- , getProtocolEntries
+- -- ** Low level functionality
+- , setProtocolEntry
+- , getProtocolEntry
+- , endProtocolEntry
+-#endif
+-
+ -- * Port numbers
+ , PortNumber
+
+@@ -83,11 +66,7 @@ module Network.BSD
+ #if !defined(cygwin32_HOST_OS) && !defined(mingw32_HOST_OS) && !defined(_WIN32)
+ , getNetworkByName
+ , getNetworkByAddr
+- , getNetworkEntries
+ -- ** Low level functionality
+- , setNetworkEntry
+- , getNetworkEntry
+- , endNetworkEntry
+ #endif
+ ) where
+
+@@ -305,31 +284,6 @@ getProtocolNumber proto = do
+ (ProtocolEntry _ _ num) <- getProtocolByName proto
+ return num
+
+-#if !defined(cygwin32_HOST_OS) && !defined(mingw32_HOST_OS) && !defined(_WIN32)
+-getProtocolEntry :: IO ProtocolEntry -- Next Protocol Entry from DB
+-getProtocolEntry = withLock $ do
+- ent <- throwNoSuchThingIfNull "getProtocolEntry" "no such protocol entry"
+- $ trySysCall c_getprotoent
+- peek ent
+-
+-foreign import ccall unsafe "getprotoent" c_getprotoent :: IO (Ptr ProtocolEntry)
+-
+-setProtocolEntry :: Bool -> IO () -- Keep DB Open ?
+-setProtocolEntry flg = withLock $ trySysCall $ c_setprotoent (fromBool flg)
+-
+-foreign import ccall unsafe "setprotoent" c_setprotoent :: CInt -> IO ()
+-
+-endProtocolEntry :: IO ()
+-endProtocolEntry = withLock $ trySysCall $ c_endprotoent
+-
+-foreign import ccall unsafe "endprotoent" c_endprotoent :: IO ()
+-
+-getProtocolEntries :: Bool -> IO [ProtocolEntry]
+-getProtocolEntries stayOpen = withLock $ do
+- setProtocolEntry stayOpen
+- getEntries (getProtocolEntry) (endProtocolEntry)
+-#endif
+-
+ -- ---------------------------------------------------------------------------
+ -- Host lookups
+
+@@ -404,31 +358,6 @@ getHostByAddr family addr = do
+ foreign import CALLCONV safe "gethostbyaddr"
+ c_gethostbyaddr :: Ptr HostAddress -> CInt -> CInt -> IO (Ptr HostEntry)
+
+-#if defined(HAVE_GETHOSTENT) && !defined(cygwin32_HOST_OS) && !defined(mingw32_HOST_OS) && !defined(_WIN32)
+-getHostEntry :: IO HostEntry
+-getHostEntry = withLock $ do
+- throwNoSuchThingIfNull "getHostEntry" "unable to retrieve host entry"
+- $ trySysCall $ c_gethostent
+- >>= peek
+-
+-foreign import ccall unsafe "gethostent" c_gethostent :: IO (Ptr HostEntry)
+-
+-setHostEntry :: Bool -> IO ()
+-setHostEntry flg = withLock $ trySysCall $ c_sethostent (fromBool flg)
+-
+-foreign import ccall unsafe "sethostent" c_sethostent :: CInt -> IO ()
+-
+-endHostEntry :: IO ()
+-endHostEntry = withLock $ c_endhostent
+-
+-foreign import ccall unsafe "endhostent" c_endhostent :: IO ()
+-
+-getHostEntries :: Bool -> IO [HostEntry]
+-getHostEntries stayOpen = do
+- setHostEntry stayOpen
+- getEntries (getHostEntry) (endHostEntry)
+-#endif
+-
+ -- ---------------------------------------------------------------------------
+ -- Accessing network information
+
+@@ -490,33 +419,6 @@ getNetworkByAddr addr family = withLock $ do
+ foreign import ccall unsafe "getnetbyaddr"
+ c_getnetbyaddr :: NetworkAddr -> CInt -> IO (Ptr NetworkEntry)
+
+-getNetworkEntry :: IO NetworkEntry
+-getNetworkEntry = withLock $ do
+- throwNoSuchThingIfNull "getNetworkEntry" "no more network entries"
+- $ trySysCall $ c_getnetent
+- >>= peek
+-
+-foreign import ccall unsafe "getnetent" c_getnetent :: IO (Ptr NetworkEntry)
+-
+--- | Open the network name database. The parameter specifies
+--- whether a connection is maintained open between various
+--- networkEntry calls
+-setNetworkEntry :: Bool -> IO ()
+-setNetworkEntry flg = withLock $ trySysCall $ c_setnetent (fromBool flg)
+-
+-foreign import ccall unsafe "setnetent" c_setnetent :: CInt -> IO ()
+-
+--- | Close the connection to the network name database.
+-endNetworkEntry :: IO ()
+-endNetworkEntry = withLock $ trySysCall $ c_endnetent
+-
+-foreign import ccall unsafe "endnetent" c_endnetent :: IO ()
+-
+--- | Get the list of network entries.
+-getNetworkEntries :: Bool -> IO [NetworkEntry]
+-getNetworkEntries stayOpen = do
+- setNetworkEntry stayOpen
+- getEntries (getNetworkEntry) (endNetworkEntry)
+ #endif
+
+ -- Mutex for name service lockdown
+--
+1.8.2.rc3
+
diff --git a/standalone/android/haskell-patches/network_2.4.1.0_0003-configure-misdetects-accept4.patch b/standalone/android/haskell-patches/network_2.4.1.0_0003-configure-misdetects-accept4.patch
new file mode 100644
index 000000000..116fa320e
--- /dev/null
+++ b/standalone/android/haskell-patches/network_2.4.1.0_0003-configure-misdetects-accept4.patch
@@ -0,0 +1,34 @@
+From 63a7a97511266c1a9d2414d3314ee17fc88bb8f2 Mon Sep 17 00:00:00 2001
+From: dummy <dummy@example.com>
+Date: Fri, 18 Oct 2013 15:58:35 +0000
+Subject: [PATCH] configure misdetects accept4
+
+---
+ Network/Socket.hsc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/Network/Socket.hsc b/Network/Socket.hsc
+index 9af31f8..6c21209 100644
+--- a/Network/Socket.hsc
++++ b/Network/Socket.hsc
+@@ -503,7 +503,7 @@ accept sock@(MkSocket s family stype protocol status) = do
+ return new_sock
+ #else
+ with (fromIntegral sz) $ \ ptr_len -> do
+-# ifdef HAVE_ACCEPT4
++#if 0
+ new_sock <- throwSocketErrorIfMinus1RetryMayBlock "accept"
+ (threadWaitRead (fromIntegral s))
+ (c_accept4 s sockaddr ptr_len (#const SOCK_NONBLOCK))
+@@ -1615,7 +1615,7 @@ foreign import CALLCONV SAFE_ON_WIN "connect"
+ c_connect :: CInt -> Ptr SockAddr -> CInt{-CSockLen???-} -> IO CInt
+ foreign import CALLCONV unsafe "accept"
+ c_accept :: CInt -> Ptr SockAddr -> Ptr CInt{-CSockLen???-} -> IO CInt
+-#ifdef HAVE_ACCEPT4
++#if 0
+ foreign import CALLCONV unsafe "accept4"
+ c_accept4 :: CInt -> Ptr SockAddr -> Ptr CInt{-CSockLen???-} -> CInt -> IO CInt
+ #endif
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/network_2.4.1.0_0004-getprotobyname-hack-for-tcp-and-udp.patch b/standalone/android/haskell-patches/network_2.4.1.0_0004-getprotobyname-hack-for-tcp-and-udp.patch
new file mode 100644
index 000000000..4cc22cbca
--- /dev/null
+++ b/standalone/android/haskell-patches/network_2.4.1.0_0004-getprotobyname-hack-for-tcp-and-udp.patch
@@ -0,0 +1,28 @@
+From b1a581007759e2d9e53ef776e4f10d1de87b8377 Mon Sep 17 00:00:00 2001
+From: Joey Hess <joey@kitenet.net>
+Date: Tue, 7 May 2013 14:51:09 -0400
+Subject: [PATCH] getprotobyname hack for tcp and udp
+
+Otherwise, core network stuff fails to get the numbers for these protocols.
+---
+ Network/BSD.hsc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/Network/BSD.hsc b/Network/BSD.hsc
+index f0c9f5b..a289143 100644
+--- a/Network/BSD.hsc
++++ b/Network/BSD.hsc
+@@ -259,6 +259,10 @@ instance Storable ProtocolEntry where
+ poke _p = error "Storable.poke(BSD.ProtocolEntry) not implemented"
+
+ getProtocolByName :: ProtocolName -> IO ProtocolEntry
++getProtocolByName "tcp" = return $
++ ProtocolEntry {protoName = "tcp", protoAliases = ["TCP"], protoNumber = 6}
++getProtocolByName "udp" = return $
++ ProtocolEntry {protoName = "udp", protoAliases = ["UDP"], protoNumber = 17}
+ getProtocolByName name = withLock $ do
+ withCString name $ \ name_cstr -> do
+ throwNoSuchThingIfNull "getProtocolByName" ("no such protocol name: " ++ name)
+--
+1.8.2.rc3
+
diff --git a/standalone/android/haskell-patches/persistent-template_stub-out.patch b/standalone/android/haskell-patches/persistent-template_stub-out.patch
new file mode 100644
index 000000000..6b7b62bd4
--- /dev/null
+++ b/standalone/android/haskell-patches/persistent-template_stub-out.patch
@@ -0,0 +1,25 @@
+From 0b9df0de3aa45918a2a9226a2da6be4680276419 Mon Sep 17 00:00:00 2001
+From: foo <foo@bar>
+Date: Sun, 22 Sep 2013 03:31:55 +0000
+Subject: [PATCH] stub out
+
+---
+ persistent-template.cabal | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/persistent-template.cabal b/persistent-template.cabal
+index 8216ce7..f23234b 100644
+--- a/persistent-template.cabal
++++ b/persistent-template.cabal
+@@ -23,7 +23,7 @@ library
+ , containers
+ , aeson
+ , monad-logger
+- exposed-modules: Database.Persist.TH
++ exposed-modules:
+ ghc-options: -Wall
+ if impl(ghc >= 7.4)
+ cpp-options: -DGHC_7_4
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/persistent_1.1.5.1_0001-disable-TH.patch b/standalone/android/haskell-patches/persistent_1.1.5.1_0001-disable-TH.patch
new file mode 100644
index 000000000..300975b83
--- /dev/null
+++ b/standalone/android/haskell-patches/persistent_1.1.5.1_0001-disable-TH.patch
@@ -0,0 +1,32 @@
+From 760fa2c5044ae38bee8114ff84c625ac59f35c6f Mon Sep 17 00:00:00 2001
+From: foo <foo@bar>
+Date: Sun, 22 Sep 2013 00:03:55 +0000
+Subject: [PATCH] disable TH
+
+---
+ Database/Persist/Sql/Raw.hs | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/Database/Persist/Sql/Raw.hs b/Database/Persist/Sql/Raw.hs
+index 73189dd..6efebea 100644
+--- a/Database/Persist/Sql/Raw.hs
++++ b/Database/Persist/Sql/Raw.hs
+@@ -22,7 +22,6 @@ rawQuery :: (MonadSqlPersist m, MonadResource m)
+ -> [PersistValue]
+ -> Source m [PersistValue]
+ rawQuery sql vals = do
+- lift $ $logDebugS (pack "SQL") $ pack $ show sql ++ " " ++ show vals
+ conn <- lift askSqlConn
+ bracketP
+ (getStmtConn conn sql)
+@@ -34,7 +33,6 @@ rawExecute x y = liftM (const ()) $ rawExecuteCount x y
+
+ rawExecuteCount :: MonadSqlPersist m => Text -> [PersistValue] -> m Int64
+ rawExecuteCount sql vals = do
+- $logDebugS (pack "SQL") $ pack $ show sql ++ " " ++ show vals
+ stmt <- getStmt sql
+ res <- liftIO $ stmtExecute stmt vals
+ liftIO $ stmtReset stmt
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/primitive_0.5.0.1_0001-disable-i386-opt-stuff-to-allow-cross-compilation.patch b/standalone/android/haskell-patches/primitive_0.5.0.1_0001-disable-i386-opt-stuff-to-allow-cross-compilation.patch
new file mode 100644
index 000000000..1bd926871
--- /dev/null
+++ b/standalone/android/haskell-patches/primitive_0.5.0.1_0001-disable-i386-opt-stuff-to-allow-cross-compilation.patch
@@ -0,0 +1,24 @@
+From 5cb5c3dabb213f809b8328b0b4049f7c754e9c77 Mon Sep 17 00:00:00 2001
+From: Joey Hess <joey@kitenet.net>
+Date: Thu, 28 Feb 2013 23:34:32 -0400
+Subject: [PATCH] disable i386 opt stuff to allow cross-compilation
+
+---
+ primitive.cabal | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/primitive.cabal b/primitive.cabal
+index 8c4328a..9a6093f 100644
+--- a/primitive.cabal
++++ b/primitive.cabal
+@@ -51,7 +51,4 @@ Library
+ includes: primitive-memops.h
+ c-sources: cbits/primitive-memops.c
+ cc-options: -O3 -ftree-vectorize -fomit-frame-pointer
+- if arch(i386) || arch(x86_64) {
+- cc-options: -msse2
+- }
+
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/process_fix-build-with-new-ghc.patch b/standalone/android/haskell-patches/process_fix-build-with-new-ghc.patch
new file mode 100644
index 000000000..a790a316d
--- /dev/null
+++ b/standalone/android/haskell-patches/process_fix-build-with-new-ghc.patch
@@ -0,0 +1,24 @@
+From 0b0d4250cfce44b1a03b50458b4122370ab349ce Mon Sep 17 00:00:00 2001
+From: foo <foo@bar>
+Date: Sat, 21 Sep 2013 21:50:51 +0000
+Subject: [PATCH] fix build with new ghc
+
+---
+ System/Process/Internals.hs | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/System/Process/Internals.hs b/System/Process/Internals.hs
+index a73c6fc..6676a72 100644
+--- a/System/Process/Internals.hs
++++ b/System/Process/Internals.hs
+@@ -61,6 +61,7 @@ import Control.Concurrent
+ import Control.Exception
+ import Foreign.C
+ import Foreign
++import System.IO.Unsafe
+
+ # ifdef __GLASGOW_HASKELL__
+
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/profunctors_3.3-0001-fix-cross-build.patch b/standalone/android/haskell-patches/profunctors_3.3-0001-fix-cross-build.patch
new file mode 100644
index 000000000..45397f3e5
--- /dev/null
+++ b/standalone/android/haskell-patches/profunctors_3.3-0001-fix-cross-build.patch
@@ -0,0 +1,26 @@
+From 392602f5ff14c0b5a801397d075ddcbcd890aa83 Mon Sep 17 00:00:00 2001
+From: Joey Hess <joey@kitenet.net>
+Date: Thu, 18 Apr 2013 17:50:59 -0400
+Subject: [PATCH] fix cross build
+
+---
+ src/Data/Profunctor/Unsafe.hs | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/src/Data/Profunctor/Unsafe.hs b/src/Data/Profunctor/Unsafe.hs
+index 025c7c4..0249274 100644
+--- a/src/Data/Profunctor/Unsafe.hs
++++ b/src/Data/Profunctor/Unsafe.hs
+@@ -40,9 +40,6 @@ import Data.Tagged
+ import Prelude hiding (id,(.),sequence)
+ import Unsafe.Coerce
+
+-{-# ANN module "Hlint: ignore Redundant lambda" #-}
+-{-# ANN module "Hlint: ignore Collapse lambdas" #-}
+-
+ infixr 9 #.
+ infixl 8 .#
+
+--
+1.8.2.rc3
+
diff --git a/standalone/android/haskell-patches/shakespeare-css_1.0.2_0001-remove-TH.patch b/standalone/android/haskell-patches/shakespeare-css_1.0.2_0001-remove-TH.patch
new file mode 100644
index 000000000..1c82eaead
--- /dev/null
+++ b/standalone/android/haskell-patches/shakespeare-css_1.0.2_0001-remove-TH.patch
@@ -0,0 +1,148 @@
+From 05d0b6e6d2f84cd8ff53b8ee3e42021fa02fe8e4 Mon Sep 17 00:00:00 2001
+From: foo <foo@bar>
+Date: Sat, 21 Sep 2013 23:21:52 +0000
+Subject: [PATCH] remove TH
+
+---
+ Text/Cassius.hs | 23 -----------------------
+ Text/CssCommon.hs | 4 ----
+ Text/Lucius.hs | 30 +-----------------------------
+ 3 files changed, 1 insertion(+), 56 deletions(-)
+
+diff --git a/Text/Cassius.hs b/Text/Cassius.hs
+index ce05374..ae56b0a 100644
+--- a/Text/Cassius.hs
++++ b/Text/Cassius.hs
+@@ -13,10 +13,6 @@ module Text.Cassius
+ , renderCss
+ , renderCssUrl
+ -- * Parsing
+- , cassius
+- , cassiusFile
+- , cassiusFileDebug
+- , cassiusFileReload
+ -- * ToCss instances
+ -- ** Color
+ , Color (..)
+@@ -27,11 +23,8 @@ module Text.Cassius
+ , AbsoluteUnit (..)
+ , AbsoluteSize (..)
+ , absoluteSize
+- , EmSize (..)
+- , ExSize (..)
+ , PercentageSize (..)
+ , percentageSize
+- , PixelSize (..)
+ -- * Internal
+ , cassiusUsedIdentifiers
+ ) where
+@@ -42,25 +35,9 @@ import Language.Haskell.TH.Quote (QuasiQuoter (..))
+ import Language.Haskell.TH.Syntax
+ import qualified Data.Text.Lazy as TL
+ import Text.CssCommon
+-import Text.Lucius (lucius)
+ import qualified Text.Lucius
+ import Text.IndentToBrace (i2b)
+
+-cassius :: QuasiQuoter
+-cassius = QuasiQuoter { quoteExp = quoteExp lucius . i2b }
+-
+-cassiusFile :: FilePath -> Q Exp
+-cassiusFile fp = do
+-#ifdef GHC_7_4
+- qAddDependentFile fp
+-#endif
+- contents <- fmap TL.unpack $ qRunIO $ readUtf8File fp
+- quoteExp cassius contents
+-
+-cassiusFileDebug, cassiusFileReload :: FilePath -> Q Exp
+-cassiusFileDebug = cssFileDebug True [|Text.Lucius.parseTopLevels|] Text.Lucius.parseTopLevels
+-cassiusFileReload = cassiusFileDebug
+-
+ -- | Determine which identifiers are used by the given template, useful for
+ -- creating systems like yesod devel.
+ cassiusUsedIdentifiers :: String -> [(Deref, VarType)]
+diff --git a/Text/CssCommon.hs b/Text/CssCommon.hs
+index 719e0a8..8c40e8c 100644
+--- a/Text/CssCommon.hs
++++ b/Text/CssCommon.hs
+@@ -1,4 +1,3 @@
+-{-# LANGUAGE TemplateHaskell #-}
+ {-# LANGUAGE GeneralizedNewtypeDeriving #-}
+ {-# LANGUAGE FlexibleInstances #-}
+ {-# LANGUAGE CPP #-}
+@@ -156,6 +155,3 @@ showSize :: Rational -> String -> String
+ showSize value' unit = printf "%f" value ++ unit
+ where value = fromRational value' :: Double
+
+-mkSizeType "EmSize" "em"
+-mkSizeType "ExSize" "ex"
+-mkSizeType "PixelSize" "px"
+diff --git a/Text/Lucius.hs b/Text/Lucius.hs
+index 89328bd..0a1cf5e 100644
+--- a/Text/Lucius.hs
++++ b/Text/Lucius.hs
+@@ -8,12 +8,8 @@
+ {-# OPTIONS_GHC -fno-warn-missing-fields #-}
+ module Text.Lucius
+ ( -- * Parsing
+- lucius
+- , luciusFile
+- , luciusFileDebug
+- , luciusFileReload
+ -- ** Mixins
+- , luciusMixin
++ luciusMixin
+ , Mixin
+ -- ** Runtime
+ , luciusRT
+@@ -40,11 +36,8 @@ module Text.Lucius
+ , AbsoluteUnit (..)
+ , AbsoluteSize (..)
+ , absoluteSize
+- , EmSize (..)
+- , ExSize (..)
+ , PercentageSize (..)
+ , percentageSize
+- , PixelSize (..)
+ -- * Internal
+ , parseTopLevels
+ , luciusUsedIdentifiers
+@@ -66,18 +59,6 @@ import Data.Monoid (mconcat)
+ import Data.List (isSuffixOf)
+ import Control.Arrow (second)
+
+--- |
+---
+--- >>> renderCss ([lucius|foo{bar:baz}|] undefined)
+--- "foo{bar:baz}"
+-lucius :: QuasiQuoter
+-lucius = QuasiQuoter { quoteExp = luciusFromString }
+-
+-luciusFromString :: String -> Q Exp
+-luciusFromString s =
+- topLevelsToCassius
+- $ either (error . show) id $ parse parseTopLevels s s
+-
+ whiteSpace :: Parser ()
+ whiteSpace = many whiteSpace1 >> return ()
+
+@@ -217,15 +198,6 @@ parseComment = do
+ _ <- manyTill anyChar $ try $ string "*/"
+ return $ ContentRaw ""
+
+-luciusFile :: FilePath -> Q Exp
+-luciusFile fp = do
+- contents <- fmap TL.unpack $ qRunIO $ readUtf8File fp
+- luciusFromString contents
+-
+-luciusFileDebug, luciusFileReload :: FilePath -> Q Exp
+-luciusFileDebug = cssFileDebug False [|parseTopLevels|] parseTopLevels
+-luciusFileReload = luciusFileDebug
+-
+ parseTopLevels :: Parser [TopLevel Unresolved]
+ parseTopLevels =
+ go id
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/shakespeare-css_1.0.2_0002-expose-modules-used-by-TH.patch b/standalone/android/haskell-patches/shakespeare-css_1.0.2_0002-expose-modules-used-by-TH.patch
new file mode 100644
index 000000000..5bf57d527
--- /dev/null
+++ b/standalone/android/haskell-patches/shakespeare-css_1.0.2_0002-expose-modules-used-by-TH.patch
@@ -0,0 +1,26 @@
+From 23e96f0d948e7a26febf1745a4c373faf579c8ee Mon Sep 17 00:00:00 2001
+From: Joey Hess <joey@kitenet.net>
+Date: Mon, 15 Apr 2013 16:32:31 -0400
+Subject: [PATCH] expose modules used by TH
+
+---
+ shakespeare-css.cabal | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/shakespeare-css.cabal b/shakespeare-css.cabal
+index de2497b..468353a 100644
+--- a/shakespeare-css.cabal
++++ b/shakespeare-css.cabal
+@@ -39,8 +39,8 @@ library
+
+ exposed-modules: Text.Cassius
+ Text.Lucius
+- other-modules: Text.MkSizeType
+ Text.Css
++ other-modules: Text.MkSizeType
+ Text.IndentToBrace
+ Text.CssCommon
+ ghc-options: -Wall
+--
+1.8.2.rc3
+
diff --git a/standalone/android/haskell-patches/shakespeare_1.0.3_0001-export-symbol-used-by-TH-splices.patch b/standalone/android/haskell-patches/shakespeare_1.0.3_0001-export-symbol-used-by-TH-splices.patch
new file mode 100644
index 000000000..51443b5d4
--- /dev/null
+++ b/standalone/android/haskell-patches/shakespeare_1.0.3_0001-export-symbol-used-by-TH-splices.patch
@@ -0,0 +1,26 @@
+From 4a75a2f0d77168aa3115b991284a5120484e18f0 Mon Sep 17 00:00:00 2001
+From: foo <foo@bar>
+Date: Sun, 22 Sep 2013 04:59:21 +0000
+Subject: [PATCH] TH exports
+
+---
+ Text/Shakespeare.hs | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/Text/Shakespeare.hs b/Text/Shakespeare.hs
+index 9eb06a2..1290ab1 100644
+--- a/Text/Shakespeare.hs
++++ b/Text/Shakespeare.hs
+@@ -23,6 +23,9 @@ module Text.Shakespeare
+ , Deref
+ , Parser
+
++ -- used by TH
++ , pack'
++
+ #ifdef TEST_EXPORT
+ , preFilter
+ #endif
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/skein_hardcode_little-endian.patch b/standalone/android/haskell-patches/skein_hardcode_little-endian.patch
new file mode 100644
index 000000000..788d8e521
--- /dev/null
+++ b/standalone/android/haskell-patches/skein_hardcode_little-endian.patch
@@ -0,0 +1,24 @@
+From 3a04b41ffce4e4e87b0fedd3a1e3434a3f06cc76 Mon Sep 17 00:00:00 2001
+From: foo <foo@bar>
+Date: Sun, 22 Sep 2013 00:18:12 +0000
+Subject: [PATCH] hardcode little endian
+
+---
+ c_impl/optimized/skein_port.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/c_impl/optimized/skein_port.h b/c_impl/optimized/skein_port.h
+index a2d0fc2..6929bb0 100644
+--- a/c_impl/optimized/skein_port.h
++++ b/c_impl/optimized/skein_port.h
+@@ -45,6 +45,7 @@ typedef uint64_t u64b_t; /* 64-bit unsigned integer */
+ * platform-specific code instead (e.g., for big-endian CPUs).
+ *
+ */
++#define SKEIN_NEED_SWAP (0)
+ #ifndef SKEIN_NEED_SWAP /* compile-time "override" for endianness? */
+
+ #include "brg_endian.h" /* get endianness selection */
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/socks_0.4.2_0001-remove-IPv6-stuff.patch b/standalone/android/haskell-patches/socks_0.4.2_0001-remove-IPv6-stuff.patch
new file mode 100644
index 000000000..c9723f3f7
--- /dev/null
+++ b/standalone/android/haskell-patches/socks_0.4.2_0001-remove-IPv6-stuff.patch
@@ -0,0 +1,135 @@
+From e1a2f80f6bec25921ab645a0aaf1c6422a8917ab Mon Sep 17 00:00:00 2001
+From: dummy <dummy@example.com>
+Date: Mon, 11 Nov 2013 01:06:58 +0000
+Subject: [PATCH] fix
+
+---
+ Network/Socks5/Command.hs | 8 +-------
+ Network/Socks5/Conf.hs | 1 -
+ Network/Socks5/Lowlevel.hs | 1 -
+ Network/Socks5/Types.hs | 18 +-----------------
+ Network/Socks5/Wire.hs | 2 --
+ 5 files changed, 2 insertions(+), 28 deletions(-)
+
+diff --git a/Network/Socks5/Command.hs b/Network/Socks5/Command.hs
+index db95fbd..fdba5ec 100644
+--- a/Network/Socks5/Command.hs
++++ b/Network/Socks5/Command.hs
+@@ -13,7 +13,6 @@ module Network.Socks5.Command
+ , Connect(..)
+ , Command(..)
+ , connectIPV4
+- , connectIPV6
+ , connectDomainName
+ -- * lowlevel interface
+ , rpc
+@@ -29,7 +28,7 @@ import qualified Data.ByteString as B
+ import qualified Data.ByteString.Char8 as BC
+ import Data.Serialize
+
+-import Network.Socket (Socket, PortNumber, HostAddress, HostAddress6)
++import Network.Socket (Socket, PortNumber, HostAddress)
+ import Network.Socket.ByteString
+
+ import Network.Socks5.Types
+@@ -65,11 +64,6 @@ connectIPV4 socket hostaddr port = onReply <$> rpc_ socket (Connect $ SocksAddre
+ where onReply (SocksAddrIPV4 h, p) = (h, p)
+ onReply _ = error "ipv4 requested, got something different"
+
+-connectIPV6 :: Socket -> HostAddress6 -> PortNumber -> IO (HostAddress6, PortNumber)
+-connectIPV6 socket hostaddr6 port = onReply <$> rpc_ socket (Connect $ SocksAddress (SocksAddrIPV6 hostaddr6) port)
+- where onReply (SocksAddrIPV6 h, p) = (h, p)
+- onReply _ = error "ipv6 requested, got something different"
+-
+ -- TODO: FQDN should only be ascii, maybe putting a "fqdn" data type
+ -- in front to make sure and make the BC.pack safe.
+ connectDomainName :: Socket -> String -> PortNumber -> IO (SocksHostAddress, PortNumber)
+diff --git a/Network/Socks5/Conf.hs b/Network/Socks5/Conf.hs
+index c29ff7b..007d382 100644
+--- a/Network/Socks5/Conf.hs
++++ b/Network/Socks5/Conf.hs
+@@ -47,5 +47,4 @@ defaultSocksConfFromSockAddr sockaddr = SocksConf server SocksVer5
+ where server = SocksAddress haddr port
+ (haddr,port) = case sockaddr of
+ SockAddrInet p h -> (SocksAddrIPV4 h, p)
+- SockAddrInet6 p _ h _ -> (SocksAddrIPV6 h, p)
+ _ -> error "unsupported unix sockaddr type"
+diff --git a/Network/Socks5/Lowlevel.hs b/Network/Socks5/Lowlevel.hs
+index c10d9b9..2c3d59c 100644
+--- a/Network/Socks5/Lowlevel.hs
++++ b/Network/Socks5/Lowlevel.hs
+@@ -17,7 +17,6 @@ resolveToSockAddr :: SocksAddress -> IO SockAddr
+ resolveToSockAddr (SocksAddress sockHostAddr port) =
+ case sockHostAddr of
+ SocksAddrIPV4 ha -> return $ SockAddrInet port ha
+- SocksAddrIPV6 ha6 -> return $ SockAddrInet6 port 0 ha6 0
+ SocksAddrDomainName bs -> do he <- getHostByName (BC.unpack bs)
+ return $ SockAddrInet port (hostAddress he)
+
+diff --git a/Network/Socks5/Types.hs b/Network/Socks5/Types.hs
+index 7fbec25..17c7c83 100644
+--- a/Network/Socks5/Types.hs
++++ b/Network/Socks5/Types.hs
+@@ -19,7 +19,7 @@ module Network.Socks5.Types
+ import Data.ByteString (ByteString)
+ import Data.Word
+ import Data.Data
+-import Network.Socket (HostAddress, HostAddress6, PortNumber)
++import Network.Socket (HostAddress, PortNumber)
+ import Control.Exception
+ import qualified Data.ByteString.Char8 as BC
+ import Numeric (showHex)
+@@ -53,12 +53,10 @@ data SocksMethod =
+ data SocksHostAddress =
+ SocksAddrIPV4 !HostAddress
+ | SocksAddrDomainName !ByteString
+- | SocksAddrIPV6 !HostAddress6
+ deriving (Eq,Ord)
+
+ instance Show SocksHostAddress where
+ show (SocksAddrIPV4 ha) = "SocksAddrIPV4(" ++ showHostAddress ha ++ ")"
+- show (SocksAddrIPV6 ha6) = "SocksAddrIPV6(" ++ showHostAddress6 ha6 ++ ")"
+ show (SocksAddrDomainName dn) = "SocksAddrDomainName(" ++ BC.unpack dn ++ ")"
+
+ -- | Converts a HostAddress to a String in dot-decimal notation
+@@ -69,20 +67,6 @@ showHostAddress num = concat [show q1, ".", show q2, ".", show q3, ".", show q4]
+ (num''',q3) = num'' `quotRem` 256
+ (_,q4) = num''' `quotRem` 256
+
+--- | Converts a IPv6 HostAddress6 to standard hex notation
+-showHostAddress6 :: HostAddress6 -> String
+-showHostAddress6 (a,b,c,d) =
+- (concat . intersperse ":" . map (flip showHex ""))
+- [p1,p2,p3,p4,p5,p6,p7,p8]
+- where (a',p2) = a `quotRem` 65536
+- (_,p1) = a' `quotRem` 65536
+- (b',p4) = b `quotRem` 65536
+- (_,p3) = b' `quotRem` 65536
+- (c',p6) = c `quotRem` 65536
+- (_,p5) = c' `quotRem` 65536
+- (d',p8) = d `quotRem` 65536
+- (_,p7) = d' `quotRem` 65536
+-
+ -- | Describe a Socket address on the SOCKS protocol
+ data SocksAddress = SocksAddress !SocksHostAddress !PortNumber
+ deriving (Show,Eq,Ord)
+diff --git a/Network/Socks5/Wire.hs b/Network/Socks5/Wire.hs
+index 10bd262..a30f32e 100644
+--- a/Network/Socks5/Wire.hs
++++ b/Network/Socks5/Wire.hs
+@@ -46,12 +46,10 @@ data SocksResponse = SocksResponse
+
+ getAddr 1 = SocksAddrIPV4 <$> getWord32host
+ getAddr 3 = SocksAddrDomainName <$> (getWord8 >>= getByteString . fromIntegral)
+-getAddr 4 = SocksAddrIPV6 <$> (liftM4 (,,,) getWord32host getWord32host getWord32host getWord32host)
+ getAddr n = error ("cannot get unknown socket address type: " ++ show n)
+
+ putAddr (SocksAddrIPV4 h) = putWord8 1 >> putWord32host h
+ putAddr (SocksAddrDomainName b) = putWord8 3 >> putWord8 (fromIntegral $ B.length b) >> putByteString b
+-putAddr (SocksAddrIPV6 (a,b,c,d)) = putWord8 4 >> mapM_ putWord32host [a,b,c,d]
+
+ getSocksRequest 5 = do
+ cmd <- toEnum . fromIntegral <$> getWord8
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/stm-chans_cross-build.patch b/standalone/android/haskell-patches/stm-chans_cross-build.patch
new file mode 100644
index 000000000..f0964d693
--- /dev/null
+++ b/standalone/android/haskell-patches/stm-chans_cross-build.patch
@@ -0,0 +1,25 @@
+From c1b166ad1dbed80f7eed7b9c1b2dc5c668eeb8fc Mon Sep 17 00:00:00 2001
+From: androidbuilder <androidbuilder@example.com>
+Date: Fri, 18 Oct 2013 23:28:56 +0000
+Subject: [PATCH] cross build
+
+---
+ stm-chans.cabal | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/stm-chans.cabal b/stm-chans.cabal
+index 89d4780..2119a74 100644
+--- a/stm-chans.cabal
++++ b/stm-chans.cabal
+@@ -6,7 +6,7 @@
+ -- and source-repository:.
+ Cabal-Version: >= 1.6
+ -- We need a custom build in order to define __HADDOCK__
+-Build-Type: Custom
++Build-Type: Simple
+
+ Name: stm-chans
+ Version: 3.0.0
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/unix-time_hack-for-Bionic.patch b/standalone/android/haskell-patches/unix-time_hack-for-Bionic.patch
new file mode 100644
index 000000000..be7956bea
--- /dev/null
+++ b/standalone/android/haskell-patches/unix-time_hack-for-Bionic.patch
@@ -0,0 +1,56 @@
+From e6d5c141186dbdbe97c698294485ffc4dcd3a843 Mon Sep 17 00:00:00 2001
+From: dummy <dummy@example.com>
+Date: Fri, 18 Oct 2013 16:45:50 +0000
+Subject: [PATCH] hack for bionic + cross build
+
+---
+ Data/UnixTime/Types.hsc | 12 ------------
+ cbits/conv.c | 2 +-
+ 2 files changed, 1 insertion(+), 13 deletions(-)
+
+diff --git a/Data/UnixTime/Types.hsc b/Data/UnixTime/Types.hsc
+index d30f39b..ec7ca4c 100644
+--- a/Data/UnixTime/Types.hsc
++++ b/Data/UnixTime/Types.hsc
+@@ -9,8 +9,6 @@ import Foreign.Storable
+
+ #include <sys/time.h>
+
+-#let alignment t = "%lu", (unsigned long)offsetof(struct {char x__; t (y__); }, y__)
+-
+ -- |
+ -- Data structure for Unix time.
+ data UnixTime = UnixTime {
+@@ -20,16 +18,6 @@ data UnixTime = UnixTime {
+ , utMicroSeconds :: {-# UNPACK #-} !Int32
+ } deriving (Eq,Ord,Show)
+
+-instance Storable UnixTime where
+- sizeOf _ = (#size struct timeval)
+- alignment _ = (#alignment struct timeval)
+- peek ptr = UnixTime
+- <$> (#peek struct timeval, tv_sec) ptr
+- <*> (#peek struct timeval, tv_usec) ptr
+- poke ptr ut = do
+- (#poke struct timeval, tv_sec) ptr (utSeconds ut)
+- (#poke struct timeval, tv_usec) ptr (utMicroSeconds ut)
+-
+ -- |
+ -- Format of the strptime()/strftime() style.
+ type Format = ByteString
+diff --git a/cbits/conv.c b/cbits/conv.c
+index 7ff7b87..2e4c870 100644
+--- a/cbits/conv.c
++++ b/cbits/conv.c
+@@ -55,7 +55,7 @@ time_t c_parse_unix_time_gmt(char *fmt, char *src) {
+ #else
+ strptime(src, fmt, &dst);
+ #endif
+- return timegm(&dst);
++ return NULL; /* timegm(&dst); (not in Bionic) */
+ }
+
+ size_t c_format_unix_time(char *fmt, time_t src, char* dst, int siz) {
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/uuid_build-without-v1-uuid-which-needs-network-info.patch b/standalone/android/haskell-patches/uuid_build-without-v1-uuid-which-needs-network-info.patch
new file mode 100644
index 000000000..12cb2a922
--- /dev/null
+++ b/standalone/android/haskell-patches/uuid_build-without-v1-uuid-which-needs-network-info.patch
@@ -0,0 +1,79 @@
+From 87283f9b6f992a7f0e36c7b1bafc288bf2bf106a Mon Sep 17 00:00:00 2001
+From: androidbuilder <androidbuilder@example.com>
+Date: Mon, 11 Nov 2013 02:46:27 +0000
+Subject: [PATCH] build without v1 uuid which needs network-ino
+
+---
+ Data/UUID/Util.hs | 11 -----------
+ Data/UUID/V1.hs | 2 --
+ uuid.cabal | 2 --
+ 3 files changed, 15 deletions(-)
+
+diff --git a/Data/UUID/Util.hs b/Data/UUID/Util.hs
+index 581391a..399e508 100644
+--- a/Data/UUID/Util.hs
++++ b/Data/UUID/Util.hs
+@@ -3,7 +3,6 @@ module Data.UUID.Util (
+ UnpackedUUID(..)
+ , unpack, pack
+ , version
+- , extractMac
+ , extractTime
+ , setTime
+ ) where
+@@ -13,7 +12,6 @@ import Data.Word
+ import Data.Word.Util
+ import Data.Bits
+ import Data.UUID.Internal
+-import Network.Info
+ import Data.Int (Int64)
+
+ version :: UUID -> Int
+@@ -43,12 +41,3 @@ extractTime uuid =
+ timeAndVersionToTime :: Word16 -> Word16
+ timeAndVersionToTime tv = tv .&. 0x0FFF
+
+-extractMac :: UUID -> Maybe MAC
+-extractMac uuid =
+- if version uuid == 1
+- then Just $
+- MAC (node_0 unpacked) (node_1 unpacked) (node_2 unpacked) (node_3 unpacked) (node_4 unpacked) (node_5 unpacked)
+- else Nothing
+- where
+- unpacked = unpack uuid
+-
+diff --git a/Data/UUID/V1.hs b/Data/UUID/V1.hs
+index 067e729..ca4c235 100644
+--- a/Data/UUID/V1.hs
++++ b/Data/UUID/V1.hs
+@@ -37,8 +37,6 @@ import System.IO.Unsafe
+
+ import qualified System.Random as R
+
+-import Network.Info
+-
+ import Data.UUID.Builder
+ import Data.UUID.Internal
+
+diff --git a/uuid.cabal b/uuid.cabal
+index 0a53059..57b1b86 100644
+--- a/uuid.cabal
++++ b/uuid.cabal
+@@ -32,14 +32,12 @@ Library
+ cryptohash >= 0.7 && < 0.12,
+ deepseq == 1.3.*,
+ hashable (>= 1.1.1.0 && < 1.2.0) || (>= 1.2.1 && < 1.3),
+- network-info == 0.2.*,
+ random >= 1.0.1 && < 1.1,
+ time >= 1.1 && < 1.5
+
+ Exposed-Modules:
+ Data.UUID
+ Data.UUID.Util
+- Data.UUID.V1
+ Data.UUID.V3
+ Data.UUID.V4
+ Data.UUID.V5
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/vector_hack-to-build-with-new-ghc.patch b/standalone/android/haskell-patches/vector_hack-to-build-with-new-ghc.patch
new file mode 100644
index 000000000..4d39e91cf
--- /dev/null
+++ b/standalone/android/haskell-patches/vector_hack-to-build-with-new-ghc.patch
@@ -0,0 +1,24 @@
+From b0a79f4f98188ba5d43b7e3912b36d34d099ab65 Mon Sep 17 00:00:00 2001
+From: dummy <dummy@example.com>
+Date: Fri, 18 Oct 2013 23:20:35 +0000
+Subject: [PATCH] cross build
+
+---
+ Data/Vector/Fusion/Stream/Monadic.hs | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/Data/Vector/Fusion/Stream/Monadic.hs b/Data/Vector/Fusion/Stream/Monadic.hs
+index 51fec75..b089b3d 100644
+--- a/Data/Vector/Fusion/Stream/Monadic.hs
++++ b/Data/Vector/Fusion/Stream/Monadic.hs
+@@ -101,7 +101,6 @@ import GHC.Exts ( SpecConstrAnnotation(..) )
+
+ data SPEC = SPEC | SPEC2
+ #if __GLASGOW_HASKELL__ >= 700
+-{-# ANN type SPEC ForceSpecConstr #-}
+ #endif
+
+ emptyStream :: String
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/wai-app-static_deal-with-TH.patch b/standalone/android/haskell-patches/wai-app-static_deal-with-TH.patch
new file mode 100644
index 000000000..d9860f922
--- /dev/null
+++ b/standalone/android/haskell-patches/wai-app-static_deal-with-TH.patch
@@ -0,0 +1,54 @@
+From 432a8fc47bb11cf8fd0a832e033cfb94a6332dbe Mon Sep 17 00:00:00 2001
+From: foo <foo@bar>
+Date: Sun, 22 Sep 2013 07:29:39 +0000
+Subject: [PATCH] deal with TH
+
+Export modules referenced by it.
+
+Should not need these icons in git-annex, so not worth using the Evil
+Splicer.
+---
+ Network/Wai/Application/Static.hs | 4 ----
+ wai-app-static.cabal | 2 +-
+ 2 files changed, 1 insertion(+), 5 deletions(-)
+
+diff --git a/Network/Wai/Application/Static.hs b/Network/Wai/Application/Static.hs
+index 3f07391..75709b7 100644
+--- a/Network/Wai/Application/Static.hs
++++ b/Network/Wai/Application/Static.hs
+@@ -33,8 +33,6 @@ import Control.Monad.IO.Class (liftIO)
+
+ import Blaze.ByteString.Builder (toByteString)
+
+-import Data.FileEmbed (embedFile)
+-
+ import Data.Text (Text)
+ import qualified Data.Text as T
+
+@@ -198,8 +196,6 @@ staticAppPieces _ _ req
+ H.status405
+ [("Content-Type", "text/plain")]
+ "Only GET is supported"
+-staticAppPieces _ [".hidden", "folder.png"] _ = return $ W.responseLBS H.status200 [("Content-Type", "image/png")] $ L.fromChunks [$(embedFile "images/folder.png")]
+-staticAppPieces _ [".hidden", "haskell.png"] _ = return $ W.responseLBS H.status200 [("Content-Type", "image/png")] $ L.fromChunks [$(embedFile "images/haskell.png")]
+ staticAppPieces ss rawPieces req = liftIO $ do
+ case toPieces rawPieces of
+ Just pieces -> checkPieces ss pieces req >>= response
+diff --git a/wai-app-static.cabal b/wai-app-static.cabal
+index ec22813..e944caa 100644
+--- a/wai-app-static.cabal
++++ b/wai-app-static.cabal
+@@ -56,9 +56,9 @@ library
+ WaiAppStatic.Storage.Embedded
+ WaiAppStatic.Listing
+ WaiAppStatic.Types
+- other-modules: Util
+ WaiAppStatic.Storage.Embedded.Runtime
+ WaiAppStatic.Storage.Embedded.TH
++ other-modules: Util
+ ghc-options: -Wall
+ extensions: CPP
+
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/yesod-auth_don-t-really-build.patch b/standalone/android/haskell-patches/yesod-auth_don-t-really-build.patch
new file mode 100644
index 000000000..7016e001c
--- /dev/null
+++ b/standalone/android/haskell-patches/yesod-auth_don-t-really-build.patch
@@ -0,0 +1,34 @@
+From 3eb7b0a42099721dc19363ac41319efeed4ac5f9 Mon Sep 17 00:00:00 2001
+From: foo <foo@bar>
+Date: Sun, 22 Sep 2013 05:19:53 +0000
+Subject: [PATCH] don't really build
+
+---
+ yesod-auth.cabal | 11 +----------
+ 1 file changed, 1 insertion(+), 10 deletions(-)
+
+diff --git a/yesod-auth.cabal b/yesod-auth.cabal
+index 591ced5..11217be 100644
+--- a/yesod-auth.cabal
++++ b/yesod-auth.cabal
+@@ -52,16 +52,7 @@ library
+ , safe
+ , time
+
+- exposed-modules: Yesod.Auth
+- Yesod.Auth.BrowserId
+- Yesod.Auth.Dummy
+- Yesod.Auth.Email
+- Yesod.Auth.OpenId
+- Yesod.Auth.Rpxnow
+- Yesod.Auth.HashDB
+- Yesod.Auth.Message
+- Yesod.Auth.GoogleEmail
+- other-modules: Yesod.Auth.Routes
++ exposed-modules:
+ ghc-options: -Wall
+
+ source-repository head
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/yesod-core_expand_TH.patch b/standalone/android/haskell-patches/yesod-core_expand_TH.patch
new file mode 100644
index 000000000..1687ff0e4
--- /dev/null
+++ b/standalone/android/haskell-patches/yesod-core_expand_TH.patch
@@ -0,0 +1,411 @@
+From 7583457fb410d07f480a2aa7d6c2f174324b3592 Mon Sep 17 00:00:00 2001
+From: dummy <dummy@example.com>
+Date: Sat, 19 Oct 2013 02:03:18 +0000
+Subject: [PATCH] hackity
+
+---
+ Yesod/Core.hs | 2 -
+ Yesod/Core/Class/Yesod.hs | 247 ++++++++++++++++++++++++++++++--------------
+ Yesod/Core/Dispatch.hs | 7 --
+ Yesod/Core/Handler.hs | 24 ++---
+ Yesod/Core/Internal/Run.hs | 2 -
+ 5 files changed, 179 insertions(+), 103 deletions(-)
+
+diff --git a/Yesod/Core.hs b/Yesod/Core.hs
+index 12e59d5..f1ff21c 100644
+--- a/Yesod/Core.hs
++++ b/Yesod/Core.hs
+@@ -94,8 +94,6 @@ module Yesod.Core
+ , JavascriptUrl
+ , renderJavascriptUrl
+ -- ** Cassius/Lucius
+- , cassius
+- , lucius
+ , CssUrl
+ , renderCssUrl
+ ) where
+diff --git a/Yesod/Core/Class/Yesod.hs b/Yesod/Core/Class/Yesod.hs
+index cf02a1a..3f1e88e 100644
+--- a/Yesod/Core/Class/Yesod.hs
++++ b/Yesod/Core/Class/Yesod.hs
+@@ -9,6 +9,10 @@ import Yesod.Core.Content
+ import Yesod.Core.Handler
+
+ import Yesod.Routes.Class
++import qualified Text.Blaze.Internal
++import qualified Control.Monad.Logger
++import qualified Text.Hamlet
++import qualified Data.Foldable
+
+ import Blaze.ByteString.Builder (Builder)
+ import Blaze.ByteString.Builder.Char.Utf8 (fromText)
+@@ -87,18 +91,27 @@ class RenderRoute site => Yesod site where
+ defaultLayout w = do
+ p <- widgetToPageContent w
+ mmsg <- getMessage
+- giveUrlRenderer [hamlet|
+- $newline never
+- $doctype 5
+- <html>
+- <head>
+- <title>#{pageTitle p}
+- ^{pageHead p}
+- <body>
+- $maybe msg <- mmsg
+- <p .message>#{msg}
+- ^{pageBody p}
+- |]
++ giveUrlRenderer $ \ _render_aHra
++ -> do { id
++ ((Text.Blaze.Internal.preEscapedText . T.pack)
++ "<!DOCTYPE html>\n<html><head><title>");
++ id (TBH.toHtml (pageTitle p));
++ id ((Text.Blaze.Internal.preEscapedText . T.pack) "</title>");
++ Text.Hamlet.asHtmlUrl (pageHead p) _render_aHra;
++ id ((Text.Blaze.Internal.preEscapedText . T.pack) "</head><body>");
++ Text.Hamlet.maybeH
++ mmsg
++ (\ msg_aHrb
++ -> do { id
++ ((Text.Blaze.Internal.preEscapedText . T.pack)
++ "<p class=\"message\">");
++ id (TBH.toHtml msg_aHrb);
++ id ((Text.Blaze.Internal.preEscapedText . T.pack) "</p>") })
++ Nothing;
++ Text.Hamlet.asHtmlUrl (pageBody p) _render_aHra;
++ id
++ ((Text.Blaze.Internal.preEscapedText . T.pack) "</body></html>") }
++
+
+ -- | Override the rendering function for a particular URL. One use case for
+ -- this is to offload static hosting to a different domain name to avoid
+@@ -356,45 +369,103 @@ widgetToPageContent w = do
+ -- modernizr should be at the end of the <head> http://www.modernizr.com/docs/#installing
+ -- the asynchronous loader means your page doesn't have to wait for all the js to load
+ let (mcomplete, asyncScripts) = asyncHelper render scripts jscript jsLoc
+- regularScriptLoad = [hamlet|
+- $newline never
+- $forall s <- scripts
+- ^{mkScriptTag s}
+- $maybe j <- jscript
+- $maybe s <- jsLoc
+- <script src="#{s}">
+- $nothing
+- <script>^{jelper j}
+- |]
+-
+- headAll = [hamlet|
+- $newline never
+- \^{head'}
+- $forall s <- stylesheets
+- ^{mkLinkTag s}
+- $forall s <- css
+- $maybe t <- right $ snd s
+- $maybe media <- fst s
+- <link rel=stylesheet media=#{media} href=#{t}>
+- $nothing
+- <link rel=stylesheet href=#{t}>
+- $maybe content <- left $ snd s
+- $maybe media <- fst s
+- <style media=#{media}>#{content}
+- $nothing
+- <style>#{content}
+- $case jsLoader master
+- $of BottomOfBody
+- $of BottomOfHeadAsync asyncJsLoader
+- ^{asyncJsLoader asyncScripts mcomplete}
+- $of BottomOfHeadBlocking
+- ^{regularScriptLoad}
+- |]
+- let bodyScript = [hamlet|
+- $newline never
+- ^{body}
+- ^{regularScriptLoad}
+- |]
++ regularScriptLoad = \ _render_aHsO
++ -> do { Data.Foldable.mapM_
++ (\ s_aHsP
++ -> Text.Hamlet.asHtmlUrl (mkScriptTag s_aHsP) _render_aHsO)
++ scripts;
++ Text.Hamlet.maybeH
++ jscript
++ (\ j_aHsQ
++ -> Text.Hamlet.maybeH
++ jsLoc
++ (\ s_aHsR
++ -> do { id
++ ((Text.Blaze.Internal.preEscapedText . T.pack)
++ "<script src=\"");
++ id (TBH.toHtml s_aHsR);
++ id
++ ((Text.Blaze.Internal.preEscapedText . T.pack)
++ "\"></script>") })
++ (Just
++ (do { id
++ ((Text.Blaze.Internal.preEscapedText . T.pack) "<script>");
++ Text.Hamlet.asHtmlUrl (jelper j_aHsQ) _render_aHsO;
++ id ((Text.Blaze.Internal.preEscapedText . T.pack) "</script>") })))
++ Nothing }
++
++
++ headAll = \ _render_aHsW
++ -> do { Text.Hamlet.asHtmlUrl head' _render_aHsW;
++ Data.Foldable.mapM_
++ (\ s_aHsX -> Text.Hamlet.asHtmlUrl (mkLinkTag s_aHsX) _render_aHsW)
++ stylesheets;
++ Data.Foldable.mapM_
++ (\ s_aHsY
++ -> do { Text.Hamlet.maybeH
++ (right (snd s_aHsY))
++ (\ t_aHsZ
++ -> Text.Hamlet.maybeH
++ (fst s_aHsY)
++ (\ media_aHt0
++ -> do { id
++ ((Text.Blaze.Internal.preEscapedText . T.pack)
++ "<link rel=\"stylesheet\" media=\"");
++ id (TBH.toHtml media_aHt0);
++ id
++ ((Text.Blaze.Internal.preEscapedText . T.pack)
++ "\" href=\"");
++ id (TBH.toHtml t_aHsZ);
++ id
++ ((Text.Blaze.Internal.preEscapedText . T.pack)
++ "\">") })
++ (Just
++ (do { id
++ ((Text.Blaze.Internal.preEscapedText . T.pack)
++ "<link rel=\"stylesheet\" href=\"");
++ id (TBH.toHtml t_aHsZ);
++ id
++ ((Text.Blaze.Internal.preEscapedText . T.pack)
++ "\">") })))
++ Nothing;
++ Text.Hamlet.maybeH
++ (left (snd s_aHsY))
++ (\ content_aHt1
++ -> Text.Hamlet.maybeH
++ (fst s_aHsY)
++ (\ media_aHt2
++ -> do { id
++ ((Text.Blaze.Internal.preEscapedText . T.pack)
++ "<style media=\"");
++ id (TBH.toHtml media_aHt2);
++ id
++ ((Text.Blaze.Internal.preEscapedText . T.pack)
++ "\">");
++ id (TBH.toHtml content_aHt1);
++ id
++ ((Text.Blaze.Internal.preEscapedText . T.pack)
++ "</style>") })
++ (Just
++ (do { id
++ ((Text.Blaze.Internal.preEscapedText . T.pack)
++ "<style>");
++ id (TBH.toHtml content_aHt1);
++ id
++ ((Text.Blaze.Internal.preEscapedText . T.pack)
++ "</style>") })))
++ Nothing })
++ css;
++ case jsLoader master of {
++ BottomOfBody -> return ()
++ ; BottomOfHeadAsync asyncJsLoader_aHt3
++ -> Text.Hamlet.asHtmlUrl
++ (asyncJsLoader_aHt3 asyncScripts mcomplete) _render_aHsW
++ ; BottomOfHeadBlocking
++ -> Text.Hamlet.asHtmlUrl regularScriptLoad _render_aHsW } }
++
++ let bodyScript = \ _render_aHt8 -> do { Text.Hamlet.asHtmlUrl body _render_aHt8;
++ Text.Hamlet.asHtmlUrl regularScriptLoad _render_aHt8 }
++
+
+ return $ PageContent title headAll $
+ case jsLoader master of
+@@ -424,10 +495,13 @@ defaultErrorHandler NotFound = selectRep $ do
+ r <- waiRequest
+ let path' = TE.decodeUtf8With TEE.lenientDecode $ W.rawPathInfo r
+ setTitle "Not Found"
+- toWidget [hamlet|
+- <h1>Not Found
+- <p>#{path'}
+- |]
++ toWidget $ \ _render_aHte
++ -> do { id
++ ((Text.Blaze.Internal.preEscapedText . T.pack)
++ "<h1>Not Found</h1>\n<p>");
++ id (TBH.toHtml path');
++ id ((Text.Blaze.Internal.preEscapedText . T.pack) "</p>") }
++
+ provideRep $ return $ object ["message" .= ("Not Found" :: Text)]
+
+ -- For API requests.
+@@ -437,10 +511,11 @@ defaultErrorHandler NotFound = selectRep $ do
+ defaultErrorHandler NotAuthenticated = selectRep $ do
+ provideRep $ defaultLayout $ do
+ setTitle "Not logged in"
+- toWidget [hamlet|
+- <h1>Not logged in
+- <p style="display:none;">Set the authRoute and the user will be redirected there.
+- |]
++ toWidget $ \ _render_aHti
++ -> id
++ ((Text.Blaze.Internal.preEscapedText . T.pack)
++ "<h1>Not logged in</h1>\n<p style=\"none;\">Set the authRoute and the user will be redirected there.</p>")
++
+
+ provideRep $ do
+ -- 401 *MUST* include a WWW-Authenticate header
+@@ -462,10 +537,13 @@ defaultErrorHandler NotAuthenticated = selectRep $ do
+ defaultErrorHandler (PermissionDenied msg) = selectRep $ do
+ provideRep $ defaultLayout $ do
+ setTitle "Permission Denied"
+- toWidget [hamlet|
+- <h1>Permission denied
+- <p>#{msg}
+- |]
++ toWidget $ \ _render_aHtq
++ -> do { id
++ ((Text.Blaze.Internal.preEscapedText . T.pack)
++ "<h1>Permission denied</h1>\n<p>");
++ id (TBH.toHtml msg);
++ id ((Text.Blaze.Internal.preEscapedText . T.pack) "</p>") }
++
+ provideRep $
+ return $ object $ [
+ "message" .= ("Permission Denied. " <> msg)
+@@ -474,30 +552,43 @@ defaultErrorHandler (PermissionDenied msg) = selectRep $ do
+ defaultErrorHandler (InvalidArgs ia) = selectRep $ do
+ provideRep $ defaultLayout $ do
+ setTitle "Invalid Arguments"
+- toWidget [hamlet|
+- <h1>Invalid Arguments
+- <ul>
+- $forall msg <- ia
+- <li>#{msg}
+- |]
++ toWidget $ \ _render_aHtv
++ -> do { id
++ ((Text.Blaze.Internal.preEscapedText . T.pack)
++ "<h1>Invalid Arguments</h1>\n<ul>");
++ Data.Foldable.mapM_
++ (\ msg_aHtw
++ -> do { id ((Text.Blaze.Internal.preEscapedText . T.pack) "<li>");
++ id (TBH.toHtml msg_aHtw);
++ id ((Text.Blaze.Internal.preEscapedText . T.pack) "</li>") })
++ ia;
++ id ((Text.Blaze.Internal.preEscapedText . T.pack) "</ul>") }
++
+ provideRep $ return $ object ["message" .= ("Invalid Arguments" :: Text), "errors" .= ia]
+ defaultErrorHandler (InternalError e) = do
+- $logErrorS "yesod-core" e
+ selectRep $ do
+ provideRep $ defaultLayout $ do
+ setTitle "Internal Server Error"
+- toWidget [hamlet|
+- <h1>Internal Server Error
+- <pre>#{e}
+- |]
++ toWidget $ \ _render_aHtC
++ -> do { id
++ ((Text.Blaze.Internal.preEscapedText . T.pack)
++ "<h1>Internal Server Error</h1>\n<pre>");
++ id (TBH.toHtml e);
++ id ((Text.Blaze.Internal.preEscapedText . T.pack) "</pre>") }
++
+ provideRep $ return $ object ["message" .= ("Internal Server Error" :: Text), "error" .= e]
+ defaultErrorHandler (BadMethod m) = selectRep $ do
+ provideRep $ defaultLayout $ do
+ setTitle"Bad Method"
+- toWidget [hamlet|
+- <h1>Method Not Supported
+- <p>Method <code>#{S8.unpack m}</code> not supported
+- |]
++ toWidget $ \ _render_aHtH
++ -> do { id
++ ((Text.Blaze.Internal.preEscapedText . T.pack)
++ "<h1>Method Not Supported</h1>\n<p>Method <code>");
++ id (TBH.toHtml (S8.unpack m));
++ id
++ ((Text.Blaze.Internal.preEscapedText . T.pack)
++ "</code> not supported</p>") }
++
+ provideRep $ return $ object ["message" .= ("Bad method" :: Text), "method" .= m]
+
+ asyncHelper :: (url -> [x] -> Text)
+diff --git a/Yesod/Core/Dispatch.hs b/Yesod/Core/Dispatch.hs
+index 335a15c..4ca05da 100644
+--- a/Yesod/Core/Dispatch.hs
++++ b/Yesod/Core/Dispatch.hs
+@@ -123,13 +123,6 @@ toWaiApp site = do
+ , yreSite = site
+ , yreSessionBackend = sb
+ }
+- messageLoggerSource
+- site
+- logger
+- $(qLocation >>= liftLoc)
+- "yesod-core"
+- LevelInfo
+- (toLogStr ("Application launched" :: S.ByteString))
+ middleware <- mkDefaultMiddlewares logger
+ return $ middleware $ toWaiAppYre yre
+
+diff --git a/Yesod/Core/Handler.hs b/Yesod/Core/Handler.hs
+index f3b1799..d819b04 100644
+--- a/Yesod/Core/Handler.hs
++++ b/Yesod/Core/Handler.hs
+@@ -152,7 +152,7 @@ import qualified Control.Monad.Trans.Writer as Writer
+
+ import Control.Monad.IO.Class (MonadIO, liftIO)
+ import Control.Monad.Trans.Resource (MonadResource, liftResourceT)
+-
++import qualified Text.Blaze.Internal
+ import qualified Network.HTTP.Types as H
+ import qualified Network.Wai as W
+ import Control.Monad.Trans.Class (lift)
+@@ -710,19 +710,15 @@ redirectToPost :: (MonadHandler m, RedirectUrl (HandlerSite m) url)
+ -> m a
+ redirectToPost url = do
+ urlText <- toTextUrl url
+- giveUrlRenderer [hamlet|
+-$newline never
+-$doctype 5
+-
+-<html>
+- <head>
+- <title>Redirecting...
+- <body onload="document.getElementById('form').submit()">
+- <form id="form" method="post" action=#{urlText}>
+- <noscript>
+- <p>Javascript has been disabled; please click on the button below to be redirected.
+- <input type="submit" value="Continue">
+-|] >>= sendResponse
++ giveUrlRenderer $ \ _render_awps
++ -> do { id
++ ((Text.Blaze.Internal.preEscapedText . T.pack)
++ "<!DOCTYPE html>\n<html><head><title>Redirecting...</title></head><body onload=\"document.getElementById('form').submit()\"><form id=\"form\" method=\"post\" action=\"");
++ id (toHtml urlText);
++ id
++ ((Text.Blaze.Internal.preEscapedText . T.pack)
++ "\"><noscript><p>Javascript has been disabled; please click on the button below to be redirected.</p></noscript><input type=\"submit\" value=\"Continue\"></form></body></html>") }
++ >>= sendResponse
+
+ -- | Wraps the 'Content' generated by 'hamletToContent' in a 'RepHtml'.
+ hamletToRepHtml :: MonadHandler m => HtmlUrl (Route (HandlerSite m)) -> m Html
+diff --git a/Yesod/Core/Internal/Run.hs b/Yesod/Core/Internal/Run.hs
+index 35f1d3f..8b92e99 100644
+--- a/Yesod/Core/Internal/Run.hs
++++ b/Yesod/Core/Internal/Run.hs
+@@ -122,8 +122,6 @@ safeEh :: (Loc -> LogSource -> LogLevel -> LogStr -> IO ())
+ -> ErrorResponse
+ -> YesodApp
+ safeEh log' er req = do
+- liftIO $ log' $(qLocation >>= liftLoc) "yesod-core" LevelError
+- $ toLogStr $ "Error handler errored out: " ++ show er
+ return $ YRPlain
+ H.status500
+ []
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/yesod-form_spliced-TH.patch b/standalone/android/haskell-patches/yesod-form_spliced-TH.patch
new file mode 100644
index 000000000..486d2aaee
--- /dev/null
+++ b/standalone/android/haskell-patches/yesod-form_spliced-TH.patch
@@ -0,0 +1,1783 @@
+From f645acc0efbfcba7715cd2b6734f0e9df98f7020 Mon Sep 17 00:00:00 2001
+From: dummy <dummy@example.com>
+Date: Mon, 11 Nov 2013 01:26:56 +0000
+Subject: [PATCH] update
+
+---
+ Yesod/Form/Fields.hs | 771 +++++++++++++++++++++++++++++++++++------------
+ Yesod/Form/Functions.hs | 237 ++++++++++++---
+ Yesod/Form/Jquery.hs | 125 ++++++--
+ Yesod/Form/MassInput.hs | 233 +++++++++++---
+ Yesod/Form/Nic.hs | 61 +++-
+ yesod-form.cabal | 1 +
+ 6 files changed, 1122 insertions(+), 306 deletions(-)
+
+diff --git a/Yesod/Form/Fields.hs b/Yesod/Form/Fields.hs
+index 0689859..1e9d49b 100644
+--- a/Yesod/Form/Fields.hs
++++ b/Yesod/Form/Fields.hs
+@@ -1,4 +1,3 @@
+-{-# LANGUAGE QuasiQuotes #-}
+ {-# LANGUAGE TypeFamilies #-}
+ {-# LANGUAGE OverloadedStrings #-}
+ {-# LANGUAGE GeneralizedNewtypeDeriving #-}
+@@ -36,15 +35,11 @@ module Yesod.Form.Fields
+ , selectFieldList
+ , radioField
+ , radioFieldList
+- , checkboxesFieldList
+- , checkboxesField
+ , multiSelectField
+ , multiSelectFieldList
+ , Option (..)
+ , OptionList (..)
+ , mkOptionList
+- , optionsPersist
+- , optionsPersistKey
+ , optionsPairs
+ , optionsEnum
+ ) where
+@@ -70,6 +65,15 @@ import Text.HTML.SanitizeXSS (sanitizeBalance)
+ import Control.Monad (when, unless)
+ import Data.Maybe (listToMaybe, fromMaybe)
+
++import qualified Text.Blaze as Text.Blaze.Internal
++import qualified Text.Blaze.Internal
++import qualified Text.Hamlet
++import qualified Yesod.Core.Widget
++import qualified Text.Css
++import qualified Data.Monoid
++import qualified Data.Foldable
++import qualified Control.Monad
++
+ import qualified Blaze.ByteString.Builder.Html.Utf8 as B
+ import Blaze.ByteString.Builder (writeByteString, toLazyByteString)
+ import Blaze.ByteString.Builder.Internal.Write (fromWriteList)
+@@ -82,14 +86,12 @@ import Data.Text (Text, unpack, pack)
+ import qualified Data.Text.Read
+
+ import qualified Data.Map as Map
+-import Yesod.Persist (selectList, runDB, Filter, SelectOpt, Key, YesodPersist, PersistEntity, PersistQuery, YesodDB)
+ import Control.Arrow ((&&&))
+
+ import Control.Applicative ((<$>), (<|>))
+
+ import Data.Attoparsec.Text (Parser, char, string, digit, skipSpace, endOfInput, parseOnly)
+
+-import Yesod.Persist.Core
+
+ defaultFormMessage :: FormMessage -> Text
+ defaultFormMessage = englishFormMessage
+@@ -102,10 +104,24 @@ intField = Field
+ Right (a, "") -> Right a
+ _ -> Left $ MsgInvalidInteger s
+
+- , fieldView = \theId name attrs val isReq -> toWidget [hamlet|
+-$newline never
+-<input id="#{theId}" name="#{name}" *{attrs} type="number" :isReq:required="" value="#{showVal val}">
+-|]
++ , fieldView = \theId name attrs val isReq -> toWidget $ \ _render_arOn
++ -> do { id
++ ((Text.Blaze.Internal.preEscapedText . pack) "<input id=\"");
++ id (toHtml theId);
++ id ((Text.Blaze.Internal.preEscapedText . pack) "\" name=\"");
++ id (toHtml name);
++ id
++ ((Text.Blaze.Internal.preEscapedText . pack) "\" type=\"number\"");
++ Text.Hamlet.condH
++ [(isReq,
++ id ((Text.Blaze.Internal.preEscapedText . pack) " required=\"\""))]
++ Nothing;
++ id ((Text.Blaze.Internal.preEscapedText . pack) " value=\"");
++ id (toHtml (showVal val));
++ id ((Text.Blaze.Internal.preEscapedText . pack) "\"");
++ id ((Text.Hamlet.attrsToHtml . toAttributes) attrs);
++ id ((Text.Blaze.Internal.preEscapedText . pack) ">") }
++
+ , fieldEnctype = UrlEncoded
+ }
+ where
+@@ -119,10 +135,24 @@ doubleField = Field
+ Right (a, "") -> Right a
+ _ -> Left $ MsgInvalidNumber s
+
+- , fieldView = \theId name attrs val isReq -> toWidget [hamlet|
+-$newline never
+-<input id="#{theId}" name="#{name}" *{attrs} type="text" :isReq:required="" value="#{showVal val}">
+-|]
++ , fieldView = \theId name attrs val isReq -> toWidget $ \ _render_arOz
++ -> do { id
++ ((Text.Blaze.Internal.preEscapedText . pack) "<input id=\"");
++ id (toHtml theId);
++ id ((Text.Blaze.Internal.preEscapedText . pack) "\" name=\"");
++ id (toHtml name);
++ id
++ ((Text.Blaze.Internal.preEscapedText . pack) "\" type=\"text\"");
++ Text.Hamlet.condH
++ [(isReq,
++ id ((Text.Blaze.Internal.preEscapedText . pack) " required=\"\""))]
++ Nothing;
++ id ((Text.Blaze.Internal.preEscapedText . pack) " value=\"");
++ id (toHtml (showVal val));
++ id ((Text.Blaze.Internal.preEscapedText . pack) "\"");
++ id ((Text.Hamlet.attrsToHtml . toAttributes) attrs);
++ id ((Text.Blaze.Internal.preEscapedText . pack) ">") }
++
+ , fieldEnctype = UrlEncoded
+ }
+ where showVal = either id (pack . show)
+@@ -130,10 +160,24 @@ $newline never
+ dayField :: Monad m => RenderMessage (HandlerSite m) FormMessage => Field m Day
+ dayField = Field
+ { fieldParse = parseHelper $ parseDate . unpack
+- , fieldView = \theId name attrs val isReq -> toWidget [hamlet|
+-$newline never
+-<input id="#{theId}" name="#{name}" *{attrs} type="date" :isReq:required="" value="#{showVal val}">
+-|]
++ , fieldView = \theId name attrs val isReq -> toWidget $ \ _render_arOJ
++ -> do { id
++ ((Text.Blaze.Internal.preEscapedText . pack) "<input id=\"");
++ id (toHtml theId);
++ id ((Text.Blaze.Internal.preEscapedText . pack) "\" name=\"");
++ id (toHtml name);
++ id
++ ((Text.Blaze.Internal.preEscapedText . pack) "\" type=\"date\"");
++ Text.Hamlet.condH
++ [(isReq,
++ id ((Text.Blaze.Internal.preEscapedText . pack) " required=\"\""))]
++ Nothing;
++ id ((Text.Blaze.Internal.preEscapedText . pack) " value=\"");
++ id (toHtml (showVal val));
++ id ((Text.Blaze.Internal.preEscapedText . pack) "\"");
++ id ((Text.Hamlet.attrsToHtml . toAttributes) attrs);
++ id ((Text.Blaze.Internal.preEscapedText . pack) ">") }
++
+ , fieldEnctype = UrlEncoded
+ }
+ where showVal = either id (pack . show)
+@@ -141,10 +185,23 @@ $newline never
+ timeField :: Monad m => RenderMessage (HandlerSite m) FormMessage => Field m TimeOfDay
+ timeField = Field
+ { fieldParse = parseHelper parseTime
+- , fieldView = \theId name attrs val isReq -> toWidget [hamlet|
+-$newline never
+-<input id="#{theId}" name="#{name}" *{attrs} :isReq:required="" value="#{showVal val}">
+-|]
++ , fieldView = \theId name attrs val isReq -> toWidget $ \ _render_arOW
++ -> do { id
++ ((Text.Blaze.Internal.preEscapedText . pack) "<input id=\"");
++ id (toHtml theId);
++ id ((Text.Blaze.Internal.preEscapedText . pack) "\" name=\"");
++ id (toHtml name);
++ id ((Text.Blaze.Internal.preEscapedText . pack) "\"");
++ Text.Hamlet.condH
++ [(isReq,
++ id ((Text.Blaze.Internal.preEscapedText . pack) " required=\"\""))]
++ Nothing;
++ id ((Text.Blaze.Internal.preEscapedText . pack) " value=\"");
++ id (toHtml (showVal val));
++ id ((Text.Blaze.Internal.preEscapedText . pack) "\"");
++ id ((Text.Hamlet.attrsToHtml . toAttributes) attrs);
++ id ((Text.Blaze.Internal.preEscapedText . pack) ">") }
++
+ , fieldEnctype = UrlEncoded
+ }
+ where
+@@ -157,10 +214,18 @@ $newline never
+ htmlField :: Monad m => RenderMessage (HandlerSite m) FormMessage => Field m Html
+ htmlField = Field
+ { fieldParse = parseHelper $ Right . preEscapedText . sanitizeBalance
+- , fieldView = \theId name attrs val _isReq -> toWidget [hamlet|
+-$newline never
+-<textarea id="#{theId}" name="#{name}" *{attrs}>#{showVal val}
+-|]
++ , fieldView = \theId name attrs val _isReq -> toWidget $ \ _render_arP6
++ -> do { id
++ ((Text.Blaze.Internal.preEscapedText . pack) "<textarea id=\"");
++ id (toHtml theId);
++ id ((Text.Blaze.Internal.preEscapedText . pack) "\" name=\"");
++ id (toHtml name);
++ id ((Text.Blaze.Internal.preEscapedText . pack) "\"");
++ id ((Text.Hamlet.attrsToHtml . toAttributes) attrs);
++ id ((Text.Blaze.Internal.preEscapedText . pack) ">");
++ id (toHtml (showVal val));
++ id ((Text.Blaze.Internal.preEscapedText . pack) "</textarea>") }
++
+ , fieldEnctype = UrlEncoded
+ }
+ where showVal = either id (pack . renderHtml)
+@@ -169,8 +234,6 @@ $newline never
+ -- br-tags.
+ newtype Textarea = Textarea { unTextarea :: Text }
+ deriving (Show, Read, Eq, PersistField, Ord)
+-instance PersistFieldSql Textarea where
+- sqlType _ = SqlString
+ instance ToHtml Textarea where
+ toHtml =
+ unsafeByteString
+@@ -188,10 +251,18 @@ instance ToHtml Textarea where
+ textareaField :: Monad m => RenderMessage (HandlerSite m) FormMessage => Field m Textarea
+ textareaField = Field
+ { fieldParse = parseHelper $ Right . Textarea
+- , fieldView = \theId name attrs val _isReq -> toWidget [hamlet|
+-$newline never
+-<textarea id="#{theId}" name="#{name}" *{attrs}>#{either id unTextarea val}
+-|]
++ , fieldView = \theId name attrs val _isReq -> toWidget $ \ _render_arPf
++ -> do { id
++ ((Text.Blaze.Internal.preEscapedText . pack) "<textarea id=\"");
++ id (toHtml theId);
++ id ((Text.Blaze.Internal.preEscapedText . pack) "\" name=\"");
++ id (toHtml name);
++ id ((Text.Blaze.Internal.preEscapedText . pack) "\"");
++ id ((Text.Hamlet.attrsToHtml . toAttributes) attrs);
++ id ((Text.Blaze.Internal.preEscapedText . pack) ">");
++ id (toHtml (either id unTextarea val));
++ id ((Text.Blaze.Internal.preEscapedText . pack) "</textarea>") }
++
+ , fieldEnctype = UrlEncoded
+ }
+
+@@ -199,10 +270,19 @@ hiddenField :: (Monad m, PathPiece p, RenderMessage (HandlerSite m) FormMessage)
+ => Field m p
+ hiddenField = Field
+ { fieldParse = parseHelper $ maybe (Left MsgValueRequired) Right . fromPathPiece
+- , fieldView = \theId name attrs val _isReq -> toWidget [hamlet|
+-$newline never
+-<input type="hidden" id="#{theId}" name="#{name}" *{attrs} value="#{either id toPathPiece val}">
+-|]
++ , fieldView = \theId name attrs val _isReq -> toWidget $ \ _render_arPo
++ -> do { id
++ ((Text.Blaze.Internal.preEscapedText . pack)
++ "<input type=\"hidden\" id=\"");
++ id (toHtml theId);
++ id ((Text.Blaze.Internal.preEscapedText . pack) "\" name=\"");
++ id (toHtml name);
++ id ((Text.Blaze.Internal.preEscapedText . pack) "\" value=\"");
++ id (toHtml (either id toPathPiece val));
++ id ((Text.Blaze.Internal.preEscapedText . pack) "\"");
++ id ((Text.Hamlet.attrsToHtml . toAttributes) attrs);
++ id ((Text.Blaze.Internal.preEscapedText . pack) ">") }
++
+ , fieldEnctype = UrlEncoded
+ }
+
+@@ -210,20 +290,55 @@ textField :: Monad m => RenderMessage (HandlerSite m) FormMessage => Field m Tex
+ textField = Field
+ { fieldParse = parseHelper $ Right
+ , fieldView = \theId name attrs val isReq ->
+- [whamlet|
+-$newline never
+-<input id="#{theId}" name="#{name}" *{attrs} type="text" :isReq:required value="#{either id id val}">
+-|]
++ do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "<input id=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml theId);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "\" name=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml name);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "\" type=\"text\"");
++ Text.Hamlet.condH
++ [(isReq,
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) " required"))]
++ Nothing;
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) " value=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ (toHtml (either id id val));
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Hamlet.attrsToHtml . toAttributes) attrs);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) ">") }
++
+ , fieldEnctype = UrlEncoded
+ }
+
+ passwordField :: Monad m => RenderMessage (HandlerSite m) FormMessage => Field m Text
+ passwordField = Field
+ { fieldParse = parseHelper $ Right
+- , fieldView = \theId name attrs val isReq -> toWidget [hamlet|
+-$newline never
+-<input id="#{theId}" name="#{name}" *{attrs} type="password" :isReq:required="" value="#{either id id val}">
+-|]
++ , fieldView = \theId name attrs val isReq -> toWidget $ \ _render_arPF
++ -> do { id
++ ((Text.Blaze.Internal.preEscapedText . pack) "<input id=\"");
++ id (toHtml theId);
++ id ((Text.Blaze.Internal.preEscapedText . pack) "\" name=\"");
++ id (toHtml name);
++ id
++ ((Text.Blaze.Internal.preEscapedText . pack)
++ "\" type=\"password\"");
++ Text.Hamlet.condH
++ [(isReq,
++ id ((Text.Blaze.Internal.preEscapedText . pack) " required=\"\""))]
++ Nothing;
++ id ((Text.Blaze.Internal.preEscapedText . pack) " value=\"");
++ id (toHtml (either id id val));
++ id ((Text.Blaze.Internal.preEscapedText . pack) "\"");
++ id ((Text.Hamlet.attrsToHtml . toAttributes) attrs);
++ id ((Text.Blaze.Internal.preEscapedText . pack) ">") }
++
+ , fieldEnctype = UrlEncoded
+ }
+
+@@ -295,10 +410,24 @@ emailField = Field
+ case Email.canonicalizeEmail $ encodeUtf8 s of
+ Just e -> Right $ decodeUtf8With lenientDecode e
+ Nothing -> Left $ MsgInvalidEmail s
+- , fieldView = \theId name attrs val isReq -> toWidget [hamlet|
+-$newline never
+-<input id="#{theId}" name="#{name}" *{attrs} type="email" :isReq:required="" value="#{either id id val}">
+-|]
++ , fieldView = \theId name attrs val isReq -> toWidget $ \ _render_arQe
++ -> do { id
++ ((Text.Blaze.Internal.preEscapedText . pack) "<input id=\"");
++ id (toHtml theId);
++ id ((Text.Blaze.Internal.preEscapedText . pack) "\" name=\"");
++ id (toHtml name);
++ id
++ ((Text.Blaze.Internal.preEscapedText . pack) "\" type=\"email\"");
++ Text.Hamlet.condH
++ [(isReq,
++ id ((Text.Blaze.Internal.preEscapedText . pack) " required=\"\""))]
++ Nothing;
++ id ((Text.Blaze.Internal.preEscapedText . pack) " value=\"");
++ id (toHtml (either id id val));
++ id ((Text.Blaze.Internal.preEscapedText . pack) "\"");
++ id ((Text.Hamlet.attrsToHtml . toAttributes) attrs);
++ id ((Text.Blaze.Internal.preEscapedText . pack) ">") }
++
+ , fieldEnctype = UrlEncoded
+ }
+
+@@ -307,20 +436,78 @@ searchField :: Monad m => RenderMessage (HandlerSite m) FormMessage => AutoFocus
+ searchField autoFocus = Field
+ { fieldParse = parseHelper Right
+ , fieldView = \theId name attrs val isReq -> do
+- [whamlet|\
+-$newline never
+-<input id="#{theId}" name="#{name}" *{attrs} type="search" :isReq:required="" :autoFocus:autofocus="" value="#{either id id val}">
+-|]
++ do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "<input id=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml theId);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "\" name=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml name);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "\" type=\"search\"");
++ Text.Hamlet.condH
++ [(isReq,
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) " required=\"\""))]
++ Nothing;
++ Text.Hamlet.condH
++ [(autoFocus,
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) " autofocus=\"\""))]
++ Nothing;
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) " value=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ (toHtml (either id id val));
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Hamlet.attrsToHtml . toAttributes) attrs);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) ">") }
++
+ when autoFocus $ do
+ -- we want this javascript to be placed immediately after the field
+- [whamlet|
+-$newline never
+-<script>if (!('autofocus' in document.createElement('input'))) {document.getElementById('#{theId}').focus();}
+-|]
+- toWidget [cassius|
+- ##{theId}
+- -webkit-appearance: textfield
+- |]
++ do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack)
++ "<script>if (!('autofocus' in document.createElement('input'))) {document.getElementById('");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml theId);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack)
++ "').focus();}</script>") }
++
++ toWidget $ \ _render_arQv
++ -> (Text.Css.CssNoWhitespace
++ . (foldr ($) []))
++ [((++)
++ $ (map
++ Text.Css.TopBlock
++ (((Text.Css.Block
++ {Text.Css.blockSelector = Data.Monoid.mconcat
++ [(Text.Css.fromText
++ . Text.Css.pack)
++ "#",
++ toCss theId],
++ Text.Css.blockAttrs = (concat
++ $ ([Text.Css.Attr
++ (Data.Monoid.mconcat
++ [(Text.Css.fromText
++ . Text.Css.pack)
++ "-webkit-appearance"])
++ (Data.Monoid.mconcat
++ [(Text.Css.fromText
++ . Text.Css.pack)
++ "textfield"])]
++ :
++ (map
++ Text.Css.mixinAttrs
++ []))),
++ Text.Css.blockBlocks = (),
++ Text.Css.blockMixins = ()}
++ :)
++ . ((foldr (.) id [])
++ . (concatMap Text.Css.mixinBlocks [] ++)))
++ [])))]
++
+ , fieldEnctype = UrlEncoded
+ }
+
+@@ -331,7 +518,30 @@ urlField = Field
+ Nothing -> Left $ MsgInvalidUrl s
+ Just _ -> Right s
+ , fieldView = \theId name attrs val isReq ->
+- [whamlet|<input ##{theId} name=#{name} *{attrs} type=url :isReq:required value=#{either id id val}>|]
++ do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "<input id=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml theId);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "\" name=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml name);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "\" type=\"url\"");
++ Text.Hamlet.condH
++ [(isReq,
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) " required"))]
++ Nothing;
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) " value=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ (toHtml (either id id val));
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Hamlet.attrsToHtml . toAttributes) attrs);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) ">") }
++
+ , fieldEnctype = UrlEncoded
+ }
+
+@@ -344,18 +554,56 @@ selectField :: (Eq a, RenderMessage site FormMessage)
+ => HandlerT site IO (OptionList a)
+ -> Field (HandlerT site IO) a
+ selectField = selectFieldHelper
+- (\theId name attrs inside -> [whamlet|
+-$newline never
+-<select ##{theId} name=#{name} *{attrs}>^{inside}
+-|]) -- outside
+- (\_theId _name isSel -> [whamlet|
+-$newline never
+-<option value=none :isSel:selected>_{MsgSelectNone}
+-|]) -- onOpt
+- (\_theId _name _attrs value isSel text -> [whamlet|
+-$newline never
+-<option value=#{value} :isSel:selected>#{text}
+-|]) -- inside
++ (\theId name attrs inside -> do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "<select id=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml theId);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "\" name=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml name);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Hamlet.attrsToHtml . toAttributes) attrs);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) ">");
++ (Yesod.Core.Widget.asWidgetT . toWidget) inside;
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "</select>") })
++ -- outside
++ (\_theId _name isSel -> do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack)
++ "<option value=\"none\"");
++ Text.Hamlet.condH
++ [(isSel,
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) " selected"))]
++ Nothing;
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) ">");
++ ((Control.Monad.liftM (toHtml .) getMessageRender)
++ >>=
++ (\ urender_arQS
++ -> (Yesod.Core.Widget.asWidgetT . toWidget)
++ (urender_arQS MsgSelectNone)));
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "</option>") })
++ -- onOpt
++ (\_theId _name _attrs value isSel text -> do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "<option value=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml value);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "\"");
++ Text.Hamlet.condH
++ [(isSel,
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) " selected"))]
++ Nothing;
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) ">");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml text);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "</option>") })
++ -- inside
+
+ multiSelectFieldList :: (Eq a, RenderMessage site FormMessage, RenderMessage site msg)
+ => [(msg, a)]
+@@ -378,11 +626,48 @@ multiSelectField ioptlist =
+ view theId name attrs val isReq = do
+ opts <- fmap olOptions $ handlerToWidget ioptlist
+ let selOpts = map (id &&& (optselected val)) opts
+- [whamlet|
+- <select ##{theId} name=#{name} :isReq:required multiple *{attrs}>
+- $forall (opt, optsel) <- selOpts
+- <option value=#{optionExternalValue opt} :optsel:selected>#{optionDisplay opt}
+- |]
++ do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "<select id=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml theId);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "\" name=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml name);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "\"");
++ Text.Hamlet.condH
++ [(isReq,
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) " required"))]
++ Nothing;
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) " multiple");
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Hamlet.attrsToHtml . toAttributes) attrs);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) ">");
++ Data.Foldable.mapM_
++ (\ (opt_arRl, optsel_arRm)
++ -> do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "<option value=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ (toHtml (optionExternalValue opt_arRl));
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "\"");
++ Text.Hamlet.condH
++ [(optsel_arRm,
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) " selected"))]
++ Nothing;
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) ">");
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ (toHtml (optionDisplay opt_arRl));
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "</option>") })
++ selOpts;
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "</select>") }
++
+ where
+ optselected (Left _) _ = False
+ optselected (Right vals) opt = (optionInternalValue opt) `elem` vals
+@@ -392,67 +677,172 @@ radioFieldList :: (Eq a, RenderMessage site FormMessage, RenderMessage site msg)
+ -> Field (HandlerT site IO) a
+ radioFieldList = radioField . optionsPairs
+
+-checkboxesFieldList :: (Eq a, RenderMessage site FormMessage, RenderMessage site msg) => [(msg, a)]
+- -> Field (HandlerT site IO) [a]
+-checkboxesFieldList = checkboxesField . optionsPairs
+-
+-checkboxesField :: (Eq a, RenderMessage site FormMessage)
+- => HandlerT site IO (OptionList a)
+- -> Field (HandlerT site IO) [a]
+-checkboxesField ioptlist = (multiSelectField ioptlist)
+- { fieldView =
+- \theId name attrs val isReq -> do
+- opts <- fmap olOptions $ handlerToWidget ioptlist
+- let optselected (Left _) _ = False
+- optselected (Right vals) opt = (optionInternalValue opt) `elem` vals
+- [whamlet|
+- <span ##{theId}>
+- $forall opt <- opts
+- <label>
+- <input type=checkbox name=#{name} value=#{optionExternalValue opt} *{attrs} :optselected val opt:checked>
+- #{optionDisplay opt}
+- |]
+- }
+
+ radioField :: (Eq a, RenderMessage site FormMessage)
+ => HandlerT site IO (OptionList a)
+ -> Field (HandlerT site IO) a
+ radioField = selectFieldHelper
+- (\theId _name _attrs inside -> [whamlet|
+-$newline never
+-<div ##{theId}>^{inside}
+-|])
+- (\theId name isSel -> [whamlet|
+-$newline never
+-<label .radio for=#{theId}-none>
+- <div>
+- <input id=#{theId}-none type=radio name=#{name} value=none :isSel:checked>
+- _{MsgSelectNone}
+-|])
+- (\theId name attrs value isSel text -> [whamlet|
+-$newline never
+-<label .radio for=#{theId}-#{value}>
+- <div>
+- <input id=#{theId}-#{value} type=radio name=#{name} value=#{value} :isSel:checked *{attrs}>
+- \#{text}
+-|])
++ (\theId _name _attrs inside -> do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "<div id=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml theId);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "\">");
++ (Yesod.Core.Widget.asWidgetT . toWidget) inside;
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "</div>") })
++
++ (\theId name isSel -> do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack)
++ "<label class=\"radio\" for=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml theId);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack)
++ "-none\"><div><input id=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml theId);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack)
++ "-none\" type=\"radio\" name=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml name);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "\" value=\"none\"");
++ Text.Hamlet.condH
++ [(isSel,
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) " checked"))]
++ Nothing;
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) ">");
++ ((Control.Monad.liftM (toHtml .) getMessageRender)
++ >>=
++ (\ urender_arRA
++ -> (Yesod.Core.Widget.asWidgetT . toWidget)
++ (urender_arRA MsgSelectNone)));
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "</div></label>") })
++
++ (\theId name attrs value isSel text -> do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack)
++ "<label class=\"radio\" for=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml theId);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "-");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml value);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack)
++ "\"><div><input id=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml theId);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "-");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml value);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack)
++ "\" type=\"radio\" name=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml name);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "\" value=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml value);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "\"");
++ Text.Hamlet.condH
++ [(isSel,
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) " checked"))]
++ Nothing;
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Hamlet.attrsToHtml . toAttributes) attrs);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) ">");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml text);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "</div></label>") })
++
+
+ boolField :: Monad m => RenderMessage (HandlerSite m) FormMessage => Field m Bool
+ boolField = Field
+ { fieldParse = \e _ -> return $ boolParser e
+- , fieldView = \theId name attrs val isReq -> [whamlet|
+-$newline never
+- $if not isReq
+- <input id=#{theId}-none *{attrs} type=radio name=#{name} value=none checked>
+- <label for=#{theId}-none>_{MsgSelectNone}
++ , fieldView = \theId name attrs val isReq -> do { Text.Hamlet.condH
++ [(not isReq,
++ do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "<input id=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml theId);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack)
++ "-none\" type=\"radio\" name=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml name);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack)
++ "\" value=\"none\" checked");
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Hamlet.attrsToHtml . toAttributes) attrs);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "><label for=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml theId);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "-none\">");
++ ((Control.Monad.liftM (toHtml .) getMessageRender)
++ >>=
++ (\ urender_arRX
++ -> (Yesod.Core.Widget.asWidgetT . toWidget)
++ (urender_arRX MsgSelectNone)));
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "</label>") })]
++ Nothing;
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "<input id=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml theId);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack)
++ "-yes\" type=\"radio\" name=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml name);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "\" value=\"yes\"");
++ Text.Hamlet.condH
++ [(showVal id val,
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) " checked"))]
++ Nothing;
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Hamlet.attrsToHtml . toAttributes) attrs);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "><label for=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml theId);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "-yes\">");
++ ((Control.Monad.liftM (toHtml .) getMessageRender)
++ >>=
++ (\ urender_arRY
++ -> (Yesod.Core.Widget.asWidgetT . toWidget)
++ (urender_arRY MsgBoolYes)));
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack)
++ "</label><input id=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml theId);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack)
++ "-no\" type=\"radio\" name=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml name);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "\" value=\"no\"");
++ Text.Hamlet.condH
++ [(showVal not val,
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) " checked"))]
++ Nothing;
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Hamlet.attrsToHtml . toAttributes) attrs);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "><label for=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml theId);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "-no\">");
++ ((Control.Monad.liftM (toHtml .) getMessageRender)
++ >>=
++ (\ urender_arRZ
++ -> (Yesod.Core.Widget.asWidgetT . toWidget)
++ (urender_arRZ MsgBoolNo)));
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "</label>") }
+
+-
+-<input id=#{theId}-yes *{attrs} type=radio name=#{name} value=yes :showVal id val:checked>
+-<label for=#{theId}-yes>_{MsgBoolYes}
+-
+-<input id=#{theId}-no *{attrs} type=radio name=#{name} value=no :showVal not val:checked>
+-<label for=#{theId}-no>_{MsgBoolNo}
+-|]
+ , fieldEnctype = UrlEncoded
+ }
+ where
+@@ -478,10 +868,25 @@ $newline never
+ checkBoxField :: Monad m => RenderMessage (HandlerSite m) FormMessage => Field m Bool
+ checkBoxField = Field
+ { fieldParse = \e _ -> return $ checkBoxParser e
+- , fieldView = \theId name attrs val _ -> [whamlet|
+-$newline never
+-<input id=#{theId} *{attrs} type=checkbox name=#{name} value=yes :showVal id val:checked>
+-|]
++ , fieldView = \theId name attrs val _ -> do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "<input id=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml theId);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack)
++ "\" type=\"checkbox\" name=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml name);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "\" value=\"yes\"");
++ Text.Hamlet.condH
++ [(showVal id val,
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) " checked"))]
++ Nothing;
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Hamlet.attrsToHtml . toAttributes) attrs);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) ">") }
++
+ , fieldEnctype = UrlEncoded
+ }
+
+@@ -525,49 +930,7 @@ optionsPairs opts = do
+ optionsEnum :: (MonadHandler m, Show a, Enum a, Bounded a) => m (OptionList a)
+ optionsEnum = optionsPairs $ map (\x -> (pack $ show x, x)) [minBound..maxBound]
+
+-optionsPersist :: ( YesodPersist site, PersistEntity a
+- , PersistQuery (YesodDB site)
+- , PathPiece (Key a)
+- , PersistEntityBackend a ~ PersistMonadBackend (YesodDB site)
+- , RenderMessage site msg
+- )
+- => [Filter a]
+- -> [SelectOpt a]
+- -> (a -> msg)
+- -> HandlerT site IO (OptionList (Entity a))
+-optionsPersist filts ords toDisplay = fmap mkOptionList $ do
+- mr <- getMessageRender
+- pairs <- runDB $ selectList filts ords
+- return $ map (\(Entity key value) -> Option
+- { optionDisplay = mr (toDisplay value)
+- , optionInternalValue = Entity key value
+- , optionExternalValue = toPathPiece key
+- }) pairs
+-
+--- | An alternative to 'optionsPersist' which returns just the @Key@ instead of
+--- the entire @Entity@.
+---
+--- Since 1.3.2
+-optionsPersistKey
+- :: (YesodPersist site
+- , PersistEntity a
+- , PersistQuery (YesodPersistBackend site (HandlerT site IO))
+- , PathPiece (Key a)
+- , RenderMessage site msg
+- , PersistEntityBackend a ~ PersistMonadBackend (YesodDB site))
+- => [Filter a]
+- -> [SelectOpt a]
+- -> (a -> msg)
+- -> HandlerT site IO (OptionList (Key a))
+-
+-optionsPersistKey filts ords toDisplay = fmap mkOptionList $ do
+- mr <- getMessageRender
+- pairs <- runDB $ selectList filts ords
+- return $ map (\(Entity key value) -> Option
+- { optionDisplay = mr (toDisplay value)
+- , optionInternalValue = key
+- , optionExternalValue = toPathPiece key
+- }) pairs
++
+
+ selectFieldHelper
+ :: (Eq a, RenderMessage site FormMessage)
+@@ -611,9 +974,21 @@ fileField = Field
+ case files of
+ [] -> Right Nothing
+ file:_ -> Right $ Just file
+- , fieldView = \id' name attrs _ isReq -> toWidget [hamlet|
+- <input id=#{id'} name=#{name} *{attrs} type=file :isReq:required>
+- |]
++ , fieldView = \id' name attrs _ isReq -> toWidget $ \ _render_arSN
++ -> do { id
++ ((Text.Blaze.Internal.preEscapedText . pack) "<input id=\"");
++ id (toHtml id');
++ id ((Text.Blaze.Internal.preEscapedText . pack) "\" name=\"");
++ id (toHtml name);
++ id
++ ((Text.Blaze.Internal.preEscapedText . pack) "\" type=\"file\"");
++ Text.Hamlet.condH
++ [(isReq,
++ id ((Text.Blaze.Internal.preEscapedText . pack) " required"))]
++ Nothing;
++ id ((Text.Hamlet.attrsToHtml . toAttributes) attrs);
++ id ((Text.Blaze.Internal.preEscapedText . pack) ">") }
++
+ , fieldEnctype = Multipart
+ }
+
+@@ -640,10 +1015,20 @@ fileAFormReq fs = AForm $ \(site, langs) menvs ints -> do
+ { fvLabel = toHtml $ renderMessage site langs $ fsLabel fs
+ , fvTooltip = fmap (toHtml . renderMessage site langs) $ fsTooltip fs
+ , fvId = id'
+- , fvInput = [whamlet|
+-$newline never
+-<input type=file name=#{name} ##{id'} *{fsAttrs fs}>
+-|]
++ , fvInput = do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack)
++ "<input type=\"file\" name=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml name);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "\" id=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml id');
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Hamlet.attrsToHtml . toAttributes) (fsAttrs fs));
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) ">") }
++
+ , fvErrors = errs
+ , fvRequired = True
+ }
+@@ -672,10 +1057,20 @@ fileAFormOpt fs = AForm $ \(master, langs) menvs ints -> do
+ { fvLabel = toHtml $ renderMessage master langs $ fsLabel fs
+ , fvTooltip = fmap (toHtml . renderMessage master langs) $ fsTooltip fs
+ , fvId = id'
+- , fvInput = [whamlet|
+-$newline never
+-<input type=file name=#{name} ##{id'} *{fsAttrs fs}>
+-|]
++ , fvInput = do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack)
++ "<input type=\"file\" name=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml name);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "\" id=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml id');
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Hamlet.attrsToHtml . toAttributes) (fsAttrs fs));
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) ">") }
++
+ , fvErrors = errs
+ , fvRequired = False
+ }
+diff --git a/Yesod/Form/Functions.hs b/Yesod/Form/Functions.hs
+index 8a36710..c375ae0 100644
+--- a/Yesod/Form/Functions.hs
++++ b/Yesod/Form/Functions.hs
+@@ -59,6 +59,10 @@ import Data.Maybe (listToMaybe, fromMaybe)
+ import qualified Data.Map as Map
+ import qualified Data.Text.Encoding as TE
+ import Control.Arrow (first)
++import qualified Text.Blaze.Internal
++import qualified Yesod.Core.Widget
++import qualified Data.Foldable
++import qualified Text.Hamlet
+
+ -- | Get a unique identifier.
+ newFormIdent :: Monad m => MForm m Text
+@@ -210,7 +214,14 @@ postHelper form env = do
+ let token =
+ case reqToken req of
+ Nothing -> mempty
+- Just n -> [shamlet|<input type=hidden name=#{tokenKey} value=#{n}>|]
++ Just n -> do { id
++ ((Text.Blaze.Internal.preEscapedText . pack)
++ "<input type=\"hidden\" name=\"");
++ id (toHtml tokenKey);
++ id ((Text.Blaze.Internal.preEscapedText . pack) "\" value=\"");
++ id (toHtml n);
++ id ((Text.Blaze.Internal.preEscapedText . pack) "\">") }
++
+ m <- getYesod
+ langs <- languages
+ ((res, xml), enctype) <- runFormGeneric (form token) m langs env
+@@ -279,7 +290,12 @@ getHelper :: MonadHandler m
+ -> Maybe (Env, FileEnv)
+ -> m (a, Enctype)
+ getHelper form env = do
+- let fragment = [shamlet|<input type=hidden name=#{getKey}>|]
++ let fragment = do { id
++ ((Text.Blaze.Internal.preEscapedText . pack)
++ "<input type=\"hidden\" name=\"");
++ id (toHtml getKey);
++ id ((Text.Blaze.Internal.preEscapedText . pack) "\">") }
++
+ langs <- languages
+ m <- getYesod
+ runFormGeneric (form fragment) m langs env
+@@ -293,19 +309,66 @@ renderTable, renderDivs, renderDivsNoLabels :: Monad m => FormRender m a
+ renderTable aform fragment = do
+ (res, views') <- aFormToForm aform
+ let views = views' []
+- let widget = [whamlet|
+-$newline never
+-\#{fragment}
+-$forall view <- views
+- <tr :fvRequired view:.required :not $ fvRequired view:.optional>
+- <td>
+- <label for=#{fvId view}>#{fvLabel view}
+- $maybe tt <- fvTooltip view
+- <div .tooltip>#{tt}
+- <td>^{fvInput view}
+- $maybe err <- fvErrors view
+- <td .errors>#{err}
+-|]
++ let widget = do { (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml fragment);
++ Data.Foldable.mapM_
++ (\ view_aagq
++ -> do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "<tr");
++ Text.Hamlet.condH
++ [(or [fvRequired view_aagq, not (fvRequired view_aagq)],
++ do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) " class=\"");
++ Text.Hamlet.condH
++ [(fvRequired view_aagq,
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "required "))]
++ Nothing;
++ Text.Hamlet.condH
++ [(not (fvRequired view_aagq),
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "optional"))]
++ Nothing;
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "\"") })]
++ Nothing;
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "><td><label for=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml (fvId view_aagq));
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "\">");
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ (toHtml (fvLabel view_aagq));
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "</label>");
++ Text.Hamlet.maybeH
++ (fvTooltip view_aagq)
++ (\ tt_aagr
++ -> do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack)
++ "<div class=\"tooltip\">");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml tt_aagr);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "</div>") })
++ Nothing;
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "</td><td>");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (fvInput view_aagq);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "</td>");
++ Text.Hamlet.maybeH
++ (fvErrors view_aagq)
++ (\ err_aags
++ -> do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack)
++ "<td class=\"errors\">");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml err_aags);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "</td>") })
++ Nothing;
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "</tr>") })
++ views }
++
+ return (res, widget)
+
+ -- | render a field inside a div
+@@ -318,19 +381,67 @@ renderDivsMaybeLabels :: Monad m => Bool -> FormRender m a
+ renderDivsMaybeLabels withLabels aform fragment = do
+ (res, views') <- aFormToForm aform
+ let views = views' []
+- let widget = [whamlet|
+-$newline never
+-\#{fragment}
+-$forall view <- views
+- <div :fvRequired view:.required :not $ fvRequired view:.optional>
+- $if withLabels
+- <label for=#{fvId view}>#{fvLabel view}
+- $maybe tt <- fvTooltip view
+- <div .tooltip>#{tt}
+- ^{fvInput view}
+- $maybe err <- fvErrors view
+- <div .errors>#{err}
+-|]
++ let widget = do { (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml fragment);
++ Data.Foldable.mapM_
++ (\ view_aagE
++ -> do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "<div");
++ Text.Hamlet.condH
++ [(or [fvRequired view_aagE, not (fvRequired view_aagE)],
++ do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) " class=\"");
++ Text.Hamlet.condH
++ [(fvRequired view_aagE,
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "required "))]
++ Nothing;
++ Text.Hamlet.condH
++ [(not (fvRequired view_aagE),
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "optional"))]
++ Nothing;
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "\"") })]
++ Nothing;
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) ">");
++ Text.Hamlet.condH
++ [(withLabels,
++ do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "<label for=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml (fvId view_aagE));
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "\">");
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ (toHtml (fvLabel view_aagE));
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "</label>") })]
++ Nothing;
++ Text.Hamlet.maybeH
++ (fvTooltip view_aagE)
++ (\ tt_aagF
++ -> do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack)
++ "<div class=\"tooltip\">");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml tt_aagF);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "</div>") })
++ Nothing;
++ (Yesod.Core.Widget.asWidgetT . toWidget) (fvInput view_aagE);
++ Text.Hamlet.maybeH
++ (fvErrors view_aagE)
++ (\ err_aagG
++ -> do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack)
++ "<div class=\"errors\">");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml err_aagG);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "</div>") })
++ Nothing;
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "</div>") })
++ views }
++
+ return (res, widget)
+
+ -- | Render a form using Bootstrap-friendly shamlet syntax.
+@@ -354,19 +465,63 @@ renderBootstrap aform fragment = do
+ let views = views' []
+ has (Just _) = True
+ has Nothing = False
+- let widget = [whamlet|
+- $newline never
+- \#{fragment}
+- $forall view <- views
+- <div .control-group .clearfix :fvRequired view:.required :not $ fvRequired view:.optional :has $ fvErrors view:.error>
+- <label .control-label for=#{fvId view}>#{fvLabel view}
+- <div .controls .input>
+- ^{fvInput view}
+- $maybe tt <- fvTooltip view
+- <span .help-block>#{tt}
+- $maybe err <- fvErrors view
+- <span .help-block>#{err}
+- |]
++ let widget = do { (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml fragment);
++ Data.Foldable.mapM_
++ (\ view_aagR
++ -> do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack)
++ "<div class=\"control-group clearfix ");
++ Text.Hamlet.condH
++ [(fvRequired view_aagR,
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "required "))]
++ Nothing;
++ Text.Hamlet.condH
++ [(not (fvRequired view_aagR),
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "optional "))]
++ Nothing;
++ Text.Hamlet.condH
++ [(has (fvErrors view_aagR),
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "error"))]
++ Nothing;
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack)
++ "\"><label class=\"control-label\" for=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml (fvId view_aagR));
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "\">");
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ (toHtml (fvLabel view_aagR));
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack)
++ "</label><div class=\"controls input\">");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (fvInput view_aagR);
++ Text.Hamlet.maybeH
++ (fvTooltip view_aagR)
++ (\ tt_aagS
++ -> do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack)
++ "<span class=\"help-block\">");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml tt_aagS);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "</span>") })
++ Nothing;
++ Text.Hamlet.maybeH
++ (fvErrors view_aagR)
++ (\ err_aagT
++ -> do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack)
++ "<span class=\"help-block\">");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml err_aagT);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "</span>") })
++ Nothing;
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . pack) "</div></div>") })
++ views }
++
+ return (res, widget)
+
+ check :: (Monad m, RenderMessage (HandlerSite m) msg)
+diff --git a/Yesod/Form/Jquery.hs b/Yesod/Form/Jquery.hs
+index 2c4ae25..4362188 100644
+--- a/Yesod/Form/Jquery.hs
++++ b/Yesod/Form/Jquery.hs
+@@ -12,6 +12,18 @@ module Yesod.Form.Jquery
+ , Default (..)
+ ) where
+
++import qualified Text.Blaze as Text.Blaze.Internal
++import qualified Text.Blaze.Internal
++import qualified Text.Hamlet
++import qualified Yesod.Core.Widget
++import qualified Text.Css
++import qualified Data.Monoid
++import qualified Data.Foldable
++import qualified Control.Monad
++import qualified Text.Julius
++import qualified Data.Text.Lazy.Builder
++import qualified Text.Shakespeare
++
+ import Yesod.Core
+ import Yesod.Form
+ import Data.Time (Day)
+@@ -60,27 +72,59 @@ jqueryDayField jds = Field
+ . readMay
+ . unpack
+ , fieldView = \theId name attrs val isReq -> do
+- toWidget [shamlet|
+-$newline never
+-<input id="#{theId}" name="#{name}" *{attrs} type="date" :isReq:required="" value="#{showVal val}">
+-|]
++ toWidget $ do { id
++ ((Text.Blaze.Internal.preEscapedText . pack) "<input id=\"");
++ id (toHtml theId);
++ id ((Text.Blaze.Internal.preEscapedText . pack) "\" name=\"");
++ id (toHtml name);
++ id
++ ((Text.Blaze.Internal.preEscapedText . pack) "\" type=\"date\"");
++ Text.Hamlet.condH
++ [(isReq,
++ id ((Text.Blaze.Internal.preEscapedText . pack) " required=\"\""))]
++ Nothing;
++ id ((Text.Blaze.Internal.preEscapedText . pack) " value=\"");
++ id (toHtml (showVal val));
++ id ((Text.Blaze.Internal.preEscapedText . pack) "\"");
++ id ((Text.Hamlet.attrsToHtml . Text.Hamlet.toAttributes) attrs);
++ id ((Text.Blaze.Internal.preEscapedText . pack) ">") }
++
+ addScript' urlJqueryJs
+ addScript' urlJqueryUiJs
+ addStylesheet' urlJqueryUiCss
+- toWidget [julius|
+-$(function(){
+- var i = document.getElementById("#{rawJS theId}");
+- if (i.type != "date") {
+- $(i).datepicker({
+- dateFormat:'yy-mm-dd',
+- changeMonth:#{jsBool $ jdsChangeMonth jds},
+- changeYear:#{jsBool $ jdsChangeYear jds},
+- numberOfMonths:#{rawJS $ mos $ jdsNumberOfMonths jds},
+- yearRange:#{toJSON $ jdsYearRange jds}
+- });
+- }
+-});
+-|]
++ toWidget $ Text.Julius.asJavascriptUrl
++ (\ _render_a1lYC
++ -> mconcat
++ [Text.Julius.Javascript
++ ((Data.Text.Lazy.Builder.fromText
++ . Text.Shakespeare.pack')
++ "\n$(function(){\n var i = document.getElementById(\""),
++ Text.Julius.toJavascript (rawJS theId),
++ Text.Julius.Javascript
++ ((Data.Text.Lazy.Builder.fromText
++ . Text.Shakespeare.pack')
++ "\");\n if (i.type != \"date\") {\n $(i).datepicker({\n dateFormat:'yy-mm-dd',\n changeMonth:"),
++ Text.Julius.toJavascript (jsBool (jdsChangeMonth jds)),
++ Text.Julius.Javascript
++ ((Data.Text.Lazy.Builder.fromText
++ . Text.Shakespeare.pack')
++ ",\n changeYear:"),
++ Text.Julius.toJavascript (jsBool (jdsChangeYear jds)),
++ Text.Julius.Javascript
++ ((Data.Text.Lazy.Builder.fromText
++ . Text.Shakespeare.pack')
++ ",\n numberOfMonths:"),
++ Text.Julius.toJavascript (rawJS (mos (jdsNumberOfMonths jds))),
++ Text.Julius.Javascript
++ ((Data.Text.Lazy.Builder.fromText
++ . Text.Shakespeare.pack')
++ ",\n yearRange:"),
++ Text.Julius.toJavascript (toJSON (jdsYearRange jds)),
++ Text.Julius.Javascript
++ ((Data.Text.Lazy.Builder.fromText
++ . Text.Shakespeare.pack')
++ "\n });\n }\n});")])
++
+ , fieldEnctype = UrlEncoded
+ }
+ where
+@@ -101,16 +145,47 @@ jqueryAutocompleteField :: (RenderMessage site FormMessage, YesodJquery site)
+ jqueryAutocompleteField src = Field
+ { fieldParse = parseHelper $ Right
+ , fieldView = \theId name attrs val isReq -> do
+- toWidget [shamlet|
+-$newline never
+-<input id="#{theId}" name="#{name}" *{attrs} type="text" :isReq:required="" value="#{either id id val}" .autocomplete>
+-|]
++ toWidget $ do { id
++ ((Text.Blaze.Internal.preEscapedText . pack)
++ "<input class=\"autocomplete\" id=\"");
++ id (toHtml theId);
++ id ((Text.Blaze.Internal.preEscapedText . pack) "\" name=\"");
++ id (toHtml name);
++ id
++ ((Text.Blaze.Internal.preEscapedText . pack) "\" type=\"text\"");
++ Text.Hamlet.condH
++ [(isReq,
++ id ((Text.Blaze.Internal.preEscapedText . pack) " required=\"\""))]
++ Nothing;
++ id ((Text.Blaze.Internal.preEscapedText . pack) " value=\"");
++ id (toHtml (either id id val));
++ id ((Text.Blaze.Internal.preEscapedText . pack) "\"");
++ id ((Text.Hamlet.attrsToHtml . Text.Hamlet.toAttributes) attrs);
++ id ((Text.Blaze.Internal.preEscapedText . pack) ">") }
++
+ addScript' urlJqueryJs
+ addScript' urlJqueryUiJs
+ addStylesheet' urlJqueryUiCss
+- toWidget [julius|
+-$(function(){$("##{rawJS theId}").autocomplete({source:"@{src}",minLength:2})});
+-|]
++ toWidget $ Text.Julius.asJavascriptUrl
++ (\ _render_a1lYP
++ -> mconcat
++ [Text.Julius.Javascript
++ ((Data.Text.Lazy.Builder.fromText
++ . Text.Shakespeare.pack')
++ "\n$(function(){$(\"#"),
++ Text.Julius.toJavascript (rawJS theId),
++ Text.Julius.Javascript
++ ((Data.Text.Lazy.Builder.fromText
++ . Text.Shakespeare.pack')
++ "\").autocomplete({source:\""),
++ Text.Julius.Javascript
++ (Data.Text.Lazy.Builder.fromText
++ (_render_a1lYP src [])),
++ Text.Julius.Javascript
++ ((Data.Text.Lazy.Builder.fromText
++ . Text.Shakespeare.pack')
++ "\",minLength:2})});")])
++
+ , fieldEnctype = UrlEncoded
+ }
+
+diff --git a/Yesod/Form/MassInput.hs b/Yesod/Form/MassInput.hs
+index 332eb66..5015e7b 100644
+--- a/Yesod/Form/MassInput.hs
++++ b/Yesod/Form/MassInput.hs
+@@ -9,6 +9,16 @@ module Yesod.Form.MassInput
+ , massTable
+ ) where
+
++import qualified Data.Text
++import qualified Text.Blaze as Text.Blaze.Internal
++import qualified Text.Blaze.Internal
++import qualified Text.Hamlet
++import qualified Yesod.Core.Widget
++import qualified Text.Css
++import qualified Data.Monoid
++import qualified Data.Foldable
++import qualified Control.Monad
++
+ import Yesod.Form.Types
+ import Yesod.Form.Functions
+ import Yesod.Form.Fields (boolField)
+@@ -70,16 +80,28 @@ inputList label fixXml single mdef = formToAForm $ do
+ { fvLabel = label
+ , fvTooltip = Nothing
+ , fvId = theId
+- , fvInput = [whamlet|
+-$newline never
+-^{fixXml views}
+-<p>
+- $forall xml <- xmls
+- ^{xml}
+- <input .count type=hidden name=#{countName} value=#{count}>
+- <input type=checkbox name=#{addName}>
+- Add another row
+-|]
++ , fvInput = do { (Yesod.Core.Widget.asWidgetT . toWidget) (fixXml views);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack) "<p>");
++ Data.Foldable.mapM_
++ (\ xml_aUS3 -> (Yesod.Core.Widget.asWidgetT . toWidget) xml_aUS3)
++ xmls;
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack)
++ "<input class=\"count\" type=\"hidden\" name=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml countName);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack)
++ "\" value=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml count);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack)
++ "\"><input type=\"checkbox\" name=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml addName);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack)
++ "\">Add another row</p>") }
++
+ , fvErrors = Nothing
+ , fvRequired = False
+ }])
+@@ -92,10 +114,14 @@ withDelete af = do
+ deleteName <- newFormIdent
+ (menv, _, _) <- ask
+ res <- case menv >>= Map.lookup deleteName . fst of
+- Just ("yes":_) -> return $ Left [whamlet|
+-$newline never
+-<input type=hidden name=#{deleteName} value=yes>
+-|]
++ Just ("yes":_) -> return $ Left $ do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack)
++ "<input type=\"hidden\" name=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml deleteName);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack)
++ "\" value=\"yes\">") }
++
+ _ -> do
+ (_, xml2) <- aFormToForm $ areq boolField FieldSettings
+ { fsLabel = SomeMessage MsgDelete
+@@ -121,32 +147,155 @@ fixme eithers =
+ massDivs, massTable
+ :: [[FieldView site]]
+ -> WidgetT site IO ()
+-massDivs viewss = [whamlet|
+-$newline never
+-$forall views <- viewss
+- <fieldset>
+- $forall view <- views
+- <div :fvRequired view:.required :not $ fvRequired view:.optional>
+- <label for=#{fvId view}>#{fvLabel view}
+- $maybe tt <- fvTooltip view
+- <div .tooltip>#{tt}
+- ^{fvInput view}
+- $maybe err <- fvErrors view
+- <div .errors>#{err}
+-|]
++massDivs viewss = Data.Foldable.mapM_
++ (\ views_aUSm
++ -> do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack)
++ "<fieldset>");
++ Data.Foldable.mapM_
++ (\ view_aUSn
++ -> do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack) "<div");
++ Text.Hamlet.condH
++ [(or [fvRequired view_aUSn, not (fvRequired view_aUSn)],
++ do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack)
++ " class=\"");
++ Text.Hamlet.condH
++ [(fvRequired view_aUSn,
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack)
++ "required "))]
++ Nothing;
++ Text.Hamlet.condH
++ [(not (fvRequired view_aUSn),
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack)
++ "optional"))]
++ Nothing;
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack)
++ "\"") })]
++ Nothing;
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack)
++ "><label for=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml (fvId view_aUSn));
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack) "\">");
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ (toHtml (fvLabel view_aUSn));
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack) "</label>");
++ Text.Hamlet.maybeH
++ (fvTooltip view_aUSn)
++ (\ tt_aUSo
++ -> do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack)
++ "<div class=\"tooltip\">");
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ (toHtml tt_aUSo);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack)
++ "</div>") })
++ Nothing;
++ (Yesod.Core.Widget.asWidgetT . toWidget) (fvInput view_aUSn);
++ Text.Hamlet.maybeH
++ (fvErrors view_aUSn)
++ (\ err_aUSp
++ -> do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack)
++ "<div class=\"errors\">");
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ (toHtml err_aUSp);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack)
++ "</div>") })
++ Nothing;
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack) "</div>") })
++ views_aUSm;
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack)
++ "</fieldset>") })
++ viewss
++
++
++massTable viewss = Data.Foldable.mapM_
++ (\ views_aUSu
++ -> do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack)
++ "<fieldset><table>");
++ Data.Foldable.mapM_
++ (\ view_aUSv
++ -> do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack) "<tr");
++ Text.Hamlet.condH
++ [(or [fvRequired view_aUSv, not (fvRequired view_aUSv)],
++ do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack)
++ " class=\"");
++ Text.Hamlet.condH
++ [(fvRequired view_aUSv,
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack)
++ "required "))]
++ Nothing;
++ Text.Hamlet.condH
++ [(not (fvRequired view_aUSv),
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack)
++ "optional"))]
++ Nothing;
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack)
++ "\"") })]
++ Nothing;
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack)
++ "><td><label for=\"");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (toHtml (fvId view_aUSv));
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack) "\">");
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ (toHtml (fvLabel view_aUSv));
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack) "</label>");
++ Text.Hamlet.maybeH
++ (fvTooltip view_aUSv)
++ (\ tt_aUSw
++ -> do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack)
++ "<div class=\"tooltip\">");
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ (toHtml tt_aUSw);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack)
++ "</div>") })
++ Nothing;
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack)
++ "</td><td>");
++ (Yesod.Core.Widget.asWidgetT . toWidget) (fvInput view_aUSv);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack) "</td>");
++ Text.Hamlet.maybeH
++ (fvErrors view_aUSv)
++ (\ err_aUSx
++ -> do { (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack)
++ "<td class=\"errors\">");
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ (toHtml err_aUSx);
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack)
++ "</td>") })
++ Nothing;
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack) "</tr>") })
++ views_aUSu;
++ (Yesod.Core.Widget.asWidgetT . toWidget)
++ ((Text.Blaze.Internal.preEscapedText . Data.Text.pack)
++ "</table></fieldset>") })
++ viewss
+
+-massTable viewss = [whamlet|
+-$newline never
+-$forall views <- viewss
+- <fieldset>
+- <table>
+- $forall view <- views
+- <tr :fvRequired view:.required :not $ fvRequired view:.optional>
+- <td>
+- <label for=#{fvId view}>#{fvLabel view}
+- $maybe tt <- fvTooltip view
+- <div .tooltip>#{tt}
+- <td>^{fvInput view}
+- $maybe err <- fvErrors view
+- <td .errors>#{err}
+-|]
+diff --git a/Yesod/Form/Nic.hs b/Yesod/Form/Nic.hs
+index 2862678..7b49b1a 100644
+--- a/Yesod/Form/Nic.hs
++++ b/Yesod/Form/Nic.hs
+@@ -9,6 +9,19 @@ module Yesod.Form.Nic
+ , nicHtmlField
+ ) where
+
++import qualified Text.Blaze as Text.Blaze.Internal
++import qualified Text.Blaze.Internal
++import qualified Text.Hamlet
++import qualified Yesod.Core.Widget
++import qualified Text.Css
++import qualified Data.Monoid
++import qualified Data.Foldable
++import qualified Control.Monad
++import qualified Text.Julius
++import qualified Data.Text.Lazy.Builder
++import qualified Text.Shakespeare
++
++
+ import Yesod.Core
+ import Yesod.Form
+ import Text.HTML.SanitizeXSS (sanitizeBalance)
+@@ -27,20 +40,48 @@ nicHtmlField :: YesodNic site => Field (HandlerT site IO) Html
+ nicHtmlField = Field
+ { fieldParse = \e _ -> return . Right . fmap (preEscapedToMarkup . sanitizeBalance) . listToMaybe $ e
+ , fieldView = \theId name attrs val _isReq -> do
+- toWidget [shamlet|
+-$newline never
+- <textarea id="#{theId}" *{attrs} name="#{name}" .html>#{showVal val}
+-|]
++ toWidget $ do { id
++ ((Text.Blaze.Internal.preEscapedText . pack)
++ "<textarea class=\"html\" id=\"");
++ id (toHtml theId);
++ id ((Text.Blaze.Internal.preEscapedText . pack) "\" name=\"");
++ id (toHtml name);
++ id ((Text.Blaze.Internal.preEscapedText . pack) "\"");
++ id ((Text.Hamlet.attrsToHtml . Text.Hamlet.toAttributes) attrs);
++ id ((Text.Blaze.Internal.preEscapedText . pack) ">");
++ id (toHtml (showVal val));
++ id ((Text.Blaze.Internal.preEscapedText . pack) "</textarea>") }
++
+ addScript' urlNicEdit
+ master <- getYesod
+ toWidget $
+ case jsLoader master of
+- BottomOfHeadBlocking -> [julius|
+-bkLib.onDomLoaded(function(){new nicEditor({fullPanel:true}).panelInstance("#{rawJS theId}")});
+-|]
+- _ -> [julius|
+-(function(){new nicEditor({fullPanel:true}).panelInstance("#{rawJS theId}")})();
+-|]
++ BottomOfHeadBlocking -> Text.Julius.asJavascriptUrl
++ (\ _render_a1qhO
++ -> Data.Monoid.mconcat
++ [Text.Julius.Javascript
++ ((Data.Text.Lazy.Builder.fromText
++ . Text.Shakespeare.pack')
++ "\nbkLib.onDomLoaded(function(){new nicEditor({true}).panelInstance(\""),
++ Text.Julius.toJavascript (rawJS theId),
++ Text.Julius.Javascript
++ ((Data.Text.Lazy.Builder.fromText
++ . Text.Shakespeare.pack')
++ "\")});")])
++
++ _ -> Text.Julius.asJavascriptUrl
++ (\ _render_a1qhS
++ -> Data.Monoid.mconcat
++ [Text.Julius.Javascript
++ ((Data.Text.Lazy.Builder.fromText
++ . Text.Shakespeare.pack')
++ "\n(function(){new nicEditor({true}).panelInstance(\""),
++ Text.Julius.toJavascript (rawJS theId),
++ Text.Julius.Javascript
++ ((Data.Text.Lazy.Builder.fromText
++ . Text.Shakespeare.pack')
++ "\")})();")])
++
+ , fieldEnctype = UrlEncoded
+ }
+ where
+diff --git a/yesod-form.cabal b/yesod-form.cabal
+index 39fa680..88ed066 100644
+--- a/yesod-form.cabal
++++ b/yesod-form.cabal
+@@ -19,6 +19,7 @@ library
+ , time >= 1.1.4
+ , hamlet >= 1.1 && < 1.2
+ , shakespeare-css >= 1.0 && < 1.1
++ , shakespeare
+ , shakespeare-js >= 1.0.2 && < 1.3
+ , persistent >= 1.2 && < 1.3
+ , template-haskell
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/yesod-persistent_do-not-really-build.patch b/standalone/android/haskell-patches/yesod-persistent_do-not-really-build.patch
new file mode 100644
index 000000000..ecccf75ac
--- /dev/null
+++ b/standalone/android/haskell-patches/yesod-persistent_do-not-really-build.patch
@@ -0,0 +1,26 @@
+From 03819615edb1c5f7414768dae84234d6791bd758 Mon Sep 17 00:00:00 2001
+From: foo <foo@bar>
+Date: Sun, 22 Sep 2013 04:11:46 +0000
+Subject: [PATCH] do not really build
+
+---
+ yesod-persistent.cabal | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/yesod-persistent.cabal b/yesod-persistent.cabal
+index 98c2146..11960cf 100644
+--- a/yesod-persistent.cabal
++++ b/yesod-persistent.cabal
+@@ -23,8 +23,7 @@ library
+ , lifted-base
+ , pool-conduit
+ , resourcet
+- exposed-modules: Yesod.Persist
+- Yesod.Persist.Core
++ exposed-modules:
+ ghc-options: -Wall
+
+ test-suite test
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/yesod-routes_export-module-referenced-by-TH-splices.patch b/standalone/android/haskell-patches/yesod-routes_export-module-referenced-by-TH-splices.patch
new file mode 100644
index 000000000..e20e3c7f1
--- /dev/null
+++ b/standalone/android/haskell-patches/yesod-routes_export-module-referenced-by-TH-splices.patch
@@ -0,0 +1,29 @@
+From f6bfe8e01d8fe6d129ad3819070aa17934094a0a Mon Sep 17 00:00:00 2001
+From: foo <foo@bar>
+Date: Sun, 22 Sep 2013 06:24:09 +0000
+Subject: [PATCH] export module referenced by TH splices
+
+---
+ yesod-routes.cabal | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/yesod-routes.cabal b/yesod-routes.cabal
+index 0b245f2..a97582a 100644
+--- a/yesod-routes.cabal
++++ b/yesod-routes.cabal
+@@ -27,11 +27,11 @@ library
+ Yesod.Routes.Class
+ Yesod.Routes.Parse
+ Yesod.Routes.Overlap
++ Yesod.Routes.TH.Types
+ other-modules: Yesod.Routes.TH.Dispatch
+ Yesod.Routes.TH.RenderRoute
+ Yesod.Routes.TH.ParseRoute
+ Yesod.Routes.TH.RouteAttrs
+- Yesod.Routes.TH.Types
+ ghc-options: -Wall
+
+ test-suite runtests
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/yesod_001_hacked-up-for-Android.patch b/standalone/android/haskell-patches/yesod_001_hacked-up-for-Android.patch
new file mode 100644
index 000000000..23ba50d33
--- /dev/null
+++ b/standalone/android/haskell-patches/yesod_001_hacked-up-for-Android.patch
@@ -0,0 +1,74 @@
+From 8bf7c428a42b984f63f435bb34f22743202ae449 Mon Sep 17 00:00:00 2001
+From: foo <foo@bar>
+Date: Sun, 22 Sep 2013 05:24:19 +0000
+Subject: [PATCH] hacked up for Android
+
+---
+ Yesod.hs | 2 --
+ Yesod/Default/Util.hs | 17 -----------------
+ 2 files changed, 19 deletions(-)
+
+diff --git a/Yesod.hs b/Yesod.hs
+index b367144..3050bf5 100644
+--- a/Yesod.hs
++++ b/Yesod.hs
+@@ -5,9 +5,7 @@ module Yesod
+ ( -- * Re-exports from yesod-core
+ module Yesod.Core
+ , module Yesod.Form
+- , module Yesod.Persist
+ ) where
+
+ import Yesod.Core
+ import Yesod.Form
+-import Yesod.Persist
+diff --git a/Yesod/Default/Util.hs b/Yesod/Default/Util.hs
+index a10358e..c5a4e58 100644
+--- a/Yesod/Default/Util.hs
++++ b/Yesod/Default/Util.hs
+@@ -8,7 +8,6 @@ module Yesod.Default.Util
+ , widgetFileNoReload
+ , widgetFileReload
+ , TemplateLanguage (..)
+- , defaultTemplateLanguages
+ , WidgetFileSettings
+ , wfsLanguages
+ , wfsHamletSettings
+@@ -20,9 +19,6 @@ import Yesod.Core -- purposely using complete import so that Haddock will see ad
+ import Control.Monad (when, unless)
+ import System.Directory (doesFileExist, createDirectoryIfMissing)
+ import Language.Haskell.TH.Syntax
+-import Text.Lucius (luciusFile, luciusFileReload)
+-import Text.Julius (juliusFile, juliusFileReload)
+-import Text.Cassius (cassiusFile, cassiusFileReload)
+ import Text.Hamlet (HamletSettings, defaultHamletSettings)
+ import Data.Maybe (catMaybes)
+ import Data.Default (Default (def))
+@@ -69,24 +65,11 @@ data TemplateLanguage = TemplateLanguage
+ , tlReload :: FilePath -> Q Exp
+ }
+
+-defaultTemplateLanguages :: HamletSettings -> [TemplateLanguage]
+-defaultTemplateLanguages hset =
+- [ TemplateLanguage False "hamlet" whamletFile' whamletFile'
+- , TemplateLanguage True "cassius" cassiusFile cassiusFileReload
+- , TemplateLanguage True "julius" juliusFile juliusFileReload
+- , TemplateLanguage True "lucius" luciusFile luciusFileReload
+- ]
+- where
+- whamletFile' = whamletFileWithSettings hset
+-
+ data WidgetFileSettings = WidgetFileSettings
+ { wfsLanguages :: HamletSettings -> [TemplateLanguage]
+ , wfsHamletSettings :: HamletSettings
+ }
+
+-instance Default WidgetFileSettings where
+- def = WidgetFileSettings defaultTemplateLanguages defaultHamletSettings
+-
+ widgetFileNoReload :: WidgetFileSettings -> FilePath -> Q Exp
+ widgetFileNoReload wfs x = combine "widgetFileNoReload" x False $ wfsLanguages wfs $ wfsHamletSettings wfs
+
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/yesod_002_hack-around-missing-symbols.patch b/standalone/android/haskell-patches/yesod_002_hack-around-missing-symbols.patch
new file mode 100644
index 000000000..eaad739e5
--- /dev/null
+++ b/standalone/android/haskell-patches/yesod_002_hack-around-missing-symbols.patch
@@ -0,0 +1,41 @@
+From 7e815b11f242d6836f9615439e32f9937bf2feaf Mon Sep 17 00:00:00 2001
+From: foo <foo@bar>
+Date: Sun, 22 Sep 2013 13:59:34 +0000
+Subject: [PATCH] hack around missing symbols
+
+---
+ Yesod.hs | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+diff --git a/Yesod.hs b/Yesod.hs
+index 3050bf5..fbe309c 100644
+--- a/Yesod.hs
++++ b/Yesod.hs
+@@ -5,7 +5,24 @@ module Yesod
+ ( -- * Re-exports from yesod-core
+ module Yesod.Core
+ , module Yesod.Form
++ , insertBy
++ , replace
++ , deleteBy
++ , delete
++ , insert
++ , Key
+ ) where
+
+ import Yesod.Core
+ import Yesod.Form
++
++-- These symbols are usually imported from persistent,
++-- But it is not built on Android. Still export them
++-- just so that hiding them will work.
++data Key = DummyKey
++insertBy = undefined
++replace = undefined
++deleteBy = undefined
++delete = undefined
++insert = undefined
++
+--
+1.7.10.4
+
diff --git a/standalone/android/haskell-patches/zlib_0.5.4.0_0001-hack-to-build-on-Android.patch b/standalone/android/haskell-patches/zlib_0.5.4.0_0001-hack-to-build-on-Android.patch
new file mode 100644
index 000000000..a899fb892
--- /dev/null
+++ b/standalone/android/haskell-patches/zlib_0.5.4.0_0001-hack-to-build-on-Android.patch
@@ -0,0 +1,35 @@
+From 63d07ae4a1e3b77cbe023364599f7c2c3e853d5f Mon Sep 17 00:00:00 2001
+From: Joey Hess <joey@kitenet.net>
+Date: Thu, 28 Feb 2013 23:40:57 -0400
+Subject: [PATCH] hack to build on Android
+
+---
+ Codec/Compression/Zlib/Stream.hsc | 4 ++--
+ zlib.cabal | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/Codec/Compression/Zlib/Stream.hsc b/Codec/Compression/Zlib/Stream.hsc
+index fe851e6..c6168f4 100644
+--- a/Codec/Compression/Zlib/Stream.hsc
++++ b/Codec/Compression/Zlib/Stream.hsc
+@@ -921,7 +921,7 @@ foreign import ccall unsafe "zlib.h inflateInit2_"
+
+ c_inflateInit2 :: StreamState -> CInt -> IO CInt
+ c_inflateInit2 z n =
+- withCAString #{const_str ZLIB_VERSION} $ \versionStr ->
++ withCAString "1.2.5" $ \versionStr ->
+ c_inflateInit2_ z n versionStr (#{const sizeof(z_stream)} :: CInt)
+
+ foreign import ccall unsafe "zlib.h inflate"
+@@ -940,7 +940,7 @@ foreign import ccall unsafe "zlib.h deflateInit2_"
+ c_deflateInit2 :: StreamState
+ -> CInt -> CInt -> CInt -> CInt -> CInt -> IO CInt
+ c_deflateInit2 z a b c d e =
+- withCAString #{const_str ZLIB_VERSION} $ \versionStr ->
++ withCAString "1.2.5" $ \versionStr ->
+ c_deflateInit2_ z a b c d e versionStr (#{const sizeof(z_stream)} :: CInt)
+
+ foreign import ccall unsafe "zlib.h deflateSetDictionary"
+--
+1.7.10.4
+
diff --git a/standalone/android/icons/drawable-hdpi/ic_launcher.png b/standalone/android/icons/drawable-hdpi/ic_launcher.png
new file mode 100644
index 000000000..6170d723c
--- /dev/null
+++ b/standalone/android/icons/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/standalone/android/icons/drawable-hdpi/ic_stat_service_notification_icon.png b/standalone/android/icons/drawable-hdpi/ic_stat_service_notification_icon.png
new file mode 100644
index 000000000..f30483b38
--- /dev/null
+++ b/standalone/android/icons/drawable-hdpi/ic_stat_service_notification_icon.png
Binary files differ
diff --git a/standalone/android/icons/drawable-ldpi/ic_launcher.png b/standalone/android/icons/drawable-ldpi/ic_launcher.png
new file mode 100644
index 000000000..0c5d55ab6
--- /dev/null
+++ b/standalone/android/icons/drawable-ldpi/ic_launcher.png
Binary files differ
diff --git a/standalone/android/icons/drawable-ldpi/ic_stat_service_notification_icon.png b/standalone/android/icons/drawable-ldpi/ic_stat_service_notification_icon.png
new file mode 100644
index 000000000..0e0b33e95
--- /dev/null
+++ b/standalone/android/icons/drawable-ldpi/ic_stat_service_notification_icon.png
Binary files differ
diff --git a/standalone/android/icons/drawable-mdpi/ic_launcher.png b/standalone/android/icons/drawable-mdpi/ic_launcher.png
new file mode 100644
index 000000000..46302b21a
--- /dev/null
+++ b/standalone/android/icons/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/standalone/android/icons/drawable-mdpi/ic_stat_service_notification_icon.png b/standalone/android/icons/drawable-mdpi/ic_stat_service_notification_icon.png
new file mode 100644
index 000000000..7febe040d
--- /dev/null
+++ b/standalone/android/icons/drawable-mdpi/ic_stat_service_notification_icon.png
Binary files differ
diff --git a/standalone/android/icons/drawable-xhdpi/ic_launcher.png b/standalone/android/icons/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 000000000..601b787cb
--- /dev/null
+++ b/standalone/android/icons/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/standalone/android/icons/drawable-xhdpi/ic_stat_service_notification_icon.png b/standalone/android/icons/drawable-xhdpi/ic_stat_service_notification_icon.png
new file mode 100644
index 000000000..253e90eb8
--- /dev/null
+++ b/standalone/android/icons/drawable-xhdpi/ic_stat_service_notification_icon.png
Binary files differ
diff --git a/standalone/android/icons/drawable/ic_launcher.png b/standalone/android/icons/drawable/ic_launcher.png
new file mode 120000
index 000000000..28d94e566
--- /dev/null
+++ b/standalone/android/icons/drawable/ic_launcher.png
@@ -0,0 +1 @@
+../drawable-mdpi/ic_launcher.png \ No newline at end of file
diff --git a/standalone/android/icons/drawable/ic_stat_service_notification_icon.png b/standalone/android/icons/drawable/ic_stat_service_notification_icon.png
new file mode 120000
index 000000000..3c30c49b0
--- /dev/null
+++ b/standalone/android/icons/drawable/ic_stat_service_notification_icon.png
@@ -0,0 +1 @@
+../drawable-mdpi/ic_stat_service_notification_icon.png \ No newline at end of file
diff --git a/standalone/android/install-haskell-packages b/standalone/android/install-haskell-packages
new file mode 100755
index 000000000..f0a4b9113
--- /dev/null
+++ b/standalone/android/install-haskell-packages
@@ -0,0 +1,120 @@
+#!/bin/bash
+# Bootstraps from an empty cabal to all the necessary haskell packages
+# being installed, with the necessary patches to work on Android.
+#
+# You should install ghc-android first.
+#
+# Note that the newest version of packages is installed.
+# It attempts to reuse patches for older versions, but
+# new versions of packages often break cross-compilation by adding TH,
+# etc
+#
+# Future work: Convert to using the method used here:
+# https://github.com/kaoskorobase/ghc-ios-cabal-scripts/
+
+set -e
+
+if [ ! -d haskell-patches ]; then
+ cd standalone/android
+fi
+
+cabalopts="$@"
+
+cabalinstall () {
+ echo cabal install "$@" "$cabalopts"
+ eval cabal install "$@" "$cabalopts"
+}
+
+patched () {
+ pkg=$1
+ shift 1
+ cabal unpack $pkg
+ cd $pkg*
+ git init
+ git config user.name dummy
+ git config user.email dummy@example.com
+ git add .
+ git commit -m "pre-patched state of $pkg"
+ for patch in ../../haskell-patches/${pkg}_*; do
+ echo trying $patch
+ if ! patch -p1 < $patch; then
+ echo "failed to apply $patch"
+ echo "please resolve this, replace the patch with a new version, and exit the subshell to continue"
+ $SHELL
+ fi
+ done
+ cabalinstall "$@"
+ rm -rf $pkg*
+ cd ..
+}
+
+installgitannexdeps () {
+ pushd ../..
+ echo cabal install --only-dependencies "$@"
+ cabal install --only-dependencies "$@"
+ popd
+}
+
+install_pkgs () {
+ rm -rf tmp
+ mkdir tmp
+ cd tmp
+
+ patched network
+ patched unix-time
+ patched lifted-base
+ patched zlib
+ patched process
+ patched MissingH
+ patched bloomfilter
+ patched SafeSemaphore
+ patched distributive
+ patched comonad
+ patched HTTP
+ patched MonadCatchIO-transformers
+ patched iproute
+ patched primitive
+ patched socks
+ patched entropy
+ patched vector
+ patched stm-chans
+ patched persistent
+ patched profunctors
+ patched skein
+ patched lens
+ patched persistent-template
+ patched wai-app-static
+ patched shakespeare
+ patched shakespeare-css
+ patched yesod-routes
+ patched yesod-core
+ patched yesod-persistent
+ patched yesod-form
+ patched crypto-numbers
+ patched yesod-auth
+ patched yesod
+ patched async
+ patched gnuidn
+ patched DAV
+ patched language-javascript
+ patched uuid
+
+ cd ..
+
+ installgitannexdeps -fAndroid -f-Pairing
+}
+
+echo
+echo
+echo native build
+echo
+cabal update
+installgitannexdeps
+
+echo
+echo
+echo cross build
+echo
+PATH=$HOME/.ghc/$(cat abiversion)/bin:$HOME/.ghc/$(cat abiversion)/arm-linux-androideabi/bin:$PATH
+cabal update
+install_pkgs
diff --git a/standalone/android/openssh.config.h b/standalone/android/openssh.config.h
new file mode 100644
index 000000000..31e78e0b8
--- /dev/null
+++ b/standalone/android/openssh.config.h
@@ -0,0 +1,249 @@
+#define DISABLE_SHADOW 1
+#define DISABLE_UTMP 1
+#define DISABLE_UTMPX 1
+#define DISABLE_WTMP 1
+#define DISABLE_WTMPX 1
+#define ENABLE_PKCS11 /**/
+#define GETPGRP_VOID 1
+#define GLOB_HAS_ALTDIRFUNC 1
+#define HAS_SHADOW_EXPIRE 1
+#define HAVE_ADDR_IN_UTMP 1
+#define HAVE_ADDR_IN_UTMPX 1
+#define HAVE_ADDR_V6_IN_UTMP 1
+#define HAVE_ADDR_V6_IN_UTMPX 1
+#define HAVE_ASPRINTF 1
+#define HAVE_ATTRIBUTE__NONNULL__ 1
+#define HAVE_BASENAME 1
+#define HAVE_BCOPY 1
+#define HAVE_BN_IS_PRIME_EX 1
+#define HAVE_CLOCK 1
+#define HAVE_CLOCK_T 1
+#define HAVE_CONST_GAI_STRERROR_PROTO 1
+#define HAVE_CONTROL_IN_MSGHDR 1
+#define HAVE_DAEMON 1
+#define HAVE_DECL_GLOB_NOMATCH 1
+#define HAVE_DECL_H_ERRNO 1
+#define HAVE_DECL_MAXSYMLINKS 1
+#define HAVE_DECL_OFFSETOF 1
+#define HAVE_DECL_O_NONBLOCK 1
+#define HAVE_DECL_SHUT_RD 1
+#define HAVE_DECL_WRITEV 1
+#define HAVE_DECL__GETLONG 0
+#define HAVE_DECL__GETSHORT 0
+#define HAVE_DEV_PTMX 1
+#define HAVE_DIRENT_H 1
+#define HAVE_DIRFD 1
+#define HAVE_DIRNAME 1
+#define HAVE_DSA_GENERATE_PARAMETERS_EX 1
+#define HAVE_ENDIAN_H 1
+#define HAVE_ENDUTENT 1
+#define HAVE_ENDUTXENT 1
+#define HAVE_EVP_SHA256 1
+#define HAVE_EXIT_IN_UTMP 1
+#define HAVE_FCHMOD 1
+#define HAVE_FCHOWN 1
+#define HAVE_FCNTL_H 1
+#define HAVE_FEATURES_H 1
+#define HAVE_FREEADDRINFO 1
+#define HAVE_FSBLKCNT_T 1
+#define HAVE_FSFILCNT_T 1
+#define HAVE_GAI_STRERROR 1
+#define HAVE_GETADDRINFO 1
+#define HAVE_GETCWD 1
+#define HAVE_GETNAMEINFO 1
+#define HAVE_GETOPT 1
+#define HAVE_GETOPT_H 1
+#define HAVE_GETPAGESIZE 1
+#define HAVE_GETRLIMIT 1
+#define HAVE_GETTIMEOFDAY 1
+#define HAVE_GETTTYENT 1
+#define HAVE_GETUTENT 1
+#define HAVE_GETUTID 1
+#define HAVE_GETUTLINE 1
+#define HAVE_GETUTXENT 1
+#define HAVE_GETUTXID 1
+#define HAVE_GETUTXLINE 1
+#define HAVE_GLOB 1
+#define HAVE_GLOB_H 1
+#define HAVE_HEADER_AD 1
+#define HAVE_HMAC_CTX_INIT 1
+#define HAVE_HOST_IN_UTMP 1
+#define HAVE_HOST_IN_UTMPX 1
+#define HAVE_ID_IN_UTMP 1
+#define HAVE_ID_IN_UTMPX 1
+#define HAVE_INET_ATON 1
+#define HAVE_INET_NTOA 1
+#define HAVE_INET_NTOP 1
+#define HAVE_INT64_T 1
+#define HAVE_INTTYPES_H 1
+#define HAVE_INTXX_T 1
+#define HAVE_IN_ADDR_T 1
+#define HAVE_ISBLANK 1
+#define HAVE_LASTLOG_H 1
+#define HAVE_LIBGEN_H 1
+#define HAVE_LIBNSL 1
+#define HAVE_LIBZ 1
+#define HAVE_LIMITS_H 1
+#define HAVE_LINUX_AUDIT_H 1
+#define HAVE_LINUX_FILTER_H 1
+#define HAVE_LINUX_IF_TUN_H 1
+#define HAVE_LOGOUT 1
+#define HAVE_LOGWTMP 1
+#define HAVE_LONG_DOUBLE 1
+#define HAVE_LONG_LONG 1
+#define HAVE_MEMMOVE 1
+#define HAVE_MEMORY_H 1
+#define HAVE_MKDTEMP 1
+#define HAVE_MMAP 1
+#define HAVE_MODE_T 1
+#define HAVE_NANOSLEEP 1
+#define HAVE_NETDB_H 1
+#define HAVE_OPENSSL 1
+#define HAVE_PATHS_H 1
+#define HAVE_PID_IN_UTMP 1
+#define HAVE_PID_T 1
+#define HAVE_POLL 1
+#define HAVE_POLL_H 1
+#define HAVE_PRCTL 1
+#define HAVE_PROC_PID 1
+#define HAVE_PUTUTLINE 1
+#define HAVE_PUTUTXLINE 1
+#define HAVE_REALPATH 1
+#define HAVE_RECVMSG 1
+#define HAVE_RLIMIT_NPROC /**/
+#define HAVE_RSA_GENERATE_KEY_EX 1
+#define HAVE_RSA_GET_DEFAULT_METHOD 1
+#define HAVE_SA_FAMILY_T 1
+#define HAVE_SENDMSG 1
+#define HAVE_SETEGID 1
+#define HAVE_SETENV 1
+#define HAVE_SETEUID 1
+#define HAVE_SETGROUPS 1
+#define HAVE_SETREGID 1
+#define HAVE_SETRESGID 1
+#define HAVE_SETRESUID 1
+#define HAVE_SETREUID 1
+#define HAVE_SETRLIMIT 1
+#define HAVE_SETSID 1
+#define HAVE_SETUTENT 1
+#define HAVE_SETUTXENT 1
+#define HAVE_SETVBUF 1
+#define HAVE_SHA256_UPDATE 1
+#define HAVE_SIGACTION 1
+#define HAVE_SIGVEC 1
+#define HAVE_SIG_ATOMIC_T 1
+#define HAVE_SIZE_T 1
+#define HAVE_SNPRINTF 1
+#define HAVE_SOCKETPAIR 1
+#define HAVE_SO_PEERCRED 1
+#define HAVE_SSIZE_T 1
+#define HAVE_SS_FAMILY_IN_SS 1
+#define HAVE_STATFS 1
+#define HAVE_STDDEF_H 1
+#define HAVE_STDINT_H 1
+#define HAVE_STDLIB_H 1
+#define HAVE_STRDUP 1
+#define HAVE_STRERROR 1
+#define HAVE_STRFTIME 1
+#define HAVE_STRICT_MKSTEMP 1
+#define HAVE_STRINGS_H 1
+#define HAVE_STRING_H 1
+#define HAVE_STRNLEN 1
+#define HAVE_STRPTIME 1
+#define HAVE_STRSEP 1
+#define HAVE_STRTOLL 1
+#define HAVE_STRTOUL 1
+#define HAVE_STRUCT_ADDRINFO 1
+#define HAVE_STRUCT_IN6_ADDR 1
+#define HAVE_STRUCT_SOCKADDR_IN6 1
+#define HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID 1
+#define HAVE_STRUCT_SOCKADDR_STORAGE 1
+#define HAVE_STRUCT_STAT_ST_BLKSIZE 1
+#define HAVE_STRUCT_TIMESPEC 1
+#define HAVE_STRUCT_TIMEVAL 1
+#define HAVE_SYSCONF 1
+#define HAVE_SYS_CDEFS_H 1
+#define HAVE_SYS_DIR_H 1
+#define HAVE_SYS_ERRLIST 1
+#define HAVE_SYS_MMAN_H 1
+#define HAVE_SYS_MOUNT_H 1
+#define HAVE_SYS_NERR 1
+#define HAVE_SYS_POLL_H 1
+#define HAVE_SYS_PRCTL_H 1
+#define HAVE_SYS_SELECT_H 1
+#define HAVE_SYS_STAT_H 1
+#define HAVE_SYS_SYSMACROS_H 1
+#define HAVE_SYS_TIME_H 1
+#define HAVE_SYS_TYPES_H 1
+#define HAVE_SYS_UN_H 1
+#define HAVE_TCGETPGRP 1
+#define HAVE_TCSENDBREAK 1
+#define HAVE_TIME 1
+#define HAVE_TIME_H 1
+#define HAVE_TRUNCATE 1
+#define HAVE_TV_IN_UTMP 1
+#define HAVE_TV_IN_UTMPX 1
+#define HAVE_TYPE_IN_UTMP 1
+#define HAVE_TYPE_IN_UTMPX 1
+#define HAVE_UINTXX_T 1
+#define HAVE_UNISTD_H 1
+#define HAVE_UNSETENV 1
+#define HAVE_UNSIGNED_LONG_LONG 1
+#define HAVE_UPDWTMP 1
+#define HAVE_UPDWTMPX 1
+#define HAVE_UTIMES 1
+#define HAVE_UTIME_H 1
+#define HAVE_UTMPNAME 1
+#define HAVE_UTMPXNAME 1
+#define HAVE_UTMP_H 1
+#define HAVE_U_CHAR 1
+#define HAVE_U_INT 1
+#define HAVE_U_INT64_T 1
+#define HAVE_U_INTXX_T 1
+#define HAVE_VASPRINTF 1
+#define HAVE_VA_COPY 1
+#define HAVE_VSNPRINTF 1
+#define HAVE_WAITPID 1
+#define HAVE__GETLONG 1
+#define HAVE__GETSHORT 1
+#define HAVE__RES_EXTERN 1
+#define HAVE___FUNCTION__ 1
+#define HAVE___PROGNAME 1
+#define HAVE___VA_COPY 1
+#define HAVE___func__ 1
+#define IPV4_IN_IPV6 1
+#define LINK_OPNOTSUPP_ERRNO EPERM
+#define LINUX_OOM_ADJUST 1
+#define LOCKED_PASSWD_PREFIX "!"
+#define LOGIN_PROGRAM_FALLBACK "/bin/login"
+#define MISSING_FD_MASK 1
+#define MISSING_HOWMANY 1
+#define OPENSSL_HAS_ECC 1
+#define OPENSSL_PRNG_ONLY 1
+#define PACKAGE_BUGREPORT "openssh-unix-dev@mindrot.org"
+#define PACKAGE_NAME "OpenSSH"
+#define PACKAGE_STRING "OpenSSH Portable"
+#define PACKAGE_TARNAME "openssh"
+#define PACKAGE_URL ""
+#define PACKAGE_VERSION "Portable"
+#define PAM_TTY_KLUDGE 1
+#define SANDBOX_RLIMIT 1
+#define SECCOMP_AUDIT_ARCH AUDIT_ARCH_ARM
+#define SIZEOF_CHAR 1
+#define SIZEOF_INT 4
+#define SIZEOF_LONG_INT 8
+#define SIZEOF_LONG_LONG_INT 8
+#define SIZEOF_SHORT_INT 2
+#define SNPRINTF_CONST const
+#define SPT_TYPE SPT_REUSEARGV
+#define SSH_PRIVSEP_USER "shell"
+#define SSH_TUN_COMPAT_AF 1
+#define SSH_TUN_LINUX 1
+#define SSH_TUN_PREPEND_AF 1
+#define STDC_HEADERS 1
+#define USER_PATH "/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin"
+#define XAUTH_PATH "/usr/bin/xauth"
+#define _PATH_BTMP "/var/log/btmp"
+#define _PATH_PASSWD_PROG "/usr/bin/passwd"
+#define _PATH_SSH_PIDDIR "/var/run"
+#define ANDROID
diff --git a/standalone/android/openssh.patch b/standalone/android/openssh.patch
new file mode 100644
index 000000000..6cdb29596
--- /dev/null
+++ b/standalone/android/openssh.patch
@@ -0,0 +1,205 @@
+diff --git a/auth.c b/auth.c
+index 6623e0f..dd10253 100644
+--- a/auth.c
++++ b/auth.c
+@@ -337,7 +337,7 @@ expand_authorized_keys(const char *filename, struct passwd *pw)
+ char *file, ret[MAXPATHLEN];
+ int i;
+
+- file = percent_expand(filename, "h", pw->pw_dir,
++ file = percent_expand(filename, "h", _PATH_ROOT_HOME_PREFIX,
+ "u", pw->pw_name, (char *)NULL);
+
+ /*
+@@ -347,7 +347,7 @@ expand_authorized_keys(const char *filename, struct passwd *pw)
+ if (*file == '/')
+ return (file);
+
+- i = snprintf(ret, sizeof(ret), "%s/%s", pw->pw_dir, file);
++ i = snprintf(ret, sizeof(ret), "%s/%s", _PATH_ROOT_HOME_PREFIX, file);
+ if (i < 0 || (size_t)i >= sizeof(ret))
+ fatal("expand_authorized_keys: path too long");
+ xfree(file);
+@@ -436,7 +436,7 @@ secure_filename(FILE *f, const char *file, struct passwd *pw,
+ strerror(errno));
+ return -1;
+ }
+- if (realpath(pw->pw_dir, homedir) != NULL)
++ if (realpath(_PATH_ROOT_HOME_PREFIX, homedir) != NULL)
+ comparehome = 1;
+
+ /* check the open file to avoid races */
+diff --git a/misc.c b/misc.c
+index 0bf2db6..4327d03 100644
+--- a/misc.c
++++ b/misc.c
+@@ -25,6 +25,7 @@
+ */
+
+ #include "includes.h"
++#include "pathnames.h"
+
+ #include <sys/types.h>
+ #include <sys/ioctl.h>
+@@ -538,12 +539,13 @@ tilde_expand_filename(const char *filename, uid_t uid)
+ } else if ((pw = getpwuid(uid)) == NULL) /* ~/path */
+ fatal("tilde_expand_filename: No such uid %ld", (long)uid);
+
+- if (strlcpy(ret, pw->pw_dir, sizeof(ret)) >= sizeof(ret))
++ char *pw_dir=_PATH_ROOT_HOME_PREFIX;
++ if (strlcpy(ret, pw_dir, sizeof(ret)) >= sizeof(ret))
+ fatal("tilde_expand_filename: Path too long");
+
+ /* Make sure directory has a trailing '/' */
+- len = strlen(pw->pw_dir);
+- if ((len == 0 || pw->pw_dir[len - 1] != '/') &&
++ len = strlen(pw_dir);
++ if ((len == 0 || pw_dir[len - 1] != '/') &&
+ strlcat(ret, "/", sizeof(ret)) >= sizeof(ret))
+ fatal("tilde_expand_filename: Path too long");
+
+diff --git a/openbsd-compat/getrrsetbyname.c b/openbsd-compat/getrrsetbyname.c
+index d2bea21..5b5d599 100644
+--- a/openbsd-compat/getrrsetbyname.c
++++ b/openbsd-compat/getrrsetbyname.c
+@@ -56,8 +56,7 @@
+ #include <arpa/inet.h>
+
+ #include "getrrsetbyname.h"
+-#include "nameser.h"
+-#include "nameser_compat.h"
++#include "arpa/nameser.h"
+
+ #if defined(HAVE_DECL_H_ERRNO) && !HAVE_DECL_H_ERRNO
+ extern int h_errno;
+diff --git a/pathnames.h b/pathnames.h
+index b7b9d91..3c10b11 100644
+--- a/pathnames.h
++++ b/pathnames.h
+@@ -67,7 +67,7 @@
+ #endif
+
+ #ifndef _PATH_ROOT_HOME_PREFIX
+-#define _PATH_ROOT_HOME_PREFIX "/data"
++#define _PATH_ROOT_HOME_PREFIX getenv("HOME")
+ #endif
+
+ /*
+diff --git a/readconf.c b/readconf.c
+index 097bb05..dcbc008 100644
+--- a/readconf.c
++++ b/readconf.c
+@@ -1085,7 +1085,7 @@ read_config_file(const char *filename, const char *host, Options *options,
+ if ((f = fopen(filename, "r")) == NULL)
+ return 0;
+
+- if (checkperm) {
++ if (checkperm && 0) {
+ struct stat sb;
+
+ if (fstat(fileno(f), &sb) == -1)
+diff --git a/ssh-add.c b/ssh-add.c
+index 738644d..f6fce4a 100644
+--- a/ssh-add.c
++++ b/ssh-add.c
+@@ -471,7 +471,7 @@ main(int argc, char **argv)
+ }
+
+ for (i = 0; default_files[i]; i++) {
+- snprintf(buf, sizeof(buf), "%s/%s", pw->pw_dir,
++ snprintf(buf, sizeof(buf), "%s/%s", _PATH_ROOT_HOME_PREFIX,
+ default_files[i]);
+ if (stat(buf, &st) < 0)
+ continue;
+diff --git a/ssh-keygen.c b/ssh-keygen.c
+index 4baf7df..ef8bb25 100644
+--- a/ssh-keygen.c
++++ b/ssh-keygen.c
+@@ -224,7 +224,7 @@ ask_filename(struct passwd *pw, const char *prompt)
+ }
+ }
+ snprintf(identity_file, sizeof(identity_file), "%s/%s",
+- strcmp(pw->pw_dir, "/") ? pw->pw_dir : _PATH_ROOT_HOME_PREFIX, name);
++ _PATH_ROOT_HOME_PREFIX, name);
+ fprintf(stderr, "%s (%s): ", prompt, identity_file);
+ if (fgets(buf, sizeof(buf), stdin) == NULL)
+ exit(1);
+@@ -2268,7 +2268,7 @@ main(int argc, char **argv)
+
+ /* Create ~/.ssh directory if it doesn't already exist. */
+ snprintf(dotsshdir, sizeof dotsshdir, "%s/%s",
+- strcmp(pw->pw_dir, "/") ? pw->pw_dir : _PATH_ROOT_HOME_PREFIX,
++ _PATH_ROOT_HOME_PREFIX,
+ _PATH_SSH_USER_DIR);
+ if (strstr(identity_file, dotsshdir) != NULL) {
+ if (stat(dotsshdir, &st) < 0) {
+diff --git a/ssh.c b/ssh.c
+index 898e966..ef6c858 100644
+--- a/ssh.c
++++ b/ssh.c
+@@ -703,7 +703,7 @@ main(int ac, char **av)
+ fatal("Can't open user config file %.100s: "
+ "%.100s", config, strerror(errno));
+ } else {
+- r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir,
++ r = snprintf(buf, sizeof buf, "%s/%s", _PATH_ROOT_HOME_PREFIX,
+ _PATH_SSH_USER_CONFFILE);
+ if (r > 0 && (size_t)r < sizeof(buf))
+ (void)read_config_file(buf, host, &options, 1);
+@@ -748,7 +748,7 @@ main(int ac, char **av)
+ if (options.local_command != NULL) {
+ debug3("expanding LocalCommand: %s", options.local_command);
+ cp = options.local_command;
+- options.local_command = percent_expand(cp, "d", pw->pw_dir,
++ options.local_command = percent_expand(cp, "d", _PATH_ROOT_HOME_PREFIX,
+ "h", host, "l", thishost, "n", host_arg, "r", options.user,
+ "p", portstr, "u", pw->pw_name, "L", shorthost,
+ (char *)NULL);
+@@ -888,7 +888,7 @@ main(int ac, char **av)
+ */
+ if (config == NULL) {
+ r = snprintf(buf, sizeof buf, "%s/%s",
+- strcmp(pw->pw_dir, "/") ? pw->pw_dir : _PATH_ROOT_HOME_PREFIX,
++ _PATH_ROOT_HOME_PREFIX,
+ _PATH_SSH_USER_DIR);
+ if (r > 0 && (size_t)r < sizeof(buf) && stat(buf, &st) < 0) {
+ #ifdef WITH_SELINUX
+@@ -1532,7 +1532,7 @@ load_public_identity_files(void)
+ if ((pw = getpwuid(original_real_uid)) == NULL)
+ fatal("load_public_identity_files: getpwuid failed");
+ pwname = xstrdup(pw->pw_name);
+- pwdir = xstrdup(pw->pw_dir);
++ pwdir = xstrdup(_PATH_ROOT_HOME_PREFIX);
+ if (gethostname(thishost, sizeof(thishost)) == -1)
+ fatal("load_public_identity_files: gethostname: %s",
+ strerror(errno));
+diff --git a/uidswap.c b/uidswap.c
+index bc6194e..5cbf5d1 100644
+--- a/uidswap.c
++++ b/uidswap.c
+@@ -28,7 +28,6 @@
+ #include "xmalloc.h"
+
+ #ifdef ANDROID
+-#include <private/android_filesystem_config.h>
+ #include <linux/capability.h>
+ #include <linux/prctl.h>
+ #endif
+@@ -230,7 +229,7 @@ permanently_set_uid(struct passwd *pw)
+ debug("permanently_set_uid: %u/%u", (u_int)pw->pw_uid,
+ (u_int)pw->pw_gid);
+
+-#ifdef ANDROID
++#if 0
+ if (pw->pw_uid == AID_SHELL) {
+ prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
+
+@@ -317,7 +316,7 @@ permanently_set_uid(struct passwd *pw)
+ (u_int)pw->pw_uid);
+ }
+
+-#ifdef ANDROID
++#if 0
+ if (pw->pw_uid == AID_SHELL) {
+ /* set CAP_SYS_BOOT capability, so "adb reboot" will succeed */
+ header.version = _LINUX_CAPABILITY_VERSION;
diff --git a/standalone/android/rsync.patch b/standalone/android/rsync.patch
new file mode 100644
index 000000000..692e9cabb
--- /dev/null
+++ b/standalone/android/rsync.patch
@@ -0,0 +1,40 @@
+From f91df535053958600d57f9df78d9ce84c8718655 Mon Sep 17 00:00:00 2001
+From: Joey Hess <joey@kitenet.net>
+Date: Wed, 13 Feb 2013 15:51:40 -0400
+Subject: [PATCH] android portability
+
+---
+ authenticate.c | 3 ++-
+ batch.c | 2 +-
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/authenticate.c b/authenticate.c
+index 7650377..626dec6 100644
+--- a/authenticate.c
++++ b/authenticate.c
+@@ -296,7 +296,8 @@ void auth_client(int fd, const char *user, const char *challenge)
+ *
+ * OpenBSD has a readpassphrase() that might be more suitable.
+ */
+- pass = getpass("Password: ");
++ /*pass = getpass("Password: "); */
++ exit(1);
+ }
+
+ if (!pass)
+diff --git a/batch.c b/batch.c
+index a3e9dca..ee31532 100644
+--- a/batch.c
++++ b/batch.c
+@@ -221,7 +221,7 @@ void write_batch_shell_file(int argc, char *argv[], int file_arg_cnt)
+ stringjoin(filename, sizeof filename,
+ batch_name, ".sh", NULL);
+ fd = do_open(filename, O_WRONLY | O_CREAT | O_TRUNC,
+- S_IRUSR | S_IWUSR | S_IEXEC);
++ S_IRUSR | S_IWUSR);
+ if (fd < 0) {
+ rsyserr(FERROR, errno, "Batch file %s open error",
+ filename);
+--
+1.7.10.4
+
diff --git a/standalone/android/runshell b/standalone/android/runshell
new file mode 100755
index 000000000..ef6744494
--- /dev/null
+++ b/standalone/android/runshell
@@ -0,0 +1,132 @@
+#!/system/bin/sh
+# This is runs a shell in an environment configured for git-annex.
+# Nearly the only command that can be used in here is busybox!
+# lib.start.so will run us in the root of our app directory
+base=$(./busybox pwd)
+cmd=$base/busybox
+
+set -e
+
+prep () {
+ # Cannot rely on Android providing a sane HOME
+ HOME="/sdcard/git-annex.home"
+ export HOME
+}
+
+buildtree () {
+ $cmd echo "Installation starting to $base"
+ $cmd cat "lib/lib.version.so"
+
+ if $cmd test -e "$base/bin"; then
+ $cmd mv "$base/bin" "$base/bin.old"
+ fi
+ $cmd mkdir -p "$base/bin"
+
+ for prog in busybox git-annex git-shell git-upload-pack git gpg rsync ssh ssh-keygen; do
+ $cmd echo "installing $prog"
+ if $cmd test -e "$base/bin/$prog"; then
+ $cmd rm -f "$base/bin/$prog"
+ fi
+ $cmd ln -s "$base/lib/lib.$prog.so" "$base/bin/$prog"
+ done
+
+ $cmd --install $base/bin
+
+ $cmd rm -rf "$base/bin.old"
+
+ $cmd tar zxf $base/lib/lib.git.tar.gz.so
+ for prog in git git-shell git-upload-pack; do
+ for link in $($cmd cat "$base/links/$prog"); do
+ $cmd echo "linking $link to $prog"
+ if $cmd test -e "$base/$link"; then
+ $cmd rm -f "$base/$link"
+ fi
+ $cmd ln -s "$base/bin/$prog" "$base/$link"
+ done
+ $cmd rm -f "$base/links/$prog"
+ done
+
+ $cmd mkdir -p "$base/templates"
+ $cmd mkdir -p "$base/tmp"
+
+ $cmd echo "#!/system/bin/sh" > "$base/runshell"
+ $cmd echo "exec $base/lib/lib.start.so" >> "$base/runshell"
+ $cmd chmod 755 runshell
+
+ $cmd cat "$base/lib/lib.version.so" > "$base/installed-version"
+ $cmd echo "Installation complete"
+}
+
+install () {
+ if ! $cmd mkdir -p "$HOME"; then
+ $cmd echo "mkdir of $HOME failed!"
+ fi
+ if $cmd test ! -e "$base/bin/git-annex"; then
+ if ! buildtree > $HOME/git-annex-install.log 2>&1; then
+ $cmd echo "Installation failed! Please report a bug and attach $HOME/git-annex-install.log"
+ $cmd sh
+ fi
+ elif $cmd test ! -e "$base/installed-version" || ! $cmd cmp "$base/installed-version" "$base/lib/lib.version.so" >/dev/null; then
+ if ! buildtree > $HOME/git-annex-install.log 2>&1; then
+ $cmd echo "Upgrade failed! Please report a bug and attach $HOME/git-annex-install.log"
+ fi
+ fi
+}
+
+run () {
+ PATH="$base/bin:$PATH"
+ export PATH
+
+ ORIG_GIT_EXEC_PATH="$GIT_EXEC_PATH"
+ export ORIG_GIT_EXEC_PATH
+ GIT_EXEC_PATH=$base/libexec/git-core
+ export GIT_EXEC_PATH
+
+ ORIG_GIT_TEMPLATE_DIR="$GIT_TEMPLATE_DIR"
+ export ORIG_GIT_TEMPLATE_DIR
+ GIT_TEMPLATE_DIR="$base/templates"
+ export GIT_TEMPLATE_DIR
+
+ # Indicate which variables were exported above.
+ GIT_ANNEX_STANDLONE_ENV="GIT_EXEC_PATH GIT_TEMPLATE_DIR"
+ export GIT_ANNEX_STANDLONE_ENV
+
+ # This is a temporary directory on a non-crippled filesystem.
+ # Needs to be as short a path as possible, for ssh sockets.
+ GIT_ANNEX_TMP_DIR=$base/tmp
+ export GIT_ANNEX_TMP_DIR
+ # /tmp probably doesn't exist, so also use it as TMPDIR
+ TMPDIR=$GIT_ANNEX_TMP_DIR
+ export TMPDIR
+
+ if $cmd test ! -e "$HOME/.gitconfig"; then
+ git config --global user.email "git-annex@android"
+ git config --global user.name "android"
+ fi
+
+ if $cmd test "$1"; then
+ cmd="$1"
+ shift 1
+ exec "$cmd" "$@"
+ else
+ # As good a start point as any.
+ cd "$HOME"
+
+ /system/bin/sh
+ fi
+}
+
+if $cmd test -n "$MKFIFO"; then
+ # because java is insane
+ $cmd mkfifo "$MKFIFO"
+else
+ if ! prep; then
+ $cmd echo "prep failed. Please report a bug."
+ read line
+ fi
+ if ! install; then
+ $cmd echo "install failed. Please report a bug."
+ read line
+ fi
+ run
+fi
diff --git a/standalone/android/start b/standalone/android/start
new file mode 100755
index 000000000..44dcb3cf4
--- /dev/null
+++ b/standalone/android/start
Binary files differ
diff --git a/standalone/android/start.c b/standalone/android/start.c
new file mode 100644
index 000000000..c67c5da0c
--- /dev/null
+++ b/standalone/android/start.c
@@ -0,0 +1,64 @@
+/* Installed as lib.start.so, this bootstraps a working busybox and uses
+ * it to run lib.runshell.so. */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+void chopdir (char *s) {
+ char *p=strrchr(s, '/');
+ if (p == NULL) {
+ fprintf(stderr, "cannot find directory in %s", s);
+ exit(1);
+ }
+ p[0] = '\0';
+}
+
+main () {
+ char buf[1024];
+ char *p;
+ struct stat st_buf;
+
+ /* Get something like /data/data/ga.androidterm/lib/lib.start.so */
+ int n=readlink("/proc/self/exe", buf, 1023);
+ if (n < 1) {
+ fprintf(stderr, "failed to find own name");
+ exit(1);
+ }
+ buf[n] = '\0';
+
+ /* Change directory to something like /data/data/ga.androidterm */
+ chopdir(buf);
+ chopdir(buf);
+ if (chdir(buf) != 0) {
+ perror("chdir");
+ exit(1);
+ }
+
+ if (stat("lib/lib.busybox.so", &st_buf) != 0) {
+ /* TODO my lib dir should be in LD_LIBRARY_PATH; check that */
+ fprintf(stderr, "Falling back to hardcoded app location; cannot find expected files in %s\n", buf);
+ if (chdir("/data/data/ga.androidterm") != 0) {
+ perror("chdir");
+ exit(1);
+ }
+ }
+
+ /* If this is the first run, set up busybox symlink,
+ * which allows busybox to run. */
+ if (stat("busybox", &st_buf) != 0) {
+ if (symlink("lib/lib.busybox.so", "busybox") != 0) {
+ /* Just in case! */
+ if (link("lib/lib.busybox.so", "busybox") != 0) {
+ perror("link busybox");
+ exit(1);
+ }
+ }
+ }
+
+ execl("./busybox", "./busybox", "sh", "lib/lib.runshell.so", NULL);
+ perror("error running busybox sh");
+}
diff --git a/standalone/android/term.patch b/standalone/android/term.patch
new file mode 100644
index 000000000..5f7d40335
--- /dev/null
+++ b/standalone/android/term.patch
@@ -0,0 +1,598 @@
+diff --git a/AndroidManifest.xml b/AndroidManifest.xml
+index b0e866a..1ab8515 100644
+--- a/AndroidManifest.xml
++++ b/AndroidManifest.xml
+@@ -7,6 +7,7 @@
+ <uses-feature android:name="android.hardware.touchscreen" android:required="false" />
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
++ <uses-permission android:name="android.permission.WRITE_MEDIA_STORAGE" />
+ <uses-permission android:name="android.permission.WAKE_LOCK" />
+ <permission android:name="jackpal.androidterm.permission.RUN_SCRIPT"
+ android:label="@string/perm_run_script"
+diff --git a/examples/widget/src/jackpal/androidterm/sample/telnet/TermActivity.java b/examples/widget/src/jackpal/androidterm/sample/telnet/TermActivity.java
+index f6952f0..1a8df8f 100644
+--- a/examples/widget/src/jackpal/androidterm/sample/telnet/TermActivity.java
++++ b/examples/widget/src/jackpal/androidterm/sample/telnet/TermActivity.java
+@@ -166,7 +166,7 @@ public class TermActivity extends Activity
+ /* ... create a process ... */
+ String execPath = LaunchActivity.getDataDir(this) + "/bin/execpty";
+ ProcessBuilder execBuild =
+- new ProcessBuilder(execPath, "/system/bin/sh", "-");
++ new ProcessBuilder(execPath, "/data/data/ga.androidterm/lib/lib.start.so", "");
+ execBuild.redirectErrorStream(true);
+ Process exec = null;
+ try {
+diff --git a/res/menu/main.xml b/res/menu/main.xml
+index 064f833..fe5f3a3 100644
+--- a/res/menu/main.xml
++++ b/res/menu/main.xml
+@@ -16,6 +16,8 @@
+ -->
+
+ <menu xmlns:android="http://schemas.android.com/apk/res/android">
++ <item android:id="@+id/menu_send_email"
++ android:title="@string/send_email" />
+ <item android:id="@+id/menu_new_window"
+ android:title="@string/new_window"
+ android:icon="@drawable/ic_menu_add" />
+@@ -34,8 +36,6 @@
+ android:icon="@drawable/ic_menu_preferences" />
+ <item android:id="@+id/menu_reset"
+ android:title="@string/reset" />
+- <item android:id="@+id/menu_send_email"
+- android:title="@string/send_email" />
+ <item android:id="@+id/menu_toggle_wakelock"
+ android:title="@string/enable_wakelock" />
+ <item android:id="@+id/menu_toggle_wifilock"
+diff --git a/res/values-cz/strings.xml b/res/values-cz/strings.xml
+index f3d19bc..882e19b 100644
+--- a/res/values-cz/strings.xml
++++ b/res/values-cz/strings.xml
+@@ -23,7 +23,7 @@
+ <string name="prev_window">Predešlé okno</string>
+ <string name="next_window">Další okno</string>
+ <string name="reset">Reset terminálu</string>
+- <string name="send_email">Napiš email</string>
++ <string name="send_email">WebApp</string>
+ <string name="special_keys">Speciální znaky</string>
+ <string name="toggle_soft_keyboard">Přepnout soft. klávesnici</string>
+
+@@ -124,4 +124,4 @@
+ <string name="control_key_dialog_fn_disabled_text">Není nastaveno žádné tlačitko pro funkční klávesu.</string>
+
+ <string name="confirm_window_close_message">Zavřít okno?</string>
+-</resources>
+\ No newline at end of file
++</resources>
+diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
+index f6134a5..06d2e1f 100644
+--- a/res/values-de/strings.xml
++++ b/res/values-de/strings.xml
+@@ -23,7 +23,7 @@
+ <string name="prev_window">Vorh. Fenster</string>
+ <string name="next_window">Nächst. Fenster</string>
+ <string name="reset">Zurücksetzen</string>
+- <string name="send_email">Email schreiben</string>
++ <string name="send_email">WebApp</string>
+ <string name="special_keys">Spezialtasten</string>
+ <string name="toggle_soft_keyboard">Tastatur an/aus</string>
+
+@@ -124,4 +124,4 @@
+
+ <string name="perm_run_script">Beliebige Scripte im Terminal Emulator ausführen</string>
+ <string name="permdesc_run_script">Erlaubt Anwendungen, neue Fenster im Android Terminal Emulator zu öffnen und in diesen Befehle auszuführen. Dies schließt alle Berechtigungen von Android Terminal Emulator ein, inklusive Internetzugang und Schreib-/Leserechte auf der SD-Karte.</string>
+-</resources>
+\ No newline at end of file
++</resources>
+diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
+index 94553b2..92d9e2a 100644
+--- a/res/values-es/strings.xml
++++ b/res/values-es/strings.xml
+@@ -23,7 +23,7 @@
+ <string name="prev_window">Ventana anterior</string>
+ <string name="next_window">Ventana posterior</string>
+ <string name="reset">Reiniciar consola</string>
+- <string name="send_email">Enviar email</string>
++ <string name="send_email">WebApp</string>
+ <string name="special_keys">Teclas especiales</string>
+ <string name="toggle_soft_keyboard">Ver/ocultar teclado</string>
+
+diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml
+index b9f0586..92a16a0 100644
+--- a/res/values-eu/strings.xml
++++ b/res/values-eu/strings.xml
+@@ -23,7 +23,7 @@
+ <string name="prev_window">Aurreko leihoa</string>
+ <string name="next_window">Hurrengo leihoa</string>
+ <string name="reset">Berrezarri terminala</string>
+- <string name="send_email">Bidali eposta ...(r)i</string>
++ <string name="send_email">WebApp</string>
+ <string name="special_keys">Tekla bereziak</string>
+ <string name="toggle_soft_keyboard">Txandakatu soft teklatua</string>
+
+diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
+index beab2be..529f720 100644
+--- a/res/values-fr/strings.xml
++++ b/res/values-fr/strings.xml
+@@ -24,7 +24,7 @@
+ <string name="prev_window">Fenêtre Préc.</string>
+ <string name="next_window">Fenêtre Suiv.</string>
+ <string name="reset">Terminal par défaut</string>
+- <string name="send_email">Envoyer un e-mail</string>
++ <string name="send_email">WebApp</string>
+ <string name="special_keys">Touches spéciales</string>
+ <string name="toggle_soft_keyboard">Afficher/Masquer Clavier</string>
+
+diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
+index 5dbecb5..ce917c5 100644
+--- a/res/values-hu/strings.xml
++++ b/res/values-hu/strings.xml
+@@ -23,7 +23,7 @@
+ <string name="prev_window">Előző ablak</string>
+ <string name="next_window">Következő ablak</string>
+ <string name="reset">Alaphelyzet</string>
+- <string name="send_email">Küldés emailben</string>
++ <string name="send_email">WebApp</string>
+ <string name="special_keys">Speciális billentyűk</string>
+ <string name="toggle_soft_keyboard">Billentyűzet ki/be</string>
+
+@@ -148,4 +148,4 @@
+ <string name="alt_sends_esc">Az Alt billentyű ESC-et küld</string>
+ <string name="alt_sends_esc_summary_on">Az Alt billentyű ESC-et küld.</string>
+ <string name="alt_sends_esc_summary_off">Az Alt billentyű nem ESC-et küld.</string>
+-</resources>
+\ No newline at end of file
++</resources>
+diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
+index e6a7294..9d97869 100644
+--- a/res/values-it/strings.xml
++++ b/res/values-it/strings.xml
+@@ -23,7 +23,7 @@
+ <string name="prev_window">Fin. successiva</string>
+ <string name="next_window">Fin. precedente</string>
+ <string name="reset">Reset terminale</string>
+- <string name="send_email">Invia email</string>
++ <string name="send_email">WebApp</string>
+ <string name="special_keys">Tasti speciali</string>
+ <string name="toggle_soft_keyboard">Mostra/nascondi tastiera</string>
+
+diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
+index 502fa23..dbfe9fa 100644
+--- a/res/values-ja/strings.xml
++++ b/res/values-ja/strings.xml
+@@ -23,7 +23,7 @@
+ <string name="prev_window">前のウインドウ</string>
+ <string name="next_window">次のウインドウ</string>
+ <string name="reset">端末をリセット</string>
+- <string name="send_email">メール送信</string>
++ <string name="send_email">WebApp</string>
+ <string name="special_keys">特殊キー</string>
+ <string name="toggle_soft_keyboard">ソフトキーボード</string>
+
+diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml
+index 06629d0..1d545b6 100644
+--- a/res/values-ka/strings.xml
++++ b/res/values-ka/strings.xml
+@@ -23,7 +23,7 @@
+ <string name="prev_window">წინა ფანჯარა</string>
+ <string name="next_window">შემდეგი ფანჯარა</string>
+ <string name="reset">ტერმინალის რესტარტი</string>
+- <string name="send_email">ელ-ფოსტის გაგზავნა</string>
++ <string name="send_email">WebApp</string>
+ <string name="special_keys">სპეციალური ღილაკები</string>
+ <string name="toggle_soft_keyboard">პროგრამული კლავიატურის ჩართ./გამორთ.</string>
+
+diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
+index d81ee07..c370c6f 100644
+--- a/res/values-nb/strings.xml
++++ b/res/values-nb/strings.xml
+@@ -18,7 +18,7 @@
+ <string name="application_terminal">Terminal Emulator</string>
+ <string name="preferences">Innstillinger</string>
+ <string name="reset">Tilbakestill terminal</string>
+- <string name="send_email">Send epost til</string>
++ <string name="send_email">WebApp</string>
+ <string name="special_keys">Spesielle tegn</string>
+ <string name="toggle_soft_keyboard">Veksle virtuelt tastatur</string>
+
+diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
+index 19fa3d0..e24fbf5 100644
+--- a/res/values-nl/strings.xml
++++ b/res/values-nl/strings.xml
+@@ -23,7 +23,7 @@
+ <string name="prev_window">Vorig venster</string>
+ <string name="next_window">Volgend venster</string>
+ <string name="reset">Herstellen</string>
+- <string name="send_email">E-mail sturen naar</string>
++ <string name="send_email">WebApp</string>
+ <string name="special_keys">Speciale knoppen</string>
+ <string name="toggle_soft_keyboard">Toetsenbord aan/uit</string>
+
+diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
+index 25b3b43..2e0e651 100644
+--- a/res/values-pl/strings.xml
++++ b/res/values-pl/strings.xml
+@@ -23,7 +23,7 @@
+ <string name="prev_window">Poprzednie okno</string>
+ <string name="next_window">Następne okno</string>
+ <string name="reset">Wyczyść terminal</string>
+- <string name="send_email">Wyślij e-mail</string>
++ <string name="send_email">WebApp</string>
+ <string name="special_keys">Przyciski specjalne</string>
+ <string name="toggle_soft_keyboard">Pokaż klawiaturę</string>
+
+diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
+index aa4ba54..aa3d735 100644
+--- a/res/values-pt-rPT/strings.xml
++++ b/res/values-pt-rPT/strings.xml
+@@ -18,7 +18,7 @@
+ <string name="application_terminal">Terminal Emulator</string>
+ <string name="preferences">Preferências</string>
+ <string name="reset">Reset terminal</string>
+- <string name="send_email">Email para</string>
++ <string name="send_email">WebApp</string>
+ <string name="special_keys">Teclas especiais</string>
+ <string name="toggle_soft_keyboard">Abrir teclado</string>
+
+diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
+index 2d992f9..e53a9ac 100644
+--- a/res/values-pt/strings.xml
++++ b/res/values-pt/strings.xml
+@@ -23,7 +23,7 @@
+ <string name="prev_window">Anterior</string>
+ <string name="next_window">Seguinte</string>
+ <string name="reset">Repor terminal</string>
+- <string name="send_email">Enviar mensagem para</string>
++ <string name="send_email">WebApp</string>
+ <string name="special_keys">Teclas especiais</string>
+ <string name="toggle_soft_keyboard">Mostrar/ocultar teclado</string>
+
+diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
+index 3c7ea06..7a072d0 100644
+--- a/res/values-ro/strings.xml
++++ b/res/values-ro/strings.xml
+@@ -21,7 +21,7 @@
+ <string name="prev_window">"Fereastra anterioră"</string>
+ <string name="next_window">"Fereastra următoare"</string>
+ <string name="reset">"Resetaţi "</string>
+- <string name="send_email">"E-mail"</string>
++ <string name="send_email">WebApp</string>
+ <string name="special_keys">"Taste speciale"</string>
+ <string name="toggle_soft_keyboard">"Comutați tastatura"</string>
+
+@@ -123,4 +123,4 @@
+ <string name="alt_sends_esc">"Tasta Alt trimite ESC"</string>
+ <string name="alt_sends_esc_summary_on">"Tasta Alt trimite ESC."</string>
+ <string name="alt_sends_esc_summary_off">"Tasta Alt nu trimite ESC."</string>
+-</resources>
+\ No newline at end of file
++</resources>
+diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
+index 0e96360..762324e 100644
+--- a/res/values-ru/strings.xml
++++ b/res/values-ru/strings.xml
+@@ -8,7 +8,7 @@
+ <string name="prev_window">Предыдущее окно</string>
+ <string name="next_window">Следующее окно</string>
+ <string name="reset">Сбросить терминал</string>
+- <string name="send_email">Отправить Email</string>
++ <string name="send_email">WebApp</string>
+ <string name="special_keys">Специальные клавиши</string>
+ <string name="toggle_soft_keyboard">Экранная клавиатура</string>
+ <string name="reset_toast_notification">Терминальное состояние этого окна было сброшено.</string>
+diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
+index ef35366..cc31d80 100644
+--- a/res/values-sk/strings.xml
++++ b/res/values-sk/strings.xml
+@@ -23,7 +23,7 @@
+ <string name="prev_window">Dalšie okno</string>
+ <string name="next_window">Predch. okno</string>
+ <string name="reset">Obnoviť term.</string>
+- <string name="send_email">Poslať e-mailom</string>
++ <string name="send_email">WebApp</string>
+ <string name="special_keys">Špec. klávesy</string>
+ <string name="toggle_soft_keyboard">Skryť/zobraziť klávesnicu</string>
+
+diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
+index 1aa9055..8de6c09 100644
+--- a/res/values-sv/strings.xml
++++ b/res/values-sv/strings.xml
+@@ -3,7 +3,7 @@
+ <string name="application_terminal">Terminalemulator</string>
+ <string name="preferences">Inställningar</string>
+ <string name="reset">Återställ terminal</string>
+- <string name="send_email">E-posta till</string>
++ <string name="send_email">WebApp</string>
+ <string name="special_keys">Special tangenter</string>
+ <string name="toggle_soft_keyboard">Växla till virtuellt tangentbord</string>
+ <string name="enable_wakelock">Aktivera VäckningsLås</string>
+diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
+index b45fa12..fb70f78 100644
+--- a/res/values-tr/strings.xml
++++ b/res/values-tr/strings.xml
+@@ -18,7 +18,7 @@
+ <string name="application_terminal">Terminal Emülatörü</string>
+ <string name="preferences">Tercihler</string>
+ <string name="reset">Terminali yeniden başlat</string>
+- <string name="send_email">Email olarak yolla</string>
++ <string name="send_email">WebApp</string>
+ <string name="special_keys">Özel tuşlar</string>
+ <string name="toggle_soft_keyboard">Ekran klavyesine geç</string>
+
+diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
+index 2f267a9..d3622c4 100644
+--- a/res/values-uk/strings.xml
++++ b/res/values-uk/strings.xml
+@@ -8,7 +8,7 @@
+ <string name="prev_window">Попереднє вікно</string>
+ <string name="next_window">Наступне вікно</string>
+ <string name="reset">Скинути термінал</string>
+- <string name="send_email">Відіслати Email</string>
++ <string name="send_email">WebApp</string>
+ <string name="special_keys">Спеціальні клавіші</string>
+ <string name="toggle_soft_keyboard">Екранна клавіатура</string>
+ <string name="reset_toast_notification">"Термінальний стан цього вікна було скинуто."</string>
+diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
+index 6f47b4f..81316ec 100644
+--- a/res/values-zh-rCN/strings.xml
++++ b/res/values-zh-rCN/strings.xml
+@@ -18,7 +18,7 @@
+ <string name="application_terminal">终端模拟器</string>
+ <string name="preferences">首选项</string>
+ <string name="reset">重置终端</string>
+- <string name="send_email">发送电子邮件到...</string>
++ <string name="send_email">WebApp</string>
+ <string name="special_keys">特殊键</string>
+ <string name="toggle_soft_keyboard">打开/关闭软键盘</string>
+
+diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
+index afda0f1..37d1b50 100644
+--- a/res/values-zh-rTW/strings.xml
++++ b/res/values-zh-rTW/strings.xml
+@@ -18,7 +18,7 @@
+ <string name="application_terminal">模擬終端</string>
+ <string name="preferences">設定</string>
+ <string name="reset">結束</string>
+- <string name="send_email">以電郵傳送</string>
++ <string name="send_email">WebApp</string>
+ <string name="special_keys">特別按鍵</string>
+ <string name="toggle_soft_keyboard">顯示/隱藏鍵盤</string>
+
+diff --git a/res/values/defaults.xml b/res/values/defaults.xml
+index 67287b2..9b7cfcd 100644
+--- a/res/values/defaults.xml
++++ b/res/values/defaults.xml
+@@ -13,10 +13,10 @@
+ <string name="pref_fnkey_default">4</string>
+ <string name="pref_ime_default">0</string>
+ <bool name="pref_alt_sends_esc_default">false</bool>
+- <string name="pref_shell_default">/system/bin/sh -</string>
+- <string name="pref_initialcommand_default"></string>
++ <string name="pref_shell_default">/data/data/ga.androidterm/lib/lib.start.so</string>
++ <string name="pref_initialcommand_default">git annex webapp</string>
+ <string name="pref_termtype_default">screen</string>
+- <bool name="pref_close_window_on_process_exit_default">true</bool>
++ <bool name="pref_close_window_on_process_exit_default">false</bool>
+ <bool name="pref_verify_path_default">true</bool>
+ <bool name="pref_do_path_extensions_default">true</bool>
+ <bool name="pref_allow_prepend_path_default">true</bool>
+diff --git a/res/values/strings.xml b/res/values/strings.xml
+index f1464e9..b06ec9a 100644
+--- a/res/values/strings.xml
++++ b/res/values/strings.xml
+@@ -23,7 +23,7 @@
+ <string name="prev_window">Prev window</string>
+ <string name="next_window">Next window</string>
+ <string name="reset">Reset term</string>
+- <string name="send_email">Email to</string>
++ <string name="send_email">Open WebApp</string>
+ <string name="special_keys">Special keys</string>
+ <string name="toggle_soft_keyboard">Toggle soft keyboard</string>
+
+diff --git a/src/jackpal/androidterm/ShellTermSession.java b/src/jackpal/androidterm/ShellTermSession.java
+index 501e7ab..0b43513 100644
+--- a/src/jackpal/androidterm/ShellTermSession.java
++++ b/src/jackpal/androidterm/ShellTermSession.java
+@@ -80,12 +80,12 @@ public class ShellTermSession extends TermSession {
+ }
+ };
+
+- public ShellTermSession(TermSettings settings, String initialCommand) {
++ public ShellTermSession(TermSettings settings, String initialCommand, String webAppFifo) {
+ super();
+
+ updatePrefs(settings);
+
+- initializeSession();
++ initializeSession(webAppFifo);
+ mInitialCommand = initialCommand;
+
+ mWatcherThread = new Thread() {
+@@ -106,7 +106,7 @@ public class ShellTermSession extends TermSession {
+ setDefaultUTF8Mode(settings.defaultToUTF8Mode());
+ }
+
+- private void initializeSession() {
++ private void initializeSession(String webAppFifo) {
+ TermSettings settings = mSettings;
+
+ int[] processId = new int[1];
+@@ -128,9 +128,10 @@ public class ShellTermSession extends TermSession {
+ if (settings.verifyPath()) {
+ path = checkPath(path);
+ }
+- String[] env = new String[2];
++ String[] env = new String[3];
+ env[0] = "TERM=" + settings.getTermType();
+ env[1] = "PATH=" + path;
++ env[2] = "FIFO=" + webAppFifo;
+
+ createSubprocess(processId, settings.getShell(), env);
+ mProcId = processId[0];
+diff --git a/src/jackpal/androidterm/Term.java b/src/jackpal/androidterm/Term.java
+index 8a3a4ac..824025d 100644
+--- a/src/jackpal/androidterm/Term.java
++++ b/src/jackpal/androidterm/Term.java
+@@ -20,6 +20,13 @@ import java.io.UnsupportedEncodingException;
+ import java.text.Collator;
+ import java.util.Arrays;
+ import java.util.Locale;
++import java.lang.Process;
++import java.lang.ProcessBuilder;
++import java.util.Map;
++
++import java.io.FileReader;
++import java.io.BufferedReader;
++import java.io.File;
+
+ import android.app.Activity;
+ import android.app.AlertDialog;
+@@ -59,6 +66,11 @@ import android.view.inputmethod.InputMethodManager;
+ import android.widget.TextView;
+ import android.widget.Toast;
+
++import android.content.Intent;
++import android.net.Uri;
++import android.app.Activity;
++import android.content.Context;
++
+ import jackpal.androidterm.emulatorview.ColorScheme;
+ import jackpal.androidterm.emulatorview.EmulatorView;
+ import jackpal.androidterm.emulatorview.TermSession;
+@@ -107,6 +119,9 @@ public class Term extends Activity implements UpdateCallback {
+ public static final String EXTRA_WINDOW_ID = "jackpal.androidterm.window_id";
+ private int onResumeSelectWindow = -1;
+
++ public static String appDir;
++ public static String webAppFifo;
++
+ private PowerManager.WakeLock mWakeLock;
+ private WifiManager.WifiLock mWifiLock;
+ // Available on API 12 and later
+@@ -257,6 +272,48 @@ public class Term extends Activity implements UpdateCallback {
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
++
++ try {
++ appDir = getApplicationContext().getPackageManager().getPackageInfo(getPackageName(), 0).applicationInfo.dataDir;
++ } catch (Exception e) {
++ appDir = "/data/data/ga.androidterm";
++ }
++ webAppFifo = appDir + "/fifo";
++
++ /* webapp url opening thread */
++ new Thread() {
++ @Override
++ public void run() {
++ try {
++ /* First, set up the fifo that urls to open will be
++ * read from. This is complicated by java not being
++ * able to mkfifo. */
++ File f = new File (webAppFifo);
++ if (! f.exists()) {
++ ProcessBuilder pb = new ProcessBuilder(appDir + "/lib/lib.start.so");
++ Map<String, String> env = pb.environment();
++ env.put("MKFIFO", webAppFifo);
++ Process p = pb.start();
++ p.waitFor();
++ }
++
++ /* Reading from the fifo blocks until a url is written
++ * to it. */
++ while (true) {
++ BufferedReader buf = new BufferedReader(new FileReader(webAppFifo));
++ String s = buf.readLine();
++ try {
++ Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(s));
++ startActivity(intent);
++ } catch (Exception e) {
++ }
++
++ }
++ } catch (Exception e) {
++ }
++ }
++ }.start();
++
+ Log.e(TermDebug.LOG_TAG, "onCreate");
+ mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
+ mSettings = new TermSettings(getResources(), mPrefs);
+@@ -427,7 +484,7 @@ public class Term extends Activity implements UpdateCallback {
+ }
+
+ protected static TermSession createTermSession(Context context, TermSettings settings, String initialCommand) {
+- ShellTermSession session = new ShellTermSession(settings, initialCommand);
++ ShellTermSession session = new ShellTermSession(settings, initialCommand, webAppFifo);
+ // XXX We should really be able to fetch this from within TermSession
+ session.setProcessExitMessage(context.getString(R.string.process_exit_message));
+
+@@ -911,31 +968,15 @@ public class Term extends Activity implements UpdateCallback {
+ }
+
+ private void doEmailTranscript() {
++ // Hack: repurposed to open the git-annex webapp
+ TermSession session = getCurrentTermSession();
+ if (session != null) {
+- // Don't really want to supply an address, but
+- // currently it's required, otherwise nobody
+- // wants to handle the intent.
+- String addr = "user@example.com";
+- Intent intent =
+- new Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:"
+- + addr));
+-
+- String subject = getString(R.string.email_transcript_subject);
+- String title = session.getTitle();
+- if (title != null) {
+- subject = subject + " - " + title;
+- }
+- intent.putExtra(Intent.EXTRA_SUBJECT, subject);
+- intent.putExtra(Intent.EXTRA_TEXT,
+- session.getTranscriptText().trim());
+ try {
+- startActivity(Intent.createChooser(intent,
+- getString(R.string.email_transcript_chooser_title)));
+- } catch (ActivityNotFoundException e) {
+- Toast.makeText(this,
+- R.string.email_transcript_no_email_activity_found,
+- Toast.LENGTH_LONG).show();
++ BufferedReader buf = new BufferedReader(new FileReader("/sdcard/git-annex.home/.git-annex-url"));
++ String s = buf.readLine();
++ Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(s));
++ startActivity(intent);
++ } catch (Exception e) {
+ }
+ }
+ }
+diff --git a/tools/build-debug b/tools/build-debug
+index 1f15cd2..e611956 100755
+--- a/tools/build-debug
++++ b/tools/build-debug
+@@ -34,4 +34,4 @@ fi
+
+ rm -rf `find . -name bin -o -name obj -prune`
+ cd jni
+-$ANDROID_NDK_ROOT/ndk-build && cd .. && ant debug
++$ANDROID_NDK_ROOT/ndk-build && cd ..
+diff --git a/tools/update.sh b/tools/update.sh
+index 57219c3..79b45ef 100755
+--- a/tools/update.sh
++++ b/tools/update.sh
+@@ -18,7 +18,7 @@ command -v "$ANDROID" >/dev/null 2>&1 || { echo >&2 "The $ANDROID tool is not fo
+
+ # Make sure target-11 is installed
+
+-$ANDROID update sdk -u -t android-11
++$ANDROID update sdk -u -t android-17
+
+ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+ ATE_ROOT="$( cd $DIR/.. && pwd )"
+@@ -31,5 +31,5 @@ for PROJECT_FILE in $PROJECT_FILES
+ do
+ PROJECT_DIR="$( dirname "$PROJECT_FILE" )"
+ echo "Updating $PROJECT_FILE"
+- $ANDROID update project -p "$PROJECT_DIR" --target android-11
++ $ANDROID update project -p "$PROJECT_DIR" --target android-17
+ done
diff --git a/standalone/licences.gz b/standalone/licences.gz
new file mode 100644
index 000000000..422f84225
--- /dev/null
+++ b/standalone/licences.gz
Binary files differ
diff --git a/standalone/linux/README b/standalone/linux/README
new file mode 100644
index 000000000..18983fd7a
--- /dev/null
+++ b/standalone/linux/README
@@ -0,0 +1,25 @@
+You can put this directory into your PATH, and use git-annex the same
+as if you'd installed it using a package manager.
+
+Or, you can use the runshell script in this directory to start a shell
+that is configured to use git-annex and the other utilities included in
+this bundle, including git, gpg, rsync, ssh, etc.
+
+This should work on any Linux system of the appropriate architecture.
+More or less. There are no external dependencies, except for glibc.
+Any recent-ish version of glibc should work (2.13 is ok; so is 2.11).
+
+
+How it works: This directory tree contains a lot of libraries and programs
+that git-annex needs. But it's not a chroot. Instead, runshell sets PATH
+and LD_LIBRARY_PATH to point to the stuff in here.
+
+The glibc libs are not included. Instead, it runs with the host system's
+glibc. We trust that glibc's excellent backwards and forward compatability
+is good enough to run binaries that were linked for a newer or older
+version. Of course, this could fail. Particularly if the binaries try to
+use some new glibc feature. But hopefully not.
+
+Why not bundle glibc too? I've not gotten it to work! The host system's
+ld-linux.so will be used for sure, as that's hardcoded into the binaries.
+When I tried including libraries from glibc in here, everything segfaulted.
diff --git a/standalone/linux/git-annex b/standalone/linux/git-annex
new file mode 100755
index 000000000..d9ec8baa5
--- /dev/null
+++ b/standalone/linux/git-annex
@@ -0,0 +1,25 @@
+#!/bin/sh
+base="$(dirname "$0")"
+if [ ! -d "$base" ]; then
+ echo "** cannot find base directory (I seem to be $0)" >&2
+ exit 1
+fi
+if [ ! -e "$base/runshell" ]; then
+ echo "** cannot find $base/runshell" >&2
+ exit 1
+fi
+
+# Get absolute path to base, to avoid breakage when things change directories.
+orig="$(pwd)"
+cd "$base"
+base="$(pwd)"
+cd "$orig"
+
+# If this is a standalone app, set a variable that git-annex can use to
+# install itself.
+if [ -e "$base/bin/git-annex" ]; then
+ GIT_ANNEX_APP_BASE="$base"
+ export GIT_ANNEX_APP_BASE
+fi
+
+exec "$base/runshell" git-annex "$@"
diff --git a/standalone/linux/git-annex-shell b/standalone/linux/git-annex-shell
new file mode 100755
index 000000000..44d5f694e
--- /dev/null
+++ b/standalone/linux/git-annex-shell
@@ -0,0 +1,25 @@
+#!/bin/sh
+base="$(dirname "$0")"
+if [ ! -d "$base" ]; then
+ echo "** cannot find base directory (I seem to be $0)" >&2
+ exit 1
+fi
+if [ ! -e "$base/runshell" ]; then
+ echo "** cannot find $base/runshell" >&2
+ exit 1
+fi
+
+# Get absolute path to base, to avoid breakage when things change directories.
+orig="$(pwd)"
+cd "$base"
+base="$(pwd)"
+cd "$orig"
+
+# If this is a standalone app, set a variable that git-annex can use to
+# install itself.
+if [ -e "$base/bin/git-annex" ]; then
+ GIT_ANNEX_APP_BASE="$base"
+ export GIT_ANNEX_APP_BASE
+fi
+
+exec "$base/runshell" git-annex-shell "$@"
diff --git a/standalone/linux/git-annex-webapp b/standalone/linux/git-annex-webapp
new file mode 100755
index 000000000..2698af9b5
--- /dev/null
+++ b/standalone/linux/git-annex-webapp
@@ -0,0 +1,25 @@
+#!/bin/sh
+base="$(dirname "$0")"
+if [ ! -d "$base" ]; then
+ echo "** cannot find base directory (I seem to be $0)" >&2
+ exit 1
+fi
+if [ ! -e "$base/runshell" ]; then
+ echo "** cannot find $base/runshell" >&2
+ exit 1
+fi
+
+# Get absolute path to base, to avoid breakage when things change directories.
+orig="$(pwd)"
+cd "$base"
+base="$(pwd)"
+cd "$orig"
+
+# If this is a standalone app, set a variable that git-annex can use to
+# install itself.
+if [ -e "$base/bin/git-annex" ]; then
+ GIT_ANNEX_APP_BASE="$base"
+ export GIT_ANNEX_APP_BASE
+fi
+
+exec "$base/runshell" git-annex webapp "$@"
diff --git a/standalone/linux/glibc-libs b/standalone/linux/glibc-libs
new file mode 100644
index 000000000..3f6e64112
--- /dev/null
+++ b/standalone/linux/glibc-libs
@@ -0,0 +1,43 @@
+libanl-.*.so
+libutil-.*.so
+libnss_hesiod-.*.so
+libcrypt-.*.so
+libnss_compat-.*.so
+libm-.*.so
+libr.so
+libpcprofile.so
+libnss_nis-.*.so
+libSegFault.so
+libpthread-.*.so
+librt-.*.so
+libnss_dns-.*.so
+libdl-.*.so
+libBrokenLocale-.*.so
+libnss_nisplus-.*.so
+libthread_db-1.0.so
+libmemusage.so
+libcidn-.*.so
+libnss_files-.*.so
+libnsl-.*.so
+libc-.*.so
+ld-.*.so
+libnss_nis.so
+libthread_db.so
+libanl.so
+libr.so
+libnss_compat.so
+libm.so
+libnss_dns.so
+libpthread.so
+libc.so
+librt.so
+libcidn.so
+libnss_nisplus.so
+libnsl.so
+libutil.so
+libBrokenLocale.so
+ld-linux.so
+libnss_files.so
+libdl.so
+libnss_hesiod.so
+libcrypt.so
diff --git a/standalone/linux/runshell b/standalone/linux/runshell
new file mode 100755
index 000000000..a36e49083
--- /dev/null
+++ b/standalone/linux/runshell
@@ -0,0 +1,76 @@
+#!/bin/sh
+# Runs a shell command (or interactive shell) using the binaries and
+# libraries bundled with this app.
+
+set -e
+
+base="$(dirname "$0")"
+
+if [ ! -d "$base" ]; then
+ echo "** cannot find base directory (I seem to be $0)" >&2
+ exit 1
+fi
+
+if [ ! -e "$base/bin/git-annex" ]; then
+ echo "** base directory $base does not contain bin/git-annex" >&2
+ exit 1
+fi
+if [ ! -e "$base/bin/git" ]; then
+ echo "** base directory $base does not contain bin/git" >&2
+ exit 1
+fi
+
+# Get absolute path to base, to avoid breakage when things change directories.
+orig="$(pwd)"
+cd "$base"
+base="$(pwd)"
+cd "$orig"
+
+# Install shim that's used to run git-annex-shell from ssh authorized_keys.
+# The assistant also does this when run, but the user may not be using the
+# assistant.
+if [ ! -e "$HOME/.ssh/git-annex-shell" ]; then
+ mkdir "$HOME/.ssh" >/dev/null 2>&1 || true
+ (
+ echo "#!/bin/sh"
+ echo "set -e"
+ echo "exec $base/runshell git-annex-shell -c \"\$SSH_ORIGINAL_COMMAND\""
+ ) > "$HOME/.ssh/git-annex-shell"
+ chmod +x "$HOME/.ssh/git-annex-shell"
+fi
+
+# Put our binaries first, to avoid issues with out of date or incompatable
+# system binaries.
+ORIG_PATH="$PATH"
+export ORIG_PATH
+PATH=$base/bin:$PATH
+export PATH
+
+ORIG_LD_LIBRARY_PATH="$LD_LIBRARY_PATH"
+export ORIG_LD_LIBRARY_PATH
+for lib in $(cat $base/libdirs); do
+ LD_LIBRARY_PATH="$base/$lib:$LD_LIBRARY_PATH"
+done
+export LD_LIBRARY_PATH
+
+ORIG_GIT_EXEC_PATH="$GIT_EXEC_PATH"
+export ORIG_GIT_EXEC_PATH
+GIT_EXEC_PATH=$base/git-core
+export GIT_EXEC_PATH
+
+ORIG_GIT_TEMPLATE_DIR="$GIT_TEMPLATE_DIR"
+export ORIG_GIT_TEMPLATE_DIR
+GIT_TEMPLATE_DIR="$base/templates"
+export GIT_TEMPLATE_DIR
+
+# Indicate which variables were exported above.
+GIT_ANNEX_STANDLONE_ENV="PATH LD_LIBRARY_PATH GIT_EXEC_PATH GIT_TEMPLATE_DIR"
+export GIT_ANNEX_STANDLONE_ENV
+
+if [ "$1" ]; then
+ cmd="$1"
+ shift 1
+ exec "$cmd" "$@"
+else
+ sh
+fi
diff --git a/standalone/osx/git-annex.app/Contents/Info.plist b/standalone/osx/git-annex.app/Contents/Info.plist
new file mode 100644
index 000000000..91f804987
--- /dev/null
+++ b/standalone/osx/git-annex.app/Contents/Info.plist
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>git-annex-webapp</string>
+ <key>NSHumanReadableCopyright</key>
+ <string>GPL 3</string>
+ <key>CFBundleGetInfoString</key>
+ <string>0.0.1</string>
+ <key>CFBundleIconFile</key>
+ <string>git-annex</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.branchable.git-annex</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>GIT-ANNEX</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>0.0.1</string>
+ <key>CFBundleSignature</key>
+ <string>git-annex</string>
+ <key>CFBundleVersion</key>
+ <string>0.0.1</string>
+ <key>LSMinimumSystemVersion</key>
+ <string>10.5</string>
+ <key>CFBundleDisplayName</key>
+ <string>Start git-annex webapp</string>
+ <key>LSMinimumSystemVersionByArchitecture</key>
+ <dict>
+ <key>i386</key>
+ <string>10.5.0</string>
+ <key>x86_64</key>
+ <string>10.6.0</string>
+ </dict>
+</dict>
+</plist>
diff --git a/standalone/osx/git-annex.app/Contents/MacOS/README b/standalone/osx/git-annex.app/Contents/MacOS/README
new file mode 100644
index 000000000..c4bcea383
--- /dev/null
+++ b/standalone/osx/git-annex.app/Contents/MacOS/README
@@ -0,0 +1,9 @@
+This is a app bundle for git-annex. Most users are going to want to
+just click on the icon to start up the git-annex webapp.
+
+To use git-annex at the command line, you can put the directory containing
+this README into your PATH.
+
+Or, you can use the runshell script in this directory to start a shell
+that is configured to use git-annex and the other utilities included in
+this bundle, including git, gpg, rsync, ssh, etc.
diff --git a/standalone/osx/git-annex.app/Contents/MacOS/git-annex b/standalone/osx/git-annex.app/Contents/MacOS/git-annex
new file mode 100755
index 000000000..452a46694
--- /dev/null
+++ b/standalone/osx/git-annex.app/Contents/MacOS/git-annex
@@ -0,0 +1,25 @@
+#!/bin/sh
+base="$(dirname "$0")"
+if [ ! -d "$base" ]; then
+ echo "** cannot find base directory (I seem to be $0)" >&2
+ exit 1
+fi
+if [ ! -e "$base/runshell" ]; then
+ echo "** cannot find $base/runshell" >&2
+ exit 1
+fi
+
+# Get absolute path to base, to avoid breakage when things change directories.
+orig="$(pwd)"
+cd "$base"
+base="$(pwd)"
+cd "$orig"
+
+# If this is a standalone app, set a variable that git-annex can use to
+# install itself.
+if [ -e "$base/git-annex" ]; then
+ GIT_ANNEX_APP_BASE="$base"
+ export GIT_ANNEX_APP_BASE
+fi
+
+exec "$base/runshell" git-annex "$@"
diff --git a/standalone/osx/git-annex.app/Contents/MacOS/git-annex-shell b/standalone/osx/git-annex.app/Contents/MacOS/git-annex-shell
new file mode 100755
index 000000000..9e8c0ad69
--- /dev/null
+++ b/standalone/osx/git-annex.app/Contents/MacOS/git-annex-shell
@@ -0,0 +1,25 @@
+#!/bin/sh
+base="$(dirname "$0")"
+if [ ! -d "$base" ]; then
+ echo "** cannot find base directory (I seem to be $0)" >&2
+ exit 1
+fi
+if [ ! -e "$base/runshell" ]; then
+ echo "** cannot find $base/runshell" >&2
+ exit 1
+fi
+
+# Get absolute path to base, to avoid breakage when things change directories.
+orig="$(pwd)"
+cd "$base"
+base="$(pwd)"
+cd "$orig"
+
+# If this is a standalone app, set a variable that git-annex can use to
+# install itself.
+if [ -e "$base/git-annex" ]; then
+ GIT_ANNEX_APP_BASE="$base"
+ export GIT_ANNEX_APP_BASE
+fi
+
+exec "$base/runshell" git-annex-shell "$@"
diff --git a/standalone/osx/git-annex.app/Contents/MacOS/git-annex-webapp b/standalone/osx/git-annex.app/Contents/MacOS/git-annex-webapp
new file mode 100755
index 000000000..37a4984af
--- /dev/null
+++ b/standalone/osx/git-annex.app/Contents/MacOS/git-annex-webapp
@@ -0,0 +1,26 @@
+#!/bin/sh
+base="$(dirname "$0")"
+if [ ! -d "$base" ]; then
+ echo "** cannot find base directory (I seem to be $0)" >&2
+ exit 1
+fi
+if [ ! -e "$base/runshell" ]; then
+ echo "** cannot find $base/runshell" >&2
+ exit 1
+fi
+
+# Get absolute path to base, to avoid breakage when things change directories.
+orig="$(pwd)"
+cd "$base"
+base="$(pwd)"
+cd "$orig"
+
+# If this is a standalone app, set a variable that git-annex can use to
+# install itself.
+if [ -e "$base/git-annex" ]; then
+ GIT_ANNEX_APP_BASE="$base"
+ export GIT_ANNEX_APP_BASE
+fi
+
+# OSX wants this to run in the background.
+exec "$base/runshell" git-annex webapp "$@" &
diff --git a/standalone/osx/git-annex.app/Contents/MacOS/runshell b/standalone/osx/git-annex.app/Contents/MacOS/runshell
new file mode 100755
index 000000000..9f1457e25
--- /dev/null
+++ b/standalone/osx/git-annex.app/Contents/MacOS/runshell
@@ -0,0 +1,71 @@
+#!/bin/sh
+# Runs a shell command (or interactive shell) using the binaries
+# bundled with this app.
+
+set -e
+
+base="$(dirname "$0")"
+
+if [ ! -d "$base" ]; then
+ echo "** cannot find base directory (I seem to be $0)" >&2
+ exit 1
+fi
+
+bundle="$base/bundle"
+
+if [ ! -e "$bundle/git-annex" ]; then
+ echo "** bundle directory $bundle does not contain git-annex" >&2
+ exit 1
+fi
+if [ ! -e "$bundle/git" ]; then
+ echo "** bundle directory $bundle does not contain git" >&2
+ exit 1
+fi
+
+# Get absolute path to base, to avoid breakage when things change directories.
+orig="$(pwd)"
+cd "$base"
+base="$(pwd)"
+cd "$orig"
+
+# Install shim that's used to run git-annex-shell from ssh authorized_keys.
+# The assistant also does this when run, but the user may not be using the
+# assistant.
+if [ ! -e "$HOME/.ssh/git-annex-shell" ]; then
+ mkdir "$HOME/.ssh" >/dev/null 2>&1 || true
+ (
+ echo "#!/bin/sh"
+ echo "set -e"
+ echo "exec $base/runshell git-annex-shell -c \"\$SSH_ORIGINAL_COMMAND\""
+ ) > "$HOME/.ssh/git-annex-shell"
+ chmod +x "$HOME/.ssh/git-annex-shell"
+fi
+
+# Put our binaries first, to avoid issues with out of date or incompatable
+# system binaries.
+ORIG_PATH="$PATH"
+export ORIG_PATH
+PATH=$bundle:$PATH
+export PATH
+
+ORIG_GIT_EXEC_PATH="$GIT_EXEC_PATH"
+export ORIG_GIT_EXEC_PATH
+GIT_EXEC_PATH=$bundle
+export GIT_EXEC_PATH
+
+ORIG_GIT_TEMPLATE_DIR="$GIT_TEMPLATE_DIR"
+export ORIG_GIT_TEMPLATE_DIR
+GIT_TEMPLATE_DIR="$bundle/templates"
+export GIT_TEMPLATE_DIR
+
+# Indicate which variables were exported above.
+GIT_ANNEX_STANDLONE_ENV="PATH GIT_EXEC_PATH GIT_TEMPLATE_DIR"
+export GIT_ANNEX_STANDLONE_ENV
+
+if [ "$1" ]; then
+ cmd="$1"
+ shift 1
+ exec "$cmd" "$@"
+else
+ $SHELL
+fi
diff --git a/standalone/osx/git-annex.app/Contents/Resources/git-annex.icns b/standalone/osx/git-annex.app/Contents/Resources/git-annex.icns
new file mode 100644
index 000000000..a79c6d9e7
--- /dev/null
+++ b/standalone/osx/git-annex.app/Contents/Resources/git-annex.icns
Binary files differ
diff --git a/standalone/windows/build.sh b/standalone/windows/build.sh
new file mode 100644
index 000000000..74148dfe5
--- /dev/null
+++ b/standalone/windows/build.sh
@@ -0,0 +1,56 @@
+#!/bin/sh
+#
+# This script is run by the jenkins autobuilder, in a mingw environment,
+# to build git-annex for Windows.
+
+set -x
+set -e
+
+HP="/c/Program Files (x86)/Haskell Platform/2012.4.0.0"
+FLAGS="-Webapp -Assistant -XMPP"
+
+PATH="$HP/bin:$HP/lib/extralibs/bin:/c/Program Files (x86)/NSIS:$PATH"
+
+UPGRADE_LOCATION=http://downloads.kitenet.net/git-annex/windows/current/git-annex-installer.exe
+
+# Run a command with the cygwin environment available.
+# However, programs not from cygwin are preferred.
+withcyg () {
+ PATH="$PATH:/c/cygwin/bin" "$@"
+}
+
+# Don't allow build artifact from a past successful build to be extracted
+# if we fail.
+rm -f git-annex-installer.exe
+
+# Install haskell dependencies.
+# cabal install is not run in cygwin, because we don't want configure scripts
+# for haskell libraries to link them with the cygwin library.
+cabal update || true
+
+cabal install --only-dependencies -f"$FLAGS"
+
+# Detect when the last build was an incremental build and failed,
+# and try a full build. Done this way because this shell seems a bit
+# broken.
+if [ -e last-incremental-failed ]; then
+ cabal clean || true
+ # windows breakage..
+ rm -rf dist
+fi
+touch last-incremental-failed
+
+# Build git-annex
+withcyg cabal configure -f"$FLAGS"
+withcyg cabal build
+
+# Build the installer
+cabal install nsis
+ghc --make Build/NullSoftInstaller.hs
+withcyg Build/NullSoftInstaller.exe
+
+rm -f last-incremental-failed
+
+# Test git-annex
+rm -rf .t
+withcyg dist/build/git-annex/git-annex.exe test || true